diff --git a/Reading/Developers/index.html b/Reading/Developers/index.html index 618ba651..ce19b8cf 100644 --- a/Reading/Developers/index.html +++ b/Reading/Developers/index.html @@ -1 +1 @@ - 程序员的职业和生存指南 - 知行斋
Skip to content

程序员的职业和生存指南 - 读约翰·森梅兹的2本书有感

2024年元旦后读了约翰·森梅兹(John Sonmez)的2本书,很有共鸣,产生了写读书感想的念头,借机也梳理了我个人的观点和想法,于是便有了下面这些文章。

《软技能:代码之外的生存指南(第2版)》

  • 第一篇 职业
    • 第2章 经营自己的职业生涯就像经营一家企业
    • 第3章 如何给自己设定好职业目标
    • 第4章 拓展自己的人际交往能力
    • 第5章 创建一份屡试屡验的简历
    • 第6章 破解面试之道
    • 第7章 软件开发人员的三条职业路径
    • 第8章 为什么你需要走专业化道路
    • 第9章 公司与公司是不一样的
    • 第10章 攀登晋升阶梯
    • 第11章 成为专业人士
    • 第12章 与老板和同事的相处之道
    • 第13章 不要陷入对技术的狂热之中
    • 第14章 如何辞职并开始为自己工作
    • 第15章 如何成为自由职业者
    • 第16章 如何成为一名企业家
    • 第17章 如何开始创业
    • 第18章 远程工作
  • 第二篇 自我营销
    • 第19章 自我营销基础课
    • 第20章 如何打造个人品牌
    • 第21章 如何创建大获成功的博客
    • 第22章 在YouTube上创立自己的专栏
    • 第23章 为何为他人增加价值非常重要
    • 第24章 善于运用社交媒体提升自己的品牌
    • 第25章 演讲、培训和报告
    • 第26章 著书立说
  • 第三篇 学习
    • 第27章 学习怎样学习
    • 第28章 我的“十步学习法”
    • 第29章 第 1 步到第 6 步:这些步骤只做一次
    • 第30章 第7步到第10步:循环往复
    • 第31章 如何寻找导师
    • 第32章 如何成为导师
    • 第33章 为何说教学相长
    • 第34章 你需要一个大学学位吗
    • 第35章 发现自己的知识短板
  • 第四篇 生产力
    • 第36章 一切始于专注
    • 第37章 我的私房“生产力提升计划”
    • 第38章 番茄工作法
    • 第39章 我的“定额工作法”
    • 第40章 对自己负责
    • 第41章 为什么说多任务并行弊大于利
    • 第42章 如何应对职业倦怠
    • 第43章 你是怎样浪费掉时间的
    • 第44章 形成惯例的重要性
    • 第45章 如何培养好习惯
    • 第46章 分解任务会提高生产力
    • 第47章 努力工作的价值,以及为什么你总是逃避努力工作
    • 第48章 任何行动都比不采取行动好
  • 第五篇 理财
    • 第49章 合理支配你的薪水
    • 第50章 怎样进行薪酬谈判
    • 第51章 为何说房地产是最好的投资
    • 第52章 你真的了解自己的退休计划吗
    • 第53章 债务的危害
    • 第54章 如何创造真正的财富
    • 第55章 我是如何做到33岁退休的
  • 第六篇 健身
    • 第56章 健身的好处
    • 第57章 设定你的健身目标
    • 第58章 如何减肥(或者增重)
    • 第59章 健身的动力从何而来
    • 第60章 增肌
    • 第61章 如何获得完美腹肌
    • 第62章 开始跑步
    • 第63章 我的减脂增肌秘诀
    • 第64章 站立式办公及其他窍门
    • 第65章 利用高科技装备健身
  • 第七篇 心态
    • 第66章 心智是如何影响身体的
    • 第67章 一切都源自积极心态
    • 第68章 如何改变你的自我形象
    • 第69章 爱情与恋爱
    • 第70章 我的私房成功书单
    • 第71章 不要害怕失败
    • 第72章 走出舒适区
    • 第73章 斯多葛哲学,以及它如何改变你的生活
    • 第74章 结束语

《软技能2:软件开发者职业生涯指南》

  • 第一篇 入行成为软件开发者
    • 第2章 跬步千里:如何入行
    • 第3章 傍身之技:你需要拥有的技术技能
    • 第4章 格物致知:如何拓展技术技能
    • 第5章 无问西东:到底应该学哪门编程语言
    • 第6章 姗姗学步:如何学好你的第一门编程语言
    • 第7章 巍巍学府:通过上大学深造成为软件开发者
    • 第8章 躬行实践:通过参加编程训练营成为软件开发者
    • 第9章 自学成才:通过自学成为软件开发者
  • 第二篇 找到一份工作
    • 第10章 初出茅庐:怎样获得实习机会
    • 第11章 柳暗花明:没有经验如何找到工作
    • 第12章 独辟蹊径:找工作时的创新思维
    • 第13章 移樽就教:怎样写简历
    • 第14章 锦囊妙计:如何对付面试
    • 第15章 唇枪舌剑:关于薪酬谈判
    • 第16章 山高水长:如果要离职,该怎么做
    • 第17章 半路出家:如何从其他行业转行成为软件开发者
    • 第18章 遇水叠桥:如何从测试或者其他技术性角色转型成为软件开发者
    • 第19章 掎摭利病:合同制员工与领薪制正式雇员之间的比较
    • 第20章 去梯之言:从未公开过的招聘行业运作的秘密
  • 第三篇 关于软件开发你需要知道些什么
    • 第21章 走马观花:编程语言概述
    • 第22章 知难而进:什么是Web开发
    • 第23章 前途大好:移动开发
    • 第24章 幕后英雄:后端开发
    • 第25章 游戏人生:游戏开发者的职业生涯
    • 第26章 事无巨细:DBA与DevOps
    • 第27章 高屋建瓴:软件开发方法论
    • 第28章 层层设防:测试和QA基础
    • 第29章 源头把关:测试驱动开发与单元测试
    • 第30章 清清爽爽:源代码控制
    • 第31章 步步为营:持续集成
    • 第32章 火眼金睛:调试
    • 第33章 日臻完善:代码维护
    • 第34章 实至名归:工作岗位与头衔
    • 第35章 多姿多彩:软件开发者的工作类型
  • 第四篇 软件开发者的日常工作
    • 第36章 和而不同:与同事相处
    • 第37章 顺势而为:与老板相处
    • 第38章 协力共进:与测试人员相处
    • 第39章 等量齐观:工作与生活的平衡
    • 第40章 并肩作战:与团队协作
    • 第41章 谠言嘉论:推销你的想法
    • 第42章 衣冠楚楚:如何着装
    • 第43章 谋事在人:安然渡过绩效评估
    • 第44章 光明磊落:处理偏见
    • 第45章 身先士卒:处于领导的位置
    • 第46章 前程似锦:获得提拔与晋升
    • 第47章 巾帼英雄:科技女性
  • 第五篇 推进你的职业发展
    • 第48章 名满天下:建立声誉
    • 第49章 广结善缘:社交与人脉
    • 第50章 与时俱进:让你的技能紧跟上时代
    • 第51章 行家里手:做专才还是做通才
    • 第52章 传经布道:演讲和参加会议
    • 第53章 笔耕不辍:创建博客
    • 第54章 海阔天空:做自由职业者乃至创业
    • 第55章 策马扬鞭:职业发展路径
    • 第56章 未雨绸缪:工作稳定性与工作保障
    • 第57章 学无止境:培训与资格认证
    • 第58章 乐此不疲:兼职项目
    • 第59章 开卷有益:要读的好书
    • 第60章 余音袅袅:结束语

读后感

\ No newline at end of file + 程序员的职业和生存指南 - 知行斋
Skip to content

程序员的职业和生存指南 - 读约翰·森梅兹的2本书有感

2024年元旦后读了约翰·森梅兹(John Sonmez)的2本书,很有共鸣,产生了写读书感想的念头,借机也梳理了我个人的观点和想法,于是便有了下面这些文章。

目录

《软技能2:软件开发者职业生涯指南》

  • 第一篇 入行成为软件开发者
    • 第2章 跬步千里:如何入行
    • 第3章 傍身之技:你需要拥有的技术技能
    • 第4章 格物致知:如何拓展技术技能
    • 第5章 无问西东:到底应该学哪门编程语言
    • 第6章 姗姗学步:如何学好你的第一门编程语言
    • 第7章 巍巍学府:通过上大学深造成为软件开发者
    • 第8章 躬行实践:通过参加编程训练营成为软件开发者
    • 第9章 自学成才:通过自学成为软件开发者
  • 第二篇 找到一份工作
    • 第10章 初出茅庐:怎样获得实习机会
    • 第11章 柳暗花明:没有经验如何找到工作
    • 第12章 独辟蹊径:找工作时的创新思维
    • 第13章 移樽就教:怎样写简历
    • 第14章 锦囊妙计:如何对付面试
    • 第15章 唇枪舌剑:关于薪酬谈判
    • 第16章 山高水长:如果要离职,该怎么做
    • 第17章 半路出家:如何从其他行业转行成为软件开发者
    • 第18章 遇水叠桥:如何从测试或者其他技术性角色转型成为软件开发者
    • 第19章 掎摭利病:合同制员工与领薪制正式雇员之间的比较
    • 第20章 去梯之言:从未公开过的招聘行业运作的秘密
  • 第三篇 关于软件开发你需要知道些什么
    • 第21章 走马观花:编程语言概述
    • 第22章 知难而进:什么是Web开发
    • 第23章 前途大好:移动开发
    • 第24章 幕后英雄:后端开发
    • 第25章 游戏人生:游戏开发者的职业生涯
    • 第26章 事无巨细:DBA与DevOps
    • 第27章 高屋建瓴:软件开发方法论
    • 第28章 层层设防:测试和QA基础
    • 第29章 源头把关:测试驱动开发与单元测试
    • 第30章 清清爽爽:源代码控制
    • 第31章 步步为营:持续集成
    • 第32章 火眼金睛:调试
    • 第33章 日臻完善:代码维护
    • 第34章 实至名归:工作岗位与头衔
    • 第35章 多姿多彩:软件开发者的工作类型
  • 第四篇 软件开发者的日常工作
    • 第36章 和而不同:与同事相处
    • 第37章 顺势而为:与老板相处
    • 第38章 协力共进:与测试人员相处
    • 第39章 等量齐观:工作与生活的平衡
    • 第40章 并肩作战:与团队协作
    • 第41章 谠言嘉论:推销你的想法
    • 第42章 衣冠楚楚:如何着装
    • 第43章 谋事在人:安然渡过绩效评估
    • 第44章 光明磊落:处理偏见
    • 第45章 身先士卒:处于领导的位置
    • 第46章 前程似锦:获得提拔与晋升
    • 第47章 巾帼英雄:科技女性
  • 第五篇 推进你的职业发展
    • 第48章 名满天下:建立声誉
    • 第49章 广结善缘:社交与人脉
    • 第50章 与时俱进:让你的技能紧跟上时代
    • 第51章 行家里手:做专才还是做通才
    • 第52章 传经布道:演讲和参加会议
    • 第53章 笔耕不辍:创建博客
    • 第54章 海阔天空:做自由职业者乃至创业
    • 第55章 策马扬鞭:职业发展路径
    • 第56章 未雨绸缪:工作稳定性与工作保障
    • 第57章 学无止境:培训与资格认证
    • 第58章 乐此不疲:兼职项目
    • 第59章 开卷有益:要读的好书
    • 第60章 余音袅袅:结束语

《软技能:代码之外的生存指南(第2版)》

  • 第一篇 职业
    • 第2章 经营自己的职业生涯就像经营一家企业
    • 第3章 如何给自己设定好职业目标
    • 第4章 拓展自己的人际交往能力
    • 第5章 创建一份屡试屡验的简历
    • 第6章 破解面试之道
    • 第7章 软件开发人员的三条职业路径
    • 第8章 为什么你需要走专业化道路
    • 第9章 公司与公司是不一样的
    • 第10章 攀登晋升阶梯
    • 第11章 成为专业人士
    • 第12章 与老板和同事的相处之道
    • 第13章 不要陷入对技术的狂热之中
    • 第14章 如何辞职并开始为自己工作
    • 第15章 如何成为自由职业者
    • 第16章 如何成为一名企业家
    • 第17章 如何开始创业
    • 第18章 远程工作
  • 第二篇 自我营销
    • 第19章 自我营销基础课
    • 第20章 如何打造个人品牌
    • 第21章 如何创建大获成功的博客
    • 第22章 在YouTube上创立自己的专栏
    • 第23章 为何为他人增加价值非常重要
    • 第24章 善于运用社交媒体提升自己的品牌
    • 第25章 演讲、培训和报告
    • 第26章 著书立说
  • 第三篇 学习
    • 第27章 学习怎样学习
    • 第28章 我的“十步学习法”
    • 第29章 第 1 步到第 6 步:这些步骤只做一次
    • 第30章 第7步到第10步:循环往复
    • 第31章 如何寻找导师
    • 第32章 如何成为导师
    • 第33章 为何说教学相长
    • 第34章 你需要一个大学学位吗
    • 第35章 发现自己的知识短板
  • 第四篇 生产力
    • 第36章 一切始于专注
    • 第37章 我的私房“生产力提升计划”
    • 第38章 番茄工作法
    • 第39章 我的“定额工作法”
    • 第40章 对自己负责
    • 第41章 为什么说多任务并行弊大于利
    • 第42章 如何应对职业倦怠
    • 第43章 你是怎样浪费掉时间的
    • 第44章 形成惯例的重要性
    • 第45章 如何培养好习惯
    • 第46章 分解任务会提高生产力
    • 第47章 努力工作的价值,以及为什么你总是逃避努力工作
    • 第48章 任何行动都比不采取行动好
  • 第五篇 理财
    • 第49章 合理支配你的薪水
    • 第50章 怎样进行薪酬谈判
    • 第51章 为何说房地产是最好的投资
    • 第52章 你真的了解自己的退休计划吗
    • 第53章 债务的危害
    • 第54章 如何创造真正的财富
    • 第55章 我是如何做到33岁退休的
  • 第六篇 健身
    • 第56章 健身的好处
    • 第57章 设定你的健身目标
    • 第58章 如何减肥(或者增重)
    • 第59章 健身的动力从何而来
    • 第60章 增肌
    • 第61章 如何获得完美腹肌
    • 第62章 开始跑步
    • 第63章 我的减脂增肌秘诀
    • 第64章 站立式办公及其他窍门
    • 第65章 利用高科技装备健身
  • 第七篇 心态
    • 第66章 心智是如何影响身体的
    • 第67章 一切都源自积极心态
    • 第68章 如何改变你的自我形象
    • 第69章 爱情与恋爱
    • 第70章 我的私房成功书单
    • 第71章 不要害怕失败
    • 第72章 走出舒适区
    • 第73章 斯多葛哲学,以及它如何改变你的生活
    • 第74章 结束语

一、入行

核心思想:

  • 成为一名软件开发者不仅仅是学习编程语言,还需要具备各种软技能,例如沟通能力、团队合作能力和解决问题的能力。
  • 本篇介绍了如何成为一名软件开发者的步骤,包括:
  • 评估你的兴趣和能力
  • 学习编程语言
  • 建立你的作品集
  • 准备简历和求职信
  • 面试技巧
  • 薪酬谈判

主要内容:

  • 评估你的兴趣和能力: 考虑你是否真的对软件开发感兴趣,并评估你的学习能力和解决问题的能力。
  • 学习编程语言: 选择一种或多种编程语言进行学习,并推荐一些学习资源。
  • 建立你的作品集: 开发一些个人项目或参与开源项目,以展示你的技能和经验。
  • 准备简历和求职信: 突出你的技能和经验,并针对不同的职位进行调整。
  • 面试技巧: 了解面试的常见问题,并练习你的回答。
  • 薪酬谈判: 了解你的薪酬范围,并学会如何谈判。

关键步骤:

  1. 自我评估: 评估你的兴趣、能力和目标。
  2. 学习计划: 制定学习编程语言的计划,并选择合适的学习资源。
  3. 实践练习: 通过开发个人项目或参与开源项目来练习你的技能。
  4. 求职准备: 准备简历、求职信和面试技巧。
  5. 持续学习: 不断学习新的技能和知识,保持竞争力。

总结:

成为一名软件开发者需要付出努力和时间。通过掌握必要的技能和知识,并做好求职准备,你就可以实现你的目标。

以下是一些具体的建议:

  • 尽早开始学习编程。 越早开始学习,你就有越多的时间来练习和提高你的技能。
  • 积极参与开源项目。 这是一个很好的学习机会,可以让你与其他开发人员合作,并展示你的技能。
  • 参加行业活动。 这是一个很好的结识其他开发人员和了解行业趋势的机会。
  • 建立自己的个人品牌。 创建一个个人网站或博客,展示你的作品和技能。
  • 保持积极主动。 不要等待机会来找你,要主动寻找机会。

以下是一些额外的补充:

  • 书中还提到了 职业规划 的重要性。设定你的职业目标,并制定实现目标的计划。
  • 书中也强调了 人脉 的重要性。建立与其他开发人员和行业专家的联系,可以帮助你获得宝贵的经验和建议。

二、找工作

核心思想:

  • 找到一份软件开发工作不仅仅是投递简历和参加面试,还需要做好充分的准备,并了解求职过程中的注意事项。
  • 本篇介绍了如何找到一份软件开发工作的步骤,包括:
  • 确定你的求职目标
  • 准备简历和求职信
  • 学习面试技巧
  • 了解薪酬谈判
  • 拓展人脉
  • 关注行业趋势

主要内容:

  • 确定你的求职目标: 明确你想要什么样的工作,并了解你所在地区的就业市场。
  • 准备简历和求职信: 突出你的技能和经验,并针对不同的职位进行调整。
  • 学习面试技巧: 了解面试的常见问题,并练习你的回答。
  • 了解薪酬谈判: 了解你的薪酬范围,并学会如何谈判。
  • 拓展人脉: 参加行业活动和建立与其他开发人员的联系,可以帮助你获得更多机会。
  • 关注行业趋势: 了解最新的技术和趋势,可以帮助你保持竞争力。

关键步骤:

  1. 自我评估: 评估你的技能、经验和目标。
  2. 求职目标: 明确你想要什么样的工作,并制定求职计划。
  3. 准备材料: 准备简历、求职信和作品集。
  4. 面试准备: 练习面试技巧,并了解常见问题。
  5. 持续学习: 不断学习新的技能和知识,保持竞争力。

总结:

找到一份软件开发工作需要付出努力和时间。通过做好充分的准备,并了解求职过程中的注意事项,你就可以提高找到理想工作的成功率。

以下是一些具体的建议:

  • 尽早开始求职。 不要等到你毕业或完成所有学习才开始求职。
  • 充分利用你的资源。 你的学校、朋友、家人和职业顾问都可以提供帮助。
  • 保持积极主动。 不要等待机会来找你,要主动寻找机会。
  • 学会推销自己。 在面试中要自信地展示你的技能和经验。
  • 不要放弃。 求职过程可能会很漫长,但不要放弃,最终你会找到一份适合你的工作。

以下是一些额外的补充:

  • 书中还提到了 实习 的重要性。实习是一个很好的获得工作经验和建立人脉的机会。
  • 书中也强调了 软技能 的重要性。良好的沟通能力、团队合作能力和解决问题的能力可以帮助你在求职中脱颖而出。

三、关于软件开发

核心思想:

  • 软件开发不仅仅是写代码,还涉及许多其他方面,例如软件设计、测试、部署和维护。
  • 本篇介绍了软件开发过程中的一些重要概念和实践,包括:
  • 软件设计原则
  • 测试方法
  • 版本控制
  • 持续集成和持续部署
  • 安全编码
  • 软件文档
  • 团队合作

主要内容:

  • 软件设计原则: 介绍了一些重要的软件设计原则,例如 SOLID 原则和可重用性。
  • 测试方法: 介绍了一些常见的测试方法,例如单元测试、集成测试和系统测试。
  • 版本控制: 介绍了版本控制的基本概念和工具,例如 Git 和 Mercurial。
  • 持续集成和持续部署: 介绍了持续集成和持续部署的概念和实践。
  • 安全编码: 介绍了一些常见的安全编码实践,例如输入验证和错误处理。
  • 软件文档: 介绍了软件文档的重要性以及如何编写文档。
  • 团队合作: 介绍了团队合作在软件开发中的重要性以及如何有效地进行团队合作。

关键步骤:

  1. 学习软件设计原则。 好的设计可以使软件更加易于理解、维护和扩展。
  2. 掌握测试方法。 测试可以确保软件的质量和可靠性。
  3. 使用版本控制工具。 版本控制可以帮助你跟踪代码的更改并回滚到之前的版本。
  4. 了解持续集成和持续部署。 持续集成和持续部署可以帮助你更快地发布软件并提高质量。
  5. 遵循安全编码实践。 安全编码可以帮助你防止软件漏洞。
  6. 编写清晰的文档。 文档可以帮助其他人理解和使用你的软件。
  7. 学会与他人合作。 团队合作可以帮助你完成更大的项目。

总结:

软件开发是一项复杂的工程,需要掌握各种知识和技能。通过学习和实践,你.

以下是一些具体的建议:

  • 阅读有关软件开发的书籍和文章。 许多优秀的资源可以帮助你学习软件开发的各个方面。
  • 参加软件开发培训课程。 培训课程可以帮助你快速掌握软件开发的最新技术和实践。
  • 参与开源项目。 这是一个很好的学习机会,可以让你与其他开发人员合作并获得经验。
  • 在个人项目中练习你的技能。 开发个人项目可以帮助你巩固你所学的知识并提高你的技能。
  • 与其他开发人员交流。 与其他开发人员交流可以帮助你学习新知识并获得新的见解。

以下是一些额外的补充:

  • 书中还提到了 专业发展 的重要性。不断学习新的技能和知识,并获得相关的认证,可以帮助你提升你的职业竞争力。
  • 书中也强调了 终身学习 的重要性。软件开发是一个快速发展的行业,你需要不断学习才能跟上最新的趋势。

四、日常工作

核心思想:

  • 软件开发者的日常工作不仅仅是写代码,还包括许多其他任务,例如沟通、协作、解决问题和学习。
  • 本篇介绍了软件开发者的日常工作内容和职责,以及如何有效地完成这些工作。

主要内容:

  • 沟通: 软件开发者需要与团队成员、客户和其他利益相关者进行有效沟通。
  • 协作: 软件开发通常是团队合作的过程,需要与他人协作才能完成任务。
  • 解决问题: 软件开发过程中会遇到各种问题,需要能够独立思考并解决问题。
  • 学习: 软件开发是一个快速发展的行业,需要不断学习才能跟上最新的技术和趋势。

关键步骤:

  1. 提高沟通能力。 清晰、简洁地表达你的想法,并学会倾听他人的意见。
  2. 学会团队合作。 与他人合作完成任务,并分享你的知识和经验。
  3. 培养解决问题的能力。 分析问题,并提出有效的解决方案。
  4. 保持终身学习的态度。 不断学习新的技能和知识,并保持对新技术的关注。

总结:

软件开发是一项充满挑战但也很有意义的工作。通过掌握必要的技能和知识,并养成良好的工作习惯,你就可以成为一名优秀的软件开发者。

以下是一些具体的建议:

  • 积极参与团队讨论。 提出你的想法,并与他人分享你的知识和经验。
  • 善于利用沟通工具。 使用电子邮件、聊天工具和其他工具与他人保持沟通。
  • 学会管理时间。 制定工作计划,并有效地利用你的时间。
  • 保持良好的工作习惯。 定期整理你的代码,并做好注释。
  • 积极参加行业活动。 这是一个很好的学习机会,可以让你与其他开发人员交流并了解最新的技术和趋势。
  • 熟悉软件开发流程。 了解每个阶段的任务和职责,并能够有效地完成这些工作。
  • 掌握必要的工具和技术。 使用合适的工具和技术可以提高你的工作效率。
  • 注重细节。 软件开发是一个需要细心的工作,要避免犯错误。
  • 善于沟通。 与团队成员、客户和其他利益相关者进行有效沟通,以确保项目顺利进行。

五、职业发展

核心思想:

  • 软件开发者的职业发展不仅仅是获得更高的职位和薪酬,更重要的是不断学习和成长,成为一名优秀的软件工程师。
  • 本篇介绍了如何推进你的职业发展的策略和方法,包括:
  • 建立个人品牌
  • 拓展人脉
  • 保持学习
  • 贡献社区
  • 寻找导师
  • 规划职业道路

主要内容:

  • 建立个人品牌: 通过博客、技术文章、开源项目等方式建立你的个人品牌,让更多的人了解你的技能和经验。
  • 拓展人脉: 参加行业活动、技术会议等,与其他软件开发者建立联系,拓展你的人脉。
  • 保持学习: 不断学习新的技能和知识,阅读书籍、参加培训课程等,保持你的竞争力。
  • 贡献社区: 参与开源项目、技术社区等,为社区做出贡献,提升你的影响力。
  • 寻找导师: 寻找一位经验丰富的软件开发者作为你的导师,可以帮助你学习和成长。
  • 规划职业道路: 明确你的职业目标,并制定计划实现你的目标。

关键步骤:

  1. 自我评估: 评估你的技能、经验和目标。
  2. 制定计划: 制定你的职业发展计划,并设定具体的目標。
  3. 行动起来: 采取行动,执行你的计划。
  4. 定期回顾: 定期回顾你的计划,并进行必要的调整。

总结:

软件开发者的职业发展是一个持续的过程。通过制定计划、采取行动 and 不断学习,你就可以实现你的职业目标,成为一名优秀的软件工程师。

以下是一些具体的建议:

  • 积极参与技术社区。 这是一个很好的学习机会,可以让你与其他开发人员交流并了解最新的技术和趋势。
  • 寻找一位导师。 一位经验丰富的导师可以帮助你学习和成长,并为你提供宝贵的建议。
  • 参加行业活动。 这是一个很好的结识其他开发人员和了解行业趋势的机会。
  • 写博客或技术文章。 这是一个分享你的知识和经验的好方法,并建立你的个人品牌。
  • 开源项目。 这是一个很好的贡献社区和学习新技能的机会。

以下是一些额外的补充:

  • 书中还提到了 工作与生活的平衡 的重要性。工作固然重要,但也要注重个人生活和健康。
  • 书中也强调了 终身学习 的重要性。软件开发是一个快速发展的行业,你需要不断学习才能跟上最新的技术和趋势。

一、职业

核心思想:

  • 软件开发人员的职业发展不仅仅是写代码,还需要掌握各种软技能,才能取得成功。
  • 本篇介绍了软件开发人员职业发展过程中需要关注的几个关键方面,包括:
  • 职业规划
  • 面试技巧
  • 沟通能力
  • 团队合作
  • 时间管理
  • 领导力

主要内容:

  • 职业规划: 设定职业目标,并制定实现目标的计划。
  • 面试技巧: 准备简历和面试材料,并练习面试技巧。
  • 沟通能力: 清晰有效地表达自己的想法和观点。
  • 团队合作: 与他人合作完成共同目标。
  • 时间管理: 高效地利用时间,完成工作任务。
  • 领导力: 领导团队完成目标。

关键步骤:

  1. 自我评估: 了解自己的优势、劣势、兴趣和技能。
  2. 设定目标: 设定短期和长期的职业目标。
  3. 制定计划: 制定实现目标的具体计划。
  4. 不断学习: 学习新技能和知识,提升自身能力。
  5. 建立人脉: 建立与其他开发人员和行业专家的联系。

总结:

软件开发人员的职业发展是一个持续学习和成长的过程。通过掌握各种软技能,可以提升自身的竞争力,在职业发展中取得成功。

以下是一些具体的建议:

  • 制定职业规划。 花时间思考你想成为一名什么样的软件开发人员,以及你想要达成的职业目标。
  • 不断学习。 软件行业发展迅速,需要不断学习新技术和知识,才能保持竞争力。
  • 建立人脉。 与其他开发人员和行业专家建立联系,可以获得宝贵的经验和建议。
  • 积极参与开源项目。 这是一个很好的方式来学习新技能,并获得其他开发人员的认可。
  • 寻找导师。 找到一位经验丰富的导师可以帮助你指引方向,并提供建议。

通过努力工作和持续学习,你一定能够在你的职业生涯中取得成功。

二、自我营销

核心思想:

  • 软件开发人员需要将自己视为产品,并进行有效的自我营销,才能在职业发展中取得成功。
  • 自我营销包括建立个人品牌、打造线上形象、积极参与社区等多个方面。

主要内容:

  • 建立个人品牌:明确自己的价值主张,并通过各种渠道将其传递给目标受众。
  • 打造线上形象:创建并维护个人网站、博客、社交媒体账号等,展示自己的专业技能和经验。
  • 积极参与社区:参加技术会议、开源项目、线上论坛等,与其他开发人员建立联系,扩大影响力。
  • 其他自我营销策略:撰写技术文章、演讲、出版书籍等,树立行业专家形象。

关键步骤:

  1. 自我评估:分析自己的优势、劣势、技能和经验,明确自己的职业目标。
  2. 制定目标:根据职业目标,确定自我营销的具体方向和策略。
  3. 执行策略:采取各种措施,建立个人品牌、打造线上形象、积极参与社区等。
  4. 持续改进:定期评估自我营销的效果,并根据需要进行调整和改进。

总结:

自我营销是软件开发人员在职业发展中不可忽视的重要技能。通过有效的自我营销,可以提升个人知名度、建立专业形象、拓展职业机会,最终实现职业目标。

以下是一些具体的建议:

  • 花时间打造你的个人品牌。 这包括创建一个个人网站或博客,并定期发布高质量的内容。 你也可以在社交媒体上积极参与,并与其他开发人员建立联系。
  • 参与开源项目。 这是一个很好的方式来展示你的技能和经验,并获得其他开发人员的认可。
  • 参加技术会议和活动。 这是一个很好的方式来学习新技术,并结识其他开发人员。
  • 撰写技术文章或书籍。 这是一个很好的方式来分享你的知识和经验,并建立你的专业形象。

通过努力工作和持续改进,你一定能够在自我营销方面取得成功。

三、学习

核心思想:

  • 学习是软件开发人员持续成长和成功的关键。
  • 本篇介绍了如何快速有效地学习新技能和知识,包括:
  • 制定学习计划
  • 选择合适的学习资源
  • 提高学习效率
  • 保持学习动力

主要内容:

  • 制定学习计划: 明确学习目标,并制定具体的学习计划。
  • 选择合适的学习资源: 选择适合自己的学习方式和资源,例如书籍、文章、视频、课程等。
  • 提高学习效率: 掌握有效的学习技巧,例如番茄工作法、费曼技巧等。
  • 保持学习动力: 保持对学习的热情和兴趣,并制定激励措施。

关键步骤:

  1. 设定目标: 明确你想要学习什么,以及你想要达到的学习目标。
  2. 制定计划: 制定具体的学习计划,包括学习内容、学习时间和学习方法等。
  3. 选择资源: 选择适合自己的学习方式和资源,并确保资源的质量和可靠性。
  4. 付诸行动: 按照计划开始学习,并定期评估学习进度和效果。
  5. 保持动力: 保持对学习的热情和兴趣,并制定激励措施。

总结:

学习是一个需要不断实践和改进的过程。通过掌握有效的学习方法,可以提高学习效率,并取得更好的学习成果。

以下是一些具体的建议:

  • 制定具体的学习目标。 目标越具体,就越容易实现。
  • 将学习任务分解成小块。 这样更容易完成,也能让你保持学习的动力。
  • 找到适合自己的学习方式。 有些人喜欢看书,有些人喜欢看视频,有些人喜欢参加课程。
  • 利用碎片时间学习。 利用通勤时间、午休时间等碎片时间学习,可以提高学习效率。
  • 与他人一起学习。 与他人一起学习可以互相鼓励,互相帮助。

通过努力学习和不断实践,你一定能够在你的职业生涯中取得成功。

四、生产力

核心思想:

  • 提高生产力是软件开发人员取得成功的关键因素之一。
  • 本篇介绍了如何提高工作效率和产出,包括:
  • 时间管理
  • 任务管理
  • 专注力
  • 沟通技巧
  • 避免干扰

主要内容:

  • 时间管理: 有效地利用时间,完成工作任务。
  • 任务管理: 制定任务计划,并有效地跟踪任务进度。
  • 专注力: 提高工作时的专注度,避免分心。
  • 沟通技巧: 清晰有效地与他人沟通,避免误解和浪费时间。
  • 避免干扰: 减少工作环境中的干扰因素,提高工作效率。

关键步骤:

  1. 评估现状: 评估当前的工作效率和产出水平。
  2. 设定目标: 设定提高生产力的目标。
  3. 制定计划: 制定具体的提高生产力的计划。
  4. 付诸行动: 按照计划开始实施,并定期评估效果。
  5. 持续改进: 不断寻找新的方法和工具来提高生产力。

总结:

提高生产力是一个需要不断实践和改进的过程。通过掌握有效的时间管理、任务管理、沟通技巧等方法,可以提高工作效率,并取得更好的工作成果。

以下是一些具体的建议:

  • 使用时间管理工具。 许多时间管理工具可以帮助你跟踪时间、制定计划和提高效率。
  • 制定任务清单。 将所有待办事项列入清单,并按照优先级排序。
  • 设定截止日期。 为每个任务设定截止日期,可以帮助你提高工作效率。
  • 避免多任务处理。 同时处理多个任务会降低效率,导致错误。
  • 创造良好的工作环境。 找到一个安静、舒适的工作环境,可以帮助你提高专注力。

通过努力提高生产力,你一定能够在你的职业生涯中取得更大的成功。

以下是一些额外的补充:

  • 书中还提到了 自动化 的重要性。通过使用自动化工具,可以将一些重复性工作自动化,从而节省时间和精力。
  • 书中也强调了 健康 的重要性。保持健康的身体和心理状态,才能更好地工作和学习。

五、理财

核心思想:

  • 理财是软件开发人员需要掌握的重要技能之一,可以帮助他们实现财务目标,并获得财务安全感。
  • 本篇介绍了理财的基本概念和原则,包括:
  • 设定财务目标
  • 制定预算
  • 投资理财
  • 退休规划
  • 避免常见的理财错误

主要内容:

  • 设定财务目标: 明确你的短期和长期的财务目标,例如购买房屋、退休养老等。
  • 制定预算: 记录你的收入和支出,并制定合理的预算计划。
  • 投资理财: 学习投资理财知识,并选择适合自己的投资方式。
  • 退休规划: 提前做好退休规划,确保退休后的生活质量。
  • 避免常见的理财错误: 了解常见的理财错误,并避免在理财过程中犯错。

关键步骤:

  1. 评估现状: 评估当前的财务状况,包括收入、支出、资产和负债等。
  2. 设定目标: 明确你的短期和长期的财务目标。
  3. 制定计划: 制定具体的理财计划,包括预算、投资和退休规划等。
  4. 付诸行动: 按照计划开始实施,并定期评估效果。
  5. 持续学习: 不断学习理财知识,并根据情况调整你的理财策略。

总结:

理财是一个需要长期坚持的过程。通过掌握理财的基本知识和技能,可以帮助你实现财务目标,并获得更好的生活。

以下是一些具体的建议:

  • 尽早开始理财。 越早开始理财,你的时间和金钱就越有价值。
  • 养成良好的消费习惯。 避免冲动消费,并学会延迟满足。
  • 定期进行财务检查。 定期检查你的财务状况,并根据需要调整你的理财计划。
  • 寻求专业帮助。 如果需要,可以寻求理财顾问的帮助。

以下是一些额外的补充:

  • 书中还提到了 保险 的重要性。通过购买保险,可以转移风险,并提供必要的保障。
  • 书中也强调了 税收规划 的重要性。通过合理的税收规划,可以减少税收负担。

六、健身

核心思想:

  • 健身是软件开发人员保持健康和活力,提高工作效率的重要途径。
  • 本篇介绍了健身的基本知识和方法,包括:
  • 制定健身目标
  • 选择适合的运动方式
  • 饮食健康
  • 睡眠充足
  • 避免久坐

主要内容:

  • 制定健身目标: 明确你的健身目标,例如减肥、增肌、提高耐力等。
  • 选择适合的运动方式: 根据你的兴趣、身体状况和时间安排,选择适合的运动方式。
  • 饮食健康: 保持健康的饮食习惯,多吃蔬菜水果、全谷物和瘦肉等。
  • 睡眠充足: 保证充足的睡眠,让身体得到充分休息。
  • 避免久坐: 避免长时间坐着不动,每小时起身活动几分钟。

关键步骤:

  1. 评估现状: 评估当前的身体状况,包括体重、体脂率、肌肉量等。
  2. 设定目标: 明确你的健身目标。
  3. 制定计划: 制定具体的健身计划,包括运动方式、饮食和睡眠等。
  4. 付诸行动: 按照计划开始实施,并定期评估效果。
  5. 保持坚持: 健身是一个需要长期坚持的过程,不要轻易放弃。

总结:

健身是一个需要长期坚持的过程。通过掌握健身的基本知识和方法,可以帮助你保持健康和活力,提高工作效率,并获得更好的生活。

以下是一些具体的建议:

  • 循序渐进,不要急于求成。 刚开始健身时,不要进行过于剧烈的运动,以免造成运动损伤。
  • 找到适合自己的运动方式。 选择你喜欢的运动方式,这样你才能坚持下去。
  • 将健身融入到你的日常生活。 例如,你可以每天步行上下班,或者利用午休时间进行锻炼。
  • 寻找健身伙伴。 与朋友或家人一起健身,可以互相鼓励,互相帮助。

以下是一些额外的补充:

  • 书中还提到了 压力管理 的重要性。通过合理的压力管理,可以减少压力对身体的负面影响。
  • 书中也强调了 心理健康 的重要性。保持良好的心理健康,才能更好地工作和生活。

七、心态

核心思想:

  • 心态是软件开发人员取得成功的重要因素之一。拥有积极乐观的心态,可以帮助他们克服困难,取得更大的成就。
  • 本篇介绍了如何培养积极乐观的心态,包括:
  • 认识自己的思维模式
  • 挑战负面思维
  • 练习正念
  • 培养感恩之心
  • 保持成长型思维

主要内容:

  • 认识自己的思维模式: 了解自己的思维模式,识别常见的思维误区。
  • 挑战负面思维: 挑战负面想法,用积极的想法替换它们。
  • 练习正念: 练习正念,活在当下,专注于你现在所做的事情。
  • 培养感恩之心: 培养感恩之心,学会欣赏你所拥有的。
  • 保持成长型思维: 相信自己可以通过努力学习和成长,不断进步。

关键步骤:

  1. 自我觉察: 观察你的想法和感受,并了解它们是如何影响你的行为的。
  2. 挑战负面思维: 当你出现负面想法时,问一问自己这些想法是否合理,并用更积极的想法替换它们。
  3. 练习正念: 每天花一些时间练习正念,例如冥想或瑜伽。
  4. 感恩练习: 写感恩日记,或者定期列出你所感激的事情。
  5. 保持成长型思维: 遇到挑战时,不要轻易放弃,相信自己可以通过努力克服困难。

总结:

拥有积极乐观的心态,可以帮助软件开发人员在职业发展中取得更大的成就。通过练习和自我觉察,可以培养积极乐观的心态,并克服困难,取得成功。

以下是一些具体的建议:

  • 阅读励志书籍和文章。 积极的书籍和文章可以帮助你建立积极的思维模式。
  • 与积极乐观的人交朋友。 与积极乐观的人在一起,可以帮助你提升自己的心态。
  • 帮助他人。 帮助他人可以让你感到快乐和满足,并提升你的自信心。
  • 学会放松。 压力会造成负面情绪,因此要学会放松,例如运动、冥想或听音乐。

以下是一些额外的补充:

  • 书中还提到了 时间管理 的重要性。通过合理的安排时间,可以避免压力和焦虑。
  • 书中也强调了 睡眠 的重要性。充足的睡眠可以帮助你保持良好的精神状态。
\ No newline at end of file diff --git a/search/search_index.json b/search/search_index.json index 3b6fbc93..60a043f2 100644 --- a/search/search_index.json +++ b/search/search_index.json @@ -1 +1 @@ -{"config":{"indexing":"full","lang":["en"],"min_search_length":3,"prebuild_index":false,"separator":"[\\s\\-]+"},"docs":[{"location":"","text":"\u77e5\u884c\u658b \u00b6 1.Linux \u00b6 1.1.Linux SRE \u00b6 \u7b2c\u4e00\u7ae0 Linux\u57fa\u7840 \u7b2c\u4e8c\u7ae0 \u6587\u4ef6\u7cfb\u7edf \u7b2c\u4e09\u7ae0 \u8eab\u4efd\u4e0e\u5b89\u5168 \u7b2c\u56db\u7ae0 \u6587\u672c\u7f16\u8f91 \u7b2c\u4e94\u7ae0 \u6b63\u5219\u8868\u8fbe\u5f0f \u7b2c\u516d\u7ae0 \u6587\u4ef6\u67e5\u627e \u7b2c\u4e03\u7ae0 \u6587\u4ef6\u6253\u5305\u548c\u89e3\u5305 1.2.SUSE Linux Administration \u00b6 Linux File System Overview Useful Commands Shell 1.3.SUSE Enterprise Storage Foundation \u00b6 SUSE Enterprise Storage Foundation SUSE Enterprise Storage Basic Operation 2.Kubernetes \u00b6 2.1.CKA Learning Memo \u00b6 Installation Single Node Installation Multiple Nodes Installation Installation on Aliyun ECS Docker Fundamentals Foundamentals Memo Overview kubectl basics Core Kubernetes Pod Deployment Service Application Modeling Namespace StatefulSet DaemonSet Job and Cronjob Configuration Secrets Persistence Role Based Access Control (RBAC) Ingress Advanced Kubernetes Scheduling Horizontal Pod Autoscaling Policy Network Policy Cluster Management Operating Kubernetes Troubleshooting Health Check Helming Topics Operations on Resources Health Check Calico Installation Kyma 2.2.CKA\u5b66\u4e60\u7b14\u8bb0 \u00b6 \u5b89\u88c5 \u5355\u8282\u70b9\u865a\u62df\u673a\u5b89\u88c5Kubernetes \u591a\u8282\u70b9\u865a\u62df\u673a\u5b89\u88c5Kubernetes \u963f\u91cc\u4e91ECS\u5b89\u88c5Kubernetes Docker Docker\u57fa\u7840 \u57fa\u7840\u77e5\u8bc6 Kubernetes\u968f\u7b14 Kubernetes\u96c6\u7fa4\u6982\u89c8 kubectl\u57fa\u7840 \u6838\u5fc3\u6982\u5ff5 Pod Deployment Service \u5e94\u7528\u4f53\u7cfb Namespace StatefulSet DaemonSet Job and Cronjob Configuration secrets Persistence RBAC\u9274\u6743 Ingress-nginx \u8fdb\u9636\u6982\u5ff5 Scheduling Horizontal Pod Autoscaling (HPA) Policy Network Policy Cluster Management \u65e5\u5e38\u7ef4\u62a4 Troubleshooting \u5065\u5eb7\u68c0\u67e5 Helm Chart \u4e3b\u9898\u8ba8\u8bba Kubernetes\u8d44\u6e90\u5e38\u89c1\u64cd\u4f5c \u5065\u5eb7\u68c0\u67e5 \u5b89\u88c5Calico Demos Build CAP Application on Kyma 3.Python \u00b6 3.1.Python\u57fa\u7840 \u00b6 Python\u5b89\u88c5 Python\u8bed\u8a00\u57fa\u7840 Python\u6253\u5305\u548c\u89e3\u5305 Python\u5185\u7f6e\u51fd\u6570\u53ca\u6587\u4ef6 Python\u9762\u5411\u5bf9\u8c61\u6982\u5ff5 Python\u9762\u5411\u5bf9\u8c61\u4e09\u5927\u7279\u6027 3.2.Python\u6570\u636e\u5206\u6790\u57fa\u7840 \u00b6 NumPy\u57fa\u7840 NumPy\u8fdb\u9636 Pandas\u5165\u95e8 \u6570\u636e\u8f7d\u5165\u3001\u5b58\u50a8\u53ca\u6587\u4ef6\u683c\u5f0f \u6570\u636e\u6e05\u6d17\u4e0e\u51c6\u5907 \u6570\u636e\u89c4\u6574\uff1a\u8fde\u63a5\u3001\u8054\u5408\u4e0e\u91cd\u5851 \u7ed8\u56fe\u4e0e\u53ef\u89c6\u5316 \u6570\u636e\u805a\u5408\u4e0e\u5206\u7ec4\u64cd\u4f5c \u65f6\u95f4\u5e8f\u5217 \u9ad8\u9636pandas Python\u5efa\u6a21\u5e93\u4ecb\u7ecd 3.3.\u6570\u636e\u7ed3\u6784\u548c\u7b97\u6cd5 \u00b6 1.\u57fa\u7840\u77e5\u8bc6\u56de\u987e 2.\u591a\u9879\u96c6\u7684\u6982\u8ff0 3.\u641c\u7d22\u3001\u6392\u5e8f\u4ee5\u53ca\u590d\u6742\u5ea6\u5206\u6790 4.\u6570\u7ec4\u548c\u94fe\u63a5\u7ed3\u6784 5.\u63a5\u53e3\u3001\u5b9e\u73b0\u548c\u591a\u6001 6.\u7ee7\u627f\u4e0e\u62bd\u8c61\u7c7b 3.5.Effective Python \u00b6 \u7b2c1\u7ae0\u3000\u57f9\u517bPythonic\u601d\u7ef4 \u7b2c1\u6761\u3000\u67e5\u8be2\u81ea\u5df1\u4f7f\u7528\u7684Python\u7248\u672c \u7b2c2\u6761\u3000\u9075\u5faaPEP 8\u98ce\u683c\u6307\u5357 \u7b2c3\u6761\u3000\u4e86\u89e3bytes\u4e0estr\u7684\u533a\u522b \u7b2c4\u6761\u3000\u7528\u652f\u6301\u63d2\u503c\u7684f-string\u53d6\u4ee3C\u98ce\u683c\u7684\u683c\u5f0f\u5b57\u7b26\u4e32\u4e0estr.format\u65b9\u6cd5 \u7b2c5\u6761\u3000\u7528\u8f85\u52a9\u51fd\u6570\u53d6\u4ee3\u590d\u6742\u7684\u8868\u8fbe\u5f0f \u7b2c6\u6761\u3000\u628a\u6570\u636e\u7ed3\u6784\u76f4\u63a5\u62c6\u5206\u5230\u591a\u4e2a\u53d8\u91cf\u91cc\uff0c\u4e0d\u8981\u4e13\u95e8\u901a\u8fc7\u4e0b\u6807\u8bbf\u95ee \u7b2c7\u6761\u3000\u5c3d\u91cf\u7528enumerate\u53d6\u4ee3range \u7b2c8\u6761\u3000\u7528zip\u51fd\u6570\u540c\u65f6\u904d\u5386\u4e24\u4e2a\u8fed\u4ee3\u5668 \u7b2c9\u6761\u3000\u4e0d\u8981\u5728for\u4e0ewhile\u5faa\u73af\u540e\u9762\u5199else\u5757 \u7b2c10\u6761\u3000\u7528\u8d4b\u503c\u8868\u8fbe\u5f0f\u51cf\u5c11\u91cd\u590d\u4ee3\u7801 \u7b2c2\u7ae0\u3000\u5217\u8868\u4e0e\u5b57\u5178 \u7b2c11\u6761\u3000\u5b66\u4f1a\u5bf9\u5e8f\u5217\u505a\u5207\u7247 \u7b2c12\u6761\u3000\u4e0d\u8981\u5728\u5207\u7247\u91cc\u540c\u65f6\u6307\u5b9a\u8d77\u6b62\u4e0b\u6807\u4e0e\u6b65\u8fdb \u7b2c13\u6761\u3000\u901a\u8fc7\u5e26\u661f\u53f7\u7684unpacking\u64cd\u4f5c\u6765\u6355\u83b7\u591a\u4e2a\u5143\u7d20\uff0c\u4e0d\u8981\u7528\u5207\u7247 \u7b2c14\u6761\u3000\u7528sort\u65b9\u6cd5\u7684key\u53c2\u6570\u6765\u8868\u793a\u590d\u6742\u7684\u6392\u5e8f\u903b\u8f91 \u7b2c15\u6761\u3000\u4e0d\u8981\u8fc7\u5206\u4f9d\u8d56\u7ed9\u5b57\u5178\u6dfb\u52a0\u6761\u76ee\u65f6\u6240\u7528\u7684\u987a\u5e8f \u7b2c16\u6761\u3000\u7528get\u5904\u7406\u952e\u4e0d\u5728\u5b57\u5178\u4e2d\u7684\u60c5\u51b5\uff0c\u4e0d\u8981\u4f7f\u7528in\u4e0eKeyError \u7b2c17\u6761\u3000\u7528defaultdict\u5904\u7406\u5185\u90e8\u72b6\u6001\u4e2d\u7f3a\u5931\u7684\u5143\u7d20\uff0c\u800c\u4e0d\u8981\u7528setdefault \u7b2c18\u6761\u3000\u5b66\u4f1a\u5229\u7528__missing__\u6784\u9020\u4f9d\u8d56\u952e\u7684\u9ed8\u8ba4\u503c \u7b2c3\u7ae0\u3000\u51fd\u6570 \u7b2c19\u6761\u3000\u4e0d\u8981\u628a\u51fd\u6570\u8fd4\u56de\u7684\u591a\u4e2a\u6570\u503c\u62c6\u5206\u5230\u4e09\u4e2a\u4ee5\u4e0a\u7684\u53d8\u91cf\u4e2d \u7b2c20\u6761\u3000\u9047\u5230\u610f\u5916\u72b6\u51b5\u65f6\u5e94\u8be5\u629b\u51fa\u5f02\u5e38\uff0c\u4e0d\u8981\u8fd4\u56deNone \u7b2c21\u6761\u3000\u4e86\u89e3\u5982\u4f55\u5728\u95ed\u5305\u91cc\u9762\u4f7f\u7528\u5916\u56f4\u4f5c\u7528\u57df\u4e2d\u7684\u53d8\u91cf \u7b2c22\u6761\u3000\u7528\u6570\u91cf\u53ef\u53d8\u7684\u4f4d\u7f6e\u53c2\u6570\u7ed9\u51fd\u6570\u8bbe\u8ba1\u6e05\u6670\u7684\u53c2\u6570\u5217\u8868 \u7b2c23\u6761\u3000\u7528\u5173\u952e\u5b57\u53c2\u6570\u6765\u8868\u793a\u53ef\u9009\u7684\u884c\u4e3a \u7b2c24\u6761\u3000\u7528None\u548cdocstring\u6765\u63cf\u8ff0\u9ed8\u8ba4\u503c\u4f1a\u53d8\u7684\u53c2\u6570 \u7b2c25\u6761\u3000\u7528\u53ea\u80fd\u4ee5\u5173\u952e\u5b57\u6307\u5b9a\u548c\u53ea\u80fd\u6309\u4f4d\u7f6e\u4f20\u5165\u7684\u53c2\u6570\u6765\u8bbe\u8ba1\u6e05\u6670\u7684\u53c2\u6570\u5217\u8868 \u7b2c26\u6761\u3000\u7528functools.wraps\u5b9a\u4e49\u51fd\u6570\u4fee\u9970\u5668 \u7b2c4\u7ae0\u3000\u63a8\u5bfc\u4e0e\u751f\u6210 \u7b2c27\u6761\u3000\u7528\u5217\u8868\u63a8\u5bfc\u53d6\u4ee3map\u4e0efilter \u7b2c28\u6761\u3000\u63a7\u5236\u63a8\u5bfc\u903b\u8f91\u7684\u5b50\u8868\u8fbe\u5f0f\u4e0d\u8981\u8d85\u8fc7\u4e24\u4e2a \u7b2c29\u6761\u3000\u7528\u8d4b\u503c\u8868\u8fbe\u5f0f\u6d88\u9664\u63a8\u5bfc\u4e2d\u7684\u91cd\u590d\u4ee3\u7801 \u7b2c30\u6761\u3000\u4e0d\u8981\u8ba9\u51fd\u6570\u76f4\u63a5\u8fd4\u56de\u5217\u8868\uff0c\u5e94\u8be5\u8ba9\u5b83\u9010\u4e2a\u751f\u6210\u5217\u8868\u91cc\u7684\u503c \u7b2c31\u6761\u3000\u8c28\u614e\u5730\u8fed\u4ee3\u51fd\u6570\u6240\u6536\u5230\u7684\u53c2\u6570 \u7b2c32\u6761\u3000\u8003\u8651\u7528\u751f\u6210\u5668\u8868\u8fbe\u5f0f\u6539\u5199\u6570\u636e\u91cf\u8f83\u5927\u7684\u5217\u8868\u63a8\u5bfc \u7b2c33\u6761\u3000\u901a\u8fc7yield from\u628a\u591a\u4e2a\u751f\u6210\u5668\u8fde\u8d77\u6765\u7528 \u7b2c34\u6761\u3000\u4e0d\u8981\u7528send\u7ed9\u751f\u6210\u5668\u6ce8\u5165\u6570\u636e \u7b2c35\u6761\u3000\u4e0d\u8981\u901a\u8fc7throw\u53d8\u6362\u751f\u6210\u5668\u7684\u72b6\u6001 \u7b2c36\u6761\u3000\u8003\u8651\u7528itertools\u62fc\u88c5\u8fed\u4ee3\u5668\u4e0e\u751f\u6210\u5668 \u7b2c5\u7ae0\u3000\u7c7b\u4e0e\u63a5\u53e3 \u7b2c37\u6761\u3000\u7528\u7ec4\u5408\u8d77\u6765\u7684\u7c7b\u6765\u5b9e\u73b0\u591a\u5c42\u7ed3\u6784\uff0c\u4e0d\u8981\u7528\u5d4c\u5957\u7684\u5185\u7f6e\u7c7b\u578b \u7b2c38\u6761\u3000\u8ba9\u7b80\u5355\u7684\u63a5\u53e3\u63a5\u53d7\u51fd\u6570\uff0c\u800c\u4e0d\u662f\u7c7b\u7684\u5b9e\u4f8b \u7b2c39\u6761\u3000\u901a\u8fc7@classmethod\u591a\u6001\u6765\u6784\u9020\u540c\u4e00\u4f53\u7cfb\u4e2d\u7684\u5404\u7c7b\u5bf9\u8c61 \u7b2c40\u6761\u3000\u901a\u8fc7super\u521d\u59cb\u5316\u8d85\u7c7b \u7b2c41\u6761\u3000\u8003\u8651\u7528mix-in\u7c7b\u6765\u8868\u793a\u53ef\u7ec4\u5408\u7684\u529f\u80fd \u7b2c42\u6761\u3000\u4f18\u5148\u8003\u8651\u7528public\u5c5e\u6027\u8868\u793a\u5e94\u53d7\u4fdd\u62a4\u7684\u6570\u636e\uff0c\u4e0d\u8981\u7528private\u5c5e\u6027\u8868\u793a \u7b2c43\u6761\u3000\u81ea\u5b9a\u4e49\u7684\u5bb9\u5668\u7c7b\u578b\u5e94\u8be5\u4ececollections.abc\u7ee7\u627f \u7b2c6\u7ae0\u3000\u5143\u7c7b\u4e0e\u5c5e\u6027 \u7b2c44\u6761\u3000\u7528\u7eaf\u5c5e\u6027\u4e0e\u4fee\u9970\u5668\u53d6\u4ee3\u65e7\u5f0f\u7684setter\u4e0egetter\u65b9\u6cd5 \u7b2c45\u6761\u3000\u8003\u8651\u7528@property\u5b9e\u73b0\u65b0\u7684\u5c5e\u6027\u8bbf\u95ee\u903b\u8f91\uff0c\u4e0d\u8981\u6025\u7740\u91cd\u6784\u539f\u6709\u7684\u4ee3\u7801 \u7b2c46\u6761\u3000\u7528\u63cf\u8ff0\u7b26\u6765\u6539\u5199\u9700\u8981\u590d\u7528\u7684@property\u65b9\u6cd5 \u7b2c47\u6761\u3000\u9488\u5bf9\u60f0\u6027\u5c5e\u6027\u4f7f\u7528__getattr__\u3001 getattribute__\u53ca__setattr \u7b2c48\u6761\u3000\u7528__init_subclass__\u9a8c\u8bc1\u5b50\u7c7b\u5199\u5f97\u662f\u5426\u6b63\u786e \u7b2c49\u6761\u3000\u7528__init_subclass__\u8bb0\u5f55\u73b0\u6709\u7684\u5b50\u7c7b \u7b2c50\u6761\u3000\u7528__set_name__\u7ed9\u7c7b\u5c5e\u6027\u52a0\u6ce8\u89e3 \u7b2c51\u6761\u3000\u4f18\u5148\u8003\u8651\u901a\u8fc7\u7c7b\u4fee\u9970\u5668\u6765\u63d0\u4f9b\u53ef\u7ec4\u5408\u7684\u6269\u5145\u529f\u80fd\uff0c\u4e0d\u8981\u4f7f\u7528\u5143\u7c7b \u7b2c7\u7ae0\u3000\u5e76\u53d1\u4e0e\u5e76\u884c \u7b2c52\u6761\u3000\u7528subprocess\u7ba1\u7406\u5b50\u8fdb\u7a0b \u7b2c53\u6761\u3000\u53ef\u4ee5\u7528\u7ebf\u7a0b\u6267\u884c\u963b\u585e\u5f0fI/O\uff0c\u4f46\u4e0d\u8981\u7528\u5b83\u505a\u5e76\u884c\u8ba1\u7b97 \u7b2c54\u6761\u3000\u5229\u7528Lock\u9632\u6b62\u591a\u4e2a\u7ebf\u7a0b\u4e89\u7528\u540c\u4e00\u4efd\u6570\u636e \u7b2c55\u6761\u3000\u7528Queue\u6765\u534f\u8c03\u5404\u7ebf\u7a0b\u4e4b\u95f4\u7684\u5de5\u4f5c\u8fdb\u5ea6 \u7b2c56\u6761\u3000\u5b66\u4f1a\u5224\u65ad\u4ec0\u4e48\u573a\u5408\u5fc5\u987b\u505a\u5e76\u53d1 \u7b2c57\u6761\u3000\u4e0d\u8981\u5728\u6bcf\u6b21fan-out\u65f6\u90fd\u65b0\u5efa\u4e00\u6279Thread\u5b9e\u4f8b \u7b2c58\u6761\u3000\u5b66\u4f1a\u6b63\u786e\u5730\u91cd\u6784\u4ee3\u7801\uff0c\u4ee5\u4fbf\u7528Queue\u505a\u5e76\u53d1 \u7b2c59\u6761\u3000\u5982\u679c\u5fc5\u987b\u7528\u7ebf\u7a0b\u505a\u5e76\u53d1\uff0c\u90a3\u5c31\u8003\u8651\u901a\u8fc7ThreadPoolExecutor\u5b9e\u73b0 \u7b2c60\u6761\u3000\u7528\u534f\u7a0b\u5b9e\u73b0\u9ad8\u5e76\u53d1\u7684I/O \u7b2c61\u6761\u3000\u5b66\u4f1a\u7528asyncio\u6539\u5199\u90a3\u4e9b\u901a\u8fc7\u7ebf\u7a0b\u5b9e\u73b0\u7684I/O \u7b2c62\u6761\u3000\u7ed3\u5408\u7ebf\u7a0b\u4e0e\u534f\u7a0b\uff0c\u5c06\u4ee3\u7801\u987a\u5229\u8fc1\u79fb\u5230asyncio \u7b2c63\u6761\u3000\u8ba9asyncio\u7684\u4e8b\u4ef6\u5faa\u73af\u4fdd\u6301\u7545\u901a\uff0c\u4ee5\u4fbf\u8fdb\u4e00\u6b65\u63d0\u5347\u7a0b\u5e8f\u7684\u54cd\u5e94\u80fd\u529b \u7b2c64\u6761\u3000\u8003\u8651\u7528concurrent.futures\u5b9e\u73b0\u771f\u6b63\u7684\u5e76\u884c\u8ba1\u7b97 \u7b2c8\u7ae0\u3000\u7a33\u5b9a\u4e0e\u6027\u80fd \u7b2c65\u6761\u3000\u5408\u7406\u5229\u7528try/except/else/finally\u7ed3\u6784\u4e2d\u7684\u6bcf\u4e2a\u4ee3\u7801\u5757 \u7b2c66\u6761\u3000\u8003\u8651\u7528contextlib\u548cwith\u8bed\u53e5\u6765\u6539\u5199\u53ef\u590d\u7528\u7684try/finally\u4ee3\u7801 \u7b2c67\u6761\u3000\u7528datetime\u6a21\u5757\u5904\u7406\u672c\u5730\u65f6\u95f4\uff0c\u4e0d\u8981\u7528time\u6a21\u5757 \u7b2c68\u6761\u3000\u7528copyreg\u5b9e\u73b0\u53ef\u9760\u7684pickle\u64cd\u4f5c \u7b2c69\u6761\u3000\u5728\u9700\u8981\u51c6\u786e\u8ba1\u7b97\u7684\u573a\u5408\uff0c\u7528decimal\u8868\u793a\u76f8\u5e94\u7684\u6570\u503c \u7b2c70\u6761\u3000\u5148\u5206\u6790\u6027\u80fd\uff0c\u7136\u540e\u518d\u4f18\u5316 \u7b2c71\u6761\u3000\u4f18\u5148\u8003\u8651\u7528deque\u5b9e\u73b0\u751f\u4ea7\u8005-\u6d88\u8d39\u8005\u961f\u5217 \u7b2c72\u6761\u3000\u8003\u8651\u7528bisect\u641c\u7d22\u5df2\u6392\u5e8f\u7684\u5e8f\u5217 \u7b2c73\u6761\u3000\u5b66\u4f1a\u4f7f\u7528heapq\u5236\u4f5c\u4f18\u5148\u7ea7\u961f\u5217 \u7b2c74\u6761\u3000\u8003\u8651\u7528memoryview\u4e0ebytearray\u6765\u5b9e\u73b0\u65e0\u987b\u62f7\u8d1d\u7684bytes\u64cd\u4f5c \u7b2c9\u7ae0\u3000\u6d4b\u8bd5\u4e0e\u8c03\u8bd5 \u7b2c75\u6761\u3000\u901a\u8fc7repr\u5b57\u7b26\u4e32\u8f93\u51fa\u8c03\u8bd5\u4fe1\u606f \u7b2c76\u6761\u3000\u5728TestCase\u5b50\u7c7b\u91cc\u9a8c\u8bc1\u76f8\u5173\u7684\u884c\u4e3a \u7b2c77\u6761\u3000\u628a\u6d4b\u8bd5\u524d\u3001\u540e\u7684\u51c6\u5907\u4e0e\u6e05\u7406\u903b\u8f91\u5199\u5728setUp\u3001tearDown\u3001setUpModule\u4e0etearDownModule\u4e2d\uff0c\u4ee5\u9632\u7528\u4f8b\u4e4b\u95f4\u4e92\u76f8\u5e72\u6270 \u7b2c78\u6761\u3000\u7528Mock\u6765\u6a21\u62df\u53d7\u6d4b\u4ee3\u7801\u6240\u4f9d\u8d56\u7684\u590d\u6742\u51fd\u6570 \u7b2c79\u6761\u3000\u628a\u53d7\u6d4b\u4ee3\u7801\u6240\u4f9d\u8d56\u7684\u7cfb\u7edf\u5c01\u88c5\u8d77\u6765\uff0c\u4ee5\u4fbf\u4e8e\u6a21\u62df\u548c\u6d4b\u8bd5 \u7b2c80\u6761\u3000\u8003\u8651\u7528pdb\u505a\u4ea4\u4e92\u8c03\u8bd5 \u7b2c81\u6761\u3000\u7528tracemalloc\u6765\u638c\u63e1\u5185\u5b58\u7684\u4f7f\u7528\u4e0e\u6cc4\u6f0f\u60c5\u51b5 \u7b2c10\u7ae0\u3000\u534f\u4f5c\u5f00\u53d1 \u7b2c82\u6761\u3000\u5b66\u4f1a\u5bfb\u627e\u7531\u5176\u4ed6Python\u5f00\u53d1\u8005\u6240\u6784\u5efa\u7684\u6a21\u5757 \u7b2c83\u6761\u3000\u7528\u865a\u62df\u73af\u5883\u9694\u79bb\u9879\u76ee\uff0c\u5e76\u91cd\u5efa\u4f9d\u8d56\u5173\u7cfb \u7b2c84\u6761\u3000\u6bcf\u4e00\u4e2a\u51fd\u6570\u3001\u7c7b\u4e0e\u6a21\u5757\u90fd\u8981\u5199docstring \u7b2c85\u6761\u3000\u7528\u5305\u6765\u5b89\u6392\u6a21\u5757\uff0c\u4ee5\u63d0\u4f9b\u7a33\u56fa\u7684API \u7b2c86\u6761\u3000\u8003\u8651\u7528\u6a21\u5757\u7ea7\u522b\u7684\u4ee3\u7801\u914d\u7f6e\u4e0d\u540c\u7684\u90e8\u7f72\u73af\u5883 \u7b2c87\u6761\u3000\u4e3a\u81ea\u7f16\u7684\u6a21\u5757\u5b9a\u4e49\u6839\u5f02\u5e38\uff0c\u8ba9\u8c03\u7528\u8005\u80fd\u591f\u4e13\u95e8\u5904\u7406\u4e0e\u6b64API\u6709\u5173\u7684\u5f02\u5e38 \u7b2c88\u6761\u3000\u7528\u9002\u5f53\u7684\u65b9\u5f0f\u6253\u7834\u5faa\u73af\u4f9d\u8d56\u5173\u7cfb \u7b2c89\u6761\u3000\u91cd\u6784\u65f6\u8003\u8651\u901a\u8fc7warnings\u63d0\u9192\u5f00\u53d1\u8005API\u5df2\u7ecf\u53d1\u751f\u53d8\u5316 \u7b2c90\u6761\u3000\u8003\u8651\u901a\u8fc7typing\u505a\u9759\u6001\u5206\u6790\uff0c\u4ee5\u6d88\u9664bug 3.5.Demos \u00b6 \u9009\u8bfe\u7cfb\u7edf 4. \u8bfb\u4e66\u6709\u611f \u00b6 \u7ea6\u7ff0\u00b7\u68ee\u6885\u5179\u76842\u672c\u4e66","title":"Index"},{"location":"#_1","text":"","title":"\u77e5\u884c\u658b"},{"location":"#1linux","text":"","title":"1.Linux"},{"location":"#11linux-sre","text":"\u7b2c\u4e00\u7ae0 Linux\u57fa\u7840 \u7b2c\u4e8c\u7ae0 \u6587\u4ef6\u7cfb\u7edf \u7b2c\u4e09\u7ae0 \u8eab\u4efd\u4e0e\u5b89\u5168 \u7b2c\u56db\u7ae0 \u6587\u672c\u7f16\u8f91 \u7b2c\u4e94\u7ae0 \u6b63\u5219\u8868\u8fbe\u5f0f \u7b2c\u516d\u7ae0 \u6587\u4ef6\u67e5\u627e \u7b2c\u4e03\u7ae0 \u6587\u4ef6\u6253\u5305\u548c\u89e3\u5305","title":"1.1.Linux SRE"},{"location":"#12suse-linux-administration","text":"Linux File System Overview Useful Commands Shell","title":"1.2.SUSE Linux Administration"},{"location":"#13suse-enterprise-storage-foundation","text":"SUSE Enterprise Storage Foundation SUSE Enterprise Storage Basic Operation","title":"1.3.SUSE Enterprise Storage Foundation"},{"location":"#2kubernetes","text":"","title":"2.Kubernetes"},{"location":"#21cka-learning-memo","text":"Installation Single Node Installation Multiple Nodes Installation Installation on Aliyun ECS Docker Fundamentals Foundamentals Memo Overview kubectl basics Core Kubernetes Pod Deployment Service Application Modeling Namespace StatefulSet DaemonSet Job and Cronjob Configuration Secrets Persistence Role Based Access Control (RBAC) Ingress Advanced Kubernetes Scheduling Horizontal Pod Autoscaling Policy Network Policy Cluster Management Operating Kubernetes Troubleshooting Health Check Helming Topics Operations on Resources Health Check Calico Installation Kyma","title":"2.1.CKA Learning Memo"},{"location":"#22cka","text":"\u5b89\u88c5 \u5355\u8282\u70b9\u865a\u62df\u673a\u5b89\u88c5Kubernetes \u591a\u8282\u70b9\u865a\u62df\u673a\u5b89\u88c5Kubernetes \u963f\u91cc\u4e91ECS\u5b89\u88c5Kubernetes Docker Docker\u57fa\u7840 \u57fa\u7840\u77e5\u8bc6 Kubernetes\u968f\u7b14 Kubernetes\u96c6\u7fa4\u6982\u89c8 kubectl\u57fa\u7840 \u6838\u5fc3\u6982\u5ff5 Pod Deployment Service \u5e94\u7528\u4f53\u7cfb Namespace StatefulSet DaemonSet Job and Cronjob Configuration secrets Persistence RBAC\u9274\u6743 Ingress-nginx \u8fdb\u9636\u6982\u5ff5 Scheduling Horizontal Pod Autoscaling (HPA) Policy Network Policy Cluster Management \u65e5\u5e38\u7ef4\u62a4 Troubleshooting \u5065\u5eb7\u68c0\u67e5 Helm Chart \u4e3b\u9898\u8ba8\u8bba Kubernetes\u8d44\u6e90\u5e38\u89c1\u64cd\u4f5c \u5065\u5eb7\u68c0\u67e5 \u5b89\u88c5Calico Demos Build CAP Application on Kyma","title":"2.2.CKA\u5b66\u4e60\u7b14\u8bb0"},{"location":"#3python","text":"","title":"3.Python"},{"location":"#31python","text":"Python\u5b89\u88c5 Python\u8bed\u8a00\u57fa\u7840 Python\u6253\u5305\u548c\u89e3\u5305 Python\u5185\u7f6e\u51fd\u6570\u53ca\u6587\u4ef6 Python\u9762\u5411\u5bf9\u8c61\u6982\u5ff5 Python\u9762\u5411\u5bf9\u8c61\u4e09\u5927\u7279\u6027","title":"3.1.Python\u57fa\u7840"},{"location":"#32python","text":"NumPy\u57fa\u7840 NumPy\u8fdb\u9636 Pandas\u5165\u95e8 \u6570\u636e\u8f7d\u5165\u3001\u5b58\u50a8\u53ca\u6587\u4ef6\u683c\u5f0f \u6570\u636e\u6e05\u6d17\u4e0e\u51c6\u5907 \u6570\u636e\u89c4\u6574\uff1a\u8fde\u63a5\u3001\u8054\u5408\u4e0e\u91cd\u5851 \u7ed8\u56fe\u4e0e\u53ef\u89c6\u5316 \u6570\u636e\u805a\u5408\u4e0e\u5206\u7ec4\u64cd\u4f5c \u65f6\u95f4\u5e8f\u5217 \u9ad8\u9636pandas Python\u5efa\u6a21\u5e93\u4ecb\u7ecd","title":"3.2.Python\u6570\u636e\u5206\u6790\u57fa\u7840"},{"location":"#33","text":"1.\u57fa\u7840\u77e5\u8bc6\u56de\u987e 2.\u591a\u9879\u96c6\u7684\u6982\u8ff0 3.\u641c\u7d22\u3001\u6392\u5e8f\u4ee5\u53ca\u590d\u6742\u5ea6\u5206\u6790 4.\u6570\u7ec4\u548c\u94fe\u63a5\u7ed3\u6784 5.\u63a5\u53e3\u3001\u5b9e\u73b0\u548c\u591a\u6001 6.\u7ee7\u627f\u4e0e\u62bd\u8c61\u7c7b","title":"3.3.\u6570\u636e\u7ed3\u6784\u548c\u7b97\u6cd5"},{"location":"#35effective-python","text":"\u7b2c1\u7ae0\u3000\u57f9\u517bPythonic\u601d\u7ef4 \u7b2c1\u6761\u3000\u67e5\u8be2\u81ea\u5df1\u4f7f\u7528\u7684Python\u7248\u672c \u7b2c2\u6761\u3000\u9075\u5faaPEP 8\u98ce\u683c\u6307\u5357 \u7b2c3\u6761\u3000\u4e86\u89e3bytes\u4e0estr\u7684\u533a\u522b \u7b2c4\u6761\u3000\u7528\u652f\u6301\u63d2\u503c\u7684f-string\u53d6\u4ee3C\u98ce\u683c\u7684\u683c\u5f0f\u5b57\u7b26\u4e32\u4e0estr.format\u65b9\u6cd5 \u7b2c5\u6761\u3000\u7528\u8f85\u52a9\u51fd\u6570\u53d6\u4ee3\u590d\u6742\u7684\u8868\u8fbe\u5f0f \u7b2c6\u6761\u3000\u628a\u6570\u636e\u7ed3\u6784\u76f4\u63a5\u62c6\u5206\u5230\u591a\u4e2a\u53d8\u91cf\u91cc\uff0c\u4e0d\u8981\u4e13\u95e8\u901a\u8fc7\u4e0b\u6807\u8bbf\u95ee \u7b2c7\u6761\u3000\u5c3d\u91cf\u7528enumerate\u53d6\u4ee3range \u7b2c8\u6761\u3000\u7528zip\u51fd\u6570\u540c\u65f6\u904d\u5386\u4e24\u4e2a\u8fed\u4ee3\u5668 \u7b2c9\u6761\u3000\u4e0d\u8981\u5728for\u4e0ewhile\u5faa\u73af\u540e\u9762\u5199else\u5757 \u7b2c10\u6761\u3000\u7528\u8d4b\u503c\u8868\u8fbe\u5f0f\u51cf\u5c11\u91cd\u590d\u4ee3\u7801 \u7b2c2\u7ae0\u3000\u5217\u8868\u4e0e\u5b57\u5178 \u7b2c11\u6761\u3000\u5b66\u4f1a\u5bf9\u5e8f\u5217\u505a\u5207\u7247 \u7b2c12\u6761\u3000\u4e0d\u8981\u5728\u5207\u7247\u91cc\u540c\u65f6\u6307\u5b9a\u8d77\u6b62\u4e0b\u6807\u4e0e\u6b65\u8fdb \u7b2c13\u6761\u3000\u901a\u8fc7\u5e26\u661f\u53f7\u7684unpacking\u64cd\u4f5c\u6765\u6355\u83b7\u591a\u4e2a\u5143\u7d20\uff0c\u4e0d\u8981\u7528\u5207\u7247 \u7b2c14\u6761\u3000\u7528sort\u65b9\u6cd5\u7684key\u53c2\u6570\u6765\u8868\u793a\u590d\u6742\u7684\u6392\u5e8f\u903b\u8f91 \u7b2c15\u6761\u3000\u4e0d\u8981\u8fc7\u5206\u4f9d\u8d56\u7ed9\u5b57\u5178\u6dfb\u52a0\u6761\u76ee\u65f6\u6240\u7528\u7684\u987a\u5e8f \u7b2c16\u6761\u3000\u7528get\u5904\u7406\u952e\u4e0d\u5728\u5b57\u5178\u4e2d\u7684\u60c5\u51b5\uff0c\u4e0d\u8981\u4f7f\u7528in\u4e0eKeyError \u7b2c17\u6761\u3000\u7528defaultdict\u5904\u7406\u5185\u90e8\u72b6\u6001\u4e2d\u7f3a\u5931\u7684\u5143\u7d20\uff0c\u800c\u4e0d\u8981\u7528setdefault \u7b2c18\u6761\u3000\u5b66\u4f1a\u5229\u7528__missing__\u6784\u9020\u4f9d\u8d56\u952e\u7684\u9ed8\u8ba4\u503c \u7b2c3\u7ae0\u3000\u51fd\u6570 \u7b2c19\u6761\u3000\u4e0d\u8981\u628a\u51fd\u6570\u8fd4\u56de\u7684\u591a\u4e2a\u6570\u503c\u62c6\u5206\u5230\u4e09\u4e2a\u4ee5\u4e0a\u7684\u53d8\u91cf\u4e2d \u7b2c20\u6761\u3000\u9047\u5230\u610f\u5916\u72b6\u51b5\u65f6\u5e94\u8be5\u629b\u51fa\u5f02\u5e38\uff0c\u4e0d\u8981\u8fd4\u56deNone \u7b2c21\u6761\u3000\u4e86\u89e3\u5982\u4f55\u5728\u95ed\u5305\u91cc\u9762\u4f7f\u7528\u5916\u56f4\u4f5c\u7528\u57df\u4e2d\u7684\u53d8\u91cf \u7b2c22\u6761\u3000\u7528\u6570\u91cf\u53ef\u53d8\u7684\u4f4d\u7f6e\u53c2\u6570\u7ed9\u51fd\u6570\u8bbe\u8ba1\u6e05\u6670\u7684\u53c2\u6570\u5217\u8868 \u7b2c23\u6761\u3000\u7528\u5173\u952e\u5b57\u53c2\u6570\u6765\u8868\u793a\u53ef\u9009\u7684\u884c\u4e3a \u7b2c24\u6761\u3000\u7528None\u548cdocstring\u6765\u63cf\u8ff0\u9ed8\u8ba4\u503c\u4f1a\u53d8\u7684\u53c2\u6570 \u7b2c25\u6761\u3000\u7528\u53ea\u80fd\u4ee5\u5173\u952e\u5b57\u6307\u5b9a\u548c\u53ea\u80fd\u6309\u4f4d\u7f6e\u4f20\u5165\u7684\u53c2\u6570\u6765\u8bbe\u8ba1\u6e05\u6670\u7684\u53c2\u6570\u5217\u8868 \u7b2c26\u6761\u3000\u7528functools.wraps\u5b9a\u4e49\u51fd\u6570\u4fee\u9970\u5668 \u7b2c4\u7ae0\u3000\u63a8\u5bfc\u4e0e\u751f\u6210 \u7b2c27\u6761\u3000\u7528\u5217\u8868\u63a8\u5bfc\u53d6\u4ee3map\u4e0efilter \u7b2c28\u6761\u3000\u63a7\u5236\u63a8\u5bfc\u903b\u8f91\u7684\u5b50\u8868\u8fbe\u5f0f\u4e0d\u8981\u8d85\u8fc7\u4e24\u4e2a \u7b2c29\u6761\u3000\u7528\u8d4b\u503c\u8868\u8fbe\u5f0f\u6d88\u9664\u63a8\u5bfc\u4e2d\u7684\u91cd\u590d\u4ee3\u7801 \u7b2c30\u6761\u3000\u4e0d\u8981\u8ba9\u51fd\u6570\u76f4\u63a5\u8fd4\u56de\u5217\u8868\uff0c\u5e94\u8be5\u8ba9\u5b83\u9010\u4e2a\u751f\u6210\u5217\u8868\u91cc\u7684\u503c \u7b2c31\u6761\u3000\u8c28\u614e\u5730\u8fed\u4ee3\u51fd\u6570\u6240\u6536\u5230\u7684\u53c2\u6570 \u7b2c32\u6761\u3000\u8003\u8651\u7528\u751f\u6210\u5668\u8868\u8fbe\u5f0f\u6539\u5199\u6570\u636e\u91cf\u8f83\u5927\u7684\u5217\u8868\u63a8\u5bfc \u7b2c33\u6761\u3000\u901a\u8fc7yield from\u628a\u591a\u4e2a\u751f\u6210\u5668\u8fde\u8d77\u6765\u7528 \u7b2c34\u6761\u3000\u4e0d\u8981\u7528send\u7ed9\u751f\u6210\u5668\u6ce8\u5165\u6570\u636e \u7b2c35\u6761\u3000\u4e0d\u8981\u901a\u8fc7throw\u53d8\u6362\u751f\u6210\u5668\u7684\u72b6\u6001 \u7b2c36\u6761\u3000\u8003\u8651\u7528itertools\u62fc\u88c5\u8fed\u4ee3\u5668\u4e0e\u751f\u6210\u5668 \u7b2c5\u7ae0\u3000\u7c7b\u4e0e\u63a5\u53e3 \u7b2c37\u6761\u3000\u7528\u7ec4\u5408\u8d77\u6765\u7684\u7c7b\u6765\u5b9e\u73b0\u591a\u5c42\u7ed3\u6784\uff0c\u4e0d\u8981\u7528\u5d4c\u5957\u7684\u5185\u7f6e\u7c7b\u578b \u7b2c38\u6761\u3000\u8ba9\u7b80\u5355\u7684\u63a5\u53e3\u63a5\u53d7\u51fd\u6570\uff0c\u800c\u4e0d\u662f\u7c7b\u7684\u5b9e\u4f8b \u7b2c39\u6761\u3000\u901a\u8fc7@classmethod\u591a\u6001\u6765\u6784\u9020\u540c\u4e00\u4f53\u7cfb\u4e2d\u7684\u5404\u7c7b\u5bf9\u8c61 \u7b2c40\u6761\u3000\u901a\u8fc7super\u521d\u59cb\u5316\u8d85\u7c7b \u7b2c41\u6761\u3000\u8003\u8651\u7528mix-in\u7c7b\u6765\u8868\u793a\u53ef\u7ec4\u5408\u7684\u529f\u80fd \u7b2c42\u6761\u3000\u4f18\u5148\u8003\u8651\u7528public\u5c5e\u6027\u8868\u793a\u5e94\u53d7\u4fdd\u62a4\u7684\u6570\u636e\uff0c\u4e0d\u8981\u7528private\u5c5e\u6027\u8868\u793a \u7b2c43\u6761\u3000\u81ea\u5b9a\u4e49\u7684\u5bb9\u5668\u7c7b\u578b\u5e94\u8be5\u4ececollections.abc\u7ee7\u627f \u7b2c6\u7ae0\u3000\u5143\u7c7b\u4e0e\u5c5e\u6027 \u7b2c44\u6761\u3000\u7528\u7eaf\u5c5e\u6027\u4e0e\u4fee\u9970\u5668\u53d6\u4ee3\u65e7\u5f0f\u7684setter\u4e0egetter\u65b9\u6cd5 \u7b2c45\u6761\u3000\u8003\u8651\u7528@property\u5b9e\u73b0\u65b0\u7684\u5c5e\u6027\u8bbf\u95ee\u903b\u8f91\uff0c\u4e0d\u8981\u6025\u7740\u91cd\u6784\u539f\u6709\u7684\u4ee3\u7801 \u7b2c46\u6761\u3000\u7528\u63cf\u8ff0\u7b26\u6765\u6539\u5199\u9700\u8981\u590d\u7528\u7684@property\u65b9\u6cd5 \u7b2c47\u6761\u3000\u9488\u5bf9\u60f0\u6027\u5c5e\u6027\u4f7f\u7528__getattr__\u3001 getattribute__\u53ca__setattr \u7b2c48\u6761\u3000\u7528__init_subclass__\u9a8c\u8bc1\u5b50\u7c7b\u5199\u5f97\u662f\u5426\u6b63\u786e \u7b2c49\u6761\u3000\u7528__init_subclass__\u8bb0\u5f55\u73b0\u6709\u7684\u5b50\u7c7b \u7b2c50\u6761\u3000\u7528__set_name__\u7ed9\u7c7b\u5c5e\u6027\u52a0\u6ce8\u89e3 \u7b2c51\u6761\u3000\u4f18\u5148\u8003\u8651\u901a\u8fc7\u7c7b\u4fee\u9970\u5668\u6765\u63d0\u4f9b\u53ef\u7ec4\u5408\u7684\u6269\u5145\u529f\u80fd\uff0c\u4e0d\u8981\u4f7f\u7528\u5143\u7c7b \u7b2c7\u7ae0\u3000\u5e76\u53d1\u4e0e\u5e76\u884c \u7b2c52\u6761\u3000\u7528subprocess\u7ba1\u7406\u5b50\u8fdb\u7a0b \u7b2c53\u6761\u3000\u53ef\u4ee5\u7528\u7ebf\u7a0b\u6267\u884c\u963b\u585e\u5f0fI/O\uff0c\u4f46\u4e0d\u8981\u7528\u5b83\u505a\u5e76\u884c\u8ba1\u7b97 \u7b2c54\u6761\u3000\u5229\u7528Lock\u9632\u6b62\u591a\u4e2a\u7ebf\u7a0b\u4e89\u7528\u540c\u4e00\u4efd\u6570\u636e \u7b2c55\u6761\u3000\u7528Queue\u6765\u534f\u8c03\u5404\u7ebf\u7a0b\u4e4b\u95f4\u7684\u5de5\u4f5c\u8fdb\u5ea6 \u7b2c56\u6761\u3000\u5b66\u4f1a\u5224\u65ad\u4ec0\u4e48\u573a\u5408\u5fc5\u987b\u505a\u5e76\u53d1 \u7b2c57\u6761\u3000\u4e0d\u8981\u5728\u6bcf\u6b21fan-out\u65f6\u90fd\u65b0\u5efa\u4e00\u6279Thread\u5b9e\u4f8b \u7b2c58\u6761\u3000\u5b66\u4f1a\u6b63\u786e\u5730\u91cd\u6784\u4ee3\u7801\uff0c\u4ee5\u4fbf\u7528Queue\u505a\u5e76\u53d1 \u7b2c59\u6761\u3000\u5982\u679c\u5fc5\u987b\u7528\u7ebf\u7a0b\u505a\u5e76\u53d1\uff0c\u90a3\u5c31\u8003\u8651\u901a\u8fc7ThreadPoolExecutor\u5b9e\u73b0 \u7b2c60\u6761\u3000\u7528\u534f\u7a0b\u5b9e\u73b0\u9ad8\u5e76\u53d1\u7684I/O \u7b2c61\u6761\u3000\u5b66\u4f1a\u7528asyncio\u6539\u5199\u90a3\u4e9b\u901a\u8fc7\u7ebf\u7a0b\u5b9e\u73b0\u7684I/O \u7b2c62\u6761\u3000\u7ed3\u5408\u7ebf\u7a0b\u4e0e\u534f\u7a0b\uff0c\u5c06\u4ee3\u7801\u987a\u5229\u8fc1\u79fb\u5230asyncio \u7b2c63\u6761\u3000\u8ba9asyncio\u7684\u4e8b\u4ef6\u5faa\u73af\u4fdd\u6301\u7545\u901a\uff0c\u4ee5\u4fbf\u8fdb\u4e00\u6b65\u63d0\u5347\u7a0b\u5e8f\u7684\u54cd\u5e94\u80fd\u529b \u7b2c64\u6761\u3000\u8003\u8651\u7528concurrent.futures\u5b9e\u73b0\u771f\u6b63\u7684\u5e76\u884c\u8ba1\u7b97 \u7b2c8\u7ae0\u3000\u7a33\u5b9a\u4e0e\u6027\u80fd \u7b2c65\u6761\u3000\u5408\u7406\u5229\u7528try/except/else/finally\u7ed3\u6784\u4e2d\u7684\u6bcf\u4e2a\u4ee3\u7801\u5757 \u7b2c66\u6761\u3000\u8003\u8651\u7528contextlib\u548cwith\u8bed\u53e5\u6765\u6539\u5199\u53ef\u590d\u7528\u7684try/finally\u4ee3\u7801 \u7b2c67\u6761\u3000\u7528datetime\u6a21\u5757\u5904\u7406\u672c\u5730\u65f6\u95f4\uff0c\u4e0d\u8981\u7528time\u6a21\u5757 \u7b2c68\u6761\u3000\u7528copyreg\u5b9e\u73b0\u53ef\u9760\u7684pickle\u64cd\u4f5c \u7b2c69\u6761\u3000\u5728\u9700\u8981\u51c6\u786e\u8ba1\u7b97\u7684\u573a\u5408\uff0c\u7528decimal\u8868\u793a\u76f8\u5e94\u7684\u6570\u503c \u7b2c70\u6761\u3000\u5148\u5206\u6790\u6027\u80fd\uff0c\u7136\u540e\u518d\u4f18\u5316 \u7b2c71\u6761\u3000\u4f18\u5148\u8003\u8651\u7528deque\u5b9e\u73b0\u751f\u4ea7\u8005-\u6d88\u8d39\u8005\u961f\u5217 \u7b2c72\u6761\u3000\u8003\u8651\u7528bisect\u641c\u7d22\u5df2\u6392\u5e8f\u7684\u5e8f\u5217 \u7b2c73\u6761\u3000\u5b66\u4f1a\u4f7f\u7528heapq\u5236\u4f5c\u4f18\u5148\u7ea7\u961f\u5217 \u7b2c74\u6761\u3000\u8003\u8651\u7528memoryview\u4e0ebytearray\u6765\u5b9e\u73b0\u65e0\u987b\u62f7\u8d1d\u7684bytes\u64cd\u4f5c \u7b2c9\u7ae0\u3000\u6d4b\u8bd5\u4e0e\u8c03\u8bd5 \u7b2c75\u6761\u3000\u901a\u8fc7repr\u5b57\u7b26\u4e32\u8f93\u51fa\u8c03\u8bd5\u4fe1\u606f \u7b2c76\u6761\u3000\u5728TestCase\u5b50\u7c7b\u91cc\u9a8c\u8bc1\u76f8\u5173\u7684\u884c\u4e3a \u7b2c77\u6761\u3000\u628a\u6d4b\u8bd5\u524d\u3001\u540e\u7684\u51c6\u5907\u4e0e\u6e05\u7406\u903b\u8f91\u5199\u5728setUp\u3001tearDown\u3001setUpModule\u4e0etearDownModule\u4e2d\uff0c\u4ee5\u9632\u7528\u4f8b\u4e4b\u95f4\u4e92\u76f8\u5e72\u6270 \u7b2c78\u6761\u3000\u7528Mock\u6765\u6a21\u62df\u53d7\u6d4b\u4ee3\u7801\u6240\u4f9d\u8d56\u7684\u590d\u6742\u51fd\u6570 \u7b2c79\u6761\u3000\u628a\u53d7\u6d4b\u4ee3\u7801\u6240\u4f9d\u8d56\u7684\u7cfb\u7edf\u5c01\u88c5\u8d77\u6765\uff0c\u4ee5\u4fbf\u4e8e\u6a21\u62df\u548c\u6d4b\u8bd5 \u7b2c80\u6761\u3000\u8003\u8651\u7528pdb\u505a\u4ea4\u4e92\u8c03\u8bd5 \u7b2c81\u6761\u3000\u7528tracemalloc\u6765\u638c\u63e1\u5185\u5b58\u7684\u4f7f\u7528\u4e0e\u6cc4\u6f0f\u60c5\u51b5 \u7b2c10\u7ae0\u3000\u534f\u4f5c\u5f00\u53d1 \u7b2c82\u6761\u3000\u5b66\u4f1a\u5bfb\u627e\u7531\u5176\u4ed6Python\u5f00\u53d1\u8005\u6240\u6784\u5efa\u7684\u6a21\u5757 \u7b2c83\u6761\u3000\u7528\u865a\u62df\u73af\u5883\u9694\u79bb\u9879\u76ee\uff0c\u5e76\u91cd\u5efa\u4f9d\u8d56\u5173\u7cfb \u7b2c84\u6761\u3000\u6bcf\u4e00\u4e2a\u51fd\u6570\u3001\u7c7b\u4e0e\u6a21\u5757\u90fd\u8981\u5199docstring \u7b2c85\u6761\u3000\u7528\u5305\u6765\u5b89\u6392\u6a21\u5757\uff0c\u4ee5\u63d0\u4f9b\u7a33\u56fa\u7684API \u7b2c86\u6761\u3000\u8003\u8651\u7528\u6a21\u5757\u7ea7\u522b\u7684\u4ee3\u7801\u914d\u7f6e\u4e0d\u540c\u7684\u90e8\u7f72\u73af\u5883 \u7b2c87\u6761\u3000\u4e3a\u81ea\u7f16\u7684\u6a21\u5757\u5b9a\u4e49\u6839\u5f02\u5e38\uff0c\u8ba9\u8c03\u7528\u8005\u80fd\u591f\u4e13\u95e8\u5904\u7406\u4e0e\u6b64API\u6709\u5173\u7684\u5f02\u5e38 \u7b2c88\u6761\u3000\u7528\u9002\u5f53\u7684\u65b9\u5f0f\u6253\u7834\u5faa\u73af\u4f9d\u8d56\u5173\u7cfb \u7b2c89\u6761\u3000\u91cd\u6784\u65f6\u8003\u8651\u901a\u8fc7warnings\u63d0\u9192\u5f00\u53d1\u8005API\u5df2\u7ecf\u53d1\u751f\u53d8\u5316 \u7b2c90\u6761\u3000\u8003\u8651\u901a\u8fc7typing\u505a\u9759\u6001\u5206\u6790\uff0c\u4ee5\u6d88\u9664bug","title":"3.5.Effective Python"},{"location":"#35demos","text":"\u9009\u8bfe\u7cfb\u7edf","title":"3.5.Demos"},{"location":"#4","text":"\u7ea6\u7ff0\u00b7\u68ee\u6885\u5179\u76842\u672c\u4e66","title":"4. \u8bfb\u4e66\u6709\u611f"},{"location":"about/","text":"About \u00b6 What's past is prologue. It\u2019s never too late to do. You may also visit my posts on zhihu . --From Shanghai China","title":"About"},{"location":"about/#about","text":"What's past is prologue. It\u2019s never too late to do. You may also visit my posts on zhihu . --From Shanghai China","title":"About"},{"location":"Reading/Developers/","text":"\u7a0b\u5e8f\u5458\u7684\u804c\u4e1a\u548c\u751f\u5b58\u6307\u5357 - \u8bfb\u7ea6\u7ff0\u00b7\u68ee\u6885\u5179\u76842\u672c\u4e66\u6709\u611f \u00b6 2024\u5e74\u5143\u65e6\u540e\u8bfb\u4e86\u7ea6\u7ff0\u00b7\u68ee\u6885\u5179\uff08John Sonmez\uff09\u76842\u672c\u4e66\uff0c\u5f88\u6709\u5171\u9e23\uff0c\u4ea7\u751f\u4e86\u5199\u8bfb\u4e66\u611f\u60f3\u7684\u5ff5\u5934\uff0c\u501f\u673a\u4e5f\u68b3\u7406\u4e86\u6211\u4e2a\u4eba\u7684\u89c2\u70b9\u548c\u60f3\u6cd5\uff0c\u4e8e\u662f\u4fbf\u6709\u4e86\u4e0b\u9762\u8fd9\u4e9b\u6587\u7ae0\u3002 \u300a\u8f6f\u6280\u80fd\uff1a\u4ee3\u7801\u4e4b\u5916\u7684\u751f\u5b58\u6307\u5357\uff08\u7b2c2\u7248\uff09\u300b \u00b6 \u7b2c\u4e00\u7bc7\u3000\u804c\u4e1a \u7b2c2\u7ae0\u3000\u7ecf\u8425\u81ea\u5df1\u7684\u804c\u4e1a\u751f\u6daf\u5c31\u50cf\u7ecf\u8425\u4e00\u5bb6\u4f01\u4e1a \u7b2c3\u7ae0\u3000\u5982\u4f55\u7ed9\u81ea\u5df1\u8bbe\u5b9a\u597d\u804c\u4e1a\u76ee\u6807 \u7b2c4\u7ae0\u3000\u62d3\u5c55\u81ea\u5df1\u7684\u4eba\u9645\u4ea4\u5f80\u80fd\u529b \u7b2c5\u7ae0\u3000\u521b\u5efa\u4e00\u4efd\u5c61\u8bd5\u5c61\u9a8c\u7684\u7b80\u5386 \u7b2c6\u7ae0\u3000\u7834\u89e3\u9762\u8bd5\u4e4b\u9053 \u7b2c7\u7ae0\u3000\u8f6f\u4ef6\u5f00\u53d1\u4eba\u5458\u7684\u4e09\u6761\u804c\u4e1a\u8def\u5f84 \u7b2c8\u7ae0\u3000\u4e3a\u4ec0\u4e48\u4f60\u9700\u8981\u8d70\u4e13\u4e1a\u5316\u9053\u8def \u7b2c9\u7ae0\u3000\u516c\u53f8\u4e0e\u516c\u53f8\u662f\u4e0d\u4e00\u6837\u7684 \u7b2c10\u7ae0\u3000\u6500\u767b\u664b\u5347\u9636\u68af \u7b2c11\u7ae0\u3000\u6210\u4e3a\u4e13\u4e1a\u4eba\u58eb \u7b2c12\u7ae0\u3000\u4e0e\u8001\u677f\u548c\u540c\u4e8b\u7684\u76f8\u5904\u4e4b\u9053 \u7b2c13\u7ae0\u3000\u4e0d\u8981\u9677\u5165\u5bf9\u6280\u672f\u7684\u72c2\u70ed\u4e4b\u4e2d \u7b2c14\u7ae0\u3000\u5982\u4f55\u8f9e\u804c\u5e76\u5f00\u59cb\u4e3a\u81ea\u5df1\u5de5\u4f5c \u7b2c15\u7ae0\u3000\u5982\u4f55\u6210\u4e3a\u81ea\u7531\u804c\u4e1a\u8005 \u7b2c16\u7ae0\u3000\u5982\u4f55\u6210\u4e3a\u4e00\u540d\u4f01\u4e1a\u5bb6 \u7b2c17\u7ae0\u3000\u5982\u4f55\u5f00\u59cb\u521b\u4e1a \u7b2c18\u7ae0\u3000\u8fdc\u7a0b\u5de5\u4f5c \u7b2c\u4e8c\u7bc7\u3000\u81ea\u6211\u8425\u9500 \u7b2c19\u7ae0\u3000\u81ea\u6211\u8425\u9500\u57fa\u7840\u8bfe \u7b2c20\u7ae0\u3000\u5982\u4f55\u6253\u9020\u4e2a\u4eba\u54c1\u724c \u7b2c21\u7ae0\u3000\u5982\u4f55\u521b\u5efa\u5927\u83b7\u6210\u529f\u7684\u535a\u5ba2 \u7b2c22\u7ae0\u3000\u5728YouTube\u4e0a\u521b\u7acb\u81ea\u5df1\u7684\u4e13\u680f \u7b2c23\u7ae0\u3000\u4e3a\u4f55\u4e3a\u4ed6\u4eba\u589e\u52a0\u4ef7\u503c\u975e\u5e38\u91cd\u8981 \u7b2c24\u7ae0\u3000\u5584\u4e8e\u8fd0\u7528\u793e\u4ea4\u5a92\u4f53\u63d0\u5347\u81ea\u5df1\u7684\u54c1\u724c \u7b2c25\u7ae0\u3000\u6f14\u8bb2\u3001\u57f9\u8bad\u548c\u62a5\u544a \u7b2c26\u7ae0\u3000\u8457\u4e66\u7acb\u8bf4 \u7b2c\u4e09\u7bc7\u3000\u5b66\u4e60 \u7b2c27\u7ae0\u3000\u5b66\u4e60\u600e\u6837\u5b66\u4e60 \u7b2c28\u7ae0\u3000\u6211\u7684\u201c\u5341\u6b65\u5b66\u4e60\u6cd5\u201d \u7b2c29\u7ae0\u3000\u7b2c 1 \u6b65\u5230\u7b2c 6 \u6b65\uff1a\u8fd9\u4e9b\u6b65\u9aa4\u53ea\u505a\u4e00\u6b21 \u7b2c30\u7ae0\u3000\u7b2c7\u6b65\u5230\u7b2c10\u6b65\uff1a\u5faa\u73af\u5f80\u590d \u7b2c31\u7ae0\u3000\u5982\u4f55\u5bfb\u627e\u5bfc\u5e08 \u7b2c32\u7ae0\u3000\u5982\u4f55\u6210\u4e3a\u5bfc\u5e08 \u7b2c33\u7ae0\u3000\u4e3a\u4f55\u8bf4\u6559\u5b66\u76f8\u957f \u7b2c34\u7ae0\u3000\u4f60\u9700\u8981\u4e00\u4e2a\u5927\u5b66\u5b66\u4f4d\u5417 \u7b2c35\u7ae0\u3000\u53d1\u73b0\u81ea\u5df1\u7684\u77e5\u8bc6\u77ed\u677f \u7b2c\u56db\u7bc7\u3000\u751f\u4ea7\u529b \u7b2c36\u7ae0\u3000\u4e00\u5207\u59cb\u4e8e\u4e13\u6ce8 \u7b2c37\u7ae0\u3000\u6211\u7684\u79c1\u623f\u201c\u751f\u4ea7\u529b\u63d0\u5347\u8ba1\u5212\u201d \u7b2c38\u7ae0\u3000\u756a\u8304\u5de5\u4f5c\u6cd5 \u7b2c39\u7ae0\u3000\u6211\u7684\u201c\u5b9a\u989d\u5de5\u4f5c\u6cd5\u201d \u7b2c40\u7ae0\u3000\u5bf9\u81ea\u5df1\u8d1f\u8d23 \u7b2c41\u7ae0\u3000\u4e3a\u4ec0\u4e48\u8bf4\u591a\u4efb\u52a1\u5e76\u884c\u5f0a\u5927\u4e8e\u5229 \u7b2c42\u7ae0\u3000\u5982\u4f55\u5e94\u5bf9\u804c\u4e1a\u5026\u6020 \u7b2c43\u7ae0\u3000\u4f60\u662f\u600e\u6837\u6d6a\u8d39\u6389\u65f6\u95f4\u7684 \u7b2c44\u7ae0\u3000\u5f62\u6210\u60ef\u4f8b\u7684\u91cd\u8981\u6027 \u7b2c45\u7ae0\u3000\u5982\u4f55\u57f9\u517b\u597d\u4e60\u60ef \u7b2c46\u7ae0\u3000\u5206\u89e3\u4efb\u52a1\u4f1a\u63d0\u9ad8\u751f\u4ea7\u529b \u7b2c47\u7ae0\u3000\u52aa\u529b\u5de5\u4f5c\u7684\u4ef7\u503c\uff0c\u4ee5\u53ca\u4e3a\u4ec0\u4e48\u4f60\u603b\u662f\u9003\u907f\u52aa\u529b\u5de5\u4f5c \u7b2c48\u7ae0\u3000\u4efb\u4f55\u884c\u52a8\u90fd\u6bd4\u4e0d\u91c7\u53d6\u884c\u52a8\u597d \u7b2c\u4e94\u7bc7\u3000\u7406\u8d22 \u7b2c49\u7ae0\u3000\u5408\u7406\u652f\u914d\u4f60\u7684\u85aa\u6c34 \u7b2c50\u7ae0\u3000\u600e\u6837\u8fdb\u884c\u85aa\u916c\u8c08\u5224 \u7b2c51\u7ae0\u3000\u4e3a\u4f55\u8bf4\u623f\u5730\u4ea7\u662f\u6700\u597d\u7684\u6295\u8d44 \u7b2c52\u7ae0\u3000\u4f60\u771f\u7684\u4e86\u89e3\u81ea\u5df1\u7684\u9000\u4f11\u8ba1\u5212\u5417 \u7b2c53\u7ae0\u3000\u503a\u52a1\u7684\u5371\u5bb3 \u7b2c54\u7ae0\u3000\u5982\u4f55\u521b\u9020\u771f\u6b63\u7684\u8d22\u5bcc \u7b2c55\u7ae0\u3000\u6211\u662f\u5982\u4f55\u505a\u523033\u5c81\u9000\u4f11\u7684 \u7b2c\u516d\u7bc7\u3000\u5065\u8eab \u7b2c56\u7ae0\u3000\u5065\u8eab\u7684\u597d\u5904 \u7b2c57\u7ae0\u3000\u8bbe\u5b9a\u4f60\u7684\u5065\u8eab\u76ee\u6807 \u7b2c58\u7ae0\u3000\u5982\u4f55\u51cf\u80a5\uff08\u6216\u8005\u589e\u91cd\uff09 \u7b2c59\u7ae0\u3000\u5065\u8eab\u7684\u52a8\u529b\u4ece\u4f55\u800c\u6765 \u7b2c60\u7ae0\u3000\u589e\u808c \u7b2c61\u7ae0\u3000\u5982\u4f55\u83b7\u5f97\u5b8c\u7f8e\u8179\u808c \u7b2c62\u7ae0\u3000\u5f00\u59cb\u8dd1\u6b65 \u7b2c63\u7ae0\u3000\u6211\u7684\u51cf\u8102\u589e\u808c\u79d8\u8bc0 \u7b2c64\u7ae0\u3000\u7ad9\u7acb\u5f0f\u529e\u516c\u53ca\u5176\u4ed6\u7a8d\u95e8 \u7b2c65\u7ae0\u3000\u5229\u7528\u9ad8\u79d1\u6280\u88c5\u5907\u5065\u8eab \u7b2c\u4e03\u7bc7\u3000\u5fc3\u6001 \u7b2c66\u7ae0\u3000\u5fc3\u667a\u662f\u5982\u4f55\u5f71\u54cd\u8eab\u4f53\u7684 \u7b2c67\u7ae0\u3000\u4e00\u5207\u90fd\u6e90\u81ea\u79ef\u6781\u5fc3\u6001 \u7b2c68\u7ae0\u3000\u5982\u4f55\u6539\u53d8\u4f60\u7684\u81ea\u6211\u5f62\u8c61 \u7b2c69\u7ae0\u3000\u7231\u60c5\u4e0e\u604b\u7231 \u7b2c70\u7ae0\u3000\u6211\u7684\u79c1\u623f\u6210\u529f\u4e66\u5355 \u7b2c71\u7ae0\u3000\u4e0d\u8981\u5bb3\u6015\u5931\u8d25 \u7b2c72\u7ae0\u3000\u8d70\u51fa\u8212\u9002\u533a \u7b2c73\u7ae0\u3000\u65af\u591a\u845b\u54f2\u5b66\uff0c\u4ee5\u53ca\u5b83\u5982\u4f55\u6539\u53d8\u4f60\u7684\u751f\u6d3b \u7b2c74\u7ae0\u3000\u7ed3\u675f\u8bed \u300a\u8f6f\u6280\u80fd2\uff1a\u8f6f\u4ef6\u5f00\u53d1\u8005\u804c\u4e1a\u751f\u6daf\u6307\u5357\u300b \u00b6 \u7b2c\u4e00\u7bc7 \u5165\u884c\u6210\u4e3a\u8f6f\u4ef6\u5f00\u53d1\u8005 \u7b2c2\u7ae0 \u8dec\u6b65\u5343\u91cc\uff1a\u5982\u4f55\u5165\u884c \u7b2c3\u7ae0 \u508d\u8eab\u4e4b\u6280\uff1a\u4f60\u9700\u8981\u62e5\u6709\u7684\u6280\u672f\u6280\u80fd \u7b2c4\u7ae0 \u683c\u7269\u81f4\u77e5\uff1a\u5982\u4f55\u62d3\u5c55\u6280\u672f\u6280\u80fd \u7b2c5\u7ae0 \u65e0\u95ee\u897f\u4e1c\uff1a\u5230\u5e95\u5e94\u8be5\u5b66\u54ea\u95e8\u7f16\u7a0b\u8bed\u8a00 \u7b2c6\u7ae0 \u59d7\u59d7\u5b66\u6b65\uff1a\u5982\u4f55\u5b66\u597d\u4f60\u7684\u7b2c\u4e00\u95e8\u7f16\u7a0b\u8bed\u8a00 \u7b2c7\u7ae0 \u5dcd\u5dcd\u5b66\u5e9c\uff1a\u901a\u8fc7\u4e0a\u5927\u5b66\u6df1\u9020\u6210\u4e3a\u8f6f\u4ef6\u5f00\u53d1\u8005 \u7b2c8\u7ae0 \u8eac\u884c\u5b9e\u8df5\uff1a\u901a\u8fc7\u53c2\u52a0\u7f16\u7a0b\u8bad\u7ec3\u8425\u6210\u4e3a\u8f6f\u4ef6\u5f00\u53d1\u8005 \u7b2c9\u7ae0 \u81ea\u5b66\u6210\u624d\uff1a\u901a\u8fc7\u81ea\u5b66\u6210\u4e3a\u8f6f\u4ef6\u5f00\u53d1\u8005 \u7b2c\u4e8c\u7bc7 \u627e\u5230\u4e00\u4efd\u5de5\u4f5c \u7b2c10\u7ae0 \u521d\u51fa\u8305\u5e90\uff1a\u600e\u6837\u83b7\u5f97\u5b9e\u4e60\u673a\u4f1a \u7b2c11\u7ae0 \u67f3\u6697\u82b1\u660e\uff1a\u6ca1\u6709\u7ecf\u9a8c\u5982\u4f55\u627e\u5230\u5de5\u4f5c \u7b2c12\u7ae0 \u72ec\u8f9f\u8e4a\u5f84\uff1a\u627e\u5de5\u4f5c\u65f6\u7684\u521b\u65b0\u601d\u7ef4 \u7b2c13\u7ae0 \u79fb\u6a3d\u5c31\u6559\uff1a\u600e\u6837\u5199\u7b80\u5386 \u7b2c14\u7ae0 \u9526\u56ca\u5999\u8ba1\uff1a\u5982\u4f55\u5bf9\u4ed8\u9762\u8bd5 \u7b2c15\u7ae0 \u5507\u67aa\u820c\u5251\uff1a\u5173\u4e8e\u85aa\u916c\u8c08\u5224 \u7b2c16\u7ae0 \u5c71\u9ad8\u6c34\u957f\uff1a\u5982\u679c\u8981\u79bb\u804c\uff0c\u8be5\u600e\u4e48\u505a \u7b2c17\u7ae0 \u534a\u8def\u51fa\u5bb6\uff1a\u5982\u4f55\u4ece\u5176\u4ed6\u884c\u4e1a\u8f6c\u884c\u6210\u4e3a\u8f6f\u4ef6\u5f00\u53d1\u8005 \u7b2c18\u7ae0 \u9047\u6c34\u53e0\u6865\uff1a\u5982\u4f55\u4ece\u6d4b\u8bd5\u6216\u8005\u5176\u4ed6\u6280\u672f\u6027\u89d2\u8272\u8f6c\u578b\u6210\u4e3a\u8f6f\u4ef6\u5f00\u53d1\u8005 \u7b2c19\u7ae0 \u638e\u646d\u5229\u75c5\uff1a\u5408\u540c\u5236\u5458\u5de5\u4e0e\u9886\u85aa\u5236\u6b63\u5f0f\u96c7\u5458\u4e4b\u95f4\u7684\u6bd4\u8f83 \u7b2c20\u7ae0 \u53bb\u68af\u4e4b\u8a00\uff1a\u4ece\u672a\u516c\u5f00\u8fc7\u7684\u62db\u8058\u884c\u4e1a\u8fd0\u4f5c\u7684\u79d8\u5bc6 \u7b2c\u4e09\u7bc7 \u5173\u4e8e\u8f6f\u4ef6\u5f00\u53d1\u4f60\u9700\u8981\u77e5\u9053\u4e9b\u4ec0\u4e48 \u7b2c21\u7ae0 \u8d70\u9a6c\u89c2\u82b1\uff1a\u7f16\u7a0b\u8bed\u8a00\u6982\u8ff0 \u7b2c22\u7ae0 \u77e5\u96be\u800c\u8fdb\uff1a\u4ec0\u4e48\u662fWeb\u5f00\u53d1 \u7b2c23\u7ae0 \u524d\u9014\u5927\u597d\uff1a\u79fb\u52a8\u5f00\u53d1 \u7b2c24\u7ae0 \u5e55\u540e\u82f1\u96c4\uff1a\u540e\u7aef\u5f00\u53d1 \u7b2c25\u7ae0 \u6e38\u620f\u4eba\u751f\uff1a\u6e38\u620f\u5f00\u53d1\u8005\u7684\u804c\u4e1a\u751f\u6daf \u7b2c26\u7ae0 \u4e8b\u65e0\u5de8\u7ec6\uff1aDBA\u4e0eDevOps \u7b2c27\u7ae0 \u9ad8\u5c4b\u5efa\u74f4\uff1a\u8f6f\u4ef6\u5f00\u53d1\u65b9\u6cd5\u8bba \u7b2c28\u7ae0 \u5c42\u5c42\u8bbe\u9632\uff1a\u6d4b\u8bd5\u548cQA\u57fa\u7840 \u7b2c29\u7ae0 \u6e90\u5934\u628a\u5173\uff1a\u6d4b\u8bd5\u9a71\u52a8\u5f00\u53d1\u4e0e\u5355\u5143\u6d4b\u8bd5 \u7b2c30\u7ae0 \u6e05\u6e05\u723d\u723d\uff1a\u6e90\u4ee3\u7801\u63a7\u5236 \u7b2c31\u7ae0 \u6b65\u6b65\u4e3a\u8425\uff1a\u6301\u7eed\u96c6\u6210 \u7b2c32\u7ae0 \u706b\u773c\u91d1\u775b\uff1a\u8c03\u8bd5 \u7b2c33\u7ae0 \u65e5\u81fb\u5b8c\u5584\uff1a\u4ee3\u7801\u7ef4\u62a4 \u7b2c34\u7ae0 \u5b9e\u81f3\u540d\u5f52\uff1a\u5de5\u4f5c\u5c97\u4f4d\u4e0e\u5934\u8854 \u7b2c35\u7ae0 \u591a\u59ff\u591a\u5f69\uff1a\u8f6f\u4ef6\u5f00\u53d1\u8005\u7684\u5de5\u4f5c\u7c7b\u578b \u7b2c\u56db\u7bc7 \u8f6f\u4ef6\u5f00\u53d1\u8005\u7684\u65e5\u5e38\u5de5\u4f5c \u7b2c36\u7ae0 \u548c\u800c\u4e0d\u540c\uff1a\u4e0e\u540c\u4e8b\u76f8\u5904 \u7b2c37\u7ae0 \u987a\u52bf\u800c\u4e3a\uff1a\u4e0e\u8001\u677f\u76f8\u5904 \u7b2c38\u7ae0 \u534f\u529b\u5171\u8fdb\uff1a\u4e0e\u6d4b\u8bd5\u4eba\u5458\u76f8\u5904 \u7b2c39\u7ae0 \u7b49\u91cf\u9f50\u89c2\uff1a\u5de5\u4f5c\u4e0e\u751f\u6d3b\u7684\u5e73\u8861 \u7b2c40\u7ae0 \u5e76\u80a9\u4f5c\u6218\uff1a\u4e0e\u56e2\u961f\u534f\u4f5c \u7b2c41\u7ae0 \u8c20\u8a00\u5609\u8bba\uff1a\u63a8\u9500\u4f60\u7684\u60f3\u6cd5 \u7b2c42\u7ae0 \u8863\u51a0\u695a\u695a\uff1a\u5982\u4f55\u7740\u88c5 \u7b2c43\u7ae0 \u8c0b\u4e8b\u5728\u4eba\uff1a\u5b89\u7136\u6e21\u8fc7\u7ee9\u6548\u8bc4\u4f30 \u7b2c44\u7ae0 \u5149\u660e\u78ca\u843d\uff1a\u5904\u7406\u504f\u89c1 \u7b2c45\u7ae0 \u8eab\u5148\u58eb\u5352\uff1a\u5904\u4e8e\u9886\u5bfc\u7684\u4f4d\u7f6e \u7b2c46\u7ae0 \u524d\u7a0b\u4f3c\u9526\uff1a\u83b7\u5f97\u63d0\u62d4\u4e0e\u664b\u5347 \u7b2c47\u7ae0 \u5dfe\u5e3c\u82f1\u96c4\uff1a\u79d1\u6280\u5973\u6027 \u7b2c\u4e94\u7bc7 \u63a8\u8fdb\u4f60\u7684\u804c\u4e1a\u53d1\u5c55 \u7b2c48\u7ae0 \u540d\u6ee1\u5929\u4e0b\uff1a\u5efa\u7acb\u58f0\u8a89 \u7b2c49\u7ae0 \u5e7f\u7ed3\u5584\u7f18\uff1a\u793e\u4ea4\u4e0e\u4eba\u8109 \u7b2c50\u7ae0 \u4e0e\u65f6\u4ff1\u8fdb\uff1a\u8ba9\u4f60\u7684\u6280\u80fd\u7d27\u8ddf\u4e0a\u65f6\u4ee3 \u7b2c51\u7ae0 \u884c\u5bb6\u91cc\u624b\uff1a\u505a\u4e13\u624d\u8fd8\u662f\u505a\u901a\u624d \u7b2c52\u7ae0 \u4f20\u7ecf\u5e03\u9053\uff1a\u6f14\u8bb2\u548c\u53c2\u52a0\u4f1a\u8bae \u7b2c53\u7ae0 \u7b14\u8015\u4e0d\u8f8d\uff1a\u521b\u5efa\u535a\u5ba2 \u7b2c54\u7ae0 \u6d77\u9614\u5929\u7a7a\uff1a\u505a\u81ea\u7531\u804c\u4e1a\u8005\u4e43\u81f3\u521b\u4e1a \u7b2c55\u7ae0 \u7b56\u9a6c\u626c\u97ad\uff1a\u804c\u4e1a\u53d1\u5c55\u8def\u5f84 \u7b2c56\u7ae0 \u672a\u96e8\u7ef8\u7f2a\uff1a\u5de5\u4f5c\u7a33\u5b9a\u6027\u4e0e\u5de5\u4f5c\u4fdd\u969c \u7b2c57\u7ae0 \u5b66\u65e0\u6b62\u5883\uff1a\u57f9\u8bad\u4e0e\u8d44\u683c\u8ba4\u8bc1 \u7b2c58\u7ae0 \u4e50\u6b64\u4e0d\u75b2\uff1a\u517c\u804c\u9879\u76ee \u7b2c59\u7ae0 \u5f00\u5377\u6709\u76ca\uff1a\u8981\u8bfb\u7684\u597d\u4e66 \u7b2c60\u7ae0 \u4f59\u97f3\u8885\u8885\uff1a\u7ed3\u675f\u8bed \u8bfb\u540e\u611f \u00b6","title":"\u7a0b\u5e8f\u5458\u7684\u804c\u4e1a\u548c\u751f\u5b58\u6307\u5357"},{"location":"Reading/Developers/#-2","text":"2024\u5e74\u5143\u65e6\u540e\u8bfb\u4e86\u7ea6\u7ff0\u00b7\u68ee\u6885\u5179\uff08John Sonmez\uff09\u76842\u672c\u4e66\uff0c\u5f88\u6709\u5171\u9e23\uff0c\u4ea7\u751f\u4e86\u5199\u8bfb\u4e66\u611f\u60f3\u7684\u5ff5\u5934\uff0c\u501f\u673a\u4e5f\u68b3\u7406\u4e86\u6211\u4e2a\u4eba\u7684\u89c2\u70b9\u548c\u60f3\u6cd5\uff0c\u4e8e\u662f\u4fbf\u6709\u4e86\u4e0b\u9762\u8fd9\u4e9b\u6587\u7ae0\u3002","title":"\u7a0b\u5e8f\u5458\u7684\u804c\u4e1a\u548c\u751f\u5b58\u6307\u5357 - \u8bfb\u7ea6\u7ff0\u00b7\u68ee\u6885\u5179\u76842\u672c\u4e66\u6709\u611f"},{"location":"Reading/Developers/#2","text":"\u7b2c\u4e00\u7bc7\u3000\u804c\u4e1a \u7b2c2\u7ae0\u3000\u7ecf\u8425\u81ea\u5df1\u7684\u804c\u4e1a\u751f\u6daf\u5c31\u50cf\u7ecf\u8425\u4e00\u5bb6\u4f01\u4e1a \u7b2c3\u7ae0\u3000\u5982\u4f55\u7ed9\u81ea\u5df1\u8bbe\u5b9a\u597d\u804c\u4e1a\u76ee\u6807 \u7b2c4\u7ae0\u3000\u62d3\u5c55\u81ea\u5df1\u7684\u4eba\u9645\u4ea4\u5f80\u80fd\u529b \u7b2c5\u7ae0\u3000\u521b\u5efa\u4e00\u4efd\u5c61\u8bd5\u5c61\u9a8c\u7684\u7b80\u5386 \u7b2c6\u7ae0\u3000\u7834\u89e3\u9762\u8bd5\u4e4b\u9053 \u7b2c7\u7ae0\u3000\u8f6f\u4ef6\u5f00\u53d1\u4eba\u5458\u7684\u4e09\u6761\u804c\u4e1a\u8def\u5f84 \u7b2c8\u7ae0\u3000\u4e3a\u4ec0\u4e48\u4f60\u9700\u8981\u8d70\u4e13\u4e1a\u5316\u9053\u8def \u7b2c9\u7ae0\u3000\u516c\u53f8\u4e0e\u516c\u53f8\u662f\u4e0d\u4e00\u6837\u7684 \u7b2c10\u7ae0\u3000\u6500\u767b\u664b\u5347\u9636\u68af \u7b2c11\u7ae0\u3000\u6210\u4e3a\u4e13\u4e1a\u4eba\u58eb \u7b2c12\u7ae0\u3000\u4e0e\u8001\u677f\u548c\u540c\u4e8b\u7684\u76f8\u5904\u4e4b\u9053 \u7b2c13\u7ae0\u3000\u4e0d\u8981\u9677\u5165\u5bf9\u6280\u672f\u7684\u72c2\u70ed\u4e4b\u4e2d \u7b2c14\u7ae0\u3000\u5982\u4f55\u8f9e\u804c\u5e76\u5f00\u59cb\u4e3a\u81ea\u5df1\u5de5\u4f5c \u7b2c15\u7ae0\u3000\u5982\u4f55\u6210\u4e3a\u81ea\u7531\u804c\u4e1a\u8005 \u7b2c16\u7ae0\u3000\u5982\u4f55\u6210\u4e3a\u4e00\u540d\u4f01\u4e1a\u5bb6 \u7b2c17\u7ae0\u3000\u5982\u4f55\u5f00\u59cb\u521b\u4e1a \u7b2c18\u7ae0\u3000\u8fdc\u7a0b\u5de5\u4f5c \u7b2c\u4e8c\u7bc7\u3000\u81ea\u6211\u8425\u9500 \u7b2c19\u7ae0\u3000\u81ea\u6211\u8425\u9500\u57fa\u7840\u8bfe \u7b2c20\u7ae0\u3000\u5982\u4f55\u6253\u9020\u4e2a\u4eba\u54c1\u724c \u7b2c21\u7ae0\u3000\u5982\u4f55\u521b\u5efa\u5927\u83b7\u6210\u529f\u7684\u535a\u5ba2 \u7b2c22\u7ae0\u3000\u5728YouTube\u4e0a\u521b\u7acb\u81ea\u5df1\u7684\u4e13\u680f \u7b2c23\u7ae0\u3000\u4e3a\u4f55\u4e3a\u4ed6\u4eba\u589e\u52a0\u4ef7\u503c\u975e\u5e38\u91cd\u8981 \u7b2c24\u7ae0\u3000\u5584\u4e8e\u8fd0\u7528\u793e\u4ea4\u5a92\u4f53\u63d0\u5347\u81ea\u5df1\u7684\u54c1\u724c \u7b2c25\u7ae0\u3000\u6f14\u8bb2\u3001\u57f9\u8bad\u548c\u62a5\u544a \u7b2c26\u7ae0\u3000\u8457\u4e66\u7acb\u8bf4 \u7b2c\u4e09\u7bc7\u3000\u5b66\u4e60 \u7b2c27\u7ae0\u3000\u5b66\u4e60\u600e\u6837\u5b66\u4e60 \u7b2c28\u7ae0\u3000\u6211\u7684\u201c\u5341\u6b65\u5b66\u4e60\u6cd5\u201d \u7b2c29\u7ae0\u3000\u7b2c 1 \u6b65\u5230\u7b2c 6 \u6b65\uff1a\u8fd9\u4e9b\u6b65\u9aa4\u53ea\u505a\u4e00\u6b21 \u7b2c30\u7ae0\u3000\u7b2c7\u6b65\u5230\u7b2c10\u6b65\uff1a\u5faa\u73af\u5f80\u590d \u7b2c31\u7ae0\u3000\u5982\u4f55\u5bfb\u627e\u5bfc\u5e08 \u7b2c32\u7ae0\u3000\u5982\u4f55\u6210\u4e3a\u5bfc\u5e08 \u7b2c33\u7ae0\u3000\u4e3a\u4f55\u8bf4\u6559\u5b66\u76f8\u957f \u7b2c34\u7ae0\u3000\u4f60\u9700\u8981\u4e00\u4e2a\u5927\u5b66\u5b66\u4f4d\u5417 \u7b2c35\u7ae0\u3000\u53d1\u73b0\u81ea\u5df1\u7684\u77e5\u8bc6\u77ed\u677f \u7b2c\u56db\u7bc7\u3000\u751f\u4ea7\u529b \u7b2c36\u7ae0\u3000\u4e00\u5207\u59cb\u4e8e\u4e13\u6ce8 \u7b2c37\u7ae0\u3000\u6211\u7684\u79c1\u623f\u201c\u751f\u4ea7\u529b\u63d0\u5347\u8ba1\u5212\u201d \u7b2c38\u7ae0\u3000\u756a\u8304\u5de5\u4f5c\u6cd5 \u7b2c39\u7ae0\u3000\u6211\u7684\u201c\u5b9a\u989d\u5de5\u4f5c\u6cd5\u201d \u7b2c40\u7ae0\u3000\u5bf9\u81ea\u5df1\u8d1f\u8d23 \u7b2c41\u7ae0\u3000\u4e3a\u4ec0\u4e48\u8bf4\u591a\u4efb\u52a1\u5e76\u884c\u5f0a\u5927\u4e8e\u5229 \u7b2c42\u7ae0\u3000\u5982\u4f55\u5e94\u5bf9\u804c\u4e1a\u5026\u6020 \u7b2c43\u7ae0\u3000\u4f60\u662f\u600e\u6837\u6d6a\u8d39\u6389\u65f6\u95f4\u7684 \u7b2c44\u7ae0\u3000\u5f62\u6210\u60ef\u4f8b\u7684\u91cd\u8981\u6027 \u7b2c45\u7ae0\u3000\u5982\u4f55\u57f9\u517b\u597d\u4e60\u60ef \u7b2c46\u7ae0\u3000\u5206\u89e3\u4efb\u52a1\u4f1a\u63d0\u9ad8\u751f\u4ea7\u529b \u7b2c47\u7ae0\u3000\u52aa\u529b\u5de5\u4f5c\u7684\u4ef7\u503c\uff0c\u4ee5\u53ca\u4e3a\u4ec0\u4e48\u4f60\u603b\u662f\u9003\u907f\u52aa\u529b\u5de5\u4f5c \u7b2c48\u7ae0\u3000\u4efb\u4f55\u884c\u52a8\u90fd\u6bd4\u4e0d\u91c7\u53d6\u884c\u52a8\u597d \u7b2c\u4e94\u7bc7\u3000\u7406\u8d22 \u7b2c49\u7ae0\u3000\u5408\u7406\u652f\u914d\u4f60\u7684\u85aa\u6c34 \u7b2c50\u7ae0\u3000\u600e\u6837\u8fdb\u884c\u85aa\u916c\u8c08\u5224 \u7b2c51\u7ae0\u3000\u4e3a\u4f55\u8bf4\u623f\u5730\u4ea7\u662f\u6700\u597d\u7684\u6295\u8d44 \u7b2c52\u7ae0\u3000\u4f60\u771f\u7684\u4e86\u89e3\u81ea\u5df1\u7684\u9000\u4f11\u8ba1\u5212\u5417 \u7b2c53\u7ae0\u3000\u503a\u52a1\u7684\u5371\u5bb3 \u7b2c54\u7ae0\u3000\u5982\u4f55\u521b\u9020\u771f\u6b63\u7684\u8d22\u5bcc \u7b2c55\u7ae0\u3000\u6211\u662f\u5982\u4f55\u505a\u523033\u5c81\u9000\u4f11\u7684 \u7b2c\u516d\u7bc7\u3000\u5065\u8eab \u7b2c56\u7ae0\u3000\u5065\u8eab\u7684\u597d\u5904 \u7b2c57\u7ae0\u3000\u8bbe\u5b9a\u4f60\u7684\u5065\u8eab\u76ee\u6807 \u7b2c58\u7ae0\u3000\u5982\u4f55\u51cf\u80a5\uff08\u6216\u8005\u589e\u91cd\uff09 \u7b2c59\u7ae0\u3000\u5065\u8eab\u7684\u52a8\u529b\u4ece\u4f55\u800c\u6765 \u7b2c60\u7ae0\u3000\u589e\u808c \u7b2c61\u7ae0\u3000\u5982\u4f55\u83b7\u5f97\u5b8c\u7f8e\u8179\u808c \u7b2c62\u7ae0\u3000\u5f00\u59cb\u8dd1\u6b65 \u7b2c63\u7ae0\u3000\u6211\u7684\u51cf\u8102\u589e\u808c\u79d8\u8bc0 \u7b2c64\u7ae0\u3000\u7ad9\u7acb\u5f0f\u529e\u516c\u53ca\u5176\u4ed6\u7a8d\u95e8 \u7b2c65\u7ae0\u3000\u5229\u7528\u9ad8\u79d1\u6280\u88c5\u5907\u5065\u8eab \u7b2c\u4e03\u7bc7\u3000\u5fc3\u6001 \u7b2c66\u7ae0\u3000\u5fc3\u667a\u662f\u5982\u4f55\u5f71\u54cd\u8eab\u4f53\u7684 \u7b2c67\u7ae0\u3000\u4e00\u5207\u90fd\u6e90\u81ea\u79ef\u6781\u5fc3\u6001 \u7b2c68\u7ae0\u3000\u5982\u4f55\u6539\u53d8\u4f60\u7684\u81ea\u6211\u5f62\u8c61 \u7b2c69\u7ae0\u3000\u7231\u60c5\u4e0e\u604b\u7231 \u7b2c70\u7ae0\u3000\u6211\u7684\u79c1\u623f\u6210\u529f\u4e66\u5355 \u7b2c71\u7ae0\u3000\u4e0d\u8981\u5bb3\u6015\u5931\u8d25 \u7b2c72\u7ae0\u3000\u8d70\u51fa\u8212\u9002\u533a \u7b2c73\u7ae0\u3000\u65af\u591a\u845b\u54f2\u5b66\uff0c\u4ee5\u53ca\u5b83\u5982\u4f55\u6539\u53d8\u4f60\u7684\u751f\u6d3b \u7b2c74\u7ae0\u3000\u7ed3\u675f\u8bed","title":"\u300a\u8f6f\u6280\u80fd\uff1a\u4ee3\u7801\u4e4b\u5916\u7684\u751f\u5b58\u6307\u5357\uff08\u7b2c2\u7248\uff09\u300b"},{"location":"Reading/Developers/#2_1","text":"\u7b2c\u4e00\u7bc7 \u5165\u884c\u6210\u4e3a\u8f6f\u4ef6\u5f00\u53d1\u8005 \u7b2c2\u7ae0 \u8dec\u6b65\u5343\u91cc\uff1a\u5982\u4f55\u5165\u884c \u7b2c3\u7ae0 \u508d\u8eab\u4e4b\u6280\uff1a\u4f60\u9700\u8981\u62e5\u6709\u7684\u6280\u672f\u6280\u80fd \u7b2c4\u7ae0 \u683c\u7269\u81f4\u77e5\uff1a\u5982\u4f55\u62d3\u5c55\u6280\u672f\u6280\u80fd \u7b2c5\u7ae0 \u65e0\u95ee\u897f\u4e1c\uff1a\u5230\u5e95\u5e94\u8be5\u5b66\u54ea\u95e8\u7f16\u7a0b\u8bed\u8a00 \u7b2c6\u7ae0 \u59d7\u59d7\u5b66\u6b65\uff1a\u5982\u4f55\u5b66\u597d\u4f60\u7684\u7b2c\u4e00\u95e8\u7f16\u7a0b\u8bed\u8a00 \u7b2c7\u7ae0 \u5dcd\u5dcd\u5b66\u5e9c\uff1a\u901a\u8fc7\u4e0a\u5927\u5b66\u6df1\u9020\u6210\u4e3a\u8f6f\u4ef6\u5f00\u53d1\u8005 \u7b2c8\u7ae0 \u8eac\u884c\u5b9e\u8df5\uff1a\u901a\u8fc7\u53c2\u52a0\u7f16\u7a0b\u8bad\u7ec3\u8425\u6210\u4e3a\u8f6f\u4ef6\u5f00\u53d1\u8005 \u7b2c9\u7ae0 \u81ea\u5b66\u6210\u624d\uff1a\u901a\u8fc7\u81ea\u5b66\u6210\u4e3a\u8f6f\u4ef6\u5f00\u53d1\u8005 \u7b2c\u4e8c\u7bc7 \u627e\u5230\u4e00\u4efd\u5de5\u4f5c \u7b2c10\u7ae0 \u521d\u51fa\u8305\u5e90\uff1a\u600e\u6837\u83b7\u5f97\u5b9e\u4e60\u673a\u4f1a \u7b2c11\u7ae0 \u67f3\u6697\u82b1\u660e\uff1a\u6ca1\u6709\u7ecf\u9a8c\u5982\u4f55\u627e\u5230\u5de5\u4f5c \u7b2c12\u7ae0 \u72ec\u8f9f\u8e4a\u5f84\uff1a\u627e\u5de5\u4f5c\u65f6\u7684\u521b\u65b0\u601d\u7ef4 \u7b2c13\u7ae0 \u79fb\u6a3d\u5c31\u6559\uff1a\u600e\u6837\u5199\u7b80\u5386 \u7b2c14\u7ae0 \u9526\u56ca\u5999\u8ba1\uff1a\u5982\u4f55\u5bf9\u4ed8\u9762\u8bd5 \u7b2c15\u7ae0 \u5507\u67aa\u820c\u5251\uff1a\u5173\u4e8e\u85aa\u916c\u8c08\u5224 \u7b2c16\u7ae0 \u5c71\u9ad8\u6c34\u957f\uff1a\u5982\u679c\u8981\u79bb\u804c\uff0c\u8be5\u600e\u4e48\u505a \u7b2c17\u7ae0 \u534a\u8def\u51fa\u5bb6\uff1a\u5982\u4f55\u4ece\u5176\u4ed6\u884c\u4e1a\u8f6c\u884c\u6210\u4e3a\u8f6f\u4ef6\u5f00\u53d1\u8005 \u7b2c18\u7ae0 \u9047\u6c34\u53e0\u6865\uff1a\u5982\u4f55\u4ece\u6d4b\u8bd5\u6216\u8005\u5176\u4ed6\u6280\u672f\u6027\u89d2\u8272\u8f6c\u578b\u6210\u4e3a\u8f6f\u4ef6\u5f00\u53d1\u8005 \u7b2c19\u7ae0 \u638e\u646d\u5229\u75c5\uff1a\u5408\u540c\u5236\u5458\u5de5\u4e0e\u9886\u85aa\u5236\u6b63\u5f0f\u96c7\u5458\u4e4b\u95f4\u7684\u6bd4\u8f83 \u7b2c20\u7ae0 \u53bb\u68af\u4e4b\u8a00\uff1a\u4ece\u672a\u516c\u5f00\u8fc7\u7684\u62db\u8058\u884c\u4e1a\u8fd0\u4f5c\u7684\u79d8\u5bc6 \u7b2c\u4e09\u7bc7 \u5173\u4e8e\u8f6f\u4ef6\u5f00\u53d1\u4f60\u9700\u8981\u77e5\u9053\u4e9b\u4ec0\u4e48 \u7b2c21\u7ae0 \u8d70\u9a6c\u89c2\u82b1\uff1a\u7f16\u7a0b\u8bed\u8a00\u6982\u8ff0 \u7b2c22\u7ae0 \u77e5\u96be\u800c\u8fdb\uff1a\u4ec0\u4e48\u662fWeb\u5f00\u53d1 \u7b2c23\u7ae0 \u524d\u9014\u5927\u597d\uff1a\u79fb\u52a8\u5f00\u53d1 \u7b2c24\u7ae0 \u5e55\u540e\u82f1\u96c4\uff1a\u540e\u7aef\u5f00\u53d1 \u7b2c25\u7ae0 \u6e38\u620f\u4eba\u751f\uff1a\u6e38\u620f\u5f00\u53d1\u8005\u7684\u804c\u4e1a\u751f\u6daf \u7b2c26\u7ae0 \u4e8b\u65e0\u5de8\u7ec6\uff1aDBA\u4e0eDevOps \u7b2c27\u7ae0 \u9ad8\u5c4b\u5efa\u74f4\uff1a\u8f6f\u4ef6\u5f00\u53d1\u65b9\u6cd5\u8bba \u7b2c28\u7ae0 \u5c42\u5c42\u8bbe\u9632\uff1a\u6d4b\u8bd5\u548cQA\u57fa\u7840 \u7b2c29\u7ae0 \u6e90\u5934\u628a\u5173\uff1a\u6d4b\u8bd5\u9a71\u52a8\u5f00\u53d1\u4e0e\u5355\u5143\u6d4b\u8bd5 \u7b2c30\u7ae0 \u6e05\u6e05\u723d\u723d\uff1a\u6e90\u4ee3\u7801\u63a7\u5236 \u7b2c31\u7ae0 \u6b65\u6b65\u4e3a\u8425\uff1a\u6301\u7eed\u96c6\u6210 \u7b2c32\u7ae0 \u706b\u773c\u91d1\u775b\uff1a\u8c03\u8bd5 \u7b2c33\u7ae0 \u65e5\u81fb\u5b8c\u5584\uff1a\u4ee3\u7801\u7ef4\u62a4 \u7b2c34\u7ae0 \u5b9e\u81f3\u540d\u5f52\uff1a\u5de5\u4f5c\u5c97\u4f4d\u4e0e\u5934\u8854 \u7b2c35\u7ae0 \u591a\u59ff\u591a\u5f69\uff1a\u8f6f\u4ef6\u5f00\u53d1\u8005\u7684\u5de5\u4f5c\u7c7b\u578b \u7b2c\u56db\u7bc7 \u8f6f\u4ef6\u5f00\u53d1\u8005\u7684\u65e5\u5e38\u5de5\u4f5c \u7b2c36\u7ae0 \u548c\u800c\u4e0d\u540c\uff1a\u4e0e\u540c\u4e8b\u76f8\u5904 \u7b2c37\u7ae0 \u987a\u52bf\u800c\u4e3a\uff1a\u4e0e\u8001\u677f\u76f8\u5904 \u7b2c38\u7ae0 \u534f\u529b\u5171\u8fdb\uff1a\u4e0e\u6d4b\u8bd5\u4eba\u5458\u76f8\u5904 \u7b2c39\u7ae0 \u7b49\u91cf\u9f50\u89c2\uff1a\u5de5\u4f5c\u4e0e\u751f\u6d3b\u7684\u5e73\u8861 \u7b2c40\u7ae0 \u5e76\u80a9\u4f5c\u6218\uff1a\u4e0e\u56e2\u961f\u534f\u4f5c \u7b2c41\u7ae0 \u8c20\u8a00\u5609\u8bba\uff1a\u63a8\u9500\u4f60\u7684\u60f3\u6cd5 \u7b2c42\u7ae0 \u8863\u51a0\u695a\u695a\uff1a\u5982\u4f55\u7740\u88c5 \u7b2c43\u7ae0 \u8c0b\u4e8b\u5728\u4eba\uff1a\u5b89\u7136\u6e21\u8fc7\u7ee9\u6548\u8bc4\u4f30 \u7b2c44\u7ae0 \u5149\u660e\u78ca\u843d\uff1a\u5904\u7406\u504f\u89c1 \u7b2c45\u7ae0 \u8eab\u5148\u58eb\u5352\uff1a\u5904\u4e8e\u9886\u5bfc\u7684\u4f4d\u7f6e \u7b2c46\u7ae0 \u524d\u7a0b\u4f3c\u9526\uff1a\u83b7\u5f97\u63d0\u62d4\u4e0e\u664b\u5347 \u7b2c47\u7ae0 \u5dfe\u5e3c\u82f1\u96c4\uff1a\u79d1\u6280\u5973\u6027 \u7b2c\u4e94\u7bc7 \u63a8\u8fdb\u4f60\u7684\u804c\u4e1a\u53d1\u5c55 \u7b2c48\u7ae0 \u540d\u6ee1\u5929\u4e0b\uff1a\u5efa\u7acb\u58f0\u8a89 \u7b2c49\u7ae0 \u5e7f\u7ed3\u5584\u7f18\uff1a\u793e\u4ea4\u4e0e\u4eba\u8109 \u7b2c50\u7ae0 \u4e0e\u65f6\u4ff1\u8fdb\uff1a\u8ba9\u4f60\u7684\u6280\u80fd\u7d27\u8ddf\u4e0a\u65f6\u4ee3 \u7b2c51\u7ae0 \u884c\u5bb6\u91cc\u624b\uff1a\u505a\u4e13\u624d\u8fd8\u662f\u505a\u901a\u624d \u7b2c52\u7ae0 \u4f20\u7ecf\u5e03\u9053\uff1a\u6f14\u8bb2\u548c\u53c2\u52a0\u4f1a\u8bae \u7b2c53\u7ae0 \u7b14\u8015\u4e0d\u8f8d\uff1a\u521b\u5efa\u535a\u5ba2 \u7b2c54\u7ae0 \u6d77\u9614\u5929\u7a7a\uff1a\u505a\u81ea\u7531\u804c\u4e1a\u8005\u4e43\u81f3\u521b\u4e1a \u7b2c55\u7ae0 \u7b56\u9a6c\u626c\u97ad\uff1a\u804c\u4e1a\u53d1\u5c55\u8def\u5f84 \u7b2c56\u7ae0 \u672a\u96e8\u7ef8\u7f2a\uff1a\u5de5\u4f5c\u7a33\u5b9a\u6027\u4e0e\u5de5\u4f5c\u4fdd\u969c \u7b2c57\u7ae0 \u5b66\u65e0\u6b62\u5883\uff1a\u57f9\u8bad\u4e0e\u8d44\u683c\u8ba4\u8bc1 \u7b2c58\u7ae0 \u4e50\u6b64\u4e0d\u75b2\uff1a\u517c\u804c\u9879\u76ee \u7b2c59\u7ae0 \u5f00\u5377\u6709\u76ca\uff1a\u8981\u8bfb\u7684\u597d\u4e66 \u7b2c60\u7ae0 \u4f59\u97f3\u8885\u8885\uff1a\u7ed3\u675f\u8bed","title":"\u300a\u8f6f\u6280\u80fd2\uff1a\u8f6f\u4ef6\u5f00\u53d1\u8005\u804c\u4e1a\u751f\u6daf\u6307\u5357\u300b"},{"location":"Reading/Developers/#_1","text":"","title":"\u8bfb\u540e\u611f"},{"location":"k8s/","text":"\u6211\u7684Kubernetes\u5b66\u4e60\u5fc3\u5f97 \u00b6 \u4f5c\u4e3a\u4e00\u79cd\u5f00\u6e90\u7684\u5bb9\u5668\u7f16\u6392\u7cfb\u7edf\uff0cKubernetes \u4e3a\u8fd0\u884c\u5728\u5bb9\u5668\u4e2d\u7684\u5e94\u7528\u7a0b\u5e8f\u63d0\u4f9b\u4e86\u4e00\u79cd\u7ba1\u7406\u65b9\u5f0f\u3002Kubernetes \u5177\u6709\u5f88\u591a\u5f3a\u5927\u7684\u529f\u80fd\uff0c\u4f8b\u5982\u81ea\u52a8\u5316\u90e8\u7f72\u3001\u8d1f\u8f7d\u5747\u8861\u3001\u81ea\u52a8\u6269\u5c55\u3001\u81ea\u52a8\u6062\u590d\u7b49\u3002 \u516c\u53f8\u5185\u90e8\u7684\u4e91\u5e73\u53f0\u4e5f\u5728\u4eceCloud Foundry\u73af\u5883\u5f00\u59cb\u5411\u57fa\u4e8eKubernetes\u7684Kyma\u73af\u5883\u5ef6\u5c55\uff0c\u518d\u52a0\u4e0a\u5404\u79cd\u5a92\u4f53\u5bf9Kubernetes\u7684\u4ecb\u7ecd\uff0c\u662f\u6211\u5f00\u59cb\u4e86\u89e3Kubernetes\u7684\u5916\u90e8\u52a8\u56e0\u3002 \u5185\u90e8\u52a8\u56e0\uff0c\u5219\u662f\u6e90\u4e8e2022\u5e74\u6625\u8282\u671f\u95f4\u53c2\u52a0\u4e86\u516c\u53f8\u5185\u90e8\u7684\u4e00\u5468Kubernetes\u57fa\u7840\u57f9\u8bad\uff0c\u56e0\u4e3a\u6388\u8bfe\u5185\u5bb9\u662f\u82f1\u8bed\uff0c\u6240\u4ee5\u6709\u5f88\u591a\u7ec6\u8282\u5728\u57f9\u8bad\u4e2d\u662fget\u4e0d\u5230\u7684\uff0c\u4e3b\u8981\u8fd8\u662f\u8bed\u8a00\u80fd\u529b\u4e0d\u591f\u5f3a\u3002\u5f53\u65f6\u7684\u76ee\u6807\u53ea\u662f\u8ddf\u7740\u5b8c\u6210\u8bb2\u5e08\u8bfe\u5802\u6f14\u793a\u3002 \u4ece3\u6708\u5f00\u59cb\uff0c\u6211\u5728\u7f51\u4e0a\u4e86\u53c2\u8003\u4e86\u522b\u4eba\u7684Kubernetes\u7684\u5b66\u4e60\u5fc3\u5f97\u548c\u8def\u7ebf\u56fe\uff0c\u51b3\u5b9a\u4ee5CKA\uff08certificate of Kubernetes administration\uff09\u8ba4\u8bc1\u4f5c\u4e3a\u5f53\u524d\u5b66\u4e60\u7684\u76ee\u6807\uff0c\u5229\u7528B\u7ad9\u7684\u89c6\u9891\uff0c\u53c2\u8003\u5b98\u65b9\u6587\u6863\uff0c\u5f00\u59cb\u4ece\u5934\u5f00\u59cb\u5b66\u4e60Kubernetes\u7684\u57fa\u7840\u77e5\u8bc6\u3002 \u4e0b\u9762\u51c6\u5907CKA\u8003\u8bd5\u7684\u4e00\u4e9b\u5fc3\u5f97\u4f53\u4f1a\uff1a \u5b66\u4e60 Kubernetes \u524d\uff0c\u9700\u8981\u4e86\u89e3\u5bb9\u5668\u6280\u672f\u548c Docker\uff0c\u6216\u8005\u8bf4\u8981\u6709\u5bb9\u5668\u5316\u7684\u57fa\u672c\u6982\u5ff5\u548c\u601d\u60f3\u65b9\u6cd5\uff0c\u56e0\u4e3a Kubernetes \u662f\u57fa\u4e8e\u5bb9\u5668\u6280\u672f\u6784\u5efa\u7684\u3002 \u5b66\u4e60 Kubernetes \u65f6\uff0c\u9700\u8981\u638c\u63e1\u5176\u6838\u5fc3\u6982\u5ff5\uff0c\u4f8b\u5982 Pod\u3001ReplicaSet\u3001Deployment\u3001Service \u7b49\u3002\u8fd9\u4e9b\u6982\u5ff5\u662f\u7406\u89e3 Kubernetes \u7684\u57fa\u7840\uff0c\u4e5f\u662f\u540e\u7eed\u5b9e\u9645\u5e94\u7528\u4e2d\u7684\u91cd\u8981\u90e8\u5206\u3002 \u5b66\u4e60 Kubernetes \u65f6\uff0c\u9700\u8981\u638c\u63e1 yaml \u6587\u4ef6\u7684\u7f16\u5199\u65b9\u6cd5\uff0c\u7279\u522b\u662f\u90a3\u4e9b\u57fa\u672c\u8d44\u6e90\u7684yaml\u6587\u4ef6\uff0c\u8981\u80fd\u505a\u5230\u4e0d\u501f\u52a9\u5e2e\u52a9\u6587\u6863\u5c31\u80fd\u5199\u51fa\u6846\u67b6\uff0c\u5426\u5219\u8003\u8bd5\u65f6\u505a\u4e0d\u5b8c\u9898\u76ee\u7684\u3002 \u5b66\u4e60 Kubernetes \u65f6\uff0c\u9700\u8981\u638c\u63e1 kubectl \u547d\u4ee4\u7684\u4f7f\u7528\uff0c\u5e38\u7528\u8d44\u6e90\u76f8\u5173\u7684\u547d\u4ee4\uff0c\u4e5f\u8981\u505a\u5230\u4e0d\u501f\u52a9\u5e2e\u52a9\u6587\u6863\u5c31\u80fd\u5199\u51fa\uff0c\u5426\u5219\u8003\u8bd5\u65f6\u4e5f\u662f\u505a\u4e0d\u5b8c\u9898\u76ee\u7684\u3002 \u5b66\u4e60 Kubernetes \u65f6\uff0c\u9700\u8981\u638c\u63e1\u5176\u7f51\u7edc\u548c\u5b58\u50a8\u914d\u7f6e\uff0c\u4f8b\u5982 Service\u3001Ingress\u3001PersistentVolume\u3001PersistentVolumeClaim \u7b49\uff0c\u8fd9\u4e9b\u90fd\u662f\u8003\u8bd5\u91cd\u70b9\u5185\u5bb9\uff0c\u8981\u719f\u6089yaml\u7279\u6027\uff0c\u80fd\u6309\u4e0d\u540c\u7684\u8981\u6c42\u8fdb\u884c\u62d3\u5c55\u548c\u53d8\u66f4\u3002 \u90e8\u7f72\u548c\u7ba1\u7406 Kubernetes \u96c6\u7fa4\u4e5f\u662f\u4e00\u4e2a\u91cd\u70b9\uff0c\u6211\u662f\u5728\u963f\u91cc\u4e91\u4e0a\u4e70\u4e863\u4e2aECS\u4f5c\u4e3a\u5b9e\u9a8c\u73af\u5883\u3002 \u6211\u7684CKA\u7684\u7b14\u8bb0\u5206\u4e2d\u6587\u548c\u82f1\u6587\u4e24\u79cd\u3002\u82f1\u6587\u7b14\u8bb0\u662f\u57fa\u4e8e\u7b2c\u4e00\u6b21\u53c2\u52a0\u516c\u53f8\u57f9\u8bad\u7684\u77e5\u8bc6\u7ed3\u6784\u505a\u7684\uff0c\u5728\u5907\u8003\u8fc7\u7a0b\u4e2d\u9010\u6b65\u5b8c\u5584\u7684\u3002\u4e2d\u6587\u7b14\u8bb0\u662f\u57282023\u5e744\u6708\u4efd\u57fa\u4e8e\u82f1\u6587\u7b14\u8bb0\u81ea\u5df1\u7ffb\u8bd1\u8fc7\u6765\u7684\uff0c\u5e76\u53d1\u5e03\u5728\u6211\u7684\u77e5\u4e4e\u4e13\u680f\u4e0a\uff0c\u7ffb\u8bd1\u8fc7\u7a0b\u8fd8\u662f\u6bd4\u8f83\u96be\u7684\uff0c\u5f88\u591a\u82f1\u8bed\u5185\u5bb9\u627e\u4e0d\u5230\u5408\u9002\u7684\u4e2d\u6587\u8868\u8fbe\u65b9\u5f0f\uff0c\u4e0d\u8fc7\u5bf9\u4e8e\u8ba1\u7b97\u673a\u884c\u4e1a\u6765\u8bb2\uff0c\u4f7f\u7528\u82f1\u8bed\u9605\u8bfb\u4e13\u4e1a\u8d44\u6599\u5e94\u8be5\u662f\u4e00\u4e2a\u5171\u8bc6\u3002 \u53c2\u8003\u7b14\u8bb0\uff0c\u5e76\u5b8c\u6210\u7b14\u8bb0\u4e2d\u7684\u7ec3\u4e60\uff0c\u518d\u719f\u7ec3\u4f7f\u7528yaml\u6587\u4ef6\u548ckubectl\u547d\u4ee4\uff0c\u901a\u8fc7\u8003\u8bd5\u6ca1\u4ec0\u4e48\u56f0\u96be\u3002","title":"Index"},{"location":"k8s/#kubernetes","text":"\u4f5c\u4e3a\u4e00\u79cd\u5f00\u6e90\u7684\u5bb9\u5668\u7f16\u6392\u7cfb\u7edf\uff0cKubernetes \u4e3a\u8fd0\u884c\u5728\u5bb9\u5668\u4e2d\u7684\u5e94\u7528\u7a0b\u5e8f\u63d0\u4f9b\u4e86\u4e00\u79cd\u7ba1\u7406\u65b9\u5f0f\u3002Kubernetes \u5177\u6709\u5f88\u591a\u5f3a\u5927\u7684\u529f\u80fd\uff0c\u4f8b\u5982\u81ea\u52a8\u5316\u90e8\u7f72\u3001\u8d1f\u8f7d\u5747\u8861\u3001\u81ea\u52a8\u6269\u5c55\u3001\u81ea\u52a8\u6062\u590d\u7b49\u3002 \u516c\u53f8\u5185\u90e8\u7684\u4e91\u5e73\u53f0\u4e5f\u5728\u4eceCloud Foundry\u73af\u5883\u5f00\u59cb\u5411\u57fa\u4e8eKubernetes\u7684Kyma\u73af\u5883\u5ef6\u5c55\uff0c\u518d\u52a0\u4e0a\u5404\u79cd\u5a92\u4f53\u5bf9Kubernetes\u7684\u4ecb\u7ecd\uff0c\u662f\u6211\u5f00\u59cb\u4e86\u89e3Kubernetes\u7684\u5916\u90e8\u52a8\u56e0\u3002 \u5185\u90e8\u52a8\u56e0\uff0c\u5219\u662f\u6e90\u4e8e2022\u5e74\u6625\u8282\u671f\u95f4\u53c2\u52a0\u4e86\u516c\u53f8\u5185\u90e8\u7684\u4e00\u5468Kubernetes\u57fa\u7840\u57f9\u8bad\uff0c\u56e0\u4e3a\u6388\u8bfe\u5185\u5bb9\u662f\u82f1\u8bed\uff0c\u6240\u4ee5\u6709\u5f88\u591a\u7ec6\u8282\u5728\u57f9\u8bad\u4e2d\u662fget\u4e0d\u5230\u7684\uff0c\u4e3b\u8981\u8fd8\u662f\u8bed\u8a00\u80fd\u529b\u4e0d\u591f\u5f3a\u3002\u5f53\u65f6\u7684\u76ee\u6807\u53ea\u662f\u8ddf\u7740\u5b8c\u6210\u8bb2\u5e08\u8bfe\u5802\u6f14\u793a\u3002 \u4ece3\u6708\u5f00\u59cb\uff0c\u6211\u5728\u7f51\u4e0a\u4e86\u53c2\u8003\u4e86\u522b\u4eba\u7684Kubernetes\u7684\u5b66\u4e60\u5fc3\u5f97\u548c\u8def\u7ebf\u56fe\uff0c\u51b3\u5b9a\u4ee5CKA\uff08certificate of Kubernetes administration\uff09\u8ba4\u8bc1\u4f5c\u4e3a\u5f53\u524d\u5b66\u4e60\u7684\u76ee\u6807\uff0c\u5229\u7528B\u7ad9\u7684\u89c6\u9891\uff0c\u53c2\u8003\u5b98\u65b9\u6587\u6863\uff0c\u5f00\u59cb\u4ece\u5934\u5f00\u59cb\u5b66\u4e60Kubernetes\u7684\u57fa\u7840\u77e5\u8bc6\u3002 \u4e0b\u9762\u51c6\u5907CKA\u8003\u8bd5\u7684\u4e00\u4e9b\u5fc3\u5f97\u4f53\u4f1a\uff1a \u5b66\u4e60 Kubernetes \u524d\uff0c\u9700\u8981\u4e86\u89e3\u5bb9\u5668\u6280\u672f\u548c Docker\uff0c\u6216\u8005\u8bf4\u8981\u6709\u5bb9\u5668\u5316\u7684\u57fa\u672c\u6982\u5ff5\u548c\u601d\u60f3\u65b9\u6cd5\uff0c\u56e0\u4e3a Kubernetes \u662f\u57fa\u4e8e\u5bb9\u5668\u6280\u672f\u6784\u5efa\u7684\u3002 \u5b66\u4e60 Kubernetes \u65f6\uff0c\u9700\u8981\u638c\u63e1\u5176\u6838\u5fc3\u6982\u5ff5\uff0c\u4f8b\u5982 Pod\u3001ReplicaSet\u3001Deployment\u3001Service \u7b49\u3002\u8fd9\u4e9b\u6982\u5ff5\u662f\u7406\u89e3 Kubernetes \u7684\u57fa\u7840\uff0c\u4e5f\u662f\u540e\u7eed\u5b9e\u9645\u5e94\u7528\u4e2d\u7684\u91cd\u8981\u90e8\u5206\u3002 \u5b66\u4e60 Kubernetes \u65f6\uff0c\u9700\u8981\u638c\u63e1 yaml \u6587\u4ef6\u7684\u7f16\u5199\u65b9\u6cd5\uff0c\u7279\u522b\u662f\u90a3\u4e9b\u57fa\u672c\u8d44\u6e90\u7684yaml\u6587\u4ef6\uff0c\u8981\u80fd\u505a\u5230\u4e0d\u501f\u52a9\u5e2e\u52a9\u6587\u6863\u5c31\u80fd\u5199\u51fa\u6846\u67b6\uff0c\u5426\u5219\u8003\u8bd5\u65f6\u505a\u4e0d\u5b8c\u9898\u76ee\u7684\u3002 \u5b66\u4e60 Kubernetes \u65f6\uff0c\u9700\u8981\u638c\u63e1 kubectl \u547d\u4ee4\u7684\u4f7f\u7528\uff0c\u5e38\u7528\u8d44\u6e90\u76f8\u5173\u7684\u547d\u4ee4\uff0c\u4e5f\u8981\u505a\u5230\u4e0d\u501f\u52a9\u5e2e\u52a9\u6587\u6863\u5c31\u80fd\u5199\u51fa\uff0c\u5426\u5219\u8003\u8bd5\u65f6\u4e5f\u662f\u505a\u4e0d\u5b8c\u9898\u76ee\u7684\u3002 \u5b66\u4e60 Kubernetes \u65f6\uff0c\u9700\u8981\u638c\u63e1\u5176\u7f51\u7edc\u548c\u5b58\u50a8\u914d\u7f6e\uff0c\u4f8b\u5982 Service\u3001Ingress\u3001PersistentVolume\u3001PersistentVolumeClaim \u7b49\uff0c\u8fd9\u4e9b\u90fd\u662f\u8003\u8bd5\u91cd\u70b9\u5185\u5bb9\uff0c\u8981\u719f\u6089yaml\u7279\u6027\uff0c\u80fd\u6309\u4e0d\u540c\u7684\u8981\u6c42\u8fdb\u884c\u62d3\u5c55\u548c\u53d8\u66f4\u3002 \u90e8\u7f72\u548c\u7ba1\u7406 Kubernetes \u96c6\u7fa4\u4e5f\u662f\u4e00\u4e2a\u91cd\u70b9\uff0c\u6211\u662f\u5728\u963f\u91cc\u4e91\u4e0a\u4e70\u4e863\u4e2aECS\u4f5c\u4e3a\u5b9e\u9a8c\u73af\u5883\u3002 \u6211\u7684CKA\u7684\u7b14\u8bb0\u5206\u4e2d\u6587\u548c\u82f1\u6587\u4e24\u79cd\u3002\u82f1\u6587\u7b14\u8bb0\u662f\u57fa\u4e8e\u7b2c\u4e00\u6b21\u53c2\u52a0\u516c\u53f8\u57f9\u8bad\u7684\u77e5\u8bc6\u7ed3\u6784\u505a\u7684\uff0c\u5728\u5907\u8003\u8fc7\u7a0b\u4e2d\u9010\u6b65\u5b8c\u5584\u7684\u3002\u4e2d\u6587\u7b14\u8bb0\u662f\u57282023\u5e744\u6708\u4efd\u57fa\u4e8e\u82f1\u6587\u7b14\u8bb0\u81ea\u5df1\u7ffb\u8bd1\u8fc7\u6765\u7684\uff0c\u5e76\u53d1\u5e03\u5728\u6211\u7684\u77e5\u4e4e\u4e13\u680f\u4e0a\uff0c\u7ffb\u8bd1\u8fc7\u7a0b\u8fd8\u662f\u6bd4\u8f83\u96be\u7684\uff0c\u5f88\u591a\u82f1\u8bed\u5185\u5bb9\u627e\u4e0d\u5230\u5408\u9002\u7684\u4e2d\u6587\u8868\u8fbe\u65b9\u5f0f\uff0c\u4e0d\u8fc7\u5bf9\u4e8e\u8ba1\u7b97\u673a\u884c\u4e1a\u6765\u8bb2\uff0c\u4f7f\u7528\u82f1\u8bed\u9605\u8bfb\u4e13\u4e1a\u8d44\u6599\u5e94\u8be5\u662f\u4e00\u4e2a\u5171\u8bc6\u3002 \u53c2\u8003\u7b14\u8bb0\uff0c\u5e76\u5b8c\u6210\u7b14\u8bb0\u4e2d\u7684\u7ec3\u4e60\uff0c\u518d\u719f\u7ec3\u4f7f\u7528yaml\u6587\u4ef6\u548ckubectl\u547d\u4ee4\uff0c\u901a\u8fc7\u8003\u8bd5\u6ca1\u4ec0\u4e48\u56f0\u96be\u3002","title":"\u6211\u7684Kubernetes\u5b66\u4e60\u5fc3\u5f97"},{"location":"k8s/cka_cn/foundamentals/basics/","text":"CKA\u81ea\u5b66\u7b14\u8bb07:kubectl\u57fa\u7840 \u00b6 \u6458\u8981 \u00b6 \u4e86\u89e3\u5982\u4f55\u4f7f\u7528 kubectl \u64cd\u4f5cKubernetes\u96c6\u7fa4\u3002 via API via kubectl via Dashboard \u68c0\u67e5\u5f53\u524dkubeconfig\u6587\u4ef6\u914d\u7f6e \u00b6 \u901a\u8fc7\u547d\u4ee4 kubectl config \u68c0\u67e5\u5f53\u524d\u914d\u7f6e\u6587\u4ef6\u4e2d\u7684\u4e0a\u4e0b\u6587\u3002 echo $KUBECONFIG kubectl config view kubectl config get-contexts \u83b7\u53d6\u8d44\u6e90\u6e05\u5355 \u00b6 \u8bfb\u53d6\u6240\u6709\u652f\u6301\u7684\u8d44\u6e90\u6e05\u5355\u3002 kubectl api-resources \u83b7\u53d6\u96c6\u7fa4\u72b6\u6001 \u00b6 Kubernetes \u63a7\u5236\u9762\u677f\u8fd0\u884c\u5728 https://:6443 \u3002 CoreDNS \u8fd0\u884c\u5728 https://:6443/api/v1/namespaces/kube-system/services/kube-dns:dns/proxy \u3002 kubectl cluster-info kubectl cluster-info dump \u8bfb\u53d6\u5f53\u524d\u8d44\u6e90 \u00b6 \u6267\u884c\u547d\u4ee4 kubectl get --help \u53ef\u4ee5\u5f97\u5230get\u547d\u4ee4\u7684\u793a\u4f8b\u548c\u4f7f\u7528\u65b9\u6cd5\u3002 \u8bfb\u53d6\u5f53\u524d\u63a7\u5236\u9762\u677f\u7684\u5065\u5eb7\u72b6\u6001\u3002 kubectl get componentstatuses kubectl get cs \u8fd0\u884c\u7ed3\u679c\uff1a NAME STATUS MESSAGE ERROR etcd-0 Healthy {\"health\":\"true\",\"reason\":\"\"} scheduler Healthy ok controller-manager Healthy ok \u8bfb\u53d6\u8282\u70b9\u72b6\u6001\u548c\u4fe1\u606f \u00b6 kubectl get nodes kubectl get nodes -o wide kubectl describe node cka001 \u53ef\u4ee5\u901a\u8fc7\u547d\u4ee4 kubectl create --help \u6765\u83b7\u53d6get\u547d\u4ee4\u7684\u5e2e\u52a9\u548c\u793a\u4f8b\u3002 \u521b\u5efaNamespace \u00b6 kubectl create namespace --help kubectl create namespace my-namespace \u63d0\u793a\uff1a \u547d\u540d\u7a7a\u95f4Namespace\u662f\u4e00\u4e2a\u96c6\u7fa4\uff0c\u5305\u542b\u4e86\u670d\u52a1\u3002\u670d\u52a1\u53ef\u80fd\u5728\u4e00\u4e2a\u8282\u70b9\u4e0a\uff0c\u4e5f\u53ef\u80fd\u4e0d\u5728\u3002 Namespace\u662f\u4e00\u79cd\u7528\u6765\u7ec4\u7ec7\u670d\u52a1\u7684\u65b9\u5f0f\uff0c\u5b83\u53ef\u4ee5\u5bf9\u670d\u52a1\u8fdb\u884c\u9694\u79bb\u548c\u5212\u5206\u3002 \u4e0d\u540c\u7684Namespace\u4e0b\uff0c\u53ef\u4ee5\u5b58\u5728\u76f8\u540c\u7684\u670d\u52a1\u540d\uff0c\u4f46\u662f\u4e0d\u540c\u7684Namespace\u4e4b\u95f4\u7684\u670d\u52a1\u4e0d\u80fd\u76f4\u63a5\u901a\u4fe1\uff0c\u9700\u8981\u901a\u8fc7Service\u6216Ingress\u6765\u66b4\u9732\u3002 \u670d\u52a1\u662f\u4e00\u79cd\u63d0\u4f9b\u529f\u80fd\u7684\u5b9e\u4f53 \u8282\u70b9\u662f\u4e00\u79cd\u8fd0\u884c\u670d\u52a1\u7684\u7269\u7406\u6216\u865a\u62df\u673a\u5668 \u521b\u5efadeployment \u00b6 \u5728\u67d0\u4e2aNamespace\u4e2d\u521b\u5efaDeployment\u3002 kubectl -n my-namespace create deployment my-busybox \\ --image = busybox \\ --replicas = 3 \\ --port = 5701 \u521b\u5efaClusterRole \u00b6 kubectl create clusterrole --help kubectl create clusterrole pod-creater \\ -n my-namespace \\ --verb = create \\ --resource = deployment \\ --resource-name = my-busybox \u521b\u5efaServiceAccount \u00b6 kubectl create serviceaccount --help kubectl -n my-namespace create serviceaccount my-service-account \u521b\u5efaRoleBinding \u00b6 RoleBinding \u53ef\u4ee5\u5f15\u7528\u540c\u4e00\u547d\u540d\u7a7a\u95f4\u4e2d\u7684\u4e00\u4e2aRole\uff0c\u6216\u8005\u5168\u5c40\u547d\u540d\u7a7a\u95f4\u4e2d\u7684\u4e00\u4e2aClusterRole\u3002 RoleBinding \u662f\u4e00\u79cd\u7528\u6765\u6388\u6743\u89d2\u8272\u7684\u8d44\u6e90\u3002 Role\u662f\u4e00\u79cd\u5b9a\u4e49\u6743\u9650\u7684\u8d44\u6e90\uff0c\u53ea\u80fd\u5728\u540c\u4e00\u547d\u540d\u7a7a\u95f4\u5185\u751f\u6548\u3002 ClusterRole\u662f\u4e00\u79cd\u5b9a\u4e49\u6743\u9650\u7684\u8d44\u6e90\uff0c\u53ef\u4ee5\u5728\u6574\u4e2a\u96c6\u7fa4\u5185\u751f\u6548\u3002 kubectl create rolebinding --help kubectl create rolebinding NAME \\ --clusterrole = NAME | --role = NAME \\ [ --user = username ] \\ [ --group = groupname ] \\ [ --serviceaccount = namespace:serviceaccountname ] \\ [ --dry-run = server | client | none ] kubectl create rolebinding my-admin \\ --clusterrole = pod-creater \\ --serviceaccount = my-namespace:my-service-account \u4f7f\u7528proxy \u00b6 \u6211\u4eec\u53ef\u4ee5\u4f7f\u7528 kubectl proxy \u547d\u4ee4\u6765\u6253\u5f00\u4e00\u4e2a\u5230API\u670d\u52a1\u5668\u7684\u96a7\u9053\uff08tunnel\uff09\uff0c\u5e76\u4f7f\u5b83\u5728\u672c\u5730\u53ef\u7528 - \u901a\u5e38\u662f\u5728 localhost:8001 / 127.0.0.1:8001 \u3002\u5f53\u6211\u60f3\u8981\u4f7f\u7528API\u65f6\uff0c\u6700\u7b80\u5355\u7684\u65b9\u6cd5\u5c31\u662f\u83b7\u53d6\u8bbf\u95ee\u6743\u9650\u3002 \u8fd0\u884c\u547d\u4ee4 kubectl proxy & \u5e76\u5728\u6d4f\u89c8\u5668\u4e2d\u6253\u5f00 http://localhost:8001/api/v1 \u3002 \u53ea\u6253\u5f00 http://localhost:8001 \u4f1a\u8fd4\u56de\u9519\u8bef\uff0c\u56e0\u4e3a\u6211\u4eec\u53ea\u80fd\u8bbf\u95eeAPI\u7684\u67d0\u4e9b\u5185\u5bb9\uff0c\u56e0\u6b64API\u8def\u5f84\u5f88\u91cd\u8981\u3002 \u8981\u70b9\u662f\uff1a kubectl proxy \u547d\u4ee4\u53ef\u4ee5\u521b\u5efa\u4e00\u4e2a\u672c\u5730\u4ee3\u7406\uff0c\u8ba9\u6211\u4eec\u53ef\u4ee5\u8bbf\u95eeAPI\u670d\u52a1\u5668\u3002 API\u670d\u52a1\u5668\u63d0\u4f9b\u4e86\u96c6\u7fa4\u7684\u5404\u79cd\u4fe1\u606f\u548c\u64cd\u4f5c\u3002 \u6211\u4eec\u9700\u8981\u6307\u5b9a\u6b63\u786e\u7684API\u8def\u5f84\uff0c\u624d\u80fd\u8bbf\u95ee\u6211\u4eec\u60f3\u8981\u7684\u8d44\u6e90\u3002 kubectl proxy & \u8f93\u51fa\u7ed3\u679c\uff1a [1] 102358 Starting to serve on 127.0.0.1:8001 \u6bd4\u5982\uff1a http://127.0.0.1:8001/ http://127.0.0.1:8001/api/v1 http://127.0.0.1:8001/api/v1/namespaces http://127.0.0.1:8001/api/v1/namespaces/default http://127.0.0.1:8001/api/v1/namespaces/sock-shop/pods \u4f5c\u4e3a\u5e94\u7528\u7a0b\u5e8f\u8bbf\u95ee \u00b6 \u5982\u679c\u6211\u4eec\u4f5c\u4e3a\u5e94\u7528\u7a0b\u5e8f\u800c\u4e0d\u662f\u7ba1\u7406\u5458\u6765\u8bbf\u95eekubernetes\uff0c\u5c31\u4e0d\u80fd\u4f7f\u7528 kubectl \uff0c\u53ef\u4ee5\u7528 curl \u7a0b\u5e8f\u6765\u4ee3\u66ff kubectl \u3002 \u6211\u4eec\u5fc5\u987b\u5411\u96c6\u7fa4\u53d1\u9001HTTP\u8bf7\u6c42\uff0c\u8be2\u95ee\u53ef\u7528\u7684\u8282\u70b9\u3002 \u786e\u4fdd kubectl proxy \u6b63\u5728\u8fd0\u884c\uff0c\u5e76\u5728 http://localhost:8001/ \u4e0a\u63d0\u4f9b\u670d\u52a1\u3002 \u6267\u884c\u4e0b\u9762\u7684\u547d\u4ee4\u65f6\u52a0\u4e0a\u4e00\u4e2a -v=9 \u7684\u6807\u5fd7\uff0c\u5b83\u4f1a\u663e\u793a\u6240\u6709\u9700\u8981\u7684\u4fe1\u606f\u3002 \u8981\u70b9\uff1a \u8bbf\u95ee\uff08access\uff09\u662f\u4e00\u79cd\u83b7\u53d6\u8d44\u6e90\u6216\u670d\u52a1\u7684\u884c\u4e3a\u3002 \u5e94\u7528\u7a0b\u5e8f\uff08application\uff09\u662f\u4e00\u79cd\u6267\u884c\u7279\u5b9a\u529f\u80fd\u7684\u8f6f\u4ef6\u3002 \u4f5c\u4e3a\u5e94\u7528\u7a0b\u5e8f\u8bbf\u95ee\u610f\u5473\u7740\u4f7f\u7528\u5e94\u7528\u7a0b\u5e8f\u7684\u8eab\u4efd\u6216\u51ed\u8bc1\u6765\u8bbf\u95ee\u3002 kubernetes\u662f\u4e00\u79cd\u7ba1\u7406\u5bb9\u5668\u5316\u5e94\u7528\u7a0b\u5e8f\u7684\u5e73\u53f0\u3002 kubectl \u662f\u4e00\u79cd\u7528\u6765\u548ckubernetes\u4ea4\u4e92\u7684\u547d\u4ee4\u884c\u5de5\u5177\u3002 curl \u662f\u4e00\u79cd\u7528\u6765\u53d1\u9001HTTP\u8bf7\u6c42\u7684\u547d\u4ee4\u884c\u5de5\u5177\u3002 kubectl proxy \u53ef\u4ee5\u521b\u5efa\u4e00\u4e2a\u672c\u5730\u4ee3\u7406\uff0c\u8ba9\u6211\u4eec\u53ef\u4ee5\u8bbf\u95eekubernetes\u7684API\u670d\u52a1\u5668\u3002 -v=9 \u662f\u4e00\u79cd\u7528\u6765\u663e\u793a\u8be6\u7ec6\u4fe1\u606f\u7684\u9009\u9879\u3002 kubectl get nodes \u5728\u4e0a\u9762\u547d\u4ee4\u7684\u8f93\u51fa\u7ed3\u679c\u4e2d\uff0c\u6211\u4eec\u53ef\u4ee5\u627e\u5230\u5bf9\u5e94\u7684curl\u8bf7\u6c42\u4fe1\u606f\u3002 curl -v -XGET \\ -H \"Accept: application/json;as=Table;v=v1;g=meta.k8s.io,application/json;as=Table;v=v1beta1;g=meta.k8s.io,application/json\" \\ -H \"User-Agent: kubectl/v1.24.1 (linux/amd64) kubernetes/3ddd0f4\" \\ 'https:///api/v1/nodes?limit=500' \u53c2\u8003\u4fe1\u606f\uff1a forum-like page \u662f\u6709K8s\u8fd0\u8425\u7684\u5e73\u53f0\uff0c\u63d0\u4f9b\u4e86\u5f88\u591a\u5173\u4e8e\u5982\u4f55\u4f7f\u7528 kubectl \u7684\u8be6\u7ec6\u4fe1\u606f\u548c\u4f8b\u5b50\u3002 Manage multiple clusters and multiple config files kubectl command documentation Shell autocompletion kubectl cheat sheet jsonpath in kubectl kubectl","title":"kubectl\u57fa\u7840"},{"location":"k8s/cka_cn/foundamentals/basics/#cka7kubectl","text":"","title":"CKA\u81ea\u5b66\u7b14\u8bb07:kubectl\u57fa\u7840"},{"location":"k8s/cka_cn/foundamentals/basics/#_1","text":"\u4e86\u89e3\u5982\u4f55\u4f7f\u7528 kubectl \u64cd\u4f5cKubernetes\u96c6\u7fa4\u3002 via API via kubectl via Dashboard","title":"\u6458\u8981"},{"location":"k8s/cka_cn/foundamentals/basics/#kubeconfig","text":"\u901a\u8fc7\u547d\u4ee4 kubectl config \u68c0\u67e5\u5f53\u524d\u914d\u7f6e\u6587\u4ef6\u4e2d\u7684\u4e0a\u4e0b\u6587\u3002 echo $KUBECONFIG kubectl config view kubectl config get-contexts","title":"\u68c0\u67e5\u5f53\u524dkubeconfig\u6587\u4ef6\u914d\u7f6e"},{"location":"k8s/cka_cn/foundamentals/basics/#_2","text":"\u8bfb\u53d6\u6240\u6709\u652f\u6301\u7684\u8d44\u6e90\u6e05\u5355\u3002 kubectl api-resources","title":"\u83b7\u53d6\u8d44\u6e90\u6e05\u5355"},{"location":"k8s/cka_cn/foundamentals/basics/#_3","text":"Kubernetes \u63a7\u5236\u9762\u677f\u8fd0\u884c\u5728 https://:6443 \u3002 CoreDNS \u8fd0\u884c\u5728 https://:6443/api/v1/namespaces/kube-system/services/kube-dns:dns/proxy \u3002 kubectl cluster-info kubectl cluster-info dump","title":"\u83b7\u53d6\u96c6\u7fa4\u72b6\u6001"},{"location":"k8s/cka_cn/foundamentals/basics/#_4","text":"\u6267\u884c\u547d\u4ee4 kubectl get --help \u53ef\u4ee5\u5f97\u5230get\u547d\u4ee4\u7684\u793a\u4f8b\u548c\u4f7f\u7528\u65b9\u6cd5\u3002 \u8bfb\u53d6\u5f53\u524d\u63a7\u5236\u9762\u677f\u7684\u5065\u5eb7\u72b6\u6001\u3002 kubectl get componentstatuses kubectl get cs \u8fd0\u884c\u7ed3\u679c\uff1a NAME STATUS MESSAGE ERROR etcd-0 Healthy {\"health\":\"true\",\"reason\":\"\"} scheduler Healthy ok controller-manager Healthy ok","title":"\u8bfb\u53d6\u5f53\u524d\u8d44\u6e90"},{"location":"k8s/cka_cn/foundamentals/basics/#_5","text":"kubectl get nodes kubectl get nodes -o wide kubectl describe node cka001 \u53ef\u4ee5\u901a\u8fc7\u547d\u4ee4 kubectl create --help \u6765\u83b7\u53d6get\u547d\u4ee4\u7684\u5e2e\u52a9\u548c\u793a\u4f8b\u3002","title":"\u8bfb\u53d6\u8282\u70b9\u72b6\u6001\u548c\u4fe1\u606f"},{"location":"k8s/cka_cn/foundamentals/basics/#namespace","text":"kubectl create namespace --help kubectl create namespace my-namespace \u63d0\u793a\uff1a \u547d\u540d\u7a7a\u95f4Namespace\u662f\u4e00\u4e2a\u96c6\u7fa4\uff0c\u5305\u542b\u4e86\u670d\u52a1\u3002\u670d\u52a1\u53ef\u80fd\u5728\u4e00\u4e2a\u8282\u70b9\u4e0a\uff0c\u4e5f\u53ef\u80fd\u4e0d\u5728\u3002 Namespace\u662f\u4e00\u79cd\u7528\u6765\u7ec4\u7ec7\u670d\u52a1\u7684\u65b9\u5f0f\uff0c\u5b83\u53ef\u4ee5\u5bf9\u670d\u52a1\u8fdb\u884c\u9694\u79bb\u548c\u5212\u5206\u3002 \u4e0d\u540c\u7684Namespace\u4e0b\uff0c\u53ef\u4ee5\u5b58\u5728\u76f8\u540c\u7684\u670d\u52a1\u540d\uff0c\u4f46\u662f\u4e0d\u540c\u7684Namespace\u4e4b\u95f4\u7684\u670d\u52a1\u4e0d\u80fd\u76f4\u63a5\u901a\u4fe1\uff0c\u9700\u8981\u901a\u8fc7Service\u6216Ingress\u6765\u66b4\u9732\u3002 \u670d\u52a1\u662f\u4e00\u79cd\u63d0\u4f9b\u529f\u80fd\u7684\u5b9e\u4f53 \u8282\u70b9\u662f\u4e00\u79cd\u8fd0\u884c\u670d\u52a1\u7684\u7269\u7406\u6216\u865a\u62df\u673a\u5668","title":"\u521b\u5efaNamespace"},{"location":"k8s/cka_cn/foundamentals/basics/#deployment","text":"\u5728\u67d0\u4e2aNamespace\u4e2d\u521b\u5efaDeployment\u3002 kubectl -n my-namespace create deployment my-busybox \\ --image = busybox \\ --replicas = 3 \\ --port = 5701","title":"\u521b\u5efadeployment"},{"location":"k8s/cka_cn/foundamentals/basics/#clusterrole","text":"kubectl create clusterrole --help kubectl create clusterrole pod-creater \\ -n my-namespace \\ --verb = create \\ --resource = deployment \\ --resource-name = my-busybox","title":"\u521b\u5efaClusterRole"},{"location":"k8s/cka_cn/foundamentals/basics/#serviceaccount","text":"kubectl create serviceaccount --help kubectl -n my-namespace create serviceaccount my-service-account","title":"\u521b\u5efaServiceAccount"},{"location":"k8s/cka_cn/foundamentals/basics/#rolebinding","text":"RoleBinding \u53ef\u4ee5\u5f15\u7528\u540c\u4e00\u547d\u540d\u7a7a\u95f4\u4e2d\u7684\u4e00\u4e2aRole\uff0c\u6216\u8005\u5168\u5c40\u547d\u540d\u7a7a\u95f4\u4e2d\u7684\u4e00\u4e2aClusterRole\u3002 RoleBinding \u662f\u4e00\u79cd\u7528\u6765\u6388\u6743\u89d2\u8272\u7684\u8d44\u6e90\u3002 Role\u662f\u4e00\u79cd\u5b9a\u4e49\u6743\u9650\u7684\u8d44\u6e90\uff0c\u53ea\u80fd\u5728\u540c\u4e00\u547d\u540d\u7a7a\u95f4\u5185\u751f\u6548\u3002 ClusterRole\u662f\u4e00\u79cd\u5b9a\u4e49\u6743\u9650\u7684\u8d44\u6e90\uff0c\u53ef\u4ee5\u5728\u6574\u4e2a\u96c6\u7fa4\u5185\u751f\u6548\u3002 kubectl create rolebinding --help kubectl create rolebinding NAME \\ --clusterrole = NAME | --role = NAME \\ [ --user = username ] \\ [ --group = groupname ] \\ [ --serviceaccount = namespace:serviceaccountname ] \\ [ --dry-run = server | client | none ] kubectl create rolebinding my-admin \\ --clusterrole = pod-creater \\ --serviceaccount = my-namespace:my-service-account","title":"\u521b\u5efaRoleBinding"},{"location":"k8s/cka_cn/foundamentals/basics/#proxy","text":"\u6211\u4eec\u53ef\u4ee5\u4f7f\u7528 kubectl proxy \u547d\u4ee4\u6765\u6253\u5f00\u4e00\u4e2a\u5230API\u670d\u52a1\u5668\u7684\u96a7\u9053\uff08tunnel\uff09\uff0c\u5e76\u4f7f\u5b83\u5728\u672c\u5730\u53ef\u7528 - \u901a\u5e38\u662f\u5728 localhost:8001 / 127.0.0.1:8001 \u3002\u5f53\u6211\u60f3\u8981\u4f7f\u7528API\u65f6\uff0c\u6700\u7b80\u5355\u7684\u65b9\u6cd5\u5c31\u662f\u83b7\u53d6\u8bbf\u95ee\u6743\u9650\u3002 \u8fd0\u884c\u547d\u4ee4 kubectl proxy & \u5e76\u5728\u6d4f\u89c8\u5668\u4e2d\u6253\u5f00 http://localhost:8001/api/v1 \u3002 \u53ea\u6253\u5f00 http://localhost:8001 \u4f1a\u8fd4\u56de\u9519\u8bef\uff0c\u56e0\u4e3a\u6211\u4eec\u53ea\u80fd\u8bbf\u95eeAPI\u7684\u67d0\u4e9b\u5185\u5bb9\uff0c\u56e0\u6b64API\u8def\u5f84\u5f88\u91cd\u8981\u3002 \u8981\u70b9\u662f\uff1a kubectl proxy \u547d\u4ee4\u53ef\u4ee5\u521b\u5efa\u4e00\u4e2a\u672c\u5730\u4ee3\u7406\uff0c\u8ba9\u6211\u4eec\u53ef\u4ee5\u8bbf\u95eeAPI\u670d\u52a1\u5668\u3002 API\u670d\u52a1\u5668\u63d0\u4f9b\u4e86\u96c6\u7fa4\u7684\u5404\u79cd\u4fe1\u606f\u548c\u64cd\u4f5c\u3002 \u6211\u4eec\u9700\u8981\u6307\u5b9a\u6b63\u786e\u7684API\u8def\u5f84\uff0c\u624d\u80fd\u8bbf\u95ee\u6211\u4eec\u60f3\u8981\u7684\u8d44\u6e90\u3002 kubectl proxy & \u8f93\u51fa\u7ed3\u679c\uff1a [1] 102358 Starting to serve on 127.0.0.1:8001 \u6bd4\u5982\uff1a http://127.0.0.1:8001/ http://127.0.0.1:8001/api/v1 http://127.0.0.1:8001/api/v1/namespaces http://127.0.0.1:8001/api/v1/namespaces/default http://127.0.0.1:8001/api/v1/namespaces/sock-shop/pods","title":"\u4f7f\u7528proxy"},{"location":"k8s/cka_cn/foundamentals/basics/#_6","text":"\u5982\u679c\u6211\u4eec\u4f5c\u4e3a\u5e94\u7528\u7a0b\u5e8f\u800c\u4e0d\u662f\u7ba1\u7406\u5458\u6765\u8bbf\u95eekubernetes\uff0c\u5c31\u4e0d\u80fd\u4f7f\u7528 kubectl \uff0c\u53ef\u4ee5\u7528 curl \u7a0b\u5e8f\u6765\u4ee3\u66ff kubectl \u3002 \u6211\u4eec\u5fc5\u987b\u5411\u96c6\u7fa4\u53d1\u9001HTTP\u8bf7\u6c42\uff0c\u8be2\u95ee\u53ef\u7528\u7684\u8282\u70b9\u3002 \u786e\u4fdd kubectl proxy \u6b63\u5728\u8fd0\u884c\uff0c\u5e76\u5728 http://localhost:8001/ \u4e0a\u63d0\u4f9b\u670d\u52a1\u3002 \u6267\u884c\u4e0b\u9762\u7684\u547d\u4ee4\u65f6\u52a0\u4e0a\u4e00\u4e2a -v=9 \u7684\u6807\u5fd7\uff0c\u5b83\u4f1a\u663e\u793a\u6240\u6709\u9700\u8981\u7684\u4fe1\u606f\u3002 \u8981\u70b9\uff1a \u8bbf\u95ee\uff08access\uff09\u662f\u4e00\u79cd\u83b7\u53d6\u8d44\u6e90\u6216\u670d\u52a1\u7684\u884c\u4e3a\u3002 \u5e94\u7528\u7a0b\u5e8f\uff08application\uff09\u662f\u4e00\u79cd\u6267\u884c\u7279\u5b9a\u529f\u80fd\u7684\u8f6f\u4ef6\u3002 \u4f5c\u4e3a\u5e94\u7528\u7a0b\u5e8f\u8bbf\u95ee\u610f\u5473\u7740\u4f7f\u7528\u5e94\u7528\u7a0b\u5e8f\u7684\u8eab\u4efd\u6216\u51ed\u8bc1\u6765\u8bbf\u95ee\u3002 kubernetes\u662f\u4e00\u79cd\u7ba1\u7406\u5bb9\u5668\u5316\u5e94\u7528\u7a0b\u5e8f\u7684\u5e73\u53f0\u3002 kubectl \u662f\u4e00\u79cd\u7528\u6765\u548ckubernetes\u4ea4\u4e92\u7684\u547d\u4ee4\u884c\u5de5\u5177\u3002 curl \u662f\u4e00\u79cd\u7528\u6765\u53d1\u9001HTTP\u8bf7\u6c42\u7684\u547d\u4ee4\u884c\u5de5\u5177\u3002 kubectl proxy \u53ef\u4ee5\u521b\u5efa\u4e00\u4e2a\u672c\u5730\u4ee3\u7406\uff0c\u8ba9\u6211\u4eec\u53ef\u4ee5\u8bbf\u95eekubernetes\u7684API\u670d\u52a1\u5668\u3002 -v=9 \u662f\u4e00\u79cd\u7528\u6765\u663e\u793a\u8be6\u7ec6\u4fe1\u606f\u7684\u9009\u9879\u3002 kubectl get nodes \u5728\u4e0a\u9762\u547d\u4ee4\u7684\u8f93\u51fa\u7ed3\u679c\u4e2d\uff0c\u6211\u4eec\u53ef\u4ee5\u627e\u5230\u5bf9\u5e94\u7684curl\u8bf7\u6c42\u4fe1\u606f\u3002 curl -v -XGET \\ -H \"Accept: application/json;as=Table;v=v1;g=meta.k8s.io,application/json;as=Table;v=v1beta1;g=meta.k8s.io,application/json\" \\ -H \"User-Agent: kubectl/v1.24.1 (linux/amd64) kubernetes/3ddd0f4\" \\ 'https:///api/v1/nodes?limit=500' \u53c2\u8003\u4fe1\u606f\uff1a forum-like page \u662f\u6709K8s\u8fd0\u8425\u7684\u5e73\u53f0\uff0c\u63d0\u4f9b\u4e86\u5f88\u591a\u5173\u4e8e\u5982\u4f55\u4f7f\u7528 kubectl \u7684\u8be6\u7ec6\u4fe1\u606f\u548c\u4f8b\u5b50\u3002 Manage multiple clusters and multiple config files kubectl command documentation Shell autocompletion kubectl cheat sheet jsonpath in kubectl kubectl","title":"\u4f5c\u4e3a\u5e94\u7528\u7a0b\u5e8f\u8bbf\u95ee"},{"location":"k8s/cka_cn/foundamentals/casestudy-calico/","text":"\u4e3b\u9898\u8ba8\u8bba:\u5b89\u88c5Calico \u00b6 \u6f14\u793a\u573a\u666f\uff1a\u5b89\u88c5Calico \u8fd9\u662f\u4e00\u4e2a\u5173\u4e8e\u5982\u4f55\u914d\u7f6e\u548c\u6d4b\u8bd5Calico\u7f51\u7edc\u7684\u7b80\u8981\u6b65\u9aa4\uff1a Calico\u6570\u636e\u5e93\uff08Datastore\uff09\uff1aCalico\u652f\u6301\u4f7f\u7528etcd\u6216Kubernetes API server\u4f5c\u4e3a\u6570\u636e\u5b58\u50a8\u540e\u7aef\u3002\u9009\u62e9\u5e76\u90e8\u7f72\u5176\u4e2d\u4e00\u4e2a\u6570\u636e\u5b58\u50a8\u540e\u7aef\u3002 \u914d\u7f6eIP\u6c60\uff1a\u4e3a\u4e86\u4e3aKubernetes\u96c6\u7fa4\u4e2d\u7684\u8282\u70b9\u5206\u914dIP\u5730\u5740\uff0c\u9700\u8981\u914d\u7f6eIP\u6c60\u3002\u53ef\u4ee5\u901a\u8fc7Calico\u81ea\u5b9a\u4e49\u8d44\u6e90\uff08CRD\uff09\u6765\u5b9a\u4e49IP\u6c60\u3002 \u5b89\u88c5CNI\u63d2\u4ef6\uff1aCNI\u63d2\u4ef6\u8d1f\u8d23\u5728\u8282\u70b9\u4e0a\u521b\u5efa\u548c\u5220\u9664\u7f51\u7edc\u63a5\u53e3\uff0c\u5b83\u4eec\u662f\u5e94\u7528\u7a0b\u5e8f\u5bb9\u5668\u548c\u7269\u7406\u7f51\u7edc\u4e4b\u95f4\u7684\u6865\u6881\u3002\u9700\u8981\u5728Kubernetes\u8282\u70b9\u4e0a\u5b89\u88c5Calico CNI\u63d2\u4ef6\u3002 \u5b89\u88c5Typha\uff1aTypha\u662fCalico\u4e2d\u592e\u63a7\u5236\u5e73\u9762\u7684\u4e00\u4e2a\u7ec4\u4ef6\u3002\u5b83\u4eceKubernetes API server\u4e2d\u83b7\u53d6\u7f51\u7edc\u7b56\u7565\u548c\u5176\u4ed6\u4fe1\u606f\uff0c\u5e76\u5c06\u5b83\u4eec\u5206\u53d1\u7ed9\u6240\u6709\u8282\u70b9\u4e0a\u7684calico/node\u3002 \u5b89\u88c5calico/node\uff1acalico/node\u662f\u4e00\u4e2a\u8fd0\u884c\u5728Kubernetes\u8282\u70b9\u4e0a\u7684\u5b88\u62a4\u8fdb\u7a0b\u3002\u5b83\u7ba1\u7406\u8282\u70b9\u4e0a\u7684\u7f51\u7edc\u63a5\u53e3\uff0c\u5e76\u4e3a\u5bb9\u5668\u5206\u914d\u548c\u91ca\u653eIP\u5730\u5740\u3002 \u6d4b\u8bd5\u7f51\u7edc\uff1a\u5728\u5b8c\u6210\u4e0a\u8ff0\u6b65\u9aa4\u540e\uff0c\u53ef\u4ee5\u901a\u8fc7\u5728Pod\u4e4b\u95f4\u8fdb\u884c\u7f51\u7edc\u901a\u4fe1\u6765\u6d4b\u8bd5Calico\u7f51\u7edc\u662f\u5426\u6b63\u5e38\u5de5\u4f5c\u3002\u53ef\u4ee5\u521b\u5efa\u4e24\u4e2a\u8fd0\u884c\u5728\u4e0d\u540c\u8282\u70b9\u4e0a\u7684Pod\uff0c\u5e76\u5c1d\u8bd5\u4ece\u4e00\u4e2aPod ping\u53e6\u4e00\u4e2aPod\u3002\u5982\u679cping\u6210\u529f\uff0c\u5219\u8868\u793aCalico\u7f51\u7edc\u5df2\u6210\u529f\u914d\u7f6e\u548c\u8fd0\u884c\u3002 Calico\u6570\u636e\u5e93 \u00b6 \u4e3a\u4e86\u5c06Kubernetes\u7528\u4f5cCalico\u6570\u636e\u5b58\u50a8\u5e93\uff0c\u6211\u4eec\u9700\u8981\u5b9a\u4e49Calico\u4f7f\u7528\u7684\u81ea\u5b9a\u4e49\u8d44\u6e90\u3002 \u4e0b\u8f7d\u5e76\u68c0\u67e5Calico\u81ea\u5b9a\u4e49\u8d44\u6e90\u5b9a\u4e49\u5217\u8868\uff0c\u5e76\u5728\u6587\u4ef6\u7f16\u8f91\u5668\u4e2d\u6253\u5f00\u5b83\u3002 wget https://projectcalico.docs.tigera.io/manifests/crds.yaml \u5728 Kubernetes \u4e2d\u521b\u5efa Calico \u7684\u81ea\u5b9a\u4e49\u8d44\u6e90\u3002 kubectl apply -f crds.yaml \u5b89\u88c5 calicoctl \u3002 \u4e0b\u8f7d calicoctl \u4e8c\u8fdb\u5236\u6587\u4ef6\u5230\u4e00\u4e2a\u53ef\u4ee5\u8bbf\u95ee Kubernetes \u7684 Linux \u4e3b\u673a\u4e0a\uff0c\u4ee5\u76f4\u63a5\u4e0e Calico \u6570\u636e\u5b58\u50a8\u4ea4\u4e92\u3002 \u6700\u65b0\u7248\u7684calicoctl\u53ef\u4ee5\u901a\u8fc7 git page \u8fdb\u884c\u4e0b\u8f7d\uff0c\u9700\u8981\u7528\u5b9e\u9645\u7248\u672c\u53f7\u66ff\u6362\u4e0b\u9762\u7684 v3.23.2 \u7684\u7248\u672c\u53f7\u3002 wget https://github.com/projectcalico/calico/releases/download/v3.23.3/calicoctl-linux-amd64 chmod +x calicoctl-linux-amd64 sudo cp calicoctl-linux-amd64 /usr/local/bin/calicoctl \u914d\u7f6e calicoctl \u4ee5\u8bbf\u95ee Kubernetes\u3002 echo \"export KUBECONFIG=/root/.kube/config\" >> ~/.bashrc echo \"export DATASTORE_TYPE=kubernetes\" >> ~/.bashrc echo $KUBECONFIG echo $DATASTORE_TYPE \u6267\u884c\u4e0b\u9762\u7684\u547d\u4ee4\uff0c\u9a8c\u8bc1 calicoctl \u80fd\u591f\u8bbf\u95ee\u6570\u636e\u5e93\u3002 calicoctl get nodes -o wide \u8fd0\u884c\u7ed3\u679c\u7c7b\u4f3c\u5982\u4e0b\uff1a NAME ASN IPV4 IPV6 cka001 cka002 cka003 \u8282\u70b9\u662f\u7531 Kubernetes \u8282\u70b9\u5bf9\u8c61\u652f\u6301\u7684\uff0c\u56e0\u6b64\u6211\u4eec\u5e94\u8be5\u770b\u5230\u4e0e kubectl get nodes \u5339\u914d\u7684\u540d\u79f0\u3002 kubectl get nodes -o wide \u8fd0\u884c\u7ed3\u679c\uff1a NAME STATUS ROLES AGE VERSION OS-IMAGE KERNEL-VERSION CONTAINER-RUNTIME cka001 NotReady control-plane,master 23m v1.24.0 Ubuntu 20.04.4 LTS 5.4.0-113-generic containerd://1.5.9 cka002 NotReady 22m v1.24.0 Ubuntu 20.04.4 LTS 5.4.0-113-generic containerd://1.5.9 cka003 NotReady 21m v1.24.0 Ubuntu 20.04.4 LTS 5.4.0-113-generic containerd://1.5.9 \u914d\u7f6eIP\u6c60 \u00b6 \u4e00\u4e2a\u5de5\u4f5c\u8d1f\u8f7d\uff08workload\uff09\u662f\u5bb9\u5668\u6216\u865a\u62df\u673a\uff0c\u57fa\u4e8eCalico\u7684\u865a\u62df\u7f51\u7edc\u3002 \u5728Kubernetes\u4e2d\uff0c\u5de5\u4f5c\u8d1f\u8f7d\u662fPod\u3002\u4e00\u4e2a\u5de5\u4f5c\u8d1f\u8f7d\u7aef\u70b9\uff08endpoint\uff09\u662f\u5de5\u4f5c\u8d1f\u8f7d\u7528\u6765\u8fde\u63a5Calico\u7f51\u7edc\u7684\u865a\u62df\u7f51\u7edc\u63a5\u53e3\u3002 IP\u6c60\u662fCalico\u4e3a\u5de5\u4f5c\u8d1f\u8f7d\u7aef\u70b9\u4f7f\u7528\u7684IP\u5730\u5740\u8303\u56f4\u3002 \u83b7\u53d6\u96c6\u7fa4\u4e2d\u5f53\u524d\u7684IP\u6c60\u3002\u76ee\u524d\uff0c\u5728\u521a\u521a\u5b89\u88c5\u5b8c\u4e4b\u540e\uff0c\u5b83\u662f\u7a7a\u7684\u3002 calicoctl get ippools \u8fd0\u884c\u7ed3\u679c\uff1a NAME CIDR SELECTOR \u6211\u4eec\u901a\u8fc7 kubeadm init \u547d\u4ee4\u6307\u5b9a\u4e86 Pod CIDR \u4e3a 10.244.0.0/16 \u3002 \u73b0\u5728\uff0c\u6211\u4eec\u4e3a\u96c6\u7fa4\u521b\u5efa\u4e24\u4e2a IP \u6c60\uff08IP pool\uff09\uff0c\u6bcf\u4e2a\u6c60\u4e4b\u95f4\u4e0d\u80fd\u91cd\u53e0\u3002 \u521b\u5efaIP\u6c60 ipv4-ippool-1 : 10.244.0.0/18 calicoctl apply -f - < /etc/cni/net.d/10-calico.conflist < /etc/cni/net.d/10-calico.conflist < /etc/cni/net.d/10-calico.conflist < 4h49m v1.24.0 cka003 Ready 4h49m v1.24.0 \u5b89\u88c5Typha \u00b6 Typha \u5904\u4e8e Kubernetes API \u670d\u52a1\u5668\u548c\u6bcf\u4e2a\u8282\u70b9\u5b88\u62a4\u8fdb\u7a0b\uff08\u5982\u8fd0\u884c\u5728 calico/node \u4e2d\u7684 Felix \u548c confd\uff09\u4e4b\u95f4\u3002 \u5b83\u76d1\u89c6\u8fd9\u4e9b\u5b88\u62a4\u8fdb\u7a0b\u4f7f\u7528\u7684 Kubernetes \u8d44\u6e90\u548c Calico \u81ea\u5b9a\u4e49\u8d44\u6e90\uff0c\u6bcf\u5f53\u8d44\u6e90\u66f4\u6539\u65f6\uff0c\u5b83\u4f1a\u5c06\u66f4\u65b0\u6269\u6563\u5230\u8fd9\u4e9b\u5b88\u62a4\u8fdb\u7a0b\u3002 \u8fd9\u51cf\u5c11\u4e86 Kubernetes API \u670d\u52a1\u5668\u9700\u8981\u670d\u52a1\u7684\u76d1\u89c6\u6570\uff0c\u63d0\u9ad8\u4e86\u96c6\u7fa4\u7684\u53ef\u6269\u5c55\u6027\u3002 \u51c6\u5907\u8bc1\u4e66 \u4e0b\u9762\uff0c\u6211\u4eec\u4f7f\u7528\u76f8\u4e92\u8ba4\u8bc1\u7684TLS\u6765\u786e\u4fddcalico/node\u548cTypha\u4e4b\u95f4\u7684\u901a\u4fe1\u5b89\u5168\u3002 \u751f\u6210\u4e00\u4e2a\u8bc1\u4e66\u6388\u6743\u673a\u6784\uff08CA\uff09\u5e76\u4f7f\u7528\u5b83\u6765\u4e3aTypha\u7b7e\u7f72\u8bc1\u4e66\u3002 \u5c06\u5f53\u524d\u5de5\u4f5c\u76ee\u5f55\u6539\u4e3a /etc/kubernetes/pki/ \u3002 cd /etc/kubernetes/pki/ \u521b\u5efaCA\u8bc1\u4e66\u548c\u5bc6\u94a5\u3002 openssl req -x509 -newkey rsa:4096 \\ -keyout typhaca.key \\ -nodes \\ -out typhaca.crt \\ -subj \"/CN=Calico Typha CA\" \\ -days 365 \u628aCA\u8bc1\u4e66\u5b58\u653e\u5728ConfigMap\u4e2d\uff0c\u4f7fTypha\u548ccalico/node\u80fd\u591f\u8bbf\u95ee\u3002 kubectl create configmap -n kube-system calico-typha-ca --from-file = typhaca.crt \u751f\u6210Typha\u5bc6\u94a5\u548c\u8bc1\u4e66\u7b7e\u540d\u8bf7\u6c42\uff08certificate signing request\uff0cCSR\uff09\u3002 openssl req -newkey rsa:4096 \\ -keyout typha.key \\ -nodes \\ -out typha.csr \\ -subj \"/CN=calico-typha\" \u8bc1\u4e66\u7684\u901a\u7528\u540d\u79f0\uff08CN\uff09\u8bbe\u7f6e\u4e3a calico-typha \u3002 calico/node \u5c06\u88ab\u7528\u6765\u9a8c\u8bc1\u6b64\u540d\u79f0\u3002 \u4f7f\u7528 CA \u5bf9 Typha \u8bc1\u4e66\u8fdb\u884c\u7b7e\u540d\u3002 openssl x509 -req -in typha.csr \\ -CA typhaca.crt \\ -CAkey typhaca.key \\ -CAcreateserial \\ -out typha.crt \\ -days 365 \u8fd0\u884c\u7ed3\u679c\uff1a Signature ok subject=CN = calico-typha Getting CA Private Key \u5c06 Typha \u5bc6\u94a5\u548c\u8bc1\u4e66\u5b58\u50a8\u5728\u4e00\u4e2a secret \u4e2d\uff0c\u4ee5\u4fbf Typha \u53ef\u4ee5\u8bbf\u95ee\u3002 kubectl create secret generic -n kube-system calico-typha-certs --from-file = typha.key --from-file = typha.crt \u914d\u7f6eRBAC \u5f53\u524d\u5de5\u4f5c\u76ee\u5f55\u4e3ahome\u8def\u5f84\u3002 cd ~ \u521b\u5efa\u4e00\u4e2aTypha\u4f7f\u7528\u7684ServiceAccount\u3002 kubectl create serviceaccount -n kube-system calico-typha \u4e3a Typha \u521b\u5efa\u4e00\u4e2a\u96c6\u7fa4\u89d2\u8272\uff0c\u6709\u89c2\u5bdf Calico \u6570\u636e\u5b58\u50a8\u5bf9\u8c61\u7684\u6743\u9650\u3002 kubectl apply -f - < pingtest-585b76c894-s2tbs 1/1 Running 0 7s 10.244.31.0 cka002 pingtest-585b76c894-vm9wn 1/1 Running 0 7s 10.244.28.64 cka003 \u7559\u610f\u7b2c\u4e8c\u4e2a\u548c\u7b2c\u4e09\u4e2a pod \u7684 IP \u5730\u5740\u3002 \u968f\u540e\u6211\u4eec\u4f1a\u5728\u7b2c\u4e00\u4e2a pod \u4e2d\u8fd0\u884c exec \u547d\u4ee4\u3002 \u5728\u7b2c\u4e00\u4e2a pod \u5185\u90e8\uff0c\u5bf9\u53e6\u5916\u4e24\u4e2a pod \u7684 IP \u5730\u5740\u8fdb\u884c ping \u6d4b\u8bd5\u3002 \u4f8b\u5982\uff1a kubectl exec -ti pingtest-585b76c894-chwjq -- sh / # ping 10.244.31.1 -c 4 4 packets transmitted, 4 packets received, 0 % packet loss / # ping 10.244.31.0 -c 4 4 packets transmitted, 4 packets received, 0 % packet loss / # ping 10.244.28.64 -c 4 4 packets transmitted, 0 packets received, 100 % packet loss \u8def\u7531\u68c0\u67e5 \u00b6 \u4ece\u5176\u4e2d\u4e00\u4e2a\u8282\u70b9\u9a8c\u8bc1\u662f\u5426\u80fdping\u901a\u5230\u6bcf\u4e2apod\u7684IP\u5730\u5740\u3002\u4f8b\u5982\uff1a ip route get 10 .244.31.1 ip route get 10 .244.31.0 ip route get 10 .244.28.64 \u5728\u4e0a\u9762\u7684\u7ed3\u679c\u4e2d\uff0c\u793a\u4f8b\u4e2d\u7684 via \uff08\u5b83\u662f\u63a7\u5236\u5e73\u9762\uff09\u8868\u793a\u6b64Pod IP\u7684\u4e0b\u4e00\u8df3\uff0c\u8fd9\u4e0ePod\u6240\u5728\u8282\u70b9\u7684IP\u5730\u5740\u5339\u914d\uff0c\u7b26\u5408\u9884\u671f\u3002 \u4e0d\u540cIP\u6c60\u7684IPAM\u5206\u914d\u3002\u5728\u524d\u9762\u7684\u6f14\u793a\u4e2d\uff0c\u6211\u4eec\u521b\u5efa\u4e86\u4e24\u4e2aIP\u6c60\uff0c\u4f46\u5c06\u4e00\u4e2a\u7981\u7528\u4e86\u3002 calicoctl get ippools -o wide \u8fd0\u884c\u7ed3\u679c\uff1a NAME CIDR NAT IPIPMODE VXLANMODE DISABLED DISABLEBGPEXPORT SELECTOR ipv4-ippool-1 10.244.0.0/18 true Never Never false false all() ipv4-ippool-2 10.244.192.0/19 true Never Never true false all() \u6fc0\u6d3b\u7b2c\u4e8c\u4e2aIP\u6c60\u3002 calicoctl --allow-version-mismatch apply -f - < \u8fde\u63a5\u5e76\u8fdb\u5165Pod pingtest-585b76c894-chwjq \u5185\u90e8\u3002 kubectl exec -ti pingtest-585b76c894-chwjq -- sh / # 10.244.203.192 -c 4 4 packets transmitted, 0 packets received, 100 % packet loss \u6807\u8bb0\uff1a \u6f14\u793a\u6b62\u4e8e\u6b64\uff0c\u8def\u7531\u6ca1\u6709\u5b89\u88c5\u9884\u671f\u5de5\u4f5c\uff0c\u539f\u56e0\u67e5\u627e\u4e2d\u3002 \u5220\u9664\u6f14\u793a\u4e2d\u521b\u5efa\u7684\u4e34\u65f6\u8d44\u6e90\u3002 kubectl delete deployments.apps pingtest kubectl delete pod pingtest-ippool-2 \u53c2\u8003\uff1a End-to-end Calico installation","title":"\u5b89\u88c5Calico"},{"location":"k8s/cka_cn/foundamentals/casestudy-calico/#calico","text":"\u6f14\u793a\u573a\u666f\uff1a\u5b89\u88c5Calico \u8fd9\u662f\u4e00\u4e2a\u5173\u4e8e\u5982\u4f55\u914d\u7f6e\u548c\u6d4b\u8bd5Calico\u7f51\u7edc\u7684\u7b80\u8981\u6b65\u9aa4\uff1a Calico\u6570\u636e\u5e93\uff08Datastore\uff09\uff1aCalico\u652f\u6301\u4f7f\u7528etcd\u6216Kubernetes API server\u4f5c\u4e3a\u6570\u636e\u5b58\u50a8\u540e\u7aef\u3002\u9009\u62e9\u5e76\u90e8\u7f72\u5176\u4e2d\u4e00\u4e2a\u6570\u636e\u5b58\u50a8\u540e\u7aef\u3002 \u914d\u7f6eIP\u6c60\uff1a\u4e3a\u4e86\u4e3aKubernetes\u96c6\u7fa4\u4e2d\u7684\u8282\u70b9\u5206\u914dIP\u5730\u5740\uff0c\u9700\u8981\u914d\u7f6eIP\u6c60\u3002\u53ef\u4ee5\u901a\u8fc7Calico\u81ea\u5b9a\u4e49\u8d44\u6e90\uff08CRD\uff09\u6765\u5b9a\u4e49IP\u6c60\u3002 \u5b89\u88c5CNI\u63d2\u4ef6\uff1aCNI\u63d2\u4ef6\u8d1f\u8d23\u5728\u8282\u70b9\u4e0a\u521b\u5efa\u548c\u5220\u9664\u7f51\u7edc\u63a5\u53e3\uff0c\u5b83\u4eec\u662f\u5e94\u7528\u7a0b\u5e8f\u5bb9\u5668\u548c\u7269\u7406\u7f51\u7edc\u4e4b\u95f4\u7684\u6865\u6881\u3002\u9700\u8981\u5728Kubernetes\u8282\u70b9\u4e0a\u5b89\u88c5Calico CNI\u63d2\u4ef6\u3002 \u5b89\u88c5Typha\uff1aTypha\u662fCalico\u4e2d\u592e\u63a7\u5236\u5e73\u9762\u7684\u4e00\u4e2a\u7ec4\u4ef6\u3002\u5b83\u4eceKubernetes API server\u4e2d\u83b7\u53d6\u7f51\u7edc\u7b56\u7565\u548c\u5176\u4ed6\u4fe1\u606f\uff0c\u5e76\u5c06\u5b83\u4eec\u5206\u53d1\u7ed9\u6240\u6709\u8282\u70b9\u4e0a\u7684calico/node\u3002 \u5b89\u88c5calico/node\uff1acalico/node\u662f\u4e00\u4e2a\u8fd0\u884c\u5728Kubernetes\u8282\u70b9\u4e0a\u7684\u5b88\u62a4\u8fdb\u7a0b\u3002\u5b83\u7ba1\u7406\u8282\u70b9\u4e0a\u7684\u7f51\u7edc\u63a5\u53e3\uff0c\u5e76\u4e3a\u5bb9\u5668\u5206\u914d\u548c\u91ca\u653eIP\u5730\u5740\u3002 \u6d4b\u8bd5\u7f51\u7edc\uff1a\u5728\u5b8c\u6210\u4e0a\u8ff0\u6b65\u9aa4\u540e\uff0c\u53ef\u4ee5\u901a\u8fc7\u5728Pod\u4e4b\u95f4\u8fdb\u884c\u7f51\u7edc\u901a\u4fe1\u6765\u6d4b\u8bd5Calico\u7f51\u7edc\u662f\u5426\u6b63\u5e38\u5de5\u4f5c\u3002\u53ef\u4ee5\u521b\u5efa\u4e24\u4e2a\u8fd0\u884c\u5728\u4e0d\u540c\u8282\u70b9\u4e0a\u7684Pod\uff0c\u5e76\u5c1d\u8bd5\u4ece\u4e00\u4e2aPod ping\u53e6\u4e00\u4e2aPod\u3002\u5982\u679cping\u6210\u529f\uff0c\u5219\u8868\u793aCalico\u7f51\u7edc\u5df2\u6210\u529f\u914d\u7f6e\u548c\u8fd0\u884c\u3002","title":"\u4e3b\u9898\u8ba8\u8bba:\u5b89\u88c5Calico"},{"location":"k8s/cka_cn/foundamentals/casestudy-calico/#calico_1","text":"\u4e3a\u4e86\u5c06Kubernetes\u7528\u4f5cCalico\u6570\u636e\u5b58\u50a8\u5e93\uff0c\u6211\u4eec\u9700\u8981\u5b9a\u4e49Calico\u4f7f\u7528\u7684\u81ea\u5b9a\u4e49\u8d44\u6e90\u3002 \u4e0b\u8f7d\u5e76\u68c0\u67e5Calico\u81ea\u5b9a\u4e49\u8d44\u6e90\u5b9a\u4e49\u5217\u8868\uff0c\u5e76\u5728\u6587\u4ef6\u7f16\u8f91\u5668\u4e2d\u6253\u5f00\u5b83\u3002 wget https://projectcalico.docs.tigera.io/manifests/crds.yaml \u5728 Kubernetes \u4e2d\u521b\u5efa Calico \u7684\u81ea\u5b9a\u4e49\u8d44\u6e90\u3002 kubectl apply -f crds.yaml \u5b89\u88c5 calicoctl \u3002 \u4e0b\u8f7d calicoctl \u4e8c\u8fdb\u5236\u6587\u4ef6\u5230\u4e00\u4e2a\u53ef\u4ee5\u8bbf\u95ee Kubernetes \u7684 Linux \u4e3b\u673a\u4e0a\uff0c\u4ee5\u76f4\u63a5\u4e0e Calico \u6570\u636e\u5b58\u50a8\u4ea4\u4e92\u3002 \u6700\u65b0\u7248\u7684calicoctl\u53ef\u4ee5\u901a\u8fc7 git page \u8fdb\u884c\u4e0b\u8f7d\uff0c\u9700\u8981\u7528\u5b9e\u9645\u7248\u672c\u53f7\u66ff\u6362\u4e0b\u9762\u7684 v3.23.2 \u7684\u7248\u672c\u53f7\u3002 wget https://github.com/projectcalico/calico/releases/download/v3.23.3/calicoctl-linux-amd64 chmod +x calicoctl-linux-amd64 sudo cp calicoctl-linux-amd64 /usr/local/bin/calicoctl \u914d\u7f6e calicoctl \u4ee5\u8bbf\u95ee Kubernetes\u3002 echo \"export KUBECONFIG=/root/.kube/config\" >> ~/.bashrc echo \"export DATASTORE_TYPE=kubernetes\" >> ~/.bashrc echo $KUBECONFIG echo $DATASTORE_TYPE \u6267\u884c\u4e0b\u9762\u7684\u547d\u4ee4\uff0c\u9a8c\u8bc1 calicoctl \u80fd\u591f\u8bbf\u95ee\u6570\u636e\u5e93\u3002 calicoctl get nodes -o wide \u8fd0\u884c\u7ed3\u679c\u7c7b\u4f3c\u5982\u4e0b\uff1a NAME ASN IPV4 IPV6 cka001 cka002 cka003 \u8282\u70b9\u662f\u7531 Kubernetes \u8282\u70b9\u5bf9\u8c61\u652f\u6301\u7684\uff0c\u56e0\u6b64\u6211\u4eec\u5e94\u8be5\u770b\u5230\u4e0e kubectl get nodes \u5339\u914d\u7684\u540d\u79f0\u3002 kubectl get nodes -o wide \u8fd0\u884c\u7ed3\u679c\uff1a NAME STATUS ROLES AGE VERSION OS-IMAGE KERNEL-VERSION CONTAINER-RUNTIME cka001 NotReady control-plane,master 23m v1.24.0 Ubuntu 20.04.4 LTS 5.4.0-113-generic containerd://1.5.9 cka002 NotReady 22m v1.24.0 Ubuntu 20.04.4 LTS 5.4.0-113-generic containerd://1.5.9 cka003 NotReady 21m v1.24.0 Ubuntu 20.04.4 LTS 5.4.0-113-generic containerd://1.5.9","title":"Calico\u6570\u636e\u5e93"},{"location":"k8s/cka_cn/foundamentals/casestudy-calico/#ip","text":"\u4e00\u4e2a\u5de5\u4f5c\u8d1f\u8f7d\uff08workload\uff09\u662f\u5bb9\u5668\u6216\u865a\u62df\u673a\uff0c\u57fa\u4e8eCalico\u7684\u865a\u62df\u7f51\u7edc\u3002 \u5728Kubernetes\u4e2d\uff0c\u5de5\u4f5c\u8d1f\u8f7d\u662fPod\u3002\u4e00\u4e2a\u5de5\u4f5c\u8d1f\u8f7d\u7aef\u70b9\uff08endpoint\uff09\u662f\u5de5\u4f5c\u8d1f\u8f7d\u7528\u6765\u8fde\u63a5Calico\u7f51\u7edc\u7684\u865a\u62df\u7f51\u7edc\u63a5\u53e3\u3002 IP\u6c60\u662fCalico\u4e3a\u5de5\u4f5c\u8d1f\u8f7d\u7aef\u70b9\u4f7f\u7528\u7684IP\u5730\u5740\u8303\u56f4\u3002 \u83b7\u53d6\u96c6\u7fa4\u4e2d\u5f53\u524d\u7684IP\u6c60\u3002\u76ee\u524d\uff0c\u5728\u521a\u521a\u5b89\u88c5\u5b8c\u4e4b\u540e\uff0c\u5b83\u662f\u7a7a\u7684\u3002 calicoctl get ippools \u8fd0\u884c\u7ed3\u679c\uff1a NAME CIDR SELECTOR \u6211\u4eec\u901a\u8fc7 kubeadm init \u547d\u4ee4\u6307\u5b9a\u4e86 Pod CIDR \u4e3a 10.244.0.0/16 \u3002 \u73b0\u5728\uff0c\u6211\u4eec\u4e3a\u96c6\u7fa4\u521b\u5efa\u4e24\u4e2a IP \u6c60\uff08IP pool\uff09\uff0c\u6bcf\u4e2a\u6c60\u4e4b\u95f4\u4e0d\u80fd\u91cd\u53e0\u3002 \u521b\u5efaIP\u6c60 ipv4-ippool-1 : 10.244.0.0/18 calicoctl apply -f - < /etc/cni/net.d/10-calico.conflist < /etc/cni/net.d/10-calico.conflist < /etc/cni/net.d/10-calico.conflist < 4h49m v1.24.0 cka003 Ready 4h49m v1.24.0","title":"\u5b89\u88c5CNI\u63d2\u4ef6"},{"location":"k8s/cka_cn/foundamentals/casestudy-calico/#typha","text":"Typha \u5904\u4e8e Kubernetes API \u670d\u52a1\u5668\u548c\u6bcf\u4e2a\u8282\u70b9\u5b88\u62a4\u8fdb\u7a0b\uff08\u5982\u8fd0\u884c\u5728 calico/node \u4e2d\u7684 Felix \u548c confd\uff09\u4e4b\u95f4\u3002 \u5b83\u76d1\u89c6\u8fd9\u4e9b\u5b88\u62a4\u8fdb\u7a0b\u4f7f\u7528\u7684 Kubernetes \u8d44\u6e90\u548c Calico \u81ea\u5b9a\u4e49\u8d44\u6e90\uff0c\u6bcf\u5f53\u8d44\u6e90\u66f4\u6539\u65f6\uff0c\u5b83\u4f1a\u5c06\u66f4\u65b0\u6269\u6563\u5230\u8fd9\u4e9b\u5b88\u62a4\u8fdb\u7a0b\u3002 \u8fd9\u51cf\u5c11\u4e86 Kubernetes API \u670d\u52a1\u5668\u9700\u8981\u670d\u52a1\u7684\u76d1\u89c6\u6570\uff0c\u63d0\u9ad8\u4e86\u96c6\u7fa4\u7684\u53ef\u6269\u5c55\u6027\u3002 \u51c6\u5907\u8bc1\u4e66 \u4e0b\u9762\uff0c\u6211\u4eec\u4f7f\u7528\u76f8\u4e92\u8ba4\u8bc1\u7684TLS\u6765\u786e\u4fddcalico/node\u548cTypha\u4e4b\u95f4\u7684\u901a\u4fe1\u5b89\u5168\u3002 \u751f\u6210\u4e00\u4e2a\u8bc1\u4e66\u6388\u6743\u673a\u6784\uff08CA\uff09\u5e76\u4f7f\u7528\u5b83\u6765\u4e3aTypha\u7b7e\u7f72\u8bc1\u4e66\u3002 \u5c06\u5f53\u524d\u5de5\u4f5c\u76ee\u5f55\u6539\u4e3a /etc/kubernetes/pki/ \u3002 cd /etc/kubernetes/pki/ \u521b\u5efaCA\u8bc1\u4e66\u548c\u5bc6\u94a5\u3002 openssl req -x509 -newkey rsa:4096 \\ -keyout typhaca.key \\ -nodes \\ -out typhaca.crt \\ -subj \"/CN=Calico Typha CA\" \\ -days 365 \u628aCA\u8bc1\u4e66\u5b58\u653e\u5728ConfigMap\u4e2d\uff0c\u4f7fTypha\u548ccalico/node\u80fd\u591f\u8bbf\u95ee\u3002 kubectl create configmap -n kube-system calico-typha-ca --from-file = typhaca.crt \u751f\u6210Typha\u5bc6\u94a5\u548c\u8bc1\u4e66\u7b7e\u540d\u8bf7\u6c42\uff08certificate signing request\uff0cCSR\uff09\u3002 openssl req -newkey rsa:4096 \\ -keyout typha.key \\ -nodes \\ -out typha.csr \\ -subj \"/CN=calico-typha\" \u8bc1\u4e66\u7684\u901a\u7528\u540d\u79f0\uff08CN\uff09\u8bbe\u7f6e\u4e3a calico-typha \u3002 calico/node \u5c06\u88ab\u7528\u6765\u9a8c\u8bc1\u6b64\u540d\u79f0\u3002 \u4f7f\u7528 CA \u5bf9 Typha \u8bc1\u4e66\u8fdb\u884c\u7b7e\u540d\u3002 openssl x509 -req -in typha.csr \\ -CA typhaca.crt \\ -CAkey typhaca.key \\ -CAcreateserial \\ -out typha.crt \\ -days 365 \u8fd0\u884c\u7ed3\u679c\uff1a Signature ok subject=CN = calico-typha Getting CA Private Key \u5c06 Typha \u5bc6\u94a5\u548c\u8bc1\u4e66\u5b58\u50a8\u5728\u4e00\u4e2a secret \u4e2d\uff0c\u4ee5\u4fbf Typha \u53ef\u4ee5\u8bbf\u95ee\u3002 kubectl create secret generic -n kube-system calico-typha-certs --from-file = typha.key --from-file = typha.crt \u914d\u7f6eRBAC \u5f53\u524d\u5de5\u4f5c\u76ee\u5f55\u4e3ahome\u8def\u5f84\u3002 cd ~ \u521b\u5efa\u4e00\u4e2aTypha\u4f7f\u7528\u7684ServiceAccount\u3002 kubectl create serviceaccount -n kube-system calico-typha \u4e3a Typha \u521b\u5efa\u4e00\u4e2a\u96c6\u7fa4\u89d2\u8272\uff0c\u6709\u89c2\u5bdf Calico \u6570\u636e\u5b58\u50a8\u5bf9\u8c61\u7684\u6743\u9650\u3002 kubectl apply -f - < pingtest-585b76c894-s2tbs 1/1 Running 0 7s 10.244.31.0 cka002 pingtest-585b76c894-vm9wn 1/1 Running 0 7s 10.244.28.64 cka003 \u7559\u610f\u7b2c\u4e8c\u4e2a\u548c\u7b2c\u4e09\u4e2a pod \u7684 IP \u5730\u5740\u3002 \u968f\u540e\u6211\u4eec\u4f1a\u5728\u7b2c\u4e00\u4e2a pod \u4e2d\u8fd0\u884c exec \u547d\u4ee4\u3002 \u5728\u7b2c\u4e00\u4e2a pod \u5185\u90e8\uff0c\u5bf9\u53e6\u5916\u4e24\u4e2a pod \u7684 IP \u5730\u5740\u8fdb\u884c ping \u6d4b\u8bd5\u3002 \u4f8b\u5982\uff1a kubectl exec -ti pingtest-585b76c894-chwjq -- sh / # ping 10.244.31.1 -c 4 4 packets transmitted, 4 packets received, 0 % packet loss / # ping 10.244.31.0 -c 4 4 packets transmitted, 4 packets received, 0 % packet loss / # ping 10.244.28.64 -c 4 4 packets transmitted, 0 packets received, 100 % packet loss","title":"pod\u4e4b\u95f4\u7684ping"},{"location":"k8s/cka_cn/foundamentals/casestudy-calico/#_2","text":"\u4ece\u5176\u4e2d\u4e00\u4e2a\u8282\u70b9\u9a8c\u8bc1\u662f\u5426\u80fdping\u901a\u5230\u6bcf\u4e2apod\u7684IP\u5730\u5740\u3002\u4f8b\u5982\uff1a ip route get 10 .244.31.1 ip route get 10 .244.31.0 ip route get 10 .244.28.64 \u5728\u4e0a\u9762\u7684\u7ed3\u679c\u4e2d\uff0c\u793a\u4f8b\u4e2d\u7684 via \uff08\u5b83\u662f\u63a7\u5236\u5e73\u9762\uff09\u8868\u793a\u6b64Pod IP\u7684\u4e0b\u4e00\u8df3\uff0c\u8fd9\u4e0ePod\u6240\u5728\u8282\u70b9\u7684IP\u5730\u5740\u5339\u914d\uff0c\u7b26\u5408\u9884\u671f\u3002 \u4e0d\u540cIP\u6c60\u7684IPAM\u5206\u914d\u3002\u5728\u524d\u9762\u7684\u6f14\u793a\u4e2d\uff0c\u6211\u4eec\u521b\u5efa\u4e86\u4e24\u4e2aIP\u6c60\uff0c\u4f46\u5c06\u4e00\u4e2a\u7981\u7528\u4e86\u3002 calicoctl get ippools -o wide \u8fd0\u884c\u7ed3\u679c\uff1a NAME CIDR NAT IPIPMODE VXLANMODE DISABLED DISABLEBGPEXPORT SELECTOR ipv4-ippool-1 10.244.0.0/18 true Never Never false false all() ipv4-ippool-2 10.244.192.0/19 true Never Never true false all() \u6fc0\u6d3b\u7b2c\u4e8c\u4e2aIP\u6c60\u3002 calicoctl --allow-version-mismatch apply -f - < \u8fde\u63a5\u5e76\u8fdb\u5165Pod pingtest-585b76c894-chwjq \u5185\u90e8\u3002 kubectl exec -ti pingtest-585b76c894-chwjq -- sh / # 10.244.203.192 -c 4 4 packets transmitted, 0 packets received, 100 % packet loss \u6807\u8bb0\uff1a \u6f14\u793a\u6b62\u4e8e\u6b64\uff0c\u8def\u7531\u6ca1\u6709\u5b89\u88c5\u9884\u671f\u5de5\u4f5c\uff0c\u539f\u56e0\u67e5\u627e\u4e2d\u3002 \u5220\u9664\u6f14\u793a\u4e2d\u521b\u5efa\u7684\u4e34\u65f6\u8d44\u6e90\u3002 kubectl delete deployments.apps pingtest kubectl delete pod pingtest-ippool-2 \u53c2\u8003\uff1a End-to-end Calico installation","title":"\u8def\u7531\u68c0\u67e5"},{"location":"k8s/cka_cn/foundamentals/casestudy-health-check/","text":"\u4e3b\u9898\u8ba8\u8bba:\u5065\u5eb7\u68c0\u67e5 \u00b6 \u6f14\u793a\u573a\u666f\uff1a \u521b\u5efa Deployment \u548c Service \u6a21\u62df\u4e00\u4e2a\u9519\u8bef\uff08\u5220\u9664 index.html\uff09 Pod \u5904\u4e8e\u4e0d\u5065\u5eb7\u72b6\u6001\u5e76\u4ece endpoint \u5217\u8868\u4e2d\u5220\u9664 \u4fee\u590d\u9519\u8bef\uff08\u6062\u590d index.html\uff09 Pod \u56de\u5230\u6b63\u5e38\u72b6\u6001\u5e76\u91cd\u65b0\u52a0\u5165 endpoint \u5217\u8868 \u521b\u5efa Deployment \u548c Service \u00b6 \u521b\u5efaDeployment nginx-healthcheck \u548cService nginx-healthcheck \u3002 kubectl apply -f - < nginx-healthcheck-79fc55d944-nwwjc 1/1 Running 0 9s 10.244.112.13 cka002 \u901a\u8fc7\u547d\u4ee4 curl \u6765\u8bbf\u95ee\u4e0a\u9762\u8fd0\u884c\u7ed3\u679c\u4e2dpod\u7684IP\u5730\u5740\u3002 curl 10 .244.102.14 curl 10 .244.112.13 \u5982\u679c\u4e0a\u9762\u547d\u4ee4\u6210\u529f\u6267\u884c\uff0c\u5219\u4f1a\u8fd4\u56deNginx\u4e2d index.html \u7684\u5185\u5bb9\u3002 \u83b7\u53d6\u524d\u9762\u521b\u5efa\u7684Service\u7684\u8be6\u7ec6\u4fe1\u606f\u3002 kubectl describe svc nginx-healthcheck \u8f93\u51fa\u7ed3\u679c\u5982\u4e0b\u3002\u5728 Endpoints \u90e8\u5206\u6211\u4eec\u53ef\u4ee5\u770b\u52302\u4e2apod\u3002 Name : nginx-healthcheck Namespace : dev Labels : Annotations : Selector : name=nginx-healthcheck Type : NodePort IP Family Policy : SingleStack IP Families : IPv4 IP : 11.244.238.20 IPs : 11.244.238.20 Port : 80/TCP TargetPort : 80/TCP NodePort : 31795/TCP Endpoints : 10.244.102.14:80,10.244.112.13:80 Session Affinity : None External Traffic Policy : Cluster Events : \u83b7\u53d6Endpoints\u7684\u4fe1\u606f\u3002 kubectl get endpoints nginx-healthcheck \u8fd0\u884c\u7ed3\u679c NAME ENDPOINTS AGE nginx-healthcheck 10.244.102.14:80,10.244.112.13:80 72s \u81f3\u6b64\uff0c2\u4e2apod nginx-healthcheck \u90fd\u80fd\u6309\u7167\u6211\u4eec\u7684\u671f\u671b\u6b63\u5e38\u5de5\u4f5c\u3002 \u6a21\u62dfreadinessProbe\u9519\u8bef \u00b6 \u8ba9\u6211\u4eec\u901a\u8fc7\u5220\u9664 nginx-healthcheck Pod \u4e2d\u7684 index.html \u6587\u4ef6\u6765\u6a21\u62df\u9519\u8bef\uff0c\u89c2\u5bdf readinessProbe \u7684\u8868\u73b0\u3002 \u9996\u5148\uff0c\u6267\u884c kubectl exec -it -- bash \u547d\u4ee4\u4ee5\u767b\u5f55\u5230 nginx-healthcheck Pod\uff0c\u5e76\u5220\u9664 index.html \u6587\u4ef6\u3002 kubectl exec -it nginx-healthcheck-79fc55d944-jw887 -- bash cd /usr/share/nginx/html/ rm -rf index.html exit \u5728\u6267\u884c\u4e86\u5220\u9664 nginx-healthcheck Pod \u4e2d\u7684 index.html \u6587\u4ef6\u4e4b\u540e\uff0c\u6211\u4eec\u68c0\u67e5\u8be5 Pod \u7684\u72b6\u6001\u3002 kubectl describe pod nginx-healthcheck-79fc55d944-jw887 \u4e0b\u9762\u7684\u8f93\u51fa\u7ed3\u679c\u4e2d\uff0c\u6211\u4eec\u53ef\u4ee5\u770b\u5230 Readiness probe failed \u8fd9\u4e2a\u9519\u8bef\u4e8b\u4ef6\u4fe1\u606f\u3002 ...... Events: Type Reason Age From Message ---- ------ ---- ---- ------- Normal Scheduled 2m8s default-scheduler Successfully assigned dev/nginx-healthcheck-79fc55d944-jw887 to cka003 Normal Pulled 2m7s kubelet Container image \"nginx:latest\" already present on machine Normal Created 2m7s kubelet Created container nginx-healthcheck Normal Started 2m7s kubelet Started container nginx-healthcheck Warning Unhealthy 2s (x2 over 7s) kubelet Readiness probe failed: HTTP probe failed with statuscode: 403 \u68c0\u67e5\u53e6\u4e00\u4e2apod\u3002 kubectl describe pod nginx-healthcheck-79fc55d944-nwwjc \u4e0b\u9762\u7684\u8f93\u51fa\u7ed3\u679c\u4e2d\uff0c\u6ca1\u6709\u53d1\u73b0\u9519\u8bef\u3002 ...... Events: Type Reason Age From Message ---- ------ ---- ---- ------- Normal Scheduled 3m46s default-scheduler Successfully assigned dev/nginx-healthcheck-79fc55d944-nwwjc to cka002 Normal Pulled 3m45s kubelet Container image \"nginx:latest\" already present on machine Normal Created 3m45s kubelet Created container nginx-healthcheck Normal Started 3m45s kubelet Started container nginx-healthcheck \u73b0\u5728\uff0c\u901a\u8fc7 curl \u547d\u4ee4\u6765\u8bbf\u95ee2\u4e2apod\u7684IP\u5730\u5740\uff0c\u6211\u4eec\u6765\u89c2\u5bdf\u4f1a\u5f97\u5230\u600e\u6837\u7684\u7ed3\u679c\u3002 curl 10 .244.102.14 curl 10 .244.112.13 \u8fd0\u884c\u7ed3\u679c\uff1a curl 10.244.102.14 \u5931\u8d25\uff0c\u9519\u8bef\u4fe1\u606f\u662f 403 Forbidden \u3002 curl 10.244.112.13 \u6210\u529f\u3002 \u6211\u4eec\u73b0\u5728\u6765\u67e5\u8be2Nginx service\u5728\u4e00\u4e2apod\u5931\u8d25\u65f6\u7684\u72b6\u6001\u3002 kubectl describe svc nginx-healthcheck \u5728\u4e0b\u9762\u7684\u8f93\u51fa\u7ed3\u679c\u4e2d\uff0c\u6211\u4eec\u770b\u5230Endpoint\u90e8\u5206\u4e2d\u53ea\u6709\u4e00\u4e2apod\u7684\u4fe1\u606f\u3002 Name : nginx-healthcheck Namespace : dev Labels : Annotations : Selector : name=nginx-healthcheck Type : NodePort IP Family Policy : SingleStack IP Families : IPv4 IP : 11.244.238.20 IPs : 11.244.238.20 Port : 80/TCP TargetPort : 80/TCP NodePort : 31795/TCP Endpoints : 10.244.112.13:80 Session Affinity : None External Traffic Policy : Cluster Events : \u540c\u6837\u7684\uff0c\u6211\u4eec\u53ef\u4ee5\u901a\u8fc7\u68c0\u67e5Endpoint\u7684\u4fe1\u606f\uff0c\u4e5f\u80fd\u53d1\u73b0\u53ea\u6709\u4e00\u4e2apod\u6b63\u5728\u8fd0\u884c\u3002 kubectl get endpoints nginx-healthcheck \u8fd0\u884c\u7ed3\u679c\uff1a NAME ENDPOINTS AGE nginx-healthcheck 10.244.112.13:80 6m5s \u4fee\u590dreadinessProbe\u9519\u8bef \u00b6 \u73b0\u5728\uff0c\u6211\u4eec\u5728pod\u4e2d\u91cd\u65b0\u521b\u5efa index.html \u6587\u4ef6\uff0c\u6765\u4fee\u590d\u9519\u8bef\u3002 kubectl exec -it nginx-healthcheck-79fc55d944-jw887 -- bash cd /usr/share/nginx/html/ cat > index.html << EOF Welcome to nginx!

Welcome to nginx!

If you see this page, the nginx web server is successfully installed and working. Further configuration is required.

For online documentation and support please refer to nginx.org.
Commercial support is available at nginx.com.

Thank you for using nginx.

EOF exit \u73b0\u5728\u6211\u4eec\u53ef\u4ee5\u770b\u5230\u4e24\u4e2aPod\u5df2\u7ecf\u91cd\u65b0\u52a0\u5165\u4e86Endpoint\u5217\u8868\uff0c\u53ef\u4ee5\u63d0\u4f9b\u670d\u52a1\u4e86\u3002 kubectl describe svc nginx-healthcheck kubectl get endpoints nginx-healthcheck \u91cd\u65b0\u901a\u8fc7 curl \u547d\u4ee4\u8bbf\u95ee2\u4e2apod\u7684IP\u5730\u5740\uff0c\u6211\u4eec\u53ef\u4ee5\u770b\u5230\u5b83\u4eec\u90fd\u5df2\u7ecf\u6062\u590d\u5230\u6b63\u5e38\u72b6\u6001\u4e86\u3002 curl 10 .244.102.14 curl 10 .244.112.13 \u518d\u6b21\u9a8c\u8bc1pod\u7684\u72b6\u6001\u3002 kubectl describe pod nginx-healthcheck-79fc55d944-jw887 \u7ed3\u8bba\uff1a \u901a\u8fc7\u5220\u9664 index.html \u6587\u4ef6\uff0cPod \u8fdb\u5165\u4e0d\u5065\u5eb7\u72b6\u6001\u5e76\u4ece\u7aef\u70b9\u5217\u8868\u4e2d\u5220\u9664\u3002 \u53ea\u6709\u4e00\u4e2a\u5065\u5eb7\u7684 Pod \u53ef\u4ee5\u63d0\u4f9b\u6b63\u5e38\u7684\u670d\u52a1\u3002 \u6e05\u9664\u6f14\u793a\u4e2d\u521b\u5efa\u7684\u4e34\u65f6\u8d44\u6e90\u3002 kubectl delete service nginx-healthcheck kubectl delete deployment nginx-healthcheck \u6a21\u62dflivenessProbe\u9519\u8bef \u00b6 \u91cd\u65b0\u521b\u5efadeployment nginx-healthcheck \u548cservice nginx-healthcheck \u3002 Deployment: NAME READY UP-TO-DATE AVAILABLE AGE nginx-healthcheck 0/2 2 0 7s Pods: NAME READY STATUS RESTARTS AGE nginx-healthcheck-79fc55d944-lknp9 1/1 Running 0 96s nginx-healthcheck-79fc55d944-wntmg 1/1 Running 0 96s \u5c06 Nginx \u9ed8\u8ba4\u76d1\u542c\u7aef\u53e3\u4ece 80 \u6539\u4e3a 90 \uff0c\u4ee5\u6a21\u62df livenessProbe \u5931\u8d25\u3002livenessProbe \u901a\u8fc7\u7aef\u53e3 80 \u68c0\u67e5\u751f\u5b58\u72b6\u6001\u3002 kubectl exec -it nginx-healthcheck-79fc55d944-lknp9 -- bash root@nginx-healthcheck-79fc55d944-lknp9:/# cd /etc/nginx/conf.d root@nginx-healthcheck-79fc55d944-lknp9:/etc/nginx/conf.d# sed -i 's/80/90/g' default.conf root@nginx-healthcheck-79fc55d944-lknp9:/etc/nginx/conf.d# nginx -s reload 2022 /07/24 12 :59:45 [ notice ] 79 #79: signal process started Pod\u73b0\u5728\u8868\u73b0\u4e3a\u5931\u8d25\u72b6\u6001\u3002 kubectl describe pod nginx-healthcheck-79fc55d944-lknp9 \u5728pod\u7684\u4e8b\u4ef6\u4fe1\u606f\u4e2d\uff0c\u6211\u4eec\u53ef\u4ee5\u53d1\u73b0 livenessProbe \u9519\u8bef\u4fe1\u606f\u3002 Events: Type Reason Age From Message ---- ------ ---- ---- ------- Normal Scheduled 17m default-scheduler Successfully assigned dev/nginx-healthcheck-79fc55d944-lknp9 to cka003 Normal Pulled 2m47s (x2 over 17m) kubelet Container image \"nginx:latest\" already present on machine Normal Created 2m47s (x2 over 17m) kubelet Created container nginx-healthcheck Normal Started 2m47s (x2 over 17m) kubelet Started container nginx-healthcheck Warning Unhealthy 2m47s (x4 over 2m57s) kubelet Readiness probe failed: Get \"http://10.244.102.46:80/\": dial tcp 10.244.102.46:80: connect: connection refused Warning Unhealthy 2m47s (x3 over 2m57s) kubelet Liveness probe failed: dial tcp 10.244.102.46:80: connect: connection refused Normal Killing 2m47s kubelet Container nginx-healthcheck failed liveness probe, will be restarted \u5f53 livenessProbe \u68c0\u6d4b\u5230\u5931\u8d25\u540e\uff0c\u5bb9\u5668\u5c06\u81ea\u52a8\u91cd\u65b0\u542f\u52a8\u3002\u6211\u4eec\u4fee\u6539\u7684 default.conf \u6587\u4ef6\u5c06\u88ab\u9ed8\u8ba4\u6587\u4ef6\u66ff\u6362\uff0c\u5bb9\u5668\u72b6\u6001\u5c06\u6062\u590d\u6b63\u5e38\u3002","title":"\u5065\u5eb7\u68c0\u67e5"},{"location":"k8s/cka_cn/foundamentals/casestudy-health-check/#_1","text":"\u6f14\u793a\u573a\u666f\uff1a \u521b\u5efa Deployment \u548c Service \u6a21\u62df\u4e00\u4e2a\u9519\u8bef\uff08\u5220\u9664 index.html\uff09 Pod \u5904\u4e8e\u4e0d\u5065\u5eb7\u72b6\u6001\u5e76\u4ece endpoint \u5217\u8868\u4e2d\u5220\u9664 \u4fee\u590d\u9519\u8bef\uff08\u6062\u590d index.html\uff09 Pod \u56de\u5230\u6b63\u5e38\u72b6\u6001\u5e76\u91cd\u65b0\u52a0\u5165 endpoint \u5217\u8868","title":"\u4e3b\u9898\u8ba8\u8bba:\u5065\u5eb7\u68c0\u67e5"},{"location":"k8s/cka_cn/foundamentals/casestudy-health-check/#deployment-service","text":"\u521b\u5efaDeployment nginx-healthcheck \u548cService nginx-healthcheck \u3002 kubectl apply -f - < nginx-healthcheck-79fc55d944-nwwjc 1/1 Running 0 9s 10.244.112.13 cka002 \u901a\u8fc7\u547d\u4ee4 curl \u6765\u8bbf\u95ee\u4e0a\u9762\u8fd0\u884c\u7ed3\u679c\u4e2dpod\u7684IP\u5730\u5740\u3002 curl 10 .244.102.14 curl 10 .244.112.13 \u5982\u679c\u4e0a\u9762\u547d\u4ee4\u6210\u529f\u6267\u884c\uff0c\u5219\u4f1a\u8fd4\u56deNginx\u4e2d index.html \u7684\u5185\u5bb9\u3002 \u83b7\u53d6\u524d\u9762\u521b\u5efa\u7684Service\u7684\u8be6\u7ec6\u4fe1\u606f\u3002 kubectl describe svc nginx-healthcheck \u8f93\u51fa\u7ed3\u679c\u5982\u4e0b\u3002\u5728 Endpoints \u90e8\u5206\u6211\u4eec\u53ef\u4ee5\u770b\u52302\u4e2apod\u3002 Name : nginx-healthcheck Namespace : dev Labels : Annotations : Selector : name=nginx-healthcheck Type : NodePort IP Family Policy : SingleStack IP Families : IPv4 IP : 11.244.238.20 IPs : 11.244.238.20 Port : 80/TCP TargetPort : 80/TCP NodePort : 31795/TCP Endpoints : 10.244.102.14:80,10.244.112.13:80 Session Affinity : None External Traffic Policy : Cluster Events : \u83b7\u53d6Endpoints\u7684\u4fe1\u606f\u3002 kubectl get endpoints nginx-healthcheck \u8fd0\u884c\u7ed3\u679c NAME ENDPOINTS AGE nginx-healthcheck 10.244.102.14:80,10.244.112.13:80 72s \u81f3\u6b64\uff0c2\u4e2apod nginx-healthcheck \u90fd\u80fd\u6309\u7167\u6211\u4eec\u7684\u671f\u671b\u6b63\u5e38\u5de5\u4f5c\u3002","title":"\u521b\u5efa Deployment \u548c Service"},{"location":"k8s/cka_cn/foundamentals/casestudy-health-check/#readinessprobe","text":"\u8ba9\u6211\u4eec\u901a\u8fc7\u5220\u9664 nginx-healthcheck Pod \u4e2d\u7684 index.html \u6587\u4ef6\u6765\u6a21\u62df\u9519\u8bef\uff0c\u89c2\u5bdf readinessProbe \u7684\u8868\u73b0\u3002 \u9996\u5148\uff0c\u6267\u884c kubectl exec -it -- bash \u547d\u4ee4\u4ee5\u767b\u5f55\u5230 nginx-healthcheck Pod\uff0c\u5e76\u5220\u9664 index.html \u6587\u4ef6\u3002 kubectl exec -it nginx-healthcheck-79fc55d944-jw887 -- bash cd /usr/share/nginx/html/ rm -rf index.html exit \u5728\u6267\u884c\u4e86\u5220\u9664 nginx-healthcheck Pod \u4e2d\u7684 index.html \u6587\u4ef6\u4e4b\u540e\uff0c\u6211\u4eec\u68c0\u67e5\u8be5 Pod \u7684\u72b6\u6001\u3002 kubectl describe pod nginx-healthcheck-79fc55d944-jw887 \u4e0b\u9762\u7684\u8f93\u51fa\u7ed3\u679c\u4e2d\uff0c\u6211\u4eec\u53ef\u4ee5\u770b\u5230 Readiness probe failed \u8fd9\u4e2a\u9519\u8bef\u4e8b\u4ef6\u4fe1\u606f\u3002 ...... Events: Type Reason Age From Message ---- ------ ---- ---- ------- Normal Scheduled 2m8s default-scheduler Successfully assigned dev/nginx-healthcheck-79fc55d944-jw887 to cka003 Normal Pulled 2m7s kubelet Container image \"nginx:latest\" already present on machine Normal Created 2m7s kubelet Created container nginx-healthcheck Normal Started 2m7s kubelet Started container nginx-healthcheck Warning Unhealthy 2s (x2 over 7s) kubelet Readiness probe failed: HTTP probe failed with statuscode: 403 \u68c0\u67e5\u53e6\u4e00\u4e2apod\u3002 kubectl describe pod nginx-healthcheck-79fc55d944-nwwjc \u4e0b\u9762\u7684\u8f93\u51fa\u7ed3\u679c\u4e2d\uff0c\u6ca1\u6709\u53d1\u73b0\u9519\u8bef\u3002 ...... Events: Type Reason Age From Message ---- ------ ---- ---- ------- Normal Scheduled 3m46s default-scheduler Successfully assigned dev/nginx-healthcheck-79fc55d944-nwwjc to cka002 Normal Pulled 3m45s kubelet Container image \"nginx:latest\" already present on machine Normal Created 3m45s kubelet Created container nginx-healthcheck Normal Started 3m45s kubelet Started container nginx-healthcheck \u73b0\u5728\uff0c\u901a\u8fc7 curl \u547d\u4ee4\u6765\u8bbf\u95ee2\u4e2apod\u7684IP\u5730\u5740\uff0c\u6211\u4eec\u6765\u89c2\u5bdf\u4f1a\u5f97\u5230\u600e\u6837\u7684\u7ed3\u679c\u3002 curl 10 .244.102.14 curl 10 .244.112.13 \u8fd0\u884c\u7ed3\u679c\uff1a curl 10.244.102.14 \u5931\u8d25\uff0c\u9519\u8bef\u4fe1\u606f\u662f 403 Forbidden \u3002 curl 10.244.112.13 \u6210\u529f\u3002 \u6211\u4eec\u73b0\u5728\u6765\u67e5\u8be2Nginx service\u5728\u4e00\u4e2apod\u5931\u8d25\u65f6\u7684\u72b6\u6001\u3002 kubectl describe svc nginx-healthcheck \u5728\u4e0b\u9762\u7684\u8f93\u51fa\u7ed3\u679c\u4e2d\uff0c\u6211\u4eec\u770b\u5230Endpoint\u90e8\u5206\u4e2d\u53ea\u6709\u4e00\u4e2apod\u7684\u4fe1\u606f\u3002 Name : nginx-healthcheck Namespace : dev Labels : Annotations : Selector : name=nginx-healthcheck Type : NodePort IP Family Policy : SingleStack IP Families : IPv4 IP : 11.244.238.20 IPs : 11.244.238.20 Port : 80/TCP TargetPort : 80/TCP NodePort : 31795/TCP Endpoints : 10.244.112.13:80 Session Affinity : None External Traffic Policy : Cluster Events : \u540c\u6837\u7684\uff0c\u6211\u4eec\u53ef\u4ee5\u901a\u8fc7\u68c0\u67e5Endpoint\u7684\u4fe1\u606f\uff0c\u4e5f\u80fd\u53d1\u73b0\u53ea\u6709\u4e00\u4e2apod\u6b63\u5728\u8fd0\u884c\u3002 kubectl get endpoints nginx-healthcheck \u8fd0\u884c\u7ed3\u679c\uff1a NAME ENDPOINTS AGE nginx-healthcheck 10.244.112.13:80 6m5s","title":"\u6a21\u62dfreadinessProbe\u9519\u8bef"},{"location":"k8s/cka_cn/foundamentals/casestudy-health-check/#readinessprobe_1","text":"\u73b0\u5728\uff0c\u6211\u4eec\u5728pod\u4e2d\u91cd\u65b0\u521b\u5efa index.html \u6587\u4ef6\uff0c\u6765\u4fee\u590d\u9519\u8bef\u3002 kubectl exec -it nginx-healthcheck-79fc55d944-jw887 -- bash cd /usr/share/nginx/html/ cat > index.html << EOF Welcome to nginx!

Welcome to nginx!

If you see this page, the nginx web server is successfully installed and working. Further configuration is required.

For online documentation and support please refer to nginx.org.
Commercial support is available at nginx.com.

Thank you for using nginx.

EOF exit \u73b0\u5728\u6211\u4eec\u53ef\u4ee5\u770b\u5230\u4e24\u4e2aPod\u5df2\u7ecf\u91cd\u65b0\u52a0\u5165\u4e86Endpoint\u5217\u8868\uff0c\u53ef\u4ee5\u63d0\u4f9b\u670d\u52a1\u4e86\u3002 kubectl describe svc nginx-healthcheck kubectl get endpoints nginx-healthcheck \u91cd\u65b0\u901a\u8fc7 curl \u547d\u4ee4\u8bbf\u95ee2\u4e2apod\u7684IP\u5730\u5740\uff0c\u6211\u4eec\u53ef\u4ee5\u770b\u5230\u5b83\u4eec\u90fd\u5df2\u7ecf\u6062\u590d\u5230\u6b63\u5e38\u72b6\u6001\u4e86\u3002 curl 10 .244.102.14 curl 10 .244.112.13 \u518d\u6b21\u9a8c\u8bc1pod\u7684\u72b6\u6001\u3002 kubectl describe pod nginx-healthcheck-79fc55d944-jw887 \u7ed3\u8bba\uff1a \u901a\u8fc7\u5220\u9664 index.html \u6587\u4ef6\uff0cPod \u8fdb\u5165\u4e0d\u5065\u5eb7\u72b6\u6001\u5e76\u4ece\u7aef\u70b9\u5217\u8868\u4e2d\u5220\u9664\u3002 \u53ea\u6709\u4e00\u4e2a\u5065\u5eb7\u7684 Pod \u53ef\u4ee5\u63d0\u4f9b\u6b63\u5e38\u7684\u670d\u52a1\u3002 \u6e05\u9664\u6f14\u793a\u4e2d\u521b\u5efa\u7684\u4e34\u65f6\u8d44\u6e90\u3002 kubectl delete service nginx-healthcheck kubectl delete deployment nginx-healthcheck","title":"\u4fee\u590dreadinessProbe\u9519\u8bef"},{"location":"k8s/cka_cn/foundamentals/casestudy-health-check/#livenessprobe","text":"\u91cd\u65b0\u521b\u5efadeployment nginx-healthcheck \u548cservice nginx-healthcheck \u3002 Deployment: NAME READY UP-TO-DATE AVAILABLE AGE nginx-healthcheck 0/2 2 0 7s Pods: NAME READY STATUS RESTARTS AGE nginx-healthcheck-79fc55d944-lknp9 1/1 Running 0 96s nginx-healthcheck-79fc55d944-wntmg 1/1 Running 0 96s \u5c06 Nginx \u9ed8\u8ba4\u76d1\u542c\u7aef\u53e3\u4ece 80 \u6539\u4e3a 90 \uff0c\u4ee5\u6a21\u62df livenessProbe \u5931\u8d25\u3002livenessProbe \u901a\u8fc7\u7aef\u53e3 80 \u68c0\u67e5\u751f\u5b58\u72b6\u6001\u3002 kubectl exec -it nginx-healthcheck-79fc55d944-lknp9 -- bash root@nginx-healthcheck-79fc55d944-lknp9:/# cd /etc/nginx/conf.d root@nginx-healthcheck-79fc55d944-lknp9:/etc/nginx/conf.d# sed -i 's/80/90/g' default.conf root@nginx-healthcheck-79fc55d944-lknp9:/etc/nginx/conf.d# nginx -s reload 2022 /07/24 12 :59:45 [ notice ] 79 #79: signal process started Pod\u73b0\u5728\u8868\u73b0\u4e3a\u5931\u8d25\u72b6\u6001\u3002 kubectl describe pod nginx-healthcheck-79fc55d944-lknp9 \u5728pod\u7684\u4e8b\u4ef6\u4fe1\u606f\u4e2d\uff0c\u6211\u4eec\u53ef\u4ee5\u53d1\u73b0 livenessProbe \u9519\u8bef\u4fe1\u606f\u3002 Events: Type Reason Age From Message ---- ------ ---- ---- ------- Normal Scheduled 17m default-scheduler Successfully assigned dev/nginx-healthcheck-79fc55d944-lknp9 to cka003 Normal Pulled 2m47s (x2 over 17m) kubelet Container image \"nginx:latest\" already present on machine Normal Created 2m47s (x2 over 17m) kubelet Created container nginx-healthcheck Normal Started 2m47s (x2 over 17m) kubelet Started container nginx-healthcheck Warning Unhealthy 2m47s (x4 over 2m57s) kubelet Readiness probe failed: Get \"http://10.244.102.46:80/\": dial tcp 10.244.102.46:80: connect: connection refused Warning Unhealthy 2m47s (x3 over 2m57s) kubelet Liveness probe failed: dial tcp 10.244.102.46:80: connect: connection refused Normal Killing 2m47s kubelet Container nginx-healthcheck failed liveness probe, will be restarted \u5f53 livenessProbe \u68c0\u6d4b\u5230\u5931\u8d25\u540e\uff0c\u5bb9\u5668\u5c06\u81ea\u52a8\u91cd\u65b0\u542f\u52a8\u3002\u6211\u4eec\u4fee\u6539\u7684 default.conf \u6587\u4ef6\u5c06\u88ab\u9ed8\u8ba4\u6587\u4ef6\u66ff\u6362\uff0c\u5bb9\u5668\u72b6\u6001\u5c06\u6062\u590d\u6b63\u5e38\u3002","title":"\u6a21\u62dflivenessProbe\u9519\u8bef"},{"location":"k8s/cka_cn/foundamentals/casestudy-operation-resources/","text":"\u4e3b\u9898\u8ba8\u8bba:Kubernetes\u8d44\u6e90\u5e38\u89c1\u64cd\u4f5c \u00b6 \u6f14\u793a\u573a\u666f\uff1a \u8282\u70b9\u6807\u7b7e\uff08Node Label\uff09 \u6ce8\u89e3\uff08Annotation\uff09 \u547d\u540d\u7a7a\u95f4\uff08Namespace\uff09 ServiceAccount \u6388\u6743\uff08ServiceAccount Authorization\uff09 \u6388\u6743\u9ed8\u8ba4 ServiceAccount \u8bbf\u95ee API \u90e8\u7f72\uff08Deployment\uff09 \u66b4\u9732\u670d\u52a1\uff08Expose Service\uff09 \u6269\u5c55\u90e8\u7f72\uff08Scale out the Deployment\uff09 \u6eda\u52a8\u5347\u7ea7\uff08Rolling update\uff09 \u56de\u6eda\u5347\u7ea7\uff08Rolling back update\uff09 \u4e8b\u4ef6\uff08Event\uff09 \u65e5\u5fd7\u8bb0\u5f55\uff08Logging\uff09 \u8282\u70b9\u6807\u7b7e\uff08Node Label\uff09 \u00b6 \u6dfb\u52a0/\u4fee\u6539/\u79fb\u51fa\u8282\u70b9\u6807\u7b7e\u3002 # Update node label kubectl label node cka002 node = demonode # Get node info with label info kubectl get node --show-labels # Search node by label kubectl get node -l node = demonode # Remove a lable of node kubectl label node cka002 node- \u6ce8\u89e3\uff08Annotation\uff09 \u00b6 \u521b\u5efadeployment Nginx \u3002 kubectl create deploy nginx --image = nginx:mainline \u83b7\u53d6\u6ce8\u89e3\u4fe1\u606f kubectl describe deployment/nginx \u8fd0\u884c\u7ed3\u679c\uff1a ...... Labels : app=nginx Annotations : deployment.kubernetes.io/revision : 1 Selector : app=nginx ...... \u6dfb\u52a0\u65b0\u7684\u6ce8\u89e3\u4fe1\u606f\u3002 kubectl annotate deployment nginx owner = James.H \u518d\u6b21\u67e5\u8be2\u6ce8\u89e3\u4fe1\u606f\u5f97\u5230\u5982\u4e0b\u7ed3\u679c\u3002 ...... Labels : app=nginx Annotations : deployment.kubernetes.io/revision : 1 owner : James.H Selector : app=nginx ...... \u66f4\u65b0/\u8986\u76d6\u6ce8\u89e3\u4fe1\u606f\u3002 kubectl annotate deployment/nginx owner = K8s --overwrite \u518d\u6b21\u67e5\u8be2\u6ce8\u89e3\u4fe1\u606f\u5f97\u5230\u5982\u4e0b\u7ed3\u679c\u3002 ...... Annotations : deployment.kubernetes.io/revision : 1 owner : K8s Selector : app=nginx ...... \u79fb\u9664\u6ce8\u89e3\u4fe1\u606f\u3002 kubectl annotate deployment/nginx owner- \u8fd0\u884c\u7ed3\u679c\uff1a ...... Labels : app=nginx Annotations : deployment.kubernetes.io/revision : 1 Selector : app=nginx ...... \u5220\u9664\u4e0a\u9762\u6f14\u793a\u4e2d\u521b\u5efa\u7684\u4e34\u65f6\u8d44\u6e90\u3002 kubectl delete deployment nginx \u547d\u540d\u7a7a\u95f4\uff08Namespace\uff09 \u00b6 \u67e5\u8be2\u5f53\u524d\u53ef\u7528namespace\u3002 kubectl get namespace \u8fd0\u884c\u7ed3\u679c\uff1a NAME STATUS AGE default Active 3h45m dev Active 3h11m kube-node-lease Active 3h45m kube-public Active 3h45m kube-system Active 3h45m \u67e5\u8be2\u67d0\u4e2anamespace\u4e0a\u8fd0\u884c\u7684pod\u4fe1\u606f\u3002 kubectl get pod -n kube-system \u8fd0\u884c\u7ed3\u679c\uff1a NAME READY STATUS RESTARTS AGE calico-kube-controllers-5c64b68895-jr4nl 1/1 Running 0 3h25m calico-node-dsx76 1/1 Running 0 3h25m calico-node-p5rf2 1/1 Running 0 3h25m calico-node-tr22l 1/1 Running 0 3h25m coredns-6d8c4cb4d-g4jxc 1/1 Running 0 3h45m coredns-6d8c4cb4d-sqcvj 1/1 Running 0 3h45m etcd-cka001 1/1 Running 0 3h45m kube-apiserver-cka001 1/1 Running 0 3h45m kube-controller-manager-cka001 1/1 Running 0 3h45m kube-proxy-5cdbj 1/1 Running 0 3h41m kube-proxy-cm4hc 1/1 Running 0 3h45m kube-proxy-g4w52 1/1 Running 0 3h41m kube-scheduler-cka001 1/1 Running 0 3h45m \u67e5\u8be2\u6240\u6709namespace\u4e0a\u7684pod\u4fe1\u606f\u3002 kubectl get pod --all-namespaces kubectl get pod -A ServiceAccount \u6388\u6743\uff08ServiceAccount Authorization\uff09 \u00b6 \u5728 Kubernetes 1.23 \u53ca\u66f4\u4f4e\u7248\u672c\u4e2d\uff0c\u5f53\u6211\u4eec\u521b\u5efa\u4e00\u4e2a\u65b0\u7684\u547d\u540d\u7a7a\u95f4\u65f6\uff0cKubernetes \u4f1a\u81ea\u52a8\u521b\u5efa\u4e00\u4e2a\u540d\u4e3a default \u7684 ServiceAccount \u548c\u4e00\u4e2a\u540d\u4e3a default-token-xxxxx \u7684\u4ee4\u724c\u3002 \u800c\u5728 Kubernetes 1.24 \u4e2d\uff0c\u521b\u5efa\u65b0\u7684\u547d\u540d\u7a7a\u95f4\u65f6\u4ec5\u4f1a\u81ea\u52a8\u521b\u5efa\u4e00\u4e2a\u540d\u4e3a default \u7684 ServiceAccount\uff0c\u9700\u8981\u624b\u52a8\u521b\u5efa\u4e0e default ServiceAccount \u76f8\u5173\u8054\u7684\u4ee4\u724c\u3002 \u4ee5\u4e0b\u662f\u521b\u5efa\u4e00\u4e2a\u540d\u4e3a dev \u7684\u65b0\u547d\u540d\u7a7a\u95f4\u7684\u793a\u4f8b\uff0c\u6211\u4eec\u53ef\u4ee5\u770b\u5230\u5728\u547d\u540d\u7a7a\u95f4 dev \u4e2d\u4ec5\u521b\u5efa\u4e86 ServiceAccount\uff1a default \uff0c\u6ca1\u6709\u4e0e ServiceAccount default \u76f8\u5173\u8054\u7684\u4ee4\u724c\uff08secret\uff09\u3002 kubectl create namespace dev kubectl get serviceaccount -n dev kubectl get secrets -n dev \u6709\u4e00\u4e2a\u9ed8\u8ba4\u7684\u96c6\u7fa4\u89d2\u8272 admin \uff0c\u4f46\u662f\u6ca1\u6709\u5c06\u5176\u7ed1\u5b9a\u5230\u4efb\u4f55\u96c6\u7fa4\u89d2\u8272\u7ed1\u5b9a\uff08clusterrole binding\uff09\u4e2d\u3002 kubectl get clusterrole admin kubectl get clusterrolebinding | grep ClusterRole/admin \u89d2\u8272Role\u548c\u89d2\u8272\u7ed1\u5b9aRoleBinding\u662f\u57fa\u4e8e\u547d\u540d\u7a7a\u95f4\u7684\u3002\u5728\u547d\u540d\u7a7a\u95f4 dev \u4e2d\uff0c\u6ca1\u6709\u89d2\u8272\u548c\u89d2\u8272\u7ed1\u5b9a\u3002 kubectl get role -n dev kubectl get rolebinding -n dev \u5728 Kubernetes \u96c6\u7fa4\u4e2d\uff0cSecret \u662f\u4e00\u4e2a\u5bf9\u8c61\uff0c\u7528\u4e8e\u5b58\u50a8\u654f\u611f\u4fe1\u606f\uff0c\u5982\u7528\u6237\u540d\u3001\u5bc6\u7801\u548c\u4ee4\u724c\u7b49\u3002Secret \u7684\u76ee\u6807\u662f\u5bf9\u51ed\u636e\u8fdb\u884c\u7f16\u7801\u6216\u54c8\u5e0c\u5316\u3002\u8fd9\u4e9b\u51ed\u636e\u53ef\u4ee5\u5728\u5404\u79cd Pod \u5b9a\u4e49\u6587\u4ef6\u4e2d\u91cd\u590d\u4f7f\u7528\u3002 kubernetes.io/service-account-token \u7c7b\u578b\u7684 Secret \u7528\u4e8e\u5b58\u50a8\u6807\u8bc6\u670d\u52a1\u8d26\u6237\u7684\u4ee4\u724c\u3002\u4f7f\u7528\u6b64\u7c7b\u578b\u7684 Secret \u65f6\uff0c\u9700\u8981\u786e\u4fdd kubernetes.io/service-account.name \u6ce8\u91ca\u8bbe\u7f6e\u4e3a\u73b0\u6709\u670d\u52a1\u8d26\u6237\u540d\u79f0\u3002 \u8ba9\u6211\u4eec\u5728 dev \u547d\u540d\u7a7a\u95f4\u4e2d\u4e3a ServiceAccount default \u521b\u5efa\u4e00\u4e2a\u4ee4\u724c\u3002 kubectl apply -f - << EOF apiVersion: v1 kind: Secret metadata: name: default-token-dev namespace: dev annotations: kubernetes.io/service-account.name: \"default\" type: kubernetes.io/service-account-token EOF \u73b0\u5728\u5728 dev \u547d\u540d\u7a7a\u95f4\u4e2d\u521b\u5efa\u4e86 ServiceAccount default \u548c Secret\uff08\u4ee4\u724c\uff09 default-token-dev \u3002 kubectl get serviceaccount -n dev kubectl get secrets -n dev \u83b7\u53d6\u9ed8\u8ba4 Service Account \u7684 token\uff0c\u5e76\u8d4b\u503c\u7ed9\u73af\u5883\u53d8\u91cf $TOKEN \u3002 TOKEN = $( kubectl -n dev describe secret $( kubectl -n dev get secrets | grep default | cut -f1 -d ' ' ) | grep -E '^token' | cut -f2 -d ':' | tr -d ' ' ) echo $TOKEN \u83b7\u53d6 API Service \u5730\u5740\uff0c\u5e76\u8d4b\u503c\u7ed9\u73af\u5883\u53d8\u91cf $APISERVER \u3002 APISERVER = $( kubectl config view | grep https | cut -f 2 - -d \":\" | tr -d \" \" ) echo $APISERVER \u901a\u8fc7 API Server \u4ee5 JSON \u683c\u5f0f\u83b7\u53d6\u547d\u540d\u7a7a\u95f4 dev \u4e2d\u7684 Pod \u8d44\u6e90\u3002 curl $APISERVER /api/v1/namespaces/dev/pods --header \"Authorization: Bearer $TOKEN \" --insecure \u6211\u4eec\u5c06\u6536\u5230\u201c403 forbidden\u201d\u7684\u9519\u8bef\u6d88\u606f\u3002ServiceAccount default \u6ca1\u6709\u8bbf\u95ee\u540d\u79f0\u7a7a\u95f4 dev \u4e2d\u7684Pod\u7684\u6388\u6743\u3002 \u8ba9\u6211\u4eec\u521b\u5efa\u4e00\u4e2a\u540d\u4e3a rolebinding-admin \u7684RoleBinding\uff0c\u5c06\u96c6\u7fa4\u89d2\u8272 admin \u7ed1\u5b9a\u5230\u540d\u79f0\u7a7a\u95f4 dev \u4e2d\u7684ServiceAccount default \u3002 \u56e0\u6b64\uff0cServiceAccount default \u88ab\u6388\u4e88\u5728\u540d\u79f0\u7a7a\u95f4 dev \u4e2d\u7684\u7ba1\u7406\u5458\u6388\u6743\u3002 # Usage: kubectl create rolebinding --clusterrole = --serviceaccount = : --namespace = # Crate rolebinding: kubectl create rolebinding rolebinding-admin --clusterrole = admin --serviceaccount = dev:default --namespace = dev \u6267\u884c\u547d\u4ee4 kubectl get rolebinding -n dev \uff0c\u5f97\u5230\u7c7b\u4f3c\u5982\u4e0b\u7684\u7ed3\u679c\u3002 NAME ROLE AGE rolebinding-admin ClusterRole/admin 10s \u518d\u6b21\u901a\u8fc7 API Server \u4ee5 JSON \u683c\u5f0f\u83b7\u53d6\u547d\u540d\u7a7a\u95f4 dev \u4e2d\u7684 Pod \u8d44\u6e90\uff0c\u6210\u529f\u3002 curl $APISERVER /api/v1/namespaces/dev/pods --header \"Authorization: Bearer $TOKEN \" --insecure \u5220\u9664\u4e0a\u9762\u6f14\u793a\u4e2d\u521b\u5efa\u7684\u4e34\u65f6\u8d44\u6e90\u3002 kubectl delete namespace dev \u90e8\u7f72\uff08Deployment\uff09 \u00b6 \u521b\u5efa\u4e00\u4e2a Ubuntu Pod \u4ee5\u8fdb\u884c\u64cd\u4f5c\uff0c\u5e76\u9644\u52a0\u5230\u8fd0\u884c\u4e2d\u7684 Pod\u3002 kubectl create -f - << EOF apiVersion: v1 kind: Pod metadata: name: ubuntu labels: app: ubuntu spec: containers: - name: ubuntu image: ubuntu:latest command: [\"/bin/sleep\", \"3650d\"] imagePullPolicy: IfNotPresent restartPolicy: Always EOF kubectl exec --stdin --tty ubuntu -- /bin/bash \u521b\u5efa\u4e00\u4e2a Deployment\uff0c\u9009\u9879 --image \u6307\u5b9a\u4e86\u4e00\u4e2a\u955c\u50cf\uff0c\u9009\u9879 --port \u6307\u5b9a\u4e86\u5916\u90e8\u8bbf\u95ee\u7684\u7aef\u53e3\u3002 \u5728\u521b\u5efa Deployment \u7684\u540c\u65f6\u4e5f\u4f1a\u521b\u5efa\u4e00\u4e2a Pod\u3002 kubectl create deployment myapp --image = docker.io/jocatalin/kubernetes-bootcamp:v1 --replicas = 1 --port = 8080 \u67e5\u8be2deployment\u7684\u72b6\u6001\u3002 kubectl get deployment myapp -o wide \u8f93\u51fa\u7ed3\u679c\uff1a NAME READY UP-TO-DATE AVAILABLE AGE CONTAINERS IMAGES SELECTOR myapp 1/1 1 1 79s kubernetes-bootcamp docker.io/jocatalin/kubernetes-bootcamp:v1 app=myapp \u67e5\u8be2deployment\u7684\u8be6\u7ec6\u4fe1\u606f\u3002 kubectl describe deployment myapp \u8fd0\u884c\u7ed3\u679c\uff1a Name: myapp Namespace: dev CreationTimestamp: Sat, 23 Jul 2022 14:36:43 +0800 Labels: app=myapp Annotations: deployment.kubernetes.io/revision: 1 Selector: app=myapp Replicas: 1 desired | 1 updated | 1 total | 1 available | 0 unavailable StrategyType: RollingUpdate MinReadySeconds: 0 RollingUpdateStrategy: 25% max unavailable, 25% max surge Pod Template: Labels: app=myapp Containers: kubernetes-bootcamp: Image: docker.io/jocatalin/kubernetes-bootcamp:v1 Port: 8080/TCP Host Port: 0/TCP Environment: Mounts: Volumes: Conditions: Type Status Reason ---- ------ ------ Available True MinimumReplicasAvailable Progressing True NewReplicaSetAvailable OldReplicaSets: NewReplicaSet: myapp-b5d775f5d (1/1 replicas created) Events: Type Reason Age From Message ---- ------ ---- ---- ------- Normal ScalingReplicaSet 95s deployment-controller Scaled up replica set myapp-b5d775f5d to 1 \u66b4\u9732\u670d\u52a1\uff08Expose Service\uff09 \u00b6 \u83b7\u53d6\u4e0a\u9762\u7ec3\u4e60\u4e2d\u521b\u5efa\u7684pod\u548cdeployment\u7684\u4fe1\u606f\u3002 kubectl get deployment myapp -o wide kubectl get pod -o wide \u8fd0\u884c\u7ed3\u679c\uff1a NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES myapp-b5d775f5d-cx8dx 1/1 Running 0 2m34s 10.244.102.7 cka003 \u6267\u884c\u547d\u4ee4 curl 10.244.102.7:8080 \uff0c\u4ee5\u53d1\u9001HTTP\u8bf7\u6c42\u5230pod\u7684\u7aef\u53e3\uff0c\u5f97\u5230\u5982\u4e0b\u7ed3\u679c\u3002 Hello Kubernetes bootcamp! | Running on: myapp-b5d775f5d-6jtgs | v=1 \u8981\u4f7f Pod \u53ef\u4ee5\u4ece\u5916\u90e8\u8bbf\u95ee\uff0c\u9700\u8981\u5c06\u7aef\u53e3 8080 \u66b4\u9732\u7ed9\u8282\u70b9\u7aef\u53e3\uff08NodePort\uff09\u3002\u8fd9\u9700\u8981\u521b\u5efa\u4e00\u4e2a\u76f8\u5173\u7684 Service\u3002 kubectl expose deployment myapp --type = NodePort --port = 8080 \u6267\u884c\u547d\u4ee4 kubectl get svc myapp -o wide \uff0c\u83b7\u53d6service myapp \u7684\u8be6\u7ec6\u4fe1\u606f\u3002 NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE SELECTOR myapp NodePort 11.244.74.3 8080:30514/TCP 7s app=myapp \u6267\u884c\u547d\u4ee4 curl 11.244.74.3:8080 \uff0c\u4ee5\u53d1\u9001HTTP\u8bf7\u6c42\u5230service\u7684\u7aef\u53e3\uff0c\u5f97\u5230\u5982\u4e0b\u7ed3\u679c\u3002 Hello Kubernetes bootcamp! | Running on: myapp-b5d775f5d-cx8dx | v=1 \u83b7\u53d6service\u7684\u8be6\u7ec6\u4fe1\u606f\u3002 kubectl get svc myapp -o yaml kubectl describe svc myapp \u6267\u884c kubectl get endpoints myapp -o wide \u547d\u4ee4\u4ee5\u83b7\u53d6\u76f8\u5173\u7684 myapp \u7aef\u70b9\uff08endpoint\uff09\u7684\u8be6\u7ec6\u4fe1\u606f\u3002 NAME ENDPOINTS AGE myapp 10.244.102.7:8080 43s \u63d0\u793a\uff1a Endpoint\uff08\u7aef\u70b9\uff09\u662f\u4e00\u4e2aKubernetes\u4e2d\u7684\u5bf9\u8c61\uff0c\u7528\u4e8e\u5b58\u50a8\u53ef\u4ee5\u88ab\u670d\u52a1\u8bbf\u95ee\u7684Pod\u7684\u7f51\u7edc\u5730\u5740\u548c\u7aef\u53e3\u4fe1\u606f\u3002 \u5f53Service\u521b\u5efa\u65f6\uff0cKubernetes\u4f1a\u81ea\u52a8\u521b\u5efa\u548c\u66f4\u65b0\u76f8\u5e94\u7684Endpoint\u3002 Endpoint\u662f\u7531kube-proxy\u81ea\u52a8\u521b\u5efa\u548c\u7ef4\u62a4\u7684\uff0c\u5e76\u6839\u636e\u9009\u62e9\u5668\u5339\u914d\u5bf9\u5e94\u7684Service\u548cPod\u3002 \u80fd\u6210\u529f\u7684\u53d1\u9001HTTP\u8bf7\u6c42\u5230service\u548c\u8282\u70b9\uff0c\u8bf4\u660epod\u7684\u7aef\u53e3 8080 \u88ab\u6b63\u786e\u7684\u6620\u5c04\u5230\u8282\u70b9\u7684\u7aef\u53e3 32566 \u3002 \u6267\u884c\u547d\u4ee4curl :30514\uff0c\u53d1\u9001HTTP\u8bf7\u6c42\u5230\u8282\u70b9 cka003 \u4e0a\u5bf9\u5e94\u7684\u7aef\u53e3\u3002 Hello Kubernetes bootcamp! | Running on: myapp-b5d775f5d-6jtgs | v=1 \u767b\u5f55\u8fdb\u5165Ubuntu pod\uff0c\u6211\u4eec\u53ef\u4ee5\u901a\u8fc7\u53d1\u9001HTTP\u8bf7\u6c42\u5230 myapp \u6240\u6620\u5c04\u7684service\u3001pod\u548c\u8282\u70b9\u7684\u7aef\u53e3\u3002 kubectl exec --stdin --tty ubuntu -- /bin/bash curl 10 .244.102.7:8080 curl 11 .244.74.3:8080 curl :30514 Hello Kubernetes bootcamp! | Running on: myapp-b5d775f5d-6jtgs | v = 1 \u6269\u5bb9\u90e8\u7f72\uff08Scale out the Deployment\uff09 \u00b6 Scale out by replicaset. We set three replicasets to scale out deployment myapp . The number of deployment myapp is now three. \u901a\u8fc7\u526f\u672c\u96c6replicaset\u8fdb\u884c\u6269\u5c55\u3002\u6211\u4eec\u901a\u8fc7\u6307\u5b9a\u526f\u672c\u96c6\u7684\u65b9\u5f0f\uff0c\u5bf9deployment myapp \u8fdb\u884c\u6269\u5c55\u90e8\u7f72\uff0c\u4e0b\u9762\u4f8b\u5b50\u4e2d\uff0cdeployment myapp \u7684\u526f\u672c\u6570\u662f\u4e09\u4e2a\u3002 kubectl scale deployment myapp --replicas = 3 \u67e5\u8be2deployment\u7684\u4fe1\u606f\u3002 kubectl get deployment myapp \u67e5\u8be2replicaset\u7684\u4fe1\u606f kubectl get replicaset \u6eda\u52a8\u5347\u7ea7\uff08Rolling update\uff09 \u00b6 \u547d\u4ee4\u7528\u6cd5\uff1a kubectl set image (-f \u6587\u4ef6\u540d | \u7c7b\u578b \u540d\u79f0) \u5bb9\u5668\u540d\u79f0_1=\u5bb9\u5668\u955c\u50cf_1 ... \u5bb9\u5668\u540d\u79f0_N=\u5bb9\u5668\u955c\u50cf_N \u3002 \u4f7f\u7528\u547d\u4ee4 kubectl get deployment \uff0c\u6211\u4eec\u53ef\u4ee5\u83b7\u53d6deployment myapp \u548c\u76f8\u5173\u5bb9\u5668 kubernetes-bootcamp \u3002 kubectl get deployment myapp -o wide \u4f7f\u7528\u547d\u4ee4 kubectl set image \u6765\u66f4\u65b0\u591a\u4e2a\u7248\u672c\u7684\u955c\u50cf\uff0c\u5e76\u4f7f\u7528\u9009\u9879 --record \u5c06\u66f4\u6539\u8bb0\u5f55\u5728\u90e8\u7f72\u7684\u6ce8\u91ca\u4e2d\u3002 kubectl set image deployment/myapp kubernetes-bootcamp = docker.io/jocatalin/kubernetes-bootcamp:v2 --record \u67e5\u8be2\u5f53\u524dreplicas\u7684\u72b6\u6001\u3002 kubectl get replicaset -o wide -l app = myapp \u8f93\u51fa\u7ed3\u679c\u5982\u4e0b\uff0cpod\u6b63\u4ee5\u65b0\u7684\u526f\u672c\u96c6replicas\u6570\u91cf\u8fd0\u884c\u3002 NAME DESIRED CURRENT READY AGE CONTAINERS IMAGES SELECTOR myapp-5dbd68cc99 1 1 0 8s kubernetes-bootcamp docker.io/jocatalin/kubernetes-bootcamp:v2 app=myapp,pod-template-hash=5dbd68cc99 myapp-b5d775f5d 3 3 3 14m kubernetes-bootcamp docker.io/jocatalin/kubernetes-bootcamp:v1 app=myapp,pod-template-hash=b5d775f5d \u6211\u4eec\u53ef\u4ee5\u5728\u5bf9\u5e94\u7684yaml\u6587\u4ef6\u4e2d metadata.annotations \u90e8\u5206\u83b7\u53d6\u53d8\u66f4\u5386\u53f2\u8bb0\u5f55\u3002 kubectl get deployment myapp -o yaml \u8fd0\u884c\u7ed3\u679c\uff1a apiVersion : apps/v1 kind : Deployment metadata : annotations : deployment.kubernetes.io/revision : \"2\" kubernetes.io/change-cause : kubectl set image deployment/myapp kubernetes-bootcamp=docker.io/jocatalin/kubernetes-bootcamp:v2 --record=true ...... \u6211\u4eec\u4e5f\u53ef\u4ee5\u4f7f\u7528\u547d\u4ee4 kubectl rollout history \u83b7\u53d6\u66f4\u65b0\u5386\u53f2\u8bb0\u5f55\uff0c\u5e76\u4f7f\u7528\u7279\u5b9a\u4fee\u8ba2\u7248\u672c\u53f7 --revision= \u663e\u793a\u8be6\u7ec6\u4fe1\u606f\u3002 kubectl rollout history deployment/myapp \u8fd0\u884c\u7ed3\u679c\uff1a deployment.apps/myapp REVISION CHANGE-CAUSE 1 2 kubectl set image deployment/myapp kubernetes-bootcamp=docker.io/jocatalin/kubernetes-bootcamp:v2 --record=true \u83b7\u53d6\u7279\u5b9a\u7248\u672c\u56de\u6eda\u5386\u53f2\u8bb0\u5f55\u3002 kubectl rollout history deployment/myapp --revision = 2 \u6267\u884c\u547d\u4ee4 kubectl rollout undo \u53ef\u4ee5\u56de\u6eda\u5230\u4e0a\u4e00\u4e2a\u7248\u672c\uff0c\u6216\u4f7f\u7528\u9009\u9879 --to-revision= \u56de\u6eda\u5230\u6307\u5b9a\u7684\u7248\u672c\u3002 kubectl rollout undo deployment/myapp --to-revision = 1 \u7248\u672c 1 \u73b0\u5728\u5df2\u7ecf\u88ab\u66ff\u6362\u6210\u7248\u672c 3 \u4e86\u3002 kubectl rollout history deployment/myapp \u8fd0\u884c\u7ed3\u679c\uff1a deployment.apps/myapp REVISION CHANGE-CAUSE 2 kubectl set image deployment/myapp kubernetes-bootcamp=docker.io/jocatalin/kubernetes-bootcamp:v2 --record=true 3 \u4e8b\u4ef6\uff08Event\uff09 \u00b6 \u83b7\u53d6\u6307\u5b9apod\u7684\u4e8b\u4ef6\u4fe1\u606f\u3002 kubectl describe pod myapp-b5d775f5d-jlx6g \u8f93\u51fa\u7ed3\u679c\uff1a ...... Events: Type Reason Age From Message ---- ------ ---- ---- ------- Normal Scheduled 54s default-scheduler Successfully assigned dev/myapp-b5d775f5d-jlx6g to cka003 Normal Pulled 53s kubelet Container image \"docker.io/jocatalin/kubernetes-bootcamp:v1\" already present on machine Normal Created 53s kubelet Created container kubernetes-bootcamp Normal Started 53s kubelet Started container kubernetes-bootcamp \u67e5\u8be2\u96c6\u7fa4\u7684\u4e8b\u4ef6\u4fe1\u606f\u3002 kubectl get event \u65e5\u5fd7\u8bb0\u5f55\uff08Logging\uff09 \u00b6 \u67e5\u8be2pod\u7684\u65e5\u5fd7\u4fe1\u606f\u3002 kubectl logs -f kubectl logs -f -c \u4f8b\u5982\uff1a kubectl logs -f myapp-b5d775f5d-jlx6g \u8fd0\u884c\u7ed3\u679c\uff1a Kubernetes Bootcamp App Started At: 2022-07-23T06:54:18.532Z | Running On: myapp-b5d775f5d-jlx6g \u67e5\u8be2K8s\u4e0d\u540c\u7ec4\u4ef6\u7684\u65e5\u5fd7\u4fe1\u606f\u3002 kubectl logs kube-apiserver-cka001 -n kube-system kubectl logs kube-controller-manager-cka001 -n kube-system kubectl logs kube-scheduler-cka001 -n kube-system kubectl logs etcd-cka001 -n kube-system systemctl status kubelet journalctl -fu kubelet kubectl logs kube-proxy-5cdbj -n kube-system \u5220\u9664\u6f14\u793a\u4e2d\u521b\u5efa\u7684\u4e34\u65f6\u8d44\u6e90\u3002 kubectl delete service myapp kubectl delete deployment myapp","title":"Kubernetes\u8d44\u6e90\u5e38\u89c1\u64cd\u4f5c"},{"location":"k8s/cka_cn/foundamentals/casestudy-operation-resources/#kubernetes","text":"\u6f14\u793a\u573a\u666f\uff1a \u8282\u70b9\u6807\u7b7e\uff08Node Label\uff09 \u6ce8\u89e3\uff08Annotation\uff09 \u547d\u540d\u7a7a\u95f4\uff08Namespace\uff09 ServiceAccount \u6388\u6743\uff08ServiceAccount Authorization\uff09 \u6388\u6743\u9ed8\u8ba4 ServiceAccount \u8bbf\u95ee API \u90e8\u7f72\uff08Deployment\uff09 \u66b4\u9732\u670d\u52a1\uff08Expose Service\uff09 \u6269\u5c55\u90e8\u7f72\uff08Scale out the Deployment\uff09 \u6eda\u52a8\u5347\u7ea7\uff08Rolling update\uff09 \u56de\u6eda\u5347\u7ea7\uff08Rolling back update\uff09 \u4e8b\u4ef6\uff08Event\uff09 \u65e5\u5fd7\u8bb0\u5f55\uff08Logging\uff09","title":"\u4e3b\u9898\u8ba8\u8bba:Kubernetes\u8d44\u6e90\u5e38\u89c1\u64cd\u4f5c"},{"location":"k8s/cka_cn/foundamentals/casestudy-operation-resources/#node-label","text":"\u6dfb\u52a0/\u4fee\u6539/\u79fb\u51fa\u8282\u70b9\u6807\u7b7e\u3002 # Update node label kubectl label node cka002 node = demonode # Get node info with label info kubectl get node --show-labels # Search node by label kubectl get node -l node = demonode # Remove a lable of node kubectl label node cka002 node-","title":"\u8282\u70b9\u6807\u7b7e\uff08Node Label\uff09"},{"location":"k8s/cka_cn/foundamentals/casestudy-operation-resources/#annotation","text":"\u521b\u5efadeployment Nginx \u3002 kubectl create deploy nginx --image = nginx:mainline \u83b7\u53d6\u6ce8\u89e3\u4fe1\u606f kubectl describe deployment/nginx \u8fd0\u884c\u7ed3\u679c\uff1a ...... Labels : app=nginx Annotations : deployment.kubernetes.io/revision : 1 Selector : app=nginx ...... \u6dfb\u52a0\u65b0\u7684\u6ce8\u89e3\u4fe1\u606f\u3002 kubectl annotate deployment nginx owner = James.H \u518d\u6b21\u67e5\u8be2\u6ce8\u89e3\u4fe1\u606f\u5f97\u5230\u5982\u4e0b\u7ed3\u679c\u3002 ...... Labels : app=nginx Annotations : deployment.kubernetes.io/revision : 1 owner : James.H Selector : app=nginx ...... \u66f4\u65b0/\u8986\u76d6\u6ce8\u89e3\u4fe1\u606f\u3002 kubectl annotate deployment/nginx owner = K8s --overwrite \u518d\u6b21\u67e5\u8be2\u6ce8\u89e3\u4fe1\u606f\u5f97\u5230\u5982\u4e0b\u7ed3\u679c\u3002 ...... Annotations : deployment.kubernetes.io/revision : 1 owner : K8s Selector : app=nginx ...... \u79fb\u9664\u6ce8\u89e3\u4fe1\u606f\u3002 kubectl annotate deployment/nginx owner- \u8fd0\u884c\u7ed3\u679c\uff1a ...... Labels : app=nginx Annotations : deployment.kubernetes.io/revision : 1 Selector : app=nginx ...... \u5220\u9664\u4e0a\u9762\u6f14\u793a\u4e2d\u521b\u5efa\u7684\u4e34\u65f6\u8d44\u6e90\u3002 kubectl delete deployment nginx","title":"\u6ce8\u89e3\uff08Annotation\uff09"},{"location":"k8s/cka_cn/foundamentals/casestudy-operation-resources/#namespace","text":"\u67e5\u8be2\u5f53\u524d\u53ef\u7528namespace\u3002 kubectl get namespace \u8fd0\u884c\u7ed3\u679c\uff1a NAME STATUS AGE default Active 3h45m dev Active 3h11m kube-node-lease Active 3h45m kube-public Active 3h45m kube-system Active 3h45m \u67e5\u8be2\u67d0\u4e2anamespace\u4e0a\u8fd0\u884c\u7684pod\u4fe1\u606f\u3002 kubectl get pod -n kube-system \u8fd0\u884c\u7ed3\u679c\uff1a NAME READY STATUS RESTARTS AGE calico-kube-controllers-5c64b68895-jr4nl 1/1 Running 0 3h25m calico-node-dsx76 1/1 Running 0 3h25m calico-node-p5rf2 1/1 Running 0 3h25m calico-node-tr22l 1/1 Running 0 3h25m coredns-6d8c4cb4d-g4jxc 1/1 Running 0 3h45m coredns-6d8c4cb4d-sqcvj 1/1 Running 0 3h45m etcd-cka001 1/1 Running 0 3h45m kube-apiserver-cka001 1/1 Running 0 3h45m kube-controller-manager-cka001 1/1 Running 0 3h45m kube-proxy-5cdbj 1/1 Running 0 3h41m kube-proxy-cm4hc 1/1 Running 0 3h45m kube-proxy-g4w52 1/1 Running 0 3h41m kube-scheduler-cka001 1/1 Running 0 3h45m \u67e5\u8be2\u6240\u6709namespace\u4e0a\u7684pod\u4fe1\u606f\u3002 kubectl get pod --all-namespaces kubectl get pod -A","title":"\u547d\u540d\u7a7a\u95f4\uff08Namespace\uff09"},{"location":"k8s/cka_cn/foundamentals/casestudy-operation-resources/#serviceaccount-serviceaccount-authorization","text":"\u5728 Kubernetes 1.23 \u53ca\u66f4\u4f4e\u7248\u672c\u4e2d\uff0c\u5f53\u6211\u4eec\u521b\u5efa\u4e00\u4e2a\u65b0\u7684\u547d\u540d\u7a7a\u95f4\u65f6\uff0cKubernetes \u4f1a\u81ea\u52a8\u521b\u5efa\u4e00\u4e2a\u540d\u4e3a default \u7684 ServiceAccount \u548c\u4e00\u4e2a\u540d\u4e3a default-token-xxxxx \u7684\u4ee4\u724c\u3002 \u800c\u5728 Kubernetes 1.24 \u4e2d\uff0c\u521b\u5efa\u65b0\u7684\u547d\u540d\u7a7a\u95f4\u65f6\u4ec5\u4f1a\u81ea\u52a8\u521b\u5efa\u4e00\u4e2a\u540d\u4e3a default \u7684 ServiceAccount\uff0c\u9700\u8981\u624b\u52a8\u521b\u5efa\u4e0e default ServiceAccount \u76f8\u5173\u8054\u7684\u4ee4\u724c\u3002 \u4ee5\u4e0b\u662f\u521b\u5efa\u4e00\u4e2a\u540d\u4e3a dev \u7684\u65b0\u547d\u540d\u7a7a\u95f4\u7684\u793a\u4f8b\uff0c\u6211\u4eec\u53ef\u4ee5\u770b\u5230\u5728\u547d\u540d\u7a7a\u95f4 dev \u4e2d\u4ec5\u521b\u5efa\u4e86 ServiceAccount\uff1a default \uff0c\u6ca1\u6709\u4e0e ServiceAccount default \u76f8\u5173\u8054\u7684\u4ee4\u724c\uff08secret\uff09\u3002 kubectl create namespace dev kubectl get serviceaccount -n dev kubectl get secrets -n dev \u6709\u4e00\u4e2a\u9ed8\u8ba4\u7684\u96c6\u7fa4\u89d2\u8272 admin \uff0c\u4f46\u662f\u6ca1\u6709\u5c06\u5176\u7ed1\u5b9a\u5230\u4efb\u4f55\u96c6\u7fa4\u89d2\u8272\u7ed1\u5b9a\uff08clusterrole binding\uff09\u4e2d\u3002 kubectl get clusterrole admin kubectl get clusterrolebinding | grep ClusterRole/admin \u89d2\u8272Role\u548c\u89d2\u8272\u7ed1\u5b9aRoleBinding\u662f\u57fa\u4e8e\u547d\u540d\u7a7a\u95f4\u7684\u3002\u5728\u547d\u540d\u7a7a\u95f4 dev \u4e2d\uff0c\u6ca1\u6709\u89d2\u8272\u548c\u89d2\u8272\u7ed1\u5b9a\u3002 kubectl get role -n dev kubectl get rolebinding -n dev \u5728 Kubernetes \u96c6\u7fa4\u4e2d\uff0cSecret \u662f\u4e00\u4e2a\u5bf9\u8c61\uff0c\u7528\u4e8e\u5b58\u50a8\u654f\u611f\u4fe1\u606f\uff0c\u5982\u7528\u6237\u540d\u3001\u5bc6\u7801\u548c\u4ee4\u724c\u7b49\u3002Secret \u7684\u76ee\u6807\u662f\u5bf9\u51ed\u636e\u8fdb\u884c\u7f16\u7801\u6216\u54c8\u5e0c\u5316\u3002\u8fd9\u4e9b\u51ed\u636e\u53ef\u4ee5\u5728\u5404\u79cd Pod \u5b9a\u4e49\u6587\u4ef6\u4e2d\u91cd\u590d\u4f7f\u7528\u3002 kubernetes.io/service-account-token \u7c7b\u578b\u7684 Secret \u7528\u4e8e\u5b58\u50a8\u6807\u8bc6\u670d\u52a1\u8d26\u6237\u7684\u4ee4\u724c\u3002\u4f7f\u7528\u6b64\u7c7b\u578b\u7684 Secret \u65f6\uff0c\u9700\u8981\u786e\u4fdd kubernetes.io/service-account.name \u6ce8\u91ca\u8bbe\u7f6e\u4e3a\u73b0\u6709\u670d\u52a1\u8d26\u6237\u540d\u79f0\u3002 \u8ba9\u6211\u4eec\u5728 dev \u547d\u540d\u7a7a\u95f4\u4e2d\u4e3a ServiceAccount default \u521b\u5efa\u4e00\u4e2a\u4ee4\u724c\u3002 kubectl apply -f - << EOF apiVersion: v1 kind: Secret metadata: name: default-token-dev namespace: dev annotations: kubernetes.io/service-account.name: \"default\" type: kubernetes.io/service-account-token EOF \u73b0\u5728\u5728 dev \u547d\u540d\u7a7a\u95f4\u4e2d\u521b\u5efa\u4e86 ServiceAccount default \u548c Secret\uff08\u4ee4\u724c\uff09 default-token-dev \u3002 kubectl get serviceaccount -n dev kubectl get secrets -n dev \u83b7\u53d6\u9ed8\u8ba4 Service Account \u7684 token\uff0c\u5e76\u8d4b\u503c\u7ed9\u73af\u5883\u53d8\u91cf $TOKEN \u3002 TOKEN = $( kubectl -n dev describe secret $( kubectl -n dev get secrets | grep default | cut -f1 -d ' ' ) | grep -E '^token' | cut -f2 -d ':' | tr -d ' ' ) echo $TOKEN \u83b7\u53d6 API Service \u5730\u5740\uff0c\u5e76\u8d4b\u503c\u7ed9\u73af\u5883\u53d8\u91cf $APISERVER \u3002 APISERVER = $( kubectl config view | grep https | cut -f 2 - -d \":\" | tr -d \" \" ) echo $APISERVER \u901a\u8fc7 API Server \u4ee5 JSON \u683c\u5f0f\u83b7\u53d6\u547d\u540d\u7a7a\u95f4 dev \u4e2d\u7684 Pod \u8d44\u6e90\u3002 curl $APISERVER /api/v1/namespaces/dev/pods --header \"Authorization: Bearer $TOKEN \" --insecure \u6211\u4eec\u5c06\u6536\u5230\u201c403 forbidden\u201d\u7684\u9519\u8bef\u6d88\u606f\u3002ServiceAccount default \u6ca1\u6709\u8bbf\u95ee\u540d\u79f0\u7a7a\u95f4 dev \u4e2d\u7684Pod\u7684\u6388\u6743\u3002 \u8ba9\u6211\u4eec\u521b\u5efa\u4e00\u4e2a\u540d\u4e3a rolebinding-admin \u7684RoleBinding\uff0c\u5c06\u96c6\u7fa4\u89d2\u8272 admin \u7ed1\u5b9a\u5230\u540d\u79f0\u7a7a\u95f4 dev \u4e2d\u7684ServiceAccount default \u3002 \u56e0\u6b64\uff0cServiceAccount default \u88ab\u6388\u4e88\u5728\u540d\u79f0\u7a7a\u95f4 dev \u4e2d\u7684\u7ba1\u7406\u5458\u6388\u6743\u3002 # Usage: kubectl create rolebinding --clusterrole = --serviceaccount = : --namespace = # Crate rolebinding: kubectl create rolebinding rolebinding-admin --clusterrole = admin --serviceaccount = dev:default --namespace = dev \u6267\u884c\u547d\u4ee4 kubectl get rolebinding -n dev \uff0c\u5f97\u5230\u7c7b\u4f3c\u5982\u4e0b\u7684\u7ed3\u679c\u3002 NAME ROLE AGE rolebinding-admin ClusterRole/admin 10s \u518d\u6b21\u901a\u8fc7 API Server \u4ee5 JSON \u683c\u5f0f\u83b7\u53d6\u547d\u540d\u7a7a\u95f4 dev \u4e2d\u7684 Pod \u8d44\u6e90\uff0c\u6210\u529f\u3002 curl $APISERVER /api/v1/namespaces/dev/pods --header \"Authorization: Bearer $TOKEN \" --insecure \u5220\u9664\u4e0a\u9762\u6f14\u793a\u4e2d\u521b\u5efa\u7684\u4e34\u65f6\u8d44\u6e90\u3002 kubectl delete namespace dev","title":"ServiceAccount \u6388\u6743\uff08ServiceAccount Authorization\uff09"},{"location":"k8s/cka_cn/foundamentals/casestudy-operation-resources/#deployment","text":"\u521b\u5efa\u4e00\u4e2a Ubuntu Pod \u4ee5\u8fdb\u884c\u64cd\u4f5c\uff0c\u5e76\u9644\u52a0\u5230\u8fd0\u884c\u4e2d\u7684 Pod\u3002 kubectl create -f - << EOF apiVersion: v1 kind: Pod metadata: name: ubuntu labels: app: ubuntu spec: containers: - name: ubuntu image: ubuntu:latest command: [\"/bin/sleep\", \"3650d\"] imagePullPolicy: IfNotPresent restartPolicy: Always EOF kubectl exec --stdin --tty ubuntu -- /bin/bash \u521b\u5efa\u4e00\u4e2a Deployment\uff0c\u9009\u9879 --image \u6307\u5b9a\u4e86\u4e00\u4e2a\u955c\u50cf\uff0c\u9009\u9879 --port \u6307\u5b9a\u4e86\u5916\u90e8\u8bbf\u95ee\u7684\u7aef\u53e3\u3002 \u5728\u521b\u5efa Deployment \u7684\u540c\u65f6\u4e5f\u4f1a\u521b\u5efa\u4e00\u4e2a Pod\u3002 kubectl create deployment myapp --image = docker.io/jocatalin/kubernetes-bootcamp:v1 --replicas = 1 --port = 8080 \u67e5\u8be2deployment\u7684\u72b6\u6001\u3002 kubectl get deployment myapp -o wide \u8f93\u51fa\u7ed3\u679c\uff1a NAME READY UP-TO-DATE AVAILABLE AGE CONTAINERS IMAGES SELECTOR myapp 1/1 1 1 79s kubernetes-bootcamp docker.io/jocatalin/kubernetes-bootcamp:v1 app=myapp \u67e5\u8be2deployment\u7684\u8be6\u7ec6\u4fe1\u606f\u3002 kubectl describe deployment myapp \u8fd0\u884c\u7ed3\u679c\uff1a Name: myapp Namespace: dev CreationTimestamp: Sat, 23 Jul 2022 14:36:43 +0800 Labels: app=myapp Annotations: deployment.kubernetes.io/revision: 1 Selector: app=myapp Replicas: 1 desired | 1 updated | 1 total | 1 available | 0 unavailable StrategyType: RollingUpdate MinReadySeconds: 0 RollingUpdateStrategy: 25% max unavailable, 25% max surge Pod Template: Labels: app=myapp Containers: kubernetes-bootcamp: Image: docker.io/jocatalin/kubernetes-bootcamp:v1 Port: 8080/TCP Host Port: 0/TCP Environment: Mounts: Volumes: Conditions: Type Status Reason ---- ------ ------ Available True MinimumReplicasAvailable Progressing True NewReplicaSetAvailable OldReplicaSets: NewReplicaSet: myapp-b5d775f5d (1/1 replicas created) Events: Type Reason Age From Message ---- ------ ---- ---- ------- Normal ScalingReplicaSet 95s deployment-controller Scaled up replica set myapp-b5d775f5d to 1","title":"\u90e8\u7f72\uff08Deployment\uff09"},{"location":"k8s/cka_cn/foundamentals/casestudy-operation-resources/#expose-service","text":"\u83b7\u53d6\u4e0a\u9762\u7ec3\u4e60\u4e2d\u521b\u5efa\u7684pod\u548cdeployment\u7684\u4fe1\u606f\u3002 kubectl get deployment myapp -o wide kubectl get pod -o wide \u8fd0\u884c\u7ed3\u679c\uff1a NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES myapp-b5d775f5d-cx8dx 1/1 Running 0 2m34s 10.244.102.7 cka003 \u6267\u884c\u547d\u4ee4 curl 10.244.102.7:8080 \uff0c\u4ee5\u53d1\u9001HTTP\u8bf7\u6c42\u5230pod\u7684\u7aef\u53e3\uff0c\u5f97\u5230\u5982\u4e0b\u7ed3\u679c\u3002 Hello Kubernetes bootcamp! | Running on: myapp-b5d775f5d-6jtgs | v=1 \u8981\u4f7f Pod \u53ef\u4ee5\u4ece\u5916\u90e8\u8bbf\u95ee\uff0c\u9700\u8981\u5c06\u7aef\u53e3 8080 \u66b4\u9732\u7ed9\u8282\u70b9\u7aef\u53e3\uff08NodePort\uff09\u3002\u8fd9\u9700\u8981\u521b\u5efa\u4e00\u4e2a\u76f8\u5173\u7684 Service\u3002 kubectl expose deployment myapp --type = NodePort --port = 8080 \u6267\u884c\u547d\u4ee4 kubectl get svc myapp -o wide \uff0c\u83b7\u53d6service myapp \u7684\u8be6\u7ec6\u4fe1\u606f\u3002 NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE SELECTOR myapp NodePort 11.244.74.3 8080:30514/TCP 7s app=myapp \u6267\u884c\u547d\u4ee4 curl 11.244.74.3:8080 \uff0c\u4ee5\u53d1\u9001HTTP\u8bf7\u6c42\u5230service\u7684\u7aef\u53e3\uff0c\u5f97\u5230\u5982\u4e0b\u7ed3\u679c\u3002 Hello Kubernetes bootcamp! | Running on: myapp-b5d775f5d-cx8dx | v=1 \u83b7\u53d6service\u7684\u8be6\u7ec6\u4fe1\u606f\u3002 kubectl get svc myapp -o yaml kubectl describe svc myapp \u6267\u884c kubectl get endpoints myapp -o wide \u547d\u4ee4\u4ee5\u83b7\u53d6\u76f8\u5173\u7684 myapp \u7aef\u70b9\uff08endpoint\uff09\u7684\u8be6\u7ec6\u4fe1\u606f\u3002 NAME ENDPOINTS AGE myapp 10.244.102.7:8080 43s \u63d0\u793a\uff1a Endpoint\uff08\u7aef\u70b9\uff09\u662f\u4e00\u4e2aKubernetes\u4e2d\u7684\u5bf9\u8c61\uff0c\u7528\u4e8e\u5b58\u50a8\u53ef\u4ee5\u88ab\u670d\u52a1\u8bbf\u95ee\u7684Pod\u7684\u7f51\u7edc\u5730\u5740\u548c\u7aef\u53e3\u4fe1\u606f\u3002 \u5f53Service\u521b\u5efa\u65f6\uff0cKubernetes\u4f1a\u81ea\u52a8\u521b\u5efa\u548c\u66f4\u65b0\u76f8\u5e94\u7684Endpoint\u3002 Endpoint\u662f\u7531kube-proxy\u81ea\u52a8\u521b\u5efa\u548c\u7ef4\u62a4\u7684\uff0c\u5e76\u6839\u636e\u9009\u62e9\u5668\u5339\u914d\u5bf9\u5e94\u7684Service\u548cPod\u3002 \u80fd\u6210\u529f\u7684\u53d1\u9001HTTP\u8bf7\u6c42\u5230service\u548c\u8282\u70b9\uff0c\u8bf4\u660epod\u7684\u7aef\u53e3 8080 \u88ab\u6b63\u786e\u7684\u6620\u5c04\u5230\u8282\u70b9\u7684\u7aef\u53e3 32566 \u3002 \u6267\u884c\u547d\u4ee4curl :30514\uff0c\u53d1\u9001HTTP\u8bf7\u6c42\u5230\u8282\u70b9 cka003 \u4e0a\u5bf9\u5e94\u7684\u7aef\u53e3\u3002 Hello Kubernetes bootcamp! | Running on: myapp-b5d775f5d-6jtgs | v=1 \u767b\u5f55\u8fdb\u5165Ubuntu pod\uff0c\u6211\u4eec\u53ef\u4ee5\u901a\u8fc7\u53d1\u9001HTTP\u8bf7\u6c42\u5230 myapp \u6240\u6620\u5c04\u7684service\u3001pod\u548c\u8282\u70b9\u7684\u7aef\u53e3\u3002 kubectl exec --stdin --tty ubuntu -- /bin/bash curl 10 .244.102.7:8080 curl 11 .244.74.3:8080 curl :30514 Hello Kubernetes bootcamp! | Running on: myapp-b5d775f5d-6jtgs | v = 1","title":"\u66b4\u9732\u670d\u52a1\uff08Expose Service\uff09"},{"location":"k8s/cka_cn/foundamentals/casestudy-operation-resources/#scale-out-the-deployment","text":"Scale out by replicaset. We set three replicasets to scale out deployment myapp . The number of deployment myapp is now three. \u901a\u8fc7\u526f\u672c\u96c6replicaset\u8fdb\u884c\u6269\u5c55\u3002\u6211\u4eec\u901a\u8fc7\u6307\u5b9a\u526f\u672c\u96c6\u7684\u65b9\u5f0f\uff0c\u5bf9deployment myapp \u8fdb\u884c\u6269\u5c55\u90e8\u7f72\uff0c\u4e0b\u9762\u4f8b\u5b50\u4e2d\uff0cdeployment myapp \u7684\u526f\u672c\u6570\u662f\u4e09\u4e2a\u3002 kubectl scale deployment myapp --replicas = 3 \u67e5\u8be2deployment\u7684\u4fe1\u606f\u3002 kubectl get deployment myapp \u67e5\u8be2replicaset\u7684\u4fe1\u606f kubectl get replicaset","title":"\u6269\u5bb9\u90e8\u7f72\uff08Scale out the Deployment\uff09"},{"location":"k8s/cka_cn/foundamentals/casestudy-operation-resources/#rolling-update","text":"\u547d\u4ee4\u7528\u6cd5\uff1a kubectl set image (-f \u6587\u4ef6\u540d | \u7c7b\u578b \u540d\u79f0) \u5bb9\u5668\u540d\u79f0_1=\u5bb9\u5668\u955c\u50cf_1 ... \u5bb9\u5668\u540d\u79f0_N=\u5bb9\u5668\u955c\u50cf_N \u3002 \u4f7f\u7528\u547d\u4ee4 kubectl get deployment \uff0c\u6211\u4eec\u53ef\u4ee5\u83b7\u53d6deployment myapp \u548c\u76f8\u5173\u5bb9\u5668 kubernetes-bootcamp \u3002 kubectl get deployment myapp -o wide \u4f7f\u7528\u547d\u4ee4 kubectl set image \u6765\u66f4\u65b0\u591a\u4e2a\u7248\u672c\u7684\u955c\u50cf\uff0c\u5e76\u4f7f\u7528\u9009\u9879 --record \u5c06\u66f4\u6539\u8bb0\u5f55\u5728\u90e8\u7f72\u7684\u6ce8\u91ca\u4e2d\u3002 kubectl set image deployment/myapp kubernetes-bootcamp = docker.io/jocatalin/kubernetes-bootcamp:v2 --record \u67e5\u8be2\u5f53\u524dreplicas\u7684\u72b6\u6001\u3002 kubectl get replicaset -o wide -l app = myapp \u8f93\u51fa\u7ed3\u679c\u5982\u4e0b\uff0cpod\u6b63\u4ee5\u65b0\u7684\u526f\u672c\u96c6replicas\u6570\u91cf\u8fd0\u884c\u3002 NAME DESIRED CURRENT READY AGE CONTAINERS IMAGES SELECTOR myapp-5dbd68cc99 1 1 0 8s kubernetes-bootcamp docker.io/jocatalin/kubernetes-bootcamp:v2 app=myapp,pod-template-hash=5dbd68cc99 myapp-b5d775f5d 3 3 3 14m kubernetes-bootcamp docker.io/jocatalin/kubernetes-bootcamp:v1 app=myapp,pod-template-hash=b5d775f5d \u6211\u4eec\u53ef\u4ee5\u5728\u5bf9\u5e94\u7684yaml\u6587\u4ef6\u4e2d metadata.annotations \u90e8\u5206\u83b7\u53d6\u53d8\u66f4\u5386\u53f2\u8bb0\u5f55\u3002 kubectl get deployment myapp -o yaml \u8fd0\u884c\u7ed3\u679c\uff1a apiVersion : apps/v1 kind : Deployment metadata : annotations : deployment.kubernetes.io/revision : \"2\" kubernetes.io/change-cause : kubectl set image deployment/myapp kubernetes-bootcamp=docker.io/jocatalin/kubernetes-bootcamp:v2 --record=true ...... \u6211\u4eec\u4e5f\u53ef\u4ee5\u4f7f\u7528\u547d\u4ee4 kubectl rollout history \u83b7\u53d6\u66f4\u65b0\u5386\u53f2\u8bb0\u5f55\uff0c\u5e76\u4f7f\u7528\u7279\u5b9a\u4fee\u8ba2\u7248\u672c\u53f7 --revision= \u663e\u793a\u8be6\u7ec6\u4fe1\u606f\u3002 kubectl rollout history deployment/myapp \u8fd0\u884c\u7ed3\u679c\uff1a deployment.apps/myapp REVISION CHANGE-CAUSE 1 2 kubectl set image deployment/myapp kubernetes-bootcamp=docker.io/jocatalin/kubernetes-bootcamp:v2 --record=true \u83b7\u53d6\u7279\u5b9a\u7248\u672c\u56de\u6eda\u5386\u53f2\u8bb0\u5f55\u3002 kubectl rollout history deployment/myapp --revision = 2 \u6267\u884c\u547d\u4ee4 kubectl rollout undo \u53ef\u4ee5\u56de\u6eda\u5230\u4e0a\u4e00\u4e2a\u7248\u672c\uff0c\u6216\u4f7f\u7528\u9009\u9879 --to-revision= \u56de\u6eda\u5230\u6307\u5b9a\u7684\u7248\u672c\u3002 kubectl rollout undo deployment/myapp --to-revision = 1 \u7248\u672c 1 \u73b0\u5728\u5df2\u7ecf\u88ab\u66ff\u6362\u6210\u7248\u672c 3 \u4e86\u3002 kubectl rollout history deployment/myapp \u8fd0\u884c\u7ed3\u679c\uff1a deployment.apps/myapp REVISION CHANGE-CAUSE 2 kubectl set image deployment/myapp kubernetes-bootcamp=docker.io/jocatalin/kubernetes-bootcamp:v2 --record=true 3 ","title":"\u6eda\u52a8\u5347\u7ea7\uff08Rolling update\uff09"},{"location":"k8s/cka_cn/foundamentals/casestudy-operation-resources/#event","text":"\u83b7\u53d6\u6307\u5b9apod\u7684\u4e8b\u4ef6\u4fe1\u606f\u3002 kubectl describe pod myapp-b5d775f5d-jlx6g \u8f93\u51fa\u7ed3\u679c\uff1a ...... Events: Type Reason Age From Message ---- ------ ---- ---- ------- Normal Scheduled 54s default-scheduler Successfully assigned dev/myapp-b5d775f5d-jlx6g to cka003 Normal Pulled 53s kubelet Container image \"docker.io/jocatalin/kubernetes-bootcamp:v1\" already present on machine Normal Created 53s kubelet Created container kubernetes-bootcamp Normal Started 53s kubelet Started container kubernetes-bootcamp \u67e5\u8be2\u96c6\u7fa4\u7684\u4e8b\u4ef6\u4fe1\u606f\u3002 kubectl get event","title":"\u4e8b\u4ef6\uff08Event\uff09"},{"location":"k8s/cka_cn/foundamentals/casestudy-operation-resources/#logging","text":"\u67e5\u8be2pod\u7684\u65e5\u5fd7\u4fe1\u606f\u3002 kubectl logs -f kubectl logs -f -c \u4f8b\u5982\uff1a kubectl logs -f myapp-b5d775f5d-jlx6g \u8fd0\u884c\u7ed3\u679c\uff1a Kubernetes Bootcamp App Started At: 2022-07-23T06:54:18.532Z | Running On: myapp-b5d775f5d-jlx6g \u67e5\u8be2K8s\u4e0d\u540c\u7ec4\u4ef6\u7684\u65e5\u5fd7\u4fe1\u606f\u3002 kubectl logs kube-apiserver-cka001 -n kube-system kubectl logs kube-controller-manager-cka001 -n kube-system kubectl logs kube-scheduler-cka001 -n kube-system kubectl logs etcd-cka001 -n kube-system systemctl status kubelet journalctl -fu kubelet kubectl logs kube-proxy-5cdbj -n kube-system \u5220\u9664\u6f14\u793a\u4e2d\u521b\u5efa\u7684\u4e34\u65f6\u8d44\u6e90\u3002 kubectl delete service myapp kubectl delete deployment myapp","title":"\u65e5\u5fd7\u8bb0\u5f55\uff08Logging\uff09"},{"location":"k8s/cka_cn/foundamentals/clustermgt/","text":"CKA\u81ea\u5b66\u7b14\u8bb024:Cluster Management \u00b6 \u6f14\u793a\u573a\u666f\uff1a etcd Backup and Restore \u5b89\u88c5 etcdctl \u5728\u5907\u4efd\u4e4b\u524d\u521b\u5efa Deployment \u5907\u4efd etcd \u5728\u5907\u4efd\u4e4b\u540e\u521b\u5efa Deployment \u505c\u6b62\u670d\u52a1 \u505c\u6b62 etcd \u6062\u590d etcd \u542f\u52a8\u670d\u52a1 \u9a8c\u8bc1 etcd \u5907\u4efd\u548c\u6062\u590d \u00b6 \u5b89\u88c5 etcdctl \u00b6 \u4e0b\u8f7d etcd \u5b89\u88c5\u5305\u3002 wget https://github.com/etcd-io/etcd/releases/download/v3.5.3/etcd-v3.5.3-linux-amd64.tar.gz \u89e3\u538b etcd \u5b89\u88c5\u5305\uff0c\u5e76\u8d4b\u4e88\u6267\u884c\u6743\u9650\u3002 tar -zxvf etcd-v3.5.3-linux-amd64.tar.gz cp etcd-v3.5.3-linux-amd64/etcdctl /usr/local/bin/ sudo chmod u+x /usr/local/bin/etcdctl \u9a8c\u8bc1\uff1a etcdctl --help \u521b\u5efa\u4e00\u4e2adeployment\uff08\u5907\u4efd\u524d\uff09 \u00b6 \u5907\u4efd\u524d\u521b\u5efa\u4e00\u4e2adeployment\u3002 kubectl create deployment app-before-backup --image = nginx \u5907\u4efd etcd \u00b6 \u8bf4\u660e\uff1a \u662f\u63a7\u5236\u5e73\u9762\u8282\u70b9\u7684\u5b9e\u9645IP\u5730\u5740\u3002 --endpoints \uff1a\u6307\u5b9a etcd \u5907\u4efd\u7684\u4fdd\u5b58\u4f4d\u7f6e\uff0c2379 \u662f etcd \u7684\u7aef\u53e3\u53f7\u3002 --cert \uff1a\u6307\u5b9a etcd \u8bc1\u4e66\u7684\u4f4d\u7f6e\uff0c\u8bc1\u4e66\u662f\u7531 kubeadm \u751f\u6210\u5e76\u4fdd\u5b58\u5728 /etc/kubernetes/pki/etcd/ \u76ee\u5f55\u4e0b\u7684\u3002 --key \uff1a\u6307\u5b9a etcd \u8bc1\u4e66\u7684\u79c1\u94a5\u7684\u4f4d\u7f6e\uff0c\u8bc1\u4e66\u662f\u7531 kubeadm \u751f\u6210\u5e76\u4fdd\u5b58\u5728 /etc/kubernetes/pki/etcd/ \u76ee\u5f55\u4e0b\u7684\u3002 --cacert \uff1a\u6307\u5b9a etcd \u8bc1\u4e66\u7684 CA \u7684\u4f4d\u7f6e\uff0c\u8bc1\u4e66\u662f\u7531 kubeadm \u751f\u6210\u5e76\u4fdd\u5b58\u5728 /etc/kubernetes/pki/etcd/ \u76ee\u5f55\u4e0b\u7684\u3002 etcdctl \\ --endpoints = https://:2379 \\ --cert = /etc/kubernetes/pki/etcd/server.crt \\ --key = /etc/kubernetes/pki/etcd/server.key \\ --cacert = /etc/kubernetes/pki/etcd/ca.crt \\ snapshot save snapshot- $( date + \"%Y%m%d%H%M%S\" ) .db \u6216\u8005 etcdctl \\ --endpoints = https://:2379 \\ --cert = /etc/kubernetes/pki/etcd/server.crt \\ --key = /etc/kubernetes/pki/etcd/server.key \\ --cacert = /etc/kubernetes/pki/etcd/ca.crt \\ snapshot save snapshot- $( date + \"%Y%m%d%H%M%S\" ) .db Output: {\"level\":\"info\",\"ts\":\"2022-07-24T18:51:21.328+0800\",\"caller\":\"snapshot/v3_snapshot.go:65\",\"msg\":\"created temporary db file\",\"path\":\"snapshot-20220724185121.db.part\"} {\"level\":\"info\",\"ts\":\"2022-07-24T18:51:21.337+0800\",\"logger\":\"client\",\"caller\":\"v3/maintenance.go:211\",\"msg\":\"opened snapshot stream; downloading\"} {\"level\":\"info\",\"ts\":\"2022-07-24T18:51:21.337+0800\",\"caller\":\"snapshot/v3_snapshot.go:73\",\"msg\":\"fetching snapshot\",\"endpoint\":\"https://:2379\"} {\"level\":\"info\",\"ts\":\"2022-07-24T18:51:21.415+0800\",\"logger\":\"client\",\"caller\":\"v3/maintenance.go:219\",\"msg\":\"completed snapshot read; closing\"} {\"level\":\"info\",\"ts\":\"2022-07-24T18:51:21.477+0800\",\"caller\":\"snapshot/v3_snapshot.go:88\",\"msg\":\"fetched snapshot\",\"endpoint\":\"https://:2379\",\"size\":\"3.6 MB\",\"took\":\"now\"} {\"level\":\"info\",\"ts\":\"2022-07-24T18:51:21.477+0800\",\"caller\":\"snapshot/v3_snapshot.go:97\",\"msg\":\"saved\",\"path\":\"snapshot-20220724185121.db\"} Snapshot saved at snapshot-20220724185121.db \u6267\u884c\u547d\u4ee4 ls -al \u5728\u5f53\u524d\u76ee\u5f55\u4e2d\u8bfb\u53d6\u6211\u4eec\u521a\u521a\u521b\u5efa\u7684\u5907\u4efd\u6587\u4ef6\u3002 -rw------- 1 root root 3616800 Jul 24 18 :51 snapshot-20220724185121.db \u521b\u5efa\u4e00\u4e2adeployment\uff08\u5907\u4efd\u540e\uff09 \u00b6 \u5907\u4efd\u540e\uff0c\u6211\u4eec\u521b\u5efa\u53e6\u5916\u4e00\u4e2adeployment\u3002 kubectl create deployment app-after-backup --image = nginx \u5220\u9664\u5907\u4efd\u524d\u6211\u4eec\u521b\u5efa\u7684\u90a3\u4e2adeployment\u3002 kubectl delete deployment app-before-backup \u68c0\u67e5deployment\u7684\u72b6\u6001\u3002 kubectl get deploy \u8fd0\u884c\u7ed3\u679c\uff1a NAME READY UP-TO-DATE AVAILABLE AGE app-after-backup 1/1 1 1 108s \u505c\u6b62Services \u00b6 \u5220\u9664 etcd \u7684\u76ee\u5f55\u3002 mv /var/lib/etcd/ /var/lib/etcd.bak \u505c\u6b62 kubelet \u3002 systemctl stop kubelet \u505c\u6b62 kube-apiserver \u3002 nerdctl -n k8s.io ps -a | grep apiserver \u8fd0\u884c\u7ed3\u679c\uff1a 0c5e69118f1b registry.aliyuncs.com/google_containers/kube-apiserver:v1.24.0 \"kube-apiserver --ad\u2026\" 32 hours ago Up k8s://kube-system/kube-apiserver-cka001/kube-apiserver 638bb602c310 registry.aliyuncs.com/google_containers/pause:3.6 \"/pause\" 32 hours ago Up k8s://kube-system/kube-apiserver-cka001 \u505c\u6b62\u90a3\u4e9b\u4ecd\u65e7\u5904\u4e8e up \u72b6\u6001\u7684\u5bb9\u5668\u3002 nerdctl -n k8s.io stop nerdctl -n k8s.io stop 0c5e69118f1b nerdctl -n k8s.io stop 638bb602c310 \u76f4\u81f3\u6ca1\u6709\u5904\u4e8e up \u72b6\u6001\u7684 kube-apiserver \u3002 nerdctl -n k8s.io ps -a | grep apiserver \u8fd0\u884c\u7ed3\u679c\uff1a 0c5e69118f1b registry.aliyuncs.com/google_containers/kube-apiserver:v1.24.0 \"kube-apiserver --ad\u2026\" 32 hours ago Created k8s://kube-system/kube-apiserver-cka001/kube-apiserver 638bb602c310 registry.aliyuncs.com/google_containers/pause:3.6 \"/pause\" 32 hours ago Created k8s://kube-system/kube-apiserver-cka001 \u505c\u6b62etcd \u00b6 nerdctl -n k8s.io ps -a | grep etcd \u8fd0\u884c\u7ed3\u679c\uff1a 0965b195f41a registry.aliyuncs.com/google_containers/etcd:3.5.1-0 \"etcd --advertise-cl\u2026\" 32 hours ago Up k8s://kube-system/etcd-cka001/etcd 9e1bea9f25d1 registry.aliyuncs.com/google_containers/pause:3.6 \"/pause\" 32 hours ago Up k8s://kube-system/etcd-cka001 \u505c\u6b62\u90a3\u4e9b\u4ecd\u65e7\u5904\u4e8e up \u72b6\u6001\u7684\u5bb9\u5668\u3002 nerdctl -n k8s.io stop nerdctl -n k8s.io stop 0965b195f41a nerdctl -n k8s.io stop 9e1bea9f25d1 \u76f4\u81f3\u6ca1\u6709\u5904\u4e8e up \u72b6\u6001\u7684 kube-apiserver \u3002 nerdctl -n k8s.io ps -a | grep etcd \u8fd0\u884c\u7ed3\u679c\uff1a 0965b195f41a registry.aliyuncs.com/google_containers/etcd:3.5.1-0 \"etcd --advertise-cl\u2026\" 32 hours ago Created k8s://kube-system/etcd-cka001/etcd 9e1bea9f25d1 registry.aliyuncs.com/google_containers/pause:3.6 \"/pause\" 32 hours ago Created k8s://kube-system/etcd-cka001 \u6062\u590d etcd \u00b6 \u5728\u63a7\u5236\u5e73\u9762\u8282\u70b9\u4e0a\u6267\u884c\u6062\u590d\u64cd\u4f5c\uff0c\u4f7f\u7528\u5b9e\u9645\u7684\u5907\u4efd\u6587\u4ef6\uff0c\u8fd9\u91cc\u662f\u6587\u4ef6 snapshot-20220724185121.db \u3002 etcdctl snapshot restore snapshot-20220724185121.db \\ --endpoints = :2379 \\ --cert = /etc/kubernetes/pki/etcd/server.crt \\ --key = /etc/kubernetes/pki/etcd/server.key \\ --cacert = /etc/kubernetes/pki/etcd/ca.crt \\ --data-dir = /var/lib/etcd \u8fd0\u884c\u7ed3\u679c\uff1a Deprecated: Use `etcdutl snapshot restore` instead. 2022-07-24T18:57:49+08:00 info snapshot/v3_snapshot.go:248 restoring snapshot {\"path\": \"snapshot-20220724185121.db\", \"wal-dir\": \"/var/lib/etcd/member/wal\", \"data-dir\": \"/var/lib/etcd\", \"snap-dir\": \"/var/lib/etcd/member/snap\", \"stack\": \"go.etcd.io/etcd/etcdutl/v3/snapshot.(*v3Manager).Restore\\n\\t/go/src/go.etcd.io/etcd/release/etcd/etcdutl/snapshot/v3_snapshot.go:254\\ngo.etcd.io/etcd/etcdutl/v3/etcdutl.SnapshotRestoreCommandFunc\\n\\t/go/src/go.etcd.io/etcd/release/etcd/etcdutl/etcdutl/snapshot_command.go:147\\ngo.etcd.io/etcd/etcdctl/v3/ctlv3/command.snapshotRestoreCommandFunc\\n\\t/go/src/go.etcd.io/etcd/release/etcd/etcdctl/ctlv3/command/snapshot_command.go:129\\ngithub.com/spf13/cobra.(*Command).execute\\n\\t/go/pkg/mod/github.com/spf13/cobra@v1.1.3/command.go:856\\ngithub.com/spf13/cobra.(*Command).ExecuteC\\n\\t/go/pkg/mod/github.com/spf13/cobra@v1.1.3/command.go:960\\ngithub.com/spf13/cobra.(*Command).Execute\\n\\t/go/pkg/mod/github.com/spf13/cobra@v1.1.3/command.go:897\\ngo.etcd.io/etcd/etcdctl/v3/ctlv3.Start\\n\\t/go/src/go.etcd.io/etcd/release/etcd/etcdctl/ctlv3/ctl.go:107\\ngo.etcd.io/etcd/etcdctl/v3/ctlv3.MustStart\\n\\t/go/src/go.etcd.io/etcd/release/etcd/etcdctl/ctlv3/ctl.go:111\\nmain.main\\n\\t/go/src/go.etcd.io/etcd/release/etcd/etcdctl/main.go:59\\nruntime.main\\n\\t/go/gos/go1.16.15/src/runtime/proc.go:225\"} 2022-07-24T18:57:49+08:00 info membership/store.go:141 Trimming membership information from the backend... 2022-07-24T18:57:49+08:00 info membership/cluster.go:421 added member {\"cluster-id\": \"cdf818194e3a8c32\", \"local-member-id\": \"0\", \"added-peer-id\": \"8e9e05c52164694d\", \"added-peer-peer-urls\": [\"http://localhost:2380\"]} 2022-07-24T18:57:49+08:00 info snapshot/v3_snapshot.go:269 restored snapshot {\"path\": \"snapshot-20220724185121.db\", \"wal-dir\": \"/var/lib/etcd/member/wal\", \"data-dir\": \"/var/lib/etcd\", \"snap-dir\": \"/var/lib/etcd/member/snap\"} \u68c0\u67e5\u88ab\u5220\u9664\u7684 etcd \u76ee\u5f55\u662f\u5426\u5df2\u7ecf\u4ece\u5907\u4efd\u4e2d\u6062\u590d\u4e86\u3002 tree /var/lib/etcd \u8fd0\u884c\u7ed3\u679c\uff1a /var/lib/etcd \u2514\u2500\u2500 member \u251c\u2500\u2500 snap \u2502 \u251c\u2500\u2500 0000000000000001-0000000000000001.snap \u2502 \u2514\u2500\u2500 db \u2514\u2500\u2500 wal \u2514\u2500\u2500 0000000000000000-0000000000000000.wal \u542f\u52a8\u670d\u52a1Services \u00b6 \u542f\u52a8 kubelet \u3002\u670d\u52a1 kube-apiserver \u548c etcd \u4e5f\u4f1a\u7ee7 kubelet \u542f\u52a8\u540e\u88ab\u81ea\u52a8\u542f\u52a8\u3002 systemctl start kubelet \u6267\u884c\u4e0b\u9762\u547d\u4ee4\u786e\u8ba4\u6240\u6709\u670d\u52a1\u90fd\u5df2\u7ecf\u542f\u52a8\u548c\u6b63\u5e38\u8fd0\u884c\u3002 systemctl status kubelet.service nerdctl -n k8s.io ps -a | grep etcd nerdctl -n k8s.io ps -a | grep apiserver \u67e5\u770b\u5f53\u524d etcd \u7684\u72b6\u6001\u3002 0965b195f41a registry.aliyuncs.com/google_containers/etcd:3.5.1-0 \"etcd --advertise-cl\u2026\" 32 hours ago Created k8s://kube-system/etcd-cka001/etcd 3b8f37c87782 registry.aliyuncs.com/google_containers/etcd:3.5.1-0 \"etcd --advertise-cl\u2026\" 6 seconds ago Up k8s://kube-system/etcd-cka001/etcd 9e1bea9f25d1 registry.aliyuncs.com/google_containers/pause:3.6 \"/pause\" 32 hours ago Created k8s://kube-system/etcd-cka001 fbbbb628a945 registry.aliyuncs.com/google_containers/pause:3.6 \"/pause\" 6 seconds ago Up k8s://kube-system/etcd-cka001 \u67e5\u770b\u5f53\u524d apiserver \u7684\u72b6\u6001\u3002 0c5e69118f1b registry.aliyuncs.com/google_containers/kube-apiserver:v1.24.0 \"kube-apiserver --ad\u2026\" 32 hours ago Created k8s://kube-system/kube-apiserver-cka001/kube-apiserver 281cf4c6670d registry.aliyuncs.com/google_containers/kube-apiserver:v1.24.0 \"kube-apiserver --ad\u2026\" 14 seconds ago Up k8s://kube-system/kube-apiserver-cka001/kube-apiserver 5ed8295d92da registry.aliyuncs.com/google_containers/pause:3.6 \"/pause\" 15 seconds ago Up k8s://kube-system/kube-apiserver-cka001 638bb602c310 registry.aliyuncs.com/google_containers/pause:3.6 \"/pause\" 32 hours ago Created k8s://kube-system/kube-apiserver-cka001 \u9a8c\u8bc1 \u00b6 \u68c0\u67e5\u96c6\u7fa4\u7684\u72b6\u6001\uff0c\u67e5\u770b\u662f\u5426pod app-before-backup \u5b58\u5728\u3002 kubectl get deploy \u8fd0\u884c\u7ed3\u679c\uff1a NAME READY UP-TO-DATE AVAILABLE AGE app-before-backup 1/1 1 1 11m \u96c6\u7fa4\u5347\u7ea7 \u00b6 \u6f14\u793a\u573a\u666f\uff1a\u96c6\u7fa4\u5347\u7ea7 \u9a71\u9010\u63a7\u5236\u5e73\u9762\u8282\u70b9 \u68c0\u67e5\u5f53\u524d\u53ef\u7528\u7684 kubeadm \u7248\u672c \u5c06 kubeadm \u5347\u7ea7\u5230\u65b0\u7248\u672c \u68c0\u67e5\u5347\u7ea7\u8ba1\u5212 \u5e94\u7528\u5347\u7ea7\u8ba1\u5212\u4ee5\u5347\u7ea7\u5230\u65b0\u7248\u672c \u5347\u7ea7 kubelet \u548c kubectl \u542f\u7528\u63a7\u5236\u5e73\u9762\u8282\u70b9\u8c03\u5ea6 \u9a71\u9010\u5de5\u4f5c\u8282\u70b9 \u5347\u7ea7 kubeadm \u548c kubelet \u542f\u7528\u5de5\u4f5c\u8282\u70b9\u8c03\u5ea6 \u53c2\u8003\uff1a kubeadm\u5347\u7ea7 \u5347\u7ea7\u63a7\u5236\u5e73\u9762 \u00b6 \u63a7\u5236\u5e73\u9762\u51c6\u5907 \u00b6 \u9a71\u9010\u63a7\u5236\u5e73\u9762\u8282\u70b9\u3002 kubectl drain --ignore-daemonsets \u8fd9\u91cc\u662f\uff1a kubectl drain cka001 --ignore-daemonsets \u8fd0\u884c\u7ed3\u679c\uff1a node/cka001 cordoned WARNING: ignoring DaemonSet-managed Pods: kube-system/calico-node-dsx76, kube-system/kube-proxy-cm4hc evicting pod kube-system/calico-kube-controllers-5c64b68895-jr4nl evicting pod kube-system/coredns-6d8c4cb4d-g4jxc evicting pod kube-system/coredns-6d8c4cb4d-sqcvj pod/calico-kube-controllers-5c64b68895-jr4nl evicted pod/coredns-6d8c4cb4d-g4jxc evicted pod/coredns-6d8c4cb4d-sqcvj evicted node/cka001 drained \u63a7\u5236\u5e73\u9762\u8282\u70b9\u73b0\u5728\u5904\u4e8e SchedulingDisabled \u72b6\u6001\u3002 kubectl get node -owide \u8fd0\u884c\u7ed3\u679c\uff1a NAME STATUS ROLES AGE VERSION OS-IMAGE KERNEL-VERSION CONTAINER-RUNTIME cka001 Ready,SchedulingDisabled control-plane,master 32h v1.24.0 Ubuntu 20.04.4 LTS 5.4.0-122-generic containerd://1.5.9 cka002 Ready 32h v1.24.0 Ubuntu 20.04.4 LTS 5.4.0-122-generic containerd://1.5.9 cka003 Ready 32h v1.24.0 Ubuntu 20.04.4 LTS 5.4.0-122-generic containerd://1.5.9 \u67e5\u8be2\u5f53\u524d kubeadm \u53ef\u7528\u7248\u672c\u3002 apt policy kubeadm \u8f93\u51fa\u7ed3\u679c\uff1a kubeadm: Installed: 1.24.0-00 Candidate: 1.24.3-00 Version table: 1.24.3-00 500 500 https://mirrors.aliyun.com/kubernetes/apt kubernetes-xenial/main amd64 Packages 1.24.2-00 500 500 https://mirrors.aliyun.com/kubernetes/apt kubernetes-xenial/main amd64 Packages 1.24.1-00 500 500 https://mirrors.aliyun.com/kubernetes/apt kubernetes-xenial/main amd64 Packages 1.24.0-00 500 500 https://mirrors.aliyun.com/kubernetes/apt kubernetes-xenial/main amd64 Packages 1.24.2-00 500 500 https://mirrors.aliyun.com/kubernetes/apt kubernetes-xenial/main amd64 Packages *** 1.24.0-00 500 500 https://mirrors.aliyun.com/kubernetes/apt kubernetes-xenial/main amd64 Packages 100 /var/lib/dpkg/status 1.23.7-00 500 500 https://mirrors.aliyun.com/kubernetes/apt kubernetes-xenial/main amd64 Packages ...... \u5347\u7ea7 kubeadm \u5230 Candidate: 1.24.2-00 \u7248\u672c\u3002 sudo apt-get -y install kubeadm = 1 .24.2-00 --allow-downgrades \u67e5\u8be2\u5347\u7ea7\u8ba1\u5212\u3002 kubeadm upgrade plan \u8f93\u51fa\u7c7b\u4f3c\u4e0b\u9762\u7684\u5347\u7ea7\u8ba1\u5212\u3002 [upgrade/config] Making sure the configuration is correct: [upgrade/config] Reading configuration from the cluster... [upgrade/config] FYI: You can look at this config file with 'kubectl -n kube-system get cm kubeadm-config -o yaml' [preflight] Running pre-flight checks. [upgrade] Running cluster health checks [upgrade] Fetching available versions to upgrade to [upgrade/versions] Cluster version: v1.24.0 [upgrade/versions] kubeadm version: v1.24.2 I0724 19:05:00.111855 1142460 version.go:255] remote version is much newer: v1.24.3; falling back to: stable-1.23 [upgrade/versions] Target version: v1.24.2 [upgrade/versions] Latest version in the v1.23 series: v1.24.2 Components that must be upgraded manually after you have upgraded the control plane with 'kubeadm upgrade apply': COMPONENT CURRENT TARGET kubelet 3 x v1.24.0 v1.24.2 Upgrade to the latest version in the v1.23 series: COMPONENT CURRENT TARGET kube-apiserver v1.24.0 v1.24.2 kube-controller-manager v1.24.0 v1.24.2 kube-scheduler v1.24.0 v1.24.2 kube-proxy v1.24.0 v1.24.2 CoreDNS v1.8.6 v1.8.6 etcd 3.5.1-0 3.5.1-0 You can now apply the upgrade by executing the following command: kubeadm upgrade apply v1.24.2 _____________________________________________________________________ The table below shows the current state of component configs as understood by this version of kubeadm. Configs that have a \"yes\" mark in the \"MANUAL UPGRADE REQUIRED\" column require manual config upgrade or resetting to kubeadm defaults before a successful upgrade can be performed. The version to manually upgrade to is denoted in the \"PREFERRED VERSION\" column. API GROUP CURRENT VERSION PREFERRED VERSION MANUAL UPGRADE REQUIRED kubeproxy.config.k8s.io v1alpha1 v1alpha1 no kubelet.config.k8s.io v1beta1 v1beta1 no _____________________________________________________________________ \u63a7\u5236\u5e73\u9762\u5347\u7ea7 \u00b6 \u53c2\u8003\u524d\u9762\u7684\u5347\u7ea7\u8ba1\u5212\uff0c\u6211\u4eec\u5347\u7ea7\u5230 v1.24.2 \u7248\u672c\u3002 kubeadm upgrade apply v1.24.2 \u901a\u8fc7\u9009\u9879 --etcd-upgrade=false \uff0c\u6211\u4eec\u628a etcd \u6392\u9664\u51fa\u5f53\u524d\u5347\u7ea7\u8303\u56f4\u3002 kubeadm upgrade apply v1.24.2 --etcd-upgrade = false \u6536\u5230\u4e0b\u9762\u7684\u4fe1\u606f\uff0c\u5219\u4ee3\u8868\u4e0a\u9762\u7684\u5347\u7ea7\u547d\u4ee4\u6210\u529f\u4e86\u3002 [upgrade/successful] SUCCESS! Your cluster was upgraded to \"v1.24.2\". Enjoy! [upgrade/kubelet] Now that your control plane is upgraded, please proceed with upgrading your kubelets if you haven't already done so. \u5347\u7ea7 kubelet \u548c kubectl \u3002 sudo apt-get -y install kubelet = 1 .24.2-00 kubectl = 1 .24.2-00 --allow-downgrades sudo systemctl daemon-reload sudo systemctl restart kubelet \u67e5\u8be2\u8282\u70b9\u5f53\u524d\u72b6\u6001\u3002 kubectl get node \u8fd0\u884c\u7ed3\u679c\uff1a NAME STATUS ROLES AGE VERSION cka001 Ready,SchedulingDisabled control-plane,master 32h v1.24.2 cka002 Ready 32h v1.24.0 cka003 Ready 32h v1.24.0 After verify that each node is in Ready status, enable node scheduling. \u5728\u786e\u8ba4\u6240\u6709\u8282\u70b9\u90fd\u5904\u4e8eReady\u72b6\u6001\uff0c\u5219\u6fc0\u6d3bscheduling\u3002 kubectl uncordon \u8fd9\u91cc\u662f\uff1a kubectl uncordon cka001 \u8f93\u51fa\u7ed3\u679c\uff1a node/cka001 uncordoned \u518d\u6b21\u68c0\u67e5\u8282\u70b9\u72b6\u6001\uff0c\u786e\u4fdd\u6240\u6709\u8282\u70b9\u90fd\u5904\u4e8eReady\u72b6\u6001\u3002 kubectl get node \u8fd0\u884c\u7ed3\u679c\uff1a NAME STATUS ROLES AGE VERSION cka001 Ready control-plane,master 32h v1.24.2 cka002 Ready 32h v1.24.0 cka003 Ready 32h v1.24.0 \u5347\u7ea7\u5de5\u4f5c\u8282\u70b9 \u00b6 \u5de5\u4f5c\u8282\u70b9\u51c6\u5907 \u00b6 \u767b\u5f55\u8282\u70b9 cka001 \u3002 \u9a71\u9010 Worker \u8282\u70b9\uff0c\u9700\u8981\u663e\u5f0f\u6307\u5b9a\u662f\u5426\u5220\u9664\u672c\u5730\u5b58\u50a8\u3002 kubectl drain --ignore-daemonsets --force kubectl drain --ignore-daemonsets --delete-emptydir-data --force \u5982\u679c\u9047\u5230\u5173\u4e8e emptydir \u4f9d\u8d56\u7684\u9519\u8bef\uff0c\u5219\u6267\u884c\u7b2c\u4e8c\u4e2a\u547d\u4ee4\u3002 kubectl drain cka002 --ignore-daemonsets --force kubectl drain cka002 --ignore-daemonsets --delete-emptydir-data --force \u8f93\u51fa\u7ed3\u679c\uff1a node/cka002 cordoned WARNING: deleting Pods not managed by ReplicationController, ReplicaSet, Job, DaemonSet or StatefulSet: dev/ubuntu; ignoring DaemonSet-managed Pods: kube-system/calico-node-p5rf2, kube-system/kube-proxy-zvs68 evicting pod ns-netpol/pod-netpol-5b67b6b496-2cgnw evicting pod dev/ubuntu evicting pod dev/app-before-backup-66dc9d5cb-6xc8c evicting pod dev/nfs-client-provisioner-86d7fb78b6-2f5dx evicting pod dev/pod-netpol-2-77478d77ff-l6rzm evicting pod ingress-nginx/ingress-nginx-admission-patch-nk9fv evicting pod ingress-nginx/ingress-nginx-admission-create-lgtdj evicting pod kube-system/coredns-6d8c4cb4d-l4kx4 pod/ingress-nginx-admission-create-lgtdj evicted pod/ingress-nginx-admission-patch-nk9fv evicted pod/nfs-client-provisioner-86d7fb78b6-2f5dx evicted pod/app-before-backup-66dc9d5cb-6xc8c evicted pod/coredns-6d8c4cb4d-l4kx4 evicted pod/pod-netpol-5b67b6b496-2cgnw evicted pod/pod-netpol-2-77478d77ff-l6rzm evicted pod/ubuntu evicted node/cka002 drained \u5de5\u4f5c\u8282\u70b9\u5347\u7ea7 \u00b6 \u767b\u5f55\u8282\u70b9 cka002 \u3002 \u4e0b\u8f7d kubeadm \u7684 v1.24.2 \u7248\u672c\u3002 sudo apt-get -y install kubeadm = 1 .24.2-00 --allow-downgrades \u5347\u7ea7 kubeadm \u3002 sudo kubeadm upgrade node \u5347\u7ea7 kubelet \u3002 sudo apt-get -y install kubelet = 1 .24.2-00 --allow-downgrades sudo systemctl daemon-reload sudo systemctl restart kubelet \u786e\u8ba4\u6240\u6709\u8282\u70b9\u90fd\u5904\u4e8eReady\u72b6\u6001\uff0c\u5219\u6fc0\u6d3bscheduling\u3002 kubectl uncordon \u8fd9\u91cc\u662f\uff1a kubectl uncordon cka002 \u5de5\u4f5c\u8282\u70b9\u9a8c\u8bc1 \u00b6 \u67e5\u8be2\u8282\u70b9\u72b6\u6001\u3002 kubectl get node \u8fd0\u884c\u7ed3\u679c\uff1a NAME STATUS ROLES AGE VERSION cka001 Ready control-plane,master 32h v1.24.2 cka002 Ready 32h v1.24.2 cka003 Ready 32h v1.24.0 \u5728\u8282\u70b9 cka003 \u4e0a\u91cd\u590d\u4e0a\u9762\u7684\u6b65\u9aa4\u3002 \u767b\u5f55\u8282\u70b9 cka003 \u3002\u5982\u679c\u9047\u5230\u5173\u4e8e emptydir \u4f9d\u8d56\u7684\u9519\u8bef\uff0c\u5219\u6267\u884c\u7b2c\u4e8c\u4e2a\u547d\u4ee4\u3002 kubectl drain cka003 --ignore-daemonsets --ignore-daemonsets --force kubectl drain cka003 --ignore-daemonsets --ignore-daemonsets --delete-emptydir-data --force \u767b\u5f55\u8282\u70b9 cka003 \uff0c\u6267\u884c\u4e0b\u9762\u7684\u547d\u4ee4\u3002 sudo apt-get -y install kubeadm = 1 .24.2-00 --allow-downgrades sudo kubeadm upgrade node sudo apt-get -y install kubelet = 1 .24.2-00 --allow-downgrades sudo systemctl daemon-reload sudo systemctl restart kubelet kubectl get node kubectl uncordon cka003 \u67e5\u8be2\u8282\u70b9\u72b6\u6001\u3002 kubectl get node \u8fd0\u884c\u7ed3\u679c\uff1a NAME STATUS ROLES AGE VERSION cka001 Ready control-plane,master 32h v1.24.2 cka002 Ready 32h v1.24.2 cka003 Ready 32h v1.24.2 \u603b\u7ed3 \u00b6 \u5728\u63a7\u5236\u9762\u677f\u4e0a\u7684\u6267\u884c\u6b65\u9aa4\uff1a kubectl get node -owide kubectl drain cka001 --ignore-daemonsets kubectl get node -owide apt policy kubeadm apt-get -y install kubeadm = 1 .24.0-00 --allow-downgrades kubeadm upgrade plan kubeadm upgrade apply v1.24.0 # kubeadm upgrade apply v1.24.0 --etcd-upgrade=false apt-get -y install kubelet = 1 .24.0-00 kubectl = 1 .24.0-00 --allow-downgrades systemctl daemon-reload systemctl restart kubelet kubectl get node kubectl uncordon cka001 \u5728\u5de5\u4f5c\u8282\u70b9\u4e0a\u7684\u6267\u884c\u6b65\u9aa4\uff1a \u5728\u63a7\u5236\u9762\u677f\u4e0a\uff1a kubectl drain cka002 --ignore-daemonsets \u5728\u5de5\u4f5c\u8282\u70b9\u4e0a\uff1a apt-get -y install kubeadm = 1 .24.1-00 --allow-downgrades kubeadm upgrade node apt-get -y install kubelet = 1 .24.1-00 --allow-downgrades systemctl daemon-reload systemctl restart kubelet kubectl uncordon cka002 \u5728\u5176\u4ed6\u5de5\u4f5c\u8282\u70b9\u4e0a\u91cd\u590d\u4e0a\u9762\u7684\u6b65\u9aa4\u3002","title":"Cluster Management"},{"location":"k8s/cka_cn/foundamentals/clustermgt/#cka24cluster-management","text":"\u6f14\u793a\u573a\u666f\uff1a etcd Backup and Restore \u5b89\u88c5 etcdctl \u5728\u5907\u4efd\u4e4b\u524d\u521b\u5efa Deployment \u5907\u4efd etcd \u5728\u5907\u4efd\u4e4b\u540e\u521b\u5efa Deployment \u505c\u6b62\u670d\u52a1 \u505c\u6b62 etcd \u6062\u590d etcd \u542f\u52a8\u670d\u52a1 \u9a8c\u8bc1","title":"CKA\u81ea\u5b66\u7b14\u8bb024:Cluster Management"},{"location":"k8s/cka_cn/foundamentals/clustermgt/#etcd","text":"","title":"etcd\u5907\u4efd\u548c\u6062\u590d"},{"location":"k8s/cka_cn/foundamentals/clustermgt/#etcdctl","text":"\u4e0b\u8f7d etcd \u5b89\u88c5\u5305\u3002 wget https://github.com/etcd-io/etcd/releases/download/v3.5.3/etcd-v3.5.3-linux-amd64.tar.gz \u89e3\u538b etcd \u5b89\u88c5\u5305\uff0c\u5e76\u8d4b\u4e88\u6267\u884c\u6743\u9650\u3002 tar -zxvf etcd-v3.5.3-linux-amd64.tar.gz cp etcd-v3.5.3-linux-amd64/etcdctl /usr/local/bin/ sudo chmod u+x /usr/local/bin/etcdctl \u9a8c\u8bc1\uff1a etcdctl --help","title":"\u5b89\u88c5etcdctl"},{"location":"k8s/cka_cn/foundamentals/clustermgt/#deployment","text":"\u5907\u4efd\u524d\u521b\u5efa\u4e00\u4e2adeployment\u3002 kubectl create deployment app-before-backup --image = nginx","title":"\u521b\u5efa\u4e00\u4e2adeployment\uff08\u5907\u4efd\u524d\uff09"},{"location":"k8s/cka_cn/foundamentals/clustermgt/#etcd_1","text":"\u8bf4\u660e\uff1a \u662f\u63a7\u5236\u5e73\u9762\u8282\u70b9\u7684\u5b9e\u9645IP\u5730\u5740\u3002 --endpoints \uff1a\u6307\u5b9a etcd \u5907\u4efd\u7684\u4fdd\u5b58\u4f4d\u7f6e\uff0c2379 \u662f etcd \u7684\u7aef\u53e3\u53f7\u3002 --cert \uff1a\u6307\u5b9a etcd \u8bc1\u4e66\u7684\u4f4d\u7f6e\uff0c\u8bc1\u4e66\u662f\u7531 kubeadm \u751f\u6210\u5e76\u4fdd\u5b58\u5728 /etc/kubernetes/pki/etcd/ \u76ee\u5f55\u4e0b\u7684\u3002 --key \uff1a\u6307\u5b9a etcd \u8bc1\u4e66\u7684\u79c1\u94a5\u7684\u4f4d\u7f6e\uff0c\u8bc1\u4e66\u662f\u7531 kubeadm \u751f\u6210\u5e76\u4fdd\u5b58\u5728 /etc/kubernetes/pki/etcd/ \u76ee\u5f55\u4e0b\u7684\u3002 --cacert \uff1a\u6307\u5b9a etcd \u8bc1\u4e66\u7684 CA \u7684\u4f4d\u7f6e\uff0c\u8bc1\u4e66\u662f\u7531 kubeadm \u751f\u6210\u5e76\u4fdd\u5b58\u5728 /etc/kubernetes/pki/etcd/ \u76ee\u5f55\u4e0b\u7684\u3002 etcdctl \\ --endpoints = https://:2379 \\ --cert = /etc/kubernetes/pki/etcd/server.crt \\ --key = /etc/kubernetes/pki/etcd/server.key \\ --cacert = /etc/kubernetes/pki/etcd/ca.crt \\ snapshot save snapshot- $( date + \"%Y%m%d%H%M%S\" ) .db \u6216\u8005 etcdctl \\ --endpoints = https://:2379 \\ --cert = /etc/kubernetes/pki/etcd/server.crt \\ --key = /etc/kubernetes/pki/etcd/server.key \\ --cacert = /etc/kubernetes/pki/etcd/ca.crt \\ snapshot save snapshot- $( date + \"%Y%m%d%H%M%S\" ) .db Output: {\"level\":\"info\",\"ts\":\"2022-07-24T18:51:21.328+0800\",\"caller\":\"snapshot/v3_snapshot.go:65\",\"msg\":\"created temporary db file\",\"path\":\"snapshot-20220724185121.db.part\"} {\"level\":\"info\",\"ts\":\"2022-07-24T18:51:21.337+0800\",\"logger\":\"client\",\"caller\":\"v3/maintenance.go:211\",\"msg\":\"opened snapshot stream; downloading\"} {\"level\":\"info\",\"ts\":\"2022-07-24T18:51:21.337+0800\",\"caller\":\"snapshot/v3_snapshot.go:73\",\"msg\":\"fetching snapshot\",\"endpoint\":\"https://:2379\"} {\"level\":\"info\",\"ts\":\"2022-07-24T18:51:21.415+0800\",\"logger\":\"client\",\"caller\":\"v3/maintenance.go:219\",\"msg\":\"completed snapshot read; closing\"} {\"level\":\"info\",\"ts\":\"2022-07-24T18:51:21.477+0800\",\"caller\":\"snapshot/v3_snapshot.go:88\",\"msg\":\"fetched snapshot\",\"endpoint\":\"https://:2379\",\"size\":\"3.6 MB\",\"took\":\"now\"} {\"level\":\"info\",\"ts\":\"2022-07-24T18:51:21.477+0800\",\"caller\":\"snapshot/v3_snapshot.go:97\",\"msg\":\"saved\",\"path\":\"snapshot-20220724185121.db\"} Snapshot saved at snapshot-20220724185121.db \u6267\u884c\u547d\u4ee4 ls -al \u5728\u5f53\u524d\u76ee\u5f55\u4e2d\u8bfb\u53d6\u6211\u4eec\u521a\u521a\u521b\u5efa\u7684\u5907\u4efd\u6587\u4ef6\u3002 -rw------- 1 root root 3616800 Jul 24 18 :51 snapshot-20220724185121.db","title":"\u5907\u4efdetcd"},{"location":"k8s/cka_cn/foundamentals/clustermgt/#deployment_1","text":"\u5907\u4efd\u540e\uff0c\u6211\u4eec\u521b\u5efa\u53e6\u5916\u4e00\u4e2adeployment\u3002 kubectl create deployment app-after-backup --image = nginx \u5220\u9664\u5907\u4efd\u524d\u6211\u4eec\u521b\u5efa\u7684\u90a3\u4e2adeployment\u3002 kubectl delete deployment app-before-backup \u68c0\u67e5deployment\u7684\u72b6\u6001\u3002 kubectl get deploy \u8fd0\u884c\u7ed3\u679c\uff1a NAME READY UP-TO-DATE AVAILABLE AGE app-after-backup 1/1 1 1 108s","title":"\u521b\u5efa\u4e00\u4e2adeployment\uff08\u5907\u4efd\u540e\uff09"},{"location":"k8s/cka_cn/foundamentals/clustermgt/#services","text":"\u5220\u9664 etcd \u7684\u76ee\u5f55\u3002 mv /var/lib/etcd/ /var/lib/etcd.bak \u505c\u6b62 kubelet \u3002 systemctl stop kubelet \u505c\u6b62 kube-apiserver \u3002 nerdctl -n k8s.io ps -a | grep apiserver \u8fd0\u884c\u7ed3\u679c\uff1a 0c5e69118f1b registry.aliyuncs.com/google_containers/kube-apiserver:v1.24.0 \"kube-apiserver --ad\u2026\" 32 hours ago Up k8s://kube-system/kube-apiserver-cka001/kube-apiserver 638bb602c310 registry.aliyuncs.com/google_containers/pause:3.6 \"/pause\" 32 hours ago Up k8s://kube-system/kube-apiserver-cka001 \u505c\u6b62\u90a3\u4e9b\u4ecd\u65e7\u5904\u4e8e up \u72b6\u6001\u7684\u5bb9\u5668\u3002 nerdctl -n k8s.io stop nerdctl -n k8s.io stop 0c5e69118f1b nerdctl -n k8s.io stop 638bb602c310 \u76f4\u81f3\u6ca1\u6709\u5904\u4e8e up \u72b6\u6001\u7684 kube-apiserver \u3002 nerdctl -n k8s.io ps -a | grep apiserver \u8fd0\u884c\u7ed3\u679c\uff1a 0c5e69118f1b registry.aliyuncs.com/google_containers/kube-apiserver:v1.24.0 \"kube-apiserver --ad\u2026\" 32 hours ago Created k8s://kube-system/kube-apiserver-cka001/kube-apiserver 638bb602c310 registry.aliyuncs.com/google_containers/pause:3.6 \"/pause\" 32 hours ago Created k8s://kube-system/kube-apiserver-cka001","title":"\u505c\u6b62Services"},{"location":"k8s/cka_cn/foundamentals/clustermgt/#etcd_2","text":"nerdctl -n k8s.io ps -a | grep etcd \u8fd0\u884c\u7ed3\u679c\uff1a 0965b195f41a registry.aliyuncs.com/google_containers/etcd:3.5.1-0 \"etcd --advertise-cl\u2026\" 32 hours ago Up k8s://kube-system/etcd-cka001/etcd 9e1bea9f25d1 registry.aliyuncs.com/google_containers/pause:3.6 \"/pause\" 32 hours ago Up k8s://kube-system/etcd-cka001 \u505c\u6b62\u90a3\u4e9b\u4ecd\u65e7\u5904\u4e8e up \u72b6\u6001\u7684\u5bb9\u5668\u3002 nerdctl -n k8s.io stop nerdctl -n k8s.io stop 0965b195f41a nerdctl -n k8s.io stop 9e1bea9f25d1 \u76f4\u81f3\u6ca1\u6709\u5904\u4e8e up \u72b6\u6001\u7684 kube-apiserver \u3002 nerdctl -n k8s.io ps -a | grep etcd \u8fd0\u884c\u7ed3\u679c\uff1a 0965b195f41a registry.aliyuncs.com/google_containers/etcd:3.5.1-0 \"etcd --advertise-cl\u2026\" 32 hours ago Created k8s://kube-system/etcd-cka001/etcd 9e1bea9f25d1 registry.aliyuncs.com/google_containers/pause:3.6 \"/pause\" 32 hours ago Created k8s://kube-system/etcd-cka001","title":"\u505c\u6b62etcd"},{"location":"k8s/cka_cn/foundamentals/clustermgt/#etcd_3","text":"\u5728\u63a7\u5236\u5e73\u9762\u8282\u70b9\u4e0a\u6267\u884c\u6062\u590d\u64cd\u4f5c\uff0c\u4f7f\u7528\u5b9e\u9645\u7684\u5907\u4efd\u6587\u4ef6\uff0c\u8fd9\u91cc\u662f\u6587\u4ef6 snapshot-20220724185121.db \u3002 etcdctl snapshot restore snapshot-20220724185121.db \\ --endpoints = :2379 \\ --cert = /etc/kubernetes/pki/etcd/server.crt \\ --key = /etc/kubernetes/pki/etcd/server.key \\ --cacert = /etc/kubernetes/pki/etcd/ca.crt \\ --data-dir = /var/lib/etcd \u8fd0\u884c\u7ed3\u679c\uff1a Deprecated: Use `etcdutl snapshot restore` instead. 2022-07-24T18:57:49+08:00 info snapshot/v3_snapshot.go:248 restoring snapshot {\"path\": \"snapshot-20220724185121.db\", \"wal-dir\": \"/var/lib/etcd/member/wal\", \"data-dir\": \"/var/lib/etcd\", \"snap-dir\": \"/var/lib/etcd/member/snap\", \"stack\": \"go.etcd.io/etcd/etcdutl/v3/snapshot.(*v3Manager).Restore\\n\\t/go/src/go.etcd.io/etcd/release/etcd/etcdutl/snapshot/v3_snapshot.go:254\\ngo.etcd.io/etcd/etcdutl/v3/etcdutl.SnapshotRestoreCommandFunc\\n\\t/go/src/go.etcd.io/etcd/release/etcd/etcdutl/etcdutl/snapshot_command.go:147\\ngo.etcd.io/etcd/etcdctl/v3/ctlv3/command.snapshotRestoreCommandFunc\\n\\t/go/src/go.etcd.io/etcd/release/etcd/etcdctl/ctlv3/command/snapshot_command.go:129\\ngithub.com/spf13/cobra.(*Command).execute\\n\\t/go/pkg/mod/github.com/spf13/cobra@v1.1.3/command.go:856\\ngithub.com/spf13/cobra.(*Command).ExecuteC\\n\\t/go/pkg/mod/github.com/spf13/cobra@v1.1.3/command.go:960\\ngithub.com/spf13/cobra.(*Command).Execute\\n\\t/go/pkg/mod/github.com/spf13/cobra@v1.1.3/command.go:897\\ngo.etcd.io/etcd/etcdctl/v3/ctlv3.Start\\n\\t/go/src/go.etcd.io/etcd/release/etcd/etcdctl/ctlv3/ctl.go:107\\ngo.etcd.io/etcd/etcdctl/v3/ctlv3.MustStart\\n\\t/go/src/go.etcd.io/etcd/release/etcd/etcdctl/ctlv3/ctl.go:111\\nmain.main\\n\\t/go/src/go.etcd.io/etcd/release/etcd/etcdctl/main.go:59\\nruntime.main\\n\\t/go/gos/go1.16.15/src/runtime/proc.go:225\"} 2022-07-24T18:57:49+08:00 info membership/store.go:141 Trimming membership information from the backend... 2022-07-24T18:57:49+08:00 info membership/cluster.go:421 added member {\"cluster-id\": \"cdf818194e3a8c32\", \"local-member-id\": \"0\", \"added-peer-id\": \"8e9e05c52164694d\", \"added-peer-peer-urls\": [\"http://localhost:2380\"]} 2022-07-24T18:57:49+08:00 info snapshot/v3_snapshot.go:269 restored snapshot {\"path\": \"snapshot-20220724185121.db\", \"wal-dir\": \"/var/lib/etcd/member/wal\", \"data-dir\": \"/var/lib/etcd\", \"snap-dir\": \"/var/lib/etcd/member/snap\"} \u68c0\u67e5\u88ab\u5220\u9664\u7684 etcd \u76ee\u5f55\u662f\u5426\u5df2\u7ecf\u4ece\u5907\u4efd\u4e2d\u6062\u590d\u4e86\u3002 tree /var/lib/etcd \u8fd0\u884c\u7ed3\u679c\uff1a /var/lib/etcd \u2514\u2500\u2500 member \u251c\u2500\u2500 snap \u2502 \u251c\u2500\u2500 0000000000000001-0000000000000001.snap \u2502 \u2514\u2500\u2500 db \u2514\u2500\u2500 wal \u2514\u2500\u2500 0000000000000000-0000000000000000.wal","title":"\u6062\u590detcd"},{"location":"k8s/cka_cn/foundamentals/clustermgt/#services_1","text":"\u542f\u52a8 kubelet \u3002\u670d\u52a1 kube-apiserver \u548c etcd \u4e5f\u4f1a\u7ee7 kubelet \u542f\u52a8\u540e\u88ab\u81ea\u52a8\u542f\u52a8\u3002 systemctl start kubelet \u6267\u884c\u4e0b\u9762\u547d\u4ee4\u786e\u8ba4\u6240\u6709\u670d\u52a1\u90fd\u5df2\u7ecf\u542f\u52a8\u548c\u6b63\u5e38\u8fd0\u884c\u3002 systemctl status kubelet.service nerdctl -n k8s.io ps -a | grep etcd nerdctl -n k8s.io ps -a | grep apiserver \u67e5\u770b\u5f53\u524d etcd \u7684\u72b6\u6001\u3002 0965b195f41a registry.aliyuncs.com/google_containers/etcd:3.5.1-0 \"etcd --advertise-cl\u2026\" 32 hours ago Created k8s://kube-system/etcd-cka001/etcd 3b8f37c87782 registry.aliyuncs.com/google_containers/etcd:3.5.1-0 \"etcd --advertise-cl\u2026\" 6 seconds ago Up k8s://kube-system/etcd-cka001/etcd 9e1bea9f25d1 registry.aliyuncs.com/google_containers/pause:3.6 \"/pause\" 32 hours ago Created k8s://kube-system/etcd-cka001 fbbbb628a945 registry.aliyuncs.com/google_containers/pause:3.6 \"/pause\" 6 seconds ago Up k8s://kube-system/etcd-cka001 \u67e5\u770b\u5f53\u524d apiserver \u7684\u72b6\u6001\u3002 0c5e69118f1b registry.aliyuncs.com/google_containers/kube-apiserver:v1.24.0 \"kube-apiserver --ad\u2026\" 32 hours ago Created k8s://kube-system/kube-apiserver-cka001/kube-apiserver 281cf4c6670d registry.aliyuncs.com/google_containers/kube-apiserver:v1.24.0 \"kube-apiserver --ad\u2026\" 14 seconds ago Up k8s://kube-system/kube-apiserver-cka001/kube-apiserver 5ed8295d92da registry.aliyuncs.com/google_containers/pause:3.6 \"/pause\" 15 seconds ago Up k8s://kube-system/kube-apiserver-cka001 638bb602c310 registry.aliyuncs.com/google_containers/pause:3.6 \"/pause\" 32 hours ago Created k8s://kube-system/kube-apiserver-cka001","title":"\u542f\u52a8\u670d\u52a1Services"},{"location":"k8s/cka_cn/foundamentals/clustermgt/#_1","text":"\u68c0\u67e5\u96c6\u7fa4\u7684\u72b6\u6001\uff0c\u67e5\u770b\u662f\u5426pod app-before-backup \u5b58\u5728\u3002 kubectl get deploy \u8fd0\u884c\u7ed3\u679c\uff1a NAME READY UP-TO-DATE AVAILABLE AGE app-before-backup 1/1 1 1 11m","title":"\u9a8c\u8bc1"},{"location":"k8s/cka_cn/foundamentals/clustermgt/#_2","text":"\u6f14\u793a\u573a\u666f\uff1a\u96c6\u7fa4\u5347\u7ea7 \u9a71\u9010\u63a7\u5236\u5e73\u9762\u8282\u70b9 \u68c0\u67e5\u5f53\u524d\u53ef\u7528\u7684 kubeadm \u7248\u672c \u5c06 kubeadm \u5347\u7ea7\u5230\u65b0\u7248\u672c \u68c0\u67e5\u5347\u7ea7\u8ba1\u5212 \u5e94\u7528\u5347\u7ea7\u8ba1\u5212\u4ee5\u5347\u7ea7\u5230\u65b0\u7248\u672c \u5347\u7ea7 kubelet \u548c kubectl \u542f\u7528\u63a7\u5236\u5e73\u9762\u8282\u70b9\u8c03\u5ea6 \u9a71\u9010\u5de5\u4f5c\u8282\u70b9 \u5347\u7ea7 kubeadm \u548c kubelet \u542f\u7528\u5de5\u4f5c\u8282\u70b9\u8c03\u5ea6 \u53c2\u8003\uff1a kubeadm\u5347\u7ea7","title":"\u96c6\u7fa4\u5347\u7ea7"},{"location":"k8s/cka_cn/foundamentals/clustermgt/#_3","text":"","title":"\u5347\u7ea7\u63a7\u5236\u5e73\u9762"},{"location":"k8s/cka_cn/foundamentals/clustermgt/#_4","text":"\u9a71\u9010\u63a7\u5236\u5e73\u9762\u8282\u70b9\u3002 kubectl drain --ignore-daemonsets \u8fd9\u91cc\u662f\uff1a kubectl drain cka001 --ignore-daemonsets \u8fd0\u884c\u7ed3\u679c\uff1a node/cka001 cordoned WARNING: ignoring DaemonSet-managed Pods: kube-system/calico-node-dsx76, kube-system/kube-proxy-cm4hc evicting pod kube-system/calico-kube-controllers-5c64b68895-jr4nl evicting pod kube-system/coredns-6d8c4cb4d-g4jxc evicting pod kube-system/coredns-6d8c4cb4d-sqcvj pod/calico-kube-controllers-5c64b68895-jr4nl evicted pod/coredns-6d8c4cb4d-g4jxc evicted pod/coredns-6d8c4cb4d-sqcvj evicted node/cka001 drained \u63a7\u5236\u5e73\u9762\u8282\u70b9\u73b0\u5728\u5904\u4e8e SchedulingDisabled \u72b6\u6001\u3002 kubectl get node -owide \u8fd0\u884c\u7ed3\u679c\uff1a NAME STATUS ROLES AGE VERSION OS-IMAGE KERNEL-VERSION CONTAINER-RUNTIME cka001 Ready,SchedulingDisabled control-plane,master 32h v1.24.0 Ubuntu 20.04.4 LTS 5.4.0-122-generic containerd://1.5.9 cka002 Ready 32h v1.24.0 Ubuntu 20.04.4 LTS 5.4.0-122-generic containerd://1.5.9 cka003 Ready 32h v1.24.0 Ubuntu 20.04.4 LTS 5.4.0-122-generic containerd://1.5.9 \u67e5\u8be2\u5f53\u524d kubeadm \u53ef\u7528\u7248\u672c\u3002 apt policy kubeadm \u8f93\u51fa\u7ed3\u679c\uff1a kubeadm: Installed: 1.24.0-00 Candidate: 1.24.3-00 Version table: 1.24.3-00 500 500 https://mirrors.aliyun.com/kubernetes/apt kubernetes-xenial/main amd64 Packages 1.24.2-00 500 500 https://mirrors.aliyun.com/kubernetes/apt kubernetes-xenial/main amd64 Packages 1.24.1-00 500 500 https://mirrors.aliyun.com/kubernetes/apt kubernetes-xenial/main amd64 Packages 1.24.0-00 500 500 https://mirrors.aliyun.com/kubernetes/apt kubernetes-xenial/main amd64 Packages 1.24.2-00 500 500 https://mirrors.aliyun.com/kubernetes/apt kubernetes-xenial/main amd64 Packages *** 1.24.0-00 500 500 https://mirrors.aliyun.com/kubernetes/apt kubernetes-xenial/main amd64 Packages 100 /var/lib/dpkg/status 1.23.7-00 500 500 https://mirrors.aliyun.com/kubernetes/apt kubernetes-xenial/main amd64 Packages ...... \u5347\u7ea7 kubeadm \u5230 Candidate: 1.24.2-00 \u7248\u672c\u3002 sudo apt-get -y install kubeadm = 1 .24.2-00 --allow-downgrades \u67e5\u8be2\u5347\u7ea7\u8ba1\u5212\u3002 kubeadm upgrade plan \u8f93\u51fa\u7c7b\u4f3c\u4e0b\u9762\u7684\u5347\u7ea7\u8ba1\u5212\u3002 [upgrade/config] Making sure the configuration is correct: [upgrade/config] Reading configuration from the cluster... [upgrade/config] FYI: You can look at this config file with 'kubectl -n kube-system get cm kubeadm-config -o yaml' [preflight] Running pre-flight checks. [upgrade] Running cluster health checks [upgrade] Fetching available versions to upgrade to [upgrade/versions] Cluster version: v1.24.0 [upgrade/versions] kubeadm version: v1.24.2 I0724 19:05:00.111855 1142460 version.go:255] remote version is much newer: v1.24.3; falling back to: stable-1.23 [upgrade/versions] Target version: v1.24.2 [upgrade/versions] Latest version in the v1.23 series: v1.24.2 Components that must be upgraded manually after you have upgraded the control plane with 'kubeadm upgrade apply': COMPONENT CURRENT TARGET kubelet 3 x v1.24.0 v1.24.2 Upgrade to the latest version in the v1.23 series: COMPONENT CURRENT TARGET kube-apiserver v1.24.0 v1.24.2 kube-controller-manager v1.24.0 v1.24.2 kube-scheduler v1.24.0 v1.24.2 kube-proxy v1.24.0 v1.24.2 CoreDNS v1.8.6 v1.8.6 etcd 3.5.1-0 3.5.1-0 You can now apply the upgrade by executing the following command: kubeadm upgrade apply v1.24.2 _____________________________________________________________________ The table below shows the current state of component configs as understood by this version of kubeadm. Configs that have a \"yes\" mark in the \"MANUAL UPGRADE REQUIRED\" column require manual config upgrade or resetting to kubeadm defaults before a successful upgrade can be performed. The version to manually upgrade to is denoted in the \"PREFERRED VERSION\" column. API GROUP CURRENT VERSION PREFERRED VERSION MANUAL UPGRADE REQUIRED kubeproxy.config.k8s.io v1alpha1 v1alpha1 no kubelet.config.k8s.io v1beta1 v1beta1 no _____________________________________________________________________","title":"\u63a7\u5236\u5e73\u9762\u51c6\u5907"},{"location":"k8s/cka_cn/foundamentals/clustermgt/#_5","text":"\u53c2\u8003\u524d\u9762\u7684\u5347\u7ea7\u8ba1\u5212\uff0c\u6211\u4eec\u5347\u7ea7\u5230 v1.24.2 \u7248\u672c\u3002 kubeadm upgrade apply v1.24.2 \u901a\u8fc7\u9009\u9879 --etcd-upgrade=false \uff0c\u6211\u4eec\u628a etcd \u6392\u9664\u51fa\u5f53\u524d\u5347\u7ea7\u8303\u56f4\u3002 kubeadm upgrade apply v1.24.2 --etcd-upgrade = false \u6536\u5230\u4e0b\u9762\u7684\u4fe1\u606f\uff0c\u5219\u4ee3\u8868\u4e0a\u9762\u7684\u5347\u7ea7\u547d\u4ee4\u6210\u529f\u4e86\u3002 [upgrade/successful] SUCCESS! Your cluster was upgraded to \"v1.24.2\". Enjoy! [upgrade/kubelet] Now that your control plane is upgraded, please proceed with upgrading your kubelets if you haven't already done so. \u5347\u7ea7 kubelet \u548c kubectl \u3002 sudo apt-get -y install kubelet = 1 .24.2-00 kubectl = 1 .24.2-00 --allow-downgrades sudo systemctl daemon-reload sudo systemctl restart kubelet \u67e5\u8be2\u8282\u70b9\u5f53\u524d\u72b6\u6001\u3002 kubectl get node \u8fd0\u884c\u7ed3\u679c\uff1a NAME STATUS ROLES AGE VERSION cka001 Ready,SchedulingDisabled control-plane,master 32h v1.24.2 cka002 Ready 32h v1.24.0 cka003 Ready 32h v1.24.0 After verify that each node is in Ready status, enable node scheduling. \u5728\u786e\u8ba4\u6240\u6709\u8282\u70b9\u90fd\u5904\u4e8eReady\u72b6\u6001\uff0c\u5219\u6fc0\u6d3bscheduling\u3002 kubectl uncordon \u8fd9\u91cc\u662f\uff1a kubectl uncordon cka001 \u8f93\u51fa\u7ed3\u679c\uff1a node/cka001 uncordoned \u518d\u6b21\u68c0\u67e5\u8282\u70b9\u72b6\u6001\uff0c\u786e\u4fdd\u6240\u6709\u8282\u70b9\u90fd\u5904\u4e8eReady\u72b6\u6001\u3002 kubectl get node \u8fd0\u884c\u7ed3\u679c\uff1a NAME STATUS ROLES AGE VERSION cka001 Ready control-plane,master 32h v1.24.2 cka002 Ready 32h v1.24.0 cka003 Ready 32h v1.24.0","title":"\u63a7\u5236\u5e73\u9762\u5347\u7ea7"},{"location":"k8s/cka_cn/foundamentals/clustermgt/#_6","text":"","title":"\u5347\u7ea7\u5de5\u4f5c\u8282\u70b9"},{"location":"k8s/cka_cn/foundamentals/clustermgt/#_7","text":"\u767b\u5f55\u8282\u70b9 cka001 \u3002 \u9a71\u9010 Worker \u8282\u70b9\uff0c\u9700\u8981\u663e\u5f0f\u6307\u5b9a\u662f\u5426\u5220\u9664\u672c\u5730\u5b58\u50a8\u3002 kubectl drain --ignore-daemonsets --force kubectl drain --ignore-daemonsets --delete-emptydir-data --force \u5982\u679c\u9047\u5230\u5173\u4e8e emptydir \u4f9d\u8d56\u7684\u9519\u8bef\uff0c\u5219\u6267\u884c\u7b2c\u4e8c\u4e2a\u547d\u4ee4\u3002 kubectl drain cka002 --ignore-daemonsets --force kubectl drain cka002 --ignore-daemonsets --delete-emptydir-data --force \u8f93\u51fa\u7ed3\u679c\uff1a node/cka002 cordoned WARNING: deleting Pods not managed by ReplicationController, ReplicaSet, Job, DaemonSet or StatefulSet: dev/ubuntu; ignoring DaemonSet-managed Pods: kube-system/calico-node-p5rf2, kube-system/kube-proxy-zvs68 evicting pod ns-netpol/pod-netpol-5b67b6b496-2cgnw evicting pod dev/ubuntu evicting pod dev/app-before-backup-66dc9d5cb-6xc8c evicting pod dev/nfs-client-provisioner-86d7fb78b6-2f5dx evicting pod dev/pod-netpol-2-77478d77ff-l6rzm evicting pod ingress-nginx/ingress-nginx-admission-patch-nk9fv evicting pod ingress-nginx/ingress-nginx-admission-create-lgtdj evicting pod kube-system/coredns-6d8c4cb4d-l4kx4 pod/ingress-nginx-admission-create-lgtdj evicted pod/ingress-nginx-admission-patch-nk9fv evicted pod/nfs-client-provisioner-86d7fb78b6-2f5dx evicted pod/app-before-backup-66dc9d5cb-6xc8c evicted pod/coredns-6d8c4cb4d-l4kx4 evicted pod/pod-netpol-5b67b6b496-2cgnw evicted pod/pod-netpol-2-77478d77ff-l6rzm evicted pod/ubuntu evicted node/cka002 drained","title":"\u5de5\u4f5c\u8282\u70b9\u51c6\u5907"},{"location":"k8s/cka_cn/foundamentals/clustermgt/#_8","text":"\u767b\u5f55\u8282\u70b9 cka002 \u3002 \u4e0b\u8f7d kubeadm \u7684 v1.24.2 \u7248\u672c\u3002 sudo apt-get -y install kubeadm = 1 .24.2-00 --allow-downgrades \u5347\u7ea7 kubeadm \u3002 sudo kubeadm upgrade node \u5347\u7ea7 kubelet \u3002 sudo apt-get -y install kubelet = 1 .24.2-00 --allow-downgrades sudo systemctl daemon-reload sudo systemctl restart kubelet \u786e\u8ba4\u6240\u6709\u8282\u70b9\u90fd\u5904\u4e8eReady\u72b6\u6001\uff0c\u5219\u6fc0\u6d3bscheduling\u3002 kubectl uncordon \u8fd9\u91cc\u662f\uff1a kubectl uncordon cka002","title":"\u5de5\u4f5c\u8282\u70b9\u5347\u7ea7"},{"location":"k8s/cka_cn/foundamentals/clustermgt/#_9","text":"\u67e5\u8be2\u8282\u70b9\u72b6\u6001\u3002 kubectl get node \u8fd0\u884c\u7ed3\u679c\uff1a NAME STATUS ROLES AGE VERSION cka001 Ready control-plane,master 32h v1.24.2 cka002 Ready 32h v1.24.2 cka003 Ready 32h v1.24.0 \u5728\u8282\u70b9 cka003 \u4e0a\u91cd\u590d\u4e0a\u9762\u7684\u6b65\u9aa4\u3002 \u767b\u5f55\u8282\u70b9 cka003 \u3002\u5982\u679c\u9047\u5230\u5173\u4e8e emptydir \u4f9d\u8d56\u7684\u9519\u8bef\uff0c\u5219\u6267\u884c\u7b2c\u4e8c\u4e2a\u547d\u4ee4\u3002 kubectl drain cka003 --ignore-daemonsets --ignore-daemonsets --force kubectl drain cka003 --ignore-daemonsets --ignore-daemonsets --delete-emptydir-data --force \u767b\u5f55\u8282\u70b9 cka003 \uff0c\u6267\u884c\u4e0b\u9762\u7684\u547d\u4ee4\u3002 sudo apt-get -y install kubeadm = 1 .24.2-00 --allow-downgrades sudo kubeadm upgrade node sudo apt-get -y install kubelet = 1 .24.2-00 --allow-downgrades sudo systemctl daemon-reload sudo systemctl restart kubelet kubectl get node kubectl uncordon cka003 \u67e5\u8be2\u8282\u70b9\u72b6\u6001\u3002 kubectl get node \u8fd0\u884c\u7ed3\u679c\uff1a NAME STATUS ROLES AGE VERSION cka001 Ready control-plane,master 32h v1.24.2 cka002 Ready 32h v1.24.2 cka003 Ready 32h v1.24.2","title":"\u5de5\u4f5c\u8282\u70b9\u9a8c\u8bc1"},{"location":"k8s/cka_cn/foundamentals/clustermgt/#_10","text":"\u5728\u63a7\u5236\u9762\u677f\u4e0a\u7684\u6267\u884c\u6b65\u9aa4\uff1a kubectl get node -owide kubectl drain cka001 --ignore-daemonsets kubectl get node -owide apt policy kubeadm apt-get -y install kubeadm = 1 .24.0-00 --allow-downgrades kubeadm upgrade plan kubeadm upgrade apply v1.24.0 # kubeadm upgrade apply v1.24.0 --etcd-upgrade=false apt-get -y install kubelet = 1 .24.0-00 kubectl = 1 .24.0-00 --allow-downgrades systemctl daemon-reload systemctl restart kubelet kubectl get node kubectl uncordon cka001 \u5728\u5de5\u4f5c\u8282\u70b9\u4e0a\u7684\u6267\u884c\u6b65\u9aa4\uff1a \u5728\u63a7\u5236\u9762\u677f\u4e0a\uff1a kubectl drain cka002 --ignore-daemonsets \u5728\u5de5\u4f5c\u8282\u70b9\u4e0a\uff1a apt-get -y install kubeadm = 1 .24.1-00 --allow-downgrades kubeadm upgrade node apt-get -y install kubelet = 1 .24.1-00 --allow-downgrades systemctl daemon-reload systemctl restart kubelet kubectl uncordon cka002 \u5728\u5176\u4ed6\u5de5\u4f5c\u8282\u70b9\u4e0a\u91cd\u590d\u4e0a\u9762\u7684\u6b65\u9aa4\u3002","title":"\u603b\u7ed3"},{"location":"k8s/cka_cn/foundamentals/configuration/","text":"CKA\u81ea\u5b66\u7b14\u8bb015:Configuration \u00b6","title":"Configuration"},{"location":"k8s/cka_cn/foundamentals/configuration/#cka15configuration","text":"","title":"CKA\u81ea\u5b66\u7b14\u8bb015:Configuration"},{"location":"k8s/cka_cn/foundamentals/daemonset/","text":"CKA\u81ea\u5b66\u7b14\u8bb013:DaemonSet \u00b6 \u6f14\u793a\u573a\u666f \u00b6 \u521b\u5efa\u4e00\u4e2aDaemonSet \u521b\u5efa\u7684DaemonSet\u4f1a\u5728\u6bcf\u4e2anode\u8282\u70b9\u4e0a\u8fd0\u884c\u81ea\u5df1\u7684pod\u3002 \u6f14\u793a \u00b6 \u521b\u5efa DaemonSet daemonset-busybox \u3002 kubectl apply -f - << EOF apiVersion: apps/v1 kind: DaemonSet metadata: name: daemonset-busybox labels: app: daemonset-busybox spec: selector: matchLabels: app: daemonset-busybox template: metadata: labels: app: daemonset-busybox spec: tolerations: - key: node-role.kubernetes.io/control-plane effect: NoSchedule - key: node-role.kubernetes.io/master effect: NoSchedule containers: - name: busybox image: busybox:1.28 args: - sleep - \"10000\" EOF \u83b7\u53d6DaemonSet\u7684\u8fd0\u884c\u72b6\u6001\u3002 kubectl get daemonsets daemonset-busybox \u8fd0\u884c\u7ed3\u679c NAME DESIRED CURRENT READY UP-TO-DATE AVAILABLE NODE SELECTOR AGE daemonset-busybox 3 3 3 3 3 5m33s \u83b7\u53d6 DaemonSet \u7684 Pod \u7684\u72b6\u6001\u3002\u8fd9\u4e9bpod\u4f1a\u90e8\u7f72\u5728\u6bcf\u4e2a\u8282\u70b9node\u4e0a\u3002 kubectl get pod -o wide \u8fd0\u884c\u7ed3\u679c NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES daemonset-busybox-54cj5 1 /1 Running 0 44s 10 .244.102.4 cka003 daemonset-busybox-5tl55 1 /1 Running 0 44s 10 .244.228.197 cka001 daemonset-busybox-wg225 1 /1 Running 0 44s 10 .244.112.5 cka002 \u5220\u9664\u6240\u521b\u5efa\u7684\u8d44\u6e90\u3002 kubectl delete daemonset daemonset-busybox","title":"DaemonSet"},{"location":"k8s/cka_cn/foundamentals/daemonset/#cka13daemonset","text":"","title":"CKA\u81ea\u5b66\u7b14\u8bb013:DaemonSet"},{"location":"k8s/cka_cn/foundamentals/daemonset/#_1","text":"\u521b\u5efa\u4e00\u4e2aDaemonSet \u521b\u5efa\u7684DaemonSet\u4f1a\u5728\u6bcf\u4e2anode\u8282\u70b9\u4e0a\u8fd0\u884c\u81ea\u5df1\u7684pod\u3002","title":"\u6f14\u793a\u573a\u666f"},{"location":"k8s/cka_cn/foundamentals/daemonset/#_2","text":"\u521b\u5efa DaemonSet daemonset-busybox \u3002 kubectl apply -f - << EOF apiVersion: apps/v1 kind: DaemonSet metadata: name: daemonset-busybox labels: app: daemonset-busybox spec: selector: matchLabels: app: daemonset-busybox template: metadata: labels: app: daemonset-busybox spec: tolerations: - key: node-role.kubernetes.io/control-plane effect: NoSchedule - key: node-role.kubernetes.io/master effect: NoSchedule containers: - name: busybox image: busybox:1.28 args: - sleep - \"10000\" EOF \u83b7\u53d6DaemonSet\u7684\u8fd0\u884c\u72b6\u6001\u3002 kubectl get daemonsets daemonset-busybox \u8fd0\u884c\u7ed3\u679c NAME DESIRED CURRENT READY UP-TO-DATE AVAILABLE NODE SELECTOR AGE daemonset-busybox 3 3 3 3 3 5m33s \u83b7\u53d6 DaemonSet \u7684 Pod \u7684\u72b6\u6001\u3002\u8fd9\u4e9bpod\u4f1a\u90e8\u7f72\u5728\u6bcf\u4e2a\u8282\u70b9node\u4e0a\u3002 kubectl get pod -o wide \u8fd0\u884c\u7ed3\u679c NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES daemonset-busybox-54cj5 1 /1 Running 0 44s 10 .244.102.4 cka003 daemonset-busybox-5tl55 1 /1 Running 0 44s 10 .244.228.197 cka001 daemonset-busybox-wg225 1 /1 Running 0 44s 10 .244.112.5 cka002 \u5220\u9664\u6240\u521b\u5efa\u7684\u8d44\u6e90\u3002 kubectl delete daemonset daemonset-busybox","title":"\u6f14\u793a"},{"location":"k8s/cka_cn/foundamentals/deployment/","text":"CKA\u81ea\u5b66\u7b14\u8bb09:Deployment \u00b6 \u6458\u8981 \u00b6 \u4fee\u6539\u5df2\u6709\u7684Deployment\uff0c\u6bd4\u5982\uff0c\u589e\u52a0\u7aef\u53e3\u53f7\u7b49\u3002 \u6f14\u793a \u00b6 \u521b\u5efaDeployment nginx \u3002 kubectl create deployment nginx --image = nginx \u6267\u884c\u4ee5\u4e0b\u547d\u4ee4\u4ee5\u83b7\u53d6\u5e26\u6709\u7aef\u53e3\u53f7\u7684yaml\u6a21\u677f\u3002 \u9009\u9879 --port=8080 \u6307\u5b9a\u4e86\u8be5\u5bb9\u5668\u66b4\u9732\u7684\u7aef\u53e3\u53f7\u3002 kubectl create deployment nginx --image = nginx --port = 8080 --dry-run = client -o yaml \u8fd9\u6837\u6211\u4eec\u5c31\u77e5\u9053\u4e86\u6dfb\u52a0\u7aef\u53e3\u53f7\u7684\u8def\u5f84\uff0c\u5c31\u50cf\u4e0b\u9762\u8fd9\u6837\uff1a kubectl explain deployment.spec.template.spec.containers.ports.containerPort \u6267\u884c\u4e0b\u9762\u7684\u547d\u4ee4\u6765\u4fee\u6539\u5f53\u524d\u6b63\u5728\u8fd0\u884c\u7684Deployment\u3002 kubectl edit deployment nginx \u6dfb\u52a0\u4e0b\u97622\u884c\u6765\u5236\u5b9a 8080 \u7aef\u53e3\u548c TCP \u534f\u8bae\u3002 spec : template : spec : containers : - image : nginx name : nginx ports : - containerPort : 8080 protocol : TCP \u901a\u8fc7\u547d\u4ee4 kubectl describe deployment \u6211\u4eec\u53ef\u4ee5\u770b\u5230\u5728Deployment\u4e2d\u7aef\u53e3\u53f7\u548c\u534f\u8bae\u5df2\u7ecf\u88ab\u6b63\u786e\u6dfb\u52a0\u4e86\u3002 Pod Template : Labels : app=nginx Containers : nginx : Image : nginx Port : 8080/TCP Host Port : 0/TCP Environment : Mounts : Volumes : \u901a\u8fc7\u547d\u4ee4 kubectl describe pod \u6211\u4eec\u53ef\u4ee5\u770b\u5230\u5728pod\u4e2d\u7aef\u53e3\u53f7\u548c\u534f\u8bae\u5df2\u7ecf\u88ab\u6b63\u786e\u6dfb\u52a0\u4e86\u3002 Containers : nginx : Container ID : containerd://af4a1243f981497074b5c006ac55fcf795688399871d1dfe91a095321f5c91aa Image : nginx Image ID : docker.io/library/nginx@sha256:1761fb5661e4d77e107427d8012ad3a5955007d997e0f4a3d41acc9ff20467c7 Port : 8080/TCP Host Port : 0/TCP State : Running Started : Sun, 24 Jul 2022 22:50:12 +0800 Ready : True Restart Count : 0 Environment : Mounts : /var/run/secrets/kubernetes.io/serviceaccount from kube-api-access-hftdt (ro) \u4ee5\u4e0b\u662fDeployment\u7684\u4e00\u4e9b\u5173\u952e\u5b57\u6bb5\uff08\u4f7f\u7528 kubectl explain \uff09\uff1a deployment.spec.revisionHistoryLimit \uff1a\u4fdd\u7559\u65e7\u7684 ReplicaSets \u7684\u6570\u91cf\uff0c\u4ee5\u4fbf\u8fdb\u884c\u56de\u6eda\u3002\u9ed8\u8ba4\u4e3a 10 \u3002 deployment.spec.strategy.type \uff1a\u90e8\u7f72\u7684\u7c7b\u578b\u3002\u53ef\u4ee5\u662f Recreate \u6216 RollingUpdate \u3002\u9ed8\u8ba4\u4e3a RollingUpdate \u3002 deployment.spec.strategy.rollingUpdate.maxUnavailable \uff1a\u5728\u66f4\u65b0\u671f\u95f4\u53ef\u4ee5\u4e0d\u53ef\u7528\u7684Pod\u7684\u6700\u5927\u6570\u91cf\u3002\u9ed8\u8ba4\u4e3a 25\uff05 \u3002 deployment.spec.strategy.rollingUpdate.maxSurge \uff1a\u53ef\u4ee5\u5b89\u6392\u7684Pod\u6570\u91cf\u8d85\u51fa\u6240\u9700Pod\u6570\u91cf\u7684\u6700\u5927\u503c\u3002\u9ed8\u8ba4\u4e3a 25\uff05 \u3002\u5982\u679c MaxUnavailable \u4e3a 0 \uff0c\u5219\u6b64\u503c\u4e0d\u80fd\u4e3a 0 \u3002 deployment.spec.minReadySeconds \uff1a\u65b0\u521b\u5efa\u7684Pod\u7684\u6700\u5c0f\u51c6\u5907\u65f6\u95f4\uff08\u6240\u6709\u5bb9\u5668\u90fd\u6ca1\u6709\u5d29\u6e83\uff09\uff0c\u4ee5\u4fbf\u88ab\u89c6\u4e3a\u53ef\u7528\u3002\u9ed8\u8ba4\u4e3a 0 \uff08\u4e00\u65e6\u51c6\u5907\u597d\u5c31\u4f1a\u88ab\u89c6\u4e3a\u53ef\u7528\uff09\u3002","title":"Deployment"},{"location":"k8s/cka_cn/foundamentals/deployment/#cka9deployment","text":"","title":"CKA\u81ea\u5b66\u7b14\u8bb09:Deployment"},{"location":"k8s/cka_cn/foundamentals/deployment/#_1","text":"\u4fee\u6539\u5df2\u6709\u7684Deployment\uff0c\u6bd4\u5982\uff0c\u589e\u52a0\u7aef\u53e3\u53f7\u7b49\u3002","title":"\u6458\u8981"},{"location":"k8s/cka_cn/foundamentals/deployment/#_2","text":"\u521b\u5efaDeployment nginx \u3002 kubectl create deployment nginx --image = nginx \u6267\u884c\u4ee5\u4e0b\u547d\u4ee4\u4ee5\u83b7\u53d6\u5e26\u6709\u7aef\u53e3\u53f7\u7684yaml\u6a21\u677f\u3002 \u9009\u9879 --port=8080 \u6307\u5b9a\u4e86\u8be5\u5bb9\u5668\u66b4\u9732\u7684\u7aef\u53e3\u53f7\u3002 kubectl create deployment nginx --image = nginx --port = 8080 --dry-run = client -o yaml \u8fd9\u6837\u6211\u4eec\u5c31\u77e5\u9053\u4e86\u6dfb\u52a0\u7aef\u53e3\u53f7\u7684\u8def\u5f84\uff0c\u5c31\u50cf\u4e0b\u9762\u8fd9\u6837\uff1a kubectl explain deployment.spec.template.spec.containers.ports.containerPort \u6267\u884c\u4e0b\u9762\u7684\u547d\u4ee4\u6765\u4fee\u6539\u5f53\u524d\u6b63\u5728\u8fd0\u884c\u7684Deployment\u3002 kubectl edit deployment nginx \u6dfb\u52a0\u4e0b\u97622\u884c\u6765\u5236\u5b9a 8080 \u7aef\u53e3\u548c TCP \u534f\u8bae\u3002 spec : template : spec : containers : - image : nginx name : nginx ports : - containerPort : 8080 protocol : TCP \u901a\u8fc7\u547d\u4ee4 kubectl describe deployment \u6211\u4eec\u53ef\u4ee5\u770b\u5230\u5728Deployment\u4e2d\u7aef\u53e3\u53f7\u548c\u534f\u8bae\u5df2\u7ecf\u88ab\u6b63\u786e\u6dfb\u52a0\u4e86\u3002 Pod Template : Labels : app=nginx Containers : nginx : Image : nginx Port : 8080/TCP Host Port : 0/TCP Environment : Mounts : Volumes : \u901a\u8fc7\u547d\u4ee4 kubectl describe pod \u6211\u4eec\u53ef\u4ee5\u770b\u5230\u5728pod\u4e2d\u7aef\u53e3\u53f7\u548c\u534f\u8bae\u5df2\u7ecf\u88ab\u6b63\u786e\u6dfb\u52a0\u4e86\u3002 Containers : nginx : Container ID : containerd://af4a1243f981497074b5c006ac55fcf795688399871d1dfe91a095321f5c91aa Image : nginx Image ID : docker.io/library/nginx@sha256:1761fb5661e4d77e107427d8012ad3a5955007d997e0f4a3d41acc9ff20467c7 Port : 8080/TCP Host Port : 0/TCP State : Running Started : Sun, 24 Jul 2022 22:50:12 +0800 Ready : True Restart Count : 0 Environment : Mounts : /var/run/secrets/kubernetes.io/serviceaccount from kube-api-access-hftdt (ro) \u4ee5\u4e0b\u662fDeployment\u7684\u4e00\u4e9b\u5173\u952e\u5b57\u6bb5\uff08\u4f7f\u7528 kubectl explain \uff09\uff1a deployment.spec.revisionHistoryLimit \uff1a\u4fdd\u7559\u65e7\u7684 ReplicaSets \u7684\u6570\u91cf\uff0c\u4ee5\u4fbf\u8fdb\u884c\u56de\u6eda\u3002\u9ed8\u8ba4\u4e3a 10 \u3002 deployment.spec.strategy.type \uff1a\u90e8\u7f72\u7684\u7c7b\u578b\u3002\u53ef\u4ee5\u662f Recreate \u6216 RollingUpdate \u3002\u9ed8\u8ba4\u4e3a RollingUpdate \u3002 deployment.spec.strategy.rollingUpdate.maxUnavailable \uff1a\u5728\u66f4\u65b0\u671f\u95f4\u53ef\u4ee5\u4e0d\u53ef\u7528\u7684Pod\u7684\u6700\u5927\u6570\u91cf\u3002\u9ed8\u8ba4\u4e3a 25\uff05 \u3002 deployment.spec.strategy.rollingUpdate.maxSurge \uff1a\u53ef\u4ee5\u5b89\u6392\u7684Pod\u6570\u91cf\u8d85\u51fa\u6240\u9700Pod\u6570\u91cf\u7684\u6700\u5927\u503c\u3002\u9ed8\u8ba4\u4e3a 25\uff05 \u3002\u5982\u679c MaxUnavailable \u4e3a 0 \uff0c\u5219\u6b64\u503c\u4e0d\u80fd\u4e3a 0 \u3002 deployment.spec.minReadySeconds \uff1a\u65b0\u521b\u5efa\u7684Pod\u7684\u6700\u5c0f\u51c6\u5907\u65f6\u95f4\uff08\u6240\u6709\u5bb9\u5668\u90fd\u6ca1\u6709\u5d29\u6e83\uff09\uff0c\u4ee5\u4fbf\u88ab\u89c6\u4e3a\u53ef\u7528\u3002\u9ed8\u8ba4\u4e3a 0 \uff08\u4e00\u65e6\u51c6\u5907\u597d\u5c31\u4f1a\u88ab\u89c6\u4e3a\u53ef\u7528\uff09\u3002","title":"\u6f14\u793a"},{"location":"k8s/cka_cn/foundamentals/docker/","text":"CKA\u81ea\u5b66\u7b14\u8bb04:Docker\u57fa\u7840 \u00b6 \u6458\u8981 \u00b6 \u4e86\u89e3Linux\u539f\u8bed\u7684\u6982\u5ff5\u548c\u5305\u542b\u7684\u7279\u6027\u3002 \u5b89\u88c5Docker\uff0c\u4e86\u89e3\u57fa\u672c\u7684Docker\u547d\u4ee4\u548cDockerfile\u7684\u4f7f\u7528\u3002 \u7ec3\u4e60\u73af\u5883 \u00b6 \u64cd\u4f5c\u7cfb\u7edf\uff1aopenSUSE 15.3 cat /etc/os-release \u8f93\u51fa\u7ed3\u679c\uff1a NAME=\"openSUSE Leap\" VERSION=\"15.3\" ID=\"opensuse-leap\" ID_LIKE=\"suse opensuse\" VERSION_ID=\"15.3\" PRETTY_NAME=\"openSUSE Leap 15.3\" ANSI_COLOR=\"0;32\" CPE_NAME=\"cpe:/o:opensuse:leap:15.3\" BUG_REPORT_URL=\"https://bugs.opensuse.org\" HOME_URL=\"https://www.opensuse.org/\" Linux\u539f\u8bed \u00b6 \u5728\u64cd\u4f5c\u7cfb\u7edf\u4e2d\uff0c\u539f\u8bed\uff08primitives\uff09\u662f\u7528\u4e8e\u521b\u5efa\u66f4\u590d\u6742\u529f\u80fd\u7684\u57fa\u672c\u6784\u5efa\u5757\u6216\u64cd\u4f5c\u3002\u5728Linux\u4e2d\uff0c\u6709\u51e0\u79cd\u5e38\u7528\u7684\u539f\u8bed\u3002\u5305\u62ec\uff1a \u8fdb\u7a0b\uff08Processes\uff09\uff1a\u8fdb\u7a0b\u662f\u7a0b\u5e8f\u6216\u5e94\u7528\u7a0b\u5e8f\u7684\u8fd0\u884c\u5b9e\u4f8b\u3002\u5b83\u4eec\u662fLinux\u4e2d\u7684\u57fa\u672c\u5de5\u4f5c\u5355\u5143\uff0c\u7531\u5185\u6838\u7ba1\u7406\u3002 \u6587\u4ef6\uff08Files\uff09\uff1a\u6587\u4ef6\u662f\u5728Linux\u4e2d\u5b58\u50a8\u6570\u636e\u7684\u4e3b\u8981\u65b9\u5f0f\u3002\u5b83\u4eec\u53ef\u4ee5\u662f\u6587\u672c\u6587\u4ef6\u3001\u4e8c\u8fdb\u5236\u6587\u4ef6\u3001\u76ee\u5f55\u6216\u7279\u6b8a\u6587\u4ef6\uff0c\u5982\u8bbe\u5907\u6587\u4ef6\u3002 \u4fe1\u53f7\uff08Signals\uff09\uff1a\u4fe1\u53f7\u662f\u8fdb\u7a0b\u4e4b\u95f4\u6216\u8fdb\u7a0b\u4e0e\u5185\u6838\u4e4b\u95f4\u901a\u4fe1\u7684\u4e00\u79cd\u65b9\u5f0f\u3002\u5b83\u4eec\u7528\u4e8e\u901a\u77e5\u8fdb\u7a0b\u4e8b\u4ef6\uff0c\u4f8b\u5982\u4efb\u52a1\u5b8c\u6210\u6216\u9519\u8bef\u53d1\u751f\u7684\u60c5\u51b5\u3002 \u5957\u63a5\u5b57\uff08Sockets\uff09\uff1a\u5957\u63a5\u5b57\u662fLinux\u4e2d\u8fdb\u7a0b\u95f4\u901a\u4fe1\u7684\u4e00\u79cd\u65b9\u5f0f\u3002\u5b83\u4eec\u5141\u8bb8\u8fdb\u7a0b\u5728\u7f51\u7edc\u6216\u672c\u5730\u673a\u5668\u4e0a\u53d1\u9001\u548c\u63a5\u6536\u6570\u636e\u3002 \u7ebf\u7a0b\uff08Threads\uff09\uff1a\u7ebf\u7a0b\u662f\u8f7b\u91cf\u7ea7\u7684\u8fdb\u7a0b\uff0c\u4e0e\u5176\u7236\u8fdb\u7a0b\u5171\u4eab\u76f8\u540c\u7684\u5185\u5b58\u7a7a\u95f4\u548c\u8d44\u6e90\u3002\u5b83\u4eec\u901a\u5e38\u7528\u4e8e\u901a\u8fc7\u5141\u8bb8\u540c\u65f6\u6267\u884c\u591a\u4e2a\u4efb\u52a1\u6765\u63d0\u9ad8\u5e94\u7528\u7a0b\u5e8f\u7684\u6027\u80fd\u3002 \u7ba1\u9053\uff08Pipes\uff09\uff1a\u7ba1\u9053\u662f\u4e00\u79cd\u5c06\u4e00\u4e2a\u8fdb\u7a0b\u7684\u8f93\u51fa\u8fde\u63a5\u5230\u53e6\u4e00\u4e2a\u8fdb\u7a0b\u7684\u8f93\u5165\u7684\u65b9\u5f0f\u3002\u5b83\u4eec\u5141\u8bb8\u8fdb\u7a0b\u4ee5\u53d7\u63a7\u7684\u65b9\u5f0f\u8fdb\u884c\u901a\u4fe1\u548c\u4ea4\u6362\u6570\u636e\u3002 \u4fe1\u53f7\u91cf\uff08Semaphores\uff09\uff1a\u4fe1\u53f7\u91cf\u662fLinux\u4e2d\u63a7\u5236\u5bf9\u5171\u4eab\u8d44\u6e90\u8bbf\u95ee\u7684\u4e00\u79cd\u65b9\u5f0f\u3002\u5b83\u4eec\u5141\u8bb8\u8fdb\u7a0b\u534f\u8c03\u5b83\u4eec\u5bf9\u5171\u4eab\u8d44\u6e90\u7684\u8bbf\u95ee\uff0c\u5982\u6587\u4ef6\u6216\u5185\u5b58\u3002 chroot \u00b6 chroot\u4f7f\u7528pivot_root\uff0c\u4ee5\u5b9e\u73b0\u5c06*\u8fdb\u7a0b*\u7684\u6839\u76ee\u5f55\u66f4\u6539\u4e3a\u4efb\u4f55\u7ed9\u5b9a\u7684\u76ee\u5f55\u3002 a. \u6a21\u62df\u5bb9\u5668 \u4f7f\u7528 chroot \u547d\u4ee4\u53ef\u4ee5\u5728Linux\u7cfb\u7edf\u4e2d\u521b\u5efa\u4e00\u4e2a\u5bb9\u5668\u3002\u8be5\u5bb9\u5668\u53ef\u4ee5\u770b\u4f5c\u662f\u4e00\u4e2a\u865a\u62df\u7684\u6839\u6587\u4ef6\u7cfb\u7edf\uff0c\u5176\u4e2d\u8fd0\u884c\u7684\u8fdb\u7a0b\u53ea\u80fd\u8bbf\u95ee\u8be5\u6839\u6587\u4ef6\u7cfb\u7edf\u4e2d\u7684\u8d44\u6e90\u3002 \u4f8b\u5982\uff0c\u4ee5\u4e0b\u547d\u4ee4\u4f1a\u5c06\u5f53\u524d\u6839\u6587\u4ef6\u7cfb\u7edf\u66f4\u6539\u4e3a /tmp/myroot \u76ee\u5f55\uff1a chroot /tmp/myroot /bin/bash \u8fd9\u6761\u547d\u4ee4\u4f1a\u542f\u52a8\u4e00\u4e2a\u65b0\u7684Bash shell\uff0c\u8be5shell\u7684\u6839\u76ee\u5f55\u4e3a /tmp/myroot \u3002 b. \u66f4\u6539\u6839\u6587\u4ef6\u7cfb\u7edf chroot \u547d\u4ee4\u8fd8\u53ef\u7528\u4e8e\u66f4\u6539\u8fdb\u7a0b\u7684\u6839\u6587\u4ef6\u7cfb\u7edf\u3002\u4f8b\u5982\uff0c\u6211\u4eec\u53ef\u4ee5\u4f7f\u7528 chroot \u547d\u4ee4\u542f\u52a8\u4e00\u4e2a\u5177\u6709\u53e6\u4e00\u4e2a\u6839\u6587\u4ef6\u7cfb\u7edf\u7684\u8fdb\u7a0b\uff0c\u800c\u4e0d\u662f\u7cfb\u7edf\u7684\u9ed8\u8ba4\u6839\u6587\u4ef6\u7cfb\u7edf\u3002 \u4f8b\u5982\uff0c\u4ee5\u4e0b\u547d\u4ee4\u4f1a\u5c06\u5f53\u524d\u76ee\u5f55\uff08\u5373 ./ \uff09\u4f5c\u4e3a\u6839\u76ee\u5f55\uff0c\u5e76\u5728\u5176\u4e2d\u542f\u52a8\u4e00\u4e2a\u65b0\u7684Bash shell\uff1a sudo chroot . /bin/bash \u547d\u540d\u7a7a\u95f4 \u00b6 \u5728Linux\u64cd\u4f5c\u7cfb\u7edf\u4e2d\uff0cNamespace\uff08\u547d\u540d\u7a7a\u95f4\uff09\u662f\u4e00\u79cd\u673a\u5236\uff0c\u7528\u4e8e\u9694\u79bb\u4e0d\u540c\u8fdb\u7a0b\u7684\u8d44\u6e90\u3002\u901a\u8fc7Namespace\u673a\u5236\uff0c\u53ef\u4ee5\u5c06\u4e00\u7ec4\u8fdb\u7a0b\u53ca\u5176\u5b50\u8fdb\u7a0b\u7684\u89c6\u56fe\u9694\u79bb\u5728\u4e00\u4e2a\u72ec\u7acb\u7684Namespace\u4e2d\uff0c\u4ece\u800c\u5b9e\u73b0\u8fdb\u7a0b\u4e4b\u95f4\u8d44\u6e90\u9694\u79bb\u7684\u76ee\u7684\u3002 \u4e0b\u9762\u662f\u4e00\u4e9b\u5e38\u89c1\u7684Namespace\u7c7b\u578b\u53ca\u5176\u4f5c\u7528\uff1a Mount Namespace\uff1a\u9694\u79bb\u6587\u4ef6\u7cfb\u7edf\u6302\u8f7d\u70b9\u3002\u53ef\u4ee5\u4f7f\u4e0d\u540c\u8fdb\u7a0b\u62e5\u6709\u81ea\u5df1\u7684\u72ec\u7acb\u7684\u6587\u4ef6\u7cfb\u7edf\u89c6\u56fe\u3002 PID Namespace\uff1a\u9694\u79bb\u8fdb\u7a0bID\u53f7\u3002\u53ef\u4ee5\u4f7f\u4e0d\u540c\u8fdb\u7a0b\u62e5\u6709\u81ea\u5df1\u7684\u8fdb\u7a0bID\u53f7\u7a7a\u95f4\uff0c\u907f\u514d\u8fdb\u7a0b\u4e4b\u95f4\u7684PID\u51b2\u7a81\u3002 Network Namespace\uff1a\u9694\u79bb\u7f51\u7edc\u6808\u3002\u53ef\u4ee5\u4f7f\u4e0d\u540c\u8fdb\u7a0b\u62e5\u6709\u81ea\u5df1\u7684\u72ec\u7acb\u7684\u7f51\u7edc\u6808\uff0c\u4ece\u800c\u907f\u514d\u8fdb\u7a0b\u4e4b\u95f4\u7684\u7f51\u7edc\u51b2\u7a81\u3002 IPC Namespace\uff1a\u9694\u79bb\u8fdb\u7a0b\u95f4\u901a\u4fe1\uff08IPC\uff09\u673a\u5236\u3002\u53ef\u4ee5\u4f7f\u4e0d\u540c\u8fdb\u7a0b\u62e5\u6709\u81ea\u5df1\u7684\u72ec\u7acb\u7684IPC\u7a7a\u95f4\uff0c\u4ece\u800c\u907f\u514dIPC\u673a\u5236\u5e26\u6765\u7684\u8d44\u6e90\u7ade\u4e89\u3002 UTS Namespace\uff1a\u9694\u79bb\u4e3b\u673a\u540d\u548c\u57df\u540d\u3002\u53ef\u4ee5\u4f7f\u4e0d\u540c\u8fdb\u7a0b\u62e5\u6709\u81ea\u5df1\u7684\u72ec\u7acb\u7684\u4e3b\u673a\u540d\u548c\u57df\u540d\u7a7a\u95f4\uff0c\u4ece\u800c\u907f\u514d\u8fdb\u7a0b\u4e4b\u95f4\u7684\u547d\u540d\u51b2\u7a81\u3002 Primitives namespace\u548cNamespace\u662f\u4e24\u4e2a\u4e0d\u540c\u7684\u6982\u5ff5\u3002 Namespace\u662fLinux\u64cd\u4f5c\u7cfb\u7edf\u63d0\u4f9b\u7684\u4e00\u79cd\u673a\u5236\uff0c\u7528\u4e8e\u9694\u79bb\u4e0d\u540c\u8fdb\u7a0b\u7684\u8d44\u6e90\uff0c\u4ee5\u5b9e\u73b0\u8fdb\u7a0b\u4e4b\u95f4\u7684\u8d44\u6e90\u9694\u79bb\u548c\u73af\u5883\u9694\u79bb\u3002\u4f8b\u5982\uff0cPID Namespace\u53ef\u4ee5\u4f7f\u4e0d\u540c\u8fdb\u7a0b\u62e5\u6709\u81ea\u5df1\u7684\u72ec\u7acb\u7684PID\u53f7\u7a7a\u95f4\uff0c\u907f\u514d\u8fdb\u7a0b\u4e4b\u95f4\u7684PID\u51b2\u7a81\uff1bNetwork Namespace\u53ef\u4ee5\u4f7f\u4e0d\u540c\u8fdb\u7a0b\u62e5\u6709\u81ea\u5df1\u7684\u72ec\u7acb\u7684\u7f51\u7edc\u6808\uff0c\u4ece\u800c\u907f\u514d\u8fdb\u7a0b\u4e4b\u95f4\u7684\u7f51\u7edc\u51b2\u7a81\u7b49\u3002 Primitives namespace\u662f\u4e00\u79cd\u65b0\u7684\u6280\u672f\u6982\u5ff5\uff0c\u5b83\u662f\u6307\u5c06\u4e0d\u540c\u7684\u57fa\u672c\u64cd\u4f5c\uff08\u4f8b\u5982\u8bfb\u5199\u6587\u4ef6\u3001\u521b\u5efa\u8fdb\u7a0b\u3001\u7f51\u7edc\u901a\u4fe1\u7b49\uff09\u4f5c\u4e3a\u539f\u8bed\u8fdb\u884c\u9694\u79bb\u548c\u5c01\u88c5\uff0c\u4f7f\u5f97\u5e94\u7528\u7a0b\u5e8f\u53ef\u4ee5\u5728\u8fd9\u4e9b\u9694\u79bb\u7684\u539f\u8bed\u4e0a\u6784\u5efa\u51fa\u81ea\u5df1\u7684\u9694\u79bb\u73af\u5883\u3002\u4f8b\u5982\uff0c\u53ef\u4ee5\u901a\u8fc7\u9694\u79bb\u6587\u4ef6\u7cfb\u7edf\u8bfb\u5199\u64cd\u4f5c\u6765\u5b9e\u73b0\u5bb9\u5668\u7ea7\u522b\u7684\u6587\u4ef6\u7cfb\u7edf\u9694\u79bb\uff1b\u901a\u8fc7\u9694\u79bb\u7f51\u7edc\u901a\u4fe1\u64cd\u4f5c\u6765\u5b9e\u73b0\u5bb9\u5668\u7ea7\u522b\u7684\u7f51\u7edc\u9694\u79bb\u7b49\u3002 \u56e0\u6b64\uff0cNamespace\u548cPrimitives namespace\u662f\u4e24\u4e2a\u4e0d\u540c\u7684\u6982\u5ff5\uff0c\u867d\u7136\u5b83\u4eec\u90fd\u53ef\u4ee5\u7528\u4e8e\u5b9e\u73b0\u9694\u79bb\u548c\u5c01\u88c5\u7684\u529f\u80fd\uff0c\u4f46\u662fNamespace\u662f\u4e00\u79cd\u66f4\u4e3a\u901a\u7528\u548c\u5e95\u5c42\u7684\u673a\u5236\uff0cPrimitives namespace\u662f\u4e00\u79cd\u66f4\u4e3a\u9ad8\u5c42\u7684\u62bd\u8c61\u6982\u5ff5\uff0c\u901a\u5e38\u7528\u4e8e\u6784\u5efa\u5bb9\u5668\u7b49\u5e94\u7528\u7ea7\u522b\u7684\u9694\u79bb\u73af\u5883\u3002 Namespace\u793a\u4f8b\uff1a \u5728Linux\u7cfb\u7edf\u4e2d\uff0c\u53ef\u4ee5\u4f7f\u7528PID Namespace\u6765\u9694\u79bb\u8fdb\u7a0bID\u53f7\u7a7a\u95f4\uff0c\u907f\u514d\u8fdb\u7a0b\u4e4b\u95f4\u7684PID\u51b2\u7a81\u3002\u4e0b\u9762\u662f\u4e00\u4e2a\u7b80\u5355\u7684\u793a\u4f8b\uff1a # \u521b\u5efa\u4e00\u4e2a\u65b0\u7684PID Namespace unshare -p /bin/bash # \u5728\u65b0\u7684PID Namespace\u4e2d\u8fd0\u884c\u4e00\u4e2a\u8fdb\u7a0b echo $$ # \u663e\u793a\u5f53\u524d\u8fdb\u7a0b\u7684PID ps aux # \u663e\u793a\u5f53\u524d\u8fdb\u7a0b\u53ca\u5176\u5b50\u8fdb\u7a0b \u5728\u4e0a\u9762\u7684\u793a\u4f8b\u4e2d\uff0c unshare -p \u547d\u4ee4\u521b\u5efa\u4e86\u4e00\u4e2a\u65b0\u7684PID Namespace\uff0c\u5e76\u5728\u5176\u4e2d\u542f\u52a8\u4e86\u4e00\u4e2a\u65b0\u7684bash\u8fdb\u7a0b\u3002\u7531\u4e8e\u8be5\u8fdb\u7a0b\u8fd0\u884c\u5728\u4e00\u4e2a\u72ec\u7acb\u7684PID Namespace\u4e2d\uff0c\u56e0\u6b64\u5b83\u7684PID\u53f7\u4e0e\u4e3b\u673a\u4e0a\u7684\u5176\u4ed6\u8fdb\u7a0b\u4e0d\u4f1a\u51b2\u7a81\u3002\u5728\u8fd9\u4e2a\u65b0\u7684bash\u8fdb\u7a0b\u4e2d\uff0c $$ \u547d\u4ee4\u663e\u793a\u7684\u662f\u8be5\u8fdb\u7a0b\u5728PID Namespace\u4e2d\u7684PID\u53f7\uff0c\u800c ps aux \u547d\u4ee4\u53ea\u4f1a\u663e\u793a\u5f53\u524dPID Namespace\u4e2d\u7684\u8fdb\u7a0b\uff0c\u4e0d\u4f1a\u663e\u793a\u4e3b\u673a\u4e0a\u7684\u5176\u4ed6\u8fdb\u7a0b\u3002 Primitives Namespace\u793a\u4f8b\uff1a \u5728Docker\u5bb9\u5668\u4e2d\uff0c\u53ef\u4ee5\u4f7f\u7528Filesystem Namespace\u6765\u9694\u79bb\u6587\u4ef6\u7cfb\u7edf\uff0c\u4f7f\u5f97\u4e0d\u540c\u7684\u5bb9\u5668\u4e4b\u95f4\u62e5\u6709\u72ec\u7acb\u7684\u6587\u4ef6\u7cfb\u7edf\u89c6\u56fe\u3002\u4e0b\u9762\u662f\u4e00\u4e2a\u7b80\u5355\u7684\u793a\u4f8b\uff1a # \u5728\u5bb9\u5668\u4e2d\u8fd0\u884c\u4e00\u4e2a\u547d\u4ee4 docker run --rm -it --name mycontainer ubuntu bash # \u5728\u5bb9\u5668\u4e2d\u521b\u5efa\u4e00\u4e2a\u6587\u4ef6\u5e76\u9000\u51fa touch myfile exit # \u5728\u4e3b\u673a\u4e0a\u67e5\u770b\u6587\u4ef6 ls myfile # myfile\u6587\u4ef6\u4e0d\u5b58\u5728 # \u518d\u6b21\u8fdb\u5165\u5bb9\u5668 docker start -i mycontainer # \u5728\u5bb9\u5668\u4e2d\u67e5\u770b\u6587\u4ef6 ls myfile # myfile\u6587\u4ef6\u5b58\u5728 \u5728\u4e0a\u9762\u7684\u793a\u4f8b\u4e2d\uff0c docker run \u547d\u4ee4\u542f\u52a8\u4e86\u4e00\u4e2a\u65b0\u7684Docker\u5bb9\u5668\uff0c\u5e76\u5728\u5176\u4e2d\u8fd0\u884c\u4e86\u4e00\u4e2abash\u8fdb\u7a0b\u3002\u7531\u4e8e\u8be5\u5bb9\u5668\u4f7f\u7528\u4e86Filesystem Namespace\uff0c\u56e0\u6b64\u5bb9\u5668\u5185\u7684\u6587\u4ef6\u7cfb\u7edf\u89c6\u56fe\u4e0e\u4e3b\u673a\u4e0a\u7684\u6587\u4ef6\u7cfb\u7edf\u89c6\u56fe\u662f\u9694\u79bb\u7684\u3002\u5728\u5bb9\u5668\u5185\u521b\u5efa\u7684\u6587\u4ef6 myfile \u53ea\u5b58\u5728\u4e8e\u5bb9\u5668\u5185\u90e8\uff0c\u5728\u4e3b\u673a\u4e0a\u662f\u770b\u4e0d\u5230\u7684\u3002\u5f53\u518d\u6b21\u8fdb\u5165\u5bb9\u5668\u65f6\uff0c myfile \u6587\u4ef6\u5c31\u53ef\u4ee5\u88ab\u770b\u5230\u4e86\u3002 \u603b\u7ed3\uff1a Namespace\u662fLinux\u5185\u6838\u63d0\u4f9b\u7684\u673a\u5236\uff0c\u800cPrimitives Namespace\u5219\u662f\u4e00\u79cd\u57fa\u4e8eNamespace\u7684\u9ad8\u5c42\u62bd\u8c61\uff0c\u7528\u4e8e\u5b9e\u73b0\u5e94\u7528\u7ea7\u522b\u7684\u9694\u79bb\u548c\u5c01\u88c5\u3002Namespace\u53ef\u4ee5\u7528\u4e8e\u9694\u79bb\u591a\u79cd\u8d44\u6e90\uff0c\u800cPrimitives Namespace\u901a\u5e38\u7528\u4e8e\u9694\u79bb\u6587\u4ef6\u7cfb\u7edf\u3001\u7f51\u7edc\u3001\u8fdb\u7a0b\u7b49\u64cd\u4f5c\u7684\u539f\u8bed\u3002 \u63a7\u5236\u7ec4 \u00b6 cgroup\uff0c\u5168\u79f0\u4e3aControl Group\uff0c\u5373\u63a7\u5236\u7ec4\uff0c\u662fLinux\u5185\u6838\u63d0\u4f9b\u7684\u4e00\u79cd\u673a\u5236\uff0c\u7528\u4e8e\u9650\u5236\u3001\u8bb0\u5f55\u3001\u9694\u79bb\u548c\u4f18\u5148\u7ea7\u63a7\u5236\u4e00\u7ec4\u8fdb\u7a0b\u7684\u8d44\u6e90\u4f7f\u7528\u3002\u5b83\u53ef\u4ee5\u9650\u5236\u8fdb\u7a0b\u7ec4\u7684CPU\u3001\u5185\u5b58\u3001\u78c1\u76d8\u3001\u7f51\u7edc\u7b49\u8d44\u6e90\u7684\u4f7f\u7528\uff0c\u540c\u65f6\u4e5f\u53ef\u4ee5\u8bb0\u5f55\u8fdb\u7a0b\u7ec4\u7684\u8d44\u6e90\u4f7f\u7528\u60c5\u51b5\u548c\u884c\u4e3a\u3002 cgroup\u901a\u8fc7\u5c06\u4e00\u7ec4\u8fdb\u7a0b\u7ec4\u7ec7\u6210\u4e00\u4e2a\u5c42\u6b21\u7ed3\u6784\uff0c\u5c06\u8d44\u6e90\u5206\u914d\u7ed9\u4e0d\u540c\u7684cgroup\u6765\u5b9e\u73b0\u8d44\u6e90\u9650\u5236\u548c\u4f18\u5148\u7ea7\u63a7\u5236\u3002\u6bcf\u4e2acgroup\u53ef\u4ee5\u8bbe\u7f6e\u8d44\u6e90\u9650\u5236\u548c\u63a7\u5236\u7b56\u7565\uff0c\u4f8b\u5982\u53ef\u4ee5\u9650\u5236\u4e00\u4e2a\u8fdb\u7a0b\u7ec4\u6700\u591a\u4f7f\u752850%\u7684CPU\u65f6\u95f4\uff0c\u6216\u8005\u9650\u5236\u4e00\u4e2a\u8fdb\u7a0b\u7ec4\u6700\u591a\u4f7f\u7528100MB\u7684\u5185\u5b58\u7b49\u3002 cgroup\u6700\u521d\u7531Google\u516c\u53f8\u5f00\u53d1\uff0c\u540e\u6765\u88abLinux\u5185\u6838\u793e\u533a\u91c7\u7eb3\u5e76\u52a0\u5165\u5230\u5185\u6838\u4e2d\uff0c\u6210\u4e3aLinux\u7cfb\u7edf\u7684\u4e00\u90e8\u5206\u3002\u5b83\u5728\u5bb9\u5668\u6280\u672f\u3001\u865a\u62df\u5316\u3001\u4e91\u8ba1\u7b97\u7b49\u9886\u57df\u90fd\u6709\u5e7f\u6cdb\u7684\u5e94\u7528\u3002 \u4e0b\u9762\u662fcgroup \u7684\u4e00\u4e9b\u5e38\u89c1\u7528\u9014\uff1a CPU \u9650\u5236\uff1a\u4f7f\u7528 cgroup \u53ef\u4ee5\u9650\u5236\u8fdb\u7a0b\u7684 CPU \u4f7f\u7528\u7387\uff0c\u907f\u514d\u67d0\u4e2a\u8fdb\u7a0b\u5360\u7528\u8fc7\u591a\u7684 CPU \u8d44\u6e90\u5bfc\u81f4\u7cfb\u7edf\u8d1f\u8f7d\u8fc7\u9ad8\uff0c\u4ece\u800c\u5f71\u54cd\u7cfb\u7edf\u7a33\u5b9a\u6027\u548c\u5176\u4ed6\u8fdb\u7a0b\u7684\u6b63\u5e38\u8fd0\u884c\u3002 \u5185\u5b58\u9650\u5236\uff1a\u4f7f\u7528 cgroup \u53ef\u4ee5\u9650\u5236\u8fdb\u7a0b\u7684\u5185\u5b58\u4f7f\u7528\u91cf\uff0c\u907f\u514d\u67d0\u4e2a\u8fdb\u7a0b\u5360\u7528\u8fc7\u591a\u7684\u5185\u5b58\u8d44\u6e90\u5bfc\u81f4\u7cfb\u7edf\u5185\u5b58\u4e0d\u8db3\uff0c\u4ece\u800c\u5f71\u54cd\u7cfb\u7edf\u6027\u80fd\u548c\u5176\u4ed6\u8fdb\u7a0b\u7684\u6b63\u5e38\u8fd0\u884c\u3002 IO \u9650\u5236\uff1a\u4f7f\u7528 cgroup \u53ef\u4ee5\u9650\u5236\u8fdb\u7a0b\u7684 IO \u5e26\u5bbd\uff0c\u907f\u514d\u67d0\u4e2a\u8fdb\u7a0b\u5360\u7528\u8fc7\u591a\u7684 IO \u8d44\u6e90\u5bfc\u81f4\u5176\u4ed6\u8fdb\u7a0b\u7684 IO \u64cd\u4f5c\u53d7\u5230\u5f71\u54cd\uff0c\u4ece\u800c\u5f71\u54cd\u7cfb\u7edf\u6027\u80fd\u548c\u54cd\u5e94\u901f\u5ea6\u3002 \u7f51\u7edc\u9650\u5236\uff1a\u4f7f\u7528 cgroup \u53ef\u4ee5\u9650\u5236\u8fdb\u7a0b\u7684\u7f51\u7edc\u5e26\u5bbd\uff0c\u907f\u514d\u67d0\u4e2a\u8fdb\u7a0b\u5360\u7528\u8fc7\u591a\u7684\u7f51\u7edc\u8d44\u6e90\u5bfc\u81f4\u7f51\u7edc\u62e5\u585e\uff0c\u4ece\u800c\u5f71\u54cd\u7cfb\u7edf\u6027\u80fd\u548c\u5176\u4ed6\u8fdb\u7a0b\u7684\u6b63\u5e38\u8fd0\u884c\u3002 \u8fdb\u7a0b\u63a7\u5236\uff1a\u4f7f\u7528 cgroup \u53ef\u4ee5\u9650\u5236\u8fdb\u7a0b\u7684\u542f\u52a8\u3001\u505c\u6b62\u548c\u8c03\u5ea6\u7b49\u884c\u4e3a\uff0c\u4ece\u800c\u5b9e\u73b0\u5bf9\u7cfb\u7edf\u8fdb\u7a0b\u7684\u63a7\u5236\u548c\u7ba1\u7406\u3002 \u8d44\u6e90\u7edf\u8ba1\uff1a\u4f7f\u7528 cgroup \u53ef\u4ee5\u5b9e\u65f6\u7edf\u8ba1\u7cfb\u7edf\u4e2d\u5404\u4e2a\u8fdb\u7a0b\u7684\u8d44\u6e90\u4f7f\u7528\u60c5\u51b5\uff0c\u4ece\u800c\u5e2e\u52a9\u7ba1\u7406\u5458\u4e86\u89e3\u7cfb\u7edf\u8d1f\u8f7d\u72b6\u51b5\u548c\u5404\u4e2a\u8fdb\u7a0b\u7684\u6027\u80fd\u74f6\u9888\uff0c\u4ece\u800c\u91c7\u53d6\u76f8\u5e94\u7684\u63aa\u65bd\u4f18\u5316\u7cfb\u7edf\u6027\u80fd\u3002 \u4e0b\u9762\u662fopenSUSE\u4e2d\u7684\u793a\u4f8b\uff1a \u5b89\u88c5\u9700\u8981\u7684\u8f6f\u4ef6\u5305\uff1a sudo zypper install libcgroup-tools \u9650\u5236CPU\u4f7f\u7528\u4e0a\u9650\uff1a # \u521b\u5efa\u65b0\u7684cgroup 'mygroup' sudo mkdir /sys/fs/cgroup/cpu/mygroup # \u7cfb\u7edf\u4f1a\u521b\u5efa\u9ed8\u8ba4\u7684\u4e00\u4e9b\u6587\u4ef6\uff0c\u542b\u521d\u59cb\u503c\uff0c\u6bd4\u5982CPU\u4f7f\u7528\u65f6\u95f4\u7684\u9650\u989d\u7684\u9ed8\u8ba4\u503c\u662f-1 cat /sys/fs/cgroup/cpu/mygroup/cpu.cfs_quota_us # \u8bbe\u5b9aCPU\u4f7f\u7528\u65f6\u95f4\u4e0a\u9650 sudo sh -c \"echo 50000 > /sys/fs/cgroup/cpu/mygroup/cpu.cfs_quota_us\" # \u542f\u52a8\u4e00\u4e2a\u65b0\u7684\u8fdb\u7a0b\uff0c\u5e76\u4e14\u5173\u8054\u5230 sudo cgcreate -g cpu:mygroup sudo cgexec -g cpu:mygroup /bin/bash \u5728\u4e0a\u9762\u7684\u4f8b\u5b50\u4e2d\uff0c cpu.cfs_quota_us \u6587\u4ef6\u8bbe\u7f6e\u4e86 cgroup \u4e2d\u7684\u8fdb\u7a0b\u53ef\u4ee5\u4f7f\u7528\u7684\u6700\u5927 CPU \u65f6\u95f4\u3002\u8be5\u503c\u4ee5\u5fae\u79d2\u4e3a\u5355\u4f4d\uff0c\u56e0\u6b64\u5c06\u5176\u8bbe\u7f6e\u4e3a 50000 \u8868\u793a\u8fdb\u7a0b\u6700\u591a\u53ef\u4ee5\u4f7f\u7528\u5355\u4e2a CPU \u6838\u5fc3\u7684 50%\u3002 cgcreate \u548c cgexec \u547d\u4ee4\u521b\u5efa\u5e76\u5c06\u8fdb\u7a0b /bin/bash \u79fb\u52a8\u5230 mygroup cgroup \u4e2d\u3002 \u9650\u5236\u5185\u5b58\u4f7f\u7528\u4e0a\u9650\uff1a # \u521b\u5efa\u65b0\u7684cgroup 'mygroup' sudo mkdir /sys/fs/cgroup/memory/mygroup # \u7cfb\u7edf\u4f1a\u521b\u5efa\u9ed8\u8ba4\u7684\u4e00\u4e9b\u6587\u4ef6\uff0c\u542b\u521d\u59cb\u503c\uff0c\u6bd4\u5982\u5185\u5b58\u4f7f\u7528\u4e0a\u9650\u7684\u9ed8\u8ba4\u503c\u662f9223372036854771712 cat /sys/fs/cgroup/memory/mygroup/memory.limit_in_bytes # \u8bbe\u7f6e\u5185\u5b58\u4f7f\u7528\u4e0a\u9650512MB sudo sh -c \"echo 536870912 > /sys/fs/cgroup/memory/mygroup/memory.limit_in_bytes\" # \u542f\u52a8\u4e00\u4e2a\u65b0\u7684\u8fdb\u7a0b\uff0c\u5e76\u4e14\u5173\u8054\u5230'mygroup' sudo cgcreate -g memory:mygroup sudo cgexec -g memory:mygroup /bin/bash \u5728\u4e0a\u9762\u4f8b\u5b50\u4e2d\uff0c memory.limit_in_bytes \u6587\u4ef6\u8bbe\u7f6e\u4e86 cgroup \u4e2d\u8fdb\u7a0b\u53ef\u4ee5\u4f7f\u7528\u7684\u6700\u5927\u5185\u5b58\u91cf\u3002\u8be5\u503c\u4ee5\u5b57\u8282\u4e3a\u5355\u4f4d\uff0c\u56e0\u6b64\u5c06\u5176\u8bbe\u7f6e\u4e3a 536870912 \u8868\u793a\u8fdb\u7a0b\u6700\u591a\u53ef\u4ee5\u4f7f\u7528 512MB \u7684\u5185\u5b58\u3002 \u8bbe\u7f6e\u4f18\u5148\u8fdb\u7a0b\u7684 I/O \u4f7f\u7528\u7387\uff1a # \u521b\u5efa\u65b0cgroup 'mygroup' sudo mkdir /sys/fs/cgroup/blkio/mygroup # \u8bbe\u7f6e\u8fdb\u7a0b\u6700\u5927\u8bfb\u548c\u5199\u7684\u901f\u738710MB/s sudo sh -c \"echo '8:0 10485760' > /sys/fs/cgroup/blkio/mygroup/blkio.throttle.read_bps_device\" sudo sh -c \"echo '8:0 10485760' > /sys/fs/cgroup/blkio/mygroup/blkio.throttle.write_bps_device\" # \u542f\u52a8\u4e00\u4e2a\u65b0\u7684\u8fdb\u7a0b\uff0c\u5e76\u4e14\u5173\u8054\u5230'mygroup' sudo cgcreate -g blkio:mygroup sudo cgexec -g blkio:mygroup /bin/bash \u5728\u4e0a\u9762\u4f8b\u5b50\u4e2d\uff0c blkio.throttle.read_bps_device \u548c blkio.throttle.write_bps_device \u6587\u4ef6\u8bbe\u7f6e\u4e86cgroup\u4e2d\u8fdb\u7a0b\u53ef\u4ee5\u4f7f\u7528\u7684\u6700\u5927\u8bfb\u53d6\u548c\u5199\u5165\u5e26\u5bbd\u3002\u8be5\u503c\u4ee5\u6bcf\u79d2\u5b57\u8282\u6570\u4e3a\u5355\u4f4d\uff0c\u56e0\u6b64\u5c06\u5176\u8bbe\u7f6e\u4e3a10485760\u610f\u5473\u7740\u8fdb\u7a0b\u5728\u4e3b\u8bbe\u5907\u53f7:\u6b21\u8bbe\u5907\u53f7\u4e3a8:0\u7684\u8bbe\u5907\uff08\u901a\u5e38\u662f\u7b2c\u4e00\u4e2a\u786c\u76d8\uff09\u4e0a\u8bfb\u53d6\u6216\u5199\u5165\u7684\u5e26\u5bbd\u6700\u591a\u4e3a10MB/s\u3002 \u5c06 8:0 10485760 \u8fd9\u4e2a\u5b57\u7b26\u4e32\u5199\u5165\u5230 /sys/fs/cgroup/blkio/mygroup/blkio.throttle.read_bps_device \u6587\u4ef6\u4e2d\u7684\u4f5c\u7528\u662f\u9650\u5236 mygroup \u63a7\u5236\u7ec4\u4e2d\u5173\u8054\u7684\u5757\u8bbe\u5907\uff08block device\uff09\u7684\u8bfb\u53d6\u901f\u7387\u3002 \u5728 Linux \u4e2d\uff0c blkio \u63a7\u5236\u7ec4\u5b50\u7cfb\u7edf\u53ef\u4ee5\u7528\u6765\u5bf9\u8fdb\u7a0b\u6216\u7ebf\u7a0b\u7684\u5757\u8bbe\u5907\u8bbf\u95ee\u8fdb\u884c\u9650\u5236\uff0c\u5982\u9650\u5236\u8bfb\u5199\u901f\u7387\u3001I/O \u4f18\u5148\u7ea7\u7b49\u3002\u800c blkio.throttle.read_bps_device \u8fd9\u4e2a\u6587\u4ef6\u5219\u7528\u4e8e\u8bbe\u7f6e\u67d0\u4e2a\u5757\u8bbe\u5907\u7684\u8bfb\u53d6\u901f\u7387\u9650\u5236\u3002 \u5177\u4f53\u6765\u8bf4\uff0c 8:0 \u8868\u793a\u8bbe\u5907\u7684\u4e3b\u6b21\u7f16\u53f7\uff08major:minor\uff09\uff0c\u8fd9\u91cc\u662f\u6307\u78c1\u76d8 /dev/sda \u3002 10485760 \u5219\u662f\u8bfb\u53d6\u901f\u7387\u7684\u9650\u5236\u503c\uff0c\u5355\u4f4d\u662f\u5b57\u8282/\u79d2\u3002\u8fd9\u4e2a\u503c\u8868\u793a /dev/sda \u6700\u5927\u8bfb\u53d6\u901f\u7387\u4e3a 10MB/s\uff0c\u8d85\u8fc7\u8fd9\u4e2a\u901f\u7387\u7684\u8bfb\u53d6\u8bf7\u6c42\u4f1a\u88ab\u5ef6\u8fdf\u6267\u884c\uff0c\u4ece\u800c\u9650\u5236\u4e86\u78c1\u76d8\u7684\u8bfb\u53d6\u5e26\u5bbd\u3002 \u56e0\u6b64\uff0c\u4ee5\u4e0a\u547d\u4ee4\u7684\u542b\u4e49\u662f\u5c06 mygroup \u63a7\u5236\u7ec4\u4e2d\u5173\u8054\u7684 /dev/sda \u78c1\u76d8\u7684\u8bfb\u53d6\u901f\u7387\u9650\u5236\u4e3a 10MB/s\uff0c\u4ece\u800c\u5b9e\u73b0\u5bf9\u8be5\u63a7\u5236\u7ec4\u4e2d\u8fdb\u7a0b\u6216\u7ebf\u7a0b\u5bf9\u78c1\u76d8\u8bfb\u53d6\u7684\u9650\u5236\u3002 \u540c\u7406\uff0c\u5c06 8:0 10485760 \u8fd9\u4e2a\u5b57\u7b26\u4e32\u5199\u5165\u5230 /sys/fs/cgroup/blkio/mygroup/blkio.throttle.write_bps_device \u6587\u4ef6\u4e2d\uff0c\u4ee5\u9650\u5236 mygroup \u63a7\u5236\u7ec4\u4e2d\u5173\u8054\u7684\u5757\u8bbe\u5907\uff08block device\uff09\u7684\u5199\u5165\u901f\u7387\u3002 \u9650\u5236\u4e00\u7ec4\u8fdb\u7a0b\u7684\u7f51\u7edc\u5e26\u5bbd\uff1a # \u521b\u5efa\u65b0\u7684cgroup 'mygroup' sudo mkdir /sys/fs/cgroup/net_cls/mygroup # \u5c06\u6b64\u7ec4\u4e2d\u7684\u8fdb\u7a0b\u7684\u7f51\u7edc\u7c7bID\u8bbe\u7f6e\u4e3a\u201cmyclass\u201d sudo sh -c \"echo 0x10001 > /sys/fs/cgroup/net_cls/mygroup/net_cls.classid\" \u4e0a\u9762\u7684\u4f8b\u5b50\u662f\u5c06 0x10001 \u8fd9\u4e2a\u5341\u516d\u8fdb\u5236\u6570\u503c\u5199\u5165\u5230 /sys/fs/cgroup/net_cls/mygroup/net_cls.classid \u6587\u4ef6\u4e2d\uff0c\u4ee5\u6307\u5b9a mygroup \u63a7\u5236\u7ec4\u7684\u7f51\u7edc\u7c7b\u522b\u6807\u8bc6\u7b26\uff08classid\uff09\u3002 \u7f51\u7edc\u7c7b\u522b\u6807\u8bc6\u7b26\u662f Linux \u5185\u6838\u4e2d\u7528\u6765\u5b9e\u73b0\u6d41\u91cf\u63a7\u5236\u548c\u6d41\u91cf\u5206\u7c7b\u7684\u4e00\u4e2a\u673a\u5236\uff0c\u5b83\u53ef\u4ee5\u5c06\u6570\u636e\u5305\u6309\u7167\u4e0d\u540c\u7684\u7c7b\u522b\uff08class\uff09\u8fdb\u884c\u6807\u8bb0\u548c\u533a\u5206\uff0c\u7136\u540e\u5728\u7f51\u7edc\u8bbe\u5907\u4e0a\u9488\u5bf9\u4e0d\u540c\u7684\u7c7b\u522b\u8fdb\u884c\u4e0d\u540c\u7684\u5904\u7406\uff0c\u5982\u9650\u901f\u3001\u4f18\u5148\u7ea7\u8c03\u6574\u7b49\u3002\u63a7\u5236\u7ec4\u4e2d\u7684 net_cls \u5b50\u7cfb\u7edf\u53ef\u4ee5\u7528\u6765\u5c06\u8fdb\u7a0b\u6216\u7ebf\u7a0b\u4e0e\u7f51\u7edc\u7c7b\u522b\u6807\u8bc6\u7b26\u5173\u8054\u8d77\u6765\uff0c\u4ece\u800c\u5b9e\u73b0\u5bf9\u5b83\u4eec\u7684\u7f51\u7edc\u6d41\u91cf\u8fdb\u884c\u63a7\u5236\u548c\u5206\u7c7b\u3002 \u56e0\u6b64\uff0c\u4ee5\u4e0a\u547d\u4ee4\u662f\u5c06 mygroup \u63a7\u5236\u7ec4\u7684\u7f51\u7edc\u7c7b\u522b\u6807\u8bc6\u7b26\u8bbe\u7f6e\u4e3a 0x10001 \uff0c\u8fd9\u6837\u4e0e\u8be5\u63a7\u5236\u7ec4\u76f8\u5173\u8054\u7684\u8fdb\u7a0b\u6216\u7ebf\u7a0b\u5c31\u4f1a\u88ab\u6807\u8bb0\u4e3a\u8be5\u7c7b\u522b\uff0c\u7136\u540e\u53ef\u4ee5\u901a\u8fc7\u5176\u4ed6\u5de5\u5177\uff08\u5982 tc \u547d\u4ee4\uff09\u5bf9\u5176\u8fdb\u884c\u7f51\u7edc\u6d41\u91cf\u63a7\u5236\u548c\u5206\u7c7b\u3002 \u5982\u679c\u9047\u5230\u5bf9\u5e94\u9650\u5236\u6587\u4ef6\u4e0d\u5b58\u5728\uff0c\u4e00\u79cd\u53ef\u80fd\u662f\u9700\u8981\u68c0\u67e5cgroup\u5b50\u7cfb\u6709\u6ca1\u6709\u6b63\u786e\u7edf\u8f7d\u6216\u8005\u6ca1\u6709\u542f\u7528\u5185\u5b58\u5b50\u7cfb\u7edf\u3002 mount | grep cgroup \u5982\u679c cgroups \u6587\u4ef6\u7cfb\u7edf\u5df2\u7ecf\u6302\u8f7d\uff0c\u5e94\u8be5\u4f1a\u770b\u5230\u8f93\u51fa\u7c7b\u4f3c\u4e8e\u4ee5\u4e0b\u5185\u5bb9\uff08\uff09\u4ee5memory\u4e3a\u4f8b\uff09\uff1a cgroup on /sys/fs/cgroup/memory type cgroup (rw,nosuid,nodev,noexec,relatime,memory) \u5982\u679c\u6ca1\u6709\u770b\u5230 memory \u5b57\u6bb5\uff0c\u5219\u8868\u793a\u5185\u5b58\u5b50\u7cfb\u7edf\u6ca1\u6709\u542f\u7528\u3002\u53ef\u4ee5\u7f16\u8f91 /etc/default/grub \u6587\u4ef6\uff0c\u6dfb\u52a0\u6216\u4fee\u6539\u4ee5\u4e0b\u884c\uff1a GRUB_CMDLINE_LINUX_DEFAULT=\"cgroup_enable=memory\" \u7136\u540e\u66f4\u65b0 GRUB \u914d\u7f6e\u5e76\u91cd\u542f\u7cfb\u7edf\uff1a sudo update-grub sudo reboot \u91cd\u542f\u540e\u518d\u6b21\u68c0\u67e5 /sys/fs/cgroup/memory/mygroup/memory.limit_in_bytes \u6587\u4ef6\u662f\u5426\u5b58\u5728\u3002\u5982\u679c\u8fd8\u662f\u4e0d\u5b58\u5728\uff0c\u53ef\u80fd\u9700\u8981\u624b\u52a8\u521b\u5efa\u5b83\u4ee5\u53ca\u5176\u4ed6\u76f8\u5173\u7684 cgroups \u6587\u4ef6\u3002\u4f8b\u5982\uff0c\u8fd0\u884c\u4ee5\u4e0b\u547d\u4ee4\uff1a sudo mkdir /sys/fs/cgroup/memory/mygroup sudo touch /sys/fs/cgroup/memory/mygroup/memory.limit_in_bytes \u7136\u540e\u5c31\u53ef\u4ee5\u50cf\u4e4b\u524d\u7684\u4f8b\u5b50\u4e00\u6837\u8bbe\u7f6e\u5185\u5b58\u9650\u5236\u4e86 Apparmor\u548cSELinux\u914d\u7f6e\u6587\u4ef6 \u00b6 \u5b89\u5168\u914d\u7f6e\u6587\u4ef6\uff0c\u7528\u4e8e\u63a7\u5236\u5bf9\u8d44\u6e90\u7684\u8bbf\u95ee AppArmor \u548c SELinux \u90fd\u662f\u5e38\u89c1\u7684\u5f3a\u5236\u8bbf\u95ee\u63a7\u5236\uff08MAC\uff09\u673a\u5236\uff0c\u53ef\u4ee5\u5bf9\u8fdb\u7a0b\u6216\u5e94\u7528\u7a0b\u5e8f\u7684\u8bbf\u95ee\u6743\u9650\u8fdb\u884c\u7cbe\u7ec6\u63a7\u5236\u3002\u4e0b\u9762\u5206\u522b\u4e3e\u4f8b\u8bf4\u660e\u8fd9\u4e24\u79cd\u673a\u5236\u7684\u914d\u7f6e\u6587\u4ef6\u4f7f\u7528\u3002 AppArmor AppArmor \u7684\u4e3b\u914d\u7f6e\u6587\u4ef6\u662f /etc/apparmor/profiles.d/ \u76ee\u5f55\u4e0b\u7684\u5404\u4e2a\u6587\u4ef6\uff0c\u6bcf\u4e2a\u6587\u4ef6\u5bf9\u5e94\u4e00\u4e2a\u5e94\u7528\u7a0b\u5e8f\u6216\u8fdb\u7a0b\u7684\u914d\u7f6e\u3002\u4ee5 sshd \u670d\u52a1\u4e3a\u4f8b\uff0c\u8be5\u670d\u52a1\u7684\u914d\u7f6e\u6587\u4ef6\u662f /etc/apparmor.d/usr.sbin.sshd \u3002 \u8be5\u914d\u7f6e\u6587\u4ef6\u7684\u5185\u5bb9\u7c7b\u4f3c\u4e8e\u4e0b\u9762\u8fd9\u6837\uff1a # Last Modified: Sun Mar 14 18 :53:00 2023 # include /usr/sbin/sshd { # include # include # allow read access to user home directories /home/** r, # allow sshd to execute /usr/bin/which to determine full path of shell /usr/bin/which ix, # allow sshd to read its own configuration file /etc/ssh/sshd_config r, # allow sshd to read the SSH host keys /etc/ssh/ssh_host_* r, # allow sshd to use pam for authentication /usr/share/pam/** r, # allow sshd to use nsswitch for name resolution /etc/nsswitch.conf r, /etc/hosts r, /etc/hostname r, /etc/resolv.conf r, # allow sshd to write to its own log file /var/log/auth.log w, # allow sshd to create and manage pid files /var/run/sshd.pid w, /var/run/sshd.dir/ w, /var/run/sshd.dir/* rw, # allow sshd to access systemd-logind /run/systemd/* r, /run/systemd/session/*.scope r, /run/systemd/sessions/*.scope r, # deny everything else deny /, } \u8be5\u914d\u7f6e\u6587\u4ef6\u5b9a\u4e49\u4e86 /usr/sbin/sshd \u8fdb\u7a0b\u7684\u6743\u9650\u9650\u5236\u89c4\u5219\uff0c\u5305\u62ec\u5141\u8bb8\u8bbf\u95ee\u7684\u6587\u4ef6\u3001\u7981\u6b62\u8bbf\u95ee\u7684\u6587\u4ef6\u7b49\u3002\u5176\u4e2d #include \u8868\u793a\u5305\u542b\u4e86\u4e00\u7ec4\u901a\u7528\u7684\u6743\u9650\u89c4\u5219\uff0c\u53ef\u4ee5\u5728\u4e0d\u540c\u7684\u5e94\u7528\u7a0b\u5e8f\u914d\u7f6e\u4e2d\u91cd\u590d\u4f7f\u7528\u3002 2.SELinux SELinux \u7684\u4e3b\u914d\u7f6e\u6587\u4ef6\u662f /etc/selinux/config \uff0c\u8be5\u6587\u4ef6\u5b9a\u4e49\u4e86\u7cfb\u7edf\u7684 SELinux \u7b56\u7565\u548c\u6a21\u5f0f\u3002\u9ed8\u8ba4\u60c5\u51b5\u4e0b\uff0copenSUSE \u4f7f\u7528\u7684\u662f targeted \u6a21\u5f0f\u3002 \u6bcf\u4e2a\u8fdb\u7a0b\u6216\u5e94\u7528\u7a0b\u5e8f\u8fd8\u9700\u8981\u5bf9\u5e94\u4e00\u4e2a SELinux \u914d\u7f6e\u6587\u4ef6\uff0c\u4ee5\u5b9a\u4e49\u5b83\u4eec\u7684\u8bbf\u95ee\u6743\u9650\u3002\u4ee5 httpd \u670d\u52a1\u4e3a\u4f8b\uff0c\u8be5\u670d\u52a1\u7684 SELinux \u914d\u7f6e\u6587\u4ef6\u662f /etc/selinux/targeted/contexts/httpd.te \u3002 \u8be5\u914d\u7f6e\u6587\u4ef6\u7684\u5185\u5bb9\u7c7b\u4f3c\u4e8e\u4e0b\u9762\u8fd9\u6837\uff1a # HTTPD server type httpd_t ; type httpd_sys_script_t ; init_daemon_domain ( httpd_t, httpd_sys_script_t ) \u8be5\u914d\u7f6e\u6587\u4ef6\u5b9a\u4e49\u4e86 httpd \u670d\u52a1\u7684 SELinux \u7c7b\u578b\u4e3a httpd_t \uff0c\u5e76\u4f7f\u7528\u4e86 httpd_sys_script_t \u4f5c\u4e3a\u5176\u521d\u59cb\u5316\u57df\u3002\u5176\u4e2d type \u8868\u793a SELinux \u7c7b\u578b\uff0c init_daemon_domain \u5219\u662f\u4e00\u4e2a SELinux \u5b8f\uff0c\u7528\u4e8e\u5b9a\u4e49\u670d\u52a1\u7684\u521d\u59cb\u57df\u3002 \u9700\u8981\u6ce8\u610f\u7684\u662f\uff0c\u5728 SELinux \u4e2d\uff0c\u8bbf\u95ee\u6743\u9650\u89c4\u5219\u4e0d\u662f\u76f4\u63a5\u5728\u914d\u7f6e\u6587\u4ef6\u4e2d\u5b9a\u4e49\u7684\uff0c\u800c\u662f\u901a\u8fc7\u8bbf\u95ee\u63a7\u5236\u7b56\u7565\u548c\u89c4\u5219\u8fdb\u884c\u63a7\u5236\u3002\u8fd9\u4e9b\u7b56\u7565\u548c\u89c4\u5219\u53ef\u4ee5\u4f7f\u7528 SELinux \u5de5\u5177\u96c6\uff08\u5982 semanage \u3001 setsebool \u3001 restorecon \u7b49\uff09\u8fdb\u884c\u7ba1\u7406\u548c\u8bbe\u7f6e\u3002 \u6bd4\u5982\uff0c\u5728openSUSE\u4e2d\u53ef\u4ee5\u770b\u5230 /etc/selinux/semanage.conf \u6587\u4ef6\u548c\u5176\u4e2d\u7684\u914d\u7f6e\u3002 \u5185\u6838\u80fd\u529b \u00b6 \u5185\u6838\u80fd\u529b\uff08Kernel capabilities\uff09 \u6ca1\u6709\u80fd\u529b\uff1aroot\u53ef\u4ee5\u6267\u884c\u6240\u6709\u64cd\u4f5c\uff0c\u5176\u4ed6\u7528\u6237\u53ef\u80fd\u4ec0\u4e48\u4e5f\u505a\u4e0d\u4e86 38\u4e2a\u7ec6\u7c92\u5ea6\u7684\u529f\u80fd\u6765\u63a7\u5236\u6743\u9650 Kernel capabilities \u662f Linux \u5185\u6838\u63d0\u4f9b\u7684\u4e00\u79cd\u673a\u5236\uff0c\u7528\u4e8e\u63a7\u5236\u8fdb\u7a0b\u5bf9\u7cfb\u7edf\u8d44\u6e90\u7684\u8bbf\u95ee\u6743\u9650\u3002\u4e0e\u4f20\u7edf\u7684 Unix \u6743\u9650\u673a\u5236\u4e0d\u540c\uff0cKernel capabilities \u53ef\u4ee5\u4f7f\u7ba1\u7406\u5458\u5728\u7cbe\u7ec6\u63a7\u5236\u7cfb\u7edf\u8d44\u6e90\u8bbf\u95ee\u7684\u540c\u65f6\uff0c\u907f\u514d\u5c06\u8fc7\u591a\u6743\u9650\u6388\u4e88\u8fdb\u7a0b\uff0c\u63d0\u9ad8\u4e86\u7cfb\u7edf\u7684\u5b89\u5168\u6027\u3002 \u5728\u4f20\u7edf Unix \u6743\u9650\u673a\u5236\u4e2d\uff0c\u6bcf\u4e2a\u8fdb\u7a0b\u90fd\u6709\u4e00\u4e2a\u6709\u6548\u7528\u6237 ID \u548c\u4e00\u4e2a\u6709\u6548\u7ec4 ID\uff0c\u8fd9\u4e9b ID \u51b3\u5b9a\u4e86\u8be5\u8fdb\u7a0b\u5bf9\u6587\u4ef6\u3001\u8bbe\u5907\u3001\u7f51\u7edc\u7b49\u8d44\u6e90\u7684\u8bbf\u95ee\u6743\u9650\u3002\u4f46\u662f\uff0c\u8fd9\u79cd\u6743\u9650\u673a\u5236\u4e0d\u591f\u7075\u6d3b\uff0c\u5982\u679c\u8981\u6388\u4e88\u8fdb\u7a0b\u67d0\u4e9b\u7279\u5b9a\u7684\u6743\u9650\uff0c\u53ef\u80fd\u9700\u8981\u5c06\u6240\u6709\u7684\u6743\u9650\u90fd\u6388\u4e88\u7ed9\u5b83\uff0c\u4ece\u800c\u964d\u4f4e\u4e86\u7cfb\u7edf\u7684\u5b89\u5168\u6027\u3002 Kernel capabilities \u63d0\u4f9b\u4e86\u4e00\u79cd\u66f4\u7ec6\u7c92\u5ea6\u7684\u6743\u9650\u63a7\u5236\u65b9\u5f0f\u3002\u6bcf\u4e2a\u8fdb\u7a0b\u90fd\u6709\u4e00\u7ec4 capabilities\uff0c\u6bcf\u4e2a capability \u8868\u793a\u4e00\u79cd\u7279\u5b9a\u7684\u6743\u9650\u3002\u8fdb\u7a0b\u53ef\u4ee5\u8bf7\u6c42\u548c\u91ca\u653e\u67d0\u4e9b capability\uff0c\u8fd9\u6837\u5c31\u53ef\u4ee5\u5c06\u6743\u9650\u6388\u4e88\u8fdb\u7a0b\uff0c\u800c\u4e0d\u5fc5\u6388\u4e88\u6240\u6709\u6743\u9650\u3002 \u4f8b\u5982\uff0c\u53ef\u4ee5\u5c06 CAP_NET_BIND_SERVICE capability \u6388\u4e88\u67d0\u4e2a\u8fdb\u7a0b\uff0c\u8fd9\u6837\u8be5\u8fdb\u7a0b\u5c31\u53ef\u4ee5\u7ed1\u5b9a 1-1023 \u7684\u7aef\u53e3\uff0c\u800c\u4e0d\u5fc5\u5177\u6709 root \u6743\u9650\u3002\u7c7b\u4f3c\u5730\uff0c\u53ef\u4ee5\u5c06 CAP_SYS_ADMIN capability \u6388\u4e88\u67d0\u4e2a\u8fdb\u7a0b\uff0c\u8fd9\u6837\u8be5\u8fdb\u7a0b\u5c31\u53ef\u4ee5\u6267\u884c\u7cfb\u7edf\u7ba1\u7406\u4efb\u52a1\uff0c\u5982\u6302\u8f7d\u6587\u4ef6\u7cfb\u7edf\u548c\u521b\u5efa\u8bbe\u5907\u8282\u70b9\u7b49\u3002 Linux \u5185\u6838\u63d0\u4f9b\u4e86\u4e00\u7ec4\u9ed8\u8ba4\u7684 capabilities\uff0c\u4e5f\u53ef\u4ee5\u901a\u8fc7\u81ea\u5b9a\u4e49\u7684\u65b9\u5f0f\u521b\u5efa\u65b0\u7684 capabilities\uff0c\u4ee5\u4fbf\u66f4\u597d\u5730\u63a7\u5236\u7cfb\u7edf\u8d44\u6e90\u7684\u8bbf\u95ee\u6743\u9650\u3002\u53ef\u4ee5\u4f7f\u7528 setcap \u547d\u4ee4\u4e3a\u4e8c\u8fdb\u5236\u6587\u4ef6\u8bbe\u7f6e capabilities\u3002\u4f8b\u5982\uff0c\u4e0b\u9762\u7684\u547d\u4ee4\u5c06 CAP_NET_RAW capability \u6388\u4e88 /usr/bin/ping \u547d\u4ee4\uff1a sudo setcap cap_net_raw+ep /usr/bin/ping \u8fd9\u6837\uff0c\u7528\u6237\u5c31\u53ef\u4ee5\u4f7f\u7528 ping \u547d\u4ee4\u800c\u4e0d\u5fc5\u4ee5 root \u7528\u6237\u7684\u8eab\u4efd\u767b\u5f55\u3002 \u9664\u4e86 CAP_NET_BIND_SERVICE \u548c CAP_SYS_ADMIN \uff0c\u8fd8\u6709\u4e00\u4e9b\u5176\u4ed6\u7684 capabilities\uff0c\u4ee5\u4e0b\u662f\u4e00\u4e9b\u4f8b\u5b50\uff1a CAP_DAC_OVERRIDE \uff1a\u5141\u8bb8\u8fdb\u7a0b\u5ffd\u7565\u6587\u4ef6\u6743\u9650\uff0c\u53ef\u4ee5\u8bbf\u95ee\u4efb\u4f55\u6587\u4ef6\u3002 CAP_CHOWN \uff1a\u5141\u8bb8\u8fdb\u7a0b\u4fee\u6539\u6587\u4ef6\u7684\u6240\u6709\u8005\u3002 CAP_SETUID \u548c CAP_SETGID \uff1a\u5141\u8bb8\u8fdb\u7a0b\u4fee\u6539\u81ea\u5df1\u7684\u7528\u6237 ID \u548c\u7ec4 ID\u3002 CAP_NET_ADMIN \uff1a\u5141\u8bb8\u8fdb\u7a0b\u6267\u884c\u7f51\u7edc\u7ba1\u7406\u4efb\u52a1\uff0c\u5982\u914d\u7f6e\u7f51\u7edc\u63a5\u53e3\u548c\u8def\u7531\u8868\u7b49\u3002 CAP_SYS_RESOURCE \uff1a\u5141\u8bb8\u8fdb\u7a0b\u4fee\u6539\u7cfb\u7edf\u8d44\u6e90\u9650\u5236\uff0c\u5982 CPU \u65f6\u95f4\u548c\u5185\u5b58\u9650\u5236\u7b49\u3002 \u53ef\u4ee5\u901a\u8fc7\u547d\u4ee4 man 7 capabilities \u6765\u67e5\u770b\u7cfb\u7edf\u63d0\u4f9b\u7684 capabilities \u5217\u8868\u548c\u8be6\u7ec6\u8bf4\u660e\u3002\u5728\u4f7f\u7528 Kernel capabilities \u65f6\uff0c\u9700\u8981\u6ce8\u610f\uff0c\u53ea\u6709\u62e5\u6709 CAP_SETFCAP \u6216 CAP_SYS_ADMIN capability \u7684\u8fdb\u7a0b\u624d\u80fd\u591f\u4fee\u6539\u81ea\u5df1\u6216\u5176\u4ed6\u8fdb\u7a0b\u7684 capabilities\uff0c\u8fd9\u4e5f\u662f\u4e3a\u4e86\u4fdd\u62a4\u7cfb\u7edf\u7684\u5b89\u5168\u6027\u3002 \u5982\u679c\u6267\u884c setcap \u547d\u4ee4\u65f6\u51fa\u73b0 \"command not found\" \u7684\u9519\u8bef\uff0c\u8fd9\u901a\u5e38\u610f\u5473\u7740 setcap \u547d\u4ee4\u6240\u5728\u7684\u5305\u5c1a\u672a\u5b89\u88c5\u3002\u5728 openSUSE \u4e2d\uff0csetcap \u547d\u4ee4\u5305\u542b\u5728 libcap-progs \u8f6f\u4ef6\u5305\u4e2d\u3002 \u5728 openSUSE \u7cfb\u7edf\u4e2d\u9700\u8981\u5b89\u88c5 libcap-progs \u8f6f\u4ef6\u5305\uff1a sudo zypper in libcap-progs \u5728 Ubuntu/Debian \u7cfb\u7edf\u4e0a\u9700\u8981\u5b89\u88c5 libcap \u5e93\uff1a sudo apt-get install libcap2-bin \u5728 CentOS/RHEL \u7cfb\u7edf\u4e0a\u9700\u8981\u5b89\u88c5 libcap \u5e93\uff1a sudo yum install libcap-devel \u5b89\u88c5\u5b8c\u6210\u540e\uff0c\u53ef\u4ee5\u4f7f\u7528 setcap \u547d\u4ee4\u4e3a\u4e8c\u8fdb\u5236\u6587\u4ef6\u8bbe\u7f6e capabilities\u3002\u5982\u679c\u8fd8\u662f\u65e0\u6cd5\u627e\u5230 setcap \u547d\u4ee4\uff0c\u53ef\u4ee5\u5c1d\u8bd5\u4f7f\u7528\u5b8c\u6574\u8def\u5f84 /sbin/setcap \u6216\u8005 /usr/sbin/setcap\u3002 seccomp\u7b56\u7565 \u00b6 seccomp\uff08secure computing mode\uff09\u662f Linux \u5185\u6838\u63d0\u4f9b\u7684\u4e00\u79cd\u5b89\u5168\u673a\u5236\uff0c\u5b83\u53ef\u4ee5\u9650\u5236\u8fdb\u7a0b\u80fd\u591f\u8fdb\u884c\u7684\u7cfb\u7edf\u8c03\u7528\u3002\u901a\u8fc7\u4f7f\u7528 seccomp\uff0c\u53ef\u4ee5\u9650\u5236\u8fdb\u7a0b\u53ea\u80fd\u591f\u4f7f\u7528\u5fc5\u8981\u7684\u7cfb\u7edf\u8c03\u7528\uff0c\u4ece\u800c\u51cf\u5c11\u7cfb\u7edf\u88ab\u653b\u51fb\u7684\u98ce\u9669\u3002 seccomp \u7b56\u7565\u53ef\u4ee5\u4f7f\u7528 BPF\uff08Berkeley Packet Filter\uff09\u8bed\u8a00\u7f16\u5199\uff0c\u5e76\u4f7f\u7528 seccomp() \u7cfb\u7edf\u8c03\u7528\u52a0\u8f7d\u3002\u4ee5\u4e0b\u662f\u4e00\u4e2a\u4f7f\u7528 seccomp \u7b56\u7565\u9650\u5236\u8fdb\u7a0b\u80fd\u591f\u8fdb\u884c\u7684\u7cfb\u7edf\u8c03\u7528\u7684\u793a\u4f8b\uff1a #include #include #include int main () { // \u521b\u5efa seccomp \u8fc7\u6ee4\u5668 struct sock_filter filter [] = { BPF_STMT ( BPF_LD | BPF_W | BPF_ABS , 0 ), BPF_JUMP ( BPF_JMP | BPF_JEQ | BPF_K , __NR_write , 0 , 1 ), BPF_STMT ( BPF_RET | BPF_K , SECCOMP_RET_ALLOW ), BPF_STMT ( BPF_RET | BPF_K , SECCOMP_RET_KILL ), }; struct sock_fprog prog = { . len = sizeof ( filter ) / sizeof ( filter [ 0 ]), . filter = filter , }; // \u52a0\u8f7d seccomp \u8fc7\u6ee4\u5668 if ( prctl ( PR_SET_SECCOMP , SECCOMP_MODE_FILTER , & prog ) < 0 ) { perror ( \"prctl\" ); return 1 ; } // \u8c03\u7528 write \u7cfb\u7edf\u8c03\u7528 char buf [] = \"Hello, world!\" ; write ( 1 , buf , sizeof ( buf )); return 0 ; } \u4e0a\u8ff0\u4ee3\u7801\u521b\u5efa\u4e86\u4e00\u4e2a seccomp \u8fc7\u6ee4\u5668\uff0c\u4ec5\u5141\u8bb8\u8fdb\u7a0b\u8c03\u7528 write() \u7cfb\u7edf\u8c03\u7528\uff0c\u5176\u4ed6\u7cfb\u7edf\u8c03\u7528\u5747\u4f1a\u88ab\u7981\u6b62\u3002\u53ef\u4ee5\u901a\u8fc7\u7f16\u8bd1\u5e76\u8fd0\u884c\u4e0a\u8ff0\u4ee3\u7801\u6765\u6f14\u793a seccomp \u7b56\u7565\u7684\u4f5c\u7528\u3002 \u9700\u8981\u6ce8\u610f\u7684\u662f\uff0cseccomp \u7b56\u7565\u53ea\u80fd\u591f\u9650\u5236\u8fdb\u7a0b\u8fdb\u884c\u7684\u7cfb\u7edf\u8c03\u7528\uff0c\u4f46\u4e0d\u80fd\u591f\u9650\u5236\u7cfb\u7edf\u8c03\u7528\u7684\u53c2\u6570\u6216\u8fd4\u56de\u503c\u3002\u56e0\u6b64\uff0c\u4f7f\u7528 seccomp \u7b56\u7565\u65f6\u9700\u8981\u7279\u522b\u5c0f\u5fc3\uff0c\u907f\u514d\u8bef\u7528\u6216\u4ea7\u751f\u6f0f\u6d1e\u3002 Netlink \u00b6 Netlink \u662f\u4e00\u79cd Linux \u5185\u6838\u63d0\u4f9b\u7684\u901a\u4fe1\u673a\u5236\uff0c\u7528\u4e8e\u5185\u6838\u548c\u7528\u6237\u7a7a\u95f4\u8fdb\u7a0b\u4e4b\u95f4\u7684\u53cc\u5411\u901a\u4fe1\uff08IPC\uff09\u3002Netlink \u53ef\u4ee5\u7528\u4e8e\u8bb8\u591a\u76ee\u7684\uff0c\u4f8b\u5982\uff1a \u914d\u7f6e\u7f51\u7edc\u8bbe\u5907\u548c\u8def\u7531\u8868\uff1a\u4f7f\u7528 Netlink \u53ef\u4ee5\u901a\u8fc7\u7528\u6237\u7a7a\u95f4\u8fdb\u7a0b\u4fee\u6539\u5185\u6838\u7684\u7f51\u7edc\u8bbe\u5907\u548c\u8def\u7531\u8868\u914d\u7f6e\uff0c\u4f8b\u5982\u6dfb\u52a0\u3001\u5220\u9664\u3001\u4fee\u6539\u7f51\u7edc\u63a5\u53e3\u3001IP \u5730\u5740\u3001\u8def\u7531\u7b49\u3002 \u76d1\u89c6\u7f51\u7edc\u4e8b\u4ef6\uff1a\u4f7f\u7528 Netlink \u53ef\u4ee5\u5b9e\u65f6\u5730\u4ece\u5185\u6838\u83b7\u53d6\u7f51\u7edc\u4e8b\u4ef6\u7684\u901a\u77e5\uff0c\u4f8b\u5982\u7f51\u7edc\u63a5\u53e3\u7684\u72b6\u6001\u53d8\u5316\u3001\u8def\u7531\u7684\u53d8\u5316\u7b49\u3002 \u7a0b\u5e8f\u95f4\u901a\u4fe1\uff1a\u4f7f\u7528 Netlink \u53ef\u4ee5\u5728\u7528\u6237\u7a7a\u95f4\u8fdb\u7a0b\u4e4b\u95f4\u8fdb\u884c\u901a\u4fe1\uff0c\u7c7b\u4f3c\u4e8e Unix \u57df\u5957\u63a5\u5b57\u3002 Netlink \u673a\u5236\u57fa\u4e8e\u4e00\u79cd\u7279\u6b8a\u7684\u5957\u63a5\u5b57\u7c7b\u578b\uff08PF_NETLINK\uff09\u548c\u4e00\u4e2a\u7279\u5b9a\u7684\u534f\u8bae\uff08NETLINK\uff09\u3002\u7528\u6237\u7a7a\u95f4\u8fdb\u7a0b\u53ef\u4ee5\u901a\u8fc7\u521b\u5efa Netlink \u5957\u63a5\u5b57\u548c\u5185\u6838\u901a\u4fe1\u3002\u5185\u6838\u548c\u7528\u6237\u7a7a\u95f4\u8fdb\u7a0b\u4e4b\u95f4\u7684\u901a\u4fe1\u662f\u57fa\u4e8e Netlink \u6d88\u606f\u7684\uff0c\u6bcf\u4e2a Netlink \u6d88\u606f\u5305\u542b\u4e00\u4e2a\u6d88\u606f\u5934\u548c\u4e00\u4e2a\u8d1f\u8f7d\uff08payload\uff09\uff0c\u8d1f\u8f7d\u53ef\u4ee5\u662f\u4efb\u4f55\u7ed3\u6784\u4f53\u6216\u4e8c\u8fdb\u5236\u6570\u636e\u3002 Netlink \u6d88\u606f\u7684\u7c7b\u578b\u548c\u683c\u5f0f\u7531\u5185\u6838\u5b9a\u4e49\u3002\u7528\u6237\u7a7a\u95f4\u8fdb\u7a0b\u9700\u8981\u4e86\u89e3\u5185\u6838\u7684 Netlink \u6d88\u606f\u683c\u5f0f\u548c\u7c7b\u578b\uff0c\u624d\u80fd\u6b63\u786e\u5730\u6784\u9020\u548c\u89e3\u6790 Netlink \u6d88\u606f\u3002\u5e38\u7528\u7684 Netlink \u6d88\u606f\u7c7b\u578b\u5305\u62ec\uff1a RTM_NEWLINK \u548c RTM_DELLINK\uff1a\u6dfb\u52a0\u548c\u5220\u9664\u7f51\u7edc\u63a5\u53e3\u3002 RTM_NEWADDR \u548c RTM_DELADDR\uff1a\u6dfb\u52a0\u548c\u5220\u9664 IP \u5730\u5740\u3002 RTM_NEWROUTE \u548c RTM_DELROUTE\uff1a\u6dfb\u52a0\u548c\u5220\u9664\u8def\u7531\u3002 RTM_NEWNEIGH \u548c RTM_DELNEIGH\uff1a\u6dfb\u52a0\u548c\u5220\u9664 ARP \u8868\u9879\u3002 Netlink \u53ef\u4ee5\u4f7f\u7528 C \u8bed\u8a00\u7684 socket API \u8fdb\u884c\u7f16\u7a0b\u3002 Netfilter \u00b6 Netfilter\u662fLinux\u5185\u6838\u4e2d\u7684\u4e00\u4e2a\u5b50\u7cfb\u7edf\uff0c\u7528\u4e8e\u5728\u6570\u636e\u5305\u4f20\u8f93\u8fc7\u7a0b\u4e2d\u8fdb\u884c\u8fc7\u6ee4\u548c\u64cd\u4f5c\u3002\u5b83\u652f\u6301\u5bf9\u7f51\u7edc\u6570\u636e\u5305\u8fdb\u884c\u5404\u79cd\u7c7b\u578b\u7684\u5904\u7406\uff0c\u5305\u62ec\u8fc7\u6ee4\u3001\u4fee\u6539\u3001\u91cd\u5b9a\u5411\u7b49\u3002Netfilter\u901a\u8fc7\u5728\u5185\u6838\u4e2d\u6ce8\u518c\u94a9\u5b50\u51fd\u6570\uff0c\u5728\u6570\u636e\u5305\u901a\u8fc7\u7f51\u7edc\u6808\u7684\u4e0d\u540c\u9636\u6bb5\u65f6\u8fdb\u884c\u62e6\u622a\u548c\u5904\u7406\u3002 Netfilter\u7684\u6838\u5fc3\u662fiptables\u547d\u4ee4\uff0c\u5b83\u53ef\u4ee5\u7528\u6765\u914d\u7f6eNetfilter\u89c4\u5219\u3002iptables\u547d\u4ee4\u53ef\u4ee5\u7528\u6765\u914d\u7f6e\u9632\u706b\u5899\u89c4\u5219\uff0cNAT\u89c4\u5219\uff0c\u9650\u5236\u8fde\u63a5\u901f\u5ea6\u7b49\u3002iptables\u547d\u4ee4\u901a\u8fc7\u5339\u914d\u4e0d\u540c\u7684\u6570\u636e\u5305\u5b57\u6bb5\uff08\u4f8b\u5982\u6e90IP\u5730\u5740\u3001\u76ee\u7684IP\u5730\u5740\u3001\u6e90\u7aef\u53e3\u3001\u76ee\u7684\u7aef\u53e3\u7b49\uff09\u6765\u8fdb\u884c\u8fc7\u6ee4\u3002 \u9664\u4e86iptables\u547d\u4ee4\uff0c\u8fd8\u6709\u5176\u4ed6\u4e00\u4e9b\u5de5\u5177\u53ef\u4ee5\u7528\u4e8e\u914d\u7f6eNetfilter\u89c4\u5219\uff0c\u4f8b\u5982nftables\u547d\u4ee4\u548cfirewalld\u670d\u52a1\u3002\u8fd9\u4e9b\u5de5\u5177\u63d0\u4f9b\u4e86\u66f4\u7075\u6d3b\u3001\u66f4\u5f3a\u5927\u7684\u914d\u7f6e\u9009\u9879\uff0c\u53ef\u4ee5\u5e2e\u52a9\u7ba1\u7406\u5458\u66f4\u597d\u5730\u7ba1\u7406\u548c\u4fdd\u62a4\u7f51\u7edc\u5b89\u5168\u3002 \u4e5f\u53ef\u4ee5\u7528\u4e8e\u5c06\u7f51\u7edc\u6570\u636e\u5305\u5b9a\u5411\u5230\u5355\u4e2a\u5bb9\u5668\u3002 \u66f4\u591a\u4fe1\u606f\u53ef\u4ee5\u53c2\u8003 LXC/LXD \u3002 \u5b89\u88c5Docker \u00b6 \u53c2\u8003 \u6307\u5bfc \u5b89\u88c5Docker\u5f15\u64ce\u3002 \u53c2\u8003 \u6307\u5bfc \u5b89\u88c5Docker\u684c\u9762\u7248\u3002 \u4e0b\u9762\u4ee5openSUSE\u4e3a\u4f8b\u5b89\u88c5Docker\u5f15\u64ce\u3002 sudo zypper in docker \u5728\u5b89\u88c5\u8fc7\u7a0b\u4e2d\uff0c\u5728\u64cd\u4f5c\u7cfb\u7edf\u4e2d\u4f1a\u81ea\u52a8\u521b\u5efa\u7ec4 docker \u3002 \u5c06vagrant\u7528\u6237\u52a0\u5165docker\u7ec4\uff0c\u5219vagrant\u7528\u6237\u53ef\u4ee5\u5728\u4e0b\u6b21\u767b\u5f55\u540e\u4e0e\u672c\u673a\u7684Docker\u5b88\u62a4\u8fdb\u7a0b\uff08daemon\uff09\u8fdb\u884c\u901a\u4fe1\u3002Docker\u5b88\u62a4\u8fdb\u7a0b\u76d1\u542c\u672c\u5730\u5957\u63a5\u5b57\uff0c\u53ea\u80fd\u7531root\u7528\u6237\u548cdocker\u7ec4\u7684\u6210\u5458\u8bbf\u95ee\u3002 sudo usermod -aG docker $USER \u542f\u7528\u5e76\u542f\u52a8 Docker \u5f15\u64ce\u3002 sudo systemctl enable docker.service sudo systemctl start docker.service sudo systemctl status docker.service \u4e0b\u9762\u901a\u8fc7\u4e00\u4e2a\u5bb9\u5668 alpine \u7684\u4f8b\u5b50\u6765\u6f14\u793a\u5728\u76ee\u5f55 /opt/test \u4e0b\u6a21\u62df\u5b9e\u73b0choot\u3002 mkdir test cd test wget https://dl-cdn.alpinelinux.org/alpine/v3.13/releases/x86_64/alpine-minirootfs-3.13.4-x86_64.tar.gz tar zxvf alpine-minirootfs-3.13.4-x86_64.tar.gz -C alpine-minirootfs/ \u67e5\u770b\u5f53\u524d\u76ee\u5f55\u7ed3\u6784\uff1a tree ./test -L 1 \u8f93\u51fa\u7ed3\u679c\uff1a ./test \u251c\u2500\u2500 alpine-minirootfs-3.13.4-x86_64.tar.gz \u251c\u2500\u2500 bin \u251c\u2500\u2500 dev \u251c\u2500\u2500 etc \u251c\u2500\u2500 home \u251c\u2500\u2500 lib \u251c\u2500\u2500 media \u251c\u2500\u2500 mnt \u251c\u2500\u2500 opt \u251c\u2500\u2500 proc \u251c\u2500\u2500 root \u251c\u2500\u2500 run \u251c\u2500\u2500 sbin \u251c\u2500\u2500 srv \u251c\u2500\u2500 sys \u251c\u2500\u2500 tmp \u251c\u2500\u2500 usr \u2514\u2500\u2500 var \u901a\u8fc7\u547d\u4ee4 unshare \u6302\u8f7d\u76ee\u5f55 /opt/test/proc \u5230\u67d0\u4e2a\u6587\u4ef6\u6765\u5b9e\u73b0\u5ba2\u6237\u5b50\u7cfb\u7edf\u3002 sudo mount -t tmpfs tmpfs /opt/test/proc sudo unshare --pid --mount-proc = $PWD /test/proc --fork chroot ./test/ /bin/sh / # ps -ef PID USER TIME COMMAND 1 root 0 :00 /bin/sh 2 root 0 :00 ps -ef / # touch 123 / # ls 123 123 \u6587\u4ef6 123 \u5728\u5ba2\u6237\u5b50\u7cfb\u7edf\u4e2d\u5df2\u521b\u5efa\uff0c\u5bf9\u5e94\u4e3b\u7cfb\u7edf\u4e2d\u4e5f\u53ef\u4ee5\u5bf9\u5176\u8fdb\u884c\u8bfb\u5199\u64cd\u4f5c\u3002\u6bd4\u5982\uff0c\u4fee\u6539\u6587\u4ef6 123 \u7684\u5185\u5bb9\u3002 su - ls 123 echo hello > 123 \u6587\u4ef6 123 \u4fee\u6539\u540e\u7684\u5185\u5bb9\u5728\u5ba2\u6237\u673a\u91cc\u9762\u4e5f\u53ef\u89c1\u3002 / # cat 123 hello \u5728\u4e3b\u7cfb\u7edf\u4e2d\u518d\u521b\u5efa\u4e24\u4e2a\u5b50\u76ee\u5f55 /opt/test-1 \u548c /opt/test-2 \u3002 mkdir test-1 mkdir test-2 \u521b\u5efa2\u4e2a\u5ba2\u6237\u5b50\u7cfb\u7edf\uff0c\u5e76\u5c06\u4e0a\u9762\u7684\u4e24\u4e2a\u5b50\u76ee\u5f55\u6302\u5728\u5230\u5404\u81ea\u7684 /opt/test/home/ \u76ee\u5f55\u3002 sudo mount --bind /opt/test-1 /opt/test/home/ sudo unshare --pid --mount-proc = $PWD /test/proc --fork chroot ./test/ /bin/sh / # cd /home /home # echo \"test-1\" > 123.1 /home # cat 123.1 test-1 sudo mount --bind /opt/test-2 /opt/test/home/ sudo unshare --pid --mount-proc = $PWD /test/proc --fork chroot ./test/ /bin/sh / # cd /home /home # echo \"test-2\" > 123.2 /home # cat 123.2 test-2 ll test/home ll test-1/ ll test-2/ \u901a\u8fc7\u4e0a\u9762\u7684\u6f14\u793a\uff0c\u53ef\u4ee5\u5f97\u51fa\u7ed3\u8bba\uff0c\u4e24\u4e2a\u5ba2\u6237\u5b50\u7cfb\u7edf\u6302\u5728\u5230\u540c\u4e00\u4e2a\u4e3b\u7cfb\u7edf\u76ee\u5f55\u65f6\uff0c\u5b50\u7cfb\u7edf\u65f6\u5171\u4eab\u4e3b\u7cfb\u7edf\u76ee\u5f55\uff0c\u5e76\u76f8\u4e92\u5f71\u54cd\u3002 \u5bb9\u5668\u751f\u547d\u5468\u671f \u00b6 \u6982\u8ff0 \u00b6 \u9884\u5148\u4e0b\u8f7d\u4e0b\u5217\u955c\u50cf\u3002 docker image pull busybox docker image pull nginx docker image pull alpine docker image pull jenkins/jenkins:lts docker image pull golang:1.12-alpine docker image pull golang \u521b\u5efa\u5e76\u4ea4\u4e92\u5f0f\u8fd0\u884c\u4e00\u4e2a\u65b0\u7684busybox\u5bb9\u5668\uff0c\u5e76\u8fde\u63a5\u4e00\u4e2a\u4f2a\u7ec8\u7aef\uff08pseudo terminal\uff09\u3002 \u5728\u5bb9\u5668\u5185\uff0c\u4f7f\u7528 top \u547d\u4ee4\u67e5\u627e /bin/sh \u6b63\u5728\u4f5c\u4e3aPID\u4e3a1\u7684\u8fdb\u7a0b\u8fd0\u884c\uff0c\u4ee5\u53ca top \u8fdb\u7a0b\u4e5f\u5728\u8fd0\u884c\u3002 \u7136\u540e\uff0c\u9000\u51fa\u5bb9\u5668\u3002 docker image ls docker run -d -it --name busybox_v1 -v /opt/test:/docker busybox:latest /bin/sh docker container ps -a docker exec -it 185efe490507 /bin/sh / # top Mem: 3627396K used, 12731512K free, 10080K shrd, 2920K buff, 2999340K cached CPU: 0 .0% usr 0 .1% sys 0 .0% nic 99 .8% idle 0 .0% io 0 .0% irq 0 .0% sirq Load average: 0 .38 1 .09 1 .29 2 /277 14 PID PPID USER STAT VSZ %VSZ CPU %CPU COMMAND 1 0 root S 1332 0 .0 1 0 .0 /bin/sh 8 0 root S 1332 0 .0 2 0 .0 /bin/sh 14 8 root R 1328 0 .0 1 0 .0 top / # exitbuild \u542f\u52a8\u4e00\u4e2a\u65b0\u7684 Nginx \u5bb9\u5668\uff0c\u5e76\u4ee5\u72ec\u7acb\u6a21\u5f0f\uff08detached mode\uff09\u8fd0\u884c\u3002 \u4f7f\u7528 docker exec \u547d\u4ee4\u5728 Nginx \u5bb9\u5668\u4e2d\u542f\u52a8\u53e6\u4e00\u4e2a shell\uff08 /bin/sh \uff09\u3002 \u4f7f\u7528 ps \u547d\u4ee4\u67e5\u770b\u5bb9\u5668\u4e2d\u6b63\u5728\u8fd0\u884c\u7684 sh \u548c ps \u547d\u4ee4\uff08\u5728\u4e0a\u4e00\u6b65\u6267\u884c\u7684\uff09\u3002 docker run -d -it --name nginx_v1 -v /opt/test:/docker nginx:latest /bin/sh docker container ps -a docker exec -it edb640127a0d /bin/sh # ps /bin/sh: 2 : ps: not found # apt-get update && apt-get install -y procps # ps PID TTY TIME CMD 8 pts/1 00 :00:00 sh 351 pts/1 00 :00:00 ps # exit \u901a\u8fc7\u4e0b\u9762\u547d\u4ee4\u53ef\u4ee5\u770b\u52302\u4e2a\u73b0\u5728\u8fd0\u884c\u4e2d\u7684\u5bb9\u5668\u3002 docker container ps -a \u4f7f\u7528 docker logs \u547d\u4ee4\u663e\u793a\u6211\u4eec\u521a\u521a\u9000\u51fa\u7684\u5bb9\u5668\u7684\u65e5\u5fd7\u3002\u9009\u9879 --since 35m \u8868\u793a\u663e\u793a\u6700\u8fd1 35 \u5206\u949f\u5185\u7684\u65e5\u5fd7\u3002 docker logs nginx_v1 --details --since 35m docker logs busybox_v1 --details --since 35m \u4f7f\u7528 docker stop \u547d\u4ee4\u6765\u505c\u6b62 nginx \u5bb9\u5668\u3002 docker stop busybox_v1 docker stop nginx_v1 docker container ps -a \u4f7f\u7528\u4e0a\u8ff0\u547d\u4ee4 docker container ps -a \uff0c\u6211\u4eec\u53ef\u4ee5\u83b7\u53d6\u6240\u6709\u6b63\u5728\u8fd0\u884c\u548c\u5df2\u9000\u51fa\u7684\u5bb9\u5668\u5217\u8868\u3002\u4f7f\u7528 docker rm \u5c06\u5176\u5220\u9664\u3002\u4f7f\u7528 docker rm $(docker ps -aq) \u6765\u6e05\u7406\u4e3b\u673a\u4e0a\u7684\u6240\u6709\u5bb9\u5668\u3002\u8bf7\u8c28\u614e\u4f7f\u7528\uff01 docker rm busybox_v1 docker container ps -a \u7aef\u53e3\u548c\u5377 \u00b6 \u73b0\u5728\u542f\u52a8\u4e00\u4e2a\u65b0\u7684 nginx \u5bb9\u5668\uff0c\u5e76\u5c06 nginx web \u670d\u52a1\u5668\u7684\u7aef\u53e3\u5bfc\u51fa\u5230 Docker \u968f\u673a\u9009\u62e9\u7684\u7aef\u53e3\u3002 \u6211\u4eec\u53ef\u4ee5\u4f7f\u7528\u547d\u4ee4 docker ps \u627e\u51fa web \u670d\u52a1\u5668\u8f6c\u53d1\u5230\u4e86\u54ea\u4e2a\u7aef\u53e3\u3002\u5728\u4e3b\u673a\u4e0a\u4f7f\u7528\u8f6c\u53d1\u7684\u7aef\u53e3\u53f7\u8bbf\u95ee docker http://localhost: \u3002 docker container ps -a docker run -d -P --name nginx_v2 nginx:latest docker container ps -a Start another nginx container and expose port to 1080 on host as an example via http://localhost:1080 . \u542f\u52a8\u53e6\u4e00\u4e2anginx\u5bb9\u5668\uff0c\u5c06\u5176\u7aef\u53e3\u6620\u5c04\u5230\u4e3b\u673a\u76841080\u7aef\u53e3\uff0c\u53ef\u4ee5\u901a\u8fc7 http://localhost:1080 \u8bbf\u95ee\u3002 docker run -d -p 1080 :80 --name nginx_v3 nginx:latest docker container ps -a \u4f7f\u7528 docker inspect \u547d\u4ee4\u67e5\u627e\u955c\u50cf\u66b4\u9732\u7684\u7aef\u53e3\u53f7\uff0c\u8f93\u51faJSON\u683c\u5f0f\u6587\u4ef6\uff0c\u7f51\u7edc\u4fe1\u606f\uff08IP\u3001\u7f51\u5173\u3001\u7aef\u53e3\u7b49\uff09\u662f\u8f93\u51faJSON\u683c\u5f0f\u7684\u4e00\u90e8\u5206\u3002 docker inspect nginx_v3 \u5728\u76ee\u5f55 /opt/test \u4e2d\u521b\u5efa\u4e00\u4e2a\u540d\u4e3a index.html \u7684\u6587\u4ef6\uff0c\u5176\u5185\u5bb9\u5982\u4e0b\uff1a < html > < head > < title > Sample Website from my container < body > < h1 > This is a custom website. < p > This website is served from my < a href = \"http://www.docker.com\" target = \"_blank\" > Docker container. \u542f\u52a8\u4e00\u4e2a\u65b0\u5bb9\u5668\uff0c\u5c06\u4e3b\u673a\u76ee\u5f55 /opt/test \u4e0e\u5bb9\u5668\u76ee\u5f55 /usr/share/nginx/html \u7ed1\u5b9a\u6302\u8f7d\u4e3a\u4e00\u4e2a\u5377\uff0c\u4ee5\u4fbfNginx\u53ef\u4ee5\u901a\u8fc7 http://localhost:49159/ \u53d1\u5e03\u6211\u4eec\u521a\u521b\u5efa\u7684html\u6587\u4ef6\uff0c\u800c\u4e0d\u662fNginx\u9ed8\u8ba4\u7684\u9875\u9762\u3002 docker run -d -P --mount type = bind,source = /opt/test/,target = /usr/share/nginx/html --name nginx_v3-1 nginx:latest docker container ps -a \u68c0\u67e5Nginx\u914d\u7f6e\u6587\u4ef6\uff0c\u67e5\u770b\u5bb9\u5668\u4e2dhtml\u4e3b\u9875\u5b58\u50a8\u7684\u4f4d\u7f6e\u3002 docker exec -it nginx_v3-1 /bin/sh # cd /etc/nginx/conf.d # ls default.conf # cat default.conf server { listen 80 ; listen [ :: ] :80 ; server_name localhost ; #access_log /var/log/nginx/host.access.log main; location / { root /usr/share/nginx/html ; <-- index index.html index.htm ; } #error_page 404 /404.html; # redirect server error pages to the static page /50x.html # error_page 500 502 503 504 /50x.html ; location = /50x.html { root /usr/share/nginx/html ; } # proxy the PHP scripts to Apache listening on 127.0.0.1:80 # #location ~ \\.php$ { # proxy_pass http://127.0.0.1; #} # pass the PHP scripts to FastCGI server listening on 127.0.0.1:9000 # #location ~ \\.php$ { # root html; # fastcgi_pass 127.0.0.1:9000; # fastcgi_index index.php; # fastcgi_param SCRIPT_FILENAME /scripts$fastcgi_script_name; # include fastcgi_params; #} # deny access to .htaccess files, if Apache's document root # concurs with nginx's one # #location ~ /\\.ht { # deny all; #} } # cd /usr/share/nginx/html # cat index.html Sample Website from my container

This is a custom website.

This website is served from my Docker container.

# \u63a8\u8350\u4f7f\u7528\u5377 API \u6765\u5b9e\u73b0\u6570\u636e\u6301\u4e45\u5316\uff0c\u800c\u4e0d\u662f\u5c06\u6570\u636e\u5b58\u50a8\u5728 Docker \u5bb9\u5668\u4e2d\u3002Docker \u652f\u6301\u4e24\u79cd\u6302\u8f7d\u65b9\u5f0f\uff1a \u7ed1\u5b9a\u6302\u8f7d\uff08Bind mounts\uff09\uff1a \u5c06\u672c\u5730\u4e3b\u673a\u76ee\u5f55\u6302\u8f7d\u5230\u5bb9\u5668\u4e2d\u7684\u67d0\u4e2a\u8def\u5f84\u3002 \u6302\u8f7d\u540e\uff0c\u76ee\u6807\u76ee\u5f55\u4e2d\u539f\u6709\u7684\u6240\u6709\u5185\u5bb9\u5c06\u88ab\u9690\u85cf\u3002 \u4f8b\u5982\uff0c\u5982\u679c\u6211\u4eec\u60f3\u8981\u6ce8\u5165\u67d0\u4e9b\u914d\u7f6e\u6587\u4ef6\uff0c\u6211\u4eec\u9700\u8981\u81ea\u5df1\u5199\u5bf9\u5e94\u7684\u914d\u7f6e\u6587\u4ef6\uff0c\u5c06\u5176\u5b58\u50a8\u5728 Docker \u4e3b\u673a\u4e0a\u7684 /home/container/config \u8def\u5f84\u4e0b\uff0c\u5e76\u5c06\u6b64\u76ee\u5f55\u7684\u5185\u5bb9\u6302\u8f7d\u5230 /usr/application/config \uff08\u5047\u8bbe\u5e94\u7528\u7a0b\u5e8f\u4ece\u6b64\u5904\u8bfb\u53d6\u914d\u7f6e\uff09\u3002 \u547d\u4ee4\uff1a docker run --mount type=bind,source=,target= \u2026 \u547d\u540d\u5377\uff08Named volumes\uff09\uff1a Docker \u53ef\u4ee5\u521b\u5efa\u4e00\u4e2a\u72ec\u7acb\u7684\u5b58\u50a8\u5377\uff0c\u5176\u751f\u547d\u5468\u671f\u72ec\u7acb\u4e8e\u5bb9\u5668\u4f46\u4ecd\u7531 Docker \u7ba1\u7406\u3002 \u5728\u521b\u5efa\u65f6\uff0c\u6302\u8f7d\u76ee\u6807\u7684\u5185\u5bb9\u5c06\u5408\u5e76\u5230\u5377\u4e2d\u3002 \u547d\u4ee4\uff1a docker run --mount source=,target= \u2026 \u5982\u4f55\u533a\u5206\u7ed1\u5b9a\u6302\u8f7d\u548c\u547d\u540d\u5377\uff1f \u5f53\u6307\u5b9a\u7edd\u5bf9\u8def\u5f84\u65f6\uff0cDocker \u4f1a\u8ba4\u4e3a\u8fd9\u662f\u4e00\u4e2a\u7ed1\u5b9a\u6302\u8f7d\u3002 \u5f53\u6211\u4eec\u4ec5\u63d0\u4f9b\u540d\u79f0\uff08\u5982\u76f8\u5bf9\u8def\u5f84 config \uff09\u65f6\uff0c\u5b83\u4f1a\u8ba4\u4e3a\u8fd9\u662f\u4e00\u4e2a\u547d\u540d\u5377\uff0c\u5e76\u521b\u5efa\u4e00\u4e2a\u540d\u4e3a config \u7684\u5377\u3002 \u6ce8\uff1a\u6301\u4e45\u5b58\u50a8\u7531\u4e3b\u673a\u63d0\u4f9b\uff0c\u53ef\u4ee5\u76f4\u63a5\u662f\u4e3b\u673a\u6587\u4ef6\u7cfb\u7edf\u7684\u4e00\u90e8\u5206\uff0c\u4e5f\u53ef\u4ee5\u662f NFS \u6302\u8f7d\u3002 Dockerfile \u00b6 \u8ba9\u6211\u4eec\u7528 Dockerfile \u6784\u5efa\u4e00\u4e2a\u955c\u50cf\uff0c\u5bf9\u5176\u8fdb\u884c\u6253\u6807\u7b7e\u5e76\u4e0a\u4f20\u5230\u955c\u50cf\u4ed3\u5e93\u3002 \u83b7\u53d6 Docker \u955c\u50cf\u7684\u6784\u5efa\u5386\u53f2\u8bb0\u5f55\u3002 docker image history nginx:latest \u521b\u5efa\u4e00\u4e2a\u7a7a\u7684\u76ee\u5f55 /opt/tmp-1 \uff0c\u8fdb\u5165\u8be5\u76ee\u5f55\u5e76\u5728\u5176\u4e2d\u521b\u5efa index.html \u6587\u4ef6\u3002 /opt/tmp-1> cat index.html Sample Website from my container

This is a custom website.

This website is served from my Docker container.

\u4f7f\u7528 FROM \u6765\u6269\u5c55\u4e00\u4e2a\u5df2\u6709\u7684\u955c\u50cf\uff0c\u5e76\u6307\u5b9a\u7248\u672c\u53f7\u3002 \u4f7f\u7528 COPY \u5c06\u4e00\u4e2a\u65b0\u7684\u9ed8\u8ba4\u7f51\u7ad9\u590d\u5236\u5230\u955c\u50cf\u4e2d\uff0c\u4f8b\u5982 /usr/share/nginx/html \u3002 \u4e3aNginx\u521b\u5efaSSL\u914d\u7f6e /opt/tmp-1/ssl.conf \u3002 server { listen 443 ssl; server_name localhost; ssl_certificate /etc/nginx/ssl/nginx.crt; ssl_certificate_key /etc/nginx/ssl/nginx.key; location / { root /usr/share/nginx/html; index index.html index.htm; } } \u4f7f\u7528OpenSSL\u521b\u5efa\u4e00\u4e2a\u81ea\u7b7e\u540d\u8bc1\u4e66\uff0c\u4ee5\u4fbfSSL/TLS\u5de5\u4f5c\u3002 \u4f7f\u7528\u4ee5\u4e0b\u547d\u4ee4\u521b\u5efa\u4e00\u4e2a\u52a0\u5bc6\u5bc6\u94a5\u548c\u8bc1\u4e66\u3002 openssl req -x509 -nodes -newkey rsa:4096 -keyout nginx.key -out nginx.crt -days 365 -subj \"/CN= $( hostname ) \" \u4e3a\u4e86\u542f\u7528\u52a0\u5bc6\u7684HTTPS\uff0c\u6211\u4eec\u9700\u8981\u4f7f\u7528 EXPOSE \u6307\u4ee4\u516c\u5f00 443 \u7aef\u53e3\u3002\u9ed8\u8ba4\u7684nginx\u955c\u50cf\u4ec5\u516c\u5f00\u7aef\u53e3 80 \uff0c\u7528\u4e8e\u975e\u52a0\u5bc6\u7684HTTP\u3002 \u5728 /opt/tmp-1 \u6587\u4ef6\u5939\u4e2d\u521b\u5efa\u4ee5\u4e0bDockerfile\u3002 cat Dockerfile \u8f93\u51fa\uff1a FROM nginx:latest # copy the custom website into the image COPY index.html /usr/share/nginx/html # copy the SSL configuration file into the image COPY ssl.conf /etc/nginx/conf.d/ssl.conf # download the SSL key and certificate into the image COPY nginx.key /etc/nginx/ssl/ COPY nginx.crt /etc/nginx/ssl/ # expose the HTTPS port EXPOSE 443 \u81f3\u6b64\uff0c\u6211\u4eec\u5728\u76ee\u5f55 /opt/tmp-1 \u4e0b\u67095\u4e2a\u6587\u4ef6\u3002 ls /opt/tmp-1 \u8f93\u51fa\uff1a Dockerfile index.html nginx.crt nginx.key ssl.conf \u4f7f\u7528 docker build \u547d\u4ee4\u6765\u6784\u5efa\u955c\u50cf\uff0c\u5e76\u5c06\u5bb9\u5668\u768480\u548c443\u7aef\u53e3\u8f6c\u53d1\u3002 docker build -t nginx:my1 /opt/tmp-1/ docker image ls docker run -d -p 1086 :80 -p 1088 :443 --name nginx_v5 nginx:my1 docker container ps -a \u901a\u8fc7\u4e0b\u9762\u4e24\u4e2a\u94fe\u63a5\u6765\u9a8c\u8bc1\u4e0a\u9762\u7684\u53d8\u5316\u662f\u5426\u751f\u6548\u3002 http://localhost:1086/ https://localhost:1088/ \u5728 DockerHub \u6ce8\u518c\u4e00\u4e2a\u4e2a\u4eba\u8d26\u53f7\uff0c\u542f\u7528 Docker Hub \u4e2d\u7684\u8bbf\u95ee\u4ee4\u724c\u4ee5\u8fdb\u884c CLI \u5ba2\u6237\u7aef\u8eab\u4efd\u9a8c\u8bc1\u3002 docker login \u8f93\u5165\u7528\u6237\u540d\u548c\u5bc6\u7801\u3002 Username: Password: \u7ed9\u8fd9\u4e2a\u955c\u50cf\u52a0\u4e0a\u4e00\u4e2a\u6807\u7b7e\uff0c\u4f8b\u5982\uff1asecure_nginx_0001\uff0c\u7248\u672c\u53f7\u4e3a v1\u3002 docker tag nginx:my1 secure_nginx_0001:v1 docker push secure_nginx_0001:v1 docker image ls \u591a\u9636\u6bb5Dockerfile \u00b6 \u4e0b\u9762\u7684\u4f8b\u5b50\u662f\u6f14\u793a\u4e00\u4e2a\u591a\u9636\u6bb5\uff08Multi-stage\uff09\u6784\u5efa\u7684\u4f8b\u5b50\u3002\u5728Docker\u7684\u4e0a\u4e0b\u6587\u4e2d\uff0c\u591a\u9636\u6bb5\uff08Multi-stage\uff09\u610f\u5473\u7740\u6211\u4eec\u53ef\u4ee5\u6709\u591a\u4e2a\u5e26\u6709 FROM \u5173\u952e\u5b57\u7684\u884c\u3002 \u521b\u5efa\u6587\u4ef6\u5939 /opt/tmp-2 \u548c /opt/tmp-2/tmpl \u3002\u521b\u5efa\u6587\u4ef6 edit.html \uff0c view.html \uff0c wiki.go \u3002 \u6587\u4ef6\u7ed3\u6784\u5982\u4e0b\uff1a tree -l /opt/tmp-2 \u8f93\u51fa\u7ed3\u679c\uff1a . \u251c\u2500\u2500 tmpl \u2502 \u251c\u2500\u2500 edit.html \u2502 \u2514\u2500\u2500 view.html \u2514\u2500\u2500 wiki.go \u521b\u5efa\u4e00\u4e2a\u65b0\u7684Dockerfile\u3002 cat Dockerfile \u6587\u4ef6\u5185\u5bb9\uff1a # app builder stage FROM golang:1.12-alpine as builder # # copy the go source code over and build the binary WORKDIR /go/src COPY wiki.go /go/src/wiki.go RUN go build wiki.go # app exec stage # separate & new image starts here!# FROM alpine:3.9 # prepare file system etc RUN mkdir -p /app/data /app/tmpl && adduser -S -D -H -h /app appuser COPY tmpl/* /app/tmpl/ # get the compiled binary from the previous stage COPY --from=builder /go/src/wiki /app/wiki # prepare runtime env RUN chown -R appuser /app USER appuser WORKDIR /app # expose app port & set default command EXPOSE 8080 CMD [\"/app/wiki\"] \u7528\u4e0a\u4e00\u6b65\u521b\u5efa\u7684Dockerfile\u6765\u521b\u5efa\u65b0\u666f\u8c61\u3002 docker build -t lizard/golang:my1 /opt/tmp-2/ \u4ee5\u72ec\u7acb\u6a21\u5f0f\uff08detached\uff09\u8fd0\u884c\u8fd9\u4e2a\u955c\u50cf\uff0c\u5e76\u5c06\u5bb9\u5668\u7aef\u53e3 8080 \u8f6c\u53d1\u5230\u4e3b\u673a\u7aef\u53e3 1090 \u3002 docker run -d -p 1090 :8080 --name golan_v1 lizard/golang:my1 \u901a\u8fc7\u94fe\u63a5 http://localhost:1090 \u8bbf\u95ee\u8fd9\u4e2a\u8fd0\u884c\u7684\u5bb9\u5668\u3002 \u5bf9\u6211\u4eec\u521a\u521a\u521b\u5efa\u7684\u65b0\u7684golang\u955c\u50cf\u8fdb\u884c\u6807\u7b7e\uff0c\u5e76\u4e14\u4e0a\u4f20\u5230Dockerhub\u3002 docker tag lizard/golang:my1 /golang_0001:v1 docker push /golang_0001:v1","title":"Docker\u57fa\u7840"},{"location":"k8s/cka_cn/foundamentals/docker/#cka4docker","text":"","title":"CKA\u81ea\u5b66\u7b14\u8bb04:Docker\u57fa\u7840"},{"location":"k8s/cka_cn/foundamentals/docker/#_1","text":"\u4e86\u89e3Linux\u539f\u8bed\u7684\u6982\u5ff5\u548c\u5305\u542b\u7684\u7279\u6027\u3002 \u5b89\u88c5Docker\uff0c\u4e86\u89e3\u57fa\u672c\u7684Docker\u547d\u4ee4\u548cDockerfile\u7684\u4f7f\u7528\u3002","title":"\u6458\u8981"},{"location":"k8s/cka_cn/foundamentals/docker/#_2","text":"\u64cd\u4f5c\u7cfb\u7edf\uff1aopenSUSE 15.3 cat /etc/os-release \u8f93\u51fa\u7ed3\u679c\uff1a NAME=\"openSUSE Leap\" VERSION=\"15.3\" ID=\"opensuse-leap\" ID_LIKE=\"suse opensuse\" VERSION_ID=\"15.3\" PRETTY_NAME=\"openSUSE Leap 15.3\" ANSI_COLOR=\"0;32\" CPE_NAME=\"cpe:/o:opensuse:leap:15.3\" BUG_REPORT_URL=\"https://bugs.opensuse.org\" HOME_URL=\"https://www.opensuse.org/\"","title":"\u7ec3\u4e60\u73af\u5883"},{"location":"k8s/cka_cn/foundamentals/docker/#linux","text":"\u5728\u64cd\u4f5c\u7cfb\u7edf\u4e2d\uff0c\u539f\u8bed\uff08primitives\uff09\u662f\u7528\u4e8e\u521b\u5efa\u66f4\u590d\u6742\u529f\u80fd\u7684\u57fa\u672c\u6784\u5efa\u5757\u6216\u64cd\u4f5c\u3002\u5728Linux\u4e2d\uff0c\u6709\u51e0\u79cd\u5e38\u7528\u7684\u539f\u8bed\u3002\u5305\u62ec\uff1a \u8fdb\u7a0b\uff08Processes\uff09\uff1a\u8fdb\u7a0b\u662f\u7a0b\u5e8f\u6216\u5e94\u7528\u7a0b\u5e8f\u7684\u8fd0\u884c\u5b9e\u4f8b\u3002\u5b83\u4eec\u662fLinux\u4e2d\u7684\u57fa\u672c\u5de5\u4f5c\u5355\u5143\uff0c\u7531\u5185\u6838\u7ba1\u7406\u3002 \u6587\u4ef6\uff08Files\uff09\uff1a\u6587\u4ef6\u662f\u5728Linux\u4e2d\u5b58\u50a8\u6570\u636e\u7684\u4e3b\u8981\u65b9\u5f0f\u3002\u5b83\u4eec\u53ef\u4ee5\u662f\u6587\u672c\u6587\u4ef6\u3001\u4e8c\u8fdb\u5236\u6587\u4ef6\u3001\u76ee\u5f55\u6216\u7279\u6b8a\u6587\u4ef6\uff0c\u5982\u8bbe\u5907\u6587\u4ef6\u3002 \u4fe1\u53f7\uff08Signals\uff09\uff1a\u4fe1\u53f7\u662f\u8fdb\u7a0b\u4e4b\u95f4\u6216\u8fdb\u7a0b\u4e0e\u5185\u6838\u4e4b\u95f4\u901a\u4fe1\u7684\u4e00\u79cd\u65b9\u5f0f\u3002\u5b83\u4eec\u7528\u4e8e\u901a\u77e5\u8fdb\u7a0b\u4e8b\u4ef6\uff0c\u4f8b\u5982\u4efb\u52a1\u5b8c\u6210\u6216\u9519\u8bef\u53d1\u751f\u7684\u60c5\u51b5\u3002 \u5957\u63a5\u5b57\uff08Sockets\uff09\uff1a\u5957\u63a5\u5b57\u662fLinux\u4e2d\u8fdb\u7a0b\u95f4\u901a\u4fe1\u7684\u4e00\u79cd\u65b9\u5f0f\u3002\u5b83\u4eec\u5141\u8bb8\u8fdb\u7a0b\u5728\u7f51\u7edc\u6216\u672c\u5730\u673a\u5668\u4e0a\u53d1\u9001\u548c\u63a5\u6536\u6570\u636e\u3002 \u7ebf\u7a0b\uff08Threads\uff09\uff1a\u7ebf\u7a0b\u662f\u8f7b\u91cf\u7ea7\u7684\u8fdb\u7a0b\uff0c\u4e0e\u5176\u7236\u8fdb\u7a0b\u5171\u4eab\u76f8\u540c\u7684\u5185\u5b58\u7a7a\u95f4\u548c\u8d44\u6e90\u3002\u5b83\u4eec\u901a\u5e38\u7528\u4e8e\u901a\u8fc7\u5141\u8bb8\u540c\u65f6\u6267\u884c\u591a\u4e2a\u4efb\u52a1\u6765\u63d0\u9ad8\u5e94\u7528\u7a0b\u5e8f\u7684\u6027\u80fd\u3002 \u7ba1\u9053\uff08Pipes\uff09\uff1a\u7ba1\u9053\u662f\u4e00\u79cd\u5c06\u4e00\u4e2a\u8fdb\u7a0b\u7684\u8f93\u51fa\u8fde\u63a5\u5230\u53e6\u4e00\u4e2a\u8fdb\u7a0b\u7684\u8f93\u5165\u7684\u65b9\u5f0f\u3002\u5b83\u4eec\u5141\u8bb8\u8fdb\u7a0b\u4ee5\u53d7\u63a7\u7684\u65b9\u5f0f\u8fdb\u884c\u901a\u4fe1\u548c\u4ea4\u6362\u6570\u636e\u3002 \u4fe1\u53f7\u91cf\uff08Semaphores\uff09\uff1a\u4fe1\u53f7\u91cf\u662fLinux\u4e2d\u63a7\u5236\u5bf9\u5171\u4eab\u8d44\u6e90\u8bbf\u95ee\u7684\u4e00\u79cd\u65b9\u5f0f\u3002\u5b83\u4eec\u5141\u8bb8\u8fdb\u7a0b\u534f\u8c03\u5b83\u4eec\u5bf9\u5171\u4eab\u8d44\u6e90\u7684\u8bbf\u95ee\uff0c\u5982\u6587\u4ef6\u6216\u5185\u5b58\u3002","title":"Linux\u539f\u8bed"},{"location":"k8s/cka_cn/foundamentals/docker/#chroot","text":"chroot\u4f7f\u7528pivot_root\uff0c\u4ee5\u5b9e\u73b0\u5c06*\u8fdb\u7a0b*\u7684\u6839\u76ee\u5f55\u66f4\u6539\u4e3a\u4efb\u4f55\u7ed9\u5b9a\u7684\u76ee\u5f55\u3002 a. \u6a21\u62df\u5bb9\u5668 \u4f7f\u7528 chroot \u547d\u4ee4\u53ef\u4ee5\u5728Linux\u7cfb\u7edf\u4e2d\u521b\u5efa\u4e00\u4e2a\u5bb9\u5668\u3002\u8be5\u5bb9\u5668\u53ef\u4ee5\u770b\u4f5c\u662f\u4e00\u4e2a\u865a\u62df\u7684\u6839\u6587\u4ef6\u7cfb\u7edf\uff0c\u5176\u4e2d\u8fd0\u884c\u7684\u8fdb\u7a0b\u53ea\u80fd\u8bbf\u95ee\u8be5\u6839\u6587\u4ef6\u7cfb\u7edf\u4e2d\u7684\u8d44\u6e90\u3002 \u4f8b\u5982\uff0c\u4ee5\u4e0b\u547d\u4ee4\u4f1a\u5c06\u5f53\u524d\u6839\u6587\u4ef6\u7cfb\u7edf\u66f4\u6539\u4e3a /tmp/myroot \u76ee\u5f55\uff1a chroot /tmp/myroot /bin/bash \u8fd9\u6761\u547d\u4ee4\u4f1a\u542f\u52a8\u4e00\u4e2a\u65b0\u7684Bash shell\uff0c\u8be5shell\u7684\u6839\u76ee\u5f55\u4e3a /tmp/myroot \u3002 b. \u66f4\u6539\u6839\u6587\u4ef6\u7cfb\u7edf chroot \u547d\u4ee4\u8fd8\u53ef\u7528\u4e8e\u66f4\u6539\u8fdb\u7a0b\u7684\u6839\u6587\u4ef6\u7cfb\u7edf\u3002\u4f8b\u5982\uff0c\u6211\u4eec\u53ef\u4ee5\u4f7f\u7528 chroot \u547d\u4ee4\u542f\u52a8\u4e00\u4e2a\u5177\u6709\u53e6\u4e00\u4e2a\u6839\u6587\u4ef6\u7cfb\u7edf\u7684\u8fdb\u7a0b\uff0c\u800c\u4e0d\u662f\u7cfb\u7edf\u7684\u9ed8\u8ba4\u6839\u6587\u4ef6\u7cfb\u7edf\u3002 \u4f8b\u5982\uff0c\u4ee5\u4e0b\u547d\u4ee4\u4f1a\u5c06\u5f53\u524d\u76ee\u5f55\uff08\u5373 ./ \uff09\u4f5c\u4e3a\u6839\u76ee\u5f55\uff0c\u5e76\u5728\u5176\u4e2d\u542f\u52a8\u4e00\u4e2a\u65b0\u7684Bash shell\uff1a sudo chroot . /bin/bash","title":"chroot"},{"location":"k8s/cka_cn/foundamentals/docker/#_3","text":"\u5728Linux\u64cd\u4f5c\u7cfb\u7edf\u4e2d\uff0cNamespace\uff08\u547d\u540d\u7a7a\u95f4\uff09\u662f\u4e00\u79cd\u673a\u5236\uff0c\u7528\u4e8e\u9694\u79bb\u4e0d\u540c\u8fdb\u7a0b\u7684\u8d44\u6e90\u3002\u901a\u8fc7Namespace\u673a\u5236\uff0c\u53ef\u4ee5\u5c06\u4e00\u7ec4\u8fdb\u7a0b\u53ca\u5176\u5b50\u8fdb\u7a0b\u7684\u89c6\u56fe\u9694\u79bb\u5728\u4e00\u4e2a\u72ec\u7acb\u7684Namespace\u4e2d\uff0c\u4ece\u800c\u5b9e\u73b0\u8fdb\u7a0b\u4e4b\u95f4\u8d44\u6e90\u9694\u79bb\u7684\u76ee\u7684\u3002 \u4e0b\u9762\u662f\u4e00\u4e9b\u5e38\u89c1\u7684Namespace\u7c7b\u578b\u53ca\u5176\u4f5c\u7528\uff1a Mount Namespace\uff1a\u9694\u79bb\u6587\u4ef6\u7cfb\u7edf\u6302\u8f7d\u70b9\u3002\u53ef\u4ee5\u4f7f\u4e0d\u540c\u8fdb\u7a0b\u62e5\u6709\u81ea\u5df1\u7684\u72ec\u7acb\u7684\u6587\u4ef6\u7cfb\u7edf\u89c6\u56fe\u3002 PID Namespace\uff1a\u9694\u79bb\u8fdb\u7a0bID\u53f7\u3002\u53ef\u4ee5\u4f7f\u4e0d\u540c\u8fdb\u7a0b\u62e5\u6709\u81ea\u5df1\u7684\u8fdb\u7a0bID\u53f7\u7a7a\u95f4\uff0c\u907f\u514d\u8fdb\u7a0b\u4e4b\u95f4\u7684PID\u51b2\u7a81\u3002 Network Namespace\uff1a\u9694\u79bb\u7f51\u7edc\u6808\u3002\u53ef\u4ee5\u4f7f\u4e0d\u540c\u8fdb\u7a0b\u62e5\u6709\u81ea\u5df1\u7684\u72ec\u7acb\u7684\u7f51\u7edc\u6808\uff0c\u4ece\u800c\u907f\u514d\u8fdb\u7a0b\u4e4b\u95f4\u7684\u7f51\u7edc\u51b2\u7a81\u3002 IPC Namespace\uff1a\u9694\u79bb\u8fdb\u7a0b\u95f4\u901a\u4fe1\uff08IPC\uff09\u673a\u5236\u3002\u53ef\u4ee5\u4f7f\u4e0d\u540c\u8fdb\u7a0b\u62e5\u6709\u81ea\u5df1\u7684\u72ec\u7acb\u7684IPC\u7a7a\u95f4\uff0c\u4ece\u800c\u907f\u514dIPC\u673a\u5236\u5e26\u6765\u7684\u8d44\u6e90\u7ade\u4e89\u3002 UTS Namespace\uff1a\u9694\u79bb\u4e3b\u673a\u540d\u548c\u57df\u540d\u3002\u53ef\u4ee5\u4f7f\u4e0d\u540c\u8fdb\u7a0b\u62e5\u6709\u81ea\u5df1\u7684\u72ec\u7acb\u7684\u4e3b\u673a\u540d\u548c\u57df\u540d\u7a7a\u95f4\uff0c\u4ece\u800c\u907f\u514d\u8fdb\u7a0b\u4e4b\u95f4\u7684\u547d\u540d\u51b2\u7a81\u3002 Primitives namespace\u548cNamespace\u662f\u4e24\u4e2a\u4e0d\u540c\u7684\u6982\u5ff5\u3002 Namespace\u662fLinux\u64cd\u4f5c\u7cfb\u7edf\u63d0\u4f9b\u7684\u4e00\u79cd\u673a\u5236\uff0c\u7528\u4e8e\u9694\u79bb\u4e0d\u540c\u8fdb\u7a0b\u7684\u8d44\u6e90\uff0c\u4ee5\u5b9e\u73b0\u8fdb\u7a0b\u4e4b\u95f4\u7684\u8d44\u6e90\u9694\u79bb\u548c\u73af\u5883\u9694\u79bb\u3002\u4f8b\u5982\uff0cPID Namespace\u53ef\u4ee5\u4f7f\u4e0d\u540c\u8fdb\u7a0b\u62e5\u6709\u81ea\u5df1\u7684\u72ec\u7acb\u7684PID\u53f7\u7a7a\u95f4\uff0c\u907f\u514d\u8fdb\u7a0b\u4e4b\u95f4\u7684PID\u51b2\u7a81\uff1bNetwork Namespace\u53ef\u4ee5\u4f7f\u4e0d\u540c\u8fdb\u7a0b\u62e5\u6709\u81ea\u5df1\u7684\u72ec\u7acb\u7684\u7f51\u7edc\u6808\uff0c\u4ece\u800c\u907f\u514d\u8fdb\u7a0b\u4e4b\u95f4\u7684\u7f51\u7edc\u51b2\u7a81\u7b49\u3002 Primitives namespace\u662f\u4e00\u79cd\u65b0\u7684\u6280\u672f\u6982\u5ff5\uff0c\u5b83\u662f\u6307\u5c06\u4e0d\u540c\u7684\u57fa\u672c\u64cd\u4f5c\uff08\u4f8b\u5982\u8bfb\u5199\u6587\u4ef6\u3001\u521b\u5efa\u8fdb\u7a0b\u3001\u7f51\u7edc\u901a\u4fe1\u7b49\uff09\u4f5c\u4e3a\u539f\u8bed\u8fdb\u884c\u9694\u79bb\u548c\u5c01\u88c5\uff0c\u4f7f\u5f97\u5e94\u7528\u7a0b\u5e8f\u53ef\u4ee5\u5728\u8fd9\u4e9b\u9694\u79bb\u7684\u539f\u8bed\u4e0a\u6784\u5efa\u51fa\u81ea\u5df1\u7684\u9694\u79bb\u73af\u5883\u3002\u4f8b\u5982\uff0c\u53ef\u4ee5\u901a\u8fc7\u9694\u79bb\u6587\u4ef6\u7cfb\u7edf\u8bfb\u5199\u64cd\u4f5c\u6765\u5b9e\u73b0\u5bb9\u5668\u7ea7\u522b\u7684\u6587\u4ef6\u7cfb\u7edf\u9694\u79bb\uff1b\u901a\u8fc7\u9694\u79bb\u7f51\u7edc\u901a\u4fe1\u64cd\u4f5c\u6765\u5b9e\u73b0\u5bb9\u5668\u7ea7\u522b\u7684\u7f51\u7edc\u9694\u79bb\u7b49\u3002 \u56e0\u6b64\uff0cNamespace\u548cPrimitives namespace\u662f\u4e24\u4e2a\u4e0d\u540c\u7684\u6982\u5ff5\uff0c\u867d\u7136\u5b83\u4eec\u90fd\u53ef\u4ee5\u7528\u4e8e\u5b9e\u73b0\u9694\u79bb\u548c\u5c01\u88c5\u7684\u529f\u80fd\uff0c\u4f46\u662fNamespace\u662f\u4e00\u79cd\u66f4\u4e3a\u901a\u7528\u548c\u5e95\u5c42\u7684\u673a\u5236\uff0cPrimitives namespace\u662f\u4e00\u79cd\u66f4\u4e3a\u9ad8\u5c42\u7684\u62bd\u8c61\u6982\u5ff5\uff0c\u901a\u5e38\u7528\u4e8e\u6784\u5efa\u5bb9\u5668\u7b49\u5e94\u7528\u7ea7\u522b\u7684\u9694\u79bb\u73af\u5883\u3002 Namespace\u793a\u4f8b\uff1a \u5728Linux\u7cfb\u7edf\u4e2d\uff0c\u53ef\u4ee5\u4f7f\u7528PID Namespace\u6765\u9694\u79bb\u8fdb\u7a0bID\u53f7\u7a7a\u95f4\uff0c\u907f\u514d\u8fdb\u7a0b\u4e4b\u95f4\u7684PID\u51b2\u7a81\u3002\u4e0b\u9762\u662f\u4e00\u4e2a\u7b80\u5355\u7684\u793a\u4f8b\uff1a # \u521b\u5efa\u4e00\u4e2a\u65b0\u7684PID Namespace unshare -p /bin/bash # \u5728\u65b0\u7684PID Namespace\u4e2d\u8fd0\u884c\u4e00\u4e2a\u8fdb\u7a0b echo $$ # \u663e\u793a\u5f53\u524d\u8fdb\u7a0b\u7684PID ps aux # \u663e\u793a\u5f53\u524d\u8fdb\u7a0b\u53ca\u5176\u5b50\u8fdb\u7a0b \u5728\u4e0a\u9762\u7684\u793a\u4f8b\u4e2d\uff0c unshare -p \u547d\u4ee4\u521b\u5efa\u4e86\u4e00\u4e2a\u65b0\u7684PID Namespace\uff0c\u5e76\u5728\u5176\u4e2d\u542f\u52a8\u4e86\u4e00\u4e2a\u65b0\u7684bash\u8fdb\u7a0b\u3002\u7531\u4e8e\u8be5\u8fdb\u7a0b\u8fd0\u884c\u5728\u4e00\u4e2a\u72ec\u7acb\u7684PID Namespace\u4e2d\uff0c\u56e0\u6b64\u5b83\u7684PID\u53f7\u4e0e\u4e3b\u673a\u4e0a\u7684\u5176\u4ed6\u8fdb\u7a0b\u4e0d\u4f1a\u51b2\u7a81\u3002\u5728\u8fd9\u4e2a\u65b0\u7684bash\u8fdb\u7a0b\u4e2d\uff0c $$ \u547d\u4ee4\u663e\u793a\u7684\u662f\u8be5\u8fdb\u7a0b\u5728PID Namespace\u4e2d\u7684PID\u53f7\uff0c\u800c ps aux \u547d\u4ee4\u53ea\u4f1a\u663e\u793a\u5f53\u524dPID Namespace\u4e2d\u7684\u8fdb\u7a0b\uff0c\u4e0d\u4f1a\u663e\u793a\u4e3b\u673a\u4e0a\u7684\u5176\u4ed6\u8fdb\u7a0b\u3002 Primitives Namespace\u793a\u4f8b\uff1a \u5728Docker\u5bb9\u5668\u4e2d\uff0c\u53ef\u4ee5\u4f7f\u7528Filesystem Namespace\u6765\u9694\u79bb\u6587\u4ef6\u7cfb\u7edf\uff0c\u4f7f\u5f97\u4e0d\u540c\u7684\u5bb9\u5668\u4e4b\u95f4\u62e5\u6709\u72ec\u7acb\u7684\u6587\u4ef6\u7cfb\u7edf\u89c6\u56fe\u3002\u4e0b\u9762\u662f\u4e00\u4e2a\u7b80\u5355\u7684\u793a\u4f8b\uff1a # \u5728\u5bb9\u5668\u4e2d\u8fd0\u884c\u4e00\u4e2a\u547d\u4ee4 docker run --rm -it --name mycontainer ubuntu bash # \u5728\u5bb9\u5668\u4e2d\u521b\u5efa\u4e00\u4e2a\u6587\u4ef6\u5e76\u9000\u51fa touch myfile exit # \u5728\u4e3b\u673a\u4e0a\u67e5\u770b\u6587\u4ef6 ls myfile # myfile\u6587\u4ef6\u4e0d\u5b58\u5728 # \u518d\u6b21\u8fdb\u5165\u5bb9\u5668 docker start -i mycontainer # \u5728\u5bb9\u5668\u4e2d\u67e5\u770b\u6587\u4ef6 ls myfile # myfile\u6587\u4ef6\u5b58\u5728 \u5728\u4e0a\u9762\u7684\u793a\u4f8b\u4e2d\uff0c docker run \u547d\u4ee4\u542f\u52a8\u4e86\u4e00\u4e2a\u65b0\u7684Docker\u5bb9\u5668\uff0c\u5e76\u5728\u5176\u4e2d\u8fd0\u884c\u4e86\u4e00\u4e2abash\u8fdb\u7a0b\u3002\u7531\u4e8e\u8be5\u5bb9\u5668\u4f7f\u7528\u4e86Filesystem Namespace\uff0c\u56e0\u6b64\u5bb9\u5668\u5185\u7684\u6587\u4ef6\u7cfb\u7edf\u89c6\u56fe\u4e0e\u4e3b\u673a\u4e0a\u7684\u6587\u4ef6\u7cfb\u7edf\u89c6\u56fe\u662f\u9694\u79bb\u7684\u3002\u5728\u5bb9\u5668\u5185\u521b\u5efa\u7684\u6587\u4ef6 myfile \u53ea\u5b58\u5728\u4e8e\u5bb9\u5668\u5185\u90e8\uff0c\u5728\u4e3b\u673a\u4e0a\u662f\u770b\u4e0d\u5230\u7684\u3002\u5f53\u518d\u6b21\u8fdb\u5165\u5bb9\u5668\u65f6\uff0c myfile \u6587\u4ef6\u5c31\u53ef\u4ee5\u88ab\u770b\u5230\u4e86\u3002 \u603b\u7ed3\uff1a Namespace\u662fLinux\u5185\u6838\u63d0\u4f9b\u7684\u673a\u5236\uff0c\u800cPrimitives Namespace\u5219\u662f\u4e00\u79cd\u57fa\u4e8eNamespace\u7684\u9ad8\u5c42\u62bd\u8c61\uff0c\u7528\u4e8e\u5b9e\u73b0\u5e94\u7528\u7ea7\u522b\u7684\u9694\u79bb\u548c\u5c01\u88c5\u3002Namespace\u53ef\u4ee5\u7528\u4e8e\u9694\u79bb\u591a\u79cd\u8d44\u6e90\uff0c\u800cPrimitives Namespace\u901a\u5e38\u7528\u4e8e\u9694\u79bb\u6587\u4ef6\u7cfb\u7edf\u3001\u7f51\u7edc\u3001\u8fdb\u7a0b\u7b49\u64cd\u4f5c\u7684\u539f\u8bed\u3002","title":"\u547d\u540d\u7a7a\u95f4"},{"location":"k8s/cka_cn/foundamentals/docker/#_4","text":"cgroup\uff0c\u5168\u79f0\u4e3aControl Group\uff0c\u5373\u63a7\u5236\u7ec4\uff0c\u662fLinux\u5185\u6838\u63d0\u4f9b\u7684\u4e00\u79cd\u673a\u5236\uff0c\u7528\u4e8e\u9650\u5236\u3001\u8bb0\u5f55\u3001\u9694\u79bb\u548c\u4f18\u5148\u7ea7\u63a7\u5236\u4e00\u7ec4\u8fdb\u7a0b\u7684\u8d44\u6e90\u4f7f\u7528\u3002\u5b83\u53ef\u4ee5\u9650\u5236\u8fdb\u7a0b\u7ec4\u7684CPU\u3001\u5185\u5b58\u3001\u78c1\u76d8\u3001\u7f51\u7edc\u7b49\u8d44\u6e90\u7684\u4f7f\u7528\uff0c\u540c\u65f6\u4e5f\u53ef\u4ee5\u8bb0\u5f55\u8fdb\u7a0b\u7ec4\u7684\u8d44\u6e90\u4f7f\u7528\u60c5\u51b5\u548c\u884c\u4e3a\u3002 cgroup\u901a\u8fc7\u5c06\u4e00\u7ec4\u8fdb\u7a0b\u7ec4\u7ec7\u6210\u4e00\u4e2a\u5c42\u6b21\u7ed3\u6784\uff0c\u5c06\u8d44\u6e90\u5206\u914d\u7ed9\u4e0d\u540c\u7684cgroup\u6765\u5b9e\u73b0\u8d44\u6e90\u9650\u5236\u548c\u4f18\u5148\u7ea7\u63a7\u5236\u3002\u6bcf\u4e2acgroup\u53ef\u4ee5\u8bbe\u7f6e\u8d44\u6e90\u9650\u5236\u548c\u63a7\u5236\u7b56\u7565\uff0c\u4f8b\u5982\u53ef\u4ee5\u9650\u5236\u4e00\u4e2a\u8fdb\u7a0b\u7ec4\u6700\u591a\u4f7f\u752850%\u7684CPU\u65f6\u95f4\uff0c\u6216\u8005\u9650\u5236\u4e00\u4e2a\u8fdb\u7a0b\u7ec4\u6700\u591a\u4f7f\u7528100MB\u7684\u5185\u5b58\u7b49\u3002 cgroup\u6700\u521d\u7531Google\u516c\u53f8\u5f00\u53d1\uff0c\u540e\u6765\u88abLinux\u5185\u6838\u793e\u533a\u91c7\u7eb3\u5e76\u52a0\u5165\u5230\u5185\u6838\u4e2d\uff0c\u6210\u4e3aLinux\u7cfb\u7edf\u7684\u4e00\u90e8\u5206\u3002\u5b83\u5728\u5bb9\u5668\u6280\u672f\u3001\u865a\u62df\u5316\u3001\u4e91\u8ba1\u7b97\u7b49\u9886\u57df\u90fd\u6709\u5e7f\u6cdb\u7684\u5e94\u7528\u3002 \u4e0b\u9762\u662fcgroup \u7684\u4e00\u4e9b\u5e38\u89c1\u7528\u9014\uff1a CPU \u9650\u5236\uff1a\u4f7f\u7528 cgroup \u53ef\u4ee5\u9650\u5236\u8fdb\u7a0b\u7684 CPU \u4f7f\u7528\u7387\uff0c\u907f\u514d\u67d0\u4e2a\u8fdb\u7a0b\u5360\u7528\u8fc7\u591a\u7684 CPU \u8d44\u6e90\u5bfc\u81f4\u7cfb\u7edf\u8d1f\u8f7d\u8fc7\u9ad8\uff0c\u4ece\u800c\u5f71\u54cd\u7cfb\u7edf\u7a33\u5b9a\u6027\u548c\u5176\u4ed6\u8fdb\u7a0b\u7684\u6b63\u5e38\u8fd0\u884c\u3002 \u5185\u5b58\u9650\u5236\uff1a\u4f7f\u7528 cgroup \u53ef\u4ee5\u9650\u5236\u8fdb\u7a0b\u7684\u5185\u5b58\u4f7f\u7528\u91cf\uff0c\u907f\u514d\u67d0\u4e2a\u8fdb\u7a0b\u5360\u7528\u8fc7\u591a\u7684\u5185\u5b58\u8d44\u6e90\u5bfc\u81f4\u7cfb\u7edf\u5185\u5b58\u4e0d\u8db3\uff0c\u4ece\u800c\u5f71\u54cd\u7cfb\u7edf\u6027\u80fd\u548c\u5176\u4ed6\u8fdb\u7a0b\u7684\u6b63\u5e38\u8fd0\u884c\u3002 IO \u9650\u5236\uff1a\u4f7f\u7528 cgroup \u53ef\u4ee5\u9650\u5236\u8fdb\u7a0b\u7684 IO \u5e26\u5bbd\uff0c\u907f\u514d\u67d0\u4e2a\u8fdb\u7a0b\u5360\u7528\u8fc7\u591a\u7684 IO \u8d44\u6e90\u5bfc\u81f4\u5176\u4ed6\u8fdb\u7a0b\u7684 IO \u64cd\u4f5c\u53d7\u5230\u5f71\u54cd\uff0c\u4ece\u800c\u5f71\u54cd\u7cfb\u7edf\u6027\u80fd\u548c\u54cd\u5e94\u901f\u5ea6\u3002 \u7f51\u7edc\u9650\u5236\uff1a\u4f7f\u7528 cgroup \u53ef\u4ee5\u9650\u5236\u8fdb\u7a0b\u7684\u7f51\u7edc\u5e26\u5bbd\uff0c\u907f\u514d\u67d0\u4e2a\u8fdb\u7a0b\u5360\u7528\u8fc7\u591a\u7684\u7f51\u7edc\u8d44\u6e90\u5bfc\u81f4\u7f51\u7edc\u62e5\u585e\uff0c\u4ece\u800c\u5f71\u54cd\u7cfb\u7edf\u6027\u80fd\u548c\u5176\u4ed6\u8fdb\u7a0b\u7684\u6b63\u5e38\u8fd0\u884c\u3002 \u8fdb\u7a0b\u63a7\u5236\uff1a\u4f7f\u7528 cgroup \u53ef\u4ee5\u9650\u5236\u8fdb\u7a0b\u7684\u542f\u52a8\u3001\u505c\u6b62\u548c\u8c03\u5ea6\u7b49\u884c\u4e3a\uff0c\u4ece\u800c\u5b9e\u73b0\u5bf9\u7cfb\u7edf\u8fdb\u7a0b\u7684\u63a7\u5236\u548c\u7ba1\u7406\u3002 \u8d44\u6e90\u7edf\u8ba1\uff1a\u4f7f\u7528 cgroup \u53ef\u4ee5\u5b9e\u65f6\u7edf\u8ba1\u7cfb\u7edf\u4e2d\u5404\u4e2a\u8fdb\u7a0b\u7684\u8d44\u6e90\u4f7f\u7528\u60c5\u51b5\uff0c\u4ece\u800c\u5e2e\u52a9\u7ba1\u7406\u5458\u4e86\u89e3\u7cfb\u7edf\u8d1f\u8f7d\u72b6\u51b5\u548c\u5404\u4e2a\u8fdb\u7a0b\u7684\u6027\u80fd\u74f6\u9888\uff0c\u4ece\u800c\u91c7\u53d6\u76f8\u5e94\u7684\u63aa\u65bd\u4f18\u5316\u7cfb\u7edf\u6027\u80fd\u3002 \u4e0b\u9762\u662fopenSUSE\u4e2d\u7684\u793a\u4f8b\uff1a \u5b89\u88c5\u9700\u8981\u7684\u8f6f\u4ef6\u5305\uff1a sudo zypper install libcgroup-tools \u9650\u5236CPU\u4f7f\u7528\u4e0a\u9650\uff1a # \u521b\u5efa\u65b0\u7684cgroup 'mygroup' sudo mkdir /sys/fs/cgroup/cpu/mygroup # \u7cfb\u7edf\u4f1a\u521b\u5efa\u9ed8\u8ba4\u7684\u4e00\u4e9b\u6587\u4ef6\uff0c\u542b\u521d\u59cb\u503c\uff0c\u6bd4\u5982CPU\u4f7f\u7528\u65f6\u95f4\u7684\u9650\u989d\u7684\u9ed8\u8ba4\u503c\u662f-1 cat /sys/fs/cgroup/cpu/mygroup/cpu.cfs_quota_us # \u8bbe\u5b9aCPU\u4f7f\u7528\u65f6\u95f4\u4e0a\u9650 sudo sh -c \"echo 50000 > /sys/fs/cgroup/cpu/mygroup/cpu.cfs_quota_us\" # \u542f\u52a8\u4e00\u4e2a\u65b0\u7684\u8fdb\u7a0b\uff0c\u5e76\u4e14\u5173\u8054\u5230 sudo cgcreate -g cpu:mygroup sudo cgexec -g cpu:mygroup /bin/bash \u5728\u4e0a\u9762\u7684\u4f8b\u5b50\u4e2d\uff0c cpu.cfs_quota_us \u6587\u4ef6\u8bbe\u7f6e\u4e86 cgroup \u4e2d\u7684\u8fdb\u7a0b\u53ef\u4ee5\u4f7f\u7528\u7684\u6700\u5927 CPU \u65f6\u95f4\u3002\u8be5\u503c\u4ee5\u5fae\u79d2\u4e3a\u5355\u4f4d\uff0c\u56e0\u6b64\u5c06\u5176\u8bbe\u7f6e\u4e3a 50000 \u8868\u793a\u8fdb\u7a0b\u6700\u591a\u53ef\u4ee5\u4f7f\u7528\u5355\u4e2a CPU \u6838\u5fc3\u7684 50%\u3002 cgcreate \u548c cgexec \u547d\u4ee4\u521b\u5efa\u5e76\u5c06\u8fdb\u7a0b /bin/bash \u79fb\u52a8\u5230 mygroup cgroup \u4e2d\u3002 \u9650\u5236\u5185\u5b58\u4f7f\u7528\u4e0a\u9650\uff1a # \u521b\u5efa\u65b0\u7684cgroup 'mygroup' sudo mkdir /sys/fs/cgroup/memory/mygroup # \u7cfb\u7edf\u4f1a\u521b\u5efa\u9ed8\u8ba4\u7684\u4e00\u4e9b\u6587\u4ef6\uff0c\u542b\u521d\u59cb\u503c\uff0c\u6bd4\u5982\u5185\u5b58\u4f7f\u7528\u4e0a\u9650\u7684\u9ed8\u8ba4\u503c\u662f9223372036854771712 cat /sys/fs/cgroup/memory/mygroup/memory.limit_in_bytes # \u8bbe\u7f6e\u5185\u5b58\u4f7f\u7528\u4e0a\u9650512MB sudo sh -c \"echo 536870912 > /sys/fs/cgroup/memory/mygroup/memory.limit_in_bytes\" # \u542f\u52a8\u4e00\u4e2a\u65b0\u7684\u8fdb\u7a0b\uff0c\u5e76\u4e14\u5173\u8054\u5230'mygroup' sudo cgcreate -g memory:mygroup sudo cgexec -g memory:mygroup /bin/bash \u5728\u4e0a\u9762\u4f8b\u5b50\u4e2d\uff0c memory.limit_in_bytes \u6587\u4ef6\u8bbe\u7f6e\u4e86 cgroup \u4e2d\u8fdb\u7a0b\u53ef\u4ee5\u4f7f\u7528\u7684\u6700\u5927\u5185\u5b58\u91cf\u3002\u8be5\u503c\u4ee5\u5b57\u8282\u4e3a\u5355\u4f4d\uff0c\u56e0\u6b64\u5c06\u5176\u8bbe\u7f6e\u4e3a 536870912 \u8868\u793a\u8fdb\u7a0b\u6700\u591a\u53ef\u4ee5\u4f7f\u7528 512MB \u7684\u5185\u5b58\u3002 \u8bbe\u7f6e\u4f18\u5148\u8fdb\u7a0b\u7684 I/O \u4f7f\u7528\u7387\uff1a # \u521b\u5efa\u65b0cgroup 'mygroup' sudo mkdir /sys/fs/cgroup/blkio/mygroup # \u8bbe\u7f6e\u8fdb\u7a0b\u6700\u5927\u8bfb\u548c\u5199\u7684\u901f\u738710MB/s sudo sh -c \"echo '8:0 10485760' > /sys/fs/cgroup/blkio/mygroup/blkio.throttle.read_bps_device\" sudo sh -c \"echo '8:0 10485760' > /sys/fs/cgroup/blkio/mygroup/blkio.throttle.write_bps_device\" # \u542f\u52a8\u4e00\u4e2a\u65b0\u7684\u8fdb\u7a0b\uff0c\u5e76\u4e14\u5173\u8054\u5230'mygroup' sudo cgcreate -g blkio:mygroup sudo cgexec -g blkio:mygroup /bin/bash \u5728\u4e0a\u9762\u4f8b\u5b50\u4e2d\uff0c blkio.throttle.read_bps_device \u548c blkio.throttle.write_bps_device \u6587\u4ef6\u8bbe\u7f6e\u4e86cgroup\u4e2d\u8fdb\u7a0b\u53ef\u4ee5\u4f7f\u7528\u7684\u6700\u5927\u8bfb\u53d6\u548c\u5199\u5165\u5e26\u5bbd\u3002\u8be5\u503c\u4ee5\u6bcf\u79d2\u5b57\u8282\u6570\u4e3a\u5355\u4f4d\uff0c\u56e0\u6b64\u5c06\u5176\u8bbe\u7f6e\u4e3a10485760\u610f\u5473\u7740\u8fdb\u7a0b\u5728\u4e3b\u8bbe\u5907\u53f7:\u6b21\u8bbe\u5907\u53f7\u4e3a8:0\u7684\u8bbe\u5907\uff08\u901a\u5e38\u662f\u7b2c\u4e00\u4e2a\u786c\u76d8\uff09\u4e0a\u8bfb\u53d6\u6216\u5199\u5165\u7684\u5e26\u5bbd\u6700\u591a\u4e3a10MB/s\u3002 \u5c06 8:0 10485760 \u8fd9\u4e2a\u5b57\u7b26\u4e32\u5199\u5165\u5230 /sys/fs/cgroup/blkio/mygroup/blkio.throttle.read_bps_device \u6587\u4ef6\u4e2d\u7684\u4f5c\u7528\u662f\u9650\u5236 mygroup \u63a7\u5236\u7ec4\u4e2d\u5173\u8054\u7684\u5757\u8bbe\u5907\uff08block device\uff09\u7684\u8bfb\u53d6\u901f\u7387\u3002 \u5728 Linux \u4e2d\uff0c blkio \u63a7\u5236\u7ec4\u5b50\u7cfb\u7edf\u53ef\u4ee5\u7528\u6765\u5bf9\u8fdb\u7a0b\u6216\u7ebf\u7a0b\u7684\u5757\u8bbe\u5907\u8bbf\u95ee\u8fdb\u884c\u9650\u5236\uff0c\u5982\u9650\u5236\u8bfb\u5199\u901f\u7387\u3001I/O \u4f18\u5148\u7ea7\u7b49\u3002\u800c blkio.throttle.read_bps_device \u8fd9\u4e2a\u6587\u4ef6\u5219\u7528\u4e8e\u8bbe\u7f6e\u67d0\u4e2a\u5757\u8bbe\u5907\u7684\u8bfb\u53d6\u901f\u7387\u9650\u5236\u3002 \u5177\u4f53\u6765\u8bf4\uff0c 8:0 \u8868\u793a\u8bbe\u5907\u7684\u4e3b\u6b21\u7f16\u53f7\uff08major:minor\uff09\uff0c\u8fd9\u91cc\u662f\u6307\u78c1\u76d8 /dev/sda \u3002 10485760 \u5219\u662f\u8bfb\u53d6\u901f\u7387\u7684\u9650\u5236\u503c\uff0c\u5355\u4f4d\u662f\u5b57\u8282/\u79d2\u3002\u8fd9\u4e2a\u503c\u8868\u793a /dev/sda \u6700\u5927\u8bfb\u53d6\u901f\u7387\u4e3a 10MB/s\uff0c\u8d85\u8fc7\u8fd9\u4e2a\u901f\u7387\u7684\u8bfb\u53d6\u8bf7\u6c42\u4f1a\u88ab\u5ef6\u8fdf\u6267\u884c\uff0c\u4ece\u800c\u9650\u5236\u4e86\u78c1\u76d8\u7684\u8bfb\u53d6\u5e26\u5bbd\u3002 \u56e0\u6b64\uff0c\u4ee5\u4e0a\u547d\u4ee4\u7684\u542b\u4e49\u662f\u5c06 mygroup \u63a7\u5236\u7ec4\u4e2d\u5173\u8054\u7684 /dev/sda \u78c1\u76d8\u7684\u8bfb\u53d6\u901f\u7387\u9650\u5236\u4e3a 10MB/s\uff0c\u4ece\u800c\u5b9e\u73b0\u5bf9\u8be5\u63a7\u5236\u7ec4\u4e2d\u8fdb\u7a0b\u6216\u7ebf\u7a0b\u5bf9\u78c1\u76d8\u8bfb\u53d6\u7684\u9650\u5236\u3002 \u540c\u7406\uff0c\u5c06 8:0 10485760 \u8fd9\u4e2a\u5b57\u7b26\u4e32\u5199\u5165\u5230 /sys/fs/cgroup/blkio/mygroup/blkio.throttle.write_bps_device \u6587\u4ef6\u4e2d\uff0c\u4ee5\u9650\u5236 mygroup \u63a7\u5236\u7ec4\u4e2d\u5173\u8054\u7684\u5757\u8bbe\u5907\uff08block device\uff09\u7684\u5199\u5165\u901f\u7387\u3002 \u9650\u5236\u4e00\u7ec4\u8fdb\u7a0b\u7684\u7f51\u7edc\u5e26\u5bbd\uff1a # \u521b\u5efa\u65b0\u7684cgroup 'mygroup' sudo mkdir /sys/fs/cgroup/net_cls/mygroup # \u5c06\u6b64\u7ec4\u4e2d\u7684\u8fdb\u7a0b\u7684\u7f51\u7edc\u7c7bID\u8bbe\u7f6e\u4e3a\u201cmyclass\u201d sudo sh -c \"echo 0x10001 > /sys/fs/cgroup/net_cls/mygroup/net_cls.classid\" \u4e0a\u9762\u7684\u4f8b\u5b50\u662f\u5c06 0x10001 \u8fd9\u4e2a\u5341\u516d\u8fdb\u5236\u6570\u503c\u5199\u5165\u5230 /sys/fs/cgroup/net_cls/mygroup/net_cls.classid \u6587\u4ef6\u4e2d\uff0c\u4ee5\u6307\u5b9a mygroup \u63a7\u5236\u7ec4\u7684\u7f51\u7edc\u7c7b\u522b\u6807\u8bc6\u7b26\uff08classid\uff09\u3002 \u7f51\u7edc\u7c7b\u522b\u6807\u8bc6\u7b26\u662f Linux \u5185\u6838\u4e2d\u7528\u6765\u5b9e\u73b0\u6d41\u91cf\u63a7\u5236\u548c\u6d41\u91cf\u5206\u7c7b\u7684\u4e00\u4e2a\u673a\u5236\uff0c\u5b83\u53ef\u4ee5\u5c06\u6570\u636e\u5305\u6309\u7167\u4e0d\u540c\u7684\u7c7b\u522b\uff08class\uff09\u8fdb\u884c\u6807\u8bb0\u548c\u533a\u5206\uff0c\u7136\u540e\u5728\u7f51\u7edc\u8bbe\u5907\u4e0a\u9488\u5bf9\u4e0d\u540c\u7684\u7c7b\u522b\u8fdb\u884c\u4e0d\u540c\u7684\u5904\u7406\uff0c\u5982\u9650\u901f\u3001\u4f18\u5148\u7ea7\u8c03\u6574\u7b49\u3002\u63a7\u5236\u7ec4\u4e2d\u7684 net_cls \u5b50\u7cfb\u7edf\u53ef\u4ee5\u7528\u6765\u5c06\u8fdb\u7a0b\u6216\u7ebf\u7a0b\u4e0e\u7f51\u7edc\u7c7b\u522b\u6807\u8bc6\u7b26\u5173\u8054\u8d77\u6765\uff0c\u4ece\u800c\u5b9e\u73b0\u5bf9\u5b83\u4eec\u7684\u7f51\u7edc\u6d41\u91cf\u8fdb\u884c\u63a7\u5236\u548c\u5206\u7c7b\u3002 \u56e0\u6b64\uff0c\u4ee5\u4e0a\u547d\u4ee4\u662f\u5c06 mygroup \u63a7\u5236\u7ec4\u7684\u7f51\u7edc\u7c7b\u522b\u6807\u8bc6\u7b26\u8bbe\u7f6e\u4e3a 0x10001 \uff0c\u8fd9\u6837\u4e0e\u8be5\u63a7\u5236\u7ec4\u76f8\u5173\u8054\u7684\u8fdb\u7a0b\u6216\u7ebf\u7a0b\u5c31\u4f1a\u88ab\u6807\u8bb0\u4e3a\u8be5\u7c7b\u522b\uff0c\u7136\u540e\u53ef\u4ee5\u901a\u8fc7\u5176\u4ed6\u5de5\u5177\uff08\u5982 tc \u547d\u4ee4\uff09\u5bf9\u5176\u8fdb\u884c\u7f51\u7edc\u6d41\u91cf\u63a7\u5236\u548c\u5206\u7c7b\u3002 \u5982\u679c\u9047\u5230\u5bf9\u5e94\u9650\u5236\u6587\u4ef6\u4e0d\u5b58\u5728\uff0c\u4e00\u79cd\u53ef\u80fd\u662f\u9700\u8981\u68c0\u67e5cgroup\u5b50\u7cfb\u6709\u6ca1\u6709\u6b63\u786e\u7edf\u8f7d\u6216\u8005\u6ca1\u6709\u542f\u7528\u5185\u5b58\u5b50\u7cfb\u7edf\u3002 mount | grep cgroup \u5982\u679c cgroups \u6587\u4ef6\u7cfb\u7edf\u5df2\u7ecf\u6302\u8f7d\uff0c\u5e94\u8be5\u4f1a\u770b\u5230\u8f93\u51fa\u7c7b\u4f3c\u4e8e\u4ee5\u4e0b\u5185\u5bb9\uff08\uff09\u4ee5memory\u4e3a\u4f8b\uff09\uff1a cgroup on /sys/fs/cgroup/memory type cgroup (rw,nosuid,nodev,noexec,relatime,memory) \u5982\u679c\u6ca1\u6709\u770b\u5230 memory \u5b57\u6bb5\uff0c\u5219\u8868\u793a\u5185\u5b58\u5b50\u7cfb\u7edf\u6ca1\u6709\u542f\u7528\u3002\u53ef\u4ee5\u7f16\u8f91 /etc/default/grub \u6587\u4ef6\uff0c\u6dfb\u52a0\u6216\u4fee\u6539\u4ee5\u4e0b\u884c\uff1a GRUB_CMDLINE_LINUX_DEFAULT=\"cgroup_enable=memory\" \u7136\u540e\u66f4\u65b0 GRUB \u914d\u7f6e\u5e76\u91cd\u542f\u7cfb\u7edf\uff1a sudo update-grub sudo reboot \u91cd\u542f\u540e\u518d\u6b21\u68c0\u67e5 /sys/fs/cgroup/memory/mygroup/memory.limit_in_bytes \u6587\u4ef6\u662f\u5426\u5b58\u5728\u3002\u5982\u679c\u8fd8\u662f\u4e0d\u5b58\u5728\uff0c\u53ef\u80fd\u9700\u8981\u624b\u52a8\u521b\u5efa\u5b83\u4ee5\u53ca\u5176\u4ed6\u76f8\u5173\u7684 cgroups \u6587\u4ef6\u3002\u4f8b\u5982\uff0c\u8fd0\u884c\u4ee5\u4e0b\u547d\u4ee4\uff1a sudo mkdir /sys/fs/cgroup/memory/mygroup sudo touch /sys/fs/cgroup/memory/mygroup/memory.limit_in_bytes \u7136\u540e\u5c31\u53ef\u4ee5\u50cf\u4e4b\u524d\u7684\u4f8b\u5b50\u4e00\u6837\u8bbe\u7f6e\u5185\u5b58\u9650\u5236\u4e86","title":"\u63a7\u5236\u7ec4"},{"location":"k8s/cka_cn/foundamentals/docker/#apparmorselinux","text":"\u5b89\u5168\u914d\u7f6e\u6587\u4ef6\uff0c\u7528\u4e8e\u63a7\u5236\u5bf9\u8d44\u6e90\u7684\u8bbf\u95ee AppArmor \u548c SELinux \u90fd\u662f\u5e38\u89c1\u7684\u5f3a\u5236\u8bbf\u95ee\u63a7\u5236\uff08MAC\uff09\u673a\u5236\uff0c\u53ef\u4ee5\u5bf9\u8fdb\u7a0b\u6216\u5e94\u7528\u7a0b\u5e8f\u7684\u8bbf\u95ee\u6743\u9650\u8fdb\u884c\u7cbe\u7ec6\u63a7\u5236\u3002\u4e0b\u9762\u5206\u522b\u4e3e\u4f8b\u8bf4\u660e\u8fd9\u4e24\u79cd\u673a\u5236\u7684\u914d\u7f6e\u6587\u4ef6\u4f7f\u7528\u3002 AppArmor AppArmor \u7684\u4e3b\u914d\u7f6e\u6587\u4ef6\u662f /etc/apparmor/profiles.d/ \u76ee\u5f55\u4e0b\u7684\u5404\u4e2a\u6587\u4ef6\uff0c\u6bcf\u4e2a\u6587\u4ef6\u5bf9\u5e94\u4e00\u4e2a\u5e94\u7528\u7a0b\u5e8f\u6216\u8fdb\u7a0b\u7684\u914d\u7f6e\u3002\u4ee5 sshd \u670d\u52a1\u4e3a\u4f8b\uff0c\u8be5\u670d\u52a1\u7684\u914d\u7f6e\u6587\u4ef6\u662f /etc/apparmor.d/usr.sbin.sshd \u3002 \u8be5\u914d\u7f6e\u6587\u4ef6\u7684\u5185\u5bb9\u7c7b\u4f3c\u4e8e\u4e0b\u9762\u8fd9\u6837\uff1a # Last Modified: Sun Mar 14 18 :53:00 2023 # include /usr/sbin/sshd { # include # include # allow read access to user home directories /home/** r, # allow sshd to execute /usr/bin/which to determine full path of shell /usr/bin/which ix, # allow sshd to read its own configuration file /etc/ssh/sshd_config r, # allow sshd to read the SSH host keys /etc/ssh/ssh_host_* r, # allow sshd to use pam for authentication /usr/share/pam/** r, # allow sshd to use nsswitch for name resolution /etc/nsswitch.conf r, /etc/hosts r, /etc/hostname r, /etc/resolv.conf r, # allow sshd to write to its own log file /var/log/auth.log w, # allow sshd to create and manage pid files /var/run/sshd.pid w, /var/run/sshd.dir/ w, /var/run/sshd.dir/* rw, # allow sshd to access systemd-logind /run/systemd/* r, /run/systemd/session/*.scope r, /run/systemd/sessions/*.scope r, # deny everything else deny /, } \u8be5\u914d\u7f6e\u6587\u4ef6\u5b9a\u4e49\u4e86 /usr/sbin/sshd \u8fdb\u7a0b\u7684\u6743\u9650\u9650\u5236\u89c4\u5219\uff0c\u5305\u62ec\u5141\u8bb8\u8bbf\u95ee\u7684\u6587\u4ef6\u3001\u7981\u6b62\u8bbf\u95ee\u7684\u6587\u4ef6\u7b49\u3002\u5176\u4e2d #include \u8868\u793a\u5305\u542b\u4e86\u4e00\u7ec4\u901a\u7528\u7684\u6743\u9650\u89c4\u5219\uff0c\u53ef\u4ee5\u5728\u4e0d\u540c\u7684\u5e94\u7528\u7a0b\u5e8f\u914d\u7f6e\u4e2d\u91cd\u590d\u4f7f\u7528\u3002 2.SELinux SELinux \u7684\u4e3b\u914d\u7f6e\u6587\u4ef6\u662f /etc/selinux/config \uff0c\u8be5\u6587\u4ef6\u5b9a\u4e49\u4e86\u7cfb\u7edf\u7684 SELinux \u7b56\u7565\u548c\u6a21\u5f0f\u3002\u9ed8\u8ba4\u60c5\u51b5\u4e0b\uff0copenSUSE \u4f7f\u7528\u7684\u662f targeted \u6a21\u5f0f\u3002 \u6bcf\u4e2a\u8fdb\u7a0b\u6216\u5e94\u7528\u7a0b\u5e8f\u8fd8\u9700\u8981\u5bf9\u5e94\u4e00\u4e2a SELinux \u914d\u7f6e\u6587\u4ef6\uff0c\u4ee5\u5b9a\u4e49\u5b83\u4eec\u7684\u8bbf\u95ee\u6743\u9650\u3002\u4ee5 httpd \u670d\u52a1\u4e3a\u4f8b\uff0c\u8be5\u670d\u52a1\u7684 SELinux \u914d\u7f6e\u6587\u4ef6\u662f /etc/selinux/targeted/contexts/httpd.te \u3002 \u8be5\u914d\u7f6e\u6587\u4ef6\u7684\u5185\u5bb9\u7c7b\u4f3c\u4e8e\u4e0b\u9762\u8fd9\u6837\uff1a # HTTPD server type httpd_t ; type httpd_sys_script_t ; init_daemon_domain ( httpd_t, httpd_sys_script_t ) \u8be5\u914d\u7f6e\u6587\u4ef6\u5b9a\u4e49\u4e86 httpd \u670d\u52a1\u7684 SELinux \u7c7b\u578b\u4e3a httpd_t \uff0c\u5e76\u4f7f\u7528\u4e86 httpd_sys_script_t \u4f5c\u4e3a\u5176\u521d\u59cb\u5316\u57df\u3002\u5176\u4e2d type \u8868\u793a SELinux \u7c7b\u578b\uff0c init_daemon_domain \u5219\u662f\u4e00\u4e2a SELinux \u5b8f\uff0c\u7528\u4e8e\u5b9a\u4e49\u670d\u52a1\u7684\u521d\u59cb\u57df\u3002 \u9700\u8981\u6ce8\u610f\u7684\u662f\uff0c\u5728 SELinux \u4e2d\uff0c\u8bbf\u95ee\u6743\u9650\u89c4\u5219\u4e0d\u662f\u76f4\u63a5\u5728\u914d\u7f6e\u6587\u4ef6\u4e2d\u5b9a\u4e49\u7684\uff0c\u800c\u662f\u901a\u8fc7\u8bbf\u95ee\u63a7\u5236\u7b56\u7565\u548c\u89c4\u5219\u8fdb\u884c\u63a7\u5236\u3002\u8fd9\u4e9b\u7b56\u7565\u548c\u89c4\u5219\u53ef\u4ee5\u4f7f\u7528 SELinux \u5de5\u5177\u96c6\uff08\u5982 semanage \u3001 setsebool \u3001 restorecon \u7b49\uff09\u8fdb\u884c\u7ba1\u7406\u548c\u8bbe\u7f6e\u3002 \u6bd4\u5982\uff0c\u5728openSUSE\u4e2d\u53ef\u4ee5\u770b\u5230 /etc/selinux/semanage.conf \u6587\u4ef6\u548c\u5176\u4e2d\u7684\u914d\u7f6e\u3002","title":"Apparmor\u548cSELinux\u914d\u7f6e\u6587\u4ef6"},{"location":"k8s/cka_cn/foundamentals/docker/#_5","text":"\u5185\u6838\u80fd\u529b\uff08Kernel capabilities\uff09 \u6ca1\u6709\u80fd\u529b\uff1aroot\u53ef\u4ee5\u6267\u884c\u6240\u6709\u64cd\u4f5c\uff0c\u5176\u4ed6\u7528\u6237\u53ef\u80fd\u4ec0\u4e48\u4e5f\u505a\u4e0d\u4e86 38\u4e2a\u7ec6\u7c92\u5ea6\u7684\u529f\u80fd\u6765\u63a7\u5236\u6743\u9650 Kernel capabilities \u662f Linux \u5185\u6838\u63d0\u4f9b\u7684\u4e00\u79cd\u673a\u5236\uff0c\u7528\u4e8e\u63a7\u5236\u8fdb\u7a0b\u5bf9\u7cfb\u7edf\u8d44\u6e90\u7684\u8bbf\u95ee\u6743\u9650\u3002\u4e0e\u4f20\u7edf\u7684 Unix \u6743\u9650\u673a\u5236\u4e0d\u540c\uff0cKernel capabilities \u53ef\u4ee5\u4f7f\u7ba1\u7406\u5458\u5728\u7cbe\u7ec6\u63a7\u5236\u7cfb\u7edf\u8d44\u6e90\u8bbf\u95ee\u7684\u540c\u65f6\uff0c\u907f\u514d\u5c06\u8fc7\u591a\u6743\u9650\u6388\u4e88\u8fdb\u7a0b\uff0c\u63d0\u9ad8\u4e86\u7cfb\u7edf\u7684\u5b89\u5168\u6027\u3002 \u5728\u4f20\u7edf Unix \u6743\u9650\u673a\u5236\u4e2d\uff0c\u6bcf\u4e2a\u8fdb\u7a0b\u90fd\u6709\u4e00\u4e2a\u6709\u6548\u7528\u6237 ID \u548c\u4e00\u4e2a\u6709\u6548\u7ec4 ID\uff0c\u8fd9\u4e9b ID \u51b3\u5b9a\u4e86\u8be5\u8fdb\u7a0b\u5bf9\u6587\u4ef6\u3001\u8bbe\u5907\u3001\u7f51\u7edc\u7b49\u8d44\u6e90\u7684\u8bbf\u95ee\u6743\u9650\u3002\u4f46\u662f\uff0c\u8fd9\u79cd\u6743\u9650\u673a\u5236\u4e0d\u591f\u7075\u6d3b\uff0c\u5982\u679c\u8981\u6388\u4e88\u8fdb\u7a0b\u67d0\u4e9b\u7279\u5b9a\u7684\u6743\u9650\uff0c\u53ef\u80fd\u9700\u8981\u5c06\u6240\u6709\u7684\u6743\u9650\u90fd\u6388\u4e88\u7ed9\u5b83\uff0c\u4ece\u800c\u964d\u4f4e\u4e86\u7cfb\u7edf\u7684\u5b89\u5168\u6027\u3002 Kernel capabilities \u63d0\u4f9b\u4e86\u4e00\u79cd\u66f4\u7ec6\u7c92\u5ea6\u7684\u6743\u9650\u63a7\u5236\u65b9\u5f0f\u3002\u6bcf\u4e2a\u8fdb\u7a0b\u90fd\u6709\u4e00\u7ec4 capabilities\uff0c\u6bcf\u4e2a capability \u8868\u793a\u4e00\u79cd\u7279\u5b9a\u7684\u6743\u9650\u3002\u8fdb\u7a0b\u53ef\u4ee5\u8bf7\u6c42\u548c\u91ca\u653e\u67d0\u4e9b capability\uff0c\u8fd9\u6837\u5c31\u53ef\u4ee5\u5c06\u6743\u9650\u6388\u4e88\u8fdb\u7a0b\uff0c\u800c\u4e0d\u5fc5\u6388\u4e88\u6240\u6709\u6743\u9650\u3002 \u4f8b\u5982\uff0c\u53ef\u4ee5\u5c06 CAP_NET_BIND_SERVICE capability \u6388\u4e88\u67d0\u4e2a\u8fdb\u7a0b\uff0c\u8fd9\u6837\u8be5\u8fdb\u7a0b\u5c31\u53ef\u4ee5\u7ed1\u5b9a 1-1023 \u7684\u7aef\u53e3\uff0c\u800c\u4e0d\u5fc5\u5177\u6709 root \u6743\u9650\u3002\u7c7b\u4f3c\u5730\uff0c\u53ef\u4ee5\u5c06 CAP_SYS_ADMIN capability \u6388\u4e88\u67d0\u4e2a\u8fdb\u7a0b\uff0c\u8fd9\u6837\u8be5\u8fdb\u7a0b\u5c31\u53ef\u4ee5\u6267\u884c\u7cfb\u7edf\u7ba1\u7406\u4efb\u52a1\uff0c\u5982\u6302\u8f7d\u6587\u4ef6\u7cfb\u7edf\u548c\u521b\u5efa\u8bbe\u5907\u8282\u70b9\u7b49\u3002 Linux \u5185\u6838\u63d0\u4f9b\u4e86\u4e00\u7ec4\u9ed8\u8ba4\u7684 capabilities\uff0c\u4e5f\u53ef\u4ee5\u901a\u8fc7\u81ea\u5b9a\u4e49\u7684\u65b9\u5f0f\u521b\u5efa\u65b0\u7684 capabilities\uff0c\u4ee5\u4fbf\u66f4\u597d\u5730\u63a7\u5236\u7cfb\u7edf\u8d44\u6e90\u7684\u8bbf\u95ee\u6743\u9650\u3002\u53ef\u4ee5\u4f7f\u7528 setcap \u547d\u4ee4\u4e3a\u4e8c\u8fdb\u5236\u6587\u4ef6\u8bbe\u7f6e capabilities\u3002\u4f8b\u5982\uff0c\u4e0b\u9762\u7684\u547d\u4ee4\u5c06 CAP_NET_RAW capability \u6388\u4e88 /usr/bin/ping \u547d\u4ee4\uff1a sudo setcap cap_net_raw+ep /usr/bin/ping \u8fd9\u6837\uff0c\u7528\u6237\u5c31\u53ef\u4ee5\u4f7f\u7528 ping \u547d\u4ee4\u800c\u4e0d\u5fc5\u4ee5 root \u7528\u6237\u7684\u8eab\u4efd\u767b\u5f55\u3002 \u9664\u4e86 CAP_NET_BIND_SERVICE \u548c CAP_SYS_ADMIN \uff0c\u8fd8\u6709\u4e00\u4e9b\u5176\u4ed6\u7684 capabilities\uff0c\u4ee5\u4e0b\u662f\u4e00\u4e9b\u4f8b\u5b50\uff1a CAP_DAC_OVERRIDE \uff1a\u5141\u8bb8\u8fdb\u7a0b\u5ffd\u7565\u6587\u4ef6\u6743\u9650\uff0c\u53ef\u4ee5\u8bbf\u95ee\u4efb\u4f55\u6587\u4ef6\u3002 CAP_CHOWN \uff1a\u5141\u8bb8\u8fdb\u7a0b\u4fee\u6539\u6587\u4ef6\u7684\u6240\u6709\u8005\u3002 CAP_SETUID \u548c CAP_SETGID \uff1a\u5141\u8bb8\u8fdb\u7a0b\u4fee\u6539\u81ea\u5df1\u7684\u7528\u6237 ID \u548c\u7ec4 ID\u3002 CAP_NET_ADMIN \uff1a\u5141\u8bb8\u8fdb\u7a0b\u6267\u884c\u7f51\u7edc\u7ba1\u7406\u4efb\u52a1\uff0c\u5982\u914d\u7f6e\u7f51\u7edc\u63a5\u53e3\u548c\u8def\u7531\u8868\u7b49\u3002 CAP_SYS_RESOURCE \uff1a\u5141\u8bb8\u8fdb\u7a0b\u4fee\u6539\u7cfb\u7edf\u8d44\u6e90\u9650\u5236\uff0c\u5982 CPU \u65f6\u95f4\u548c\u5185\u5b58\u9650\u5236\u7b49\u3002 \u53ef\u4ee5\u901a\u8fc7\u547d\u4ee4 man 7 capabilities \u6765\u67e5\u770b\u7cfb\u7edf\u63d0\u4f9b\u7684 capabilities \u5217\u8868\u548c\u8be6\u7ec6\u8bf4\u660e\u3002\u5728\u4f7f\u7528 Kernel capabilities \u65f6\uff0c\u9700\u8981\u6ce8\u610f\uff0c\u53ea\u6709\u62e5\u6709 CAP_SETFCAP \u6216 CAP_SYS_ADMIN capability \u7684\u8fdb\u7a0b\u624d\u80fd\u591f\u4fee\u6539\u81ea\u5df1\u6216\u5176\u4ed6\u8fdb\u7a0b\u7684 capabilities\uff0c\u8fd9\u4e5f\u662f\u4e3a\u4e86\u4fdd\u62a4\u7cfb\u7edf\u7684\u5b89\u5168\u6027\u3002 \u5982\u679c\u6267\u884c setcap \u547d\u4ee4\u65f6\u51fa\u73b0 \"command not found\" \u7684\u9519\u8bef\uff0c\u8fd9\u901a\u5e38\u610f\u5473\u7740 setcap \u547d\u4ee4\u6240\u5728\u7684\u5305\u5c1a\u672a\u5b89\u88c5\u3002\u5728 openSUSE \u4e2d\uff0csetcap \u547d\u4ee4\u5305\u542b\u5728 libcap-progs \u8f6f\u4ef6\u5305\u4e2d\u3002 \u5728 openSUSE \u7cfb\u7edf\u4e2d\u9700\u8981\u5b89\u88c5 libcap-progs \u8f6f\u4ef6\u5305\uff1a sudo zypper in libcap-progs \u5728 Ubuntu/Debian \u7cfb\u7edf\u4e0a\u9700\u8981\u5b89\u88c5 libcap \u5e93\uff1a sudo apt-get install libcap2-bin \u5728 CentOS/RHEL \u7cfb\u7edf\u4e0a\u9700\u8981\u5b89\u88c5 libcap \u5e93\uff1a sudo yum install libcap-devel \u5b89\u88c5\u5b8c\u6210\u540e\uff0c\u53ef\u4ee5\u4f7f\u7528 setcap \u547d\u4ee4\u4e3a\u4e8c\u8fdb\u5236\u6587\u4ef6\u8bbe\u7f6e capabilities\u3002\u5982\u679c\u8fd8\u662f\u65e0\u6cd5\u627e\u5230 setcap \u547d\u4ee4\uff0c\u53ef\u4ee5\u5c1d\u8bd5\u4f7f\u7528\u5b8c\u6574\u8def\u5f84 /sbin/setcap \u6216\u8005 /usr/sbin/setcap\u3002","title":"\u5185\u6838\u80fd\u529b"},{"location":"k8s/cka_cn/foundamentals/docker/#seccomp","text":"seccomp\uff08secure computing mode\uff09\u662f Linux \u5185\u6838\u63d0\u4f9b\u7684\u4e00\u79cd\u5b89\u5168\u673a\u5236\uff0c\u5b83\u53ef\u4ee5\u9650\u5236\u8fdb\u7a0b\u80fd\u591f\u8fdb\u884c\u7684\u7cfb\u7edf\u8c03\u7528\u3002\u901a\u8fc7\u4f7f\u7528 seccomp\uff0c\u53ef\u4ee5\u9650\u5236\u8fdb\u7a0b\u53ea\u80fd\u591f\u4f7f\u7528\u5fc5\u8981\u7684\u7cfb\u7edf\u8c03\u7528\uff0c\u4ece\u800c\u51cf\u5c11\u7cfb\u7edf\u88ab\u653b\u51fb\u7684\u98ce\u9669\u3002 seccomp \u7b56\u7565\u53ef\u4ee5\u4f7f\u7528 BPF\uff08Berkeley Packet Filter\uff09\u8bed\u8a00\u7f16\u5199\uff0c\u5e76\u4f7f\u7528 seccomp() \u7cfb\u7edf\u8c03\u7528\u52a0\u8f7d\u3002\u4ee5\u4e0b\u662f\u4e00\u4e2a\u4f7f\u7528 seccomp \u7b56\u7565\u9650\u5236\u8fdb\u7a0b\u80fd\u591f\u8fdb\u884c\u7684\u7cfb\u7edf\u8c03\u7528\u7684\u793a\u4f8b\uff1a #include #include #include int main () { // \u521b\u5efa seccomp \u8fc7\u6ee4\u5668 struct sock_filter filter [] = { BPF_STMT ( BPF_LD | BPF_W | BPF_ABS , 0 ), BPF_JUMP ( BPF_JMP | BPF_JEQ | BPF_K , __NR_write , 0 , 1 ), BPF_STMT ( BPF_RET | BPF_K , SECCOMP_RET_ALLOW ), BPF_STMT ( BPF_RET | BPF_K , SECCOMP_RET_KILL ), }; struct sock_fprog prog = { . len = sizeof ( filter ) / sizeof ( filter [ 0 ]), . filter = filter , }; // \u52a0\u8f7d seccomp \u8fc7\u6ee4\u5668 if ( prctl ( PR_SET_SECCOMP , SECCOMP_MODE_FILTER , & prog ) < 0 ) { perror ( \"prctl\" ); return 1 ; } // \u8c03\u7528 write \u7cfb\u7edf\u8c03\u7528 char buf [] = \"Hello, world!\" ; write ( 1 , buf , sizeof ( buf )); return 0 ; } \u4e0a\u8ff0\u4ee3\u7801\u521b\u5efa\u4e86\u4e00\u4e2a seccomp \u8fc7\u6ee4\u5668\uff0c\u4ec5\u5141\u8bb8\u8fdb\u7a0b\u8c03\u7528 write() \u7cfb\u7edf\u8c03\u7528\uff0c\u5176\u4ed6\u7cfb\u7edf\u8c03\u7528\u5747\u4f1a\u88ab\u7981\u6b62\u3002\u53ef\u4ee5\u901a\u8fc7\u7f16\u8bd1\u5e76\u8fd0\u884c\u4e0a\u8ff0\u4ee3\u7801\u6765\u6f14\u793a seccomp \u7b56\u7565\u7684\u4f5c\u7528\u3002 \u9700\u8981\u6ce8\u610f\u7684\u662f\uff0cseccomp \u7b56\u7565\u53ea\u80fd\u591f\u9650\u5236\u8fdb\u7a0b\u8fdb\u884c\u7684\u7cfb\u7edf\u8c03\u7528\uff0c\u4f46\u4e0d\u80fd\u591f\u9650\u5236\u7cfb\u7edf\u8c03\u7528\u7684\u53c2\u6570\u6216\u8fd4\u56de\u503c\u3002\u56e0\u6b64\uff0c\u4f7f\u7528 seccomp \u7b56\u7565\u65f6\u9700\u8981\u7279\u522b\u5c0f\u5fc3\uff0c\u907f\u514d\u8bef\u7528\u6216\u4ea7\u751f\u6f0f\u6d1e\u3002","title":"seccomp\u7b56\u7565"},{"location":"k8s/cka_cn/foundamentals/docker/#netlink","text":"Netlink \u662f\u4e00\u79cd Linux \u5185\u6838\u63d0\u4f9b\u7684\u901a\u4fe1\u673a\u5236\uff0c\u7528\u4e8e\u5185\u6838\u548c\u7528\u6237\u7a7a\u95f4\u8fdb\u7a0b\u4e4b\u95f4\u7684\u53cc\u5411\u901a\u4fe1\uff08IPC\uff09\u3002Netlink \u53ef\u4ee5\u7528\u4e8e\u8bb8\u591a\u76ee\u7684\uff0c\u4f8b\u5982\uff1a \u914d\u7f6e\u7f51\u7edc\u8bbe\u5907\u548c\u8def\u7531\u8868\uff1a\u4f7f\u7528 Netlink \u53ef\u4ee5\u901a\u8fc7\u7528\u6237\u7a7a\u95f4\u8fdb\u7a0b\u4fee\u6539\u5185\u6838\u7684\u7f51\u7edc\u8bbe\u5907\u548c\u8def\u7531\u8868\u914d\u7f6e\uff0c\u4f8b\u5982\u6dfb\u52a0\u3001\u5220\u9664\u3001\u4fee\u6539\u7f51\u7edc\u63a5\u53e3\u3001IP \u5730\u5740\u3001\u8def\u7531\u7b49\u3002 \u76d1\u89c6\u7f51\u7edc\u4e8b\u4ef6\uff1a\u4f7f\u7528 Netlink \u53ef\u4ee5\u5b9e\u65f6\u5730\u4ece\u5185\u6838\u83b7\u53d6\u7f51\u7edc\u4e8b\u4ef6\u7684\u901a\u77e5\uff0c\u4f8b\u5982\u7f51\u7edc\u63a5\u53e3\u7684\u72b6\u6001\u53d8\u5316\u3001\u8def\u7531\u7684\u53d8\u5316\u7b49\u3002 \u7a0b\u5e8f\u95f4\u901a\u4fe1\uff1a\u4f7f\u7528 Netlink \u53ef\u4ee5\u5728\u7528\u6237\u7a7a\u95f4\u8fdb\u7a0b\u4e4b\u95f4\u8fdb\u884c\u901a\u4fe1\uff0c\u7c7b\u4f3c\u4e8e Unix \u57df\u5957\u63a5\u5b57\u3002 Netlink \u673a\u5236\u57fa\u4e8e\u4e00\u79cd\u7279\u6b8a\u7684\u5957\u63a5\u5b57\u7c7b\u578b\uff08PF_NETLINK\uff09\u548c\u4e00\u4e2a\u7279\u5b9a\u7684\u534f\u8bae\uff08NETLINK\uff09\u3002\u7528\u6237\u7a7a\u95f4\u8fdb\u7a0b\u53ef\u4ee5\u901a\u8fc7\u521b\u5efa Netlink \u5957\u63a5\u5b57\u548c\u5185\u6838\u901a\u4fe1\u3002\u5185\u6838\u548c\u7528\u6237\u7a7a\u95f4\u8fdb\u7a0b\u4e4b\u95f4\u7684\u901a\u4fe1\u662f\u57fa\u4e8e Netlink \u6d88\u606f\u7684\uff0c\u6bcf\u4e2a Netlink \u6d88\u606f\u5305\u542b\u4e00\u4e2a\u6d88\u606f\u5934\u548c\u4e00\u4e2a\u8d1f\u8f7d\uff08payload\uff09\uff0c\u8d1f\u8f7d\u53ef\u4ee5\u662f\u4efb\u4f55\u7ed3\u6784\u4f53\u6216\u4e8c\u8fdb\u5236\u6570\u636e\u3002 Netlink \u6d88\u606f\u7684\u7c7b\u578b\u548c\u683c\u5f0f\u7531\u5185\u6838\u5b9a\u4e49\u3002\u7528\u6237\u7a7a\u95f4\u8fdb\u7a0b\u9700\u8981\u4e86\u89e3\u5185\u6838\u7684 Netlink \u6d88\u606f\u683c\u5f0f\u548c\u7c7b\u578b\uff0c\u624d\u80fd\u6b63\u786e\u5730\u6784\u9020\u548c\u89e3\u6790 Netlink \u6d88\u606f\u3002\u5e38\u7528\u7684 Netlink \u6d88\u606f\u7c7b\u578b\u5305\u62ec\uff1a RTM_NEWLINK \u548c RTM_DELLINK\uff1a\u6dfb\u52a0\u548c\u5220\u9664\u7f51\u7edc\u63a5\u53e3\u3002 RTM_NEWADDR \u548c RTM_DELADDR\uff1a\u6dfb\u52a0\u548c\u5220\u9664 IP \u5730\u5740\u3002 RTM_NEWROUTE \u548c RTM_DELROUTE\uff1a\u6dfb\u52a0\u548c\u5220\u9664\u8def\u7531\u3002 RTM_NEWNEIGH \u548c RTM_DELNEIGH\uff1a\u6dfb\u52a0\u548c\u5220\u9664 ARP \u8868\u9879\u3002 Netlink \u53ef\u4ee5\u4f7f\u7528 C \u8bed\u8a00\u7684 socket API \u8fdb\u884c\u7f16\u7a0b\u3002","title":"Netlink"},{"location":"k8s/cka_cn/foundamentals/docker/#netfilter","text":"Netfilter\u662fLinux\u5185\u6838\u4e2d\u7684\u4e00\u4e2a\u5b50\u7cfb\u7edf\uff0c\u7528\u4e8e\u5728\u6570\u636e\u5305\u4f20\u8f93\u8fc7\u7a0b\u4e2d\u8fdb\u884c\u8fc7\u6ee4\u548c\u64cd\u4f5c\u3002\u5b83\u652f\u6301\u5bf9\u7f51\u7edc\u6570\u636e\u5305\u8fdb\u884c\u5404\u79cd\u7c7b\u578b\u7684\u5904\u7406\uff0c\u5305\u62ec\u8fc7\u6ee4\u3001\u4fee\u6539\u3001\u91cd\u5b9a\u5411\u7b49\u3002Netfilter\u901a\u8fc7\u5728\u5185\u6838\u4e2d\u6ce8\u518c\u94a9\u5b50\u51fd\u6570\uff0c\u5728\u6570\u636e\u5305\u901a\u8fc7\u7f51\u7edc\u6808\u7684\u4e0d\u540c\u9636\u6bb5\u65f6\u8fdb\u884c\u62e6\u622a\u548c\u5904\u7406\u3002 Netfilter\u7684\u6838\u5fc3\u662fiptables\u547d\u4ee4\uff0c\u5b83\u53ef\u4ee5\u7528\u6765\u914d\u7f6eNetfilter\u89c4\u5219\u3002iptables\u547d\u4ee4\u53ef\u4ee5\u7528\u6765\u914d\u7f6e\u9632\u706b\u5899\u89c4\u5219\uff0cNAT\u89c4\u5219\uff0c\u9650\u5236\u8fde\u63a5\u901f\u5ea6\u7b49\u3002iptables\u547d\u4ee4\u901a\u8fc7\u5339\u914d\u4e0d\u540c\u7684\u6570\u636e\u5305\u5b57\u6bb5\uff08\u4f8b\u5982\u6e90IP\u5730\u5740\u3001\u76ee\u7684IP\u5730\u5740\u3001\u6e90\u7aef\u53e3\u3001\u76ee\u7684\u7aef\u53e3\u7b49\uff09\u6765\u8fdb\u884c\u8fc7\u6ee4\u3002 \u9664\u4e86iptables\u547d\u4ee4\uff0c\u8fd8\u6709\u5176\u4ed6\u4e00\u4e9b\u5de5\u5177\u53ef\u4ee5\u7528\u4e8e\u914d\u7f6eNetfilter\u89c4\u5219\uff0c\u4f8b\u5982nftables\u547d\u4ee4\u548cfirewalld\u670d\u52a1\u3002\u8fd9\u4e9b\u5de5\u5177\u63d0\u4f9b\u4e86\u66f4\u7075\u6d3b\u3001\u66f4\u5f3a\u5927\u7684\u914d\u7f6e\u9009\u9879\uff0c\u53ef\u4ee5\u5e2e\u52a9\u7ba1\u7406\u5458\u66f4\u597d\u5730\u7ba1\u7406\u548c\u4fdd\u62a4\u7f51\u7edc\u5b89\u5168\u3002 \u4e5f\u53ef\u4ee5\u7528\u4e8e\u5c06\u7f51\u7edc\u6570\u636e\u5305\u5b9a\u5411\u5230\u5355\u4e2a\u5bb9\u5668\u3002 \u66f4\u591a\u4fe1\u606f\u53ef\u4ee5\u53c2\u8003 LXC/LXD \u3002","title":"Netfilter"},{"location":"k8s/cka_cn/foundamentals/docker/#docker","text":"\u53c2\u8003 \u6307\u5bfc \u5b89\u88c5Docker\u5f15\u64ce\u3002 \u53c2\u8003 \u6307\u5bfc \u5b89\u88c5Docker\u684c\u9762\u7248\u3002 \u4e0b\u9762\u4ee5openSUSE\u4e3a\u4f8b\u5b89\u88c5Docker\u5f15\u64ce\u3002 sudo zypper in docker \u5728\u5b89\u88c5\u8fc7\u7a0b\u4e2d\uff0c\u5728\u64cd\u4f5c\u7cfb\u7edf\u4e2d\u4f1a\u81ea\u52a8\u521b\u5efa\u7ec4 docker \u3002 \u5c06vagrant\u7528\u6237\u52a0\u5165docker\u7ec4\uff0c\u5219vagrant\u7528\u6237\u53ef\u4ee5\u5728\u4e0b\u6b21\u767b\u5f55\u540e\u4e0e\u672c\u673a\u7684Docker\u5b88\u62a4\u8fdb\u7a0b\uff08daemon\uff09\u8fdb\u884c\u901a\u4fe1\u3002Docker\u5b88\u62a4\u8fdb\u7a0b\u76d1\u542c\u672c\u5730\u5957\u63a5\u5b57\uff0c\u53ea\u80fd\u7531root\u7528\u6237\u548cdocker\u7ec4\u7684\u6210\u5458\u8bbf\u95ee\u3002 sudo usermod -aG docker $USER \u542f\u7528\u5e76\u542f\u52a8 Docker \u5f15\u64ce\u3002 sudo systemctl enable docker.service sudo systemctl start docker.service sudo systemctl status docker.service \u4e0b\u9762\u901a\u8fc7\u4e00\u4e2a\u5bb9\u5668 alpine \u7684\u4f8b\u5b50\u6765\u6f14\u793a\u5728\u76ee\u5f55 /opt/test \u4e0b\u6a21\u62df\u5b9e\u73b0choot\u3002 mkdir test cd test wget https://dl-cdn.alpinelinux.org/alpine/v3.13/releases/x86_64/alpine-minirootfs-3.13.4-x86_64.tar.gz tar zxvf alpine-minirootfs-3.13.4-x86_64.tar.gz -C alpine-minirootfs/ \u67e5\u770b\u5f53\u524d\u76ee\u5f55\u7ed3\u6784\uff1a tree ./test -L 1 \u8f93\u51fa\u7ed3\u679c\uff1a ./test \u251c\u2500\u2500 alpine-minirootfs-3.13.4-x86_64.tar.gz \u251c\u2500\u2500 bin \u251c\u2500\u2500 dev \u251c\u2500\u2500 etc \u251c\u2500\u2500 home \u251c\u2500\u2500 lib \u251c\u2500\u2500 media \u251c\u2500\u2500 mnt \u251c\u2500\u2500 opt \u251c\u2500\u2500 proc \u251c\u2500\u2500 root \u251c\u2500\u2500 run \u251c\u2500\u2500 sbin \u251c\u2500\u2500 srv \u251c\u2500\u2500 sys \u251c\u2500\u2500 tmp \u251c\u2500\u2500 usr \u2514\u2500\u2500 var \u901a\u8fc7\u547d\u4ee4 unshare \u6302\u8f7d\u76ee\u5f55 /opt/test/proc \u5230\u67d0\u4e2a\u6587\u4ef6\u6765\u5b9e\u73b0\u5ba2\u6237\u5b50\u7cfb\u7edf\u3002 sudo mount -t tmpfs tmpfs /opt/test/proc sudo unshare --pid --mount-proc = $PWD /test/proc --fork chroot ./test/ /bin/sh / # ps -ef PID USER TIME COMMAND 1 root 0 :00 /bin/sh 2 root 0 :00 ps -ef / # touch 123 / # ls 123 123 \u6587\u4ef6 123 \u5728\u5ba2\u6237\u5b50\u7cfb\u7edf\u4e2d\u5df2\u521b\u5efa\uff0c\u5bf9\u5e94\u4e3b\u7cfb\u7edf\u4e2d\u4e5f\u53ef\u4ee5\u5bf9\u5176\u8fdb\u884c\u8bfb\u5199\u64cd\u4f5c\u3002\u6bd4\u5982\uff0c\u4fee\u6539\u6587\u4ef6 123 \u7684\u5185\u5bb9\u3002 su - ls 123 echo hello > 123 \u6587\u4ef6 123 \u4fee\u6539\u540e\u7684\u5185\u5bb9\u5728\u5ba2\u6237\u673a\u91cc\u9762\u4e5f\u53ef\u89c1\u3002 / # cat 123 hello \u5728\u4e3b\u7cfb\u7edf\u4e2d\u518d\u521b\u5efa\u4e24\u4e2a\u5b50\u76ee\u5f55 /opt/test-1 \u548c /opt/test-2 \u3002 mkdir test-1 mkdir test-2 \u521b\u5efa2\u4e2a\u5ba2\u6237\u5b50\u7cfb\u7edf\uff0c\u5e76\u5c06\u4e0a\u9762\u7684\u4e24\u4e2a\u5b50\u76ee\u5f55\u6302\u5728\u5230\u5404\u81ea\u7684 /opt/test/home/ \u76ee\u5f55\u3002 sudo mount --bind /opt/test-1 /opt/test/home/ sudo unshare --pid --mount-proc = $PWD /test/proc --fork chroot ./test/ /bin/sh / # cd /home /home # echo \"test-1\" > 123.1 /home # cat 123.1 test-1 sudo mount --bind /opt/test-2 /opt/test/home/ sudo unshare --pid --mount-proc = $PWD /test/proc --fork chroot ./test/ /bin/sh / # cd /home /home # echo \"test-2\" > 123.2 /home # cat 123.2 test-2 ll test/home ll test-1/ ll test-2/ \u901a\u8fc7\u4e0a\u9762\u7684\u6f14\u793a\uff0c\u53ef\u4ee5\u5f97\u51fa\u7ed3\u8bba\uff0c\u4e24\u4e2a\u5ba2\u6237\u5b50\u7cfb\u7edf\u6302\u5728\u5230\u540c\u4e00\u4e2a\u4e3b\u7cfb\u7edf\u76ee\u5f55\u65f6\uff0c\u5b50\u7cfb\u7edf\u65f6\u5171\u4eab\u4e3b\u7cfb\u7edf\u76ee\u5f55\uff0c\u5e76\u76f8\u4e92\u5f71\u54cd\u3002","title":"\u5b89\u88c5Docker"},{"location":"k8s/cka_cn/foundamentals/docker/#_6","text":"","title":"\u5bb9\u5668\u751f\u547d\u5468\u671f"},{"location":"k8s/cka_cn/foundamentals/docker/#_7","text":"\u9884\u5148\u4e0b\u8f7d\u4e0b\u5217\u955c\u50cf\u3002 docker image pull busybox docker image pull nginx docker image pull alpine docker image pull jenkins/jenkins:lts docker image pull golang:1.12-alpine docker image pull golang \u521b\u5efa\u5e76\u4ea4\u4e92\u5f0f\u8fd0\u884c\u4e00\u4e2a\u65b0\u7684busybox\u5bb9\u5668\uff0c\u5e76\u8fde\u63a5\u4e00\u4e2a\u4f2a\u7ec8\u7aef\uff08pseudo terminal\uff09\u3002 \u5728\u5bb9\u5668\u5185\uff0c\u4f7f\u7528 top \u547d\u4ee4\u67e5\u627e /bin/sh \u6b63\u5728\u4f5c\u4e3aPID\u4e3a1\u7684\u8fdb\u7a0b\u8fd0\u884c\uff0c\u4ee5\u53ca top \u8fdb\u7a0b\u4e5f\u5728\u8fd0\u884c\u3002 \u7136\u540e\uff0c\u9000\u51fa\u5bb9\u5668\u3002 docker image ls docker run -d -it --name busybox_v1 -v /opt/test:/docker busybox:latest /bin/sh docker container ps -a docker exec -it 185efe490507 /bin/sh / # top Mem: 3627396K used, 12731512K free, 10080K shrd, 2920K buff, 2999340K cached CPU: 0 .0% usr 0 .1% sys 0 .0% nic 99 .8% idle 0 .0% io 0 .0% irq 0 .0% sirq Load average: 0 .38 1 .09 1 .29 2 /277 14 PID PPID USER STAT VSZ %VSZ CPU %CPU COMMAND 1 0 root S 1332 0 .0 1 0 .0 /bin/sh 8 0 root S 1332 0 .0 2 0 .0 /bin/sh 14 8 root R 1328 0 .0 1 0 .0 top / # exitbuild \u542f\u52a8\u4e00\u4e2a\u65b0\u7684 Nginx \u5bb9\u5668\uff0c\u5e76\u4ee5\u72ec\u7acb\u6a21\u5f0f\uff08detached mode\uff09\u8fd0\u884c\u3002 \u4f7f\u7528 docker exec \u547d\u4ee4\u5728 Nginx \u5bb9\u5668\u4e2d\u542f\u52a8\u53e6\u4e00\u4e2a shell\uff08 /bin/sh \uff09\u3002 \u4f7f\u7528 ps \u547d\u4ee4\u67e5\u770b\u5bb9\u5668\u4e2d\u6b63\u5728\u8fd0\u884c\u7684 sh \u548c ps \u547d\u4ee4\uff08\u5728\u4e0a\u4e00\u6b65\u6267\u884c\u7684\uff09\u3002 docker run -d -it --name nginx_v1 -v /opt/test:/docker nginx:latest /bin/sh docker container ps -a docker exec -it edb640127a0d /bin/sh # ps /bin/sh: 2 : ps: not found # apt-get update && apt-get install -y procps # ps PID TTY TIME CMD 8 pts/1 00 :00:00 sh 351 pts/1 00 :00:00 ps # exit \u901a\u8fc7\u4e0b\u9762\u547d\u4ee4\u53ef\u4ee5\u770b\u52302\u4e2a\u73b0\u5728\u8fd0\u884c\u4e2d\u7684\u5bb9\u5668\u3002 docker container ps -a \u4f7f\u7528 docker logs \u547d\u4ee4\u663e\u793a\u6211\u4eec\u521a\u521a\u9000\u51fa\u7684\u5bb9\u5668\u7684\u65e5\u5fd7\u3002\u9009\u9879 --since 35m \u8868\u793a\u663e\u793a\u6700\u8fd1 35 \u5206\u949f\u5185\u7684\u65e5\u5fd7\u3002 docker logs nginx_v1 --details --since 35m docker logs busybox_v1 --details --since 35m \u4f7f\u7528 docker stop \u547d\u4ee4\u6765\u505c\u6b62 nginx \u5bb9\u5668\u3002 docker stop busybox_v1 docker stop nginx_v1 docker container ps -a \u4f7f\u7528\u4e0a\u8ff0\u547d\u4ee4 docker container ps -a \uff0c\u6211\u4eec\u53ef\u4ee5\u83b7\u53d6\u6240\u6709\u6b63\u5728\u8fd0\u884c\u548c\u5df2\u9000\u51fa\u7684\u5bb9\u5668\u5217\u8868\u3002\u4f7f\u7528 docker rm \u5c06\u5176\u5220\u9664\u3002\u4f7f\u7528 docker rm $(docker ps -aq) \u6765\u6e05\u7406\u4e3b\u673a\u4e0a\u7684\u6240\u6709\u5bb9\u5668\u3002\u8bf7\u8c28\u614e\u4f7f\u7528\uff01 docker rm busybox_v1 docker container ps -a","title":"\u6982\u8ff0"},{"location":"k8s/cka_cn/foundamentals/docker/#_8","text":"\u73b0\u5728\u542f\u52a8\u4e00\u4e2a\u65b0\u7684 nginx \u5bb9\u5668\uff0c\u5e76\u5c06 nginx web \u670d\u52a1\u5668\u7684\u7aef\u53e3\u5bfc\u51fa\u5230 Docker \u968f\u673a\u9009\u62e9\u7684\u7aef\u53e3\u3002 \u6211\u4eec\u53ef\u4ee5\u4f7f\u7528\u547d\u4ee4 docker ps \u627e\u51fa web \u670d\u52a1\u5668\u8f6c\u53d1\u5230\u4e86\u54ea\u4e2a\u7aef\u53e3\u3002\u5728\u4e3b\u673a\u4e0a\u4f7f\u7528\u8f6c\u53d1\u7684\u7aef\u53e3\u53f7\u8bbf\u95ee docker http://localhost: \u3002 docker container ps -a docker run -d -P --name nginx_v2 nginx:latest docker container ps -a Start another nginx container and expose port to 1080 on host as an example via http://localhost:1080 . \u542f\u52a8\u53e6\u4e00\u4e2anginx\u5bb9\u5668\uff0c\u5c06\u5176\u7aef\u53e3\u6620\u5c04\u5230\u4e3b\u673a\u76841080\u7aef\u53e3\uff0c\u53ef\u4ee5\u901a\u8fc7 http://localhost:1080 \u8bbf\u95ee\u3002 docker run -d -p 1080 :80 --name nginx_v3 nginx:latest docker container ps -a \u4f7f\u7528 docker inspect \u547d\u4ee4\u67e5\u627e\u955c\u50cf\u66b4\u9732\u7684\u7aef\u53e3\u53f7\uff0c\u8f93\u51faJSON\u683c\u5f0f\u6587\u4ef6\uff0c\u7f51\u7edc\u4fe1\u606f\uff08IP\u3001\u7f51\u5173\u3001\u7aef\u53e3\u7b49\uff09\u662f\u8f93\u51faJSON\u683c\u5f0f\u7684\u4e00\u90e8\u5206\u3002 docker inspect nginx_v3 \u5728\u76ee\u5f55 /opt/test \u4e2d\u521b\u5efa\u4e00\u4e2a\u540d\u4e3a index.html \u7684\u6587\u4ef6\uff0c\u5176\u5185\u5bb9\u5982\u4e0b\uff1a < html > < head > < title > Sample Website from my container < body > < h1 > This is a custom website. < p > This website is served from my < a href = \"http://www.docker.com\" target = \"_blank\" > Docker container. \u542f\u52a8\u4e00\u4e2a\u65b0\u5bb9\u5668\uff0c\u5c06\u4e3b\u673a\u76ee\u5f55 /opt/test \u4e0e\u5bb9\u5668\u76ee\u5f55 /usr/share/nginx/html \u7ed1\u5b9a\u6302\u8f7d\u4e3a\u4e00\u4e2a\u5377\uff0c\u4ee5\u4fbfNginx\u53ef\u4ee5\u901a\u8fc7 http://localhost:49159/ \u53d1\u5e03\u6211\u4eec\u521a\u521b\u5efa\u7684html\u6587\u4ef6\uff0c\u800c\u4e0d\u662fNginx\u9ed8\u8ba4\u7684\u9875\u9762\u3002 docker run -d -P --mount type = bind,source = /opt/test/,target = /usr/share/nginx/html --name nginx_v3-1 nginx:latest docker container ps -a \u68c0\u67e5Nginx\u914d\u7f6e\u6587\u4ef6\uff0c\u67e5\u770b\u5bb9\u5668\u4e2dhtml\u4e3b\u9875\u5b58\u50a8\u7684\u4f4d\u7f6e\u3002 docker exec -it nginx_v3-1 /bin/sh # cd /etc/nginx/conf.d # ls default.conf # cat default.conf server { listen 80 ; listen [ :: ] :80 ; server_name localhost ; #access_log /var/log/nginx/host.access.log main; location / { root /usr/share/nginx/html ; <-- index index.html index.htm ; } #error_page 404 /404.html; # redirect server error pages to the static page /50x.html # error_page 500 502 503 504 /50x.html ; location = /50x.html { root /usr/share/nginx/html ; } # proxy the PHP scripts to Apache listening on 127.0.0.1:80 # #location ~ \\.php$ { # proxy_pass http://127.0.0.1; #} # pass the PHP scripts to FastCGI server listening on 127.0.0.1:9000 # #location ~ \\.php$ { # root html; # fastcgi_pass 127.0.0.1:9000; # fastcgi_index index.php; # fastcgi_param SCRIPT_FILENAME /scripts$fastcgi_script_name; # include fastcgi_params; #} # deny access to .htaccess files, if Apache's document root # concurs with nginx's one # #location ~ /\\.ht { # deny all; #} } # cd /usr/share/nginx/html # cat index.html Sample Website from my container

This is a custom website.

This website is served from my Docker container.

# \u63a8\u8350\u4f7f\u7528\u5377 API \u6765\u5b9e\u73b0\u6570\u636e\u6301\u4e45\u5316\uff0c\u800c\u4e0d\u662f\u5c06\u6570\u636e\u5b58\u50a8\u5728 Docker \u5bb9\u5668\u4e2d\u3002Docker \u652f\u6301\u4e24\u79cd\u6302\u8f7d\u65b9\u5f0f\uff1a \u7ed1\u5b9a\u6302\u8f7d\uff08Bind mounts\uff09\uff1a \u5c06\u672c\u5730\u4e3b\u673a\u76ee\u5f55\u6302\u8f7d\u5230\u5bb9\u5668\u4e2d\u7684\u67d0\u4e2a\u8def\u5f84\u3002 \u6302\u8f7d\u540e\uff0c\u76ee\u6807\u76ee\u5f55\u4e2d\u539f\u6709\u7684\u6240\u6709\u5185\u5bb9\u5c06\u88ab\u9690\u85cf\u3002 \u4f8b\u5982\uff0c\u5982\u679c\u6211\u4eec\u60f3\u8981\u6ce8\u5165\u67d0\u4e9b\u914d\u7f6e\u6587\u4ef6\uff0c\u6211\u4eec\u9700\u8981\u81ea\u5df1\u5199\u5bf9\u5e94\u7684\u914d\u7f6e\u6587\u4ef6\uff0c\u5c06\u5176\u5b58\u50a8\u5728 Docker \u4e3b\u673a\u4e0a\u7684 /home/container/config \u8def\u5f84\u4e0b\uff0c\u5e76\u5c06\u6b64\u76ee\u5f55\u7684\u5185\u5bb9\u6302\u8f7d\u5230 /usr/application/config \uff08\u5047\u8bbe\u5e94\u7528\u7a0b\u5e8f\u4ece\u6b64\u5904\u8bfb\u53d6\u914d\u7f6e\uff09\u3002 \u547d\u4ee4\uff1a docker run --mount type=bind,source=,target= \u2026 \u547d\u540d\u5377\uff08Named volumes\uff09\uff1a Docker \u53ef\u4ee5\u521b\u5efa\u4e00\u4e2a\u72ec\u7acb\u7684\u5b58\u50a8\u5377\uff0c\u5176\u751f\u547d\u5468\u671f\u72ec\u7acb\u4e8e\u5bb9\u5668\u4f46\u4ecd\u7531 Docker \u7ba1\u7406\u3002 \u5728\u521b\u5efa\u65f6\uff0c\u6302\u8f7d\u76ee\u6807\u7684\u5185\u5bb9\u5c06\u5408\u5e76\u5230\u5377\u4e2d\u3002 \u547d\u4ee4\uff1a docker run --mount source=,target= \u2026 \u5982\u4f55\u533a\u5206\u7ed1\u5b9a\u6302\u8f7d\u548c\u547d\u540d\u5377\uff1f \u5f53\u6307\u5b9a\u7edd\u5bf9\u8def\u5f84\u65f6\uff0cDocker \u4f1a\u8ba4\u4e3a\u8fd9\u662f\u4e00\u4e2a\u7ed1\u5b9a\u6302\u8f7d\u3002 \u5f53\u6211\u4eec\u4ec5\u63d0\u4f9b\u540d\u79f0\uff08\u5982\u76f8\u5bf9\u8def\u5f84 config \uff09\u65f6\uff0c\u5b83\u4f1a\u8ba4\u4e3a\u8fd9\u662f\u4e00\u4e2a\u547d\u540d\u5377\uff0c\u5e76\u521b\u5efa\u4e00\u4e2a\u540d\u4e3a config \u7684\u5377\u3002 \u6ce8\uff1a\u6301\u4e45\u5b58\u50a8\u7531\u4e3b\u673a\u63d0\u4f9b\uff0c\u53ef\u4ee5\u76f4\u63a5\u662f\u4e3b\u673a\u6587\u4ef6\u7cfb\u7edf\u7684\u4e00\u90e8\u5206\uff0c\u4e5f\u53ef\u4ee5\u662f NFS \u6302\u8f7d\u3002","title":"\u7aef\u53e3\u548c\u5377"},{"location":"k8s/cka_cn/foundamentals/docker/#dockerfile","text":"\u8ba9\u6211\u4eec\u7528 Dockerfile \u6784\u5efa\u4e00\u4e2a\u955c\u50cf\uff0c\u5bf9\u5176\u8fdb\u884c\u6253\u6807\u7b7e\u5e76\u4e0a\u4f20\u5230\u955c\u50cf\u4ed3\u5e93\u3002 \u83b7\u53d6 Docker \u955c\u50cf\u7684\u6784\u5efa\u5386\u53f2\u8bb0\u5f55\u3002 docker image history nginx:latest \u521b\u5efa\u4e00\u4e2a\u7a7a\u7684\u76ee\u5f55 /opt/tmp-1 \uff0c\u8fdb\u5165\u8be5\u76ee\u5f55\u5e76\u5728\u5176\u4e2d\u521b\u5efa index.html \u6587\u4ef6\u3002 /opt/tmp-1> cat index.html Sample Website from my container

This is a custom website.

This website is served from my Docker container.

\u4f7f\u7528 FROM \u6765\u6269\u5c55\u4e00\u4e2a\u5df2\u6709\u7684\u955c\u50cf\uff0c\u5e76\u6307\u5b9a\u7248\u672c\u53f7\u3002 \u4f7f\u7528 COPY \u5c06\u4e00\u4e2a\u65b0\u7684\u9ed8\u8ba4\u7f51\u7ad9\u590d\u5236\u5230\u955c\u50cf\u4e2d\uff0c\u4f8b\u5982 /usr/share/nginx/html \u3002 \u4e3aNginx\u521b\u5efaSSL\u914d\u7f6e /opt/tmp-1/ssl.conf \u3002 server { listen 443 ssl; server_name localhost; ssl_certificate /etc/nginx/ssl/nginx.crt; ssl_certificate_key /etc/nginx/ssl/nginx.key; location / { root /usr/share/nginx/html; index index.html index.htm; } } \u4f7f\u7528OpenSSL\u521b\u5efa\u4e00\u4e2a\u81ea\u7b7e\u540d\u8bc1\u4e66\uff0c\u4ee5\u4fbfSSL/TLS\u5de5\u4f5c\u3002 \u4f7f\u7528\u4ee5\u4e0b\u547d\u4ee4\u521b\u5efa\u4e00\u4e2a\u52a0\u5bc6\u5bc6\u94a5\u548c\u8bc1\u4e66\u3002 openssl req -x509 -nodes -newkey rsa:4096 -keyout nginx.key -out nginx.crt -days 365 -subj \"/CN= $( hostname ) \" \u4e3a\u4e86\u542f\u7528\u52a0\u5bc6\u7684HTTPS\uff0c\u6211\u4eec\u9700\u8981\u4f7f\u7528 EXPOSE \u6307\u4ee4\u516c\u5f00 443 \u7aef\u53e3\u3002\u9ed8\u8ba4\u7684nginx\u955c\u50cf\u4ec5\u516c\u5f00\u7aef\u53e3 80 \uff0c\u7528\u4e8e\u975e\u52a0\u5bc6\u7684HTTP\u3002 \u5728 /opt/tmp-1 \u6587\u4ef6\u5939\u4e2d\u521b\u5efa\u4ee5\u4e0bDockerfile\u3002 cat Dockerfile \u8f93\u51fa\uff1a FROM nginx:latest # copy the custom website into the image COPY index.html /usr/share/nginx/html # copy the SSL configuration file into the image COPY ssl.conf /etc/nginx/conf.d/ssl.conf # download the SSL key and certificate into the image COPY nginx.key /etc/nginx/ssl/ COPY nginx.crt /etc/nginx/ssl/ # expose the HTTPS port EXPOSE 443 \u81f3\u6b64\uff0c\u6211\u4eec\u5728\u76ee\u5f55 /opt/tmp-1 \u4e0b\u67095\u4e2a\u6587\u4ef6\u3002 ls /opt/tmp-1 \u8f93\u51fa\uff1a Dockerfile index.html nginx.crt nginx.key ssl.conf \u4f7f\u7528 docker build \u547d\u4ee4\u6765\u6784\u5efa\u955c\u50cf\uff0c\u5e76\u5c06\u5bb9\u5668\u768480\u548c443\u7aef\u53e3\u8f6c\u53d1\u3002 docker build -t nginx:my1 /opt/tmp-1/ docker image ls docker run -d -p 1086 :80 -p 1088 :443 --name nginx_v5 nginx:my1 docker container ps -a \u901a\u8fc7\u4e0b\u9762\u4e24\u4e2a\u94fe\u63a5\u6765\u9a8c\u8bc1\u4e0a\u9762\u7684\u53d8\u5316\u662f\u5426\u751f\u6548\u3002 http://localhost:1086/ https://localhost:1088/ \u5728 DockerHub \u6ce8\u518c\u4e00\u4e2a\u4e2a\u4eba\u8d26\u53f7\uff0c\u542f\u7528 Docker Hub \u4e2d\u7684\u8bbf\u95ee\u4ee4\u724c\u4ee5\u8fdb\u884c CLI \u5ba2\u6237\u7aef\u8eab\u4efd\u9a8c\u8bc1\u3002 docker login \u8f93\u5165\u7528\u6237\u540d\u548c\u5bc6\u7801\u3002 Username: Password: \u7ed9\u8fd9\u4e2a\u955c\u50cf\u52a0\u4e0a\u4e00\u4e2a\u6807\u7b7e\uff0c\u4f8b\u5982\uff1asecure_nginx_0001\uff0c\u7248\u672c\u53f7\u4e3a v1\u3002 docker tag nginx:my1 secure_nginx_0001:v1 docker push secure_nginx_0001:v1 docker image ls","title":"Dockerfile"},{"location":"k8s/cka_cn/foundamentals/docker/#dockerfile_1","text":"\u4e0b\u9762\u7684\u4f8b\u5b50\u662f\u6f14\u793a\u4e00\u4e2a\u591a\u9636\u6bb5\uff08Multi-stage\uff09\u6784\u5efa\u7684\u4f8b\u5b50\u3002\u5728Docker\u7684\u4e0a\u4e0b\u6587\u4e2d\uff0c\u591a\u9636\u6bb5\uff08Multi-stage\uff09\u610f\u5473\u7740\u6211\u4eec\u53ef\u4ee5\u6709\u591a\u4e2a\u5e26\u6709 FROM \u5173\u952e\u5b57\u7684\u884c\u3002 \u521b\u5efa\u6587\u4ef6\u5939 /opt/tmp-2 \u548c /opt/tmp-2/tmpl \u3002\u521b\u5efa\u6587\u4ef6 edit.html \uff0c view.html \uff0c wiki.go \u3002 \u6587\u4ef6\u7ed3\u6784\u5982\u4e0b\uff1a tree -l /opt/tmp-2 \u8f93\u51fa\u7ed3\u679c\uff1a . \u251c\u2500\u2500 tmpl \u2502 \u251c\u2500\u2500 edit.html \u2502 \u2514\u2500\u2500 view.html \u2514\u2500\u2500 wiki.go \u521b\u5efa\u4e00\u4e2a\u65b0\u7684Dockerfile\u3002 cat Dockerfile \u6587\u4ef6\u5185\u5bb9\uff1a # app builder stage FROM golang:1.12-alpine as builder # # copy the go source code over and build the binary WORKDIR /go/src COPY wiki.go /go/src/wiki.go RUN go build wiki.go # app exec stage # separate & new image starts here!# FROM alpine:3.9 # prepare file system etc RUN mkdir -p /app/data /app/tmpl && adduser -S -D -H -h /app appuser COPY tmpl/* /app/tmpl/ # get the compiled binary from the previous stage COPY --from=builder /go/src/wiki /app/wiki # prepare runtime env RUN chown -R appuser /app USER appuser WORKDIR /app # expose app port & set default command EXPOSE 8080 CMD [\"/app/wiki\"] \u7528\u4e0a\u4e00\u6b65\u521b\u5efa\u7684Dockerfile\u6765\u521b\u5efa\u65b0\u666f\u8c61\u3002 docker build -t lizard/golang:my1 /opt/tmp-2/ \u4ee5\u72ec\u7acb\u6a21\u5f0f\uff08detached\uff09\u8fd0\u884c\u8fd9\u4e2a\u955c\u50cf\uff0c\u5e76\u5c06\u5bb9\u5668\u7aef\u53e3 8080 \u8f6c\u53d1\u5230\u4e3b\u673a\u7aef\u53e3 1090 \u3002 docker run -d -p 1090 :8080 --name golan_v1 lizard/golang:my1 \u901a\u8fc7\u94fe\u63a5 http://localhost:1090 \u8bbf\u95ee\u8fd9\u4e2a\u8fd0\u884c\u7684\u5bb9\u5668\u3002 \u5bf9\u6211\u4eec\u521a\u521a\u521b\u5efa\u7684\u65b0\u7684golang\u955c\u50cf\u8fdb\u884c\u6807\u7b7e\uff0c\u5e76\u4e14\u4e0a\u4f20\u5230Dockerhub\u3002 docker tag lizard/golang:my1 /golang_0001:v1 docker push /golang_0001:v1","title":"\u591a\u9636\u6bb5Dockerfile"},{"location":"k8s/cka_cn/foundamentals/healthcheck/","text":"CKA\u81ea\u5b66\u7b14\u8bb026:\u5065\u5eb7\u68c0\u67e5 \u00b6 Pod\u548cContainer\u7684\u72b6\u6001 \u00b6 \u6f14\u793a\u573a\u666f\uff1a \u521b\u5efa\u4e00\u4e2a\u67092\u4e2a\u5bb9\u5668\u7684pod\u3002 \u6f14\u793a\uff1a \u521b\u5efa\u4e00\u4e2a\u5305\u542b\u4e24\u4e2a\u5bb9\u5668 nginx \u548c busybox \u7684 Pod\uff0c\u547d\u540d\u4e3a multi-pods \u3002 kubectl apply -f - << EOF apiVersion: v1 kind: Pod metadata: labels: run: multi-pods name: multi-pods spec: containers: - image: nginx name: nginx - image: busybox name: busybox dnsPolicy: ClusterFirst restartPolicy: Always EOF \u6267\u884c\u4e0b\u9762\u547d\u4ee4\u6765\u76d1\u63a7\u72b6\u6001\uff0c\u4f7f\u7528\u9009\u9879 --watch \u3002 \u6ce8\u610f\uff0cpod\u7684\u72b6\u6001\u5df2\u7ecf\u4ece ContainerCreating \u53d8\u4e3a NotReady \uff0c\u518d\u53d8\u4e3a CrashLoopBackOff \u3002 kubectl get pod multi-pods --watch \u83b7\u53d6 Pod multi-pods \u7684\u8be6\u7ec6\u4fe1\u606f\uff0c\u5173\u6ce8 Containers \u90e8\u5206\u4e0b\u7684\u5bb9\u5668\u72b6\u6001\u548c Conditions \u90e8\u5206\u4e0b\u7684 Pod \u72b6\u6001\u3002 kubectl describe pod multi-pods \u8fd0\u884c\u7ed3\u679c\uff08\u90e8\u5206\uff09\uff1a ...... Containers : nginx : ...... State : Running Started : Sat, 23 Jul 2022 15:06:56 +0800 Ready : True Restart Count : 0 ...... busybox : ...... State : Terminated Reason : Completed Exit Code : 0 ...... Conditions : Type Status Initialized True Ready False ContainersReady False PodScheduled True ...... LivenessProbe \u00b6 \u6f14\u793a\u573a\u666f\uff1a \u521b\u5efa\u4e00\u4e2apod\uff0c\u5185\u542b livenessProbe \u68c0\u67e5\u3002 \u6f14\u793a\u7684\u8be6\u7ec6\u8bf4\u660e\u53ef\u4ee5\u67e5\u8be2 Kubernetes document \u3002 \u6f14\u793a\uff1a \u521b\u5efayaml\u6587\u4ef6 liveness.yaml \uff0c\u5e76\u5305\u542b livenessProbe \u914d\u7f6e\uff0c\u5e76\u5e94\u7528\u4e4b\u3002 kubectl apply -f - <> ~/.bashrc source < ( helm completion bash ) \u901a\u8fc7Helm\u5b89\u88c5MySQL \u00b6 \u6dfb\u52a0Bitnami Chartes\u4ed3\u5e93\u3002 helm repo add bitnami https://charts.bitnami.com/bitnami \u67e5\u8be2\u5f53\u524d\u53ef\u7528\u7684Chartes\u4ed3\u5e93\u3002 helm repo list \u8fd0\u884c\u7ed3\u679c\uff1a NAME URL bitnami https://charts.bitnami.com/bitnami \u540c\u6b65\u672c\u5730Charts\u4ed3\u5e93\u3002 helm repo update \u5728Charts\u4ed3\u5e93\u4e2d\u67e5\u627ebitnami Charts\u4ed3\u5e93\u3002 helm search repo bitnami \u5728\u4ed3\u5e93\u4e2d\u641c\u7d22bitnami/mysql Charts\u3002 helm search repo bitnami/mysql \u5728namespace dev \u4e0a\u5b89\u88c5MySQL Chart\u3002 helm install mysql bitnami/mysql -n dev \u8fd0\u884c\u7ed3\u679c\uff1a NAME: mysql LAST DEPLOYED: Sun Jul 24 19:37:20 2022 NAMESPACE: dev STATUS: deployed REVISION: 1 TEST SUITE: None NOTES: CHART NAME: mysql CHART VERSION: 9.2.1 APP VERSION: 8.0.29 ** Please be patient while the chart is being deployed ** Tip: Watch the deployment status using the command: kubectl get pods -w --namespace dev Services: echo Primary: mysql.dev.svc.cluster.local:3306 Execute the following to get the administrator credentials: echo Username: root MYSQL_ROOT_PASSWORD=$(kubectl get secret --namespace dev mysql -o jsonpath=\"{.data.mysql-root-password}\" | base64 -d) To connect to your database: 1. Run a pod that you can use as a client: kubectl run mysql-client --rm --tty -i --restart='Never' --image docker.io/bitnami/mysql:8.0.29-debian-11-r9 --namespace dev --env MYSQL_ROOT_PASSWORD=$MYSQL_ROOT_PASSWORD --command -- bash 2. To connect to primary service (read/write): mysql -h mysql.dev.svc.cluster.local -uroot -p\"$MYSQL_ROOT_PASSWORD\" \u67e5\u770b\u5f53\u524d\u5b89\u88c5\u5305\u7684\u4fe1\u606f\u3002 helm list \u8fd0\u884c\u7ed3\u679c\uff1a NAME NAMESPACE REVISION UPDATED STATUS CHART APP VERSION mysql dev 1 2022-07-24 19:37:20.710988009 +0800 CST deployed mysql-9.2.1 8.0.29 \u68c0\u67e5\u5f53\u524d\u5b89\u88c5\u7684mysql\u7248\u672c\u4fe1\u606f\u3002 helm status mysql \u68c0\u67e5pod mysql \u7684\u72b6\u6001\u3002 kubectl get pod \u8fd0\u884c\u7ed3\u679c\uff1a NAME READY STATUS RESTARTS AGE mysql-0 1/1 Running 0 72s \u90e8\u7f72\u4e00\u4e2aChart \u00b6 \u4e0b\u9762\u6f14\u793a\u4e86\u5982\u4f55\u90e8\u7f72\u4e00\u4e2aChart\u3002 \u6267\u884c\u547d\u4ee4 helm create \u6765\u521d\u59cb\u5316\u4e00\u4e2aChart\u3002 # Naming conventions of Chart: lowercase a~z and -(minus sign) helm create cka-demo \u76ee\u5f55 cka-demo \u4f1a\u88ab\u521b\u5efa\uff0c\u67e5\u770b\u8fd9\u4e2a\u76ee\u5f55\u7684\u7ed3\u6784\u3002 tree cka-demo/ \u8fd0\u884c\u7ed3\u679c\uff1a cka-demo/ \u251c\u2500\u2500 charts \u251c\u2500\u2500 Chart.yaml \u251c\u2500\u2500 templates \u2502 \u251c\u2500\u2500 deployment.yaml \u2502 \u251c\u2500\u2500 _helpers.tpl \u2502 \u251c\u2500\u2500 hpa.yaml \u2502 \u251c\u2500\u2500 ingress.yaml \u2502 \u251c\u2500\u2500 NOTES.txt \u2502 \u251c\u2500\u2500 serviceaccount.yaml \u2502 \u251c\u2500\u2500 service.yaml \u2502 \u2514\u2500\u2500 tests \u2502 \u2514\u2500\u2500 test-connection.yaml \u2514\u2500\u2500 values.yaml \u5220\u9664\u6216\u6e05\u7a7a\u67d0\u4e9b\u6587\u4ef6\uff0c\u6211\u4eec\u4f1a\u5728\u540e\u9762\u91cd\u65b0\u521b\u5efa\u8fd9\u4e9b\u6587\u4ef6\u3002 cd cka-demo rm -rf charts rm -rf templates/tests rm -rf templates/*.yaml echo \"\" > values.yaml echo \"\" > templates/NOTES.txt echo \"\" > templates/_helpers.tpl cd .. \u76ee\u5f55 cka-demo \u7684\u67b6\u6784\u73b0\u5728\u5e94\u8be5\u770b\u8d77\u6765\u7c7b\u4f3c\u4e0b\u9762\u7684\u7ed3\u679c\u3002 tree cka-demo/ \u8fd0\u884c\u7ed3\u679c\uff1a cka-demo/ \u251c\u2500\u2500 Chart.yaml \u251c\u2500\u2500 templates \u2502 \u251c\u2500\u2500 _helpers.tpl \u2502 \u2514\u2500\u2500 NOTES.txt \u2514\u2500\u2500 values.yaml NOTES.txt \u00b6 NOTES.txt \u7528\u4e8e\u5411 Chart \u7528\u6237\u63d0\u4f9b\u6982\u8981\u4fe1\u606f\u3002\u5728\u6f14\u793a\u4e2d\uff0c\u6211\u4eec\u5c06\u4f7f\u7528 NOTES.txt \u63d0\u4f9b\u5173\u4e8e\u7528\u6237\u662f\u5426\u901a\u8fc7 CKA \u8ba4\u8bc1\u7684\u6982\u8981\u4fe1\u606f\u3002 cd cka-demo/ vi templates/NOTES.txt \u6dfb\u52a0\u4e0b\u9762\u7684\u5185\u5bb9\u3002 {{- if .Values.passExam }} Congratulations! You have successfully completed Certified Kubernetes Administrator China Exam (CKA-CN). Your CKA score is: {{ .Values.ckaScore }} Click the link below to view and download your certificate. https://trainingportal.linuxfoundation.org/learn/dashboard {{- else }} Come on! you can do it next time! {{- end }} \u90e8\u7f72\u6a21\u7248 \u00b6 \u4e0b\u9762\u4f1a\u4f7f\u7528 Busybox \u670d\u52a1\u6765\u751f\u6210\u4fe1\u606f\u3002 \u901a\u8fc7\u547d\u4ee4 kubectl create deployment --dry-run=client -oyaml \u751f\u6210 Deployment \u7684 YAML \u6587\u4ef6\uff0c\u5e76\u5c06\u5176\u5185\u5bb9\u5199\u5165\u6587\u4ef6 templates/deployment.yaml \u3002 kubectl create deployment cka-demo-busybox --image = busybox:latest --dry-run = client -oyaml > templates/deployment.yaml \u68c0\u67e5deployment\u7684yaml\u6587\u4ef6 templates/deployment.yaml \u7684\u5185\u5bb9\u3002 cat templates/deployment.yaml \u8fd0\u884c\u7ed3\u679c\uff1a apiVersion : apps/v1 kind : Deployment metadata : creationTimestamp : null labels : app : cka-demo-busybox name : cka-demo-busybox spec : replicas : 1 selector : matchLabels : app : cka-demo-busybox strategy : {} template : metadata : creationTimestamp : null labels : app : cka-demo-busybox spec : containers : - image : busybox:latest name : busybox resources : {} status : {} \u7f16\u8f91\u4fee\u6539\u6587\u4ef6 templates/deployment.yaml \u3002 vi templates/deployment.yaml \u8ba9\u6211\u4eec\u5c06 .spec.replicas \u7684\u503c\u4ece 1 \u66ff\u6362\u4e3a\u53d8\u91cf {{ .Values.replicaCount }} \uff0c\u8fd9\u6837\u6211\u4eec\u53ef\u4ee5\u4e3a\u5176\u4ed6 Deployment \u52a8\u6001\u5206\u914d\u526f\u672c\u6570\u3002 apiVersion : apps/v1 kind : Deployment metadata : creationTimestamp : null labels : app : cka-demo-busybox name : cka-demo-busybox spec : replicas : {{ .Values.replicaCount }} selector : matchLabels : app : cka-demo-busybox strategy : {} template : metadata : creationTimestamp : null labels : app : cka-demo-busybox spec : containers : - image : busybox:latest name : busybox resources : {} status : {} .spec.replicas \u5c06\u5728\u90e8\u7f72\u671f\u95f4\u88ab\u5b9e\u9645\u7684 .Values.replicaCount \u503c\u66ff\u6362\u3002 \u73b0\u5728\u521b\u5efa\u53e6\u4e00\u4e2a\u6587\u4ef6 values.yaml \u5e76\u5728\u6587\u4ef6\u4e2d\u6dfb\u52a0\u4e00\u4e2a\u53d8\u91cf replicaCount \uff0c\u9ed8\u8ba4\u503c\u4e3a1\u3002 \u5f3a\u70c8\u5efa\u8bae\u5728\u6587\u4ef6 values.yaml \u4e2d\u5b9a\u4e49\u7684\u6bcf\u4e2a\u503c\u6dfb\u52a0\u6ce8\u91ca\u3002 vi values.yaml \u8f93\u51fa\u7ed3\u679c\uff1a # Number of deployment replicas replicaCount: 1 \u4e0b\u9762\u5bf9\u6587\u4ef6 templates/deployment.yaml \u6dfb\u52a0\u66f4\u591a\u7684\u53d8\u91cf\u3002 \u5c06 .metadata.name \u7684 Release \u540d\u79f0\u66ff\u6362\u4e3a {{ .Release.Name }} \uff0c\u5e76\u7528\u5728 values.yaml \u6587\u4ef6\u4e2d\u5b9a\u4e49\u7684\u53d8\u91cf\u586b\u5145\u3002 \u5c06\u6807\u7b7e\u540d\u79f0 .metadata.labels \u66ff\u6362\u4e3a {{- include \"cka-demo.labels\" . | nindent 4 }} \uff0c\u5e76\u7528\u5728 _helpers.tpl \u6587\u4ef6\u4e2d\u5b9a\u4e49\u7684\u6807\u7b7e\u540d\u79f0 cka-demo.labels \u586b\u5145\u3002 \u5c06 .spec.replicas \u66ff\u6362\u4e3a {{ .Values.replicaCount }} \uff0c\u5e76\u7528\u5728 values.yaml \u6587\u4ef6\u4e2d\u5b9a\u4e49\u7684\u53d8\u91cf\u586b\u5145\u3002 \u5c06 .spec.selector.matchLabels \u66ff\u6362\u4e3a {{- include \"cka-demo.selectorLabels\" . | nindent 6 }} \u5e76\u4f7f\u7528\u5728 _helpers.tpl \u6587\u4ef6\u4e2d\u5b9a\u4e49\u7684 cka-demo.selectorLabels \u8fdb\u884c\u586b\u5145\u3002 \u5c06 .spec.template.metadata.labels \u66ff\u6362\u4e3a {{- include \"cka-demo.selectorLabels\" . | nindent 8 }} \u5e76\u4f7f\u7528\u5728 _helpers.tpl \u6587\u4ef6\u4e2d\u5b9a\u4e49\u7684 cka-demo.selectorLabels \u8fdb\u884c\u586b\u5145\u3002 \u5c06 .spec.template.spec.containers[0].image \u66ff\u6362\u4e3a {{ .Values.image.repository }} \u548c {{ .Values.image.tag }} \u5e76\u4f7f\u7528\u5728 values.yaml \u6587\u4ef6\u4e2d\u5b9a\u4e49\u7684\u53d8\u91cf\u586b\u5145\u955c\u50cf\u540d\u79f0\u548c\u955c\u50cf\u6807\u7b7e\u3002 \u5c06 .spec.template.spec.containers[0].command \u66ff\u6362\u4e3a\u4e00\u4e2a if-else \u8bed\u53e5\uff0c\u5982\u679c .Values.passExam \u4e3a\u771f\uff0c\u5219\u6267\u884c\u5728 .Values.passCommand \u4e2d\u5b9a\u4e49\u7684\u547d\u4ee4\uff0c\u5426\u5219\u6267\u884c\u5728 .Values.lostCommand \u4e2d\u5b9a\u4e49\u7684\u547d\u4ee4\u3002 \u4f7f\u7528 .spec.template.spec.containers[0].env \u4e2d\u7684 key \u4f5c\u4e3a ConfigMap \u540d\u79f0\u7684\u524d\u7f00\uff0c\u5e76\u4f7f\u7528\u5728 values.yaml \u6587\u4ef6\u4e2d\u5b9a\u4e49\u7684 {{ .Values.studentName }} \u8fdb\u884c\u586b\u5145\u3002 \u5c06 .spec.template.spec.containers[0].resources \u66ff\u6362\u4e3a {{ .Values.resources }} \u5e76\u4f7f\u7528\u5728 values.yaml \u6587\u4ef6\u4e2d\u5b9a\u4e49\u7684\u53d8\u91cf\u8fdb\u884c\u586b\u5145\u3002 .Release.Name \u662f\u5185\u7f6e\u5bf9\u8c61\uff0c\u5728\u6587\u4ef6 values.yaml \u4e2d\u4e0d\u9700\u8981\u6307\u5b9a\u3002\u5b83\u662f\u7531 helm install \u751f\u6210\u7684Release\u3002 \u79fb\u9664\u4e0d\u5fc5\u8981\u7684\u884c\uff0c\u6700\u7ec8\u6587\u4ef6\u770b\u8d77\u6765\u7c7b\u4f3c\u4e0b\u9762\u7684\u7ed3\u679c\uff1a apiVersion : apps/v1 kind : Deployment metadata : name : {{ .Release.Name }} labels : {{ - include \"cka-demo.labels\" . | nindent 4 }} spec : replicas : {{ .Values.replicaCount }} selector : matchLabels : {{ - include \"cka-demo.selectorLabels\" . | nindent 6 }} template : metadata : labels : {{ - include \"cka-demo.selectorLabels\" . | nindent 8 }} spec : containers : - name : id-generator image : \"{{ .Values.image.repository }}:{{ .Values.image.tag }}\" {{ - if .Values.passExam }} {{ - with .Values.passCommand }} command : {{ range . }} - {{ . | quote }} {{ - end }} {{ - end }} {{ - else }} {{ - with .Values.lostCommand }} command : {{ range . }} - {{ . | quote }} {{ - end }} {{ - end }} {{ - end }} env : - name : CKA_SCORE valueFrom : configMapKeyRef : name : {{ .Values.studentName }} -cka-score key : cka_score {{ - with .Values.resources }} resources : {{ - toYaml . | nindent 12 }} {{ - end }} restartPolicy : Always \u66f4\u65b0\u6587\u4ef6 values.yaml \u4e2d\u53d8\u91cf\u7684\u9ed8\u8ba4\u503c\u3002\u5efa\u8bae\u9010\u4e2a\u6dfb\u52a0\u53d8\u91cf\u5e76\u6d4b\u8bd5\uff0c\u4e0d\u8981\u4e00\u6b21\u6dfb\u52a0\u6240\u6709\u53d8\u91cf\u3002 vi values.yaml \u8fd0\u884c\u7ed3\u679c\uff1a # Number of deployment replicas replicaCount: 1 # Image repository and tag image: repository: busybox tag: latest # Container start command passCommand: - '/bin/sh' - '-c' - \"echo Your CKA score is $(CKA_SCORE) and your CKA certificate ID number is $(tr -dc 'A-Za-z0-9' < /dev/urandom | head -c 13; echo) ; sleep 86400\" lostCommand: - '/bin/sh' - '-c' - \"echo Your CKA score is $(CKA_SCORE), Come on! you can do it next time! ; sleep 86400\" # Container resources resources: limits: cpu: 200m memory: 256Mi requests: cpu: 100m memory: 128Mi # Student Name studentName: whoareyou # Student pass CKA exam or not passExam: true ConfigMap\u6a21\u7248 \u00b6 ConfigMap\u88ab\u90e8\u7f72\u4e2d\u7684Deployment\u6240\u5f15\u7528\uff0c\u56e0\u6b64\u6211\u4eec\u9700\u8981\u5b9a\u4e49ConfigMap\u7684\u6a21\u677f\u3002 \u6211\u4eec\u5c06\u628aConfigMap\u7684\u540d\u79f0\u548c cka_score \u7ec4\u5408\u6210\u4e00\u4e2a\u53d8\u91cf\uff0c\u4f8b\u5982 name-cka-score \u3002 vi templates/configmap.yaml \u8fd0\u884c\u7ed3\u679c\uff1a apiVersion : v1 kind : ConfigMap metadata : name : {{ .Values.studentName }} -cka-score labels : {{ - include \"cka-demo.labels\" . | nindent 4 }} data : cka_score : {{ .Values.ckaScore | quote }} studentName \u5df2\u7ecf\u5728 values.yaml \u6587\u4ef6\u4e2d\u5b9a\u4e49\u8fc7\u4e86\uff0c\u6211\u4eec\u53ea\u9700\u8981\u6dfb\u52a0\u4e00\u4e2a\u540d\u4e3a ckaScore \u7684\u53d8\u91cf\u5e76\u7ed9\u5b83\u4e00\u4e2a\u9ed8\u8ba4\u503c\u5373\u53ef\u3002 vi values.yaml \u8fd0\u884c\u7ed3\u679c # Student CKA Score ckaScore: 100 _helpers.tpl \u00b6 \u5b9a\u4e49\u4e00\u4e2a\u901a\u7528\u7684\u6a21\u677f _helpers.tpl \uff0c\u4e3aDeployment\u548cConfigMap\u7684\u6807\u7b7e\u548c\u9009\u62e9\u5668\u6807\u7b7e\u6dfb\u52a0\u6807\u7b7e\u3002 vi templates/_helpers.tpl \u8fd0\u884c\u7ed3\u679c\uff1a {{/* Common labels */}} {{- define \"cka-demo.labels\" -}} {{ include \"cka-demo.selectorLabels\" . }} {{- if .Chart.AppVersion }} app.kubernetes.io/version: {{ .Chart.AppVersion | quote }} {{- end }} app.kubernetes.io/managed-by: {{ .Release.Service }} {{- end -}} {{/* Selector labels */}} {{- define \"cka-demo.selectorLabels\" -}} app: {{ .Chart.Name }} release: {{ .Release.Name }} {{- end -}} Chart.yaml \u00b6 \u8fd9\u91cc\u6211\u4eec\u4f7f\u7528CKA\u7684logo\u6765\u4f5c\u4e3aChart\u7684\u56fe\u6807\u3002 wget https://www.cncf.io/wp-content/uploads/2021/09/kubernetes-cka-color.svg \u7f16\u8f91\u4fee\u6539 Chart.yaml \u6587\u4ef6\u3002 vi Chart.yaml \u628a\u56fe\u6807\u4fe1\u606f\u6dfb\u52a0\u5230Chart.yaml\u6587\u4ef6\u672b\u5c3e\u3002 icon: file://./kubernetes-cka-color.svg \u628a\u4f5c\u8005\u4fe1\u606f\u6dfb\u52a0\u5230Chart.yaml\u6587\u4ef6\u672b\u5c3e\u3002 vi Chart.yaml \u8fd0\u884c\u7ed3\u679c\uff1a maintainers: - name: James.H \u6700\u7ec8\u7684 Chart.yaml \u7c7b\u4f3c\u5982\u4e0b\u5185\u5bb9\u3002\u522b\u5fd8\u8bb0\u66f4\u65b0 appVersion: \"v1.23\" \u4e3a\u5f53\u524dKubernetes\u7684\u7248\u672c\u3002 apiVersion: v2 name: cka-demo description: A Helm chart for CKA demo. type: application version: 0.1.0 appVersion: \"v1.23\" maintainers: - name: James.H icon: file://./kubernetes-cka-color.svg Chart Debug \u00b6 \u4f7f\u7528 helm lint \u6765\u9a8c\u8bc1\u4e0a\u8ff0\u53d8\u66f4\u3002 helm lint \u8fd0\u884c\u7ed3\u679c\uff1a 1 chart(s) linted, 0 chart(s) failed helm lint \u53ea\u68c0\u67e5Chart\u7684\u683c\u5f0f\uff0c\u4e0d\u68c0\u67e5Manifest\u6587\u4ef6\u3002 \u6211\u4eec\u53ef\u4ee5\u4f7f\u7528 helm install --debug --dry-run \u6216 helm template \u547d\u4ee4\u6765\u68c0\u67e5\u751f\u6210\u7684 Manifest \u662f\u5426\u6b63\u786e\u3002 helm template cka-demo ./ \u901a\u8fc7\u547d\u4ee4 helm install --debug --dry-run \u6765\u6a21\u62df\u5b89\u88c5\u3002\u6211\u4eec\u53ef\u4ee5\u4ece\u4e24\u4e2a\u4e0d\u540c\u7684\u9009\u9879\uff08\u901a\u8fc7\u6216\u672a\u901a\u8fc7CKA\u8ba4\u8bc1\uff09\u4e2d\u83b7\u5f97\u9884\u671f\u7684\u7ed3\u679c\u3002 helm install --debug --dry-run cka-demo ./ --create-namespace \\ -n cka \\ --set studentName = kubernetes \\ --set ckaScore = 99 \\ --set passExam = true helm install --debug --dry-run cka-demo ./ --create-namespace \\ -n cka \\ --set studentName = kubernetes \\ --set ckaScore = 0 \\ --set passExam = false \u628a Chart \u6253\u5305\u6210 .tgz \u6587\u4ef6\uff0c\u5e76\u4e0a\u4f20\u5230\u4ed3\u5e93\uff0c\u4f8b\u5982 Chart Museum \u6216\u8005 OCI Repo\u3002 cd ../ helm package cka-demo \u8fd0\u884c\u7ed3\u679c\uff1a Successfully packaged chart and saved it to: /root/cka-demo-0.1.0.tgz \u81f3\u6b64\uff0c\u6211\u4eec\u5df2\u7ecf\u5b8c\u6210\u4e86\u914d\u7f6e\u4e00\u4e2a\u65b0\u7684Chart\uff0c\u73b0\u5728\u5f00\u59cb\u5b89\u88c5\u8fd9\u4e2aChart\u3002 helm install cka-demo cka-demo-0.1.0.tgz --create-namespace \\ -n cka \\ --set studentName = kubernetes \\ --set ckaScore = 0 \\ --set passExam = false \u8fd0\u884c\u7ed3\u679c\uff1a NAME: cka-demo LAST DEPLOYED: Sun Jul 24 19:58:36 2022 NAMESPACE: cka STATUS: deployed REVISION: 1 TEST SUITE: None NOTES: Come on! you can do it next time! \u68c0\u67e5\u90e8\u7f72\u60c5\u51b5\uff1a helm list --all-namespaces \u8fd0\u884c\u7ed3\u679c\uff1a NAME NAMESPACE REVISION UPDATED STATUS CHART APP VERSION cka-demo cka 1 2022-07-24 19:58:36.272093383 +0800 CST deployed cka-demo-0.1.0 v1.23 mysql dev 1 2022-07-24 19:37:20.710988009 +0800 CST deployed mysql-9.2.1 8.0.29 \u5982\u679c\u9047\u5230\u9519\u8bef\uff0c\u5219\u9700\u8981\u5378\u8f7d cka-demo \u5e76\u91cd\u65b0\u5b89\u88c5\u5b83\u3002 helm uninstall cka-demo -n \u68c0\u67e5 cka-demo \u7684\u65e5\u5fd7\u3002 kubectl logs -n cka -l app = cka-demo \u8fd0\u884c\u7ed3\u679c Your CKA score is 0, Come on! you can do it next time! \u901a\u8fc7\u5176\u4ed6\u9009\u9879\u5b89\u88c5 cka-demo \u3002 helm uninstall cka-demo -n cka helm install cka-demo cka-demo-0.1.0.tgz --create-namespace \\ -n cka \\ --set studentName = kubernetes \\ --set ckaScore = 100 \\ --set passExam = true \u8fd0\u884c\u7ed3\u679c\uff1a NAME: cka-demo LAST DEPLOYED: Sun Jul 24 20:01:34 2022 NAMESPACE: cka STATUS: deployed REVISION: 1 TEST SUITE: None NOTES: Congratulations! You have successfully completed Certified Kubernetes Administrator China Exam (CKA-CN). Your CKA score is: 100 Click the link below to view and download your certificate. https://trainingportal.linuxfoundation.org/learn/dashboard \u68c0\u67e5 cka-demo \u7684\u65e5\u5fd7\u3002 kubectl logs -n cka -l app = cka-demo \u8fd0\u884c\u7ed3\u679c\uff1a Your CKA score is 100 and your CKA certificate ID number is BQKoVYVhjzl3G Built-in Objects\u5217\u8868 Release.Name # \u53d1\u5e03\u540d\u79f0 Release.Namespace # \u53d1\u5e03Namespace Release.Service # \u6e32\u67d3\u6a21\u677f\u7684\u670d\u52a1\uff0c\u5728Helm\u4e2d\u9ed8\u8ba4\u503c\u4e3a\"Helm\" Release.IsUpgrade # \u5982\u679c\u5f53\u524d\u662f\u5347\u7ea7\u6216\u56de\u6eda\uff0c\u8bbe\u7f6e\u4e3atrue Release.IsInstall # \u5982\u679c\u5f53\u524d\u662f\u5b89\u88c5\uff0c\u8bbe\u7f6e\u4e3atrue Release.Revision # \u53d1\u5e03\u7248\u672c\u53f7 Values # \u4ecevalues.yaml\u548c--set\u4f20\u5165\uff0c\u9ed8\u8ba4\u4e3a\u7a7a Chart # \u6240\u6709Chart.yaml\u4e2d\u7684\u5185\u5bb9 Chart.Version # Chart.Maintainers # Files # \u5728chart\u4e2d\u8bbf\u95ee\u975e\u7279\u6b8a\u6587\u4ef6 Capabilities # \u63d0\u4f9b\u5173\u4e8e\u652f\u6301\u80fd\u529b\u7684\u4fe1\u606f\uff08K8s API\u7248\u672c\u3001K8s\u7248\u672c\u3001Helm\u7248\u672c\uff09 Capabilities.KubeVersion # Kubernetes\u7684\u7248\u672c\u53f7 Capabilities.APIVersions.Has \"batch/v1\" # K8s API\u7248\u672c\u5305\u542b\"batch/v1\" Template # \u5f53\u524d\u6a21\u677f\u4fe1\u606f Template.Name # \u5f53\u524d\u6a21\u677f\u6587\u4ef6\u8def\u5f84 Template.BasePath # \u5f53\u524d\u6a21\u677f\u76ee\u5f55\u8def\u5f84 \u53c2\u8003\uff1a Helm \u5b98\u7f51 Helm \u7248\u672c\u652f\u6301\u7b56\u7565 Helm Chart \u8d44\u6e90\u5bf9\u8c61\u5b89\u88c5\u987a\u5e8f","title":"Helm Chart"},{"location":"k8s/cka_cn/foundamentals/helming/#cka27helm-chart","text":"","title":"CKA\u81ea\u5b66\u7b14\u8bb027:Helm Chart"},{"location":"k8s/cka_cn/foundamentals/helming/#helm","text":"\u5728\u8282\u70b9 cka001 \u4e0a\u5b89\u88c5Helm\u3002 # https://github.com/helm/helm/releases wget https://get.helm.sh/helm-v3.8.2-linux-amd64.tar.gz tar -zxvf helm-v3.8.2-linux-amd64.tar.gz cp linux-amd64/helm /usr/bin/ rm -rf linux-amd64 helm-v3.8.2-linux-amd64.tar.gz \u6216\u8005\u4ece\u94fe\u63a5 https://get.helm.sh/helm-v3.8.2-linux-amd64.tar.gz \u624b\u5de5\u4e0b\u8f7d\u5b89\u88c5\u5305\uff0c\u5e76\u62f7\u8d1d\u5230\u8282\u70b9 cka001 \u4e0a\u3002 scp -i cka-key-pair.pem ./Package/helm-v3.8.2-linux-amd64.tar.gz root@cka001:/root/ ssh -i cka-key-pair.pem root@cka001 tar -zxvf helm-v3.8.2-linux-amd64.tar.gz cp linux-amd64/helm /usr/bin/ rm -rf linux-amd64 helm-v3.8.2-linux-amd64.tar.gz","title":"\u5b89\u88c5Helm"},{"location":"k8s/cka_cn/foundamentals/helming/#helm_1","text":"\u68c0\u67e5 helm \u7684\u7248\u672c\u3002 helm version \u8fd0\u884c\u7ed3\u679c\uff1a version.BuildInfo{Version:\"v3.8.2\", GitCommit:\"6e3701edea09e5d55a8ca2aae03a68917630e91b\", GitTreeState:\"clean\", GoVersion:\"go1.17.5\"} \u83b7\u53d6 helm \u7684\u5e2e\u52a9\u4fe1\u606f\u3002 helm help \u914d\u7f6e helm \u7684\u547d\u4ee4\u81ea\u52a8\u8865\u5168\u529f\u80fd\u3002 echo \"source <(helm completion bash)\" >> ~/.bashrc source < ( helm completion bash )","title":"Helm\u7528\u6cd5"},{"location":"k8s/cka_cn/foundamentals/helming/#helmmysql","text":"\u6dfb\u52a0Bitnami Chartes\u4ed3\u5e93\u3002 helm repo add bitnami https://charts.bitnami.com/bitnami \u67e5\u8be2\u5f53\u524d\u53ef\u7528\u7684Chartes\u4ed3\u5e93\u3002 helm repo list \u8fd0\u884c\u7ed3\u679c\uff1a NAME URL bitnami https://charts.bitnami.com/bitnami \u540c\u6b65\u672c\u5730Charts\u4ed3\u5e93\u3002 helm repo update \u5728Charts\u4ed3\u5e93\u4e2d\u67e5\u627ebitnami Charts\u4ed3\u5e93\u3002 helm search repo bitnami \u5728\u4ed3\u5e93\u4e2d\u641c\u7d22bitnami/mysql Charts\u3002 helm search repo bitnami/mysql \u5728namespace dev \u4e0a\u5b89\u88c5MySQL Chart\u3002 helm install mysql bitnami/mysql -n dev \u8fd0\u884c\u7ed3\u679c\uff1a NAME: mysql LAST DEPLOYED: Sun Jul 24 19:37:20 2022 NAMESPACE: dev STATUS: deployed REVISION: 1 TEST SUITE: None NOTES: CHART NAME: mysql CHART VERSION: 9.2.1 APP VERSION: 8.0.29 ** Please be patient while the chart is being deployed ** Tip: Watch the deployment status using the command: kubectl get pods -w --namespace dev Services: echo Primary: mysql.dev.svc.cluster.local:3306 Execute the following to get the administrator credentials: echo Username: root MYSQL_ROOT_PASSWORD=$(kubectl get secret --namespace dev mysql -o jsonpath=\"{.data.mysql-root-password}\" | base64 -d) To connect to your database: 1. Run a pod that you can use as a client: kubectl run mysql-client --rm --tty -i --restart='Never' --image docker.io/bitnami/mysql:8.0.29-debian-11-r9 --namespace dev --env MYSQL_ROOT_PASSWORD=$MYSQL_ROOT_PASSWORD --command -- bash 2. To connect to primary service (read/write): mysql -h mysql.dev.svc.cluster.local -uroot -p\"$MYSQL_ROOT_PASSWORD\" \u67e5\u770b\u5f53\u524d\u5b89\u88c5\u5305\u7684\u4fe1\u606f\u3002 helm list \u8fd0\u884c\u7ed3\u679c\uff1a NAME NAMESPACE REVISION UPDATED STATUS CHART APP VERSION mysql dev 1 2022-07-24 19:37:20.710988009 +0800 CST deployed mysql-9.2.1 8.0.29 \u68c0\u67e5\u5f53\u524d\u5b89\u88c5\u7684mysql\u7248\u672c\u4fe1\u606f\u3002 helm status mysql \u68c0\u67e5pod mysql \u7684\u72b6\u6001\u3002 kubectl get pod \u8fd0\u884c\u7ed3\u679c\uff1a NAME READY STATUS RESTARTS AGE mysql-0 1/1 Running 0 72s","title":"\u901a\u8fc7Helm\u5b89\u88c5MySQL"},{"location":"k8s/cka_cn/foundamentals/helming/#chart","text":"\u4e0b\u9762\u6f14\u793a\u4e86\u5982\u4f55\u90e8\u7f72\u4e00\u4e2aChart\u3002 \u6267\u884c\u547d\u4ee4 helm create \u6765\u521d\u59cb\u5316\u4e00\u4e2aChart\u3002 # Naming conventions of Chart: lowercase a~z and -(minus sign) helm create cka-demo \u76ee\u5f55 cka-demo \u4f1a\u88ab\u521b\u5efa\uff0c\u67e5\u770b\u8fd9\u4e2a\u76ee\u5f55\u7684\u7ed3\u6784\u3002 tree cka-demo/ \u8fd0\u884c\u7ed3\u679c\uff1a cka-demo/ \u251c\u2500\u2500 charts \u251c\u2500\u2500 Chart.yaml \u251c\u2500\u2500 templates \u2502 \u251c\u2500\u2500 deployment.yaml \u2502 \u251c\u2500\u2500 _helpers.tpl \u2502 \u251c\u2500\u2500 hpa.yaml \u2502 \u251c\u2500\u2500 ingress.yaml \u2502 \u251c\u2500\u2500 NOTES.txt \u2502 \u251c\u2500\u2500 serviceaccount.yaml \u2502 \u251c\u2500\u2500 service.yaml \u2502 \u2514\u2500\u2500 tests \u2502 \u2514\u2500\u2500 test-connection.yaml \u2514\u2500\u2500 values.yaml \u5220\u9664\u6216\u6e05\u7a7a\u67d0\u4e9b\u6587\u4ef6\uff0c\u6211\u4eec\u4f1a\u5728\u540e\u9762\u91cd\u65b0\u521b\u5efa\u8fd9\u4e9b\u6587\u4ef6\u3002 cd cka-demo rm -rf charts rm -rf templates/tests rm -rf templates/*.yaml echo \"\" > values.yaml echo \"\" > templates/NOTES.txt echo \"\" > templates/_helpers.tpl cd .. \u76ee\u5f55 cka-demo \u7684\u67b6\u6784\u73b0\u5728\u5e94\u8be5\u770b\u8d77\u6765\u7c7b\u4f3c\u4e0b\u9762\u7684\u7ed3\u679c\u3002 tree cka-demo/ \u8fd0\u884c\u7ed3\u679c\uff1a cka-demo/ \u251c\u2500\u2500 Chart.yaml \u251c\u2500\u2500 templates \u2502 \u251c\u2500\u2500 _helpers.tpl \u2502 \u2514\u2500\u2500 NOTES.txt \u2514\u2500\u2500 values.yaml","title":"\u90e8\u7f72\u4e00\u4e2aChart"},{"location":"k8s/cka_cn/foundamentals/helming/#notestxt","text":"NOTES.txt \u7528\u4e8e\u5411 Chart \u7528\u6237\u63d0\u4f9b\u6982\u8981\u4fe1\u606f\u3002\u5728\u6f14\u793a\u4e2d\uff0c\u6211\u4eec\u5c06\u4f7f\u7528 NOTES.txt \u63d0\u4f9b\u5173\u4e8e\u7528\u6237\u662f\u5426\u901a\u8fc7 CKA \u8ba4\u8bc1\u7684\u6982\u8981\u4fe1\u606f\u3002 cd cka-demo/ vi templates/NOTES.txt \u6dfb\u52a0\u4e0b\u9762\u7684\u5185\u5bb9\u3002 {{- if .Values.passExam }} Congratulations! You have successfully completed Certified Kubernetes Administrator China Exam (CKA-CN). Your CKA score is: {{ .Values.ckaScore }} Click the link below to view and download your certificate. https://trainingportal.linuxfoundation.org/learn/dashboard {{- else }} Come on! you can do it next time! {{- end }}","title":"NOTES.txt"},{"location":"k8s/cka_cn/foundamentals/helming/#_1","text":"\u4e0b\u9762\u4f1a\u4f7f\u7528 Busybox \u670d\u52a1\u6765\u751f\u6210\u4fe1\u606f\u3002 \u901a\u8fc7\u547d\u4ee4 kubectl create deployment --dry-run=client -oyaml \u751f\u6210 Deployment \u7684 YAML \u6587\u4ef6\uff0c\u5e76\u5c06\u5176\u5185\u5bb9\u5199\u5165\u6587\u4ef6 templates/deployment.yaml \u3002 kubectl create deployment cka-demo-busybox --image = busybox:latest --dry-run = client -oyaml > templates/deployment.yaml \u68c0\u67e5deployment\u7684yaml\u6587\u4ef6 templates/deployment.yaml \u7684\u5185\u5bb9\u3002 cat templates/deployment.yaml \u8fd0\u884c\u7ed3\u679c\uff1a apiVersion : apps/v1 kind : Deployment metadata : creationTimestamp : null labels : app : cka-demo-busybox name : cka-demo-busybox spec : replicas : 1 selector : matchLabels : app : cka-demo-busybox strategy : {} template : metadata : creationTimestamp : null labels : app : cka-demo-busybox spec : containers : - image : busybox:latest name : busybox resources : {} status : {} \u7f16\u8f91\u4fee\u6539\u6587\u4ef6 templates/deployment.yaml \u3002 vi templates/deployment.yaml \u8ba9\u6211\u4eec\u5c06 .spec.replicas \u7684\u503c\u4ece 1 \u66ff\u6362\u4e3a\u53d8\u91cf {{ .Values.replicaCount }} \uff0c\u8fd9\u6837\u6211\u4eec\u53ef\u4ee5\u4e3a\u5176\u4ed6 Deployment \u52a8\u6001\u5206\u914d\u526f\u672c\u6570\u3002 apiVersion : apps/v1 kind : Deployment metadata : creationTimestamp : null labels : app : cka-demo-busybox name : cka-demo-busybox spec : replicas : {{ .Values.replicaCount }} selector : matchLabels : app : cka-demo-busybox strategy : {} template : metadata : creationTimestamp : null labels : app : cka-demo-busybox spec : containers : - image : busybox:latest name : busybox resources : {} status : {} .spec.replicas \u5c06\u5728\u90e8\u7f72\u671f\u95f4\u88ab\u5b9e\u9645\u7684 .Values.replicaCount \u503c\u66ff\u6362\u3002 \u73b0\u5728\u521b\u5efa\u53e6\u4e00\u4e2a\u6587\u4ef6 values.yaml \u5e76\u5728\u6587\u4ef6\u4e2d\u6dfb\u52a0\u4e00\u4e2a\u53d8\u91cf replicaCount \uff0c\u9ed8\u8ba4\u503c\u4e3a1\u3002 \u5f3a\u70c8\u5efa\u8bae\u5728\u6587\u4ef6 values.yaml \u4e2d\u5b9a\u4e49\u7684\u6bcf\u4e2a\u503c\u6dfb\u52a0\u6ce8\u91ca\u3002 vi values.yaml \u8f93\u51fa\u7ed3\u679c\uff1a # Number of deployment replicas replicaCount: 1 \u4e0b\u9762\u5bf9\u6587\u4ef6 templates/deployment.yaml \u6dfb\u52a0\u66f4\u591a\u7684\u53d8\u91cf\u3002 \u5c06 .metadata.name \u7684 Release \u540d\u79f0\u66ff\u6362\u4e3a {{ .Release.Name }} \uff0c\u5e76\u7528\u5728 values.yaml \u6587\u4ef6\u4e2d\u5b9a\u4e49\u7684\u53d8\u91cf\u586b\u5145\u3002 \u5c06\u6807\u7b7e\u540d\u79f0 .metadata.labels \u66ff\u6362\u4e3a {{- include \"cka-demo.labels\" . | nindent 4 }} \uff0c\u5e76\u7528\u5728 _helpers.tpl \u6587\u4ef6\u4e2d\u5b9a\u4e49\u7684\u6807\u7b7e\u540d\u79f0 cka-demo.labels \u586b\u5145\u3002 \u5c06 .spec.replicas \u66ff\u6362\u4e3a {{ .Values.replicaCount }} \uff0c\u5e76\u7528\u5728 values.yaml \u6587\u4ef6\u4e2d\u5b9a\u4e49\u7684\u53d8\u91cf\u586b\u5145\u3002 \u5c06 .spec.selector.matchLabels \u66ff\u6362\u4e3a {{- include \"cka-demo.selectorLabels\" . | nindent 6 }} \u5e76\u4f7f\u7528\u5728 _helpers.tpl \u6587\u4ef6\u4e2d\u5b9a\u4e49\u7684 cka-demo.selectorLabels \u8fdb\u884c\u586b\u5145\u3002 \u5c06 .spec.template.metadata.labels \u66ff\u6362\u4e3a {{- include \"cka-demo.selectorLabels\" . | nindent 8 }} \u5e76\u4f7f\u7528\u5728 _helpers.tpl \u6587\u4ef6\u4e2d\u5b9a\u4e49\u7684 cka-demo.selectorLabels \u8fdb\u884c\u586b\u5145\u3002 \u5c06 .spec.template.spec.containers[0].image \u66ff\u6362\u4e3a {{ .Values.image.repository }} \u548c {{ .Values.image.tag }} \u5e76\u4f7f\u7528\u5728 values.yaml \u6587\u4ef6\u4e2d\u5b9a\u4e49\u7684\u53d8\u91cf\u586b\u5145\u955c\u50cf\u540d\u79f0\u548c\u955c\u50cf\u6807\u7b7e\u3002 \u5c06 .spec.template.spec.containers[0].command \u66ff\u6362\u4e3a\u4e00\u4e2a if-else \u8bed\u53e5\uff0c\u5982\u679c .Values.passExam \u4e3a\u771f\uff0c\u5219\u6267\u884c\u5728 .Values.passCommand \u4e2d\u5b9a\u4e49\u7684\u547d\u4ee4\uff0c\u5426\u5219\u6267\u884c\u5728 .Values.lostCommand \u4e2d\u5b9a\u4e49\u7684\u547d\u4ee4\u3002 \u4f7f\u7528 .spec.template.spec.containers[0].env \u4e2d\u7684 key \u4f5c\u4e3a ConfigMap \u540d\u79f0\u7684\u524d\u7f00\uff0c\u5e76\u4f7f\u7528\u5728 values.yaml \u6587\u4ef6\u4e2d\u5b9a\u4e49\u7684 {{ .Values.studentName }} \u8fdb\u884c\u586b\u5145\u3002 \u5c06 .spec.template.spec.containers[0].resources \u66ff\u6362\u4e3a {{ .Values.resources }} \u5e76\u4f7f\u7528\u5728 values.yaml \u6587\u4ef6\u4e2d\u5b9a\u4e49\u7684\u53d8\u91cf\u8fdb\u884c\u586b\u5145\u3002 .Release.Name \u662f\u5185\u7f6e\u5bf9\u8c61\uff0c\u5728\u6587\u4ef6 values.yaml \u4e2d\u4e0d\u9700\u8981\u6307\u5b9a\u3002\u5b83\u662f\u7531 helm install \u751f\u6210\u7684Release\u3002 \u79fb\u9664\u4e0d\u5fc5\u8981\u7684\u884c\uff0c\u6700\u7ec8\u6587\u4ef6\u770b\u8d77\u6765\u7c7b\u4f3c\u4e0b\u9762\u7684\u7ed3\u679c\uff1a apiVersion : apps/v1 kind : Deployment metadata : name : {{ .Release.Name }} labels : {{ - include \"cka-demo.labels\" . | nindent 4 }} spec : replicas : {{ .Values.replicaCount }} selector : matchLabels : {{ - include \"cka-demo.selectorLabels\" . | nindent 6 }} template : metadata : labels : {{ - include \"cka-demo.selectorLabels\" . | nindent 8 }} spec : containers : - name : id-generator image : \"{{ .Values.image.repository }}:{{ .Values.image.tag }}\" {{ - if .Values.passExam }} {{ - with .Values.passCommand }} command : {{ range . }} - {{ . | quote }} {{ - end }} {{ - end }} {{ - else }} {{ - with .Values.lostCommand }} command : {{ range . }} - {{ . | quote }} {{ - end }} {{ - end }} {{ - end }} env : - name : CKA_SCORE valueFrom : configMapKeyRef : name : {{ .Values.studentName }} -cka-score key : cka_score {{ - with .Values.resources }} resources : {{ - toYaml . | nindent 12 }} {{ - end }} restartPolicy : Always \u66f4\u65b0\u6587\u4ef6 values.yaml \u4e2d\u53d8\u91cf\u7684\u9ed8\u8ba4\u503c\u3002\u5efa\u8bae\u9010\u4e2a\u6dfb\u52a0\u53d8\u91cf\u5e76\u6d4b\u8bd5\uff0c\u4e0d\u8981\u4e00\u6b21\u6dfb\u52a0\u6240\u6709\u53d8\u91cf\u3002 vi values.yaml \u8fd0\u884c\u7ed3\u679c\uff1a # Number of deployment replicas replicaCount: 1 # Image repository and tag image: repository: busybox tag: latest # Container start command passCommand: - '/bin/sh' - '-c' - \"echo Your CKA score is $(CKA_SCORE) and your CKA certificate ID number is $(tr -dc 'A-Za-z0-9' < /dev/urandom | head -c 13; echo) ; sleep 86400\" lostCommand: - '/bin/sh' - '-c' - \"echo Your CKA score is $(CKA_SCORE), Come on! you can do it next time! ; sleep 86400\" # Container resources resources: limits: cpu: 200m memory: 256Mi requests: cpu: 100m memory: 128Mi # Student Name studentName: whoareyou # Student pass CKA exam or not passExam: true","title":"\u90e8\u7f72\u6a21\u7248"},{"location":"k8s/cka_cn/foundamentals/helming/#configmap","text":"ConfigMap\u88ab\u90e8\u7f72\u4e2d\u7684Deployment\u6240\u5f15\u7528\uff0c\u56e0\u6b64\u6211\u4eec\u9700\u8981\u5b9a\u4e49ConfigMap\u7684\u6a21\u677f\u3002 \u6211\u4eec\u5c06\u628aConfigMap\u7684\u540d\u79f0\u548c cka_score \u7ec4\u5408\u6210\u4e00\u4e2a\u53d8\u91cf\uff0c\u4f8b\u5982 name-cka-score \u3002 vi templates/configmap.yaml \u8fd0\u884c\u7ed3\u679c\uff1a apiVersion : v1 kind : ConfigMap metadata : name : {{ .Values.studentName }} -cka-score labels : {{ - include \"cka-demo.labels\" . | nindent 4 }} data : cka_score : {{ .Values.ckaScore | quote }} studentName \u5df2\u7ecf\u5728 values.yaml \u6587\u4ef6\u4e2d\u5b9a\u4e49\u8fc7\u4e86\uff0c\u6211\u4eec\u53ea\u9700\u8981\u6dfb\u52a0\u4e00\u4e2a\u540d\u4e3a ckaScore \u7684\u53d8\u91cf\u5e76\u7ed9\u5b83\u4e00\u4e2a\u9ed8\u8ba4\u503c\u5373\u53ef\u3002 vi values.yaml \u8fd0\u884c\u7ed3\u679c # Student CKA Score ckaScore: 100","title":"ConfigMap\u6a21\u7248"},{"location":"k8s/cka_cn/foundamentals/helming/#_helperstpl","text":"\u5b9a\u4e49\u4e00\u4e2a\u901a\u7528\u7684\u6a21\u677f _helpers.tpl \uff0c\u4e3aDeployment\u548cConfigMap\u7684\u6807\u7b7e\u548c\u9009\u62e9\u5668\u6807\u7b7e\u6dfb\u52a0\u6807\u7b7e\u3002 vi templates/_helpers.tpl \u8fd0\u884c\u7ed3\u679c\uff1a {{/* Common labels */}} {{- define \"cka-demo.labels\" -}} {{ include \"cka-demo.selectorLabels\" . }} {{- if .Chart.AppVersion }} app.kubernetes.io/version: {{ .Chart.AppVersion | quote }} {{- end }} app.kubernetes.io/managed-by: {{ .Release.Service }} {{- end -}} {{/* Selector labels */}} {{- define \"cka-demo.selectorLabels\" -}} app: {{ .Chart.Name }} release: {{ .Release.Name }} {{- end -}}","title":"_helpers.tpl"},{"location":"k8s/cka_cn/foundamentals/helming/#chartyaml","text":"\u8fd9\u91cc\u6211\u4eec\u4f7f\u7528CKA\u7684logo\u6765\u4f5c\u4e3aChart\u7684\u56fe\u6807\u3002 wget https://www.cncf.io/wp-content/uploads/2021/09/kubernetes-cka-color.svg \u7f16\u8f91\u4fee\u6539 Chart.yaml \u6587\u4ef6\u3002 vi Chart.yaml \u628a\u56fe\u6807\u4fe1\u606f\u6dfb\u52a0\u5230Chart.yaml\u6587\u4ef6\u672b\u5c3e\u3002 icon: file://./kubernetes-cka-color.svg \u628a\u4f5c\u8005\u4fe1\u606f\u6dfb\u52a0\u5230Chart.yaml\u6587\u4ef6\u672b\u5c3e\u3002 vi Chart.yaml \u8fd0\u884c\u7ed3\u679c\uff1a maintainers: - name: James.H \u6700\u7ec8\u7684 Chart.yaml \u7c7b\u4f3c\u5982\u4e0b\u5185\u5bb9\u3002\u522b\u5fd8\u8bb0\u66f4\u65b0 appVersion: \"v1.23\" \u4e3a\u5f53\u524dKubernetes\u7684\u7248\u672c\u3002 apiVersion: v2 name: cka-demo description: A Helm chart for CKA demo. type: application version: 0.1.0 appVersion: \"v1.23\" maintainers: - name: James.H icon: file://./kubernetes-cka-color.svg","title":"Chart.yaml"},{"location":"k8s/cka_cn/foundamentals/helming/#chart-debug","text":"\u4f7f\u7528 helm lint \u6765\u9a8c\u8bc1\u4e0a\u8ff0\u53d8\u66f4\u3002 helm lint \u8fd0\u884c\u7ed3\u679c\uff1a 1 chart(s) linted, 0 chart(s) failed helm lint \u53ea\u68c0\u67e5Chart\u7684\u683c\u5f0f\uff0c\u4e0d\u68c0\u67e5Manifest\u6587\u4ef6\u3002 \u6211\u4eec\u53ef\u4ee5\u4f7f\u7528 helm install --debug --dry-run \u6216 helm template \u547d\u4ee4\u6765\u68c0\u67e5\u751f\u6210\u7684 Manifest \u662f\u5426\u6b63\u786e\u3002 helm template cka-demo ./ \u901a\u8fc7\u547d\u4ee4 helm install --debug --dry-run \u6765\u6a21\u62df\u5b89\u88c5\u3002\u6211\u4eec\u53ef\u4ee5\u4ece\u4e24\u4e2a\u4e0d\u540c\u7684\u9009\u9879\uff08\u901a\u8fc7\u6216\u672a\u901a\u8fc7CKA\u8ba4\u8bc1\uff09\u4e2d\u83b7\u5f97\u9884\u671f\u7684\u7ed3\u679c\u3002 helm install --debug --dry-run cka-demo ./ --create-namespace \\ -n cka \\ --set studentName = kubernetes \\ --set ckaScore = 99 \\ --set passExam = true helm install --debug --dry-run cka-demo ./ --create-namespace \\ -n cka \\ --set studentName = kubernetes \\ --set ckaScore = 0 \\ --set passExam = false \u628a Chart \u6253\u5305\u6210 .tgz \u6587\u4ef6\uff0c\u5e76\u4e0a\u4f20\u5230\u4ed3\u5e93\uff0c\u4f8b\u5982 Chart Museum \u6216\u8005 OCI Repo\u3002 cd ../ helm package cka-demo \u8fd0\u884c\u7ed3\u679c\uff1a Successfully packaged chart and saved it to: /root/cka-demo-0.1.0.tgz \u81f3\u6b64\uff0c\u6211\u4eec\u5df2\u7ecf\u5b8c\u6210\u4e86\u914d\u7f6e\u4e00\u4e2a\u65b0\u7684Chart\uff0c\u73b0\u5728\u5f00\u59cb\u5b89\u88c5\u8fd9\u4e2aChart\u3002 helm install cka-demo cka-demo-0.1.0.tgz --create-namespace \\ -n cka \\ --set studentName = kubernetes \\ --set ckaScore = 0 \\ --set passExam = false \u8fd0\u884c\u7ed3\u679c\uff1a NAME: cka-demo LAST DEPLOYED: Sun Jul 24 19:58:36 2022 NAMESPACE: cka STATUS: deployed REVISION: 1 TEST SUITE: None NOTES: Come on! you can do it next time! \u68c0\u67e5\u90e8\u7f72\u60c5\u51b5\uff1a helm list --all-namespaces \u8fd0\u884c\u7ed3\u679c\uff1a NAME NAMESPACE REVISION UPDATED STATUS CHART APP VERSION cka-demo cka 1 2022-07-24 19:58:36.272093383 +0800 CST deployed cka-demo-0.1.0 v1.23 mysql dev 1 2022-07-24 19:37:20.710988009 +0800 CST deployed mysql-9.2.1 8.0.29 \u5982\u679c\u9047\u5230\u9519\u8bef\uff0c\u5219\u9700\u8981\u5378\u8f7d cka-demo \u5e76\u91cd\u65b0\u5b89\u88c5\u5b83\u3002 helm uninstall cka-demo -n \u68c0\u67e5 cka-demo \u7684\u65e5\u5fd7\u3002 kubectl logs -n cka -l app = cka-demo \u8fd0\u884c\u7ed3\u679c Your CKA score is 0, Come on! you can do it next time! \u901a\u8fc7\u5176\u4ed6\u9009\u9879\u5b89\u88c5 cka-demo \u3002 helm uninstall cka-demo -n cka helm install cka-demo cka-demo-0.1.0.tgz --create-namespace \\ -n cka \\ --set studentName = kubernetes \\ --set ckaScore = 100 \\ --set passExam = true \u8fd0\u884c\u7ed3\u679c\uff1a NAME: cka-demo LAST DEPLOYED: Sun Jul 24 20:01:34 2022 NAMESPACE: cka STATUS: deployed REVISION: 1 TEST SUITE: None NOTES: Congratulations! You have successfully completed Certified Kubernetes Administrator China Exam (CKA-CN). Your CKA score is: 100 Click the link below to view and download your certificate. https://trainingportal.linuxfoundation.org/learn/dashboard \u68c0\u67e5 cka-demo \u7684\u65e5\u5fd7\u3002 kubectl logs -n cka -l app = cka-demo \u8fd0\u884c\u7ed3\u679c\uff1a Your CKA score is 100 and your CKA certificate ID number is BQKoVYVhjzl3G Built-in Objects\u5217\u8868 Release.Name # \u53d1\u5e03\u540d\u79f0 Release.Namespace # \u53d1\u5e03Namespace Release.Service # \u6e32\u67d3\u6a21\u677f\u7684\u670d\u52a1\uff0c\u5728Helm\u4e2d\u9ed8\u8ba4\u503c\u4e3a\"Helm\" Release.IsUpgrade # \u5982\u679c\u5f53\u524d\u662f\u5347\u7ea7\u6216\u56de\u6eda\uff0c\u8bbe\u7f6e\u4e3atrue Release.IsInstall # \u5982\u679c\u5f53\u524d\u662f\u5b89\u88c5\uff0c\u8bbe\u7f6e\u4e3atrue Release.Revision # \u53d1\u5e03\u7248\u672c\u53f7 Values # \u4ecevalues.yaml\u548c--set\u4f20\u5165\uff0c\u9ed8\u8ba4\u4e3a\u7a7a Chart # \u6240\u6709Chart.yaml\u4e2d\u7684\u5185\u5bb9 Chart.Version # Chart.Maintainers # Files # \u5728chart\u4e2d\u8bbf\u95ee\u975e\u7279\u6b8a\u6587\u4ef6 Capabilities # \u63d0\u4f9b\u5173\u4e8e\u652f\u6301\u80fd\u529b\u7684\u4fe1\u606f\uff08K8s API\u7248\u672c\u3001K8s\u7248\u672c\u3001Helm\u7248\u672c\uff09 Capabilities.KubeVersion # Kubernetes\u7684\u7248\u672c\u53f7 Capabilities.APIVersions.Has \"batch/v1\" # K8s API\u7248\u672c\u5305\u542b\"batch/v1\" Template # \u5f53\u524d\u6a21\u677f\u4fe1\u606f Template.Name # \u5f53\u524d\u6a21\u677f\u6587\u4ef6\u8def\u5f84 Template.BasePath # \u5f53\u524d\u6a21\u677f\u76ee\u5f55\u8def\u5f84 \u53c2\u8003\uff1a Helm \u5b98\u7f51 Helm \u7248\u672c\u652f\u6301\u7b56\u7565 Helm Chart \u8d44\u6e90\u5bf9\u8c61\u5b89\u88c5\u987a\u5e8f","title":"Chart Debug"},{"location":"k8s/cka_cn/foundamentals/hpa/","text":"CKA\u81ea\u5b66\u7b14\u8bb021:Horizontal Pod Autoscaling (HPA) \u00b6 \u6f14\u793a\u573a\u666f\uff1a \u5b89\u88c5 Metrics Server \u7ec4\u4ef6 \u521b\u5efa Deployment podinfo \u548c Service podinfo \u7528\u4e8e\u538b\u529b\u6d4b\u8bd5 \u521b\u5efa HPA my-hpa \u8fdb\u884c\u538b\u529b\u6d4b\u8bd5 \u5b89\u88c5Metrics Server \u00b6 \u4e0b\u8f7d components.yaml \u6587\u4ef6\uff0c\u6765\u90e8\u7f72Metrics Server\u3002 wget https://github.com/kubernetes-sigs/metrics-server/releases/latest/download/components.yaml \u628ayaml\u6587\u4ef6\u4e2dgoogle\u7684\u955c\u50cf\u6e90\u66ff\u6362\u4e3a\u963f\u91cc\u7684\u955c\u50cf\u6e90 image: registry.aliyuncs.com/google_containers/metrics-server:v0.6.1 \u3002 sed -i 's/k8s\\.gcr\\.io\\/metrics-server\\/metrics-server\\:v0\\.6\\.1/registry\\.aliyuncs\\.com\\/google_containers\\/metrics-server\\:v0\\.6\\.1/g' components.yaml \u4fee\u6539deployment metrics-server \u7684 args \uff0c\u6dfb\u52a0\u9009\u9879 --kubelet-insecure-tls \u4ee5\u7981\u7528\u8bc1\u4e66\u9a8c\u8bc1\u3002 vi components.yaml \u66f4\u65b0 args \u3002 ...... template : metadata : labels : k8s-app : metrics-server spec : containers : - args : - --cert-dir=/tmp - --secure-port=4443 - --kubelet-preferred-address-types=InternalIP,ExternalIP,Hostname - --kubelet-use-node-status-port - --metric-resolution=15s - --kubelet-insecure-tls image : registry.aliyuncs.com/google_containers/metrics-server:v0.6.1 ...... \u5e94\u7528\u6587\u4ef6 components.yaml \u6765\u90e8\u7f72 metrics-server \u3002 kubectl apply -f components.yaml \u4e0b\u9762\u662f\u8fd0\u884c\u7ed3\u679c\uff0c\u76f8\u5173\u8d44\u6e90\u88ab\u521b\u5efa\u3002 serviceaccount/metrics-server created clusterrole.rbac.authorization.k8s.io/system:aggregated-metrics-reader created clusterrole.rbac.authorization.k8s.io/system:metrics-server created rolebinding.rbac.authorization.k8s.io/metrics-server-auth-reader created clusterrolebinding.rbac.authorization.k8s.io/metrics-server:system:auth-delegator created clusterrolebinding.rbac.authorization.k8s.io/system:metrics-server created service/metrics-server created deployment.apps/metrics-server created apiservice.apiregistration.k8s.io/v1beta1.metrics.k8s.io created \u9a8c\u8bc1 pod metrics-server \u662f\u5426\u6309\u9884\u671f\u5728\u6b63\u5e38\u8fd0\u884c\u3002 kubectl get pod -n kube-system -owide | grep metrics-server \u8fd0\u884c\u7ed3\u679c\u3002\u5173\u6ce8READY\u4e0b\u7684\u72b6\u6001\uff1a 1/1 running\u4ee3\u8868\u6b63\u5e38\u8fd0\u884c\u3002 NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES metrics-server-7fd564dc66-sdhdc 1/1 Running 0 61s 10.244.102.15 cka003 \u67e5\u8be2\u6bcf\u4e2a\u8282\u70b9\u4e0a\u5f53\u524dCPU\u548c\u5185\u5b58\u7684\u7528\u91cf\u60c5\u51b5\u3002 kubectl top node \u8fd0\u884c\u7ed3\u679c\uff1a NAME CPU(cores) CPU% MEMORY(bytes) MEMORY% cka001 595m 29% 1937Mi 50% cka002 75m 3% 1081Mi 28% cka003 79m 3% 1026Mi 26% \u90e8\u7f72\u670d\u52a1 podinfo \u00b6 \u521b\u5efa Deployment podinfo \u548c Service podinfo \uff0c\u540e\u9762\u4f1a\u8fdb\u884c\u66f4\u8fdb\u4e00\u6b65\u7684\u538b\u529b\u6d4b\u8bd5\u3002 kubectl apply -f - << EOF apiVersion: v1 kind: Service metadata: name: podinfo labels: app: podinfo spec: type: NodePort ports: - port: 9898 targetPort: 9898 nodePort: 31198 protocol: TCP selector: app: podinfo --- apiVersion: apps/v1 kind: Deployment metadata: name: podinfo labels: app: podinfo spec: replicas: 2 selector: matchLabels: app: podinfo template: metadata: labels: app: podinfo spec: containers: - name: podinfod image: stefanprodan/podinfo:0.0.1 imagePullPolicy: Always command: - ./podinfo - -port=9898 - -logtostderr=true - -v=2 ports: - containerPort: 9898 protocol: TCP resources: requests: memory: \"32Mi\" cpu: \"10m\" limits: memory: \"256Mi\" cpu: \"100m\" EOF Config HPA \u00b6 \u521b\u5efa\u4e00\u4e2a\u540d\u4e3a my-hpa \u7684 HPA\uff0c\u5e76\u5c06\u5176\u7ed1\u5b9a\u5230\u540d\u4e3a podinfo \u7684\u90e8\u7f72\u4e2d\uff0c\u8bbe\u5b9a\u5176 CPU \u5229\u7528\u7387\u4e3a 50% \u4f5c\u4e3a\u89e6\u53d1\u81ea\u52a8\u7f29\u653e\u7684\u9608\u503c\uff0c\u6700\u5c0f\u526f\u672c\u6570\u4e3a 2 \uff0c\u6700\u5927\u526f\u672c\u6570\u4e3a 10 \u3002 \u4f7f\u7528\u4ee5\u4e0b\u547d\u4ee4\u521b\u5efa my-hpa HPA\uff1a kubectl autoscale deployment podinfo --cpu-percent = 50 --min = 2 --max = 10 --name = my-hpa kubectl autoscale deployment podinfo --cpu-percent = 50 --min = 1 --max = 10 \u4f7f\u7528 autoscaling/v1 \u7248\u672c\u7684\u6a21\u7248\u6765\u521b\u5efaHPA my-hpa \u3002 kubectl apply -f - < \u67e5\u8be2\u6bcf\u4e2a\u8282\u70b9\u4e0a\u5f53\u524dCPU\u548c\u5185\u5b58\u7684\u7528\u91cf\u60c5\u51b5\u3002 kubectl top node \u8fd0\u884c\u7ed3\u679c\uff1a NAME CPU(cores) CPU% MEMORY(bytes) MEMORY% cka001 595m 29% 1937Mi 50% cka002 75m 3% 1081Mi 28% cka003 79m 3% 1026Mi 26%","title":"\u5b89\u88c5Metrics Server"},{"location":"k8s/cka_cn/foundamentals/hpa/#podinfo","text":"\u521b\u5efa Deployment podinfo \u548c Service podinfo \uff0c\u540e\u9762\u4f1a\u8fdb\u884c\u66f4\u8fdb\u4e00\u6b65\u7684\u538b\u529b\u6d4b\u8bd5\u3002 kubectl apply -f - << EOF apiVersion: v1 kind: Service metadata: name: podinfo labels: app: podinfo spec: type: NodePort ports: - port: 9898 targetPort: 9898 nodePort: 31198 protocol: TCP selector: app: podinfo --- apiVersion: apps/v1 kind: Deployment metadata: name: podinfo labels: app: podinfo spec: replicas: 2 selector: matchLabels: app: podinfo template: metadata: labels: app: podinfo spec: containers: - name: podinfod image: stefanprodan/podinfo:0.0.1 imagePullPolicy: Always command: - ./podinfo - -port=9898 - -logtostderr=true - -v=2 ports: - containerPort: 9898 protocol: TCP resources: requests: memory: \"32Mi\" cpu: \"10m\" limits: memory: \"256Mi\" cpu: \"100m\" EOF","title":"\u90e8\u7f72\u670d\u52a1podinfo"},{"location":"k8s/cka_cn/foundamentals/hpa/#config-hpa","text":"\u521b\u5efa\u4e00\u4e2a\u540d\u4e3a my-hpa \u7684 HPA\uff0c\u5e76\u5c06\u5176\u7ed1\u5b9a\u5230\u540d\u4e3a podinfo \u7684\u90e8\u7f72\u4e2d\uff0c\u8bbe\u5b9a\u5176 CPU \u5229\u7528\u7387\u4e3a 50% \u4f5c\u4e3a\u89e6\u53d1\u81ea\u52a8\u7f29\u653e\u7684\u9608\u503c\uff0c\u6700\u5c0f\u526f\u672c\u6570\u4e3a 2 \uff0c\u6700\u5927\u526f\u672c\u6570\u4e3a 10 \u3002 \u4f7f\u7528\u4ee5\u4e0b\u547d\u4ee4\u521b\u5efa my-hpa HPA\uff1a kubectl autoscale deployment podinfo --cpu-percent = 50 --min = 2 --max = 10 --name = my-hpa kubectl autoscale deployment podinfo --cpu-percent = 50 --min = 1 --max = 10 \u4f7f\u7528 autoscaling/v1 \u7248\u672c\u7684\u6a21\u7248\u6765\u521b\u5efaHPA my-hpa \u3002 kubectl apply -f - << body >< h1 > It works! \u5220\u9664\u6f14\u793a\u4e2d\u521b\u5efa\u7684\u4e34\u65f6\u8d44\u6e90\u3002 kubectl delete ingress demo-localhost kubectl delete service demo kubectl delete deployment demo \u521b\u5efaDeployments \u00b6 \u521b\u5efa2\u4e2adeployment nginx-app-1 \u548c nginx-app-2 \u3002 kubectl apply -f - << EOF apiVersion: apps/v1 kind: Deployment metadata: name: nginx-app-1 spec: selector: matchLabels: app: nginx-app-1 replicas: 1 template: metadata: labels: app: nginx-app-1 spec: containers: - name: nginx image: nginx ports: - containerPort: 80 volumeMounts: - name: html mountPath: /usr/share/nginx/html volumes: - name: html hostPath: path: /opt/html-1 --- apiVersion: apps/v1 kind: Deployment metadata: name: nginx-app-2 spec: selector: matchLabels: app: nginx-app-2 replicas: 1 template: metadata: labels: app: nginx-app-2 spec: containers: - name: nginx image: nginx ports: - containerPort: 80 volumeMounts: - name: html mountPath: /usr/share/nginx/html volumes: - name: html hostPath: path: /opt/html-2 EOF \u6267\u884c\u547d\u4ee4 kubectl get pod -o wide \u6765\u83b7\u53d6pod\u7684\u72b6\u6001\u3002 \u53ef\u4ee5\u770b\u5230\u4e00\u4e2apod\u8fd0\u884c\u5728\u8282\u70b9 cka002 \uff0c\u53e6\u5916\u4e00\u4e2apod\u8fd0\u884c\u5728\u8282\u70b9 cka003 \u3002 Directory /opt/html-2/ is on cka002 Directory /opt/html-1/ is on cka002 \u901a\u8fc7 curl \u547d\u4ee4\u6765\u8bbf\u95ee\u8fd92\u4e2apod\uff0c\u6536\u5230 403 Forbidden \u9519\u8bef\u3002 curl 10 .244.102.13 curl 10 .244.112.19 \u767b\u5f55\u5230\u8282\u70b9 cka002 \uff0c\u6267\u884c\u4e0b\u9762\u547d\u4ee4\uff0c\u5728 /opt/html-2/ \u8def\u5f84\u4e0b\u521b\u5efa\u6587\u4ef6 index.html \u3002 cat < app1.com app2.com EOF \u6267\u884c\u4ee5\u4e0b\u547d\u4ee4\uff0c\u53ef\u4ee5\u5f97\u5230 IP \u5730\u5740\u6216 FQDN\u3002 kubectl get service ingress-nginx-controller --namespace = ingress-nginx \u5728\u8f93\u51fa\u7ed3\u679c\u4e2d\u53ef\u4ee5\u770b\u5230 EXTERNAL-IP \u5b57\u6bb5\u3002\u5982\u679c\u8be5\u5b57\u6bb5\u50cf\u4e0b\u9762\u4e00\u6837\u663e\u793a\u4e3a \uff0c\u8fd9\u610f\u5473\u7740 Kubernetes \u96c6\u7fa4\u65e0\u6cd5\u63d0\u4f9b\u8d1f\u8f7d\u5747\u8861\u5668\uff08\u901a\u5e38\u662f\u56e0\u4e3a\u5b83\u4e0d\u652f\u6301 LoadBalancer \u7c7b\u578b\u7684\u670d\u52a1\uff09\u3002 \u7531\u4e8e\u6ca1\u6709\u914d\u7f6e\u963f\u91cc\u4e91 ELB\uff0c\u56e0\u6b64\u6709\u4ee5\u4e0b\u4e24\u4e2a\u9009\u9879\u53ef\u4ee5\u89e3\u51b3\u8fd9\u4e2a\u95ee\u9898\u3002 \u9009\u9879 1\uff1a\u624b\u52a8\u5c06\u8282\u70b9 IP \u6dfb\u52a0\u5230\u8fd0\u884c ingress \u63a7\u5236\u5668\u7684\u8282\u70b9\u4e0a\u3002 \u6267\u884c\u547d\u4ee4 kubectl get pod -n ingress-nginx -o wide \u6765\u67e5\u770b ingress \u63a7\u5236\u5668 pod \u8fd0\u884c\u5728\u54ea\u4e2a\u8282\u70b9\u4e0a\u3002 \u624b\u52a8\u5c06 cka003 \u7684\u5916\u90e8 IP \u8865\u4e01\u5230 EXTERNAL-IP \u5b57\u6bb5\u3002 kubectl patch svc ingress-nginx-controller \\ --namespace = ingress-nginx \\ -p '{\"spec\": {\"type\": \"LoadBalancer\", \"externalIPs\":[\"\"]}}' \u9009\u9879 2\uff1a\u5c06 ingress \u63a7\u5236\u5668\u4ece LoadBalancer \u7c7b\u578b\u66f4\u6539\u4e3a NodePort \u7c7b\u578b\u3002 \u4e24\u4e2a Pod \u4e2d\u5404\u6709\u4e00\u4e2a index.html \u6587\u4ef6\uff0cWeb \u670d\u52a1\u901a\u8fc7\u8282\u70b9 IP \u5bf9\u5916\u66b4\u9732\u3002 ingress-nginx-controller \u4f5c\u4e3a\u4e2d\u5fc3\u5165\u53e3\u70b9\uff0c\u4e3a\u6765\u81ea Pod \u7684\u4e0d\u540c\u540e\u7aef\u670d\u52a1\u63d0\u4f9b\u4e86\u4e24\u4e2a\u7aef\u53e3\u3002 \u53d1\u9001HTTP\u8bf7\u6c42\u5230\u5728Ingress\u4e2d\u5b9a\u4e49\u76842\u4e2a\u4e3b\u673a\u8282\u70b9\u3002 curl http://app1.com:30011 curl http://app2.com:30011 curl app1.com:30011 curl app2.com:30011 \u53ef\u4ee5\u5f97\u5230\u4e0b\u9762\u7684\u4fe1\u606f\uff0c\u8bf4\u660e\u8bbf\u95ee\u6210\u529f\u3002 This is test 1 !! This is test 2 !! \u5220\u9664\u4e0a\u9762\u6f14\u793a\u4e2d\u521b\u5efa\u7684\u4e34\u65f6\u8d44\u6e90\u3002 kubectl delete ingress ingress-nginx-app kubectl delete service nginx-app-1 kubectl delete service nginx-app-2 kubectl delete deployment nginx-app-1 kubectl delete deployment nginx-app-2","title":"Ingress-nginx"},{"location":"k8s/cka_cn/foundamentals/ingress/#cka19ingress-nginx","text":"\u6f14\u793a\u573a\u666f\uff1a \u90e8\u7f72Ingress Controller\u3002 \u521b\u5efa\u4e24\u4e2aDeployment nginx-app-1 \u548c nginx-app-2 \u3002 \u5728\u8fd0\u884c\u4e3b\u673a\u4e0a\u521b\u5efa\u4e3b\u673a\u76ee\u5f55 /root/html-1 \u548c /root/html-2 \u5e76\u6302\u8f7d\u5230\u4e24\u4e2aDeployment\u4e0a\u3002 \u521b\u5efaService\u3002 \u521b\u5efaService nginx-app-1 \u548c nginx-app-2 \u5e76\u5c06\u5176\u6620\u5c04\u5230\u76f8\u5173\u7684Deployment nginx-app-1 \u548c nginx-app-2 \u3002 \u521b\u5efaIngress\u3002 \u521b\u5efaIngress\u8d44\u6e90 nginx-app \u5e76\u5c06\u5176\u6620\u5c04\u5230\u4e24\u4e2aServices nginx-app-1 \u548c nginx-app-1 \u3002 \u6d4b\u8bd5\u53ef\u8bbf\u95ee\u6027\u3002 \u5411Ingress\u4e2d\u5b9a\u4e49\u7684\u4e24\u4e2a\u4e3b\u673a\u53d1\u9001HTTP\u8bf7\u6c42\u3002 \u53c2\u8003\uff1a Github ingress-nginx Installation Guide","title":"CKA\u81ea\u5b66\u7b14\u8bb019:Ingress-nginx"},{"location":"k8s/cka_cn/foundamentals/ingress/#ingress","text":"\u83b7\u53d6Ingress\u63a7\u5236\u5668\u7684yaml\u6587\u4ef6\u3002\u6700\u65b0\u7248\u672c\u7684\u94fe\u63a5\u5728 \u5b89\u88c5\u6307\u5357 \u4e2d\u3002 wget https://raw.githubusercontent.com/kubernetes/ingress-nginx/controller-v1.3.0/deploy/static/provider/cloud/deploy.yaml \u4fee\u6539 deploy.yaml \u6587\u4ef6\u4e2d\u955c\u50cf\u6e90\u4e3a\u963f\u91cc\u4e91\u7684\u6e90\u3002 deploy.yaml \u6587\u4ef6\u4e2d\u9700\u8981\u4fee\u6539\u7684\u884c\uff1a image : k8s.gcr.io/ingress-nginx/controller:v1.2.1@sha256:5516d103a9c2ecc4f026efbd4b40662ce22dc1f824fb129ed121460aaa5c47f8 image : registry.k8s.io/ingress-nginx/controller:v1.3.0@sha256:d1707ca76d3b044ab8a28277a2466a02100ee9f58a86af1535a3edf9323ea1b5 image : k8s.gcr.io/ingress-nginx/kube-webhook-certgen:v1.1.1@sha256:64d8c73dca984af206adf9d6d7e46aa550362b1d7a01f3a0a91b20cc67868660 \u4fee\u6539\u5185\u5bb9\uff1a k8s.gcr.io/ingress-nginx/controller \u6539\u4e3a registry.aliyuncs.com/google_containers/nginx-ingress-controller \u3002 registry.k8s.io/ingress-nginx/controller \u6539\u4e3a registry.aliyuncs.com/google_containers/nginx-ingress-controller \u3002 k8s.gcr.io/ingress-nginx/kube-webhook-certgen \u6539\u4e3a registry.aliyuncs.com/google_containers/kube-webhook-certgen \u3002 \u4fee\u6539\u547d\u4ee4\uff1a sed -i 's/k8s.gcr.io\\/ingress-nginx\\/kube-webhook-certgen/registry.aliyuncs.com\\/google\\_containers\\/kube-webhook-certgen/g' deploy.yaml sed -i 's/k8s.gcr.io\\/ingress-nginx\\/controller/registry.aliyuncs.com\\/google\\_containers\\/nginx-ingress-controller/g' deploy.yaml \u5e94\u7528\u6587\u4ef6 deploy.yaml \u6765\u521b\u5efa Ingress Nginx\u3002 \u4e00\u4e2a\u65b0\u7684\u547d\u540d\u7a7a\u95f4namespace ingress-nginx \u4f1a\u88ab\u521b\u5efa\uff0cIngress Nginx\u76f8\u5173\u7684\u8d44\u6e90\u8fd0\u884c\u5728\u8fd9\u4e2anamespace\u4e0a\u3002 kubectl apply -f deploy.yaml \u67e5\u770bPod\u7684\u72b6\u6001\u3002 kubectl get pod -n ingress-nginx \u786e\u4fdd\u6240\u4ee5pod\u7684\u8fd0\u884c\u72b6\u6001\u90fd\u6b63\u5e38\uff0c\u7c7b\u4f3c\u5982\u4e0b\u7ed3\u679c\uff1a NAME READY STATUS RESTARTS AGE ingress-nginx-admission-create-lgtdj 0/1 Completed 0 49s ingress-nginx-admission-patch-nk9fv 0/1 Completed 0 49s ingress-nginx-controller-556fbd6d6f-6jl4x 1/1 Running 0 49s","title":"\u90e8\u7f72Ingress\u63a7\u5236\u5668"},{"location":"k8s/cka_cn/foundamentals/ingress/#_1","text":"\u8ba9\u6211\u4eec\u521b\u5efa\u4e00\u4e2a\u7b80\u5355\u7684 Web \u670d\u52a1\u5668\u548c\u76f8\u5173\u7684\u670d\u52a1\uff1a kubectl create deployment demo --image = httpd --port = 80 kubectl expose deployment demo \u63a5\u4e0b\u6765\u521b\u5efa\u4e00\u4e2a Ingress \u8d44\u6e90\u3002\u4ee5\u4e0b\u793a\u4f8b\u4f7f\u7528\u5c06\u4e3b\u673a\u6620\u5c04\u5230 localhost: kubectl create ingress demo-localhost --class = nginx --rule = \"demo.localdev.me/*=demo:80\" \u73b0\u5728\uff0c\u5c06\u672c\u5730\u7aef\u53e3\u8f6c\u53d1\u5230Ingress\u63a7\u5236\u5668\uff1a kubectl port-forward --namespace = ingress-nginx service/ingress-nginx-controller 8080 :80 \u73b0\u5728\uff0c\u5728\u53e6\u4e00\u4e2a\u7ec8\u7aef\u4e2d\u8bbf\u95ee http://demo.localdev.me:8080/ \uff0c\u6211\u4eec\u5e94\u8be5\u770b\u5230\u4e00\u4e2a HTML \u9875\u9762\uff0c\u4e0a\u9762\u5199\u7740 \"It works!\"\u3002 curl http://demo.localdev.me:8080/ \u8fd0\u884c\u7ed3\u679c\uff1b < html >< body >< h1 > It works! \u5220\u9664\u6f14\u793a\u4e2d\u521b\u5efa\u7684\u4e34\u65f6\u8d44\u6e90\u3002 kubectl delete ingress demo-localhost kubectl delete service demo kubectl delete deployment demo","title":"\u672c\u5730\u6d4b\u8bd5\u65b9\u5f0f"},{"location":"k8s/cka_cn/foundamentals/ingress/#deployments","text":"\u521b\u5efa2\u4e2adeployment nginx-app-1 \u548c nginx-app-2 \u3002 kubectl apply -f - << EOF apiVersion: apps/v1 kind: Deployment metadata: name: nginx-app-1 spec: selector: matchLabels: app: nginx-app-1 replicas: 1 template: metadata: labels: app: nginx-app-1 spec: containers: - name: nginx image: nginx ports: - containerPort: 80 volumeMounts: - name: html mountPath: /usr/share/nginx/html volumes: - name: html hostPath: path: /opt/html-1 --- apiVersion: apps/v1 kind: Deployment metadata: name: nginx-app-2 spec: selector: matchLabels: app: nginx-app-2 replicas: 1 template: metadata: labels: app: nginx-app-2 spec: containers: - name: nginx image: nginx ports: - containerPort: 80 volumeMounts: - name: html mountPath: /usr/share/nginx/html volumes: - name: html hostPath: path: /opt/html-2 EOF \u6267\u884c\u547d\u4ee4 kubectl get pod -o wide \u6765\u83b7\u53d6pod\u7684\u72b6\u6001\u3002 \u53ef\u4ee5\u770b\u5230\u4e00\u4e2apod\u8fd0\u884c\u5728\u8282\u70b9 cka002 \uff0c\u53e6\u5916\u4e00\u4e2apod\u8fd0\u884c\u5728\u8282\u70b9 cka003 \u3002 Directory /opt/html-2/ is on cka002 Directory /opt/html-1/ is on cka002 \u901a\u8fc7 curl \u547d\u4ee4\u6765\u8bbf\u95ee\u8fd92\u4e2apod\uff0c\u6536\u5230 403 Forbidden \u9519\u8bef\u3002 curl 10 .244.102.13 curl 10 .244.112.19 \u767b\u5f55\u5230\u8282\u70b9 cka002 \uff0c\u6267\u884c\u4e0b\u9762\u547d\u4ee4\uff0c\u5728 /opt/html-2/ \u8def\u5f84\u4e0b\u521b\u5efa\u6587\u4ef6 index.html \u3002 cat < app1.com app2.com EOF \u6267\u884c\u4ee5\u4e0b\u547d\u4ee4\uff0c\u53ef\u4ee5\u5f97\u5230 IP \u5730\u5740\u6216 FQDN\u3002 kubectl get service ingress-nginx-controller --namespace = ingress-nginx \u5728\u8f93\u51fa\u7ed3\u679c\u4e2d\u53ef\u4ee5\u770b\u5230 EXTERNAL-IP \u5b57\u6bb5\u3002\u5982\u679c\u8be5\u5b57\u6bb5\u50cf\u4e0b\u9762\u4e00\u6837\u663e\u793a\u4e3a \uff0c\u8fd9\u610f\u5473\u7740 Kubernetes \u96c6\u7fa4\u65e0\u6cd5\u63d0\u4f9b\u8d1f\u8f7d\u5747\u8861\u5668\uff08\u901a\u5e38\u662f\u56e0\u4e3a\u5b83\u4e0d\u652f\u6301 LoadBalancer \u7c7b\u578b\u7684\u670d\u52a1\uff09\u3002 \u7531\u4e8e\u6ca1\u6709\u914d\u7f6e\u963f\u91cc\u4e91 ELB\uff0c\u56e0\u6b64\u6709\u4ee5\u4e0b\u4e24\u4e2a\u9009\u9879\u53ef\u4ee5\u89e3\u51b3\u8fd9\u4e2a\u95ee\u9898\u3002 \u9009\u9879 1\uff1a\u624b\u52a8\u5c06\u8282\u70b9 IP \u6dfb\u52a0\u5230\u8fd0\u884c ingress \u63a7\u5236\u5668\u7684\u8282\u70b9\u4e0a\u3002 \u6267\u884c\u547d\u4ee4 kubectl get pod -n ingress-nginx -o wide \u6765\u67e5\u770b ingress \u63a7\u5236\u5668 pod \u8fd0\u884c\u5728\u54ea\u4e2a\u8282\u70b9\u4e0a\u3002 \u624b\u52a8\u5c06 cka003 \u7684\u5916\u90e8 IP \u8865\u4e01\u5230 EXTERNAL-IP \u5b57\u6bb5\u3002 kubectl patch svc ingress-nginx-controller \\ --namespace = ingress-nginx \\ -p '{\"spec\": {\"type\": \"LoadBalancer\", \"externalIPs\":[\"\"]}}' \u9009\u9879 2\uff1a\u5c06 ingress \u63a7\u5236\u5668\u4ece LoadBalancer \u7c7b\u578b\u66f4\u6539\u4e3a NodePort \u7c7b\u578b\u3002 \u4e24\u4e2a Pod \u4e2d\u5404\u6709\u4e00\u4e2a index.html \u6587\u4ef6\uff0cWeb \u670d\u52a1\u901a\u8fc7\u8282\u70b9 IP \u5bf9\u5916\u66b4\u9732\u3002 ingress-nginx-controller \u4f5c\u4e3a\u4e2d\u5fc3\u5165\u53e3\u70b9\uff0c\u4e3a\u6765\u81ea Pod \u7684\u4e0d\u540c\u540e\u7aef\u670d\u52a1\u63d0\u4f9b\u4e86\u4e24\u4e2a\u7aef\u53e3\u3002 \u53d1\u9001HTTP\u8bf7\u6c42\u5230\u5728Ingress\u4e2d\u5b9a\u4e49\u76842\u4e2a\u4e3b\u673a\u8282\u70b9\u3002 curl http://app1.com:30011 curl http://app2.com:30011 curl app1.com:30011 curl app2.com:30011 \u53ef\u4ee5\u5f97\u5230\u4e0b\u9762\u7684\u4fe1\u606f\uff0c\u8bf4\u660e\u8bbf\u95ee\u6210\u529f\u3002 This is test 1 !! This is test 2 !! \u5220\u9664\u4e0a\u9762\u6f14\u793a\u4e2d\u521b\u5efa\u7684\u4e34\u65f6\u8d44\u6e90\u3002 kubectl delete ingress ingress-nginx-app kubectl delete service nginx-app-1 kubectl delete service nginx-app-2 kubectl delete deployment nginx-app-1 kubectl delete deployment nginx-app-2","title":"\u53ef\u8bbf\u95ee\u6027\u6d4b\u8bd5"},{"location":"k8s/cka_cn/foundamentals/job/","text":"CKA\u81ea\u5b66\u7b14\u8bb014:Job and Cronjob \u00b6 Job \u00b6 \u6f14\u793a\u573a\u666f\uff1a \u521b\u5efaJob\u3002 \u6f14\u793a\uff1a \u521b\u5efaJob pi \u3002 kubectl apply -f - << EOF apiVersion: batch/v1 kind: Job metadata: name: pi spec: template: spec: containers: - name: pi image: perl:5.34 command: [\"perl\", \"-Mbignum=bpi\", \"-wle\", \"print bpi(2000)\"] restartPolicy: Never backoffLimit: 4 EOF \u83b7\u53d6Job\u7684\u8be6\u7ec6\u4fe1\u606f\u3002 kubectl get jobs \u83b7\u53d6Job\u7684Pod\u7684\u8be6\u7ec6\u4fe1\u606f\u3002 Completed \u7684\u72b6\u6001\u4ee3\u8868\u8fd9\u4e2ajob\u5df2\u7ecf\u6210\u529f\u5b8c\u6210\u4e86\u3002 kubectl get pod \u83b7\u53d6Job\u7684Pod\u7684\u65e5\u5fd7\u4fe1\u606f\u3002 kubectl pi-2s74d 3 .141592653589793.............. \u5220\u9664\u6240\u521b\u5efa\u7684\u8d44\u6e90\u3002 kubectl delete job pi Cronjob \u00b6 \u6f14\u793a\u573a\u666f\uff1a \u521b\u5efaCronjob\u3002 \u6f14\u793a\uff1a \u521b\u5efaCronjob hello \u3002 kubectl apply -f - << EOF apiVersion: batch/v1 kind: CronJob metadata: name: hello spec: schedule: \"*/1 * * * *\" jobTemplate: spec: template: spec: containers: - name: hello image: busybox args: - /bin/sh - -c - date ; echo Hello from the kubernetes cluster restartPolicy: OnFailure EOF \u83b7\u53d6Cronjob\u7684\u8be6\u7ec6\u4fe1\u606f\u3002 kubectl get cronjobs -o wide \u8fd0\u884c\u7ed3\u679c NAME SCHEDULE SUSPEND ACTIVE LAST SCHEDULE AGE CONTAINERS IMAGES SELECTOR hello */1 * * * * False 0 25s hello busybox \u76d1\u63a7Jobs\u3002\u6bcf\u96941\u5206\u949f\uff0c\u4e00\u4e2a\u65b0\u7684job\u4f1a\u88ab\u521b\u5efa\u3002 kubectl get jobs -w \u5220\u9664\u521b\u5efa\u7684\u8d44\u6e90\u3002 kubectl delete cronjob hello","title":"Job and Cronjob"},{"location":"k8s/cka_cn/foundamentals/job/#cka14job-and-cronjob","text":"","title":"CKA\u81ea\u5b66\u7b14\u8bb014:Job and Cronjob"},{"location":"k8s/cka_cn/foundamentals/job/#job","text":"\u6f14\u793a\u573a\u666f\uff1a \u521b\u5efaJob\u3002 \u6f14\u793a\uff1a \u521b\u5efaJob pi \u3002 kubectl apply -f - << EOF apiVersion: batch/v1 kind: Job metadata: name: pi spec: template: spec: containers: - name: pi image: perl:5.34 command: [\"perl\", \"-Mbignum=bpi\", \"-wle\", \"print bpi(2000)\"] restartPolicy: Never backoffLimit: 4 EOF \u83b7\u53d6Job\u7684\u8be6\u7ec6\u4fe1\u606f\u3002 kubectl get jobs \u83b7\u53d6Job\u7684Pod\u7684\u8be6\u7ec6\u4fe1\u606f\u3002 Completed \u7684\u72b6\u6001\u4ee3\u8868\u8fd9\u4e2ajob\u5df2\u7ecf\u6210\u529f\u5b8c\u6210\u4e86\u3002 kubectl get pod \u83b7\u53d6Job\u7684Pod\u7684\u65e5\u5fd7\u4fe1\u606f\u3002 kubectl pi-2s74d 3 .141592653589793.............. \u5220\u9664\u6240\u521b\u5efa\u7684\u8d44\u6e90\u3002 kubectl delete job pi","title":"Job"},{"location":"k8s/cka_cn/foundamentals/job/#cronjob","text":"\u6f14\u793a\u573a\u666f\uff1a \u521b\u5efaCronjob\u3002 \u6f14\u793a\uff1a \u521b\u5efaCronjob hello \u3002 kubectl apply -f - << EOF apiVersion: batch/v1 kind: CronJob metadata: name: hello spec: schedule: \"*/1 * * * *\" jobTemplate: spec: template: spec: containers: - name: hello image: busybox args: - /bin/sh - -c - date ; echo Hello from the kubernetes cluster restartPolicy: OnFailure EOF \u83b7\u53d6Cronjob\u7684\u8be6\u7ec6\u4fe1\u606f\u3002 kubectl get cronjobs -o wide \u8fd0\u884c\u7ed3\u679c NAME SCHEDULE SUSPEND ACTIVE LAST SCHEDULE AGE CONTAINERS IMAGES SELECTOR hello */1 * * * * False 0 25s hello busybox \u76d1\u63a7Jobs\u3002\u6bcf\u96941\u5206\u949f\uff0c\u4e00\u4e2a\u65b0\u7684job\u4f1a\u88ab\u521b\u5efa\u3002 kubectl get jobs -w \u5220\u9664\u521b\u5efa\u7684\u8d44\u6e90\u3002 kubectl delete cronjob hello","title":"Cronjob"},{"location":"k8s/cka_cn/foundamentals/memo/","text":"CKA\u81ea\u5b66\u7b14\u8bb05:Kubernetes\u968f\u7b14 \u00b6 \u6458\u8981 \u00b6 \u8fb9\u7ec3\u4e60\u8fb9\u8bb0\u5f55\u7684\u5185\u5bb9\uff0c\u4e0d\u662f\u5168\u9762\u7cfb\u7edf\u7684\uff0c\u5305\u62ec\u4e0b\u9762\u4e3b\u8981\u5185\u5bb9\uff1a Kubernetes\u57fa\u672c\u6982\u5ff5 \u7ec4\u4ef6 API \u5bf9\u8c61 \u8d44\u6e90 \u5de5\u4f5c\u8d1f\u8f7d\u8d44\u6e90 Pod Deployment ReplicaSet StatefulSet DaemonSet Job CronJob \u670d\u52a1\u8d44\u6e90 Service Endpoints \u914d\u7f6e\u548c\u5b58\u50a8\u8d44\u6e90 \u5377 Storage Class PV Access Modes Kubernetes\u57fa\u672c\u6982\u5ff5 \u00b6 Kubernetes\u7ec4\u4ef6 \u00b6 \u4e00\u4e2aKubernetes\u96c6\u7fa4\u7531\u4ee3\u8868\u63a7\u5236\u5e73\u9762\uff08control plane\uff09\u7684\u7ec4\u4ef6\u548c\u4e00\u7ec4\u79f0\u4e3a\u8282\u70b9\uff08nodes\uff09\u7684\u673a\u5668\u7ec4\u6210\u3002 Kubernetes\u7ec4\u4ef6: \u63a7\u5236\u5e73\u9762\u7ec4\u4ef6 Control Plane Components kube-apiserver: \u67e5\u8be2\u548c\u64cd\u4f5c Kubernetes \u4e2d\u5bf9\u8c61\u7684\u72b6\u6001\u3002 \u5145\u5f53\u6240\u6709\u8d44\u6e90\u4e4b\u95f4\u7684\u901a\u4fe1\u4e2d\u5fc3\uff08communication hub\uff09\u3002 \u63d0\u4f9b\u96c6\u7fa4\u5b89\u5168\u8eab\u4efd\u9a8c\u8bc1\u3001\u6388\u6743\u548c\u89d2\u8272\u5206\u914d\u3002 \u662f\u552f\u4e00\u80fd\u8fde\u63a5\u5230 etcd \u7684\u7ec4\u4ef6\u3002 etcd: \u6240\u6709 Kubernetes \u5bf9\u8c61\u90fd\u5b58\u50a8\u5728 etcd \u4e2d\u3002 Kubernetes \u5bf9\u8c61\u662f Kubernetes \u7cfb\u7edf\u4e2d\u7684\u6301\u4e45\u5b9e\u4f53(entities)\uff0c\u7528\u4e8e\u8868\u793a\u96c6\u7fa4\u7684\u72b6\u6001\u3002 kube-scheduler: \u76d1\u89c6\u6ca1\u6709\u5206\u914d\u8282\u70b9\u7684\u65b0\u521b\u5efa\u7684 Pod\uff0c\u5e76\u4e3a\u5b83\u4eec\u9009\u62e9\u4e00\u4e2a\u8282\u70b9\u6765\u8fd0\u884c\u3002 kube-controller-manager: \u8fd0\u884c\u63a7\u5236\u5668\u8fdb\u7a0b\u3002 Node controller : \u8d1f\u8d23\u8b66\u793a\u548c\u54cd\u5e94\u8282\u70b9\u7684\u6545\u969c\u3002 Job controller : \u76d1\u89c6\u8868\u793a\u4e00\u6b21\u6027\u4efb\u52a1\u7684 Job \u5bf9\u8c61\uff0c\u7136\u540e\u521b\u5efa Pod \u6765\u5b8c\u6210\u8fd9\u4e9b\u4efb\u52a1\u3002 Endpoints controller : \u586b\u5145 Endpoints \u5bf9\u8c61\uff08\u5373\u5c06 Service \u548c Pod \u8fde\u63a5\u8d77\u6765\uff09\u3002 Service Account & Token controllers : \u4e3a\u65b0\u547d\u540d\u7a7a\u95f4\u521b\u5efa\u9ed8\u8ba4\u5e10\u6237\u548c API \u8bbf\u95ee\u4ee4\u724c\u3002 cloud-controller-manager: \u5d4c\u5165\u4e91\u7279\u5b9a\u7684\u63a7\u5236\u903b\u8f91\uff0c\u4ec5\u8fd0\u884c\u7279\u5b9a\u4e8e\u6211\u4eec\u9009\u62e9\u7684\u4e91\u63d0\u4f9b\u5546\u7684\u63a7\u5236\u5668\uff0c\u65e0\u9700\u81ea\u5df1\u7684\u57fa\u7840\u8bbe\u65bd\u548c\u5b66\u4e60\u73af\u5883\u3002 Node controller : \u7528\u4e8e\u68c0\u67e5\u4e91\u63d0\u4f9b\u5546\uff0c\u4ee5\u786e\u5b9a\u8282\u70b9\u5728\u5728\u5b83\u505c\u6b62\u54cd\u5e94\u540e\u662f\u5426\u5df2\u5728\u4e91\u4e2d\u88ab\u5220\u9664\u3002 Route controller : \u7528\u4e8e\u5728\u5e95\u5c42\u4e91\u57fa\u7840\u67b6\u6784\u4e2d\u8bbe\u7f6e\u8def\u7531\u3002 Service controller : \u7528\u4e8e\u521b\u5efa\u3001\u66f4\u65b0\u548c\u5220\u9664\u4e91\u63d0\u4f9b\u5546\u8d1f\u8f7d\u5747\u8861\u5668\u3002 \u8282\u70b9\u7ec4\u4ef6 Node Components kubelet: \u5728\u96c6\u7fa4\u4e2d\u6bcf\u4e2a\u8282\u70b9\u4e0a\u8fd0\u884c\u7684\u4ee3\u7406\u3002 \u7ba1\u7406\u8282\u70b9\u3002\u5b83\u786e\u4fdd Pod \u4e2d\u8fd0\u884c\u5bb9\u5668\u3002 kubelet \u5411 APIServer \u6ce8\u518c\u548c\u66f4\u65b0\u8282\u70b9\u4fe1\u606f\uff0cAPIServer \u5c06\u5b83\u4eec\u5b58\u50a8\u5230 etcd \u4e2d\u3002 \u7ba1\u7406 Pod\u3002\u901a\u8fc7 APIServer \u76d1\u89c6 Pod\uff0c\u5e76\u5bf9 Pod \u6216 Pod \u4e2d\u7684\u5bb9\u5668\u91c7\u53d6\u884c\u52a8\u3002 \u5728\u5bb9\u5668\u7ea7\u522b\u8fdb\u884c\u5065\u5eb7\u68c0\u67e5\u3002 kube-proxy: \u662f\u5728\u96c6\u7fa4\u4e2d\u6bcf\u4e2a\u8282\u70b9\u4e0a\u8fd0\u884c\u7684\u7f51\u7edc\u4ee3\u7406\u3002 iptables ipvs \u7ef4\u62a4\u8282\u70b9\u4e0a\u7684\u7f51\u7edc\u89c4\u5219\u3002 \u5bb9\u5668\u8fd0\u884c\u65f6Container runtime\uff1a \u8d1f\u8d23\u8fd0\u884c\u5bb9\u5668\u7684\u8f6f\u4ef6\u3002 \u63d2\u4ef6Addons DNS: \u662f DNS \u670d\u52a1\u5668\uff0c\u662f\u6240\u6709 Kubernetes \u96c6\u7fa4\u6240\u5fc5\u9700\u7684\u3002 Web UI\uff08\u4eea\u8868\u76d8\uff09\uff1a\u7528\u4e8e Kubernetes \u96c6\u7fa4\u7684\u57fa\u4e8e Web \u7684\u7528\u6237\u754c\u9762\u3002 \u5bb9\u5668\u8d44\u6e90\u76d1\u63a7\uff1a\u8bb0\u5f55\u6709\u5173\u96c6\u4e2d\u5f0f\u6570\u636e\u5e93\u4e2d\u5bb9\u5668\u7684\u901a\u7528\u65f6\u95f4\u5e8f\u5217\u5ea6\u91cf\u3002 Cluster-level Logging\uff1a\u8d1f\u8d23\u5c06\u5bb9\u5668\u65e5\u5fd7\u4fdd\u5b58\u5230\u5177\u6709\u641c\u7d22/\u6d4f\u89c8\u63a5\u53e3\u7684\u4e2d\u592e\u65e5\u5fd7\u5b58\u50a8\u4e2d\u3002 \u53ef\u6269\u5c55\u6027\uff1a \u6c34\u5e73\u6269\u5c55\uff08Scaling out\uff09\u901a\u8fc7\u6dfb\u52a0\u66f4\u591a\u7684\u670d\u52a1\u5668\u5230\u67b6\u6784\u4e2d\uff0c\u5c06\u5de5\u4f5c\u8d1f\u8f7d\u5206\u6563\u5230\u66f4\u591a\u7684\u673a\u5668\u4e0a\u3002 \u5782\u76f4\u6269\u5c55\uff08Scaling up\uff09\u901a\u8fc7\u6dfb\u52a0\u66f4\u591a\u7684\u786c\u76d8\u548c\u5185\u5b58\u6765\u589e\u52a0\u7269\u7406\u670d\u52a1\u5668\u7684\u8ba1\u7b97\u80fd\u529b\u3002 Kubernetes API \u00b6 REST API\u662fKubernetes\u7684\u57fa\u672c\u6846\u67b6\u3002\u6240\u6709\u7ec4\u4ef6\u4e4b\u95f4\u7684\u64cd\u4f5c\u548c\u901a\u4fe1\uff0c\u4ee5\u53ca\u5916\u90e8\u7528\u6237\u547d\u4ee4\u90fd\u662f\u7531API\u670d\u52a1\u5668\u5904\u7406\u7684REST API\u8c03\u7528\u3002\u56e0\u6b64\uff0cKubernetes\u5e73\u53f0\u4e2d\u7684\u6240\u6709\u5185\u5bb9\u90fd\u88ab\u89c6\u4e3aAPI\u5bf9\u8c61\uff08API object\uff09\uff0c\u5e76\u5728API\u4e2d\u6709\u76f8\u5e94\u7684\u6761\u76ee\u3002 Kubernetes\u63a7\u5236\u5e73\u9762\u7684\u6838\u5fc3\u662fAPI\u670d\u52a1\u5668\u3002 CRI\uff1a\u5bb9\u5668\u8fd0\u884c\u65f6\u63a5\u53e3 CNI\uff1a\u5bb9\u5668\u7f51\u7edc\u63a5\u53e3 CSI\uff1a\u5bb9\u5668\u5b58\u50a8\u63a5\u53e3 API\u670d\u52a1\u5668\u516c\u5f00\u4e86\u4e00\u4e2aHTTP API\uff0c\u5141\u8bb8\u6700\u7ec8\u7528\u6237\u3001\u96c6\u7fa4\u7684\u4e0d\u540c\u90e8\u5206\u548c\u5916\u90e8\u7ec4\u4ef6\u5f7c\u6b64\u901a\u4fe1\u3002 Kubernetes API\u5141\u8bb8\u6211\u4eec\u67e5\u8be2\u548c\u64cd\u4f5cKubernetes\u4e2dAPI\u5bf9\u8c61\u7684\u72b6\u6001\uff08\u4f8b\u5982\uff1aPod\u3001Namespace\u3001ConfigMap\u548cEvent\uff09\u3002 Kubernetes API\uff1a OpenAPI\u89c4\u8303 OpenAPI V2 OpenAPI V3 \u6301\u4e45\u6027\u3002Kubernetes\u901a\u8fc7\u5c06\u5bf9\u8c61\u7684\u5e8f\u5217\u5316\u72b6\u6001\u5199\u5165etcd\u6765\u5b58\u50a8\u5b83\u4eec\u3002 API\u7ec4\u548c\u7248\u672c\u63a7\u5236\u3002\u7248\u672c\u63a7\u5236\u662f\u5728API\u7ea7\u522b\u8fdb\u884c\u7684\u3002API\u8d44\u6e90\u901a\u8fc7\u5b83\u4eec\u7684API\u7ec4\u3001\u8d44\u6e90\u7c7b\u578b\u3001\u547d\u540d\u7a7a\u95f4\uff08\u7528\u4e8e\u547d\u540d\u7a7a\u95f4\u8d44\u6e90\uff09\u548c\u540d\u79f0\u8fdb\u884c\u533a\u5206\u3002 API\u66f4\u6539 API\u6269\u5c55 API Version \u00b6 API\u7248\u672c\u548c\u8f6f\u4ef6\u7248\u672c\u95f4\u5b58\u5728\u95f4\u63a5\u5173\u7cfb\u3002API\u548c\u53d1\u5e03\u7248\u672c\u8ba1\u5212\u63cf\u8ff0\u4e86API\u7248\u672c\u548c\u8f6f\u4ef6\u7248\u672c\u4e4b\u95f4\u7684\u5173\u7cfb\u3002\u4e0d\u540c\u7684API\u7248\u672c\u8868\u793a\u4e0d\u540c\u7684\u7a33\u5b9a\u6027\u548c\u652f\u6301\u7ea7\u522b\u3002 \u4ee5\u4e0b\u662f\u6bcf\u4e2a\u7ea7\u522b\u7684\u6458\u8981\uff1a Alpha\uff1a \u7248\u672c\u540d\u79f0\u5305\u542balpha\uff08\u4f8b\u5982\uff0cv1alpha1\uff09\u3002 \u8f6f\u4ef6\u53ef\u80fd\u5305\u542b\u9519\u8bef\u3002\u542f\u7528\u529f\u80fd\u53ef\u80fd\u4f1a\u66b4\u9732\u9519\u8bef\u3002\u67d0\u4e9b\u529f\u80fd\u53ef\u80fd\u9ed8\u8ba4\u7981\u7528\u3002 \u5bf9\u4e8e\u67d0\u4e9b\u529f\u80fd\u7684\u652f\u6301\u53ef\u4ee5\u968f\u65f6\u53d6\u6d88\uff0c\u800c\u4e0d\u4f1a\u63d0\u524d\u901a\u77e5\u3002 API\u53ef\u80fd\u4f1a\u5728\u4ee5\u540e\u7684\u8f6f\u4ef6\u53d1\u5e03\u4e2d\u4ee5\u4e0d\u517c\u5bb9\u7684\u65b9\u5f0f\u66f4\u6539\uff0c\u800c\u4e0d\u4f1a\u63d0\u524d\u901a\u77e5\u3002 \u7531\u4e8e\u9519\u8bef\u98ce\u9669\u589e\u52a0\u548c\u957f\u671f\u652f\u6301\u4e0d\u8db3\uff0c\u5efa\u8bae\u4ec5\u5728\u77ed\u6682\u7684\u6d4b\u8bd5\u96c6\u7fa4\u4e2d\u4f7f\u7528\u8be5\u8f6f\u4ef6\u3002 Beta\uff1a \u7248\u672c\u540d\u79f0\u5305\u542bbeta\uff08\u4f8b\u5982\uff0cv2beta3\uff09\u3002 \u8f6f\u4ef6\u7ecf\u8fc7\u5145\u5206\u6d4b\u8bd5\u3002\u542f\u7528\u529f\u80fd\u88ab\u8ba4\u4e3a\u662f\u5b89\u5168\u7684\u3002\u67d0\u4e9b\u529f\u80fd\u9ed8\u8ba4\u542f\u7528\u3002 \u5bf9\u4e8e\u67d0\u4e9b\u529f\u80fd\u7684\u652f\u6301\u4e0d\u4f1a\u53d6\u6d88\uff0c\u4f46\u7ec6\u8282\u53ef\u80fd\u4f1a\u66f4\u6539\u3002 \u5bf9\u8c61\u7684\u6a21\u5f0f\u548c/\u6216\u8bed\u4e49\u53ef\u80fd\u4f1a\u5728\u540e\u7eed\u7684Beta\u6216\u7a33\u5b9a\u7248\u53d1\u5e03\u4e2d\u4ee5\u4e0d\u517c\u5bb9\u7684\u65b9\u5f0f\u66f4\u6539\u3002\u5f53\u53d1\u751f\u8fd9\u79cd\u60c5\u51b5\u65f6\uff0c\u5c06\u63d0\u4f9b\u8fc1\u79fb\u8bf4\u660e\u3002\u6a21\u5f0f\u66f4\u6539\u53ef\u80fd\u9700\u8981\u5220\u9664\u3001\u7f16\u8f91\u548c\u91cd\u65b0\u521b\u5efa API\u5bf9\u8c61\u3002\u7f16\u8f91\u8fc7\u7a0b\u53ef\u80fd\u4e0d\u7b80\u5355\u3002\u8fc1\u79fb\u53ef\u80fd\u9700\u8981\u505c\u673a\uff0c\u4ee5\u4fbf\u4f9d\u8d56\u4e8e\u8be5\u529f\u80fd\u7684\u5e94\u7528\u7a0b\u5e8f\u3002 \u4e0d\u5efa\u8bae\u5c06\u8be5\u8f6f\u4ef6\u7528\u4e8e\u751f\u4ea7\u7528\u9014\u3002\u540e\u7eed\u7684\u53d1\u5e03\u53ef\u80fd\u4f1a\u5f15\u5165\u4e0d\u517c\u5bb9\u7684\u66f4\u6539\u3002\u5982\u679c\u60a8\u6709\u591a\u4e2a\u53ef\u4ee5\u72ec\u7acb\u5347\u7ea7\u7684\u96c6\u7fa4\uff0c\u5219\u53ef\u4ee5\u653e\u5bbd\u6b64\u9650\u5236\u3002 \u6ce8\u610f\uff1a\u8bf7\u5c1d\u8bd5beta\u529f\u80fd\u5e76\u63d0\u4f9b\u53cd\u9988\u3002\u529f\u80fd\u9000\u51fabeta\u540e\uff0c\u53ef\u80fd\u4e0d\u5b9e\u9645\u518d\u8fdb\u884c\u66f4\u6539\u3002 \u7a33\u5b9a\u7248\uff1a \u7248\u672c\u540d\u79f0\u4e3avX\uff0c\u5176\u4e2dX\u662f\u6574\u6570\u3002 \u529f\u80fd\u7684\u7a33\u5b9a\u7248\u672c\u51fa\u73b0\u5728\u53d1\u5e03\u7684\u8f6f\u4ef6\u4e2d\u7684\u8bb8\u591a\u540e\u7eed\u7248\u672c\u4e2d\u3002 \u8bfb\u53d6\u5f53\u524dAPI\u7684\u7248\u672c\u547d\u4ee4\uff1a kubectl api-resources API Group \u00b6 API\u7ec4\uff08API groups\uff09 \u4f7f\u6269\u5c55Kubernetes API\u66f4\u52a0\u5bb9\u6613\u3002API\u7ec4\u5728REST\u8def\u5f84\u548c\u5e8f\u5217\u5316\u5bf9\u8c61\u7684apiVersion\u5b57\u6bb5\u4e2d\u6307\u5b9a\u3002 Kubernetes\u6709\u51e0\u4e2aAPI\u7ec4\uff1a \u6838\u5fc3\u7ec4\uff08\u4e5f\u79f0\u4e3a\u9057\u7559legacy\uff09\u4f4d\u4e8eREST\u8def\u5f84 /api/v1 \u3002 \u6838\u5fc3\u7ec4\u4e0d\u4f5c\u4e3aapiVersion\u5b57\u6bb5\u7684\u4e00\u90e8\u5206\u6307\u5b9a\uff0c\u4f8b\u5982 apiVersion: v1\u3002 \u547d\u540d\u7ec4\u4f4d\u4e8eREST\u8def\u5f84 /apis/$GROUP_NAME/$VERSION \uff0c\u5e76\u4f7f\u7528 apiVersion: $GROUP_NAME/$VERSION \uff08\u4f8b\u5982 apiVersion: batch/v1\uff09\u3002 Kubernetes\u5bf9\u8c61 \u00b6 \u5bf9\u8c61\u6982\u8ff0 \u00b6 \u5bf9\u8c61\u89c4\u8303\uff08Object Spec\uff09\uff1a \u63d0\u4f9b\u4e86\u4e00\u4e2a\u63cf\u8ff0\u6240\u521b\u5efa\u8d44\u6e90\u7684\u7279\u6027\u7684\u8bf4\u660e\uff1a \u5176\u671f\u671b\u7684\u72b6\u6001 \u3002 \u5bf9\u8c61\u72b6\u6001\uff08Object Status\uff09\uff1a \u63cf\u8ff0\u4e86\u5bf9\u8c61\u7684\u5f53\u524d\u72b6\u6001\u3002 \u6bd4\u5982\uff0cDeployment\u662f\u4e00\u4e2a\u53ef\u4ee5\u4ee3\u8868\u96c6\u7fa4\u4e0a\u8fd0\u884c\u7684\u5e94\u7528\u7a0b\u5e8f\u7684\u5bf9\u8c61\u3002 apiVersion : apps/v1 # \u5f53\u524d\u7528\u6765\u521b\u5efa\u5bf9\u8c61\u7684API\u7248\u672c kind : Deployment # \u521b\u5efa\u5bf9\u8c61\u7684\u7c7b\u578b metadata : # \u7528\u6765\u533a\u5206\u5bf9\u8c61\u7684\u5143\u6570\u636e\uff0c\u6bd4\u5982\uff1a\u540d\u79f0\uff0cUID\uff0c\u547d\u540d\u7a7a\u95f4\u7b49 name : nginx-deployment spec : # \u671f\u671b\u6240\u521b\u5efa\u5bf9\u8c61\u7684\u72b6\u6001 selector : matchLabels : app : nginx replicas : 2 # \u544a\u8bc9Deployment\u57fa\u4e8e\u4e0b\u9762\u7684\u6a21\u677ftemplate\u521b\u5efa2\u4e2aPods template : metadata : labels : app : nginx spec : containers : - name : nginx image : nginx:1.14.2 ports : - containerPort : 80 \u5bf9\u8c61\u7ba1\u7406 \u00b6 kubectl \u547d\u4ee4\u884c\u5de5\u5177\u652f\u6301\u591a\u79cd\u4e0d\u540c\u7684\u65b9\u5f0f\u6765\u521b\u5efa\u548c\u7ba1\u7406 Kubernetes \u5bf9\u8c61\u3002\u8be6\u7ec6\u4fe1\u606f\u8bf7\u9605\u8bfb Kubectl book \u3002 \u4e00\u4e2a Kubernetes \u5bf9\u8c61\u5e94\u8be5\u4ec5\u4f7f\u7528\u4e00\u79cd\u6280\u672f\u8fdb\u884c\u7ba1\u7406\u3002\u6df7\u5408\u4f7f\u7528\u4e0d\u540c\u7684\u6280\u672f\u6765\u7ba1\u7406\u540c\u4e00\u4e2a\u5bf9\u8c61\u4f1a\u5bfc\u81f4\u975e\u9884\u671f\u7684\u7ed3\u679c\u3002 \u4e09\u79cd\u7ba1\u7406\u6280\u672f: \u547d\u4ee4\u5f0f\u547d\u4ee4 \u76f4\u63a5\u5728\u96c6\u7fa4\u4e2d\u64cd\u4f5c\u5b9e\u65f6\u5bf9\u8c61\u3002 kubectl create deployment nginx --image nginx \u547d\u4ee4\u5f0f\u5bf9\u8c61\u914d\u7f6e kubectl create -f nginx.yaml kubectl delete -f nginx.yaml -f redis.yaml kubectl replace -f nginx.yaml \u58f0\u660e\u5f0f\u5bf9\u8c61\u914d\u7f6e kubectl diff -f configs/ kubectl apply -f configs/ \u5bf9\u8c61\u540d\u79f0\u548cID \u00b6 \u96c6\u7fa4\u4e2d\u7684\u6bcf\u4e2a\u5bf9\u8c61\u90fd\u6709\u4e00\u4e2a\u5728\u8be5\u8d44\u6e90\u7c7b\u578b\u4e2d\u552f\u4e00\u7684\u540d\u79f0\u3002 DNS \u5b50\u57df\u540d \u6807\u7b7e\u540d\u79f0 \u8def\u5f84\u6bb5\u540d\u79f0 \u6bcf\u4e2a Kubernetes \u5bf9\u8c61\u8fd8\u6709\u4e00\u4e2a UID\uff0c\u5728\u6574\u4e2a\u96c6\u7fa4\u4e2d\u662f\u552f\u4e00\u7684\u3002 \u547d\u540d\u7a7a\u95f4 \u00b6 \u5728Kubernetes\u4e2d\uff0c\u547d\u540d\u7a7a\u95f4\u63d0\u4f9b\u4e86\u4e00\u79cd\u5728\u5355\u4e2a\u96c6\u7fa4\u5185\u9694\u79bb\u8d44\u6e90\u7ec4\u7684\u673a\u5236\u3002 \u8d44\u6e90\u7684\u540d\u79f0\u9700\u8981\u5728\u547d\u540d\u7a7a\u95f4\u5185\u662f\u552f\u4e00\u7684\uff0c\u4f46\u4e0d\u9700\u8981\u8de8\u547d\u540d\u7a7a\u95f4\u552f\u4e00\u3002 \u57fa\u4e8e\u547d\u540d\u7a7a\u95f4\u7684\u8303\u56f4\u4ec5\u9002\u7528\u4e8e\u547d\u540d\u7a7a\u95f4\u5bf9\u8c61\uff08\u4f8b\u5982\u90e8\u7f72\uff0c\u670d\u52a1\u7b49\uff09\uff0c\u800c\u4e0d\u9002\u7528\u4e8e\u96c6\u7fa4\u8303\u56f4\u7684\u5bf9\u8c61\uff08\u4f8b\u5982StorageClass\uff0c\u8282\u70b9\uff0c\u6301\u4e45\u5377\u7b49\uff09\u3002 \u5e76\u975e\u6240\u6709\u5bf9\u8c61\u90fd\u4f4d\u4e8e\u547d\u540d\u7a7a\u95f4\u4e2d\u3002 Kubernetes\u4ece\u56db\u4e2a\u521d\u59cb\u547d\u540d\u7a7a\u95f4\u5f00\u59cb\uff1a default \u7528\u4e8e\u6ca1\u6709\u5176\u4ed6\u547d\u540d\u7a7a\u95f4\u7684\u5bf9\u8c61\u7684\u9ed8\u8ba4\u547d\u540d\u7a7a\u95f4 kube-system Kubernetes\u7cfb\u7edf\u521b\u5efa\u7684\u5bf9\u8c61\u7684\u547d\u540d\u7a7a\u95f4 kube-public \u8be5\u547d\u540d\u7a7a\u95f4\u662f\u81ea\u52a8\u521b\u5efa\u7684\uff0c\u5e76\u53ef\u7531\u6240\u6709\u7528\u6237\uff08\u5305\u62ec\u672a\u7ecf\u8eab\u4efd\u9a8c\u8bc1\u7684\u7528\u6237\uff09\u8bfb\u53d6\u3002\u6b64\u547d\u540d\u7a7a\u95f4\u5927\u591a\u4fdd\u7559\u4f9b\u96c6\u7fa4\u4f7f\u7528\uff0c\u4ee5\u9632\u4e00\u4e9b\u8d44\u6e90\u5e94\u5728\u6574\u4e2a\u96c6\u7fa4\u8303\u56f4\u5185\u516c\u5f00\u548c\u53ef\u8bfb\u3002\u6b64\u547d\u540d\u7a7a\u95f4\u7684\u516c\u5171\u65b9\u9762\u53ea\u662f\u4e00\u79cd\u7ea6\u5b9a\uff0c\u800c\u4e0d\u662f\u8981\u6c42\u3002 kube-node-lease \u6b64\u547d\u540d\u7a7a\u95f4\u4fdd\u5b58\u4e0e\u6bcf\u4e2a\u8282\u70b9\u5173\u8054\u7684\u79df\u8d41\u5bf9\u8c61\u3002\u8282\u70b9\u79df\u8d41\u5141\u8bb8kubelet\u53d1\u9001\u5fc3\u8df3\uff0c\u4ee5\u4fbf\u63a7\u5236\u5e73\u9762\u53ef\u4ee5\u68c0\u6d4b\u5230\u8282\u70b9\u6545\u969c\u3002 \u67e5\u770b\u547d\u540d\u7a7a\u95f4\uff1a kubectl get namespace \u4e3a\u8bf7\u6c42\u8bbe\u7f6e\u547d\u540d\u7a7a\u95f4 kubectl run nginx --image=nginx --namespace=<\u63d2\u5165\u547d\u540d\u7a7a\u95f4\u540d\u79f0> kubectl get pods --namespace=<\u63d2\u5165\u547d\u540d\u7a7a\u95f4\u540d\u79f0> \u6807\u7b7e\u548c\u9009\u62e9\u5668 \u00b6 \u6807\u7b7e\u662f\u9644\u52a0\u5230\u5bf9\u8c61\uff08\u4f8b\u5982 Pod\uff09\u7684\u952e/\u503c\u5bf9\u3002\u6709\u6548\u7684\u6807\u7b7e\u952e\u6709\u4e24\u4e2a\u90e8\u5206\uff1a\u53ef\u9009\u7684\u524d\u7f00\u548c\u540d\u79f0\uff0c\u7531\u659c\u6760\uff08 / \uff09\u5206\u9694\u3002 \u6807\u7b7e\u65e8\u5728\u7528\u4e8e\u6307\u5b9a\u5bf9\u7528\u6237\u6709\u610f\u4e49\u548c\u76f8\u5173\u7684\u5bf9\u8c61\u8bc6\u522b\u5c5e\u6027\u3002 \u6807\u7b7e\u53ef\u7528\u4e8e\u7ec4\u7ec7\u548c\u9009\u62e9\u5bf9\u8c61\u5b50\u96c6\u3002\u6807\u7b7e\u53ef\u4ee5\u5728\u521b\u5efa\u5bf9\u8c61\u65f6\u9644\u52a0\uff0c\u968f\u540e\u5728\u4efb\u4f55\u65f6\u5019\u6dfb\u52a0\u548c\u4fee\u6539\u3002\u6bcf\u4e2a\u5bf9\u8c61\u53ef\u4ee5\u5b9a\u4e49\u4e00\u7ec4\u952e/\u503c\u6807\u7b7e\uff0c\u6bcf\u4e2a\u952e\u5fc5\u987b\u5bf9\u4e8e\u7ed9\u5b9a\u5bf9\u8c61\u662f\u552f\u4e00\u7684\u3002 \u6807\u7b7e\u7684\u793a\u4f8b\uff1a \"metadata\" : { \"labels\" : { \"key1\" : \"value1\" , \"key2\" : \"value2\" } } \u4e0e\u540d\u79f0\u548c UID \u4e0d\u540c\uff0c\u6807\u7b7e\u4e0d\u63d0\u4f9b\u552f\u4e00\u6027\u3002\u901a\u5e38\u60c5\u51b5\u4e0b\uff0c\u6211\u4eec\u671f\u671b\u8bb8\u591a\u5bf9\u8c61\u5e26\u6709\u76f8\u540c\u7684\u6807\u7b7e\u3002 \u76ee\u524d API \u652f\u6301\u4e24\u79cd\u7c7b\u578b\u7684\u9009\u62e9\u5668\uff1a \u57fa\u4e8e\u7b49\u5f0f\u7684\u9009\u62e9\u5668\uff0c\u4f8b\u5982\uff1a environment = production \u3001 tier != frontend \u57fa\u4e8e\u96c6\u5408\u7684\u9009\u62e9\u5668\uff0c\u4f8b\u5982\uff1a environment in (production, qa) \u3001 tier notin (frontend, backend) \u4f8b\u5982\uff1a kubectl get pods -l environment = production,tier = frontend kubectl get pods -l 'environment in (production),tier in (frontend)' kubectl get pods -l 'environment in (production, qa)' kubectl get pods -l 'environment,environment notin (frontend)' \u6ce8\u91caAnnotations \u00b6 \u4f7f\u7528 Kubernetes \u6ce8\u91ca\uff08Annotations\uff09\u5c06\u4efb\u610f\u975e\u6807\u8bc6\u5143\u6570\u636e\u9644\u52a0\u5230\u5bf9\u8c61\u4e0a\u3002 \u5de5\u5177\u548c\u5e93\u7b49\u5ba2\u6237\u7aef\u53ef\u4ee5\u68c0\u7d22\u6b64\u5143\u6570\u636e\u3002 \u4f7f\u7528\u6807\u7b7e\u6216\u6ce8\u91ca\u5c06\u5143\u6570\u636e\u9644\u52a0\u5230 Kubernetes \u5bf9\u8c61\u4e0a\u3002 \u6807\u7b7e\u53ef\u7528\u4e8e\u9009\u62e9\u5bf9\u8c61\u5e76\u67e5\u627e\u6ee1\u8db3\u67d0\u4e9b\u6761\u4ef6\u7684\u5bf9\u8c61\u96c6\u5408\u3002 \u6ce8\u91ca\u4e0d\u7528\u4e8e\u6807\u8bc6\u548c\u9009\u62e9\u5bf9\u8c61\u3002 \u6ce8\u91ca\u4e0e\u6807\u7b7e\u7c7b\u4f3c\uff0c\u90fd\u662f\u952e/\u503c\u6620\u5c04\u3002 \u6620\u5c04\u4e2d\u7684\u952e\u548c\u503c\u5fc5\u987b\u662f\u5b57\u7b26\u4e32\u3002 \u4f8b\u5982\uff1a \"metadata\" : { \"annotations\" : { \"key1\" : \"value1\" , \"key2\" : \"value2\" } } \u5408\u6cd5\u7684\u6ce8\u91ca\u952e\u5177\u6709\u4e24\u4e2a\u90e8\u5206\uff1a\u53ef\u9009\u7684\u524d\u7f00\u548c\u540d\u79f0\uff0c\u7531\u659c\u6760 ( / ) \u5206\u9694\u3002 \u5b57\u6bb5\u9009\u62e9\u5668 \u00b6 \u5b57\u6bb5\u9009\u62e9\u5668\uff08field selectors\uff09\u53ef\u4ee5\u6839\u636e\u4e00\u4e2a\u6216\u591a\u4e2a\u8d44\u6e90\u5b57\u6bb5\u7684\u503c\u9009\u62e9Kubernetes\u8d44\u6e90\u3002 \u4e0b\u9762\u662f\u4e00\u4e9b\u4f7f\u7528\u5b57\u6bb5\u9009\u62e9\u5668\u8fdb\u884c\u67e5\u8be2\u7b5b\u9009\u7684\u4f8b\u5b50\uff1a metadata.name=my-service metadata.namespace!=default status.phase=Pending This kubectl command selects all Pods for which the value of the status.phase field is Running: kubectl get pods --field-selector status.phase=Running Supported field selectors vary by Kubernetes resource type. All resource types support the metadata.name and metadata.namespace fields. Use the = , == , and != operators with field selectors ( = and == mean the same thing). \u4e0b\u9762 kubectl \u547d\u4ee4\u9009\u62e9\u6240\u6709\u72b6\u6001(phase)\u5b57\u6bb5\u503c\u4e3a Running \u7684 Pod\uff1a kubectl get pods --field-selector status.phase = Running \u652f\u6301\u7684\u5b57\u6bb5\u9009\u62e9\u5668\u56e0 Kubernetes \u8d44\u6e90\u7c7b\u578b\u800c\u5f02\u3002\u6240\u6709\u8d44\u6e90\u7c7b\u578b\u90fd\u652f\u6301 metadata.name \u548c metadata.namespace \u5b57\u6bb5\u3002 \u5728\u5b57\u6bb5\u9009\u62e9\u5668\u4e2d\u4f7f\u7528 = , == , \u548c != \u8fd0\u7b97\u7b26( = \u548c == \u8868\u793a\u76f8\u540c\u7684\u610f\u601d)\u3002 \u4f8b\u5982\uff1a kubectl get ingress --field-selector foo.bar = baz kubectl get services --all-namespaces --field-selector metadata.namespace! = default kubectl get pods --field-selector = status.phase! = Running,spec.restartPolicy = Always kubectl get statefulsets,services --all-namespaces --field-selector metadata.namespace! = default Finalizers\u662f*\u547d\u540d\u7a7a\u95f4\u952e*\uff0c\u544a\u8bc9Kubernetes\u5728\u6ee1\u8db3\u7279\u5b9a\u6761\u4ef6\u4e4b\u524d\u7b49\u5f85\uff0c\u7136\u540e\u518d\u5b8c\u5168\u5220\u9664\u6807\u8bb0\u4e3a*\u5220\u9664*\u7684\u8d44\u6e90\u3002 Finalizer\u8b66\u544a\u63a7\u5236\u5668controller\u6e05\u7406\u5df2\u5220\u9664\u5bf9\u8c61\u6240\u62e5\u6709\u7684\u8d44\u6e90\u3002 \u901a\u5e38\u56e0\u4e3a\u67d0\u79cd\u76ee\u7684\u4e3a\u8d44\u6e90\u6dfb\u52a0Finalizers\uff0c\u5f3a\u5236\u5220\u9664\u5b83\u4eec\u53ef\u80fd\u4f1a\u5bfc\u81f4\u96c6\u7fa4\u4e2d\u51fa\u73b0\u95ee\u9898\u3002 \u4e0e\u6807\u7b7e\u7c7b\u4f3c\uff0c \u6240\u6709\u8005\u5f15\u7528 \uff08Owner references\uff09\u63cf\u8ff0\u4e86Kubernetes\u4e2d\u5bf9\u8c61\u4e4b\u95f4\u7684\u5173\u7cfb\uff0c\u4f46\u7528\u4e8e\u4e0d\u540c\u7684\u76ee\u7684\u3002 Kubernetes\u4f7f\u7528\u6240\u6709\u8005\u5f15\u7528\uff08\u800c\u4e0d\u662f\u6807\u7b7e\uff09\u6765\u786e\u5b9a\u96c6\u7fa4\u4e2d\u54ea\u4e9bPod\u9700\u8981\u6e05\u7406\u3002 \u5f53Kubernetes\u8bc6\u522b\u5230\u76ee\u6807\u5220\u9664\u7684\u8d44\u6e90\u4e0a\u6709\u6240\u6709\u8005\u5f15\u7528\u65f6\uff0c\u5b83\u4f1a\u5904\u7406Finalizer\u3002 \u6240\u6709\u8005\u548c\u4f9d\u8d56\u5173\u7cfb \u00b6 \u5728 Kubernetes \u4e2d\uff0c\u4e00\u4e9b\u5bf9\u8c61\u62e5\u6709\u5176\u4ed6\u5bf9\u8c61\u3002\u4f8b\u5982\uff0cReplicaSet \u662f\u4e00\u7ec4 Pod \u7684\u6240\u6709\u8005\u3002\u8fd9\u4e9b\u88ab\u62e5\u6709\u7684\u5bf9\u8c61\u662f\u5176\u6240\u6709\u8005\u7684\u4ece\u5c5e\u5bf9\u8c61\u3002 \u4ece\u5c5e\u5bf9\u8c61\u5177\u6709\u4e00\u4e2a metadata.ownerReferences \u5b57\u6bb5\uff0c\u8be5\u5b57\u6bb5\u5f15\u7528\u5176\u6240\u6709\u8005\u5bf9\u8c61\u3002 \u6709\u6548\u7684\u6240\u6709\u8005\u5f15\u7528\u5305\u62ec\u5bf9\u8c61\u540d\u79f0\u548c\u4e0e\u4ece\u5c5e\u5bf9\u8c61\u76f8\u540c\u7684\u547d\u540d\u7a7a\u95f4\u4e2d\u7684 UID\u3002 \u4ece\u5c5e\u5bf9\u8c61\u8fd8\u5177\u6709\u4e00\u4e2a ownerReferences.blockOwnerDeletion \u5b57\u6bb5\uff0c\u8be5\u5b57\u6bb5\u5177\u6709\u5e03\u5c14\u503c\uff0c\u63a7\u5236\u7279\u5b9a\u7684\u4ece\u5c5e\u5bf9\u8c61\u662f\u5426\u53ef\u4ee5\u963b\u6b62\u5783\u573e\u56de\u6536\u5220\u9664\u5176\u6240\u6709\u8005\u5bf9\u8c61\u3002 \u8d44\u6e90 \u00b6 Kubernetes\u8d44\u6e90\u548c\u201c\u610f\u5411\u8bb0\u5f55\u201d\u90fd\u4ee5API\u5bf9\u8c61\u7684\u5f62\u5f0f\u5b58\u50a8\uff0c\u5e76\u901a\u8fc7\u5bf9API\u7684RESTful\u8c03\u7528\u8fdb\u884c\u4fee\u6539\u3002 API\u5141\u8bb8\u4ee5\u58f0\u660e\u6027\u65b9\u5f0f\u7ba1\u7406\u914d\u7f6e\u3002 \u7528\u6237\u53ef\u4ee5\u76f4\u63a5\u4e0eKubernetes API\u4ea4\u4e92\uff0c\u4e5f\u53ef\u4ee5\u901a\u8fc7\u50cfkubectl\u8fd9\u6837\u7684\u5de5\u5177\u8fdb\u884c\u4ea4\u4e92\u3002 \u6838\u5fc3Kubernetes API\u5177\u6709\u7075\u6d3b\u6027\uff0c\u4e5f\u53ef\u4ee5\u6269\u5c55\u4ee5\u652f\u6301\u81ea\u5b9a\u4e49\u8d44\u6e90\u3002 \u5de5\u4f5c\u8d1f\u8f7d\u8d44\u6e90\uff08Workload Resources\uff09 Pod \u3002Pod \u662f\u53ef\u4ee5\u5728\u4e3b\u673a\u4e0a\u8fd0\u884c\u7684\u5bb9\u5668\u96c6\u5408\u3002 PodTemplate \u3002PodTemplate \u63cf\u8ff0\u4e86\u9884\u5b9a\u4e49 pod \u7684\u526f\u672c\u6a21\u677f\u3002 ReplicationController \u3002ReplicationController \u8868\u793a\u4e00\u4e2a\u590d\u5236\u63a7\u5236\u5668\u7684\u914d\u7f6e\u3002 ReplicaSet \u3002ReplicaSet \u786e\u4fdd\u5728\u4efb\u4f55\u7ed9\u5b9a\u65f6\u95f4\u6709\u6307\u5b9a\u6570\u91cf\u7684 pod \u526f\u672c\u6b63\u5728\u8fd0\u884c\u3002 Deployment \u3002Deployment \u4f7f Pod \u548c ReplicaSet \u7684\u58f0\u660e\u6027\u66f4\u65b0\u6210\u4e3a\u53ef\u80fd\u3002 StatefulSet \u3002StatefulSet \u8868\u793a\u5177\u6709\u4e00\u81f4\u6807\u8bc6\u7684 pod \u96c6\u5408\u3002 ControllerRevision \u3002ControllerRevision \u5b9e\u73b0\u4e86\u72b6\u6001\u6570\u636e\u7684\u4e0d\u53ef\u53d8\u5feb\u7167\u3002 DaemonSet \u3002DaemonSet \u8868\u793a\u4e00\u4e2a\u5b88\u62a4\u8fdb\u7a0b\u96c6\u7684\u914d\u7f6e\u3002 Job \u3002Job \u8868\u793a\u5355\u4e2a job \u7684\u914d\u7f6e\u3002 CronJob \u3002CronJob \u8868\u793a\u5355\u4e2a cron job \u7684\u914d\u7f6e\u3002 HorizontalPodAutoscaler \u3002HorizontalPodAutoscaler \u8868\u793a\u6c34\u5e73 pod \u81ea\u52a8\u7f29\u653e\u5668\u7684\u914d\u7f6e\u3002 HorizontalPodAutoscaler v2beta2 \u3002HorizontalPodAutoscaler \u662f\u6c34\u5e73 pod \u81ea\u52a8\u7f29\u653e\u5668\u7684\u914d\u7f6e\uff0c\u6839\u636e\u6307\u5b9a\u7684\u6307\u6807\u81ea\u52a8\u7ba1\u7406\u5b9e\u73b0\u6bd4\u4f8b\u5b50\u8d44\u6e90\u7684\u4efb\u4f55\u8d44\u6e90\u7684\u526f\u672c\u8ba1\u6570\u3002 PriorityClass \u3002PriorityClass \u5b9a\u4e49\u4e86\u4ece\u4f18\u5148\u7ea7\u7c7b\u540d\u79f0\u5230\u4f18\u5148\u7ea7\u6574\u6570\u503c\u7684\u6620\u5c04\u3002 \u670d\u52a1\u8d44\u6e90\uff08Service Resources\uff09 Service . Service \u662f\u5bf9\u8f6f\u4ef6\u670d\u52a1\uff08\u4f8b\u5982mysql\uff09\u7684\u547d\u540d\u62bd\u8c61\uff0c\u7531\u4ee3\u7406\u76d1\u542c\u7684\u672c\u5730\u7aef\u53e3\uff08\u4f8b\u59823306\uff09\u548c\u786e\u5b9a\u54ea\u4e9bPod\u5c06\u56de\u7b54\u901a\u8fc7\u4ee3\u7406\u53d1\u9001\u7684\u8bf7\u6c42\u7684\u9009\u62e9\u5668\u7ec4\u6210\u3002 Endpoints . Endpoints \u662f\u5b9e\u73b0\u5b9e\u9645\u670d\u52a1\u7684\u4e00\u7ec4\u7ec8\u7ed3\u70b9\u3002 EndpointSlice . EndpointSlice \u8868\u793a\u5b9e\u73b0\u670d\u52a1\u7684\u7ec8\u7ed3\u70b9\u7684\u5b50\u96c6\u3002 Ingress . Ingress \u662f\u4e00\u7ec4\u89c4\u5219\uff0c\u5141\u8bb8\u5165\u7ad9\u8fde\u63a5\u5230\u8fbe\u7531\u540e\u7aef\u5b9a\u4e49\u7684\u7ec8\u7ed3\u70b9\u3002 IngressClass . IngressClass \u8868\u793a Ingress \u7684\u7c7b\uff0c\u7531 Ingress Spec \u5f15\u7528\u3002 \u914d\u7f6e\u548c\u5b58\u50a8\u8d44\u6e90\uff08Config and Storage Resources\uff09 ConfigMap \u3002ConfigMap\u4fdd\u5b58\u5bb9\u5668\u9700\u8981\u4f7f\u7528\u7684\u914d\u7f6e\u6570\u636e\u3002 Secret \u3002Secret\u4fdd\u5b58\u7279\u5b9a\u7c7b\u578b\u7684\u673a\u5bc6\u6570\u636e\u3002 Volume \u3002Volume\u8868\u793aPod\u4e2d\u7684\u547d\u540d\u5377\uff0c\u53ef\u4ee5\u88abPod\u4e2d\u7684\u4efb\u4f55\u5bb9\u5668\u8bbf\u95ee\u3002 PersistentVolumeClaim \u3002PersistentVolumeClaim\u662f\u7528\u6237\u5bf9\u6301\u4e45\u5377\u7684\u8bf7\u6c42\u548c\u58f0\u660e\u3002 PersistentVolume \u3002PersistentVolume\uff08PV\uff09\u662f\u7531\u7ba1\u7406\u5458\u63d0\u4f9b\u7684\u5b58\u50a8\u8d44\u6e90\u3002 StorageClass \u3002StorageClass\u63cf\u8ff0\u53ef\u52a8\u6001\u5206\u914dPersistentVolumes\u7684\u5b58\u50a8\u7c7b\u522b\u7684\u53c2\u6570\u3002 VolumeAttachment \u3002VolumeAttachment\u8bb0\u5f55\u5c06\u6307\u5b9a\u7684\u5377\u9644\u52a0\u5230/\u4ece\u6307\u5b9a\u8282\u70b9\u4e2d\u5206\u79bb\u7684\u610f\u56fe\u3002 CSIDriver \u3002CSIDriver\u8bb0\u5f55\u96c6\u7fa4\u4e0a\u90e8\u7f72\u7684\u5bb9\u5668\u5b58\u50a8\u63a5\u53e3\uff08CSI\uff09\u5377\u9a71\u52a8\u7a0b\u5e8f\u7684\u4fe1\u606f\u3002 CSINode \u3002CSINode\u4fdd\u5b58\u6709\u5173\u8282\u70b9\u4e0a\u5b89\u88c5\u7684\u6240\u6709CSI\u9a71\u52a8\u7a0b\u5e8f\u7684\u4fe1\u606f\u3002 CSIStorageCapacity \u3002CSIStorageCapacity\u5b58\u50a8\u4e00\u4e2aCSI GetCapacity\u8c03\u7528\u7684\u7ed3\u679c\u3002 \u8ba4\u8bc1\u8d44\u6e90\uff08Authentication Resources\uff09 ServiceAccount*\u3002ServiceAccount\u548c\u4e0b\u9762\u7684\u4fe1\u606f\u7ed1\u5b9a\u5728\u4e00\u8d77\uff1a \u4e00\u4e2a\u53ef\u88ab\u7528\u6237\u548c\u5468\u8fb9\u7cfb\u7edf\u7406\u89e3\u7684\u540d\u79f0\uff0c\u7528\u4e8e\u8eab\u4efd\u8bc6\u522b \u53ef\u8fdb\u884c\u8eab\u4efd\u9a8c\u8bc1\u548c\u6388\u6743\u7684\u4e3b\u4f53 \u4e00\u7ec4\u5bc6\u94a5\u3002 TokenRequest*\u3002TokenRequest\u4e3a\u7ed9\u5b9a\u7684ServiceAccount\u8bf7\u6c42\u4e00\u4e2a\u4ee4\u724c\u3002 TokenReview*\u3002TokenReview\u5c1d\u8bd5\u5bf9\u5df2\u77e5\u7528\u6237\u7684\u4ee4\u724c\u8fdb\u884c\u8eab\u4efd\u9a8c\u8bc1\u3002 CertificateSigningRequest*\u3002CertificateSigningRequest\u5bf9\u8c61\u63d0\u4f9b\u4e86\u4e00\u79cd\u901a\u8fc7\u63d0\u4ea4\u8bc1\u4e66\u7b7e\u540d\u8bf7\u6c42\u5e76\u5f02\u6b65\u6279\u51c6\u548c\u53d1\u653e\u6765\u83b7\u53d6x509\u8bc1\u4e66\u7684\u673a\u5236\u3002 \u6388\u6743\u8d44\u6e90\uff08Authorization Resources\uff09 LocalSubjectAccessReview*\u3002LocalSubjectAccessReview\u68c0\u67e5\u4e00\u4e2a\u7528\u6237\u6216\u7ec4\u5728\u7ed9\u5b9a\u547d\u540d\u7a7a\u95f4\u4e2d\u662f\u5426\u80fd\u6267\u884c\u67d0\u4e2a\u64cd\u4f5c\u3002 SelfSubjectAccessReview*\u3002SelfSubjectAccessReview\u68c0\u67e5\u5f53\u524d\u7528\u6237\u662f\u5426\u80fd\u6267\u884c\u67d0\u4e2a\u64cd\u4f5c\u3002 SelfSubjectRulesReview*\u3002SelfSubjectRulesReview\u679a\u4e3e\u5f53\u524d\u7528\u6237\u5728\u4e00\u4e2a\u547d\u540d\u7a7a\u95f4\u5185\u53ef\u4ee5\u6267\u884c\u7684\u64cd\u4f5c\u96c6\u5408\u3002 SubjectAccessReview*\u3002SubjectAccessReview\u68c0\u67e5\u4e00\u4e2a\u7528\u6237\u6216\u7ec4\u662f\u5426\u80fd\u6267\u884c\u67d0\u4e2a\u64cd\u4f5c\u3002 ClusterRole*\u3002ClusterRole\u662f\u4e00\u4e2a\u96c6\u7fa4\u7ea7\u522b\u7684PolicyRules\u903b\u8f91\u5206\u7ec4\uff0c\u53ef\u4ee5\u88abRoleBinding\u6216ClusterRoleBinding\u5f15\u7528\u4e3a\u4e00\u4e2a\u5355\u5143\u3002 ClusterRoleBinding*\u3002ClusterRoleBinding\u5f15\u7528\u4e00\u4e2aClusterRole\uff0c\u4f46\u4e0d\u5305\u542b\u5b83\u3002 Role*\u3002Role\u662f\u4e00\u4e2a\u547d\u540d\u7a7a\u95f4\u7ea7\u522b\u7684PolicyRules\u903b\u8f91\u5206\u7ec4\uff0c\u53ef\u4ee5\u88abRoleBinding\u5f15\u7528\u4e3a\u4e00\u4e2a\u5355\u5143\u3002 RoleBinding*\u3002RoleBinding\u5f15\u7528\u4e00\u4e2aRole\uff0c\u4f46\u4e0d\u5305\u542b\u5b83\u3002 \u7b56\u7565\u8d44\u6e90\uff08Policy Resources\uff09 LimitRange*\u3002LimitRange\u4e3a\u547d\u540d\u7a7a\u95f4\u4e2d\u6bcf\u79cd\u8d44\u6e90\u8bbe\u7f6e\u8d44\u6e90\u4f7f\u7528\u9650\u5236\u3002 ResourceQuota*\u3002ResourceQuota\u8bbe\u7f6e\u6bcf\u4e2a\u547d\u540d\u7a7a\u95f4\u5f3a\u5236\u6267\u884c\u7684\u603b\u914d\u989d\u9650\u5236\u3002 NetworkPolicy*\u3002NetworkPolicy\u63cf\u8ff0\u4e86\u4e00\u7ec4Pod\u5141\u8bb8\u7684\u7f51\u7edc\u6d41\u91cf\u3002 PodDisruptionBudget*\u3002PodDisruptionBudget\u662f\u4e00\u4e2a\u5bf9\u8c61\uff0c\u7528\u4e8e\u5b9a\u4e49\u5bf9\u4e00\u7ec4Pod\u53ef\u80fd\u9020\u6210\u7684\u6700\u5927\u4e2d\u65ad\u3002 PodSecurityPolicy v1beta1*\u3002PodSecurityPolicy\u63a7\u5236\u5bf9\u53ef\u80fd\u5f71\u54cd\u5c06\u5e94\u7528\u4e8ePod\u548c\u5bb9\u5668\u7684\u5b89\u5168\u4e0a\u4e0b\u6587\u7684\u8bf7\u6c42\u7684\u80fd\u529b\u3002 \u6269\u5c55\u8d44\u6e90\uff08Extend Resources\uff09 CustomResourceDefinition*\u3002CustomResourceDefinition\u8868\u793a\u5e94\u5728API\u670d\u52a1\u5668\u4e0a\u516c\u5f00\u7684\u8d44\u6e90\u3002 MutatingWebhookConfiguration*\u3002MutatingWebhookConfiguration\u63cf\u8ff0\u63a5\u53d7\u6216\u62d2\u7edd\u5e76\u53ef\u80fd\u66f4\u6539\u5bf9\u8c61\u7684\u51c6\u5165Webhook\u7684\u914d\u7f6e\u3002 ValidatingWebhookConfiguration*\u3002ValidatingWebhookConfiguration\u63cf\u8ff0\u63a5\u53d7\u6216\u62d2\u7edd\u5bf9\u8c61\u4f46\u4e0d\u66f4\u6539\u5bf9\u8c61\u7684\u51c6\u5165Webhook\u7684\u914d\u7f6e\u3002 \u96c6\u7fa4\u8d44\u6e90\uff08Cluster Resources\uff09 Node*\u3002Node\u662fKubernetes\u4e2d\u7684\u5de5\u4f5c\u8282\u70b9\u3002 Namespace*\u3002Namespace\u4e3a\u540d\u79f0\u63d0\u4f9b\u4e86\u4f5c\u7528\u57df\u3002 Event*\u3002Event\u662f\u5bf9\u96c6\u7fa4\u4e2d\u67d0\u4e2a\u4f4d\u7f6e\u53d1\u751f\u4e8b\u4ef6\u7684\u62a5\u544a\u3002 APIService*\u3002APIService\u8868\u793a\u7279\u5b9aGroupVersion\u7684\u670d\u52a1\u5668\u3002 Lease*\u3002Lease\u5b9a\u4e49\u4e86\u79df\u8d41\u7684\u6982\u5ff5\u3002 RuntimeClass*\u3002RuntimeClass\u5b9a\u4e49\u4e86\u96c6\u7fa4\u4e2d\u652f\u6301\u7684\u5bb9\u5668\u8fd0\u884c\u65f6\u7c7b\u3002 FlowSchema v1beta2*\u3002FlowSchema\u5b9a\u4e49\u4e86\u4e00\u7ec4\u6d41\u7a0b\u7684\u67b6\u6784\u3002 PriorityLevelConfiguration v1beta2*\u3002PriorityLevelConfiguration\u8868\u793a\u4f18\u5148\u7ea7\u7ea7\u522b\u7684\u914d\u7f6e\u3002 Binding*\u3002Binding\u5c06\u4e00\u4e2a\u5bf9\u8c61\u7ed1\u5b9a\u5230\u53e6\u4e00\u4e2a\u5bf9\u8c61\uff1b\u4f8b\u5982\uff0c\u8c03\u5ea6\u7a0b\u5e8f\u5c06Pod\u7ed1\u5b9a\u5230\u8282\u70b9\u4e0a\u3002 ComponentStatus*\u3002ComponentStatus\uff08\u548cComponentStatusList\uff09\u4fdd\u5b58\u96c6\u7fa4\u9a8c\u8bc1\u4fe1\u606f\u3002 \u4f7f\u7528\u547d\u4ee4 kube api-resources \u83b7\u53d6\u652f\u6301\u7684API\u8d44\u6e90\u3002 \u4f7f\u7528\u547d\u4ee4 kubectl explain RESOURCE [options] \u63cf\u8ff0\u4e0e\u6bcf\u4e2a\u652f\u6301\u7684API\u8d44\u6e90\u76f8\u5173\u8054\u7684\u5b57\u6bb5\u3002\u8fd9\u4e9b\u5b57\u6bb5\u53ef\u4ee5\u901a\u8fc7\u7b80\u5355\u7684JSONPath\u6807\u8bc6\u7b26\u8fdb\u884c\u8bc6\u522b\uff1a kubectl explain binding kubectl explain binding.metadata kubectl explain binding.metadata.name \u5de5\u4f5c\u8d1f\u8f7d\u8d44\u6e90 \u00b6 Pods \u00b6 Pod\u662fKubernetes\u4e2d\u53ef\u521b\u5efa\u548c\u7ba1\u7406\u7684\u6700\u5c0f\u90e8\u7f72\u8ba1\u7b97\u5355\u4f4d\u3002 Pod\u662f\u4e00\u4e2a\u5305\u542b\u4e00\u4e2a\u6216\u591a\u4e2a\u5bb9\u5668\u3001\u5171\u4eab\u5b58\u50a8\u548c\u7f51\u7edc\u8d44\u6e90\u4ee5\u53ca\u5982\u4f55\u8fd0\u884c\u5bb9\u5668\u7684\u89c4\u8303\u7684\u7ec4\u3002 Pod\u7684\u5185\u5bb9\u59cb\u7ec8\u5171\u540c\u5b9a\u4f4d\u548c\u5171\u540c\u5b89\u6392\uff0c\u5e76\u5728\u5171\u4eab\u73af\u5883\u4e2d\u8fd0\u884c\u3002 Pod\u6a21\u62df\u4e86\u4e00\u4e2a\u7279\u5b9a\u4e8e\u5e94\u7528\u7a0b\u5e8f\u7684\u201c\u903b\u8f91\u4e3b\u673a\u201d\uff1a\u5b83\u5305\u542b\u4e00\u4e2a\u6216\u591a\u4e2a\u76f8\u5bf9\u7d27\u5bc6\u8026\u5408\u7684\u5e94\u7528\u7a0b\u5e8f\u5bb9\u5668\u3002 \u5728\u975e\u4e91\u73af\u5883\u4e2d\uff0c\u540c\u4e00\u7269\u7406\u6216\u865a\u62df\u673a\u4e0a\u6267\u884c\u7684\u5e94\u7528\u7a0b\u5e8f\u7c7b\u4f3c\u4e8e\u5728\u540c\u4e00\u903b\u8f91\u4e3b\u673a\u4e0a\u6267\u884c\u7684\u4e91\u5e94\u7528\u7a0b\u5e8f\u3002 Pod\u7684\u5171\u4eab\u73af\u5883\u662f\u4e00\u7ec4Linux\u547d\u540d\u7a7a\u95f4\u3001cgroups\u548c\u53ef\u80fd\u7684\u5176\u4ed6\u9694\u79bb\u8981\u7d20 - \u8fd9\u4e9b\u8981\u7d20\u4e0e\u9694\u79bbDocker\u5bb9\u5668\u7684\u65b9\u5f0f\u76f8\u540c\u3002 \u5728Docker\u6982\u5ff5\u65b9\u9762\uff0cPod\u7c7b\u4f3c\u4e8e\u5177\u6709\u5171\u4eab\u547d\u540d\u7a7a\u95f4\u548c\u5171\u4eab\u6587\u4ef6\u7cfb\u7edf\u5377\u7684\u4e00\u7ec4Docker\u5bb9\u5668\u3002 \u901a\u5e38\u60c5\u51b5\u4e0b\uff0c\u751a\u81f3\u662f\u5355\u4f8bPod\uff0c\u6211\u4eec\u90fd\u4e0d\u9700\u8981\u76f4\u63a5\u521b\u5efaPod\uff0c\u800c\u662f\u4f7f\u7528\u5de5\u4f5c\u8d1f\u8f7d\u8d44\u6e90\uff0c\u4f8b\u5982*Deployment*\u6216*Job*\u6765\u521b\u5efa\u5b83\u4eec\u3002\u5982\u679cPod\u9700\u8981\u8ddf\u8e2a\u72b6\u6001\uff0c\u5219\u53ef\u4ee5\u4f7f\u7528StatefulSet\u8d44\u6e90\u3002 Kubernetes\u96c6\u7fa4\u4e2d\u7684Pod\u6709\u4e24\u79cd\u4e3b\u8981\u7528\u6cd5\uff1a \u8fd0\u884c\u5355\u4e2a\u5bb9\u5668\u7684Pod\u3002 \u8fd0\u884c\u9700\u8981\u5171\u540c\u5de5\u4f5c\u7684\u591a\u4e2a\u5bb9\u5668\u7684Pod\u3002 \u201c\u6bcf\u4e2aPod\u4e00\u4e2a\u5bb9\u5668\u201d\u7684\u6a21\u578b\u662f\u6700\u5e38\u89c1\u7684Kubernetes\u7528\u4f8b\uff1b\u5728\u8fd9\u79cd\u60c5\u51b5\u4e0b\u53ef\u4ee5\u5c06Pod\u89c6\u4e3a\u5355\u4e2a\u5bb9\u5668\u7684\u5305\u88c5\u5668\uff1bKubernetes\u7ba1\u7406Pod\u800c\u4e0d\u662f\u76f4\u63a5\u7ba1\u7406\u5bb9\u5668\u3002 \u4e00\u4e2aPod\u53ef\u4ee5\u5c01\u88c5\u7531\u591a\u4e2a\u5171\u540c\u5b9a\u4f4d\u3001\u7d27\u5bc6\u8026\u5408\u4e14\u9700\u8981\u5171\u4eab\u8d44\u6e90\u7684\u5bb9\u5668\u7ec4\u6210\u7684\u5e94\u7528\u7a0b\u5e8f\u3002 \u8fd9\u4e9b\u5171\u540c\u5b9a\u4f4d\u7684\u5bb9\u5668\u5f62\u6210\u4e00\u4e2a\u5355\u4e00\u7684\u670d\u52a1\u6574\u4f53\u5355\u5143 - \u4f8b\u5982\uff0c\u4e00\u4e2a\u5bb9\u5668\u5411\u516c\u4f17\u63d0\u4f9b\u5b58\u50a8\u5728\u5171\u4eab\u5377\u4e2d\u7684\u6570\u636e\uff0c\u800c\u53e6\u4e00\u4e2a\u72ec\u7acb\u7684Sidecar\u5bb9\u5668\u5237\u65b0\u6216\u66f4\u65b0\u8fd9\u4e9b\u6587\u4ef6\u3002Pod\u5c06\u8fd9\u4e9b\u5bb9\u5668\u3001\u5b58\u50a8\u8d44\u6e90\u548c\u77ed\u6682\u7684\u7f51\u7edc\u6807\u8bc6\u5305\u88c5\u5728\u4e00\u8d77\uff0c\u4f5c\u4e3a\u4e00\u4e2a\u5355\u72ec\u7684\u5355\u4f4d\u3002 \u5728\u5355\u4e2aPod\u4e2d\u5206\u7ec4\u591a\u4e2a\u5171\u540c\u5b9a\u4f4d\u548c\u5171\u540c\u7ba1\u7406\u7684\u5bb9\u5668\u662f\u76f8\u5bf9\u9ad8\u7ea7\u7684\u7528\u4f8b\u3002\u5e94\u8be5*\u4ec5\u5728*\u5bb9\u5668\u7d27\u5bc6\u8026\u5408\u7684\u7279\u5b9a\u60c5\u51b5\u4e0b\u4f7f\u7528\u6b64\u6a21\u5f0f\u3002 \u6bcf\u4e2aPod\u90fd\u65e8\u5728\u8fd0\u884c\u7ed9\u5b9a\u5e94\u7528\u7a0b\u5e8f\u7684\u5355\u4e2a\u5b9e\u4f8b\u3002\u5982\u679c\u6211\u4eec\u60f3\u6c34\u5e73\u6269\u5c55\u60a8\u7684\u5e94\u7528\u7a0b\u5e8f\uff08\u901a\u8fc7\u8fd0\u884c\u66f4\u591a\u5b9e\u4f8b\u63d0\u4f9b\u66f4\u591a\u7684\u603b\u8d44\u6e90\uff09\uff0c\u5219\u5e94\u8be5\u4f7f\u7528\u591a\u4e2aPod\uff0c\u6bcf\u4e2a\u5b9e\u4f8b\u4e00\u4e2aPod\u3002\u5728Kubernetes\u4e2d\uff0c\u8fd9\u901a\u5e38\u79f0\u4e3a*\u590d\u5236*\u3002\u590d\u5236\u7684Pod\u901a\u5e38\u4f5c\u4e3a\u5de5\u4f5c\u8d1f\u8f7d\u8d44\u6e90\u53ca\u5176\u63a7\u5236\u5668\u7684\u4e00\u7ec4\u521b\u5efa\u548c\u7ba1\u7406\u3002 Pod\u672c\u5730\u63d0\u4f9b\u4e24\u79cd\u5171\u4eab\u8d44\u6e90\u4ee5\u4f9b\u5176\u7ec4\u6210\u5bb9\u5668\u4f7f\u7528\uff1a \u7f51\u7edc *\u548c \u5b58\u50a8 *\u3002 \u4e00\u4e2aPod\u53ef\u4ee5\u6307\u5b9a\u4e00\u7ec4\u5171\u4eab\u7684\u5b58\u50a8\u5377\u3002Pod\u4e2d\u7684\u6240\u6709\u5bb9\u5668\u90fd\u53ef\u4ee5\u8bbf\u95ee\u8fd9\u4e9b\u5171\u4eab\u5377\uff0c\u4f7f\u8fd9\u4e9b\u5bb9\u5668\u53ef\u4ee5\u5171\u4eab\u6570\u636e\u3002 \u6bcf\u4e2aPod\u4e3a\u6bcf\u4e2a\u5730\u5740\u65cf\u5206\u914d\u4e00\u4e2a\u552f\u4e00\u7684IP\u5730\u5740\u3002 \u5728\u4e00\u4e2aPod\u5185\uff0c\u5bb9\u5668\u5171\u4eab\u4e00\u4e2aIP\u5730\u5740\u548c\u7aef\u53e3\u7a7a\u95f4\uff0c\u5e76\u53ef\u4ee5\u901a\u8fc7\u201clocalhost\u201d\u627e\u5230\u5f7c\u6b64\u3002\u60f3\u8981\u4e0e\u8fd0\u884c\u5728\u4e0d\u540cPod\u4e2d\u7684\u5bb9\u5668\u4ea4\u4e92\u7684\u5bb9\u5668\u53ef\u4ee5\u4f7f\u7528IP\u7f51\u7edc\u8fdb\u884c\u901a\u4fe1\u3002 \u5f53\u521b\u5efa\u4e00\u4e2aPod\u65f6\uff0c\u65b0\u7684Pod\u88ab\u8c03\u5ea6\u5728\u96c6\u7fa4\u4e2d\u7684\u4e00\u4e2a\u8282\u70b9\u4e0a\u8fd0\u884c\u3002Pod\u4fdd\u7559\u5728\u8be5\u8282\u70b9\u4e0a\uff0c\u76f4\u5230Pod\u6267\u884c\u5b8c\u6bd5\u3001Pod\u5bf9\u8c61\u88ab\u5220\u9664\u3001Pod\u56e0\u7f3a\u4e4f\u8d44\u6e90\u800c\u88ab\u9a71\u9010\u6216\u8282\u70b9\u53d1\u751f\u6545\u969c\u3002 \u5728Pod\u4e2d\u91cd\u65b0\u542f\u52a8\u4e00\u4e2a\u5bb9\u5668\u4e0d\u5e94\u4e0e\u91cd\u65b0\u542f\u52a8\u4e00\u4e2aPod\u6df7\u6dc6\u3002Pod\u4e0d\u662f\u4e00\u4e2a\u8fdb\u7a0b\uff0c\u800c\u662f\u4e00\u4e2a\u8fd0\u884c\u5bb9\u5668\u7684\u73af\u5883\u3002Pod\u4f1a\u4e00\u76f4\u4fdd\u7559\uff0c\u76f4\u5230\u88ab\u5220\u9664\u4e3a\u6b62\u3002 \u60a8\u53ef\u4ee5\u4f7f\u7528\u5de5\u4f5c\u8d1f\u8f7d\u8d44\u6e90\uff08\u4f8b\u5982Deployment\u3001StatefulSet\u3001DaemonSet\uff09\u4e3a\u81ea\u5df1\u521b\u5efa\u548c\u7ba1\u7406\u591a\u4e2aPod\u3002\u8d44\u6e90\u7684\u63a7\u5236\u5668\u5904\u7406\u590d\u5236\u3001\u6eda\u52a8\u548c\u5728Pod\u5931\u8d25\u65f6\u7684\u81ea\u52a8\u6062\u590d\u3002 \u521d\u59cb\u5316\u5bb9\u5668 \u00b6 \u4e00\u4e9bPod\u8fd8\u6709\u521d\u59cb\u5316\u5bb9\u5668\uff08Init containers\uff09\u548c\u5e94\u7528\u5bb9\u5668\uff08app containers\uff09\u3002\u521d\u59cb\u5316\u5bb9\u5668\u5728\u5e94\u7528\u5bb9\u5668\u542f\u52a8\u4e4b\u524d\u8fd0\u884c\u5e76\u5b8c\u6210\u3002 \u6211\u4eec\u53ef\u4ee5\u5728Pod\u89c4\u8303\u4e2d\u6307\u5b9a\u521d\u59cb\u5316\u5bb9\u5668\uff0c\u540c\u65f6\u4e5f\u53ef\u4ee5\u5728\u5bb9\u5668\u6570\u7ec4\u4e2d\u63cf\u8ff0\u5e94\u7528\u5bb9\u5668\u3002 \u9759\u6001Pod \u00b6 \u9759\u6001Pod\u662f\u76f4\u63a5\u7531\u7279\u5b9a\u8282\u70b9\u4e0a\u7684kubelet\u5b88\u62a4\u7a0b\u5e8f\u7ba1\u7406\u7684\uff0cAPI\u670d\u52a1\u5668\u4e0d\u4f1a\u89c2\u5bdf\u5b83\u4eec\u3002 \u9759\u6001Pod\u59cb\u7ec8\u7ed1\u5b9a\u5230\u7279\u5b9a\u8282\u70b9\u4e0a\u7684\u4e00\u4e2aKubelet\u3002 \u9759\u6001Pod\u7684\u4e3b\u8981\u7528\u9014\u662f\u8fd0\u884c\u81ea\u6258\u7ba1\u63a7\u5236\u9762\u677f\uff1a\u6362\u53e5\u8bdd\u8bf4\uff0c\u4f7f\u7528kubelet\u76d1\u7763\u5404\u4e2a\u63a7\u5236\u9762\u677f\u7ec4\u4ef6\u3002 kubelet\u4f1a\u81ea\u52a8\u5c1d\u8bd5\u4e3a\u6bcf\u4e2a\u9759\u6001Pod\u5728Kubernetes API\u670d\u52a1\u5668\u4e0a\u521b\u5efa\u4e00\u4e2a\u955c\u50cfPod\u3002\u8fd9\u610f\u5473\u7740\u5728\u8282\u70b9\u4e0a\u8fd0\u884c\u7684Pod\u5728API\u670d\u52a1\u5668\u4e0a\u53ef\u89c1\uff0c\u4f46\u65e0\u6cd5\u4ece\u90a3\u91cc\u63a7\u5236\u3002 \u5bb9\u5668\u63a2\u9488 \u00b6 \u63a2\u9488\u662f kubelet \u5b9a\u671f\u5bf9\u5bb9\u5668\u6267\u884c\u7684\u4e00\u79cd\u8bca\u65ad\u3002 \u4e3a\u6267\u884c\u8bca\u65ad\uff0ckubelet \u8981\u4e48\u5728\u5bb9\u5668\u5185\u6267\u884c\u4ee3\u7801\uff0c\u8981\u4e48\u53d1\u8d77\u7f51\u7edc\u8bf7\u6c42\u3002 \u4f7f\u7528\u63a2\u9488\u6709\u56db\u79cd\u4e0d\u540c\u7684\u68c0\u67e5\u5bb9\u5668\u65b9\u5f0f\u3002\u6bcf\u4e2a\u63a2\u9488\u5fc5\u987b\u6070\u597d\u5b9a\u4e49\u8fd9\u56db\u79cd\u673a\u5236\u4e2d\u7684\u4e00\u79cd\uff1a exec \u3002\u5982\u679c\u547d\u4ee4\u4ee5\u72b6\u6001\u4ee3\u7801 0 \u9000\u51fa\uff0c\u5219\u5c06\u8bca\u65ad\u89c6\u4e3a\u6210\u529f\u3002 grpc \u3002\u5982\u679c\u54cd\u5e94\u7684\u72b6\u6001\u4e3a SERVING\uff0c\u5219\u5c06\u8bca\u65ad\u89c6\u4e3a\u6210\u529f\u3002 httpGet \u3002\u5982\u679c\u54cd\u5e94\u7684\u72b6\u6001\u4ee3\u7801\u5927\u4e8e\u6216\u7b49\u4e8e 200 \u4e14\u5c0f\u4e8e 400\uff0c\u5219\u5c06\u8bca\u65ad\u89c6\u4e3a\u6210\u529f\u3002 tcpSocket \u3002\u5982\u679c\u7aef\u53e3\u5f00\u653e\uff0c\u5219\u5c06\u8bca\u65ad\u89c6\u4e3a\u6210\u529f\u3002 \u6bcf\u4e2a\u63a2\u9488\u6709\u4e09\u79cd\u7ed3\u679c\uff1a \u6210\u529f \u5931\u8d25 \u672a\u77e5 \u63a2\u9488\u7c7b\u578b\uff1a livenessProbe \u3002\u6307\u793a\u5bb9\u5668\u662f\u5426\u6b63\u5728\u8fd0\u884c\u3002 readinessProbe \u3002\u6307\u793a\u5bb9\u5668\u662f\u5426\u51c6\u5907\u597d\u54cd\u5e94\u8bf7\u6c42\u3002 startupProbe \u3002\u6307\u793a\u5bb9\u5668\u5185\u7684\u5e94\u7528\u7a0b\u5e8f\u662f\u5426\u542f\u52a8\u3002 Deployment \u00b6 ReplicaSet \u00b6 ReplicaSet\u7684\u76ee\u7684\u662f\u5728\u4efb\u4f55\u65f6\u5019\u7ef4\u62a4\u4e00\u7ec4\u7a33\u5b9a\u7684\u526f\u672cPod\u3002\u56e0\u6b64\uff0c\u5b83\u901a\u5e38\u7528\u4e8e\u4fdd\u8bc1\u6307\u5b9a\u6570\u91cf\u7684\u76f8\u540cPod\u7684\u53ef\u7528\u6027\u3002 \u6211\u4eec\u4e00\u822c\u4e0d\u9700\u8981\u76f4\u63a5\u64cd\u7eb5ReplicaSet\u5bf9\u8c61\uff1a\u4f7f\u7528Deployment\uff0c\u7136\u540e\u5728spec\u90e8\u5206\u4e2d\u5b9a\u4e49\u60a8\u7684\u5e94\u7528\u7a0b\u5e8f\u3002 \u53ef\u4ee5\u901a\u8fc7\u8bbe\u7f6e replicaset.spec.replicas \u6765\u6307\u5b9a\u5e94\u540c\u65f6\u8fd0\u884c\u591a\u5c11\u4e2aPod\u3002 ReplicaSet\u5c06\u521b\u5efa/\u5220\u9664\u5176Pod\u4ee5\u5339\u914d\u6b64\u6570\u5b57\u3002 \u5982\u679c\u4e0d\u6307\u5b9a replicaset.spec.replicas \uff0c\u5219\u9ed8\u8ba4\u503c\u4e3a 1 \u3002 StatefulSet \u00b6 StatefulSet \u7279\u70b9\uff08\u53c8\u79f0\u56fa\u5b9a\u6807\u8bc6\uff09\uff1a Pod \u7684\u540d\u79f0\u5728\u521b\u5efa\u540e\u4e0d\u53ef\u53d8\u3002 DNS \u4e3b\u673a\u540d\u5728\u521b\u5efa\u540e\u4e0d\u53ef\u53d8\u3002 \u6302\u8f7d\u7684\u5377\u5728\u521b\u5efa\u540e\u4e0d\u53ef\u53d8\u3002 StatefulSet \u7684\u56fa\u5b9a\u6807\u8bc6\u5728\u5931\u8d25\u3001\u6269\u5c55\u548c\u5176\u4ed6\u64cd\u4f5c\u540e\u4e0d\u4f1a\u6539\u53d8\u3002 StatefulSet \u7684\u547d\u540d\u7ea6\u5b9a\u4e3a\uff1a - \u3002 StatefulSet \u53ef\u4ee5\u81ea\u884c\u8fdb\u884c\u6269\u5c55\uff0c\u4f46\u662f Deployment \u9700\u8981\u4f9d\u9760 ReplicaSet \u8fdb\u884c\u6269\u5c55\u3002 \u5efa\u8bae\uff1a\u5148\u5c06 StatefulSet \u51cf\u5c11\u5230 0\uff0c\u800c\u4e0d\u662f\u76f4\u63a5\u5220\u9664\u5b83\u3002 headless Service \u548c governing Service\uff1a Headless Service \u662f\u4e00\u4e2a\u666e\u901a\u7684 Kubernetes Service \u5bf9\u8c61\uff0c\u5176 spec.clusterIP \u88ab\u8bbe\u7f6e\u4e3a None \u3002 \u5f53 StatefulSet \u7684 spec.ServiceName \u8bbe\u7f6e\u4e3a headless Service \u540d\u79f0\u65f6\uff0cStatefulSet \u73b0\u5728\u662f\u4e00\u4e2a governing Service\u3002 \u521b\u5efa StatefulSet \u7684\u4e00\u822c\u8fc7\u7a0b\uff1a \u521b\u5efa StorageClass\u3002 \u521b\u5efa Headless Service\u3002 \u57fa\u4e8e\u4e0a\u8ff0\u4e24\u4e2a\u521b\u5efa StatefulSet\u3002 DaemonSet \u00b6 DaemonSet\u4fdd\u8bc1\u6240\u6709\uff08\u6216\u90e8\u5206\uff09\u8282\u70b9\u8fd0\u884cPod\u7684\u526f\u672c\u3002\u968f\u7740\u8282\u70b9\u4ece\u96c6\u7fa4\u4e2d\u5220\u9664\uff0c\u8fd9\u4e9bPod\u5c06\u88ab\u5783\u573e\u56de\u6536\u3002 \u5220\u9664DaemonSet\u5c06\u6e05\u7406\u5b83\u521b\u5efa\u7684Pod\u3002 \u4e00\u4e9b\u5178\u578bDaemonSet\u7684\u7528\u9014\u5305\u62ec\uff1a \u5728\u6bcf\u4e2a\u8282\u70b9\u4e0a\u8fd0\u884c\u96c6\u7fa4\u5b58\u50a8\u5b88\u62a4\u7a0b\u5e8f\u3002 \u5728\u6bcf\u4e2a\u8282\u70b9\u4e0a\u8fd0\u884c\u65e5\u5fd7\u6536\u96c6\u5b88\u62a4\u7a0b\u5e8f\u3002 \u5728\u6bcf\u4e2a\u8282\u70b9\u4e0a\u8fd0\u884c\u8282\u70b9\u76d1\u89c6\u5b88\u62a4\u7a0b\u5e8f\u3002 \u5728\u7b80\u5355\u7684\u60c5\u51b5\u4e0b\uff0c\u6bcf\u79cd\u7c7b\u578b\u7684\u5b88\u62a4\u7a0b\u5e8f\u5c06\u4f7f\u7528\u8986\u76d6\u6240\u6709\u8282\u70b9\u7684\u4e00\u4e2aDaemonSet\u3002 \u66f4\u590d\u6742\u7684\u8bbe\u7f6e\u53ef\u80fd\u4f1a\u4e3a\u5355\u4e2a\u5b88\u62a4\u7a0b\u5e8f\u4f7f\u7528\u591a\u4e2aDaemonSet\uff0c\u4f46\u4f7f\u7528\u4e0d\u540c\u7684\u6807\u5fd7\u548c/\u6216\u4e0d\u540c\u7684\u5185\u5b58\u548cCPU\u8bf7\u6c42\u6765\u652f\u6301\u4e0d\u540c\u7684\u786c\u4ef6\u7c7b\u578b\u3002 DaemonSet\u63a7\u5236\u5668\u8c03\u548c\u8fc7\u7a0b\u540c\u65f6\u68c0\u67e5\u73b0\u6709\u8282\u70b9\u548c\u65b0\u521b\u5efa\u7684\u8282\u70b9\u3002 \u9ed8\u8ba4\u60c5\u51b5\u4e0b\uff0cKubernetes\u8c03\u5ea6\u7a0b\u5e8f\u5ffd\u7565\u7531DamonSet\u521b\u5efa\u7684Pod\uff0c\u5e76\u5141\u8bb8\u5b83\u4eec\u5b58\u5728\u4e8e\u8282\u70b9\u4e0a\uff0c\u76f4\u5230\u5173\u95ed\u8282\u70b9\u672c\u8eab\u3002 \u5728\u9009\u62e9\u8282\u70b9\u4e0a\u8fd0\u884cPod\uff1a \u5982\u679c\u60a8\u6307\u5b9a daemonset.spec.template.spec.nodeSelector \uff0c\u90a3\u4e48DaemonSet\u63a7\u5236\u5668\u5c06\u5728\u4e0e\u8be5\u8282\u70b9\u9009\u62e9\u5668\u5339\u914d\u7684\u8282\u70b9\u4e0a\u521b\u5efaPod\u3002 \u5982\u679c\u60a8\u6307\u5b9a daemonset.spec.template.spec.affinity \uff0c\u90a3\u4e48DaemonSet\u63a7\u5236\u5668\u5c06\u5728\u4e0e\u8be5\u8282\u70b9\u4eb2\u548c\u529b\u5339\u914d\u7684\u8282\u70b9\u4e0a\u521b\u5efaPod\u3002 \u5982\u679c\u4e24\u8005\u90fd\u4e0d\u6307\u5b9a\uff0c\u5219DaemonSet\u63a7\u5236\u5668\u5c06\u5728\u6240\u6709\u8282\u70b9\u4e0a\u521b\u5efaPod\u3002 \u5728 kubectl explain daemonset.spec \u4e2d\u6ca1\u6709 replicas \u5b57\u6bb5\u4e0e kubectl explain deployment.spec.replicas \u76f8\u5bf9\u5e94\u3002\u5f53\u521b\u5efa\u4e00\u4e2aDaemonSet\u65f6\uff0c\u6bcf\u4e2a\u8282\u70b9\u5c06\u8fd0\u884c*\u4e00\u4e2a* DaemonSet Pod\u3002 \u5bf9\u4e8e\u670d\u52a1\uff0c\u901a\u5e38\u662f\u65e0\u72b6\u6001\u7684\uff0c\u4e00\u822c\u4e0d\u5173\u5fc3\u8282\u70b9\u5728\u54ea\u91cc\u8fd0\u884c\uff0c\u66f4\u5173\u5fc3Pod\u526f\u672c\u7684\u6570\u91cf\uff0c\u5e76\u4e14\u6211\u4eec\u53ef\u4ee5\u5c06\u8fd9\u4e9b\u526f\u672c/replicas\u7f29\u653e\u3002\u5728\u8fd9\u91cc\uff0c\u6eda\u52a8\u66f4\u65b0\u4e5f\u5c06\u662f\u4e00\u4e2a\u4f18\u70b9\u3002 \u5f53Pod\u7684\u4e00\u4e2a\u526f\u672c\u5fc5\u987b\u5728\u67d0\u4e2a\u6307\u5b9a\u8282\u70b9\u4e0a\u8fd0\u884c\u65f6\uff0c\u6211\u4eec\u5c06\u4f7f\u7528 DaemonSet \u3002\u6211\u4eec\u7684\u5b88\u62a4\u8fdb\u7a0bPod\u8fd8\u9700\u8981\u5728\u6211\u4eec\u7684\u5176\u4ed6Pod\u4e4b\u524d\u542f\u52a8\u3002 DaemonSet\u662f\u7528\u4e8e\u540e\u53f0\u670d\u52a1\u7684\u7b80\u5355\u53ef\u6269\u5c55\u6027\u7b56\u7565\u3002\u5f53\u66f4\u591a\u7684\u5408\u9002\u7684\u8282\u70b9\u6dfb\u52a0\u5230\u96c6\u7fa4\u65f6\uff0c\u540e\u53f0\u670d\u52a1\u5c06\u6269\u5c55\u3002\u5f53\u8282\u70b9\u88ab\u5220\u9664\u65f6\uff0c\u5b83\u5c06\u81ea\u52a8\u7f29\u5c0f\u3002 Job \u00b6 CronJob \u00b6 \u670d\u52a1\u8d44\u6e90 \u00b6 Service \u00b6 Service\u662f\u8f6f\u4ef6\u670d\u52a1\uff08\u4f8b\u5982mysql\uff09\u7684\u547d\u540d\u62bd\u8c61\uff0c\u7531\u4ee3\u7406\u76d1\u542c\u7684\u672c\u5730\u7aef\u53e3\uff08\u4f8b\u59823306\uff09\u548c\u786e\u5b9a\u54ea\u4e9bPod\u5c06\u56de\u7b54\u901a\u8fc7\u4ee3\u7406\u53d1\u9001\u7684\u8bf7\u6c42\u7684\u9009\u62e9\u5668\u7ec4\u6210\u3002 \u4e00\u4e2aService\u7684\u76ee\u6807Pod\u96c6\u5408\u901a\u5e38\u7531\u4e00\u4e2a\u9009\u62e9\u5668\uff08\u6807\u7b7e\u9009\u62e9\u5668\uff09\u6765\u786e\u5b9a\u3002 Service\u8d44\u6e90\u7684\u7c7b\u578b\u5305\u62ec\uff1a ClusterIP Service\uff08\u9ed8\u8ba4\uff09\uff1a\u53ef\u9760\u7684IP\u3001DNS\u548c\u7aef\u53e3\u3002\u4ec5\u9650\u5185\u90e8\u8bbf\u95ee\u3002 NodePort Service\uff1a\u5411\u5916\u90e8\u63d0\u4f9b\u8bbf\u95ee\u3002 LoadBalancer\uff1a\u57fa\u4e8eNodePort\uff0c\u5e76\u4e0e\u4e91\u4f9b\u5e94\u5546\u63d0\u4f9b\u7684\u8d1f\u8f7d\u5e73\u8861\u96c6\u6210\uff08\u4f8b\u5982AWS\u3001GCP\u7b49\uff09\u3002 ExternalName\uff1a\u8bbf\u95ee\u5c06\u88ab\u8f6c\u53d1\u5230\u5916\u90e8\u670d\u52a1\u3002 \u4e0b\u9762\u662f\u4e00\u4e2a\u521b\u5efa\u7b80\u5355Service\u7684yaml\u6587\u4ef6\uff1a apiVersion : v1 kind : Service metadata : name : nginx-service labels : tier : application spec : ports : - port : 80 protocol : TCP targetPort : 8080 selector : run : nginx type : NodePort \u4e0b\u9762\u662f\u4e00\u4e2aService\u7684\u4f8b\u5b50\uff1a IP 10.96.17.77 \u662f\u8be5\u670d\u52a1\u7684 ClusterIP(VIP)\u3002 \u7aef\u53e3 80/TCP \u662f Pod \u5728\u96c6\u7fa4\u5185\u76d1\u542c\u7684\u7aef\u53e3\u3002 TargetPort 8080/TCP \u662f\u5bb9\u5668\u5185\u670d\u52a1\u5e94\u8be5\u5b9a\u5411\u6d41\u91cf\u5230\u8fbe\u7684\u7aef\u53e3\u3002 NodePort 31893/TCP \u662f\u53ef\u4ee5\u4ece\u5916\u90e8\u8bbf\u95ee\u7684\u7aef\u53e3\u3002\u9ed8\u8ba4\u8303\u56f4\u662f 30000~32767 \u3002\u8be5\u7aef\u53e3\u4f1a\u5728\u6574\u4e2a\u96c6\u7fa4\u7684\u6240\u6709\u8282\u70b9\u4e0a\u66b4\u9732\u3002 Endpoints \u663e\u793a\u4e86\u5339\u914d\u670d\u52a1\u6807\u7b7e\u7684 Pod \u5217\u8868\u3002 Name : nginx-deployment Namespace : jh-namespace Labels : tier=application Annotations : Selector : run=nginx Type : NodePort IP Family Policy : SingleStack IP Families : IPv4 IP : 10.96.17.77 IPs : 10.96.17.77 Port : 80/TCP TargetPort : 8080/TCP NodePort : 31893/TCP Endpoints : 10.244.1.177:8080,10.244.1.178:8080,10.244.1.179:8080 + 7 more... Session Affinity : None External Traffic Policy : Cluster Events : \u5728 Kubernetes \u96c6\u7fa4\u4e2d\uff0c\u57fa\u4e8eDeployment coredns \u7684Service kube-dns \u63d0\u4f9b\u4e86\u96c6\u7fa4 DNS \u670d\u52a1\u3002 \u670d\u52a1\u6ce8\u518c\uff1a Kubernetes \u4f7f\u7528\u96c6\u7fa4 DNS \u4f5c\u4e3a\u670d\u52a1\u6ce8\u518c\u3002 \u6ce8\u518c\u662f\u57fa\u4e8e Service \u800c\u975e Pod \u7684\u3002 \u96c6\u7fa4 DNS\uff08CoreDNS\uff09\u4e3b\u52a8\u76d1\u89c6\u548c\u53d1\u73b0\u65b0\u670d\u52a1\u3002 Service \u540d\u79f0\u3001IP\u3001\u7aef\u53e3\u5c06\u88ab\u6ce8\u518c\u3002 Service \u6ce8\u518c\u7684\u8fc7\u7a0b\u5982\u4e0b\uff1a \u5c06\u65b0\u7684 Service POST \u5230 API Server\u3002 \u4e3a\u65b0\u7684 Service \u5206\u914d ClusterIP\u3002 \u5c06\u65b0\u7684 Service \u914d\u7f6e\u4fe1\u606f\u4fdd\u5b58\u5230 etcd \u4e2d\u3002 \u521b\u5efa\u4e0e\u65b0 Service \u5173\u8054\u7684\u5e26\u6709\u76f8\u5173 Pod IP \u7684 endpoints\u3002 \u901a\u8fc7 ClusterDNS \u63a2\u7d22\u65b0\u7684 Service\u3002 \u521b\u5efa DNS \u4fe1\u606f\u3002 kube-proxy \u83b7\u53d6 Service \u914d\u7f6e\u4fe1\u606f\u3002 \u521b\u5efa IPSV \u89c4\u5219\u3002 Service \u53d1\u73b0\u7684\u8fc7\u7a0b\u3002 \u8bf7\u6c42\u4e00\u4e2a Service \u540d\u79f0\u7684 DNS \u540d\u79f0\u89e3\u6790\u3002 \u6536\u5230 ClusterIP\u3002 \u8bbf\u95ee ClusterIP\u3002 \u6ca1\u6709\u8def\u7531\u5668\u3002\u5c06\u8bf7\u6c42\u8f6c\u53d1\u5230 Pod \u7684\u9ed8\u8ba4\u7f51\u5173\u3002 \u5c06\u8bf7\u6c42\u8f6c\u53d1\u5230\u8282\u70b9\u3002 \u6ca1\u6709\u8def\u7531\u5668\u3002\u5c06\u8bf7\u6c42\u8f6c\u53d1\u5230\u8282\u70b9\u7684\u9ed8\u8ba4\u7f51\u5173\u3002 \u8282\u70b9\u5185\u6838\u7ee7\u7eed\u5904\u7406\u8bf7\u6c42\u3002 \u4f7f\u7528 IPSV \u89c4\u5219\u6355\u83b7\u8bf7\u6c42\u3002 \u5c06\u76ee\u6807 Pod \u7684 IP \u653e\u5165\u8bf7\u6c42\u7684\u76ee\u6807 IP \u4e2d\u3002 \u8bf7\u6c42\u5230\u8fbe\u76ee\u6807 Pod\u3002 FQDN\u683c\u5f0f\u4e3a\uff1a ..svc.cluster.local \u3002\u6211\u4eec\u79f0 \u4e3a\u975e\u9650\u5b9a\u540d\u79f0\u6216\u7b80\u77ed\u540d\u79f0\u3002 \u547d\u540d\u7a7a\u95f4\u53ef\u4ee5\u9694\u79bb\u96c6\u7fa4\u7684\u5730\u5740\u7a7a\u95f4\u3002\u540c\u65f6\uff0c\u5b83\u8fd8\u53ef\u4ee5\u7528\u4e8e\u5b9e\u73b0\u8bbf\u95ee\u63a7\u5236\u548c\u8d44\u6e90\u914d\u989d\u3002 \u83b7\u53d6Pod\u4e2d\u7684DNS\u914d\u7f6e\u3002 nameserver\u7684IP\u4e0ekube-dns\u670d\u52a1\u7684ClusterIP\u76f8\u540c\uff0c\u8fd9\u662f\u7528\u4e8eDNS\u8bf7\u6c42\u6216\u670d\u52a1\u53d1\u73b0\u8bf7\u6c42\u7684\u4f17\u6240\u5468\u77e5\u7684IP\u3002 $ kubectl get service kube-dns -n kube-system NAME TYPE CLUSTER-IP EXTERNAL-IP PORT ( S ) AGE kube-dns ClusterIP 10 .96.0.10 53 /UDP,53/TCP,9153/TCP 7d7h $ kubectl exec -it nginx-5f5496dc9-bv5dx -- /bin/bash root@nginx-5f5496dc9-bv5dx:/# cat /etc/resolv.conf search jh-namespace.svc.cluster.local svc.cluster.local cluster.local nameserver 10 .96.0.10 options ndots:5 \u8bfb\u53d6 kube-dns \u4fe1\u606f\uff1a $ kubectl describe service kube-dns -n kube-system Name: kube-dns Namespace: kube-system Labels: k8s-app = kube-dns kubernetes.io/cluster-service = true kubernetes.io/name = CoreDNS Annotations: prometheus.io/port: 9153 prometheus.io/scrape: true Selector: k8s-app = kube-dns Type: ClusterIP IP Family Policy: SingleStack IP Families: IPv4 IP: 10 .96.0.10 IPs: 10 .96.0.10 Port: dns 53 /UDP TargetPort: 53 /UDP Endpoints: 10 .244.0.2:53,10.244.0.3:53 Port: dns-tcp 53 /TCP TargetPort: 53 /TCP Endpoints: 10 .244.0.2:53,10.244.0.3:53 Port: metrics 9153 /TCP TargetPort: 9153 /TCP Endpoints: 10 .244.0.2:9153,10.244.0.3:9153 Session Affinity: None Events: Endpoints \u00b6 Endpoints\u662f\u4e00\u7ec4\u5b9e\u73b0\u5b9e\u9645\u670d\u52a1\u7684\u7aef\u70b9\u96c6\u5408\u3002 \u5f53\u521b\u5efa\u670d\u52a1\u65f6\uff0c\u5b83\u4f1a\u4e0e\u4e00\u4e2aEndpoint\u5bf9\u8c61\u76f8\u5173\u8054\uff0c\u53ef\u4ee5\u4f7f\u7528\u547d\u4ee4 kubectl get endpoints \u83b7\u53d6\u3002 \u5339\u914d\u670d\u52a1\u6807\u7b7e\u7684Pod\u5217\u8868\u7ef4\u62a4\u4e3aEndpoint\u5bf9\u8c61\uff0c\u6dfb\u52a0\u65b0\u7684\u5339\u914dPod\u5e76\u5220\u9664\u4e0d\u5339\u914d\u7684Pod\u3002 \u914d\u7f6e\u548c\u5b58\u50a8\u8d44\u6e90 \u00b6 \u5377 \u00b6 emptyDir \u00b6 emptyDir \u5377\u662f\u5728Pod\u5206\u914d\u5230\u8282\u70b9\u65f6\u9996\u5148\u521b\u5efa\u7684\uff0c\u5e76\u4e14\u53ea\u8981\u8be5Pod\u5728\u8be5\u8282\u70b9\u4e0a\u8fd0\u884c\uff0c\u5b83\u5c31\u4f1a\u5b58\u5728\u3002 emptyDir \u5377\u6700\u521d\u4e3a\u7a7a\u3002 Pod\u4e2d\u7684\u6240\u6709\u5bb9\u5668\u90fd\u53ef\u4ee5\u8bfb\u53d6\u548c\u5199\u5165 emptyDir \u5377\u4e2d\u7684\u76f8\u540c\u6587\u4ef6\uff0c\u5c3d\u7ba1\u8be5\u5377\u53ef\u4ee5\u5728\u6bcf\u4e2a\u5bb9\u5668\u4e2d\u4ee5\u76f8\u540c\u6216\u4e0d\u540c\u7684\u8def\u5f84\u6302\u8f7d\u3002 \u5f53\u7531\u4e8e\u4efb\u4f55\u539f\u56e0\u4ece\u8282\u70b9\u4e2d\u5220\u9664Pod\u65f6\uff0c emptyDir \u4e2d\u7684\u6570\u636e\u5c06\u6c38\u4e45\u5220\u9664\u3002 \u5bb9\u5668\u5d29\u6e83\u4e0d\u4f1a\u5c06Pod\u4ece\u8282\u70b9\u4e2d\u5220\u9664\u3002 emptyDir \u5377\u4e2d\u7684\u6570\u636e\u53ef\u4ee5\u5728\u5bb9\u5668\u5d29\u6e83\u65f6\u5b89\u5168\u4fdd\u7559\u3002 \u7528\u9014\uff1a \u4e34\u65f6\u7a7a\u95f4\uff0c\u4f8b\u5982\u57fa\u4e8e\u78c1\u76d8\u7684\u5f52\u5e76\u6392\u5e8f \u4e3a\u4e86\u4ece\u5d29\u6e83\u4e2d\u6062\u590d\u800c\u8fdb\u884c\u7684\u957f\u65f6\u95f4\u8ba1\u7b97\u7684\u68c0\u67e5\u70b9 \u4fdd\u5b58\u5185\u5bb9\u7ba1\u7406\u5668\u5bb9\u5668\u63d0\u53d6\u7684\u6587\u4ef6\uff0c\u540c\u65f6Web\u670d\u52a1\u5668\u5bb9\u5668\u63d0\u4f9b\u6570\u636e hostPath \u00b6 hostPath \u5377\u5c06\u4e3b\u673a\u8282\u70b9\u6587\u4ef6\u7cfb\u7edf\u4e2d\u7684\u6587\u4ef6\u6216\u76ee\u5f55\u6302\u8f7d\u5230 Pod \u4e2d\u3002\u8fd9\u4e0d\u662f\u5927\u591a\u6570 Pod \u90fd\u9700\u8981\u7684\uff0c\u4f46\u5bf9\u4e8e\u67d0\u4e9b\u5e94\u7528\u7a0b\u5e8f\u6765\u8bf4\uff0c\u5b83\u63d0\u4f9b\u4e86\u4e00\u4e2a\u5f3a\u5927\u7684\u9003\u751f\u53e3\u3002 hostPath \u5377\u5b58\u5728\u8bb8\u591a\u5b89\u5168\u98ce\u9669\uff0c\u56e0\u6b64\u5728\u53ef\u80fd\u7684\u60c5\u51b5\u4e0b\u6700\u597d\u907f\u514d\u4f7f\u7528 HostPath\u3002\u5f53\u5fc5\u987b\u4f7f\u7528 HostPath \u5377\u65f6\uff0c\u5e94\u5c06\u5176\u8303\u56f4\u9650\u5b9a\u4e3a\u4ec5\u6240\u9700\u7684\u6587\u4ef6\u6216\u76ee\u5f55\uff0c\u5e76\u4ee5\u53ea\u8bfb\u65b9\u5f0f\u6302\u8f7d\u3002 \u5982\u679c\u901a\u8fc7 AdmissionPolicy \u9650\u5236 HostPath \u8bbf\u95ee\u7279\u5b9a\u76ee\u5f55\uff0c\u5219\u5fc5\u987b\u8981\u6c42 volumeMounts \u4f7f\u7528 readOnly \u6302\u8f7d\uff0c\u4ee5\u4f7f\u7b56\u7565\u751f\u6548\u3002 \u7528\u9014\uff1a \u4e0e DaemonSet \u4e00\u8d77\u8fd0\u884c\uff0c\u4f8b\u5982\uff0cEFK Fluentd \u6302\u8f7d\u672c\u5730\u4e3b\u673a\u7684\u65e5\u5fd7\u76ee\u5f55\u4ee5\u6536\u96c6\u4e3b\u673a\u65e5\u5fd7\u4fe1\u606f\u3002 \u901a\u8fc7\u4f7f\u7528 hostPath \u5377\u5728\u7279\u5b9a\u8282\u70b9\u4e0a\u8fd0\u884c\uff0c\u53ef\u4ee5\u83b7\u5f97\u9ad8\u6027\u80fd\u7684\u78c1\u76d8 I/O\u3002 \u8fd0\u884c\u9700\u8981\u8bbf\u95ee Docker \u5185\u90e8\u7684\u5bb9\u5668\uff1b\u4f7f\u7528 /var/lib/docker \u7684 hostPath\u3002 \u5728\u5bb9\u5668\u4e2d\u8fd0\u884c cAdvisor\uff1b\u4f7f\u7528 /sys \u7684 hostPath\u3002 \u5141\u8bb8 Pod \u6307\u5b9a\u7ed9\u5b9a\u7684 hostPath \u662f\u5426\u5e94\u8be5\u5728 Pod \u8fd0\u884c\u4e4b\u524d\u5b58\u5728\uff0c\u662f\u5426\u5e94\u8be5\u521b\u5efa\u5b83\u4ee5\u53ca\u5b83\u5e94\u8be5\u5b58\u5728\u7684\u5185\u5bb9\u3002 Storage Class \u00b6 StorageClass \u90e8\u7f72\u548c\u5b9e\u73b0\u7684\u6b65\u9aa4\u5982\u4e0b\uff1a \u521b\u5efa Kubernetes \u96c6\u7fa4\u548c\u540e\u7aef\u5b58\u50a8\u3002 \u786e\u4fdd Kubernetes \u4e2d\u7684 provisioner/plugin \u53ef\u7528\u3002 \u521b\u5efa\u4e00\u4e2a StorageClass \u5bf9\u8c61\u5e76\u5c06\u5176\u94fe\u63a5\u5230\u540e\u7aef\u5b58\u50a8\u3002StorageClass \u5c06\u81ea\u52a8\u521b\u5efa\u76f8\u5173\u7684 PV\u3002 \u521b\u5efa\u4e00\u4e2a PVC \u5bf9\u8c61\u5e76\u5c06\u5176\u94fe\u63a5\u5230\u6211\u4eec\u521b\u5efa\u7684 StorageClass\u3002 \u90e8\u7f72\u4e00\u4e2a Pod \u5e76\u4f7f\u7528 PVC \u5377\u3002 PV \u00b6 PV\u56de\u6536\u7b56\u7565\uff1a \u4fdd\u7559 (Retain) \u5220\u9664 (Delete) \u56de\u6536 (Recycle) PV in-tree\u7c7b\u578b\uff1a hostPath local NFS CSI Access Modes \u00b6 Access Modes\uff08\u8bbf\u95ee\u6a21\u5f0f\uff09\u4e2d\uff0c spec.accessModes \u5b9a\u4e49\u4e86 PV \u7684\u6302\u8f7d\u9009\u9879\uff1a ReadWriteOnce(RWO)\uff1a\u4e00\u4e2a PV \u53ea\u80fd\u88ab\u4e00\u4e2a\u8bfb\u5199\u6a21\u5f0f\u7684 PVC \u6302\u8f7d\uff0c\u7c7b\u4f3c\u4e8e\u5757\u8bbe\u5907\u3002 ReadWriteMany(RWM)\uff1a\u4e00\u4e2a PV \u53ef\u4ee5\u88ab\u591a\u4e2a\u8bfb\u5199\u6a21\u5f0f\u7684 PVC \u6302\u8f7d\uff0c\u4f8b\u5982 NFS\u3002 ReadOnlyMany(ROM)\uff1a\u4e00\u4e2a PV \u53ef\u4ee5\u88ab\u591a\u4e2a\u53ea\u8bfb\u6a21\u5f0f\u7684 PVC \u6302\u8f7d\u3002 ReadWriteOncePod(RWOP)\uff1a\u53ea\u652f\u6301 CSI \u7c7b\u578b\u7684 PV\uff0c\u53ea\u80fd\u88ab\u5355\u4e2a Pod \u6302\u8f7d\u3002 \u4e00\u4e2a PV \u53ea\u80fd\u8bbe\u7f6e\u4e00\u79cd\u9009\u9879\u3002Pod \u6302\u8f7d PVC\uff0c\u800c\u4e0d\u662f PV\u3002","title":"Kubernetes\u968f\u7b14"},{"location":"k8s/cka_cn/foundamentals/memo/#cka5kubernetes","text":"","title":"CKA\u81ea\u5b66\u7b14\u8bb05:Kubernetes\u968f\u7b14"},{"location":"k8s/cka_cn/foundamentals/memo/#_1","text":"\u8fb9\u7ec3\u4e60\u8fb9\u8bb0\u5f55\u7684\u5185\u5bb9\uff0c\u4e0d\u662f\u5168\u9762\u7cfb\u7edf\u7684\uff0c\u5305\u62ec\u4e0b\u9762\u4e3b\u8981\u5185\u5bb9\uff1a Kubernetes\u57fa\u672c\u6982\u5ff5 \u7ec4\u4ef6 API \u5bf9\u8c61 \u8d44\u6e90 \u5de5\u4f5c\u8d1f\u8f7d\u8d44\u6e90 Pod Deployment ReplicaSet StatefulSet DaemonSet Job CronJob \u670d\u52a1\u8d44\u6e90 Service Endpoints \u914d\u7f6e\u548c\u5b58\u50a8\u8d44\u6e90 \u5377 Storage Class PV Access Modes","title":"\u6458\u8981"},{"location":"k8s/cka_cn/foundamentals/memo/#kubernetes","text":"","title":"Kubernetes\u57fa\u672c\u6982\u5ff5"},{"location":"k8s/cka_cn/foundamentals/memo/#kubernetes_1","text":"\u4e00\u4e2aKubernetes\u96c6\u7fa4\u7531\u4ee3\u8868\u63a7\u5236\u5e73\u9762\uff08control plane\uff09\u7684\u7ec4\u4ef6\u548c\u4e00\u7ec4\u79f0\u4e3a\u8282\u70b9\uff08nodes\uff09\u7684\u673a\u5668\u7ec4\u6210\u3002 Kubernetes\u7ec4\u4ef6: \u63a7\u5236\u5e73\u9762\u7ec4\u4ef6 Control Plane Components kube-apiserver: \u67e5\u8be2\u548c\u64cd\u4f5c Kubernetes \u4e2d\u5bf9\u8c61\u7684\u72b6\u6001\u3002 \u5145\u5f53\u6240\u6709\u8d44\u6e90\u4e4b\u95f4\u7684\u901a\u4fe1\u4e2d\u5fc3\uff08communication hub\uff09\u3002 \u63d0\u4f9b\u96c6\u7fa4\u5b89\u5168\u8eab\u4efd\u9a8c\u8bc1\u3001\u6388\u6743\u548c\u89d2\u8272\u5206\u914d\u3002 \u662f\u552f\u4e00\u80fd\u8fde\u63a5\u5230 etcd \u7684\u7ec4\u4ef6\u3002 etcd: \u6240\u6709 Kubernetes \u5bf9\u8c61\u90fd\u5b58\u50a8\u5728 etcd \u4e2d\u3002 Kubernetes \u5bf9\u8c61\u662f Kubernetes \u7cfb\u7edf\u4e2d\u7684\u6301\u4e45\u5b9e\u4f53(entities)\uff0c\u7528\u4e8e\u8868\u793a\u96c6\u7fa4\u7684\u72b6\u6001\u3002 kube-scheduler: \u76d1\u89c6\u6ca1\u6709\u5206\u914d\u8282\u70b9\u7684\u65b0\u521b\u5efa\u7684 Pod\uff0c\u5e76\u4e3a\u5b83\u4eec\u9009\u62e9\u4e00\u4e2a\u8282\u70b9\u6765\u8fd0\u884c\u3002 kube-controller-manager: \u8fd0\u884c\u63a7\u5236\u5668\u8fdb\u7a0b\u3002 Node controller : \u8d1f\u8d23\u8b66\u793a\u548c\u54cd\u5e94\u8282\u70b9\u7684\u6545\u969c\u3002 Job controller : \u76d1\u89c6\u8868\u793a\u4e00\u6b21\u6027\u4efb\u52a1\u7684 Job \u5bf9\u8c61\uff0c\u7136\u540e\u521b\u5efa Pod \u6765\u5b8c\u6210\u8fd9\u4e9b\u4efb\u52a1\u3002 Endpoints controller : \u586b\u5145 Endpoints \u5bf9\u8c61\uff08\u5373\u5c06 Service \u548c Pod \u8fde\u63a5\u8d77\u6765\uff09\u3002 Service Account & Token controllers : \u4e3a\u65b0\u547d\u540d\u7a7a\u95f4\u521b\u5efa\u9ed8\u8ba4\u5e10\u6237\u548c API \u8bbf\u95ee\u4ee4\u724c\u3002 cloud-controller-manager: \u5d4c\u5165\u4e91\u7279\u5b9a\u7684\u63a7\u5236\u903b\u8f91\uff0c\u4ec5\u8fd0\u884c\u7279\u5b9a\u4e8e\u6211\u4eec\u9009\u62e9\u7684\u4e91\u63d0\u4f9b\u5546\u7684\u63a7\u5236\u5668\uff0c\u65e0\u9700\u81ea\u5df1\u7684\u57fa\u7840\u8bbe\u65bd\u548c\u5b66\u4e60\u73af\u5883\u3002 Node controller : \u7528\u4e8e\u68c0\u67e5\u4e91\u63d0\u4f9b\u5546\uff0c\u4ee5\u786e\u5b9a\u8282\u70b9\u5728\u5728\u5b83\u505c\u6b62\u54cd\u5e94\u540e\u662f\u5426\u5df2\u5728\u4e91\u4e2d\u88ab\u5220\u9664\u3002 Route controller : \u7528\u4e8e\u5728\u5e95\u5c42\u4e91\u57fa\u7840\u67b6\u6784\u4e2d\u8bbe\u7f6e\u8def\u7531\u3002 Service controller : \u7528\u4e8e\u521b\u5efa\u3001\u66f4\u65b0\u548c\u5220\u9664\u4e91\u63d0\u4f9b\u5546\u8d1f\u8f7d\u5747\u8861\u5668\u3002 \u8282\u70b9\u7ec4\u4ef6 Node Components kubelet: \u5728\u96c6\u7fa4\u4e2d\u6bcf\u4e2a\u8282\u70b9\u4e0a\u8fd0\u884c\u7684\u4ee3\u7406\u3002 \u7ba1\u7406\u8282\u70b9\u3002\u5b83\u786e\u4fdd Pod \u4e2d\u8fd0\u884c\u5bb9\u5668\u3002 kubelet \u5411 APIServer \u6ce8\u518c\u548c\u66f4\u65b0\u8282\u70b9\u4fe1\u606f\uff0cAPIServer \u5c06\u5b83\u4eec\u5b58\u50a8\u5230 etcd \u4e2d\u3002 \u7ba1\u7406 Pod\u3002\u901a\u8fc7 APIServer \u76d1\u89c6 Pod\uff0c\u5e76\u5bf9 Pod \u6216 Pod \u4e2d\u7684\u5bb9\u5668\u91c7\u53d6\u884c\u52a8\u3002 \u5728\u5bb9\u5668\u7ea7\u522b\u8fdb\u884c\u5065\u5eb7\u68c0\u67e5\u3002 kube-proxy: \u662f\u5728\u96c6\u7fa4\u4e2d\u6bcf\u4e2a\u8282\u70b9\u4e0a\u8fd0\u884c\u7684\u7f51\u7edc\u4ee3\u7406\u3002 iptables ipvs \u7ef4\u62a4\u8282\u70b9\u4e0a\u7684\u7f51\u7edc\u89c4\u5219\u3002 \u5bb9\u5668\u8fd0\u884c\u65f6Container runtime\uff1a \u8d1f\u8d23\u8fd0\u884c\u5bb9\u5668\u7684\u8f6f\u4ef6\u3002 \u63d2\u4ef6Addons DNS: \u662f DNS \u670d\u52a1\u5668\uff0c\u662f\u6240\u6709 Kubernetes \u96c6\u7fa4\u6240\u5fc5\u9700\u7684\u3002 Web UI\uff08\u4eea\u8868\u76d8\uff09\uff1a\u7528\u4e8e Kubernetes \u96c6\u7fa4\u7684\u57fa\u4e8e Web \u7684\u7528\u6237\u754c\u9762\u3002 \u5bb9\u5668\u8d44\u6e90\u76d1\u63a7\uff1a\u8bb0\u5f55\u6709\u5173\u96c6\u4e2d\u5f0f\u6570\u636e\u5e93\u4e2d\u5bb9\u5668\u7684\u901a\u7528\u65f6\u95f4\u5e8f\u5217\u5ea6\u91cf\u3002 Cluster-level Logging\uff1a\u8d1f\u8d23\u5c06\u5bb9\u5668\u65e5\u5fd7\u4fdd\u5b58\u5230\u5177\u6709\u641c\u7d22/\u6d4f\u89c8\u63a5\u53e3\u7684\u4e2d\u592e\u65e5\u5fd7\u5b58\u50a8\u4e2d\u3002 \u53ef\u6269\u5c55\u6027\uff1a \u6c34\u5e73\u6269\u5c55\uff08Scaling out\uff09\u901a\u8fc7\u6dfb\u52a0\u66f4\u591a\u7684\u670d\u52a1\u5668\u5230\u67b6\u6784\u4e2d\uff0c\u5c06\u5de5\u4f5c\u8d1f\u8f7d\u5206\u6563\u5230\u66f4\u591a\u7684\u673a\u5668\u4e0a\u3002 \u5782\u76f4\u6269\u5c55\uff08Scaling up\uff09\u901a\u8fc7\u6dfb\u52a0\u66f4\u591a\u7684\u786c\u76d8\u548c\u5185\u5b58\u6765\u589e\u52a0\u7269\u7406\u670d\u52a1\u5668\u7684\u8ba1\u7b97\u80fd\u529b\u3002","title":"Kubernetes\u7ec4\u4ef6"},{"location":"k8s/cka_cn/foundamentals/memo/#kubernetes-api","text":"REST API\u662fKubernetes\u7684\u57fa\u672c\u6846\u67b6\u3002\u6240\u6709\u7ec4\u4ef6\u4e4b\u95f4\u7684\u64cd\u4f5c\u548c\u901a\u4fe1\uff0c\u4ee5\u53ca\u5916\u90e8\u7528\u6237\u547d\u4ee4\u90fd\u662f\u7531API\u670d\u52a1\u5668\u5904\u7406\u7684REST API\u8c03\u7528\u3002\u56e0\u6b64\uff0cKubernetes\u5e73\u53f0\u4e2d\u7684\u6240\u6709\u5185\u5bb9\u90fd\u88ab\u89c6\u4e3aAPI\u5bf9\u8c61\uff08API object\uff09\uff0c\u5e76\u5728API\u4e2d\u6709\u76f8\u5e94\u7684\u6761\u76ee\u3002 Kubernetes\u63a7\u5236\u5e73\u9762\u7684\u6838\u5fc3\u662fAPI\u670d\u52a1\u5668\u3002 CRI\uff1a\u5bb9\u5668\u8fd0\u884c\u65f6\u63a5\u53e3 CNI\uff1a\u5bb9\u5668\u7f51\u7edc\u63a5\u53e3 CSI\uff1a\u5bb9\u5668\u5b58\u50a8\u63a5\u53e3 API\u670d\u52a1\u5668\u516c\u5f00\u4e86\u4e00\u4e2aHTTP API\uff0c\u5141\u8bb8\u6700\u7ec8\u7528\u6237\u3001\u96c6\u7fa4\u7684\u4e0d\u540c\u90e8\u5206\u548c\u5916\u90e8\u7ec4\u4ef6\u5f7c\u6b64\u901a\u4fe1\u3002 Kubernetes API\u5141\u8bb8\u6211\u4eec\u67e5\u8be2\u548c\u64cd\u4f5cKubernetes\u4e2dAPI\u5bf9\u8c61\u7684\u72b6\u6001\uff08\u4f8b\u5982\uff1aPod\u3001Namespace\u3001ConfigMap\u548cEvent\uff09\u3002 Kubernetes API\uff1a OpenAPI\u89c4\u8303 OpenAPI V2 OpenAPI V3 \u6301\u4e45\u6027\u3002Kubernetes\u901a\u8fc7\u5c06\u5bf9\u8c61\u7684\u5e8f\u5217\u5316\u72b6\u6001\u5199\u5165etcd\u6765\u5b58\u50a8\u5b83\u4eec\u3002 API\u7ec4\u548c\u7248\u672c\u63a7\u5236\u3002\u7248\u672c\u63a7\u5236\u662f\u5728API\u7ea7\u522b\u8fdb\u884c\u7684\u3002API\u8d44\u6e90\u901a\u8fc7\u5b83\u4eec\u7684API\u7ec4\u3001\u8d44\u6e90\u7c7b\u578b\u3001\u547d\u540d\u7a7a\u95f4\uff08\u7528\u4e8e\u547d\u540d\u7a7a\u95f4\u8d44\u6e90\uff09\u548c\u540d\u79f0\u8fdb\u884c\u533a\u5206\u3002 API\u66f4\u6539 API\u6269\u5c55","title":"Kubernetes API"},{"location":"k8s/cka_cn/foundamentals/memo/#api-version","text":"API\u7248\u672c\u548c\u8f6f\u4ef6\u7248\u672c\u95f4\u5b58\u5728\u95f4\u63a5\u5173\u7cfb\u3002API\u548c\u53d1\u5e03\u7248\u672c\u8ba1\u5212\u63cf\u8ff0\u4e86API\u7248\u672c\u548c\u8f6f\u4ef6\u7248\u672c\u4e4b\u95f4\u7684\u5173\u7cfb\u3002\u4e0d\u540c\u7684API\u7248\u672c\u8868\u793a\u4e0d\u540c\u7684\u7a33\u5b9a\u6027\u548c\u652f\u6301\u7ea7\u522b\u3002 \u4ee5\u4e0b\u662f\u6bcf\u4e2a\u7ea7\u522b\u7684\u6458\u8981\uff1a Alpha\uff1a \u7248\u672c\u540d\u79f0\u5305\u542balpha\uff08\u4f8b\u5982\uff0cv1alpha1\uff09\u3002 \u8f6f\u4ef6\u53ef\u80fd\u5305\u542b\u9519\u8bef\u3002\u542f\u7528\u529f\u80fd\u53ef\u80fd\u4f1a\u66b4\u9732\u9519\u8bef\u3002\u67d0\u4e9b\u529f\u80fd\u53ef\u80fd\u9ed8\u8ba4\u7981\u7528\u3002 \u5bf9\u4e8e\u67d0\u4e9b\u529f\u80fd\u7684\u652f\u6301\u53ef\u4ee5\u968f\u65f6\u53d6\u6d88\uff0c\u800c\u4e0d\u4f1a\u63d0\u524d\u901a\u77e5\u3002 API\u53ef\u80fd\u4f1a\u5728\u4ee5\u540e\u7684\u8f6f\u4ef6\u53d1\u5e03\u4e2d\u4ee5\u4e0d\u517c\u5bb9\u7684\u65b9\u5f0f\u66f4\u6539\uff0c\u800c\u4e0d\u4f1a\u63d0\u524d\u901a\u77e5\u3002 \u7531\u4e8e\u9519\u8bef\u98ce\u9669\u589e\u52a0\u548c\u957f\u671f\u652f\u6301\u4e0d\u8db3\uff0c\u5efa\u8bae\u4ec5\u5728\u77ed\u6682\u7684\u6d4b\u8bd5\u96c6\u7fa4\u4e2d\u4f7f\u7528\u8be5\u8f6f\u4ef6\u3002 Beta\uff1a \u7248\u672c\u540d\u79f0\u5305\u542bbeta\uff08\u4f8b\u5982\uff0cv2beta3\uff09\u3002 \u8f6f\u4ef6\u7ecf\u8fc7\u5145\u5206\u6d4b\u8bd5\u3002\u542f\u7528\u529f\u80fd\u88ab\u8ba4\u4e3a\u662f\u5b89\u5168\u7684\u3002\u67d0\u4e9b\u529f\u80fd\u9ed8\u8ba4\u542f\u7528\u3002 \u5bf9\u4e8e\u67d0\u4e9b\u529f\u80fd\u7684\u652f\u6301\u4e0d\u4f1a\u53d6\u6d88\uff0c\u4f46\u7ec6\u8282\u53ef\u80fd\u4f1a\u66f4\u6539\u3002 \u5bf9\u8c61\u7684\u6a21\u5f0f\u548c/\u6216\u8bed\u4e49\u53ef\u80fd\u4f1a\u5728\u540e\u7eed\u7684Beta\u6216\u7a33\u5b9a\u7248\u53d1\u5e03\u4e2d\u4ee5\u4e0d\u517c\u5bb9\u7684\u65b9\u5f0f\u66f4\u6539\u3002\u5f53\u53d1\u751f\u8fd9\u79cd\u60c5\u51b5\u65f6\uff0c\u5c06\u63d0\u4f9b\u8fc1\u79fb\u8bf4\u660e\u3002\u6a21\u5f0f\u66f4\u6539\u53ef\u80fd\u9700\u8981\u5220\u9664\u3001\u7f16\u8f91\u548c\u91cd\u65b0\u521b\u5efa API\u5bf9\u8c61\u3002\u7f16\u8f91\u8fc7\u7a0b\u53ef\u80fd\u4e0d\u7b80\u5355\u3002\u8fc1\u79fb\u53ef\u80fd\u9700\u8981\u505c\u673a\uff0c\u4ee5\u4fbf\u4f9d\u8d56\u4e8e\u8be5\u529f\u80fd\u7684\u5e94\u7528\u7a0b\u5e8f\u3002 \u4e0d\u5efa\u8bae\u5c06\u8be5\u8f6f\u4ef6\u7528\u4e8e\u751f\u4ea7\u7528\u9014\u3002\u540e\u7eed\u7684\u53d1\u5e03\u53ef\u80fd\u4f1a\u5f15\u5165\u4e0d\u517c\u5bb9\u7684\u66f4\u6539\u3002\u5982\u679c\u60a8\u6709\u591a\u4e2a\u53ef\u4ee5\u72ec\u7acb\u5347\u7ea7\u7684\u96c6\u7fa4\uff0c\u5219\u53ef\u4ee5\u653e\u5bbd\u6b64\u9650\u5236\u3002 \u6ce8\u610f\uff1a\u8bf7\u5c1d\u8bd5beta\u529f\u80fd\u5e76\u63d0\u4f9b\u53cd\u9988\u3002\u529f\u80fd\u9000\u51fabeta\u540e\uff0c\u53ef\u80fd\u4e0d\u5b9e\u9645\u518d\u8fdb\u884c\u66f4\u6539\u3002 \u7a33\u5b9a\u7248\uff1a \u7248\u672c\u540d\u79f0\u4e3avX\uff0c\u5176\u4e2dX\u662f\u6574\u6570\u3002 \u529f\u80fd\u7684\u7a33\u5b9a\u7248\u672c\u51fa\u73b0\u5728\u53d1\u5e03\u7684\u8f6f\u4ef6\u4e2d\u7684\u8bb8\u591a\u540e\u7eed\u7248\u672c\u4e2d\u3002 \u8bfb\u53d6\u5f53\u524dAPI\u7684\u7248\u672c\u547d\u4ee4\uff1a kubectl api-resources","title":"API Version"},{"location":"k8s/cka_cn/foundamentals/memo/#api-group","text":"API\u7ec4\uff08API groups\uff09 \u4f7f\u6269\u5c55Kubernetes API\u66f4\u52a0\u5bb9\u6613\u3002API\u7ec4\u5728REST\u8def\u5f84\u548c\u5e8f\u5217\u5316\u5bf9\u8c61\u7684apiVersion\u5b57\u6bb5\u4e2d\u6307\u5b9a\u3002 Kubernetes\u6709\u51e0\u4e2aAPI\u7ec4\uff1a \u6838\u5fc3\u7ec4\uff08\u4e5f\u79f0\u4e3a\u9057\u7559legacy\uff09\u4f4d\u4e8eREST\u8def\u5f84 /api/v1 \u3002 \u6838\u5fc3\u7ec4\u4e0d\u4f5c\u4e3aapiVersion\u5b57\u6bb5\u7684\u4e00\u90e8\u5206\u6307\u5b9a\uff0c\u4f8b\u5982 apiVersion: v1\u3002 \u547d\u540d\u7ec4\u4f4d\u4e8eREST\u8def\u5f84 /apis/$GROUP_NAME/$VERSION \uff0c\u5e76\u4f7f\u7528 apiVersion: $GROUP_NAME/$VERSION \uff08\u4f8b\u5982 apiVersion: batch/v1\uff09\u3002","title":"API Group"},{"location":"k8s/cka_cn/foundamentals/memo/#kubernetes_2","text":"","title":"Kubernetes\u5bf9\u8c61"},{"location":"k8s/cka_cn/foundamentals/memo/#_2","text":"\u5bf9\u8c61\u89c4\u8303\uff08Object Spec\uff09\uff1a \u63d0\u4f9b\u4e86\u4e00\u4e2a\u63cf\u8ff0\u6240\u521b\u5efa\u8d44\u6e90\u7684\u7279\u6027\u7684\u8bf4\u660e\uff1a \u5176\u671f\u671b\u7684\u72b6\u6001 \u3002 \u5bf9\u8c61\u72b6\u6001\uff08Object Status\uff09\uff1a \u63cf\u8ff0\u4e86\u5bf9\u8c61\u7684\u5f53\u524d\u72b6\u6001\u3002 \u6bd4\u5982\uff0cDeployment\u662f\u4e00\u4e2a\u53ef\u4ee5\u4ee3\u8868\u96c6\u7fa4\u4e0a\u8fd0\u884c\u7684\u5e94\u7528\u7a0b\u5e8f\u7684\u5bf9\u8c61\u3002 apiVersion : apps/v1 # \u5f53\u524d\u7528\u6765\u521b\u5efa\u5bf9\u8c61\u7684API\u7248\u672c kind : Deployment # \u521b\u5efa\u5bf9\u8c61\u7684\u7c7b\u578b metadata : # \u7528\u6765\u533a\u5206\u5bf9\u8c61\u7684\u5143\u6570\u636e\uff0c\u6bd4\u5982\uff1a\u540d\u79f0\uff0cUID\uff0c\u547d\u540d\u7a7a\u95f4\u7b49 name : nginx-deployment spec : # \u671f\u671b\u6240\u521b\u5efa\u5bf9\u8c61\u7684\u72b6\u6001 selector : matchLabels : app : nginx replicas : 2 # \u544a\u8bc9Deployment\u57fa\u4e8e\u4e0b\u9762\u7684\u6a21\u677ftemplate\u521b\u5efa2\u4e2aPods template : metadata : labels : app : nginx spec : containers : - name : nginx image : nginx:1.14.2 ports : - containerPort : 80","title":"\u5bf9\u8c61\u6982\u8ff0"},{"location":"k8s/cka_cn/foundamentals/memo/#_3","text":"kubectl \u547d\u4ee4\u884c\u5de5\u5177\u652f\u6301\u591a\u79cd\u4e0d\u540c\u7684\u65b9\u5f0f\u6765\u521b\u5efa\u548c\u7ba1\u7406 Kubernetes \u5bf9\u8c61\u3002\u8be6\u7ec6\u4fe1\u606f\u8bf7\u9605\u8bfb Kubectl book \u3002 \u4e00\u4e2a Kubernetes \u5bf9\u8c61\u5e94\u8be5\u4ec5\u4f7f\u7528\u4e00\u79cd\u6280\u672f\u8fdb\u884c\u7ba1\u7406\u3002\u6df7\u5408\u4f7f\u7528\u4e0d\u540c\u7684\u6280\u672f\u6765\u7ba1\u7406\u540c\u4e00\u4e2a\u5bf9\u8c61\u4f1a\u5bfc\u81f4\u975e\u9884\u671f\u7684\u7ed3\u679c\u3002 \u4e09\u79cd\u7ba1\u7406\u6280\u672f: \u547d\u4ee4\u5f0f\u547d\u4ee4 \u76f4\u63a5\u5728\u96c6\u7fa4\u4e2d\u64cd\u4f5c\u5b9e\u65f6\u5bf9\u8c61\u3002 kubectl create deployment nginx --image nginx \u547d\u4ee4\u5f0f\u5bf9\u8c61\u914d\u7f6e kubectl create -f nginx.yaml kubectl delete -f nginx.yaml -f redis.yaml kubectl replace -f nginx.yaml \u58f0\u660e\u5f0f\u5bf9\u8c61\u914d\u7f6e kubectl diff -f configs/ kubectl apply -f configs/","title":"\u5bf9\u8c61\u7ba1\u7406"},{"location":"k8s/cka_cn/foundamentals/memo/#id","text":"\u96c6\u7fa4\u4e2d\u7684\u6bcf\u4e2a\u5bf9\u8c61\u90fd\u6709\u4e00\u4e2a\u5728\u8be5\u8d44\u6e90\u7c7b\u578b\u4e2d\u552f\u4e00\u7684\u540d\u79f0\u3002 DNS \u5b50\u57df\u540d \u6807\u7b7e\u540d\u79f0 \u8def\u5f84\u6bb5\u540d\u79f0 \u6bcf\u4e2a Kubernetes \u5bf9\u8c61\u8fd8\u6709\u4e00\u4e2a UID\uff0c\u5728\u6574\u4e2a\u96c6\u7fa4\u4e2d\u662f\u552f\u4e00\u7684\u3002","title":"\u5bf9\u8c61\u540d\u79f0\u548cID"},{"location":"k8s/cka_cn/foundamentals/memo/#_4","text":"\u5728Kubernetes\u4e2d\uff0c\u547d\u540d\u7a7a\u95f4\u63d0\u4f9b\u4e86\u4e00\u79cd\u5728\u5355\u4e2a\u96c6\u7fa4\u5185\u9694\u79bb\u8d44\u6e90\u7ec4\u7684\u673a\u5236\u3002 \u8d44\u6e90\u7684\u540d\u79f0\u9700\u8981\u5728\u547d\u540d\u7a7a\u95f4\u5185\u662f\u552f\u4e00\u7684\uff0c\u4f46\u4e0d\u9700\u8981\u8de8\u547d\u540d\u7a7a\u95f4\u552f\u4e00\u3002 \u57fa\u4e8e\u547d\u540d\u7a7a\u95f4\u7684\u8303\u56f4\u4ec5\u9002\u7528\u4e8e\u547d\u540d\u7a7a\u95f4\u5bf9\u8c61\uff08\u4f8b\u5982\u90e8\u7f72\uff0c\u670d\u52a1\u7b49\uff09\uff0c\u800c\u4e0d\u9002\u7528\u4e8e\u96c6\u7fa4\u8303\u56f4\u7684\u5bf9\u8c61\uff08\u4f8b\u5982StorageClass\uff0c\u8282\u70b9\uff0c\u6301\u4e45\u5377\u7b49\uff09\u3002 \u5e76\u975e\u6240\u6709\u5bf9\u8c61\u90fd\u4f4d\u4e8e\u547d\u540d\u7a7a\u95f4\u4e2d\u3002 Kubernetes\u4ece\u56db\u4e2a\u521d\u59cb\u547d\u540d\u7a7a\u95f4\u5f00\u59cb\uff1a default \u7528\u4e8e\u6ca1\u6709\u5176\u4ed6\u547d\u540d\u7a7a\u95f4\u7684\u5bf9\u8c61\u7684\u9ed8\u8ba4\u547d\u540d\u7a7a\u95f4 kube-system Kubernetes\u7cfb\u7edf\u521b\u5efa\u7684\u5bf9\u8c61\u7684\u547d\u540d\u7a7a\u95f4 kube-public \u8be5\u547d\u540d\u7a7a\u95f4\u662f\u81ea\u52a8\u521b\u5efa\u7684\uff0c\u5e76\u53ef\u7531\u6240\u6709\u7528\u6237\uff08\u5305\u62ec\u672a\u7ecf\u8eab\u4efd\u9a8c\u8bc1\u7684\u7528\u6237\uff09\u8bfb\u53d6\u3002\u6b64\u547d\u540d\u7a7a\u95f4\u5927\u591a\u4fdd\u7559\u4f9b\u96c6\u7fa4\u4f7f\u7528\uff0c\u4ee5\u9632\u4e00\u4e9b\u8d44\u6e90\u5e94\u5728\u6574\u4e2a\u96c6\u7fa4\u8303\u56f4\u5185\u516c\u5f00\u548c\u53ef\u8bfb\u3002\u6b64\u547d\u540d\u7a7a\u95f4\u7684\u516c\u5171\u65b9\u9762\u53ea\u662f\u4e00\u79cd\u7ea6\u5b9a\uff0c\u800c\u4e0d\u662f\u8981\u6c42\u3002 kube-node-lease \u6b64\u547d\u540d\u7a7a\u95f4\u4fdd\u5b58\u4e0e\u6bcf\u4e2a\u8282\u70b9\u5173\u8054\u7684\u79df\u8d41\u5bf9\u8c61\u3002\u8282\u70b9\u79df\u8d41\u5141\u8bb8kubelet\u53d1\u9001\u5fc3\u8df3\uff0c\u4ee5\u4fbf\u63a7\u5236\u5e73\u9762\u53ef\u4ee5\u68c0\u6d4b\u5230\u8282\u70b9\u6545\u969c\u3002 \u67e5\u770b\u547d\u540d\u7a7a\u95f4\uff1a kubectl get namespace \u4e3a\u8bf7\u6c42\u8bbe\u7f6e\u547d\u540d\u7a7a\u95f4 kubectl run nginx --image=nginx --namespace=<\u63d2\u5165\u547d\u540d\u7a7a\u95f4\u540d\u79f0> kubectl get pods --namespace=<\u63d2\u5165\u547d\u540d\u7a7a\u95f4\u540d\u79f0>","title":"\u547d\u540d\u7a7a\u95f4"},{"location":"k8s/cka_cn/foundamentals/memo/#_5","text":"\u6807\u7b7e\u662f\u9644\u52a0\u5230\u5bf9\u8c61\uff08\u4f8b\u5982 Pod\uff09\u7684\u952e/\u503c\u5bf9\u3002\u6709\u6548\u7684\u6807\u7b7e\u952e\u6709\u4e24\u4e2a\u90e8\u5206\uff1a\u53ef\u9009\u7684\u524d\u7f00\u548c\u540d\u79f0\uff0c\u7531\u659c\u6760\uff08 / \uff09\u5206\u9694\u3002 \u6807\u7b7e\u65e8\u5728\u7528\u4e8e\u6307\u5b9a\u5bf9\u7528\u6237\u6709\u610f\u4e49\u548c\u76f8\u5173\u7684\u5bf9\u8c61\u8bc6\u522b\u5c5e\u6027\u3002 \u6807\u7b7e\u53ef\u7528\u4e8e\u7ec4\u7ec7\u548c\u9009\u62e9\u5bf9\u8c61\u5b50\u96c6\u3002\u6807\u7b7e\u53ef\u4ee5\u5728\u521b\u5efa\u5bf9\u8c61\u65f6\u9644\u52a0\uff0c\u968f\u540e\u5728\u4efb\u4f55\u65f6\u5019\u6dfb\u52a0\u548c\u4fee\u6539\u3002\u6bcf\u4e2a\u5bf9\u8c61\u53ef\u4ee5\u5b9a\u4e49\u4e00\u7ec4\u952e/\u503c\u6807\u7b7e\uff0c\u6bcf\u4e2a\u952e\u5fc5\u987b\u5bf9\u4e8e\u7ed9\u5b9a\u5bf9\u8c61\u662f\u552f\u4e00\u7684\u3002 \u6807\u7b7e\u7684\u793a\u4f8b\uff1a \"metadata\" : { \"labels\" : { \"key1\" : \"value1\" , \"key2\" : \"value2\" } } \u4e0e\u540d\u79f0\u548c UID \u4e0d\u540c\uff0c\u6807\u7b7e\u4e0d\u63d0\u4f9b\u552f\u4e00\u6027\u3002\u901a\u5e38\u60c5\u51b5\u4e0b\uff0c\u6211\u4eec\u671f\u671b\u8bb8\u591a\u5bf9\u8c61\u5e26\u6709\u76f8\u540c\u7684\u6807\u7b7e\u3002 \u76ee\u524d API \u652f\u6301\u4e24\u79cd\u7c7b\u578b\u7684\u9009\u62e9\u5668\uff1a \u57fa\u4e8e\u7b49\u5f0f\u7684\u9009\u62e9\u5668\uff0c\u4f8b\u5982\uff1a environment = production \u3001 tier != frontend \u57fa\u4e8e\u96c6\u5408\u7684\u9009\u62e9\u5668\uff0c\u4f8b\u5982\uff1a environment in (production, qa) \u3001 tier notin (frontend, backend) \u4f8b\u5982\uff1a kubectl get pods -l environment = production,tier = frontend kubectl get pods -l 'environment in (production),tier in (frontend)' kubectl get pods -l 'environment in (production, qa)' kubectl get pods -l 'environment,environment notin (frontend)'","title":"\u6807\u7b7e\u548c\u9009\u62e9\u5668"},{"location":"k8s/cka_cn/foundamentals/memo/#annotations","text":"\u4f7f\u7528 Kubernetes \u6ce8\u91ca\uff08Annotations\uff09\u5c06\u4efb\u610f\u975e\u6807\u8bc6\u5143\u6570\u636e\u9644\u52a0\u5230\u5bf9\u8c61\u4e0a\u3002 \u5de5\u5177\u548c\u5e93\u7b49\u5ba2\u6237\u7aef\u53ef\u4ee5\u68c0\u7d22\u6b64\u5143\u6570\u636e\u3002 \u4f7f\u7528\u6807\u7b7e\u6216\u6ce8\u91ca\u5c06\u5143\u6570\u636e\u9644\u52a0\u5230 Kubernetes \u5bf9\u8c61\u4e0a\u3002 \u6807\u7b7e\u53ef\u7528\u4e8e\u9009\u62e9\u5bf9\u8c61\u5e76\u67e5\u627e\u6ee1\u8db3\u67d0\u4e9b\u6761\u4ef6\u7684\u5bf9\u8c61\u96c6\u5408\u3002 \u6ce8\u91ca\u4e0d\u7528\u4e8e\u6807\u8bc6\u548c\u9009\u62e9\u5bf9\u8c61\u3002 \u6ce8\u91ca\u4e0e\u6807\u7b7e\u7c7b\u4f3c\uff0c\u90fd\u662f\u952e/\u503c\u6620\u5c04\u3002 \u6620\u5c04\u4e2d\u7684\u952e\u548c\u503c\u5fc5\u987b\u662f\u5b57\u7b26\u4e32\u3002 \u4f8b\u5982\uff1a \"metadata\" : { \"annotations\" : { \"key1\" : \"value1\" , \"key2\" : \"value2\" } } \u5408\u6cd5\u7684\u6ce8\u91ca\u952e\u5177\u6709\u4e24\u4e2a\u90e8\u5206\uff1a\u53ef\u9009\u7684\u524d\u7f00\u548c\u540d\u79f0\uff0c\u7531\u659c\u6760 ( / ) \u5206\u9694\u3002","title":"\u6ce8\u91caAnnotations"},{"location":"k8s/cka_cn/foundamentals/memo/#_6","text":"\u5b57\u6bb5\u9009\u62e9\u5668\uff08field selectors\uff09\u53ef\u4ee5\u6839\u636e\u4e00\u4e2a\u6216\u591a\u4e2a\u8d44\u6e90\u5b57\u6bb5\u7684\u503c\u9009\u62e9Kubernetes\u8d44\u6e90\u3002 \u4e0b\u9762\u662f\u4e00\u4e9b\u4f7f\u7528\u5b57\u6bb5\u9009\u62e9\u5668\u8fdb\u884c\u67e5\u8be2\u7b5b\u9009\u7684\u4f8b\u5b50\uff1a metadata.name=my-service metadata.namespace!=default status.phase=Pending This kubectl command selects all Pods for which the value of the status.phase field is Running: kubectl get pods --field-selector status.phase=Running Supported field selectors vary by Kubernetes resource type. All resource types support the metadata.name and metadata.namespace fields. Use the = , == , and != operators with field selectors ( = and == mean the same thing). \u4e0b\u9762 kubectl \u547d\u4ee4\u9009\u62e9\u6240\u6709\u72b6\u6001(phase)\u5b57\u6bb5\u503c\u4e3a Running \u7684 Pod\uff1a kubectl get pods --field-selector status.phase = Running \u652f\u6301\u7684\u5b57\u6bb5\u9009\u62e9\u5668\u56e0 Kubernetes \u8d44\u6e90\u7c7b\u578b\u800c\u5f02\u3002\u6240\u6709\u8d44\u6e90\u7c7b\u578b\u90fd\u652f\u6301 metadata.name \u548c metadata.namespace \u5b57\u6bb5\u3002 \u5728\u5b57\u6bb5\u9009\u62e9\u5668\u4e2d\u4f7f\u7528 = , == , \u548c != \u8fd0\u7b97\u7b26( = \u548c == \u8868\u793a\u76f8\u540c\u7684\u610f\u601d)\u3002 \u4f8b\u5982\uff1a kubectl get ingress --field-selector foo.bar = baz kubectl get services --all-namespaces --field-selector metadata.namespace! = default kubectl get pods --field-selector = status.phase! = Running,spec.restartPolicy = Always kubectl get statefulsets,services --all-namespaces --field-selector metadata.namespace! = default Finalizers\u662f*\u547d\u540d\u7a7a\u95f4\u952e*\uff0c\u544a\u8bc9Kubernetes\u5728\u6ee1\u8db3\u7279\u5b9a\u6761\u4ef6\u4e4b\u524d\u7b49\u5f85\uff0c\u7136\u540e\u518d\u5b8c\u5168\u5220\u9664\u6807\u8bb0\u4e3a*\u5220\u9664*\u7684\u8d44\u6e90\u3002 Finalizer\u8b66\u544a\u63a7\u5236\u5668controller\u6e05\u7406\u5df2\u5220\u9664\u5bf9\u8c61\u6240\u62e5\u6709\u7684\u8d44\u6e90\u3002 \u901a\u5e38\u56e0\u4e3a\u67d0\u79cd\u76ee\u7684\u4e3a\u8d44\u6e90\u6dfb\u52a0Finalizers\uff0c\u5f3a\u5236\u5220\u9664\u5b83\u4eec\u53ef\u80fd\u4f1a\u5bfc\u81f4\u96c6\u7fa4\u4e2d\u51fa\u73b0\u95ee\u9898\u3002 \u4e0e\u6807\u7b7e\u7c7b\u4f3c\uff0c \u6240\u6709\u8005\u5f15\u7528 \uff08Owner references\uff09\u63cf\u8ff0\u4e86Kubernetes\u4e2d\u5bf9\u8c61\u4e4b\u95f4\u7684\u5173\u7cfb\uff0c\u4f46\u7528\u4e8e\u4e0d\u540c\u7684\u76ee\u7684\u3002 Kubernetes\u4f7f\u7528\u6240\u6709\u8005\u5f15\u7528\uff08\u800c\u4e0d\u662f\u6807\u7b7e\uff09\u6765\u786e\u5b9a\u96c6\u7fa4\u4e2d\u54ea\u4e9bPod\u9700\u8981\u6e05\u7406\u3002 \u5f53Kubernetes\u8bc6\u522b\u5230\u76ee\u6807\u5220\u9664\u7684\u8d44\u6e90\u4e0a\u6709\u6240\u6709\u8005\u5f15\u7528\u65f6\uff0c\u5b83\u4f1a\u5904\u7406Finalizer\u3002","title":"\u5b57\u6bb5\u9009\u62e9\u5668"},{"location":"k8s/cka_cn/foundamentals/memo/#_7","text":"\u5728 Kubernetes \u4e2d\uff0c\u4e00\u4e9b\u5bf9\u8c61\u62e5\u6709\u5176\u4ed6\u5bf9\u8c61\u3002\u4f8b\u5982\uff0cReplicaSet \u662f\u4e00\u7ec4 Pod \u7684\u6240\u6709\u8005\u3002\u8fd9\u4e9b\u88ab\u62e5\u6709\u7684\u5bf9\u8c61\u662f\u5176\u6240\u6709\u8005\u7684\u4ece\u5c5e\u5bf9\u8c61\u3002 \u4ece\u5c5e\u5bf9\u8c61\u5177\u6709\u4e00\u4e2a metadata.ownerReferences \u5b57\u6bb5\uff0c\u8be5\u5b57\u6bb5\u5f15\u7528\u5176\u6240\u6709\u8005\u5bf9\u8c61\u3002 \u6709\u6548\u7684\u6240\u6709\u8005\u5f15\u7528\u5305\u62ec\u5bf9\u8c61\u540d\u79f0\u548c\u4e0e\u4ece\u5c5e\u5bf9\u8c61\u76f8\u540c\u7684\u547d\u540d\u7a7a\u95f4\u4e2d\u7684 UID\u3002 \u4ece\u5c5e\u5bf9\u8c61\u8fd8\u5177\u6709\u4e00\u4e2a ownerReferences.blockOwnerDeletion \u5b57\u6bb5\uff0c\u8be5\u5b57\u6bb5\u5177\u6709\u5e03\u5c14\u503c\uff0c\u63a7\u5236\u7279\u5b9a\u7684\u4ece\u5c5e\u5bf9\u8c61\u662f\u5426\u53ef\u4ee5\u963b\u6b62\u5783\u573e\u56de\u6536\u5220\u9664\u5176\u6240\u6709\u8005\u5bf9\u8c61\u3002","title":"\u6240\u6709\u8005\u548c\u4f9d\u8d56\u5173\u7cfb"},{"location":"k8s/cka_cn/foundamentals/memo/#_8","text":"Kubernetes\u8d44\u6e90\u548c\u201c\u610f\u5411\u8bb0\u5f55\u201d\u90fd\u4ee5API\u5bf9\u8c61\u7684\u5f62\u5f0f\u5b58\u50a8\uff0c\u5e76\u901a\u8fc7\u5bf9API\u7684RESTful\u8c03\u7528\u8fdb\u884c\u4fee\u6539\u3002 API\u5141\u8bb8\u4ee5\u58f0\u660e\u6027\u65b9\u5f0f\u7ba1\u7406\u914d\u7f6e\u3002 \u7528\u6237\u53ef\u4ee5\u76f4\u63a5\u4e0eKubernetes API\u4ea4\u4e92\uff0c\u4e5f\u53ef\u4ee5\u901a\u8fc7\u50cfkubectl\u8fd9\u6837\u7684\u5de5\u5177\u8fdb\u884c\u4ea4\u4e92\u3002 \u6838\u5fc3Kubernetes API\u5177\u6709\u7075\u6d3b\u6027\uff0c\u4e5f\u53ef\u4ee5\u6269\u5c55\u4ee5\u652f\u6301\u81ea\u5b9a\u4e49\u8d44\u6e90\u3002 \u5de5\u4f5c\u8d1f\u8f7d\u8d44\u6e90\uff08Workload Resources\uff09 Pod \u3002Pod \u662f\u53ef\u4ee5\u5728\u4e3b\u673a\u4e0a\u8fd0\u884c\u7684\u5bb9\u5668\u96c6\u5408\u3002 PodTemplate \u3002PodTemplate \u63cf\u8ff0\u4e86\u9884\u5b9a\u4e49 pod \u7684\u526f\u672c\u6a21\u677f\u3002 ReplicationController \u3002ReplicationController \u8868\u793a\u4e00\u4e2a\u590d\u5236\u63a7\u5236\u5668\u7684\u914d\u7f6e\u3002 ReplicaSet \u3002ReplicaSet \u786e\u4fdd\u5728\u4efb\u4f55\u7ed9\u5b9a\u65f6\u95f4\u6709\u6307\u5b9a\u6570\u91cf\u7684 pod \u526f\u672c\u6b63\u5728\u8fd0\u884c\u3002 Deployment \u3002Deployment \u4f7f Pod \u548c ReplicaSet \u7684\u58f0\u660e\u6027\u66f4\u65b0\u6210\u4e3a\u53ef\u80fd\u3002 StatefulSet \u3002StatefulSet \u8868\u793a\u5177\u6709\u4e00\u81f4\u6807\u8bc6\u7684 pod \u96c6\u5408\u3002 ControllerRevision \u3002ControllerRevision \u5b9e\u73b0\u4e86\u72b6\u6001\u6570\u636e\u7684\u4e0d\u53ef\u53d8\u5feb\u7167\u3002 DaemonSet \u3002DaemonSet \u8868\u793a\u4e00\u4e2a\u5b88\u62a4\u8fdb\u7a0b\u96c6\u7684\u914d\u7f6e\u3002 Job \u3002Job \u8868\u793a\u5355\u4e2a job \u7684\u914d\u7f6e\u3002 CronJob \u3002CronJob \u8868\u793a\u5355\u4e2a cron job \u7684\u914d\u7f6e\u3002 HorizontalPodAutoscaler \u3002HorizontalPodAutoscaler \u8868\u793a\u6c34\u5e73 pod \u81ea\u52a8\u7f29\u653e\u5668\u7684\u914d\u7f6e\u3002 HorizontalPodAutoscaler v2beta2 \u3002HorizontalPodAutoscaler \u662f\u6c34\u5e73 pod \u81ea\u52a8\u7f29\u653e\u5668\u7684\u914d\u7f6e\uff0c\u6839\u636e\u6307\u5b9a\u7684\u6307\u6807\u81ea\u52a8\u7ba1\u7406\u5b9e\u73b0\u6bd4\u4f8b\u5b50\u8d44\u6e90\u7684\u4efb\u4f55\u8d44\u6e90\u7684\u526f\u672c\u8ba1\u6570\u3002 PriorityClass \u3002PriorityClass \u5b9a\u4e49\u4e86\u4ece\u4f18\u5148\u7ea7\u7c7b\u540d\u79f0\u5230\u4f18\u5148\u7ea7\u6574\u6570\u503c\u7684\u6620\u5c04\u3002 \u670d\u52a1\u8d44\u6e90\uff08Service Resources\uff09 Service . Service \u662f\u5bf9\u8f6f\u4ef6\u670d\u52a1\uff08\u4f8b\u5982mysql\uff09\u7684\u547d\u540d\u62bd\u8c61\uff0c\u7531\u4ee3\u7406\u76d1\u542c\u7684\u672c\u5730\u7aef\u53e3\uff08\u4f8b\u59823306\uff09\u548c\u786e\u5b9a\u54ea\u4e9bPod\u5c06\u56de\u7b54\u901a\u8fc7\u4ee3\u7406\u53d1\u9001\u7684\u8bf7\u6c42\u7684\u9009\u62e9\u5668\u7ec4\u6210\u3002 Endpoints . Endpoints \u662f\u5b9e\u73b0\u5b9e\u9645\u670d\u52a1\u7684\u4e00\u7ec4\u7ec8\u7ed3\u70b9\u3002 EndpointSlice . EndpointSlice \u8868\u793a\u5b9e\u73b0\u670d\u52a1\u7684\u7ec8\u7ed3\u70b9\u7684\u5b50\u96c6\u3002 Ingress . Ingress \u662f\u4e00\u7ec4\u89c4\u5219\uff0c\u5141\u8bb8\u5165\u7ad9\u8fde\u63a5\u5230\u8fbe\u7531\u540e\u7aef\u5b9a\u4e49\u7684\u7ec8\u7ed3\u70b9\u3002 IngressClass . IngressClass \u8868\u793a Ingress \u7684\u7c7b\uff0c\u7531 Ingress Spec \u5f15\u7528\u3002 \u914d\u7f6e\u548c\u5b58\u50a8\u8d44\u6e90\uff08Config and Storage Resources\uff09 ConfigMap \u3002ConfigMap\u4fdd\u5b58\u5bb9\u5668\u9700\u8981\u4f7f\u7528\u7684\u914d\u7f6e\u6570\u636e\u3002 Secret \u3002Secret\u4fdd\u5b58\u7279\u5b9a\u7c7b\u578b\u7684\u673a\u5bc6\u6570\u636e\u3002 Volume \u3002Volume\u8868\u793aPod\u4e2d\u7684\u547d\u540d\u5377\uff0c\u53ef\u4ee5\u88abPod\u4e2d\u7684\u4efb\u4f55\u5bb9\u5668\u8bbf\u95ee\u3002 PersistentVolumeClaim \u3002PersistentVolumeClaim\u662f\u7528\u6237\u5bf9\u6301\u4e45\u5377\u7684\u8bf7\u6c42\u548c\u58f0\u660e\u3002 PersistentVolume \u3002PersistentVolume\uff08PV\uff09\u662f\u7531\u7ba1\u7406\u5458\u63d0\u4f9b\u7684\u5b58\u50a8\u8d44\u6e90\u3002 StorageClass \u3002StorageClass\u63cf\u8ff0\u53ef\u52a8\u6001\u5206\u914dPersistentVolumes\u7684\u5b58\u50a8\u7c7b\u522b\u7684\u53c2\u6570\u3002 VolumeAttachment \u3002VolumeAttachment\u8bb0\u5f55\u5c06\u6307\u5b9a\u7684\u5377\u9644\u52a0\u5230/\u4ece\u6307\u5b9a\u8282\u70b9\u4e2d\u5206\u79bb\u7684\u610f\u56fe\u3002 CSIDriver \u3002CSIDriver\u8bb0\u5f55\u96c6\u7fa4\u4e0a\u90e8\u7f72\u7684\u5bb9\u5668\u5b58\u50a8\u63a5\u53e3\uff08CSI\uff09\u5377\u9a71\u52a8\u7a0b\u5e8f\u7684\u4fe1\u606f\u3002 CSINode \u3002CSINode\u4fdd\u5b58\u6709\u5173\u8282\u70b9\u4e0a\u5b89\u88c5\u7684\u6240\u6709CSI\u9a71\u52a8\u7a0b\u5e8f\u7684\u4fe1\u606f\u3002 CSIStorageCapacity \u3002CSIStorageCapacity\u5b58\u50a8\u4e00\u4e2aCSI GetCapacity\u8c03\u7528\u7684\u7ed3\u679c\u3002 \u8ba4\u8bc1\u8d44\u6e90\uff08Authentication Resources\uff09 ServiceAccount*\u3002ServiceAccount\u548c\u4e0b\u9762\u7684\u4fe1\u606f\u7ed1\u5b9a\u5728\u4e00\u8d77\uff1a \u4e00\u4e2a\u53ef\u88ab\u7528\u6237\u548c\u5468\u8fb9\u7cfb\u7edf\u7406\u89e3\u7684\u540d\u79f0\uff0c\u7528\u4e8e\u8eab\u4efd\u8bc6\u522b \u53ef\u8fdb\u884c\u8eab\u4efd\u9a8c\u8bc1\u548c\u6388\u6743\u7684\u4e3b\u4f53 \u4e00\u7ec4\u5bc6\u94a5\u3002 TokenRequest*\u3002TokenRequest\u4e3a\u7ed9\u5b9a\u7684ServiceAccount\u8bf7\u6c42\u4e00\u4e2a\u4ee4\u724c\u3002 TokenReview*\u3002TokenReview\u5c1d\u8bd5\u5bf9\u5df2\u77e5\u7528\u6237\u7684\u4ee4\u724c\u8fdb\u884c\u8eab\u4efd\u9a8c\u8bc1\u3002 CertificateSigningRequest*\u3002CertificateSigningRequest\u5bf9\u8c61\u63d0\u4f9b\u4e86\u4e00\u79cd\u901a\u8fc7\u63d0\u4ea4\u8bc1\u4e66\u7b7e\u540d\u8bf7\u6c42\u5e76\u5f02\u6b65\u6279\u51c6\u548c\u53d1\u653e\u6765\u83b7\u53d6x509\u8bc1\u4e66\u7684\u673a\u5236\u3002 \u6388\u6743\u8d44\u6e90\uff08Authorization Resources\uff09 LocalSubjectAccessReview*\u3002LocalSubjectAccessReview\u68c0\u67e5\u4e00\u4e2a\u7528\u6237\u6216\u7ec4\u5728\u7ed9\u5b9a\u547d\u540d\u7a7a\u95f4\u4e2d\u662f\u5426\u80fd\u6267\u884c\u67d0\u4e2a\u64cd\u4f5c\u3002 SelfSubjectAccessReview*\u3002SelfSubjectAccessReview\u68c0\u67e5\u5f53\u524d\u7528\u6237\u662f\u5426\u80fd\u6267\u884c\u67d0\u4e2a\u64cd\u4f5c\u3002 SelfSubjectRulesReview*\u3002SelfSubjectRulesReview\u679a\u4e3e\u5f53\u524d\u7528\u6237\u5728\u4e00\u4e2a\u547d\u540d\u7a7a\u95f4\u5185\u53ef\u4ee5\u6267\u884c\u7684\u64cd\u4f5c\u96c6\u5408\u3002 SubjectAccessReview*\u3002SubjectAccessReview\u68c0\u67e5\u4e00\u4e2a\u7528\u6237\u6216\u7ec4\u662f\u5426\u80fd\u6267\u884c\u67d0\u4e2a\u64cd\u4f5c\u3002 ClusterRole*\u3002ClusterRole\u662f\u4e00\u4e2a\u96c6\u7fa4\u7ea7\u522b\u7684PolicyRules\u903b\u8f91\u5206\u7ec4\uff0c\u53ef\u4ee5\u88abRoleBinding\u6216ClusterRoleBinding\u5f15\u7528\u4e3a\u4e00\u4e2a\u5355\u5143\u3002 ClusterRoleBinding*\u3002ClusterRoleBinding\u5f15\u7528\u4e00\u4e2aClusterRole\uff0c\u4f46\u4e0d\u5305\u542b\u5b83\u3002 Role*\u3002Role\u662f\u4e00\u4e2a\u547d\u540d\u7a7a\u95f4\u7ea7\u522b\u7684PolicyRules\u903b\u8f91\u5206\u7ec4\uff0c\u53ef\u4ee5\u88abRoleBinding\u5f15\u7528\u4e3a\u4e00\u4e2a\u5355\u5143\u3002 RoleBinding*\u3002RoleBinding\u5f15\u7528\u4e00\u4e2aRole\uff0c\u4f46\u4e0d\u5305\u542b\u5b83\u3002 \u7b56\u7565\u8d44\u6e90\uff08Policy Resources\uff09 LimitRange*\u3002LimitRange\u4e3a\u547d\u540d\u7a7a\u95f4\u4e2d\u6bcf\u79cd\u8d44\u6e90\u8bbe\u7f6e\u8d44\u6e90\u4f7f\u7528\u9650\u5236\u3002 ResourceQuota*\u3002ResourceQuota\u8bbe\u7f6e\u6bcf\u4e2a\u547d\u540d\u7a7a\u95f4\u5f3a\u5236\u6267\u884c\u7684\u603b\u914d\u989d\u9650\u5236\u3002 NetworkPolicy*\u3002NetworkPolicy\u63cf\u8ff0\u4e86\u4e00\u7ec4Pod\u5141\u8bb8\u7684\u7f51\u7edc\u6d41\u91cf\u3002 PodDisruptionBudget*\u3002PodDisruptionBudget\u662f\u4e00\u4e2a\u5bf9\u8c61\uff0c\u7528\u4e8e\u5b9a\u4e49\u5bf9\u4e00\u7ec4Pod\u53ef\u80fd\u9020\u6210\u7684\u6700\u5927\u4e2d\u65ad\u3002 PodSecurityPolicy v1beta1*\u3002PodSecurityPolicy\u63a7\u5236\u5bf9\u53ef\u80fd\u5f71\u54cd\u5c06\u5e94\u7528\u4e8ePod\u548c\u5bb9\u5668\u7684\u5b89\u5168\u4e0a\u4e0b\u6587\u7684\u8bf7\u6c42\u7684\u80fd\u529b\u3002 \u6269\u5c55\u8d44\u6e90\uff08Extend Resources\uff09 CustomResourceDefinition*\u3002CustomResourceDefinition\u8868\u793a\u5e94\u5728API\u670d\u52a1\u5668\u4e0a\u516c\u5f00\u7684\u8d44\u6e90\u3002 MutatingWebhookConfiguration*\u3002MutatingWebhookConfiguration\u63cf\u8ff0\u63a5\u53d7\u6216\u62d2\u7edd\u5e76\u53ef\u80fd\u66f4\u6539\u5bf9\u8c61\u7684\u51c6\u5165Webhook\u7684\u914d\u7f6e\u3002 ValidatingWebhookConfiguration*\u3002ValidatingWebhookConfiguration\u63cf\u8ff0\u63a5\u53d7\u6216\u62d2\u7edd\u5bf9\u8c61\u4f46\u4e0d\u66f4\u6539\u5bf9\u8c61\u7684\u51c6\u5165Webhook\u7684\u914d\u7f6e\u3002 \u96c6\u7fa4\u8d44\u6e90\uff08Cluster Resources\uff09 Node*\u3002Node\u662fKubernetes\u4e2d\u7684\u5de5\u4f5c\u8282\u70b9\u3002 Namespace*\u3002Namespace\u4e3a\u540d\u79f0\u63d0\u4f9b\u4e86\u4f5c\u7528\u57df\u3002 Event*\u3002Event\u662f\u5bf9\u96c6\u7fa4\u4e2d\u67d0\u4e2a\u4f4d\u7f6e\u53d1\u751f\u4e8b\u4ef6\u7684\u62a5\u544a\u3002 APIService*\u3002APIService\u8868\u793a\u7279\u5b9aGroupVersion\u7684\u670d\u52a1\u5668\u3002 Lease*\u3002Lease\u5b9a\u4e49\u4e86\u79df\u8d41\u7684\u6982\u5ff5\u3002 RuntimeClass*\u3002RuntimeClass\u5b9a\u4e49\u4e86\u96c6\u7fa4\u4e2d\u652f\u6301\u7684\u5bb9\u5668\u8fd0\u884c\u65f6\u7c7b\u3002 FlowSchema v1beta2*\u3002FlowSchema\u5b9a\u4e49\u4e86\u4e00\u7ec4\u6d41\u7a0b\u7684\u67b6\u6784\u3002 PriorityLevelConfiguration v1beta2*\u3002PriorityLevelConfiguration\u8868\u793a\u4f18\u5148\u7ea7\u7ea7\u522b\u7684\u914d\u7f6e\u3002 Binding*\u3002Binding\u5c06\u4e00\u4e2a\u5bf9\u8c61\u7ed1\u5b9a\u5230\u53e6\u4e00\u4e2a\u5bf9\u8c61\uff1b\u4f8b\u5982\uff0c\u8c03\u5ea6\u7a0b\u5e8f\u5c06Pod\u7ed1\u5b9a\u5230\u8282\u70b9\u4e0a\u3002 ComponentStatus*\u3002ComponentStatus\uff08\u548cComponentStatusList\uff09\u4fdd\u5b58\u96c6\u7fa4\u9a8c\u8bc1\u4fe1\u606f\u3002 \u4f7f\u7528\u547d\u4ee4 kube api-resources \u83b7\u53d6\u652f\u6301\u7684API\u8d44\u6e90\u3002 \u4f7f\u7528\u547d\u4ee4 kubectl explain RESOURCE [options] \u63cf\u8ff0\u4e0e\u6bcf\u4e2a\u652f\u6301\u7684API\u8d44\u6e90\u76f8\u5173\u8054\u7684\u5b57\u6bb5\u3002\u8fd9\u4e9b\u5b57\u6bb5\u53ef\u4ee5\u901a\u8fc7\u7b80\u5355\u7684JSONPath\u6807\u8bc6\u7b26\u8fdb\u884c\u8bc6\u522b\uff1a kubectl explain binding kubectl explain binding.metadata kubectl explain binding.metadata.name","title":"\u8d44\u6e90"},{"location":"k8s/cka_cn/foundamentals/memo/#_9","text":"","title":"\u5de5\u4f5c\u8d1f\u8f7d\u8d44\u6e90"},{"location":"k8s/cka_cn/foundamentals/memo/#pods","text":"Pod\u662fKubernetes\u4e2d\u53ef\u521b\u5efa\u548c\u7ba1\u7406\u7684\u6700\u5c0f\u90e8\u7f72\u8ba1\u7b97\u5355\u4f4d\u3002 Pod\u662f\u4e00\u4e2a\u5305\u542b\u4e00\u4e2a\u6216\u591a\u4e2a\u5bb9\u5668\u3001\u5171\u4eab\u5b58\u50a8\u548c\u7f51\u7edc\u8d44\u6e90\u4ee5\u53ca\u5982\u4f55\u8fd0\u884c\u5bb9\u5668\u7684\u89c4\u8303\u7684\u7ec4\u3002 Pod\u7684\u5185\u5bb9\u59cb\u7ec8\u5171\u540c\u5b9a\u4f4d\u548c\u5171\u540c\u5b89\u6392\uff0c\u5e76\u5728\u5171\u4eab\u73af\u5883\u4e2d\u8fd0\u884c\u3002 Pod\u6a21\u62df\u4e86\u4e00\u4e2a\u7279\u5b9a\u4e8e\u5e94\u7528\u7a0b\u5e8f\u7684\u201c\u903b\u8f91\u4e3b\u673a\u201d\uff1a\u5b83\u5305\u542b\u4e00\u4e2a\u6216\u591a\u4e2a\u76f8\u5bf9\u7d27\u5bc6\u8026\u5408\u7684\u5e94\u7528\u7a0b\u5e8f\u5bb9\u5668\u3002 \u5728\u975e\u4e91\u73af\u5883\u4e2d\uff0c\u540c\u4e00\u7269\u7406\u6216\u865a\u62df\u673a\u4e0a\u6267\u884c\u7684\u5e94\u7528\u7a0b\u5e8f\u7c7b\u4f3c\u4e8e\u5728\u540c\u4e00\u903b\u8f91\u4e3b\u673a\u4e0a\u6267\u884c\u7684\u4e91\u5e94\u7528\u7a0b\u5e8f\u3002 Pod\u7684\u5171\u4eab\u73af\u5883\u662f\u4e00\u7ec4Linux\u547d\u540d\u7a7a\u95f4\u3001cgroups\u548c\u53ef\u80fd\u7684\u5176\u4ed6\u9694\u79bb\u8981\u7d20 - \u8fd9\u4e9b\u8981\u7d20\u4e0e\u9694\u79bbDocker\u5bb9\u5668\u7684\u65b9\u5f0f\u76f8\u540c\u3002 \u5728Docker\u6982\u5ff5\u65b9\u9762\uff0cPod\u7c7b\u4f3c\u4e8e\u5177\u6709\u5171\u4eab\u547d\u540d\u7a7a\u95f4\u548c\u5171\u4eab\u6587\u4ef6\u7cfb\u7edf\u5377\u7684\u4e00\u7ec4Docker\u5bb9\u5668\u3002 \u901a\u5e38\u60c5\u51b5\u4e0b\uff0c\u751a\u81f3\u662f\u5355\u4f8bPod\uff0c\u6211\u4eec\u90fd\u4e0d\u9700\u8981\u76f4\u63a5\u521b\u5efaPod\uff0c\u800c\u662f\u4f7f\u7528\u5de5\u4f5c\u8d1f\u8f7d\u8d44\u6e90\uff0c\u4f8b\u5982*Deployment*\u6216*Job*\u6765\u521b\u5efa\u5b83\u4eec\u3002\u5982\u679cPod\u9700\u8981\u8ddf\u8e2a\u72b6\u6001\uff0c\u5219\u53ef\u4ee5\u4f7f\u7528StatefulSet\u8d44\u6e90\u3002 Kubernetes\u96c6\u7fa4\u4e2d\u7684Pod\u6709\u4e24\u79cd\u4e3b\u8981\u7528\u6cd5\uff1a \u8fd0\u884c\u5355\u4e2a\u5bb9\u5668\u7684Pod\u3002 \u8fd0\u884c\u9700\u8981\u5171\u540c\u5de5\u4f5c\u7684\u591a\u4e2a\u5bb9\u5668\u7684Pod\u3002 \u201c\u6bcf\u4e2aPod\u4e00\u4e2a\u5bb9\u5668\u201d\u7684\u6a21\u578b\u662f\u6700\u5e38\u89c1\u7684Kubernetes\u7528\u4f8b\uff1b\u5728\u8fd9\u79cd\u60c5\u51b5\u4e0b\u53ef\u4ee5\u5c06Pod\u89c6\u4e3a\u5355\u4e2a\u5bb9\u5668\u7684\u5305\u88c5\u5668\uff1bKubernetes\u7ba1\u7406Pod\u800c\u4e0d\u662f\u76f4\u63a5\u7ba1\u7406\u5bb9\u5668\u3002 \u4e00\u4e2aPod\u53ef\u4ee5\u5c01\u88c5\u7531\u591a\u4e2a\u5171\u540c\u5b9a\u4f4d\u3001\u7d27\u5bc6\u8026\u5408\u4e14\u9700\u8981\u5171\u4eab\u8d44\u6e90\u7684\u5bb9\u5668\u7ec4\u6210\u7684\u5e94\u7528\u7a0b\u5e8f\u3002 \u8fd9\u4e9b\u5171\u540c\u5b9a\u4f4d\u7684\u5bb9\u5668\u5f62\u6210\u4e00\u4e2a\u5355\u4e00\u7684\u670d\u52a1\u6574\u4f53\u5355\u5143 - \u4f8b\u5982\uff0c\u4e00\u4e2a\u5bb9\u5668\u5411\u516c\u4f17\u63d0\u4f9b\u5b58\u50a8\u5728\u5171\u4eab\u5377\u4e2d\u7684\u6570\u636e\uff0c\u800c\u53e6\u4e00\u4e2a\u72ec\u7acb\u7684Sidecar\u5bb9\u5668\u5237\u65b0\u6216\u66f4\u65b0\u8fd9\u4e9b\u6587\u4ef6\u3002Pod\u5c06\u8fd9\u4e9b\u5bb9\u5668\u3001\u5b58\u50a8\u8d44\u6e90\u548c\u77ed\u6682\u7684\u7f51\u7edc\u6807\u8bc6\u5305\u88c5\u5728\u4e00\u8d77\uff0c\u4f5c\u4e3a\u4e00\u4e2a\u5355\u72ec\u7684\u5355\u4f4d\u3002 \u5728\u5355\u4e2aPod\u4e2d\u5206\u7ec4\u591a\u4e2a\u5171\u540c\u5b9a\u4f4d\u548c\u5171\u540c\u7ba1\u7406\u7684\u5bb9\u5668\u662f\u76f8\u5bf9\u9ad8\u7ea7\u7684\u7528\u4f8b\u3002\u5e94\u8be5*\u4ec5\u5728*\u5bb9\u5668\u7d27\u5bc6\u8026\u5408\u7684\u7279\u5b9a\u60c5\u51b5\u4e0b\u4f7f\u7528\u6b64\u6a21\u5f0f\u3002 \u6bcf\u4e2aPod\u90fd\u65e8\u5728\u8fd0\u884c\u7ed9\u5b9a\u5e94\u7528\u7a0b\u5e8f\u7684\u5355\u4e2a\u5b9e\u4f8b\u3002\u5982\u679c\u6211\u4eec\u60f3\u6c34\u5e73\u6269\u5c55\u60a8\u7684\u5e94\u7528\u7a0b\u5e8f\uff08\u901a\u8fc7\u8fd0\u884c\u66f4\u591a\u5b9e\u4f8b\u63d0\u4f9b\u66f4\u591a\u7684\u603b\u8d44\u6e90\uff09\uff0c\u5219\u5e94\u8be5\u4f7f\u7528\u591a\u4e2aPod\uff0c\u6bcf\u4e2a\u5b9e\u4f8b\u4e00\u4e2aPod\u3002\u5728Kubernetes\u4e2d\uff0c\u8fd9\u901a\u5e38\u79f0\u4e3a*\u590d\u5236*\u3002\u590d\u5236\u7684Pod\u901a\u5e38\u4f5c\u4e3a\u5de5\u4f5c\u8d1f\u8f7d\u8d44\u6e90\u53ca\u5176\u63a7\u5236\u5668\u7684\u4e00\u7ec4\u521b\u5efa\u548c\u7ba1\u7406\u3002 Pod\u672c\u5730\u63d0\u4f9b\u4e24\u79cd\u5171\u4eab\u8d44\u6e90\u4ee5\u4f9b\u5176\u7ec4\u6210\u5bb9\u5668\u4f7f\u7528\uff1a \u7f51\u7edc *\u548c \u5b58\u50a8 *\u3002 \u4e00\u4e2aPod\u53ef\u4ee5\u6307\u5b9a\u4e00\u7ec4\u5171\u4eab\u7684\u5b58\u50a8\u5377\u3002Pod\u4e2d\u7684\u6240\u6709\u5bb9\u5668\u90fd\u53ef\u4ee5\u8bbf\u95ee\u8fd9\u4e9b\u5171\u4eab\u5377\uff0c\u4f7f\u8fd9\u4e9b\u5bb9\u5668\u53ef\u4ee5\u5171\u4eab\u6570\u636e\u3002 \u6bcf\u4e2aPod\u4e3a\u6bcf\u4e2a\u5730\u5740\u65cf\u5206\u914d\u4e00\u4e2a\u552f\u4e00\u7684IP\u5730\u5740\u3002 \u5728\u4e00\u4e2aPod\u5185\uff0c\u5bb9\u5668\u5171\u4eab\u4e00\u4e2aIP\u5730\u5740\u548c\u7aef\u53e3\u7a7a\u95f4\uff0c\u5e76\u53ef\u4ee5\u901a\u8fc7\u201clocalhost\u201d\u627e\u5230\u5f7c\u6b64\u3002\u60f3\u8981\u4e0e\u8fd0\u884c\u5728\u4e0d\u540cPod\u4e2d\u7684\u5bb9\u5668\u4ea4\u4e92\u7684\u5bb9\u5668\u53ef\u4ee5\u4f7f\u7528IP\u7f51\u7edc\u8fdb\u884c\u901a\u4fe1\u3002 \u5f53\u521b\u5efa\u4e00\u4e2aPod\u65f6\uff0c\u65b0\u7684Pod\u88ab\u8c03\u5ea6\u5728\u96c6\u7fa4\u4e2d\u7684\u4e00\u4e2a\u8282\u70b9\u4e0a\u8fd0\u884c\u3002Pod\u4fdd\u7559\u5728\u8be5\u8282\u70b9\u4e0a\uff0c\u76f4\u5230Pod\u6267\u884c\u5b8c\u6bd5\u3001Pod\u5bf9\u8c61\u88ab\u5220\u9664\u3001Pod\u56e0\u7f3a\u4e4f\u8d44\u6e90\u800c\u88ab\u9a71\u9010\u6216\u8282\u70b9\u53d1\u751f\u6545\u969c\u3002 \u5728Pod\u4e2d\u91cd\u65b0\u542f\u52a8\u4e00\u4e2a\u5bb9\u5668\u4e0d\u5e94\u4e0e\u91cd\u65b0\u542f\u52a8\u4e00\u4e2aPod\u6df7\u6dc6\u3002Pod\u4e0d\u662f\u4e00\u4e2a\u8fdb\u7a0b\uff0c\u800c\u662f\u4e00\u4e2a\u8fd0\u884c\u5bb9\u5668\u7684\u73af\u5883\u3002Pod\u4f1a\u4e00\u76f4\u4fdd\u7559\uff0c\u76f4\u5230\u88ab\u5220\u9664\u4e3a\u6b62\u3002 \u60a8\u53ef\u4ee5\u4f7f\u7528\u5de5\u4f5c\u8d1f\u8f7d\u8d44\u6e90\uff08\u4f8b\u5982Deployment\u3001StatefulSet\u3001DaemonSet\uff09\u4e3a\u81ea\u5df1\u521b\u5efa\u548c\u7ba1\u7406\u591a\u4e2aPod\u3002\u8d44\u6e90\u7684\u63a7\u5236\u5668\u5904\u7406\u590d\u5236\u3001\u6eda\u52a8\u548c\u5728Pod\u5931\u8d25\u65f6\u7684\u81ea\u52a8\u6062\u590d\u3002","title":"Pods"},{"location":"k8s/cka_cn/foundamentals/memo/#_10","text":"\u4e00\u4e9bPod\u8fd8\u6709\u521d\u59cb\u5316\u5bb9\u5668\uff08Init containers\uff09\u548c\u5e94\u7528\u5bb9\u5668\uff08app containers\uff09\u3002\u521d\u59cb\u5316\u5bb9\u5668\u5728\u5e94\u7528\u5bb9\u5668\u542f\u52a8\u4e4b\u524d\u8fd0\u884c\u5e76\u5b8c\u6210\u3002 \u6211\u4eec\u53ef\u4ee5\u5728Pod\u89c4\u8303\u4e2d\u6307\u5b9a\u521d\u59cb\u5316\u5bb9\u5668\uff0c\u540c\u65f6\u4e5f\u53ef\u4ee5\u5728\u5bb9\u5668\u6570\u7ec4\u4e2d\u63cf\u8ff0\u5e94\u7528\u5bb9\u5668\u3002","title":"\u521d\u59cb\u5316\u5bb9\u5668"},{"location":"k8s/cka_cn/foundamentals/memo/#pod","text":"\u9759\u6001Pod\u662f\u76f4\u63a5\u7531\u7279\u5b9a\u8282\u70b9\u4e0a\u7684kubelet\u5b88\u62a4\u7a0b\u5e8f\u7ba1\u7406\u7684\uff0cAPI\u670d\u52a1\u5668\u4e0d\u4f1a\u89c2\u5bdf\u5b83\u4eec\u3002 \u9759\u6001Pod\u59cb\u7ec8\u7ed1\u5b9a\u5230\u7279\u5b9a\u8282\u70b9\u4e0a\u7684\u4e00\u4e2aKubelet\u3002 \u9759\u6001Pod\u7684\u4e3b\u8981\u7528\u9014\u662f\u8fd0\u884c\u81ea\u6258\u7ba1\u63a7\u5236\u9762\u677f\uff1a\u6362\u53e5\u8bdd\u8bf4\uff0c\u4f7f\u7528kubelet\u76d1\u7763\u5404\u4e2a\u63a7\u5236\u9762\u677f\u7ec4\u4ef6\u3002 kubelet\u4f1a\u81ea\u52a8\u5c1d\u8bd5\u4e3a\u6bcf\u4e2a\u9759\u6001Pod\u5728Kubernetes API\u670d\u52a1\u5668\u4e0a\u521b\u5efa\u4e00\u4e2a\u955c\u50cfPod\u3002\u8fd9\u610f\u5473\u7740\u5728\u8282\u70b9\u4e0a\u8fd0\u884c\u7684Pod\u5728API\u670d\u52a1\u5668\u4e0a\u53ef\u89c1\uff0c\u4f46\u65e0\u6cd5\u4ece\u90a3\u91cc\u63a7\u5236\u3002","title":"\u9759\u6001Pod"},{"location":"k8s/cka_cn/foundamentals/memo/#_11","text":"\u63a2\u9488\u662f kubelet \u5b9a\u671f\u5bf9\u5bb9\u5668\u6267\u884c\u7684\u4e00\u79cd\u8bca\u65ad\u3002 \u4e3a\u6267\u884c\u8bca\u65ad\uff0ckubelet \u8981\u4e48\u5728\u5bb9\u5668\u5185\u6267\u884c\u4ee3\u7801\uff0c\u8981\u4e48\u53d1\u8d77\u7f51\u7edc\u8bf7\u6c42\u3002 \u4f7f\u7528\u63a2\u9488\u6709\u56db\u79cd\u4e0d\u540c\u7684\u68c0\u67e5\u5bb9\u5668\u65b9\u5f0f\u3002\u6bcf\u4e2a\u63a2\u9488\u5fc5\u987b\u6070\u597d\u5b9a\u4e49\u8fd9\u56db\u79cd\u673a\u5236\u4e2d\u7684\u4e00\u79cd\uff1a exec \u3002\u5982\u679c\u547d\u4ee4\u4ee5\u72b6\u6001\u4ee3\u7801 0 \u9000\u51fa\uff0c\u5219\u5c06\u8bca\u65ad\u89c6\u4e3a\u6210\u529f\u3002 grpc \u3002\u5982\u679c\u54cd\u5e94\u7684\u72b6\u6001\u4e3a SERVING\uff0c\u5219\u5c06\u8bca\u65ad\u89c6\u4e3a\u6210\u529f\u3002 httpGet \u3002\u5982\u679c\u54cd\u5e94\u7684\u72b6\u6001\u4ee3\u7801\u5927\u4e8e\u6216\u7b49\u4e8e 200 \u4e14\u5c0f\u4e8e 400\uff0c\u5219\u5c06\u8bca\u65ad\u89c6\u4e3a\u6210\u529f\u3002 tcpSocket \u3002\u5982\u679c\u7aef\u53e3\u5f00\u653e\uff0c\u5219\u5c06\u8bca\u65ad\u89c6\u4e3a\u6210\u529f\u3002 \u6bcf\u4e2a\u63a2\u9488\u6709\u4e09\u79cd\u7ed3\u679c\uff1a \u6210\u529f \u5931\u8d25 \u672a\u77e5 \u63a2\u9488\u7c7b\u578b\uff1a livenessProbe \u3002\u6307\u793a\u5bb9\u5668\u662f\u5426\u6b63\u5728\u8fd0\u884c\u3002 readinessProbe \u3002\u6307\u793a\u5bb9\u5668\u662f\u5426\u51c6\u5907\u597d\u54cd\u5e94\u8bf7\u6c42\u3002 startupProbe \u3002\u6307\u793a\u5bb9\u5668\u5185\u7684\u5e94\u7528\u7a0b\u5e8f\u662f\u5426\u542f\u52a8\u3002","title":"\u5bb9\u5668\u63a2\u9488"},{"location":"k8s/cka_cn/foundamentals/memo/#deployment","text":"","title":"Deployment"},{"location":"k8s/cka_cn/foundamentals/memo/#replicaset","text":"ReplicaSet\u7684\u76ee\u7684\u662f\u5728\u4efb\u4f55\u65f6\u5019\u7ef4\u62a4\u4e00\u7ec4\u7a33\u5b9a\u7684\u526f\u672cPod\u3002\u56e0\u6b64\uff0c\u5b83\u901a\u5e38\u7528\u4e8e\u4fdd\u8bc1\u6307\u5b9a\u6570\u91cf\u7684\u76f8\u540cPod\u7684\u53ef\u7528\u6027\u3002 \u6211\u4eec\u4e00\u822c\u4e0d\u9700\u8981\u76f4\u63a5\u64cd\u7eb5ReplicaSet\u5bf9\u8c61\uff1a\u4f7f\u7528Deployment\uff0c\u7136\u540e\u5728spec\u90e8\u5206\u4e2d\u5b9a\u4e49\u60a8\u7684\u5e94\u7528\u7a0b\u5e8f\u3002 \u53ef\u4ee5\u901a\u8fc7\u8bbe\u7f6e replicaset.spec.replicas \u6765\u6307\u5b9a\u5e94\u540c\u65f6\u8fd0\u884c\u591a\u5c11\u4e2aPod\u3002 ReplicaSet\u5c06\u521b\u5efa/\u5220\u9664\u5176Pod\u4ee5\u5339\u914d\u6b64\u6570\u5b57\u3002 \u5982\u679c\u4e0d\u6307\u5b9a replicaset.spec.replicas \uff0c\u5219\u9ed8\u8ba4\u503c\u4e3a 1 \u3002","title":"ReplicaSet"},{"location":"k8s/cka_cn/foundamentals/memo/#statefulset","text":"StatefulSet \u7279\u70b9\uff08\u53c8\u79f0\u56fa\u5b9a\u6807\u8bc6\uff09\uff1a Pod \u7684\u540d\u79f0\u5728\u521b\u5efa\u540e\u4e0d\u53ef\u53d8\u3002 DNS \u4e3b\u673a\u540d\u5728\u521b\u5efa\u540e\u4e0d\u53ef\u53d8\u3002 \u6302\u8f7d\u7684\u5377\u5728\u521b\u5efa\u540e\u4e0d\u53ef\u53d8\u3002 StatefulSet \u7684\u56fa\u5b9a\u6807\u8bc6\u5728\u5931\u8d25\u3001\u6269\u5c55\u548c\u5176\u4ed6\u64cd\u4f5c\u540e\u4e0d\u4f1a\u6539\u53d8\u3002 StatefulSet \u7684\u547d\u540d\u7ea6\u5b9a\u4e3a\uff1a - \u3002 StatefulSet \u53ef\u4ee5\u81ea\u884c\u8fdb\u884c\u6269\u5c55\uff0c\u4f46\u662f Deployment \u9700\u8981\u4f9d\u9760 ReplicaSet \u8fdb\u884c\u6269\u5c55\u3002 \u5efa\u8bae\uff1a\u5148\u5c06 StatefulSet \u51cf\u5c11\u5230 0\uff0c\u800c\u4e0d\u662f\u76f4\u63a5\u5220\u9664\u5b83\u3002 headless Service \u548c governing Service\uff1a Headless Service \u662f\u4e00\u4e2a\u666e\u901a\u7684 Kubernetes Service \u5bf9\u8c61\uff0c\u5176 spec.clusterIP \u88ab\u8bbe\u7f6e\u4e3a None \u3002 \u5f53 StatefulSet \u7684 spec.ServiceName \u8bbe\u7f6e\u4e3a headless Service \u540d\u79f0\u65f6\uff0cStatefulSet \u73b0\u5728\u662f\u4e00\u4e2a governing Service\u3002 \u521b\u5efa StatefulSet \u7684\u4e00\u822c\u8fc7\u7a0b\uff1a \u521b\u5efa StorageClass\u3002 \u521b\u5efa Headless Service\u3002 \u57fa\u4e8e\u4e0a\u8ff0\u4e24\u4e2a\u521b\u5efa StatefulSet\u3002","title":"StatefulSet"},{"location":"k8s/cka_cn/foundamentals/memo/#daemonset","text":"DaemonSet\u4fdd\u8bc1\u6240\u6709\uff08\u6216\u90e8\u5206\uff09\u8282\u70b9\u8fd0\u884cPod\u7684\u526f\u672c\u3002\u968f\u7740\u8282\u70b9\u4ece\u96c6\u7fa4\u4e2d\u5220\u9664\uff0c\u8fd9\u4e9bPod\u5c06\u88ab\u5783\u573e\u56de\u6536\u3002 \u5220\u9664DaemonSet\u5c06\u6e05\u7406\u5b83\u521b\u5efa\u7684Pod\u3002 \u4e00\u4e9b\u5178\u578bDaemonSet\u7684\u7528\u9014\u5305\u62ec\uff1a \u5728\u6bcf\u4e2a\u8282\u70b9\u4e0a\u8fd0\u884c\u96c6\u7fa4\u5b58\u50a8\u5b88\u62a4\u7a0b\u5e8f\u3002 \u5728\u6bcf\u4e2a\u8282\u70b9\u4e0a\u8fd0\u884c\u65e5\u5fd7\u6536\u96c6\u5b88\u62a4\u7a0b\u5e8f\u3002 \u5728\u6bcf\u4e2a\u8282\u70b9\u4e0a\u8fd0\u884c\u8282\u70b9\u76d1\u89c6\u5b88\u62a4\u7a0b\u5e8f\u3002 \u5728\u7b80\u5355\u7684\u60c5\u51b5\u4e0b\uff0c\u6bcf\u79cd\u7c7b\u578b\u7684\u5b88\u62a4\u7a0b\u5e8f\u5c06\u4f7f\u7528\u8986\u76d6\u6240\u6709\u8282\u70b9\u7684\u4e00\u4e2aDaemonSet\u3002 \u66f4\u590d\u6742\u7684\u8bbe\u7f6e\u53ef\u80fd\u4f1a\u4e3a\u5355\u4e2a\u5b88\u62a4\u7a0b\u5e8f\u4f7f\u7528\u591a\u4e2aDaemonSet\uff0c\u4f46\u4f7f\u7528\u4e0d\u540c\u7684\u6807\u5fd7\u548c/\u6216\u4e0d\u540c\u7684\u5185\u5b58\u548cCPU\u8bf7\u6c42\u6765\u652f\u6301\u4e0d\u540c\u7684\u786c\u4ef6\u7c7b\u578b\u3002 DaemonSet\u63a7\u5236\u5668\u8c03\u548c\u8fc7\u7a0b\u540c\u65f6\u68c0\u67e5\u73b0\u6709\u8282\u70b9\u548c\u65b0\u521b\u5efa\u7684\u8282\u70b9\u3002 \u9ed8\u8ba4\u60c5\u51b5\u4e0b\uff0cKubernetes\u8c03\u5ea6\u7a0b\u5e8f\u5ffd\u7565\u7531DamonSet\u521b\u5efa\u7684Pod\uff0c\u5e76\u5141\u8bb8\u5b83\u4eec\u5b58\u5728\u4e8e\u8282\u70b9\u4e0a\uff0c\u76f4\u5230\u5173\u95ed\u8282\u70b9\u672c\u8eab\u3002 \u5728\u9009\u62e9\u8282\u70b9\u4e0a\u8fd0\u884cPod\uff1a \u5982\u679c\u60a8\u6307\u5b9a daemonset.spec.template.spec.nodeSelector \uff0c\u90a3\u4e48DaemonSet\u63a7\u5236\u5668\u5c06\u5728\u4e0e\u8be5\u8282\u70b9\u9009\u62e9\u5668\u5339\u914d\u7684\u8282\u70b9\u4e0a\u521b\u5efaPod\u3002 \u5982\u679c\u60a8\u6307\u5b9a daemonset.spec.template.spec.affinity \uff0c\u90a3\u4e48DaemonSet\u63a7\u5236\u5668\u5c06\u5728\u4e0e\u8be5\u8282\u70b9\u4eb2\u548c\u529b\u5339\u914d\u7684\u8282\u70b9\u4e0a\u521b\u5efaPod\u3002 \u5982\u679c\u4e24\u8005\u90fd\u4e0d\u6307\u5b9a\uff0c\u5219DaemonSet\u63a7\u5236\u5668\u5c06\u5728\u6240\u6709\u8282\u70b9\u4e0a\u521b\u5efaPod\u3002 \u5728 kubectl explain daemonset.spec \u4e2d\u6ca1\u6709 replicas \u5b57\u6bb5\u4e0e kubectl explain deployment.spec.replicas \u76f8\u5bf9\u5e94\u3002\u5f53\u521b\u5efa\u4e00\u4e2aDaemonSet\u65f6\uff0c\u6bcf\u4e2a\u8282\u70b9\u5c06\u8fd0\u884c*\u4e00\u4e2a* DaemonSet Pod\u3002 \u5bf9\u4e8e\u670d\u52a1\uff0c\u901a\u5e38\u662f\u65e0\u72b6\u6001\u7684\uff0c\u4e00\u822c\u4e0d\u5173\u5fc3\u8282\u70b9\u5728\u54ea\u91cc\u8fd0\u884c\uff0c\u66f4\u5173\u5fc3Pod\u526f\u672c\u7684\u6570\u91cf\uff0c\u5e76\u4e14\u6211\u4eec\u53ef\u4ee5\u5c06\u8fd9\u4e9b\u526f\u672c/replicas\u7f29\u653e\u3002\u5728\u8fd9\u91cc\uff0c\u6eda\u52a8\u66f4\u65b0\u4e5f\u5c06\u662f\u4e00\u4e2a\u4f18\u70b9\u3002 \u5f53Pod\u7684\u4e00\u4e2a\u526f\u672c\u5fc5\u987b\u5728\u67d0\u4e2a\u6307\u5b9a\u8282\u70b9\u4e0a\u8fd0\u884c\u65f6\uff0c\u6211\u4eec\u5c06\u4f7f\u7528 DaemonSet \u3002\u6211\u4eec\u7684\u5b88\u62a4\u8fdb\u7a0bPod\u8fd8\u9700\u8981\u5728\u6211\u4eec\u7684\u5176\u4ed6Pod\u4e4b\u524d\u542f\u52a8\u3002 DaemonSet\u662f\u7528\u4e8e\u540e\u53f0\u670d\u52a1\u7684\u7b80\u5355\u53ef\u6269\u5c55\u6027\u7b56\u7565\u3002\u5f53\u66f4\u591a\u7684\u5408\u9002\u7684\u8282\u70b9\u6dfb\u52a0\u5230\u96c6\u7fa4\u65f6\uff0c\u540e\u53f0\u670d\u52a1\u5c06\u6269\u5c55\u3002\u5f53\u8282\u70b9\u88ab\u5220\u9664\u65f6\uff0c\u5b83\u5c06\u81ea\u52a8\u7f29\u5c0f\u3002","title":"DaemonSet"},{"location":"k8s/cka_cn/foundamentals/memo/#job","text":"","title":"Job"},{"location":"k8s/cka_cn/foundamentals/memo/#cronjob","text":"","title":"CronJob"},{"location":"k8s/cka_cn/foundamentals/memo/#_12","text":"","title":"\u670d\u52a1\u8d44\u6e90"},{"location":"k8s/cka_cn/foundamentals/memo/#service","text":"Service\u662f\u8f6f\u4ef6\u670d\u52a1\uff08\u4f8b\u5982mysql\uff09\u7684\u547d\u540d\u62bd\u8c61\uff0c\u7531\u4ee3\u7406\u76d1\u542c\u7684\u672c\u5730\u7aef\u53e3\uff08\u4f8b\u59823306\uff09\u548c\u786e\u5b9a\u54ea\u4e9bPod\u5c06\u56de\u7b54\u901a\u8fc7\u4ee3\u7406\u53d1\u9001\u7684\u8bf7\u6c42\u7684\u9009\u62e9\u5668\u7ec4\u6210\u3002 \u4e00\u4e2aService\u7684\u76ee\u6807Pod\u96c6\u5408\u901a\u5e38\u7531\u4e00\u4e2a\u9009\u62e9\u5668\uff08\u6807\u7b7e\u9009\u62e9\u5668\uff09\u6765\u786e\u5b9a\u3002 Service\u8d44\u6e90\u7684\u7c7b\u578b\u5305\u62ec\uff1a ClusterIP Service\uff08\u9ed8\u8ba4\uff09\uff1a\u53ef\u9760\u7684IP\u3001DNS\u548c\u7aef\u53e3\u3002\u4ec5\u9650\u5185\u90e8\u8bbf\u95ee\u3002 NodePort Service\uff1a\u5411\u5916\u90e8\u63d0\u4f9b\u8bbf\u95ee\u3002 LoadBalancer\uff1a\u57fa\u4e8eNodePort\uff0c\u5e76\u4e0e\u4e91\u4f9b\u5e94\u5546\u63d0\u4f9b\u7684\u8d1f\u8f7d\u5e73\u8861\u96c6\u6210\uff08\u4f8b\u5982AWS\u3001GCP\u7b49\uff09\u3002 ExternalName\uff1a\u8bbf\u95ee\u5c06\u88ab\u8f6c\u53d1\u5230\u5916\u90e8\u670d\u52a1\u3002 \u4e0b\u9762\u662f\u4e00\u4e2a\u521b\u5efa\u7b80\u5355Service\u7684yaml\u6587\u4ef6\uff1a apiVersion : v1 kind : Service metadata : name : nginx-service labels : tier : application spec : ports : - port : 80 protocol : TCP targetPort : 8080 selector : run : nginx type : NodePort \u4e0b\u9762\u662f\u4e00\u4e2aService\u7684\u4f8b\u5b50\uff1a IP 10.96.17.77 \u662f\u8be5\u670d\u52a1\u7684 ClusterIP(VIP)\u3002 \u7aef\u53e3 80/TCP \u662f Pod \u5728\u96c6\u7fa4\u5185\u76d1\u542c\u7684\u7aef\u53e3\u3002 TargetPort 8080/TCP \u662f\u5bb9\u5668\u5185\u670d\u52a1\u5e94\u8be5\u5b9a\u5411\u6d41\u91cf\u5230\u8fbe\u7684\u7aef\u53e3\u3002 NodePort 31893/TCP \u662f\u53ef\u4ee5\u4ece\u5916\u90e8\u8bbf\u95ee\u7684\u7aef\u53e3\u3002\u9ed8\u8ba4\u8303\u56f4\u662f 30000~32767 \u3002\u8be5\u7aef\u53e3\u4f1a\u5728\u6574\u4e2a\u96c6\u7fa4\u7684\u6240\u6709\u8282\u70b9\u4e0a\u66b4\u9732\u3002 Endpoints \u663e\u793a\u4e86\u5339\u914d\u670d\u52a1\u6807\u7b7e\u7684 Pod \u5217\u8868\u3002 Name : nginx-deployment Namespace : jh-namespace Labels : tier=application Annotations : Selector : run=nginx Type : NodePort IP Family Policy : SingleStack IP Families : IPv4 IP : 10.96.17.77 IPs : 10.96.17.77 Port : 80/TCP TargetPort : 8080/TCP NodePort : 31893/TCP Endpoints : 10.244.1.177:8080,10.244.1.178:8080,10.244.1.179:8080 + 7 more... Session Affinity : None External Traffic Policy : Cluster Events : \u5728 Kubernetes \u96c6\u7fa4\u4e2d\uff0c\u57fa\u4e8eDeployment coredns \u7684Service kube-dns \u63d0\u4f9b\u4e86\u96c6\u7fa4 DNS \u670d\u52a1\u3002 \u670d\u52a1\u6ce8\u518c\uff1a Kubernetes \u4f7f\u7528\u96c6\u7fa4 DNS \u4f5c\u4e3a\u670d\u52a1\u6ce8\u518c\u3002 \u6ce8\u518c\u662f\u57fa\u4e8e Service \u800c\u975e Pod \u7684\u3002 \u96c6\u7fa4 DNS\uff08CoreDNS\uff09\u4e3b\u52a8\u76d1\u89c6\u548c\u53d1\u73b0\u65b0\u670d\u52a1\u3002 Service \u540d\u79f0\u3001IP\u3001\u7aef\u53e3\u5c06\u88ab\u6ce8\u518c\u3002 Service \u6ce8\u518c\u7684\u8fc7\u7a0b\u5982\u4e0b\uff1a \u5c06\u65b0\u7684 Service POST \u5230 API Server\u3002 \u4e3a\u65b0\u7684 Service \u5206\u914d ClusterIP\u3002 \u5c06\u65b0\u7684 Service \u914d\u7f6e\u4fe1\u606f\u4fdd\u5b58\u5230 etcd \u4e2d\u3002 \u521b\u5efa\u4e0e\u65b0 Service \u5173\u8054\u7684\u5e26\u6709\u76f8\u5173 Pod IP \u7684 endpoints\u3002 \u901a\u8fc7 ClusterDNS \u63a2\u7d22\u65b0\u7684 Service\u3002 \u521b\u5efa DNS \u4fe1\u606f\u3002 kube-proxy \u83b7\u53d6 Service \u914d\u7f6e\u4fe1\u606f\u3002 \u521b\u5efa IPSV \u89c4\u5219\u3002 Service \u53d1\u73b0\u7684\u8fc7\u7a0b\u3002 \u8bf7\u6c42\u4e00\u4e2a Service \u540d\u79f0\u7684 DNS \u540d\u79f0\u89e3\u6790\u3002 \u6536\u5230 ClusterIP\u3002 \u8bbf\u95ee ClusterIP\u3002 \u6ca1\u6709\u8def\u7531\u5668\u3002\u5c06\u8bf7\u6c42\u8f6c\u53d1\u5230 Pod \u7684\u9ed8\u8ba4\u7f51\u5173\u3002 \u5c06\u8bf7\u6c42\u8f6c\u53d1\u5230\u8282\u70b9\u3002 \u6ca1\u6709\u8def\u7531\u5668\u3002\u5c06\u8bf7\u6c42\u8f6c\u53d1\u5230\u8282\u70b9\u7684\u9ed8\u8ba4\u7f51\u5173\u3002 \u8282\u70b9\u5185\u6838\u7ee7\u7eed\u5904\u7406\u8bf7\u6c42\u3002 \u4f7f\u7528 IPSV \u89c4\u5219\u6355\u83b7\u8bf7\u6c42\u3002 \u5c06\u76ee\u6807 Pod \u7684 IP \u653e\u5165\u8bf7\u6c42\u7684\u76ee\u6807 IP \u4e2d\u3002 \u8bf7\u6c42\u5230\u8fbe\u76ee\u6807 Pod\u3002 FQDN\u683c\u5f0f\u4e3a\uff1a ..svc.cluster.local \u3002\u6211\u4eec\u79f0 \u4e3a\u975e\u9650\u5b9a\u540d\u79f0\u6216\u7b80\u77ed\u540d\u79f0\u3002 \u547d\u540d\u7a7a\u95f4\u53ef\u4ee5\u9694\u79bb\u96c6\u7fa4\u7684\u5730\u5740\u7a7a\u95f4\u3002\u540c\u65f6\uff0c\u5b83\u8fd8\u53ef\u4ee5\u7528\u4e8e\u5b9e\u73b0\u8bbf\u95ee\u63a7\u5236\u548c\u8d44\u6e90\u914d\u989d\u3002 \u83b7\u53d6Pod\u4e2d\u7684DNS\u914d\u7f6e\u3002 nameserver\u7684IP\u4e0ekube-dns\u670d\u52a1\u7684ClusterIP\u76f8\u540c\uff0c\u8fd9\u662f\u7528\u4e8eDNS\u8bf7\u6c42\u6216\u670d\u52a1\u53d1\u73b0\u8bf7\u6c42\u7684\u4f17\u6240\u5468\u77e5\u7684IP\u3002 $ kubectl get service kube-dns -n kube-system NAME TYPE CLUSTER-IP EXTERNAL-IP PORT ( S ) AGE kube-dns ClusterIP 10 .96.0.10 53 /UDP,53/TCP,9153/TCP 7d7h $ kubectl exec -it nginx-5f5496dc9-bv5dx -- /bin/bash root@nginx-5f5496dc9-bv5dx:/# cat /etc/resolv.conf search jh-namespace.svc.cluster.local svc.cluster.local cluster.local nameserver 10 .96.0.10 options ndots:5 \u8bfb\u53d6 kube-dns \u4fe1\u606f\uff1a $ kubectl describe service kube-dns -n kube-system Name: kube-dns Namespace: kube-system Labels: k8s-app = kube-dns kubernetes.io/cluster-service = true kubernetes.io/name = CoreDNS Annotations: prometheus.io/port: 9153 prometheus.io/scrape: true Selector: k8s-app = kube-dns Type: ClusterIP IP Family Policy: SingleStack IP Families: IPv4 IP: 10 .96.0.10 IPs: 10 .96.0.10 Port: dns 53 /UDP TargetPort: 53 /UDP Endpoints: 10 .244.0.2:53,10.244.0.3:53 Port: dns-tcp 53 /TCP TargetPort: 53 /TCP Endpoints: 10 .244.0.2:53,10.244.0.3:53 Port: metrics 9153 /TCP TargetPort: 9153 /TCP Endpoints: 10 .244.0.2:9153,10.244.0.3:9153 Session Affinity: None Events: ","title":"Service"},{"location":"k8s/cka_cn/foundamentals/memo/#endpoints","text":"Endpoints\u662f\u4e00\u7ec4\u5b9e\u73b0\u5b9e\u9645\u670d\u52a1\u7684\u7aef\u70b9\u96c6\u5408\u3002 \u5f53\u521b\u5efa\u670d\u52a1\u65f6\uff0c\u5b83\u4f1a\u4e0e\u4e00\u4e2aEndpoint\u5bf9\u8c61\u76f8\u5173\u8054\uff0c\u53ef\u4ee5\u4f7f\u7528\u547d\u4ee4 kubectl get endpoints \u83b7\u53d6\u3002 \u5339\u914d\u670d\u52a1\u6807\u7b7e\u7684Pod\u5217\u8868\u7ef4\u62a4\u4e3aEndpoint\u5bf9\u8c61\uff0c\u6dfb\u52a0\u65b0\u7684\u5339\u914dPod\u5e76\u5220\u9664\u4e0d\u5339\u914d\u7684Pod\u3002","title":"Endpoints"},{"location":"k8s/cka_cn/foundamentals/memo/#_13","text":"","title":"\u914d\u7f6e\u548c\u5b58\u50a8\u8d44\u6e90"},{"location":"k8s/cka_cn/foundamentals/memo/#_14","text":"","title":"\u5377"},{"location":"k8s/cka_cn/foundamentals/memo/#emptydir","text":"emptyDir \u5377\u662f\u5728Pod\u5206\u914d\u5230\u8282\u70b9\u65f6\u9996\u5148\u521b\u5efa\u7684\uff0c\u5e76\u4e14\u53ea\u8981\u8be5Pod\u5728\u8be5\u8282\u70b9\u4e0a\u8fd0\u884c\uff0c\u5b83\u5c31\u4f1a\u5b58\u5728\u3002 emptyDir \u5377\u6700\u521d\u4e3a\u7a7a\u3002 Pod\u4e2d\u7684\u6240\u6709\u5bb9\u5668\u90fd\u53ef\u4ee5\u8bfb\u53d6\u548c\u5199\u5165 emptyDir \u5377\u4e2d\u7684\u76f8\u540c\u6587\u4ef6\uff0c\u5c3d\u7ba1\u8be5\u5377\u53ef\u4ee5\u5728\u6bcf\u4e2a\u5bb9\u5668\u4e2d\u4ee5\u76f8\u540c\u6216\u4e0d\u540c\u7684\u8def\u5f84\u6302\u8f7d\u3002 \u5f53\u7531\u4e8e\u4efb\u4f55\u539f\u56e0\u4ece\u8282\u70b9\u4e2d\u5220\u9664Pod\u65f6\uff0c emptyDir \u4e2d\u7684\u6570\u636e\u5c06\u6c38\u4e45\u5220\u9664\u3002 \u5bb9\u5668\u5d29\u6e83\u4e0d\u4f1a\u5c06Pod\u4ece\u8282\u70b9\u4e2d\u5220\u9664\u3002 emptyDir \u5377\u4e2d\u7684\u6570\u636e\u53ef\u4ee5\u5728\u5bb9\u5668\u5d29\u6e83\u65f6\u5b89\u5168\u4fdd\u7559\u3002 \u7528\u9014\uff1a \u4e34\u65f6\u7a7a\u95f4\uff0c\u4f8b\u5982\u57fa\u4e8e\u78c1\u76d8\u7684\u5f52\u5e76\u6392\u5e8f \u4e3a\u4e86\u4ece\u5d29\u6e83\u4e2d\u6062\u590d\u800c\u8fdb\u884c\u7684\u957f\u65f6\u95f4\u8ba1\u7b97\u7684\u68c0\u67e5\u70b9 \u4fdd\u5b58\u5185\u5bb9\u7ba1\u7406\u5668\u5bb9\u5668\u63d0\u53d6\u7684\u6587\u4ef6\uff0c\u540c\u65f6Web\u670d\u52a1\u5668\u5bb9\u5668\u63d0\u4f9b\u6570\u636e","title":"emptyDir"},{"location":"k8s/cka_cn/foundamentals/memo/#hostpath","text":"hostPath \u5377\u5c06\u4e3b\u673a\u8282\u70b9\u6587\u4ef6\u7cfb\u7edf\u4e2d\u7684\u6587\u4ef6\u6216\u76ee\u5f55\u6302\u8f7d\u5230 Pod \u4e2d\u3002\u8fd9\u4e0d\u662f\u5927\u591a\u6570 Pod \u90fd\u9700\u8981\u7684\uff0c\u4f46\u5bf9\u4e8e\u67d0\u4e9b\u5e94\u7528\u7a0b\u5e8f\u6765\u8bf4\uff0c\u5b83\u63d0\u4f9b\u4e86\u4e00\u4e2a\u5f3a\u5927\u7684\u9003\u751f\u53e3\u3002 hostPath \u5377\u5b58\u5728\u8bb8\u591a\u5b89\u5168\u98ce\u9669\uff0c\u56e0\u6b64\u5728\u53ef\u80fd\u7684\u60c5\u51b5\u4e0b\u6700\u597d\u907f\u514d\u4f7f\u7528 HostPath\u3002\u5f53\u5fc5\u987b\u4f7f\u7528 HostPath \u5377\u65f6\uff0c\u5e94\u5c06\u5176\u8303\u56f4\u9650\u5b9a\u4e3a\u4ec5\u6240\u9700\u7684\u6587\u4ef6\u6216\u76ee\u5f55\uff0c\u5e76\u4ee5\u53ea\u8bfb\u65b9\u5f0f\u6302\u8f7d\u3002 \u5982\u679c\u901a\u8fc7 AdmissionPolicy \u9650\u5236 HostPath \u8bbf\u95ee\u7279\u5b9a\u76ee\u5f55\uff0c\u5219\u5fc5\u987b\u8981\u6c42 volumeMounts \u4f7f\u7528 readOnly \u6302\u8f7d\uff0c\u4ee5\u4f7f\u7b56\u7565\u751f\u6548\u3002 \u7528\u9014\uff1a \u4e0e DaemonSet \u4e00\u8d77\u8fd0\u884c\uff0c\u4f8b\u5982\uff0cEFK Fluentd \u6302\u8f7d\u672c\u5730\u4e3b\u673a\u7684\u65e5\u5fd7\u76ee\u5f55\u4ee5\u6536\u96c6\u4e3b\u673a\u65e5\u5fd7\u4fe1\u606f\u3002 \u901a\u8fc7\u4f7f\u7528 hostPath \u5377\u5728\u7279\u5b9a\u8282\u70b9\u4e0a\u8fd0\u884c\uff0c\u53ef\u4ee5\u83b7\u5f97\u9ad8\u6027\u80fd\u7684\u78c1\u76d8 I/O\u3002 \u8fd0\u884c\u9700\u8981\u8bbf\u95ee Docker \u5185\u90e8\u7684\u5bb9\u5668\uff1b\u4f7f\u7528 /var/lib/docker \u7684 hostPath\u3002 \u5728\u5bb9\u5668\u4e2d\u8fd0\u884c cAdvisor\uff1b\u4f7f\u7528 /sys \u7684 hostPath\u3002 \u5141\u8bb8 Pod \u6307\u5b9a\u7ed9\u5b9a\u7684 hostPath \u662f\u5426\u5e94\u8be5\u5728 Pod \u8fd0\u884c\u4e4b\u524d\u5b58\u5728\uff0c\u662f\u5426\u5e94\u8be5\u521b\u5efa\u5b83\u4ee5\u53ca\u5b83\u5e94\u8be5\u5b58\u5728\u7684\u5185\u5bb9\u3002","title":"hostPath"},{"location":"k8s/cka_cn/foundamentals/memo/#storage-class","text":"StorageClass \u90e8\u7f72\u548c\u5b9e\u73b0\u7684\u6b65\u9aa4\u5982\u4e0b\uff1a \u521b\u5efa Kubernetes \u96c6\u7fa4\u548c\u540e\u7aef\u5b58\u50a8\u3002 \u786e\u4fdd Kubernetes \u4e2d\u7684 provisioner/plugin \u53ef\u7528\u3002 \u521b\u5efa\u4e00\u4e2a StorageClass \u5bf9\u8c61\u5e76\u5c06\u5176\u94fe\u63a5\u5230\u540e\u7aef\u5b58\u50a8\u3002StorageClass \u5c06\u81ea\u52a8\u521b\u5efa\u76f8\u5173\u7684 PV\u3002 \u521b\u5efa\u4e00\u4e2a PVC \u5bf9\u8c61\u5e76\u5c06\u5176\u94fe\u63a5\u5230\u6211\u4eec\u521b\u5efa\u7684 StorageClass\u3002 \u90e8\u7f72\u4e00\u4e2a Pod \u5e76\u4f7f\u7528 PVC \u5377\u3002","title":"Storage Class"},{"location":"k8s/cka_cn/foundamentals/memo/#pv","text":"PV\u56de\u6536\u7b56\u7565\uff1a \u4fdd\u7559 (Retain) \u5220\u9664 (Delete) \u56de\u6536 (Recycle) PV in-tree\u7c7b\u578b\uff1a hostPath local NFS CSI","title":"PV"},{"location":"k8s/cka_cn/foundamentals/memo/#access-modes","text":"Access Modes\uff08\u8bbf\u95ee\u6a21\u5f0f\uff09\u4e2d\uff0c spec.accessModes \u5b9a\u4e49\u4e86 PV \u7684\u6302\u8f7d\u9009\u9879\uff1a ReadWriteOnce(RWO)\uff1a\u4e00\u4e2a PV \u53ea\u80fd\u88ab\u4e00\u4e2a\u8bfb\u5199\u6a21\u5f0f\u7684 PVC \u6302\u8f7d\uff0c\u7c7b\u4f3c\u4e8e\u5757\u8bbe\u5907\u3002 ReadWriteMany(RWM)\uff1a\u4e00\u4e2a PV \u53ef\u4ee5\u88ab\u591a\u4e2a\u8bfb\u5199\u6a21\u5f0f\u7684 PVC \u6302\u8f7d\uff0c\u4f8b\u5982 NFS\u3002 ReadOnlyMany(ROM)\uff1a\u4e00\u4e2a PV \u53ef\u4ee5\u88ab\u591a\u4e2a\u53ea\u8bfb\u6a21\u5f0f\u7684 PVC \u6302\u8f7d\u3002 ReadWriteOncePod(RWOP)\uff1a\u53ea\u652f\u6301 CSI \u7c7b\u578b\u7684 PV\uff0c\u53ea\u80fd\u88ab\u5355\u4e2a Pod \u6302\u8f7d\u3002 \u4e00\u4e2a PV \u53ea\u80fd\u8bbe\u7f6e\u4e00\u79cd\u9009\u9879\u3002Pod \u6302\u8f7d PVC\uff0c\u800c\u4e0d\u662f PV\u3002","title":"Access Modes"},{"location":"k8s/cka_cn/foundamentals/namespace/","text":"CKA\u81ea\u5b66\u7b14\u8bb011:Namespace \u00b6 \u6f14\u793a\u573a\u666f \u00b6 \u83b7\u53d6namespace\u5217\u8868 \u521b\u5efa\u65b0\u7684namespace \u7ed9namespace\u8bbe\u5b9a\u6807\u7b7e \u5220\u9664\u4e00\u4e2anamespace \u6f14\u793a \u00b6 \u83b7\u53d6\u5f53\u524dnamespace\u5217\u8868\u3002 kubectl get namespace \u83b7\u53d6\u5f53\u524dnamespace\u5217\u8868\u548c\u5bf9\u5e94\u6807\u7b7e\u4fe1\u606f\u3002 kubectl get ns --show-labels \u521b\u5efa\u4e00\u4e2anamespace cka \u3002 kubectl create namespace cka \u7ed9\u65b0\u521b\u5efa\u7684namespace cka \u8bbe\u5b9a\u6807\u7b7e\u3002 kubectl label ns cka cka = true \u5728namespace cka \u4e0a\u521b\u5efa Nginx Deployment\u3002 kubectl create deploy nginx --image = nginx --namespace cka \u5728namespace cka \u4e0a\u68c0\u67e5\u6b63\u5728\u8fd0\u884c\u7684deployment\u548cpod\u3002 kubectl get deploy,pod -n cka \u8fd0\u884c\u7ed3\u679c\uff1a NAME READY UP-TO-DATE AVAILABLE AGE deployment.apps/nginx 1/1 1 1 2m14s NAME READY STATUS RESTARTS AGE pod/nginx-85b98978db-bmkhf 1/1 Running 0 2m14s \u5220\u9664namespace cka \uff0c\u5219\u6240\u6709\u8fd0\u884c\u5728\u8fd9\u4e2anamespace\u4e0a\u7684\u8d44\u6e90\u90fd\u4f1a\u88ab\u5220\u9664\u3002 kubectl delete ns cka \u5982\u679c\u5728\u5220\u9664\u67d0\u4e2anamespace\u65f6\u9047\u5230\u72b6\u6001\u4e00\u76f4\u662f Terminating \uff0c\u5219\u53ef\u4ee5\u5c1d\u8bd5\u7528\u4e0b\u9762\u7684\u65b9\u6cd5\u89e3\u51b3\u3002 kubectl get namespace $NAMESPACE -o json | sed -e 's/\"kubernetes\"//' | kubectl replace --raw \"/api/v1/namespaces $NAMESPACE /finalize\" -f -","title":"Namespace"},{"location":"k8s/cka_cn/foundamentals/namespace/#cka11namespace","text":"","title":"CKA\u81ea\u5b66\u7b14\u8bb011:Namespace"},{"location":"k8s/cka_cn/foundamentals/namespace/#_1","text":"\u83b7\u53d6namespace\u5217\u8868 \u521b\u5efa\u65b0\u7684namespace \u7ed9namespace\u8bbe\u5b9a\u6807\u7b7e \u5220\u9664\u4e00\u4e2anamespace","title":"\u6f14\u793a\u573a\u666f"},{"location":"k8s/cka_cn/foundamentals/namespace/#_2","text":"\u83b7\u53d6\u5f53\u524dnamespace\u5217\u8868\u3002 kubectl get namespace \u83b7\u53d6\u5f53\u524dnamespace\u5217\u8868\u548c\u5bf9\u5e94\u6807\u7b7e\u4fe1\u606f\u3002 kubectl get ns --show-labels \u521b\u5efa\u4e00\u4e2anamespace cka \u3002 kubectl create namespace cka \u7ed9\u65b0\u521b\u5efa\u7684namespace cka \u8bbe\u5b9a\u6807\u7b7e\u3002 kubectl label ns cka cka = true \u5728namespace cka \u4e0a\u521b\u5efa Nginx Deployment\u3002 kubectl create deploy nginx --image = nginx --namespace cka \u5728namespace cka \u4e0a\u68c0\u67e5\u6b63\u5728\u8fd0\u884c\u7684deployment\u548cpod\u3002 kubectl get deploy,pod -n cka \u8fd0\u884c\u7ed3\u679c\uff1a NAME READY UP-TO-DATE AVAILABLE AGE deployment.apps/nginx 1/1 1 1 2m14s NAME READY STATUS RESTARTS AGE pod/nginx-85b98978db-bmkhf 1/1 Running 0 2m14s \u5220\u9664namespace cka \uff0c\u5219\u6240\u6709\u8fd0\u884c\u5728\u8fd9\u4e2anamespace\u4e0a\u7684\u8d44\u6e90\u90fd\u4f1a\u88ab\u5220\u9664\u3002 kubectl delete ns cka \u5982\u679c\u5728\u5220\u9664\u67d0\u4e2anamespace\u65f6\u9047\u5230\u72b6\u6001\u4e00\u76f4\u662f Terminating \uff0c\u5219\u53ef\u4ee5\u5c1d\u8bd5\u7528\u4e0b\u9762\u7684\u65b9\u6cd5\u89e3\u51b3\u3002 kubectl get namespace $NAMESPACE -o json | sed -e 's/\"kubernetes\"//' | kubectl replace --raw \"/api/v1/namespaces $NAMESPACE /finalize\" -f -","title":"\u6f14\u793a"},{"location":"k8s/cka_cn/foundamentals/networkpolicy/","text":"CKA\u81ea\u5b66\u7b14\u8bb023:Network Policy \u00b6 \u7528Calico\u66ff\u6362Flannel \u00b6 \u6f14\u793a\u573a\u666f\uff1a \u5378\u8f7dFlannel \u5b89\u88c5Calico \u6f14\u793a\uff1a \u5982\u679c\u5728\u5b89\u88c5\u8fc7\u7a0b\u4e2d\u5df2\u7ecf\u5b89\u88c5\u4e86 Calico\uff0c\u5219\u53ef\u4ee5\u5ffd\u7565\u8fd9\u90e8\u5206\u5185\u5bb9\u3002 \u5378\u8f7dFlannel kubectl delete -f https://raw.githubusercontent.com/coreos/flannel/v0.18.1/Documentation/kube-flannel.yml \u6216\u8005 kubectl delete -f kube-flannel.yml \u8f93\u51fa\uff1a Warning: policy/v1beta1 PodSecurityPolicy is deprecated in v1.21+, unavailable in v1.25+ podsecuritypolicy.policy \"psp.flannel.unprivileged\" deleted clusterrole.rbac.authorization.k8s.io \"flannel\" deleted clusterrolebinding.rbac.authorization.k8s.io \"flannel\" deleted serviceaccount \"flannel\" deleted configmap \"kube-flannel-cfg\" deleted daemonset.apps \"kube-flannel-ds\" deleted \u5728\u6240\u6709\u8282\u70b9\u4e0a\u6e05\u9664iptables\u8bbe\u7f6e\u3002 rm -rf /var/run/flannel /opt/cni /etc/cni /var/lib/cni iptables -F && iptables -t nat -F && iptables -t mangle -F && iptables -X \u91cd\u65b0\u767b\u5f55\u4e3b\u673a\u8282\u70b9\uff0c\u4f8b\u5982 cka001 \uff0c\u5b89\u88c5Calico\uff0c curl https://docs.projectcalico.org/manifests/calico.yaml -O kubectl apply -f calico.yaml Output: configmap/calico-config created customresourcedefinition.apiextensions.k8s.io/bgpconfigurations.crd.projectcalico.org created customresourcedefinition.apiextensions.k8s.io/bgppeers.crd.projectcalico.org created customresourcedefinition.apiextensions.k8s.io/blockaffinities.crd.projectcalico.org created customresourcedefinition.apiextensions.k8s.io/caliconodestatuses.crd.projectcalico.org created customresourcedefinition.apiextensions.k8s.io/clusterinformations.crd.projectcalico.org created customresourcedefinition.apiextensions.k8s.io/felixconfigurations.crd.projectcalico.org created customresourcedefinition.apiextensions.k8s.io/globalnetworkpolicies.crd.projectcalico.org created customresourcedefinition.apiextensions.k8s.io/globalnetworksets.crd.projectcalico.org created customresourcedefinition.apiextensions.k8s.io/hostendpoints.crd.projectcalico.org created customresourcedefinition.apiextensions.k8s.io/ipamblocks.crd.projectcalico.org created customresourcedefinition.apiextensions.k8s.io/ipamconfigs.crd.projectcalico.org created customresourcedefinition.apiextensions.k8s.io/ipamhandles.crd.projectcalico.org created customresourcedefinition.apiextensions.k8s.io/ippools.crd.projectcalico.org created customresourcedefinition.apiextensions.k8s.io/ipreservations.crd.projectcalico.org created customresourcedefinition.apiextensions.k8s.io/kubecontrollersconfigurations.crd.projectcalico.org created customresourcedefinition.apiextensions.k8s.io/networkpolicies.crd.projectcalico.org created customresourcedefinition.apiextensions.k8s.io/networksets.crd.projectcalico.org created clusterrole.rbac.authorization.k8s.io/calico-kube-controllers created clusterrolebinding.rbac.authorization.k8s.io/calico-kube-controllers created clusterrole.rbac.authorization.k8s.io/calico-node created clusterrolebinding.rbac.authorization.k8s.io/calico-node created daemonset.apps/calico-node created serviceaccount/calico-node created deployment.apps/calico-kube-controllers created serviceaccount/calico-kube-controllers created poddisruptionbudget.policy/calico-kube-controllers created \u9a8c\u8bc1Calico\u5b89\u88c5\u72b6\u6001\uff0c\u786e\u4fdd\u5728\u6bcf\u4e2a\u8282\u70b9\u4e0a\u90fd\u6b63\u5e38\u8fd0\u884c\u3002 kubectl get pod -n kube-system | grep calico \u8f93\u51fa\u7ed3\u679c\uff1a NAME READY STATUS RESTARTS AGE calico-kube-controllers-7bc6547ffb-tjfcg 1/1 Running 0 30m calico-node-7x8jm 1/1 Running 0 30m calico-node-cwxj5 1/1 Running 0 30m calico-node-rq978 1/1 Running 0 30m \u5982\u679c\u9047\u5230\u4efb\u4f55\u9519\u8bef\uff0c\u9996\u5148\u68c0\u67e5\u5bb9\u5668container\u65e5\u5fd7\u3002 # Get Container ID crictl ps # Get log info crictl logs \u7531\u4e8e\u6211\u4eec\u5c06 CNI \u4ece Flannel \u66f4\u6539\u4e3a Calico\uff0c\u6211\u4eec\u9700\u8981\u5220\u9664\u6240\u6709 Pod\uff0c\u6240\u6709 Pod \u90fd\u5c06\u81ea\u52a8\u91cd\u65b0\u521b\u5efa\u3002 kubectl delete pod -A --all \u67e5\u8be2\u6240\u6709pod\u90fd\u72b6\u6001\uff0c\u786e\u4fdd\u4ed6\u4eec\u90fd\u6b63\u5e38\u8fd0\u884c\u3002 kubectl get pod -A \u5165\u7ad9\u89c4\u5219\uff08Inbound Rules\uff09 \u00b6 \u6f14\u793a\u573a\u666f\uff1a \u521b\u5efa\u7528\u4e8e\u6d4b\u8bd5\u7684\u5de5\u4f5c\u8d1f\u8f7d\u3002 \u7981\u6b62\u6240\u6709\u5165\u7ad9\u6d41\u91cf\u3002 \u5141\u8bb8\u7279\u5b9a\u7684\u5165\u7ad9\u6d41\u91cf\u3002 \u9a8c\u8bc1NetworkPolicy\u3002 \u521b\u5efa\u6d4b\u8bd5\u5de5\u4f5c\u8d1f\u8f7d \u00b6 \u521b\u5efa\u4e09\u4e2a Deployment\uff0c\u540d\u79f0\u4e3a pod-netpol-1 \u3001 pod-netpol-2 \u548c pod-netpol-3 \uff0c\u5b83\u4eec\u90fd\u57fa\u4e8e\u955c\u50cf busybox \u3002 kubectl apply -f - << EOF apiVersion: apps/v1 kind: Deployment metadata: labels: app: pod-netpol-1 name: pod-netpol-1 spec: replicas: 1 selector: matchLabels: app: pod-netpol-1 template: metadata: labels: app: pod-netpol-1 spec: containers: - image: busybox name: busybox command: [\"sh\", \"-c\", \"sleep 1h\"] --- apiVersion: apps/v1 kind: Deployment metadata: labels: app: pod-netpol-2 name: pod-netpol-2 spec: replicas: 1 selector: matchLabels: app: pod-netpol-2 template: metadata: labels: app: pod-netpol-2 spec: containers: - image: busybox name: busybox command: [\"sh\", \"-c\", \"sleep 1h\"] --- apiVersion: apps/v1 kind: Deployment metadata: labels: app: pod-netpol-3 name: pod-netpol-3 spec: replicas: 1 selector: matchLabels: app: pod-netpol-3 template: metadata: labels: app: pod-netpol-3 spec: containers: - image: busybox name: busybox command: [\"sh\", \"-c\", \"sleep 1h\"] EOF \u68c0\u67e5pod\u7684IP\u5730\u5740\uff1a kubectl get pod -owide \u8f93\u51fa\u7ed3\u679c\uff1a NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES pod-netpol-1-6494f6bf8b-n58r9 1/1 Running 0 29s 10.244.102.30 cka003 pod-netpol-2-77478d77ff-l6rzm 1/1 Running 0 29s 10.244.112.30 cka002 pod-netpol-3-68977dcb48-ql5s6 1/1 Running 0 29s 10.244.102.31 cka003 \u767b\u5f55\u8fdb\u5165pod pod-netpol-1 \u3002 kubectl exec -it pod-netpol-1-6494f6bf8b-n58r9 -- sh \u6267\u884c\u547d\u4ee4 ping \uff0c\u786e\u4fdd pod-netpol-2 \u548c pod-netpol-3 \u53ef\u4e92\u76f8\u8bbf\u95ee\u3002 / # ping 10.244.112.30 3 packets transmitted, 3 packets received, 0 % packet loss / # ping 10.244.102.31 3 packets transmitted, 3 packets received, 0 % packet loss \u7981\u6b62\u6240\u6709\u5165\u7ad9\u6d41\u91cf \u00b6 \u521b\u5efa\u7b56\u7565\uff0c\u7981\u6b62\u6240\u6709\u5165\u7ad9\u6d41\u91cf\u3002 kubectl apply -f - << EOF apiVersion: networking.k8s.io/v1 kind: NetworkPolicy metadata: name: default-deny-ingress spec: podSelector: {} policyTypes: - Ingress EOF \u518d\u6b21\u767b\u5f55\u8fdb\u5165pod pod-netpol-1 \u3002 kubectl exec -it pod-netpol-1-6494f6bf8b-n58r9 -- sh Execute command ping that pod-netpol-2 and pod-netpol-3 are both unreachable as expected. \u6267\u884c\u547d\u4ee4 ping \uff0c\u548c\u6211\u4eec\u9884\u671f\u4e00\u6837\uff0c pod-netpol-2 \u548c pod-netpol-3 \u6b64\u65f6\u4e92\u76f8\u65e0\u6cd5\u8bbf\u95ee\u3002 / # ping 10.244.112.30 3 packets transmitted, 0 packets received, 100 % packet loss / # ping 10.244.102.31 3 packets transmitted, 0 packets received, 100 % packet loss \u5141\u8bb8\u7279\u5b9a\u7684\u5165\u7ad9\u6d41\u91cf \u00b6 \u521b\u5efa NetworkPolicy\uff0c\u5141\u8bb8\u6765\u81ea pod-netpol-1 \u5230 pod-netpol-2 \u7684\u5165\u7ad9\u6d41\u91cf\u3002 kubectl apply -f - <:80 \u5931\u8d25 \u8fd0\u884c curl :80 \u6210\u529f kubectl run centos --image = centos -n my-ns-1 -- \"/bin/sh\" \"-c\" \"sleep 3600\" kubectl exec -it mycentos -n my-ns-1 -- bash \u5728namespace my-ns-2 \u4e2d\u521b\u5efa\u4e00\u4e2a\u4e34\u65f6 Pod\uff0c\u7136\u540e\u8fde\u63a5\u5230\u8be5 Pod \u5e76\u9a8c\u8bc1\u8bbf\u95ee\u3002 \u547d\u4ee4 curl :80 \u5931\u8d25 \u547d\u4ee4 curl :80 \u5931\u8d25\u3002 kubectl run centos --image = centos -n my-ns-2 -- \"/bin/sh\" \"-c\" \"sleep 3600\" kubectl exec -it mycentos -n my-ns-2 -- bash \u4fee\u6539 my-networkpolicy-1 \uff0c \u628a ingress.from.namespaceSelector.matchLabels \u7684\u503c\u6539\u4e3a my-ns-2 \u3002 \u767b\u5f55\u8fdb\u5165namespace my-ns-2 \u4e0a\u7684\u4e34\u65f6pod\uff0c\u9a8c\u8bc1\u8bbf\u95ee\u3002 \u547d\u4ee4 curl :80 \u5931\u8d25 \u547d\u4ee4 curl :80 \u6210\u529f kubectl exec -it mycentos -n my-ns-2 -- bash \u5220\u9664\u6f14\u793a\u4e2d\u521b\u5efa\u7684\u4e34\u65f6\u8d44\u6e90\u3002 kubectl delete namespace my-ns-1 kubectl delete namespace my-ns-2","title":"Network Policy"},{"location":"k8s/cka_cn/foundamentals/networkpolicy/#cka23network-policy","text":"","title":"CKA\u81ea\u5b66\u7b14\u8bb023:Network Policy"},{"location":"k8s/cka_cn/foundamentals/networkpolicy/#calicoflannel","text":"\u6f14\u793a\u573a\u666f\uff1a \u5378\u8f7dFlannel \u5b89\u88c5Calico \u6f14\u793a\uff1a \u5982\u679c\u5728\u5b89\u88c5\u8fc7\u7a0b\u4e2d\u5df2\u7ecf\u5b89\u88c5\u4e86 Calico\uff0c\u5219\u53ef\u4ee5\u5ffd\u7565\u8fd9\u90e8\u5206\u5185\u5bb9\u3002 \u5378\u8f7dFlannel kubectl delete -f https://raw.githubusercontent.com/coreos/flannel/v0.18.1/Documentation/kube-flannel.yml \u6216\u8005 kubectl delete -f kube-flannel.yml \u8f93\u51fa\uff1a Warning: policy/v1beta1 PodSecurityPolicy is deprecated in v1.21+, unavailable in v1.25+ podsecuritypolicy.policy \"psp.flannel.unprivileged\" deleted clusterrole.rbac.authorization.k8s.io \"flannel\" deleted clusterrolebinding.rbac.authorization.k8s.io \"flannel\" deleted serviceaccount \"flannel\" deleted configmap \"kube-flannel-cfg\" deleted daemonset.apps \"kube-flannel-ds\" deleted \u5728\u6240\u6709\u8282\u70b9\u4e0a\u6e05\u9664iptables\u8bbe\u7f6e\u3002 rm -rf /var/run/flannel /opt/cni /etc/cni /var/lib/cni iptables -F && iptables -t nat -F && iptables -t mangle -F && iptables -X \u91cd\u65b0\u767b\u5f55\u4e3b\u673a\u8282\u70b9\uff0c\u4f8b\u5982 cka001 \uff0c\u5b89\u88c5Calico\uff0c curl https://docs.projectcalico.org/manifests/calico.yaml -O kubectl apply -f calico.yaml Output: configmap/calico-config created customresourcedefinition.apiextensions.k8s.io/bgpconfigurations.crd.projectcalico.org created customresourcedefinition.apiextensions.k8s.io/bgppeers.crd.projectcalico.org created customresourcedefinition.apiextensions.k8s.io/blockaffinities.crd.projectcalico.org created customresourcedefinition.apiextensions.k8s.io/caliconodestatuses.crd.projectcalico.org created customresourcedefinition.apiextensions.k8s.io/clusterinformations.crd.projectcalico.org created customresourcedefinition.apiextensions.k8s.io/felixconfigurations.crd.projectcalico.org created customresourcedefinition.apiextensions.k8s.io/globalnetworkpolicies.crd.projectcalico.org created customresourcedefinition.apiextensions.k8s.io/globalnetworksets.crd.projectcalico.org created customresourcedefinition.apiextensions.k8s.io/hostendpoints.crd.projectcalico.org created customresourcedefinition.apiextensions.k8s.io/ipamblocks.crd.projectcalico.org created customresourcedefinition.apiextensions.k8s.io/ipamconfigs.crd.projectcalico.org created customresourcedefinition.apiextensions.k8s.io/ipamhandles.crd.projectcalico.org created customresourcedefinition.apiextensions.k8s.io/ippools.crd.projectcalico.org created customresourcedefinition.apiextensions.k8s.io/ipreservations.crd.projectcalico.org created customresourcedefinition.apiextensions.k8s.io/kubecontrollersconfigurations.crd.projectcalico.org created customresourcedefinition.apiextensions.k8s.io/networkpolicies.crd.projectcalico.org created customresourcedefinition.apiextensions.k8s.io/networksets.crd.projectcalico.org created clusterrole.rbac.authorization.k8s.io/calico-kube-controllers created clusterrolebinding.rbac.authorization.k8s.io/calico-kube-controllers created clusterrole.rbac.authorization.k8s.io/calico-node created clusterrolebinding.rbac.authorization.k8s.io/calico-node created daemonset.apps/calico-node created serviceaccount/calico-node created deployment.apps/calico-kube-controllers created serviceaccount/calico-kube-controllers created poddisruptionbudget.policy/calico-kube-controllers created \u9a8c\u8bc1Calico\u5b89\u88c5\u72b6\u6001\uff0c\u786e\u4fdd\u5728\u6bcf\u4e2a\u8282\u70b9\u4e0a\u90fd\u6b63\u5e38\u8fd0\u884c\u3002 kubectl get pod -n kube-system | grep calico \u8f93\u51fa\u7ed3\u679c\uff1a NAME READY STATUS RESTARTS AGE calico-kube-controllers-7bc6547ffb-tjfcg 1/1 Running 0 30m calico-node-7x8jm 1/1 Running 0 30m calico-node-cwxj5 1/1 Running 0 30m calico-node-rq978 1/1 Running 0 30m \u5982\u679c\u9047\u5230\u4efb\u4f55\u9519\u8bef\uff0c\u9996\u5148\u68c0\u67e5\u5bb9\u5668container\u65e5\u5fd7\u3002 # Get Container ID crictl ps # Get log info crictl logs \u7531\u4e8e\u6211\u4eec\u5c06 CNI \u4ece Flannel \u66f4\u6539\u4e3a Calico\uff0c\u6211\u4eec\u9700\u8981\u5220\u9664\u6240\u6709 Pod\uff0c\u6240\u6709 Pod \u90fd\u5c06\u81ea\u52a8\u91cd\u65b0\u521b\u5efa\u3002 kubectl delete pod -A --all \u67e5\u8be2\u6240\u6709pod\u90fd\u72b6\u6001\uff0c\u786e\u4fdd\u4ed6\u4eec\u90fd\u6b63\u5e38\u8fd0\u884c\u3002 kubectl get pod -A","title":"\u7528Calico\u66ff\u6362Flannel"},{"location":"k8s/cka_cn/foundamentals/networkpolicy/#inbound-rules","text":"\u6f14\u793a\u573a\u666f\uff1a \u521b\u5efa\u7528\u4e8e\u6d4b\u8bd5\u7684\u5de5\u4f5c\u8d1f\u8f7d\u3002 \u7981\u6b62\u6240\u6709\u5165\u7ad9\u6d41\u91cf\u3002 \u5141\u8bb8\u7279\u5b9a\u7684\u5165\u7ad9\u6d41\u91cf\u3002 \u9a8c\u8bc1NetworkPolicy\u3002","title":"\u5165\u7ad9\u89c4\u5219\uff08Inbound Rules\uff09"},{"location":"k8s/cka_cn/foundamentals/networkpolicy/#_1","text":"\u521b\u5efa\u4e09\u4e2a Deployment\uff0c\u540d\u79f0\u4e3a pod-netpol-1 \u3001 pod-netpol-2 \u548c pod-netpol-3 \uff0c\u5b83\u4eec\u90fd\u57fa\u4e8e\u955c\u50cf busybox \u3002 kubectl apply -f - << EOF apiVersion: apps/v1 kind: Deployment metadata: labels: app: pod-netpol-1 name: pod-netpol-1 spec: replicas: 1 selector: matchLabels: app: pod-netpol-1 template: metadata: labels: app: pod-netpol-1 spec: containers: - image: busybox name: busybox command: [\"sh\", \"-c\", \"sleep 1h\"] --- apiVersion: apps/v1 kind: Deployment metadata: labels: app: pod-netpol-2 name: pod-netpol-2 spec: replicas: 1 selector: matchLabels: app: pod-netpol-2 template: metadata: labels: app: pod-netpol-2 spec: containers: - image: busybox name: busybox command: [\"sh\", \"-c\", \"sleep 1h\"] --- apiVersion: apps/v1 kind: Deployment metadata: labels: app: pod-netpol-3 name: pod-netpol-3 spec: replicas: 1 selector: matchLabels: app: pod-netpol-3 template: metadata: labels: app: pod-netpol-3 spec: containers: - image: busybox name: busybox command: [\"sh\", \"-c\", \"sleep 1h\"] EOF \u68c0\u67e5pod\u7684IP\u5730\u5740\uff1a kubectl get pod -owide \u8f93\u51fa\u7ed3\u679c\uff1a NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES pod-netpol-1-6494f6bf8b-n58r9 1/1 Running 0 29s 10.244.102.30 cka003 pod-netpol-2-77478d77ff-l6rzm 1/1 Running 0 29s 10.244.112.30 cka002 pod-netpol-3-68977dcb48-ql5s6 1/1 Running 0 29s 10.244.102.31 cka003 \u767b\u5f55\u8fdb\u5165pod pod-netpol-1 \u3002 kubectl exec -it pod-netpol-1-6494f6bf8b-n58r9 -- sh \u6267\u884c\u547d\u4ee4 ping \uff0c\u786e\u4fdd pod-netpol-2 \u548c pod-netpol-3 \u53ef\u4e92\u76f8\u8bbf\u95ee\u3002 / # ping 10.244.112.30 3 packets transmitted, 3 packets received, 0 % packet loss / # ping 10.244.102.31 3 packets transmitted, 3 packets received, 0 % packet loss","title":"\u521b\u5efa\u6d4b\u8bd5\u5de5\u4f5c\u8d1f\u8f7d"},{"location":"k8s/cka_cn/foundamentals/networkpolicy/#_2","text":"\u521b\u5efa\u7b56\u7565\uff0c\u7981\u6b62\u6240\u6709\u5165\u7ad9\u6d41\u91cf\u3002 kubectl apply -f - << EOF apiVersion: networking.k8s.io/v1 kind: NetworkPolicy metadata: name: default-deny-ingress spec: podSelector: {} policyTypes: - Ingress EOF \u518d\u6b21\u767b\u5f55\u8fdb\u5165pod pod-netpol-1 \u3002 kubectl exec -it pod-netpol-1-6494f6bf8b-n58r9 -- sh Execute command ping that pod-netpol-2 and pod-netpol-3 are both unreachable as expected. \u6267\u884c\u547d\u4ee4 ping \uff0c\u548c\u6211\u4eec\u9884\u671f\u4e00\u6837\uff0c pod-netpol-2 \u548c pod-netpol-3 \u6b64\u65f6\u4e92\u76f8\u65e0\u6cd5\u8bbf\u95ee\u3002 / # ping 10.244.112.30 3 packets transmitted, 0 packets received, 100 % packet loss / # ping 10.244.102.31 3 packets transmitted, 0 packets received, 100 % packet loss","title":"\u7981\u6b62\u6240\u6709\u5165\u7ad9\u6d41\u91cf"},{"location":"k8s/cka_cn/foundamentals/networkpolicy/#_3","text":"\u521b\u5efa NetworkPolicy\uff0c\u5141\u8bb8\u6765\u81ea pod-netpol-1 \u5230 pod-netpol-2 \u7684\u5165\u7ad9\u6d41\u91cf\u3002 kubectl apply -f - <:80 \u5931\u8d25 \u8fd0\u884c curl :80 \u6210\u529f kubectl run centos --image = centos -n my-ns-1 -- \"/bin/sh\" \"-c\" \"sleep 3600\" kubectl exec -it mycentos -n my-ns-1 -- bash \u5728namespace my-ns-2 \u4e2d\u521b\u5efa\u4e00\u4e2a\u4e34\u65f6 Pod\uff0c\u7136\u540e\u8fde\u63a5\u5230\u8be5 Pod \u5e76\u9a8c\u8bc1\u8bbf\u95ee\u3002 \u547d\u4ee4 curl :80 \u5931\u8d25 \u547d\u4ee4 curl :80 \u5931\u8d25\u3002 kubectl run centos --image = centos -n my-ns-2 -- \"/bin/sh\" \"-c\" \"sleep 3600\" kubectl exec -it mycentos -n my-ns-2 -- bash \u4fee\u6539 my-networkpolicy-1 \uff0c \u628a ingress.from.namespaceSelector.matchLabels \u7684\u503c\u6539\u4e3a my-ns-2 \u3002 \u767b\u5f55\u8fdb\u5165namespace my-ns-2 \u4e0a\u7684\u4e34\u65f6pod\uff0c\u9a8c\u8bc1\u8bbf\u95ee\u3002 \u547d\u4ee4 curl :80 \u5931\u8d25 \u547d\u4ee4 curl :80 \u6210\u529f kubectl exec -it mycentos -n my-ns-2 -- bash \u5220\u9664\u6f14\u793a\u4e2d\u521b\u5efa\u7684\u4e34\u65f6\u8d44\u6e90\u3002 kubectl delete namespace my-ns-1 kubectl delete namespace my-ns-2","title":"NetworkPolicy"},{"location":"k8s/cka_cn/foundamentals/overview/","text":"CKA\u81ea\u5b66\u7b14\u8bb06:Kubernetes\u96c6\u7fa4\u6982\u89c8 \u00b6 \u6458\u8981 \u00b6 \u5305\u542b\u4e0b\u9762\u5185\u5bb9\uff1a \u5bb9\u5668\u5c42 Kubernetes\u5c42 \u63d0\u793a\uff1a \u540e\u7eed\u5b9e\u9a8c\u73af\u5883\u90fd\u662f\u4f7f\u7528\u5728\u963f\u91cc\u4e91\u90e8\u7f72\u7684Ubuntu\u4e09\u8282\u70b9\u96c6\u7fa4\uff0c\u4e09\u4e2a\u8282\u70b9\u5206\u522b\u4e3a cka001 \u3001 cka002 \u548c cka003 \u3002 \u5bb9\u5668\u5c42 \u00b6 \u573a\u666f\uff1a \u4f7f\u7528Containerd\u670d\u52a1\uff0c\u901a\u8fc7\u547d\u4ee4 nerdctl \u6765\u7ba1\u7406\u6211\u4eec\u7684\u955c\u50cf\u548c\u5bb9\u5668\uff0c\u8fd9\u4e0eDocker\u7684\u6982\u5ff5\u76f8\u540c\u3002 Get namespace. Get containers. Get images. Get volumes. Get overall status. Get network status. \u6f14\u793a\uff1a \u8bfb\u53d6\u547d\u540d\u7a7a\u95f4namespaces\u3002 sudo nerdctl namespace ls \u8fd0\u884c\u7ed3\u679c\uff1a NAME CONTAINERS IMAGES VOLUMES LABELS k8s.io 21 30 0 \u8bfb\u53d6\u547d\u540d\u7a7a\u95f4 k8s.io \u4e0b\u7684\u5bb9\u5668\u3002 sudo nerdctl -n k8s.io ps \u8fd0\u884c\u7ed3\u679c\uff1a CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 0a3625f22f65 registry.aliyuncs.com/google_containers/pause:3.6 \"/pause\" 16 hours ago Up k8s://kube-system/coredns-74586cf9b6-4jwmk 121af2ecd1a1 registry.aliyuncs.com/google_containers/coredns:v1.8.6 \"/coredns -conf /etc\u2026\" 16 hours ago Up k8s://kube-system/coredns-74586cf9b6-c5mll/coredns 49f6c7e3efe5 registry.aliyuncs.com/google_containers/kube-proxy:v1.24.0 \"/usr/local/bin/kube\u2026\" 16 hours ago Up k8s://kube-system/kube-proxy-dmj2t/kube-proxy 4bba5fbd701d registry.aliyuncs.com/google_containers/pause:3.6 \"/pause\" 16 hours ago Up k8s://kube-system/kube-scheduler-cka001 57d47b57eb12 docker.io/calico/node:v3.23.3 \"start_runit\" 16 hours ago Up k8s://kube-system/calico-node-w8nvl/calico-node 5ce4c351a886 registry.aliyuncs.com/google_containers/pause:3.6 \"/pause\" 16 hours ago Up k8s://kube-system/calico-node-w8nvl 6456eef784bf registry.aliyuncs.com/google_containers/kube-scheduler:v1.24.0 \"kube-scheduler --au\u2026\" 16 hours ago Up k8s://kube-system/kube-scheduler-cka001/kube-scheduler 6a687305871c registry.aliyuncs.com/google_containers/kube-apiserver:v1.24.0 \"kube-apiserver --ad\u2026\" 16 hours ago Up k8s://kube-system/kube-apiserver-cka001/kube-apiserver 7dcb24568574 registry.aliyuncs.com/google_containers/pause:3.6 \"/pause\" 16 hours ago Up k8s://kube-system/coredns-74586cf9b6-c5mll a06b101118b8 registry.aliyuncs.com/google_containers/pause:3.6 \"/pause\" 16 hours ago Up k8s://kube-system/kube-controller-manager-cka001 a07ef8c3fc3a registry.aliyuncs.com/google_containers/pause:3.6 \"/pause\" 16 hours ago Up k8s://kube-system/etcd-cka001 b8566d3e4174 registry.aliyuncs.com/google_containers/kube-controller-manager:v1.24.0 \"kube-controller-man\u2026\" 16 hours ago Up k8s://kube-system/kube-controller-manager-cka001/kube-controller-manager ca6ac26314ff registry.aliyuncs.com/google_containers/coredns:v1.8.6 \"/coredns -conf /etc\u2026\" 16 hours ago Up k8s://kube-system/coredns-74586cf9b6-4jwmk/coredns cdc041b4791e registry.aliyuncs.com/google_containers/etcd:3.5.3-0 \"etcd --advertise-cl\u2026\" 16 hours ago Up k8s://kube-system/etcd-cka001/etcd e0c59abadf2e registry.aliyuncs.com/google_containers/pause:3.6 \"/pause\" 16 hours ago Up k8s://kube-system/kube-proxy-dmj2t e0d2e5f6ccff registry.aliyuncs.com/google_containers/pause:3.6 \"/pause\" 16 hours ago Up k8s://kube-system/kube-apiserver-cka001 \u8bfb\u53d6\u547d\u540d\u7a7a\u95f4 k8s.io \u4e0b\u7684\u955c\u50cf\u3002 sudo nerdctl -n k8s.io image ls -a \u8bfb\u53d6\u547d\u540d\u7a7a\u95f4 k8s.io \u4e0b\u7684\u5377Volume\u3002\u521d\u59cb\u5316\u5b89\u88c5\u540e\uff0c\u8be5\u547d\u540d\u7a7a\u95f4\u4e0b\u6ca1\u6709\u4efb\u4f55\u5377\u3002 sudo nerdctl -n k8s.io volume ls \u8bfb\u53d6\u96c6\u7fa4\u72b6\u6001\u3002 sudo nerdctl stats \u8bfb\u53d6\u7f51\u7edc\u72b6\u6001\u3002 sudo nerdctl network ls sudo nerdctl network inspect bridge sudo nerdctl network inspect k8s-pod-network \u8fd0\u884c\u7ed3\u679c\uff1a NETWORK ID NAME FILE k8s-pod-network /etc/cni/net.d/10-calico.conflist 0 bridge /etc/cni/net.d/nerdctl-bridge.conflist host none Get network interface in host cka001 with command ip addr list . IP pool of 10.4.0.1/24 is ipam and defined in /etc/cni/net.d/nerdctl-bridge.conflist . \u4f7f\u7528\u547d\u4ee4 ip addr list \u83b7\u53d6\u4e3b\u673a cka001 \u7684\u7f51\u7edc\u63a5\u53e3\u3002 10.4.0.1/24 \u7684IP\u6c60\u662f ipam \uff0c\u5728 /etc/cni/net.d/nerdctl-bridge.conflist \u4e2d\u5b9a\u4e49\u3002 lo : inet 127.0.0.1/8 qlen 1000 eth0 : inet /24 brd xxx.xxx.xxx.255 scope global dynamic eth0 tunl0@NONE : inet 10.244.228.192/32 scope global tunl0 cali96e32d88db2@if4 : cali93613212490@if4 : nerdctl-bridge.conflist \u6587\u4ef6\u7684\u4f5c\u7528\u662f\uff1a \u5b9a\u4e49\u4e86nerdctl\u4f7f\u7528\u7684\u9ed8\u8ba4\u6865\u63a5CNI\u7f51\u7edc\u7684\u914d\u7f6e\uff0c\u5305\u62ec\u7f51\u7edc\u540d\u79f0\u3001\u5b50\u7f51\u3001\u7f51\u5173\u3001IP\u5206\u914d\u7b56\u7565\u7b49 1 \uff0c 2 \u3002 \u4f7f\u5f97nerdctl\u53ef\u4ee5\u4f7f\u7528docker run -it --rm alpine\u8fd9\u6837\u7684\u547d\u4ee4\u6765\u8fd0\u884c\u4e00\u4e2a\u5bb9\u5668\uff0c\u5e76\u81ea\u52a8\u5206\u914d\u4e00\u4e2a10.4.0.0/24\u7f51\u6bb5\u7684IP\u5730\u5740 1 \uff0c 3 \u3002 \u4f7f\u5f97nerdctl\u53ef\u4ee5\u652f\u6301\u4e00\u4e9b\u57fa\u672c\u7684CNI\u63d2\u4ef6\uff0c\u5982bridge, portmap, firewall, tuning 1 \uff0c 2 \u3002 Kubernetes\u5c42 \u00b6 \u573a\u666f\uff1a \u8282\u70b9Nodes \u547d\u540d\u7a7a\u95f4Namespaces \u7cfb\u7edfPods \u6f14\u793a\uff1a \u8bfb\u53d6\u8282\u70b9\u72b6\u6001\uff1a kubectl get node -o wide \u5728\u4e09\u4e2a\u8282\u70b9\u4e0a\u6709\u56db\u4e2a\u521d\u59cb\u7684\u547d\u540d\u7a7a\u95f4\u3002 kubectl get namespace -A \u8fd0\u884c\u7ed3\u679c\uff1a NAME STATUS AGE default Active 56m kube-node-lease Active 56m kube-public Active 56m kube-system Active 56m \u5728\u4e09\u4e2a\u8282\u70b9\u4e0a\u7684\u521d\u59cb\u5316Pod\u3002 kubectl get pod -A -o wide \u8fd0\u884c\u7ed3\u679c\uff1a NAMESPACE NAME READY STATUS RESTARTS AGE NODE NOMINATED NODE READINESS GATES kube-system calico-kube-controllers-555bc4b957-l8bn2 1/1 Running 0 15h cka003 kube-system calico-node-255pc 1/1 Running 0 15h cka003 kube-system calico-node-7tmnb 1/1 Running 0 15h cka002 kube-system calico-node-w8nvl 1/1 Running 0 15h cka001 kube-system coredns-74586cf9b6-4jwmk 1/1 Running 0 15h cka001 kube-system coredns-74586cf9b6-c5mll 1/1 Running 0 15h cka001 kube-system etcd-cka001 1/1 Running 0 15h cka001 kube-system kube-apiserver-cka001 1/1 Running 0 15h cka001 kube-system kube-controller-manager-cka001 1/1 Running 0 15h cka001 kube-system kube-proxy-dmj2t 1/1 Running 0 15h cka001 kube-system kube-proxy-n77zw 1/1 Running 0 15h cka002 kube-system kube-proxy-qs6rf 1/1 Running 0 15h cka003 kube-system kube-scheduler-cka001 1/1 Running 0 15h cka001 \u603b\u7ed3\uff1a \u4e0b\u9762\u5217\u51fa\u4e86\u521d\u59cb\u96c6\u7fa4\u4e2d\u4e3b\u8282\u70b9\u548c\u6240\u6709\u8282\u70b9\u4e2d\u6240\u5305\u542b\u7684\u5bb9\u5668\u548cPod\u7684\u5173\u7cfb\u3002 Master node: CoreDNS: 2 Pod etcd: 1 Pod apiserver: 1 Pod controller-manager: 1 Pod scheduler: 1 Pod Calico Controller: 1 Pod All nodes: Calico Node: 1 Pod each Proxy: 1 Pod each \u53c2\u8003\uff1a pause\u5bb9\u5668\uff1a \u6587\u7ae01 and \u6587\u7ae02 . nerdctl","title":"Kubernetes\u96c6\u7fa4\u6982\u89c8"},{"location":"k8s/cka_cn/foundamentals/overview/#cka6kubernetes","text":"","title":"CKA\u81ea\u5b66\u7b14\u8bb06:Kubernetes\u96c6\u7fa4\u6982\u89c8"},{"location":"k8s/cka_cn/foundamentals/overview/#_1","text":"\u5305\u542b\u4e0b\u9762\u5185\u5bb9\uff1a \u5bb9\u5668\u5c42 Kubernetes\u5c42 \u63d0\u793a\uff1a \u540e\u7eed\u5b9e\u9a8c\u73af\u5883\u90fd\u662f\u4f7f\u7528\u5728\u963f\u91cc\u4e91\u90e8\u7f72\u7684Ubuntu\u4e09\u8282\u70b9\u96c6\u7fa4\uff0c\u4e09\u4e2a\u8282\u70b9\u5206\u522b\u4e3a cka001 \u3001 cka002 \u548c cka003 \u3002","title":"\u6458\u8981"},{"location":"k8s/cka_cn/foundamentals/overview/#_2","text":"\u573a\u666f\uff1a \u4f7f\u7528Containerd\u670d\u52a1\uff0c\u901a\u8fc7\u547d\u4ee4 nerdctl \u6765\u7ba1\u7406\u6211\u4eec\u7684\u955c\u50cf\u548c\u5bb9\u5668\uff0c\u8fd9\u4e0eDocker\u7684\u6982\u5ff5\u76f8\u540c\u3002 Get namespace. Get containers. Get images. Get volumes. Get overall status. Get network status. \u6f14\u793a\uff1a \u8bfb\u53d6\u547d\u540d\u7a7a\u95f4namespaces\u3002 sudo nerdctl namespace ls \u8fd0\u884c\u7ed3\u679c\uff1a NAME CONTAINERS IMAGES VOLUMES LABELS k8s.io 21 30 0 \u8bfb\u53d6\u547d\u540d\u7a7a\u95f4 k8s.io \u4e0b\u7684\u5bb9\u5668\u3002 sudo nerdctl -n k8s.io ps \u8fd0\u884c\u7ed3\u679c\uff1a CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 0a3625f22f65 registry.aliyuncs.com/google_containers/pause:3.6 \"/pause\" 16 hours ago Up k8s://kube-system/coredns-74586cf9b6-4jwmk 121af2ecd1a1 registry.aliyuncs.com/google_containers/coredns:v1.8.6 \"/coredns -conf /etc\u2026\" 16 hours ago Up k8s://kube-system/coredns-74586cf9b6-c5mll/coredns 49f6c7e3efe5 registry.aliyuncs.com/google_containers/kube-proxy:v1.24.0 \"/usr/local/bin/kube\u2026\" 16 hours ago Up k8s://kube-system/kube-proxy-dmj2t/kube-proxy 4bba5fbd701d registry.aliyuncs.com/google_containers/pause:3.6 \"/pause\" 16 hours ago Up k8s://kube-system/kube-scheduler-cka001 57d47b57eb12 docker.io/calico/node:v3.23.3 \"start_runit\" 16 hours ago Up k8s://kube-system/calico-node-w8nvl/calico-node 5ce4c351a886 registry.aliyuncs.com/google_containers/pause:3.6 \"/pause\" 16 hours ago Up k8s://kube-system/calico-node-w8nvl 6456eef784bf registry.aliyuncs.com/google_containers/kube-scheduler:v1.24.0 \"kube-scheduler --au\u2026\" 16 hours ago Up k8s://kube-system/kube-scheduler-cka001/kube-scheduler 6a687305871c registry.aliyuncs.com/google_containers/kube-apiserver:v1.24.0 \"kube-apiserver --ad\u2026\" 16 hours ago Up k8s://kube-system/kube-apiserver-cka001/kube-apiserver 7dcb24568574 registry.aliyuncs.com/google_containers/pause:3.6 \"/pause\" 16 hours ago Up k8s://kube-system/coredns-74586cf9b6-c5mll a06b101118b8 registry.aliyuncs.com/google_containers/pause:3.6 \"/pause\" 16 hours ago Up k8s://kube-system/kube-controller-manager-cka001 a07ef8c3fc3a registry.aliyuncs.com/google_containers/pause:3.6 \"/pause\" 16 hours ago Up k8s://kube-system/etcd-cka001 b8566d3e4174 registry.aliyuncs.com/google_containers/kube-controller-manager:v1.24.0 \"kube-controller-man\u2026\" 16 hours ago Up k8s://kube-system/kube-controller-manager-cka001/kube-controller-manager ca6ac26314ff registry.aliyuncs.com/google_containers/coredns:v1.8.6 \"/coredns -conf /etc\u2026\" 16 hours ago Up k8s://kube-system/coredns-74586cf9b6-4jwmk/coredns cdc041b4791e registry.aliyuncs.com/google_containers/etcd:3.5.3-0 \"etcd --advertise-cl\u2026\" 16 hours ago Up k8s://kube-system/etcd-cka001/etcd e0c59abadf2e registry.aliyuncs.com/google_containers/pause:3.6 \"/pause\" 16 hours ago Up k8s://kube-system/kube-proxy-dmj2t e0d2e5f6ccff registry.aliyuncs.com/google_containers/pause:3.6 \"/pause\" 16 hours ago Up k8s://kube-system/kube-apiserver-cka001 \u8bfb\u53d6\u547d\u540d\u7a7a\u95f4 k8s.io \u4e0b\u7684\u955c\u50cf\u3002 sudo nerdctl -n k8s.io image ls -a \u8bfb\u53d6\u547d\u540d\u7a7a\u95f4 k8s.io \u4e0b\u7684\u5377Volume\u3002\u521d\u59cb\u5316\u5b89\u88c5\u540e\uff0c\u8be5\u547d\u540d\u7a7a\u95f4\u4e0b\u6ca1\u6709\u4efb\u4f55\u5377\u3002 sudo nerdctl -n k8s.io volume ls \u8bfb\u53d6\u96c6\u7fa4\u72b6\u6001\u3002 sudo nerdctl stats \u8bfb\u53d6\u7f51\u7edc\u72b6\u6001\u3002 sudo nerdctl network ls sudo nerdctl network inspect bridge sudo nerdctl network inspect k8s-pod-network \u8fd0\u884c\u7ed3\u679c\uff1a NETWORK ID NAME FILE k8s-pod-network /etc/cni/net.d/10-calico.conflist 0 bridge /etc/cni/net.d/nerdctl-bridge.conflist host none Get network interface in host cka001 with command ip addr list . IP pool of 10.4.0.1/24 is ipam and defined in /etc/cni/net.d/nerdctl-bridge.conflist . \u4f7f\u7528\u547d\u4ee4 ip addr list \u83b7\u53d6\u4e3b\u673a cka001 \u7684\u7f51\u7edc\u63a5\u53e3\u3002 10.4.0.1/24 \u7684IP\u6c60\u662f ipam \uff0c\u5728 /etc/cni/net.d/nerdctl-bridge.conflist \u4e2d\u5b9a\u4e49\u3002 lo : inet 127.0.0.1/8 qlen 1000 eth0 : inet /24 brd xxx.xxx.xxx.255 scope global dynamic eth0 tunl0@NONE : inet 10.244.228.192/32 scope global tunl0 cali96e32d88db2@if4 : cali93613212490@if4 : nerdctl-bridge.conflist \u6587\u4ef6\u7684\u4f5c\u7528\u662f\uff1a \u5b9a\u4e49\u4e86nerdctl\u4f7f\u7528\u7684\u9ed8\u8ba4\u6865\u63a5CNI\u7f51\u7edc\u7684\u914d\u7f6e\uff0c\u5305\u62ec\u7f51\u7edc\u540d\u79f0\u3001\u5b50\u7f51\u3001\u7f51\u5173\u3001IP\u5206\u914d\u7b56\u7565\u7b49 1 \uff0c 2 \u3002 \u4f7f\u5f97nerdctl\u53ef\u4ee5\u4f7f\u7528docker run -it --rm alpine\u8fd9\u6837\u7684\u547d\u4ee4\u6765\u8fd0\u884c\u4e00\u4e2a\u5bb9\u5668\uff0c\u5e76\u81ea\u52a8\u5206\u914d\u4e00\u4e2a10.4.0.0/24\u7f51\u6bb5\u7684IP\u5730\u5740 1 \uff0c 3 \u3002 \u4f7f\u5f97nerdctl\u53ef\u4ee5\u652f\u6301\u4e00\u4e9b\u57fa\u672c\u7684CNI\u63d2\u4ef6\uff0c\u5982bridge, portmap, firewall, tuning 1 \uff0c 2 \u3002","title":"\u5bb9\u5668\u5c42"},{"location":"k8s/cka_cn/foundamentals/overview/#kubernetes","text":"\u573a\u666f\uff1a \u8282\u70b9Nodes \u547d\u540d\u7a7a\u95f4Namespaces \u7cfb\u7edfPods \u6f14\u793a\uff1a \u8bfb\u53d6\u8282\u70b9\u72b6\u6001\uff1a kubectl get node -o wide \u5728\u4e09\u4e2a\u8282\u70b9\u4e0a\u6709\u56db\u4e2a\u521d\u59cb\u7684\u547d\u540d\u7a7a\u95f4\u3002 kubectl get namespace -A \u8fd0\u884c\u7ed3\u679c\uff1a NAME STATUS AGE default Active 56m kube-node-lease Active 56m kube-public Active 56m kube-system Active 56m \u5728\u4e09\u4e2a\u8282\u70b9\u4e0a\u7684\u521d\u59cb\u5316Pod\u3002 kubectl get pod -A -o wide \u8fd0\u884c\u7ed3\u679c\uff1a NAMESPACE NAME READY STATUS RESTARTS AGE NODE NOMINATED NODE READINESS GATES kube-system calico-kube-controllers-555bc4b957-l8bn2 1/1 Running 0 15h cka003 kube-system calico-node-255pc 1/1 Running 0 15h cka003 kube-system calico-node-7tmnb 1/1 Running 0 15h cka002 kube-system calico-node-w8nvl 1/1 Running 0 15h cka001 kube-system coredns-74586cf9b6-4jwmk 1/1 Running 0 15h cka001 kube-system coredns-74586cf9b6-c5mll 1/1 Running 0 15h cka001 kube-system etcd-cka001 1/1 Running 0 15h cka001 kube-system kube-apiserver-cka001 1/1 Running 0 15h cka001 kube-system kube-controller-manager-cka001 1/1 Running 0 15h cka001 kube-system kube-proxy-dmj2t 1/1 Running 0 15h cka001 kube-system kube-proxy-n77zw 1/1 Running 0 15h cka002 kube-system kube-proxy-qs6rf 1/1 Running 0 15h cka003 kube-system kube-scheduler-cka001 1/1 Running 0 15h cka001 \u603b\u7ed3\uff1a \u4e0b\u9762\u5217\u51fa\u4e86\u521d\u59cb\u96c6\u7fa4\u4e2d\u4e3b\u8282\u70b9\u548c\u6240\u6709\u8282\u70b9\u4e2d\u6240\u5305\u542b\u7684\u5bb9\u5668\u548cPod\u7684\u5173\u7cfb\u3002 Master node: CoreDNS: 2 Pod etcd: 1 Pod apiserver: 1 Pod controller-manager: 1 Pod scheduler: 1 Pod Calico Controller: 1 Pod All nodes: Calico Node: 1 Pod each Proxy: 1 Pod each \u53c2\u8003\uff1a pause\u5bb9\u5668\uff1a \u6587\u7ae01 and \u6587\u7ae02 . nerdctl","title":"Kubernetes\u5c42"},{"location":"k8s/cka_cn/foundamentals/persistence/","text":"CKA\u81ea\u5b66\u7b14\u8bb017:Persistence \u00b6 \u6458\u8981 \u00b6 \u6f14\u793a\u573a\u666f\uff1a \u521b\u5efa\u4e00\u4e2a\u7c7b\u578b\u4e3a emptyDir \u7684\u5377\u6765\u521b\u5efa Pod\uff0cPod \u4e2d\u7684\u5bb9\u5668\u5c06\u4f1a\u6302\u8f7d\u5728\u8fd0\u884c\u8282\u70b9\u4e0a\u7684\u9ed8\u8ba4\u76ee\u5f55 /var/lib/kubelet/pods/ \u4e2d\u3002 \u521b\u5efa\u4e00\u4e2a\u7c7b\u578b\u4e3a hostPath \u7684\u5377\u6765\u521b\u5efa Deployment\uff0cDeployment \u4e2d\u7684\u5bb9\u5668\u5c06\u4f1a\u6302\u8f7d\u5728\u8fd0\u884c\u8282\u70b9\u4e0a\u5b9a\u4e49\u7684\u76ee\u5f55 hostPath: \u4e2d\u3002 \u521b\u5efa PV \u548c PVC\uff1a \u8bbe\u7f6e NFS \u670d\u52a1\u5668\u5e76\u5171\u4eab /nfsdata/ \u76ee\u5f55\u3002 \u521b\u5efa PV mysql-pv \u5e76\u6620\u5c04\u5230\u5171\u4eab\u76ee\u5f55 /nfsdata/ \uff0c\u540c\u65f6\u8bbe\u7f6e StorageClassName \u4e3a nfs \u3002 \u521b\u5efa PVC mysql-pvc \u5e76\u6620\u5c04\u5230 StorageClassName \u4e3a nfs \u7684 PV \u4e0a\u3002 \u521b\u5efa Deployment mysql \u6765\u4f7f\u7528 PVC mysql-pvc \u3002 \u521b\u5efa StorageClass\uff1a \u521b\u5efa ServiceAccount nfs-client-provisioner \u3002 \u521b\u5efa ClusterRole nfs-client-provisioner-runner \u548c Role leader-locking-nfs-client-provisioner \uff0c\u5e76\u5c06\u5176\u7ed1\u5b9a\u5230 ServiceAccount \u4e0a\uff0c\u4ee5\u4fbf\u8be5 ServiceAccount \u53ef\u4ee5\u64cd\u4f5c\u4e0b\u4e00\u6b65\u4e2d\u521b\u5efa\u7684 Deployment\u3002 \u521b\u5efa Deployment nfs-client-provisioner \u6765\u6dfb\u52a0\u8fde\u63a5\u5230 NFS \u670d\u52a1\u5668\u7684\u4fe1\u606f\uff0c\u4f8b\u5982 PROVISIONER_NAME \u662f k8s-sigs.io/nfs-subdir-external-provisioner \u3002 \u521b\u5efa StorageClass nfs-client \u5e76\u94fe\u63a5\u5230 provisioner: k8s-sigs.io/nfs-subdir-external-provisioner \uff0c\u76f8\u5173\u7684 PV \u4f1a\u81ea\u52a8\u521b\u5efa\u3002 \u521b\u5efa PVC nfs-pvc-from-sc \u5e76\u6620\u5c04\u5230 StorageClass nfs-client \u4e0a\u7684 PV\u3002 \u914d\u7f6eConfiguration\uff1a \u521b\u5efa\u4e00\u4e2a ConfigMap \u4ee5\u5305\u542b\u6587\u4ef6\u7684\u5185\u5bb9\uff0c\u5e76\u5c06\u6b64 ConfigMap \u6302\u8f7d\u5230 Pod \u4e2d\u7684\u7279\u5b9a\u6587\u4ef6\u4e2d\u3002 \u521b\u5efa\u4e00\u4e2a ConfigMap \u6765\u5305\u542b\u7528\u6237\u540d\u548c\u5bc6\u7801\uff0c\u5e76\u5728 Pod \u4e2d\u4f7f\u7528\u5b83\u4eec\u3002 \u5728 Pod \u4e2d\u5c06 ConfigMap \u7528\u4f5c\u73af\u5883\u53d8\u91cf\u3002 \u5efa\u8bae\uff1a \u9996\u5148\u5220\u9664 PVC\uff0c\u7136\u540e\u518d\u5220\u9664 PV\u3002 \u5982\u679c\u5220\u9664 PVC \u65f6\u9047\u5230 Terminating \u72b6\u6001\uff0c\u4f7f\u7528 kubectl edit pvc \u547d\u4ee4\uff0c\u7136\u540e\u5220\u9664 finalize: \u3002 emptyDir \u00b6 \u521b\u5efa\u4e00\u4e2a\u540d\u4e3a hello-producer \u7684 Pod\uff0c\u5e76\u4f7f\u7528 emptyDir \u7c7b\u578b\u7684 Volume\u3002 cat > pod-emptydir.yaml < /producer_dir/hello; sleep 30000 volumes: - name: shared-volume emptyDir: {} EOF kubectl apply -f pod-emptydir.yaml \u67e5\u770bPod hello-producer \u7684\u72b6\u6001\u3002 kubectl get pod hello-producer -owide Pod hello-producer \u8fd0\u884c\u5728\u8282\u70b9node cka003 \u4e0a\u3002 NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES hello-producer 1/1 Running 0 6s 10.244.102.24 cka003 \u767b\u5f55 cka003 \uff0c\u56e0\u4e3a Pod hello-producer \u6b63\u5728\u8be5\u8282\u70b9\u4e0a\u8fd0\u884c\u3002 \u4e3a crictl \u547d\u4ee4\u8bbe\u7f6e\u73af\u5883\u53d8\u91cf CONTAINER_RUNTIME_ENDPOINT \u3002\u5efa\u8bae\u5728\u6240\u6709\u8282\u70b9\u4e0a\u6267\u884c\u76f8\u540c\u7684\u64cd\u4f5c\u3002 export CONTAINER_RUNTIME_ENDPOINT = unix:///run/containerd/containerd.sock \u8fd0\u884c\u547d\u4ee4 crictl ps \u6765\u83b7\u53d6 Pod hello-producer \u7684\u5bb9\u5668 ID\u3002 crictl ps | grep hello-producer \u5bb9\u5668 producer \u7684ID\u662f 05f5e1bb6a1bb \u3002 CONTAINER IMAGE CREATED STATE NAME ATTEMPT POD ID POD 50058afb3cba5 62aedd01bd852 About an hour ago Running producer 0 e6953bd4833a7 hello-producer \u8fd0\u884c\u547d\u4ee4 crictl inspect \uff0c\u83b7\u53d6\u5df2\u6302\u8f7d\u7684 shared-volume \u7684\u8def\u5f84\uff0c\u5b83\u662f emptyDir \u7c7b\u578b\u7684\u3002 crictl inspect 50058afb3cba5 | grep source | grep empty \u8fd0\u884c\u7ed3\u679c \"source\": \"/var/lib/kubelet/pods/d7424f86-534a-48f9-9001-9d2a6e822b12/volumes/kubernetes.io~empty-dir/shared-volume\", \u4fee\u6539\u8def\u5f84\u4e3a\u4e0a\u9762\u83b7\u53d6\u5230\u7684 shared-volume \u7684\u6302\u8f7d\u8def\u5f84\u3002\u7136\u540e\u6211\u4eec\u4f1a\u770b\u5230\u6587\u4ef6 hello \u4e2d\u7684\u5185\u5bb9 hello world \u3002 cd /var/lib/kubelet/pods/d7424f86-534a-48f9-9001-9d2a6e822b12/volumes/kubernetes.io~empty-dir/shared-volume cat hello Pod\u5185\u7684\u8def\u5f84 /producer_dir \u88ab\u6302\u8f7d\u5230\u4e86\u672c\u5730\u5bbf\u4e3b\u673a\u8def\u5f84 /var/lib/kubelet/pods/d7424f86-534a-48f9-9001-9d2a6e822b12/volumes/kubernetes.io~empty-dir/shared-volume \u3002 \u6211\u4eec\u5728Pod\u5185\u521b\u5efa\u7684\u6587\u4ef6 /producer_dir/hello \u5b9e\u9645\u4e0a\u5728\u5bbf\u4e3b\u673a\u672c\u5730\u8def\u5f84\u4e2d\u3002 \u8ba9\u6211\u4eec\u5220\u9664\u5bb9\u5668 producer \uff0c\u5bb9\u5668 producer \u5c06\u4ee5\u65b0\u7684\u5bb9\u5668ID\u91cd\u65b0\u542f\u52a8\uff0c\u800c\u6587\u4ef6 hello \u4ecd\u5c06\u5b58\u5728\u3002 crictl ps crictl stop crictl rm \u73b0\u5728\u5220\u9664Pod hello-producer \uff0c\u5bb9\u5668 producer \u4f1a\u88ab\u5220\u9664\uff0c\u6587\u4ef6 hello \u4e5f\u4f1a\u88ab\u5220\u9664\u3002 kubectl delete pod hello-producer hostPath \u00b6 \u5e94\u7528\u4ee5\u4e0b yaml \u6587\u4ef6\u521b\u5efa\u4e00\u4e2a MySQL Pod \u5e76\u6302\u8f7d\u4e00\u4e2a hostPath \u3002 \u5c06\u4e3b\u673a\u76ee\u5f55 /tmp/mysql \u6302\u8f7d\u5230 Pod \u76ee\u5f55 /var/lib/mysql \u3002 \u5728\u672c\u5730\u68c0\u67e5\u662f\u5426\u5b58\u5728\u76ee\u5f55 /tmp/mysql \uff0c\u5982\u679c\u4e0d\u5b58\u5728\uff0c\u5219\u6267\u884c\u547d\u4ee4 mkdir /tmp/mysql \u521b\u5efa\u5b83\u3002 cat > mysql-hostpath.yaml < cka003 \u5728MySQL Pod\u8fd0\u884c\u7684\u8282\u70b9\u767b\u9646\u8fdb\u5165pod\u5185\u90e8\u3002 kubectl exec -it -- bash \u5728 Pod \u4e2d\uff0c\u8fdb\u5165 /var/lib/mysql \u76ee\u5f55\uff0c\u8be5\u76ee\u5f55\u4e2d\u7684\u6240\u6709\u6587\u4ef6\u90fd\u4e0e\u8282\u70b9 cka003 \u4e0a /tmp/mysql \u76ee\u5f55\u4e2d\u7684\u6240\u6709\u6587\u4ef6\u76f8\u540c\u3002 \u8fde\u63a5\u5230 Pod \u4e2d\u7684\u6570\u636e\u5e93\u3002 mysql -h 127 .0.0.1 -uroot -ppassword \u6267\u884c\u4e0b\u9762\u547d\u4ee4\u5bf9\u6570\u636e\u5e93\u8fdb\u884c\u7b80\u5355\u7684\u64cd\u4f5c\u3002 mysql> show databases ; mysql> connect mysql ; mysql> show tables ; mysql> exit PV\u548cPVC \u00b6 \u4e0b\u9762\u7684\u6f14\u793a\u4e2d\uff0c\u6211\u4eec\u5c06\u4f7f\u7528NFS\u4f5c\u4e3a\u540e\u7aef\u5b58\u50a8\u6765\u6f14\u793a\u5982\u4f55\u90e8\u7f72PV\u548cPVC\u3002 \u8bbe\u7f6eNFS\u5171\u4eab \u00b6 \u5b89\u88c5nfs-kernel-server \u767b\u5f55\u5230\u8282\u70b9 cka002 \u3002\u914d\u7f6eWorker cka002 \u6210\u4e3aNFS\u670d\u52a1\u5668\u3002 sudo apt-get install -y nfs-kernel-server 2.\u914d\u7f6e\u5171\u4eab\u76ee\u5f55 \u521b\u5efa\u5171\u4eab\u6587\u4ef6\u5939\u3002 mkdir /nfsdata \u7f16\u8f91\u6587\u4ef6 /etc/exports \uff0c\u6dfb\u52a0\u4e00\u884c /nfsdata *(rw,sync,no_root_squash) \u3002 cat >> /etc/exports << EOF /nfsdata *(rw,sync,no_root_squash) EOF \u6709\u8bb8\u591a\u4e0d\u540c\u7684NFS\u5171\u4eab\u9009\u9879\uff0c\u4f8b\u5982\uff1a * \uff1a\u5bf9\u6240\u6709IP\u6216\u7279\u5b9aIP\u53ef\u8bbf\u95ee\u3002 rw \uff1a\u4f5c\u4e3a\u8bfb\u5199\u5171\u4eab\u3002\u8bf7\u6ce8\u610f\uff0c\u6b63\u5e38\u7684Linux\u6743\u9650\u4ecd\u7136\u9002\u7528\u3002\uff08\u8bf7\u6ce8\u610f\uff0c\u8fd9\u662f\u9ed8\u8ba4\u9009\u9879\u3002\uff09 ro \uff1a\u4f5c\u4e3a\u53ea\u8bfb\u5171\u4eab\u3002 sync \uff1a\u6587\u4ef6\u6570\u636e\u66f4\u6539\u4f1a\u7acb\u5373\u5199\u5165\u78c1\u76d8\uff0c\u8fd9\u4f1a\u5f71\u54cd\u6027\u80fd\uff0c\u4f46\u4e0d\u592a\u53ef\u80fd\u5bfc\u81f4\u6570\u636e\u4e22\u5931\u3002\u5728\u67d0\u4e9b\u53d1\u884c\u7248\u4e0a\uff0c\u8fd9\u662f\u9ed8\u8ba4\u9009\u9879\u3002 async \uff1a\u4e0esync\u76f8\u53cd\uff0c\u6587\u4ef6\u6570\u636e\u66f4\u6539\u6700\u521d\u5199\u5165\u5185\u5b58\u3002\u8fd9\u63d0\u9ad8\u4e86\u6027\u80fd\uff0c\u4f46\u66f4\u5bb9\u6613\u5bfc\u81f4\u6570\u636e\u4e22\u5931\u3002\u5728\u67d0\u4e9b\u53d1\u884c\u7248\u4e0a\uff0c\u8fd9\u662f\u9ed8\u8ba4\u9009\u9879\u3002 root_squash \uff1a\u5c06NFS\u5ba2\u6237\u7aef\u7684root\u7528\u6237\u548c\u7ec4\u5e10\u6237\u6620\u5c04\u5230\u533f\u540d\u5e10\u6237\uff0c\u901a\u5e38\u662fnobody\u5e10\u6237\u6216nfsnobody\u5e10\u6237\u3002\u6709\u5173\u66f4\u591a\u8be6\u7ec6\u4fe1\u606f\uff0c\u8bf7\u53c2\u89c1\u672c\u6587\u540e\u7eed\u7684\u201c\u7528\u6237ID\u6620\u5c04\u201d\u3002\uff08\u8bf7\u6ce8\u610f\uff0c\u8fd9\u662f\u9ed8\u8ba4\u9009\u9879\u3002\uff09 no_root_squash \uff1a\u5c06NFS\u5ba2\u6237\u7aef\u7684root\u7528\u6237\u548c\u7ec4\u5e10\u6237\u6620\u5c04\u5230\u672c\u5730root\u548c\u7ec4\u5e10\u6237\u3002 \u6211\u4eec\u5c06\u4f7f\u7528\u57fa\u4e8eLinux\u670d\u52a1\u5668\u4e4b\u95f4\u7684 nfs \u548c rpcbind \u670d\u52a1\u7684\u65e0\u5bc6\u7801\u8fdc\u7a0b\u6302\u8f7d\uff0c\u800c\u4e0d\u662f\u57fa\u4e8e smb \u670d\u52a1\u3002\u9996\u5148\uff0c\u8fd9\u4e24\u53f0\u670d\u52a1\u5668\u5fc5\u987b\u6388\u6743\u3001\u5b89\u88c5\u5e76\u8bbe\u7f6enfs\u548crpcbind\u670d\u52a1\uff0c\u8bbe\u7f6e\u5171\u4eab\u76ee\u5f55\uff0c\u542f\u52a8\u670d\u52a1\uff0c\u5e76\u5728\u5ba2\u6237\u7aef\u4e0a\u8fdb\u884c\u6302\u8f7d\u3002 \u542f\u52a8 rpcbind \u670d\u52a1\u3002 sudo systemctl enable rpcbind sudo systemctl restart rpcbind \u542f\u52a8 nfs \u670d\u52a1\u3002 sudo systemctl enable nfs-server sudo systemctl start nfs-server \u5982\u679c /etc/exports \u6587\u4ef6\u88ab\u4fee\u6539\uff0c\u6211\u4eec\u9700\u8981\u8fd0\u884c\u4e0b\u9762\u7684\u547d\u4ee4\u4f7f\u4e4b\u751f\u6548\u3002 exportfs -ra \u8fd0\u884c\u7ed3\u679c exportfs: /etc/exports [ 1 ] : Neither 'subtree_check' or 'no_subtree_check' specified for export \"*:/nfsdata\" . Assuming default behaviour ( 'no_subtree_check' ) . NOTE: this default has changed since nfs-utils version 1 .0.x \u68c0\u67e5\u5171\u4eab\u76ee\u5f55\u662f\u5426\u5df2\u7ecf\u88ab\u6b63\u786e\u914d\u7f6e\u4e86\u3002 showmount -e \u5982\u679c\u770b\u5230\u4e0b\u9762\u7684\u7ed3\u679c\uff0c\u5219\u8bf4\u660e\u5171\u4eab\u76ee\u5f55\u5df2\u7ecf\u88ab\u6b63\u786e\u914d\u7f6e\u4e86\u3002 Export list for cka002: /nfsdata * 3.\u5b89\u88c5NFS\u5ba2\u6237\u7aef \u5728\u6240\u6709\u8282\u70b9\u4e0a\u5b89\u88c5NFS\u5ba2\u6237\u7aef\u3002 sudo apt-get install -y nfs-common 4.\u9a8c\u8bc1NFS\u670d\u52a1 \u767b\u5f55\u5230\u4efb\u4f55\u4e00\u4e2a\u8282\u70b9\u6765\u9a8c\u8bc1NFS\u670d\u52a1\u662f\u5426\u6b63\u786e\u5de5\u4f5c\uff0c\u4ee5\u53caNFS\u670d\u52a1\u6240\u5171\u4eab\u5230\u76ee\u5f55\u662f\u5426\u53ef\u89c1\u3002 \u767b\u9646\u5230 cka001 \uff0c\u5e76\u68c0\u67e5 cka002 \u7684\u5171\u4eab\u76ee\u5f55\u72b6\u6001\u3002 showmount -e cka002 \u5982\u679c\u5f97\u5230\u7c7b\u4f3c\u4e0b\u9762\u7684\u7ed3\u679c\uff0c\u5219\u8bf4\u660eNFS\u670d\u52a1\u6b63\u5e38\u5de5\u4f5c\uff0c\u5305\u62ec\u5171\u4eab\u76ee\u5f55\u3002 Export list for cka002: /nfsdata * 5.\u6302\u8f7dNFS\u5171\u4eab\u76ee\u5f55 \u6267\u884c\u4e0b\u9762\u547d\u4ee4\uff0c\u6302\u8f7dNFS\u5171\u4eab\u76ee\u5f55\u5230\u4efb\u4f55\u4e00\u4e2a\u975eNFS\u670d\u52a1\u5668\u8282\u70b9\uff0c\u6bd4\u5982 cka001 or cka003 \u3002 mkdir /remote-nfs-dir mount -t nfs cka002:/nfsdata /remote-nfs-dir/ \u6267\u884c\u547d\u4ee4 df -h \u6765\u68c0\u67e5NFS\u6302\u8f7d\u70b9\u662f\u5426\u6b63\u786e\uff0c\u7c7b\u4f3c\u4e0b\u9762\u7684\u7ed3\u679c\u3002 Filesystem Size Used Avail Use% Mounted on cka002:/nfsdata 40G 5 .8G 32G 16 % /remote-nfs-dir \u521b\u5efa PV \u00b6 \u521b\u5efa\u4e00\u4e2a PV mysql-pv \u3002 \u5c06 NFS \u670d\u52a1\u5668 IP \u66ff\u6362\u4e3a\u5b9e\u9645\u7684 IP\uff08\u8fd9\u91cc\u662f \uff09\uff0c\u5b83\u662f\u8fd0\u884c NFS \u670d\u52a1\u5668 cka002 \u7684 IP\u3002 kubectl apply -f - < EOF \u6267\u884c\u4e0b\u9762\u7684\u547d\u4ee4\uff0c\u68c0\u67e5\u521b\u5efa\u7684PV\u3002 kubectl get pv \u8fd0\u884c\u7ed3\u679c NAME CAPACITY ACCESS MODES RECLAIM POLICY STATUS CLAIM STORAGECLASS REASON AGE mysql-pv 1Gi RWO Retain Available nfs 19s \u521b\u5efa PVC \u00b6 \u521b\u5efa PVC mysql-pvc \u5e76\u6307\u5b9a\u5b58\u50a8\u5927\u5c0f\u3001\u8bbf\u95ee\u6a21\u5f0f\u548c\u5b58\u50a8\u7c7b\u3002 PVC mysql-pvc \u5c06\u901a\u8fc7\u5b58\u50a8\u7c7b\u540d\u79f0\u81ea\u52a8\u4e0e PV \u7ed1\u5b9a\u3002 kubectl apply -f - < nfs-provisioner-rbac.yaml < ( cka002 ) \u4e0a\u7684 /nfsdata \u76ee\u5f55\u7684\u5377 nfs-client-root \u3002 \u628a NFS \u670d\u52a1\u5668\u7684 IP \u66ff\u6362\u4e3a\u5b9e\u9645\u7684 IP \u5730\u5740\u5373\u53ef\uff08\u8fd9\u91cc\u7528 \u8868\u793a\uff09\u3002 cat > nfs-provisioner-deployment.yaml < - name: NFS_PATH value: /nfsdata volumes: - name: nfs-client-root nfs: server: path: /nfsdata EOF kubectl apply -f nfs-provisioner-deployment.yaml \u521b\u5efa NFS StorageClass \u00b6 \u521b\u5efa StorageClass nfs-client \uff0c\u5b9a\u4e49 NFS \u5b50\u76ee\u5f55\u5916\u90e8 provisioner \u7684 Kubernetes Storage Class\u3002 \u6267\u884c\u4e0b\u9762\u7684\u547d\u4ee4\u7f16\u8f91 nfs-storageclass.yaml \u6587\u4ef6\u3002 vi nfs-storageclass.yaml \u6dfb\u52a0\u4e0b\u9762\u7684\u4fe1\u606f\u6765\u914d\u7f6e NFS StorageClass\u3002 apiVersion: storage.k8s.io/v1 kind: StorageClass metadata: name: nfs-client annotations: storageclass.kubernetes.io/is-default-class: \"true\" provisioner: k8s-sigs.io/nfs-subdir-external-provisioner parameters: pathPattern: \" ${ .PVC.namespace } / ${ .PVC.annotations.nfs.io/storage-path } \" onDelete: delete \u5e94\u7528\u4e0a\u9762\u7684yaml\u6587\u4ef6\uff0c\u4f7f\u4e4b\u751f\u6548\u3002 kubectl apply -f nfs-storageclass.yaml \u521b\u5efaPVC \u00b6 \u521b\u5efa PVC nfs-pvc-from-sc \u3002 kubectl apply -f - < mysql-with-sc-pvc-7c97d875f8-wkvr9 1/1 Running 0 3m37s 10.244.102.27 cka003 \u6211\u4eec\u73b0\u5728\u6765\u67e5\u770b NFS \u670d\u52a1\u5668 cka002 \u4e0a\u7684\u5171\u4eab\u76ee\u5f55 /nfsdata/ \u3002 ll /nfsdata/ NFS \u670d\u52a1\u5668 cka002 \u4e0a\u7684\u5171\u4eab\u76ee\u5f55 /nfsdata/ \u4e0b\u6709\u4e862\u4e2a\u5b50\u76ee\u5f55\uff0c\u4e0e\u5176\u4ed62\u4e2a\u8282\u70b9\u4e0a\u7684\u76ee\u5f55 /remote-nfs-dir/ \u4e0b\u7684\u5185\u5bb9\u662f\u4e00\u81f4\u3002 drwxrwxrwx 6 systemd-coredump root 4096 Jul 23 23 :35 dev/ drwxr-xr-x 6 systemd-coredump root 4096 Jul 23 22 :29 mysqldata/ \u547d\u540d\u7a7a\u95f4Namespace\u7684\u540d\u79f0\u4f5c\u4e3a\u76ee\u5f55\u540d\u5728 /nfsdata/ \u76ee\u5f55\u4e0b\u7528\u4e8e\u6302\u8f7d\u5230 Pod \u4e2d\u3002 \u9ed8\u8ba4\u60c5\u51b5\u4e0b\uff0c\u547d\u540d\u7a7a\u95f4Namespace\u540d\u79f0\u5c06\u7528\u4e8e\u6302\u8f7d\u70b9\u3002 \u5982\u679c\u6211\u4eec\u60f3\u8981\u4f7f\u7528\u81ea\u5b9a\u4e49\u7684\u6587\u4ef6\u5939\u6765\u4ee3\u66ff\uff0c\u6211\u4eec\u9700\u8981\u58f0\u660e\u4e00\u4e2a nfs.io/storage-path \u6ce8\u91ca\uff0c\u4f8b\u5982\u4e0b\u9762\u7684\u4f8b\u5b50\u3002 \u5728\u547d\u540d\u7a7a\u95f4 kube-system \u4e0a\u521b\u5efa PVC test-claim \uff0c\u5e76\u6d88\u8d39 nfs-client \u5377\u3002 kubectl apply -f - < ..data/password lrwxrwxrwx 1 root root 15 Jul 23 16 :30 username -> ..data/username \u800c\u4e14\u6211\u4eec\u53ef\u4ee5\u770b\u5230\u8fd92\u4e2a\u6570\u636e\u5143\u7d20\uff08 username \u548c password \uff09\u7684\u5185\u5bb9\u5c31\u662f\u6211\u4eec\u9884\u5148\u5b9a\u4e49\u7684\u3002 / # cat /tmp/secret/username admin / # cat /tmp/secret/password 123456 \u62d3\u5c55\u6848\u4f8b \u00b6 \u591a\u79cd\u65b9\u6cd5\u521b\u5efaConfigMap \u00b6 \u6211\u4eec\u53ef\u4ee5\u901a\u8fc7\u6587\u4ef6\u3001\u76ee\u5f55\u3001\u6216\u8005\u503c\u6765\u521b\u5efaConfigMap\u3002 \u4e0b\u9762\u6211\u4eec\u521b\u5efaConfigMap colors \uff0c\u5305\u542b\uff1a \u56db\u4e2a\u6587\u4ef6\uff0c\u6587\u4ef6\u540d\u662f\u56db\u4e2a\u989c\u8272\u3002 \u4e00\u4e2a\u6587\u4ef6\uff0c\u6587\u4ef6\u540d\u662f\u6700\u559c\u6b22\u7684\u989c\u8272\u3002 mkdir configmap cd configmap mkdir primary echo c > primary/cyan echo m > primary/magenta echo y > primary/yellow echo k > primary/black echo \"known as key\" >> primary/black echo blue > favorite \u6267\u884c\u547d\u4ee4 tree configmap \uff0c\u53ef\u4ee5\u770b\u5230\u7c7b\u4f3c\u4e0b\u9762\u7684\u6587\u4ef6\u76ee\u5f55\u7ed3\u6784\u3002 configmap \u251c\u2500\u2500 favorite \u2514\u2500\u2500 primary \u251c\u2500\u2500 black \u251c\u2500\u2500 cyan \u251c\u2500\u2500 magenta \u2514\u2500\u2500 yellow \u521b\u5efa\u4e00\u4e2a ConfigMap\uff0c\u5f15\u7528\u4e0a\u9762\u6211\u4eec\u521b\u5efa\u7684\u6587\u4ef6\u3002\u786e\u4fdd\u6211\u4eec\u73b0\u5728\u5728\u8def\u5f84 ~/configmap \u4e0b\u3002 kubectl create configmap colors \\ --from-literal = text = black \\ --from-file = ./favorite \\ --from-file = ./primary/ \u67e5\u770bConfigMap colors \u7684\u5185\u5bb9\u3002 kubectl get configmap colors -o yaml \u8fd0\u884c\u7ed3\u679c\uff1a apiVersion: v1 data: black: | k known as key cyan: | c favorite: | blue magenta: | m text: black yellow: | y kind: ConfigMap metadata: creationTimestamp: \"2022-07-12T16:38:27Z\" name: colors namespace: dev resourceVersion: \"2377258\" uid: d5ab133f-5e4d-41d4-bc9e-2bbb22a872a1 \u901a\u8fc7ConfigMap\u8bbe\u5b9a\u73af\u5883\u53d8\u91cf \u00b6 \u7ee7\u7eed\u4e0a\u9762\u7684\u4f8b\u5b50\uff0c\u73b0\u5728\u6211\u4eec\u51c6\u5907\u521b\u5efa\u4e00\u4e2a\u540d\u4e3a pod-configmap-env \u7684Pod\uff0c\u8bbe\u7f6e\u73af\u5883\u53d8\u91cf ilike \u5e76\u4eceConfigMap colors \u4e2d\u5206\u914d\u503c favorite \u3002 kubectl apply -f - << EOF apiVersion: v1 kind: Pod metadata: name: pod-configmap-env spec: containers: - name: nginx image: nginx env: - name: ilike valueFrom: configMapKeyRef: name: colors key: favorite EOF \u8fde\u63a5\u5e76\u8fdb\u5165Pod pod-configmap-env \u5185\u90e8\u3002 kubectl exec -it pod-configmap-env -- bash \u9a8c\u8bc1\u73af\u5883\u53d8\u91cf ilike \u7684\u503c\u662f blue \uff0c\u8fd9\u662f ConfigMap colors \u7684 favorite \u503c\u3002 root@pod-configmap-env:/# echo $ilike blue \u6211\u4eec\u8fd8\u53ef\u4ee5\u4f7f\u7528 ConfigMap \u7684\u6240\u6709\u952e\u503c\u5bf9\u6765\u8bbe\u7f6e Pod \u7684\u73af\u5883\u53d8\u91cf\u3002 kubectl apply -f - << EOF apiVersion: v1 kind: Pod metadata: name: pod-configmap-env-2 spec: containers: - name: nginx image: nginx envFrom: - configMapRef: name: colors EOF \u8fde\u63a5\u5e76\u8fdb\u5165Pod pod-configmap-env-2 \u5185\u90e8\u3002 kubectl exec -it pod-configmap-env-2 -- bash \u9a8c\u8bc1\u73af\u5883\u53d8\u91cf\u7684\u503c\u662f\u6211\u4eec\u5728ConfigMap colors \u6240\u5b9a\u4e49\u7684\u952e\u503c\u5bf9\u3002 root@pod-configmap-env-2:/# echo $black k known as key root@pod-configmap-env-2:/# echo $cyan c root@pod-configmap-env-2:/# echo $favorite blue","title":"Persistence"},{"location":"k8s/cka_cn/foundamentals/persistence/#cka17persistence","text":"","title":"CKA\u81ea\u5b66\u7b14\u8bb017:Persistence"},{"location":"k8s/cka_cn/foundamentals/persistence/#_1","text":"\u6f14\u793a\u573a\u666f\uff1a \u521b\u5efa\u4e00\u4e2a\u7c7b\u578b\u4e3a emptyDir \u7684\u5377\u6765\u521b\u5efa Pod\uff0cPod \u4e2d\u7684\u5bb9\u5668\u5c06\u4f1a\u6302\u8f7d\u5728\u8fd0\u884c\u8282\u70b9\u4e0a\u7684\u9ed8\u8ba4\u76ee\u5f55 /var/lib/kubelet/pods/ \u4e2d\u3002 \u521b\u5efa\u4e00\u4e2a\u7c7b\u578b\u4e3a hostPath \u7684\u5377\u6765\u521b\u5efa Deployment\uff0cDeployment \u4e2d\u7684\u5bb9\u5668\u5c06\u4f1a\u6302\u8f7d\u5728\u8fd0\u884c\u8282\u70b9\u4e0a\u5b9a\u4e49\u7684\u76ee\u5f55 hostPath: \u4e2d\u3002 \u521b\u5efa PV \u548c PVC\uff1a \u8bbe\u7f6e NFS \u670d\u52a1\u5668\u5e76\u5171\u4eab /nfsdata/ \u76ee\u5f55\u3002 \u521b\u5efa PV mysql-pv \u5e76\u6620\u5c04\u5230\u5171\u4eab\u76ee\u5f55 /nfsdata/ \uff0c\u540c\u65f6\u8bbe\u7f6e StorageClassName \u4e3a nfs \u3002 \u521b\u5efa PVC mysql-pvc \u5e76\u6620\u5c04\u5230 StorageClassName \u4e3a nfs \u7684 PV \u4e0a\u3002 \u521b\u5efa Deployment mysql \u6765\u4f7f\u7528 PVC mysql-pvc \u3002 \u521b\u5efa StorageClass\uff1a \u521b\u5efa ServiceAccount nfs-client-provisioner \u3002 \u521b\u5efa ClusterRole nfs-client-provisioner-runner \u548c Role leader-locking-nfs-client-provisioner \uff0c\u5e76\u5c06\u5176\u7ed1\u5b9a\u5230 ServiceAccount \u4e0a\uff0c\u4ee5\u4fbf\u8be5 ServiceAccount \u53ef\u4ee5\u64cd\u4f5c\u4e0b\u4e00\u6b65\u4e2d\u521b\u5efa\u7684 Deployment\u3002 \u521b\u5efa Deployment nfs-client-provisioner \u6765\u6dfb\u52a0\u8fde\u63a5\u5230 NFS \u670d\u52a1\u5668\u7684\u4fe1\u606f\uff0c\u4f8b\u5982 PROVISIONER_NAME \u662f k8s-sigs.io/nfs-subdir-external-provisioner \u3002 \u521b\u5efa StorageClass nfs-client \u5e76\u94fe\u63a5\u5230 provisioner: k8s-sigs.io/nfs-subdir-external-provisioner \uff0c\u76f8\u5173\u7684 PV \u4f1a\u81ea\u52a8\u521b\u5efa\u3002 \u521b\u5efa PVC nfs-pvc-from-sc \u5e76\u6620\u5c04\u5230 StorageClass nfs-client \u4e0a\u7684 PV\u3002 \u914d\u7f6eConfiguration\uff1a \u521b\u5efa\u4e00\u4e2a ConfigMap \u4ee5\u5305\u542b\u6587\u4ef6\u7684\u5185\u5bb9\uff0c\u5e76\u5c06\u6b64 ConfigMap \u6302\u8f7d\u5230 Pod \u4e2d\u7684\u7279\u5b9a\u6587\u4ef6\u4e2d\u3002 \u521b\u5efa\u4e00\u4e2a ConfigMap \u6765\u5305\u542b\u7528\u6237\u540d\u548c\u5bc6\u7801\uff0c\u5e76\u5728 Pod \u4e2d\u4f7f\u7528\u5b83\u4eec\u3002 \u5728 Pod \u4e2d\u5c06 ConfigMap \u7528\u4f5c\u73af\u5883\u53d8\u91cf\u3002 \u5efa\u8bae\uff1a \u9996\u5148\u5220\u9664 PVC\uff0c\u7136\u540e\u518d\u5220\u9664 PV\u3002 \u5982\u679c\u5220\u9664 PVC \u65f6\u9047\u5230 Terminating \u72b6\u6001\uff0c\u4f7f\u7528 kubectl edit pvc \u547d\u4ee4\uff0c\u7136\u540e\u5220\u9664 finalize: \u3002","title":"\u6458\u8981"},{"location":"k8s/cka_cn/foundamentals/persistence/#emptydir","text":"\u521b\u5efa\u4e00\u4e2a\u540d\u4e3a hello-producer \u7684 Pod\uff0c\u5e76\u4f7f\u7528 emptyDir \u7c7b\u578b\u7684 Volume\u3002 cat > pod-emptydir.yaml < /producer_dir/hello; sleep 30000 volumes: - name: shared-volume emptyDir: {} EOF kubectl apply -f pod-emptydir.yaml \u67e5\u770bPod hello-producer \u7684\u72b6\u6001\u3002 kubectl get pod hello-producer -owide Pod hello-producer \u8fd0\u884c\u5728\u8282\u70b9node cka003 \u4e0a\u3002 NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES hello-producer 1/1 Running 0 6s 10.244.102.24 cka003 \u767b\u5f55 cka003 \uff0c\u56e0\u4e3a Pod hello-producer \u6b63\u5728\u8be5\u8282\u70b9\u4e0a\u8fd0\u884c\u3002 \u4e3a crictl \u547d\u4ee4\u8bbe\u7f6e\u73af\u5883\u53d8\u91cf CONTAINER_RUNTIME_ENDPOINT \u3002\u5efa\u8bae\u5728\u6240\u6709\u8282\u70b9\u4e0a\u6267\u884c\u76f8\u540c\u7684\u64cd\u4f5c\u3002 export CONTAINER_RUNTIME_ENDPOINT = unix:///run/containerd/containerd.sock \u8fd0\u884c\u547d\u4ee4 crictl ps \u6765\u83b7\u53d6 Pod hello-producer \u7684\u5bb9\u5668 ID\u3002 crictl ps | grep hello-producer \u5bb9\u5668 producer \u7684ID\u662f 05f5e1bb6a1bb \u3002 CONTAINER IMAGE CREATED STATE NAME ATTEMPT POD ID POD 50058afb3cba5 62aedd01bd852 About an hour ago Running producer 0 e6953bd4833a7 hello-producer \u8fd0\u884c\u547d\u4ee4 crictl inspect \uff0c\u83b7\u53d6\u5df2\u6302\u8f7d\u7684 shared-volume \u7684\u8def\u5f84\uff0c\u5b83\u662f emptyDir \u7c7b\u578b\u7684\u3002 crictl inspect 50058afb3cba5 | grep source | grep empty \u8fd0\u884c\u7ed3\u679c \"source\": \"/var/lib/kubelet/pods/d7424f86-534a-48f9-9001-9d2a6e822b12/volumes/kubernetes.io~empty-dir/shared-volume\", \u4fee\u6539\u8def\u5f84\u4e3a\u4e0a\u9762\u83b7\u53d6\u5230\u7684 shared-volume \u7684\u6302\u8f7d\u8def\u5f84\u3002\u7136\u540e\u6211\u4eec\u4f1a\u770b\u5230\u6587\u4ef6 hello \u4e2d\u7684\u5185\u5bb9 hello world \u3002 cd /var/lib/kubelet/pods/d7424f86-534a-48f9-9001-9d2a6e822b12/volumes/kubernetes.io~empty-dir/shared-volume cat hello Pod\u5185\u7684\u8def\u5f84 /producer_dir \u88ab\u6302\u8f7d\u5230\u4e86\u672c\u5730\u5bbf\u4e3b\u673a\u8def\u5f84 /var/lib/kubelet/pods/d7424f86-534a-48f9-9001-9d2a6e822b12/volumes/kubernetes.io~empty-dir/shared-volume \u3002 \u6211\u4eec\u5728Pod\u5185\u521b\u5efa\u7684\u6587\u4ef6 /producer_dir/hello \u5b9e\u9645\u4e0a\u5728\u5bbf\u4e3b\u673a\u672c\u5730\u8def\u5f84\u4e2d\u3002 \u8ba9\u6211\u4eec\u5220\u9664\u5bb9\u5668 producer \uff0c\u5bb9\u5668 producer \u5c06\u4ee5\u65b0\u7684\u5bb9\u5668ID\u91cd\u65b0\u542f\u52a8\uff0c\u800c\u6587\u4ef6 hello \u4ecd\u5c06\u5b58\u5728\u3002 crictl ps crictl stop crictl rm \u73b0\u5728\u5220\u9664Pod hello-producer \uff0c\u5bb9\u5668 producer \u4f1a\u88ab\u5220\u9664\uff0c\u6587\u4ef6 hello \u4e5f\u4f1a\u88ab\u5220\u9664\u3002 kubectl delete pod hello-producer","title":"emptyDir"},{"location":"k8s/cka_cn/foundamentals/persistence/#hostpath","text":"\u5e94\u7528\u4ee5\u4e0b yaml \u6587\u4ef6\u521b\u5efa\u4e00\u4e2a MySQL Pod \u5e76\u6302\u8f7d\u4e00\u4e2a hostPath \u3002 \u5c06\u4e3b\u673a\u76ee\u5f55 /tmp/mysql \u6302\u8f7d\u5230 Pod \u76ee\u5f55 /var/lib/mysql \u3002 \u5728\u672c\u5730\u68c0\u67e5\u662f\u5426\u5b58\u5728\u76ee\u5f55 /tmp/mysql \uff0c\u5982\u679c\u4e0d\u5b58\u5728\uff0c\u5219\u6267\u884c\u547d\u4ee4 mkdir /tmp/mysql \u521b\u5efa\u5b83\u3002 cat > mysql-hostpath.yaml < cka003 \u5728MySQL Pod\u8fd0\u884c\u7684\u8282\u70b9\u767b\u9646\u8fdb\u5165pod\u5185\u90e8\u3002 kubectl exec -it -- bash \u5728 Pod \u4e2d\uff0c\u8fdb\u5165 /var/lib/mysql \u76ee\u5f55\uff0c\u8be5\u76ee\u5f55\u4e2d\u7684\u6240\u6709\u6587\u4ef6\u90fd\u4e0e\u8282\u70b9 cka003 \u4e0a /tmp/mysql \u76ee\u5f55\u4e2d\u7684\u6240\u6709\u6587\u4ef6\u76f8\u540c\u3002 \u8fde\u63a5\u5230 Pod \u4e2d\u7684\u6570\u636e\u5e93\u3002 mysql -h 127 .0.0.1 -uroot -ppassword \u6267\u884c\u4e0b\u9762\u547d\u4ee4\u5bf9\u6570\u636e\u5e93\u8fdb\u884c\u7b80\u5355\u7684\u64cd\u4f5c\u3002 mysql> show databases ; mysql> connect mysql ; mysql> show tables ; mysql> exit","title":"hostPath"},{"location":"k8s/cka_cn/foundamentals/persistence/#pvpvc","text":"\u4e0b\u9762\u7684\u6f14\u793a\u4e2d\uff0c\u6211\u4eec\u5c06\u4f7f\u7528NFS\u4f5c\u4e3a\u540e\u7aef\u5b58\u50a8\u6765\u6f14\u793a\u5982\u4f55\u90e8\u7f72PV\u548cPVC\u3002","title":"PV\u548cPVC"},{"location":"k8s/cka_cn/foundamentals/persistence/#nfs","text":"\u5b89\u88c5nfs-kernel-server \u767b\u5f55\u5230\u8282\u70b9 cka002 \u3002\u914d\u7f6eWorker cka002 \u6210\u4e3aNFS\u670d\u52a1\u5668\u3002 sudo apt-get install -y nfs-kernel-server 2.\u914d\u7f6e\u5171\u4eab\u76ee\u5f55 \u521b\u5efa\u5171\u4eab\u6587\u4ef6\u5939\u3002 mkdir /nfsdata \u7f16\u8f91\u6587\u4ef6 /etc/exports \uff0c\u6dfb\u52a0\u4e00\u884c /nfsdata *(rw,sync,no_root_squash) \u3002 cat >> /etc/exports << EOF /nfsdata *(rw,sync,no_root_squash) EOF \u6709\u8bb8\u591a\u4e0d\u540c\u7684NFS\u5171\u4eab\u9009\u9879\uff0c\u4f8b\u5982\uff1a * \uff1a\u5bf9\u6240\u6709IP\u6216\u7279\u5b9aIP\u53ef\u8bbf\u95ee\u3002 rw \uff1a\u4f5c\u4e3a\u8bfb\u5199\u5171\u4eab\u3002\u8bf7\u6ce8\u610f\uff0c\u6b63\u5e38\u7684Linux\u6743\u9650\u4ecd\u7136\u9002\u7528\u3002\uff08\u8bf7\u6ce8\u610f\uff0c\u8fd9\u662f\u9ed8\u8ba4\u9009\u9879\u3002\uff09 ro \uff1a\u4f5c\u4e3a\u53ea\u8bfb\u5171\u4eab\u3002 sync \uff1a\u6587\u4ef6\u6570\u636e\u66f4\u6539\u4f1a\u7acb\u5373\u5199\u5165\u78c1\u76d8\uff0c\u8fd9\u4f1a\u5f71\u54cd\u6027\u80fd\uff0c\u4f46\u4e0d\u592a\u53ef\u80fd\u5bfc\u81f4\u6570\u636e\u4e22\u5931\u3002\u5728\u67d0\u4e9b\u53d1\u884c\u7248\u4e0a\uff0c\u8fd9\u662f\u9ed8\u8ba4\u9009\u9879\u3002 async \uff1a\u4e0esync\u76f8\u53cd\uff0c\u6587\u4ef6\u6570\u636e\u66f4\u6539\u6700\u521d\u5199\u5165\u5185\u5b58\u3002\u8fd9\u63d0\u9ad8\u4e86\u6027\u80fd\uff0c\u4f46\u66f4\u5bb9\u6613\u5bfc\u81f4\u6570\u636e\u4e22\u5931\u3002\u5728\u67d0\u4e9b\u53d1\u884c\u7248\u4e0a\uff0c\u8fd9\u662f\u9ed8\u8ba4\u9009\u9879\u3002 root_squash \uff1a\u5c06NFS\u5ba2\u6237\u7aef\u7684root\u7528\u6237\u548c\u7ec4\u5e10\u6237\u6620\u5c04\u5230\u533f\u540d\u5e10\u6237\uff0c\u901a\u5e38\u662fnobody\u5e10\u6237\u6216nfsnobody\u5e10\u6237\u3002\u6709\u5173\u66f4\u591a\u8be6\u7ec6\u4fe1\u606f\uff0c\u8bf7\u53c2\u89c1\u672c\u6587\u540e\u7eed\u7684\u201c\u7528\u6237ID\u6620\u5c04\u201d\u3002\uff08\u8bf7\u6ce8\u610f\uff0c\u8fd9\u662f\u9ed8\u8ba4\u9009\u9879\u3002\uff09 no_root_squash \uff1a\u5c06NFS\u5ba2\u6237\u7aef\u7684root\u7528\u6237\u548c\u7ec4\u5e10\u6237\u6620\u5c04\u5230\u672c\u5730root\u548c\u7ec4\u5e10\u6237\u3002 \u6211\u4eec\u5c06\u4f7f\u7528\u57fa\u4e8eLinux\u670d\u52a1\u5668\u4e4b\u95f4\u7684 nfs \u548c rpcbind \u670d\u52a1\u7684\u65e0\u5bc6\u7801\u8fdc\u7a0b\u6302\u8f7d\uff0c\u800c\u4e0d\u662f\u57fa\u4e8e smb \u670d\u52a1\u3002\u9996\u5148\uff0c\u8fd9\u4e24\u53f0\u670d\u52a1\u5668\u5fc5\u987b\u6388\u6743\u3001\u5b89\u88c5\u5e76\u8bbe\u7f6enfs\u548crpcbind\u670d\u52a1\uff0c\u8bbe\u7f6e\u5171\u4eab\u76ee\u5f55\uff0c\u542f\u52a8\u670d\u52a1\uff0c\u5e76\u5728\u5ba2\u6237\u7aef\u4e0a\u8fdb\u884c\u6302\u8f7d\u3002 \u542f\u52a8 rpcbind \u670d\u52a1\u3002 sudo systemctl enable rpcbind sudo systemctl restart rpcbind \u542f\u52a8 nfs \u670d\u52a1\u3002 sudo systemctl enable nfs-server sudo systemctl start nfs-server \u5982\u679c /etc/exports \u6587\u4ef6\u88ab\u4fee\u6539\uff0c\u6211\u4eec\u9700\u8981\u8fd0\u884c\u4e0b\u9762\u7684\u547d\u4ee4\u4f7f\u4e4b\u751f\u6548\u3002 exportfs -ra \u8fd0\u884c\u7ed3\u679c exportfs: /etc/exports [ 1 ] : Neither 'subtree_check' or 'no_subtree_check' specified for export \"*:/nfsdata\" . Assuming default behaviour ( 'no_subtree_check' ) . NOTE: this default has changed since nfs-utils version 1 .0.x \u68c0\u67e5\u5171\u4eab\u76ee\u5f55\u662f\u5426\u5df2\u7ecf\u88ab\u6b63\u786e\u914d\u7f6e\u4e86\u3002 showmount -e \u5982\u679c\u770b\u5230\u4e0b\u9762\u7684\u7ed3\u679c\uff0c\u5219\u8bf4\u660e\u5171\u4eab\u76ee\u5f55\u5df2\u7ecf\u88ab\u6b63\u786e\u914d\u7f6e\u4e86\u3002 Export list for cka002: /nfsdata * 3.\u5b89\u88c5NFS\u5ba2\u6237\u7aef \u5728\u6240\u6709\u8282\u70b9\u4e0a\u5b89\u88c5NFS\u5ba2\u6237\u7aef\u3002 sudo apt-get install -y nfs-common 4.\u9a8c\u8bc1NFS\u670d\u52a1 \u767b\u5f55\u5230\u4efb\u4f55\u4e00\u4e2a\u8282\u70b9\u6765\u9a8c\u8bc1NFS\u670d\u52a1\u662f\u5426\u6b63\u786e\u5de5\u4f5c\uff0c\u4ee5\u53caNFS\u670d\u52a1\u6240\u5171\u4eab\u5230\u76ee\u5f55\u662f\u5426\u53ef\u89c1\u3002 \u767b\u9646\u5230 cka001 \uff0c\u5e76\u68c0\u67e5 cka002 \u7684\u5171\u4eab\u76ee\u5f55\u72b6\u6001\u3002 showmount -e cka002 \u5982\u679c\u5f97\u5230\u7c7b\u4f3c\u4e0b\u9762\u7684\u7ed3\u679c\uff0c\u5219\u8bf4\u660eNFS\u670d\u52a1\u6b63\u5e38\u5de5\u4f5c\uff0c\u5305\u62ec\u5171\u4eab\u76ee\u5f55\u3002 Export list for cka002: /nfsdata * 5.\u6302\u8f7dNFS\u5171\u4eab\u76ee\u5f55 \u6267\u884c\u4e0b\u9762\u547d\u4ee4\uff0c\u6302\u8f7dNFS\u5171\u4eab\u76ee\u5f55\u5230\u4efb\u4f55\u4e00\u4e2a\u975eNFS\u670d\u52a1\u5668\u8282\u70b9\uff0c\u6bd4\u5982 cka001 or cka003 \u3002 mkdir /remote-nfs-dir mount -t nfs cka002:/nfsdata /remote-nfs-dir/ \u6267\u884c\u547d\u4ee4 df -h \u6765\u68c0\u67e5NFS\u6302\u8f7d\u70b9\u662f\u5426\u6b63\u786e\uff0c\u7c7b\u4f3c\u4e0b\u9762\u7684\u7ed3\u679c\u3002 Filesystem Size Used Avail Use% Mounted on cka002:/nfsdata 40G 5 .8G 32G 16 % /remote-nfs-dir","title":"\u8bbe\u7f6eNFS\u5171\u4eab"},{"location":"k8s/cka_cn/foundamentals/persistence/#pv","text":"\u521b\u5efa\u4e00\u4e2a PV mysql-pv \u3002 \u5c06 NFS \u670d\u52a1\u5668 IP \u66ff\u6362\u4e3a\u5b9e\u9645\u7684 IP\uff08\u8fd9\u91cc\u662f \uff09\uff0c\u5b83\u662f\u8fd0\u884c NFS \u670d\u52a1\u5668 cka002 \u7684 IP\u3002 kubectl apply -f - < EOF \u6267\u884c\u4e0b\u9762\u7684\u547d\u4ee4\uff0c\u68c0\u67e5\u521b\u5efa\u7684PV\u3002 kubectl get pv \u8fd0\u884c\u7ed3\u679c NAME CAPACITY ACCESS MODES RECLAIM POLICY STATUS CLAIM STORAGECLASS REASON AGE mysql-pv 1Gi RWO Retain Available nfs 19s","title":"\u521b\u5efa PV"},{"location":"k8s/cka_cn/foundamentals/persistence/#pvc","text":"\u521b\u5efa PVC mysql-pvc \u5e76\u6307\u5b9a\u5b58\u50a8\u5927\u5c0f\u3001\u8bbf\u95ee\u6a21\u5f0f\u548c\u5b58\u50a8\u7c7b\u3002 PVC mysql-pvc \u5c06\u901a\u8fc7\u5b58\u50a8\u7c7b\u540d\u79f0\u81ea\u52a8\u4e0e PV \u7ed1\u5b9a\u3002 kubectl apply -f - < nfs-provisioner-rbac.yaml < ( cka002 ) \u4e0a\u7684 /nfsdata \u76ee\u5f55\u7684\u5377 nfs-client-root \u3002 \u628a NFS \u670d\u52a1\u5668\u7684 IP \u66ff\u6362\u4e3a\u5b9e\u9645\u7684 IP \u5730\u5740\u5373\u53ef\uff08\u8fd9\u91cc\u7528 \u8868\u793a\uff09\u3002 cat > nfs-provisioner-deployment.yaml < - name: NFS_PATH value: /nfsdata volumes: - name: nfs-client-root nfs: server: path: /nfsdata EOF kubectl apply -f nfs-provisioner-deployment.yaml","title":"\u521b\u5efaProvisioner\u7684Deloyment"},{"location":"k8s/cka_cn/foundamentals/persistence/#nfs-storageclass","text":"\u521b\u5efa StorageClass nfs-client \uff0c\u5b9a\u4e49 NFS \u5b50\u76ee\u5f55\u5916\u90e8 provisioner \u7684 Kubernetes Storage Class\u3002 \u6267\u884c\u4e0b\u9762\u7684\u547d\u4ee4\u7f16\u8f91 nfs-storageclass.yaml \u6587\u4ef6\u3002 vi nfs-storageclass.yaml \u6dfb\u52a0\u4e0b\u9762\u7684\u4fe1\u606f\u6765\u914d\u7f6e NFS StorageClass\u3002 apiVersion: storage.k8s.io/v1 kind: StorageClass metadata: name: nfs-client annotations: storageclass.kubernetes.io/is-default-class: \"true\" provisioner: k8s-sigs.io/nfs-subdir-external-provisioner parameters: pathPattern: \" ${ .PVC.namespace } / ${ .PVC.annotations.nfs.io/storage-path } \" onDelete: delete \u5e94\u7528\u4e0a\u9762\u7684yaml\u6587\u4ef6\uff0c\u4f7f\u4e4b\u751f\u6548\u3002 kubectl apply -f nfs-storageclass.yaml","title":"\u521b\u5efa NFS StorageClass"},{"location":"k8s/cka_cn/foundamentals/persistence/#pvc_2","text":"\u521b\u5efa PVC nfs-pvc-from-sc \u3002 kubectl apply -f - < mysql-with-sc-pvc-7c97d875f8-wkvr9 1/1 Running 0 3m37s 10.244.102.27 cka003 \u6211\u4eec\u73b0\u5728\u6765\u67e5\u770b NFS \u670d\u52a1\u5668 cka002 \u4e0a\u7684\u5171\u4eab\u76ee\u5f55 /nfsdata/ \u3002 ll /nfsdata/ NFS \u670d\u52a1\u5668 cka002 \u4e0a\u7684\u5171\u4eab\u76ee\u5f55 /nfsdata/ \u4e0b\u6709\u4e862\u4e2a\u5b50\u76ee\u5f55\uff0c\u4e0e\u5176\u4ed62\u4e2a\u8282\u70b9\u4e0a\u7684\u76ee\u5f55 /remote-nfs-dir/ \u4e0b\u7684\u5185\u5bb9\u662f\u4e00\u81f4\u3002 drwxrwxrwx 6 systemd-coredump root 4096 Jul 23 23 :35 dev/ drwxr-xr-x 6 systemd-coredump root 4096 Jul 23 22 :29 mysqldata/ \u547d\u540d\u7a7a\u95f4Namespace\u7684\u540d\u79f0\u4f5c\u4e3a\u76ee\u5f55\u540d\u5728 /nfsdata/ \u76ee\u5f55\u4e0b\u7528\u4e8e\u6302\u8f7d\u5230 Pod \u4e2d\u3002 \u9ed8\u8ba4\u60c5\u51b5\u4e0b\uff0c\u547d\u540d\u7a7a\u95f4Namespace\u540d\u79f0\u5c06\u7528\u4e8e\u6302\u8f7d\u70b9\u3002 \u5982\u679c\u6211\u4eec\u60f3\u8981\u4f7f\u7528\u81ea\u5b9a\u4e49\u7684\u6587\u4ef6\u5939\u6765\u4ee3\u66ff\uff0c\u6211\u4eec\u9700\u8981\u58f0\u660e\u4e00\u4e2a nfs.io/storage-path \u6ce8\u91ca\uff0c\u4f8b\u5982\u4e0b\u9762\u7684\u4f8b\u5b50\u3002 \u5728\u547d\u540d\u7a7a\u95f4 kube-system \u4e0a\u521b\u5efa PVC test-claim \uff0c\u5e76\u6d88\u8d39 nfs-client \u5377\u3002 kubectl apply -f - < ..data/password lrwxrwxrwx 1 root root 15 Jul 23 16 :30 username -> ..data/username \u800c\u4e14\u6211\u4eec\u53ef\u4ee5\u770b\u5230\u8fd92\u4e2a\u6570\u636e\u5143\u7d20\uff08 username \u548c password \uff09\u7684\u5185\u5bb9\u5c31\u662f\u6211\u4eec\u9884\u5148\u5b9a\u4e49\u7684\u3002 / # cat /tmp/secret/username admin / # cat /tmp/secret/password 123456","title":"Secret"},{"location":"k8s/cka_cn/foundamentals/persistence/#_2","text":"","title":"\u62d3\u5c55\u6848\u4f8b"},{"location":"k8s/cka_cn/foundamentals/persistence/#configmap_1","text":"\u6211\u4eec\u53ef\u4ee5\u901a\u8fc7\u6587\u4ef6\u3001\u76ee\u5f55\u3001\u6216\u8005\u503c\u6765\u521b\u5efaConfigMap\u3002 \u4e0b\u9762\u6211\u4eec\u521b\u5efaConfigMap colors \uff0c\u5305\u542b\uff1a \u56db\u4e2a\u6587\u4ef6\uff0c\u6587\u4ef6\u540d\u662f\u56db\u4e2a\u989c\u8272\u3002 \u4e00\u4e2a\u6587\u4ef6\uff0c\u6587\u4ef6\u540d\u662f\u6700\u559c\u6b22\u7684\u989c\u8272\u3002 mkdir configmap cd configmap mkdir primary echo c > primary/cyan echo m > primary/magenta echo y > primary/yellow echo k > primary/black echo \"known as key\" >> primary/black echo blue > favorite \u6267\u884c\u547d\u4ee4 tree configmap \uff0c\u53ef\u4ee5\u770b\u5230\u7c7b\u4f3c\u4e0b\u9762\u7684\u6587\u4ef6\u76ee\u5f55\u7ed3\u6784\u3002 configmap \u251c\u2500\u2500 favorite \u2514\u2500\u2500 primary \u251c\u2500\u2500 black \u251c\u2500\u2500 cyan \u251c\u2500\u2500 magenta \u2514\u2500\u2500 yellow \u521b\u5efa\u4e00\u4e2a ConfigMap\uff0c\u5f15\u7528\u4e0a\u9762\u6211\u4eec\u521b\u5efa\u7684\u6587\u4ef6\u3002\u786e\u4fdd\u6211\u4eec\u73b0\u5728\u5728\u8def\u5f84 ~/configmap \u4e0b\u3002 kubectl create configmap colors \\ --from-literal = text = black \\ --from-file = ./favorite \\ --from-file = ./primary/ \u67e5\u770bConfigMap colors \u7684\u5185\u5bb9\u3002 kubectl get configmap colors -o yaml \u8fd0\u884c\u7ed3\u679c\uff1a apiVersion: v1 data: black: | k known as key cyan: | c favorite: | blue magenta: | m text: black yellow: | y kind: ConfigMap metadata: creationTimestamp: \"2022-07-12T16:38:27Z\" name: colors namespace: dev resourceVersion: \"2377258\" uid: d5ab133f-5e4d-41d4-bc9e-2bbb22a872a1","title":"\u591a\u79cd\u65b9\u6cd5\u521b\u5efaConfigMap"},{"location":"k8s/cka_cn/foundamentals/persistence/#configmap_2","text":"\u7ee7\u7eed\u4e0a\u9762\u7684\u4f8b\u5b50\uff0c\u73b0\u5728\u6211\u4eec\u51c6\u5907\u521b\u5efa\u4e00\u4e2a\u540d\u4e3a pod-configmap-env \u7684Pod\uff0c\u8bbe\u7f6e\u73af\u5883\u53d8\u91cf ilike \u5e76\u4eceConfigMap colors \u4e2d\u5206\u914d\u503c favorite \u3002 kubectl apply -f - << EOF apiVersion: v1 kind: Pod metadata: name: pod-configmap-env spec: containers: - name: nginx image: nginx env: - name: ilike valueFrom: configMapKeyRef: name: colors key: favorite EOF \u8fde\u63a5\u5e76\u8fdb\u5165Pod pod-configmap-env \u5185\u90e8\u3002 kubectl exec -it pod-configmap-env -- bash \u9a8c\u8bc1\u73af\u5883\u53d8\u91cf ilike \u7684\u503c\u662f blue \uff0c\u8fd9\u662f ConfigMap colors \u7684 favorite \u503c\u3002 root@pod-configmap-env:/# echo $ilike blue \u6211\u4eec\u8fd8\u53ef\u4ee5\u4f7f\u7528 ConfigMap \u7684\u6240\u6709\u952e\u503c\u5bf9\u6765\u8bbe\u7f6e Pod \u7684\u73af\u5883\u53d8\u91cf\u3002 kubectl apply -f - << EOF apiVersion: v1 kind: Pod metadata: name: pod-configmap-env-2 spec: containers: - name: nginx image: nginx envFrom: - configMapRef: name: colors EOF \u8fde\u63a5\u5e76\u8fdb\u5165Pod pod-configmap-env-2 \u5185\u90e8\u3002 kubectl exec -it pod-configmap-env-2 -- bash \u9a8c\u8bc1\u73af\u5883\u53d8\u91cf\u7684\u503c\u662f\u6211\u4eec\u5728ConfigMap colors \u6240\u5b9a\u4e49\u7684\u952e\u503c\u5bf9\u3002 root@pod-configmap-env-2:/# echo $black k known as key root@pod-configmap-env-2:/# echo $cyan c root@pod-configmap-env-2:/# echo $favorite blue","title":"\u901a\u8fc7ConfigMap\u8bbe\u5b9a\u73af\u5883\u53d8\u91cf"},{"location":"k8s/cka_cn/foundamentals/pod/","text":"CKA\u81ea\u5b66\u7b14\u8bb08:Pod \u00b6 \u6458\u8981 \u00b6 \u7ec3\u4e60\u76ee\u6807\uff1a \u521b\u5efapod \u8ffd\u8e2apod pod\u6807\u7b7e \u9759\u6001pod \u591a\u5bb9\u5668pod \u542b\u521d\u59cb\u5316\u5bb9\u5668\u7684pod \u521b\u5efaPod \u00b6 \u521b\u5efaPod my-first-podl \u3002 kubectl apply -f - << EOF apiVersion: v1 kind: Pod metadata: name: my-first-pod spec: containers: - name: nginx image: nginx:mainline ports: - containerPort: 80 EOF \u9a8c\u8bc1\u521a\u521a\u521b\u5efa\u7684pod\u7684\u72b6\u6001\u3002 kubectl get pods -o wide \u8ffd\u8e2apod \u00b6 \u68c0\u67e5\u521a\u521a\u521b\u5efa\u7684pod\u7684\u65e5\u5fd7\u3002 kubectl logs my-first-pod \u5982\u679c\u65e5\u5fd7\u6216\u8005\u5176\u4ed6\u547d\u4ee4\u8f93\u51fa\u7684\u4fe1\u606f\u4e0d\u8db3\u4ee5\u5e2e\u52a9\u6211\u4eec\u67e5\u627e\u6839\u672c\u539f\u56e0\uff0c\u6211\u4eec\u53ef\u4ee5\u901a\u8fc7 kubectl exec -it -- bash \u6765\u8fdb\u5165pod\u5185\u90e8\u8fdb\u884c\u5206\u6790\u3002 kubectl exec -it my-first-pod -- bash root@my-first-pod:/# ls root@my-first-pod:/# cd bin root@my-first-pod:/bin# ls root@my-first-pod:/bin# exit \u6267\u884c\u547d\u4ee4 kubectl explain pod.spec \u53ef\u4ee5\u5f97\u5230pod\u5bf9\u5e94\u7684yaml\u6587\u4ef6\u4e2dSpec\u533a\u6bb5\u7684\u5185\u5bb9\u3002 \u6211\u4eec\u53ef\u4ee5\u67e5\u770b Pod \u8d44\u6e90\u7684\u5b98\u65b9 API \u53c2\u8003\u6587\u6863\uff0c\u6216\u8005\u4f7f\u7528 kubectl explain pod \u547d\u4ee4\u884c\u83b7\u53d6\u8be5\u8d44\u6e90\u7684\u63cf\u8ff0\u4fe1\u606f\u3002\u901a\u8fc7\u5728\u8d44\u6e90\u7c7b\u578b\u540e\u6dfb\u52a0 . \uff0cexplain \u547d\u4ee4\u4f1a\u63d0\u4f9b\u8be5\u6307\u5b9a\u5b57\u6bb5\u7684\u66f4\u591a\u8be6\u7ec6\u4fe1\u606f\u3002 kubectl explain pod.kind kubectl explain pod.spec kubectl explain pod.spec.containers kubectl explain pod.spec.containers.name pod\u7684\u6807\u7b7e \u00b6 \u901a\u8fc7\u9009\u9879 --show-labels \u6765\u83b7\u5f97pod\u7684\u6807\u7b7e\u3002 kubectl get pods kubectl get pods --show-labels \u7ed9pod pod my-first-pod \u6dfb\u52a02\u4e2a\u6807\u7b7e\u3002 kubectl label pod my-first-pod nginx = mainline kubectl label pod my-first-pod env = demo kubectl get pods --show-labels \u901a\u8fc7\u6807\u7b7e\u6765\u67e5\u627epod\u3002 kubectl get pod -l env = demo kubectl get pod -l env = demo,nginx = mainline kubectl get pod -l env = training \u79fb\u9664pod\u7684\u6807\u7b7e\u3002 kubectl label pods my-first-pod env- kubectl get pods --show-labels \u63cf\u8ff0 Pod\u3002 kubectl describe pod my-first-pod \u5220\u9664pod. \u8fd0\u884c\u547d\u4ee4 watch kubectl get pods \u6765\u83b7\u53d6pod\u7684\u72b6\u6001\u3002 kubectl delete pod my-first-pod watch kubectl get pods \u9759\u6001pod \u00b6 \u6f14\u793a\u573a\u666f\uff1a \u521b\u5efa\u4e00\u4e2a\u9759\u6001pod\u3002 kubectl \u4f1a\u81ea\u52a8\u68c0\u67e5 /etc/kubernetes/manifests/ \u4e2d\u7684 YAML \u6587\u4ef6\uff0c\u5e76\u5728\u68c0\u6d4b\u5230\u540e\u521b\u5efa\u9759\u6001 Pod\u3002 \u6f14\u793a\uff1a \u67e5\u770b\u7cfb\u7edf\u521d\u59cb\u5316\u540e\u5df2\u7ecf\u5b58\u5728\u7684\u9759\u6001pod\u3002 ll /etc/kubernetes/manifests/ \u8fd0\u884c\u7ed3\u679c\uff1a -rw------- 1 root root 2292 Jul 23 10:45 etcd.yaml -rw------- 1 root root 3889 Jul 23 10:45 kube-apiserver.yaml -rw------- 1 root root 3395 Jul 23 10:45 kube-controller-manager.yaml -rw------- 1 root root 1464 Jul 23 10:45 kube-scheduler.yaml \u5728 /etc/kubernetes/manifests/ \u76ee\u5f55\u4e2d\u521b\u5efayaml\u6587\u4ef6 my-nginx.yaml \uff0c\u4e00\u65e6\u6587\u4ef6\u521b\u5efa\u5b8c\u6210\uff0c\u9759\u6001Pod my-nginx \u5c06\u4f1a\u88ab\u81ea\u52a8\u521b\u5efa\u3002 kubectl run my-nginx --image = nginx:mainline --dry-run = client -n default -oyaml | sudo tee /etc/kubernetes/manifests/my-nginx.yaml \u68c0\u67e5 Pod my-nginx \u7684\u72b6\u6001\u3002Pod \u540d\u79f0\u4e2d\u5305\u542b\u8282\u70b9\u540d\u79f0 cka001 \uff0c\u8fd9\u610f\u5473\u7740\u8be5 Pod \u6b63\u5728\u8282\u70b9 cka001 \u4e0a\u8fd0\u884c\u3002 kubectl get pod -o wide \u8fd0\u884c\u7ed3\u679c\uff1a NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES my-nginx-cka001 1/1 Running 0 20s 10.244.228.196 cka001 \u5220\u9664 /etc/kubernetes/manifests/my-nginx.yaml \u8fd9\u4e2a yaml \u6587\u4ef6\uff0c\u5bf9\u5e94\u7684\u9759\u6001 Pod my-nginx \u5c06\u4f1a\u88ab\u81ea\u52a8\u5220\u9664\u3002 sudo rm /etc/kubernetes/manifests/my-nginx.yaml \u591a\u5bb9\u5668Pod \u00b6 \u6f14\u793a\u573a\u666f\uff1a \u521b\u5efa\u591a\u5bb9\u5668Pod \u63cf\u8ff0\u8be5Pod \u68c0\u67e5Pod\u7684\u65e5\u5fd7 \u68c0\u67e5\u5bb9\u5668\u7684\u65e5\u5fd7 \u6f14\u793a\uff1a \u521b\u5efa\u4e00\u4e2a\u540d\u4e3a multi-container-pod \u7684Pod\uff0c\u5305\u542b\u591a\u4e2a\u5bb9\u5668\uff1a container-1-nginx \u548c container-2-alpine \u3002 kubectl apply -f - << EOF apiVersion : v1 kind : Pod metadata : name : multi-container-pod spec : containers : - name : container-1-nginx image : nginx ports : - containerPort : 80 - name : container-2-alpine image : alpine command : [ \"watch\" , \"wget\" , \"-qO-\" , \"localhost\" ] EOF \u83b7\u53d6pod\u72b6\u6001\u3002 kubectl get pod multi-container-pod \u8fd0\u884c\u7ed3\u679c \u83b7\u53d6pod\u7684\u8be6\u7ec6\u4fe1\u606f\u3002 kubectl describe pod multi-container-pod \u8fd0\u884c\u7ed3\u679c\uff1a ....... Events: Type Reason Age From Message ---- ------ ---- ---- ------- Normal Scheduled 41s default-scheduler Successfully assigned dev/multi-container-pod to cka002 Normal Pulling 40s kubelet Pulling image \"nginx\" Normal Pulled 23s kubelet Successfully pulled image \"nginx\" in 16.767129903s Normal Created 22s kubelet Created container container-1-nginx Normal Started 22s kubelet Started container container-1-nginx Normal Pulling 22s kubelet Pulling image \"alpine\" Normal Pulled 14s kubelet Successfully pulled image \"alpine\" in 7.776104353s Normal Created 14s kubelet Created container container-2-alpine Normal Started 14s kubelet Started container container-2-alpine \u5bf9\u4e8e\u591a\u5bb9\u5668 Pod\uff0c\u5982\u679c\u6211\u4eec\u60f3\u901a\u8fc7\u547d\u4ee4 kubectl logs \u83b7\u53d6 Pod \u7684\u65e5\u5fd7\uff0c\u9700\u8981\u6307\u5b9a\u5bb9\u5668\u540d\u79f0\u3002\u5982\u679c\u4e0d\u6307\u5b9a\u5bb9\u5668\u540d\u79f0\uff0c\u5c06\u4f1a\u6536\u5230\u9519\u8bef\u4fe1\u606f\u3002 kubectl logs multi-container-pod \u8fd0\u884c\u7ed3\u679c error: a container name must be specified for pod multi-container-pod, choose one of: [ container-1-nginx container-2-alpine ] \u6307\u5b9a\u5bb9\u5668\u540d\u79f0\uff0c\u6211\u4eec\u53ef\u4ee5\u5f97\u5230\u5bf9\u5e94\u7684\u65e5\u5fd7\u4fe1\u606f\u3002 kubectl logs multi-container-pod container-1-nginx \u8fd0\u884c\u7ed3\u679c ...... ::1 - - [ 23 /Jul/2022:04:06:37 +0000 ] \"GET / HTTP/1.1\" 200 615 \"-\" \"Wget\" \"-\" \u5982\u679c\u6211\u4eec\u9700\u8981\u4f7f\u7528\u547d\u4ee4 kubectl exec -it -c -- \u767b\u5f55\u5230 Pod \u4e2d\uff0c\u540c\u6837\u9700\u8981\u6307\u5b9a\u5bb9\u5668\u540d\u79f0\u3002\u5982\u679c\u6ca1\u6709\u6307\u5b9a\u5bb9\u5668\u540d\u79f0\uff0c\u4f1a\u51fa\u73b0\u9519\u8bef\u3002 kubectl exec -it multi-container-pod -c container-1-nginx -- /bin/bash root@multi-container-pod:/# ls \u5220\u9664\u4e0a\u9762\u7ec3\u4e60\u4e2d\u521b\u5efa\u7684pod\u3002 kubectl delete pod multi-container-pod \u4e0b\u9762\u662f\u4e00\u4e2a\u57fa\u672c\u7684yaml\u6587\u4ef6\u7528\u6765\u521b\u5efa\u591a\u5bb9\u5668pod\u3002 kubectl apply -f - << EOF apiVersion : v1 kind : Pod metadata : name : my-multi-pod spec : containers : - image : nginx name : nginx - image : memcached name : memcached - image : redis name : redis EOF \u6f14\u793a\u573a\u666f\uff1a \u521b\u5efa\u4e00\u4e2a\u540d\u4e3a my-busybox \u7684Pod\uff0c\u5e76\u5728\u5176\u4e2d\u6dfb\u52a0\u4e00\u4e2a\u540d\u4e3a container-1-busybox \u7684\u5bb9\u5668\u3002\u8be5\u5bb9\u5668\u5c06\u628a\u6d88\u606f\u5199\u5165\u5230\u6587\u4ef6 /var/log/my-pod-busybox.log \u4e2d\u3002 \u5411Pod my-busybox \u4e2d\u6dfb\u52a0\u53e6\u4e00\u4e2a\u5bb9\u5668 container-2-busybox \uff08Sidecar\uff09\u3002Sidecar\u5bb9\u5668\u4ece\u6587\u4ef6 /var/log/my-pod-busybox.log \u4e2d\u8bfb\u53d6\u6d88\u606f\u3002 \u63d0\u793a\uff1a\u521b\u5efa\u4e00\u4e2aVolume\u6765\u5b58\u50a8\u65e5\u5fd7\u6587\u4ef6\uff0c\u5e76\u4e0e\u4e24\u4e2a\u5bb9\u5668\u5171\u4eab\u3002 \u6f14\u793a\uff1a \u521b\u5efa\u4e00\u4e2a\u540d\u4e3a my-busybox \u7684 Pod\uff0c\u5176\u4e2d\u5305\u542b\u4e00\u4e2a\u5bb9\u5668 container-1-busybox \u3002 kubectl apply -f - << EOF apiVersion: v1 kind: Pod metadata: name: my-busybox spec: containers: - name: container-1-busybox image: busybox args: - /bin/sh - -c - > i=0; while true; do echo \"Hello message from container-1: $i\" >> /var/log/my-pod-busybox.log; i=$((i+1)); sleep 1; done EOF \u5728 Kubernetes \u6587\u6863\u4e2d\u641c\u7d22 emptyDir \u3002 \u53c2\u8003\u4ee5\u4e0b\u6a21\u677f\u7528\u4e8e emptyDir \uff1a https://kubernetes.io/zh-cn/docs/concepts/storage/volumes/ \u5c06\u4ee5\u4e0b\u65b0\u529f\u80fd\u6dfb\u52a0\u5230 Pod \u4e2d\uff1a Volume\uff1a \u5377\u540d\u79f0\uff1a logfile \u7c7b\u578b\uff1a emptyDir \u66f4\u65b0\u73b0\u6709\u5bb9\u5668\uff1a name: container-1-busybox volumeMounts name: logfile mounthPath: /var/log \u6dfb\u52a0\u65b0\u5bb9\u5668\uff1a name: container-2-busybox image: busybox args: ['/bin/sh', '-c', 'tail -n+1 -f /var/log/my-pod-busybox.log'] volumeMounts: name: logfile mountPath: /var/log kubectl get pod my-busybox -o yaml > my-busybox.yaml vi my-busybox.yaml kubectl delete pod my-busybox kubectl apply -f my-busybox.yaml kubectl logs my-busybox -c container-2-busybox \u66f4\u65b0\u540e\u7684\u6587\u4ef6 my-busybox.yaml \u5982\u4e0b\uff1a apiVersion : v1 kind : Pod metadata : annotations : cni.projectcalico.org/containerID : 89644b6b073cd152f94b4cae7bdea6bbc3292cf59afd4f28102bd74f0205c9e4 cni.projectcalico.org/podIP : 10.244.102.20/32 cni.projectcalico.org/podIPs : 10.244.102.20/32 kubectl.kubernetes.io/last-applied-configuration : | {\"apiVersion\":\"v1\",\"kind\":\"Pod\",\"metadata\":{\"annotations\":{},\"name\":\"my-busybox\",\"namespace\":\"dev\"},\"spec\":{\"containers\":[{\"args\":[\"/bin/sh\",\"-c\",\"i=0; while true; do\\n echo \\\"Hello message from container-1: \\\" \\u003e\\u003e /var/log/my-pod-busybox.log;\\n i=1;\\n sleep 1;\\ndone\\n\"],\"image\":\"busybox\",\"name\":\"container-1-busybox\"}]}} creationTimestamp : \"2022-07-29T22:58:27Z\" name : my-busybox namespace : dev resourceVersion : \"1185720\" uid : c5e62a16-4459-4828-a441-7d1471b89a56 spec : containers : - name : container-2-busybox image : busybox args : [ '/bin/sh' , '-c' , 'tail -n+1 -f /var/log/my-pod-busybox.log' ] volumeMounts : - name : logfile mountPath : /var/log - args : - /bin/sh - -c - | i=0; while true; do echo \"Hello message from container-1: $i\" >> /var/log/my-pod-busybox.log; i=1; sleep 1; done image : busybox imagePullPolicy : Always name : container-1-busybox resources : {} terminationMessagePath : /dev/termination-log terminationMessagePolicy : File volumeMounts : - name : logfile mountPath : /var/log - mountPath : /var/run/secrets/kubernetes.io/serviceaccount name : kube-api-access-mhxlf readOnly : true dnsPolicy : ClusterFirst enableServiceLinks : true nodeName : cka003 preemptionPolicy : PreemptLowerPriority priority : 0 restartPolicy : Always schedulerName : default-scheduler securityContext : {} serviceAccount : default serviceAccountName : default terminationGracePeriodSeconds : 30 tolerations : - effect : NoExecute key : node.kubernetes.io/not-ready operator : Exists tolerationSeconds : 300 - effect : NoExecute key : node.kubernetes.io/unreachable operator : Exists tolerationSeconds : 300 volumes : - name : logfile emptyDir : {} - name : kube-api-access-mhxlf projected : defaultMode : 420 sources : - serviceAccountToken : expirationSeconds : 3607 path : token - configMap : items : - key : ca.crt path : ca.crt name : kube-root-ca.crt - downwardAPI : items : - fieldRef : apiVersion : v1 fieldPath : metadata.namespace path : namespace status : conditions : - lastProbeTime : null lastTransitionTime : \"2022-07-29T22:58:27Z\" status : \"True\" type : Initialized - lastProbeTime : null lastTransitionTime : \"2022-07-29T22:58:30Z\" status : \"True\" type : Ready - lastProbeTime : null lastTransitionTime : \"2022-07-29T22:58:30Z\" status : \"True\" type : ContainersReady - lastProbeTime : null lastTransitionTime : \"2022-07-29T22:58:27Z\" status : \"True\" type : PodScheduled containerStatuses : - containerID : containerd://fd42d4ba4d94d8918d8846327b1db2328be13c5f93f381877ff0228ed7b5468d image : docker.io/library/busybox:latest imageID : docker.io/library/busybox@sha256:0e97a8ca6955f22dbc7db9e9dbe970971f423541e52c34b8cb96ccc88d6a3883 lastState : {} name : container-1-busybox ready : true restartCount : 0 started : true state : running : startedAt : \"2022-07-29T22:58:30Z\" hostIP : phase : Running podIP : 10.244.102.20 podIPs : - ip : 10.244.102.20 qosClass : BestEffort startTime : \"2022-07-29T22:58:27Z\" \u6e05\u7406\u4e0a\u9762\u7ec3\u4e60\u4e2d\u521b\u5efa\u7684pod\u3002 kubectl delete pod my-busybox \u542b\u521d\u59cb\u5316\u5bb9\u5668Pod \u00b6 \u6f14\u793a\u573a\u666f\uff1a \u521b\u5efa\u62e5\u6709\u4e24\u4e2a\u521d\u59cb\u5316\u5bb9\u5668\u7684 Pod myapp-pod \u3002 myapp-container init-mydb \u521b\u5efa\u4e24\u4e2a\u670d\u52a1\uff1a myservice mydb \u6f14\u793a\u9884\u671f\u7ed3\u8bba\uff1a myapp-container \u7b49\u5f85\u670d\u52a1 myservice \u542f\u52a8\uff0c\u4ee5\u89e3\u6790\u540d\u79f0 myservice.dev.svc.cluster.local init-mydb \u7b49\u5f85\u670d\u52a1 mydb \u542f\u52a8\uff0c\u4ee5\u89e3\u6790\u540d\u79f0 mydb.dev.svc.cluster.local \u3002 \u6f14\u793a\uff1a \u521b\u5efa\u540d\u4e3a myapp-pod.yaml \u7684yaml\u6587\u4ef6\uff0c\u5e76\u6dfb\u52a0\u4ee5\u4e0b\u5185\u5bb9\u3002 \u6ce8\u610f\uff1a\u7531\u4e8e\u547d\u4ee4 $(cat /var/..... \u5c06\u88ab\u89c6\u4e3a\u4e3b\u673a\u53d8\u91cf\uff0c\u56e0\u6b64\u6211\u4eec\u4e0d\u80fd\u4f7f\u7528echo\u751f\u6210\u8be5\u6587\u4ef6\u3002\u5b83\u662f\u5bb9\u5668\u672c\u8eab\u7684\u53d8\u91cf\u3002 vi myapp-pod.yaml \u6587\u4ef6\u5185\u5bb9 apiVersion : v1 kind : Pod metadata : name : myapp-pod labels : app : myapp spec : containers : - name : myapp-container image : busybox:1.28 command : [ 'sh' , '-c' , 'echo The app is running! && sleep 3600' ] initContainers : - name : init-myservice image : busybox:1.28 command : [ 'sh' , '-c' , \"until nslookup myservice.$(cat /var/run/secrets/kubernetes.io/serviceaccount/namespace).svc.cluster.local; do echo waiting for myservice; sleep 2; done\" ] - name : init-mydb image : busybox:1.28 command : [ 'sh' , '-c' , \"until nslookup mydb.$(cat /var/run/secrets/kubernetes.io/serviceaccount/namespace).svc.cluster.local; do echo waiting for mydb; sleep 2; done\" ] \u7528\u4e0a\u9762\u521b\u5efa\u7684yaml\u6587\u4ef6\u521b\u5efaPod myapp-pod \u3002 kubectl apply -f myapp-pod.yaml \u68c0\u67e5pod\u7684\u72b6\u6001\u3002 kubectl get pod myapp-pod \u8fd0\u884c\u7ed3\u679c\uff1a NAME READY STATUS RESTARTS AGE myapp-pod 0/1 Init:0/2 0 12m \u68c0\u67e5Pod\uff0c\u53ef\u4ee5\u770b\u5230\u4e24\u4e2a\u9519\u8bef\uff1a nslookup: \u65e0\u6cd5\u89e3\u6790'myservice.dev.svc.cluster.local' Pod \"myapp-pod\"\u4e2d\u7684\u5bb9\u5668\u201cinit-mydb\u201d\u6b63\u5728\u7b49\u5f85\u542f\u52a8\uff1aPodInitializing kubectl logs myapp-pod -c init-myservice # Inspect the first init container kubectl logs myapp-pod -c init-mydb # Inspect the second init container \u5728\u8fd9\u4e2a\u65f6\u5019\uff0c\u8fd9\u4e9b init \u5bb9\u5668\u5c06\u7b49\u5f85\u53d1\u73b0\u540d\u4e3a mydb \u548c myservice \u7684\u670d\u52a1\u3002 \u521b\u5efa mydb \u548c myservice \u670d\u52a1\uff1a kubectl apply -f - << EOF apiVersion: v1 kind: Service metadata: name: myservice spec: ports: - protocol: TCP port: 80 targetPort: 9376 --- apiVersion: v1 kind: Service metadata: name: mydb spec: ports: - protocol: TCP port: 80 targetPort: 9377 EOF \u67e5\u770b\u521b\u5efa\u7684\u670d\u52a1\u7684\u72b6\u6001\u3002 kubectl get service \u521b\u5efa\u76842\u4e2a\u670d\u52a1\u90fd\u662f\u8fd0\u884c\u72b6\u6001\u3002 NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE mydb ClusterIP 11.244.239.149 80/TCP 6s myservice ClusterIP 11.244.116.126 80/TCP 6s \u518d\u6b21\u67e5\u770bpod\u7684\u72b6\u6001\u3002 kubectl get pod myapp-pod -o wide pod\u5df2\u7ecf\u6b63\u5e38\u8fd0\u884c\u4e86\u3002 NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES myapp-pod 0/1 Init:0/2 0 2m40s 10.244.112.2 cka002 \u73b0\u5728\u6211\u4eec\u53ef\u4ee5\u770b\u5230\u90a3\u4e9b\u521d\u59cb\u5316\u5bb9\u5668\u90fd\u5df2\u7ecf\u5b8c\u6210\uff0c myapp-pod Pod \u8fdb\u5165\u4e86 Running \u72b6\u6001\u3002 \u5220\u9664\u4e0a\u9762\u7ec3\u4e60\u4e2d\u521b\u5efa\u7684pod\u3002 kubectl delete service mydb myservice kubectl delete pod myapp-pod \u53c2\u8003\uff1a Pod basics Lifecycle & phases Kubernetes pod design pattern","title":"Pod"},{"location":"k8s/cka_cn/foundamentals/pod/#cka8pod","text":"","title":"CKA\u81ea\u5b66\u7b14\u8bb08:Pod"},{"location":"k8s/cka_cn/foundamentals/pod/#_1","text":"\u7ec3\u4e60\u76ee\u6807\uff1a \u521b\u5efapod \u8ffd\u8e2apod pod\u6807\u7b7e \u9759\u6001pod \u591a\u5bb9\u5668pod \u542b\u521d\u59cb\u5316\u5bb9\u5668\u7684pod","title":"\u6458\u8981"},{"location":"k8s/cka_cn/foundamentals/pod/#pod","text":"\u521b\u5efaPod my-first-podl \u3002 kubectl apply -f - << EOF apiVersion: v1 kind: Pod metadata: name: my-first-pod spec: containers: - name: nginx image: nginx:mainline ports: - containerPort: 80 EOF \u9a8c\u8bc1\u521a\u521a\u521b\u5efa\u7684pod\u7684\u72b6\u6001\u3002 kubectl get pods -o wide","title":"\u521b\u5efaPod"},{"location":"k8s/cka_cn/foundamentals/pod/#pod_1","text":"\u68c0\u67e5\u521a\u521a\u521b\u5efa\u7684pod\u7684\u65e5\u5fd7\u3002 kubectl logs my-first-pod \u5982\u679c\u65e5\u5fd7\u6216\u8005\u5176\u4ed6\u547d\u4ee4\u8f93\u51fa\u7684\u4fe1\u606f\u4e0d\u8db3\u4ee5\u5e2e\u52a9\u6211\u4eec\u67e5\u627e\u6839\u672c\u539f\u56e0\uff0c\u6211\u4eec\u53ef\u4ee5\u901a\u8fc7 kubectl exec -it -- bash \u6765\u8fdb\u5165pod\u5185\u90e8\u8fdb\u884c\u5206\u6790\u3002 kubectl exec -it my-first-pod -- bash root@my-first-pod:/# ls root@my-first-pod:/# cd bin root@my-first-pod:/bin# ls root@my-first-pod:/bin# exit \u6267\u884c\u547d\u4ee4 kubectl explain pod.spec \u53ef\u4ee5\u5f97\u5230pod\u5bf9\u5e94\u7684yaml\u6587\u4ef6\u4e2dSpec\u533a\u6bb5\u7684\u5185\u5bb9\u3002 \u6211\u4eec\u53ef\u4ee5\u67e5\u770b Pod \u8d44\u6e90\u7684\u5b98\u65b9 API \u53c2\u8003\u6587\u6863\uff0c\u6216\u8005\u4f7f\u7528 kubectl explain pod \u547d\u4ee4\u884c\u83b7\u53d6\u8be5\u8d44\u6e90\u7684\u63cf\u8ff0\u4fe1\u606f\u3002\u901a\u8fc7\u5728\u8d44\u6e90\u7c7b\u578b\u540e\u6dfb\u52a0 . \uff0cexplain \u547d\u4ee4\u4f1a\u63d0\u4f9b\u8be5\u6307\u5b9a\u5b57\u6bb5\u7684\u66f4\u591a\u8be6\u7ec6\u4fe1\u606f\u3002 kubectl explain pod.kind kubectl explain pod.spec kubectl explain pod.spec.containers kubectl explain pod.spec.containers.name","title":"\u8ffd\u8e2apod"},{"location":"k8s/cka_cn/foundamentals/pod/#pod_2","text":"\u901a\u8fc7\u9009\u9879 --show-labels \u6765\u83b7\u5f97pod\u7684\u6807\u7b7e\u3002 kubectl get pods kubectl get pods --show-labels \u7ed9pod pod my-first-pod \u6dfb\u52a02\u4e2a\u6807\u7b7e\u3002 kubectl label pod my-first-pod nginx = mainline kubectl label pod my-first-pod env = demo kubectl get pods --show-labels \u901a\u8fc7\u6807\u7b7e\u6765\u67e5\u627epod\u3002 kubectl get pod -l env = demo kubectl get pod -l env = demo,nginx = mainline kubectl get pod -l env = training \u79fb\u9664pod\u7684\u6807\u7b7e\u3002 kubectl label pods my-first-pod env- kubectl get pods --show-labels \u63cf\u8ff0 Pod\u3002 kubectl describe pod my-first-pod \u5220\u9664pod. \u8fd0\u884c\u547d\u4ee4 watch kubectl get pods \u6765\u83b7\u53d6pod\u7684\u72b6\u6001\u3002 kubectl delete pod my-first-pod watch kubectl get pods","title":"pod\u7684\u6807\u7b7e"},{"location":"k8s/cka_cn/foundamentals/pod/#pod_3","text":"\u6f14\u793a\u573a\u666f\uff1a \u521b\u5efa\u4e00\u4e2a\u9759\u6001pod\u3002 kubectl \u4f1a\u81ea\u52a8\u68c0\u67e5 /etc/kubernetes/manifests/ \u4e2d\u7684 YAML \u6587\u4ef6\uff0c\u5e76\u5728\u68c0\u6d4b\u5230\u540e\u521b\u5efa\u9759\u6001 Pod\u3002 \u6f14\u793a\uff1a \u67e5\u770b\u7cfb\u7edf\u521d\u59cb\u5316\u540e\u5df2\u7ecf\u5b58\u5728\u7684\u9759\u6001pod\u3002 ll /etc/kubernetes/manifests/ \u8fd0\u884c\u7ed3\u679c\uff1a -rw------- 1 root root 2292 Jul 23 10:45 etcd.yaml -rw------- 1 root root 3889 Jul 23 10:45 kube-apiserver.yaml -rw------- 1 root root 3395 Jul 23 10:45 kube-controller-manager.yaml -rw------- 1 root root 1464 Jul 23 10:45 kube-scheduler.yaml \u5728 /etc/kubernetes/manifests/ \u76ee\u5f55\u4e2d\u521b\u5efayaml\u6587\u4ef6 my-nginx.yaml \uff0c\u4e00\u65e6\u6587\u4ef6\u521b\u5efa\u5b8c\u6210\uff0c\u9759\u6001Pod my-nginx \u5c06\u4f1a\u88ab\u81ea\u52a8\u521b\u5efa\u3002 kubectl run my-nginx --image = nginx:mainline --dry-run = client -n default -oyaml | sudo tee /etc/kubernetes/manifests/my-nginx.yaml \u68c0\u67e5 Pod my-nginx \u7684\u72b6\u6001\u3002Pod \u540d\u79f0\u4e2d\u5305\u542b\u8282\u70b9\u540d\u79f0 cka001 \uff0c\u8fd9\u610f\u5473\u7740\u8be5 Pod \u6b63\u5728\u8282\u70b9 cka001 \u4e0a\u8fd0\u884c\u3002 kubectl get pod -o wide \u8fd0\u884c\u7ed3\u679c\uff1a NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES my-nginx-cka001 1/1 Running 0 20s 10.244.228.196 cka001 \u5220\u9664 /etc/kubernetes/manifests/my-nginx.yaml \u8fd9\u4e2a yaml \u6587\u4ef6\uff0c\u5bf9\u5e94\u7684\u9759\u6001 Pod my-nginx \u5c06\u4f1a\u88ab\u81ea\u52a8\u5220\u9664\u3002 sudo rm /etc/kubernetes/manifests/my-nginx.yaml","title":"\u9759\u6001pod"},{"location":"k8s/cka_cn/foundamentals/pod/#pod_4","text":"\u6f14\u793a\u573a\u666f\uff1a \u521b\u5efa\u591a\u5bb9\u5668Pod \u63cf\u8ff0\u8be5Pod \u68c0\u67e5Pod\u7684\u65e5\u5fd7 \u68c0\u67e5\u5bb9\u5668\u7684\u65e5\u5fd7 \u6f14\u793a\uff1a \u521b\u5efa\u4e00\u4e2a\u540d\u4e3a multi-container-pod \u7684Pod\uff0c\u5305\u542b\u591a\u4e2a\u5bb9\u5668\uff1a container-1-nginx \u548c container-2-alpine \u3002 kubectl apply -f - << EOF apiVersion : v1 kind : Pod metadata : name : multi-container-pod spec : containers : - name : container-1-nginx image : nginx ports : - containerPort : 80 - name : container-2-alpine image : alpine command : [ \"watch\" , \"wget\" , \"-qO-\" , \"localhost\" ] EOF \u83b7\u53d6pod\u72b6\u6001\u3002 kubectl get pod multi-container-pod \u8fd0\u884c\u7ed3\u679c \u83b7\u53d6pod\u7684\u8be6\u7ec6\u4fe1\u606f\u3002 kubectl describe pod multi-container-pod \u8fd0\u884c\u7ed3\u679c\uff1a ....... Events: Type Reason Age From Message ---- ------ ---- ---- ------- Normal Scheduled 41s default-scheduler Successfully assigned dev/multi-container-pod to cka002 Normal Pulling 40s kubelet Pulling image \"nginx\" Normal Pulled 23s kubelet Successfully pulled image \"nginx\" in 16.767129903s Normal Created 22s kubelet Created container container-1-nginx Normal Started 22s kubelet Started container container-1-nginx Normal Pulling 22s kubelet Pulling image \"alpine\" Normal Pulled 14s kubelet Successfully pulled image \"alpine\" in 7.776104353s Normal Created 14s kubelet Created container container-2-alpine Normal Started 14s kubelet Started container container-2-alpine \u5bf9\u4e8e\u591a\u5bb9\u5668 Pod\uff0c\u5982\u679c\u6211\u4eec\u60f3\u901a\u8fc7\u547d\u4ee4 kubectl logs \u83b7\u53d6 Pod \u7684\u65e5\u5fd7\uff0c\u9700\u8981\u6307\u5b9a\u5bb9\u5668\u540d\u79f0\u3002\u5982\u679c\u4e0d\u6307\u5b9a\u5bb9\u5668\u540d\u79f0\uff0c\u5c06\u4f1a\u6536\u5230\u9519\u8bef\u4fe1\u606f\u3002 kubectl logs multi-container-pod \u8fd0\u884c\u7ed3\u679c error: a container name must be specified for pod multi-container-pod, choose one of: [ container-1-nginx container-2-alpine ] \u6307\u5b9a\u5bb9\u5668\u540d\u79f0\uff0c\u6211\u4eec\u53ef\u4ee5\u5f97\u5230\u5bf9\u5e94\u7684\u65e5\u5fd7\u4fe1\u606f\u3002 kubectl logs multi-container-pod container-1-nginx \u8fd0\u884c\u7ed3\u679c ...... ::1 - - [ 23 /Jul/2022:04:06:37 +0000 ] \"GET / HTTP/1.1\" 200 615 \"-\" \"Wget\" \"-\" \u5982\u679c\u6211\u4eec\u9700\u8981\u4f7f\u7528\u547d\u4ee4 kubectl exec -it -c -- \u767b\u5f55\u5230 Pod \u4e2d\uff0c\u540c\u6837\u9700\u8981\u6307\u5b9a\u5bb9\u5668\u540d\u79f0\u3002\u5982\u679c\u6ca1\u6709\u6307\u5b9a\u5bb9\u5668\u540d\u79f0\uff0c\u4f1a\u51fa\u73b0\u9519\u8bef\u3002 kubectl exec -it multi-container-pod -c container-1-nginx -- /bin/bash root@multi-container-pod:/# ls \u5220\u9664\u4e0a\u9762\u7ec3\u4e60\u4e2d\u521b\u5efa\u7684pod\u3002 kubectl delete pod multi-container-pod \u4e0b\u9762\u662f\u4e00\u4e2a\u57fa\u672c\u7684yaml\u6587\u4ef6\u7528\u6765\u521b\u5efa\u591a\u5bb9\u5668pod\u3002 kubectl apply -f - << EOF apiVersion : v1 kind : Pod metadata : name : my-multi-pod spec : containers : - image : nginx name : nginx - image : memcached name : memcached - image : redis name : redis EOF \u6f14\u793a\u573a\u666f\uff1a \u521b\u5efa\u4e00\u4e2a\u540d\u4e3a my-busybox \u7684Pod\uff0c\u5e76\u5728\u5176\u4e2d\u6dfb\u52a0\u4e00\u4e2a\u540d\u4e3a container-1-busybox \u7684\u5bb9\u5668\u3002\u8be5\u5bb9\u5668\u5c06\u628a\u6d88\u606f\u5199\u5165\u5230\u6587\u4ef6 /var/log/my-pod-busybox.log \u4e2d\u3002 \u5411Pod my-busybox \u4e2d\u6dfb\u52a0\u53e6\u4e00\u4e2a\u5bb9\u5668 container-2-busybox \uff08Sidecar\uff09\u3002Sidecar\u5bb9\u5668\u4ece\u6587\u4ef6 /var/log/my-pod-busybox.log \u4e2d\u8bfb\u53d6\u6d88\u606f\u3002 \u63d0\u793a\uff1a\u521b\u5efa\u4e00\u4e2aVolume\u6765\u5b58\u50a8\u65e5\u5fd7\u6587\u4ef6\uff0c\u5e76\u4e0e\u4e24\u4e2a\u5bb9\u5668\u5171\u4eab\u3002 \u6f14\u793a\uff1a \u521b\u5efa\u4e00\u4e2a\u540d\u4e3a my-busybox \u7684 Pod\uff0c\u5176\u4e2d\u5305\u542b\u4e00\u4e2a\u5bb9\u5668 container-1-busybox \u3002 kubectl apply -f - << EOF apiVersion: v1 kind: Pod metadata: name: my-busybox spec: containers: - name: container-1-busybox image: busybox args: - /bin/sh - -c - > i=0; while true; do echo \"Hello message from container-1: $i\" >> /var/log/my-pod-busybox.log; i=$((i+1)); sleep 1; done EOF \u5728 Kubernetes \u6587\u6863\u4e2d\u641c\u7d22 emptyDir \u3002 \u53c2\u8003\u4ee5\u4e0b\u6a21\u677f\u7528\u4e8e emptyDir \uff1a https://kubernetes.io/zh-cn/docs/concepts/storage/volumes/ \u5c06\u4ee5\u4e0b\u65b0\u529f\u80fd\u6dfb\u52a0\u5230 Pod \u4e2d\uff1a Volume\uff1a \u5377\u540d\u79f0\uff1a logfile \u7c7b\u578b\uff1a emptyDir \u66f4\u65b0\u73b0\u6709\u5bb9\u5668\uff1a name: container-1-busybox volumeMounts name: logfile mounthPath: /var/log \u6dfb\u52a0\u65b0\u5bb9\u5668\uff1a name: container-2-busybox image: busybox args: ['/bin/sh', '-c', 'tail -n+1 -f /var/log/my-pod-busybox.log'] volumeMounts: name: logfile mountPath: /var/log kubectl get pod my-busybox -o yaml > my-busybox.yaml vi my-busybox.yaml kubectl delete pod my-busybox kubectl apply -f my-busybox.yaml kubectl logs my-busybox -c container-2-busybox \u66f4\u65b0\u540e\u7684\u6587\u4ef6 my-busybox.yaml \u5982\u4e0b\uff1a apiVersion : v1 kind : Pod metadata : annotations : cni.projectcalico.org/containerID : 89644b6b073cd152f94b4cae7bdea6bbc3292cf59afd4f28102bd74f0205c9e4 cni.projectcalico.org/podIP : 10.244.102.20/32 cni.projectcalico.org/podIPs : 10.244.102.20/32 kubectl.kubernetes.io/last-applied-configuration : | {\"apiVersion\":\"v1\",\"kind\":\"Pod\",\"metadata\":{\"annotations\":{},\"name\":\"my-busybox\",\"namespace\":\"dev\"},\"spec\":{\"containers\":[{\"args\":[\"/bin/sh\",\"-c\",\"i=0; while true; do\\n echo \\\"Hello message from container-1: \\\" \\u003e\\u003e /var/log/my-pod-busybox.log;\\n i=1;\\n sleep 1;\\ndone\\n\"],\"image\":\"busybox\",\"name\":\"container-1-busybox\"}]}} creationTimestamp : \"2022-07-29T22:58:27Z\" name : my-busybox namespace : dev resourceVersion : \"1185720\" uid : c5e62a16-4459-4828-a441-7d1471b89a56 spec : containers : - name : container-2-busybox image : busybox args : [ '/bin/sh' , '-c' , 'tail -n+1 -f /var/log/my-pod-busybox.log' ] volumeMounts : - name : logfile mountPath : /var/log - args : - /bin/sh - -c - | i=0; while true; do echo \"Hello message from container-1: $i\" >> /var/log/my-pod-busybox.log; i=1; sleep 1; done image : busybox imagePullPolicy : Always name : container-1-busybox resources : {} terminationMessagePath : /dev/termination-log terminationMessagePolicy : File volumeMounts : - name : logfile mountPath : /var/log - mountPath : /var/run/secrets/kubernetes.io/serviceaccount name : kube-api-access-mhxlf readOnly : true dnsPolicy : ClusterFirst enableServiceLinks : true nodeName : cka003 preemptionPolicy : PreemptLowerPriority priority : 0 restartPolicy : Always schedulerName : default-scheduler securityContext : {} serviceAccount : default serviceAccountName : default terminationGracePeriodSeconds : 30 tolerations : - effect : NoExecute key : node.kubernetes.io/not-ready operator : Exists tolerationSeconds : 300 - effect : NoExecute key : node.kubernetes.io/unreachable operator : Exists tolerationSeconds : 300 volumes : - name : logfile emptyDir : {} - name : kube-api-access-mhxlf projected : defaultMode : 420 sources : - serviceAccountToken : expirationSeconds : 3607 path : token - configMap : items : - key : ca.crt path : ca.crt name : kube-root-ca.crt - downwardAPI : items : - fieldRef : apiVersion : v1 fieldPath : metadata.namespace path : namespace status : conditions : - lastProbeTime : null lastTransitionTime : \"2022-07-29T22:58:27Z\" status : \"True\" type : Initialized - lastProbeTime : null lastTransitionTime : \"2022-07-29T22:58:30Z\" status : \"True\" type : Ready - lastProbeTime : null lastTransitionTime : \"2022-07-29T22:58:30Z\" status : \"True\" type : ContainersReady - lastProbeTime : null lastTransitionTime : \"2022-07-29T22:58:27Z\" status : \"True\" type : PodScheduled containerStatuses : - containerID : containerd://fd42d4ba4d94d8918d8846327b1db2328be13c5f93f381877ff0228ed7b5468d image : docker.io/library/busybox:latest imageID : docker.io/library/busybox@sha256:0e97a8ca6955f22dbc7db9e9dbe970971f423541e52c34b8cb96ccc88d6a3883 lastState : {} name : container-1-busybox ready : true restartCount : 0 started : true state : running : startedAt : \"2022-07-29T22:58:30Z\" hostIP : phase : Running podIP : 10.244.102.20 podIPs : - ip : 10.244.102.20 qosClass : BestEffort startTime : \"2022-07-29T22:58:27Z\" \u6e05\u7406\u4e0a\u9762\u7ec3\u4e60\u4e2d\u521b\u5efa\u7684pod\u3002 kubectl delete pod my-busybox","title":"\u591a\u5bb9\u5668Pod"},{"location":"k8s/cka_cn/foundamentals/pod/#pod_5","text":"\u6f14\u793a\u573a\u666f\uff1a \u521b\u5efa\u62e5\u6709\u4e24\u4e2a\u521d\u59cb\u5316\u5bb9\u5668\u7684 Pod myapp-pod \u3002 myapp-container init-mydb \u521b\u5efa\u4e24\u4e2a\u670d\u52a1\uff1a myservice mydb \u6f14\u793a\u9884\u671f\u7ed3\u8bba\uff1a myapp-container \u7b49\u5f85\u670d\u52a1 myservice \u542f\u52a8\uff0c\u4ee5\u89e3\u6790\u540d\u79f0 myservice.dev.svc.cluster.local init-mydb \u7b49\u5f85\u670d\u52a1 mydb \u542f\u52a8\uff0c\u4ee5\u89e3\u6790\u540d\u79f0 mydb.dev.svc.cluster.local \u3002 \u6f14\u793a\uff1a \u521b\u5efa\u540d\u4e3a myapp-pod.yaml \u7684yaml\u6587\u4ef6\uff0c\u5e76\u6dfb\u52a0\u4ee5\u4e0b\u5185\u5bb9\u3002 \u6ce8\u610f\uff1a\u7531\u4e8e\u547d\u4ee4 $(cat /var/..... \u5c06\u88ab\u89c6\u4e3a\u4e3b\u673a\u53d8\u91cf\uff0c\u56e0\u6b64\u6211\u4eec\u4e0d\u80fd\u4f7f\u7528echo\u751f\u6210\u8be5\u6587\u4ef6\u3002\u5b83\u662f\u5bb9\u5668\u672c\u8eab\u7684\u53d8\u91cf\u3002 vi myapp-pod.yaml \u6587\u4ef6\u5185\u5bb9 apiVersion : v1 kind : Pod metadata : name : myapp-pod labels : app : myapp spec : containers : - name : myapp-container image : busybox:1.28 command : [ 'sh' , '-c' , 'echo The app is running! && sleep 3600' ] initContainers : - name : init-myservice image : busybox:1.28 command : [ 'sh' , '-c' , \"until nslookup myservice.$(cat /var/run/secrets/kubernetes.io/serviceaccount/namespace).svc.cluster.local; do echo waiting for myservice; sleep 2; done\" ] - name : init-mydb image : busybox:1.28 command : [ 'sh' , '-c' , \"until nslookup mydb.$(cat /var/run/secrets/kubernetes.io/serviceaccount/namespace).svc.cluster.local; do echo waiting for mydb; sleep 2; done\" ] \u7528\u4e0a\u9762\u521b\u5efa\u7684yaml\u6587\u4ef6\u521b\u5efaPod myapp-pod \u3002 kubectl apply -f myapp-pod.yaml \u68c0\u67e5pod\u7684\u72b6\u6001\u3002 kubectl get pod myapp-pod \u8fd0\u884c\u7ed3\u679c\uff1a NAME READY STATUS RESTARTS AGE myapp-pod 0/1 Init:0/2 0 12m \u68c0\u67e5Pod\uff0c\u53ef\u4ee5\u770b\u5230\u4e24\u4e2a\u9519\u8bef\uff1a nslookup: \u65e0\u6cd5\u89e3\u6790'myservice.dev.svc.cluster.local' Pod \"myapp-pod\"\u4e2d\u7684\u5bb9\u5668\u201cinit-mydb\u201d\u6b63\u5728\u7b49\u5f85\u542f\u52a8\uff1aPodInitializing kubectl logs myapp-pod -c init-myservice # Inspect the first init container kubectl logs myapp-pod -c init-mydb # Inspect the second init container \u5728\u8fd9\u4e2a\u65f6\u5019\uff0c\u8fd9\u4e9b init \u5bb9\u5668\u5c06\u7b49\u5f85\u53d1\u73b0\u540d\u4e3a mydb \u548c myservice \u7684\u670d\u52a1\u3002 \u521b\u5efa mydb \u548c myservice \u670d\u52a1\uff1a kubectl apply -f - << EOF apiVersion: v1 kind: Service metadata: name: myservice spec: ports: - protocol: TCP port: 80 targetPort: 9376 --- apiVersion: v1 kind: Service metadata: name: mydb spec: ports: - protocol: TCP port: 80 targetPort: 9377 EOF \u67e5\u770b\u521b\u5efa\u7684\u670d\u52a1\u7684\u72b6\u6001\u3002 kubectl get service \u521b\u5efa\u76842\u4e2a\u670d\u52a1\u90fd\u662f\u8fd0\u884c\u72b6\u6001\u3002 NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE mydb ClusterIP 11.244.239.149 80/TCP 6s myservice ClusterIP 11.244.116.126 80/TCP 6s \u518d\u6b21\u67e5\u770bpod\u7684\u72b6\u6001\u3002 kubectl get pod myapp-pod -o wide pod\u5df2\u7ecf\u6b63\u5e38\u8fd0\u884c\u4e86\u3002 NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES myapp-pod 0/1 Init:0/2 0 2m40s 10.244.112.2 cka002 \u73b0\u5728\u6211\u4eec\u53ef\u4ee5\u770b\u5230\u90a3\u4e9b\u521d\u59cb\u5316\u5bb9\u5668\u90fd\u5df2\u7ecf\u5b8c\u6210\uff0c myapp-pod Pod \u8fdb\u5165\u4e86 Running \u72b6\u6001\u3002 \u5220\u9664\u4e0a\u9762\u7ec3\u4e60\u4e2d\u521b\u5efa\u7684pod\u3002 kubectl delete service mydb myservice kubectl delete pod myapp-pod \u53c2\u8003\uff1a Pod basics Lifecycle & phases Kubernetes pod design pattern","title":"\u542b\u521d\u59cb\u5316\u5bb9\u5668Pod"},{"location":"k8s/cka_cn/foundamentals/policy/","text":"CKA\u81ea\u5b66\u7b14\u8bb022:Policy \u00b6 ResourceQuota \u00b6 \u6f14\u793a\u573a\u666f\uff1a \u4e3anamespace quota-object-example \u521b\u5efa\u8d44\u6e90\u914d\u989dResourceQuota object-quota-demo \u3002 \u4e3a NodePort \u6d4b\u8bd5 ResourceQuota object-quota-demo \u3002 \u4e3a PVC \u6d4b\u8bd5 ResourceQuota object-quota-demo \u3002 Create Namespace \u00b6 \u521b\u5efaNamespace\u3002 kubectl create ns quota-object-example \u521b\u5efaResourceQuota \u00b6 \u4e3anamespace quota-object-example \u521b\u5efa\u8d44\u6e90\u914d\u989dResourceQuota object-quota-demo \u3002 \u5728\u8be5namespace\u4e2d\uff0c\u6211\u4eec\u53ea\u80fd\u521b\u5efa 1 \u4e2a\u6c38\u4e45\u5377PVC\u30011 \u4e2a\u8d1f\u8f7d\u5747\u8861LoadBalancer\u670d\u52a1\uff0c\u4e0d\u80fd\u521b\u5efa NodePort \u670d\u52a1\u3002 kubectl apply -f - <@ \uff09 CURRENT NAME CLUSTER AUTHINFO NAMESPACE * kubernetes-admin@kubernetes kubernetes kubernetes-admin dev \u521b\u5efaCA\u914d\u7f6e\u6587\u4ef6 \u00b6 CA\uff08Certificate Authority\uff09\u914d\u7f6e\u6587\u4ef6\uff08config file\uff09\u662f\u4e00\u4e2a\u7528\u4e8e\u5b58\u50a8\u8bc1\u4e66\u9881\u53d1\u673a\u6784\uff08CA\uff09\u4fe1\u606f\u7684\u6587\u4ef6\u3002 \u5728\u4f7f\u7528TLS/SSL\u52a0\u5bc6\u901a\u4fe1\u65f6\uff0c\u9700\u8981\u4f7f\u7528\u8bc1\u4e66\u6765\u9a8c\u8bc1\u901a\u4fe1\u53cc\u65b9\u7684\u8eab\u4efd\u3002 \u800cCA\u5219\u662f\u8d1f\u8d23\u7b7e\u53d1\u548c\u9a8c\u8bc1\u8bc1\u4e66\u7684\u673a\u6784\uff0c\u56e0\u6b64\u5728\u5efa\u7acbTLS/SSL\u8fde\u63a5\u65f6\u9700\u8981\u5148\u9a8c\u8bc1CA\u7684\u4fe1\u4efb\u5173\u7cfb\uff0c\u4ee5\u4fdd\u8bc1\u8bc1\u4e66\u7684\u6709\u6548\u6027\u3002 CA\u6587\u4ef6\u4e2d\u5b58\u50a8\u4e86CA\u7684\u516c\u94a5\u4fe1\u606f\u548c\u5176\u4ed6\u76f8\u5173\u7684\u914d\u7f6e\u4fe1\u606f\u3002 \u5728Kubernetes\u4e2d\uff0c\u4f7f\u7528CA\u6587\u4ef6\u6765\u9a8c\u8bc1\u8bc1\u4e66\u7684\u6709\u6548\u6027\u548c\u6388\u6743\u8bbf\u95ee\u3002 \u67e5\u770b\u76ee\u5f55 /etc/kubernetes/pki \u53ca\u5176\u5b50\u76ee\u5f55\u7684\u7ed3\u6784\u60c5\u51b5\u3002 tree /etc/kubernetes/pki \u8fd0\u884c\u7ed3\u679c\uff0c\u4e0b\u9762\u662fKubernetes\u521d\u59cb\u5b89\u88c5\u540e\u7684\u6587\u4ef6\u7ed3\u6784\u7684\u793a\u4f8b\u5185\u5bb9\u3002 /etc/kubernetes/pki \u251c\u2500\u2500 apiserver.crt \u251c\u2500\u2500 apiserver-etcd-client.crt \u251c\u2500\u2500 apiserver-etcd-client.key \u251c\u2500\u2500 apiserver.key \u251c\u2500\u2500 apiserver-kubelet-client.crt \u251c\u2500\u2500 apiserver-kubelet-client.key \u251c\u2500\u2500 ca.crt \u251c\u2500\u2500 ca.key \u251c\u2500\u2500 etcd \u2502 \u251c\u2500\u2500 ca.crt \u2502 \u251c\u2500\u2500 ca.key \u2502 \u251c\u2500\u2500 healthcheck-client.crt \u2502 \u251c\u2500\u2500 healthcheck-client.key \u2502 \u251c\u2500\u2500 peer.crt \u2502 \u251c\u2500\u2500 peer.key \u2502 \u251c\u2500\u2500 server.crt \u2502 \u2514\u2500\u2500 server.key \u251c\u2500\u2500 front-proxy-ca.crt \u251c\u2500\u2500 front-proxy-ca.key \u251c\u2500\u2500 front-proxy-client.crt \u251c\u2500\u2500 front-proxy-client.key \u251c\u2500\u2500 sa.key \u2514\u2500\u2500 sa.pub \u8fdb\u5165\u76ee\u5f55 /etc/kubernetes/pki \uff0c\u5373\u5f53\u524d\u5de5\u4f5c\u76ee\u5f55\u3002 cd /etc/kubernetes/pki \u68c0\u67e5\u6587\u4ef6 ca-config.json \u662f\u5426\u5df2\u7ecf\u5b58\u5728\u4e0e\u5f53\u524d\u5de5\u4f5c\u76ee\u5f55\u3002 ll ca-config.json \u5982\u679c\u4e0d\u5b58\u5728\uff0c\u5219\u521b\u5efa\u8fd9\u4e2a\u6587\u4ef6\u3002 \u6211\u4eec\u53ef\u4ee5\u6dfb\u52a0\u591a\u4e2a\u914d\u7f6e\u6587\u4ef6\u6765\u6307\u5b9a\u4e0d\u540c\u7684\u8fc7\u671f\u65e5\u671f\u3001\u573a\u666f\u3001\u53c2\u6570\u7b49\u3002 \u914d\u7f6e\u6587\u4ef6\u5c06\u7528\u4e8e\u7b7e\u7f72\u8bc1\u4e66\u3002 87600 \u5c0f\u65f6\u5927\u7ea6\u662f10\u5e74\u3002 \u8fd9\u91cc\u6211\u4eec\u5c06\u5728 ca-config.json \u6587\u4ef6\u4e2d\u6dfb\u52a0\u4e00\u4e2a\u540d\u4e3a dev \u7684\u914d\u7f6e\u6587\u4ef6\u3002 cat > ca-config.json < cka-dev-csr.json < \uff09\u6765\u62fc\u63a5\u51fa\u73af\u5883\u53d8\u91cf APISERVER \u7684\u503c\uff0c\u5982\uff1a https://: \u3002 kubectl get node -owide \u8fd0\u884c\u7ed3\u679c\uff1a NAME STATUS ROLES AGE VERSION OS-IMAGE KERNEL-VERSION CONTAINER-RUNTIME cka001 Ready control-plane,master 14h v1.24.0 Ubuntu 20.04.4 LTS 5.4.0-122-generic containerd://1.5.9 cka002 Ready 14h v1.24.0 Ubuntu 20.04.4 LTS 5.4.0-122-generic containerd://1.5.9 cka003 Ready 14h v1.24.0 Ubuntu 20.04.4 LTS 5.4.0-122-generic containerd://1.5.9 \u8bbe\u5b9a\u5e76\u8f93\u51fa\u73af\u5883\u53d8\u91cf APISERVER \u3002 echo \"export APISERVER=\\\"https://:6443\\\"\" >> ~/.bashrc source ~/.bashrc \u9a8c\u8bc1\u73af\u5883\u53d8\u91cf APISERVER \u7684\u503c\u3002 echo $APISERVER \u8fd0\u884c\u7ed3\u679c\uff1a https://:6443 \u8bbe\u7f6e\u96c6\u7fa4 \u00b6 \u4fdd\u6301\u5f53\u524d\u5de5\u4f5c\u76ee\u5f55\u4e3a /etc/kubernetes/pki \u3002 \u751f\u6210 kubeconfig \u6587\u4ef6\u3002 kubectl config set-cluster kubernetes \\ --certificate-authority = /etc/kubernetes/pki/ca.crt \\ --embed-certs = true \\ --server = ${ APISERVER } \\ --kubeconfig = cka-dev.kubeconfig \u73b0\u5728\u6211\u4eec\u751f\u6210\u4e86\u65b0\u7684\u914d\u7f6e\u6587\u4ef6 cka-dev.kubeconfig \u3002 ll -tr | grep cka-dev \u8f93\u51fa\u7ed3\u679c\uff1a -rw-r--r-- 1 root root 222 Jul 24 08:49 cka-dev-csr.json -rw-r--r-- 1 root root 1281 Jul 24 09:14 cka-dev.pem -rw------- 1 root root 1675 Jul 24 09:14 cka-dev-key.pem -rw-r--r-- 1 root root 1001 Jul 24 09:14 cka-dev.csr -rw------- 1 root root 1671 Jul 24 09:16 cka-dev.kubeconfig \u8bfb\u53d6\u914d\u7f6e\u6587\u4ef6 cka-dev.kubeconfig \u7684\u5185\u5bb9\u3002 cat cka-dev.kubeconfig \u8f93\u51fa\u7684\u5185\u5bb9\uff1a apiVersion : v1 clusters : - cluster : certificate-authority-data : server : https://:6443 name : kubernetes contexts : null current-context : \"\" kind : Config preferences : {} users : null \u914d\u7f6e\u7528\u6237 \u00b6 \u5728\u6587\u4ef6 cka-dev.kubeconfig \u4e2d\uff0c\u7528\u6237\u4fe1\u606f\u8fd9\u90e8\u5206\u662f\u7a7a\u7684\u3002 \u4e0b\u9762\u6211\u4eec\u914d\u7f6e\u4e00\u4e2a\u7528\u6237 cka-dev \u3002 kubectl config set-credentials cka-dev \\ --client-certificate = /etc/kubernetes/pki/cka-dev.pem \\ --client-key = /etc/kubernetes/pki/cka-dev-key.pem \\ --embed-certs = true \\ --kubeconfig = cka-dev.kubeconfig \u73b0\u5728\uff0c\u7528\u6237\u4fe1\u606f\u5df2\u7ecf\u88ab\u6dfb\u52a0\u5230\u914d\u7f6e\u6587\u4ef6 cka-dev.kubeconfig \u4e2d\u4e86\u3002 cat cka-dev.kubeconfig \u8f93\u51fa\u7ed3\u679c\uff1a apiVersion : v1 clusters : - cluster : certificate-authority-data : server : https://:6443 name : kubernetes contexts : null current-context : \"\" kind : Config preferences : {} users : - name : cka-dev user : client-certificate-data : client-key-data : \u81f3\u6b64\u6211\u4eec\u5f97\u5230\u4e86\u4e00\u4e2a\u5b8c\u6574\u7684\u914d\u7f6e\u6587\u4ef6 cka-dev.kubeconfig \u3002 \u7531\u4e8e\u6211\u4eec\u6ca1\u6709\u5728 kubeconfig \u6587\u4ef6\u4e2d\u8bbe\u7f6e\u5f53\u524d\u4e0a\u4e0b\u6587\uff0c\u5f53\u6211\u4eec\u4f7f\u7528\u5b83\u6765\u83b7\u53d6\u8282\u70b9\u4fe1\u606f\u65f6\uff0c\u4f1a\u6536\u5230\u4ee5\u4e0b\u9519\u8bef\u3002 kubectl --kubeconfig = cka-dev.kubeconfig get nodes \u8fd0\u884c\u7ed3\u679c\uff1a The connection to the server localhost:8080 was refused - did you specify the right host or port? \u5f53\u524d\u4e0a\u4e0b\u6587\u5185\u5bb9\u662f\u7a7a\u767d\u3002 kubectl --kubeconfig = cka-dev.kubeconfig config get-contexts \u8f93\u51fa\u7ed3\u679c\uff1a CURRENT NAME CLUSTER AUTHINFO NAMESPACE \u914d\u7f6e\u4e0a\u4e0b\u6587 \u00b6 \u914d\u7f6e\u4e0a\u4e0b\u6587\u3002 kubectl config set-context dev --cluster = kubernetes --user = cka-dev --kubeconfig = cka-dev.kubeconfig \u73b0\u5728\u6211\u4eec\u914d\u7f6e\u4e86\u4e0a\u4e0b\u6587\uff0c\u4f46\u5176\u4e2d CURRENT \u4ecd\u7136\u662f\u7a7a\u767d\u3002 kubectl --kubeconfig = cka-dev.kubeconfig config get-contexts \u8fd0\u884c\u7ed3\u679c\uff1a CURRENT NAME CLUSTER AUTHINFO NAMESPACE dev kubernetes cka-dev \u8bbe\u7f6e\u9ed8\u8ba4\u4e0a\u4e0b\u6587\u3002\u4e0a\u4e0b\u6587\u5c06\u4e3a\u591a\u96c6\u7fa4\u73af\u5883\u4e2d\u7684\u96c6\u7fa4\u548c\u7528\u6237\u94fe\u63a5\uff0c\u5e76\u4e14\u6211\u4eec\u53ef\u4ee5\u5207\u6362\u5230\u4e0d\u540c\u7684\u96c6\u7fa4\u3002 kubectl --kubeconfig = cka-dev.kubeconfig config use-context dev \u9a8c\u8bc1 \u00b6 \u73b0\u5728 CURRENT \u5df2\u7ecf\u88ab\u6807\u8bb0\u4e3a * \u4e86\uff0c\u8fd9\u5c31\u8bf4\u660e\u5f53\u524d\u4e0a\u4e0b\u6587\u5df2\u7ecf\u914d\u7f6e\u597d\u4e86\u3002 kubectl --kubeconfig = cka-dev.kubeconfig config get-contexts \u8fd0\u884c\u7ed3\u679c\uff1a CURRENT NAME CLUSTER AUTHINFO NAMESPACE * dev kubernetes cka-dev \u56e0\u4e3a\u7528\u6237 cka-dev \u5728\u8be5\u96c6\u7fa4\u4e2d\u6ca1\u6709\u6388\u6743\uff0c\u6240\u4ee5\u5f53\u6211\u4eec\u5c1d\u8bd5\u83b7\u53d6 Pod \u6216 Node \u7684\u4fe1\u606f\u65f6\uff0c\u4f1a\u6536\u5230\u201c\u7981\u6b62\u8bbf\u95ee\uff08forbidden\uff09\u201d\u9519\u8bef\u3002 kubectl --kubeconfig = /etc/kubernetes/pki/cka-dev.kubeconfig get pod kubectl --kubeconfig = /etc/kubernetes/pki/cka-dev.kubeconfig get node \u5408\u5e76kubeconfig\u6587\u4ef6 \u00b6 \u62f7\u8d1d\u5f53\u524d\u914d\u7f6e\u6587\u4ef6\uff0c\u4f5c\u4e3a\u5907\u4efd\u3002 cp ~/.kube/config ~/.kube/config.old \u628a\u4e24\u4e2a\u914d\u7f6e\u6587\u4ef6\u5408\u5e76\u6210\u4e00\u4e2a\u65b0\u7684\u914d\u7f6e\u6587\u4ef6\uff0c\u5e76\u5b58\u653e\u5728 /tmp/config \u3002 KUBECONFIG = ~/.kube/config:/etc/kubernetes/pki/cka-dev.kubeconfig kubectl config view --flatten > /tmp/config \u7528\u5408\u5e76\u540e\u7684\u65b0\u914d\u7f6e\u6587\u4ef6\u66ff\u6362\u8001\u7684\u914d\u7f6e\u6587\u4ef6\u3002 mv /tmp/config ~/.kube/config \u65b0\u7684\u914d\u7f6e\u6587\u4ef6 ~/.kube/config \u7c7b\u4f3c\u5982\u4e0b\u3002 apiVersion : v1 clusters : - cluster : certificate-authority-data : server : https://:6443 name : kubernetes contexts : - context : cluster : kubernetes user : cka-dev name : dev - context : cluster : kubernetes user : kubernetes-admin name : kubernetes-admin@kubernetes current-context : kubernetes-admin@kubernetes kind : Config preferences : {} users : - name : cka-dev user : client-certificate-data : client-key-data : - name : kubernetes-admin user : client-certificate-data : client-key-data : \u68c0\u67e5\u57fa\u4e8e\u65b0\u7684\u914d\u7f6e\u6587\u4ef6\u4e0b\u7684\u5f53\u524d\u4e0a\u4e0b\u6587\u3002 kubectl config get-contexts \u5f53\u524d\u4e0a\u4e0b\u6587\u662f\u7cfb\u7edf\u9ed8\u8ba4\u914d\u7f6e kubernetes-admin@kubernetes \u3002 CURRENT NAME CLUSTER AUTHINFO NAMESPACE dev kubernetes cka-dev * kubernetes-admin@kubernetes kubernetes kubernetes-admin dev \u547d\u540d\u7a7a\u95f4\u548c\u4e0a\u4e0b\u6587 \u00b6 \u67e5\u8be2\u5f53\u524d\u547d\u540d\u7a7a\u95f4namespace\u5217\u8868\u548c\u5bf9\u5e94\u6807\u7b7elabel\u7684\u4fe1\u606f\u3002 kubectl get ns --show-labels \u521b\u5efanamespace cka \u3002 kubectl create namespace cka \u4f7f\u7528\u4ee5\u4e0b\u547d\u4ee4\u66f4\u65b0\u4e0a\u4e0b\u6587\u4fe1\u606f\uff0c\u4f8b\u5982\uff0c\u66f4\u65b0\u9ed8\u8ba4\u547d\u540d\u7a7a\u95f4\u7b49\u3002 kubectl config set-context --cluster = --namespace = --user = \u4e0b\u9762\u9488\u5bf9\u6bcf\u4e2a\u4e0a\u4e0b\u6587context\u8bbe\u5b9a\u9ed8\u8ba4\u7684namespace\u3002 kubectl config set-context kubernetes-admin@kubernetes --cluster = kubernetes --namespace = default --user = kubernetes-admin kubectl config set-context dev --cluster = kubernetes --namespace = cka --user = cka-dev \u68c0\u67e5\u5f53\u524d\u4e0a\u4e0b\u6587context\u7684\u4fe1\u606f\u3002 kubectl config get-contexts \u8f93\u51fa\u7ed3\u679c\uff1a CURRENT NAME CLUSTER AUTHINFO NAMESPACE dev kubernetes cka-dev cka * kubernetes-admin@kubernetes kubernetes kubernetes-admin dev \u901a\u8fc7\u4e0b\u9762\u7684\u547d\u4ee4\uff0c\u53ef\u4ee5\u5207\u6362\u5230\u65b0\u7684context\u3002 kubectl config use-contexts \u4f8b\u5982\uff1a kubectl config use-context dev \u68c0\u67e5\u4e0a\u9762\u7684\u53d8\u66f4\u662f\u5426\u751f\u6548\u3002 kubectl config get-contexts \u8fd0\u884c\u7ed3\u679c\uff1b CURRENT NAME CLUSTER AUTHINFO NAMESPACE * dev kubernetes cka-dev cka kubernetes-admin@kubernetes kubernetes kubernetes-admin dev Be noted, four users beginning with cka-dev created don't have any authorizations, e.g., access namespaces, get pods, etc.. Referring RBAC to grant their authorizations. \u6ce8\u610f\uff1a\u524d\u9762\u521b\u5efa\u7684\u4ee5 cka-dev \u5f00\u5934\u7684\u7528\u6237\u5b9e\u9645\u6ca1\u6709\u4efb\u4f55\u6743\u9650\uff0c\u4f8b\u5982\u8bbf\u95ee\u547d\u540d\u7a7a\u95f4\u3001\u83b7\u53d6 pod \u7b49\uff0c\u4e0b\u9762\u5c06\u901a\u8fc7 RBAC \u6388\u4e88\u4ed6\u4eec\u6388\u6743\u3002 \u89d2\u8272Role\u548c\u89d2\u8272\u7ed1\u5b9aRoleBinding \u00b6 \u5c06\u5f53\u524d\u5de5\u4f5c\u4e0a\u4e0b\u6587\u5207\u6362\u5230 kubernetes-admin@kubernetes \u3002 kubectl config use-context kubernetes-admin@kubernetes \u4f7f\u7528\u5e26\u6709\u9009\u9879 --dry-run=client \u548c -o yaml \u7684 kubectl create role \u547d\u4ee4\uff0c\u751f\u6210\u521b\u5efa\u89d2\u8272role\u7684 yaml \u6a21\u677f\u3002 kubectl create role admin-dev --resource = pods --verb = get --verb = list --verb = watch --dry-run = client -o yaml \u5728namespace cka \u4e0a\u521b\u5efa\u89d2\u8272role admin-dev \u3002 kubectl apply -f - << EOF apiVersion: rbac.authorization.k8s.io/v1 kind: Role metadata: namespace: cka name: admin-dev rules: - apiGroups: - \"\" resources: - pods verbs: - get - watch - list EOF \u4f7f\u7528\u5e26\u6709\u9009\u9879 --dry-run=client \u548c -o yaml \u7684 kubectl create rolebinding \u547d\u4ee4\uff0c\u751f\u6210\u521b\u5efa\u89d2\u8272\u7ed1\u5b9arolebinding\u7684 yaml \u6a21\u677f\u3002 kubectl create rolebinding admin --role = admin-dev --user = cka-dev --dry-run = client -o yaml \u5728namespace cka \u4e0a\u521b\u5efa\u4e00\u4e2a\u89d2\u8272\u7ed1\u5b9arolebinding admin \u3002 kubectl apply -f - << EOF apiVersion: rbac.authorization.k8s.io/v1 kind: RoleBinding metadata: name: admin namespace: cka roleRef: apiGroup: rbac.authorization.k8s.io kind: Role name: admin-dev subjects: - apiGroup: rbac.authorization.k8s.io kind: User name: cka-dev EOF \u9a8c\u8bc1namespace cka \u4e0a\u7684\u7528\u6237 cka-dev \u7684\u6743\u9650\u3002 \u5207\u6362\u5230\u4e0a\u4e0b\u6587 dev \u3002 kubectl config use-context dev \u67e5\u8be2namespace cka \u4e0apod\u7684\u72b6\u6001\uff0c\u6210\u529f\uff01 kubectl get pod -n cka \u67e5\u8be2namespace kube-system \u4e0apod\u7684\u72b6\u6001\uff0c\u5931\u8d25\uff01\u56e0\u4e3a\u524d\u9762\u6dfb\u52a0\u7684\u6743\u9650\u4ec5\u9650\u4e8enamespace cka \u3002 kubectl get pod -n kube-system \u67e5\u8be2\u8282\u70b9node\u7684\u72b6\u6001\uff0c\u5931\u8d25\uff01\u56e0\u4e3a\u5728\u89d2\u8272role\u91cc\u9762\u6211\u4eec\u53ea\u5b9a\u4e49\u4e86pod\u8fd9\u4e00\u79cd\u8d44\u6e90\u3002 kubectl get node \u5728namespace dev \u4e0a\u521b\u5efa\u4e00\u4e2apod\uff0c\u5931\u8d25\uff01\u56e0\u4e3a\u6211\u4eec\u5728\u53ea\u6709\u5bf9pod\u7684 get , watch , list \u4e09\u79cd\u64cd\u4f5c\u6743\u9650\uff0c\u6ca1\u6709 create \u6743\u9650\u3002 kubectl run nginx --image = nginx -n cka \u96c6\u7fa4\u89d2\u8272ClusterRole\u548c\u96c6\u7fa4\u89d2\u8272\u7ed1\u5b9aClusterRoleBinding \u00b6 \u5207\u6362\u5230\u4e0a\u4e0b\u6587 kubernetes-admin@kubernetes \u3002 kubectl config use-context kubernetes-admin@kubernetes \u521b\u5efa\u4e00\u4e2a\u540d\u4e3a nodes-admin \u7684 ClusterRole\uff0c\u5b83\u6388\u4e88 get \u3001 watch \u3001 list \u5bf9 nodes \u8d44\u6e90\u7684\u6388\u6743\u3002 kubectl apply -f - <@ \uff09 CURRENT NAME CLUSTER AUTHINFO NAMESPACE * kubernetes-admin@kubernetes kubernetes kubernetes-admin dev","title":"\u5f53\u524d\u4e0a\u4e0b\u6587"},{"location":"k8s/cka_cn/foundamentals/rbac/#ca","text":"CA\uff08Certificate Authority\uff09\u914d\u7f6e\u6587\u4ef6\uff08config file\uff09\u662f\u4e00\u4e2a\u7528\u4e8e\u5b58\u50a8\u8bc1\u4e66\u9881\u53d1\u673a\u6784\uff08CA\uff09\u4fe1\u606f\u7684\u6587\u4ef6\u3002 \u5728\u4f7f\u7528TLS/SSL\u52a0\u5bc6\u901a\u4fe1\u65f6\uff0c\u9700\u8981\u4f7f\u7528\u8bc1\u4e66\u6765\u9a8c\u8bc1\u901a\u4fe1\u53cc\u65b9\u7684\u8eab\u4efd\u3002 \u800cCA\u5219\u662f\u8d1f\u8d23\u7b7e\u53d1\u548c\u9a8c\u8bc1\u8bc1\u4e66\u7684\u673a\u6784\uff0c\u56e0\u6b64\u5728\u5efa\u7acbTLS/SSL\u8fde\u63a5\u65f6\u9700\u8981\u5148\u9a8c\u8bc1CA\u7684\u4fe1\u4efb\u5173\u7cfb\uff0c\u4ee5\u4fdd\u8bc1\u8bc1\u4e66\u7684\u6709\u6548\u6027\u3002 CA\u6587\u4ef6\u4e2d\u5b58\u50a8\u4e86CA\u7684\u516c\u94a5\u4fe1\u606f\u548c\u5176\u4ed6\u76f8\u5173\u7684\u914d\u7f6e\u4fe1\u606f\u3002 \u5728Kubernetes\u4e2d\uff0c\u4f7f\u7528CA\u6587\u4ef6\u6765\u9a8c\u8bc1\u8bc1\u4e66\u7684\u6709\u6548\u6027\u548c\u6388\u6743\u8bbf\u95ee\u3002 \u67e5\u770b\u76ee\u5f55 /etc/kubernetes/pki \u53ca\u5176\u5b50\u76ee\u5f55\u7684\u7ed3\u6784\u60c5\u51b5\u3002 tree /etc/kubernetes/pki \u8fd0\u884c\u7ed3\u679c\uff0c\u4e0b\u9762\u662fKubernetes\u521d\u59cb\u5b89\u88c5\u540e\u7684\u6587\u4ef6\u7ed3\u6784\u7684\u793a\u4f8b\u5185\u5bb9\u3002 /etc/kubernetes/pki \u251c\u2500\u2500 apiserver.crt \u251c\u2500\u2500 apiserver-etcd-client.crt \u251c\u2500\u2500 apiserver-etcd-client.key \u251c\u2500\u2500 apiserver.key \u251c\u2500\u2500 apiserver-kubelet-client.crt \u251c\u2500\u2500 apiserver-kubelet-client.key \u251c\u2500\u2500 ca.crt \u251c\u2500\u2500 ca.key \u251c\u2500\u2500 etcd \u2502 \u251c\u2500\u2500 ca.crt \u2502 \u251c\u2500\u2500 ca.key \u2502 \u251c\u2500\u2500 healthcheck-client.crt \u2502 \u251c\u2500\u2500 healthcheck-client.key \u2502 \u251c\u2500\u2500 peer.crt \u2502 \u251c\u2500\u2500 peer.key \u2502 \u251c\u2500\u2500 server.crt \u2502 \u2514\u2500\u2500 server.key \u251c\u2500\u2500 front-proxy-ca.crt \u251c\u2500\u2500 front-proxy-ca.key \u251c\u2500\u2500 front-proxy-client.crt \u251c\u2500\u2500 front-proxy-client.key \u251c\u2500\u2500 sa.key \u2514\u2500\u2500 sa.pub \u8fdb\u5165\u76ee\u5f55 /etc/kubernetes/pki \uff0c\u5373\u5f53\u524d\u5de5\u4f5c\u76ee\u5f55\u3002 cd /etc/kubernetes/pki \u68c0\u67e5\u6587\u4ef6 ca-config.json \u662f\u5426\u5df2\u7ecf\u5b58\u5728\u4e0e\u5f53\u524d\u5de5\u4f5c\u76ee\u5f55\u3002 ll ca-config.json \u5982\u679c\u4e0d\u5b58\u5728\uff0c\u5219\u521b\u5efa\u8fd9\u4e2a\u6587\u4ef6\u3002 \u6211\u4eec\u53ef\u4ee5\u6dfb\u52a0\u591a\u4e2a\u914d\u7f6e\u6587\u4ef6\u6765\u6307\u5b9a\u4e0d\u540c\u7684\u8fc7\u671f\u65e5\u671f\u3001\u573a\u666f\u3001\u53c2\u6570\u7b49\u3002 \u914d\u7f6e\u6587\u4ef6\u5c06\u7528\u4e8e\u7b7e\u7f72\u8bc1\u4e66\u3002 87600 \u5c0f\u65f6\u5927\u7ea6\u662f10\u5e74\u3002 \u8fd9\u91cc\u6211\u4eec\u5c06\u5728 ca-config.json \u6587\u4ef6\u4e2d\u6dfb\u52a0\u4e00\u4e2a\u540d\u4e3a dev \u7684\u914d\u7f6e\u6587\u4ef6\u3002 cat > ca-config.json < cka-dev-csr.json < \uff09\u6765\u62fc\u63a5\u51fa\u73af\u5883\u53d8\u91cf APISERVER \u7684\u503c\uff0c\u5982\uff1a https://: \u3002 kubectl get node -owide \u8fd0\u884c\u7ed3\u679c\uff1a NAME STATUS ROLES AGE VERSION OS-IMAGE KERNEL-VERSION CONTAINER-RUNTIME cka001 Ready control-plane,master 14h v1.24.0 Ubuntu 20.04.4 LTS 5.4.0-122-generic containerd://1.5.9 cka002 Ready 14h v1.24.0 Ubuntu 20.04.4 LTS 5.4.0-122-generic containerd://1.5.9 cka003 Ready 14h v1.24.0 Ubuntu 20.04.4 LTS 5.4.0-122-generic containerd://1.5.9 \u8bbe\u5b9a\u5e76\u8f93\u51fa\u73af\u5883\u53d8\u91cf APISERVER \u3002 echo \"export APISERVER=\\\"https://:6443\\\"\" >> ~/.bashrc source ~/.bashrc \u9a8c\u8bc1\u73af\u5883\u53d8\u91cf APISERVER \u7684\u503c\u3002 echo $APISERVER \u8fd0\u884c\u7ed3\u679c\uff1a https://:6443","title":"\u521b\u5efakubeconfig\u6587\u4ef6"},{"location":"k8s/cka_cn/foundamentals/rbac/#_4","text":"\u4fdd\u6301\u5f53\u524d\u5de5\u4f5c\u76ee\u5f55\u4e3a /etc/kubernetes/pki \u3002 \u751f\u6210 kubeconfig \u6587\u4ef6\u3002 kubectl config set-cluster kubernetes \\ --certificate-authority = /etc/kubernetes/pki/ca.crt \\ --embed-certs = true \\ --server = ${ APISERVER } \\ --kubeconfig = cka-dev.kubeconfig \u73b0\u5728\u6211\u4eec\u751f\u6210\u4e86\u65b0\u7684\u914d\u7f6e\u6587\u4ef6 cka-dev.kubeconfig \u3002 ll -tr | grep cka-dev \u8f93\u51fa\u7ed3\u679c\uff1a -rw-r--r-- 1 root root 222 Jul 24 08:49 cka-dev-csr.json -rw-r--r-- 1 root root 1281 Jul 24 09:14 cka-dev.pem -rw------- 1 root root 1675 Jul 24 09:14 cka-dev-key.pem -rw-r--r-- 1 root root 1001 Jul 24 09:14 cka-dev.csr -rw------- 1 root root 1671 Jul 24 09:16 cka-dev.kubeconfig \u8bfb\u53d6\u914d\u7f6e\u6587\u4ef6 cka-dev.kubeconfig \u7684\u5185\u5bb9\u3002 cat cka-dev.kubeconfig \u8f93\u51fa\u7684\u5185\u5bb9\uff1a apiVersion : v1 clusters : - cluster : certificate-authority-data : server : https://:6443 name : kubernetes contexts : null current-context : \"\" kind : Config preferences : {} users : null","title":"\u8bbe\u7f6e\u96c6\u7fa4"},{"location":"k8s/cka_cn/foundamentals/rbac/#_5","text":"\u5728\u6587\u4ef6 cka-dev.kubeconfig \u4e2d\uff0c\u7528\u6237\u4fe1\u606f\u8fd9\u90e8\u5206\u662f\u7a7a\u7684\u3002 \u4e0b\u9762\u6211\u4eec\u914d\u7f6e\u4e00\u4e2a\u7528\u6237 cka-dev \u3002 kubectl config set-credentials cka-dev \\ --client-certificate = /etc/kubernetes/pki/cka-dev.pem \\ --client-key = /etc/kubernetes/pki/cka-dev-key.pem \\ --embed-certs = true \\ --kubeconfig = cka-dev.kubeconfig \u73b0\u5728\uff0c\u7528\u6237\u4fe1\u606f\u5df2\u7ecf\u88ab\u6dfb\u52a0\u5230\u914d\u7f6e\u6587\u4ef6 cka-dev.kubeconfig \u4e2d\u4e86\u3002 cat cka-dev.kubeconfig \u8f93\u51fa\u7ed3\u679c\uff1a apiVersion : v1 clusters : - cluster : certificate-authority-data : server : https://:6443 name : kubernetes contexts : null current-context : \"\" kind : Config preferences : {} users : - name : cka-dev user : client-certificate-data : client-key-data : \u81f3\u6b64\u6211\u4eec\u5f97\u5230\u4e86\u4e00\u4e2a\u5b8c\u6574\u7684\u914d\u7f6e\u6587\u4ef6 cka-dev.kubeconfig \u3002 \u7531\u4e8e\u6211\u4eec\u6ca1\u6709\u5728 kubeconfig \u6587\u4ef6\u4e2d\u8bbe\u7f6e\u5f53\u524d\u4e0a\u4e0b\u6587\uff0c\u5f53\u6211\u4eec\u4f7f\u7528\u5b83\u6765\u83b7\u53d6\u8282\u70b9\u4fe1\u606f\u65f6\uff0c\u4f1a\u6536\u5230\u4ee5\u4e0b\u9519\u8bef\u3002 kubectl --kubeconfig = cka-dev.kubeconfig get nodes \u8fd0\u884c\u7ed3\u679c\uff1a The connection to the server localhost:8080 was refused - did you specify the right host or port? \u5f53\u524d\u4e0a\u4e0b\u6587\u5185\u5bb9\u662f\u7a7a\u767d\u3002 kubectl --kubeconfig = cka-dev.kubeconfig config get-contexts \u8f93\u51fa\u7ed3\u679c\uff1a CURRENT NAME CLUSTER AUTHINFO NAMESPACE","title":"\u914d\u7f6e\u7528\u6237"},{"location":"k8s/cka_cn/foundamentals/rbac/#_6","text":"\u914d\u7f6e\u4e0a\u4e0b\u6587\u3002 kubectl config set-context dev --cluster = kubernetes --user = cka-dev --kubeconfig = cka-dev.kubeconfig \u73b0\u5728\u6211\u4eec\u914d\u7f6e\u4e86\u4e0a\u4e0b\u6587\uff0c\u4f46\u5176\u4e2d CURRENT \u4ecd\u7136\u662f\u7a7a\u767d\u3002 kubectl --kubeconfig = cka-dev.kubeconfig config get-contexts \u8fd0\u884c\u7ed3\u679c\uff1a CURRENT NAME CLUSTER AUTHINFO NAMESPACE dev kubernetes cka-dev \u8bbe\u7f6e\u9ed8\u8ba4\u4e0a\u4e0b\u6587\u3002\u4e0a\u4e0b\u6587\u5c06\u4e3a\u591a\u96c6\u7fa4\u73af\u5883\u4e2d\u7684\u96c6\u7fa4\u548c\u7528\u6237\u94fe\u63a5\uff0c\u5e76\u4e14\u6211\u4eec\u53ef\u4ee5\u5207\u6362\u5230\u4e0d\u540c\u7684\u96c6\u7fa4\u3002 kubectl --kubeconfig = cka-dev.kubeconfig config use-context dev","title":"\u914d\u7f6e\u4e0a\u4e0b\u6587"},{"location":"k8s/cka_cn/foundamentals/rbac/#_7","text":"\u73b0\u5728 CURRENT \u5df2\u7ecf\u88ab\u6807\u8bb0\u4e3a * \u4e86\uff0c\u8fd9\u5c31\u8bf4\u660e\u5f53\u524d\u4e0a\u4e0b\u6587\u5df2\u7ecf\u914d\u7f6e\u597d\u4e86\u3002 kubectl --kubeconfig = cka-dev.kubeconfig config get-contexts \u8fd0\u884c\u7ed3\u679c\uff1a CURRENT NAME CLUSTER AUTHINFO NAMESPACE * dev kubernetes cka-dev \u56e0\u4e3a\u7528\u6237 cka-dev \u5728\u8be5\u96c6\u7fa4\u4e2d\u6ca1\u6709\u6388\u6743\uff0c\u6240\u4ee5\u5f53\u6211\u4eec\u5c1d\u8bd5\u83b7\u53d6 Pod \u6216 Node \u7684\u4fe1\u606f\u65f6\uff0c\u4f1a\u6536\u5230\u201c\u7981\u6b62\u8bbf\u95ee\uff08forbidden\uff09\u201d\u9519\u8bef\u3002 kubectl --kubeconfig = /etc/kubernetes/pki/cka-dev.kubeconfig get pod kubectl --kubeconfig = /etc/kubernetes/pki/cka-dev.kubeconfig get node","title":"\u9a8c\u8bc1"},{"location":"k8s/cka_cn/foundamentals/rbac/#kubeconfig_1","text":"\u62f7\u8d1d\u5f53\u524d\u914d\u7f6e\u6587\u4ef6\uff0c\u4f5c\u4e3a\u5907\u4efd\u3002 cp ~/.kube/config ~/.kube/config.old \u628a\u4e24\u4e2a\u914d\u7f6e\u6587\u4ef6\u5408\u5e76\u6210\u4e00\u4e2a\u65b0\u7684\u914d\u7f6e\u6587\u4ef6\uff0c\u5e76\u5b58\u653e\u5728 /tmp/config \u3002 KUBECONFIG = ~/.kube/config:/etc/kubernetes/pki/cka-dev.kubeconfig kubectl config view --flatten > /tmp/config \u7528\u5408\u5e76\u540e\u7684\u65b0\u914d\u7f6e\u6587\u4ef6\u66ff\u6362\u8001\u7684\u914d\u7f6e\u6587\u4ef6\u3002 mv /tmp/config ~/.kube/config \u65b0\u7684\u914d\u7f6e\u6587\u4ef6 ~/.kube/config \u7c7b\u4f3c\u5982\u4e0b\u3002 apiVersion : v1 clusters : - cluster : certificate-authority-data : server : https://:6443 name : kubernetes contexts : - context : cluster : kubernetes user : cka-dev name : dev - context : cluster : kubernetes user : kubernetes-admin name : kubernetes-admin@kubernetes current-context : kubernetes-admin@kubernetes kind : Config preferences : {} users : - name : cka-dev user : client-certificate-data : client-key-data : - name : kubernetes-admin user : client-certificate-data : client-key-data : \u68c0\u67e5\u57fa\u4e8e\u65b0\u7684\u914d\u7f6e\u6587\u4ef6\u4e0b\u7684\u5f53\u524d\u4e0a\u4e0b\u6587\u3002 kubectl config get-contexts \u5f53\u524d\u4e0a\u4e0b\u6587\u662f\u7cfb\u7edf\u9ed8\u8ba4\u914d\u7f6e kubernetes-admin@kubernetes \u3002 CURRENT NAME CLUSTER AUTHINFO NAMESPACE dev kubernetes cka-dev * kubernetes-admin@kubernetes kubernetes kubernetes-admin dev","title":"\u5408\u5e76kubeconfig\u6587\u4ef6"},{"location":"k8s/cka_cn/foundamentals/rbac/#_8","text":"\u67e5\u8be2\u5f53\u524d\u547d\u540d\u7a7a\u95f4namespace\u5217\u8868\u548c\u5bf9\u5e94\u6807\u7b7elabel\u7684\u4fe1\u606f\u3002 kubectl get ns --show-labels \u521b\u5efanamespace cka \u3002 kubectl create namespace cka \u4f7f\u7528\u4ee5\u4e0b\u547d\u4ee4\u66f4\u65b0\u4e0a\u4e0b\u6587\u4fe1\u606f\uff0c\u4f8b\u5982\uff0c\u66f4\u65b0\u9ed8\u8ba4\u547d\u540d\u7a7a\u95f4\u7b49\u3002 kubectl config set-context --cluster = --namespace = --user = \u4e0b\u9762\u9488\u5bf9\u6bcf\u4e2a\u4e0a\u4e0b\u6587context\u8bbe\u5b9a\u9ed8\u8ba4\u7684namespace\u3002 kubectl config set-context kubernetes-admin@kubernetes --cluster = kubernetes --namespace = default --user = kubernetes-admin kubectl config set-context dev --cluster = kubernetes --namespace = cka --user = cka-dev \u68c0\u67e5\u5f53\u524d\u4e0a\u4e0b\u6587context\u7684\u4fe1\u606f\u3002 kubectl config get-contexts \u8f93\u51fa\u7ed3\u679c\uff1a CURRENT NAME CLUSTER AUTHINFO NAMESPACE dev kubernetes cka-dev cka * kubernetes-admin@kubernetes kubernetes kubernetes-admin dev \u901a\u8fc7\u4e0b\u9762\u7684\u547d\u4ee4\uff0c\u53ef\u4ee5\u5207\u6362\u5230\u65b0\u7684context\u3002 kubectl config use-contexts \u4f8b\u5982\uff1a kubectl config use-context dev \u68c0\u67e5\u4e0a\u9762\u7684\u53d8\u66f4\u662f\u5426\u751f\u6548\u3002 kubectl config get-contexts \u8fd0\u884c\u7ed3\u679c\uff1b CURRENT NAME CLUSTER AUTHINFO NAMESPACE * dev kubernetes cka-dev cka kubernetes-admin@kubernetes kubernetes kubernetes-admin dev Be noted, four users beginning with cka-dev created don't have any authorizations, e.g., access namespaces, get pods, etc.. Referring RBAC to grant their authorizations. \u6ce8\u610f\uff1a\u524d\u9762\u521b\u5efa\u7684\u4ee5 cka-dev \u5f00\u5934\u7684\u7528\u6237\u5b9e\u9645\u6ca1\u6709\u4efb\u4f55\u6743\u9650\uff0c\u4f8b\u5982\u8bbf\u95ee\u547d\u540d\u7a7a\u95f4\u3001\u83b7\u53d6 pod \u7b49\uff0c\u4e0b\u9762\u5c06\u901a\u8fc7 RBAC \u6388\u4e88\u4ed6\u4eec\u6388\u6743\u3002","title":"\u547d\u540d\u7a7a\u95f4\u548c\u4e0a\u4e0b\u6587"},{"location":"k8s/cka_cn/foundamentals/rbac/#rolerolebinding","text":"\u5c06\u5f53\u524d\u5de5\u4f5c\u4e0a\u4e0b\u6587\u5207\u6362\u5230 kubernetes-admin@kubernetes \u3002 kubectl config use-context kubernetes-admin@kubernetes \u4f7f\u7528\u5e26\u6709\u9009\u9879 --dry-run=client \u548c -o yaml \u7684 kubectl create role \u547d\u4ee4\uff0c\u751f\u6210\u521b\u5efa\u89d2\u8272role\u7684 yaml \u6a21\u677f\u3002 kubectl create role admin-dev --resource = pods --verb = get --verb = list --verb = watch --dry-run = client -o yaml \u5728namespace cka \u4e0a\u521b\u5efa\u89d2\u8272role admin-dev \u3002 kubectl apply -f - << EOF apiVersion: rbac.authorization.k8s.io/v1 kind: Role metadata: namespace: cka name: admin-dev rules: - apiGroups: - \"\" resources: - pods verbs: - get - watch - list EOF \u4f7f\u7528\u5e26\u6709\u9009\u9879 --dry-run=client \u548c -o yaml \u7684 kubectl create rolebinding \u547d\u4ee4\uff0c\u751f\u6210\u521b\u5efa\u89d2\u8272\u7ed1\u5b9arolebinding\u7684 yaml \u6a21\u677f\u3002 kubectl create rolebinding admin --role = admin-dev --user = cka-dev --dry-run = client -o yaml \u5728namespace cka \u4e0a\u521b\u5efa\u4e00\u4e2a\u89d2\u8272\u7ed1\u5b9arolebinding admin \u3002 kubectl apply -f - << EOF apiVersion: rbac.authorization.k8s.io/v1 kind: RoleBinding metadata: name: admin namespace: cka roleRef: apiGroup: rbac.authorization.k8s.io kind: Role name: admin-dev subjects: - apiGroup: rbac.authorization.k8s.io kind: User name: cka-dev EOF \u9a8c\u8bc1namespace cka \u4e0a\u7684\u7528\u6237 cka-dev \u7684\u6743\u9650\u3002 \u5207\u6362\u5230\u4e0a\u4e0b\u6587 dev \u3002 kubectl config use-context dev \u67e5\u8be2namespace cka \u4e0apod\u7684\u72b6\u6001\uff0c\u6210\u529f\uff01 kubectl get pod -n cka \u67e5\u8be2namespace kube-system \u4e0apod\u7684\u72b6\u6001\uff0c\u5931\u8d25\uff01\u56e0\u4e3a\u524d\u9762\u6dfb\u52a0\u7684\u6743\u9650\u4ec5\u9650\u4e8enamespace cka \u3002 kubectl get pod -n kube-system \u67e5\u8be2\u8282\u70b9node\u7684\u72b6\u6001\uff0c\u5931\u8d25\uff01\u56e0\u4e3a\u5728\u89d2\u8272role\u91cc\u9762\u6211\u4eec\u53ea\u5b9a\u4e49\u4e86pod\u8fd9\u4e00\u79cd\u8d44\u6e90\u3002 kubectl get node \u5728namespace dev \u4e0a\u521b\u5efa\u4e00\u4e2apod\uff0c\u5931\u8d25\uff01\u56e0\u4e3a\u6211\u4eec\u5728\u53ea\u6709\u5bf9pod\u7684 get , watch , list \u4e09\u79cd\u64cd\u4f5c\u6743\u9650\uff0c\u6ca1\u6709 create \u6743\u9650\u3002 kubectl run nginx --image = nginx -n cka","title":"\u89d2\u8272Role\u548c\u89d2\u8272\u7ed1\u5b9aRoleBinding"},{"location":"k8s/cka_cn/foundamentals/rbac/#clusterroleclusterrolebinding","text":"\u5207\u6362\u5230\u4e0a\u4e0b\u6587 kubernetes-admin@kubernetes \u3002 kubectl config use-context kubernetes-admin@kubernetes \u521b\u5efa\u4e00\u4e2a\u540d\u4e3a nodes-admin \u7684 ClusterRole\uff0c\u5b83\u6388\u4e88 get \u3001 watch \u3001 list \u5bf9 nodes \u8d44\u6e90\u7684\u6388\u6743\u3002 kubectl apply -f - < nodeName \u00b6 \u6ce8\u610f\uff0c nodeName \u5177\u6709\u6700\u9ad8\u4f18\u5148\u7ea7\uff0c\u56e0\u4e3a\u5b83\u4e0d\u662f\u7531 Scheduler \u8fdb\u884c\u8c03\u5ea6\u7684\u3002 \u521b\u5efa\u4e00\u4e2a Pod nginx-nodename \uff0c\u5e76\u5c06\u5176\u6307\u5b9a\u5728 cka003 \u8282\u70b9\u4e0a\u3002 kubectl apply -f - < Affinity \u00b6 \u5728 Kubernetes \u96c6\u7fa4\u4e2d\uff0c\u6709\u4e9b Pod \u9700\u8981\u9891\u7e41\u4e0e\u5176\u4ed6 Pod \u8fdb\u884c\u4ea4\u4e92\u3002\u5728\u8fd9\u79cd\u60c5\u51b5\u4e0b\uff0c\u5efa\u8bae\u5c06\u8fd9\u4e9b Pod \u8c03\u5ea6\u5230\u540c\u4e00\u4e2a\u8282\u70b9\u4e0a\u8fd0\u884c\u3002\u4f8b\u5982\uff0c\u4e24\u4e2a Pod\uff1a Nginx \u548c Mysql \uff0c\u5982\u679c\u5b83\u4eec\u9891\u7e41\u901a\u4fe1\uff0c\u5219\u9700\u8981\u5728\u540c\u4e00\u4e2a\u8282\u70b9\u4e0a\u90e8\u7f72\u5b83\u4eec\u3002 \u57fa\u4e8epod\u4e4b\u95f4\u7684\u5173\u7cfb\uff0c\u6211\u4eec\u53ef\u4ee5\u4f7f\u7528 podAffinity \u8fdb\u884c\u9009\u62e9\u3002 podAffinity \u6709\u4e24\u79cd\u8c03\u5ea6\u7c7b\u578b\uff1a requiredDuringSchedulingIgnoredDuringExecution \uff08\u786c\u4eb2\u548c\uff09 preferredDuringSchedulingIgnoredDuringExecution \uff08\u8f6f\u4eb2\u548c\uff09 \u53ef\u4ee5\u4f7f\u7528\u4ee5\u4e0b\u7c7b\u578b\u8bbe\u7f6e topologyKey \uff1a kubernetes.io/hostname \uff03NodeName failure-domain.beta.kubernetes.io/zone \uff03\u533a\u57df Zone failure-domain.beta.kubernetes.io/region # \u533a\u57df Zone \u6211\u4eec\u53ef\u4ee5\u8bbe\u7f6e\u8282\u70b9\u6807\u7b7e\u6765\u5bf9\u8282\u70b9\u7684\u540d\u79f0/\u533a\u57df\u8fdb\u884c\u5206\u7c7b\uff0c\u8fd9\u6837\u5c31\u53ef\u4ee5\u88ab podAffinity \u6240\u4f7f\u7528\u3002 \u521b\u5efapod Nginx \u3002 kubectl apply -f - < ","title":"nodeSelector"},{"location":"k8s/cka_cn/foundamentals/scheduling/#nodename","text":"\u6ce8\u610f\uff0c nodeName \u5177\u6709\u6700\u9ad8\u4f18\u5148\u7ea7\uff0c\u56e0\u4e3a\u5b83\u4e0d\u662f\u7531 Scheduler \u8fdb\u884c\u8c03\u5ea6\u7684\u3002 \u521b\u5efa\u4e00\u4e2a Pod nginx-nodename \uff0c\u5e76\u5c06\u5176\u6307\u5b9a\u5728 cka003 \u8282\u70b9\u4e0a\u3002 kubectl apply -f - < ","title":"nodeName"},{"location":"k8s/cka_cn/foundamentals/scheduling/#affinity","text":"\u5728 Kubernetes \u96c6\u7fa4\u4e2d\uff0c\u6709\u4e9b Pod \u9700\u8981\u9891\u7e41\u4e0e\u5176\u4ed6 Pod \u8fdb\u884c\u4ea4\u4e92\u3002\u5728\u8fd9\u79cd\u60c5\u51b5\u4e0b\uff0c\u5efa\u8bae\u5c06\u8fd9\u4e9b Pod \u8c03\u5ea6\u5230\u540c\u4e00\u4e2a\u8282\u70b9\u4e0a\u8fd0\u884c\u3002\u4f8b\u5982\uff0c\u4e24\u4e2a Pod\uff1a Nginx \u548c Mysql \uff0c\u5982\u679c\u5b83\u4eec\u9891\u7e41\u901a\u4fe1\uff0c\u5219\u9700\u8981\u5728\u540c\u4e00\u4e2a\u8282\u70b9\u4e0a\u90e8\u7f72\u5b83\u4eec\u3002 \u57fa\u4e8epod\u4e4b\u95f4\u7684\u5173\u7cfb\uff0c\u6211\u4eec\u53ef\u4ee5\u4f7f\u7528 podAffinity \u8fdb\u884c\u9009\u62e9\u3002 podAffinity \u6709\u4e24\u79cd\u8c03\u5ea6\u7c7b\u578b\uff1a requiredDuringSchedulingIgnoredDuringExecution \uff08\u786c\u4eb2\u548c\uff09 preferredDuringSchedulingIgnoredDuringExecution \uff08\u8f6f\u4eb2\u548c\uff09 \u53ef\u4ee5\u4f7f\u7528\u4ee5\u4e0b\u7c7b\u578b\u8bbe\u7f6e topologyKey \uff1a kubernetes.io/hostname \uff03NodeName failure-domain.beta.kubernetes.io/zone \uff03\u533a\u57df Zone failure-domain.beta.kubernetes.io/region # \u533a\u57df Zone \u6211\u4eec\u53ef\u4ee5\u8bbe\u7f6e\u8282\u70b9\u6807\u7b7e\u6765\u5bf9\u8282\u70b9\u7684\u540d\u79f0/\u533a\u57df\u8fdb\u884c\u5206\u7c7b\uff0c\u8fd9\u6837\u5c31\u53ef\u4ee5\u88ab podAffinity \u6240\u4f7f\u7528\u3002 \u521b\u5efapod Nginx \u3002 kubectl apply -f - < 80/TCP 14s app=httpd NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES pod/httpd-app-6496d888c9-4nb6z 1/1 Running 0 77s 10.244.102.21 cka003 pod/httpd-app-6496d888c9-b7xht 1/1 Running 0 77s 10.244.112.19 cka002 \u6267\u884c\u4e0b\u9762\u7684\u547d\u4ee4\uff0c\u9a8c\u8bc1\u5bf9pod\u7684IP\u5730\u5740\u7684\u8bbf\u95ee\u3002 curl 10 .244.102.21 curl 10 .244.112.19 \u53ef\u4ee5\u5f97\u5230\u4e0b\u9762\u7684\u4fe1\u606f\uff0c\u8bf4\u660e\u8bbf\u95ee\u6210\u529f\u3002

It works!

\u6267\u884c\u4e0b\u9762\u7684\u547d\u4ee4\uff0c\u9a8c\u8bc1\u901a\u8fc7\u7aef\u53e3\u5bf9ClusterIP\u7684\u8bbf\u95ee\u3002 curl 11 .244.247.7:80 \u53ef\u4ee5\u5f97\u5230\u4e0b\u9762\u7684\u4fe1\u606f\uff0c\u8bf4\u660e\u8bbf\u95ee\u6210\u529f\u3002

It works!

\u66b4\u9732Service \u00b6 \u521b\u5efa\u4e00\u4e2a\u4e34\u65f6\u7684Pod nslookup \uff0c\u5e76\u9644\u52a0\u5230\u5b83\u4ee5\u9a8c\u8bc1DNS\u89e3\u6790\u3002\u9009\u9879 --rm \u8868\u793a\u5728\u9000\u51fa\u540e\u5220\u9664\u8be5Pod\u3002 kubectl run -it nslookup --rm --image = busybox:1.28 \u8fde\u63a5\u5230\u8fd9\u4e2aPod\u540e\uff0c\u8fd0\u884c\u547d\u4ee4 nslookup httpd-app \u3002\u6211\u4eec\u4f1a\u6536\u5230 httpd-app \u670d\u52a1\u7684 ClusterIP \u548c\u5b8c\u6574\u7684\u57df\u540d\u3002 / # nslookup httpd-app Server: 11.244.0.10 Address 1: 11.244.0.10 kube-dns.kube-system.svc.cluster.local Name: httpd-app Address 1: 11.244.247.7 httpd-app.dev.svc.cluster.local \u6211\u4eec\u53ef\u4ee5\u901a\u8fc7\u6267\u884c\u547d\u4ee4 kubectl get pod -o wide \u6765\u5728\u65b0\u7684\u7ec8\u7aef\u4e2d\u68c0\u67e5\u4e34\u65f6 Pod nslookup \u7684 IP \u5730\u5740\u3002Pod nslookup \u7684 IP \u5730\u5740\u4e3a 10.244.112.20 \u3002 kubectl get pod nslookup \u8fd0\u884c\u7ed3\u679c NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES nslookup 1/1 Running 0 2m44s 10.244.112.20 cka002 NodePort \u00b6 \u521b\u5efa\u5e76\u5e94\u7528\u6587\u4ef6 svc-nodeport.yaml \u6765\u521b\u5efaService httpd-app \u3002 kubectl apply -f - < will update configuration to existing resources. Here the Service httpd-app is changed from ClusterIP to NodePort type. No change to the Deployment httpd-app . \u6211\u4eec\u5c06\u6536\u5230\u4ee5\u4e0b\u8f93\u51fa\u3002 \u5176\u4e2d\uff0c\u547d\u4ee4 kubectl apply -f \u5c06\u66f4\u65b0\u73b0\u6709\u8d44\u6e90\u7684\u914d\u7f6e\u3002 \u5728\u8fd9\u91cc\uff0cService httpd-app \u4ece ClusterIP \u7c7b\u578b\u66f4\u6539\u4e3a NodePort \u7c7b\u578b\u3002 \u5bf9Deployment httpd-app \u6ca1\u6709\u4efb\u4f55\u66f4\u6539\u3002 service/httpd-app configured deployment.apps/httpd-app unchanged \u901a\u8fc7\u547d\u4ee4 kubectl get svc \u6765\u68c0\u67e5Service httpd-app \uff0c\u5176\u4e2d\uff1a Service\u7684IP\u5730\u5740\u4e0d\u53d8\u3002 Service\u7684\u7c7b\u578b\u53d8\u4e3a NodePort \u3002 Service\u7684\u7aef\u53e3\u53f7\u4ece 80/TCP \u53d8\u4e3a 80:30080/TCP \u3002 NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE httpd-app NodePort 11.244.247.7 80:30080/TCP 18m \u5728\u6bcf\u4e2a\u8282\u70b9node\u4e0a\u6267\u884c\u547d\u4ee4 curl :30080 \uff0c\u6d4b\u8bd5\u5bf9Service httpd-app \u7684\u8054\u901a\u6027\u3002 curl :30080 curl :30080 curl :30080 \u53ef\u4ee5\u5f97\u5230\u4e0b\u9762\u7684\u4fe1\u606f\uff0c\u8bf4\u660e\u8bbf\u95ee\u6210\u529f\u3002

It works!

Headless Service \u00b6 \u521b\u5efaHeadless Service web \u548cStatefulSet web . kubectl apply -f - < web-1 1/1 Running 0 6s 10.244.112.21 cka002 \u6267\u884c\u547d\u4ee4 kubectl describe svc -l app=web \uff0c\u68c0\u67e5\u521b\u5efa\u7684Service\u7684\u8be6\u7ec6\u4fe1\u606f\u3002 Name : web Namespace : dev Labels : app=web Annotations : Selector : app=web Type : ClusterIP IP Family Policy : SingleStack IP Families : IPv4 IP : None IPs : None Port : web 80/TCP TargetPort : 80/TCP Endpoints : 10.244.102.22:80,10.244.112.21:80 Session Affinity : None Events : \u8fde\u63a5\u5230\u4e34\u65f6Pod nslookup \uff0c\u901a\u8fc7 nslookup \u6765\u9a8c\u8bc1DNS\u5230\u89e3\u6790\u3002 kubectl run -it nslookup --rm --image = busybox:1.28 \u901a\u8fc7 nslookup \u547d\u4ee4\u8bbf\u95eeHeadless Service web \uff0c\u6211\u4eec\u53ef\u4ee5\u5f97\u52302\u4e2apod\u7684IP\u5730\u5740\uff0c\u6ce8\u610f\u4e0d\u662f\u96c6\u7fa4IP\u5730\u5740ClusterIP\uff08\u56e0\u4e3a\u662fHeadless Service\uff09\u3002 / # nslookup web Server: 11.244.0.10 Address 1: 11.244.0.10 kube-dns.kube-system.svc.cluster.local Name: web Address 1: 10.244.112.21 web-1.web.dev.svc.cluster.local Address 2: 10.244.102.22 web-0.web.dev.svc.cluster.local \u6211\u4eec\u4e5f\u53ef\u4ee5\u4f7f\u7528 nslookup \u547d\u4ee4\u6765\u67e5\u627e web-0.web \u548c web-1.web \u3002Headless Service\u7684\u6bcf\u4e2a Pod \u90fd\u6709\u81ea\u5df1\u7684\u670d\u52a1\u540d\u79f0\u7528\u4e8e DNS \u67e5\u627e\u3002 / # nslookup web-0.web Server: 11.244.0.10 Address 1: 11.244.0.10 kube-dns.kube-system.svc.cluster.local Name: web-0.web Address 1: 10.244.102.22 web-0.web.dev.svc.cluster.local / # nslookup web-1.web Server: 11.244.0.10 Address 1: 11.244.0.10 kube-dns.kube-system.svc.cluster.local Name: web-1.web Address 1: 10.244.112.21 web-1.web.dev.svc.cluster.local \u5220\u9664\u4e0a\u9762\u521b\u5efa\u7684\u4e34\u65f6\u8d44\u6e90\u3002 kubectl delete sts web kubectl delete service httpd-app web kubectl delete deployment httpd-app \u670d\u52a1\u5185\u90e8\u6d41\u91cf\u7b56\u7565 \u00b6 Service Internal Traffic Policy\uff08\u670d\u52a1\u5185\u90e8\u6d41\u91cf\u7b56\u7565\uff09\u662fKubernetes\u4e2d\u4e00\u79cd\u7528\u4e8e\u63a7\u5236\u670d\u52a1\u5185\u90e8\u6d41\u91cf\u7684\u7b56\u7565\u3002\u5b83\u7684\u4e3b\u8981\u76ee\u7684\u662f\u63a7\u5236Service\u5bf9\u8c61\u4e2dPod\u7684\u8bbf\u95ee\u7b56\u7565\u3002 \u5728Kubernetes\u4e2d\uff0cService\u5bf9\u8c61\u5c06\u4e00\u4e2a\u865a\u62dfIP\u5730\u5740\u7ed1\u5b9a\u5230\u4e00\u7ec4Pod\u4e0a\uff0c\u4ee5\u4fbf\u53ef\u4ee5\u901a\u8fc7\u8fd9\u4e2a\u865a\u62dfIP\u5730\u5740\u6765\u8bbf\u95ee\u8fd9\u7ec4Pod\u3002Service\u5bf9\u8c61\u5728\u67d0\u79cd\u7a0b\u5ea6\u4e0a\u50cf\u8d1f\u8f7d\u5747\u8861\u5668\uff0c\u53ef\u4ee5\u5c06\u8bf7\u6c42\u6d41\u91cf\u8def\u7531\u5230\u5176\u4e0b\u9762\u7684Pod\u3002 Service\u5bf9\u8c61\u901a\u5e38\u4f1a\u4f7f\u7528\u4ee5\u4e0b\u4e24\u79cd\u7c7b\u578b\u4e4b\u4e00\u6765\u8def\u7531\u6d41\u91cf\uff1a ClusterIP\uff1a\u6b64\u7c7b\u578b\u7684Service\u53ea\u80fd\u4ece\u540c\u4e00Kubernetes\u96c6\u7fa4\u5185\u7684\u5176\u4ed6Pod\u8bbf\u95ee\uff0c\u56e0\u4e3a\u5b83\u662f\u5728Kubernetes\u96c6\u7fa4\u5185\u90e8\u8def\u7531\u8bf7\u6c42\u6d41\u91cf\u7684\u3002 NodePort\uff1a\u6b64\u7c7b\u578b\u7684Service\u5728\u6240\u6709\u8282\u70b9\u4e0a\u516c\u5f00\u4e86\u4e00\u4e2a\u9759\u6001\u7aef\u53e3\uff0c\u4ece\u800c\u53ef\u4ee5\u4ece\u96c6\u7fa4\u5916\u90e8\u8bbf\u95ee\u5b83\u3002\u4f46\u662f\uff0c\u5b83\u4ecd\u7136\u53ef\u4ee5\u4ece\u96c6\u7fa4\u5185\u90e8\u8bbf\u95ee\u3002 Service Internal Traffic Policy\u5b9a\u4e49\u4e86Pod\u5982\u4f55\u8bbf\u95ee\u540c\u4e00\u4e2aService\u4e2d\u7684\u5176\u4ed6Pod\u3002\u53ef\u4ee5\u5c06\u5176\u8bbe\u7f6e\u4e3a\u4ee5\u4e0b\u4e09\u4e2a\u9009\u9879\u4e4b\u4e00\uff1a Cluster\uff1a\u8fd9\u662f\u9ed8\u8ba4\u8bbe\u7f6e\uff0c\u5b83\u5141\u8bb8Service\u4e2d\u7684\u4efb\u4f55Pod\u90fd\u53ef\u4ee5\u8bbf\u95ee\u53e6\u4e00\u4e2aPod\u3002 Local\uff1a\u6b64\u9009\u9879\u5141\u8bb8Pod\u4ec5\u8bbf\u95ee\u5728\u540c\u4e00\u8282\u70b9\u4e0a\u8fd0\u884c\u7684\u5176\u4ed6Pod\u3002\u5982\u679cPod\u9700\u8981\u5feb\u901f\u7684\u3001\u4f4e\u5ef6\u8fdf\u7684\u7f51\u7edc\u8bbf\u95ee\uff0c\u53ef\u4ee5\u4f7f\u7528\u6b64\u9009\u9879\u3002 Disabled\uff1a\u6b64\u9009\u9879\u5c06\u5b8c\u5168\u7981\u6b62Service\u5185\u90e8\u7684\u6d41\u91cf\u3002\u5b83\u9002\u7528\u4e8e\u7279\u5b9a\u7684\u73af\u5883\u548c\u90e8\u7f72\u4e2d\u3002 \u6f14\u793a\u573a\u666f\uff1a \u6a21\u62df Service \u5185\u90e8\u6d41\u91cf\u7b56\u7565\u7684\u5de5\u4f5c\u65b9\u5f0f\u3002 \u9884\u671f\u7ed3\u679c\uff1a \u901a\u8fc7\u8bbe\u7f6e Service \u7684 internalTrafficPolicy: Local \uff0cService \u53ea\u4f1a\u5c06\u6d41\u91cf\u8def\u7531\u5230 Pod \u6240\u5728\u7684\u8282\u70b9\u5185\u90e8\u3002 \u6f14\u793a\u76ee\u7684\uff1a Service Internal Traffic Policy\uff08\u670d\u52a1\u5185\u90e8\u6d41\u91cf\u7b56\u7565\uff09\u53ef\u4ee5\u9650\u5236\u5185\u90e8\u6d41\u91cf\u4ec5\u8def\u7531\u5230\u540c\u4e00\u8282\u70b9\u4e2d\u7684\u7ec8\u7aef\u8282\u70b9\u3002 \u8fd9\u91cc\u7684\u201c\u5185\u90e8\u201d\u6d41\u91cf\u662f\u6307\u6e90\u81ea\u5f53\u524d\u96c6\u7fa4\u4e2d\u7684Pod\u7684\u6d41\u91cf\u3002 \u901a\u8fc7\u5c06\u5176 .spec.internalTrafficPolicy \u8bbe\u7f6e\u4e3a Local\uff0c\u53ef\u4ee5\u544a\u8bc9 kube-proxy \u4ec5\u5bf9\u96c6\u7fa4\u5185\u90e8\u6d41\u91cf\u4f7f\u7528\u672c\u5730\u8282\u70b9\u7684\u7ec8\u7aef\u8282\u70b9\u3002 \u5bf9\u4e8e\u4f4d\u4e8e\u6ca1\u6709\u7ed9\u5b9a\u670d\u52a1\u7684\u7ec8\u7aef\u8282\u70b9\u7684\u8282\u70b9\u4e0a\u7684Pod\uff0c\u5373\u4f7f\u670d\u52a1\u5728\u5176\u4ed6\u8282\u70b9\u4e0a\u6709\u7ec8\u7aef\u8282\u70b9\uff0c\u8be5\u670d\u52a1\u4e5f\u4f1a\u88ab\u89c6\u4e3a\u5728\u8be5\u8282\u70b9\u4e0a\u6ca1\u6709\u7ec8\u7aef\u8282\u70b9\uff08\u5bf9\u4e8e\u8be5\u8282\u70b9\u4e0a\u7684Pod\uff09\u3002 \u6f14\u793a\uff1a \u521b\u5efa Deployment my-nginx \u548c Service my-nginx . kubectl apply -f - << EOF apiVersion: apps/v1 kind: Deployment metadata: name: my-nginx spec: selector: matchLabels: run: my-nginx replicas: 1 template: metadata: labels: run: my-nginx spec: containers: - name: my-nginx image: nginx ports: - containerPort: 80 --- apiVersion: v1 kind: Service metadata: name: my-nginx labels: run: my-nginx spec: ports: - port: 80 protocol: TCP selector: run: my-nginx EOF \u4f7f\u7528\u547d\u4ee4 kubectl get pod -o wide \uff0c\u6211\u4eec\u53ef\u4ee5\u5f97\u77e5 Deployment my-nginx \u7684 Pod \u6b63\u5728\u8fd0\u884c\u5728 cka003 \u8282\u70b9\u4e0a\u3002 NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES my-nginx-cf54cdbf7-bscf8 1/1 Running 0 9h 10.244.112.63 cka002 \u8ba9\u6211\u4eec\u4ece cka001 \u53d1\u9001 http \u8bf7\u6c42\u5230\u8fd0\u884c\u5728 cka002 \u4e0a\u7684 Pod\u3002 \u6211\u4eec\u5c06\u6536\u5230 Welcome to nginx! \u4fe1\u606f\uff0c\u8fd9\u610f\u5473\u7740\u8be5 Pod \u53ef\u4ee5\u4ece\u5176\u4ed6\u8282\u70b9\u8bbf\u95ee\u3002 curl 11 .244.163.60 \u73b0\u5728\u6765\u4fee\u6539Service my-nginx \u5e76\u6307\u5b9a internalTrafficPolicy: Local \u3002 kubectl apply -f - << EOF apiVersion: v1 kind: Service metadata: name: my-nginx labels: run: my-nginx spec: ports: - port: 80 protocol: TCP selector: run: my-nginx internalTrafficPolicy: Local EOF Let's send http request from cka001 to the http request to the Pod again. We will receive curl: (7) Failed to connect to 11.244.163.60 port 80: Connection refused error information. \u6211\u4eec\u518d\u6b21\u4ece cka001 \u53d1\u9001http\u8bf7\u6c42\u5230\u8be5Pod\u3002 \u6211\u4eec\u5c06\u6536\u5230\u9519\u8bef\u4fe1\u606f curl: (7) Failed to connect to 11.244.163.60 port 80: Connection refused \u3002 curl 11 .244.163.60 \u8ba9\u6211\u4eec\u767b\u5f55\u5230 cka002 \u8282\u70b9\u5e76\u518d\u6b21\u5411 Pod \u53d1\u9001 HTTP \u8bf7\u6c42\u3002 \u6211\u4eec\u5c06\u6536\u5230 Welcome to nginx! \u7684\u4fe1\u606f\u3002 curl 11 .244.163.60 \u6f14\u793a\u7ed3\u8bba\uff1a \u8bbe\u7f6e Service \u7684 internalTrafficPolicy: Local \u540e\uff0cService \u53ea\u4f1a\u5c06\u6d41\u91cf\u8def\u7531\u5230\u5f53\u524d Pod \u6240\u5728\u7684\u8282\u70b9\u5185\u90e8\u7684 Pod\u3002 \u6f14\u793a\u573a\u666f\uff1a \u521b\u5efa\u4e00\u4e2a nginx Deployment \u6dfb\u52a0 nginx Pod\u7684\u7aef\u53e3\u53f7\u548c\u522b\u540d \u4f7f\u7528\u672c\u5730\u6d41\u91cf\u5c06Deployment\u66b4\u9732\u51fa\u53bb\u3002 \u6f14\u793a\uff1a \u4f7f\u7528\u7aef\u53e3\u53f7\u4e3a 80 \u521b\u5efa my-nginx Deployment\u3002 kubectl create deployment my-nginx --image = nginx --port = 80 \u4fee\u6539Deployment\u3002 kubectl edit deployment my-nginx \u5728 my-nginx Deployment\u4e2d\u6dfb\u52a0\u7aef\u53e3\u522b\u540d http \u3002 \u8bf7\u53c2\u8003\u4ee5\u4e0b\u90e8\u7f72\u7684 YAML \u6a21\u677f\u94fe\u63a5\uff1a https://kubernetes.io/docs/concepts/workloads/controllers/deployment/ \u3002 spec : containers : - image : nginx imagePullPolicy : Always name : nginx ports : - containerPort : 80 protocol : TCP name : http \u4f7f\u7528 NodePort \u7c7b\u578b\u66b4\u9732 deployment\u3002 kubectl expose deployment my-nginx --port = 80 --target-port = http --name = my-nginx-svc --type = NodePort \u4fee\u6539service\uff0c\u628a internalTrafficPolicy \u4ece Cluster \u6539\u4e3a Local \u3002 kubectl edit svc my-nginx-svc \u9a8c\u8bc1\u8bbf\u95ee\u3002 \u6ce8\u610f\uff0cPod \u6b63\u5728\u8fd0\u884c\u5728\u8282\u70b9 cka003 \u4e0a\u3002\u6211\u4eec\u5c06\u770b\u5230\u4ee5\u4e0b\u9884\u671f\u7ed3\u679c\u3002 curl :80 # succeed on node cka003. internalTrafficPolicy is effective. curl :80 # succeed on all nodes. curl : # succeed on all nodes.","title":"Service"},{"location":"k8s/cka_cn/foundamentals/service/#cka10service","text":"","title":"CKA\u81ea\u5b66\u7b14\u8bb010:Service"},{"location":"k8s/cka_cn/foundamentals/service/#_1","text":"\u6f14\u793a\u573a\u666f\uff1a \u521b\u5efa\u540d\u4e3a httpd-app \u7684Deployment\u3002 \u521b\u5efa\u7c7b\u578b\u4e3a ClusterIP \u7684 httpd-app \u670d\u52a1\uff0c\u9ed8\u8ba4\u7c7b\u578b\u662f ClusterIP\uff0c\u53ea\u80fd\u5185\u90e8\u8bbf\u95ee\u3002 \u9a8c\u8bc1\u5bf9Pod\u7684IP\u548c\u670d\u52a1\u7684\u96c6\u7fa4IP\u7684\u8bbf\u95ee\u3002 \u5c06 httpd-app \u670d\u52a1\u7c7b\u578b\u66f4\u65b0\u4e3a NodePort \uff0c\u4e0d\u9700\u8981\u5bf9 httpd-app \u8fd9\u4e2aDeployment\u8fdb\u884c\u4efb\u4f55\u66f4\u6539\u3002 \u9a8c\u8bc1\u8282\u70b9node\u7684\u8bbf\u95ee\u3002\u5bf9\u8282\u70b9node\u5bf9\u8bbf\u95ee\u5c06\u88ab\u8def\u7531\u5230Pod\uff0c\u4ece\u800c\u5b9e\u73b0\u4ece\u5916\u90e8\u8bbf\u95ee\u6211\u4eec\u521b\u5efa\u7684\u670d\u52a1 httpd-app \u3002 \u521b\u5efa\u65e0\u5934\u670d\u52a1\uff08Headless Service\uff09 web \u548c \u6709\u72b6\u6001\u526f\u672c\u96c6\uff08StatefulSet\uff09 web \u3002 \u670d\u52a1\u7684\u5185\u90e8\u6d41\u91cf\u7b56\u7565\u3002 NodePort \u53ef\u4ee5\u7ffb\u8bd1\u4e3a\u201c\u8282\u70b9\u7aef\u53e3\u201d\uff0c\u662f\u4e00\u79cdService\u7684\u7c7b\u578b\uff0c\u53ef\u4ee5\u901a\u8fc7\u5728\u6bcf\u4e2a\u8282\u70b9\u4e0a\u6253\u5f00\u4e00\u4e2a\u7aef\u53e3\uff0c\u5c06Service\u66b4\u9732\u5230\u96c6\u7fa4\u5916\u90e8\u3002 ClusterIP \u53ef\u4ee5\u7ffb\u8bd1\u4e3a\u201c\u96c6\u7fa4IP\u201d\uff0c\u4e5f\u662f\u4e00\u79cdService\u7684\u7c7b\u578b\uff0c\u4e3aService\u63d0\u4f9b\u4e86\u4e00\u4e2a\u865a\u62dfIP\u5730\u5740\uff0c\u53ef\u4ee5\u5728\u96c6\u7fa4\u5185\u90e8\u8fdb\u884c\u8bbf\u95ee\u3002\u8fd9\u4e2aIP\u5730\u5740\u901a\u5e38\u7531\u96c6\u7fa4\u4e2d\u7684Kubernetes\u4ee3\u7406\u81ea\u52a8\u5206\u914d\uff0c\u5e76\u4e14\u53ea\u80fd\u5728\u96c6\u7fa4\u5185\u90e8\u4f7f\u7528\u3002","title":"\u6458\u8981"},{"location":"k8s/cka_cn/foundamentals/service/#clusterip","text":"","title":"ClusterIP"},{"location":"k8s/cka_cn/foundamentals/service/#service","text":"\u521b\u5efaDeployment http-app \u3002 \u521b\u5efaService httpd-app \u5e76\u901a\u8fc7\u6807\u7b7e\u9009\u62e9\u5668\uff08Label Selector\uff09\u5173\u8054\u5230Development http-app \u3002 Service\u7684\u7c7b\u578b\u662f ClusterIP \uff0c\u8fd9\u662fService\u7684\u9ed8\u8ba4\u7c7b\u578b\uff0c\u53ea\u9650\u4e8e\u5185\u90e8\u8bbf\u95ee\u3002 kubectl apply -f - < 80/TCP 14s app=httpd NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES pod/httpd-app-6496d888c9-4nb6z 1/1 Running 0 77s 10.244.102.21 cka003 pod/httpd-app-6496d888c9-b7xht 1/1 Running 0 77s 10.244.112.19 cka002 \u6267\u884c\u4e0b\u9762\u7684\u547d\u4ee4\uff0c\u9a8c\u8bc1\u5bf9pod\u7684IP\u5730\u5740\u7684\u8bbf\u95ee\u3002 curl 10 .244.102.21 curl 10 .244.112.19 \u53ef\u4ee5\u5f97\u5230\u4e0b\u9762\u7684\u4fe1\u606f\uff0c\u8bf4\u660e\u8bbf\u95ee\u6210\u529f\u3002

It works!

\u6267\u884c\u4e0b\u9762\u7684\u547d\u4ee4\uff0c\u9a8c\u8bc1\u901a\u8fc7\u7aef\u53e3\u5bf9ClusterIP\u7684\u8bbf\u95ee\u3002 curl 11 .244.247.7:80 \u53ef\u4ee5\u5f97\u5230\u4e0b\u9762\u7684\u4fe1\u606f\uff0c\u8bf4\u660e\u8bbf\u95ee\u6210\u529f\u3002

It works!

","title":"\u521b\u5efaService"},{"location":"k8s/cka_cn/foundamentals/service/#service_1","text":"\u521b\u5efa\u4e00\u4e2a\u4e34\u65f6\u7684Pod nslookup \uff0c\u5e76\u9644\u52a0\u5230\u5b83\u4ee5\u9a8c\u8bc1DNS\u89e3\u6790\u3002\u9009\u9879 --rm \u8868\u793a\u5728\u9000\u51fa\u540e\u5220\u9664\u8be5Pod\u3002 kubectl run -it nslookup --rm --image = busybox:1.28 \u8fde\u63a5\u5230\u8fd9\u4e2aPod\u540e\uff0c\u8fd0\u884c\u547d\u4ee4 nslookup httpd-app \u3002\u6211\u4eec\u4f1a\u6536\u5230 httpd-app \u670d\u52a1\u7684 ClusterIP \u548c\u5b8c\u6574\u7684\u57df\u540d\u3002 / # nslookup httpd-app Server: 11.244.0.10 Address 1: 11.244.0.10 kube-dns.kube-system.svc.cluster.local Name: httpd-app Address 1: 11.244.247.7 httpd-app.dev.svc.cluster.local \u6211\u4eec\u53ef\u4ee5\u901a\u8fc7\u6267\u884c\u547d\u4ee4 kubectl get pod -o wide \u6765\u5728\u65b0\u7684\u7ec8\u7aef\u4e2d\u68c0\u67e5\u4e34\u65f6 Pod nslookup \u7684 IP \u5730\u5740\u3002Pod nslookup \u7684 IP \u5730\u5740\u4e3a 10.244.112.20 \u3002 kubectl get pod nslookup \u8fd0\u884c\u7ed3\u679c NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES nslookup 1/1 Running 0 2m44s 10.244.112.20 cka002 ","title":"\u66b4\u9732Service"},{"location":"k8s/cka_cn/foundamentals/service/#nodeport","text":"\u521b\u5efa\u5e76\u5e94\u7528\u6587\u4ef6 svc-nodeport.yaml \u6765\u521b\u5efaService httpd-app \u3002 kubectl apply -f - < will update configuration to existing resources. Here the Service httpd-app is changed from ClusterIP to NodePort type. No change to the Deployment httpd-app . \u6211\u4eec\u5c06\u6536\u5230\u4ee5\u4e0b\u8f93\u51fa\u3002 \u5176\u4e2d\uff0c\u547d\u4ee4 kubectl apply -f \u5c06\u66f4\u65b0\u73b0\u6709\u8d44\u6e90\u7684\u914d\u7f6e\u3002 \u5728\u8fd9\u91cc\uff0cService httpd-app \u4ece ClusterIP \u7c7b\u578b\u66f4\u6539\u4e3a NodePort \u7c7b\u578b\u3002 \u5bf9Deployment httpd-app \u6ca1\u6709\u4efb\u4f55\u66f4\u6539\u3002 service/httpd-app configured deployment.apps/httpd-app unchanged \u901a\u8fc7\u547d\u4ee4 kubectl get svc \u6765\u68c0\u67e5Service httpd-app \uff0c\u5176\u4e2d\uff1a Service\u7684IP\u5730\u5740\u4e0d\u53d8\u3002 Service\u7684\u7c7b\u578b\u53d8\u4e3a NodePort \u3002 Service\u7684\u7aef\u53e3\u53f7\u4ece 80/TCP \u53d8\u4e3a 80:30080/TCP \u3002 NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE httpd-app NodePort 11.244.247.7 80:30080/TCP 18m \u5728\u6bcf\u4e2a\u8282\u70b9node\u4e0a\u6267\u884c\u547d\u4ee4 curl :30080 \uff0c\u6d4b\u8bd5\u5bf9Service httpd-app \u7684\u8054\u901a\u6027\u3002 curl :30080 curl :30080 curl :30080 \u53ef\u4ee5\u5f97\u5230\u4e0b\u9762\u7684\u4fe1\u606f\uff0c\u8bf4\u660e\u8bbf\u95ee\u6210\u529f\u3002

It works!

","title":"NodePort"},{"location":"k8s/cka_cn/foundamentals/service/#headless-service","text":"\u521b\u5efaHeadless Service web \u548cStatefulSet web . kubectl apply -f - < web-1 1/1 Running 0 6s 10.244.112.21 cka002 \u6267\u884c\u547d\u4ee4 kubectl describe svc -l app=web \uff0c\u68c0\u67e5\u521b\u5efa\u7684Service\u7684\u8be6\u7ec6\u4fe1\u606f\u3002 Name : web Namespace : dev Labels : app=web Annotations : Selector : app=web Type : ClusterIP IP Family Policy : SingleStack IP Families : IPv4 IP : None IPs : None Port : web 80/TCP TargetPort : 80/TCP Endpoints : 10.244.102.22:80,10.244.112.21:80 Session Affinity : None Events : \u8fde\u63a5\u5230\u4e34\u65f6Pod nslookup \uff0c\u901a\u8fc7 nslookup \u6765\u9a8c\u8bc1DNS\u5230\u89e3\u6790\u3002 kubectl run -it nslookup --rm --image = busybox:1.28 \u901a\u8fc7 nslookup \u547d\u4ee4\u8bbf\u95eeHeadless Service web \uff0c\u6211\u4eec\u53ef\u4ee5\u5f97\u52302\u4e2apod\u7684IP\u5730\u5740\uff0c\u6ce8\u610f\u4e0d\u662f\u96c6\u7fa4IP\u5730\u5740ClusterIP\uff08\u56e0\u4e3a\u662fHeadless Service\uff09\u3002 / # nslookup web Server: 11.244.0.10 Address 1: 11.244.0.10 kube-dns.kube-system.svc.cluster.local Name: web Address 1: 10.244.112.21 web-1.web.dev.svc.cluster.local Address 2: 10.244.102.22 web-0.web.dev.svc.cluster.local \u6211\u4eec\u4e5f\u53ef\u4ee5\u4f7f\u7528 nslookup \u547d\u4ee4\u6765\u67e5\u627e web-0.web \u548c web-1.web \u3002Headless Service\u7684\u6bcf\u4e2a Pod \u90fd\u6709\u81ea\u5df1\u7684\u670d\u52a1\u540d\u79f0\u7528\u4e8e DNS \u67e5\u627e\u3002 / # nslookup web-0.web Server: 11.244.0.10 Address 1: 11.244.0.10 kube-dns.kube-system.svc.cluster.local Name: web-0.web Address 1: 10.244.102.22 web-0.web.dev.svc.cluster.local / # nslookup web-1.web Server: 11.244.0.10 Address 1: 11.244.0.10 kube-dns.kube-system.svc.cluster.local Name: web-1.web Address 1: 10.244.112.21 web-1.web.dev.svc.cluster.local \u5220\u9664\u4e0a\u9762\u521b\u5efa\u7684\u4e34\u65f6\u8d44\u6e90\u3002 kubectl delete sts web kubectl delete service httpd-app web kubectl delete deployment httpd-app","title":"Headless Service"},{"location":"k8s/cka_cn/foundamentals/service/#_2","text":"Service Internal Traffic Policy\uff08\u670d\u52a1\u5185\u90e8\u6d41\u91cf\u7b56\u7565\uff09\u662fKubernetes\u4e2d\u4e00\u79cd\u7528\u4e8e\u63a7\u5236\u670d\u52a1\u5185\u90e8\u6d41\u91cf\u7684\u7b56\u7565\u3002\u5b83\u7684\u4e3b\u8981\u76ee\u7684\u662f\u63a7\u5236Service\u5bf9\u8c61\u4e2dPod\u7684\u8bbf\u95ee\u7b56\u7565\u3002 \u5728Kubernetes\u4e2d\uff0cService\u5bf9\u8c61\u5c06\u4e00\u4e2a\u865a\u62dfIP\u5730\u5740\u7ed1\u5b9a\u5230\u4e00\u7ec4Pod\u4e0a\uff0c\u4ee5\u4fbf\u53ef\u4ee5\u901a\u8fc7\u8fd9\u4e2a\u865a\u62dfIP\u5730\u5740\u6765\u8bbf\u95ee\u8fd9\u7ec4Pod\u3002Service\u5bf9\u8c61\u5728\u67d0\u79cd\u7a0b\u5ea6\u4e0a\u50cf\u8d1f\u8f7d\u5747\u8861\u5668\uff0c\u53ef\u4ee5\u5c06\u8bf7\u6c42\u6d41\u91cf\u8def\u7531\u5230\u5176\u4e0b\u9762\u7684Pod\u3002 Service\u5bf9\u8c61\u901a\u5e38\u4f1a\u4f7f\u7528\u4ee5\u4e0b\u4e24\u79cd\u7c7b\u578b\u4e4b\u4e00\u6765\u8def\u7531\u6d41\u91cf\uff1a ClusterIP\uff1a\u6b64\u7c7b\u578b\u7684Service\u53ea\u80fd\u4ece\u540c\u4e00Kubernetes\u96c6\u7fa4\u5185\u7684\u5176\u4ed6Pod\u8bbf\u95ee\uff0c\u56e0\u4e3a\u5b83\u662f\u5728Kubernetes\u96c6\u7fa4\u5185\u90e8\u8def\u7531\u8bf7\u6c42\u6d41\u91cf\u7684\u3002 NodePort\uff1a\u6b64\u7c7b\u578b\u7684Service\u5728\u6240\u6709\u8282\u70b9\u4e0a\u516c\u5f00\u4e86\u4e00\u4e2a\u9759\u6001\u7aef\u53e3\uff0c\u4ece\u800c\u53ef\u4ee5\u4ece\u96c6\u7fa4\u5916\u90e8\u8bbf\u95ee\u5b83\u3002\u4f46\u662f\uff0c\u5b83\u4ecd\u7136\u53ef\u4ee5\u4ece\u96c6\u7fa4\u5185\u90e8\u8bbf\u95ee\u3002 Service Internal Traffic Policy\u5b9a\u4e49\u4e86Pod\u5982\u4f55\u8bbf\u95ee\u540c\u4e00\u4e2aService\u4e2d\u7684\u5176\u4ed6Pod\u3002\u53ef\u4ee5\u5c06\u5176\u8bbe\u7f6e\u4e3a\u4ee5\u4e0b\u4e09\u4e2a\u9009\u9879\u4e4b\u4e00\uff1a Cluster\uff1a\u8fd9\u662f\u9ed8\u8ba4\u8bbe\u7f6e\uff0c\u5b83\u5141\u8bb8Service\u4e2d\u7684\u4efb\u4f55Pod\u90fd\u53ef\u4ee5\u8bbf\u95ee\u53e6\u4e00\u4e2aPod\u3002 Local\uff1a\u6b64\u9009\u9879\u5141\u8bb8Pod\u4ec5\u8bbf\u95ee\u5728\u540c\u4e00\u8282\u70b9\u4e0a\u8fd0\u884c\u7684\u5176\u4ed6Pod\u3002\u5982\u679cPod\u9700\u8981\u5feb\u901f\u7684\u3001\u4f4e\u5ef6\u8fdf\u7684\u7f51\u7edc\u8bbf\u95ee\uff0c\u53ef\u4ee5\u4f7f\u7528\u6b64\u9009\u9879\u3002 Disabled\uff1a\u6b64\u9009\u9879\u5c06\u5b8c\u5168\u7981\u6b62Service\u5185\u90e8\u7684\u6d41\u91cf\u3002\u5b83\u9002\u7528\u4e8e\u7279\u5b9a\u7684\u73af\u5883\u548c\u90e8\u7f72\u4e2d\u3002 \u6f14\u793a\u573a\u666f\uff1a \u6a21\u62df Service \u5185\u90e8\u6d41\u91cf\u7b56\u7565\u7684\u5de5\u4f5c\u65b9\u5f0f\u3002 \u9884\u671f\u7ed3\u679c\uff1a \u901a\u8fc7\u8bbe\u7f6e Service \u7684 internalTrafficPolicy: Local \uff0cService \u53ea\u4f1a\u5c06\u6d41\u91cf\u8def\u7531\u5230 Pod \u6240\u5728\u7684\u8282\u70b9\u5185\u90e8\u3002 \u6f14\u793a\u76ee\u7684\uff1a Service Internal Traffic Policy\uff08\u670d\u52a1\u5185\u90e8\u6d41\u91cf\u7b56\u7565\uff09\u53ef\u4ee5\u9650\u5236\u5185\u90e8\u6d41\u91cf\u4ec5\u8def\u7531\u5230\u540c\u4e00\u8282\u70b9\u4e2d\u7684\u7ec8\u7aef\u8282\u70b9\u3002 \u8fd9\u91cc\u7684\u201c\u5185\u90e8\u201d\u6d41\u91cf\u662f\u6307\u6e90\u81ea\u5f53\u524d\u96c6\u7fa4\u4e2d\u7684Pod\u7684\u6d41\u91cf\u3002 \u901a\u8fc7\u5c06\u5176 .spec.internalTrafficPolicy \u8bbe\u7f6e\u4e3a Local\uff0c\u53ef\u4ee5\u544a\u8bc9 kube-proxy \u4ec5\u5bf9\u96c6\u7fa4\u5185\u90e8\u6d41\u91cf\u4f7f\u7528\u672c\u5730\u8282\u70b9\u7684\u7ec8\u7aef\u8282\u70b9\u3002 \u5bf9\u4e8e\u4f4d\u4e8e\u6ca1\u6709\u7ed9\u5b9a\u670d\u52a1\u7684\u7ec8\u7aef\u8282\u70b9\u7684\u8282\u70b9\u4e0a\u7684Pod\uff0c\u5373\u4f7f\u670d\u52a1\u5728\u5176\u4ed6\u8282\u70b9\u4e0a\u6709\u7ec8\u7aef\u8282\u70b9\uff0c\u8be5\u670d\u52a1\u4e5f\u4f1a\u88ab\u89c6\u4e3a\u5728\u8be5\u8282\u70b9\u4e0a\u6ca1\u6709\u7ec8\u7aef\u8282\u70b9\uff08\u5bf9\u4e8e\u8be5\u8282\u70b9\u4e0a\u7684Pod\uff09\u3002 \u6f14\u793a\uff1a \u521b\u5efa Deployment my-nginx \u548c Service my-nginx . kubectl apply -f - << EOF apiVersion: apps/v1 kind: Deployment metadata: name: my-nginx spec: selector: matchLabels: run: my-nginx replicas: 1 template: metadata: labels: run: my-nginx spec: containers: - name: my-nginx image: nginx ports: - containerPort: 80 --- apiVersion: v1 kind: Service metadata: name: my-nginx labels: run: my-nginx spec: ports: - port: 80 protocol: TCP selector: run: my-nginx EOF \u4f7f\u7528\u547d\u4ee4 kubectl get pod -o wide \uff0c\u6211\u4eec\u53ef\u4ee5\u5f97\u77e5 Deployment my-nginx \u7684 Pod \u6b63\u5728\u8fd0\u884c\u5728 cka003 \u8282\u70b9\u4e0a\u3002 NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES my-nginx-cf54cdbf7-bscf8 1/1 Running 0 9h 10.244.112.63 cka002 \u8ba9\u6211\u4eec\u4ece cka001 \u53d1\u9001 http \u8bf7\u6c42\u5230\u8fd0\u884c\u5728 cka002 \u4e0a\u7684 Pod\u3002 \u6211\u4eec\u5c06\u6536\u5230 Welcome to nginx! \u4fe1\u606f\uff0c\u8fd9\u610f\u5473\u7740\u8be5 Pod \u53ef\u4ee5\u4ece\u5176\u4ed6\u8282\u70b9\u8bbf\u95ee\u3002 curl 11 .244.163.60 \u73b0\u5728\u6765\u4fee\u6539Service my-nginx \u5e76\u6307\u5b9a internalTrafficPolicy: Local \u3002 kubectl apply -f - << EOF apiVersion: v1 kind: Service metadata: name: my-nginx labels: run: my-nginx spec: ports: - port: 80 protocol: TCP selector: run: my-nginx internalTrafficPolicy: Local EOF Let's send http request from cka001 to the http request to the Pod again. We will receive curl: (7) Failed to connect to 11.244.163.60 port 80: Connection refused error information. \u6211\u4eec\u518d\u6b21\u4ece cka001 \u53d1\u9001http\u8bf7\u6c42\u5230\u8be5Pod\u3002 \u6211\u4eec\u5c06\u6536\u5230\u9519\u8bef\u4fe1\u606f curl: (7) Failed to connect to 11.244.163.60 port 80: Connection refused \u3002 curl 11 .244.163.60 \u8ba9\u6211\u4eec\u767b\u5f55\u5230 cka002 \u8282\u70b9\u5e76\u518d\u6b21\u5411 Pod \u53d1\u9001 HTTP \u8bf7\u6c42\u3002 \u6211\u4eec\u5c06\u6536\u5230 Welcome to nginx! \u7684\u4fe1\u606f\u3002 curl 11 .244.163.60 \u6f14\u793a\u7ed3\u8bba\uff1a \u8bbe\u7f6e Service \u7684 internalTrafficPolicy: Local \u540e\uff0cService \u53ea\u4f1a\u5c06\u6d41\u91cf\u8def\u7531\u5230\u5f53\u524d Pod \u6240\u5728\u7684\u8282\u70b9\u5185\u90e8\u7684 Pod\u3002 \u6f14\u793a\u573a\u666f\uff1a \u521b\u5efa\u4e00\u4e2a nginx Deployment \u6dfb\u52a0 nginx Pod\u7684\u7aef\u53e3\u53f7\u548c\u522b\u540d \u4f7f\u7528\u672c\u5730\u6d41\u91cf\u5c06Deployment\u66b4\u9732\u51fa\u53bb\u3002 \u6f14\u793a\uff1a \u4f7f\u7528\u7aef\u53e3\u53f7\u4e3a 80 \u521b\u5efa my-nginx Deployment\u3002 kubectl create deployment my-nginx --image = nginx --port = 80 \u4fee\u6539Deployment\u3002 kubectl edit deployment my-nginx \u5728 my-nginx Deployment\u4e2d\u6dfb\u52a0\u7aef\u53e3\u522b\u540d http \u3002 \u8bf7\u53c2\u8003\u4ee5\u4e0b\u90e8\u7f72\u7684 YAML \u6a21\u677f\u94fe\u63a5\uff1a https://kubernetes.io/docs/concepts/workloads/controllers/deployment/ \u3002 spec : containers : - image : nginx imagePullPolicy : Always name : nginx ports : - containerPort : 80 protocol : TCP name : http \u4f7f\u7528 NodePort \u7c7b\u578b\u66b4\u9732 deployment\u3002 kubectl expose deployment my-nginx --port = 80 --target-port = http --name = my-nginx-svc --type = NodePort \u4fee\u6539service\uff0c\u628a internalTrafficPolicy \u4ece Cluster \u6539\u4e3a Local \u3002 kubectl edit svc my-nginx-svc \u9a8c\u8bc1\u8bbf\u95ee\u3002 \u6ce8\u610f\uff0cPod \u6b63\u5728\u8fd0\u884c\u5728\u8282\u70b9 cka003 \u4e0a\u3002\u6211\u4eec\u5c06\u770b\u5230\u4ee5\u4e0b\u9884\u671f\u7ed3\u679c\u3002 curl :80 # succeed on node cka003. internalTrafficPolicy is effective. curl :80 # succeed on all nodes. curl : # succeed on all nodes.","title":"\u670d\u52a1\u5185\u90e8\u6d41\u91cf\u7b56\u7565"},{"location":"k8s/cka_cn/foundamentals/statefulset/","text":"CKA\u81ea\u5b66\u7b14\u8bb012:StatefulSet \u00b6 \u6f14\u793a\u573a\u666f \u00b6 \u521b\u5efa\u4e00\u4e2a Headless Service nginx \u548c\u4e00\u4e2aStatefulSet web \u6269\u5c55 StatefulSet web \u6f14\u793a \u00b6 \u521b\u5efa\u4e00\u4e2a Headless Service nginx \u548c\u4e00\u4e2aStatefulSet web kubectl apply -f - << EOF --- apiVersion: v1 kind: Service metadata: name: nginx labels: app: nginx spec: ports: - port: 80 name: web clusterIP: None selector: app: nginx --- apiVersion: apps/v1 kind: StatefulSet metadata: name: web spec: serviceName: \"nginx\" replicas: 2 selector: matchLabels: app: nginx template: metadata: labels: app: nginx spec: containers: - name: nginx image: nginx ports: - containerPort: 80 name: web EOF \u8bfb\u53d6\u4e0a\u4e00\u6b65\u521b\u5efa\u7684StatefulSet Pod \u7684\u8be6\u7ec6\u4fe1\u606f\u3002 kubectl get pod | grep web \u8fd0\u884c\u7ed3\u679c NAME READY STATUS RESTARTS AGE web-0 1 /1 Running 0 27s web-1 1 /1 Running 0 10s \u4f7f\u7528\u547d\u4ee4 kubectl edit sts web \u66f4\u65b0\u73b0\u6709\u7684 StatefulSet\u3002 \u53ea\u6709\u4ee5\u4e0b\u5b57\u6bb5\u53ef\u4ee5\u66f4\u65b0\uff1a replicas \u3001 image \u3001 rolling updates \u3001 labels \u3001 resource request/limit \u548c annotations \u3002 \u6ce8\u610f\uff1a\u5f53 StatefulSet Pod \u5728\u5f53\u524d\u8282\u70b9\u4e2d\u6b7b\u4ea1\u65f6\uff0c\u4e0d\u4f1a\u81ea\u52a8\u5728\u5176\u4ed6\u8282\u70b9\u4e2d\u521b\u5efa\u526f\u672c\u3002 \u6269\u5c55 StatefulSet\u3002 \u5c06 StatefulSet web \u7684\u526f\u672c\u6570\u6269\u5c55\u5230 5 \u3002 kubectl scale sts web --replicas = 5 \u53c2\u8003\uff1a Partition\u8868\u793a\u5728\u66f4\u65b0\u671f\u95f4\u5e94\u5c06 StatefulSet \u5212\u5206\u4e3a\u54ea\u4e2a\u5e8f\u53f7\u3002 \u5728\u6eda\u52a8\u66f4\u65b0\u671f\u95f4\uff0c\u4ece\u5e8f\u53f7 Replicas-1 \u5230 Partition \u7684\u6240\u6709 Pod \u90fd\u4f1a\u66f4\u65b0\u3002 \u4ece\u5e8f\u53f7 Partition-1 \u5230 0 \u7684\u6240\u6709 Pod \u90fd\u4fdd\u6301\u4e0d\u53d8\u3002\u8fd9\u5bf9\u4e8e\u8fdb\u884c\u91d1\u4e1d\u96c0\u90e8\u7f72\u975e\u5e38\u6709\u7528\u3002\u9ed8\u8ba4\u503c\u4e3a0\u3002 \u547d\u4ee4\uff1a kubectl explain statefulsets.spec.updateStrategy.rollingUpdate.partition \u91d1\u4e1d\u96c0\u90e8\u7f72\u662f\u4e00\u79cd\u8f6f\u4ef6\u90e8\u7f72\u6280\u672f\uff0c\u5176\u4e2d\u5728\u5c06\u65b0\u529f\u80fd\u6216\u7248\u672c\u53d1\u5e03\u7ed9\u66f4\u5927\u7684\u7528\u6237\u5b50\u96c6\u6216\u6240\u6709\u7528\u6237\u4e4b\u524d\uff0c\u5148\u5c06\u5176\u53d1\u5e03\u7ed9\u751f\u4ea7\u4e2d\u7684\u4e00\u5c0f\u90e8\u5206\u7528\u6237\u3002 \u8fd9\u79cd\u6280\u672f\u662f\u4f4e\u98ce\u9669\u7684\uff0c\u56e0\u4e3a\u65b0\u529f\u80fd\u6700\u521d\u53ea\u90e8\u7f72\u7ed9\u5c11\u91cf\u7528\u6237\u3002 \"Canary\"\u4e00\u8bcd\u6e90\u81ea\u65e7\u7684\u7164\u77ff\u6280\u672f\uff0c\u5f53\u65f6\u91d1\u4e1d\u96c0\u88ab\u7528\u4f5c\u7a7a\u6c14\u4e2d\u6bd2\u7d20\u7684\u65e9\u671f\u63a2\u6d4b\u5668\u3002 \u5728\u91d1\u4e1d\u96c0\u90e8\u7f72\u4e2d\uff0c\u76ee\u6807\u73af\u5883\u4e2d\u7684\u6240\u6709\u57fa\u7840\u8bbe\u65bd\u90fd\u4f1a\u4ee5\u5c0f\u9636\u6bb5\u8fdb\u884c\u66f4\u65b0\u3002 \u5b83\u7528\u4e8e\u6d4b\u8bd5\u65b0\u529f\u80fd\u548c\u5347\u7ea7\u4ee5\u67e5\u770b\u5b83\u4eec\u5982\u4f55\u5904\u7406\u751f\u4ea7\u73af\u5883\u3002 \u5220\u9664\u6240\u521b\u5efa\u7684\u8d44\u6e90\u3002 kubectl delete sts web kubectl delete service nginx","title":"StatefulSet"},{"location":"k8s/cka_cn/foundamentals/statefulset/#cka12statefulset","text":"","title":"CKA\u81ea\u5b66\u7b14\u8bb012:StatefulSet"},{"location":"k8s/cka_cn/foundamentals/statefulset/#_1","text":"\u521b\u5efa\u4e00\u4e2a Headless Service nginx \u548c\u4e00\u4e2aStatefulSet web \u6269\u5c55 StatefulSet web","title":"\u6f14\u793a\u573a\u666f"},{"location":"k8s/cka_cn/foundamentals/statefulset/#_2","text":"\u521b\u5efa\u4e00\u4e2a Headless Service nginx \u548c\u4e00\u4e2aStatefulSet web kubectl apply -f - << EOF --- apiVersion: v1 kind: Service metadata: name: nginx labels: app: nginx spec: ports: - port: 80 name: web clusterIP: None selector: app: nginx --- apiVersion: apps/v1 kind: StatefulSet metadata: name: web spec: serviceName: \"nginx\" replicas: 2 selector: matchLabels: app: nginx template: metadata: labels: app: nginx spec: containers: - name: nginx image: nginx ports: - containerPort: 80 name: web EOF \u8bfb\u53d6\u4e0a\u4e00\u6b65\u521b\u5efa\u7684StatefulSet Pod \u7684\u8be6\u7ec6\u4fe1\u606f\u3002 kubectl get pod | grep web \u8fd0\u884c\u7ed3\u679c NAME READY STATUS RESTARTS AGE web-0 1 /1 Running 0 27s web-1 1 /1 Running 0 10s \u4f7f\u7528\u547d\u4ee4 kubectl edit sts web \u66f4\u65b0\u73b0\u6709\u7684 StatefulSet\u3002 \u53ea\u6709\u4ee5\u4e0b\u5b57\u6bb5\u53ef\u4ee5\u66f4\u65b0\uff1a replicas \u3001 image \u3001 rolling updates \u3001 labels \u3001 resource request/limit \u548c annotations \u3002 \u6ce8\u610f\uff1a\u5f53 StatefulSet Pod \u5728\u5f53\u524d\u8282\u70b9\u4e2d\u6b7b\u4ea1\u65f6\uff0c\u4e0d\u4f1a\u81ea\u52a8\u5728\u5176\u4ed6\u8282\u70b9\u4e2d\u521b\u5efa\u526f\u672c\u3002 \u6269\u5c55 StatefulSet\u3002 \u5c06 StatefulSet web \u7684\u526f\u672c\u6570\u6269\u5c55\u5230 5 \u3002 kubectl scale sts web --replicas = 5 \u53c2\u8003\uff1a Partition\u8868\u793a\u5728\u66f4\u65b0\u671f\u95f4\u5e94\u5c06 StatefulSet \u5212\u5206\u4e3a\u54ea\u4e2a\u5e8f\u53f7\u3002 \u5728\u6eda\u52a8\u66f4\u65b0\u671f\u95f4\uff0c\u4ece\u5e8f\u53f7 Replicas-1 \u5230 Partition \u7684\u6240\u6709 Pod \u90fd\u4f1a\u66f4\u65b0\u3002 \u4ece\u5e8f\u53f7 Partition-1 \u5230 0 \u7684\u6240\u6709 Pod \u90fd\u4fdd\u6301\u4e0d\u53d8\u3002\u8fd9\u5bf9\u4e8e\u8fdb\u884c\u91d1\u4e1d\u96c0\u90e8\u7f72\u975e\u5e38\u6709\u7528\u3002\u9ed8\u8ba4\u503c\u4e3a0\u3002 \u547d\u4ee4\uff1a kubectl explain statefulsets.spec.updateStrategy.rollingUpdate.partition \u91d1\u4e1d\u96c0\u90e8\u7f72\u662f\u4e00\u79cd\u8f6f\u4ef6\u90e8\u7f72\u6280\u672f\uff0c\u5176\u4e2d\u5728\u5c06\u65b0\u529f\u80fd\u6216\u7248\u672c\u53d1\u5e03\u7ed9\u66f4\u5927\u7684\u7528\u6237\u5b50\u96c6\u6216\u6240\u6709\u7528\u6237\u4e4b\u524d\uff0c\u5148\u5c06\u5176\u53d1\u5e03\u7ed9\u751f\u4ea7\u4e2d\u7684\u4e00\u5c0f\u90e8\u5206\u7528\u6237\u3002 \u8fd9\u79cd\u6280\u672f\u662f\u4f4e\u98ce\u9669\u7684\uff0c\u56e0\u4e3a\u65b0\u529f\u80fd\u6700\u521d\u53ea\u90e8\u7f72\u7ed9\u5c11\u91cf\u7528\u6237\u3002 \"Canary\"\u4e00\u8bcd\u6e90\u81ea\u65e7\u7684\u7164\u77ff\u6280\u672f\uff0c\u5f53\u65f6\u91d1\u4e1d\u96c0\u88ab\u7528\u4f5c\u7a7a\u6c14\u4e2d\u6bd2\u7d20\u7684\u65e9\u671f\u63a2\u6d4b\u5668\u3002 \u5728\u91d1\u4e1d\u96c0\u90e8\u7f72\u4e2d\uff0c\u76ee\u6807\u73af\u5883\u4e2d\u7684\u6240\u6709\u57fa\u7840\u8bbe\u65bd\u90fd\u4f1a\u4ee5\u5c0f\u9636\u6bb5\u8fdb\u884c\u66f4\u65b0\u3002 \u5b83\u7528\u4e8e\u6d4b\u8bd5\u65b0\u529f\u80fd\u548c\u5347\u7ea7\u4ee5\u67e5\u770b\u5b83\u4eec\u5982\u4f55\u5904\u7406\u751f\u4ea7\u73af\u5883\u3002 \u5220\u9664\u6240\u521b\u5efa\u7684\u8d44\u6e90\u3002 kubectl delete sts web kubectl delete service nginx","title":"\u6f14\u793a"},{"location":"k8s/cka_cn/foundamentals/troubleshooting/","text":"CKA\u81ea\u5b66\u7b14\u8bb025:Troubleshooting \u00b6 \u4e8b\u4ef6 \u00b6 \u6f14\u793a\u573a\u666f\uff1a \u63cf\u8ff0pod\u4ee5\u83b7\u53d6\u4e8b\u4ef6\u4fe1\u606f\u3002 \u6f14\u793a\uff1a \u547d\u4ee4\u7528\u6cd5\uff1a kubectl describe --namespace = \u67e5\u8be2pod\u7684\u4e8b\u4ef6\u4fe1\u606f\u3002 \u521b\u5efa\u4e00\u4e2aTomcat\u7684pod\u3002 kubectl run tomcat --image = tomcat \u67e5\u8be2pod\u7684\u4e8b\u4ef6\u4fe1\u606f\u3002 kubectl describe pod/tomcat \u5f97\u5230\u7c7b\u4f3c\u4e0b\u9762\u7684\u4e8b\u4ef6\u4fe1\u606f\u3002 Events: Type Reason Age From Message ---- ------ ---- ---- ------- Normal Scheduled 55s default-scheduler Successfully assigned dev/tomcat to cka002 Normal Pulling 54s kubelet Pulling image \"tomcat\" Normal Pulled 21s kubelet Successfully pulled image \"tomcat\" in 33.134162692s Normal Created 19s kubelet Created container tomcat Normal Started 19s kubelet Started container tomcat \u67e5\u8be2namespace\u7684\u4e8b\u4ef6\u4fe1\u606f\u3002 kubectl get events -n \u5f97\u5230\u7c7b\u4f3c\u4e0b\u9762\u7684\u9ed8\u8ba4namespace\u7684\u4e8b\u4ef6\u4fe1\u606f\u3002 LAST SEEN TYPE REASON OBJECT MESSAGE 70s Warning FailedGetScale horizontalpodautoscaler/nginx deployments/scale.apps \"podinfo\" not found 2m16s Normal Scheduled pod/tomcat Successfully assigned dev/tomcat to cka002 2m15s Normal Pulling pod/tomcat Pulling image \"tomcat\" 102s Normal Pulled pod/tomcat Successfully pulled image \"tomcat\" in 33.134162692s 100s Normal Created pod/tomcat Created container tomcat 100s Normal Started pod/tomcat Started container tomcat \u5f97\u5230\u7c7b\u4f3c\u4e0b\u9762\u7684\u6240\u6709\u7684namespace\u7684\u4e8b\u4ef6\u4fe1\u606f\u3002 kubectl get events -A \u65e5\u5fd7 \u00b6 \u6f14\u793a\u573a\u666f\uff1a \u67e5\u8be2pod\u7684\u65e5\u5fd7 \u547d\u4ee4\u7528\u6cd5\uff1a kubectl logs -n \u9009\u9879\uff1a --tail : \u663e\u793a\u8f93\u51fa\u7684\u6700\u8fd1 \u884c\u3002 -f \uff1a\u5b9e\u65f6\u6d41\u5f0f\u663e\u793a\u8f93\u51fa\u3002 \u663e\u793a\u8f93\u51fa\u7684\u6700\u8fd1100\u884c\u8f93\u51fa\u3002 kubectl logs -f tomcat --tail 100 \u5982\u679c\u662f\u4e00\u4e2a\u591a\u5bb9\u5668pod\uff0c\u5219\u4f7f\u7528\u9009\u9879 -c \u6765\u6307\u5b9a\u67d0\u4e2a\u7279\u5b9a\u7684\u5bb9\u5668\u3002 kubectl logs -f tomcat --tail 100 -c tomcat \u8282\u70b9\u53ef\u7528\u6027 \u00b6 \u67e5\u770b\u53ef\u7528\u8282\u70b9 \u00b6 \u6f14\u793a\u573a\u666f\uff1a \u67e5\u770b\u8282\u70b9\u53ef\u7528\u6027 \u6f14\u793a\uff1a \u65b9\u5f0f1\uff1a kubectl describe node | grep -i taint \u624b\u5de5\u65b9\u5f0f\u68c0\u67e5\u65e5\u5fd7\uff0c\u4e0b\u9762\u7684\u4f8b\u5b50\u8bf4\u660e2\u4e2a\u8282\u70b9\u5904\u4e8e\u4e0d\u53ef\u7528\u72b6\u6001\u3002 Taints : node-role.kubernetes.io/control-plane:NoSchedule Taints : Taints : \u65b9\u5f0f2\uff1a kubectl describe node | grep -i taint | grep -vc NoSchedule \u8fd9\u91cc\u6211\u4eec\u4f1a\u5f97\u5230\u76f8\u540c\u7684\u7ed3\u679c\uff0c2\u4e2a\u8282\u70b9\u5904\u4e8e\u4e0d\u53ef\u7528\u72b6\u6001\u3002\u8fd9\u91cc\u7684 -v \u8868\u793a\u6392\u9664\uff0c -c \u8868\u793a\u8ba1\u6570\u3002 \u67e5\u770b\u4e0d\u53ef\u7528\u8282\u70b9 \u00b6 \u6f14\u793a\u573a\u666f\uff1a \u5f53\u6211\u4eec\u5728Worker\u8282\u70b9 cka002 \u4e0a\u505c\u6b62 kubelet \u670d\u52a1\u65f6\uff0c \u6bcf\u4e2a\u8282\u70b9\u7684\u72b6\u6001\u662f\u4ec0\u4e48\uff1f \u901a\u8fc7 nerdctl \u547d\u4ee4\u66f4\u6539\u4e86\u54ea\u4e9b\u5bb9\u5668\uff1f \u901a\u8fc7\u547d\u4ee4 kubectl get pod -owide -A \u67e5\u770b\u7684Pod\u72b6\u6001\u662f\u4ec0\u4e48\uff1f \u6f14\u793a\uff1a \u5728 cka002 \u8282\u70b9\u4e0a\u6267\u884c\u547d\u4ee4 systemctl stop kubelet.service \u3002 \u5728 cka001 \u6216 cka003 \u4e0a\u6267\u884c\u547d\u4ee4 kubectl get node \uff0c\u53ef\u4ee5\u770b\u5230 cka002 \u7684\u72b6\u6001\u4ece Ready \u53d8\u4e3a NotReady \u3002 \u5728 cka002 \u4e0a\u6267\u884c\u547d\u4ee4 nerdctl -n k8s.io container ls \uff0c\u53ef\u4ee5\u770b\u5230\u6240\u6709\u5bb9\u5668\u90fd\u4ecd\u5728\u8fd0\u884c\uff0c\u5305\u62ecPod my-first-pod \u3002 \u5728 cka002 \u4e0a\u6267\u884c\u547d\u4ee4 systemctl start kubelet.service \u3002 \u7ed3\u8bba\uff1a \u8282\u70b9\u72b6\u6001\u7531 Ready \u53d8\u4e3a NotReady \u3002 \u5bf9\u4e8e\u90a3\u4e9b\u7c7b\u4f3c calico \u3001 kube-proxy \u8fd9\u6837\u7684 DaemonSet Pod\uff0c\u5b83\u4eec\u4e13\u95e8\u5728\u6bcf\u4e2a\u8282\u70b9\u4e0a\u8fd0\u884c\u3002\u5728 kubelet \u505c\u6b62\u540e\u5b83\u4eec\u4e0d\u4f1a\u88ab\u7ec8\u6b62\u3002 Pod my-first-pod \u7684\u72b6\u6001\u5728\u6bcf\u4e2a\u8282\u70b9\u4e0a\u4ecd\u7136\u663e\u793a\u4e3a Terminating \uff0c\u56e0\u4e3a\u72b6\u6001\u65e0\u6cd5\u901a\u8fc7 apiserver \u4ece cka002 \u540c\u6b65\u5230\u5176\u4ed6\u8282\u70b9\uff0c\u56e0\u4e3a kubelet \u5df2\u505c\u6b62\u3002 Pod\u7684\u72b6\u6001\u7531\u63a7\u5236\u5668\u6807\u8bb0\u5e76\u7531 kubelet \u56de\u6536\u3002 \u5f53\u6211\u4eec\u5728 cka003 \u4e0a\u542f\u52a8 kubelet \u670d\u52a1\u65f6\uff0cPod my-first-pod \u5c06\u5b8c\u5168\u5728 cka002 \u4e0a\u88ab\u7ec8\u6b62\u3002 \u6b64\u5916\uff0c\u8ba9\u6211\u4eec\u521b\u5efa\u4e00\u4e2a\u526f\u672c\u6570\u4e3a3\u7684Deployment\u3002\u5176\u4e2d\u4e24\u4e2a\u526f\u672c\u8fd0\u884c\u5728 cka003 \u4e0a\uff0c\u53e6\u4e00\u4e2a\u526f\u672c\u8fd0\u884c\u5728 cka002 \u4e0a\u3002 kubectl get pod -o wide -w \u8fd0\u884c\u7ed3\u679c NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES nginx-deployment-9d745469b-2xdk4 1/1 Running 0 2m8s 10.244.2.3 cka003 nginx-deployment-9d745469b-4gvmr 1/1 Running 0 2m8s 10.244.2.4 cka003 nginx-deployment-9d745469b-5j927 1/1 Running 0 2m8s 10.244.1.3 cka002 \u5728\u6211\u4eec\u505c\u6b62 cka003 \u4e0a\u7684 kubelet \u670d\u52a1\u540e\uff0c\u539f\u5148\u5728 cka003 \u4e0a\u8fd0\u884c\u7684\u4e24\u4e2a\u526f\u672c\u4f1a\u88ab\u7ec8\u6b62\uff0c\u7136\u540e\u4f1a\u81ea\u52a8\u5728 cka002 \u4e0a\u521b\u5efa\u4e24\u4e2a\u65b0\u7684\u526f\u672c\u5e76\u8fd0\u884c\u3002 \u76d1\u63a7\u6307\u6807 \u00b6 \u6f14\u793a\u573a\u666f\uff1a \u67e5\u8be2pod\u7684\u76d1\u63a7\u6307\u6807 \u6f14\u793a\uff1a \u67e5\u8be2\u8282\u70b9\u7684\u5065\u5eb7\u4fe1\u606f\u3002 kubectl top node \u8fd0\u884c\u7ed3\u679c\uff1a NAME CPU(cores) CPU% MEMORY(bytes) MEMORY% cka001 147m 7% 1940Mi 50% cka002 62m 3% 2151Mi 56% cka003 63m 3% 1825Mi 47% \u67e5\u8be2pod\u7684\u76d1\u63a7\u6307\u6807\u3002 kubectl top pod \u8fd0\u884c\u7ed3\u679c\uff1a NAME CPU(cores) MEMORY(bytes) busybox-with-secret 0m 0Mi mysql 2m 366Mi mysql-774db46945-sztrp 2m 349Mi mysql-nodeselector-6b7d9c875d-227t6 2m 365Mi mysql-tolerations-5c5986944b-cg9bs 2m 366Mi mysql-with-sc-pvc-7c97d875f8-dwfkc 2m 349Mi nfs-client-provisioner-699db7fd58-bccqs 2m 7Mi nginx 0m 3Mi nginx-app-1-695b7b647d-l76bh 0m 3Mi nginx-app-2-7f6bf6f4d4-lvbz8 0m 3Mi nginx-nodename 0m 3Mi nginx-with-cm 0m 3Mi pod-configmap-env 0m 3Mi pod-configmap-env-2 0m 3Mi tomcat 1m 58Mi \u901a\u8fc7\u9009\u9879 --sort-by \uff0c\u5bf9\u8f93\u51fa\u7ed3\u679c\u6309\u7167CPU\u6216\u8005\u5185\u5b58\u7528\u91cf\u8fdb\u884c\u6392\u5e8f\u3002 kubectl top pod --sort-by = cpu kubectl top pod --sort-by = memory \u8fd0\u884c\u7ed3\u679c\uff1a NAME CPU(cores) MEMORY(bytes) nfs-client-provisioner-699db7fd58-bccqs 2m 7Mi mysql 2m 366Mi mysql-774db46945-sztrp 2m 349Mi mysql-nodeselector-6b7d9c875d-227t6 2m 365Mi mysql-tolerations-5c5986944b-cg9bs 2m 366Mi mysql-with-sc-pvc-7c97d875f8-dwfkc 2m 349Mi tomcat 1m 58Mi nginx 0m 3Mi nginx-app-1-695b7b647d-l76bh 0m 3Mi nginx-app-2-7f6bf6f4d4-lvbz8 0m 3Mi nginx-nodename 0m 3Mi nginx-with-cm 0m 3Mi pod-configmap-env 0m 3Mi pod-configmap-env-2 0m 3Mi busybox-with-secret 0m 0Mi \u8282\u70b9\u9a71\u9010 \u00b6 \u8282\u70b9\u7684\u53ef\u8c03\u5ea6\u6027 \u00b6 \u6f14\u793a\u573a\u666f\uff1a \u8282\u70b9\u8c03\u5ea6 \u6f14\u793a\uff1a \u7981\u6b62\u4e00\u4e2a\u8282\u70b9\u7684\u8c03\u5ea6\u3002 kubectl cordon \u4e3e\u4f8b\uff1a kubectl cordon cka003 \u8f93\u51fa\u7ed3\u679c\uff0c\u8282\u70b9\u72b6\u6001\u5982\u4e0b\uff1a NAME STATUS ROLES AGE VERSION cka001 Ready control-plane,master 18d v1.24.0 cka002 Ready 18d v1.24.0 cka003 Ready,SchedulingDisabled 18d v1.24.0 \u6fc0\u6d3b\u4e00\u4e2a\u8282\u70b9\u7684\u8c03\u5ea6\u3002 kubectl uncordon \u4e3e\u4f8b\uff1a kubectl uncordon cka003 \u8f93\u51fa\u7ed3\u679c\uff0c\u8282\u70b9\u72b6\u6001\u5982\u4e0b\uff1a NAME STATUS ROLES AGE VERSION cka001 Ready control-plane,master 18d v1.24.0 cka002 Ready 18d v1.24.0 cka003 Ready 18d v1.24.0 \u9a71\u9010\u8282\u70b9 \u00b6 \u6f14\u793a\u5185\u5bb9\uff1a \u9a71\u9010\u8282\u70b9 cka003 \u6f14\u793a\uff1a \u83b7\u53d6\u5f53\u524d\u8fd0\u884cpod\u7684\u5217\u8868\u3002 kubectl get pod -o wide \u5176\u4e2d\u6709\u4e00\u4e2apod\u8fd0\u884c\u5728\u8282\u70b9 cka003 \u4e0a\u3002 NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES nfs-client-provisioner-86d7fb78b6-xk8nw 1/1 Running 0 22h 10.244.102.3 cka003 \u9a71\u9010\u8282\u70b9 cka003 \u3002 kubectl drain cka003 --ignore-daemonsets --delete-emptydir-data --force \u8f93\u51fa\u7ed3\u679c\uff1a node/cka003 cordoned WARNING: ignoring DaemonSet-managed Pods: kube-system/calico-node-tr22l, kube-system/kube-proxy-g76kg evicting pod dev/nfs-client-provisioner-86d7fb78b6-xk8nw evicting pod cka/cka-demo-64f88f7f46-dkxmk pod/nfs-client-provisioner-86d7fb78b6-xk8nw evicted pod/cka-demo-64f88f7f46-dkxmk evicted node/cka003 drained \u518d\u6b21\u67e5\u770bpod\u7684\u72b6\u6001\u3002 kubectl get pod -o wide \u5148\u524d\u8fd0\u884c\u5728\u8282\u70b9 cka003 \u4e0a\u7684pod\u73b0\u5728\u6b63\u8fd0\u884c\u5728\u8282\u70b9 cka002 \u4e0a\u3002 NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES nfs-client-provisioner-86d7fb78b6-k8xnl 1/1 Running 0 2m20s 10.244.112.4 cka002 \u5907\u6ce8\uff1a cordon \u547d\u4ee4\u5df2\u7ecf\u5305\u542b\u5728 drain \u547d\u4ee4\u4e2d\uff0c\u4e0d\u9700\u8981\u5728\u6267\u884c drain \u4e4b\u524d\u5355\u72ec\u6267\u884c cordon \u6765\u7981\u6b62node\u7684\u8c03\u5ea6\u3002","title":"Troubleshooting"},{"location":"k8s/cka_cn/foundamentals/troubleshooting/#cka25troubleshooting","text":"","title":"CKA\u81ea\u5b66\u7b14\u8bb025:Troubleshooting"},{"location":"k8s/cka_cn/foundamentals/troubleshooting/#_1","text":"\u6f14\u793a\u573a\u666f\uff1a \u63cf\u8ff0pod\u4ee5\u83b7\u53d6\u4e8b\u4ef6\u4fe1\u606f\u3002 \u6f14\u793a\uff1a \u547d\u4ee4\u7528\u6cd5\uff1a kubectl describe --namespace = \u67e5\u8be2pod\u7684\u4e8b\u4ef6\u4fe1\u606f\u3002 \u521b\u5efa\u4e00\u4e2aTomcat\u7684pod\u3002 kubectl run tomcat --image = tomcat \u67e5\u8be2pod\u7684\u4e8b\u4ef6\u4fe1\u606f\u3002 kubectl describe pod/tomcat \u5f97\u5230\u7c7b\u4f3c\u4e0b\u9762\u7684\u4e8b\u4ef6\u4fe1\u606f\u3002 Events: Type Reason Age From Message ---- ------ ---- ---- ------- Normal Scheduled 55s default-scheduler Successfully assigned dev/tomcat to cka002 Normal Pulling 54s kubelet Pulling image \"tomcat\" Normal Pulled 21s kubelet Successfully pulled image \"tomcat\" in 33.134162692s Normal Created 19s kubelet Created container tomcat Normal Started 19s kubelet Started container tomcat \u67e5\u8be2namespace\u7684\u4e8b\u4ef6\u4fe1\u606f\u3002 kubectl get events -n \u5f97\u5230\u7c7b\u4f3c\u4e0b\u9762\u7684\u9ed8\u8ba4namespace\u7684\u4e8b\u4ef6\u4fe1\u606f\u3002 LAST SEEN TYPE REASON OBJECT MESSAGE 70s Warning FailedGetScale horizontalpodautoscaler/nginx deployments/scale.apps \"podinfo\" not found 2m16s Normal Scheduled pod/tomcat Successfully assigned dev/tomcat to cka002 2m15s Normal Pulling pod/tomcat Pulling image \"tomcat\" 102s Normal Pulled pod/tomcat Successfully pulled image \"tomcat\" in 33.134162692s 100s Normal Created pod/tomcat Created container tomcat 100s Normal Started pod/tomcat Started container tomcat \u5f97\u5230\u7c7b\u4f3c\u4e0b\u9762\u7684\u6240\u6709\u7684namespace\u7684\u4e8b\u4ef6\u4fe1\u606f\u3002 kubectl get events -A","title":"\u4e8b\u4ef6"},{"location":"k8s/cka_cn/foundamentals/troubleshooting/#_2","text":"\u6f14\u793a\u573a\u666f\uff1a \u67e5\u8be2pod\u7684\u65e5\u5fd7 \u547d\u4ee4\u7528\u6cd5\uff1a kubectl logs -n \u9009\u9879\uff1a --tail : \u663e\u793a\u8f93\u51fa\u7684\u6700\u8fd1 \u884c\u3002 -f \uff1a\u5b9e\u65f6\u6d41\u5f0f\u663e\u793a\u8f93\u51fa\u3002 \u663e\u793a\u8f93\u51fa\u7684\u6700\u8fd1100\u884c\u8f93\u51fa\u3002 kubectl logs -f tomcat --tail 100 \u5982\u679c\u662f\u4e00\u4e2a\u591a\u5bb9\u5668pod\uff0c\u5219\u4f7f\u7528\u9009\u9879 -c \u6765\u6307\u5b9a\u67d0\u4e2a\u7279\u5b9a\u7684\u5bb9\u5668\u3002 kubectl logs -f tomcat --tail 100 -c tomcat","title":"\u65e5\u5fd7"},{"location":"k8s/cka_cn/foundamentals/troubleshooting/#_3","text":"","title":"\u8282\u70b9\u53ef\u7528\u6027"},{"location":"k8s/cka_cn/foundamentals/troubleshooting/#_4","text":"\u6f14\u793a\u573a\u666f\uff1a \u67e5\u770b\u8282\u70b9\u53ef\u7528\u6027 \u6f14\u793a\uff1a \u65b9\u5f0f1\uff1a kubectl describe node | grep -i taint \u624b\u5de5\u65b9\u5f0f\u68c0\u67e5\u65e5\u5fd7\uff0c\u4e0b\u9762\u7684\u4f8b\u5b50\u8bf4\u660e2\u4e2a\u8282\u70b9\u5904\u4e8e\u4e0d\u53ef\u7528\u72b6\u6001\u3002 Taints : node-role.kubernetes.io/control-plane:NoSchedule Taints : Taints : \u65b9\u5f0f2\uff1a kubectl describe node | grep -i taint | grep -vc NoSchedule \u8fd9\u91cc\u6211\u4eec\u4f1a\u5f97\u5230\u76f8\u540c\u7684\u7ed3\u679c\uff0c2\u4e2a\u8282\u70b9\u5904\u4e8e\u4e0d\u53ef\u7528\u72b6\u6001\u3002\u8fd9\u91cc\u7684 -v \u8868\u793a\u6392\u9664\uff0c -c \u8868\u793a\u8ba1\u6570\u3002","title":"\u67e5\u770b\u53ef\u7528\u8282\u70b9"},{"location":"k8s/cka_cn/foundamentals/troubleshooting/#_5","text":"\u6f14\u793a\u573a\u666f\uff1a \u5f53\u6211\u4eec\u5728Worker\u8282\u70b9 cka002 \u4e0a\u505c\u6b62 kubelet \u670d\u52a1\u65f6\uff0c \u6bcf\u4e2a\u8282\u70b9\u7684\u72b6\u6001\u662f\u4ec0\u4e48\uff1f \u901a\u8fc7 nerdctl \u547d\u4ee4\u66f4\u6539\u4e86\u54ea\u4e9b\u5bb9\u5668\uff1f \u901a\u8fc7\u547d\u4ee4 kubectl get pod -owide -A \u67e5\u770b\u7684Pod\u72b6\u6001\u662f\u4ec0\u4e48\uff1f \u6f14\u793a\uff1a \u5728 cka002 \u8282\u70b9\u4e0a\u6267\u884c\u547d\u4ee4 systemctl stop kubelet.service \u3002 \u5728 cka001 \u6216 cka003 \u4e0a\u6267\u884c\u547d\u4ee4 kubectl get node \uff0c\u53ef\u4ee5\u770b\u5230 cka002 \u7684\u72b6\u6001\u4ece Ready \u53d8\u4e3a NotReady \u3002 \u5728 cka002 \u4e0a\u6267\u884c\u547d\u4ee4 nerdctl -n k8s.io container ls \uff0c\u53ef\u4ee5\u770b\u5230\u6240\u6709\u5bb9\u5668\u90fd\u4ecd\u5728\u8fd0\u884c\uff0c\u5305\u62ecPod my-first-pod \u3002 \u5728 cka002 \u4e0a\u6267\u884c\u547d\u4ee4 systemctl start kubelet.service \u3002 \u7ed3\u8bba\uff1a \u8282\u70b9\u72b6\u6001\u7531 Ready \u53d8\u4e3a NotReady \u3002 \u5bf9\u4e8e\u90a3\u4e9b\u7c7b\u4f3c calico \u3001 kube-proxy \u8fd9\u6837\u7684 DaemonSet Pod\uff0c\u5b83\u4eec\u4e13\u95e8\u5728\u6bcf\u4e2a\u8282\u70b9\u4e0a\u8fd0\u884c\u3002\u5728 kubelet \u505c\u6b62\u540e\u5b83\u4eec\u4e0d\u4f1a\u88ab\u7ec8\u6b62\u3002 Pod my-first-pod \u7684\u72b6\u6001\u5728\u6bcf\u4e2a\u8282\u70b9\u4e0a\u4ecd\u7136\u663e\u793a\u4e3a Terminating \uff0c\u56e0\u4e3a\u72b6\u6001\u65e0\u6cd5\u901a\u8fc7 apiserver \u4ece cka002 \u540c\u6b65\u5230\u5176\u4ed6\u8282\u70b9\uff0c\u56e0\u4e3a kubelet \u5df2\u505c\u6b62\u3002 Pod\u7684\u72b6\u6001\u7531\u63a7\u5236\u5668\u6807\u8bb0\u5e76\u7531 kubelet \u56de\u6536\u3002 \u5f53\u6211\u4eec\u5728 cka003 \u4e0a\u542f\u52a8 kubelet \u670d\u52a1\u65f6\uff0cPod my-first-pod \u5c06\u5b8c\u5168\u5728 cka002 \u4e0a\u88ab\u7ec8\u6b62\u3002 \u6b64\u5916\uff0c\u8ba9\u6211\u4eec\u521b\u5efa\u4e00\u4e2a\u526f\u672c\u6570\u4e3a3\u7684Deployment\u3002\u5176\u4e2d\u4e24\u4e2a\u526f\u672c\u8fd0\u884c\u5728 cka003 \u4e0a\uff0c\u53e6\u4e00\u4e2a\u526f\u672c\u8fd0\u884c\u5728 cka002 \u4e0a\u3002 kubectl get pod -o wide -w \u8fd0\u884c\u7ed3\u679c NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES nginx-deployment-9d745469b-2xdk4 1/1 Running 0 2m8s 10.244.2.3 cka003 nginx-deployment-9d745469b-4gvmr 1/1 Running 0 2m8s 10.244.2.4 cka003 nginx-deployment-9d745469b-5j927 1/1 Running 0 2m8s 10.244.1.3 cka002 \u5728\u6211\u4eec\u505c\u6b62 cka003 \u4e0a\u7684 kubelet \u670d\u52a1\u540e\uff0c\u539f\u5148\u5728 cka003 \u4e0a\u8fd0\u884c\u7684\u4e24\u4e2a\u526f\u672c\u4f1a\u88ab\u7ec8\u6b62\uff0c\u7136\u540e\u4f1a\u81ea\u52a8\u5728 cka002 \u4e0a\u521b\u5efa\u4e24\u4e2a\u65b0\u7684\u526f\u672c\u5e76\u8fd0\u884c\u3002","title":"\u67e5\u770b\u4e0d\u53ef\u7528\u8282\u70b9"},{"location":"k8s/cka_cn/foundamentals/troubleshooting/#_6","text":"\u6f14\u793a\u573a\u666f\uff1a \u67e5\u8be2pod\u7684\u76d1\u63a7\u6307\u6807 \u6f14\u793a\uff1a \u67e5\u8be2\u8282\u70b9\u7684\u5065\u5eb7\u4fe1\u606f\u3002 kubectl top node \u8fd0\u884c\u7ed3\u679c\uff1a NAME CPU(cores) CPU% MEMORY(bytes) MEMORY% cka001 147m 7% 1940Mi 50% cka002 62m 3% 2151Mi 56% cka003 63m 3% 1825Mi 47% \u67e5\u8be2pod\u7684\u76d1\u63a7\u6307\u6807\u3002 kubectl top pod \u8fd0\u884c\u7ed3\u679c\uff1a NAME CPU(cores) MEMORY(bytes) busybox-with-secret 0m 0Mi mysql 2m 366Mi mysql-774db46945-sztrp 2m 349Mi mysql-nodeselector-6b7d9c875d-227t6 2m 365Mi mysql-tolerations-5c5986944b-cg9bs 2m 366Mi mysql-with-sc-pvc-7c97d875f8-dwfkc 2m 349Mi nfs-client-provisioner-699db7fd58-bccqs 2m 7Mi nginx 0m 3Mi nginx-app-1-695b7b647d-l76bh 0m 3Mi nginx-app-2-7f6bf6f4d4-lvbz8 0m 3Mi nginx-nodename 0m 3Mi nginx-with-cm 0m 3Mi pod-configmap-env 0m 3Mi pod-configmap-env-2 0m 3Mi tomcat 1m 58Mi \u901a\u8fc7\u9009\u9879 --sort-by \uff0c\u5bf9\u8f93\u51fa\u7ed3\u679c\u6309\u7167CPU\u6216\u8005\u5185\u5b58\u7528\u91cf\u8fdb\u884c\u6392\u5e8f\u3002 kubectl top pod --sort-by = cpu kubectl top pod --sort-by = memory \u8fd0\u884c\u7ed3\u679c\uff1a NAME CPU(cores) MEMORY(bytes) nfs-client-provisioner-699db7fd58-bccqs 2m 7Mi mysql 2m 366Mi mysql-774db46945-sztrp 2m 349Mi mysql-nodeselector-6b7d9c875d-227t6 2m 365Mi mysql-tolerations-5c5986944b-cg9bs 2m 366Mi mysql-with-sc-pvc-7c97d875f8-dwfkc 2m 349Mi tomcat 1m 58Mi nginx 0m 3Mi nginx-app-1-695b7b647d-l76bh 0m 3Mi nginx-app-2-7f6bf6f4d4-lvbz8 0m 3Mi nginx-nodename 0m 3Mi nginx-with-cm 0m 3Mi pod-configmap-env 0m 3Mi pod-configmap-env-2 0m 3Mi busybox-with-secret 0m 0Mi","title":"\u76d1\u63a7\u6307\u6807"},{"location":"k8s/cka_cn/foundamentals/troubleshooting/#_7","text":"","title":"\u8282\u70b9\u9a71\u9010"},{"location":"k8s/cka_cn/foundamentals/troubleshooting/#_8","text":"\u6f14\u793a\u573a\u666f\uff1a \u8282\u70b9\u8c03\u5ea6 \u6f14\u793a\uff1a \u7981\u6b62\u4e00\u4e2a\u8282\u70b9\u7684\u8c03\u5ea6\u3002 kubectl cordon \u4e3e\u4f8b\uff1a kubectl cordon cka003 \u8f93\u51fa\u7ed3\u679c\uff0c\u8282\u70b9\u72b6\u6001\u5982\u4e0b\uff1a NAME STATUS ROLES AGE VERSION cka001 Ready control-plane,master 18d v1.24.0 cka002 Ready 18d v1.24.0 cka003 Ready,SchedulingDisabled 18d v1.24.0 \u6fc0\u6d3b\u4e00\u4e2a\u8282\u70b9\u7684\u8c03\u5ea6\u3002 kubectl uncordon \u4e3e\u4f8b\uff1a kubectl uncordon cka003 \u8f93\u51fa\u7ed3\u679c\uff0c\u8282\u70b9\u72b6\u6001\u5982\u4e0b\uff1a NAME STATUS ROLES AGE VERSION cka001 Ready control-plane,master 18d v1.24.0 cka002 Ready 18d v1.24.0 cka003 Ready 18d v1.24.0","title":"\u8282\u70b9\u7684\u53ef\u8c03\u5ea6\u6027"},{"location":"k8s/cka_cn/foundamentals/troubleshooting/#_9","text":"\u6f14\u793a\u5185\u5bb9\uff1a \u9a71\u9010\u8282\u70b9 cka003 \u6f14\u793a\uff1a \u83b7\u53d6\u5f53\u524d\u8fd0\u884cpod\u7684\u5217\u8868\u3002 kubectl get pod -o wide \u5176\u4e2d\u6709\u4e00\u4e2apod\u8fd0\u884c\u5728\u8282\u70b9 cka003 \u4e0a\u3002 NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES nfs-client-provisioner-86d7fb78b6-xk8nw 1/1 Running 0 22h 10.244.102.3 cka003 \u9a71\u9010\u8282\u70b9 cka003 \u3002 kubectl drain cka003 --ignore-daemonsets --delete-emptydir-data --force \u8f93\u51fa\u7ed3\u679c\uff1a node/cka003 cordoned WARNING: ignoring DaemonSet-managed Pods: kube-system/calico-node-tr22l, kube-system/kube-proxy-g76kg evicting pod dev/nfs-client-provisioner-86d7fb78b6-xk8nw evicting pod cka/cka-demo-64f88f7f46-dkxmk pod/nfs-client-provisioner-86d7fb78b6-xk8nw evicted pod/cka-demo-64f88f7f46-dkxmk evicted node/cka003 drained \u518d\u6b21\u67e5\u770bpod\u7684\u72b6\u6001\u3002 kubectl get pod -o wide \u5148\u524d\u8fd0\u884c\u5728\u8282\u70b9 cka003 \u4e0a\u7684pod\u73b0\u5728\u6b63\u8fd0\u884c\u5728\u8282\u70b9 cka002 \u4e0a\u3002 NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES nfs-client-provisioner-86d7fb78b6-k8xnl 1/1 Running 0 2m20s 10.244.112.4 cka002 \u5907\u6ce8\uff1a cordon \u547d\u4ee4\u5df2\u7ecf\u5305\u542b\u5728 drain \u547d\u4ee4\u4e2d\uff0c\u4e0d\u9700\u8981\u5728\u6267\u884c drain \u4e4b\u524d\u5355\u72ec\u6267\u884c cordon \u6765\u7981\u6b62node\u7684\u8c03\u5ea6\u3002","title":"\u9a71\u9010\u8282\u70b9"},{"location":"k8s/cka_cn/installation/aliyun-ubuntu/","text":"CKA\u81ea\u5b66\u7b14\u8bb03:\u963f\u91cc\u4e91ECS\u5b89\u88c5Kubernetes \u00b6 \u6458\u8981 \u00b6 \u5728\u963f\u91cc\u4e91ECS\u88c5\u4e09\u53f0Ubuntu\u865a\u62df\u673a\u3002\u5728Ubuntu\u865a\u62df\u673a\u4e2d\u5b89\u88c5\u57fa\u4e8eContainerd\u7684Kubernetes\u7cfb\u7edf\uff0c\u5e76\u5206\u522b\u914d\u7f6e\u4e00\u4e2a\u4e3b\u8282\u70b9Master\u548c\u4e24\u4e2a\u5de5\u4f5c\u8282\u70b9Worker\uff0c\u3002 \u51c6\u5907\u5de5\u4f5c \u00b6 \u6ce8\u518c\u963f\u91cc\u4e91\u8d26\u53f7\uff1a Alibaba Cloud home console \u3002\u6ce8\u610f\u4fdd\u7559\u8bbf\u95ee\u5bc6\u94a5key\u6587\u4ef6\uff0c\u53ea\u80fd\u5bfc\u51fa\u4e00\u6b21\uff0c\u5f53\u524d\u7ec3\u4e60\u4e2dkey\u6587\u4ef6\u662f aliyun-root \u3002 \u53c2\u8003\u4e0b\u9762\u914d\u7f6e\u6ce8\u518c\u7533\u8bf7\u4e09\u4e2aECS\uff08Elastic Computer Service\uff09\u670d\u52a1\u5b9e\u4f8b\uff1a \u4e3b\u673a\uff1a2vCPU+4GiB \u64cd\u4f5c\u7cfb\u7edf\uff1aUbuntu 20.04 x86_64 \u5b9e\u4f8b\u7c7b\u578b\uff1aecs.sn1.medium \u5b9e\u4f8b\u540d\u79f0\uff1acka001, cka002, cka003 \u7f51\u7edc\u914d\u7f6e\uff1aboth public IPs and private IPs \u6700\u5927\u7f51\u7edc\u5e26\u5bbd\uff1a100Mbps (Peak Value) \u4e91\u76d8\uff1a40GiB \u652f\u4ed8\u65b9\u5f0f\uff1a\u62a2\u5360\u5f0f\u5b9e\u4f8b \u5728\u672c\u5730\u6253\u5f00\u7ec8\u7aef\u7a97\u53e3\uff0c\u901a\u8fc7\u5bc6\u94a5\u6587\u4ef6 aliyun-root \u8bbf\u95ee\u8fdc\u7a0bECS\u8282\u70b9 cka001 \u3002 ssh -i aliyun-root root@cka001 \u521b\u5efa\u4e00\u4e2a\u666e\u901a\u7528\u6237\uff0c\u7528\u6765\u5b89\u88c5Kubernetes\uff0c\u5f53\u524d\u7ec3\u4e60\u4e2d\u521b\u5efa\u7528\u6237 vagrant \uff0c\u4e14\u4fee\u6539\u8be5\u7528\u6237\u7684\u4e3b\u8981\u7ec4\u4e3a sudo \u6b21\u8981\u7ec4\u5305\u542b root \u3002 adduser vagrant usermod -g sudo vagrant usermod -a -G root vagrant \u65b0\u5f00\u4e00\u4e2a\u672c\u5730\u7ec8\u7aef\u7a97\u53e3\uff0c\u4e3a\u7528\u6237 vagrant \u521b\u5efa\u5bc6\u94a5key\u3002 # Windows ssh-keygen.exe # Linux ssh-keygen \u4e0a\u9762\u7684\u547d\u4ee4\u4f1a\u751f\u62102\u4e2a\u6587\u4ef6\uff0c\u5f53\u524d\u7ec3\u4e60\u4e2d\u8fd92\u4e2a\u6587\u4ef6\u662f aliyun-vagrant and aliyun-vagrant.pub \u901a\u8fc7 sftp \u547d\u4ee4\u5c06\u516c\u94a5\u6587\u4ef6 aliyun-vagrant.pub \u4e0a\u4f20\u5230\u8fdc\u7a0b\u8282\u70b9 cka001 \u3002 sftp -i aliyun-root root@cka001 put aliyun-vagrant.pub \u65b0\u5f00\u4e00\u4e2a\u7ec8\u7aef\u7a97\u53e3\uff0c\u7528 root \u7684\u5bc6\u94a5\u767b\u5f55 cka001 \u8282\u70b9\u3002 \u5c06\u4e0a\u4e00\u6b65\u4e0a\u4f20\u7684\u5bc6\u94a5\u6587\u4ef6 aliyun-vagrant.pub \u4ece /root \u76ee\u5f55\u62f7\u8d1d\u5230 /home/vagrant/.ssh/ \u3002 \u5c06\u516c\u94a5\u6587\u4ef6 aliyun-vagrant.pub \u91cd\u547d\u540d\u4e3a authorized_keys \u3002 \u66f4\u6539\u6587\u4ef6 authorized_keys \u7684\u6240\u6709\u8005owner\u4e3a vagrant . \u66f4\u6539\u6587\u4ef6 authorized_keys \u7684\u4e3b\u8981\u7ec4\u4e3a sudo \u3002 mkdir /home/vagrant/.ssh/ mv aliyun-james.pub /home/vagrant/.ssh/authorized_keys chown vagrant.sudo /home/vagrant/.ssh/authorized_keys chmod 600 /home/vagrant/.ssh/authorized_keys \u68c0\u67e5\u6587\u4ef6 /etc/ssh/sshd_config \uff0c\u786e\u5b9a\u5bc6\u7801\u767b\u5f55\u9a8c\u8bc1\u53c2\u6570 asswordAuthentication \u8bbe\u5b9a\u4e3a no \uff0c\u5373\u53ea\u80fd\u901a\u8fc7\u8bc1\u4e66\u8fdc\u7a0b\u767b\u5f55\u3002 cat /etc/ssh/sshd_config \u65b0\u5f00\u4e00\u4e2a\u7ec8\u7aef\u7a97\u53e3\uff0c\u4f7f\u7528\u7528\u6237vagrant\u767b\u5f55\u8fdc\u7a0b\u8282\u70b9 cka001 \uff0c\u9a8c\u8bc1\u7528\u6237 vagrant \u80fd\u901a\u8fc7\u524d\u9762\u521b\u5efa\u7684\u8bc1\u4e66\u767b\u5f55\u8282\u70b9 cka001 \u3002 ssh -i aliyun-vagrant vagrant@cka001 \u91cd\u590d\u4e0a\u8ff0\u6b65\u9aa4\uff0c\u901a\u8fc7 sftp \u547d\u4ee4\u5c06\u516c\u94a5\u6587\u4ef6 aliyun-vagrant.pub \u5206\u522b\u4e0a\u4f20\u5230\u8fdc\u7a0b\u8282\u70b9 cka002 \u548c cka003 \uff0c\u4e14\u5b8c\u6210\u540c\u6837\u7684\u914d\u7f6e\uff0c\u4f7f\u7528\u6237 vagrant \u4e5f\u80fd\u901a\u8fc7\u5bc6\u94a5\u6587\u4ef6\u767b\u5f55\u8fdc\u7a0b\u8282\u70b9 cka002 \u548c cka003 \u3002 \u81f3\u6b64\uff0c\u7528\u6237 vagrant \u53ef\u4ee5\u901a\u8fc7\u5bc6\u94a5\u6587\u4ef6 aliyun-vagrant \u4ece\u672c\u5730\u7ec8\u7aef\u7a97\u53e3\u767b\u5f55\u8fdc\u7a0b\u8282\u70b9 cka001 , cka002 \u548c cka003 \u3002 \u4e0b\u9762\u6240\u6709\u6b65\u9aa4\u90fd\u662f\u901a\u8fc7\u7528\u6237 vagrant \u5b8c\u6210\u3002 \u521d\u59cb\u5316ECS\u8282\u70b9 \u00b6 \u914d\u7f6e\u6587\u4ef6/etc/hosts \u00b6 \u66f4\u65b0\u6240\u6709ECS\u8282\u70b9\u7684\u6587\u4ef6/etc/hosts\uff0c\u6dfb\u52a0\u5176\u4ed6\u8282\u70b9\u7684\u79c1\u6709IP\uff08private IP\uff09\u3002 vi /etc/hosts \u7981\u7528firewall \u00b6 \u5728\u6240\u6709\u8282\u70b9\u4e0a\u7981\u7528\u9632\u706b\u5899\u3002 sudo ufw disable \u68c0\u67e5\u9632\u706b\u5899\u72b6\u6001\u3002 sudo ufw status verbose \u5173\u95edswap \u00b6 \u5728\u6240\u6709\u8282\u70b9\u4e0a\u5173\u95edswap\u3002 sudo swapoff -a \u8bbe\u7f6e\u65f6\u533a\u548c\u5730\u57df \u00b6 \u5728\u6240\u6709\u8282\u70b9\u8bbe\u5b9a\u65f6\u533a\u548c\u5730\u57df\u3002\u8fd9\u4e00\u5e03\u5728\u521d\u59cb\u5316ECS\u65f6\u5019\u5df2\u7ecf\u5b8c\u6210\u3002\u53ef\u4ee5\u901a\u8fc7\u4e0b\u9762\u547d\u4ee4\u8fdb\u884c\u8bbe\u5b9a\u3002 ln -sf /usr/share/zoneinfo/Asia/Shanghai /etc/localtime sudo echo 'LANG=\"en_US.UTF-8\"' >> /etc/profile source /etc/profile \u901a\u8fc7\u4e0b\u9762\u547d\u4ee4\u68c0\u67e5\u65f6\u533a\u548c\u5730\u57df\u7684\u8bbe\u7f6e\u3002 ll /etc/localtime lrwxrwxrwx 1 root root 33 Jul 5 14:51 /etc/localtime -> /usr/share/zoneinfo/Asia/Shanghai \u5185\u6838\u8bbe\u7f6e \u00b6 \u5728\u6240\u6709\u8282\u70b9\u4e0a\u6267\u884c\u4e0b\u9762\u7684\u547d\u4ee4\u4ee5\u914d\u7f6e\u5185\u6838\u3002 \u4f7f\u7528\u6a21\u5757overlay\uff1a \u521b\u5efaContainerd\u670d\u52a1\u914d\u7f6e\u6587\u4ef6 /etc/modules-load.d/containerd.conf \uff0c\u5982\u679c\u5df2\u5b58\u5728\u5219\u8df3\u8fc7\u8fd9\u4e00\u6b65\u3002\u914d\u7f6e\u8fd9\u4e2a\u6587\u4ef6\u7684\u76ee\u7684\u662f\u4e3a\u4e86\u52a0\u8f7d\u6a21\u5757 overlay \u548c br_netfilter \u5230\u5185\u6838\u4e2d\u3002 \u670d\u52a1Containerd\u4f9d\u8d56\u6a21\u5757 overlay \u5b9e\u73b0 overlay-filesystem \u6587\u4ef6\u7cfb\u7edf\u529f\u80fd\u3002 Linux\u4e2d\u7684overlay\u6a21\u5757\u63d0\u4f9b\u4e86\u521b\u5efa\u4e24\u4e2a\u76ee\u5f55\u7684\u5408\u5e76\u89c6\u56fe\u7684\u80fd\u529b\uff0c\u8fd9\u4e24\u4e2a\u76ee\u5f55\u79f0\u4e3a\u5c42\u3002\u5b83\u7ecf\u5e38\u88ab\u7528\u4e8e\u5b9e\u73b0\u8054\u5408\u6302\u8f7d\uff0c\u8fd9\u662f\u4e00\u79cd\u5c06\u4e24\u4e2a\u6216\u66f4\u591a\u76ee\u5f55\u4e00\u8d77\u6302\u8f7d\u7684\u65b9\u5f0f\uff0c\u5c31\u50cf\u5b83\u4eec\u662f\u4e00\u4e2a\u76ee\u5f55\u4e00\u6837\uff08union-filesystems\uff09\u3002 overlay\u6a21\u5757\u5728\u5bb9\u5668\u6280\u672f\u4e2d\u88ab\u5e7f\u6cdb\u4f7f\u7528\uff0c\u6bd4\u5982Docker\uff0c\u56e0\u4e3a\u5b83\u5141\u8bb8\u591a\u4e2a\u5bb9\u5668\u5171\u4eab\u57fa\u7840\u955c\u50cf\uff0c\u540c\u65f6\u4fdd\u6301\u5b83\u4eec\u81ea\u5df1\u7684\u6587\u4ef6\u7cfb\u7edf\u3002 \u8981\u4f7f\u7528overlay\u6a21\u5757\uff0c\u9700\u8981\u4e24\u4e2a\u76ee\u5f55\uff1a\u8f83\u4f4e\u7684\u76ee\u5f55\uff08lower directory\uff09\u548c\u8f83\u9ad8\u7684\u76ee\u5f55\uff08upper directory\uff09\u3002\u8f83\u4f4e\u7684\u76ee\u5f55\u901a\u5e38\u662f\u53ea\u8bfb\u7684\uff0c\u5305\u542b\u539f\u59cb\u6587\u4ef6\uff0c\u800c\u8f83\u9ad8\u7684\u76ee\u5f55\u662f\u53ef\u8bfb\u5199\u7684\uff0c\u5305\u542b\u5bf9\u6587\u4ef6\u7684\u66f4\u6539\u3002\u5f53\u8bf7\u6c42\u6587\u4ef6\u65f6\uff0coverlay\u6a21\u5757\u9996\u5148\u67e5\u627e\u4e0a\u5c42\u76ee\u5f55\uff0c\u5982\u679c\u672a\u627e\u5230\uff0c\u5219\u67e5\u627e\u4e0b\u5c42\u76ee\u5f55\u3002 \u6bd4\u5982\uff1a \u521b\u5efa\u4e24\u4e2a\u76ee\u5f55\uff0c\u4e00\u4e2a\u7528\u4e8e\u8f83\u4f4e\u7684\u76ee\u5f55\uff0c\u4e00\u4e2a\u7528\u4e8e\u8f83\u9ad8\u7684\u76ee\u5f55\u3002\u7136\u540e\u4f7f\u7528overlay\u6587\u4ef6\u7cfb\u7edf\u7c7b\u578b\u5c06\u5b83\u4eec\u6302\u8f7d\u8d77\u6765\uff1a sudo mkdir /lower sudo mkdir /upper sudo mount -t overlay overlay -o lowerdir = /lower,upperdir = /upper /merged \u5728\u4e0a\u9762\u7684\u4f8b\u5b50\u4e2d\uff0c\u4e24\u4e2a\u76ee\u5f55\u7684\u5408\u5e76\u89c6\u56fe\u88ab\u521b\u5efa\u5728 /merged \u76ee\u5f55\u4e2d\u3002\u5728 /merged \u76ee\u5f55\u4e2d\u5bf9\u6587\u4ef6\u6240\u505a\u7684\u4efb\u4f55\u66f4\u6539\u90fd\u5b58\u50a8\u5728\u4e0a\u5c42\u76ee\u5f55\u4e2d\uff0c\u800c\u539f\u59cb\u6587\u4ef6\u4ecd\u7136\u5728\u4e0b\u5c42\u76ee\u5f55\u4e2d\u3002 \u4f7f\u7528\u6a21\u5757br_netfilter\uff1a br_netfilter \u662fLinux\u5185\u6838\u4e2d\u7684\u4e00\u4e2a\u6a21\u5757\uff0c\u5b83\u63d0\u4f9b\u4e86\u4e00\u79cd\u673a\u5236\u6765\u8fc7\u6ee4\u7f51\u6865\u7684\u7f51\u7edc\u6d41\u91cf\u3002\u8be5\u6a21\u5757\u5141\u8bb8\u7ba1\u7406\u5458\u914d\u7f6e\u89c4\u5219\uff0c\u4ee5\u5141\u8bb8\u6216\u62d2\u7edd\u7279\u5b9a\u7684\u7f51\u7edc\u6d41\u91cf\u901a\u8fc7\u7f51\u6865\u3002 \u7f51\u6865\u662f\u4e00\u79cd\u7f51\u7edc\u8bbe\u5907\uff0c\u5b83\u53ef\u4ee5\u8fde\u63a5\u591a\u4e2a\u7f51\u7edc\u6bb5\uff0c\u5e76\u8f6c\u53d1\u6d41\u91cf\u4ee5\u4f7f\u4e0d\u540c\u7684\u7f51\u7edc\u6bb5\u4e4b\u95f4\u901a\u4fe1\u3002 br_netfilter \u6a21\u5757\u53ef\u4ee5\u7528\u6765\u9650\u5236\u6216\u8fc7\u6ee4\u8fd9\u4e9b\u6d41\u91cf\u3002 \u5f53\u542f\u7528\u4e86 br_netfilter \u6a21\u5757\u65f6\uff0c\u5b83\u4f1a\u81ea\u52a8\u542f\u7528\u4e00\u4e2a\u79f0\u4e3a bridge-nf \u7684\u529f\u80fd\uff0c\u8be5\u529f\u80fd\u5c06\u5728\u7f51\u7edc\u6d41\u91cf\u901a\u8fc7\u7f51\u6865\u65f6\u5e94\u7528\u89c4\u5219\u3002\u7ba1\u7406\u5458\u53ef\u4ee5\u4f7f\u7528iptables\u7b49\u5de5\u5177\u6765\u914d\u7f6e\u8fd9\u4e9b\u89c4\u5219\u3002\u4f8b\u5982\uff0c\u6211\u4eec\u53ef\u4ee5\u8bbe\u5b9a\u5141\u8bb8\u4ece\u4e00\u4e2a\u7f51\u7edc\u6bb5\u5230\u53e6\u4e00\u4e2a\u7f51\u7edc\u6bb5\u7684\u6d41\u91cf\uff0c\u6216\u8005\u62d2\u7edd\u6765\u81ea\u7279\u5b9aIP\u5730\u5740\u6216\u7aef\u53e3\u7684\u6d41\u91cf\u3002 \u5728Kubernetes\u4e2d\uff0c br_netfilter \u6a21\u5757\u4e3b\u8981\u7528\u4e8e\u542f\u7528Kubernetes\u670d\u52a1\u7684\u6d41\u91cf\u8f6c\u53d1\u548c\u8d1f\u8f7d\u5747\u8861\u3002\u8fd9\u4e9b\u670d\u52a1\u4f7f\u7528\u4e86Linux\u5185\u6838\u4e2d\u7684iptables\u89c4\u5219\u6765\u7ba1\u7406\u6d41\u91cf\uff0c\u8fd9\u4e9b\u89c4\u5219\u662f\u901a\u8fc7 br_netfilter \u6a21\u5757\u5b9e\u73b0\u7684\u3002 \u5177\u4f53\u6765\u8bf4\uff0c\u5f53\u6211\u4eec\u5728Kubernetes\u96c6\u7fa4\u4e2d\u521b\u5efa\u4e00\u4e2a\u670d\u52a1\u65f6\uff0c\u8be5\u670d\u52a1\u5c06\u5206\u914d\u4e00\u4e2a\u865a\u62dfIP\u5730\u5740\uff0c\u7528\u4e8e\u4ee3\u8868\u670d\u52a1\u3002\u7136\u540e\uff0c\u901a\u8fc7iptables\u89c4\u5219\uff0c\u5c06\u8fd9\u4e2a\u865a\u62dfIP\u5730\u5740\u6620\u5c04\u5230\u4e00\u4e2a\u6216\u591a\u4e2a\u540e\u7aefPod\u7684IP\u5730\u5740\uff0c\u4ee5\u4fbf\u5728\u9700\u8981\u65f6\u5c06\u6d41\u91cf\u8def\u7531\u5230\u8fd9\u4e9bPod\u3002 \u5728\u8fd9\u4e2a\u8fc7\u7a0b\u4e2d\uff0c br_netfilter \u6a21\u5757\u8d1f\u8d23\u76d1\u89c6\u670d\u52a1\u7684\u6d41\u91cf\uff0c\u5e76\u6839\u636eiptables\u89c4\u5219\u8fdb\u884c\u8f6c\u53d1\u548c\u8d1f\u8f7d\u5747\u8861\u3002\u8fd9\u5305\u62ec\u8fc7\u6ee4\u6765\u81ea\u4e0d\u53d7\u4fe1\u4efb\u6e90\u7684\u6d41\u91cf\u4ee5\u53ca\u9650\u5236\u670d\u52a1\u7684\u8bbf\u95ee\u6743\u9650\u3002 \u9700\u8981\u6ce8\u610f\u7684\u662f\uff0c\u4e3a\u4e86\u542f\u7528Kubernetes\u670d\u52a1\u7684\u6d41\u91cf\u8f6c\u53d1\u548c\u8d1f\u8f7d\u5747\u8861\uff0c br_netfilter \u6a21\u5757\u5fc5\u987b\u5728\u6240\u6709\u8282\u70b9\u4e0a\u542f\u7528\uff0c\u5e76\u4e14\u5fc5\u987b\u914d\u7f6e\u6b63\u786e\u7684iptables\u89c4\u5219\u3002 \u7531\u4e8e br_netfilter \u6a21\u5757\u7684\u4f5c\u7528\u975e\u5e38\u5173\u952e\uff0c\u56e0\u6b64\u5728\u5347\u7ea7\u6216\u66f4\u6539\u7cfb\u7edf\u65f6\u9700\u8981\u7279\u522b\u6ce8\u610f\u5b83\u7684\u914d\u7f6e\u548c\u72b6\u6001\u3002 \u4e0b\u9762\u547d\u4ee4\u5c06\u6a21\u5757 overlay \u548c br_netfilter \u6dfb\u52a0\u5230\u914d\u7f6e\u6587\u4ef6 containerd.conf \u4e2d\u3002 cat < /etc/apt/sources.list << EOF deb http://mirrors.cloud.aliyuncs.com/ubuntu/ focal main restricted deb-src http://mirrors.cloud.aliyuncs.com/ubuntu/ focal main restricted deb http://mirrors.cloud.aliyuncs.com/ubuntu/ focal-updates main restricted deb-src http://mirrors.cloud.aliyuncs.com/ubuntu/ focal-updates main restricted deb http://mirrors.cloud.aliyuncs.com/ubuntu/ focal universe deb-src http://mirrors.cloud.aliyuncs.com/ubuntu/ focal universe deb http://mirrors.cloud.aliyuncs.com/ubuntu/ focal-updates universe deb-src http://mirrors.cloud.aliyuncs.com/ubuntu/ focal-updates universe deb http://mirrors.cloud.aliyuncs.com/ubuntu/ focal multiverse deb-src http://mirrors.cloud.aliyuncs.com/ubuntu/ focal multiverse deb http://mirrors.cloud.aliyuncs.com/ubuntu/ focal-updates multiverse deb-src http://mirrors.cloud.aliyuncs.com/ubuntu/ focal-updates multiverse deb http://mirrors.cloud.aliyuncs.com/ubuntu/ focal-backports main restricted universe multiverse deb-src http://mirrors.cloud.aliyuncs.com/ubuntu/ focal-backports main restricted universe multivers deb http://mirrors.cloud.aliyuncs.com/ubuntu focal-security main restricted deb-src http://mirrors.cloud.aliyuncs.com/ubuntu focal-security main restricted deb http://mirrors.cloud.aliyuncs.com/ubuntu focal-security universe deb-src http://mirrors.cloud.aliyuncs.com/ubuntu focal-security universe # deb http://mirrors.cloud.aliyuncs.com/ubuntu focal-security multiverse # deb-src http://mirrors.cloud.aliyuncs.com/ubuntu focal-security multiverse EOF \u5b89\u88c5Containered\u3002 sudo apt-get update && sudo apt-get install -y containerd \u914d\u7f6eContainerd\u3002\u4fee\u6539\u6587\u4ef6 /etc/containerd/config.toml \u3002 sudo mkdir -p /etc/containerd containerd config default | sudo tee /etc/containerd/config.toml sudo vi /etc/containerd/config.toml \u4fee\u6539\u53c2\u6570 sandbox_image \u7684\u503c\u4e3a \"registry.aliyuncs.com/google_containers/pause:3.6\" \u3002 \u4fee\u6539\u53c2\u6570 SystemdCgroup \u7684\u503c\u4e3a true \u3002 [plugins] [plugins.\"io.containerd.gc.v1.scheduler\"] [plugins.\"io.containerd.grpc.v1.cri\"] sandbox_image = \"registry.aliyuncs.com/google_containers/pause:3.6\" [plugins.\"io.containerd.grpc.v1.cri\".cni] [plugins.\"io.containerd.grpc.v1.cri\".containerd] [plugins.\"io.containerd.grpc.v1.cri\".containerd.default_runtime] [plugins.\"io.containerd.grpc.v1.cri\".containerd.default_runtime.options] [plugins.\"io.containerd.grpc.v1.cri\".containerd.runtimes] [plugins.\"io.containerd.grpc.v1.cri\".containerd.runtimes.runc] [plugins.\"io.containerd.grpc.v1.cri\".containerd.runtimes.runc.options] SystemdCgroup = true \u91cd\u542fContainerd\u670d\u52a1\u3002 sudo systemctl restart containerd sudo systemctl status containerd \u5b89\u88c5nerdctl \u00b6 \u5728\u6240\u6709\u8282\u70b9\u4e0a\u5b89\u88c5nerdctl\u670d\u52a1\u3002 nerdctl \u670d\u52a1\u652f\u6301Contanerd\u6240\u63d0\u4f9b\u7684\u5bb9\u5668\u5316\u7279\u6027\uff0c\u7279\u522b\u662f\u4e00\u4e9bDocker\u4e0d\u5177\u5907\u7684\u65b0\u7279\u6027\u3002 \u4e8c\u8fdb\u5236\u5b89\u88c5\u5305\u53ef\u4ee5\u901a\u8fc7\u8fd9\u4e2a\u94fe\u63a5\u53d6\u5f97: Releases \u00b7 containerd/nerdctl \u00b7 GitHub \u3002 wget https://github.com/containerd/nerdctl/releases/download/v0.22.2/nerdctl-0.22.2-linux-amd64.tar.gz tar -zxvf nerdctl-0.22.2-linux-amd64.tar.gz sudo cp nerdctl /usr/bin/ \u9a8c\u8bc1 nerdctl \u670d\u52a1\u3002 sudo nerdctl --help \u5217\u51fa\u521d\u59cb\u5b89\u88c5Kubernetes\u65f6\u7684\u5bb9\u5668container\u5217\u8868\u3002 nerdctl -n k8s.io ps \u5b89\u88c5kubeadm \u00b6 \u5728\u6240\u6709\u8282\u70b9\u4e0a\u5b89\u88c5Kubeadm\uff0ckubectl\uff0ckubelet\u3002 \u5b89\u88c5\u548c\u5347\u7ea7Ubuntu\u7cfb\u7edf\u4f9d\u8d56\u5305 apt-transport-https , ca-certificates , curl \u3002 sudo apt-get update && sudo apt-get install -y apt-transport-https ca-certificates curl \u5b89\u88c5gpg\u8bc1\u4e66\u3002 curl https://mirrors.aliyun.com/kubernetes/apt/doc/apt-key.gpg | sudo apt-key add - \u6dfb\u52a0Kubernetes\u5b89\u88c5\u6e90\u3002 cat << EOF > /etc/apt/sources.list.d/kubernetes.list deb https://mirrors.aliyun.com/kubernetes/apt/ kubernetes-xenial main EOF \u5b89\u88c5\u548c\u5347\u7ea7Ubuntu\u7cfb\u7edf\u4f9d\u8d56\u5305\u3002 sudo apt-get update sudo apt-get install ebtables sudo apt-get install libxtables12 sudo apt-get upgrade iptables \u68c0\u67e5\u5f53\u524d\u53ef\u7528\u7684 kubeadm \u7248\u672c\u3002 apt policy kubeadm \u5f53\u524d\u5b89\u88c5 1.24.0-00 \u7248\u672c\u7684 kubeadm \uff0c\u540e\u7eed\u4f1a\u5347\u7ea7\u5230 1.24.2 \u7248\u672c\u3002 sudo apt-get -y install kubelet = 1 .24.0-00 kubeadm = 1 .24.0-00 kubectl = 1 .24.0-00 --allow-downgrades \u914d\u7f6e\u4e3b\u8282\u70b9 \u00b6 kubeadm\u521d\u59cb\u5316 \u00b6 \u5728\u627f\u62c5\u4e3b\u8282\u70b9\u7684\u865a\u62df\u673a\u91cc\u914d\u7f6e\u63a7\u5236\u5e73\u9762\uff08Control Plane\uff09\u3002 \u68c0\u67e5 kubeadm \u5f53\u524d\u9ed8\u8ba4\u914d\u7f6e\u53c2\u6570\u3002 kubeadm config print init-defaults \u7c7b\u4f3c\u7ed3\u679c\u5982\u4e0b\u3002\u4fdd\u5b58\u9ed8\u8ba4\u914d\u7f6e\u7684\u7ed3\u679c\uff0c\u540e\u7eed\u4f1a\u4f5c\u4e3a\u53c2\u8003\u3002 apiVersion : kubeadm.k8s.io/v1beta3 bootstrapTokens : - groups : - system:bootstrappers:kubeadm:default-node-token token : abcdef.0123456789abcdef ttl : 24h0m0s usages : - signing - authentication kind : InitConfiguration localAPIEndpoint : advertiseAddress : 1.2.3.4 bindPort : 6443 nodeRegistration : criSocket : unix:///var/run/containerd/containerd.sock imagePullPolicy : IfNotPresent name : node taints : null --- apiServer : timeoutForControlPlane : 4m0s apiVersion : kubeadm.k8s.io/v1beta3 certificatesDir : /etc/kubernetes/pki clusterName : kubernetes controllerManager : {} dns : {} etcd : local : dataDir : /var/lib/etcd imageRepository : k8s.gcr.io kind : ClusterConfiguration kubernetesVersion : 1.24.0 networking : dnsDomain : cluster.local serviceSubnet : 10.96.0.0/12 scheduler : {} \u6a21\u62df\u5b89\u88c5\u548c\u6b63\u5f0f\u5b89\u88c5\u3002 \u901a\u8fc7\u547d\u4ee4 kubeadm init \u8fdb\u884c\u4e3b\u8282\u70b9\u7684\u521d\u59cb\u5316\uff0c\u4e0b\u9762\u662f\u8fd9\u4e2a\u547d\u4ee4\u4e3b\u8981\u53c2\u6570\u7684\u8bf4\u660e\uff0c\u7279\u522b\u662f\u7f51\u7edc\u53c2\u6570\u7684\u4e09\u4e2a\u9009\u62e9\u3002 --pod-network-cidr : \u6307\u5b9apod\u4f7f\u7528\u7684IP\u5730\u5740\u8303\u56f4\u3002\u5982\u679c\u6307\u5b9a\u4e86\u8be5\u53c2\u6570\uff0c\u5219Control Plane\u4f1a\u81ea\u52a8\u8bb2\u6307\u5b9a\u7684CIDR\u5206\u914d\u7ed9\u6bcf\u4e2a\u8282\u70b9\u3002 IP\u5730\u5740\u6bb5 10.244.0.0/16 \u662fFlannel\u7f51\u7edc\u7ec4\u4ef6\u9ed8\u8ba4\u7684\u5730\u5740\u8303\u56f4\u3002\u5982\u679c\u9700\u8981\u4fee\u6539Flannel\u7684IP\u5730\u5740\u6bb5\uff0c\u9700\u8981\u5728\u8fd9\u91cc\u6307\u5b9a\uff0c\u4e14\u5728\u90e8\u7f72Flannel\u65f6\u4e5f\u8981\u4fdd\u6301\u4e00\u81f4\u7684IP\u6bb5\u3002 --apiserver-bind-port : API\u670d\u52a1\uff08API Server\uff09\u7684\u7aef\u53e3\uff0c\u9ed8\u8ba4\u65f66443\u3002 --service-cidr : \u6307\u5b9a\u670d\u52a1\uff08service\uff09\u7684IP\u5730\u5740\u6bb5\uff0c\u9ed8\u8ba4\u662f 10.96.0.0/12 \u3002 \u63d0\u793a\uff1a \u670d\u52a1VIPs\uff08service VIPs\uff09\uff0c\u4e5f\u79f0\u4f5c\u96c6\u7fa4IP\uff08Cluster IP\uff09\uff0c\u901a\u8fc7\u53c2\u6570 --service-cidr \u6307\u5b9a\u3002 podCIDR\uff0c\u4e5f\u79f0\u4e3aendpoint IP\uff0c\u901a\u8fc7\u53c2\u6570 --pod-network-cidr \u6307\u5b9a\u3002 \u67094\u79cd\u5178\u578b\u7684\u7f51\u7edc\u95ee\u9898\uff1a \u9ad8\u5ea6\u8026\u5408\u7684\u5bb9\u5668\u4e0e\u5bb9\u5668\u4e4b\u95f4\u7684\u901a\u4fe1\uff1a\u8fd9\u53ef\u4ee5\u901a\u8fc7Pod\uff08podCIDR\uff09\u548c\u672c\u5730\u4e3b\u673a\u901a\u4fe1\u6765\u89e3\u51b3\u3002 Pod\u5bf9Pod\u901a\u4fe1\uff08Pod-to-Pod\uff09\uff1a \u4e5f\u88ab\u79f0\u4e3a\u5bb9\u5668\u5bf9\u5bb9\u5668\u901a\u4fe1\uff08container-to-container\uff09\u3002 \u5728Flannel\u7f51\u7edc\u63d2\u4ef6\u4e2d\u7684\u793a\u4f8b\u6d41\u7a0b\u662f\uff1aPod \u2192 veth\u5bf9 \u2192 cni0 \u2192 flannel.1 \u2192 \u5bbf\u4e3b\u673aeth0 \u2192 \u5bbf\u4e3b\u673aeth0 \u2192 flannel.1 \u2192 cni0 \u2192 veth\u5bf9 \u2192 Pod\u3002 Pod\u5bf9Service\u901a\u4fe1\uff08Pod-to-Service\uff09\uff1a \u6d41\u7a0b: Pod \u2192 \u5185\u6838 \u2192 Service iptables \u2192 Service \u2192 Pod iptables \u2192 Pod\u3002 \u5916\u90e8\u5bf9Service\u901a\u4fe1\uff08External-to-Service\uff09\uff1a \u8d1f\u8f7d\u5747\u8861\u5668: SLB \u2192 NodePort \u2192 Service \u2192 Pod\u3002 kube-proxy \u662f\u5bf9iptables\u8d1f\u8d23\uff0c\u4e0d\u662f\u7f51\u7edc\u6d41\u91cf\uff08traffic\uff09\u3002 kube-proxy \u662fKubernetes\u96c6\u7fa4\u4e2d\u7684\u4e00\u4e2a\u7ec4\u4ef6\uff0c\u8d1f\u8d23\u4e3aService\u63d0\u4f9b\u4ee3\u7406\u670d\u52a1\uff0c\u540c\u65f6\u4e5f\u662fKubernetes\u7f51\u7edc\u6a21\u578b\u4e2d\u7684\u91cd\u8981\u7ec4\u6210\u90e8\u5206\u4e4b\u4e00\u3002 kube-proxy \u4f1a\u5728\u6bcf\u4e2a\u8282\u70b9\u4e0a\u542f\u52a8\u4e00\u4e2a\u4ee3\u7406\u8fdb\u7a0b\uff0c\u901a\u8fc7\u76d1\u542cKubernetes API Server\u7684Service\u548cEndpoint\u7684\u53d8\u5316\u6765\u7ef4\u62a4\u4e00\u4e2a\u672c\u5730\u7684Service\u548cEndpoint\u7684\u7f13\u5b58\u3002\u5f53\u6709\u8bf7\u6c42\u5230\u8fbe\u67d0\u4e2aService\u65f6\uff0c kube-proxy \u4f1a\u6839\u636e\u8be5Service\u7684\u7c7b\u578b\uff08ClusterIP\u3001NodePort\u3001LoadBalancer\u3001ExternalName\uff09\u548c\u7aef\u53e3\u53f7\uff0c\u751f\u6210\u76f8\u5e94\u7684iptables\u89c4\u5219\uff0c\u5c06\u8bf7\u6c42\u8f6c\u53d1\u7ed9Service\u6240\u4ee3\u7406\u7684\u540e\u7aefPod\u3002 iptables\u662fLinux\u7cfb\u7edf\u4e2d\u7684\u4e00\u4e2a\u91cd\u8981\u7f51\u7edc\u5de5\u5177\uff0c\u53ef\u4ee5\u8bbe\u7f6eIP\u5305\u7684\u8fc7\u6ee4\u3001\u8f6c\u53d1\u548c\u4fee\u6539\u89c4\u5219\uff0c\u53ef\u4ee5\u5b9e\u73b0\u7f51\u7edc\u5c42\u7684\u9632\u706b\u5899\u3001NAT\u7b49\u529f\u80fd\u3002\u5728Kubernetes\u96c6\u7fa4\u4e2d\uff0c kube-proxy \u901a\u8fc7\u751f\u6210\u548c\u66f4\u65b0iptables\u89c4\u5219\uff0c\u6765\u5b9e\u73b0Service\u548cEndpoint\u4e4b\u95f4\u7684\u8f6c\u53d1\u548c\u4ee3\u7406\u3002\u5177\u4f53\u6765\u8bf4\uff0ckube-proxy\u4f1a\u4e3a\u6bcf\u4e2aService\u521b\u5efa\u4e09\u6761iptables\u89c4\u5219\u94fe\uff08nat\u8868\u4e2d\u7684KUBE-SERVICES\u548cKUBE-NODEPORTS\u94fe\uff0c\u4ee5\u53cafilter\u8868\u4e2d\u7684KUBE-SVC-XXXXX\u94fe\uff09\uff0c\u901a\u8fc7\u8fd9\u4e9b\u89c4\u5219\u94fe\uff0c\u5c06\u8bf7\u6c42\u8f6c\u53d1\u5230\u76f8\u5e94\u7684Pod\u6216\u8005Service\u4e0a\u3002 \u56e0\u6b64\uff0c kube-proxy \u548ciptables\u662f\u7d27\u5bc6\u76f8\u5173\u7684\u4e24\u4e2a\u7ec4\u4ef6\uff0c\u901a\u8fc7iptables\u89c4\u5219\u6765\u5b9e\u73b0Service\u548cPod\u4e4b\u95f4\u7684\u8f6c\u53d1\u548c\u4ee3\u7406\u3002\u8fd9\u79cd\u5b9e\u73b0\u65b9\u5f0f\u5177\u6709\u53ef\u6269\u5c55\u6027\u548c\u9ad8\u53ef\u7528\u6027\uff0c\u540c\u65f6\u4e5f\u63d0\u4f9b\u4e86\u4e00\u79cd\u7075\u6d3b\u7684\u7f51\u7edc\u6a21\u578b\uff0c\u53ef\u4ee5\u65b9\u4fbf\u5730\u5b9e\u73b0\u670d\u52a1\u53d1\u73b0\u3001\u8d1f\u8f7d\u5747\u8861\u7b49\u529f\u80fd\u3002 sudo kubeadm init \\ --dry-run \\ --pod-network-cidr = 10 .244.0.0/16 \\ --service-cidr 11 .244.0.0/16 \\ --image-repository = registry.aliyuncs.com/google_containers \\ --kubernetes-version = v1.24.0 sudo kubeadm init \\ --pod-network-cidr = 10 .244.0.0/16 \\ --service-cidr 11 .244.0.0/16 \\ --image-repository = registry.aliyuncs.com/google_containers \\ --kubernetes-version = v1.24.0 sudo kubeadm init \\ --pod-network-cidr = 10 .244.0.0/16 \\ --service-cidr 11 .244.0.0/16 \\ --kubernetes-version = v1.24.0 kubeconfig\u6587\u4ef6 \u00b6 \u7ed9\u5f53\u524d\u5b89\u88c5\u7528\u6237\u914d\u7f6e kubeconfig \u6587\u4ef6\uff08\u5f53\u524d\u4f8b\u5b50\u662f\u7528\u6237 vagrant \uff09\u3002 mkdir -p $HOME /.kube sudo cp -i /etc/kubernetes/admin.conf $HOME /.kube/config sudo chown $( id -u ) : $( id -g ) $HOME /.kube/config Kubernetes \u63d0\u4f9b\u4e86\u4e00\u4e2a\u547d\u4ee4\u884c\u5de5\u5177 kubectl \uff0c\u7528\u4e8e\u4f7f\u7528 Kubernetes API \u4e0e Kubernetes \u96c6\u7fa4\u7684\u63a7\u5236\u5e73\u9762\u8fdb\u884c\u901a\u4fe1\u3002 kubectl \u63a7\u5236 Kubernetes cluster manager \uff08\u96c6\u7fa4\u7ba1\u7406\u5668\uff09\u3002 \u5bf9\u4e8e\u914d\u7f6e\uff0ckubectl \u5728 $HOME/.kube \u76ee\u5f55\u4e2d\u67e5\u627e\u4e00\u4e2a\u540d\u4e3a config \u7684\u6587\u4ef6\uff0c\u8be5\u6587\u4ef6\u662f\u7531 kubeadm init \u751f\u6210\u7684\u6587\u4ef6 /etc/kubernetes/admin.conf \u7684\u526f\u672c\u3002 \u6211\u4eec\u53ef\u4ee5\u901a\u8fc7\u8bbe\u7f6e KUBECONFIG \u73af\u5883\u53d8\u91cf\u6216\u8bbe\u7f6e --kubeconfig flag \u6807\u5fd7\u6765\u6307\u5b9a\u5176\u4ed6 kubeconfig \u6587\u4ef6\u3002\u5982\u679c KUBECONFIG \u73af\u5883\u53d8\u91cf\u4e0d\u5b58\u5728\uff0ckubectl \u5c06\u4f7f\u7528\u9ed8\u8ba4\u7684 kubeconfig \u6587\u4ef6 $HOME/.kube/config \u3002 kubeconfig \u6587\u4ef6\u4e2d\u7684 context\uff08\u4e0a\u4e0b\u6587\uff09 \u5143\u7d20\u7528\u4e8e\u5c06\u8bbf\u95ee\u53c2\u6570\u5206\u7ec4\u5230\u4e00\u4e2a\u65b9\u4fbf\u7684\u540d\u79f0\u4e0b\u3002\u6bcf\u4e2a\u4e0a\u4e0b\u6587\u90fd\u6709\u4e09\u4e2a\u53c2\u6570\uff1a\u96c6\u7fa4\u3001\u547d\u540d\u7a7a\u95f4\u548c\u7528\u6237\u3002\u9ed8\u8ba4\u60c5\u51b5\u4e0b\uff0ckubectl \u547d\u4ee4\u884c\u5de5\u5177\u4f7f\u7528\u5f53\u524d\u4e0a\u4e0b\u6587\u4e2d\u7684\u53c2\u6570\u4e0e\u96c6\u7fa4\u901a\u4fe1\u3002 \u6587\u4ef6 .kube/config \u7684\u4f8b\u5b50\uff1a apiVersion : v1 clusters : - cluster : certificate-authority-data : server : https://:6443 name : contexts : - context : cluster : namespace : user : name : @ current-context : kind : Config preferences : {} users : - name : user : client-certificate-data : client-key-data : \u8bfb\u53d6\u5f53\u524d\u4e0a\u4e0b\u6587\uff1a kubectl config get-contexts \u8fd0\u884c\u7ed3\u679c\uff1a CURRENT NAME CLUSTER AUTHINFO NAMESPACE * kubernetes-admin@kubernetes kubernetes kubernetes-admin \u914d\u7f6e\u5de5\u4f5c\u8282\u70b9 \u00b6 \u4f7f\u7528 kubeadm token \u6765\u751f\u6210\u52a0\u5165\u96c6\u7fa4\u7684\u4ee4\u724c\uff08token\uff09\u548c\u54c8\u897f\u503c\uff08hash value\uff09\u3002 kubeadm token create --print-join-command \u5728\u6240\u6709\u5de5\u4f5c\u8282\u70b9\u4e0a\u6267\u884c\u4e0b\u9762\u7684\u547d\u4ee4\uff0c\u5c06\u5de5\u4f5c\u8282\u70b9\u52a0\u5165Kubernetes\u96c6\u7fa4\u3002 # kubeadm join :6443 --token --discovery-token-ca-cert-hash \u6267\u884c\u4e0b\u9762\u547d\u4ee4\u68c0\u67e5\u6240\u6709\u8282\u70b9\u7684\u72b6\u6001\u3002 \u5f53\u524d\u6240\u6709\u8282\u70b9\u7684\u72b6\u6001\u90fd\u662f NotReady \u3002\u76ee\u524d\u4e0d\u9700\u8981\u505a\u4ec0\u4e48\uff0c\u540e\u9762\u6211\u4eec\u4f1a\u5b89\u88c5\u76f8\u5173\u7684\u7f51\u7edc\u670d\u52a1\uff08Calico \u6216 Flannel\uff09\uff0c\u5404\u8282\u70b9\u7684\u72b6\u6001\u5c31\u4f1a\u53d8\u6210Ready\u72b6\u6001\u3002 \u5b89\u88c5Calico\u6216Flannel \u00b6 \u5728\u63a7\u5236\u5e73\u9762Control Plane\u4e0a\u5b89\u88c5Calico\u6216\u8005Flannel\u3002\u5982\u679c\u9700\u8981\u914d\u7f6e\u7f51\u7edc\u7b56\u7565\uff0c\u5219\u9009\u62e9Calico\u3002 \u5b89\u88c5Flannel \u00b6 Flannel \u662f\u4e3a Kubernetes \u8bbe\u8ba1\u7684\u4e00\u79cd\u7b80\u5355\u6613\u7528\u7684\u914d\u7f6e\u4e09\u5c42\u7f51\u7edc\u7684\u65b9\u6cd5\u3002 \u90e8\u7f72Flannel\uff1a \u5728 kube-flannel.yml \u4e2d\uff0c\u6211\u4eec\u53ef\u4ee5\u83b7\u53d6 Flannel \u7684\u9ed8\u8ba4\u7f51\u7edc\u8bbe\u7f6e\uff0c\u5b83\u4e0e\u6211\u4eec\u5728\u4f7f\u7528 kubeadm \u521d\u59cb\u5316\u96c6\u7fa4\u65f6\u6307\u5b9a\u7684\u53c2\u6570 --pod-network-cidr=10.244.0.0/16 \u76f8\u540c\u3002 net - co nf .jso n : | { \"Network\" : \"10.244.0.0/16\" , \"Backend\" : { \"Type\" : \"vxlan\" } } \u521b\u5efaFlannel\u670d\u52a1\u3002 apply -f https://raw.githubusercontent.com/coreos/flannel/master/Documentation/kube-flannel.yml \u8f93\u51fa\u7ed3\u679c\uff1a Warning: policy/v1beta1 PodSecurityPolicy is deprecated in v1.21+, unavailable in v1.25+ podsecuritypolicy.policy/psp.flannel.unprivileged created clusterrole.rbac.authorization.k8s.io/flannel created clusterrolebinding.rbac.authorization.k8s.io/flannel created serviceaccount/flannel created configmap/kube-flannel-cfg created daemonset.apps/kube-flannel-ds created \u5b89\u88c5Calico \u00b6 \u5b89\u88c5\u6307\u5bfc\u624b\u518c\uff1a End-to-end Calico installation \u3002 \u4e0b\u8f7d\u5e76\u5b89\u88c5Calico\u670d\u52a1\u3002 curl https://docs.projectcalico.org/manifests/calico.yaml -O kubectl apply -f calico.yaml \u8f93\u51fa\u7ed3\u679c\uff1a configmap/calico-config created customresourcedefinition.apiextensions.k8s.io/bgpconfigurations.crd.projectcalico.org created customresourcedefinition.apiextensions.k8s.io/bgppeers.crd.projectcalico.org created customresourcedefinition.apiextensions.k8s.io/blockaffinities.crd.projectcalico.org created customresourcedefinition.apiextensions.k8s.io/caliconodestatuses.crd.projectcalico.org created customresourcedefinition.apiextensions.k8s.io/clusterinformations.crd.projectcalico.org created customresourcedefinition.apiextensions.k8s.io/felixconfigurations.crd.projectcalico.org created customresourcedefinition.apiextensions.k8s.io/globalnetworkpolicies.crd.projectcalico.org created customresourcedefinition.apiextensions.k8s.io/globalnetworksets.crd.projectcalico.org created customresourcedefinition.apiextensions.k8s.io/hostendpoints.crd.projectcalico.org created customresourcedefinition.apiextensions.k8s.io/ipamblocks.crd.projectcalico.org created customresourcedefinition.apiextensions.k8s.io/ipamconfigs.crd.projectcalico.org created customresourcedefinition.apiextensions.k8s.io/ipamhandles.crd.projectcalico.org created customresourcedefinition.apiextensions.k8s.io/ippools.crd.projectcalico.org created customresourcedefinition.apiextensions.k8s.io/ipreservations.crd.projectcalico.org created customresourcedefinition.apiextensions.k8s.io/kubecontrollersconfigurations.crd.projectcalico.org created customresourcedefinition.apiextensions.k8s.io/networkpolicies.crd.projectcalico.org created customresourcedefinition.apiextensions.k8s.io/networksets.crd.projectcalico.org created clusterrole.rbac.authorization.k8s.io/calico-kube-controllers created clusterrolebinding.rbac.authorization.k8s.io/calico-kube-controllers created clusterrole.rbac.authorization.k8s.io/calico-node created clusterrolebinding.rbac.authorization.k8s.io/calico-node created daemonset.apps/calico-node created serviceaccount/calico-node created deployment.apps/calico-kube-controllers created serviceaccount/calico-kube-controllers created poddisruptionbudget.policy/calico-kube-controllers created \u9a8c\u8bc1Calico\u670d\u52a1\u72b6\u6001\uff1a kubectl get pod -n kube-system | grep calico \u8f93\u51fa\u7ed3\u679c\uff1a calico-kube-controllers-555bc4b957-l8bn2 0 /1 Pending 0 28s calico-node-255pc 0 /1 Init:1/3 0 29s calico-node-7tmnb 0 /1 Init:1/3 0 29s calico-node-w8nvl 0 /1 Init:1/3 0 29s \u68c0\u67e5\u96c6\u7fa4\u7684\u7f51\u7edc\u72b6\u6001\uff1a sudo nerdctl network ls \u8f93\u51fa\u7ed3\u679c\uff1a NETWORK ID NAME FILE k8s-pod-network /etc/cni/net.d/10-calico.conflist 0 bridge /etc/cni/net.d/nerdctl-bridge.conflist host none \u68c0\u67e5\u96c6\u7fa4\u72b6\u6001 \u00b6 \u5728\u4e3b\u8282\u70b9\u4e0a\u6267\u884c\u547d\u4ee4 kubectl cluster-info \u53ef\u4ee5\u5f97\u5230\u4e0b\u9762\u7684\u4fe1\u606f\uff1a \u63a7\u5236\u5e73\u9762\uff08control plane\uff09\u8fd0\u884c\u5728 https://:6443 CoreDNS\u670d\u52a1\u8fd0\u884c\u5728 https://:6443/api/v1/namespaces/kube-system/services/kube-dns:dns/proxy kubectl cluster-info \u67e5\u770b\u8282\u70b9\u8fd0\u884c\u72b6\u6001\u3002\u6b64\u65f6\uff0c\u6240\u6709\u8282\u70b9\u90fd\u662f Ready \u7684\u6b63\u5e38\u72b6\u6001\u4e86\u3002 OS Image: Ubuntu 20.04.4 LTS Kernel Version: 5.4.0-122-generic Container Runtime: containerd://1.5.9 kubectl get nodes -owide \u8f93\u51fa\u7ed3\u679c\uff1a NAME STATUS ROLES AGE VERSION cka001 Ready control-plane 13m v1.24.0 cka002 Ready 8m35s v1.24.0 cka003 Ready 8m26s v1.24.0 \u67e5\u770bPods\u7684\u72b6\u6001\u3002 kubectl get pod -A \u8f93\u51fa\u7ed3\u679c\uff1a NAMESPACE NAME READY STATUS RESTARTS AGE kube-system calico-kube-controllers-555bc4b957-l8bn2 1/1 Running 0 7m18s kube-system calico-node-255pc 1/1 Running 0 7m19s kube-system calico-node-7tmnb 1/1 Running 0 7m19s kube-system calico-node-w8nvl 1/1 Running 0 7m19s kube-system coredns-74586cf9b6-4jwmk 1/1 Running 0 15m kube-system coredns-74586cf9b6-c5mll 1/1 Running 0 15m kube-system etcd-cka001 1/1 Running 0 15m kube-system kube-apiserver-cka001 1/1 Running 0 15m kube-system kube-controller-manager-cka001 1/1 Running 0 15m kube-system kube-proxy-dmj2t 1/1 Running 0 15m kube-system kube-proxy-n77zw 1/1 Running 0 11m kube-system kube-proxy-qs6rf 1/1 Running 0 11m kube-system kube-scheduler-cka001 1/1 Running 0 15m \u66f4\u65b0\u5b89\u88c5 \u00b6 Bash\u81ea\u52a8\u8865\u5168 \u00b6 \u5728\u6bcf\u4e2a\u8282\u70b9\u4e0a\u914d\u7f6eBash\u81ea\u52a8\u8865\u5168\u529f\u80fd\u3002 \u53c2\u8003 \u6307\u5bfc \u8bbe\u7f6e kubectl \u81ea\u52a8\u8865\u5168\u529f\u80fdauto-completion \u3002 apt install -y bash-completion source /usr/share/bash-completion/bash_completion source < ( kubectl completion bash ) echo \"source <(kubectl completion bash)\" >> ~/.bashrc source ~/.bashrc \u522b\u540d \u00b6 \u5982\u679c\u6211\u4eec\u4e3a kubectl \u8bbe\u7f6e\u4e00\u4e2a\u522b\u540d\uff0c\u6211\u4eec\u53ef\u4ee5\u901a\u8fc7\u4e00\u4e9b\u65b9\u6cd5\u6765\u6269\u5c55 shell \u81ea\u52a8\u8865\u5168\u529f\u80fd\uff0c\u4f7f\u5176\u80fd\u591f\u4e0e\u8be5\u522b\u540d\u4e00\u8d77\u4f7f\u7528\u3002 \u4e00\u79cd\u65b9\u6cd5\u662f\u5728 Bash shell \u914d\u7f6e\u6587\u4ef6\uff08\u5982 .bashrc \u6216 .bash_profile\uff09\u4e2d\u8bbe\u7f6e\u522b\u540d\uff0c\u5e76\u4e3a\u8be5\u522b\u540d\u6307\u5b9a kubectl \u7684\u5b8c\u6574\u8def\u5f84\u3002\u4f8b\u5982\uff0c\u53ef\u4ee5\u5728 .bashrc \u6587\u4ef6\u4e2d\u6dfb\u52a0\u4ee5\u4e0b\u5185\u5bb9\uff1a alias k = 'path/to/kubectl' \u7136\u540e\uff0c\u53ef\u4ee5\u4f7f\u7528\u4ee5\u4e0b\u547d\u4ee4\u91cd\u65b0\u52a0\u8f7d .bashrc \u6587\u4ef6\uff1a source ~/.bashrc \u63a5\u4e0b\u6765\uff0c\u53ef\u4ee5\u4f7f\u7528 k \u547d\u4ee4\u6765\u4ee3\u66ff kubectl \u547d\u4ee4\uff0c\u5e76\u5728\u5176\u540e\u9762\u6dfb\u52a0\u76f8\u5e94\u7684\u53c2\u6570\u548c\u9009\u9879\u3002\u5f53\u4f7f\u7528\u81ea\u52a8\u8865\u5168\u529f\u80fd\u65f6\uff0cBash shell \u4f1a\u81ea\u52a8\u5c06 k \u522b\u540d\u8f6c\u6362\u4e3a kubectl \u7684\u5b8c\u6574\u8def\u5f84\uff0c\u5e76\u5bf9\u5176\u8fdb\u884c\u81ea\u52a8\u8865\u5168\u3002 \u53e6\u4e00\u79cd\u65b9\u6cd5\u662f\u4f7f\u7528 Bash shell \u5185\u7f6e\u7684 complete \u51fd\u6570\u6765\u4e3a\u522b\u540d\u8bbe\u7f6e\u81ea\u52a8\u8865\u5168\u529f\u80fd\u3002\u4f8b\u5982\uff0c\u53ef\u4ee5\u5728 .bashrc \u6587\u4ef6\u4e2d\u6dfb\u52a0\u4ee5\u4e0b\u5185\u5bb9\uff1a echo 'alias k=kubectl' >>~/.bashrc echo 'complete -o default -F __start_kubectl k' >>~/.bashrc \u8fd9\u5c06\u4e3a\u522b\u540d k \u8bbe\u7f6e\u81ea\u52a8\u8865\u5168\u529f\u80fd\uff0c\u5e76\u5c06\u5176\u4e0e kubectl \u7684\u81ea\u52a8\u8865\u5168\u51fd\u6570 __start_kubectl \u5173\u8054\u8d77\u6765\u3002\u8fd9\u6837\uff0c\u5f53\u7528\u6237\u5728 k \u547d\u4ee4\u540e\u8f93\u5165Tab\u952e\u65f6\uff0cBash shell \u4f1a\u81ea\u52a8\u8c03\u7528 __start_kubectl \u51fd\u6570\uff0c\u5e76\u4e3a\u7528\u6237\u63d0\u4f9b\u76f8\u5e94\u7684\u81ea\u52a8\u8865\u5168\u5efa\u8bae\u3002 \u66f4\u65b0\u9ed8\u8ba4Context \u00b6 \u67e5\u770b\u5f53\u524d\u7684 context \u5217\u8868\uff1a kubectl config get-contexts \u8fd9\u4e2a\u547d\u4ee4\u4f1a\u5217\u51fa\u6240\u6709\u53ef\u7528\u7684 context \u5217\u8868\uff0c\u5e76\u6807\u8bb0\u51fa\u5f53\u524d\u6b63\u5728\u4f7f\u7528\u7684 context\u3002 \u7c7b\u4f3c\u4e0b\u9762\u7ed3\u679c\uff1a kubernetes-admin@kubernetes \u662fContext\u540d\u3002 kubernetes \u662f\u96c6\u7fa4\u540d\u3002 kubernetes-admin \u662f\u7528\u6237\u540d\u3002 \u5f53\u524d\u4f8b\u5b50\u4e2d\u6ca1\u6709\u6307\u5b9a\u540d\u79f0\u7a7a\u95f4\u3002 CURRENT NAME CLUSTER AUTHINFO NAMESPACE * kubernetes-admin@kubernetes kubernetes kubernetes-admin \u66f4\u65b0context\u3002\u4f8b\u5982\uff0c\u66f4\u65b0context\u7684\u9ed8\u8ba4\u540d\u79f0\u7a7a\u95f4\u7b49\u3002 # Usage: kubectl config set-context --cluster = --namespace = --user = # Set default namespace kubectl config set-context kubernetes-admin@kubernetes --cluster = kubernetes --namespace = default --user = kubernetes-admin \u5728\u4e0d\u540c\u7684context\u4e4b\u95f4\u5207\u6362\u3002 # Usage: kubectl config use-context # Switch to new context kubectl config use-context kubernetes-admin@kubernetes \u53c2\u8003\u8d44\u6599\uff1a kubectl [commandline \u91cd\u7f6e\u96c6\u7fa4 \u00b6 \u6ce8\u610f\uff1a\u4e0b\u9762\u7684\u64cd\u4f5c\u4f1a\u91cd\u7f6e\u5f53\u524d\u96c6\u7fa4\uff08\u5220\u9664\u96c6\u7fa4\uff09\u3002 \u5220\u9664\u96c6\u7fa4\u4e2d\u6240\u6709\u8282\u70b9\u3002 kubeadm reset \u6e05\u9664 iptables \u4e2d\u5df2\u5b9a\u4e49\u7684\u89c4\u5219\u3002 iptables -F && iptables -t nat -F && iptables -t mangle -F && iptables -X \u6e05\u9664 IPVS \u4e2d\u5b9a\u4e49\u7684\u89c4\u5219\uff08\u5982\u679c\u4f7f\u7528 IPVS \uff09\u3002 ipvsadm --clear \u6392\u9519 \u00b6 \u9519\u8bef1 \u00b6 \u62a5\u9519\u4fe1\u606f\uff1a The connection to the server :6443 was refused - did you specify the right host or port? \u89e3\u51b3\u5c1d\u8bd5\uff1a Reference \u68c0\u67e5\u6587\u4ef6kubeconfig\u7684\u5185\u5bb9\u548c\u6587\u4ef6\u8def\u5f84\u662f\u5426\u6b63\u786e\u3002 \u68c0\u67e5\u73af\u5883\u53d8\u91cf\u8bbe\u7f6e\u3002 env | grep -i kub \u68c0\u67e5\u5bb9\u5668\u8fd0\u884c\u72b6\u6001\u3002 sudo systemctl status containerd.service \u68c0\u67e5kubelet\u670d\u52a1\u3002 sudo systemctl status kubelet.service \u68c0\u67e5 6443 \u7aef\u53e3\u76d1\u542c\u72b6\u6001\u3002 netstat -pnlt | grep 6443 \u68c0\u67e5\u9632\u706b\u5899\u72b6\u6001\u3002 sudo systemctl status firewalld.service \u68c0\u67e5kubelet\u65e5\u5fd7\u3002 journalctl -xeu kubelet \u9519\u8bef2 \u00b6 \u62a5\u9519\u4fe1\u606f\uff1a \"Container runtime network not ready\" networkReady=\"NetworkReady=false reason:NetworkPluginNotReady message:Network plugin returns error: cni plugin not initialized\" \u5c1d\u8bd5\u65b9\u6cd5\uff1a \u91cd\u542fContainerd\u670d\u52a1\u3002 sudo systemctl restart containerd sudo systemctl status containerd","title":"\u963f\u91cc\u4e91ECS\u5b89\u88c5Kubernetes"},{"location":"k8s/cka_cn/installation/aliyun-ubuntu/#cka3ecskubernetes","text":"","title":"CKA\u81ea\u5b66\u7b14\u8bb03:\u963f\u91cc\u4e91ECS\u5b89\u88c5Kubernetes"},{"location":"k8s/cka_cn/installation/aliyun-ubuntu/#_1","text":"\u5728\u963f\u91cc\u4e91ECS\u88c5\u4e09\u53f0Ubuntu\u865a\u62df\u673a\u3002\u5728Ubuntu\u865a\u62df\u673a\u4e2d\u5b89\u88c5\u57fa\u4e8eContainerd\u7684Kubernetes\u7cfb\u7edf\uff0c\u5e76\u5206\u522b\u914d\u7f6e\u4e00\u4e2a\u4e3b\u8282\u70b9Master\u548c\u4e24\u4e2a\u5de5\u4f5c\u8282\u70b9Worker\uff0c\u3002","title":"\u6458\u8981"},{"location":"k8s/cka_cn/installation/aliyun-ubuntu/#_2","text":"\u6ce8\u518c\u963f\u91cc\u4e91\u8d26\u53f7\uff1a Alibaba Cloud home console \u3002\u6ce8\u610f\u4fdd\u7559\u8bbf\u95ee\u5bc6\u94a5key\u6587\u4ef6\uff0c\u53ea\u80fd\u5bfc\u51fa\u4e00\u6b21\uff0c\u5f53\u524d\u7ec3\u4e60\u4e2dkey\u6587\u4ef6\u662f aliyun-root \u3002 \u53c2\u8003\u4e0b\u9762\u914d\u7f6e\u6ce8\u518c\u7533\u8bf7\u4e09\u4e2aECS\uff08Elastic Computer Service\uff09\u670d\u52a1\u5b9e\u4f8b\uff1a \u4e3b\u673a\uff1a2vCPU+4GiB \u64cd\u4f5c\u7cfb\u7edf\uff1aUbuntu 20.04 x86_64 \u5b9e\u4f8b\u7c7b\u578b\uff1aecs.sn1.medium \u5b9e\u4f8b\u540d\u79f0\uff1acka001, cka002, cka003 \u7f51\u7edc\u914d\u7f6e\uff1aboth public IPs and private IPs \u6700\u5927\u7f51\u7edc\u5e26\u5bbd\uff1a100Mbps (Peak Value) \u4e91\u76d8\uff1a40GiB \u652f\u4ed8\u65b9\u5f0f\uff1a\u62a2\u5360\u5f0f\u5b9e\u4f8b \u5728\u672c\u5730\u6253\u5f00\u7ec8\u7aef\u7a97\u53e3\uff0c\u901a\u8fc7\u5bc6\u94a5\u6587\u4ef6 aliyun-root \u8bbf\u95ee\u8fdc\u7a0bECS\u8282\u70b9 cka001 \u3002 ssh -i aliyun-root root@cka001 \u521b\u5efa\u4e00\u4e2a\u666e\u901a\u7528\u6237\uff0c\u7528\u6765\u5b89\u88c5Kubernetes\uff0c\u5f53\u524d\u7ec3\u4e60\u4e2d\u521b\u5efa\u7528\u6237 vagrant \uff0c\u4e14\u4fee\u6539\u8be5\u7528\u6237\u7684\u4e3b\u8981\u7ec4\u4e3a sudo \u6b21\u8981\u7ec4\u5305\u542b root \u3002 adduser vagrant usermod -g sudo vagrant usermod -a -G root vagrant \u65b0\u5f00\u4e00\u4e2a\u672c\u5730\u7ec8\u7aef\u7a97\u53e3\uff0c\u4e3a\u7528\u6237 vagrant \u521b\u5efa\u5bc6\u94a5key\u3002 # Windows ssh-keygen.exe # Linux ssh-keygen \u4e0a\u9762\u7684\u547d\u4ee4\u4f1a\u751f\u62102\u4e2a\u6587\u4ef6\uff0c\u5f53\u524d\u7ec3\u4e60\u4e2d\u8fd92\u4e2a\u6587\u4ef6\u662f aliyun-vagrant and aliyun-vagrant.pub \u901a\u8fc7 sftp \u547d\u4ee4\u5c06\u516c\u94a5\u6587\u4ef6 aliyun-vagrant.pub \u4e0a\u4f20\u5230\u8fdc\u7a0b\u8282\u70b9 cka001 \u3002 sftp -i aliyun-root root@cka001 put aliyun-vagrant.pub \u65b0\u5f00\u4e00\u4e2a\u7ec8\u7aef\u7a97\u53e3\uff0c\u7528 root \u7684\u5bc6\u94a5\u767b\u5f55 cka001 \u8282\u70b9\u3002 \u5c06\u4e0a\u4e00\u6b65\u4e0a\u4f20\u7684\u5bc6\u94a5\u6587\u4ef6 aliyun-vagrant.pub \u4ece /root \u76ee\u5f55\u62f7\u8d1d\u5230 /home/vagrant/.ssh/ \u3002 \u5c06\u516c\u94a5\u6587\u4ef6 aliyun-vagrant.pub \u91cd\u547d\u540d\u4e3a authorized_keys \u3002 \u66f4\u6539\u6587\u4ef6 authorized_keys \u7684\u6240\u6709\u8005owner\u4e3a vagrant . \u66f4\u6539\u6587\u4ef6 authorized_keys \u7684\u4e3b\u8981\u7ec4\u4e3a sudo \u3002 mkdir /home/vagrant/.ssh/ mv aliyun-james.pub /home/vagrant/.ssh/authorized_keys chown vagrant.sudo /home/vagrant/.ssh/authorized_keys chmod 600 /home/vagrant/.ssh/authorized_keys \u68c0\u67e5\u6587\u4ef6 /etc/ssh/sshd_config \uff0c\u786e\u5b9a\u5bc6\u7801\u767b\u5f55\u9a8c\u8bc1\u53c2\u6570 asswordAuthentication \u8bbe\u5b9a\u4e3a no \uff0c\u5373\u53ea\u80fd\u901a\u8fc7\u8bc1\u4e66\u8fdc\u7a0b\u767b\u5f55\u3002 cat /etc/ssh/sshd_config \u65b0\u5f00\u4e00\u4e2a\u7ec8\u7aef\u7a97\u53e3\uff0c\u4f7f\u7528\u7528\u6237vagrant\u767b\u5f55\u8fdc\u7a0b\u8282\u70b9 cka001 \uff0c\u9a8c\u8bc1\u7528\u6237 vagrant \u80fd\u901a\u8fc7\u524d\u9762\u521b\u5efa\u7684\u8bc1\u4e66\u767b\u5f55\u8282\u70b9 cka001 \u3002 ssh -i aliyun-vagrant vagrant@cka001 \u91cd\u590d\u4e0a\u8ff0\u6b65\u9aa4\uff0c\u901a\u8fc7 sftp \u547d\u4ee4\u5c06\u516c\u94a5\u6587\u4ef6 aliyun-vagrant.pub \u5206\u522b\u4e0a\u4f20\u5230\u8fdc\u7a0b\u8282\u70b9 cka002 \u548c cka003 \uff0c\u4e14\u5b8c\u6210\u540c\u6837\u7684\u914d\u7f6e\uff0c\u4f7f\u7528\u6237 vagrant \u4e5f\u80fd\u901a\u8fc7\u5bc6\u94a5\u6587\u4ef6\u767b\u5f55\u8fdc\u7a0b\u8282\u70b9 cka002 \u548c cka003 \u3002 \u81f3\u6b64\uff0c\u7528\u6237 vagrant \u53ef\u4ee5\u901a\u8fc7\u5bc6\u94a5\u6587\u4ef6 aliyun-vagrant \u4ece\u672c\u5730\u7ec8\u7aef\u7a97\u53e3\u767b\u5f55\u8fdc\u7a0b\u8282\u70b9 cka001 , cka002 \u548c cka003 \u3002 \u4e0b\u9762\u6240\u6709\u6b65\u9aa4\u90fd\u662f\u901a\u8fc7\u7528\u6237 vagrant \u5b8c\u6210\u3002","title":"\u51c6\u5907\u5de5\u4f5c"},{"location":"k8s/cka_cn/installation/aliyun-ubuntu/#ecs","text":"","title":"\u521d\u59cb\u5316ECS\u8282\u70b9"},{"location":"k8s/cka_cn/installation/aliyun-ubuntu/#etchosts","text":"\u66f4\u65b0\u6240\u6709ECS\u8282\u70b9\u7684\u6587\u4ef6/etc/hosts\uff0c\u6dfb\u52a0\u5176\u4ed6\u8282\u70b9\u7684\u79c1\u6709IP\uff08private IP\uff09\u3002 vi /etc/hosts","title":"\u914d\u7f6e\u6587\u4ef6/etc/hosts"},{"location":"k8s/cka_cn/installation/aliyun-ubuntu/#firewall","text":"\u5728\u6240\u6709\u8282\u70b9\u4e0a\u7981\u7528\u9632\u706b\u5899\u3002 sudo ufw disable \u68c0\u67e5\u9632\u706b\u5899\u72b6\u6001\u3002 sudo ufw status verbose","title":"\u7981\u7528firewall"},{"location":"k8s/cka_cn/installation/aliyun-ubuntu/#swap","text":"\u5728\u6240\u6709\u8282\u70b9\u4e0a\u5173\u95edswap\u3002 sudo swapoff -a","title":"\u5173\u95edswap"},{"location":"k8s/cka_cn/installation/aliyun-ubuntu/#_3","text":"\u5728\u6240\u6709\u8282\u70b9\u8bbe\u5b9a\u65f6\u533a\u548c\u5730\u57df\u3002\u8fd9\u4e00\u5e03\u5728\u521d\u59cb\u5316ECS\u65f6\u5019\u5df2\u7ecf\u5b8c\u6210\u3002\u53ef\u4ee5\u901a\u8fc7\u4e0b\u9762\u547d\u4ee4\u8fdb\u884c\u8bbe\u5b9a\u3002 ln -sf /usr/share/zoneinfo/Asia/Shanghai /etc/localtime sudo echo 'LANG=\"en_US.UTF-8\"' >> /etc/profile source /etc/profile \u901a\u8fc7\u4e0b\u9762\u547d\u4ee4\u68c0\u67e5\u65f6\u533a\u548c\u5730\u57df\u7684\u8bbe\u7f6e\u3002 ll /etc/localtime lrwxrwxrwx 1 root root 33 Jul 5 14:51 /etc/localtime -> /usr/share/zoneinfo/Asia/Shanghai","title":"\u8bbe\u7f6e\u65f6\u533a\u548c\u5730\u57df"},{"location":"k8s/cka_cn/installation/aliyun-ubuntu/#_4","text":"\u5728\u6240\u6709\u8282\u70b9\u4e0a\u6267\u884c\u4e0b\u9762\u7684\u547d\u4ee4\u4ee5\u914d\u7f6e\u5185\u6838\u3002 \u4f7f\u7528\u6a21\u5757overlay\uff1a \u521b\u5efaContainerd\u670d\u52a1\u914d\u7f6e\u6587\u4ef6 /etc/modules-load.d/containerd.conf \uff0c\u5982\u679c\u5df2\u5b58\u5728\u5219\u8df3\u8fc7\u8fd9\u4e00\u6b65\u3002\u914d\u7f6e\u8fd9\u4e2a\u6587\u4ef6\u7684\u76ee\u7684\u662f\u4e3a\u4e86\u52a0\u8f7d\u6a21\u5757 overlay \u548c br_netfilter \u5230\u5185\u6838\u4e2d\u3002 \u670d\u52a1Containerd\u4f9d\u8d56\u6a21\u5757 overlay \u5b9e\u73b0 overlay-filesystem \u6587\u4ef6\u7cfb\u7edf\u529f\u80fd\u3002 Linux\u4e2d\u7684overlay\u6a21\u5757\u63d0\u4f9b\u4e86\u521b\u5efa\u4e24\u4e2a\u76ee\u5f55\u7684\u5408\u5e76\u89c6\u56fe\u7684\u80fd\u529b\uff0c\u8fd9\u4e24\u4e2a\u76ee\u5f55\u79f0\u4e3a\u5c42\u3002\u5b83\u7ecf\u5e38\u88ab\u7528\u4e8e\u5b9e\u73b0\u8054\u5408\u6302\u8f7d\uff0c\u8fd9\u662f\u4e00\u79cd\u5c06\u4e24\u4e2a\u6216\u66f4\u591a\u76ee\u5f55\u4e00\u8d77\u6302\u8f7d\u7684\u65b9\u5f0f\uff0c\u5c31\u50cf\u5b83\u4eec\u662f\u4e00\u4e2a\u76ee\u5f55\u4e00\u6837\uff08union-filesystems\uff09\u3002 overlay\u6a21\u5757\u5728\u5bb9\u5668\u6280\u672f\u4e2d\u88ab\u5e7f\u6cdb\u4f7f\u7528\uff0c\u6bd4\u5982Docker\uff0c\u56e0\u4e3a\u5b83\u5141\u8bb8\u591a\u4e2a\u5bb9\u5668\u5171\u4eab\u57fa\u7840\u955c\u50cf\uff0c\u540c\u65f6\u4fdd\u6301\u5b83\u4eec\u81ea\u5df1\u7684\u6587\u4ef6\u7cfb\u7edf\u3002 \u8981\u4f7f\u7528overlay\u6a21\u5757\uff0c\u9700\u8981\u4e24\u4e2a\u76ee\u5f55\uff1a\u8f83\u4f4e\u7684\u76ee\u5f55\uff08lower directory\uff09\u548c\u8f83\u9ad8\u7684\u76ee\u5f55\uff08upper directory\uff09\u3002\u8f83\u4f4e\u7684\u76ee\u5f55\u901a\u5e38\u662f\u53ea\u8bfb\u7684\uff0c\u5305\u542b\u539f\u59cb\u6587\u4ef6\uff0c\u800c\u8f83\u9ad8\u7684\u76ee\u5f55\u662f\u53ef\u8bfb\u5199\u7684\uff0c\u5305\u542b\u5bf9\u6587\u4ef6\u7684\u66f4\u6539\u3002\u5f53\u8bf7\u6c42\u6587\u4ef6\u65f6\uff0coverlay\u6a21\u5757\u9996\u5148\u67e5\u627e\u4e0a\u5c42\u76ee\u5f55\uff0c\u5982\u679c\u672a\u627e\u5230\uff0c\u5219\u67e5\u627e\u4e0b\u5c42\u76ee\u5f55\u3002 \u6bd4\u5982\uff1a \u521b\u5efa\u4e24\u4e2a\u76ee\u5f55\uff0c\u4e00\u4e2a\u7528\u4e8e\u8f83\u4f4e\u7684\u76ee\u5f55\uff0c\u4e00\u4e2a\u7528\u4e8e\u8f83\u9ad8\u7684\u76ee\u5f55\u3002\u7136\u540e\u4f7f\u7528overlay\u6587\u4ef6\u7cfb\u7edf\u7c7b\u578b\u5c06\u5b83\u4eec\u6302\u8f7d\u8d77\u6765\uff1a sudo mkdir /lower sudo mkdir /upper sudo mount -t overlay overlay -o lowerdir = /lower,upperdir = /upper /merged \u5728\u4e0a\u9762\u7684\u4f8b\u5b50\u4e2d\uff0c\u4e24\u4e2a\u76ee\u5f55\u7684\u5408\u5e76\u89c6\u56fe\u88ab\u521b\u5efa\u5728 /merged \u76ee\u5f55\u4e2d\u3002\u5728 /merged \u76ee\u5f55\u4e2d\u5bf9\u6587\u4ef6\u6240\u505a\u7684\u4efb\u4f55\u66f4\u6539\u90fd\u5b58\u50a8\u5728\u4e0a\u5c42\u76ee\u5f55\u4e2d\uff0c\u800c\u539f\u59cb\u6587\u4ef6\u4ecd\u7136\u5728\u4e0b\u5c42\u76ee\u5f55\u4e2d\u3002 \u4f7f\u7528\u6a21\u5757br_netfilter\uff1a br_netfilter \u662fLinux\u5185\u6838\u4e2d\u7684\u4e00\u4e2a\u6a21\u5757\uff0c\u5b83\u63d0\u4f9b\u4e86\u4e00\u79cd\u673a\u5236\u6765\u8fc7\u6ee4\u7f51\u6865\u7684\u7f51\u7edc\u6d41\u91cf\u3002\u8be5\u6a21\u5757\u5141\u8bb8\u7ba1\u7406\u5458\u914d\u7f6e\u89c4\u5219\uff0c\u4ee5\u5141\u8bb8\u6216\u62d2\u7edd\u7279\u5b9a\u7684\u7f51\u7edc\u6d41\u91cf\u901a\u8fc7\u7f51\u6865\u3002 \u7f51\u6865\u662f\u4e00\u79cd\u7f51\u7edc\u8bbe\u5907\uff0c\u5b83\u53ef\u4ee5\u8fde\u63a5\u591a\u4e2a\u7f51\u7edc\u6bb5\uff0c\u5e76\u8f6c\u53d1\u6d41\u91cf\u4ee5\u4f7f\u4e0d\u540c\u7684\u7f51\u7edc\u6bb5\u4e4b\u95f4\u901a\u4fe1\u3002 br_netfilter \u6a21\u5757\u53ef\u4ee5\u7528\u6765\u9650\u5236\u6216\u8fc7\u6ee4\u8fd9\u4e9b\u6d41\u91cf\u3002 \u5f53\u542f\u7528\u4e86 br_netfilter \u6a21\u5757\u65f6\uff0c\u5b83\u4f1a\u81ea\u52a8\u542f\u7528\u4e00\u4e2a\u79f0\u4e3a bridge-nf \u7684\u529f\u80fd\uff0c\u8be5\u529f\u80fd\u5c06\u5728\u7f51\u7edc\u6d41\u91cf\u901a\u8fc7\u7f51\u6865\u65f6\u5e94\u7528\u89c4\u5219\u3002\u7ba1\u7406\u5458\u53ef\u4ee5\u4f7f\u7528iptables\u7b49\u5de5\u5177\u6765\u914d\u7f6e\u8fd9\u4e9b\u89c4\u5219\u3002\u4f8b\u5982\uff0c\u6211\u4eec\u53ef\u4ee5\u8bbe\u5b9a\u5141\u8bb8\u4ece\u4e00\u4e2a\u7f51\u7edc\u6bb5\u5230\u53e6\u4e00\u4e2a\u7f51\u7edc\u6bb5\u7684\u6d41\u91cf\uff0c\u6216\u8005\u62d2\u7edd\u6765\u81ea\u7279\u5b9aIP\u5730\u5740\u6216\u7aef\u53e3\u7684\u6d41\u91cf\u3002 \u5728Kubernetes\u4e2d\uff0c br_netfilter \u6a21\u5757\u4e3b\u8981\u7528\u4e8e\u542f\u7528Kubernetes\u670d\u52a1\u7684\u6d41\u91cf\u8f6c\u53d1\u548c\u8d1f\u8f7d\u5747\u8861\u3002\u8fd9\u4e9b\u670d\u52a1\u4f7f\u7528\u4e86Linux\u5185\u6838\u4e2d\u7684iptables\u89c4\u5219\u6765\u7ba1\u7406\u6d41\u91cf\uff0c\u8fd9\u4e9b\u89c4\u5219\u662f\u901a\u8fc7 br_netfilter \u6a21\u5757\u5b9e\u73b0\u7684\u3002 \u5177\u4f53\u6765\u8bf4\uff0c\u5f53\u6211\u4eec\u5728Kubernetes\u96c6\u7fa4\u4e2d\u521b\u5efa\u4e00\u4e2a\u670d\u52a1\u65f6\uff0c\u8be5\u670d\u52a1\u5c06\u5206\u914d\u4e00\u4e2a\u865a\u62dfIP\u5730\u5740\uff0c\u7528\u4e8e\u4ee3\u8868\u670d\u52a1\u3002\u7136\u540e\uff0c\u901a\u8fc7iptables\u89c4\u5219\uff0c\u5c06\u8fd9\u4e2a\u865a\u62dfIP\u5730\u5740\u6620\u5c04\u5230\u4e00\u4e2a\u6216\u591a\u4e2a\u540e\u7aefPod\u7684IP\u5730\u5740\uff0c\u4ee5\u4fbf\u5728\u9700\u8981\u65f6\u5c06\u6d41\u91cf\u8def\u7531\u5230\u8fd9\u4e9bPod\u3002 \u5728\u8fd9\u4e2a\u8fc7\u7a0b\u4e2d\uff0c br_netfilter \u6a21\u5757\u8d1f\u8d23\u76d1\u89c6\u670d\u52a1\u7684\u6d41\u91cf\uff0c\u5e76\u6839\u636eiptables\u89c4\u5219\u8fdb\u884c\u8f6c\u53d1\u548c\u8d1f\u8f7d\u5747\u8861\u3002\u8fd9\u5305\u62ec\u8fc7\u6ee4\u6765\u81ea\u4e0d\u53d7\u4fe1\u4efb\u6e90\u7684\u6d41\u91cf\u4ee5\u53ca\u9650\u5236\u670d\u52a1\u7684\u8bbf\u95ee\u6743\u9650\u3002 \u9700\u8981\u6ce8\u610f\u7684\u662f\uff0c\u4e3a\u4e86\u542f\u7528Kubernetes\u670d\u52a1\u7684\u6d41\u91cf\u8f6c\u53d1\u548c\u8d1f\u8f7d\u5747\u8861\uff0c br_netfilter \u6a21\u5757\u5fc5\u987b\u5728\u6240\u6709\u8282\u70b9\u4e0a\u542f\u7528\uff0c\u5e76\u4e14\u5fc5\u987b\u914d\u7f6e\u6b63\u786e\u7684iptables\u89c4\u5219\u3002 \u7531\u4e8e br_netfilter \u6a21\u5757\u7684\u4f5c\u7528\u975e\u5e38\u5173\u952e\uff0c\u56e0\u6b64\u5728\u5347\u7ea7\u6216\u66f4\u6539\u7cfb\u7edf\u65f6\u9700\u8981\u7279\u522b\u6ce8\u610f\u5b83\u7684\u914d\u7f6e\u548c\u72b6\u6001\u3002 \u4e0b\u9762\u547d\u4ee4\u5c06\u6a21\u5757 overlay \u548c br_netfilter \u6dfb\u52a0\u5230\u914d\u7f6e\u6587\u4ef6 containerd.conf \u4e2d\u3002 cat < /etc/apt/sources.list << EOF deb http://mirrors.cloud.aliyuncs.com/ubuntu/ focal main restricted deb-src http://mirrors.cloud.aliyuncs.com/ubuntu/ focal main restricted deb http://mirrors.cloud.aliyuncs.com/ubuntu/ focal-updates main restricted deb-src http://mirrors.cloud.aliyuncs.com/ubuntu/ focal-updates main restricted deb http://mirrors.cloud.aliyuncs.com/ubuntu/ focal universe deb-src http://mirrors.cloud.aliyuncs.com/ubuntu/ focal universe deb http://mirrors.cloud.aliyuncs.com/ubuntu/ focal-updates universe deb-src http://mirrors.cloud.aliyuncs.com/ubuntu/ focal-updates universe deb http://mirrors.cloud.aliyuncs.com/ubuntu/ focal multiverse deb-src http://mirrors.cloud.aliyuncs.com/ubuntu/ focal multiverse deb http://mirrors.cloud.aliyuncs.com/ubuntu/ focal-updates multiverse deb-src http://mirrors.cloud.aliyuncs.com/ubuntu/ focal-updates multiverse deb http://mirrors.cloud.aliyuncs.com/ubuntu/ focal-backports main restricted universe multiverse deb-src http://mirrors.cloud.aliyuncs.com/ubuntu/ focal-backports main restricted universe multivers deb http://mirrors.cloud.aliyuncs.com/ubuntu focal-security main restricted deb-src http://mirrors.cloud.aliyuncs.com/ubuntu focal-security main restricted deb http://mirrors.cloud.aliyuncs.com/ubuntu focal-security universe deb-src http://mirrors.cloud.aliyuncs.com/ubuntu focal-security universe # deb http://mirrors.cloud.aliyuncs.com/ubuntu focal-security multiverse # deb-src http://mirrors.cloud.aliyuncs.com/ubuntu focal-security multiverse EOF \u5b89\u88c5Containered\u3002 sudo apt-get update && sudo apt-get install -y containerd \u914d\u7f6eContainerd\u3002\u4fee\u6539\u6587\u4ef6 /etc/containerd/config.toml \u3002 sudo mkdir -p /etc/containerd containerd config default | sudo tee /etc/containerd/config.toml sudo vi /etc/containerd/config.toml \u4fee\u6539\u53c2\u6570 sandbox_image \u7684\u503c\u4e3a \"registry.aliyuncs.com/google_containers/pause:3.6\" \u3002 \u4fee\u6539\u53c2\u6570 SystemdCgroup \u7684\u503c\u4e3a true \u3002 [plugins] [plugins.\"io.containerd.gc.v1.scheduler\"] [plugins.\"io.containerd.grpc.v1.cri\"] sandbox_image = \"registry.aliyuncs.com/google_containers/pause:3.6\" [plugins.\"io.containerd.grpc.v1.cri\".cni] [plugins.\"io.containerd.grpc.v1.cri\".containerd] [plugins.\"io.containerd.grpc.v1.cri\".containerd.default_runtime] [plugins.\"io.containerd.grpc.v1.cri\".containerd.default_runtime.options] [plugins.\"io.containerd.grpc.v1.cri\".containerd.runtimes] [plugins.\"io.containerd.grpc.v1.cri\".containerd.runtimes.runc] [plugins.\"io.containerd.grpc.v1.cri\".containerd.runtimes.runc.options] SystemdCgroup = true \u91cd\u542fContainerd\u670d\u52a1\u3002 sudo systemctl restart containerd sudo systemctl status containerd","title":"\u5b89\u88c5Containerd"},{"location":"k8s/cka_cn/installation/aliyun-ubuntu/#nerdctl","text":"\u5728\u6240\u6709\u8282\u70b9\u4e0a\u5b89\u88c5nerdctl\u670d\u52a1\u3002 nerdctl \u670d\u52a1\u652f\u6301Contanerd\u6240\u63d0\u4f9b\u7684\u5bb9\u5668\u5316\u7279\u6027\uff0c\u7279\u522b\u662f\u4e00\u4e9bDocker\u4e0d\u5177\u5907\u7684\u65b0\u7279\u6027\u3002 \u4e8c\u8fdb\u5236\u5b89\u88c5\u5305\u53ef\u4ee5\u901a\u8fc7\u8fd9\u4e2a\u94fe\u63a5\u53d6\u5f97: Releases \u00b7 containerd/nerdctl \u00b7 GitHub \u3002 wget https://github.com/containerd/nerdctl/releases/download/v0.22.2/nerdctl-0.22.2-linux-amd64.tar.gz tar -zxvf nerdctl-0.22.2-linux-amd64.tar.gz sudo cp nerdctl /usr/bin/ \u9a8c\u8bc1 nerdctl \u670d\u52a1\u3002 sudo nerdctl --help \u5217\u51fa\u521d\u59cb\u5b89\u88c5Kubernetes\u65f6\u7684\u5bb9\u5668container\u5217\u8868\u3002 nerdctl -n k8s.io ps","title":"\u5b89\u88c5nerdctl"},{"location":"k8s/cka_cn/installation/aliyun-ubuntu/#kubeadm","text":"\u5728\u6240\u6709\u8282\u70b9\u4e0a\u5b89\u88c5Kubeadm\uff0ckubectl\uff0ckubelet\u3002 \u5b89\u88c5\u548c\u5347\u7ea7Ubuntu\u7cfb\u7edf\u4f9d\u8d56\u5305 apt-transport-https , ca-certificates , curl \u3002 sudo apt-get update && sudo apt-get install -y apt-transport-https ca-certificates curl \u5b89\u88c5gpg\u8bc1\u4e66\u3002 curl https://mirrors.aliyun.com/kubernetes/apt/doc/apt-key.gpg | sudo apt-key add - \u6dfb\u52a0Kubernetes\u5b89\u88c5\u6e90\u3002 cat << EOF > /etc/apt/sources.list.d/kubernetes.list deb https://mirrors.aliyun.com/kubernetes/apt/ kubernetes-xenial main EOF \u5b89\u88c5\u548c\u5347\u7ea7Ubuntu\u7cfb\u7edf\u4f9d\u8d56\u5305\u3002 sudo apt-get update sudo apt-get install ebtables sudo apt-get install libxtables12 sudo apt-get upgrade iptables \u68c0\u67e5\u5f53\u524d\u53ef\u7528\u7684 kubeadm \u7248\u672c\u3002 apt policy kubeadm \u5f53\u524d\u5b89\u88c5 1.24.0-00 \u7248\u672c\u7684 kubeadm \uff0c\u540e\u7eed\u4f1a\u5347\u7ea7\u5230 1.24.2 \u7248\u672c\u3002 sudo apt-get -y install kubelet = 1 .24.0-00 kubeadm = 1 .24.0-00 kubectl = 1 .24.0-00 --allow-downgrades","title":"\u5b89\u88c5kubeadm"},{"location":"k8s/cka_cn/installation/aliyun-ubuntu/#_5","text":"","title":"\u914d\u7f6e\u4e3b\u8282\u70b9"},{"location":"k8s/cka_cn/installation/aliyun-ubuntu/#kubeadm_1","text":"\u5728\u627f\u62c5\u4e3b\u8282\u70b9\u7684\u865a\u62df\u673a\u91cc\u914d\u7f6e\u63a7\u5236\u5e73\u9762\uff08Control Plane\uff09\u3002 \u68c0\u67e5 kubeadm \u5f53\u524d\u9ed8\u8ba4\u914d\u7f6e\u53c2\u6570\u3002 kubeadm config print init-defaults \u7c7b\u4f3c\u7ed3\u679c\u5982\u4e0b\u3002\u4fdd\u5b58\u9ed8\u8ba4\u914d\u7f6e\u7684\u7ed3\u679c\uff0c\u540e\u7eed\u4f1a\u4f5c\u4e3a\u53c2\u8003\u3002 apiVersion : kubeadm.k8s.io/v1beta3 bootstrapTokens : - groups : - system:bootstrappers:kubeadm:default-node-token token : abcdef.0123456789abcdef ttl : 24h0m0s usages : - signing - authentication kind : InitConfiguration localAPIEndpoint : advertiseAddress : 1.2.3.4 bindPort : 6443 nodeRegistration : criSocket : unix:///var/run/containerd/containerd.sock imagePullPolicy : IfNotPresent name : node taints : null --- apiServer : timeoutForControlPlane : 4m0s apiVersion : kubeadm.k8s.io/v1beta3 certificatesDir : /etc/kubernetes/pki clusterName : kubernetes controllerManager : {} dns : {} etcd : local : dataDir : /var/lib/etcd imageRepository : k8s.gcr.io kind : ClusterConfiguration kubernetesVersion : 1.24.0 networking : dnsDomain : cluster.local serviceSubnet : 10.96.0.0/12 scheduler : {} \u6a21\u62df\u5b89\u88c5\u548c\u6b63\u5f0f\u5b89\u88c5\u3002 \u901a\u8fc7\u547d\u4ee4 kubeadm init \u8fdb\u884c\u4e3b\u8282\u70b9\u7684\u521d\u59cb\u5316\uff0c\u4e0b\u9762\u662f\u8fd9\u4e2a\u547d\u4ee4\u4e3b\u8981\u53c2\u6570\u7684\u8bf4\u660e\uff0c\u7279\u522b\u662f\u7f51\u7edc\u53c2\u6570\u7684\u4e09\u4e2a\u9009\u62e9\u3002 --pod-network-cidr : \u6307\u5b9apod\u4f7f\u7528\u7684IP\u5730\u5740\u8303\u56f4\u3002\u5982\u679c\u6307\u5b9a\u4e86\u8be5\u53c2\u6570\uff0c\u5219Control Plane\u4f1a\u81ea\u52a8\u8bb2\u6307\u5b9a\u7684CIDR\u5206\u914d\u7ed9\u6bcf\u4e2a\u8282\u70b9\u3002 IP\u5730\u5740\u6bb5 10.244.0.0/16 \u662fFlannel\u7f51\u7edc\u7ec4\u4ef6\u9ed8\u8ba4\u7684\u5730\u5740\u8303\u56f4\u3002\u5982\u679c\u9700\u8981\u4fee\u6539Flannel\u7684IP\u5730\u5740\u6bb5\uff0c\u9700\u8981\u5728\u8fd9\u91cc\u6307\u5b9a\uff0c\u4e14\u5728\u90e8\u7f72Flannel\u65f6\u4e5f\u8981\u4fdd\u6301\u4e00\u81f4\u7684IP\u6bb5\u3002 --apiserver-bind-port : API\u670d\u52a1\uff08API Server\uff09\u7684\u7aef\u53e3\uff0c\u9ed8\u8ba4\u65f66443\u3002 --service-cidr : \u6307\u5b9a\u670d\u52a1\uff08service\uff09\u7684IP\u5730\u5740\u6bb5\uff0c\u9ed8\u8ba4\u662f 10.96.0.0/12 \u3002 \u63d0\u793a\uff1a \u670d\u52a1VIPs\uff08service VIPs\uff09\uff0c\u4e5f\u79f0\u4f5c\u96c6\u7fa4IP\uff08Cluster IP\uff09\uff0c\u901a\u8fc7\u53c2\u6570 --service-cidr \u6307\u5b9a\u3002 podCIDR\uff0c\u4e5f\u79f0\u4e3aendpoint IP\uff0c\u901a\u8fc7\u53c2\u6570 --pod-network-cidr \u6307\u5b9a\u3002 \u67094\u79cd\u5178\u578b\u7684\u7f51\u7edc\u95ee\u9898\uff1a \u9ad8\u5ea6\u8026\u5408\u7684\u5bb9\u5668\u4e0e\u5bb9\u5668\u4e4b\u95f4\u7684\u901a\u4fe1\uff1a\u8fd9\u53ef\u4ee5\u901a\u8fc7Pod\uff08podCIDR\uff09\u548c\u672c\u5730\u4e3b\u673a\u901a\u4fe1\u6765\u89e3\u51b3\u3002 Pod\u5bf9Pod\u901a\u4fe1\uff08Pod-to-Pod\uff09\uff1a \u4e5f\u88ab\u79f0\u4e3a\u5bb9\u5668\u5bf9\u5bb9\u5668\u901a\u4fe1\uff08container-to-container\uff09\u3002 \u5728Flannel\u7f51\u7edc\u63d2\u4ef6\u4e2d\u7684\u793a\u4f8b\u6d41\u7a0b\u662f\uff1aPod \u2192 veth\u5bf9 \u2192 cni0 \u2192 flannel.1 \u2192 \u5bbf\u4e3b\u673aeth0 \u2192 \u5bbf\u4e3b\u673aeth0 \u2192 flannel.1 \u2192 cni0 \u2192 veth\u5bf9 \u2192 Pod\u3002 Pod\u5bf9Service\u901a\u4fe1\uff08Pod-to-Service\uff09\uff1a \u6d41\u7a0b: Pod \u2192 \u5185\u6838 \u2192 Service iptables \u2192 Service \u2192 Pod iptables \u2192 Pod\u3002 \u5916\u90e8\u5bf9Service\u901a\u4fe1\uff08External-to-Service\uff09\uff1a \u8d1f\u8f7d\u5747\u8861\u5668: SLB \u2192 NodePort \u2192 Service \u2192 Pod\u3002 kube-proxy \u662f\u5bf9iptables\u8d1f\u8d23\uff0c\u4e0d\u662f\u7f51\u7edc\u6d41\u91cf\uff08traffic\uff09\u3002 kube-proxy \u662fKubernetes\u96c6\u7fa4\u4e2d\u7684\u4e00\u4e2a\u7ec4\u4ef6\uff0c\u8d1f\u8d23\u4e3aService\u63d0\u4f9b\u4ee3\u7406\u670d\u52a1\uff0c\u540c\u65f6\u4e5f\u662fKubernetes\u7f51\u7edc\u6a21\u578b\u4e2d\u7684\u91cd\u8981\u7ec4\u6210\u90e8\u5206\u4e4b\u4e00\u3002 kube-proxy \u4f1a\u5728\u6bcf\u4e2a\u8282\u70b9\u4e0a\u542f\u52a8\u4e00\u4e2a\u4ee3\u7406\u8fdb\u7a0b\uff0c\u901a\u8fc7\u76d1\u542cKubernetes API Server\u7684Service\u548cEndpoint\u7684\u53d8\u5316\u6765\u7ef4\u62a4\u4e00\u4e2a\u672c\u5730\u7684Service\u548cEndpoint\u7684\u7f13\u5b58\u3002\u5f53\u6709\u8bf7\u6c42\u5230\u8fbe\u67d0\u4e2aService\u65f6\uff0c kube-proxy \u4f1a\u6839\u636e\u8be5Service\u7684\u7c7b\u578b\uff08ClusterIP\u3001NodePort\u3001LoadBalancer\u3001ExternalName\uff09\u548c\u7aef\u53e3\u53f7\uff0c\u751f\u6210\u76f8\u5e94\u7684iptables\u89c4\u5219\uff0c\u5c06\u8bf7\u6c42\u8f6c\u53d1\u7ed9Service\u6240\u4ee3\u7406\u7684\u540e\u7aefPod\u3002 iptables\u662fLinux\u7cfb\u7edf\u4e2d\u7684\u4e00\u4e2a\u91cd\u8981\u7f51\u7edc\u5de5\u5177\uff0c\u53ef\u4ee5\u8bbe\u7f6eIP\u5305\u7684\u8fc7\u6ee4\u3001\u8f6c\u53d1\u548c\u4fee\u6539\u89c4\u5219\uff0c\u53ef\u4ee5\u5b9e\u73b0\u7f51\u7edc\u5c42\u7684\u9632\u706b\u5899\u3001NAT\u7b49\u529f\u80fd\u3002\u5728Kubernetes\u96c6\u7fa4\u4e2d\uff0c kube-proxy \u901a\u8fc7\u751f\u6210\u548c\u66f4\u65b0iptables\u89c4\u5219\uff0c\u6765\u5b9e\u73b0Service\u548cEndpoint\u4e4b\u95f4\u7684\u8f6c\u53d1\u548c\u4ee3\u7406\u3002\u5177\u4f53\u6765\u8bf4\uff0ckube-proxy\u4f1a\u4e3a\u6bcf\u4e2aService\u521b\u5efa\u4e09\u6761iptables\u89c4\u5219\u94fe\uff08nat\u8868\u4e2d\u7684KUBE-SERVICES\u548cKUBE-NODEPORTS\u94fe\uff0c\u4ee5\u53cafilter\u8868\u4e2d\u7684KUBE-SVC-XXXXX\u94fe\uff09\uff0c\u901a\u8fc7\u8fd9\u4e9b\u89c4\u5219\u94fe\uff0c\u5c06\u8bf7\u6c42\u8f6c\u53d1\u5230\u76f8\u5e94\u7684Pod\u6216\u8005Service\u4e0a\u3002 \u56e0\u6b64\uff0c kube-proxy \u548ciptables\u662f\u7d27\u5bc6\u76f8\u5173\u7684\u4e24\u4e2a\u7ec4\u4ef6\uff0c\u901a\u8fc7iptables\u89c4\u5219\u6765\u5b9e\u73b0Service\u548cPod\u4e4b\u95f4\u7684\u8f6c\u53d1\u548c\u4ee3\u7406\u3002\u8fd9\u79cd\u5b9e\u73b0\u65b9\u5f0f\u5177\u6709\u53ef\u6269\u5c55\u6027\u548c\u9ad8\u53ef\u7528\u6027\uff0c\u540c\u65f6\u4e5f\u63d0\u4f9b\u4e86\u4e00\u79cd\u7075\u6d3b\u7684\u7f51\u7edc\u6a21\u578b\uff0c\u53ef\u4ee5\u65b9\u4fbf\u5730\u5b9e\u73b0\u670d\u52a1\u53d1\u73b0\u3001\u8d1f\u8f7d\u5747\u8861\u7b49\u529f\u80fd\u3002 sudo kubeadm init \\ --dry-run \\ --pod-network-cidr = 10 .244.0.0/16 \\ --service-cidr 11 .244.0.0/16 \\ --image-repository = registry.aliyuncs.com/google_containers \\ --kubernetes-version = v1.24.0 sudo kubeadm init \\ --pod-network-cidr = 10 .244.0.0/16 \\ --service-cidr 11 .244.0.0/16 \\ --image-repository = registry.aliyuncs.com/google_containers \\ --kubernetes-version = v1.24.0 sudo kubeadm init \\ --pod-network-cidr = 10 .244.0.0/16 \\ --service-cidr 11 .244.0.0/16 \\ --kubernetes-version = v1.24.0","title":"kubeadm\u521d\u59cb\u5316"},{"location":"k8s/cka_cn/installation/aliyun-ubuntu/#kubeconfig","text":"\u7ed9\u5f53\u524d\u5b89\u88c5\u7528\u6237\u914d\u7f6e kubeconfig \u6587\u4ef6\uff08\u5f53\u524d\u4f8b\u5b50\u662f\u7528\u6237 vagrant \uff09\u3002 mkdir -p $HOME /.kube sudo cp -i /etc/kubernetes/admin.conf $HOME /.kube/config sudo chown $( id -u ) : $( id -g ) $HOME /.kube/config Kubernetes \u63d0\u4f9b\u4e86\u4e00\u4e2a\u547d\u4ee4\u884c\u5de5\u5177 kubectl \uff0c\u7528\u4e8e\u4f7f\u7528 Kubernetes API \u4e0e Kubernetes \u96c6\u7fa4\u7684\u63a7\u5236\u5e73\u9762\u8fdb\u884c\u901a\u4fe1\u3002 kubectl \u63a7\u5236 Kubernetes cluster manager \uff08\u96c6\u7fa4\u7ba1\u7406\u5668\uff09\u3002 \u5bf9\u4e8e\u914d\u7f6e\uff0ckubectl \u5728 $HOME/.kube \u76ee\u5f55\u4e2d\u67e5\u627e\u4e00\u4e2a\u540d\u4e3a config \u7684\u6587\u4ef6\uff0c\u8be5\u6587\u4ef6\u662f\u7531 kubeadm init \u751f\u6210\u7684\u6587\u4ef6 /etc/kubernetes/admin.conf \u7684\u526f\u672c\u3002 \u6211\u4eec\u53ef\u4ee5\u901a\u8fc7\u8bbe\u7f6e KUBECONFIG \u73af\u5883\u53d8\u91cf\u6216\u8bbe\u7f6e --kubeconfig flag \u6807\u5fd7\u6765\u6307\u5b9a\u5176\u4ed6 kubeconfig \u6587\u4ef6\u3002\u5982\u679c KUBECONFIG \u73af\u5883\u53d8\u91cf\u4e0d\u5b58\u5728\uff0ckubectl \u5c06\u4f7f\u7528\u9ed8\u8ba4\u7684 kubeconfig \u6587\u4ef6 $HOME/.kube/config \u3002 kubeconfig \u6587\u4ef6\u4e2d\u7684 context\uff08\u4e0a\u4e0b\u6587\uff09 \u5143\u7d20\u7528\u4e8e\u5c06\u8bbf\u95ee\u53c2\u6570\u5206\u7ec4\u5230\u4e00\u4e2a\u65b9\u4fbf\u7684\u540d\u79f0\u4e0b\u3002\u6bcf\u4e2a\u4e0a\u4e0b\u6587\u90fd\u6709\u4e09\u4e2a\u53c2\u6570\uff1a\u96c6\u7fa4\u3001\u547d\u540d\u7a7a\u95f4\u548c\u7528\u6237\u3002\u9ed8\u8ba4\u60c5\u51b5\u4e0b\uff0ckubectl \u547d\u4ee4\u884c\u5de5\u5177\u4f7f\u7528\u5f53\u524d\u4e0a\u4e0b\u6587\u4e2d\u7684\u53c2\u6570\u4e0e\u96c6\u7fa4\u901a\u4fe1\u3002 \u6587\u4ef6 .kube/config \u7684\u4f8b\u5b50\uff1a apiVersion : v1 clusters : - cluster : certificate-authority-data : server : https://:6443 name : contexts : - context : cluster : namespace : user : name : @ current-context : kind : Config preferences : {} users : - name : user : client-certificate-data : client-key-data : \u8bfb\u53d6\u5f53\u524d\u4e0a\u4e0b\u6587\uff1a kubectl config get-contexts \u8fd0\u884c\u7ed3\u679c\uff1a CURRENT NAME CLUSTER AUTHINFO NAMESPACE * kubernetes-admin@kubernetes kubernetes kubernetes-admin","title":"kubeconfig\u6587\u4ef6"},{"location":"k8s/cka_cn/installation/aliyun-ubuntu/#_6","text":"\u4f7f\u7528 kubeadm token \u6765\u751f\u6210\u52a0\u5165\u96c6\u7fa4\u7684\u4ee4\u724c\uff08token\uff09\u548c\u54c8\u897f\u503c\uff08hash value\uff09\u3002 kubeadm token create --print-join-command \u5728\u6240\u6709\u5de5\u4f5c\u8282\u70b9\u4e0a\u6267\u884c\u4e0b\u9762\u7684\u547d\u4ee4\uff0c\u5c06\u5de5\u4f5c\u8282\u70b9\u52a0\u5165Kubernetes\u96c6\u7fa4\u3002 # kubeadm join :6443 --token --discovery-token-ca-cert-hash \u6267\u884c\u4e0b\u9762\u547d\u4ee4\u68c0\u67e5\u6240\u6709\u8282\u70b9\u7684\u72b6\u6001\u3002 \u5f53\u524d\u6240\u6709\u8282\u70b9\u7684\u72b6\u6001\u90fd\u662f NotReady \u3002\u76ee\u524d\u4e0d\u9700\u8981\u505a\u4ec0\u4e48\uff0c\u540e\u9762\u6211\u4eec\u4f1a\u5b89\u88c5\u76f8\u5173\u7684\u7f51\u7edc\u670d\u52a1\uff08Calico \u6216 Flannel\uff09\uff0c\u5404\u8282\u70b9\u7684\u72b6\u6001\u5c31\u4f1a\u53d8\u6210Ready\u72b6\u6001\u3002","title":"\u914d\u7f6e\u5de5\u4f5c\u8282\u70b9"},{"location":"k8s/cka_cn/installation/aliyun-ubuntu/#calicoflannel","text":"\u5728\u63a7\u5236\u5e73\u9762Control Plane\u4e0a\u5b89\u88c5Calico\u6216\u8005Flannel\u3002\u5982\u679c\u9700\u8981\u914d\u7f6e\u7f51\u7edc\u7b56\u7565\uff0c\u5219\u9009\u62e9Calico\u3002","title":"\u5b89\u88c5Calico\u6216Flannel"},{"location":"k8s/cka_cn/installation/aliyun-ubuntu/#flannel","text":"Flannel \u662f\u4e3a Kubernetes \u8bbe\u8ba1\u7684\u4e00\u79cd\u7b80\u5355\u6613\u7528\u7684\u914d\u7f6e\u4e09\u5c42\u7f51\u7edc\u7684\u65b9\u6cd5\u3002 \u90e8\u7f72Flannel\uff1a \u5728 kube-flannel.yml \u4e2d\uff0c\u6211\u4eec\u53ef\u4ee5\u83b7\u53d6 Flannel \u7684\u9ed8\u8ba4\u7f51\u7edc\u8bbe\u7f6e\uff0c\u5b83\u4e0e\u6211\u4eec\u5728\u4f7f\u7528 kubeadm \u521d\u59cb\u5316\u96c6\u7fa4\u65f6\u6307\u5b9a\u7684\u53c2\u6570 --pod-network-cidr=10.244.0.0/16 \u76f8\u540c\u3002 net - co nf .jso n : | { \"Network\" : \"10.244.0.0/16\" , \"Backend\" : { \"Type\" : \"vxlan\" } } \u521b\u5efaFlannel\u670d\u52a1\u3002 apply -f https://raw.githubusercontent.com/coreos/flannel/master/Documentation/kube-flannel.yml \u8f93\u51fa\u7ed3\u679c\uff1a Warning: policy/v1beta1 PodSecurityPolicy is deprecated in v1.21+, unavailable in v1.25+ podsecuritypolicy.policy/psp.flannel.unprivileged created clusterrole.rbac.authorization.k8s.io/flannel created clusterrolebinding.rbac.authorization.k8s.io/flannel created serviceaccount/flannel created configmap/kube-flannel-cfg created daemonset.apps/kube-flannel-ds created","title":"\u5b89\u88c5Flannel"},{"location":"k8s/cka_cn/installation/aliyun-ubuntu/#calico","text":"\u5b89\u88c5\u6307\u5bfc\u624b\u518c\uff1a End-to-end Calico installation \u3002 \u4e0b\u8f7d\u5e76\u5b89\u88c5Calico\u670d\u52a1\u3002 curl https://docs.projectcalico.org/manifests/calico.yaml -O kubectl apply -f calico.yaml \u8f93\u51fa\u7ed3\u679c\uff1a configmap/calico-config created customresourcedefinition.apiextensions.k8s.io/bgpconfigurations.crd.projectcalico.org created customresourcedefinition.apiextensions.k8s.io/bgppeers.crd.projectcalico.org created customresourcedefinition.apiextensions.k8s.io/blockaffinities.crd.projectcalico.org created customresourcedefinition.apiextensions.k8s.io/caliconodestatuses.crd.projectcalico.org created customresourcedefinition.apiextensions.k8s.io/clusterinformations.crd.projectcalico.org created customresourcedefinition.apiextensions.k8s.io/felixconfigurations.crd.projectcalico.org created customresourcedefinition.apiextensions.k8s.io/globalnetworkpolicies.crd.projectcalico.org created customresourcedefinition.apiextensions.k8s.io/globalnetworksets.crd.projectcalico.org created customresourcedefinition.apiextensions.k8s.io/hostendpoints.crd.projectcalico.org created customresourcedefinition.apiextensions.k8s.io/ipamblocks.crd.projectcalico.org created customresourcedefinition.apiextensions.k8s.io/ipamconfigs.crd.projectcalico.org created customresourcedefinition.apiextensions.k8s.io/ipamhandles.crd.projectcalico.org created customresourcedefinition.apiextensions.k8s.io/ippools.crd.projectcalico.org created customresourcedefinition.apiextensions.k8s.io/ipreservations.crd.projectcalico.org created customresourcedefinition.apiextensions.k8s.io/kubecontrollersconfigurations.crd.projectcalico.org created customresourcedefinition.apiextensions.k8s.io/networkpolicies.crd.projectcalico.org created customresourcedefinition.apiextensions.k8s.io/networksets.crd.projectcalico.org created clusterrole.rbac.authorization.k8s.io/calico-kube-controllers created clusterrolebinding.rbac.authorization.k8s.io/calico-kube-controllers created clusterrole.rbac.authorization.k8s.io/calico-node created clusterrolebinding.rbac.authorization.k8s.io/calico-node created daemonset.apps/calico-node created serviceaccount/calico-node created deployment.apps/calico-kube-controllers created serviceaccount/calico-kube-controllers created poddisruptionbudget.policy/calico-kube-controllers created \u9a8c\u8bc1Calico\u670d\u52a1\u72b6\u6001\uff1a kubectl get pod -n kube-system | grep calico \u8f93\u51fa\u7ed3\u679c\uff1a calico-kube-controllers-555bc4b957-l8bn2 0 /1 Pending 0 28s calico-node-255pc 0 /1 Init:1/3 0 29s calico-node-7tmnb 0 /1 Init:1/3 0 29s calico-node-w8nvl 0 /1 Init:1/3 0 29s \u68c0\u67e5\u96c6\u7fa4\u7684\u7f51\u7edc\u72b6\u6001\uff1a sudo nerdctl network ls \u8f93\u51fa\u7ed3\u679c\uff1a NETWORK ID NAME FILE k8s-pod-network /etc/cni/net.d/10-calico.conflist 0 bridge /etc/cni/net.d/nerdctl-bridge.conflist host none","title":"\u5b89\u88c5Calico"},{"location":"k8s/cka_cn/installation/aliyun-ubuntu/#_7","text":"\u5728\u4e3b\u8282\u70b9\u4e0a\u6267\u884c\u547d\u4ee4 kubectl cluster-info \u53ef\u4ee5\u5f97\u5230\u4e0b\u9762\u7684\u4fe1\u606f\uff1a \u63a7\u5236\u5e73\u9762\uff08control plane\uff09\u8fd0\u884c\u5728 https://:6443 CoreDNS\u670d\u52a1\u8fd0\u884c\u5728 https://:6443/api/v1/namespaces/kube-system/services/kube-dns:dns/proxy kubectl cluster-info \u67e5\u770b\u8282\u70b9\u8fd0\u884c\u72b6\u6001\u3002\u6b64\u65f6\uff0c\u6240\u6709\u8282\u70b9\u90fd\u662f Ready \u7684\u6b63\u5e38\u72b6\u6001\u4e86\u3002 OS Image: Ubuntu 20.04.4 LTS Kernel Version: 5.4.0-122-generic Container Runtime: containerd://1.5.9 kubectl get nodes -owide \u8f93\u51fa\u7ed3\u679c\uff1a NAME STATUS ROLES AGE VERSION cka001 Ready control-plane 13m v1.24.0 cka002 Ready 8m35s v1.24.0 cka003 Ready 8m26s v1.24.0 \u67e5\u770bPods\u7684\u72b6\u6001\u3002 kubectl get pod -A \u8f93\u51fa\u7ed3\u679c\uff1a NAMESPACE NAME READY STATUS RESTARTS AGE kube-system calico-kube-controllers-555bc4b957-l8bn2 1/1 Running 0 7m18s kube-system calico-node-255pc 1/1 Running 0 7m19s kube-system calico-node-7tmnb 1/1 Running 0 7m19s kube-system calico-node-w8nvl 1/1 Running 0 7m19s kube-system coredns-74586cf9b6-4jwmk 1/1 Running 0 15m kube-system coredns-74586cf9b6-c5mll 1/1 Running 0 15m kube-system etcd-cka001 1/1 Running 0 15m kube-system kube-apiserver-cka001 1/1 Running 0 15m kube-system kube-controller-manager-cka001 1/1 Running 0 15m kube-system kube-proxy-dmj2t 1/1 Running 0 15m kube-system kube-proxy-n77zw 1/1 Running 0 11m kube-system kube-proxy-qs6rf 1/1 Running 0 11m kube-system kube-scheduler-cka001 1/1 Running 0 15m","title":"\u68c0\u67e5\u96c6\u7fa4\u72b6\u6001"},{"location":"k8s/cka_cn/installation/aliyun-ubuntu/#_8","text":"","title":"\u66f4\u65b0\u5b89\u88c5"},{"location":"k8s/cka_cn/installation/aliyun-ubuntu/#bash","text":"\u5728\u6bcf\u4e2a\u8282\u70b9\u4e0a\u914d\u7f6eBash\u81ea\u52a8\u8865\u5168\u529f\u80fd\u3002 \u53c2\u8003 \u6307\u5bfc \u8bbe\u7f6e kubectl \u81ea\u52a8\u8865\u5168\u529f\u80fdauto-completion \u3002 apt install -y bash-completion source /usr/share/bash-completion/bash_completion source < ( kubectl completion bash ) echo \"source <(kubectl completion bash)\" >> ~/.bashrc source ~/.bashrc","title":"Bash\u81ea\u52a8\u8865\u5168"},{"location":"k8s/cka_cn/installation/aliyun-ubuntu/#_9","text":"\u5982\u679c\u6211\u4eec\u4e3a kubectl \u8bbe\u7f6e\u4e00\u4e2a\u522b\u540d\uff0c\u6211\u4eec\u53ef\u4ee5\u901a\u8fc7\u4e00\u4e9b\u65b9\u6cd5\u6765\u6269\u5c55 shell \u81ea\u52a8\u8865\u5168\u529f\u80fd\uff0c\u4f7f\u5176\u80fd\u591f\u4e0e\u8be5\u522b\u540d\u4e00\u8d77\u4f7f\u7528\u3002 \u4e00\u79cd\u65b9\u6cd5\u662f\u5728 Bash shell \u914d\u7f6e\u6587\u4ef6\uff08\u5982 .bashrc \u6216 .bash_profile\uff09\u4e2d\u8bbe\u7f6e\u522b\u540d\uff0c\u5e76\u4e3a\u8be5\u522b\u540d\u6307\u5b9a kubectl \u7684\u5b8c\u6574\u8def\u5f84\u3002\u4f8b\u5982\uff0c\u53ef\u4ee5\u5728 .bashrc \u6587\u4ef6\u4e2d\u6dfb\u52a0\u4ee5\u4e0b\u5185\u5bb9\uff1a alias k = 'path/to/kubectl' \u7136\u540e\uff0c\u53ef\u4ee5\u4f7f\u7528\u4ee5\u4e0b\u547d\u4ee4\u91cd\u65b0\u52a0\u8f7d .bashrc \u6587\u4ef6\uff1a source ~/.bashrc \u63a5\u4e0b\u6765\uff0c\u53ef\u4ee5\u4f7f\u7528 k \u547d\u4ee4\u6765\u4ee3\u66ff kubectl \u547d\u4ee4\uff0c\u5e76\u5728\u5176\u540e\u9762\u6dfb\u52a0\u76f8\u5e94\u7684\u53c2\u6570\u548c\u9009\u9879\u3002\u5f53\u4f7f\u7528\u81ea\u52a8\u8865\u5168\u529f\u80fd\u65f6\uff0cBash shell \u4f1a\u81ea\u52a8\u5c06 k \u522b\u540d\u8f6c\u6362\u4e3a kubectl \u7684\u5b8c\u6574\u8def\u5f84\uff0c\u5e76\u5bf9\u5176\u8fdb\u884c\u81ea\u52a8\u8865\u5168\u3002 \u53e6\u4e00\u79cd\u65b9\u6cd5\u662f\u4f7f\u7528 Bash shell \u5185\u7f6e\u7684 complete \u51fd\u6570\u6765\u4e3a\u522b\u540d\u8bbe\u7f6e\u81ea\u52a8\u8865\u5168\u529f\u80fd\u3002\u4f8b\u5982\uff0c\u53ef\u4ee5\u5728 .bashrc \u6587\u4ef6\u4e2d\u6dfb\u52a0\u4ee5\u4e0b\u5185\u5bb9\uff1a echo 'alias k=kubectl' >>~/.bashrc echo 'complete -o default -F __start_kubectl k' >>~/.bashrc \u8fd9\u5c06\u4e3a\u522b\u540d k \u8bbe\u7f6e\u81ea\u52a8\u8865\u5168\u529f\u80fd\uff0c\u5e76\u5c06\u5176\u4e0e kubectl \u7684\u81ea\u52a8\u8865\u5168\u51fd\u6570 __start_kubectl \u5173\u8054\u8d77\u6765\u3002\u8fd9\u6837\uff0c\u5f53\u7528\u6237\u5728 k \u547d\u4ee4\u540e\u8f93\u5165Tab\u952e\u65f6\uff0cBash shell \u4f1a\u81ea\u52a8\u8c03\u7528 __start_kubectl \u51fd\u6570\uff0c\u5e76\u4e3a\u7528\u6237\u63d0\u4f9b\u76f8\u5e94\u7684\u81ea\u52a8\u8865\u5168\u5efa\u8bae\u3002","title":"\u522b\u540d"},{"location":"k8s/cka_cn/installation/aliyun-ubuntu/#context","text":"\u67e5\u770b\u5f53\u524d\u7684 context \u5217\u8868\uff1a kubectl config get-contexts \u8fd9\u4e2a\u547d\u4ee4\u4f1a\u5217\u51fa\u6240\u6709\u53ef\u7528\u7684 context \u5217\u8868\uff0c\u5e76\u6807\u8bb0\u51fa\u5f53\u524d\u6b63\u5728\u4f7f\u7528\u7684 context\u3002 \u7c7b\u4f3c\u4e0b\u9762\u7ed3\u679c\uff1a kubernetes-admin@kubernetes \u662fContext\u540d\u3002 kubernetes \u662f\u96c6\u7fa4\u540d\u3002 kubernetes-admin \u662f\u7528\u6237\u540d\u3002 \u5f53\u524d\u4f8b\u5b50\u4e2d\u6ca1\u6709\u6307\u5b9a\u540d\u79f0\u7a7a\u95f4\u3002 CURRENT NAME CLUSTER AUTHINFO NAMESPACE * kubernetes-admin@kubernetes kubernetes kubernetes-admin \u66f4\u65b0context\u3002\u4f8b\u5982\uff0c\u66f4\u65b0context\u7684\u9ed8\u8ba4\u540d\u79f0\u7a7a\u95f4\u7b49\u3002 # Usage: kubectl config set-context --cluster = --namespace = --user = # Set default namespace kubectl config set-context kubernetes-admin@kubernetes --cluster = kubernetes --namespace = default --user = kubernetes-admin \u5728\u4e0d\u540c\u7684context\u4e4b\u95f4\u5207\u6362\u3002 # Usage: kubectl config use-context # Switch to new context kubectl config use-context kubernetes-admin@kubernetes \u53c2\u8003\u8d44\u6599\uff1a kubectl [commandline","title":"\u66f4\u65b0\u9ed8\u8ba4Context"},{"location":"k8s/cka_cn/installation/aliyun-ubuntu/#_10","text":"\u6ce8\u610f\uff1a\u4e0b\u9762\u7684\u64cd\u4f5c\u4f1a\u91cd\u7f6e\u5f53\u524d\u96c6\u7fa4\uff08\u5220\u9664\u96c6\u7fa4\uff09\u3002 \u5220\u9664\u96c6\u7fa4\u4e2d\u6240\u6709\u8282\u70b9\u3002 kubeadm reset \u6e05\u9664 iptables \u4e2d\u5df2\u5b9a\u4e49\u7684\u89c4\u5219\u3002 iptables -F && iptables -t nat -F && iptables -t mangle -F && iptables -X \u6e05\u9664 IPVS \u4e2d\u5b9a\u4e49\u7684\u89c4\u5219\uff08\u5982\u679c\u4f7f\u7528 IPVS \uff09\u3002 ipvsadm --clear","title":"\u91cd\u7f6e\u96c6\u7fa4"},{"location":"k8s/cka_cn/installation/aliyun-ubuntu/#_11","text":"","title":"\u6392\u9519"},{"location":"k8s/cka_cn/installation/aliyun-ubuntu/#1","text":"\u62a5\u9519\u4fe1\u606f\uff1a The connection to the server :6443 was refused - did you specify the right host or port? \u89e3\u51b3\u5c1d\u8bd5\uff1a Reference \u68c0\u67e5\u6587\u4ef6kubeconfig\u7684\u5185\u5bb9\u548c\u6587\u4ef6\u8def\u5f84\u662f\u5426\u6b63\u786e\u3002 \u68c0\u67e5\u73af\u5883\u53d8\u91cf\u8bbe\u7f6e\u3002 env | grep -i kub \u68c0\u67e5\u5bb9\u5668\u8fd0\u884c\u72b6\u6001\u3002 sudo systemctl status containerd.service \u68c0\u67e5kubelet\u670d\u52a1\u3002 sudo systemctl status kubelet.service \u68c0\u67e5 6443 \u7aef\u53e3\u76d1\u542c\u72b6\u6001\u3002 netstat -pnlt | grep 6443 \u68c0\u67e5\u9632\u706b\u5899\u72b6\u6001\u3002 sudo systemctl status firewalld.service \u68c0\u67e5kubelet\u65e5\u5fd7\u3002 journalctl -xeu kubelet","title":"\u9519\u8bef1"},{"location":"k8s/cka_cn/installation/aliyun-ubuntu/#2","text":"\u62a5\u9519\u4fe1\u606f\uff1a \"Container runtime network not ready\" networkReady=\"NetworkReady=false reason:NetworkPluginNotReady message:Network plugin returns error: cni plugin not initialized\" \u5c1d\u8bd5\u65b9\u6cd5\uff1a \u91cd\u542fContainerd\u670d\u52a1\u3002 sudo systemctl restart containerd sudo systemctl status containerd","title":"\u9519\u8bef2"},{"location":"k8s/cka_cn/installation/multiple-local/","text":"CKA\u81ea\u5b66\u7b14\u8bb02:\u591a\u8282\u70b9\u865a\u62df\u673a\u5b89\u88c5Kubernetes \u00b6 \u6458\u8981 \u00b6 \u5728\u672c\u5730Windows\u73af\u5883\u4e2d\uff0c\u901a\u8fc7VMWare\u5b89\u88c5\u4e09\u53f0Ubuntu\u865a\u62df\u673a\u3002\u5728Ubuntu\u865a\u62df\u673a\u4e2d\u5b89\u88c5\u57fa\u4e8eContainerd\u7684Kubernetes\u7cfb\u7edf\uff0c\u5e76\u5206\u522b\u914d\u7f6e\u4e00\u4e2a\u4e3b\u8282\u70b9Master\u548c\u4e24\u4e2a\u5de5\u4f5c\u8282\u70b9Worker\u3002 \u672c\u5730\u865a\u62df\u673a\u8bbe\u7f6e \u00b6 VMWare \u8bbe\u7f6e VMnet1: host-only\u6a21\u5f0f, \u7f51\u7edcsubnet: 192.168.150.0/24 VMnet8: NAT\u6a21\u5f0f, \u7f51\u7edcsubnet: 11.0.1.0/24 \u901a\u8fc7VMWare\u521b\u5efa\u5ba2\u6237\u865a\u62df\u673a\u3002 \u5185\u5b58\uff1a4 GB CPU\uff1a1 CPUs with 2 Cores \u64cd\u4f5c\u7cfb\u7edf\uff1aUbuntu Server 22.04 \u7f51\u7edc\uff1aNAT \u63d0\u793a\uff1a \u5f53\u524d\u7ec3\u4e60\u4e2d\uff0cKubernetes\u662f\u57fa\u4e8eContainerd\uff0c\u4e0d\u662fDocker\u3002 Ubuntu\u9884\u914d\u7f6e \u00b6 \u6ce8\u610f\uff1a\u4e0b\u9762\u7684\u4efb\u52a1\uff0c\u9700\u8981\u5728\u6bcf\u53f0\u865a\u62df\u673a\u4e2d\u6267\u884c\u4e00\u6b21\u3002\u4ee5\u4e0b\u7b80\u79f0\u865a\u62df\u673a\u4e3a\u8282\u70b9\u3002 \u5728\u6240\u6709\u8282\u70b9\u4e2d\u521b\u5efa\u7528\u6237 vagrant \u3002 sudo adduser vagrant sudo usermod -g sudo vagrant sudo usermod -a -G root vagrant sudo passwd vagrant \u5728\u6240\u6709\u8282\u70b9\u4e2d\u8bbe\u7f6e\u7528\u6237 root \u7684\u5bc6\u7801\u3002 sudo passwd root \u4fee\u6539ssh\u670d\u52a1\u7684\u914d\u7f6e\u6587\u4ef6\u3002\u5f00\u653e root \u7528\u6237\u901a\u8fc7ssh\u767b\u5f55\uff08\u9ed8\u8ba4\u662f\u7981\u7528\u7684\uff09\u3002 sudo vi /etc/ssh/sshd_config \u628a\u53c2\u6570 PermitRootLogin \u7684\u503c\u4ece prohibit-password \u6539\u4e3a yes \u3002 PermitRootLogin yes # PermitRootLogin prohibit-password \u91cd\u65b0\u542f\u52a8sshd\u670d\u52a1\u3002 sudo systemctl restart sshd \u66f4\u6539\u4e3b\u673a\u540d\uff0c\u8fd9\u91cc\u662f ubu1 . sudo hostnamectl set-hostname ubu1 sudo hostnamectl set-hostname ubu1 --pretty \u9a8c\u8bc1\u4e3b\u673a\u540d\u662f\u5426\u88ab\u6b63\u786e\u4fee\u6539\u4e86\uff0c\u6bd4\u5982\u6539\u4e3a ubu1 \u3002 cat /etc/machine-info \u9a8c\u8bc1\u4e3b\u673a\u540d\u662f\u5426\u88ab\u6b63\u786e\u4fee\u6539\u4e86\uff0c\u6bd4\u5982\u6539\u4e3a ubu1 \u3002 cat /etc/hostname \u9a8c\u8bc1\u4e3b\u673aIP\u5730\u5740 127.0.1.1 \u5df2\u7ecf\u914d\u7f6e\u7ed9\u5f53\u524d\u8282\u70b9\uff0c\u6bd4\u5982 ubu1 \u3002\u540c\u65f6\uff0c\u5728\u6240\u6709\u8282\u70b9\u7684 /etc/hosts \u6587\u4ef6\u4e2d\u6dfb\u52a0\u5176\u4ed6\u8282\u70b9\u7684IP\u548c\u4e3b\u673a\u5bf9\u5e94\u4fe1\u606f\u3002 sudo vi /etc/hosts \u4ee5\u5f53\u524d\u7ec3\u4e60\u4e3a\u4f8b\uff0c\u4fee\u6539\u540e\u7684 /etc/hosts \u6587\u4ef6\u7c7b\u4f3c\u5982\u4e0b\u5185\u5bb9\u3002 127.0.1.1 ubu1 11.0.1.129 ubu1 11.0.1.130 ubu2 11.0.1.131 ubu3 11.0.1.132 ubu4 \u521b\u5efa\u6587\u4ef6 /etc/netplan/00-installer-config.yaml \u3002 sudo vi /etc/netplan/00-installer-config.yaml \u66f4\u65b0\u6b64\u6587\u4ef6\uff0c\u8bbe\u5b9a\u5f53\u524d\u8282\u70b9\u4f7f\u7528\u56fa\u5b9aIP\u5730\u5740\uff0c\u6bd4\u5982\uff0c 11.0.1.129 \u3002 network : ethernets : ens33 : dhcp4 : false addresses : - 11.0.1.129/24 nameservers : addresses : - 11.0.1.2 routes : - to : default via : 11.0.1.2 version : 2 \u6267\u884c\u4e0b\u9762\u547d\u4ee4\u65f6\uff0c\u4f7f\u4e0a\u8ff0\u6539\u52a8\u751f\u6548\u3002\u6ce8\u610f\uff0c\u5f53\u524dssh\u8fde\u63a5\u4f1a\u56e0\u6b64\u800c\u65ad\u5f00\u3002 sudo netplan apply \u5728\u6240\u6709\u8282\u70b9\u7981\u7528\u4ea4\u6362\u5206\u533aswap\u548c\u9632\u706b\u5899firewall\u3002 sudo swapoff -a sudo ufw disable sudo ufw status verbose \u5728\u6240\u6709\u8282\u70b9\u7684\u6587\u4ef6 /etc/fstab \u4e2d\u6ce8\u91ca\u6389\u6d89\u53caswap\u7684\u90a3\u4e00\u884c\uff0c\u4fee\u6539\u540e\u9700\u8981\u91cd\u542f\u5f53\u524d\u8282\u70b9\u3002 sudo vi /etc/fstab \u4fee\u6539\u540e\u7684\u7ed3\u679c\u7c7b\u4f3c\u5982\u4e0b\u3002 /dev/disk/by-uuid/df370d2a-83e5-4895-8c7f-633f2545e3fe / ext4 defaults 0 1 # /swap.img none swap sw 0 0 \u5728\u6240\u6709\u8282\u70b9\u8bbe\u7f6e\u7edf\u4e00\u7684\u65f6\u533a\u3002 sudo ln -sf /usr/share/zoneinfo/Asia/Shanghai /etc/localtime sudo cp /etc/profile /etc/profile.bak echo 'LANG=\"en_US.UTF-8\"' | sudo tee -a /etc/profile source /etc/profile \u6267\u884c\u547d\u4ee4 ll /etc/localtime \u6765\u9a8c\u8bc1\u65f6\u533a\u662f\u5426\u4fee\u6539\u6b63\u786e\u3002 lrwxrwxrwx 1 root root 33 Jul 15 22:00 /etc/localtime -> /usr/share/zoneinfo/Asia/Shanghai \u5728\u6240\u6709\u8282\u70b9\u4fee\u6539\u5185\u6838\u8bbe\u7f6e\u3002 cat < /etc/apt/sources.list.d/kubernetes.list deb https://mirrors.aliyun.com/kubernetes/apt/ kubernetes-xenial main EOF \u68c0\u67e5\u5f53\u524d kubeadm \u7684\u7248\u672c\u3002 apt policy kubeadm \u5b89\u88c5 1.24.1-00 \u7248\u672c\u7684 kubeadm . sudo apt-get -y install kubelet = 1 .24.1-00 kubeadm = 1 .24.1-00 kubectl = 1 .24.1-00 --allow-downgrades \u914d\u7f6e\u4e3b\u8282\u70b9 \u00b6 kubeadm\u521d\u59cb\u5316 \u00b6 \u5728\u627f\u62c5\u4e3b\u8282\u70b9\u7684\u865a\u62df\u673a\u91cc\u914d\u7f6e\u63a7\u5236\u5e73\u9762\uff08Control Plane\uff09\u3002 \u68c0\u67e5 kubeadm \u5f53\u524d\u9ed8\u8ba4\u914d\u7f6e\u53c2\u6570\u3002 kubeadm config print init-defaults \u7c7b\u4f3c\u7ed3\u679c\u5982\u4e0b\u3002\u4fdd\u5b58\u9ed8\u8ba4\u914d\u7f6e\u7684\u7ed3\u679c\uff0c\u540e\u7eed\u4f1a\u4f5c\u4e3a\u53c2\u8003\u3002 apiVersion : kubeadm.k8s.io/v1beta3 bootstrapTokens : - groups : - system:bootstrappers:kubeadm:default-node-token token : abcdef.0123456789abcdef ttl : 24h0m0s usages : - signing - authentication kind : InitConfiguration localAPIEndpoint : advertiseAddress : 1.2.3.4 bindPort : 6443 nodeRegistration : criSocket : unix:///var/run/containerd/containerd.sock imagePullPolicy : IfNotPresent name : node taints : null --- apiServer : timeoutForControlPlane : 4m0s apiVersion : kubeadm.k8s.io/v1beta3 certificatesDir : /etc/kubernetes/pki clusterName : kubernetes controllerManager : {} dns : {} etcd : local : dataDir : /var/lib/etcd imageRepository : k8s.gcr.io kind : ClusterConfiguration kubernetesVersion : 1.24.0 networking : dnsDomain : cluster.local serviceSubnet : 10.96.0.0/12 scheduler : {} \u6a21\u62df\u5b89\u88c5\u548c\u6b63\u5f0f\u5b89\u88c5\u3002 \u901a\u8fc7\u547d\u4ee4 kubeadm init \u8fdb\u884c\u4e3b\u8282\u70b9\u7684\u521d\u59cb\u5316\uff0c\u4e0b\u9762\u662f\u8fd9\u4e2a\u547d\u4ee4\u4e3b\u8981\u53c2\u6570\u7684\u8bf4\u660e\uff0c\u7279\u522b\u662f\u7f51\u7edc\u53c2\u6570\u7684\u4e09\u4e2a\u9009\u62e9\u3002 --pod-network-cidr : \u6307\u5b9apod\u4f7f\u7528\u7684IP\u5730\u5740\u8303\u56f4\u3002\u5982\u679c\u6307\u5b9a\u4e86\u8be5\u53c2\u6570\uff0c\u5219Control Plane\u4f1a\u81ea\u52a8\u8bb2\u6307\u5b9a\u7684CIDR\u5206\u914d\u7ed9\u6bcf\u4e2a\u8282\u70b9\u3002 IP\u5730\u5740\u6bb5 10.244.0.0/16 \u662fFlannel\u7f51\u7edc\u7ec4\u4ef6\u9ed8\u8ba4\u7684\u5730\u5740\u8303\u56f4\u3002\u5982\u679c\u9700\u8981\u4fee\u6539Flannel\u7684IP\u5730\u5740\u6bb5\uff0c\u9700\u8981\u5728\u8fd9\u91cc\u6307\u5b9a\uff0c\u4e14\u5728\u90e8\u7f72Flannel\u65f6\u4e5f\u8981\u4fdd\u6301\u4e00\u81f4\u7684IP\u6bb5\u3002 --apiserver-bind-port : API\u670d\u52a1\uff08API Server\uff09\u7684\u7aef\u53e3\uff0c\u9ed8\u8ba4\u65f66443\u3002 --service-cidr : \u6307\u5b9a\u670d\u52a1\uff08service\uff09\u7684IP\u5730\u5740\u6bb5\uff0c\u9ed8\u8ba4\u662f 10.96.0.0/12 \u3002 \u63d0\u793a\uff1a \u670d\u52a1VIPs\uff08service VIPs\uff09\uff0c\u4e5f\u79f0\u4f5c\u96c6\u7fa4IP\uff08Cluster IP\uff09\uff0c\u901a\u8fc7\u53c2\u6570 --service-cidr \u6307\u5b9a\u3002 podCIDR\uff0c\u4e5f\u79f0\u4e3aendpoint IP\uff0c\u901a\u8fc7\u53c2\u6570 --pod-network-cidr \u6307\u5b9a\u3002 \u67094\u79cd\u5178\u578b\u7684\u7f51\u7edc\u95ee\u9898\uff1a \u9ad8\u5ea6\u8026\u5408\u7684\u5bb9\u5668\u4e0e\u5bb9\u5668\u4e4b\u95f4\u7684\u901a\u4fe1\uff1a\u8fd9\u53ef\u4ee5\u901a\u8fc7Pod\uff08podCIDR\uff09\u548c\u672c\u5730\u4e3b\u673a\u901a\u4fe1\u6765\u89e3\u51b3\u3002 Pod\u5bf9Pod\u901a\u4fe1\uff08Pod-to-Pod\uff09\uff1a \u4e5f\u88ab\u79f0\u4e3a\u5bb9\u5668\u5bf9\u5bb9\u5668\u901a\u4fe1\uff08container-to-container\uff09\u3002 \u5728Flannel\u7f51\u7edc\u63d2\u4ef6\u4e2d\u7684\u793a\u4f8b\u6d41\u7a0b\u662f\uff1aPod \u2192 veth\u5bf9 \u2192 cni0 \u2192 flannel.1 \u2192 \u5bbf\u4e3b\u673aeth0 \u2192 \u5bbf\u4e3b\u673aeth0 \u2192 flannel.1 \u2192 cni0 \u2192 veth\u5bf9 \u2192 Pod\u3002 Pod\u5bf9Service\u901a\u4fe1\uff08Pod-to-Service\uff09\uff1a \u6d41\u7a0b: Pod \u2192 \u5185\u6838 \u2192 Service iptables \u2192 Service \u2192 Pod iptables \u2192 Pod\u3002 \u5916\u90e8\u5bf9Service\u901a\u4fe1\uff08External-to-Service\uff09\uff1a \u8d1f\u8f7d\u5747\u8861\u5668: SLB \u2192 NodePort \u2192 Service \u2192 Pod\u3002 kube-proxy \u662f\u5bf9iptables\u8d1f\u8d23\uff0c\u4e0d\u662f\u7f51\u7edc\u6d41\u91cf\uff08traffic\uff09\u3002 kube-proxy \u662fKubernetes\u96c6\u7fa4\u4e2d\u7684\u4e00\u4e2a\u7ec4\u4ef6\uff0c\u8d1f\u8d23\u4e3aService\u63d0\u4f9b\u4ee3\u7406\u670d\u52a1\uff0c\u540c\u65f6\u4e5f\u662fKubernetes\u7f51\u7edc\u6a21\u578b\u4e2d\u7684\u91cd\u8981\u7ec4\u6210\u90e8\u5206\u4e4b\u4e00\u3002 kube-proxy \u4f1a\u5728\u6bcf\u4e2a\u8282\u70b9\u4e0a\u542f\u52a8\u4e00\u4e2a\u4ee3\u7406\u8fdb\u7a0b\uff0c\u901a\u8fc7\u76d1\u542cKubernetes API Server\u7684Service\u548cEndpoint\u7684\u53d8\u5316\u6765\u7ef4\u62a4\u4e00\u4e2a\u672c\u5730\u7684Service\u548cEndpoint\u7684\u7f13\u5b58\u3002\u5f53\u6709\u8bf7\u6c42\u5230\u8fbe\u67d0\u4e2aService\u65f6\uff0c kube-proxy \u4f1a\u6839\u636e\u8be5Service\u7684\u7c7b\u578b\uff08ClusterIP\u3001NodePort\u3001LoadBalancer\u3001ExternalName\uff09\u548c\u7aef\u53e3\u53f7\uff0c\u751f\u6210\u76f8\u5e94\u7684iptables\u89c4\u5219\uff0c\u5c06\u8bf7\u6c42\u8f6c\u53d1\u7ed9Service\u6240\u4ee3\u7406\u7684\u540e\u7aefPod\u3002 iptables\u662fLinux\u7cfb\u7edf\u4e2d\u7684\u4e00\u4e2a\u91cd\u8981\u7f51\u7edc\u5de5\u5177\uff0c\u53ef\u4ee5\u8bbe\u7f6eIP\u5305\u7684\u8fc7\u6ee4\u3001\u8f6c\u53d1\u548c\u4fee\u6539\u89c4\u5219\uff0c\u53ef\u4ee5\u5b9e\u73b0\u7f51\u7edc\u5c42\u7684\u9632\u706b\u5899\u3001NAT\u7b49\u529f\u80fd\u3002\u5728Kubernetes\u96c6\u7fa4\u4e2d\uff0c kube-proxy \u901a\u8fc7\u751f\u6210\u548c\u66f4\u65b0iptables\u89c4\u5219\uff0c\u6765\u5b9e\u73b0Service\u548cEndpoint\u4e4b\u95f4\u7684\u8f6c\u53d1\u548c\u4ee3\u7406\u3002\u5177\u4f53\u6765\u8bf4\uff0ckube-proxy\u4f1a\u4e3a\u6bcf\u4e2aService\u521b\u5efa\u4e09\u6761iptables\u89c4\u5219\u94fe\uff08nat\u8868\u4e2d\u7684KUBE-SERVICES\u548cKUBE-NODEPORTS\u94fe\uff0c\u4ee5\u53cafilter\u8868\u4e2d\u7684KUBE-SVC-XXXXX\u94fe\uff09\uff0c\u901a\u8fc7\u8fd9\u4e9b\u89c4\u5219\u94fe\uff0c\u5c06\u8bf7\u6c42\u8f6c\u53d1\u5230\u76f8\u5e94\u7684Pod\u6216\u8005Service\u4e0a\u3002 \u56e0\u6b64\uff0c kube-proxy \u548ciptables\u662f\u7d27\u5bc6\u76f8\u5173\u7684\u4e24\u4e2a\u7ec4\u4ef6\uff0c\u901a\u8fc7iptables\u89c4\u5219\u6765\u5b9e\u73b0Service\u548cPod\u4e4b\u95f4\u7684\u8f6c\u53d1\u548c\u4ee3\u7406\u3002\u8fd9\u79cd\u5b9e\u73b0\u65b9\u5f0f\u5177\u6709\u53ef\u6269\u5c55\u6027\u548c\u9ad8\u53ef\u7528\u6027\uff0c\u540c\u65f6\u4e5f\u63d0\u4f9b\u4e86\u4e00\u79cd\u7075\u6d3b\u7684\u7f51\u7edc\u6a21\u578b\uff0c\u53ef\u4ee5\u65b9\u4fbf\u5730\u5b9e\u73b0\u670d\u52a1\u53d1\u73b0\u3001\u8d1f\u8f7d\u5747\u8861\u7b49\u529f\u80fd\u3002 sudo kubeadm init \\ --dry-run \\ --pod-network-cidr = 10 .244.0.0/16 \\ --service-cidr = 192 .244.0.0/16 \\ --image-repository = registry.aliyuncs.com/google_containers \\ --kubernetes-version = v1.24.0 sudo kubeadm init \\ --pod-network-cidr = 10 .244.0.0/16 \\ --service-cidr = 192 .244.0.0/16 \\ --image-repository = registry.aliyuncs.com/google_containers \\ --kubernetes-version = v1.24.0 kubeconfig\u6587\u4ef6 \u00b6 \u7ed9\u5f53\u524d\u5b89\u88c5\u7528\u6237\u914d\u7f6e kubeconfig \u6587\u4ef6\uff08\u5f53\u524d\u4f8b\u5b50\u662f\u7528\u6237 vagrant \uff09\u3002 mkdir -p $HOME /.kube sudo cp -i /etc/kubernetes/admin.conf $HOME /.kube/config sudo chown $( id -u ) : $( id -g ) $HOME /.kube/config Kubernetes \u63d0\u4f9b\u4e86\u4e00\u4e2a\u547d\u4ee4\u884c\u5de5\u5177 kubectl \uff0c\u7528\u4e8e\u4f7f\u7528 Kubernetes API \u4e0e Kubernetes \u96c6\u7fa4\u7684\u63a7\u5236\u5e73\u9762\u8fdb\u884c\u901a\u4fe1\u3002 kubectl \u63a7\u5236 Kubernetes cluster manager \uff08\u96c6\u7fa4\u7ba1\u7406\u5668\uff09\u3002 \u5bf9\u4e8e\u914d\u7f6e\uff0ckubectl \u5728 $HOME/.kube \u76ee\u5f55\u4e2d\u67e5\u627e\u4e00\u4e2a\u540d\u4e3a config \u7684\u6587\u4ef6\uff0c\u8be5\u6587\u4ef6\u662f\u7531 kubeadm init \u751f\u6210\u7684\u6587\u4ef6 /etc/kubernetes/admin.conf \u7684\u526f\u672c\u3002 \u6211\u4eec\u53ef\u4ee5\u901a\u8fc7\u8bbe\u7f6e KUBECONFIG \u73af\u5883\u53d8\u91cf\u6216\u8bbe\u7f6e --kubeconfig flag \u6807\u5fd7\u6765\u6307\u5b9a\u5176\u4ed6 kubeconfig \u6587\u4ef6\u3002\u5982\u679c KUBECONFIG \u73af\u5883\u53d8\u91cf\u4e0d\u5b58\u5728\uff0ckubectl \u5c06\u4f7f\u7528\u9ed8\u8ba4\u7684 kubeconfig \u6587\u4ef6 $HOME/.kube/config \u3002 kubeconfig \u6587\u4ef6\u4e2d\u7684 context\uff08\u4e0a\u4e0b\u6587\uff09 \u5143\u7d20\u7528\u4e8e\u5c06\u8bbf\u95ee\u53c2\u6570\u5206\u7ec4\u5230\u4e00\u4e2a\u65b9\u4fbf\u7684\u540d\u79f0\u4e0b\u3002\u6bcf\u4e2a\u4e0a\u4e0b\u6587\u90fd\u6709\u4e09\u4e2a\u53c2\u6570\uff1a\u96c6\u7fa4\u3001\u547d\u540d\u7a7a\u95f4\u548c\u7528\u6237\u3002\u9ed8\u8ba4\u60c5\u51b5\u4e0b\uff0ckubectl \u547d\u4ee4\u884c\u5de5\u5177\u4f7f\u7528\u5f53\u524d\u4e0a\u4e0b\u6587\u4e2d\u7684\u53c2\u6570\u4e0e\u96c6\u7fa4\u901a\u4fe1\u3002 \u6587\u4ef6 .kube/config \u7684\u4f8b\u5b50\uff1a apiVersion : v1 clusters : - cluster : certificate-authority-data : server : https://:6443 name : contexts : - context : cluster : namespace : user : name : @ current-context : kind : Config preferences : {} users : - name : user : client-certificate-data : client-key-data : \u8bfb\u53d6\u5f53\u524d\u4e0a\u4e0b\u6587\uff1a kubectl config get-contexts \u8fd0\u884c\u7ed3\u679c\uff1a CURRENT NAME CLUSTER AUTHINFO NAMESPACE * kubernetes-admin@kubernetes kubernetes kubernetes-admin \u5b89\u88c5Calico \u00b6 \u53c2\u8003\u5b89\u88c5\u6307\u5bfc End-to-end Calico installation \u3002 \u5feb\u901f\u5b89\u88c5\u624b\u518c QuickStart \u5b89\u88c5 Calico\uff1a kubectl create -f https://raw.githubusercontent.com/projectcalico/calico/v3.25.1/manifests/tigera-operator.yaml \u8fd0\u884c\u7ed3\u679c\uff1a namespace/tigera-operator created customresourcedefinition.apiextensions.k8s.io/bgpconfigurations.crd.projectcalico.org created customresourcedefinition.apiextensions.k8s.io/bgppeers.crd.projectcalico.org created customresourcedefinition.apiextensions.k8s.io/blockaffinities.crd.projectcalico.org created customresourcedefinition.apiextensions.k8s.io/caliconodestatuses.crd.projectcalico.org created customresourcedefinition.apiextensions.k8s.io/clusterinformations.crd.projectcalico.org created customresourcedefinition.apiextensions.k8s.io/felixconfigurations.crd.projectcalico.org created customresourcedefinition.apiextensions.k8s.io/globalnetworkpolicies.crd.projectcalico.org created customresourcedefinition.apiextensions.k8s.io/globalnetworksets.crd.projectcalico.org created customresourcedefinition.apiextensions.k8s.io/hostendpoints.crd.projectcalico.org created customresourcedefinition.apiextensions.k8s.io/ipamblocks.crd.projectcalico.org created customresourcedefinition.apiextensions.k8s.io/ipamconfigs.crd.projectcalico.org created customresourcedefinition.apiextensions.k8s.io/ipamhandles.crd.projectcalico.org created customresourcedefinition.apiextensions.k8s.io/ippools.crd.projectcalico.org created customresourcedefinition.apiextensions.k8s.io/ipreservations.crd.projectcalico.org created customresourcedefinition.apiextensions.k8s.io/kubecontrollersconfigurations.crd.projectcalico.org created customresourcedefinition.apiextensions.k8s.io/networkpolicies.crd.projectcalico.org created customresourcedefinition.apiextensions.k8s.io/networksets.crd.projectcalico.org created customresourcedefinition.apiextensions.k8s.io/apiservers.operator.tigera.io created customresourcedefinition.apiextensions.k8s.io/imagesets.operator.tigera.io created customresourcedefinition.apiextensions.k8s.io/installations.operator.tigera.io created customresourcedefinition.apiextensions.k8s.io/tigerastatuses.operator.tigera.io created serviceaccount/tigera-operator created clusterrole.rbac.authorization.k8s.io/tigera-operator created clusterrolebinding.rbac.authorization.k8s.io/tigera-operator created deployment.apps/tigera-operator created kubectl apply -f https://raw.githubusercontent.com/projectcalico/calico/v3.25.1/manifests/calicoctl.yaml \u8fd0\u884c\u7ed3\u679c\uff1a serviceaccount/calicoctl created pod/calicoctl created clusterrole.rbac.authorization.k8s.io/calicoctl created clusterrolebinding.rbac.authorization.k8s.io/calicoctl created \u9a8c\u8bc1Calico\u7684\u72b6\u6001\u3002Calico\u7684\u521d\u59cb\u5316\u8fc7\u7a0b\u53ef\u80fd\u9700\u8981\u51e0\u5206\u949f\u65f6\u95f4\u5b8c\u6210\u3002 kubectl get pod -n kube-system | grep calico \u8fd0\u884c\u7ed3\u679c\uff1a calico-kube-controllers-555bc4b957-l8bn2 0/1 Pending 0 28s calico-node-255pc 0/1 Init:1/3 0 29s calico-node-7tmnb 0/1 Init:1/3 0 29s calico-node-w8nvl 0/1 Init:1/3 0 29s \u9a8c\u8bc1\u7f51\u7edc\u72b6\u6001\u3002 sudo nerdctl network ls \u8fd0\u884c\u7ed3\u679c\uff1a NETWORK ID NAME FILE k8s-pod-network /etc/cni/net.d/10-calico.conflist 17f29b073143 bridge /etc/cni/net.d/nerdctl-bridge.conflist host none \u914d\u7f6e\u5de5\u4f5c\u8282\u70b9 \u00b6 \u4f7f\u7528 kubeadm token \u6765\u751f\u6210\u52a0\u5165\u96c6\u7fa4\u7684\u4ee4\u724c\uff08token\uff09\u548c\u54c8\u897f\u503c\uff08hash value\uff09\u3002 kubeadm token create --print-join-command \u547d\u4ee4\u7528\u6cd5\uff1a sudo kubeadm join :6443 --token --discovery-token-ca-cert-hash < hash key generated by kubeadm init> \u8fd0\u884c\u7ed3\u679c\uff1a [preflight] Running pre-flight checks [WARNING SystemVerification]: missing optional cgroups: blkio [preflight] Reading configuration from the cluster... [preflight] FYI: You can look at this config file with 'kubectl -n kube-system get cm kubeadm-config -o yaml' [kubelet-start] Writing kubelet configuration to file \"/var/lib/kubelet/config.yaml\" [kubelet-start] Writing kubelet environment file with flags to file \"/var/lib/kubelet/kubeadm-flags.env\" [kubelet-start] Starting the kubelet [kubelet-start] Waiting for the kubelet to perform the TLS Bootstrap... This node has joined the cluster: * Certificate signing request was sent to apiserver and a response was received. * The Kubelet was informed of the new secure connection details. Run 'kubectl get nodes' on the control-plane to see this node join the cluster. \u68c0\u67e5\u96c6\u7fa4\u72b6\u6001 \u00b6 \u67e5\u770b Kubernetes \u96c6\u7fa4\u7684\u4fe1\u606f\uff0c\u5305\u62ec\u96c6\u7fa4 API Server \u7684\u5730\u5740\u3001Kubernetes DNS \u670d\u52a1\u7684\u5730\u5740\u7b49\u3002 kubectl cluster-info \u8fd0\u884c\u7ed3\u679c\uff1a bKubernetes control plane is running at https://11.0.1.129:6443 CoreDNS is running at https://11.0.1.129:6443/api/v1/namespaces/kube-system/services/kube-dns:dns/proxy To further debug and diagnose cluster problems, use 'kubectl cluster-info dump'. \u5217\u51fa\u96c6\u7fa4\u4e2d\u6240\u6709\u8282\u70b9\u7684\u8be6\u7ec6\u4fe1\u606f\uff0c\u5305\u62ec\u8282\u70b9\u540d\u79f0\u3001\u8282\u70b9 IP\u3001\u8282\u70b9\u6807\u7b7e\u3001\u8282\u70b9\u72b6\u6001\u7b49\u3002 kubectl get nodes -owide \u5217\u51fa Kubernetes \u96c6\u7fa4\u4e2d\u6240\u6709 Namespace \u4e0b\u7684 Pod\u3002 kubectl get pod -A \u66f4\u65b0\u5b89\u88c5 \u00b6 Bash\u81ea\u52a8\u8865\u5168 \u00b6 \u5728\u6bcf\u4e2a\u8282\u70b9\u4e0a\u914d\u7f6eBash\u81ea\u52a8\u8865\u5168\u529f\u80fd\u3002 \u53c2\u8003 \u6307\u5bfc \u8bbe\u7f6e kubectl \u81ea\u52a8\u8865\u5168\u529f\u80fdauto-completion \u3002 apt install -y bash-completion source /usr/share/bash-completion/bash_completion source < ( kubectl completion bash ) echo \"source <(kubectl completion bash)\" >> ~/.bashrc source ~/.bashrc \u522b\u540d \u00b6 \u5982\u679c\u6211\u4eec\u4e3a kubectl \u8bbe\u7f6e\u4e00\u4e2a\u522b\u540d\uff0c\u6211\u4eec\u53ef\u4ee5\u901a\u8fc7\u4e00\u4e9b\u65b9\u6cd5\u6765\u6269\u5c55 shell \u81ea\u52a8\u8865\u5168\u529f\u80fd\uff0c\u4f7f\u5176\u80fd\u591f\u4e0e\u8be5\u522b\u540d\u4e00\u8d77\u4f7f\u7528\u3002 \u4e00\u79cd\u65b9\u6cd5\u662f\u5728 Bash shell \u914d\u7f6e\u6587\u4ef6\uff08\u5982 .bashrc \u6216 .bash_profile\uff09\u4e2d\u8bbe\u7f6e\u522b\u540d\uff0c\u5e76\u4e3a\u8be5\u522b\u540d\u6307\u5b9a kubectl \u7684\u5b8c\u6574\u8def\u5f84\u3002\u4f8b\u5982\uff0c\u53ef\u4ee5\u5728 .bashrc \u6587\u4ef6\u4e2d\u6dfb\u52a0\u4ee5\u4e0b\u5185\u5bb9\uff1a alias k = 'path/to/kubectl' \u7136\u540e\uff0c\u53ef\u4ee5\u4f7f\u7528\u4ee5\u4e0b\u547d\u4ee4\u91cd\u65b0\u52a0\u8f7d .bashrc \u6587\u4ef6\uff1a source ~/.bashrc \u63a5\u4e0b\u6765\uff0c\u53ef\u4ee5\u4f7f\u7528 k \u547d\u4ee4\u6765\u4ee3\u66ff kubectl \u547d\u4ee4\uff0c\u5e76\u5728\u5176\u540e\u9762\u6dfb\u52a0\u76f8\u5e94\u7684\u53c2\u6570\u548c\u9009\u9879\u3002\u5f53\u4f7f\u7528\u81ea\u52a8\u8865\u5168\u529f\u80fd\u65f6\uff0cBash shell \u4f1a\u81ea\u52a8\u5c06 k \u522b\u540d\u8f6c\u6362\u4e3a kubectl \u7684\u5b8c\u6574\u8def\u5f84\uff0c\u5e76\u5bf9\u5176\u8fdb\u884c\u81ea\u52a8\u8865\u5168\u3002 \u53e6\u4e00\u79cd\u65b9\u6cd5\u662f\u4f7f\u7528 Bash shell \u5185\u7f6e\u7684 complete \u51fd\u6570\u6765\u4e3a\u522b\u540d\u8bbe\u7f6e\u81ea\u52a8\u8865\u5168\u529f\u80fd\u3002\u4f8b\u5982\uff0c\u53ef\u4ee5\u5728 .bashrc \u6587\u4ef6\u4e2d\u6dfb\u52a0\u4ee5\u4e0b\u5185\u5bb9\uff1a echo 'alias k=kubectl' >>~/.bashrc echo 'complete -o default -F __start_kubectl k' >>~/.bashrc \u8fd9\u5c06\u4e3a\u522b\u540d k \u8bbe\u7f6e\u81ea\u52a8\u8865\u5168\u529f\u80fd\uff0c\u5e76\u5c06\u5176\u4e0e kubectl \u7684\u81ea\u52a8\u8865\u5168\u51fd\u6570 __start_kubectl \u5173\u8054\u8d77\u6765\u3002\u8fd9\u6837\uff0c\u5f53\u7528\u6237\u5728 k \u547d\u4ee4\u540e\u8f93\u5165Tab\u952e\u65f6\uff0cBash shell \u4f1a\u81ea\u52a8\u8c03\u7528 __start_kubectl \u51fd\u6570\uff0c\u5e76\u4e3a\u7528\u6237\u63d0\u4f9b\u76f8\u5e94\u7684\u81ea\u52a8\u8865\u5168\u5efa\u8bae\u3002 \u66f4\u65b0\u9ed8\u8ba4Context \u00b6 \u67e5\u770b\u5f53\u524d\u7684 context \u5217\u8868\uff1a kubectl config get-contexts \u8fd9\u4e2a\u547d\u4ee4\u4f1a\u5217\u51fa\u6240\u6709\u53ef\u7528\u7684 context \u5217\u8868\uff0c\u5e76\u6807\u8bb0\u51fa\u5f53\u524d\u6b63\u5728\u4f7f\u7528\u7684 context\u3002 \u7c7b\u4f3c\u4e0b\u9762\u7ed3\u679c\uff1a kubernetes-admin@kubernetes \u662fContext\u540d\u3002 kubernetes \u662f\u96c6\u7fa4\u540d\u3002 kubernetes-admin \u662f\u7528\u6237\u540d\u3002 \u5f53\u524d\u4f8b\u5b50\u4e2d\u6ca1\u6709\u6307\u5b9a\u540d\u79f0\u7a7a\u95f4\u3002 CURRENT NAME CLUSTER AUTHINFO NAMESPACE * kubernetes-admin@kubernetes kubernetes kubernetes-admin \u66f4\u65b0context\u3002\u4f8b\u5982\uff0c\u66f4\u65b0context\u7684\u9ed8\u8ba4\u540d\u79f0\u7a7a\u95f4\u7b49\u3002 # Usage: kubectl config set-context --cluster = --namespace = --user = # Set default namespace kubectl config set-context kubernetes-admin@kubernetes --cluster = kubernetes --namespace = default --user = kubernetes-admin \u5728\u4e0d\u540c\u7684context\u4e4b\u95f4\u5207\u6362\u3002 # Usage: kubectl config use-context # Switch to new context kubectl config use-context kubernetes-admin@kubernetes \u53c2\u8003\u8d44\u6599\uff1a * kubectl * commandline \u5b89\u88c5Helm \u00b6 Helm \u662f Kubernetes \u7684\u5305\u7ba1\u7406\u5de5\u5177\uff0c\u5b83\u4e0d\u968f Kubernetes \u4e00\u8d77\u63d0\u4f9b\u3002 Helm \u6709\u4e09\u4e2a\u6838\u5fc3\u6982\u5ff5\uff1a Chart\uff08\u56fe\u8868\uff09\u662f Helm \u7684\u8f6f\u4ef6\u5305\uff0c\u5b83\u5305\u542b\u4e86\u5728 Kubernetes \u96c6\u7fa4\u4e2d\u8fd0\u884c\u5e94\u7528\u7a0b\u5e8f\u3001\u5de5\u5177\u6216\u670d\u52a1\u6240\u9700\u7684\u6240\u6709\u8d44\u6e90\u5b9a\u4e49\u3002\u53ef\u4ee5\u5c06\u5176\u89c6\u4e3a Kubernetes \u7684 Homebrew \u516c\u5f0f\u3001Apt dpkg \u6216 Yum RPM \u6587\u4ef6\u7b49\u7b49\u3002 Repository\uff08\u4ed3\u5e93\uff09\u662f\u56fe\u8868\u53ef\u4ee5\u88ab\u6536\u96c6\u548c\u5171\u4eab\u7684\u5730\u65b9\uff0c\u7c7b\u4f3c\u4e8e Perl \u7684 CPAN \u5b58\u50a8\u5e93\u6216 Fedora \u7684\u8f6f\u4ef6\u5305\u6570\u636e\u5e93\uff0c\u4f46\u7528\u4e8e Kubernetes \u8f6f\u4ef6\u5305\u3002 Release\uff08\u53d1\u5e03\uff09\u662f\u5728 Kubernetes \u96c6\u7fa4\u4e2d\u8fd0\u884c\u7684\u56fe\u8868\u5b9e\u4f8b\u3002\u4e00\u4e2a\u56fe\u8868\u901a\u5e38\u53ef\u4ee5\u5728\u540c\u4e00\u96c6\u7fa4\u4e2d\u5b89\u88c5\u591a\u6b21\uff0c\u5e76\u4e14\u6bcf\u6b21\u5b89\u88c5\u90fd\u4f1a\u521b\u5efa\u4e00\u4e2a\u65b0\u7684\u53d1\u5e03\u3002\u4ee5 MySQL \u56fe\u8868\u4e3a\u4f8b\uff0c\u5982\u679c\u60f3\u8981\u5728\u96c6\u7fa4\u4e2d\u8fd0\u884c\u4e24\u4e2a\u6570\u636e\u5e93\uff0c\u5219\u53ef\u4ee5\u5b89\u88c5\u8be5\u56fe\u8868\u4e24\u6b21\uff0c\u6bcf\u6b21\u5b89\u88c5\u90fd\u4f1a\u521b\u5efa\u4e00\u4e2a\u65b0\u7684\u53d1\u5e03\uff0c\u6bcf\u4e2a\u53d1\u5e03\u90fd\u6709\u81ea\u5df1\u7684\u53d1\u5e03\u540d\u79f0\u3002 \u53c2\u8003\u6587\u6863\uff1a installation guide binary release source code . Helm\u5ba2\u6237\u7aef\u5b89\u88c5\uff1a curl -fsSL -o get_helm.sh https://raw.githubusercontent.com/helm/helm/main/scripts/get-helm-3 chmod 700 get_helm.sh ./get_helm.sh \u8fd0\u884c\u7ed3\u679c\uff1a Downloading https://get.helm.sh/helm-v3.9.1-linux-amd64.tar.gz Verifying checksum... Done. Preparing to install helm into /usr/local/bin helm installed into /usr/local/bin/helm \u63d0\u793a\uff1a * helm init \u5728Helm 3\u4e2d\u5df2\u53d6\u6d88\uff0c\u4e14Tiller\u4e5f\u4e00\u540c\u53d6\u6d88\u3002\u4eca\u540e\u5728\u96c6\u7fa4\u4e2d\u4f7f\u7528Helm\u65f6\u4e0d\u518d\u9700\u8981\u5b89\u88c5Tiller\u3002 * helm search \u53ef\u4ee5\u7528\u6765\u641c\u7d22\u4e24\u79cd\u4e0d\u540c\u7c7b\u578b\u7684\u8d44\u6e90\uff1a * helm search hub \u5728 Artifact Hub \u4e2d\u641c\u7d22\uff0c\u8fd9\u4e2ahub\u91cc\u5217\u51fa\u6765\u81ea\u6570\u5341\u4e2a\u4e0d\u540c\u4ed3\u5e93\u7684 Helm Chart\u3002 * helm search repo \u547d\u4ee4\u7528\u4e8e\u641c\u7d22\u5df2\u6dfb\u52a0\u5230\u672c\u5730 Helm \u5ba2\u6237\u7aef\u7684\u4ed3\u5e93\uff08\u4f7f\u7528 helm repo add \u547d\u4ee4\uff09\u3002\u6b64\u641c\u7d22\u662f\u5728\u672c\u5730\u6570\u636e\u4e0a\u8fdb\u884c\u7684\uff0c\u4e0d\u9700\u8981\u516c\u5171\u7f51\u7edc\u8fde\u63a5\u3002 \u53c2\u8003\u8d44\u6599\uff1a Helming development \u91cd\u7f6e\u96c6\u7fa4 \u00b6 \u6ce8\u610f\uff1a\u4e0b\u9762\u7684\u64cd\u4f5c\u4f1a\u91cd\u7f6e\u5f53\u524d\u96c6\u7fa4\uff08\u5220\u9664\u96c6\u7fa4\uff09\u3002 \u5220\u9664\u96c6\u7fa4\u4e2d\u6240\u6709\u8282\u70b9\u3002 kubeadm reset \u6e05\u9664 iptables \u4e2d\u5df2\u5b9a\u4e49\u7684\u89c4\u5219\u3002 iptables -F && iptables -t nat -F && iptables -t mangle -F && iptables -X \u6e05\u9664 IPVS \u4e2d\u5b9a\u4e49\u7684\u89c4\u5219\uff08\u5982\u679c\u4f7f\u7528 IPVS \uff09\u3002 ipvsadm --clear","title":"\u591a\u8282\u70b9\u865a\u62df\u673a\u5b89\u88c5Kubernetes"},{"location":"k8s/cka_cn/installation/multiple-local/#cka2kubernetes","text":"","title":"CKA\u81ea\u5b66\u7b14\u8bb02:\u591a\u8282\u70b9\u865a\u62df\u673a\u5b89\u88c5Kubernetes"},{"location":"k8s/cka_cn/installation/multiple-local/#_1","text":"\u5728\u672c\u5730Windows\u73af\u5883\u4e2d\uff0c\u901a\u8fc7VMWare\u5b89\u88c5\u4e09\u53f0Ubuntu\u865a\u62df\u673a\u3002\u5728Ubuntu\u865a\u62df\u673a\u4e2d\u5b89\u88c5\u57fa\u4e8eContainerd\u7684Kubernetes\u7cfb\u7edf\uff0c\u5e76\u5206\u522b\u914d\u7f6e\u4e00\u4e2a\u4e3b\u8282\u70b9Master\u548c\u4e24\u4e2a\u5de5\u4f5c\u8282\u70b9Worker\u3002","title":"\u6458\u8981"},{"location":"k8s/cka_cn/installation/multiple-local/#_2","text":"VMWare \u8bbe\u7f6e VMnet1: host-only\u6a21\u5f0f, \u7f51\u7edcsubnet: 192.168.150.0/24 VMnet8: NAT\u6a21\u5f0f, \u7f51\u7edcsubnet: 11.0.1.0/24 \u901a\u8fc7VMWare\u521b\u5efa\u5ba2\u6237\u865a\u62df\u673a\u3002 \u5185\u5b58\uff1a4 GB CPU\uff1a1 CPUs with 2 Cores \u64cd\u4f5c\u7cfb\u7edf\uff1aUbuntu Server 22.04 \u7f51\u7edc\uff1aNAT \u63d0\u793a\uff1a \u5f53\u524d\u7ec3\u4e60\u4e2d\uff0cKubernetes\u662f\u57fa\u4e8eContainerd\uff0c\u4e0d\u662fDocker\u3002","title":"\u672c\u5730\u865a\u62df\u673a\u8bbe\u7f6e"},{"location":"k8s/cka_cn/installation/multiple-local/#ubuntu","text":"\u6ce8\u610f\uff1a\u4e0b\u9762\u7684\u4efb\u52a1\uff0c\u9700\u8981\u5728\u6bcf\u53f0\u865a\u62df\u673a\u4e2d\u6267\u884c\u4e00\u6b21\u3002\u4ee5\u4e0b\u7b80\u79f0\u865a\u62df\u673a\u4e3a\u8282\u70b9\u3002 \u5728\u6240\u6709\u8282\u70b9\u4e2d\u521b\u5efa\u7528\u6237 vagrant \u3002 sudo adduser vagrant sudo usermod -g sudo vagrant sudo usermod -a -G root vagrant sudo passwd vagrant \u5728\u6240\u6709\u8282\u70b9\u4e2d\u8bbe\u7f6e\u7528\u6237 root \u7684\u5bc6\u7801\u3002 sudo passwd root \u4fee\u6539ssh\u670d\u52a1\u7684\u914d\u7f6e\u6587\u4ef6\u3002\u5f00\u653e root \u7528\u6237\u901a\u8fc7ssh\u767b\u5f55\uff08\u9ed8\u8ba4\u662f\u7981\u7528\u7684\uff09\u3002 sudo vi /etc/ssh/sshd_config \u628a\u53c2\u6570 PermitRootLogin \u7684\u503c\u4ece prohibit-password \u6539\u4e3a yes \u3002 PermitRootLogin yes # PermitRootLogin prohibit-password \u91cd\u65b0\u542f\u52a8sshd\u670d\u52a1\u3002 sudo systemctl restart sshd \u66f4\u6539\u4e3b\u673a\u540d\uff0c\u8fd9\u91cc\u662f ubu1 . sudo hostnamectl set-hostname ubu1 sudo hostnamectl set-hostname ubu1 --pretty \u9a8c\u8bc1\u4e3b\u673a\u540d\u662f\u5426\u88ab\u6b63\u786e\u4fee\u6539\u4e86\uff0c\u6bd4\u5982\u6539\u4e3a ubu1 \u3002 cat /etc/machine-info \u9a8c\u8bc1\u4e3b\u673a\u540d\u662f\u5426\u88ab\u6b63\u786e\u4fee\u6539\u4e86\uff0c\u6bd4\u5982\u6539\u4e3a ubu1 \u3002 cat /etc/hostname \u9a8c\u8bc1\u4e3b\u673aIP\u5730\u5740 127.0.1.1 \u5df2\u7ecf\u914d\u7f6e\u7ed9\u5f53\u524d\u8282\u70b9\uff0c\u6bd4\u5982 ubu1 \u3002\u540c\u65f6\uff0c\u5728\u6240\u6709\u8282\u70b9\u7684 /etc/hosts \u6587\u4ef6\u4e2d\u6dfb\u52a0\u5176\u4ed6\u8282\u70b9\u7684IP\u548c\u4e3b\u673a\u5bf9\u5e94\u4fe1\u606f\u3002 sudo vi /etc/hosts \u4ee5\u5f53\u524d\u7ec3\u4e60\u4e3a\u4f8b\uff0c\u4fee\u6539\u540e\u7684 /etc/hosts \u6587\u4ef6\u7c7b\u4f3c\u5982\u4e0b\u5185\u5bb9\u3002 127.0.1.1 ubu1 11.0.1.129 ubu1 11.0.1.130 ubu2 11.0.1.131 ubu3 11.0.1.132 ubu4 \u521b\u5efa\u6587\u4ef6 /etc/netplan/00-installer-config.yaml \u3002 sudo vi /etc/netplan/00-installer-config.yaml \u66f4\u65b0\u6b64\u6587\u4ef6\uff0c\u8bbe\u5b9a\u5f53\u524d\u8282\u70b9\u4f7f\u7528\u56fa\u5b9aIP\u5730\u5740\uff0c\u6bd4\u5982\uff0c 11.0.1.129 \u3002 network : ethernets : ens33 : dhcp4 : false addresses : - 11.0.1.129/24 nameservers : addresses : - 11.0.1.2 routes : - to : default via : 11.0.1.2 version : 2 \u6267\u884c\u4e0b\u9762\u547d\u4ee4\u65f6\uff0c\u4f7f\u4e0a\u8ff0\u6539\u52a8\u751f\u6548\u3002\u6ce8\u610f\uff0c\u5f53\u524dssh\u8fde\u63a5\u4f1a\u56e0\u6b64\u800c\u65ad\u5f00\u3002 sudo netplan apply \u5728\u6240\u6709\u8282\u70b9\u7981\u7528\u4ea4\u6362\u5206\u533aswap\u548c\u9632\u706b\u5899firewall\u3002 sudo swapoff -a sudo ufw disable sudo ufw status verbose \u5728\u6240\u6709\u8282\u70b9\u7684\u6587\u4ef6 /etc/fstab \u4e2d\u6ce8\u91ca\u6389\u6d89\u53caswap\u7684\u90a3\u4e00\u884c\uff0c\u4fee\u6539\u540e\u9700\u8981\u91cd\u542f\u5f53\u524d\u8282\u70b9\u3002 sudo vi /etc/fstab \u4fee\u6539\u540e\u7684\u7ed3\u679c\u7c7b\u4f3c\u5982\u4e0b\u3002 /dev/disk/by-uuid/df370d2a-83e5-4895-8c7f-633f2545e3fe / ext4 defaults 0 1 # /swap.img none swap sw 0 0 \u5728\u6240\u6709\u8282\u70b9\u8bbe\u7f6e\u7edf\u4e00\u7684\u65f6\u533a\u3002 sudo ln -sf /usr/share/zoneinfo/Asia/Shanghai /etc/localtime sudo cp /etc/profile /etc/profile.bak echo 'LANG=\"en_US.UTF-8\"' | sudo tee -a /etc/profile source /etc/profile \u6267\u884c\u547d\u4ee4 ll /etc/localtime \u6765\u9a8c\u8bc1\u65f6\u533a\u662f\u5426\u4fee\u6539\u6b63\u786e\u3002 lrwxrwxrwx 1 root root 33 Jul 15 22:00 /etc/localtime -> /usr/share/zoneinfo/Asia/Shanghai \u5728\u6240\u6709\u8282\u70b9\u4fee\u6539\u5185\u6838\u8bbe\u7f6e\u3002 cat < /etc/apt/sources.list.d/kubernetes.list deb https://mirrors.aliyun.com/kubernetes/apt/ kubernetes-xenial main EOF \u68c0\u67e5\u5f53\u524d kubeadm \u7684\u7248\u672c\u3002 apt policy kubeadm \u5b89\u88c5 1.24.1-00 \u7248\u672c\u7684 kubeadm . sudo apt-get -y install kubelet = 1 .24.1-00 kubeadm = 1 .24.1-00 kubectl = 1 .24.1-00 --allow-downgrades","title":"\u5b89\u88c5Kubernetes"},{"location":"k8s/cka_cn/installation/multiple-local/#_3","text":"","title":"\u914d\u7f6e\u4e3b\u8282\u70b9"},{"location":"k8s/cka_cn/installation/multiple-local/#kubeadm","text":"\u5728\u627f\u62c5\u4e3b\u8282\u70b9\u7684\u865a\u62df\u673a\u91cc\u914d\u7f6e\u63a7\u5236\u5e73\u9762\uff08Control Plane\uff09\u3002 \u68c0\u67e5 kubeadm \u5f53\u524d\u9ed8\u8ba4\u914d\u7f6e\u53c2\u6570\u3002 kubeadm config print init-defaults \u7c7b\u4f3c\u7ed3\u679c\u5982\u4e0b\u3002\u4fdd\u5b58\u9ed8\u8ba4\u914d\u7f6e\u7684\u7ed3\u679c\uff0c\u540e\u7eed\u4f1a\u4f5c\u4e3a\u53c2\u8003\u3002 apiVersion : kubeadm.k8s.io/v1beta3 bootstrapTokens : - groups : - system:bootstrappers:kubeadm:default-node-token token : abcdef.0123456789abcdef ttl : 24h0m0s usages : - signing - authentication kind : InitConfiguration localAPIEndpoint : advertiseAddress : 1.2.3.4 bindPort : 6443 nodeRegistration : criSocket : unix:///var/run/containerd/containerd.sock imagePullPolicy : IfNotPresent name : node taints : null --- apiServer : timeoutForControlPlane : 4m0s apiVersion : kubeadm.k8s.io/v1beta3 certificatesDir : /etc/kubernetes/pki clusterName : kubernetes controllerManager : {} dns : {} etcd : local : dataDir : /var/lib/etcd imageRepository : k8s.gcr.io kind : ClusterConfiguration kubernetesVersion : 1.24.0 networking : dnsDomain : cluster.local serviceSubnet : 10.96.0.0/12 scheduler : {} \u6a21\u62df\u5b89\u88c5\u548c\u6b63\u5f0f\u5b89\u88c5\u3002 \u901a\u8fc7\u547d\u4ee4 kubeadm init \u8fdb\u884c\u4e3b\u8282\u70b9\u7684\u521d\u59cb\u5316\uff0c\u4e0b\u9762\u662f\u8fd9\u4e2a\u547d\u4ee4\u4e3b\u8981\u53c2\u6570\u7684\u8bf4\u660e\uff0c\u7279\u522b\u662f\u7f51\u7edc\u53c2\u6570\u7684\u4e09\u4e2a\u9009\u62e9\u3002 --pod-network-cidr : \u6307\u5b9apod\u4f7f\u7528\u7684IP\u5730\u5740\u8303\u56f4\u3002\u5982\u679c\u6307\u5b9a\u4e86\u8be5\u53c2\u6570\uff0c\u5219Control Plane\u4f1a\u81ea\u52a8\u8bb2\u6307\u5b9a\u7684CIDR\u5206\u914d\u7ed9\u6bcf\u4e2a\u8282\u70b9\u3002 IP\u5730\u5740\u6bb5 10.244.0.0/16 \u662fFlannel\u7f51\u7edc\u7ec4\u4ef6\u9ed8\u8ba4\u7684\u5730\u5740\u8303\u56f4\u3002\u5982\u679c\u9700\u8981\u4fee\u6539Flannel\u7684IP\u5730\u5740\u6bb5\uff0c\u9700\u8981\u5728\u8fd9\u91cc\u6307\u5b9a\uff0c\u4e14\u5728\u90e8\u7f72Flannel\u65f6\u4e5f\u8981\u4fdd\u6301\u4e00\u81f4\u7684IP\u6bb5\u3002 --apiserver-bind-port : API\u670d\u52a1\uff08API Server\uff09\u7684\u7aef\u53e3\uff0c\u9ed8\u8ba4\u65f66443\u3002 --service-cidr : \u6307\u5b9a\u670d\u52a1\uff08service\uff09\u7684IP\u5730\u5740\u6bb5\uff0c\u9ed8\u8ba4\u662f 10.96.0.0/12 \u3002 \u63d0\u793a\uff1a \u670d\u52a1VIPs\uff08service VIPs\uff09\uff0c\u4e5f\u79f0\u4f5c\u96c6\u7fa4IP\uff08Cluster IP\uff09\uff0c\u901a\u8fc7\u53c2\u6570 --service-cidr \u6307\u5b9a\u3002 podCIDR\uff0c\u4e5f\u79f0\u4e3aendpoint IP\uff0c\u901a\u8fc7\u53c2\u6570 --pod-network-cidr \u6307\u5b9a\u3002 \u67094\u79cd\u5178\u578b\u7684\u7f51\u7edc\u95ee\u9898\uff1a \u9ad8\u5ea6\u8026\u5408\u7684\u5bb9\u5668\u4e0e\u5bb9\u5668\u4e4b\u95f4\u7684\u901a\u4fe1\uff1a\u8fd9\u53ef\u4ee5\u901a\u8fc7Pod\uff08podCIDR\uff09\u548c\u672c\u5730\u4e3b\u673a\u901a\u4fe1\u6765\u89e3\u51b3\u3002 Pod\u5bf9Pod\u901a\u4fe1\uff08Pod-to-Pod\uff09\uff1a \u4e5f\u88ab\u79f0\u4e3a\u5bb9\u5668\u5bf9\u5bb9\u5668\u901a\u4fe1\uff08container-to-container\uff09\u3002 \u5728Flannel\u7f51\u7edc\u63d2\u4ef6\u4e2d\u7684\u793a\u4f8b\u6d41\u7a0b\u662f\uff1aPod \u2192 veth\u5bf9 \u2192 cni0 \u2192 flannel.1 \u2192 \u5bbf\u4e3b\u673aeth0 \u2192 \u5bbf\u4e3b\u673aeth0 \u2192 flannel.1 \u2192 cni0 \u2192 veth\u5bf9 \u2192 Pod\u3002 Pod\u5bf9Service\u901a\u4fe1\uff08Pod-to-Service\uff09\uff1a \u6d41\u7a0b: Pod \u2192 \u5185\u6838 \u2192 Service iptables \u2192 Service \u2192 Pod iptables \u2192 Pod\u3002 \u5916\u90e8\u5bf9Service\u901a\u4fe1\uff08External-to-Service\uff09\uff1a \u8d1f\u8f7d\u5747\u8861\u5668: SLB \u2192 NodePort \u2192 Service \u2192 Pod\u3002 kube-proxy \u662f\u5bf9iptables\u8d1f\u8d23\uff0c\u4e0d\u662f\u7f51\u7edc\u6d41\u91cf\uff08traffic\uff09\u3002 kube-proxy \u662fKubernetes\u96c6\u7fa4\u4e2d\u7684\u4e00\u4e2a\u7ec4\u4ef6\uff0c\u8d1f\u8d23\u4e3aService\u63d0\u4f9b\u4ee3\u7406\u670d\u52a1\uff0c\u540c\u65f6\u4e5f\u662fKubernetes\u7f51\u7edc\u6a21\u578b\u4e2d\u7684\u91cd\u8981\u7ec4\u6210\u90e8\u5206\u4e4b\u4e00\u3002 kube-proxy \u4f1a\u5728\u6bcf\u4e2a\u8282\u70b9\u4e0a\u542f\u52a8\u4e00\u4e2a\u4ee3\u7406\u8fdb\u7a0b\uff0c\u901a\u8fc7\u76d1\u542cKubernetes API Server\u7684Service\u548cEndpoint\u7684\u53d8\u5316\u6765\u7ef4\u62a4\u4e00\u4e2a\u672c\u5730\u7684Service\u548cEndpoint\u7684\u7f13\u5b58\u3002\u5f53\u6709\u8bf7\u6c42\u5230\u8fbe\u67d0\u4e2aService\u65f6\uff0c kube-proxy \u4f1a\u6839\u636e\u8be5Service\u7684\u7c7b\u578b\uff08ClusterIP\u3001NodePort\u3001LoadBalancer\u3001ExternalName\uff09\u548c\u7aef\u53e3\u53f7\uff0c\u751f\u6210\u76f8\u5e94\u7684iptables\u89c4\u5219\uff0c\u5c06\u8bf7\u6c42\u8f6c\u53d1\u7ed9Service\u6240\u4ee3\u7406\u7684\u540e\u7aefPod\u3002 iptables\u662fLinux\u7cfb\u7edf\u4e2d\u7684\u4e00\u4e2a\u91cd\u8981\u7f51\u7edc\u5de5\u5177\uff0c\u53ef\u4ee5\u8bbe\u7f6eIP\u5305\u7684\u8fc7\u6ee4\u3001\u8f6c\u53d1\u548c\u4fee\u6539\u89c4\u5219\uff0c\u53ef\u4ee5\u5b9e\u73b0\u7f51\u7edc\u5c42\u7684\u9632\u706b\u5899\u3001NAT\u7b49\u529f\u80fd\u3002\u5728Kubernetes\u96c6\u7fa4\u4e2d\uff0c kube-proxy \u901a\u8fc7\u751f\u6210\u548c\u66f4\u65b0iptables\u89c4\u5219\uff0c\u6765\u5b9e\u73b0Service\u548cEndpoint\u4e4b\u95f4\u7684\u8f6c\u53d1\u548c\u4ee3\u7406\u3002\u5177\u4f53\u6765\u8bf4\uff0ckube-proxy\u4f1a\u4e3a\u6bcf\u4e2aService\u521b\u5efa\u4e09\u6761iptables\u89c4\u5219\u94fe\uff08nat\u8868\u4e2d\u7684KUBE-SERVICES\u548cKUBE-NODEPORTS\u94fe\uff0c\u4ee5\u53cafilter\u8868\u4e2d\u7684KUBE-SVC-XXXXX\u94fe\uff09\uff0c\u901a\u8fc7\u8fd9\u4e9b\u89c4\u5219\u94fe\uff0c\u5c06\u8bf7\u6c42\u8f6c\u53d1\u5230\u76f8\u5e94\u7684Pod\u6216\u8005Service\u4e0a\u3002 \u56e0\u6b64\uff0c kube-proxy \u548ciptables\u662f\u7d27\u5bc6\u76f8\u5173\u7684\u4e24\u4e2a\u7ec4\u4ef6\uff0c\u901a\u8fc7iptables\u89c4\u5219\u6765\u5b9e\u73b0Service\u548cPod\u4e4b\u95f4\u7684\u8f6c\u53d1\u548c\u4ee3\u7406\u3002\u8fd9\u79cd\u5b9e\u73b0\u65b9\u5f0f\u5177\u6709\u53ef\u6269\u5c55\u6027\u548c\u9ad8\u53ef\u7528\u6027\uff0c\u540c\u65f6\u4e5f\u63d0\u4f9b\u4e86\u4e00\u79cd\u7075\u6d3b\u7684\u7f51\u7edc\u6a21\u578b\uff0c\u53ef\u4ee5\u65b9\u4fbf\u5730\u5b9e\u73b0\u670d\u52a1\u53d1\u73b0\u3001\u8d1f\u8f7d\u5747\u8861\u7b49\u529f\u80fd\u3002 sudo kubeadm init \\ --dry-run \\ --pod-network-cidr = 10 .244.0.0/16 \\ --service-cidr = 192 .244.0.0/16 \\ --image-repository = registry.aliyuncs.com/google_containers \\ --kubernetes-version = v1.24.0 sudo kubeadm init \\ --pod-network-cidr = 10 .244.0.0/16 \\ --service-cidr = 192 .244.0.0/16 \\ --image-repository = registry.aliyuncs.com/google_containers \\ --kubernetes-version = v1.24.0","title":"kubeadm\u521d\u59cb\u5316"},{"location":"k8s/cka_cn/installation/multiple-local/#kubeconfig","text":"\u7ed9\u5f53\u524d\u5b89\u88c5\u7528\u6237\u914d\u7f6e kubeconfig \u6587\u4ef6\uff08\u5f53\u524d\u4f8b\u5b50\u662f\u7528\u6237 vagrant \uff09\u3002 mkdir -p $HOME /.kube sudo cp -i /etc/kubernetes/admin.conf $HOME /.kube/config sudo chown $( id -u ) : $( id -g ) $HOME /.kube/config Kubernetes \u63d0\u4f9b\u4e86\u4e00\u4e2a\u547d\u4ee4\u884c\u5de5\u5177 kubectl \uff0c\u7528\u4e8e\u4f7f\u7528 Kubernetes API \u4e0e Kubernetes \u96c6\u7fa4\u7684\u63a7\u5236\u5e73\u9762\u8fdb\u884c\u901a\u4fe1\u3002 kubectl \u63a7\u5236 Kubernetes cluster manager \uff08\u96c6\u7fa4\u7ba1\u7406\u5668\uff09\u3002 \u5bf9\u4e8e\u914d\u7f6e\uff0ckubectl \u5728 $HOME/.kube \u76ee\u5f55\u4e2d\u67e5\u627e\u4e00\u4e2a\u540d\u4e3a config \u7684\u6587\u4ef6\uff0c\u8be5\u6587\u4ef6\u662f\u7531 kubeadm init \u751f\u6210\u7684\u6587\u4ef6 /etc/kubernetes/admin.conf \u7684\u526f\u672c\u3002 \u6211\u4eec\u53ef\u4ee5\u901a\u8fc7\u8bbe\u7f6e KUBECONFIG \u73af\u5883\u53d8\u91cf\u6216\u8bbe\u7f6e --kubeconfig flag \u6807\u5fd7\u6765\u6307\u5b9a\u5176\u4ed6 kubeconfig \u6587\u4ef6\u3002\u5982\u679c KUBECONFIG \u73af\u5883\u53d8\u91cf\u4e0d\u5b58\u5728\uff0ckubectl \u5c06\u4f7f\u7528\u9ed8\u8ba4\u7684 kubeconfig \u6587\u4ef6 $HOME/.kube/config \u3002 kubeconfig \u6587\u4ef6\u4e2d\u7684 context\uff08\u4e0a\u4e0b\u6587\uff09 \u5143\u7d20\u7528\u4e8e\u5c06\u8bbf\u95ee\u53c2\u6570\u5206\u7ec4\u5230\u4e00\u4e2a\u65b9\u4fbf\u7684\u540d\u79f0\u4e0b\u3002\u6bcf\u4e2a\u4e0a\u4e0b\u6587\u90fd\u6709\u4e09\u4e2a\u53c2\u6570\uff1a\u96c6\u7fa4\u3001\u547d\u540d\u7a7a\u95f4\u548c\u7528\u6237\u3002\u9ed8\u8ba4\u60c5\u51b5\u4e0b\uff0ckubectl \u547d\u4ee4\u884c\u5de5\u5177\u4f7f\u7528\u5f53\u524d\u4e0a\u4e0b\u6587\u4e2d\u7684\u53c2\u6570\u4e0e\u96c6\u7fa4\u901a\u4fe1\u3002 \u6587\u4ef6 .kube/config \u7684\u4f8b\u5b50\uff1a apiVersion : v1 clusters : - cluster : certificate-authority-data : server : https://:6443 name : contexts : - context : cluster : namespace : user : name : @ current-context : kind : Config preferences : {} users : - name : user : client-certificate-data : client-key-data : \u8bfb\u53d6\u5f53\u524d\u4e0a\u4e0b\u6587\uff1a kubectl config get-contexts \u8fd0\u884c\u7ed3\u679c\uff1a CURRENT NAME CLUSTER AUTHINFO NAMESPACE * kubernetes-admin@kubernetes kubernetes kubernetes-admin","title":"kubeconfig\u6587\u4ef6"},{"location":"k8s/cka_cn/installation/multiple-local/#calico","text":"\u53c2\u8003\u5b89\u88c5\u6307\u5bfc End-to-end Calico installation \u3002 \u5feb\u901f\u5b89\u88c5\u624b\u518c QuickStart \u5b89\u88c5 Calico\uff1a kubectl create -f https://raw.githubusercontent.com/projectcalico/calico/v3.25.1/manifests/tigera-operator.yaml \u8fd0\u884c\u7ed3\u679c\uff1a namespace/tigera-operator created customresourcedefinition.apiextensions.k8s.io/bgpconfigurations.crd.projectcalico.org created customresourcedefinition.apiextensions.k8s.io/bgppeers.crd.projectcalico.org created customresourcedefinition.apiextensions.k8s.io/blockaffinities.crd.projectcalico.org created customresourcedefinition.apiextensions.k8s.io/caliconodestatuses.crd.projectcalico.org created customresourcedefinition.apiextensions.k8s.io/clusterinformations.crd.projectcalico.org created customresourcedefinition.apiextensions.k8s.io/felixconfigurations.crd.projectcalico.org created customresourcedefinition.apiextensions.k8s.io/globalnetworkpolicies.crd.projectcalico.org created customresourcedefinition.apiextensions.k8s.io/globalnetworksets.crd.projectcalico.org created customresourcedefinition.apiextensions.k8s.io/hostendpoints.crd.projectcalico.org created customresourcedefinition.apiextensions.k8s.io/ipamblocks.crd.projectcalico.org created customresourcedefinition.apiextensions.k8s.io/ipamconfigs.crd.projectcalico.org created customresourcedefinition.apiextensions.k8s.io/ipamhandles.crd.projectcalico.org created customresourcedefinition.apiextensions.k8s.io/ippools.crd.projectcalico.org created customresourcedefinition.apiextensions.k8s.io/ipreservations.crd.projectcalico.org created customresourcedefinition.apiextensions.k8s.io/kubecontrollersconfigurations.crd.projectcalico.org created customresourcedefinition.apiextensions.k8s.io/networkpolicies.crd.projectcalico.org created customresourcedefinition.apiextensions.k8s.io/networksets.crd.projectcalico.org created customresourcedefinition.apiextensions.k8s.io/apiservers.operator.tigera.io created customresourcedefinition.apiextensions.k8s.io/imagesets.operator.tigera.io created customresourcedefinition.apiextensions.k8s.io/installations.operator.tigera.io created customresourcedefinition.apiextensions.k8s.io/tigerastatuses.operator.tigera.io created serviceaccount/tigera-operator created clusterrole.rbac.authorization.k8s.io/tigera-operator created clusterrolebinding.rbac.authorization.k8s.io/tigera-operator created deployment.apps/tigera-operator created kubectl apply -f https://raw.githubusercontent.com/projectcalico/calico/v3.25.1/manifests/calicoctl.yaml \u8fd0\u884c\u7ed3\u679c\uff1a serviceaccount/calicoctl created pod/calicoctl created clusterrole.rbac.authorization.k8s.io/calicoctl created clusterrolebinding.rbac.authorization.k8s.io/calicoctl created \u9a8c\u8bc1Calico\u7684\u72b6\u6001\u3002Calico\u7684\u521d\u59cb\u5316\u8fc7\u7a0b\u53ef\u80fd\u9700\u8981\u51e0\u5206\u949f\u65f6\u95f4\u5b8c\u6210\u3002 kubectl get pod -n kube-system | grep calico \u8fd0\u884c\u7ed3\u679c\uff1a calico-kube-controllers-555bc4b957-l8bn2 0/1 Pending 0 28s calico-node-255pc 0/1 Init:1/3 0 29s calico-node-7tmnb 0/1 Init:1/3 0 29s calico-node-w8nvl 0/1 Init:1/3 0 29s \u9a8c\u8bc1\u7f51\u7edc\u72b6\u6001\u3002 sudo nerdctl network ls \u8fd0\u884c\u7ed3\u679c\uff1a NETWORK ID NAME FILE k8s-pod-network /etc/cni/net.d/10-calico.conflist 17f29b073143 bridge /etc/cni/net.d/nerdctl-bridge.conflist host none","title":"\u5b89\u88c5Calico"},{"location":"k8s/cka_cn/installation/multiple-local/#_4","text":"\u4f7f\u7528 kubeadm token \u6765\u751f\u6210\u52a0\u5165\u96c6\u7fa4\u7684\u4ee4\u724c\uff08token\uff09\u548c\u54c8\u897f\u503c\uff08hash value\uff09\u3002 kubeadm token create --print-join-command \u547d\u4ee4\u7528\u6cd5\uff1a sudo kubeadm join :6443 --token --discovery-token-ca-cert-hash < hash key generated by kubeadm init> \u8fd0\u884c\u7ed3\u679c\uff1a [preflight] Running pre-flight checks [WARNING SystemVerification]: missing optional cgroups: blkio [preflight] Reading configuration from the cluster... [preflight] FYI: You can look at this config file with 'kubectl -n kube-system get cm kubeadm-config -o yaml' [kubelet-start] Writing kubelet configuration to file \"/var/lib/kubelet/config.yaml\" [kubelet-start] Writing kubelet environment file with flags to file \"/var/lib/kubelet/kubeadm-flags.env\" [kubelet-start] Starting the kubelet [kubelet-start] Waiting for the kubelet to perform the TLS Bootstrap... This node has joined the cluster: * Certificate signing request was sent to apiserver and a response was received. * The Kubelet was informed of the new secure connection details. Run 'kubectl get nodes' on the control-plane to see this node join the cluster.","title":"\u914d\u7f6e\u5de5\u4f5c\u8282\u70b9"},{"location":"k8s/cka_cn/installation/multiple-local/#_5","text":"\u67e5\u770b Kubernetes \u96c6\u7fa4\u7684\u4fe1\u606f\uff0c\u5305\u62ec\u96c6\u7fa4 API Server \u7684\u5730\u5740\u3001Kubernetes DNS \u670d\u52a1\u7684\u5730\u5740\u7b49\u3002 kubectl cluster-info \u8fd0\u884c\u7ed3\u679c\uff1a bKubernetes control plane is running at https://11.0.1.129:6443 CoreDNS is running at https://11.0.1.129:6443/api/v1/namespaces/kube-system/services/kube-dns:dns/proxy To further debug and diagnose cluster problems, use 'kubectl cluster-info dump'. \u5217\u51fa\u96c6\u7fa4\u4e2d\u6240\u6709\u8282\u70b9\u7684\u8be6\u7ec6\u4fe1\u606f\uff0c\u5305\u62ec\u8282\u70b9\u540d\u79f0\u3001\u8282\u70b9 IP\u3001\u8282\u70b9\u6807\u7b7e\u3001\u8282\u70b9\u72b6\u6001\u7b49\u3002 kubectl get nodes -owide \u5217\u51fa Kubernetes \u96c6\u7fa4\u4e2d\u6240\u6709 Namespace \u4e0b\u7684 Pod\u3002 kubectl get pod -A","title":"\u68c0\u67e5\u96c6\u7fa4\u72b6\u6001"},{"location":"k8s/cka_cn/installation/multiple-local/#_6","text":"","title":"\u66f4\u65b0\u5b89\u88c5"},{"location":"k8s/cka_cn/installation/multiple-local/#bash","text":"\u5728\u6bcf\u4e2a\u8282\u70b9\u4e0a\u914d\u7f6eBash\u81ea\u52a8\u8865\u5168\u529f\u80fd\u3002 \u53c2\u8003 \u6307\u5bfc \u8bbe\u7f6e kubectl \u81ea\u52a8\u8865\u5168\u529f\u80fdauto-completion \u3002 apt install -y bash-completion source /usr/share/bash-completion/bash_completion source < ( kubectl completion bash ) echo \"source <(kubectl completion bash)\" >> ~/.bashrc source ~/.bashrc","title":"Bash\u81ea\u52a8\u8865\u5168"},{"location":"k8s/cka_cn/installation/multiple-local/#_7","text":"\u5982\u679c\u6211\u4eec\u4e3a kubectl \u8bbe\u7f6e\u4e00\u4e2a\u522b\u540d\uff0c\u6211\u4eec\u53ef\u4ee5\u901a\u8fc7\u4e00\u4e9b\u65b9\u6cd5\u6765\u6269\u5c55 shell \u81ea\u52a8\u8865\u5168\u529f\u80fd\uff0c\u4f7f\u5176\u80fd\u591f\u4e0e\u8be5\u522b\u540d\u4e00\u8d77\u4f7f\u7528\u3002 \u4e00\u79cd\u65b9\u6cd5\u662f\u5728 Bash shell \u914d\u7f6e\u6587\u4ef6\uff08\u5982 .bashrc \u6216 .bash_profile\uff09\u4e2d\u8bbe\u7f6e\u522b\u540d\uff0c\u5e76\u4e3a\u8be5\u522b\u540d\u6307\u5b9a kubectl \u7684\u5b8c\u6574\u8def\u5f84\u3002\u4f8b\u5982\uff0c\u53ef\u4ee5\u5728 .bashrc \u6587\u4ef6\u4e2d\u6dfb\u52a0\u4ee5\u4e0b\u5185\u5bb9\uff1a alias k = 'path/to/kubectl' \u7136\u540e\uff0c\u53ef\u4ee5\u4f7f\u7528\u4ee5\u4e0b\u547d\u4ee4\u91cd\u65b0\u52a0\u8f7d .bashrc \u6587\u4ef6\uff1a source ~/.bashrc \u63a5\u4e0b\u6765\uff0c\u53ef\u4ee5\u4f7f\u7528 k \u547d\u4ee4\u6765\u4ee3\u66ff kubectl \u547d\u4ee4\uff0c\u5e76\u5728\u5176\u540e\u9762\u6dfb\u52a0\u76f8\u5e94\u7684\u53c2\u6570\u548c\u9009\u9879\u3002\u5f53\u4f7f\u7528\u81ea\u52a8\u8865\u5168\u529f\u80fd\u65f6\uff0cBash shell \u4f1a\u81ea\u52a8\u5c06 k \u522b\u540d\u8f6c\u6362\u4e3a kubectl \u7684\u5b8c\u6574\u8def\u5f84\uff0c\u5e76\u5bf9\u5176\u8fdb\u884c\u81ea\u52a8\u8865\u5168\u3002 \u53e6\u4e00\u79cd\u65b9\u6cd5\u662f\u4f7f\u7528 Bash shell \u5185\u7f6e\u7684 complete \u51fd\u6570\u6765\u4e3a\u522b\u540d\u8bbe\u7f6e\u81ea\u52a8\u8865\u5168\u529f\u80fd\u3002\u4f8b\u5982\uff0c\u53ef\u4ee5\u5728 .bashrc \u6587\u4ef6\u4e2d\u6dfb\u52a0\u4ee5\u4e0b\u5185\u5bb9\uff1a echo 'alias k=kubectl' >>~/.bashrc echo 'complete -o default -F __start_kubectl k' >>~/.bashrc \u8fd9\u5c06\u4e3a\u522b\u540d k \u8bbe\u7f6e\u81ea\u52a8\u8865\u5168\u529f\u80fd\uff0c\u5e76\u5c06\u5176\u4e0e kubectl \u7684\u81ea\u52a8\u8865\u5168\u51fd\u6570 __start_kubectl \u5173\u8054\u8d77\u6765\u3002\u8fd9\u6837\uff0c\u5f53\u7528\u6237\u5728 k \u547d\u4ee4\u540e\u8f93\u5165Tab\u952e\u65f6\uff0cBash shell \u4f1a\u81ea\u52a8\u8c03\u7528 __start_kubectl \u51fd\u6570\uff0c\u5e76\u4e3a\u7528\u6237\u63d0\u4f9b\u76f8\u5e94\u7684\u81ea\u52a8\u8865\u5168\u5efa\u8bae\u3002","title":"\u522b\u540d"},{"location":"k8s/cka_cn/installation/multiple-local/#context","text":"\u67e5\u770b\u5f53\u524d\u7684 context \u5217\u8868\uff1a kubectl config get-contexts \u8fd9\u4e2a\u547d\u4ee4\u4f1a\u5217\u51fa\u6240\u6709\u53ef\u7528\u7684 context \u5217\u8868\uff0c\u5e76\u6807\u8bb0\u51fa\u5f53\u524d\u6b63\u5728\u4f7f\u7528\u7684 context\u3002 \u7c7b\u4f3c\u4e0b\u9762\u7ed3\u679c\uff1a kubernetes-admin@kubernetes \u662fContext\u540d\u3002 kubernetes \u662f\u96c6\u7fa4\u540d\u3002 kubernetes-admin \u662f\u7528\u6237\u540d\u3002 \u5f53\u524d\u4f8b\u5b50\u4e2d\u6ca1\u6709\u6307\u5b9a\u540d\u79f0\u7a7a\u95f4\u3002 CURRENT NAME CLUSTER AUTHINFO NAMESPACE * kubernetes-admin@kubernetes kubernetes kubernetes-admin \u66f4\u65b0context\u3002\u4f8b\u5982\uff0c\u66f4\u65b0context\u7684\u9ed8\u8ba4\u540d\u79f0\u7a7a\u95f4\u7b49\u3002 # Usage: kubectl config set-context --cluster = --namespace = --user = # Set default namespace kubectl config set-context kubernetes-admin@kubernetes --cluster = kubernetes --namespace = default --user = kubernetes-admin \u5728\u4e0d\u540c\u7684context\u4e4b\u95f4\u5207\u6362\u3002 # Usage: kubectl config use-context # Switch to new context kubectl config use-context kubernetes-admin@kubernetes \u53c2\u8003\u8d44\u6599\uff1a * kubectl * commandline","title":"\u66f4\u65b0\u9ed8\u8ba4Context"},{"location":"k8s/cka_cn/installation/multiple-local/#helm","text":"Helm \u662f Kubernetes \u7684\u5305\u7ba1\u7406\u5de5\u5177\uff0c\u5b83\u4e0d\u968f Kubernetes \u4e00\u8d77\u63d0\u4f9b\u3002 Helm \u6709\u4e09\u4e2a\u6838\u5fc3\u6982\u5ff5\uff1a Chart\uff08\u56fe\u8868\uff09\u662f Helm \u7684\u8f6f\u4ef6\u5305\uff0c\u5b83\u5305\u542b\u4e86\u5728 Kubernetes \u96c6\u7fa4\u4e2d\u8fd0\u884c\u5e94\u7528\u7a0b\u5e8f\u3001\u5de5\u5177\u6216\u670d\u52a1\u6240\u9700\u7684\u6240\u6709\u8d44\u6e90\u5b9a\u4e49\u3002\u53ef\u4ee5\u5c06\u5176\u89c6\u4e3a Kubernetes \u7684 Homebrew \u516c\u5f0f\u3001Apt dpkg \u6216 Yum RPM \u6587\u4ef6\u7b49\u7b49\u3002 Repository\uff08\u4ed3\u5e93\uff09\u662f\u56fe\u8868\u53ef\u4ee5\u88ab\u6536\u96c6\u548c\u5171\u4eab\u7684\u5730\u65b9\uff0c\u7c7b\u4f3c\u4e8e Perl \u7684 CPAN \u5b58\u50a8\u5e93\u6216 Fedora \u7684\u8f6f\u4ef6\u5305\u6570\u636e\u5e93\uff0c\u4f46\u7528\u4e8e Kubernetes \u8f6f\u4ef6\u5305\u3002 Release\uff08\u53d1\u5e03\uff09\u662f\u5728 Kubernetes \u96c6\u7fa4\u4e2d\u8fd0\u884c\u7684\u56fe\u8868\u5b9e\u4f8b\u3002\u4e00\u4e2a\u56fe\u8868\u901a\u5e38\u53ef\u4ee5\u5728\u540c\u4e00\u96c6\u7fa4\u4e2d\u5b89\u88c5\u591a\u6b21\uff0c\u5e76\u4e14\u6bcf\u6b21\u5b89\u88c5\u90fd\u4f1a\u521b\u5efa\u4e00\u4e2a\u65b0\u7684\u53d1\u5e03\u3002\u4ee5 MySQL \u56fe\u8868\u4e3a\u4f8b\uff0c\u5982\u679c\u60f3\u8981\u5728\u96c6\u7fa4\u4e2d\u8fd0\u884c\u4e24\u4e2a\u6570\u636e\u5e93\uff0c\u5219\u53ef\u4ee5\u5b89\u88c5\u8be5\u56fe\u8868\u4e24\u6b21\uff0c\u6bcf\u6b21\u5b89\u88c5\u90fd\u4f1a\u521b\u5efa\u4e00\u4e2a\u65b0\u7684\u53d1\u5e03\uff0c\u6bcf\u4e2a\u53d1\u5e03\u90fd\u6709\u81ea\u5df1\u7684\u53d1\u5e03\u540d\u79f0\u3002 \u53c2\u8003\u6587\u6863\uff1a installation guide binary release source code . Helm\u5ba2\u6237\u7aef\u5b89\u88c5\uff1a curl -fsSL -o get_helm.sh https://raw.githubusercontent.com/helm/helm/main/scripts/get-helm-3 chmod 700 get_helm.sh ./get_helm.sh \u8fd0\u884c\u7ed3\u679c\uff1a Downloading https://get.helm.sh/helm-v3.9.1-linux-amd64.tar.gz Verifying checksum... Done. Preparing to install helm into /usr/local/bin helm installed into /usr/local/bin/helm \u63d0\u793a\uff1a * helm init \u5728Helm 3\u4e2d\u5df2\u53d6\u6d88\uff0c\u4e14Tiller\u4e5f\u4e00\u540c\u53d6\u6d88\u3002\u4eca\u540e\u5728\u96c6\u7fa4\u4e2d\u4f7f\u7528Helm\u65f6\u4e0d\u518d\u9700\u8981\u5b89\u88c5Tiller\u3002 * helm search \u53ef\u4ee5\u7528\u6765\u641c\u7d22\u4e24\u79cd\u4e0d\u540c\u7c7b\u578b\u7684\u8d44\u6e90\uff1a * helm search hub \u5728 Artifact Hub \u4e2d\u641c\u7d22\uff0c\u8fd9\u4e2ahub\u91cc\u5217\u51fa\u6765\u81ea\u6570\u5341\u4e2a\u4e0d\u540c\u4ed3\u5e93\u7684 Helm Chart\u3002 * helm search repo \u547d\u4ee4\u7528\u4e8e\u641c\u7d22\u5df2\u6dfb\u52a0\u5230\u672c\u5730 Helm \u5ba2\u6237\u7aef\u7684\u4ed3\u5e93\uff08\u4f7f\u7528 helm repo add \u547d\u4ee4\uff09\u3002\u6b64\u641c\u7d22\u662f\u5728\u672c\u5730\u6570\u636e\u4e0a\u8fdb\u884c\u7684\uff0c\u4e0d\u9700\u8981\u516c\u5171\u7f51\u7edc\u8fde\u63a5\u3002 \u53c2\u8003\u8d44\u6599\uff1a Helming development","title":"\u5b89\u88c5Helm"},{"location":"k8s/cka_cn/installation/multiple-local/#_8","text":"\u6ce8\u610f\uff1a\u4e0b\u9762\u7684\u64cd\u4f5c\u4f1a\u91cd\u7f6e\u5f53\u524d\u96c6\u7fa4\uff08\u5220\u9664\u96c6\u7fa4\uff09\u3002 \u5220\u9664\u96c6\u7fa4\u4e2d\u6240\u6709\u8282\u70b9\u3002 kubeadm reset \u6e05\u9664 iptables \u4e2d\u5df2\u5b9a\u4e49\u7684\u89c4\u5219\u3002 iptables -F && iptables -t nat -F && iptables -t mangle -F && iptables -X \u6e05\u9664 IPVS \u4e2d\u5b9a\u4e49\u7684\u89c4\u5219\uff08\u5982\u679c\u4f7f\u7528 IPVS \uff09\u3002 ipvsadm --clear","title":"\u91cd\u7f6e\u96c6\u7fa4"},{"location":"k8s/cka_cn/installation/single-local/","text":"CKA\u81ea\u5b66\u7b14\u8bb01:\u5355\u8282\u70b9\u865a\u62df\u673a\u5b89\u88c5Kubernetes \u00b6 \u6458\u8981 \u00b6 \u5728\u672c\u5730Windows\u73af\u5883\u4e2d\uff0c\u901a\u8fc7VMWare\u5b89\u88c5Ubuntu\u865a\u62df\u673a\u3002\u5728Ubuntu\u865a\u62df\u673a\u4e2d\u5b89\u88c5\u57fa\u4e8eDocker\u7684Kubernetes\u7cfb\u7edf\u3002\u5728\u8be5\u865a\u62df\u673a\u4e2d\u540c\u65f6\u914d\u7f6e\u4e3b\u8282\u70b9Master\u548c\u5de5\u4f5c\u8282\u70b9Worker\u3002 \u672c\u5730\u865a\u62df\u673a\u8bbe\u7f6e \u00b6 VMWare\u865a\u62df\u673a\u8bbe\u7f6e\u3002 VMnet1: host-only\u6a21\u5f0f, \u7f51\u7edcsubnet: 192.168.150.0/24 VMnet8: NAT\u6a21\u5f0f, \u7f51\u7edcsubnet: 11.0.1.0/24 \u901a\u8fc7VMWare\u521b\u5efa\u5ba2\u6237\u673a\u3002 \u5185\u5b58\uff1a4 GB CPU\uff1a2 CPUs with 2 Cores \u64cd\u4f5c\u7cfb\u7edf\uff1aUbuntu Server 22.04 \u7f51\u7edc\uff1aNAT Kubernetes\u8fd0\u884c\u5728Docker\u4e0a\u3002 Ubuntu\u9884\u914d\u7f6e \u00b6 \u521b\u5efa\u7528\u6237 vagrant \u3002 sudo adduser vagrant sudo usermod -aG adm,sudo,syslog,cdrom,dip,plugdev,lxd vagrant sudo passwd vagrant \u8bbe\u7f6e\u7528\u6237 root \u7684\u5bc6\u7801\u3002 sudo passwd root \u66f4\u65b0\u5ba2\u6237\u673a\u7684\u4e3b\u673a\u540d\uff0c\u8fd9\u91cc\u662f ubusvr \u3002 sudo hostnamectl set-hostname ubusvr sudo hostnamectl set-hostname ubusvr --pretty \u9a8c\u8bc1\u4e3b\u673a\u540d\u662f\u5426\u5df2\u6210\u529f\u66f4\u65b0\u4e3a ubusvr \u3002 cat /etc/machine-info cat /etc/hostname \u9a8c\u8bc1\u4e3b\u673aIP\u5730\u5740 127.0.1.1 \u5df2\u7ecf\u914d\u7f6e\u7ed9\u5f53\u524d\u865a\u62df\u673a ubusvr \u3002 cat /etc/hosts 127.0.0.1 localhost 127.0.1.1 ubusrv # The following lines are desirable for IPv6 capable hosts ::1 ip6-localhost ip6-loopback fe00::0 ip6-localnet ff00::0 ip6-mcastprefix ff02::1 ip6-allnodes ff02::2 ip6-allrouters \u8bbe\u7f6e\u5ba2\u6237\u673a\u4e3a\u56fa\u5b9aIP\u5730\u5740\uff0c\u8fd9\u91cc\u662f 11.0.1.136 \u3002 sudo vi 00 -installer-config.yaml network : ethernets : ens33 : dhcp4 : false addresses : - 11.0.1.136/24 nameservers : addresses : - 11.0.1.2 routes : - to : default via : 11.0.1.2 version : 2 sudo netplan apply \u7981\u7528\u4ea4\u6362\u5206\u533aswap\u3002 sudo swapoff -a sudo ufw disable sudo ufw status verbose \u6ce8\u91ca\u6389\u6587\u4ef6 /etc/fstab \u7684\u6700\u540e\u4e00\u884c\uff0c\u5373\u7981\u7528\u4ea4\u6362\u5206\u533a\u3002\u9700\u8981\u91cd\u542f\u5ba2\u6237\u673a\u4f7f\u4e4b\u751f\u6548\u3002 /dev/disk/by-uuid/df370d2a-83e5-4895-8c7f-633f2545e3fe / ext4 defaults 0 1 # /swap.img none swap sw 0 0 \u8bbe\u7f6e\u5ba2\u6237\u673a\u65f6\u533a\u3002 sudo ln -sf /usr/share/zoneinfo/Asia/Shanghai /etc/localtime sudo echo 'LANG=\"en_US.UTF-8\"' >> /etc/profile source /etc/profile \u6267\u884c\u547d\u4ee4 ll /etc/localtime \u9a8c\u8bc1\u65f6\u533a\u662f\u5426\u5df2\u6b63\u786e\u8bbe\u7f6e\u5e76\u751f\u6548\u3002 lrwxrwxrwx 1 root root 33 Jul 15 22:00 /etc/localtime -> /usr/share/zoneinfo/Asia/Shanghai \u5ba2\u6237\u673a\u5185\u6838\u8bbe\u7f6e\u3002 cat < /dev/null sudo apt-get update sudo apt-get install docker-ce docker-ce-cli containerd.io docker-compose-plugin sudo systemctl status docker.service sudo systemctl status containerd.service sudo groupadd docker sudo usermod -aG docker $USER \u8bbe\u7f6eContainerd\u3002 containerd config default | sudo tee /etc/containerd/config.toml sudo vi /etc/containerd/config.toml sudo systemctl restart containerd sudo systemctl status containerd \u5b89\u88c5Kubernetes \u00b6 \u5b89\u88c5kubeadm sudo apt-get update && sudo apt-get install -y apt-transport-https ca-certificates curl curl https://mirrors.aliyun.com/kubernetes/apt/doc/apt-key.gpg | sudo apt-key add - cat << EOF > /etc/apt/sources.list.d/kubernetes.list deb https://mirrors.aliyun.com/kubernetes/apt/ kubernetes-xenial main EOF sudo apt-get update sudo apt-get install ebtables sudo apt-get install libxtables12 sudo apt-get upgrade iptables apt policy kubeadm sudo apt-get -y install kubelet = 1 .23.8-00 kubeadm = 1 .23.8-00 kubectl = 1 .23.8-00 --allow-downgrades \u914d\u7f6e\u4e3b\u8282\u70b9\uff08Master\uff09\u3002 sudo kubeadm config print init-defaults \u5b89\u88c5\u9884\u6f14Dry run\u3002 sudo kubeadm init --dry-run --pod-network-cidr = 10 .244.0.0/16 --image-repository = registry.aliyuncs.com/google_containers --kubernetes-version = v1.23.8 \u5b89\u88c5\u3002 sudo kubeadm init --pod-network-cidr = 10 .244.0.0/16 --image-repository = registry.aliyuncs.com/google_containers --kubernetes-version = v1.23.8 mkdir -p $HOME /.kube sudo cp -i /etc/kubernetes/admin.conf $HOME /.kube/config sudo chown $( id -u ) : $( id -g ) $HOME /.kube/config \u5b89\u88c5Flannel\u3002\u5982\u679c\u9700\u8981\u8003\u8651\u7f51\u7edc\u7b56\u7565\uff0c\u5219\u5b89\u88c5Calico\u3002\u53c2\u7167 \u963f\u91cc\u4e91ECS \u4e2dInstall Calico or Flannel\u90e8\u5206\u3002 kubectl apply -f https://raw.githubusercontent.com/coreos/flannel/master/Documentation/kube-flannel.yml \u914d\u7f6e\u5de5\u4f5c\u8282\u70b9\uff08Worker Node\uff09\u3002 kubeadm join :6443 --token --discovery-token-ca-cert-hash < hash key generated by kubeadm init> kubeadm join 11 .0.1.136:6443 --token 6zqh1u.8b4afzc2ov4e7iuj \\ --discovery-token-ca-cert-hash sha256:815fdb9dd9e3ae0af07ffaf6c216964388098b150ef01ee3ae900c261a429d24 \u5728\u6240\u6709\u8282\u70b9\u4e0a\u914d\u7f6ebash\u81ea\u52a8\u8865\u5168\u529f\u80fd\u3002 sudo apt install -y bash-completion source /usr/share/bash-completion/bash_completion source < ( kubectl completion bash ) echo \"source <(kubectl completion bash)\" >> ~/.bashrc \u5728\u6240\u6709\u8282\u70b9\u4e0a\u5b9a\u4e49\u522b\u540d\uff08alias\uff09\u3002 echo 'alias k=kubectl' >>~/.bashrc echo 'complete -o default -F __start_kubectl k' >>~/.bashrc \u67e5\u770b\u5f53\u524d\u96c6\u7fa4\u72b6\u6001\u3002 kubectl cluster-info kubectl get nodes -owide kubectl get pod -A \u5b89\u88c5Helm \u00b6 \u5b89\u88c5Helm\u5ba2\u6237\u7aef\u3002 curl -fsSL -o get_helm.sh https://raw.githubusercontent.com/helm/helm/main/scripts/get-helm-3 chmod 700 get_helm.sh ./get_helm.sh \u8f93\u51fa\u7ed3\u679c\uff1a Downloading https://get.helm.sh/helm-v3.9.0-linux-amd64.tar.gz Verifying checksum... Done. Preparing to install helm into /usr/local/bin helm installed into /usr/local/bin/helm \u91cd\u7f6e\u96c6\u7fa4 \u00b6 \u6ce8\u610f\uff1a\u4e0b\u9762\u7684\u64cd\u4f5c\u4f1a\u91cd\u7f6e\u5f53\u524d\u96c6\u7fa4\uff08\u5220\u9664\u96c6\u7fa4\uff09\u3002 \u5220\u9664\u96c6\u7fa4\u4e2d\u6240\u6709\u8282\u70b9\u3002 kubeadm reset \u6e05\u9664 iptables \u4e2d\u5df2\u5b9a\u4e49\u7684\u89c4\u5219\u3002 iptables -F && iptables -t nat -F && iptables -t mangle -F && iptables -X \u6e05\u9664 IPVS \u4e2d\u5b9a\u4e49\u7684\u89c4\u5219\uff08\u5982\u679c\u4f7f\u7528 IPVS \uff09\u3002 ipvsadm --clear","title":"\u5355\u8282\u70b9\u865a\u62df\u673a\u5b89\u88c5Kubernetes"},{"location":"k8s/cka_cn/installation/single-local/#cka1kubernetes","text":"","title":"CKA\u81ea\u5b66\u7b14\u8bb01:\u5355\u8282\u70b9\u865a\u62df\u673a\u5b89\u88c5Kubernetes"},{"location":"k8s/cka_cn/installation/single-local/#_1","text":"\u5728\u672c\u5730Windows\u73af\u5883\u4e2d\uff0c\u901a\u8fc7VMWare\u5b89\u88c5Ubuntu\u865a\u62df\u673a\u3002\u5728Ubuntu\u865a\u62df\u673a\u4e2d\u5b89\u88c5\u57fa\u4e8eDocker\u7684Kubernetes\u7cfb\u7edf\u3002\u5728\u8be5\u865a\u62df\u673a\u4e2d\u540c\u65f6\u914d\u7f6e\u4e3b\u8282\u70b9Master\u548c\u5de5\u4f5c\u8282\u70b9Worker\u3002","title":"\u6458\u8981"},{"location":"k8s/cka_cn/installation/single-local/#_2","text":"VMWare\u865a\u62df\u673a\u8bbe\u7f6e\u3002 VMnet1: host-only\u6a21\u5f0f, \u7f51\u7edcsubnet: 192.168.150.0/24 VMnet8: NAT\u6a21\u5f0f, \u7f51\u7edcsubnet: 11.0.1.0/24 \u901a\u8fc7VMWare\u521b\u5efa\u5ba2\u6237\u673a\u3002 \u5185\u5b58\uff1a4 GB CPU\uff1a2 CPUs with 2 Cores \u64cd\u4f5c\u7cfb\u7edf\uff1aUbuntu Server 22.04 \u7f51\u7edc\uff1aNAT Kubernetes\u8fd0\u884c\u5728Docker\u4e0a\u3002","title":"\u672c\u5730\u865a\u62df\u673a\u8bbe\u7f6e"},{"location":"k8s/cka_cn/installation/single-local/#ubuntu","text":"\u521b\u5efa\u7528\u6237 vagrant \u3002 sudo adduser vagrant sudo usermod -aG adm,sudo,syslog,cdrom,dip,plugdev,lxd vagrant sudo passwd vagrant \u8bbe\u7f6e\u7528\u6237 root \u7684\u5bc6\u7801\u3002 sudo passwd root \u66f4\u65b0\u5ba2\u6237\u673a\u7684\u4e3b\u673a\u540d\uff0c\u8fd9\u91cc\u662f ubusvr \u3002 sudo hostnamectl set-hostname ubusvr sudo hostnamectl set-hostname ubusvr --pretty \u9a8c\u8bc1\u4e3b\u673a\u540d\u662f\u5426\u5df2\u6210\u529f\u66f4\u65b0\u4e3a ubusvr \u3002 cat /etc/machine-info cat /etc/hostname \u9a8c\u8bc1\u4e3b\u673aIP\u5730\u5740 127.0.1.1 \u5df2\u7ecf\u914d\u7f6e\u7ed9\u5f53\u524d\u865a\u62df\u673a ubusvr \u3002 cat /etc/hosts 127.0.0.1 localhost 127.0.1.1 ubusrv # The following lines are desirable for IPv6 capable hosts ::1 ip6-localhost ip6-loopback fe00::0 ip6-localnet ff00::0 ip6-mcastprefix ff02::1 ip6-allnodes ff02::2 ip6-allrouters \u8bbe\u7f6e\u5ba2\u6237\u673a\u4e3a\u56fa\u5b9aIP\u5730\u5740\uff0c\u8fd9\u91cc\u662f 11.0.1.136 \u3002 sudo vi 00 -installer-config.yaml network : ethernets : ens33 : dhcp4 : false addresses : - 11.0.1.136/24 nameservers : addresses : - 11.0.1.2 routes : - to : default via : 11.0.1.2 version : 2 sudo netplan apply \u7981\u7528\u4ea4\u6362\u5206\u533aswap\u3002 sudo swapoff -a sudo ufw disable sudo ufw status verbose \u6ce8\u91ca\u6389\u6587\u4ef6 /etc/fstab \u7684\u6700\u540e\u4e00\u884c\uff0c\u5373\u7981\u7528\u4ea4\u6362\u5206\u533a\u3002\u9700\u8981\u91cd\u542f\u5ba2\u6237\u673a\u4f7f\u4e4b\u751f\u6548\u3002 /dev/disk/by-uuid/df370d2a-83e5-4895-8c7f-633f2545e3fe / ext4 defaults 0 1 # /swap.img none swap sw 0 0 \u8bbe\u7f6e\u5ba2\u6237\u673a\u65f6\u533a\u3002 sudo ln -sf /usr/share/zoneinfo/Asia/Shanghai /etc/localtime sudo echo 'LANG=\"en_US.UTF-8\"' >> /etc/profile source /etc/profile \u6267\u884c\u547d\u4ee4 ll /etc/localtime \u9a8c\u8bc1\u65f6\u533a\u662f\u5426\u5df2\u6b63\u786e\u8bbe\u7f6e\u5e76\u751f\u6548\u3002 lrwxrwxrwx 1 root root 33 Jul 15 22:00 /etc/localtime -> /usr/share/zoneinfo/Asia/Shanghai \u5ba2\u6237\u673a\u5185\u6838\u8bbe\u7f6e\u3002 cat < /dev/null sudo apt-get update sudo apt-get install docker-ce docker-ce-cli containerd.io docker-compose-plugin sudo systemctl status docker.service sudo systemctl status containerd.service sudo groupadd docker sudo usermod -aG docker $USER \u8bbe\u7f6eContainerd\u3002 containerd config default | sudo tee /etc/containerd/config.toml sudo vi /etc/containerd/config.toml sudo systemctl restart containerd sudo systemctl status containerd","title":"\u5b89\u88c5Docker"},{"location":"k8s/cka_cn/installation/single-local/#kubernetes","text":"\u5b89\u88c5kubeadm sudo apt-get update && sudo apt-get install -y apt-transport-https ca-certificates curl curl https://mirrors.aliyun.com/kubernetes/apt/doc/apt-key.gpg | sudo apt-key add - cat << EOF > /etc/apt/sources.list.d/kubernetes.list deb https://mirrors.aliyun.com/kubernetes/apt/ kubernetes-xenial main EOF sudo apt-get update sudo apt-get install ebtables sudo apt-get install libxtables12 sudo apt-get upgrade iptables apt policy kubeadm sudo apt-get -y install kubelet = 1 .23.8-00 kubeadm = 1 .23.8-00 kubectl = 1 .23.8-00 --allow-downgrades \u914d\u7f6e\u4e3b\u8282\u70b9\uff08Master\uff09\u3002 sudo kubeadm config print init-defaults \u5b89\u88c5\u9884\u6f14Dry run\u3002 sudo kubeadm init --dry-run --pod-network-cidr = 10 .244.0.0/16 --image-repository = registry.aliyuncs.com/google_containers --kubernetes-version = v1.23.8 \u5b89\u88c5\u3002 sudo kubeadm init --pod-network-cidr = 10 .244.0.0/16 --image-repository = registry.aliyuncs.com/google_containers --kubernetes-version = v1.23.8 mkdir -p $HOME /.kube sudo cp -i /etc/kubernetes/admin.conf $HOME /.kube/config sudo chown $( id -u ) : $( id -g ) $HOME /.kube/config \u5b89\u88c5Flannel\u3002\u5982\u679c\u9700\u8981\u8003\u8651\u7f51\u7edc\u7b56\u7565\uff0c\u5219\u5b89\u88c5Calico\u3002\u53c2\u7167 \u963f\u91cc\u4e91ECS \u4e2dInstall Calico or Flannel\u90e8\u5206\u3002 kubectl apply -f https://raw.githubusercontent.com/coreos/flannel/master/Documentation/kube-flannel.yml \u914d\u7f6e\u5de5\u4f5c\u8282\u70b9\uff08Worker Node\uff09\u3002 kubeadm join :6443 --token --discovery-token-ca-cert-hash < hash key generated by kubeadm init> kubeadm join 11 .0.1.136:6443 --token 6zqh1u.8b4afzc2ov4e7iuj \\ --discovery-token-ca-cert-hash sha256:815fdb9dd9e3ae0af07ffaf6c216964388098b150ef01ee3ae900c261a429d24 \u5728\u6240\u6709\u8282\u70b9\u4e0a\u914d\u7f6ebash\u81ea\u52a8\u8865\u5168\u529f\u80fd\u3002 sudo apt install -y bash-completion source /usr/share/bash-completion/bash_completion source < ( kubectl completion bash ) echo \"source <(kubectl completion bash)\" >> ~/.bashrc \u5728\u6240\u6709\u8282\u70b9\u4e0a\u5b9a\u4e49\u522b\u540d\uff08alias\uff09\u3002 echo 'alias k=kubectl' >>~/.bashrc echo 'complete -o default -F __start_kubectl k' >>~/.bashrc \u67e5\u770b\u5f53\u524d\u96c6\u7fa4\u72b6\u6001\u3002 kubectl cluster-info kubectl get nodes -owide kubectl get pod -A","title":"\u5b89\u88c5Kubernetes"},{"location":"k8s/cka_cn/installation/single-local/#helm","text":"\u5b89\u88c5Helm\u5ba2\u6237\u7aef\u3002 curl -fsSL -o get_helm.sh https://raw.githubusercontent.com/helm/helm/main/scripts/get-helm-3 chmod 700 get_helm.sh ./get_helm.sh \u8f93\u51fa\u7ed3\u679c\uff1a Downloading https://get.helm.sh/helm-v3.9.0-linux-amd64.tar.gz Verifying checksum... Done. Preparing to install helm into /usr/local/bin helm installed into /usr/local/bin/helm","title":"\u5b89\u88c5Helm"},{"location":"k8s/cka_cn/installation/single-local/#_3","text":"\u6ce8\u610f\uff1a\u4e0b\u9762\u7684\u64cd\u4f5c\u4f1a\u91cd\u7f6e\u5f53\u524d\u96c6\u7fa4\uff08\u5220\u9664\u96c6\u7fa4\uff09\u3002 \u5220\u9664\u96c6\u7fa4\u4e2d\u6240\u6709\u8282\u70b9\u3002 kubeadm reset \u6e05\u9664 iptables \u4e2d\u5df2\u5b9a\u4e49\u7684\u89c4\u5219\u3002 iptables -F && iptables -t nat -F && iptables -t mangle -F && iptables -X \u6e05\u9664 IPVS \u4e2d\u5b9a\u4e49\u7684\u89c4\u5219\uff08\u5982\u679c\u4f7f\u7528 IPVS \uff09\u3002 ipvsadm --clear","title":"\u91cd\u7f6e\u96c6\u7fa4"},{"location":"k8s/cka_en/foundamentals/basics/","text":"kubectl basics \u00b6 Scenario: get to know how to operate Kubernetes cluster using kubectl . via API via kubectl via Dashboard Demo: Check current kubeconfig file \u00b6 Use the kubectl config command to get current context of configuration file. echo $KUBECONFIG kubectl config view kubectl config get-contexts Get resource list \u00b6 Get a complete list of supported resources kubectl api-resources Get cluster status \u00b6 Kubernetes control plane is running at https://:6443 CoreDNS is running at https://:6443/api/v1/namespaces/kube-system/services/kube-dns:dns/proxy kubectl cluster-info kubectl cluster-info dump Display resources \u00b6 Use kubectl get --help to get examples of displaying one or many resources. Get health status of control plane. kubectl get componentstatuses kubectl get cs Result NAME STATUS MESSAGE ERROR etcd-0 Healthy {\"health\":\"true\",\"reason\":\"\"} scheduler Healthy ok controller-manager Healthy ok Get node status and details \u00b6 kubectl get nodes kubectl get nodes -o wide kubectl describe node cka001 Use command kubectl create --help to get examples of creating resources. Create namespace \u00b6 kubectl create namespace --help kubectl create namespace my-namespace Information Namespace is a cluster, which includes services. Service may be on a node, may be not. Create deployment \u00b6 Create Deployment on the namespace. kubectl -n my-namespace create deployment my-busybox \\ --image=busybox \\ --replicas=3 \\ --port=5701 Create ClusterRole \u00b6 kubectl create clusterrole --help kubectl create clusterrole pod-creater \\ -n my-namespace \\ --verb=create \\ --resource=deployment \\ --resource-name=my-busybox Create ServiceAccount \u00b6 kubectl create serviceaccount --help kubectl -n my-namespace create serviceaccount my-service-account Create RoleBinding \u00b6 Note RoleBinding can reference a Role in the same namespace or a ClusterRole in the global namespace. kubectl create rolebinding --help kubectl create rolebinding NAME \\ --clusterrole=NAME|--role=NAME \\ [--user=username] \\ [--group=groupname] \\ [--serviceaccount=namespace:serviceaccountname] \\ [--dry-run=server|client|none] kubectl create rolebinding my-admin \\ --clusterrole=pod-creater \\ --serviceaccount=my-namespace:my-service-account Use the proxy \u00b6 We can use kubectl proxy command to open a tunnel to the API server and make it available locally - usually on localhost:8001 / 127.0.0.1:8001. When I want to explore the API, this is an easy way to gain access. Run the command kubectl proxy & and open http://localhost:8001/api/v1 in browser. Just opening http://localhost:8001 will return an error because we are only allowed to access certain parts of the API. Hence the API path is important kubectl proxy & Output [1] 102358 Starting to serve on 127.0.0.1:8001 Example, get available API groups and so on via below link: http://127.0.0.1:8001/ http://127.0.0.1:8001/api/v1 http://127.0.0.1:8001/api/v1/namespaces http://127.0.0.1:8001/api/v1/namespaces/default http://127.0.0.1:8001/api/v1/namespaces/sock-shop/pods Access as application \u00b6 If we access kubernetes as an application rather than an administrator, we cannot use the kubectl . Instead of kubectl we can use the program curl . We have to send HTTP requests to the cluster. asking for the available nodes. Make sure kubectl proxy is running and serving on http://localhost:8001/ . Execute command below with a -v=9 flag, it shows all the information needed. kubectl get nodes Go through the command's output and find the correct curl request below. curl -v -XGET \\ -H \"Accept: application/json;as=Table;v=v1;g=meta.k8s.io,application/json;as=Table;v=v1beta1;g=meta.k8s.io,application/json\" \\ -H \"User-Agent: kubectl/v1.24.1 (linux/amd64) kubernetes/3ddd0f4\" \\ 'https:///api/v1/nodes?limit=500' Reference *There is a forum-like page hosted by K8s with lots of information around kubectl and how to use it best. * Manage multiple clusters and multiple config files * kubectl command documentation * Shell autocompletion * kubectl cheat sheet * jsonpath in kubectl * kubectl","title":"kubectl basics"},{"location":"k8s/cka_en/foundamentals/basics/#kubectl-basics","text":"Scenario: get to know how to operate Kubernetes cluster using kubectl . via API via kubectl via Dashboard Demo:","title":"kubectl basics"},{"location":"k8s/cka_en/foundamentals/basics/#check-current-kubeconfig-file","text":"Use the kubectl config command to get current context of configuration file. echo $KUBECONFIG kubectl config view kubectl config get-contexts","title":"Check current kubeconfig file"},{"location":"k8s/cka_en/foundamentals/basics/#get-resource-list","text":"Get a complete list of supported resources kubectl api-resources","title":"Get resource list"},{"location":"k8s/cka_en/foundamentals/basics/#get-cluster-status","text":"Kubernetes control plane is running at https://:6443 CoreDNS is running at https://:6443/api/v1/namespaces/kube-system/services/kube-dns:dns/proxy kubectl cluster-info kubectl cluster-info dump","title":"Get cluster status"},{"location":"k8s/cka_en/foundamentals/basics/#display-resources","text":"Use kubectl get --help to get examples of displaying one or many resources. Get health status of control plane. kubectl get componentstatuses kubectl get cs Result NAME STATUS MESSAGE ERROR etcd-0 Healthy {\"health\":\"true\",\"reason\":\"\"} scheduler Healthy ok controller-manager Healthy ok","title":"Display resources"},{"location":"k8s/cka_en/foundamentals/basics/#get-node-status-and-details","text":"kubectl get nodes kubectl get nodes -o wide kubectl describe node cka001 Use command kubectl create --help to get examples of creating resources.","title":"Get node status and details"},{"location":"k8s/cka_en/foundamentals/basics/#create-namespace","text":"kubectl create namespace --help kubectl create namespace my-namespace Information Namespace is a cluster, which includes services. Service may be on a node, may be not.","title":"Create namespace"},{"location":"k8s/cka_en/foundamentals/basics/#create-deployment","text":"Create Deployment on the namespace. kubectl -n my-namespace create deployment my-busybox \\ --image=busybox \\ --replicas=3 \\ --port=5701","title":"Create deployment"},{"location":"k8s/cka_en/foundamentals/basics/#create-clusterrole","text":"kubectl create clusterrole --help kubectl create clusterrole pod-creater \\ -n my-namespace \\ --verb=create \\ --resource=deployment \\ --resource-name=my-busybox","title":"Create ClusterRole"},{"location":"k8s/cka_en/foundamentals/basics/#create-serviceaccount","text":"kubectl create serviceaccount --help kubectl -n my-namespace create serviceaccount my-service-account","title":"Create ServiceAccount"},{"location":"k8s/cka_en/foundamentals/basics/#create-rolebinding","text":"Note RoleBinding can reference a Role in the same namespace or a ClusterRole in the global namespace. kubectl create rolebinding --help kubectl create rolebinding NAME \\ --clusterrole=NAME|--role=NAME \\ [--user=username] \\ [--group=groupname] \\ [--serviceaccount=namespace:serviceaccountname] \\ [--dry-run=server|client|none] kubectl create rolebinding my-admin \\ --clusterrole=pod-creater \\ --serviceaccount=my-namespace:my-service-account","title":"Create RoleBinding"},{"location":"k8s/cka_en/foundamentals/basics/#use-the-proxy","text":"We can use kubectl proxy command to open a tunnel to the API server and make it available locally - usually on localhost:8001 / 127.0.0.1:8001. When I want to explore the API, this is an easy way to gain access. Run the command kubectl proxy & and open http://localhost:8001/api/v1 in browser. Just opening http://localhost:8001 will return an error because we are only allowed to access certain parts of the API. Hence the API path is important kubectl proxy & Output [1] 102358 Starting to serve on 127.0.0.1:8001 Example, get available API groups and so on via below link: http://127.0.0.1:8001/ http://127.0.0.1:8001/api/v1 http://127.0.0.1:8001/api/v1/namespaces http://127.0.0.1:8001/api/v1/namespaces/default http://127.0.0.1:8001/api/v1/namespaces/sock-shop/pods","title":"Use the proxy"},{"location":"k8s/cka_en/foundamentals/basics/#access-as-application","text":"If we access kubernetes as an application rather than an administrator, we cannot use the kubectl . Instead of kubectl we can use the program curl . We have to send HTTP requests to the cluster. asking for the available nodes. Make sure kubectl proxy is running and serving on http://localhost:8001/ . Execute command below with a -v=9 flag, it shows all the information needed. kubectl get nodes Go through the command's output and find the correct curl request below. curl -v -XGET \\ -H \"Accept: application/json;as=Table;v=v1;g=meta.k8s.io,application/json;as=Table;v=v1beta1;g=meta.k8s.io,application/json\" \\ -H \"User-Agent: kubectl/v1.24.1 (linux/amd64) kubernetes/3ddd0f4\" \\ 'https:///api/v1/nodes?limit=500' Reference *There is a forum-like page hosted by K8s with lots of information around kubectl and how to use it best. * Manage multiple clusters and multiple config files * kubectl command documentation * Shell autocompletion * kubectl cheat sheet * jsonpath in kubectl * kubectl","title":"Access as application"},{"location":"k8s/cka_en/foundamentals/casestudy-calico/","text":"Case Study: Install Calico \u00b6 Scenario: Install Calico Calico Datastore Configure IP Pools Install CNI plugin Install Typha Install calico/node Test networking The Calico Datastore \u00b6 In order to use Kubernetes as the Calico datastore, we need to define the custom resources Calico uses. Download and examine the list of Calico custom resource definitions, and open it in a file editor. wget https://projectcalico.docs.tigera.io/manifests/crds.yaml Create the custom resource definitions in Kubernetes. kubectl apply -f crds.yaml Install calicoctl . To interact directly with the Calico datastore, use the calicoctl client tool. Download the calicoctl binary to a Linux host with access to Kubernetes. The latest release of calicoctl can be found in the git page and replace below v3.23.2 by actual release number. wget https://github.com/projectcalico/calico/releases/download/v3.23.3/calicoctl-linux-amd64 chmod +x calicoctl-linux-amd64 sudo cp calicoctl-linux-amd64 /usr/local/bin/calicoctl Configure calicoctl to access Kubernetes echo \"export KUBECONFIG=/root/.kube/config\" >> ~/.bashrc echo \"export DATASTORE_TYPE=kubernetes\" >> ~/.bashrc echo $KUBECONFIG echo $DATASTORE_TYPE Verify calicoctl can reach the datastore by running\uff1a calicoctl get nodes -o wide Output similar to below: NAME ASN IPV4 IPV6 cka001 cka002 cka003 Nodes are backed by the Kubernetes node object, so we should see names that match kubectl get nodes . kubectl get nodes -o wide NAME STATUS ROLES AGE VERSION OS-IMAGE KERNEL-VERSION CONTAINER-RUNTIME cka001 NotReady control-plane,master 23m v1.24.0 Ubuntu 20.04.4 LTS 5.4.0-113-generic containerd://1.5.9 cka002 NotReady 22m v1.24.0 Ubuntu 20.04.4 LTS 5.4.0-113-generic containerd://1.5.9 cka003 NotReady 21m v1.24.0 Ubuntu 20.04.4 LTS 5.4.0-113-generic containerd://1.5.9 Configure IP Pools \u00b6 A workload is a container or VM that Calico handles the virtual networking for. In Kubernetes, workloads are pods. A workload endpoint is the virtual network interface a workload uses to connect to the Calico network. IP pools are ranges of IP addresses that Calico uses for workload endpoints. Get current IP pools in the cluster. So far, it's empty after fresh installation. calicoctl get ippools NAME CIDR SELECTOR The Pod CIDR is 10.244.0.0/16 we specified via kubeadm init . Let's create two IP pools for use in the cluster. Each pool can not have any overlaps. ipv4-ippool-1: 10.244.0.0/18 ipv4-ippool-2: 10.244.192.0/19 calicoctl apply -f - < /etc/cni/net.d/10-calico.conflist < /etc/cni/net.d/10-calico.conflist < /etc/cni/net.d/10-calico.conflist < 4h49m v1.24.0 cka003 Ready 4h49m v1.24.0 Install Typha \u00b6 Typha sits between the Kubernetes API server and per-node daemons like Felix and confd (running in calico/node). It watches the Kubernetes resources and Calico custom resources used by these daemons, and whenever a resource changes it fans out the update to the daemons. This reduces the number of watches the Kubernetes API server needs to serve and improves scalability of the cluster. Provision Certificates We will use mutually authenticated TLS to ensure that calico/node and Typha communicate securely. We generate a certificate authority (CA) and use it to sign a certificate for Typha. Change to directory /etc/kubernetes/pki/ . cd /etc/kubernetes/pki/ Create the CA certificate and key openssl req -x509 -newkey rsa:4096 \\ -keyout typhaca.key \\ -nodes \\ -out typhaca.crt \\ -subj \"/CN=Calico Typha CA\" \\ -days 365 Store the CA certificate in a ConfigMap that Typha & calico/node will access. kubectl create configmap -n kube-system calico-typha-ca --from-file=typhaca.crt Create the Typha key and certificate signing request (CSR). openssl req -newkey rsa:4096 \\ -keyout typha.key \\ -nodes \\ -out typha.csr \\ -subj \"/CN=calico-typha\" The certificate presents the Common Name (CN) as calico-typha . calico/node will be configured to verify this name. Sign the Typha certificate with the CA. openssl x509 -req -in typha.csr \\ -CA typhaca.crt \\ -CAkey typhaca.key \\ -CAcreateserial \\ -out typha.crt \\ -days 365 Signature ok subject=CN = calico-typha Getting CA Private Key Store the Typha key and certificate in a secret that Typha will access kubectl create secret generic -n kube-system calico-typha-certs --from-file=typha.key --from-file=typha.crt Provision RBAC Change to home directory. cd ~ Create a ServiceAccount that will be used to run Typha. kubectl create serviceaccount -n kube-system calico-typha Define a cluster role for Typha with permission to watch Calico datastore objects. kubectl apply -f - < pingtest-585b76c894-s2tbs 1/1 Running 0 7s 10.244.31.0 cka002 pingtest-585b76c894-vm9wn 1/1 Running 0 7s 10.244.28.64 cka003 Note the IP addresses of the second two pods, then exec into the first one. From inside the pod, ping the other two pod IP addresses. For example: kubectl exec -ti pingtest-585b76c894-chwjq -- sh / # ping 10.244.31.1 -c 4 4 packets transmitted, 4 packets received, 0% packet loss / # ping 10.244.31.0 -c 4 4 packets transmitted, 4 packets received, 0% packet loss / # ping 10.244.28.64 -c 4 4 packets transmitted, 0 packets received, 100% packet loss Check routes \u00b6 From one of the nodes, verify that routes exist to each of the pingtest pods\u2019 IP addresses. For example ip route get 10.244.31.1 ip route get 10.244.31.0 ip route get 10.244.28.64 In the result, the via (it's control-plane) in this example indicates the next-hop for this pod IP, which matches the IP address of the node the pod is scheduled on, as expected. IPAM allocations from different pools. Recall that we created two IP pools, but left one disabled. calicoctl get ippools -o wide Result NAME CIDR NAT IPIPMODE VXLANMODE DISABLED DISABLEBGPEXPORT SELECTOR ipv4-ippool-1 10.244.0.0/18 true Never Never false false all() ipv4-ippool-2 10.244.192.0/19 true Never Never true false all() Enable the second pool. calicoctl --allow-version-mismatch apply -f - < Let's attach to the Pod pingtest-585b76c894-chwjq again. kubectl exec -ti pingtest-585b76c894-chwjq -- sh / # 10.244.203.192 -c 4 4 packets transmitted, 0 packets received, 100 % packet loss Mark here. it's failed. Need further check why the route does not work. Clean up kubectl delete deployments.apps pingtest kubectl delete pod pingtest-ippool-2 Reference End-to-end Calico installation","title":"Calico Installation"},{"location":"k8s/cka_en/foundamentals/casestudy-calico/#case-study-install-calico","text":"Scenario: Install Calico Calico Datastore Configure IP Pools Install CNI plugin Install Typha Install calico/node Test networking","title":"Case Study: Install Calico"},{"location":"k8s/cka_en/foundamentals/casestudy-calico/#the-calico-datastore","text":"In order to use Kubernetes as the Calico datastore, we need to define the custom resources Calico uses. Download and examine the list of Calico custom resource definitions, and open it in a file editor. wget https://projectcalico.docs.tigera.io/manifests/crds.yaml Create the custom resource definitions in Kubernetes. kubectl apply -f crds.yaml Install calicoctl . To interact directly with the Calico datastore, use the calicoctl client tool. Download the calicoctl binary to a Linux host with access to Kubernetes. The latest release of calicoctl can be found in the git page and replace below v3.23.2 by actual release number. wget https://github.com/projectcalico/calico/releases/download/v3.23.3/calicoctl-linux-amd64 chmod +x calicoctl-linux-amd64 sudo cp calicoctl-linux-amd64 /usr/local/bin/calicoctl Configure calicoctl to access Kubernetes echo \"export KUBECONFIG=/root/.kube/config\" >> ~/.bashrc echo \"export DATASTORE_TYPE=kubernetes\" >> ~/.bashrc echo $KUBECONFIG echo $DATASTORE_TYPE Verify calicoctl can reach the datastore by running\uff1a calicoctl get nodes -o wide Output similar to below: NAME ASN IPV4 IPV6 cka001 cka002 cka003 Nodes are backed by the Kubernetes node object, so we should see names that match kubectl get nodes . kubectl get nodes -o wide NAME STATUS ROLES AGE VERSION OS-IMAGE KERNEL-VERSION CONTAINER-RUNTIME cka001 NotReady control-plane,master 23m v1.24.0 Ubuntu 20.04.4 LTS 5.4.0-113-generic containerd://1.5.9 cka002 NotReady 22m v1.24.0 Ubuntu 20.04.4 LTS 5.4.0-113-generic containerd://1.5.9 cka003 NotReady 21m v1.24.0 Ubuntu 20.04.4 LTS 5.4.0-113-generic containerd://1.5.9","title":"The Calico Datastore"},{"location":"k8s/cka_en/foundamentals/casestudy-calico/#configure-ip-pools","text":"A workload is a container or VM that Calico handles the virtual networking for. In Kubernetes, workloads are pods. A workload endpoint is the virtual network interface a workload uses to connect to the Calico network. IP pools are ranges of IP addresses that Calico uses for workload endpoints. Get current IP pools in the cluster. So far, it's empty after fresh installation. calicoctl get ippools NAME CIDR SELECTOR The Pod CIDR is 10.244.0.0/16 we specified via kubeadm init . Let's create two IP pools for use in the cluster. Each pool can not have any overlaps. ipv4-ippool-1: 10.244.0.0/18 ipv4-ippool-2: 10.244.192.0/19 calicoctl apply -f - < /etc/cni/net.d/10-calico.conflist < /etc/cni/net.d/10-calico.conflist < /etc/cni/net.d/10-calico.conflist < 4h49m v1.24.0 cka003 Ready 4h49m v1.24.0","title":"Install CNI plugin"},{"location":"k8s/cka_en/foundamentals/casestudy-calico/#install-typha","text":"Typha sits between the Kubernetes API server and per-node daemons like Felix and confd (running in calico/node). It watches the Kubernetes resources and Calico custom resources used by these daemons, and whenever a resource changes it fans out the update to the daemons. This reduces the number of watches the Kubernetes API server needs to serve and improves scalability of the cluster. Provision Certificates We will use mutually authenticated TLS to ensure that calico/node and Typha communicate securely. We generate a certificate authority (CA) and use it to sign a certificate for Typha. Change to directory /etc/kubernetes/pki/ . cd /etc/kubernetes/pki/ Create the CA certificate and key openssl req -x509 -newkey rsa:4096 \\ -keyout typhaca.key \\ -nodes \\ -out typhaca.crt \\ -subj \"/CN=Calico Typha CA\" \\ -days 365 Store the CA certificate in a ConfigMap that Typha & calico/node will access. kubectl create configmap -n kube-system calico-typha-ca --from-file=typhaca.crt Create the Typha key and certificate signing request (CSR). openssl req -newkey rsa:4096 \\ -keyout typha.key \\ -nodes \\ -out typha.csr \\ -subj \"/CN=calico-typha\" The certificate presents the Common Name (CN) as calico-typha . calico/node will be configured to verify this name. Sign the Typha certificate with the CA. openssl x509 -req -in typha.csr \\ -CA typhaca.crt \\ -CAkey typhaca.key \\ -CAcreateserial \\ -out typha.crt \\ -days 365 Signature ok subject=CN = calico-typha Getting CA Private Key Store the Typha key and certificate in a secret that Typha will access kubectl create secret generic -n kube-system calico-typha-certs --from-file=typha.key --from-file=typha.crt Provision RBAC Change to home directory. cd ~ Create a ServiceAccount that will be used to run Typha. kubectl create serviceaccount -n kube-system calico-typha Define a cluster role for Typha with permission to watch Calico datastore objects. kubectl apply -f - < pingtest-585b76c894-s2tbs 1/1 Running 0 7s 10.244.31.0 cka002 pingtest-585b76c894-vm9wn 1/1 Running 0 7s 10.244.28.64 cka003 Note the IP addresses of the second two pods, then exec into the first one. From inside the pod, ping the other two pod IP addresses. For example: kubectl exec -ti pingtest-585b76c894-chwjq -- sh / # ping 10.244.31.1 -c 4 4 packets transmitted, 4 packets received, 0% packet loss / # ping 10.244.31.0 -c 4 4 packets transmitted, 4 packets received, 0% packet loss / # ping 10.244.28.64 -c 4 4 packets transmitted, 0 packets received, 100% packet loss","title":"Pod to pod pings"},{"location":"k8s/cka_en/foundamentals/casestudy-calico/#check-routes","text":"From one of the nodes, verify that routes exist to each of the pingtest pods\u2019 IP addresses. For example ip route get 10.244.31.1 ip route get 10.244.31.0 ip route get 10.244.28.64 In the result, the via (it's control-plane) in this example indicates the next-hop for this pod IP, which matches the IP address of the node the pod is scheduled on, as expected. IPAM allocations from different pools. Recall that we created two IP pools, but left one disabled. calicoctl get ippools -o wide Result NAME CIDR NAT IPIPMODE VXLANMODE DISABLED DISABLEBGPEXPORT SELECTOR ipv4-ippool-1 10.244.0.0/18 true Never Never false false all() ipv4-ippool-2 10.244.192.0/19 true Never Never true false all() Enable the second pool. calicoctl --allow-version-mismatch apply -f - < Let's attach to the Pod pingtest-585b76c894-chwjq again. kubectl exec -ti pingtest-585b76c894-chwjq -- sh / # 10.244.203.192 -c 4 4 packets transmitted, 0 packets received, 100 % packet loss Mark here. it's failed. Need further check why the route does not work. Clean up kubectl delete deployments.apps pingtest kubectl delete pod pingtest-ippool-2 Reference End-to-end Calico installation","title":"Check routes"},{"location":"k8s/cka_en/foundamentals/casestudy-health-check/","text":"Case Study: Health Check \u00b6 Scenario: Create Deployment and Service Simulate an error (delete index.html) Pod is in unhealth status and is removed from endpoint list Fix the error (revert the index.html) Pod is back to normal and in endpoint list Create Deployment and Service \u00b6 Create Deployment nginx-healthcheck and Service nginx-healthcheck . kubectl apply -f - < nginx-healthcheck-79fc55d944-nwwjc 1/1 Running 0 9s 10.244.112.13 cka002 Access Pod IP via curl command, e.g., above example. curl 10.244.102.14 curl 10.244.112.13 We see a successful index.html content of Nginx below with above example. Check details of Service craeted in above example. kubectl describe svc nginx-healthcheck We will see below output. There are two Pods information listed in Endpoints . Name: nginx-healthcheck Namespace: dev Labels: Annotations: Selector: name=nginx-healthcheck Type: NodePort IP Family Policy: SingleStack IP Families: IPv4 IP: 11.244.238.20 IPs: 11.244.238.20 Port: 80/TCP TargetPort: 80/TCP NodePort: 31795/TCP Endpoints: 10.244.102.14:80,10.244.112.13:80 Session Affinity: None External Traffic Policy: Cluster Events: We can also get information of Endpoints. kubectl get endpoints nginx-healthcheck Result NAME ENDPOINTS AGE nginx-healthcheck 10.244.102.14:80,10.244.112.13:80 72s Till now, two nginx-healthcheck Pods are working and providing service as expected. Simulate readinessProbe Failure \u00b6 Let's simulate an error by deleting and index.html file in on of nginx-healthcheck Pod and see what's readinessProbe will do. First, execute kubectl exec -it -- bash to log into nginx-healthcheck Pod, and delete the index.html file. kubectl exec -it nginx-healthcheck-79fc55d944-jw887 -- bash cd /usr/share/nginx/html/ rm -rf index.html exit After that, let's check the status of above Pod that index.html file was deleted. kubectl describe pod nginx-healthcheck-79fc55d944-jw887 We can now see Readiness probe failed error event message. ...... Events: Type Reason Age From Message ---- ------ ---- ---- ------- Normal Scheduled 2m8s default-scheduler Successfully assigned dev/nginx-healthcheck-79fc55d944-jw887 to cka003 Normal Pulled 2m7s kubelet Container image \"nginx:latest\" already present on machine Normal Created 2m7s kubelet Created container nginx-healthcheck Normal Started 2m7s kubelet Started container nginx-healthcheck Warning Unhealthy 2s (x2 over 7s) kubelet Readiness probe failed: HTTP probe failed with statuscode: 403 Let's check another Pod. kubectl describe pod nginx-healthcheck-79fc55d944-nwwjc There is no error info. ...... Events: Type Reason Age From Message ---- ------ ---- ---- ------- Normal Scheduled 3m46s default-scheduler Successfully assigned dev/nginx-healthcheck-79fc55d944-nwwjc to cka002 Normal Pulled 3m45s kubelet Container image \"nginx:latest\" already present on machine Normal Created 3m45s kubelet Created container nginx-healthcheck Normal Started 3m45s kubelet Started container nginx-healthcheck Now, access Pod IP via curl command and see what the result of each Pod. curl 10.244.102.14 curl 10.244.112.13 Result: curl 10.244.102.14 failed with 403 Forbidden error below. curl 10.244.112.13 works well. Let's check current status of Nginx Service after one of Pods runs into failure. kubectl describe svc nginx-healthcheck In below output, there is only one Pod information listed in Endpoint. Name: nginx-healthcheck Namespace: dev Labels: Annotations: Selector: name=nginx-healthcheck Type: NodePort IP Family Policy: SingleStack IP Families: IPv4 IP: 11.244.238.20 IPs: 11.244.238.20 Port: 80/TCP TargetPort: 80/TCP NodePort: 31795/TCP Endpoints: 10.244.112.13:80 Session Affinity: None External Traffic Policy: Cluster Events: Same result we can get by checking information of Endpoints, which is only Pod is running. kubectl get endpoints nginx-healthcheck Output: NAME ENDPOINTS AGE nginx-healthcheck 10.244.112.13:80 6m5s Fix readinessProbe Failure \u00b6 Let's re-create the index.html file again in the Pod. kubectl exec -it nginx-healthcheck-79fc55d944-jw887 -- bash cd /usr/share/nginx/html/ cat > index.html << EOF Welcome to nginx!

Welcome to nginx!

If you see this page, the nginx web server is successfully installed and working. Further configuration is required.

For online documentation and support please refer to nginx.org.
Commercial support is available at nginx.com.

Thank you for using nginx.

EOF exit We now can see that two Pods are back to Endpoints to provide service now. kubectl describe svc nginx-healthcheck kubectl get endpoints nginx-healthcheck Re-access Pod IP via curl command and we can see both are back to normal status. curl 10.244.102.14 curl 10.244.112.13 Verify the Pod status again. kubectl describe pod nginx-healthcheck-79fc55d944-jw887 Conclusion: By delete the index.html file, the Pod is in unhealth status and is removed from endpoint list. One one health Pod can provide normal service. Clean up kubectl delete service nginx-healthcheck kubectl delete deployment nginx-healthcheck Simulate livenessProbe Failure \u00b6 Re-create Deployment nginx-healthcheck and Service nginx-healthcheck . Deployment: NAME READY UP-TO-DATE AVAILABLE AGE nginx-healthcheck 0/2 2 0 7s Pods: NAME READY STATUS RESTARTS AGE nginx-healthcheck-79fc55d944-lknp9 1/1 Running 0 96s nginx-healthcheck-79fc55d944-wntmg 1/1 Running 0 96s Change nginx default listening port from 80 to 90 to simulate livenessProbe Failure. livenessProbe check the live status via port 80 . kubectl exec -it nginx-healthcheck-79fc55d944-lknp9 -- bash root@nginx-healthcheck-79fc55d944-lknp9:/# cd /etc/nginx/conf.d root@nginx-healthcheck-79fc55d944-lknp9:/etc/nginx/conf.d# sed -i 's/80/90/g' default.conf root@nginx-healthcheck-79fc55d944-lknp9:/etc/nginx/conf.d# nginx -s reload 2022/07/24 12:59:45 [notice] 79#79: signal process started The Pod runs into failure. kubectl describe pod nginx-healthcheck-79fc55d944-lknp9 We can see livenessProbe failed error event message. Events: Type Reason Age From Message ---- ------ ---- ---- ------- Normal Scheduled 17m default-scheduler Successfully assigned dev/nginx-healthcheck-79fc55d944-lknp9 to cka003 Normal Pulled 2m47s (x2 over 17m) kubelet Container image \"nginx:latest\" already present on machine Normal Created 2m47s (x2 over 17m) kubelet Created container nginx-healthcheck Normal Started 2m47s (x2 over 17m) kubelet Started container nginx-healthcheck Warning Unhealthy 2m47s (x4 over 2m57s) kubelet Readiness probe failed: Get \"http://10.244.102.46:80/\": dial tcp 10.244.102.46:80: connect: connection refused Warning Unhealthy 2m47s (x3 over 2m57s) kubelet Liveness probe failed: dial tcp 10.244.102.46:80: connect: connection refused Normal Killing 2m47s kubelet Container nginx-healthcheck failed liveness probe, will be restarted Once failure detected by livenessProbe , the container will restarted again automatically. The default.conf we modified will be replaced by default file and the container status is up and normal.","title":"Health Check"},{"location":"k8s/cka_en/foundamentals/casestudy-health-check/#case-study-health-check","text":"Scenario: Create Deployment and Service Simulate an error (delete index.html) Pod is in unhealth status and is removed from endpoint list Fix the error (revert the index.html) Pod is back to normal and in endpoint list","title":"Case Study: Health Check"},{"location":"k8s/cka_en/foundamentals/casestudy-health-check/#create-deployment-and-service","text":"Create Deployment nginx-healthcheck and Service nginx-healthcheck . kubectl apply -f - < nginx-healthcheck-79fc55d944-nwwjc 1/1 Running 0 9s 10.244.112.13 cka002 Access Pod IP via curl command, e.g., above example. curl 10.244.102.14 curl 10.244.112.13 We see a successful index.html content of Nginx below with above example. Check details of Service craeted in above example. kubectl describe svc nginx-healthcheck We will see below output. There are two Pods information listed in Endpoints . Name: nginx-healthcheck Namespace: dev Labels: Annotations: Selector: name=nginx-healthcheck Type: NodePort IP Family Policy: SingleStack IP Families: IPv4 IP: 11.244.238.20 IPs: 11.244.238.20 Port: 80/TCP TargetPort: 80/TCP NodePort: 31795/TCP Endpoints: 10.244.102.14:80,10.244.112.13:80 Session Affinity: None External Traffic Policy: Cluster Events: We can also get information of Endpoints. kubectl get endpoints nginx-healthcheck Result NAME ENDPOINTS AGE nginx-healthcheck 10.244.102.14:80,10.244.112.13:80 72s Till now, two nginx-healthcheck Pods are working and providing service as expected.","title":"Create Deployment and Service"},{"location":"k8s/cka_en/foundamentals/casestudy-health-check/#simulate-readinessprobe-failure","text":"Let's simulate an error by deleting and index.html file in on of nginx-healthcheck Pod and see what's readinessProbe will do. First, execute kubectl exec -it -- bash to log into nginx-healthcheck Pod, and delete the index.html file. kubectl exec -it nginx-healthcheck-79fc55d944-jw887 -- bash cd /usr/share/nginx/html/ rm -rf index.html exit After that, let's check the status of above Pod that index.html file was deleted. kubectl describe pod nginx-healthcheck-79fc55d944-jw887 We can now see Readiness probe failed error event message. ...... Events: Type Reason Age From Message ---- ------ ---- ---- ------- Normal Scheduled 2m8s default-scheduler Successfully assigned dev/nginx-healthcheck-79fc55d944-jw887 to cka003 Normal Pulled 2m7s kubelet Container image \"nginx:latest\" already present on machine Normal Created 2m7s kubelet Created container nginx-healthcheck Normal Started 2m7s kubelet Started container nginx-healthcheck Warning Unhealthy 2s (x2 over 7s) kubelet Readiness probe failed: HTTP probe failed with statuscode: 403 Let's check another Pod. kubectl describe pod nginx-healthcheck-79fc55d944-nwwjc There is no error info. ...... Events: Type Reason Age From Message ---- ------ ---- ---- ------- Normal Scheduled 3m46s default-scheduler Successfully assigned dev/nginx-healthcheck-79fc55d944-nwwjc to cka002 Normal Pulled 3m45s kubelet Container image \"nginx:latest\" already present on machine Normal Created 3m45s kubelet Created container nginx-healthcheck Normal Started 3m45s kubelet Started container nginx-healthcheck Now, access Pod IP via curl command and see what the result of each Pod. curl 10.244.102.14 curl 10.244.112.13 Result: curl 10.244.102.14 failed with 403 Forbidden error below. curl 10.244.112.13 works well. Let's check current status of Nginx Service after one of Pods runs into failure. kubectl describe svc nginx-healthcheck In below output, there is only one Pod information listed in Endpoint. Name: nginx-healthcheck Namespace: dev Labels: Annotations: Selector: name=nginx-healthcheck Type: NodePort IP Family Policy: SingleStack IP Families: IPv4 IP: 11.244.238.20 IPs: 11.244.238.20 Port: 80/TCP TargetPort: 80/TCP NodePort: 31795/TCP Endpoints: 10.244.112.13:80 Session Affinity: None External Traffic Policy: Cluster Events: Same result we can get by checking information of Endpoints, which is only Pod is running. kubectl get endpoints nginx-healthcheck Output: NAME ENDPOINTS AGE nginx-healthcheck 10.244.112.13:80 6m5s","title":"Simulate readinessProbe Failure"},{"location":"k8s/cka_en/foundamentals/casestudy-health-check/#fix-readinessprobe-failure","text":"Let's re-create the index.html file again in the Pod. kubectl exec -it nginx-healthcheck-79fc55d944-jw887 -- bash cd /usr/share/nginx/html/ cat > index.html << EOF Welcome to nginx!

Welcome to nginx!

If you see this page, the nginx web server is successfully installed and working. Further configuration is required.

For online documentation and support please refer to nginx.org.
Commercial support is available at nginx.com.

Thank you for using nginx.

EOF exit We now can see that two Pods are back to Endpoints to provide service now. kubectl describe svc nginx-healthcheck kubectl get endpoints nginx-healthcheck Re-access Pod IP via curl command and we can see both are back to normal status. curl 10.244.102.14 curl 10.244.112.13 Verify the Pod status again. kubectl describe pod nginx-healthcheck-79fc55d944-jw887 Conclusion: By delete the index.html file, the Pod is in unhealth status and is removed from endpoint list. One one health Pod can provide normal service. Clean up kubectl delete service nginx-healthcheck kubectl delete deployment nginx-healthcheck","title":"Fix readinessProbe Failure"},{"location":"k8s/cka_en/foundamentals/casestudy-health-check/#simulate-livenessprobe-failure","text":"Re-create Deployment nginx-healthcheck and Service nginx-healthcheck . Deployment: NAME READY UP-TO-DATE AVAILABLE AGE nginx-healthcheck 0/2 2 0 7s Pods: NAME READY STATUS RESTARTS AGE nginx-healthcheck-79fc55d944-lknp9 1/1 Running 0 96s nginx-healthcheck-79fc55d944-wntmg 1/1 Running 0 96s Change nginx default listening port from 80 to 90 to simulate livenessProbe Failure. livenessProbe check the live status via port 80 . kubectl exec -it nginx-healthcheck-79fc55d944-lknp9 -- bash root@nginx-healthcheck-79fc55d944-lknp9:/# cd /etc/nginx/conf.d root@nginx-healthcheck-79fc55d944-lknp9:/etc/nginx/conf.d# sed -i 's/80/90/g' default.conf root@nginx-healthcheck-79fc55d944-lknp9:/etc/nginx/conf.d# nginx -s reload 2022/07/24 12:59:45 [notice] 79#79: signal process started The Pod runs into failure. kubectl describe pod nginx-healthcheck-79fc55d944-lknp9 We can see livenessProbe failed error event message. Events: Type Reason Age From Message ---- ------ ---- ---- ------- Normal Scheduled 17m default-scheduler Successfully assigned dev/nginx-healthcheck-79fc55d944-lknp9 to cka003 Normal Pulled 2m47s (x2 over 17m) kubelet Container image \"nginx:latest\" already present on machine Normal Created 2m47s (x2 over 17m) kubelet Created container nginx-healthcheck Normal Started 2m47s (x2 over 17m) kubelet Started container nginx-healthcheck Warning Unhealthy 2m47s (x4 over 2m57s) kubelet Readiness probe failed: Get \"http://10.244.102.46:80/\": dial tcp 10.244.102.46:80: connect: connection refused Warning Unhealthy 2m47s (x3 over 2m57s) kubelet Liveness probe failed: dial tcp 10.244.102.46:80: connect: connection refused Normal Killing 2m47s kubelet Container nginx-healthcheck failed liveness probe, will be restarted Once failure detected by livenessProbe , the container will restarted again automatically. The default.conf we modified will be replaced by default file and the container status is up and normal.","title":"Simulate livenessProbe Failure"},{"location":"k8s/cka_en/foundamentals/casestudy-operation-resources/","text":"Case Study: Operations on Resources \u00b6 Scenario: Node Label Annotation Namespace ServiceAccount Authorization Grant API access authorization to default ServiceAccount Deployment Expose Service Scale out the Deployment Rolling update Rolling back update Event Logging Node Label \u00b6 Add/update/remove node Label. # Update node label kubectl label node cka002 node=demonode # Get node info with label info kubectl get node --show-labels # Search node by label kubectl get node -l node=demonode # Remove a lable of node kubectl label node cka002 node- Annotation \u00b6 Create Nginx deployment kubectl create deploy nginx --image=nginx:mainline Get Annotation info. kubectl describe deployment/nginx Result ...... Labels: app=nginx Annotations: deployment.kubernetes.io/revision: 1 Selector: app=nginx ...... Add new Annotation. kubectl annotate deployment nginx owner=James.H Now annotation looks like below. ...... Labels: app=nginx Annotations: deployment.kubernetes.io/revision: 1 owner: James.H Selector: app=nginx ...... Update/Overwrite Annotation. kubectl annotate deployment/nginx owner=K8s --overwrite Now annotation looks like below. ...... Annotations: deployment.kubernetes.io/revision: 1 owner: K8s Selector: app=nginx ...... Remove Annotation kubectl annotate deployment/nginx owner- ...... Labels: app=nginx Annotations: deployment.kubernetes.io/revision: 1 Selector: app=nginx ...... Clean up kubectl delete deployment nginx Namespace \u00b6 Get current available namespaces. kubectl get namespace Result NAME STATUS AGE default Active 3h45m dev Active 3h11m kube-node-lease Active 3h45m kube-public Active 3h45m kube-system Active 3h45m Get Pod under a specific namespace. kubectl get pod -n kube-system Result NAME READY STATUS RESTARTS AGE calico-kube-controllers-5c64b68895-jr4nl 1/1 Running 0 3h25m calico-node-dsx76 1/1 Running 0 3h25m calico-node-p5rf2 1/1 Running 0 3h25m calico-node-tr22l 1/1 Running 0 3h25m coredns-6d8c4cb4d-g4jxc 1/1 Running 0 3h45m coredns-6d8c4cb4d-sqcvj 1/1 Running 0 3h45m etcd-cka001 1/1 Running 0 3h45m kube-apiserver-cka001 1/1 Running 0 3h45m kube-controller-manager-cka001 1/1 Running 0 3h45m kube-proxy-5cdbj 1/1 Running 0 3h41m kube-proxy-cm4hc 1/1 Running 0 3h45m kube-proxy-g4w52 1/1 Running 0 3h41m kube-scheduler-cka001 1/1 Running 0 3h45m Get Pods in all namespaces. kubectl get pod --all-namespaces kubectl get pod -A ServiceAccount Authorization \u00b6 With Kubernetes 1.23 and lower version, when we create a new namespace, Kubernetes will automatically create a ServiceAccount default and a token default-token-xxxxx . With Kubernetes 1.24, only ServiceAccount default is created automatically when a new namespace is created, need manually create a toke linked to the ServiceAccount default . Here is an example to create a new namespace dev , we can see that only ServiceAcccount: default was created in namespace dev , no secretes (token) linked to the ServiceAccount default . kubectl create namespace dev kubectl get serviceaccount -n dev kubectl get secrets -n dev There is a default cluster role admin . But there is no clusterrole binding to the cluster role admin . kubectl get clusterrole admin kubectl get clusterrolebinding | grep ClusterRole/admin Role and rolebinding is namespaces based. On namespace dev , there is no role and rolebinding. kubectl get role -n dev kubectl get rolebinding -n dev A Secret in the Kubernetes cluster is an object and it is used to store sensitive information such as username, password, and token, etc. The objective of Secrets is to encode or hash the credentials. The secrets can be reused in the various Pod definition file. A kubernetes.io/service-account-token type of Secret is used to store a token that identifies a service account. When using this Secret type, you need to ensure that the kubernetes.io/service-account.name annotation is set to an existing service account name. Let's create token for the ServiceAcccount: default in namespace dev . kubectl apply -f - << EOF apiVersion: v1 kind: Secret metadata: name: default-token-dev namespace: dev annotations: kubernetes.io/service-account.name: \"default\" type: kubernetes.io/service-account-token EOF Now we get ServiceAcccount: default and Secret (token) default-token-dev in namespace dev . kubectl get serviceaccount -n dev kubectl get secrets -n dev Get token of the service account default . TOKEN=$(kubectl -n dev describe secret $(kubectl -n dev get secrets | grep default | cut -f1 -d ' ') | grep -E '^token' | cut -f2 -d':' | tr -d ' ') echo $TOKEN Get API Service address. APISERVER=$(kubectl config view | grep https | cut -f 2- -d \":\" | tr -d \" \") echo $APISERVER Get Pod resources in namespace dev via API server with JSON layout. curl $APISERVER/api/v1/namespaces/dev/pods --header \"Authorization: Bearer $TOKEN\" --insecure We will receive 403 forbidden error message. The ServiceAccount default does not have authorization to access pod in namespace dev . Let's create a rolebinding rolebinding-admin to bind cluster role admin to service account default in namespapce dev . Hence service account default is granted adminstrator authorization in namespace dev . # Usage: kubectl create rolebinding --clusterrole= --serviceaccount=: --namespace= # Crate rolebinding: kubectl create rolebinding rolebinding-admin --clusterrole=admin --serviceaccount=dev:default --namespace=dev Result looks like below by executing kubectl get rolebinding -n dev . NAME ROLE AGE rolebinding-admin ClusterRole/admin 10s Try again, get pod resources in namespace dev via API server with JSON layout. curl $APISERVER/api/v1/namespaces/dev/pods --header \"Authorization: Bearer $TOKEN\" --insecure Clean up. kubectl delete namespace dev Deployment \u00b6 Create a Ubuntu Pod for operation. And attach to the running Pod. kubectl create -f - << EOF apiVersion: v1 kind: Pod metadata: name: ubuntu labels: app: ubuntu spec: containers: - name: ubuntu image: ubuntu:latest command: [\"/bin/sleep\", \"3650d\"] imagePullPolicy: IfNotPresent restartPolicy: Always EOF kubectl exec --stdin --tty ubuntu -- /bin/bash Create a deployment, option --image specifies a image\uff0coption --port specifies port for external access. A pod is also created when deployment is created. kubectl create deployment myapp --image=docker.io/jocatalin/kubernetes-bootcamp:v1 --replicas=1 --port=8080 Get deployment status kubectl get deployment myapp -o wide Result NAME READY UP-TO-DATE AVAILABLE AGE CONTAINERS IMAGES SELECTOR myapp 1/1 1 1 79s kubernetes-bootcamp docker.io/jocatalin/kubernetes-bootcamp:v1 app=myapp Get detail information of deployment. kubectl describe deployment myapp Result Name: myapp Namespace: dev CreationTimestamp: Sat, 23 Jul 2022 14:36:43 +0800 Labels: app=myapp Annotations: deployment.kubernetes.io/revision: 1 Selector: app=myapp Replicas: 1 desired | 1 updated | 1 total | 1 available | 0 unavailable StrategyType: RollingUpdate MinReadySeconds: 0 RollingUpdateStrategy: 25% max unavailable, 25% max surge Pod Template: Labels: app=myapp Containers: kubernetes-bootcamp: Image: docker.io/jocatalin/kubernetes-bootcamp:v1 Port: 8080/TCP Host Port: 0/TCP Environment: Mounts: Volumes: Conditions: Type Status Reason ---- ------ ------ Available True MinimumReplicasAvailable Progressing True NewReplicaSetAvailable OldReplicaSets: NewReplicaSet: myapp-b5d775f5d (1/1 replicas created) Events: Type Reason Age From Message ---- ------ ---- ---- ------- Normal ScalingReplicaSet 95s deployment-controller Scaled up replica set myapp-b5d775f5d to 1 Expose Service \u00b6 Get the Pod and Deployment we created just now. kubectl get deployment myapp -o wide kubectl get pod -o wide Result NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES myapp-b5d775f5d-cx8dx 1/1 Running 0 2m34s 10.244.102.7 cka003 Send http request to the Pod curl 10.244.102.7:8080 with below result. Hello Kubernetes bootcamp! | Running on: myapp-b5d775f5d-6jtgs | v=1 To make pod be accessed outside, we need expose port 8080 to a node port. A related service will be created. kubectl expose deployment myapp --type=NodePort --port=8080 Get details of service myapp by executing kubectl get svc myapp -o wide . NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE SELECTOR myapp NodePort 11.244.74.3 8080:30514/TCP 7s app=myapp Send http request to service port. curl 11.244.74.3:8080 Hello Kubernetes bootcamp! | Running on: myapp-b5d775f5d-cx8dx | v=1 Get more details of the service. kubectl get svc myapp -o yaml kubectl describe svc myapp Get details of related endpoint myapp by executing kubectl get endpoints myapp -o wide . NAME ENDPOINTS AGE myapp 10.244.102.7:8080 43s Send http request to the service and node sucessfully. Pod port 8080 is mapped to node port 32566 . Send http request to node port on cka003 . curl :30514 Hello Kubernetes bootcamp! | Running on: myapp-b5d775f5d-6jtgs | v=1 Attach to Ubuntu Pod we created and send http request to the Service and Pod and Node of myapp . kubectl exec --stdin --tty ubuntu -- /bin/bash curl 10.244.102.7:8080 curl 11.244.74.3:8080 curl :30514 Hello Kubernetes bootcamp! | Running on: myapp-b5d775f5d-6jtgs | v=1 Scale out Deployment \u00b6 Scale out by replicaset. We set three replicasets to scale out deployment myapp . The number of deployment myapp is now three. kubectl scale deployment myapp --replicas=3 Get status of deployment kubectl get deployment myapp Get status of replicaset kubectl get replicaset Rolling update \u00b6 Command usage: kubectl set image (-f FILENAME | TYPE NAME) CONTAINER_NAME_1=CONTAINER_IMAGE_1 ... CONTAINER_NAME_N=CONTAINER_IMAGE_N . With the command kubectl get deployment , we will get deployment name myapp and related container name kubernetes-bootcamp . kubectl get deployment myapp -o wide With the command kubectl set image to update image to many versions and log the change under deployment's annotations with option --record . kubectl set image deployment/myapp kubernetes-bootcamp=docker.io/jocatalin/kubernetes-bootcamp:v2 --record Current replicas status kubectl get replicaset -o wide -l app=myapp Result. Pods are running on new Replicas. NAME DESIRED CURRENT READY AGE CONTAINERS IMAGES SELECTOR myapp-5dbd68cc99 1 1 0 8s kubernetes-bootcamp docker.io/jocatalin/kubernetes-bootcamp:v2 app=myapp,pod-template-hash=5dbd68cc99 myapp-b5d775f5d 3 3 3 14m kubernetes-bootcamp docker.io/jocatalin/kubernetes-bootcamp:v1 app=myapp,pod-template-hash=b5d775f5d We can get the change history under metadata.annotations . kubectl get deployment myapp -o yaml Result apiVersion : apps/v1 kind : Deployment metadata : annotations : deployment.kubernetes.io/revision : \"2\" kubernetes.io/change-cause : kubectl set image deployment/myapp kubernetes-bootcamp=docker.io/jocatalin/kubernetes-bootcamp:v2 --record=true ...... We can also get the change history by command kubectl rollout history , and show details with specific revision --revision= . kubectl rollout history deployment/myapp Result deployment.apps/myapp REVISION CHANGE-CAUSE 1 2 kubectl set image deployment/myapp kubernetes-bootcamp=docker.io/jocatalin/kubernetes-bootcamp:v2 --record=true Get rollout history with specific revision. kubectl rollout history deployment/myapp --revision=2 Roll back to previous revision with command kubectl rollout undo , or roll back to specific revision with option --to-revision= . kubectl rollout undo deployment/myapp --to-revision=1 Revision 1 was replaced by new revision 3 now. kubectl rollout history deployment/myapp Result deployment.apps/myapp REVISION CHANGE-CAUSE 2 kubectl set image deployment/myapp kubernetes-bootcamp=docker.io/jocatalin/kubernetes-bootcamp:v2 --record=true 3 Event \u00b6 Get detail event info of related Pod. kubectl describe pod myapp-b5d775f5d-jlx6g Result looks like below. ...... Events: Type Reason Age From Message ---- ------ ---- ---- ------- Normal Scheduled 54s default-scheduler Successfully assigned dev/myapp-b5d775f5d-jlx6g to cka003 Normal Pulled 53s kubelet Container image \"docker.io/jocatalin/kubernetes-bootcamp:v1\" already present on machine Normal Created 53s kubelet Created container kubernetes-bootcamp Normal Started 53s kubelet Started container kubernetes-bootcamp Get detail event info of entire cluster. kubectl get event Logging \u00b6 Get log info of Pod. kubectl logs -f kubectl logs -f -c Get a Pod logs kubectl logs -f myapp-b5d775f5d-jlx6g Kubernetes Bootcamp App Started At: 2022-07-23T06:54:18.532Z | Running On: myapp-b5d775f5d-jlx6g Get log info of K8s components. kubectl logs kube-apiserver-cka001 -n kube-system kubectl logs kube-controller-manager-cka001 -n kube-system kubectl logs kube-scheduler-cka001 -n kube-system kubectl logs etcd-cka001 -n kube-system systemctl status kubelet journalctl -fu kubelet kubectl logs kube-proxy-5cdbj -n kube-system Clean up. kubectl delete service myapp kubectl delete deployment myapp","title":"Operations on Resources"},{"location":"k8s/cka_en/foundamentals/casestudy-operation-resources/#case-study-operations-on-resources","text":"Scenario: Node Label Annotation Namespace ServiceAccount Authorization Grant API access authorization to default ServiceAccount Deployment Expose Service Scale out the Deployment Rolling update Rolling back update Event Logging","title":"Case Study: Operations on Resources"},{"location":"k8s/cka_en/foundamentals/casestudy-operation-resources/#node-label","text":"Add/update/remove node Label. # Update node label kubectl label node cka002 node=demonode # Get node info with label info kubectl get node --show-labels # Search node by label kubectl get node -l node=demonode # Remove a lable of node kubectl label node cka002 node-","title":"Node Label"},{"location":"k8s/cka_en/foundamentals/casestudy-operation-resources/#annotation","text":"Create Nginx deployment kubectl create deploy nginx --image=nginx:mainline Get Annotation info. kubectl describe deployment/nginx Result ...... Labels: app=nginx Annotations: deployment.kubernetes.io/revision: 1 Selector: app=nginx ...... Add new Annotation. kubectl annotate deployment nginx owner=James.H Now annotation looks like below. ...... Labels: app=nginx Annotations: deployment.kubernetes.io/revision: 1 owner: James.H Selector: app=nginx ...... Update/Overwrite Annotation. kubectl annotate deployment/nginx owner=K8s --overwrite Now annotation looks like below. ...... Annotations: deployment.kubernetes.io/revision: 1 owner: K8s Selector: app=nginx ...... Remove Annotation kubectl annotate deployment/nginx owner- ...... Labels: app=nginx Annotations: deployment.kubernetes.io/revision: 1 Selector: app=nginx ...... Clean up kubectl delete deployment nginx","title":"Annotation"},{"location":"k8s/cka_en/foundamentals/casestudy-operation-resources/#namespace","text":"Get current available namespaces. kubectl get namespace Result NAME STATUS AGE default Active 3h45m dev Active 3h11m kube-node-lease Active 3h45m kube-public Active 3h45m kube-system Active 3h45m Get Pod under a specific namespace. kubectl get pod -n kube-system Result NAME READY STATUS RESTARTS AGE calico-kube-controllers-5c64b68895-jr4nl 1/1 Running 0 3h25m calico-node-dsx76 1/1 Running 0 3h25m calico-node-p5rf2 1/1 Running 0 3h25m calico-node-tr22l 1/1 Running 0 3h25m coredns-6d8c4cb4d-g4jxc 1/1 Running 0 3h45m coredns-6d8c4cb4d-sqcvj 1/1 Running 0 3h45m etcd-cka001 1/1 Running 0 3h45m kube-apiserver-cka001 1/1 Running 0 3h45m kube-controller-manager-cka001 1/1 Running 0 3h45m kube-proxy-5cdbj 1/1 Running 0 3h41m kube-proxy-cm4hc 1/1 Running 0 3h45m kube-proxy-g4w52 1/1 Running 0 3h41m kube-scheduler-cka001 1/1 Running 0 3h45m Get Pods in all namespaces. kubectl get pod --all-namespaces kubectl get pod -A","title":"Namespace"},{"location":"k8s/cka_en/foundamentals/casestudy-operation-resources/#serviceaccount-authorization","text":"With Kubernetes 1.23 and lower version, when we create a new namespace, Kubernetes will automatically create a ServiceAccount default and a token default-token-xxxxx . With Kubernetes 1.24, only ServiceAccount default is created automatically when a new namespace is created, need manually create a toke linked to the ServiceAccount default . Here is an example to create a new namespace dev , we can see that only ServiceAcccount: default was created in namespace dev , no secretes (token) linked to the ServiceAccount default . kubectl create namespace dev kubectl get serviceaccount -n dev kubectl get secrets -n dev There is a default cluster role admin . But there is no clusterrole binding to the cluster role admin . kubectl get clusterrole admin kubectl get clusterrolebinding | grep ClusterRole/admin Role and rolebinding is namespaces based. On namespace dev , there is no role and rolebinding. kubectl get role -n dev kubectl get rolebinding -n dev A Secret in the Kubernetes cluster is an object and it is used to store sensitive information such as username, password, and token, etc. The objective of Secrets is to encode or hash the credentials. The secrets can be reused in the various Pod definition file. A kubernetes.io/service-account-token type of Secret is used to store a token that identifies a service account. When using this Secret type, you need to ensure that the kubernetes.io/service-account.name annotation is set to an existing service account name. Let's create token for the ServiceAcccount: default in namespace dev . kubectl apply -f - << EOF apiVersion: v1 kind: Secret metadata: name: default-token-dev namespace: dev annotations: kubernetes.io/service-account.name: \"default\" type: kubernetes.io/service-account-token EOF Now we get ServiceAcccount: default and Secret (token) default-token-dev in namespace dev . kubectl get serviceaccount -n dev kubectl get secrets -n dev Get token of the service account default . TOKEN=$(kubectl -n dev describe secret $(kubectl -n dev get secrets | grep default | cut -f1 -d ' ') | grep -E '^token' | cut -f2 -d':' | tr -d ' ') echo $TOKEN Get API Service address. APISERVER=$(kubectl config view | grep https | cut -f 2- -d \":\" | tr -d \" \") echo $APISERVER Get Pod resources in namespace dev via API server with JSON layout. curl $APISERVER/api/v1/namespaces/dev/pods --header \"Authorization: Bearer $TOKEN\" --insecure We will receive 403 forbidden error message. The ServiceAccount default does not have authorization to access pod in namespace dev . Let's create a rolebinding rolebinding-admin to bind cluster role admin to service account default in namespapce dev . Hence service account default is granted adminstrator authorization in namespace dev . # Usage: kubectl create rolebinding --clusterrole= --serviceaccount=: --namespace= # Crate rolebinding: kubectl create rolebinding rolebinding-admin --clusterrole=admin --serviceaccount=dev:default --namespace=dev Result looks like below by executing kubectl get rolebinding -n dev . NAME ROLE AGE rolebinding-admin ClusterRole/admin 10s Try again, get pod resources in namespace dev via API server with JSON layout. curl $APISERVER/api/v1/namespaces/dev/pods --header \"Authorization: Bearer $TOKEN\" --insecure Clean up. kubectl delete namespace dev","title":"ServiceAccount Authorization"},{"location":"k8s/cka_en/foundamentals/casestudy-operation-resources/#deployment","text":"Create a Ubuntu Pod for operation. And attach to the running Pod. kubectl create -f - << EOF apiVersion: v1 kind: Pod metadata: name: ubuntu labels: app: ubuntu spec: containers: - name: ubuntu image: ubuntu:latest command: [\"/bin/sleep\", \"3650d\"] imagePullPolicy: IfNotPresent restartPolicy: Always EOF kubectl exec --stdin --tty ubuntu -- /bin/bash Create a deployment, option --image specifies a image\uff0coption --port specifies port for external access. A pod is also created when deployment is created. kubectl create deployment myapp --image=docker.io/jocatalin/kubernetes-bootcamp:v1 --replicas=1 --port=8080 Get deployment status kubectl get deployment myapp -o wide Result NAME READY UP-TO-DATE AVAILABLE AGE CONTAINERS IMAGES SELECTOR myapp 1/1 1 1 79s kubernetes-bootcamp docker.io/jocatalin/kubernetes-bootcamp:v1 app=myapp Get detail information of deployment. kubectl describe deployment myapp Result Name: myapp Namespace: dev CreationTimestamp: Sat, 23 Jul 2022 14:36:43 +0800 Labels: app=myapp Annotations: deployment.kubernetes.io/revision: 1 Selector: app=myapp Replicas: 1 desired | 1 updated | 1 total | 1 available | 0 unavailable StrategyType: RollingUpdate MinReadySeconds: 0 RollingUpdateStrategy: 25% max unavailable, 25% max surge Pod Template: Labels: app=myapp Containers: kubernetes-bootcamp: Image: docker.io/jocatalin/kubernetes-bootcamp:v1 Port: 8080/TCP Host Port: 0/TCP Environment: Mounts: Volumes: Conditions: Type Status Reason ---- ------ ------ Available True MinimumReplicasAvailable Progressing True NewReplicaSetAvailable OldReplicaSets: NewReplicaSet: myapp-b5d775f5d (1/1 replicas created) Events: Type Reason Age From Message ---- ------ ---- ---- ------- Normal ScalingReplicaSet 95s deployment-controller Scaled up replica set myapp-b5d775f5d to 1","title":"Deployment"},{"location":"k8s/cka_en/foundamentals/casestudy-operation-resources/#expose-service","text":"Get the Pod and Deployment we created just now. kubectl get deployment myapp -o wide kubectl get pod -o wide Result NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES myapp-b5d775f5d-cx8dx 1/1 Running 0 2m34s 10.244.102.7 cka003 Send http request to the Pod curl 10.244.102.7:8080 with below result. Hello Kubernetes bootcamp! | Running on: myapp-b5d775f5d-6jtgs | v=1 To make pod be accessed outside, we need expose port 8080 to a node port. A related service will be created. kubectl expose deployment myapp --type=NodePort --port=8080 Get details of service myapp by executing kubectl get svc myapp -o wide . NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE SELECTOR myapp NodePort 11.244.74.3 8080:30514/TCP 7s app=myapp Send http request to service port. curl 11.244.74.3:8080 Hello Kubernetes bootcamp! | Running on: myapp-b5d775f5d-cx8dx | v=1 Get more details of the service. kubectl get svc myapp -o yaml kubectl describe svc myapp Get details of related endpoint myapp by executing kubectl get endpoints myapp -o wide . NAME ENDPOINTS AGE myapp 10.244.102.7:8080 43s Send http request to the service and node sucessfully. Pod port 8080 is mapped to node port 32566 . Send http request to node port on cka003 . curl :30514 Hello Kubernetes bootcamp! | Running on: myapp-b5d775f5d-6jtgs | v=1 Attach to Ubuntu Pod we created and send http request to the Service and Pod and Node of myapp . kubectl exec --stdin --tty ubuntu -- /bin/bash curl 10.244.102.7:8080 curl 11.244.74.3:8080 curl :30514 Hello Kubernetes bootcamp! | Running on: myapp-b5d775f5d-6jtgs | v=1","title":"Expose Service"},{"location":"k8s/cka_en/foundamentals/casestudy-operation-resources/#scale-out-deployment","text":"Scale out by replicaset. We set three replicasets to scale out deployment myapp . The number of deployment myapp is now three. kubectl scale deployment myapp --replicas=3 Get status of deployment kubectl get deployment myapp Get status of replicaset kubectl get replicaset","title":"Scale out Deployment"},{"location":"k8s/cka_en/foundamentals/casestudy-operation-resources/#rolling-update","text":"Command usage: kubectl set image (-f FILENAME | TYPE NAME) CONTAINER_NAME_1=CONTAINER_IMAGE_1 ... CONTAINER_NAME_N=CONTAINER_IMAGE_N . With the command kubectl get deployment , we will get deployment name myapp and related container name kubernetes-bootcamp . kubectl get deployment myapp -o wide With the command kubectl set image to update image to many versions and log the change under deployment's annotations with option --record . kubectl set image deployment/myapp kubernetes-bootcamp=docker.io/jocatalin/kubernetes-bootcamp:v2 --record Current replicas status kubectl get replicaset -o wide -l app=myapp Result. Pods are running on new Replicas. NAME DESIRED CURRENT READY AGE CONTAINERS IMAGES SELECTOR myapp-5dbd68cc99 1 1 0 8s kubernetes-bootcamp docker.io/jocatalin/kubernetes-bootcamp:v2 app=myapp,pod-template-hash=5dbd68cc99 myapp-b5d775f5d 3 3 3 14m kubernetes-bootcamp docker.io/jocatalin/kubernetes-bootcamp:v1 app=myapp,pod-template-hash=b5d775f5d We can get the change history under metadata.annotations . kubectl get deployment myapp -o yaml Result apiVersion : apps/v1 kind : Deployment metadata : annotations : deployment.kubernetes.io/revision : \"2\" kubernetes.io/change-cause : kubectl set image deployment/myapp kubernetes-bootcamp=docker.io/jocatalin/kubernetes-bootcamp:v2 --record=true ...... We can also get the change history by command kubectl rollout history , and show details with specific revision --revision= . kubectl rollout history deployment/myapp Result deployment.apps/myapp REVISION CHANGE-CAUSE 1 2 kubectl set image deployment/myapp kubernetes-bootcamp=docker.io/jocatalin/kubernetes-bootcamp:v2 --record=true Get rollout history with specific revision. kubectl rollout history deployment/myapp --revision=2 Roll back to previous revision with command kubectl rollout undo , or roll back to specific revision with option --to-revision= . kubectl rollout undo deployment/myapp --to-revision=1 Revision 1 was replaced by new revision 3 now. kubectl rollout history deployment/myapp Result deployment.apps/myapp REVISION CHANGE-CAUSE 2 kubectl set image deployment/myapp kubernetes-bootcamp=docker.io/jocatalin/kubernetes-bootcamp:v2 --record=true 3 ","title":"Rolling update"},{"location":"k8s/cka_en/foundamentals/casestudy-operation-resources/#event","text":"Get detail event info of related Pod. kubectl describe pod myapp-b5d775f5d-jlx6g Result looks like below. ...... Events: Type Reason Age From Message ---- ------ ---- ---- ------- Normal Scheduled 54s default-scheduler Successfully assigned dev/myapp-b5d775f5d-jlx6g to cka003 Normal Pulled 53s kubelet Container image \"docker.io/jocatalin/kubernetes-bootcamp:v1\" already present on machine Normal Created 53s kubelet Created container kubernetes-bootcamp Normal Started 53s kubelet Started container kubernetes-bootcamp Get detail event info of entire cluster. kubectl get event","title":"Event"},{"location":"k8s/cka_en/foundamentals/casestudy-operation-resources/#logging","text":"Get log info of Pod. kubectl logs -f kubectl logs -f -c Get a Pod logs kubectl logs -f myapp-b5d775f5d-jlx6g Kubernetes Bootcamp App Started At: 2022-07-23T06:54:18.532Z | Running On: myapp-b5d775f5d-jlx6g Get log info of K8s components. kubectl logs kube-apiserver-cka001 -n kube-system kubectl logs kube-controller-manager-cka001 -n kube-system kubectl logs kube-scheduler-cka001 -n kube-system kubectl logs etcd-cka001 -n kube-system systemctl status kubelet journalctl -fu kubelet kubectl logs kube-proxy-5cdbj -n kube-system Clean up. kubectl delete service myapp kubectl delete deployment myapp","title":"Logging"},{"location":"k8s/cka_en/foundamentals/clustermgt/","text":"Cluster Management \u00b6 Scenario: etcd Backup and Restore Install etcdctl Create Deployment Before Backup Backup etcd Create Deployment After Backup Stop Services Stop etcd Restore etcd Start Services Verify etcd Backup and Restore \u00b6 Install etcdctl \u00b6 Download etcd package from Github. wget https://github.com/etcd-io/etcd/releases/download/v3.5.3/etcd-v3.5.3-linux-amd64.tar.gz Unzip and grant execute permission. tar -zxvf etcd-v3.5.3-linux-amd64.tar.gz cp etcd-v3.5.3-linux-amd64/etcdctl /usr/local/bin/ sudo chmod u+x /usr/local/bin/etcdctl Verify etcdctl --help Create Deployment Before Backup \u00b6 Create Deployment before backup. kubectl create deployment app-before-backup --image=nginx Backup etcd \u00b6 Usage * is the actual IP address of Control Plane. * --endpoints : specify where to save backup of etcd, 2379 is etcd port. * --cert : sepcify etcd certificate, which was generated by kubeadm and saved in /etc/kubernetes/pki/etcd/ . * --key : specify etcd certificate key, which was generated by kubeadm and saved in /etc/kubernetes/pki/etcd/ . * --cacert : specify etcd certificate CA, which was generated by kubeadm and saved in /etc/kubernetes/pki/etcd/ . etcdctl \\ --endpoints=https://:2379 \\ --cert=/etc/kubernetes/pki/etcd/server.crt \\ --key=/etc/kubernetes/pki/etcd/server.key \\ --cacert=/etc/kubernetes/pki/etcd/ca.crt \\ snapshot save snapshot-$(date +\"%Y%m%d%H%M%S\").db etcdctl \\ --endpoints=https://:2379 \\ --cert=/etc/kubernetes/pki/etcd/server.crt \\ --key=/etc/kubernetes/pki/etcd/server.key \\ --cacert=/etc/kubernetes/pki/etcd/ca.crt \\ snapshot save snapshot-$(date +\"%Y%m%d%H%M%S\").db Output: {\"level\":\"info\",\"ts\":\"2022-07-24T18:51:21.328+0800\",\"caller\":\"snapshot/v3_snapshot.go:65\",\"msg\":\"created temporary db file\",\"path\":\"snapshot-20220724185121.db.part\"} {\"level\":\"info\",\"ts\":\"2022-07-24T18:51:21.337+0800\",\"logger\":\"client\",\"caller\":\"v3/maintenance.go:211\",\"msg\":\"opened snapshot stream; downloading\"} {\"level\":\"info\",\"ts\":\"2022-07-24T18:51:21.337+0800\",\"caller\":\"snapshot/v3_snapshot.go:73\",\"msg\":\"fetching snapshot\",\"endpoint\":\"https://:2379\"} {\"level\":\"info\",\"ts\":\"2022-07-24T18:51:21.415+0800\",\"logger\":\"client\",\"caller\":\"v3/maintenance.go:219\",\"msg\":\"completed snapshot read; closing\"} {\"level\":\"info\",\"ts\":\"2022-07-24T18:51:21.477+0800\",\"caller\":\"snapshot/v3_snapshot.go:88\",\"msg\":\"fetched snapshot\",\"endpoint\":\"https://:2379\",\"size\":\"3.6 MB\",\"took\":\"now\"} {\"level\":\"info\",\"ts\":\"2022-07-24T18:51:21.477+0800\",\"caller\":\"snapshot/v3_snapshot.go:97\",\"msg\":\"saved\",\"path\":\"snapshot-20220724185121.db\"} Snapshot saved at snapshot-20220724185121.db We can get the backup file in current directory with ls -al command. -rw------- 1 root root 3616800 Jul 24 18:51 snapshot-20220724185121.db Create Deployment After Backup \u00b6 Create Deployment after backup. kubectl create deployment app-after-backup --image=nginx Delete Deployment we created before backup. kubectl delete deployment app-before-backup Check Deployment status kubectl get deploy NAME READY UP-TO-DATE AVAILABLE AGE app-after-backup 1/1 1 1 108s Stop Services \u00b6 Delete etcd directory. mv /var/lib/etcd/ /var/lib/etcd.bak Stop kubelet systemctl stop kubelet Stop kube-apiserver nerdctl -n k8s.io ps -a | grep apiserver 0c5e69118f1b registry.aliyuncs.com/google_containers/kube-apiserver:v1.24.0 \"kube-apiserver --ad\u2026\" 32 hours ago Up k8s://kube-system/kube-apiserver-cka001/kube-apiserver 638bb602c310 registry.aliyuncs.com/google_containers/pause:3.6 \"/pause\" 32 hours ago Up k8s://kube-system/kube-apiserver-cka001 Stop those up status containers. nerdctl -n k8s.io stop nerdctl -n k8s.io stop 0c5e69118f1b nerdctl -n k8s.io stop 638bb602c310 No up status kube-apiserver now. nerdctl -n k8s.io ps -a | grep apiserver 0c5e69118f1b registry.aliyuncs.com/google_containers/kube-apiserver:v1.24.0 \"kube-apiserver --ad\u2026\" 32 hours ago Created k8s://kube-system/kube-apiserver-cka001/kube-apiserver 638bb602c310 registry.aliyuncs.com/google_containers/pause:3.6 \"/pause\" 32 hours ago Created k8s://kube-system/kube-apiserver-cka001 Stop etcd \u00b6 nerdctl -n k8s.io ps -a | grep etcd 0965b195f41a registry.aliyuncs.com/google_containers/etcd:3.5.1-0 \"etcd --advertise-cl\u2026\" 32 hours ago Up k8s://kube-system/etcd-cka001/etcd 9e1bea9f25d1 registry.aliyuncs.com/google_containers/pause:3.6 \"/pause\" 32 hours ago Up k8s://kube-system/etcd-cka001 Stop those up status containers. nerdctl -n k8s.io stop nerdctl -n k8s.io stop 0965b195f41a nerdctl -n k8s.io stop 9e1bea9f25d1 No up status etcd now. nerdctl -n k8s.io ps -a | grep etcd 0965b195f41a registry.aliyuncs.com/google_containers/etcd:3.5.1-0 \"etcd --advertise-cl\u2026\" 32 hours ago Created k8s://kube-system/etcd-cka001/etcd 9e1bea9f25d1 registry.aliyuncs.com/google_containers/pause:3.6 \"/pause\" 32 hours ago Created k8s://kube-system/etcd-cka001 Restore etcd \u00b6 Execute the restore operation on Control Plane node with actual backup file, here it's file snapshot-20220724185121.db . etcdctl snapshot restore snapshot-20220724185121.db \\ --endpoints=:2379 \\ --cert=/etc/kubernetes/pki/etcd/server.crt \\ --key=/etc/kubernetes/pki/etcd/server.key \\ --cacert=/etc/kubernetes/pki/etcd/ca.crt\\ --data-dir=/var/lib/etcd Output: Deprecated: Use `etcdutl snapshot restore` instead. 2022-07-24T18:57:49+08:00 info snapshot/v3_snapshot.go:248 restoring snapshot {\"path\": \"snapshot-20220724185121.db\", \"wal-dir\": \"/var/lib/etcd/member/wal\", \"data-dir\": \"/var/lib/etcd\", \"snap-dir\": \"/var/lib/etcd/member/snap\", \"stack\": \"go.etcd.io/etcd/etcdutl/v3/snapshot.(*v3Manager).Restore\\n\\t/go/src/go.etcd.io/etcd/release/etcd/etcdutl/snapshot/v3_snapshot.go:254\\ngo.etcd.io/etcd/etcdutl/v3/etcdutl.SnapshotRestoreCommandFunc\\n\\t/go/src/go.etcd.io/etcd/release/etcd/etcdutl/etcdutl/snapshot_command.go:147\\ngo.etcd.io/etcd/etcdctl/v3/ctlv3/command.snapshotRestoreCommandFunc\\n\\t/go/src/go.etcd.io/etcd/release/etcd/etcdctl/ctlv3/command/snapshot_command.go:129\\ngithub.com/spf13/cobra.(*Command).execute\\n\\t/go/pkg/mod/github.com/spf13/cobra@v1.1.3/command.go:856\\ngithub.com/spf13/cobra.(*Command).ExecuteC\\n\\t/go/pkg/mod/github.com/spf13/cobra@v1.1.3/command.go:960\\ngithub.com/spf13/cobra.(*Command).Execute\\n\\t/go/pkg/mod/github.com/spf13/cobra@v1.1.3/command.go:897\\ngo.etcd.io/etcd/etcdctl/v3/ctlv3.Start\\n\\t/go/src/go.etcd.io/etcd/release/etcd/etcdctl/ctlv3/ctl.go:107\\ngo.etcd.io/etcd/etcdctl/v3/ctlv3.MustStart\\n\\t/go/src/go.etcd.io/etcd/release/etcd/etcdctl/ctlv3/ctl.go:111\\nmain.main\\n\\t/go/src/go.etcd.io/etcd/release/etcd/etcdctl/main.go:59\\nruntime.main\\n\\t/go/gos/go1.16.15/src/runtime/proc.go:225\"} 2022-07-24T18:57:49+08:00 info membership/store.go:141 Trimming membership information from the backend... 2022-07-24T18:57:49+08:00 info membership/cluster.go:421 added member {\"cluster-id\": \"cdf818194e3a8c32\", \"local-member-id\": \"0\", \"added-peer-id\": \"8e9e05c52164694d\", \"added-peer-peer-urls\": [\"http://localhost:2380\"]} 2022-07-24T18:57:49+08:00 info snapshot/v3_snapshot.go:269 restored snapshot {\"path\": \"snapshot-20220724185121.db\", \"wal-dir\": \"/var/lib/etcd/member/wal\", \"data-dir\": \"/var/lib/etcd\", \"snap-dir\": \"/var/lib/etcd/member/snap\"} Check if etcd folder is back from restore. tree /var/lib/etcd /var/lib/etcd \u2514\u2500\u2500 member \u251c\u2500\u2500 snap \u2502 \u251c\u2500\u2500 0000000000000001-0000000000000001.snap \u2502 \u2514\u2500\u2500 db \u2514\u2500\u2500 wal \u2514\u2500\u2500 0000000000000000-0000000000000000.wal Start Services \u00b6 Start kubelet . The kube-apiserver and etcd will be started automatically by kubelet . systemctl start kubelet Execute below comamnds to make sure services are all up. systemctl status kubelet.service nerdctl -n k8s.io ps -a | grep etcd nerdctl -n k8s.io ps -a | grep apiserver The current status of etcd . 0965b195f41a registry.aliyuncs.com/google_containers/etcd:3.5.1-0 \"etcd --advertise-cl\u2026\" 32 hours ago Created k8s://kube-system/etcd-cka001/etcd 3b8f37c87782 registry.aliyuncs.com/google_containers/etcd:3.5.1-0 \"etcd --advertise-cl\u2026\" 6 seconds ago Up k8s://kube-system/etcd-cka001/etcd 9e1bea9f25d1 registry.aliyuncs.com/google_containers/pause:3.6 \"/pause\" 32 hours ago Created k8s://kube-system/etcd-cka001 fbbbb628a945 registry.aliyuncs.com/google_containers/pause:3.6 \"/pause\" 6 seconds ago Up k8s://kube-system/etcd-cka001 The current status of apiserver . 0c5e69118f1b registry.aliyuncs.com/google_containers/kube-apiserver:v1.24.0 \"kube-apiserver --ad\u2026\" 32 hours ago Created k8s://kube-system/kube-apiserver-cka001/kube-apiserver 281cf4c6670d registry.aliyuncs.com/google_containers/kube-apiserver:v1.24.0 \"kube-apiserver --ad\u2026\" 14 seconds ago Up k8s://kube-system/kube-apiserver-cka001/kube-apiserver 5ed8295d92da registry.aliyuncs.com/google_containers/pause:3.6 \"/pause\" 15 seconds ago Up k8s://kube-system/kube-apiserver-cka001 638bb602c310 registry.aliyuncs.com/google_containers/pause:3.6 \"/pause\" 32 hours ago Created k8s://kube-system/kube-apiserver-cka001 Verify \u00b6 Check cluster status, if the Pod app-before-backup is there. kubectl get deploy Result NAME READY UP-TO-DATE AVAILABLE AGE app-before-backup 1/1 1 1 11m Upgrade \u00b6 Scenario: Upgrade Evict Control Plane node Check current available version of kubeadm Upgrade kubeadm to new version Check upgrade plan Apply upgrade plan to upgrade to new version Upgrade kubelet and kubectl Enable Control Plane node scheduling Evict Worker nodes Upgrade kubeadm and kubelet Enable Worker node scheduling Reference documentation Upgrade Control Plane \u00b6 Preparation \u00b6 Evict Control Plane node. kubectl drain --ignore-daemonsets kubectl drain cka001 --ignore-daemonsets node/cka001 cordoned WARNING: ignoring DaemonSet-managed Pods: kube-system/calico-node-dsx76, kube-system/kube-proxy-cm4hc evicting pod kube-system/calico-kube-controllers-5c64b68895-jr4nl evicting pod kube-system/coredns-6d8c4cb4d-g4jxc evicting pod kube-system/coredns-6d8c4cb4d-sqcvj pod/calico-kube-controllers-5c64b68895-jr4nl evicted pod/coredns-6d8c4cb4d-g4jxc evicted pod/coredns-6d8c4cb4d-sqcvj evicted node/cka001 drained The Control Plane node is now in SchedulingDisabled status. kubectl get node -owide Result NAME STATUS ROLES AGE VERSION OS-IMAGE KERNEL-VERSION CONTAINER-RUNTIME cka001 Ready,SchedulingDisabled control-plane,master 32h v1.24.0 Ubuntu 20.04.4 LTS 5.4.0-122-generic containerd://1.5.9 cka002 Ready 32h v1.24.0 Ubuntu 20.04.4 LTS 5.4.0-122-generic containerd://1.5.9 cka003 Ready 32h v1.24.0 Ubuntu 20.04.4 LTS 5.4.0-122-generic containerd://1.5.9 Check current available version of kubeadm . apt policy kubeadm kubeadm: Installed: 1.24.0-00 Candidate: 1.24.3-00 Version table: 1.24.3-00 500 500 https://mirrors.aliyun.com/kubernetes/apt kubernetes-xenial/main amd64 Packages 1.24.2-00 500 500 https://mirrors.aliyun.com/kubernetes/apt kubernetes-xenial/main amd64 Packages 1.24.1-00 500 500 https://mirrors.aliyun.com/kubernetes/apt kubernetes-xenial/main amd64 Packages 1.24.0-00 500 500 https://mirrors.aliyun.com/kubernetes/apt kubernetes-xenial/main amd64 Packages 1.24.2-00 500 500 https://mirrors.aliyun.com/kubernetes/apt kubernetes-xenial/main amd64 Packages *** 1.24.0-00 500 500 https://mirrors.aliyun.com/kubernetes/apt kubernetes-xenial/main amd64 Packages 100 /var/lib/dpkg/status 1.23.7-00 500 500 https://mirrors.aliyun.com/kubernetes/apt kubernetes-xenial/main amd64 Packages ...... Upgrade kubeadm to Candidate: 1.24.2-00 version. sudo apt-get -y install kubeadm=1.24.2-00 --allow-downgrades Check upgrade plan. kubeadm upgrade plan Get below guideline of upgrade. [upgrade/config] Making sure the configuration is correct: [upgrade/config] Reading configuration from the cluster... [upgrade/config] FYI: You can look at this config file with 'kubectl -n kube-system get cm kubeadm-config -o yaml' [preflight] Running pre-flight checks. [upgrade] Running cluster health checks [upgrade] Fetching available versions to upgrade to [upgrade/versions] Cluster version: v1.24.0 [upgrade/versions] kubeadm version: v1.24.2 I0724 19:05:00.111855 1142460 version.go:255] remote version is much newer: v1.24.3; falling back to: stable-1.23 [upgrade/versions] Target version: v1.24.2 [upgrade/versions] Latest version in the v1.23 series: v1.24.2 Components that must be upgraded manually after you have upgraded the control plane with 'kubeadm upgrade apply': COMPONENT CURRENT TARGET kubelet 3 x v1.24.0 v1.24.2 Upgrade to the latest version in the v1.23 series: COMPONENT CURRENT TARGET kube-apiserver v1.24.0 v1.24.2 kube-controller-manager v1.24.0 v1.24.2 kube-scheduler v1.24.0 v1.24.2 kube-proxy v1.24.0 v1.24.2 CoreDNS v1.8.6 v1.8.6 etcd 3.5.1-0 3.5.1-0 You can now apply the upgrade by executing the following command: kubeadm upgrade apply v1.24.2 _____________________________________________________________________ The table below shows the current state of component configs as understood by this version of kubeadm. Configs that have a \"yes\" mark in the \"MANUAL UPGRADE REQUIRED\" column require manual config upgrade or resetting to kubeadm defaults before a successful upgrade can be performed. The version to manually upgrade to is denoted in the \"PREFERRED VERSION\" column. API GROUP CURRENT VERSION PREFERRED VERSION MANUAL UPGRADE REQUIRED kubeproxy.config.k8s.io v1alpha1 v1alpha1 no kubelet.config.k8s.io v1beta1 v1beta1 no _____________________________________________________________________ Upgrade Control Plane \u00b6 Refer to upgrade plan, let's upgrade to v1.24.2 version. kubeadm upgrade apply v1.24.2 With option --etcd-upgrade=false , the etcd can be excluded from the upgrade. kubeadm upgrade apply v1.24.2 --etcd-upgrade=false It's successful when receiving below message. [upgrade/successful] SUCCESS! Your cluster was upgraded to \"v1.24.2\". Enjoy! [upgrade/kubelet] Now that your control plane is upgraded, please proceed with upgrading your kubelets if you haven't already done so. Upgrade kubelet and kubectl . sudo apt-get -y install kubelet=1.24.2-00 kubectl=1.24.2-00 --allow-downgrades sudo systemctl daemon-reload sudo systemctl restart kubelet Get current node status. kubectl get node NAME STATUS ROLES AGE VERSION cka001 Ready,SchedulingDisabled control-plane,master 32h v1.24.2 cka002 Ready 32h v1.24.0 cka003 Ready 32h v1.24.0 After verify that each node is in Ready status, enable node scheduling. kubectl uncordon kubectl uncordon cka001 Output: node/cka001 uncordoned Check node status again. Make sure all nodes are in Ready status. kubectl get node Output: NAME STATUS ROLES AGE VERSION cka001 Ready control-plane,master 32h v1.24.2 cka002 Ready 32h v1.24.0 cka003 Ready 32h v1.24.0 Upgrade Worker \u00b6 Preparation for Worker \u00b6 Log on to cka001 Evict Worker nodes, explicitly specify to remove local storage if needed. kubectl drain --ignore-daemonsets --force kubectl drain --ignore-daemonsets --delete-emptydir-data --force If have error on dependency of emptydir , use the 2 nd command. kubectl drain cka002 --ignore-daemonsets --force kubectl drain cka002 --ignore-daemonsets --delete-emptydir-data --force node/cka002 cordoned WARNING: deleting Pods not managed by ReplicationController, ReplicaSet, Job, DaemonSet or StatefulSet: dev/ubuntu; ignoring DaemonSet-managed Pods: kube-system/calico-node-p5rf2, kube-system/kube-proxy-zvs68 evicting pod ns-netpol/pod-netpol-5b67b6b496-2cgnw evicting pod dev/ubuntu evicting pod dev/app-before-backup-66dc9d5cb-6xc8c evicting pod dev/nfs-client-provisioner-86d7fb78b6-2f5dx evicting pod dev/pod-netpol-2-77478d77ff-l6rzm evicting pod ingress-nginx/ingress-nginx-admission-patch-nk9fv evicting pod ingress-nginx/ingress-nginx-admission-create-lgtdj evicting pod kube-system/coredns-6d8c4cb4d-l4kx4 pod/ingress-nginx-admission-create-lgtdj evicted pod/ingress-nginx-admission-patch-nk9fv evicted pod/nfs-client-provisioner-86d7fb78b6-2f5dx evicted pod/app-before-backup-66dc9d5cb-6xc8c evicted pod/coredns-6d8c4cb4d-l4kx4 evicted pod/pod-netpol-5b67b6b496-2cgnw evicted pod/pod-netpol-2-77478d77ff-l6rzm evicted pod/ubuntu evicted node/cka002 drained Upgrade Workers \u00b6 Log on to cka002 . Download kubeadm with version v1.24.2 . sudo apt-get -y install kubeadm=1.24.2-00 --allow-downgrades Upgrade kubeadm . sudo kubeadm upgrade node Upgrade kubelet . sudo apt-get -y install kubelet=1.24.2-00 --allow-downgrades sudo systemctl daemon-reload sudo systemctl restart kubelet Make sure all nodes are in Ready status, then, enable node scheduling. kubectl uncordon kubectl uncordon cka002 Verify Upgrade \u00b6 Check node status. kubectl get node Result NAME STATUS ROLES AGE VERSION cka001 Ready control-plane,master 32h v1.24.2 cka002 Ready 32h v1.24.2 cka003 Ready 32h v1.24.0 Repeat the same on node cka003 . Log onto cka001 . If have error on dependency of emptydir , use the 2 nd command. kubectl drain cka003 --ignore-daemonsets --ignore-daemonsets --force kubectl drain cka003 --ignore-daemonsets --ignore-daemonsets --delete-emptydir-data --force Log onto cka003 and perform below commands. sudo apt-get -y install kubeadm=1.24.2-00 --allow-downgrades sudo kubeadm upgrade node sudo apt-get -y install kubelet=1.24.2-00 --allow-downgrades sudo systemctl daemon-reload sudo systemctl restart kubelet kubectl get node kubectl uncordon cka003 Get final status of all nodes. kubectl get node NAME STATUS ROLES AGE VERSION cka001 Ready control-plane,master 32h v1.24.2 cka002 Ready 32h v1.24.2 cka003 Ready 32h v1.24.2 Summary: Control Plane kubectl get node -owide kubectl drain cka001 --ignore-daemonsets kubectl get node -owide apt policy kubeadm apt-get -y install kubeadm=1.24.0-00 --allow-downgrades kubeadm upgrade plan kubeadm upgrade apply v1.24.0 # kubeadm upgrade apply v1.24.0 --etcd-upgrade = false apt-get -y install kubelet=1.24.0-00 kubectl=1.24.0-00 --allow-downgrades systemctl daemon-reload systemctl restart kubelet kubectl get node kubectl uncordon cka001 Worker Node On Control Plane kubectl drain cka002 --ignore-daemonsets On Workder Node apt-get -y install kubeadm=1.24.1-00 --allow-downgrades kubeadm upgrade node apt-get -y install kubelet=1.24.1-00 --allow-downgrades systemctl daemon-reload systemctl restart kubelet kubectl uncordon cka002 Repeat for other Worker nodes","title":"Cluster Management"},{"location":"k8s/cka_en/foundamentals/clustermgt/#cluster-management","text":"Scenario: etcd Backup and Restore Install etcdctl Create Deployment Before Backup Backup etcd Create Deployment After Backup Stop Services Stop etcd Restore etcd Start Services Verify","title":"Cluster Management"},{"location":"k8s/cka_en/foundamentals/clustermgt/#etcd-backup-and-restore","text":"","title":"etcd Backup and Restore"},{"location":"k8s/cka_en/foundamentals/clustermgt/#install-etcdctl","text":"Download etcd package from Github. wget https://github.com/etcd-io/etcd/releases/download/v3.5.3/etcd-v3.5.3-linux-amd64.tar.gz Unzip and grant execute permission. tar -zxvf etcd-v3.5.3-linux-amd64.tar.gz cp etcd-v3.5.3-linux-amd64/etcdctl /usr/local/bin/ sudo chmod u+x /usr/local/bin/etcdctl Verify etcdctl --help","title":"Install etcdctl"},{"location":"k8s/cka_en/foundamentals/clustermgt/#create-deployment-before-backup","text":"Create Deployment before backup. kubectl create deployment app-before-backup --image=nginx","title":"Create Deployment Before Backup"},{"location":"k8s/cka_en/foundamentals/clustermgt/#backup-etcd","text":"Usage * is the actual IP address of Control Plane. * --endpoints : specify where to save backup of etcd, 2379 is etcd port. * --cert : sepcify etcd certificate, which was generated by kubeadm and saved in /etc/kubernetes/pki/etcd/ . * --key : specify etcd certificate key, which was generated by kubeadm and saved in /etc/kubernetes/pki/etcd/ . * --cacert : specify etcd certificate CA, which was generated by kubeadm and saved in /etc/kubernetes/pki/etcd/ . etcdctl \\ --endpoints=https://:2379 \\ --cert=/etc/kubernetes/pki/etcd/server.crt \\ --key=/etc/kubernetes/pki/etcd/server.key \\ --cacert=/etc/kubernetes/pki/etcd/ca.crt \\ snapshot save snapshot-$(date +\"%Y%m%d%H%M%S\").db etcdctl \\ --endpoints=https://:2379 \\ --cert=/etc/kubernetes/pki/etcd/server.crt \\ --key=/etc/kubernetes/pki/etcd/server.key \\ --cacert=/etc/kubernetes/pki/etcd/ca.crt \\ snapshot save snapshot-$(date +\"%Y%m%d%H%M%S\").db Output: {\"level\":\"info\",\"ts\":\"2022-07-24T18:51:21.328+0800\",\"caller\":\"snapshot/v3_snapshot.go:65\",\"msg\":\"created temporary db file\",\"path\":\"snapshot-20220724185121.db.part\"} {\"level\":\"info\",\"ts\":\"2022-07-24T18:51:21.337+0800\",\"logger\":\"client\",\"caller\":\"v3/maintenance.go:211\",\"msg\":\"opened snapshot stream; downloading\"} {\"level\":\"info\",\"ts\":\"2022-07-24T18:51:21.337+0800\",\"caller\":\"snapshot/v3_snapshot.go:73\",\"msg\":\"fetching snapshot\",\"endpoint\":\"https://:2379\"} {\"level\":\"info\",\"ts\":\"2022-07-24T18:51:21.415+0800\",\"logger\":\"client\",\"caller\":\"v3/maintenance.go:219\",\"msg\":\"completed snapshot read; closing\"} {\"level\":\"info\",\"ts\":\"2022-07-24T18:51:21.477+0800\",\"caller\":\"snapshot/v3_snapshot.go:88\",\"msg\":\"fetched snapshot\",\"endpoint\":\"https://:2379\",\"size\":\"3.6 MB\",\"took\":\"now\"} {\"level\":\"info\",\"ts\":\"2022-07-24T18:51:21.477+0800\",\"caller\":\"snapshot/v3_snapshot.go:97\",\"msg\":\"saved\",\"path\":\"snapshot-20220724185121.db\"} Snapshot saved at snapshot-20220724185121.db We can get the backup file in current directory with ls -al command. -rw------- 1 root root 3616800 Jul 24 18:51 snapshot-20220724185121.db","title":"Backup etcd"},{"location":"k8s/cka_en/foundamentals/clustermgt/#create-deployment-after-backup","text":"Create Deployment after backup. kubectl create deployment app-after-backup --image=nginx Delete Deployment we created before backup. kubectl delete deployment app-before-backup Check Deployment status kubectl get deploy NAME READY UP-TO-DATE AVAILABLE AGE app-after-backup 1/1 1 1 108s","title":"Create Deployment After Backup"},{"location":"k8s/cka_en/foundamentals/clustermgt/#stop-services","text":"Delete etcd directory. mv /var/lib/etcd/ /var/lib/etcd.bak Stop kubelet systemctl stop kubelet Stop kube-apiserver nerdctl -n k8s.io ps -a | grep apiserver 0c5e69118f1b registry.aliyuncs.com/google_containers/kube-apiserver:v1.24.0 \"kube-apiserver --ad\u2026\" 32 hours ago Up k8s://kube-system/kube-apiserver-cka001/kube-apiserver 638bb602c310 registry.aliyuncs.com/google_containers/pause:3.6 \"/pause\" 32 hours ago Up k8s://kube-system/kube-apiserver-cka001 Stop those up status containers. nerdctl -n k8s.io stop nerdctl -n k8s.io stop 0c5e69118f1b nerdctl -n k8s.io stop 638bb602c310 No up status kube-apiserver now. nerdctl -n k8s.io ps -a | grep apiserver 0c5e69118f1b registry.aliyuncs.com/google_containers/kube-apiserver:v1.24.0 \"kube-apiserver --ad\u2026\" 32 hours ago Created k8s://kube-system/kube-apiserver-cka001/kube-apiserver 638bb602c310 registry.aliyuncs.com/google_containers/pause:3.6 \"/pause\" 32 hours ago Created k8s://kube-system/kube-apiserver-cka001","title":"Stop Services"},{"location":"k8s/cka_en/foundamentals/clustermgt/#stop-etcd","text":"nerdctl -n k8s.io ps -a | grep etcd 0965b195f41a registry.aliyuncs.com/google_containers/etcd:3.5.1-0 \"etcd --advertise-cl\u2026\" 32 hours ago Up k8s://kube-system/etcd-cka001/etcd 9e1bea9f25d1 registry.aliyuncs.com/google_containers/pause:3.6 \"/pause\" 32 hours ago Up k8s://kube-system/etcd-cka001 Stop those up status containers. nerdctl -n k8s.io stop nerdctl -n k8s.io stop 0965b195f41a nerdctl -n k8s.io stop 9e1bea9f25d1 No up status etcd now. nerdctl -n k8s.io ps -a | grep etcd 0965b195f41a registry.aliyuncs.com/google_containers/etcd:3.5.1-0 \"etcd --advertise-cl\u2026\" 32 hours ago Created k8s://kube-system/etcd-cka001/etcd 9e1bea9f25d1 registry.aliyuncs.com/google_containers/pause:3.6 \"/pause\" 32 hours ago Created k8s://kube-system/etcd-cka001","title":"Stop etcd"},{"location":"k8s/cka_en/foundamentals/clustermgt/#restore-etcd","text":"Execute the restore operation on Control Plane node with actual backup file, here it's file snapshot-20220724185121.db . etcdctl snapshot restore snapshot-20220724185121.db \\ --endpoints=:2379 \\ --cert=/etc/kubernetes/pki/etcd/server.crt \\ --key=/etc/kubernetes/pki/etcd/server.key \\ --cacert=/etc/kubernetes/pki/etcd/ca.crt\\ --data-dir=/var/lib/etcd Output: Deprecated: Use `etcdutl snapshot restore` instead. 2022-07-24T18:57:49+08:00 info snapshot/v3_snapshot.go:248 restoring snapshot {\"path\": \"snapshot-20220724185121.db\", \"wal-dir\": \"/var/lib/etcd/member/wal\", \"data-dir\": \"/var/lib/etcd\", \"snap-dir\": \"/var/lib/etcd/member/snap\", \"stack\": \"go.etcd.io/etcd/etcdutl/v3/snapshot.(*v3Manager).Restore\\n\\t/go/src/go.etcd.io/etcd/release/etcd/etcdutl/snapshot/v3_snapshot.go:254\\ngo.etcd.io/etcd/etcdutl/v3/etcdutl.SnapshotRestoreCommandFunc\\n\\t/go/src/go.etcd.io/etcd/release/etcd/etcdutl/etcdutl/snapshot_command.go:147\\ngo.etcd.io/etcd/etcdctl/v3/ctlv3/command.snapshotRestoreCommandFunc\\n\\t/go/src/go.etcd.io/etcd/release/etcd/etcdctl/ctlv3/command/snapshot_command.go:129\\ngithub.com/spf13/cobra.(*Command).execute\\n\\t/go/pkg/mod/github.com/spf13/cobra@v1.1.3/command.go:856\\ngithub.com/spf13/cobra.(*Command).ExecuteC\\n\\t/go/pkg/mod/github.com/spf13/cobra@v1.1.3/command.go:960\\ngithub.com/spf13/cobra.(*Command).Execute\\n\\t/go/pkg/mod/github.com/spf13/cobra@v1.1.3/command.go:897\\ngo.etcd.io/etcd/etcdctl/v3/ctlv3.Start\\n\\t/go/src/go.etcd.io/etcd/release/etcd/etcdctl/ctlv3/ctl.go:107\\ngo.etcd.io/etcd/etcdctl/v3/ctlv3.MustStart\\n\\t/go/src/go.etcd.io/etcd/release/etcd/etcdctl/ctlv3/ctl.go:111\\nmain.main\\n\\t/go/src/go.etcd.io/etcd/release/etcd/etcdctl/main.go:59\\nruntime.main\\n\\t/go/gos/go1.16.15/src/runtime/proc.go:225\"} 2022-07-24T18:57:49+08:00 info membership/store.go:141 Trimming membership information from the backend... 2022-07-24T18:57:49+08:00 info membership/cluster.go:421 added member {\"cluster-id\": \"cdf818194e3a8c32\", \"local-member-id\": \"0\", \"added-peer-id\": \"8e9e05c52164694d\", \"added-peer-peer-urls\": [\"http://localhost:2380\"]} 2022-07-24T18:57:49+08:00 info snapshot/v3_snapshot.go:269 restored snapshot {\"path\": \"snapshot-20220724185121.db\", \"wal-dir\": \"/var/lib/etcd/member/wal\", \"data-dir\": \"/var/lib/etcd\", \"snap-dir\": \"/var/lib/etcd/member/snap\"} Check if etcd folder is back from restore. tree /var/lib/etcd /var/lib/etcd \u2514\u2500\u2500 member \u251c\u2500\u2500 snap \u2502 \u251c\u2500\u2500 0000000000000001-0000000000000001.snap \u2502 \u2514\u2500\u2500 db \u2514\u2500\u2500 wal \u2514\u2500\u2500 0000000000000000-0000000000000000.wal","title":"Restore etcd"},{"location":"k8s/cka_en/foundamentals/clustermgt/#start-services","text":"Start kubelet . The kube-apiserver and etcd will be started automatically by kubelet . systemctl start kubelet Execute below comamnds to make sure services are all up. systemctl status kubelet.service nerdctl -n k8s.io ps -a | grep etcd nerdctl -n k8s.io ps -a | grep apiserver The current status of etcd . 0965b195f41a registry.aliyuncs.com/google_containers/etcd:3.5.1-0 \"etcd --advertise-cl\u2026\" 32 hours ago Created k8s://kube-system/etcd-cka001/etcd 3b8f37c87782 registry.aliyuncs.com/google_containers/etcd:3.5.1-0 \"etcd --advertise-cl\u2026\" 6 seconds ago Up k8s://kube-system/etcd-cka001/etcd 9e1bea9f25d1 registry.aliyuncs.com/google_containers/pause:3.6 \"/pause\" 32 hours ago Created k8s://kube-system/etcd-cka001 fbbbb628a945 registry.aliyuncs.com/google_containers/pause:3.6 \"/pause\" 6 seconds ago Up k8s://kube-system/etcd-cka001 The current status of apiserver . 0c5e69118f1b registry.aliyuncs.com/google_containers/kube-apiserver:v1.24.0 \"kube-apiserver --ad\u2026\" 32 hours ago Created k8s://kube-system/kube-apiserver-cka001/kube-apiserver 281cf4c6670d registry.aliyuncs.com/google_containers/kube-apiserver:v1.24.0 \"kube-apiserver --ad\u2026\" 14 seconds ago Up k8s://kube-system/kube-apiserver-cka001/kube-apiserver 5ed8295d92da registry.aliyuncs.com/google_containers/pause:3.6 \"/pause\" 15 seconds ago Up k8s://kube-system/kube-apiserver-cka001 638bb602c310 registry.aliyuncs.com/google_containers/pause:3.6 \"/pause\" 32 hours ago Created k8s://kube-system/kube-apiserver-cka001","title":"Start Services"},{"location":"k8s/cka_en/foundamentals/clustermgt/#verify","text":"Check cluster status, if the Pod app-before-backup is there. kubectl get deploy Result NAME READY UP-TO-DATE AVAILABLE AGE app-before-backup 1/1 1 1 11m","title":"Verify"},{"location":"k8s/cka_en/foundamentals/clustermgt/#upgrade","text":"Scenario: Upgrade Evict Control Plane node Check current available version of kubeadm Upgrade kubeadm to new version Check upgrade plan Apply upgrade plan to upgrade to new version Upgrade kubelet and kubectl Enable Control Plane node scheduling Evict Worker nodes Upgrade kubeadm and kubelet Enable Worker node scheduling Reference documentation","title":"Upgrade"},{"location":"k8s/cka_en/foundamentals/clustermgt/#upgrade-control-plane","text":"","title":"Upgrade Control Plane"},{"location":"k8s/cka_en/foundamentals/clustermgt/#preparation","text":"Evict Control Plane node. kubectl drain --ignore-daemonsets kubectl drain cka001 --ignore-daemonsets node/cka001 cordoned WARNING: ignoring DaemonSet-managed Pods: kube-system/calico-node-dsx76, kube-system/kube-proxy-cm4hc evicting pod kube-system/calico-kube-controllers-5c64b68895-jr4nl evicting pod kube-system/coredns-6d8c4cb4d-g4jxc evicting pod kube-system/coredns-6d8c4cb4d-sqcvj pod/calico-kube-controllers-5c64b68895-jr4nl evicted pod/coredns-6d8c4cb4d-g4jxc evicted pod/coredns-6d8c4cb4d-sqcvj evicted node/cka001 drained The Control Plane node is now in SchedulingDisabled status. kubectl get node -owide Result NAME STATUS ROLES AGE VERSION OS-IMAGE KERNEL-VERSION CONTAINER-RUNTIME cka001 Ready,SchedulingDisabled control-plane,master 32h v1.24.0 Ubuntu 20.04.4 LTS 5.4.0-122-generic containerd://1.5.9 cka002 Ready 32h v1.24.0 Ubuntu 20.04.4 LTS 5.4.0-122-generic containerd://1.5.9 cka003 Ready 32h v1.24.0 Ubuntu 20.04.4 LTS 5.4.0-122-generic containerd://1.5.9 Check current available version of kubeadm . apt policy kubeadm kubeadm: Installed: 1.24.0-00 Candidate: 1.24.3-00 Version table: 1.24.3-00 500 500 https://mirrors.aliyun.com/kubernetes/apt kubernetes-xenial/main amd64 Packages 1.24.2-00 500 500 https://mirrors.aliyun.com/kubernetes/apt kubernetes-xenial/main amd64 Packages 1.24.1-00 500 500 https://mirrors.aliyun.com/kubernetes/apt kubernetes-xenial/main amd64 Packages 1.24.0-00 500 500 https://mirrors.aliyun.com/kubernetes/apt kubernetes-xenial/main amd64 Packages 1.24.2-00 500 500 https://mirrors.aliyun.com/kubernetes/apt kubernetes-xenial/main amd64 Packages *** 1.24.0-00 500 500 https://mirrors.aliyun.com/kubernetes/apt kubernetes-xenial/main amd64 Packages 100 /var/lib/dpkg/status 1.23.7-00 500 500 https://mirrors.aliyun.com/kubernetes/apt kubernetes-xenial/main amd64 Packages ...... Upgrade kubeadm to Candidate: 1.24.2-00 version. sudo apt-get -y install kubeadm=1.24.2-00 --allow-downgrades Check upgrade plan. kubeadm upgrade plan Get below guideline of upgrade. [upgrade/config] Making sure the configuration is correct: [upgrade/config] Reading configuration from the cluster... [upgrade/config] FYI: You can look at this config file with 'kubectl -n kube-system get cm kubeadm-config -o yaml' [preflight] Running pre-flight checks. [upgrade] Running cluster health checks [upgrade] Fetching available versions to upgrade to [upgrade/versions] Cluster version: v1.24.0 [upgrade/versions] kubeadm version: v1.24.2 I0724 19:05:00.111855 1142460 version.go:255] remote version is much newer: v1.24.3; falling back to: stable-1.23 [upgrade/versions] Target version: v1.24.2 [upgrade/versions] Latest version in the v1.23 series: v1.24.2 Components that must be upgraded manually after you have upgraded the control plane with 'kubeadm upgrade apply': COMPONENT CURRENT TARGET kubelet 3 x v1.24.0 v1.24.2 Upgrade to the latest version in the v1.23 series: COMPONENT CURRENT TARGET kube-apiserver v1.24.0 v1.24.2 kube-controller-manager v1.24.0 v1.24.2 kube-scheduler v1.24.0 v1.24.2 kube-proxy v1.24.0 v1.24.2 CoreDNS v1.8.6 v1.8.6 etcd 3.5.1-0 3.5.1-0 You can now apply the upgrade by executing the following command: kubeadm upgrade apply v1.24.2 _____________________________________________________________________ The table below shows the current state of component configs as understood by this version of kubeadm. Configs that have a \"yes\" mark in the \"MANUAL UPGRADE REQUIRED\" column require manual config upgrade or resetting to kubeadm defaults before a successful upgrade can be performed. The version to manually upgrade to is denoted in the \"PREFERRED VERSION\" column. API GROUP CURRENT VERSION PREFERRED VERSION MANUAL UPGRADE REQUIRED kubeproxy.config.k8s.io v1alpha1 v1alpha1 no kubelet.config.k8s.io v1beta1 v1beta1 no _____________________________________________________________________","title":"Preparation"},{"location":"k8s/cka_en/foundamentals/clustermgt/#upgrade-control-plane_1","text":"Refer to upgrade plan, let's upgrade to v1.24.2 version. kubeadm upgrade apply v1.24.2 With option --etcd-upgrade=false , the etcd can be excluded from the upgrade. kubeadm upgrade apply v1.24.2 --etcd-upgrade=false It's successful when receiving below message. [upgrade/successful] SUCCESS! Your cluster was upgraded to \"v1.24.2\". Enjoy! [upgrade/kubelet] Now that your control plane is upgraded, please proceed with upgrading your kubelets if you haven't already done so. Upgrade kubelet and kubectl . sudo apt-get -y install kubelet=1.24.2-00 kubectl=1.24.2-00 --allow-downgrades sudo systemctl daemon-reload sudo systemctl restart kubelet Get current node status. kubectl get node NAME STATUS ROLES AGE VERSION cka001 Ready,SchedulingDisabled control-plane,master 32h v1.24.2 cka002 Ready 32h v1.24.0 cka003 Ready 32h v1.24.0 After verify that each node is in Ready status, enable node scheduling. kubectl uncordon kubectl uncordon cka001 Output: node/cka001 uncordoned Check node status again. Make sure all nodes are in Ready status. kubectl get node Output: NAME STATUS ROLES AGE VERSION cka001 Ready control-plane,master 32h v1.24.2 cka002 Ready 32h v1.24.0 cka003 Ready 32h v1.24.0","title":"Upgrade Control Plane"},{"location":"k8s/cka_en/foundamentals/clustermgt/#upgrade-worker","text":"","title":"Upgrade Worker"},{"location":"k8s/cka_en/foundamentals/clustermgt/#preparation-for-worker","text":"Log on to cka001 Evict Worker nodes, explicitly specify to remove local storage if needed. kubectl drain --ignore-daemonsets --force kubectl drain --ignore-daemonsets --delete-emptydir-data --force If have error on dependency of emptydir , use the 2 nd command. kubectl drain cka002 --ignore-daemonsets --force kubectl drain cka002 --ignore-daemonsets --delete-emptydir-data --force node/cka002 cordoned WARNING: deleting Pods not managed by ReplicationController, ReplicaSet, Job, DaemonSet or StatefulSet: dev/ubuntu; ignoring DaemonSet-managed Pods: kube-system/calico-node-p5rf2, kube-system/kube-proxy-zvs68 evicting pod ns-netpol/pod-netpol-5b67b6b496-2cgnw evicting pod dev/ubuntu evicting pod dev/app-before-backup-66dc9d5cb-6xc8c evicting pod dev/nfs-client-provisioner-86d7fb78b6-2f5dx evicting pod dev/pod-netpol-2-77478d77ff-l6rzm evicting pod ingress-nginx/ingress-nginx-admission-patch-nk9fv evicting pod ingress-nginx/ingress-nginx-admission-create-lgtdj evicting pod kube-system/coredns-6d8c4cb4d-l4kx4 pod/ingress-nginx-admission-create-lgtdj evicted pod/ingress-nginx-admission-patch-nk9fv evicted pod/nfs-client-provisioner-86d7fb78b6-2f5dx evicted pod/app-before-backup-66dc9d5cb-6xc8c evicted pod/coredns-6d8c4cb4d-l4kx4 evicted pod/pod-netpol-5b67b6b496-2cgnw evicted pod/pod-netpol-2-77478d77ff-l6rzm evicted pod/ubuntu evicted node/cka002 drained","title":"Preparation for Worker"},{"location":"k8s/cka_en/foundamentals/clustermgt/#upgrade-workers","text":"Log on to cka002 . Download kubeadm with version v1.24.2 . sudo apt-get -y install kubeadm=1.24.2-00 --allow-downgrades Upgrade kubeadm . sudo kubeadm upgrade node Upgrade kubelet . sudo apt-get -y install kubelet=1.24.2-00 --allow-downgrades sudo systemctl daemon-reload sudo systemctl restart kubelet Make sure all nodes are in Ready status, then, enable node scheduling. kubectl uncordon kubectl uncordon cka002","title":"Upgrade Workers"},{"location":"k8s/cka_en/foundamentals/clustermgt/#verify-upgrade","text":"Check node status. kubectl get node Result NAME STATUS ROLES AGE VERSION cka001 Ready control-plane,master 32h v1.24.2 cka002 Ready 32h v1.24.2 cka003 Ready 32h v1.24.0 Repeat the same on node cka003 . Log onto cka001 . If have error on dependency of emptydir , use the 2 nd command. kubectl drain cka003 --ignore-daemonsets --ignore-daemonsets --force kubectl drain cka003 --ignore-daemonsets --ignore-daemonsets --delete-emptydir-data --force Log onto cka003 and perform below commands. sudo apt-get -y install kubeadm=1.24.2-00 --allow-downgrades sudo kubeadm upgrade node sudo apt-get -y install kubelet=1.24.2-00 --allow-downgrades sudo systemctl daemon-reload sudo systemctl restart kubelet kubectl get node kubectl uncordon cka003 Get final status of all nodes. kubectl get node NAME STATUS ROLES AGE VERSION cka001 Ready control-plane,master 32h v1.24.2 cka002 Ready 32h v1.24.2 cka003 Ready 32h v1.24.2 Summary: Control Plane kubectl get node -owide kubectl drain cka001 --ignore-daemonsets kubectl get node -owide apt policy kubeadm apt-get -y install kubeadm=1.24.0-00 --allow-downgrades kubeadm upgrade plan kubeadm upgrade apply v1.24.0 # kubeadm upgrade apply v1.24.0 --etcd-upgrade = false apt-get -y install kubelet=1.24.0-00 kubectl=1.24.0-00 --allow-downgrades systemctl daemon-reload systemctl restart kubelet kubectl get node kubectl uncordon cka001 Worker Node On Control Plane kubectl drain cka002 --ignore-daemonsets On Workder Node apt-get -y install kubeadm=1.24.1-00 --allow-downgrades kubeadm upgrade node apt-get -y install kubelet=1.24.1-00 --allow-downgrades systemctl daemon-reload systemctl restart kubelet kubectl uncordon cka002 Repeat for other Worker nodes","title":"Verify Upgrade"},{"location":"k8s/cka_en/foundamentals/configuration/","text":"","title":"Configuration"},{"location":"k8s/cka_en/foundamentals/daemonset/","text":"DaemonSet \u00b6 Scenario: Create DaemonSet. The DaemonSet will run its pod on each node. Demo: Create DaemonSet daemonset-busybox . kubectl apply -f - << EOF apiVersion: apps/v1 kind: DaemonSet metadata: name: daemonset-busybox labels: app: daemonset-busybox spec: selector: matchLabels: app: daemonset-busybox template: metadata: labels: app: daemonset-busybox spec: tolerations: - key: node-role.kubernetes.io/control-plane effect: NoSchedule - key: node-role.kubernetes.io/master effect: NoSchedule containers: - name: busybox image: busybox:1.28 args: - sleep - \"10000\" EOF Get status of DaemonSet. kubectl get daemonsets daemonset-busybox Result NAME DESIRED CURRENT READY UP-TO-DATE AVAILABLE NODE SELECTOR AGE daemonset-busybox 3 3 3 3 3 5m33s Get DaemonSet Pod status. It's deployed on each node. kubectl get pod -o wide Result NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES daemonset-busybox-54cj5 1/1 Running 0 44s 10.244.102.4 cka003 daemonset-busybox-5tl55 1/1 Running 0 44s 10.244.228.197 cka001 daemonset-busybox-wg225 1/1 Running 0 44s 10.244.112.5 cka002 Clean up. kubectl delete daemonset daemonset-busybox","title":"DaemonSet"},{"location":"k8s/cka_en/foundamentals/daemonset/#daemonset","text":"Scenario: Create DaemonSet. The DaemonSet will run its pod on each node. Demo: Create DaemonSet daemonset-busybox . kubectl apply -f - << EOF apiVersion: apps/v1 kind: DaemonSet metadata: name: daemonset-busybox labels: app: daemonset-busybox spec: selector: matchLabels: app: daemonset-busybox template: metadata: labels: app: daemonset-busybox spec: tolerations: - key: node-role.kubernetes.io/control-plane effect: NoSchedule - key: node-role.kubernetes.io/master effect: NoSchedule containers: - name: busybox image: busybox:1.28 args: - sleep - \"10000\" EOF Get status of DaemonSet. kubectl get daemonsets daemonset-busybox Result NAME DESIRED CURRENT READY UP-TO-DATE AVAILABLE NODE SELECTOR AGE daemonset-busybox 3 3 3 3 3 5m33s Get DaemonSet Pod status. It's deployed on each node. kubectl get pod -o wide Result NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES daemonset-busybox-54cj5 1/1 Running 0 44s 10.244.102.4 cka003 daemonset-busybox-5tl55 1/1 Running 0 44s 10.244.228.197 cka001 daemonset-busybox-wg225 1/1 Running 0 44s 10.244.112.5 cka002 Clean up. kubectl delete daemonset daemonset-busybox","title":"DaemonSet"},{"location":"k8s/cka_en/foundamentals/deployment/","text":"Deployment \u00b6 Scenario: Modify Existing Deployment, e.g., add port number in below demo. Demo: Create Deployment nginx . kubectl create deployment nginx --image = nginx Execute command below to get yaml template with port number. The option --port=8080 specified the port that this container exposes. kubectl create deployment nginx --image = nginx --port = 8080 --dry-run = client -o yaml Then we get to know the path to add port number, like below. kubectl explain deployment.spec.template.spec.containers.ports.containerPort Execute command below to edit the Deployemnt. kubectl edit deployment nginx Add below two lines to specify port number with 8080 and protocol is TCP . spec : template : spec : containers : - image : nginx name : nginx ports : - containerPort : 8080 protocol : TCP Use command kubectl describe deployment , we can see the port number was added. Pod Template : Labels : app=nginx Containers : nginx : Image : nginx Port : 8080/TCP Host Port : 0/TCP Environment : Mounts : Volumes : With command kubectl describe pod , we can see the port number was added. Containers : nginx : Container ID : containerd://af4a1243f981497074b5c006ac55fcf795688399871d1dfe91a095321f5c91aa Image : nginx Image ID : docker.io/library/nginx@sha256:1761fb5661e4d77e107427d8012ad3a5955007d997e0f4a3d41acc9ff20467c7 Port : 8080/TCP Host Port : 0/TCP State : Running Started : Sun, 24 Jul 2022 22:50:12 +0800 Ready : True Restart Count : 0 Environment : Mounts : /var/run/secrets/kubernetes.io/serviceaccount from kube-api-access-hftdt (ro) Info: Some key fields of deployment (use kubectl explain ): deployment.spec.revisionHistoryLimit : The number of old ReplicaSets to retain to allow rollback. Defaults to 10 . deployment.spec.strategy.type : Type of deployment. Can be Recreate or RollingUpdate . Default is RollingUpdate . deployment.spec.strategy.rollingUpdate.maxUnavailable : The maximum number of pods that can be unavailable during the update. Defaults to 25%. deployment.spec.strategy.rollingUpdate.maxSurge : The maximum number of pods that can be scheduled above the desired number of pods. Defaults to 25%. This can not be 0 if MaxUnavailable is 0. deployment.spec.minReadySeconds : Minimum number of seconds for which a newly created pod should be ready without any of its container crashing, for it to be considered available. Defaults to 0 (pod will be considered available as soon as it is ready).","title":"Deployment"},{"location":"k8s/cka_en/foundamentals/deployment/#deployment","text":"Scenario: Modify Existing Deployment, e.g., add port number in below demo. Demo: Create Deployment nginx . kubectl create deployment nginx --image = nginx Execute command below to get yaml template with port number. The option --port=8080 specified the port that this container exposes. kubectl create deployment nginx --image = nginx --port = 8080 --dry-run = client -o yaml Then we get to know the path to add port number, like below. kubectl explain deployment.spec.template.spec.containers.ports.containerPort Execute command below to edit the Deployemnt. kubectl edit deployment nginx Add below two lines to specify port number with 8080 and protocol is TCP . spec : template : spec : containers : - image : nginx name : nginx ports : - containerPort : 8080 protocol : TCP Use command kubectl describe deployment , we can see the port number was added. Pod Template : Labels : app=nginx Containers : nginx : Image : nginx Port : 8080/TCP Host Port : 0/TCP Environment : Mounts : Volumes : With command kubectl describe pod , we can see the port number was added. Containers : nginx : Container ID : containerd://af4a1243f981497074b5c006ac55fcf795688399871d1dfe91a095321f5c91aa Image : nginx Image ID : docker.io/library/nginx@sha256:1761fb5661e4d77e107427d8012ad3a5955007d997e0f4a3d41acc9ff20467c7 Port : 8080/TCP Host Port : 0/TCP State : Running Started : Sun, 24 Jul 2022 22:50:12 +0800 Ready : True Restart Count : 0 Environment : Mounts : /var/run/secrets/kubernetes.io/serviceaccount from kube-api-access-hftdt (ro) Info: Some key fields of deployment (use kubectl explain ): deployment.spec.revisionHistoryLimit : The number of old ReplicaSets to retain to allow rollback. Defaults to 10 . deployment.spec.strategy.type : Type of deployment. Can be Recreate or RollingUpdate . Default is RollingUpdate . deployment.spec.strategy.rollingUpdate.maxUnavailable : The maximum number of pods that can be unavailable during the update. Defaults to 25%. deployment.spec.strategy.rollingUpdate.maxSurge : The maximum number of pods that can be scheduled above the desired number of pods. Defaults to 25%. This can not be 0 if MaxUnavailable is 0. deployment.spec.minReadySeconds : Minimum number of seconds for which a newly created pod should be ready without any of its container crashing, for it to be considered available. Defaults to 0 (pod will be considered available as soon as it is ready).","title":"Deployment"},{"location":"k8s/cka_en/foundamentals/docker/","text":"Docker Fundamentals \u00b6 Demo environment \u00b6 Linux: openSUSE 15.3 cat /etc/os-release Output NAME=\"openSUSE Leap\" VERSION=\"15.3\" ID=\"opensuse-leap\" ID_LIKE=\"suse opensuse\" VERSION_ID=\"15.3\" PRETTY_NAME=\"openSUSE Leap 15.3\" ANSI_COLOR=\"0;32\" CPE_NAME=\"cpe:/o:opensuse:leap:15.3\" BUG_REPORT_URL=\"https://bugs.opensuse.org\" HOME_URL=\"https://www.opensuse.org/\" Linux Primitives \u00b6 chroot(using pivot_root) Changes the root directory for a process to any given directory namespaces Different processes see different environments even though they are on the same host/OS mnt (mount points) pid (process tree) net (network interfaces and connectivity) ipc (interprocess communication framework) uts (unix timesharing - domain name, hostname, etc.) uid (user IDs and mappings) cgroups(control groups) manage/limit resource allocation to individual processes Prioritization of processes Apparmor and SELinux profiles Security profiles to govern access to resources Kernel capabilities without capabilities: root can do everything, everybody else may do nothing 38 granular facilities to control privileges seccomp policies Limitation of allowed kernel syscalls Unallowed syscalls lead to process termination Netlink A Linux kernel interface used for inter-process communication (IPC) between both the kernel and userspace processes, and between different userspace processes. Netfilter A framework provided by the Linux kernel that allows various networking-related operations Packet filtering, network address translation, and port translation(iptables/nftables) used to direct network packages to individual containers More inforamtion could refer to LXC/LXD Let's download an image alpine to simulate an root file system under /opt/test folder. mkdir test cd test wget https://dl-cdn.alpinelinux.org/alpine/v3.13/releases/x86_64/alpine-minirootfs-3.13.4-x86_64.tar.gz tar zxvf alpine-minirootfs-3.13.4-x86_64.tar.gz -C alpine-minirootfs/ Current directory structure. tree ./test -L 1 Output ./test \u251c\u2500\u2500 alpine-minirootfs-3.13.4-x86_64.tar.gz \u251c\u2500\u2500 bin \u251c\u2500\u2500 dev \u251c\u2500\u2500 etc \u251c\u2500\u2500 home \u251c\u2500\u2500 lib \u251c\u2500\u2500 media \u251c\u2500\u2500 mnt \u251c\u2500\u2500 opt \u251c\u2500\u2500 proc \u251c\u2500\u2500 root \u251c\u2500\u2500 run \u251c\u2500\u2500 sbin \u251c\u2500\u2500 srv \u251c\u2500\u2500 sys \u251c\u2500\u2500 tmp \u251c\u2500\u2500 usr \u2514\u2500\u2500 var Mount folder /opt/test/proc to a file and use command unshare to build a guest system. sudo mount -t tmpfs tmpfs /opt/test/proc sudo unshare --pid --mount-proc = $PWD /test/proc --fork chroot ./test/ /bin/sh / # ps -ef PID USER TIME COMMAND 1 root 0 :00 /bin/sh 2 root 0 :00 ps -ef / # touch 123 / # ls 123 123 The file 123 created in guest system is accessable and writable from host system. su - ls 123 echo hello > 123 We will see above change in guest system. / # cat 123 hello Let's create two folders /opt/test-1 and /opt/test-2 . mkdir test-1 mkdir test-2 Create two guests system. Mount /opt/test/home/ to different folders for different guests. sudo mount --bind /opt/test-1 /opt/test/home/ sudo unshare --pid --mount-proc = $PWD /test/proc --fork chroot ./test/ /bin/sh / # cd /home /home # echo \"test-1\" > 123.1 /home # cat 123.1 test-1 sudo mount --bind /opt/test-2 /opt/test/home/ sudo unshare --pid --mount-proc = $PWD /test/proc --fork chroot ./test/ /bin/sh / # cd /home /home # echo \"test-2\" > 123.2 /home # cat 123.2 test-2 ll test/home ll test-1/ ll test-2/ With above demo, the conclusion is that two guests share same home folder on host system and will impact each other. Installing Docker \u00b6 Install Docker engine by referring the guide , and Docker Desktop by referring the guide . Install engine via openSUSE repository automatically. sudo zypper in docker The docker group is automatically created at package installation time. The user can communicate with the local Docker daemon upon its next login. The Docker daemon listens on a local socket which is accessible only by the root user and by the members of the docker group. Add current user to docker group. sudo usermod -aG docker $USER Enable and start Docker engine. sudo systemctl enable docker.service sudo systemctl start docker.service sudo systemctl status docker.service Container lifecycle \u00b6 Overview \u00b6 Pull down below images in advance. docker image pull busybox docker image pull nginx docker image pull alpine docker image pull jenkins/jenkins:lts docker image pull golang:1.12-alpine docker image pull golang Download some docker images. Create and run a new busybox container interactively and connect a pseudo terminal to it. Inside the container, use the top command to find out that /bin/sh is running as process with the PID 1 and top process is also running. After that, just exit. docker image ls docker run -d -it --name busybox_v1 -v /opt/test:/docker busybox:latest /bin/sh docker container ps -a docker exec -it 185efe490507 /bin/sh / # top Mem: 3627396K used, 12731512K free, 10080K shrd, 2920K buff, 2999340K cached CPU: 0 .0% usr 0 .1% sys 0 .0% nic 99 .8% idle 0 .0% io 0 .0% irq 0 .0% sirq Load average: 0 .38 1 .09 1 .29 2 /277 14 PID PPID USER STAT VSZ %VSZ CPU %CPU COMMAND 1 0 root S 1332 0 .0 1 0 .0 /bin/sh 8 0 root S 1332 0 .0 2 0 .0 /bin/sh 14 8 root R 1328 0 .0 1 0 .0 top / # exitbuild Start a new nginx container in detached mode. Use the docker exec command to start another shell ( /bin/sh ) in the nginx container. Use ps to find out that sh and ps commands are running in your container. docker run -d -it --name nginx_v1 -v /opt/test:/docker nginx:latest /bin/sh docker container ps -a docker exec -it edb640127a0d /bin/sh # ps /bin/sh: 2 : ps: not found # apt-get update && apt-get install -y procps # ps PID TTY TIME CMD 8 pts/1 00 :00:00 sh 351 pts/1 00 :00:00 ps # exit Now we have two running containers below. docker container ps -a Let's use docker logs to display the logs of the container we just exited from. The option --since 35m means display log in last 35 minutes. docker logs nginx_v1 --details --since 35m docker logs busybox_v1 --details --since 35m Let's make use of this to create a new stage: Use the docker stop command to end your nginx container. docker stop busybox_v1 docker stop nginx_v1 docker container ps -a With above command docker container ps -a , we get a list of all running and exited containers. Remove them with docker rm. Use docker rm $(docker ps -aq) to clean up all containers on your host. Use it with caution! docker rm busybox_v1 docker container ps -a Ports and volumes \u00b6 Now, let's run an nginx webserver in a container and serve a website to the outside world. Start a new nginx container and export the port of the nginx webserver to a random port that is chosen by Docker. Use command docker ps to find you which port the webserver is forwarded. Access the docker with the forwarded port number on host http://localhost: . docker container ps -a docker run -d -P --name nginx_v2 nginx:latest docker container ps -a Start another nginx container and expose port to 1080 on host as an example via http://localhost:1080 . docker run -d -p 1080:80 --name nginx_v3 nginx:latest docker container ps -a Let's make use of this to create a new stage: Use command docker inspect to find out which port is exposed by the image. Network information (ip, gateway, ports, etc.) is part of the output JSON format. docker inspect nginx_v3 Create a file index.html in folder /opt/test with below sample content. < html > < head > < title > Sample Website from my container < body > < h1 > This is a custom website. < p > This website is served from my < a href = \"http://www.docker.com\" target = \"_blank\" > Docker container. Start a new container that bind-mounts host directory /opt/test to container directory /usr/share/nginx/html as a volume, so that NGINX will publish the HTML file wee just created instead of its default message via http://localhost:49159/ below. docker run -d -P --mount type=bind,source=/opt/test/,target=/usr/share/nginx/html --name nginx_v3-1 nginx:latest docker container ps -a Check nginx config file on where is the html home page stored in container. docker exec -it nginx_v3-1 /bin/sh # cd /etc/nginx/conf.d # ls default.conf # cat default.conf server { listen 80; listen [::]:80; server_name localhost; # access_log /var/log/nginx/host.access.log main ; location / { root /usr/share/nginx/html; <-- index index.html index.htm; } # error_page 404 /404.html ; # redirect server error pages to the static page /50x.html # error_page 500 502 503 504 /50x.html; location = /50x.html { root /usr/share/nginx/html; } # proxy the PHP scripts to Apache listening on 127 .0.0.1:80 # # location ~ \\. php$ { # proxy_pass http://127.0.0.1 ; # } # pass the PHP scripts to FastCGI server listening on 127 .0.0.1:9000 # # location ~ \\. php$ { # root html ; # fastcgi_pass 127 .0.0.1:9000 ; # fastcgi_index index.php ; # fastcgi_param SCRIPT_FILENAME /scripts $fastcgi_script_name ; # include fastcgi_params ; # } # deny access to .htaccess files, if Apache 's document root # concurs with nginx' s one # # location ~ / \\. ht { # deny all ; # } } # cd /usr/share/nginx/html # cat index.html Sample Website from my container

This is a custom website.

This website is served from my Docker container.

# It's recommendable to add a persistence with volumes API, instead of storing data in a docker container. Docker supports 2 ways of mount: Bind mounts: mount a local host directory onto a certain path in the container. Everything that was present before in the target directory is hidden (nature of the bind mount). For example, if you have some configuration you want to inject, write your config file, store it on your docker host at /home/container/config and mount the content of this directory to /usr/application/config (assuming the application reads config from there). Command: docker run --mount type=bind,source=,target= \u2026 Named volumes: docker can create a separated storage volume. Its lifecycle is independent from the container but still managed by docker. Upon creation, the content of the mount target is merged into the volume. Command: docker run --mount source=,target= \u2026 How to differentiate between bind mountbuild s and named volumes? When specifying an absolute path, docker assumes a bind mount. When you just give a name (like in a relative path \u201cconfig\u201d), it will assume a named volume and create a volume \u201cconfig\u201d. Note: Persistent storage is 'provided' by the host. It can be a part of the file system on the host directly but also an NFS mount. Dockerfile \u00b6 Let's build an image with a Dockerfile,build tag it and upload it to a registry. Get docker image build history. docker image history nginx:latest Create an empty directory /opt/tmp-1 , change to the directory and create an sample index.html file in /opt/tmp-1 . /opt/tmp-1> cat index.html Sample Website from my container

This is a custom website.

This website is served from my Docker container.

Use FROM to extend an existing image, specify the release number. Use COPY to copy a new default website into the image, e.g., /usr/share/nginx/html Create SSL configuration /opt/tmp-1/ssl.conf for nginx. server { listen 443 ssl; server_name localhost; ssl_certificate /etc/nginx/ssl/nginx.crt; ssl_certificate_key /etc/nginx/ssl/nginx.key; location / { root /usr/share/nginx/html; index index.html index.htm; } } Use OpenSSL to create a self-signed certificate so SSL/TLS to work would work. Use the following command to create an encryption key and a certificate. openssl req -x509 -nodes -newkey rsa:4096 -keyout nginx.key -out nginx.crt -days 365 -subj \"/CN=$(hostname)\" To enable encrypted HTTPS, we need to expose port 443 with the EXPOSE directive. The default nginx image only exposes port 80 for unencrypted HTTP. In summary, we create below Dockerfile in foder /opt/tmp-1 . cat Dockerfile Output FROM nginx:latest # copy the custom website into the image COPY index.html /usr/share/nginx/html # copy the SSL configuration file into the image COPY ssl.conf /etc/nginx/conf.d/ssl.conf # download the SSL key and certificate into the image COPY nginx.key /etc/nginx/ssl/ COPY nginx.crt /etc/nginx/ssl/ # expose the HTTPS port EXPOSE 443 We have five files in foder /opt/tmp-1 till now. ls /opt/tmp-1 Output Dockerfile index.html nginx.crt nginx.key ssl.conf Now let's use the docker build command to build the image, forward the containers ports 80 and 443. docker build -t nginx:my1 /opt/tmp-1/ docker image ls docker run -d -p 1086:80 -p 1088:443 --name nginx_v5 nginx:my1 docker container ps -a Above changes can be validated via below links: http://localhost:1086/ https://localhost:1088/ Register an account in DockerHub and enable access token in Docker Hub for CLI client authentication. docker login Input username and password. Username: Password: Tag the image to give image a nice name and a release number as tag, e.g., name is secure_nginx_0001 , tag is v1 . docker tag nginx:my1 secure_nginx_0001:v1 docker push secure_nginx_0001:v1 docker image ls Multi-stage Dockerfile \u00b6 Let's show an example of multi-stage build. The multi-stage in the context of Docker means, we can have more than one line with a FROM keyword. Create folder /opt/tmp-2 and /opt/tmp-2/tmpl . Create files edit.html , view.html , wiki.go and structure likes below. tree -l /opt/tmp-2 . \u251c\u2500\u2500 tmpl \u2502 \u251c\u2500\u2500 edit.html \u2502 \u2514\u2500\u2500 view.html \u2514\u2500\u2500 wiki.go Create an new Dockerfile that starts cat Dockerfile # app builder stage FROM golang:1.12-alpine as builder ## copy the go source code over and build the binary WORKDIR /go/src COPY wiki.go /go/src/wiki.go RUN go build wiki.go # app exec stage # separate & new image starts here!# FROM alpine:3.9 # prepare file system etc RUN mkdir -p /app/data /app/tmpl && adduser -S -D -H -h /app appuser COPY tmpl/* /app/tmpl/ # get the compiled binary from the previous stage COPY --from = builder /go/src/wiki /app/wiki # prepare runtime env RUN chown -R appuser /app USER appuser WORKDIR /app # expose app port & set default command EXPOSE 8080 CMD [ \"/app/wiki\" ] Build the images by Dockerfile we created above. docker build -t lizard/golang:my1 /opt/tmp-2/ Run the image in detached mode, create a port forwarding from port 8080 in the container to port 1090 on the host. docker run -d -p 1090:8080 --name golan_v1 lizard/golang:my1 Access the container via link http://localhost:1090 Tab the golang image we created and push it to DockerHub. docker tag lizard/golang:my1 /golang_0001:v1 docker push /golang_0001:v1","title":"Fundamentals"},{"location":"k8s/cka_en/foundamentals/docker/#docker-fundamentals","text":"","title":"Docker Fundamentals"},{"location":"k8s/cka_en/foundamentals/docker/#demo-environment","text":"Linux: openSUSE 15.3 cat /etc/os-release Output NAME=\"openSUSE Leap\" VERSION=\"15.3\" ID=\"opensuse-leap\" ID_LIKE=\"suse opensuse\" VERSION_ID=\"15.3\" PRETTY_NAME=\"openSUSE Leap 15.3\" ANSI_COLOR=\"0;32\" CPE_NAME=\"cpe:/o:opensuse:leap:15.3\" BUG_REPORT_URL=\"https://bugs.opensuse.org\" HOME_URL=\"https://www.opensuse.org/\"","title":"Demo environment"},{"location":"k8s/cka_en/foundamentals/docker/#linux-primitives","text":"chroot(using pivot_root) Changes the root directory for a process to any given directory namespaces Different processes see different environments even though they are on the same host/OS mnt (mount points) pid (process tree) net (network interfaces and connectivity) ipc (interprocess communication framework) uts (unix timesharing - domain name, hostname, etc.) uid (user IDs and mappings) cgroups(control groups) manage/limit resource allocation to individual processes Prioritization of processes Apparmor and SELinux profiles Security profiles to govern access to resources Kernel capabilities without capabilities: root can do everything, everybody else may do nothing 38 granular facilities to control privileges seccomp policies Limitation of allowed kernel syscalls Unallowed syscalls lead to process termination Netlink A Linux kernel interface used for inter-process communication (IPC) between both the kernel and userspace processes, and between different userspace processes. Netfilter A framework provided by the Linux kernel that allows various networking-related operations Packet filtering, network address translation, and port translation(iptables/nftables) used to direct network packages to individual containers More inforamtion could refer to LXC/LXD Let's download an image alpine to simulate an root file system under /opt/test folder. mkdir test cd test wget https://dl-cdn.alpinelinux.org/alpine/v3.13/releases/x86_64/alpine-minirootfs-3.13.4-x86_64.tar.gz tar zxvf alpine-minirootfs-3.13.4-x86_64.tar.gz -C alpine-minirootfs/ Current directory structure. tree ./test -L 1 Output ./test \u251c\u2500\u2500 alpine-minirootfs-3.13.4-x86_64.tar.gz \u251c\u2500\u2500 bin \u251c\u2500\u2500 dev \u251c\u2500\u2500 etc \u251c\u2500\u2500 home \u251c\u2500\u2500 lib \u251c\u2500\u2500 media \u251c\u2500\u2500 mnt \u251c\u2500\u2500 opt \u251c\u2500\u2500 proc \u251c\u2500\u2500 root \u251c\u2500\u2500 run \u251c\u2500\u2500 sbin \u251c\u2500\u2500 srv \u251c\u2500\u2500 sys \u251c\u2500\u2500 tmp \u251c\u2500\u2500 usr \u2514\u2500\u2500 var Mount folder /opt/test/proc to a file and use command unshare to build a guest system. sudo mount -t tmpfs tmpfs /opt/test/proc sudo unshare --pid --mount-proc = $PWD /test/proc --fork chroot ./test/ /bin/sh / # ps -ef PID USER TIME COMMAND 1 root 0 :00 /bin/sh 2 root 0 :00 ps -ef / # touch 123 / # ls 123 123 The file 123 created in guest system is accessable and writable from host system. su - ls 123 echo hello > 123 We will see above change in guest system. / # cat 123 hello Let's create two folders /opt/test-1 and /opt/test-2 . mkdir test-1 mkdir test-2 Create two guests system. Mount /opt/test/home/ to different folders for different guests. sudo mount --bind /opt/test-1 /opt/test/home/ sudo unshare --pid --mount-proc = $PWD /test/proc --fork chroot ./test/ /bin/sh / # cd /home /home # echo \"test-1\" > 123.1 /home # cat 123.1 test-1 sudo mount --bind /opt/test-2 /opt/test/home/ sudo unshare --pid --mount-proc = $PWD /test/proc --fork chroot ./test/ /bin/sh / # cd /home /home # echo \"test-2\" > 123.2 /home # cat 123.2 test-2 ll test/home ll test-1/ ll test-2/ With above demo, the conclusion is that two guests share same home folder on host system and will impact each other.","title":"Linux Primitives"},{"location":"k8s/cka_en/foundamentals/docker/#installing-docker","text":"Install Docker engine by referring the guide , and Docker Desktop by referring the guide . Install engine via openSUSE repository automatically. sudo zypper in docker The docker group is automatically created at package installation time. The user can communicate with the local Docker daemon upon its next login. The Docker daemon listens on a local socket which is accessible only by the root user and by the members of the docker group. Add current user to docker group. sudo usermod -aG docker $USER Enable and start Docker engine. sudo systemctl enable docker.service sudo systemctl start docker.service sudo systemctl status docker.service","title":"Installing Docker"},{"location":"k8s/cka_en/foundamentals/docker/#container-lifecycle","text":"","title":"Container lifecycle"},{"location":"k8s/cka_en/foundamentals/docker/#overview","text":"Pull down below images in advance. docker image pull busybox docker image pull nginx docker image pull alpine docker image pull jenkins/jenkins:lts docker image pull golang:1.12-alpine docker image pull golang Download some docker images. Create and run a new busybox container interactively and connect a pseudo terminal to it. Inside the container, use the top command to find out that /bin/sh is running as process with the PID 1 and top process is also running. After that, just exit. docker image ls docker run -d -it --name busybox_v1 -v /opt/test:/docker busybox:latest /bin/sh docker container ps -a docker exec -it 185efe490507 /bin/sh / # top Mem: 3627396K used, 12731512K free, 10080K shrd, 2920K buff, 2999340K cached CPU: 0 .0% usr 0 .1% sys 0 .0% nic 99 .8% idle 0 .0% io 0 .0% irq 0 .0% sirq Load average: 0 .38 1 .09 1 .29 2 /277 14 PID PPID USER STAT VSZ %VSZ CPU %CPU COMMAND 1 0 root S 1332 0 .0 1 0 .0 /bin/sh 8 0 root S 1332 0 .0 2 0 .0 /bin/sh 14 8 root R 1328 0 .0 1 0 .0 top / # exitbuild Start a new nginx container in detached mode. Use the docker exec command to start another shell ( /bin/sh ) in the nginx container. Use ps to find out that sh and ps commands are running in your container. docker run -d -it --name nginx_v1 -v /opt/test:/docker nginx:latest /bin/sh docker container ps -a docker exec -it edb640127a0d /bin/sh # ps /bin/sh: 2 : ps: not found # apt-get update && apt-get install -y procps # ps PID TTY TIME CMD 8 pts/1 00 :00:00 sh 351 pts/1 00 :00:00 ps # exit Now we have two running containers below. docker container ps -a Let's use docker logs to display the logs of the container we just exited from. The option --since 35m means display log in last 35 minutes. docker logs nginx_v1 --details --since 35m docker logs busybox_v1 --details --since 35m Let's make use of this to create a new stage: Use the docker stop command to end your nginx container. docker stop busybox_v1 docker stop nginx_v1 docker container ps -a With above command docker container ps -a , we get a list of all running and exited containers. Remove them with docker rm. Use docker rm $(docker ps -aq) to clean up all containers on your host. Use it with caution! docker rm busybox_v1 docker container ps -a","title":"Overview"},{"location":"k8s/cka_en/foundamentals/docker/#ports-and-volumes","text":"Now, let's run an nginx webserver in a container and serve a website to the outside world. Start a new nginx container and export the port of the nginx webserver to a random port that is chosen by Docker. Use command docker ps to find you which port the webserver is forwarded. Access the docker with the forwarded port number on host http://localhost: . docker container ps -a docker run -d -P --name nginx_v2 nginx:latest docker container ps -a Start another nginx container and expose port to 1080 on host as an example via http://localhost:1080 . docker run -d -p 1080:80 --name nginx_v3 nginx:latest docker container ps -a Let's make use of this to create a new stage: Use command docker inspect to find out which port is exposed by the image. Network information (ip, gateway, ports, etc.) is part of the output JSON format. docker inspect nginx_v3 Create a file index.html in folder /opt/test with below sample content. < html > < head > < title > Sample Website from my container < body > < h1 > This is a custom website. < p > This website is served from my < a href = \"http://www.docker.com\" target = \"_blank\" > Docker container. Start a new container that bind-mounts host directory /opt/test to container directory /usr/share/nginx/html as a volume, so that NGINX will publish the HTML file wee just created instead of its default message via http://localhost:49159/ below. docker run -d -P --mount type=bind,source=/opt/test/,target=/usr/share/nginx/html --name nginx_v3-1 nginx:latest docker container ps -a Check nginx config file on where is the html home page stored in container. docker exec -it nginx_v3-1 /bin/sh # cd /etc/nginx/conf.d # ls default.conf # cat default.conf server { listen 80; listen [::]:80; server_name localhost; # access_log /var/log/nginx/host.access.log main ; location / { root /usr/share/nginx/html; <-- index index.html index.htm; } # error_page 404 /404.html ; # redirect server error pages to the static page /50x.html # error_page 500 502 503 504 /50x.html; location = /50x.html { root /usr/share/nginx/html; } # proxy the PHP scripts to Apache listening on 127 .0.0.1:80 # # location ~ \\. php$ { # proxy_pass http://127.0.0.1 ; # } # pass the PHP scripts to FastCGI server listening on 127 .0.0.1:9000 # # location ~ \\. php$ { # root html ; # fastcgi_pass 127 .0.0.1:9000 ; # fastcgi_index index.php ; # fastcgi_param SCRIPT_FILENAME /scripts $fastcgi_script_name ; # include fastcgi_params ; # } # deny access to .htaccess files, if Apache 's document root # concurs with nginx' s one # # location ~ / \\. ht { # deny all ; # } } # cd /usr/share/nginx/html # cat index.html Sample Website from my container

This is a custom website.

This website is served from my Docker container.

# It's recommendable to add a persistence with volumes API, instead of storing data in a docker container. Docker supports 2 ways of mount: Bind mounts: mount a local host directory onto a certain path in the container. Everything that was present before in the target directory is hidden (nature of the bind mount). For example, if you have some configuration you want to inject, write your config file, store it on your docker host at /home/container/config and mount the content of this directory to /usr/application/config (assuming the application reads config from there). Command: docker run --mount type=bind,source=,target= \u2026 Named volumes: docker can create a separated storage volume. Its lifecycle is independent from the container but still managed by docker. Upon creation, the content of the mount target is merged into the volume. Command: docker run --mount source=,target= \u2026 How to differentiate between bind mountbuild s and named volumes? When specifying an absolute path, docker assumes a bind mount. When you just give a name (like in a relative path \u201cconfig\u201d), it will assume a named volume and create a volume \u201cconfig\u201d. Note: Persistent storage is 'provided' by the host. It can be a part of the file system on the host directly but also an NFS mount.","title":"Ports and volumes"},{"location":"k8s/cka_en/foundamentals/docker/#dockerfile","text":"Let's build an image with a Dockerfile,build tag it and upload it to a registry. Get docker image build history. docker image history nginx:latest Create an empty directory /opt/tmp-1 , change to the directory and create an sample index.html file in /opt/tmp-1 . /opt/tmp-1> cat index.html Sample Website from my container

This is a custom website.

This website is served from my Docker container.

Use FROM to extend an existing image, specify the release number. Use COPY to copy a new default website into the image, e.g., /usr/share/nginx/html Create SSL configuration /opt/tmp-1/ssl.conf for nginx. server { listen 443 ssl; server_name localhost; ssl_certificate /etc/nginx/ssl/nginx.crt; ssl_certificate_key /etc/nginx/ssl/nginx.key; location / { root /usr/share/nginx/html; index index.html index.htm; } } Use OpenSSL to create a self-signed certificate so SSL/TLS to work would work. Use the following command to create an encryption key and a certificate. openssl req -x509 -nodes -newkey rsa:4096 -keyout nginx.key -out nginx.crt -days 365 -subj \"/CN=$(hostname)\" To enable encrypted HTTPS, we need to expose port 443 with the EXPOSE directive. The default nginx image only exposes port 80 for unencrypted HTTP. In summary, we create below Dockerfile in foder /opt/tmp-1 . cat Dockerfile Output FROM nginx:latest # copy the custom website into the image COPY index.html /usr/share/nginx/html # copy the SSL configuration file into the image COPY ssl.conf /etc/nginx/conf.d/ssl.conf # download the SSL key and certificate into the image COPY nginx.key /etc/nginx/ssl/ COPY nginx.crt /etc/nginx/ssl/ # expose the HTTPS port EXPOSE 443 We have five files in foder /opt/tmp-1 till now. ls /opt/tmp-1 Output Dockerfile index.html nginx.crt nginx.key ssl.conf Now let's use the docker build command to build the image, forward the containers ports 80 and 443. docker build -t nginx:my1 /opt/tmp-1/ docker image ls docker run -d -p 1086:80 -p 1088:443 --name nginx_v5 nginx:my1 docker container ps -a Above changes can be validated via below links: http://localhost:1086/ https://localhost:1088/ Register an account in DockerHub and enable access token in Docker Hub for CLI client authentication. docker login Input username and password. Username: Password: Tag the image to give image a nice name and a release number as tag, e.g., name is secure_nginx_0001 , tag is v1 . docker tag nginx:my1 secure_nginx_0001:v1 docker push secure_nginx_0001:v1 docker image ls","title":"Dockerfile"},{"location":"k8s/cka_en/foundamentals/docker/#multi-stage-dockerfile","text":"Let's show an example of multi-stage build. The multi-stage in the context of Docker means, we can have more than one line with a FROM keyword. Create folder /opt/tmp-2 and /opt/tmp-2/tmpl . Create files edit.html , view.html , wiki.go and structure likes below. tree -l /opt/tmp-2 . \u251c\u2500\u2500 tmpl \u2502 \u251c\u2500\u2500 edit.html \u2502 \u2514\u2500\u2500 view.html \u2514\u2500\u2500 wiki.go Create an new Dockerfile that starts cat Dockerfile # app builder stage FROM golang:1.12-alpine as builder ## copy the go source code over and build the binary WORKDIR /go/src COPY wiki.go /go/src/wiki.go RUN go build wiki.go # app exec stage # separate & new image starts here!# FROM alpine:3.9 # prepare file system etc RUN mkdir -p /app/data /app/tmpl && adduser -S -D -H -h /app appuser COPY tmpl/* /app/tmpl/ # get the compiled binary from the previous stage COPY --from = builder /go/src/wiki /app/wiki # prepare runtime env RUN chown -R appuser /app USER appuser WORKDIR /app # expose app port & set default command EXPOSE 8080 CMD [ \"/app/wiki\" ] Build the images by Dockerfile we created above. docker build -t lizard/golang:my1 /opt/tmp-2/ Run the image in detached mode, create a port forwarding from port 8080 in the container to port 1090 on the host. docker run -d -p 1090:8080 --name golan_v1 lizard/golang:my1 Access the container via link http://localhost:1090 Tab the golang image we created and push it to DockerHub. docker tag lizard/golang:my1 /golang_0001:v1 docker push /golang_0001:v1","title":"Multi-stage Dockerfile"},{"location":"k8s/cka_en/foundamentals/healthcheck/","text":"Health Check \u00b6 Status of Pod and Container \u00b6 Scenario: Create a pod with two containers. Demo: Create a Pod multi-pods with two containers nginx and busybox . kubectl apply -f - << EOF apiVersion: v1 kind: Pod metadata: labels: run: multi-pods name: multi-pods spec: containers: - image: nginx name: nginx - image: busybox name: busybox dnsPolicy: ClusterFirst restartPolicy: Always EOF Minotor the status with option --watch . The status of Pod was changed from ContainerCreating to NotReady to CrashLoopBackOff . kubectl get pod multi-pods --watch Get details of the Pod multi-pods , focus on Container's state under segment Containers and Conditions of Pod under segment Conditions . kubectl describe pod multi-pods Result ...... Containers: nginx: ...... State: Running Started: Sat, 23 Jul 2022 15:06:56 +0800 Ready: True Restart Count: 0 ...... busybox: ...... State: Terminated Reason: Completed Exit Code: 0 ...... Conditions: Type Status Initialized True Ready False ContainersReady False PodScheduled True ...... LivenessProbe \u00b6 Scenario: Create pod with livenessProbe check. Detail description of the demo can be found on the Kubernetes document . Demo: Create a yaml file liveness.yaml with livenessProbe setting and apply it. kubectl apply -f - <> ~/.bashrc source <(helm completion bash) Install MySQL from Helm \u00b6 Add bitnami Chartes Repository. helm repo add bitnami https://charts.bitnami.com/bitnami Get current Charts repositories. helm repo list NAME URL bitnami https://charts.bitnami.com/bitnami Sync up local Charts repositories. helm repo update Search bitnami Charts in repositories. helm search repo bitnami Search bitnami/mysql Charts in repositories. helm search repo bitnami/mysql Install MySQL Chart on namespace dev \uff1a helm install mysql bitnami/mysql -n dev Output NAME: mysql LAST DEPLOYED: Sun Jul 24 19:37:20 2022 NAMESPACE: dev STATUS: deployed REVISION: 1 TEST SUITE: None NOTES: CHART NAME: mysql CHART VERSION: 9.2.1 APP VERSION: 8.0.29 ** Please be patient while the chart is being deployed ** Tip: Watch the deployment status using the command: kubectl get pods -w --namespace dev Services: echo Primary: mysql.dev.svc.cluster.local:3306 Execute the following to get the administrator credentials: echo Username: root MYSQL_ROOT_PASSWORD=$(kubectl get secret --namespace dev mysql -o jsonpath=\"{.data.mysql-root-password}\" | base64 -d) To connect to your database: 1. Run a pod that you can use as a client: kubectl run mysql-client --rm --tty -i --restart='Never' --image docker.io/bitnami/mysql:8.0.29-debian-11-r9 --namespace dev --env MYSQL_ROOT_PASSWORD=$MYSQL_ROOT_PASSWORD --command -- bash 2. To connect to primary service (read/write): mysql -h mysql.dev.svc.cluster.local -uroot -p\"$MYSQL_ROOT_PASSWORD\" Check installed release\uff1a helm list Result NAME NAMESPACE REVISION UPDATED STATUS CHART APP VERSION mysql dev 1 2022-07-24 19:37:20.710988009 +0800 CST deployed mysql-9.2.1 8.0.29 Check installed mysql release information. helm status mysql Check mysql Pod status. kubectl get pod Result NAME READY STATUS RESTARTS AGE mysql-0 1/1 Running 0 72s Develop a Chart \u00b6 Below is a demo on how to develop a Chart. Execute helm create to initiate a Chart\uff1a # Naming conventions of Chart: lowercase a~z and - ( minus sign ) helm create cka-demo A folder cka-demo was created. Check the folder structure. tree cka-demo/ Output cka-demo/ \u251c\u2500\u2500 charts \u251c\u2500\u2500 Chart.yaml \u251c\u2500\u2500 templates \u2502 \u251c\u2500\u2500 deployment.yaml \u2502 \u251c\u2500\u2500 _helpers.tpl \u2502 \u251c\u2500\u2500 hpa.yaml \u2502 \u251c\u2500\u2500 ingress.yaml \u2502 \u251c\u2500\u2500 NOTES.txt \u2502 \u251c\u2500\u2500 serviceaccount.yaml \u2502 \u251c\u2500\u2500 service.yaml \u2502 \u2514\u2500\u2500 tests \u2502 \u2514\u2500\u2500 test-connection.yaml \u2514\u2500\u2500 values.yaml Delete or empty some files, which will be re-created later. cd cka-demo rm -rf charts rm -rf templates/tests rm -rf templates/*.yaml echo \"\" > values.yaml echo \"\" > templates/NOTES.txt echo \"\" > templates/_helpers.tpl cd .. Now new structure looks like below. tree cka-demo/ Output cka-demo/ \u251c\u2500\u2500 Chart.yaml \u251c\u2500\u2500 templates \u2502 \u251c\u2500\u2500 _helpers.tpl \u2502 \u2514\u2500\u2500 NOTES.txt \u2514\u2500\u2500 values.yaml NOTES.txt \u00b6 NOTES.txt is used to provide summary information to Chart users. In the demo, we will use NOTES.txt to privide summary info about whether the user passed CKA certificate or not. cd cka-demo/ vi templates/NOTES.txt Add below info. {{- if .Values.passExam }} Congratulations! You have successfully completed Certified Kubernetes Administrator China Exam (CKA-CN). Your CKA score is: {{ .Values.ckaScore }} Click the link below to view and download your certificate. https://trainingportal.linuxfoundation.org/learn/dashboard {{- else }} Come on! you can do it next time! {{- end }} Deployment Template \u00b6 Let's use Busybox service to generate information. We use kubectl create deployment --dry-run=client -oyaml to generate Deployment yaml file and write it the yaml file content into file templates/deployment.yaml . kubectl create deployment cka-demo-busybox --image=busybox:latest --dry-run=client -oyaml > templates/deployment.yaml Check content of deployment yaml file templates/deployment.yaml . cat templates/deployment.yaml apiVersion : apps/v1 kind : Deployment metadata : creationTimestamp : null labels : app : cka-demo-busybox name : cka-demo-busybox spec : replicas : 1 selector : matchLabels : app : cka-demo-busybox strategy : {} template : metadata : creationTimestamp : null labels : app : cka-demo-busybox spec : containers : - image : busybox:latest name : busybox resources : {} status : {} Edit file templates/deployment.yaml . vi templates/deployment.yaml Let's replace value of .spec.replicas from 1 to a variable {{ .Values.replicaCount }} , so we can dynamicly assign replicas number for other Deployment. apiVersion : apps/v1 kind : Deployment metadata : creationTimestamp : null labels : app : cka-demo-busybox name : cka-demo-busybox spec : replicas : {{ .Values.replicaCount }} selector : matchLabels : app : cka-demo-busybox strategy : {} template : metadata : creationTimestamp : null labels : app : cka-demo-busybox spec : containers : - image : busybox:latest name : busybox resources : {} status : {} The .spec.replicas will be replaced by actula value of .Values.replicaCount during deployment. Let's create another file values.yaml and add a variable replicaCount with default value 1 into the file. Strong recommended to add comments for each value we defined in file values.yaml . vi values.yaml # Number of deployment replicas replicaCount: 1 Let's add more variables into file templates/deployment.yaml . Replace Release name .metadata.name by {{ .Release.Name }} and filled with variable defined in file values.yaml . Replace label name .metadata.labels by {{- include \"cka-demo.labels\" . | nindent 4 }} , and filled with labels name cka-demo.labels defined in file _helpers.tpl . Replace .spec.replicas by {{ .Values.replicaCount }} and filled with variable defined in file values.yaml . Replace .spec.selector.matchLabels by {{- include \"cka-demo.selectorLabels\" . | nindent 6 }} and filled with cka-demo.selectorLabels defined in file _helpers.tpl . Replace .spec.template.metadata.labels by {{- include \"cka-demo.selectorLabels\" . | nindent 8 }} and filled with cka-demo.selectorLabels defined in file _helpers.tpl . Replace .spec.template.spec.containers[0].image by {{ .Values.image.repository }} and {{ .Values.image.tag }} and filled with variables defined in values.yaml for image name and image tag. Replace .spec.template.spec.containers[0].command and add if-else statement, if .Values.passExam is true, execute commands defined in .Values.passCommand , if false, execute commands defined in .Values.lostCommand . Use key from ConfigMap from .spec.template.spec.containers[0].env as prefix of ConfigMap name and filled with {{ .Values.studentName }} defined in file values.yaml . Replace .spec.template.spec.containers[0].resources by {{ .Values.resources }} and filled with variable defined in file values.yaml . The .Release.Name is built-in object, no need to be specified in file values.yaml . It's generated by Release by helm install . Remove unused lines and final one looks like below. apiVersion : apps/v1 kind : Deployment metadata : name : {{ .Release.Name }} labels : {{ - include \"cka-demo.labels\" . | nindent 4 }} spec : replicas : {{ .Values.replicaCount }} selector : matchLabels : {{ - include \"cka-demo.selectorLabels\" . | nindent 6 }} template : metadata : labels : {{ - include \"cka-demo.selectorLabels\" . | nindent 8 }} spec : containers : - name : id-generator image : \"{{ .Values.image.repository }}:{{ .Values.image.tag }}\" {{ - if .Values.passExam }} {{ - with .Values.passCommand }} command : {{ range . }} - {{ . | quote }} {{ - end }} {{ - end }} {{ - else }} {{ - with .Values.lostCommand }} command : {{ range . }} - {{ . | quote }} {{ - end }} {{ - end }} {{ - end }} env : - name : CKA_SCORE valueFrom : configMapKeyRef : name : {{ .Values.studentName }} -cka-score key : cka_score {{ - with .Values.resources }} resources : {{ - toYaml . | nindent 12 }} {{ - end }} restartPolicy : Always Update file values.yaml with variables default values. Suggestions\uff1aadd variables one and test one, don't add all at one time. vi values.yaml # Number of deployment replicas replicaCount: 1 # Image repository and tag image: repository: busybox tag: latest # Container start command passCommand: - '/bin/sh' - '-c' - \"echo Your CKA score is $(CKA_SCORE) and your CKA certificate ID number is $(tr -dc 'A-Za-z0-9' < /dev/urandom | head -c 13; echo) ; sleep 86400\" lostCommand: - '/bin/sh' - '-c' - \"echo Your CKA score is $(CKA_SCORE), Come on! you can do it next time! ; sleep 86400\" # Container resources resources: limits: cpu: 200m memory: 256Mi requests: cpu: 100m memory: 128Mi # Student Name studentName: whoareyou # Student pass CKA exam or not passExam: true ConfigMap Template \u00b6 ConfigMap is referred in the Deployment, hence we need define the ConfigMap template. We will combine name of ConfigMap and cka_score as a variable, like name-cka-score . vi templates/configmap.yaml apiVersion : v1 kind : ConfigMap metadata : name : {{ .Values.studentName }} -cka-score labels : {{ - include \"cka-demo.labels\" . | nindent 4 }} data : cka_score : {{ .Values.ckaScore | quote }} The studentName was already defined in file values.yaml , we just need add ckaScore with default value. vi values.yaml # Student CKA Score ckaScore: 100 _helpers.tpl \u00b6 Define a common template _helpers.tpl to add labels and labels of Selector for labels of Deployment and ConfigMap. vi templates/_helpers.tpl {{/* Common labels */}} {{- define \"cka-demo.labels\" -}} {{ include \"cka-demo.selectorLabels\" . }} {{- if .Chart.AppVersion }} app.kubernetes.io/version: {{ .Chart.AppVersion | quote }} {{- end }} app.kubernetes.io/managed-by: {{ .Release.Service }} {{- end -}} {{/* Selector labels */}} {{- define \"cka-demo.selectorLabels\" -}} app: {{ .Chart.Name }} release: {{ .Release.Name }} {{- end -}} Chart.yaml \u00b6 We use CKA logo as the icon of Chart wget https://www.cncf.io/wp-content/uploads/2021/09/kubernetes-cka-color.svg Edit Chart.yaml file. vi Chart.yaml Append icon info in the file. icon: file://./kubernetes-cka-color.svg Add author info for the Chart vi Chart.yaml maintainers: - name: James.H Final Chart.yaml looks like below. Don't forget to update appVersion: \"v1.23\" to current Kubernetes API version. apiVersion : v2 name : cka-demo description : A Helm chart for CKA demo. type : application version : 0.1.0 appVersion : \"v1.23\" maintainers : - name : James.H icon : file://./kubernetes-cka-color.svg Chart Debug \u00b6 Use helm lint to verify above change. helm lint 1 chart(s) linted, 0 chart(s) failed helm lint only check format of Chart, won't check Manifest file. We can use helm install --debug --dry-run or helm template to check Manifest output in order to verify all yaml files are correct or not. helm template cka-demo ./ Use helm install --debug --dry-run to simulate the installation. We can get expected results from two different options (passed or failed the CKA certificate). helm install --debug --dry-run cka-demo ./ --create-namespace \\ -n cka \\ --set studentName=kubernetes \\ --set ckaScore=99 \\ --set passExam=true helm install --debug --dry-run cka-demo ./ --create-namespace \\ -n cka \\ --set studentName=kubernetes \\ --set ckaScore=0 \\ --set passExam=false Package Chart to .tgz file, and upload to repository, e.g., Chart Museum or OCI Repo. cd ../ helm package cka-demo Successfully packaged chart and saved it to: /root/cka-demo-0.1.0.tgz Till now, we have done our task to develop a Chart. Let's install the Chart. helm install cka-demo cka-demo-0.1.0.tgz --create-namespace \\ -n cka \\ --set studentName=kubernetes \\ --set ckaScore=0 \\ --set passExam=false Result NAME: cka-demo LAST DEPLOYED: Sun Jul 24 19:58:36 2022 NAMESPACE: cka STATUS: deployed REVISION: 1 TEST SUITE: None NOTES: Come on! you can do it next time! Check the deployment helm list --all-namespaces Result NAME NAMESPACE REVISION UPDATED STATUS CHART APP VERSION cka-demo cka 1 2022-07-24 19:58:36.272093383 +0800 CST deployed cka-demo-0.1.0 v1.23 mysql dev 1 2022-07-24 19:37:20.710988009 +0800 CST deployed mysql-9.2.1 8.0.29 If any error, need to unstall cka-demo and reinstall it. helm uninstall cka-demo -n Check log of cka-demo . kubectl logs -n cka -l app=cka-demo Result Your CKA score is 0, Come on! you can do it next time! Install cka-demo with different options. helm uninstall cka-demo -n cka helm install cka-demo cka-demo-0.1.0.tgz --create-namespace \\ -n cka \\ --set studentName=kubernetes \\ --set ckaScore=100 \\ --set passExam=true NAME: cka-demo LAST DEPLOYED: Sun Jul 24 20:01:34 2022 NAMESPACE: cka STATUS: deployed REVISION: 1 TEST SUITE: None NOTES: Congratulations! You have successfully completed Certified Kubernetes Administrator China Exam (CKA-CN). Your CKA score is: 100 Click the link below to view and download your certificate. https://trainingportal.linuxfoundation.org/learn/dashboard Check log of cka-demo . kubectl logs -n cka -l app=cka-demo Your CKA score is 100 and your CKA certificate ID number is BQKoVYVhjzl3G Built-in Objects: Release.Name # \u53d1\u5e03\u540d\u79f0 Release.Namespace # \u53d1\u5e03Namespace Release.Service # \u6e32\u67d3\u6a21\u677f\u7684\u670d\u52a1\uff0c\u5728Helm\u4e2d\u9ed8\u8ba4\u503c\u4e3a\"Helm\" Release.IsUpgrade # \u5982\u679c\u5f53\u524d\u662f\u5347\u7ea7\u6216\u56de\u6eda\uff0c\u8bbe\u7f6e\u4e3atrue Release.IsInstall # \u5982\u679c\u5f53\u524d\u662f\u5b89\u88c5\uff0c\u8bbe\u7f6e\u4e3atrue Release.Revision # \u53d1\u5e03\u7248\u672c\u53f7 Values # \u4ecevalues.yaml\u548c--set\u4f20\u5165\uff0c\u9ed8\u8ba4\u4e3a\u7a7a Chart # \u6240\u6709Chart.yaml\u4e2d\u7684\u5185\u5bb9 Chart.Version # Chart.Maintainers # Files # \u5728chart\u4e2d\u8bbf\u95ee\u975e\u7279\u6b8a\u6587\u4ef6 Capabilities # \u63d0\u4f9b\u5173\u4e8e\u652f\u6301\u80fd\u529b\u7684\u4fe1\u606f\uff08K8s API\u7248\u672c\u3001K8s\u7248\u672c\u3001Helm\u7248\u672c\uff09 Capabilities.KubeVersion # Kubernetes\u7684\u7248\u672c\u53f7 Capabilities.APIVersions.Has \"batch/v1\" # K8s API\u7248\u672c\u5305\u542b\"batch/v1\" Template # \u5f53\u524d\u6a21\u677f\u4fe1\u606f Template.Name # \u5f53\u524d\u6a21\u677f\u6587\u4ef6\u8def\u5f84 Template.BasePath # \u5f53\u524d\u6a21\u677f\u76ee\u5f55\u8def\u5f84 Reference: Helm \u5b98\u7f51 Helm \u7248\u672c\u652f\u6301\u7b56\u7565 Helm Chart \u8d44\u6e90\u5bf9\u8c61\u5b89\u88c5\u987a\u5e8f","title":"Helming"},{"location":"k8s/cka_en/foundamentals/helming/#helm-chart","text":"","title":"Helm Chart"},{"location":"k8s/cka_en/foundamentals/helming/#install-helm","text":"Install Helm on cka001 . # https://github.com/helm/helm/releases wget https://get.helm.sh/helm-v3.8.2-linux-amd64.tar.gz tar -zxvf helm-v3.8.2-linux-amd64.tar.gz cp linux-amd64/helm /usr/bin/ rm -rf linux-amd64 helm-v3.8.2-linux-amd64.tar.gz Or manually download the file via link https://get.helm.sh/helm-v3.8.2-linux-amd64.tar.gz , and remote copy to cka001 . scp -i cka-key-pair.pem ./Package/helm-v3.8.2-linux-amd64.tar.gz root@cka001:/root/ ssh -i cka-key-pair.pem root@cka001 tar -zxvf helm-v3.8.2-linux-amd64.tar.gz cp linux-amd64/helm /usr/bin/ rm -rf linux-amd64 helm-v3.8.2-linux-amd64.tar.gz","title":"Install Helm"},{"location":"k8s/cka_en/foundamentals/helming/#usage-of-helm","text":"Check helm version helm version version.BuildInfo{Version:\"v3.8.2\", GitCommit:\"6e3701edea09e5d55a8ca2aae03a68917630e91b\", GitTreeState:\"clean\", GoVersion:\"go1.17.5\"} Get help of helm . helm help Configure auto-completion for helm . echo \"source <(helm completion bash)\" >> ~/.bashrc source <(helm completion bash)","title":"Usage of Helm"},{"location":"k8s/cka_en/foundamentals/helming/#install-mysql-from-helm","text":"Add bitnami Chartes Repository. helm repo add bitnami https://charts.bitnami.com/bitnami Get current Charts repositories. helm repo list NAME URL bitnami https://charts.bitnami.com/bitnami Sync up local Charts repositories. helm repo update Search bitnami Charts in repositories. helm search repo bitnami Search bitnami/mysql Charts in repositories. helm search repo bitnami/mysql Install MySQL Chart on namespace dev \uff1a helm install mysql bitnami/mysql -n dev Output NAME: mysql LAST DEPLOYED: Sun Jul 24 19:37:20 2022 NAMESPACE: dev STATUS: deployed REVISION: 1 TEST SUITE: None NOTES: CHART NAME: mysql CHART VERSION: 9.2.1 APP VERSION: 8.0.29 ** Please be patient while the chart is being deployed ** Tip: Watch the deployment status using the command: kubectl get pods -w --namespace dev Services: echo Primary: mysql.dev.svc.cluster.local:3306 Execute the following to get the administrator credentials: echo Username: root MYSQL_ROOT_PASSWORD=$(kubectl get secret --namespace dev mysql -o jsonpath=\"{.data.mysql-root-password}\" | base64 -d) To connect to your database: 1. Run a pod that you can use as a client: kubectl run mysql-client --rm --tty -i --restart='Never' --image docker.io/bitnami/mysql:8.0.29-debian-11-r9 --namespace dev --env MYSQL_ROOT_PASSWORD=$MYSQL_ROOT_PASSWORD --command -- bash 2. To connect to primary service (read/write): mysql -h mysql.dev.svc.cluster.local -uroot -p\"$MYSQL_ROOT_PASSWORD\" Check installed release\uff1a helm list Result NAME NAMESPACE REVISION UPDATED STATUS CHART APP VERSION mysql dev 1 2022-07-24 19:37:20.710988009 +0800 CST deployed mysql-9.2.1 8.0.29 Check installed mysql release information. helm status mysql Check mysql Pod status. kubectl get pod Result NAME READY STATUS RESTARTS AGE mysql-0 1/1 Running 0 72s","title":"Install MySQL from Helm"},{"location":"k8s/cka_en/foundamentals/helming/#develop-a-chart","text":"Below is a demo on how to develop a Chart. Execute helm create to initiate a Chart\uff1a # Naming conventions of Chart: lowercase a~z and - ( minus sign ) helm create cka-demo A folder cka-demo was created. Check the folder structure. tree cka-demo/ Output cka-demo/ \u251c\u2500\u2500 charts \u251c\u2500\u2500 Chart.yaml \u251c\u2500\u2500 templates \u2502 \u251c\u2500\u2500 deployment.yaml \u2502 \u251c\u2500\u2500 _helpers.tpl \u2502 \u251c\u2500\u2500 hpa.yaml \u2502 \u251c\u2500\u2500 ingress.yaml \u2502 \u251c\u2500\u2500 NOTES.txt \u2502 \u251c\u2500\u2500 serviceaccount.yaml \u2502 \u251c\u2500\u2500 service.yaml \u2502 \u2514\u2500\u2500 tests \u2502 \u2514\u2500\u2500 test-connection.yaml \u2514\u2500\u2500 values.yaml Delete or empty some files, which will be re-created later. cd cka-demo rm -rf charts rm -rf templates/tests rm -rf templates/*.yaml echo \"\" > values.yaml echo \"\" > templates/NOTES.txt echo \"\" > templates/_helpers.tpl cd .. Now new structure looks like below. tree cka-demo/ Output cka-demo/ \u251c\u2500\u2500 Chart.yaml \u251c\u2500\u2500 templates \u2502 \u251c\u2500\u2500 _helpers.tpl \u2502 \u2514\u2500\u2500 NOTES.txt \u2514\u2500\u2500 values.yaml","title":"Develop a Chart"},{"location":"k8s/cka_en/foundamentals/helming/#notestxt","text":"NOTES.txt is used to provide summary information to Chart users. In the demo, we will use NOTES.txt to privide summary info about whether the user passed CKA certificate or not. cd cka-demo/ vi templates/NOTES.txt Add below info. {{- if .Values.passExam }} Congratulations! You have successfully completed Certified Kubernetes Administrator China Exam (CKA-CN). Your CKA score is: {{ .Values.ckaScore }} Click the link below to view and download your certificate. https://trainingportal.linuxfoundation.org/learn/dashboard {{- else }} Come on! you can do it next time! {{- end }}","title":"NOTES.txt"},{"location":"k8s/cka_en/foundamentals/helming/#deployment-template","text":"Let's use Busybox service to generate information. We use kubectl create deployment --dry-run=client -oyaml to generate Deployment yaml file and write it the yaml file content into file templates/deployment.yaml . kubectl create deployment cka-demo-busybox --image=busybox:latest --dry-run=client -oyaml > templates/deployment.yaml Check content of deployment yaml file templates/deployment.yaml . cat templates/deployment.yaml apiVersion : apps/v1 kind : Deployment metadata : creationTimestamp : null labels : app : cka-demo-busybox name : cka-demo-busybox spec : replicas : 1 selector : matchLabels : app : cka-demo-busybox strategy : {} template : metadata : creationTimestamp : null labels : app : cka-demo-busybox spec : containers : - image : busybox:latest name : busybox resources : {} status : {} Edit file templates/deployment.yaml . vi templates/deployment.yaml Let's replace value of .spec.replicas from 1 to a variable {{ .Values.replicaCount }} , so we can dynamicly assign replicas number for other Deployment. apiVersion : apps/v1 kind : Deployment metadata : creationTimestamp : null labels : app : cka-demo-busybox name : cka-demo-busybox spec : replicas : {{ .Values.replicaCount }} selector : matchLabels : app : cka-demo-busybox strategy : {} template : metadata : creationTimestamp : null labels : app : cka-demo-busybox spec : containers : - image : busybox:latest name : busybox resources : {} status : {} The .spec.replicas will be replaced by actula value of .Values.replicaCount during deployment. Let's create another file values.yaml and add a variable replicaCount with default value 1 into the file. Strong recommended to add comments for each value we defined in file values.yaml . vi values.yaml # Number of deployment replicas replicaCount: 1 Let's add more variables into file templates/deployment.yaml . Replace Release name .metadata.name by {{ .Release.Name }} and filled with variable defined in file values.yaml . Replace label name .metadata.labels by {{- include \"cka-demo.labels\" . | nindent 4 }} , and filled with labels name cka-demo.labels defined in file _helpers.tpl . Replace .spec.replicas by {{ .Values.replicaCount }} and filled with variable defined in file values.yaml . Replace .spec.selector.matchLabels by {{- include \"cka-demo.selectorLabels\" . | nindent 6 }} and filled with cka-demo.selectorLabels defined in file _helpers.tpl . Replace .spec.template.metadata.labels by {{- include \"cka-demo.selectorLabels\" . | nindent 8 }} and filled with cka-demo.selectorLabels defined in file _helpers.tpl . Replace .spec.template.spec.containers[0].image by {{ .Values.image.repository }} and {{ .Values.image.tag }} and filled with variables defined in values.yaml for image name and image tag. Replace .spec.template.spec.containers[0].command and add if-else statement, if .Values.passExam is true, execute commands defined in .Values.passCommand , if false, execute commands defined in .Values.lostCommand . Use key from ConfigMap from .spec.template.spec.containers[0].env as prefix of ConfigMap name and filled with {{ .Values.studentName }} defined in file values.yaml . Replace .spec.template.spec.containers[0].resources by {{ .Values.resources }} and filled with variable defined in file values.yaml . The .Release.Name is built-in object, no need to be specified in file values.yaml . It's generated by Release by helm install . Remove unused lines and final one looks like below. apiVersion : apps/v1 kind : Deployment metadata : name : {{ .Release.Name }} labels : {{ - include \"cka-demo.labels\" . | nindent 4 }} spec : replicas : {{ .Values.replicaCount }} selector : matchLabels : {{ - include \"cka-demo.selectorLabels\" . | nindent 6 }} template : metadata : labels : {{ - include \"cka-demo.selectorLabels\" . | nindent 8 }} spec : containers : - name : id-generator image : \"{{ .Values.image.repository }}:{{ .Values.image.tag }}\" {{ - if .Values.passExam }} {{ - with .Values.passCommand }} command : {{ range . }} - {{ . | quote }} {{ - end }} {{ - end }} {{ - else }} {{ - with .Values.lostCommand }} command : {{ range . }} - {{ . | quote }} {{ - end }} {{ - end }} {{ - end }} env : - name : CKA_SCORE valueFrom : configMapKeyRef : name : {{ .Values.studentName }} -cka-score key : cka_score {{ - with .Values.resources }} resources : {{ - toYaml . | nindent 12 }} {{ - end }} restartPolicy : Always Update file values.yaml with variables default values. Suggestions\uff1aadd variables one and test one, don't add all at one time. vi values.yaml # Number of deployment replicas replicaCount: 1 # Image repository and tag image: repository: busybox tag: latest # Container start command passCommand: - '/bin/sh' - '-c' - \"echo Your CKA score is $(CKA_SCORE) and your CKA certificate ID number is $(tr -dc 'A-Za-z0-9' < /dev/urandom | head -c 13; echo) ; sleep 86400\" lostCommand: - '/bin/sh' - '-c' - \"echo Your CKA score is $(CKA_SCORE), Come on! you can do it next time! ; sleep 86400\" # Container resources resources: limits: cpu: 200m memory: 256Mi requests: cpu: 100m memory: 128Mi # Student Name studentName: whoareyou # Student pass CKA exam or not passExam: true","title":"Deployment Template"},{"location":"k8s/cka_en/foundamentals/helming/#configmap-template","text":"ConfigMap is referred in the Deployment, hence we need define the ConfigMap template. We will combine name of ConfigMap and cka_score as a variable, like name-cka-score . vi templates/configmap.yaml apiVersion : v1 kind : ConfigMap metadata : name : {{ .Values.studentName }} -cka-score labels : {{ - include \"cka-demo.labels\" . | nindent 4 }} data : cka_score : {{ .Values.ckaScore | quote }} The studentName was already defined in file values.yaml , we just need add ckaScore with default value. vi values.yaml # Student CKA Score ckaScore: 100","title":"ConfigMap Template"},{"location":"k8s/cka_en/foundamentals/helming/#_helperstpl","text":"Define a common template _helpers.tpl to add labels and labels of Selector for labels of Deployment and ConfigMap. vi templates/_helpers.tpl {{/* Common labels */}} {{- define \"cka-demo.labels\" -}} {{ include \"cka-demo.selectorLabels\" . }} {{- if .Chart.AppVersion }} app.kubernetes.io/version: {{ .Chart.AppVersion | quote }} {{- end }} app.kubernetes.io/managed-by: {{ .Release.Service }} {{- end -}} {{/* Selector labels */}} {{- define \"cka-demo.selectorLabels\" -}} app: {{ .Chart.Name }} release: {{ .Release.Name }} {{- end -}}","title":"_helpers.tpl"},{"location":"k8s/cka_en/foundamentals/helming/#chartyaml","text":"We use CKA logo as the icon of Chart wget https://www.cncf.io/wp-content/uploads/2021/09/kubernetes-cka-color.svg Edit Chart.yaml file. vi Chart.yaml Append icon info in the file. icon: file://./kubernetes-cka-color.svg Add author info for the Chart vi Chart.yaml maintainers: - name: James.H Final Chart.yaml looks like below. Don't forget to update appVersion: \"v1.23\" to current Kubernetes API version. apiVersion : v2 name : cka-demo description : A Helm chart for CKA demo. type : application version : 0.1.0 appVersion : \"v1.23\" maintainers : - name : James.H icon : file://./kubernetes-cka-color.svg","title":"Chart.yaml"},{"location":"k8s/cka_en/foundamentals/helming/#chart-debug","text":"Use helm lint to verify above change. helm lint 1 chart(s) linted, 0 chart(s) failed helm lint only check format of Chart, won't check Manifest file. We can use helm install --debug --dry-run or helm template to check Manifest output in order to verify all yaml files are correct or not. helm template cka-demo ./ Use helm install --debug --dry-run to simulate the installation. We can get expected results from two different options (passed or failed the CKA certificate). helm install --debug --dry-run cka-demo ./ --create-namespace \\ -n cka \\ --set studentName=kubernetes \\ --set ckaScore=99 \\ --set passExam=true helm install --debug --dry-run cka-demo ./ --create-namespace \\ -n cka \\ --set studentName=kubernetes \\ --set ckaScore=0 \\ --set passExam=false Package Chart to .tgz file, and upload to repository, e.g., Chart Museum or OCI Repo. cd ../ helm package cka-demo Successfully packaged chart and saved it to: /root/cka-demo-0.1.0.tgz Till now, we have done our task to develop a Chart. Let's install the Chart. helm install cka-demo cka-demo-0.1.0.tgz --create-namespace \\ -n cka \\ --set studentName=kubernetes \\ --set ckaScore=0 \\ --set passExam=false Result NAME: cka-demo LAST DEPLOYED: Sun Jul 24 19:58:36 2022 NAMESPACE: cka STATUS: deployed REVISION: 1 TEST SUITE: None NOTES: Come on! you can do it next time! Check the deployment helm list --all-namespaces Result NAME NAMESPACE REVISION UPDATED STATUS CHART APP VERSION cka-demo cka 1 2022-07-24 19:58:36.272093383 +0800 CST deployed cka-demo-0.1.0 v1.23 mysql dev 1 2022-07-24 19:37:20.710988009 +0800 CST deployed mysql-9.2.1 8.0.29 If any error, need to unstall cka-demo and reinstall it. helm uninstall cka-demo -n Check log of cka-demo . kubectl logs -n cka -l app=cka-demo Result Your CKA score is 0, Come on! you can do it next time! Install cka-demo with different options. helm uninstall cka-demo -n cka helm install cka-demo cka-demo-0.1.0.tgz --create-namespace \\ -n cka \\ --set studentName=kubernetes \\ --set ckaScore=100 \\ --set passExam=true NAME: cka-demo LAST DEPLOYED: Sun Jul 24 20:01:34 2022 NAMESPACE: cka STATUS: deployed REVISION: 1 TEST SUITE: None NOTES: Congratulations! You have successfully completed Certified Kubernetes Administrator China Exam (CKA-CN). Your CKA score is: 100 Click the link below to view and download your certificate. https://trainingportal.linuxfoundation.org/learn/dashboard Check log of cka-demo . kubectl logs -n cka -l app=cka-demo Your CKA score is 100 and your CKA certificate ID number is BQKoVYVhjzl3G Built-in Objects: Release.Name # \u53d1\u5e03\u540d\u79f0 Release.Namespace # \u53d1\u5e03Namespace Release.Service # \u6e32\u67d3\u6a21\u677f\u7684\u670d\u52a1\uff0c\u5728Helm\u4e2d\u9ed8\u8ba4\u503c\u4e3a\"Helm\" Release.IsUpgrade # \u5982\u679c\u5f53\u524d\u662f\u5347\u7ea7\u6216\u56de\u6eda\uff0c\u8bbe\u7f6e\u4e3atrue Release.IsInstall # \u5982\u679c\u5f53\u524d\u662f\u5b89\u88c5\uff0c\u8bbe\u7f6e\u4e3atrue Release.Revision # \u53d1\u5e03\u7248\u672c\u53f7 Values # \u4ecevalues.yaml\u548c--set\u4f20\u5165\uff0c\u9ed8\u8ba4\u4e3a\u7a7a Chart # \u6240\u6709Chart.yaml\u4e2d\u7684\u5185\u5bb9 Chart.Version # Chart.Maintainers # Files # \u5728chart\u4e2d\u8bbf\u95ee\u975e\u7279\u6b8a\u6587\u4ef6 Capabilities # \u63d0\u4f9b\u5173\u4e8e\u652f\u6301\u80fd\u529b\u7684\u4fe1\u606f\uff08K8s API\u7248\u672c\u3001K8s\u7248\u672c\u3001Helm\u7248\u672c\uff09 Capabilities.KubeVersion # Kubernetes\u7684\u7248\u672c\u53f7 Capabilities.APIVersions.Has \"batch/v1\" # K8s API\u7248\u672c\u5305\u542b\"batch/v1\" Template # \u5f53\u524d\u6a21\u677f\u4fe1\u606f Template.Name # \u5f53\u524d\u6a21\u677f\u6587\u4ef6\u8def\u5f84 Template.BasePath # \u5f53\u524d\u6a21\u677f\u76ee\u5f55\u8def\u5f84 Reference: Helm \u5b98\u7f51 Helm \u7248\u672c\u652f\u6301\u7b56\u7565 Helm Chart \u8d44\u6e90\u5bf9\u8c61\u5b89\u88c5\u987a\u5e8f","title":"Chart Debug"},{"location":"k8s/cka_en/foundamentals/hpa/","text":"Horizontal Pod Autoscaling (HPA) \u00b6 Scenario: Install Metrics Server component Create Deployment podinfo and Service podinfo for stress testing Create HPA my-hpa Stress Testing Demo: Install Metrics Server component \u00b6 Download yaml file for Metrics Server component wget https://github.com/kubernetes-sigs/metrics-server/releases/latest/download/components.yaml Replace Google image by Aliyun image image: registry.aliyuncs.com/google_containers/metrics-server:v0.6.1 . sed -i 's/k8s\\.gcr\\.io\\/metrics-server\\/metrics-server\\:v0\\.6\\.1/registry\\.aliyuncs\\.com\\/google_containers\\/metrics-server\\:v0\\.6\\.1/g' components.yaml Change arg of deployment metrics-server by adding --kubelet-insecure-tls to disable tls certificate validation. vi components.yaml Updated arg of metrics-server is below. ...... template : metadata : labels : k8s-app : metrics-server spec : containers : - args : - --cert-dir=/tmp - --secure-port=4443 - --kubelet-preferred-address-types=InternalIP,ExternalIP,Hostname - --kubelet-use-node-status-port - --metric-resolution=15s - --kubelet-insecure-tls image : registry.aliyuncs.com/google_containers/metrics-server:v0.6.1 ...... Appy the yaml file components.yaml to deploy metrics-server . kubectl apply -f components.yaml Below resources were crested. serviceaccount/metrics-server created clusterrole.rbac.authorization.k8s.io/system:aggregated-metrics-reader created clusterrole.rbac.authorization.k8s.io/system:metrics-server created rolebinding.rbac.authorization.k8s.io/metrics-server-auth-reader created clusterrolebinding.rbac.authorization.k8s.io/metrics-server:system:auth-delegator created clusterrolebinding.rbac.authorization.k8s.io/system:metrics-server created service/metrics-server created deployment.apps/metrics-server created apiservice.apiregistration.k8s.io/v1beta1.metrics.k8s.io created Verify if metrics-server Pod is running as expected ( 1/1 running) kubectl get pod -n kube-system -owide | grep metrics-server Result NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES metrics-server-7fd564dc66-sdhdc 1/1 Running 0 61s 10.244.102.15 cka003 Get current usage of CPU, memory of each node. kubectl top node Result: NAME CPU(cores) CPU% MEMORY(bytes) MEMORY% cka001 595m 29% 1937Mi 50% cka002 75m 3% 1081Mi 28% cka003 79m 3% 1026Mi 26% Deploy a Service podinfo \u00b6 Create Deployment podinfo and Service podinfo for further stress testing. kubectl apply -f - << EOF apiVersion: v1 kind: Service metadata: name: podinfo labels: app: podinfo spec: type: NodePort ports: - port: 9898 targetPort: 9898 nodePort: 31198 protocol: TCP selector: app: podinfo --- apiVersion: apps/v1 kind: Deployment metadata: name: podinfo labels: app: podinfo spec: replicas: 2 selector: matchLabels: app: podinfo template: metadata: labels: app: podinfo spec: containers: - name: podinfod image: stefanprodan/podinfo:0.0.1 imagePullPolicy: Always command: - ./podinfo - -port=9898 - -logtostderr=true - -v=2 ports: - containerPort: 9898 protocol: TCP resources: requests: memory: \"32Mi\" cpu: \"10m\" limits: memory: \"256Mi\" cpu: \"100m\" EOF Config HPA \u00b6 Create HPA my-hpa by setting CPU threshold 50% to trigger auto-scalling with minimal 2 and maximal 10 Replicas. Use kubectl autoscal to create HPA my-hpa . kubectl autoscale deployment podinfo --cpu-percent=50 --min=1 --max=10 Use autoscaling/v1 version template to crreate HPA my-hpa . kubectl apply -f - < Get current usage of CPU, memory of each node. kubectl top node Result: NAME CPU(cores) CPU% MEMORY(bytes) MEMORY% cka001 595m 29% 1937Mi 50% cka002 75m 3% 1081Mi 28% cka003 79m 3% 1026Mi 26%","title":"Install Metrics Server component"},{"location":"k8s/cka_en/foundamentals/hpa/#deploy-a-service-podinfo","text":"Create Deployment podinfo and Service podinfo for further stress testing. kubectl apply -f - << EOF apiVersion: v1 kind: Service metadata: name: podinfo labels: app: podinfo spec: type: NodePort ports: - port: 9898 targetPort: 9898 nodePort: 31198 protocol: TCP selector: app: podinfo --- apiVersion: apps/v1 kind: Deployment metadata: name: podinfo labels: app: podinfo spec: replicas: 2 selector: matchLabels: app: podinfo template: metadata: labels: app: podinfo spec: containers: - name: podinfod image: stefanprodan/podinfo:0.0.1 imagePullPolicy: Always command: - ./podinfo - -port=9898 - -logtostderr=true - -v=2 ports: - containerPort: 9898 protocol: TCP resources: requests: memory: \"32Mi\" cpu: \"10m\" limits: memory: \"256Mi\" cpu: \"100m\" EOF","title":"Deploy a Service podinfo"},{"location":"k8s/cka_en/foundamentals/hpa/#config-hpa","text":"Create HPA my-hpa by setting CPU threshold 50% to trigger auto-scalling with minimal 2 and maximal 10 Replicas. Use kubectl autoscal to create HPA my-hpa . kubectl autoscale deployment podinfo --cpu-percent=50 --min=1 --max=10 Use autoscaling/v1 version template to crreate HPA my-hpa . kubectl apply -f - <

It works!

Clean up. kubectl delete ingress demo-localhost kubectl delete service demo kubectl delete deployment demo Create Deployments \u00b6 Create two deployment nginx-app-1 and nginx-app-2 . kubectl apply -f - << EOF apiVersion: apps/v1 kind: Deployment metadata: name: nginx-app-1 spec: selector: matchLabels: app: nginx-app-1 replicas: 1 template: metadata: labels: app: nginx-app-1 spec: containers: - name: nginx image: nginx ports: - containerPort: 80 volumeMounts: - name: html mountPath: /usr/share/nginx/html volumes: - name: html hostPath: path: /opt/html-1 --- apiVersion: apps/v1 kind: Deployment metadata: name: nginx-app-2 spec: selector: matchLabels: app: nginx-app-2 replicas: 1 template: metadata: labels: app: nginx-app-2 spec: containers: - name: nginx image: nginx ports: - containerPort: 80 volumeMounts: - name: html mountPath: /usr/share/nginx/html volumes: - name: html hostPath: path: /opt/html-2 EOF Get status of Pods by executing kubectl get pod -o wide . One pod is running on node cka002 , another pod is running on node cka003 . Directory /opt/html-2/ is on cka002 Directory /opt/html-1/ is on cka002 Access to two Pod via curl. We get 403 Forbidden error. curl 10.244.102.13 curl 10.244.112.19 Log onto node cka002 , create index.html file in path /opt/html-2/ with below command. cat < app1.com app2.com EOF Get IP address or FQDN with the following command: kubectl get service ingress-nginx-controller --namespace=ingress-nginx It will be the EXTERNAL-IP field. If that field shows like below, this means that the Kubernetes cluster wasn't able to provision the load balancer (generally, this is because it doesn't support services of type LoadBalancer). As there is no Aliyun ELB configured, use below two options to make the external IP in place. Option 1: manually add node ip to ingress controller, which the controller pod is running on. Execute command kubectl get pod -n ingress-nginx -o wide to see that ingress controller pod is running on node cka003 . Manually patch the external ip of cak003 to the EXTERNAL-IP field. kubectl patch svc ingress-nginx-controller \\ --namespace=ingress-nginx \\ -p '{\"spec\": {\"type\": \"LoadBalancer\", \"externalIPs\":[\"\"]}}' Option 2: change ingress controller from LoadBalancer to NodePort . Two files index.html are in two Pods, the web services are exposed to outside via node IP. The ingress-nginx-controller plays a central entry point for outside access, and provide two ports for different backend services from Pods. Send HTTP request to two hosts defined in Ingress. curl http://app1.com:30011 curl http://app2.com:30011 curl app1.com:30011 curl app2.com:30011 Get below successful information. This is test 1 !! This is test 2 !! Clean up. kubectl delete ingress ingress-nginx-app kubectl delete service nginx-app-1 kubectl delete service nginx-app-2 kubectl delete deployment nginx-app-1 kubectl delete deployment nginx-app-2","title":"Ingress"},{"location":"k8s/cka_en/foundamentals/ingress/#ingress-nginx","text":"Scenario *Deploy Ingress Controller. * Create two deployment nginx-app-1 and nginx-app-2 . *Host directory /root/html-1 and /root/html-2 will be created and mounted to two Deployments on running host. * Create Service. *Create Service nginx-app-1 and nginx-app-2 and map to related Deployment nginx-app-1 and nginx-app-2 . * Create Ingress. *Create Ingress resource nginx-app and map to two Services nginx-app-1 and nginx-app-1 . * Test Accessibility. * Send HTTP request to two hosts defined in Ingress Reference *Github ingress-nginx * Installation Guide","title":"Ingress-nginx"},{"location":"k8s/cka_en/foundamentals/ingress/#deploy-ingress-controller","text":"Get Ingress Controller yaml file. The latest version link is in Installation Guide . wget https://raw.githubusercontent.com/kubernetes/ingress-nginx/controller-v1.3.0/deploy/static/provider/cloud/deploy.yaml Below two images's sources needto be changed to Aliyun. image: k8s.gcr.io/ingress-nginx/controller:v1.2.1@sha256:5516d103a9c2ecc4f026efbd4b40662ce22dc1f824fb129ed121460aaa5c47f8 image: registry.k8s.io/ingress-nginx/controller:v1.3.0@sha256:d1707ca76d3b044ab8a28277a2466a02100ee9f58a86af1535a3edf9323ea1b5 image: k8s.gcr.io/ingress-nginx/kube-webhook-certgen:v1.1.1@sha256:64d8c73dca984af206adf9d6d7e46aa550362b1d7a01f3a0a91b20cc67868660 From grc.io to Aliyun. k8s.gcr.io/ingress-nginx/controller to registry.aliyuncs.com/google_containers/nginx-ingress-controller registry.k8s.io/ingress-nginx/controller to registry.aliyuncs.com/google_containers/nginx-ingress-controller * k8s.gcr.io/ingress-nginx/kube-webhook-certgen to registry.aliyuncs.com/google_containers/kube-webhook-certgen Commands: sed -i 's/k8s.gcr.io\\/ingress-nginx\\/kube-webhook-certgen/registry.aliyuncs.com\\/google\\_containers\\/kube-webhook-certgen/g' deploy.yaml sed -i 's/k8s.gcr.io\\/ingress-nginx\\/controller/registry.aliyuncs.com\\/google\\_containers\\/nginx-ingress-controller/g' deploy.yaml Apply the yaml file deploy.yaml to create Ingress Nginx. A new namespace ingress-nginx was created and Ingress Nginx resources are running under the new namespace. kubectl apply -f deploy.yaml Check the status of Pod. kubectl get pod -n ingress-nginx Make sure all pods are not in error status, like below. NAME READY STATUS RESTARTS AGE ingress-nginx-admission-create-lgtdj 0/1 Completed 0 49s ingress-nginx-admission-patch-nk9fv 0/1 Completed 0 49s ingress-nginx-controller-556fbd6d6f-6jl4x 1/1 Running 0 49s","title":"Deploy Ingress Controller"},{"location":"k8s/cka_en/foundamentals/ingress/#local-testing","text":"Let's create a simple web server and the associated service: kubectl create deployment demo --image=httpd --port=80 kubectl expose deployment demo Then create an ingress resource. The following example uses a host that maps to localhost: kubectl create ingress demo-localhost --class=nginx --rule=\"demo.localdev.me/*=demo:80\" Now, forward a local port to the ingress controller: kubectl port-forward --namespace=ingress-nginx service/ingress-nginx-controller 8080:80 At this point, open another terminal to access http://demo.localdev.me:8080/ , we should see an HTML page telling you \"It works!\". curl http://demo.localdev.me:8080/ Result

It works!

Clean up. kubectl delete ingress demo-localhost kubectl delete service demo kubectl delete deployment demo","title":"Local testing"},{"location":"k8s/cka_en/foundamentals/ingress/#create-deployments","text":"Create two deployment nginx-app-1 and nginx-app-2 . kubectl apply -f - << EOF apiVersion: apps/v1 kind: Deployment metadata: name: nginx-app-1 spec: selector: matchLabels: app: nginx-app-1 replicas: 1 template: metadata: labels: app: nginx-app-1 spec: containers: - name: nginx image: nginx ports: - containerPort: 80 volumeMounts: - name: html mountPath: /usr/share/nginx/html volumes: - name: html hostPath: path: /opt/html-1 --- apiVersion: apps/v1 kind: Deployment metadata: name: nginx-app-2 spec: selector: matchLabels: app: nginx-app-2 replicas: 1 template: metadata: labels: app: nginx-app-2 spec: containers: - name: nginx image: nginx ports: - containerPort: 80 volumeMounts: - name: html mountPath: /usr/share/nginx/html volumes: - name: html hostPath: path: /opt/html-2 EOF Get status of Pods by executing kubectl get pod -o wide . One pod is running on node cka002 , another pod is running on node cka003 . Directory /opt/html-2/ is on cka002 Directory /opt/html-1/ is on cka002 Access to two Pod via curl. We get 403 Forbidden error. curl 10.244.102.13 curl 10.244.112.19 Log onto node cka002 , create index.html file in path /opt/html-2/ with below command. cat < app1.com app2.com EOF Get IP address or FQDN with the following command: kubectl get service ingress-nginx-controller --namespace=ingress-nginx It will be the EXTERNAL-IP field. If that field shows like below, this means that the Kubernetes cluster wasn't able to provision the load balancer (generally, this is because it doesn't support services of type LoadBalancer). As there is no Aliyun ELB configured, use below two options to make the external IP in place. Option 1: manually add node ip to ingress controller, which the controller pod is running on. Execute command kubectl get pod -n ingress-nginx -o wide to see that ingress controller pod is running on node cka003 . Manually patch the external ip of cak003 to the EXTERNAL-IP field. kubectl patch svc ingress-nginx-controller \\ --namespace=ingress-nginx \\ -p '{\"spec\": {\"type\": \"LoadBalancer\", \"externalIPs\":[\"\"]}}' Option 2: change ingress controller from LoadBalancer to NodePort . Two files index.html are in two Pods, the web services are exposed to outside via node IP. The ingress-nginx-controller plays a central entry point for outside access, and provide two ports for different backend services from Pods. Send HTTP request to two hosts defined in Ingress. curl http://app1.com:30011 curl http://app2.com:30011 curl app1.com:30011 curl app2.com:30011 Get below successful information. This is test 1 !! This is test 2 !! Clean up. kubectl delete ingress ingress-nginx-app kubectl delete service nginx-app-1 kubectl delete service nginx-app-2 kubectl delete deployment nginx-app-1 kubectl delete deployment nginx-app-2","title":"Test Accessiblity"},{"location":"k8s/cka_en/foundamentals/job/","text":"Job and Cronjob \u00b6 Job \u00b6 Scenario Create Job. Demo: Create Job pi . kubectl apply -f - << EOF apiVersion: batch/v1 kind: Job metadata: name: pi spec: template: spec: containers: - name: pi image: perl:5.34 command: [\"perl\", \"-Mbignum=bpi\", \"-wle\", \"print bpi(2000)\"] restartPolicy: Never backoffLimit: 4 EOF Get details of Job. kubectl get jobs Get details of Job Pod. The status Completed means the job was done successfully. kubectl get pod Get log info of the Job Pod. kubectl pi-2s74d 3.141592653589793.............. Clean up kubectl delete job pi Cronjob \u00b6 Scenario Create Cronjob. Demo: Create Cronjob hello . kubectl apply -f - << EOF apiVersion: batch/v1 kind: CronJob metadata: name: hello spec: schedule: \"*/1 * * * *\" jobTemplate: spec: template: spec: containers: - name: hello image: busybox args: - /bin/sh - -c - date ; echo Hello from the kubernetes cluster restartPolicy: OnFailure EOF Get detail of Cronjob kubectl get cronjobs -o wide Result NAME SCHEDULE SUSPEND ACTIVE LAST SCHEDULE AGE CONTAINERS IMAGES SELECTOR hello */1 * * * * False 0 25s hello busybox Monitor Jobs. Every 1 minute a new job will be created. kubectl get jobs -w Clean up kubectl delete cronjob hello","title":"Job and Cronjob"},{"location":"k8s/cka_en/foundamentals/job/#job-and-cronjob","text":"","title":"Job and Cronjob"},{"location":"k8s/cka_en/foundamentals/job/#job","text":"Scenario Create Job. Demo: Create Job pi . kubectl apply -f - << EOF apiVersion: batch/v1 kind: Job metadata: name: pi spec: template: spec: containers: - name: pi image: perl:5.34 command: [\"perl\", \"-Mbignum=bpi\", \"-wle\", \"print bpi(2000)\"] restartPolicy: Never backoffLimit: 4 EOF Get details of Job. kubectl get jobs Get details of Job Pod. The status Completed means the job was done successfully. kubectl get pod Get log info of the Job Pod. kubectl pi-2s74d 3.141592653589793.............. Clean up kubectl delete job pi","title":"Job"},{"location":"k8s/cka_en/foundamentals/job/#cronjob","text":"Scenario Create Cronjob. Demo: Create Cronjob hello . kubectl apply -f - << EOF apiVersion: batch/v1 kind: CronJob metadata: name: hello spec: schedule: \"*/1 * * * *\" jobTemplate: spec: template: spec: containers: - name: hello image: busybox args: - /bin/sh - -c - date ; echo Hello from the kubernetes cluster restartPolicy: OnFailure EOF Get detail of Cronjob kubectl get cronjobs -o wide Result NAME SCHEDULE SUSPEND ACTIVE LAST SCHEDULE AGE CONTAINERS IMAGES SELECTOR hello */1 * * * * False 0 25s hello busybox Monitor Jobs. Every 1 minute a new job will be created. kubectl get jobs -w Clean up kubectl delete cronjob hello","title":"Cronjob"},{"location":"k8s/cka_en/foundamentals/kyma/","text":"Kyma \u00b6 Deploy Kyma on control plane node. Install Kyma CLI \u00b6 Install Kyma CLI on Linux, run: curl -Lo kyma.tar.gz \"https://github.com/kyma-project/cli/releases/download/$(curl -s https://api.github.com/repos/kyma-project/cli/releases/latest | grep tag_name | cut -d '\"' -f 4)/kyma_Linux_x86_64.tar.gz\" mkdir /opt/kyma-release tar -C /opt/kyma-release -zxvf kyma.tar.gz chmod +x /opt/kyma-release/kyma sudo cp /opt/kyma-release/kyma /usr/local/bin rm -rf kyma-release kyma.tar.gz Reference Install Kyma CLI Install Kyma \u00b6 Use the deploy command to install Kyma. kyma deploy Get file components.yaml to manually install failed components. If no Namespace provided, the default Namespace called kyma-system is used. For example: kyma deploy --component serverless@kyma-integration kyma deploy --component monitoring@kyma-integration kyma deploy --component kiali@kyma-integration File components.yaml looks like below. --- defaultNamespace: kyma-system prerequisites: - name: \"cluster-essentials\" - name: \"istio\" namespace: \"istio-system\" - name: \"certificates\" namespace: \"istio-system\" components: - name: \"istio-resources\" - name: \"logging\" - name: \"telemetry\" - name: \"tracing\" - name: \"kiali\" - name: \"monitoring\" - name: \"eventing\" - name: \"ory\" - name: \"api-gateway\" - name: \"cluster-users\" - name: \"serverless\" - name: \"application-connector\" namespace: \"kyma-integration\" Reference: By default, Kyma is installed with the default chart values defined in the values.yaml files. You can also control the allocation of resources, such as memory and CPU, that the components consume by installing Kyma with the following pre-defined profiles: Evaluation needs limited resources and is suited for trial purposes. Production is configured for high availability and scalability. It requires more resources than the evaluation profile but is a better choice for production workload. Install Kyma To see a complete list of all Kyma components go to the components.yaml file. Install specific components kyma deploy --components-file {COMPONENTS_FILE_PATH}","title":"Kyma"},{"location":"k8s/cka_en/foundamentals/kyma/#kyma","text":"Deploy Kyma on control plane node.","title":"Kyma"},{"location":"k8s/cka_en/foundamentals/kyma/#install-kyma-cli","text":"Install Kyma CLI on Linux, run: curl -Lo kyma.tar.gz \"https://github.com/kyma-project/cli/releases/download/$(curl -s https://api.github.com/repos/kyma-project/cli/releases/latest | grep tag_name | cut -d '\"' -f 4)/kyma_Linux_x86_64.tar.gz\" mkdir /opt/kyma-release tar -C /opt/kyma-release -zxvf kyma.tar.gz chmod +x /opt/kyma-release/kyma sudo cp /opt/kyma-release/kyma /usr/local/bin rm -rf kyma-release kyma.tar.gz Reference Install Kyma CLI","title":"Install Kyma CLI"},{"location":"k8s/cka_en/foundamentals/kyma/#install-kyma","text":"Use the deploy command to install Kyma. kyma deploy Get file components.yaml to manually install failed components. If no Namespace provided, the default Namespace called kyma-system is used. For example: kyma deploy --component serverless@kyma-integration kyma deploy --component monitoring@kyma-integration kyma deploy --component kiali@kyma-integration File components.yaml looks like below. --- defaultNamespace: kyma-system prerequisites: - name: \"cluster-essentials\" - name: \"istio\" namespace: \"istio-system\" - name: \"certificates\" namespace: \"istio-system\" components: - name: \"istio-resources\" - name: \"logging\" - name: \"telemetry\" - name: \"tracing\" - name: \"kiali\" - name: \"monitoring\" - name: \"eventing\" - name: \"ory\" - name: \"api-gateway\" - name: \"cluster-users\" - name: \"serverless\" - name: \"application-connector\" namespace: \"kyma-integration\" Reference: By default, Kyma is installed with the default chart values defined in the values.yaml files. You can also control the allocation of resources, such as memory and CPU, that the components consume by installing Kyma with the following pre-defined profiles: Evaluation needs limited resources and is suited for trial purposes. Production is configured for high availability and scalability. It requires more resources than the evaluation profile but is a better choice for production workload. Install Kyma To see a complete list of all Kyma components go to the components.yaml file. Install specific components kyma deploy --components-file {COMPONENTS_FILE_PATH}","title":"Install Kyma"},{"location":"k8s/cka_en/foundamentals/memo/","text":"Kubernetes Learning Memo \u00b6 Basic Concepts of Kubernetes \u00b6 Kubernetes Components \u00b6 A Kubernetes cluster consists of the components that represent the control plane and a set of machines called nodes . Kubernetes Components : Control Plane Components kube-apiserver: query and manipulate the state of objects in Kubernetes. play as \"communication hub\" among all resources in cluster. provide cluster security authentication, authorization, and role assignment. the only one can connect to etcd . etcd: all Kubernetes objects are stored on etcd. Kubernetes objects are persistent entities in the Kubernetes system, which are used to represent the state of your cluster. kube-scheduler: watches for newly created Pods with no assigned node, and selects a node for them to run on. kube-controller-manager: runs controller processes. Node controller : Responsible for noticing and responding when nodes go down. Job controller : Watches for Job objects that represent one-off tasks, then creates Pods to run those tasks to completion. Endpoints controller : Populates the Endpoints object (that is, joins Services & Pods). Service Account & Token controllers : Create default accounts and API access tokens for new namespaces. cloud-controller-manager: embeds cloud-specific control logic and only runs controllers that are specific to your cloud provider, no need for own premises and learning environment. Node controller : For checking the cloud provider to determine if a node has been deleted in the cloud after it stops responding Route controller : For setting up routes in the underlying cloud infrastructure Service controller : For creating, updating and deleting cloud provider load balancers Node Components kubelet: An agent that runs on each node in the cluster. Manage node. It makes sure that containers are running in a Pod. kubelet registers and updates nodes information to APIServer, and APIServer stores them into etcd . Manage pod. Watch pod via APIServer, and action on pods or containers in pods. Health check at container level. kube-proxy: is a network proxy that runs on each node in cluster. iptables ipvs maintains network rules on nodes. Container runtime: is the software that is responsible for running containers. Addons DNS: is a DNS server and required by all Kubernetes clusters. Web UI (Dashboard): web-based UI for Kubernetes clusters. Container Resource Monitoring: records generic time-series metrics about containers in a central database Cluster-level Logging: is responsible for saving container logs to a central log store with search/browsing interface. Scalability: Scaling out (horizontal scaling) by adding more servers to your architecture to spread the workload across more machines. Scaling up (vertical scaling) by adding more hard drives and memory to increase the computing capacity of physical servers. Kubernetes API \u00b6 The REST API is the fundamental fabric of Kubernetes. All operations and communications between components, and external user commands are REST API calls that the API Server handles. Consequently, everything in the Kubernetes platform is treated as an API object and has a corresponding entry in the API. The core of Kubernetes' control plane is the API server. CRI: Container Runtime Interface CNI: Container Network Interface CSI: Container Storage Interface The API server exposes an HTTP API that lets end users, different parts of cluster, and external components communicate with one another. The Kubernetes API lets we query and manipulate the state of API objects in Kubernetes (for example: Pods, Namespaces, ConfigMaps, and Events). Kubernetes API: OpenAPI specification OpenAPI V2 OpenAPI V3 Persistence. Kubernetes stores the serialized state of objects by writing them into etcd. API groups and versioning. Versioning is done at the API level. API resources are distinguished by their API group, resource type, namespace (for namespaced resources), and name. API changes API Extension API Version \u00b6 The API versioning and software versioning are indirectly related. The API and release versioning proposal describes the relationship between API versioning and software versioning. Different API versions indicate different levels of stability and support. Here's a summary of each level: Alpha: The version names contain alpha (for example, v1alpha1). The software may contain bugs. Enabling a feature may expose bugs. A feature may be disabled by default. The support for a feature may be dropped at any time without notice. The API may change in incompatible ways in a later software release without notice. The software is recommended for use only in short-lived testing clusters, due to increased risk of bugs and lack of long-term support. Beta: The version names contain beta (for example, v2beta3). The software is well tested. Enabling a feature is considered safe. Features are enabled by default. The support for a feature will not be dropped, though the details may change. The schema and/or semantics of objects may change in incompatible ways in a subsequent beta or stable release. When this happens, migration instructions are provided. Schema changes may require deleting, editing, and re-creating API objects. The editing process may not be straightforward. The migration may require downtime for applications that rely on the feature. The software is not recommended for production uses. Subsequent releases may introduce incompatible changes. If you have multiple clusters which can be upgraded independently, you may be able to relax this restriction. Note: Please try beta features and provide feedback. After the features exit beta, it may not be practical to make more changes. Stable: The version name is vX where X is an integer. The stable versions of features appear in released software for many subsequent versions. Command to get current API kubectl api-resources API Group \u00b6 API groups make it easier to extend the Kubernetes API. The API group is specified in a REST path and in the apiVersion field of a serialized object. There are several API groups in Kubernetes: The core (also called legacy) group is found at REST path /api/v1 . The core group is not specified as part of the apiVersion field, for example, apiVersion: v1. The named groups are at REST path /apis/$GROUP_NAME/$VERSION and use apiVersion: $GROUP_NAME/$VERSION (for example, apiVersion: batch/v1). Kubernetes Objects \u00b6 Objects Overview \u00b6 Object Spec: providing a description of the characteristics the resource created to have: its desired state . Object Status: describes the current state of the object. Example of Deployment as an object that can represent an application running on cluster. apiVersion : apps/v1 # Which version of the Kubernetes API you're using to create this object kind : Deployment # What kind of object you want to create metadata : # Data that helps uniquely identify the object, including a name string, UID, and optional namespace name : nginx-deployment spec : # What state you desire for the object selector : matchLabels : app : nginx replicas : 2 # tells deployment to run 2 pods matching the template template : metadata : labels : app : nginx spec : containers : - name : nginx image : nginx:1.14.2 ports : - containerPort : 80 Object Management \u00b6 The kubectl command-line tool supports several different ways to create and manage Kubernetes objects. Read the Kubectl book for details. A Kubernetes object should be managed using ONLY one technique. Mixing and matching techniques for the same object results in undefined behavior. Three management techniques: Imperative commands operates directly on live objects in a cluster. kubectl create deployment nginx --image nginx Imperative object configuration kubectl create -f nginx.yaml kubectl delete -f nginx.yaml -f redis.yaml kubectl replace -f nginx.yaml Declarative object configuration kubectl diff -f configs/ kubectl apply -f configs/ Object Names and IDs \u00b6 Each object in your cluster has a Name that is unique for that type of resource. DNS Subdomain Names Label Names Path Segment Names Every Kubernetes object also has a UID that is unique across the whole cluster. Namespaces \u00b6 In Kubernetes, namespaces provides a mechanism for isolating groups of resources within a single cluster. Names of resources need to be unique within a namespace, but not across namespaces. Namespace-based scoping is applicable only for namespaced objects (e.g. Deployments, Services, etc) and not for cluster-wide objects (e.g. StorageClass, Nodes, PersistentVolumes, etc) Not All Objects are in a Namespace. Kubernetes starts with four initial namespaces: default The default namespace for objects with no other namespace kube-system The namespace for objects created by the Kubernetes system kube-public This namespace is created automatically and is readable by all users (including those not authenticated). This namespace is mostly reserved for cluster usage, in case that some resources should be visible and readable publicly throughout the whole cluster. The public aspect of this namespace is only a convention, not a requirement. kube-node-lease This namespace holds Lease objects associated with each node. Node leases allow the kubelet to send heartbeats so that the control plane can detect node failure. Viewing namespaces: kubectl get namespace Setting the namespace for a request kubectl run nginx --image=nginx --namespace= kubectl get pods --namespace= Labels and Selectors \u00b6 Labels are key/value pairs that are attached to objects, such as pods. Valid label keys have two segments: an optional prefix and name, separated by a slash ( / ). Labels are intended to be used to specify identifying attributes of objects that are meaningful and relevant to users. Labels can be used to organize and to select subsets of objects. Labels can be attached to objects at creation time and subsequently added and modified at any time. Each object can have a set of key/value labels defined. Each Key must be unique for a given object. Example of labels: \"metadata\" : { \"labels\" : { \"key1\" : \"value1\" , \"key2\" : \"value2\" } } Unlike names and UIDs, labels do not provide uniqueness. In general, we expect many objects to carry the same label(s). The API currently supports two types of selectors: equality-based, e.g., environment = production , tier != frontend set-based, e.g., environment in (production, qa) , tier notin (frontend, backend) Sample commands: kubectl get pods -l environment=production,tier=frontend kubectl get pods -l 'environment in (production),tier in (frontend)' kubectl get pods -l 'environment in (production, qa)' kubectl get pods -l 'environment,environment notin (frontend)' Annotations \u00b6 Use Kubernetes annotations to attach arbitrary non-identifying metadata to objects. Clients such as tools and libraries can retrieve this metadata. Use either labels or annotations to attach metadata to Kubernetes objects. Labels can be used to select objects and to find collections of objects that satisfy certain conditions. Annotations are not used to identify and select objects. Annotations, like labels, are key/value maps. The keys and the values in the map must be strings. \"metadata\" : { \"annotations\" : { \"key1\" : \"value1\" , \"key2\" : \"value2\" } } Valid annotation keys have two segments: an optional prefix and name, separated by a slash ( / ). Field Selectors \u00b6 Field selectors let you select Kubernetes resources based on the value of one or more resource fields. Here are some examples of field selector queries: metadata.name=my-service metadata.namespace!=default status.phase=Pending This kubectl command selects all Pods for which the value of the status.phase field is Running: kubectl get pods --field-selector status.phase=Running Supported field selectors vary by Kubernetes resource type. All resource types support the metadata.name and metadata.namespace fields. Use the = , == , and != operators with field selectors ( = and == mean the same thing). For example: kubectl get ingress --field-selector foo.bar=baz With operators, kubectl get services --all-namespaces --field-selector metadata.namespace!=default Chained selectors, kubectl get pods --field-selector=status.phase!=Running,spec.restartPolicy=Always Multiple resource types, kubectl get statefulsets,services --all-namespaces --field-selector metadata.namespace!=default Finalizers \u00b6 Finalizers are namespaced keys that tell Kubernetes to wait until specific conditions are met before it fully deletes resources marked for deletion . Finalizers alert controllers to clean up resources the deleted object owned. Finalizers are usually added to resources for a reason, so forcefully removing them can lead to issues in the cluster. Like labels, owner references describe the relationships between objects in Kubernetes, but are used for a different purpose. Kubernetes uses the owner references (not labels) to determine which Pods in the cluster need cleanup. Kubernetes processes finalizers when it identifies owner references on a resource targeted for deletion. Owners and Dependents \u00b6 In Kubernetes, some objects are owners of other objects. For example, a ReplicaSet is the owner of a set of Pods. These owned objects are dependents of their owner. Dependent objects have a metadata.ownerReferences field that references their owner object. A valid owner reference consists of the object name and a UID within the same namespace as the dependent object. Dependent objects also have an ownerReferences.blockOwnerDeletion field that takes a boolean value and controls whether specific dependents can block garbage collection from deleting their owner object. Resource \u00b6 Kubernetes resources and \"records of intent\" are all stored as API objects, and modified via RESTful calls to the API. The API allows configuration to be managed in a declarative way. Users can interact with the Kubernetes API directly, or via tools like kubectl. The core Kubernetes API is flexible and can also be extended to support custom resources. Workload Resources Pod . Pod is a collection of containers that can run on a host. PodTemplate . PodTemplate describes a template for creating copies of a predefined pod. ReplicationController . ReplicationController represents the configuration of a replication controller. ReplicaSet . ReplicaSet ensures that a specified number of pod replicas are running at any given time. Deployment . Deployment enables declarative updates for Pods and ReplicaSets. StatefulSet . StatefulSet represents a set of pods with consistent identities. ControllerRevision . ControllerRevision implements an immutable snapshot of state data. DaemonSet . DaemonSet represents the configuration of a daemon set. Job . Job represents the configuration of a single job. CronJob . CronJob represents the configuration of a single cron job. HorizontalPodAutoscaler . configuration of a horizontal pod autoscaler. HorizontalPodAutoscaler . HorizontalPodAutoscaler is the configuration for a horizontal pod autoscaler, which automatically manages the replica count of any resource implementing the scale subresource based on the metrics specified. HorizontalPodAutoscaler v2beta2 . HorizontalPodAutoscaler is the configuration for a horizontal pod autoscaler, which automatically manages the replica count of any resource implementing the scale subresource based on the metrics specified. PriorityClass . PriorityClass defines mapping from a priority class name to the priority integer value. Service Resources Service . Service is a named abstraction of software service (for example, mysql) consisting of local port (for example 3306) that the proxy listens on, and the selector that determines which pods will answer requests sent through the proxy. Endpoints . Endpoints is a collection of endpoints that implement the actual service. EndpointSlice . EndpointSlice represents a subset of the endpoints that implement a service. Ingress . Ingress is a collection of rules that allow inbound connections to reach the endpoints defined by a backend. IngressClass . IngressClass represents the class of the Ingress, referenced by the Ingress Spec. Config and Storage Resources ConfigMap . ConfigMap holds configuration data for pods to consume. Secret . Secret holds secret data of a certain type. Volume . Volume represents a named volume in a pod that may be accessed by any container in the pod. PersistentVolumeClaim . PersistentVolumeClaim is a user's request for and claim to a persistent volume. PersistentVolume . PersistentVolume (PV) is a storage resource provisioned by an administrator. StorageClass . StorageClass describes the parameters for a class of storage for which PersistentVolumes can be dynamically provisioned. VolumeAttachment . VolumeAttachment captures the intent to attach or detach the specified volume to/from the specified node. CSIDriver . CSIDriver captures information about a Container Storage Interface (CSI) volume driver deployed on the cluster. CSINode . CSINode holds information about all CSI drivers installed on a node. CSIStorageCapacity . CSIStorageCapacity stores the result of one CSI GetCapacity call. Authentication Resources ServiceAccount . ServiceAccount binds together: a name, understood by users, and perhaps by peripheral systems, for an identity a principal that can be authenticated and authorized a set of secrets. TokenRequest . TokenRequest requests a token for a given service account. TokenReview . TokenReview attempts to authenticate a token to a known user. CertificateSigningRequest . CertificateSigningRequest objects provide a mechanism to obtain x509 certificates by submitting a certificate signing request, and having it asynchronously approved and issued. Authorization Resources LocalSubjectAccessReview . LocalSubjectAccessReview checks whether or not a user or group can perform an action in a given namespace. SelfSubjectAccessReview . SelfSubjectAccessReview checks whether or the current user can perform an action. SelfSubjectRulesReview . SelfSubjectRulesReview enumerates the set of actions the current user can perform within a namespace. SubjectAccessReview . SubjectAccessReview checks whether or not a user or group can perform an action. ClusterRole . ClusterRole is a cluster level, logical grouping of PolicyRules that can be referenced as a unit by a RoleBinding or ClusterRoleBinding. ClusterRoleBinding . ClusterRoleBinding references a ClusterRole, but not contain it. Role . Role is a namespaced, logical grouping of PolicyRules that can be referenced as a unit by a RoleBinding. RoleBinding . RoleBinding references a role, but does not contain it. Policy Resources LimitRange . LimitRange sets resource usage limits for each kind of resource in a Namespace. ResourceQuota . ResourceQuota sets aggregate quota restrictions enforced per namespace. NetworkPolicy . NetworkPolicy describes what network traffic is allowed for a set of Pods. PodDisruptionBudget . PodDisruptionBudget is an object to define the max disruption that can be caused to a collection of pods. PodSecurityPolicy v1beta1 . PodSecurityPolicy governs the ability to make requests that affect the Security Context that will be applied to a pod and container. Extend Resources CustomResourceDefinition . CustomResourceDefinition represents a resource that should be exposed on the API server. MutatingWebhookConfiguration . MutatingWebhookConfiguration describes the configuration of and admission webhook that accept or reject and may change the object. *ValidatingWebhookConfiguration(). ValidatingWebhookConfiguration describes the configuration of and admission webhook that accept or reject and object without changing it. Cluster Resources Node . Node is a worker node in Kubernetes. Namespace . Namespace provides a scope for Names. Event . Event is a report of an event somewhere in the cluster. APIService . APIService represents a server for a particular GroupVersion. Lease . Lease defines a lease concept. RuntimeClass . RuntimeClass defines a class of container runtime supported in the cluster. FlowSchema v1beta2 . FlowSchema defines the schema of a group of flows. PriorityLevelConfiguration v1beta2 . PriorityLevelConfiguration represents the configuration of a priority level. Binding . Binding ties one object to another; for example, a pod is bound to a node by a scheduler. ComponentStatus . ComponentStatus (and ComponentStatusList) holds the cluster validation info. Command kube api-resources to get the supported API resources. Command kubectl explain RESOURCE [options] describes the fields associated with each supported API resource. Fields are identified via a simple JSONPath identifier: kubectl explain binding kubectl explain binding.metadata kubectl explain binding.metadata.name Workload Resources \u00b6 Pods \u00b6 Pods are the smallest deployable units of computing that you can create and manage in Kubernetes. A Pod is a group of one or more containers, with shared storage and network resources, and a specification for how to run the containers. A Pod's contents are always co-located and co-scheduled, and run in a shared context. A Pod models an application-specific \"logical host\": it contains one or more application containers which are relatively tightly coupled. In non-cloud contexts, applications executed on the same physical or virtual machine are analogous to cloud applications executed on the same logical host. The shared context of a Pod is a set of Linux namespaces, cgroups, and potentially other facets of isolation - the same things that isolate a Docker container. In terms of Docker concepts, a Pod is similar to a group of Docker containers with shared namespaces and shared filesystem volumes. Usually you don't need to create Pods directly, even singleton Pods. Instead, create them using workload resources such as Deployment or Job . If your Pods need to track state, consider the StatefulSet resource. Pods in a Kubernetes cluster are used in two main ways: Pods that run a single container. Pods that run multiple containers that need to work together. The \"one-container-per-Pod\" model is the most common Kubernetes use case; in this case, you can think of a Pod as a wrapper around a single container; Kubernetes manages Pods rather than managing the containers directly. A Pod can encapsulate an application composed of multiple co-located containers that are tightly coupled and need to share resources. These co-located containers form a single cohesive unit of service\u2014for example, one container serving data stored in a shared volume to the public, while a separate sidecar container refreshes or updates those files. The Pod wraps these containers, storage resources, and an ephemeral network identity together as a single unit. Grouping multiple co-located and co-managed containers in a single Pod is a relatively advanced use case. You should use this pattern only in specific instances in which your containers are tightly coupled. Each Pod is meant to run a single instance of a given application. If you want to scale your application horizontally (to provide more overall resources by running more instances), you should use multiple Pods, one for each instance. In Kubernetes, this is typically referred to as replication . Replicated Pods are usually created and managed as a group by a workload resource and its controller. Pods natively provide two kinds of shared resources for their constituent containers: networking and storage . A Pod can specify a set of shared storage volumes. All containers in the Pod can access the shared volumes, allowing those containers to share data. Each Pod is assigned a unique IP address for each address family. Within a Pod, containers share an IP address and port space, and can find each other via localhost . Containers that want to interact with a container running in a different Pod can use IP networking to communicate. When a Pod gets created, the new Pod is scheduled to run on a Node in your cluster. The Pod remains on that node until the Pod finishes execution, the Pod object is deleted, the Pod is evicted for lack of resources, or the node fails. Restarting a container in a Pod should not be confused with restarting a Pod. A Pod is not a process, but an environment for running container(s). A Pod persists until it is deleted. You can use workload resources (e.g., Deployment, StatefulSet, DaemonSet) to create and manage multiple Pods for you. A controller for the resource handles replication and rollout and automatic healing in case of Pod failure. InitContainer \u00b6 Some Pods have init containers as well as app containers. Init containers run and complete before the app containers are started. You can specify init containers in the Pod specification alongside the containers array (which describes app containers). Static Pod \u00b6 Static Pods are managed directly by the kubelet daemon on a specific node, without the API server observing them. Static Pods are always bound to one Kubelet on a specific node. The main use for static Pods is to run a self-hosted control plane: in other words, using the kubelet to supervise the individual control plane components. The kubelet automatically tries to create a mirror Pod on the Kubernetes API server for each static Pod. This means that the Pods running on a node are visible on the API server, but cannot be controlled from there. Container probes \u00b6 A probe is a diagnostic performed periodically by the kubelet on a container. To perform a diagnostic, the kubelet either executes code within the container, or makes a network request. There are four different ways to check a container using a probe. Each probe must define exactly one of these four mechanisms: exec . The diagnostic is considered successful if the command exits with a status code of 0. grpc . The diagnostic is considered successful if the status of the response is SERVING. httpGet . The diagnostic is considered successful if the response has a status code greater than or equal to 200 and less than 400. tcpSocket . The diagnostic is considered successful if the port is open. Each probe has one of three results: Success Failure Unknown Types of probe: livenessProbe . Indicates whether the container is running. readinessProbe . Indicates whether the container is ready to respond to requests. startupProbe . Indicates whether the application within the container is started. Deployment \u00b6 ReplicaSet \u00b6 A ReplicaSet\u2019s purpose is to maintain a stable set of replica Pods running at any given time. As such, it is often used to guarantee the availability of a specified number of identical Pods. You may never need to manipulate ReplicaSet objects: use a Deployment instead, and define your application in the spec section. You can specify how many Pods should run concurrently by setting replicaset.spec.replicas . The ReplicaSet will create/delete its Pods to match this number. If you do not specify replicaset.spec.replicas , then it defaults to 1 . StatefulSet \u00b6 StatefulSet Characteristics (aka, stick ID): Pod's name is immutable after created. DNS hostname is immutable after created. Mounted volume is immutable after created. Stick ID of StatefulSet won't be changed after failure, scaling, and other operations. Naming convention of StatefulSet: - . StatefulSet can be scalling by itsself, but Deployment need rely on ReplicaSet for scalling. Recommendation: reduce StatefulSet to 0 first instead of delete it directly. headless Service and governing Service: Headless Service is a normal Kubernetes Service object that its spec.clusterIP is set to None . When spec.ServiceName of StatefulSet is set to the headless Service name, the StatefulSet is now a governing Service. General procedure to create a StatefulSet: Create a StorageClass Create Headless Service Create StatefulSet based on above two. DaemonSet \u00b6 A DaemonSet ensures that all (or some) Nodes run a copy of a Pod. As nodes are removed from the cluster, those Pods are garbage collected. Deleting a DaemonSet will clean up the Pods it created. Some typical uses of a DaemonSet are: running a cluster storage daemon on every node running a logs collection daemon on every node running a node monitoring daemon on every node In a simple case, one DaemonSet, covering all nodes, would be used for each type of daemon. A more complex setup might use multiple DaemonSets for a single type of daemon, but with different flags and/or different memory and cpu requests for different hardware types. The DaemonSet controller reconciliation process reviews both existing nodes and newly created nodes. By default, the Kubernetes scheduler ignores the pods created by the DamonSet, and lets them exist on the node until the node itself is shut down. Running Pods on select Nodes: If you specify a daemonset.spec.template.spec.nodeSelector , then the DaemonSet controller will create Pods on nodes which match that node selector. If you specify a daemonset.spec.template.spec.affinity , then DaemonSet controller will create Pods on nodes which match that node affinity. If you do not specify either, then the DaemonSet controller will create Pods on all nodes. There is no field replicas in kubectl explain daemonset.spec against with kubectl explain deployment.spec.replicas . When a DaemonSet is created, each node will have one DaemonSet Pod running. We\u2019ll use a Deployment / ReplicaSet for services, mostly stateless, where we don\u2019t care where the node is running, but we care more about the number of copies of our pod is running, and we can scale those copies/replicas up or down. Rolling updates would also be a benefit here. We\u2019ll use a DaemonSet when a copy of our pod must be running on the specific nodes that we require. Our daemon pod also needs to start before any of our other pods. A DaemonSet is a simple scalability strategy for background services. When more eligible nodes are added to the cluster, the background service scales up. When nodes are removed, it will automatically scale down. Job \u00b6 CronJob \u00b6 Service Resource \u00b6 Service \u00b6 Service is a named abstraction of software service (for example, mysql) consisting of local port (for example 3306) that the proxy listens on, and the selector that determines which pods will answer requests sent through the proxy. The set of Pods targeted by a Service is usually determined by a selector (label selector). Type of service resource: ClusterIP Service (default): Reliable IP, DNS, and Port. Internal acess only. NodePort Service: Expose to external access. LoadBalancer: Based on NodePort and integrated with loader balance provided by cloud venders (e.g., AWS, GCP, etc.). ExternalName: Acces will be trafficed to external service. Here is an example of yaml file to create a Service. apiVersion : v1 kind : Service metadata : name : nginx-service labels : tier : application spec : ports : - port : 80 protocol : TCP targetPort : 8080 selector : run : nginx type : NodePort Here is an example of Service. IP 10.96.17.77 is ClusterIP(VIP) of the service Port 80/TCP is the port on Pod that service listening within the cluster. TargetPort 8080/TCP is the port on the container that the service should direct traffic to. NodePort 31893/TCP is the port that can be accessed outside. Default range is 30000~32767 . The port is exposed across all nodes in cluster. Endpoints show the list of Pods matched the service labels. Name: nginx-deployment Namespace: jh-namespace Labels: tier=application Annotations: Selector: run=nginx Type: NodePort IP Family Policy: SingleStack IP Families: IPv4 IP: 10.96.17.77 IPs: 10.96.17.77 Port: 80/TCP TargetPort: 8080/TCP NodePort: 31893/TCP Endpoints: 10.244.1.177:8080,10.244.1.178:8080,10.244.1.179:8080 + 7 more... Session Affinity: None External Traffic Policy: Cluster Events: Service kube-dns beyond Deployment coredns provides cluster DNS service in Kubernetes cluster. Service registration: Kubernetes uses cluster DNS as service registration. Registration is Service based, not Pod based. Cluster DNS (CoreDNS) is monitoring and discvering new service actively. Service Name, IP, Port will be registered. Procedure of Service registration. POST new Service to API Server. Assign ClusterIP to the new Service. Save new Service configuration info to etcd. Create endpoints with related Pod IPs associated with the new Service. Explore the new Service by ClusterDNS. Create DNS info. kube-proxy fetch Service configration info. Create IPSV rule. Procedure of Service discovery. Request DNS name resolution for a Service name. Receive ClusterIP. Traffic access to ClusterIP. No router. Forward request to Pod's default gateway. Forward request to node. No router. Forward request to Node's default gateway. Proceed the request by Node kernel. Trap the request by IPSV rule. Put destination Pod's IP into the request's destination IP. The request arrives destination Pod. FQDN format: ..svc.cluster.local . We call as unqualified name, or short name. Namespaces can segregate the cluster's address space. At the same time, it can also be used to implement access control and resource quotas. Get DNS configuration in a Pod. The IP of nameserver is same with ClusterIP of kube-dns Service, which is well-known IP for request of DNS or service discovery. root@cka001:/etc# kubectl get service kube-dns -n kube-system NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE kube-dns ClusterIP 10.96.0.10 53/UDP,53/TCP,9153/TCP 7d7h root@cka001:~# kubectl exec -it nginx-5f5496dc9-bv5dx -- /bin/bash root@nginx-5f5496dc9-bv5dx:/# cat /etc/resolv.conf search jh-namespace.svc.cluster.local svc.cluster.local cluster.local nameserver 10.96.0.10 options ndots:5 Get information of kube-dns . root@cka001:~# kubectl describe service kube-dns -n kube-system Name: kube-dns Namespace: kube-system Labels: k8s-app=kube-dns kubernetes.io/cluster-service=true kubernetes.io/name=CoreDNS Annotations: prometheus.io/port: 9153 prometheus.io/scrape: true Selector: k8s-app=kube-dns Type: ClusterIP IP Family Policy: SingleStack IP Families: IPv4 IP: 10.96.0.10 IPs: 10.96.0.10 Port: dns 53/UDP TargetPort: 53/UDP Endpoints: 10.244.0.2:53,10.244.0.3:53 Port: dns-tcp 53/TCP TargetPort: 53/TCP Endpoints: 10.244.0.2:53,10.244.0.3:53 Port: metrics 9153/TCP TargetPort: 9153/TCP Endpoints: 10.244.0.2:9153,10.244.0.3:9153 Session Affinity: None Events: Endpoints \u00b6 Endpoints is a collection of endpoints that implement the actual service. When a service is created, it associates with a Endpoint object, kubectl get endpoints . A list of matched Pod by service label is maintained as Endpoint object, add new matched Pods and remove not matched Pods. Config and Storage Resources \u00b6 Volumes \u00b6 emptyDir \u00b6 An emptyDir volume is first created when a Pod is assigned to a node, and exists as long as that Pod is running on that node. The emptyDir volume is initially empty. All containers in the Pod can read and write the same files in the emptyDir volume, though that volume can be mounted at the same or different paths in each container. When a Pod is removed from a node for any reason, the data in the emptyDir is deleted permanently. A container crashing does not remove a Pod from a node. The data in an emptyDir volume is safe across container crashes. Usage: scratch space, such as for a disk-based merge sort checkpointing a long computation for recovery from crashes holding files that a content-manager container fetches while a webserver container serves the data hostPath \u00b6 A hostPath volume mounts a file or directory from the host node's filesystem into your Pod. This is not something that most Pods will need, but it offers a powerful escape hatch for some applications. hostPath volumes present many security risks, and it is a best practice to avoid the use of HostPaths when possible. When a HostPath volume MUST be used, it should be scoped to only the required file or directory, and mounted as ReadOnly. If restricting HostPath access to specific directories through AdmissionPolicy, volumeMounts MUST be required to use readOnly mounts for the policy to be effective. Usage: Running together with DaemonSet, e.g., EFK Fluentd mount log directory of local host in order to collect host log information. Running on a specific node by using hostPath volumne, which can get high performance disk I/O. Running a container that needs access to Docker internals; use a hostPath of /var/lib/docker . Running cAdvisor in a container; use a hostPath of /sys . Allowing a Pod to specify whether a given hostPath should exist prior to the Pod running, whether it should be created, and what it should exist as. Storage Class \u00b6 Procedure of StorageClass deployment and implementation: Create Kubernetes cluster and backend storage. Make sure the provisioner/plugin is ready in Kubernetes. Create a StorageClass object to link to backend storage. The StorageClass will create related PV automatically. Create a PVC object to link to the StorageClass we created. Deploy a Pod and use the PVC volume. PV \u00b6 PV Recycle Policy. Retain. Delete. Recycle. PV in-tree type: hostPath local NFS CSI Access Modes \u00b6 spec.accessModes defines mount option of a PV: ReadWriteOnce(RWO). A PV can be mounted only to a PVC with read/write mode, like block device. ReadWriteMany(RWM). A PV can be mounted to more than one PVC with read/write mode, like NFS. ReadOnlyMany(ROM). A PV can be mounted to more than one PVC with read only mode. ReadWriteOncePod (RWOP). Only support CSI type PV, can be mounted by single Pod. A PV can only be set with one option. Pod mount PVC, not PV.","title":"Memo"},{"location":"k8s/cka_en/foundamentals/memo/#kubernetes-learning-memo","text":"","title":"Kubernetes Learning Memo"},{"location":"k8s/cka_en/foundamentals/memo/#basic-concepts-of-kubernetes","text":"","title":"Basic Concepts of Kubernetes"},{"location":"k8s/cka_en/foundamentals/memo/#kubernetes-components","text":"A Kubernetes cluster consists of the components that represent the control plane and a set of machines called nodes . Kubernetes Components : Control Plane Components kube-apiserver: query and manipulate the state of objects in Kubernetes. play as \"communication hub\" among all resources in cluster. provide cluster security authentication, authorization, and role assignment. the only one can connect to etcd . etcd: all Kubernetes objects are stored on etcd. Kubernetes objects are persistent entities in the Kubernetes system, which are used to represent the state of your cluster. kube-scheduler: watches for newly created Pods with no assigned node, and selects a node for them to run on. kube-controller-manager: runs controller processes. Node controller : Responsible for noticing and responding when nodes go down. Job controller : Watches for Job objects that represent one-off tasks, then creates Pods to run those tasks to completion. Endpoints controller : Populates the Endpoints object (that is, joins Services & Pods). Service Account & Token controllers : Create default accounts and API access tokens for new namespaces. cloud-controller-manager: embeds cloud-specific control logic and only runs controllers that are specific to your cloud provider, no need for own premises and learning environment. Node controller : For checking the cloud provider to determine if a node has been deleted in the cloud after it stops responding Route controller : For setting up routes in the underlying cloud infrastructure Service controller : For creating, updating and deleting cloud provider load balancers Node Components kubelet: An agent that runs on each node in the cluster. Manage node. It makes sure that containers are running in a Pod. kubelet registers and updates nodes information to APIServer, and APIServer stores them into etcd . Manage pod. Watch pod via APIServer, and action on pods or containers in pods. Health check at container level. kube-proxy: is a network proxy that runs on each node in cluster. iptables ipvs maintains network rules on nodes. Container runtime: is the software that is responsible for running containers. Addons DNS: is a DNS server and required by all Kubernetes clusters. Web UI (Dashboard): web-based UI for Kubernetes clusters. Container Resource Monitoring: records generic time-series metrics about containers in a central database Cluster-level Logging: is responsible for saving container logs to a central log store with search/browsing interface. Scalability: Scaling out (horizontal scaling) by adding more servers to your architecture to spread the workload across more machines. Scaling up (vertical scaling) by adding more hard drives and memory to increase the computing capacity of physical servers.","title":"Kubernetes Components"},{"location":"k8s/cka_en/foundamentals/memo/#kubernetes-api","text":"The REST API is the fundamental fabric of Kubernetes. All operations and communications between components, and external user commands are REST API calls that the API Server handles. Consequently, everything in the Kubernetes platform is treated as an API object and has a corresponding entry in the API. The core of Kubernetes' control plane is the API server. CRI: Container Runtime Interface CNI: Container Network Interface CSI: Container Storage Interface The API server exposes an HTTP API that lets end users, different parts of cluster, and external components communicate with one another. The Kubernetes API lets we query and manipulate the state of API objects in Kubernetes (for example: Pods, Namespaces, ConfigMaps, and Events). Kubernetes API: OpenAPI specification OpenAPI V2 OpenAPI V3 Persistence. Kubernetes stores the serialized state of objects by writing them into etcd. API groups and versioning. Versioning is done at the API level. API resources are distinguished by their API group, resource type, namespace (for namespaced resources), and name. API changes API Extension","title":"Kubernetes API"},{"location":"k8s/cka_en/foundamentals/memo/#api-version","text":"The API versioning and software versioning are indirectly related. The API and release versioning proposal describes the relationship between API versioning and software versioning. Different API versions indicate different levels of stability and support. Here's a summary of each level: Alpha: The version names contain alpha (for example, v1alpha1). The software may contain bugs. Enabling a feature may expose bugs. A feature may be disabled by default. The support for a feature may be dropped at any time without notice. The API may change in incompatible ways in a later software release without notice. The software is recommended for use only in short-lived testing clusters, due to increased risk of bugs and lack of long-term support. Beta: The version names contain beta (for example, v2beta3). The software is well tested. Enabling a feature is considered safe. Features are enabled by default. The support for a feature will not be dropped, though the details may change. The schema and/or semantics of objects may change in incompatible ways in a subsequent beta or stable release. When this happens, migration instructions are provided. Schema changes may require deleting, editing, and re-creating API objects. The editing process may not be straightforward. The migration may require downtime for applications that rely on the feature. The software is not recommended for production uses. Subsequent releases may introduce incompatible changes. If you have multiple clusters which can be upgraded independently, you may be able to relax this restriction. Note: Please try beta features and provide feedback. After the features exit beta, it may not be practical to make more changes. Stable: The version name is vX where X is an integer. The stable versions of features appear in released software for many subsequent versions. Command to get current API kubectl api-resources","title":"API Version"},{"location":"k8s/cka_en/foundamentals/memo/#api-group","text":"API groups make it easier to extend the Kubernetes API. The API group is specified in a REST path and in the apiVersion field of a serialized object. There are several API groups in Kubernetes: The core (also called legacy) group is found at REST path /api/v1 . The core group is not specified as part of the apiVersion field, for example, apiVersion: v1. The named groups are at REST path /apis/$GROUP_NAME/$VERSION and use apiVersion: $GROUP_NAME/$VERSION (for example, apiVersion: batch/v1).","title":"API Group"},{"location":"k8s/cka_en/foundamentals/memo/#kubernetes-objects","text":"","title":"Kubernetes Objects"},{"location":"k8s/cka_en/foundamentals/memo/#objects-overview","text":"Object Spec: providing a description of the characteristics the resource created to have: its desired state . Object Status: describes the current state of the object. Example of Deployment as an object that can represent an application running on cluster. apiVersion : apps/v1 # Which version of the Kubernetes API you're using to create this object kind : Deployment # What kind of object you want to create metadata : # Data that helps uniquely identify the object, including a name string, UID, and optional namespace name : nginx-deployment spec : # What state you desire for the object selector : matchLabels : app : nginx replicas : 2 # tells deployment to run 2 pods matching the template template : metadata : labels : app : nginx spec : containers : - name : nginx image : nginx:1.14.2 ports : - containerPort : 80","title":"Objects Overview"},{"location":"k8s/cka_en/foundamentals/memo/#object-management","text":"The kubectl command-line tool supports several different ways to create and manage Kubernetes objects. Read the Kubectl book for details. A Kubernetes object should be managed using ONLY one technique. Mixing and matching techniques for the same object results in undefined behavior. Three management techniques: Imperative commands operates directly on live objects in a cluster. kubectl create deployment nginx --image nginx Imperative object configuration kubectl create -f nginx.yaml kubectl delete -f nginx.yaml -f redis.yaml kubectl replace -f nginx.yaml Declarative object configuration kubectl diff -f configs/ kubectl apply -f configs/","title":"Object Management"},{"location":"k8s/cka_en/foundamentals/memo/#object-names-and-ids","text":"Each object in your cluster has a Name that is unique for that type of resource. DNS Subdomain Names Label Names Path Segment Names Every Kubernetes object also has a UID that is unique across the whole cluster.","title":"Object Names and IDs"},{"location":"k8s/cka_en/foundamentals/memo/#namespaces","text":"In Kubernetes, namespaces provides a mechanism for isolating groups of resources within a single cluster. Names of resources need to be unique within a namespace, but not across namespaces. Namespace-based scoping is applicable only for namespaced objects (e.g. Deployments, Services, etc) and not for cluster-wide objects (e.g. StorageClass, Nodes, PersistentVolumes, etc) Not All Objects are in a Namespace. Kubernetes starts with four initial namespaces: default The default namespace for objects with no other namespace kube-system The namespace for objects created by the Kubernetes system kube-public This namespace is created automatically and is readable by all users (including those not authenticated). This namespace is mostly reserved for cluster usage, in case that some resources should be visible and readable publicly throughout the whole cluster. The public aspect of this namespace is only a convention, not a requirement. kube-node-lease This namespace holds Lease objects associated with each node. Node leases allow the kubelet to send heartbeats so that the control plane can detect node failure. Viewing namespaces: kubectl get namespace Setting the namespace for a request kubectl run nginx --image=nginx --namespace= kubectl get pods --namespace=","title":"Namespaces"},{"location":"k8s/cka_en/foundamentals/memo/#labels-and-selectors","text":"Labels are key/value pairs that are attached to objects, such as pods. Valid label keys have two segments: an optional prefix and name, separated by a slash ( / ). Labels are intended to be used to specify identifying attributes of objects that are meaningful and relevant to users. Labels can be used to organize and to select subsets of objects. Labels can be attached to objects at creation time and subsequently added and modified at any time. Each object can have a set of key/value labels defined. Each Key must be unique for a given object. Example of labels: \"metadata\" : { \"labels\" : { \"key1\" : \"value1\" , \"key2\" : \"value2\" } } Unlike names and UIDs, labels do not provide uniqueness. In general, we expect many objects to carry the same label(s). The API currently supports two types of selectors: equality-based, e.g., environment = production , tier != frontend set-based, e.g., environment in (production, qa) , tier notin (frontend, backend) Sample commands: kubectl get pods -l environment=production,tier=frontend kubectl get pods -l 'environment in (production),tier in (frontend)' kubectl get pods -l 'environment in (production, qa)' kubectl get pods -l 'environment,environment notin (frontend)'","title":"Labels and Selectors"},{"location":"k8s/cka_en/foundamentals/memo/#annotations","text":"Use Kubernetes annotations to attach arbitrary non-identifying metadata to objects. Clients such as tools and libraries can retrieve this metadata. Use either labels or annotations to attach metadata to Kubernetes objects. Labels can be used to select objects and to find collections of objects that satisfy certain conditions. Annotations are not used to identify and select objects. Annotations, like labels, are key/value maps. The keys and the values in the map must be strings. \"metadata\" : { \"annotations\" : { \"key1\" : \"value1\" , \"key2\" : \"value2\" } } Valid annotation keys have two segments: an optional prefix and name, separated by a slash ( / ).","title":"Annotations"},{"location":"k8s/cka_en/foundamentals/memo/#field-selectors","text":"Field selectors let you select Kubernetes resources based on the value of one or more resource fields. Here are some examples of field selector queries: metadata.name=my-service metadata.namespace!=default status.phase=Pending This kubectl command selects all Pods for which the value of the status.phase field is Running: kubectl get pods --field-selector status.phase=Running Supported field selectors vary by Kubernetes resource type. All resource types support the metadata.name and metadata.namespace fields. Use the = , == , and != operators with field selectors ( = and == mean the same thing). For example: kubectl get ingress --field-selector foo.bar=baz With operators, kubectl get services --all-namespaces --field-selector metadata.namespace!=default Chained selectors, kubectl get pods --field-selector=status.phase!=Running,spec.restartPolicy=Always Multiple resource types, kubectl get statefulsets,services --all-namespaces --field-selector metadata.namespace!=default","title":"Field Selectors"},{"location":"k8s/cka_en/foundamentals/memo/#finalizers","text":"Finalizers are namespaced keys that tell Kubernetes to wait until specific conditions are met before it fully deletes resources marked for deletion . Finalizers alert controllers to clean up resources the deleted object owned. Finalizers are usually added to resources for a reason, so forcefully removing them can lead to issues in the cluster. Like labels, owner references describe the relationships between objects in Kubernetes, but are used for a different purpose. Kubernetes uses the owner references (not labels) to determine which Pods in the cluster need cleanup. Kubernetes processes finalizers when it identifies owner references on a resource targeted for deletion.","title":"Finalizers"},{"location":"k8s/cka_en/foundamentals/memo/#owners-and-dependents","text":"In Kubernetes, some objects are owners of other objects. For example, a ReplicaSet is the owner of a set of Pods. These owned objects are dependents of their owner. Dependent objects have a metadata.ownerReferences field that references their owner object. A valid owner reference consists of the object name and a UID within the same namespace as the dependent object. Dependent objects also have an ownerReferences.blockOwnerDeletion field that takes a boolean value and controls whether specific dependents can block garbage collection from deleting their owner object.","title":"Owners and Dependents"},{"location":"k8s/cka_en/foundamentals/memo/#resource","text":"Kubernetes resources and \"records of intent\" are all stored as API objects, and modified via RESTful calls to the API. The API allows configuration to be managed in a declarative way. Users can interact with the Kubernetes API directly, or via tools like kubectl. The core Kubernetes API is flexible and can also be extended to support custom resources. Workload Resources Pod . Pod is a collection of containers that can run on a host. PodTemplate . PodTemplate describes a template for creating copies of a predefined pod. ReplicationController . ReplicationController represents the configuration of a replication controller. ReplicaSet . ReplicaSet ensures that a specified number of pod replicas are running at any given time. Deployment . Deployment enables declarative updates for Pods and ReplicaSets. StatefulSet . StatefulSet represents a set of pods with consistent identities. ControllerRevision . ControllerRevision implements an immutable snapshot of state data. DaemonSet . DaemonSet represents the configuration of a daemon set. Job . Job represents the configuration of a single job. CronJob . CronJob represents the configuration of a single cron job. HorizontalPodAutoscaler . configuration of a horizontal pod autoscaler. HorizontalPodAutoscaler . HorizontalPodAutoscaler is the configuration for a horizontal pod autoscaler, which automatically manages the replica count of any resource implementing the scale subresource based on the metrics specified. HorizontalPodAutoscaler v2beta2 . HorizontalPodAutoscaler is the configuration for a horizontal pod autoscaler, which automatically manages the replica count of any resource implementing the scale subresource based on the metrics specified. PriorityClass . PriorityClass defines mapping from a priority class name to the priority integer value. Service Resources Service . Service is a named abstraction of software service (for example, mysql) consisting of local port (for example 3306) that the proxy listens on, and the selector that determines which pods will answer requests sent through the proxy. Endpoints . Endpoints is a collection of endpoints that implement the actual service. EndpointSlice . EndpointSlice represents a subset of the endpoints that implement a service. Ingress . Ingress is a collection of rules that allow inbound connections to reach the endpoints defined by a backend. IngressClass . IngressClass represents the class of the Ingress, referenced by the Ingress Spec. Config and Storage Resources ConfigMap . ConfigMap holds configuration data for pods to consume. Secret . Secret holds secret data of a certain type. Volume . Volume represents a named volume in a pod that may be accessed by any container in the pod. PersistentVolumeClaim . PersistentVolumeClaim is a user's request for and claim to a persistent volume. PersistentVolume . PersistentVolume (PV) is a storage resource provisioned by an administrator. StorageClass . StorageClass describes the parameters for a class of storage for which PersistentVolumes can be dynamically provisioned. VolumeAttachment . VolumeAttachment captures the intent to attach or detach the specified volume to/from the specified node. CSIDriver . CSIDriver captures information about a Container Storage Interface (CSI) volume driver deployed on the cluster. CSINode . CSINode holds information about all CSI drivers installed on a node. CSIStorageCapacity . CSIStorageCapacity stores the result of one CSI GetCapacity call. Authentication Resources ServiceAccount . ServiceAccount binds together: a name, understood by users, and perhaps by peripheral systems, for an identity a principal that can be authenticated and authorized a set of secrets. TokenRequest . TokenRequest requests a token for a given service account. TokenReview . TokenReview attempts to authenticate a token to a known user. CertificateSigningRequest . CertificateSigningRequest objects provide a mechanism to obtain x509 certificates by submitting a certificate signing request, and having it asynchronously approved and issued. Authorization Resources LocalSubjectAccessReview . LocalSubjectAccessReview checks whether or not a user or group can perform an action in a given namespace. SelfSubjectAccessReview . SelfSubjectAccessReview checks whether or the current user can perform an action. SelfSubjectRulesReview . SelfSubjectRulesReview enumerates the set of actions the current user can perform within a namespace. SubjectAccessReview . SubjectAccessReview checks whether or not a user or group can perform an action. ClusterRole . ClusterRole is a cluster level, logical grouping of PolicyRules that can be referenced as a unit by a RoleBinding or ClusterRoleBinding. ClusterRoleBinding . ClusterRoleBinding references a ClusterRole, but not contain it. Role . Role is a namespaced, logical grouping of PolicyRules that can be referenced as a unit by a RoleBinding. RoleBinding . RoleBinding references a role, but does not contain it. Policy Resources LimitRange . LimitRange sets resource usage limits for each kind of resource in a Namespace. ResourceQuota . ResourceQuota sets aggregate quota restrictions enforced per namespace. NetworkPolicy . NetworkPolicy describes what network traffic is allowed for a set of Pods. PodDisruptionBudget . PodDisruptionBudget is an object to define the max disruption that can be caused to a collection of pods. PodSecurityPolicy v1beta1 . PodSecurityPolicy governs the ability to make requests that affect the Security Context that will be applied to a pod and container. Extend Resources CustomResourceDefinition . CustomResourceDefinition represents a resource that should be exposed on the API server. MutatingWebhookConfiguration . MutatingWebhookConfiguration describes the configuration of and admission webhook that accept or reject and may change the object. *ValidatingWebhookConfiguration(). ValidatingWebhookConfiguration describes the configuration of and admission webhook that accept or reject and object without changing it. Cluster Resources Node . Node is a worker node in Kubernetes. Namespace . Namespace provides a scope for Names. Event . Event is a report of an event somewhere in the cluster. APIService . APIService represents a server for a particular GroupVersion. Lease . Lease defines a lease concept. RuntimeClass . RuntimeClass defines a class of container runtime supported in the cluster. FlowSchema v1beta2 . FlowSchema defines the schema of a group of flows. PriorityLevelConfiguration v1beta2 . PriorityLevelConfiguration represents the configuration of a priority level. Binding . Binding ties one object to another; for example, a pod is bound to a node by a scheduler. ComponentStatus . ComponentStatus (and ComponentStatusList) holds the cluster validation info. Command kube api-resources to get the supported API resources. Command kubectl explain RESOURCE [options] describes the fields associated with each supported API resource. Fields are identified via a simple JSONPath identifier: kubectl explain binding kubectl explain binding.metadata kubectl explain binding.metadata.name","title":"Resource"},{"location":"k8s/cka_en/foundamentals/memo/#workload-resources","text":"","title":"Workload Resources"},{"location":"k8s/cka_en/foundamentals/memo/#pods","text":"Pods are the smallest deployable units of computing that you can create and manage in Kubernetes. A Pod is a group of one or more containers, with shared storage and network resources, and a specification for how to run the containers. A Pod's contents are always co-located and co-scheduled, and run in a shared context. A Pod models an application-specific \"logical host\": it contains one or more application containers which are relatively tightly coupled. In non-cloud contexts, applications executed on the same physical or virtual machine are analogous to cloud applications executed on the same logical host. The shared context of a Pod is a set of Linux namespaces, cgroups, and potentially other facets of isolation - the same things that isolate a Docker container. In terms of Docker concepts, a Pod is similar to a group of Docker containers with shared namespaces and shared filesystem volumes. Usually you don't need to create Pods directly, even singleton Pods. Instead, create them using workload resources such as Deployment or Job . If your Pods need to track state, consider the StatefulSet resource. Pods in a Kubernetes cluster are used in two main ways: Pods that run a single container. Pods that run multiple containers that need to work together. The \"one-container-per-Pod\" model is the most common Kubernetes use case; in this case, you can think of a Pod as a wrapper around a single container; Kubernetes manages Pods rather than managing the containers directly. A Pod can encapsulate an application composed of multiple co-located containers that are tightly coupled and need to share resources. These co-located containers form a single cohesive unit of service\u2014for example, one container serving data stored in a shared volume to the public, while a separate sidecar container refreshes or updates those files. The Pod wraps these containers, storage resources, and an ephemeral network identity together as a single unit. Grouping multiple co-located and co-managed containers in a single Pod is a relatively advanced use case. You should use this pattern only in specific instances in which your containers are tightly coupled. Each Pod is meant to run a single instance of a given application. If you want to scale your application horizontally (to provide more overall resources by running more instances), you should use multiple Pods, one for each instance. In Kubernetes, this is typically referred to as replication . Replicated Pods are usually created and managed as a group by a workload resource and its controller. Pods natively provide two kinds of shared resources for their constituent containers: networking and storage . A Pod can specify a set of shared storage volumes. All containers in the Pod can access the shared volumes, allowing those containers to share data. Each Pod is assigned a unique IP address for each address family. Within a Pod, containers share an IP address and port space, and can find each other via localhost . Containers that want to interact with a container running in a different Pod can use IP networking to communicate. When a Pod gets created, the new Pod is scheduled to run on a Node in your cluster. The Pod remains on that node until the Pod finishes execution, the Pod object is deleted, the Pod is evicted for lack of resources, or the node fails. Restarting a container in a Pod should not be confused with restarting a Pod. A Pod is not a process, but an environment for running container(s). A Pod persists until it is deleted. You can use workload resources (e.g., Deployment, StatefulSet, DaemonSet) to create and manage multiple Pods for you. A controller for the resource handles replication and rollout and automatic healing in case of Pod failure.","title":"Pods"},{"location":"k8s/cka_en/foundamentals/memo/#initcontainer","text":"Some Pods have init containers as well as app containers. Init containers run and complete before the app containers are started. You can specify init containers in the Pod specification alongside the containers array (which describes app containers).","title":"InitContainer"},{"location":"k8s/cka_en/foundamentals/memo/#static-pod","text":"Static Pods are managed directly by the kubelet daemon on a specific node, without the API server observing them. Static Pods are always bound to one Kubelet on a specific node. The main use for static Pods is to run a self-hosted control plane: in other words, using the kubelet to supervise the individual control plane components. The kubelet automatically tries to create a mirror Pod on the Kubernetes API server for each static Pod. This means that the Pods running on a node are visible on the API server, but cannot be controlled from there.","title":"Static Pod"},{"location":"k8s/cka_en/foundamentals/memo/#container-probes","text":"A probe is a diagnostic performed periodically by the kubelet on a container. To perform a diagnostic, the kubelet either executes code within the container, or makes a network request. There are four different ways to check a container using a probe. Each probe must define exactly one of these four mechanisms: exec . The diagnostic is considered successful if the command exits with a status code of 0. grpc . The diagnostic is considered successful if the status of the response is SERVING. httpGet . The diagnostic is considered successful if the response has a status code greater than or equal to 200 and less than 400. tcpSocket . The diagnostic is considered successful if the port is open. Each probe has one of three results: Success Failure Unknown Types of probe: livenessProbe . Indicates whether the container is running. readinessProbe . Indicates whether the container is ready to respond to requests. startupProbe . Indicates whether the application within the container is started.","title":"Container probes"},{"location":"k8s/cka_en/foundamentals/memo/#deployment","text":"","title":"Deployment"},{"location":"k8s/cka_en/foundamentals/memo/#replicaset","text":"A ReplicaSet\u2019s purpose is to maintain a stable set of replica Pods running at any given time. As such, it is often used to guarantee the availability of a specified number of identical Pods. You may never need to manipulate ReplicaSet objects: use a Deployment instead, and define your application in the spec section. You can specify how many Pods should run concurrently by setting replicaset.spec.replicas . The ReplicaSet will create/delete its Pods to match this number. If you do not specify replicaset.spec.replicas , then it defaults to 1 .","title":"ReplicaSet"},{"location":"k8s/cka_en/foundamentals/memo/#statefulset","text":"StatefulSet Characteristics (aka, stick ID): Pod's name is immutable after created. DNS hostname is immutable after created. Mounted volume is immutable after created. Stick ID of StatefulSet won't be changed after failure, scaling, and other operations. Naming convention of StatefulSet: - . StatefulSet can be scalling by itsself, but Deployment need rely on ReplicaSet for scalling. Recommendation: reduce StatefulSet to 0 first instead of delete it directly. headless Service and governing Service: Headless Service is a normal Kubernetes Service object that its spec.clusterIP is set to None . When spec.ServiceName of StatefulSet is set to the headless Service name, the StatefulSet is now a governing Service. General procedure to create a StatefulSet: Create a StorageClass Create Headless Service Create StatefulSet based on above two.","title":"StatefulSet"},{"location":"k8s/cka_en/foundamentals/memo/#daemonset","text":"A DaemonSet ensures that all (or some) Nodes run a copy of a Pod. As nodes are removed from the cluster, those Pods are garbage collected. Deleting a DaemonSet will clean up the Pods it created. Some typical uses of a DaemonSet are: running a cluster storage daemon on every node running a logs collection daemon on every node running a node monitoring daemon on every node In a simple case, one DaemonSet, covering all nodes, would be used for each type of daemon. A more complex setup might use multiple DaemonSets for a single type of daemon, but with different flags and/or different memory and cpu requests for different hardware types. The DaemonSet controller reconciliation process reviews both existing nodes and newly created nodes. By default, the Kubernetes scheduler ignores the pods created by the DamonSet, and lets them exist on the node until the node itself is shut down. Running Pods on select Nodes: If you specify a daemonset.spec.template.spec.nodeSelector , then the DaemonSet controller will create Pods on nodes which match that node selector. If you specify a daemonset.spec.template.spec.affinity , then DaemonSet controller will create Pods on nodes which match that node affinity. If you do not specify either, then the DaemonSet controller will create Pods on all nodes. There is no field replicas in kubectl explain daemonset.spec against with kubectl explain deployment.spec.replicas . When a DaemonSet is created, each node will have one DaemonSet Pod running. We\u2019ll use a Deployment / ReplicaSet for services, mostly stateless, where we don\u2019t care where the node is running, but we care more about the number of copies of our pod is running, and we can scale those copies/replicas up or down. Rolling updates would also be a benefit here. We\u2019ll use a DaemonSet when a copy of our pod must be running on the specific nodes that we require. Our daemon pod also needs to start before any of our other pods. A DaemonSet is a simple scalability strategy for background services. When more eligible nodes are added to the cluster, the background service scales up. When nodes are removed, it will automatically scale down.","title":"DaemonSet"},{"location":"k8s/cka_en/foundamentals/memo/#job","text":"","title":"Job"},{"location":"k8s/cka_en/foundamentals/memo/#cronjob","text":"","title":"CronJob"},{"location":"k8s/cka_en/foundamentals/memo/#service-resource","text":"","title":"Service Resource"},{"location":"k8s/cka_en/foundamentals/memo/#service","text":"Service is a named abstraction of software service (for example, mysql) consisting of local port (for example 3306) that the proxy listens on, and the selector that determines which pods will answer requests sent through the proxy. The set of Pods targeted by a Service is usually determined by a selector (label selector). Type of service resource: ClusterIP Service (default): Reliable IP, DNS, and Port. Internal acess only. NodePort Service: Expose to external access. LoadBalancer: Based on NodePort and integrated with loader balance provided by cloud venders (e.g., AWS, GCP, etc.). ExternalName: Acces will be trafficed to external service. Here is an example of yaml file to create a Service. apiVersion : v1 kind : Service metadata : name : nginx-service labels : tier : application spec : ports : - port : 80 protocol : TCP targetPort : 8080 selector : run : nginx type : NodePort Here is an example of Service. IP 10.96.17.77 is ClusterIP(VIP) of the service Port 80/TCP is the port on Pod that service listening within the cluster. TargetPort 8080/TCP is the port on the container that the service should direct traffic to. NodePort 31893/TCP is the port that can be accessed outside. Default range is 30000~32767 . The port is exposed across all nodes in cluster. Endpoints show the list of Pods matched the service labels. Name: nginx-deployment Namespace: jh-namespace Labels: tier=application Annotations: Selector: run=nginx Type: NodePort IP Family Policy: SingleStack IP Families: IPv4 IP: 10.96.17.77 IPs: 10.96.17.77 Port: 80/TCP TargetPort: 8080/TCP NodePort: 31893/TCP Endpoints: 10.244.1.177:8080,10.244.1.178:8080,10.244.1.179:8080 + 7 more... Session Affinity: None External Traffic Policy: Cluster Events: Service kube-dns beyond Deployment coredns provides cluster DNS service in Kubernetes cluster. Service registration: Kubernetes uses cluster DNS as service registration. Registration is Service based, not Pod based. Cluster DNS (CoreDNS) is monitoring and discvering new service actively. Service Name, IP, Port will be registered. Procedure of Service registration. POST new Service to API Server. Assign ClusterIP to the new Service. Save new Service configuration info to etcd. Create endpoints with related Pod IPs associated with the new Service. Explore the new Service by ClusterDNS. Create DNS info. kube-proxy fetch Service configration info. Create IPSV rule. Procedure of Service discovery. Request DNS name resolution for a Service name. Receive ClusterIP. Traffic access to ClusterIP. No router. Forward request to Pod's default gateway. Forward request to node. No router. Forward request to Node's default gateway. Proceed the request by Node kernel. Trap the request by IPSV rule. Put destination Pod's IP into the request's destination IP. The request arrives destination Pod. FQDN format: ..svc.cluster.local . We call as unqualified name, or short name. Namespaces can segregate the cluster's address space. At the same time, it can also be used to implement access control and resource quotas. Get DNS configuration in a Pod. The IP of nameserver is same with ClusterIP of kube-dns Service, which is well-known IP for request of DNS or service discovery. root@cka001:/etc# kubectl get service kube-dns -n kube-system NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE kube-dns ClusterIP 10.96.0.10 53/UDP,53/TCP,9153/TCP 7d7h root@cka001:~# kubectl exec -it nginx-5f5496dc9-bv5dx -- /bin/bash root@nginx-5f5496dc9-bv5dx:/# cat /etc/resolv.conf search jh-namespace.svc.cluster.local svc.cluster.local cluster.local nameserver 10.96.0.10 options ndots:5 Get information of kube-dns . root@cka001:~# kubectl describe service kube-dns -n kube-system Name: kube-dns Namespace: kube-system Labels: k8s-app=kube-dns kubernetes.io/cluster-service=true kubernetes.io/name=CoreDNS Annotations: prometheus.io/port: 9153 prometheus.io/scrape: true Selector: k8s-app=kube-dns Type: ClusterIP IP Family Policy: SingleStack IP Families: IPv4 IP: 10.96.0.10 IPs: 10.96.0.10 Port: dns 53/UDP TargetPort: 53/UDP Endpoints: 10.244.0.2:53,10.244.0.3:53 Port: dns-tcp 53/TCP TargetPort: 53/TCP Endpoints: 10.244.0.2:53,10.244.0.3:53 Port: metrics 9153/TCP TargetPort: 9153/TCP Endpoints: 10.244.0.2:9153,10.244.0.3:9153 Session Affinity: None Events: ","title":"Service"},{"location":"k8s/cka_en/foundamentals/memo/#endpoints","text":"Endpoints is a collection of endpoints that implement the actual service. When a service is created, it associates with a Endpoint object, kubectl get endpoints . A list of matched Pod by service label is maintained as Endpoint object, add new matched Pods and remove not matched Pods.","title":"Endpoints"},{"location":"k8s/cka_en/foundamentals/memo/#config-and-storage-resources","text":"","title":"Config and Storage Resources"},{"location":"k8s/cka_en/foundamentals/memo/#volumes","text":"","title":"Volumes"},{"location":"k8s/cka_en/foundamentals/memo/#emptydir","text":"An emptyDir volume is first created when a Pod is assigned to a node, and exists as long as that Pod is running on that node. The emptyDir volume is initially empty. All containers in the Pod can read and write the same files in the emptyDir volume, though that volume can be mounted at the same or different paths in each container. When a Pod is removed from a node for any reason, the data in the emptyDir is deleted permanently. A container crashing does not remove a Pod from a node. The data in an emptyDir volume is safe across container crashes. Usage: scratch space, such as for a disk-based merge sort checkpointing a long computation for recovery from crashes holding files that a content-manager container fetches while a webserver container serves the data","title":"emptyDir"},{"location":"k8s/cka_en/foundamentals/memo/#hostpath","text":"A hostPath volume mounts a file or directory from the host node's filesystem into your Pod. This is not something that most Pods will need, but it offers a powerful escape hatch for some applications. hostPath volumes present many security risks, and it is a best practice to avoid the use of HostPaths when possible. When a HostPath volume MUST be used, it should be scoped to only the required file or directory, and mounted as ReadOnly. If restricting HostPath access to specific directories through AdmissionPolicy, volumeMounts MUST be required to use readOnly mounts for the policy to be effective. Usage: Running together with DaemonSet, e.g., EFK Fluentd mount log directory of local host in order to collect host log information. Running on a specific node by using hostPath volumne, which can get high performance disk I/O. Running a container that needs access to Docker internals; use a hostPath of /var/lib/docker . Running cAdvisor in a container; use a hostPath of /sys . Allowing a Pod to specify whether a given hostPath should exist prior to the Pod running, whether it should be created, and what it should exist as.","title":"hostPath"},{"location":"k8s/cka_en/foundamentals/memo/#storage-class","text":"Procedure of StorageClass deployment and implementation: Create Kubernetes cluster and backend storage. Make sure the provisioner/plugin is ready in Kubernetes. Create a StorageClass object to link to backend storage. The StorageClass will create related PV automatically. Create a PVC object to link to the StorageClass we created. Deploy a Pod and use the PVC volume.","title":"Storage Class"},{"location":"k8s/cka_en/foundamentals/memo/#pv","text":"PV Recycle Policy. Retain. Delete. Recycle. PV in-tree type: hostPath local NFS CSI","title":"PV"},{"location":"k8s/cka_en/foundamentals/memo/#access-modes","text":"spec.accessModes defines mount option of a PV: ReadWriteOnce(RWO). A PV can be mounted only to a PVC with read/write mode, like block device. ReadWriteMany(RWM). A PV can be mounted to more than one PVC with read/write mode, like NFS. ReadOnlyMany(ROM). A PV can be mounted to more than one PVC with read only mode. ReadWriteOncePod (RWOP). Only support CSI type PV, can be mounted by single Pod. A PV can only be set with one option. Pod mount PVC, not PV.","title":"Access Modes"},{"location":"k8s/cka_en/foundamentals/namespace/","text":"Namespace \u00b6 Scenario: Get namespace list Create new namespace Label a namespace Delete a namespace Demo: Get list of Namespace kubectl get namespace Get list of Namespace with Label information. kubectl get ns --show-labels Create a Namespace kubectl create namespace cka Label the new created Namespace cka . kubectl label ns cka cka=true Create Nginx Deployment in Namespace cka . kubectl create deploy nginx --image=nginx --namespace cka Check Deployments and Pods running in namespace cka . kubectl get deploy,pod -n cka Result is below. NAME READY UP-TO-DATE AVAILABLE AGE deployment.apps/nginx 1/1 1 1 2m14s NAME READY STATUS RESTARTS AGE pod/nginx-85b98978db-bmkhf 1/1 Running 0 2m14s Delete namespace cka . All resources in the namespaces will be gone. kubectl delete ns cka Tip: Kubernetes Namespaces stuck in Terminating status. kubectl get namespace $NAMESPACE -o json | sed -e 's/\"kubernetes\"//' | kubectl replace --raw \"/api/v1/namespaces/$NAMESPACE/finalize\" -f -","title":"Namespace"},{"location":"k8s/cka_en/foundamentals/namespace/#namespace","text":"Scenario: Get namespace list Create new namespace Label a namespace Delete a namespace Demo: Get list of Namespace kubectl get namespace Get list of Namespace with Label information. kubectl get ns --show-labels Create a Namespace kubectl create namespace cka Label the new created Namespace cka . kubectl label ns cka cka=true Create Nginx Deployment in Namespace cka . kubectl create deploy nginx --image=nginx --namespace cka Check Deployments and Pods running in namespace cka . kubectl get deploy,pod -n cka Result is below. NAME READY UP-TO-DATE AVAILABLE AGE deployment.apps/nginx 1/1 1 1 2m14s NAME READY STATUS RESTARTS AGE pod/nginx-85b98978db-bmkhf 1/1 Running 0 2m14s Delete namespace cka . All resources in the namespaces will be gone. kubectl delete ns cka Tip: Kubernetes Namespaces stuck in Terminating status. kubectl get namespace $NAMESPACE -o json | sed -e 's/\"kubernetes\"//' | kubectl replace --raw \"/api/v1/namespaces/$NAMESPACE/finalize\" -f -","title":"Namespace"},{"location":"k8s/cka_en/foundamentals/networkpolicy/","text":"Network Policy \u00b6 Replace Flannel by Calico \u00b6 Scenario Remove Flannel Install Calico Demo: If Calico was installed at the installation phase, ignore this section. Delete Flannel kubectl delete -f https://raw.githubusercontent.com/coreos/flannel/v0.18.1/Documentation/kube-flannel.yml or kubectl delete -f kube-flannel.yml Output: Warning: policy/v1beta1 PodSecurityPolicy is deprecated in v1.21+, unavailable in v1.25+ podsecuritypolicy.policy \"psp.flannel.unprivileged\" deleted clusterrole.rbac.authorization.k8s.io \"flannel\" deleted clusterrolebinding.rbac.authorization.k8s.io \"flannel\" deleted serviceaccount \"flannel\" deleted configmap \"kube-flannel-cfg\" deleted daemonset.apps \"kube-flannel-ds\" deleted Clean up iptables for all nodes. rm -rf /var/run/flannel /opt/cni /etc/cni /var/lib/cni iptables -F && iptables -t nat -F && iptables -t mangle -F && iptables -X Log out and log on to host (e.g., cka001) again. Install Calico. curl https://docs.projectcalico.org/manifests/calico.yaml -O kubectl apply -f calico.yaml Output: configmap/calico-config created customresourcedefinition.apiextensions.k8s.io/bgpconfigurations.crd.projectcalico.org created customresourcedefinition.apiextensions.k8s.io/bgppeers.crd.projectcalico.org created customresourcedefinition.apiextensions.k8s.io/blockaffinities.crd.projectcalico.org created customresourcedefinition.apiextensions.k8s.io/caliconodestatuses.crd.projectcalico.org created customresourcedefinition.apiextensions.k8s.io/clusterinformations.crd.projectcalico.org created customresourcedefinition.apiextensions.k8s.io/felixconfigurations.crd.projectcalico.org created customresourcedefinition.apiextensions.k8s.io/globalnetworkpolicies.crd.projectcalico.org created customresourcedefinition.apiextensions.k8s.io/globalnetworksets.crd.projectcalico.org created customresourcedefinition.apiextensions.k8s.io/hostendpoints.crd.projectcalico.org created customresourcedefinition.apiextensions.k8s.io/ipamblocks.crd.projectcalico.org created customresourcedefinition.apiextensions.k8s.io/ipamconfigs.crd.projectcalico.org created customresourcedefinition.apiextensions.k8s.io/ipamhandles.crd.projectcalico.org created customresourcedefinition.apiextensions.k8s.io/ippools.crd.projectcalico.org created customresourcedefinition.apiextensions.k8s.io/ipreservations.crd.projectcalico.org created customresourcedefinition.apiextensions.k8s.io/kubecontrollersconfigurations.crd.projectcalico.org created customresourcedefinition.apiextensions.k8s.io/networkpolicies.crd.projectcalico.org created customresourcedefinition.apiextensions.k8s.io/networksets.crd.projectcalico.org created clusterrole.rbac.authorization.k8s.io/calico-kube-controllers created clusterrolebinding.rbac.authorization.k8s.io/calico-kube-controllers created clusterrole.rbac.authorization.k8s.io/calico-node created clusterrolebinding.rbac.authorization.k8s.io/calico-node created daemonset.apps/calico-node created serviceaccount/calico-node created deployment.apps/calico-kube-controllers created serviceaccount/calico-kube-controllers created poddisruptionbudget.policy/calico-kube-controllers created Verify status of Calico. Make sure all Pods are running kubectl get pod -n kube-system | grep calico Output: NAME READY STATUS RESTARTS AGE calico-kube-controllers-7bc6547ffb-tjfcg 1/1 Running 0 30m calico-node-7x8jm 1/1 Running 0 30m calico-node-cwxj5 1/1 Running 0 30m calico-node-rq978 1/1 Running 0 30m If facing any error, check log in the Container. # Get Container ID crictl ps # Get log info crictl logs As we change CNI from Flannel to Calico, we need delete all Pods. All of Pods will be created automatically again. kubectl delete pod -A --all Make sure all Pods are up and running successfully. kubectl get pod -A Inbound Rules \u00b6 Scenario Create workload for test. Deny For All Ingress Allow For Specific Ingress Verify NetworkPolicy Demo: Create workload for test. \u00b6 Create three Deployments pod-netpol-1 , pod-netpol-2 , pod-netpol-3 based on image busybox . kubectl apply -f - << EOF apiVersion: apps/v1 kind: Deployment metadata: labels: app: pod-netpol-1 name: pod-netpol-1 spec: replicas: 1 selector: matchLabels: app: pod-netpol-1 template: metadata: labels: app: pod-netpol-1 spec: containers: - image: busybox name: busybox command: [\"sh\", \"-c\", \"sleep 1h\"] --- apiVersion: apps/v1 kind: Deployment metadata: labels: app: pod-netpol-2 name: pod-netpol-2 spec: replicas: 1 selector: matchLabels: app: pod-netpol-2 template: metadata: labels: app: pod-netpol-2 spec: containers: - image: busybox name: busybox command: [\"sh\", \"-c\", \"sleep 1h\"] --- apiVersion: apps/v1 kind: Deployment metadata: labels: app: pod-netpol-3 name: pod-netpol-3 spec: replicas: 1 selector: matchLabels: app: pod-netpol-3 template: metadata: labels: app: pod-netpol-3 spec: containers: - image: busybox name: busybox command: [\"sh\", \"-c\", \"sleep 1h\"] EOF Check Pods IP. kubectl get pod -owide Output: NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES pod-netpol-1-6494f6bf8b-n58r9 1/1 Running 0 29s 10.244.102.30 cka003 pod-netpol-2-77478d77ff-l6rzm 1/1 Running 0 29s 10.244.112.30 cka002 pod-netpol-3-68977dcb48-ql5s6 1/1 Running 0 29s 10.244.102.31 cka003 Attach to Pod pod-netpol-1 kubectl exec -it pod-netpol-1-6494f6bf8b-n58r9 -- sh Execute command ping that pod-netpol-2 and pod-netpol-3 are both reachable. / # ping 10.244.112.30 3 packets transmitted, 3 packets received, 0% packet loss / # ping 10.244.102.31 3 packets transmitted, 3 packets received, 0% packet loss Deny For All Ingress \u00b6 Create deny policy for all ingress. kubectl apply -f - << EOF apiVersion: networking.k8s.io/v1 kind: NetworkPolicy metadata: name: default-deny-ingress spec: podSelector: {} policyTypes: - Ingress EOF Attach to Pod pod-netpol-1 again kubectl exec -it pod-netpol-1-6494f6bf8b-n58r9 -- sh Execute command ping that pod-netpol-2 and pod-netpol-3 are both unreachable as expected. / # ping 10.244.112.30 3 packets transmitted, 0 packets received, 100% packet loss / # ping 10.244.102.31 3 packets transmitted, 0 packets received, 100% packet loss Allow For Specific Ingress \u00b6 Create NetworkPlicy to allow ingress from pod-netpol-1 to pod-netpol-2 . kubectl apply -f - <:80 failed. Command curl :80 succeed. kubectl run centos --image=centos -n my-ns-1 -- \"/bin/sh\" \"-c\" \"sleep 3600\" kubectl exec -it mycentos -n my-ns-1 -- bash Create temp pod on namespace my-ns-2 . Attach to the pod and verify the access. Command curl :80 failed. Command curl :80 failed. kubectl run centos --image=centos -n my-ns-2 -- \"/bin/sh\" \"-c\" \"sleep 3600\" kubectl exec -it mycentos -n my-ns-2 -- bash Edit my-networkpolicy-1 to change ingress.from.namespaceSelector.matchLabels to my-ns-2 . Attach to temp pod on namespace my-ns-2 . Verify the access. Command curl :80 failed. Command curl :80 succeed. kubectl exec -it mycentos -n my-ns-2 -- bash Clean up: kubectl delete namespace my-ns-1 kubectl delete namespace my-ns-2","title":"Network Policy"},{"location":"k8s/cka_en/foundamentals/networkpolicy/#network-policy","text":"","title":"Network Policy"},{"location":"k8s/cka_en/foundamentals/networkpolicy/#replace-flannel-by-calico","text":"Scenario Remove Flannel Install Calico Demo: If Calico was installed at the installation phase, ignore this section. Delete Flannel kubectl delete -f https://raw.githubusercontent.com/coreos/flannel/v0.18.1/Documentation/kube-flannel.yml or kubectl delete -f kube-flannel.yml Output: Warning: policy/v1beta1 PodSecurityPolicy is deprecated in v1.21+, unavailable in v1.25+ podsecuritypolicy.policy \"psp.flannel.unprivileged\" deleted clusterrole.rbac.authorization.k8s.io \"flannel\" deleted clusterrolebinding.rbac.authorization.k8s.io \"flannel\" deleted serviceaccount \"flannel\" deleted configmap \"kube-flannel-cfg\" deleted daemonset.apps \"kube-flannel-ds\" deleted Clean up iptables for all nodes. rm -rf /var/run/flannel /opt/cni /etc/cni /var/lib/cni iptables -F && iptables -t nat -F && iptables -t mangle -F && iptables -X Log out and log on to host (e.g., cka001) again. Install Calico. curl https://docs.projectcalico.org/manifests/calico.yaml -O kubectl apply -f calico.yaml Output: configmap/calico-config created customresourcedefinition.apiextensions.k8s.io/bgpconfigurations.crd.projectcalico.org created customresourcedefinition.apiextensions.k8s.io/bgppeers.crd.projectcalico.org created customresourcedefinition.apiextensions.k8s.io/blockaffinities.crd.projectcalico.org created customresourcedefinition.apiextensions.k8s.io/caliconodestatuses.crd.projectcalico.org created customresourcedefinition.apiextensions.k8s.io/clusterinformations.crd.projectcalico.org created customresourcedefinition.apiextensions.k8s.io/felixconfigurations.crd.projectcalico.org created customresourcedefinition.apiextensions.k8s.io/globalnetworkpolicies.crd.projectcalico.org created customresourcedefinition.apiextensions.k8s.io/globalnetworksets.crd.projectcalico.org created customresourcedefinition.apiextensions.k8s.io/hostendpoints.crd.projectcalico.org created customresourcedefinition.apiextensions.k8s.io/ipamblocks.crd.projectcalico.org created customresourcedefinition.apiextensions.k8s.io/ipamconfigs.crd.projectcalico.org created customresourcedefinition.apiextensions.k8s.io/ipamhandles.crd.projectcalico.org created customresourcedefinition.apiextensions.k8s.io/ippools.crd.projectcalico.org created customresourcedefinition.apiextensions.k8s.io/ipreservations.crd.projectcalico.org created customresourcedefinition.apiextensions.k8s.io/kubecontrollersconfigurations.crd.projectcalico.org created customresourcedefinition.apiextensions.k8s.io/networkpolicies.crd.projectcalico.org created customresourcedefinition.apiextensions.k8s.io/networksets.crd.projectcalico.org created clusterrole.rbac.authorization.k8s.io/calico-kube-controllers created clusterrolebinding.rbac.authorization.k8s.io/calico-kube-controllers created clusterrole.rbac.authorization.k8s.io/calico-node created clusterrolebinding.rbac.authorization.k8s.io/calico-node created daemonset.apps/calico-node created serviceaccount/calico-node created deployment.apps/calico-kube-controllers created serviceaccount/calico-kube-controllers created poddisruptionbudget.policy/calico-kube-controllers created Verify status of Calico. Make sure all Pods are running kubectl get pod -n kube-system | grep calico Output: NAME READY STATUS RESTARTS AGE calico-kube-controllers-7bc6547ffb-tjfcg 1/1 Running 0 30m calico-node-7x8jm 1/1 Running 0 30m calico-node-cwxj5 1/1 Running 0 30m calico-node-rq978 1/1 Running 0 30m If facing any error, check log in the Container. # Get Container ID crictl ps # Get log info crictl logs As we change CNI from Flannel to Calico, we need delete all Pods. All of Pods will be created automatically again. kubectl delete pod -A --all Make sure all Pods are up and running successfully. kubectl get pod -A","title":"Replace Flannel by Calico"},{"location":"k8s/cka_en/foundamentals/networkpolicy/#inbound-rules","text":"Scenario Create workload for test. Deny For All Ingress Allow For Specific Ingress Verify NetworkPolicy Demo:","title":"Inbound Rules"},{"location":"k8s/cka_en/foundamentals/networkpolicy/#create-workload-for-test","text":"Create three Deployments pod-netpol-1 , pod-netpol-2 , pod-netpol-3 based on image busybox . kubectl apply -f - << EOF apiVersion: apps/v1 kind: Deployment metadata: labels: app: pod-netpol-1 name: pod-netpol-1 spec: replicas: 1 selector: matchLabels: app: pod-netpol-1 template: metadata: labels: app: pod-netpol-1 spec: containers: - image: busybox name: busybox command: [\"sh\", \"-c\", \"sleep 1h\"] --- apiVersion: apps/v1 kind: Deployment metadata: labels: app: pod-netpol-2 name: pod-netpol-2 spec: replicas: 1 selector: matchLabels: app: pod-netpol-2 template: metadata: labels: app: pod-netpol-2 spec: containers: - image: busybox name: busybox command: [\"sh\", \"-c\", \"sleep 1h\"] --- apiVersion: apps/v1 kind: Deployment metadata: labels: app: pod-netpol-3 name: pod-netpol-3 spec: replicas: 1 selector: matchLabels: app: pod-netpol-3 template: metadata: labels: app: pod-netpol-3 spec: containers: - image: busybox name: busybox command: [\"sh\", \"-c\", \"sleep 1h\"] EOF Check Pods IP. kubectl get pod -owide Output: NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES pod-netpol-1-6494f6bf8b-n58r9 1/1 Running 0 29s 10.244.102.30 cka003 pod-netpol-2-77478d77ff-l6rzm 1/1 Running 0 29s 10.244.112.30 cka002 pod-netpol-3-68977dcb48-ql5s6 1/1 Running 0 29s 10.244.102.31 cka003 Attach to Pod pod-netpol-1 kubectl exec -it pod-netpol-1-6494f6bf8b-n58r9 -- sh Execute command ping that pod-netpol-2 and pod-netpol-3 are both reachable. / # ping 10.244.112.30 3 packets transmitted, 3 packets received, 0% packet loss / # ping 10.244.102.31 3 packets transmitted, 3 packets received, 0% packet loss","title":"Create workload for test."},{"location":"k8s/cka_en/foundamentals/networkpolicy/#deny-for-all-ingress","text":"Create deny policy for all ingress. kubectl apply -f - << EOF apiVersion: networking.k8s.io/v1 kind: NetworkPolicy metadata: name: default-deny-ingress spec: podSelector: {} policyTypes: - Ingress EOF Attach to Pod pod-netpol-1 again kubectl exec -it pod-netpol-1-6494f6bf8b-n58r9 -- sh Execute command ping that pod-netpol-2 and pod-netpol-3 are both unreachable as expected. / # ping 10.244.112.30 3 packets transmitted, 0 packets received, 100% packet loss / # ping 10.244.102.31 3 packets transmitted, 0 packets received, 100% packet loss","title":"Deny For All Ingress"},{"location":"k8s/cka_en/foundamentals/networkpolicy/#allow-for-specific-ingress","text":"Create NetworkPlicy to allow ingress from pod-netpol-1 to pod-netpol-2 . kubectl apply -f - <:80 failed. Command curl :80 succeed. kubectl run centos --image=centos -n my-ns-1 -- \"/bin/sh\" \"-c\" \"sleep 3600\" kubectl exec -it mycentos -n my-ns-1 -- bash Create temp pod on namespace my-ns-2 . Attach to the pod and verify the access. Command curl :80 failed. Command curl :80 failed. kubectl run centos --image=centos -n my-ns-2 -- \"/bin/sh\" \"-c\" \"sleep 3600\" kubectl exec -it mycentos -n my-ns-2 -- bash Edit my-networkpolicy-1 to change ingress.from.namespaceSelector.matchLabels to my-ns-2 . Attach to temp pod on namespace my-ns-2 . Verify the access. Command curl :80 failed. Command curl :80 succeed. kubectl exec -it mycentos -n my-ns-2 -- bash Clean up: kubectl delete namespace my-ns-1 kubectl delete namespace my-ns-2","title":"NetworkPolicy"},{"location":"k8s/cka_en/foundamentals/overview/","text":"Cluster Overview \u00b6 Contents \u00b6 Container Layer Kubernetes Layer Information: For environment setup, refer to Installation on Aliyun Ubuntu Container Layer \u00b6 Scenario: Use Containerd service to manage our images and containers via command nerdctl , which is same concept with Docker. Get namespace. Get containers. Get images. Get volumes. Get overall status. Get network status. Demo: Get namespaces. sudo nerdctl namespace ls Result NAME CONTAINERS IMAGES VOLUMES LABELS k8s.io 21 30 0 Get containers under specific namespace k8s.io . sudo nerdctl -n k8s.io ps Result CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 0a3625f22f65 registry.aliyuncs.com/google_containers/pause:3.6 \"/pause\" 16 hours ago Up k8s://kube-system/coredns-74586cf9b6-4jwmk 121af2ecd1a1 registry.aliyuncs.com/google_containers/coredns:v1.8.6 \"/coredns -conf /etc\u2026\" 16 hours ago Up k8s://kube-system/coredns-74586cf9b6-c5mll/coredns 49f6c7e3efe5 registry.aliyuncs.com/google_containers/kube-proxy:v1.24.0 \"/usr/local/bin/kube\u2026\" 16 hours ago Up k8s://kube-system/kube-proxy-dmj2t/kube-proxy 4bba5fbd701d registry.aliyuncs.com/google_containers/pause:3.6 \"/pause\" 16 hours ago Up k8s://kube-system/kube-scheduler-cka001 57d47b57eb12 docker.io/calico/node:v3.23.3 \"start_runit\" 16 hours ago Up k8s://kube-system/calico-node-w8nvl/calico-node 5ce4c351a886 registry.aliyuncs.com/google_containers/pause:3.6 \"/pause\" 16 hours ago Up k8s://kube-system/calico-node-w8nvl 6456eef784bf registry.aliyuncs.com/google_containers/kube-scheduler:v1.24.0 \"kube-scheduler --au\u2026\" 16 hours ago Up k8s://kube-system/kube-scheduler-cka001/kube-scheduler 6a687305871c registry.aliyuncs.com/google_containers/kube-apiserver:v1.24.0 \"kube-apiserver --ad\u2026\" 16 hours ago Up k8s://kube-system/kube-apiserver-cka001/kube-apiserver 7dcb24568574 registry.aliyuncs.com/google_containers/pause:3.6 \"/pause\" 16 hours ago Up k8s://kube-system/coredns-74586cf9b6-c5mll a06b101118b8 registry.aliyuncs.com/google_containers/pause:3.6 \"/pause\" 16 hours ago Up k8s://kube-system/kube-controller-manager-cka001 a07ef8c3fc3a registry.aliyuncs.com/google_containers/pause:3.6 \"/pause\" 16 hours ago Up k8s://kube-system/etcd-cka001 b8566d3e4174 registry.aliyuncs.com/google_containers/kube-controller-manager:v1.24.0 \"kube-controller-man\u2026\" 16 hours ago Up k8s://kube-system/kube-controller-manager-cka001/kube-controller-manager ca6ac26314ff registry.aliyuncs.com/google_containers/coredns:v1.8.6 \"/coredns -conf /etc\u2026\" 16 hours ago Up k8s://kube-system/coredns-74586cf9b6-4jwmk/coredns cdc041b4791e registry.aliyuncs.com/google_containers/etcd:3.5.3-0 \"etcd --advertise-cl\u2026\" 16 hours ago Up k8s://kube-system/etcd-cka001/etcd e0c59abadf2e registry.aliyuncs.com/google_containers/pause:3.6 \"/pause\" 16 hours ago Up k8s://kube-system/kube-proxy-dmj2t e0d2e5f6ccff registry.aliyuncs.com/google_containers/pause:3.6 \"/pause\" 16 hours ago Up k8s://kube-system/kube-apiserver-cka001 Get images. sudo nerdctl -n k8s.io image ls -a Get volumes. After inintial installation, no volume within namespaces. sudo nerdctl -n k8s.io volume ls Get overall status sudo nerdctl stats Get network status. sudo nerdctl network ls sudo nerdctl network inspect bridge sudo nerdctl network inspect k8s-pod-network Result NETWORK ID NAME FILE k8s-pod-network /etc/cni/net.d/10-calico.conflist 0 bridge /etc/cni/net.d/nerdctl-bridge.conflist host none Get network interface in host cka001 with command ip addr list . IP pool of 10.4.0.1/24 is ipam and defined in /etc/cni/net.d/nerdctl-bridge.conflist . lo : inet 127.0.0.1/8 qlen 1000 eth0 : inet /24 brd xxx.xxx.xxx.255 scope global dynamic eth0 tunl0@NONE : inet 10.244.228.192/32 scope global tunl0 cali96e32d88db2@if4 : cali93613212490@if4 : Kubernetes Layer \u00b6 Scenario: Nodes Namespaces System Pods Demo: Information: In the demo, there are three nodes, cka001 , cka002 , and cka003 . Get nodes status. kubectl get node -o wide There are four initial namespaces across three nodes. kubectl get namespace -A Result NAME STATUS AGE default Active 56m kube-node-lease Active 56m kube-public Active 56m kube-system Active 56m There are some initial pods. kubectl get pod -A -o wide Result NAMESPACE NAME READY STATUS RESTARTS AGE NODE NOMINATED NODE READINESS GATES kube-system calico-kube-controllers-555bc4b957-l8bn2 1/1 Running 0 15h cka003 kube-system calico-node-255pc 1/1 Running 0 15h cka003 kube-system calico-node-7tmnb 1/1 Running 0 15h cka002 kube-system calico-node-w8nvl 1/1 Running 0 15h cka001 kube-system coredns-74586cf9b6-4jwmk 1/1 Running 0 15h cka001 kube-system coredns-74586cf9b6-c5mll 1/1 Running 0 15h cka001 kube-system etcd-cka001 1/1 Running 0 15h cka001 kube-system kube-apiserver-cka001 1/1 Running 0 15h cka001 kube-system kube-controller-manager-cka001 1/1 Running 0 15h cka001 kube-system kube-proxy-dmj2t 1/1 Running 0 15h cka001 kube-system kube-proxy-n77zw 1/1 Running 0 15h cka002 kube-system kube-proxy-qs6rf 1/1 Running 0 15h cka003 kube-system kube-scheduler-cka001 1/1 Running 0 15h cka001 Summary: Below shows the relationship between containers and pods. Master node: CoreDNS: 2 Pod etcd: 1 Pod apiserver: 1 Pod controller-manager: 1 Pod scheduler: 1 Pod Calico Controller: 1 Pod All nodes: Calico Node: 1 Pod each Proxy: 1 Pod each Reference Container pause: article and artical . nerdctl","title":"Overview"},{"location":"k8s/cka_en/foundamentals/overview/#cluster-overview","text":"","title":"Cluster Overview"},{"location":"k8s/cka_en/foundamentals/overview/#contents","text":"Container Layer Kubernetes Layer Information: For environment setup, refer to Installation on Aliyun Ubuntu","title":"Contents"},{"location":"k8s/cka_en/foundamentals/overview/#container-layer","text":"Scenario: Use Containerd service to manage our images and containers via command nerdctl , which is same concept with Docker. Get namespace. Get containers. Get images. Get volumes. Get overall status. Get network status. Demo: Get namespaces. sudo nerdctl namespace ls Result NAME CONTAINERS IMAGES VOLUMES LABELS k8s.io 21 30 0 Get containers under specific namespace k8s.io . sudo nerdctl -n k8s.io ps Result CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 0a3625f22f65 registry.aliyuncs.com/google_containers/pause:3.6 \"/pause\" 16 hours ago Up k8s://kube-system/coredns-74586cf9b6-4jwmk 121af2ecd1a1 registry.aliyuncs.com/google_containers/coredns:v1.8.6 \"/coredns -conf /etc\u2026\" 16 hours ago Up k8s://kube-system/coredns-74586cf9b6-c5mll/coredns 49f6c7e3efe5 registry.aliyuncs.com/google_containers/kube-proxy:v1.24.0 \"/usr/local/bin/kube\u2026\" 16 hours ago Up k8s://kube-system/kube-proxy-dmj2t/kube-proxy 4bba5fbd701d registry.aliyuncs.com/google_containers/pause:3.6 \"/pause\" 16 hours ago Up k8s://kube-system/kube-scheduler-cka001 57d47b57eb12 docker.io/calico/node:v3.23.3 \"start_runit\" 16 hours ago Up k8s://kube-system/calico-node-w8nvl/calico-node 5ce4c351a886 registry.aliyuncs.com/google_containers/pause:3.6 \"/pause\" 16 hours ago Up k8s://kube-system/calico-node-w8nvl 6456eef784bf registry.aliyuncs.com/google_containers/kube-scheduler:v1.24.0 \"kube-scheduler --au\u2026\" 16 hours ago Up k8s://kube-system/kube-scheduler-cka001/kube-scheduler 6a687305871c registry.aliyuncs.com/google_containers/kube-apiserver:v1.24.0 \"kube-apiserver --ad\u2026\" 16 hours ago Up k8s://kube-system/kube-apiserver-cka001/kube-apiserver 7dcb24568574 registry.aliyuncs.com/google_containers/pause:3.6 \"/pause\" 16 hours ago Up k8s://kube-system/coredns-74586cf9b6-c5mll a06b101118b8 registry.aliyuncs.com/google_containers/pause:3.6 \"/pause\" 16 hours ago Up k8s://kube-system/kube-controller-manager-cka001 a07ef8c3fc3a registry.aliyuncs.com/google_containers/pause:3.6 \"/pause\" 16 hours ago Up k8s://kube-system/etcd-cka001 b8566d3e4174 registry.aliyuncs.com/google_containers/kube-controller-manager:v1.24.0 \"kube-controller-man\u2026\" 16 hours ago Up k8s://kube-system/kube-controller-manager-cka001/kube-controller-manager ca6ac26314ff registry.aliyuncs.com/google_containers/coredns:v1.8.6 \"/coredns -conf /etc\u2026\" 16 hours ago Up k8s://kube-system/coredns-74586cf9b6-4jwmk/coredns cdc041b4791e registry.aliyuncs.com/google_containers/etcd:3.5.3-0 \"etcd --advertise-cl\u2026\" 16 hours ago Up k8s://kube-system/etcd-cka001/etcd e0c59abadf2e registry.aliyuncs.com/google_containers/pause:3.6 \"/pause\" 16 hours ago Up k8s://kube-system/kube-proxy-dmj2t e0d2e5f6ccff registry.aliyuncs.com/google_containers/pause:3.6 \"/pause\" 16 hours ago Up k8s://kube-system/kube-apiserver-cka001 Get images. sudo nerdctl -n k8s.io image ls -a Get volumes. After inintial installation, no volume within namespaces. sudo nerdctl -n k8s.io volume ls Get overall status sudo nerdctl stats Get network status. sudo nerdctl network ls sudo nerdctl network inspect bridge sudo nerdctl network inspect k8s-pod-network Result NETWORK ID NAME FILE k8s-pod-network /etc/cni/net.d/10-calico.conflist 0 bridge /etc/cni/net.d/nerdctl-bridge.conflist host none Get network interface in host cka001 with command ip addr list . IP pool of 10.4.0.1/24 is ipam and defined in /etc/cni/net.d/nerdctl-bridge.conflist . lo : inet 127.0.0.1/8 qlen 1000 eth0 : inet /24 brd xxx.xxx.xxx.255 scope global dynamic eth0 tunl0@NONE : inet 10.244.228.192/32 scope global tunl0 cali96e32d88db2@if4 : cali93613212490@if4 :","title":"Container Layer"},{"location":"k8s/cka_en/foundamentals/overview/#kubernetes-layer","text":"Scenario: Nodes Namespaces System Pods Demo: Information: In the demo, there are three nodes, cka001 , cka002 , and cka003 . Get nodes status. kubectl get node -o wide There are four initial namespaces across three nodes. kubectl get namespace -A Result NAME STATUS AGE default Active 56m kube-node-lease Active 56m kube-public Active 56m kube-system Active 56m There are some initial pods. kubectl get pod -A -o wide Result NAMESPACE NAME READY STATUS RESTARTS AGE NODE NOMINATED NODE READINESS GATES kube-system calico-kube-controllers-555bc4b957-l8bn2 1/1 Running 0 15h cka003 kube-system calico-node-255pc 1/1 Running 0 15h cka003 kube-system calico-node-7tmnb 1/1 Running 0 15h cka002 kube-system calico-node-w8nvl 1/1 Running 0 15h cka001 kube-system coredns-74586cf9b6-4jwmk 1/1 Running 0 15h cka001 kube-system coredns-74586cf9b6-c5mll 1/1 Running 0 15h cka001 kube-system etcd-cka001 1/1 Running 0 15h cka001 kube-system kube-apiserver-cka001 1/1 Running 0 15h cka001 kube-system kube-controller-manager-cka001 1/1 Running 0 15h cka001 kube-system kube-proxy-dmj2t 1/1 Running 0 15h cka001 kube-system kube-proxy-n77zw 1/1 Running 0 15h cka002 kube-system kube-proxy-qs6rf 1/1 Running 0 15h cka003 kube-system kube-scheduler-cka001 1/1 Running 0 15h cka001 Summary: Below shows the relationship between containers and pods. Master node: CoreDNS: 2 Pod etcd: 1 Pod apiserver: 1 Pod controller-manager: 1 Pod scheduler: 1 Pod Calico Controller: 1 Pod All nodes: Calico Node: 1 Pod each Proxy: 1 Pod each Reference Container pause: article and artical . nerdctl","title":"Kubernetes Layer"},{"location":"k8s/cka_en/foundamentals/persistence/","text":"Persistence \u00b6 Scenario Creat Pod with emptyDir type Volume. Container in the Pod will mount default directory /var/lib/kubelet/pods/ on running node. Create Deployment Deployment with hostPath type volume. Container in the Deployment will mount directory defined in hostPath: on running node. PV and PVC. Set up NFS Server and share folder /nfsdata/ . Create PV mysql-pv to link to the share folder /nfsdata/ and set StorageClassName nfs . Create PVC mysql-pvc mapped with StorageClassName nfs . Create Deployment mysql to consume PVC mysql-pvc . StorageClass Create ServiceAccount nfs-client-provisioner . Create ClusterRole nfs-client-provisioner-runner and Role leader-locking-nfs-client-provisioner and bind them to the ServiceAccount so the ServiceAccount has authorization to operate the Deployment created in next step. Create Deployment nfs-client-provisioner to to add connection information for your NFS server, e.g, PROVISIONER_NAME is k8s-sigs.io/ nfs-subdir-external-provisioner Create StorageClass nfs-client link to provisioner: k8s-sigs.io/nfs-subdir-external-provisioner . Releated PV is created automatically. Create PVC nfs-pvc-from-sc mapped to PV and StorageClass nfs-client . Configuration Create a ConfigMap for content of a file, and mount this ConfigMap to a specific file in a Pod. Create a ConfigMap for username and password, and consume them within a Pod. Use ConfigMap as environment variables in Pod. Tips Delete PVC first, then delete PV. If facing Terminating status when delete a PVC, use kubectl edit pvc and remove finalize: . emptyDir \u00b6 Create a Pod hello-producer with emptyDir type Volume. cat > pod-emptydir.yaml < /producer_dir/hello; sleep 30000 volumes: - name: shared-volume emptyDir: {} EOF kubectl apply -f pod-emptydir.yaml The Pod hello-producer is running on node cka003 . kubectl get pod hello-producer -owide The Pod is running on node cka003 . NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES hello-producer 1/1 Running 0 6s 10.244.102.24 cka003 Log onto cka003 because the Pod hello-producer is running on the node. Set up the environment CONTAINER_RUNTIME_ENDPOINT for command crictl . Suggest to do the same for all nodes. export CONTAINER_RUNTIME_ENDPOINT=unix:///run/containerd/containerd.sock Run command crictl ps to get the container ID of Pod hello-producer . crictl ps |grep hello-producer The ID of container producer is 05f5e1bb6a1bb . CONTAINER IMAGE CREATED STATE NAME ATTEMPT POD ID POD 50058afb3cba5 62aedd01bd852 About an hour ago Running producer 0 e6953bd4833a7 hello-producer Run command crictl inspect to get the path of mounted shared-volume , which is emptyDir . crictl inspect 50058afb3cba5 | grep source | grep empty The result is below. \"source\": \"/var/lib/kubelet/pods/d7424f86-534a-48f9-9001-9d2a6e822b12/volumes/kubernetes.io~empty-dir/shared-volume\", Change the path to the path of mounted shared-volume we get above. We will see the content hello world of file hello . cd /var/lib/kubelet/pods/d7424f86-534a-48f9-9001-9d2a6e822b12/volumes/kubernetes.io~empty-dir/shared-volume cat hello The path /producer_dir inside the Pod is mounted to the local host path /var/lib/kubelet/pods/d7424f86-534a-48f9-9001-9d2a6e822b12/volumes/kubernetes.io~empty-dir/shared-volume . The file /producer_dir/hello we created inside the Pod is actually in the host local path. Let's delete the container producer , the container producer will be started again with new container ID and the file hello is still there. crictl ps crictl stop crictl rm Let's delete the Pod hello-producer , the container producer is deleted, file hello is deleted. kubectl delete pod hello-producer hostPath \u00b6 Apply below yaml file to create a MySQL Pod and mount a hostPath . It'll mount host directory /tmp/mysql to Pod directory /var/lib/mysql . Check locally if directory /tmp/mysql is in place. If not, create it using mkdir /tmp/mysql . cat > mysql-hostpath.yaml < cka003 Attach into the MySQL Pod on the running node. kubectl exec -it -- bash Within the Pod, go to directory /var/lib/mysql , all files in the directory are same with all files in directory /tmp/mysql on node cka003 . Connect to the database in the Pod. mysql -h 127.0.0.1 -uroot -ppassword Operate the database. mysql> show databases; mysql> connect mysql; mysql> show tables; mysql> exit PV and PVC \u00b6 Here we will use NFS as backend storage to demo how to deploy PV and PVC. Set up NFS Share \u00b6 Install nfs-kernel-server Log onto cka002 . Choose one Worker cka002 to build NFS server. sudo apt-get install -y nfs-kernel-server Configure Share Folder Create share folder. mkdir /nfsdata Append one line in file /etc/exports . cat >> /etc/exports << EOF /nfsdata *(rw,sync,no_root_squash) EOF There are many different NFS sharing options, including these: * : accessable to all IPs, or specific IPs. rw : Share as read-write. Keep in mind that normal Linux permissions still apply. (Note that this is a default option.) ro : Share as read-only. sync : File data changes are made to disk immediately, which has an impact on performance, but is less likely to result in data loss. On som* `distributions this is the default. async : The opposite of sync; file data changes are made initially to memory. This speeds up performance but is more likely to result in data loss. O* `some distributions this is the default. root_squash : Map the root user and group account from the NFS client to the anonymous accounts, typically either the nobody account or the nfsnobod* `account. See the next section, \u201cUser ID Mapping,\u201d for more details. (Note that this is a default option.) no_root_squash : Map the root user and group account from the NFS client to the local root and group accounts. We will use password-free remote mount based on nfs and rpcbind services between Linux servers, not based on smb service. The two servers must first grant credit, install and set up nfs and rpcbind services on the server side, set the common directory, start the service, and mount it on the client Start rpcbind service. sudo systemctl enable rpcbind sudo systemctl restart rpcbind Start nfs service. sudo systemctl enable nfs-server sudo systemctl start nfs-server Once /etc/exports is changed, we need run below command to make change effected. exportfs -ra Result exportfs: /etc/exports [1]: Neither 'subtree_check' or 'no_subtree_check' specified for export \"*:/nfsdata\". Assuming default behaviour ('no_subtree_check'). NOTE: this default has changed since nfs-utils version 1.0.x Check whether sharefolder is configured. showmount -e And see below output. Export list for cka002: /nfsdata * Install NFS Client Install NFS client on all nodes. sudo apt-get install -y nfs-common Verify NFS Server Log onto any nodes to verify NFS service and sharefolder list. Log onto cka001 and check sharefolder status on cka002 . showmount -e cka002 Below result will be shown if no issues. Export list for cka002: /nfsdata * Mount NFS Execute below command to mount remote NFS folder on any other non-NFS-server node, e.g., cka001 or cka003 . mkdir /remote-nfs-dir mount -t nfs cka002:/nfsdata /remote-nfs-dir/ Use command df -h to verify mount point. Below is the sample output. Filesystem Size Used Avail Use% Mounted on cka002:/nfsdata 40G 5.8G 32G 16% /remote-nfs-dir Create PV \u00b6 Create a PV mysql-pv . Replace the NFS Server IP with actual IP (here is ) that NFS server cka002 is running on. kubectl apply -f - < EOF Check the PV. kubectl get pv The result: NAME CAPACITY ACCESS MODES RECLAIM POLICY STATUS CLAIM STORAGECLASS REASON AGE mysql-pv 1Gi RWO Retain Available nfs 19s Create PVC \u00b6 Create a PVC mysql-pvc and specify storage size, access mode, and storage class. The PVC mysql-pvc will be binded with PV automatically via storage class name. kubectl apply -f - < nfs-provisioner-rbac.yaml < ( cka002 ). Replace NFS server IP with actual IP (here is ) cat > nfs-provisioner-deployment.yaml < - name: NFS_PATH value: /nfsdata volumes: - name: nfs-client-root nfs: server: path: /nfsdata EOF kubectl apply -f nfs-provisioner-deployment.yaml Create NFS StorageClass \u00b6 Create StorageClass nfs-client . Define the NFS subdir external provisioner's Kubernetes Storage Class. vi nfs-storageclass.yaml And add below info to create NFS StorageClass. apiVersion : storage.k8s.io/v1 kind : StorageClass metadata : name : nfs-client annotations : storageclass.kubernetes.io/is-default-class : \"true\" provisioner : k8s-sigs.io/nfs-subdir-external-provisioner parameters : pathPattern : \"${.PVC.namespace}/${.PVC.annotations.nfs.io/storage-path}\" onDelete : delete Apply the yaml file. kubectl apply -f nfs-storageclass.yaml Create PVC \u00b6 Create PVC nfs-pvc-from-sc . kubectl apply -f - < mysql-with-sc-pvc-7c97d875f8-wkvr9 1/1 Running 0 3m37s 10.244.102.27 cka003 Let's check directory /nfsdata/ on NFS server cka002 . ll /nfsdata/ Two folders were created. Same content of /remote-nfs-dir/ on other nodes. drwxrwxrwx 6 systemd-coredump root 4096 Jul 23 23:35 dev/ drwxr-xr-x 6 systemd-coredump root 4096 Jul 23 22:29 mysqldata/ Namespace name is used as folder name under directory /nfsdata/ and it is mounted to Pod. By default, namespace name will be used at mount point. If we want to use customized folder for that purpose, we need claim an annotation nfs.io/storage-path , e.g., below example. Create PVC test-claim on Namespace kube-system and consume volume nfs-client . kubectl apply -f - < ..data/password lrwxrwxrwx 1 root root 15 Jul 23 16:30 username -> ..data/username And we can get the content of each element, which are predefined before. / # cat /tmp/secret/username admin / # cat /tmp/secret/password 123456 Additional Cases \u00b6 Various way to create ConfigMap \u00b6 ConfigMap can be created by file, directory, or value. Let's create a ConfigMap colors includes: Four files with four color names. One file with favorite color name. mkdir configmap cd configmap mkdir primary echo c > primary/cyan echo m > primary/magenta echo y > primary/yellow echo k > primary/black echo \"known as key\" >> primary/black echo blue > favorite Final structure looks like below via command tree configmap . configmap \u251c\u2500\u2500 favorite \u2514\u2500\u2500 primary \u251c\u2500\u2500 black \u251c\u2500\u2500 cyan \u251c\u2500\u2500 magenta \u2514\u2500\u2500 yellow Create ConfigMap referring above files we created. Make sure we are now in the path ~/configmap . kubectl create configmap colors \\ --from-literal=text=black \\ --from-file=./favorite \\ --from-file=./primary/ Check content of the ConfigMap colors . kubectl get configmap colors -o yaml apiVersion : v1 data : black : | k known as key cyan : | c favorite : | blue magenta : | m text : black yellow : | y kind : ConfigMap metadata : creationTimestamp : \"2022-07-12T16:38:27Z\" name : colors namespace : dev resourceVersion : \"2377258\" uid : d5ab133f-5e4d-41d4-bc9e-2bbb22a872a1 Set environment variable via ConfigMap \u00b6 Here we will create a Pod pod-configmap-env and set the environment variable ilike and assign value of favorite from ConfigMap colors . kubectl apply -f - << EOF apiVersion: v1 kind: Pod metadata: name: pod-configmap-env spec: containers: - name: nginx image: nginx env: - name: ilike valueFrom: configMapKeyRef: name: colors key: favorite EOF Attach to the Pod pod-configmap-env . kubectl exec -it pod-configmap-env -- bash Verify the value of env variable ilike is blue , which is the value of favorite of ConfigMap colors . root@pod-configmap-env:/# echo $ ilike blue We can also use all key-value of ConfigMap to set up environment variables of Pod. kubectl apply -f - << EOF apiVersion: v1 kind: Pod metadata: name: pod-configmap-env-2 spec: containers: - name: nginx image: nginx envFrom: - configMapRef: name: colors EOF Attach to the Pod pod-configmap-env-2 . kubectl exec -it pod-configmap-env-2 -- bash Verify the value of env variables based on key-values we defined in ConfigMap colors . root@pod-configmap-env-2:/# echo $ black k known as key root@pod-configmap-env-2:/# echo $ cyan c root@pod-configmap-env-2:/# echo $ favorite blue","title":"Persistence"},{"location":"k8s/cka_en/foundamentals/persistence/#persistence","text":"Scenario Creat Pod with emptyDir type Volume. Container in the Pod will mount default directory /var/lib/kubelet/pods/ on running node. Create Deployment Deployment with hostPath type volume. Container in the Deployment will mount directory defined in hostPath: on running node. PV and PVC. Set up NFS Server and share folder /nfsdata/ . Create PV mysql-pv to link to the share folder /nfsdata/ and set StorageClassName nfs . Create PVC mysql-pvc mapped with StorageClassName nfs . Create Deployment mysql to consume PVC mysql-pvc . StorageClass Create ServiceAccount nfs-client-provisioner . Create ClusterRole nfs-client-provisioner-runner and Role leader-locking-nfs-client-provisioner and bind them to the ServiceAccount so the ServiceAccount has authorization to operate the Deployment created in next step. Create Deployment nfs-client-provisioner to to add connection information for your NFS server, e.g, PROVISIONER_NAME is k8s-sigs.io/ nfs-subdir-external-provisioner Create StorageClass nfs-client link to provisioner: k8s-sigs.io/nfs-subdir-external-provisioner . Releated PV is created automatically. Create PVC nfs-pvc-from-sc mapped to PV and StorageClass nfs-client . Configuration Create a ConfigMap for content of a file, and mount this ConfigMap to a specific file in a Pod. Create a ConfigMap for username and password, and consume them within a Pod. Use ConfigMap as environment variables in Pod. Tips Delete PVC first, then delete PV. If facing Terminating status when delete a PVC, use kubectl edit pvc and remove finalize: .","title":"Persistence"},{"location":"k8s/cka_en/foundamentals/persistence/#emptydir","text":"Create a Pod hello-producer with emptyDir type Volume. cat > pod-emptydir.yaml < /producer_dir/hello; sleep 30000 volumes: - name: shared-volume emptyDir: {} EOF kubectl apply -f pod-emptydir.yaml The Pod hello-producer is running on node cka003 . kubectl get pod hello-producer -owide The Pod is running on node cka003 . NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES hello-producer 1/1 Running 0 6s 10.244.102.24 cka003 Log onto cka003 because the Pod hello-producer is running on the node. Set up the environment CONTAINER_RUNTIME_ENDPOINT for command crictl . Suggest to do the same for all nodes. export CONTAINER_RUNTIME_ENDPOINT=unix:///run/containerd/containerd.sock Run command crictl ps to get the container ID of Pod hello-producer . crictl ps |grep hello-producer The ID of container producer is 05f5e1bb6a1bb . CONTAINER IMAGE CREATED STATE NAME ATTEMPT POD ID POD 50058afb3cba5 62aedd01bd852 About an hour ago Running producer 0 e6953bd4833a7 hello-producer Run command crictl inspect to get the path of mounted shared-volume , which is emptyDir . crictl inspect 50058afb3cba5 | grep source | grep empty The result is below. \"source\": \"/var/lib/kubelet/pods/d7424f86-534a-48f9-9001-9d2a6e822b12/volumes/kubernetes.io~empty-dir/shared-volume\", Change the path to the path of mounted shared-volume we get above. We will see the content hello world of file hello . cd /var/lib/kubelet/pods/d7424f86-534a-48f9-9001-9d2a6e822b12/volumes/kubernetes.io~empty-dir/shared-volume cat hello The path /producer_dir inside the Pod is mounted to the local host path /var/lib/kubelet/pods/d7424f86-534a-48f9-9001-9d2a6e822b12/volumes/kubernetes.io~empty-dir/shared-volume . The file /producer_dir/hello we created inside the Pod is actually in the host local path. Let's delete the container producer , the container producer will be started again with new container ID and the file hello is still there. crictl ps crictl stop crictl rm Let's delete the Pod hello-producer , the container producer is deleted, file hello is deleted. kubectl delete pod hello-producer","title":"emptyDir"},{"location":"k8s/cka_en/foundamentals/persistence/#hostpath","text":"Apply below yaml file to create a MySQL Pod and mount a hostPath . It'll mount host directory /tmp/mysql to Pod directory /var/lib/mysql . Check locally if directory /tmp/mysql is in place. If not, create it using mkdir /tmp/mysql . cat > mysql-hostpath.yaml < cka003 Attach into the MySQL Pod on the running node. kubectl exec -it -- bash Within the Pod, go to directory /var/lib/mysql , all files in the directory are same with all files in directory /tmp/mysql on node cka003 . Connect to the database in the Pod. mysql -h 127.0.0.1 -uroot -ppassword Operate the database. mysql> show databases; mysql> connect mysql; mysql> show tables; mysql> exit","title":"hostPath"},{"location":"k8s/cka_en/foundamentals/persistence/#pv-and-pvc","text":"Here we will use NFS as backend storage to demo how to deploy PV and PVC.","title":"PV and PVC"},{"location":"k8s/cka_en/foundamentals/persistence/#set-up-nfs-share","text":"Install nfs-kernel-server Log onto cka002 . Choose one Worker cka002 to build NFS server. sudo apt-get install -y nfs-kernel-server Configure Share Folder Create share folder. mkdir /nfsdata Append one line in file /etc/exports . cat >> /etc/exports << EOF /nfsdata *(rw,sync,no_root_squash) EOF There are many different NFS sharing options, including these: * : accessable to all IPs, or specific IPs. rw : Share as read-write. Keep in mind that normal Linux permissions still apply. (Note that this is a default option.) ro : Share as read-only. sync : File data changes are made to disk immediately, which has an impact on performance, but is less likely to result in data loss. On som* `distributions this is the default. async : The opposite of sync; file data changes are made initially to memory. This speeds up performance but is more likely to result in data loss. O* `some distributions this is the default. root_squash : Map the root user and group account from the NFS client to the anonymous accounts, typically either the nobody account or the nfsnobod* `account. See the next section, \u201cUser ID Mapping,\u201d for more details. (Note that this is a default option.) no_root_squash : Map the root user and group account from the NFS client to the local root and group accounts. We will use password-free remote mount based on nfs and rpcbind services between Linux servers, not based on smb service. The two servers must first grant credit, install and set up nfs and rpcbind services on the server side, set the common directory, start the service, and mount it on the client Start rpcbind service. sudo systemctl enable rpcbind sudo systemctl restart rpcbind Start nfs service. sudo systemctl enable nfs-server sudo systemctl start nfs-server Once /etc/exports is changed, we need run below command to make change effected. exportfs -ra Result exportfs: /etc/exports [1]: Neither 'subtree_check' or 'no_subtree_check' specified for export \"*:/nfsdata\". Assuming default behaviour ('no_subtree_check'). NOTE: this default has changed since nfs-utils version 1.0.x Check whether sharefolder is configured. showmount -e And see below output. Export list for cka002: /nfsdata * Install NFS Client Install NFS client on all nodes. sudo apt-get install -y nfs-common Verify NFS Server Log onto any nodes to verify NFS service and sharefolder list. Log onto cka001 and check sharefolder status on cka002 . showmount -e cka002 Below result will be shown if no issues. Export list for cka002: /nfsdata * Mount NFS Execute below command to mount remote NFS folder on any other non-NFS-server node, e.g., cka001 or cka003 . mkdir /remote-nfs-dir mount -t nfs cka002:/nfsdata /remote-nfs-dir/ Use command df -h to verify mount point. Below is the sample output. Filesystem Size Used Avail Use% Mounted on cka002:/nfsdata 40G 5.8G 32G 16% /remote-nfs-dir","title":"Set up NFS Share"},{"location":"k8s/cka_en/foundamentals/persistence/#create-pv","text":"Create a PV mysql-pv . Replace the NFS Server IP with actual IP (here is ) that NFS server cka002 is running on. kubectl apply -f - < EOF Check the PV. kubectl get pv The result: NAME CAPACITY ACCESS MODES RECLAIM POLICY STATUS CLAIM STORAGECLASS REASON AGE mysql-pv 1Gi RWO Retain Available nfs 19s","title":"Create PV"},{"location":"k8s/cka_en/foundamentals/persistence/#create-pvc","text":"Create a PVC mysql-pvc and specify storage size, access mode, and storage class. The PVC mysql-pvc will be binded with PV automatically via storage class name. kubectl apply -f - < nfs-provisioner-rbac.yaml < ( cka002 ). Replace NFS server IP with actual IP (here is ) cat > nfs-provisioner-deployment.yaml < - name: NFS_PATH value: /nfsdata volumes: - name: nfs-client-root nfs: server: path: /nfsdata EOF kubectl apply -f nfs-provisioner-deployment.yaml","title":"Create Provisioner's Deloyment"},{"location":"k8s/cka_en/foundamentals/persistence/#create-nfs-storageclass","text":"Create StorageClass nfs-client . Define the NFS subdir external provisioner's Kubernetes Storage Class. vi nfs-storageclass.yaml And add below info to create NFS StorageClass. apiVersion : storage.k8s.io/v1 kind : StorageClass metadata : name : nfs-client annotations : storageclass.kubernetes.io/is-default-class : \"true\" provisioner : k8s-sigs.io/nfs-subdir-external-provisioner parameters : pathPattern : \"${.PVC.namespace}/${.PVC.annotations.nfs.io/storage-path}\" onDelete : delete Apply the yaml file. kubectl apply -f nfs-storageclass.yaml","title":"Create NFS StorageClass"},{"location":"k8s/cka_en/foundamentals/persistence/#create-pvc_1","text":"Create PVC nfs-pvc-from-sc . kubectl apply -f - < mysql-with-sc-pvc-7c97d875f8-wkvr9 1/1 Running 0 3m37s 10.244.102.27 cka003 Let's check directory /nfsdata/ on NFS server cka002 . ll /nfsdata/ Two folders were created. Same content of /remote-nfs-dir/ on other nodes. drwxrwxrwx 6 systemd-coredump root 4096 Jul 23 23:35 dev/ drwxr-xr-x 6 systemd-coredump root 4096 Jul 23 22:29 mysqldata/ Namespace name is used as folder name under directory /nfsdata/ and it is mounted to Pod. By default, namespace name will be used at mount point. If we want to use customized folder for that purpose, we need claim an annotation nfs.io/storage-path , e.g., below example. Create PVC test-claim on Namespace kube-system and consume volume nfs-client . kubectl apply -f - < ..data/password lrwxrwxrwx 1 root root 15 Jul 23 16:30 username -> ..data/username And we can get the content of each element, which are predefined before. / # cat /tmp/secret/username admin / # cat /tmp/secret/password 123456","title":"Secret"},{"location":"k8s/cka_en/foundamentals/persistence/#additional-cases","text":"","title":"Additional Cases"},{"location":"k8s/cka_en/foundamentals/persistence/#various-way-to-create-configmap","text":"ConfigMap can be created by file, directory, or value. Let's create a ConfigMap colors includes: Four files with four color names. One file with favorite color name. mkdir configmap cd configmap mkdir primary echo c > primary/cyan echo m > primary/magenta echo y > primary/yellow echo k > primary/black echo \"known as key\" >> primary/black echo blue > favorite Final structure looks like below via command tree configmap . configmap \u251c\u2500\u2500 favorite \u2514\u2500\u2500 primary \u251c\u2500\u2500 black \u251c\u2500\u2500 cyan \u251c\u2500\u2500 magenta \u2514\u2500\u2500 yellow Create ConfigMap referring above files we created. Make sure we are now in the path ~/configmap . kubectl create configmap colors \\ --from-literal=text=black \\ --from-file=./favorite \\ --from-file=./primary/ Check content of the ConfigMap colors . kubectl get configmap colors -o yaml apiVersion : v1 data : black : | k known as key cyan : | c favorite : | blue magenta : | m text : black yellow : | y kind : ConfigMap metadata : creationTimestamp : \"2022-07-12T16:38:27Z\" name : colors namespace : dev resourceVersion : \"2377258\" uid : d5ab133f-5e4d-41d4-bc9e-2bbb22a872a1","title":"Various way to create ConfigMap"},{"location":"k8s/cka_en/foundamentals/persistence/#set-environment-variable-via-configmap","text":"Here we will create a Pod pod-configmap-env and set the environment variable ilike and assign value of favorite from ConfigMap colors . kubectl apply -f - << EOF apiVersion: v1 kind: Pod metadata: name: pod-configmap-env spec: containers: - name: nginx image: nginx env: - name: ilike valueFrom: configMapKeyRef: name: colors key: favorite EOF Attach to the Pod pod-configmap-env . kubectl exec -it pod-configmap-env -- bash Verify the value of env variable ilike is blue , which is the value of favorite of ConfigMap colors . root@pod-configmap-env:/# echo $ ilike blue We can also use all key-value of ConfigMap to set up environment variables of Pod. kubectl apply -f - << EOF apiVersion: v1 kind: Pod metadata: name: pod-configmap-env-2 spec: containers: - name: nginx image: nginx envFrom: - configMapRef: name: colors EOF Attach to the Pod pod-configmap-env-2 . kubectl exec -it pod-configmap-env-2 -- bash Verify the value of env variables based on key-values we defined in ConfigMap colors . root@pod-configmap-env-2:/# echo $ black k known as key root@pod-configmap-env-2:/# echo $ cyan c root@pod-configmap-env-2:/# echo $ favorite blue","title":"Set environment variable via ConfigMap"},{"location":"k8s/cka_en/foundamentals/pod/","text":"Work on pod \u00b6 Create pod \u00b6 Create pod my-first-podl . kubectl apply -f - << EOF apiVersion: v1 kind: Pod metadata: name: my-first-pod spec: containers: - name: nginx image: nginx:mainline ports: - containerPort: 80 EOF Verify status of the pod just created. kubectl get pods -o wide Track pod \u00b6 Check logs of the pod just created. kubectl logs my-first-pod In case logs or describe or any other of the output generating commands don't help us to get to the root cause of an issue, we can use use kubectl exec -it -- bash command to look into it ourselves. kubectl exec -it my-first-pod -- bash root@my-first-pod:/# ls root@my-first-pod:/# cd bin root@my-first-pod:/bin# ls root@my-first-pod:/bin# exit Execute command kubectl explain pod.spec will get details of Spec segment of Pod kind in yaml file. We can check the official API reference of the pod resource for help or use kubectl explain pod to get a command-line based description of the resource. By appending . to the resource type, the explain command will provide more details on the specified field. kubectl explain pod.kind kubectl explain pod.spec kubectl explain pod.spec.containers kubectl explain pod.spec.containers.name Label pod \u00b6 Get pod's label with option --show-labels . kubectl get pods kubectl get pods --show-labels Add two labels to the pod pod my-first-pod . kubectl label pod my-first-pod nginx=mainline kubectl label pod my-first-pod env=demo kubectl get pods --show-labels Search pod by labels. kubectl get pod -l env=demo kubectl get pod -l env=demo,nginx=mainline kubectl get pod -l env=training Remove label kubectl label pods my-first-pod env- kubectl get pods --show-labels Describe pod. kubectl describe pod my-first-pod Delete pod. Run watch kubectl get pods to monitor the pod status. kubectl delete pod my-first-pod watch kubectl get pods Static Pod \u00b6 Scenario *Create a static pod. * kubectl will automatically check yaml file in /etc/kubernetes/manifests/ and create the static pod once it's detected. Demo: Some system static Pods are already in place. ll /etc/kubernetes/manifests/ Result -rw------- 1 root root 2292 Jul 23 10:45 etcd.yaml -rw------- 1 root root 3889 Jul 23 10:45 kube-apiserver.yaml -rw------- 1 root root 3395 Jul 23 10:45 kube-controller-manager.yaml -rw------- 1 root root 1464 Jul 23 10:45 kube-scheduler.yaml Create yaml file my-nginx.yaml in directory /etc/kubernetes/manifests/ . Once the file is created, the static pod my-nginx is created automatically. kubectl run my-nginx --image=nginx:mainline --dry-run=client -n default -oyaml | sudo tee /etc/kubernetes/manifests/my-nginx.yaml Check status of the Pod my-nginx . The node name cka001 is part of the Pod name, which means the Pod is running on node cka001 . kubectl get pod -o wide Result NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES my-nginx-cka001 1/1 Running 0 20s 10.244.228.196 cka001 Delete the yaml file /etc/kubernetes/manifests/my-nginx.yaml , the static pod will be deleted automatically. sudo rm /etc/kubernetes/manifests/my-nginx.yaml Multi-Container Pod \u00b6 Scenario: Create Multi-Container Pod Describe the Pod Check the log of Pod Check the log of Containers Create a Pod multi-container-pod with multiple container container-1-nginx and container-2-alpine . kubectl apply -f - << EOF apiVersion: v1 kind: Pod metadata: name: multi-container-pod spec: containers: - name: container-1-nginx image: nginx ports: - containerPort: 80 - name: container-2-alpine image: alpine command: [\"watch\", \"wget\", \"-qO-\", \"localhost\"] EOF Get the status. kubectl get pod multi-container-pod Result NAME READY STATUS RESTARTS AGE multi-container-pod 2/2 Running 0 81s Get details of the pod. kubectl describe pod multi-container-pod Result ....... Events: Type Reason Age From Message ---- ------ ---- ---- ------- Normal Scheduled 41s default-scheduler Successfully assigned dev/multi-container-pod to cka002 Normal Pulling 40s kubelet Pulling image \"nginx\" Normal Pulled 23s kubelet Successfully pulled image \"nginx\" in 16.767129903s Normal Created 22s kubelet Created container container-1-nginx Normal Started 22s kubelet Started container container-1-nginx Normal Pulling 22s kubelet Pulling image \"alpine\" Normal Pulled 14s kubelet Successfully pulled image \"alpine\" in 7.776104353s Normal Created 14s kubelet Created container container-2-alpine Normal Started 14s kubelet Started container container-2-alpine For multi-container pod, container name is needed if we want to get log of pod via command kubectl logs . Without the container name, we receive error. kubectl logs multi-container-pod Result error: a container name must be specified for pod multi-container-pod, choose one of: [container-1-nginx container-2-alpine] With specified container name, we get the log info. kubectl logs multi-container-pod container-1-nginx Result ...... ::1 - - [23/Jul/2022:04:06:37 +0000] \"GET / HTTP/1.1\" 200 615 \"-\" \"Wget\" \"-\" Same if we need specify container name to login into the pod via command kubectl exec -it -c -- . kubectl exec -it multi-container-pod -c container-1-nginx -- /bin/bash root@multi-container-pod:/# ls Clean up kubectl delete pod multi-container-pod Quick reference of a simple yaml file to create Multiple Containers. kubectl apply -f - << EOF apiVersion: v1 kind: Pod metadata: name: my-multi-pod spec: containers: - image: nginx name: nginx - image: memcached name: memcached - image: redis name: redis EOF Scenario: Create a Pod my-busybox with a container container-1-busybox . The container will write message to file /var/log/my-pod-busybox.log . Add another container container-2-busybox (Sidecar) to the Pod my-busybox . The sidecar container read message from file /var/log/my-pod-busybox.log . Tips: create a Volume to store the log file, which is shared with two containers. Demo: Create a Pod my-busybox with a container container-1-busybox . kubectl apply -f - << EOF apiVersion: v1 kind: Pod metadata: name: my-busybox spec: containers: - name: container-1-busybox image: busybox args: - /bin/sh - -c - > i=0; while true; do echo \"Hello message from container-1: $i\" >> /var/log/my-pod-busybox.log; i=$((i+1)); sleep 1; done EOF Search emptyDir in the Kubernetes documetation. Refer to below template for emptyDir via https://kubernetes.io/zh-cn/docs/concepts/storage/volumes/ Add below new features into the Pod Volume: volume name: logfile type: emptyDir Update existing container: name: container-1-busybox volumeMounts name: logfile mounthPath: /var/log Add new container: name: container-2-busybox image: busybox args: ['/bin/sh', '-c', 'tail -n+1 -f /var/log/my-pod-busybox.log'] volumeMounts: name: logfile mountPath: /var/log kubectl get pod my-busybox -o yaml > my-busybox.yaml vi my-busybox.yaml kubectl delete pod my-busybox kubectl apply -f my-busybox.yaml kubectl logs my-busybox -c container-2-busybox The final file my-busybox.yaml looks like below. apiVersion: v1 kind: Pod metadata: annotations: cni.projectcalico.org/containerID: 89644b6b073cd152f94b4cae7bdea6bbc3292cf59afd4f28102bd74f0205c9e4 cni.projectcalico.org/podIP: 10.244.102.20/32 cni.projectcalico.org/podIPs: 10.244.102.20/32 kubectl.kubernetes.io/last-applied-configuration: | {\"apiVersion\":\"v1\",\"kind\":\"Pod\",\"metadata\":{\"annotations\":{},\"name\":\"my-busybox\",\"namespace\":\"dev\"},\"spec\":{\"containers\":[{\"args\":[\"/bin/sh\",\"-c\",\"i=0; while true; do\\n echo \\\"Hello message from container-1: \\\" \\u003e\\u003e /var/log/my-pod-busybox.log;\\n i=1;\\n sleep 1;\\ndone\\n\"],\"image\":\"busybox\",\"name\":\"container-1-busybox\"}]}} creationTimestamp: \"2022-07-29T22:58:27Z\" name: my-busybox namespace: dev resourceVersion: \"1185720\" uid: c5e62a16-4459-4828-a441-7d1471b89a56 spec: containers: - name: container-2-busybox image: busybox args: ['/bin/sh', '-c', 'tail -n+1 -f /var/log/my-pod-busybox.log'] volumeMounts: - name: logfile mountPath: /var/log - args: - /bin/sh - -c - | i=0; while true; do echo \"Hello message from container-1: $i\" >> /var/log/my-pod-busybox.log; i=1; sleep 1; done image: busybox imagePullPolicy: Always name: container-1-busybox resources: {} terminationMessagePath: /dev/termination-log terminationMessagePolicy: File volumeMounts: - name: logfile mountPath: /var/log - mountPath: /var/run/secrets/kubernetes.io/serviceaccount name: kube-api-access-mhxlf readOnly: true dnsPolicy: ClusterFirst enableServiceLinks: true nodeName: cka003 preemptionPolicy: PreemptLowerPriority priority: 0 restartPolicy: Always schedulerName: default-scheduler securityContext: {} serviceAccount: default serviceAccountName: default terminationGracePeriodSeconds: 30 tolerations: - effect: NoExecute key: node.kubernetes.io/not-ready operator: Exists tolerationSeconds: 300 - effect: NoExecute key: node.kubernetes.io/unreachable operator: Exists tolerationSeconds: 300 volumes: - name: logfile emptyDir: {} - name: kube-api-access-mhxlf projected: defaultMode: 420 sources: - serviceAccountToken: expirationSeconds: 3607 path: token - configMap: items: - key: ca.crt path: ca.crt name: kube-root-ca.crt - downwardAPI: items: - fieldRef: apiVersion: v1 fieldPath: metadata.namespace path: namespace status: conditions: - lastProbeTime: null lastTransitionTime: \"2022-07-29T22:58:27Z\" status: \"True\" type: Initialized - lastProbeTime: null lastTransitionTime: \"2022-07-29T22:58:30Z\" status: \"True\" type: Ready - lastProbeTime: null lastTransitionTime: \"2022-07-29T22:58:30Z\" status: \"True\" type: ContainersReady - lastProbeTime: null lastTransitionTime: \"2022-07-29T22:58:27Z\" status: \"True\" type: PodScheduled containerStatuses: - containerID: containerd://fd42d4ba4d94d8918d8846327b1db2328be13c5f93f381877ff0228ed7b5468d image: docker.io/library/busybox:latest imageID: docker.io/library/busybox@sha256:0e97a8ca6955f22dbc7db9e9dbe970971f423541e52c34b8cb96ccc88d6a3883 lastState: {} name: container-1-busybox ready: true restartCount: 0 started: true state: running: startedAt: \"2022-07-29T22:58:30Z\" hostIP: phase: Running podIP: 10.244.102.20 podIPs: - ip: 10.244.102.20 qosClass: BestEffort startTime: \"2022-07-29T22:58:27Z\" Clean up: kubectl delete pod my-busybox initContainer Pod \u00b6 Scenario: Create Pod myapp-pod that has two init containers. myapp-container init-mydb Create two Services. myservice mydb Conclusion: myapp-container waits for Service myservice up in order to resolve the name myservice.dev.svc.cluster.local init-mydb waits for Service mydb up in order to resolve the name mydb.dev.svc.cluster.local . Demo: Create Pod myapp-pod with below yaml file. Create yaml file myapp-pod.yaml and add below content. Note: Due to the command $(cat /var/..... will be treated as host variable, we can not use echo to generate the file. It's the variabel in container itself. vi myapp-pod.yaml Content apiVersion: v1 kind: Pod metadata: name: myapp-pod labels: app: myapp spec: containers: - name: myapp-container image: busybox:1.28 command: ['sh', '-c', 'echo The app is running! && sleep 3600'] initContainers: - name: init-myservice image: busybox:1.28 command: ['sh', '-c', \"until nslookup myservice.$(cat /var/run/secrets/kubernetes.io/serviceaccount/namespace).svc.cluster.local; do echo waiting for myservice; sleep 2; done\"] - name: init-mydb image: busybox:1.28 command: ['sh', '-c', \"until nslookup mydb.$(cat /var/run/secrets/kubernetes.io/serviceaccount/namespace).svc.cluster.local; do echo waiting for mydb; sleep 2; done\"] Apply the yaml file to create the Pod. kubectl apply -f myapp-pod.yaml Check Pod status. kubectl get pod myapp-pod Result NAME READY STATUS RESTARTS AGE myapp-pod 0/1 Init:0/2 0 12m Inspect Pods. Get two errors: nslookup: can't resolve 'myservice.dev.svc.cluster.local' container \"init-mydb\" in pod \"myapp-pod\" is waiting to start: PodInitializing kubectl logs myapp-pod -c init-myservice # Inspect the first init container kubectl logs myapp-pod -c init-mydb # Inspect the second init container At this point, those init containers will be waiting to discover Services named mydb and myservice. Create the mydb and myservice services: kubectl apply -f - << EOF apiVersion: v1 kind: Service metadata: name: myservice spec: ports: - protocol: TCP port: 80 targetPort: 9376 --- apiVersion: v1 kind: Service metadata: name: mydb spec: ports: - protocol: TCP port: 80 targetPort: 9377 EOF Get current status of Services. kubectl get service Both of Services are up. NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE mydb ClusterIP 11.244.239.149 80/TCP 6s myservice ClusterIP 11.244.116.126 80/TCP 6s Get current Pod status. kubectl get pod myapp-pod -o wide The Pod is up. NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES myapp-pod 0/1 Init:0/2 0 2m40s 10.244.112.2 cka002 We now see that those init containers complete, and that the myapp-pod Pod moves into the Running state. Clean up. kubectl delete service mydb myservice kubectl delete pod myapp-pod References: Pod basics Lifecycle & phases Kubernetes pod design pattern","title":"Pod"},{"location":"k8s/cka_en/foundamentals/pod/#work-on-pod","text":"","title":"Work on pod"},{"location":"k8s/cka_en/foundamentals/pod/#create-pod","text":"Create pod my-first-podl . kubectl apply -f - << EOF apiVersion: v1 kind: Pod metadata: name: my-first-pod spec: containers: - name: nginx image: nginx:mainline ports: - containerPort: 80 EOF Verify status of the pod just created. kubectl get pods -o wide","title":"Create pod"},{"location":"k8s/cka_en/foundamentals/pod/#track-pod","text":"Check logs of the pod just created. kubectl logs my-first-pod In case logs or describe or any other of the output generating commands don't help us to get to the root cause of an issue, we can use use kubectl exec -it -- bash command to look into it ourselves. kubectl exec -it my-first-pod -- bash root@my-first-pod:/# ls root@my-first-pod:/# cd bin root@my-first-pod:/bin# ls root@my-first-pod:/bin# exit Execute command kubectl explain pod.spec will get details of Spec segment of Pod kind in yaml file. We can check the official API reference of the pod resource for help or use kubectl explain pod to get a command-line based description of the resource. By appending . to the resource type, the explain command will provide more details on the specified field. kubectl explain pod.kind kubectl explain pod.spec kubectl explain pod.spec.containers kubectl explain pod.spec.containers.name","title":"Track pod"},{"location":"k8s/cka_en/foundamentals/pod/#label-pod","text":"Get pod's label with option --show-labels . kubectl get pods kubectl get pods --show-labels Add two labels to the pod pod my-first-pod . kubectl label pod my-first-pod nginx=mainline kubectl label pod my-first-pod env=demo kubectl get pods --show-labels Search pod by labels. kubectl get pod -l env=demo kubectl get pod -l env=demo,nginx=mainline kubectl get pod -l env=training Remove label kubectl label pods my-first-pod env- kubectl get pods --show-labels Describe pod. kubectl describe pod my-first-pod Delete pod. Run watch kubectl get pods to monitor the pod status. kubectl delete pod my-first-pod watch kubectl get pods","title":"Label pod"},{"location":"k8s/cka_en/foundamentals/pod/#static-pod","text":"Scenario *Create a static pod. * kubectl will automatically check yaml file in /etc/kubernetes/manifests/ and create the static pod once it's detected. Demo: Some system static Pods are already in place. ll /etc/kubernetes/manifests/ Result -rw------- 1 root root 2292 Jul 23 10:45 etcd.yaml -rw------- 1 root root 3889 Jul 23 10:45 kube-apiserver.yaml -rw------- 1 root root 3395 Jul 23 10:45 kube-controller-manager.yaml -rw------- 1 root root 1464 Jul 23 10:45 kube-scheduler.yaml Create yaml file my-nginx.yaml in directory /etc/kubernetes/manifests/ . Once the file is created, the static pod my-nginx is created automatically. kubectl run my-nginx --image=nginx:mainline --dry-run=client -n default -oyaml | sudo tee /etc/kubernetes/manifests/my-nginx.yaml Check status of the Pod my-nginx . The node name cka001 is part of the Pod name, which means the Pod is running on node cka001 . kubectl get pod -o wide Result NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES my-nginx-cka001 1/1 Running 0 20s 10.244.228.196 cka001 Delete the yaml file /etc/kubernetes/manifests/my-nginx.yaml , the static pod will be deleted automatically. sudo rm /etc/kubernetes/manifests/my-nginx.yaml","title":"Static Pod"},{"location":"k8s/cka_en/foundamentals/pod/#multi-container-pod","text":"Scenario: Create Multi-Container Pod Describe the Pod Check the log of Pod Check the log of Containers Create a Pod multi-container-pod with multiple container container-1-nginx and container-2-alpine . kubectl apply -f - << EOF apiVersion: v1 kind: Pod metadata: name: multi-container-pod spec: containers: - name: container-1-nginx image: nginx ports: - containerPort: 80 - name: container-2-alpine image: alpine command: [\"watch\", \"wget\", \"-qO-\", \"localhost\"] EOF Get the status. kubectl get pod multi-container-pod Result NAME READY STATUS RESTARTS AGE multi-container-pod 2/2 Running 0 81s Get details of the pod. kubectl describe pod multi-container-pod Result ....... Events: Type Reason Age From Message ---- ------ ---- ---- ------- Normal Scheduled 41s default-scheduler Successfully assigned dev/multi-container-pod to cka002 Normal Pulling 40s kubelet Pulling image \"nginx\" Normal Pulled 23s kubelet Successfully pulled image \"nginx\" in 16.767129903s Normal Created 22s kubelet Created container container-1-nginx Normal Started 22s kubelet Started container container-1-nginx Normal Pulling 22s kubelet Pulling image \"alpine\" Normal Pulled 14s kubelet Successfully pulled image \"alpine\" in 7.776104353s Normal Created 14s kubelet Created container container-2-alpine Normal Started 14s kubelet Started container container-2-alpine For multi-container pod, container name is needed if we want to get log of pod via command kubectl logs . Without the container name, we receive error. kubectl logs multi-container-pod Result error: a container name must be specified for pod multi-container-pod, choose one of: [container-1-nginx container-2-alpine] With specified container name, we get the log info. kubectl logs multi-container-pod container-1-nginx Result ...... ::1 - - [23/Jul/2022:04:06:37 +0000] \"GET / HTTP/1.1\" 200 615 \"-\" \"Wget\" \"-\" Same if we need specify container name to login into the pod via command kubectl exec -it -c -- . kubectl exec -it multi-container-pod -c container-1-nginx -- /bin/bash root@multi-container-pod:/# ls Clean up kubectl delete pod multi-container-pod Quick reference of a simple yaml file to create Multiple Containers. kubectl apply -f - << EOF apiVersion: v1 kind: Pod metadata: name: my-multi-pod spec: containers: - image: nginx name: nginx - image: memcached name: memcached - image: redis name: redis EOF Scenario: Create a Pod my-busybox with a container container-1-busybox . The container will write message to file /var/log/my-pod-busybox.log . Add another container container-2-busybox (Sidecar) to the Pod my-busybox . The sidecar container read message from file /var/log/my-pod-busybox.log . Tips: create a Volume to store the log file, which is shared with two containers. Demo: Create a Pod my-busybox with a container container-1-busybox . kubectl apply -f - << EOF apiVersion: v1 kind: Pod metadata: name: my-busybox spec: containers: - name: container-1-busybox image: busybox args: - /bin/sh - -c - > i=0; while true; do echo \"Hello message from container-1: $i\" >> /var/log/my-pod-busybox.log; i=$((i+1)); sleep 1; done EOF Search emptyDir in the Kubernetes documetation. Refer to below template for emptyDir via https://kubernetes.io/zh-cn/docs/concepts/storage/volumes/ Add below new features into the Pod Volume: volume name: logfile type: emptyDir Update existing container: name: container-1-busybox volumeMounts name: logfile mounthPath: /var/log Add new container: name: container-2-busybox image: busybox args: ['/bin/sh', '-c', 'tail -n+1 -f /var/log/my-pod-busybox.log'] volumeMounts: name: logfile mountPath: /var/log kubectl get pod my-busybox -o yaml > my-busybox.yaml vi my-busybox.yaml kubectl delete pod my-busybox kubectl apply -f my-busybox.yaml kubectl logs my-busybox -c container-2-busybox The final file my-busybox.yaml looks like below. apiVersion: v1 kind: Pod metadata: annotations: cni.projectcalico.org/containerID: 89644b6b073cd152f94b4cae7bdea6bbc3292cf59afd4f28102bd74f0205c9e4 cni.projectcalico.org/podIP: 10.244.102.20/32 cni.projectcalico.org/podIPs: 10.244.102.20/32 kubectl.kubernetes.io/last-applied-configuration: | {\"apiVersion\":\"v1\",\"kind\":\"Pod\",\"metadata\":{\"annotations\":{},\"name\":\"my-busybox\",\"namespace\":\"dev\"},\"spec\":{\"containers\":[{\"args\":[\"/bin/sh\",\"-c\",\"i=0; while true; do\\n echo \\\"Hello message from container-1: \\\" \\u003e\\u003e /var/log/my-pod-busybox.log;\\n i=1;\\n sleep 1;\\ndone\\n\"],\"image\":\"busybox\",\"name\":\"container-1-busybox\"}]}} creationTimestamp: \"2022-07-29T22:58:27Z\" name: my-busybox namespace: dev resourceVersion: \"1185720\" uid: c5e62a16-4459-4828-a441-7d1471b89a56 spec: containers: - name: container-2-busybox image: busybox args: ['/bin/sh', '-c', 'tail -n+1 -f /var/log/my-pod-busybox.log'] volumeMounts: - name: logfile mountPath: /var/log - args: - /bin/sh - -c - | i=0; while true; do echo \"Hello message from container-1: $i\" >> /var/log/my-pod-busybox.log; i=1; sleep 1; done image: busybox imagePullPolicy: Always name: container-1-busybox resources: {} terminationMessagePath: /dev/termination-log terminationMessagePolicy: File volumeMounts: - name: logfile mountPath: /var/log - mountPath: /var/run/secrets/kubernetes.io/serviceaccount name: kube-api-access-mhxlf readOnly: true dnsPolicy: ClusterFirst enableServiceLinks: true nodeName: cka003 preemptionPolicy: PreemptLowerPriority priority: 0 restartPolicy: Always schedulerName: default-scheduler securityContext: {} serviceAccount: default serviceAccountName: default terminationGracePeriodSeconds: 30 tolerations: - effect: NoExecute key: node.kubernetes.io/not-ready operator: Exists tolerationSeconds: 300 - effect: NoExecute key: node.kubernetes.io/unreachable operator: Exists tolerationSeconds: 300 volumes: - name: logfile emptyDir: {} - name: kube-api-access-mhxlf projected: defaultMode: 420 sources: - serviceAccountToken: expirationSeconds: 3607 path: token - configMap: items: - key: ca.crt path: ca.crt name: kube-root-ca.crt - downwardAPI: items: - fieldRef: apiVersion: v1 fieldPath: metadata.namespace path: namespace status: conditions: - lastProbeTime: null lastTransitionTime: \"2022-07-29T22:58:27Z\" status: \"True\" type: Initialized - lastProbeTime: null lastTransitionTime: \"2022-07-29T22:58:30Z\" status: \"True\" type: Ready - lastProbeTime: null lastTransitionTime: \"2022-07-29T22:58:30Z\" status: \"True\" type: ContainersReady - lastProbeTime: null lastTransitionTime: \"2022-07-29T22:58:27Z\" status: \"True\" type: PodScheduled containerStatuses: - containerID: containerd://fd42d4ba4d94d8918d8846327b1db2328be13c5f93f381877ff0228ed7b5468d image: docker.io/library/busybox:latest imageID: docker.io/library/busybox@sha256:0e97a8ca6955f22dbc7db9e9dbe970971f423541e52c34b8cb96ccc88d6a3883 lastState: {} name: container-1-busybox ready: true restartCount: 0 started: true state: running: startedAt: \"2022-07-29T22:58:30Z\" hostIP: phase: Running podIP: 10.244.102.20 podIPs: - ip: 10.244.102.20 qosClass: BestEffort startTime: \"2022-07-29T22:58:27Z\" Clean up: kubectl delete pod my-busybox","title":"Multi-Container Pod"},{"location":"k8s/cka_en/foundamentals/pod/#initcontainer-pod","text":"Scenario: Create Pod myapp-pod that has two init containers. myapp-container init-mydb Create two Services. myservice mydb Conclusion: myapp-container waits for Service myservice up in order to resolve the name myservice.dev.svc.cluster.local init-mydb waits for Service mydb up in order to resolve the name mydb.dev.svc.cluster.local . Demo: Create Pod myapp-pod with below yaml file. Create yaml file myapp-pod.yaml and add below content. Note: Due to the command $(cat /var/..... will be treated as host variable, we can not use echo to generate the file. It's the variabel in container itself. vi myapp-pod.yaml Content apiVersion: v1 kind: Pod metadata: name: myapp-pod labels: app: myapp spec: containers: - name: myapp-container image: busybox:1.28 command: ['sh', '-c', 'echo The app is running! && sleep 3600'] initContainers: - name: init-myservice image: busybox:1.28 command: ['sh', '-c', \"until nslookup myservice.$(cat /var/run/secrets/kubernetes.io/serviceaccount/namespace).svc.cluster.local; do echo waiting for myservice; sleep 2; done\"] - name: init-mydb image: busybox:1.28 command: ['sh', '-c', \"until nslookup mydb.$(cat /var/run/secrets/kubernetes.io/serviceaccount/namespace).svc.cluster.local; do echo waiting for mydb; sleep 2; done\"] Apply the yaml file to create the Pod. kubectl apply -f myapp-pod.yaml Check Pod status. kubectl get pod myapp-pod Result NAME READY STATUS RESTARTS AGE myapp-pod 0/1 Init:0/2 0 12m Inspect Pods. Get two errors: nslookup: can't resolve 'myservice.dev.svc.cluster.local' container \"init-mydb\" in pod \"myapp-pod\" is waiting to start: PodInitializing kubectl logs myapp-pod -c init-myservice # Inspect the first init container kubectl logs myapp-pod -c init-mydb # Inspect the second init container At this point, those init containers will be waiting to discover Services named mydb and myservice. Create the mydb and myservice services: kubectl apply -f - << EOF apiVersion: v1 kind: Service metadata: name: myservice spec: ports: - protocol: TCP port: 80 targetPort: 9376 --- apiVersion: v1 kind: Service metadata: name: mydb spec: ports: - protocol: TCP port: 80 targetPort: 9377 EOF Get current status of Services. kubectl get service Both of Services are up. NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE mydb ClusterIP 11.244.239.149 80/TCP 6s myservice ClusterIP 11.244.116.126 80/TCP 6s Get current Pod status. kubectl get pod myapp-pod -o wide The Pod is up. NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES myapp-pod 0/1 Init:0/2 0 2m40s 10.244.112.2 cka002 We now see that those init containers complete, and that the myapp-pod Pod moves into the Running state. Clean up. kubectl delete service mydb myservice kubectl delete pod myapp-pod References: Pod basics Lifecycle & phases Kubernetes pod design pattern","title":"initContainer Pod"},{"location":"k8s/cka_en/foundamentals/policy/","text":"Policy \u00b6 ResourceQuota \u00b6 Scenario: Create ResourceQuota object-quota-demo for namespace quota-object-example . Test ResourceQuota object-quota-demo for NodePort Test ResourceQuota object-quota-demo for PVC Create Namespace \u00b6 Ceate a Namespace kubectl create ns quota-object-example Create ResourceQuota for Namespace \u00b6 Create ResourceQuota object-quota-demo for namespace quota-object-example . Within the namespace, we can only create 1 PVC, 1 LoadBalancer Service, can not create NodePort Service. kubectl apply -f - <@ ) CURRENT NAME CLUSTER AUTHINFO NAMESPACE * kubernetes-admin@kubernetes kubernetes kubernetes-admin dev Create CA Config File \u00b6 Get overview of directory /etc/kubernetes/pki . tree /etc/kubernetes/pki Result /etc/kubernetes/pki \u251c\u2500\u2500 apiserver.crt \u251c\u2500\u2500 apiserver-etcd-client.crt \u251c\u2500\u2500 apiserver-etcd-client.key \u251c\u2500\u2500 apiserver.key \u251c\u2500\u2500 apiserver-kubelet-client.crt \u251c\u2500\u2500 apiserver-kubelet-client.key \u251c\u2500\u2500 ca.crt \u251c\u2500\u2500 ca.key \u251c\u2500\u2500 etcd \u2502 \u251c\u2500\u2500 ca.crt \u2502 \u251c\u2500\u2500 ca.key \u2502 \u251c\u2500\u2500 healthcheck-client.crt \u2502 \u251c\u2500\u2500 healthcheck-client.key \u2502 \u251c\u2500\u2500 peer.crt \u2502 \u251c\u2500\u2500 peer.key \u2502 \u251c\u2500\u2500 server.crt \u2502 \u2514\u2500\u2500 server.key \u251c\u2500\u2500 front-proxy-ca.crt \u251c\u2500\u2500 front-proxy-ca.key \u251c\u2500\u2500 front-proxy-client.crt \u251c\u2500\u2500 front-proxy-client.key \u251c\u2500\u2500 sa.key \u2514\u2500\u2500 sa.pub Change to directory /etc/kubernetes/pki . cd /etc/kubernetes/pki Check if file ca-config.json is in place in current directory. ll ca-config.json If not, create it. We can add multiple profiles to specify different expiry date, scenario, parameters, etc.. Profile will be used to sign certificate. 87600 hours are about 10 years. Here we will create 1 additional profile dev . cat > ca-config.json < cka-dev-csr.json < here) to composite evn variable APISERVER ( https://: ). kubectl get node -owide NAME STATUS ROLES AGE VERSION OS-IMAGE KERNEL-VERSION CONTAINER-RUNTIME cka001 Ready control-plane,master 14h v1.24.0 Ubuntu 20.04.4 LTS 5.4.0-122-generic containerd://1.5.9 cka002 Ready 14h v1.24.0 Ubuntu 20.04.4 LTS 5.4.0-122-generic containerd://1.5.9 cka003 Ready 14h v1.24.0 Ubuntu 20.04.4 LTS 5.4.0-122-generic containerd://1.5.9 Export env APISERVER . echo \"export APISERVER=\\\"https://:6443\\\"\" >> ~/.bashrc source ~/.bashrc Verify the setting. echo $APISERVER Output: https://:6443 1.Set up cluster Stay in the directory /etc/kubernetes/pki . Generate kubeconfig file. kubectl config set-cluster kubernetes \\ --certificate-authority=/etc/kubernetes/pki/ca.crt \\ --embed-certs=true \\ --server=${APISERVER} \\ --kubeconfig=cka-dev.kubeconfig Now we get the new config file cka-dev.kubeconfig ll -tr | grep cka-dev Output: -rw-r--r-- 1 root root 222 Jul 24 08:49 cka-dev-csr.json -rw-r--r-- 1 root root 1281 Jul 24 09:14 cka-dev.pem -rw------- 1 root root 1675 Jul 24 09:14 cka-dev-key.pem -rw-r--r-- 1 root root 1001 Jul 24 09:14 cka-dev.csr -rw------- 1 root root 1671 Jul 24 09:16 cka-dev.kubeconfig Get content of file cka-dev.kubeconfig . cat cka-dev.kubeconfig apiVersion : v1 clusters : - cluster : certificate-authority-data : server : https://:6443 name : kubernetes contexts : null current-context : \"\" kind : Config preferences : {} users : null 2.Set up user In file cka-dev.kubeconfig , user info is null. Set up user cka-dev . kubectl config set-credentials cka-dev \\ --client-certificate=/etc/kubernetes/pki/cka-dev.pem \\ --client-key=/etc/kubernetes/pki/cka-dev-key.pem \\ --embed-certs=true \\ --kubeconfig=cka-dev.kubeconfig Now file cka-dev.kubeconfig was updated and user information was added. cat cka-dev.kubeconfig apiVersion : v1 clusters : - cluster : certificate-authority-data : server : https://:6443 name : kubernetes contexts : null current-context : \"\" kind : Config preferences : {} users : - name : cka-dev user : client-certificate-data : client-key-data : Now we have a complete kubeconfig file cka-dev.kubeconfig . When we use it to get node information, receive error below because we did not set up current-context in kubeconfig file. kubectl --kubeconfig=cka-dev.kubeconfig get nodes The connection to the server localhost:8080 was refused - did you specify the right host or port? Current contents is empty. kubectl --kubeconfig=cka-dev.kubeconfig config get-contexts CURRENT NAME CLUSTER AUTHINFO NAMESPACE 3.Set up Context Set up context. kubectl config set-context dev --cluster=kubernetes --user=cka-dev --kubeconfig=cka-dev.kubeconfig Now we have context now but the CURRENT flag is empty. kubectl --kubeconfig=cka-dev.kubeconfig config get-contexts Output: CURRENT NAME CLUSTER AUTHINFO NAMESPACE dev kubernetes cka-dev Set up default context. The context will link clusters and users for multiple clusters environment and we can switch to different cluster. kubectl --kubeconfig=cka-dev.kubeconfig config use-context dev 4.Verify Now CURRENT is marked with * , that is, current-context is set up. kubectl --kubeconfig=cka-dev.kubeconfig config get-contexts CURRENT NAME CLUSTER AUTHINFO NAMESPACE * dev kubernetes cka-dev Because user cka-dev does not have authorization in the cluster, we will receive forbidden error when we try to get information of Pods or Nodes. kubectl --kubeconfig=/etc/kubernetes/pki/cka-dev.kubeconfig get pod kubectl --kubeconfig=/etc/kubernetes/pki/cka-dev.kubeconfig get node Merge kubeconfig files \u00b6 Make a copy of your existing config cp ~/.kube/config ~/.kube/config.old Merge the two config files together into a new config file /tmp/config . KUBECONFIG=~/.kube/config:/etc/kubernetes/pki/cka-dev.kubeconfig kubectl config view --flatten > /tmp/config Replace the old config with the new merged config mv /tmp/config ~/.kube/config Now the new ~/.kube/config looks like below. apiVersion: v1 clusters: - cluster: certificate-authority-data: server: https://:6443 name: kubernetes contexts: - context: cluster: kubernetes user: cka-dev name: dev - context: cluster: kubernetes user: kubernetes-admin name: kubernetes-admin@kubernetes current-context: kubernetes-admin@kubernetes kind: Config preferences: {} users: - name: cka-dev user: client-certificate-data: client-key-data: - name: kubernetes-admin user: client-certificate-data: client-key-data: Verify contexts after kubeconfig merged. kubectl config get-contexts Current context is the system default kubernetes-admin@kubernetes . CURRENT NAME CLUSTER AUTHINFO NAMESPACE dev kubernetes cka-dev * kubernetes-admin@kubernetes kubernetes kubernetes-admin dev Namespaces & Contexts \u00b6 Get list of Namespace with Label information. kubectl get ns --show-labels Create Namespace cka . kubectl create namespace cka Use below command to set a context with new update, e.g, update default namespace, etc.. kubectl config set-context --cluster= --namespace= --user= Let's set default namespace to each context. kubectl config set-context kubernetes-admin@kubernetes --cluster=kubernetes --namespace=default --user=kubernetes-admin kubectl config set-context dev --cluster=kubernetes --namespace=cka --user=cka-dev Let's check current context information. kubectl config get-contexts Output: CURRENT NAME CLUSTER AUTHINFO NAMESPACE dev kubernetes cka-dev cka * kubernetes-admin@kubernetes kubernetes kubernetes-admin dev To switch to a new context, use below command. kubectl config use-contexts For example. kubectl config use-context dev Verify if it's changed as expected. kubectl config get-contexts CURRENT NAME CLUSTER AUTHINFO NAMESPACE * dev kubernetes cka-dev cka kubernetes-admin@kubernetes kubernetes kubernetes-admin dev Be noted, four users beginning with cka-dev created don't have any authorizations, e.g., access namespaces, get pods, etc.. Referring RBAC to grant their authorizations. Role & RoleBinding \u00b6 Switch to context kubernetes-admin@kubernetes . kubectl config use-context kubernetes-admin@kubernetes Use kubectl create role command with option --dry-run=client and -o yaml to generate yaml template for customizing. kubectl create role admin-dev --resource=pods --verb=get --verb=list --verb=watch --dry-run=client -o yaml Create role admin-dev on namespace cka . kubectl apply -f - << EOF apiVersion: rbac.authorization.k8s.io/v1 kind: Role metadata: namespace: cka name: admin-dev rules: - apiGroups: - \"\" resources: - pods verbs: - get - watch - list EOF Use kubectl create rolebinding command with option --dry-run=client and -o yaml to generate yaml template for customizing. kubectl create rolebinding admin --role=admin-dev --user=cka-dev --dry-run=client -o yaml Create rolebinding admin on namespace cka . kubectl apply -f - << EOF apiVersion: rbac.authorization.k8s.io/v1 kind: RoleBinding metadata: name: admin namespace: cka roleRef: apiGroup: rbac.authorization.k8s.io kind: Role name: admin-dev subjects: - apiGroup: rbac.authorization.k8s.io kind: User name: cka-dev EOF Verify authorzation of user cka-dev on Namespace cka . Switch to context dev . kubectl config use-context dev Get Pods status in Namespace cka . Success! kubectl get pod -n cka Get Pods status in Namespace kube-system . Failed, because the authorzation is only for Namespace cka . kubectl get pod -n kube-system Get Nodes status. Failed, because the role we defined is only for Pod resource. kubectl get node Create a Pod in Namespace dev . Failed because we only have get , watch , list for Pod, no create authorization. kubectl run nginx --image=nginx -n cka ClusterRole & ClusterRoleBinding \u00b6 Switch to context kubernetes-admin@kubernetes . kubectl config use-context kubernetes-admin@kubernetes Create a ClusterRole nodes-admin with authorization get , watch , list for nodes resource. kubectl apply -f - <@ ) CURRENT NAME CLUSTER AUTHINFO NAMESPACE * kubernetes-admin@kubernetes kubernetes kubernetes-admin dev","title":"Current Context"},{"location":"k8s/cka_en/foundamentals/rbac/#create-ca-config-file","text":"Get overview of directory /etc/kubernetes/pki . tree /etc/kubernetes/pki Result /etc/kubernetes/pki \u251c\u2500\u2500 apiserver.crt \u251c\u2500\u2500 apiserver-etcd-client.crt \u251c\u2500\u2500 apiserver-etcd-client.key \u251c\u2500\u2500 apiserver.key \u251c\u2500\u2500 apiserver-kubelet-client.crt \u251c\u2500\u2500 apiserver-kubelet-client.key \u251c\u2500\u2500 ca.crt \u251c\u2500\u2500 ca.key \u251c\u2500\u2500 etcd \u2502 \u251c\u2500\u2500 ca.crt \u2502 \u251c\u2500\u2500 ca.key \u2502 \u251c\u2500\u2500 healthcheck-client.crt \u2502 \u251c\u2500\u2500 healthcheck-client.key \u2502 \u251c\u2500\u2500 peer.crt \u2502 \u251c\u2500\u2500 peer.key \u2502 \u251c\u2500\u2500 server.crt \u2502 \u2514\u2500\u2500 server.key \u251c\u2500\u2500 front-proxy-ca.crt \u251c\u2500\u2500 front-proxy-ca.key \u251c\u2500\u2500 front-proxy-client.crt \u251c\u2500\u2500 front-proxy-client.key \u251c\u2500\u2500 sa.key \u2514\u2500\u2500 sa.pub Change to directory /etc/kubernetes/pki . cd /etc/kubernetes/pki Check if file ca-config.json is in place in current directory. ll ca-config.json If not, create it. We can add multiple profiles to specify different expiry date, scenario, parameters, etc.. Profile will be used to sign certificate. 87600 hours are about 10 years. Here we will create 1 additional profile dev . cat > ca-config.json < cka-dev-csr.json < here) to composite evn variable APISERVER ( https://: ). kubectl get node -owide NAME STATUS ROLES AGE VERSION OS-IMAGE KERNEL-VERSION CONTAINER-RUNTIME cka001 Ready control-plane,master 14h v1.24.0 Ubuntu 20.04.4 LTS 5.4.0-122-generic containerd://1.5.9 cka002 Ready 14h v1.24.0 Ubuntu 20.04.4 LTS 5.4.0-122-generic containerd://1.5.9 cka003 Ready 14h v1.24.0 Ubuntu 20.04.4 LTS 5.4.0-122-generic containerd://1.5.9 Export env APISERVER . echo \"export APISERVER=\\\"https://:6443\\\"\" >> ~/.bashrc source ~/.bashrc Verify the setting. echo $APISERVER Output: https://:6443 1.Set up cluster Stay in the directory /etc/kubernetes/pki . Generate kubeconfig file. kubectl config set-cluster kubernetes \\ --certificate-authority=/etc/kubernetes/pki/ca.crt \\ --embed-certs=true \\ --server=${APISERVER} \\ --kubeconfig=cka-dev.kubeconfig Now we get the new config file cka-dev.kubeconfig ll -tr | grep cka-dev Output: -rw-r--r-- 1 root root 222 Jul 24 08:49 cka-dev-csr.json -rw-r--r-- 1 root root 1281 Jul 24 09:14 cka-dev.pem -rw------- 1 root root 1675 Jul 24 09:14 cka-dev-key.pem -rw-r--r-- 1 root root 1001 Jul 24 09:14 cka-dev.csr -rw------- 1 root root 1671 Jul 24 09:16 cka-dev.kubeconfig Get content of file cka-dev.kubeconfig . cat cka-dev.kubeconfig apiVersion : v1 clusters : - cluster : certificate-authority-data : server : https://:6443 name : kubernetes contexts : null current-context : \"\" kind : Config preferences : {} users : null 2.Set up user In file cka-dev.kubeconfig , user info is null. Set up user cka-dev . kubectl config set-credentials cka-dev \\ --client-certificate=/etc/kubernetes/pki/cka-dev.pem \\ --client-key=/etc/kubernetes/pki/cka-dev-key.pem \\ --embed-certs=true \\ --kubeconfig=cka-dev.kubeconfig Now file cka-dev.kubeconfig was updated and user information was added. cat cka-dev.kubeconfig apiVersion : v1 clusters : - cluster : certificate-authority-data : server : https://:6443 name : kubernetes contexts : null current-context : \"\" kind : Config preferences : {} users : - name : cka-dev user : client-certificate-data : client-key-data : Now we have a complete kubeconfig file cka-dev.kubeconfig . When we use it to get node information, receive error below because we did not set up current-context in kubeconfig file. kubectl --kubeconfig=cka-dev.kubeconfig get nodes The connection to the server localhost:8080 was refused - did you specify the right host or port? Current contents is empty. kubectl --kubeconfig=cka-dev.kubeconfig config get-contexts CURRENT NAME CLUSTER AUTHINFO NAMESPACE 3.Set up Context Set up context. kubectl config set-context dev --cluster=kubernetes --user=cka-dev --kubeconfig=cka-dev.kubeconfig Now we have context now but the CURRENT flag is empty. kubectl --kubeconfig=cka-dev.kubeconfig config get-contexts Output: CURRENT NAME CLUSTER AUTHINFO NAMESPACE dev kubernetes cka-dev Set up default context. The context will link clusters and users for multiple clusters environment and we can switch to different cluster. kubectl --kubeconfig=cka-dev.kubeconfig config use-context dev 4.Verify Now CURRENT is marked with * , that is, current-context is set up. kubectl --kubeconfig=cka-dev.kubeconfig config get-contexts CURRENT NAME CLUSTER AUTHINFO NAMESPACE * dev kubernetes cka-dev Because user cka-dev does not have authorization in the cluster, we will receive forbidden error when we try to get information of Pods or Nodes. kubectl --kubeconfig=/etc/kubernetes/pki/cka-dev.kubeconfig get pod kubectl --kubeconfig=/etc/kubernetes/pki/cka-dev.kubeconfig get node","title":"Create file kubeconfig"},{"location":"k8s/cka_en/foundamentals/rbac/#merge-kubeconfig-files","text":"Make a copy of your existing config cp ~/.kube/config ~/.kube/config.old Merge the two config files together into a new config file /tmp/config . KUBECONFIG=~/.kube/config:/etc/kubernetes/pki/cka-dev.kubeconfig kubectl config view --flatten > /tmp/config Replace the old config with the new merged config mv /tmp/config ~/.kube/config Now the new ~/.kube/config looks like below. apiVersion: v1 clusters: - cluster: certificate-authority-data: server: https://:6443 name: kubernetes contexts: - context: cluster: kubernetes user: cka-dev name: dev - context: cluster: kubernetes user: kubernetes-admin name: kubernetes-admin@kubernetes current-context: kubernetes-admin@kubernetes kind: Config preferences: {} users: - name: cka-dev user: client-certificate-data: client-key-data: - name: kubernetes-admin user: client-certificate-data: client-key-data: Verify contexts after kubeconfig merged. kubectl config get-contexts Current context is the system default kubernetes-admin@kubernetes . CURRENT NAME CLUSTER AUTHINFO NAMESPACE dev kubernetes cka-dev * kubernetes-admin@kubernetes kubernetes kubernetes-admin dev","title":"Merge kubeconfig files"},{"location":"k8s/cka_en/foundamentals/rbac/#namespaces-contexts","text":"Get list of Namespace with Label information. kubectl get ns --show-labels Create Namespace cka . kubectl create namespace cka Use below command to set a context with new update, e.g, update default namespace, etc.. kubectl config set-context --cluster= --namespace= --user= Let's set default namespace to each context. kubectl config set-context kubernetes-admin@kubernetes --cluster=kubernetes --namespace=default --user=kubernetes-admin kubectl config set-context dev --cluster=kubernetes --namespace=cka --user=cka-dev Let's check current context information. kubectl config get-contexts Output: CURRENT NAME CLUSTER AUTHINFO NAMESPACE dev kubernetes cka-dev cka * kubernetes-admin@kubernetes kubernetes kubernetes-admin dev To switch to a new context, use below command. kubectl config use-contexts For example. kubectl config use-context dev Verify if it's changed as expected. kubectl config get-contexts CURRENT NAME CLUSTER AUTHINFO NAMESPACE * dev kubernetes cka-dev cka kubernetes-admin@kubernetes kubernetes kubernetes-admin dev Be noted, four users beginning with cka-dev created don't have any authorizations, e.g., access namespaces, get pods, etc.. Referring RBAC to grant their authorizations.","title":"Namespaces & Contexts"},{"location":"k8s/cka_en/foundamentals/rbac/#role-rolebinding","text":"Switch to context kubernetes-admin@kubernetes . kubectl config use-context kubernetes-admin@kubernetes Use kubectl create role command with option --dry-run=client and -o yaml to generate yaml template for customizing. kubectl create role admin-dev --resource=pods --verb=get --verb=list --verb=watch --dry-run=client -o yaml Create role admin-dev on namespace cka . kubectl apply -f - << EOF apiVersion: rbac.authorization.k8s.io/v1 kind: Role metadata: namespace: cka name: admin-dev rules: - apiGroups: - \"\" resources: - pods verbs: - get - watch - list EOF Use kubectl create rolebinding command with option --dry-run=client and -o yaml to generate yaml template for customizing. kubectl create rolebinding admin --role=admin-dev --user=cka-dev --dry-run=client -o yaml Create rolebinding admin on namespace cka . kubectl apply -f - << EOF apiVersion: rbac.authorization.k8s.io/v1 kind: RoleBinding metadata: name: admin namespace: cka roleRef: apiGroup: rbac.authorization.k8s.io kind: Role name: admin-dev subjects: - apiGroup: rbac.authorization.k8s.io kind: User name: cka-dev EOF Verify authorzation of user cka-dev on Namespace cka . Switch to context dev . kubectl config use-context dev Get Pods status in Namespace cka . Success! kubectl get pod -n cka Get Pods status in Namespace kube-system . Failed, because the authorzation is only for Namespace cka . kubectl get pod -n kube-system Get Nodes status. Failed, because the role we defined is only for Pod resource. kubectl get node Create a Pod in Namespace dev . Failed because we only have get , watch , list for Pod, no create authorization. kubectl run nginx --image=nginx -n cka","title":"Role & RoleBinding"},{"location":"k8s/cka_en/foundamentals/rbac/#clusterrole-clusterrolebinding","text":"Switch to context kubernetes-admin@kubernetes . kubectl config use-context kubernetes-admin@kubernetes Create a ClusterRole nodes-admin with authorization get , watch , list for nodes resource. kubectl apply -f - < nodeName \u00b6 Be noted, nodeName has hightest priority as it's not scheduled by Scheduler . Create a Pod nginx-nodename with nodeName=cka003 . kubectl apply -f - < Affinity \u00b6 In Kubernetes cluster, some Pods have frequent interaction with other Pods. With that situation, it's suggested to schedule these Pods running on same node. For example, Two Pods Nginx and Mysql, we need deploy them on one node if they frequently communicate. We can use podAffinity to select Pods based on their relationship. There are two scheduling type of podAffinity . requiredDuringSchedulingIgnoredDuringExecution (\u786c\u4eb2\u548c) preferredDuringSchedulingIgnoredDuringExecution (\u8f6f\u4eb2\u548c) topologyKey could be set by below types: kubernetes.io/hostname \uff03NodeName failure-domain.beta.kubernetes.io/zone \uff03Zone failure-domain.beta.kubernetes.io/region # Region We can set node Label to classify Name/Zone/Region of node, which can be used by podAffinity . Create a Pod Nginx. kubectl apply -f - < ","title":"nodeSelector"},{"location":"k8s/cka_en/foundamentals/scheduling/#nodename","text":"Be noted, nodeName has hightest priority as it's not scheduled by Scheduler . Create a Pod nginx-nodename with nodeName=cka003 . kubectl apply -f - < ","title":"nodeName"},{"location":"k8s/cka_en/foundamentals/scheduling/#affinity","text":"In Kubernetes cluster, some Pods have frequent interaction with other Pods. With that situation, it's suggested to schedule these Pods running on same node. For example, Two Pods Nginx and Mysql, we need deploy them on one node if they frequently communicate. We can use podAffinity to select Pods based on their relationship. There are two scheduling type of podAffinity . requiredDuringSchedulingIgnoredDuringExecution (\u786c\u4eb2\u548c) preferredDuringSchedulingIgnoredDuringExecution (\u8f6f\u4eb2\u548c) topologyKey could be set by below types: kubernetes.io/hostname \uff03NodeName failure-domain.beta.kubernetes.io/zone \uff03Zone failure-domain.beta.kubernetes.io/region # Region We can set node Label to classify Name/Zone/Region of node, which can be used by podAffinity . Create a Pod Nginx. kubectl apply -f - < 80/TCP 14s app=httpd NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES pod/httpd-app-6496d888c9-4nb6z 1/1 Running 0 77s 10.244.102.21 cka003 pod/httpd-app-6496d888c9-b7xht 1/1 Running 0 77s 10.244.112.19 cka002 Verify the access to Pod IPs. curl 10.244.102.21 curl 10.244.112.19 And receive below successful information.

It works!

Verify the access via ClusterIP with Port. curl 11.244.247.7:80 And receive below successful information.

It works!

Expose Service \u00b6 Create and attach to a temporary Pod nslookup and to verify DNS resolution. The option --rm means delete the Pod after exit. kubectl run -it nslookup --rm --image=busybox:1.28 After attach to the Pod, run command nslookup httpd-app . We receive the ClusterIP of Service httpd-app and full domain name. / # nslookup httpd-app Server: 11.244.0.10 Address 1: 11.244.0.10 kube-dns.kube-system.svc.cluster.local Name: httpd-app Address 1: 11.244.247.7 httpd-app.dev.svc.cluster.local We can check the IP of temporary Pod nslookup in a new terminal by executing command kubectl get pod -o wide . The Pod nslookup has Pod IP 10.244.112.20 . kubectl get pod nslookup Result NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES nslookup 1/1 Running 0 2m44s 10.244.112.20 cka002 NodePort \u00b6 Create and apply yaml file svc-nodeport.yaml to create a Service httpd-app . kubectl apply -f - < will update configuration to existing resources. Here the Service httpd-app is changed from ClusterIP to NodePort type. No change to the Deployment httpd-app . service/httpd-app configured deployment.apps/httpd-app unchanged Check the Service httpd-app via kubectl get svc . IP is the same. Type is changed to NodePort. Port numbers is changed from 80/TCP to 80:30080/TCP . NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE httpd-app NodePort 11.244.247.7 80:30080/TCP 18m Test the connection to the Service httpd-app via command curl :30080 to each node. curl :30080 curl :30080 curl :30080 We will receive below successful information.

It works!

Headless Service \u00b6 Create Headless Service web and StatefulSet web . kubectl apply -f - < web-1 1/1 Running 0 6s 10.244.112.21 cka002 Get details of the Service by command kubectl describe svc -l app=web . Name: web Namespace: dev Labels: app=web Annotations: Selector: app=web Type: ClusterIP IP Family Policy: SingleStack IP Families: IPv4 IP: None IPs: None Port: web 80/TCP TargetPort: 80/TCP Endpoints: 10.244.102.22:80,10.244.112.21:80 Session Affinity: None Events: Attach to the temporary Pod nslookup and use nslookup to verify DNS resolution. kubectl run -it nslookup --rm --image=busybox:1.28 With nslookup command for Headless Service web , we received two Pod IPs, not ClusterIP due to Headless Service. / # nslookup web Server: 11.244.0.10 Address 1: 11.244.0.10 kube-dns.kube-system.svc.cluster.local Name: web Address 1: 10.244.112.21 web-1.web.dev.svc.cluster.local Address 2: 10.244.102.22 web-0.web.dev.svc.cluster.local We can also use nslookup for web-0.web and web-1.web . Every Pod of Headless Service has own Service Name for DNS lookup. / # nslookup web-0.web Server: 11.244.0.10 Address 1: 11.244.0.10 kube-dns.kube-system.svc.cluster.local Name: web-0.web Address 1: 10.244.102.22 web-0.web.dev.svc.cluster.local / # nslookup web-1.web Server: 11.244.0.10 Address 1: 11.244.0.10 kube-dns.kube-system.svc.cluster.local Name: web-1.web Address 1: 10.244.112.21 web-1.web.dev.svc.cluster.local Clean up. kubectl delete sts web kubectl delete service httpd-app web kubectl delete deployment httpd-app Service Internal Traffic Policy \u00b6 Scenario Simulate how Service Internal Traffic Policy works. Expected result: With setting Service internalTrafficPolicy: Local , the Service only route internal traffic within the nodes that Pods are running. Backgroud: Service Internal Traffic Policy enables internal traffic restrictions to only route internal traffic to endpoints within the node the traffic originated from. The \"internal\" traffic here refers to traffic originated from Pods in the current cluster. By setting its .spec.internalTrafficPolicy to Local. This tells kube-proxy to only use node local endpoints for cluster internal traffic. For pods on nodes with no endpoints for a given Service, the Service behaves as if it has zero endpoints (for Pods on this node) even if the service does have endpoints on other nodes. Demo: Create Deployment my-nginx and Service my-nginx . kubectl apply -f - << EOF apiVersion: apps/v1 kind: Deployment metadata: name: my-nginx spec: selector: matchLabels: run: my-nginx replicas: 1 template: metadata: labels: run: my-nginx spec: containers: - name: my-nginx image: nginx ports: - containerPort: 80 --- apiVersion: v1 kind: Service metadata: name: my-nginx labels: run: my-nginx spec: ports: - port: 80 protocol: TCP selector: run: my-nginx EOF With command kubectl get pod -o wide , we know the Pod of Deployment my-nginx is running on node cka003 . NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES my-nginx-cf54cdbf7-bscf8 1/1 Running 0 9h 10.244.112.63 cka002 Let's send http request from cka001 to the Pod on cka002 . We will receive Welcome to nginx! information, which means the Pod is accessable from other nodes. curl 11.244.163.60 Let's modify the Serivce my-nginx and specify internalTrafficPolicy: Local . kubectl apply -f - << EOF apiVersion: v1 kind: Service metadata: name: my-nginx labels: run: my-nginx spec: ports: - port: 80 protocol: TCP selector: run: my-nginx internalTrafficPolicy: Local EOF Let's send http request from cka001 to the http request to the Pod again. We will receive curl: (7) Failed to connect to 11.244.163.60 port 80: Connection refused error information. curl 11.244.163.60 Let's log onto cka002 and the http request to the Pod again. We will receive Welcome to nginx! information, curl 11.244.163.60 Conclution With setting Service internalTrafficPolicy: Local , the Service only route internal traffic within the nodes that Pods are running. Scenario *Create a nginx deployment * Add port number and alias name of the nginx Pod. * Expose the deployment with internal traffic to local only. Demo: Create deployment my-nginx with port number 80 . kubectl create deployment my-nginx --image=nginx --port=80 Edit deployment. kubectl edit deployment my-nginx Add port alias name http . Refer to the link for deployment yaml template https://kubernetes.io/docs/concepts/workloads/controllers/deployment/ spec : containers : - image : nginx imagePullPolicy : Always name : nginx ports : - containerPort : 80 protocol : TCP name : http Expose the deployment with NodePort type. kubectl expose deployment my-nginx --port=80 --target-port=http --name=my-nginx-svc --type=NodePort Edit the service. Change internalTrafficPolicy from Cluster to Local . kubectl edit svc my-nginx-svc Verify the access. Note, the pod is running on node cka003 . We will see below expected results. curl :80 # succeed on node cka003. internalTrafficPolicy is effective. curl :80 # succeed on all nodes. curl : # succeed on all nodes.","title":"Service"},{"location":"k8s/cka_en/foundamentals/service/#service","text":"Scenario: Create Deployment httpd-app . Create Service httpd-app with type ClusterIP , which is default type and accessable internally. Verify the access to Pod IP and Service ClusterIP. Update Service httpd-app with type NodePort . No change to the Deployment httpd-app . Verify the access to Node. The access will route to Pod. The service is now accesable from outside. Create Headless Service web and StatefulSet web . Service Internal Traffic Policy","title":"Service"},{"location":"k8s/cka_en/foundamentals/service/#clusterip","text":"","title":"ClusterIP"},{"location":"k8s/cka_en/foundamentals/service/#create-service","text":"Create a Deployment http-app . Create a Service httpd-app link to Development http-app by Label Selector. Service type is ClusterIP , which is default type and accessable internally. kubectl apply -f - < 80/TCP 14s app=httpd NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES pod/httpd-app-6496d888c9-4nb6z 1/1 Running 0 77s 10.244.102.21 cka003 pod/httpd-app-6496d888c9-b7xht 1/1 Running 0 77s 10.244.112.19 cka002 Verify the access to Pod IPs. curl 10.244.102.21 curl 10.244.112.19 And receive below successful information.

It works!

Verify the access via ClusterIP with Port. curl 11.244.247.7:80 And receive below successful information.

It works!

","title":"Create Service"},{"location":"k8s/cka_en/foundamentals/service/#expose-service","text":"Create and attach to a temporary Pod nslookup and to verify DNS resolution. The option --rm means delete the Pod after exit. kubectl run -it nslookup --rm --image=busybox:1.28 After attach to the Pod, run command nslookup httpd-app . We receive the ClusterIP of Service httpd-app and full domain name. / # nslookup httpd-app Server: 11.244.0.10 Address 1: 11.244.0.10 kube-dns.kube-system.svc.cluster.local Name: httpd-app Address 1: 11.244.247.7 httpd-app.dev.svc.cluster.local We can check the IP of temporary Pod nslookup in a new terminal by executing command kubectl get pod -o wide . The Pod nslookup has Pod IP 10.244.112.20 . kubectl get pod nslookup Result NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES nslookup 1/1 Running 0 2m44s 10.244.112.20 cka002 ","title":"Expose Service"},{"location":"k8s/cka_en/foundamentals/service/#nodeport","text":"Create and apply yaml file svc-nodeport.yaml to create a Service httpd-app . kubectl apply -f - < will update configuration to existing resources. Here the Service httpd-app is changed from ClusterIP to NodePort type. No change to the Deployment httpd-app . service/httpd-app configured deployment.apps/httpd-app unchanged Check the Service httpd-app via kubectl get svc . IP is the same. Type is changed to NodePort. Port numbers is changed from 80/TCP to 80:30080/TCP . NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE httpd-app NodePort 11.244.247.7 80:30080/TCP 18m Test the connection to the Service httpd-app via command curl :30080 to each node. curl :30080 curl :30080 curl :30080 We will receive below successful information.

It works!

","title":"NodePort"},{"location":"k8s/cka_en/foundamentals/service/#headless-service","text":"Create Headless Service web and StatefulSet web . kubectl apply -f - < web-1 1/1 Running 0 6s 10.244.112.21 cka002 Get details of the Service by command kubectl describe svc -l app=web . Name: web Namespace: dev Labels: app=web Annotations: Selector: app=web Type: ClusterIP IP Family Policy: SingleStack IP Families: IPv4 IP: None IPs: None Port: web 80/TCP TargetPort: 80/TCP Endpoints: 10.244.102.22:80,10.244.112.21:80 Session Affinity: None Events: Attach to the temporary Pod nslookup and use nslookup to verify DNS resolution. kubectl run -it nslookup --rm --image=busybox:1.28 With nslookup command for Headless Service web , we received two Pod IPs, not ClusterIP due to Headless Service. / # nslookup web Server: 11.244.0.10 Address 1: 11.244.0.10 kube-dns.kube-system.svc.cluster.local Name: web Address 1: 10.244.112.21 web-1.web.dev.svc.cluster.local Address 2: 10.244.102.22 web-0.web.dev.svc.cluster.local We can also use nslookup for web-0.web and web-1.web . Every Pod of Headless Service has own Service Name for DNS lookup. / # nslookup web-0.web Server: 11.244.0.10 Address 1: 11.244.0.10 kube-dns.kube-system.svc.cluster.local Name: web-0.web Address 1: 10.244.102.22 web-0.web.dev.svc.cluster.local / # nslookup web-1.web Server: 11.244.0.10 Address 1: 11.244.0.10 kube-dns.kube-system.svc.cluster.local Name: web-1.web Address 1: 10.244.112.21 web-1.web.dev.svc.cluster.local Clean up. kubectl delete sts web kubectl delete service httpd-app web kubectl delete deployment httpd-app","title":"Headless Service"},{"location":"k8s/cka_en/foundamentals/service/#service-internal-traffic-policy","text":"Scenario Simulate how Service Internal Traffic Policy works. Expected result: With setting Service internalTrafficPolicy: Local , the Service only route internal traffic within the nodes that Pods are running. Backgroud: Service Internal Traffic Policy enables internal traffic restrictions to only route internal traffic to endpoints within the node the traffic originated from. The \"internal\" traffic here refers to traffic originated from Pods in the current cluster. By setting its .spec.internalTrafficPolicy to Local. This tells kube-proxy to only use node local endpoints for cluster internal traffic. For pods on nodes with no endpoints for a given Service, the Service behaves as if it has zero endpoints (for Pods on this node) even if the service does have endpoints on other nodes. Demo: Create Deployment my-nginx and Service my-nginx . kubectl apply -f - << EOF apiVersion: apps/v1 kind: Deployment metadata: name: my-nginx spec: selector: matchLabels: run: my-nginx replicas: 1 template: metadata: labels: run: my-nginx spec: containers: - name: my-nginx image: nginx ports: - containerPort: 80 --- apiVersion: v1 kind: Service metadata: name: my-nginx labels: run: my-nginx spec: ports: - port: 80 protocol: TCP selector: run: my-nginx EOF With command kubectl get pod -o wide , we know the Pod of Deployment my-nginx is running on node cka003 . NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES my-nginx-cf54cdbf7-bscf8 1/1 Running 0 9h 10.244.112.63 cka002 Let's send http request from cka001 to the Pod on cka002 . We will receive Welcome to nginx! information, which means the Pod is accessable from other nodes. curl 11.244.163.60 Let's modify the Serivce my-nginx and specify internalTrafficPolicy: Local . kubectl apply -f - << EOF apiVersion: v1 kind: Service metadata: name: my-nginx labels: run: my-nginx spec: ports: - port: 80 protocol: TCP selector: run: my-nginx internalTrafficPolicy: Local EOF Let's send http request from cka001 to the http request to the Pod again. We will receive curl: (7) Failed to connect to 11.244.163.60 port 80: Connection refused error information. curl 11.244.163.60 Let's log onto cka002 and the http request to the Pod again. We will receive Welcome to nginx! information, curl 11.244.163.60 Conclution With setting Service internalTrafficPolicy: Local , the Service only route internal traffic within the nodes that Pods are running. Scenario *Create a nginx deployment * Add port number and alias name of the nginx Pod. * Expose the deployment with internal traffic to local only. Demo: Create deployment my-nginx with port number 80 . kubectl create deployment my-nginx --image=nginx --port=80 Edit deployment. kubectl edit deployment my-nginx Add port alias name http . Refer to the link for deployment yaml template https://kubernetes.io/docs/concepts/workloads/controllers/deployment/ spec : containers : - image : nginx imagePullPolicy : Always name : nginx ports : - containerPort : 80 protocol : TCP name : http Expose the deployment with NodePort type. kubectl expose deployment my-nginx --port=80 --target-port=http --name=my-nginx-svc --type=NodePort Edit the service. Change internalTrafficPolicy from Cluster to Local . kubectl edit svc my-nginx-svc Verify the access. Note, the pod is running on node cka003 . We will see below expected results. curl :80 # succeed on node cka003. internalTrafficPolicy is effective. curl :80 # succeed on all nodes. curl : # succeed on all nodes.","title":"Service Internal Traffic Policy"},{"location":"k8s/cka_en/foundamentals/statefulset/","text":"StatefulSet \u00b6 Scenario: Create Headless Service nginx and StatefulSet web Scale out StatefulSet web Demo: Create Headless Service nginx and StatefulSet web . kubectl apply -f - << EOF --- apiVersion: v1 kind: Service metadata: name: nginx labels: app: nginx spec: ports: - port: 80 name: web clusterIP: None selector: app: nginx --- apiVersion: apps/v1 kind: StatefulSet metadata: name: web spec: serviceName: \"nginx\" replicas: 2 selector: matchLabels: app: nginx template: metadata: labels: app: nginx spec: containers: - name: nginx image: nginx ports: - containerPort: 80 name: web EOF Get details of StatefulSet Pod created just now. kubectl get pod | grep web Result NAME READY STATUS RESTARTS AGE web-0 1/1 Running 0 27s web-1 1/1 Running 0 10s Use command kubectl edit sts web to update an existing StatefulSet. ONLY these fields can be updated: replicas \u3001 image \u3001 rolling updates \u3001 labels \u3001 resource request/limit and annotations . Note: When StatefulSet Pod is dead in current node, no copies will be created in other node automatically. Scale out StatefulSet. Scale StatefulSet web to 5 Replicas. kubectl scale sts web --replicas=5 Info Partition indicates the ordinal at which the StatefulSet should be partitioned for updates. During a rolling update, all pods from ordinal Replicas-1 to Partition are updated. All pods from ordinal Partition-1 to 0 remain untouched. This is helpful in being able to do a canary based deployment. The default value is 0. Command: kubectl explain statefulsets.spec.updateStrategy.rollingUpdate.partition Clean up. kubectl delete sts web kubectl delete service nginx","title":"StatefulSet"},{"location":"k8s/cka_en/foundamentals/statefulset/#statefulset","text":"Scenario: Create Headless Service nginx and StatefulSet web Scale out StatefulSet web Demo: Create Headless Service nginx and StatefulSet web . kubectl apply -f - << EOF --- apiVersion: v1 kind: Service metadata: name: nginx labels: app: nginx spec: ports: - port: 80 name: web clusterIP: None selector: app: nginx --- apiVersion: apps/v1 kind: StatefulSet metadata: name: web spec: serviceName: \"nginx\" replicas: 2 selector: matchLabels: app: nginx template: metadata: labels: app: nginx spec: containers: - name: nginx image: nginx ports: - containerPort: 80 name: web EOF Get details of StatefulSet Pod created just now. kubectl get pod | grep web Result NAME READY STATUS RESTARTS AGE web-0 1/1 Running 0 27s web-1 1/1 Running 0 10s Use command kubectl edit sts web to update an existing StatefulSet. ONLY these fields can be updated: replicas \u3001 image \u3001 rolling updates \u3001 labels \u3001 resource request/limit and annotations . Note: When StatefulSet Pod is dead in current node, no copies will be created in other node automatically. Scale out StatefulSet. Scale StatefulSet web to 5 Replicas. kubectl scale sts web --replicas=5 Info Partition indicates the ordinal at which the StatefulSet should be partitioned for updates. During a rolling update, all pods from ordinal Replicas-1 to Partition are updated. All pods from ordinal Partition-1 to 0 remain untouched. This is helpful in being able to do a canary based deployment. The default value is 0. Command: kubectl explain statefulsets.spec.updateStrategy.rollingUpdate.partition Clean up. kubectl delete sts web kubectl delete service nginx","title":"StatefulSet"},{"location":"k8s/cka_en/foundamentals/troubleshooting/","text":"Troubleshooting \u00b6 Event \u00b6 Scenario Describe pod to get event information. Demo: Usage: kubectl describe --namespace= Get event information of a Pod Create a Tomcat Pod. kubectl run tomcat --image=tomcat Check event of above deplyment. kubectl describe pod/tomcat Get below event information. Events: Type Reason Age From Message ---- ------ ---- ---- ------- Normal Scheduled 55s default-scheduler Successfully assigned dev/tomcat to cka002 Normal Pulling 54s kubelet Pulling image \"tomcat\" Normal Pulled 21s kubelet Successfully pulled image \"tomcat\" in 33.134162692s Normal Created 19s kubelet Created container tomcat Normal Started 19s kubelet Started container tomcat Get event information for a Namespace. kubectl get events -n Get current default namespace event information. LAST SEEN TYPE REASON OBJECT MESSAGE 70s Warning FailedGetScale horizontalpodautoscaler/nginx deployments/scale.apps \"podinfo\" not found 2m16s Normal Scheduled pod/tomcat Successfully assigned dev/tomcat to cka002 2m15s Normal Pulling pod/tomcat Pulling image \"tomcat\" 102s Normal Pulled pod/tomcat Successfully pulled image \"tomcat\" in 33.134162692s 100s Normal Created pod/tomcat Created container tomcat 100s Normal Started pod/tomcat Started container tomcat Get event information for all Namespace. kubectl get events -A Logs \u00b6 Scenario Get log of pod Usage: kubectl logs -n Options: --tail : display only the most recent lines of output -f : streaming the output Get the most recent 100 lines of output. kubectl logs -f tomcat --tail 100 If it's multipPod, use -c to specify Container. kubectl logs -f tomcat --tail 100 -c tomcat Node Availability \u00b6 Check Available Node \u00b6 Scenario Check node availibility. Demo: Option 1: kubectl describe node | grep -i taint Manual check the result, here it's 2 nodes are available Taints: node-role.kubernetes.io/control-plane:NoSchedule Taints: Taints: Option 2: kubectl describe node | grep -i taint |grep -vc NoSchedule We will get same result 2 . Here -v means exclude, -c count numbers. Node NotReady \u00b6 Scenario: When we stop kubelet service on worker node cka002 , What's the status of each node? What's containers changed via command nerdctl ? What's pods status via command kubectl get pod -owide -A ? Demo: Execute command systemctl stop kubelet.service on cka002 . Execute command kubectl get node on either cka001 or cka003 , the status of cka002 is NotReady . Execute command nerdctl -n k8s.io container ls on cka002 and we can observe all containers are still up and running, including the pod my-first-pod . Execute command systemctl start kubelet.service on cka002 . Conclusion: The node status is changed to NotReady from Ready . For those DaemonSet pods, like calico \u3001 kube-proxy , are exclusively running on each node. They won't be terminated after kubelet is down. The status of pod my-first-pod keeps showing Terminating on each node because status can not be synced to other nodes via apiserver from cka002 because kubelet is down. The status of pod is marked by controller and recycled by kubelet . When we start kubelet service on cka003 , the pod my-first-pod will be termiated completely on cka002 . In addition, let's create a deployment with 3 replicas. Two are running on cka003 and one is running on cka002 . root@cka001:~# kubectl get pod -o wide -w NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES nginx-deployment-9d745469b-2xdk4 1/1 Running 0 2m8s 10.244.2.3 cka003 nginx-deployment-9d745469b-4gvmr 1/1 Running 0 2m8s 10.244.2.4 cka003 nginx-deployment-9d745469b-5j927 1/1 Running 0 2m8s 10.244.1.3 cka002 After we stop kubelet service on cka003 , the two running on cka003 are terminated and another two are created and running on cka002 automatically. Monitoring Indicators \u00b6 Scenario: Get monitoring indicators of pod Demo: Get node monitoring information kubectl top node Output: NAME CPU(cores) CPU% MEMORY(bytes) MEMORY% cka001 147m 7% 1940Mi 50% cka002 62m 3% 2151Mi 56% cka003 63m 3% 1825Mi 47% Get Pod monitoring information kubectl top pod Output: root@cka001:~# kubectl top pod NAME CPU(cores) MEMORY(bytes) busybox-with-secret 0m 0Mi mysql 2m 366Mi mysql-774db46945-sztrp 2m 349Mi mysql-nodeselector-6b7d9c875d-227t6 2m 365Mi mysql-tolerations-5c5986944b-cg9bs 2m 366Mi mysql-with-sc-pvc-7c97d875f8-dwfkc 2m 349Mi nfs-client-provisioner-699db7fd58-bccqs 2m 7Mi nginx 0m 3Mi nginx-app-1-695b7b647d-l76bh 0m 3Mi nginx-app-2-7f6bf6f4d4-lvbz8 0m 3Mi nginx-nodename 0m 3Mi nginx-with-cm 0m 3Mi pod-configmap-env 0m 3Mi pod-configmap-env-2 0m 3Mi tomcat 1m 58Mi Sort output by CPU or Memory using option --sort-by , the field can be either 'cpu' or 'memory'. kubectl top pod --sort-by=cpu kubectl top pod --sort-by=memory Output: NAME CPU(cores) MEMORY(bytes) nfs-client-provisioner-699db7fd58-bccqs 2m 7Mi mysql 2m 366Mi mysql-774db46945-sztrp 2m 349Mi mysql-nodeselector-6b7d9c875d-227t6 2m 365Mi mysql-tolerations-5c5986944b-cg9bs 2m 366Mi mysql-with-sc-pvc-7c97d875f8-dwfkc 2m 349Mi tomcat 1m 58Mi nginx 0m 3Mi nginx-app-1-695b7b647d-l76bh 0m 3Mi nginx-app-2-7f6bf6f4d4-lvbz8 0m 3Mi nginx-nodename 0m 3Mi nginx-with-cm 0m 3Mi pod-configmap-env 0m 3Mi pod-configmap-env-2 0m 3Mi busybox-with-secret 0m 0Mi Node Eviction \u00b6 Cordon/Uncordon \u00b6 Scenario Scheduling for a node Demo: Disable scheduling for a Node. kubectl cordon Example: kubectl cordon cka003 Node status: NAME STATUS ROLES AGE VERSION cka001 Ready control-plane,master 18d v1.24.0 cka002 Ready 18d v1.24.0 cka003 Ready,SchedulingDisabled 18d v1.24.0 Enable scheduling for a Node. kubectl uncordon Example: kubectl uncordon cka003 Node status: NAME STATUS ROLES AGE VERSION cka001 Ready control-plane,master 18d v1.24.0 cka002 Ready 18d v1.24.0 cka003 Ready 18d v1.24.0 Drain Node \u00b6 Scenario Drain the node cka003 Demo: Get list of Pods running. kubectl get pod -o wide We know that a Pod is running on cka003 . NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES nfs-client-provisioner-86d7fb78b6-xk8nw 1/1 Running 0 22h 10.244.102.3 cka003 Evict node cka003 . kubectl drain cka003 --ignore-daemonsets --delete-emptydir-data --force Output looks like below. node/cka003 cordoned WARNING: ignoring DaemonSet-managed Pods: kube-system/calico-node-tr22l, kube-system/kube-proxy-g76kg evicting pod dev/nfs-client-provisioner-86d7fb78b6-xk8nw evicting pod cka/cka-demo-64f88f7f46-dkxmk pod/nfs-client-provisioner-86d7fb78b6-xk8nw evicted pod/cka-demo-64f88f7f46-dkxmk evicted node/cka003 drained Check pod status again. kubectl get pod -o wide The pod is running on cka002 now. NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES nfs-client-provisioner-86d7fb78b6-k8xnl 1/1 Running 0 2m20s 10.244.112.4 cka002 Note cordon is included in drain , no need additional step to cordon node before drain node.","title":"Troubleshooting"},{"location":"k8s/cka_en/foundamentals/troubleshooting/#troubleshooting","text":"","title":"Troubleshooting"},{"location":"k8s/cka_en/foundamentals/troubleshooting/#event","text":"Scenario Describe pod to get event information. Demo: Usage: kubectl describe --namespace= Get event information of a Pod Create a Tomcat Pod. kubectl run tomcat --image=tomcat Check event of above deplyment. kubectl describe pod/tomcat Get below event information. Events: Type Reason Age From Message ---- ------ ---- ---- ------- Normal Scheduled 55s default-scheduler Successfully assigned dev/tomcat to cka002 Normal Pulling 54s kubelet Pulling image \"tomcat\" Normal Pulled 21s kubelet Successfully pulled image \"tomcat\" in 33.134162692s Normal Created 19s kubelet Created container tomcat Normal Started 19s kubelet Started container tomcat Get event information for a Namespace. kubectl get events -n Get current default namespace event information. LAST SEEN TYPE REASON OBJECT MESSAGE 70s Warning FailedGetScale horizontalpodautoscaler/nginx deployments/scale.apps \"podinfo\" not found 2m16s Normal Scheduled pod/tomcat Successfully assigned dev/tomcat to cka002 2m15s Normal Pulling pod/tomcat Pulling image \"tomcat\" 102s Normal Pulled pod/tomcat Successfully pulled image \"tomcat\" in 33.134162692s 100s Normal Created pod/tomcat Created container tomcat 100s Normal Started pod/tomcat Started container tomcat Get event information for all Namespace. kubectl get events -A","title":"Event"},{"location":"k8s/cka_en/foundamentals/troubleshooting/#logs","text":"Scenario Get log of pod Usage: kubectl logs -n Options: --tail : display only the most recent lines of output -f : streaming the output Get the most recent 100 lines of output. kubectl logs -f tomcat --tail 100 If it's multipPod, use -c to specify Container. kubectl logs -f tomcat --tail 100 -c tomcat","title":"Logs"},{"location":"k8s/cka_en/foundamentals/troubleshooting/#node-availability","text":"","title":"Node Availability"},{"location":"k8s/cka_en/foundamentals/troubleshooting/#check-available-node","text":"Scenario Check node availibility. Demo: Option 1: kubectl describe node | grep -i taint Manual check the result, here it's 2 nodes are available Taints: node-role.kubernetes.io/control-plane:NoSchedule Taints: Taints: Option 2: kubectl describe node | grep -i taint |grep -vc NoSchedule We will get same result 2 . Here -v means exclude, -c count numbers.","title":"Check Available Node"},{"location":"k8s/cka_en/foundamentals/troubleshooting/#node-notready","text":"Scenario: When we stop kubelet service on worker node cka002 , What's the status of each node? What's containers changed via command nerdctl ? What's pods status via command kubectl get pod -owide -A ? Demo: Execute command systemctl stop kubelet.service on cka002 . Execute command kubectl get node on either cka001 or cka003 , the status of cka002 is NotReady . Execute command nerdctl -n k8s.io container ls on cka002 and we can observe all containers are still up and running, including the pod my-first-pod . Execute command systemctl start kubelet.service on cka002 . Conclusion: The node status is changed to NotReady from Ready . For those DaemonSet pods, like calico \u3001 kube-proxy , are exclusively running on each node. They won't be terminated after kubelet is down. The status of pod my-first-pod keeps showing Terminating on each node because status can not be synced to other nodes via apiserver from cka002 because kubelet is down. The status of pod is marked by controller and recycled by kubelet . When we start kubelet service on cka003 , the pod my-first-pod will be termiated completely on cka002 . In addition, let's create a deployment with 3 replicas. Two are running on cka003 and one is running on cka002 . root@cka001:~# kubectl get pod -o wide -w NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES nginx-deployment-9d745469b-2xdk4 1/1 Running 0 2m8s 10.244.2.3 cka003 nginx-deployment-9d745469b-4gvmr 1/1 Running 0 2m8s 10.244.2.4 cka003 nginx-deployment-9d745469b-5j927 1/1 Running 0 2m8s 10.244.1.3 cka002 After we stop kubelet service on cka003 , the two running on cka003 are terminated and another two are created and running on cka002 automatically.","title":"Node NotReady"},{"location":"k8s/cka_en/foundamentals/troubleshooting/#monitoring-indicators","text":"Scenario: Get monitoring indicators of pod Demo: Get node monitoring information kubectl top node Output: NAME CPU(cores) CPU% MEMORY(bytes) MEMORY% cka001 147m 7% 1940Mi 50% cka002 62m 3% 2151Mi 56% cka003 63m 3% 1825Mi 47% Get Pod monitoring information kubectl top pod Output: root@cka001:~# kubectl top pod NAME CPU(cores) MEMORY(bytes) busybox-with-secret 0m 0Mi mysql 2m 366Mi mysql-774db46945-sztrp 2m 349Mi mysql-nodeselector-6b7d9c875d-227t6 2m 365Mi mysql-tolerations-5c5986944b-cg9bs 2m 366Mi mysql-with-sc-pvc-7c97d875f8-dwfkc 2m 349Mi nfs-client-provisioner-699db7fd58-bccqs 2m 7Mi nginx 0m 3Mi nginx-app-1-695b7b647d-l76bh 0m 3Mi nginx-app-2-7f6bf6f4d4-lvbz8 0m 3Mi nginx-nodename 0m 3Mi nginx-with-cm 0m 3Mi pod-configmap-env 0m 3Mi pod-configmap-env-2 0m 3Mi tomcat 1m 58Mi Sort output by CPU or Memory using option --sort-by , the field can be either 'cpu' or 'memory'. kubectl top pod --sort-by=cpu kubectl top pod --sort-by=memory Output: NAME CPU(cores) MEMORY(bytes) nfs-client-provisioner-699db7fd58-bccqs 2m 7Mi mysql 2m 366Mi mysql-774db46945-sztrp 2m 349Mi mysql-nodeselector-6b7d9c875d-227t6 2m 365Mi mysql-tolerations-5c5986944b-cg9bs 2m 366Mi mysql-with-sc-pvc-7c97d875f8-dwfkc 2m 349Mi tomcat 1m 58Mi nginx 0m 3Mi nginx-app-1-695b7b647d-l76bh 0m 3Mi nginx-app-2-7f6bf6f4d4-lvbz8 0m 3Mi nginx-nodename 0m 3Mi nginx-with-cm 0m 3Mi pod-configmap-env 0m 3Mi pod-configmap-env-2 0m 3Mi busybox-with-secret 0m 0Mi","title":"Monitoring Indicators"},{"location":"k8s/cka_en/foundamentals/troubleshooting/#node-eviction","text":"","title":"Node Eviction"},{"location":"k8s/cka_en/foundamentals/troubleshooting/#cordonuncordon","text":"Scenario Scheduling for a node Demo: Disable scheduling for a Node. kubectl cordon Example: kubectl cordon cka003 Node status: NAME STATUS ROLES AGE VERSION cka001 Ready control-plane,master 18d v1.24.0 cka002 Ready 18d v1.24.0 cka003 Ready,SchedulingDisabled 18d v1.24.0 Enable scheduling for a Node. kubectl uncordon Example: kubectl uncordon cka003 Node status: NAME STATUS ROLES AGE VERSION cka001 Ready control-plane,master 18d v1.24.0 cka002 Ready 18d v1.24.0 cka003 Ready 18d v1.24.0","title":"Cordon/Uncordon"},{"location":"k8s/cka_en/foundamentals/troubleshooting/#drain-node","text":"Scenario Drain the node cka003 Demo: Get list of Pods running. kubectl get pod -o wide We know that a Pod is running on cka003 . NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES nfs-client-provisioner-86d7fb78b6-xk8nw 1/1 Running 0 22h 10.244.102.3 cka003 Evict node cka003 . kubectl drain cka003 --ignore-daemonsets --delete-emptydir-data --force Output looks like below. node/cka003 cordoned WARNING: ignoring DaemonSet-managed Pods: kube-system/calico-node-tr22l, kube-system/kube-proxy-g76kg evicting pod dev/nfs-client-provisioner-86d7fb78b6-xk8nw evicting pod cka/cka-demo-64f88f7f46-dkxmk pod/nfs-client-provisioner-86d7fb78b6-xk8nw evicted pod/cka-demo-64f88f7f46-dkxmk evicted node/cka003 drained Check pod status again. kubectl get pod -o wide The pod is running on cka002 now. NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES nfs-client-provisioner-86d7fb78b6-k8xnl 1/1 Running 0 2m20s 10.244.112.4 cka002 Note cordon is included in drain , no need additional step to cordon node before drain node.","title":"Drain Node"},{"location":"k8s/cka_en/installation/aliyun-ubuntu/","text":"Installation on Aliyun Ubuntu \u00b6 Preparation \u00b6 Register Aliyun account via Alibaba Cloud home console . Request three Elastic Computer Service(ECS) instances with below sizing: System: 2vCPU+4GiB OS: Ubuntu 20.04 x86_64 Instance Type: ecs.sn1.medium Instance Name: cka001, cka002, cka003 Network: both public IPs and private IPs Maximum Bandwidth: 100Mbps (Peak Value) Cloud disk: 40GiB Billing Method: Preemptible instance (spot price) Open a local terminal, log onto remote ECS cka001 using the key pair (e.g., aliyun-root ) from Aliyun cloud. ssh -i aliyun-root root@cka001 Create a common user (e.g., james ), and set primary group as sudo and other group as root . adduser james usermod -g sudo james usermod -a -G root james Back to the local terminal, generate key for common user james by below command. # Windows ssh-keygen.exe # Linux ssh-keygen Two files will be created, e.g., aliyun-james and aliyun-james.pub Upload the public key aliyun-james.pub to remote cka001 using sftp command. sftp -i aliyun-root root@cka001 put aliyun-james.pub Log onto remote ECS cka001 using root account again. Move the key aliyun-james.pub to /home/james/.ssh/ . Rename file aliyun-james.pub to authorized_keys . Change ower of file authorized_keys to james . Change default group of file authorized_keys to sudo . mkdir /home/james/.ssh/ mv aliyun-james.pub /home/james/.ssh/authorized_keys chown james.sudo /home/james/.ssh/authorized_keys chmod 600 /home/james/.ssh/authorized_keys Check file /etc/ssh/sshd_config , make sure password authentication is disabled PasswordAuthentication no cat /etc/ssh/sshd_config Back to the local terminal, use james to log onto remote cka001 . ssh -i aliyun-james james@cka001 Upload the public key aliyun-james.pub to remote cka002 and cka003 using sftp command and do the same set up on cka002 and cka003 in order to enable user james to log onto cka002 and cka003 . Till now, user james can log onto cka001 , cka002 and cka003 using key aliyun-james . All demo below will be done by user james . Initialize VMs \u00b6 Configure /etc/hosts file \u00b6 Add private IPs in the /etc/hosts file in all VMs. vi /etc/hosts Disable firewall \u00b6 Disable firewall by command ufw disable in all VMs. Disable swap on Ubuntu. sudo ufw disable Check status of swap on Ubuntu. sudo ufw status verbose Turn off swap \u00b6 Turn off swap in all VMs. sudo swapoff -a Set timezone and locale \u00b6 Set timezone and local for all VMs. This step was already done during Aliyun ECS installation. ln -sf /usr/share/zoneinfo/Asia/Shanghai /etc/localtime sudo echo 'LANG=\"en_US.UTF-8\"' >> /etc/profile source /etc/profile Something like this: ll /etc/localtime lrwxrwxrwx 1 root root 33 Jul 5 14 :51 /etc/localtime -> /usr/share/zoneinfo/Asia/Shanghai Kernel setting \u00b6 Perform below kernel setting in all VMs. Create file /etc/modules-load.d/containerd.conf to set up containerd configure file. It's to load two modules overlay and br_netfilter . Service containerd depends on overlay filesystem. Sometimes referred to as union-filesystems. An overlay-filesystem tries to present a filesystem which is the result over overlaying one filesystem on top of the other. The br_netfilter module is required to enable transparent masquerading and to facilitate Virtual Extensible LAN (VxLAN) traffic for communication between Kubernetes pods across the cluster. cat < /etc/apt/sources.list << EOF deb http://mirrors.cloud.aliyuncs.com/ubuntu/ focal main restricted deb-src http://mirrors.cloud.aliyuncs.com/ubuntu/ focal main restricted deb http://mirrors.cloud.aliyuncs.com/ubuntu/ focal-updates main restricted deb-src http://mirrors.cloud.aliyuncs.com/ubuntu/ focal-updates main restricted deb http://mirrors.cloud.aliyuncs.com/ubuntu/ focal universe deb-src http://mirrors.cloud.aliyuncs.com/ubuntu/ focal universe deb http://mirrors.cloud.aliyuncs.com/ubuntu/ focal-updates universe deb-src http://mirrors.cloud.aliyuncs.com/ubuntu/ focal-updates universe deb http://mirrors.cloud.aliyuncs.com/ubuntu/ focal multiverse deb-src http://mirrors.cloud.aliyuncs.com/ubuntu/ focal multiverse deb http://mirrors.cloud.aliyuncs.com/ubuntu/ focal-updates multiverse deb-src http://mirrors.cloud.aliyuncs.com/ubuntu/ focal-updates multiverse deb http://mirrors.cloud.aliyuncs.com/ubuntu/ focal-backports main restricted universe multiverse deb-src http://mirrors.cloud.aliyuncs.com/ubuntu/ focal-backports main restricted universe multivers deb http://mirrors.cloud.aliyuncs.com/ubuntu focal-security main restricted deb-src http://mirrors.cloud.aliyuncs.com/ubuntu focal-security main restricted deb http://mirrors.cloud.aliyuncs.com/ubuntu focal-security universe deb-src http://mirrors.cloud.aliyuncs.com/ubuntu focal-security universe # deb http://mirrors.cloud.aliyuncs.com/ubuntu focal-security multiverse # deb-src http://mirrors.cloud.aliyuncs.com/ubuntu focal-security multiverse EOF Install Containered. sudo apt-get update && sudo apt-get install -y containerd Configure Containerd. Modify file /etc/containerd/config.toml . sudo mkdir -p /etc/containerd containerd config default | sudo tee /etc/containerd/config.toml sudo vi /etc/containerd/config.toml Update sandbox_image with new value \"registry.aliyuncs.com/google_containers/pause:3.6\" . Update SystemdCgroup with new value true . [plugins] [plugins.\"io.containerd.gc.v1.scheduler\"] [plugins.\"io.containerd.grpc.v1.cri\"] sandbox_image = \"registry.aliyuncs.com/google_containers/pause:3.6\" [plugins.\"io.containerd.grpc.v1.cri\".cni] [plugins.\"io.containerd.grpc.v1.cri\".containerd] [plugins.\"io.containerd.grpc.v1.cri\".containerd.default_runtime] [plugins.\"io.containerd.grpc.v1.cri\".containerd.default_runtime.options] [plugins.\"io.containerd.grpc.v1.cri\".containerd.runtimes] [plugins.\"io.containerd.grpc.v1.cri\".containerd.runtimes.runc] [plugins.\"io.containerd.grpc.v1.cri\".containerd.runtimes.runc.options] SystemdCgroup = true Restart Containerd service. sudo systemctl restart containerd sudo systemctl status containerd Install nerdctl \u00b6 Install nerdctl sevice fro all VMs. The goal of nerdctl is to facilitate experimenting the cutting-edge features of containerd that are not present in Docker. Get the release from the link https://github.com/containerd/nerdctl/releases . wget https://github.com/containerd/nerdctl/releases/download/v0.22.0/nerdctl-0.22.0-linux-amd64.tar.gz tar -zxvf nerdctl-0.22.0-linux-amd64.tar.gz sudo cp nerdctl /usr/bin/ sudo cp containerd-rootless* /usr/bin/ Verify nerdctl. nerdctl --help To list local Kubernetes containers. nerdctl -n k8s.io ps Install kubeadm \u00b6 Update apt-transport-https , ca-certificates , and curl . sudo apt-get update && sudo apt-get install -y apt-transport-https ca-certificates curl Install gpg certificate. sudo curl -fsSLo /usr/share/keyrings/kubernetes-archive-keyring.gpg https://mirrors.aliyun.com/kubernetes/apt/doc/apt-key.gpg Add Kubernetes repo. Just choose one of below command and execute. echo \"deb [signed-by=/usr/share/keyrings/kubernetes-archive-keyring.gpg] https://mirrors.aliyun.com/kubernetes/apt/ \\ kubernetes-xenial main\" | sudo tee /etc/apt/sources.list.d/kubernetes.list Update and install dependencied packages. sudo apt-get update sudo apt-get install ebtables sudo apt-get install libxtables12 sudo apt-get upgrade iptables Check available versions of kubeadm. apt policy kubeadm Install 1.24.0-00 version of kubeadm and will upgrade to 1.24.2 later. sudo apt-get -y install kubelet = 1 .24.0-00 kubeadm = 1 .24.0-00 kubectl = 1 .24.0-00 --allow-downgrades Setup Master Node \u00b6 kubeadm init \u00b6 Set up Control Plane on VM playing master node. Check kubeadm default parameters for initialization. kubeadm config print init-defaults Reuslt: apiVersion : kubeadm.k8s.io/v1beta3 bootstrapTokens : - groups : - system:bootstrappers:kubeadm:default-node-token token : abcdef.0123456789abcdef ttl : 24h0m0s usages : - signing - authentication kind : InitConfiguration localAPIEndpoint : advertiseAddress : 1.2.3.4 bindPort : 6443 nodeRegistration : criSocket : unix:///var/run/containerd/containerd.sock imagePullPolicy : IfNotPresent name : node taints : null --- apiServer : timeoutForControlPlane : 4m0s apiVersion : kubeadm.k8s.io/v1beta3 certificatesDir : /etc/kubernetes/pki clusterName : kubernetes controllerManager : {} dns : {} etcd : local : dataDir : /var/lib/etcd imageRepository : k8s.gcr.io kind : ClusterConfiguration kubernetesVersion : 1.24.0 networking : dnsDomain : cluster.local serviceSubnet : 10.96.0.0/12 scheduler : {} Dry rune and run. Save the output, which will be used later on work nodes. With kubeadm init to initiate cluster, we need understand below three options about network. --pod-network-cidr : Specify range of IP addresses for the pod network. If set, the control plane will automatically allocate CIDRs for every node. Be noted that 10.244.0.0/16 is default range of flannel. If it's changed here, please do change the same when deploy Flannel . --apiserver-bind-port : Port for the API Server to bind to. (default 6443) --service-cidr : Use alternative range of IP address for service VIPs. (default \"10.96.0.0/12\") Note: service VIPs (a.k.a. Cluster IP), specified by option --service-cidr . podCIDR (a.k.a. endpoint IP)\uff0cspecified by option --pod-network-cidr . There are 4 distinct networking problems to address: Highly-coupled container-to-container communications: this is solved by Pods (podCIDR) and localhost communications. Pod-to-Pod communications: a.k.a. container-to-container. Example with Flannel, the flow is: Pod \u2192 veth pair \u2192 cni0 \u2192 flannel.1 \u2192 host eth0 \u2192 host eth0 \u2192 flannel.1 \u2192 cni0 \u2192 veth pair \u2192 Pod. Pod-to-Service communications: Flow: Pod \u2192 Kernel \u2192 Servive iptables \u2192 service \u2192 Pod iptables \u2192 Pod External-to-Service communications: LoadBalancer: SLB \u2192 NodePort \u2192 Service \u2192 Pod kube-proxy is responsible for iptables, not traffic. sudo kubeadm init \\ --dry-run \\ --pod-network-cidr = 10 .244.0.0/16 \\ --service-cidr 11 .244.0.0/16 \\ --image-repository = registry.aliyuncs.com/google_containers \\ --kubernetes-version = v1.24.0 sudo kubeadm init \\ --pod-network-cidr = 10 .244.0.0/16 \\ --service-cidr 11 .244.0.0/16 \\ --image-repository = registry.aliyuncs.com/google_containers \\ --kubernetes-version = v1.24.0 sudo kubeadm init \\ --pod-network-cidr = 10 .244.0.0/16 \\ --service-cidr 11 .244.0.0/16 \\ --kubernetes-version = v1.24.0 kubeconfig file \u00b6 Set kubeconfig file for current user (here it's james ). mkdir -p $HOME /.kube sudo cp -i /etc/kubernetes/admin.conf $HOME /.kube/config sudo chown $( id -u ) : $( id -g ) $HOME /.kube/config Kubernetes provides a command line tool kubectl for communicating with a Kubernetes cluster's control plane, using the Kubernetes API. kubectl controls the Kubernetes cluster manager . For configuration, kubectl looks for a file named config in the $HOME/.kube directory, which is a copy of file /etc/kubernetes/admin.conf generated by kubeadm init . We can specify other kubeconfig files by setting the KUBECONFIG environment variable or by setting the --kubeconfig flag . If the KUBECONFIG environment variable doesn't exist, kubectl uses the default kubeconfig file, $HOME/.kube/config . A context element in a kubeconfig file is used to group access parameters under a convenient name. Each context has three parameters: cluster, namespace, and user. By default, the kubectl command-line tool uses parameters from the current context to communicate with the cluster. A sample of .kube/config . apiVersion : v1 clusters : - cluster : certificate-authority-data : server : https://:6443 name : contexts : - context : cluster : namespace : user : name : @ current-context : kind : Config preferences : {} users : - name : user : client-certificate-data : client-key-data : To get the current context: kubectl config get-contexts Result CURRENT NAME CLUSTER AUTHINFO NAMESPACE * kubernetes-admin@kubernetes kubernetes kubernetes-admin Setup Work Nodes \u00b6 Perform on all VMs playing work nodes. # kubeadm join :6443 --token --discovery-token-ca-cert-hash Use kubeadm token to generate the join token and hash value. kubeadm token create --print-join-command Execute the command generated above on each node that we want to join the cluster as Worker node. Verify status on master node. All nodes' status is NotReady . Leave it at the moment and continue to install network plugin. kubectl get node -o wide Install Calico or Flannel \u00b6 Choose Calico or Flannel on control plane node. For NetworkPolicy purpose, choose Calico. Install Flannel \u00b6 Flannel is a simple and easy way to configure a layer 3 network fabric designed for Kubernetes. Deploy Flannel. In the kube-flannel.yml we can get the default network setting of Flannel, which is same with --pod-network-cidr=10.244.0.0/16 we defined before when we initiated kubeadm . net-conf.json : | { \"Network\": \"10.244.0.0/16\", \"Backend\": { \"Type\": \"vxlan\" } } Create Flannel apply -f https://raw.githubusercontent.com/coreos/flannel/master/Documentation/kube-flannel.yml Result Warning: policy/v1beta1 PodSecurityPolicy is deprecated in v1.21+, unavailable in v1.25+ podsecuritypolicy.policy/psp.flannel.unprivileged created clusterrole.rbac.authorization.k8s.io/flannel created clusterrolebinding.rbac.authorization.k8s.io/flannel created serviceaccount/flannel created configmap/kube-flannel-cfg created daemonset.apps/kube-flannel-ds created Install Calico \u00b6 Here is guidance of End-to-end Calico installation . Detail practice demo, can be found in section \"Install Calico\" of \"A1.Discussion\" below. Install Calico curl https://docs.projectcalico.org/manifests/calico.yaml -O kubectl apply -f calico.yaml Result configmap/calico-config created customresourcedefinition.apiextensions.k8s.io/bgpconfigurations.crd.projectcalico.org created customresourcedefinition.apiextensions.k8s.io/bgppeers.crd.projectcalico.org created customresourcedefinition.apiextensions.k8s.io/blockaffinities.crd.projectcalico.org created customresourcedefinition.apiextensions.k8s.io/caliconodestatuses.crd.projectcalico.org created customresourcedefinition.apiextensions.k8s.io/clusterinformations.crd.projectcalico.org created customresourcedefinition.apiextensions.k8s.io/felixconfigurations.crd.projectcalico.org created customresourcedefinition.apiextensions.k8s.io/globalnetworkpolicies.crd.projectcalico.org created customresourcedefinition.apiextensions.k8s.io/globalnetworksets.crd.projectcalico.org created customresourcedefinition.apiextensions.k8s.io/hostendpoints.crd.projectcalico.org created customresourcedefinition.apiextensions.k8s.io/ipamblocks.crd.projectcalico.org created customresourcedefinition.apiextensions.k8s.io/ipamconfigs.crd.projectcalico.org created customresourcedefinition.apiextensions.k8s.io/ipamhandles.crd.projectcalico.org created customresourcedefinition.apiextensions.k8s.io/ippools.crd.projectcalico.org created customresourcedefinition.apiextensions.k8s.io/ipreservations.crd.projectcalico.org created customresourcedefinition.apiextensions.k8s.io/kubecontrollersconfigurations.crd.projectcalico.org created customresourcedefinition.apiextensions.k8s.io/networkpolicies.crd.projectcalico.org created customresourcedefinition.apiextensions.k8s.io/networksets.crd.projectcalico.org created clusterrole.rbac.authorization.k8s.io/calico-kube-controllers created clusterrolebinding.rbac.authorization.k8s.io/calico-kube-controllers created clusterrole.rbac.authorization.k8s.io/calico-node created clusterrolebinding.rbac.authorization.k8s.io/calico-node created daemonset.apps/calico-node created serviceaccount/calico-node created deployment.apps/calico-kube-controllers created serviceaccount/calico-kube-controllers created poddisruptionbudget.policy/calico-kube-controllers created Verify status of Calico. kubectl get pod -n kube-system | grep calico Result calico-kube-controllers-555bc4b957-l8bn2 0/1 Pending 0 28s calico-node-255pc 0/1 Init:1/3 0 29s calico-node-7tmnb 0/1 Init:1/3 0 29s calico-node-w8nvl 0/1 Init:1/3 0 29s Verify network status. sudo nerdctl network ls Result NETWORK ID NAME FILE k8s-pod-network /etc/cni/net.d/10-calico.conflist 0 bridge /etc/cni/net.d/nerdctl-bridge.conflist host none Check Cluster Status \u00b6 Perform kubectl cluster-info command on master node we will get below information. Kubernetes control plane is running at https://:6443 CoreDNS is running at https://:6443/api/v1/namespaces/kube-system/services/kube-dns:dns/proxy kubectl cluster-info Get nodes status. kubectl get nodes -owide All nodes are up with normal status. OS Image: Ubuntu 20.04.4 LTS Kernel Version: 5.4.0-122-generic Container Runtime: containerd://1.5.9 NAME STATUS ROLES AGE VERSION cka001 Ready control-plane 13m v1.24.0 cka002 Ready 8m35s v1.24.0 cka003 Ready 8m26s v1.24.0 Get pods status kubectl get pod -A Result: NAMESPACE NAME READY STATUS RESTARTS AGE kube-system calico-kube-controllers-555bc4b957-l8bn2 1/1 Running 0 7m18s kube-system calico-node-255pc 1/1 Running 0 7m19s kube-system calico-node-7tmnb 1/1 Running 0 7m19s kube-system calico-node-w8nvl 1/1 Running 0 7m19s kube-system coredns-74586cf9b6-4jwmk 1/1 Running 0 15m kube-system coredns-74586cf9b6-c5mll 1/1 Running 0 15m kube-system etcd-cka001 1/1 Running 0 15m kube-system kube-apiserver-cka001 1/1 Running 0 15m kube-system kube-controller-manager-cka001 1/1 Running 0 15m kube-system kube-proxy-dmj2t 1/1 Running 0 15m kube-system kube-proxy-n77zw 1/1 Running 0 11m kube-system kube-proxy-qs6rf 1/1 Running 0 11m kube-system kube-scheduler-cka001 1/1 Running 0 15m Reset cluster \u00b6 CAUTION: below steps will destroy current cluster. Delete all nodes in the cluster. kubeadm reset Output: [reset] Reading configuration from the cluster... [reset] FYI: You can look at this config file with 'kubectl -n kube-system get cm kubeadm-config -o yaml' W0717 08:15:17.411992 3913615 preflight.go:55] [reset] WARNING: Changes made to this host by 'kubeadm init' or 'kubeadm join' will be reverted. [reset] Are you sure you want to proceed? [y/N]: y [preflight] Running pre-flight checks [reset] Stopping the kubelet service [reset] Unmounting mounted directories in \"/var/lib/kubelet\" [reset] Deleting contents of directories: [/etc/kubernetes/manifests /etc/kubernetes/pki] [reset] Deleting files: [/etc/kubernetes/admin.conf /etc/kubernetes/kubelet.conf /etc/kubernetes/bootstrap-kubelet.conf /etc/kubernetes/controller-manager.conf /etc/kubernetes/scheduler.conf] [reset] Deleting contents of stateful directories: [/var/lib/etcd /var/lib/kubelet /var/lib/dockershim /var/run/kubernetes /var/lib/cni] The reset process does not clean CNI configuration. To do so, you must remove /etc/cni/net.d The reset process does not reset or clean up iptables rules or IPVS tables. If you wish to reset iptables, you must do so manually by using the \"iptables\" command. If your cluster was setup to utilize IPVS, run ipvsadm --clear (or similar) to reset your system's IPVS tables. The reset process does not clean your kubeconfig files and you must remove them manually. Please, check the contents of the $HOME/.kube/config file. Clean up network setting rm -rf /var/run/flannel /opt/cni /etc/cni /var/lib/cni Clean up rule of iptables . iptables -F && iptables -t nat -F && iptables -t mangle -F && iptables -X Clean up rule of IPVS if using IPVS . ipvsadm --clear Troubleshooting \u00b6 Issue 1 \u00b6 The connection to the server :6443 was refused - did you specify the right host or port? Try : Reference Check if the kubeconfig file is update to udpate and exists in right place. Check environment setting. env | grep -i kub Check container status. sudo systemctl status containerd.service Check kubelet service. sudo systemctl status kubelet.service Check port listening status. netstat -pnlt | grep 6443 Check firewall status. sudo systemctl status firewalld.service Check log. journalctl -xeu kubelet Issue 2 \u00b6 \"Container runtime network not ready\" networkReady=\"NetworkReady=false reason:NetworkPluginNotReady message:Network plugin returns error: cni plugin not initialized\" Try : Restart Containerd service. sudo systemctl restart containerd sudo systemctl status containerd Post Installation \u00b6 Bash Autocomplete \u00b6 On each node. Set kubectl auto-completion following the guideline . apt install -y bash-completion source /usr/share/bash-completion/bash_completion source < ( kubectl completion bash ) echo \"source <(kubectl completion bash)\" >> ~/.bashrc Alias \u00b6 If we set an alias for kubectl, we can extend shell completion to work with that alias: echo 'alias k=kubectl' >>~/.bashrc echo 'complete -o default -F __start_kubectl k' >>~/.bashrc Update Default Context \u00b6 Get current context. kubectl config get-contexts In below result, we know: Contenxt name is kubernetes-admin@kubernetes . Cluster name is kubernetes . User is kubernetes-admin . No namespace explicitly defined. CURRENT NAME CLUSTER AUTHINFO NAMESPACE * kubernetes-admin@kubernetes kubernetes kubernetes-admin To set a context with new update, e.g, update default namespace, etc.. # Usage: kubectl config set-context --cluster = --namespace = --user = # Set default namespace kubectl config set-context kubernetes-admin@kubernetes --cluster = kubernetes --namespace = default --user = kubernetes-admin To switch to a new context. kubectl config use-context kubectl config use-context kubernetes-admin@kubernetes Reference of kubectl and commandline .","title":"Installation on Aliyun ECS"},{"location":"k8s/cka_en/installation/aliyun-ubuntu/#installation-on-aliyun-ubuntu","text":"","title":"Installation on Aliyun Ubuntu"},{"location":"k8s/cka_en/installation/aliyun-ubuntu/#preparation","text":"Register Aliyun account via Alibaba Cloud home console . Request three Elastic Computer Service(ECS) instances with below sizing: System: 2vCPU+4GiB OS: Ubuntu 20.04 x86_64 Instance Type: ecs.sn1.medium Instance Name: cka001, cka002, cka003 Network: both public IPs and private IPs Maximum Bandwidth: 100Mbps (Peak Value) Cloud disk: 40GiB Billing Method: Preemptible instance (spot price) Open a local terminal, log onto remote ECS cka001 using the key pair (e.g., aliyun-root ) from Aliyun cloud. ssh -i aliyun-root root@cka001 Create a common user (e.g., james ), and set primary group as sudo and other group as root . adduser james usermod -g sudo james usermod -a -G root james Back to the local terminal, generate key for common user james by below command. # Windows ssh-keygen.exe # Linux ssh-keygen Two files will be created, e.g., aliyun-james and aliyun-james.pub Upload the public key aliyun-james.pub to remote cka001 using sftp command. sftp -i aliyun-root root@cka001 put aliyun-james.pub Log onto remote ECS cka001 using root account again. Move the key aliyun-james.pub to /home/james/.ssh/ . Rename file aliyun-james.pub to authorized_keys . Change ower of file authorized_keys to james . Change default group of file authorized_keys to sudo . mkdir /home/james/.ssh/ mv aliyun-james.pub /home/james/.ssh/authorized_keys chown james.sudo /home/james/.ssh/authorized_keys chmod 600 /home/james/.ssh/authorized_keys Check file /etc/ssh/sshd_config , make sure password authentication is disabled PasswordAuthentication no cat /etc/ssh/sshd_config Back to the local terminal, use james to log onto remote cka001 . ssh -i aliyun-james james@cka001 Upload the public key aliyun-james.pub to remote cka002 and cka003 using sftp command and do the same set up on cka002 and cka003 in order to enable user james to log onto cka002 and cka003 . Till now, user james can log onto cka001 , cka002 and cka003 using key aliyun-james . All demo below will be done by user james .","title":"Preparation"},{"location":"k8s/cka_en/installation/aliyun-ubuntu/#initialize-vms","text":"","title":"Initialize VMs"},{"location":"k8s/cka_en/installation/aliyun-ubuntu/#configure-etchosts-file","text":"Add private IPs in the /etc/hosts file in all VMs. vi /etc/hosts","title":"Configure /etc/hosts file"},{"location":"k8s/cka_en/installation/aliyun-ubuntu/#disable-firewall","text":"Disable firewall by command ufw disable in all VMs. Disable swap on Ubuntu. sudo ufw disable Check status of swap on Ubuntu. sudo ufw status verbose","title":"Disable firewall"},{"location":"k8s/cka_en/installation/aliyun-ubuntu/#turn-off-swap","text":"Turn off swap in all VMs. sudo swapoff -a","title":"Turn off swap"},{"location":"k8s/cka_en/installation/aliyun-ubuntu/#set-timezone-and-locale","text":"Set timezone and local for all VMs. This step was already done during Aliyun ECS installation. ln -sf /usr/share/zoneinfo/Asia/Shanghai /etc/localtime sudo echo 'LANG=\"en_US.UTF-8\"' >> /etc/profile source /etc/profile Something like this: ll /etc/localtime lrwxrwxrwx 1 root root 33 Jul 5 14 :51 /etc/localtime -> /usr/share/zoneinfo/Asia/Shanghai","title":"Set timezone and locale"},{"location":"k8s/cka_en/installation/aliyun-ubuntu/#kernel-setting","text":"Perform below kernel setting in all VMs. Create file /etc/modules-load.d/containerd.conf to set up containerd configure file. It's to load two modules overlay and br_netfilter . Service containerd depends on overlay filesystem. Sometimes referred to as union-filesystems. An overlay-filesystem tries to present a filesystem which is the result over overlaying one filesystem on top of the other. The br_netfilter module is required to enable transparent masquerading and to facilitate Virtual Extensible LAN (VxLAN) traffic for communication between Kubernetes pods across the cluster. cat < /etc/apt/sources.list << EOF deb http://mirrors.cloud.aliyuncs.com/ubuntu/ focal main restricted deb-src http://mirrors.cloud.aliyuncs.com/ubuntu/ focal main restricted deb http://mirrors.cloud.aliyuncs.com/ubuntu/ focal-updates main restricted deb-src http://mirrors.cloud.aliyuncs.com/ubuntu/ focal-updates main restricted deb http://mirrors.cloud.aliyuncs.com/ubuntu/ focal universe deb-src http://mirrors.cloud.aliyuncs.com/ubuntu/ focal universe deb http://mirrors.cloud.aliyuncs.com/ubuntu/ focal-updates universe deb-src http://mirrors.cloud.aliyuncs.com/ubuntu/ focal-updates universe deb http://mirrors.cloud.aliyuncs.com/ubuntu/ focal multiverse deb-src http://mirrors.cloud.aliyuncs.com/ubuntu/ focal multiverse deb http://mirrors.cloud.aliyuncs.com/ubuntu/ focal-updates multiverse deb-src http://mirrors.cloud.aliyuncs.com/ubuntu/ focal-updates multiverse deb http://mirrors.cloud.aliyuncs.com/ubuntu/ focal-backports main restricted universe multiverse deb-src http://mirrors.cloud.aliyuncs.com/ubuntu/ focal-backports main restricted universe multivers deb http://mirrors.cloud.aliyuncs.com/ubuntu focal-security main restricted deb-src http://mirrors.cloud.aliyuncs.com/ubuntu focal-security main restricted deb http://mirrors.cloud.aliyuncs.com/ubuntu focal-security universe deb-src http://mirrors.cloud.aliyuncs.com/ubuntu focal-security universe # deb http://mirrors.cloud.aliyuncs.com/ubuntu focal-security multiverse # deb-src http://mirrors.cloud.aliyuncs.com/ubuntu focal-security multiverse EOF Install Containered. sudo apt-get update && sudo apt-get install -y containerd Configure Containerd. Modify file /etc/containerd/config.toml . sudo mkdir -p /etc/containerd containerd config default | sudo tee /etc/containerd/config.toml sudo vi /etc/containerd/config.toml Update sandbox_image with new value \"registry.aliyuncs.com/google_containers/pause:3.6\" . Update SystemdCgroup with new value true . [plugins] [plugins.\"io.containerd.gc.v1.scheduler\"] [plugins.\"io.containerd.grpc.v1.cri\"] sandbox_image = \"registry.aliyuncs.com/google_containers/pause:3.6\" [plugins.\"io.containerd.grpc.v1.cri\".cni] [plugins.\"io.containerd.grpc.v1.cri\".containerd] [plugins.\"io.containerd.grpc.v1.cri\".containerd.default_runtime] [plugins.\"io.containerd.grpc.v1.cri\".containerd.default_runtime.options] [plugins.\"io.containerd.grpc.v1.cri\".containerd.runtimes] [plugins.\"io.containerd.grpc.v1.cri\".containerd.runtimes.runc] [plugins.\"io.containerd.grpc.v1.cri\".containerd.runtimes.runc.options] SystemdCgroup = true Restart Containerd service. sudo systemctl restart containerd sudo systemctl status containerd","title":"Install Containerd"},{"location":"k8s/cka_en/installation/aliyun-ubuntu/#install-nerdctl","text":"Install nerdctl sevice fro all VMs. The goal of nerdctl is to facilitate experimenting the cutting-edge features of containerd that are not present in Docker. Get the release from the link https://github.com/containerd/nerdctl/releases . wget https://github.com/containerd/nerdctl/releases/download/v0.22.0/nerdctl-0.22.0-linux-amd64.tar.gz tar -zxvf nerdctl-0.22.0-linux-amd64.tar.gz sudo cp nerdctl /usr/bin/ sudo cp containerd-rootless* /usr/bin/ Verify nerdctl. nerdctl --help To list local Kubernetes containers. nerdctl -n k8s.io ps","title":"Install nerdctl"},{"location":"k8s/cka_en/installation/aliyun-ubuntu/#install-kubeadm","text":"Update apt-transport-https , ca-certificates , and curl . sudo apt-get update && sudo apt-get install -y apt-transport-https ca-certificates curl Install gpg certificate. sudo curl -fsSLo /usr/share/keyrings/kubernetes-archive-keyring.gpg https://mirrors.aliyun.com/kubernetes/apt/doc/apt-key.gpg Add Kubernetes repo. Just choose one of below command and execute. echo \"deb [signed-by=/usr/share/keyrings/kubernetes-archive-keyring.gpg] https://mirrors.aliyun.com/kubernetes/apt/ \\ kubernetes-xenial main\" | sudo tee /etc/apt/sources.list.d/kubernetes.list Update and install dependencied packages. sudo apt-get update sudo apt-get install ebtables sudo apt-get install libxtables12 sudo apt-get upgrade iptables Check available versions of kubeadm. apt policy kubeadm Install 1.24.0-00 version of kubeadm and will upgrade to 1.24.2 later. sudo apt-get -y install kubelet = 1 .24.0-00 kubeadm = 1 .24.0-00 kubectl = 1 .24.0-00 --allow-downgrades","title":"Install kubeadm"},{"location":"k8s/cka_en/installation/aliyun-ubuntu/#setup-master-node","text":"","title":"Setup Master Node"},{"location":"k8s/cka_en/installation/aliyun-ubuntu/#kubeadm-init","text":"Set up Control Plane on VM playing master node. Check kubeadm default parameters for initialization. kubeadm config print init-defaults Reuslt: apiVersion : kubeadm.k8s.io/v1beta3 bootstrapTokens : - groups : - system:bootstrappers:kubeadm:default-node-token token : abcdef.0123456789abcdef ttl : 24h0m0s usages : - signing - authentication kind : InitConfiguration localAPIEndpoint : advertiseAddress : 1.2.3.4 bindPort : 6443 nodeRegistration : criSocket : unix:///var/run/containerd/containerd.sock imagePullPolicy : IfNotPresent name : node taints : null --- apiServer : timeoutForControlPlane : 4m0s apiVersion : kubeadm.k8s.io/v1beta3 certificatesDir : /etc/kubernetes/pki clusterName : kubernetes controllerManager : {} dns : {} etcd : local : dataDir : /var/lib/etcd imageRepository : k8s.gcr.io kind : ClusterConfiguration kubernetesVersion : 1.24.0 networking : dnsDomain : cluster.local serviceSubnet : 10.96.0.0/12 scheduler : {} Dry rune and run. Save the output, which will be used later on work nodes. With kubeadm init to initiate cluster, we need understand below three options about network. --pod-network-cidr : Specify range of IP addresses for the pod network. If set, the control plane will automatically allocate CIDRs for every node. Be noted that 10.244.0.0/16 is default range of flannel. If it's changed here, please do change the same when deploy Flannel . --apiserver-bind-port : Port for the API Server to bind to. (default 6443) --service-cidr : Use alternative range of IP address for service VIPs. (default \"10.96.0.0/12\") Note: service VIPs (a.k.a. Cluster IP), specified by option --service-cidr . podCIDR (a.k.a. endpoint IP)\uff0cspecified by option --pod-network-cidr . There are 4 distinct networking problems to address: Highly-coupled container-to-container communications: this is solved by Pods (podCIDR) and localhost communications. Pod-to-Pod communications: a.k.a. container-to-container. Example with Flannel, the flow is: Pod \u2192 veth pair \u2192 cni0 \u2192 flannel.1 \u2192 host eth0 \u2192 host eth0 \u2192 flannel.1 \u2192 cni0 \u2192 veth pair \u2192 Pod. Pod-to-Service communications: Flow: Pod \u2192 Kernel \u2192 Servive iptables \u2192 service \u2192 Pod iptables \u2192 Pod External-to-Service communications: LoadBalancer: SLB \u2192 NodePort \u2192 Service \u2192 Pod kube-proxy is responsible for iptables, not traffic. sudo kubeadm init \\ --dry-run \\ --pod-network-cidr = 10 .244.0.0/16 \\ --service-cidr 11 .244.0.0/16 \\ --image-repository = registry.aliyuncs.com/google_containers \\ --kubernetes-version = v1.24.0 sudo kubeadm init \\ --pod-network-cidr = 10 .244.0.0/16 \\ --service-cidr 11 .244.0.0/16 \\ --image-repository = registry.aliyuncs.com/google_containers \\ --kubernetes-version = v1.24.0 sudo kubeadm init \\ --pod-network-cidr = 10 .244.0.0/16 \\ --service-cidr 11 .244.0.0/16 \\ --kubernetes-version = v1.24.0","title":"kubeadm init"},{"location":"k8s/cka_en/installation/aliyun-ubuntu/#kubeconfig-file","text":"Set kubeconfig file for current user (here it's james ). mkdir -p $HOME /.kube sudo cp -i /etc/kubernetes/admin.conf $HOME /.kube/config sudo chown $( id -u ) : $( id -g ) $HOME /.kube/config Kubernetes provides a command line tool kubectl for communicating with a Kubernetes cluster's control plane, using the Kubernetes API. kubectl controls the Kubernetes cluster manager . For configuration, kubectl looks for a file named config in the $HOME/.kube directory, which is a copy of file /etc/kubernetes/admin.conf generated by kubeadm init . We can specify other kubeconfig files by setting the KUBECONFIG environment variable or by setting the --kubeconfig flag . If the KUBECONFIG environment variable doesn't exist, kubectl uses the default kubeconfig file, $HOME/.kube/config . A context element in a kubeconfig file is used to group access parameters under a convenient name. Each context has three parameters: cluster, namespace, and user. By default, the kubectl command-line tool uses parameters from the current context to communicate with the cluster. A sample of .kube/config . apiVersion : v1 clusters : - cluster : certificate-authority-data : server : https://:6443 name : contexts : - context : cluster : namespace : user : name : @ current-context : kind : Config preferences : {} users : - name : user : client-certificate-data : client-key-data : To get the current context: kubectl config get-contexts Result CURRENT NAME CLUSTER AUTHINFO NAMESPACE * kubernetes-admin@kubernetes kubernetes kubernetes-admin","title":"kubeconfig file"},{"location":"k8s/cka_en/installation/aliyun-ubuntu/#setup-work-nodes","text":"Perform on all VMs playing work nodes. # kubeadm join :6443 --token --discovery-token-ca-cert-hash Use kubeadm token to generate the join token and hash value. kubeadm token create --print-join-command Execute the command generated above on each node that we want to join the cluster as Worker node. Verify status on master node. All nodes' status is NotReady . Leave it at the moment and continue to install network plugin. kubectl get node -o wide","title":"Setup Work Nodes"},{"location":"k8s/cka_en/installation/aliyun-ubuntu/#install-calico-or-flannel","text":"Choose Calico or Flannel on control plane node. For NetworkPolicy purpose, choose Calico.","title":"Install Calico or Flannel"},{"location":"k8s/cka_en/installation/aliyun-ubuntu/#install-flannel","text":"Flannel is a simple and easy way to configure a layer 3 network fabric designed for Kubernetes. Deploy Flannel. In the kube-flannel.yml we can get the default network setting of Flannel, which is same with --pod-network-cidr=10.244.0.0/16 we defined before when we initiated kubeadm . net-conf.json : | { \"Network\": \"10.244.0.0/16\", \"Backend\": { \"Type\": \"vxlan\" } } Create Flannel apply -f https://raw.githubusercontent.com/coreos/flannel/master/Documentation/kube-flannel.yml Result Warning: policy/v1beta1 PodSecurityPolicy is deprecated in v1.21+, unavailable in v1.25+ podsecuritypolicy.policy/psp.flannel.unprivileged created clusterrole.rbac.authorization.k8s.io/flannel created clusterrolebinding.rbac.authorization.k8s.io/flannel created serviceaccount/flannel created configmap/kube-flannel-cfg created daemonset.apps/kube-flannel-ds created","title":"Install Flannel"},{"location":"k8s/cka_en/installation/aliyun-ubuntu/#install-calico","text":"Here is guidance of End-to-end Calico installation . Detail practice demo, can be found in section \"Install Calico\" of \"A1.Discussion\" below. Install Calico curl https://docs.projectcalico.org/manifests/calico.yaml -O kubectl apply -f calico.yaml Result configmap/calico-config created customresourcedefinition.apiextensions.k8s.io/bgpconfigurations.crd.projectcalico.org created customresourcedefinition.apiextensions.k8s.io/bgppeers.crd.projectcalico.org created customresourcedefinition.apiextensions.k8s.io/blockaffinities.crd.projectcalico.org created customresourcedefinition.apiextensions.k8s.io/caliconodestatuses.crd.projectcalico.org created customresourcedefinition.apiextensions.k8s.io/clusterinformations.crd.projectcalico.org created customresourcedefinition.apiextensions.k8s.io/felixconfigurations.crd.projectcalico.org created customresourcedefinition.apiextensions.k8s.io/globalnetworkpolicies.crd.projectcalico.org created customresourcedefinition.apiextensions.k8s.io/globalnetworksets.crd.projectcalico.org created customresourcedefinition.apiextensions.k8s.io/hostendpoints.crd.projectcalico.org created customresourcedefinition.apiextensions.k8s.io/ipamblocks.crd.projectcalico.org created customresourcedefinition.apiextensions.k8s.io/ipamconfigs.crd.projectcalico.org created customresourcedefinition.apiextensions.k8s.io/ipamhandles.crd.projectcalico.org created customresourcedefinition.apiextensions.k8s.io/ippools.crd.projectcalico.org created customresourcedefinition.apiextensions.k8s.io/ipreservations.crd.projectcalico.org created customresourcedefinition.apiextensions.k8s.io/kubecontrollersconfigurations.crd.projectcalico.org created customresourcedefinition.apiextensions.k8s.io/networkpolicies.crd.projectcalico.org created customresourcedefinition.apiextensions.k8s.io/networksets.crd.projectcalico.org created clusterrole.rbac.authorization.k8s.io/calico-kube-controllers created clusterrolebinding.rbac.authorization.k8s.io/calico-kube-controllers created clusterrole.rbac.authorization.k8s.io/calico-node created clusterrolebinding.rbac.authorization.k8s.io/calico-node created daemonset.apps/calico-node created serviceaccount/calico-node created deployment.apps/calico-kube-controllers created serviceaccount/calico-kube-controllers created poddisruptionbudget.policy/calico-kube-controllers created Verify status of Calico. kubectl get pod -n kube-system | grep calico Result calico-kube-controllers-555bc4b957-l8bn2 0/1 Pending 0 28s calico-node-255pc 0/1 Init:1/3 0 29s calico-node-7tmnb 0/1 Init:1/3 0 29s calico-node-w8nvl 0/1 Init:1/3 0 29s Verify network status. sudo nerdctl network ls Result NETWORK ID NAME FILE k8s-pod-network /etc/cni/net.d/10-calico.conflist 0 bridge /etc/cni/net.d/nerdctl-bridge.conflist host none","title":"Install Calico"},{"location":"k8s/cka_en/installation/aliyun-ubuntu/#check-cluster-status","text":"Perform kubectl cluster-info command on master node we will get below information. Kubernetes control plane is running at https://:6443 CoreDNS is running at https://:6443/api/v1/namespaces/kube-system/services/kube-dns:dns/proxy kubectl cluster-info Get nodes status. kubectl get nodes -owide All nodes are up with normal status. OS Image: Ubuntu 20.04.4 LTS Kernel Version: 5.4.0-122-generic Container Runtime: containerd://1.5.9 NAME STATUS ROLES AGE VERSION cka001 Ready control-plane 13m v1.24.0 cka002 Ready 8m35s v1.24.0 cka003 Ready 8m26s v1.24.0 Get pods status kubectl get pod -A Result: NAMESPACE NAME READY STATUS RESTARTS AGE kube-system calico-kube-controllers-555bc4b957-l8bn2 1/1 Running 0 7m18s kube-system calico-node-255pc 1/1 Running 0 7m19s kube-system calico-node-7tmnb 1/1 Running 0 7m19s kube-system calico-node-w8nvl 1/1 Running 0 7m19s kube-system coredns-74586cf9b6-4jwmk 1/1 Running 0 15m kube-system coredns-74586cf9b6-c5mll 1/1 Running 0 15m kube-system etcd-cka001 1/1 Running 0 15m kube-system kube-apiserver-cka001 1/1 Running 0 15m kube-system kube-controller-manager-cka001 1/1 Running 0 15m kube-system kube-proxy-dmj2t 1/1 Running 0 15m kube-system kube-proxy-n77zw 1/1 Running 0 11m kube-system kube-proxy-qs6rf 1/1 Running 0 11m kube-system kube-scheduler-cka001 1/1 Running 0 15m","title":"Check Cluster Status"},{"location":"k8s/cka_en/installation/aliyun-ubuntu/#reset-cluster","text":"CAUTION: below steps will destroy current cluster. Delete all nodes in the cluster. kubeadm reset Output: [reset] Reading configuration from the cluster... [reset] FYI: You can look at this config file with 'kubectl -n kube-system get cm kubeadm-config -o yaml' W0717 08:15:17.411992 3913615 preflight.go:55] [reset] WARNING: Changes made to this host by 'kubeadm init' or 'kubeadm join' will be reverted. [reset] Are you sure you want to proceed? [y/N]: y [preflight] Running pre-flight checks [reset] Stopping the kubelet service [reset] Unmounting mounted directories in \"/var/lib/kubelet\" [reset] Deleting contents of directories: [/etc/kubernetes/manifests /etc/kubernetes/pki] [reset] Deleting files: [/etc/kubernetes/admin.conf /etc/kubernetes/kubelet.conf /etc/kubernetes/bootstrap-kubelet.conf /etc/kubernetes/controller-manager.conf /etc/kubernetes/scheduler.conf] [reset] Deleting contents of stateful directories: [/var/lib/etcd /var/lib/kubelet /var/lib/dockershim /var/run/kubernetes /var/lib/cni] The reset process does not clean CNI configuration. To do so, you must remove /etc/cni/net.d The reset process does not reset or clean up iptables rules or IPVS tables. If you wish to reset iptables, you must do so manually by using the \"iptables\" command. If your cluster was setup to utilize IPVS, run ipvsadm --clear (or similar) to reset your system's IPVS tables. The reset process does not clean your kubeconfig files and you must remove them manually. Please, check the contents of the $HOME/.kube/config file. Clean up network setting rm -rf /var/run/flannel /opt/cni /etc/cni /var/lib/cni Clean up rule of iptables . iptables -F && iptables -t nat -F && iptables -t mangle -F && iptables -X Clean up rule of IPVS if using IPVS . ipvsadm --clear","title":"Reset cluster"},{"location":"k8s/cka_en/installation/aliyun-ubuntu/#troubleshooting","text":"","title":"Troubleshooting"},{"location":"k8s/cka_en/installation/aliyun-ubuntu/#issue-1","text":"The connection to the server :6443 was refused - did you specify the right host or port? Try : Reference Check if the kubeconfig file is update to udpate and exists in right place. Check environment setting. env | grep -i kub Check container status. sudo systemctl status containerd.service Check kubelet service. sudo systemctl status kubelet.service Check port listening status. netstat -pnlt | grep 6443 Check firewall status. sudo systemctl status firewalld.service Check log. journalctl -xeu kubelet","title":"Issue 1"},{"location":"k8s/cka_en/installation/aliyun-ubuntu/#issue-2","text":"\"Container runtime network not ready\" networkReady=\"NetworkReady=false reason:NetworkPluginNotReady message:Network plugin returns error: cni plugin not initialized\" Try : Restart Containerd service. sudo systemctl restart containerd sudo systemctl status containerd","title":"Issue 2"},{"location":"k8s/cka_en/installation/aliyun-ubuntu/#post-installation","text":"","title":"Post Installation"},{"location":"k8s/cka_en/installation/aliyun-ubuntu/#bash-autocomplete","text":"On each node. Set kubectl auto-completion following the guideline . apt install -y bash-completion source /usr/share/bash-completion/bash_completion source < ( kubectl completion bash ) echo \"source <(kubectl completion bash)\" >> ~/.bashrc","title":"Bash Autocomplete"},{"location":"k8s/cka_en/installation/aliyun-ubuntu/#alias","text":"If we set an alias for kubectl, we can extend shell completion to work with that alias: echo 'alias k=kubectl' >>~/.bashrc echo 'complete -o default -F __start_kubectl k' >>~/.bashrc","title":"Alias"},{"location":"k8s/cka_en/installation/aliyun-ubuntu/#update-default-context","text":"Get current context. kubectl config get-contexts In below result, we know: Contenxt name is kubernetes-admin@kubernetes . Cluster name is kubernetes . User is kubernetes-admin . No namespace explicitly defined. CURRENT NAME CLUSTER AUTHINFO NAMESPACE * kubernetes-admin@kubernetes kubernetes kubernetes-admin To set a context with new update, e.g, update default namespace, etc.. # Usage: kubectl config set-context --cluster = --namespace = --user = # Set default namespace kubectl config set-context kubernetes-admin@kubernetes --cluster = kubernetes --namespace = default --user = kubernetes-admin To switch to a new context. kubectl config use-context kubectl config use-context kubernetes-admin@kubernetes Reference of kubectl and commandline .","title":"Update Default Context"},{"location":"k8s/cka_en/installation/multiple-local/","text":"Multiple Nodes Installation \u00b6 Local VM setting \u00b6 VMWare Setting. VMnet1: host-only, subnet: 192.168.150.0/24 VMnet8: NAT, subnet: 11.0.1.0/24 Create guest machine with VMWare Player. 4 GB RAM 1 CPUs with 2 Cores Ubuntu Server 22.04 NAT Info: Kubernetes running on Containerd. Ubuntu Post Installation \u00b6 Info: Log onto each VM with the account created during Ubuntu installation, and perform below tasks on every VM. Create user vagrant on all guests. sudo adduser vagrant sudo usermod -aG adm,sudo,syslog,cdrom,dip,plugdev,lxd,root vagrant sudo passwd vagrant Set password for root on all guests. sudo passwd root Enable root ssh logon. sudo vi /etc/ssh/sshd_config Update parameter PermitRootLogin from prohibit-password to yes . PermitRootLogin yes # PermitRootLogin prohibit-password Restart the sshd service. sudo systemctl restart sshd Change host name, e.g., ubu1 . sudo hostnamectl set-hostname ubu1 sudo hostnamectl set-hostname ubu1 --pretty Verify if the hostname is set to expected name, e.g., ubu1 . cat /etc/machine-info Verify if the hostname is set to expected name, e.g., ubu1 . cat /etc/hostname Verify if the hostname of 127.0.1.1 is set to expected name, e.g., ubu1 . And add all nodes into the file /etc/hosts . sudo vi /etc/hosts Related setting looks like below. 127.0.1.1 ubu1 11.0.1.129 ubu1 11.0.1.130 ubu2 11.0.1.131 ubu3 11.0.1.132 ubu4 Create file /etc/netplan/00-installer-config.yaml . sudo vi /etc/netplan/00-installer-config.yaml Update it with information below to set VM with fixed IP with actual IP address, e.g, 11.0.1.129 . network : ethernets : ens33 : dhcp4 : false addresses : - 11.0.1.129/24 nameservers : addresses : - 11.0.1.2 routes : - to : default via : 11.0.1.2 version : 2 Effect above change. sudo netplan apply Attention: The current ssh connection will be broken due to network setting change. Disable swap and firewall on all nodes. sudo swapoff -a sudo ufw disable sudo ufw status verbose And comment the last line of swap setting in file /etc/fstab . Need reboot guest here. sudo vi /etc/fstab Result likes below. /dev/disk/by-uuid/df370d2a-83e5-4895-8c7f-633f2545e3fe / ext4 defaults 0 1 # /swap.img none swap sw 0 0 Setup timezone on all nodes sudo ln -sf /usr/share/zoneinfo/Asia/Shanghai /etc/localtime sudo cp /etc/profile /etc/profile.bak echo 'LANG=\"en_US.UTF-8\"' | sudo tee -a /etc/profile source /etc/profile Something like this after execute command ll /etc/localtime lrwxrwxrwx 1 root root 33 Jul 15 22:00 /etc/localtime -> /usr/share/zoneinfo/Asia/Shanghai Kernel setting. cat < server : https://:6443 name : contexts : - context : cluster : namespace : user : name : @ current-context : kind : Config preferences : {} users : - name : user : client-certificate-data : client-key-data : To get the current context: kubectl config get-contexts Result CURRENT NAME CLUSTER AUTHINFO NAMESPACE * kubernetes-admin@kubernetes kubernetes kubernetes-admin Install Calico \u00b6 Here is guidance of End-to-end Calico installation . Detail practice demo, can be found in section \"Install Calico\" of \"A1.Discussion\" below. Install Calico curl https://docs.projectcalico.org/manifests/calico.yaml -O kubectl apply -f calico.yaml Result configmap/calico-config created customresourcedefinition.apiextensions.k8s.io/bgpconfigurations.crd.projectcalico.org created customresourcedefinition.apiextensions.k8s.io/bgppeers.crd.projectcalico.org created customresourcedefinition.apiextensions.k8s.io/blockaffinities.crd.projectcalico.org created customresourcedefinition.apiextensions.k8s.io/caliconodestatuses.crd.projectcalico.org created customresourcedefinition.apiextensions.k8s.io/clusterinformations.crd.projectcalico.org created customresourcedefinition.apiextensions.k8s.io/felixconfigurations.crd.projectcalico.org created customresourcedefinition.apiextensions.k8s.io/globalnetworkpolicies.crd.projectcalico.org created customresourcedefinition.apiextensions.k8s.io/globalnetworksets.crd.projectcalico.org created customresourcedefinition.apiextensions.k8s.io/hostendpoints.crd.projectcalico.org created customresourcedefinition.apiextensions.k8s.io/ipamblocks.crd.projectcalico.org created customresourcedefinition.apiextensions.k8s.io/ipamconfigs.crd.projectcalico.org created customresourcedefinition.apiextensions.k8s.io/ipamhandles.crd.projectcalico.org created customresourcedefinition.apiextensions.k8s.io/ippools.crd.projectcalico.org created customresourcedefinition.apiextensions.k8s.io/ipreservations.crd.projectcalico.org created customresourcedefinition.apiextensions.k8s.io/kubecontrollersconfigurations.crd.projectcalico.org created customresourcedefinition.apiextensions.k8s.io/networkpolicies.crd.projectcalico.org created customresourcedefinition.apiextensions.k8s.io/networksets.crd.projectcalico.org created clusterrole.rbac.authorization.k8s.io/calico-kube-controllers created clusterrolebinding.rbac.authorization.k8s.io/calico-kube-controllers created clusterrole.rbac.authorization.k8s.io/calico-node created clusterrolebinding.rbac.authorization.k8s.io/calico-node created daemonset.apps/calico-node created serviceaccount/calico-node created deployment.apps/calico-kube-controllers created serviceaccount/calico-kube-controllers created poddisruptionbudget.policy/calico-kube-controllers created Verify status of Calico. It may take minutes to complete initialization. kubectl get pod -n kube-system | grep calico Result calico-kube-controllers-555bc4b957-l8bn2 0/1 Pending 0 28s calico-node-255pc 0/1 Init:1/3 0 29s calico-node-7tmnb 0/1 Init:1/3 0 29s calico-node-w8nvl 0/1 Init:1/3 0 29s Verify network status. sudo nerdctl network ls Result NETWORK ID NAME FILE k8s-pod-network /etc/cni/net.d/10-calico.conflist 17f29b073143 bridge /etc/cni/net.d/nerdctl-bridge.conflist host none Setup Work Nodes \u00b6 Use kubeadm token to generate the join token and hash value. kubeadm token create --print-join-command Command usage: sudo kubeadm join :6443 --token --discovery-token-ca-cert-hash < hash key generated by kubeadm init> Result looks like below. [preflight] Running pre-flight checks [WARNING SystemVerification]: missing optional cgroups: blkio [preflight] Reading configuration from the cluster... [preflight] FYI: You can look at this config file with 'kubectl -n kube-system get cm kubeadm-config -o yaml' [kubelet-start] Writing kubelet configuration to file \"/var/lib/kubelet/config.yaml\" [kubelet-start] Writing kubelet environment file with flags to file \"/var/lib/kubelet/kubeadm-flags.env\" [kubelet-start] Starting the kubelet [kubelet-start] Waiting for the kubelet to perform the TLS Bootstrap... This node has joined the cluster: * Certificate signing request was sent to apiserver and a response was received. * The Kubelet was informed of the new secure connection details. Run 'kubectl get nodes' on the control-plane to see this node join the cluster. Check Cluster Status \u00b6 Cluster info: kubectl cluster-info Output Kubernetes control plane is running at https://11.0.1.129:6443 CoreDNS is running at https://11.0.1.129:6443/api/v1/namespaces/kube-system/services/kube-dns:dns/proxy To further debug and diagnose cluster problems, use 'kubectl cluster-info dump'. Node info: kubectl get nodes -owide Pod info: kubectl get pod -A Post Installation \u00b6 Bash Autocomplete \u00b6 On each node. Set kubectl auto-completion following the guideline . apt install -y bash-completion source /usr/share/bash-completion/bash_completion source < ( kubectl completion bash ) echo \"source <(kubectl completion bash)\" >> ~/.bashrc source ~/.bashrc Alias \u00b6 If we set an alias for kubectl, we can extend shell completion to work with that alias: echo 'alias k=kubectl' >>~/.bashrc echo 'complete -o default -F __start_kubectl k' >>~/.bashrc Update Default Context \u00b6 Get current context. kubectl config get-contexts In below result, we know: Contenxt name is kubernetes-admin@kubernetes . Cluster name is kubernetes . User is kubernetes-admin . No namespace explicitly defined. CURRENT NAME CLUSTER AUTHINFO NAMESPACE * kubernetes-admin@kubernetes kubernetes kubernetes-admin To set a context with new update, e.g, update default namespace, etc.. # Usage: kubectl config set-context --cluster = --namespace = --user = # Set default namespace kubectl config set-context kubernetes-admin@kubernetes --cluster = kubernetes --namespace = default --user = kubernetes-admin To switch to a new context. kubectl config use-context kubectl config use-context kubernetes-admin@kubernetes Reference: kubectl commandline Install Helm \u00b6 Helm is the Kubernetes package manager. It doesn't come with Kubernetes. Three concepts of helm: A Chart is a Helm package. It contains all of the resource definitions necessary to run an application, tool, or service inside of a Kubernetes cluster. Think of it like the Kubernetes equivalent of a Homebrew formula, an Apt dpkg, or a Yum RPM file. A Repository is the place where charts can be collected and shared. It's like Perl's CPAN archive or the Fedora Package Database, but for Kubernetes packages. A Release is an instance of a chart running in a Kubernetes cluster. One chart can often be installed many times into the same cluster. And each time it is installed, a new release is created. Consider a MySQL chart. If you want two databases running in your cluster, you can install that chart twice. Each one will have its own release, which will in turn have its own release name. Reference: installation guide binary release source code . Helm Client Installation: curl -fsSL -o get_helm.sh https://raw.githubusercontent.com/helm/helm/main/scripts/get-helm-3 chmod 700 get_helm.sh ./get_helm.sh Output: Downloading https://get.helm.sh/helm-v3.9.1-linux-amd64.tar.gz Verifying checksum... Done. Preparing to install helm into /usr/local/bin helm installed into /usr/local/bin/helm Note: helm init does not exist in Helm 3, following the removal of Tiller. You no longer need to install Tiller in your cluster in order to use Helm. helm search can be used to search two different types of source: helm search hub searches the Artifact Hub , which lists helm charts from dozens of different repositories. helm search repo searches the repositories that you have added to your local helm client (with helm repo add). This search is done over local data, and no public network connection is needed. Reference: Helming development Reset cluster \u00b6 Caution: below steps will destroy current cluster. Delete all nodes in the cluster. kubeadm reset Clean up rule of iptables . iptables -F && iptables -t nat -F && iptables -t mangle -F && iptables -X Clean up rule of IPVS if using IPVS . ipvsadm --clear","title":"Multiple Nodes Installation"},{"location":"k8s/cka_en/installation/multiple-local/#multiple-nodes-installation","text":"","title":"Multiple Nodes Installation"},{"location":"k8s/cka_en/installation/multiple-local/#local-vm-setting","text":"VMWare Setting. VMnet1: host-only, subnet: 192.168.150.0/24 VMnet8: NAT, subnet: 11.0.1.0/24 Create guest machine with VMWare Player. 4 GB RAM 1 CPUs with 2 Cores Ubuntu Server 22.04 NAT Info: Kubernetes running on Containerd.","title":"Local VM setting"},{"location":"k8s/cka_en/installation/multiple-local/#ubuntu-post-installation","text":"Info: Log onto each VM with the account created during Ubuntu installation, and perform below tasks on every VM. Create user vagrant on all guests. sudo adduser vagrant sudo usermod -aG adm,sudo,syslog,cdrom,dip,plugdev,lxd,root vagrant sudo passwd vagrant Set password for root on all guests. sudo passwd root Enable root ssh logon. sudo vi /etc/ssh/sshd_config Update parameter PermitRootLogin from prohibit-password to yes . PermitRootLogin yes # PermitRootLogin prohibit-password Restart the sshd service. sudo systemctl restart sshd Change host name, e.g., ubu1 . sudo hostnamectl set-hostname ubu1 sudo hostnamectl set-hostname ubu1 --pretty Verify if the hostname is set to expected name, e.g., ubu1 . cat /etc/machine-info Verify if the hostname is set to expected name, e.g., ubu1 . cat /etc/hostname Verify if the hostname of 127.0.1.1 is set to expected name, e.g., ubu1 . And add all nodes into the file /etc/hosts . sudo vi /etc/hosts Related setting looks like below. 127.0.1.1 ubu1 11.0.1.129 ubu1 11.0.1.130 ubu2 11.0.1.131 ubu3 11.0.1.132 ubu4 Create file /etc/netplan/00-installer-config.yaml . sudo vi /etc/netplan/00-installer-config.yaml Update it with information below to set VM with fixed IP with actual IP address, e.g, 11.0.1.129 . network : ethernets : ens33 : dhcp4 : false addresses : - 11.0.1.129/24 nameservers : addresses : - 11.0.1.2 routes : - to : default via : 11.0.1.2 version : 2 Effect above change. sudo netplan apply Attention: The current ssh connection will be broken due to network setting change. Disable swap and firewall on all nodes. sudo swapoff -a sudo ufw disable sudo ufw status verbose And comment the last line of swap setting in file /etc/fstab . Need reboot guest here. sudo vi /etc/fstab Result likes below. /dev/disk/by-uuid/df370d2a-83e5-4895-8c7f-633f2545e3fe / ext4 defaults 0 1 # /swap.img none swap sw 0 0 Setup timezone on all nodes sudo ln -sf /usr/share/zoneinfo/Asia/Shanghai /etc/localtime sudo cp /etc/profile /etc/profile.bak echo 'LANG=\"en_US.UTF-8\"' | sudo tee -a /etc/profile source /etc/profile Something like this after execute command ll /etc/localtime lrwxrwxrwx 1 root root 33 Jul 15 22:00 /etc/localtime -> /usr/share/zoneinfo/Asia/Shanghai Kernel setting. cat < server : https://:6443 name : contexts : - context : cluster : namespace : user : name : @ current-context : kind : Config preferences : {} users : - name : user : client-certificate-data : client-key-data : To get the current context: kubectl config get-contexts Result CURRENT NAME CLUSTER AUTHINFO NAMESPACE * kubernetes-admin@kubernetes kubernetes kubernetes-admin","title":"kubeconfig file"},{"location":"k8s/cka_en/installation/multiple-local/#install-calico","text":"Here is guidance of End-to-end Calico installation . Detail practice demo, can be found in section \"Install Calico\" of \"A1.Discussion\" below. Install Calico curl https://docs.projectcalico.org/manifests/calico.yaml -O kubectl apply -f calico.yaml Result configmap/calico-config created customresourcedefinition.apiextensions.k8s.io/bgpconfigurations.crd.projectcalico.org created customresourcedefinition.apiextensions.k8s.io/bgppeers.crd.projectcalico.org created customresourcedefinition.apiextensions.k8s.io/blockaffinities.crd.projectcalico.org created customresourcedefinition.apiextensions.k8s.io/caliconodestatuses.crd.projectcalico.org created customresourcedefinition.apiextensions.k8s.io/clusterinformations.crd.projectcalico.org created customresourcedefinition.apiextensions.k8s.io/felixconfigurations.crd.projectcalico.org created customresourcedefinition.apiextensions.k8s.io/globalnetworkpolicies.crd.projectcalico.org created customresourcedefinition.apiextensions.k8s.io/globalnetworksets.crd.projectcalico.org created customresourcedefinition.apiextensions.k8s.io/hostendpoints.crd.projectcalico.org created customresourcedefinition.apiextensions.k8s.io/ipamblocks.crd.projectcalico.org created customresourcedefinition.apiextensions.k8s.io/ipamconfigs.crd.projectcalico.org created customresourcedefinition.apiextensions.k8s.io/ipamhandles.crd.projectcalico.org created customresourcedefinition.apiextensions.k8s.io/ippools.crd.projectcalico.org created customresourcedefinition.apiextensions.k8s.io/ipreservations.crd.projectcalico.org created customresourcedefinition.apiextensions.k8s.io/kubecontrollersconfigurations.crd.projectcalico.org created customresourcedefinition.apiextensions.k8s.io/networkpolicies.crd.projectcalico.org created customresourcedefinition.apiextensions.k8s.io/networksets.crd.projectcalico.org created clusterrole.rbac.authorization.k8s.io/calico-kube-controllers created clusterrolebinding.rbac.authorization.k8s.io/calico-kube-controllers created clusterrole.rbac.authorization.k8s.io/calico-node created clusterrolebinding.rbac.authorization.k8s.io/calico-node created daemonset.apps/calico-node created serviceaccount/calico-node created deployment.apps/calico-kube-controllers created serviceaccount/calico-kube-controllers created poddisruptionbudget.policy/calico-kube-controllers created Verify status of Calico. It may take minutes to complete initialization. kubectl get pod -n kube-system | grep calico Result calico-kube-controllers-555bc4b957-l8bn2 0/1 Pending 0 28s calico-node-255pc 0/1 Init:1/3 0 29s calico-node-7tmnb 0/1 Init:1/3 0 29s calico-node-w8nvl 0/1 Init:1/3 0 29s Verify network status. sudo nerdctl network ls Result NETWORK ID NAME FILE k8s-pod-network /etc/cni/net.d/10-calico.conflist 17f29b073143 bridge /etc/cni/net.d/nerdctl-bridge.conflist host none","title":"Install Calico"},{"location":"k8s/cka_en/installation/multiple-local/#setup-work-nodes","text":"Use kubeadm token to generate the join token and hash value. kubeadm token create --print-join-command Command usage: sudo kubeadm join :6443 --token --discovery-token-ca-cert-hash < hash key generated by kubeadm init> Result looks like below. [preflight] Running pre-flight checks [WARNING SystemVerification]: missing optional cgroups: blkio [preflight] Reading configuration from the cluster... [preflight] FYI: You can look at this config file with 'kubectl -n kube-system get cm kubeadm-config -o yaml' [kubelet-start] Writing kubelet configuration to file \"/var/lib/kubelet/config.yaml\" [kubelet-start] Writing kubelet environment file with flags to file \"/var/lib/kubelet/kubeadm-flags.env\" [kubelet-start] Starting the kubelet [kubelet-start] Waiting for the kubelet to perform the TLS Bootstrap... This node has joined the cluster: * Certificate signing request was sent to apiserver and a response was received. * The Kubelet was informed of the new secure connection details. Run 'kubectl get nodes' on the control-plane to see this node join the cluster.","title":"Setup Work Nodes"},{"location":"k8s/cka_en/installation/multiple-local/#check-cluster-status","text":"Cluster info: kubectl cluster-info Output Kubernetes control plane is running at https://11.0.1.129:6443 CoreDNS is running at https://11.0.1.129:6443/api/v1/namespaces/kube-system/services/kube-dns:dns/proxy To further debug and diagnose cluster problems, use 'kubectl cluster-info dump'. Node info: kubectl get nodes -owide Pod info: kubectl get pod -A","title":"Check Cluster Status"},{"location":"k8s/cka_en/installation/multiple-local/#post-installation","text":"","title":"Post Installation"},{"location":"k8s/cka_en/installation/multiple-local/#bash-autocomplete","text":"On each node. Set kubectl auto-completion following the guideline . apt install -y bash-completion source /usr/share/bash-completion/bash_completion source < ( kubectl completion bash ) echo \"source <(kubectl completion bash)\" >> ~/.bashrc source ~/.bashrc","title":"Bash Autocomplete"},{"location":"k8s/cka_en/installation/multiple-local/#alias","text":"If we set an alias for kubectl, we can extend shell completion to work with that alias: echo 'alias k=kubectl' >>~/.bashrc echo 'complete -o default -F __start_kubectl k' >>~/.bashrc","title":"Alias"},{"location":"k8s/cka_en/installation/multiple-local/#update-default-context","text":"Get current context. kubectl config get-contexts In below result, we know: Contenxt name is kubernetes-admin@kubernetes . Cluster name is kubernetes . User is kubernetes-admin . No namespace explicitly defined. CURRENT NAME CLUSTER AUTHINFO NAMESPACE * kubernetes-admin@kubernetes kubernetes kubernetes-admin To set a context with new update, e.g, update default namespace, etc.. # Usage: kubectl config set-context --cluster = --namespace = --user = # Set default namespace kubectl config set-context kubernetes-admin@kubernetes --cluster = kubernetes --namespace = default --user = kubernetes-admin To switch to a new context. kubectl config use-context kubectl config use-context kubernetes-admin@kubernetes Reference: kubectl commandline","title":"Update Default Context"},{"location":"k8s/cka_en/installation/multiple-local/#install-helm","text":"Helm is the Kubernetes package manager. It doesn't come with Kubernetes. Three concepts of helm: A Chart is a Helm package. It contains all of the resource definitions necessary to run an application, tool, or service inside of a Kubernetes cluster. Think of it like the Kubernetes equivalent of a Homebrew formula, an Apt dpkg, or a Yum RPM file. A Repository is the place where charts can be collected and shared. It's like Perl's CPAN archive or the Fedora Package Database, but for Kubernetes packages. A Release is an instance of a chart running in a Kubernetes cluster. One chart can often be installed many times into the same cluster. And each time it is installed, a new release is created. Consider a MySQL chart. If you want two databases running in your cluster, you can install that chart twice. Each one will have its own release, which will in turn have its own release name. Reference: installation guide binary release source code . Helm Client Installation: curl -fsSL -o get_helm.sh https://raw.githubusercontent.com/helm/helm/main/scripts/get-helm-3 chmod 700 get_helm.sh ./get_helm.sh Output: Downloading https://get.helm.sh/helm-v3.9.1-linux-amd64.tar.gz Verifying checksum... Done. Preparing to install helm into /usr/local/bin helm installed into /usr/local/bin/helm Note: helm init does not exist in Helm 3, following the removal of Tiller. You no longer need to install Tiller in your cluster in order to use Helm. helm search can be used to search two different types of source: helm search hub searches the Artifact Hub , which lists helm charts from dozens of different repositories. helm search repo searches the repositories that you have added to your local helm client (with helm repo add). This search is done over local data, and no public network connection is needed. Reference: Helming development","title":"Install Helm"},{"location":"k8s/cka_en/installation/multiple-local/#reset-cluster","text":"Caution: below steps will destroy current cluster. Delete all nodes in the cluster. kubeadm reset Clean up rule of iptables . iptables -F && iptables -t nat -F && iptables -t mangle -F && iptables -X Clean up rule of IPVS if using IPVS . ipvsadm --clear","title":"Reset cluster"},{"location":"k8s/cka_en/installation/single-local/","text":"Single Node Installation \u00b6 Local VM setting \u00b6 VMWare Setting. VMnet1: host-only, subnet: 192.168.150.0/24 VMnet8: NAT, subnet: 11.0.1.0/24 Create guest machine with VMWare Player. 4 GB RAM 2 CPUs with 2 Cores Ubuntu Server 22.04 NAT Kubernetes running on Docker. Ubuntu Post Installation \u00b6 Create user vagrant . sudo adduser vagrant sudo usermod -aG adm,sudo,syslog,cdrom,dip,plugdev,lxd vagrant sudo passwd vagrant Set password for root . sudo passwd root Update guest's hostname. Here it's ubusvr . sudo hostnamectl set-hostname ubusvr sudo hostnamectl set-hostname ubusvr --pretty Verify if the hostname is set to ubusvr . cat /etc/machine-info Verify if the hostname is set to ubusvr . cat /etc/hostname Verify if the hostname of 127.0.1.1 is set to ubusvr . cat /etc/hosts 127 .0.0.1 localhost 127 .0.1.1 ubusrv # The following lines are desirable for IPv6 capable hosts ::1 ip6-localhost ip6-loopback fe00::0 ip6-localnet ff00::0 ip6-mcastprefix ff02::1 ip6-allnodes ff02::2 ip6-allrouters Set guest with fix ip, e.g, 11.0.1.136 . sudo vi 00 -installer-config.yaml network: ethernets: ens33: dhcp4: false addresses: - 11 .0.1.136/24 nameservers: addresses: - 11 .0.1.2 routes: - to: default via: 11 .0.1.2 version: 2 sudo netplan apply Disable swap sudo swapoff -a sudo ufw disable sudo ufw status verbose And comment the last line of swap setting in file /etc/fstab . Need reboot guest here. /dev/disk/by-uuid/df370d2a-83e5-4895-8c7f-633f2545e3fe / ext4 defaults 0 1 # /swap.img none swap sw 0 0 Setup timezone sudo ln -sf /usr/share/zoneinfo/Asia/Shanghai /etc/localtime sudo echo 'LANG=\"en_US.UTF-8\"' >> /etc/profile source /etc/profile Something like this after execute command ll /etc/localtime lrwxrwxrwx 1 root root 33 Jul 15 22 :00 /etc/localtime -> /usr/share/zoneinfo/Asia/Shanghai Kernel setting cat < /dev/null sudo apt-get update sudo apt-get install docker-ce docker-ce-cli containerd.io docker-compose-plugin sudo systemctl status docker.service sudo systemctl status containerd.service sudo groupadd docker sudo usermod -aG docker $USER Setup Containerd containerd config default | sudo tee /etc/containerd/config.toml sudo vi /etc/containerd/config.toml sudo systemctl restart containerd sudo systemctl status containerd Install Kubernetes \u00b6 Install kubeadm sudo apt-get update && sudo apt-get install -y apt-transport-https ca-certificates curl sudo curl -fsSLo /usr/share/keyrings/kubernetes-archive-keyring.gpg https://mirrors.aliyun.com/kubernetes/apt/doc/apt-key.gpg echo \"deb [signed-by=/usr/share/keyrings/kubernetes-archive-keyring.gpg] https://mirrors.aliyun.com/kubernetes/apt/ kubernetes-xenial main\" | sudo tee /etc/apt/sources.list.d/kubernetes.list sudo apt-get update sudo apt-get install ebtables sudo apt-get install libxtables12 sudo apt-get upgrade iptables apt policy kubeadm sudo apt-get -y install kubelet = 1 .23.8-00 kubeadm = 1 .23.8-00 kubectl = 1 .23.8-00 --allow-downgrades Setup Master Node sudo kubeadm config print init-defaults Dry run sudo kubeadm init --dry-run --pod-network-cidr = 10 .244.0.0/16 --image-repository = registry.aliyuncs.com/google_containers --kubernetes-version = v1.23.8 Run sudo kubeadm init --pod-network-cidr = 10 .244.0.0/16 --image-repository = registry.aliyuncs.com/google_containers --kubernetes-version = v1.23.8 mkdir -p $HOME /.kube sudo cp -i /etc/kubernetes/admin.conf $HOME /.kube/config sudo chown $( id -u ) : $( id -g ) $HOME /.kube/config Install Flannel. If NetworkPolicy is the case, then install Calico. Refer to the \"Install Calico or Flannel\" of below section \"Installation on Aliyun Ubuntu\". kubectl apply -f https://raw.githubusercontent.com/coreos/flannel/master/Documentation/kube-flannel.yml Setup on Worker Node Command usage: kubeadm join :6443 --token --discovery-token-ca-cert-hash < hash key generated by kubeadm init> kubeadm join 11 .0.1.136:6443 --token 6zqh1u.8b4afzc2ov4e7iuj \\ --discovery-token-ca-cert-hash sha256:815fdb9dd9e3ae0af07ffaf6c216964388098b150ef01ee3ae900c261a429d24 Setup bash auto completion on all nodes sudo apt install -y bash-completion source /usr/share/bash-completion/bash_completion source < ( kubectl completion bash ) echo \"source <(kubectl completion bash)\" >> ~/.bashrc Create alias echo 'alias k=kubectl' >>~/.bashrc echo 'complete -o default -F __start_kubectl k' >>~/.bashrc Check Cluster Status kubectl cluster-info kubectl get nodes -owide kubectl get pod -A Reset cluster \u00b6 CAUTION: below steps will destroy current cluster. Delete all nodes in the cluster. kubeadm reset Clean up rule of iptables . iptables -F && iptables -t nat -F && iptables -t mangle -F && iptables -X Clean up rule of IPVS if using IPVS . ipvsadm --clear Install Helm \u00b6 Helm Client Installation: curl -fsSL -o get_helm.sh https://raw.githubusercontent.com/helm/helm/main/scripts/get-helm-3 chmod 700 get_helm.sh ./get_helm.sh Output: Downloading https://get.helm.sh/helm-v3.9.0-linux-amd64.tar.gz Verifying checksum... Done. Preparing to install helm into /usr/local/bin helm installed into /usr/local/bin/helm","title":"Single Node Installation"},{"location":"k8s/cka_en/installation/single-local/#single-node-installation","text":"","title":"Single Node Installation"},{"location":"k8s/cka_en/installation/single-local/#local-vm-setting","text":"VMWare Setting. VMnet1: host-only, subnet: 192.168.150.0/24 VMnet8: NAT, subnet: 11.0.1.0/24 Create guest machine with VMWare Player. 4 GB RAM 2 CPUs with 2 Cores Ubuntu Server 22.04 NAT Kubernetes running on Docker.","title":"Local VM setting"},{"location":"k8s/cka_en/installation/single-local/#ubuntu-post-installation","text":"Create user vagrant . sudo adduser vagrant sudo usermod -aG adm,sudo,syslog,cdrom,dip,plugdev,lxd vagrant sudo passwd vagrant Set password for root . sudo passwd root Update guest's hostname. Here it's ubusvr . sudo hostnamectl set-hostname ubusvr sudo hostnamectl set-hostname ubusvr --pretty Verify if the hostname is set to ubusvr . cat /etc/machine-info Verify if the hostname is set to ubusvr . cat /etc/hostname Verify if the hostname of 127.0.1.1 is set to ubusvr . cat /etc/hosts 127 .0.0.1 localhost 127 .0.1.1 ubusrv # The following lines are desirable for IPv6 capable hosts ::1 ip6-localhost ip6-loopback fe00::0 ip6-localnet ff00::0 ip6-mcastprefix ff02::1 ip6-allnodes ff02::2 ip6-allrouters Set guest with fix ip, e.g, 11.0.1.136 . sudo vi 00 -installer-config.yaml network: ethernets: ens33: dhcp4: false addresses: - 11 .0.1.136/24 nameservers: addresses: - 11 .0.1.2 routes: - to: default via: 11 .0.1.2 version: 2 sudo netplan apply Disable swap sudo swapoff -a sudo ufw disable sudo ufw status verbose And comment the last line of swap setting in file /etc/fstab . Need reboot guest here. /dev/disk/by-uuid/df370d2a-83e5-4895-8c7f-633f2545e3fe / ext4 defaults 0 1 # /swap.img none swap sw 0 0 Setup timezone sudo ln -sf /usr/share/zoneinfo/Asia/Shanghai /etc/localtime sudo echo 'LANG=\"en_US.UTF-8\"' >> /etc/profile source /etc/profile Something like this after execute command ll /etc/localtime lrwxrwxrwx 1 root root 33 Jul 15 22 :00 /etc/localtime -> /usr/share/zoneinfo/Asia/Shanghai Kernel setting cat < /dev/null sudo apt-get update sudo apt-get install docker-ce docker-ce-cli containerd.io docker-compose-plugin sudo systemctl status docker.service sudo systemctl status containerd.service sudo groupadd docker sudo usermod -aG docker $USER Setup Containerd containerd config default | sudo tee /etc/containerd/config.toml sudo vi /etc/containerd/config.toml sudo systemctl restart containerd sudo systemctl status containerd","title":"Install Docker"},{"location":"k8s/cka_en/installation/single-local/#install-kubernetes","text":"Install kubeadm sudo apt-get update && sudo apt-get install -y apt-transport-https ca-certificates curl sudo curl -fsSLo /usr/share/keyrings/kubernetes-archive-keyring.gpg https://mirrors.aliyun.com/kubernetes/apt/doc/apt-key.gpg echo \"deb [signed-by=/usr/share/keyrings/kubernetes-archive-keyring.gpg] https://mirrors.aliyun.com/kubernetes/apt/ kubernetes-xenial main\" | sudo tee /etc/apt/sources.list.d/kubernetes.list sudo apt-get update sudo apt-get install ebtables sudo apt-get install libxtables12 sudo apt-get upgrade iptables apt policy kubeadm sudo apt-get -y install kubelet = 1 .23.8-00 kubeadm = 1 .23.8-00 kubectl = 1 .23.8-00 --allow-downgrades Setup Master Node sudo kubeadm config print init-defaults Dry run sudo kubeadm init --dry-run --pod-network-cidr = 10 .244.0.0/16 --image-repository = registry.aliyuncs.com/google_containers --kubernetes-version = v1.23.8 Run sudo kubeadm init --pod-network-cidr = 10 .244.0.0/16 --image-repository = registry.aliyuncs.com/google_containers --kubernetes-version = v1.23.8 mkdir -p $HOME /.kube sudo cp -i /etc/kubernetes/admin.conf $HOME /.kube/config sudo chown $( id -u ) : $( id -g ) $HOME /.kube/config Install Flannel. If NetworkPolicy is the case, then install Calico. Refer to the \"Install Calico or Flannel\" of below section \"Installation on Aliyun Ubuntu\". kubectl apply -f https://raw.githubusercontent.com/coreos/flannel/master/Documentation/kube-flannel.yml Setup on Worker Node Command usage: kubeadm join :6443 --token --discovery-token-ca-cert-hash < hash key generated by kubeadm init> kubeadm join 11 .0.1.136:6443 --token 6zqh1u.8b4afzc2ov4e7iuj \\ --discovery-token-ca-cert-hash sha256:815fdb9dd9e3ae0af07ffaf6c216964388098b150ef01ee3ae900c261a429d24 Setup bash auto completion on all nodes sudo apt install -y bash-completion source /usr/share/bash-completion/bash_completion source < ( kubectl completion bash ) echo \"source <(kubectl completion bash)\" >> ~/.bashrc Create alias echo 'alias k=kubectl' >>~/.bashrc echo 'complete -o default -F __start_kubectl k' >>~/.bashrc Check Cluster Status kubectl cluster-info kubectl get nodes -owide kubectl get pod -A","title":"Install Kubernetes"},{"location":"k8s/cka_en/installation/single-local/#reset-cluster","text":"CAUTION: below steps will destroy current cluster. Delete all nodes in the cluster. kubeadm reset Clean up rule of iptables . iptables -F && iptables -t nat -F && iptables -t mangle -F && iptables -X Clean up rule of IPVS if using IPVS . ipvsadm --clear","title":"Reset cluster"},{"location":"k8s/cka_en/installation/single-local/#install-helm","text":"Helm Client Installation: curl -fsSL -o get_helm.sh https://raw.githubusercontent.com/helm/helm/main/scripts/get-helm-3 chmod 700 get_helm.sh ./get_helm.sh Output: Downloading https://get.helm.sh/helm-v3.9.0-linux-amd64.tar.gz Verifying checksum... Done. Preparing to install helm into /usr/local/bin helm installed into /usr/local/bin/helm","title":"Install Helm"},{"location":"k8s/demo/cap_on_kyma/","text":"Build CAP Application on Kyma \u00b6 This is the memo of self-practice following the tutorials from Deploy Your CAP Application on SAP BTP Kyma Runtime . Prerequisites: Register account in Developer@SAP . Register trial account in SAP BTP . Tasks: Configure Kyma in SAP Business Technology Platform (SAP BTP) subaccount and prepare Kyma development environment. Create an HDI container for an SAP HANA Cloud instance on Cloud Foundry and create credentials for this SAP HANA cloud instance in Kyma cluster. Develop a business application using SAP Cloud Application Programming Model (CAP). Start on local environment, enhance it with an SAP Fiori UI, add business logic to it, and also roles and authorization check. Add a Helm chart to the application, build docker images, push them to your container registry, and deploy your application to your Kyma cluster on SAP BTP. Local environment: Applel Silicon M1 chipset macOS 12.6 (command sw_vers ) Nodejs version: CDS version: jq - for JSON processing in CLI ( brew install jq ) SAP BTP subaccount configuration \u00b6 For the SAP BTP free tier, the recommendation is as well to use an AWS-based subaccount. Kyma runtime in the free tier is only available on AWS. Choose the entitlements for the subdomain: Alert Notification: Standard plan Continuous Integration & Delivery: default (Application) or the trial (Application) or free (Application) plans which are not charged Kyma runtime: any available plan in the list (trial and free are not charged) Launchpad Service: standard (Application) or free (Application) SAP HANA Cloud: hana SAP HANA Schemas & HDI Containers: hdi-shared Set up local BTP environment \u00b6 Here we will use btp command to set up cloud environment. Details we can refer to help document Working with Environments Using the btp CLI . Download BTP CLI package btp-cli-darwin-amd64-.tar.gz via link and unpackage it. tar xvf btp-cli-darwin-amd64-.tar.gz A new subfolder darwin-amd64 will be created in current path and a bin file btp is under the subfolder. Move file btp to folder /usr/local/bin/ . sudo mv ./darwin-amd64/btp /usr/local/bin/ Log on to the subaccount on BTP. btp login --url https://cpcli.cf.eu10.hana.ondemand.com --subdomain --user Configuration file was stored at /Users/$USER/Library/Application Support/.btp/config.json . In Linux, the configuration file is on /home/$USER/.config/.btp/config.json . We can get current user via command echo $USER . Tips: Commands are executed in the target, unless specified otherwise using a parameter. To change the target, use btp target . For an explanation of the targeting mechanism, use btp help target . Get the subaccount ID in BTP and we will know that kyma and cloundfoundry are available in current trial account. btp list accounts/available-environment --subaccount Get details about an environment available for a subaccount btp get accounts/available-environment --subaccount --environment cloudfoundry --service cloudfoundry --plan standard btp get accounts/available-environment --subaccount --environment kyma --service kymaruntime --plan trial Get status running instances. Here we will also get environment ID of running instances. btp list accounts/environment-instance --subaccount Delete a running instance if needed. btp delete accounts/environment-instance --subaccount Create Kyma instance. btp create accounts/environment-instance --subaccount --environment kyma --service kymaruntime --plan trial --parameters '{\"name\": \"\"}' btp get accounts/environment-instance --subaccount Create CloudFoundry instance btp create accounts/environment-instance --subaccount --environment cloudfoundry --service cloudfoundry --plan standard --parameters '{\"instance_name\": \"\"}' btp get accounts/environment-instance --subaccount Log onto CF to create space DEV by providing API endpoint, Email and Password, which are ready in the subaccount overview page. cf login cf create-space DEV Install Homebrew \u00b6 Refer to installation guide . Set environment variables export HOMEBREW_BREW_GIT_REMOTE = \"https://mirrors.ustc.edu.cn/brew.git\" export HOMEBREW_CORE_GIT_REMOTE = \"https://mirrors.ustc.edu.cn/homebrew-core.git\" export HOMEBREW_BOTTLE_DOMAIN = \"https://mirrors.ustc.edu.cn/homebrew-bottles\" Install Homebrew /bin/bash -c \" $( curl -fsSL https://github.com/Homebrew/install/raw/HEAD/install.sh ) \" Add below in file ~/.zprofile . export HOMEBREW_BREW_GIT_REMOTE = \"https://mirrors.ustc.edu.cn/brew.git\" export HOMEBREW_CORE_GIT_REMOTE = \"https://mirrors.ustc.edu.cn/homebrew-core.git\" export HOMEBREW_BOTTLE_DOMAIN = \"https://mirrors.ustc.edu.cn/homebrew-bottles\" eval \" $( /opt/homebrew/bin/brew shellenv ) \" Make it effected. source ~/.zprofile Install kubetcl \u00b6 The kubectl installation guide curl -LO \"https://dl.k8s.io/release/ $( curl -L -s https://dl.k8s.io/release/stable.txt ) /bin/darwin/arm64/kubectl\" chmod +x ./kubectl sudo mv ./kubectl /usr/local/bin/kubectl sudo chown root: /usr/local/bin/kubectl kubectl version --client Install plugin oidc-login . curl -fsSLO https://github.com/kubernetes-sigs/krew/releases/latest/download/krew-darwin_arm64.tar.gz tar xvf krew-darwin_arm64.tar.gz ./krew-darwin_arm64 install krew Add the $HOME/.krew/bin directory to the PATH environment variable by updating ~/.zprofile . export PATH = $HOME /.krew/bin: $PATH : $PATH Make it effected source ~/.zprofile Run kubectl krew to check the installation. Install/uninstall plugin oidc-login . kubectl krew install oidc-login kubectl krew uninstall oidc-login SAP Kyma runtime \u00b6 In the Overview area of your subaccount open the Link to dashboard link which appears next to the Console URL under the Kyma Environment area. At the top left of the window choose the Clusters Overview drop down and choose your cluster. In the Clusters Overview window choose the Download Kubeconfig for your Kyma runtime to download your KUBECONFIG. Add below to ~/.zprofile to set the kubeconfig to an environment variable. export KUBECONFIG = Make above change effected. source ~/.zprofile chmod 600 Test connection between kubectl and Kyma on BTP. kubectl cluster-info Install Node.js \u00b6 Refer to installation guide brew search node brew install node@16 brew unlink node brew link node@16 node -v Install SQLite \u00b6 Install SQLite via brew . brew search sqlite brew install sqlite Add below to ~/.zprofile export PATH = /opt/homebrew/opt/sqlite/bin: $PATH Make it effected source ~/.zprofile Install Xcode \u00b6 (For macOS) We have to install Command-Line Tools for Xcode , cause some node modules need binary modules (node-gyp). xcode-select --install xcode-select --help Install Git \u00b6 Refer to installation guide . brew install git git version Install SAPUI5 \u00b6 Install the UI5 CLI. npm search --global @ui5/cli npm install --global @ui5/cli npm list --global @ui5/cli ui5 --version npm search --global grunt-cli npm install --global grunt-cli npm list --global grunt-cli Install CF CLI \u00b6 Refer to installation guide . brew install cloudfoundry/tap/cf-cli@8 cf --version Install CAP Tooling \u00b6 See the details in the CAP documentation . npm search --global @sap/cds-dk npm install --global @sap/cds-dk npm list --global @sap/cds-dk cds --version Install VSCode \u00b6 In VS Code, invoke the Command Palette ( View \u2192 Command Palette or \u21e7\u2318P) and type shell command to find the Shell Command: Install 'code' command in PATH . Install SAP CDS Language Support extension. Install SAP Fiori tools - Extension Pack extension. Install Yeoman \u00b6 Yeoman is a tool for scaffolding web apps. You\u2019ll need it if you want to carry out the tutorial Add the SAP Launchpad Service. npm install --global yo yo --version Install Docker \u00b6 brew install docker --cask Install Helm \u00b6 Refer to installation guide brew install helm Install Paketo(pack) \u00b6 Refer to installation guide . brew install buildpacks/tap/pack Install Rancher Desktop \u00b6 Download the Rancher Desktop installer for macOS from the release page . Refer to installation guide . Download tutorial \u00b6 Go to tutorial root directory and clone the code. git clone https://github.com/SAP-samples/cloud-cap-risk-management tutorial Initialize the project \u00b6 Install required Node.js modules in the app directory cpapp . cd app cds init npm install cds watch Add files to the project \u00b6 Copy the file schema.cds from templates/create-cap-application/db to the db folder of the app. It creates two entities in the namespace sap.ui.riskmanagement : Risks and Mitigations . Copy the file risk-service.cds from templates/create-cap-application/srv to the srv folder of the app. It creates a new service RiskService in the namespace sap.ui.riskmanagement . This service exposes two entities: Risks and Mitigations , which are exposing the entities of the database schema we've created in the step before. Copy the folder data from templates/create-cap-application/db to the db folder of the app. There are two comma-separated value (CSV) files that contain local data for both the Risks and the Mitigations entities. Use Fiori Application Generator (VSCode extension) to generate Risk UI with Fiori element template. The generation will create a risks and a webapp folder with a Component.js file in the app folder of the project. Copy the file risks-service-ui.cds from templates/create-ui-fiori-elements/srv to the srv folder of the app. It defines annotations to show a work list with some columns and the data from the service in the Risk UI. Edit app/risks/webapp/manifest.json file to make the header fields editable, that is, shows title and description in Risk UI. Copy the file risk-service.js from templates/cap-business-logic/srv to the srv folder of the app. It now shows the work list in Risk UI with the columns Priority and Impact with color and an icon, depending on the amount in Impact . Use Fiori Application Generator (VSCode extension) to generate Migration UI with Fiori free-style template. The generation will create a migrations and a webapp folder with a Component.js file in the app folder of the project. Update file cpapp/app/mitigations/webapp/view/Worklist.view.xml to show Description , Owner , and Timeline columns, as well as in detail object page. Till now, our risks and mitigations application have been generated by the SAP Fiori Tools Generator and can be started independently. They are launched without a launch page. Copy the file launchpage.html from templates/launchpage/app to the app folder of the app. There are two applications in the launch page with URLs that point to the respective apps. We now see the Mitigations app next to the Risks app on the launch page. Open the file srv/risk-service.cds and add role restrictions to entities. Copy the file templates/cap-roles/.cdsrc.json to the project directory cpapp . The file defines two users risk.viewer@tester.sap.com and risk.manager@tester.sap.com . The default password can be found in the file .cdsrc.json . We will see the CAP server to show above applications via link http://localhost:4004 . Prepare Kyma Development Environment \u00b6 Execute cds version to make sure the package.json is using @sap/cds 6.0.1 or newer and we have @sap/cds-dk 6.0.1 or newer globally installed. Create namespace on Kyma. kubectl create namespace risk-management Switch to the namespace. kubectl config set-context --current --namespace risk-management Create container registry secret. Copy the folder scripts from templates/Kyma-Prepare-Dev-Environment to the project root folder cpapp . In the root folder cpapp of the project, run the script to create the secret. ./scripts/create-container-registry-secret.sh Need provide below input: docker-server = https://registry-1.docker.io docker-username = docker-email = docker-password = Verify kubectl get secret Set Up SAP HANA Cloud for Kyma \u00b6 Add SAP HANA support to your project. This adds the db module for SAP HANA access to the package.json file. Execute the command below in the project root directory cpapp . cds add hana --for production Verify the access to both CF and Kyma by executing below commands. cf login kubectl cluster-info Create HANA Cloud instance cpapp-db in CloudFoundry DEV namespace. The admin user id is DBADMIN . In the root folder cpapp of the project, execute: ./scripts/create-db-secret.sh cpapp-db Get the host name pattern of the cluster with the following command. Result looks like *.c-.sap.kyma.ondemand.com . kubectl get gateway -n kyma-system kyma-gateway -o jsonpath = '{.spec.servers[0].hosts[0]}' The script will: Create service key cpapp-db-key for HANA Cloud service instance cpapp-db as . Create Kubernetes secret cpapp-db for HANA DB instance. View it using kubectl get secret cpapp-db -o yaml . User Authentication and Authorization (XSUAA) Setup \u00b6 Set up XSUAA. cds add xsuaa --for production Above command will do: Adds the XSUAA service to the package.json file of the project Creates the XSUAA security configuration xs-security.json for the project Add Helm Chart \u00b6 Add Helm Chart. cds add helm Get docker server URL by command: cat ~/.docker/config.json Get the image pull secret for container registry. In the demo, it's container-registry . kubectl get secret Get the host name pattern of the cluster. kubectl get gateway -n kyma-system kyma-gateway -o jsonpath = '{.spec.servers[0].hosts[0]}' Open the file chart/values.yaml : Replace the placeholder with docker server URL https://docker.io/ . Set imagePullSecret with value name: container-registry . Add host name of the cluster without leading *. . Add the binding db pointing to the SAP HANA Cloud instance secret cpapp-db . Point the binding hana of the SAP HANA Cloud instance secret cpapp-db . Add the Authorization and Trust Management service to allow user login. Deploy CAP Application to Kyma \u00b6 Build docker image. CONTAINER_REGISTRY = https://index.docker.io/v1 CONTAINER_REGISTRY = https://registry-1.docker.io/yuhuihu CONTAINER_REGISTRY = yuhuihu CAP build. cds build --production Build CAP service. pack build $CONTAINER_REGISTRY /cpapp-srv --path gen/srv \\ --buildpack gcr.io/paketo-buildpacks/nodejs \\ --builder paketobuildpacks/builder:base","title":"Build CAP Application on Kyma"},{"location":"k8s/demo/cap_on_kyma/#build-cap-application-on-kyma","text":"This is the memo of self-practice following the tutorials from Deploy Your CAP Application on SAP BTP Kyma Runtime . Prerequisites: Register account in Developer@SAP . Register trial account in SAP BTP . Tasks: Configure Kyma in SAP Business Technology Platform (SAP BTP) subaccount and prepare Kyma development environment. Create an HDI container for an SAP HANA Cloud instance on Cloud Foundry and create credentials for this SAP HANA cloud instance in Kyma cluster. Develop a business application using SAP Cloud Application Programming Model (CAP). Start on local environment, enhance it with an SAP Fiori UI, add business logic to it, and also roles and authorization check. Add a Helm chart to the application, build docker images, push them to your container registry, and deploy your application to your Kyma cluster on SAP BTP. Local environment: Applel Silicon M1 chipset macOS 12.6 (command sw_vers ) Nodejs version: CDS version: jq - for JSON processing in CLI ( brew install jq )","title":"Build CAP Application on Kyma"},{"location":"k8s/demo/cap_on_kyma/#sap-btp-subaccount-configuration","text":"For the SAP BTP free tier, the recommendation is as well to use an AWS-based subaccount. Kyma runtime in the free tier is only available on AWS. Choose the entitlements for the subdomain: Alert Notification: Standard plan Continuous Integration & Delivery: default (Application) or the trial (Application) or free (Application) plans which are not charged Kyma runtime: any available plan in the list (trial and free are not charged) Launchpad Service: standard (Application) or free (Application) SAP HANA Cloud: hana SAP HANA Schemas & HDI Containers: hdi-shared","title":"SAP BTP subaccount configuration"},{"location":"k8s/demo/cap_on_kyma/#set-up-local-btp-environment","text":"Here we will use btp command to set up cloud environment. Details we can refer to help document Working with Environments Using the btp CLI . Download BTP CLI package btp-cli-darwin-amd64-.tar.gz via link and unpackage it. tar xvf btp-cli-darwin-amd64-.tar.gz A new subfolder darwin-amd64 will be created in current path and a bin file btp is under the subfolder. Move file btp to folder /usr/local/bin/ . sudo mv ./darwin-amd64/btp /usr/local/bin/ Log on to the subaccount on BTP. btp login --url https://cpcli.cf.eu10.hana.ondemand.com --subdomain --user Configuration file was stored at /Users/$USER/Library/Application Support/.btp/config.json . In Linux, the configuration file is on /home/$USER/.config/.btp/config.json . We can get current user via command echo $USER . Tips: Commands are executed in the target, unless specified otherwise using a parameter. To change the target, use btp target . For an explanation of the targeting mechanism, use btp help target . Get the subaccount ID in BTP and we will know that kyma and cloundfoundry are available in current trial account. btp list accounts/available-environment --subaccount Get details about an environment available for a subaccount btp get accounts/available-environment --subaccount --environment cloudfoundry --service cloudfoundry --plan standard btp get accounts/available-environment --subaccount --environment kyma --service kymaruntime --plan trial Get status running instances. Here we will also get environment ID of running instances. btp list accounts/environment-instance --subaccount Delete a running instance if needed. btp delete accounts/environment-instance --subaccount Create Kyma instance. btp create accounts/environment-instance --subaccount --environment kyma --service kymaruntime --plan trial --parameters '{\"name\": \"\"}' btp get accounts/environment-instance --subaccount Create CloudFoundry instance btp create accounts/environment-instance --subaccount --environment cloudfoundry --service cloudfoundry --plan standard --parameters '{\"instance_name\": \"\"}' btp get accounts/environment-instance --subaccount Log onto CF to create space DEV by providing API endpoint, Email and Password, which are ready in the subaccount overview page. cf login cf create-space DEV","title":"Set up local BTP environment"},{"location":"k8s/demo/cap_on_kyma/#install-homebrew","text":"Refer to installation guide . Set environment variables export HOMEBREW_BREW_GIT_REMOTE = \"https://mirrors.ustc.edu.cn/brew.git\" export HOMEBREW_CORE_GIT_REMOTE = \"https://mirrors.ustc.edu.cn/homebrew-core.git\" export HOMEBREW_BOTTLE_DOMAIN = \"https://mirrors.ustc.edu.cn/homebrew-bottles\" Install Homebrew /bin/bash -c \" $( curl -fsSL https://github.com/Homebrew/install/raw/HEAD/install.sh ) \" Add below in file ~/.zprofile . export HOMEBREW_BREW_GIT_REMOTE = \"https://mirrors.ustc.edu.cn/brew.git\" export HOMEBREW_CORE_GIT_REMOTE = \"https://mirrors.ustc.edu.cn/homebrew-core.git\" export HOMEBREW_BOTTLE_DOMAIN = \"https://mirrors.ustc.edu.cn/homebrew-bottles\" eval \" $( /opt/homebrew/bin/brew shellenv ) \" Make it effected. source ~/.zprofile","title":"Install Homebrew"},{"location":"k8s/demo/cap_on_kyma/#install-kubetcl","text":"The kubectl installation guide curl -LO \"https://dl.k8s.io/release/ $( curl -L -s https://dl.k8s.io/release/stable.txt ) /bin/darwin/arm64/kubectl\" chmod +x ./kubectl sudo mv ./kubectl /usr/local/bin/kubectl sudo chown root: /usr/local/bin/kubectl kubectl version --client Install plugin oidc-login . curl -fsSLO https://github.com/kubernetes-sigs/krew/releases/latest/download/krew-darwin_arm64.tar.gz tar xvf krew-darwin_arm64.tar.gz ./krew-darwin_arm64 install krew Add the $HOME/.krew/bin directory to the PATH environment variable by updating ~/.zprofile . export PATH = $HOME /.krew/bin: $PATH : $PATH Make it effected source ~/.zprofile Run kubectl krew to check the installation. Install/uninstall plugin oidc-login . kubectl krew install oidc-login kubectl krew uninstall oidc-login","title":"Install kubetcl"},{"location":"k8s/demo/cap_on_kyma/#sap-kyma-runtime","text":"In the Overview area of your subaccount open the Link to dashboard link which appears next to the Console URL under the Kyma Environment area. At the top left of the window choose the Clusters Overview drop down and choose your cluster. In the Clusters Overview window choose the Download Kubeconfig for your Kyma runtime to download your KUBECONFIG. Add below to ~/.zprofile to set the kubeconfig to an environment variable. export KUBECONFIG = Make above change effected. source ~/.zprofile chmod 600 Test connection between kubectl and Kyma on BTP. kubectl cluster-info","title":"SAP Kyma runtime"},{"location":"k8s/demo/cap_on_kyma/#install-nodejs","text":"Refer to installation guide brew search node brew install node@16 brew unlink node brew link node@16 node -v","title":"Install Node.js"},{"location":"k8s/demo/cap_on_kyma/#install-sqlite","text":"Install SQLite via brew . brew search sqlite brew install sqlite Add below to ~/.zprofile export PATH = /opt/homebrew/opt/sqlite/bin: $PATH Make it effected source ~/.zprofile","title":"Install SQLite"},{"location":"k8s/demo/cap_on_kyma/#install-xcode","text":"(For macOS) We have to install Command-Line Tools for Xcode , cause some node modules need binary modules (node-gyp). xcode-select --install xcode-select --help","title":"Install Xcode"},{"location":"k8s/demo/cap_on_kyma/#install-git","text":"Refer to installation guide . brew install git git version","title":"Install Git"},{"location":"k8s/demo/cap_on_kyma/#install-sapui5","text":"Install the UI5 CLI. npm search --global @ui5/cli npm install --global @ui5/cli npm list --global @ui5/cli ui5 --version npm search --global grunt-cli npm install --global grunt-cli npm list --global grunt-cli","title":"Install SAPUI5"},{"location":"k8s/demo/cap_on_kyma/#install-cf-cli","text":"Refer to installation guide . brew install cloudfoundry/tap/cf-cli@8 cf --version","title":"Install CF CLI"},{"location":"k8s/demo/cap_on_kyma/#install-cap-tooling","text":"See the details in the CAP documentation . npm search --global @sap/cds-dk npm install --global @sap/cds-dk npm list --global @sap/cds-dk cds --version","title":"Install CAP Tooling"},{"location":"k8s/demo/cap_on_kyma/#install-vscode","text":"In VS Code, invoke the Command Palette ( View \u2192 Command Palette or \u21e7\u2318P) and type shell command to find the Shell Command: Install 'code' command in PATH . Install SAP CDS Language Support extension. Install SAP Fiori tools - Extension Pack extension.","title":"Install VSCode"},{"location":"k8s/demo/cap_on_kyma/#install-yeoman","text":"Yeoman is a tool for scaffolding web apps. You\u2019ll need it if you want to carry out the tutorial Add the SAP Launchpad Service. npm install --global yo yo --version","title":"Install Yeoman"},{"location":"k8s/demo/cap_on_kyma/#install-docker","text":"brew install docker --cask","title":"Install Docker"},{"location":"k8s/demo/cap_on_kyma/#install-helm","text":"Refer to installation guide brew install helm","title":"Install Helm"},{"location":"k8s/demo/cap_on_kyma/#install-paketopack","text":"Refer to installation guide . brew install buildpacks/tap/pack","title":"Install Paketo(pack)"},{"location":"k8s/demo/cap_on_kyma/#install-rancher-desktop","text":"Download the Rancher Desktop installer for macOS from the release page . Refer to installation guide .","title":"Install Rancher Desktop"},{"location":"k8s/demo/cap_on_kyma/#download-tutorial","text":"Go to tutorial root directory and clone the code. git clone https://github.com/SAP-samples/cloud-cap-risk-management tutorial","title":"Download tutorial"},{"location":"k8s/demo/cap_on_kyma/#initialize-the-project","text":"Install required Node.js modules in the app directory cpapp . cd app cds init npm install cds watch","title":"Initialize the project"},{"location":"k8s/demo/cap_on_kyma/#add-files-to-the-project","text":"Copy the file schema.cds from templates/create-cap-application/db to the db folder of the app. It creates two entities in the namespace sap.ui.riskmanagement : Risks and Mitigations . Copy the file risk-service.cds from templates/create-cap-application/srv to the srv folder of the app. It creates a new service RiskService in the namespace sap.ui.riskmanagement . This service exposes two entities: Risks and Mitigations , which are exposing the entities of the database schema we've created in the step before. Copy the folder data from templates/create-cap-application/db to the db folder of the app. There are two comma-separated value (CSV) files that contain local data for both the Risks and the Mitigations entities. Use Fiori Application Generator (VSCode extension) to generate Risk UI with Fiori element template. The generation will create a risks and a webapp folder with a Component.js file in the app folder of the project. Copy the file risks-service-ui.cds from templates/create-ui-fiori-elements/srv to the srv folder of the app. It defines annotations to show a work list with some columns and the data from the service in the Risk UI. Edit app/risks/webapp/manifest.json file to make the header fields editable, that is, shows title and description in Risk UI. Copy the file risk-service.js from templates/cap-business-logic/srv to the srv folder of the app. It now shows the work list in Risk UI with the columns Priority and Impact with color and an icon, depending on the amount in Impact . Use Fiori Application Generator (VSCode extension) to generate Migration UI with Fiori free-style template. The generation will create a migrations and a webapp folder with a Component.js file in the app folder of the project. Update file cpapp/app/mitigations/webapp/view/Worklist.view.xml to show Description , Owner , and Timeline columns, as well as in detail object page. Till now, our risks and mitigations application have been generated by the SAP Fiori Tools Generator and can be started independently. They are launched without a launch page. Copy the file launchpage.html from templates/launchpage/app to the app folder of the app. There are two applications in the launch page with URLs that point to the respective apps. We now see the Mitigations app next to the Risks app on the launch page. Open the file srv/risk-service.cds and add role restrictions to entities. Copy the file templates/cap-roles/.cdsrc.json to the project directory cpapp . The file defines two users risk.viewer@tester.sap.com and risk.manager@tester.sap.com . The default password can be found in the file .cdsrc.json . We will see the CAP server to show above applications via link http://localhost:4004 .","title":"Add files to the project"},{"location":"k8s/demo/cap_on_kyma/#prepare-kyma-development-environment","text":"Execute cds version to make sure the package.json is using @sap/cds 6.0.1 or newer and we have @sap/cds-dk 6.0.1 or newer globally installed. Create namespace on Kyma. kubectl create namespace risk-management Switch to the namespace. kubectl config set-context --current --namespace risk-management Create container registry secret. Copy the folder scripts from templates/Kyma-Prepare-Dev-Environment to the project root folder cpapp . In the root folder cpapp of the project, run the script to create the secret. ./scripts/create-container-registry-secret.sh Need provide below input: docker-server = https://registry-1.docker.io docker-username = docker-email = docker-password = Verify kubectl get secret","title":"Prepare Kyma Development Environment"},{"location":"k8s/demo/cap_on_kyma/#set-up-sap-hana-cloud-for-kyma","text":"Add SAP HANA support to your project. This adds the db module for SAP HANA access to the package.json file. Execute the command below in the project root directory cpapp . cds add hana --for production Verify the access to both CF and Kyma by executing below commands. cf login kubectl cluster-info Create HANA Cloud instance cpapp-db in CloudFoundry DEV namespace. The admin user id is DBADMIN . In the root folder cpapp of the project, execute: ./scripts/create-db-secret.sh cpapp-db Get the host name pattern of the cluster with the following command. Result looks like *.c-.sap.kyma.ondemand.com . kubectl get gateway -n kyma-system kyma-gateway -o jsonpath = '{.spec.servers[0].hosts[0]}' The script will: Create service key cpapp-db-key for HANA Cloud service instance cpapp-db as . Create Kubernetes secret cpapp-db for HANA DB instance. View it using kubectl get secret cpapp-db -o yaml .","title":"Set Up SAP HANA Cloud for Kyma"},{"location":"k8s/demo/cap_on_kyma/#user-authentication-and-authorization-xsuaa-setup","text":"Set up XSUAA. cds add xsuaa --for production Above command will do: Adds the XSUAA service to the package.json file of the project Creates the XSUAA security configuration xs-security.json for the project","title":"User Authentication and Authorization (XSUAA) Setup"},{"location":"k8s/demo/cap_on_kyma/#add-helm-chart","text":"Add Helm Chart. cds add helm Get docker server URL by command: cat ~/.docker/config.json Get the image pull secret for container registry. In the demo, it's container-registry . kubectl get secret Get the host name pattern of the cluster. kubectl get gateway -n kyma-system kyma-gateway -o jsonpath = '{.spec.servers[0].hosts[0]}' Open the file chart/values.yaml : Replace the placeholder with docker server URL https://docker.io/ . Set imagePullSecret with value name: container-registry . Add host name of the cluster without leading *. . Add the binding db pointing to the SAP HANA Cloud instance secret cpapp-db . Point the binding hana of the SAP HANA Cloud instance secret cpapp-db . Add the Authorization and Trust Management service to allow user login.","title":"Add Helm Chart"},{"location":"k8s/demo/cap_on_kyma/#deploy-cap-application-to-kyma","text":"Build docker image. CONTAINER_REGISTRY = https://index.docker.io/v1 CONTAINER_REGISTRY = https://registry-1.docker.io/yuhuihu CONTAINER_REGISTRY = yuhuihu CAP build. cds build --production Build CAP service. pack build $CONTAINER_REGISTRY /cpapp-srv --path gen/srv \\ --buildpack gcr.io/paketo-buildpacks/nodejs \\ --builder paketobuildpacks/builder:base","title":"Deploy CAP Application to Kyma"},{"location":"linux/","text":"Content \u00b6 Memo Linux SRE is online training hosted by Magedu that I am taking part in. SUSE Linux Administration is the learning memo for certificate of SLES Administration. SUSE Enterprise Storage Foundation is the learning memo for certificate of SES Basic Ops and Data Access. Linux SRE SUSE Linux Adminstration SUSE Enterprise Storage Foundation","title":"Index"},{"location":"linux/#content","text":"Memo Linux SRE is online training hosted by Magedu that I am taking part in. SUSE Linux Administration is the learning memo for certificate of SLES Administration. SUSE Enterprise Storage Foundation is the learning memo for certificate of SES Basic Ops and Data Access. Linux SRE SUSE Linux Adminstration SUSE Enterprise Storage Foundation","title":"Content"},{"location":"linux/Administration/01/","text":"Linux File System Overview \u00b6 Linux File System Overview \u00b6 Filesystem Hierarchy Standard (FHS), which is part of the LSB (Linux Standards Base) specifications. The Root directory \"/\". Refers to the highest layer of the file system tree. This root partition is mounted first at system boot. All programs that are run at system startup must be in this partition. The following directories must be in the root partition: /bin - User binaries. \u57fa\u672c\u7a0b\u5e8f Contains executables required when no other file systems are mounted. For example, programs required for system booting, working with files and configuration. /bin/bash - The bash shell /bin/cat - Display file contents /bin/cp - Copy files /bin/dd - Copy files byte-wise /bin/gzip - Compress files /bin/mount - Mount file systems /bin/rm - Delete files /bin/vi - Edit files /sbin - System binaries. \u7cfb\u7edf\u7a0b\u5e8f Contains programs important for system administration. \u5b58\u653e\u7cfb\u7edf\u7ba1\u7406\u7684\u7a0b\u5e8f Typically are intended to be run by the root user and therefore it is not in the regular users path. \u9ed8\u8ba4\u662froot\u7528\u6237\u6709\u6743\u9650\u6267\u884c Some important files: /sbin/yast - Administration tool /sbin/fdisk* - Modifies partitions /sbin/fsck* - File system check \u4e0d\u80fd\u5728\u8fd0\u884c\u7684\u7cfb\u7edf\u4e0a\u9762\u76f4\u63a5\u6267\u884cfsck\uff0c\u635f\u574f\u6839\u6587\u4ef6\u7cfb\u7edf\uff0c\u9700\u8981umount /sbin/mkfs - Creates file systems /sbin/shutdown - Shuts down the system /dev - Device files Each system hardware component is represented (except network cards, which are kernel modules). \u4ee5\u592a\u7f51\u5361\u662f\u5185\u6838\u6a21\u5757\uff0c\u5176\u4ed6\u786c\u4ef6\u90fd\u4ee5\u8bbe\u5907dev\u7684\u65b9\u5f0f\u5c55\u73b0 Applications read from and write to these files to address hardware components. Two kinds of device files: Character-oriented \u2013 Sequential devices (printer, tape and mouse) \u5b57\u7b26\u8bbe\u5907 Block-oriented \u2013 Hard disks and DVDs \u5757\u8bbe\u5907 Connections to device drivers are implemented in the kernel using channels called major device numbers. \u4e0e\u8bbe\u5907\u9a71\u52a8\u7a0b\u5e8f\u7684\u8fde\u63a5\u901a\u8fc7\u5185\u6838\u4e2d\u79f0\u4e3a\u4e3b\u8bbe\u5907\u53f7\u7684\u901a\u9053\u5b9e\u73b0\u3002 When using ls -l the file size is replaced with the device numbers, such as 8, 0. In the past these files were created manually using the mknod command. Today they are created automatically (by udev) when the devices are discovered by the kernel. Some important device files: Null device: - /dev/null Zero device: - /dev/zero System Console: - /dev/console Virtual Terminal: - /dev/tty1 Serial ports - /dev/ttyS0 Parallel port: - /dev/lp0 Floppy disk drive: - /dev/fd0 Hard drive: - /dev/sda Hard disk partition: - /dev/sda1 CD-ROM drive: - /dev/scd0 /etc - Configuration files Contains system and services configuration files. \u5b58\u653e\u7cfb\u7edf\u548c\u670d\u52a1\u7684\u914d\u7f6e\u6587\u4ef6 Most of these files are ASCII files. \u5927\u90e8\u5206\u90fd\u662fASCII\u6587\u4ef6 Normal users can read most of these by default. This can be a security issue since some of these files contain passwords so it important that these files are only readable by the rootuser. \u666e\u901a\u7528\u6237\u53ef\u4ee5\u9ed8\u8ba4\u8bfb\u53d6\u5176\u4e2d\u7684\u5927\u90e8\u5206\u5185\u5bb9\u3002 \u8fd9\u53ef\u80fd\u662f\u4e00\u4e2a\u5b89\u5168\u95ee\u9898\uff0c\u56e0\u4e3a\u5176\u4e2d\u4e00\u4e9b\u6587\u4ef6\u5305\u542b\u5bc6\u7801\uff0c\u56e0\u6b64\u91cd\u8981\u7684\u662f\u8fd9\u4e9b\u6587\u4ef6\u53ea\u80fd\u7531root\u7528\u6237\u8bfb\u53d6 No executables can be put here according to the FHS, however subdirectories may contain shell scripts. \u6839\u636eFHS\uff0c\u6b64\u5904\u4e0d\u80fd\u653e\u7f6e\u4efb\u4f55\u53ef\u6267\u884c\u6587\u4ef6\uff0c\u4f46\u5b50\u76ee\u5f55\u53ef\u80fd\u5305\u542bshell\u811a\u672c\u3002 Almost every installed service has at least one configuration file in /etc or a subdirectory. \u51e0\u4e4e\u6bcf\u4e2a\u5df2\u5b89\u88c5\u7684\u670d\u52a1\u5728/ etc\u6216\u5b50\u76ee\u5f55\u4e2d\u81f3\u5c11\u6709\u4e00\u4e2a\u914d\u7f6e\u6587\u4ef6\u3002 Some important configuration files: /etc/SuSE-release - Version of installed system /etc/DIR_COLORS - Colors for the ls command /etc/fstab - For file systems to be mounted /etc/profile - Shell login script /etc/passwd - User database, except passwords /etc/shadow - Password and password info /etc/group - Database of user groups /etc/cups/* - For the CUPS printing system (CUPS=Common UNIX Printing System) /etc/hosts - Host names to IP addresses /etc/motd - Message after login /etc/issue - Message before login /etc/sysconfig/* - System configuration files /lib - Libraries. Many programs have common functions they need. The functions can be kept in a shared library. Libraries are called shared objects and end with the .so extension. \u5171\u4eab\u5e93 Libraries in /lib are used by programs in /bin and /sbin . There are additional libraries in subdirectories. Kernel modules are located in /lib/modules . /lib64 - 64-Bit Libraries. Similar to the /lib directory. This is an architecture dependent directory. Some systems support different binary formats and keep different versions of the same shared library. /usr - Contains application programs, graphical interface files, libraries, local programs, documentation and more. /usr means Unix System Resources. Examples: /usr/X11R6/ - X Window System Files /usr/bin/ - Almost all executables /usr/lib/ - Libraries and application directories /usr/local/ - Locally installed programs (i.e. on local system if /usr is mounted from the network). The content is not overwritten by system updates. \u4e0b\u97623\u4e2a\u76ee\u5f55\u5728\u521d\u59cb\u5b89\u88c5\u540e\u662f\u7a7a\u7684 /usr/local/bin - /usr/local/sbin - /usr/local/lib - /usr/sbin/ - System administration programs /usr/share/doc/ - Documentation /usr/src/ - Source code of kernel and programs /usr/src/linux - /usr/share/man/ - Manual pages /opt - Optional Application Directory Where optional or third party applications that are not considered to be \u201cpart of the distribution\u201d store their static files. Applications considered to be \u201cpart of the distribution\u201d are usually installed under /usr/lib/ rather than /opt . At installation a directory is created for each application's files with the name of the application. Example: /opt/novell - /boot - The Boot Directory /boot/grub2 - Contains static boot loader files for GRUB2. (GRUB = Grand Unified Boot Loader) Contains the kernel and initrd file identified with the links vmlinuz and initrd. /root - Administrator's Home Directory The root user's home directory. Not under /home with regular users' home directories. Needs to be in the root partition so that root can always log in with his configured environment. /home - User Directories Every system user has an assigned file area which becomes the current working directory after log in. By default they exist in /home . The files and directories in /home could be in a separate partition or on another computer on the network. The user profile and configuration files are found here: .profile - Private user login script .bashrc - Configuration file for bash .bash_history - Previous commands run in bash /run/media//* - Mount Point for Removable Media SLE 12 creates directories here for mounting removable media. The name depends on the device that is mounted/discovered. Examples: /run/media/media_name/ (Created if labeled media is inserted) /run/media/cdrom/ - /run/media/dvd/ - /run/media/usbdisk/ - /mnt - Temporarily Mounted File Systems \u6587\u4ef6\u7cfb\u7edf\u4e34\u65f6\u6302\u8f7d\u70b9 Standard directory for integrating file systems that are used temporarily. File systems are mounted using the mount command and removed using the umount command. Subdirectories do not exist by default and are not automatically created. /srv - Service Data Directories Contains subdirectories for various services. Examples: \u5b58\u653e\u5404\u79cd\u670d\u52a1\u7684\u6570\u636e /srv/www - for the Apache Web Server /srv/ftp - for an FTP server /var - Variable Files Contains files that can be modified while the system is running. \u5728\u7cfb\u7edf\u8fd0\u884c\u8fc7\u7a0b\u4e2d\u4f1a\u88ab\u4fee\u6539\u7684\u6587\u4ef6 Important subdirectories: /var/lib/ - Variable libraries, like databases \u53ef\u53d8\u5e93\u6587\u4ef6 /var/log/ - Services log files \u65e5\u5fd7\u6587\u4ef6 /var/run/ - Information on running processes \u8fd0\u884c\u4e2d\u7684\u7ebf\u7a0b\u7684\u4fe1\u606f /var/spool/ - Queues (printers, email) /var/spool/mail - /var/spool/cron - /var/lock/ - Lock files for multiuser access /var/cache - /var/mail - /tmp - Temporary Area Where programs create temporary files while they are running /proc - Process Files A virtual file system that exists only in memory and is used to display the current state of processes running on the system. (Takes no space - file size always 0) \u865a\u62df\u6587\u4ef6\u7cfb\u7edf\uff0c\u4e0d\u5360\u95f4\uff0c\u5927\u5c0f* \u59cb\u7ec8\u96f6\uff0c\u663e\u793a\u5f53\u524d\u8fdb\u7a0b\u7684\u72b6\u6001\u4fe1\u606f Directories containing information about individual processes are named according to the PID number of the process. Some values can be modified to change how things are running in real time. Any changes made are lost at reboot. Examples: \u6709\u4e9b\u503c\u53ef\u4ee5\u4e34\u65f6\u5728\u7ebf\u66f4\u6539\u751f\u6548\uff0c\u4f46\u91cd\u542f\u540e\u4e22\u5931 /proc/cpuinfo/ - Processor information /proc/dma/ - Use of DMA ports /proc/interrupts/ - Use of interrupts /proc/ioports/ - Use of I/O ports /proc/filesystems/ - File system formats the kernel knows /proc/modules/ - Active modules /proc/mounts/ - Mounted file systems /proc/net/* - Network information and statistics /proc/partitions/ - Existing partitions /proc/bus/pci/ - Connected PCI devices /proc/bus/scsi/ - Connected SCSI devices /proc/sys/* - System and kernel information /proc/version - Kernel version /sys - System Information Directory A virtual file system that exists only in memory. Takes no space so file size always 0 \u865a\u62df\u6587\u4ef6\u7cfb\u7edf Provides information on: hardware buses hardware devices active devices drivers Lab: Explore Filesystem Hierarchy \u00b6 Show the directory structure of the /data folder hierarchy of current logon user: mySUSE:~ # tree /data /data \u2514\u2500\u2500 linktype \u251c\u2500\u2500 file \u251c\u2500\u2500 hardlinkfile1 \u251c\u2500\u2500 hardlinkfile2 \u251c\u2500\u2500 symlinkfile1 -> file \u251c\u2500\u2500 symlinkfile1-1 -> symlinkfile1 \u2514\u2500\u2500 symlinkfile2 -> file Show only directories in the /data hierarchhy, not the files in them: mySUSE:~ # tree -d /data /data \u2514\u2500\u2500 linktype Show the files and directories in the /data hierarchy, including the full path and filename of each object. mySUSE:~ # tree -f /data /data \u2514\u2500\u2500 /data/linktype \u251c\u2500\u2500 /data/linktype/file \u251c\u2500\u2500 /data/linktype/hardlinkfile1 \u251c\u2500\u2500 /data/linktype/hardlinkfile2 \u251c\u2500\u2500 /data/linktype/symlinkfile1 -> file \u251c\u2500\u2500 /data/linktype/symlinkfile1-1 -> symlinkfile1 \u2514\u2500\u2500 /data/linktype/symlinkfile2 -> file Seven Different types of files \u00b6 Normal files , examples: ASCII text files Executable files Graphics files Directories Organize files on the disk Contain files and subdirectories Implement the hierarchical file system Links Hard links Secondary file names for files on the disk Multiple file names referencing a single inode Referenced file must reside in the same file system Symbolic links: References to other files on the disk The inode contains a reference to another file name .Referenced files can exist in the same file system or in other file systems A symbolic link can reference a non-existent file (broken link) Sockets - Used for two-way communication between processes. \u5957\u63a5\u5b57 Pipes (FIFOs) - Used for one-way communication from one process to another. \u7ba1\u9053 Block Devices \u5757\u8bbe\u5907 Character Devices \u5b57\u7b26\u8bbe\u5907 Linux Link Type \u00b6 Hard links : A hard link is a directory reference, or pointer, to a file on a storage volume. The name associated with the file is a label stored in a directory structure that refers the operating system to the file data. As such, more than one name can be associated with the same file. When accessed through different names, any changes made will affect the same file data. \u786c\u94fe\u63a5\u662f\u5b58\u50a8\u5377\u4e0a\u6587\u4ef6\u7684\u76ee\u5f55\u5f15\u7528\u6216\u6307\u9488\u3002 \u6587\u4ef6\u540d\u662f\u5b58\u50a8\u5728\u76ee\u5f55\u7ed3\u6784\u4e2d\u7684\u6807\u7b7e\uff0c\u76ee\u5f55\u7ed3\u6784\u6307\u5411\u6587\u4ef6\u6570\u636e\u3002 \u56e0\u6b64\uff0c\u53ef\u4ee5\u5c06\u591a\u4e2a\u6587\u4ef6\u540d\u4e0e\u540c\u4e00\u6587\u4ef6\u5173\u8054\u3002 \u901a\u8fc7\u4e0d\u540c\u7684\u6587\u4ef6\u540d\u8bbf\u95ee\u65f6\uff0c\u6240\u505a\u7684\u4efb\u4f55\u66f4\u6539\u90fd\u662f\u9488\u5bf9\u6e90\u6587\u4ef6\u6570\u636e\u3002 Symbolic links : A symbolic link contains a text string that is interpreted and followed by the operating system as a path to another file or directory. It is a file on its own and can exist independently of its target. If a symbolic link is deleted, its target remains unaffected. If the target is moved, renamed or deleted, any symbolic link that used to point to it continues to exist but now points to a non-existing file. \u7b26\u53f7\u94fe\u63a5\u5305\u542b\u4e00\u4e2a\u6587\u672c\u5b57\u7b26\u4e32\uff0c\u64cd\u4f5c\u7cfb\u7edf\u5c06\u5176\u89e3\u91ca\u5e76\u4f5c\u4e3a\u53e6\u4e00\u4e2a\u6587\u4ef6\u6216\u76ee\u5f55\u7684\u8def\u5f84\u3002 \u5b83\u672c\u8eab\u5c31\u662f\u4e00\u4e2a\u6587\u4ef6\uff0c\u53ef\u4ee5\u72ec\u7acb\u4e8e\u76ee\u6807\u800c\u5b58\u5728\u3002 \u5982\u679c\u5220\u9664\u4e86\u7b26\u53f7\u94fe\u63a5\uff0c\u5219\u5176\u76ee\u6807\u4e0d\u53d7\u5f71\u54cd\u3002 \u5982\u679c\u79fb\u52a8\uff0c\u91cd\u547d\u540d\u6216\u5220\u9664\u76ee\u6807\uff0c\u5219\u7528\u4e8e\u6307\u5411\u5b83\u7684\u4efb\u4f55\u7b26\u53f7\u94fe\u63a5\u5c06\u7ee7\u7eed\u5b58\u5728\uff0c\u4f46\u73b0\u5728\u6307\u5411\u4e0d\u5b58\u5728\u7684\u6587\u4ef6\u3002 Hard links can only be used when both the file and the link are in the same file system (on the same partition), because inode numbers are only unique within the same file system. You create a hard link by using the ln command, which points to the inode of an already existing file. Thereafter, the file can be accessed under both names\u2013that of the file and that of the link, and you can no longer discern which name existed first or how the original file and the link differ. \u4ec5\u5f53\u6587\u4ef6\u548c\u94fe\u63a5\u6587\u4ef6\u4f4d\u4e8e\u540c\u4e00\u6587\u4ef6\u7cfb\u7edf\uff08\u5728\u540c\u4e00\u5206\u533a\u4e0a\uff09\u65f6\uff0c\u624d\u80fd\u4f7f\u7528\u786c\u94fe\u63a5\uff0c\u56e0\u4e3ainode\u7f16\u53f7\u5728\u540c\u4e00\u6587\u4ef6\u7cfb\u7edf\u4e2d\u4ec5\u662f\u552f\u4e00\u7684\u3002 \u60a8\u53ef\u4ee5\u4f7f\u7528ln\u547d\u4ee4\u521b\u5efa\u786c\u94fe\u63a5\uff0c\u8be5\u547d\u4ee4\u6307\u5411\u5df2\u5b58\u5728\u6587\u4ef6\u7684inode\u3002 \u6b64\u540e\uff0c\u53ef\u4ee5\u5728\u6587\u4ef6\u7684\u540d\u79f0\u548c\u94fe\u63a5\u7684\u540d\u79f0\u4e0b\u8bbf\u95ee\u6587\u4ef6\uff0c\u5e76\u4e14\u65e0\u6cd5\u518d\u8bc6\u522b\u9996\u5148\u5b58\u5728\u7684\u540d\u79f0\u6216\u539f\u59cb\u6587\u4ef6\u548c\u94fe\u63a5\u7684\u4e0d\u540c\u4e4b\u5904\u3002 You can create a symbolic link with the ln command and the -s option. A symbolic link is assigned its own inode\u2014the link refers to a file, so a distinction can always be made between the link and the actual file. \u8f6f\u8fde\u63a5\u53ef\u4ee5\u9488\u5bf9\u76ee\u5f55\uff0c\u786c\u8fde\u63a5\u53ea\u80fd\u9488\u5bf9\u6587\u4ef6\u3002 A file system is essentially a database that is used to keep track of files in a volume. For normal files, data blocks are allocated to store the file's data, an inode is allocated to point to the data blocks as well as store the metadata about the file and then a file name is assigned to the inode. A hard link is a secondary file name associated with an existing inode. For symbolic links, a new inode is allocated with a new file name associated with it but the inode references another file name rather than referencing datablocks. \u6587\u4ef6\u7cfb\u7edf\u672c\u8d28\u4e0a\u662f\u4e00\u4e2a\u7528\u4e8e\u8ddf\u8e2a\u5377\u4e2d\u6587\u4ef6\u7684\u6570\u636e\u5e93\u3002 \u5bf9\u4e8e\u666e\u901a\u6587\u4ef6\uff0c\u5206\u914d\u6570\u636e\u5757\u4ee5\u5b58\u50a8\u6587\u4ef6\u7684\u6570\u636e\uff0c\u5206\u914dinode\u4ee5\u6307\u5411\u6570\u636e\u5757\u4ee5\u53ca\u5b58\u50a8\u5173\u4e8e\u6587\u4ef6\u7684\u5143\u6570\u636e\uff0c\u7136\u540e\u5c06\u6587\u4ef6\u540d\u5206\u914d\u7ed9inode\u3002 \u786c\u94fe\u63a5\u662f\u4e0e\u73b0\u6709inode\u5173\u8054\u7684\u8f85\u52a9\u6587\u4ef6\u540d\u3002 \u5bf9\u4e8e\u7b26\u53f7\u94fe\u63a5\uff0c\u5c06\u4e3a\u65b0\u7684inode\u5206\u914d\u4e00\u4e2a\u4e0e\u4e4b\u5173\u8054\u7684\u65b0\u6587\u4ef6\u540d\uff0c\u4f46inode\u5f15\u7528\u53e6\u4e00\u4e2a\u6587\u4ef6\u540d\u800c\u4e0d\u662f\u5f15\u7528\u6570\u636e\u5757\u3002 A good way to see the relationship between file names and inodes is to use the ls -il command. The typical size of an inode is 128 Bit and data blocks can range in size from 1k, 2k, 4k or larger depending on the file system type. \u67e5\u770b\u6587\u4ef6\u540d\u548cinode\u4e4b\u95f4\u5173\u7cfb\u7684\u597d\u65b9\u6cd5\u662f\u4f7f\u7528ls -il\u547d\u4ee4\u3002inode\u7684\u5178\u578b\u5927\u5c0f\u4e3a128\u4f4d\uff0c\u6570\u636e\u5757\u7684\u5927\u5c0f\u8303\u56f4\u53ef\u4ee5\u662f1k\uff0c2k\uff0c4k\u6216\u66f4\u5927\uff0c\u5177\u4f53\u53d6\u51b3\u4e8e\u6587\u4ef6\u7cfb\u7edf\u7c7b\u578b\u3002 \u786c\u94fe\u63a5\u76f8\u5f53\u4e8e\u589e\u52a0\u4e86\u4e00\u4e2a\u767b\u8bb0\u9879\uff0c\u4f7f\u5f97\u539f\u6765\u7684\u6587\u4ef6\u591a\u4e86\u4e00\u4e2a\u540d\u5b57\uff0c\u81f3\u4e8einode\u90fd\u6ca1\u53d8\u3002\u6240\u8c13\u7684\u767b\u8bb0\u9879\u5176\u5b9e\u662f\u76ee\u5f55\u6587\u4ef6\u4e2d\u7684\u4e00\u4e2a\u6761\u76ee(\u76ee\u5f55\u9879)\uff0c\u4f7f\u7528hard link \u662f\u8ba9\u591a\u4e2a\u4e0d\u540c\u7684\u76ee\u5f55\u9879\u6307\u5411\u540c\u4e00\u4e2a\u6587\u4ef6\u7684inode\uff0c\u6ca1\u6709\u591a\u4f59\u7684\u5185\u5bb9\u9700\u8981\u5b58\u50a8\u5728\u78c1\u76d8\u6247\u533a\u4e2d\uff0c\u6240\u4ee5hardlink\u4e0d\u5360\u7528\u989d\u5916\u7684\u7a7a\u95f4\u3002 \u7b26\u53f7\u94fe\u63a5\u6709\u5355\u72ec\u7684inode\uff0c\u5728inode\u4e2d\u5b58\u653e\u53e6\u4e00\u4e2a\u6587\u4ef6\u7684\u8def\u5f84\u800c\u4e0d\u662f\u6587\u4ef6\u6570\u636e\uff0c\u6240\u4ee5\u7b26\u53f7\u94fe\u63a5\u4f1a\u5360\u7528\u989d\u5916\u7684\u7a7a\u95f4\u3002 Lab: File Link Type \u00b6 Create original file mySUSE:/data/linktype # echo \"it's original file\" > file mySUSE:/data/linktype # l -rw-r--r-- 1 root root 19 Mar 28 15 :20 file Create hardlink file (\u6ce8\u610ffile\u3001hardlinkfile1\u3001hardlinkfile2\u7684link\u4f4d\u7f6e\u7684\u6570\u503c\u7684\u53d8\u5316[\u7ea2\u8272]) mySUSE:/data/linktype # ln file hardlinkfile1 mySUSE:/data/linktype # ln -s file symlinkfile1 mySUSE:/data/linktype # ln -s file symlinkfile2 mySUSE:/data/linktype # l -rw-r--r-- 2 root root 19 Mar 28 15 :20 file -rw-r--r-- 2 root root 19 Mar 28 15 :20 hardlinkfile1 lrwxrwxrwx 1 root root 4 Mar 28 15 :21 symlinkfile1 -> file lrwxrwxrwx 1 root root 4 Mar 28 15 :23 symlinkfile2 -> file mySUSE:/data/linktype # ln file hardlinkfile2 mySUSE:/data/linktype # l -rw-r--r-- 3 root root 19 Mar 28 15 :20 file ( \u5305\u62ec\u81ea\u5df1\uff0c\u4e00\u5171\u67093\u4e2a\u786c\u94fe\u63a5 ) -rw-r--r-- 3 root root 19 Mar 28 15 :20 hardlinkfile1 ( \u7ee7\u627f\u4e86\u539f\u6587\u4ef6\u7684\u786c\u94fe\u63a5\u6570\u91cf ) -rw-r--r-- 3 root root 19 Mar 28 15 :20 hardlinkfile2 ( \u7ee7\u627f\u4e86\u539f\u6587\u4ef6\u7684\u786c\u94fe\u63a5\u6570\u91cf ) lrwxrwxrwx 1 root root 4 Mar 28 15 :21 symlinkfile1 -> file lrwxrwxrwx 1 root root 4 Mar 28 15 :23 symlinkfile2 -> file Modify content of file (original file). Content change were shown in all hard/soft link files mySUSE:/data/linktype # echo \"add oneline\" >> file mySUSE:/data/linktype # cat file it 's original file add oneline mySUSE:/data/linktype # cat hardlinkfile1 it' s original file add oneline mySUSE:/data/linktype # cat hardlinkfile2 it 's original file add oneline mySUSE:/data/linktype # cat symlinkfile1 it' s original file add oneline mySUSE:/data/linktype # cat symlinkfile2 it ' s original file add oneline To view the value stored in a symbolic link use the command readlink. mySUSE:/data/linktype # ln -s symlinkfile1 symlinkfile1-1 mySUSE:/data/linktype # ls -il 258 -rw-r--r-- 3 root root 31 Mar 28 15 :42 file 258 -rw-r--r-- 3 root root 31 Mar 28 15 :42 hardlinkfile1 258 -rw-r--r-- 3 root root 31 Mar 28 15 :42 hardlinkfile2 259 lrwxrwxrwx 1 root root 4 Mar 28 15 :21 symlinkfile1 -> file 265 lrwxrwxrwx 1 root root 12 Mar 28 15 :49 symlinkfile1-1 -> symlinkfile1 260 lrwxrwxrwx 1 root root 4 Mar 28 15 :23 symlinkfile2 -> file mySUSE:/data/linktype # readlink symlinkfile1 file mySUSE:/data/linktype # readlink symlinkfile2 file mySUSE:/data/linktype # readlink symlinkfile1-1 symlinkfile1 ( \u6ce8\u610f\uff1a\u8fd9\u4ecd\u7136\u662f\u4e00\u4e2a\u7b26\u53f7\u94fe\u63a5\u6587\u4ef6 ) mySUSE:/data/linktype # readlink -f symlinkfile1-1(\u53c2\u6570-f\u53ef\u4ee5\u76f4\u63a5\u5b9a\u4f4d\u771f\u6b63\u7684\u6e90\u6587\u4ef6) /data/linktype/file ( \u6ce8\u610f\uff1a\u8fd9\u624d\u662f\u771f\u6b63\u7684\u539f\u6587\u4ef6 ) Linux Device File \u00b6 Represent hardware (except network cards). Each piece of hardware is represented by a device file. Network cards are interfaces. (\u533a\u522b) Link between hardware devices and the kernel drivers \u8bbe\u5907\u6587\u4ef6\u628a\u5185\u6838\u9a71\u52a8\u548c\u7269\u7406\u786c\u4ef6\u8bbe\u5907\u8fde\u63a5\u8d77\u6765 Kernel drivers read from and write to the device file \u5185\u6838\u9a71\u52a8\u7a0b\u5e8f\u5bf9\u8bbe\u5907\u6587\u4ef6\u8fdb\u884c\u8bfb\u5199\u6765\u5b9e\u73b0\u5bf9\u786c\u4ef6\u7684\u8bfb\u5199 The kernel gets the data to the actual hardware in the correct format \u5185\u6838\u4ee5\u6b63\u786e\u7684\u683c\u5f0f\u5bf9\u7269\u7406\u8bbe\u5907\u8fdb\u884c\u8bfb\u5199 Types: Block Devices. A block device reads/writes information in (normally) 512 byte large blocks. Character Devices. A character device reads/writes information character wise. Character devices provide unbuffered access directly to a hardware device. \u76f4\u63a5\u8bfb\u5199\uff0c\u4e0d\u901a\u8fc7\u7f13\u5b58 Sometimes referred to as raw devices. \u88f8\u8bbe\u5907\uff08\u6ce8\u610f\uff1a\u88f8\u8bbe\u5907\u88ab\u89c6\u4e3a\u5b57\u7b26\u8bbe\u5907\uff0c\u4e0d\u662f\u5757\u8bbe\u5907\uff09 any different options for character devices, making their use and application wide and varied. Created automatically by the OS (udev) when the device is discovered by the kernel. \u5185\u6838\u76f4\u63a5\u521b\u5efa\u5bf9\u5e94\u786c\u4ef6\u7684\u8bbe\u5907\u6587\u4ef6","title":"Linux File System Overview"},{"location":"linux/Administration/01/#linux-file-system-overview","text":"","title":"Linux File System Overview"},{"location":"linux/Administration/01/#linux-file-system-overview_1","text":"Filesystem Hierarchy Standard (FHS), which is part of the LSB (Linux Standards Base) specifications. The Root directory \"/\". Refers to the highest layer of the file system tree. This root partition is mounted first at system boot. All programs that are run at system startup must be in this partition. The following directories must be in the root partition: /bin - User binaries. \u57fa\u672c\u7a0b\u5e8f Contains executables required when no other file systems are mounted. For example, programs required for system booting, working with files and configuration. /bin/bash - The bash shell /bin/cat - Display file contents /bin/cp - Copy files /bin/dd - Copy files byte-wise /bin/gzip - Compress files /bin/mount - Mount file systems /bin/rm - Delete files /bin/vi - Edit files /sbin - System binaries. \u7cfb\u7edf\u7a0b\u5e8f Contains programs important for system administration. \u5b58\u653e\u7cfb\u7edf\u7ba1\u7406\u7684\u7a0b\u5e8f Typically are intended to be run by the root user and therefore it is not in the regular users path. \u9ed8\u8ba4\u662froot\u7528\u6237\u6709\u6743\u9650\u6267\u884c Some important files: /sbin/yast - Administration tool /sbin/fdisk* - Modifies partitions /sbin/fsck* - File system check \u4e0d\u80fd\u5728\u8fd0\u884c\u7684\u7cfb\u7edf\u4e0a\u9762\u76f4\u63a5\u6267\u884cfsck\uff0c\u635f\u574f\u6839\u6587\u4ef6\u7cfb\u7edf\uff0c\u9700\u8981umount /sbin/mkfs - Creates file systems /sbin/shutdown - Shuts down the system /dev - Device files Each system hardware component is represented (except network cards, which are kernel modules). \u4ee5\u592a\u7f51\u5361\u662f\u5185\u6838\u6a21\u5757\uff0c\u5176\u4ed6\u786c\u4ef6\u90fd\u4ee5\u8bbe\u5907dev\u7684\u65b9\u5f0f\u5c55\u73b0 Applications read from and write to these files to address hardware components. Two kinds of device files: Character-oriented \u2013 Sequential devices (printer, tape and mouse) \u5b57\u7b26\u8bbe\u5907 Block-oriented \u2013 Hard disks and DVDs \u5757\u8bbe\u5907 Connections to device drivers are implemented in the kernel using channels called major device numbers. \u4e0e\u8bbe\u5907\u9a71\u52a8\u7a0b\u5e8f\u7684\u8fde\u63a5\u901a\u8fc7\u5185\u6838\u4e2d\u79f0\u4e3a\u4e3b\u8bbe\u5907\u53f7\u7684\u901a\u9053\u5b9e\u73b0\u3002 When using ls -l the file size is replaced with the device numbers, such as 8, 0. In the past these files were created manually using the mknod command. Today they are created automatically (by udev) when the devices are discovered by the kernel. Some important device files: Null device: - /dev/null Zero device: - /dev/zero System Console: - /dev/console Virtual Terminal: - /dev/tty1 Serial ports - /dev/ttyS0 Parallel port: - /dev/lp0 Floppy disk drive: - /dev/fd0 Hard drive: - /dev/sda Hard disk partition: - /dev/sda1 CD-ROM drive: - /dev/scd0 /etc - Configuration files Contains system and services configuration files. \u5b58\u653e\u7cfb\u7edf\u548c\u670d\u52a1\u7684\u914d\u7f6e\u6587\u4ef6 Most of these files are ASCII files. \u5927\u90e8\u5206\u90fd\u662fASCII\u6587\u4ef6 Normal users can read most of these by default. This can be a security issue since some of these files contain passwords so it important that these files are only readable by the rootuser. \u666e\u901a\u7528\u6237\u53ef\u4ee5\u9ed8\u8ba4\u8bfb\u53d6\u5176\u4e2d\u7684\u5927\u90e8\u5206\u5185\u5bb9\u3002 \u8fd9\u53ef\u80fd\u662f\u4e00\u4e2a\u5b89\u5168\u95ee\u9898\uff0c\u56e0\u4e3a\u5176\u4e2d\u4e00\u4e9b\u6587\u4ef6\u5305\u542b\u5bc6\u7801\uff0c\u56e0\u6b64\u91cd\u8981\u7684\u662f\u8fd9\u4e9b\u6587\u4ef6\u53ea\u80fd\u7531root\u7528\u6237\u8bfb\u53d6 No executables can be put here according to the FHS, however subdirectories may contain shell scripts. \u6839\u636eFHS\uff0c\u6b64\u5904\u4e0d\u80fd\u653e\u7f6e\u4efb\u4f55\u53ef\u6267\u884c\u6587\u4ef6\uff0c\u4f46\u5b50\u76ee\u5f55\u53ef\u80fd\u5305\u542bshell\u811a\u672c\u3002 Almost every installed service has at least one configuration file in /etc or a subdirectory. \u51e0\u4e4e\u6bcf\u4e2a\u5df2\u5b89\u88c5\u7684\u670d\u52a1\u5728/ etc\u6216\u5b50\u76ee\u5f55\u4e2d\u81f3\u5c11\u6709\u4e00\u4e2a\u914d\u7f6e\u6587\u4ef6\u3002 Some important configuration files: /etc/SuSE-release - Version of installed system /etc/DIR_COLORS - Colors for the ls command /etc/fstab - For file systems to be mounted /etc/profile - Shell login script /etc/passwd - User database, except passwords /etc/shadow - Password and password info /etc/group - Database of user groups /etc/cups/* - For the CUPS printing system (CUPS=Common UNIX Printing System) /etc/hosts - Host names to IP addresses /etc/motd - Message after login /etc/issue - Message before login /etc/sysconfig/* - System configuration files /lib - Libraries. Many programs have common functions they need. The functions can be kept in a shared library. Libraries are called shared objects and end with the .so extension. \u5171\u4eab\u5e93 Libraries in /lib are used by programs in /bin and /sbin . There are additional libraries in subdirectories. Kernel modules are located in /lib/modules . /lib64 - 64-Bit Libraries. Similar to the /lib directory. This is an architecture dependent directory. Some systems support different binary formats and keep different versions of the same shared library. /usr - Contains application programs, graphical interface files, libraries, local programs, documentation and more. /usr means Unix System Resources. Examples: /usr/X11R6/ - X Window System Files /usr/bin/ - Almost all executables /usr/lib/ - Libraries and application directories /usr/local/ - Locally installed programs (i.e. on local system if /usr is mounted from the network). The content is not overwritten by system updates. \u4e0b\u97623\u4e2a\u76ee\u5f55\u5728\u521d\u59cb\u5b89\u88c5\u540e\u662f\u7a7a\u7684 /usr/local/bin - /usr/local/sbin - /usr/local/lib - /usr/sbin/ - System administration programs /usr/share/doc/ - Documentation /usr/src/ - Source code of kernel and programs /usr/src/linux - /usr/share/man/ - Manual pages /opt - Optional Application Directory Where optional or third party applications that are not considered to be \u201cpart of the distribution\u201d store their static files. Applications considered to be \u201cpart of the distribution\u201d are usually installed under /usr/lib/ rather than /opt . At installation a directory is created for each application's files with the name of the application. Example: /opt/novell - /boot - The Boot Directory /boot/grub2 - Contains static boot loader files for GRUB2. (GRUB = Grand Unified Boot Loader) Contains the kernel and initrd file identified with the links vmlinuz and initrd. /root - Administrator's Home Directory The root user's home directory. Not under /home with regular users' home directories. Needs to be in the root partition so that root can always log in with his configured environment. /home - User Directories Every system user has an assigned file area which becomes the current working directory after log in. By default they exist in /home . The files and directories in /home could be in a separate partition or on another computer on the network. The user profile and configuration files are found here: .profile - Private user login script .bashrc - Configuration file for bash .bash_history - Previous commands run in bash /run/media//* - Mount Point for Removable Media SLE 12 creates directories here for mounting removable media. The name depends on the device that is mounted/discovered. Examples: /run/media/media_name/ (Created if labeled media is inserted) /run/media/cdrom/ - /run/media/dvd/ - /run/media/usbdisk/ - /mnt - Temporarily Mounted File Systems \u6587\u4ef6\u7cfb\u7edf\u4e34\u65f6\u6302\u8f7d\u70b9 Standard directory for integrating file systems that are used temporarily. File systems are mounted using the mount command and removed using the umount command. Subdirectories do not exist by default and are not automatically created. /srv - Service Data Directories Contains subdirectories for various services. Examples: \u5b58\u653e\u5404\u79cd\u670d\u52a1\u7684\u6570\u636e /srv/www - for the Apache Web Server /srv/ftp - for an FTP server /var - Variable Files Contains files that can be modified while the system is running. \u5728\u7cfb\u7edf\u8fd0\u884c\u8fc7\u7a0b\u4e2d\u4f1a\u88ab\u4fee\u6539\u7684\u6587\u4ef6 Important subdirectories: /var/lib/ - Variable libraries, like databases \u53ef\u53d8\u5e93\u6587\u4ef6 /var/log/ - Services log files \u65e5\u5fd7\u6587\u4ef6 /var/run/ - Information on running processes \u8fd0\u884c\u4e2d\u7684\u7ebf\u7a0b\u7684\u4fe1\u606f /var/spool/ - Queues (printers, email) /var/spool/mail - /var/spool/cron - /var/lock/ - Lock files for multiuser access /var/cache - /var/mail - /tmp - Temporary Area Where programs create temporary files while they are running /proc - Process Files A virtual file system that exists only in memory and is used to display the current state of processes running on the system. (Takes no space - file size always 0) \u865a\u62df\u6587\u4ef6\u7cfb\u7edf\uff0c\u4e0d\u5360\u95f4\uff0c\u5927\u5c0f* \u59cb\u7ec8\u96f6\uff0c\u663e\u793a\u5f53\u524d\u8fdb\u7a0b\u7684\u72b6\u6001\u4fe1\u606f Directories containing information about individual processes are named according to the PID number of the process. Some values can be modified to change how things are running in real time. Any changes made are lost at reboot. Examples: \u6709\u4e9b\u503c\u53ef\u4ee5\u4e34\u65f6\u5728\u7ebf\u66f4\u6539\u751f\u6548\uff0c\u4f46\u91cd\u542f\u540e\u4e22\u5931 /proc/cpuinfo/ - Processor information /proc/dma/ - Use of DMA ports /proc/interrupts/ - Use of interrupts /proc/ioports/ - Use of I/O ports /proc/filesystems/ - File system formats the kernel knows /proc/modules/ - Active modules /proc/mounts/ - Mounted file systems /proc/net/* - Network information and statistics /proc/partitions/ - Existing partitions /proc/bus/pci/ - Connected PCI devices /proc/bus/scsi/ - Connected SCSI devices /proc/sys/* - System and kernel information /proc/version - Kernel version /sys - System Information Directory A virtual file system that exists only in memory. Takes no space so file size always 0 \u865a\u62df\u6587\u4ef6\u7cfb\u7edf Provides information on: hardware buses hardware devices active devices drivers","title":"Linux File System Overview"},{"location":"linux/Administration/01/#lab-explore-filesystem-hierarchy","text":"Show the directory structure of the /data folder hierarchy of current logon user: mySUSE:~ # tree /data /data \u2514\u2500\u2500 linktype \u251c\u2500\u2500 file \u251c\u2500\u2500 hardlinkfile1 \u251c\u2500\u2500 hardlinkfile2 \u251c\u2500\u2500 symlinkfile1 -> file \u251c\u2500\u2500 symlinkfile1-1 -> symlinkfile1 \u2514\u2500\u2500 symlinkfile2 -> file Show only directories in the /data hierarchhy, not the files in them: mySUSE:~ # tree -d /data /data \u2514\u2500\u2500 linktype Show the files and directories in the /data hierarchy, including the full path and filename of each object. mySUSE:~ # tree -f /data /data \u2514\u2500\u2500 /data/linktype \u251c\u2500\u2500 /data/linktype/file \u251c\u2500\u2500 /data/linktype/hardlinkfile1 \u251c\u2500\u2500 /data/linktype/hardlinkfile2 \u251c\u2500\u2500 /data/linktype/symlinkfile1 -> file \u251c\u2500\u2500 /data/linktype/symlinkfile1-1 -> symlinkfile1 \u2514\u2500\u2500 /data/linktype/symlinkfile2 -> file","title":"Lab: Explore Filesystem Hierarchy"},{"location":"linux/Administration/01/#seven-different-types-of-files","text":"Normal files , examples: ASCII text files Executable files Graphics files Directories Organize files on the disk Contain files and subdirectories Implement the hierarchical file system Links Hard links Secondary file names for files on the disk Multiple file names referencing a single inode Referenced file must reside in the same file system Symbolic links: References to other files on the disk The inode contains a reference to another file name .Referenced files can exist in the same file system or in other file systems A symbolic link can reference a non-existent file (broken link) Sockets - Used for two-way communication between processes. \u5957\u63a5\u5b57 Pipes (FIFOs) - Used for one-way communication from one process to another. \u7ba1\u9053 Block Devices \u5757\u8bbe\u5907 Character Devices \u5b57\u7b26\u8bbe\u5907","title":"Seven Different types of files"},{"location":"linux/Administration/01/#linux-link-type","text":"Hard links : A hard link is a directory reference, or pointer, to a file on a storage volume. The name associated with the file is a label stored in a directory structure that refers the operating system to the file data. As such, more than one name can be associated with the same file. When accessed through different names, any changes made will affect the same file data. \u786c\u94fe\u63a5\u662f\u5b58\u50a8\u5377\u4e0a\u6587\u4ef6\u7684\u76ee\u5f55\u5f15\u7528\u6216\u6307\u9488\u3002 \u6587\u4ef6\u540d\u662f\u5b58\u50a8\u5728\u76ee\u5f55\u7ed3\u6784\u4e2d\u7684\u6807\u7b7e\uff0c\u76ee\u5f55\u7ed3\u6784\u6307\u5411\u6587\u4ef6\u6570\u636e\u3002 \u56e0\u6b64\uff0c\u53ef\u4ee5\u5c06\u591a\u4e2a\u6587\u4ef6\u540d\u4e0e\u540c\u4e00\u6587\u4ef6\u5173\u8054\u3002 \u901a\u8fc7\u4e0d\u540c\u7684\u6587\u4ef6\u540d\u8bbf\u95ee\u65f6\uff0c\u6240\u505a\u7684\u4efb\u4f55\u66f4\u6539\u90fd\u662f\u9488\u5bf9\u6e90\u6587\u4ef6\u6570\u636e\u3002 Symbolic links : A symbolic link contains a text string that is interpreted and followed by the operating system as a path to another file or directory. It is a file on its own and can exist independently of its target. If a symbolic link is deleted, its target remains unaffected. If the target is moved, renamed or deleted, any symbolic link that used to point to it continues to exist but now points to a non-existing file. \u7b26\u53f7\u94fe\u63a5\u5305\u542b\u4e00\u4e2a\u6587\u672c\u5b57\u7b26\u4e32\uff0c\u64cd\u4f5c\u7cfb\u7edf\u5c06\u5176\u89e3\u91ca\u5e76\u4f5c\u4e3a\u53e6\u4e00\u4e2a\u6587\u4ef6\u6216\u76ee\u5f55\u7684\u8def\u5f84\u3002 \u5b83\u672c\u8eab\u5c31\u662f\u4e00\u4e2a\u6587\u4ef6\uff0c\u53ef\u4ee5\u72ec\u7acb\u4e8e\u76ee\u6807\u800c\u5b58\u5728\u3002 \u5982\u679c\u5220\u9664\u4e86\u7b26\u53f7\u94fe\u63a5\uff0c\u5219\u5176\u76ee\u6807\u4e0d\u53d7\u5f71\u54cd\u3002 \u5982\u679c\u79fb\u52a8\uff0c\u91cd\u547d\u540d\u6216\u5220\u9664\u76ee\u6807\uff0c\u5219\u7528\u4e8e\u6307\u5411\u5b83\u7684\u4efb\u4f55\u7b26\u53f7\u94fe\u63a5\u5c06\u7ee7\u7eed\u5b58\u5728\uff0c\u4f46\u73b0\u5728\u6307\u5411\u4e0d\u5b58\u5728\u7684\u6587\u4ef6\u3002 Hard links can only be used when both the file and the link are in the same file system (on the same partition), because inode numbers are only unique within the same file system. You create a hard link by using the ln command, which points to the inode of an already existing file. Thereafter, the file can be accessed under both names\u2013that of the file and that of the link, and you can no longer discern which name existed first or how the original file and the link differ. \u4ec5\u5f53\u6587\u4ef6\u548c\u94fe\u63a5\u6587\u4ef6\u4f4d\u4e8e\u540c\u4e00\u6587\u4ef6\u7cfb\u7edf\uff08\u5728\u540c\u4e00\u5206\u533a\u4e0a\uff09\u65f6\uff0c\u624d\u80fd\u4f7f\u7528\u786c\u94fe\u63a5\uff0c\u56e0\u4e3ainode\u7f16\u53f7\u5728\u540c\u4e00\u6587\u4ef6\u7cfb\u7edf\u4e2d\u4ec5\u662f\u552f\u4e00\u7684\u3002 \u60a8\u53ef\u4ee5\u4f7f\u7528ln\u547d\u4ee4\u521b\u5efa\u786c\u94fe\u63a5\uff0c\u8be5\u547d\u4ee4\u6307\u5411\u5df2\u5b58\u5728\u6587\u4ef6\u7684inode\u3002 \u6b64\u540e\uff0c\u53ef\u4ee5\u5728\u6587\u4ef6\u7684\u540d\u79f0\u548c\u94fe\u63a5\u7684\u540d\u79f0\u4e0b\u8bbf\u95ee\u6587\u4ef6\uff0c\u5e76\u4e14\u65e0\u6cd5\u518d\u8bc6\u522b\u9996\u5148\u5b58\u5728\u7684\u540d\u79f0\u6216\u539f\u59cb\u6587\u4ef6\u548c\u94fe\u63a5\u7684\u4e0d\u540c\u4e4b\u5904\u3002 You can create a symbolic link with the ln command and the -s option. A symbolic link is assigned its own inode\u2014the link refers to a file, so a distinction can always be made between the link and the actual file. \u8f6f\u8fde\u63a5\u53ef\u4ee5\u9488\u5bf9\u76ee\u5f55\uff0c\u786c\u8fde\u63a5\u53ea\u80fd\u9488\u5bf9\u6587\u4ef6\u3002 A file system is essentially a database that is used to keep track of files in a volume. For normal files, data blocks are allocated to store the file's data, an inode is allocated to point to the data blocks as well as store the metadata about the file and then a file name is assigned to the inode. A hard link is a secondary file name associated with an existing inode. For symbolic links, a new inode is allocated with a new file name associated with it but the inode references another file name rather than referencing datablocks. \u6587\u4ef6\u7cfb\u7edf\u672c\u8d28\u4e0a\u662f\u4e00\u4e2a\u7528\u4e8e\u8ddf\u8e2a\u5377\u4e2d\u6587\u4ef6\u7684\u6570\u636e\u5e93\u3002 \u5bf9\u4e8e\u666e\u901a\u6587\u4ef6\uff0c\u5206\u914d\u6570\u636e\u5757\u4ee5\u5b58\u50a8\u6587\u4ef6\u7684\u6570\u636e\uff0c\u5206\u914dinode\u4ee5\u6307\u5411\u6570\u636e\u5757\u4ee5\u53ca\u5b58\u50a8\u5173\u4e8e\u6587\u4ef6\u7684\u5143\u6570\u636e\uff0c\u7136\u540e\u5c06\u6587\u4ef6\u540d\u5206\u914d\u7ed9inode\u3002 \u786c\u94fe\u63a5\u662f\u4e0e\u73b0\u6709inode\u5173\u8054\u7684\u8f85\u52a9\u6587\u4ef6\u540d\u3002 \u5bf9\u4e8e\u7b26\u53f7\u94fe\u63a5\uff0c\u5c06\u4e3a\u65b0\u7684inode\u5206\u914d\u4e00\u4e2a\u4e0e\u4e4b\u5173\u8054\u7684\u65b0\u6587\u4ef6\u540d\uff0c\u4f46inode\u5f15\u7528\u53e6\u4e00\u4e2a\u6587\u4ef6\u540d\u800c\u4e0d\u662f\u5f15\u7528\u6570\u636e\u5757\u3002 A good way to see the relationship between file names and inodes is to use the ls -il command. The typical size of an inode is 128 Bit and data blocks can range in size from 1k, 2k, 4k or larger depending on the file system type. \u67e5\u770b\u6587\u4ef6\u540d\u548cinode\u4e4b\u95f4\u5173\u7cfb\u7684\u597d\u65b9\u6cd5\u662f\u4f7f\u7528ls -il\u547d\u4ee4\u3002inode\u7684\u5178\u578b\u5927\u5c0f\u4e3a128\u4f4d\uff0c\u6570\u636e\u5757\u7684\u5927\u5c0f\u8303\u56f4\u53ef\u4ee5\u662f1k\uff0c2k\uff0c4k\u6216\u66f4\u5927\uff0c\u5177\u4f53\u53d6\u51b3\u4e8e\u6587\u4ef6\u7cfb\u7edf\u7c7b\u578b\u3002 \u786c\u94fe\u63a5\u76f8\u5f53\u4e8e\u589e\u52a0\u4e86\u4e00\u4e2a\u767b\u8bb0\u9879\uff0c\u4f7f\u5f97\u539f\u6765\u7684\u6587\u4ef6\u591a\u4e86\u4e00\u4e2a\u540d\u5b57\uff0c\u81f3\u4e8einode\u90fd\u6ca1\u53d8\u3002\u6240\u8c13\u7684\u767b\u8bb0\u9879\u5176\u5b9e\u662f\u76ee\u5f55\u6587\u4ef6\u4e2d\u7684\u4e00\u4e2a\u6761\u76ee(\u76ee\u5f55\u9879)\uff0c\u4f7f\u7528hard link \u662f\u8ba9\u591a\u4e2a\u4e0d\u540c\u7684\u76ee\u5f55\u9879\u6307\u5411\u540c\u4e00\u4e2a\u6587\u4ef6\u7684inode\uff0c\u6ca1\u6709\u591a\u4f59\u7684\u5185\u5bb9\u9700\u8981\u5b58\u50a8\u5728\u78c1\u76d8\u6247\u533a\u4e2d\uff0c\u6240\u4ee5hardlink\u4e0d\u5360\u7528\u989d\u5916\u7684\u7a7a\u95f4\u3002 \u7b26\u53f7\u94fe\u63a5\u6709\u5355\u72ec\u7684inode\uff0c\u5728inode\u4e2d\u5b58\u653e\u53e6\u4e00\u4e2a\u6587\u4ef6\u7684\u8def\u5f84\u800c\u4e0d\u662f\u6587\u4ef6\u6570\u636e\uff0c\u6240\u4ee5\u7b26\u53f7\u94fe\u63a5\u4f1a\u5360\u7528\u989d\u5916\u7684\u7a7a\u95f4\u3002","title":"Linux Link Type"},{"location":"linux/Administration/01/#lab-file-link-type","text":"Create original file mySUSE:/data/linktype # echo \"it's original file\" > file mySUSE:/data/linktype # l -rw-r--r-- 1 root root 19 Mar 28 15 :20 file Create hardlink file (\u6ce8\u610ffile\u3001hardlinkfile1\u3001hardlinkfile2\u7684link\u4f4d\u7f6e\u7684\u6570\u503c\u7684\u53d8\u5316[\u7ea2\u8272]) mySUSE:/data/linktype # ln file hardlinkfile1 mySUSE:/data/linktype # ln -s file symlinkfile1 mySUSE:/data/linktype # ln -s file symlinkfile2 mySUSE:/data/linktype # l -rw-r--r-- 2 root root 19 Mar 28 15 :20 file -rw-r--r-- 2 root root 19 Mar 28 15 :20 hardlinkfile1 lrwxrwxrwx 1 root root 4 Mar 28 15 :21 symlinkfile1 -> file lrwxrwxrwx 1 root root 4 Mar 28 15 :23 symlinkfile2 -> file mySUSE:/data/linktype # ln file hardlinkfile2 mySUSE:/data/linktype # l -rw-r--r-- 3 root root 19 Mar 28 15 :20 file ( \u5305\u62ec\u81ea\u5df1\uff0c\u4e00\u5171\u67093\u4e2a\u786c\u94fe\u63a5 ) -rw-r--r-- 3 root root 19 Mar 28 15 :20 hardlinkfile1 ( \u7ee7\u627f\u4e86\u539f\u6587\u4ef6\u7684\u786c\u94fe\u63a5\u6570\u91cf ) -rw-r--r-- 3 root root 19 Mar 28 15 :20 hardlinkfile2 ( \u7ee7\u627f\u4e86\u539f\u6587\u4ef6\u7684\u786c\u94fe\u63a5\u6570\u91cf ) lrwxrwxrwx 1 root root 4 Mar 28 15 :21 symlinkfile1 -> file lrwxrwxrwx 1 root root 4 Mar 28 15 :23 symlinkfile2 -> file Modify content of file (original file). Content change were shown in all hard/soft link files mySUSE:/data/linktype # echo \"add oneline\" >> file mySUSE:/data/linktype # cat file it 's original file add oneline mySUSE:/data/linktype # cat hardlinkfile1 it' s original file add oneline mySUSE:/data/linktype # cat hardlinkfile2 it 's original file add oneline mySUSE:/data/linktype # cat symlinkfile1 it' s original file add oneline mySUSE:/data/linktype # cat symlinkfile2 it ' s original file add oneline To view the value stored in a symbolic link use the command readlink. mySUSE:/data/linktype # ln -s symlinkfile1 symlinkfile1-1 mySUSE:/data/linktype # ls -il 258 -rw-r--r-- 3 root root 31 Mar 28 15 :42 file 258 -rw-r--r-- 3 root root 31 Mar 28 15 :42 hardlinkfile1 258 -rw-r--r-- 3 root root 31 Mar 28 15 :42 hardlinkfile2 259 lrwxrwxrwx 1 root root 4 Mar 28 15 :21 symlinkfile1 -> file 265 lrwxrwxrwx 1 root root 12 Mar 28 15 :49 symlinkfile1-1 -> symlinkfile1 260 lrwxrwxrwx 1 root root 4 Mar 28 15 :23 symlinkfile2 -> file mySUSE:/data/linktype # readlink symlinkfile1 file mySUSE:/data/linktype # readlink symlinkfile2 file mySUSE:/data/linktype # readlink symlinkfile1-1 symlinkfile1 ( \u6ce8\u610f\uff1a\u8fd9\u4ecd\u7136\u662f\u4e00\u4e2a\u7b26\u53f7\u94fe\u63a5\u6587\u4ef6 ) mySUSE:/data/linktype # readlink -f symlinkfile1-1(\u53c2\u6570-f\u53ef\u4ee5\u76f4\u63a5\u5b9a\u4f4d\u771f\u6b63\u7684\u6e90\u6587\u4ef6) /data/linktype/file ( \u6ce8\u610f\uff1a\u8fd9\u624d\u662f\u771f\u6b63\u7684\u539f\u6587\u4ef6 )","title":"Lab: File Link Type"},{"location":"linux/Administration/01/#linux-device-file","text":"Represent hardware (except network cards). Each piece of hardware is represented by a device file. Network cards are interfaces. (\u533a\u522b) Link between hardware devices and the kernel drivers \u8bbe\u5907\u6587\u4ef6\u628a\u5185\u6838\u9a71\u52a8\u548c\u7269\u7406\u786c\u4ef6\u8bbe\u5907\u8fde\u63a5\u8d77\u6765 Kernel drivers read from and write to the device file \u5185\u6838\u9a71\u52a8\u7a0b\u5e8f\u5bf9\u8bbe\u5907\u6587\u4ef6\u8fdb\u884c\u8bfb\u5199\u6765\u5b9e\u73b0\u5bf9\u786c\u4ef6\u7684\u8bfb\u5199 The kernel gets the data to the actual hardware in the correct format \u5185\u6838\u4ee5\u6b63\u786e\u7684\u683c\u5f0f\u5bf9\u7269\u7406\u8bbe\u5907\u8fdb\u884c\u8bfb\u5199 Types: Block Devices. A block device reads/writes information in (normally) 512 byte large blocks. Character Devices. A character device reads/writes information character wise. Character devices provide unbuffered access directly to a hardware device. \u76f4\u63a5\u8bfb\u5199\uff0c\u4e0d\u901a\u8fc7\u7f13\u5b58 Sometimes referred to as raw devices. \u88f8\u8bbe\u5907\uff08\u6ce8\u610f\uff1a\u88f8\u8bbe\u5907\u88ab\u89c6\u4e3a\u5b57\u7b26\u8bbe\u5907\uff0c\u4e0d\u662f\u5757\u8bbe\u5907\uff09 any different options for character devices, making their use and application wide and varied. Created automatically by the OS (udev) when the device is discovered by the kernel. \u5185\u6838\u76f4\u63a5\u521b\u5efa\u5bf9\u5e94\u786c\u4ef6\u7684\u8bbe\u5907\u6587\u4ef6","title":"Linux Device File"},{"location":"linux/Administration/02/","text":"Useful Commands \u00b6 Some common abbreviations \u00b6 Abbreviations Description . represents the current directory .. represents the parent directory ~ represents the home directory ~username represents the home directory of user username Software package documentation \u00b6 /usr/share/doc/packages/ Release Notes \u00b6 /usr/share/doc/release-notes/ Command help \u00b6 -h or --help # tree --help Manual pages \u00b6 man [ section ] command # man 5 crontab # man /sestion options Show tree command manual: # man tree List for keywords: # man -k keyword Force mandb to update. Normally this is done daily via a cron job. # mandb Search for all instances of a command or a file named crontab # man -f crontab # whatis crontab (same output with above command) # man -k crontab # apropos crontab (same output with above command) To go directly to a given man page: # man 5 crontab * 1G : go to the 1 st line * 10G : go to the 10 th line * G : go to the end of the page * /^SELinux : search the word SELinux * /section OPTIONS : go to the section OPTIONS man\u5171\u6709\u4ee5\u4e0b\u51e0\u4e2a\u7ae0\u8282\uff0c\u6bd4\u5982\uff0cman 5 crontab\u5c31\u662f\u8fdb\u5165crontab\u7684\u7b2c5\u7ae0\u8282\uff1a Executable programs or shell commands \uff08\u6807\u51c6\u547d\u4ee4\uff09 System calls (functions provided by the kernel)\uff08\u7cfb\u7edf\u8c03\u7528\uff09 Library calls (functions within program libraries)\uff08\u5e93\u51fd\u6570\uff09 Special files (usually found in /dev)\uff08\u8bbe\u5907\u8bf4\u660e\uff09 File formats and conventions eg /etc/passwd \uff08\u6587\u4ef6\u683c\u5f0f\uff09 Games \uff08\u6e38\u620f\u548c\u5a31\u4e50\uff09 Miscellaneous (including macro packages and conventions)\uff08\u6742\u9879\uff0c\u60ef\u4f8b\u4e0e\u534f\u5b9a\u7b49\u7f51\u7edc\u534f\u5b9a\u3001ASCII code\u7b49\u7b49\u7684\u8aaa\u660e\uff09 System administration commands (usually only for root) \uff08\u7ba1\u7406\u5458\u547d\u4ee4\uff09 Kernel routines [Non standard] \uff08\u5176\u4ed6Linux\u7279\u5b9a\u7684\uff0c\u7528\u6765\u5b58\u653e\u5185\u6838\u4f8b\u884c\u7a0b\u5e8f\u7684\u6587\u6863\u3002\uff09 man\u5e38\u7528\u5feb\u6377\u952e \u7ffb\u5c4f \u5411\u540e\u7ffb\u4e00\u5c4f\uff1aspace(\u7a7a\u683c\u952e) \u5411\u524d\u7ffb\u4e00\u5c4f\uff1ab \u5411\u540e\u7ffb\u4e00\u884c\uff1aEnter(\u56de\u8f66\u952e) \u5411\u524d\u7ffb\u4e00\u884c\uff1ak \u67e5\u627e /\u5173\u952e\u8bcd ?\u5173\u952e\u8bcd n (\u4e0b\u4e00\u4e2a) N (\u524d\u4e00\u4e2a) man \u4e2d\u6587\u5316\u3002\u5728 /etc/profile \u52a0\u5165\u4e0b\u9762alias\uff0c\u53ef\u4ee5\u5728man\u4e2d\u8f93\u51fa\u4e2d\u6587 # For man in zh_CH alias cman='man -M /usr/share/man/zh_CN' Display descriptions: \u00b6 whatis command Info pages: \u00b6 info command # info # info top From the terminal window display the info pages for the info command by entering: # info info Move the cursor to the line referring to (Invoking Info) by pressing Tab Tab Follow the link by pressing Enter Move the cursor to the link Note Custom Key Bindings: by pressing Tab (6 times) Follow the link by pressing Enter Return to the page Note Custom Key Bindings: by typing (lowercase L): l Exit the info file by typing: q pwd command \u00b6 Display the current working directory cd command \u00b6 Change directory ls command \u00b6 Display directory contents * Display hidden files with -a option * Detailed listing with -l option * Output is recursive, including all subdirectories with -R option * With option -F After each name, a character indicates the file type (\u201c/\u201d for directories, \u201c*\u201d for executable files, \u201c|\u201d for FIFO files, \u201c@\u201d symbolic link). cp command \u00b6 Copy a file or directory Syntax: cp [option] Option -a : Copies a directory and subdirectories (compare -R ); symbolic links, file permissions, owners, and time stamps are not changed. \u5b83\u4fdd\u7559\u7b26\u53f7\u94fe\u63a5\u3001\u6587\u4ef6\u5c5e\u6027\uff0c\u5e76\u590d\u5236\u76ee\u5f55\u4e0b\u7684\u6240\u6709\u5185\u5bb9\u3002\u5176\u4f5c\u7528\u7b49\u4e8e-dpR\u53c2\u6570\u7ec4\u5408\u3002 Option -I : Asks before overwriting. Option -R , -r : Copies directories recursively (the directory and any subdirectories). \u9012\u5f52\u62f7\u8d1d\uff0c\u5305\u542b\u5b50\u76ee\u5f55\u53ca\uff08\u9690\u542b\uff09\u6587\u4ef6\uff0c\u7ee7\u627f\u76ee\u6807\u76ee\u5f55\u7684\u6743\u9650\u548c\u5c5e\u6027\u7b49 Option -l : Makes hardlinks instead of copying (\u521b\u5efa\u786c\u94fe\u63a5\u7684\u53e6\u5916\u4e00\u4e2a\u65b9\u6cd5) Option -s : Makes symbolic instead of copying (\u521b\u5efa\u7b26\u53f7\u94fe\u63a5\u7684\u53e6\u5916\u4e00\u4e2a\u65b9\u6cd5) Option -u : Copies a file only when the source file is newer than the destination file or when the destination file is missing. Option -p : \u8fde\u540c\u6863\u6848\u7684\u5c5e\u6027\u4e00\u8d77\u590d\u5236\u8fc7\u53bb\uff0c\u5305\u62ec\u4fee\u6539\u65f6\u95f4\u3001\u8bbf\u95ee\u6743\u9650\u3001\u6240\u6709\u8005\u7ec4\u7b49\uff0c\u800c\u975e\u4f7f\u7528\u9884\u8bbe\u5c5e\u6027\uff1b Labs: Initiate directories and files mySUSE:~ # su - pmgr pmgr@mySUSE:~> mkdir /data/program pmgr@mySUSE:~> mkdir /data/program/general pmgr@mySUSE:~> mkdir /data/program/general/staffing pmgr@mySUSE:~> touch /data/program/general/program_scope pmgr@mySUSE:~> touch /data/program/general/staffing/assignment mySUSE:~ # su - pm1 pm1@mySUSE:~> mkdir /data/project1 pm1@mySUSE:~> mkdir /data/project1/iot pm1@mySUSE:~> mkdir /data/project1/iot/bigdata pm1@mySUSE:~> touch /data/project1/iot/devicelist pm1@mySUSE:~> touch /data/project1/iot/bigdata/math_lib mySUSE:~ # su - pm2 pm2@mySUSE:~> mkdir /data/project2 pm2@mySUSE:~> mkdir /data/project2/erp pm2@mySUSE:~> mkdir /data/project2/erp/fin pm2@mySUSE:~> touch /data/project2/erp/erp_vision pm2@mySUSE:~> touch /data/project2/erp/fin/fin_ar pm2@mySUSE:~> chmod g+w /data/project2/erp/erp_vision pmgr@mySUSE:~> ln /data/project2/erp/erp_vision /data/program/general/p2_erp_version ( \u521b\u5efa\u786c\u94fe\u63a5\uff0c\u5f53\u524d\u7528\u6237\u9700\u8981\u5bf9\u6e90\u6587\u4ef6erp_vision\u6709w\u6743\u9650 ) pmgr@mySUSE:~> ln -s /data/project1/iot/devicelist /data/program/general/p1_devicelist ( \u521b\u5efa\u7b26\u53f7\u94fe\u63a5\uff0c\u4e0d\u9a8c\u8bc1\u5f53\u524d\u7528\u6237\u662f\u5426\u5bf9\u6e90\u6587\u4ef6devicelist\u6709\u6743\u9650 ) mySUSE:~ # tree /data /data \u251c\u2500\u2500 program \u2502 \u2514\u2500\u2500 general \u2502 \u251c\u2500\u2500 p1_devicelist -> /data/project1/iot/devicelist \u2502 \u251c\u2500\u2500 p2_erp_version \u2502 \u251c\u2500\u2500 program_scope \u2502 \u2514\u2500\u2500 staffing \u2502 \u2514\u2500\u2500 assignment \u251c\u2500\u2500 project1 \u2502 \u2514\u2500\u2500 iot \u2502 \u251c\u2500\u2500 bigdata \u2502 \u2502 \u2514\u2500\u2500 math_lib \u2502 \u2514\u2500\u2500 devicelist \u2514\u2500\u2500 project2 \u2514\u2500\u2500 erp \u251c\u2500\u2500 erp_vision \u2514\u2500\u2500 fin \u2514\u2500\u2500 fin_ar pmgr@mySUSE:~> cp -R /data/project1 /data/program/ ( /data/program/project1\u7684\u7528\u6237\u548c\u7ec4\u90fd\u7ee7\u627f\u4e86/data/program/ ) pmgr@mySUSE:~> cp -a /data/project2 /data/program/ ( /data/program/project2\u7684\u7528\u6237\u7ee7\u627f\u4e86/data/program/\uff0c\u4f46\u7ec4\u8fd8\u662f\u4fdd\u7559\u539f\u6765\u7684 ) mv command \u00b6 Move or rename a file or directory Option -i : Asks for confirmation before moving or renaming a file. This prevents existing files with the same name from being overwritten. Option -u : Only moves files that are newer than the target files of the same name. pmgr@mySUSE:/data/program/general> cp program_scope ./staffing/ pmgr@mySUSE:/data/program/general> mv -i program_scope ./staffing/ mv: overwrite './staffing/program_scope'? n rm command \u00b6 Delete a file or directory Option -i : Asks for confirmation before deleting. Option -r : (recursively) Allows full directories to be deleted. Option -f : (force) By default, rm asks for confirmation if the file that should be deleted is read-only. Using this option, the files are deleted without asking for confirmation. mkdir command \u00b6 Create a new directory Option -p lets you create a complete path (\u5c42\u7ea7\u8def\u5f84\u4e00\u6b21\u521b\u5efa) pmgr@mySUSE:/data> mkdir -p industry/utilities pmgr@mySUSE:/data> tree ./industry/ ./industry/ \u2514\u2500\u2500 utilities rmdir command \u00b6 Remove an empty directory. The directory or directories must be empty before you can delete them. ln command \u00b6 Create a link Default: Hard link Symbolic link with -s option Syntax: ln [-s] touch command \u00b6 Change the access and modification times Create an empty file if the given file does not exist. Change the time stamp of a file. Option -a : Changes only the time of the last read access (access time). Option -m : Changes only the time of the last modification (modification time). Option -r file : Sets the time stamp of file instead of the current time. Option -t time : Instead of the current time, sets time (structure: [[CC]YY]MMDDhhmm.[ss] ([Century]Year] Month Day Hour Minute [Seconds], two digits in each)) pmgr@mySUSE:/data/industry> touch readme pmgr@mySUSE:/data/industry> touch -a readme pmgr@mySUSE:/data/industry> touch -m readme pmgr@mySUSE:/data/industry> stat readme File: readme Size: 0 Blocks: 0 IO Block: 4096 regular empty file Device: 3dh/61d Inode: 338 Links: 1 Access: (0644/-rw-r--r--) Uid: ( 1003/ pmgr) Gid: ( 1000/ admins) Access: 2019-03-31 10:07:47.489055973 +0800 Modify: 2019-03-31 10:07:58.805109884 +0800 Change: 2019-03-31 10:07:58.805109884 +0800 Birth: - cat command \u00b6 Concatenates files tac command \u00b6 Same as cat, but displays the file(s) in reverse pmgr@mySUSE:/data/industry> cat readme line 1 line 2 line 3 pmgr@mySUSE:/data/industry> tac readme line 3 line 2 line 1 more command \u00b6 Display file contents one page at a time less command \u00b6 Displays file contents for better navigation head command \u00b6 Displays the first 10 lines of a file. To set the number of lines use the -n option pmgr@mySUSE:/data/industry> head readme line 1 line 2 line 3 line 4 line 5 line 6 line 7 line 8 line 9 line 10 pmgr@mySUSE:/data/industry> head -n 5 readme line 1 line 2 line 3 line 4 line 5 tail command \u00b6 Display the last lines of a file To set the number of lines use the -n option To output appended data use -f option, displays a continuously updated view of the last lines of a file. To exit tail -f, press Ctrl+C. pmgr@mySUSE:/data/industry> tail -n 6 readme line 10 line 11 line 12 line 13 line 14 line 15 tar command \u00b6 Create, expand or list archive files Use option c to create an archive Use option f to specify the archive file name Use option v for verbose mode Use option x to extract an archive Use option t to list the content of an archive Use option z to (un-)compress the archive with gzip Use option j to (un-)compress the archive with bzip The /etc directory (include sub-directories) is backed up to the /backup/etc.tar file pmgr@mySUSE:~> tar -cvf /data/backup/project1.tar /data/project1/ pmgr@mySUSE:~> tar -cvf /data/backup/project2.tar /data/project2/ pmgr@mySUSE:~> tar -cv --exclude='*.conf' -f /data/backup/project2a.tar /data/project2/ View the contents of an archive. Some .conf files are excluded in project2a.tar file. pmgr@mySUSE:~> tar -tvf /data/backup/project2.tar drwxr-xr-x pm2/project2 0 2019-03-31 16:47 data/project2/ drwxr-xr-x pm2/project2 0 2019-03-31 16:47 data/project2/erp/ drwxr-xr-x pm2/project2 0 2019-03-31 16:47 data/project2/erp/fin/ -rw-r--r-- pm2/project2 0 2019-03-29 16:06 data/project2/erp/fin/fin_ar -rw-r--r-- pm2/project2 0 2019-03-31 16:47 data/project2/erp/fin/fin.conf -rw-rw-r-- pm2/project2 0 2019-03-29 16:06 data/project2/erp/erp_vision -rw-r--r-- pm2/project2 0 2019-03-31 16:47 data/project2/erp/erp.conf -rw-r--r-- pm2/project2 0 2019-03-31 16:47 data/project2/project2.conf pmgr@mySUSE:~> tar -tvf /data/backup/project2a.tar drwxr-xr-x pm2/project2 0 2019-03-31 16:47 data/project2/ drwxr-xr-x pm2/project2 0 2019-03-31 16:47 data/project2/erp/ drwxr-xr-x pm2/project2 0 2019-03-31 16:47 data/project2/erp/fin/ -rw-r--r-- pm2/project2 0 2019-03-29 16:06 data/project2/erp/fin/fin_ar -rw-rw-r-- pm2/project2 0 2019-03-29 16:06 data/project2/erp/erp_vision Unpack and write all files in the archive to the current directory. Extract to another directory by using the -C option pmgr@mySUSE:~> mkdir project1.backup pmgr@mySUSE:~> tar -xvf /data/backup/project1.tar -C /data/backup/project1.backup/ Incremental backup with tar command pmgr@mySUSE:~> tar -g snapshot_program -cvf /data/backup/bkp_program_full.tar /data/program/ pmgr@mySUSE:~> tar -tvf /data/backup/bkp_program_full.tar pmgr@mySUSE:~> touch /data/program/general/general.conf pmgr@mySUSE:~> tar -g snapshot_program -cvf /data/backup/bkp_program_inc.tar /data/program/ pmgr@mySUSE:~> rm -rf program/ pmgr@mySUSE:~> tar -xvf /data/backup/bkp_program_inc.tar -C /data/ cpio command \u00b6 Another archiving command gzip command \u00b6 Compress files using the gzip algorithm Option -c : Compresses the file without modifying the original file. The result is written to the standard output (usually the screen). From there, it can be redirected to a file with \u201c>\u201d. Option -d : Decompresses the specified file (gunzip) Option -r : Compresses and decompresses files in all subdirectories. Option -1 to -9, --fast, --best : Controls the compression speed: -1 means --fast and causes a quick compression but produces larger files, -9 corresponds to --best and requires more computing time but produces smaller files. The default setting is -6. gunzip command \u00b6 Expand files compressed with gzip bzip2 command \u00b6 Compress files using the bzip2 algorithm Option -c : Option -d : Decompresses the specified file (bunzip2). Option -1 to -9 : Controls the compression speed: -1 causes a quick compression but produces larger files, -9 requires more computing time but produces smaller files. The default setting is -9 . bunzip2 command \u00b6 Expand files compressed with bzip rsync command \u00b6 Copy only deltas between two directories. A key benefit of using rsync is that when copying data, rsync compares the source and the target directory and transfers only data that has changed or has been created. \u4ec5\u590d\u5236\u4e24\u4e2a\u76ee\u5f55\u4e4b\u95f4\u7684\u589e\u91cf\u3002 \u4f7f\u7528rsync\u7684\u4e00\u4e2a\u4e3b\u8981\u597d\u5904\u662f\uff0c\u5728\u590d\u5236\u6570\u636e\u65f6\uff0crsync\u4f1a\u6bd4\u8f83\u6e90\u76ee\u5f55\u548c\u76ee\u6807\u76ee\u5f55\uff0c\u5e76\u4ec5\u4f20\u8f93\u5df2\u66f4\u6539\u6216\u5df2\u521b\u5efa\u7684\u6570\u636e\u3002 Local or via network \u672c\u5730\u6216\u901a\u8fc7\u7f51\u7edc Uses ssh as default transport \u4f7f\u7528ssh\u4f5c\u4e3a\u9ed8\u8ba4\u4f20\u8f93 Can talk to rsync daemon on the remote machine \u53ef\u4ee5\u4e0e\u8fdc\u7a0b\u8ba1\u7b97\u673a\u4e0a\u7684rsync\u5b88\u62a4\u7a0b\u5e8f\u901a\u4fe1 Note: rsync must be installed on both the source and the target computer for this to work. \u5fc5\u987b\u5728\u6e90\u8ba1\u7b97\u673a\u548c\u76ee\u6807\u8ba1\u7b97\u673a\u4e0a\u5b89\u88c5rsync\u624d\u80fd\u4f7f\u5176\u6b63\u5e38\u5de5\u4f5c\u3002 As the default shell used by rsync is ssh, the -e option only needs to be used when you want to use something else than ssh. \u7531\u4e8ersync\u4f7f\u7528\u7684\u9ed8\u8ba4shell\u662fssh\uff0c\u56e0\u6b64\u53ea\u6709\u5728\u60f3\u8981\u4f7f\u7528\u9664ssh\u4ee5\u5916\u7684\u5176\u4ed6\u5de5\u5177\u65f6\u624d\u9700\u8981\u4f7f\u7528-e\u9009\u9879\u3002 Options Option -a : Puts rsync into the archive mode. The -a option ensures the following are preserved \u4fdd\u7559 in the mirrored copy of the directory: Symbolic links (l option) Access permissions (p option) Owners (o option) Group membership (g option) Time stamp (t option) Option -x : Saves files on one file system only, which means that rsync does not follow symbolic links to other file systems. \u4e0d\u8de8\u6587\u4ef6\u7cfb\u7edf\uff0c\u53ea\u5728\u4e00\u4e2a\u6587\u4ef6\u7cfb\u7edf\u5185(don't cross filesyste* undaries) Option -v : Enables the verbose mode. Use this mode to output information about the transferred files and the progress of the copying process. \u8f93\u51fa\u4f20\u8f93\u8fc7\u7a0b\u7684\u7ec6\u8282\u4fe1\u606f Option -z : Compresses the data during the transfer. This is especially useful for remote synchronization. \u538b\u7f29\u65b9\u5f0f\u4f20\u8f93 Option --delete : Deletes files from the mirrored directory that no longer exist in the original directory. Option --exclude-from : Does not back up files listed in an exclude file. Local backup via rsync command pmgr@mySUSE:/data> rsync -av /data/industry/* /data/backup/industry/ sending incremental file list created directory /data/backup/industry readme utilities/ sent 264 bytes received 87 bytes 702.00 bytes/sec total size is 111 speedup is 0.32 pmgr@mySUSE:/data/industry/utilities> touch roadmap.txt pmgr@mySUSE:/data> rsync -av /data/industry/* /data/backup/industry/ sending incremental file list utilities/ utilities/roadmap.txt sent 171 bytes received 39 bytes 420.00 bytes/sec total size is 111 speedup is 0.53 pmgr@mySUSE:/data> rm roadmap.txt pmgr@mySUSE:/data> rsync -av /data/industry/* --delete /data/backup/industry/ sending incremental file list deleting utilities/roadmap.txt utilities/ sent 102 bytes received 41 bytes 286.00 bytes/sec total size is 111 speedup is 0.78 dd command \u00b6 Copies files block by block Used to create disk or partition images Most important options: if =input_file `of``=output_file bs =block_size You can use the dd command to convert and copy files byte-wise. Normally dd reads from the standard input and writes the result to the standard output. But with the appropriate parameters, regular files can be addressed as well. You can copy all kinds of Linux data with this command, including entire hard disk partitions. You can even copy an entire installed system (or just parts of it). Copy file /etc/protocols to protocols.old. The default size for a record is 512 bytes. Below 45+1 means, 45 complete record of standard size and 1 incomplete record (less than 512 bytes pmgr@mySUSE:/data/program> dd if=/etc/protocols of=protocols.old bs=512 45+1 records in 45+1 records out 23259 bytes (23 kB, 23 KiB) copied, 0.000595392 s, 39.1 MB/s \u521b\u5efa\u4e00\u4e2a100M\u7684\u7a7a\u6587\u4ef6 pmgr@mySUSE:/data/program> dd if=/dev/zero of=datafile bs=100M count=2 2+0 records in 2+0 records out 209715200 bytes (210 MB, 200 MiB) copied, 2.79311 s, 75.1 MB/s \u5907\u4efd\u6574\u4e2a\u5206\u533a #dd if=/dev/sda1 of=boot.partition \u5236\u4f5cU\u76d8\u542f\u52a8\u76d8\uff08U\u76d8\u6302\u8f7d\u5230/dev/sdb\uff09 #dd if=/root/diskboot.img of=/dev/sdb bs=125682176 \u5907\u4efd\u786c\u76d8\u4e3b\u5f15\u5bfc\u8bb0\u5f55 #dd if=/dev/sda of=/tmp/mbr_copy bs=512 count=1 \u8fd8\u539f\u786c\u76d8\u4e3b\u5f15\u5bfc\u8bb0\u5f55 #dd if=/disk.mbr of=/dev/hda bs=512 count=1 \u5c06\u5185\u5b58\u91cc\u7684\u6570\u636e\u62f7\u8d1d\u5230root\u76ee\u5f55\u4e0b\u7684mem.bin\u6587\u4ef6 # dd if=/dev/mem of=/root/mem.bin bs=1024 \u62f7\u8d1d\u5149\u76d8\u6570\u636e\u5230root\u6587\u4ef6\u5939\u4e0b\uff0c\u5e76\u4fdd\u5b58\u4e3acd.iso\u6587\u4ef6 # dd if=/dev/cdrom of=/root/cd.iso \u5229\u7528\u968f\u673a\u7684\u6570\u636e\u586b\u5145\u786c\u76d8(\u9500\u6bc1\u786c\u76d8\u6570\u636e) # dd if=/dev/urandom of=/dev/hda1 \u6d4b\u8bd5\u786c\u76d8\u8bfb\u5199\u901f\u5ea6\u3002\u901a\u8fc7\u4e24\u4e2a\u547d\u4ee4\u8f93\u51fa\u7684\u6267\u884c\u65f6\u95f4\uff0c\u53ef\u4ee5\u8ba1\u7b97\u51fa\u6d4b\u8bd5\u786c\u76d8\u7684\u8bfb\uff0f\u5199\u901f\u5ea6\uff1a mySUSE:/data # dd if=/data/program/datafile bs=64k | dd of=/dev/null 3200+0 records in 3200+0 records out 209715200 bytes (210 MB, 200 MiB) copied, 0.67138 s, 312 MB/s 409600+0 records in 409600+0 records out 209715200 bytes (210 MB, 200 MiB) copied, 0.675912 s, 310 MB/s # dd if=/dev/zero of=/data/program/datafile bs=1024 count=100 \u5207\u5272\u5927\u6587\u4ef6bigfile\uff0c\u517198336321\u5b57\u8282\uff0c\u5219\uff1a # dd if=bigfile of=smallfile1 bs=1 count=20000000 # dd if=bigfile of=smallfile2 bs=1 count=20000000 skip=20000000 # dd if=bigfile of=smallfile3 bs=1 count=20000000 skip=40000000 # dd if=bigfile of=smallfile4 bs=1 count=20000000 skip=60000000 # dd if=bigfile of=smallfile5 bs=1 count=18336321 skip=80000000 \u5c06\u5207\u5272\u6587\u4ef6\u7ec4\u88c5 # dd if=smallfile1 of=bigfile bs=1 count=20000000 # dd if=smallfile2 of=bigfile bs=1 count=20000000 seek=20000000 # dd if=smallfile3 of=bigfile bs=1 count=20000000 seek=40000000 # dd if=smallfile4 of=bigfile bs=1 count=20000000 seek=60000000 # dd if=smallfile5 of=bigfile bs=1 count=18336321 seek=80000000 if: \u8981\u5207\u5272\u7684\u5927\u6587\u4ef6\u540d of: \u5207\u5272\u540e\u7684\u5b50\u6587\u4ef6\u540d bs: \u4ee5\u591a\u5c11\u5b57\u8282\u4f5c\u4e3a\u4e00\u4e2a\u5207\u5272\u8bb0\u5f55\u5355\u4f4d count: \u662f\u8981\u5207\u5272\u7684\u5355\u4f4d\u8bb0\u5f55\u6570 skip: \u8bf4\u660e\u5207\u5272\u65f6\u7684\u8d77\u70b9 seek: \u660e\u786e\u6307\u51fa\u5f00\u59cb\u4f4d\u7f6e find command \u00b6 Search for files or directories Syntax: find path criterion [action] The find command has a multitude of options, a few of which are explained here. You can use the following arguments with the command: path: The section of the file system to search (the specified directory and all its subdirectories). If nothing is specified, the file system below the current directory is used. criterion: The properties the file should have (see below) action: Options that influence the following conditions or control the search as a whole The most important actions are: -print (default) -exec command With the -exec option, you can call up another command. This option is frequently used to link find and grep, as in the following: \u627e\u51fagen\u5f00\u5934\u7684\u6587\u4ef6 pmgr@dcmaster:/data> find . -name gen\\* ./program/general ./program/general/general.conf \u627e\u51fagen\u5f00\u5934\u7684\u6587\u4ef6\uff0c\u5e76\u5728\u6587\u4ef6\u5185\u5bb9\u4e2d\u67e5\u627exen\uff0c\u627e\u5230\u540e\u7ed3\u679c\u8f93\u51faxen pmgr@dcmaster:/data> find . -name gen\\* -type f -exec grep xen {} \\; xen xening The two brackets \u201c{}\u201d stand as placeholders for the file names which are found and passed to the grep command. The semicolon closes the -exec instruction. Because this is a special character, it is masked by placing a backslash in front of it. -ctime [\u00b1]days Searches for files whose last change took place no later than (no earlier than) a specified number of days ago. \u5728\u8fc7\u53bbn\u5929\u5185\u88ab\u4fee\u6539\u8fc7\u7684\u6587\u4ef6 mgr@dcmaster:/data> find . -ctime 1 . ./program/datafile -gid number Searches for files with the numeric GID (Group ID) number. (gid \u662f n) -group name Searches for files that are owned by the group name. Instead of a name, the numeric GID is allowed. (group \u540d\u79f0\u662f name) -name pattern Searches for files whose names contain the given pattern. If the pattern contains meta characters or wild cards, the name must be enclosed by quotation marks. Otherwise thename will be interpreted by the shell and not by find. -newer file Searches for files that were modified more recently than file. \u6bd4\u6587\u4ef6 file \u66f4\u65b0\u7684\u6587\u4ef6 pmgr@dcmaster:/data> find . -cnewer ./program/datafile . -size [\u00b1]size Matches files that are above or below a certain size. The size (in blocks of 512 bytes) is given as an argument. The suffix \u201cc\u201cswitches to byte and \u201ck\u201d to blocks of 1024bytes. A preceding \u201c+\u201d stands for all larger files and a \u201c-\u201d for all smaller files. (\u6587\u4ef6\u5927\u5c0f \u662f n \u2022 b \u4ee3\u8868 512 \u4f4d\u5143\u7ec4\u7684\u533a\u5757 \u2022 c \u8868\u793a\u5b57\u5143\u6570 \u2022 k \u8868\u793a kilo bytes \u2022 w \u662f\u4e8c\u4e2a\u4f4d\u5143\u7ec4 pmgr@dcmaster:/data> find . -size 20k ./backup/project2.tar -type file_type Searches for a file type. A file type can be one of the following: * c : \u6587\u4ef6\u7c7b\u578b\u662f c \u7684\u6587\u4ef6\u3002 * d: \u76ee\u5f55 * c: \u5b57\u578b\u88c5\u7f6e\u6587\u4ef6 * b: \u533a\u5757\u88c5\u7f6e\u6587\u4ef6 * p: \u5177\u540d\u8d2e\u5217 * f: \u4e00\u822c\u6587\u4ef6 * l: \u7b26\u53f7\u8fde\u7ed3 * s: socket -uid number Searches for files with the numeric UID (User ID) number. -user name Searches for files, which are owned by user name. Instead of a name, the numeric UID is allowed. \u5e38\u7528\u53c2\u6570 mount, -xdev : \u53ea\u68c0\u67e5\u548c\u6307\u5b9a\u76ee\u5f55\u5728\u540c\u4e00\u4e2a\u6587\u4ef6\u7cfb\u7edf\u4e0b\u7684\u6587\u4ef6\uff0c\u907f\u514d\u5217\u51fa\u5176\u5b83\u6587\u4ef6\u7cfb\u7edf\u4e2d\u7684\u6587\u4ef6 amin n : \u5728\u8fc7\u53bb n \u5206\u949f\u5185\u88ab\u8bfb\u53d6\u8fc7 anewer file : \u6bd4\u6587\u4ef6 file \u66f4\u665a\u88ab\u8bfb\u53d6\u8fc7\u7684\u6587\u4ef6 atime n : \u5728\u8fc7\u53bbn\u5929\u5185\u88ab\u8bfb\u53d6\u8fc7\u7684\u6587\u4ef6 pmgr@dcmaster:/data> find . -atime 1 ./program/datafile cmin n : \u5728\u8fc7\u53bb n \u5206\u949f\u5185\u88ab\u4fee\u6539\u8fc7 pmgr@dcmaster:/data> find . -cmin 20 empty : \u7a7a\u7684\u6587\u4ef6 ipath p, -path p : \u8def\u5f84\u540d\u79f0\u7b26\u5408 p \u7684\u6587\u4ef6\uff0cipath \u4f1a\u5ffd\u7565\u5927\u5c0f\u5199 name name, -iname name : \u6587\u4ef6\u540d\u79f0\u7b26\u5408 name \u7684\u6587\u4ef6\u3002iname \u4f1a\u5ffd\u7565\u5927\u5c0f\u5199 pid n : process id \u662f n \u7684\u6587\u4ef6 \u67e5\u627e\u5f53\u524d\u76ee\u5f55\u53ca\u5b50\u76ee\u5f55\u4e2d\u6240\u6709\u6587\u4ef6\u957f\u5ea6\u4e3a0\u7684\u666e\u901a\u6587\u4ef6\uff0c\u5e76\u5217\u51fa\u5b83\u4eec\u7684\u5b8c\u6574\u8def\u5f84 pmgr@dcmaster:/data> find . -type f -size 0 -exec ls -l {} \\; \u67e5\u627e\u524d\u76ee\u5f55\u4e2d\u6587\u4ef6\u5c5e\u4e3b\u5177\u6709\u8bfb\u3001\u5199\u6743\u9650\uff0c\u5e76\u4e14\u6587\u4ef6\u6240\u5c5e\u7ec4\u7684\u7528\u6237\u548c\u5176\u4ed6\u7528\u6237\u5177\u6709\u8bfb\u6743\u9650\u7684\u6587\u4ef6 pmgr@dcmaster:/data> find . -type f -perm 644 -exec ls -l {} \\; \u67e5\u627e/var/log\u76ee\u5f55\u4e2d\u66f4\u6539\u65f6\u95f4\u572817\u65e5\u4ee5\u524d\u7684\u666e\u901a\u6587\u4ef6\uff0c\u5e76\u5728\u5220\u9664\u4e4b\u524d\u8be2\u95ee\u5b83\u4eec pmgr@dcmaster:/data> find /var/log -type f -mtime +17 -ok rm {} \\; \u5c06\u76ee\u524d\u76ee\u5f55\u53ca\u5176\u5b50\u76ee\u5f55\u4e0b\u6240\u6709\u6700\u8fd1 1 \u5929\u5185\u66f4\u65b0\u8fc7\u7684\u6587\u4ef6\u5217\u51fa mgr@dcmaster:/data> find . -ctime 1 \u5c06\u76ee\u524d\u76ee\u5f55\u5176\u5176\u4e0b\u5b50\u76ee\u5f55\u4e2d\u6240\u6709\u4e00\u822c\u6587\u4ef6\u5217\u51fa pmgr@dcmaster:/data> find . -type f \u5c06\u76ee\u524d\u76ee\u5f55\u53ca\u5176\u5b50\u76ee\u5f55\u4e0b\u6240\u6709\u5ef6\u4f38\u6863\u540d\u662fconf \u7684\u6587\u4ef6\u5217\u51fa\u6765 pmgr@dcmaster:/data> find . -name \"*.conf\" which command \u00b6 Searches all paths listed in the variable $PATH and returns the full path of the command The which command searches all paths listed in the variable $PATH for the specified command and returns the full path of the command. In the variable \\(PATH, the most important directoriesare listed where the shell looks for executable files. which\u547d\u4ee4\u641c\u7d22\u53d8\u91cf\\) PATH\u4e2d\u5217\u51fa\u7684\u6240\u6709\u8def\u5f84\u4ee5\u83b7\u53d6\u6307\u5b9a\u547d\u4ee4\uff0c\u5e76\u8fd4\u56de\u547d\u4ee4\u7684\u5b8c\u6574\u8def\u5f84\u3002 The which command is especially useful if several versions of a command exist in different directories and you want to know which version is executed when entered without specifying apath. \u5982\u679c\u547d\u4ee4\u7684\u591a\u4e2a\u7248\u672c\u5b58\u5728\u4e8e\u4e0d\u540c\u7684\u76ee\u5f55\u4e2d\uff0c\u5e76\u4e14\u60a8\u60f3\u77e5\u9053\u5728\u8f93\u5165\u65f6\u6267\u884c\u4e86\u54ea\u4e2a\u7248\u672c\u800c\u672a\u6307\u5b9a\u8def\u5f84\uff0c\u90a3\u4e48which\u547d\u4ee4\u7279\u522b\u6709\u7528\u3002 NOTE: To see the content of a variable, use the echo command Options Description -n<\u6587\u4ef6\u540d\u957f\u5ea6> \u6307\u5b9a\u6587\u4ef6\u540d\u957f\u5ea6\uff0c\u6307\u5b9a\u7684\u957f\u5ea6\u5fc5\u987b\u5927\u4e8e\u6216\u7b49\u4e8e\u6240\u6709\u6587\u4ef6\u4e2d\u6700\u957f\u7684\u6587\u4ef6\u540d\u3002 -p<\u6587\u4ef6\u540d\u957f\u5ea6> \u4e0e-n\u53c2\u6570\u76f8\u540c\uff0c\u4f46\u6b64\u5904\u7684<\u6587\u4ef6\u540d\u957f\u5ea6>\u5305\u62ec\u4e86\u6587\u4ef6\u7684\u8def\u5f84\u3002 -w \u6307\u5b9a\u8f93\u51fa\u65f6\u680f\u4f4d\u7684\u5bbd\u5ea6\u3002 -V \u663e\u793a\u7248\u672c\u4fe1\u606f # which grep /usr/bin/grep # which -V grep GNU which v2.21, Copyright (C) 1999 - 2015 Carlo Wood. GNU which comes with ABSOLUTELY NO WARRANTY; This program is free software; your freedom to use, change and distribute this program is protected by the GPL. whereis command \u00b6 The whereis command returns the binaries (option -b), manual pages (option -m), and the source code (option -s) of the specified command. If no option is used, all this information is returned, provided the information is available. This command is faster than find, but it is less thorough. Attempts to locate the desired program in the standard Linux places, and in the places specified by $PATH and $MANPATH . \u5c1d\u8bd5\u5728\u6807\u51c6Linux\u4f4d\u7f6e\u548c\u6307\u5b9a\u4f4d\u7f6e( \\(PATH\u548c\\) MANPATH)\u627e\u5230\u6240\u9700\u7684\u7a0b\u5e8f Options Description -b \u53ea\u67e5\u627e\u4e8c\u8fdb\u5236\u6587\u4ef6\u3002 -B<\u76ee\u5f55> \u53ea\u5728\u8bbe\u7f6e\u7684\u76ee\u5f55\u4e0b\u67e5\u627e\u4e8c\u8fdb\u5236\u6587\u4ef6\u3002 -f \u4e0d\u663e\u793a\u6587\u4ef6\u540d\u524d\u7684\u8def\u5f84\u540d\u79f0\u3002 -m \u53ea\u67e5\u627e\u8bf4\u660e\u6587\u4ef6\u3002 -M<\u76ee\u5f55> \u53ea\u5728\u8bbe\u7f6e\u7684\u76ee\u5f55\u4e0b\u67e5\u627e\u8bf4\u660e\u6587\u4ef6\u3002 -s \u53ea\u67e5\u627e\u539f\u59cb\u4ee3\u7801\u6587\u4ef6\u3002 -S<\u76ee\u5f55> \u53ea\u5728\u8bbe\u7f6e\u7684\u76ee\u5f55\u4e0b\u67e5\u627e\u539f\u59cb\u4ee3\u7801\u6587\u4ef6\u3002 -u \u67e5\u627e\u4e0d\u5305\u542b\u6307\u5b9a\u7c7b\u578b\u7684\u6587\u4ef6\u3002 \u4ee5\u4e0b\u8f93\u51fa\u4fe1\u606f\u4ece\u5de6\u81f3\u53f3\u5206\u522b\u4e3a\u67e5\u8be2\u7684\u7a0b\u5e8f\u540d\u3001bash\u8def\u5f84\u3001bash\u7684man\u624b\u518c\u9875\u8def\u5f84\u3002 # whereis grep grep: /usr/bin/grep /bin/grep /usr/share/man/man1/grep.1.gz /usr/share/info/grep.info.gz \u663e\u793abash \u547d\u4ee4\u7684\u4e8c\u8fdb\u5236\u7a0b\u5e8f # whereis -b grep grep: /usr/bin/grep /bin/grep \u663e\u793abash \u547d\u4ee4\u7684\u5e2e\u52a9\u6587\u4ef6 # whereis -m grep grep: /usr/share/man/man1/grep.1.gz /usr/share/info/grep.info.gz type command \u00b6 The type command shows what kind of command is executed when you enter it: \u547d\u4ee4\u7684\u7c7b\u578b a shell built-in command (an essential command that is hard coded in the shell), for example type or cd an external command (called by the shell) an alias, for example ls. An alias defines shortcuts and synonyms for commonly used shell commands. a function The -a option delivers all instances of a command bearing this name in the file system. NOTE: If you want to have more information about a file format, you can use the file command. \u4e0d\u9002\u7528\u4e8e\u666e\u901a\u6587\u4ef6 dcmaster:/data/shell # type pwd.txt -bash: type: pwd.txt: not found \u4e0d\u9002\u7528\u4e8e\u81ea\u5b9a\u4e49\u53ef\u6267\u884c\u811a\u672c dcmaster:/data/shell # type math.sh -bash: type: math.sh: not found \u7cfb\u7edf\u547d\u4ee4 dcmaster:/data/shell # type rsync rsync is /usr/bin/rsync \u522b\u540d dcmaster:/data/shell # type l l is aliased to `ls -alF' file command \u00b6 file\u547d\u4ee4\u7528\u4e8e\u8fa8\u8bc6\u6587\u4ef6\u7c7b\u578b -b \u5217\u51fa\u8fa8\u8bc6\u7ed3\u679c\u65f6\uff0c\u4e0d\u663e\u793a\u6587\u4ef6\u540d\u79f0\u3002 -c \u8be6\u7ec6\u663e\u793a\u6307\u4ee4\u6267\u884c\u8fc7\u7a0b\uff0c\u4fbf\u4e8e\u6392\u9519\u6216\u5206\u6790\u7a0b\u5e8f\u6267\u884c\u7684\u60c5\u5f62\u3002 -f <\u540d\u79f0\u6587\u4ef6> \u6307\u5b9a\u540d\u79f0\u6587\u4ef6\uff0c\u5176\u5185\u5bb9\u6709\u4e00\u4e2a\u6216\u591a\u4e2a\u6587\u4ef6\u540d\u79f0\u65f6\uff0c\u8ba9file\u4f9d\u5e8f\u8fa8\u8bc6\u8fd9\u4e9b\u6587\u4ef6\uff0c\u683c\u5f0f\u4e3a\u6bcf\u5217\u4e00\u4e2a\u6587\u4ef6\u540d\u79f0\u3002 -L \u76f4\u63a5\u663e\u793a\u7b26\u53f7\u8fde\u63a5\u6240\u6307\u5411\u7684\u6587\u4ef6\u7684\u7c7b\u522b\u3002 -m<\u9b54\u6cd5\u6570\u5b57\u6587\u4ef6> \u6307\u5b9a\u9b54\u6cd5\u6570\u5b57\u6587\u4ef6\u3002 -v \u663e\u793a\u7248\u672c\u4fe1\u606f\u3002 -z \u5c1d\u8bd5\u53bb\u89e3\u8bfb\u538b\u7f29\u6587\u4ef6\u7684\u5185\u5bb9\u3002 dcmaster:/data/linktype # l -rw-r--r-- 3 root root 44 May 3 09:50 file -rw-r--r-- 3 root root 44 May 3 09:50 hardlinkfile1 -rw-r--r-- 3 root root 44 May 3 09:50 hardlinkfile2 lrwxrwxrwx 1 root root 4 Mar 28 15:21 symlinkfile1 -> file lrwxrwxrwx 1 root root 12 Mar 28 15:49 symlinkfile1-1 -> symlinkfile1 lrwxrwxrwx 1 root root 4 Mar 28 15:23 symlinkfile2 -> file dcmaster:/data/linktype # file hardlinkfile1 hardlinkfile1: ASCII text dcmaster:/data/linktype # file -i hardlinkfile1 hardlinkfile1: text/plain; charset=us-ascii dcmaster:/data/linktype # file /data/linktype/ /data/linktype/: directory dcmaster:/data/linktype # file -L /data/linktype/ /data/linktype/: directory dcmaster:/data/linktype # file -i /data/linktype/ /data/linktype/: inode/directory; charset=binary dcmaster:/data/linktype # file symlinkfile1 symlinkfile1: symbolic link to file dcmaster:/data/linktype # file -i symlinkfile1 symlinkfile1: inode/symlink; charset=binary grep command \u00b6 You can specify search patterns in the form of regular expressions, although the basic grep command is limited in this regard. To search for more complex patterns, use the egrep command (or grep -E ) instead, which accepts extended regular expressions. To avoid having special characters in search patterns interpreted by the shell, enclose the pattern in quotation marks. Syntax: grep [options] search_pattern filename * egrep = grep -E * rgrep \u53c2\u6570 -a \u6216 --text : \u4e0d\u8981\u5ffd\u7565\u4e8c\u8fdb\u5236\u7684\u6570\u636e\u3002 -A<\u663e\u793a\u884c\u6570> \u6216 --after-context=<\u663e\u793a\u884c\u6570> : \u9664\u4e86\u663e\u793a\u7b26\u5408\u8303\u672c\u6837\u5f0f\u7684\u90a3\u4e00\u5217\u4e4b\u5916\uff0c\u5e76\u663e\u793a\u8be5\u884c\u4e4b\u540e\u7684\u5185\u5bb9\u3002 -b \u6216 --byte-offset : \u5728\u663e\u793a\u7b26\u5408\u6837\u5f0f\u7684\u90a3\u4e00\u884c\u4e4b\u524d\uff0c\u6807\u793a\u51fa\u8be5\u884c\u7b2c\u4e00\u4e2a\u5b57\u7b26\u7684\u7f16\u53f7\u3002 -B<\u663e\u793a\u884c\u6570> \u6216 --before-context=<\u663e\u793a\u884c\u6570> : \u9664\u4e86\u663e\u793a\u7b26\u5408\u6837\u5f0f\u7684\u90a3\u4e00\u884c\u4e4b\u5916\uff0c\u5e76\u663e\u793a\u8be5\u884c\u4e4b\u524d\u7684\u5185\u5bb9\u3002 -c \u6216 --count : \u8ba1\u7b97\u7b26\u5408\u6837\u5f0f\u7684\u5217\u6570\u3002 -C<\u663e\u793a\u884c\u6570> \u6216 --context=<\u663e\u793a\u884c\u6570> \u6216 -<\u663e\u793a\u884c\u6570> : \u9664\u4e86\u663e\u793a\u7b26\u5408\u6837\u5f0f\u7684\u90a3\u4e00\u884c\u4e4b\u5916\uff0c\u5e76\u663e\u793a\u8be5\u884c\u4e4b\u524d\u540e\u7684\u5185\u5bb9\u3002 -d <\u52a8\u4f5c> \u6216 --directories=<\u52a8\u4f5c> : \u5f53\u6307\u5b9a\u8981\u67e5\u627e\u7684\u662f\u76ee\u5f55\u800c\u975e\u6587\u4ef6\u65f6\uff0c\u5fc5\u987b\u4f7f\u7528\u8fd9\u9879\u53c2\u6570\uff0c\u5426\u5219grep\u6307\u4ee4\u5c06\u56de\u62a5\u4fe1\u606f\u5e76\u505c\u6b62\u52a8\u4f5c\u3002 -e<\u8303\u672c\u6837\u5f0f> \u6216 --regexp=<\u8303\u672c\u6837\u5f0f> : \u6307\u5b9a\u5b57\u7b26\u4e32\u505a\u4e3a\u67e5\u627e\u6587\u4ef6\u5185\u5bb9\u7684\u6837\u5f0f\u3002 -E \u6216 --extended-regexp : \u5c06\u6837\u5f0f\u4e3a\u5ef6\u4f38\u7684\u666e\u901a\u8868\u793a\u6cd5\u6765\u4f7f\u7528\u3002 -f<\u89c4\u5219\u6587\u4ef6> \u6216 --file=<\u89c4\u5219\u6587\u4ef6> : \u6307\u5b9a\u89c4\u5219\u6587\u4ef6\uff0c\u5176\u5185\u5bb9\u542b\u6709\u4e00\u4e2a\u6216\u591a\u4e2a\u89c4\u5219\u6837\u5f0f\uff0c\u8ba9grep\u67e5\u627e\u7b26\u5408\u89c4\u5219\u6761\u4ef6\u7684\u6587\u4ef6\u5185\u5bb9\uff0c\u683c\u5f0f\u4e3a\u6bcf\u884c\u4e00\u4e2a\u89c4\u5219\u6837\u5f0f\u3002 -F \u6216 --fixed-regexp : \u5c06\u6837\u5f0f\u89c6\u4e3a\u56fa\u5b9a\u5b57\u7b26\u4e32\u7684\u5217\u8868\u3002 -G \u6216 --basic-regexp : \u5c06\u6837\u5f0f\u89c6\u4e3a\u666e\u901a\u7684\u8868\u793a\u6cd5\u6765\u4f7f\u7528\u3002 -h \u6216 --no-filename : \u5728\u663e\u793a\u7b26\u5408\u6837\u5f0f\u7684\u90a3\u4e00\u884c\u4e4b\u524d\uff0c\u4e0d\u6807\u793a\u8be5\u884c\u6240\u5c5e\u7684\u6587\u4ef6\u540d\u79f0\u3002 -H \u6216 --with-filename : \u5728\u663e\u793a\u7b26\u5408\u6837\u5f0f\u7684\u90a3\u4e00\u884c\u4e4b\u524d\uff0c\u8868\u793a\u8be5\u884c\u6240\u5c5e\u7684\u6587\u4ef6\u540d\u79f0\u3002 -i \u6216 --ignore-case : \u5ffd\u7565\u5b57\u7b26\u5927\u5c0f\u5199\u7684\u5dee\u522b\u3002 -l \u6216 --file-with-matches : \u5217\u51fa\u6587\u4ef6\u5185\u5bb9\u7b26\u5408\u6307\u5b9a\u7684\u6837\u5f0f\u7684\u6587\u4ef6\u540d\u79f0\u3002 -L \u6216 --files-without-match : \u5217\u51fa\u6587\u4ef6\u5185\u5bb9\u4e0d\u7b26\u5408\u6307\u5b9a\u7684\u6837\u5f0f\u7684\u6587\u4ef6\u540d\u79f0\u3002 -n \u6216 --line-number : \u5728\u663e\u793a\u7b26\u5408\u6837\u5f0f\u7684\u90a3\u4e00\u884c\u4e4b\u524d\uff0c\u6807\u793a\u51fa\u8be5\u884c\u7684\u5217\u6570\u7f16\u53f7\u3002 -o \u6216 --only-matching : \u53ea\u663e\u793a\u5339\u914dPATTERN \u90e8\u5206\u3002 -q \u6216 --quiet\u6216--silent : \u4e0d\u663e\u793a\u4efb\u4f55\u4fe1\u606f\u3002 -r \u6216 --recursive : \u6b64\u53c2\u6570\u7684\u6548\u679c\u548c\u6307\u5b9a\"-d recurse\"\u53c2\u6570\u76f8\u540c\u3002 -s \u6216 --no-messages : \u4e0d\u663e\u793a\u9519\u8bef\u4fe1\u606f\u3002 -v \u6216 --revert-match : \u663e\u793a\u4e0d\u5305\u542b\u5339\u914d\u6587\u672c\u7684\u6240\u6709\u884c\u3002 -V \u6216 --version : \u663e\u793a\u7248\u672c\u4fe1\u606f\u3002 -w \u6216 --word-regexp : \u53ea\u663e\u793a\u5168\u5b57\u7b26\u5408\u7684\u5217\u3002 -x --line-regexp : \u53ea\u663e\u793a\u5168\u5217\u7b26\u5408\u7684\u5217\u3002 -y : \u6b64\u53c2\u6570\u7684\u6548\u679c\u548c\u6307\u5b9a\"-i\"\u53c2\u6570\u76f8\u540c\u3002 \u5728\u5f53\u524d\u76ee\u5f55\u4e2d\uff0c\u67e5\u627e\u540e\u7f00\u6709conf\u5b57\u6837\u7684\u6587\u4ef6\u4e2d\u5305\u542bxen\u5b57\u7b26\u4e32\u7684\u6587\u4ef6\uff0c\u5e76\u6253\u5370\u51fa\u8be5\u5b57\u7b26\u4e32\u7684\u884c\u3002 pmgr@dcmaster:/data/program/general> grep xen *.conf xen xening \u67e5\u627e\u524d\u7f00\u6709gen\u7684\u6587\u4ef6\u5305\u542bxen\u5b57\u7b26\u4e32\u7684\u6587\u4ef6 pmgr@dcmaster:/data/program/general> grep xen gen* xen xening \u4ee5\u9012\u5f52\u7684\u65b9\u5f0f\u67e5\u627e\u7b26\u5408\u6761\u4ef6\u7684\u6587\u4ef6\u3002\u67e5\u627e\u6307\u5b9a\u76ee\u5f55/data/program/\u53ca\u5176\u5b50\u76ee\u5f55\uff08\u5982\u679c\u5b58\u5728\u5b50\u76ee\u5f55\u7684\u8bdd\uff09\u4e0b\u6240\u6709\u6587\u4ef6\u4e2d\u5305\u542b\u5b57\u7b26\u4e32xen\u7684\u6587\u4ef6\uff0c\u5e76\u6253\u5370\u51fa\u8be5\u5b57\u7b26\u4e32\u6240\u5728\u884c\u7684\u5185\u5bb9 pmgr@dcmaster:/data> grep -r xen /data/program/ ./program/general/general.conf:xen ./program/general/general.conf:xening \u53cd\u5411\u67e5\u627e\u3002\u524d\u9762\u5404\u4e2a\u4f8b\u5b50\u662f\u67e5\u627e\u5e76\u6253\u5370\u51fa\u7b26\u5408\u6761\u4ef6\u7684\u884c\uff0c\u901a\u8fc7 -v \u53c2\u6570\u53ef\u4ee5\u6253\u5370\u51fa\u4e0d\u7b26\u5408\u6761\u4ef6\u884c\u7684\u5185\u5bb9\u3002\u67e5\u627e\u6587\u4ef6\u540d\u4e2d\u5305\u542bxen\u7684\u6587\u4ef6\u4e2d\u4e0d\u5305\u542bxen\u7684\u884c pmgr@dcmaster:/data/program/general> grep -v xen gen* Linux Test test \u67e5\u627e\u5f53\u524d\u76ee\u5f55\u4e0b\u5305\u542b\u5b57\u7b26\u4e32\u201cLinux\u201d\u7684\u6587\u4ef6 pmgr@dcmaster:/data/program/general> grep Linux * general.conf:Linux grep: staffing: Is a directory pmgr@dcmaster:/data/program/general> egrep Linux * general.conf:Linux grep: staffing: Is a directory","title":"Useful Commands"},{"location":"linux/Administration/02/#useful-commands","text":"","title":"Useful Commands"},{"location":"linux/Administration/02/#some-common-abbreviations","text":"Abbreviations Description . represents the current directory .. represents the parent directory ~ represents the home directory ~username represents the home directory of user username","title":"Some common abbreviations"},{"location":"linux/Administration/02/#software-package-documentation","text":"/usr/share/doc/packages/","title":"Software package documentation"},{"location":"linux/Administration/02/#release-notes","text":"/usr/share/doc/release-notes/","title":"Release Notes"},{"location":"linux/Administration/02/#command-help","text":" -h or --help # tree --help","title":"Command help"},{"location":"linux/Administration/02/#manual-pages","text":"man [ section ] command # man 5 crontab # man /sestion options Show tree command manual: # man tree List for keywords: # man -k keyword Force mandb to update. Normally this is done daily via a cron job. # mandb Search for all instances of a command or a file named crontab # man -f crontab # whatis crontab (same output with above command) # man -k crontab # apropos crontab (same output with above command) To go directly to a given man page: # man 5 crontab * 1G : go to the 1 st line * 10G : go to the 10 th line * G : go to the end of the page * /^SELinux : search the word SELinux * /section OPTIONS : go to the section OPTIONS man\u5171\u6709\u4ee5\u4e0b\u51e0\u4e2a\u7ae0\u8282\uff0c\u6bd4\u5982\uff0cman 5 crontab\u5c31\u662f\u8fdb\u5165crontab\u7684\u7b2c5\u7ae0\u8282\uff1a Executable programs or shell commands \uff08\u6807\u51c6\u547d\u4ee4\uff09 System calls (functions provided by the kernel)\uff08\u7cfb\u7edf\u8c03\u7528\uff09 Library calls (functions within program libraries)\uff08\u5e93\u51fd\u6570\uff09 Special files (usually found in /dev)\uff08\u8bbe\u5907\u8bf4\u660e\uff09 File formats and conventions eg /etc/passwd \uff08\u6587\u4ef6\u683c\u5f0f\uff09 Games \uff08\u6e38\u620f\u548c\u5a31\u4e50\uff09 Miscellaneous (including macro packages and conventions)\uff08\u6742\u9879\uff0c\u60ef\u4f8b\u4e0e\u534f\u5b9a\u7b49\u7f51\u7edc\u534f\u5b9a\u3001ASCII code\u7b49\u7b49\u7684\u8aaa\u660e\uff09 System administration commands (usually only for root) \uff08\u7ba1\u7406\u5458\u547d\u4ee4\uff09 Kernel routines [Non standard] \uff08\u5176\u4ed6Linux\u7279\u5b9a\u7684\uff0c\u7528\u6765\u5b58\u653e\u5185\u6838\u4f8b\u884c\u7a0b\u5e8f\u7684\u6587\u6863\u3002\uff09 man\u5e38\u7528\u5feb\u6377\u952e \u7ffb\u5c4f \u5411\u540e\u7ffb\u4e00\u5c4f\uff1aspace(\u7a7a\u683c\u952e) \u5411\u524d\u7ffb\u4e00\u5c4f\uff1ab \u5411\u540e\u7ffb\u4e00\u884c\uff1aEnter(\u56de\u8f66\u952e) \u5411\u524d\u7ffb\u4e00\u884c\uff1ak \u67e5\u627e /\u5173\u952e\u8bcd ?\u5173\u952e\u8bcd n (\u4e0b\u4e00\u4e2a) N (\u524d\u4e00\u4e2a) man \u4e2d\u6587\u5316\u3002\u5728 /etc/profile \u52a0\u5165\u4e0b\u9762alias\uff0c\u53ef\u4ee5\u5728man\u4e2d\u8f93\u51fa\u4e2d\u6587 # For man in zh_CH alias cman='man -M /usr/share/man/zh_CN'","title":"Manual pages"},{"location":"linux/Administration/02/#display-descriptions","text":"whatis command","title":"Display descriptions:"},{"location":"linux/Administration/02/#info-pages","text":"info command # info # info top From the terminal window display the info pages for the info command by entering: # info info Move the cursor to the line referring to (Invoking Info) by pressing Tab Tab Follow the link by pressing Enter Move the cursor to the link Note Custom Key Bindings: by pressing Tab (6 times) Follow the link by pressing Enter Return to the page Note Custom Key Bindings: by typing (lowercase L): l Exit the info file by typing: q","title":"Info pages:"},{"location":"linux/Administration/02/#pwd-command","text":"Display the current working directory","title":"pwd command"},{"location":"linux/Administration/02/#cd-command","text":"Change directory","title":"cd command"},{"location":"linux/Administration/02/#ls-command","text":"Display directory contents * Display hidden files with -a option * Detailed listing with -l option * Output is recursive, including all subdirectories with -R option * With option -F After each name, a character indicates the file type (\u201c/\u201d for directories, \u201c*\u201d for executable files, \u201c|\u201d for FIFO files, \u201c@\u201d symbolic link).","title":"ls command"},{"location":"linux/Administration/02/#cp-command","text":"Copy a file or directory Syntax: cp [option] Option -a : Copies a directory and subdirectories (compare -R ); symbolic links, file permissions, owners, and time stamps are not changed. \u5b83\u4fdd\u7559\u7b26\u53f7\u94fe\u63a5\u3001\u6587\u4ef6\u5c5e\u6027\uff0c\u5e76\u590d\u5236\u76ee\u5f55\u4e0b\u7684\u6240\u6709\u5185\u5bb9\u3002\u5176\u4f5c\u7528\u7b49\u4e8e-dpR\u53c2\u6570\u7ec4\u5408\u3002 Option -I : Asks before overwriting. Option -R , -r : Copies directories recursively (the directory and any subdirectories). \u9012\u5f52\u62f7\u8d1d\uff0c\u5305\u542b\u5b50\u76ee\u5f55\u53ca\uff08\u9690\u542b\uff09\u6587\u4ef6\uff0c\u7ee7\u627f\u76ee\u6807\u76ee\u5f55\u7684\u6743\u9650\u548c\u5c5e\u6027\u7b49 Option -l : Makes hardlinks instead of copying (\u521b\u5efa\u786c\u94fe\u63a5\u7684\u53e6\u5916\u4e00\u4e2a\u65b9\u6cd5) Option -s : Makes symbolic instead of copying (\u521b\u5efa\u7b26\u53f7\u94fe\u63a5\u7684\u53e6\u5916\u4e00\u4e2a\u65b9\u6cd5) Option -u : Copies a file only when the source file is newer than the destination file or when the destination file is missing. Option -p : \u8fde\u540c\u6863\u6848\u7684\u5c5e\u6027\u4e00\u8d77\u590d\u5236\u8fc7\u53bb\uff0c\u5305\u62ec\u4fee\u6539\u65f6\u95f4\u3001\u8bbf\u95ee\u6743\u9650\u3001\u6240\u6709\u8005\u7ec4\u7b49\uff0c\u800c\u975e\u4f7f\u7528\u9884\u8bbe\u5c5e\u6027\uff1b Labs: Initiate directories and files mySUSE:~ # su - pmgr pmgr@mySUSE:~> mkdir /data/program pmgr@mySUSE:~> mkdir /data/program/general pmgr@mySUSE:~> mkdir /data/program/general/staffing pmgr@mySUSE:~> touch /data/program/general/program_scope pmgr@mySUSE:~> touch /data/program/general/staffing/assignment mySUSE:~ # su - pm1 pm1@mySUSE:~> mkdir /data/project1 pm1@mySUSE:~> mkdir /data/project1/iot pm1@mySUSE:~> mkdir /data/project1/iot/bigdata pm1@mySUSE:~> touch /data/project1/iot/devicelist pm1@mySUSE:~> touch /data/project1/iot/bigdata/math_lib mySUSE:~ # su - pm2 pm2@mySUSE:~> mkdir /data/project2 pm2@mySUSE:~> mkdir /data/project2/erp pm2@mySUSE:~> mkdir /data/project2/erp/fin pm2@mySUSE:~> touch /data/project2/erp/erp_vision pm2@mySUSE:~> touch /data/project2/erp/fin/fin_ar pm2@mySUSE:~> chmod g+w /data/project2/erp/erp_vision pmgr@mySUSE:~> ln /data/project2/erp/erp_vision /data/program/general/p2_erp_version ( \u521b\u5efa\u786c\u94fe\u63a5\uff0c\u5f53\u524d\u7528\u6237\u9700\u8981\u5bf9\u6e90\u6587\u4ef6erp_vision\u6709w\u6743\u9650 ) pmgr@mySUSE:~> ln -s /data/project1/iot/devicelist /data/program/general/p1_devicelist ( \u521b\u5efa\u7b26\u53f7\u94fe\u63a5\uff0c\u4e0d\u9a8c\u8bc1\u5f53\u524d\u7528\u6237\u662f\u5426\u5bf9\u6e90\u6587\u4ef6devicelist\u6709\u6743\u9650 ) mySUSE:~ # tree /data /data \u251c\u2500\u2500 program \u2502 \u2514\u2500\u2500 general \u2502 \u251c\u2500\u2500 p1_devicelist -> /data/project1/iot/devicelist \u2502 \u251c\u2500\u2500 p2_erp_version \u2502 \u251c\u2500\u2500 program_scope \u2502 \u2514\u2500\u2500 staffing \u2502 \u2514\u2500\u2500 assignment \u251c\u2500\u2500 project1 \u2502 \u2514\u2500\u2500 iot \u2502 \u251c\u2500\u2500 bigdata \u2502 \u2502 \u2514\u2500\u2500 math_lib \u2502 \u2514\u2500\u2500 devicelist \u2514\u2500\u2500 project2 \u2514\u2500\u2500 erp \u251c\u2500\u2500 erp_vision \u2514\u2500\u2500 fin \u2514\u2500\u2500 fin_ar pmgr@mySUSE:~> cp -R /data/project1 /data/program/ ( /data/program/project1\u7684\u7528\u6237\u548c\u7ec4\u90fd\u7ee7\u627f\u4e86/data/program/ ) pmgr@mySUSE:~> cp -a /data/project2 /data/program/ ( /data/program/project2\u7684\u7528\u6237\u7ee7\u627f\u4e86/data/program/\uff0c\u4f46\u7ec4\u8fd8\u662f\u4fdd\u7559\u539f\u6765\u7684 )","title":"cp command"},{"location":"linux/Administration/02/#mv-command","text":"Move or rename a file or directory Option -i : Asks for confirmation before moving or renaming a file. This prevents existing files with the same name from being overwritten. Option -u : Only moves files that are newer than the target files of the same name. pmgr@mySUSE:/data/program/general> cp program_scope ./staffing/ pmgr@mySUSE:/data/program/general> mv -i program_scope ./staffing/ mv: overwrite './staffing/program_scope'? n","title":"mv command"},{"location":"linux/Administration/02/#rm-command","text":"Delete a file or directory Option -i : Asks for confirmation before deleting. Option -r : (recursively) Allows full directories to be deleted. Option -f : (force) By default, rm asks for confirmation if the file that should be deleted is read-only. Using this option, the files are deleted without asking for confirmation.","title":"rm command"},{"location":"linux/Administration/02/#mkdir-command","text":"Create a new directory Option -p lets you create a complete path (\u5c42\u7ea7\u8def\u5f84\u4e00\u6b21\u521b\u5efa) pmgr@mySUSE:/data> mkdir -p industry/utilities pmgr@mySUSE:/data> tree ./industry/ ./industry/ \u2514\u2500\u2500 utilities","title":"mkdir command"},{"location":"linux/Administration/02/#rmdir-command","text":"Remove an empty directory. The directory or directories must be empty before you can delete them.","title":"rmdir command"},{"location":"linux/Administration/02/#ln-command","text":"Create a link Default: Hard link Symbolic link with -s option Syntax: ln [-s] ","title":"ln command"},{"location":"linux/Administration/02/#touch-command","text":"Change the access and modification times Create an empty file if the given file does not exist. Change the time stamp of a file. Option -a : Changes only the time of the last read access (access time). Option -m : Changes only the time of the last modification (modification time). Option -r file : Sets the time stamp of file instead of the current time. Option -t time : Instead of the current time, sets time (structure: [[CC]YY]MMDDhhmm.[ss] ([Century]Year] Month Day Hour Minute [Seconds], two digits in each)) pmgr@mySUSE:/data/industry> touch readme pmgr@mySUSE:/data/industry> touch -a readme pmgr@mySUSE:/data/industry> touch -m readme pmgr@mySUSE:/data/industry> stat readme File: readme Size: 0 Blocks: 0 IO Block: 4096 regular empty file Device: 3dh/61d Inode: 338 Links: 1 Access: (0644/-rw-r--r--) Uid: ( 1003/ pmgr) Gid: ( 1000/ admins) Access: 2019-03-31 10:07:47.489055973 +0800 Modify: 2019-03-31 10:07:58.805109884 +0800 Change: 2019-03-31 10:07:58.805109884 +0800 Birth: -","title":"touch command"},{"location":"linux/Administration/02/#cat-command","text":"Concatenates files","title":"cat command"},{"location":"linux/Administration/02/#tac-command","text":"Same as cat, but displays the file(s) in reverse pmgr@mySUSE:/data/industry> cat readme line 1 line 2 line 3 pmgr@mySUSE:/data/industry> tac readme line 3 line 2 line 1","title":"tac command"},{"location":"linux/Administration/02/#more-command","text":"Display file contents one page at a time","title":"more command"},{"location":"linux/Administration/02/#less-command","text":"Displays file contents for better navigation","title":"less command"},{"location":"linux/Administration/02/#head-command","text":"Displays the first 10 lines of a file. To set the number of lines use the -n option pmgr@mySUSE:/data/industry> head readme line 1 line 2 line 3 line 4 line 5 line 6 line 7 line 8 line 9 line 10 pmgr@mySUSE:/data/industry> head -n 5 readme line 1 line 2 line 3 line 4 line 5","title":"head command"},{"location":"linux/Administration/02/#tail-command","text":"Display the last lines of a file To set the number of lines use the -n option To output appended data use -f option, displays a continuously updated view of the last lines of a file. To exit tail -f, press Ctrl+C. pmgr@mySUSE:/data/industry> tail -n 6 readme line 10 line 11 line 12 line 13 line 14 line 15","title":"tail command"},{"location":"linux/Administration/02/#tar-command","text":"Create, expand or list archive files Use option c to create an archive Use option f to specify the archive file name Use option v for verbose mode Use option x to extract an archive Use option t to list the content of an archive Use option z to (un-)compress the archive with gzip Use option j to (un-)compress the archive with bzip The /etc directory (include sub-directories) is backed up to the /backup/etc.tar file pmgr@mySUSE:~> tar -cvf /data/backup/project1.tar /data/project1/ pmgr@mySUSE:~> tar -cvf /data/backup/project2.tar /data/project2/ pmgr@mySUSE:~> tar -cv --exclude='*.conf' -f /data/backup/project2a.tar /data/project2/ View the contents of an archive. Some .conf files are excluded in project2a.tar file. pmgr@mySUSE:~> tar -tvf /data/backup/project2.tar drwxr-xr-x pm2/project2 0 2019-03-31 16:47 data/project2/ drwxr-xr-x pm2/project2 0 2019-03-31 16:47 data/project2/erp/ drwxr-xr-x pm2/project2 0 2019-03-31 16:47 data/project2/erp/fin/ -rw-r--r-- pm2/project2 0 2019-03-29 16:06 data/project2/erp/fin/fin_ar -rw-r--r-- pm2/project2 0 2019-03-31 16:47 data/project2/erp/fin/fin.conf -rw-rw-r-- pm2/project2 0 2019-03-29 16:06 data/project2/erp/erp_vision -rw-r--r-- pm2/project2 0 2019-03-31 16:47 data/project2/erp/erp.conf -rw-r--r-- pm2/project2 0 2019-03-31 16:47 data/project2/project2.conf pmgr@mySUSE:~> tar -tvf /data/backup/project2a.tar drwxr-xr-x pm2/project2 0 2019-03-31 16:47 data/project2/ drwxr-xr-x pm2/project2 0 2019-03-31 16:47 data/project2/erp/ drwxr-xr-x pm2/project2 0 2019-03-31 16:47 data/project2/erp/fin/ -rw-r--r-- pm2/project2 0 2019-03-29 16:06 data/project2/erp/fin/fin_ar -rw-rw-r-- pm2/project2 0 2019-03-29 16:06 data/project2/erp/erp_vision Unpack and write all files in the archive to the current directory. Extract to another directory by using the -C option pmgr@mySUSE:~> mkdir project1.backup pmgr@mySUSE:~> tar -xvf /data/backup/project1.tar -C /data/backup/project1.backup/ Incremental backup with tar command pmgr@mySUSE:~> tar -g snapshot_program -cvf /data/backup/bkp_program_full.tar /data/program/ pmgr@mySUSE:~> tar -tvf /data/backup/bkp_program_full.tar pmgr@mySUSE:~> touch /data/program/general/general.conf pmgr@mySUSE:~> tar -g snapshot_program -cvf /data/backup/bkp_program_inc.tar /data/program/ pmgr@mySUSE:~> rm -rf program/ pmgr@mySUSE:~> tar -xvf /data/backup/bkp_program_inc.tar -C /data/","title":"tar command"},{"location":"linux/Administration/02/#cpio-command","text":"Another archiving command","title":"cpio command"},{"location":"linux/Administration/02/#gzip-command","text":"Compress files using the gzip algorithm Option -c : Compresses the file without modifying the original file. The result is written to the standard output (usually the screen). From there, it can be redirected to a file with \u201c>\u201d. Option -d : Decompresses the specified file (gunzip) Option -r : Compresses and decompresses files in all subdirectories. Option -1 to -9, --fast, --best : Controls the compression speed: -1 means --fast and causes a quick compression but produces larger files, -9 corresponds to --best and requires more computing time but produces smaller files. The default setting is -6.","title":"gzip command"},{"location":"linux/Administration/02/#gunzip-command","text":"Expand files compressed with gzip","title":"gunzip command"},{"location":"linux/Administration/02/#bzip2-command","text":"Compress files using the bzip2 algorithm Option -c : Option -d : Decompresses the specified file (bunzip2). Option -1 to -9 : Controls the compression speed: -1 causes a quick compression but produces larger files, -9 requires more computing time but produces smaller files. The default setting is -9 .","title":"bzip2 command"},{"location":"linux/Administration/02/#bunzip2-command","text":"Expand files compressed with bzip","title":"bunzip2 command"},{"location":"linux/Administration/02/#rsync-command","text":"Copy only deltas between two directories. A key benefit of using rsync is that when copying data, rsync compares the source and the target directory and transfers only data that has changed or has been created. \u4ec5\u590d\u5236\u4e24\u4e2a\u76ee\u5f55\u4e4b\u95f4\u7684\u589e\u91cf\u3002 \u4f7f\u7528rsync\u7684\u4e00\u4e2a\u4e3b\u8981\u597d\u5904\u662f\uff0c\u5728\u590d\u5236\u6570\u636e\u65f6\uff0crsync\u4f1a\u6bd4\u8f83\u6e90\u76ee\u5f55\u548c\u76ee\u6807\u76ee\u5f55\uff0c\u5e76\u4ec5\u4f20\u8f93\u5df2\u66f4\u6539\u6216\u5df2\u521b\u5efa\u7684\u6570\u636e\u3002 Local or via network \u672c\u5730\u6216\u901a\u8fc7\u7f51\u7edc Uses ssh as default transport \u4f7f\u7528ssh\u4f5c\u4e3a\u9ed8\u8ba4\u4f20\u8f93 Can talk to rsync daemon on the remote machine \u53ef\u4ee5\u4e0e\u8fdc\u7a0b\u8ba1\u7b97\u673a\u4e0a\u7684rsync\u5b88\u62a4\u7a0b\u5e8f\u901a\u4fe1 Note: rsync must be installed on both the source and the target computer for this to work. \u5fc5\u987b\u5728\u6e90\u8ba1\u7b97\u673a\u548c\u76ee\u6807\u8ba1\u7b97\u673a\u4e0a\u5b89\u88c5rsync\u624d\u80fd\u4f7f\u5176\u6b63\u5e38\u5de5\u4f5c\u3002 As the default shell used by rsync is ssh, the -e option only needs to be used when you want to use something else than ssh. \u7531\u4e8ersync\u4f7f\u7528\u7684\u9ed8\u8ba4shell\u662fssh\uff0c\u56e0\u6b64\u53ea\u6709\u5728\u60f3\u8981\u4f7f\u7528\u9664ssh\u4ee5\u5916\u7684\u5176\u4ed6\u5de5\u5177\u65f6\u624d\u9700\u8981\u4f7f\u7528-e\u9009\u9879\u3002 Options Option -a : Puts rsync into the archive mode. The -a option ensures the following are preserved \u4fdd\u7559 in the mirrored copy of the directory: Symbolic links (l option) Access permissions (p option) Owners (o option) Group membership (g option) Time stamp (t option) Option -x : Saves files on one file system only, which means that rsync does not follow symbolic links to other file systems. \u4e0d\u8de8\u6587\u4ef6\u7cfb\u7edf\uff0c\u53ea\u5728\u4e00\u4e2a\u6587\u4ef6\u7cfb\u7edf\u5185(don't cross filesyste* undaries) Option -v : Enables the verbose mode. Use this mode to output information about the transferred files and the progress of the copying process. \u8f93\u51fa\u4f20\u8f93\u8fc7\u7a0b\u7684\u7ec6\u8282\u4fe1\u606f Option -z : Compresses the data during the transfer. This is especially useful for remote synchronization. \u538b\u7f29\u65b9\u5f0f\u4f20\u8f93 Option --delete : Deletes files from the mirrored directory that no longer exist in the original directory. Option --exclude-from : Does not back up files listed in an exclude file. Local backup via rsync command pmgr@mySUSE:/data> rsync -av /data/industry/* /data/backup/industry/ sending incremental file list created directory /data/backup/industry readme utilities/ sent 264 bytes received 87 bytes 702.00 bytes/sec total size is 111 speedup is 0.32 pmgr@mySUSE:/data/industry/utilities> touch roadmap.txt pmgr@mySUSE:/data> rsync -av /data/industry/* /data/backup/industry/ sending incremental file list utilities/ utilities/roadmap.txt sent 171 bytes received 39 bytes 420.00 bytes/sec total size is 111 speedup is 0.53 pmgr@mySUSE:/data> rm roadmap.txt pmgr@mySUSE:/data> rsync -av /data/industry/* --delete /data/backup/industry/ sending incremental file list deleting utilities/roadmap.txt utilities/ sent 102 bytes received 41 bytes 286.00 bytes/sec total size is 111 speedup is 0.78","title":"rsync command"},{"location":"linux/Administration/02/#dd-command","text":"Copies files block by block Used to create disk or partition images Most important options: if =input_file `of``=output_file bs =block_size You can use the dd command to convert and copy files byte-wise. Normally dd reads from the standard input and writes the result to the standard output. But with the appropriate parameters, regular files can be addressed as well. You can copy all kinds of Linux data with this command, including entire hard disk partitions. You can even copy an entire installed system (or just parts of it). Copy file /etc/protocols to protocols.old. The default size for a record is 512 bytes. Below 45+1 means, 45 complete record of standard size and 1 incomplete record (less than 512 bytes pmgr@mySUSE:/data/program> dd if=/etc/protocols of=protocols.old bs=512 45+1 records in 45+1 records out 23259 bytes (23 kB, 23 KiB) copied, 0.000595392 s, 39.1 MB/s \u521b\u5efa\u4e00\u4e2a100M\u7684\u7a7a\u6587\u4ef6 pmgr@mySUSE:/data/program> dd if=/dev/zero of=datafile bs=100M count=2 2+0 records in 2+0 records out 209715200 bytes (210 MB, 200 MiB) copied, 2.79311 s, 75.1 MB/s \u5907\u4efd\u6574\u4e2a\u5206\u533a #dd if=/dev/sda1 of=boot.partition \u5236\u4f5cU\u76d8\u542f\u52a8\u76d8\uff08U\u76d8\u6302\u8f7d\u5230/dev/sdb\uff09 #dd if=/root/diskboot.img of=/dev/sdb bs=125682176 \u5907\u4efd\u786c\u76d8\u4e3b\u5f15\u5bfc\u8bb0\u5f55 #dd if=/dev/sda of=/tmp/mbr_copy bs=512 count=1 \u8fd8\u539f\u786c\u76d8\u4e3b\u5f15\u5bfc\u8bb0\u5f55 #dd if=/disk.mbr of=/dev/hda bs=512 count=1 \u5c06\u5185\u5b58\u91cc\u7684\u6570\u636e\u62f7\u8d1d\u5230root\u76ee\u5f55\u4e0b\u7684mem.bin\u6587\u4ef6 # dd if=/dev/mem of=/root/mem.bin bs=1024 \u62f7\u8d1d\u5149\u76d8\u6570\u636e\u5230root\u6587\u4ef6\u5939\u4e0b\uff0c\u5e76\u4fdd\u5b58\u4e3acd.iso\u6587\u4ef6 # dd if=/dev/cdrom of=/root/cd.iso \u5229\u7528\u968f\u673a\u7684\u6570\u636e\u586b\u5145\u786c\u76d8(\u9500\u6bc1\u786c\u76d8\u6570\u636e) # dd if=/dev/urandom of=/dev/hda1 \u6d4b\u8bd5\u786c\u76d8\u8bfb\u5199\u901f\u5ea6\u3002\u901a\u8fc7\u4e24\u4e2a\u547d\u4ee4\u8f93\u51fa\u7684\u6267\u884c\u65f6\u95f4\uff0c\u53ef\u4ee5\u8ba1\u7b97\u51fa\u6d4b\u8bd5\u786c\u76d8\u7684\u8bfb\uff0f\u5199\u901f\u5ea6\uff1a mySUSE:/data # dd if=/data/program/datafile bs=64k | dd of=/dev/null 3200+0 records in 3200+0 records out 209715200 bytes (210 MB, 200 MiB) copied, 0.67138 s, 312 MB/s 409600+0 records in 409600+0 records out 209715200 bytes (210 MB, 200 MiB) copied, 0.675912 s, 310 MB/s # dd if=/dev/zero of=/data/program/datafile bs=1024 count=100 \u5207\u5272\u5927\u6587\u4ef6bigfile\uff0c\u517198336321\u5b57\u8282\uff0c\u5219\uff1a # dd if=bigfile of=smallfile1 bs=1 count=20000000 # dd if=bigfile of=smallfile2 bs=1 count=20000000 skip=20000000 # dd if=bigfile of=smallfile3 bs=1 count=20000000 skip=40000000 # dd if=bigfile of=smallfile4 bs=1 count=20000000 skip=60000000 # dd if=bigfile of=smallfile5 bs=1 count=18336321 skip=80000000 \u5c06\u5207\u5272\u6587\u4ef6\u7ec4\u88c5 # dd if=smallfile1 of=bigfile bs=1 count=20000000 # dd if=smallfile2 of=bigfile bs=1 count=20000000 seek=20000000 # dd if=smallfile3 of=bigfile bs=1 count=20000000 seek=40000000 # dd if=smallfile4 of=bigfile bs=1 count=20000000 seek=60000000 # dd if=smallfile5 of=bigfile bs=1 count=18336321 seek=80000000 if: \u8981\u5207\u5272\u7684\u5927\u6587\u4ef6\u540d of: \u5207\u5272\u540e\u7684\u5b50\u6587\u4ef6\u540d bs: \u4ee5\u591a\u5c11\u5b57\u8282\u4f5c\u4e3a\u4e00\u4e2a\u5207\u5272\u8bb0\u5f55\u5355\u4f4d count: \u662f\u8981\u5207\u5272\u7684\u5355\u4f4d\u8bb0\u5f55\u6570 skip: \u8bf4\u660e\u5207\u5272\u65f6\u7684\u8d77\u70b9 seek: \u660e\u786e\u6307\u51fa\u5f00\u59cb\u4f4d\u7f6e","title":"dd command"},{"location":"linux/Administration/02/#find-command","text":"Search for files or directories Syntax: find path criterion [action] The find command has a multitude of options, a few of which are explained here. You can use the following arguments with the command: path: The section of the file system to search (the specified directory and all its subdirectories). If nothing is specified, the file system below the current directory is used. criterion: The properties the file should have (see below) action: Options that influence the following conditions or control the search as a whole The most important actions are: -print (default) -exec command With the -exec option, you can call up another command. This option is frequently used to link find and grep, as in the following: \u627e\u51fagen\u5f00\u5934\u7684\u6587\u4ef6 pmgr@dcmaster:/data> find . -name gen\\* ./program/general ./program/general/general.conf \u627e\u51fagen\u5f00\u5934\u7684\u6587\u4ef6\uff0c\u5e76\u5728\u6587\u4ef6\u5185\u5bb9\u4e2d\u67e5\u627exen\uff0c\u627e\u5230\u540e\u7ed3\u679c\u8f93\u51faxen pmgr@dcmaster:/data> find . -name gen\\* -type f -exec grep xen {} \\; xen xening The two brackets \u201c{}\u201d stand as placeholders for the file names which are found and passed to the grep command. The semicolon closes the -exec instruction. Because this is a special character, it is masked by placing a backslash in front of it. -ctime [\u00b1]days Searches for files whose last change took place no later than (no earlier than) a specified number of days ago. \u5728\u8fc7\u53bbn\u5929\u5185\u88ab\u4fee\u6539\u8fc7\u7684\u6587\u4ef6 mgr@dcmaster:/data> find . -ctime 1 . ./program/datafile -gid number Searches for files with the numeric GID (Group ID) number. (gid \u662f n) -group name Searches for files that are owned by the group name. Instead of a name, the numeric GID is allowed. (group \u540d\u79f0\u662f name) -name pattern Searches for files whose names contain the given pattern. If the pattern contains meta characters or wild cards, the name must be enclosed by quotation marks. Otherwise thename will be interpreted by the shell and not by find. -newer file Searches for files that were modified more recently than file. \u6bd4\u6587\u4ef6 file \u66f4\u65b0\u7684\u6587\u4ef6 pmgr@dcmaster:/data> find . -cnewer ./program/datafile . -size [\u00b1]size Matches files that are above or below a certain size. The size (in blocks of 512 bytes) is given as an argument. The suffix \u201cc\u201cswitches to byte and \u201ck\u201d to blocks of 1024bytes. A preceding \u201c+\u201d stands for all larger files and a \u201c-\u201d for all smaller files. (\u6587\u4ef6\u5927\u5c0f \u662f n \u2022 b \u4ee3\u8868 512 \u4f4d\u5143\u7ec4\u7684\u533a\u5757 \u2022 c \u8868\u793a\u5b57\u5143\u6570 \u2022 k \u8868\u793a kilo bytes \u2022 w \u662f\u4e8c\u4e2a\u4f4d\u5143\u7ec4 pmgr@dcmaster:/data> find . -size 20k ./backup/project2.tar -type file_type Searches for a file type. A file type can be one of the following: * c : \u6587\u4ef6\u7c7b\u578b\u662f c \u7684\u6587\u4ef6\u3002 * d: \u76ee\u5f55 * c: \u5b57\u578b\u88c5\u7f6e\u6587\u4ef6 * b: \u533a\u5757\u88c5\u7f6e\u6587\u4ef6 * p: \u5177\u540d\u8d2e\u5217 * f: \u4e00\u822c\u6587\u4ef6 * l: \u7b26\u53f7\u8fde\u7ed3 * s: socket -uid number Searches for files with the numeric UID (User ID) number. -user name Searches for files, which are owned by user name. Instead of a name, the numeric UID is allowed. \u5e38\u7528\u53c2\u6570 mount, -xdev : \u53ea\u68c0\u67e5\u548c\u6307\u5b9a\u76ee\u5f55\u5728\u540c\u4e00\u4e2a\u6587\u4ef6\u7cfb\u7edf\u4e0b\u7684\u6587\u4ef6\uff0c\u907f\u514d\u5217\u51fa\u5176\u5b83\u6587\u4ef6\u7cfb\u7edf\u4e2d\u7684\u6587\u4ef6 amin n : \u5728\u8fc7\u53bb n \u5206\u949f\u5185\u88ab\u8bfb\u53d6\u8fc7 anewer file : \u6bd4\u6587\u4ef6 file \u66f4\u665a\u88ab\u8bfb\u53d6\u8fc7\u7684\u6587\u4ef6 atime n : \u5728\u8fc7\u53bbn\u5929\u5185\u88ab\u8bfb\u53d6\u8fc7\u7684\u6587\u4ef6 pmgr@dcmaster:/data> find . -atime 1 ./program/datafile cmin n : \u5728\u8fc7\u53bb n \u5206\u949f\u5185\u88ab\u4fee\u6539\u8fc7 pmgr@dcmaster:/data> find . -cmin 20 empty : \u7a7a\u7684\u6587\u4ef6 ipath p, -path p : \u8def\u5f84\u540d\u79f0\u7b26\u5408 p \u7684\u6587\u4ef6\uff0cipath \u4f1a\u5ffd\u7565\u5927\u5c0f\u5199 name name, -iname name : \u6587\u4ef6\u540d\u79f0\u7b26\u5408 name \u7684\u6587\u4ef6\u3002iname \u4f1a\u5ffd\u7565\u5927\u5c0f\u5199 pid n : process id \u662f n \u7684\u6587\u4ef6 \u67e5\u627e\u5f53\u524d\u76ee\u5f55\u53ca\u5b50\u76ee\u5f55\u4e2d\u6240\u6709\u6587\u4ef6\u957f\u5ea6\u4e3a0\u7684\u666e\u901a\u6587\u4ef6\uff0c\u5e76\u5217\u51fa\u5b83\u4eec\u7684\u5b8c\u6574\u8def\u5f84 pmgr@dcmaster:/data> find . -type f -size 0 -exec ls -l {} \\; \u67e5\u627e\u524d\u76ee\u5f55\u4e2d\u6587\u4ef6\u5c5e\u4e3b\u5177\u6709\u8bfb\u3001\u5199\u6743\u9650\uff0c\u5e76\u4e14\u6587\u4ef6\u6240\u5c5e\u7ec4\u7684\u7528\u6237\u548c\u5176\u4ed6\u7528\u6237\u5177\u6709\u8bfb\u6743\u9650\u7684\u6587\u4ef6 pmgr@dcmaster:/data> find . -type f -perm 644 -exec ls -l {} \\; \u67e5\u627e/var/log\u76ee\u5f55\u4e2d\u66f4\u6539\u65f6\u95f4\u572817\u65e5\u4ee5\u524d\u7684\u666e\u901a\u6587\u4ef6\uff0c\u5e76\u5728\u5220\u9664\u4e4b\u524d\u8be2\u95ee\u5b83\u4eec pmgr@dcmaster:/data> find /var/log -type f -mtime +17 -ok rm {} \\; \u5c06\u76ee\u524d\u76ee\u5f55\u53ca\u5176\u5b50\u76ee\u5f55\u4e0b\u6240\u6709\u6700\u8fd1 1 \u5929\u5185\u66f4\u65b0\u8fc7\u7684\u6587\u4ef6\u5217\u51fa mgr@dcmaster:/data> find . -ctime 1 \u5c06\u76ee\u524d\u76ee\u5f55\u5176\u5176\u4e0b\u5b50\u76ee\u5f55\u4e2d\u6240\u6709\u4e00\u822c\u6587\u4ef6\u5217\u51fa pmgr@dcmaster:/data> find . -type f \u5c06\u76ee\u524d\u76ee\u5f55\u53ca\u5176\u5b50\u76ee\u5f55\u4e0b\u6240\u6709\u5ef6\u4f38\u6863\u540d\u662fconf \u7684\u6587\u4ef6\u5217\u51fa\u6765 pmgr@dcmaster:/data> find . -name \"*.conf\"","title":"find command"},{"location":"linux/Administration/02/#which-command","text":"Searches all paths listed in the variable $PATH and returns the full path of the command The which command searches all paths listed in the variable $PATH for the specified command and returns the full path of the command. In the variable \\(PATH, the most important directoriesare listed where the shell looks for executable files. which\u547d\u4ee4\u641c\u7d22\u53d8\u91cf\\) PATH\u4e2d\u5217\u51fa\u7684\u6240\u6709\u8def\u5f84\u4ee5\u83b7\u53d6\u6307\u5b9a\u547d\u4ee4\uff0c\u5e76\u8fd4\u56de\u547d\u4ee4\u7684\u5b8c\u6574\u8def\u5f84\u3002 The which command is especially useful if several versions of a command exist in different directories and you want to know which version is executed when entered without specifying apath. \u5982\u679c\u547d\u4ee4\u7684\u591a\u4e2a\u7248\u672c\u5b58\u5728\u4e8e\u4e0d\u540c\u7684\u76ee\u5f55\u4e2d\uff0c\u5e76\u4e14\u60a8\u60f3\u77e5\u9053\u5728\u8f93\u5165\u65f6\u6267\u884c\u4e86\u54ea\u4e2a\u7248\u672c\u800c\u672a\u6307\u5b9a\u8def\u5f84\uff0c\u90a3\u4e48which\u547d\u4ee4\u7279\u522b\u6709\u7528\u3002 NOTE: To see the content of a variable, use the echo command Options Description -n<\u6587\u4ef6\u540d\u957f\u5ea6> \u6307\u5b9a\u6587\u4ef6\u540d\u957f\u5ea6\uff0c\u6307\u5b9a\u7684\u957f\u5ea6\u5fc5\u987b\u5927\u4e8e\u6216\u7b49\u4e8e\u6240\u6709\u6587\u4ef6\u4e2d\u6700\u957f\u7684\u6587\u4ef6\u540d\u3002 -p<\u6587\u4ef6\u540d\u957f\u5ea6> \u4e0e-n\u53c2\u6570\u76f8\u540c\uff0c\u4f46\u6b64\u5904\u7684<\u6587\u4ef6\u540d\u957f\u5ea6>\u5305\u62ec\u4e86\u6587\u4ef6\u7684\u8def\u5f84\u3002 -w \u6307\u5b9a\u8f93\u51fa\u65f6\u680f\u4f4d\u7684\u5bbd\u5ea6\u3002 -V \u663e\u793a\u7248\u672c\u4fe1\u606f # which grep /usr/bin/grep # which -V grep GNU which v2.21, Copyright (C) 1999 - 2015 Carlo Wood. GNU which comes with ABSOLUTELY NO WARRANTY; This program is free software; your freedom to use, change and distribute this program is protected by the GPL.","title":"which command"},{"location":"linux/Administration/02/#whereis-command","text":"The whereis command returns the binaries (option -b), manual pages (option -m), and the source code (option -s) of the specified command. If no option is used, all this information is returned, provided the information is available. This command is faster than find, but it is less thorough. Attempts to locate the desired program in the standard Linux places, and in the places specified by $PATH and $MANPATH . \u5c1d\u8bd5\u5728\u6807\u51c6Linux\u4f4d\u7f6e\u548c\u6307\u5b9a\u4f4d\u7f6e( \\(PATH\u548c\\) MANPATH)\u627e\u5230\u6240\u9700\u7684\u7a0b\u5e8f Options Description -b \u53ea\u67e5\u627e\u4e8c\u8fdb\u5236\u6587\u4ef6\u3002 -B<\u76ee\u5f55> \u53ea\u5728\u8bbe\u7f6e\u7684\u76ee\u5f55\u4e0b\u67e5\u627e\u4e8c\u8fdb\u5236\u6587\u4ef6\u3002 -f \u4e0d\u663e\u793a\u6587\u4ef6\u540d\u524d\u7684\u8def\u5f84\u540d\u79f0\u3002 -m \u53ea\u67e5\u627e\u8bf4\u660e\u6587\u4ef6\u3002 -M<\u76ee\u5f55> \u53ea\u5728\u8bbe\u7f6e\u7684\u76ee\u5f55\u4e0b\u67e5\u627e\u8bf4\u660e\u6587\u4ef6\u3002 -s \u53ea\u67e5\u627e\u539f\u59cb\u4ee3\u7801\u6587\u4ef6\u3002 -S<\u76ee\u5f55> \u53ea\u5728\u8bbe\u7f6e\u7684\u76ee\u5f55\u4e0b\u67e5\u627e\u539f\u59cb\u4ee3\u7801\u6587\u4ef6\u3002 -u \u67e5\u627e\u4e0d\u5305\u542b\u6307\u5b9a\u7c7b\u578b\u7684\u6587\u4ef6\u3002 \u4ee5\u4e0b\u8f93\u51fa\u4fe1\u606f\u4ece\u5de6\u81f3\u53f3\u5206\u522b\u4e3a\u67e5\u8be2\u7684\u7a0b\u5e8f\u540d\u3001bash\u8def\u5f84\u3001bash\u7684man\u624b\u518c\u9875\u8def\u5f84\u3002 # whereis grep grep: /usr/bin/grep /bin/grep /usr/share/man/man1/grep.1.gz /usr/share/info/grep.info.gz \u663e\u793abash \u547d\u4ee4\u7684\u4e8c\u8fdb\u5236\u7a0b\u5e8f # whereis -b grep grep: /usr/bin/grep /bin/grep \u663e\u793abash \u547d\u4ee4\u7684\u5e2e\u52a9\u6587\u4ef6 # whereis -m grep grep: /usr/share/man/man1/grep.1.gz /usr/share/info/grep.info.gz","title":"whereis command"},{"location":"linux/Administration/02/#type-command","text":"The type command shows what kind of command is executed when you enter it: \u547d\u4ee4\u7684\u7c7b\u578b a shell built-in command (an essential command that is hard coded in the shell), for example type or cd an external command (called by the shell) an alias, for example ls. An alias defines shortcuts and synonyms for commonly used shell commands. a function The -a option delivers all instances of a command bearing this name in the file system. NOTE: If you want to have more information about a file format, you can use the file command. \u4e0d\u9002\u7528\u4e8e\u666e\u901a\u6587\u4ef6 dcmaster:/data/shell # type pwd.txt -bash: type: pwd.txt: not found \u4e0d\u9002\u7528\u4e8e\u81ea\u5b9a\u4e49\u53ef\u6267\u884c\u811a\u672c dcmaster:/data/shell # type math.sh -bash: type: math.sh: not found \u7cfb\u7edf\u547d\u4ee4 dcmaster:/data/shell # type rsync rsync is /usr/bin/rsync \u522b\u540d dcmaster:/data/shell # type l l is aliased to `ls -alF'","title":"type command"},{"location":"linux/Administration/02/#file-command","text":"file\u547d\u4ee4\u7528\u4e8e\u8fa8\u8bc6\u6587\u4ef6\u7c7b\u578b -b \u5217\u51fa\u8fa8\u8bc6\u7ed3\u679c\u65f6\uff0c\u4e0d\u663e\u793a\u6587\u4ef6\u540d\u79f0\u3002 -c \u8be6\u7ec6\u663e\u793a\u6307\u4ee4\u6267\u884c\u8fc7\u7a0b\uff0c\u4fbf\u4e8e\u6392\u9519\u6216\u5206\u6790\u7a0b\u5e8f\u6267\u884c\u7684\u60c5\u5f62\u3002 -f <\u540d\u79f0\u6587\u4ef6> \u6307\u5b9a\u540d\u79f0\u6587\u4ef6\uff0c\u5176\u5185\u5bb9\u6709\u4e00\u4e2a\u6216\u591a\u4e2a\u6587\u4ef6\u540d\u79f0\u65f6\uff0c\u8ba9file\u4f9d\u5e8f\u8fa8\u8bc6\u8fd9\u4e9b\u6587\u4ef6\uff0c\u683c\u5f0f\u4e3a\u6bcf\u5217\u4e00\u4e2a\u6587\u4ef6\u540d\u79f0\u3002 -L \u76f4\u63a5\u663e\u793a\u7b26\u53f7\u8fde\u63a5\u6240\u6307\u5411\u7684\u6587\u4ef6\u7684\u7c7b\u522b\u3002 -m<\u9b54\u6cd5\u6570\u5b57\u6587\u4ef6> \u6307\u5b9a\u9b54\u6cd5\u6570\u5b57\u6587\u4ef6\u3002 -v \u663e\u793a\u7248\u672c\u4fe1\u606f\u3002 -z \u5c1d\u8bd5\u53bb\u89e3\u8bfb\u538b\u7f29\u6587\u4ef6\u7684\u5185\u5bb9\u3002 dcmaster:/data/linktype # l -rw-r--r-- 3 root root 44 May 3 09:50 file -rw-r--r-- 3 root root 44 May 3 09:50 hardlinkfile1 -rw-r--r-- 3 root root 44 May 3 09:50 hardlinkfile2 lrwxrwxrwx 1 root root 4 Mar 28 15:21 symlinkfile1 -> file lrwxrwxrwx 1 root root 12 Mar 28 15:49 symlinkfile1-1 -> symlinkfile1 lrwxrwxrwx 1 root root 4 Mar 28 15:23 symlinkfile2 -> file dcmaster:/data/linktype # file hardlinkfile1 hardlinkfile1: ASCII text dcmaster:/data/linktype # file -i hardlinkfile1 hardlinkfile1: text/plain; charset=us-ascii dcmaster:/data/linktype # file /data/linktype/ /data/linktype/: directory dcmaster:/data/linktype # file -L /data/linktype/ /data/linktype/: directory dcmaster:/data/linktype # file -i /data/linktype/ /data/linktype/: inode/directory; charset=binary dcmaster:/data/linktype # file symlinkfile1 symlinkfile1: symbolic link to file dcmaster:/data/linktype # file -i symlinkfile1 symlinkfile1: inode/symlink; charset=binary","title":"file command"},{"location":"linux/Administration/02/#grep-command","text":"You can specify search patterns in the form of regular expressions, although the basic grep command is limited in this regard. To search for more complex patterns, use the egrep command (or grep -E ) instead, which accepts extended regular expressions. To avoid having special characters in search patterns interpreted by the shell, enclose the pattern in quotation marks. Syntax: grep [options] search_pattern filename * egrep = grep -E * rgrep \u53c2\u6570 -a \u6216 --text : \u4e0d\u8981\u5ffd\u7565\u4e8c\u8fdb\u5236\u7684\u6570\u636e\u3002 -A<\u663e\u793a\u884c\u6570> \u6216 --after-context=<\u663e\u793a\u884c\u6570> : \u9664\u4e86\u663e\u793a\u7b26\u5408\u8303\u672c\u6837\u5f0f\u7684\u90a3\u4e00\u5217\u4e4b\u5916\uff0c\u5e76\u663e\u793a\u8be5\u884c\u4e4b\u540e\u7684\u5185\u5bb9\u3002 -b \u6216 --byte-offset : \u5728\u663e\u793a\u7b26\u5408\u6837\u5f0f\u7684\u90a3\u4e00\u884c\u4e4b\u524d\uff0c\u6807\u793a\u51fa\u8be5\u884c\u7b2c\u4e00\u4e2a\u5b57\u7b26\u7684\u7f16\u53f7\u3002 -B<\u663e\u793a\u884c\u6570> \u6216 --before-context=<\u663e\u793a\u884c\u6570> : \u9664\u4e86\u663e\u793a\u7b26\u5408\u6837\u5f0f\u7684\u90a3\u4e00\u884c\u4e4b\u5916\uff0c\u5e76\u663e\u793a\u8be5\u884c\u4e4b\u524d\u7684\u5185\u5bb9\u3002 -c \u6216 --count : \u8ba1\u7b97\u7b26\u5408\u6837\u5f0f\u7684\u5217\u6570\u3002 -C<\u663e\u793a\u884c\u6570> \u6216 --context=<\u663e\u793a\u884c\u6570> \u6216 -<\u663e\u793a\u884c\u6570> : \u9664\u4e86\u663e\u793a\u7b26\u5408\u6837\u5f0f\u7684\u90a3\u4e00\u884c\u4e4b\u5916\uff0c\u5e76\u663e\u793a\u8be5\u884c\u4e4b\u524d\u540e\u7684\u5185\u5bb9\u3002 -d <\u52a8\u4f5c> \u6216 --directories=<\u52a8\u4f5c> : \u5f53\u6307\u5b9a\u8981\u67e5\u627e\u7684\u662f\u76ee\u5f55\u800c\u975e\u6587\u4ef6\u65f6\uff0c\u5fc5\u987b\u4f7f\u7528\u8fd9\u9879\u53c2\u6570\uff0c\u5426\u5219grep\u6307\u4ee4\u5c06\u56de\u62a5\u4fe1\u606f\u5e76\u505c\u6b62\u52a8\u4f5c\u3002 -e<\u8303\u672c\u6837\u5f0f> \u6216 --regexp=<\u8303\u672c\u6837\u5f0f> : \u6307\u5b9a\u5b57\u7b26\u4e32\u505a\u4e3a\u67e5\u627e\u6587\u4ef6\u5185\u5bb9\u7684\u6837\u5f0f\u3002 -E \u6216 --extended-regexp : \u5c06\u6837\u5f0f\u4e3a\u5ef6\u4f38\u7684\u666e\u901a\u8868\u793a\u6cd5\u6765\u4f7f\u7528\u3002 -f<\u89c4\u5219\u6587\u4ef6> \u6216 --file=<\u89c4\u5219\u6587\u4ef6> : \u6307\u5b9a\u89c4\u5219\u6587\u4ef6\uff0c\u5176\u5185\u5bb9\u542b\u6709\u4e00\u4e2a\u6216\u591a\u4e2a\u89c4\u5219\u6837\u5f0f\uff0c\u8ba9grep\u67e5\u627e\u7b26\u5408\u89c4\u5219\u6761\u4ef6\u7684\u6587\u4ef6\u5185\u5bb9\uff0c\u683c\u5f0f\u4e3a\u6bcf\u884c\u4e00\u4e2a\u89c4\u5219\u6837\u5f0f\u3002 -F \u6216 --fixed-regexp : \u5c06\u6837\u5f0f\u89c6\u4e3a\u56fa\u5b9a\u5b57\u7b26\u4e32\u7684\u5217\u8868\u3002 -G \u6216 --basic-regexp : \u5c06\u6837\u5f0f\u89c6\u4e3a\u666e\u901a\u7684\u8868\u793a\u6cd5\u6765\u4f7f\u7528\u3002 -h \u6216 --no-filename : \u5728\u663e\u793a\u7b26\u5408\u6837\u5f0f\u7684\u90a3\u4e00\u884c\u4e4b\u524d\uff0c\u4e0d\u6807\u793a\u8be5\u884c\u6240\u5c5e\u7684\u6587\u4ef6\u540d\u79f0\u3002 -H \u6216 --with-filename : \u5728\u663e\u793a\u7b26\u5408\u6837\u5f0f\u7684\u90a3\u4e00\u884c\u4e4b\u524d\uff0c\u8868\u793a\u8be5\u884c\u6240\u5c5e\u7684\u6587\u4ef6\u540d\u79f0\u3002 -i \u6216 --ignore-case : \u5ffd\u7565\u5b57\u7b26\u5927\u5c0f\u5199\u7684\u5dee\u522b\u3002 -l \u6216 --file-with-matches : \u5217\u51fa\u6587\u4ef6\u5185\u5bb9\u7b26\u5408\u6307\u5b9a\u7684\u6837\u5f0f\u7684\u6587\u4ef6\u540d\u79f0\u3002 -L \u6216 --files-without-match : \u5217\u51fa\u6587\u4ef6\u5185\u5bb9\u4e0d\u7b26\u5408\u6307\u5b9a\u7684\u6837\u5f0f\u7684\u6587\u4ef6\u540d\u79f0\u3002 -n \u6216 --line-number : \u5728\u663e\u793a\u7b26\u5408\u6837\u5f0f\u7684\u90a3\u4e00\u884c\u4e4b\u524d\uff0c\u6807\u793a\u51fa\u8be5\u884c\u7684\u5217\u6570\u7f16\u53f7\u3002 -o \u6216 --only-matching : \u53ea\u663e\u793a\u5339\u914dPATTERN \u90e8\u5206\u3002 -q \u6216 --quiet\u6216--silent : \u4e0d\u663e\u793a\u4efb\u4f55\u4fe1\u606f\u3002 -r \u6216 --recursive : \u6b64\u53c2\u6570\u7684\u6548\u679c\u548c\u6307\u5b9a\"-d recurse\"\u53c2\u6570\u76f8\u540c\u3002 -s \u6216 --no-messages : \u4e0d\u663e\u793a\u9519\u8bef\u4fe1\u606f\u3002 -v \u6216 --revert-match : \u663e\u793a\u4e0d\u5305\u542b\u5339\u914d\u6587\u672c\u7684\u6240\u6709\u884c\u3002 -V \u6216 --version : \u663e\u793a\u7248\u672c\u4fe1\u606f\u3002 -w \u6216 --word-regexp : \u53ea\u663e\u793a\u5168\u5b57\u7b26\u5408\u7684\u5217\u3002 -x --line-regexp : \u53ea\u663e\u793a\u5168\u5217\u7b26\u5408\u7684\u5217\u3002 -y : \u6b64\u53c2\u6570\u7684\u6548\u679c\u548c\u6307\u5b9a\"-i\"\u53c2\u6570\u76f8\u540c\u3002 \u5728\u5f53\u524d\u76ee\u5f55\u4e2d\uff0c\u67e5\u627e\u540e\u7f00\u6709conf\u5b57\u6837\u7684\u6587\u4ef6\u4e2d\u5305\u542bxen\u5b57\u7b26\u4e32\u7684\u6587\u4ef6\uff0c\u5e76\u6253\u5370\u51fa\u8be5\u5b57\u7b26\u4e32\u7684\u884c\u3002 pmgr@dcmaster:/data/program/general> grep xen *.conf xen xening \u67e5\u627e\u524d\u7f00\u6709gen\u7684\u6587\u4ef6\u5305\u542bxen\u5b57\u7b26\u4e32\u7684\u6587\u4ef6 pmgr@dcmaster:/data/program/general> grep xen gen* xen xening \u4ee5\u9012\u5f52\u7684\u65b9\u5f0f\u67e5\u627e\u7b26\u5408\u6761\u4ef6\u7684\u6587\u4ef6\u3002\u67e5\u627e\u6307\u5b9a\u76ee\u5f55/data/program/\u53ca\u5176\u5b50\u76ee\u5f55\uff08\u5982\u679c\u5b58\u5728\u5b50\u76ee\u5f55\u7684\u8bdd\uff09\u4e0b\u6240\u6709\u6587\u4ef6\u4e2d\u5305\u542b\u5b57\u7b26\u4e32xen\u7684\u6587\u4ef6\uff0c\u5e76\u6253\u5370\u51fa\u8be5\u5b57\u7b26\u4e32\u6240\u5728\u884c\u7684\u5185\u5bb9 pmgr@dcmaster:/data> grep -r xen /data/program/ ./program/general/general.conf:xen ./program/general/general.conf:xening \u53cd\u5411\u67e5\u627e\u3002\u524d\u9762\u5404\u4e2a\u4f8b\u5b50\u662f\u67e5\u627e\u5e76\u6253\u5370\u51fa\u7b26\u5408\u6761\u4ef6\u7684\u884c\uff0c\u901a\u8fc7 -v \u53c2\u6570\u53ef\u4ee5\u6253\u5370\u51fa\u4e0d\u7b26\u5408\u6761\u4ef6\u884c\u7684\u5185\u5bb9\u3002\u67e5\u627e\u6587\u4ef6\u540d\u4e2d\u5305\u542bxen\u7684\u6587\u4ef6\u4e2d\u4e0d\u5305\u542bxen\u7684\u884c pmgr@dcmaster:/data/program/general> grep -v xen gen* Linux Test test \u67e5\u627e\u5f53\u524d\u76ee\u5f55\u4e0b\u5305\u542b\u5b57\u7b26\u4e32\u201cLinux\u201d\u7684\u6587\u4ef6 pmgr@dcmaster:/data/program/general> grep Linux * general.conf:Linux grep: staffing: Is a directory pmgr@dcmaster:/data/program/general> egrep Linux * general.conf:Linux grep: staffing: Is a directory","title":"grep command"},{"location":"linux/Administration/03/","text":"Shell \u00b6","title":"Shell"},{"location":"linux/Administration/03/#shell","text":"","title":"Shell"},{"location":"linux/SES/linux_ses_demo/","text":"SUSE Enterprise Storage 6 Installation and Basic Operation \u00b6 1. Installation \u00b6 1.1. Environment Setup \u00b6 In this demo, I use below environment, including VM setting and software installed. All VMs installed here was built on a physical host 10.58.121.68 . Host Server: 10.58.121.68 root / rootroot Account root / root123 Gateway: 10.58.120.1 Network Mask: 255.255.254.0 Nameserver: 10.58.32.32 10.33.50.20 Domain Search sha.me.corp dhcp.sha.me.corp me.corp ind.me.corp bgr.me.corp SUSE Server 15 SP1 Extensions and Modules were installed as below. [x] SUSE Enterprise Storage 6 [x] Basesystem Module 15 SP1 x86_64 [x] Server Applications Module 15 SP1 x86_64 Disable Services is as below: AppArmor Firewall Enable Services is as below. SSH Register SLES15.1 to local SMT. # SUSEConnect --url https://smtproxy.ind.me.corp Demo Environment summary is below. Alias Host Name Memory Disk eth0 eth0 mac address sles01 admin (salt-master) 16GB Disk1: 20G 10.58.121.181/23 52:54:00:23:7d:cd sles02 data1 16GB Disk1: 20G 10.58.121.182/23 52:54:00:5f:ce:6f Disk2: 8G Disk3: 8G Disk4: 8G sles03 data2 16GB Disk1: 20G 10.58.121.183/23 52:54:00:6f:f2:23 Disk2: 8G Disk3: 8G Disk4: 8G sles04 data3 16GB Disk1: 20G 10.58.121.184/23 52:54:00:93:4c:67 Disk2: 8G Disk3: 8G Disk4: 8G sles05 data4 16GB Disk1: 20G 10.58.121.185/23 52:54:00:90:b0:b0 Disk2: 8G Disk3: 8G Disk4: 8G sles06 mon1 16GB Disk1: 20G 10.58.121.186/23 52:54:00:46:43:7a sles07 mon2 16GB Disk1: 20G 10.58.121.187/23 52:54:00:00:fe:6b sles08 mon3 16GB Disk1: 20G 10.58.121.188/23 52:54:00:60:a3:92 Add hostname to file /etc/hosts (all nodes) If you do not specify a cluster network during Ceph deployment, it assumes a single public network environment. Make sure that the fully qualified domain name (FQDN) of each node can be resolved to the public network IP address by all other nodes. # vi /etc/hosts 10.58.121.181 admin.sha.me.corp admin salt 10.58.121.182 data1.sha.me.corp data1 10.58.121.183 data2.sha.me.corp data2 10.58.121.184 data3.sha.me.corp data3 10.58.121.185 data4.sha.me.corp data4 10.58.121.186 mon1.sha.me.corp mon1 10.58.121.187 mon2.sha.me.corp mon2 10.58.121.188 mon3.sha.me.corp mon3 Add all nodes as trust ssh access (root account) # cd ~ # ssh-keygen -t rsa # ssh-copy-id -i ~/.ssh/id_rsa.pub root@admin # ssh-copy-id -i ~/.ssh/id_rsa.pub root@data1 # ssh-copy-id -i ~/.ssh/id_rsa.pub root@data2 # ssh-copy-id -i ~/.ssh/id_rsa.pub root@data3 # ssh-copy-id -i ~/.ssh/id_rsa.pub root@data4 # ssh-copy-id -i ~/.ssh/id_rsa.pub root@mon1 # ssh-copy-id -i ~/.ssh/id_rsa.pub root@mon2 # ssh-copy-id -i ~/.ssh/id_rsa.pub root@mon3 # ssh admin.sha.me.corp # ssh data1.sha.me.corp # ssh data2.sha.me.corp # ssh data3.sha.me.corp # ssh data4.sha.me.corp # ssh mon1.sha.me.corp # ssh mon2.sha.me.corp # ssh mon3.sha.me.corp # ssh salt # ssh admin # ssh data1 # ssh data2 # ssh data3 # ssh data4 # ssh mon1 # ssh mon2 # ssh mon3 Disable firewall (all nodes) # sudo /sbin/SuSEfirewall2 off # firewall-cmd --state not running # systemctl stop firewalld.service # systemctl status firewalld.service firewalld.service - firewalld - dynamic firewall daemon Loaded: loaded (/usr/lib/systemd/system/firewalld.service; disabled; vendor preset: disabled) Active: inactive (dead) Docs: man:firewalld(1) Disable IPv6 (all nodes) and Set kernel pid to max value (all nodes) # vi /etc/sysctl.conf net.ipv6.conf.all.disable_ipv6 = 1 net.ipv6.conf.default.disable_ipv6 = 1 net.ipv6.conf.lo.disable_ipv6 = 1 kernel.pid_max = 4194303 # sysctl -p Set DEV_ENV=true in /etc/profile.local in all nodes Install basic software (all nodes) # zypper in -y -t pattern yast2_basis base # zypper in -y net-tools vim man sudo tuned irqbalance # zypper in -y ethtool rsyslog iputils less supportutils-plugin-ses # zypper in -y net-tools-deprecated tree wget Configure NTP service (all nodes), Setting via YaST2 and add server cn.pool.ntp.,org . And /etc/chrony.conf file looks like below. admin:~ # cat /etc/chrony.conf # Use public servers from the pool.ntp.org project. pool cn.pool.ntp.org iburst ! pool pool.ntp.org iburst # Record the rate at which the system clock gains/losses time. driftfile /var/lib/chrony/drift # Allow the system clock to be stepped in the first three updates # if its offset is larger than 1 second. makestep 1.0 3 # Enable kernel synchronization of the real-time clock (RTC). rtcsync # Enable hardware timestamping on all interfaces that support it. #hwtimestamp * # Increase the minimum numbgr of selectable sources required to adjust # the system clock. #minsources 2 # Allow NTP client access from local network. #allow 192.168.0.0/16 # Serve time even if not synchronized to a time source. #local stratum 10 # Specify file containing keys for NTP authentication. #keyfile /etc/chrony.keys # Get TAI-UTC offset and leap seconds from the system tz database. #leapsectz right/UTC # Specify directory for log files. logdir /var/log/chrony # Select which information is logged. #log measurements statistics tracking # Also include any directives found in configuration files in /etc/chrony.d include /etc/chrony.d/*.conf Make /etc/chrony.conf effective. # systemctl enable chronyd.service # systemctl restart chronyd.service # systemctl status chronyd.service # chronyc sources 1.2. Install Packages \u00b6 Install salt-minion on all nodes. And start the service. Hostname is in file `/etc/salt/minion_id` # zypper in -y salt-minion Uncomment below to let all nodes know who is master # vi /etc/salt/minion master: salt # systemctl enable salt-minion.service # systemctl start salt-minion.service # systemctl status salt-minion.service Install Ceph in admin node. Check log in /var/log/salt admin:~ # zypper in -y salt-master admin:~ # systemctl enable salt-master.service admin:~ # systemctl start salt-master.service admin:~ # systemctl status salt-master.service Note: ganesha will be installed on mon1, not admin node. admin:~ # zypper se ganesha admin:~ # zypper in nfs-ganesha admin:~ # systemctl enable nfs-ganesha admin:~ # systemctl start nfs-ganesha admin:~ # systemctl status nfs-ganesha admin:~ # cd /var/log/salt List fingerprints of all unaccepted minion keys on the Salt master. admin:~ # salt-key -F Local Keys: master.pem: c0:e5:***:04:c7 master.pub: 43:73:***:6a:34 Unaccepted Keys: admin.sha.me.corp: fe:51:***:b9:48 mon1.sha.me.corp: 94:13:***:91:63 mon2.sha.me.corp: c0:fd:***:39:3f mon3.sha.me.corp: 38:fc:***:2e:05 data1.sha.me.corp: b6:6c:***:63:4f data2.sha.me.corp: ab:14:***:c8:ac data3.sha.me.corp: 90:3f:***:76:3b data4.sha.me.corp: d8:12:***:f1:20 If the minions' fingerprints match, accept them admin:~ # salt-key --accept-all The following keys are going to be accepted: Unaccepted Keys: admin.sha.me.corp mon1.sha.me.corp mon2.sha.me.corp mon3.sha.me.corp data1.sha.me.corp data2.sha.me.corp data3.sha.me.corp data4.sha.me.corp Proceed? [n/Y] Y Key for minion admin.sha.me.corp accepted. Key for minion mon1.sha.me.corp accepted. Key for minion mon2.sha.me.corp accepted. Key for minion mon3.sha.me.corp accepted. Key for minion data1.sha.me.corp accepted. Key for minion data2.sha.me.corp accepted. Key for minion data3.sha.me.corp accepted. Key for minion data4.sha.me.corp accepted. Verify that the keys have been accepted admin:~ # salt-key -F admin:~ # salt-key --list-all Accepted Keys: admin.sha.me.corp data1.sha.me.corp data2.sha.me.corp data3.sha.me.corp data4.sha.me.corp mon1.sha.me.corp mon2.sha.me.corp mon3.sha.me.corp Denied Keys: Unaccepted Keys: Rejected Keys: Zero out all drivers which will be used as OSDs (optional) data1:~ lsblk data1:~ # for I in {b,c,d}; do dd if=/dev/zero of=dev/sd$i bs=512 count=40 oflag=direct; done data2:~ # for I in {b,c,d}; do dd if=/dev/zero of=dev/sd$i bs=512 count=40 oflag=direct; done data3:~ # for I in {b,c,d}; do dd if=/dev/zero of=dev/sd$i bs=512 count=40 oflag=direct; done Install DeepSea admin:~ # zypper in -y deepsea Edit the /srv/pillar/ceph/deepsea_minions.sls file on the Salt master (admin node) and add or replace the following line: admin:~ # vi /srv/pillar/ceph/deepsea_minions.sls # Choose minions with a deepsea grain deepsea_minions: 'G@deepsea:*' #Match all Salt minions in the cluster # Choose all minions # deepsea_minions: '*' #Match all minions with the 'deepsea' grain # Choose custom Salt targeting # deepsea_minions: 'ses*' # deepsea_minions: 'ceph* or salt' Target the Minions Affirm salt-master (admin node) can communicate with the minions. And deploy the grains from admin node to all minions. admin:~ # salt '*' test.ping mon1.sha.me.corp: True data4.sha.me.corp: True data3.sha.me.corp: True data2.sha.me.corp: True data1.sha.me.corp: True mon3.sha.me.corp: True admin.sha.me.corp: True mon2.sha.me.corp: True Apply the 'deepsea' grain to a group of minions, and target with a DeepSea Grain admin:~ # salt '*' grains.append deepsea default data3.sha.me.corp: The val default was already in the list deepsea mon2.sha.me.corp: The val default was already in the list deepsea data1.sha.me.corp: The val default was already in the list deepsea data4.sha.me.corp: The val default was already in the list deepsea data2.sha.me.corp: The val default was already in the list deepsea mon3.sha.me.corp: The val default was already in the list deepsea admin.sha.me.corp: The val default was already in the list deepsea mon1.sha.me.corp: The val default was already in the list deepsea admin:~ # salt -G 'deepsea:*' test.ping (The following command is an equivalent) admin:~ # salt -C 'G@deepsea:*' test.ping admin.sha.me.corp: True data3.sha.me.corp: True mon1.sha.me.corp: True mon2.sha.me.corp: True data2.sha.me.corp: True data4.sha.me.corp: True mon3.sha.me.corp: True data1.sha.me.corp: True 1.3. Stage 0 \u2014 the preparation \u00b6 Run Stage 0\u2014the preparation During this stage, all required updates are applied and your system may be rebooted. If there are errors, re-run the stage. admin:~ # deepsea stage run ceph.stage.0 (The following commands are equivalents) admin:~ # salt-run state.orch ceph.stage.0 admin:~ # salt-run state.orch ceph.stage.prep Run Stage 1\u2014the discovery Here all hardware in your cluster is being detected and necessary information for the Ceph configuration is being collected. The discovery stage collects data from all minions and creates configuration fragments that are stored in the directory /srv/pillar/ceph/proposals . The data are stored in the YAML format in *.sls or *.yml files admin:~ # deepsea stage run ceph.stage.1 (The following commands are equivalents) admin:~ # salt-run state.orch ceph.stage.1 admin:~ # salt-run state.orch ceph.stage.discovery 1.4. Stage 2 \u2014 the configuration \u00b6 Run Stage 2 \u2014 the configuration \u2014 you need to prepare configuration data in a particular format. The assignment follows this pattern: role-ROLE_NAME/PATH/FILES_TO_INCLUDE (NOTE, the parent directory of PATH is /srv/pillar/ceph/ ) To avoid trouble with performance and the upgrade procedure, do not deploy the Ceph OSD, Metadata Server, or Ceph Monitor role to the Admin Node. Monitors, Metadata Server, and gateways can be co-located on the OSD nodes. If you are using CephFS, S3/Swift, iSCSI, at least two instances of the respective roles (Metadata Server, Object Gateway, iSCSI) are required for redundancy and availability. admin:~ # cp /usr/share/doc/packages/deepsea/examples/policy.cfg-rolebased /srv/pillar/ceph/proposals/policy.cfg admin:~ # vi /srv/pillar/ceph/proposals/policy.cfg ## Cluster Assignment # Add all nodes into Ceph cluster cluster-ceph/cluster/*.sls ## Roles # The Admin node fills the \u201cmaster\u201d and \u201cadmin\u201d roles for DeepSea # The master role is mandatory, always add a similar line to the following role-master/cluster/admin*.sls role-admin/cluster/admin*.sls # Monitoring # Cluster monitoring and data graphs, most commonly they run on Admin node # NFS Ganesha is configured via the file /etc/ganesha/ganesha.conf # As additional configuration is required to install NFS Ganesha, you can install NFS Ganesha later. # The following requirements need to be met before DeepSea stages 2 and 4 can be executed to install NFS Ganesha: # a)At least one node needs to be assigned the role-ganesha. # b)You can define only one role-ganesha per minion. # c)NFS Ganesha needs either an Object Gateway or CephFS to work, otherwise the validation will fail in Stage 3. # d)The kernel based NFS needs to be disabled on minions with the role-ganesha role. role-prometheus/cluster/admin*.sls role-grafana/cluster/mon1*.sls # MON # The minion will provide the monitor service to the Ceph cluster role-mon/cluster/mon*.sls # MGR # The Ceph manager daemon which collects all the state information from the whole cluster # Deploy it on all minions where you plan to deploy the Ceph monitor role role-mgr/cluster/mon1*.sls # MDS # The minion will provide the metadata service to support CephFS role-mds/cluster/mon*.sls # IGW # The minion will act as an iSCSI Gateway role-igw/cluster/mon2*.sls # RGW # The minion will act as an Object Gateway role-rgw/cluster/mon3*.sls # Storage # Use this role to specify storage nodes # It points to data1~4 nodes with a wildcard. role-storage/cluster/data*.sls # COMMON # It includes configuration files generated during the discovery (Stage 1) # Accept the default values for common configuration parameters such as fsid and public_network config/stack/default/global.yml config/stack/default/ceph/cluster.yml admin:~ # deepsea stage run ceph.stage.2 (The following commands are equivalents) admin:~ # salt-run state.orch ceph.stage.2 admin:~ # salt-run state.orch ceph.stage.configure After the command succeeds, run below command to view the pillar data for the specified minions admin:~ # salt 'mon*' pillar.items admin:~ # salt '*' saltutil.pillar_refresh Check time server (admin node) (the directory /srv/pillar/ceph/stack was initialized after deepsea installed, but global.yml file was not created yet until stage 2) By default, DeepSea uses the Admin Node as the time server for other cluster nodes. admin:~ # cat /srv/pillar/ceph/stack/default/global.yml (this file will be generated after stage 2) monitoring: prometheus: metric_relabel_config: ceph: [] grafana: [] node_exporter: [] prometheus: [] relabel_config: ceph: [] grafana: [] node_exporter: [] prometheus: [] rule_files: [] scrape_interval: ceph: 10s grafana: 10s node_exporter: 10s prometheus: 10s target_partition: ceph: 1/1 grafana: 1/1 node_exporter: 1/1 prometheus: 1/1 time_server: admin.sha.me.corp Verify network (the directory /srv/pillar/ceph/stack was initialized after deepsea installed, but cluster.yml file was not created until stage 2 ) admin:~ # cat /srv/pillar/ceph/stack/ceph/cluster.yml --nothing admin:~ # cat /srv/pillar/ceph/stack/default/ceph/cluster.yml available_roles: - storage - admin - mon - mds - mgr - igw - grafana - prometheus - storage - rgw - ganesha - client-cephfs - client-radosgw - client-iscsi - client-nfs - benchmark-rbd - benchmark-blockdev - benchmark-fs - master cluster_network: 10.58.120.0/23 fsid: 343ee7d3-232f-4c71-8216-1edbc55ac6e0 public_network: 10.58.120.0/23 Note: customized file will overwrite default one. Default file: /srv/pillar/ceph/stack/default/ceph/cluster.yml Customized file: /srv/pillar/ceph/stack/ceph/cluster.yml Check DriveGroup DriveGroups specify the layouts of OSDs in the Ceph cluster. They are defined in a single file /srv/salt/ceph/configuration/files/drive_groups.yml admin:~ # cat /srv/salt/ceph/configuration/files/drive_groups.yml default_drive_group_name: target: 'data*' <--original: 'I@role:storage' data_devices: all: true admin:~ # salt 'data*' pillar.items | grep -B5 stroage 1.5. Stage 3 \u2014 the deployment \u00b6 Run Stage 3 \u2014 the deployment \u2014 creates a basic Ceph cluster with mandatory Ceph services. This Deployment stage has more than 60 automated steps. Be patient and make sure the stage completes successfully before proceeding. Set dev environment and disable subvolume: admin:~ # vi /srv/pillar/ceph/stack/global.yml admin:~ # vi /srv/pillar/ceph/stack/default/global.yml monitoring: prometheus: metric_relabel_config: ceph: [] grafana: [] node_exporter: [] prometheus: [] relabel_config: ceph: [] grafana: [] node_exporter: [] prometheus: [] rule_files: [] scrape_interval: ceph: 10s grafana: 10s node_exporter: 10s prometheus: 10s target_partition: ceph: 1/1 grafana: 1/1 node_exporter: 1/1 prometheus: 1/1 time_server: admin.sha.me.corp DEV_ENV: True subvolume_init: disabled admin:~ # salt '*' saltutil.pillar_refresh Note: customized file will overwrite default one. Default file: /srv/pillar/ceph/stack/default/global.yml Customized file: /srv/pillar/ceph/stack/global.yml admin:~ # deepsea stage run ceph.stage.3 (The following commands are equivalents) admin:~ # salt-run state.orch ceph.stage.3 admin:~ # salt-run state.orch ceph.stage.deploy After the command succeeds, run the following to check the status: admin:~ # ceph -s Below comands return you a structure of matching disks based on your DriveGroups. (will show available information after stage 3) admin:~ # salt-run disks.Report admin:~ # salt-run disks.list admin:~ # salt-run disks.details 1.6. Stage 4 \u2014 the services \u00b6 Run Stage 4 \u2014 the services \u2014 additional features of Ceph like iSCSI, Object Gateway and CephFS can be installed in this stage. Each is optional. admin:~ # deepsea stage run ceph.stage.4 (The following commands are equivalents) admin:~ # salt-run state.orch ceph.stage.4 admin:~ # salt-run state.orch ceph.stage.services admin:~ # ceph osd lspools 1 iscsi-images 2 cephfs_data 3 cephfs_metadata 4 .rgw.root 5 default.rgw.control 6 default.rgw.meta 7 default.rgw.log Before logon to dashboard via url, need get credentials first admin:~ # salt-call grains.get dashboard_creds local: ---------- admin: --> the password was changed to mypassword to log on to dashboard admin:~ # ceph mgr services { \"dashboard\": \"https://mon1.sha.me.corp:8443/\", \"prometheus\": \"http://mon1.sha.me.corp:9283/\" } https://10.58.121.186:8443 http://10.58.121.186:9283 admin:~ # watch ceph -s Every 2.0s: ceph -s admin: Mon Oct 5 14:41:51 2020 cluster: id: health: HEALTH_OK services:s: ceph -s mon: 3 daemons, quorum mon1,mon2,mon3 (age 87m) mgr: mon1(active, since 82m) mds: cephfs:1 {0=mon3=up:active} 2 up:standby osd: 12 osds: 12 up (since 85m), 12 in (since 85m) rgw: 1 daemon active (mon3) task status: scrub status: mds.mon3: idle data: pools: 7 pools, 576 pgs objects: 213 objects, 4.2 KiB usage: 12 GiB used, 84 GiB / 96 GiB avail pgs: 576 active+clean io: client: 852 B/s rd, 0 op/s rd, 0 op/s wr 1.7. Stage 5 \u2014 the removal stage \u00b6 Run Stage 5 \u2014 the removal stage. This stage is not mandatory and during the initial setup it is usually not needed. In this stage the roles of minions and also the cluster configuration are removed. You need to run this stage when you need to remove a storage node from your cluster. admin:~ # deepsea stage run ceph.stage. 1.8. Installation Guide \u00b6 Deployment Guide (EN) Deployment Guide (ZH) 1.9. Issues during installation \u00b6 [ERROR]: The Salt Master has cached the public key for this node SOLUTION : Restart minions service [ERROR]: This server_id is computed nor by Adler32 neither by CRC32 [QUESTION]: How to change new salt key Stop salt-minion service # systemctl stop salt-minion Delete salt-minion pulic key # rm /etc/salt/pki/minion/minion.pub # rm /etc/salt/pki/minion/minion.pem Change new minion_id admin:~ # echo admin.sha.me.corp > /etc/salt/minion_id data1:~ # echo data1.sha.me.corp > /etc/salt/minion_id data2:~ # echo data2.sha.me.corp > /etc/salt/minion_id data3:~ # echo data3.sha.me.corp > /etc/salt/minion_id data4:~ # echo data4.sha.me.corp > /etc/salt/minion_id mon1:~ # echo mon1.sha.me.corp > /etc/salt/minion_id mon2:~ # echo mon2.sha.me.corp > /etc/salt/minion_id mon3:~ # echo mon3.sha.me.corp > /etc/salt/minion_id Delete old ID on admin node # salt-key -D Restart salt-minion service # systemctl restart salt-minion Accept all new key on admin node admin:~ # salt-key -L admin:~ # salt-key -A or admin:~ # salt-key -a admin.sha.me.corp data1:~ # salt-key -a data1.sha.me.corp data2:~ # salt-key -a data2.sha.me.corp data3:~ # salt-key -a data3.sha.me.corp data4:~ # salt-key -a data4.sha.me.corp mon1:~ # salt-key -a mon1.sha.me.corp mon2:~ # salt-key -a mon2.sha.me.corp mon3:~ # salt-key -a mon3.sha.me.corp [ERROR] ['/var/lib/ceph subvolume missing on mon3.sha.me.corp', '/var/lib/ceph subvolume missing on mon1.sha.me.corp', '/var/lib/ceph subvolume missing on mon2.sha.me.corp', 'See /srv/salt/ceph/subvolume/README.md'] SOLUTION Edit /srv/pillar/ceph/stack/global.yml and add the following line: subvolume_init: disabled Then refresh the Salt pillar and re-run DeepSea stage.3: admin:~ # salt '*' saltutil.refresh_pillar admin:~ # salt-run state.orch ceph.stage.3 After DeepSea successfully finished stage.3, the Ceph Dashboard will be running. Refer to Book \u201cAdministration Guide\u201d, Chapter 20 \u201cCeph Dashboard\u201d for a detailed overview of Ceph Dashboard features. To list nodes running dashboard, run: admin:~ # ceph mgr services | grep dashboard To list admin credentials, run: admin:~ # salt-call grains.get dashboard_creds [ERROR] module function cephprocesses.wait executed on nodes mon1~3 and data1~4 in Stage 0 SOLUTION Check below on all nodes # salt-call cephprocesses.check ERROR: process ceph-mds for role mds is not running ERROR: process radosgw for role rgw is not running admin:~ # ceph -s Clock skew detected on mon ceph (mon.mon2, mon.mon3) Set time server to public server (China) # chronyc sources 1.10. Shutting Down the Whole Ceph Cluster \u00b6 Shut down or disconnect any clients accessing the cluster. To prevent CRUSH from automatically rebalancing the cluster, set the cluster to noout: # ceph osd set noout Other flags you can set per osd: nodown noup noin noout Disable safety measures and run the ceph.shutdown runner: admin:~ # salt-run disengage.safety safety is now disabled for cluster ceph admin:~ # salt-run state.orch ceph.shutdown admin.sha.me.corp_master: Name: set noout - Function: salt.state - Result: Changed Started: - 14:32:14.398022 Duration: 2266.75 ms Name: Shutting down radosgw for rgw - Function: salt.state - Result: Changed Started: - 14:32:16.665452 Duration: 1461.23 ms Name: Shutting down cephfs - Function: salt.state - Result: Changed Started: - 14:32:18.127353 Duration: 30326.193 ms Name: Shutting down iscsi - Function: salt.state - Result: Clean Started: - 14:32:48.454187 Duration: 30142.468 ms Name: Shutting down storage - Function: salt.state - Result: Changed Started: - 14:33:18.597321 Duration: 10841.45 ms Name: Shutting down mgr - Function: salt.state - Result: Changed Started: - 14:33:29.439442 Duration: 29209.141 ms Name: Shutting down mon - Function: salt.state - Result: Changed Started: - 14:33:58.649221 Duration: 30519.97 ms Summary for admin.sha.me.corp_master ------------ Succeeded: 7 (changed=6) Failed: 0 ------------ Total states run: 7 Total run time: 134.767 s Power off all cluster nodes: admin:~ # salt -C 'G@deepsea:*' cmd.run \"shutdown -h\" Broadcast message from root@admin (Sat 2021-03-06 14:40:37 CST): The system is going down for poweroff at Sat 2021-03-06 14:41:37 CST! admin.sha.me.corp: Shutdown scheduled for Sat 2021-03-06 14:41:37 CST, use 'shutdown -c' to cancel. mon2.sha.me.corp: Shutdown scheduled for Sat 2021-03-06 14:41:37 CST, use 'shutdown -c' to cancel. data2.sha.me.corp: Shutdown scheduled for Sat 2021-03-06 14:41:37 CST, use 'shutdown -c' to cancel. mon3.sha.me.corp: Shutdown scheduled for Sat 2021-03-06 14:41:37 CST, use 'shutdown -c' to cancel. data3.sha.me.corp: Shutdown scheduled for Sat 2021-03-06 14:41:37 CST, use 'shutdown -c' to cancel. data4.sha.me.corp: Shutdown scheduled for Sat 2021-03-06 14:41:37 CST, use 'shutdown -c' to cancel. mon1.sha.me.corp: Shutdown scheduled for Sat 2021-03-06 14:41:37 CST, use 'shutdown -c' to cancel. data1.sha.me.corp: Shutdown scheduled for Sat 2021-03-06 14:41:37 CST, use 'shutdown -c' to cancel. 1.11. Starting, Stopping, and Restarting Services Using Targets \u00b6 # ls /usr/lib/systemd/system/ceph*.target ceph.target ceph-osd.target ceph-mon.target ceph-mgr.target ceph-mds.target ceph-radosgw.target ceph-rbd-mirror.target To start/stop/restart all Ceph services on the node, run: # systemctl start ceph.target # systemctl stop ceph.target # systemctl restart ceph.target To start/stop/restart all OSDs on the node, run: # systemctl start ceph-osd.target # systemctl stop ceph-osd.target # systemctl restart ceph-osd.target Starting, Stopping, and Restarting Individual Services # systemctl list-unit-files --all --type=service ceph* ceph-osd@.service ceph-mon@.service ceph-mds@.service ceph-mgr@.service ceph-radosgw@.service ceph-rbd-mirror@.service Example : # systemctl status ceph-mon@HOSTNAME.service (e.g., ceph-mon@mon1.service) # systemctl start ceph-osd@1.service # systemctl stop ceph-osd@1.service # systemctl restart ceph-osd@1.service # systemctl status ceph-osd@1.service 1.12. Restarting All Services \u00b6 # salt-run state.orch ceph.restart 1.13. Restarting Specific Services \u00b6 Example: salt-run state.orch ceph.restart.service_name # salt-run state.orch ceph.restart.mon # salt-run state.orch ceph.restart.mgr # salt-run state.orch ceph.restart.osd # salt-run state.orch ceph.restart.mds # salt-run state.orch ceph.restart.rgw # salt-run state.orch ceph.restart.igw # salt-run state.orch ceph.restart.ganesha Default log file path of salt-run: /var/log/salt/master 2. Basic Operation \u00b6 2.1. Pools and Data Placement \u00b6 2.1.1. Enable the PG Autoscaler and Balancer Modules \u00b6 Task 1: View the state of all the Manager Modules \u00b6 List all the existing Manager Modules admin:~ # ceph mgr module ls | less Task 2: List the Existing Pools \u00b6 List the pools that already exist in the cluster admin:~ # ceph osd lspools 1 iscsi-images 2 cephfs_data 3 cephfs_metadata 4 .rgw.root 5 default.rgw.control 6 default.rgw.meta 7 default.rgw.log List the pools again, but this time using the rados command: admin:~ # rados lspools iscsi-images cephfs_data cephfs_metadata .rgw.root default.rgw.control default.rgw.meta default.rgw.log View the output of placement group autoscale-status command for the pools admin:~ # ceph osd pool autoscale-status Error ENOTSUP: Module 'pg_autoscaler' is not enabled (required by command 'osd pool autoscale-status'): use `ceph mgr module enable pg_autoscaler` to enable it Task 3: Enable the pg_autoscaler module \u00b6 Enable the pg_autoscaler module admin:~ # ceph mgr module enable pg_autoscaler admin:~ # ceph osd pool autoscale-status POOL SIZE TARGET SIZE RATE RAW CAPACITY RATIO TARGET RATIO EFFECTIVE RATIO BIAS PG_NUM NEW PG_NUM AUTOSCALE iscsi-images 389 3.0 98256M 0.0000 1.0 128 32 warn cephfs_data 0 3.0 98256M 0.0000 1.0 256 32 warn cephfs_metadata 7285 3.0 98256M 0.0000 4.0 64 16 warn .rgw.root 1245 3.0 98256M 0.0000 1.0 32 warn default.rgw.control 0 3.0 98256M 0.0000 1.0 32 warn default.rgw.meta 381 3.0 98256M 0.0000 1.0 32 warn default.rgw.log 18078 3.0 98256M 0.0000 1.0 32 warn Note that for the iscsi-images pool the PG_NUM value is 128. And note that the NEW PG_NUM value is 32. The PGs won\u2019t be adjusted automatically because the default setting for the autoscaler is \u201cwarn\u201d. Note the last column (mode) that shows status \u201cwarn\u201d for all the pools. Check current status. \u201chave too many placement groups\u201d. That\u2019s exactly what we want the pg_autoscaler to tell us. admin:~ # ceph health HEALTH_WARN 3 pools have too many placement groups Turn off the pg_autoscaler feature for CephFS pools admin:~ # ceph osd pool set cephfs_data pg_autoscale_mode off set pool 2 pg_autoscale_mode to off admin:~ # ceph osd pool set cephfs_metadata pg_autoscale_mode off set pool 3 pg_autoscale_mode to off admin:~ # ceph health HEALTH_WARN 1 pools have too many placement groups Set the pg_autoscaler mode to \u201con\u201d for the iscs-images pool: admin:~ # ceph osd pool set iscsi-images pg_autoscale_mode on set pool 1 pg_autoscale_mode to on admin:~ # ceph osd pool autoscale-status POOL SIZE TARGET SIZE RATE RAW CAPACITY RATIO TARGET RATIO EFFECTIVE RATIO BIAS PG_NUM NEW PG_NUM AUTOSCALE iscsi-images 389 3.0 98256M 0.0000 1.0 128 32 on cephfs_data 0 3.0 98256M 0.0000 1.0 256 32 off cephfs_metadata 7412 3.0 98256M 0.0000 4.0 64 16 off .rgw.root 1245 3.0 98256M 0.0000 1.0 32 warn default.rgw.control 0 3.0 98256M 0.0000 1.0 32 warn default.rgw.meta 381 3.0 98256M 0.0000 1.0 32 warn default.rgw.log 18078 3.0 98256M 0.0000 1.0 32 warn Turn on the pg_autoscaler feature for CephFS pools admin:~ # ceph osd pool set cephfs_data pg_autoscale_mode on set pool 2 pg_autoscale_mode to on admin:~ # ceph osd pool set cephfs_metadata pg_autoscale_mode on set pool 3 pg_autoscale_mode to on PG numbgrs must always be a power of 2 admin:~ # ceph osd pool autoscale-status POOL SIZE TARGET SIZE RATE RAW CAPACITY RATIO TARGET RATIO EFFECTIVE RATIO BIAS PG_NUM NEW PG_NUM AUTOSCALE iscsi-images 389 3.0 98256M 0.0000 1.0 32 on cephfs_data 0 3.0 98256M 0.0000 1.0 32 off cephfs_metadata 7412 3.0 98256M 0.0000 4.0 16 off .rgw.root 1245 3.0 98256M 0.0000 1.0 32 warn default.rgw.control 0 3.0 98256M 0.0000 1.0 32 warn default.rgw.meta 381 3.0 98256M 0.0000 1.0 32 warn default.rgw.log 35900 3.0 98256M 0.0000 1.0 32 warn Show the cluster health admin:~ # ceph -s cluster: id: health: HEALTH_OK services: mon: 3 daemons, quorum mon1,mon2,mon3 (age 4w) mgr: mon1(active, since 46h) mds: cephfs:1 {0=mon3=up:active} 2 up:standby osd: 12 osds: 12 up (since 8w), 12 in (since 8w) rgw: 1 daemon active (mon3) task status: scrub status: mds.mon3: idle data: pools: 7 pools, 433 pgs objects: 246 objects, 4.7 KiB usage: 13 GiB used, 83 GiB / 96 GiB avail pgs: 0.462% pgs not active 431 active+clean 2 peering io: client: 45 KiB/s rd, 0 B/s wr, 44 op/s rd, 28 op/s wr Task 4: Turn on the Placement Group balancer feature \u00b6 1). Show the \u201cstatus\u201d of the balancer: admin:~ # ceph balancer status { \"plans\": [], \"active\": false, \"last_optimize_started\": \"\", \"last_optimize_duration\": \"\", \"optimize_result\": \"\", \"mode\": \"none\" } admin:~ # ceph balancer on admin:~ # ceph balancer status { \"plans\": [], \"active\": true, \"last_optimize_started\": \"Mon Jan 4 20:22:57 2021\", \"last_optimize_duration\": \"0:00:00.001379\", \"optimize_result\": \"Please do \\\"ceph balancer mode\\\" to choose a valid mode first\", \"mode\": \"none\" } 2). Set the mode for the balancer to \u201cupmap\u201d: admin:~ # ceph balancer mode upmap Error EPERM: min_compat_client \"jewel\" < \"luminous\", which is required for pg-upmap. Try \"ceph osd set-require-min-compat-client luminous\" before enabling this mode admin:~ # ceph osd set-require-min-compat-client luminous --yes-i-really-mean-it set require_min_compat_client to luminous admin:~ # ceph balancer mode upmap admin:~ # ceph balancer status { \"plans\": [], \"active\": true, \"last_optimize_started\": \"Mon Jan 4 20:23:57 2021\", \"last_optimize_duration\": \"0:00:00.001807\", \"optimize_result\": \"Please do \\\"ceph balancer mode\\\" to choose a valid mode first\", \"mode\": \"upmap\" } 3). Create a balancer optimization plan called basic-plan. Ceph won\u2019t let you do this yet. Because you just recently enabled the pg_autoscaler, Ceph is moving objects around, and the PGs are quite busy with re-peering. admin:~ # ceph balancer optimize basic-plan Error EINVAL: Balancer enabled, disable to optimize manually 4). Show the details of the plan: This shows what \u201cexecute\u201d-ing the plan will do, itemizing which PGs will be affected. admin:~ # ceph balancer show basic-plan Error ENOENT: plan basic-plan not found <--- failed here 5). Show the effectiveness of the plan by comparing the current score for the pre-planned balancing and the score for the planned balancing: admin:~ # ceph balancer eval current cluster score 0.118731 (lower is better) admin:~ # ceph balancer eval basic-plan Error EINVAL: option \"basic-plan\" not a plan or a pool 6). Show the status of the balancer, now with all of these settings having been set, but before putting them into effect: The pg_autoscaler has already optimized the balance of PGs sufficiently. That\u2019s because this cluster is very small and has no significant content stored in it yet. If that\u2019s the case, you would see a message like \u201cError EALREADY: Unable to find further optimization, or pool(s)' pg_num is decreasing, or distribution is already perfect.\u201d If you receive this message, then you will not be able to complete this task. At some later time in the course you may choose to revisit this task to complete it. admin:~ # ceph balancer status { \"plans\": [], \"active\": true, \"last_optimize_started\": \"Mon Jan 4 20:32:59 2021\", \"last_optimize_duration\": \"0:00:00.004170\", \"optimize_result\": \"Unable to find further optimization, or pool(s) pg_num is decreasing, or distribution is already perfect\", \"mode\": \"upmap\" } 7). Set the basic-plan into effect: admin:~ # ceph balancer execute basic-plan Error EINVAL: Balancer enabled, disable to execute a plan 8). Now re-show the current score for the balanced cluster: admin:~ # ceph balancer eval current cluster score 0.118731 (lower is better) 2.1.2. Manipulate Erasure Code Profiles \u00b6 Task 1: Display a list of the current Erasure Code profiles \u00b6 admin:~ # ceph osd erasure-code-profile no valid command found; 4 closest matches: osd erasure-code-profile set { [...]} {--force} osd erasure-code-profile get osd erasure-code-profile rm osd erasure-code-profile ls Error EINVAL: invalid command admin:~ # ceph osd erasure-code-profile ls default Task 2: Examine the details of the default EC profile \u00b6 admin:~ # ceph osd erasure-code-profile get default k=2 m=1 plugin=jerasure technique=reed_sol_van Task 3: Create and remove a new EC profile \u00b6 1. Create a new EC profile from the command line. This is going to be a \u201cbad\u201d profile that will be removed in a moment: admin:~ # ceph osd erasure-code-profile set bad_profile k=2 m=4 plugin=jerasure admin:~ # ceph osd erasure-code-profile ls bad_profile default admin:~ # ceph osd erasure-code-profile get bad_profile crush-device-class= crush-failure-domain=host crush-root=default jerasure-per-chunk-alignment=false k=2 m=4 plugin=jerasure technique=reed_sol_van w=8 admin:~ # ceph osd erasure-code-profile rm bad_profile admin:~ # ceph osd erasure-code-profile ls default Task 4: Create a better EC profile \u00b6 admin:~ # ceph osd erasure-code-profile set usable_profile k=2 m=1 plugin=jerasure technique=reed_sol_van stripe_unit=4K crush-failure-domain=host admin:~ # ceph osd erasure-code-profile get usable_profile crush-device-class= crush-failure-domain=host crush-root=default jerasure-per-chunk-alignment=false k=2 m=1 plugin=jerasure stripe_unit=4K technique=reed_sol_van w=8 2.1.3. Manipulate CRUSH Map Rulesets \u00b6 Task 1: Display a list of the current CRUSH Map rules \u00b6 admin:~ # ceph osd crush rule ls replicated_rule admin:~ # ceph osd crush osd crush rule ls osd crush rule ls-by-class osd crush rule dump {} osd crush dump osd crush set {} osd crush add-bucket { [...]} osd crush rename-bucket osd crush set [...] osd crush add [...] osd crush set-all-straw-buckets-to-straw2 admin:~ # ceph osd crush rule osd crush rule ls osd crush rule ls-by-class osd crush rule dump {} osd crush rule create-simple {firstn|indep} osd crush rule create-replicated {} osd crush rule create-erasure {} osd crush rule rm osd crush rule rename List the existing CRUSH Map rulesets that have been defined according to a particular device class: admin:~ # ceph osd crush rule ls-by-class hdd admin:~ # ceph osd crush rule ls-by-class ssd Error ENOENT: failed to get rules by class 'ssd' admin:~ # ceph osd crush rule ls-by-class nvme Error ENOENT: failed to get rules by class 'nvme' Task 2: Examine the details of the default CRUSH Map rule \u00b6 Show the details of the default CRUSH Map rule with the dump sub-command: The \u201crule_id\u201d and \u201cruleset\u201d values just numbgrs to keep track of rules similar to a DB key id. \u201cmin_size\u201d and \u201cmax_size\u201d are related to how CRUSH behaves when a certain numbgr of replicas are created. The \u201csteps\u201d section is the most functional portion of the rule, providing an ordered set of rules for how CRUSH should behave. Note that there are three \u201cop\u201d parts, one each for \u201ctake\u201d, \u201cchooseleaf_firstn\u201d, and \u201cemit\u201d. \u201ctake\u201d in a replicated rule is always the first step, and \u201cemit\u201d is always the last step. The \u201citem_type\u201d in the \u201ctake\u201d step is the crush_root value, and the \u201chost\u201d in the \u201cchooseleaf_firstn\u201d step is the failure_domain. admin:~ # ceph osd crush rule dump replicated_rule { \"rule_id\": 0, \"rule_name\": \"replicated_rule\", \"ruleset\": 0, \"type\": 1, \"min_size\": 1, \"max_size\": 10, \"steps\": [ { \"op\": \"take\", \"item\": -1, \"item_name\": \"default\" }, { \"op\": \"chooseleaf_firstn\", \"num\": 0, \"type\": \"host\" }, { \"op\": \"emit\" } ] } Task 3: Create and remove a new CRUSH Map rule \u00b6 1). Create a new CRUSH ruleset from the command line.We made two mistakes here: First, we named it \u201cbud\u201d instead of \u201cbad\u201d. admin:~ # ceph osd crush rule create-replicated bud_ruleset default host admin:~ # ceph osd crush rule ls replicated_rule bud_ruleset 2). Rename the ruleset: admin:~ # ceph osd crush rule rename bud_ruleset bad_ruleset admin:~ # ceph osd crush rule ls replicated_rule bad_ruleset 3). The second mistake was that we specified the failure-domain at the host-bucket level. This is technically not a bad thing to do, in fact it would be a common use case. But for this demo we want to set the failure domain at the rack-bucket level. We can\u2019t change a defined CRUSH Map ruleset, so delete the bad one: admin:~ # ceph osd crush rule rm bad_ruleset admin:~ # ceph osd crush rule ls replicated_rule Task 4: Create a better CRUSH Map rule \u00b6 Create a more appropriate CRUSH Map rule from the CLI, that will survive the failure of a rack: admin:~ # ceph osd crush rule create-replicated better_ruleset default rack admin:~ # ceph osd crush rule dump better_ruleset { \"rule_id\": 1, \"rule_name\": \"better_ruleset\", \"ruleset\": 1, \"type\": 1, \"min_size\": 1, \"max_size\": 10, \"steps\": [ { \"op\": \"take\", \"item\": -1, \"item_name\": \"default\" }, { \"op\": \"chooseleaf_firstn\", \"num\": 0, \"type\": \"rack\" }, { \"op\": \"emit\" } ] } Task 5: Create CRUSH Map rules for different classes of devices \u00b6 1). Create two different CRUSH Map rules from the CLI, that will accommodate a slow set of devices (HDDs) and a fast set of devices (SDDs): The error of 2 nd is because the cluster does not have any SSD devices. admin:~ # ceph osd crush rule create-replicated slow_devices default host hdd admin:~ # ceph osd crush rule create-replicated fast_devices default host sdd Error EINVAL: device class sdd does not exist 2). Display the details of the new \u201cslow\u201d rule: admin:~ # ceph osd crush rule dump slow_devices { \"rule_id\": 2, \"rule_name\": \"slow_devices\", \"ruleset\": 2, \"type\": 1, \"min_size\": 1, \"max_size\": 10, \"steps\": [ { \"op\": \"take\", \"item\": -2, \"item_name\": \"default~hdd\" }, { \"op\": \"chooseleaf_firstn\", \"num\": 0, \"type\": \"host\" }, { \"op\": \"emit\" } ] } Task 6: Change the ruleset used by a pool \u00b6 1). Show which CRUSH Map Ruleset is being used by the cephfs_data pool: The rule should be listed as replicated_rule. admin:~ # ceph osd pool get cephfs_data crush_rule crush_rule: replicated_rule 2). Change the cephfs_data pool to use the new CRUSH Map ruleset that you created in the previous task. admin:~ # ceph osd pool set cephfs_data crush_rule better_ruleset set pool 2 crush_rule to better_ruleset 3). Verify that the rule has been changed by re-running the earlier command: admin:~ # ceph osd pool get cephfs_data crush_rule crush_rule: better_ruleset 4). In this demo cluster, making the cephfs_data pool use the \u201cbetter_ruleset\u201d will result in problems. (There\u2019s no rack for the CRUSH Map, and not enough nodes to accommodate the requirement for a large numbgr of PGs.) So change the setting back to the replicated_rule. admin:~ # ceph osd pool set cephfs_data crush_rule replicated_rule set pool 2 crush_rule to replicated_rule admin:~ # ceph osd pool get cephfs_data crush_rule crush_rule: replicated_rule Task 7: Create a CRUSH Map rule enhanced with an EC profile 1). Combine the benefits of Erasure Coding with a CRUSH Map rule: This will only work if you have already created an appropriate EC profile called usable_profile. In this demo you would have done in an earlier exercise. And in this demo you need to tie this ec_rule to the usable_profile, not the better_profile.Or else any pool that you create using the ec_rule will fail due to insufficient resources. admin:~ # ceph osd crush rule create-erasure ec_rule usable_profile Link the CRUSH map rule (ec_rule) to EC profile (usable_profile) created rule ec_rule at 3 P.S., The useable_profile was created by : admin:~ # ceph osd erasure-code-profile set usable_profile k=2 m=1 plugin=jerasure technique=reed_sol_van stripe_unit=4K crush-failure-domain=host 2). Display the details of the EC-enhanced CRUSH Map rule: See the added, extra \u201cop\u201d steps. You might also notice the different values for \u201ctype,\u201d \u201cmin_size,\u201d and \u201cmax_size\u201d than what you saw in the standard replicated rules. admin:~ # ceph osd crush rule dump ec_rule { \"rule_id\": 3, \"rule_name\": \"ec_rule\", \"ruleset\": 3, \"type\": 3, \"min_size\": 3, \"max_size\": 3, \"steps\": [ { \"op\": \"set_chooseleaf_tries\", \"num\": 5 }, { \"op\": \"set_choose_tries\", \"num\": 100 }, { \"op\": \"take\", \"item\": -1, \"item_name\": \"default\" }, { \"op\": \"chooseleaf_indep\", \"num\": 0, \"type\": \"host\" }, { \"op\": \"emit\" } ] } admin:~ # ceph osd crush rule ls replicated_rule better_ruleset slow_devices ec_rule admin:~ # ceph osd crush rule create-replicated better_ruleset default rack admin:~ # ceph osd crush rule create-replicated slow_devices default host hdd admin:~ # ceph osd crush rule create-erasure ec_rule usable_profile admin:~ # ceph osd crush rule dump replicated_rule { \"rule_id\": 0, \"rule_name\": \"replicated_rule\", \"ruleset\": 0, \"type\": 1, \"min_size\": 1, \"max_size\": 10, \"steps\": [ { \"op\": \"take\", \"item\": -1, \"item_name\": \"default\" }, { \"op\": \"chooseleaf_firstn\", \"num\": 0, \"type\": \"host\" }, { \"op\": \"emit\" } ] } admin:~ # ceph osd crush rule dump better_ruleset { \"rule_id\": 1, \"rule_name\": \"better_ruleset\", \"ruleset\": 1, \"type\": 1, \"min_size\": 1, \"max_size\": 10, \"steps\": [ { \"op\": \"take\", \"item\": -1, \"item_name\": \"default\" }, { \"op\": \"chooseleaf_firstn\", \"num\": 0, \"type\": \"rack\" }, { \"op\": \"emit\" } ] } admin:~ # ceph osd crush rule dump slow_devices { \"rule_id\": 2, \"rule_name\": \"slow_devices\", \"ruleset\": 2, \"type\": 1, \"min_size\": 1, \"max_size\": 10, \"steps\": [ { \"op\": \"take\", \"item\": -2, \"item_name\": \"default~hdd\" }, { \"op\": \"chooseleaf_firstn\", \"num\": 0, \"type\": \"host\" }, { \"op\": \"emit\" } ] } admin:~ # ceph osd pool osd pool stats {} osd pool scrub [...] osd pool deep-scrub [...] osd pool repair [...] osd pool force-recovery [...] osd pool force-backfill [...] osd pool cancel-force-recovery [...] osd pool cancel-force-backfill [...] osd pool autoscale-status osd pool mksnap admin:~ # ceph osd pool get size min_size pg_num pgp_num crush_rule Hashpspool Nodelete Nopgchange Nosizechange write_fadvise_dontneed Noscrub nodeep-scrub hit_set_type hit_set_period hit_set_count hit_set_fpp use_gmt_hitset target_max_objects target_max_bytes cache_target_dirty_ratio cache_target_dirty_high_ratio cache_target_full_ratio cache_min_flush_age cache_min_evict_age erasure_code_profile min_read_recency_for_promote All min_write_recency_for_promote fast_read hit_set_grade_decay_rate hit_set_search_last_n scrub_min_interval scrub_max_interval deep_scrub_interval recovery_priority recovery_op_priority scrub_priority compression_mode compression_algorithm compression_required_ratio compression_max_blob_size compression_min_blob_size csum_type csum_min_block csum_max_block allow_ec_overwrites fingerprint_algorithm pg_autoscale_mode pg_autoscale_bias pg_num_min target_size_bytes target_size_ratio 2.1.4. Investigate BlueStore \u00b6 Task 1: Explore the drive_groups.yml configuration \u00b6 After deployment, the drive_groups.yml file is where the storage administrator defines the configuration of the cluster\u2019s storage devices. Note the \u201cdata_devices\u201d parameter. In this demo, \u201call\u201d storage devices are data devices for BlueStore. Note that there are no definitions for \u201cwal_devices\u201d or \u201cdb_devices.\u201d That\u2019s because in this demo environment we don\u2019t have any other \u201cfast\u201d devices that would be appropriate for these roles. Since BlueStore is the default, there is no definition of a \u201cformat\u201d for the devices. Otherwise, a \u201cFormat: bluestore\u201d key-value pair might exist to ensure that BlueStore is used. admin:~ # cd /srv/salt/ceph/configuration/files admin:/srv/salt/ceph/configuration/files # cat drive_groups.yml # default: <- just a name - can be anything # target: 'data*' <- must be resolvable by salt's targeting processor # data_devices: # size: 20G # db_devices: # size: 10G # rotational: 1 # allflash: # target: 'fast_nodes*' # data_devices: # size: 100G # db_devices: # size: 50G # rotational: 0 # This is the default configuration and # will create an OSD on all available drives default: target: 'data*' data_devices: all: true Task 2: Examine a storage host\u2019s storage devices \u00b6 admin:~ # ssh data1 Last login: Tue Jan 5 18:06:40 2021 from 10.58.121.181 Should see 3 devices, which are named ceph LVM-type devices data1:~ # lsblk NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINT sda 8:0 0 8G 0 disk \u2514\u2500ceph--14c886af--269d--475f--8ee3--f5e4abbb222d-osd--data--38911b2d--f30a--4b09--9010--8dd6fad2fcc6 254:0 0 8G 0 lvm sdb 8:16 0 8G 0 disk \u2514\u2500ceph--9ec4a77a--5d67--4b21--be53--d7e9221082de-osd--data--00cb3dc6--c28b--41ae--95de--efb86da254da 254:1 0 8G 0 lvm sdc 8:32 0 8G 0 disk \u2514\u2500ceph--5eaea8a8--bb68--49dd--a1e3--b82c5464ab1f-osd--data--a4a05f70--53d9--41d4--a273--4f47a088968a 254:2 0 8G 0 lvm sr0 11:0 1 672M 0 rom vda 253:0 0 20G 0 disk \u251c\u2500vda1 253:1 0 8M 0 part \u251c\u2500vda2 253:2 0 18.4G 0 part / \u2514\u2500vda3 253:3 0 1.7G 0 part [SWAP] See the raw ceph devices data1:~ # ls -lad /dev/ceph* drwxr-xr-x 2 root root 60 Oct 5 13:15 /dev/ceph-14c886af-269d-475f-8ee3-f5e4abbb222d drwxr-xr-x 2 root root 60 Oct 5 13:16 /dev/ceph-5eaea8a8-bb68-49dd-a1e3-b82c5464ab1f drwxr-xr-x 2 root root 60 Oct 5 13:15 /dev/ceph-9ec4a77a-5d67-4b21-be53-d7e9221082de Dig down even farther by examining the content of one of the directories, see a symlink to an LVM device-mapper device. All the devices are tied together with LVM. Note that the name of the symlink is named osd-data- . data1:~ # ls -l /dev/ceph-14c886af-269d-475f-8ee3-f5e4abbb222d lrwxrwxrwx 1 ceph ceph 7 Oct 5 13:15 osd-data-38911b2d-f30a-4b09-9010-8dd6fad2fcc6 -> ../dm-0 data1:~ # l /dev/dm* brw-rw---- 1 ceph ceph 254, 0 Jan 5 18:10 /dev/dm-0 brw-rw---- 1 ceph ceph 254, 1 Jan 5 18:10 /dev/dm-1 brw-rw---- 1 ceph ceph 254, 2 Jan 5 18:10 /dev/dm-2 Task 3: Examine a storage host\u2019s OSD details \u00b6 data1:~ # cd /var/lib/ceph/ data1:/var/lib/ceph # ls -l drwxr-x--- 1 ceph ceph 0 Aug 24 22:03 bootstrap-mds drwxr-x--- 1 ceph ceph 0 Aug 24 22:03 bootstrap-mgr drwxr-x--- 1 ceph ceph 24 Oct 5 13:15 bootstrap-osd drwxr-x--- 1 ceph ceph 0 Aug 24 22:03 bootstrap-rbd drwxr-x--- 1 ceph ceph 0 Aug 24 22:03 bootstrap-rbd-mirror drwxr-x--- 1 ceph ceph 0 Aug 24 22:03 bootstrap-rgw drwxr-x--- 1 ceph ceph 12 Oct 5 09:04 crash drwxr-x--- 1 ceph ceph 0 Aug 24 22:03 mds drwxr-x--- 1 ceph ceph 0 Aug 24 22:03 mgr drwxr-x--- 1 ceph ceph 0 Aug 24 22:03 mon drwxr-x--- 1 ceph ceph 38 Oct 5 13:16 osd drwxr-x--- 1 ceph ceph 0 Aug 24 22:03 tmp See 3 different sub-directories, each representing the 3 different OSDs (ceph-2, ceph-6, ceph-10) that are running on this storage server data1:/var/lib/ceph # cd osd/ data1:/var/lib/ceph/osd # ls -l drwxrwxrwt 2 ceph ceph 320 Oct 5 13:16 ceph-10 drwxrwxrwt 2 ceph ceph 320 Oct 5 13:15 ceph-2 drwxrwxrwt 2 ceph ceph 320 Oct 5 13:16 ceph-6 See some functional files associated with the OSD and BlueStore. See a block file, which is a symlink to one of the ceph devices, which stores the raw objects for the OSD. data1:/var/lib/ceph/osd # cd ceph-2 data1:/var/lib/ceph/osd/ceph-2 # ls -l -rw-r--r-- 1 ceph ceph 400 Oct 5 13:15 activate.monmap lrwxrwxrwx 1 ceph ceph 92 Oct 5 13:15 block -> /dev/ceph-14c886af-269d-475f-8ee3-f5e4abbb222d/osd-data-38911b2d-f30a-4b09-9010-8dd6fad2fcc6 -rw------- 1 ceph ceph 2 Oct 5 13:15 bluefs -rw------- 1 ceph ceph 37 Oct 5 13:15 ceph_fsid -rw-r--r-- 1 ceph ceph 37 Oct 5 13:15 fsid -rw------- 1 ceph ceph 55 Oct 5 13:15 keyring -rw------- 1 ceph ceph 8 Oct 5 13:15 kv_backend -rw------- 1 ceph ceph 21 Oct 5 13:15 magic -rw------- 1 ceph ceph 4 Oct 5 13:15 mkfs_done -rw------- 1 ceph ceph 41 Oct 5 13:15 osd_key -rw------- 1 ceph ceph 6 Oct 5 13:15 ready -rw------- 1 ceph ceph 3 Oct 5 13:15 require_osd_release -rw------- 1 ceph ceph 10 Oct 5 13:15 type -rw------- 1 ceph ceph 2 Oct 5 13:15 whoami data1:/var/lib/ceph/osd/ceph-2 # cat ceph_fsid # The unique ID of this Ceph cluster 343ee7d3-232f-4c71-8216-1edbc55ac6e0 data1:/var/lib/ceph/osd/ceph-2 # cat fsid # The unique ID of this OSD 6df58ebc-dbfe-4822-9714-90212c06ea05 data1:/var/lib/ceph/osd/ceph-2 # cat keyring # The Ceph key for this OSD [osd.2] key = data1:/var/lib/ceph/osd/ceph-2 # cat ready # Indication of the readiness of this OSD ready data1:/var/lib/ceph/osd/ceph-2 # cat type # filestore or bluestore (in this case: bluestore) bluestore data1:/var/lib/ceph/osd/ceph-2 # cat whoami # The integer id of this OSD (in this case: 2) 2 Task 4: Display BlueStore information using ceph-bluestore-tool \u00b6 Show BlueStore metadata for osd.2: data1:/var/lib/ceph/osd/ceph-2 # ceph-bluestore-tool show-label --path /var/lib/ceph/osd/ceph-2 inferring bluefs devices from bluestore path { \"/var/lib/ceph/osd/ceph-2/block\": { \"osd_uuid\": \"6df58ebc-dbfe-4822-9714-90212c06ea05\", \"size\": 8585740288, \"btime\": \"2020-10-05 13:15:51.227799\", \"description\": \"main\", \"bluefs\": \"1\", \"ceph_fsid\": \"343ee7d3-232f-4c71-8216-1edbc55ac6e0\", \"kv_backend\": \"rocksdb\", \"magic\": \"ceph osd volume v026\", \"mkfs_done\": \"yes\", \"osd_key\": , \"ready\": \"ready\", \"require_osd_release\": \"14\", \"whoami\": \"2\" } Run a manual \u201cscrub\u201d on osd.7 using ceph-blestore-tool. (Received error, the tool won\u2019t allow you to do this while the OSD is running.) data1:/var/lib/ceph/osd/ceph-2 # ceph-bluestore-tool fsck --path /var/lib/ceph/osd/ceph-2 error from fsck: (11) Resource temporarily unavailable 2021-01-05 18:32:25.528 7f4abad6e180 -1 bluestore(/var/lib/ceph/osd/ceph-2) _lock_fsid failed to lock /var/lib/ceph/osd/ceph-2/fsid (is another ceph-osd still running?)(11) Resource temporarily unavailable Simulate that the OSD is down, shutdown the OSD: data1:/var/lib/ceph/osd/ceph-2 # systemctl stop ceph-osd@2.service Now run the \u201cfsck\u201d command again. This time the \u201cfsck\u201d has worked, with the output showing: \u201cfsck success\u201d data1:/var/lib/ceph/osd/ceph-2 # ceph-bluestore-tool fsck --path /var/lib/ceph/osd/ceph-2 fsck success Restart the OSD: data1:/var/lib/ceph/osd/ceph-2 # systemctl start ceph-osd@2.service data1:/var/lib/ceph/osd/ceph-2 # ceph-bluestore-tool show-label --path /var/lib/ceph/osd/ceph-2 inferring bluefs devices from bluestore path { \"/var/lib/ceph/osd/ceph-2/block\": { \"osd_uuid\": \"6df58ebc-dbfe-4822-9714-90212c06ea05\", \"size\": 8585740288, \"btime\": \"2020-10-05 13:15:51.227799\", \"description\": \"main\", \"bluefs\": \"1\", \"ceph_fsid\": \"343ee7d3-232f-4c71-8216-1edbc55ac6e0\", \"kv_backend\": \"rocksdb\", \"magic\": \"ceph osd volume v026\", \"mkfs_done\": \"yes\", \"osd_key\": , \"ready\": \"ready\", \"require_osd_release\": \"14\", \"whoami\": \"2\" } } 2.2. Common Day 1 Tasks Using the CLI \u00b6 Including ollowing topics in relation to the commandline: Users and Ceph Configuration Health commands Erasure Code Profiles CRUSH Map rules Pools Scrubbing OSDs and Placement Groups Manager modules The tell commands 2.2.1. Ceph Users and Configuration \u00b6 Task 1: View the current user keyrings \u00b6 Ceph keyrings are stored in below directory admin:~ # cd /etc/ceph/ admin:/etc/ceph # ls -l -rw------- 1 root root 151 Oct 5 13:13 ceph.client.admin.keyring -rw-r--r-- 1 root root 980 Oct 5 13:13 ceph.conf -rw-r--r-- 1 root root 92 Aug 24 22:03 rbdmap The value of 'key' is the key that\u2019s on the keyring. The admin keyring is \u201callow\u201ded all capabilities (permissions) to all services in the cluster, as expected. there are more than just client keys. admin:/etc/ceph # cat ceph.client.admin.keyring [client.admin] key = caps mds = \"allow *\" caps mon = \"allow *\" caps osd = \"allow *\" caps mgr = \"allow *\" Display the existing users with the \u201cauth\u201d command: Below two commands are equivalent admin:/etc/ceph # ceph -n client.admin -keyring=/etc/ceph/ceph.client.admin.keyring auth ls -- failed??? no valid command found admin:/etc/ceph # ceph auth ls installed auth entries: mds.mon1 key: caps: [mds] allow * caps: [mgr] allow profile mds caps: [mon] allow profile mds caps: [osd] allow rwx mds.mon2 key: caps: [mds] allow * caps: [mgr] allow profile mds caps: [mon] allow profile mds caps: [osd] allow rwx mds.mon3 key: caps: [mds] allow * caps: [mgr] allow profile mds caps: [mon] allow profile mds caps: [osd] allow rwx osd.0 key: caps: [mgr] allow profile osd caps: [mon] allow profile osd caps: [osd] allow * osd.1 key: caps: [mgr] allow profile osd caps: [mon] allow profile osd caps: [osd] allow * osd.10 key: caps: [mgr] allow profile osd caps: [mon] allow profile osd caps: [osd] allow * osd.11 key: caps: [mgr] allow profile osd caps: [mon] allow profile osd caps: [osd] allow * osd.2 key: caps: [mgr] allow profile osd caps: [mon] allow profile osd caps: [osd] allow * osd.3 key: caps: [mgr] allow profile osd caps: [mon] allow profile osd caps: [osd] allow * osd.4 key: caps: [mgr] allow profile osd caps: [mon] allow profile osd caps: [osd] allow * osd.5 key: caps: [mgr] allow profile osd caps: [mon] allow profile osd caps: [osd] allow * osd.6 key: caps: [mgr] allow profile osd caps: [mon] allow profile osd caps: [osd] allow * osd.7 key: caps: [mgr] allow profile osd caps: [mon] allow profile osd caps: [osd] allow * osd.8 key: caps: [mgr] allow profile osd caps: [mon] allow profile osd caps: [osd] allow * osd.9 key: caps: [mgr] allow profile osd caps: [mon] allow profile osd caps: [osd] allow * client.admin key: caps: [mds] allow * caps: [mgr] allow * caps: [mon] allow * caps: [osd] allow * client.bootstrap-mds key: caps: [mon] allow profile bootstrap-mds client.bootstrap-mgr key: caps: [mon] allow profile bootstrap-mgr client.bootstrap-osd key: caps: [mgr] allow r caps: [mon] allow profile bootstrap-osd client.bootstrap-rbd key: caps: [mon] allow profile bootstrap-rbd client.bootstrap-rbd-mirror key: caps: [mon] allow profile bootstrap-rbd-mirror client.bootstrap-rgw key: caps: [mon] allow profile bootstrap-rgw client.igw.mon2 key: caps: [mgr] allow r caps: [mon] allow * caps: [osd] allow * client.rgw.mon3 key: caps: [mgr] allow r caps: [mon] allow rwx caps: [osd] allow rwx client.storage key: caps: [mon] allow rw mgr.mon1 key: caps: [mds] allow * caps: [mon] allow profile mgr caps: [osd] allow * Task 2: Create a new keyring and associated user \u00b6 1). There are several different ways to create a new keyring and user. This is just one way. Create a new keyring and associated user named James . Remembgr that typically all new users will need read rights for the mon capability, and will need read/write rights for the osd capability, including a specification of rights to a pool. admin:/etc/ceph # ceph-authtool -g -n client.james --cap mon 'allow r' --cap osd 'allow rw pool=iscsi-images' -C /etc/ceph/ceph.client.james.keyring creating /etc/ceph/ceph.client.james.keyring admin:/etc/ceph # l total 16 drwxr-xr-x 1 root root 130 Jan 5 19:31 ./ drwxr-xr-x 1 root root 4392 Oct 5 13:03 ../ -rw------- 1 root root 151 Oct 5 13:13 ceph.client.admin.keyring -rw------- 1 root root 126 Jan 5 19:31 ceph.client.james.keyring -rw-r--r-- 1 root root 980 Oct 5 13:13 ceph.conf -rw-r--r-- 1 root root 92 Aug 24 22:03 rbdmap 2). Show the content of the newly created keyring: admin:/etc/ceph # cat ceph.client.james.keyring [client.james] key = caps mon = \"allow r\" caps osd = \"allow rw pool=iscsi-images\" 3). Officially add the new keyring to Ceph: admin:/etc/ceph # ceph auth add client.james -i /etc/ceph/ceph.client.james.keyring added key for client.james 4). Show the key information using the \u201cauth\u201d function: admin:/etc/ceph # ceph auth get client.james exported keyring for client.james [client.james] key = caps mon = \"allow r\" caps osd = \"allow rw pool=iscsi-images\" Task 3: Create a client key for RBD \u00b6 1). Change to the directory that contains the ceph keyrings. admin:~ # cd /etc/ceph/ 2). List the content of the directory: Although you see the admin users\u2019s keyring, ceph.client.admin.keyring, there is not yet a file that is appropriate for a specific application to use. Also note that the permissions on the keyring file are quite restrictive: 0600 admin:/etc/ceph # ls -l -rw------- 1 root root 151 Oct 5 13:13 ceph.client.admin.keyring -rw------- 1 root root 126 Jan 5 19:31 ceph.client.james.keyring -rw-r--r-- 1 root root 980 Oct 5 13:13 ceph.conf -rw-r--r-- 1 root root 92 Aug 24 22:03 rbdmap 3). Show the content of the admin user\u2019s keyring: You will use the value associated with the \u201ckey\u201d key to create a new file. Copy the \u201ckey\u201d value using your favorite method. admin:/etc/ceph # cat ceph.client.admin.keyring [client.admin] key = caps mds = \"allow *\" caps mon = \"allow *\" caps osd = \"allow *\" caps mgr = \"allow *\" 4). Open a new file for editing called admin.secret using your favorite editor (such as vi): The name of the file isn\u2019t very important, but naming it this way will help to identify its purpose: it\u2019s a secret key for the admin user. Note that there are many ways to do this. An alternative way is mentioned in the tip below that will do this in one step using grep and awk. admin:/etc/ceph # vi admin.secret 5). Paste the \u201ckey\u201d value into the new file. It will be the only content of the file. It will look like this (in fact it\u2019s probably exactly the same as this, if you\u2019re using the demo environment provided to you): admin:/etc/ceph # cat admin.secret 6). Save the file and exist out of the editor. 7). Change the permissions of the file so that no other user on the host can see the content of the file: admin:/etc/ceph # chmod 0600 admin.secret admin:/etc/ceph # l drwxr-xr-x 1 root root 154 Jan 5 20:03 ./ drwxr-xr-x 1 root root 4392 Oct 5 13:03 ../ -rw------- 1 root root 41 Jan 5 20:03 admin.secret -rw------- 1 root root 151 Oct 5 13:13 ceph.client.admin.keyring -rw------- 1 root root 126 Jan 5 19:31 ceph.client.james.keyring -rw-r--r-- 1 root root 980 Oct 5 13:13 ceph.conf -rw-r--r-- 1 root root 92 Aug 24 22:03 rbdmap Tip: An alternative way to create this key file is to simply use grep/awk together in one bash command, like this: admin:/etc/ceph # grep \"key =\" ceph.client.admin.keyring | awk -F\" = \" '{ print $2 }' admin:/etc/ceph # grep \"key =\" ceph.client.admin.keyring | awk -F\" = \" '{ print $2 }' > admin.secret admin:/etc/ceph # cat admin.secret Task 4: View the Ceph master configuration file \u00b6 View the content of the file. The file is managed and controlled by DeepSea. The comment makes reference to the control files in the /srv/salt/ceph/configuration/ directory hierarchy. This is a very simple storage cluster. In a more diverse and sophisticated ceph cluster there may be more configuration settings defined. Although this exercise doesn\u2019t call out any more specific information about this configuration file, you may take a moment to consider the content of the file before finishing the task. admin:/etc/ceph # cat ceph.conf # DeepSea default configuration. Changes in this file will be overwritten on # package update. Include custom configuration fragments in # /srv/salt/ceph/configuration/files/ceph.conf.d/[global,osd,mon,mgr,mds,client].conf [global] fsid = 343ee7d3-232f-4c71-8216-1edbc55ac6e0 mon_initial_membgrs = mon1, mon2, mon3 mon_host = 10.58.121.186, 10.58.121.187, 10.58.121.188 auth_cluster_required = cephx auth_service_required = cephx auth_client_required = cephx public_network = 10.58.120.0/23 cluster_network = 10.58.120.0/23 ms_bind_msgr2 = false # enable old ceph health format in the json output. This fixes the # ceph_exporter. This option will only stay until the prometheus plugin takes # over mon_health_preluminous_compat = true mon health preluminous compat warning = false rbd default features = 3 [client.rgw.mon3] rgw frontends = \"beast port=80\" rgw dns name = mon3.sha.me.corp rgw enable usage log = true [osd] [mon] [mgr] [mds] [client] admin:/etc/ceph # ls -l /srv/salt/ceph/configuration/ drwxr-xr-x 1 salt salt 18 Oct 5 13:13 cache drwxr-xr-x 1 root root 38 Oct 5 09:04 check drwxr-xr-x 1 root root 74 Oct 5 09:04 create -rw-r--r-- 1 root root 217 May 14 2020 default-import.sls -rw-r--r-- 1 root root 222 May 14 2020 default.sls drwxr-xr-x 1 root root 276 Oct 5 12:55 files -rw-r--r-- 1 root root 74 May 14 2020 init.sls 2.2.2. Run the Ceph Health Commands \u00b6 Get overall health status admin:~ # ceph health HEALTH_OK admin:~ # ceph -s admin:~ # ceph status cluster: id: 343ee7d3-232f-4c71-8216-1edbc55ac6e0 health: HEALTH_OK services: mon: 3 daemons, quorum mon1,mon2,mon3 (age 9w) mgr: mon1(active, since 5w) mds: cephfs:1 {0=mon3=up:active} 2 up:standby osd: 12 osds: 12 up (since 98m), 12 in (since 3M) rgw: 1 daemon active (mon3) task status: scrub status: mds.mon3: idle data: pools: 7 pools, 208 pgs objects: 246 objects, 4.7 KiB usage: 14 GiB used, 82 GiB / 96 GiB avail pgs: 208 active+clean io: client: 852 B/s rd, 0 op/s rd, 0 op/s wr Run the \u201cstatus\u201d command for the monitors: admin:~ # ceph mon stat e1: 3 mons at { mon1=[v2:10.58.121.186:3300/0,v1:10.58.121.186:6789/0], mon2=[v2:10.58.121.187:3300/0,v1:10.58.121.187:6789/0], mon3=[v2:10.58.121.188:3300/0,v1:10.58.121.188:6789/0] }, election epoch 22, leader 0 mon1, quorum 0,1,2 mon1,mon2,mon3 Run the \u201cstatus\u201d command for the placement groups: admin:~ # ceph pg stat 208 pgs: 208 active+clean; 4.7 KiB data, 2.1 GiB used, 82 GiB / 96 GiB avail; 852 B/s rd, 0 op/s Run the ceph \u201cstatus\u201d command while watching for changes to the status: admin:~ # ceph -s --watch-debug cluster: id: 343ee7d3-232f-4c71-8216-1edbc55ac6e0 health: HEALTH_OK services: mon: 3 daemons, quorum mon1,mon2,mon3 (age 9w) mgr: mon1(active, since 5w) mds: cephfs:1 {0=mon3=up:active} 2 up:standby osd: 12 osds: 12 up (since 104m), 12 in (since 3M) rgw: 1 daemon active (mon3) task status: scrub status: mds.mon3: idle data: pools: 7 pools, 208 pgs objects: 246 objects, 4.7 KiB usage: 14 GiB used, 82 GiB / 96 GiB avail pgs: 208 active+clean io: client: 1.2 KiB/s rd, 1 op/s rd, 0 op/s wr 2021-01-05 20:20:53.947298 mgr.mon1 [DBG] pgmap v1597415: 208 pgs: 208 active+clean; 4.7 KiB data, 2.1 GiB used, 82 GiB / 96 GiB avail; 852 B/s rd, 0 op/s 2021-01-05 20:20:55.949294 mgr.mon1 [DBG] pgmap v1597416: 208 pgs: 208 active+clean; 4.7 KiB data, 2.1 GiB used, 82 GiB / 96 GiB avail; 1.2 KiB/s rd, 1 op/s ....... 2.2.3. Manipulate Pools \u00b6 Task 1: Display a list of the current pools \u00b6 admin:~ # ceph osd pool ls iscsi-images cephfs_data cephfs_metadata .rgw.root default.rgw.control default.rgw.meta default.rgw.log admin:~ # ceph osd pool ls detail pool 1 'iscsi-images' replicated size 3 min_size 2 crush_rule 0 object_hash rjenkins pg_num 32 pgp_num 32 autoscale_mode on last_change 448 lfor 0/448/446 flags hashpspool stripe_width 0 application rbd pool 2 'cephfs_data' replicated size 3 min_size 2 crush_rule 0 object_hash rjenkins pg_num 32 pgp_num 32 last_change 1395 lfor 0/1374/1372 flags hashpspool stripe_width 0 application cephfs pool 3 'cephfs_metadata' replicated size 3 min_size 2 crush_rule 0 object_hash rjenkins pg_num 16 pgp_num 16 last_change 1385 lfor 0/975/973 flags hashpspool stripe_width 0 pg_autoscale_bias 4 pg_num_min 16 recovery_priority 5 application cephfs pool 4 '.rgw.root' replicated size 3 min_size 2 crush_rule 0 object_hash rjenkins pg_num 32 pgp_num 32 autoscale_mode warn last_change 31 flags hashpspool stripe_width 0 application rgw pool 5 'default.rgw.control' replicated size 3 min_size 2 crush_rule 0 object_hash rjenkins pg_num 32 pgp_num 32 autoscale_mode warn last_change 33 flags hashpspool stripe_width 0 application rgw pool 6 'default.rgw.meta' replicated size 3 min_size 2 crush_rule 0 object_hash rjenkins pg_num 32 pgp_num 32 autoscale_mode warn last_change 35 flags hashpspool stripe_width 0 application rgw pool 7 'default.rgw.log' replicated size 3 min_size 2 crush_rule 0 object_hash rjenkins pg_num 32 pgp_num 32 autoscale_mode warn last_change 37 flags hashpspool stripe_width 0 application rgw List pools with their index numbgr. Note how the index numbgr matches the index numbgr of the detail listing above. admin:~ # ceph osd lspools 1 iscsi-images 2 cephfs_data 3 cephfs_metadata 4 .rgw.root 5 default.rgw.control 6 default.rgw.meta 7 default.rgw.log Task 2: Display the usage data and stats of the current pools \u00b6 Display pool usages. Note again index \u201cID\u201d for the pool. admin:~ # ceph df RAW STORAGE: CLASS SIZE AVAIL USED RAW USED %RAW USED hdd 96 GiB 82 GiB 2.1 GiB 14 GiB 14.81 TOTAL 96 GiB 82 GiB 2.1 GiB 14 GiB 14.81 POOLS: POOL ID STORED OBJECTS USED %USED MAX AVAIL iscsi-images 1 389 B 2 192 KiB 0 25 GiB cephfs_data 2 0 B 0 0 B 0 25 GiB cephfs_metadata 3 7.2 KiB 48 1.5 MiB 0 25 GiB .rgw.root 4 1.2 KiB 4 768 KiB 0 25 GiB default.rgw.control 5 0 B 8 0 B 0 25 GiB default.rgw.meta 6 381 B 3 576 KiB 0 25 GiB default.rgw.log 7 35 KiB 208 35 KiB 0 25 GiB admin:~ # ceph df detail RAW STORAGE: CLASS SIZE AVAIL USED RAW USED %RAW USED hdd 96 GiB 82 GiB 2.1 GiB 14 GiB 14.81 TOTAL 96 GiB 82 GiB 2.1 GiB 14 GiB 14.81 POOLS: POOL ID STORED OBJECTS USED %USED MAX AVAIL QUOTA OBJECTS QUOTA BYTES DIRTY USED COMPR UNDER COMPR iscsi-images 1 389 B 2 192 KiB 0 25 GiB N/A N/A 2 0 B 0 B cephfs_data 2 0 B 0 0 B 0 25 GiB N/A N/A 0 0 B 0 B cephfs_metadata 3 7.2 KiB 48 1.5 MiB 0 25 GiB N/A N/A 48 0 B 0 B .rgw.root 4 1.2 KiB 4 768 KiB 0 25 GiB N/A N/A 4 0 B 0 B default.rgw.control 5 0 B 8 0 B 0 25 GiB N/A N/A 8 0 B 0 B default.rgw.meta 6 381 B 3 576 KiB 0 25 GiB N/A N/A 3 0 B 0 B default.rgw.log 7 35 KiB 208 35 KiB 0 25 GiB N/A N/A 208 0 B 0 B Display pool usages using rados command admin:~ # rados df POOL_NAME USED OBJECTS CLONES COPIES MISSING_ON_PRIMARY UNFOUND DEGRADED RD_OPS RD WR_OPS WR USED COMPR UNDER COMPR .rgw.root 768 KiB 4 0 12 0 0 0 40 40 KiB 4 4 KiB 0 B 0 B cephfs_data 0 B 0 0 0 0 0 0 0 0 B 0 0 B 0 B 0 B cephfs_metadata 1.5 MiB 48 0 144 0 0 0 0 0 B 111 42 KiB 0 B 0 B default.rgw.control 0 B 8 0 24 0 0 0 0 0 B 0 0 B 0 B 0 B default.rgw.log 35 KiB 208 0 624 0 0 0 5919671 5.6 GiB 3945118 946 KiB 0 B 0 B default.rgw.meta 576 KiB 3 0 9 0 0 0 38 28 KiB 4 3 KiB 0 B 0 B iscsi-images 192 KiB 2 0 6 0 0 0 4184657 4.0 GiB 8 2 KiB 0 B 0 B total_objects 246 total_used 14 GiB total_avail 82 GiB total_space 96 GiB Show the statistics of the pools: admin:~ # ceph osd pool stats pool iscsi-images id 1 client io 1.2 KiB/s rd, 1 op/s rd, 0 op/s wr pool cephfs_data id 2 nothing is going on pool cephfs_metadata id 3 nothing is going on pool .rgw.root id 4 nothing is going on pool default.rgw.control id 5 nothing is going on pool default.rgw.meta id 6 nothing is going on pool default.rgw.log id 7 nothing is going on Show only the statistics about a specific pool: admin:~ # ceph osd pool stats .rgw.root pool .rgw.root id 4 nothing is going on Show which CRUSH Map ruleset was used to create the .rgw.root pool: admin:~ # ceph osd pool get .rgw.root crush_rule crush_rule: replicated_rule Show the list of all the attributes of a pool that can be queried: admin:~ # ceph osd pool get .rgw.root size min_size pg_num pgp_num crush_rule Hashpspool Nodelete Nopgchange Nosizechange write_fadvise_dontneed noscrub|nodeep-scrub hit_set_type hit_set_period hit_set_count hit_set_fpp use_gmt_hitset target_max_objects target_max_bytes cache_target_dirty_ratio cache_target_dirty_high_ratio cache_target_full_ratio cache_min_flush_age cache_min_evict_age erasure_code_profile min_read_recency_for_promote all|min_write_recency_for_promote fast_read|hit_set_grade_decay_rate hit_set_search_last_n scrub_min_interval scrub_max_interval deep_scrub_interval recovery_priority recovery_op_priority scrub_priority compression_mode compression_algorithm compression_required_ratio compression_max_blob_size compression_min_blob_size csum_type|csum_min_block csum_max_block allow_ec_overwrites fingerprint_algorithm pg_autoscale_mode pg_autoscale_bias pg_num_min target_size_bytes target_size_ratio Task 3: Create two new pools, one replicated, one EC \u00b6 1). Create a new replicated pool that will be used for storing block data for RBD. Use the standard replicated_ruleset CRUSH Map: It would be tempting to the use the better_ruleset, but this demo environment doesn\u2019t have enough resources for that. This is a demo environment, so the PG numbgrs will be low. In your production environments, be sure to assign an appropriately high numbgr, or use the pg_autoscaler manager module. admin:~ # ceph osd pool create rbd_pool 4 4 replicated replicated_rule pool 'rbd_pool' created 2). Tell the cluster that you expect to have this new rbd_pool to use 50% of the total capacity: admin:~ # ceph osd pool set rbd_pool target_size_ratio .5 set pool 8 target_size_ratio to .5 3). Create a new EC pool that will be used for storing RGW buckets and objects. Use the usable_profile Erasure Code profile that was created in an earlier exercise. And use the ec_rule CRUSH Map ruleset that was created in an earlier exercise: admin:~ # ceph osd pool create bucket_pool 4 4 erasure usable_profile ec_rule pool 'bucket_pool' created 4). Tell the cluster that you expect to have this new bucket_pool to use 100GB of data: POOL_TARGET_SIZE_BYTES_OVERCOMMITTED admin:~ # ceph osd pool set bucket_pool target_size_bytes 100000000000 set pool 9 target_size_bytes to 100000000000 5). Enable the PG Autoscaler feature on the two new pools, to ensure that we have an appropriate assignment of placement groups in the demo cluster: This presumes that you completed an earlier exercise that enable the pg_autoscaler manager module. admin:~ # ceph osd pool set bucket_pool pg_autoscale_mode on set pool 9 pg_autoscale_mode to on admin:~ # ceph osd pool set rbd_pool pg_autoscale_mode on set pool 8 pg_autoscale_mode to on 6). Again display a list of all the pools, which will now include the two new pools that you\u2019ve just created: Notice in the detail listing that the two new pools don\u2019t have an application attribute assigned to them. admin:~ # ceph osd lspools 1 iscsi-images 2 cephfs_data 3 cephfs_metadata 4 .rgw.root 5 default.rgw.control 6 default.rgw.meta 7 default.rgw.log 8 rbd_pool 9 bucket_pool admin:~ # ceph osd pool ls detail pool 1 'iscsi-images' replicated size 3 min_size 2 crush_rule 0 object_hash rjenkins pg_num 32 pgp_num 32 autoscale_mode on last_change 448 lfor 0/448/446 flags hashpspool stripe_width 0 application rbd pool 2 'cephfs_data' replicated size 3 min_size 2 crush_rule 0 object_hash rjenkins pg_num 32 pgp_num 32 last_change 1395 lfor 0/1374/1372 flags hashpspool stripe_width 0 application cephfs pool 3 'cephfs_metadata' replicated size 3 min_size 2 crush_rule 0 object_hash rjenkins pg_num 16 pgp_num 16 last_change 1385 lfor 0/975/973 flags hashpspool stripe_width 0 pg_autoscale_bias 4 pg_num_min 16 recovery_priority 5 application cephfs pool 4 '.rgw.root' replicated size 3 min_size 2 crush_rule 0 object_hash rjenkins pg_num 32 pgp_num 32 autoscale_mode warn last_change 31 flags hashpspool stripe_width 0 application rgw pool 5 'default.rgw.control' replicated size 3 min_size 2 crush_rule 0 object_hash rjenkins pg_num 32 pgp_num 32 autoscale_mode warn last_change 33 flags hashpspool stripe_width 0 application rgw pool 6 'default.rgw.meta' replicated size 3 min_size 2 crush_rule 0 object_hash rjenkins pg_num 32 pgp_num 32 autoscale_mode warn last_change 35 flags hashpspool stripe_width 0 application rgw pool 7 'default.rgw.log' replicated size 3 min_size 2 crush_rule 0 object_hash rjenkins pg_num 32 pgp_num 32 autoscale_mode warn last_change 37 flags hashpspool stripe_width 0 application rgw pool 8 'rbd_pool' replicated size 3 min_size 2 crush_rule 0 object_hash rjenkins pg_num 32 pgp_num 32 autoscale_mode on last_change 1415 lfor 0/0/1413 flags hashpspool stripe_width 0 target_size_ratio 0.5 pool 9 'bucket_pool' erasure size 3 min_size 2 crush_rule 3 object_hash rjenkins pg_num 4 pgp_num 4 autoscale_mode on last_change 1410 flags hashpspool stripe_width 8192 target_size_bytes 100000000000 7). Check the pg_autoscale status, particularly to see a comparison of how much raw space is being consumed by the two pools: See that the RATE column for all of the replicated pools shows the value of 3.0, while the value for the bucket_pool \u2013 which is an EC pool \u2013 is 1.5. The EC pool, with a K+M of 2+1 consumes considerably less raw storage space. See the TARGET RATIO for the rbd_pool. Notice that the autoscaler has automatically adjusted the numbgr PGs assigned to rbd_pool from \u201c4\u201d to \u201c128\u201d because you told the cluster to have the pool use 50% of the capacity. See the TARGET SIZE for the bucket_pool, roughly 100GB. But the cluster may not have changed the PG_NUM value yet. The autoscaler will adjust the numbgr of PGs gradually, so as not to disrupt the performance too dramatically. While you\u2019re here, you might also notice the RAW CAPACITY column. All pools are expecting to divide the cluster space equally, even though you\u2019ve explicitly told the cluster that rbd_pool and bucket_pool will deviate from that even division. admin:~ # ceph osd pool autoscale-status POOL SIZE TARGET SIZE RATE RAW CAPACITY RATIO TARGET RATIO EFFECTIVE RATIO BIAS PG_NUM NEW PG_NUM AUTOSCALE iscsi-images 389 3.0 98256M 0.0000 1.0 32 on cephfs_data 0 3.0 98256M 0.0000 1.0 32 off cephfs_metadata 7412 3.0 98256M 0.0000 4.0 16 off .rgw.root 1245 3.0 98256M 0.0000 1.0 32 warn default.rgw.control 0 3.0 98256M 0.0000 1.0 32 warn default.rgw.meta 381 3.0 98256M 0.0000 1.0 32 warn default.rgw.log 35900 3.0 98256M 0.0000 1.0 32 warn rbd_pool 0 3.0 98256M 0.0000 0.5000 1.0 32 on bucket_pool 0 95367M 1.5 98256M 1.4559 1.0 4 on Task 4: Assign an application to the two new pools \u00b6 1). Assign the rbd application to the new rbd_pool that you created in the previous task: admin:~ # ceph osd pool application enable rbd_pool rbd enabled application 'rbd' on pool 'rbd_pool' 2). Instruct the cluster to prepare the new rbd_pool for storing block device images: admin:~ # rbd pool init rbd_pool 3). Assign the rgw application to the new bucket_pool that you created in the previous task: admin:~ # ceph osd pool application enable bucket_pool rgw enabled application 'rgw' on pool 'bucket_pool' 4). Display a list of all the pools again, this time noticing that the application attribute is set on the two new pools. admin:~ # ceph osd lspools 1 iscsi-images 2 cephfs_data 3 cephfs_metadata 4 .rgw.root 5 default.rgw.control 6 default.rgw.meta 7 default.rgw.log 8 rbd_pool 9 bucket_pool admin:~ # ceph osd pool ls detail pool 1 'iscsi-images' replicated size 3 min_size 2 crush_rule 0 object_hash rjenkins pg_num 32 pgp_num 32 autoscale_mode on last_change 448 lfor 0/448/446 flags hashpspool stripe_width 0 application rbd pool 2 'cephfs_data' replicated size 3 min_size 2 crush_rule 0 object_hash rjenkins pg_num 32 pgp_num 32 last_change 1395 lfor 0/1374/1372 flags hashpspool stripe_width 0 application cephfs pool 3 'cephfs_metadata' replicated size 3 min_size 2 crush_rule 0 object_hash rjenkins pg_num 16 pgp_num 16 last_change 1385 lfor 0/975/973 flags hashpspool stripe_width 0 pg_autoscale_bias 4 pg_num_min 16 recovery_priority 5 application cephfs pool 4 '.rgw.root' replicated size 3 min_size 2 crush_rule 0 object_hash rjenkins pg_num 32 pgp_num 32 autoscale_mode warn last_change 31 flags hashpspool stripe_width 0 application rgw pool 5 'default.rgw.control' replicated size 3 min_size 2 crush_rule 0 object_hash rjenkins pg_num 32 pgp_num 32 autoscale_mode warn last_change 33 flags hashpspool stripe_width 0 application rgw pool 6 'default.rgw.meta' replicated size 3 min_size 2 crush_rule 0 object_hash rjenkins pg_num 32 pgp_num 32 autoscale_mode warn last_change 35 flags hashpspool stripe_width 0 application rgw pool 7 'default.rgw.log' replicated size 3 min_size 2 crush_rule 0 object_hash rjenkins pg_num 32 pgp_num 32 autoscale_mode warn last_change 37 flags hashpspool stripe_width 0 application rgw pool 8 'rbd_pool' replicated size 3 min_size 2 crush_rule 0 object_hash rjenkins pg_num 32 pgp_num 32 autoscale_mode on last_change 1420 lfor 0/0/1413 flags hashpspool,selfmanaged_snaps stripe_width 0 target_size_ratio 0.5 application rbd removed_snaps [1~3] pool 9 'bucket_pool' erasure size 3 min_size 2 crush_rule 3 object_hash rjenkins pg_num 4 pgp_num 4 autoscale_mode on last_change 1422 flags hashpspool stripe_width 8192 target_size_bytes 100000000000 application rgw 5). Another way to display which application is assigned to a pool is: admin:~ # ceph osd pool application get bucket_pool { \"rgw\": {} } admin:~ # ceph osd pool application get rbd_pool { \"rbd\": {} } Task 5: Manage snapshots of the new RGW bucket pool \u00b6 1). Display a list of the snapshots that exist of the bucket_pool that you created in the previous task: The output show that there are \u201c0 snaps.\u201d Right, it is a little funny that you only list the snapshots with rados command; no such functionality exists with the ceph osd pool command. admin:~ # rados -p bucket_pool lssnap 0 snaps 2). Take (make) a snapshot of the rbd_pool: admin:~ # ceph osd pool mksnap bucket_pool brand_new_pool_snapshot created pool bucket_pool snap brand_new_pool_snapshot 3). Display the list of the snapshots again: admin:~ # rados -p bucket_pool lssnap 1 brand_new_pool_snapshot 2021.01.05 22:23:23 1 snaps 4). Remove the snapshot: admin:~ # ceph osd pool rmsnap bucket_pool brand_new_pool_snapshot removed pool bucket_pool snap brand_new_pool_snapshot 5). Display the list of the snapshots again: admin:~ # rados -p bucket_pool lssnap 0 snaps 2.2.4. Maintain consistency of data with Scrub and Repair \u00b6 Scrubbing is like \u201cfsck,\u201d which ensures that OSDs have durable, consistent data. Most of the scrubbing of OSDs happens automatically on a periodic basis. Task 1: Display a few of the Scrub settings \u00b6 1). Show the possible configuration settings related to scrub: If you simply grep for \u201cscrub\u201d you\u2019ll get more than you really want; there are some mon_scrub settings that aren\u2019t related to this exercise. admin:~ # ceph config ls | grep osd_scrub osd_scrub_invalid_stats osd_scrub_during_recovery osd_scrub_begin_hour osd_scrub_end_hour osd_scrub_begin_week_day osd_scrub_end_week_day osd_scrub_load_threshold osd_scrub_min_interval osd_scrub_max_interval osd_scrub_interval_randomize_ratio osd_scrub_backoff_ratio osd_scrub_chunk_min osd_scrub_chunk_max osd_scrub_sleep osd_scrub_auto_repair osd_scrub_auto_repair_num_errors osd_scrub_max_preemptions osd_scrub_priority osd_scrub_cost admin:~ # ceph config ls | grep osd_deep_scrub osd_deep_scrub_interval osd_deep_scrub_randomize_ratio osd_deep_scrub_stride osd_deep_scrub_keys osd_deep_scrub_update_digest_min_age osd_deep_scrub_large_omap_object_key_threshold osd_deep_scrub_large_omap_object_value_sum_threshold admin:~ # ceph config ls | grep scrub mon_warn_pg_not_scrubbed_ratio mon_warn_pg_not_deep_scrubbed_ratio mon_scrub_interval mon_scrub_timeout mon_scrub_max_keys mon_scrub_inject_crc_mismatch mon_scrub_inject_missing_keys osd_op_queue_mclock_scrub_res osd_op_queue_mclock_scrub_wgt osd_op_queue_mclock_scrub_lim osd_scrub_invalid_stats osd_max_scrubs osd_scrub_during_recovery osd_scrub_begin_hour osd_scrub_end_hour osd_scrub_begin_week_day osd_scrub_end_week_day osd_scrub_load_threshold osd_scrub_min_interval osd_scrub_max_interval osd_scrub_interval_randomize_ratio osd_scrub_backoff_ratio osd_scrub_chunk_min osd_scrub_chunk_max osd_scrub_sleep osd_scrub_auto_repair osd_scrub_auto_repair_num_errors osd_scrub_max_preemptions osd_deep_scrub_interval osd_deep_scrub_randomize_ratio osd_deep_scrub_stride osd_deep_scrub_keys osd_deep_scrub_update_digest_min_age osd_deep_scrub_large_omap_object_key_threshold osd_deep_scrub_large_omap_object_value_sum_threshold osd_debug_deep_scrub_sleep osd_scrub_priority osd_scrub_cost osd_requested_scrub_priority mds_max_scrub_ops_in_progress 2). Get the value of a few of the different scrub schedule settings: Note that \u201c0\u201d and \u201c24\u201d are the same setting. admin:~ # ceph config get osd.* osd_scrub_begin_hour 0 admin:~ # ceph config get osd.* osd_scrub_end_hour 24 3). Get the value of the scrub and repair settings: The \u201cauto repair\u201d feature is turned off, and the maximum numbgr of errors that \u201cauto repair\u201d would automatically repair is 5. admin:~ # ceph config get osd.* osd_scrub_auto_repair false admin:~ # ceph config get osd.* osd_scrub_auto_repair_num_errors 5 Task 2: Change the Scrub settings in ceph.conf \u00b6 1). Display the ceph.conf, and verify that the file doesn\u2019t have any settings defined yet that are related to scrub. The settings would be located in the [global] section of the file: # DeepSea default configuration. Changes in this file will be overwritten on # package update. Include custom configuration fragments in # /srv/salt/ceph/configuration/files/ceph.conf.d/[global,osd,mon,mgr,mds,client].conf [global] fsid = 343ee7d3-232f-4c71-8216-1edbc55ac6e0 mon_initial_membgrs = mon1, mon2, mon3 mon_host = 10.58.121.186, 10.58.121.187, 10.58.121.188 auth_cluster_required = cephx auth_service_required = cephx auth_client_required = cephx public_network = 10.58.120.0/23 cluster_network = 10.58.120.0/23 ms_bind_msgr2 = false # enable old ceph health format in the json output. This fixes the # ceph_exporter. This option will only stay until the prometheus plugin takes # over mon_health_preluminous_compat = true mon health preluminous compat warning = false rbd default features = 3 [client.rgw.mon3] rgw frontends = \"beast port=80\" rgw dns name = mon3.sha.me.corp rgw enable usage log = true [osd] [mon] [mgr] [mds] [client] 2). Change to the Salt File Server directory that will have Salt control the master ceph.conf configuration file: admin:~ # cd /srv/salt/ceph/configuration/files/ceph.conf.d/ 3). List the content of the directory: The directory is empty. (Well, there is a README, but no other functional files.) admin:/srv/salt/ceph/configuration/files/ceph.conf.d # ls -l -rw-r--r-- 1 root root 1989 May 14 2020 README 4). Create and edit a new file called global.conf. You don\u2019t have to use vi, but this step uses vi as one way of doing it: Be sure that you spell everything correctly, including the absence of \u201c_\u201d characters; there are spaces. Save the file and exit out of the editor. admin:/srv/salt/ceph/configuration/files/ceph.conf.d # vi global.conf Add the following content to the file: osd scrub begin hour = 23 osd scrub end hour = 5 osd scrub auto repair = True osd scrub auto repair num errors = 10 5). Use DeepSea (Salt) to stage the file properly in Salt\u2019s File Server on the Salt Master (admin): admin:/srv/salt/ceph/configuration/files/ceph.conf.d # salt admin* state.apply ceph.configuration.create admin.sha.me.corp: Name: /var/cache/salt/minion/files/base/ceph/configuration - Function: file.absent - Result: Changed Started: - 22:42:34.900173 Duration: 20.891 ms Name: /srv/salt/ceph/configuration/cache/ceph.conf - Function: file.managed - Result: Changed Started: - 22:42:34.921454 Duration: 8576.516 ms Name: find /var/cache/salt/master/jobs -user root -exec chown salt:salt {} ';' - Function: cmd.run - Result: Changed Started: - 22:42:43.535022 Duration: 71.957 ms Summary for admin.sha.me.corp ------------ Succeeded: 3 (changed=3) Failed: 0 ------------ Total states run: 3 Total run time: 8.669 s 6). Using DeepSea (Salt), distribute the new ceph.conf configuration settings to all the nodes in the cluster: admin:/srv/salt/ceph/configuration/files/ceph.conf.d # salt \\* state.apply ceph.configuration mon3.sha.me.corp: Name: /etc/ceph/ceph.conf - Function: file.managed - Result: Changed Started: - 22:44:07.986661 Duration: 101.977 ms Summary for mon3.sha.me.corp ------------ Succeeded: 1 (changed=1) Failed: 0 ------------ Total states run: 1 Total run time: 101.977 ms mon1.sha.me.corp: Name: /etc/ceph/ceph.conf - Function: file.managed - Result: Changed Started: - 22:44:08.012479 Duration: 108.888 ms Summary for mon1.sha.me.corp ------------ Succeeded: 1 (changed=1) Failed: 0 ------------ Total states run: 1 Total run time: 108.888 ms data3.sha.me.corp: Name: /etc/ceph/ceph.conf - Function: file.managed - Result: Changed Started: - 22:44:08.052247 Duration: 98.681 ms Summary for data3.sha.me.corp ------------ Succeeded: 1 (changed=1) Failed: 0 ------------ Total states run: 1 Total run time: 98.681 ms admin.sha.me.corp: Name: /etc/ceph/ceph.conf - Function: file.managed - Result: Changed Started: - 22:44:08.072402 Duration: 97.231 ms Summary for admin.sha.me.corp ------------ Succeeded: 1 (changed=1) Failed: 0 ------------ Total states run: 1 Total run time: 97.231 ms data1.sha.me.corp: Name: /etc/ceph/ceph.conf - Function: file.managed - Result: Changed Started: - 22:44:08.076279 Duration: 104.169 ms Summary for data1.sha.me.corp ------------ Succeeded: 1 (changed=1) Failed: 0 ------------ Total states run: 1 Total run time: 104.169 ms data4.sha.me.corp: Name: /etc/ceph/ceph.conf - Function: file.managed - Result: Changed Started: - 22:44:08.081635 Duration: 105.13 ms Summary for data4.sha.me.corp ------------ Succeeded: 1 (changed=1) Failed: 0 ------------ Total states run: 1 Total run time: 105.130 ms mon2.sha.me.corp: Name: /etc/ceph/ceph.conf - Function: file.managed - Result: Changed Started: - 22:44:08.155758 Duration: 105.004 ms Summary for mon2.sha.me.corp ------------ Succeeded: 1 (changed=1) Failed: 0 ------------ Total states run: 1 Total run time: 105.004 ms data2.sha.me.corp: Name: /etc/ceph/ceph.conf - Function: file.managed - Result: Changed Started: - 22:44:08.252200 Duration: 109.552 ms Summary for data2.sha.me.corp ------------ Succeeded: 1 (changed=1) Failed: 0 ------------ Total states run: 1 Total run time: 109.552 ms 7). Verify that the new ceph.conf settings have been put into place on the admin node: admin:/srv/salt/ceph/configuration/files/ceph.conf.d # cat /etc/ceph/ceph.conf # DeepSea default configuration. Changes in this file will be overwritten on # package update. Include custom configuration fragments in # /srv/salt/ceph/configuration/files/ceph.conf.d/[global,osd,mon,mgr,mds,client].conf [global] fsid = 343ee7d3-232f-4c71-8216-1edbc55ac6e0 mon_initial_membgrs = mon1, mon2, mon3 mon_host = 10.58.121.188, 10.58.121.187, 10.58.121.186 auth_cluster_required = cephx auth_service_required = cephx auth_client_required = cephx public_network = 10.58.120.0/23 cluster_network = 10.58.120.0/23 ms_bind_msgr2 = false # enable old ceph health format in the json output. This fixes the # ceph_exporter. This option will only stay until the prometheus plugin takes # over mon_health_preluminous_compat = true mon health preluminous compat warning = false rbd default features = 3 osd scrub begin hour = 23 osd scrub end hour = 5 osd scrub auto repair = True osd scrub auto repair num errors = 10 [client.rgw.mon3] rgw frontends = \"beast port=80\" rgw dns name = mon3.sha.me.corp rgw enable usage log = true [osd] [mon] [mgr] [mds] [client] 8). Also verify that other minions in the cluster have also received the updated configuration file, such as on the mon1 and data2 nodes: admin:/srv/salt/ceph/configuration/files/ceph.conf.d # ssh mon1 cat /etc/ceph/ceph.conf # DeepSea default configuration. Changes in this file will be overwritten on # package update. Include custom configuration fragments in # /srv/salt/ceph/configuration/files/ceph.conf.d/[global,osd,mon,mgr,mds,client].conf [global] fsid = 343ee7d3-232f-4c71-8216-1edbc55ac6e0 mon_initial_membgrs = mon1, mon2, mon3 mon_host = 10.58.121.188, 10.58.121.187, 10.58.121.186 auth_cluster_required = cephx auth_service_required = cephx auth_client_required = cephx public_network = 10.58.120.0/23 cluster_network = 10.58.120.0/23 ms_bind_msgr2 = false # enable old ceph health format in the json output. This fixes the # ceph_exporter. This option will only stay until the prometheus plugin takes # over mon_health_preluminous_compat = true mon health preluminous compat warning = false rbd default features = 3 osd scrub begin hour = 23 osd scrub end hour = 5 osd scrub auto repair = True osd scrub auto repair num errors = 10 [client.rgw.mon3] rgw frontends = \"beast port=80\" rgw dns name = mon3.sha.me.corp rgw enable usage log = true [osd] [mon] [mgr] [mds] [client] admin:/srv/salt/ceph/configuration/files/ceph.conf.d # ssh data1 cat /etc/ceph/ceph.conf # DeepSea default configuration. Changes in this file will be overwritten on # package update. Include custom configuration fragments in # /srv/salt/ceph/configuration/files/ceph.conf.d/[global,osd,mon,mgr,mds,client].conf [global] fsid = 343ee7d3-232f-4c71-8216-1edbc55ac6e0 mon_initial_membgrs = mon1, mon2, mon3 mon_host = 10.58.121.188, 10.58.121.187, 10.58.121.186 auth_cluster_required = cephx auth_service_required = cephx auth_client_required = cephx public_network = 10.58.120.0/23 cluster_network = 10.58.120.0/23 ms_bind_msgr2 = false # enable old ceph health format in the json output. This fixes the # ceph_exporter. This option will only stay until the prometheus plugin takes # over mon_health_preluminous_compat = true mon health preluminous compat warning = false rbd default features = 3 osd scrub begin hour = 23 osd scrub end hour = 5 osd scrub auto repair = True osd scrub auto repair num errors = 10 [client.rgw.mon3] rgw frontends = \"beast port=80\" rgw dns name = mon3.sha.me.corp rgw enable usage log = true [osd] [mon] [mgr] [mds] [client] 9). Apply the settings of the ceph.conf file to appropriate nodes in the cluster: admin:/srv/salt/ceph/configuration/files/ceph.conf.d # ceph config assimilate-conf -i /etc/ceph/ceph.conf [global] fsid = 343ee7d3-232f-4c71-8216-1edbc55ac6e0 mon_health_preluminous_compat = true mon_health_preluminous_compat_warning = false mon_host = 10.58.121.188, 10.58.121.187, 10.58.121.186 mon_initial_membgrs = mon1, mon2, mon3 Task 3: Change the Scrub settings directly in the Configuration DB \u00b6 1). Query the configuration database to see the value of \u201cosd_scrub_auto_repair_num_errors\u201d: You changed this value to \u201c10\u201d in the previous Task. admin:~ # ceph config get osd.* osd_scrub_auto_repair_num_errors 10 2). Change the value of \u201cosd_scrub_auto_repair_num_errors\u201d to \u201c8\u201d: admin:~ # ceph config set osd.* osd_scrub_auto_repair_num_errors 8 3). Show that the change has taken immediate effect by re-running the same command that was used in the first step: admin:~ # ceph config get osd.* osd_scrub_auto_repair_num_errors 8 Task 4: Manually scrub and repair an OSD and a PG \u00b6 This won\u2019t do much in this demo environment, because the OSDs aren\u2019t storing very much data. But it\u2019s worth having some practice. 1). Start a scrubbing of one of the OSDs: admin:~ # ceph osd scrub osd.1 instructed osd(s) 1 to scrub 2). Scrub a Placement Group: admin:~ # ceph pg scrub 8.1 instructing pg 8.1 on osd.0 to scrub 3). Repair an OSD: admin:~ # ceph osd repair osd.1 instructed osd(s) 1 to repair 4). Repair a PG: admin:~ # ceph pg repair 8.1 instructing pg 8.1 on osd.0 to repair 5). Show what\u2019s currently happening to the OSD that you instructed to have scrubbed and repaired: admin:~ # ceph osd dump | grep osd.1 max_osd 12 osd.1 up in weight 1 up_from 10 up_thru 1415 down_at 0 last_clean_interval [0,0) v1:10.58.121.185:6800/11157 v1:10.58.121.185:6801/11157 exists,up 32c78078-1878-4fac-9738-00d8bf80deea osd.10 up in weight 1 up_from 18 up_thru 1413 down_at 0 last_clean_interval [0,0) v1:10.58.121.182:6808/11130 v1:10.58.121.182:6809/11130 exists,up 6cb26fdc-09b1-42de-8855-7203931a0101 osd.11 up in weight 1 up_from 18 up_thru 1415 down_at 0 last_clean_interval [0,0) v1:10.58.121.185:6808/11995 v1:10.58.121.185:6809/11995 exists,up cc22107d-0239-4874-8308-6c137c8a0931 6). Show what\u2019s currently happening to the PG that you instructed to have scrubbed and repaired: admin:~ # ceph pg dump | grep \"8\\.1\" dumped all 8.16 0 0 0 0 0 0 0 0 0 0 active+clean 2021-01-05 21:01:16.383909 0'0 1423:27 [6,4,5] 6 [6,4,5] 6 0'0 2021-01-05 20:53:47.314062 0'0 2021-01-05 20:53:47.314062 0 8.17 0 0 0 0 0 0 0 0 0 0 active+clean 2021-01-05 22:57:01.044252 0'0 1424:30 [1,6,8] 1 [1,6,8] 1 0'0 2021-01-05 22:57:01.044098 0'0 2021-01-05 22:57:01.044098 0 8.14 0 0 0 0 0 0 0 0 0 0 active+clean 2021-01-05 22:56:56.081480 0'0 1424:30 [1,2,4] 1 [1,2,4] 1 0'0 2021-01-05 22:56:56.081356 0'0 2021-01-05 22:56:56.081356 0 8.15 0 0 0 0 0 0 0 0 0 0 active+clean 2021-01-05 21:01:16.375386 0'0 1423:27 [3,5,0] 3 [3,5,0] 3 0'0 2021-01-05 20:53:53.231124 0'0 2021-01-05 20:48:05.301705 0 8.12 0 0 0 0 0 0 0 0 0 0 active+clean 2021-01-05 21:01:16.370121 0'0 1423:27 [11,2,8] 11 [11,2,8] 11 0'0 2021-01-05 20:53:48.149449 0'0 2021-01-05 20:48:05.301705 0 2.18 0 0 0 0 0 0 0 0 0 0 active+clean 2021-01-05 16:44:58.986205 0'0 1423:1630 [10,1,8] 10 [10,1,8] 10 0'0 2021-01-05 13:02:00.365382 0'0 2021-01-02 00:38:58.134100 0 8.13 0 0 0 0 0 0 0 0 0 0 active+clean 2021-01-05 21:01:16.387832 0'0 1423:27 [0,8,1] 0 [0,8,1] 0 0'0 2021-01-05 20:53:56.132358 0'0 2021-01-05 20:48:05.301705 0 8.10 0 0 0 0 0 0 0 0 0 0 active+clean 2021-01-05 21:01:16.368416 0'0 1423:27 [11,3,6] 11 [11,3,6] 11 0'0 2021-01-05 20:53:51.152790 0'0 2021-01-05 20:48:05.301705 0 8.11 0 0 0 0 0 0 0 0 0 0 active+clean 2021-01-05 21:01:16.377871 0'0 1423:24 [3,10,5] 3 [3,10,5] 3 0'0 2021-01-05 20:53:45.195257 0'0 2021-01-05 20:48:05.301705 0 8.1e 0 0 0 0 0 0 0 0 0 0 active+clean 2021-01-05 21:01:16.391754 0'0 1423:47 [0,11,8] 0 [0,11,8] 0 0'0 2021-01-05 20:53:55.081582 0'0 2021-01-05 20:48:05.301705 0 8.1 0 0 0 0 0 0 0 0 0 0 active+clean 2021-01-05 22:56:39.829397 0'0 1424:54 [0,7,10] 0 [0,7,10] 0 0'0 2021-01-05 22:56:39.829241 0'0 2021-01-05 22:56:39.829241 0 8.1f 0 0 0 0 0 0 0 0 0 0 active+clean 2021-01-05 21:01:16.392315 0'0 1423:27 [7,5,9] 7 [7,5,9] 7 0'0 2021-01-05 20:53:59.988252 0'0 2021-01-05 20:48:05.301705 0 5.4 0 0 0 0 0 0 0 0 0 0 active+clean 2021-01-05 18:21:28.179266 0'0 1423:1554 [7,9,6] 7 [7,9,6] 7 0'0 2021-01-05 18:21:28.179166 0'0 2021-01-05 18:21:28.179166 0 5.b 0 0 0 0 0 0 0 0 0 0 active+clean 2021-01-05 18:37:01.467457 0'0 1423:1547 [2,0,11] 2 [2,0,11] 2 0'0 2021-01-04 23:46:58.132824 0'0 2021-01-02 03:35:41.214192 0 8.19 0 0 0 0 0 0 0 0 0 0 active+clean 2021-01-05 22:57:06.059090 0'0 1424:30 [1,8,2] 1 [1,8,2] 1 0'0 2021-01-05 22:57:06.058935 0'0 2021-01-05 22:57:06.058935 0 8.18 0 0 0 0 0 0 0 0 0 0 active+clean 2021-01-05 22:57:05.097742 0'0 1424:30 [1,3,6] 1 [1,3,6] 1 0'0 2021-01-05 22:57:05.097670 0'0 2021-01-05 22:57:05.097670 0 1.11 0 0 0 0 0 0 0 0 0 0 active+clean 2021-01-05 00:30:18.193988 0'0 1423:1605 [0,8,6] 0 [0,8,6] 0 0'0 2021-01-05 00:30:18.193868 0'0 2020-12-29 06:30:58.897565 0 8.1b 0 0 0 0 0 0 0 0 0 0 active+clean 2021-01-05 22:57:13.146469 0'0 1424:30 [1,4,6] 1 [1,4,6] 1 0'0 2021-01-05 22:57:13.146390 0'0 2021-01-05 22:57:13.146390 0 8.1a 1 0 0 0 0 19 0 0 2 2 active+clean 2021-01-05 21:01:16.386166 1420'2 1423:29 [9,11,10] 9 [9,11,10] 9 0'0 2021-01-05 20:53:48.690239 0'0 2021-01-05 20:48:05.301705 0 8.1d 0 0 0 0 0 0 0 0 0 0 active+clean 2021-01-05 21:01:16.388079 0'0 1423:56 [0,2,3] 0 [0,2,3] 0 0'0 2021-01-05 20:53:54.121281 0'0 2021-01-05 20:48:05.301705 0 8.1c 0 0 0 0 0 0 0 0 0 0 active+clean 2021-01-05 21:01:16.385846 0'0 1423:27 [2,11,7] 2 [2,11,7] 2 0'0 2021-01-05 20:53:55.458714 0'0 2021-01-05 20:48:05.301705 0 2.2.5. Manipulate Manager Modules \u00b6 Task 1: Display the list of enabled Manager Modules \u00b6 1). Run the following command to show the list of enabled manager modules: Note that several modules are already enabled, such as: dashboard, iostat, pg_autosclater, prometheus, and restful. Even though they are not listed, the crash module and the balancer module are already enabled by default. admin:~ # ceph mgr module ls | head { \"always_on_modules\": [ \"balancer\", \"crash\", \"devicehealth\", \"orchestrator_cli\", \"progress\", \"rbd_support\", \"status\", \"volumes\" 2). Demonstrate that the crash module is enabled by running its command with no arguments: A list of \u201c7 closest matches\u201d is displayed, representing possible additional arguments to be used with the crash command. The crash module is therefore available. admin:~ # ceph crash crash info crash ls crash ls-new crash post crash prune crash rm crash stat crash json_report crash archive crash archive-all admin:~ # ceph crash stat 0 crashes recorded Task 2: Use the iostat module to display statistics for the IO of the cluster The iostat module is really simple, but very helpful. Run the command: admin:~ # ceph iostat +-----------------------------+-----------------------------+-----------------------------+-----------------------------+-----------------------------+-----------------------------+ | Read | Write | Total | Read IOPS | Write IOPS | Total IOPS | +-----------------------------+-----------------------------+-----------------------------+-----------------------------+-----------------------------+-----------------------------+ | 1024 B/s | 0 B/s | 1024 B/s | 1 | 0 | 1 | | 1024 B/s | 0 B/s | 1024 B/s | 1 | 0 | 1 | | 0 B/s | 0 B/s | 0 B/s | 0 | 0 | 0 | Task 3: Enable and configure the telemetry manager module 1). Enable the telemetry manager module: admin:~ # ceph mgr module enable telemetry 2). Show the various sub-commands that are associated with the telemetry command: A list of \u201c5 closest matches\u201d is displayed, showing various options. admin:~ # ceph telemetry telemetry status telemetry send {ceph|device [ceph|device...]} {} telemetry show { [...]} telemetry show-device telemetry on {} telemetry off 3). Show the status of the telemetry module: Notice that the output is returned as key/value pairs. Notice also that although the module has been enabled (which you accomplished in the first step of this task), the functionality is not enabled (enable=false). And for most of the keys, a null value is set. See that the url value is set to https://telemetry.ceph.com/report. That means that crash reports and other usage information about this cluster are going to be sent to the Ceph Community. admin:~ # ceph telemetry status { \"url\": \"https://telemetry.ceph.com/report\", \"device_url\": \"https://telemetry.ceph.com/device\", \"enabled\": false, \"last_opt_revision\": 1, \"leaderboard\": false, \"description\": null, \"contact\": null, \"organization\": null, \"proxy\": null, \"interval\": 24, \"channel_basic\": true, \"channel_ident\": false, \"channel_crash\": true, \"channel_device\": true, \"last_upload\": null } 4). Set the description, contact, and organization values: admin:~ # ceph config set mgr mgr/telemetry/contact 'JD ' admin:~ # ceph config set mgr mgr/telemetry/description 'Training Cluster' admin:~ # ceph config set mgr mgr/telemetry/organization 'SUSE Training' 5). Display the telemetry data that is collected to be sent: admin:~ # ceph telemetry show | less 6). With the contact information properly set, enable the telemetry functionality: This is a demo cluster with no connection to the internet, so no telemetry data will actually be sent. admin:~ # ceph telemetry on Error EPERM: Telemetry data is licensed under the Community Data License Agreement - Sharing - Version 1.0 (https://cdla.io/sharing-1-0/). To enable, add '--license sharing-1-0' to the 'ceph telemetry on' command. admin:~ # ceph telemetry on --license sharing-1-0 7). Disable the telemetry module: admin:~ # ceph mgr module disable telemetry admin:~ # ceph telemetry show | less Error ENOTSUP: Module 'telemetry' is not enabled (required by command 'telemetry show'): use `ceph mgr module enable telemetry` to enable it Task 4: Briefly attempt to use the crash manager module \u00b6 1). Show (again) the various sub-commands that are associated with the crash command: admin:~ # ceph crash crash info crash ls crash ls-new crash post crash prune crash rm crash stat crash json_report crash archive crash archive-all 2). Show the current status of the crash database, including the numbgr of crash reports that have been collected so far: It\u2019s likely that the numbgr of crashes recorded in the demo environment is 0. admin:~ # ceph crash stat 0 crashes recorded 2.2.6. Introduction to the Tell command \u00b6 Tell is a very powerful command within Ceph to control the cluster. You don\u2019t use it everyday, but you need to know how to use it when the occasion to use it arises. It\u2019s mostly an Advanced Command, but exposure to it now reduces the stress of learning about it in a more advanced setting later. Run the tell command in a few different circumstances to control the behavior of various Ceph services. Task 1: Run a benchmark test on an OSD \u00b6 1). Run the following command to run and see the result of a benchmark test on osd.8: admin:~ # ceph tell osd.8 bench { \"bytes_written\": 1073741824, \"blocksize\": 4194304, \"elapsed_sec\": 3.7797023200000002, \"bytes_per_sec\": 284081055.35676152, \"iops\": 67.730201567831401 } Task 2: Change the protection setting regarding the deletion of pools \u00b6 1). The default behavior in Ceph is that you can\u2019t delete pools. Try to delete a pool: The output says that you have to be VERY careful and provide more arguments in order to delete a pool admin:~ # ceph osd pool delete rbd_pool Error EPERM: WARNING: this will *PERMANENTLY DESTROY* all data stored in pool rbd_pool. If you are *ABSOLUTELY CERTAIN* that is what you want, pass the pool name *twice*, followed by --yes-i-really-really-mean-it. 2). Try deleting the pool again, this time with the extra arguments: Ceph still won\u2019t let you do it because the mon allow pool delete setting has the value of false. admin:~ # ceph osd pool delete rbd_pool rbd_pool --yes-i-really-really-mean-it Error EPERM: pool deletion is disabled; you must first set the mon_allow_pool_delete config option to true before you can destroy a pool 3). Show that the mon allow pool delete setting has the value of false: Indeed, the output shows that the value is false. admin:~ # ceph config get mon.mon\\* mon_allow_pool_delete false 4). Change to value of the setting using injectargs: Note that the \u201c-\u201d and \u201c_\u201d characters can be confusing. And note that the setting is preceded with the double \u201c--\u201d. The injected args must be enclosed in single quotes. You could have done this with ceph config set, but this is an alternative way to directly \u201ctell\u201d the cluster to change a setting. admin:~ # ceph tell mon.\\* injectargs '--mon-allow-pool-delete=true' mon.mon1: injectargs:mon_allow_pool_delete = 'true' mon.mon2: injectargs:mon_allow_pool_delete = 'true' mon.mon3: injectargs:mon_allow_pool_delete = 'true' 2.3. Ceph Dashboard \u00b6 2.3.1. Access Dashboard \u00b6 Task 1: Set the password for the admin user of the Ceph Dashboard \u00b6 1). In a Bash terminal as the root user, show that the Dashboard module is enabled: \u201cdashboard\u201d should be included in the list of \u201cenabled_modules\u201d at the top of the output. admin:~ # ceph mgr module ls | more \"enabled_modules\": [ \"dashboard\", \"iostat\", \"pg_autoscaler\", \"prometheus\", \"restful\" ], 2). Show the valid dashboard users that have already been created by DeepSea during initial deployment: It\u2019s possible that other users will be listed, but at least the \u201cadmin\u201d user should be displayed in the output. admin:~ # ceph dashboard ac-user-show [\"admin\"] 3). Show the \u201cadmin\u201d user\u2019s information as stored in the user database: You can see that the admin user has a password set, but it is stored as a hash. So you don\u2019t really know what the password is, and have no way of discovering it. admin:~ # ceph dashboard ac-user-show admin {\"username\": \"admin\", \"password\": , \"roles\": [\"administrator\"], \"name\": null, \"email\": null, \"lastUpdate\": 1601874928} 4). Change the \u201cadmin\u201d user\u2019s password for the dashboard: This sets the \u201cadmin\u201d user\u2019s password to the string: mypassword admin:~ # ceph dashboard ac-user-set-password admin mypassword {\"username\": \"admin\", \"password\": , \"roles\": [\"administrator\"], \"name\": null, \"email\": null, \"lastUpdate\": 1609860842} admin:~ # Task 3: Visit the Ceph Dashboard URL \u00b6 admin:~ # salt-call grains.get dashboard_creds local: ---------- admin: admin:~ # ceph mgr services { \"dashboard\": \"https://mon1.sha.me.corp:8443/\", \"prometheus\": \"http://mon1.sha.me.corp:9283/\" } admin:~ # ceph -s cluster: id: 343ee7d3-232f-4c71-8216-1edbc55ac6e0 health: HEALTH_WARN 1 subtrees have overcommitted pool target_size_bytes services: mon: 3 daemons, quorum mon1,mon2,mon3 (age 9w) mgr: mon1(active, since 25m) mds: cephfs:1 {0=mon3=up:active} 2 up:standby osd: 12 osds: 12 up (since 5h), 12 in (since 3M) rgw: 1 daemon active (mon3) task status: scrub status: mds.mon3: idle data: pools: 9 pools, 244 pgs objects: 247 objects, 5.7 KiB usage: 14 GiB used, 82 GiB / 96 GiB avail pgs: 244 active+clean io: client: 1.2 KiB/s rd, 1 op/s rd, 0 op/s wr URL: https://mon1.sha.me.corp:8443/ https://10.58.121.186:8443 2.3.2. Explore the Dashboard Health, Performance, Status \u00b6 Dashboard Status Cluster Status Monitors OSDs Manager Daemons Hosts Object Gateway Metadata Service iSCSI Gateway Performance Client IOPS Client Throughput Client Read/Write Recovery Throughput Scrub Capacity Pools Raw Capacity Objects PGs per OSD PG Status [SUSE Enterprise Storage Portal Cluster\u2192Configuration Cluster\u2192Manager Modules Pools\u2192Create Pool 2.4. Storage Data Access \u00b6 2.4.1. Ensure the SES Cluster is Healthy \u00b6 Task 1: Check the Cluster\u2019s health \u00b6 1). Run the following command to check the status (health) of the SES cluster: admin:~ # ceph -s cluster: id: 343ee7d3-232f-4c71-8216-1edbc55ac6e0 health: HEALTH_WARN 1 subtrees have overcommitted pool target_size_bytes 1 pools have too few placement groups services: mon: 3 daemons, quorum mon1,mon2,mon3 (age 9w) mgr: mon1(active, since 18h) mds: cephfs:1 {0=mon3=up:active} 2 up:standby osd: 12 osds: 12 up (since 23h), 12 in (since 3M) rgw: 1 daemon active (mon3) task status: scrub status: mds.mon3: idle data: pools: 10 pools, 248 pgs objects: 247 objects, 5.7 KiB usage: 14 GiB used, 82 GiB / 96 GiB avail pgs: 248 active+clean io: client: 1.2 KiB/s rd, 1 op/s rd, 0 op/s wr 2). Evaluate the output. The cluster in this demonstration environment often doesn\u2019t startup correctly due to the nature of a demo environment and it\u2019s less-predictable resources. Depending on whether any of the following tasks are necessary, followup accordingly to ensure that the cluster is healthy before proceeding with the course lectures or any further exercises. 3). Run the following series of commands to restart the Monitor daemons on each of the Monitor nodes: It\u2019s certainly not necessary to restart the monitor daemons on all of the monitor nodes if only one is down. If you prefer, you can take a different approach to starting the daemon on a single monitor node. admin:~ # for h in mon1 mon2 mon3; \\ do \\ ssh $h systemctl restart ceph-mon@$h; \\ done 4). After waiting a few moments for the daemons to restart, check the status again: admin:~ # ceph -s cluster: id: 343ee7d3-232f-4c71-8216-1edbc55ac6e0 health: HEALTH_WARN 1 subtrees have overcommitted pool target_size_bytes 1 pools have too few placement groups services: mon: 3 daemons, quorum mon1,mon2,mon3 (age 15s) mgr: mon1(active, since 21h) mds: cephfs:1 {0=mon3=up:active} 2 up:standby osd: 12 osds: 12 up (since 26h), 12 in (since 3M) rgw: 1 daemon active (mon3) task status: scrub status: mds.mon3: idle data: pools: 10 pools, 248 pgs objects: 247 objects, 5.7 KiB usage: 14 GiB used, 82 GiB / 96 GiB avail pgs: 248 active+clean io: client: 767 B/s rd, 0 op/s rd, 0 op/s wr 5). Run the following series of commands to restart the Manager daemons on each of the Monitor nodes: admin:~ # for h in mon1 mon2 mon3; \\ do \\ ssh $h systemctl restart ceph-mgr@$h; \\ done 6). After waiting a few moments for the daemons to restart, check the status again: admin:~ # ceph -s cluster: id: 343ee7d3-232f-4c71-8216-1edbc55ac6e0 health: HEALTH_OK services: mon: 3 daemons, quorum mon1,mon2,mon3 (age 8m) mgr: mon1(active, since 18s) mds: cephfs:1 {0=mon3=up:active} 2 up:standby osd: 12 osds: 12 up (since 26h), 12 in (since 3M) rgw: 1 daemon active (mon3) task status: scrub status: mds.mon3: idle data: pools: 10 pools, 248 pgs objects: 247 objects, 6.1 KiB usage: 14 GiB used, 82 GiB / 96 GiB avail pgs: 248 active+clean io: client: 852 B/s rd, 0 op/s rd, 0 op/s wr 7). Run the following command to restart the MDS daemon on the MDS node (mon1): admin:~ # ssh mon1 systemctl restart ceph-mds@mon1.service 8). After waiting a few moments for the mds daemon to restart, check the status again: Look for the mds service to be plain active rather than laggy or crashed admin:~ # ceph -s cluster: id: 343ee7d3-232f-4c71-8216-1edbc55ac6e0 health: HEALTH_WARN 1 subtrees have overcommitted pool target_size_bytes 1 pools have too few placement groups services: mon: 3 daemons, quorum mon1,mon2,mon3 (age 17m) mgr: mon1(active, since 8m) mds: cephfs:1 {0=mon3=up:active} 2 up:standby osd: 12 osds: 12 up (since 26h), 12 in (since 3M) rgw: 1 daemon active (mon3) task status: scrub status: mds.mon3: idle data: pools: 10 pools, 248 pgs objects: 247 objects, 6.2 KiB usage: 14 GiB used, 82 GiB / 96 GiB avail pgs: 248 active+clean io: client: 852 B/s rd, 0 op/s rd, 0 op/s wr 9). Verify if the OSDs \u201cup\u201d and running properly. It is only necessary if the output of ceph -s shows that there are fewer than 9 OSDs shown as being \u201cup\u201d. It\u2019s most likely that a storage node is simply not quite fully booted yet, such that the OSD daemons haven\u2019t fully come up. But if you suspect that the solution requires something different than simply waiting a little longer, you should try the following steps. First, identify which server is hosting the down\u2019d OSDs. One way of doing that is with this command: admin:~ # ceph osd tree ID CLASS WEIGHT TYPE NAME STATUS REWEIGHT PRI-AFF -1 0.09357 root default -9 0.02339 host data1 2 hdd 0.00780 osd.2 up 1.00000 1.00000 6 hdd 0.00780 osd.6 up 1.00000 1.00000 10 hdd 0.00780 osd.10 up 1.00000 1.00000 -3 0.02339 host data2 0 hdd 0.00780 osd.0 up 1.00000 1.00000 4 hdd 0.00780 osd.4 up 1.00000 1.00000 9 hdd 0.00780 osd.9 up 1.00000 1.00000 -7 0.02339 host data3 3 hdd 0.00780 osd.3 up 1.00000 1.00000 7 hdd 0.00780 osd.7 up 1.00000 1.00000 8 hdd 0.00780 osd.8 up 1.00000 1.00000 -5 0.02339 host data4 1 hdd 0.00780 osd.1 up 1.00000 1.00000 5 hdd 0.00780 osd.5 up 1.00000 1.00000 11 hdd 0.00780 osd.11 up 1.00000 1.00000 Simply try restarting the storage daemon processes on the affected host, such as with this example: admin:~ # ssh data2 systemctl restart ceph-osd@9.service admin:~ # ceph -s cluster: id: 343ee7d3-232f-4c71-8216-1edbc55ac6e0 health: HEALTH_WARN 1 subtrees have overcommitted pool target_size_bytes 1 pools have too few placement groups services: mon: 3 daemons, quorum mon1,mon2,mon3 (age 32m) mgr: mon1(active, since 24m) mds: cephfs:1 {0=mon3=up:active} 2 up:standby osd: 12 osds: 12 up (since 27s), 12 in (since 3M) rgw: 1 daemon active (mon3) task status: scrub status: mds.mon3: idle data: pools: 10 pools, 248 pgs objects: 247 objects, 6.2 KiB usage: 14 GiB used, 82 GiB / 96 GiB avail pgs: 248 active+clean io: client: 852 B/s rd, 0 op/s rd, 0 op/s wr If the OSD daemon processes are being stubborn and uncooperative, you may choose to reboot the storage virtual machine entirely. This is one way to do that: admin:~ # ssh data1 systemctl reboot After waiting some time for the daemons to get started, verify that all the OSDs are \u201cup\u201d and that the cluster is healthy: admin:~ # ceph osd tree admin:~ # ceph status 10). Run the following command to restart the RADOS Gateway daemon on the node that is hosting the gateway (mon3): admin:~ # ssh mon3 systemctl restart ceph-radosgw@rgw.mon3.service admin:~ # ssh mon3 systemctl status ceph-radosgw@rgw.mon3.service \u25cf ceph-radosgw@rgw.mon3.service - Ceph rados gateway Loaded: loaded (/usr/lib/systemd/system/ceph-radosgw@.service; enabled; vendor preset: disabled) Active: active (running) since Wed 2021-01-06 21:37:53 CST; 23s ago Main PID: 781880 (radosgw) Tasks: 588 CGroup: /system.slice/system-ceph\\x2dradosgw.slice/ceph-radosgw@rgw.mon3.service \u2514\u2500781880 /usr/bin/radosgw -f --cluster ceph --name client.rgw.mon3 --setuser ceph --setgroup ceph Jan 06 21:37:53 mon3 systemd[1]: Started Ceph rados gateway. 11). After waiting a few moments for the daemon to restart, check the status again: admin:~ # ceph -s cluster: id: 343ee7d3-232f-4c71-8216-1edbc55ac6e0 health: HEALTH_WARN 1 subtrees have overcommitted pool target_size_bytes 1 pools have too few placement groups services: mon: 3 daemons, quorum mon1,mon2,mon3 (age 39m) mgr: mon1(active, since 30m) mds: cephfs:1 {0=mon3=up:active} 2 up:standby osd: 12 osds: 12 up (since 6m), 12 in (since 3M) rgw: 1 daemon active (mon3) task status: scrub status: mds.mon3: idle data: pools: 10 pools, 248 pgs objects: 247 objects, 6.2 KiB usage: 14 GiB used, 82 GiB / 96 GiB avail pgs: 248 active+clean io: client: 1.2 KiB/s rd, 1 op/s rd, 0 op/s wr 2.4.2. Use the S3 API to Interact with the RADOS Gateway \u00b6 In this lab we used the s3cmd and radosgw-admin utilities to interact with the SUSE Enterprise Storage cluster. We created a new user, a new bucket, and a new file. We then uploaded the file to the cluster and verified that the object gateway stored it to the cluster. Task 1: Using the s3cmd tool and create an S3 user \u00b6 1). As the root user (password is linux) in a shell or terminal, verify that the s3cmd is available on the admin node: You will likely see an error about configuration files missing, etc. This is enough information to validate the utility is installed. admin:~ # pip --version pip 10.0.1 from /usr/lib/python3.6/site-packages/pip (python 3.6) admin:~ # pip install s3cmd Collecting s3cmd Downloading https://files.pythonhosted.org/packages/26/44/19e08f69b2169003f7307565f19449d997895251c6a6566ce21d5d636435/s3cmd-2.1.0-py2.py3-none-any.whl (145kB) 100% | 153kB 2.7MB/s Collecting python-magic (from s3cmd) Downloading https://files.pythonhosted.org/packages/59/77/c76dc35249df428ce2c38a3196e2b2e8f9d2f847a8ca1d4d7a3973c28601/python_magic-0.4.18-py2.py3-none-any.whl Requirement already satisfied: python-dateutil in /usr/lib/python3.6/site-packages (from s3cmd) (2.7.3) Requirement already satisfied: six>=1.5 in /usr/lib/python3.6/site-packages (from python-dateutil->s3cmd) (1.11.0) Installing collected packages: python-magic, s3cmd Successfully installed python-magic-0.4.18 s3cmd-2.1.0 2). Create a new S3 user to be used: The output will include an access_key value and a secret_key value. You will need both of those values in later steps. admin:~ # radosgw-admin user create --uid=s3user --display-name=S3 User --email=s3user@example.net { \"user_id\": \"s3user\", \"display_name\": \"S3\", \"email\": \"s3user@example.net\", \"suspended\": 0, \"max_buckets\": 1000, \"subusers\": [], \"keys\": [ { \"user\": \"s3user\", \"access_key\": , \"secret_key\": } ], \"swift_keys\": [], \"caps\": [], \"op_mask\": \"read, write, delete\", \"default_placement\": \"\", \"default_storage_class\": \"\", \"placement_tags\": [], \"bucket_quota\": { \"enabled\": false, \"check_on_raw\": false, \"max_size\": -1, \"max_size_kb\": 0, \"max_objects\": -1 }, \"user_quota\": { \"enabled\": false, \"check_on_raw\": false, \"max_size\": -1, \"max_size_kb\": 0, \"max_objects\": -1 }, \"temp_url_keys\": [], \"type\": \"rgw\", \"mfa_ids\": [] } Retrieve above information admin:~ # radosgw-admin user info --uid=s3user Task 2: Create a new s3cmd configuration file and a new S3 bucket \u00b6 1). Generate a new s3cmd configuration file from a shell on the admin node: Fill in as listed below: admin:~ # cd ~ admin:~ # s3cmd --configure Enter new values or accept defaults in brackets with Enter. Refer to user manual for detailed description of all options. Access key and Secret key are your identifiers for Amazon S3. Leave them empty for using the env variables. Access Key: Secret Key: Default Region [US]: Use \"s3.amazonaws.com\" for S3 Endpoint and not modify it to the target Amazon S3. S3 Endpoint [s3.amazonaws.com]: mon3.sha.me.corp Use \"%(bucket)s.s3.amazonaws.com\" to the target Amazon S3. \"%(bucket)s\" and \"%(location)s\" vars can be used if the target S3 system supports dns based buckets. DNS-style bucket+hostname:port template for accessing a bucket [%(bucket)s.s3.amazonaws.com]: %(bucket)s.mon3.sha.me.corp Encryption password is used to protect your files from reading by unauthorized persons while in transfer to S3 Encryption password: Path to GPG program [/usr/bin/gpg]: When using secure HTTPS protocol all communication with Amazon S3 servers is protected from 3 rd party eavesdropping. This method is slower than plain HTTP, and can only be proxied with Python 2.7 or newer Use HTTPS protocol [Yes]: No On some networks all internet access must go through a HTTP proxy. Try setting it here if you can't connect to S3 directly HTTP Proxy server name: New settings: Access Key: Secret Key: Default Region: US S3 Endpoint: mon3.sha.me.corp DNS-style bucket+hostname:port template for accessing a bucket: %(bucket)s.mon3.sha.me.corp Encryption password: Path to GPG program: /usr/bin/gpg Use HTTPS protocol: False HTTP Proxy server name: HTTP Proxy server port: 0 Test access with supplied credentials? [Y/n] n Save settings? [y/N] y Configuration saved to '/root/.s3cfg' 2). Test the configuration by checking for existing files or directories: Since no buckets or files have been made available for the user, no items are listed and the command returns you to the prompt with no output. This is normal. If there is an error, your configuration may have a typo in it. The configuration file will have been saved as .s3cfg. Edit the file to match the configuration in step one. admin:~ # s3cmd ls 3). Create a new bucket for uploading files to using the s3cmd: You should see feedback that the bucket has been created. Although not technically required by the S3 API, the bucket name needs to be in all uppercase to avoid a bug with the s3cmd tool itself. admin:~ # s3cmd mb s3://S3CMDTEST Bucket 's3://S3CMDTEST/' created admin:~ # s3cmd ls 2021-01-06 14:04 s3://S3CMDTEST (it's GMT timezone) Task3: Create and upload a file to a bucket using the S3 API \u00b6 1). Create a file with a few words of text: admin:~ # echo \"The mountains are beautiful\" > newfile 2). Put the new file into your bucket using s3cmd: You should see the file being uploaded. admin:~ # s3cmd put newfile s3://S3CMDTEST upload: 'newfile' -> 's3://S3CMDTEST/newfile' [1 of 1] 28 of 28 100% in 3s 7.66 B/s done 3). Verify the file is now in your bucket, safely stored in you SES cluster: admin:~ # s3cmd ls s3://S3CMDTEST 2021-01-06 14:11 28 s3://S3CMDTEST/newfile 2.4.3. Use the swift API to Interact with the RADOS Gateway \u00b6 OpenStack packages for SUSE Install and configure the storage nodes for openSUSE and SUSE Linux Enterprise SUSE Package Hub: python-PasteDeploy Enable SUSE Package Hub extension admin:~ # SUSEConnect -p PackageHub/15.1/x86_64 Install python3-PasteDeploy, which is dependency of python-swift installation admin:~ # zypper in python3-PasteDeploy admin:~ # rpm -ivh python3-PyECLib-1.6.0-1.6.x86_64.rpm warning: python3-PyECLib-1.6.0-1.6.x86_64.rpm: Header V3 RSA/SHA256 Signature, key ID 3dbdc284: NOKEY error: Failed dependencies: python(abi) = 3.8 is needed by python3-PyECLib-1.6.0-1.6.x86_64 rpmlib(PayloadIsZstd) <= 5.4.18-1 is needed by python3-PyECLib-1.6.0-1.6.x86_64 Add OpenStack Swift Repository for SUSE admin:~ # zypper addrepo -f obs://Cloud:OpenStack:Train/SLE_15_SP1 Train admin:~ # zypper in openstack-swift openstack-swift-account openstack-swift-container openstack-swift-object Task 1: Create a swift subuser \u00b6 1). In a shell or terminal as the root user (password of linux) on the admin node, create a new subuser: The output will contain the access and secret keys for the s3user and a secret key for the new swift subuser.. admin:~ # radosgw-admin subuser create --uid=s3user --subuser=s3user:swift --access=full { \"user_id\": \"s3user\", \"display_name\": \"S3\", \"email\": \"s3user@example.net\", \"suspended\": 0, \"max_buckets\": 1000, \"subusers\": [ { \"id\": \"s3user:swift\", \"permissions\": \"full-control\" } ], \"keys\": [ { \"user\": \"s3user\", \"access_key\": , \"secret_key\": } ], \"swift_keys\": [ { \"user\": \"s3user:swift\", \"secret_key\": } ], \"caps\": [], \"op_mask\": \"read, write, delete\", \"default_placement\": \"\", \"default_storage_class\": \"\", \"placement_tags\": [], \"bucket_quota\": { \"enabled\": false, \"check_on_raw\": false, \"max_size\": -1, \"max_size_kb\": 0, \"max_objects\": -1 }, \"user_quota\": { \"enabled\": false, \"check_on_raw\": false, \"max_size\": -1, \"max_size_kb\": 0, \"max_objects\": -1 }, \"temp_url_keys\": [], \"type\": \"rgw\", \"mfa_ids\": [] } 2). Verify that the subuser has access to at least one bucket and list the buckets with a swift command: swift -A http://mon3.sha.me.corp/auth/1.0 -U s3user:swift -K '{SECRET_KEY_FROM_STEP_1}' list admin:~ # swift -A http://mon3.sha.me.corp/auth/1.0 -U s3user:swift -K '' list S3CMDTEST Task 2: Use the swift command to access a file created with the S3cmd tool \u00b6 1). Since the S3 API and the swift API are accessing the same SUSE Enterprise Storage cluster, and since the RADOS gateway is built to be inter-operable with both, you can use the swift API to retrieve the object which was uploaded to SES via the S3 API: swift -A http://mon3.example.net/auth/1.0 -U s3user:swift -K '{SECRET_KEY_FROM_STEP_1}' download -a An example of the command is listed here: admin:~ # swift -A http://mon3.sha.me.corp/auth/1.0 -U s3user:swift -K '' download -a Although we have taken a shortcut by using the -a option (meaning grab every object this user has access to), it illustrates the tool\u2019s capability. We\u2019ve uploaded the newfile with S3, we\u2019ve retrieved it with swift. 2.4.4. Create Snapshots on SES using RBD \u00b6 In this lab we worked with rbd images. We mapped an rbd image to a Linux device file, then created a filesystem and mounted it. Then we created snapshots to preserve the images data state at a particular time, and rolled it back to demonstrate functionality. Task 1: Create a new pool for RBD images \u00b6 1). Access https://mon1.pvg.me.corp:8443 or https://10.58.121.186:8443 2). Log in with the following credentials: Username: admin Password: mypassword 3). Click on the Pools tab near the top of the page 4). Click the Create button and use the following in the available fields: Name: rbd-images Pool type: replicated Placement groups: 16 Crush ruleset: replicated_rule Replicted size: 2 Applications: rbd Compression Mode: none 5). Click Create Pool Task 2: Create a new RBD image in the rbd-images pool \u00b6 6). Create a new RBD image using the rbd command: admin:~ # rbd create --size 1024 rbd-images/barfoo 7). Verify the new image has been created in the rbd-images pool: The new image named barfoo should be displayed. admin:~ # rbd ls -p rbd-images barfoo Task 3: Mount the new image on the admin node and create a filesystem \u00b6 1). As the root user in a shell or terminal on the admin node, map the new rbd image to a block device: admin:~ # rbd map rbd-images/barfoo /dev/rbd0 2). Create a filesystem on the newly mapped device: admin:~ # mkfs.ext4 /dev/rbd0 mke2fs 1.43.8 (1-Jan-2018) Discarding device blocks: done Creating filesystem with 262144 4k blocks and 65536 inodes Filesystem UUID: 19da6b86-1989-4834-a365-2f654fcce6f6 Superblock backups stored on blocks: 32768, 98304, 163840, 229376 Allocating group tables: done Writing inode tables: done Creating journal (8192 blocks): done Writing superblocks and filesystem accounting information: done 3). Mount the image to the /mnt directory: admin:~ # mount /dev/rbd0 /mnt admin:~ # l /mnt total 20 drwxr-xr-x 3 root root 4096 Jan 6 23:48 ./ drwxr-xr-x 1 root root 156 Oct 5 08:53 ../ drwx------ 2 root root 16384 Jan 6 23:48 lost+found/ Task 4: Create a file on the new filesystem and snapshot the rbd image and make some additional changes \u00b6 1). Change to the /mnt directory and create a simple file: admin:~ # cd /mnt admin:/mnt # echo \"This is some sample text\" > start.txt 2). List the directories contents to see that the start.txt file has been created on the storage cluster. admin:/mnt # ls -l total 20 drwx------ 2 root root 16384 Jan 6 23:48 lost+found -rw-r--r-- 1 root root 25 Jan 6 23:50 start.txt 3). Create a snapshot of what the rbd image contained: Wait for confirmation that the snapshot has been created. It should only take a few seconds. admin:/mnt # rbd snap create rbd-images/barfoo@begin 4). List the rbd snapshots for the rbd-images/barfoo image: You should see the new snap called begin listed. admin:/mnt # rbd snap ls rbd-images/barfoo SNAPID NAME SIZE PROTECTED TIMESTAMP 4 begin 1 GiB Wed Jan 6 23:51:12 2021 5). Add another file to the filesystem: admin:/mnt # echo \"Some more text\" > end.txt 6). List the contents of the /mnt to verify the existence of two files. admin:/mnt # ls -l total 24 -rw-r--r-- 1 root root 15 Jan 6 23:52 end.txt drwx------ 2 root root 16384 Jan 6 23:48 lost+found -rw-r--r-- 1 root root 25 Jan 6 23:50 start.txt 7). Create a second snapshot of the rbd-images/barfoo image: admin:/mnt # rbd snap create rbd-images/barfoo@finish 8). List the rbd snapshots: There should be begin and finish snapshots. admin:/mnt # rbd snap ls rbd-images/barfoo SNAPID NAME SIZE PROTECTED TIMESTAMP 4 begin 1 GiB Wed Jan 6 23:51:12 2021 5 finish 1 GiB Wed Jan 6 23:53:15 2021 9). List the contents of the /mnt directory again and verify the two files. 10). Rollback the data to the begin snapshot: This process will be relatively quick because the size of the image is small and we have very little data on it. admin:/mnt # rbd snap rollback rbd-images/barfoo@begin Rolling back to snapshot: 100% complete...done. 11). Change to the root user\u2019s home directory, then remount the image in order to see that the rbd image has been rolled back: admin:/mnt # cd ~ admin:~ # umount /mnt admin:~ # mount /dev/rbd0 /mnt 12). List the contents of the /mnt directory to verify that only the start.txt file exists on the image. admin:/mnt # ls -l total 20 drwx------ 2 root root 16384 Jan 6 23:48 lost+found -rw-r--r-- 1 root root 25 Jan 6 23:50 start.txt 13). Rollback the data to the finish snapshot: admin:/mnt # rbd snap rollback rbd-images/barfoo@finish Rolling back to snapshot: 100% complete...done. 14). Unmount and remount the image: admin:/mnt # cd ~ admin:~ # umount /mnt admin:~ # mount /dev/rbd0 /mnt 15). List the contents of the /mnt directory to show it has indeed been rolled back and contains the start.txt and end.txt files admin:/mnt # ls -l total 24 -rw-r--r-- 1 root root 15 Jan 6 23:52 end.txt drwx------ 2 root root 16384 Jan 6 23:48 lost+found -rw-r--r-- 1 root root 25 Jan 6 23:50 start.txt 16). Change to the root user\u2019s home directory and unmount the image: admin:/mnt # cd ~ admin:~ # umount /mnt 2.4.5. Create and manage COW Clones with rbd \u00b6 In this lab you will created a new pool and block device image in the pool. You then mapped the block storage to a linux device and took a snapshot. Finally you protected the snapshot from modification. This would be done so the snapshot can be safely used as a parent cow image which can then be cloned to create new virtual machines. Task 1: Create a new pool \u00b6 1). View the current osds and pools: admin:~ # ceph osd ls 0 1 2 3 4 5 6 7 8 9 10 11 admin:~ # ceph osd pool ls iscsi-images cephfs_data cephfs_metadata .rgw.root default.rgw.control default.rgw.meta default.rgw.log rbd_pool bucket_pool EC_RBD_Pool default.rgw.buckets.index default.rgw.buckets.data rbd-images 2). Create a new pool called cow-pool: admin:~ # ceph osd pool create cow-pool 128 pool 'cow-pool' created 3). List the available pools to view the new pool using either of the following commands: admin:~ # ceph osd pool ls iscsi-images cephfs_data cephfs_metadata .rgw.root default.rgw.control default.rgw.meta default.rgw.log rbd_pool bucket_pool EC_RBD_Pool default.rgw.buckets.index default.rgw.buckets.data rbd-images cow-pool admin:~ # rados lspools iscsi-images cephfs_data cephfs_metadata .rgw.root default.rgw.control default.rgw.meta default.rgw.log rbd_pool bucket_pool EC_RBD_Pool default.rgw.buckets.index default.rgw.buckets.data rbd-images cow-pool Task 2: Create a block device image in a pool 1). Create a format 2 rbd image called cow-base in the cow-pool storage pool with a size of 1GB *Note that the \u2013image-format statement is optional as format 2 is default admin:~ # rbd create -p cow-pool cow-base --size 1024 --image-format 2 2). Check that the image has been created, that the format is 2 and that layering (COW Clones) is supported admin:~ # rbd -p cow-pool list cow-base admin:~ # rbd -p cow-pool info cow-base rbd image 'cow-base': size 1 GiB in 256 objects order 22 (4 MiB objects) snapshot_count: 0 id: 269d5b817222aa block_name_prefix: rbd_data.269d5b817222aa format: 2 features: layering op_features: flags: create_timestamp: Thu Jan 7 10:12:31 2021 access_timestamp: Thu Jan 7 10:12:31 2021 modify_timestamp: Thu Jan 7 10:12:31 2021 Task 3: Map the block storage image to a Linux host 1). In a shell or terminal as user root open a terminal window. Using the rbd map command, map an rbd device to the block-storage image created above. admin:~ # rbd map -p cow-pool --image cow-base /dev/rbd1 2). View the mapped block devices admin:~ # rbd showmapped id pool namespace image snap device 0 rbd-images barfoo - /dev/rbd0 1 cow-pool cow-base - /dev/rbd1 3). Note the rbd index numbgr (e.g. rbd0, rbd1) associated with the cow-base image: RBD ___1____ 4). View the devices in /dev. Note the device name(s) admin:~ # ls -l /dev/rbd* brw-rw---- 1 root disk 252, 0 Jan 6 23:49 /dev/rbd0 brw-rw---- 1 root disk 252, 16 Jan 7 10:14 /dev/rbd1 /dev/rbd: total 0 drwxr-xr-x 2 root root 60 Jan 7 10:14 cow-pool drwxr-xr-x 2 root root 60 Jan 6 23:48 rbd-images 5). View the block device:(use the device numbgr from step above) admin:~ # fdisk -l /dev/rbd1 Disk /dev/rbd1: 1 GiB, 1073741824 bytes, 2097152 sectors Units: sectors of 1 * 512 = 512 bytes Sector size (logical/physical): 512 bytes / 512 bytes I/O size (minimum/optimal): 4194304 bytes / 4194304 bytes 6). Format the device with an ext4 filesystem: admin:~ # mkfs.ext4 /dev/rbd1 mke2fs 1.43.8 (1-Jan-2018) Discarding device blocks: done Creating filesystem with 262144 4k blocks and 65536 inodes Filesystem UUID: 64c9a973-cf31-4239-881f-ec5642bf34e3 Superblock backups stored on blocks: 32768, 98304, 163840, 229376 Allocating group tables: done Writing inode tables: done Creating journal (8192 blocks): done Writing superblocks and filesystem accounting information: done 7). Mount the block device on the local filesystem: admin:~ # mkdir /mnt/cow-base admin:~ # mount /dev/rbd1 /mnt/cow-base 8). Test the storage access by creating a file: admin:~ # cd /mnt/cow-base admin:/mnt/cow-base # touch base-image-file admin:/mnt/cow-base # ls base-image-file lost+found Task 4: Snapshot the rbd image and protect the snapshot \u00b6 1). List the snapshots in the cow-base image: admin:/mnt/cow-base # rbd snap ls cow-pool/cow-base 2). Create a snapshot of the cow-base rbd image which contains the base-image-file file admin:/mnt/cow-base # rbd snap create cow-pool/cow-base@base-snap 3). List the snapshot: admin:/mnt/cow-base # rbd snap ls cow-pool/cow-base SNAPID NAME SIZE PROTECTED TIMESTAMP 4 base-snap 1 GiB Thu Jan 7 10:37:13 2021 4). This snapshot will form the parent snapshot for COW clone images so you will now protected it from modification: admin:/mnt/cow-base # rbd snap protect cow-pool/cow-base@base-snap admin:/mnt/cow-base # rbd snap ls cow-pool/cow-base SNAPID NAME SIZE PROTECTED TIMESTAMP 4 base-snap 1 GiB yes Thu Jan 7 10:37:13 2021 Task 5: Create writable COW clones from the parent snapshot 1). Create a COW clone from the cow-base with the base-snap snapshot as the parent image admin:/mnt/cow-base # rbd clone cow-pool/cow-base@base-snap cow-pool/cow-image1 2). Check the information for the new image admin:/mnt/cow-base # rbd -p cow-pool --image cow-image1 info rbd image 'cow-image1': size 1 GiB in 256 objects order 22 (4 MiB objects) snapshot_count: 0 id: 26a1209678cad4 block_name_prefix: rbd_data.26a1209678cad4 format: 2 features: layering op_features: flags: create_timestamp: Thu Jan 7 10:38:58 2021 access_timestamp: Thu Jan 7 10:38:58 2021 modify_timestamp: Thu Jan 7 10:38:58 2021 parent: cow-pool/cow-base@base-snap overlap: 1 GiB 3). Note that the image has details of the parent image and overlap 4). Repeat steps 2 & 3 for an additional image called cow-image2 admin:/mnt/cow-base # rbd clone cow-pool/cow-base@base-snap cow-pool/cow-image2 admin:/mnt/cow-base # rbd -p cow-pool --image cow-image2 info rbd image 'cow-image2': size 1 GiB in 256 objects order 22 (4 MiB objects) snapshot_count: 0 id: 26a2fbcec7b8d9 block_name_prefix: rbd_data.26a2fbcec7b8d9 format: 2 features: layering op_features: flags: create_timestamp: Thu Jan 7 10:47:28 2021 access_timestamp: Thu Jan 7 10:47:28 2021 modify_timestamp: Thu Jan 7 10:47:28 2021 parent: cow-pool/cow-base@base-snap overlap: 1 GiB Task 6: Test that the COW clones are functional 1). Create a new directory and mount the COW clone called cow-image1 Note the rbd device name and use it to mount the file system admin:/mnt # mkdir /mnt/cow-image1 admin:/mnt # rbd map -p cow-pool --image cow-image1 /dev/rbd2 admin:/mnt # l total 4 drwxr-xr-x 1 root root 36 Jan 7 10:54 ./ drwxr-xr-x 1 root root 156 Oct 5 08:53 ../ drwxr-xr-x 3 root root 4096 Jan 7 10:19 cow-base/ drwxr-xr-x 1 root root 0 Jan 7 10:54 cow-image1/ admin:/mnt # ls -l /dev/rbd* brw-rw---- 1 root disk 252, 0 Jan 6 23:49 /dev/rbd0 brw-rw---- 1 root disk 252, 16 Jan 7 10:18 /dev/rbd1 brw-rw---- 1 root disk 252, 32 Jan 7 10:55 /dev/rbd2 /dev/rbd: total 0 drwxr-xr-x 2 root root 80 Jan 7 10:55 cow-pool drwxr-xr-x 2 root root 60 Jan 6 23:48 rbd-images admin:/mnt # mount /dev/rbd2 /mnt/cow-image1 2). Check that the base-image-file which was created in the parent snapshot is present admin:/mnt # cd /mnt/cow-image1 admin:/mnt/cow-image1 # ls base-image-file lost+found 3). Repeat steps 1 and 2 for cow-image2 admin:/mnt # mkdir /mnt/cow-image2 admin:/mnt # rbd map -p cow-pool --image cow-image2 /dev/rbd3 admin:/mnt # mount /dev/rbd3 /mnt/cow-image2 admin:/mnt # ls ./cow-image2/ base-image-file lost+found --> same file with image1 4). Create a new file in the directory where cow-image1 is mounted admin:/mnt # cd cow-image1 admin:/mnt/cow-image1 # touch additional-file admin:/mnt/cow-image1 # ls additional-file base-image-file lost+found 5). Look in the cow-image2 directory. Although they share the same parent snapshot, you can see that the files contained in each COW image are now different. admin:/mnt # ls ./cow-image2/ base-image-file lost+found Task 7: Flatten a COW Clone and remove the parent image \u00b6 1). Convert the COW clone called cow-image1 to a standalone rbd image Wait while the flatten process completes. Unlike a clone process this is not instantaneous and can take considerable time. admin:/mnt # rbd flatten cow-pool/cow-image1 Image flatten: 100% complete...done. 2). Check to see that the flatten process has removed the link to the parent snapshot admin:/mnt # rbd -p cow-pool --image cow-image1 info rbd image 'cow-image1': size 1 GiB in 256 objects order 22 (4 MiB objects) snapshot_count: 0 id: 26a1209678cad4 block_name_prefix: rbd_data.26a1209678cad4 format: 2 features: layering op_features: flags: create_timestamp: Thu Jan 7 10:38:58 2021 access_timestamp: Thu Jan 7 10:38:58 2021 modify_timestamp: Thu Jan 7 10:38:58 2021 admin:/mnt # rbd -p cow-pool --image cow-image2 info rbd image 'cow-image2': size 1 GiB in 256 objects order 22 (4 MiB objects) snapshot_count: 0 id: 26a2fbcec7b8d9 block_name_prefix: rbd_data.26a2fbcec7b8d9 format: 2 features: layering op_features: flags: create_timestamp: Thu Jan 7 10:47:28 2021 access_timestamp: Thu Jan 7 10:47:28 2021 modify_timestamp: Thu Jan 7 10:47:28 2021 parent: cow-pool/cow-base@base-snap overlap: 1 GiB 3). Unmount the images admin:/mnt # umount /mnt/cow-image1 admin:/mnt # umount /mnt/cow-image2 admin:/mnt # umount /mnt/cow-base 2.4.6. Configure iSCSI on SES \u00b6 In this lab an iSCSI Target was configured via the iSCSI gateway on our SUSE Enterprise Storage. An image was added to it. An iSCSI initiator then connected to the target, created a filesystem, and mounted it. Task 1: Create a new RBD image in the iscsi-images pool \u00b6 1). Create a new RBD image using the rbd command: admin:~ # rbd create --size 1024 iscsi-images/fooiscsi 2). Verify the new image has been created in the iscsi-images pool: The new image named fooiscsi should be displayed. admin:~ # rbd ls iscsi-images fooiscsi Task 2: Define a new iSCSI target with the Ceph Dashboard \u00b6 1). Access the Ceph Dashboard and log in: https://mon1.pvg.me.corp:8443 or https://10.58.121.186:8443 Username: admin Password: mypassword 2). Once logged in, click on the Block drop-down item near the top. Select iSCSI. 3). With the Overview tab showing for iSCSI, click on the Targets tab near the top. Note: When clicking on the Targets tab, if you see an error that says something about \u201cUnsupported `ceph-iscsi` config version\u2026\u201d, perform the following steps: 1. Close the browser window where the error occurred 2. Restart the mon1 virtual machine. Do this with the following steps: from the Virtual Machine Manager on your lab machine (not in the admin virtual machine), restart the mon1 virtual machine by right-clicking on the mon1 virtual machine > Shut Down > Reboot 3. Wait at least 30 seconds, then from the admin node, open up the browser again and log in to the Ceph Dashboard: https://mon1.pvg.me.corp:8443 or https://10.58.121.186:8443 Username: admin Password: mypassword 4. Continue the lab as directed below by navigating to the Block > iSCSI section, clicking on the Targets tab, and completing the steps below 4). Click Add. Use the following values: Target IQN: Portals: mon2.example.net:172.17.6.132 Images: iscsi-images/fooiscsi ACL authentication: Click Create Target. Task 3: Access the new iSCSI target from the admin node \u00b6 1). On the admin node, launch YaST either the ncurses or GUI interface, and select the iSCSI Initiator module: YaST > Network Services > iSCSI Initiator 2). Select the Discovered Targets tab (alt-v) 3). Select Discovery at the bottom of the frame (alt-d) 4). Add the ip address of mon2: 10.58.121.187. Leave the port as the default of 3260. Select Next. 5). Once again on the Discovered Targets tab, the mon2 target should be listed. With the new target highlighted, select Connect (alt-e) at the bottom of the frame. 6). Leave the Startup (in YaST2) or On boot (in YaST) value as manual. Select Next. 7). Select OK to exit the iscsi client configuration module 8). To verify that the iscsi device is now connected, use the lsscsi command to list devices: You should see there is one disk of type RBD connected on a device file similar to the following: admin:~ # lsscsi [0:0:0:0] cd/dvd QEMU QEMU DVD-ROM 1.4. /dev/sr0 [2:0:0:0] disk SUSE RBD 4.0 /dev/sda 9). Create an ext4 filesystem on the connected device file: admin:~ # mkfs.ext4 /dev/sda mke2fs 1.43.8 (1-Jan-2018) Creating filesystem with 262144 4k blocks and 65536 inodes Filesystem UUID: e3896f7e-0664-4b14-85db-0f77cb234c43 Superblock backups stored on blocks: 32768, 98304, 163840, 229376 Allocating group tables: done Writing inode tables: done Creating journal (8192 blocks): done Writing superblocks and filesystem accounting information: done 10). Mount the device to /mnt: admin:~ # mount /dev/sda /mnt 11). Use the mount command to list the connected device: admin:/mnt # mount | grep sda /dev/sda on /mnt type ext4 (rw,relatime,stripe=1024,data=ordered) 12).Change the root user\u2019s home directory and unmount the device: admin:/mnt # cd .. admin:/ # umount /mnt 2.4.7. Mount CephFS Provided by SUSE Enterprise Storage \u00b6 In this lab a ceph user was configured to mount the ceph filesystem provided by the SUSE Enterprise Cluster. A keyfile was generated, then used in the process. Task 1: Verify cephfs configuration of the SES cluster \u00b6 1). Cephfs requires two pools for operation: one for data, the other for metadata. Verify that the cluster has two pools for this purpose: admin:~ # ceph fs ls name: cephfs, metadata pool: cephfs_metadata, data pools: [cephfs_data ] Task 2: Create a secret key file for the admin user on the admin node 1). Because cephx authentication is enabled by default on SUSE Enterprise Storage, a secret key will need to be provided to allow access to mount the ceph filesystem. The admin user (identified \u2013 in this case \u2013 on the system as root) on the admin node has a key, but we will need to either provide it on the command line during the mount process (less secure), or put it in a permissions-restricted file and point to the file when mounting (more secure). If we do not specify the key or a file with the key, we will get an error. The following command will return an error: admin:~ # mount -t ceph mon1:6789:/ /mnt 2021-01-07 14:16:36.924 7f45108a9d80 -1 auth: unable to find a keyring on /etc/ceph/ceph.client.guest.keyring,/etc/ceph/ceph.keyring,/etc/ceph/keyring,/etc/ceph/keyring.bin,: (2) No such file or directory mount error 22 = Invalid argument 2). Take secret key value found in the /etc/ceph/ceph.client.admin.keyring file and put it in a new file: admin:~ # cat /etc/ceph/ceph.client.admin.keyring [client.admin] key = caps mds = \"allow *\" caps mon = \"allow *\" caps osd = \"allow *\" caps mgr = \"allow *\" 3). Create a new file and paste the secret key value into it: admin:~ # vi /etc/ceph/admin.secret Put the key value into the file and save it. 4). Change the permissions of the file to be read only by the user: admin:~ # ls -l /etc/ceph/admin.secret -r-------- 1 root root 41 Jan 5 20:05 /etc/ceph/admin.secret Task 3: Mount the ceph filesystem on the admin node \u00b6 1). Now that the keyfile is created, we can mount the filesystem: admin:~ # mount -t ceph mon1:6789:/ /mnt -o name=admin,secretfile=/etc/ceph/admin.secret admin:~ # ls -l /mnt total 0 2). Verify that the mount shows as expected: admin:~ # mount | grep ceph 10.58.121.186:6789:/ on /mnt type ceph (rw,relatime,name=admin,secret=,acl) 3). Change to the root user\u2019s home directory and unmount the filesystem: admin:~ # cd ~ admin:~ # umount /mnt 2.4.8. Export an NFS Share from SES with NFS Ganesha \u00b6 Task 0: Install and configure Ganesha (Ganesha config location is not configured. Please set the GANESHA_RADOS_POOL_NAMESPACE setting.) \u00b6 admin:~ # zypper in nfs-ganesha admin:/etc/ganesha # cat ganesha.conf NFSv4 { RecoveryBackend = 'rados_cluster'; #RecoveryBackend = 'rados_ng'; } RADOS_URLS { ceph_conf = '/etc/ceph/ceph.conf'; userid = \"admin\"; watch_url = \"rados://data/ganesha-export-index/conf-nfs1\"; } RADOS_KV { pool = \"metadata\"; namespace = \"ganesha-grace\"; nodeid = \"nfs1\"; } %url rados://data/ganesha-export-index/conf-nfs1 admin:/etc/ganesha # ganesha-rados-grace -p metadata -n ganesha-grace add nfs1 nfs2 nfs3 admin:/etc/ganesha # ganesha-rados-grace -p metadata -n ganesha-grace cur=1 rec=0 ====================================================== nfs1 E nfs2 E nfs3 E http://images.45drives.com/ceph/cephfs/nfs-ganesha-ceph.conf Task 1: Create an NFS export using the Ceph Dashboard \u00b6 1). In a browser, navigate to a monitor to access the Ceph Dashboard and log in: https://10.58.121.186:8443/ Username: admin Password: mypassword 2). Click on the NFS tab near the top of the page 3). Click on the green Add button 4). Click on the Add daemon button to the right and select mon1 5). Complete the configuration with the following values: Storage Backend: Object Gateway Object Storage User: s3user Path: S3CMDTEST NFS Protocol: NFSv3 and NFSv4 checked NFS Tag: Pseudo: /S3BKT Access Type: RW Squash: root_squash Transport Protocol: UDP and TCP checked Clients: Click Submit Task 2: Mount the NFS export on the admin node \u00b6 1). As the root user on the admin node, query the NFS Ganesha gateway node to see what mounts are available: showmount -e mon1 You should see something similar to the following: Export list for mon1: S3CMDTEST (everyone) 2). Mount the available nfs share to the /mnt directory on the admin server: mount -t nfs mon1:/S3BKT /mnt 3). List the nfs mount: mount | grep mnt Note the type listed as nfs4 4). Change to the root user\u2019s home directory and unmount the export: cd umount /mnt 2.4.9. Configure and Mount CIFS \u00b6 In this lab the Samba gateway was configured. A keyring for the Samba gateway was created, the Samba service was modified, and a user created to allow CIFS access to the SES cluster. Task 1: Prepare the CephFS share for CIFS \u00b6 1). In order for CIFS to work in our SES environment, a valid CephFS share must be available. The CephFS lab previously done in this workbook is sufficient. Using the same configuration that we used previously, mount the CephFS share and give permissions to all users at the root of the share: admin:~ # mount -t ceph mon1:6789:/ /mnt -o name=admin,secretfile=/etc/ceph/admin.secret admin:~ # chmod 777 /mnt admin:~ # l /mnt total 0 drwxrwxrwx 2 root root 0 Oct 5 14:30 ./ drwxr-xr-x 1 root root 156 Oct 5 08:53 ../ admin:~ # umount /mnt Task 2: Create a Samba gateway specific keyring on the Ceph admin node and copy it to the Samba gateway node \u00b6 1). A new keyring will be needed for the Samba gateway to allow access to the Ceph cluster. As root, perform the following: admin:~ # ceph auth get-or-create client.samba.gw mon 'allow r' osd 'allow *' mds 'allow *' -o ceph.client.samba.gw.keyring 2). Copy the new keyring to the Samba gateway node: admin:~ # scp ceph.client.samba.gw.keyring mon1:/etc/ceph/ ceph.client.samba.gw.keyring admin:~ # ssh mon1 Last login: Thu Jan 7 14:35:58 2021 from 10.58.121.181 mon1:~ # ls -l /etc/ceph/ total 12 -rw-r--r-- 1 root root 66 Jan 7 15:15 ceph.client.samba.gw.keyring -rw-r--r-- 1 root root 1095 Jan 5 22:44 ceph.conf -rw-r--r-- 1 root root 92 Aug 24 22:03 rbdmap Task 3: Configure Samba on the Samba gateway node \u00b6 1). The /etc/samba/smb.conf file will need to be edited to allow CIFS access to the storage cluster. On the mon1 node, replace all of the contents of the file with the following: admin:~ # ssh mon1 mon1:~ # vi /etc/samba/smb.conf mon1:/etc/samba # cat smb.conf [global] netbios name = SAMBA-GW clustering = no idmap config * : backend = tdb2 passdb backend = tdbsam # disable print server load printers = no smbd: backgroundqueue = no [ceph-smb] path = / vfs objects = ceph ceph: config_file = /etc/ceph/ceph.conf ceph: user_id = samba.gw read only = no oplocks = no kernel share modes = no 2). Create a smb user on the mon1 node named joesmb with a password of mypassword: mon1:/etc/samba # useradd joesmb mon1:/etc/samba # passwd joesmb ---> 123 Add joesmb to the smb password database with a password of mypassword: mon1:/etc/samba # smbpasswd -a joesmb New SMB password: ---> 123 Retype new SMB password: ---> 123 Added user joesmb. 3). Start and enable the smb and nmb daemons on mon1: mon1:/etc/samba # systemctl start smb nmb mon1:/etc/samba # systemctl enable smb nmb Created symlink /etc/systemd/system/multi-user.target.wants/smb.service \u2192 /usr/lib/systemd/system/smb.service. Created symlink /etc/systemd/system/multi-user.target.wants/nmb.service \u2192 /usr/lib/systemd/system/nmb.service. 4). Unmount the filesystem: mon1:~ # umount /mnt umount: /mnt: not mounted. Task 4: Connect a client to the Samba gateway \u00b6 1). On the admin node, verify that the Samba gateway is sharing via CIFS. The password is 123 admin:~ # smbclient -U joesmb -L //mon1 Enter WORKGROUP\\joesmb's password: ---> 123 Sharename Type Comment --------- ---- ------- ceph-smb Disk IPC$ IPC IPC Service (Samba 4.9.5-git.373.26895a83dbf3.44.1-SUSE-oS15.0-x86_64) Reconnecting with SMB1 for workgroup listing. Server Comment --------- ------- Workgroup Master --------- ------- GLOBAL CNPVGVSYB900 WORKGROUP SAMBA-GW 2). Connect to the ceph-smb share as joesmb. The password is 123 admin:~ # smbclient -U joesmb //mon1/ceph-smb Enter WORKGROUP\\joesmb's password: ---> 123 tree connect failed: NT_STATUS_BAD_NETWORK_NAME You should see output similar to the following: Try \u201chelp\u201d to get a list of possible commands. smb: \\>","title":"SUSE Enterprise Storage Basic Operation"},{"location":"linux/SES/linux_ses_demo/#suse-enterprise-storage-6-installation-and-basic-operation","text":"","title":"SUSE Enterprise Storage 6 Installation and Basic Operation"},{"location":"linux/SES/linux_ses_demo/#1-installation","text":"","title":"1. Installation"},{"location":"linux/SES/linux_ses_demo/#11-environment-setup","text":"In this demo, I use below environment, including VM setting and software installed. All VMs installed here was built on a physical host 10.58.121.68 . Host Server: 10.58.121.68 root / rootroot Account root / root123 Gateway: 10.58.120.1 Network Mask: 255.255.254.0 Nameserver: 10.58.32.32 10.33.50.20 Domain Search sha.me.corp dhcp.sha.me.corp me.corp ind.me.corp bgr.me.corp SUSE Server 15 SP1 Extensions and Modules were installed as below. [x] SUSE Enterprise Storage 6 [x] Basesystem Module 15 SP1 x86_64 [x] Server Applications Module 15 SP1 x86_64 Disable Services is as below: AppArmor Firewall Enable Services is as below. SSH Register SLES15.1 to local SMT. # SUSEConnect --url https://smtproxy.ind.me.corp Demo Environment summary is below. Alias Host Name Memory Disk eth0 eth0 mac address sles01 admin (salt-master) 16GB Disk1: 20G 10.58.121.181/23 52:54:00:23:7d:cd sles02 data1 16GB Disk1: 20G 10.58.121.182/23 52:54:00:5f:ce:6f Disk2: 8G Disk3: 8G Disk4: 8G sles03 data2 16GB Disk1: 20G 10.58.121.183/23 52:54:00:6f:f2:23 Disk2: 8G Disk3: 8G Disk4: 8G sles04 data3 16GB Disk1: 20G 10.58.121.184/23 52:54:00:93:4c:67 Disk2: 8G Disk3: 8G Disk4: 8G sles05 data4 16GB Disk1: 20G 10.58.121.185/23 52:54:00:90:b0:b0 Disk2: 8G Disk3: 8G Disk4: 8G sles06 mon1 16GB Disk1: 20G 10.58.121.186/23 52:54:00:46:43:7a sles07 mon2 16GB Disk1: 20G 10.58.121.187/23 52:54:00:00:fe:6b sles08 mon3 16GB Disk1: 20G 10.58.121.188/23 52:54:00:60:a3:92 Add hostname to file /etc/hosts (all nodes) If you do not specify a cluster network during Ceph deployment, it assumes a single public network environment. Make sure that the fully qualified domain name (FQDN) of each node can be resolved to the public network IP address by all other nodes. # vi /etc/hosts 10.58.121.181 admin.sha.me.corp admin salt 10.58.121.182 data1.sha.me.corp data1 10.58.121.183 data2.sha.me.corp data2 10.58.121.184 data3.sha.me.corp data3 10.58.121.185 data4.sha.me.corp data4 10.58.121.186 mon1.sha.me.corp mon1 10.58.121.187 mon2.sha.me.corp mon2 10.58.121.188 mon3.sha.me.corp mon3 Add all nodes as trust ssh access (root account) # cd ~ # ssh-keygen -t rsa # ssh-copy-id -i ~/.ssh/id_rsa.pub root@admin # ssh-copy-id -i ~/.ssh/id_rsa.pub root@data1 # ssh-copy-id -i ~/.ssh/id_rsa.pub root@data2 # ssh-copy-id -i ~/.ssh/id_rsa.pub root@data3 # ssh-copy-id -i ~/.ssh/id_rsa.pub root@data4 # ssh-copy-id -i ~/.ssh/id_rsa.pub root@mon1 # ssh-copy-id -i ~/.ssh/id_rsa.pub root@mon2 # ssh-copy-id -i ~/.ssh/id_rsa.pub root@mon3 # ssh admin.sha.me.corp # ssh data1.sha.me.corp # ssh data2.sha.me.corp # ssh data3.sha.me.corp # ssh data4.sha.me.corp # ssh mon1.sha.me.corp # ssh mon2.sha.me.corp # ssh mon3.sha.me.corp # ssh salt # ssh admin # ssh data1 # ssh data2 # ssh data3 # ssh data4 # ssh mon1 # ssh mon2 # ssh mon3 Disable firewall (all nodes) # sudo /sbin/SuSEfirewall2 off # firewall-cmd --state not running # systemctl stop firewalld.service # systemctl status firewalld.service firewalld.service - firewalld - dynamic firewall daemon Loaded: loaded (/usr/lib/systemd/system/firewalld.service; disabled; vendor preset: disabled) Active: inactive (dead) Docs: man:firewalld(1) Disable IPv6 (all nodes) and Set kernel pid to max value (all nodes) # vi /etc/sysctl.conf net.ipv6.conf.all.disable_ipv6 = 1 net.ipv6.conf.default.disable_ipv6 = 1 net.ipv6.conf.lo.disable_ipv6 = 1 kernel.pid_max = 4194303 # sysctl -p Set DEV_ENV=true in /etc/profile.local in all nodes Install basic software (all nodes) # zypper in -y -t pattern yast2_basis base # zypper in -y net-tools vim man sudo tuned irqbalance # zypper in -y ethtool rsyslog iputils less supportutils-plugin-ses # zypper in -y net-tools-deprecated tree wget Configure NTP service (all nodes), Setting via YaST2 and add server cn.pool.ntp.,org . And /etc/chrony.conf file looks like below. admin:~ # cat /etc/chrony.conf # Use public servers from the pool.ntp.org project. pool cn.pool.ntp.org iburst ! pool pool.ntp.org iburst # Record the rate at which the system clock gains/losses time. driftfile /var/lib/chrony/drift # Allow the system clock to be stepped in the first three updates # if its offset is larger than 1 second. makestep 1.0 3 # Enable kernel synchronization of the real-time clock (RTC). rtcsync # Enable hardware timestamping on all interfaces that support it. #hwtimestamp * # Increase the minimum numbgr of selectable sources required to adjust # the system clock. #minsources 2 # Allow NTP client access from local network. #allow 192.168.0.0/16 # Serve time even if not synchronized to a time source. #local stratum 10 # Specify file containing keys for NTP authentication. #keyfile /etc/chrony.keys # Get TAI-UTC offset and leap seconds from the system tz database. #leapsectz right/UTC # Specify directory for log files. logdir /var/log/chrony # Select which information is logged. #log measurements statistics tracking # Also include any directives found in configuration files in /etc/chrony.d include /etc/chrony.d/*.conf Make /etc/chrony.conf effective. # systemctl enable chronyd.service # systemctl restart chronyd.service # systemctl status chronyd.service # chronyc sources","title":"1.1. Environment Setup"},{"location":"linux/SES/linux_ses_demo/#12-install-packages","text":"Install salt-minion on all nodes. And start the service. Hostname is in file `/etc/salt/minion_id` # zypper in -y salt-minion Uncomment below to let all nodes know who is master # vi /etc/salt/minion master: salt # systemctl enable salt-minion.service # systemctl start salt-minion.service # systemctl status salt-minion.service Install Ceph in admin node. Check log in /var/log/salt admin:~ # zypper in -y salt-master admin:~ # systemctl enable salt-master.service admin:~ # systemctl start salt-master.service admin:~ # systemctl status salt-master.service Note: ganesha will be installed on mon1, not admin node. admin:~ # zypper se ganesha admin:~ # zypper in nfs-ganesha admin:~ # systemctl enable nfs-ganesha admin:~ # systemctl start nfs-ganesha admin:~ # systemctl status nfs-ganesha admin:~ # cd /var/log/salt List fingerprints of all unaccepted minion keys on the Salt master. admin:~ # salt-key -F Local Keys: master.pem: c0:e5:***:04:c7 master.pub: 43:73:***:6a:34 Unaccepted Keys: admin.sha.me.corp: fe:51:***:b9:48 mon1.sha.me.corp: 94:13:***:91:63 mon2.sha.me.corp: c0:fd:***:39:3f mon3.sha.me.corp: 38:fc:***:2e:05 data1.sha.me.corp: b6:6c:***:63:4f data2.sha.me.corp: ab:14:***:c8:ac data3.sha.me.corp: 90:3f:***:76:3b data4.sha.me.corp: d8:12:***:f1:20 If the minions' fingerprints match, accept them admin:~ # salt-key --accept-all The following keys are going to be accepted: Unaccepted Keys: admin.sha.me.corp mon1.sha.me.corp mon2.sha.me.corp mon3.sha.me.corp data1.sha.me.corp data2.sha.me.corp data3.sha.me.corp data4.sha.me.corp Proceed? [n/Y] Y Key for minion admin.sha.me.corp accepted. Key for minion mon1.sha.me.corp accepted. Key for minion mon2.sha.me.corp accepted. Key for minion mon3.sha.me.corp accepted. Key for minion data1.sha.me.corp accepted. Key for minion data2.sha.me.corp accepted. Key for minion data3.sha.me.corp accepted. Key for minion data4.sha.me.corp accepted. Verify that the keys have been accepted admin:~ # salt-key -F admin:~ # salt-key --list-all Accepted Keys: admin.sha.me.corp data1.sha.me.corp data2.sha.me.corp data3.sha.me.corp data4.sha.me.corp mon1.sha.me.corp mon2.sha.me.corp mon3.sha.me.corp Denied Keys: Unaccepted Keys: Rejected Keys: Zero out all drivers which will be used as OSDs (optional) data1:~ lsblk data1:~ # for I in {b,c,d}; do dd if=/dev/zero of=dev/sd$i bs=512 count=40 oflag=direct; done data2:~ # for I in {b,c,d}; do dd if=/dev/zero of=dev/sd$i bs=512 count=40 oflag=direct; done data3:~ # for I in {b,c,d}; do dd if=/dev/zero of=dev/sd$i bs=512 count=40 oflag=direct; done Install DeepSea admin:~ # zypper in -y deepsea Edit the /srv/pillar/ceph/deepsea_minions.sls file on the Salt master (admin node) and add or replace the following line: admin:~ # vi /srv/pillar/ceph/deepsea_minions.sls # Choose minions with a deepsea grain deepsea_minions: 'G@deepsea:*' #Match all Salt minions in the cluster # Choose all minions # deepsea_minions: '*' #Match all minions with the 'deepsea' grain # Choose custom Salt targeting # deepsea_minions: 'ses*' # deepsea_minions: 'ceph* or salt' Target the Minions Affirm salt-master (admin node) can communicate with the minions. And deploy the grains from admin node to all minions. admin:~ # salt '*' test.ping mon1.sha.me.corp: True data4.sha.me.corp: True data3.sha.me.corp: True data2.sha.me.corp: True data1.sha.me.corp: True mon3.sha.me.corp: True admin.sha.me.corp: True mon2.sha.me.corp: True Apply the 'deepsea' grain to a group of minions, and target with a DeepSea Grain admin:~ # salt '*' grains.append deepsea default data3.sha.me.corp: The val default was already in the list deepsea mon2.sha.me.corp: The val default was already in the list deepsea data1.sha.me.corp: The val default was already in the list deepsea data4.sha.me.corp: The val default was already in the list deepsea data2.sha.me.corp: The val default was already in the list deepsea mon3.sha.me.corp: The val default was already in the list deepsea admin.sha.me.corp: The val default was already in the list deepsea mon1.sha.me.corp: The val default was already in the list deepsea admin:~ # salt -G 'deepsea:*' test.ping (The following command is an equivalent) admin:~ # salt -C 'G@deepsea:*' test.ping admin.sha.me.corp: True data3.sha.me.corp: True mon1.sha.me.corp: True mon2.sha.me.corp: True data2.sha.me.corp: True data4.sha.me.corp: True mon3.sha.me.corp: True data1.sha.me.corp: True","title":"1.2. Install Packages"},{"location":"linux/SES/linux_ses_demo/#13-stage-0-the-preparation","text":"Run Stage 0\u2014the preparation During this stage, all required updates are applied and your system may be rebooted. If there are errors, re-run the stage. admin:~ # deepsea stage run ceph.stage.0 (The following commands are equivalents) admin:~ # salt-run state.orch ceph.stage.0 admin:~ # salt-run state.orch ceph.stage.prep Run Stage 1\u2014the discovery Here all hardware in your cluster is being detected and necessary information for the Ceph configuration is being collected. The discovery stage collects data from all minions and creates configuration fragments that are stored in the directory /srv/pillar/ceph/proposals . The data are stored in the YAML format in *.sls or *.yml files admin:~ # deepsea stage run ceph.stage.1 (The following commands are equivalents) admin:~ # salt-run state.orch ceph.stage.1 admin:~ # salt-run state.orch ceph.stage.discovery","title":"1.3. Stage 0 \u2014 the preparation"},{"location":"linux/SES/linux_ses_demo/#14-stage-2-the-configuration","text":"Run Stage 2 \u2014 the configuration \u2014 you need to prepare configuration data in a particular format. The assignment follows this pattern: role-ROLE_NAME/PATH/FILES_TO_INCLUDE (NOTE, the parent directory of PATH is /srv/pillar/ceph/ ) To avoid trouble with performance and the upgrade procedure, do not deploy the Ceph OSD, Metadata Server, or Ceph Monitor role to the Admin Node. Monitors, Metadata Server, and gateways can be co-located on the OSD nodes. If you are using CephFS, S3/Swift, iSCSI, at least two instances of the respective roles (Metadata Server, Object Gateway, iSCSI) are required for redundancy and availability. admin:~ # cp /usr/share/doc/packages/deepsea/examples/policy.cfg-rolebased /srv/pillar/ceph/proposals/policy.cfg admin:~ # vi /srv/pillar/ceph/proposals/policy.cfg ## Cluster Assignment # Add all nodes into Ceph cluster cluster-ceph/cluster/*.sls ## Roles # The Admin node fills the \u201cmaster\u201d and \u201cadmin\u201d roles for DeepSea # The master role is mandatory, always add a similar line to the following role-master/cluster/admin*.sls role-admin/cluster/admin*.sls # Monitoring # Cluster monitoring and data graphs, most commonly they run on Admin node # NFS Ganesha is configured via the file /etc/ganesha/ganesha.conf # As additional configuration is required to install NFS Ganesha, you can install NFS Ganesha later. # The following requirements need to be met before DeepSea stages 2 and 4 can be executed to install NFS Ganesha: # a)At least one node needs to be assigned the role-ganesha. # b)You can define only one role-ganesha per minion. # c)NFS Ganesha needs either an Object Gateway or CephFS to work, otherwise the validation will fail in Stage 3. # d)The kernel based NFS needs to be disabled on minions with the role-ganesha role. role-prometheus/cluster/admin*.sls role-grafana/cluster/mon1*.sls # MON # The minion will provide the monitor service to the Ceph cluster role-mon/cluster/mon*.sls # MGR # The Ceph manager daemon which collects all the state information from the whole cluster # Deploy it on all minions where you plan to deploy the Ceph monitor role role-mgr/cluster/mon1*.sls # MDS # The minion will provide the metadata service to support CephFS role-mds/cluster/mon*.sls # IGW # The minion will act as an iSCSI Gateway role-igw/cluster/mon2*.sls # RGW # The minion will act as an Object Gateway role-rgw/cluster/mon3*.sls # Storage # Use this role to specify storage nodes # It points to data1~4 nodes with a wildcard. role-storage/cluster/data*.sls # COMMON # It includes configuration files generated during the discovery (Stage 1) # Accept the default values for common configuration parameters such as fsid and public_network config/stack/default/global.yml config/stack/default/ceph/cluster.yml admin:~ # deepsea stage run ceph.stage.2 (The following commands are equivalents) admin:~ # salt-run state.orch ceph.stage.2 admin:~ # salt-run state.orch ceph.stage.configure After the command succeeds, run below command to view the pillar data for the specified minions admin:~ # salt 'mon*' pillar.items admin:~ # salt '*' saltutil.pillar_refresh Check time server (admin node) (the directory /srv/pillar/ceph/stack was initialized after deepsea installed, but global.yml file was not created yet until stage 2) By default, DeepSea uses the Admin Node as the time server for other cluster nodes. admin:~ # cat /srv/pillar/ceph/stack/default/global.yml (this file will be generated after stage 2) monitoring: prometheus: metric_relabel_config: ceph: [] grafana: [] node_exporter: [] prometheus: [] relabel_config: ceph: [] grafana: [] node_exporter: [] prometheus: [] rule_files: [] scrape_interval: ceph: 10s grafana: 10s node_exporter: 10s prometheus: 10s target_partition: ceph: 1/1 grafana: 1/1 node_exporter: 1/1 prometheus: 1/1 time_server: admin.sha.me.corp Verify network (the directory /srv/pillar/ceph/stack was initialized after deepsea installed, but cluster.yml file was not created until stage 2 ) admin:~ # cat /srv/pillar/ceph/stack/ceph/cluster.yml --nothing admin:~ # cat /srv/pillar/ceph/stack/default/ceph/cluster.yml available_roles: - storage - admin - mon - mds - mgr - igw - grafana - prometheus - storage - rgw - ganesha - client-cephfs - client-radosgw - client-iscsi - client-nfs - benchmark-rbd - benchmark-blockdev - benchmark-fs - master cluster_network: 10.58.120.0/23 fsid: 343ee7d3-232f-4c71-8216-1edbc55ac6e0 public_network: 10.58.120.0/23 Note: customized file will overwrite default one. Default file: /srv/pillar/ceph/stack/default/ceph/cluster.yml Customized file: /srv/pillar/ceph/stack/ceph/cluster.yml Check DriveGroup DriveGroups specify the layouts of OSDs in the Ceph cluster. They are defined in a single file /srv/salt/ceph/configuration/files/drive_groups.yml admin:~ # cat /srv/salt/ceph/configuration/files/drive_groups.yml default_drive_group_name: target: 'data*' <--original: 'I@role:storage' data_devices: all: true admin:~ # salt 'data*' pillar.items | grep -B5 stroage","title":"1.4. Stage 2 \u2014 the configuration"},{"location":"linux/SES/linux_ses_demo/#15-stage-3-the-deployment","text":"Run Stage 3 \u2014 the deployment \u2014 creates a basic Ceph cluster with mandatory Ceph services. This Deployment stage has more than 60 automated steps. Be patient and make sure the stage completes successfully before proceeding. Set dev environment and disable subvolume: admin:~ # vi /srv/pillar/ceph/stack/global.yml admin:~ # vi /srv/pillar/ceph/stack/default/global.yml monitoring: prometheus: metric_relabel_config: ceph: [] grafana: [] node_exporter: [] prometheus: [] relabel_config: ceph: [] grafana: [] node_exporter: [] prometheus: [] rule_files: [] scrape_interval: ceph: 10s grafana: 10s node_exporter: 10s prometheus: 10s target_partition: ceph: 1/1 grafana: 1/1 node_exporter: 1/1 prometheus: 1/1 time_server: admin.sha.me.corp DEV_ENV: True subvolume_init: disabled admin:~ # salt '*' saltutil.pillar_refresh Note: customized file will overwrite default one. Default file: /srv/pillar/ceph/stack/default/global.yml Customized file: /srv/pillar/ceph/stack/global.yml admin:~ # deepsea stage run ceph.stage.3 (The following commands are equivalents) admin:~ # salt-run state.orch ceph.stage.3 admin:~ # salt-run state.orch ceph.stage.deploy After the command succeeds, run the following to check the status: admin:~ # ceph -s Below comands return you a structure of matching disks based on your DriveGroups. (will show available information after stage 3) admin:~ # salt-run disks.Report admin:~ # salt-run disks.list admin:~ # salt-run disks.details","title":"1.5. Stage 3 \u2014 the deployment"},{"location":"linux/SES/linux_ses_demo/#16-stage-4-the-services","text":"Run Stage 4 \u2014 the services \u2014 additional features of Ceph like iSCSI, Object Gateway and CephFS can be installed in this stage. Each is optional. admin:~ # deepsea stage run ceph.stage.4 (The following commands are equivalents) admin:~ # salt-run state.orch ceph.stage.4 admin:~ # salt-run state.orch ceph.stage.services admin:~ # ceph osd lspools 1 iscsi-images 2 cephfs_data 3 cephfs_metadata 4 .rgw.root 5 default.rgw.control 6 default.rgw.meta 7 default.rgw.log Before logon to dashboard via url, need get credentials first admin:~ # salt-call grains.get dashboard_creds local: ---------- admin: --> the password was changed to mypassword to log on to dashboard admin:~ # ceph mgr services { \"dashboard\": \"https://mon1.sha.me.corp:8443/\", \"prometheus\": \"http://mon1.sha.me.corp:9283/\" } https://10.58.121.186:8443 http://10.58.121.186:9283 admin:~ # watch ceph -s Every 2.0s: ceph -s admin: Mon Oct 5 14:41:51 2020 cluster: id: health: HEALTH_OK services:s: ceph -s mon: 3 daemons, quorum mon1,mon2,mon3 (age 87m) mgr: mon1(active, since 82m) mds: cephfs:1 {0=mon3=up:active} 2 up:standby osd: 12 osds: 12 up (since 85m), 12 in (since 85m) rgw: 1 daemon active (mon3) task status: scrub status: mds.mon3: idle data: pools: 7 pools, 576 pgs objects: 213 objects, 4.2 KiB usage: 12 GiB used, 84 GiB / 96 GiB avail pgs: 576 active+clean io: client: 852 B/s rd, 0 op/s rd, 0 op/s wr","title":"1.6. Stage 4 \u2014 the services"},{"location":"linux/SES/linux_ses_demo/#17-stage-5-the-removal-stage","text":"Run Stage 5 \u2014 the removal stage. This stage is not mandatory and during the initial setup it is usually not needed. In this stage the roles of minions and also the cluster configuration are removed. You need to run this stage when you need to remove a storage node from your cluster. admin:~ # deepsea stage run ceph.stage.","title":"1.7. Stage 5 \u2014 the removal stage"},{"location":"linux/SES/linux_ses_demo/#18-installation-guide","text":"Deployment Guide (EN) Deployment Guide (ZH)","title":"1.8. Installation Guide"},{"location":"linux/SES/linux_ses_demo/#19-issues-during-installation","text":"[ERROR]: The Salt Master has cached the public key for this node SOLUTION : Restart minions service [ERROR]: This server_id is computed nor by Adler32 neither by CRC32 [QUESTION]: How to change new salt key Stop salt-minion service # systemctl stop salt-minion Delete salt-minion pulic key # rm /etc/salt/pki/minion/minion.pub # rm /etc/salt/pki/minion/minion.pem Change new minion_id admin:~ # echo admin.sha.me.corp > /etc/salt/minion_id data1:~ # echo data1.sha.me.corp > /etc/salt/minion_id data2:~ # echo data2.sha.me.corp > /etc/salt/minion_id data3:~ # echo data3.sha.me.corp > /etc/salt/minion_id data4:~ # echo data4.sha.me.corp > /etc/salt/minion_id mon1:~ # echo mon1.sha.me.corp > /etc/salt/minion_id mon2:~ # echo mon2.sha.me.corp > /etc/salt/minion_id mon3:~ # echo mon3.sha.me.corp > /etc/salt/minion_id Delete old ID on admin node # salt-key -D Restart salt-minion service # systemctl restart salt-minion Accept all new key on admin node admin:~ # salt-key -L admin:~ # salt-key -A or admin:~ # salt-key -a admin.sha.me.corp data1:~ # salt-key -a data1.sha.me.corp data2:~ # salt-key -a data2.sha.me.corp data3:~ # salt-key -a data3.sha.me.corp data4:~ # salt-key -a data4.sha.me.corp mon1:~ # salt-key -a mon1.sha.me.corp mon2:~ # salt-key -a mon2.sha.me.corp mon3:~ # salt-key -a mon3.sha.me.corp [ERROR] ['/var/lib/ceph subvolume missing on mon3.sha.me.corp', '/var/lib/ceph subvolume missing on mon1.sha.me.corp', '/var/lib/ceph subvolume missing on mon2.sha.me.corp', 'See /srv/salt/ceph/subvolume/README.md'] SOLUTION Edit /srv/pillar/ceph/stack/global.yml and add the following line: subvolume_init: disabled Then refresh the Salt pillar and re-run DeepSea stage.3: admin:~ # salt '*' saltutil.refresh_pillar admin:~ # salt-run state.orch ceph.stage.3 After DeepSea successfully finished stage.3, the Ceph Dashboard will be running. Refer to Book \u201cAdministration Guide\u201d, Chapter 20 \u201cCeph Dashboard\u201d for a detailed overview of Ceph Dashboard features. To list nodes running dashboard, run: admin:~ # ceph mgr services | grep dashboard To list admin credentials, run: admin:~ # salt-call grains.get dashboard_creds [ERROR] module function cephprocesses.wait executed on nodes mon1~3 and data1~4 in Stage 0 SOLUTION Check below on all nodes # salt-call cephprocesses.check ERROR: process ceph-mds for role mds is not running ERROR: process radosgw for role rgw is not running admin:~ # ceph -s Clock skew detected on mon ceph (mon.mon2, mon.mon3) Set time server to public server (China) # chronyc sources","title":"1.9. Issues during installation"},{"location":"linux/SES/linux_ses_demo/#110-shutting-down-the-whole-ceph-cluster","text":"Shut down or disconnect any clients accessing the cluster. To prevent CRUSH from automatically rebalancing the cluster, set the cluster to noout: # ceph osd set noout Other flags you can set per osd: nodown noup noin noout Disable safety measures and run the ceph.shutdown runner: admin:~ # salt-run disengage.safety safety is now disabled for cluster ceph admin:~ # salt-run state.orch ceph.shutdown admin.sha.me.corp_master: Name: set noout - Function: salt.state - Result: Changed Started: - 14:32:14.398022 Duration: 2266.75 ms Name: Shutting down radosgw for rgw - Function: salt.state - Result: Changed Started: - 14:32:16.665452 Duration: 1461.23 ms Name: Shutting down cephfs - Function: salt.state - Result: Changed Started: - 14:32:18.127353 Duration: 30326.193 ms Name: Shutting down iscsi - Function: salt.state - Result: Clean Started: - 14:32:48.454187 Duration: 30142.468 ms Name: Shutting down storage - Function: salt.state - Result: Changed Started: - 14:33:18.597321 Duration: 10841.45 ms Name: Shutting down mgr - Function: salt.state - Result: Changed Started: - 14:33:29.439442 Duration: 29209.141 ms Name: Shutting down mon - Function: salt.state - Result: Changed Started: - 14:33:58.649221 Duration: 30519.97 ms Summary for admin.sha.me.corp_master ------------ Succeeded: 7 (changed=6) Failed: 0 ------------ Total states run: 7 Total run time: 134.767 s Power off all cluster nodes: admin:~ # salt -C 'G@deepsea:*' cmd.run \"shutdown -h\" Broadcast message from root@admin (Sat 2021-03-06 14:40:37 CST): The system is going down for poweroff at Sat 2021-03-06 14:41:37 CST! admin.sha.me.corp: Shutdown scheduled for Sat 2021-03-06 14:41:37 CST, use 'shutdown -c' to cancel. mon2.sha.me.corp: Shutdown scheduled for Sat 2021-03-06 14:41:37 CST, use 'shutdown -c' to cancel. data2.sha.me.corp: Shutdown scheduled for Sat 2021-03-06 14:41:37 CST, use 'shutdown -c' to cancel. mon3.sha.me.corp: Shutdown scheduled for Sat 2021-03-06 14:41:37 CST, use 'shutdown -c' to cancel. data3.sha.me.corp: Shutdown scheduled for Sat 2021-03-06 14:41:37 CST, use 'shutdown -c' to cancel. data4.sha.me.corp: Shutdown scheduled for Sat 2021-03-06 14:41:37 CST, use 'shutdown -c' to cancel. mon1.sha.me.corp: Shutdown scheduled for Sat 2021-03-06 14:41:37 CST, use 'shutdown -c' to cancel. data1.sha.me.corp: Shutdown scheduled for Sat 2021-03-06 14:41:37 CST, use 'shutdown -c' to cancel.","title":"1.10. Shutting Down the Whole Ceph Cluster"},{"location":"linux/SES/linux_ses_demo/#111-starting-stopping-and-restarting-services-using-targets","text":"# ls /usr/lib/systemd/system/ceph*.target ceph.target ceph-osd.target ceph-mon.target ceph-mgr.target ceph-mds.target ceph-radosgw.target ceph-rbd-mirror.target To start/stop/restart all Ceph services on the node, run: # systemctl start ceph.target # systemctl stop ceph.target # systemctl restart ceph.target To start/stop/restart all OSDs on the node, run: # systemctl start ceph-osd.target # systemctl stop ceph-osd.target # systemctl restart ceph-osd.target Starting, Stopping, and Restarting Individual Services # systemctl list-unit-files --all --type=service ceph* ceph-osd@.service ceph-mon@.service ceph-mds@.service ceph-mgr@.service ceph-radosgw@.service ceph-rbd-mirror@.service Example : # systemctl status ceph-mon@HOSTNAME.service (e.g., ceph-mon@mon1.service) # systemctl start ceph-osd@1.service # systemctl stop ceph-osd@1.service # systemctl restart ceph-osd@1.service # systemctl status ceph-osd@1.service","title":"1.11. Starting, Stopping, and Restarting Services Using Targets"},{"location":"linux/SES/linux_ses_demo/#112-restarting-all-services","text":"# salt-run state.orch ceph.restart","title":"1.12. Restarting All Services"},{"location":"linux/SES/linux_ses_demo/#113-restarting-specific-services","text":"Example: salt-run state.orch ceph.restart.service_name # salt-run state.orch ceph.restart.mon # salt-run state.orch ceph.restart.mgr # salt-run state.orch ceph.restart.osd # salt-run state.orch ceph.restart.mds # salt-run state.orch ceph.restart.rgw # salt-run state.orch ceph.restart.igw # salt-run state.orch ceph.restart.ganesha Default log file path of salt-run: /var/log/salt/master","title":"1.13. Restarting Specific Services"},{"location":"linux/SES/linux_ses_demo/#2-basic-operation","text":"","title":"2. Basic Operation"},{"location":"linux/SES/linux_ses_demo/#21-pools-and-data-placement","text":"","title":"2.1. Pools and Data Placement"},{"location":"linux/SES/linux_ses_demo/#211-enable-the-pg-autoscaler-and-balancer-modules","text":"","title":"2.1.1. Enable the PG Autoscaler and Balancer Modules"},{"location":"linux/SES/linux_ses_demo/#task-1-view-the-state-of-all-the-manager-modules","text":"List all the existing Manager Modules admin:~ # ceph mgr module ls | less","title":"Task 1: View the state of all the Manager Modules"},{"location":"linux/SES/linux_ses_demo/#task-2-list-the-existing-pools","text":"List the pools that already exist in the cluster admin:~ # ceph osd lspools 1 iscsi-images 2 cephfs_data 3 cephfs_metadata 4 .rgw.root 5 default.rgw.control 6 default.rgw.meta 7 default.rgw.log List the pools again, but this time using the rados command: admin:~ # rados lspools iscsi-images cephfs_data cephfs_metadata .rgw.root default.rgw.control default.rgw.meta default.rgw.log View the output of placement group autoscale-status command for the pools admin:~ # ceph osd pool autoscale-status Error ENOTSUP: Module 'pg_autoscaler' is not enabled (required by command 'osd pool autoscale-status'): use `ceph mgr module enable pg_autoscaler` to enable it","title":"Task 2: List the Existing Pools"},{"location":"linux/SES/linux_ses_demo/#task-3-enable-the-pg_autoscaler-module","text":"Enable the pg_autoscaler module admin:~ # ceph mgr module enable pg_autoscaler admin:~ # ceph osd pool autoscale-status POOL SIZE TARGET SIZE RATE RAW CAPACITY RATIO TARGET RATIO EFFECTIVE RATIO BIAS PG_NUM NEW PG_NUM AUTOSCALE iscsi-images 389 3.0 98256M 0.0000 1.0 128 32 warn cephfs_data 0 3.0 98256M 0.0000 1.0 256 32 warn cephfs_metadata 7285 3.0 98256M 0.0000 4.0 64 16 warn .rgw.root 1245 3.0 98256M 0.0000 1.0 32 warn default.rgw.control 0 3.0 98256M 0.0000 1.0 32 warn default.rgw.meta 381 3.0 98256M 0.0000 1.0 32 warn default.rgw.log 18078 3.0 98256M 0.0000 1.0 32 warn Note that for the iscsi-images pool the PG_NUM value is 128. And note that the NEW PG_NUM value is 32. The PGs won\u2019t be adjusted automatically because the default setting for the autoscaler is \u201cwarn\u201d. Note the last column (mode) that shows status \u201cwarn\u201d for all the pools. Check current status. \u201chave too many placement groups\u201d. That\u2019s exactly what we want the pg_autoscaler to tell us. admin:~ # ceph health HEALTH_WARN 3 pools have too many placement groups Turn off the pg_autoscaler feature for CephFS pools admin:~ # ceph osd pool set cephfs_data pg_autoscale_mode off set pool 2 pg_autoscale_mode to off admin:~ # ceph osd pool set cephfs_metadata pg_autoscale_mode off set pool 3 pg_autoscale_mode to off admin:~ # ceph health HEALTH_WARN 1 pools have too many placement groups Set the pg_autoscaler mode to \u201con\u201d for the iscs-images pool: admin:~ # ceph osd pool set iscsi-images pg_autoscale_mode on set pool 1 pg_autoscale_mode to on admin:~ # ceph osd pool autoscale-status POOL SIZE TARGET SIZE RATE RAW CAPACITY RATIO TARGET RATIO EFFECTIVE RATIO BIAS PG_NUM NEW PG_NUM AUTOSCALE iscsi-images 389 3.0 98256M 0.0000 1.0 128 32 on cephfs_data 0 3.0 98256M 0.0000 1.0 256 32 off cephfs_metadata 7412 3.0 98256M 0.0000 4.0 64 16 off .rgw.root 1245 3.0 98256M 0.0000 1.0 32 warn default.rgw.control 0 3.0 98256M 0.0000 1.0 32 warn default.rgw.meta 381 3.0 98256M 0.0000 1.0 32 warn default.rgw.log 18078 3.0 98256M 0.0000 1.0 32 warn Turn on the pg_autoscaler feature for CephFS pools admin:~ # ceph osd pool set cephfs_data pg_autoscale_mode on set pool 2 pg_autoscale_mode to on admin:~ # ceph osd pool set cephfs_metadata pg_autoscale_mode on set pool 3 pg_autoscale_mode to on PG numbgrs must always be a power of 2 admin:~ # ceph osd pool autoscale-status POOL SIZE TARGET SIZE RATE RAW CAPACITY RATIO TARGET RATIO EFFECTIVE RATIO BIAS PG_NUM NEW PG_NUM AUTOSCALE iscsi-images 389 3.0 98256M 0.0000 1.0 32 on cephfs_data 0 3.0 98256M 0.0000 1.0 32 off cephfs_metadata 7412 3.0 98256M 0.0000 4.0 16 off .rgw.root 1245 3.0 98256M 0.0000 1.0 32 warn default.rgw.control 0 3.0 98256M 0.0000 1.0 32 warn default.rgw.meta 381 3.0 98256M 0.0000 1.0 32 warn default.rgw.log 35900 3.0 98256M 0.0000 1.0 32 warn Show the cluster health admin:~ # ceph -s cluster: id: health: HEALTH_OK services: mon: 3 daemons, quorum mon1,mon2,mon3 (age 4w) mgr: mon1(active, since 46h) mds: cephfs:1 {0=mon3=up:active} 2 up:standby osd: 12 osds: 12 up (since 8w), 12 in (since 8w) rgw: 1 daemon active (mon3) task status: scrub status: mds.mon3: idle data: pools: 7 pools, 433 pgs objects: 246 objects, 4.7 KiB usage: 13 GiB used, 83 GiB / 96 GiB avail pgs: 0.462% pgs not active 431 active+clean 2 peering io: client: 45 KiB/s rd, 0 B/s wr, 44 op/s rd, 28 op/s wr","title":"Task 3: Enable the pg_autoscaler module"},{"location":"linux/SES/linux_ses_demo/#task-4-turn-on-the-placement-group-balancer-feature","text":"1). Show the \u201cstatus\u201d of the balancer: admin:~ # ceph balancer status { \"plans\": [], \"active\": false, \"last_optimize_started\": \"\", \"last_optimize_duration\": \"\", \"optimize_result\": \"\", \"mode\": \"none\" } admin:~ # ceph balancer on admin:~ # ceph balancer status { \"plans\": [], \"active\": true, \"last_optimize_started\": \"Mon Jan 4 20:22:57 2021\", \"last_optimize_duration\": \"0:00:00.001379\", \"optimize_result\": \"Please do \\\"ceph balancer mode\\\" to choose a valid mode first\", \"mode\": \"none\" } 2). Set the mode for the balancer to \u201cupmap\u201d: admin:~ # ceph balancer mode upmap Error EPERM: min_compat_client \"jewel\" < \"luminous\", which is required for pg-upmap. Try \"ceph osd set-require-min-compat-client luminous\" before enabling this mode admin:~ # ceph osd set-require-min-compat-client luminous --yes-i-really-mean-it set require_min_compat_client to luminous admin:~ # ceph balancer mode upmap admin:~ # ceph balancer status { \"plans\": [], \"active\": true, \"last_optimize_started\": \"Mon Jan 4 20:23:57 2021\", \"last_optimize_duration\": \"0:00:00.001807\", \"optimize_result\": \"Please do \\\"ceph balancer mode\\\" to choose a valid mode first\", \"mode\": \"upmap\" } 3). Create a balancer optimization plan called basic-plan. Ceph won\u2019t let you do this yet. Because you just recently enabled the pg_autoscaler, Ceph is moving objects around, and the PGs are quite busy with re-peering. admin:~ # ceph balancer optimize basic-plan Error EINVAL: Balancer enabled, disable to optimize manually 4). Show the details of the plan: This shows what \u201cexecute\u201d-ing the plan will do, itemizing which PGs will be affected. admin:~ # ceph balancer show basic-plan Error ENOENT: plan basic-plan not found <--- failed here 5). Show the effectiveness of the plan by comparing the current score for the pre-planned balancing and the score for the planned balancing: admin:~ # ceph balancer eval current cluster score 0.118731 (lower is better) admin:~ # ceph balancer eval basic-plan Error EINVAL: option \"basic-plan\" not a plan or a pool 6). Show the status of the balancer, now with all of these settings having been set, but before putting them into effect: The pg_autoscaler has already optimized the balance of PGs sufficiently. That\u2019s because this cluster is very small and has no significant content stored in it yet. If that\u2019s the case, you would see a message like \u201cError EALREADY: Unable to find further optimization, or pool(s)' pg_num is decreasing, or distribution is already perfect.\u201d If you receive this message, then you will not be able to complete this task. At some later time in the course you may choose to revisit this task to complete it. admin:~ # ceph balancer status { \"plans\": [], \"active\": true, \"last_optimize_started\": \"Mon Jan 4 20:32:59 2021\", \"last_optimize_duration\": \"0:00:00.004170\", \"optimize_result\": \"Unable to find further optimization, or pool(s) pg_num is decreasing, or distribution is already perfect\", \"mode\": \"upmap\" } 7). Set the basic-plan into effect: admin:~ # ceph balancer execute basic-plan Error EINVAL: Balancer enabled, disable to execute a plan 8). Now re-show the current score for the balanced cluster: admin:~ # ceph balancer eval current cluster score 0.118731 (lower is better)","title":"Task 4: Turn on the Placement Group balancer feature"},{"location":"linux/SES/linux_ses_demo/#212-manipulate-erasure-code-profiles","text":"","title":"2.1.2. Manipulate Erasure Code Profiles"},{"location":"linux/SES/linux_ses_demo/#task-1-display-a-list-of-the-current-erasure-code-profiles","text":"admin:~ # ceph osd erasure-code-profile no valid command found; 4 closest matches: osd erasure-code-profile set { [...]} {--force} osd erasure-code-profile get osd erasure-code-profile rm osd erasure-code-profile ls Error EINVAL: invalid command admin:~ # ceph osd erasure-code-profile ls default","title":"Task 1: Display a list of the current Erasure Code profiles"},{"location":"linux/SES/linux_ses_demo/#task-2-examine-the-details-of-the-default-ec-profile","text":"admin:~ # ceph osd erasure-code-profile get default k=2 m=1 plugin=jerasure technique=reed_sol_van","title":"Task 2: Examine the details of the default EC profile"},{"location":"linux/SES/linux_ses_demo/#task-3-create-and-remove-a-new-ec-profile","text":"1. Create a new EC profile from the command line. This is going to be a \u201cbad\u201d profile that will be removed in a moment: admin:~ # ceph osd erasure-code-profile set bad_profile k=2 m=4 plugin=jerasure admin:~ # ceph osd erasure-code-profile ls bad_profile default admin:~ # ceph osd erasure-code-profile get bad_profile crush-device-class= crush-failure-domain=host crush-root=default jerasure-per-chunk-alignment=false k=2 m=4 plugin=jerasure technique=reed_sol_van w=8 admin:~ # ceph osd erasure-code-profile rm bad_profile admin:~ # ceph osd erasure-code-profile ls default","title":"Task 3: Create and remove a new EC profile"},{"location":"linux/SES/linux_ses_demo/#task-4-create-a-better-ec-profile","text":"admin:~ # ceph osd erasure-code-profile set usable_profile k=2 m=1 plugin=jerasure technique=reed_sol_van stripe_unit=4K crush-failure-domain=host admin:~ # ceph osd erasure-code-profile get usable_profile crush-device-class= crush-failure-domain=host crush-root=default jerasure-per-chunk-alignment=false k=2 m=1 plugin=jerasure stripe_unit=4K technique=reed_sol_van w=8","title":"Task 4: Create a better EC profile"},{"location":"linux/SES/linux_ses_demo/#213-manipulate-crush-map-rulesets","text":"","title":"2.1.3. Manipulate CRUSH Map Rulesets"},{"location":"linux/SES/linux_ses_demo/#task-1-display-a-list-of-the-current-crush-map-rules","text":"admin:~ # ceph osd crush rule ls replicated_rule admin:~ # ceph osd crush osd crush rule ls osd crush rule ls-by-class osd crush rule dump {} osd crush dump osd crush set {} osd crush add-bucket { [...]} osd crush rename-bucket osd crush set [...] osd crush add [...] osd crush set-all-straw-buckets-to-straw2 admin:~ # ceph osd crush rule osd crush rule ls osd crush rule ls-by-class osd crush rule dump {} osd crush rule create-simple {firstn|indep} osd crush rule create-replicated {} osd crush rule create-erasure {} osd crush rule rm osd crush rule rename List the existing CRUSH Map rulesets that have been defined according to a particular device class: admin:~ # ceph osd crush rule ls-by-class hdd admin:~ # ceph osd crush rule ls-by-class ssd Error ENOENT: failed to get rules by class 'ssd' admin:~ # ceph osd crush rule ls-by-class nvme Error ENOENT: failed to get rules by class 'nvme'","title":"Task 1: Display a list of the current CRUSH Map rules"},{"location":"linux/SES/linux_ses_demo/#task-2-examine-the-details-of-the-default-crush-map-rule","text":"Show the details of the default CRUSH Map rule with the dump sub-command: The \u201crule_id\u201d and \u201cruleset\u201d values just numbgrs to keep track of rules similar to a DB key id. \u201cmin_size\u201d and \u201cmax_size\u201d are related to how CRUSH behaves when a certain numbgr of replicas are created. The \u201csteps\u201d section is the most functional portion of the rule, providing an ordered set of rules for how CRUSH should behave. Note that there are three \u201cop\u201d parts, one each for \u201ctake\u201d, \u201cchooseleaf_firstn\u201d, and \u201cemit\u201d. \u201ctake\u201d in a replicated rule is always the first step, and \u201cemit\u201d is always the last step. The \u201citem_type\u201d in the \u201ctake\u201d step is the crush_root value, and the \u201chost\u201d in the \u201cchooseleaf_firstn\u201d step is the failure_domain. admin:~ # ceph osd crush rule dump replicated_rule { \"rule_id\": 0, \"rule_name\": \"replicated_rule\", \"ruleset\": 0, \"type\": 1, \"min_size\": 1, \"max_size\": 10, \"steps\": [ { \"op\": \"take\", \"item\": -1, \"item_name\": \"default\" }, { \"op\": \"chooseleaf_firstn\", \"num\": 0, \"type\": \"host\" }, { \"op\": \"emit\" } ] }","title":"Task 2: Examine the details of the default CRUSH Map rule"},{"location":"linux/SES/linux_ses_demo/#task-3-create-and-remove-a-new-crush-map-rule","text":"1). Create a new CRUSH ruleset from the command line.We made two mistakes here: First, we named it \u201cbud\u201d instead of \u201cbad\u201d. admin:~ # ceph osd crush rule create-replicated bud_ruleset default host admin:~ # ceph osd crush rule ls replicated_rule bud_ruleset 2). Rename the ruleset: admin:~ # ceph osd crush rule rename bud_ruleset bad_ruleset admin:~ # ceph osd crush rule ls replicated_rule bad_ruleset 3). The second mistake was that we specified the failure-domain at the host-bucket level. This is technically not a bad thing to do, in fact it would be a common use case. But for this demo we want to set the failure domain at the rack-bucket level. We can\u2019t change a defined CRUSH Map ruleset, so delete the bad one: admin:~ # ceph osd crush rule rm bad_ruleset admin:~ # ceph osd crush rule ls replicated_rule","title":"Task 3: Create and remove a new CRUSH Map rule"},{"location":"linux/SES/linux_ses_demo/#task-4-create-a-better-crush-map-rule","text":"Create a more appropriate CRUSH Map rule from the CLI, that will survive the failure of a rack: admin:~ # ceph osd crush rule create-replicated better_ruleset default rack admin:~ # ceph osd crush rule dump better_ruleset { \"rule_id\": 1, \"rule_name\": \"better_ruleset\", \"ruleset\": 1, \"type\": 1, \"min_size\": 1, \"max_size\": 10, \"steps\": [ { \"op\": \"take\", \"item\": -1, \"item_name\": \"default\" }, { \"op\": \"chooseleaf_firstn\", \"num\": 0, \"type\": \"rack\" }, { \"op\": \"emit\" } ] }","title":"Task 4: Create a better CRUSH Map rule"},{"location":"linux/SES/linux_ses_demo/#task-5-create-crush-map-rules-for-different-classes-of-devices","text":"1). Create two different CRUSH Map rules from the CLI, that will accommodate a slow set of devices (HDDs) and a fast set of devices (SDDs): The error of 2 nd is because the cluster does not have any SSD devices. admin:~ # ceph osd crush rule create-replicated slow_devices default host hdd admin:~ # ceph osd crush rule create-replicated fast_devices default host sdd Error EINVAL: device class sdd does not exist 2). Display the details of the new \u201cslow\u201d rule: admin:~ # ceph osd crush rule dump slow_devices { \"rule_id\": 2, \"rule_name\": \"slow_devices\", \"ruleset\": 2, \"type\": 1, \"min_size\": 1, \"max_size\": 10, \"steps\": [ { \"op\": \"take\", \"item\": -2, \"item_name\": \"default~hdd\" }, { \"op\": \"chooseleaf_firstn\", \"num\": 0, \"type\": \"host\" }, { \"op\": \"emit\" } ] }","title":"Task 5: Create CRUSH Map rules for different classes of devices"},{"location":"linux/SES/linux_ses_demo/#task-6-change-the-ruleset-used-by-a-pool","text":"1). Show which CRUSH Map Ruleset is being used by the cephfs_data pool: The rule should be listed as replicated_rule. admin:~ # ceph osd pool get cephfs_data crush_rule crush_rule: replicated_rule 2). Change the cephfs_data pool to use the new CRUSH Map ruleset that you created in the previous task. admin:~ # ceph osd pool set cephfs_data crush_rule better_ruleset set pool 2 crush_rule to better_ruleset 3). Verify that the rule has been changed by re-running the earlier command: admin:~ # ceph osd pool get cephfs_data crush_rule crush_rule: better_ruleset 4). In this demo cluster, making the cephfs_data pool use the \u201cbetter_ruleset\u201d will result in problems. (There\u2019s no rack for the CRUSH Map, and not enough nodes to accommodate the requirement for a large numbgr of PGs.) So change the setting back to the replicated_rule. admin:~ # ceph osd pool set cephfs_data crush_rule replicated_rule set pool 2 crush_rule to replicated_rule admin:~ # ceph osd pool get cephfs_data crush_rule crush_rule: replicated_rule Task 7: Create a CRUSH Map rule enhanced with an EC profile 1). Combine the benefits of Erasure Coding with a CRUSH Map rule: This will only work if you have already created an appropriate EC profile called usable_profile. In this demo you would have done in an earlier exercise. And in this demo you need to tie this ec_rule to the usable_profile, not the better_profile.Or else any pool that you create using the ec_rule will fail due to insufficient resources. admin:~ # ceph osd crush rule create-erasure ec_rule usable_profile Link the CRUSH map rule (ec_rule) to EC profile (usable_profile) created rule ec_rule at 3 P.S., The useable_profile was created by : admin:~ # ceph osd erasure-code-profile set usable_profile k=2 m=1 plugin=jerasure technique=reed_sol_van stripe_unit=4K crush-failure-domain=host 2). Display the details of the EC-enhanced CRUSH Map rule: See the added, extra \u201cop\u201d steps. You might also notice the different values for \u201ctype,\u201d \u201cmin_size,\u201d and \u201cmax_size\u201d than what you saw in the standard replicated rules. admin:~ # ceph osd crush rule dump ec_rule { \"rule_id\": 3, \"rule_name\": \"ec_rule\", \"ruleset\": 3, \"type\": 3, \"min_size\": 3, \"max_size\": 3, \"steps\": [ { \"op\": \"set_chooseleaf_tries\", \"num\": 5 }, { \"op\": \"set_choose_tries\", \"num\": 100 }, { \"op\": \"take\", \"item\": -1, \"item_name\": \"default\" }, { \"op\": \"chooseleaf_indep\", \"num\": 0, \"type\": \"host\" }, { \"op\": \"emit\" } ] } admin:~ # ceph osd crush rule ls replicated_rule better_ruleset slow_devices ec_rule admin:~ # ceph osd crush rule create-replicated better_ruleset default rack admin:~ # ceph osd crush rule create-replicated slow_devices default host hdd admin:~ # ceph osd crush rule create-erasure ec_rule usable_profile admin:~ # ceph osd crush rule dump replicated_rule { \"rule_id\": 0, \"rule_name\": \"replicated_rule\", \"ruleset\": 0, \"type\": 1, \"min_size\": 1, \"max_size\": 10, \"steps\": [ { \"op\": \"take\", \"item\": -1, \"item_name\": \"default\" }, { \"op\": \"chooseleaf_firstn\", \"num\": 0, \"type\": \"host\" }, { \"op\": \"emit\" } ] } admin:~ # ceph osd crush rule dump better_ruleset { \"rule_id\": 1, \"rule_name\": \"better_ruleset\", \"ruleset\": 1, \"type\": 1, \"min_size\": 1, \"max_size\": 10, \"steps\": [ { \"op\": \"take\", \"item\": -1, \"item_name\": \"default\" }, { \"op\": \"chooseleaf_firstn\", \"num\": 0, \"type\": \"rack\" }, { \"op\": \"emit\" } ] } admin:~ # ceph osd crush rule dump slow_devices { \"rule_id\": 2, \"rule_name\": \"slow_devices\", \"ruleset\": 2, \"type\": 1, \"min_size\": 1, \"max_size\": 10, \"steps\": [ { \"op\": \"take\", \"item\": -2, \"item_name\": \"default~hdd\" }, { \"op\": \"chooseleaf_firstn\", \"num\": 0, \"type\": \"host\" }, { \"op\": \"emit\" } ] } admin:~ # ceph osd pool osd pool stats {} osd pool scrub [...] osd pool deep-scrub [...] osd pool repair [...] osd pool force-recovery [...] osd pool force-backfill [...] osd pool cancel-force-recovery [...] osd pool cancel-force-backfill [...] osd pool autoscale-status osd pool mksnap admin:~ # ceph osd pool get size min_size pg_num pgp_num crush_rule Hashpspool Nodelete Nopgchange Nosizechange write_fadvise_dontneed Noscrub nodeep-scrub hit_set_type hit_set_period hit_set_count hit_set_fpp use_gmt_hitset target_max_objects target_max_bytes cache_target_dirty_ratio cache_target_dirty_high_ratio cache_target_full_ratio cache_min_flush_age cache_min_evict_age erasure_code_profile min_read_recency_for_promote All min_write_recency_for_promote fast_read hit_set_grade_decay_rate hit_set_search_last_n scrub_min_interval scrub_max_interval deep_scrub_interval recovery_priority recovery_op_priority scrub_priority compression_mode compression_algorithm compression_required_ratio compression_max_blob_size compression_min_blob_size csum_type csum_min_block csum_max_block allow_ec_overwrites fingerprint_algorithm pg_autoscale_mode pg_autoscale_bias pg_num_min target_size_bytes target_size_ratio","title":"Task 6: Change the ruleset used by a pool"},{"location":"linux/SES/linux_ses_demo/#214-investigate-bluestore","text":"","title":"2.1.4. Investigate BlueStore"},{"location":"linux/SES/linux_ses_demo/#task-1-explore-the-drive_groupsyml-configuration","text":"After deployment, the drive_groups.yml file is where the storage administrator defines the configuration of the cluster\u2019s storage devices. Note the \u201cdata_devices\u201d parameter. In this demo, \u201call\u201d storage devices are data devices for BlueStore. Note that there are no definitions for \u201cwal_devices\u201d or \u201cdb_devices.\u201d That\u2019s because in this demo environment we don\u2019t have any other \u201cfast\u201d devices that would be appropriate for these roles. Since BlueStore is the default, there is no definition of a \u201cformat\u201d for the devices. Otherwise, a \u201cFormat: bluestore\u201d key-value pair might exist to ensure that BlueStore is used. admin:~ # cd /srv/salt/ceph/configuration/files admin:/srv/salt/ceph/configuration/files # cat drive_groups.yml # default: <- just a name - can be anything # target: 'data*' <- must be resolvable by salt's targeting processor # data_devices: # size: 20G # db_devices: # size: 10G # rotational: 1 # allflash: # target: 'fast_nodes*' # data_devices: # size: 100G # db_devices: # size: 50G # rotational: 0 # This is the default configuration and # will create an OSD on all available drives default: target: 'data*' data_devices: all: true","title":"Task 1: Explore the drive_groups.yml configuration"},{"location":"linux/SES/linux_ses_demo/#task-2-examine-a-storage-hosts-storage-devices","text":"admin:~ # ssh data1 Last login: Tue Jan 5 18:06:40 2021 from 10.58.121.181 Should see 3 devices, which are named ceph LVM-type devices data1:~ # lsblk NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINT sda 8:0 0 8G 0 disk \u2514\u2500ceph--14c886af--269d--475f--8ee3--f5e4abbb222d-osd--data--38911b2d--f30a--4b09--9010--8dd6fad2fcc6 254:0 0 8G 0 lvm sdb 8:16 0 8G 0 disk \u2514\u2500ceph--9ec4a77a--5d67--4b21--be53--d7e9221082de-osd--data--00cb3dc6--c28b--41ae--95de--efb86da254da 254:1 0 8G 0 lvm sdc 8:32 0 8G 0 disk \u2514\u2500ceph--5eaea8a8--bb68--49dd--a1e3--b82c5464ab1f-osd--data--a4a05f70--53d9--41d4--a273--4f47a088968a 254:2 0 8G 0 lvm sr0 11:0 1 672M 0 rom vda 253:0 0 20G 0 disk \u251c\u2500vda1 253:1 0 8M 0 part \u251c\u2500vda2 253:2 0 18.4G 0 part / \u2514\u2500vda3 253:3 0 1.7G 0 part [SWAP] See the raw ceph devices data1:~ # ls -lad /dev/ceph* drwxr-xr-x 2 root root 60 Oct 5 13:15 /dev/ceph-14c886af-269d-475f-8ee3-f5e4abbb222d drwxr-xr-x 2 root root 60 Oct 5 13:16 /dev/ceph-5eaea8a8-bb68-49dd-a1e3-b82c5464ab1f drwxr-xr-x 2 root root 60 Oct 5 13:15 /dev/ceph-9ec4a77a-5d67-4b21-be53-d7e9221082de Dig down even farther by examining the content of one of the directories, see a symlink to an LVM device-mapper device. All the devices are tied together with LVM. Note that the name of the symlink is named osd-data- . data1:~ # ls -l /dev/ceph-14c886af-269d-475f-8ee3-f5e4abbb222d lrwxrwxrwx 1 ceph ceph 7 Oct 5 13:15 osd-data-38911b2d-f30a-4b09-9010-8dd6fad2fcc6 -> ../dm-0 data1:~ # l /dev/dm* brw-rw---- 1 ceph ceph 254, 0 Jan 5 18:10 /dev/dm-0 brw-rw---- 1 ceph ceph 254, 1 Jan 5 18:10 /dev/dm-1 brw-rw---- 1 ceph ceph 254, 2 Jan 5 18:10 /dev/dm-2","title":"Task 2: Examine a storage host\u2019s storage devices"},{"location":"linux/SES/linux_ses_demo/#task-3-examine-a-storage-hosts-osd-details","text":"data1:~ # cd /var/lib/ceph/ data1:/var/lib/ceph # ls -l drwxr-x--- 1 ceph ceph 0 Aug 24 22:03 bootstrap-mds drwxr-x--- 1 ceph ceph 0 Aug 24 22:03 bootstrap-mgr drwxr-x--- 1 ceph ceph 24 Oct 5 13:15 bootstrap-osd drwxr-x--- 1 ceph ceph 0 Aug 24 22:03 bootstrap-rbd drwxr-x--- 1 ceph ceph 0 Aug 24 22:03 bootstrap-rbd-mirror drwxr-x--- 1 ceph ceph 0 Aug 24 22:03 bootstrap-rgw drwxr-x--- 1 ceph ceph 12 Oct 5 09:04 crash drwxr-x--- 1 ceph ceph 0 Aug 24 22:03 mds drwxr-x--- 1 ceph ceph 0 Aug 24 22:03 mgr drwxr-x--- 1 ceph ceph 0 Aug 24 22:03 mon drwxr-x--- 1 ceph ceph 38 Oct 5 13:16 osd drwxr-x--- 1 ceph ceph 0 Aug 24 22:03 tmp See 3 different sub-directories, each representing the 3 different OSDs (ceph-2, ceph-6, ceph-10) that are running on this storage server data1:/var/lib/ceph # cd osd/ data1:/var/lib/ceph/osd # ls -l drwxrwxrwt 2 ceph ceph 320 Oct 5 13:16 ceph-10 drwxrwxrwt 2 ceph ceph 320 Oct 5 13:15 ceph-2 drwxrwxrwt 2 ceph ceph 320 Oct 5 13:16 ceph-6 See some functional files associated with the OSD and BlueStore. See a block file, which is a symlink to one of the ceph devices, which stores the raw objects for the OSD. data1:/var/lib/ceph/osd # cd ceph-2 data1:/var/lib/ceph/osd/ceph-2 # ls -l -rw-r--r-- 1 ceph ceph 400 Oct 5 13:15 activate.monmap lrwxrwxrwx 1 ceph ceph 92 Oct 5 13:15 block -> /dev/ceph-14c886af-269d-475f-8ee3-f5e4abbb222d/osd-data-38911b2d-f30a-4b09-9010-8dd6fad2fcc6 -rw------- 1 ceph ceph 2 Oct 5 13:15 bluefs -rw------- 1 ceph ceph 37 Oct 5 13:15 ceph_fsid -rw-r--r-- 1 ceph ceph 37 Oct 5 13:15 fsid -rw------- 1 ceph ceph 55 Oct 5 13:15 keyring -rw------- 1 ceph ceph 8 Oct 5 13:15 kv_backend -rw------- 1 ceph ceph 21 Oct 5 13:15 magic -rw------- 1 ceph ceph 4 Oct 5 13:15 mkfs_done -rw------- 1 ceph ceph 41 Oct 5 13:15 osd_key -rw------- 1 ceph ceph 6 Oct 5 13:15 ready -rw------- 1 ceph ceph 3 Oct 5 13:15 require_osd_release -rw------- 1 ceph ceph 10 Oct 5 13:15 type -rw------- 1 ceph ceph 2 Oct 5 13:15 whoami data1:/var/lib/ceph/osd/ceph-2 # cat ceph_fsid # The unique ID of this Ceph cluster 343ee7d3-232f-4c71-8216-1edbc55ac6e0 data1:/var/lib/ceph/osd/ceph-2 # cat fsid # The unique ID of this OSD 6df58ebc-dbfe-4822-9714-90212c06ea05 data1:/var/lib/ceph/osd/ceph-2 # cat keyring # The Ceph key for this OSD [osd.2] key = data1:/var/lib/ceph/osd/ceph-2 # cat ready # Indication of the readiness of this OSD ready data1:/var/lib/ceph/osd/ceph-2 # cat type # filestore or bluestore (in this case: bluestore) bluestore data1:/var/lib/ceph/osd/ceph-2 # cat whoami # The integer id of this OSD (in this case: 2) 2","title":"Task 3: Examine a storage host\u2019s OSD details"},{"location":"linux/SES/linux_ses_demo/#task-4-display-bluestore-information-using-ceph-bluestore-tool","text":"Show BlueStore metadata for osd.2: data1:/var/lib/ceph/osd/ceph-2 # ceph-bluestore-tool show-label --path /var/lib/ceph/osd/ceph-2 inferring bluefs devices from bluestore path { \"/var/lib/ceph/osd/ceph-2/block\": { \"osd_uuid\": \"6df58ebc-dbfe-4822-9714-90212c06ea05\", \"size\": 8585740288, \"btime\": \"2020-10-05 13:15:51.227799\", \"description\": \"main\", \"bluefs\": \"1\", \"ceph_fsid\": \"343ee7d3-232f-4c71-8216-1edbc55ac6e0\", \"kv_backend\": \"rocksdb\", \"magic\": \"ceph osd volume v026\", \"mkfs_done\": \"yes\", \"osd_key\": , \"ready\": \"ready\", \"require_osd_release\": \"14\", \"whoami\": \"2\" } Run a manual \u201cscrub\u201d on osd.7 using ceph-blestore-tool. (Received error, the tool won\u2019t allow you to do this while the OSD is running.) data1:/var/lib/ceph/osd/ceph-2 # ceph-bluestore-tool fsck --path /var/lib/ceph/osd/ceph-2 error from fsck: (11) Resource temporarily unavailable 2021-01-05 18:32:25.528 7f4abad6e180 -1 bluestore(/var/lib/ceph/osd/ceph-2) _lock_fsid failed to lock /var/lib/ceph/osd/ceph-2/fsid (is another ceph-osd still running?)(11) Resource temporarily unavailable Simulate that the OSD is down, shutdown the OSD: data1:/var/lib/ceph/osd/ceph-2 # systemctl stop ceph-osd@2.service Now run the \u201cfsck\u201d command again. This time the \u201cfsck\u201d has worked, with the output showing: \u201cfsck success\u201d data1:/var/lib/ceph/osd/ceph-2 # ceph-bluestore-tool fsck --path /var/lib/ceph/osd/ceph-2 fsck success Restart the OSD: data1:/var/lib/ceph/osd/ceph-2 # systemctl start ceph-osd@2.service data1:/var/lib/ceph/osd/ceph-2 # ceph-bluestore-tool show-label --path /var/lib/ceph/osd/ceph-2 inferring bluefs devices from bluestore path { \"/var/lib/ceph/osd/ceph-2/block\": { \"osd_uuid\": \"6df58ebc-dbfe-4822-9714-90212c06ea05\", \"size\": 8585740288, \"btime\": \"2020-10-05 13:15:51.227799\", \"description\": \"main\", \"bluefs\": \"1\", \"ceph_fsid\": \"343ee7d3-232f-4c71-8216-1edbc55ac6e0\", \"kv_backend\": \"rocksdb\", \"magic\": \"ceph osd volume v026\", \"mkfs_done\": \"yes\", \"osd_key\": , \"ready\": \"ready\", \"require_osd_release\": \"14\", \"whoami\": \"2\" } }","title":"Task 4: Display BlueStore information using ceph-bluestore-tool"},{"location":"linux/SES/linux_ses_demo/#22-common-day-1-tasks-using-the-cli","text":"Including ollowing topics in relation to the commandline: Users and Ceph Configuration Health commands Erasure Code Profiles CRUSH Map rules Pools Scrubbing OSDs and Placement Groups Manager modules The tell commands","title":"2.2. Common Day 1 Tasks Using the CLI"},{"location":"linux/SES/linux_ses_demo/#221-ceph-users-and-configuration","text":"","title":"2.2.1. Ceph Users and Configuration"},{"location":"linux/SES/linux_ses_demo/#task-1-view-the-current-user-keyrings","text":"Ceph keyrings are stored in below directory admin:~ # cd /etc/ceph/ admin:/etc/ceph # ls -l -rw------- 1 root root 151 Oct 5 13:13 ceph.client.admin.keyring -rw-r--r-- 1 root root 980 Oct 5 13:13 ceph.conf -rw-r--r-- 1 root root 92 Aug 24 22:03 rbdmap The value of 'key' is the key that\u2019s on the keyring. The admin keyring is \u201callow\u201ded all capabilities (permissions) to all services in the cluster, as expected. there are more than just client keys. admin:/etc/ceph # cat ceph.client.admin.keyring [client.admin] key = caps mds = \"allow *\" caps mon = \"allow *\" caps osd = \"allow *\" caps mgr = \"allow *\" Display the existing users with the \u201cauth\u201d command: Below two commands are equivalent admin:/etc/ceph # ceph -n client.admin -keyring=/etc/ceph/ceph.client.admin.keyring auth ls -- failed??? no valid command found admin:/etc/ceph # ceph auth ls installed auth entries: mds.mon1 key: caps: [mds] allow * caps: [mgr] allow profile mds caps: [mon] allow profile mds caps: [osd] allow rwx mds.mon2 key: caps: [mds] allow * caps: [mgr] allow profile mds caps: [mon] allow profile mds caps: [osd] allow rwx mds.mon3 key: caps: [mds] allow * caps: [mgr] allow profile mds caps: [mon] allow profile mds caps: [osd] allow rwx osd.0 key: caps: [mgr] allow profile osd caps: [mon] allow profile osd caps: [osd] allow * osd.1 key: caps: [mgr] allow profile osd caps: [mon] allow profile osd caps: [osd] allow * osd.10 key: caps: [mgr] allow profile osd caps: [mon] allow profile osd caps: [osd] allow * osd.11 key: caps: [mgr] allow profile osd caps: [mon] allow profile osd caps: [osd] allow * osd.2 key: caps: [mgr] allow profile osd caps: [mon] allow profile osd caps: [osd] allow * osd.3 key: caps: [mgr] allow profile osd caps: [mon] allow profile osd caps: [osd] allow * osd.4 key: caps: [mgr] allow profile osd caps: [mon] allow profile osd caps: [osd] allow * osd.5 key: caps: [mgr] allow profile osd caps: [mon] allow profile osd caps: [osd] allow * osd.6 key: caps: [mgr] allow profile osd caps: [mon] allow profile osd caps: [osd] allow * osd.7 key: caps: [mgr] allow profile osd caps: [mon] allow profile osd caps: [osd] allow * osd.8 key: caps: [mgr] allow profile osd caps: [mon] allow profile osd caps: [osd] allow * osd.9 key: caps: [mgr] allow profile osd caps: [mon] allow profile osd caps: [osd] allow * client.admin key: caps: [mds] allow * caps: [mgr] allow * caps: [mon] allow * caps: [osd] allow * client.bootstrap-mds key: caps: [mon] allow profile bootstrap-mds client.bootstrap-mgr key: caps: [mon] allow profile bootstrap-mgr client.bootstrap-osd key: caps: [mgr] allow r caps: [mon] allow profile bootstrap-osd client.bootstrap-rbd key: caps: [mon] allow profile bootstrap-rbd client.bootstrap-rbd-mirror key: caps: [mon] allow profile bootstrap-rbd-mirror client.bootstrap-rgw key: caps: [mon] allow profile bootstrap-rgw client.igw.mon2 key: caps: [mgr] allow r caps: [mon] allow * caps: [osd] allow * client.rgw.mon3 key: caps: [mgr] allow r caps: [mon] allow rwx caps: [osd] allow rwx client.storage key: caps: [mon] allow rw mgr.mon1 key: caps: [mds] allow * caps: [mon] allow profile mgr caps: [osd] allow *","title":"Task 1: View the current user keyrings"},{"location":"linux/SES/linux_ses_demo/#task-2-create-a-new-keyring-and-associated-user","text":"1). There are several different ways to create a new keyring and user. This is just one way. Create a new keyring and associated user named James . Remembgr that typically all new users will need read rights for the mon capability, and will need read/write rights for the osd capability, including a specification of rights to a pool. admin:/etc/ceph # ceph-authtool -g -n client.james --cap mon 'allow r' --cap osd 'allow rw pool=iscsi-images' -C /etc/ceph/ceph.client.james.keyring creating /etc/ceph/ceph.client.james.keyring admin:/etc/ceph # l total 16 drwxr-xr-x 1 root root 130 Jan 5 19:31 ./ drwxr-xr-x 1 root root 4392 Oct 5 13:03 ../ -rw------- 1 root root 151 Oct 5 13:13 ceph.client.admin.keyring -rw------- 1 root root 126 Jan 5 19:31 ceph.client.james.keyring -rw-r--r-- 1 root root 980 Oct 5 13:13 ceph.conf -rw-r--r-- 1 root root 92 Aug 24 22:03 rbdmap 2). Show the content of the newly created keyring: admin:/etc/ceph # cat ceph.client.james.keyring [client.james] key = caps mon = \"allow r\" caps osd = \"allow rw pool=iscsi-images\" 3). Officially add the new keyring to Ceph: admin:/etc/ceph # ceph auth add client.james -i /etc/ceph/ceph.client.james.keyring added key for client.james 4). Show the key information using the \u201cauth\u201d function: admin:/etc/ceph # ceph auth get client.james exported keyring for client.james [client.james] key = caps mon = \"allow r\" caps osd = \"allow rw pool=iscsi-images\"","title":"Task 2: Create a new keyring and associated user"},{"location":"linux/SES/linux_ses_demo/#task-3-create-a-client-key-for-rbd","text":"1). Change to the directory that contains the ceph keyrings. admin:~ # cd /etc/ceph/ 2). List the content of the directory: Although you see the admin users\u2019s keyring, ceph.client.admin.keyring, there is not yet a file that is appropriate for a specific application to use. Also note that the permissions on the keyring file are quite restrictive: 0600 admin:/etc/ceph # ls -l -rw------- 1 root root 151 Oct 5 13:13 ceph.client.admin.keyring -rw------- 1 root root 126 Jan 5 19:31 ceph.client.james.keyring -rw-r--r-- 1 root root 980 Oct 5 13:13 ceph.conf -rw-r--r-- 1 root root 92 Aug 24 22:03 rbdmap 3). Show the content of the admin user\u2019s keyring: You will use the value associated with the \u201ckey\u201d key to create a new file. Copy the \u201ckey\u201d value using your favorite method. admin:/etc/ceph # cat ceph.client.admin.keyring [client.admin] key = caps mds = \"allow *\" caps mon = \"allow *\" caps osd = \"allow *\" caps mgr = \"allow *\" 4). Open a new file for editing called admin.secret using your favorite editor (such as vi): The name of the file isn\u2019t very important, but naming it this way will help to identify its purpose: it\u2019s a secret key for the admin user. Note that there are many ways to do this. An alternative way is mentioned in the tip below that will do this in one step using grep and awk. admin:/etc/ceph # vi admin.secret 5). Paste the \u201ckey\u201d value into the new file. It will be the only content of the file. It will look like this (in fact it\u2019s probably exactly the same as this, if you\u2019re using the demo environment provided to you): admin:/etc/ceph # cat admin.secret 6). Save the file and exist out of the editor. 7). Change the permissions of the file so that no other user on the host can see the content of the file: admin:/etc/ceph # chmod 0600 admin.secret admin:/etc/ceph # l drwxr-xr-x 1 root root 154 Jan 5 20:03 ./ drwxr-xr-x 1 root root 4392 Oct 5 13:03 ../ -rw------- 1 root root 41 Jan 5 20:03 admin.secret -rw------- 1 root root 151 Oct 5 13:13 ceph.client.admin.keyring -rw------- 1 root root 126 Jan 5 19:31 ceph.client.james.keyring -rw-r--r-- 1 root root 980 Oct 5 13:13 ceph.conf -rw-r--r-- 1 root root 92 Aug 24 22:03 rbdmap Tip: An alternative way to create this key file is to simply use grep/awk together in one bash command, like this: admin:/etc/ceph # grep \"key =\" ceph.client.admin.keyring | awk -F\" = \" '{ print $2 }' admin:/etc/ceph # grep \"key =\" ceph.client.admin.keyring | awk -F\" = \" '{ print $2 }' > admin.secret admin:/etc/ceph # cat admin.secret ","title":"Task 3: Create a client key for RBD"},{"location":"linux/SES/linux_ses_demo/#task-4-view-the-ceph-master-configuration-file","text":"View the content of the file. The file is managed and controlled by DeepSea. The comment makes reference to the control files in the /srv/salt/ceph/configuration/ directory hierarchy. This is a very simple storage cluster. In a more diverse and sophisticated ceph cluster there may be more configuration settings defined. Although this exercise doesn\u2019t call out any more specific information about this configuration file, you may take a moment to consider the content of the file before finishing the task. admin:/etc/ceph # cat ceph.conf # DeepSea default configuration. Changes in this file will be overwritten on # package update. Include custom configuration fragments in # /srv/salt/ceph/configuration/files/ceph.conf.d/[global,osd,mon,mgr,mds,client].conf [global] fsid = 343ee7d3-232f-4c71-8216-1edbc55ac6e0 mon_initial_membgrs = mon1, mon2, mon3 mon_host = 10.58.121.186, 10.58.121.187, 10.58.121.188 auth_cluster_required = cephx auth_service_required = cephx auth_client_required = cephx public_network = 10.58.120.0/23 cluster_network = 10.58.120.0/23 ms_bind_msgr2 = false # enable old ceph health format in the json output. This fixes the # ceph_exporter. This option will only stay until the prometheus plugin takes # over mon_health_preluminous_compat = true mon health preluminous compat warning = false rbd default features = 3 [client.rgw.mon3] rgw frontends = \"beast port=80\" rgw dns name = mon3.sha.me.corp rgw enable usage log = true [osd] [mon] [mgr] [mds] [client] admin:/etc/ceph # ls -l /srv/salt/ceph/configuration/ drwxr-xr-x 1 salt salt 18 Oct 5 13:13 cache drwxr-xr-x 1 root root 38 Oct 5 09:04 check drwxr-xr-x 1 root root 74 Oct 5 09:04 create -rw-r--r-- 1 root root 217 May 14 2020 default-import.sls -rw-r--r-- 1 root root 222 May 14 2020 default.sls drwxr-xr-x 1 root root 276 Oct 5 12:55 files -rw-r--r-- 1 root root 74 May 14 2020 init.sls","title":"Task 4: View the Ceph master configuration file"},{"location":"linux/SES/linux_ses_demo/#222-run-the-ceph-health-commands","text":"Get overall health status admin:~ # ceph health HEALTH_OK admin:~ # ceph -s admin:~ # ceph status cluster: id: 343ee7d3-232f-4c71-8216-1edbc55ac6e0 health: HEALTH_OK services: mon: 3 daemons, quorum mon1,mon2,mon3 (age 9w) mgr: mon1(active, since 5w) mds: cephfs:1 {0=mon3=up:active} 2 up:standby osd: 12 osds: 12 up (since 98m), 12 in (since 3M) rgw: 1 daemon active (mon3) task status: scrub status: mds.mon3: idle data: pools: 7 pools, 208 pgs objects: 246 objects, 4.7 KiB usage: 14 GiB used, 82 GiB / 96 GiB avail pgs: 208 active+clean io: client: 852 B/s rd, 0 op/s rd, 0 op/s wr Run the \u201cstatus\u201d command for the monitors: admin:~ # ceph mon stat e1: 3 mons at { mon1=[v2:10.58.121.186:3300/0,v1:10.58.121.186:6789/0], mon2=[v2:10.58.121.187:3300/0,v1:10.58.121.187:6789/0], mon3=[v2:10.58.121.188:3300/0,v1:10.58.121.188:6789/0] }, election epoch 22, leader 0 mon1, quorum 0,1,2 mon1,mon2,mon3 Run the \u201cstatus\u201d command for the placement groups: admin:~ # ceph pg stat 208 pgs: 208 active+clean; 4.7 KiB data, 2.1 GiB used, 82 GiB / 96 GiB avail; 852 B/s rd, 0 op/s Run the ceph \u201cstatus\u201d command while watching for changes to the status: admin:~ # ceph -s --watch-debug cluster: id: 343ee7d3-232f-4c71-8216-1edbc55ac6e0 health: HEALTH_OK services: mon: 3 daemons, quorum mon1,mon2,mon3 (age 9w) mgr: mon1(active, since 5w) mds: cephfs:1 {0=mon3=up:active} 2 up:standby osd: 12 osds: 12 up (since 104m), 12 in (since 3M) rgw: 1 daemon active (mon3) task status: scrub status: mds.mon3: idle data: pools: 7 pools, 208 pgs objects: 246 objects, 4.7 KiB usage: 14 GiB used, 82 GiB / 96 GiB avail pgs: 208 active+clean io: client: 1.2 KiB/s rd, 1 op/s rd, 0 op/s wr 2021-01-05 20:20:53.947298 mgr.mon1 [DBG] pgmap v1597415: 208 pgs: 208 active+clean; 4.7 KiB data, 2.1 GiB used, 82 GiB / 96 GiB avail; 852 B/s rd, 0 op/s 2021-01-05 20:20:55.949294 mgr.mon1 [DBG] pgmap v1597416: 208 pgs: 208 active+clean; 4.7 KiB data, 2.1 GiB used, 82 GiB / 96 GiB avail; 1.2 KiB/s rd, 1 op/s .......","title":"2.2.2. Run the Ceph Health Commands"},{"location":"linux/SES/linux_ses_demo/#223-manipulate-pools","text":"","title":"2.2.3. Manipulate Pools"},{"location":"linux/SES/linux_ses_demo/#task-1-display-a-list-of-the-current-pools","text":"admin:~ # ceph osd pool ls iscsi-images cephfs_data cephfs_metadata .rgw.root default.rgw.control default.rgw.meta default.rgw.log admin:~ # ceph osd pool ls detail pool 1 'iscsi-images' replicated size 3 min_size 2 crush_rule 0 object_hash rjenkins pg_num 32 pgp_num 32 autoscale_mode on last_change 448 lfor 0/448/446 flags hashpspool stripe_width 0 application rbd pool 2 'cephfs_data' replicated size 3 min_size 2 crush_rule 0 object_hash rjenkins pg_num 32 pgp_num 32 last_change 1395 lfor 0/1374/1372 flags hashpspool stripe_width 0 application cephfs pool 3 'cephfs_metadata' replicated size 3 min_size 2 crush_rule 0 object_hash rjenkins pg_num 16 pgp_num 16 last_change 1385 lfor 0/975/973 flags hashpspool stripe_width 0 pg_autoscale_bias 4 pg_num_min 16 recovery_priority 5 application cephfs pool 4 '.rgw.root' replicated size 3 min_size 2 crush_rule 0 object_hash rjenkins pg_num 32 pgp_num 32 autoscale_mode warn last_change 31 flags hashpspool stripe_width 0 application rgw pool 5 'default.rgw.control' replicated size 3 min_size 2 crush_rule 0 object_hash rjenkins pg_num 32 pgp_num 32 autoscale_mode warn last_change 33 flags hashpspool stripe_width 0 application rgw pool 6 'default.rgw.meta' replicated size 3 min_size 2 crush_rule 0 object_hash rjenkins pg_num 32 pgp_num 32 autoscale_mode warn last_change 35 flags hashpspool stripe_width 0 application rgw pool 7 'default.rgw.log' replicated size 3 min_size 2 crush_rule 0 object_hash rjenkins pg_num 32 pgp_num 32 autoscale_mode warn last_change 37 flags hashpspool stripe_width 0 application rgw List pools with their index numbgr. Note how the index numbgr matches the index numbgr of the detail listing above. admin:~ # ceph osd lspools 1 iscsi-images 2 cephfs_data 3 cephfs_metadata 4 .rgw.root 5 default.rgw.control 6 default.rgw.meta 7 default.rgw.log","title":"Task 1: Display a list of the current pools"},{"location":"linux/SES/linux_ses_demo/#task-2-display-the-usage-data-and-stats-of-the-current-pools","text":"Display pool usages. Note again index \u201cID\u201d for the pool. admin:~ # ceph df RAW STORAGE: CLASS SIZE AVAIL USED RAW USED %RAW USED hdd 96 GiB 82 GiB 2.1 GiB 14 GiB 14.81 TOTAL 96 GiB 82 GiB 2.1 GiB 14 GiB 14.81 POOLS: POOL ID STORED OBJECTS USED %USED MAX AVAIL iscsi-images 1 389 B 2 192 KiB 0 25 GiB cephfs_data 2 0 B 0 0 B 0 25 GiB cephfs_metadata 3 7.2 KiB 48 1.5 MiB 0 25 GiB .rgw.root 4 1.2 KiB 4 768 KiB 0 25 GiB default.rgw.control 5 0 B 8 0 B 0 25 GiB default.rgw.meta 6 381 B 3 576 KiB 0 25 GiB default.rgw.log 7 35 KiB 208 35 KiB 0 25 GiB admin:~ # ceph df detail RAW STORAGE: CLASS SIZE AVAIL USED RAW USED %RAW USED hdd 96 GiB 82 GiB 2.1 GiB 14 GiB 14.81 TOTAL 96 GiB 82 GiB 2.1 GiB 14 GiB 14.81 POOLS: POOL ID STORED OBJECTS USED %USED MAX AVAIL QUOTA OBJECTS QUOTA BYTES DIRTY USED COMPR UNDER COMPR iscsi-images 1 389 B 2 192 KiB 0 25 GiB N/A N/A 2 0 B 0 B cephfs_data 2 0 B 0 0 B 0 25 GiB N/A N/A 0 0 B 0 B cephfs_metadata 3 7.2 KiB 48 1.5 MiB 0 25 GiB N/A N/A 48 0 B 0 B .rgw.root 4 1.2 KiB 4 768 KiB 0 25 GiB N/A N/A 4 0 B 0 B default.rgw.control 5 0 B 8 0 B 0 25 GiB N/A N/A 8 0 B 0 B default.rgw.meta 6 381 B 3 576 KiB 0 25 GiB N/A N/A 3 0 B 0 B default.rgw.log 7 35 KiB 208 35 KiB 0 25 GiB N/A N/A 208 0 B 0 B Display pool usages using rados command admin:~ # rados df POOL_NAME USED OBJECTS CLONES COPIES MISSING_ON_PRIMARY UNFOUND DEGRADED RD_OPS RD WR_OPS WR USED COMPR UNDER COMPR .rgw.root 768 KiB 4 0 12 0 0 0 40 40 KiB 4 4 KiB 0 B 0 B cephfs_data 0 B 0 0 0 0 0 0 0 0 B 0 0 B 0 B 0 B cephfs_metadata 1.5 MiB 48 0 144 0 0 0 0 0 B 111 42 KiB 0 B 0 B default.rgw.control 0 B 8 0 24 0 0 0 0 0 B 0 0 B 0 B 0 B default.rgw.log 35 KiB 208 0 624 0 0 0 5919671 5.6 GiB 3945118 946 KiB 0 B 0 B default.rgw.meta 576 KiB 3 0 9 0 0 0 38 28 KiB 4 3 KiB 0 B 0 B iscsi-images 192 KiB 2 0 6 0 0 0 4184657 4.0 GiB 8 2 KiB 0 B 0 B total_objects 246 total_used 14 GiB total_avail 82 GiB total_space 96 GiB Show the statistics of the pools: admin:~ # ceph osd pool stats pool iscsi-images id 1 client io 1.2 KiB/s rd, 1 op/s rd, 0 op/s wr pool cephfs_data id 2 nothing is going on pool cephfs_metadata id 3 nothing is going on pool .rgw.root id 4 nothing is going on pool default.rgw.control id 5 nothing is going on pool default.rgw.meta id 6 nothing is going on pool default.rgw.log id 7 nothing is going on Show only the statistics about a specific pool: admin:~ # ceph osd pool stats .rgw.root pool .rgw.root id 4 nothing is going on Show which CRUSH Map ruleset was used to create the .rgw.root pool: admin:~ # ceph osd pool get .rgw.root crush_rule crush_rule: replicated_rule Show the list of all the attributes of a pool that can be queried: admin:~ # ceph osd pool get .rgw.root size min_size pg_num pgp_num crush_rule Hashpspool Nodelete Nopgchange Nosizechange write_fadvise_dontneed noscrub|nodeep-scrub hit_set_type hit_set_period hit_set_count hit_set_fpp use_gmt_hitset target_max_objects target_max_bytes cache_target_dirty_ratio cache_target_dirty_high_ratio cache_target_full_ratio cache_min_flush_age cache_min_evict_age erasure_code_profile min_read_recency_for_promote all|min_write_recency_for_promote fast_read|hit_set_grade_decay_rate hit_set_search_last_n scrub_min_interval scrub_max_interval deep_scrub_interval recovery_priority recovery_op_priority scrub_priority compression_mode compression_algorithm compression_required_ratio compression_max_blob_size compression_min_blob_size csum_type|csum_min_block csum_max_block allow_ec_overwrites fingerprint_algorithm pg_autoscale_mode pg_autoscale_bias pg_num_min target_size_bytes target_size_ratio","title":"Task 2: Display the usage data and stats of the current pools"},{"location":"linux/SES/linux_ses_demo/#task-3-create-two-new-pools-one-replicated-one-ec","text":"1). Create a new replicated pool that will be used for storing block data for RBD. Use the standard replicated_ruleset CRUSH Map: It would be tempting to the use the better_ruleset, but this demo environment doesn\u2019t have enough resources for that. This is a demo environment, so the PG numbgrs will be low. In your production environments, be sure to assign an appropriately high numbgr, or use the pg_autoscaler manager module. admin:~ # ceph osd pool create rbd_pool 4 4 replicated replicated_rule pool 'rbd_pool' created 2). Tell the cluster that you expect to have this new rbd_pool to use 50% of the total capacity: admin:~ # ceph osd pool set rbd_pool target_size_ratio .5 set pool 8 target_size_ratio to .5 3). Create a new EC pool that will be used for storing RGW buckets and objects. Use the usable_profile Erasure Code profile that was created in an earlier exercise. And use the ec_rule CRUSH Map ruleset that was created in an earlier exercise: admin:~ # ceph osd pool create bucket_pool 4 4 erasure usable_profile ec_rule pool 'bucket_pool' created 4). Tell the cluster that you expect to have this new bucket_pool to use 100GB of data: POOL_TARGET_SIZE_BYTES_OVERCOMMITTED admin:~ # ceph osd pool set bucket_pool target_size_bytes 100000000000 set pool 9 target_size_bytes to 100000000000 5). Enable the PG Autoscaler feature on the two new pools, to ensure that we have an appropriate assignment of placement groups in the demo cluster: This presumes that you completed an earlier exercise that enable the pg_autoscaler manager module. admin:~ # ceph osd pool set bucket_pool pg_autoscale_mode on set pool 9 pg_autoscale_mode to on admin:~ # ceph osd pool set rbd_pool pg_autoscale_mode on set pool 8 pg_autoscale_mode to on 6). Again display a list of all the pools, which will now include the two new pools that you\u2019ve just created: Notice in the detail listing that the two new pools don\u2019t have an application attribute assigned to them. admin:~ # ceph osd lspools 1 iscsi-images 2 cephfs_data 3 cephfs_metadata 4 .rgw.root 5 default.rgw.control 6 default.rgw.meta 7 default.rgw.log 8 rbd_pool 9 bucket_pool admin:~ # ceph osd pool ls detail pool 1 'iscsi-images' replicated size 3 min_size 2 crush_rule 0 object_hash rjenkins pg_num 32 pgp_num 32 autoscale_mode on last_change 448 lfor 0/448/446 flags hashpspool stripe_width 0 application rbd pool 2 'cephfs_data' replicated size 3 min_size 2 crush_rule 0 object_hash rjenkins pg_num 32 pgp_num 32 last_change 1395 lfor 0/1374/1372 flags hashpspool stripe_width 0 application cephfs pool 3 'cephfs_metadata' replicated size 3 min_size 2 crush_rule 0 object_hash rjenkins pg_num 16 pgp_num 16 last_change 1385 lfor 0/975/973 flags hashpspool stripe_width 0 pg_autoscale_bias 4 pg_num_min 16 recovery_priority 5 application cephfs pool 4 '.rgw.root' replicated size 3 min_size 2 crush_rule 0 object_hash rjenkins pg_num 32 pgp_num 32 autoscale_mode warn last_change 31 flags hashpspool stripe_width 0 application rgw pool 5 'default.rgw.control' replicated size 3 min_size 2 crush_rule 0 object_hash rjenkins pg_num 32 pgp_num 32 autoscale_mode warn last_change 33 flags hashpspool stripe_width 0 application rgw pool 6 'default.rgw.meta' replicated size 3 min_size 2 crush_rule 0 object_hash rjenkins pg_num 32 pgp_num 32 autoscale_mode warn last_change 35 flags hashpspool stripe_width 0 application rgw pool 7 'default.rgw.log' replicated size 3 min_size 2 crush_rule 0 object_hash rjenkins pg_num 32 pgp_num 32 autoscale_mode warn last_change 37 flags hashpspool stripe_width 0 application rgw pool 8 'rbd_pool' replicated size 3 min_size 2 crush_rule 0 object_hash rjenkins pg_num 32 pgp_num 32 autoscale_mode on last_change 1415 lfor 0/0/1413 flags hashpspool stripe_width 0 target_size_ratio 0.5 pool 9 'bucket_pool' erasure size 3 min_size 2 crush_rule 3 object_hash rjenkins pg_num 4 pgp_num 4 autoscale_mode on last_change 1410 flags hashpspool stripe_width 8192 target_size_bytes 100000000000 7). Check the pg_autoscale status, particularly to see a comparison of how much raw space is being consumed by the two pools: See that the RATE column for all of the replicated pools shows the value of 3.0, while the value for the bucket_pool \u2013 which is an EC pool \u2013 is 1.5. The EC pool, with a K+M of 2+1 consumes considerably less raw storage space. See the TARGET RATIO for the rbd_pool. Notice that the autoscaler has automatically adjusted the numbgr PGs assigned to rbd_pool from \u201c4\u201d to \u201c128\u201d because you told the cluster to have the pool use 50% of the capacity. See the TARGET SIZE for the bucket_pool, roughly 100GB. But the cluster may not have changed the PG_NUM value yet. The autoscaler will adjust the numbgr of PGs gradually, so as not to disrupt the performance too dramatically. While you\u2019re here, you might also notice the RAW CAPACITY column. All pools are expecting to divide the cluster space equally, even though you\u2019ve explicitly told the cluster that rbd_pool and bucket_pool will deviate from that even division. admin:~ # ceph osd pool autoscale-status POOL SIZE TARGET SIZE RATE RAW CAPACITY RATIO TARGET RATIO EFFECTIVE RATIO BIAS PG_NUM NEW PG_NUM AUTOSCALE iscsi-images 389 3.0 98256M 0.0000 1.0 32 on cephfs_data 0 3.0 98256M 0.0000 1.0 32 off cephfs_metadata 7412 3.0 98256M 0.0000 4.0 16 off .rgw.root 1245 3.0 98256M 0.0000 1.0 32 warn default.rgw.control 0 3.0 98256M 0.0000 1.0 32 warn default.rgw.meta 381 3.0 98256M 0.0000 1.0 32 warn default.rgw.log 35900 3.0 98256M 0.0000 1.0 32 warn rbd_pool 0 3.0 98256M 0.0000 0.5000 1.0 32 on bucket_pool 0 95367M 1.5 98256M 1.4559 1.0 4 on","title":"Task 3: Create two new pools, one replicated, one EC"},{"location":"linux/SES/linux_ses_demo/#task-4-assign-an-application-to-the-two-new-pools","text":"1). Assign the rbd application to the new rbd_pool that you created in the previous task: admin:~ # ceph osd pool application enable rbd_pool rbd enabled application 'rbd' on pool 'rbd_pool' 2). Instruct the cluster to prepare the new rbd_pool for storing block device images: admin:~ # rbd pool init rbd_pool 3). Assign the rgw application to the new bucket_pool that you created in the previous task: admin:~ # ceph osd pool application enable bucket_pool rgw enabled application 'rgw' on pool 'bucket_pool' 4). Display a list of all the pools again, this time noticing that the application attribute is set on the two new pools. admin:~ # ceph osd lspools 1 iscsi-images 2 cephfs_data 3 cephfs_metadata 4 .rgw.root 5 default.rgw.control 6 default.rgw.meta 7 default.rgw.log 8 rbd_pool 9 bucket_pool admin:~ # ceph osd pool ls detail pool 1 'iscsi-images' replicated size 3 min_size 2 crush_rule 0 object_hash rjenkins pg_num 32 pgp_num 32 autoscale_mode on last_change 448 lfor 0/448/446 flags hashpspool stripe_width 0 application rbd pool 2 'cephfs_data' replicated size 3 min_size 2 crush_rule 0 object_hash rjenkins pg_num 32 pgp_num 32 last_change 1395 lfor 0/1374/1372 flags hashpspool stripe_width 0 application cephfs pool 3 'cephfs_metadata' replicated size 3 min_size 2 crush_rule 0 object_hash rjenkins pg_num 16 pgp_num 16 last_change 1385 lfor 0/975/973 flags hashpspool stripe_width 0 pg_autoscale_bias 4 pg_num_min 16 recovery_priority 5 application cephfs pool 4 '.rgw.root' replicated size 3 min_size 2 crush_rule 0 object_hash rjenkins pg_num 32 pgp_num 32 autoscale_mode warn last_change 31 flags hashpspool stripe_width 0 application rgw pool 5 'default.rgw.control' replicated size 3 min_size 2 crush_rule 0 object_hash rjenkins pg_num 32 pgp_num 32 autoscale_mode warn last_change 33 flags hashpspool stripe_width 0 application rgw pool 6 'default.rgw.meta' replicated size 3 min_size 2 crush_rule 0 object_hash rjenkins pg_num 32 pgp_num 32 autoscale_mode warn last_change 35 flags hashpspool stripe_width 0 application rgw pool 7 'default.rgw.log' replicated size 3 min_size 2 crush_rule 0 object_hash rjenkins pg_num 32 pgp_num 32 autoscale_mode warn last_change 37 flags hashpspool stripe_width 0 application rgw pool 8 'rbd_pool' replicated size 3 min_size 2 crush_rule 0 object_hash rjenkins pg_num 32 pgp_num 32 autoscale_mode on last_change 1420 lfor 0/0/1413 flags hashpspool,selfmanaged_snaps stripe_width 0 target_size_ratio 0.5 application rbd removed_snaps [1~3] pool 9 'bucket_pool' erasure size 3 min_size 2 crush_rule 3 object_hash rjenkins pg_num 4 pgp_num 4 autoscale_mode on last_change 1422 flags hashpspool stripe_width 8192 target_size_bytes 100000000000 application rgw 5). Another way to display which application is assigned to a pool is: admin:~ # ceph osd pool application get bucket_pool { \"rgw\": {} } admin:~ # ceph osd pool application get rbd_pool { \"rbd\": {} }","title":"Task 4: Assign an application to the two new pools"},{"location":"linux/SES/linux_ses_demo/#task-5-manage-snapshots-of-the-new-rgw-bucket-pool","text":"1). Display a list of the snapshots that exist of the bucket_pool that you created in the previous task: The output show that there are \u201c0 snaps.\u201d Right, it is a little funny that you only list the snapshots with rados command; no such functionality exists with the ceph osd pool command. admin:~ # rados -p bucket_pool lssnap 0 snaps 2). Take (make) a snapshot of the rbd_pool: admin:~ # ceph osd pool mksnap bucket_pool brand_new_pool_snapshot created pool bucket_pool snap brand_new_pool_snapshot 3). Display the list of the snapshots again: admin:~ # rados -p bucket_pool lssnap 1 brand_new_pool_snapshot 2021.01.05 22:23:23 1 snaps 4). Remove the snapshot: admin:~ # ceph osd pool rmsnap bucket_pool brand_new_pool_snapshot removed pool bucket_pool snap brand_new_pool_snapshot 5). Display the list of the snapshots again: admin:~ # rados -p bucket_pool lssnap 0 snaps","title":"Task 5: Manage snapshots of the new RGW bucket pool"},{"location":"linux/SES/linux_ses_demo/#224-maintain-consistency-of-data-with-scrub-and-repair","text":"Scrubbing is like \u201cfsck,\u201d which ensures that OSDs have durable, consistent data. Most of the scrubbing of OSDs happens automatically on a periodic basis.","title":"2.2.4. Maintain consistency of data with Scrub and Repair"},{"location":"linux/SES/linux_ses_demo/#task-1-display-a-few-of-the-scrub-settings","text":"1). Show the possible configuration settings related to scrub: If you simply grep for \u201cscrub\u201d you\u2019ll get more than you really want; there are some mon_scrub settings that aren\u2019t related to this exercise. admin:~ # ceph config ls | grep osd_scrub osd_scrub_invalid_stats osd_scrub_during_recovery osd_scrub_begin_hour osd_scrub_end_hour osd_scrub_begin_week_day osd_scrub_end_week_day osd_scrub_load_threshold osd_scrub_min_interval osd_scrub_max_interval osd_scrub_interval_randomize_ratio osd_scrub_backoff_ratio osd_scrub_chunk_min osd_scrub_chunk_max osd_scrub_sleep osd_scrub_auto_repair osd_scrub_auto_repair_num_errors osd_scrub_max_preemptions osd_scrub_priority osd_scrub_cost admin:~ # ceph config ls | grep osd_deep_scrub osd_deep_scrub_interval osd_deep_scrub_randomize_ratio osd_deep_scrub_stride osd_deep_scrub_keys osd_deep_scrub_update_digest_min_age osd_deep_scrub_large_omap_object_key_threshold osd_deep_scrub_large_omap_object_value_sum_threshold admin:~ # ceph config ls | grep scrub mon_warn_pg_not_scrubbed_ratio mon_warn_pg_not_deep_scrubbed_ratio mon_scrub_interval mon_scrub_timeout mon_scrub_max_keys mon_scrub_inject_crc_mismatch mon_scrub_inject_missing_keys osd_op_queue_mclock_scrub_res osd_op_queue_mclock_scrub_wgt osd_op_queue_mclock_scrub_lim osd_scrub_invalid_stats osd_max_scrubs osd_scrub_during_recovery osd_scrub_begin_hour osd_scrub_end_hour osd_scrub_begin_week_day osd_scrub_end_week_day osd_scrub_load_threshold osd_scrub_min_interval osd_scrub_max_interval osd_scrub_interval_randomize_ratio osd_scrub_backoff_ratio osd_scrub_chunk_min osd_scrub_chunk_max osd_scrub_sleep osd_scrub_auto_repair osd_scrub_auto_repair_num_errors osd_scrub_max_preemptions osd_deep_scrub_interval osd_deep_scrub_randomize_ratio osd_deep_scrub_stride osd_deep_scrub_keys osd_deep_scrub_update_digest_min_age osd_deep_scrub_large_omap_object_key_threshold osd_deep_scrub_large_omap_object_value_sum_threshold osd_debug_deep_scrub_sleep osd_scrub_priority osd_scrub_cost osd_requested_scrub_priority mds_max_scrub_ops_in_progress 2). Get the value of a few of the different scrub schedule settings: Note that \u201c0\u201d and \u201c24\u201d are the same setting. admin:~ # ceph config get osd.* osd_scrub_begin_hour 0 admin:~ # ceph config get osd.* osd_scrub_end_hour 24 3). Get the value of the scrub and repair settings: The \u201cauto repair\u201d feature is turned off, and the maximum numbgr of errors that \u201cauto repair\u201d would automatically repair is 5. admin:~ # ceph config get osd.* osd_scrub_auto_repair false admin:~ # ceph config get osd.* osd_scrub_auto_repair_num_errors 5","title":"Task 1: Display a few of the Scrub settings"},{"location":"linux/SES/linux_ses_demo/#task-2-change-the-scrub-settings-in-cephconf","text":"1). Display the ceph.conf, and verify that the file doesn\u2019t have any settings defined yet that are related to scrub. The settings would be located in the [global] section of the file: # DeepSea default configuration. Changes in this file will be overwritten on # package update. Include custom configuration fragments in # /srv/salt/ceph/configuration/files/ceph.conf.d/[global,osd,mon,mgr,mds,client].conf [global] fsid = 343ee7d3-232f-4c71-8216-1edbc55ac6e0 mon_initial_membgrs = mon1, mon2, mon3 mon_host = 10.58.121.186, 10.58.121.187, 10.58.121.188 auth_cluster_required = cephx auth_service_required = cephx auth_client_required = cephx public_network = 10.58.120.0/23 cluster_network = 10.58.120.0/23 ms_bind_msgr2 = false # enable old ceph health format in the json output. This fixes the # ceph_exporter. This option will only stay until the prometheus plugin takes # over mon_health_preluminous_compat = true mon health preluminous compat warning = false rbd default features = 3 [client.rgw.mon3] rgw frontends = \"beast port=80\" rgw dns name = mon3.sha.me.corp rgw enable usage log = true [osd] [mon] [mgr] [mds] [client] 2). Change to the Salt File Server directory that will have Salt control the master ceph.conf configuration file: admin:~ # cd /srv/salt/ceph/configuration/files/ceph.conf.d/ 3). List the content of the directory: The directory is empty. (Well, there is a README, but no other functional files.) admin:/srv/salt/ceph/configuration/files/ceph.conf.d # ls -l -rw-r--r-- 1 root root 1989 May 14 2020 README 4). Create and edit a new file called global.conf. You don\u2019t have to use vi, but this step uses vi as one way of doing it: Be sure that you spell everything correctly, including the absence of \u201c_\u201d characters; there are spaces. Save the file and exit out of the editor. admin:/srv/salt/ceph/configuration/files/ceph.conf.d # vi global.conf Add the following content to the file: osd scrub begin hour = 23 osd scrub end hour = 5 osd scrub auto repair = True osd scrub auto repair num errors = 10 5). Use DeepSea (Salt) to stage the file properly in Salt\u2019s File Server on the Salt Master (admin): admin:/srv/salt/ceph/configuration/files/ceph.conf.d # salt admin* state.apply ceph.configuration.create admin.sha.me.corp: Name: /var/cache/salt/minion/files/base/ceph/configuration - Function: file.absent - Result: Changed Started: - 22:42:34.900173 Duration: 20.891 ms Name: /srv/salt/ceph/configuration/cache/ceph.conf - Function: file.managed - Result: Changed Started: - 22:42:34.921454 Duration: 8576.516 ms Name: find /var/cache/salt/master/jobs -user root -exec chown salt:salt {} ';' - Function: cmd.run - Result: Changed Started: - 22:42:43.535022 Duration: 71.957 ms Summary for admin.sha.me.corp ------------ Succeeded: 3 (changed=3) Failed: 0 ------------ Total states run: 3 Total run time: 8.669 s 6). Using DeepSea (Salt), distribute the new ceph.conf configuration settings to all the nodes in the cluster: admin:/srv/salt/ceph/configuration/files/ceph.conf.d # salt \\* state.apply ceph.configuration mon3.sha.me.corp: Name: /etc/ceph/ceph.conf - Function: file.managed - Result: Changed Started: - 22:44:07.986661 Duration: 101.977 ms Summary for mon3.sha.me.corp ------------ Succeeded: 1 (changed=1) Failed: 0 ------------ Total states run: 1 Total run time: 101.977 ms mon1.sha.me.corp: Name: /etc/ceph/ceph.conf - Function: file.managed - Result: Changed Started: - 22:44:08.012479 Duration: 108.888 ms Summary for mon1.sha.me.corp ------------ Succeeded: 1 (changed=1) Failed: 0 ------------ Total states run: 1 Total run time: 108.888 ms data3.sha.me.corp: Name: /etc/ceph/ceph.conf - Function: file.managed - Result: Changed Started: - 22:44:08.052247 Duration: 98.681 ms Summary for data3.sha.me.corp ------------ Succeeded: 1 (changed=1) Failed: 0 ------------ Total states run: 1 Total run time: 98.681 ms admin.sha.me.corp: Name: /etc/ceph/ceph.conf - Function: file.managed - Result: Changed Started: - 22:44:08.072402 Duration: 97.231 ms Summary for admin.sha.me.corp ------------ Succeeded: 1 (changed=1) Failed: 0 ------------ Total states run: 1 Total run time: 97.231 ms data1.sha.me.corp: Name: /etc/ceph/ceph.conf - Function: file.managed - Result: Changed Started: - 22:44:08.076279 Duration: 104.169 ms Summary for data1.sha.me.corp ------------ Succeeded: 1 (changed=1) Failed: 0 ------------ Total states run: 1 Total run time: 104.169 ms data4.sha.me.corp: Name: /etc/ceph/ceph.conf - Function: file.managed - Result: Changed Started: - 22:44:08.081635 Duration: 105.13 ms Summary for data4.sha.me.corp ------------ Succeeded: 1 (changed=1) Failed: 0 ------------ Total states run: 1 Total run time: 105.130 ms mon2.sha.me.corp: Name: /etc/ceph/ceph.conf - Function: file.managed - Result: Changed Started: - 22:44:08.155758 Duration: 105.004 ms Summary for mon2.sha.me.corp ------------ Succeeded: 1 (changed=1) Failed: 0 ------------ Total states run: 1 Total run time: 105.004 ms data2.sha.me.corp: Name: /etc/ceph/ceph.conf - Function: file.managed - Result: Changed Started: - 22:44:08.252200 Duration: 109.552 ms Summary for data2.sha.me.corp ------------ Succeeded: 1 (changed=1) Failed: 0 ------------ Total states run: 1 Total run time: 109.552 ms 7). Verify that the new ceph.conf settings have been put into place on the admin node: admin:/srv/salt/ceph/configuration/files/ceph.conf.d # cat /etc/ceph/ceph.conf # DeepSea default configuration. Changes in this file will be overwritten on # package update. Include custom configuration fragments in # /srv/salt/ceph/configuration/files/ceph.conf.d/[global,osd,mon,mgr,mds,client].conf [global] fsid = 343ee7d3-232f-4c71-8216-1edbc55ac6e0 mon_initial_membgrs = mon1, mon2, mon3 mon_host = 10.58.121.188, 10.58.121.187, 10.58.121.186 auth_cluster_required = cephx auth_service_required = cephx auth_client_required = cephx public_network = 10.58.120.0/23 cluster_network = 10.58.120.0/23 ms_bind_msgr2 = false # enable old ceph health format in the json output. This fixes the # ceph_exporter. This option will only stay until the prometheus plugin takes # over mon_health_preluminous_compat = true mon health preluminous compat warning = false rbd default features = 3 osd scrub begin hour = 23 osd scrub end hour = 5 osd scrub auto repair = True osd scrub auto repair num errors = 10 [client.rgw.mon3] rgw frontends = \"beast port=80\" rgw dns name = mon3.sha.me.corp rgw enable usage log = true [osd] [mon] [mgr] [mds] [client] 8). Also verify that other minions in the cluster have also received the updated configuration file, such as on the mon1 and data2 nodes: admin:/srv/salt/ceph/configuration/files/ceph.conf.d # ssh mon1 cat /etc/ceph/ceph.conf # DeepSea default configuration. Changes in this file will be overwritten on # package update. Include custom configuration fragments in # /srv/salt/ceph/configuration/files/ceph.conf.d/[global,osd,mon,mgr,mds,client].conf [global] fsid = 343ee7d3-232f-4c71-8216-1edbc55ac6e0 mon_initial_membgrs = mon1, mon2, mon3 mon_host = 10.58.121.188, 10.58.121.187, 10.58.121.186 auth_cluster_required = cephx auth_service_required = cephx auth_client_required = cephx public_network = 10.58.120.0/23 cluster_network = 10.58.120.0/23 ms_bind_msgr2 = false # enable old ceph health format in the json output. This fixes the # ceph_exporter. This option will only stay until the prometheus plugin takes # over mon_health_preluminous_compat = true mon health preluminous compat warning = false rbd default features = 3 osd scrub begin hour = 23 osd scrub end hour = 5 osd scrub auto repair = True osd scrub auto repair num errors = 10 [client.rgw.mon3] rgw frontends = \"beast port=80\" rgw dns name = mon3.sha.me.corp rgw enable usage log = true [osd] [mon] [mgr] [mds] [client] admin:/srv/salt/ceph/configuration/files/ceph.conf.d # ssh data1 cat /etc/ceph/ceph.conf # DeepSea default configuration. Changes in this file will be overwritten on # package update. Include custom configuration fragments in # /srv/salt/ceph/configuration/files/ceph.conf.d/[global,osd,mon,mgr,mds,client].conf [global] fsid = 343ee7d3-232f-4c71-8216-1edbc55ac6e0 mon_initial_membgrs = mon1, mon2, mon3 mon_host = 10.58.121.188, 10.58.121.187, 10.58.121.186 auth_cluster_required = cephx auth_service_required = cephx auth_client_required = cephx public_network = 10.58.120.0/23 cluster_network = 10.58.120.0/23 ms_bind_msgr2 = false # enable old ceph health format in the json output. This fixes the # ceph_exporter. This option will only stay until the prometheus plugin takes # over mon_health_preluminous_compat = true mon health preluminous compat warning = false rbd default features = 3 osd scrub begin hour = 23 osd scrub end hour = 5 osd scrub auto repair = True osd scrub auto repair num errors = 10 [client.rgw.mon3] rgw frontends = \"beast port=80\" rgw dns name = mon3.sha.me.corp rgw enable usage log = true [osd] [mon] [mgr] [mds] [client] 9). Apply the settings of the ceph.conf file to appropriate nodes in the cluster: admin:/srv/salt/ceph/configuration/files/ceph.conf.d # ceph config assimilate-conf -i /etc/ceph/ceph.conf [global] fsid = 343ee7d3-232f-4c71-8216-1edbc55ac6e0 mon_health_preluminous_compat = true mon_health_preluminous_compat_warning = false mon_host = 10.58.121.188, 10.58.121.187, 10.58.121.186 mon_initial_membgrs = mon1, mon2, mon3","title":"Task 2: Change the Scrub settings in ceph.conf"},{"location":"linux/SES/linux_ses_demo/#task-3-change-the-scrub-settings-directly-in-the-configuration-db","text":"1). Query the configuration database to see the value of \u201cosd_scrub_auto_repair_num_errors\u201d: You changed this value to \u201c10\u201d in the previous Task. admin:~ # ceph config get osd.* osd_scrub_auto_repair_num_errors 10 2). Change the value of \u201cosd_scrub_auto_repair_num_errors\u201d to \u201c8\u201d: admin:~ # ceph config set osd.* osd_scrub_auto_repair_num_errors 8 3). Show that the change has taken immediate effect by re-running the same command that was used in the first step: admin:~ # ceph config get osd.* osd_scrub_auto_repair_num_errors 8","title":"Task 3: Change the Scrub settings directly in the Configuration DB"},{"location":"linux/SES/linux_ses_demo/#task-4-manually-scrub-and-repair-an-osd-and-a-pg","text":"This won\u2019t do much in this demo environment, because the OSDs aren\u2019t storing very much data. But it\u2019s worth having some practice. 1). Start a scrubbing of one of the OSDs: admin:~ # ceph osd scrub osd.1 instructed osd(s) 1 to scrub 2). Scrub a Placement Group: admin:~ # ceph pg scrub 8.1 instructing pg 8.1 on osd.0 to scrub 3). Repair an OSD: admin:~ # ceph osd repair osd.1 instructed osd(s) 1 to repair 4). Repair a PG: admin:~ # ceph pg repair 8.1 instructing pg 8.1 on osd.0 to repair 5). Show what\u2019s currently happening to the OSD that you instructed to have scrubbed and repaired: admin:~ # ceph osd dump | grep osd.1 max_osd 12 osd.1 up in weight 1 up_from 10 up_thru 1415 down_at 0 last_clean_interval [0,0) v1:10.58.121.185:6800/11157 v1:10.58.121.185:6801/11157 exists,up 32c78078-1878-4fac-9738-00d8bf80deea osd.10 up in weight 1 up_from 18 up_thru 1413 down_at 0 last_clean_interval [0,0) v1:10.58.121.182:6808/11130 v1:10.58.121.182:6809/11130 exists,up 6cb26fdc-09b1-42de-8855-7203931a0101 osd.11 up in weight 1 up_from 18 up_thru 1415 down_at 0 last_clean_interval [0,0) v1:10.58.121.185:6808/11995 v1:10.58.121.185:6809/11995 exists,up cc22107d-0239-4874-8308-6c137c8a0931 6). Show what\u2019s currently happening to the PG that you instructed to have scrubbed and repaired: admin:~ # ceph pg dump | grep \"8\\.1\" dumped all 8.16 0 0 0 0 0 0 0 0 0 0 active+clean 2021-01-05 21:01:16.383909 0'0 1423:27 [6,4,5] 6 [6,4,5] 6 0'0 2021-01-05 20:53:47.314062 0'0 2021-01-05 20:53:47.314062 0 8.17 0 0 0 0 0 0 0 0 0 0 active+clean 2021-01-05 22:57:01.044252 0'0 1424:30 [1,6,8] 1 [1,6,8] 1 0'0 2021-01-05 22:57:01.044098 0'0 2021-01-05 22:57:01.044098 0 8.14 0 0 0 0 0 0 0 0 0 0 active+clean 2021-01-05 22:56:56.081480 0'0 1424:30 [1,2,4] 1 [1,2,4] 1 0'0 2021-01-05 22:56:56.081356 0'0 2021-01-05 22:56:56.081356 0 8.15 0 0 0 0 0 0 0 0 0 0 active+clean 2021-01-05 21:01:16.375386 0'0 1423:27 [3,5,0] 3 [3,5,0] 3 0'0 2021-01-05 20:53:53.231124 0'0 2021-01-05 20:48:05.301705 0 8.12 0 0 0 0 0 0 0 0 0 0 active+clean 2021-01-05 21:01:16.370121 0'0 1423:27 [11,2,8] 11 [11,2,8] 11 0'0 2021-01-05 20:53:48.149449 0'0 2021-01-05 20:48:05.301705 0 2.18 0 0 0 0 0 0 0 0 0 0 active+clean 2021-01-05 16:44:58.986205 0'0 1423:1630 [10,1,8] 10 [10,1,8] 10 0'0 2021-01-05 13:02:00.365382 0'0 2021-01-02 00:38:58.134100 0 8.13 0 0 0 0 0 0 0 0 0 0 active+clean 2021-01-05 21:01:16.387832 0'0 1423:27 [0,8,1] 0 [0,8,1] 0 0'0 2021-01-05 20:53:56.132358 0'0 2021-01-05 20:48:05.301705 0 8.10 0 0 0 0 0 0 0 0 0 0 active+clean 2021-01-05 21:01:16.368416 0'0 1423:27 [11,3,6] 11 [11,3,6] 11 0'0 2021-01-05 20:53:51.152790 0'0 2021-01-05 20:48:05.301705 0 8.11 0 0 0 0 0 0 0 0 0 0 active+clean 2021-01-05 21:01:16.377871 0'0 1423:24 [3,10,5] 3 [3,10,5] 3 0'0 2021-01-05 20:53:45.195257 0'0 2021-01-05 20:48:05.301705 0 8.1e 0 0 0 0 0 0 0 0 0 0 active+clean 2021-01-05 21:01:16.391754 0'0 1423:47 [0,11,8] 0 [0,11,8] 0 0'0 2021-01-05 20:53:55.081582 0'0 2021-01-05 20:48:05.301705 0 8.1 0 0 0 0 0 0 0 0 0 0 active+clean 2021-01-05 22:56:39.829397 0'0 1424:54 [0,7,10] 0 [0,7,10] 0 0'0 2021-01-05 22:56:39.829241 0'0 2021-01-05 22:56:39.829241 0 8.1f 0 0 0 0 0 0 0 0 0 0 active+clean 2021-01-05 21:01:16.392315 0'0 1423:27 [7,5,9] 7 [7,5,9] 7 0'0 2021-01-05 20:53:59.988252 0'0 2021-01-05 20:48:05.301705 0 5.4 0 0 0 0 0 0 0 0 0 0 active+clean 2021-01-05 18:21:28.179266 0'0 1423:1554 [7,9,6] 7 [7,9,6] 7 0'0 2021-01-05 18:21:28.179166 0'0 2021-01-05 18:21:28.179166 0 5.b 0 0 0 0 0 0 0 0 0 0 active+clean 2021-01-05 18:37:01.467457 0'0 1423:1547 [2,0,11] 2 [2,0,11] 2 0'0 2021-01-04 23:46:58.132824 0'0 2021-01-02 03:35:41.214192 0 8.19 0 0 0 0 0 0 0 0 0 0 active+clean 2021-01-05 22:57:06.059090 0'0 1424:30 [1,8,2] 1 [1,8,2] 1 0'0 2021-01-05 22:57:06.058935 0'0 2021-01-05 22:57:06.058935 0 8.18 0 0 0 0 0 0 0 0 0 0 active+clean 2021-01-05 22:57:05.097742 0'0 1424:30 [1,3,6] 1 [1,3,6] 1 0'0 2021-01-05 22:57:05.097670 0'0 2021-01-05 22:57:05.097670 0 1.11 0 0 0 0 0 0 0 0 0 0 active+clean 2021-01-05 00:30:18.193988 0'0 1423:1605 [0,8,6] 0 [0,8,6] 0 0'0 2021-01-05 00:30:18.193868 0'0 2020-12-29 06:30:58.897565 0 8.1b 0 0 0 0 0 0 0 0 0 0 active+clean 2021-01-05 22:57:13.146469 0'0 1424:30 [1,4,6] 1 [1,4,6] 1 0'0 2021-01-05 22:57:13.146390 0'0 2021-01-05 22:57:13.146390 0 8.1a 1 0 0 0 0 19 0 0 2 2 active+clean 2021-01-05 21:01:16.386166 1420'2 1423:29 [9,11,10] 9 [9,11,10] 9 0'0 2021-01-05 20:53:48.690239 0'0 2021-01-05 20:48:05.301705 0 8.1d 0 0 0 0 0 0 0 0 0 0 active+clean 2021-01-05 21:01:16.388079 0'0 1423:56 [0,2,3] 0 [0,2,3] 0 0'0 2021-01-05 20:53:54.121281 0'0 2021-01-05 20:48:05.301705 0 8.1c 0 0 0 0 0 0 0 0 0 0 active+clean 2021-01-05 21:01:16.385846 0'0 1423:27 [2,11,7] 2 [2,11,7] 2 0'0 2021-01-05 20:53:55.458714 0'0 2021-01-05 20:48:05.301705 0","title":"Task 4: Manually scrub and repair an OSD and a PG"},{"location":"linux/SES/linux_ses_demo/#225-manipulate-manager-modules","text":"","title":"2.2.5. Manipulate Manager Modules"},{"location":"linux/SES/linux_ses_demo/#task-1-display-the-list-of-enabled-manager-modules","text":"1). Run the following command to show the list of enabled manager modules: Note that several modules are already enabled, such as: dashboard, iostat, pg_autosclater, prometheus, and restful. Even though they are not listed, the crash module and the balancer module are already enabled by default. admin:~ # ceph mgr module ls | head { \"always_on_modules\": [ \"balancer\", \"crash\", \"devicehealth\", \"orchestrator_cli\", \"progress\", \"rbd_support\", \"status\", \"volumes\" 2). Demonstrate that the crash module is enabled by running its command with no arguments: A list of \u201c7 closest matches\u201d is displayed, representing possible additional arguments to be used with the crash command. The crash module is therefore available. admin:~ # ceph crash crash info crash ls crash ls-new crash post crash prune crash rm crash stat crash json_report crash archive crash archive-all admin:~ # ceph crash stat 0 crashes recorded Task 2: Use the iostat module to display statistics for the IO of the cluster The iostat module is really simple, but very helpful. Run the command: admin:~ # ceph iostat +-----------------------------+-----------------------------+-----------------------------+-----------------------------+-----------------------------+-----------------------------+ | Read | Write | Total | Read IOPS | Write IOPS | Total IOPS | +-----------------------------+-----------------------------+-----------------------------+-----------------------------+-----------------------------+-----------------------------+ | 1024 B/s | 0 B/s | 1024 B/s | 1 | 0 | 1 | | 1024 B/s | 0 B/s | 1024 B/s | 1 | 0 | 1 | | 0 B/s | 0 B/s | 0 B/s | 0 | 0 | 0 | Task 3: Enable and configure the telemetry manager module 1). Enable the telemetry manager module: admin:~ # ceph mgr module enable telemetry 2). Show the various sub-commands that are associated with the telemetry command: A list of \u201c5 closest matches\u201d is displayed, showing various options. admin:~ # ceph telemetry telemetry status telemetry send {ceph|device [ceph|device...]} {} telemetry show { [...]} telemetry show-device telemetry on {} telemetry off 3). Show the status of the telemetry module: Notice that the output is returned as key/value pairs. Notice also that although the module has been enabled (which you accomplished in the first step of this task), the functionality is not enabled (enable=false). And for most of the keys, a null value is set. See that the url value is set to https://telemetry.ceph.com/report. That means that crash reports and other usage information about this cluster are going to be sent to the Ceph Community. admin:~ # ceph telemetry status { \"url\": \"https://telemetry.ceph.com/report\", \"device_url\": \"https://telemetry.ceph.com/device\", \"enabled\": false, \"last_opt_revision\": 1, \"leaderboard\": false, \"description\": null, \"contact\": null, \"organization\": null, \"proxy\": null, \"interval\": 24, \"channel_basic\": true, \"channel_ident\": false, \"channel_crash\": true, \"channel_device\": true, \"last_upload\": null } 4). Set the description, contact, and organization values: admin:~ # ceph config set mgr mgr/telemetry/contact 'JD ' admin:~ # ceph config set mgr mgr/telemetry/description 'Training Cluster' admin:~ # ceph config set mgr mgr/telemetry/organization 'SUSE Training' 5). Display the telemetry data that is collected to be sent: admin:~ # ceph telemetry show | less 6). With the contact information properly set, enable the telemetry functionality: This is a demo cluster with no connection to the internet, so no telemetry data will actually be sent. admin:~ # ceph telemetry on Error EPERM: Telemetry data is licensed under the Community Data License Agreement - Sharing - Version 1.0 (https://cdla.io/sharing-1-0/). To enable, add '--license sharing-1-0' to the 'ceph telemetry on' command. admin:~ # ceph telemetry on --license sharing-1-0 7). Disable the telemetry module: admin:~ # ceph mgr module disable telemetry admin:~ # ceph telemetry show | less Error ENOTSUP: Module 'telemetry' is not enabled (required by command 'telemetry show'): use `ceph mgr module enable telemetry` to enable it","title":"Task 1: Display the list of enabled Manager Modules"},{"location":"linux/SES/linux_ses_demo/#task-4-briefly-attempt-to-use-the-crash-manager-module","text":"1). Show (again) the various sub-commands that are associated with the crash command: admin:~ # ceph crash crash info crash ls crash ls-new crash post crash prune crash rm crash stat crash json_report crash archive crash archive-all 2). Show the current status of the crash database, including the numbgr of crash reports that have been collected so far: It\u2019s likely that the numbgr of crashes recorded in the demo environment is 0. admin:~ # ceph crash stat 0 crashes recorded","title":"Task 4: Briefly attempt to use the crash manager module"},{"location":"linux/SES/linux_ses_demo/#226-introduction-to-the-tell-command","text":"Tell is a very powerful command within Ceph to control the cluster. You don\u2019t use it everyday, but you need to know how to use it when the occasion to use it arises. It\u2019s mostly an Advanced Command, but exposure to it now reduces the stress of learning about it in a more advanced setting later. Run the tell command in a few different circumstances to control the behavior of various Ceph services.","title":"2.2.6. Introduction to the Tell command"},{"location":"linux/SES/linux_ses_demo/#task-1-run-a-benchmark-test-on-an-osd","text":"1). Run the following command to run and see the result of a benchmark test on osd.8: admin:~ # ceph tell osd.8 bench { \"bytes_written\": 1073741824, \"blocksize\": 4194304, \"elapsed_sec\": 3.7797023200000002, \"bytes_per_sec\": 284081055.35676152, \"iops\": 67.730201567831401 }","title":"Task 1: Run a benchmark test on an OSD"},{"location":"linux/SES/linux_ses_demo/#task-2-change-the-protection-setting-regarding-the-deletion-of-pools","text":"1). The default behavior in Ceph is that you can\u2019t delete pools. Try to delete a pool: The output says that you have to be VERY careful and provide more arguments in order to delete a pool admin:~ # ceph osd pool delete rbd_pool Error EPERM: WARNING: this will *PERMANENTLY DESTROY* all data stored in pool rbd_pool. If you are *ABSOLUTELY CERTAIN* that is what you want, pass the pool name *twice*, followed by --yes-i-really-really-mean-it. 2). Try deleting the pool again, this time with the extra arguments: Ceph still won\u2019t let you do it because the mon allow pool delete setting has the value of false. admin:~ # ceph osd pool delete rbd_pool rbd_pool --yes-i-really-really-mean-it Error EPERM: pool deletion is disabled; you must first set the mon_allow_pool_delete config option to true before you can destroy a pool 3). Show that the mon allow pool delete setting has the value of false: Indeed, the output shows that the value is false. admin:~ # ceph config get mon.mon\\* mon_allow_pool_delete false 4). Change to value of the setting using injectargs: Note that the \u201c-\u201d and \u201c_\u201d characters can be confusing. And note that the setting is preceded with the double \u201c--\u201d. The injected args must be enclosed in single quotes. You could have done this with ceph config set, but this is an alternative way to directly \u201ctell\u201d the cluster to change a setting. admin:~ # ceph tell mon.\\* injectargs '--mon-allow-pool-delete=true' mon.mon1: injectargs:mon_allow_pool_delete = 'true' mon.mon2: injectargs:mon_allow_pool_delete = 'true' mon.mon3: injectargs:mon_allow_pool_delete = 'true'","title":"Task 2: Change the protection setting regarding the deletion of pools"},{"location":"linux/SES/linux_ses_demo/#23-ceph-dashboard","text":"","title":"2.3. Ceph Dashboard"},{"location":"linux/SES/linux_ses_demo/#231-access-dashboard","text":"","title":"2.3.1. Access Dashboard"},{"location":"linux/SES/linux_ses_demo/#task-1-set-the-password-for-the-admin-user-of-the-ceph-dashboard","text":"1). In a Bash terminal as the root user, show that the Dashboard module is enabled: \u201cdashboard\u201d should be included in the list of \u201cenabled_modules\u201d at the top of the output. admin:~ # ceph mgr module ls | more \"enabled_modules\": [ \"dashboard\", \"iostat\", \"pg_autoscaler\", \"prometheus\", \"restful\" ], 2). Show the valid dashboard users that have already been created by DeepSea during initial deployment: It\u2019s possible that other users will be listed, but at least the \u201cadmin\u201d user should be displayed in the output. admin:~ # ceph dashboard ac-user-show [\"admin\"] 3). Show the \u201cadmin\u201d user\u2019s information as stored in the user database: You can see that the admin user has a password set, but it is stored as a hash. So you don\u2019t really know what the password is, and have no way of discovering it. admin:~ # ceph dashboard ac-user-show admin {\"username\": \"admin\", \"password\": , \"roles\": [\"administrator\"], \"name\": null, \"email\": null, \"lastUpdate\": 1601874928} 4). Change the \u201cadmin\u201d user\u2019s password for the dashboard: This sets the \u201cadmin\u201d user\u2019s password to the string: mypassword admin:~ # ceph dashboard ac-user-set-password admin mypassword {\"username\": \"admin\", \"password\": , \"roles\": [\"administrator\"], \"name\": null, \"email\": null, \"lastUpdate\": 1609860842} admin:~ #","title":"Task 1: Set the password for the admin user of the Ceph Dashboard"},{"location":"linux/SES/linux_ses_demo/#task-3-visit-the-ceph-dashboard-url","text":"admin:~ # salt-call grains.get dashboard_creds local: ---------- admin: admin:~ # ceph mgr services { \"dashboard\": \"https://mon1.sha.me.corp:8443/\", \"prometheus\": \"http://mon1.sha.me.corp:9283/\" } admin:~ # ceph -s cluster: id: 343ee7d3-232f-4c71-8216-1edbc55ac6e0 health: HEALTH_WARN 1 subtrees have overcommitted pool target_size_bytes services: mon: 3 daemons, quorum mon1,mon2,mon3 (age 9w) mgr: mon1(active, since 25m) mds: cephfs:1 {0=mon3=up:active} 2 up:standby osd: 12 osds: 12 up (since 5h), 12 in (since 3M) rgw: 1 daemon active (mon3) task status: scrub status: mds.mon3: idle data: pools: 9 pools, 244 pgs objects: 247 objects, 5.7 KiB usage: 14 GiB used, 82 GiB / 96 GiB avail pgs: 244 active+clean io: client: 1.2 KiB/s rd, 1 op/s rd, 0 op/s wr URL: https://mon1.sha.me.corp:8443/ https://10.58.121.186:8443","title":"Task 3: Visit the Ceph Dashboard URL"},{"location":"linux/SES/linux_ses_demo/#232-explore-the-dashboard-health-performance-status","text":"Dashboard Status Cluster Status Monitors OSDs Manager Daemons Hosts Object Gateway Metadata Service iSCSI Gateway Performance Client IOPS Client Throughput Client Read/Write Recovery Throughput Scrub Capacity Pools Raw Capacity Objects PGs per OSD PG Status [SUSE Enterprise Storage Portal Cluster\u2192Configuration Cluster\u2192Manager Modules Pools\u2192Create Pool","title":"2.3.2. Explore the Dashboard Health, Performance, Status"},{"location":"linux/SES/linux_ses_demo/#24-storage-data-access","text":"","title":"2.4. Storage Data Access"},{"location":"linux/SES/linux_ses_demo/#241-ensure-the-ses-cluster-is-healthy","text":"","title":"2.4.1. Ensure the SES Cluster is Healthy"},{"location":"linux/SES/linux_ses_demo/#task-1-check-the-clusters-health","text":"1). Run the following command to check the status (health) of the SES cluster: admin:~ # ceph -s cluster: id: 343ee7d3-232f-4c71-8216-1edbc55ac6e0 health: HEALTH_WARN 1 subtrees have overcommitted pool target_size_bytes 1 pools have too few placement groups services: mon: 3 daemons, quorum mon1,mon2,mon3 (age 9w) mgr: mon1(active, since 18h) mds: cephfs:1 {0=mon3=up:active} 2 up:standby osd: 12 osds: 12 up (since 23h), 12 in (since 3M) rgw: 1 daemon active (mon3) task status: scrub status: mds.mon3: idle data: pools: 10 pools, 248 pgs objects: 247 objects, 5.7 KiB usage: 14 GiB used, 82 GiB / 96 GiB avail pgs: 248 active+clean io: client: 1.2 KiB/s rd, 1 op/s rd, 0 op/s wr 2). Evaluate the output. The cluster in this demonstration environment often doesn\u2019t startup correctly due to the nature of a demo environment and it\u2019s less-predictable resources. Depending on whether any of the following tasks are necessary, followup accordingly to ensure that the cluster is healthy before proceeding with the course lectures or any further exercises. 3). Run the following series of commands to restart the Monitor daemons on each of the Monitor nodes: It\u2019s certainly not necessary to restart the monitor daemons on all of the monitor nodes if only one is down. If you prefer, you can take a different approach to starting the daemon on a single monitor node. admin:~ # for h in mon1 mon2 mon3; \\ do \\ ssh $h systemctl restart ceph-mon@$h; \\ done 4). After waiting a few moments for the daemons to restart, check the status again: admin:~ # ceph -s cluster: id: 343ee7d3-232f-4c71-8216-1edbc55ac6e0 health: HEALTH_WARN 1 subtrees have overcommitted pool target_size_bytes 1 pools have too few placement groups services: mon: 3 daemons, quorum mon1,mon2,mon3 (age 15s) mgr: mon1(active, since 21h) mds: cephfs:1 {0=mon3=up:active} 2 up:standby osd: 12 osds: 12 up (since 26h), 12 in (since 3M) rgw: 1 daemon active (mon3) task status: scrub status: mds.mon3: idle data: pools: 10 pools, 248 pgs objects: 247 objects, 5.7 KiB usage: 14 GiB used, 82 GiB / 96 GiB avail pgs: 248 active+clean io: client: 767 B/s rd, 0 op/s rd, 0 op/s wr 5). Run the following series of commands to restart the Manager daemons on each of the Monitor nodes: admin:~ # for h in mon1 mon2 mon3; \\ do \\ ssh $h systemctl restart ceph-mgr@$h; \\ done 6). After waiting a few moments for the daemons to restart, check the status again: admin:~ # ceph -s cluster: id: 343ee7d3-232f-4c71-8216-1edbc55ac6e0 health: HEALTH_OK services: mon: 3 daemons, quorum mon1,mon2,mon3 (age 8m) mgr: mon1(active, since 18s) mds: cephfs:1 {0=mon3=up:active} 2 up:standby osd: 12 osds: 12 up (since 26h), 12 in (since 3M) rgw: 1 daemon active (mon3) task status: scrub status: mds.mon3: idle data: pools: 10 pools, 248 pgs objects: 247 objects, 6.1 KiB usage: 14 GiB used, 82 GiB / 96 GiB avail pgs: 248 active+clean io: client: 852 B/s rd, 0 op/s rd, 0 op/s wr 7). Run the following command to restart the MDS daemon on the MDS node (mon1): admin:~ # ssh mon1 systemctl restart ceph-mds@mon1.service 8). After waiting a few moments for the mds daemon to restart, check the status again: Look for the mds service to be plain active rather than laggy or crashed admin:~ # ceph -s cluster: id: 343ee7d3-232f-4c71-8216-1edbc55ac6e0 health: HEALTH_WARN 1 subtrees have overcommitted pool target_size_bytes 1 pools have too few placement groups services: mon: 3 daemons, quorum mon1,mon2,mon3 (age 17m) mgr: mon1(active, since 8m) mds: cephfs:1 {0=mon3=up:active} 2 up:standby osd: 12 osds: 12 up (since 26h), 12 in (since 3M) rgw: 1 daemon active (mon3) task status: scrub status: mds.mon3: idle data: pools: 10 pools, 248 pgs objects: 247 objects, 6.2 KiB usage: 14 GiB used, 82 GiB / 96 GiB avail pgs: 248 active+clean io: client: 852 B/s rd, 0 op/s rd, 0 op/s wr 9). Verify if the OSDs \u201cup\u201d and running properly. It is only necessary if the output of ceph -s shows that there are fewer than 9 OSDs shown as being \u201cup\u201d. It\u2019s most likely that a storage node is simply not quite fully booted yet, such that the OSD daemons haven\u2019t fully come up. But if you suspect that the solution requires something different than simply waiting a little longer, you should try the following steps. First, identify which server is hosting the down\u2019d OSDs. One way of doing that is with this command: admin:~ # ceph osd tree ID CLASS WEIGHT TYPE NAME STATUS REWEIGHT PRI-AFF -1 0.09357 root default -9 0.02339 host data1 2 hdd 0.00780 osd.2 up 1.00000 1.00000 6 hdd 0.00780 osd.6 up 1.00000 1.00000 10 hdd 0.00780 osd.10 up 1.00000 1.00000 -3 0.02339 host data2 0 hdd 0.00780 osd.0 up 1.00000 1.00000 4 hdd 0.00780 osd.4 up 1.00000 1.00000 9 hdd 0.00780 osd.9 up 1.00000 1.00000 -7 0.02339 host data3 3 hdd 0.00780 osd.3 up 1.00000 1.00000 7 hdd 0.00780 osd.7 up 1.00000 1.00000 8 hdd 0.00780 osd.8 up 1.00000 1.00000 -5 0.02339 host data4 1 hdd 0.00780 osd.1 up 1.00000 1.00000 5 hdd 0.00780 osd.5 up 1.00000 1.00000 11 hdd 0.00780 osd.11 up 1.00000 1.00000 Simply try restarting the storage daemon processes on the affected host, such as with this example: admin:~ # ssh data2 systemctl restart ceph-osd@9.service admin:~ # ceph -s cluster: id: 343ee7d3-232f-4c71-8216-1edbc55ac6e0 health: HEALTH_WARN 1 subtrees have overcommitted pool target_size_bytes 1 pools have too few placement groups services: mon: 3 daemons, quorum mon1,mon2,mon3 (age 32m) mgr: mon1(active, since 24m) mds: cephfs:1 {0=mon3=up:active} 2 up:standby osd: 12 osds: 12 up (since 27s), 12 in (since 3M) rgw: 1 daemon active (mon3) task status: scrub status: mds.mon3: idle data: pools: 10 pools, 248 pgs objects: 247 objects, 6.2 KiB usage: 14 GiB used, 82 GiB / 96 GiB avail pgs: 248 active+clean io: client: 852 B/s rd, 0 op/s rd, 0 op/s wr If the OSD daemon processes are being stubborn and uncooperative, you may choose to reboot the storage virtual machine entirely. This is one way to do that: admin:~ # ssh data1 systemctl reboot After waiting some time for the daemons to get started, verify that all the OSDs are \u201cup\u201d and that the cluster is healthy: admin:~ # ceph osd tree admin:~ # ceph status 10). Run the following command to restart the RADOS Gateway daemon on the node that is hosting the gateway (mon3): admin:~ # ssh mon3 systemctl restart ceph-radosgw@rgw.mon3.service admin:~ # ssh mon3 systemctl status ceph-radosgw@rgw.mon3.service \u25cf ceph-radosgw@rgw.mon3.service - Ceph rados gateway Loaded: loaded (/usr/lib/systemd/system/ceph-radosgw@.service; enabled; vendor preset: disabled) Active: active (running) since Wed 2021-01-06 21:37:53 CST; 23s ago Main PID: 781880 (radosgw) Tasks: 588 CGroup: /system.slice/system-ceph\\x2dradosgw.slice/ceph-radosgw@rgw.mon3.service \u2514\u2500781880 /usr/bin/radosgw -f --cluster ceph --name client.rgw.mon3 --setuser ceph --setgroup ceph Jan 06 21:37:53 mon3 systemd[1]: Started Ceph rados gateway. 11). After waiting a few moments for the daemon to restart, check the status again: admin:~ # ceph -s cluster: id: 343ee7d3-232f-4c71-8216-1edbc55ac6e0 health: HEALTH_WARN 1 subtrees have overcommitted pool target_size_bytes 1 pools have too few placement groups services: mon: 3 daemons, quorum mon1,mon2,mon3 (age 39m) mgr: mon1(active, since 30m) mds: cephfs:1 {0=mon3=up:active} 2 up:standby osd: 12 osds: 12 up (since 6m), 12 in (since 3M) rgw: 1 daemon active (mon3) task status: scrub status: mds.mon3: idle data: pools: 10 pools, 248 pgs objects: 247 objects, 6.2 KiB usage: 14 GiB used, 82 GiB / 96 GiB avail pgs: 248 active+clean io: client: 1.2 KiB/s rd, 1 op/s rd, 0 op/s wr","title":"Task 1: Check the Cluster\u2019s health"},{"location":"linux/SES/linux_ses_demo/#242-use-the-s3-api-to-interact-with-the-rados-gateway","text":"In this lab we used the s3cmd and radosgw-admin utilities to interact with the SUSE Enterprise Storage cluster. We created a new user, a new bucket, and a new file. We then uploaded the file to the cluster and verified that the object gateway stored it to the cluster.","title":"2.4.2. Use the S3 API to Interact with the RADOS Gateway"},{"location":"linux/SES/linux_ses_demo/#task-1-using-the-s3cmd-tool-and-create-an-s3-user","text":"1). As the root user (password is linux) in a shell or terminal, verify that the s3cmd is available on the admin node: You will likely see an error about configuration files missing, etc. This is enough information to validate the utility is installed. admin:~ # pip --version pip 10.0.1 from /usr/lib/python3.6/site-packages/pip (python 3.6) admin:~ # pip install s3cmd Collecting s3cmd Downloading https://files.pythonhosted.org/packages/26/44/19e08f69b2169003f7307565f19449d997895251c6a6566ce21d5d636435/s3cmd-2.1.0-py2.py3-none-any.whl (145kB) 100% | 153kB 2.7MB/s Collecting python-magic (from s3cmd) Downloading https://files.pythonhosted.org/packages/59/77/c76dc35249df428ce2c38a3196e2b2e8f9d2f847a8ca1d4d7a3973c28601/python_magic-0.4.18-py2.py3-none-any.whl Requirement already satisfied: python-dateutil in /usr/lib/python3.6/site-packages (from s3cmd) (2.7.3) Requirement already satisfied: six>=1.5 in /usr/lib/python3.6/site-packages (from python-dateutil->s3cmd) (1.11.0) Installing collected packages: python-magic, s3cmd Successfully installed python-magic-0.4.18 s3cmd-2.1.0 2). Create a new S3 user to be used: The output will include an access_key value and a secret_key value. You will need both of those values in later steps. admin:~ # radosgw-admin user create --uid=s3user --display-name=S3 User --email=s3user@example.net { \"user_id\": \"s3user\", \"display_name\": \"S3\", \"email\": \"s3user@example.net\", \"suspended\": 0, \"max_buckets\": 1000, \"subusers\": [], \"keys\": [ { \"user\": \"s3user\", \"access_key\": , \"secret_key\": } ], \"swift_keys\": [], \"caps\": [], \"op_mask\": \"read, write, delete\", \"default_placement\": \"\", \"default_storage_class\": \"\", \"placement_tags\": [], \"bucket_quota\": { \"enabled\": false, \"check_on_raw\": false, \"max_size\": -1, \"max_size_kb\": 0, \"max_objects\": -1 }, \"user_quota\": { \"enabled\": false, \"check_on_raw\": false, \"max_size\": -1, \"max_size_kb\": 0, \"max_objects\": -1 }, \"temp_url_keys\": [], \"type\": \"rgw\", \"mfa_ids\": [] } Retrieve above information admin:~ # radosgw-admin user info --uid=s3user","title":"Task 1: Using the s3cmd tool and create an S3 user"},{"location":"linux/SES/linux_ses_demo/#task-2-create-a-new-s3cmd-configuration-file-and-a-new-s3-bucket","text":"1). Generate a new s3cmd configuration file from a shell on the admin node: Fill in as listed below: admin:~ # cd ~ admin:~ # s3cmd --configure Enter new values or accept defaults in brackets with Enter. Refer to user manual for detailed description of all options. Access key and Secret key are your identifiers for Amazon S3. Leave them empty for using the env variables. Access Key: Secret Key: Default Region [US]: Use \"s3.amazonaws.com\" for S3 Endpoint and not modify it to the target Amazon S3. S3 Endpoint [s3.amazonaws.com]: mon3.sha.me.corp Use \"%(bucket)s.s3.amazonaws.com\" to the target Amazon S3. \"%(bucket)s\" and \"%(location)s\" vars can be used if the target S3 system supports dns based buckets. DNS-style bucket+hostname:port template for accessing a bucket [%(bucket)s.s3.amazonaws.com]: %(bucket)s.mon3.sha.me.corp Encryption password is used to protect your files from reading by unauthorized persons while in transfer to S3 Encryption password: Path to GPG program [/usr/bin/gpg]: When using secure HTTPS protocol all communication with Amazon S3 servers is protected from 3 rd party eavesdropping. This method is slower than plain HTTP, and can only be proxied with Python 2.7 or newer Use HTTPS protocol [Yes]: No On some networks all internet access must go through a HTTP proxy. Try setting it here if you can't connect to S3 directly HTTP Proxy server name: New settings: Access Key: Secret Key: Default Region: US S3 Endpoint: mon3.sha.me.corp DNS-style bucket+hostname:port template for accessing a bucket: %(bucket)s.mon3.sha.me.corp Encryption password: Path to GPG program: /usr/bin/gpg Use HTTPS protocol: False HTTP Proxy server name: HTTP Proxy server port: 0 Test access with supplied credentials? [Y/n] n Save settings? [y/N] y Configuration saved to '/root/.s3cfg' 2). Test the configuration by checking for existing files or directories: Since no buckets or files have been made available for the user, no items are listed and the command returns you to the prompt with no output. This is normal. If there is an error, your configuration may have a typo in it. The configuration file will have been saved as .s3cfg. Edit the file to match the configuration in step one. admin:~ # s3cmd ls 3). Create a new bucket for uploading files to using the s3cmd: You should see feedback that the bucket has been created. Although not technically required by the S3 API, the bucket name needs to be in all uppercase to avoid a bug with the s3cmd tool itself. admin:~ # s3cmd mb s3://S3CMDTEST Bucket 's3://S3CMDTEST/' created admin:~ # s3cmd ls 2021-01-06 14:04 s3://S3CMDTEST (it's GMT timezone)","title":"Task 2: Create a new s3cmd configuration file and a new S3 bucket"},{"location":"linux/SES/linux_ses_demo/#task3-create-and-upload-a-file-to-a-bucket-using-the-s3-api","text":"1). Create a file with a few words of text: admin:~ # echo \"The mountains are beautiful\" > newfile 2). Put the new file into your bucket using s3cmd: You should see the file being uploaded. admin:~ # s3cmd put newfile s3://S3CMDTEST upload: 'newfile' -> 's3://S3CMDTEST/newfile' [1 of 1] 28 of 28 100% in 3s 7.66 B/s done 3). Verify the file is now in your bucket, safely stored in you SES cluster: admin:~ # s3cmd ls s3://S3CMDTEST 2021-01-06 14:11 28 s3://S3CMDTEST/newfile","title":"Task3: Create and upload a file to a bucket using the S3 API"},{"location":"linux/SES/linux_ses_demo/#243-use-the-swift-api-to-interact-with-the-rados-gateway","text":"OpenStack packages for SUSE Install and configure the storage nodes for openSUSE and SUSE Linux Enterprise SUSE Package Hub: python-PasteDeploy Enable SUSE Package Hub extension admin:~ # SUSEConnect -p PackageHub/15.1/x86_64 Install python3-PasteDeploy, which is dependency of python-swift installation admin:~ # zypper in python3-PasteDeploy admin:~ # rpm -ivh python3-PyECLib-1.6.0-1.6.x86_64.rpm warning: python3-PyECLib-1.6.0-1.6.x86_64.rpm: Header V3 RSA/SHA256 Signature, key ID 3dbdc284: NOKEY error: Failed dependencies: python(abi) = 3.8 is needed by python3-PyECLib-1.6.0-1.6.x86_64 rpmlib(PayloadIsZstd) <= 5.4.18-1 is needed by python3-PyECLib-1.6.0-1.6.x86_64 Add OpenStack Swift Repository for SUSE admin:~ # zypper addrepo -f obs://Cloud:OpenStack:Train/SLE_15_SP1 Train admin:~ # zypper in openstack-swift openstack-swift-account openstack-swift-container openstack-swift-object","title":"2.4.3. Use the swift API to Interact with the RADOS Gateway"},{"location":"linux/SES/linux_ses_demo/#task-1-create-a-swift-subuser","text":"1). In a shell or terminal as the root user (password of linux) on the admin node, create a new subuser: The output will contain the access and secret keys for the s3user and a secret key for the new swift subuser.. admin:~ # radosgw-admin subuser create --uid=s3user --subuser=s3user:swift --access=full { \"user_id\": \"s3user\", \"display_name\": \"S3\", \"email\": \"s3user@example.net\", \"suspended\": 0, \"max_buckets\": 1000, \"subusers\": [ { \"id\": \"s3user:swift\", \"permissions\": \"full-control\" } ], \"keys\": [ { \"user\": \"s3user\", \"access_key\": , \"secret_key\": } ], \"swift_keys\": [ { \"user\": \"s3user:swift\", \"secret_key\": } ], \"caps\": [], \"op_mask\": \"read, write, delete\", \"default_placement\": \"\", \"default_storage_class\": \"\", \"placement_tags\": [], \"bucket_quota\": { \"enabled\": false, \"check_on_raw\": false, \"max_size\": -1, \"max_size_kb\": 0, \"max_objects\": -1 }, \"user_quota\": { \"enabled\": false, \"check_on_raw\": false, \"max_size\": -1, \"max_size_kb\": 0, \"max_objects\": -1 }, \"temp_url_keys\": [], \"type\": \"rgw\", \"mfa_ids\": [] } 2). Verify that the subuser has access to at least one bucket and list the buckets with a swift command: swift -A http://mon3.sha.me.corp/auth/1.0 -U s3user:swift -K '{SECRET_KEY_FROM_STEP_1}' list admin:~ # swift -A http://mon3.sha.me.corp/auth/1.0 -U s3user:swift -K '' list S3CMDTEST","title":"Task 1: Create a swift subuser"},{"location":"linux/SES/linux_ses_demo/#task-2-use-the-swift-command-to-access-a-file-created-with-the-s3cmd-tool","text":"1). Since the S3 API and the swift API are accessing the same SUSE Enterprise Storage cluster, and since the RADOS gateway is built to be inter-operable with both, you can use the swift API to retrieve the object which was uploaded to SES via the S3 API: swift -A http://mon3.example.net/auth/1.0 -U s3user:swift -K '{SECRET_KEY_FROM_STEP_1}' download -a An example of the command is listed here: admin:~ # swift -A http://mon3.sha.me.corp/auth/1.0 -U s3user:swift -K '' download -a Although we have taken a shortcut by using the -a option (meaning grab every object this user has access to), it illustrates the tool\u2019s capability. We\u2019ve uploaded the newfile with S3, we\u2019ve retrieved it with swift.","title":"Task 2: Use the swift command to access a file created with the S3cmd tool"},{"location":"linux/SES/linux_ses_demo/#244-create-snapshots-on-ses-using-rbd","text":"In this lab we worked with rbd images. We mapped an rbd image to a Linux device file, then created a filesystem and mounted it. Then we created snapshots to preserve the images data state at a particular time, and rolled it back to demonstrate functionality.","title":"2.4.4. Create Snapshots on SES using RBD"},{"location":"linux/SES/linux_ses_demo/#task-1-create-a-new-pool-for-rbd-images","text":"1). Access https://mon1.pvg.me.corp:8443 or https://10.58.121.186:8443 2). Log in with the following credentials: Username: admin Password: mypassword 3). Click on the Pools tab near the top of the page 4). Click the Create button and use the following in the available fields: Name: rbd-images Pool type: replicated Placement groups: 16 Crush ruleset: replicated_rule Replicted size: 2 Applications: rbd Compression Mode: none 5). Click Create Pool","title":"Task 1: Create a new pool for RBD images"},{"location":"linux/SES/linux_ses_demo/#task-2-create-a-new-rbd-image-in-the-rbd-images-pool","text":"6). Create a new RBD image using the rbd command: admin:~ # rbd create --size 1024 rbd-images/barfoo 7). Verify the new image has been created in the rbd-images pool: The new image named barfoo should be displayed. admin:~ # rbd ls -p rbd-images barfoo","title":"Task 2: Create a new RBD image in the rbd-images pool"},{"location":"linux/SES/linux_ses_demo/#task-3-mount-the-new-image-on-the-admin-node-and-create-a-filesystem","text":"1). As the root user in a shell or terminal on the admin node, map the new rbd image to a block device: admin:~ # rbd map rbd-images/barfoo /dev/rbd0 2). Create a filesystem on the newly mapped device: admin:~ # mkfs.ext4 /dev/rbd0 mke2fs 1.43.8 (1-Jan-2018) Discarding device blocks: done Creating filesystem with 262144 4k blocks and 65536 inodes Filesystem UUID: 19da6b86-1989-4834-a365-2f654fcce6f6 Superblock backups stored on blocks: 32768, 98304, 163840, 229376 Allocating group tables: done Writing inode tables: done Creating journal (8192 blocks): done Writing superblocks and filesystem accounting information: done 3). Mount the image to the /mnt directory: admin:~ # mount /dev/rbd0 /mnt admin:~ # l /mnt total 20 drwxr-xr-x 3 root root 4096 Jan 6 23:48 ./ drwxr-xr-x 1 root root 156 Oct 5 08:53 ../ drwx------ 2 root root 16384 Jan 6 23:48 lost+found/","title":"Task 3: Mount the new image on the admin node and create a filesystem"},{"location":"linux/SES/linux_ses_demo/#task-4-create-a-file-on-the-new-filesystem-and-snapshot-the-rbd-image-and-make-some-additional-changes","text":"1). Change to the /mnt directory and create a simple file: admin:~ # cd /mnt admin:/mnt # echo \"This is some sample text\" > start.txt 2). List the directories contents to see that the start.txt file has been created on the storage cluster. admin:/mnt # ls -l total 20 drwx------ 2 root root 16384 Jan 6 23:48 lost+found -rw-r--r-- 1 root root 25 Jan 6 23:50 start.txt 3). Create a snapshot of what the rbd image contained: Wait for confirmation that the snapshot has been created. It should only take a few seconds. admin:/mnt # rbd snap create rbd-images/barfoo@begin 4). List the rbd snapshots for the rbd-images/barfoo image: You should see the new snap called begin listed. admin:/mnt # rbd snap ls rbd-images/barfoo SNAPID NAME SIZE PROTECTED TIMESTAMP 4 begin 1 GiB Wed Jan 6 23:51:12 2021 5). Add another file to the filesystem: admin:/mnt # echo \"Some more text\" > end.txt 6). List the contents of the /mnt to verify the existence of two files. admin:/mnt # ls -l total 24 -rw-r--r-- 1 root root 15 Jan 6 23:52 end.txt drwx------ 2 root root 16384 Jan 6 23:48 lost+found -rw-r--r-- 1 root root 25 Jan 6 23:50 start.txt 7). Create a second snapshot of the rbd-images/barfoo image: admin:/mnt # rbd snap create rbd-images/barfoo@finish 8). List the rbd snapshots: There should be begin and finish snapshots. admin:/mnt # rbd snap ls rbd-images/barfoo SNAPID NAME SIZE PROTECTED TIMESTAMP 4 begin 1 GiB Wed Jan 6 23:51:12 2021 5 finish 1 GiB Wed Jan 6 23:53:15 2021 9). List the contents of the /mnt directory again and verify the two files. 10). Rollback the data to the begin snapshot: This process will be relatively quick because the size of the image is small and we have very little data on it. admin:/mnt # rbd snap rollback rbd-images/barfoo@begin Rolling back to snapshot: 100% complete...done. 11). Change to the root user\u2019s home directory, then remount the image in order to see that the rbd image has been rolled back: admin:/mnt # cd ~ admin:~ # umount /mnt admin:~ # mount /dev/rbd0 /mnt 12). List the contents of the /mnt directory to verify that only the start.txt file exists on the image. admin:/mnt # ls -l total 20 drwx------ 2 root root 16384 Jan 6 23:48 lost+found -rw-r--r-- 1 root root 25 Jan 6 23:50 start.txt 13). Rollback the data to the finish snapshot: admin:/mnt # rbd snap rollback rbd-images/barfoo@finish Rolling back to snapshot: 100% complete...done. 14). Unmount and remount the image: admin:/mnt # cd ~ admin:~ # umount /mnt admin:~ # mount /dev/rbd0 /mnt 15). List the contents of the /mnt directory to show it has indeed been rolled back and contains the start.txt and end.txt files admin:/mnt # ls -l total 24 -rw-r--r-- 1 root root 15 Jan 6 23:52 end.txt drwx------ 2 root root 16384 Jan 6 23:48 lost+found -rw-r--r-- 1 root root 25 Jan 6 23:50 start.txt 16). Change to the root user\u2019s home directory and unmount the image: admin:/mnt # cd ~ admin:~ # umount /mnt","title":"Task 4: Create a file on the new filesystem and snapshot the rbd image and make some additional changes"},{"location":"linux/SES/linux_ses_demo/#245-create-and-manage-cow-clones-with-rbd","text":"In this lab you will created a new pool and block device image in the pool. You then mapped the block storage to a linux device and took a snapshot. Finally you protected the snapshot from modification. This would be done so the snapshot can be safely used as a parent cow image which can then be cloned to create new virtual machines.","title":"2.4.5. Create and manage COW Clones with rbd"},{"location":"linux/SES/linux_ses_demo/#task-1-create-a-new-pool","text":"1). View the current osds and pools: admin:~ # ceph osd ls 0 1 2 3 4 5 6 7 8 9 10 11 admin:~ # ceph osd pool ls iscsi-images cephfs_data cephfs_metadata .rgw.root default.rgw.control default.rgw.meta default.rgw.log rbd_pool bucket_pool EC_RBD_Pool default.rgw.buckets.index default.rgw.buckets.data rbd-images 2). Create a new pool called cow-pool: admin:~ # ceph osd pool create cow-pool 128 pool 'cow-pool' created 3). List the available pools to view the new pool using either of the following commands: admin:~ # ceph osd pool ls iscsi-images cephfs_data cephfs_metadata .rgw.root default.rgw.control default.rgw.meta default.rgw.log rbd_pool bucket_pool EC_RBD_Pool default.rgw.buckets.index default.rgw.buckets.data rbd-images cow-pool admin:~ # rados lspools iscsi-images cephfs_data cephfs_metadata .rgw.root default.rgw.control default.rgw.meta default.rgw.log rbd_pool bucket_pool EC_RBD_Pool default.rgw.buckets.index default.rgw.buckets.data rbd-images cow-pool Task 2: Create a block device image in a pool 1). Create a format 2 rbd image called cow-base in the cow-pool storage pool with a size of 1GB *Note that the \u2013image-format statement is optional as format 2 is default admin:~ # rbd create -p cow-pool cow-base --size 1024 --image-format 2 2). Check that the image has been created, that the format is 2 and that layering (COW Clones) is supported admin:~ # rbd -p cow-pool list cow-base admin:~ # rbd -p cow-pool info cow-base rbd image 'cow-base': size 1 GiB in 256 objects order 22 (4 MiB objects) snapshot_count: 0 id: 269d5b817222aa block_name_prefix: rbd_data.269d5b817222aa format: 2 features: layering op_features: flags: create_timestamp: Thu Jan 7 10:12:31 2021 access_timestamp: Thu Jan 7 10:12:31 2021 modify_timestamp: Thu Jan 7 10:12:31 2021 Task 3: Map the block storage image to a Linux host 1). In a shell or terminal as user root open a terminal window. Using the rbd map command, map an rbd device to the block-storage image created above. admin:~ # rbd map -p cow-pool --image cow-base /dev/rbd1 2). View the mapped block devices admin:~ # rbd showmapped id pool namespace image snap device 0 rbd-images barfoo - /dev/rbd0 1 cow-pool cow-base - /dev/rbd1 3). Note the rbd index numbgr (e.g. rbd0, rbd1) associated with the cow-base image: RBD ___1____ 4). View the devices in /dev. Note the device name(s) admin:~ # ls -l /dev/rbd* brw-rw---- 1 root disk 252, 0 Jan 6 23:49 /dev/rbd0 brw-rw---- 1 root disk 252, 16 Jan 7 10:14 /dev/rbd1 /dev/rbd: total 0 drwxr-xr-x 2 root root 60 Jan 7 10:14 cow-pool drwxr-xr-x 2 root root 60 Jan 6 23:48 rbd-images 5). View the block device:(use the device numbgr from step above) admin:~ # fdisk -l /dev/rbd1 Disk /dev/rbd1: 1 GiB, 1073741824 bytes, 2097152 sectors Units: sectors of 1 * 512 = 512 bytes Sector size (logical/physical): 512 bytes / 512 bytes I/O size (minimum/optimal): 4194304 bytes / 4194304 bytes 6). Format the device with an ext4 filesystem: admin:~ # mkfs.ext4 /dev/rbd1 mke2fs 1.43.8 (1-Jan-2018) Discarding device blocks: done Creating filesystem with 262144 4k blocks and 65536 inodes Filesystem UUID: 64c9a973-cf31-4239-881f-ec5642bf34e3 Superblock backups stored on blocks: 32768, 98304, 163840, 229376 Allocating group tables: done Writing inode tables: done Creating journal (8192 blocks): done Writing superblocks and filesystem accounting information: done 7). Mount the block device on the local filesystem: admin:~ # mkdir /mnt/cow-base admin:~ # mount /dev/rbd1 /mnt/cow-base 8). Test the storage access by creating a file: admin:~ # cd /mnt/cow-base admin:/mnt/cow-base # touch base-image-file admin:/mnt/cow-base # ls base-image-file lost+found","title":"Task 1: Create a new pool"},{"location":"linux/SES/linux_ses_demo/#task-4-snapshot-the-rbd-image-and-protect-the-snapshot","text":"1). List the snapshots in the cow-base image: admin:/mnt/cow-base # rbd snap ls cow-pool/cow-base 2). Create a snapshot of the cow-base rbd image which contains the base-image-file file admin:/mnt/cow-base # rbd snap create cow-pool/cow-base@base-snap 3). List the snapshot: admin:/mnt/cow-base # rbd snap ls cow-pool/cow-base SNAPID NAME SIZE PROTECTED TIMESTAMP 4 base-snap 1 GiB Thu Jan 7 10:37:13 2021 4). This snapshot will form the parent snapshot for COW clone images so you will now protected it from modification: admin:/mnt/cow-base # rbd snap protect cow-pool/cow-base@base-snap admin:/mnt/cow-base # rbd snap ls cow-pool/cow-base SNAPID NAME SIZE PROTECTED TIMESTAMP 4 base-snap 1 GiB yes Thu Jan 7 10:37:13 2021 Task 5: Create writable COW clones from the parent snapshot 1). Create a COW clone from the cow-base with the base-snap snapshot as the parent image admin:/mnt/cow-base # rbd clone cow-pool/cow-base@base-snap cow-pool/cow-image1 2). Check the information for the new image admin:/mnt/cow-base # rbd -p cow-pool --image cow-image1 info rbd image 'cow-image1': size 1 GiB in 256 objects order 22 (4 MiB objects) snapshot_count: 0 id: 26a1209678cad4 block_name_prefix: rbd_data.26a1209678cad4 format: 2 features: layering op_features: flags: create_timestamp: Thu Jan 7 10:38:58 2021 access_timestamp: Thu Jan 7 10:38:58 2021 modify_timestamp: Thu Jan 7 10:38:58 2021 parent: cow-pool/cow-base@base-snap overlap: 1 GiB 3). Note that the image has details of the parent image and overlap 4). Repeat steps 2 & 3 for an additional image called cow-image2 admin:/mnt/cow-base # rbd clone cow-pool/cow-base@base-snap cow-pool/cow-image2 admin:/mnt/cow-base # rbd -p cow-pool --image cow-image2 info rbd image 'cow-image2': size 1 GiB in 256 objects order 22 (4 MiB objects) snapshot_count: 0 id: 26a2fbcec7b8d9 block_name_prefix: rbd_data.26a2fbcec7b8d9 format: 2 features: layering op_features: flags: create_timestamp: Thu Jan 7 10:47:28 2021 access_timestamp: Thu Jan 7 10:47:28 2021 modify_timestamp: Thu Jan 7 10:47:28 2021 parent: cow-pool/cow-base@base-snap overlap: 1 GiB Task 6: Test that the COW clones are functional 1). Create a new directory and mount the COW clone called cow-image1 Note the rbd device name and use it to mount the file system admin:/mnt # mkdir /mnt/cow-image1 admin:/mnt # rbd map -p cow-pool --image cow-image1 /dev/rbd2 admin:/mnt # l total 4 drwxr-xr-x 1 root root 36 Jan 7 10:54 ./ drwxr-xr-x 1 root root 156 Oct 5 08:53 ../ drwxr-xr-x 3 root root 4096 Jan 7 10:19 cow-base/ drwxr-xr-x 1 root root 0 Jan 7 10:54 cow-image1/ admin:/mnt # ls -l /dev/rbd* brw-rw---- 1 root disk 252, 0 Jan 6 23:49 /dev/rbd0 brw-rw---- 1 root disk 252, 16 Jan 7 10:18 /dev/rbd1 brw-rw---- 1 root disk 252, 32 Jan 7 10:55 /dev/rbd2 /dev/rbd: total 0 drwxr-xr-x 2 root root 80 Jan 7 10:55 cow-pool drwxr-xr-x 2 root root 60 Jan 6 23:48 rbd-images admin:/mnt # mount /dev/rbd2 /mnt/cow-image1 2). Check that the base-image-file which was created in the parent snapshot is present admin:/mnt # cd /mnt/cow-image1 admin:/mnt/cow-image1 # ls base-image-file lost+found 3). Repeat steps 1 and 2 for cow-image2 admin:/mnt # mkdir /mnt/cow-image2 admin:/mnt # rbd map -p cow-pool --image cow-image2 /dev/rbd3 admin:/mnt # mount /dev/rbd3 /mnt/cow-image2 admin:/mnt # ls ./cow-image2/ base-image-file lost+found --> same file with image1 4). Create a new file in the directory where cow-image1 is mounted admin:/mnt # cd cow-image1 admin:/mnt/cow-image1 # touch additional-file admin:/mnt/cow-image1 # ls additional-file base-image-file lost+found 5). Look in the cow-image2 directory. Although they share the same parent snapshot, you can see that the files contained in each COW image are now different. admin:/mnt # ls ./cow-image2/ base-image-file lost+found","title":"Task 4: Snapshot the rbd image and protect the snapshot"},{"location":"linux/SES/linux_ses_demo/#task-7-flatten-a-cow-clone-and-remove-the-parent-image","text":"1). Convert the COW clone called cow-image1 to a standalone rbd image Wait while the flatten process completes. Unlike a clone process this is not instantaneous and can take considerable time. admin:/mnt # rbd flatten cow-pool/cow-image1 Image flatten: 100% complete...done. 2). Check to see that the flatten process has removed the link to the parent snapshot admin:/mnt # rbd -p cow-pool --image cow-image1 info rbd image 'cow-image1': size 1 GiB in 256 objects order 22 (4 MiB objects) snapshot_count: 0 id: 26a1209678cad4 block_name_prefix: rbd_data.26a1209678cad4 format: 2 features: layering op_features: flags: create_timestamp: Thu Jan 7 10:38:58 2021 access_timestamp: Thu Jan 7 10:38:58 2021 modify_timestamp: Thu Jan 7 10:38:58 2021 admin:/mnt # rbd -p cow-pool --image cow-image2 info rbd image 'cow-image2': size 1 GiB in 256 objects order 22 (4 MiB objects) snapshot_count: 0 id: 26a2fbcec7b8d9 block_name_prefix: rbd_data.26a2fbcec7b8d9 format: 2 features: layering op_features: flags: create_timestamp: Thu Jan 7 10:47:28 2021 access_timestamp: Thu Jan 7 10:47:28 2021 modify_timestamp: Thu Jan 7 10:47:28 2021 parent: cow-pool/cow-base@base-snap overlap: 1 GiB 3). Unmount the images admin:/mnt # umount /mnt/cow-image1 admin:/mnt # umount /mnt/cow-image2 admin:/mnt # umount /mnt/cow-base","title":"Task 7: Flatten a COW Clone and remove the parent image"},{"location":"linux/SES/linux_ses_demo/#246-configure-iscsi-on-ses","text":"In this lab an iSCSI Target was configured via the iSCSI gateway on our SUSE Enterprise Storage. An image was added to it. An iSCSI initiator then connected to the target, created a filesystem, and mounted it.","title":"2.4.6. Configure iSCSI on SES"},{"location":"linux/SES/linux_ses_demo/#task-1-create-a-new-rbd-image-in-the-iscsi-images-pool","text":"1). Create a new RBD image using the rbd command: admin:~ # rbd create --size 1024 iscsi-images/fooiscsi 2). Verify the new image has been created in the iscsi-images pool: The new image named fooiscsi should be displayed. admin:~ # rbd ls iscsi-images fooiscsi","title":"Task 1: Create a new RBD image in the iscsi-images pool"},{"location":"linux/SES/linux_ses_demo/#task-2-define-a-new-iscsi-target-with-the-ceph-dashboard","text":"1). Access the Ceph Dashboard and log in: https://mon1.pvg.me.corp:8443 or https://10.58.121.186:8443 Username: admin Password: mypassword 2). Once logged in, click on the Block drop-down item near the top. Select iSCSI. 3). With the Overview tab showing for iSCSI, click on the Targets tab near the top. Note: When clicking on the Targets tab, if you see an error that says something about \u201cUnsupported `ceph-iscsi` config version\u2026\u201d, perform the following steps: 1. Close the browser window where the error occurred 2. Restart the mon1 virtual machine. Do this with the following steps: from the Virtual Machine Manager on your lab machine (not in the admin virtual machine), restart the mon1 virtual machine by right-clicking on the mon1 virtual machine > Shut Down > Reboot 3. Wait at least 30 seconds, then from the admin node, open up the browser again and log in to the Ceph Dashboard: https://mon1.pvg.me.corp:8443 or https://10.58.121.186:8443 Username: admin Password: mypassword 4. Continue the lab as directed below by navigating to the Block > iSCSI section, clicking on the Targets tab, and completing the steps below 4). Click Add. Use the following values: Target IQN: Portals: mon2.example.net:172.17.6.132 Images: iscsi-images/fooiscsi ACL authentication: Click Create Target.","title":"Task 2: Define a new iSCSI target with the Ceph Dashboard"},{"location":"linux/SES/linux_ses_demo/#task-3-access-the-new-iscsi-target-from-the-admin-node","text":"1). On the admin node, launch YaST either the ncurses or GUI interface, and select the iSCSI Initiator module: YaST > Network Services > iSCSI Initiator 2). Select the Discovered Targets tab (alt-v) 3). Select Discovery at the bottom of the frame (alt-d) 4). Add the ip address of mon2: 10.58.121.187. Leave the port as the default of 3260. Select Next. 5). Once again on the Discovered Targets tab, the mon2 target should be listed. With the new target highlighted, select Connect (alt-e) at the bottom of the frame. 6). Leave the Startup (in YaST2) or On boot (in YaST) value as manual. Select Next. 7). Select OK to exit the iscsi client configuration module 8). To verify that the iscsi device is now connected, use the lsscsi command to list devices: You should see there is one disk of type RBD connected on a device file similar to the following: admin:~ # lsscsi [0:0:0:0] cd/dvd QEMU QEMU DVD-ROM 1.4. /dev/sr0 [2:0:0:0] disk SUSE RBD 4.0 /dev/sda 9). Create an ext4 filesystem on the connected device file: admin:~ # mkfs.ext4 /dev/sda mke2fs 1.43.8 (1-Jan-2018) Creating filesystem with 262144 4k blocks and 65536 inodes Filesystem UUID: e3896f7e-0664-4b14-85db-0f77cb234c43 Superblock backups stored on blocks: 32768, 98304, 163840, 229376 Allocating group tables: done Writing inode tables: done Creating journal (8192 blocks): done Writing superblocks and filesystem accounting information: done 10). Mount the device to /mnt: admin:~ # mount /dev/sda /mnt 11). Use the mount command to list the connected device: admin:/mnt # mount | grep sda /dev/sda on /mnt type ext4 (rw,relatime,stripe=1024,data=ordered) 12).Change the root user\u2019s home directory and unmount the device: admin:/mnt # cd .. admin:/ # umount /mnt","title":"Task 3: Access the new iSCSI target from the admin node"},{"location":"linux/SES/linux_ses_demo/#247-mount-cephfs-provided-by-suse-enterprise-storage","text":"In this lab a ceph user was configured to mount the ceph filesystem provided by the SUSE Enterprise Cluster. A keyfile was generated, then used in the process.","title":"2.4.7. Mount CephFS Provided by SUSE Enterprise Storage"},{"location":"linux/SES/linux_ses_demo/#task-1-verify-cephfs-configuration-of-the-ses-cluster","text":"1). Cephfs requires two pools for operation: one for data, the other for metadata. Verify that the cluster has two pools for this purpose: admin:~ # ceph fs ls name: cephfs, metadata pool: cephfs_metadata, data pools: [cephfs_data ] Task 2: Create a secret key file for the admin user on the admin node 1). Because cephx authentication is enabled by default on SUSE Enterprise Storage, a secret key will need to be provided to allow access to mount the ceph filesystem. The admin user (identified \u2013 in this case \u2013 on the system as root) on the admin node has a key, but we will need to either provide it on the command line during the mount process (less secure), or put it in a permissions-restricted file and point to the file when mounting (more secure). If we do not specify the key or a file with the key, we will get an error. The following command will return an error: admin:~ # mount -t ceph mon1:6789:/ /mnt 2021-01-07 14:16:36.924 7f45108a9d80 -1 auth: unable to find a keyring on /etc/ceph/ceph.client.guest.keyring,/etc/ceph/ceph.keyring,/etc/ceph/keyring,/etc/ceph/keyring.bin,: (2) No such file or directory mount error 22 = Invalid argument 2). Take secret key value found in the /etc/ceph/ceph.client.admin.keyring file and put it in a new file: admin:~ # cat /etc/ceph/ceph.client.admin.keyring [client.admin] key = caps mds = \"allow *\" caps mon = \"allow *\" caps osd = \"allow *\" caps mgr = \"allow *\" 3). Create a new file and paste the secret key value into it: admin:~ # vi /etc/ceph/admin.secret Put the key value into the file and save it. 4). Change the permissions of the file to be read only by the user: admin:~ # ls -l /etc/ceph/admin.secret -r-------- 1 root root 41 Jan 5 20:05 /etc/ceph/admin.secret","title":"Task 1: Verify cephfs configuration of the SES cluster"},{"location":"linux/SES/linux_ses_demo/#task-3-mount-the-ceph-filesystem-on-the-admin-node","text":"1). Now that the keyfile is created, we can mount the filesystem: admin:~ # mount -t ceph mon1:6789:/ /mnt -o name=admin,secretfile=/etc/ceph/admin.secret admin:~ # ls -l /mnt total 0 2). Verify that the mount shows as expected: admin:~ # mount | grep ceph 10.58.121.186:6789:/ on /mnt type ceph (rw,relatime,name=admin,secret=,acl) 3). Change to the root user\u2019s home directory and unmount the filesystem: admin:~ # cd ~ admin:~ # umount /mnt","title":"Task 3: Mount the ceph filesystem on the admin node"},{"location":"linux/SES/linux_ses_demo/#248-export-an-nfs-share-from-ses-with-nfs-ganesha","text":"","title":"2.4.8. Export an NFS Share from SES with NFS Ganesha"},{"location":"linux/SES/linux_ses_demo/#task-0-install-and-configure-ganesha-ganesha-config-location-is-not-configured-please-set-the-ganesha_rados_pool_namespace-setting","text":"admin:~ # zypper in nfs-ganesha admin:/etc/ganesha # cat ganesha.conf NFSv4 { RecoveryBackend = 'rados_cluster'; #RecoveryBackend = 'rados_ng'; } RADOS_URLS { ceph_conf = '/etc/ceph/ceph.conf'; userid = \"admin\"; watch_url = \"rados://data/ganesha-export-index/conf-nfs1\"; } RADOS_KV { pool = \"metadata\"; namespace = \"ganesha-grace\"; nodeid = \"nfs1\"; } %url rados://data/ganesha-export-index/conf-nfs1 admin:/etc/ganesha # ganesha-rados-grace -p metadata -n ganesha-grace add nfs1 nfs2 nfs3 admin:/etc/ganesha # ganesha-rados-grace -p metadata -n ganesha-grace cur=1 rec=0 ====================================================== nfs1 E nfs2 E nfs3 E http://images.45drives.com/ceph/cephfs/nfs-ganesha-ceph.conf","title":"Task 0: Install and configure Ganesha (Ganesha config location is not configured. Please set the GANESHA_RADOS_POOL_NAMESPACE setting.)"},{"location":"linux/SES/linux_ses_demo/#task-1-create-an-nfs-export-using-the-ceph-dashboard","text":"1). In a browser, navigate to a monitor to access the Ceph Dashboard and log in: https://10.58.121.186:8443/ Username: admin Password: mypassword 2). Click on the NFS tab near the top of the page 3). Click on the green Add button 4). Click on the Add daemon button to the right and select mon1 5). Complete the configuration with the following values: Storage Backend: Object Gateway Object Storage User: s3user Path: S3CMDTEST NFS Protocol: NFSv3 and NFSv4 checked NFS Tag: Pseudo: /S3BKT Access Type: RW Squash: root_squash Transport Protocol: UDP and TCP checked Clients: Click Submit","title":"Task 1: Create an NFS export using the Ceph Dashboard"},{"location":"linux/SES/linux_ses_demo/#task-2-mount-the-nfs-export-on-the-admin-node","text":"1). As the root user on the admin node, query the NFS Ganesha gateway node to see what mounts are available: showmount -e mon1 You should see something similar to the following: Export list for mon1: S3CMDTEST (everyone) 2). Mount the available nfs share to the /mnt directory on the admin server: mount -t nfs mon1:/S3BKT /mnt 3). List the nfs mount: mount | grep mnt Note the type listed as nfs4 4). Change to the root user\u2019s home directory and unmount the export: cd umount /mnt","title":"Task 2: Mount the NFS export on the admin node"},{"location":"linux/SES/linux_ses_demo/#249-configure-and-mount-cifs","text":"In this lab the Samba gateway was configured. A keyring for the Samba gateway was created, the Samba service was modified, and a user created to allow CIFS access to the SES cluster.","title":"2.4.9. Configure and Mount CIFS"},{"location":"linux/SES/linux_ses_demo/#task-1-prepare-the-cephfs-share-for-cifs","text":"1). In order for CIFS to work in our SES environment, a valid CephFS share must be available. The CephFS lab previously done in this workbook is sufficient. Using the same configuration that we used previously, mount the CephFS share and give permissions to all users at the root of the share: admin:~ # mount -t ceph mon1:6789:/ /mnt -o name=admin,secretfile=/etc/ceph/admin.secret admin:~ # chmod 777 /mnt admin:~ # l /mnt total 0 drwxrwxrwx 2 root root 0 Oct 5 14:30 ./ drwxr-xr-x 1 root root 156 Oct 5 08:53 ../ admin:~ # umount /mnt","title":"Task 1: Prepare the CephFS share for CIFS"},{"location":"linux/SES/linux_ses_demo/#task-2-create-a-samba-gateway-specific-keyring-on-the-ceph-admin-node-and-copy-it-to-the-samba-gateway-node","text":"1). A new keyring will be needed for the Samba gateway to allow access to the Ceph cluster. As root, perform the following: admin:~ # ceph auth get-or-create client.samba.gw mon 'allow r' osd 'allow *' mds 'allow *' -o ceph.client.samba.gw.keyring 2). Copy the new keyring to the Samba gateway node: admin:~ # scp ceph.client.samba.gw.keyring mon1:/etc/ceph/ ceph.client.samba.gw.keyring admin:~ # ssh mon1 Last login: Thu Jan 7 14:35:58 2021 from 10.58.121.181 mon1:~ # ls -l /etc/ceph/ total 12 -rw-r--r-- 1 root root 66 Jan 7 15:15 ceph.client.samba.gw.keyring -rw-r--r-- 1 root root 1095 Jan 5 22:44 ceph.conf -rw-r--r-- 1 root root 92 Aug 24 22:03 rbdmap","title":"Task 2: Create a Samba gateway specific keyring on the Ceph admin node and copy it to the Samba gateway node"},{"location":"linux/SES/linux_ses_demo/#task-3-configure-samba-on-the-samba-gateway-node","text":"1). The /etc/samba/smb.conf file will need to be edited to allow CIFS access to the storage cluster. On the mon1 node, replace all of the contents of the file with the following: admin:~ # ssh mon1 mon1:~ # vi /etc/samba/smb.conf mon1:/etc/samba # cat smb.conf [global] netbios name = SAMBA-GW clustering = no idmap config * : backend = tdb2 passdb backend = tdbsam # disable print server load printers = no smbd: backgroundqueue = no [ceph-smb] path = / vfs objects = ceph ceph: config_file = /etc/ceph/ceph.conf ceph: user_id = samba.gw read only = no oplocks = no kernel share modes = no 2). Create a smb user on the mon1 node named joesmb with a password of mypassword: mon1:/etc/samba # useradd joesmb mon1:/etc/samba # passwd joesmb ---> 123 Add joesmb to the smb password database with a password of mypassword: mon1:/etc/samba # smbpasswd -a joesmb New SMB password: ---> 123 Retype new SMB password: ---> 123 Added user joesmb. 3). Start and enable the smb and nmb daemons on mon1: mon1:/etc/samba # systemctl start smb nmb mon1:/etc/samba # systemctl enable smb nmb Created symlink /etc/systemd/system/multi-user.target.wants/smb.service \u2192 /usr/lib/systemd/system/smb.service. Created symlink /etc/systemd/system/multi-user.target.wants/nmb.service \u2192 /usr/lib/systemd/system/nmb.service. 4). Unmount the filesystem: mon1:~ # umount /mnt umount: /mnt: not mounted.","title":"Task 3: Configure Samba on the Samba gateway node"},{"location":"linux/SES/linux_ses_demo/#task-4-connect-a-client-to-the-samba-gateway","text":"1). On the admin node, verify that the Samba gateway is sharing via CIFS. The password is 123 admin:~ # smbclient -U joesmb -L //mon1 Enter WORKGROUP\\joesmb's password: ---> 123 Sharename Type Comment --------- ---- ------- ceph-smb Disk IPC$ IPC IPC Service (Samba 4.9.5-git.373.26895a83dbf3.44.1-SUSE-oS15.0-x86_64) Reconnecting with SMB1 for workgroup listing. Server Comment --------- ------- Workgroup Master --------- ------- GLOBAL CNPVGVSYB900 WORKGROUP SAMBA-GW 2). Connect to the ceph-smb share as joesmb. The password is 123 admin:~ # smbclient -U joesmb //mon1/ceph-smb Enter WORKGROUP\\joesmb's password: ---> 123 tree connect failed: NT_STATUS_BAD_NETWORK_NAME You should see output similar to the following: Try \u201chelp\u201d to get a list of possible commands. smb: \\>","title":"Task 4: Connect a client to the Samba gateway"},{"location":"linux/SES/linux_ses_memo/","text":"SUSE Enterprise Storage Foundation \u00b6 Ceph\u2019s RADOS \u00b6 Everything in Ceph is stored in the RADOS cluster as Objects. Ceph\u2019s RADOS: Reliable Autonomous Distributed Object Store Ceph\u2019s RADOS is composed of storage devices represented as: Raw storage device with LVM (BlueStore) Standard filesystem (FileStore) The Object Storage Daemon (OSD) integrates each disk device as part of the RADOS cluster. Ceph architecture \u00b6 Ceph is made of two groups of core components The RADOS cluster Provides the clustered object storage Native Object Access methods Gateways Access to the object store via standard protocols librados Direct access to the object store using a native API Examples: iSCSI Gateway (block) -- IGW - iSCSI is a storage area network (SAN) protocol. Exports RADOS Block Device (--RBD) (images as iSCSI disks). iSCSI access to RDB images. lrbd is no longer used in SES6. RADOS Gateway (object) -- RGW Is an object storage interface built on top of librados CephFS (file) A MetaData Service (MDS) is required. Direct access to RADOS (no LIBRADOS layer) Traditional filesystem interface. NFS Ganesha (object, file) Provides NFS exports to: RGW buckets for access the object store The CephFS filesystem Client access the storage services of the cluster via Gateways and Librados The librados API allows interaction with the following daemons: The Ceph Monitor, which maintains a master copy of the cluster map The Ceph OSD Daemon (OSD), which stores data as objects on a storage node. Enhanced SES Architecture Diagram \u00b6 Object Storage \u00b6 The state of the art of distributed SDS storage Unstructured, to better accommodate large files and large quantities of files For large files and large quantities of files, it performs far better than other storage mechanisms Agile, scalable, extensible, and very customizable Invisible to the end-user, ideal for backends Perfect for systemic, application-based use cases. Not necessarily perfect for direct Human use Through associated metadata, ideal for computational analytics And CRUSH takes full advantage of this (CRUSH = Controllable Replication Under Scalable Hashing) Ceph Object Storage supports two interfaces: S3-compatible Swift-compatible Object-based storage has become the standard backend storage mechanism for nearly all modern Enterprise Storage Solutions. Ceph OSDs (Object Storage Daemon) \u00b6 A Ceph OSD (object storage daemon, ceph-osd) stores data, handles data replication, recovery, rebalancing, and provides some monitoring information to Ceph Monitors and Managers by checking other Ceph OSD Daemons for a heartbeat. The Ceph Storage Cluster receives data from Ceph Clients. Clients (dedicated access points, e.g., gateway) could be a Ceph Block Device, Ceph Object Storage, the Ceph Filesystem or a custom implementation using librados. The client requests the cluster status from a monitor node The client uses the status information to identify the location of objects in the cluster The client accesses the objects directly via the OSD node The OSD then stores the data as objects. Each object corresponds to a file in a filesystem which is stored on an OSD. The OSD Daemons take care of the reads and writes on the storage disks. When OSDs are deployed in SES5 the default is to use BlueStore which uses the raw disk and does not require a linux file system to be placed on the disk before it can be used. OSD Daemons store all data as objects in a flat namespace, i.e. no hierarchy of directories. At least 3 Ceph OSDs are normally required for redundancy and high availability. Ceph Mons (Monitor Servers) \u00b6 A Ceph Monitor (ceph-mon) maintains maps of the cluster state, including Monitor Map Manager Map OSD Map PG Map CRUSH Map Epoch These maps are critical cluster state required for Ceph daemons to coordinate with each other. Monitors are also responsible for managing authentication between daemons and clients. At least 3 monitors are normally required for redundancy and high availability. An odd number of MONs is required (Paxos requires). Typically 5 is sufficient for mid or large size cluster. Paxos is an algorithm used for cluster durability. Leader MON expects 50% quality to create quorum. Lowest IP address becomes leader. After new leader selected, all MONs polled for epoch. Leader Mon provides lease to non-leader MONs. MONs are NOT in the data path. They merely serve maps to clients so that the client can go directly to the appropriate OSD storage daemon. Monitor nodes MONs do not serve objects to clients Ceph MGRs (Manager Daemon) \u00b6 A Ceph Manager daemon (ceph-mgr) is responsible for keeping track of runtime metrics and the current state of the Ceph cluster, including storage utilization current performance metrics system load The Ceph Manager daemons also host python-based plugins to manage and expose Ceph cluster information, including a web-based dashboard and REST API. At least two managers are normally required for high availability. MON/MGR daemons are required to run on the same node in SES Ceph MDS (Metadata) \u00b6 A Ceph Metadata Server (MDS, ceph-mds) stores metadata on behalf of the Ceph Filesystem. Ceph Metadata Servers allow POSIX file system users to execute basic commands, for example ls -al without placing an large load on the Ceph Storage Cluster. Ceph Admin Node \u00b6 The Admin node fills the \u201cmaster\u201d and \u201cadmin\u201d roles for DeepSea. Salt is central to SES. SES\u2019s deployment and life-cycle management tool. The Admin node keeps master Ceph authentication keys. Prometheus and Grafana provide cluster monitoring and data graphs Ceph Dashboard \u00b6 Runs as a Ceph Manager module; runs via the MON/MGR node. Client Access \u00b6 Object Storage (RADOSGW or RGW) Block Storage (RDB). RBD is built on top of librados. CephFS iSCSI Gateway NFS Ganesha SMB/CIFS Native protocols via librados Objects in Ceph \u00b6 Everything stored in the Ceph cluster is an object. Default object size is 4MB. Each object has a unique ID. ID is unique across the entire cluster. Objects have associated metadata, in Key: Value pairs. In Ceph we use Storage Pools to organize or arrange our objects. Pools are logical partitions to manage objects Parameters to manage Pools Number of data replicas (Replica pools), or configuration of Erasure Code (size) (Erasure Code pools) Erasure Code is an alternative to Replication SIZE for Erasure Coding is K+M K = Data chunks, M = \u201cParity\u201d chunks EC reduces the hit to raw storage capacity EC incurs a greater hit to CPU on the OSDs as a tradeoff Placement Groups (PG) PG is used to manage objects within a pool. PGs are associated with OSDs for data placement PGs are a central feature of CRUSH that help to provide data durability by way of distribution No PG is owned by an OSD. (And an OSD is not owned by a PG.) PGs are just randomly assigned by CRUSH through all of the OSDs to spread the distribution of data Locating data among PGs is all handled economically, deterministically by way of CRUSH calculations PGs are subdivisions of pools Number of PGs = (Number of OSDs * 100) / Size (Size = either num of replicas, or K+M) The final PG number must be a power of 2 The default number of PGs for a new pool is 8 (it's too small for enterprise solution) In general, PG and PGP numbers should be the same pg_num is the number of placement groups for the pool (placement group, \u5b58\u50a8\u6c60\u7684\u76ee\u5f55\u4e2a\u6570 ) pgp_num is the number of placement groups that will be considered for placement (placement group for placement purpose, pg\u53ef\u7528\u7684osd\u6392\u5217\u7ec4\u5408\u6570\u91cf) \u4ec5\u589e\u5927pg_num\uff1a \u56e0\u4e3apgp_num\u6ca1\u53d8\uff0cpg\u7684osd\u7ec4\u5408\u4ecd\u53ea\u80fd\u4ece\u5f53\u524dpgp_num\u79cd\u7ec4\u5408\u91cc\u9762\u6311\u9009\uff0c\u5bfc\u81f4\u65b0\u589e\u7684pg\u548c\u65e7pg\u4f1a\u6709\u91cd\u590d\u7684osd\u7ec4\u5408\uff0c\u8be5\u73b0\u8c61\u79f0\u4e4b\u4e3a\u5206\u88c2\uff1b\u6b64\u65f6pg\u548cosd\u7684\u6620\u5c04\u6ca1\u6709\u53d8\uff1b \u7ee7\u7eed\u589e\u5927pgp_num\uff0c\u4f7f\u5176\u7b49\u4e8epg_num\uff1a \u65e7pg\u6ca1\u6709\u53d8\u5316\uff0c\u4f46\u65b0\u589epg\u7684osd\u7ec4\u5408\u53d1\u751f\u53d8\u5316\uff0c\u5373\u5f00\u59cb\u91cd\u65b0\u5206\u5e03 Placement Group (PG) \u5f52\u7f6e\u7ec4\u72b6\u6001 Creating \u521b\u5efa\u5b58\u50a8\u6c60\u65f6\uff0c\u5b83\u4f1a\u521b\u5efa\u6307\u5b9a\u6570\u91cf\u7684\u5f52\u7f6e\u7ec4\u3002 ceph \u5728\u521b\u5efa\u4e00\u6216\u591a\u4e2a\u5f52\u7f6e\u7ec4\u65f6\u4f1a\u663e\u793a creating\u3002 \u521b\u5efa\u5b8c\u540e\uff0c\u5728\u5176\u5f52\u7f6e\u7ec4\u7684 Acting Set \u91cc\u7684 OSD \u5c06\u5efa\u7acb\u4e92\u8054\u3002 \u4e00\u65e6\u4e92\u8054\u5b8c\u6210\uff0c\u5f52\u7f6e\u7ec4\u72b6\u6001\u5e94\u8be5\u53d8\u4e3a active+clean\uff0c\u610f\u601d\u662fceph \u5ba2\u6237\u7aef\u53ef\u4ee5\u5411\u5f52\u7f6e\u7ec4\u5199\u5165\u6570\u636e\u4e86\u3002 peering ceph \u4e3a\u5f52\u7f6e\u7ec4\u5efa\u7acb\u4e92\u8054\u65f6\uff0c\u4f1a\u8ba9\u5b58\u50a8\u5f52\u7f6e\u7ec4\u526f\u672c\u7684 OSD \u4e4b\u95f4\u5c31\u5176\u4e2d\u7684\u5bf9\u8c61\u548c\u5143\u6570\u636e\u72b6\u6001\u8fbe\u6210\u4e00\u81f4\u3002 ceph \u5b8c\u6210\u4e86\u4e92\u8054\uff0c\u4e5f\u5c31\u610f\u5473\u7740\u5b58\u50a8\u7740\u5f52\u7f6e\u7ec4\u7684 OSD \u5c31\u5176\u5f53\u524d\u72b6\u6001\u8fbe\u6210\u4e86\u4e00\u81f4\u3002 \u7136\u800c\uff0c\u4e92\u8054\u8fc7\u7a0b\u7684\u5b8c\u6210\u5e76\u4e0d\u80fd\u8868\u660e\u5404\u526f\u672c\u90fd\u6709\u4e86\u6570\u636e\u7684\u6700\u65b0\u7248\u672c\u3002 active ceph \u5b8c\u6210\u4e92\u8054\u8fdb\u7a0b\u540e,\u4e00\u5f52\u7f6e\u7ec4\u5c31\u53ef\u53d8\u4e3a active\u3002 active \u72b6\u6001\u901a\u5e38\u610f\u5473\u7740\u5728\u4e3b\u5f52\u7f6e\u7ec4\u548c\u526f\u672c\u4e2d\u7684\u6570\u636e\u90fd\u53ef\u4ee5\u8bfb\u5199\u3002 clean \u67d0\u4e00\u5f52\u7f6e\u7ec4\u5904\u4e8e clean \u72b6\u6001\u65f6\uff0c\u4e3b OSD \u548c\u526f\u672c OSD \u5df2\u6210\u529f\u4e92\u8054\uff0c\u5e76\u4e14\u6ca1\u6709\u504f\u79bb\u7684\u5f52\u7f6e\u7ec4\u3002 ceph \u5df2\u628a\u5f52\u7f6e\u7ec4\u4e2d\u7684\u5bf9\u8c61\u590d\u5236\u4e86\u89c4\u5b9a\u6b21\u6570\u3002 degraded \u5f53\u5ba2\u6237\u7aef\u5411\u4e3b OSD \u5199\u5165\u6570\u636e\u65f6\uff0c\u7531\u4e3b OSD \u8d1f\u8d23\u628a\u526f\u672c\u5199\u5165\u5176\u4f59\u590d\u5236 OSD\u3002 \u4e3b OSD \u628a\u5bf9\u8c61\u5199\u5165\u590d\u5236 OSD \u540e\uff0c\u5728\u6ca1\u6536\u5230\u6210\u529f\u5b8c\u6210\u7684\u786e\u8ba4\u524d\uff0c\u4e3b OSD \u4f1a\u4e00\u76f4\u505c\u7559\u5728 degraded \u72b6\u6001\u3002 \u5f52\u7f6e\u7ec4\u72b6\u6001\u53ef\u4ee5\u662f active+degraded \u72b6\u6001\uff0c\u539f\u56e0\u5728\u4e8e\u4e00 OSD \u5373\u4f7f\u6ca1\u6240\u6709\u5bf9\u8c61\u4e5f\u53ef\u4ee5\u5904\u4e8e active \u72b6\u6001\u3002 \u5982\u679c\u4e00OSD \u6302\u4e86\uff0cceph \u4f1a\u628a\u76f8\u5173\u7684\u5f52\u7f6e\u7ec4\u90fd\u6807\u8bb0\u4e3a degraded\u3002 \u90a3\u4e2a OSD \u91cd\u751f\u540e\uff0c\u5b83\u4eec\u5fc5\u987b\u91cd\u65b0\u4e92\u8054\u3002 \u7136\u800c\uff0c\u5982\u679c\u5f52\u7f6e\u7ec4\u4ecd\u5904\u4e8e active \u72b6\u6001\uff0c\u5373\u4fbf\u5b83\u5904\u4e8e degraded \u72b6\u6001\uff0c\u5ba2\u6237\u7aef\u8fd8\u53ef\u4ee5\u5411\u5176\u5199\u5165\u65b0\u5bf9\u8c61\u3002 \u5982\u679c\u4e00 OSD \u6302\u4e86\uff0c\u4e14 degraded \u72b6\u6001\u6301\u7eed\uff0cceph \u4f1a\u628a down \u7684 OSD \u6807\u8bb0\u4e3a\u5728\u96c6\u7fa4\u5916(out)\u3001\u5e76\u628a\u90a3\u4e9b down \u6389\u7684 OSD \u4e0a\u7684\u6570\u636e\u91cd\u6620\u5c04\u5230\u5176\u5b83 OSD\u3002 \u4ece\u6807\u8bb0\u4e3a down \u5230 out \u7684\u65f6\u95f4\u95f4\u9694\u7531 mon osd down out interval \u63a7\u5236,\u9ed8\u8ba4\u662f 300 \u79d2\u3002 \u5f52\u7f6e\u7ec4\u4e5f\u4f1a\u88ab\u964d\u7ea7(degraded)\uff0c\u56e0\u4e3a\u5f52\u7f6e\u7ec4\u627e\u4e0d\u5230\u672c\u5e94\u5b58\u5728\u4e8e\u5f52\u7f6e\u7ec4\u4e2d\u7684\u4e00\u6216\u591a\u4e2a\u5bf9\u8c61\uff0c\u8fd9\u65f6\uff0c\u4f60\u4e0d\u80fd\u8bfb\u6216\u5199\u627e\u4e0d\u5230\u7684\u5bf9\u8c61\uff0c\u4f46\u4ecd\u80fd\u8bbf\u95ee\u5176\u5b83\u4f4d\u4e8e\u964d\u7ea7\u5f52\u7f6e\u7ec4\u4e2d\u7684\u5bf9\u8c61\u3002 recovering ceph \u88ab\u8bbe\u8ba1\u4e3a\u53ef\u5bb9\u9519\uff0c\u53ef\u62b5\u5fa1\u4e00\u5b9a\u89c4\u6a21\u7684\u8f6f\u3001\u786c\u4ef6\u95ee\u9898\u3002 \u5f53\u67d0 OSD \u6302\u4e86(down)\u65f6\uff0c\u5176\u5185\u5bb9\u7248\u672c\u4f1a\u843d\u540e\u4e8e\u5f52\u7f6e\u7ec4\u5185\u7684\u5176\u5b83\u526f\u672c\u3002 \u5b83\u91cd\u751f(up)\u65f6\uff0c\u5f52\u7f6e\u7ec4\u5185\u5bb9\u5fc5\u987b\u66f4\u65b0\uff0c\u4ee5\u53cd\u6620\u5f53\u524d\u72b6\u6001\u3002 \u5728\u6b64\u671f\u95f4\uff0cOSD \u5728recovering \u72b6\u6001\u3002 \u4e00\u6b21\u786c\u4ef6\u5931\u8d25\u53ef\u80fd\u7275\u8fde\u591a\u4e2a OSD\u3002\u6bd4\u5982\u4e00\u4e2a\u673a\u67dc\u7684\u7f51\u7edc\u4ea4\u6362\u673a\u5931\u8d25\u4e86\uff0c\u8fd9\u4f1a\u5bfc\u81f4\u591a\u4e2a\u4e3b\u673a\u843d\u540e\u4e8e\u96c6\u7fa4\u7684\u5f53\u524d\u72b6\u6001\uff0c\u95ee\u9898\u89e3\u51b3\u540e\u6bcf\u4e00\u4e2a OSD \u90fd\u5fc5\u987b\u6062\u590d\u3002 ceph \u63d0\u4f9b\u4e86\u5f88\u591a\u9009\u9879\u6765\u5747\u8861\u8d44\u6e90\u7ade\u4e89\uff0c\u5982\u65b0\u670d\u52a1\u8bf7\u6c42\u3001\u6062\u590d\u6570\u636e\u5bf9\u8c61\u548c\u6062\u590d\u5f52\u7f6e\u7ec4\u5230\u5f53\u524d\u72b6\u6001\u3002 osd recovery delay start \u9009\u9879\u5141\u8bb8\u4e00 OSD \u5728\u5f00\u59cb\u6062\u590d\u8fdb\u7a0b\u524d\uff0c\u5148\u91cd\u542f\u3001\u91cd\u5efa\u4e92\u8054\u3001\u751a\u81f3\u5904\u7406\u4e00\u4e9b\u91cd\u653e\u8bf7\u6c42\u3002 osd recovery threads \u9009\u9879\u9650\u5236\u6062\u590d\u8fdb\u7a0b\u7684\u7ebf\u7a0b\u6570\uff0c\u9ed8\u8ba4\u4e3a 1 \u7ebf\u7a0b\u3002 osd recovery thread timeout \u8bbe\u7f6e\u7ebf\u7a0b\u8d85\u65f6\uff0c\u56e0\u4e3a\u591a\u4e2aOSD \u53ef\u80fd\u4ea4\u66ff\u5931\u8d25\u3001\u91cd\u542f\u548c\u91cd\u5efa\u4e92\u8054\u3002 osd recovery max active \u9009\u9879\u9650\u5236\u4e00 OSD \u6700\u591a\u540c\u65f6\u63a5\u53d7\u591a\u5c11\u8bf7\u6c42\uff0c\u4ee5\u9632\u5b83\u538b\u529b\u8fc7\u5927\u800c\u4e0d\u80fd\u6b63\u5e38\u670d\u52a1\u3002 osd recovery max chunk \u9009\u9879\u9650\u5236\u6062\u590d\u6570\u636e\u5757\u5c3a\u5bf8\uff0c\u4ee5\u9632\u7f51\u7edc\u62e5\u585e\u3002 back filling \u6709\u65b0 OSD \u52a0\u5165\u96c6\u7fa4\u65f6\uff0cCRUSH \u4f1a\u628a\u73b0\u6709\u96c6\u7fa4\u5185\u7684\u5f52\u7f6e\u7ec4\u91cd\u5206\u914d\u7ed9\u5b83\u3002 \u5f3a\u5236\u65b0 OSD \u7acb\u5373\u63a5\u53d7\u91cd\u5206\u914d\u7684\u5f52\u7f6e\u7ec4\u4f1a\u4f7f\u4e4b\u8fc7\u8f7d\uff0c\u7528\u5f52\u7f6e\u7ec4\u56de\u586b\u53ef\u4f7f\u8fd9\u4e2a\u8fc7\u7a0b\u5728\u540e\u53f0\u5f00\u59cb\u3002 \u56de\u586b\u5b8c\u6210\u540e\uff0c\u65b0 OSD \u51c6\u5907\u597d\u65f6\u5c31\u53ef\u4ee5\u5bf9\u5916\u670d\u52a1\u4e86\u3002 remapped \u67d0\u4e00\u5f52\u7f6e\u7ec4\u7684 Acting Set \u53d8\u66f4\u65f6\uff0c\u6570\u636e\u8981\u4ece\u65e7\u96c6\u5408\u8fc1\u79fb\u5230\u65b0\u7684\u3002 \u4e3b OSD \u8981\u82b1\u8d39\u4e00\u4e9b\u65f6\u95f4\u624d\u80fd\u63d0\u4f9b\u670d\u52a1\uff0c\u6240\u4ee5\u5b83\u53ef\u4ee5\u8ba9\u8001\u7684\u4e3b OSD \u6301\u7eed\u670d\u52a1\u3001\u76f4\u5230\u5f52\u7f6e\u7ec4\u8fc1\u79fb\u5b8c\u3002 \u6570\u636e\u8fc1\u79fb\u5b8c\u540e,\u4e3b OSD \u4f1a\u6620\u5c04\u5230\u65b0 acting set\u3002 stale \u867d\u7136 ceph \u7528\u5fc3\u8df3\u6765\u4fdd\u8bc1\u4e3b\u673a\u548c\u5b88\u62a4\u8fdb\u7a0b\u5728\u8fd0\u884c\uff0c\u4f46\u662f ceph-osd \u4ecd\u6709\u53ef\u80fd\u8fdb\u5165 stuck \u72b6\u6001\uff0c\u5b83\u4eec\u6ca1\u6709\u6309\u65f6\u62a5\u544a\u5176\u72b6\u6001(\u5982\u7f51\u7edc\u77ac\u65ad)\u3002 \u9ed8\u8ba4OSD \u5b88\u62a4\u8fdb\u7a0b\u6bcf\u534a\u79d2(0.5)\u4f1a\u4e00\u6b21\u62a5\u544a\u5176\u5f52\u7f6e\u7ec4\u3001\u51fa\u6d41\u91cf\u3001\u5f15\u5bfc\u548c\u5931\u8d25\u7edf\u8ba1\u72b6\u6001\uff0c\u6b64\u9891\u7387\u9ad8\u4e8e\u5fc3\u8df3\u9600\u503c\u3002 \u5982\u679c\u4e00\u5f52\u7f6e\u7ec4\u7684\u4e3b OSD \u6240\u5728\u7684 acting set \u6ca1\u80fd\u5411\u76d1\u89c6\u5668\u62a5\u544a\u3001\u6216\u8005\u5176\u5b83\u76d1\u89c6\u5668\u5df2\u7ecf\u62a5\u544a\u4e86\u90a3\u4e2a\u4e3b OSD \u5df2 down\uff0c\u76d1\u89c6\u5668\u4eec\u5c31\u4f1a\u628a\u6b64\u5f52\u7f6e\u7ec4\u6807\u8bb0\u4e3a stale\u3002 \u542f\u52a8\u96c6\u7fa4\u65f6\uff0c\u4f1a\u7ecf\u5e38\u770b\u5230 stale \u72b6\u6001\uff0c\u76f4\u5230\u4e92\u8054\u5b8c\u6210\u3002 \u96c6\u7fa4\u8fd0\u884c\u4e00\u9635\u540e\uff0c\u5982\u679c\u8fd8\u80fd\u770b\u5230\u6709\u5f52\u7f6e\u7ec4\u4f4d\u4e8e stale \u72b6\u6001\uff0c\u5c31\u8bf4\u660e\u90a3\u4e9b\u5f52\u7f6e\u7ec4\u7684\u4e3b OSD \u6302\u4e86(down)\u3001\u6216\u6ca1\u5728\u5411\u76d1\u89c6\u5668\u62a5\u544a\u7edf\u8ba1\u4fe1\u606f\u3002 Each pool has its own autoscaler settings The PG balancer optimizes the placement of PGs across OSD crush-compat mode It's default mode Uses the compat weight-set feature upmap mode. It's perfect mode, which an equal number of PGs on each OSD Use fine-grained control over the PG mapping Snapshots Rulesets to manage CRUSH placement Each pool has a defined CRUSH ruleset A CRUSH ruleset is a definition of how the OSDs organize data This allows configuration of data distribution to be managed per pool A single CRUSH ruleset can be reused by multiple pools A ruleset can take into account: \u9700\u8981\u8003\u8651\u7684\u70b9 physical layout of nodes in the cluster organization of network infrastructure selection of OSDs backed by SSDs versus HDDs, etc Each pool can use either Replication or Erasure Coding Replication is the original, default approach to resiliency Erasure Coded pools have an EC Profile assigned Different than CRUSH rulesets, but similar: define how OSDs organize data The profile defines K, M values; encoding method/plugin; etc CRUSH (Controllable Replication Under Scalable Hashing) \u00b6 CRUSH is a key piece of the Ceph storage solution With the CRUSH algorithm used by Ceph: Data is not centrally stored, it is distributed CRUSH calculates the storage location for each object dynamically No requirement to store a global index of object locations CRUSH Algorithm \u00b6 The CRUSH algorithm deterministically calculates the location of any object in the Ceph RADOS cluster Overhead is low and calculation is performed by each client As no metadata store is required, CRUSH removes the limitations of traditional metadata based management No direct control over the placement of your data in the cluster Higher CPU requirements CRUSH Maps and Rulesets \u00b6 CRUSH Rulesets are the named sets of rules: Combining all of the customizable CRUSH behavior settings Assigned to pool to govern how the pool\u2019s data is distributed in the cluster CRUSH Maps are central to how Ceph distributes data, and maintaining the durability of the data When the cluster is deployed, Ceph creates a simple default ruleset for replicated pools: replicated_rule CRUSH behavior depends on the behaviors and performance of storage devices CRUSH Maps should be crafted to take advantage of those behaviors Rulesets should be used to clearly identify how the devices in your environment should be employed Device Classes exist to indicate performance behavior: hdd, ssd, nvme Ceph OSDs will automatically set the Device Class of a storage device when the OSD is started Working with CRUSH Map Rulesets List the OSDs, which host each OSD belongs to: ceph osd tree ceph osd df tree ceph osd df tree -f json-pretty Find the host of a specific OSD: ceph osd find 8 Show the existing defined rulesets: ceph osd crush rule ls Examine the definition of an existing ruleset: ceph osd crush rule dump There are 3 options for creating a new ruleset: simple replicated erasure Creating new rulesets: ceph osd crush rule create-replicated ceph osd crush rule create-erasure Create a new ruleset using a Device Class: create-replicated Description : The name of the node under which data should be placed. Type : String Example : default (rarely would you need to make this different than \u201cdefault\u201d) or Description : The type of CRUSH node (bucket) across which replicas should be separated. Type : String Example : rack Description : The device class data should be placed on. Type : String Example : ssd CRUSH Weight \u00b6 You may need to move data around New nodes degraded nodes rebalancing View the current CRUSH weights ceph osd crush tree ceph osd df tree Change the weight for an OSD ceph osd crush reweight The important difference between ceph osd reweight and ceph osd crush reweight \"ceph osd crush reweight\" sets the CRUSH weight of the OSD. This weight is an arbitrary value (generally the size of the disk in TB or something) and controls how much data the system tries to allocate to the OSD. \"ceph osd reweight\" sets an override weight on the OSD. This value is in the range 0 to 1, and forces CRUSH to re-place (1-weight) of the data that would otherwise live on this drive. It does not change the weights assigned to the buckets above the OSD, and is a corrective measure in case the normal CRUSH distribution isn\u2019t working out quite right. \"ceph osd reweight\" is temporary. \"ceph osd crush reweight\" is sticky, permanent (until you change it again). Setting a weight of an OSD to 0 is effectively setting the OSD \"out\" - you don\u2019t want it to store data. The Monitor\u2019s Cluster Map contains \u00b6 Monitor Map Unique Cluster ID, details of each Mon node, current epoch, date/time of last change OSD Map Contains the cluster fsid, when the map was created and last modified, a list of pools, replica sizes, PG numbers, a list of OSDs and their status PG Map Contains the PG version, its time stamp, the last OSD map epoch, the full ratios, and details on each placement group such as the PG ID, the Up Set, the Acting Set, the state of the PG (e.g., active + clean), and data usage statistics for each pool MDS Map Contains the current MDS map epoch, references to pool(s) for storing metadata, list of MDS servers, and which metadata servers are up and in CRUSH Map Contains a list of storage devices, the failure domain hierarchy (e.g., device, host, rack, row, room, etc.), and rules for traversing the hierarchy when storing data CRUSH Hierarchy \u00b6 The CRUSH Map includes details of physical & network infrastructure The CRUSH Map hierarchy is defined by a storage architect The default hierarchical list of infrastructure elements: (Hierarchy of CRUSH buckets) OSD host chassis \u5200\u7247\u673a\u7bb1 rack \u673a\u67b6 row pdu \u7535\u6e90\u5206\u914d\u5355\u5143 pod \u6027\u80fd\u4f18\u5316\u7684\u6570\u636e\u4e2d\u5fc3(Performance Optimize Datacenter)\uff0c\u57fa\u4e8e\u6807\u51c6\u5316\u8bbe\u65bd\u7684\u6700\u4f73\u5b9e\u8df5\uff0c\u6bcf\u4e2aPOD\u5185IT\u90e8\u5206\u5305\u542b\u76845000\u53f0\u670d\u52a1\u5668\uff0c\u5206\u5c5e\u5230200\u4e2a\u673a\u67b6\uff0c\u5982\u679c\u4ee5\u6bcf\u53f0\u670d\u52a1\u5668400W\u529f\u7387\u8ba1\u7b97\u7684\u8bdd\uff0c\u6bcf\u4e2a\u673a\u67dc\u9700\u898110KW\u7684\u4f9b\u7535\uff0c\u5373\u6bcf\u4e2aPOD\u7684IT\u8d1f\u8f7d\u5bb9\u91cf\u662f2MW\u3002 room datacenter region root CRUSH is the algorithm and calculation for distributing data through the cluster. CRUSH Map obviously plays a part in how those CRUSH calculations work. CRUSH Map Sections (Six main sections) \u00b6 tunables: adjustments to legacy behavior devices: The list of OSDs (usually no customization needed) \u25cb \"device class\" is meaningful; useful in relation to creating/using CRUSH rulesets \u25cb Standard \"device class\" values are \"hdd.\", \"ssd.\", and \"nvme.\" \u25cb Example: device 7 osd.7 types: types of buckets (usually no customization needed) buckets: the most functional, customizable aspect of the Map \u25cb A bucket typically represents a physical location in the cluster, has a \u201ctype\u201d \u25cb Nodes (containers such as hosts) and leaves (storage devices such as OSDs) rules: define policies of how data should be distributed \u25cb The behind-the-scenes rules that CRUSH follows for data placement \u25cb IMPORTANT: this is NOT the same as the \"ruleset\". In fact, a ruleset is the combined set of all of these six Map sections. choose_args (optional): Rarely used exceptional settings to adjust weights From the documentation: \"choose_args are alternative weights associated with the hierarchy that have been adjusted to optimize data placement. A single choose_args map can be used for the entire cluster, or one can be created for each individual pool.\" Erasure Coding \u00b6 In information theory : an erasure code is a forward error correction (FEC, \u524d\u5411\u7ea0\u9519) code for the binary erasure channel, which transforms a message of k symbols into a longer message (code word) with n symbols such that the original message can be recovered from a subset of the n symbols. The fraction r = k/n is called the code rate The fraction k\u2019/k, where k\u2019 denotes the number of symbols required for recovery, is called reception efficiency Another (easier) way of describing EC: It\u2019s like RAID in Clustered Storage Erasure Coding in SES \u00b6 The default resilience strategy in SES is simple replication * SES Simple replication has overheads, size=3 means 3 times the storage requirements Simplistic EC details: k = number of \u201cdata\u201d chunks, split across \u201ck\u201d number of OSDs m = number of \u201cparity\u201d chunks, split across \u201cm\u201d number of OSDs Ceph calls these \u201ccoding chunks\u201d r (size) = k + m admin:~ # ceph osd crush rule ls replicated_rule Replication vs Erasure Code \u00b6 Replication (default): Use Case: active data Simple and fast Uses more disk space Erasure coding: Use Case: archive data, more static data Calculates recovery data (needs more CPU power) Definable redundancy level Example: K data chunks = 2 , M code chunks = 1 Similar to a replication size of 2 But with only 50% more raw storage consumed Example: for 1GB of effective storage replication pool of size of 2 needs 2GB raw storage erasure coded pool with k=2/m=1 only requires 1.5GB raw storage EC Overwrites \u00b6 Historically, EC only works properly with Objects EC only allowed appends; overwrites were not allowed Works perfectly for objects in buckets but doesn\u2019t work well with Block or CephFS With recent releases of SES, EC can work well with Block and CephFS Facilitated by \u201cEC Overwrites\u201d feature Store data in an EC Pool, and store object metadata in a Replicated Pool Requires a little extra work when defining pools, but worth it ceph osd pool set allow_ec_overwrites true EC Profiles \u00b6 Using Erasure Coding, each Pool is assigned an EC Profile Multiple pools can share a single Profile The profile is just a definition Each Profile has multiple settings The common required settings for all Profiles are K, M EC Profiles must be created before EC Pools can be created Created from the Dashboard or CLI Once an EC Profile is created, you can create a CRUSH Ruleset based on the EC profile Once a pool is created, its EC Profile properties cannot be changed Main profile parameters K: M: stripe_unit - allows you to adjust the size of the data chunk Default size is 4K stripe_unit : size of data striped across devices; default 4K This variable can also be set in the master configuration (osd_erasure_code_stripe_unit) EC plugins - choose your favorite EC algorithm via a plugin jerasure/gf-complete (default, free, open, and very fast) (www.jerasure.org) ISA (Intel library; optimized for modern Intel processors) (only runs on Intel processors) LRC (\u201cLocally Repairable Code\u201d; layers over existing plugins) SHEC (\u201cShingled EC\u201d; trades extra storage for recovery efficiency) CLAY (\u201cCoupled LAYer\u201d; good for reduced network traffic) Creating Erasure Code Profiles and Pools \u00b6 Syntax: ceph osd erasure-code-profile OPTIONS Option Description get - view details of an existing EC profile set - set a profile (create a profile), requires k and m values, with optional values such as ruleset, plugin. Once you create a profile, you can\u2019t change it. ceph osd erasure-code-profile set k= m= [plugin=] [stripe_unit=] ls - list profiles rm - Remove an EC profile ceph osd erasure-code-profile rm Common example (below) The default profile \u2012 2+1=3; data is written over 3 OSDs \u2012 Two data chunks \u2012 One code (parity) chunk \u2012 Uses jerasure plugin with standard Reed/Solomon (reed_sol_van) technique Setting a Custom EC Profile Option: \u2012 Profile name \u2012 K : number of stripes required \u2012 M : number of failed units Example: ceph osd erasure-code-profile set example-profile k=8 m=2 ruleset-failure-domain=host ruleset-failure-domain = crush bucket level for failure admin:/etc/ceph # ceph osd erasure-code-profile \\ set common_profile \\ k=4 \\ m=2 \\ plugin=jerasure \\ technique=reed_sol_van \\ stripe_unit=4K \\ crush-root=default \\ crush-failure-domain=rackcrush-device-class=ssd admin:/etc/ceph # ceph osd erasure-code-profile ls default admin:~ # ceph osd erasure-code-profile get default k=2 m=1 plugin=jerasure technique=reed_sol_van Pools Pools are at the heart of Storage Pools are tied to OSDs Display a list of existing pools: ceph osd pool ls or ceph osd lspools View the statistics and characteristics of pools: ceph osd pool stats ceph osd pool stats ceph osd pool get Show usage and related details of existing pools: rados df or ceph df or ceph df detail All storage revolves around Pools Each pool must be dedicated to a purpose: Object, Block, File Must specify # of Placement Groups and PG Placements Must specify whether using Replication or EC Must specify a CRUSH ruleset Create a Replicated Pool Syntax: ceph osd pool create replicated = number of placement groups for the pool = number of PGs for placement; routinely will be the same as pg_num Always a power of 2 Don\u2019t make the number too small; don\u2019t err on the high side, either Practices For a new pool, the pgp_num will generally (likley) just be the same as the pg_num When increasing the PGs in a pool, you may want to retain the smaller pgp_num to minimize rebalancing, and increase pgp_num later when rebalancing is more convenient If decreasing the PGs in a pool, the pgp_num is adjusted automatically Create an EC Pool (using an EC Profile) Syntax: ceph osd pool create erasure Example: ceph osd pool create EC-pool 128 128 erasure my-ec-profile Pools \u2013 Application Assignment Each Pool must have a stated purpose; application This defines which capabilities the Pool must support The applications are: Block (rbd), Object (rgw), and File (cephfs) There are subtypes of cephfs: i.e. cephfs:data, cephfs:metadata Application assignment happens after creating a pool It\u2019s effortless (and required) to assign an application on a new pool ceph osd pool application enable Changing application assignment after a pool is in use is \u201chard\u201d. Not recommended, only to be done as an expert Pools \u2013 Quotas One of the more desirable features of SDS is to set a maximum usage of a Pool - Quotas Prevent the over-use of a pool Set quotas based on number of objects or number of bytes ceph osd pool set-quota max_objects ceph osd pool set-quota max_bytes Show quota settings ceph osd pool get-quota To remove a quota, set the existing quota setting to 0 There are also application-level quotas For rgw and cephfs (not rbd; images are already limited in size) Pool Quotas vs. Application Quotas. When a pool quota nears its limit, the HEALTH mechanisms will display a \u201cPOOL_NEAR_FULL\u201d warning to the storage administrator. When the quota limit has been exceeded, the HEALTH mechanisms will display a \u201cPOOL_FULL\u201d warning to the storage administrator. Applications (clients) don\u2019t always handle the quotas cleanly. In most cases, once the Pool Quota is exceeded, the application will simply stop writing to the pool, and error messages and behavior at the application are inconsistent (if there are any messages at all). Pools \u2013 Snapshots Take (make) a snapshot of an existing pool ceph osd pool mksnap Remove a snapshot of a pool ceph osd pool rmsnap List pool snapshots rados -p lssnap Rollback the pool to an earlier snapshot rados -p rollback Images and cephfs have their own snapshot facilities. Object and Bucket snapshotting features related to rgw don\u2019t exist. Pools Snapshots versus App Snapshots The two different snapshot features cannot be used at the same time on a pool Either Pool Snapshots, or Application Snapshots; not both. (snap_mode = pool versus snap_mode = selfmanaged) Once you commit to pool snapshots for an RBD pool, you can\u2019t change to using RBD snapshots Pros and Cons of each, depending on your Use Case admin:~ # ceph osd pool ls detail -f json-pretty | grep snap_mode \"snap_mode\": \"selfmanaged\", \"snap_mode\": \"selfmanaged\", \"snap_mode\": \"selfmanaged\", \"snap_mode\": \"selfmanaged\", \"snap_mode\": \"selfmanaged\", \"snap_mode\": \"selfmanaged\", \"snap_mode\": \"selfmanaged\", BlueStore \u00b6 BlueStore is the default storage backend in SES Highlighted features: compressing, no double-writes, faster checksums Ceph FileStore Model It is not ideal for a specialized purpose like a highly scalable distributed storage system. Only recommend that XFS be used. Both btrfs and ext4 have known bugs. The FileStore model uses cache from the filesystem (XFS). Memory for cache is managed by filesystem kernel module. Ceph BlueStore Model BlueStore consumes raw block devices. Metadata management with RocksDB. BlueStore employs RocksDB\u2019s key/value database in order to manage internal metadata, such as the mapping from object names to block locations on disk. Full data and metadata checksumming. By default all data and metadata written to BlueStore is protected by one or more checksums. A small specialized filesystem called BlueFS. This provides just enough of a filesystem to allow RocksDB to store its \"key/value files\" to share metadata across all the raw device(s) No data or metadata will be read from disk or returned to the user without being verified. Multi-device metadata tiering. BlueStore allows its internal journal (write-ahead log) to be written to a separate, highspeed device (like an SSD, NVMe, or NVDIMM) to increased performance. Efficient copy-on-write. RBD and CephFS snapshots rely on a copy-on-write clone mechanism that is implemented efficiently in BlueStore. BlueStore is a userspace model that provides its own memory management and cache. No need to clear the storage device cache OSDs help facilitate the performance of caching Default: cache the reads, don\u2019t cache the writes RocksDB\uff1a rocksdb\u662ffacebook\u57fa\u4e8eleveldb\u5f00\u53d1\u7684\u4e00\u6b3ekv\u6570\u636e\u5e93\uff0cBlueStore\u5c06\u5143\u6570\u636e\u5168\u90e8\u5b58\u653e\u81f3RocksDB\u4e2d\uff0c\u8fd9\u4e9b\u5143\u6570\u636e\u5305\u62ec\u5b58\u50a8\u9884\u5199\u5f0f\u65e5\u5fd7\u3001\u6570\u636e\u5bf9\u8c61\u5143\u6570\u636e\u3001Ceph\u7684omap\u6570\u636e\u4fe1\u606f\u3001\u4ee5\u53ca\u5206\u914d\u5668\u7684\u5143\u6570\u636e \u3002 BlueRocksEnv\uff1a \u662fRocksDB\u4e0eBlueFS\u4ea4\u4e92\u7684\u63a5\u53e3\uff1bRocksDB\u63d0\u4f9b\u4e86\u6587\u4ef6\u64cd\u4f5c\u7684\u63a5\u53e3EnvWrapper\uff0c\u7528\u6237\u53ef\u4ee5\u901a\u8fc7\u7ee7\u627f\u5b9e\u73b0\u8be5\u63a5\u53e3\u6765\u81ea\u5b9a\u4e49\u5e95\u5c42\u7684\u8bfb\u5199\u64cd\u4f5c\uff0cBlueRocksEnv\u5c31\u662f\u7ee7\u627f\u81eaEnvWrapper\u5b9e\u73b0\u5bf9BlueFS\u7684\u8bfb\u5199\u3002 BlueFS\uff1a BlueFS\u662fBlueStore\u9488\u5bf9RocksDB\u5f00\u53d1\u7684\u8f7b\u91cf\u7ea7\u6587\u4ef6\u7cfb\u7edf\uff0c\u7528\u4e8e\u5b58\u653eRocksDB\u4ea7\u751f\u7684.sst\u548c.log\u7b49\u6587\u4ef6\u3002 BlockDecive\uff1a BlueStore\u629b\u5f03\u4e86\u4f20\u7edf\u7684ext4\u3001xfs\u6587\u4ef6\u7cfb\u7edf\uff0c\u4f7f\u7528\u76f4\u63a5\u7ba1\u7406\u88f8\u76d8\u7684\u65b9\u5f0f\uff1b BlueStore\u652f\u6301\u540c\u65f6\u4f7f\u7528\u591a\u79cd\u4e0d\u540c\u7c7b\u578b\u7684\u8bbe\u5907\uff0c\u5728\u903b\u8f91\u4e0aBlueStore\u5c06\u5b58\u50a8\u7a7a\u95f4\u5212\u5206\u4e3a\u4e09\u5c42\uff1a\u6162\u901f\uff08Slow\uff09\u7a7a\u95f4\u3001\u9ad8\u901f\uff08DB\uff09\u7a7a\u95f4\u3001\u8d85\u9ad8\u901f\uff08WAL\uff09\u7a7a\u95f4\uff0c\u4e0d\u540c\u7684\u7a7a\u95f4\u53ef\u4ee5\u6307\u5b9a\u4f7f\u7528\u4e0d\u540c\u7684\u8bbe\u5907\u7c7b\u578b\uff0c\u5f53\u7136\u4e5f\u53ef\u4f7f\u7528\u540c\u4e00\u5757\u8bbe\u5907\u3002 Allocator\uff1a\u8d1f\u8d23\u88f8\u8bbe\u5907\u7684\u7a7a\u95f4\u7ba1\u7406\uff0c\u53ea\u5728\u5185\u5b58\u505a\u6807\u8bb0\uff0c\u76ee\u524d\u652f\u6301StupidAllocator\u548cBitmapAllocator\u4e24\u79cd\u5206\u914d\u5668,Stupid\u57fa\u4e8eextent\u7684\u65b9\u5f0f\u5b9e\u73b0 Ceph BlueStore with Mixed Devices BlueStore Cache Parameters \u00b6 Under most circumstances, autotune is best bluestore_cache_autotune Description: Automatically tune the ratios assigned to different bluestore caches while respecting minimum values Type: Boolean Required: Yes Default: True (enabled) Related settings: bluestore_cache_autotune_chunk_size, bluestore_cache_autotune_interval, and others bluestore_cache_size Description: The amount of memory BlueStore will use for its cache. If zero, bluestore_cache_size_hdd or bluestore_cache_size_ssd will be used instead. Type: Integer Required: Yes Default: 0 bluestore_cache_size_hdd Description: The default amount of memory BlueStore will use for its cache when backed by an HDD Type: Integer Required: Yes Default: 1 * 1024 * 1024 * 1024 (1 GB) bluestore_cache_size_ssd Description: The default amount of memory BlueStore will use for its cache when backed by an SSD. Type: Integer Required: Yes Default: 3 * 1024 * 1024 * 1024 (3 GB) bluestore_cache_meta_ratio Description: The ratio of cache devoted to metadata. Type: Floating point Default: .01 bluestore_cache_kv_ratio Description: The ratio of cache devoted to key/value data (rocksdb). Type : Floating point Default: .99 bluestore_cache_kv_max Description : The maximum amount of cache devoted to key/value data (rocksdb). Type : Unsigned Integer Default : 512 * 1024*1024 (512 MB) BlueStore Device Types \u00b6 BlueStore has three types of roles for devices: The DATA role: Required: main device (block symlink) stores all object data. If no other types: \u201cdata\u201d device serves all the other roles The DB role: Optional: DB device (block.db symlink) stores metadata in RocksDB Whatever doesn\u2019t fit will spill back onto the \u201cdata\u201d device The Write Ahead Log (WAL/Journal) role: Optional: WAL device (block.wal symlink) stores the internal journal Can combine all 3 roles into one physical device Or combine DB/WAL onto a single device with the DATA device separate Or all three on seperate devices BlueStore Configuration Recommendations \u00b6 Devote DB and WAL to SSD or NVMe Allocate 64 GB to the RocksDB Allocate 4-6 GB to the WAL Assign the \u201cdata\u201d role to the slower (HDD) devices If combining WAL/DB on one device, use a single partition for both You can use a single SSD/NVMe to store multiple journals Architecture Overview of Object, Block, Filesystem Access \u00b6 Object Storage \u00b6 The state of the art of distributed storage Object storage is the Cloud Storage mechanism of choice Unstructured, to better accommodate large files and large quantities of files Ideal for large media files, like streaming videos, audio Scales really well, large capacities Ceph provides access to the storage via all three major data access methods: Block, Object, and File. For the storage backend, Object Storage is ideal Block Storage \u00b6 Traditional Block Storage: Volumes as a collection of blocks Blocks can be of various sizes, but all the same within a volume Typically a filesystem is installed on top of the volume Hard Drives, CDs, USB sticks, etc The standard disk device mechanism for Unix, Linux, Windows, etc. Ceph presents RADOS as block device (RBD = RADOS Block Device) Ceph calls these block devices \u201cimages\u201d Provides clients with access like a \u201cdisk drive\u201d KVM/QEMU; libvirt; or remote Linux system A native Windows client that can access the Block storage of Ceph directly is in progress RADOS Block Device (RBD) \u00b6 RBD is the RADOS Block Device A specific RBD instance in the cluster is called an \u201cimage\u201d RBD images can be accessed by OSs other than linux librbd provides interface for gateways like iSCSI RBD allows the client to decide what to do with the storage Filesystem type; raw disk, such as for a DB; etc RBD images can accommodate 16Eb file system sizes No matter the size, the storage is distributed durably throughout the cluster Data is striped across the RADOS cluster in object sized chunks 4MB default Provides high performance and durability Notable Benefits Ability to mount with Linux or QEMU KVM clients Thinly provisioned Resizable images Image import/export Image copy or rename Read-only snapshots Revert to snapshots Copy on Write clones Useful for standing up lots of virtual machines with same base configuration High performance due to striping across cluster nodes RBD image definition: Defined storage area presented as a block device to a client RBD Storage File Storage \u00b6 POSIX Filesystem via CephFS File access is a significant use case Home directories Historical comfort with files and directories Ease of managing \u201csmall\u201d stuff broadly, in a distributed system A Use Case that\u2019s growing in popularity: HPC CephFS is fast, scalable, and flexible Fits into many existing paradigms, rather seamlessly In particular: NFS, Samba/CIFS But even better: extending Linux filesystems Requires Metadata Service (MDS) for POSIX capabilities SUSE does NOT support any FUSE clients. Ceph Users and Authentication \u00b6 Ceph Users are generally applications; applications that use the storage cluster The must common user is Admin A ceph admin user and credentials must exist Additional users and associated credentials are useful Each user must have credentials to access the storage cluster The most fundamental form of credentials in Ceph is keys Ceph Users and Keys The admin user has rights to all Ceph resources. Other users can be setup to have a subset of rights There are basically two types of Users (Actors): An individual (a person) An application (like a gateway, or some other kind of system) Most users are of the type client, and are represented as a dotted string, such as: client.admin, or client.steve, or client.swift The root linux user on the Admin node is effectively the Admin Ceph user, since the root user has all privileges to all filesystem objects on the Adminnode, including the ceph.client.admin.keyring. The root user on any of the nodes in the cluster can \u201cimpersonate\u201d all of the Ceph clients. Linux user accounts do not have any affect on the Ceph Users as managed in the dashboard. Take care to keep backups of the /etc/ceph/ directory structure, so that you don\u2019t lose these keys/keyrings. Each user must have a key/keyring, for example: /etc/ceph/ceph.client.admin.keyring on the Admin node /etc/ceph/ceph.client.storage.keyring on a storage node admin:/etc/ceph # cat ceph.client.admin.keyring [client.admin] key = AQD6pHpfAAAAABAAHJvkvLhOKZyQxm9lgnR5Qg== caps mds = \"allow *\" caps mon = \"allow *\" caps osd = \"allow *\" caps mgr = \"allow *\" data1:/etc/ceph # cat ceph.client.storage.keyring [client.storage] key = AQD8pHpfAAAAABAAHecCBgBsLIyPrJf+27eXUQ== caps mon = \"allow rw\" Ceph Keys and Keyrings A keyring contains one or more keys Each user can have its own keyring A keyring can contain multiple keys Different clients and users must have their own key, but multiple keys can be joined together in a single keyring Normally a key will be contained in a keyring Core Ceph will only recognize and use keys from keyrings Stand-alone keys are useful for other tools, like clients Ceph Authentication List The Admin node (and client.admin) can list all Users ceph auth list Create a Ceph User A typical user will have read rights to MONs, and read/write rights to a pool (osd) ceph auth get/add/get-or-create xxxxxx Create a User with ceph-authtool Create a keyring ceph-authtool -C /etc/ceph/ceph.client.richard.keyring Create a key, and place it on the keyring ceph-authtool --gen-key -n client.richard --cap osd 'allow rw pool=data' --cap mon 'allow r' /etc/ceph/ceph.client.richard.keyring Now officially tell the cluster about the key (add user to the key) ceph auth add client.richard -i /etc/ceph/ceph.client.richard.keyring Authentication with cephx The mechanism for passing keys around is cephx Authentication for users and daemons Does not provide data encryption, only authentication with keys cephx simply ensures the authenticity of actors So that no man-in-the-middle attacks can occur Other authentication mechanisms are theoretically possible Attempts to integrate LDAP and Kerberos have been made \u2026 but they have not come to full fruition yet Ceph Configuration \u00b6 Historically, the Ceph configuration was kept only in a file on the Admin node: /etc/ceph/ceph.conf, and sync'd to MONs and Storage Nodes SES DeepSea manages the ceph.conf file. Don\u2019t edit it directly; use Salt and DeepSea With Ceph Nautilus, most configuration held as objects in the Monitors using Dashboard or CLI for operation Ceph Configuration Stored in the MONs The MONs keep a configuration database Show all the configuration keys: admin:/etc/ceph # ceph config ls |less Show the configuration settings that have been customized. The dumped output also indicates an EXPERTISE LEVEL The keys also have a \u201cwho\u201d attribute. In below case, \"osd.*\" represents the \"who\", which is getting the general setting for all OSDs Ceph Configuration Settings Show configuration settings that have been customized: admin:/etc/ceph # ceph config dump WHO MASK LEVEL OPTION VALUE RO mgr advanced mgr/dashboard/GRAFANA_API_URL https://mon1.pvgl.sap.corp:3000 * mgr advanced mgr/dashboard/RGW_API_ACCESS_KEY M11I3JGQHAQM94CS910K * mgr advanced mgr/dashboard/RGW_API_HOST mon3.pvgl.sap.corp * mgr advanced mgr/dashboard/RGW_API_PORT 80 * mgr advanced mgr/dashboard/RGW_API_SECRET_KEY YWyRc3mayEPiOEUzQ2o76KePSKmVKN4fIWxgqTt6 * mgr advanced mgr/dashboard/RGW_API_USER_ID admin * mgr advanced mgr/dashboard/ssl_server_port 8443 admin:/etc/ceph # ceph config get osd.* osd_max_object_size 134217728 admin:/etc/ceph # ceph config show osd.0 \u2026\u2026 admin:/etc/ceph # ceph config show osd.11 (4 data nodes, 3 osds in each node) \u25cb Each of the configuration settings have default values ceph config show-with-defaults osd.2 | less \u25cb Ceph keeps a log of configuration changes admin:/etc/ceph # ceph config log --- 8 --- 2020-10-05 14:31:51.425902 --- + mgr/mgr/dashboard/RGW_API_USER_ID = admin --- 7 --- 2020-10-05 14:31:50.418622 --- + mgr/mgr/dashboard/RGW_API_HOST = mon3.pvgl.sap.corp --- 6 --- 2020-10-05 14:31:49.398448 --- + mgr/mgr/dashboard/RGW_API_PORT = 80 --- 5 --- 2020-10-05 14:31:48.403965 --- + mgr/mgr/dashboard/RGW_API_SECRET_KEY = YWyRc3mayEPiOEUzQ2o76KePSKmVKN4fIWxgqTt6 --- 4 --- 2020-10-05 14:31:46.905701 --- + mgr/mgr/dashboard/RGW_API_ACCESS_KEY = M11I3JGQHAQM94CS910K --- 3 --- 2020-10-05 13:15:29.530355 --- + mgr/mgr/dashboard/GRAFANA_API_URL = https://mon1.pvgl.sap.corp:3000 --- 2 --- 2020-10-05 13:15:14.349623 --- + mgr/mgr/dashboard/ssl_server_port = 8443 --- 1 --- 2020-10-05 13:13:55.637896 --- Health \u00b6 Show status admin:/etc/ceph # ceph status cluster: id: 343ee7d3-232f-4c71-8216-1edbc55ac6e0 health: HEALTH_OK services: mon: 3 daemons, quorum mon1,mon2,mon3 (age 6w) mgr: mon1(active, since 13d) mds: cephfs:1 {0=mon3=up:active} 2 up:standby osd: 12 osds: 12 up (since 9w), 12 in (since 9w) rgw: 1 daemon active (mon3) task status: scrub status: mds.mon3: idle data: pools: 7 pools, 208 pgs objects: 246 objects, 4.7 KiB usage: 14 GiB used, 82 GiB / 96 GiB avail pgs: 208 active+clean io: client: 11 KiB/s rd, 0 B/s wr, 11 op/s rd, 6 op/s wr admin:/etc/ceph # ceph health HEALTH_OK admin:/etc/ceph # ceph health detail HEALTH_OK admin:/etc/ceph # ceph mon stat e1: 3 mons at {mon1=[v2:10.58.121.186:3300/0,v1:10.58.121.186:6789/0],mon2=[v2:10.58.121.187:3300/0,v1:10.58.121.187:6789/0],mon3=[v2:10.58.121.188:3300/0v1:10.58.121.188:6789/0]}, election epoch 22, leader 0 mon1, quorum 0,1,2 mon1,mon2,mon3 admin:/etc/ceph # ceph osd stat 12 osds: 12 up (since 9w), 12 in (since 9w); epoch: e1375 admin:/etc/ceph # ceph pg stat 208 pgs: 208 active+clean; 4.7 KiB data, 2.0 GiB used, 82 GiB / 96 GiB avail; 1.2 KiB/s rd, 1 op/s Watch status -w, --watch : Watch live cluster changes --watch-debug : Watch debug events --watch-info : Watch info events --watch-sec : Watch security events --watch-warn : Watch warning events --watch-error : Watch error Scrub and Deep-Scrub \u00b6 \"Scrub\" is the process of doing a data consistency check Basically like running fsck on the cluster In Replicas: compare object metadata among replicas In EC: verify \u201ccode\u201d chunks Manual scrubbing can be done per OSD or per PG. \"osd scrub\" is just a collaborative wrapper of \"pg scrub\". ceph osd scrub osd.11 ceph pg scrub 3.33 \"scrub\" is a light process, daily Checks object size and attributes \"deep-scrub\" is a more thorough process, weekly Reads all data and checks the checksums Scrub \u2013 Manual vs Automatic You can let Ceph just do the default Run scrub daily, run deep-scrub weekly Ceph pays attention to usage and backs off when necessary You can change the defaults for both scrub and deepscrub, examples: osd_scrub_begin_week_day=6 (Saturday) osd_scrub_end_week_day=7 (Sunday) You can manually run scrubbings at any time if you suspect it\u2019s wanted or needed Manual scrubbings are not common Adjustments to Scrub Settings For most circumstances the default behavior of Scrub is adequate See current Scrub configuration settings: ceph config ls | grep osd_scrub ceph config ls | grep osd_deep_scrub ceph config get osd.* osd_scrub_begin_hour Change the settings immediately in the MON DB ceph config set osd.* osd_scrub_begin_hour 23 ceph config set osd.* osd_scrub_end_hour 5 Adjust Settings in ceph.conf with DeepSea To permanently change settings in ceph.conf This is the \u201cold\u201d way, but is still valid Remember that ceph.conf is controlled by DeepSea Add changes to /srv/salt/ceph/configuration/files/ceph.conf.d/global.conf Run the following DeepSea (Salt) commands: salt admin* state.apply ceph.configuration.create salt \\* state.apply ceph.configuration Wait for services/servers to be restarted, or tell Ceph to assimilate the ceph.conf settings now ceph config assimilate-conf -i /etc/ceph/ceph.conf Repair \u00b6 Problems Found by Scrubbing * If data (in an OSD or PG) becomes inconsistent, it will need to be repaired. You can configure scrubbing to automatically repair errors * osd_scrub_auto_repair=True * osd_scrub_auto_repair_num_errors=5 * Manually repair when appropriate * ceph osd repair osd.11 * ceph pg repair 3.33 Ceph Manager Modules \u00b6 Manager Modules help to extend the capabilities of Ceph List of Modules Supported in SES Balancer (always on) rash (always on) Dashboard DeepSea iostat Orchestrator (always on) progress (always on, tech preview) Prometheus RESTful rbd_support (always on) status (always on) telemetry volume (always on) Zabbix (plugin only, not the required agent) Enabling Manager Modules Show a list of Manager Modules ceph mgr module ls | less The output is quite long; best to pipe it through less The top of the output shows those modules that have been enabled The exhaustive output also displays the \u201cAPI\u201d of each module Manager modules are quite easy to enable and disable ceph mgr module enable ceph mgr module disable Show list of services that are active from the Modules ceph mgr services Module Capabilities Each module has its own settings, configuration Once the module is enabled, the ceph command accepts commands for the module No need to run the command as ceph mgr ... Examples: ceph crash stat ceph telemetry show Setting parameters (key/value pairs) of Modules ceph config set mgr mgr/telemetry/contact 'JD ' ceph config set mgr mgr/telemetry/description 'Training Cluster' Ceph Tell \u00b6 Tell commands are actually directed to the target service by way of the MONs ceph tell is a tool to tell a ceph daemon to perform a task \u2026 change a setting \u2026 execute a subroutine The target of ceph tell can be a single daemon or a collection of daemons All MONs: ceph tell mon.* injectargs '--mon-pg-warn-max-per-osd 4096' A specific OSD: ceph tell osd.9 bench ceph tell is the most common way to change logging for troubleshooting ceph tell . injectargs '--debug- ' ceph tell osd.7 injectargs '--debug-osd 20' ceph tell osd.7 config set debug_osd 20 A \u201c/\u201d allows you to change both the file log and memory log settings simultaneously ceph tell mon.3 injectargs '--debug-mon 0/10' (The first is the file parameter, the second is the memory parameter) Since logging can fill space, important to restore settings after investigating ceph tell mon.3 injectargs '--debug-mon 1/5' ceph tell sends its instructions via the Monitors. So what if the MONs are having problems? To avoid running commands through the MONs, go directly to thenode running the daemon ssh storage1 ceph daemon osd.29 config show ceph daemon osd.29 config set debug_osd 0/20 Use with great care Ceph Dashboard \u00b6 What's Ceph Dashboard SES WEB-based Management Interface A Ceph MGR module, built-in to Ceph The open source \"port\" of openATTIC to Ceph. Technically it\u2019s not a port of openATTIC. SUSE and Ceph Community worked on implementing the openATTIC capabilities directly within Ceph Role-based and Multi-User Management of the SES cluster Create, manage, and monitor Pools, RBDs Manage users, access keys, quotas and buckets of RGW Manage NFS exports, iSCSI targets and portals, CephFS View cluster nodes/roles, monitor performance metrics Manage Ceph settings/configuration Reduces the need to understand complex Ceph commands The dashboard is stateless, it will reflect any changes to the Ceph cluster, Highlighted Enterprise Behavior via Ceph Dashboard Uses SSL/TLS By default will use a CA and certificate created by DeepSea or provide your own CA and certificate Can run without SSL/TLS (not recommended) Multi-User and Role Management Variety of mappings, i.e.: read, create, update, delete Single Sign-On, complying with SAML 2.0 Single Sign-On, complying with SAML 2.0 Auditing on the backend, to monitor specific user activity Internationalization (I18N), with a variety of language translations Ceph Dashboard Architecture Backend is based on CherryPy framework (CherryPy is a Minimalist Python Web Framework) Frontend WebUI is based on Angular/TypeScript A custom REST API Monitoring facilitated by Prometheus Visualization of data facilitated by Grafana Dependent upon DBUS, systemd, and systems\u2019 shell Dashboard as Manager Module Ceph Dashboard runs as a Manager module Runs on each MON/MGR node Really only actively available via the active MGR Runs on \u201cstandby\u201d on the standby MGR nodes Standby Dashboards will redirect to active MGR URL Dashboard automatically switches to active MGR node Helpful High Availability feature As a MGR module, enabled and configured by DeepSea Can be disabled if unwanted URL example: https://10.58.121.186:8443 Grafana and Prometheus Prometheus collects various data about the cluster Grafana represents the data as graphs Ceph Dashboard uses both to improve insight into SES Prometheus Open source event monitoring software \"Scrapes\" (collects) data from nodes/services in the cluster Real-time Time series Custom scrapers have been created for Ceph Stores scraped data in memory and on disk Presents data to other software for graphical representation Integrated nicely with Grafana Grafana The leading open source software for time series analytics \"Dashboards\" of panels, graphs, metrics, etc. \"Dashboard\" is a slightly conflicting term, but still meaningful Renders data in a graphical way collected from Prometheus Graphs are customized for use on the Ceph Dashboard Dashboard Users Always need an \u201cAdmin\u201d user for the Dashboard \u00a7 The admin keys of the root user on the \u201cAdmin\u201d node in the cluster Dashboard Users are accounts that relate only to using the Dashboard \u00a7 Not the same as Ceph CLI users and client keys; but could coincide Any person who wants to interact with the storage cluster via the Dashboard must have a user account Variety of Users established by the Admin User, and various permissions based on Admin-defined Roles User Authentication Dashboard Administrators can setup users with specific privileges The privileges and permissions are managed as \"roles\" User accounts can be created directly in the Dashboard Stored as objects in Ceph User accounts can also be tied to other authentication mechanisms: Single Sign-On Service; SAML 2.0 compliant protocol Dashboard accounts can be managed from the Dashboard or from the CLI Example: ceph dashboard ac-user-show [] The Admin Dashboard User (the term \u201cadmin\u201d is used differently in different places) The Dashboard Admin User is not the same as other admins The \u201cadmin\u201d node is obviously not directly tied to any admin user The Admin Dashboard User is created at Deployment time Given a random password by DeepSea You must use the CLI to establish the admin password ceph dashboard ac-user-show admin ceph dashboard ac-user-set-password admin \u25cb The SES Deployment Course has set the password to mypassword admin:~ # ceph dashboard ac-user-show [\"admin\"] admin:~ # ceph dashboard ac-user-show admin {\"username\": \"admin\", \"password\": \"$2b$12$4lC/AU7jc6midTZufj4P4.rBtVzRGf7Zy7fUbD6G9YfdfVEwkwuUy\", \"roles\": [\"administrator\"], \"name\": null \"email\":null\"lastUpdate\": 1601874928} Health from the Dashboard Cluster Status Monitors OSDs Manager Daemons Hosts Object Gateways Metadata Service iSCSI Gateways Cluster Performance from Dashboard Client IOPS Client Throughput Client Read/Write Recovery Throughput Scrub Performance Data Hosts: Overall Performance Monitors: Performance Counters OSDs: Relative Read/Write bar graphs, and Overall Performance Pools: Relative Read/Write bar graphs, and Overall Performance Block images: Overall Performance CephFS: Performance Details RGW: Overall Performance Cluster Capacity from Dashboard Capacity data: Number of Pools Raw Capacity Number of Objects (Ceph objects, not user objects from RGW) Placement Groups per OSD Placement Group Status Basic Troubleshooting \u00b6 Ceph Logs Logs normally stored in /var/log/ceph/ No real logs on the admin node Each service has its own log on the MON, Storage and Gateway nodes Logs handled routinely by logrotate Ceph has logs that are stored to files and in memory (triggered by event or manual request) There are 21 different levels of logging: 0-20 (0 is no logging; 20 is the most verbose logging) There are many subsystems that do their own logging, and can be configured independently Most common: mon, osd, mgr, rados, rbd, mds, rgw Others: asok, auth, client, filestore, journal, monc, ms, paxos, and more There are only 3 types of daemons: osd, mon, mds Using Tell to Change Log Levels 1) Check the Dashboard and Health. Common commands ceph status ceph osd status ceph osd df ceph osd utilization ceph osd pool stats ceph osd tree ceph pg stat 2) Network Troubleshooting Always be sure that the network (and related services) are working properly Ceph depends heavily on tightly synchronized time; make sure network time services are working on each node DNS hostnames are similarly essential 3) Check the Logs Go to the node of the component implicated in HEALTH 4: Raise the DEBUG Level. Follow this simple formula: Raise the debug level (a little each time until you see the problem) Check the logs Repeat as necessary Don\u2019t forget to restore the debug level back to its normal level 5) Check the Storage Device If the problem is with an OSD or a storage device, go straight to the device: hdparm smartctl And check out the details of the combination of OSD and storage device: lsblk /var/lib/ceph/osd/ 6) Scrub (or not) Sometimes simply scrubbing an OSD or PG can cause the checksum-ing process to reveal problems At least some problems can be made more clear with the result of scrub and/or deep-scrub Even doing a scrub can kick Ceph into fixing the problem itself And don\u2019t forget ceph osd repair On the other hand, sometimes Scrub can make things worse. If you suspect Scrub is part of the problem, turn it off: ceph osd set noscrub ceph osd unset noscrub 7) Placement Groups When Placement Groups cause problems: * ceph pg dump summary * ceph pg dump pools * ceph pg dump_jason * ceph pg dump | less Followed by a strategic \u201crepair\u201d of the PG * ceph pg repair 8) Running supportconfig YaST Support Module From CLI: supportconfig The collected data is stored in a file called /var/log/nts__.txz","title":"SUSE Enterprise Storage Foundation"},{"location":"linux/SES/linux_ses_memo/#suse-enterprise-storage-foundation","text":"","title":"SUSE Enterprise Storage Foundation"},{"location":"linux/SES/linux_ses_memo/#cephs-rados","text":"Everything in Ceph is stored in the RADOS cluster as Objects. Ceph\u2019s RADOS: Reliable Autonomous Distributed Object Store Ceph\u2019s RADOS is composed of storage devices represented as: Raw storage device with LVM (BlueStore) Standard filesystem (FileStore) The Object Storage Daemon (OSD) integrates each disk device as part of the RADOS cluster.","title":"Ceph\u2019s RADOS"},{"location":"linux/SES/linux_ses_memo/#ceph-architecture","text":"Ceph is made of two groups of core components The RADOS cluster Provides the clustered object storage Native Object Access methods Gateways Access to the object store via standard protocols librados Direct access to the object store using a native API Examples: iSCSI Gateway (block) -- IGW - iSCSI is a storage area network (SAN) protocol. Exports RADOS Block Device (--RBD) (images as iSCSI disks). iSCSI access to RDB images. lrbd is no longer used in SES6. RADOS Gateway (object) -- RGW Is an object storage interface built on top of librados CephFS (file) A MetaData Service (MDS) is required. Direct access to RADOS (no LIBRADOS layer) Traditional filesystem interface. NFS Ganesha (object, file) Provides NFS exports to: RGW buckets for access the object store The CephFS filesystem Client access the storage services of the cluster via Gateways and Librados The librados API allows interaction with the following daemons: The Ceph Monitor, which maintains a master copy of the cluster map The Ceph OSD Daemon (OSD), which stores data as objects on a storage node.","title":"Ceph architecture"},{"location":"linux/SES/linux_ses_memo/#enhanced-ses-architecture-diagram","text":"","title":"Enhanced SES Architecture Diagram"},{"location":"linux/SES/linux_ses_memo/#object-storage","text":"The state of the art of distributed SDS storage Unstructured, to better accommodate large files and large quantities of files For large files and large quantities of files, it performs far better than other storage mechanisms Agile, scalable, extensible, and very customizable Invisible to the end-user, ideal for backends Perfect for systemic, application-based use cases. Not necessarily perfect for direct Human use Through associated metadata, ideal for computational analytics And CRUSH takes full advantage of this (CRUSH = Controllable Replication Under Scalable Hashing) Ceph Object Storage supports two interfaces: S3-compatible Swift-compatible Object-based storage has become the standard backend storage mechanism for nearly all modern Enterprise Storage Solutions.","title":"Object Storage"},{"location":"linux/SES/linux_ses_memo/#ceph-osds-object-storage-daemon","text":"A Ceph OSD (object storage daemon, ceph-osd) stores data, handles data replication, recovery, rebalancing, and provides some monitoring information to Ceph Monitors and Managers by checking other Ceph OSD Daemons for a heartbeat. The Ceph Storage Cluster receives data from Ceph Clients. Clients (dedicated access points, e.g., gateway) could be a Ceph Block Device, Ceph Object Storage, the Ceph Filesystem or a custom implementation using librados. The client requests the cluster status from a monitor node The client uses the status information to identify the location of objects in the cluster The client accesses the objects directly via the OSD node The OSD then stores the data as objects. Each object corresponds to a file in a filesystem which is stored on an OSD. The OSD Daemons take care of the reads and writes on the storage disks. When OSDs are deployed in SES5 the default is to use BlueStore which uses the raw disk and does not require a linux file system to be placed on the disk before it can be used. OSD Daemons store all data as objects in a flat namespace, i.e. no hierarchy of directories. At least 3 Ceph OSDs are normally required for redundancy and high availability.","title":"Ceph OSDs (Object Storage Daemon)"},{"location":"linux/SES/linux_ses_memo/#ceph-mons-monitor-servers","text":"A Ceph Monitor (ceph-mon) maintains maps of the cluster state, including Monitor Map Manager Map OSD Map PG Map CRUSH Map Epoch These maps are critical cluster state required for Ceph daemons to coordinate with each other. Monitors are also responsible for managing authentication between daemons and clients. At least 3 monitors are normally required for redundancy and high availability. An odd number of MONs is required (Paxos requires). Typically 5 is sufficient for mid or large size cluster. Paxos is an algorithm used for cluster durability. Leader MON expects 50% quality to create quorum. Lowest IP address becomes leader. After new leader selected, all MONs polled for epoch. Leader Mon provides lease to non-leader MONs. MONs are NOT in the data path. They merely serve maps to clients so that the client can go directly to the appropriate OSD storage daemon. Monitor nodes MONs do not serve objects to clients","title":"Ceph Mons (Monitor Servers)"},{"location":"linux/SES/linux_ses_memo/#ceph-mgrs-manager-daemon","text":"A Ceph Manager daemon (ceph-mgr) is responsible for keeping track of runtime metrics and the current state of the Ceph cluster, including storage utilization current performance metrics system load The Ceph Manager daemons also host python-based plugins to manage and expose Ceph cluster information, including a web-based dashboard and REST API. At least two managers are normally required for high availability. MON/MGR daemons are required to run on the same node in SES","title":"Ceph MGRs (Manager Daemon)"},{"location":"linux/SES/linux_ses_memo/#ceph-mds-metadata","text":"A Ceph Metadata Server (MDS, ceph-mds) stores metadata on behalf of the Ceph Filesystem. Ceph Metadata Servers allow POSIX file system users to execute basic commands, for example ls -al without placing an large load on the Ceph Storage Cluster.","title":"Ceph MDS (Metadata)"},{"location":"linux/SES/linux_ses_memo/#ceph-admin-node","text":"The Admin node fills the \u201cmaster\u201d and \u201cadmin\u201d roles for DeepSea. Salt is central to SES. SES\u2019s deployment and life-cycle management tool. The Admin node keeps master Ceph authentication keys. Prometheus and Grafana provide cluster monitoring and data graphs","title":"Ceph Admin Node"},{"location":"linux/SES/linux_ses_memo/#ceph-dashboard","text":"Runs as a Ceph Manager module; runs via the MON/MGR node.","title":"Ceph Dashboard"},{"location":"linux/SES/linux_ses_memo/#client-access","text":"Object Storage (RADOSGW or RGW) Block Storage (RDB). RBD is built on top of librados. CephFS iSCSI Gateway NFS Ganesha SMB/CIFS Native protocols via librados","title":"Client Access"},{"location":"linux/SES/linux_ses_memo/#objects-in-ceph","text":"Everything stored in the Ceph cluster is an object. Default object size is 4MB. Each object has a unique ID. ID is unique across the entire cluster. Objects have associated metadata, in Key: Value pairs. In Ceph we use Storage Pools to organize or arrange our objects. Pools are logical partitions to manage objects Parameters to manage Pools Number of data replicas (Replica pools), or configuration of Erasure Code (size) (Erasure Code pools) Erasure Code is an alternative to Replication SIZE for Erasure Coding is K+M K = Data chunks, M = \u201cParity\u201d chunks EC reduces the hit to raw storage capacity EC incurs a greater hit to CPU on the OSDs as a tradeoff Placement Groups (PG) PG is used to manage objects within a pool. PGs are associated with OSDs for data placement PGs are a central feature of CRUSH that help to provide data durability by way of distribution No PG is owned by an OSD. (And an OSD is not owned by a PG.) PGs are just randomly assigned by CRUSH through all of the OSDs to spread the distribution of data Locating data among PGs is all handled economically, deterministically by way of CRUSH calculations PGs are subdivisions of pools Number of PGs = (Number of OSDs * 100) / Size (Size = either num of replicas, or K+M) The final PG number must be a power of 2 The default number of PGs for a new pool is 8 (it's too small for enterprise solution) In general, PG and PGP numbers should be the same pg_num is the number of placement groups for the pool (placement group, \u5b58\u50a8\u6c60\u7684\u76ee\u5f55\u4e2a\u6570 ) pgp_num is the number of placement groups that will be considered for placement (placement group for placement purpose, pg\u53ef\u7528\u7684osd\u6392\u5217\u7ec4\u5408\u6570\u91cf) \u4ec5\u589e\u5927pg_num\uff1a \u56e0\u4e3apgp_num\u6ca1\u53d8\uff0cpg\u7684osd\u7ec4\u5408\u4ecd\u53ea\u80fd\u4ece\u5f53\u524dpgp_num\u79cd\u7ec4\u5408\u91cc\u9762\u6311\u9009\uff0c\u5bfc\u81f4\u65b0\u589e\u7684pg\u548c\u65e7pg\u4f1a\u6709\u91cd\u590d\u7684osd\u7ec4\u5408\uff0c\u8be5\u73b0\u8c61\u79f0\u4e4b\u4e3a\u5206\u88c2\uff1b\u6b64\u65f6pg\u548cosd\u7684\u6620\u5c04\u6ca1\u6709\u53d8\uff1b \u7ee7\u7eed\u589e\u5927pgp_num\uff0c\u4f7f\u5176\u7b49\u4e8epg_num\uff1a \u65e7pg\u6ca1\u6709\u53d8\u5316\uff0c\u4f46\u65b0\u589epg\u7684osd\u7ec4\u5408\u53d1\u751f\u53d8\u5316\uff0c\u5373\u5f00\u59cb\u91cd\u65b0\u5206\u5e03 Placement Group (PG) \u5f52\u7f6e\u7ec4\u72b6\u6001 Creating \u521b\u5efa\u5b58\u50a8\u6c60\u65f6\uff0c\u5b83\u4f1a\u521b\u5efa\u6307\u5b9a\u6570\u91cf\u7684\u5f52\u7f6e\u7ec4\u3002 ceph \u5728\u521b\u5efa\u4e00\u6216\u591a\u4e2a\u5f52\u7f6e\u7ec4\u65f6\u4f1a\u663e\u793a creating\u3002 \u521b\u5efa\u5b8c\u540e\uff0c\u5728\u5176\u5f52\u7f6e\u7ec4\u7684 Acting Set \u91cc\u7684 OSD \u5c06\u5efa\u7acb\u4e92\u8054\u3002 \u4e00\u65e6\u4e92\u8054\u5b8c\u6210\uff0c\u5f52\u7f6e\u7ec4\u72b6\u6001\u5e94\u8be5\u53d8\u4e3a active+clean\uff0c\u610f\u601d\u662fceph \u5ba2\u6237\u7aef\u53ef\u4ee5\u5411\u5f52\u7f6e\u7ec4\u5199\u5165\u6570\u636e\u4e86\u3002 peering ceph \u4e3a\u5f52\u7f6e\u7ec4\u5efa\u7acb\u4e92\u8054\u65f6\uff0c\u4f1a\u8ba9\u5b58\u50a8\u5f52\u7f6e\u7ec4\u526f\u672c\u7684 OSD \u4e4b\u95f4\u5c31\u5176\u4e2d\u7684\u5bf9\u8c61\u548c\u5143\u6570\u636e\u72b6\u6001\u8fbe\u6210\u4e00\u81f4\u3002 ceph \u5b8c\u6210\u4e86\u4e92\u8054\uff0c\u4e5f\u5c31\u610f\u5473\u7740\u5b58\u50a8\u7740\u5f52\u7f6e\u7ec4\u7684 OSD \u5c31\u5176\u5f53\u524d\u72b6\u6001\u8fbe\u6210\u4e86\u4e00\u81f4\u3002 \u7136\u800c\uff0c\u4e92\u8054\u8fc7\u7a0b\u7684\u5b8c\u6210\u5e76\u4e0d\u80fd\u8868\u660e\u5404\u526f\u672c\u90fd\u6709\u4e86\u6570\u636e\u7684\u6700\u65b0\u7248\u672c\u3002 active ceph \u5b8c\u6210\u4e92\u8054\u8fdb\u7a0b\u540e,\u4e00\u5f52\u7f6e\u7ec4\u5c31\u53ef\u53d8\u4e3a active\u3002 active \u72b6\u6001\u901a\u5e38\u610f\u5473\u7740\u5728\u4e3b\u5f52\u7f6e\u7ec4\u548c\u526f\u672c\u4e2d\u7684\u6570\u636e\u90fd\u53ef\u4ee5\u8bfb\u5199\u3002 clean \u67d0\u4e00\u5f52\u7f6e\u7ec4\u5904\u4e8e clean \u72b6\u6001\u65f6\uff0c\u4e3b OSD \u548c\u526f\u672c OSD \u5df2\u6210\u529f\u4e92\u8054\uff0c\u5e76\u4e14\u6ca1\u6709\u504f\u79bb\u7684\u5f52\u7f6e\u7ec4\u3002 ceph \u5df2\u628a\u5f52\u7f6e\u7ec4\u4e2d\u7684\u5bf9\u8c61\u590d\u5236\u4e86\u89c4\u5b9a\u6b21\u6570\u3002 degraded \u5f53\u5ba2\u6237\u7aef\u5411\u4e3b OSD \u5199\u5165\u6570\u636e\u65f6\uff0c\u7531\u4e3b OSD \u8d1f\u8d23\u628a\u526f\u672c\u5199\u5165\u5176\u4f59\u590d\u5236 OSD\u3002 \u4e3b OSD \u628a\u5bf9\u8c61\u5199\u5165\u590d\u5236 OSD \u540e\uff0c\u5728\u6ca1\u6536\u5230\u6210\u529f\u5b8c\u6210\u7684\u786e\u8ba4\u524d\uff0c\u4e3b OSD \u4f1a\u4e00\u76f4\u505c\u7559\u5728 degraded \u72b6\u6001\u3002 \u5f52\u7f6e\u7ec4\u72b6\u6001\u53ef\u4ee5\u662f active+degraded \u72b6\u6001\uff0c\u539f\u56e0\u5728\u4e8e\u4e00 OSD \u5373\u4f7f\u6ca1\u6240\u6709\u5bf9\u8c61\u4e5f\u53ef\u4ee5\u5904\u4e8e active \u72b6\u6001\u3002 \u5982\u679c\u4e00OSD \u6302\u4e86\uff0cceph \u4f1a\u628a\u76f8\u5173\u7684\u5f52\u7f6e\u7ec4\u90fd\u6807\u8bb0\u4e3a degraded\u3002 \u90a3\u4e2a OSD \u91cd\u751f\u540e\uff0c\u5b83\u4eec\u5fc5\u987b\u91cd\u65b0\u4e92\u8054\u3002 \u7136\u800c\uff0c\u5982\u679c\u5f52\u7f6e\u7ec4\u4ecd\u5904\u4e8e active \u72b6\u6001\uff0c\u5373\u4fbf\u5b83\u5904\u4e8e degraded \u72b6\u6001\uff0c\u5ba2\u6237\u7aef\u8fd8\u53ef\u4ee5\u5411\u5176\u5199\u5165\u65b0\u5bf9\u8c61\u3002 \u5982\u679c\u4e00 OSD \u6302\u4e86\uff0c\u4e14 degraded \u72b6\u6001\u6301\u7eed\uff0cceph \u4f1a\u628a down \u7684 OSD \u6807\u8bb0\u4e3a\u5728\u96c6\u7fa4\u5916(out)\u3001\u5e76\u628a\u90a3\u4e9b down \u6389\u7684 OSD \u4e0a\u7684\u6570\u636e\u91cd\u6620\u5c04\u5230\u5176\u5b83 OSD\u3002 \u4ece\u6807\u8bb0\u4e3a down \u5230 out \u7684\u65f6\u95f4\u95f4\u9694\u7531 mon osd down out interval \u63a7\u5236,\u9ed8\u8ba4\u662f 300 \u79d2\u3002 \u5f52\u7f6e\u7ec4\u4e5f\u4f1a\u88ab\u964d\u7ea7(degraded)\uff0c\u56e0\u4e3a\u5f52\u7f6e\u7ec4\u627e\u4e0d\u5230\u672c\u5e94\u5b58\u5728\u4e8e\u5f52\u7f6e\u7ec4\u4e2d\u7684\u4e00\u6216\u591a\u4e2a\u5bf9\u8c61\uff0c\u8fd9\u65f6\uff0c\u4f60\u4e0d\u80fd\u8bfb\u6216\u5199\u627e\u4e0d\u5230\u7684\u5bf9\u8c61\uff0c\u4f46\u4ecd\u80fd\u8bbf\u95ee\u5176\u5b83\u4f4d\u4e8e\u964d\u7ea7\u5f52\u7f6e\u7ec4\u4e2d\u7684\u5bf9\u8c61\u3002 recovering ceph \u88ab\u8bbe\u8ba1\u4e3a\u53ef\u5bb9\u9519\uff0c\u53ef\u62b5\u5fa1\u4e00\u5b9a\u89c4\u6a21\u7684\u8f6f\u3001\u786c\u4ef6\u95ee\u9898\u3002 \u5f53\u67d0 OSD \u6302\u4e86(down)\u65f6\uff0c\u5176\u5185\u5bb9\u7248\u672c\u4f1a\u843d\u540e\u4e8e\u5f52\u7f6e\u7ec4\u5185\u7684\u5176\u5b83\u526f\u672c\u3002 \u5b83\u91cd\u751f(up)\u65f6\uff0c\u5f52\u7f6e\u7ec4\u5185\u5bb9\u5fc5\u987b\u66f4\u65b0\uff0c\u4ee5\u53cd\u6620\u5f53\u524d\u72b6\u6001\u3002 \u5728\u6b64\u671f\u95f4\uff0cOSD \u5728recovering \u72b6\u6001\u3002 \u4e00\u6b21\u786c\u4ef6\u5931\u8d25\u53ef\u80fd\u7275\u8fde\u591a\u4e2a OSD\u3002\u6bd4\u5982\u4e00\u4e2a\u673a\u67dc\u7684\u7f51\u7edc\u4ea4\u6362\u673a\u5931\u8d25\u4e86\uff0c\u8fd9\u4f1a\u5bfc\u81f4\u591a\u4e2a\u4e3b\u673a\u843d\u540e\u4e8e\u96c6\u7fa4\u7684\u5f53\u524d\u72b6\u6001\uff0c\u95ee\u9898\u89e3\u51b3\u540e\u6bcf\u4e00\u4e2a OSD \u90fd\u5fc5\u987b\u6062\u590d\u3002 ceph \u63d0\u4f9b\u4e86\u5f88\u591a\u9009\u9879\u6765\u5747\u8861\u8d44\u6e90\u7ade\u4e89\uff0c\u5982\u65b0\u670d\u52a1\u8bf7\u6c42\u3001\u6062\u590d\u6570\u636e\u5bf9\u8c61\u548c\u6062\u590d\u5f52\u7f6e\u7ec4\u5230\u5f53\u524d\u72b6\u6001\u3002 osd recovery delay start \u9009\u9879\u5141\u8bb8\u4e00 OSD \u5728\u5f00\u59cb\u6062\u590d\u8fdb\u7a0b\u524d\uff0c\u5148\u91cd\u542f\u3001\u91cd\u5efa\u4e92\u8054\u3001\u751a\u81f3\u5904\u7406\u4e00\u4e9b\u91cd\u653e\u8bf7\u6c42\u3002 osd recovery threads \u9009\u9879\u9650\u5236\u6062\u590d\u8fdb\u7a0b\u7684\u7ebf\u7a0b\u6570\uff0c\u9ed8\u8ba4\u4e3a 1 \u7ebf\u7a0b\u3002 osd recovery thread timeout \u8bbe\u7f6e\u7ebf\u7a0b\u8d85\u65f6\uff0c\u56e0\u4e3a\u591a\u4e2aOSD \u53ef\u80fd\u4ea4\u66ff\u5931\u8d25\u3001\u91cd\u542f\u548c\u91cd\u5efa\u4e92\u8054\u3002 osd recovery max active \u9009\u9879\u9650\u5236\u4e00 OSD \u6700\u591a\u540c\u65f6\u63a5\u53d7\u591a\u5c11\u8bf7\u6c42\uff0c\u4ee5\u9632\u5b83\u538b\u529b\u8fc7\u5927\u800c\u4e0d\u80fd\u6b63\u5e38\u670d\u52a1\u3002 osd recovery max chunk \u9009\u9879\u9650\u5236\u6062\u590d\u6570\u636e\u5757\u5c3a\u5bf8\uff0c\u4ee5\u9632\u7f51\u7edc\u62e5\u585e\u3002 back filling \u6709\u65b0 OSD \u52a0\u5165\u96c6\u7fa4\u65f6\uff0cCRUSH \u4f1a\u628a\u73b0\u6709\u96c6\u7fa4\u5185\u7684\u5f52\u7f6e\u7ec4\u91cd\u5206\u914d\u7ed9\u5b83\u3002 \u5f3a\u5236\u65b0 OSD \u7acb\u5373\u63a5\u53d7\u91cd\u5206\u914d\u7684\u5f52\u7f6e\u7ec4\u4f1a\u4f7f\u4e4b\u8fc7\u8f7d\uff0c\u7528\u5f52\u7f6e\u7ec4\u56de\u586b\u53ef\u4f7f\u8fd9\u4e2a\u8fc7\u7a0b\u5728\u540e\u53f0\u5f00\u59cb\u3002 \u56de\u586b\u5b8c\u6210\u540e\uff0c\u65b0 OSD \u51c6\u5907\u597d\u65f6\u5c31\u53ef\u4ee5\u5bf9\u5916\u670d\u52a1\u4e86\u3002 remapped \u67d0\u4e00\u5f52\u7f6e\u7ec4\u7684 Acting Set \u53d8\u66f4\u65f6\uff0c\u6570\u636e\u8981\u4ece\u65e7\u96c6\u5408\u8fc1\u79fb\u5230\u65b0\u7684\u3002 \u4e3b OSD \u8981\u82b1\u8d39\u4e00\u4e9b\u65f6\u95f4\u624d\u80fd\u63d0\u4f9b\u670d\u52a1\uff0c\u6240\u4ee5\u5b83\u53ef\u4ee5\u8ba9\u8001\u7684\u4e3b OSD \u6301\u7eed\u670d\u52a1\u3001\u76f4\u5230\u5f52\u7f6e\u7ec4\u8fc1\u79fb\u5b8c\u3002 \u6570\u636e\u8fc1\u79fb\u5b8c\u540e,\u4e3b OSD \u4f1a\u6620\u5c04\u5230\u65b0 acting set\u3002 stale \u867d\u7136 ceph \u7528\u5fc3\u8df3\u6765\u4fdd\u8bc1\u4e3b\u673a\u548c\u5b88\u62a4\u8fdb\u7a0b\u5728\u8fd0\u884c\uff0c\u4f46\u662f ceph-osd \u4ecd\u6709\u53ef\u80fd\u8fdb\u5165 stuck \u72b6\u6001\uff0c\u5b83\u4eec\u6ca1\u6709\u6309\u65f6\u62a5\u544a\u5176\u72b6\u6001(\u5982\u7f51\u7edc\u77ac\u65ad)\u3002 \u9ed8\u8ba4OSD \u5b88\u62a4\u8fdb\u7a0b\u6bcf\u534a\u79d2(0.5)\u4f1a\u4e00\u6b21\u62a5\u544a\u5176\u5f52\u7f6e\u7ec4\u3001\u51fa\u6d41\u91cf\u3001\u5f15\u5bfc\u548c\u5931\u8d25\u7edf\u8ba1\u72b6\u6001\uff0c\u6b64\u9891\u7387\u9ad8\u4e8e\u5fc3\u8df3\u9600\u503c\u3002 \u5982\u679c\u4e00\u5f52\u7f6e\u7ec4\u7684\u4e3b OSD \u6240\u5728\u7684 acting set \u6ca1\u80fd\u5411\u76d1\u89c6\u5668\u62a5\u544a\u3001\u6216\u8005\u5176\u5b83\u76d1\u89c6\u5668\u5df2\u7ecf\u62a5\u544a\u4e86\u90a3\u4e2a\u4e3b OSD \u5df2 down\uff0c\u76d1\u89c6\u5668\u4eec\u5c31\u4f1a\u628a\u6b64\u5f52\u7f6e\u7ec4\u6807\u8bb0\u4e3a stale\u3002 \u542f\u52a8\u96c6\u7fa4\u65f6\uff0c\u4f1a\u7ecf\u5e38\u770b\u5230 stale \u72b6\u6001\uff0c\u76f4\u5230\u4e92\u8054\u5b8c\u6210\u3002 \u96c6\u7fa4\u8fd0\u884c\u4e00\u9635\u540e\uff0c\u5982\u679c\u8fd8\u80fd\u770b\u5230\u6709\u5f52\u7f6e\u7ec4\u4f4d\u4e8e stale \u72b6\u6001\uff0c\u5c31\u8bf4\u660e\u90a3\u4e9b\u5f52\u7f6e\u7ec4\u7684\u4e3b OSD \u6302\u4e86(down)\u3001\u6216\u6ca1\u5728\u5411\u76d1\u89c6\u5668\u62a5\u544a\u7edf\u8ba1\u4fe1\u606f\u3002 Each pool has its own autoscaler settings The PG balancer optimizes the placement of PGs across OSD crush-compat mode It's default mode Uses the compat weight-set feature upmap mode. It's perfect mode, which an equal number of PGs on each OSD Use fine-grained control over the PG mapping Snapshots Rulesets to manage CRUSH placement Each pool has a defined CRUSH ruleset A CRUSH ruleset is a definition of how the OSDs organize data This allows configuration of data distribution to be managed per pool A single CRUSH ruleset can be reused by multiple pools A ruleset can take into account: \u9700\u8981\u8003\u8651\u7684\u70b9 physical layout of nodes in the cluster organization of network infrastructure selection of OSDs backed by SSDs versus HDDs, etc Each pool can use either Replication or Erasure Coding Replication is the original, default approach to resiliency Erasure Coded pools have an EC Profile assigned Different than CRUSH rulesets, but similar: define how OSDs organize data The profile defines K, M values; encoding method/plugin; etc","title":"Objects in Ceph"},{"location":"linux/SES/linux_ses_memo/#crush-controllable-replication-under-scalable-hashing","text":"CRUSH is a key piece of the Ceph storage solution With the CRUSH algorithm used by Ceph: Data is not centrally stored, it is distributed CRUSH calculates the storage location for each object dynamically No requirement to store a global index of object locations","title":"CRUSH (Controllable Replication Under Scalable Hashing)"},{"location":"linux/SES/linux_ses_memo/#crush-algorithm","text":"The CRUSH algorithm deterministically calculates the location of any object in the Ceph RADOS cluster Overhead is low and calculation is performed by each client As no metadata store is required, CRUSH removes the limitations of traditional metadata based management No direct control over the placement of your data in the cluster Higher CPU requirements","title":"CRUSH Algorithm"},{"location":"linux/SES/linux_ses_memo/#crush-maps-and-rulesets","text":"CRUSH Rulesets are the named sets of rules: Combining all of the customizable CRUSH behavior settings Assigned to pool to govern how the pool\u2019s data is distributed in the cluster CRUSH Maps are central to how Ceph distributes data, and maintaining the durability of the data When the cluster is deployed, Ceph creates a simple default ruleset for replicated pools: replicated_rule CRUSH behavior depends on the behaviors and performance of storage devices CRUSH Maps should be crafted to take advantage of those behaviors Rulesets should be used to clearly identify how the devices in your environment should be employed Device Classes exist to indicate performance behavior: hdd, ssd, nvme Ceph OSDs will automatically set the Device Class of a storage device when the OSD is started Working with CRUSH Map Rulesets List the OSDs, which host each OSD belongs to: ceph osd tree ceph osd df tree ceph osd df tree -f json-pretty Find the host of a specific OSD: ceph osd find 8 Show the existing defined rulesets: ceph osd crush rule ls Examine the definition of an existing ruleset: ceph osd crush rule dump There are 3 options for creating a new ruleset: simple replicated erasure Creating new rulesets: ceph osd crush rule create-replicated ceph osd crush rule create-erasure Create a new ruleset using a Device Class: create-replicated Description : The name of the node under which data should be placed. Type : String Example : default (rarely would you need to make this different than \u201cdefault\u201d) or Description : The type of CRUSH node (bucket) across which replicas should be separated. Type : String Example : rack Description : The device class data should be placed on. Type : String Example : ssd","title":"CRUSH Maps and Rulesets"},{"location":"linux/SES/linux_ses_memo/#crush-weight","text":"You may need to move data around New nodes degraded nodes rebalancing View the current CRUSH weights ceph osd crush tree ceph osd df tree Change the weight for an OSD ceph osd crush reweight The important difference between ceph osd reweight and ceph osd crush reweight \"ceph osd crush reweight\" sets the CRUSH weight of the OSD. This weight is an arbitrary value (generally the size of the disk in TB or something) and controls how much data the system tries to allocate to the OSD. \"ceph osd reweight\" sets an override weight on the OSD. This value is in the range 0 to 1, and forces CRUSH to re-place (1-weight) of the data that would otherwise live on this drive. It does not change the weights assigned to the buckets above the OSD, and is a corrective measure in case the normal CRUSH distribution isn\u2019t working out quite right. \"ceph osd reweight\" is temporary. \"ceph osd crush reweight\" is sticky, permanent (until you change it again). Setting a weight of an OSD to 0 is effectively setting the OSD \"out\" - you don\u2019t want it to store data.","title":"CRUSH Weight"},{"location":"linux/SES/linux_ses_memo/#the-monitors-cluster-map-contains","text":"Monitor Map Unique Cluster ID, details of each Mon node, current epoch, date/time of last change OSD Map Contains the cluster fsid, when the map was created and last modified, a list of pools, replica sizes, PG numbers, a list of OSDs and their status PG Map Contains the PG version, its time stamp, the last OSD map epoch, the full ratios, and details on each placement group such as the PG ID, the Up Set, the Acting Set, the state of the PG (e.g., active + clean), and data usage statistics for each pool MDS Map Contains the current MDS map epoch, references to pool(s) for storing metadata, list of MDS servers, and which metadata servers are up and in CRUSH Map Contains a list of storage devices, the failure domain hierarchy (e.g., device, host, rack, row, room, etc.), and rules for traversing the hierarchy when storing data","title":"The Monitor\u2019s Cluster Map contains"},{"location":"linux/SES/linux_ses_memo/#crush-hierarchy","text":"The CRUSH Map includes details of physical & network infrastructure The CRUSH Map hierarchy is defined by a storage architect The default hierarchical list of infrastructure elements: (Hierarchy of CRUSH buckets) OSD host chassis \u5200\u7247\u673a\u7bb1 rack \u673a\u67b6 row pdu \u7535\u6e90\u5206\u914d\u5355\u5143 pod \u6027\u80fd\u4f18\u5316\u7684\u6570\u636e\u4e2d\u5fc3(Performance Optimize Datacenter)\uff0c\u57fa\u4e8e\u6807\u51c6\u5316\u8bbe\u65bd\u7684\u6700\u4f73\u5b9e\u8df5\uff0c\u6bcf\u4e2aPOD\u5185IT\u90e8\u5206\u5305\u542b\u76845000\u53f0\u670d\u52a1\u5668\uff0c\u5206\u5c5e\u5230200\u4e2a\u673a\u67b6\uff0c\u5982\u679c\u4ee5\u6bcf\u53f0\u670d\u52a1\u5668400W\u529f\u7387\u8ba1\u7b97\u7684\u8bdd\uff0c\u6bcf\u4e2a\u673a\u67dc\u9700\u898110KW\u7684\u4f9b\u7535\uff0c\u5373\u6bcf\u4e2aPOD\u7684IT\u8d1f\u8f7d\u5bb9\u91cf\u662f2MW\u3002 room datacenter region root CRUSH is the algorithm and calculation for distributing data through the cluster. CRUSH Map obviously plays a part in how those CRUSH calculations work.","title":"CRUSH Hierarchy"},{"location":"linux/SES/linux_ses_memo/#crush-map-sections-six-main-sections","text":"tunables: adjustments to legacy behavior devices: The list of OSDs (usually no customization needed) \u25cb \"device class\" is meaningful; useful in relation to creating/using CRUSH rulesets \u25cb Standard \"device class\" values are \"hdd.\", \"ssd.\", and \"nvme.\" \u25cb Example: device 7 osd.7 types: types of buckets (usually no customization needed) buckets: the most functional, customizable aspect of the Map \u25cb A bucket typically represents a physical location in the cluster, has a \u201ctype\u201d \u25cb Nodes (containers such as hosts) and leaves (storage devices such as OSDs) rules: define policies of how data should be distributed \u25cb The behind-the-scenes rules that CRUSH follows for data placement \u25cb IMPORTANT: this is NOT the same as the \"ruleset\". In fact, a ruleset is the combined set of all of these six Map sections. choose_args (optional): Rarely used exceptional settings to adjust weights From the documentation: \"choose_args are alternative weights associated with the hierarchy that have been adjusted to optimize data placement. A single choose_args map can be used for the entire cluster, or one can be created for each individual pool.\"","title":"CRUSH Map Sections (Six main sections)"},{"location":"linux/SES/linux_ses_memo/#erasure-coding","text":"In information theory : an erasure code is a forward error correction (FEC, \u524d\u5411\u7ea0\u9519) code for the binary erasure channel, which transforms a message of k symbols into a longer message (code word) with n symbols such that the original message can be recovered from a subset of the n symbols. The fraction r = k/n is called the code rate The fraction k\u2019/k, where k\u2019 denotes the number of symbols required for recovery, is called reception efficiency Another (easier) way of describing EC: It\u2019s like RAID in Clustered Storage","title":"Erasure Coding"},{"location":"linux/SES/linux_ses_memo/#erasure-coding-in-ses","text":"The default resilience strategy in SES is simple replication * SES Simple replication has overheads, size=3 means 3 times the storage requirements Simplistic EC details: k = number of \u201cdata\u201d chunks, split across \u201ck\u201d number of OSDs m = number of \u201cparity\u201d chunks, split across \u201cm\u201d number of OSDs Ceph calls these \u201ccoding chunks\u201d r (size) = k + m admin:~ # ceph osd crush rule ls replicated_rule","title":"Erasure Coding in SES"},{"location":"linux/SES/linux_ses_memo/#replication-vs-erasure-code","text":"Replication (default): Use Case: active data Simple and fast Uses more disk space Erasure coding: Use Case: archive data, more static data Calculates recovery data (needs more CPU power) Definable redundancy level Example: K data chunks = 2 , M code chunks = 1 Similar to a replication size of 2 But with only 50% more raw storage consumed Example: for 1GB of effective storage replication pool of size of 2 needs 2GB raw storage erasure coded pool with k=2/m=1 only requires 1.5GB raw storage","title":"Replication vs Erasure Code"},{"location":"linux/SES/linux_ses_memo/#ec-overwrites","text":"Historically, EC only works properly with Objects EC only allowed appends; overwrites were not allowed Works perfectly for objects in buckets but doesn\u2019t work well with Block or CephFS With recent releases of SES, EC can work well with Block and CephFS Facilitated by \u201cEC Overwrites\u201d feature Store data in an EC Pool, and store object metadata in a Replicated Pool Requires a little extra work when defining pools, but worth it ceph osd pool set allow_ec_overwrites true","title":"EC Overwrites"},{"location":"linux/SES/linux_ses_memo/#ec-profiles","text":"Using Erasure Coding, each Pool is assigned an EC Profile Multiple pools can share a single Profile The profile is just a definition Each Profile has multiple settings The common required settings for all Profiles are K, M EC Profiles must be created before EC Pools can be created Created from the Dashboard or CLI Once an EC Profile is created, you can create a CRUSH Ruleset based on the EC profile Once a pool is created, its EC Profile properties cannot be changed Main profile parameters K: M: stripe_unit - allows you to adjust the size of the data chunk Default size is 4K stripe_unit : size of data striped across devices; default 4K This variable can also be set in the master configuration (osd_erasure_code_stripe_unit) EC plugins - choose your favorite EC algorithm via a plugin jerasure/gf-complete (default, free, open, and very fast) (www.jerasure.org) ISA (Intel library; optimized for modern Intel processors) (only runs on Intel processors) LRC (\u201cLocally Repairable Code\u201d; layers over existing plugins) SHEC (\u201cShingled EC\u201d; trades extra storage for recovery efficiency) CLAY (\u201cCoupled LAYer\u201d; good for reduced network traffic)","title":"EC Profiles"},{"location":"linux/SES/linux_ses_memo/#creating-erasure-code-profiles-and-pools","text":"Syntax: ceph osd erasure-code-profile OPTIONS Option Description get - view details of an existing EC profile set - set a profile (create a profile), requires k and m values, with optional values such as ruleset, plugin. Once you create a profile, you can\u2019t change it. ceph osd erasure-code-profile set k= m= [plugin=] [stripe_unit=] ls - list profiles rm - Remove an EC profile ceph osd erasure-code-profile rm Common example (below) The default profile \u2012 2+1=3; data is written over 3 OSDs \u2012 Two data chunks \u2012 One code (parity) chunk \u2012 Uses jerasure plugin with standard Reed/Solomon (reed_sol_van) technique Setting a Custom EC Profile Option: \u2012 Profile name \u2012 K : number of stripes required \u2012 M : number of failed units Example: ceph osd erasure-code-profile set example-profile k=8 m=2 ruleset-failure-domain=host ruleset-failure-domain = crush bucket level for failure admin:/etc/ceph # ceph osd erasure-code-profile \\ set common_profile \\ k=4 \\ m=2 \\ plugin=jerasure \\ technique=reed_sol_van \\ stripe_unit=4K \\ crush-root=default \\ crush-failure-domain=rackcrush-device-class=ssd admin:/etc/ceph # ceph osd erasure-code-profile ls default admin:~ # ceph osd erasure-code-profile get default k=2 m=1 plugin=jerasure technique=reed_sol_van Pools Pools are at the heart of Storage Pools are tied to OSDs Display a list of existing pools: ceph osd pool ls or ceph osd lspools View the statistics and characteristics of pools: ceph osd pool stats ceph osd pool stats ceph osd pool get Show usage and related details of existing pools: rados df or ceph df or ceph df detail All storage revolves around Pools Each pool must be dedicated to a purpose: Object, Block, File Must specify # of Placement Groups and PG Placements Must specify whether using Replication or EC Must specify a CRUSH ruleset Create a Replicated Pool Syntax: ceph osd pool create replicated = number of placement groups for the pool = number of PGs for placement; routinely will be the same as pg_num Always a power of 2 Don\u2019t make the number too small; don\u2019t err on the high side, either Practices For a new pool, the pgp_num will generally (likley) just be the same as the pg_num When increasing the PGs in a pool, you may want to retain the smaller pgp_num to minimize rebalancing, and increase pgp_num later when rebalancing is more convenient If decreasing the PGs in a pool, the pgp_num is adjusted automatically Create an EC Pool (using an EC Profile) Syntax: ceph osd pool create erasure Example: ceph osd pool create EC-pool 128 128 erasure my-ec-profile Pools \u2013 Application Assignment Each Pool must have a stated purpose; application This defines which capabilities the Pool must support The applications are: Block (rbd), Object (rgw), and File (cephfs) There are subtypes of cephfs: i.e. cephfs:data, cephfs:metadata Application assignment happens after creating a pool It\u2019s effortless (and required) to assign an application on a new pool ceph osd pool application enable Changing application assignment after a pool is in use is \u201chard\u201d. Not recommended, only to be done as an expert Pools \u2013 Quotas One of the more desirable features of SDS is to set a maximum usage of a Pool - Quotas Prevent the over-use of a pool Set quotas based on number of objects or number of bytes ceph osd pool set-quota max_objects ceph osd pool set-quota max_bytes Show quota settings ceph osd pool get-quota To remove a quota, set the existing quota setting to 0 There are also application-level quotas For rgw and cephfs (not rbd; images are already limited in size) Pool Quotas vs. Application Quotas. When a pool quota nears its limit, the HEALTH mechanisms will display a \u201cPOOL_NEAR_FULL\u201d warning to the storage administrator. When the quota limit has been exceeded, the HEALTH mechanisms will display a \u201cPOOL_FULL\u201d warning to the storage administrator. Applications (clients) don\u2019t always handle the quotas cleanly. In most cases, once the Pool Quota is exceeded, the application will simply stop writing to the pool, and error messages and behavior at the application are inconsistent (if there are any messages at all). Pools \u2013 Snapshots Take (make) a snapshot of an existing pool ceph osd pool mksnap Remove a snapshot of a pool ceph osd pool rmsnap List pool snapshots rados -p lssnap Rollback the pool to an earlier snapshot rados -p rollback Images and cephfs have their own snapshot facilities. Object and Bucket snapshotting features related to rgw don\u2019t exist. Pools Snapshots versus App Snapshots The two different snapshot features cannot be used at the same time on a pool Either Pool Snapshots, or Application Snapshots; not both. (snap_mode = pool versus snap_mode = selfmanaged) Once you commit to pool snapshots for an RBD pool, you can\u2019t change to using RBD snapshots Pros and Cons of each, depending on your Use Case admin:~ # ceph osd pool ls detail -f json-pretty | grep snap_mode \"snap_mode\": \"selfmanaged\", \"snap_mode\": \"selfmanaged\", \"snap_mode\": \"selfmanaged\", \"snap_mode\": \"selfmanaged\", \"snap_mode\": \"selfmanaged\", \"snap_mode\": \"selfmanaged\", \"snap_mode\": \"selfmanaged\",","title":"Creating Erasure Code Profiles and Pools"},{"location":"linux/SES/linux_ses_memo/#bluestore","text":"BlueStore is the default storage backend in SES Highlighted features: compressing, no double-writes, faster checksums Ceph FileStore Model It is not ideal for a specialized purpose like a highly scalable distributed storage system. Only recommend that XFS be used. Both btrfs and ext4 have known bugs. The FileStore model uses cache from the filesystem (XFS). Memory for cache is managed by filesystem kernel module. Ceph BlueStore Model BlueStore consumes raw block devices. Metadata management with RocksDB. BlueStore employs RocksDB\u2019s key/value database in order to manage internal metadata, such as the mapping from object names to block locations on disk. Full data and metadata checksumming. By default all data and metadata written to BlueStore is protected by one or more checksums. A small specialized filesystem called BlueFS. This provides just enough of a filesystem to allow RocksDB to store its \"key/value files\" to share metadata across all the raw device(s) No data or metadata will be read from disk or returned to the user without being verified. Multi-device metadata tiering. BlueStore allows its internal journal (write-ahead log) to be written to a separate, highspeed device (like an SSD, NVMe, or NVDIMM) to increased performance. Efficient copy-on-write. RBD and CephFS snapshots rely on a copy-on-write clone mechanism that is implemented efficiently in BlueStore. BlueStore is a userspace model that provides its own memory management and cache. No need to clear the storage device cache OSDs help facilitate the performance of caching Default: cache the reads, don\u2019t cache the writes RocksDB\uff1a rocksdb\u662ffacebook\u57fa\u4e8eleveldb\u5f00\u53d1\u7684\u4e00\u6b3ekv\u6570\u636e\u5e93\uff0cBlueStore\u5c06\u5143\u6570\u636e\u5168\u90e8\u5b58\u653e\u81f3RocksDB\u4e2d\uff0c\u8fd9\u4e9b\u5143\u6570\u636e\u5305\u62ec\u5b58\u50a8\u9884\u5199\u5f0f\u65e5\u5fd7\u3001\u6570\u636e\u5bf9\u8c61\u5143\u6570\u636e\u3001Ceph\u7684omap\u6570\u636e\u4fe1\u606f\u3001\u4ee5\u53ca\u5206\u914d\u5668\u7684\u5143\u6570\u636e \u3002 BlueRocksEnv\uff1a \u662fRocksDB\u4e0eBlueFS\u4ea4\u4e92\u7684\u63a5\u53e3\uff1bRocksDB\u63d0\u4f9b\u4e86\u6587\u4ef6\u64cd\u4f5c\u7684\u63a5\u53e3EnvWrapper\uff0c\u7528\u6237\u53ef\u4ee5\u901a\u8fc7\u7ee7\u627f\u5b9e\u73b0\u8be5\u63a5\u53e3\u6765\u81ea\u5b9a\u4e49\u5e95\u5c42\u7684\u8bfb\u5199\u64cd\u4f5c\uff0cBlueRocksEnv\u5c31\u662f\u7ee7\u627f\u81eaEnvWrapper\u5b9e\u73b0\u5bf9BlueFS\u7684\u8bfb\u5199\u3002 BlueFS\uff1a BlueFS\u662fBlueStore\u9488\u5bf9RocksDB\u5f00\u53d1\u7684\u8f7b\u91cf\u7ea7\u6587\u4ef6\u7cfb\u7edf\uff0c\u7528\u4e8e\u5b58\u653eRocksDB\u4ea7\u751f\u7684.sst\u548c.log\u7b49\u6587\u4ef6\u3002 BlockDecive\uff1a BlueStore\u629b\u5f03\u4e86\u4f20\u7edf\u7684ext4\u3001xfs\u6587\u4ef6\u7cfb\u7edf\uff0c\u4f7f\u7528\u76f4\u63a5\u7ba1\u7406\u88f8\u76d8\u7684\u65b9\u5f0f\uff1b BlueStore\u652f\u6301\u540c\u65f6\u4f7f\u7528\u591a\u79cd\u4e0d\u540c\u7c7b\u578b\u7684\u8bbe\u5907\uff0c\u5728\u903b\u8f91\u4e0aBlueStore\u5c06\u5b58\u50a8\u7a7a\u95f4\u5212\u5206\u4e3a\u4e09\u5c42\uff1a\u6162\u901f\uff08Slow\uff09\u7a7a\u95f4\u3001\u9ad8\u901f\uff08DB\uff09\u7a7a\u95f4\u3001\u8d85\u9ad8\u901f\uff08WAL\uff09\u7a7a\u95f4\uff0c\u4e0d\u540c\u7684\u7a7a\u95f4\u53ef\u4ee5\u6307\u5b9a\u4f7f\u7528\u4e0d\u540c\u7684\u8bbe\u5907\u7c7b\u578b\uff0c\u5f53\u7136\u4e5f\u53ef\u4f7f\u7528\u540c\u4e00\u5757\u8bbe\u5907\u3002 Allocator\uff1a\u8d1f\u8d23\u88f8\u8bbe\u5907\u7684\u7a7a\u95f4\u7ba1\u7406\uff0c\u53ea\u5728\u5185\u5b58\u505a\u6807\u8bb0\uff0c\u76ee\u524d\u652f\u6301StupidAllocator\u548cBitmapAllocator\u4e24\u79cd\u5206\u914d\u5668,Stupid\u57fa\u4e8eextent\u7684\u65b9\u5f0f\u5b9e\u73b0 Ceph BlueStore with Mixed Devices","title":"BlueStore"},{"location":"linux/SES/linux_ses_memo/#bluestore-cache-parameters","text":"Under most circumstances, autotune is best bluestore_cache_autotune Description: Automatically tune the ratios assigned to different bluestore caches while respecting minimum values Type: Boolean Required: Yes Default: True (enabled) Related settings: bluestore_cache_autotune_chunk_size, bluestore_cache_autotune_interval, and others bluestore_cache_size Description: The amount of memory BlueStore will use for its cache. If zero, bluestore_cache_size_hdd or bluestore_cache_size_ssd will be used instead. Type: Integer Required: Yes Default: 0 bluestore_cache_size_hdd Description: The default amount of memory BlueStore will use for its cache when backed by an HDD Type: Integer Required: Yes Default: 1 * 1024 * 1024 * 1024 (1 GB) bluestore_cache_size_ssd Description: The default amount of memory BlueStore will use for its cache when backed by an SSD. Type: Integer Required: Yes Default: 3 * 1024 * 1024 * 1024 (3 GB) bluestore_cache_meta_ratio Description: The ratio of cache devoted to metadata. Type: Floating point Default: .01 bluestore_cache_kv_ratio Description: The ratio of cache devoted to key/value data (rocksdb). Type : Floating point Default: .99 bluestore_cache_kv_max Description : The maximum amount of cache devoted to key/value data (rocksdb). Type : Unsigned Integer Default : 512 * 1024*1024 (512 MB)","title":"BlueStore Cache Parameters"},{"location":"linux/SES/linux_ses_memo/#bluestore-device-types","text":"BlueStore has three types of roles for devices: The DATA role: Required: main device (block symlink) stores all object data. If no other types: \u201cdata\u201d device serves all the other roles The DB role: Optional: DB device (block.db symlink) stores metadata in RocksDB Whatever doesn\u2019t fit will spill back onto the \u201cdata\u201d device The Write Ahead Log (WAL/Journal) role: Optional: WAL device (block.wal symlink) stores the internal journal Can combine all 3 roles into one physical device Or combine DB/WAL onto a single device with the DATA device separate Or all three on seperate devices","title":"BlueStore Device Types"},{"location":"linux/SES/linux_ses_memo/#bluestore-configuration-recommendations","text":"Devote DB and WAL to SSD or NVMe Allocate 64 GB to the RocksDB Allocate 4-6 GB to the WAL Assign the \u201cdata\u201d role to the slower (HDD) devices If combining WAL/DB on one device, use a single partition for both You can use a single SSD/NVMe to store multiple journals","title":"BlueStore Configuration Recommendations"},{"location":"linux/SES/linux_ses_memo/#architecture-overview-of-object-block-filesystem-access","text":"","title":"Architecture Overview of Object, Block, Filesystem Access"},{"location":"linux/SES/linux_ses_memo/#object-storage_1","text":"The state of the art of distributed storage Object storage is the Cloud Storage mechanism of choice Unstructured, to better accommodate large files and large quantities of files Ideal for large media files, like streaming videos, audio Scales really well, large capacities Ceph provides access to the storage via all three major data access methods: Block, Object, and File. For the storage backend, Object Storage is ideal","title":"Object Storage"},{"location":"linux/SES/linux_ses_memo/#block-storage","text":"Traditional Block Storage: Volumes as a collection of blocks Blocks can be of various sizes, but all the same within a volume Typically a filesystem is installed on top of the volume Hard Drives, CDs, USB sticks, etc The standard disk device mechanism for Unix, Linux, Windows, etc. Ceph presents RADOS as block device (RBD = RADOS Block Device) Ceph calls these block devices \u201cimages\u201d Provides clients with access like a \u201cdisk drive\u201d KVM/QEMU; libvirt; or remote Linux system A native Windows client that can access the Block storage of Ceph directly is in progress","title":"Block Storage"},{"location":"linux/SES/linux_ses_memo/#rados-block-device-rbd","text":"RBD is the RADOS Block Device A specific RBD instance in the cluster is called an \u201cimage\u201d RBD images can be accessed by OSs other than linux librbd provides interface for gateways like iSCSI RBD allows the client to decide what to do with the storage Filesystem type; raw disk, such as for a DB; etc RBD images can accommodate 16Eb file system sizes No matter the size, the storage is distributed durably throughout the cluster Data is striped across the RADOS cluster in object sized chunks 4MB default Provides high performance and durability Notable Benefits Ability to mount with Linux or QEMU KVM clients Thinly provisioned Resizable images Image import/export Image copy or rename Read-only snapshots Revert to snapshots Copy on Write clones Useful for standing up lots of virtual machines with same base configuration High performance due to striping across cluster nodes RBD image definition: Defined storage area presented as a block device to a client RBD Storage","title":"RADOS Block Device (RBD)"},{"location":"linux/SES/linux_ses_memo/#file-storage","text":"POSIX Filesystem via CephFS File access is a significant use case Home directories Historical comfort with files and directories Ease of managing \u201csmall\u201d stuff broadly, in a distributed system A Use Case that\u2019s growing in popularity: HPC CephFS is fast, scalable, and flexible Fits into many existing paradigms, rather seamlessly In particular: NFS, Samba/CIFS But even better: extending Linux filesystems Requires Metadata Service (MDS) for POSIX capabilities SUSE does NOT support any FUSE clients.","title":"File Storage"},{"location":"linux/SES/linux_ses_memo/#ceph-users-and-authentication","text":"Ceph Users are generally applications; applications that use the storage cluster The must common user is Admin A ceph admin user and credentials must exist Additional users and associated credentials are useful Each user must have credentials to access the storage cluster The most fundamental form of credentials in Ceph is keys Ceph Users and Keys The admin user has rights to all Ceph resources. Other users can be setup to have a subset of rights There are basically two types of Users (Actors): An individual (a person) An application (like a gateway, or some other kind of system) Most users are of the type client, and are represented as a dotted string, such as: client.admin, or client.steve, or client.swift The root linux user on the Admin node is effectively the Admin Ceph user, since the root user has all privileges to all filesystem objects on the Adminnode, including the ceph.client.admin.keyring. The root user on any of the nodes in the cluster can \u201cimpersonate\u201d all of the Ceph clients. Linux user accounts do not have any affect on the Ceph Users as managed in the dashboard. Take care to keep backups of the /etc/ceph/ directory structure, so that you don\u2019t lose these keys/keyrings. Each user must have a key/keyring, for example: /etc/ceph/ceph.client.admin.keyring on the Admin node /etc/ceph/ceph.client.storage.keyring on a storage node admin:/etc/ceph # cat ceph.client.admin.keyring [client.admin] key = AQD6pHpfAAAAABAAHJvkvLhOKZyQxm9lgnR5Qg== caps mds = \"allow *\" caps mon = \"allow *\" caps osd = \"allow *\" caps mgr = \"allow *\" data1:/etc/ceph # cat ceph.client.storage.keyring [client.storage] key = AQD8pHpfAAAAABAAHecCBgBsLIyPrJf+27eXUQ== caps mon = \"allow rw\" Ceph Keys and Keyrings A keyring contains one or more keys Each user can have its own keyring A keyring can contain multiple keys Different clients and users must have their own key, but multiple keys can be joined together in a single keyring Normally a key will be contained in a keyring Core Ceph will only recognize and use keys from keyrings Stand-alone keys are useful for other tools, like clients Ceph Authentication List The Admin node (and client.admin) can list all Users ceph auth list Create a Ceph User A typical user will have read rights to MONs, and read/write rights to a pool (osd) ceph auth get/add/get-or-create xxxxxx Create a User with ceph-authtool Create a keyring ceph-authtool -C /etc/ceph/ceph.client.richard.keyring Create a key, and place it on the keyring ceph-authtool --gen-key -n client.richard --cap osd 'allow rw pool=data' --cap mon 'allow r' /etc/ceph/ceph.client.richard.keyring Now officially tell the cluster about the key (add user to the key) ceph auth add client.richard -i /etc/ceph/ceph.client.richard.keyring Authentication with cephx The mechanism for passing keys around is cephx Authentication for users and daemons Does not provide data encryption, only authentication with keys cephx simply ensures the authenticity of actors So that no man-in-the-middle attacks can occur Other authentication mechanisms are theoretically possible Attempts to integrate LDAP and Kerberos have been made \u2026 but they have not come to full fruition yet","title":"Ceph Users and Authentication"},{"location":"linux/SES/linux_ses_memo/#ceph-configuration","text":"Historically, the Ceph configuration was kept only in a file on the Admin node: /etc/ceph/ceph.conf, and sync'd to MONs and Storage Nodes SES DeepSea manages the ceph.conf file. Don\u2019t edit it directly; use Salt and DeepSea With Ceph Nautilus, most configuration held as objects in the Monitors using Dashboard or CLI for operation Ceph Configuration Stored in the MONs The MONs keep a configuration database Show all the configuration keys: admin:/etc/ceph # ceph config ls |less Show the configuration settings that have been customized. The dumped output also indicates an EXPERTISE LEVEL The keys also have a \u201cwho\u201d attribute. In below case, \"osd.*\" represents the \"who\", which is getting the general setting for all OSDs Ceph Configuration Settings Show configuration settings that have been customized: admin:/etc/ceph # ceph config dump WHO MASK LEVEL OPTION VALUE RO mgr advanced mgr/dashboard/GRAFANA_API_URL https://mon1.pvgl.sap.corp:3000 * mgr advanced mgr/dashboard/RGW_API_ACCESS_KEY M11I3JGQHAQM94CS910K * mgr advanced mgr/dashboard/RGW_API_HOST mon3.pvgl.sap.corp * mgr advanced mgr/dashboard/RGW_API_PORT 80 * mgr advanced mgr/dashboard/RGW_API_SECRET_KEY YWyRc3mayEPiOEUzQ2o76KePSKmVKN4fIWxgqTt6 * mgr advanced mgr/dashboard/RGW_API_USER_ID admin * mgr advanced mgr/dashboard/ssl_server_port 8443 admin:/etc/ceph # ceph config get osd.* osd_max_object_size 134217728 admin:/etc/ceph # ceph config show osd.0 \u2026\u2026 admin:/etc/ceph # ceph config show osd.11 (4 data nodes, 3 osds in each node) \u25cb Each of the configuration settings have default values ceph config show-with-defaults osd.2 | less \u25cb Ceph keeps a log of configuration changes admin:/etc/ceph # ceph config log --- 8 --- 2020-10-05 14:31:51.425902 --- + mgr/mgr/dashboard/RGW_API_USER_ID = admin --- 7 --- 2020-10-05 14:31:50.418622 --- + mgr/mgr/dashboard/RGW_API_HOST = mon3.pvgl.sap.corp --- 6 --- 2020-10-05 14:31:49.398448 --- + mgr/mgr/dashboard/RGW_API_PORT = 80 --- 5 --- 2020-10-05 14:31:48.403965 --- + mgr/mgr/dashboard/RGW_API_SECRET_KEY = YWyRc3mayEPiOEUzQ2o76KePSKmVKN4fIWxgqTt6 --- 4 --- 2020-10-05 14:31:46.905701 --- + mgr/mgr/dashboard/RGW_API_ACCESS_KEY = M11I3JGQHAQM94CS910K --- 3 --- 2020-10-05 13:15:29.530355 --- + mgr/mgr/dashboard/GRAFANA_API_URL = https://mon1.pvgl.sap.corp:3000 --- 2 --- 2020-10-05 13:15:14.349623 --- + mgr/mgr/dashboard/ssl_server_port = 8443 --- 1 --- 2020-10-05 13:13:55.637896 ---","title":"Ceph Configuration"},{"location":"linux/SES/linux_ses_memo/#health","text":"Show status admin:/etc/ceph # ceph status cluster: id: 343ee7d3-232f-4c71-8216-1edbc55ac6e0 health: HEALTH_OK services: mon: 3 daemons, quorum mon1,mon2,mon3 (age 6w) mgr: mon1(active, since 13d) mds: cephfs:1 {0=mon3=up:active} 2 up:standby osd: 12 osds: 12 up (since 9w), 12 in (since 9w) rgw: 1 daemon active (mon3) task status: scrub status: mds.mon3: idle data: pools: 7 pools, 208 pgs objects: 246 objects, 4.7 KiB usage: 14 GiB used, 82 GiB / 96 GiB avail pgs: 208 active+clean io: client: 11 KiB/s rd, 0 B/s wr, 11 op/s rd, 6 op/s wr admin:/etc/ceph # ceph health HEALTH_OK admin:/etc/ceph # ceph health detail HEALTH_OK admin:/etc/ceph # ceph mon stat e1: 3 mons at {mon1=[v2:10.58.121.186:3300/0,v1:10.58.121.186:6789/0],mon2=[v2:10.58.121.187:3300/0,v1:10.58.121.187:6789/0],mon3=[v2:10.58.121.188:3300/0v1:10.58.121.188:6789/0]}, election epoch 22, leader 0 mon1, quorum 0,1,2 mon1,mon2,mon3 admin:/etc/ceph # ceph osd stat 12 osds: 12 up (since 9w), 12 in (since 9w); epoch: e1375 admin:/etc/ceph # ceph pg stat 208 pgs: 208 active+clean; 4.7 KiB data, 2.0 GiB used, 82 GiB / 96 GiB avail; 1.2 KiB/s rd, 1 op/s Watch status -w, --watch : Watch live cluster changes --watch-debug : Watch debug events --watch-info : Watch info events --watch-sec : Watch security events --watch-warn : Watch warning events --watch-error : Watch error","title":"Health"},{"location":"linux/SES/linux_ses_memo/#scrub-and-deep-scrub","text":"\"Scrub\" is the process of doing a data consistency check Basically like running fsck on the cluster In Replicas: compare object metadata among replicas In EC: verify \u201ccode\u201d chunks Manual scrubbing can be done per OSD or per PG. \"osd scrub\" is just a collaborative wrapper of \"pg scrub\". ceph osd scrub osd.11 ceph pg scrub 3.33 \"scrub\" is a light process, daily Checks object size and attributes \"deep-scrub\" is a more thorough process, weekly Reads all data and checks the checksums Scrub \u2013 Manual vs Automatic You can let Ceph just do the default Run scrub daily, run deep-scrub weekly Ceph pays attention to usage and backs off when necessary You can change the defaults for both scrub and deepscrub, examples: osd_scrub_begin_week_day=6 (Saturday) osd_scrub_end_week_day=7 (Sunday) You can manually run scrubbings at any time if you suspect it\u2019s wanted or needed Manual scrubbings are not common Adjustments to Scrub Settings For most circumstances the default behavior of Scrub is adequate See current Scrub configuration settings: ceph config ls | grep osd_scrub ceph config ls | grep osd_deep_scrub ceph config get osd.* osd_scrub_begin_hour Change the settings immediately in the MON DB ceph config set osd.* osd_scrub_begin_hour 23 ceph config set osd.* osd_scrub_end_hour 5 Adjust Settings in ceph.conf with DeepSea To permanently change settings in ceph.conf This is the \u201cold\u201d way, but is still valid Remember that ceph.conf is controlled by DeepSea Add changes to /srv/salt/ceph/configuration/files/ceph.conf.d/global.conf Run the following DeepSea (Salt) commands: salt admin* state.apply ceph.configuration.create salt \\* state.apply ceph.configuration Wait for services/servers to be restarted, or tell Ceph to assimilate the ceph.conf settings now ceph config assimilate-conf -i /etc/ceph/ceph.conf","title":"Scrub and Deep-Scrub"},{"location":"linux/SES/linux_ses_memo/#repair","text":"Problems Found by Scrubbing * If data (in an OSD or PG) becomes inconsistent, it will need to be repaired. You can configure scrubbing to automatically repair errors * osd_scrub_auto_repair=True * osd_scrub_auto_repair_num_errors=5 * Manually repair when appropriate * ceph osd repair osd.11 * ceph pg repair 3.33","title":"Repair"},{"location":"linux/SES/linux_ses_memo/#ceph-manager-modules","text":"Manager Modules help to extend the capabilities of Ceph List of Modules Supported in SES Balancer (always on) rash (always on) Dashboard DeepSea iostat Orchestrator (always on) progress (always on, tech preview) Prometheus RESTful rbd_support (always on) status (always on) telemetry volume (always on) Zabbix (plugin only, not the required agent) Enabling Manager Modules Show a list of Manager Modules ceph mgr module ls | less The output is quite long; best to pipe it through less The top of the output shows those modules that have been enabled The exhaustive output also displays the \u201cAPI\u201d of each module Manager modules are quite easy to enable and disable ceph mgr module enable ceph mgr module disable Show list of services that are active from the Modules ceph mgr services Module Capabilities Each module has its own settings, configuration Once the module is enabled, the ceph command accepts commands for the module No need to run the command as ceph mgr ... Examples: ceph crash stat ceph telemetry show Setting parameters (key/value pairs) of Modules ceph config set mgr mgr/telemetry/contact 'JD ' ceph config set mgr mgr/telemetry/description 'Training Cluster'","title":"Ceph Manager Modules"},{"location":"linux/SES/linux_ses_memo/#ceph-tell","text":"Tell commands are actually directed to the target service by way of the MONs ceph tell is a tool to tell a ceph daemon to perform a task \u2026 change a setting \u2026 execute a subroutine The target of ceph tell can be a single daemon or a collection of daemons All MONs: ceph tell mon.* injectargs '--mon-pg-warn-max-per-osd 4096' A specific OSD: ceph tell osd.9 bench ceph tell is the most common way to change logging for troubleshooting ceph tell . injectargs '--debug- ' ceph tell osd.7 injectargs '--debug-osd 20' ceph tell osd.7 config set debug_osd 20 A \u201c/\u201d allows you to change both the file log and memory log settings simultaneously ceph tell mon.3 injectargs '--debug-mon 0/10' (The first is the file parameter, the second is the memory parameter) Since logging can fill space, important to restore settings after investigating ceph tell mon.3 injectargs '--debug-mon 1/5' ceph tell sends its instructions via the Monitors. So what if the MONs are having problems? To avoid running commands through the MONs, go directly to thenode running the daemon ssh storage1 ceph daemon osd.29 config show ceph daemon osd.29 config set debug_osd 0/20 Use with great care","title":"Ceph Tell"},{"location":"linux/SES/linux_ses_memo/#ceph-dashboard_1","text":"What's Ceph Dashboard SES WEB-based Management Interface A Ceph MGR module, built-in to Ceph The open source \"port\" of openATTIC to Ceph. Technically it\u2019s not a port of openATTIC. SUSE and Ceph Community worked on implementing the openATTIC capabilities directly within Ceph Role-based and Multi-User Management of the SES cluster Create, manage, and monitor Pools, RBDs Manage users, access keys, quotas and buckets of RGW Manage NFS exports, iSCSI targets and portals, CephFS View cluster nodes/roles, monitor performance metrics Manage Ceph settings/configuration Reduces the need to understand complex Ceph commands The dashboard is stateless, it will reflect any changes to the Ceph cluster, Highlighted Enterprise Behavior via Ceph Dashboard Uses SSL/TLS By default will use a CA and certificate created by DeepSea or provide your own CA and certificate Can run without SSL/TLS (not recommended) Multi-User and Role Management Variety of mappings, i.e.: read, create, update, delete Single Sign-On, complying with SAML 2.0 Single Sign-On, complying with SAML 2.0 Auditing on the backend, to monitor specific user activity Internationalization (I18N), with a variety of language translations Ceph Dashboard Architecture Backend is based on CherryPy framework (CherryPy is a Minimalist Python Web Framework) Frontend WebUI is based on Angular/TypeScript A custom REST API Monitoring facilitated by Prometheus Visualization of data facilitated by Grafana Dependent upon DBUS, systemd, and systems\u2019 shell Dashboard as Manager Module Ceph Dashboard runs as a Manager module Runs on each MON/MGR node Really only actively available via the active MGR Runs on \u201cstandby\u201d on the standby MGR nodes Standby Dashboards will redirect to active MGR URL Dashboard automatically switches to active MGR node Helpful High Availability feature As a MGR module, enabled and configured by DeepSea Can be disabled if unwanted URL example: https://10.58.121.186:8443 Grafana and Prometheus Prometheus collects various data about the cluster Grafana represents the data as graphs Ceph Dashboard uses both to improve insight into SES Prometheus Open source event monitoring software \"Scrapes\" (collects) data from nodes/services in the cluster Real-time Time series Custom scrapers have been created for Ceph Stores scraped data in memory and on disk Presents data to other software for graphical representation Integrated nicely with Grafana Grafana The leading open source software for time series analytics \"Dashboards\" of panels, graphs, metrics, etc. \"Dashboard\" is a slightly conflicting term, but still meaningful Renders data in a graphical way collected from Prometheus Graphs are customized for use on the Ceph Dashboard Dashboard Users Always need an \u201cAdmin\u201d user for the Dashboard \u00a7 The admin keys of the root user on the \u201cAdmin\u201d node in the cluster Dashboard Users are accounts that relate only to using the Dashboard \u00a7 Not the same as Ceph CLI users and client keys; but could coincide Any person who wants to interact with the storage cluster via the Dashboard must have a user account Variety of Users established by the Admin User, and various permissions based on Admin-defined Roles User Authentication Dashboard Administrators can setup users with specific privileges The privileges and permissions are managed as \"roles\" User accounts can be created directly in the Dashboard Stored as objects in Ceph User accounts can also be tied to other authentication mechanisms: Single Sign-On Service; SAML 2.0 compliant protocol Dashboard accounts can be managed from the Dashboard or from the CLI Example: ceph dashboard ac-user-show [] The Admin Dashboard User (the term \u201cadmin\u201d is used differently in different places) The Dashboard Admin User is not the same as other admins The \u201cadmin\u201d node is obviously not directly tied to any admin user The Admin Dashboard User is created at Deployment time Given a random password by DeepSea You must use the CLI to establish the admin password ceph dashboard ac-user-show admin ceph dashboard ac-user-set-password admin \u25cb The SES Deployment Course has set the password to mypassword admin:~ # ceph dashboard ac-user-show [\"admin\"] admin:~ # ceph dashboard ac-user-show admin {\"username\": \"admin\", \"password\": \"$2b$12$4lC/AU7jc6midTZufj4P4.rBtVzRGf7Zy7fUbD6G9YfdfVEwkwuUy\", \"roles\": [\"administrator\"], \"name\": null \"email\":null\"lastUpdate\": 1601874928} Health from the Dashboard Cluster Status Monitors OSDs Manager Daemons Hosts Object Gateways Metadata Service iSCSI Gateways Cluster Performance from Dashboard Client IOPS Client Throughput Client Read/Write Recovery Throughput Scrub Performance Data Hosts: Overall Performance Monitors: Performance Counters OSDs: Relative Read/Write bar graphs, and Overall Performance Pools: Relative Read/Write bar graphs, and Overall Performance Block images: Overall Performance CephFS: Performance Details RGW: Overall Performance Cluster Capacity from Dashboard Capacity data: Number of Pools Raw Capacity Number of Objects (Ceph objects, not user objects from RGW) Placement Groups per OSD Placement Group Status","title":"Ceph Dashboard"},{"location":"linux/SES/linux_ses_memo/#basic-troubleshooting","text":"Ceph Logs Logs normally stored in /var/log/ceph/ No real logs on the admin node Each service has its own log on the MON, Storage and Gateway nodes Logs handled routinely by logrotate Ceph has logs that are stored to files and in memory (triggered by event or manual request) There are 21 different levels of logging: 0-20 (0 is no logging; 20 is the most verbose logging) There are many subsystems that do their own logging, and can be configured independently Most common: mon, osd, mgr, rados, rbd, mds, rgw Others: asok, auth, client, filestore, journal, monc, ms, paxos, and more There are only 3 types of daemons: osd, mon, mds Using Tell to Change Log Levels 1) Check the Dashboard and Health. Common commands ceph status ceph osd status ceph osd df ceph osd utilization ceph osd pool stats ceph osd tree ceph pg stat 2) Network Troubleshooting Always be sure that the network (and related services) are working properly Ceph depends heavily on tightly synchronized time; make sure network time services are working on each node DNS hostnames are similarly essential 3) Check the Logs Go to the node of the component implicated in HEALTH 4: Raise the DEBUG Level. Follow this simple formula: Raise the debug level (a little each time until you see the problem) Check the logs Repeat as necessary Don\u2019t forget to restore the debug level back to its normal level 5) Check the Storage Device If the problem is with an OSD or a storage device, go straight to the device: hdparm smartctl And check out the details of the combination of OSD and storage device: lsblk /var/lib/ceph/osd/ 6) Scrub (or not) Sometimes simply scrubbing an OSD or PG can cause the checksum-ing process to reveal problems At least some problems can be made more clear with the result of scrub and/or deep-scrub Even doing a scrub can kick Ceph into fixing the problem itself And don\u2019t forget ceph osd repair On the other hand, sometimes Scrub can make things worse. If you suspect Scrub is part of the problem, turn it off: ceph osd set noscrub ceph osd unset noscrub 7) Placement Groups When Placement Groups cause problems: * ceph pg dump summary * ceph pg dump pools * ceph pg dump_jason * ceph pg dump | less Followed by a strategic \u201crepair\u201d of the PG * ceph pg repair 8) Running supportconfig YaST Support Module From CLI: supportconfig The collected data is stored in a file called /var/log/nts__.txz","title":"Basic Troubleshooting"},{"location":"linux/SRE/01-fundamentals/","text":"\u7b2c\u4e00\u7ae0 Linux\u57fa\u7840 \u00b6 1.\u5b98\u65b9\u6587\u6863 \u00b6 Rocky Linux Instructional Books openSUSE Documentation Ubuntu Documentation 2.\u7cfb\u7edf\u73af\u5883 \u00b6 2.1.Rocky \u00b6 \u4f7f\u7528\u7248\u672c\uff1a Rocky 9.0 \u3002 \u4ece\u7f51\u7ad9\u4e0b\u8f7dRocky\u7cfb\u7edf ISO\u955c\u50cf \uff0c\u6216\u8005\u901a\u8fc7 wget \u547d\u4ee4\u4e0b\u8f7dRocky\u7cfb\u7edfISO\u955c\u50cf\u3002 wget https://download.rockylinux.org/pub/rocky/9.0/isos/x86_64/Rocky-9.0-x86_64-dvd.iso \u5b89\u88c5\u65f6\u6211\u9009\u62e9\u4e86\u6fc0\u6d3b root \u7528\u6237\uff0c\u9009\u62e9\u4e86Server\u6a21\u5f0f\u5b89\u88c5\uff08\u6ca1\u6709GUI\uff09\u3002 \u4ee5 root \u767b\u5f55\uff0c\u6267\u884c\u4e0b\u9762\u547d\u4ee4\u4fee\u6539 sudo \u6743\u9650\u3002 visudo \u5e76\u6fc0\u6d3b\u4e0b\u9762\u4e00\u884c\uff08\u4e0d\u8bbe\u5bc6\u7801\uff0c\u65b9\u4fbf\u7ec3\u4e60\uff09\uff1a %wheel ALL =( ALL ) NOPASSWD: ALL \u521b\u5efa\u7528\u6237 vagrant \uff0c\u5e76\u8bbe\u7f6e wheel \u4e3a\u4e3b\u8981\u7ec4\u548c\u4fee\u6539\u5bc6\u7801\u3002 adduser vagrant usermod -g wheel vagrant passwd vagrant \u8bbe\u5b9ahostname\uff08\u5305\u62ec\u522b\u540d\uff09\uff0c\u5e76\u67e5\u770b\u7ed3\u679c\u3002 hostnamectl set-hostname --static \"rocky9\" hostnamectl set-hostname --pretty \"rocky9\" hostnamectl cat /etc/hostname \u5c0f\u8d34\u58eb\uff1a \u7531systemd\u63a7\u5236\u7684\u4e3b\u673a\u540d\u7684\u670d\u52a1\u914d\u7f6e\u4fe1\u606f\uff1a /usr/lib/systemd/system/systemd-hostnamed.service Rocky\u7684\u8f6f\u4ef6\u6e90\u7684\u914d\u7f6e\u4fe1\u606f\u4fdd\u5b58\u5728\u76ee\u5f55 /etc/yum.repos.d/ \u4e0b\u3002\u5982\u679c\u8bbf\u95ee\u9ed8\u8ba4\u6e90\u6bd4\u8f83\u6162\uff0c\u53ef\u4ee5\u66f4\u65b0\u963f\u91cc\u6e90\u6216\u8005\u79d1\u5927\u6e90\u3002 \u66f4\u6362\u963f\u91cc\u6e90\u3002 sed -e 's|^mirrorlist=|#mirrorlist=|g' \\ -e 's|^#baseurl=http://dl.rockylinux.org/$contentdir|baseurl=https://mirrors.aliyun.com/rockylinux|g' \\ -i.bak \\ /etc/yum.repos.d/Rocky-*.repo \u66f4\u6362\u79d1\u5927\u6e90\u3002 sed -e 's|^mirrorlist=|#mirrorlist=|g' \\ -e 's|^#baseurl=http://dl.rockylinux.org/$contentdir|baseurl=https://mirrors.ustc.edu.cn/rocky|g' \\ -i.bak \\ /etc/yum.repos.d/rocky-extras.repo \\ /etc/yum.repos.d/rocky.repo \u5237\u65b0\u7f13\u5b58\u3002 dnf makecache 2.2.Ubuntu \u00b6 \u4f7f\u7528\u7248\u672c\uff1a Ubuntu 2204 \u3002 \u8bbe\u5b9aroot\u7528\u6237\u7684\u5bc6\u7801\u3002 sudo passwd root \u901a\u8fc7\u5b89\u88c5\u65f6\u5df2\u521b\u5efa\u7684\u7528\u6237 vagrant \u767b\u5f55\u3002\u6267\u884c\u4e0b\u9762\u547d\u4ee4\u4fee\u6539 sudo \u6743\u9650\u3002 sudo visudo \u6dfb\u52a0 vagrant \u5230\u7279\u6743\u7528\u6237\uff08Rocky\u548copenSUSE\u4e0d\u9700\u8981\u6dfb\u52a0\uff09\uff0c\u5e76\u6fc0\u6d3bsudo\u4e00\u884c\uff08\u4e0d\u8bbe\u5bc6\u7801\uff0c\u65b9\u4fbf\u7ec3\u4e60\uff09\uff1a # User privilege specification root ALL =( ALL:ALL ) ALL vagrant ALL =( ALL:ALL ) ALL # Allow members of group sudo to execute any command sudo ALL =( ALL:ALL ) NOPASSWD: ALL \u4fee\u6539\u7528\u6237 vagrant \u7684\u4e3b\u8981\u7ec4\u4e3a sudo \u3002 sudo usermod -g sudo vagrant \u4fee\u6539\u4e3b\u673a\u540d\u548c\u522b\u540d\u3002 sudo hostnamectl set-hostname ubuntu2204 sudo hostnamectl set-hostname ubuntu2204 --pretty \u5c0f\u8d34\u58eb\uff1a \u5982\u4f55\u5904\u7406 Username is not in the sudoers file. This incident will be reported \u95ee\u9898\u3002 \u5982\u679c\u6ca1\u6709\u521d\u59cb\u5316 root \u7528\u6237\u7684\u5bc6\u7801\uff0c\u4e14\u5f53\u524d\u7528\u6237\u4e5f\u65e0\u6cd5\u6267\u884c sudo \u547d\u4ee4\uff0c\u53ef\u4ee5\u901a\u8fc7\u4e0b\u9762\u6b65\u9aa4\u901a\u8fc7recovery\u6551\u63f4\u6a21\u5f0f\u8fdb\u884c\u6062\u590d\u3002 \u6309 shift \u952e\u5f00\u673a\uff0c\u8fdb\u5165grub\u542f\u52a8\u83dc\u5355\u3002\uff08VMWare\u4e5f\u9002\u7528\uff09 \u5411\u4e0b\u79fb\u52a8\u9ad8\u4eae\u6761\uff0c\u9009\u62e9\u83dc\u5355 Advanced options for Ubuntu \uff0c\u5e76\u786e\u8ba4\u56de\u8f66\u3002 \u9009\u62e9\u5e26\u6709 recovery mode \u7684\u5185\u6838\uff0c\u786e\u8ba4\u56de\u8f66\u3002 \u5411\u4e0b\u79fb\u52a8\u9ad8\u4eae\u6761\uff0c\u9009\u62e9\u83dc\u5355 root Drop to root shell prompt \uff0c\u5e76\u786e\u8ba4\u56de\u8f66\u3002 \u56de\u8f66\u786e\u8ba4 press Enter for maintenance \u3002 \u51fa\u73b0 root \u7684\u547d\u4ee4\u63d0\u793a\u7b26\u540e\uff0c\u6267\u884c\u547d\u4ee4 mount -o rw,remount / \u3002 \u6267\u884c\u547d\u4ee4 passwd \u7ed9 root \u8bbe\u5b9a\u5bc6\u7801\u3002 \u6267\u884c\u547d\u4ee4 adduser username sudo \u628a\u6307\u5b9a\u7528\u6237\u52a0\u5165 sudo \u7ec4\u3002 \u6267\u884c\u547d\u4ee4 visudo \u8fdb\u884c\u5fc5\u8981\u7684\u4fee\u6b63\u6216\u4fee\u6539\u3002 2.3.openSUSE \u00b6 \u4f7f\u7528\u7248\u672c\uff1a Leap 15.4 \u3002 \u9009\u62e9\u670d\u52a1\u5668\u6a21\u5f0f\u5b89\u88c5\uff0c\u65e0\u56fe\u5f62\u754c\u9762\u3002\u5b89\u88c5\u4e2d\u4e0d\u521b\u5efa\u7528\u6237\u3002 \u521b\u5efa\u7528\u6237 vagrant \uff0c\u5e76\u8bbe\u7f6e wheel \u4e3a\u4e3b\u8981\u7ec4\u3002 useradd -m -g wheel -G root -c \"vagrant\" vagrant passwd vagrant \u6267\u884c visudo \u547d\u4ee4\uff0c\u6fc0\u6d3b\u4e0b\u9762\u4e00\u884c\uff0c\u6dfb\u52a0 sudo \u6743\u9650\u3002 % wheel ALL =( ALL ) NOPASSWD: ALL \u4fee\u6539\u4e3b\u673a\u540d\u548c\u522b\u540d\u3002 sudo hostnamectl set-hostname lizard sudo hostnamectl set-hostname lizard --pretty 3.\u5e38\u7528\u547d\u4ee4 \u00b6 \u8bf4\u660e\uff1a \u9ed8\u8ba4\u5f53\u524d\u64cd\u4f5c\u7528\u6237\u4e3a vagrant \u3002 3.1.\u4fee\u6539\u63d0\u793a\u7b26\u98ce\u683c \u00b6 \u6267\u884c\u4e0b\u9762\u547d\u4ee4\u53ef\u4ee5\u770b\u5230\u5f53\u524d\u7cfb\u7edf\u7684\u547d\u4ee4\u63d0\u793a\u7b26\u683c\u5f0f\u3002 echo $PS1 \u5404\u7cfb\u7edf\u9ed8\u8ba4\u8bbe\u7f6e\u662f\u6709\u5dee\u5f02\u7684\u3002 # Rocky [ \\u @ \\h \\W ] \\$ # Ubuntu \\[\\e ] 0 ; \\u @ \\h : \\w\\a\\] ${ debian_chroot :+( $debian_chroot ) } \\[\\0 33 [ 01 ; 32m \\]\\u @ \\h\\[\\0 33 [ 00m \\] : \\[\\0 33 [ 01 ; 34m \\]\\w\\[\\0 33 [ 00m \\]\\$ # openSUSE \\u @ \\h : \\w > \u5c0f\u8d34\u58eb\uff1a bash\u53ef\u8bc6\u522b\u7684\u8f6c\u4e49\u5e8f\u5217\u6709\u4e0b\u9762\u8fd9\u4e9b\uff1a \\u : \u5f53\u524d\u7528\u6237\u7684\u8d26\u53f7\u540d\u79f0 \\h : \u4e3b\u673a\u540d\u7b2c\u4e00\u90e8\u5206 \\H : \u5b8c\u6574\u7684\u4e3b\u673a\u540d\u79f0 \\w : \u5b8c\u6574\u7684\u5de5\u4f5c\u76ee\u5f55\u540d\u79f0\uff08\u5982 \"/home/username/mywork\"\uff09 \\W : \u5f53\u524d\u5de5\u4f5c\u76ee\u5f55\u7684\"\u57fa\u540d (basename)\"\uff08\u5982 \"mywork\") \\t : \u663e\u793a\u65f6\u95f4\u4e3a24\u5c0f\u65f6\u683c\u5f0f\uff0c\u5982\uff1aHH:MM:SS \\T : \u663e\u793a\u65f6\u95f4\u4e3a12\u5c0f\u65f6\u683c\u5f0f \\A : \u663e\u793a\u65f6\u95f4\u4e3a24\u5c0f\u65f6\u683c\u5f0f\uff1aHH:MM \\@ : \u5e26\u6709 am/pm \u7684 12 \u5c0f\u65f6\u5236\u65f6\u95f4 \\d : \u4ee3\u8868\u65e5\u671f\uff0c\u683c\u5f0f\u4e3aweekday month date\uff0c\u4f8b\u5982\uff1a\"Mon Aug 1\" \\s : shell \u7684\u540d\u79f0\uff08\u5982 \"bash\") \\v : bash\u7684\u7248\u672c\uff08\u5982 2.04\uff09 \\V : bash\u7684\u7248\u672c\uff08\u5305\u62ec\u8865\u4e01\u7ea7\u522b\uff09 \\n : \u6362\u884c\u7b26 \\r : \u56de\u8f66\u7b26 \\\\ : \u53cd\u659c\u6760 \\a : ASCII \u54cd\u94c3\u5b57\u7b26\uff08\u4e5f\u53ef\u4ee5\u952e\u5165 07 \uff09 \\e : ASCII \u8f6c\u4e49\u5b57\u7b26\uff08\u4e5f\u53ef\u4ee5\u952e\u5165 33 ) \\[ : \u8fd9\u4e2a\u5e8f\u5217\u5e94\u8be5\u51fa\u73b0\u5728\u4e0d\u79fb\u52a8\u5149\u6807\u7684\u5b57\u7b26\u5e8f\u5217\uff08\u5982\u989c\u8272\u8f6c\u4e49\u5e8f\u5217\uff09\u4e4b\u524d\u3002\u5b83\u4f7fbash\u80fd\u591f\u6b63\u786e\u8ba1\u7b97\u81ea\u52a8\u6362\u884c \\] : \u8fd9\u4e2a\u5e8f\u5217\u5e94\u8be5\u51fa\u73b0\u5728\u975e\u6253\u5370\u5b57\u7b26\u5e8f\u5217\u4e4b\u540e \\# : \u4e0b\u8fbe\u7684\u7b2c\u51e0\u4e2a\u547d\u4ee4 \\$ : \u63d0\u793a\u5b57\u7b26\uff0c\u5982\u679c\u662froot\u7528\u6237\uff0c\u63d0\u793a\u7b26\u4e3a # \uff0c\u666e\u901a\u7528\u6237\u5219\u4e3a $ \u5728PS1\u4e2d\u8bbe\u7f6e\u5b57\u7b26\u989c\u8272\u7684\u683c\u5f0f\u4e3a\uff1a [\\e[F;Bm]........[\\e[0m] \uff0c\u5176\u4e2d [\\e[0m] \u4f5c\u4e3a\u989c\u8272\u8bbe\u5b9a\u7684\u7ed3\u675f\u3002 \u5176\u4e2d\"F\"\u4e3a\u5b57\u4f53\u989c\u8272\uff0c\u7f16\u53f7\u4e3a30-37\uff0c\"B\"\u4e3a\u80cc\u666f\u989c\u8272\uff0c\u7f16\u53f7\u4e3a40-47\u3002 \u5c0f\u8d34\u58eb\uff1a \u989c\u8272\u5bf9\u7167\u8868: F:30 , B:40 : \u9ed1\u8272 F:31 , B:41 : \u7ea2\u8272 F:32 , B:42 : \u7eff\u8272 F:33 , B:43 : \u9ec4\u8272 F:34 , B:44 : \u84dd\u8272 F:35 , B:45 : \u7d2b\u7ea2\u8272 F:36 , B:46 : \u9752\u84dd\u8272 F:37 , B:47 : \u767d\u8272 \u4ee5\u4e0b\u9762\u7684PS1\u8bbe\u5b9a\u4e3a\u4f8b\u8bf4\u660e\u989c\u8272\u8bbe\u5b9a\u3002 PS1 = \"\\[\\e[37;40m\\][\\[\\e[32;40m\\]\\u\\[\\e[37;40m\\]@\\h:\\[\\e[36;40m\\]\\w\\[\\e[0m\\]]\\$ \" \u62c6\u89e3\u5206\u6790\uff1a PS1=\" \\[\\e[37;40m\\] # \u6574\u4e2a\u63d0\u793a\u7b26\u533a\u57df\u524d\u666f\u767d\u8272\uff0c\u80cc\u666f\u9ed1\u8272 [ # \u663e\u793a\u5b57\u7b26[ \\[\\e[32;40m\\] # \u4fee\u9970\u540e\u9762\u7684\\u\uff0c\u524d\u666f\u7eff\u8272\uff0c\u80cc\u666f\u9ed1\u8272 \\u # \u663e\u793a\u5f53\u524d\u7528\u6237\u7684\u8d26\u53f7\u540d\u79f0 \\[\\e[37;40m\\] # \u4fee\u9970\u540e\u9762\u7684\u5b57\u7b26@\u548c\u4e3b\u673a\u540d @ # \u663e\u793a\u5b57\u7b26@ \\h # \u663e\u793a\u4e3b\u673a\u540d : # \u663e\u793a\u5b57\u7b26: \\[\\e[36;40m\\] # \u4fee\u9970\u540e\u9762\u7684\\w\uff0c\u524d\u666f\u9752\u84dd\u8272\uff0c\u80cc\u666f\u9ed1\u8272 \\w # \u663e\u793a\u5b8c\u6574\u5de5\u4f5c\u76ee\u5f55 \\[\\e[0m\\] # \u7ed3\u675f\u989c\u8272\u8bbe\u5b9a ] # \u663e\u793a\u5b57\u7b26] \\$\" # \u5982\u679c\u662froot\u7528\u6237\uff0c\u63d0\u793a\u7b26\u4e3a# \uff0c\u666e\u901a\u7528\u6237\u5219\u4e3a$ \u5bf9\u4e0d\u540c\u4e3b\u673a\u505a\u4e0d\u540c\u8bbe\u7f6e\uff1a # Rocky PS1 = \"\\[\\e[37;40m\\][\\[\\e[32;40m\\]\\u\\[\\e[37;40m\\]@\\h:\\[\\e[36;40m\\]\\w\\[\\e[0m\\]]\\$ \" # Ubuntu PS1 = \"\\[\\e[37;40m\\][\\[\\e[32;40m\\]\\u\\[\\e[33;40m\\]@\\h:\\[\\e[36;40m\\]\\w\\[\\e[0m\\]]\\$ \" # openSUSE PS1 = \"\\[\\e[37;40m\\][\\[\\e[32;40m\\]\\u\\[\\e[35;40m\\]@\\h:\\[\\e[36;40m\\]\\w\\[\\e[0m\\]]\\$ \" \u5c06\u4e0a\u8ff0PS1\u7684\u8bbe\u5b9a\uff0c\u8ffd\u52a0\u5230\u5f53\u524d\u7528\u6237\u7684 ~/.bashrc \u6587\u4ef6\u672b\u5c3e\uff0c\u4ee5\u5b9e\u73b0\u5bf9\u5f53\u524d\u7528\u6237\u7684\u63d0\u793a\u7b26\u98ce\u683c\u505a\u6301\u4e45\u4fdd\u5b58\u3002 3.2.Linux\u7684\u5185\u5916\u90e8\u547d\u4ee4 \u00b6 \u5185\u90e8\u547d\u4ee4 (internal command)\u5b9e\u9645\u4e0a\u662fshell\u7a0b\u5e8f\u7684\u4e00\u90e8\u5206\uff0c\u5305\u542b\u7684\u662f\u4e00\u4e9b\u6bd4\u8f83\u7b80\u5355\u7684linux\u7cfb\u7edf\u547d\u4ee4\uff0c\u8fd9\u4e9b\u547d\u4ee4\u7531shell\u7a0b\u5e8f\u8bc6\u522b\u5e76\u5728shell\u7a0b\u5e8f\u5185\u90e8\u5b8c\u6210\u8fd0\u884c\uff0c\u901a\u5e38\u5728linux\u7cfb\u7edf\u52a0\u8f7d\u8fd0\u884c\u65f6shell\u5c31\u88ab\u52a0\u8f7d\u5e76\u9a7b\u7559\u5728\u7cfb\u7edf\u5185\u5b58\u4e2d\u3002 \u5916\u90e8\u547d\u4ee4 (external command)\u662flinux\u7cfb\u7edf\u4e2d\u7684\u5b9e\u7528\u7a0b\u5e8f\u90e8\u5206\uff0c\u7cfb\u7edf\u52a0\u8f7d\u65f6\u5e76\u4e0d\u968f\u7cfb\u7edf\u4e00\u8d77\u88ab\u52a0\u8f7d\u5230\u5185\u5b58\u4e2d\uff0c\u800c\u662f\u5728\u9700\u8981\u65f6\u624d\u5c06\u5176\u8c03\u7528\u5185\u5b58\u3002\u901a\u5e38\u5916\u90e8\u547d\u4ee4\u7684\u5b9e\u4f53\u5e76\u4e0d\u5305\u542b\u5728shell\u4e2d\uff0c\u4f46\u662f\u5176\u547d\u4ee4\u6267\u884c\u8fc7\u7a0b\u662f\u7531shell\u7a0b\u5e8f\u63a7\u5236\u7684\u3002 \u6bd4\u5982\uff1a \u6267\u884c\u547d\u4ee4 type -t cp \uff0c\u7cfb\u7edf\u8fd4\u56de\u7ed3\u679c\u662f file \uff0c\u5916\u90e8\u547d\u4ee4\u3002 \u6267\u884c\u547d\u4ee4 type -t cd \uff0c\u7cfb\u7edf\u8fd4\u56de\u7ed3\u679c builtin \uff0c\u5185\u90e8\u547d\u4ee4\u3002 \u6267\u884c\u547d\u4ee4 enable -a cp \uff0c\u7cfb\u7edf\u8fd4\u56de -bash: enable: cp: not a shell builtin \uff0c\u4e5f\u53ef\u4ee5\u5224\u65ad\u662f\u5426\u4e3a\u5185\u90e8\u547d\u4ee4\u3002 \u5bf9\u4e8e\u5185\u90e8\u547d\u4ee4\uff0c\u53ef\u4ee5\u901a\u8fc7enable\u547d\u4ee4\u6765\u542f\u7528\u6216\u8005\u7981\u7528\u3002 # \u7981\u7528cd\u547d\u4ee4 enable -n cd # \u67e5\u770b\u6240\u6709\u88ab\u7981\u7528\u7684\u547d\u4ee4 enable -n # \u542f\u7528cd\u547d\u4ee4 enable cd \u5bf9\u4e8e\u547d\u4ee4\uff0c\u53ef\u4ee5\u901a\u8fc7 whereis \u547d\u4ee4\u6765\u67e5\u770b\u8def\u5f84\u3002 whereis cp whereis cd 3.3.CPU\u4fe1\u606f \u00b6 lscpu cat /proc/cpuinfo 3.4.\u5185\u5b58\u4f7f\u7528\u72b6\u6001 \u00b6 free cat /proc/meminfo 3.5.\u786c\u76d8\u548c\u5206\u533a\u60c5\u51b5 \u00b6 lsblk openSUSE\u5728VMWare\u9ed8\u8ba4\u5b89\u88c5\u7684\u72b6\u6001\uff1a NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINTS sda 8 :0 0 200G 0 disk \u251c\u2500sda1 8 :1 0 8M 0 part \u251c\u2500sda2 8 :2 0 198G 0 part /home \u2502 /var \u2502 /opt \u2502 /usr/local \u2502 /root \u2502 /tmp \u2502 /srv \u2502 /boot/grub2/x86_64-efi \u2502 /boot/grub2/i386-pc \u2502 /.snapshots \u2502 / \u2514\u2500sda3 8 :3 0 2G 0 part [ SWAP ] sr0 11 :0 1 3 .8G 0 rom Ubuntu\u5728VMWare\u9ed8\u8ba4\u5b89\u88c5\u7684\u72b6\u6001\uff1a NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINTS loop0 7 :0 0 61 .9M 1 loop /snap/core20/1405 loop1 7 :1 0 63 .2M 1 loop /snap/core20/1623 loop2 7 :2 0 79 .9M 1 loop /snap/lxd/22923 loop3 7 :3 0 48M 1 loop /snap/snapd/17029 loop4 7 :4 0 103M 1 loop /snap/lxd/23541 loop5 7 :5 0 48M 1 loop /snap/snapd/17336 sda 8 :0 0 50G 0 disk \u251c\u2500sda1 8 :1 0 1M 0 part \u251c\u2500sda2 8 :2 0 2G 0 part /boot \u2514\u2500sda3 8 :3 0 48G 0 part \u2514\u2500ubuntu--vg-ubuntu--lv 253 :0 0 24G 0 lvm / sr0 11 :0 1 1 .4G 0 rom Rocky\u5728VMWare\u9ed8\u8ba4\u5b89\u88c5\u7684\u72b6\u6001\uff1a NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINTS sda 8 :0 0 50G 0 disk \u251c\u2500sda1 8 :1 0 1G 0 part /boot \u2514\u2500sda2 8 :2 0 49G 0 part \u251c\u2500rl-root 253 :0 0 45 .1G 0 lvm / \u2514\u2500rl-swap 253 :1 0 3 .9G 0 lvm [ SWAP ] sr0 11 :0 1 7 .9G 0 rom 3.6.\u7cfb\u7edf\u67b6\u6784\u4fe1\u606f \u00b6 arch openSUSE\uff0cUbuntu\u548cRocky\u7684\u8fd4\u56de\u7ed3\u679c\u90fd\u662f x86_64 \u3002 3.7.\u5185\u6838\u7248\u672c \u00b6 uname -r \u4e09\u4e2a\u53d1\u884c\u7248\u8fd4\u56de\u7684\u7ed3\u679c\u4e0d\u5c3d\u76f8\u540c\uff1a # openSUSE 5 .14.21-150400.24.21-default # Ubuntu 5 .15.0-52-generic # Rocky 5 .14.0-70.17.1.el9_0.x86_64 3.8.\u64cd\u4f5c\u7cfb\u7edf\u7248\u672c \u00b6 cat /etc/os-release cat /etc/issue # Rocky 9 sudo cat /etc/redhat-release lsb-release -a lsb_release -cs lsb_release -is lsb_release -rs \u5728openSUSE\u4e2d\uff0c\u9700\u8981\u5b89\u88c5 lsb-release \u5305\u3002\u6267\u884c lsb-release -a \u548c lsb_release -a \u8fd4\u56de\u7684\u7ed3\u679c\u662f\u4e00\u6837\u7684\u3002 sudo zypper in lsb-release \u5728Ubuntu\u4e2d\uff0c\u9700\u8981\u5b89\u88c5 lsb-release \u5305\u3002\u53ea\u80fd\u6267\u884c lsb_release -a \u3002 sudo apt install lsb-release \u5728Rocky 9\u4e2d\uff0c\u627e\u4e0d\u5230 lsb-release \u76f8\u5173\u7684\u5305\u3002 3.9.\u65e5\u671f\u548c\u65f6\u95f4 \u00b6 \u663e\u793a\u9ed8\u8ba4\u683c\u5f0f\u7684\u5f53\u524d\u65e5\u671f\u3002 date \u4e09\u4e2a\u7cfb\u7edf\u7684\u9ed8\u8ba4\u65e5\u671f\u683c\u5f0f\u7565\u6709\u4e0d\u540c\u3002 # openSUSE Mon 24 Oct 2022 09 :28:06 AM CST # Ubuntu Mon Oct 24 01 :28:09 AM UTC 2022 # Rocky Mon Oct 24 09 :24:01 AM CST 2022 \u663e\u793a\u81ea1970-01-01 00:00:00 UTC\u5230\u5f53\u524d\u7684\u79d2\u6570\u3002 date +%s \u5c06\u4e0a\u4e00\u547d\u4ee4\u4e2d\u7684\u63cf\u8ff0\u8f6c\u6362\u4e3a\u7cfb\u7edf\u9ed8\u8ba4\u65e5\u671f\u683c\u5f0f\u3002 date -d @ ` date +%s ` date --date = @ '1666575347' \u663e\u793a\u786c\u4ef6\u65f6\u949f\u3002 hwclock \u4e5f\u88ab\u79f0\u4e3a Real Time Clock (RTC)\u3002 \u5728Rocky9\u4e2d\uff0c clock \u6709\u4e00\u4e2a\u8f6f\u8fde\u63a5\u6307\u5411 hwclock \uff1a /usr/sbin/clock -> hwclock \u3002\u5728openSUSE\u548cUbuntu\u4e2d\u53ea\u6709 hwclock \u3002 ll /usr/sbin/clock ll /usr/sbin/hwclock \u8bfb\u53d6RTC\u65f6\u95f4\u3002 sudo hwclock --get sudo hwclock -r \u6821\u51c6\u65f6\u95f4\uff1a -s, \u2013hctosys : \u4ee5RTC\u786c\u4ef6\u65f6\u95f4\u6765\u6821\u51c6\u7cfb\u7edf\u65f6\u95f4\u3002 -w, \u2013systohoc : \u4ee5\u7cfb\u7edf\u65f6\u95f4\u6765\u6821\u51c6RTC\u786c\u4ef6\u65f6\u95f4\u3002 \u663e\u793a\u5f53\u524d\u7cfb\u7edf\u65f6\u533a\u3002 ll /etc/localtime \u7cfb\u7edf\u53ef\u80fd\u4f1a\u8fd4\u56de\u4e0d\u540c\u7ed3\u679c\uff0c\u4f8b\u5982\uff1a /etc/localtime -> /usr/share/zoneinfo/Asia/Shanghai /etc/localtime -> /usr/share/zoneinfo/Etc/UTC \u663e\u793a\u5f53\u524d\u53ef\u4ee5\u65f6\u533a\u5217\u8868\u3002 timedatectl list-timezones timedatectl list-timezones | grep -i Asia \u4fee\u6539\u5f53\u524d\u7cfb\u7edf\u65f6\u533a\u3002 sudo timedatectl set-timezone Asia/Shanghai \u663e\u793a\u65e5\u5386\u3002 cal -y openSUSE\u548cRocky\u4e2d\uff0c\u4f7f\u7528 cal \u547d\u4ee4\u9700\u8981\u5b89\u88c5 util-linux \u5305\u3002 Ubuntu\u4e2d\uff0c\u4f7f\u7528 cal \u547d\u4ee4\u9700\u8981\u5b89\u88c5 ncal \u5305\u3002 sudo apt install ncal sudo zypper se util-linux sudo yum install util-linux 3.10.\u7528\u6237\u767b\u5f55\u4fe1\u606f \u00b6 whoami \uff1a\u5f53\u524d\u767b\u5f55\u7528\u6237 who \uff1a\u7cfb\u7edf\u5f53\u524d\u6240\u6709\u7684\u767b\u5f55\u4f1a\u8bdd w \uff1a\u7cfb\u7edf\u5f53\u524d\u6240\u6709\u7684\u767b\u5f55\u4f1a\u8bdd\u53ca\u6240\u4f5c\u7684\u64cd\u4f5c \u63d0\u793a\uff1a MOTD is the abbreviation of \"Message Of The Day\", and it is used to display a message when a remote user login to the Linux Operating system using SSH. Linux administrators often need to display different messages on the login of the user, like displaying custom information about the server or any necessary information. \u7f16\u8f91\u6587\u4ef6 /etc/motd \u53ef\u4ee5\u81ea\u5b9a\u4e49\"Message Of The Day\"\u7684\u4fe1\u606f\u3002 Ubuntu 2204\u65b0\u5b89\u88c5\u540e\u6ca1\u6709\u8fd9\u4e2a\u6587\u4ef6\uff0c\u9700\u8981\u81ea\u5df1\u521b\u5efa\u3002 openSUSE\u65b0\u5b89\u88c5\u540e\u6709\u9884\u5b9a\u4e49\u7684\u4fe1\u606f\u3002 Rocky9 \u65b0\u5b89\u88c5\u540e\u6709\u8be5\u6587\u4ef6\uff0c\u7a7a\u767d\u6587\u4ef6\u65e0\u5185\u5bb9\u3002 3.11.\u4f1a\u8bdd\u7ba1\u7406\u5de5\u5177 \u00b6 screen \u5de5\u5177 screen -S (Create new screen session) screen -ls (list current screen sessions) screen -x (Attach to existing screeen session, sync between both) screen -r (Reattach existing screen session) tmux \u5de5\u5177 tmux \u662f\u6307 Terminal Multiplexer . \u5b89\u88c5 tmux \u5de5\u5177\u3002 # Rocky sudo yum install tmux # Ubuntu sudo apt install tmux # openSUSE sudo zypper in tmux \u5e38\u7528\u65b9\u6cd5\uff1a tmux new -s (Create new session) tmux detach (Detach current session) tmux ls (list current sessions) tmux attach -t (Reattach existing session) tmux switch -t (Switch to another session) tmux kill-session -t (Kill existing session) tmux list-keys (List all short keys) tmux list-commands (List commands and parameters) tmux info (List all sessions info) tmux split-window (Split window) 3.12. echo \u547d\u4ee4 \u00b6 echo \u547d\u4ee4\u4e2d\u53ef\u4ee5\u8f93\u51fa\u53d8\u91cf\uff0c\u5982\u679c\u53d8\u91cf\u662f\u7528\u662f\u5355\u5f15\u53f7\u5f15\u8d77\u6765\uff0c\u8868\u793a\u8fd9\u4e2a\u53d8\u91cf\u4e0d\u7528IFS\u66ff\u6362\uff01\uff01 echo \"Home=$HOME\" \u7684\u8f93\u51fa\u7ed3\u679c\u662f Home=/home/vagrant echo 'Home=$HOME' \u7684\u8f93\u51fa\u7ed3\u679c\u662f Home=$HOME echo -e \u542f\u7528 \\ \u5b57\u7b26\u7684\u89e3\u91ca\u529f\u80fd\uff0c\u6bd4\u5982\uff1a echo -e \"a\\x0Ab\" \uff0c\u8f93\u51fa\u5b57\u7b26 a \u548c b \uff0c\u4e2d\u95f4 \\x0A \u4ee3\u8868\u5341\u516d\u8fdb\u5236 OA \uff08\u5373\u56de\u8f66\uff09 echo -e \"\\x4A \\x41 \\x4D \\x45 \\x53\" \uff0c\u8f93\u51fa\u7ed3\u679c\u662f J A M E S \u63d0\u793a\uff1a \u4ee5\u901a\u8fc7man 7 ascii\u6765\u67e5\u770b\u5404\u8fdb\u5236\u7684\u542b\u4e49\u3002 echo -e \u8f93\u51fa\u5e26\u989c\u8272\u5b57\u7b26\u3002 \u793a\u4f8b\uff1a echo -e \"\\e[35m \u7d2b\u8272 \\e[0m\" echo -e \"\\e[43m \u9ec4\u5e95 \\e[0m\" echo -e \"\\e[93m \u9ed1\u5e95\u9ec4\u5b57 \\e[0m\" \u53c2\u8003\u4fe1\u606f\uff1a \u5b57\u4f53\u989c\u8272\uff1a \\e[30m \uff1a \u9ed1\u8272 \\e[31m \uff1a \u7ea2\u8272 \\e[32m \uff1a \u7eff\u8272 \\e[33m \uff1a \u9ec4\u8272 \\e[34m \uff1a \u84dd\u8272 \\e[35m \uff1a \u7d2b\u8272 \\e[36m \uff1a \u9752\u8272 \\e[37m \uff1a \u767d\u8272 \\e[40m \uff1a \u9ed1\u5e95 \\e[41m \uff1a \u7ea2\u5e95 \\e[42m \uff1a \u7eff\u5e95 \\e[43m \uff1a \u9ec4\u5e95 \\e[44m \uff1a \u84dd\u5e95 \\e[45m \uff1a \u7d2b\u5e95 \\e[46m \uff1a \u9752\u5e95 \\e[47m \uff1a \u767d\u5e95 \u80cc\u666f\u989c\u8272\uff1a \\e[90m \uff1a \u9ed1\u5e95\u9ed1\u5b57 \\e[91m \uff1a \u9ed1\u5e95\u7ea2\u5b57 \\e[92m \uff1a \u9ed1\u5e95\u7eff\u5b57 \\e[93m \uff1a \u9ed1\u5e95\u9ec4\u5b57 \\e[94m \uff1a \u9ed1\u5e95\u84dd\u5b57 \\e[95m \uff1a \u9ed1\u5e95\u7d2b\u5b57 \\e[96m \uff1a \u9ed1\u5e95\u9752\u5b57 \\e[97m \uff1a \u9ed1\u5e95\u767d\u5b57 \u63a7\u5236\u5c5e\u6027\uff1a \\e[0m \u5173\u95ed\u6240\u6709\u5c5e\u6027 \\e[1m \u8bbe\u7f6e\u9ad8\u4eae\u5ea6 \\e[4m \u4e0b\u5212\u7ebf \\e[5m \u95ea\u70c1 \\e[7m \u53cd\u663e\uff0c\u649e\u8272\u663e\u793a\uff0c\u663e\u793a\u4e3a\u767d\u5b57\u9ed1\u5e95\uff0c\u6216\u8005\u663e\u793a\u4e3a\u9ed1\u5e95\u767d\u5b57 \\e[8m \u6d88\u5f71\uff0c\u5b57\u7b26\u989c\u8272\u5c06\u4f1a\u4e0e\u80cc\u666f\u989c\u8272\u76f8\u540c \\e[nA \u5149\u6807\u4e0a\u79fb n \u884c \\e[nB \u5149\u6807\u4e0b\u79fb n \u884c \\e[nC \u5149\u6807\u53f3\u79fb n \u884c \\e[nD \u5149\u6807\u5de6\u79fb n \u884c \\e[y;xH \u8bbe\u7f6e\u5149\u6807\u4f4d\u7f6e \\e[2J \u6e05\u5c4f \\e[K \u6e05\u9664\u4ece\u5149\u6807\u5230\u884c\u5c3e\u7684\u5185\u5bb9 \\e[s \u4fdd\u5b58\u5149\u6807\u4f4d\u7f6e \\e[u \u6062\u590d\u5149\u6807\u4f4d\u7f6e \\e[?25 \u9690\u85cf\u5149\u6807 \\e[?25h \u663e\u793a\u5149\u6807 3.13. man \u547d\u4ee4 \u00b6 \u5b89\u88c5\u5305\uff1a # openSUSE sudo zypper install man-pages man-pages-zh_CN man-pages-posix # Rocky sudo yum install man-pages # Ubuntu sudo apt install man-db manpages-posix manpages manpages-zh sudo apt install manpages-dev manpages-posix-dev \u66f4\u65b0mandb mandb \u67e5\u627e\u67d0\u4e2a\u547d\u4ee4\u7684man\u4fe1\u606f\uff0c\u4f8b\u5982\u67e5\u627e crontab \u547d\u4ee4\u7684\u4fe1\u606f\u3002 # \u7cbe\u786e\u67e5\u627e man -f crontab whatis crontab # \u6a21\u7cca\u67e5\u8be2 man -k crontab apropos crontab \u8f93\u51fa\u7ed3\u679c\u5982\u4e0b\uff1a crontab (5) - files used to schedule the execution of programs crontab (1) - maintains crontab files for individual users crontab (1p) - schedule periodic background work \u67e5\u627ecrontab\u7b2c5\u7ae0\u7684\u5185\u5bb9\uff0c\u5219\u53ef\u4ee5\u6267\u884c\uff1a man 5 crontab \u5e38\u7528\u5feb\u6377\u952e\u793a\u4f8bs\uff1a 1G : go to the 1 st line 10G : go to the 10 th line G : go to the end of the page /^SELinux : search the word SELinux /section OPTIONS : go to the section OPTIONS 3.14. tr \u547d\u4ee4 \u00b6 tr \u547d\u4ee4\u53ef\u4ee5\u5bf9\u6765\u81ea\u6807\u51c6\u8f93\u5165\u7684\u5b57\u7b26\u8fdb\u884c\u66ff\u6362\u3001\u538b\u7f29\u548c\u5220\u9664\u3002\u5b83\u53ef\u4ee5\u5c06\u4e00\u7ec4\u5b57\u7b26\u53d8\u6210\u53e6\u4e00\u7ec4\u5b57\u7b26\u3002 \u683c\u5f0f\uff1a tr [OPTION]... SET1 [SET2] \u4e3e\u4f8b\uff1a # \u5c06\u8f93\u5165\u5b57\u7b26\u7531\u5927\u5199\u8f6c\u6362\u4e3a\u5c0f\u5199 $ echo \"HELLO WORLD\" | tr 'A-Z' 'a-z' hello world # \u5220\u9664\u51fa\u73b0\u7684\u6570\u5b57 $ echo \"HELLO 1234 WORLD 4567\" | tr -d '0-9' HELLO WORLD # \u4ece\u8f93\u5165\u6587\u672c\u4e2d\u5c06\u4e0d\u5728\u8865\u96c6\u4e2d\u7684\u6240\u6709\u5b57\u7b26\u5220\u9664\uff08\u53ea\u4fdd\u7559\u6570\u5b571\uff0c2\uff0c3\uff0c4\uff0c5\uff09 $ echo \"HELLO 1234 WORLD 4567\" | tr -d -c '1-5' 123445 # \u5c06\u8fde\u7eed\u91cd\u590d\u7684\u5b57\u7b26\u4ee5\u5355\u72ec\u4e00\u4e2a\u5b57\u7b26\u8868\u793a $ echo \"HELLOOO 1222235555555554\" | tr -s 'O215' HELLO 12354 # \u5220\u9664\u7531\u4e8eWindows\u6587\u4ef6\u9020\u6210\u7684'^M'\u5b57\u7b26 $ cat file.txt | tr -s '\\r' '\\n' > new.txt $ cat file.txt | tr -d '\\r' > new.txt # \u5c06\u6362\u884c\u7b26\u66ff\u6362\u6210\u5236\u8868\u7b26 $ cat file.txt | tr '\\n' '\\t' > new.txt # \u5c06\u5927\u5199\u5b57\u6bcd\u8f6c\u6362\u4e3a\u5c0f\u5199\u5b57\u6bcd $ echo \"HELLO 1234 WORLD 4567\" | tr '[:upper:]' '[:lower:]' hello 1234 world 4567 3.15. tee \u547d\u4ee4 \u00b6 tee \u547d\u4ee4\u57fa\u4e8e\u6807\u51c6\u8f93\u5165\u8bfb\u53d6\u6570\u636e\uff0c\u6807\u51c6\u8f93\u51fa\u6216\u6587\u4ef6\u5199\u5165\u6570\u636e\u3002 \u4e3e\u4f8b\uff1a # ping\u547d\u4ee4\u7684\u8f93\u51fa\uff0c\u4e0d\u4ec5\u8f93\u51fa\u5230\u5c4f\u5e55\uff0c\u4e5f\u540c\u65f6\u5199\u5165\u6587\u4ef6output.txt\u4e2d\uff08\u8986\u76d6\u5f0f\u5199\u5165\uff09\u3002 $ ping www.baidu.com | tee output.txt # ping\u547d\u4ee4\u7684\u8f93\u51fa\uff0c\u4e0d\u4ec5\u8f93\u51fa\u5230\u5c4f\u5e55\uff0c\u4e5f\u540c\u65f6\u5199\u5165\u6587\u4ef6output.txt\u4e2d\uff08\u8ffd\u52a0\u5f0f\u5199\u5165\uff09\u3002 $ ping www.baidu.com | tee -a output.txt # ping\u547d\u4ee4\u7684\u8f93\u51fa\uff0c\u4e0d\u4ec5\u8f93\u51fa\u5230\u5c4f\u5e55\uff0c\u4e5f\u540c\u65f6\u5199\u5165\u591a\u4e2a\u6587\u4ef6\u4e2d\uff08\u8986\u76d6\u5f0f\u5199\u5165\uff09\u3002 $ ping www.baidu.com | tee output1.txt output2.txt output3.txt # ls\u547d\u4ee4\u7684\u8f93\u51fa\u5199\u5165\u6587\u4ef6output.txt\u4e2d\uff0c\u5e76\u4f5c\u4e3awc\u547d\u4ee4\u7684\u8f93\u5165\u3002 $ ls *.txt | tee output.txt | wc -l 4 # cat output.txt f1.txt f2.txt output.txt test.txt \u6280\u5de7\uff1a \u5728vi\u4f7f\u7528\u4e2d\uff0c\u901a\u8fc7 tee \u547d\u4ee4\u63d0\u5347\u6587\u4ef6\u5199\u5165\u6743\u9650\u3002 \u6bd4\u5982\u975eroot\u7528\u6237\u6267\u884c vi /etc/hosts \uff0c\u5728vi\u4e2d\u4f7f\u7528 :w !sudo tee % \u53ef\u4ee5\u63d0\u9ad8\u6743\u9650\u4fdd\u5b58\u8fd9\u4e2a\u6587\u4ef6\u3002 3.16.\u8bed\u8a00\u73af\u5883LANG \u00b6 \u5b89\u88c5\u8bed\u8a00\u5305\u3002 # Ubuntu sudo apt install locales-all # Rocky sudo yum install glibc-langpack-zh.x86_64 # openSUSE sudo zypper install glibc-locale glibc-locale-32bit glibc-locale-base \u67e5\u770b\u5f53\u524d\u8bed\u8a00\u8bbe\u7f6e\uff1a echo $LANG locale -a locale -k LC_TIME localectl status localectl list-locales \u5168\u5c40locale\u914d\u7f6e(Global locale settings)\u3002 # openSUSE & Rocky sudo cat /etc/locale.conf # Ubuntu sudo cat /etc/default/locale \u4e34\u65f6\u4fee\u6539\u5f53\u524dsession\u7684locale\u3002 LANG = \"zh_CN.utf8\" \u6c38\u4e45\u4fee\u6539locale\u8bbe\u7f6e\u3002 sudo localectl set-locale LANG = zh_CN.utf8 \u4fee\u6539\u56de\u539f\u8bbe\u7f6e\u3002 sudo localectl set-locale LANG = en_US.utf8 Tips: Mac OS ssh\u767b\u9646Linux\u662f\u7ec8\u7aef\u63d0\u793a /usr/bin/manpath: can't set the locale; make sure $LC_* and $LANG are correct \u89e3\u51b3\u65b9\u6cd5\uff1a\u5728\u672c\u5730mac\u7535\u8111\u4e0a\u4fee\u6539/etc/ssh/ssh_config\u6216\u8005/etc/ssh/ssh_config\u6587\u4ef6\uff0c\u5220\u9664\u6389\u6216\u8005\u6ce8\u91ca\u6389\u8fd9\u4e00\u884c\u914d\u7f6e\u5185\u5bb9 # SendEnv LANG LC_* \u3002 \u5982\u679c\u4f7f\u7528\u7684\u662f Iterm2 \uff0c\u53ef\u4ee5\u6253\u5f00 iterm2 \u7684 preferences -> Profiles -> Terminal \u83dc\u5355\u91cc\u5173\u95ed Set locale variables automatically \u9009\u9879\u3002 3.17.\u7b26\u53f7 $ \u7528\u6cd5 \u00b6 \u7b26\u53f7 $ \u7684\u7528\u6cd5\uff1a $ \uff0c\u83b7\u53d6\u53d8\u96f6\u503c\u3002 x = 1 echo $x echo \" $x \" \u5efa\u8bae\u4f7f\u7528\"$x\"\uff0c\u4ee5\u907f\u514dshell\u7f16\u7a0b\u4e2d\u4ea7\u751f\u6b67\u4e49\u3002\u5982\u4e0b\u4f8b\uff1a s = \"this is a string\" echo $s echo \"this is a string\" \u6267\u884c [ $s == \"this is a string\" ] \u4f1a\u62a5\u9519\uff0c\u8fd9\u662f\u5b9e\u9645\u751f\u6210\u7684\u6bd4\u8f83\u5f0f this is a string == \"this is a string\" \u3002 \u6211\u4eec\u9884\u671f\u7684\u662f \"this is a string\" == \"this is a string\" \uff0c\u6240\u4ee5\u9700\u8981\u6539\u6210 [ \"$s\" == \"this is a string\" ] \u3002 $0 , $1 , $n , $# \uff1a \u751f\u6210\u4e00\u4e2a\u6d4b\u8bd5\u811a\u672c\u3002 echo 'echo $0 $1 $2 $#' > test.sh chmod 755 test.sh \u9a8c\u8bc1\u5404\u4e2a\u53c2\u6570\u4f4d\u7f6e\u3002 ./test.sh a b c d e \u8f93\u51fa\u7ed3\u679c\uff1a ./test.sh a b 5 \u7ed3\u8bba\uff1a $0 \u8f93\u51fa\u811a\u672c\u6587\u4ef6\u540d\uff1b $1 \u8f93\u51fa\u7b2c\u4e00\u4e2a\u53c2\u6570\uff1b $2 \u8f93\u51fa\u7b2c\u4e8c\u4e2a\u53c2\u6570\uff1b $# \u8f93\u51fa\u53c2\u6570\u4e2a\u6570\u3002 ${} ${} \u7528\u4e8e\u533a\u5206\u53d8\u91cf\u7684\u8fb9\u754c\u3002 \u4e0b\u9762\u4f8b\u5b50\u4e2d\uff0c $abc \u65e0\u7ed3\u679c\u8f93\u51fa\uff0c ${a}bc \u8f93\u51fa\u7ed3\u679c stringbc \uff0c\u901a\u8fc7{}\u6307\u5b9a\u4e86\u67d0\u4e2a\u5b57\u7b26\u5c5e\u4e8e\u53d8\u91cf\u3002 a = \"string\" echo ${ a } bc echo $abc ${#} ${#} \u662f\u8fd4\u56de\u53d8\u91cf\u503c\u7684\u957f\u5ea6\u3002 s = 'this is a string' echo \" $s \" echo \" ${# s } \" \u547d\u4ee4 echo \"${#s}\" \u8f93\u51fa\u7ed3\u679c\u662f\u5b57\u4e32 this is a string \u7684\u957f\u5ea6 16 \u3002 $? $? \u662f\u8fd4\u56de\u4e0a\u4e00\u547d\u4ee4\u662f\u5426\u6210\u529f\u7684\u72b6\u6001\uff0c 0 \u4ee3\u8868\u6210\u529f\uff0c\u975e\u96f6\u4ee3\u8868\u5931\u8d25\u3002 ls \u662f\u4e00\u4e2a\u547d\u4ee4\uff0c\u6240\u4ee5\u8fd4\u56de\u503c\u662f 0 \u3002 tom \u662f\u4e00\u4e2a\u4e0d\u5b58\u5728\u7684\u547d\u4ee4\uff0c\u5219\u8fd4\u56de 127 \u3002 ls echo $? tom echo $? $() $() \u7b49\u540c\u4e8e\u53cd\u5f15\u53f7\u3002 echo $(ls) \u7b49\u540c\u4e8e\u6267\u884c ls \u547d\u4ee4\u3002 $() \u7684\u5f0a\u7aef\u662f\uff0c\u4e0d\u662f\u6240\u6709\u7684\u7c7bunix\u7cfb\u7edf\u90fd\u652f\u6301\uff0c\u53cd\u5f15\u53f7\u662f\u80af\u5b9a\u652f\u6301\u7684\u3002 $() \u7684\u4f18\u52bf\u662f\u76f4\u89c2\uff0c\u5728\u8f6c\u79fb\u5904\u7406\u65f6\uff0c\u6bd4\u53cd\u5f15\u53f7\u76f4\u89c2\u5bb9\u6613\u4e9b\u3002 echo $( ls ) # test.sh echo $( cat $( ls )) # echo $0 $1 $2 $# \u4e0a\u8ff0\u5d4c\u5957\u683c\u5f0f\u4e2d\uff0cls\u547d\u4ee4\u7684\u8f93\u51fa\uff0c\u662fcat\u547d\u4ee4\u7684\u8f93\u5165\uff0c\u53ef\u4ee5\u8fdb\u884c\u591a\u5c42\u5d4c\u5957\uff0c\u5185\u5c42\u547d\u4ee4\u7684\u8f93\u51fa\u662f\u5916\u5c42\u547d\u4ee4\u7684\u8f93\u5165\u3002 $[] $[] \u662f\u8868\u8fbe\u5f0f\u8ba1\u7b97\u3002 echo $ [ 3 + 2 ] $- $- \u663e\u793ashell\u5f53\u524d\u6240\u4f7f\u7528\u7684\u9009\u9879\u3002 \u6267\u884c echo $- \uff0c\u8f93\u51fa\u7ed3\u679c himBHs \u3002himBH\u6bcf\u4e00\u4e2a\u5b57\u7b26\u662f\u4e00\u4e2ashell\u7684\u9009\u9879\u3002 $! $! \u83b7\u53d6\u6700\u540e\u4e00\u4e2a\u8fd0\u884c\u7684\u540e\u53f0\u8fdb\u7a0b\u7684pid\u3002 \u6bd4\u5982\u6267\u884c cat test.sh & \uff0c\u7ed3\u679c\u4e2d\u4f1a\u5305\u542b\u4e00\u4e2apid\u53f7\uff0c\u9a6c\u4e0a\u7740\u6267\u884c echo $! \uff0c\u5982\u679c2\u4e2a\u547d\u4ee4\u95f4\u9694\u4e4b\u95f4\u6ca1\u6709\u5176\u4ed6\u540e\u53f0\u8fdb\u7a0b\u6267\u884c\uff0c\u5219\u53ef\u4ee5\u5f97\u5230\u548c\u524d\u9762\u4e00\u81f4\u7684pid\u53f7\u3002 !$ !$ \u8fd4\u56de\u4e0a\u4e00\u6761\u547d\u4ee4\u7684\u6700\u540e\u4e00\u4e2a\u53c2\u6570\u3002 \u6267\u884c ./test.sh a b c iamhere \uff0c\u5f97\u5230\u7ed3\u679c ./test.sh a b 4 \u3002 \u6267\u884c echo !$ \uff0c\u5f97\u52302\u4e2a\u7ed3\u679c\uff0c echo iamhere \u548c iamhere \u3002 !! !! \u8f93\u51fa\u4e0a\u4e00\u6761\u547d\u4ee4\uff0c\u5e76\u6267\u884c\u3002 !! \u4f1a\u5148\u8f93\u51fa\u4e0a\u4e00\u6761\u547d\u4ee4 cat test.sh \uff0c\u7136\u540e\u518d\u6267\u884c\u8fd9\u6761\u547d\u4ee4\uff0c\u7b2c\u4e8c\u884c\u5373\u6267\u884c\u7ed3\u679c\u3002 [ vagrant@lizard:~ ] $ cat test.sh echo $0 $1 $2 $# [ vagrant@lizard:~ ] $ !! cat test.sh echo $0 $1 $2 $# $$ $$ \u8f93\u51fa\u5f53\u524d\u8fdb\u7a0b\u7684pid\u3002 echo $$ $@ & $* $@ \u548c $* \u662f\u5bf9\u4f20\u5165\u53c2\u6570\u7684\u4e0d\u540c\u4f53\u73b0\uff0c $@ \u662f\u4ee5\u53d8\u91cf\u5f62\u5f0f\u5f15\u7528\u4f20\u5165\u53c2\u6570\uff0c $* \u662f\u4ee5\u6570\u7ec4\u7684\u5f62\u5f0f\u5f15\u7528\u4f20\u5165\u53c2\u6570\u3002 \u521b\u5efa\u4e00\u4e2a\u6587\u4ef6 script.sh \u5305\u542b\u4e0b\u9762\u7684\u811a\u672c\u3002\u5e76\u6dfb\u52a0\u6267\u884c\u6743\u9650 chmod 755 script.sh \u3002 echo '$@\u4ee5\u53d8\u91cf\u65b9\u5f0f\u5f15\u7528\u4f20\u5165\u53c2\u6570\uff1a' for x in \" $@ \" do echo $x done echo '$*\u4ee5\u6570\u7ec4\u7684\u5f62\u5f0f\u5f15\u7528\u4f20\u5165\u53c2\u6570\uff1a' for x in \" $* \" do echo $x done \u8f93\u51fa\u7ed3\u679c\uff1a $@ \u4ee5\u53d8\u91cf\u65b9\u5f0f\u5f15\u7528\u4f20\u5165\u53c2\u6570\uff1a a b 3 5 d $* \u4ee5\u6570\u7ec4\u7684\u5f62\u5f0f\u5f15\u7528\u4f20\u5165\u53c2\u6570\uff1a a b 3 5 d","title":"\u7b2c\u4e00\u7ae0 Linux\u57fa\u7840"},{"location":"linux/SRE/01-fundamentals/#linux","text":"","title":"\u7b2c\u4e00\u7ae0 Linux\u57fa\u7840"},{"location":"linux/SRE/01-fundamentals/#1","text":"Rocky Linux Instructional Books openSUSE Documentation Ubuntu Documentation","title":"1.\u5b98\u65b9\u6587\u6863"},{"location":"linux/SRE/01-fundamentals/#2","text":"","title":"2.\u7cfb\u7edf\u73af\u5883"},{"location":"linux/SRE/01-fundamentals/#21rocky","text":"\u4f7f\u7528\u7248\u672c\uff1a Rocky 9.0 \u3002 \u4ece\u7f51\u7ad9\u4e0b\u8f7dRocky\u7cfb\u7edf ISO\u955c\u50cf \uff0c\u6216\u8005\u901a\u8fc7 wget \u547d\u4ee4\u4e0b\u8f7dRocky\u7cfb\u7edfISO\u955c\u50cf\u3002 wget https://download.rockylinux.org/pub/rocky/9.0/isos/x86_64/Rocky-9.0-x86_64-dvd.iso \u5b89\u88c5\u65f6\u6211\u9009\u62e9\u4e86\u6fc0\u6d3b root \u7528\u6237\uff0c\u9009\u62e9\u4e86Server\u6a21\u5f0f\u5b89\u88c5\uff08\u6ca1\u6709GUI\uff09\u3002 \u4ee5 root \u767b\u5f55\uff0c\u6267\u884c\u4e0b\u9762\u547d\u4ee4\u4fee\u6539 sudo \u6743\u9650\u3002 visudo \u5e76\u6fc0\u6d3b\u4e0b\u9762\u4e00\u884c\uff08\u4e0d\u8bbe\u5bc6\u7801\uff0c\u65b9\u4fbf\u7ec3\u4e60\uff09\uff1a %wheel ALL =( ALL ) NOPASSWD: ALL \u521b\u5efa\u7528\u6237 vagrant \uff0c\u5e76\u8bbe\u7f6e wheel \u4e3a\u4e3b\u8981\u7ec4\u548c\u4fee\u6539\u5bc6\u7801\u3002 adduser vagrant usermod -g wheel vagrant passwd vagrant \u8bbe\u5b9ahostname\uff08\u5305\u62ec\u522b\u540d\uff09\uff0c\u5e76\u67e5\u770b\u7ed3\u679c\u3002 hostnamectl set-hostname --static \"rocky9\" hostnamectl set-hostname --pretty \"rocky9\" hostnamectl cat /etc/hostname \u5c0f\u8d34\u58eb\uff1a \u7531systemd\u63a7\u5236\u7684\u4e3b\u673a\u540d\u7684\u670d\u52a1\u914d\u7f6e\u4fe1\u606f\uff1a /usr/lib/systemd/system/systemd-hostnamed.service Rocky\u7684\u8f6f\u4ef6\u6e90\u7684\u914d\u7f6e\u4fe1\u606f\u4fdd\u5b58\u5728\u76ee\u5f55 /etc/yum.repos.d/ \u4e0b\u3002\u5982\u679c\u8bbf\u95ee\u9ed8\u8ba4\u6e90\u6bd4\u8f83\u6162\uff0c\u53ef\u4ee5\u66f4\u65b0\u963f\u91cc\u6e90\u6216\u8005\u79d1\u5927\u6e90\u3002 \u66f4\u6362\u963f\u91cc\u6e90\u3002 sed -e 's|^mirrorlist=|#mirrorlist=|g' \\ -e 's|^#baseurl=http://dl.rockylinux.org/$contentdir|baseurl=https://mirrors.aliyun.com/rockylinux|g' \\ -i.bak \\ /etc/yum.repos.d/Rocky-*.repo \u66f4\u6362\u79d1\u5927\u6e90\u3002 sed -e 's|^mirrorlist=|#mirrorlist=|g' \\ -e 's|^#baseurl=http://dl.rockylinux.org/$contentdir|baseurl=https://mirrors.ustc.edu.cn/rocky|g' \\ -i.bak \\ /etc/yum.repos.d/rocky-extras.repo \\ /etc/yum.repos.d/rocky.repo \u5237\u65b0\u7f13\u5b58\u3002 dnf makecache","title":"2.1.Rocky"},{"location":"linux/SRE/01-fundamentals/#22ubuntu","text":"\u4f7f\u7528\u7248\u672c\uff1a Ubuntu 2204 \u3002 \u8bbe\u5b9aroot\u7528\u6237\u7684\u5bc6\u7801\u3002 sudo passwd root \u901a\u8fc7\u5b89\u88c5\u65f6\u5df2\u521b\u5efa\u7684\u7528\u6237 vagrant \u767b\u5f55\u3002\u6267\u884c\u4e0b\u9762\u547d\u4ee4\u4fee\u6539 sudo \u6743\u9650\u3002 sudo visudo \u6dfb\u52a0 vagrant \u5230\u7279\u6743\u7528\u6237\uff08Rocky\u548copenSUSE\u4e0d\u9700\u8981\u6dfb\u52a0\uff09\uff0c\u5e76\u6fc0\u6d3bsudo\u4e00\u884c\uff08\u4e0d\u8bbe\u5bc6\u7801\uff0c\u65b9\u4fbf\u7ec3\u4e60\uff09\uff1a # User privilege specification root ALL =( ALL:ALL ) ALL vagrant ALL =( ALL:ALL ) ALL # Allow members of group sudo to execute any command sudo ALL =( ALL:ALL ) NOPASSWD: ALL \u4fee\u6539\u7528\u6237 vagrant \u7684\u4e3b\u8981\u7ec4\u4e3a sudo \u3002 sudo usermod -g sudo vagrant \u4fee\u6539\u4e3b\u673a\u540d\u548c\u522b\u540d\u3002 sudo hostnamectl set-hostname ubuntu2204 sudo hostnamectl set-hostname ubuntu2204 --pretty \u5c0f\u8d34\u58eb\uff1a \u5982\u4f55\u5904\u7406 Username is not in the sudoers file. This incident will be reported \u95ee\u9898\u3002 \u5982\u679c\u6ca1\u6709\u521d\u59cb\u5316 root \u7528\u6237\u7684\u5bc6\u7801\uff0c\u4e14\u5f53\u524d\u7528\u6237\u4e5f\u65e0\u6cd5\u6267\u884c sudo \u547d\u4ee4\uff0c\u53ef\u4ee5\u901a\u8fc7\u4e0b\u9762\u6b65\u9aa4\u901a\u8fc7recovery\u6551\u63f4\u6a21\u5f0f\u8fdb\u884c\u6062\u590d\u3002 \u6309 shift \u952e\u5f00\u673a\uff0c\u8fdb\u5165grub\u542f\u52a8\u83dc\u5355\u3002\uff08VMWare\u4e5f\u9002\u7528\uff09 \u5411\u4e0b\u79fb\u52a8\u9ad8\u4eae\u6761\uff0c\u9009\u62e9\u83dc\u5355 Advanced options for Ubuntu \uff0c\u5e76\u786e\u8ba4\u56de\u8f66\u3002 \u9009\u62e9\u5e26\u6709 recovery mode \u7684\u5185\u6838\uff0c\u786e\u8ba4\u56de\u8f66\u3002 \u5411\u4e0b\u79fb\u52a8\u9ad8\u4eae\u6761\uff0c\u9009\u62e9\u83dc\u5355 root Drop to root shell prompt \uff0c\u5e76\u786e\u8ba4\u56de\u8f66\u3002 \u56de\u8f66\u786e\u8ba4 press Enter for maintenance \u3002 \u51fa\u73b0 root \u7684\u547d\u4ee4\u63d0\u793a\u7b26\u540e\uff0c\u6267\u884c\u547d\u4ee4 mount -o rw,remount / \u3002 \u6267\u884c\u547d\u4ee4 passwd \u7ed9 root \u8bbe\u5b9a\u5bc6\u7801\u3002 \u6267\u884c\u547d\u4ee4 adduser username sudo \u628a\u6307\u5b9a\u7528\u6237\u52a0\u5165 sudo \u7ec4\u3002 \u6267\u884c\u547d\u4ee4 visudo \u8fdb\u884c\u5fc5\u8981\u7684\u4fee\u6b63\u6216\u4fee\u6539\u3002","title":"2.2.Ubuntu"},{"location":"linux/SRE/01-fundamentals/#23opensuse","text":"\u4f7f\u7528\u7248\u672c\uff1a Leap 15.4 \u3002 \u9009\u62e9\u670d\u52a1\u5668\u6a21\u5f0f\u5b89\u88c5\uff0c\u65e0\u56fe\u5f62\u754c\u9762\u3002\u5b89\u88c5\u4e2d\u4e0d\u521b\u5efa\u7528\u6237\u3002 \u521b\u5efa\u7528\u6237 vagrant \uff0c\u5e76\u8bbe\u7f6e wheel \u4e3a\u4e3b\u8981\u7ec4\u3002 useradd -m -g wheel -G root -c \"vagrant\" vagrant passwd vagrant \u6267\u884c visudo \u547d\u4ee4\uff0c\u6fc0\u6d3b\u4e0b\u9762\u4e00\u884c\uff0c\u6dfb\u52a0 sudo \u6743\u9650\u3002 % wheel ALL =( ALL ) NOPASSWD: ALL \u4fee\u6539\u4e3b\u673a\u540d\u548c\u522b\u540d\u3002 sudo hostnamectl set-hostname lizard sudo hostnamectl set-hostname lizard --pretty","title":"2.3.openSUSE"},{"location":"linux/SRE/01-fundamentals/#3","text":"\u8bf4\u660e\uff1a \u9ed8\u8ba4\u5f53\u524d\u64cd\u4f5c\u7528\u6237\u4e3a vagrant \u3002","title":"3.\u5e38\u7528\u547d\u4ee4"},{"location":"linux/SRE/01-fundamentals/#31","text":"\u6267\u884c\u4e0b\u9762\u547d\u4ee4\u53ef\u4ee5\u770b\u5230\u5f53\u524d\u7cfb\u7edf\u7684\u547d\u4ee4\u63d0\u793a\u7b26\u683c\u5f0f\u3002 echo $PS1 \u5404\u7cfb\u7edf\u9ed8\u8ba4\u8bbe\u7f6e\u662f\u6709\u5dee\u5f02\u7684\u3002 # Rocky [ \\u @ \\h \\W ] \\$ # Ubuntu \\[\\e ] 0 ; \\u @ \\h : \\w\\a\\] ${ debian_chroot :+( $debian_chroot ) } \\[\\0 33 [ 01 ; 32m \\]\\u @ \\h\\[\\0 33 [ 00m \\] : \\[\\0 33 [ 01 ; 34m \\]\\w\\[\\0 33 [ 00m \\]\\$ # openSUSE \\u @ \\h : \\w > \u5c0f\u8d34\u58eb\uff1a bash\u53ef\u8bc6\u522b\u7684\u8f6c\u4e49\u5e8f\u5217\u6709\u4e0b\u9762\u8fd9\u4e9b\uff1a \\u : \u5f53\u524d\u7528\u6237\u7684\u8d26\u53f7\u540d\u79f0 \\h : \u4e3b\u673a\u540d\u7b2c\u4e00\u90e8\u5206 \\H : \u5b8c\u6574\u7684\u4e3b\u673a\u540d\u79f0 \\w : \u5b8c\u6574\u7684\u5de5\u4f5c\u76ee\u5f55\u540d\u79f0\uff08\u5982 \"/home/username/mywork\"\uff09 \\W : \u5f53\u524d\u5de5\u4f5c\u76ee\u5f55\u7684\"\u57fa\u540d (basename)\"\uff08\u5982 \"mywork\") \\t : \u663e\u793a\u65f6\u95f4\u4e3a24\u5c0f\u65f6\u683c\u5f0f\uff0c\u5982\uff1aHH:MM:SS \\T : \u663e\u793a\u65f6\u95f4\u4e3a12\u5c0f\u65f6\u683c\u5f0f \\A : \u663e\u793a\u65f6\u95f4\u4e3a24\u5c0f\u65f6\u683c\u5f0f\uff1aHH:MM \\@ : \u5e26\u6709 am/pm \u7684 12 \u5c0f\u65f6\u5236\u65f6\u95f4 \\d : \u4ee3\u8868\u65e5\u671f\uff0c\u683c\u5f0f\u4e3aweekday month date\uff0c\u4f8b\u5982\uff1a\"Mon Aug 1\" \\s : shell \u7684\u540d\u79f0\uff08\u5982 \"bash\") \\v : bash\u7684\u7248\u672c\uff08\u5982 2.04\uff09 \\V : bash\u7684\u7248\u672c\uff08\u5305\u62ec\u8865\u4e01\u7ea7\u522b\uff09 \\n : \u6362\u884c\u7b26 \\r : \u56de\u8f66\u7b26 \\\\ : \u53cd\u659c\u6760 \\a : ASCII \u54cd\u94c3\u5b57\u7b26\uff08\u4e5f\u53ef\u4ee5\u952e\u5165 07 \uff09 \\e : ASCII \u8f6c\u4e49\u5b57\u7b26\uff08\u4e5f\u53ef\u4ee5\u952e\u5165 33 ) \\[ : \u8fd9\u4e2a\u5e8f\u5217\u5e94\u8be5\u51fa\u73b0\u5728\u4e0d\u79fb\u52a8\u5149\u6807\u7684\u5b57\u7b26\u5e8f\u5217\uff08\u5982\u989c\u8272\u8f6c\u4e49\u5e8f\u5217\uff09\u4e4b\u524d\u3002\u5b83\u4f7fbash\u80fd\u591f\u6b63\u786e\u8ba1\u7b97\u81ea\u52a8\u6362\u884c \\] : \u8fd9\u4e2a\u5e8f\u5217\u5e94\u8be5\u51fa\u73b0\u5728\u975e\u6253\u5370\u5b57\u7b26\u5e8f\u5217\u4e4b\u540e \\# : \u4e0b\u8fbe\u7684\u7b2c\u51e0\u4e2a\u547d\u4ee4 \\$ : \u63d0\u793a\u5b57\u7b26\uff0c\u5982\u679c\u662froot\u7528\u6237\uff0c\u63d0\u793a\u7b26\u4e3a # \uff0c\u666e\u901a\u7528\u6237\u5219\u4e3a $ \u5728PS1\u4e2d\u8bbe\u7f6e\u5b57\u7b26\u989c\u8272\u7684\u683c\u5f0f\u4e3a\uff1a [\\e[F;Bm]........[\\e[0m] \uff0c\u5176\u4e2d [\\e[0m] \u4f5c\u4e3a\u989c\u8272\u8bbe\u5b9a\u7684\u7ed3\u675f\u3002 \u5176\u4e2d\"F\"\u4e3a\u5b57\u4f53\u989c\u8272\uff0c\u7f16\u53f7\u4e3a30-37\uff0c\"B\"\u4e3a\u80cc\u666f\u989c\u8272\uff0c\u7f16\u53f7\u4e3a40-47\u3002 \u5c0f\u8d34\u58eb\uff1a \u989c\u8272\u5bf9\u7167\u8868: F:30 , B:40 : \u9ed1\u8272 F:31 , B:41 : \u7ea2\u8272 F:32 , B:42 : \u7eff\u8272 F:33 , B:43 : \u9ec4\u8272 F:34 , B:44 : \u84dd\u8272 F:35 , B:45 : \u7d2b\u7ea2\u8272 F:36 , B:46 : \u9752\u84dd\u8272 F:37 , B:47 : \u767d\u8272 \u4ee5\u4e0b\u9762\u7684PS1\u8bbe\u5b9a\u4e3a\u4f8b\u8bf4\u660e\u989c\u8272\u8bbe\u5b9a\u3002 PS1 = \"\\[\\e[37;40m\\][\\[\\e[32;40m\\]\\u\\[\\e[37;40m\\]@\\h:\\[\\e[36;40m\\]\\w\\[\\e[0m\\]]\\$ \" \u62c6\u89e3\u5206\u6790\uff1a PS1=\" \\[\\e[37;40m\\] # \u6574\u4e2a\u63d0\u793a\u7b26\u533a\u57df\u524d\u666f\u767d\u8272\uff0c\u80cc\u666f\u9ed1\u8272 [ # \u663e\u793a\u5b57\u7b26[ \\[\\e[32;40m\\] # \u4fee\u9970\u540e\u9762\u7684\\u\uff0c\u524d\u666f\u7eff\u8272\uff0c\u80cc\u666f\u9ed1\u8272 \\u # \u663e\u793a\u5f53\u524d\u7528\u6237\u7684\u8d26\u53f7\u540d\u79f0 \\[\\e[37;40m\\] # \u4fee\u9970\u540e\u9762\u7684\u5b57\u7b26@\u548c\u4e3b\u673a\u540d @ # \u663e\u793a\u5b57\u7b26@ \\h # \u663e\u793a\u4e3b\u673a\u540d : # \u663e\u793a\u5b57\u7b26: \\[\\e[36;40m\\] # \u4fee\u9970\u540e\u9762\u7684\\w\uff0c\u524d\u666f\u9752\u84dd\u8272\uff0c\u80cc\u666f\u9ed1\u8272 \\w # \u663e\u793a\u5b8c\u6574\u5de5\u4f5c\u76ee\u5f55 \\[\\e[0m\\] # \u7ed3\u675f\u989c\u8272\u8bbe\u5b9a ] # \u663e\u793a\u5b57\u7b26] \\$\" # \u5982\u679c\u662froot\u7528\u6237\uff0c\u63d0\u793a\u7b26\u4e3a# \uff0c\u666e\u901a\u7528\u6237\u5219\u4e3a$ \u5bf9\u4e0d\u540c\u4e3b\u673a\u505a\u4e0d\u540c\u8bbe\u7f6e\uff1a # Rocky PS1 = \"\\[\\e[37;40m\\][\\[\\e[32;40m\\]\\u\\[\\e[37;40m\\]@\\h:\\[\\e[36;40m\\]\\w\\[\\e[0m\\]]\\$ \" # Ubuntu PS1 = \"\\[\\e[37;40m\\][\\[\\e[32;40m\\]\\u\\[\\e[33;40m\\]@\\h:\\[\\e[36;40m\\]\\w\\[\\e[0m\\]]\\$ \" # openSUSE PS1 = \"\\[\\e[37;40m\\][\\[\\e[32;40m\\]\\u\\[\\e[35;40m\\]@\\h:\\[\\e[36;40m\\]\\w\\[\\e[0m\\]]\\$ \" \u5c06\u4e0a\u8ff0PS1\u7684\u8bbe\u5b9a\uff0c\u8ffd\u52a0\u5230\u5f53\u524d\u7528\u6237\u7684 ~/.bashrc \u6587\u4ef6\u672b\u5c3e\uff0c\u4ee5\u5b9e\u73b0\u5bf9\u5f53\u524d\u7528\u6237\u7684\u63d0\u793a\u7b26\u98ce\u683c\u505a\u6301\u4e45\u4fdd\u5b58\u3002","title":"3.1.\u4fee\u6539\u63d0\u793a\u7b26\u98ce\u683c"},{"location":"linux/SRE/01-fundamentals/#32linux","text":"\u5185\u90e8\u547d\u4ee4 (internal command)\u5b9e\u9645\u4e0a\u662fshell\u7a0b\u5e8f\u7684\u4e00\u90e8\u5206\uff0c\u5305\u542b\u7684\u662f\u4e00\u4e9b\u6bd4\u8f83\u7b80\u5355\u7684linux\u7cfb\u7edf\u547d\u4ee4\uff0c\u8fd9\u4e9b\u547d\u4ee4\u7531shell\u7a0b\u5e8f\u8bc6\u522b\u5e76\u5728shell\u7a0b\u5e8f\u5185\u90e8\u5b8c\u6210\u8fd0\u884c\uff0c\u901a\u5e38\u5728linux\u7cfb\u7edf\u52a0\u8f7d\u8fd0\u884c\u65f6shell\u5c31\u88ab\u52a0\u8f7d\u5e76\u9a7b\u7559\u5728\u7cfb\u7edf\u5185\u5b58\u4e2d\u3002 \u5916\u90e8\u547d\u4ee4 (external command)\u662flinux\u7cfb\u7edf\u4e2d\u7684\u5b9e\u7528\u7a0b\u5e8f\u90e8\u5206\uff0c\u7cfb\u7edf\u52a0\u8f7d\u65f6\u5e76\u4e0d\u968f\u7cfb\u7edf\u4e00\u8d77\u88ab\u52a0\u8f7d\u5230\u5185\u5b58\u4e2d\uff0c\u800c\u662f\u5728\u9700\u8981\u65f6\u624d\u5c06\u5176\u8c03\u7528\u5185\u5b58\u3002\u901a\u5e38\u5916\u90e8\u547d\u4ee4\u7684\u5b9e\u4f53\u5e76\u4e0d\u5305\u542b\u5728shell\u4e2d\uff0c\u4f46\u662f\u5176\u547d\u4ee4\u6267\u884c\u8fc7\u7a0b\u662f\u7531shell\u7a0b\u5e8f\u63a7\u5236\u7684\u3002 \u6bd4\u5982\uff1a \u6267\u884c\u547d\u4ee4 type -t cp \uff0c\u7cfb\u7edf\u8fd4\u56de\u7ed3\u679c\u662f file \uff0c\u5916\u90e8\u547d\u4ee4\u3002 \u6267\u884c\u547d\u4ee4 type -t cd \uff0c\u7cfb\u7edf\u8fd4\u56de\u7ed3\u679c builtin \uff0c\u5185\u90e8\u547d\u4ee4\u3002 \u6267\u884c\u547d\u4ee4 enable -a cp \uff0c\u7cfb\u7edf\u8fd4\u56de -bash: enable: cp: not a shell builtin \uff0c\u4e5f\u53ef\u4ee5\u5224\u65ad\u662f\u5426\u4e3a\u5185\u90e8\u547d\u4ee4\u3002 \u5bf9\u4e8e\u5185\u90e8\u547d\u4ee4\uff0c\u53ef\u4ee5\u901a\u8fc7enable\u547d\u4ee4\u6765\u542f\u7528\u6216\u8005\u7981\u7528\u3002 # \u7981\u7528cd\u547d\u4ee4 enable -n cd # \u67e5\u770b\u6240\u6709\u88ab\u7981\u7528\u7684\u547d\u4ee4 enable -n # \u542f\u7528cd\u547d\u4ee4 enable cd \u5bf9\u4e8e\u547d\u4ee4\uff0c\u53ef\u4ee5\u901a\u8fc7 whereis \u547d\u4ee4\u6765\u67e5\u770b\u8def\u5f84\u3002 whereis cp whereis cd","title":"3.2.Linux\u7684\u5185\u5916\u90e8\u547d\u4ee4"},{"location":"linux/SRE/01-fundamentals/#33cpu","text":"lscpu cat /proc/cpuinfo","title":"3.3.CPU\u4fe1\u606f"},{"location":"linux/SRE/01-fundamentals/#34","text":"free cat /proc/meminfo","title":"3.4.\u5185\u5b58\u4f7f\u7528\u72b6\u6001"},{"location":"linux/SRE/01-fundamentals/#35","text":"lsblk openSUSE\u5728VMWare\u9ed8\u8ba4\u5b89\u88c5\u7684\u72b6\u6001\uff1a NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINTS sda 8 :0 0 200G 0 disk \u251c\u2500sda1 8 :1 0 8M 0 part \u251c\u2500sda2 8 :2 0 198G 0 part /home \u2502 /var \u2502 /opt \u2502 /usr/local \u2502 /root \u2502 /tmp \u2502 /srv \u2502 /boot/grub2/x86_64-efi \u2502 /boot/grub2/i386-pc \u2502 /.snapshots \u2502 / \u2514\u2500sda3 8 :3 0 2G 0 part [ SWAP ] sr0 11 :0 1 3 .8G 0 rom Ubuntu\u5728VMWare\u9ed8\u8ba4\u5b89\u88c5\u7684\u72b6\u6001\uff1a NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINTS loop0 7 :0 0 61 .9M 1 loop /snap/core20/1405 loop1 7 :1 0 63 .2M 1 loop /snap/core20/1623 loop2 7 :2 0 79 .9M 1 loop /snap/lxd/22923 loop3 7 :3 0 48M 1 loop /snap/snapd/17029 loop4 7 :4 0 103M 1 loop /snap/lxd/23541 loop5 7 :5 0 48M 1 loop /snap/snapd/17336 sda 8 :0 0 50G 0 disk \u251c\u2500sda1 8 :1 0 1M 0 part \u251c\u2500sda2 8 :2 0 2G 0 part /boot \u2514\u2500sda3 8 :3 0 48G 0 part \u2514\u2500ubuntu--vg-ubuntu--lv 253 :0 0 24G 0 lvm / sr0 11 :0 1 1 .4G 0 rom Rocky\u5728VMWare\u9ed8\u8ba4\u5b89\u88c5\u7684\u72b6\u6001\uff1a NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINTS sda 8 :0 0 50G 0 disk \u251c\u2500sda1 8 :1 0 1G 0 part /boot \u2514\u2500sda2 8 :2 0 49G 0 part \u251c\u2500rl-root 253 :0 0 45 .1G 0 lvm / \u2514\u2500rl-swap 253 :1 0 3 .9G 0 lvm [ SWAP ] sr0 11 :0 1 7 .9G 0 rom","title":"3.5.\u786c\u76d8\u548c\u5206\u533a\u60c5\u51b5"},{"location":"linux/SRE/01-fundamentals/#36","text":"arch openSUSE\uff0cUbuntu\u548cRocky\u7684\u8fd4\u56de\u7ed3\u679c\u90fd\u662f x86_64 \u3002","title":"3.6.\u7cfb\u7edf\u67b6\u6784\u4fe1\u606f"},{"location":"linux/SRE/01-fundamentals/#37","text":"uname -r \u4e09\u4e2a\u53d1\u884c\u7248\u8fd4\u56de\u7684\u7ed3\u679c\u4e0d\u5c3d\u76f8\u540c\uff1a # openSUSE 5 .14.21-150400.24.21-default # Ubuntu 5 .15.0-52-generic # Rocky 5 .14.0-70.17.1.el9_0.x86_64","title":"3.7.\u5185\u6838\u7248\u672c"},{"location":"linux/SRE/01-fundamentals/#38","text":"cat /etc/os-release cat /etc/issue # Rocky 9 sudo cat /etc/redhat-release lsb-release -a lsb_release -cs lsb_release -is lsb_release -rs \u5728openSUSE\u4e2d\uff0c\u9700\u8981\u5b89\u88c5 lsb-release \u5305\u3002\u6267\u884c lsb-release -a \u548c lsb_release -a \u8fd4\u56de\u7684\u7ed3\u679c\u662f\u4e00\u6837\u7684\u3002 sudo zypper in lsb-release \u5728Ubuntu\u4e2d\uff0c\u9700\u8981\u5b89\u88c5 lsb-release \u5305\u3002\u53ea\u80fd\u6267\u884c lsb_release -a \u3002 sudo apt install lsb-release \u5728Rocky 9\u4e2d\uff0c\u627e\u4e0d\u5230 lsb-release \u76f8\u5173\u7684\u5305\u3002","title":"3.8.\u64cd\u4f5c\u7cfb\u7edf\u7248\u672c"},{"location":"linux/SRE/01-fundamentals/#39","text":"\u663e\u793a\u9ed8\u8ba4\u683c\u5f0f\u7684\u5f53\u524d\u65e5\u671f\u3002 date \u4e09\u4e2a\u7cfb\u7edf\u7684\u9ed8\u8ba4\u65e5\u671f\u683c\u5f0f\u7565\u6709\u4e0d\u540c\u3002 # openSUSE Mon 24 Oct 2022 09 :28:06 AM CST # Ubuntu Mon Oct 24 01 :28:09 AM UTC 2022 # Rocky Mon Oct 24 09 :24:01 AM CST 2022 \u663e\u793a\u81ea1970-01-01 00:00:00 UTC\u5230\u5f53\u524d\u7684\u79d2\u6570\u3002 date +%s \u5c06\u4e0a\u4e00\u547d\u4ee4\u4e2d\u7684\u63cf\u8ff0\u8f6c\u6362\u4e3a\u7cfb\u7edf\u9ed8\u8ba4\u65e5\u671f\u683c\u5f0f\u3002 date -d @ ` date +%s ` date --date = @ '1666575347' \u663e\u793a\u786c\u4ef6\u65f6\u949f\u3002 hwclock \u4e5f\u88ab\u79f0\u4e3a Real Time Clock (RTC)\u3002 \u5728Rocky9\u4e2d\uff0c clock \u6709\u4e00\u4e2a\u8f6f\u8fde\u63a5\u6307\u5411 hwclock \uff1a /usr/sbin/clock -> hwclock \u3002\u5728openSUSE\u548cUbuntu\u4e2d\u53ea\u6709 hwclock \u3002 ll /usr/sbin/clock ll /usr/sbin/hwclock \u8bfb\u53d6RTC\u65f6\u95f4\u3002 sudo hwclock --get sudo hwclock -r \u6821\u51c6\u65f6\u95f4\uff1a -s, \u2013hctosys : \u4ee5RTC\u786c\u4ef6\u65f6\u95f4\u6765\u6821\u51c6\u7cfb\u7edf\u65f6\u95f4\u3002 -w, \u2013systohoc : \u4ee5\u7cfb\u7edf\u65f6\u95f4\u6765\u6821\u51c6RTC\u786c\u4ef6\u65f6\u95f4\u3002 \u663e\u793a\u5f53\u524d\u7cfb\u7edf\u65f6\u533a\u3002 ll /etc/localtime \u7cfb\u7edf\u53ef\u80fd\u4f1a\u8fd4\u56de\u4e0d\u540c\u7ed3\u679c\uff0c\u4f8b\u5982\uff1a /etc/localtime -> /usr/share/zoneinfo/Asia/Shanghai /etc/localtime -> /usr/share/zoneinfo/Etc/UTC \u663e\u793a\u5f53\u524d\u53ef\u4ee5\u65f6\u533a\u5217\u8868\u3002 timedatectl list-timezones timedatectl list-timezones | grep -i Asia \u4fee\u6539\u5f53\u524d\u7cfb\u7edf\u65f6\u533a\u3002 sudo timedatectl set-timezone Asia/Shanghai \u663e\u793a\u65e5\u5386\u3002 cal -y openSUSE\u548cRocky\u4e2d\uff0c\u4f7f\u7528 cal \u547d\u4ee4\u9700\u8981\u5b89\u88c5 util-linux \u5305\u3002 Ubuntu\u4e2d\uff0c\u4f7f\u7528 cal \u547d\u4ee4\u9700\u8981\u5b89\u88c5 ncal \u5305\u3002 sudo apt install ncal sudo zypper se util-linux sudo yum install util-linux","title":"3.9.\u65e5\u671f\u548c\u65f6\u95f4"},{"location":"linux/SRE/01-fundamentals/#310","text":"whoami \uff1a\u5f53\u524d\u767b\u5f55\u7528\u6237 who \uff1a\u7cfb\u7edf\u5f53\u524d\u6240\u6709\u7684\u767b\u5f55\u4f1a\u8bdd w \uff1a\u7cfb\u7edf\u5f53\u524d\u6240\u6709\u7684\u767b\u5f55\u4f1a\u8bdd\u53ca\u6240\u4f5c\u7684\u64cd\u4f5c \u63d0\u793a\uff1a MOTD is the abbreviation of \"Message Of The Day\", and it is used to display a message when a remote user login to the Linux Operating system using SSH. Linux administrators often need to display different messages on the login of the user, like displaying custom information about the server or any necessary information. \u7f16\u8f91\u6587\u4ef6 /etc/motd \u53ef\u4ee5\u81ea\u5b9a\u4e49\"Message Of The Day\"\u7684\u4fe1\u606f\u3002 Ubuntu 2204\u65b0\u5b89\u88c5\u540e\u6ca1\u6709\u8fd9\u4e2a\u6587\u4ef6\uff0c\u9700\u8981\u81ea\u5df1\u521b\u5efa\u3002 openSUSE\u65b0\u5b89\u88c5\u540e\u6709\u9884\u5b9a\u4e49\u7684\u4fe1\u606f\u3002 Rocky9 \u65b0\u5b89\u88c5\u540e\u6709\u8be5\u6587\u4ef6\uff0c\u7a7a\u767d\u6587\u4ef6\u65e0\u5185\u5bb9\u3002","title":"3.10.\u7528\u6237\u767b\u5f55\u4fe1\u606f"},{"location":"linux/SRE/01-fundamentals/#311","text":"screen \u5de5\u5177 screen -S (Create new screen session) screen -ls (list current screen sessions) screen -x (Attach to existing screeen session, sync between both) screen -r (Reattach existing screen session) tmux \u5de5\u5177 tmux \u662f\u6307 Terminal Multiplexer . \u5b89\u88c5 tmux \u5de5\u5177\u3002 # Rocky sudo yum install tmux # Ubuntu sudo apt install tmux # openSUSE sudo zypper in tmux \u5e38\u7528\u65b9\u6cd5\uff1a tmux new -s (Create new session) tmux detach (Detach current session) tmux ls (list current sessions) tmux attach -t (Reattach existing session) tmux switch -t (Switch to another session) tmux kill-session -t (Kill existing session) tmux list-keys (List all short keys) tmux list-commands (List commands and parameters) tmux info (List all sessions info) tmux split-window (Split window)","title":"3.11.\u4f1a\u8bdd\u7ba1\u7406\u5de5\u5177"},{"location":"linux/SRE/01-fundamentals/#312echo","text":"echo \u547d\u4ee4\u4e2d\u53ef\u4ee5\u8f93\u51fa\u53d8\u91cf\uff0c\u5982\u679c\u53d8\u91cf\u662f\u7528\u662f\u5355\u5f15\u53f7\u5f15\u8d77\u6765\uff0c\u8868\u793a\u8fd9\u4e2a\u53d8\u91cf\u4e0d\u7528IFS\u66ff\u6362\uff01\uff01 echo \"Home=$HOME\" \u7684\u8f93\u51fa\u7ed3\u679c\u662f Home=/home/vagrant echo 'Home=$HOME' \u7684\u8f93\u51fa\u7ed3\u679c\u662f Home=$HOME echo -e \u542f\u7528 \\ \u5b57\u7b26\u7684\u89e3\u91ca\u529f\u80fd\uff0c\u6bd4\u5982\uff1a echo -e \"a\\x0Ab\" \uff0c\u8f93\u51fa\u5b57\u7b26 a \u548c b \uff0c\u4e2d\u95f4 \\x0A \u4ee3\u8868\u5341\u516d\u8fdb\u5236 OA \uff08\u5373\u56de\u8f66\uff09 echo -e \"\\x4A \\x41 \\x4D \\x45 \\x53\" \uff0c\u8f93\u51fa\u7ed3\u679c\u662f J A M E S \u63d0\u793a\uff1a \u4ee5\u901a\u8fc7man 7 ascii\u6765\u67e5\u770b\u5404\u8fdb\u5236\u7684\u542b\u4e49\u3002 echo -e \u8f93\u51fa\u5e26\u989c\u8272\u5b57\u7b26\u3002 \u793a\u4f8b\uff1a echo -e \"\\e[35m \u7d2b\u8272 \\e[0m\" echo -e \"\\e[43m \u9ec4\u5e95 \\e[0m\" echo -e \"\\e[93m \u9ed1\u5e95\u9ec4\u5b57 \\e[0m\" \u53c2\u8003\u4fe1\u606f\uff1a \u5b57\u4f53\u989c\u8272\uff1a \\e[30m \uff1a \u9ed1\u8272 \\e[31m \uff1a \u7ea2\u8272 \\e[32m \uff1a \u7eff\u8272 \\e[33m \uff1a \u9ec4\u8272 \\e[34m \uff1a \u84dd\u8272 \\e[35m \uff1a \u7d2b\u8272 \\e[36m \uff1a \u9752\u8272 \\e[37m \uff1a \u767d\u8272 \\e[40m \uff1a \u9ed1\u5e95 \\e[41m \uff1a \u7ea2\u5e95 \\e[42m \uff1a \u7eff\u5e95 \\e[43m \uff1a \u9ec4\u5e95 \\e[44m \uff1a \u84dd\u5e95 \\e[45m \uff1a \u7d2b\u5e95 \\e[46m \uff1a \u9752\u5e95 \\e[47m \uff1a \u767d\u5e95 \u80cc\u666f\u989c\u8272\uff1a \\e[90m \uff1a \u9ed1\u5e95\u9ed1\u5b57 \\e[91m \uff1a \u9ed1\u5e95\u7ea2\u5b57 \\e[92m \uff1a \u9ed1\u5e95\u7eff\u5b57 \\e[93m \uff1a \u9ed1\u5e95\u9ec4\u5b57 \\e[94m \uff1a \u9ed1\u5e95\u84dd\u5b57 \\e[95m \uff1a \u9ed1\u5e95\u7d2b\u5b57 \\e[96m \uff1a \u9ed1\u5e95\u9752\u5b57 \\e[97m \uff1a \u9ed1\u5e95\u767d\u5b57 \u63a7\u5236\u5c5e\u6027\uff1a \\e[0m \u5173\u95ed\u6240\u6709\u5c5e\u6027 \\e[1m \u8bbe\u7f6e\u9ad8\u4eae\u5ea6 \\e[4m \u4e0b\u5212\u7ebf \\e[5m \u95ea\u70c1 \\e[7m \u53cd\u663e\uff0c\u649e\u8272\u663e\u793a\uff0c\u663e\u793a\u4e3a\u767d\u5b57\u9ed1\u5e95\uff0c\u6216\u8005\u663e\u793a\u4e3a\u9ed1\u5e95\u767d\u5b57 \\e[8m \u6d88\u5f71\uff0c\u5b57\u7b26\u989c\u8272\u5c06\u4f1a\u4e0e\u80cc\u666f\u989c\u8272\u76f8\u540c \\e[nA \u5149\u6807\u4e0a\u79fb n \u884c \\e[nB \u5149\u6807\u4e0b\u79fb n \u884c \\e[nC \u5149\u6807\u53f3\u79fb n \u884c \\e[nD \u5149\u6807\u5de6\u79fb n \u884c \\e[y;xH \u8bbe\u7f6e\u5149\u6807\u4f4d\u7f6e \\e[2J \u6e05\u5c4f \\e[K \u6e05\u9664\u4ece\u5149\u6807\u5230\u884c\u5c3e\u7684\u5185\u5bb9 \\e[s \u4fdd\u5b58\u5149\u6807\u4f4d\u7f6e \\e[u \u6062\u590d\u5149\u6807\u4f4d\u7f6e \\e[?25 \u9690\u85cf\u5149\u6807 \\e[?25h \u663e\u793a\u5149\u6807","title":"3.12.echo\u547d\u4ee4"},{"location":"linux/SRE/01-fundamentals/#313man","text":"\u5b89\u88c5\u5305\uff1a # openSUSE sudo zypper install man-pages man-pages-zh_CN man-pages-posix # Rocky sudo yum install man-pages # Ubuntu sudo apt install man-db manpages-posix manpages manpages-zh sudo apt install manpages-dev manpages-posix-dev \u66f4\u65b0mandb mandb \u67e5\u627e\u67d0\u4e2a\u547d\u4ee4\u7684man\u4fe1\u606f\uff0c\u4f8b\u5982\u67e5\u627e crontab \u547d\u4ee4\u7684\u4fe1\u606f\u3002 # \u7cbe\u786e\u67e5\u627e man -f crontab whatis crontab # \u6a21\u7cca\u67e5\u8be2 man -k crontab apropos crontab \u8f93\u51fa\u7ed3\u679c\u5982\u4e0b\uff1a crontab (5) - files used to schedule the execution of programs crontab (1) - maintains crontab files for individual users crontab (1p) - schedule periodic background work \u67e5\u627ecrontab\u7b2c5\u7ae0\u7684\u5185\u5bb9\uff0c\u5219\u53ef\u4ee5\u6267\u884c\uff1a man 5 crontab \u5e38\u7528\u5feb\u6377\u952e\u793a\u4f8bs\uff1a 1G : go to the 1 st line 10G : go to the 10 th line G : go to the end of the page /^SELinux : search the word SELinux /section OPTIONS : go to the section OPTIONS","title":"3.13.man\u547d\u4ee4"},{"location":"linux/SRE/01-fundamentals/#314tr","text":"tr \u547d\u4ee4\u53ef\u4ee5\u5bf9\u6765\u81ea\u6807\u51c6\u8f93\u5165\u7684\u5b57\u7b26\u8fdb\u884c\u66ff\u6362\u3001\u538b\u7f29\u548c\u5220\u9664\u3002\u5b83\u53ef\u4ee5\u5c06\u4e00\u7ec4\u5b57\u7b26\u53d8\u6210\u53e6\u4e00\u7ec4\u5b57\u7b26\u3002 \u683c\u5f0f\uff1a tr [OPTION]... SET1 [SET2] \u4e3e\u4f8b\uff1a # \u5c06\u8f93\u5165\u5b57\u7b26\u7531\u5927\u5199\u8f6c\u6362\u4e3a\u5c0f\u5199 $ echo \"HELLO WORLD\" | tr 'A-Z' 'a-z' hello world # \u5220\u9664\u51fa\u73b0\u7684\u6570\u5b57 $ echo \"HELLO 1234 WORLD 4567\" | tr -d '0-9' HELLO WORLD # \u4ece\u8f93\u5165\u6587\u672c\u4e2d\u5c06\u4e0d\u5728\u8865\u96c6\u4e2d\u7684\u6240\u6709\u5b57\u7b26\u5220\u9664\uff08\u53ea\u4fdd\u7559\u6570\u5b571\uff0c2\uff0c3\uff0c4\uff0c5\uff09 $ echo \"HELLO 1234 WORLD 4567\" | tr -d -c '1-5' 123445 # \u5c06\u8fde\u7eed\u91cd\u590d\u7684\u5b57\u7b26\u4ee5\u5355\u72ec\u4e00\u4e2a\u5b57\u7b26\u8868\u793a $ echo \"HELLOOO 1222235555555554\" | tr -s 'O215' HELLO 12354 # \u5220\u9664\u7531\u4e8eWindows\u6587\u4ef6\u9020\u6210\u7684'^M'\u5b57\u7b26 $ cat file.txt | tr -s '\\r' '\\n' > new.txt $ cat file.txt | tr -d '\\r' > new.txt # \u5c06\u6362\u884c\u7b26\u66ff\u6362\u6210\u5236\u8868\u7b26 $ cat file.txt | tr '\\n' '\\t' > new.txt # \u5c06\u5927\u5199\u5b57\u6bcd\u8f6c\u6362\u4e3a\u5c0f\u5199\u5b57\u6bcd $ echo \"HELLO 1234 WORLD 4567\" | tr '[:upper:]' '[:lower:]' hello 1234 world 4567","title":"3.14.tr\u547d\u4ee4"},{"location":"linux/SRE/01-fundamentals/#315tee","text":"tee \u547d\u4ee4\u57fa\u4e8e\u6807\u51c6\u8f93\u5165\u8bfb\u53d6\u6570\u636e\uff0c\u6807\u51c6\u8f93\u51fa\u6216\u6587\u4ef6\u5199\u5165\u6570\u636e\u3002 \u4e3e\u4f8b\uff1a # ping\u547d\u4ee4\u7684\u8f93\u51fa\uff0c\u4e0d\u4ec5\u8f93\u51fa\u5230\u5c4f\u5e55\uff0c\u4e5f\u540c\u65f6\u5199\u5165\u6587\u4ef6output.txt\u4e2d\uff08\u8986\u76d6\u5f0f\u5199\u5165\uff09\u3002 $ ping www.baidu.com | tee output.txt # ping\u547d\u4ee4\u7684\u8f93\u51fa\uff0c\u4e0d\u4ec5\u8f93\u51fa\u5230\u5c4f\u5e55\uff0c\u4e5f\u540c\u65f6\u5199\u5165\u6587\u4ef6output.txt\u4e2d\uff08\u8ffd\u52a0\u5f0f\u5199\u5165\uff09\u3002 $ ping www.baidu.com | tee -a output.txt # ping\u547d\u4ee4\u7684\u8f93\u51fa\uff0c\u4e0d\u4ec5\u8f93\u51fa\u5230\u5c4f\u5e55\uff0c\u4e5f\u540c\u65f6\u5199\u5165\u591a\u4e2a\u6587\u4ef6\u4e2d\uff08\u8986\u76d6\u5f0f\u5199\u5165\uff09\u3002 $ ping www.baidu.com | tee output1.txt output2.txt output3.txt # ls\u547d\u4ee4\u7684\u8f93\u51fa\u5199\u5165\u6587\u4ef6output.txt\u4e2d\uff0c\u5e76\u4f5c\u4e3awc\u547d\u4ee4\u7684\u8f93\u5165\u3002 $ ls *.txt | tee output.txt | wc -l 4 # cat output.txt f1.txt f2.txt output.txt test.txt \u6280\u5de7\uff1a \u5728vi\u4f7f\u7528\u4e2d\uff0c\u901a\u8fc7 tee \u547d\u4ee4\u63d0\u5347\u6587\u4ef6\u5199\u5165\u6743\u9650\u3002 \u6bd4\u5982\u975eroot\u7528\u6237\u6267\u884c vi /etc/hosts \uff0c\u5728vi\u4e2d\u4f7f\u7528 :w !sudo tee % \u53ef\u4ee5\u63d0\u9ad8\u6743\u9650\u4fdd\u5b58\u8fd9\u4e2a\u6587\u4ef6\u3002","title":"3.15.tee\u547d\u4ee4"},{"location":"linux/SRE/01-fundamentals/#316lang","text":"\u5b89\u88c5\u8bed\u8a00\u5305\u3002 # Ubuntu sudo apt install locales-all # Rocky sudo yum install glibc-langpack-zh.x86_64 # openSUSE sudo zypper install glibc-locale glibc-locale-32bit glibc-locale-base \u67e5\u770b\u5f53\u524d\u8bed\u8a00\u8bbe\u7f6e\uff1a echo $LANG locale -a locale -k LC_TIME localectl status localectl list-locales \u5168\u5c40locale\u914d\u7f6e(Global locale settings)\u3002 # openSUSE & Rocky sudo cat /etc/locale.conf # Ubuntu sudo cat /etc/default/locale \u4e34\u65f6\u4fee\u6539\u5f53\u524dsession\u7684locale\u3002 LANG = \"zh_CN.utf8\" \u6c38\u4e45\u4fee\u6539locale\u8bbe\u7f6e\u3002 sudo localectl set-locale LANG = zh_CN.utf8 \u4fee\u6539\u56de\u539f\u8bbe\u7f6e\u3002 sudo localectl set-locale LANG = en_US.utf8 Tips: Mac OS ssh\u767b\u9646Linux\u662f\u7ec8\u7aef\u63d0\u793a /usr/bin/manpath: can't set the locale; make sure $LC_* and $LANG are correct \u89e3\u51b3\u65b9\u6cd5\uff1a\u5728\u672c\u5730mac\u7535\u8111\u4e0a\u4fee\u6539/etc/ssh/ssh_config\u6216\u8005/etc/ssh/ssh_config\u6587\u4ef6\uff0c\u5220\u9664\u6389\u6216\u8005\u6ce8\u91ca\u6389\u8fd9\u4e00\u884c\u914d\u7f6e\u5185\u5bb9 # SendEnv LANG LC_* \u3002 \u5982\u679c\u4f7f\u7528\u7684\u662f Iterm2 \uff0c\u53ef\u4ee5\u6253\u5f00 iterm2 \u7684 preferences -> Profiles -> Terminal \u83dc\u5355\u91cc\u5173\u95ed Set locale variables automatically \u9009\u9879\u3002","title":"3.16.\u8bed\u8a00\u73af\u5883LANG"},{"location":"linux/SRE/01-fundamentals/#317","text":"\u7b26\u53f7 $ \u7684\u7528\u6cd5\uff1a $ \uff0c\u83b7\u53d6\u53d8\u96f6\u503c\u3002 x = 1 echo $x echo \" $x \" \u5efa\u8bae\u4f7f\u7528\"$x\"\uff0c\u4ee5\u907f\u514dshell\u7f16\u7a0b\u4e2d\u4ea7\u751f\u6b67\u4e49\u3002\u5982\u4e0b\u4f8b\uff1a s = \"this is a string\" echo $s echo \"this is a string\" \u6267\u884c [ $s == \"this is a string\" ] \u4f1a\u62a5\u9519\uff0c\u8fd9\u662f\u5b9e\u9645\u751f\u6210\u7684\u6bd4\u8f83\u5f0f this is a string == \"this is a string\" \u3002 \u6211\u4eec\u9884\u671f\u7684\u662f \"this is a string\" == \"this is a string\" \uff0c\u6240\u4ee5\u9700\u8981\u6539\u6210 [ \"$s\" == \"this is a string\" ] \u3002 $0 , $1 , $n , $# \uff1a \u751f\u6210\u4e00\u4e2a\u6d4b\u8bd5\u811a\u672c\u3002 echo 'echo $0 $1 $2 $#' > test.sh chmod 755 test.sh \u9a8c\u8bc1\u5404\u4e2a\u53c2\u6570\u4f4d\u7f6e\u3002 ./test.sh a b c d e \u8f93\u51fa\u7ed3\u679c\uff1a ./test.sh a b 5 \u7ed3\u8bba\uff1a $0 \u8f93\u51fa\u811a\u672c\u6587\u4ef6\u540d\uff1b $1 \u8f93\u51fa\u7b2c\u4e00\u4e2a\u53c2\u6570\uff1b $2 \u8f93\u51fa\u7b2c\u4e8c\u4e2a\u53c2\u6570\uff1b $# \u8f93\u51fa\u53c2\u6570\u4e2a\u6570\u3002 ${} ${} \u7528\u4e8e\u533a\u5206\u53d8\u91cf\u7684\u8fb9\u754c\u3002 \u4e0b\u9762\u4f8b\u5b50\u4e2d\uff0c $abc \u65e0\u7ed3\u679c\u8f93\u51fa\uff0c ${a}bc \u8f93\u51fa\u7ed3\u679c stringbc \uff0c\u901a\u8fc7{}\u6307\u5b9a\u4e86\u67d0\u4e2a\u5b57\u7b26\u5c5e\u4e8e\u53d8\u91cf\u3002 a = \"string\" echo ${ a } bc echo $abc ${#} ${#} \u662f\u8fd4\u56de\u53d8\u91cf\u503c\u7684\u957f\u5ea6\u3002 s = 'this is a string' echo \" $s \" echo \" ${# s } \" \u547d\u4ee4 echo \"${#s}\" \u8f93\u51fa\u7ed3\u679c\u662f\u5b57\u4e32 this is a string \u7684\u957f\u5ea6 16 \u3002 $? $? \u662f\u8fd4\u56de\u4e0a\u4e00\u547d\u4ee4\u662f\u5426\u6210\u529f\u7684\u72b6\u6001\uff0c 0 \u4ee3\u8868\u6210\u529f\uff0c\u975e\u96f6\u4ee3\u8868\u5931\u8d25\u3002 ls \u662f\u4e00\u4e2a\u547d\u4ee4\uff0c\u6240\u4ee5\u8fd4\u56de\u503c\u662f 0 \u3002 tom \u662f\u4e00\u4e2a\u4e0d\u5b58\u5728\u7684\u547d\u4ee4\uff0c\u5219\u8fd4\u56de 127 \u3002 ls echo $? tom echo $? $() $() \u7b49\u540c\u4e8e\u53cd\u5f15\u53f7\u3002 echo $(ls) \u7b49\u540c\u4e8e\u6267\u884c ls \u547d\u4ee4\u3002 $() \u7684\u5f0a\u7aef\u662f\uff0c\u4e0d\u662f\u6240\u6709\u7684\u7c7bunix\u7cfb\u7edf\u90fd\u652f\u6301\uff0c\u53cd\u5f15\u53f7\u662f\u80af\u5b9a\u652f\u6301\u7684\u3002 $() \u7684\u4f18\u52bf\u662f\u76f4\u89c2\uff0c\u5728\u8f6c\u79fb\u5904\u7406\u65f6\uff0c\u6bd4\u53cd\u5f15\u53f7\u76f4\u89c2\u5bb9\u6613\u4e9b\u3002 echo $( ls ) # test.sh echo $( cat $( ls )) # echo $0 $1 $2 $# \u4e0a\u8ff0\u5d4c\u5957\u683c\u5f0f\u4e2d\uff0cls\u547d\u4ee4\u7684\u8f93\u51fa\uff0c\u662fcat\u547d\u4ee4\u7684\u8f93\u5165\uff0c\u53ef\u4ee5\u8fdb\u884c\u591a\u5c42\u5d4c\u5957\uff0c\u5185\u5c42\u547d\u4ee4\u7684\u8f93\u51fa\u662f\u5916\u5c42\u547d\u4ee4\u7684\u8f93\u5165\u3002 $[] $[] \u662f\u8868\u8fbe\u5f0f\u8ba1\u7b97\u3002 echo $ [ 3 + 2 ] $- $- \u663e\u793ashell\u5f53\u524d\u6240\u4f7f\u7528\u7684\u9009\u9879\u3002 \u6267\u884c echo $- \uff0c\u8f93\u51fa\u7ed3\u679c himBHs \u3002himBH\u6bcf\u4e00\u4e2a\u5b57\u7b26\u662f\u4e00\u4e2ashell\u7684\u9009\u9879\u3002 $! $! \u83b7\u53d6\u6700\u540e\u4e00\u4e2a\u8fd0\u884c\u7684\u540e\u53f0\u8fdb\u7a0b\u7684pid\u3002 \u6bd4\u5982\u6267\u884c cat test.sh & \uff0c\u7ed3\u679c\u4e2d\u4f1a\u5305\u542b\u4e00\u4e2apid\u53f7\uff0c\u9a6c\u4e0a\u7740\u6267\u884c echo $! \uff0c\u5982\u679c2\u4e2a\u547d\u4ee4\u95f4\u9694\u4e4b\u95f4\u6ca1\u6709\u5176\u4ed6\u540e\u53f0\u8fdb\u7a0b\u6267\u884c\uff0c\u5219\u53ef\u4ee5\u5f97\u5230\u548c\u524d\u9762\u4e00\u81f4\u7684pid\u53f7\u3002 !$ !$ \u8fd4\u56de\u4e0a\u4e00\u6761\u547d\u4ee4\u7684\u6700\u540e\u4e00\u4e2a\u53c2\u6570\u3002 \u6267\u884c ./test.sh a b c iamhere \uff0c\u5f97\u5230\u7ed3\u679c ./test.sh a b 4 \u3002 \u6267\u884c echo !$ \uff0c\u5f97\u52302\u4e2a\u7ed3\u679c\uff0c echo iamhere \u548c iamhere \u3002 !! !! \u8f93\u51fa\u4e0a\u4e00\u6761\u547d\u4ee4\uff0c\u5e76\u6267\u884c\u3002 !! \u4f1a\u5148\u8f93\u51fa\u4e0a\u4e00\u6761\u547d\u4ee4 cat test.sh \uff0c\u7136\u540e\u518d\u6267\u884c\u8fd9\u6761\u547d\u4ee4\uff0c\u7b2c\u4e8c\u884c\u5373\u6267\u884c\u7ed3\u679c\u3002 [ vagrant@lizard:~ ] $ cat test.sh echo $0 $1 $2 $# [ vagrant@lizard:~ ] $ !! cat test.sh echo $0 $1 $2 $# $$ $$ \u8f93\u51fa\u5f53\u524d\u8fdb\u7a0b\u7684pid\u3002 echo $$ $@ & $* $@ \u548c $* \u662f\u5bf9\u4f20\u5165\u53c2\u6570\u7684\u4e0d\u540c\u4f53\u73b0\uff0c $@ \u662f\u4ee5\u53d8\u91cf\u5f62\u5f0f\u5f15\u7528\u4f20\u5165\u53c2\u6570\uff0c $* \u662f\u4ee5\u6570\u7ec4\u7684\u5f62\u5f0f\u5f15\u7528\u4f20\u5165\u53c2\u6570\u3002 \u521b\u5efa\u4e00\u4e2a\u6587\u4ef6 script.sh \u5305\u542b\u4e0b\u9762\u7684\u811a\u672c\u3002\u5e76\u6dfb\u52a0\u6267\u884c\u6743\u9650 chmod 755 script.sh \u3002 echo '$@\u4ee5\u53d8\u91cf\u65b9\u5f0f\u5f15\u7528\u4f20\u5165\u53c2\u6570\uff1a' for x in \" $@ \" do echo $x done echo '$*\u4ee5\u6570\u7ec4\u7684\u5f62\u5f0f\u5f15\u7528\u4f20\u5165\u53c2\u6570\uff1a' for x in \" $* \" do echo $x done \u8f93\u51fa\u7ed3\u679c\uff1a $@ \u4ee5\u53d8\u91cf\u65b9\u5f0f\u5f15\u7528\u4f20\u5165\u53c2\u6570\uff1a a b 3 5 d $* \u4ee5\u6570\u7ec4\u7684\u5f62\u5f0f\u5f15\u7528\u4f20\u5165\u53c2\u6570\uff1a a b 3 5 d","title":"3.17.\u7b26\u53f7$\u7528\u6cd5"},{"location":"linux/SRE/02-filesystem/","text":"\u7b2c\u4e8c\u7ae0 \u6587\u4ef6\u7cfb\u7edf \u00b6 \u6587\u4ef6\u7cfb\u7edf\u5c42\u6b21\u6807\u51c6\uff08Filesystem Hierarchy Standard, FHS\uff09\uff0c\u5b83\u662fLinux \u6807\u51c6\u5e93\uff08Linux Standards Base, LSB\uff09\u89c4\u8303\u7684\u4e00\u90e8\u5206\u3002 \u6839\u76ee\u5f55 / \u6307\u6587\u4ef6\u7cfb\u7edf\u6811\u7684\u6700\u9ad8\u5c42\u3002 \u6839\u5206\u533a\u5728\u7cfb\u7edf\u542f\u52a8\u65f6\u9996\u5148\u6302\u8f7d\u3002 \u7cfb\u7edf\u542f\u52a8\u65f6\u8fd0\u884c\u7684\u6240\u6709\u7a0b\u5e8f\u90fd\u5fc5\u987b\u5728\u6b64\u5206\u533a\u4e2d\u3002 1.\u4e3b\u8981\u76ee\u5f55 \u00b6 \u4ee5\u4e0b\u76ee\u5f55\u5fc5\u987b\u5728\u6839\u5206\u533a\u4e2d\uff1a /bin - \u7528\u6237\u57fa\u672c\u7a0b\u5e8f\u3002 \u5305\u542b\u672a\u6302\u8f7d\u5176\u4ed6\u6587\u4ef6\u7cfb\u7edf\u65f6\u6240\u9700\u7684\u53ef\u6267\u884c\u6587\u4ef6\u3002 \u4f8b\u5982\uff0c\u7cfb\u7edf\u542f\u52a8\u3001\u5904\u7406\u6587\u4ef6\u548c\u914d\u7f6e\u6240\u9700\u7684\u7a0b\u5e8f\u3002 \u4e0d\u80fd\u5173\u8054\u5230\u72ec\u7acb\u5206\u533a\uff0c\u64cd\u4f5c\u7cfb\u7edf\u542f\u52a8\u5373\u4f1a\u8c03\u7528\u7684\u7a0b\u5e8f\u3002 /bin/bash - bash \u811a\u672c\u5904\u7406 /bin/cat - \u663e\u793a\u6587\u4ef6\u5185\u5bb9 /bin/cp - \u62f7\u8d1d\u6587\u4ef6 /bin/dd - \u62f7\u8d1d\u6587\u4ef6\uff08\u57fa\u4e8e\u5b57\u8282byte\uff09 /bin/gzip - \u538b\u7f29\u6587\u4ef6 /bin/mount - \u6302\u8f7d\u6587\u4ef6\u7cfb\u7edf /bin/rm - \u5220\u9664\u6587\u4ef6 /bin/vi - \u6587\u4ef6\u7f16\u8f91 /sbin - \u7cfb\u7edf\u57fa\u672c\u7a0b\u5e8f\u3002 \u5305\u542b\u57fa\u672c\u7cfb\u7edf\u7ba1\u7406\u7684\u7a0b\u5e8f\u3002 \u9ed8\u8ba4\u662froot\u7528\u6237\u6709\u6743\u9650\u6267\u884c\uff0c\u56e0\u6b64\u5b83\u4e0d\u5728\u5e38\u89c4\u7528\u6237\u8def\u5f84\u4e2d\u3002 \u4e0d\u80fd\u5173\u8054\u5230\u72ec\u7acb\u5206\u533a\uff0c\u64cd\u4f5c\u7cfb\u7edf\u542f\u52a8\u5373\u4f1a\u8c03\u7528\u7684\u7a0b\u5e8f \u4e00\u4e9b\u91cd\u8981\u7ba1\u7406\u7a0b\u5e8f\uff1a /sbin/fdisk* - \u7ba1\u7406\u786c\u76d8\u5206\u533a /sbin/fsck* - \u6587\u4ef6\u7cfb\u7edf\u68c0\u67e5\u3002\u4e0d\u80fd\u5728\u8fd0\u884c\u7684\u7cfb\u7edf\u4e0a\u9762\u76f4\u63a5\u6267\u884c fsck \uff0c\u635f\u574f\u6839\u6587\u4ef6\u7cfb\u7edf\uff0c\u6267\u884c\u524d\u9700\u8981 umount \u3002 /sbin/mkfs - \u521b\u5efa\u6587\u4ef6\u7cfb\u7edf /sbin/shutdown - \u5173\u95ed\u7cfb\u7edf /dev - \u8bbe\u5907\u6587\u4ef6 \u4ee5\u592a\u7f51\u5361\u662f\u5185\u6838\u6a21\u5757\uff0c\u5176\u4ed6\u786c\u4ef6\u90fd\u4ee5\u8bbe\u5907dev\u7684\u65b9\u5f0f\u5c55\u73b0\u3002 \u5e94\u7528\u7a0b\u5e8f\u8bfb\u53d6\u548c\u5199\u5165\u8fd9\u4e9b\u6587\u4ef6\u4ee5\u64cd\u4f5c\u4f7f\u7528\u786c\u4ef6\u7ec4\u4ef6\u3002 \u4e24\u79cd\u7c7b\u578b\u8bbe\u5907\u6587\u4ef6\uff1a \u5b57\u7b26\u8bbe\u5907\uff08Character-oriented\uff09\u2013 \u5e8f\u5217\u8bbe\u5907\uff08\u6253\u5370\u673a\uff0c\u78c1\u5e26\u673a\uff0c\u9f20\u6807\u7b49\uff09 \u5757\u8bbe\u5907\uff08Block-oriented\uff09\u2013 \u786c\u76d8\uff0cDVD\u7b49 \u4e0e\u8bbe\u5907\u9a71\u52a8\u7a0b\u5e8f\u7684\u8fde\u63a5\u901a\u8fc7\u5185\u6838\u4e2d\u79f0\u4e3a\u4e3b\u8bbe\u5907\u53f7\u7684\u901a\u9053\u5b9e\u73b0\u3002 \u8fc7\u53bb\uff0c\u8fd9\u4e9b\u6587\u4ef6\u662f\u4f7f\u7528 mknod \u547d\u4ee4\u624b\u52a8\u521b\u5efa\u7684\u3002 \u73b0\u5728\u5f53\u5185\u6838\u53d1\u73b0\u8bbe\u5907\u65f6\uff0c\u5b83\u4eec\u4f1a\u7531 udev \u81ea\u52a8\u521b\u5efa\u3002 \u4e00\u4e9b\u91cd\u8981\u7684\u8bbe\u5907\u6587\u4ef6\uff1a Null\u8bbe\u5907: - /dev/null Zero\u8bbe\u5907: - /dev/zero \u7cfb\u7edf\u7ec8\u7aef: - /dev/console \u865a\u62df\u7ec8\u7aef: - /dev/tty1 \u4e32\u884c\u7aef\u53e3 - /dev/ttyS0 \u5e76\u884c\u7aef\u53e3: - /dev/lp0 \u8f6f\u76d8\u9a71\u52a8\u5668: - /dev/fd0 \u786c\u76d8\u9a71\u52a8\u5668: - /dev/sda \u786c\u76d8\u5206\u533a: - /dev/sda1 CD-ROM\u9a71\u52a8\u5668: - /dev/scd0 /etc - \u914d\u7f6e\u6587\u4ef6 \u5b58\u653e\u7cfb\u7edf\u548c\u670d\u52a1\u7684\u914d\u7f6e\u6587\u4ef6\u3002 \u5927\u90e8\u5206\u90fd\u662fASCII\u6587\u4ef6 \u666e\u901a\u7528\u6237\u53ef\u4ee5\u9ed8\u8ba4\u8bfb\u53d6\u5176\u4e2d\u7684\u5927\u90e8\u5206\u5185\u5bb9\u3002 \u8fd9\u4f1a\u5e26\u6765\u4e00\u4e2a\u6f5c\u5728\u7684\u5168\u95ee\u9898\uff0c\u56e0\u4e3a\u5176\u4e2d\u4e00\u4e9b\u6587\u4ef6\u5305\u542b\u5bc6\u7801\uff0c\u56e0\u6b64\u91cd\u8981\u7684\u662f\u8981\u786e\u4fdd\u8fd9\u4e9b\u6587\u4ef6\u53ea\u80fd\u7531root\u7528\u6237\u8bfb\u53d6\u3002 \u6839\u636eFHS\u6807\u51c6\uff0c\u6b64\u5904\u4e0d\u80fd\u653e\u7f6e\u4efb\u4f55\u53ef\u6267\u884c\u6587\u4ef6\uff0c\u4f46\u5b50\u76ee\u5f55\u53ef\u80fd\u5305\u542bshell\u811a\u672c\u3002 \u51e0\u4e4e\u6bcf\u4e2a\u5df2\u5b89\u88c5\u7684\u670d\u52a1\u5728 /etc \u6216\u5176\u5b50\u76ee\u5f55\u4e2d\u81f3\u5c11\u6709\u4e00\u4e2a\u914d\u7f6e\u6587\u4ef6\u3002 \u4e00\u4e9b\u91cd\u8981\u7684\u914d\u7f6e\u6587\u4ef6: /etc/os-release - \u7cfb\u7edf\u7248\u672c\u4fe1\u606f /etc/DIR_COLORS - ls \u547d\u4ee4\u4e2d\u7684\u989c\u8272\u914d\u7f6e\u4fe1\u606f\uff08openSUSE\u548cRocky\uff09 /etc/fstab - \u914d\u7f6e\u8981\u6302\u8f7d\u7684\u6587\u4ef6\u7cfb\u7edf /etc/profile - Shell\u767b\u5f55\u811a\u672c /etc/passwd - \u7528\u6237\u4fe1\u606f\u96c6\u5408\uff08\u4e0d\u542b\u5bc6\u7801\uff09 /etc/shadow - \u5bc6\u7801\u548c\u76f8\u5173\u4fe1\u606f /etc/group - \u7528\u6237\u7ec4\u4fe1\u606f\u96c6\u5408 /etc/cups/* - \u7528\u4e8eCUPS\u6253\u5370\u7cfb\u7edf\uff08CUPS=Common UNIX Printing System\uff09 /etc/hosts - \u4e3b\u673a\u540d\u673a\u5668IP\u5730\u5740 /etc/motd - \u767b\u5f55\u540e\u663e\u793a\u7684\u6b22\u8fce\u4fe1\u606f /etc/issue - \u767b\u5f55\u524d\u663e\u793a\u7684\u6b22\u8fce\u4fe1\u606f /etc/sysconfig/* - \u7cfb\u7edf\u914d\u7f6e\u6587\u4ef6 /lib - \u5e93\uff08Libraries\uff09 \u8bb8\u591a\u7a0b\u5e8f\u90fd\u5177\u6709\u4e00\u4e9b\u901a\u7528\u529f\u80fd\u3002 \u8fd9\u4e9b\u901a\u7528\u529f\u80fd\u53ef\u4ee5\u4fdd\u5b58\u5728\u5171\u4eab\u5e93\u4e2d\u3002 \u5171\u4eab\u5e93\u4e2d\u6587\u4ef6\u7684\u6269\u5c55\u540d\u662f .so \u3002 \u76ee\u5f55 /lib \u5305\u542b\u7684\u5171\u4eab\u5e93\u6587\u4ef6\u4e3b\u8981\u662f\u88ab /bin \u548c /sbin \u76ee\u5f55\u5305\u542b\u7684\u7a0b\u5e8f\u6240\u8c03\u7528\u3002 \u76ee\u5f55 /lib \u7684\u5b50\u76ee\u5f55\u5305\u542b\u4e00\u4e9b\u989d\u5916\u9700\u8981\u7684\u5171\u4eab\u5e93\u3002 \u5185\u6838\u6a21\u5757\u5b58\u50a8\u5728\u76ee\u5f55 /lib/modules \u3002 /lib64 - 64\u4f4d\u5171\u4eab\u5e93\uff0864-Bit Libraries\uff09\uff0c\u7c7b\u4f3c\u76ee\u5f55 /lib \u3002 \u8fd9\u4e2a\u76ee\u5f55\u56e0\u7cfb\u7edf\u67b6\u6784\u4e0d\u540c\u800c\u4e0d\u540c\u3002 \u4e00\u4e9b\u7cfb\u7edf\u652f\u6301\u4e0d\u540c\u7684\u4e8c\u8fdb\u5236\u683c\u5f0f\u5e76\u4fdd\u7559\u540c\u4e00\u4e2a\u5171\u4eab\u5e93\u7684\u4e0d\u540c\u7248\u672c\u3002 /usr - \u5305\u542b\u5e94\u7528\u7a0b\u5e8f\u3001\u56fe\u5f62\u754c\u9762\u6587\u4ef6\u3001\u5e93\u3001\u672c\u5730\u7a0b\u5e8f\u3001\u6587\u6863\u7b49\u3002 /usr \u5373 Unix System Resources. \u4f8b\u5982\uff1a /usr/X11R6/ - X Window \u7cfb\u7edf\u6587\u4ef6 /usr/bin/ - \u51e0\u4e4e\u5305\u542b\u6240\u6709\u53ef\u6267\u884c\u6587\u4ef6 /usr/lib/ - \u5305\u542b\u5e93\u548c\u5e94\u7528\u7a0b\u5e8f /usr/lib64/ - \u5305\u542b64\u4f4d\u5e93\u548c\u5e94\u7528\u7a0b\u5e8f /usr/include/ - \u5305\u542bC\u7a0b\u5e8f\u7684\u5934\u6587\u4ef6\uff08head file\uff09 /usr/local/ - \u5305\u542b\u672c\u5730\u5b89\u88c5\u7a0b\u5e8f\u3002\u8fd9\u4e2a\u76ee\u5f55\u4e0b\u7684\u5185\u5bb9\u4e0d\u4f1a\u88ab\u7cfb\u7edf\u5347\u7ea7\u6240\u8986\u76d6\u3002\u4e0b\u97623\u4e2a\u76ee\u5f55\u5728\u521d\u59cb\u5b89\u88c5\u540e\u662f\u7a7a\u7684\u3002 /usr/local/bin - /usr/local/sbin - /usr/local/lib - /usr/sbin/ - \u7cfb\u7edf\u7ba1\u7406\u7a0b\u5e8f /usr/src/ - \u5185\u6838\u548c\u5e94\u7528\u7a0b\u5e8f\u7684\u6e90\u4ee3\u7801 /usr/src/linux - /usr/share/ - \u7ed3\u6784\u5316\u72ec\u7acb\u6570\u636e /usr/share/doc/ - \u6587\u6863 /usr/share/man/ - man \u547d\u4ee4\u4f7f\u7528\u7684\u5185\u5bb9 /opt - \u7b2c\u4e09\u65b9\u5e94\u7528\u7a0b\u5e8f\u76ee\u5f55 \u5404\u53d1\u884c\u7248\u5305\u542b\u7684\u5e94\u7528\u7a0b\u5e8f\u4e00\u822c\u5b58\u50a8\u5728\u76ee\u5f55 /usr/lib/ \u3002 \u5404\u53d1\u884c\u7248\u53ef\u9009\u7a0b\u5e8f\uff0c\u6216\u7b2c\u4e09\u65b9\u5e94\u7528\u7a0b\u5e8f\u5219\u5b58\u50a8\u5728\u76ee\u5f55 /opt \u3002 \u5728\u5b89\u88c5\u65f6\uff0c\u4f1a\u4e3a\u6bcf\u4e2a\u5e94\u7528\u7a0b\u5e8f\u7684\u6587\u4ef6\u521b\u5efa\u4e00\u4e2a\u76ee\u5f55\uff0c\u5176\u4e2d\u5305\u542b\u5e94\u7528\u7a0b\u5e8f\u7684\u540d\u79f0\u3002\u6bd4\u5982\uff1a /opt/novell - /boot - \u5f15\u5bfc\u76ee\u5f55 /boot/grub2 - \u5305\u542bGRUB2\u7684\u9759\u6001\u5f15\u5bfc\u52a0\u8f7d\u7a0b\u5e8f\u6587\u4ef6\uff08GRUB = Grand Unified Boot Loader\uff09\u3002 \u5305\u542b\u4ee5\u94fe\u63a5 vmlinuz \u548c initrd \u6807\u8bc6\u7684\u5185\u6838\u548c initrd \u6587\u4ef6\u3002 /root - \u7ba1\u7406\u5458\u7684\u4e3b\u76ee\u5f55\uff08home directory\uff09\u3002 root \u7528\u6237\u7684\u4e3b\u76ee\u5f55\u3002\u5176\u4ed6\u7528\u6237\u7684\u4e3b\u76ee\u5f55\u662f\u5728\u76ee\u5f55 /home \u4e0b\u3002 root \u7528\u6237\u7684\u767b\u5f55\u73af\u5883\u914d\u7f6e\u4fdd\u5b58\u81f3 /root \u5206\u533a\u4e2d\u3002 /home - \u7528\u6237\u4e3b\u76ee\u5f55 \u6bcf\u4e2a\u7cfb\u7edf\u7528\u6237\u90fd\u6709\u4e00\u4e2a\u5206\u914d\u7684\u6587\u4ef6\u533a\u57df\uff0c\u8be5\u6587\u4ef6\u533a\u57df\u5728\u767b\u5f55\u540e\u6210\u4e3a\u5f53\u524d\u5de5\u4f5c\u76ee\u5f55\u3002 \u9ed8\u8ba4\u60c5\u51b5\u4e0b\uff0c\u5b83\u4eec\u5b58\u5728\u4e8e /home \u4e2d\u3002 /home \u4e2d\u7684\u6587\u4ef6\u548c\u76ee\u5f55\u53ef\u4ee5\u4f4d\u4e8e\u5355\u72ec\u7684\u5206\u533a\u4e2d\uff0c\u4e5f\u53ef\u4ee5\u4f4d\u4e8e\u7f51\u7edc\u4e0a\u7684\u53e6\u4e00\u53f0\u8ba1\u7b97\u673a\u4e0a\u3002 \u7528\u6237\u914d\u7f6e\u4fe1\u606f\u548c\u914d\u7f6e\u6587\u4ef6\uff08user profile and configuration files\uff09\u4e3b\u8981\u6709\uff1a .profile - \u7528\u6237\u79c1\u6709\u767b\u5f55\u811a\u672c .bashrc - bash \u7684\u914d\u7f6e\u6587\u4ef6 .bash_history - bash \u73af\u5883\u4e0b\u4fdd\u6301\u547d\u4ee4\u5386\u53f2\u8bb0\u5f55 run - \u5e94\u7528\u7a0b\u5e8f\u72b6\u6001\u6587\u4ef6 \u4e3a\u5e94\u7528\u7a0b\u5e8f\u63d0\u4f9b\u4e86\u4e00\u4e2a\u6807\u51c6\u4f4d\u7f6e\u6765\u5b58\u50a8\u5b83\u4eec\u9700\u8981\u7684\u4e34\u65f6\u6587\u4ef6\uff0c\u4f8b\u5982\u5957\u63a5\u5b57\u548c\u8fdb\u7a0bID\u3002 \u8fd9\u4e9b\u6587\u4ef6\u4e0d\u80fd\u5b58\u50a8\u5728 /tmp \u4e2d\uff0c\u56e0\u4e3a /tmp \u4e2d\u7684\u6587\u4ef6\u53ef\u80fd\u4f1a\u88ab\u5220\u9664\u3002 /run/media//* - \u53ef\u79fb\u52a8\u8bbe\u5907\u7684\u6302\u8f7d\u70b9\uff0c\u4f8b\u5982\uff1a /run/media/media_name/ /run/media/cdrom/ - /run/media/dvd/ - /run/media/usbdisk/ - /mnt - \u6587\u4ef6\u7cfb\u7edf\u4e34\u65f6\u6302\u8f7d\u70b9 \u7528\u4e8e\u6302\u8f7d\u4e34\u65f6\u4f7f\u7528\u7684\u6587\u4ef6\u7cfb\u7edf\u7684\u76ee\u5f55\u3002 \u6587\u4ef6\u7cfb\u7edf\u4f7f\u7528 mount \u547d\u4ee4\u6302\u8f7d\uff0c\u4f7f\u7528 umount \u547d\u4ee4\u5220\u9664\u3002 \u5b50\u76ee\u5f55\u9ed8\u8ba4\u4e0d\u5b58\u5728\uff0c\u4e5f\u4e0d\u4f1a\u81ea\u52a8\u521b\u5efa\u3002 /srv - \u670d\u52a1\u6570\u636e\u76ee\u5f55 \u5b58\u653e\u5404\u79cd\u670d\u52a1\u7684\u6570\u636e\uff0c\u6bd4\u5982\uff1a /srv/www - \u7528\u4e8e\u5b58\u653e Apache Web Server \u7684\u6570\u636e /srv/ftp - \u7528\u4e8e\u5b58\u653e FTP server \u7684\u6570\u636e /var - \u53ef\u53d8\u6587\u4ef6\uff08Variable Files\uff09 \u5728\u7cfb\u7edf\u8fd0\u884c\u8fc7\u7a0b\u4e2d\u4f1a\u88ab\u4fee\u6539\u7684\u6587\u4ef6 Important subdirectories: /var/lib/ - \u53ef\u53d8\u5e93\u6587\u4ef6\uff0c\u5e94\u7528\u7a0b\u5e8f\u72b6\u6001\u4fe1\u606f\u6570\u636e /var/log/ - \u65e5\u5fd7\u6587\u4ef6 /var/run/ - \u8fd0\u884c\u4e2d\u7684\u8fdb\u7a0b\u7684\u4fe1\u606f /var/lock/ - \u591a\u7528\u6237\u8bbf\u95ee\u65f6\u7684\u9501\u6587\u4ef6 /var/cache - \u5e94\u7528\u7a0b\u5e8f\u7f13\u5b58\u6570\u636e\u76ee\u5f55 /var/opt - \u4e13\u4e3a /opt \u4e0b\u7684\u5e94\u7528\u7a0b\u5e8f\u5b58\u50a8\u53ef\u53d8\u6570\u636e /var/mail - /var/spool/ - \u5e94\u7528\u7a0b\u5e8f\u6570\u636e\u6c60\uff0c\u6bd4\u5982\uff1a\u6253\u5370\u673a\uff0c\u90ae\u4ef6 /var/spool/mail - /var/spool/cron - /tmp - \u4e34\u65f6\u6587\u4ef6 \u7a0b\u5e8f\u5728\u8fd0\u884c\u65f6\u521b\u5efa\u4e34\u65f6\u6587\u4ef6\u7684\u4f4d\u7f6e /proc - \u8fdb\u7a0b\u6587\u4ef6 \u865a\u62df\u6587\u4ef6\u7cfb\u7edf\uff0c\u4e0d\u5360\u7a7a\u95f4\uff0c\u5927\u5c0f\u59cb\u7ec8\u4e3a\u96f6\uff0c\u4fdd\u6301\u5f53\u524d\u8fdb\u7a0b\u7684\u72b6\u6001\u4fe1\u606f \u5305\u542b\u6709\u5173\u5404\u4e2a\u8fdb\u7a0b\u7684\u4fe1\u606f\u7684\u76ee\u5f55\uff0c\u6839\u636e\u8fdb\u7a0b\u7684 PID \u53f7\u547d\u540d \u6709\u4e9b\u503c\u53ef\u4ee5\u4e34\u65f6\u5728\u7ebf\u66f4\u6539\u751f\u6548\uff0c\u4f46\u91cd\u542f\u540e\u4e22\u5931 /proc/cpuinfo/ - Processor information /proc/dma/ - Use of DMA ports /proc/interrupts/ - Use of interrupts /proc/ioports/ - Use of I/O ports /proc/filesystems/ - File system formats the kernel knows /proc/modules/ - Active modules /proc/mounts/ - Mounted file systems /proc/net/* - Network information and statistics /proc/partitions/ - Existing partitions /proc/bus/pci/ - Connected PCI devices /proc/bus/scsi/ - Connected SCSI devices /proc/sys/* - System and kernel information /proc/version - Kernel version /sys - \u7cfb\u7edf\u4fe1\u606f\u76ee\u5f55 \u865a\u62df\u6587\u4ef6\u7cfb\u7edf\uff0c\u4ec5\u5b58\u5728\u4e8e\u5185\u5b58\u4e2d\uff0c\u6587\u4ef6\u5927\u5c0f\u4e3a\u96f6\u3002\u4e3b\u8981\u63d0\u4f9b\u5982\u4e0b\u4fe1\u606f\uff1a \u786c\u4ef6\u603b\u7ebf\uff08hardware buses\uff09 \u786c\u4ef6\u8bbe\u5907\uff08hardware devices\uff09 \u6709\u6e90\u8bbe\u5907\uff08active devices\uff09 \u9a71\u52a8\u7a0b\u5e8f\uff08drivers\uff09 2.\u6587\u4ef6\u64cd\u4f5c\u547d\u4ee4 \u00b6 2.1.\u663e\u793a\u5f53\u524d\u5de5\u4f5c\u76ee\u5f55 \u00b6 pwd\u547d\u4ee4\uff08print working directory\uff09: -L: \u663e\u793a\u94fe\u63a5\u8def\u5f84 -P\uff1a\u663e\u793a\u771f\u5b9e\u7269\u7406\u8def\u5f84 2.2.\u76f8\u5bf9\u548c\u7edd\u5bf9\u8def\u5f84 \u00b6 \u5bf9\u4e8e\u7edd\u5bf9\u8def\u5f84 /etc/firewalld/policies \uff0c\u53ef\u4ee5\u901a\u8fc7\u4e0b\u9762\u547d\u4ee4\u5f97\u5230\u8be5\u8def\u5f84\u7684\u57fa\u540d policies \u548c\u76ee\u5f55\u540d /etc/firewalld \u3002 basename /etc/firewalld/policies dirname /etc/firewalld/policies 2.3.\u66f4\u6539\u76ee\u5f55 \u00b6 . \u6307\u5f53\u524d\u76ee\u5f55\uff0c\u5373 pwd \u547d\u4ee4\u6240\u8fd4\u56de\u7684\u76ee\u5f55\u3002 .. \u6307\u5f53\u524d\u76ee\u5f55\u7684\u4e0a\u4e00\u7ea7\u76ee\u5f55\uff0c\u53ca\u5f53\u524d\u76ee\u5f55\u7684\u7236\u76ee\u5f55\u3002 \u5207\u6362\u81f3\u7236\u76ee\u5f55\uff1a cd .. \u5207\u6362\u81f3\u5f53\u524d\u7528\u6237\u4e3b\u76ee\u5f55\uff1a cd ~ \u5207\u6362\u81f3\u4e0a\u6b21\u5de5\u4f5c\u76ee\u5f55\uff1a cd - echo $PWD \uff1a\u5f53\u524d\u5de5\u4f5c\u76ee\u5f55 echo $OLDPWD \uff1a\u4e0a\u6b21\u5de5\u4f5c\u76ee\u5f55 2.4.\u5217\u51fa\u76ee\u5f55\u5185\u5bb9 \u00b6 ls \u547d\u4ee4\uff1a -a \u663e\u793a\u6240\u6709\u6587\u4ef6\u53ca\u76ee\u5f55 (. \u5f00\u5934\u7684\u9690\u85cf\u6587\u4ef6\u4e5f\u4f1a\u5217\u51fa) -A \u540c -a \uff0c\u4f46\u4e0d\u5217\u51fa . (\u76ee\u524d\u76ee\u5f55) \u53ca .. (\u7236\u76ee\u5f55) -l \u9664\u6587\u4ef6\u540d\u79f0\u5916\uff0c\u4ea6\u5c06\u6587\u4ef6\u578b\u6001\u3001\u6743\u9650\u3001\u62e5\u6709\u8005\u3001\u6587\u4ef6\u5927\u5c0f\u7b49\u8d44\u8baf\u8be6\u7ec6\u5217\u51fa -r \u5c06\u6587\u4ef6\u4ee5\u76f8\u53cd\u6b21\u5e8f\u663e\u793a(\u539f\u5b9a\u4f9d\u82f1\u6587\u5b57\u6bcd\u6b21\u5e8f) -t \u5c06\u6587\u4ef6\u4f9d\u5efa\u7acb\u65f6\u95f4\u4e4b\u5148\u540e\u6b21\u5e8f\u5217\u51fa -F \u5728\u5217\u51fa\u7684\u6587\u4ef6\u540d\u79f0\u540e\u52a0\u4e00\u7b26\u53f7\uff1b\u4f8b\u5982\u53ef\u6267\u884c\u6863\u5219\u52a0 \"*\", \u76ee\u5f55\u5219\u52a0 \"/\" -R \u9012\u5f52\u5217\u51fa\u5b50\u76ee\u5f55 -S \u6309\u6587\u4ef6\u5927\u5c0f\u6392\u5e8f\uff0c\u4ece\u5927\u5230\u5c0f -1 \u6309\u4e00\u4e2a\u6587\u4ef6\u4e00\u884c\u5217\u51fa -t \u6309\u6587\u4ef6\u65f6\u95f4\u6392\u5e8f\uff0c\u6700\u65b0\u7684\u5728\u524d -U \u4e0d\u6392\u5e8f\u8f93\u51fa\uff0c\u6309\u76ee\u5f55\u5b58\u653e\u987a\u5e8f\u5217\u51fa -u \u914d\u5408 -lt \uff0c\u6309\u8bbf\u95ee\u65f6\u95f4\u6392\u5e8f\u5e76\u663e\u793a\uff1b\u914d\u5408 -l \uff0c\u663e\u793a\u8bbf\u95ee\u65f6\u95f4\u5e76\u6309\u540d\u79f0\u6392\u5e8f\uff1b \u5426\u5219\u6309\u8bbf\u95ee\u65f6\u95f4\u6392\u5e8f\uff0c\u6700\u65b0\u7684\u5728\u524d -X \u6309\u6587\u4ef6\u6269\u5c55\u540d\u5b57\u6bcd\u987a\u5e8f\u6392\u5e8f\u8f93\u51fa -F \u5bf9\u4e0d\u540c\u7c7b\u578b\u6587\u4ef6\u663e\u793a\u65f6\u9644\u52a0\u4e0d\u540c\u7684\u7b26\u53f7\uff0c * / = > @ | \u4e4b\u4e00 ls \u547d\u4ee4\u67e5\u770b\u4e0d\u540c\u6587\u4ef6\u662f\u7684\u989c\u8272\uff0c\u7531 /etc/DIR_COLORS \u548c\u53d8\u91cf @LS_COLORS \u5b9a\u4e49\u3002 2.5.\u6587\u4ef6\u72b6\u6001stat \u00b6 \u6bcf\u4e2a\u6587\u4ef6\u6709\u4e09\u4e2a\u65f6\u95f4\u6233\uff1a \u8bbf\u95ee\u65f6\u95f4 Access Time atime : \u8bfb\u53d6\u6587\u4ef6\u5185\u5bb9\u3002 \u4fee\u6539\u65f6\u95f4 Modify Time mtime : \u6539\u53d8\u6587\u4ef6\u5185\u5bb9\uff08\u6570\u636e\uff09\u3002 \u6539\u53d8\u65f6\u95f4 Change Time ctime : \u5143\u6570\u636e\u53d1\u751f\u6539\u53d8\u3002 \u8bfb\u53d6\u4e09\u4e2a\u65f6\u95f4\u6233\u7684\u547d\u4ee4 stat \uff1a stat /etc/fstab \u8f93\u51fa\u7ed3\u679c\uff1a File: /etc/fstab Size: 927 Blocks: 8 IO Block: 4096 regular file Device: 30h/48d Inode: 263 Links: 1 Access: (0644/-rw-r--r--) Uid: ( 0/ root) Gid: ( 0/ root) Access: 2022-10-31 10:26:34.987466959 +0800 Modify: 2022-06-24 14:50:24.387992912 +0800 Change: 2022-06-24 14:50:24.387992912 +0800 Birth: 2022-06-24 14:50:23.755992937 +0800 2.6.\u786e\u5b9a\u6587\u4ef6\u7c7b\u578b \u00b6 \u547d\u4ee4 file \u68c0\u67e5\u6587\u4ef6\u7c7b\u578b\u3002 -b \uff1a\u5217\u51fa\u8fa8\u8bc6\u7ed3\u679c\u65f6\uff0c\u4e0d\u663e\u793a\u6587\u4ef6\u540d\u79f0\u3002 -c \uff1a\u8be6\u7ec6\u663e\u793a\u6307\u4ee4\u6267\u884c\u8fc7\u7a0b\uff0c\u4fbf\u4e8e\u6392\u9519\u6216\u5206\u6790\u7a0b\u5e8f\u6267\u884c\u7684\u60c5\u5f62\u3002 -f <\u540d\u79f0\u6587\u4ef6> \uff1a\u6307\u5b9a\u540d\u79f0\u6587\u4ef6\uff0c\u5176\u5185\u5bb9\u6709\u4e00\u4e2a\u6216\u591a\u4e2a\u6587\u4ef6\u540d\u79f0\u65f6\uff0c\u8ba9file\u4f9d\u5e8f\u8fa8\u8bc6\u8fd9\u4e9b\u6587\u4ef6\uff0c\u683c\u5f0f\u4e3a\u6bcf\u5217\u4e00\u4e2a\u6587\u4ef6\u540d\u79f0\u3002 -L \uff1a \u76f4\u63a5\u663e\u793a\u7b26\u53f7\u8fde\u63a5\u6240\u6307\u5411\u7684\u6587\u4ef6\u7684\u7c7b\u522b\u3002 -v \uff1a \u663e\u793a\u7248\u672c\u4fe1\u606f\u3002 -z \uff1a \u5c1d\u8bd5\u53bb\u89e3\u8bfb\u538b\u7f29\u6587\u4ef6\u7684\u5185\u5bb9\u3002 \u7f16\u8f91\u6587\u4ef6 list.txt \u5305\u542b\u4e00\u4e0b\u5185\u5bb9\uff1a /etc/ /bin /etc/issue \u8fd0\u884c\u547d\u4ee4 file -f list.txt \uff0c\u7ed3\u679c\u5982\u4e0b\uff1a /etc/: directory /bin: directory /etc/issue: symbolic link to ../run/issue 2.7.\u6587\u4ef6\u7f16\u7801\u8f6c\u6362 \u00b6 iconv \u547d\u4ee4\u7528\u4e8e\u5c06\u4e00\u79cd\u7f16\u7801\u4e2d\u7684\u67d0\u4e9b\u6587\u672c\u8f6c\u6362\u4e3a\u53e6\u4e00\u79cd\u7f16\u7801\u3002 \u5982\u679c\u6ca1\u6709\u63d0\u4f9b\u8f93\u5165\u6587\u4ef6\uff0c\u5219\u5b83\u4ece\u6807\u51c6\u8f93\u5165\u4e2d\u8bfb\u53d6\u3002 \u540c\u6837\uff0c\u5982\u679c\u6ca1\u6709\u7ed9\u51fa\u8f93\u51fa\u6587\u4ef6\uff0c\u90a3\u4e48\u5b83\u4f1a\u5199\u5165\u6807\u51c6\u8f93\u51fa\u3002 \u5982\u679c\u6ca1\u6709\u63d0\u4f9b from-encoding \u6216 to-encoding \uff0c\u5219\u5b83\u4f7f\u7528\u5f53\u524d\u672c\u5730\u7684\u5b57\u7b26\u7f16\u7801\u3002 \u5c06\u6587\u672c\u4ece ISO 8859-15 \u5b57\u7b26\u7f16\u7801\u8f6c\u6362\u4e3a UTF-8\uff0c\u8bfb\u5165 input.txt \uff0c\u8f93\u51fa output.txt \u3002 iconv -f ISO-8859-15 -t UTF-8 < input.txt > output.txt \u4ece UTF-8 \u8f6c\u6362\u4e3a ASCII\uff0c\u5c3d\u53ef\u80fd\u8fdb\u884c\u97f3\u8bd1\uff08transliterating\uff09\uff1a echo abc \u00df \u03b1 \u20ac \u00e0\u1e03\u00e7 | iconv -f UTF-8 -t ASCII//TRANSLIT \u8fd0\u884c\u7ed3\u679c\uff1a abc ss ? EUR abc 2.8.\u901a\u914d\u7b26 \u00b6 \u901a\u914d\u7b26\uff0c\u6307\u5305\u542b\u8fd9\u4e9b\u5b57\u7b26\u7684\u5b57\u7b26\u4e32 ? \uff1a\u8868\u793a\u4efb\u610f\u4e00\u4e2a\u5b57\u7b26 * \uff1a\u8868\u793a\u4efb\u610f\u957f\u5ea6\u7684\u4efb\u610f\u5b57\u7b26 [] \uff1a\u5339\u914d\u6307\u5b9a\u8303\u56f4\u5185\u4efb\u610f\u4e00\u4e2a\u5b57\u7b26 [abcd] \uff1a\u5339\u914dabcd\u4e2d\u7684\u4efb\u4f55\u4e00\u4e2a\u5b57\u7b26 [a-z] \uff1a\u5339\u914d\u8303\u56f4a\u5230z\u5185\u4efb\u610f\u4e00\u4e2a\u5b57\u7b26 [!abcd] \uff1a\u4e0d\u5339\u914d\u62ec\u53f7\u91cc\u9762\u4efb\u4f55\u4e00\u4e2a\u5b57\u7b26 {} \uff1a\u8868\u793a\u751f\u6210\u5e8f\u5217\uff0c\u4ee5\u9017\u53f7\u5206\u5272\uff0c\u4e0d\u80fd\u6709\u7a7a\u683c \u793a\u4f8b\uff1a $ touch file_ { a..z } .txt $ touch file_ { A..Z } .txt $ ls file_a.txt file_C.txt file_f.txt file_H.txt file_k.txt file_M.txt file_p.txt file_R.txt file_u.txt file_W.txt file_z.txt file_A.txt file_d.txt file_F.txt file_i.txt file_K.txt file_n.txt file_P.txt file_s.txt file_U.txt file_x.txt file_Z.txt file_b.txt file_D.txt file_g.txt file_I.txt file_l.txt file_N.txt file_q.txt file_S.txt file_v.txt file_X.txt file_B.txt file_e.txt file_G.txt file_j.txt file_L.txt file_o.txt file_Q.txt file_t.txt file_V.txt file_y.txt file_c.txt file_E.txt file_h.txt file_J.txt file_m.txt file_O.txt file_r.txt file_T.txt file_w.txt file_Y.txt $ ls file_ [ a..d ] .* file_a.txt file_d.txt $ ls file_ [ a...d ] .* file_a.txt file_d.txt $ ls file_ [ ad ] .* file_a.txt file_d.txt $ ls file_ [ a-c ] .* file_a.txt file_A.txt file_b.txt file_B.txt file_c.txt $ ls file_ [ a-C ] .* file_a.txt file_A.txt file_b.txt file_B.txt file_c.txt file_C.txt $ ls file_ [ !d-W ] .* file_a.txt file_b.txt file_c.txt file_x.txt file_y.txt file_z.txt file_A.txt file_B.txt file_C.txt file_X.txt file_Y.txt file_Z.txt \u6bd4\u8f83\u6709\u65e0 * \u7684\u533a\u522b\uff1a $ ls -a * file_a.txt file_D.txt file_h.txt file_K.txt file_o.txt file_R.txt file_v.txt file_Y.txt file_A.txt file_e.txt file_H.txt file_l.txt file_O.txt file_s.txt file_V.txt file_z.txt file_b.txt file_E.txt file_i.txt file_L.txt file_p.txt file_S.txt file_w.txt file_Z.txt file_B.txt file_f.txt file_I.txt file_m.txt file_P.txt file_t.txt file_W.txt file_c.txt file_F.txt file_j.txt file_M.txt file_q.txt file_T.txt file_x.txt file_C.txt file_g.txt file_J.txt file_n.txt file_Q.txt file_u.txt file_X.txt file_d.txt file_G.txt file_k.txt file_N.txt file_r.txt file_U.txt file_y.txt $ ls -a . file_C.txt file_g.txt file_J.txt file_n.txt file_Q.txt file_u.txt file_X.txt .. file_d.txt file_G.txt file_k.txt file_N.txt file_r.txt file_U.txt file_y.txt file_a.txt file_D.txt file_h.txt file_K.txt file_o.txt file_R.txt file_v.txt file_Y.txt file_A.txt file_e.txt file_H.txt file_l.txt file_O.txt file_s.txt file_V.txt file_z.txt file_b.txt file_E.txt file_i.txt file_L.txt file_p.txt file_S.txt file_w.txt file_Z.txt file_B.txt file_f.txt file_I.txt file_m.txt file_P.txt file_t.txt file_W.txt file_c.txt file_F.txt file_j.txt file_M.txt file_q.txt file_T.txt file_x.txt 2.9.\u5b57\u7b26\u96c6 \u00b6 [:alpha:] \uff1a\u8868\u793a\u6240\u6709\u7684\u5b57\u6bcd\uff08\u4e0d\u533a\u5206\u5927\u5c0f\u5199\uff09\uff0c\u6548\u679c\u540c [a-z] [:digit:] \uff1a\u8868\u793a\u4efb\u610f\u5355\u4e2a\u6570\u5b57\uff0c\u6548\u679c\u540c [0-9] [:xdigit:] \uff1a\u8868\u793a\u5341\u516d\u8fdb\u5236\u6570\u5b57 [:lower:] \uff1a\u8868\u793a\u4efb\u610f\u5355\u4e2a\u5c0f\u5199\u5b57\u6bcd [:upper:] \uff1a\u8868\u793a\u4efb\u610f\u5355\u4e2a\u5927\u5199\u5b57\u6bcd [:alnum:] \uff1a\u8868\u793a\u4efb\u610f\u5355\u4e2a\u5b57\u6bcd\u6216\u6570\u5b57 [:blank:] \uff1a\u8868\u793a\u7a7a\u767d\u5b57\u7b26\uff08\u7a7a\u683c\u548c\u5236\u8868\u7b26\uff09 [:space:] \uff1a\u8868\u793a\u5305\u62ec\u7a7a\u683c\u3001\u5236\u8868\u7b26\uff08\u6c34\u5e73\u548c\u5782\u76f4\uff09\u3001\u6362\u884c\u7b26\u3001\u56de\u8f66\u7b26\u7b49\u5404\u79cd\u7c7b\u578b\u7684\u7a7a\u767d\uff0c\u6bd4 [:blank:] \u8303\u56f4\u66f4\u5e7f [:cntrl:] \uff1a\u8868\u793a\u4e0d\u53ef\u6253\u5370\u7684\u63a7\u5236\u5b57\u7b26\uff08\u9000\u683c\u3001\u5220\u9664\u3001\u8b66\u94c3\u7b49\uff09 [:graph:] \uff1a\u8868\u793a\u53ef\u6253\u5370\u7684\u975e\u7a7a\u767d\u5b57\u7b26 [:print:] \uff1a\u8868\u793a\u53ef\u6253\u5370\u5b57\u7b26 [:punct:] \uff1a\u8868\u793a\u6807\u70b9\u7b26\u53f7 \u4e3e\u4f8b\uff1a ls -d [[:alpha:]] \u5373 ls -d [a-Z] \uff1a\u663e\u793a\u5f53\u524d\u76ee\u5f55\u4e0b\u6240\u6709\u5355\u4e2a\u5b57\u6bcd\u7684\u76ee\u5f55\u548c\u6587\u4ef6 ls -d *[[:digit:]] \u5373 ls -d *[0-9] \uff1a\u663e\u793a\u5f53\u524d\u76ee\u5f55\u4e0b\u6240\u6709\u4ee5\u6570\u5b57\u7ed3\u5c3e\u7684\u76ee\u5f55\u548c\u6587\u4ef6 ls [[:lower:]].txt \uff1a\u663e\u793a\u5f53\u524d\u76ee\u5f55\u4e0b\u6240\u6709\u4ee5\u5355\u4e2a\u5c0f\u5199\u5b57\u6bcd\u4e3a\u540d\u7684.txt\u683c\u5f0f\u7684\u6587\u4ef6 ls -d [[:alnum:]] \uff1a\u663e\u793a\u5f53\u524d\u76ee\u5f55\u4e0b\u6240\u6709\u5355\u4e2a\u5b57\u6bcd\uff08\u4e0d\u533a\u5206\u5927\u5c0f\u5199\uff09\u6216\u6570\u5b57\u4e3a\u540d\u7684\u76ee\u5f55\u6216\u6587\u4ef6 2.10.\u7279\u6b8a\u7b26\u53f7 \u00b6 | \uff1a\u7ba1\u9053\u7b26\uff0c\u6216\u8005\uff08\u6b63\u5219\uff09 > \uff1a\u8f93\u51fa\u91cd\u5b9a\u5411 >> \uff1a\u8f93\u51fa\u8ffd\u52a0\u91cd\u5b9a\u5411 < \uff1a\u8f93\u5165\u91cd\u5b9a\u5411 << \uff1a\u8ffd\u52a0\u8f93\u5165\u91cd\u5b9a\u5411 ~ \uff1a\u5f53\u524d\u7528\u6237\u5bb6\u76ee\u5f55 $() \uff1a\u5f15\u7528\u547d\u4ee4\u88ab\u6267\u884c\u540e\u7684\u7ed3\u679c $ \uff1a\u4ee5...\u7ed3\u5c3e\uff08\u6b63\u5219\uff09 ^ \uff1a\u4ee5...\u5f00\u5934\uff08\u6b63\u5219\uff09 * \uff1a\u5339\u914d\u5168\u90e8\u5b57\u7b26\uff0c\u901a\u914d\u7b26 ? \uff1a\u4efb\u610f\u4e00\u4e2a\u5b57\u7b26\uff0c\u901a\u914d\u7b26 # \uff1a\u6ce8\u91ca & \uff1a\u8ba9\u7a0b\u5e8f\u6216\u811a\u672c\u5207\u6362\u5230\u540e\u53f0\u6267\u884c && \uff1a\u5e76\u4e14\uff0c\u540c\u65f6\u6210\u7acb [] \uff1a\u8868\u793a\u4e00\u4e2a\u8303\u56f4\uff08\u6b63\u5219\uff0c\u901a\u914d\u7b26\uff09 {} \uff1a\u4ea7\u751f\u4e00\u4e2a\u5e8f\u5217\uff08\u901a\u914d\u7b26\uff09 . \uff1a\u5f53\u524d\u76ee\u5f55\u7684\u786c\u94fe\u63a5 .. \uff1a\u4e0a\u7ea7\u76ee\u5f55\u7684\u786c\u94fe\u63a5 2.11.\u5237\u65b0\u6587\u4ef6\u65f6\u95f4 touch \u00b6 touch \u547d\u4ee4\u53ef\u4ee5\u521b\u5efa\u7a7a\u6587\u4ef6\uff0c\u4e5f\u53ef\u4ee5\u5237\u65b0\u6587\u4ef6\u65f6\u95f4\u3002\u53c2\u6570\u5982\u4e0b\uff1a -a \uff1a\u4ec5\u6539\u53d8 atime \u548c ctime -m \uff1a\u4ec5\u6539\u53d8 mtime \u548c ctime -t [[CC]YY]MMDDhhmm[.ss] \uff1a\u6307\u5b9a atime \u548c mtime -c \uff1a\u5982\u679c\u6587\u4ef6\u4e0d\u5b58\u5728\uff0c\u5219\u4e0d\u521b\u5efa $ touch file1 $ touch file2 $ ll -rw-r--r--. 1 vagrant wheel 5 Nov 8 20 :49 file1 -rw-r--r--. 1 vagrant wheel 0 Nov 8 20 :28 file2 \u521b\u5efa\u6587\u4ef6file-non.log\uff0c\u5982\u679c\u4e0d\u5b58\u5728\u5219\u4e0d\u521b\u5efa\u3002 touch -c file-non.log \u66f4\u65b0 file1 \u7684\u65f6\u95f4\u548c file2 \u4e00\u81f4\u3002 $ touch -r file1 file2 $ ll -rw-r--r--. 1 vagrant wheel 5 Nov 8 20 :49 file1 -rw-r--r--. 1 vagrant wheel 0 Nov 8 20 :49 file2 \u6307\u5b9a file2 \u7684\u65f6\u95f4\u3002 202210012135.25 \u4ee3\u8868 YYYYMMDDHHMM.SS \u3002 $ touch -t 202210012135 .25 file2 $ ll -rw-r--r--. 1 vagrant wheel 5 Nov 8 20 :49 file1 -rw-r--r--. 1 vagrant wheel 0 Oct 1 21 :35 file2 $ stat file2 File: file2 Size: 0 Blocks: 0 IO Block: 4096 regular empty file Device: fd02h/64770d Inode: 140 Links: 1 Access: ( 0644 /-rw-r--r-- ) Uid: ( 1000 / vagrant ) Gid: ( 10 / wheel ) Context: unconfined_u:object_r:user_home_t:s0 Access: 2022 -10-01 21 :35:25.000000000 +0800 Modify: 2022 -10-01 21 :35:25.000000000 +0800 Change: 2022 -11-08 20 :56:18.306315887 +0800 Birth: 2022 -11-08 20 :28:37.809551441 +0800 2.12.\u590d\u5236\u6587\u4ef6\u548c\u76ee\u5f55 cp \u00b6 cp \u547d\u4ee4\uff1aCopy SOURCE to DEST, or multiple SOURCE(s) to DIRECTORY. \u5e38\u7528\u53c2\u6570\uff1a -a \uff1a\u5f52\u6863\uff0c\u76f8\u5f53\u4e8e -dR --preserv=all \u53c2\u6570\u7ec4\u5408\uff0c\u5e38\u7528\u4e8e\u5907\u4efd\u3002 -d \uff1a\u4e0d\u590d\u5236\u539f\u6587\u4ef6\uff0c\u53ea\u590d\u5236\u94fe\u63a5\u540d\u3002\u76f8\u5f53\u4e8e --no-dereference --preserve=links \u53c2\u6570\u7ec4\u5408\u3002 -f \uff1a\u8986\u76d6\u5df2\u7ecf\u5b58\u5728\u7684\u76ee\u6807\u6587\u4ef6\u3002 -i \uff1a\u8986\u76d6\u76ee\u6807\u6587\u4ef6\u4e4b\u524d\u7ed9\u51fa\u63d0\u793a\u3002 -p \uff1a\u9664\u590d\u5236\u6587\u4ef6\u7684\u5185\u5bb9\u5916\uff0c\u4e5f\u590d\u5236\u6587\u4ef6\u6743\u9650\uff0c\u65f6\u95f4\u6233\uff0c\u5c5e\u4e3b\u5c5e\u7ec4\u3002\u76f8\u5f53\u4e8e --preserve=mode,ownership,timestamps \u3002 -r, -R, --recursive \uff1a\u9012\u5f52\u590d\u5236\u76ee\u5f55\u6240\u5305\u542b\u7684\u5168\u90e8\u5185\u5bb9\u3002 -l \uff1a\u4e0d\u590d\u5236\u6587\u4ef6\uff0c\u53ea\u662f\u751f\u6210\u786c\u94fe\u63a5\u6587\u4ef6\u3002 \u53c2\u6570 --preserv \u53ef\u9009\u9879\uff1a mode\uff1a\u6743\u9650 ownership\uff1a\u5c5e\u4e3b\u5c5e\u7ec4 timestamp links xattr context all \u521b\u5efa\u6d4b\u8bd5\u76ee\u5f55\u3002 cd ~ mkdir test \u5bf9\u6bd4\u53c2\u6570 -p \u7684\u5dee\u522b\u3002 $ cp /etc/issue ~/test/issue1 $ cp -p /etc/issue ~/test/issue1 $ sudo cp /etc/issue ~/test/issue3 $ sudo cp -p /etc/issue ~/test/issue4 $ ll ~/test -rw-r--r--. 1 vagrant wheel 23 Nov 8 22 :25 issue1 -rw-r--r--. 1 vagrant wheel 23 Jul 21 01 :10 issue2 -rw-r--r--. 1 root root 23 Nov 8 22 :43 issue3 -rw-r--r--. 1 root root 23 Jul 21 01 :10 issue4 $ ll /etc/issue -rw-r--r--. 1 root root 23 Jul 21 01 :10 /etc/issue \u5bf9\u6bd4\u53c2\u6570 -r \u3002 $ sudo cp /etc/sysconfig/ ~/test cp: -r not specified ; omitting directory '/etc/sysconfig/' $ sudo cp -r /etc/sysconfig/ ~/test $ tree -L 2 ~/test /home/vagrant/test \u251c\u2500\u2500 issue1 \u251c\u2500\u2500 issue2 \u251c\u2500\u2500 issue3 \u251c\u2500\u2500 issue4 \u2514\u2500\u2500 sysconfig \u251c\u2500\u2500 anaconda \u251c\u2500\u2500 atd \u251c\u2500\u2500 chronyd \u251c\u2500\u2500 cpupower \u251c\u2500\u2500 crond \u251c\u2500\u2500 firewalld \u251c\u2500\u2500 irqbalance \u251c\u2500\u2500 kdump \u251c\u2500\u2500 kernel \u251c\u2500\u2500 man-db \u251c\u2500\u2500 network \u251c\u2500\u2500 network-scripts \u251c\u2500\u2500 nftables.conf \u251c\u2500\u2500 raid-check \u251c\u2500\u2500 rsyslog \u251c\u2500\u2500 run-parts \u251c\u2500\u2500 samba \u251c\u2500\u2500 selinux -> ../selinux/config \u251c\u2500\u2500 smartmontools \u2514\u2500\u2500 sshd \u53c2\u6570 -b \uff0c\u5982\u679c\u76ee\u6807\u6587\u4ef6\u5b58\u5728\uff0c\u590d\u5236\u524d\u5148\u5c06\u539f\u6587\u4ef6\u590d\u5236\u5e76\u4ee5 ~ \u7ed3\u5c3e\u3002 $ ll /etc/motd -rw-r--r--. 1 root root 0 Jun 23 2020 /etc/motd $ ll ~/test/issue1 -rw-r--r--. 1 vagrant wheel 23 Nov 8 22 :25 /home/vagrant/test/issue1 $ cp -b /etc/motd ~/test/issue $ cp -b /etc/motd ~/test/issue1 $ ll ~/test -rw-r--r--. 1 vagrant wheel 0 Nov 8 23 :00 issue -rw-r--r--. 1 vagrant wheel 0 Nov 8 22 :57 issue1 -rw-r--r--. 1 vagrant wheel 23 Nov 8 22 :25 issue1~ -rw-r--r--. 1 vagrant wheel 23 Jul 21 01 :10 issue2 -rw-r--r--. 1 root root 23 Nov 8 22 :43 issue3 -rw-r--r--. 1 root root 23 Jul 21 01 :10 issue4 drwxr-xr-x. 3 root root 4096 Nov 8 22 :49 sysconfig \u53c2\u6570 --backup=numbered \u4f1a\u5728\u590d\u5236\u539f\u6587\u4ef6\u65f6\u52a0\u4e0a\u6570\u5b57\u5e8f\u53f7\uff0c\u5e8f\u53f71\u4ee3\u8868\u539f\u59cb\u7684\u6587\u4ef6\u3002 $ cp --backup = numbered /etc/motd ~/test/issue2 $ cp --backup = numbered /etc/motd ~/test/issue2 $ cp --backup = numbered /etc/motd ~/test/issue2 $ ll ~/test -rw-r--r--. 1 vagrant wheel 0 Nov 8 23 :00 issue -rw-r--r--. 1 vagrant wheel 0 Nov 8 22 :57 issue1 -rw-r--r--. 1 vagrant wheel 23 Nov 8 22 :25 issue1~ -rw-r--r--. 1 vagrant wheel 0 Nov 8 23 :09 issue2 -rw-r--r--. 1 vagrant wheel 23 Jul 21 01 :10 issue2.~1~ -rw-r--r--. 1 vagrant wheel 0 Nov 8 23 :09 issue2.~2~ -rw-r--r--. 1 vagrant wheel 0 Nov 8 23 :09 issue2.~3~ -rw-r--r--. 1 root root 23 Nov 8 22 :43 issue3 -rw-r--r--. 1 root root 23 Jul 21 01 :10 issue4 drwxr-xr-x. 3 root root 4096 Nov 8 22 :49 sysconfig 2.13.\u79fb\u52a8\u6587\u4ef6\u548c\u76ee\u5f55 mv \u00b6 mv \u547d\u4ee4\u3002Rename SOURCE to DEST, or move SOURCE(s) to DIRECTORY. \u5e38\u7528\u53c2\u6570\uff1a -v \uff1a\u663e\u793a\u547d\u4ee4\u6267\u884c\u7684\u4fe1\u606f\u3002 -i \uff1a\u4ea4\u4e92\u5f0f\uff0c\u6bd4\u5982\uff0c\u91cd\u540d\u8986\u76d6\u65f6\u4f1a\u63d0\u5347\u662f\u5426\u786e\u8ba4\u3002 -b \uff1a\u8986\u76d6\u65f6\u521b\u5efa\u5907\u4efd\u3002\u9ed8\u8ba4\u60c5\u51b5\u4e0b\uff0c\u79fb\u52a8\u6587\u4ef6\u5c06\u4f1a\u8986\u76d6\u5df2\u5b58\u5728\u7684\u76ee\u6807\u6587\u4ef6\u3002 \u79fb\u52a8\u591a\u4e2a\u6587\u4ef6\u5230\u67d0\u4e2a\u76ee\u5f55\u3002 mv file1 file2 file3 ~/dest mv file* ~/dest \u79fb\u52a8\u76ee\u5f55\u3002 mv ~/test ~/dest/new/one/ \u91cd\u547d\u540d\u6587\u4ef6\u548c\u76ee\u5f55\u3002 mv file1 file2 mv ~/test ~/dest 2.14.\u91cd\u547d\u540d\u6587\u4ef6\u548c\u76ee\u5f55 rename \u00b6 rename \u547d\u4ee4\u3002\u5206\u4e3aperl\u7248\u672c\u548cC\u8bed\u8a00\u7248\u672c\u3002 \u533a\u5206\u65b9\u6cd5: rename --version \u3002\u5982\u679c\u8fd4\u56de\u7ed3\u679c\u4e2d\u5305\u542b util-linux \uff0c\u8bf4\u660e\u662fC\u8bed\u8a00\u7248\u672c, \u53cd\u4e4b\u662fPerl\u7248\u672c\u3002 openSUSE\u548cRocy\u662fC\u8bed\u8a00\u7248\u672c\uff0cUbuntu\u662fPerl\u7248\u672c\u3002 \u4e3e\u4f8b\uff1a\u4fee\u6539\u5f53\u524d\u76ee\u5f55\u6240\u6709\u6269\u5c55\u540d\u4e3a s \u7684\u6587\u4ef6\u6539\u4e3a\u6269\u5c55\u540d\u4e3a gz \u3002 $ touch file { 1 ..3 } .s $ rename -v '.s' '.gz' *.s $ rename -v \".s\" \".gz\" *.s ` file1.txt ' -> `file1.html' ` file2.txt ' -> `file2.html' ` file3.txt ' -> `file3.html' \u5728Ubuntu\u4e0a\u5b8c\u6210\u540c\u6837\u4efb\u52a1\uff0c\u5219\u9700\u8981\u4f7f\u7528\u6b63\u5219\u3002 rename -v \"s/s/gz/g\" *.s 2.15.\u5220\u9664\u6587\u4ef6 rm \u00b6 rm \u547d\u4ee4\u3002\u5efa\u8bae\u4f7f\u7528 mv \u547d\u4ee4\u4ee3\u66ff rm \u547d\u4ee4\u3002 2.16.\u76ee\u5f55\u64cd\u4f5c\u547d\u4ee4 \u00b6 \u521b\u5efa\u76ee\u5f55\uff1a mkdir \u5220\u9664\u7a7a\u76ee\u5f55\uff1a rmdir \u5220\u9664\u975e\u7a7a\u76ee\u5f55\uff1a rm -r \u663e\u793a\u76ee\u5f55\u6811\uff1a tree 2.17.\u7ec3\u4e60 \u00b6 \u663e\u793a /etc \u76ee\u5f55\u4e0b\u6240\u6709\u4ee5 l \u5f00\u5934\uff0c\u4ee5\u4e00\u4e2a\u5c0f\u5199\u5b57\u6bcd\u7ed3\u5c3e\uff0c\u4e14\u4e2d\u95f4\u51fa\u73b0\u81f3\u5c11\u4e00\u4f4d\u6570\u5b57\u7684\u6587\u4ef6\u6216\u76ee\u5f55\u5217\u8868\u3002 ls -d /etc/l* [ 0 -9 ] * [ a-z ] ls -d /etc/l* [[ :digit: ]] * [[ :lower: ]] \u5982\u679c\u65e0\u7b26\u5408\u6761\u4ef6\u7684\u8bb0\u5f55\u8fd4\u56de\uff0c\u53ef\u4ee5\u624b\u5de5\u521b\u5efa\u4e00\u4e2a\u7b26\u5408\u6761\u4ef6\u7684\u6587\u4ef6\u548c\u76ee\u5f55\u3002 sudo touch /etc/lam4you sudo mkdir /etc/lam5you \u9a8c\u8bc1\u540e\u5220\u9664\u3002 sudo rm /etc/lam4you sudo rm -rf /etc/lam5you \u663e\u793a /etc \u76ee\u5f55\u4e0b\u4ee5\u4efb\u610f\u4e00\u4f4d\u6570\u5b57\u5f00\u5934\uff0c\u4e14\u4ee5\u975e\u6570\u5b57\u7ed3\u5c3e\u7684\u6587\u4ef6\u6216\u76ee\u5f55\u5217\u8868\u3002 ls /etc/ [ 0 -9 ] * [ !0-9 ] ls /etc/ [[ :digit: ]] * [ ^ [ :digit: ]] \u5982\u679c\u65e0\u7b26\u5408\u6761\u4ef6\u7684\u8bb0\u5f55\u8fd4\u56de\uff0c\u53ef\u4ee5\u624b\u5de5\u521b\u5efa\u4e00\u4e2a\u7b26\u5408\u6761\u4ef6\u7684\u6587\u4ef6\u548c\u76ee\u5f55\u3002 sudo touch /etc/5am4yo. sudo mkdir /etc/5am5yo. \u9a8c\u8bc1\u540e\u5220\u9664\u3002 sudo rm /etc/5am4yo. sudo rm -rf /etc/5am5yo. \u663e\u793a /etc \u76ee\u5f55\u4e0b\u4ee5\u975e\u5b57\u6bcd\u5f00\u5934\uff0c\u540e\u9762\u8ddf\u4e86\u4e00\u4e2a\u5b57\u6bcd\u53ca\u5176\u5b83\u4efb\u610f\u957f\u5ea6\u4efb\u610f\u5b57\u7b26\u7684\u6587\u4ef6\u6216\u76ee\u5f55\u5217\u8868\u3002 ls /etc/ [ !a-zA-Z ][ a-zA-Z ] * ls /etc/ [ ^ [ :alpha: ]][[ :alpha: ]] * \u5982\u679c\u65e0\u7b26\u5408\u6761\u4ef6\u7684\u8bb0\u5f55\u8fd4\u56de\uff0c\u53ef\u4ee5\u624b\u5de5\u521b\u5efa\u4e00\u4e2a\u7b26\u5408\u6761\u4ef6\u7684\u6587\u4ef6\u548c\u76ee\u5f55\u3002 sudo touch /etc/5Ato3 sudo mkdir /etc/6dog6 \u9a8c\u8bc1\u540e\u5220\u9664\u3002 sudo rm /etc/5Ato3 sudo rm -rf /etc/6dog6 \u663e\u793a /etc \u76ee\u5f55\u4e0b\uff0c\u6240\u6709\u4ee5 rc \u5f00\u5934\uff0c\u5e76\u540e\u9762\u662f0-6\u4e4b\u95f4\u7684\u6570\u5b57\uff0c\u5176\u5b83\u4e3a\u4efb\u610f\u5b57\u7b26\u7684\u6587\u4ef6\u6216\u76ee\u5f55\u5217\u8868\u3002 ls /etc/rc [ 0 -6 ] * \u5982\u679c\u65e0\u7b26\u5408\u6761\u4ef6\u7684\u8bb0\u5f55\u8fd4\u56de\uff0c\u53ef\u4ee5\u624b\u5de5\u521b\u5efa\u4e00\u4e2a\u7b26\u5408\u6761\u4ef6\u7684\u6587\u4ef6\u548c\u76ee\u5f55\u3002 sudo touch /etc/rc5come sudo mkdir /etc/rc0123 \u9a8c\u8bc1\u540e\u5220\u9664\u3002 sudo rm /etc/rc5come sudo rm -rf /etc/rc0123 \u663e\u793a /etc \u76ee\u5f55\u4e0b\uff0c\u6240\u6709\u4ee5 .conf \u7ed3\u5c3e\uff0c\u4e14\u4ee5 m \u3001 n \u3001 r \u3001 p \u5f00\u5934\u7684\u6587\u4ef6\u6216\u76ee\u5f55\u5217\u8868\u3002 ls /etc/ [ mnrp ] *.conf \u53ea\u663e\u793a /root \u4e0b\u7684\u9690\u85cf\u6587\u4ef6\u548c\u76ee\u5f55\u5217\u8868\u3002 ls .* \u53ea\u663e\u793a/etc\u4e0b\u975e\u9690\u85cf\u76ee\u5f55\u5217\u8868\u3002 ls /etc/ [ ^. ] */ \u5c06 /etc \u76ee\u5f55\u4e0b\u6240\u6709\u6587\u4ef6\uff0c\u5907\u4efd\u5230 ~/test/ \u76ee\u5f55\u4e0b\uff0c\u5e76\u8981\u6c42\u5b50\u76ee\u5f55\u683c\u5f0f\u4e3a backupYYYY-mm-dd \uff0c\u5907\u4efd\u8fc7\u7a0b\u53ef\u89c1\u3002 sudo cp -av /etc/ ~/test/backup ` date +%F ` sudo cp -av /etc/ ~/test/backup ` date +%F_%H-%M-%S ` \u521b\u5efa\u76ee\u5f55 ~/testdir/dir1/x \uff0c ~/testdir/dir1/y \uff0c ~/testdir/dir1/x/a \uff0c ~/testdir/dir1/x/b \uff0c ~/testdir/dir1/y/a \uff0c ~/testdir/dir1/y/b \u3002 $ mkdir -p ~/testdir/dir1/ { x,y } / { a,b } $ tree ~/testdir/dir1/ /home/vagrant/testdir/dir1/ \u251c\u2500\u2500 x \u2502 \u251c\u2500\u2500 a \u2502 \u2514\u2500\u2500 b \u2514\u2500\u2500 y \u251c\u2500\u2500 a \u2514\u2500\u2500 b \u521b\u5efa\u76ee\u5f55 ~/testdir/dir2/x \uff0c ~/testdir/dir2/y \uff0c ~/testdir/dir2/x/a \uff0c ~/testdir/dir2/x/b \u3002 $ mkdir -p ~/testdir/dir2/ { x/ { a,b } ,y } $ tree ~/testdir/dir2/ /home/vagrant/testdir/dir2/ \u251c\u2500\u2500 x \u2502 \u251c\u2500\u2500 a \u2502 \u2514\u2500\u2500 b \u2514\u2500\u2500 y \u521b\u5efa\u76ee\u5f55 ~/testdir/dir3 \u3001 ~/testdir/dir4 \u3001 ~/testdir/dir5 \u3001 ~/testdir/dir5/dir6 \u3001 ~/testdir/dir5/dir7 \u3002 $ mkdir -p ~/testdir/dir { 3 ,4,5/dir { 6 ,7 }} $ tree ~/testdir /home/vagrant/testdir \u251c\u2500\u2500 dir1 \u2502 \u251c\u2500\u2500 x \u2502 \u2502 \u251c\u2500\u2500 a \u2502 \u2502 \u2514\u2500\u2500 b \u2502 \u2514\u2500\u2500 y \u2502 \u251c\u2500\u2500 a \u2502 \u2514\u2500\u2500 b \u251c\u2500\u2500 dir2 \u2502 \u251c\u2500\u2500 x \u2502 \u2502 \u251c\u2500\u2500 a \u2502 \u2502 \u2514\u2500\u2500 b \u2502 \u2514\u2500\u2500 y \u251c\u2500\u2500 dir3 \u251c\u2500\u2500 dir4 \u2514\u2500\u2500 dir5 \u251c\u2500\u2500 dir6 \u2514\u2500\u2500 dir7 3.\u4e03\u79cd\u6587\u4ef6\u7c7b\u578b \u00b6 \u666e\u901a\u6587\u4ef6\uff08Normal Files\uff09 ASCII \u6587\u672c\u6587\u4ef6 \u53ef\u6267\u884c\u6587\u4ef6 \u56fe\u5f62\u6587\u4ef6 \u76ee\u5f55\uff08Directories\uff09 \u7ec4\u7ec7\u89c4\u5212\u78c1\u76d8\u4e0a\u7684\u6587\u4ef6 \u5305\u542b\u6587\u4ef6\u548c\u5b50\u76ee\u5f55 \u5b9e\u73b0\u5206\u5c42\u6587\u4ef6\u7cfb\u7edf \u94fe\u63a5\uff08Links\uff09 \u786c\u94fe\u63a5\uff08Hard links\uff09 \u78c1\u76d8\u4e0a\u6587\u4ef6\u7684\u8f85\u52a9\u6587\u4ef6\u540d \u591a\u4e2a\u6587\u4ef6\u540d\u5f15\u7528\u5355\u4e2a inode \u5f15\u7528\u7684\u6587\u4ef6\u5fc5\u987b\u5b58\u5728\u4e8e\u540c\u4e00\u4e2a\u6587\u4ef6\u7cfb\u7edf\u4e2d \u7b26\u53f7\u94fe\u63a5\uff08Symbolic links\uff09 \u5bf9\u78c1\u76d8\u4e0a\u5176\u4ed6\u6587\u4ef6\u7684\u5f15\u7528 inode \u5305\u542b\u5bf9\u53e6\u4e00\u4e2a\u6587\u4ef6\u540d\u7684\u5f15\u7528 \u88ab\u5f15\u7528\u7684\u6587\u4ef6\u53ef\u4ee5\u5b58\u5728\u4e8e\u540c\u4e00\u4e2a\u6587\u4ef6\u7cfb\u7edf\u4e2d\uff0c\u4e5f\u53ef\u4ee5\u5b58\u5728\u4e8e\u5176\u4ed6\u6587\u4ef6\u7cfb\u7edf\u4e2d \u7b26\u53f7\u94fe\u63a5\u53ef\u4ee5\u5f15\u7528\u4e0d\u5b58\u5728\u7684\u6587\u4ef6\uff08\u65ad\u5f00\u7684\u94fe\u63a5\uff09 \u5957\u63a5\u5b57Sockets - \u7528\u4e8e\u8fdb\u7a0b\u4e4b\u95f4\u7684\u53cc\u5411\u901a\u4fe1\u3002 \u7ba1\u9053\uff08Pipes\uff09(FIFOs) - \u7528\u4e8e\u4ece\u4e00\u4e2a\u8fdb\u7a0b\u5230\u53e6\u4e00\u4e2a\u8fdb\u7a0b\u7684\u5355\u5411\u901a\u4fe1\u3002 \u5757\u8bbe\u5907\uff08Block Devices\uff09 \u5b57\u7b26\u8bbe\u5907\uff08Character Devices\uff09 3.1.inode\u7ed3\u6784 \u00b6 \u6587\u4ef6\u50a8\u5b58\u5728\u786c\u76d8\u4e0a\uff0c\u786c\u76d8\u7684\u6700\u5c0f\u5b58\u50a8\u5355\u4f4d\u53eb\u505a\u201c\u6247\u533a\u201d\uff08Sector\uff09\u3002\u6bcf\u4e2a\u6247\u533a\u50a8\u5b58512\u5b57\u8282\uff08\u76f8\u5f53\u4e8e0.5KB\uff09\u3002 \u64cd\u4f5c\u7cfb\u7edf\u8bfb\u53d6\u786c\u76d8\u7684\u65f6\u5019\uff0c\u4e0d\u662f\u4e00\u4e2a\u4e00\u4e2a\u6247\u533a\u8bfb\u53d6\uff0c\u800c\u662f\u4e00\u6b21\u6027\u8fde\u7eed\u8bfb\u53d6\u591a\u4e2a\u6247\u533a\uff0c\u6211\u4eec\u79f0\u4e3a\u8bfb\u53d6\u4e00\u4e2a\u201c\u5757\u201d\uff08block\uff09\u3002 \u5e38\u89c1\u7684block\u7684\u5927\u5c0f\u662f4KB\uff08\u8fde\u7eed\u516b\u4e2asector\u7ec4\u6210\u4e00\u4e2ablock\uff09\u3002 \u591a\u4e2a\u6247\u533a\u7ec4\u6210\u7684block\u662f\u6587\u4ef6\u5b58\u53d6\u7684*\u6700\u5c0f\u5355\u4f4d*\u3002 \u6587\u4ef6\u6570\u636e\u50a8\u5b58\u5728block\u4e2d\uff0c\u6587\u4ef6\u7684\u5143\u4fe1\u606f\uff0c\u6bd4\u5982\u6587\u4ef6\u7684\u521b\u5efa\u8005\u3001\u521b\u5efa\u65e5\u671f\u3001\u6587\u5927\u5c0f\u7b49\uff0c\u5b58\u50a8\u5728inode\uff0c\u5373\u201c\u7d22\u5f15\u8282\u70b9\u201d\u3002 \u6bcf\u4e00\u4e2a\u6587\u4ef6\u90fd\u6709\u5bf9\u5e94\u7684inode\uff0c\u91cc\u9762\u5305\u542b\u4e86\u4e0e\u8be5\u6587\u4ef6\u6709\u5173\u7684\u4e00\u4e9b\u4fe1\u606f\u3002\u6ce8\u610f\uff0c\u9664\u4e86\u6587\u4ef6\u540d\u4ee5\u5916\u7684\u5176\u5b83\u6587\u4ef6\u4fe1\u606f\uff0c\u90fd\u5b58\u5728inode\u4e4b\u4e2d\u3002 inode\u5305\u542b\u6587\u4ef6\u7684\u5143\u4fe1\u606f\u4e3b\u8981\u6709\uff1a \u6587\u4ef6\u7684\u5b57\u8282\u6570 \u6587\u4ef6\u62e5\u6709\u8005\u7684 User ID \u6587\u4ef6\u7684 Group ID \u6587\u4ef6\u7684\u8bfb\u3001\u5199\u3001\u6267\u884c\u6743\u9650 \u6587\u4ef6\u7684\u65f6\u95f4\u6233\uff0c\u5171\u6709\u4e09\u4e2a\uff1actime\u6307inode\u4e0a\u4e00\u6b21\u53d8\u52a8\u7684\u65f6\u95f4\uff0cmtime\u6307\u6587\u4ef6\u5185\u5bb9\u4e0a\u4e00\u6b21\u53d8\u52a8\u7684\u65f6\u95f4\uff0catime\u6307\u6587\u4ef6\u4e0a\u4e00\u6b21\u6253\u5f00\u7684\u65f6\u95f4\u3002 \u94fe\u63a5\u6570\uff0c\u5373\u6709\u591a\u5c11\u6587\u4ef6\u540d\u6307\u5411\u8fd9\u4e2ainode \u6587\u4ef6\u6570\u636eblock\u7684\u4f4d\u7f6e \u67e5\u770binode\u4fe1\u606f\u7684\u547d\u4ee4 stat \uff1a $ stat file1 File: file1 Size: 5 Blocks: 8 IO Block: 4096 regular file Device: fd02h/64770d Inode: 143 Links: 1 Access: ( 0644 /-rw-r--r-- ) Uid: ( 1000 / vagrant ) Gid: ( 10 / wheel ) Context: unconfined_u:object_r:user_home_t:s0 Access: 2022 -11-08 20 :49:26.019678244 +0800 Modify: 2022 -11-08 20 :49:26.019678244 +0800 Change: 2022 -11-08 20 :49:26.028678455 +0800 Birth: 2022 -11-08 20 :49:26.019678244 +0800 \u683c\u5f0f\u5316\u786c\u76d8\u65f6\uff0c\u64cd\u4f5c\u7cfb\u7edf\u4f1a\u81ea\u52a8\u5c06\u786c\u76d8\u5206\u6210\u4e24\u4e2a\u533a\u57df\u3002\u4e00\u4e2a\u662f\u6570\u636e\u533a\uff0c\u5b58\u653e\u6587\u4ef6\u6570\u636e\u3002\u53e6\u4e00\u4e2a\u662finode\u533a\uff08inode table\uff09\uff0c\u5b58\u653einode\u6240\u5305\u542b\u7684\u6587\u4ef6\u7684\u5143\u4fe1\u606f\u3002 \u6bcf\u4e2ainode\u8282\u70b9\u7684\u5927\u5c0f\uff0c\u4e00\u822c\u662f128\u5b57\u8282\u6216256\u5b57\u8282\u3002inode\u8282\u70b9\u7684\u603b\u6570\uff0c\u5728\u683c\u5f0f\u5316\u65f6\u5c31\u786e\u5b9a\u4e86\uff0c\u4e00\u822c\u662f\u6bcf1KB\u6216\u6bcf2KB\u5c31\u8bbe\u7f6e\u4e00\u4e2ainode\u3002 \u5047\u5b9a\u4e00\u57571GB\u7684\u786c\u76d8\uff0c\u5982\u679c\u6bcf\u4e2ainode\u8282\u70b9\u7684\u5927\u5c0f\u4e3a128\u5b57\u8282\uff0c\u4e14\u6bcf1KB\u5c31\u8bbe\u7f6e\u4e00\u4e2ainode\uff0c\u5219inode table\u7684\u5927\u5c0f\u5c31\u4f1a\u8fbe\u5230128MB\uff0c\u5360\u6574\u5757\u786c\u76d8\u768412.8%\u3002 \u901a\u8fc7 df \u547d\u4ee4\u67e5\u770b\u6bcf\u4e2a\u786c\u76d8\u5206\u533a\u7684inode\u603b\u6570\u548c\u5df2\u7ecf\u4f7f\u7528\u7684\u6570\u91cf\u3002 \u7531\u4e8e\u6bcf\u4e2a\u6587\u4ef6\u90fd\u5fc5\u987b\u6709\u4e00\u4e2ainode\uff0c\u56e0\u6b64\u6709\u53ef\u80fd\u53d1\u751finode\u5df2\u7ecf\u7528\u5149\uff0c\u4f46\u662f\u786c\u76d8\u8fd8\u672a\u5b58\u6ee1\u7684\u60c5\u51b5\uff0c\u4e5f\u5c31\u65e0\u6cd5\u5728\u786c\u76d8\u4e0a\u521b\u5efa\u65b0\u6587\u4ef6\u3002 $ df -i Filesystem Inodes IUsed IFree IUse% Mounted on tmpfs 497897 872 497025 1 % /run /dev/mapper/ubuntu--vg-ubuntu--lv 3211264 81473 3129791 3 % / tmpfs 497897 1 497896 1 % /dev/shm tmpfs 497897 3 497894 1 % /run/lock /dev/sda2 131072 316 130756 1 % /boot tmpfs 99579 25 99554 1 % /run/user/1000 \u4e0b\u9762\u547d\u4ee4\u53ef\u4ee5\u67e5\u770b\u6bcf\u4e2ainode\u8282\u70b9\u7684\u5927\u5c0f\uff1a $ sudo dumpe2fs -h /dev/sda2 | grep \"Inode size\" dumpe2fs 1 .46.5 ( 30 -Dec-2021 ) Inode size: 256 \u6bcf\u4e2ainode\u90fd\u6709\u4e00\u4e2a\u53f7\u7801\uff0c\u64cd\u4f5c\u7cfb\u7edf\u7528inode\u53f7\u7801\u6765\u8bc6\u522b\u4e0d\u540c\u7684\u6587\u4ef6\uff0c\u6ce8\u610f\uff0c\u4e0d\u662f\u901a\u8fc7\u6587\u4ef6\u540d\u6765\u8bc6\u522b\u4e0d\u540c\u6587\u4ef6\u3002\u4ece\u64cd\u4f5c\u7cfb\u7edf\u89d2\u5ea6\u770b\uff0c\u6587\u4ef6\u540d\u53ea\u662finode\u53f7\u7801\u5bf9\u4e00\u4e2a\u522b\u540d\u3002 \u7528\u6237\u901a\u8fc7\u6587\u4ef6\u540d\uff0c\u6253\u5f00\u67d0\u4e2a\u6587\u4ef6\u7684\u8fc7\u7a0b\uff0c\u64cd\u4f5c\u7cfb\u7edf\u5206\u6210\u4e09\u6b65\u5b8c\u6210\uff1a \u9996\u5148\uff0c\u7cfb\u7edf\u627e\u5230\u8fd9\u4e2a\u6587\u4ef6\u540d\u5bf9\u5e94\u7684inode\u53f7\u7801\u3002 \u5176\u6b21\uff0c\u901a\u8fc7inode\u53f7\uff0c\u83b7\u53d6inode\u4fe1\u606f\u3002 \u7b2c\u4e09\uff0c\u901a\u8fc7inode\u4fe1\u606f\uff0c\u627e\u5230\u6587\u4ef6\u6570\u636e\u6240\u5728\u7684block\uff0c\u8bfb\u51fa\u6570\u636e\u3002 \u901a\u8fc7 ls -i \u547d\u4ee4\uff0c\u53ef\u4ee5\u5f97\u5230\u6587\u4ef6\u5bf9\u5e94\u7684inode\u53f7\uff1a $ ls -i file1 143 file1 \u76ee\u5f55\uff08directory\uff09\u4e5f\u662f\u4e00\u79cd\u6587\u4ef6\u3002\u6253\u5f00\u76ee\u5f55\uff0c\u5b9e\u9645\u4e0a\u5c31\u662f\u6253\u5f00\u76ee\u5f55\u6587\u4ef6\u3002 \u76ee\u5f55\u6587\u4ef6\u7684\u7ed3\u6784\u662f\u7531\u4e00\u4e2a\u5305\u542b\u4e00\u7cfb\u5217\u76ee\u5f55\u9879\uff08dirent\uff09\u7684\u5217\u8868\u7ec4\u6210\u3002 \u6bcf\u4e2a\u76ee\u5f55\u9879\u7531\u4e24\u90e8\u5206\u7ec4\u6210\uff1a\u6240\u5305\u542b\u6587\u4ef6\u7684\u6587\u4ef6\u540d\uff0c\u4ee5\u53ca\u8be5\u6587\u4ef6\u540d\u5bf9\u5e94\u7684inode\u53f7\u3002 \u547d\u4ee4 ls -i \u5217\u51fa\u6574\u4e2a\u76ee\u5f55\u6587\u4ef6\uff0c\u5373\u6587\u4ef6\u540d\u548cinode\u53f7\uff1a $ ls -i 143 file1 140 file2 139 test $ ls -il 143 -rw-r--r--. 1 vagrant wheel 5 Nov 8 20 :49 file1 140 -rw-r--r--. 1 vagrant wheel 0 Oct 1 21 :35 file2 139 drwxr-xr-x. 5 vagrant wheel 4096 Nov 9 22 :00 test 3.2.\u94fe\u63a5\u7c7b\u578b \u00b6 \u786c\u94fe\u63a5 \uff08Hard links\uff09\u786c\u94fe\u63a5\u662f\u5b58\u50a8\u5377\u4e0a\u6587\u4ef6\u7684\u76ee\u5f55\u5f15\u7528\u6216\u6307\u9488\u3002 \u6587\u4ef6\u540d\u662f\u5b58\u50a8\u5728\u76ee\u5f55\u7ed3\u6784\u4e2d\u7684\u6807\u7b7e\uff0c\u76ee\u5f55\u7ed3\u6784\u6307\u5411\u6587\u4ef6\u6570\u636e\u3002 \u56e0\u6b64\uff0c\u53ef\u4ee5\u5c06\u591a\u4e2a\u6587\u4ef6\u540d\u4e0e\u540c\u4e00\u6587\u4ef6\u5173\u8054\u3002 \u901a\u8fc7\u4e0d\u540c\u7684\u6587\u4ef6\u540d\u8bbf\u95ee\u65f6\uff0c\u6240\u505a\u7684\u4efb\u4f55\u66f4\u6539\u90fd\u662f\u9488\u5bf9\u6e90\u6587\u4ef6\u6570\u636e\u3002 \u7b26\u53f7\u94fe\u63a5 \uff08Symbolic links\uff09: \u7b26\u53f7\u94fe\u63a5\u5305\u542b\u4e00\u4e2a\u6587\u672c\u5b57\u7b26\u4e32\uff0c\u64cd\u4f5c\u7cfb\u7edf\u5c06\u5176\u89e3\u91ca\u4e3a\u53e6\u4e00\u4e2a\u6587\u4ef6\u6216\u76ee\u5f55\u3002 \u5b83\u672c\u8eab\u5c31\u662f\u4e00\u4e2a\u6587\u4ef6\uff0c\u53ef\u4ee5\u72ec\u7acb\u4e8e\u76ee\u6807\u800c\u5b58\u5728\u3002 \u5982\u679c\u5220\u9664\u4e86\u7b26\u53f7\u94fe\u63a5\uff0c\u5219\u5176\u76ee\u6807\u6587\u4ef6\u6216\u76ee\u5f55\u4e0d\u53d7\u5f71\u54cd\u3002 \u5982\u679c\u79fb\u52a8\uff0c\u91cd\u547d\u540d\u6216\u5220\u9664\u76ee\u6807\u6587\u4ef6\u6216\u76ee\u5f55\uff0c\u5219\u7528\u4e8e\u6307\u5411\u5b83\u7684\u4efb\u4f55\u7b26\u53f7\u94fe\u63a5\u5c06\u7ee7\u7eed\u5b58\u5728\uff0c\u4f46\u6307\u5411\u7684\u662f\u4e00\u4e2a\u4e0d\u5b58\u5728\u7684\u6587\u4ef6\u3002 \u4ec5\u5f53\u6587\u4ef6\u548c\u94fe\u63a5\u6587\u4ef6\u4f4d\u4e8e\u540c\u4e00\u6587\u4ef6\u7cfb\u7edf\uff08\u5728\u540c\u4e00\u5206\u533a\u4e0a\uff09\u65f6\uff0c\u624d\u80fd\u4f7f\u7528\u786c\u94fe\u63a5\uff0c\u56e0\u4e3ainode\u7f16\u53f7\u5728\u540c\u4e00\u6587\u4ef6\u7cfb\u7edf\u4e2d\u4ec5\u662f\u552f\u4e00\u7684\u3002 \u53ef\u4ee5\u4f7f\u7528 ln \u547d\u4ee4\u521b\u5efa\u786c\u94fe\u63a5\uff0c\u6307\u5411\u5df2\u5b58\u5728\u6587\u4ef6\u7684inode\uff0c\u53ef\u4ee5\u901a\u8fc7\u6587\u4ef6\u540d\u6216\u8005\u786c\u94fe\u63a5\u540d\u8bbf\u95ee\u6587\u4ef6\u3002 \u53ef\u4ee5\u4f7f\u7528 ln -s \u9009\u9879\u521b\u5efa\u7b26\u53f7\u94fe\u63a5\u3002 \u4e00\u4e2a\u7b26\u53f7\u94fe\u63a5\u4f1a\u88ab\u5206\u914d\u4e00\u4e2a\u5355\u72ec\u7684inode\uff0c\u5e76\u6307\u5411\u4e00\u4e2a\u6587\u4ef6\uff0c\u6240\u4ee5\u53ef\u4ee5\u660e\u663e\u533a\u5206\u7b26\u53f7\u94fe\u63a5\u6587\u4ef6\u548c\u5b9e\u9645\u6587\u4ef6\u3002 \u6587\u4ef6\u7cfb\u7edf\u672c\u8d28\u4e0a\u662f\u4e00\u4e2a\u7528\u4e8e\u8ddf\u8e2a\u5206\u533a\u5377\u4e2d\u7684\u6587\u4ef6\u7684\u6570\u636e\u5e93\u3002 \u5bf9\u4e8e\u666e\u901a\u6587\u4ef6\uff0c\u5206\u914d\u6570\u636e\u5757\u4ee5\u5b58\u50a8\u6587\u4ef6\u7684\u6570\u636e\uff0c\u5206\u914dinode\u4ee5\u6307\u5411\u6570\u636e\u5757\u4ee5\u53ca\u5b58\u50a8\u5173\u4e8e\u6587\u4ef6\u7684\u5143\u6570\u636e\uff0c\u7136\u540e\u5c06\u6587\u4ef6\u540d\u5206\u914d\u7ed9inode\u3002 \u786c\u94fe\u63a5\u662f\u4e0e\u73b0\u6709inode\u5173\u8054\u7684\u8f85\u52a9\u6587\u4ef6\u540d\u3002 \u5bf9\u4e8e\u7b26\u53f7\u94fe\u63a5\uff0c\u5c06\u4e3a\u65b0\u7684inode\u5206\u914d\u4e00\u4e2a\u4e0e\u4e4b\u5173\u8054\u7684\u65b0\u6587\u4ef6\u540d\uff0c\u4f46inode\u5f15\u7528\u53e6\u4e00\u4e2a\u6587\u4ef6\u540d\u800c\u4e0d\u662f\u5f15\u7528\u6570\u636e\u5757\u3002 \u67e5\u770b\u6587\u4ef6\u540d\u548cinode\u4e4b\u95f4\u5173\u7cfb\u7684\u4e00\u4e2a\u65b9\u6cd5\u662f\u4f7f\u7528 ls -il \u547d\u4ee4\u3002inode\u7684\u5178\u578b\u5927\u5c0f\u4e3a128\u4f4d\uff0c\u6570\u636e\u5757\u7684\u5927\u5c0f\u8303\u56f4\u53ef\u4ee5\u662f1k\uff0c2k\uff0c4k\u6216\u66f4\u5927\uff0c\u5177\u4f53\u53d6\u51b3\u4e8e\u6587\u4ef6\u7cfb\u7edf\u7c7b\u578b\u3002 \u8f6f\u8fde\u63a5\u53ef\u4ee5\u9488\u5bf9\u76ee\u5f55\uff0c\u786c\u8fde\u63a5\u53ea\u80fd\u9488\u5bf9\u6587\u4ef6\u3002 \u786c\u94fe\u63a5\u76f8\u5f53\u4e8e\u589e\u52a0\u4e86\u4e00\u4e2a\u767b\u8bb0\u9879\uff0c\u4f7f\u5f97\u539f\u6765\u7684\u6587\u4ef6\u591a\u4e86\u4e00\u4e2a\u540d\u5b57\uff0c\u81f3\u4e8einode\u90fd\u6ca1\u53d8\u3002\u6240\u8c13\u7684\u767b\u8bb0\u9879\u5176\u5b9e\u662f\u76ee\u5f55\u6587\u4ef6\u4e2d\u7684\u4e00\u4e2a\u6761\u76ee(\u76ee\u5f55\u9879)\uff0c\u4f7f\u7528hard link \u662f\u8ba9\u591a\u4e2a\u4e0d\u540c\u7684\u76ee\u5f55\u9879\u6307\u5411\u540c\u4e00\u4e2a\u6587\u4ef6\u7684inode\uff0c\u6ca1\u6709\u591a\u4f59\u7684\u5185\u5bb9\u9700\u8981\u5b58\u50a8\u5728\u78c1\u76d8\u6247\u533a\u4e2d\uff0c\u6240\u4ee5hardlink\u4e0d\u5360\u7528\u989d\u5916\u7684\u7a7a\u95f4\u3002 \u7b26\u53f7\u94fe\u63a5\u6709\u5355\u72ec\u7684inode\uff0c\u5728inode\u4e2d\u5b58\u653e\u53e6\u4e00\u4e2a\u6587\u4ef6\u7684\u8def\u5f84\u800c\u4e0d\u662f\u6587\u4ef6\u6570\u636e\uff0c\u6240\u4ee5\u7b26\u53f7\u94fe\u63a5\u4f1a\u5360\u7528\u989d\u5916\u7684\u7a7a\u95f4\u3002 \u7279\u5f81 \u786c\u94fe\u63a5 \u7b26\u53f7\u94fe\u63a5 \u672c\u8d28 \u540c\u4e00\u4e2a\u6587\u4ef6 \u4e0d\u662f\u540c\u4e00\u4e2a\u6587\u4ef6 \u8de8\u8bbe\u5907 \u4e0d\u652f\u6301 \u652f\u6301 inode \u76f8\u540c \u4e0d\u540c \u94fe\u63a5\u6570 \u521b\u5efa\u786c\u94fe\u63a5\uff0c\u94fe\u63a5\u6570\u4f1a\u589e\u52a0\uff0c\u5220\u9664\u5219\u51cf\u5c11 \u521b\u5efa\u6216\u5220\u9664\uff0c\u94fe\u63a5\u6570\u90fd\u4e0d\u53d8 \u6587\u4ef6\u5939 \u4e0d\u652f\u6301 \u652f\u6301 \u76f8\u5bf9\u8def\u5f84 \u539f\u59cb\u6587\u4ef6\u7684\u76f8\u5bf9\u8def\u5f84\u662f\u76f8\u5bf9\u4e8e\u5f53\u524d\u5de5\u4f5c\u76ee\u5f55 \u539f\u59cb\u6587\u4ef6\u7684\u76f8\u5bf9\u8def\u5f84\u662f\u76f8\u5bf9\u4e8e\u94fe\u63a5\u6587\u4ef6\u7684\u76f8\u5bf9\u8def\u5f84 \u5220\u9664\u6e90\u6587\u4ef6 \u53ea\u662f\u94fe\u63a5\u6570\u51cf\u5c11\uff0c\u94fe\u63a5\u6587\u4ef6\u8bbf\u95ee\u4e0d\u53d7\u5f71\u54cd \u94fe\u63a5\u6587\u4ef6\u5c06\u65e0\u6cd5\u8bbf\u95ee \u6587\u4ef6\u7c7b\u578b \u548c\u6e90\u6587\u4ef6\u76f8\u540c \u94fe\u63a5\u6587\u4ef6\uff0c\u548c\u6e90\u6587\u4ef6\u65e0\u5173 \u6587\u4ef6\u5927\u5c0f \u548c\u6e90\u6587\u4ef6\u76f8\u540c \u6e90\u6587\u4ef6\u7684\u8def\u5f84\u7684\u957f\u5ea6 3.3.\u8bbe\u5907\u6587\u4ef6 \u00b6 \u8bbe\u5907\u6587\u4ef6 \uff08Device File\uff09\u8868\u793a\u786c\u4ef6\uff08\u7f51\u5361\u9664\u5916\uff09\u3002 \u6bcf\u4e2a\u786c\u4ef6\u90fd\u7531\u4e00\u4e2a\u8bbe\u5907\u6587\u4ef6\u8868\u793a\u3002 \u7f51\u5361\u662f\u63a5\u53e3\u3002 \u8bbe\u5907\u6587\u4ef6\u628a\u5185\u6838\u9a71\u52a8\u548c\u7269\u7406\u786c\u4ef6\u8bbe\u5907\u8fde\u63a5\u8d77\u6765\u3002 \u5185\u6838\u9a71\u52a8\u7a0b\u5e8f\u901a\u8fc7\u5bf9\u8bbe\u5907\u6587\u4ef6\u8fdb\u884c\u8bfb\u5199\uff08\u6b63\u786e\u7684\u683c\u5f0f\uff09\u6765\u5b9e\u73b0\u5bf9\u786c\u4ef6\u7684\u8bfb\u5199\u3002 \u7c7b\u578b\uff1a \u5757\u8bbe\u5907\uff08Block Devices\uff09\uff1a\u5757\u8bbe\u5907\uff08\u901a\u5e38\uff09\u5728512\u5b57\u8282\u7684\u5927\u5757\u4e2d\u8bfb\u53d6/\u5199\u5165\u4fe1\u606f\u3002 \u5b57\u7b26\u8bbe\u5907\uff08Character Devices\uff09\uff1a\u5b57\u7b26\u8bbe\u5907\u4ee5\u5b57\u7b26\u65b9\u5f0f\u8bfb\u53d6/\u5199\u5165\u4fe1\u606f\u3002 \u5b57\u7b26\u8bbe\u5907\u76f4\u63a5\u63d0\u4f9b\u5bf9\u786c\u4ef6\u8bbe\u5907\u7684\u65e0\u7f13\u51b2\u8bbf\u95ee\u3002 \u6709\u65f6\u79f0\u4e3a\u88f8\u8bbe\u5907\uff08raw devices\uff09\u3002\uff08\u6ce8\u610f\uff1a\u88f8\u8bbe\u5907\u88ab\u89c6\u4e3a\u5b57\u7b26\u8bbe\u5907\uff0c\u4e0d\u662f\u5757\u8bbe\u5907\uff09 \u901a\u8fc7\u8f85\u4ee5\u4e0d\u540c\u9009\u9879\uff0c\u53ef\u4ee5\u5e7f\u6cdb\u800c\u591a\u6837\u5730\u5e94\u7528\u548c\u4f7f\u7528\u5b57\u7b26\u8bbe\u5907\u3002 \u5f53\u5185\u6838\u53d1\u73b0\u8bbe\u5907\u65f6\u7531\u64cd\u4f5c\u7cfb\u7edf udev \u81ea\u52a8\u521b\u5efa\u3002 3.4.\u7ec3\u4e60 \u00b6 \u76ee\u6807\uff1a\u4ee5Rocky 9\u4e3a\u4f8b\u3002 \u67e5\u770b\u8f6f/\u786c\u94fe\u63a5\u6587\u4ef6\u7684\u7279\u5f81\u3002 \u67e5\u770b\u76ee\u5f55\u7ed3\u6784\u3002 \u53ef\u4ee5\u901a\u8fc7\u4e0b\u9762\u547d\u4ee4\u5f97\u5230\u5f53\u524d\u7cfb\u7edf\u76842\u7ea7\u76ee\u5f55\u7684\u7ed3\u6784\u3002 tree -L 2 -d / \u521b\u5efa\u7ec3\u4e60\u76ee\u5f55\u3002 mkdir data mkdir -p data/typelink cd data \u521b\u5efa\u786c\u94fe\u63a5\u3002\u6ce8\u610f\uff1a file \u3001 hardlinkfile1 \u3001 hardlinkfile2 \u6587\u4ef6\u7684\u94fe\u63a5\u4f4d\u7f6e\u7684\u6570\u503c\u7684\u53d8\u5316) echo \"it's original file\" > file ln file hardlinkfile1 ln -s file symlinkfile1 ln -s file symlinkfile2 \u6267\u884c ls -l \u547d\u4ee4\u53ef\u4ee5\u5f97\u5230\u4e0b\u9762\u7684\u7ed3\u679c\uff1a -rw-r--r--. 2 vagrant wheel 19 Nov 1 10 :42 file -rw-r--r--. 2 vagrant wheel 19 Nov 1 10 :42 hardlinkfile1 lrwxrwxrwx. 1 vagrant wheel 4 Nov 1 10 :43 symlinkfile1 -> file lrwxrwxrwx. 1 vagrant wheel 4 Nov 1 10 :43 symlinkfile2 -> file \u521b\u5efa\u53e6\u5916\u4e00\u4e2a\u786c\u94fe\u63a5\u3002 ln file hardlinkfile2 \u6267\u884c ls -l \u547d\u4ee4\u53ef\u4ee5\u5f97\u5230\u4e0b\u9762\u7684\u7ed3\u679c\uff1a -rw-r--r--. 3 vagrant wheel 19 Nov 1 10 :42 file -rw-r--r--. 3 vagrant wheel 19 Nov 1 10 :42 hardlinkfile1 -rw-r--r--. 3 vagrant wheel 19 Nov 1 10 :42 hardlinkfile2 lrwxrwxrwx. 1 vagrant wheel 4 Nov 1 10 :43 symlinkfile1 -> file lrwxrwxrwx. 1 vagrant wheel 4 Nov 1 10 :43 symlinkfile2 -> file \u4fee\u6539 file \u6587\u4ef6\u7684\u5185\u5bb9\u3002 echo \"add oneline\" >> file \u901a\u8fc7\u547d\u4ee4 cat file \u67e5\u770b\u5f53\u524d file \u7684\u5185\u5bb9\u3002 it ' s original file add oneline \u901a\u8fc7\u4e0b\u9762\u7684\u547d\u4ee4\uff0c\u53ef\u4ee5\u770b\u5230\u6240\u4ee5\u8f6f/\u786c\u94fe\u63a5\u6587\u4ef6\u5185\u5bb9\u90fd\u66f4\u65b0\u4e86\uff0c\u548c file \u6587\u4ef6\u66f4\u65b0\u540e\u7684\u5185\u5bb9\u4fdd\u6301\u4e00\u81f4\u3002 cat hardlinkfile1 cat hardlinkfile2 cat symlinkfile1 cat symlinkfile2 \u5bf9\u6587\u4ef6 symlinkfile1 \u518d\u521b\u5efa\u65b0\u7684\u8f6f\u8fde\u63a5\u3002 ln -s symlinkfile1 symlinkfile1-1 \u901a\u8fc7\u547d\u4ee4 ls -il \u67e5\u770b\u73b0\u5728\u7684\u76ee\u5f55\u4fe1\u606f\u3002 67274680 -rw-r--r--. 3 vagrant wheel 31 Nov 1 11 :14 file 67274680 -rw-r--r--. 3 vagrant wheel 31 Nov 1 11 :14 hardlinkfile1 67274680 -rw-r--r--. 3 vagrant wheel 31 Nov 1 11 :14 hardlinkfile2 67274681 lrwxrwxrwx. 1 vagrant wheel 4 Nov 1 10 :43 symlinkfile1 -> file 67274683 lrwxrwxrwx. 1 vagrant wheel 12 Nov 1 11 :20 symlinkfile1-1 -> symlinkfile1 67274682 lrwxrwxrwx. 1 vagrant wheel 4 Nov 1 10 :43 symlinkfile2 -> file \u8bfb\u53d6\u8f6f\u94fe\u63a5\u6587\u4ef6\u7684\u6e90\u6587\u4ef6\u4fe1\u606f readlink symlinkfile1 readlink symlinkfile2 \u6ce8\u610f\uff0c\u5bf9\u4e8e symlinkfile1-1 \u7684\u60c5\u51b5\u6709\u4e9b\u4e0d\u540c\u3002 readlink symlinkfile1-1 \u4e0a\u9762\u547d\u4ee4\u8fd4\u56de\u7ed3\u679c symlinkfile1 \u4ecd\u7136\u662f\u4e00\u4e2a\u7b26\u53f7\u94fe\u63a5\u6587\u4ef6\u3002\u901a\u8fc7 readlink -f \u53ef\u4ee5\u76f4\u63a5\u5b9a\u4f4d\u771f\u6b63\u7684\u6e90\u6587\u4ef6\u3002 readlink -f symlinkfile1-1 \u4e0a\u9762\u7684\u8fd4\u56de\u7ed3\u679c /data/linktype/file \u662f symlinkfile1-1 \u771f\u6b63\u7684\u6e90\u6587\u4ef6\u3002 \u663e\u793a data \u76ee\u5f55\u4e0b\u7684\u6587\u4ef6\u548c\u5b50\u76ee\u5f55\uff1a cd ~ tree ./data \u8fd0\u884c\u7ed3\u679c\uff1a ./data \u251c\u2500\u2500 file \u251c\u2500\u2500 hardlinkfile1 \u251c\u2500\u2500 hardlinkfile2 \u251c\u2500\u2500 symlinkfile1 -> file \u251c\u2500\u2500 symlinkfile1-1 -> symlinkfile1 \u251c\u2500\u2500 symlinkfile2 -> file \u2514\u2500\u2500 typelink \u53ea\u663e\u793a data \u76ee\u5f55\u4e0b\u7684\u5b50\u76ee\u5f55\uff1a tree -d ./data \u8fd0\u884c\u7ed3\u679c\uff1a ./data \u2514\u2500\u2500 typelink \u663e\u793a data \u76ee\u5f55\u4e0b\u7684\u6587\u4ef6\u548c\u5b50\u76ee\u5f55\uff0c\u5305\u542b\u5168\u76ee\u5f55\uff1a tree -f ./data \u8fd0\u884c\u7ed3\u679c\uff1a ./data \u251c\u2500\u2500 ./data/file \u251c\u2500\u2500 ./data/hardlinkfile1 \u251c\u2500\u2500 ./data/hardlinkfile2 \u251c\u2500\u2500 ./data/symlinkfile1 -> file \u251c\u2500\u2500 ./data/symlinkfile1-1 -> symlinkfile1 \u251c\u2500\u2500 ./data/symlinkfile2 -> file \u2514\u2500\u2500 ./data/typelink 4.\u6587\u4ef6\u5c5e\u6027\u8bf4\u660e \u00b6 \u6267\u884c\u547d\u4ee4 ls -ihl \uff0c\u53ef\u4ee5\u5f97\u5230\u4e0b\u9762\u7684\u8f93\u51fa\u7ed3\u679c\uff08Rocky 9\uff09\u3002 67274680 -rw-r--r--. 3 vagrant wheel 31 Nov 1 11 :14 file 67274680 -rw-r--r--. 3 vagrant wheel 31 Nov 1 11 :14 hardlinkfile1 67274680 -rw-r--r--. 3 vagrant wheel 31 Nov 1 11 :14 hardlinkfile2 67274681 lrwxrwxrwx. 1 vagrant wheel 4 Nov 1 10 :43 symlinkfile1 -> file 67274683 lrwxrwxrwx. 1 vagrant wheel 12 Nov 1 11 :20 symlinkfile1-1 -> symlinkfile1 67274682 lrwxrwxrwx. 1 vagrant wheel 4 Nov 1 10 :43 symlinkfile2 -> file 33555262 drwxr-xr-x. 2 vagrant wheel 6 Nov 1 11 :30 typelink \u4ee5 67274680 -rw-r--r--. 3 vagrant wheel 31 Nov 1 11:14 file \u4e3a\u4f8b\uff1a 67274680 : inode \u7d22\u5f15\u8282\u70b9\u7f16\u53f7\u3002 -rw-r--r-- \uff1a\u6587\u4ef6\u7c7b\u578b\u53ca\u6743\u9650 - \uff1a\u6587\u4ef6\u7c7b\u578b\uff0c\u4f8b\u5b50\u4e2d\u51fa\u73b0\u4e86\u4e09\u79cd\uff0c - \uff0c l \u548c d \u3002 - \uff1a\u666e\u901a\u6587\u4ef6 d \uff1a\u76ee\u5f55 l \uff1a\u7b26\u53f7\u94fe\u63a5\u6587\u4ef6\uff08link\uff09 b \uff1a\u5757\u8bbe\u5907\uff08block\uff09 c \uff1a\u5b57\u7b26\u8bbe\u5907\uff08character\uff09 p \uff1a\u7ba1\u9053\u6587\u4ef6\uff08pipe\uff09 s \uff1a\u5957\u63a5\u5b57\u6587\u4ef6\uff08socket\uff09 rw-r--r-- \uff1a\u6587\u4ef6\u6743\u9650\uff0c\u4ece\u5de6\u5230\u53f3\u4f9d\u6b21\u4e3a\uff1a rw- \uff1a\u6587\u4ef6\u5c5e\u4e3b\u6743\u9650\uff0c\u4f8b\u5b50\u4e2d\u662f vagrant \u3002 r-- \uff1a\u6587\u4ef6\u5c5e\u7ec4\u7684\u6743\u9650\uff0c\u4f8b\u5b50\u4e2d\u662f wheel \u3002 r-- \uff1a\u5176\u4ed6\u7ec4\u7684\u6743\u9650\u3002 . \uff1a\u8fd9\u4e2a\u70b9\u8868\u793a\u6587\u4ef6\u5e26\u6709SELinux\u7684\u5b89\u5168\u4e0a\u4e0b\u6587\uff08SELinux Contexts\uff09\u3002\u5173\u95edSELinux\uff0c\u65b0\u521b\u5efa\u7684\u6587\u4ef6\u5c31\u4e0d\u4f1a\u518d\u6709\u8fd9\u4e2a\u70b9\u4e86\u3002\u4f46\u662f\uff0c\u4ee5\u524d\u521b\u5efa\u7684\u6587\u4ef6\u672c\u6765\u6709\u8fd9\u4e2a\u70b9\u7684\u8fd8\u4f1a\u663e\u793a\u8fd9\u4e2a\u70b9\uff08\u867d\u7136SELinux\u4e0d\u8d77\u4f5c\u7528\u4e86\uff09\u3002 3 \uff1a\u786c\u94fe\u63a5\u6570\uff0c\u4f8b\u5b50\u4e2d file \u548c hardlinkfile1 \u548c hardlinkfile2 \u4e4b\u95f4\u662f\u786c\u94fe\u63a5\uff0c\u6240\u4ee5\u8fd9\u4e09\u4e2a\u6587\u4ef6\u7684\u786c\u94fe\u63a5\u6570\u90fd\u662f 3 \u3002 vagrant \uff1a\u6587\u4ef6\u5c5e\u4e3b wheel \uff1a\u6587\u4ef6\u5c5e\u7ec4 31 \uff1a\u6587\u4ef6\u6216\u76ee\u5f55\u7684\u5927\u5c0f Nov 1 11:14 \uff1a\u6587\u4ef6\u6216\u76ee\u5f55\u7684\u521b\u5efa\u65e5\u671f\u548c\u65f6\u95f4 file \uff1a\u6587\u4ef6\u6216\u76ee\u5f55\u540d\u79f0 \u4e0b\u9762\u662f\u547d\u4ee4 ls -ihl \u5728openSUSE\u548cUbuntu\u4e0a\u7684\u663e\u793a\u7ed3\u679c\u3002 $ ls -ihl 233647 -rw-r--r-- 3 vagrant wheel 31 Nov 1 15 :52 file 233647 -rw-r--r-- 3 vagrant wheel 31 Nov 1 15 :52 hardlinkfile1 233647 -rw-r--r-- 3 vagrant wheel 31 Nov 1 15 :52 hardlinkfile2 233648 lrwxrwxrwx 1 vagrant wheel 4 Nov 1 15 :52 symlinkfile1 -> file 233650 lrwxrwxrwx 1 vagrant wheel 12 Nov 1 15 :52 symlinkfile1-1 -> symlinkfile1 233649 lrwxrwxrwx 1 vagrant wheel 4 Nov 1 15 :52 symlinkfile2 -> file 233646 drwxr-xr-x 1 vagrant wheel 0 Nov 1 15 :51 typelink 5.\u6807\u51c6\u8f93\u5165\u8f93\u51fa \u00b6 \u6807\u51c6\u8f93\u5165\u8f93\u51fa\uff0c\u5373I/O\uff0cI/O\u7684I\u662fInput\uff0cO\u662foutput\u3002 I\uff1a\u4ece\u5916\u90e8\u8bbe\u5907\u8f93\u5165\u5230\u5185\u5b58 O\uff1a\u4ece\u5185\u5b58\u8f93\u51fa\u5230\u5916\u90e8\u8bbe\u5907 \u6807\u51c6\u8f93\u5165\u548c\u6807\u51c6\u8f93\u51fa\u662f\u7528\u4e8eIO\u7684\uff0c\u5b83\u4eec\u5c5e\u4e8e\u5916\u90e8\u8bbe\u5907\uff08\u903b\u8f91\u4e0a\u7684\u5916\u90e8\u8bbe\u5907\uff09\uff0c\u4e0d\u662f\u5185\u5b58\u3002 linux\u4e2d\u4e00\u5207\u8bbe\u5907\u7686\u662f\u6587\u4ef6\uff01\u56e0\u6b64\u6807\u51c6\u8f93\u5165\u548c\u8f93\u51fa\u672c\u8d28\u5c31\u662f\u6587\u4ef6\uff0c\u5916\u90e8\u8bbe\u5907\u4ee5\u6587\u4ef6\u5f62\u5f0f\u8868\u73b0\u3002 \u5728Linux\u7cfb\u7edf\u4e2d\uff0c\u6807\u51c6\u8f93\u5165\u548c\u6807\u51c6\u8f93\u51fa\u5bf9\u5e94\u7684\u6587\u4ef6\u662f /dev/stdin \u548c /dev/stdout \u8fd9\u4e24\u4e2a\u6587\u4ef6\u3002 \u4ece\u6807\u51c6\u8f93\u5165\u8bfb\uff0c\u4ece\u903b\u8f91\u4e0a\u8bb2\uff0c\u5c31\u662f\u6253\u5f00 /dev/stdin \u8fd9\u4e2a\u6587\u4ef6\uff0c\u5e76\u8bfb\u5165\u6587\u4ef6\u5185\u5bb9\u3002 \u8f93\u51fa\u5230\u6807\u51c6\u8f93\u51fa\uff0c\u4ece\u903b\u8f91\u4e0a\u8bb2\uff0c\u5c31\u662f\u6253\u5f00 /dev/stdout \u8fd9\u4e2a\u6587\u4ef6\uff0c\u5e76\u628a\u5185\u5bb9\u8f93\u51fa\u5230\u8fd9\u4e2a\u6587\u4ef6\u91cc\u53bb\u3002 \u8fd9\u91cc\u5f3a\u8c03\u7684\u662f\u201c\u903b\u8f91\u4e0a\u201d\uff0c\u56e0\u4e3a /dev/stdin \u548c /dev/stdout \u8fd92\u4e2a\u6587\u4ef6\u672c\u8eab\u4e0d\u662f\u8bbe\u5907\u6587\u4ef6\u3002Linux\u4e2d\u8bbe\u5907\u662f\u6587\u4ef6\uff0c\u4f46\u662f\u6587\u4ef6\u4e0d\u4e00\u5b9a\u662f\u8bbe\u5907\u3002 \u56e0\u6b64\uff0c\u64cd\u4f5c /dev/stdin \u548c/dev/stdout`\u8fd92\u4e2a\u6587\u4ef6\uff0c\u5b9e\u9645\u4e0a\u662f\u64cd\u4f5c\u4e24\u4e2a\u6587\u4ef6\u5b58\u653e\u5730\u5740\u5bf9\u5e94\u7684\u8bbe\u5907\u6587\u4ef6\u3002 \u901a\u8fc7\u4e0b\u9762\u547d\u4ee4\u53ef\u4ee5\u770b\u5230\u6807\u51c6\u8f93\u5165\u8f93\u51fa\u6587\u4ef6\u7684\u7279\u70b9\uff0c\u4ed6\u4eec\u867d\u7136\u5728 /dev \u76ee\u5f55\u4e0b\uff0c\u90fd\u662f\u4ee5 l \u5f00\u5934\u7684\u94fe\u63a5\u6587\u4ef6\uff0c\u6307\u5411\u7684\u662f\u53e6\u4e00\u4e2a\u6587\u4ef6\u7684\u5730\u5740\u3002 $ ls -l /dev/std* lrwxrwxrwx 1 root root 15 Nov 13 10 :39 /dev/stderr -> /proc/self/fd/2 lrwxrwxrwx 1 root root 15 Nov 13 10 :39 /dev/stdin -> /proc/self/fd/0 lrwxrwxrwx 1 root root 15 Nov 13 10 :39 /dev/stdout -> /proc/self/fd/1 # Rocky $ ll /proc/self/fd/ lrwx------. 1 vagrant wheel 64 Nov 13 22 :38 0 -> /dev/pts/0 lrwx------. 1 vagrant wheel 64 Nov 13 22 :38 1 -> /dev/pts/0 lrwx------. 1 vagrant wheel 64 Nov 13 22 :38 2 -> /dev/pts/0 lr-x------. 1 vagrant wheel 64 Nov 13 22 :38 3 -> /proc/1702/fd # Ubuntu $ ll /proc/self/fd/ lrwx------ 1 vagrant sudo 64 Nov 13 14 :38 0 -> /dev/pts/0 lrwx------ 1 vagrant sudo 64 Nov 13 14 :38 1 -> /dev/pts/0 lrwx------ 1 vagrant sudo 64 Nov 13 14 :38 2 -> /dev/pts/0 lr-x------ 1 vagrant sudo 64 Nov 13 14 :38 3 -> /proc/2062/fd/ # openSUSE $ ll /proc/self/fd/* ls: cannot access '/proc/self/fd/255' : No such file or directory ls: cannot access '/proc/self/fd/3' : No such file or directory lrwx------ 1 vagrant wheel 64 Nov 13 22 :37 /proc/self/fd/0 -> /dev/pts/0 lrwx------ 1 vagrant wheel 64 Nov 13 22 :37 /proc/self/fd/1 -> /dev/pts/0 lrwx------ 1 vagrant wheel 64 Nov 13 22 :37 /proc/self/fd/2 -> /dev/pts/0 Linux\u8fdb\u7a0b\u9ed8\u8ba4\u4f1a\u6253\u5f00\u7684\u4e09\u4e2a\u6587\u4ef6\uff1a \u6807\u51c6\u8f93\u5165 /dev/stdin \uff0c\u63cf\u8ff0\u7b26\u4e3a 0\uff0c\u9ed8\u8ba4\u662f\u952e\u76d8\u8f93\u5165\u3002 \u6807\u51c6\u8f93\u51fa /dev/stdout \uff0c\u63cf\u8ff0\u7b26\u4e3a 1\uff0c\u9ed8\u8ba4\u662f\u8f93\u51fa\u5230\u5c4f\u5e55\u3002 \u6807\u51c6\u8f93\u51fa /dev/stderr \uff0c\u63cf\u8ff0\u7b26\u4e3a 2\uff0c\u9ed8\u8ba4\u662f\u8f93\u51fa\u5230\u5c4f\u5e55\u3002 \u4ee5Rocky\u4e3a\u4f8b\uff0c\u521b\u5efa file.py \u6587\u4ef6\u3002 $ cat > file.py < test.txt \u8fd0\u884c file.py \u7a0b\u5e8f\u3002 python3 file.py \u6253\u5f00\u65b0\u7684\u7ec8\u7aef\u7a97\u53e3\uff0c\u6267\u884c\u4e0b\u9762\u547d\u4ee4\uff0c\u5f97\u5230python3\u8fd9\u4e2a\u7a0b\u5e8f\u8fd0\u884c\u7684process ID\u3002\u5176\u4e2d\u53ef\u4ee5\u770b\u5230\u6709\u4e00\u4e2a\u6765\u81ea\u6587\u4ef6test.txt\u88ab\u7a0b\u5e8ffile.py\u6253\u5f00\uff08\u8f93\u5165\uff09\u3002 $ pidof python3 1739 788 $ sudo ls -l /proc/788/fd/ lr-x------. 1 root root 64 Nov 13 23 :00 0 -> /dev/null l-wx------. 1 root root 64 Nov 13 23 :00 1 -> /dev/null lrwx------. 1 root root 64 Nov 13 23 :00 10 -> 'socket:[24677]' lrwx------. 1 root root 64 Nov 13 23 :00 11 -> 'socket:[24678]' l-wx------. 1 root root 64 Nov 13 23 :00 2 -> /dev/null l-wx------. 1 root root 64 Nov 13 10 :41 3 -> /var/log/firewalld lrwx------. 1 root root 64 Nov 13 23 :00 4 -> 'socket:[23421]' lrwx------. 1 root root 64 Nov 13 23 :00 5 -> 'anon_inode:[eventfd]' lrwx------. 1 root root 64 Nov 13 23 :00 6 -> 'socket:[24586]' lr-x------. 1 root root 64 Nov 13 23 :00 7 -> anon_inode:inotify lrwx------. 1 root root 64 Nov 13 23 :00 8 -> 'anon_inode:[eventfd]' lrwx------. 1 root root 64 Nov 13 23 :00 9 -> '/memfd:libffi (deleted)' $ sudo ls -l /proc/1739/fd/ lrwx------. 1 vagrant wheel 64 Nov 13 23 :00 0 -> /dev/pts/0 lrwx------. 1 vagrant wheel 64 Nov 13 23 :00 1 -> /dev/pts/0 lrwx------. 1 vagrant wheel 64 Nov 13 23 :00 2 -> /dev/pts/0 lr-x------. 1 vagrant wheel 64 Nov 13 23 :00 3 -> /home/vagrant/test.txt \u5728Ubuntu\u4e2d\u8fd0\u884c file.py \u7a0b\u5e8f\uff0cpidof\u4f1a\u53d6\u5f973\u4e2aprocess IDs\u3002 $ pidof python3 2128 924 873 $ sudo ls -l /proc/2128/fd/ lrwx------ 1 vagrant sudo 64 Nov 13 15 :10 0 -> /dev/pts/0 lrwx------ 1 vagrant sudo 64 Nov 13 15 :10 1 -> /dev/pts/0 lrwx------ 1 vagrant sudo 64 Nov 13 15 :10 2 -> /dev/pts/0 lr-x------ 1 vagrant sudo 64 Nov 13 15 :10 3 -> /home/vagrant/test.txt $ sudo ls -l /proc/924/fd/ lr-x------ 1 root root 64 Nov 13 15 :11 0 -> /dev/null lrwx------ 1 root root 64 Nov 13 15 :11 1 -> 'socket:[31593]' lrwx------ 1 root root 64 Nov 13 15 :11 2 -> 'socket:[31593]' l-wx------ 1 root root 64 Nov 13 02 :40 3 -> /var/log/unattended-upgrades/unattended-upgrades-shutdown.log lrwx------ 1 root root 64 Nov 13 15 :11 4 -> 'socket:[31652]' lrwx------ 1 root root 64 Nov 13 15 :11 5 -> 'anon_inode:[eventfd]' lrwx------ 1 root root 64 Nov 13 15 :11 6 -> 'anon_inode:[eventfd]' lrwx------ 1 root root 64 Nov 13 15 :11 7 -> 'socket:[31657]' l-wx------ 1 root root 64 Nov 13 15 :11 8 -> /run/systemd/inhibit/1.ref lrwx------ 1 root root 64 Nov 13 15 :11 9 -> 'socket:[31658]' $ sudo ls -l /proc/873/fd/ lr-x------ 1 root root 64 Nov 13 15 :11 0 -> /dev/null lrwx------ 1 root root 64 Nov 13 15 :11 1 -> 'socket:[31412]' lrwx------ 1 root root 64 Nov 13 15 :11 2 -> 'socket:[31412]' lrwx------ 1 root root 64 Nov 13 02 :40 3 -> 'socket:[31650]' lrwx------ 1 root root 64 Nov 13 15 :11 4 -> 'anon_inode:[eventfd]' lrwx------ 1 root root 64 Nov 13 15 :11 5 -> 'socket:[31663]' lrwx------ 1 root root 64 Nov 13 15 :11 6 -> 'socket:[31664]' openSUSE\u9700\u8981\u5b89\u88c5\u5305 sysvinit-tools \u624d\u80fd\u4f7f\u7528 pidof \u547d\u4ee4\u3002 sudo zypper in sysvinit-tools \u7531\u4e8eopenSUSE\u4e2dpidof python3\u53ea\u8fd4\u56de\u4e00\u4e2aprocess ID\uff0c\u6240\u4ee5\u53ef\u4ee5\u7b80\u5316\u547d\u4ee4\u884c\u5f97\u5230process ID\u7684\u8be6\u7ec6\u4fe1\u606f\u3002 $ sudo ls -l /proc/ ` pidof python3 ` /fd/ lrwx------ 1 vagrant wheel 64 Nov 13 23 :21 0 -> /dev/pts/0 lrwx------ 1 vagrant wheel 64 Nov 13 23 :21 1 -> /dev/pts/0 lrwx------ 1 vagrant wheel 64 Nov 13 23 :21 2 -> /dev/pts/0 lr-x------ 1 vagrant wheel 64 Nov 13 23 :21 3 -> /home/vagrant/test.txt \u53c2\u8003\uff1a \u5f53\u952e\u76d8\u548c\u9f20\u6807\u7b49\u8bbe\u5907\u901a\u8fc7\u4e32\u53e3\u76f4\u63a5\u8fde\u63a5\u5230\u8ba1\u7b97\u673a\u65f6\uff0c\u8fd9\u79cd\u8fde\u63a5\u79f0\u4e3aTTY\u3002 \u4f2a\u7ec8\u7aefpseudoterminal\uff08\u7f29\u5199\u4e3a\u201cpty\u201d\uff09\u662f\u4e00\u5bf9\u63d0\u4f9b\u53cc\u5411\u901a\u4fe1\u901a\u9053\u7684\u865a\u62df\u5b57\u7b26\u8bbe\u5907\u3002 \u901a\u9053\u7684\u4e00\u7aef\u79f0\u4e3a\u4e3b\u7aefmaster\uff1b \u53e6\u4e00\u7aef\u79f0\u4e3a\u4ece\u7aefslave\u3002 /dev/pts \u8868\u793a\u4e0e\u4f2a\u7ec8\u7aefpseudoterminal\u7684\u4e3b\u7aefmaster\u6216\u4ece\u7aefslave\u76f8\u5173\u7684master\u6587\u4ef6\uff0c\u64cd\u4f5c\u7cfb\u7edf\u5c06\u5176\u4fdd\u5b58\u4e3a /dev/ptmx \u6587\u4ef6\u3002 telnet \u548c ssh \u7b49\u7a0b\u5e8f\u80fd\u591f\u4eff \u7aef\u7528\u6237> \u4e0e\u5b83\u4eec\u7684\u4ea4\u4e92\uff0c\u867d\u7136\u672c\u8d28\u4e0a\u662f\u4e0e\u6587\u4ef6 /dev/ptmx \u8fdb\u884c\u4ea4\u4e92\uff0c\u4f46\u5448\u73b0\u7ed9\u7528\u6237\u7684\u5374\u662f\u597d\u50cf\u8fd0\u884c\u5728\u771f\u6b63\u7684\u7ec8\u7aef\u7a97\u53e3\u4e00\u6837\uff0c\u4ece\u7aef\u7684\u6587\u4ef6\u662f\u4e3b\u7aef\u7684\u8f93\u5165\u3002 \u4f2a\u7ec8\u7aef\u8fdb\u7a0b\u5728Linux\u4e2d\u88ab\u5b58\u50a8\u5728 /dev/pts/ \u76ee\u5f55\u4e0b\u3002 /dev/pts/ \u76ee\u5f55\u4e0b\u7684\u5185\u5bb9\u662f\u4e00\u4e9b\u7279\u6b8a\u7684\u76ee\u5f55\uff0c\u7531Linux\u5185\u6838\u6240\u521b\u5efa\u3002 \u6bcf\u4e2a\u552f\u4e00\u7684\u7ec8\u7aef\u7a97\u53e3\u90fd\u4e0e /dev/pts \u7cfb\u7edf\u4e2d\u7684\u4e00\u4e2aLinux pts \u6761\u76ee\u76f8\u5173\u3002 \u4e0b\u9762\u8fd4\u56de\u7684\u7ed3\u679c\u8bf4\u660e\u67092\u4e2a\u8fdc\u7a0b\u7ec8\u7aef\u8fde\u63a5\u5230\u5f53\u524d\u7684\u673a\u5668\u3002 $ ll /dev/pts/ crw--w----. 1 vagrant tty 136 , 0 Nov 13 23 :18 0 crw--w----. 1 vagrant tty 136 , 1 Nov 13 23 :48 1 c---------. 1 root root 5 , 2 Nov 13 10 :41 ptmx \u4e5f\u53ef\u4ee5\u901a\u8fc7 w \u547d\u4ee4\u770b\u52302\u4e2a\u7ec8\u7aef\u8fdb\u7a0b\u3002 $ w 23 :55:05 up 13 :14, 2 users, load average: 0 .00, 0 .00, 0 .00 USER TTY LOGIN@ IDLE JCPU PCPU WHAT vagrant pts/0 10 :51 37 :03 0 .05s 0 .05s -bash vagrant pts/1 23 :48 0 .00s 0 .03s 0 .00s w \u5355\u4e2a\u4f2a\u7ec8\u7aefpseudoterminal\u53ef\u4ee5\u540c\u65f6\u63a5\u6536\u6765\u81ea\u4e0d\u540c\u7684\u7a0b\u5e8f\u7684\u8f93\u51fa\u3002 \u591a\u4e2a\u7a0b\u5e8f\u540c\u65f6\u5bf9\u4e00\u4e2a\u4f2a\u7ec8\u7aefpseudoterminal\u8fdb\u884c\u8bfb\u53d6\u4f1a\u5f15\u8d77\u6df7\u6dc6\u3002 \u5b58\u50a8\u5728 /dev/pts \u76ee\u5f55\u4e2d\u7684\u6587\u4ef6\u662f\u62bd\u8c61\u6587\u4ef6\u800c\u4e0d\u662f\u771f\u5b9e\u6587\u4ef6\uff0c\u662f\u4f2a\u7ec8\u7aef\u4e2d\u6267\u884c\u7a0b\u5e8f\u65f6\u4e34\u65f6\u5b58\u50a8\u7684\u6570\u636e\u3002 \u6253\u5f00 /dev/pts \u4e0b\u7684\u6587\u4ef6\u901a\u5e38\u6ca1\u6709\u4ec0\u4e48\u5b9e\u9645\u610f\u4e49\u3002 6.\u91cd\u5b9a\u5411\u548c\u7ba1\u9053 \u00b6 6.1.\u8f93\u5165\u91cd\u5b9a\u5411 \u00b6 \u5e38\u7528\u547d\u4ee4\u683c\u5f0f\uff1a command < file \uff1a\u5c06\u6307\u5b9a\u6587\u4ef6 file \u4f5c\u4e3a\u547d\u4ee4\u7684\u8f93\u5165\u8bbe\u5907\u3002 command << delimiter \uff1a\u8868\u793a\u4ece\u6807\u51c6\u8f93\u5165\u8bbe\u5907\uff08\u952e\u76d8\uff09\u4e2d\u8bfb\u5165\uff0c\u76f4\u5230\u9047\u5230\u5206\u754c\u7b26 delimiter \u505c\u6b62\uff08\u8bfb\u5165\u7684\u6570\u636e\u4e0d\u5305\u62ec\u5206\u754c\u7b26\uff09\uff0c\u8fd9\u91cc\u7684\u5206\u754c\u7b26\u53ef\u4ee5\u7406\u89e3\u4e3a\u81ea\u5b9a\u4e49\u7684\u5b57\u7b26\u4e32\u3002 command < file1 > file2 \uff1a\u5c06 file1 \u4f5c\u4e3a\u547d\u4ee4\u7684\u8f93\u5165\u8bbe\u5907\uff0c\u8be5\u547d\u4ee4\u7684\u6267\u884c\u7ed3\u679c\u8f93\u51fa\u5230 file2 \u4e2d\u3002 # \u8f93\u51fa\u6587\u4ef6file.py\u5185\u5bb9\uff08\u8f93\u5165\u8bbe\u5907\u662f\u952e\u76d8\uff09 $ cat file.py # \u8f93\u51fa\u6587\u4ef6file.py\u5185\u5bb9\uff08\u8f93\u5165\u8bbe\u5907\u662f\u6587\u4ef6file.py\uff09 $ cat < file.py # \u6307\u5b9a\u5206\u754c\u7b26\uff08\u8fd9\u91cc\u662fEOF\uff09\uff0c\u8bfb\u53d6\u952e\u76d8\u8f93\u5165\u5185\u5bb9\uff0c\u76f4\u5230\u9047\u5230\u6307\u5b9a\u5206\u754c\u7b26\u4e3a\u6b62\uff0c\u5c06\u6240\u8bfb\u53d6\u7684\u5185\u5bb9\u8f93\u51fa\u5230\u6587\u4ef6file.py\u3002 $ cat > file.py < new.py 6.2.\u8f93\u51fa\u91cd\u5b9a\u5411 \u00b6 \u8f93\u51fa\u91cd\u5b9a\u5411\u5206\u4e3a\u6807\u51c6\u8f93\u51fa\u91cd\u5b9a\u5411\u548c\u9519\u8bef\u8f93\u51fa\u91cd\u5b9a\u5411\u4e24\u79cd\u3002 \u5e38\u7528\u547d\u4ee4\u683c\u5f0f\uff1a command > file \uff1a\u5c06\u547d\u4ee4 command \u6267\u884c\u7684\u6807\u51c6\u8f93\u51fa\u7ed3\u679c\u91cd\u5b9a\u5411\u8f93\u51fa\u5230\u6307\u5b9a\u7684\u6587\u4ef6 file \u4e2d\uff0c\u5982\u679c\u8be5\u6587\u4ef6\u5df2\u5305\u542b\u6570\u636e\uff0c\u4f1a\u6e05\u7a7a\u539f\u6709\u6570\u636e\uff0c\u518d\u5199\u5165\u65b0\u6570\u636e\u3002 command 2> file \uff1a\u5c06\u547d\u4ee4 command \u6267\u884c\u7684\u9519\u8bef\u8f93\u51fa\u7ed3\u679c\u91cd\u5b9a\u5411\u5230\u6307\u5b9a\u7684\u6587\u4ef6 file \u4e2d\uff0c\u5982\u679c\u8be5\u6587\u4ef6\u4e2d\u5df2\u5305\u542b\u6570\u636e\uff0c\u4f1a\u6e05\u7a7a\u539f\u6709\u6570\u636e\uff0c\u518d\u5199\u5165\u65b0\u6570\u636e\u3002 command >> file \uff1a\u5c06\u547d\u4ee4 command \u6267\u884c\u7684\u6807\u51c6\u8f93\u51fa\u7ed3\u679c\u91cd\u5b9a\u5411\u8f93\u51fa\u5230\u6307\u5b9a\u7684\u6587\u4ef6 file \u4e2d\uff0c\u5982\u679c\u8be5\u6587\u4ef6\u5df2\u5305\u542b\u6570\u636e\uff0c\u65b0\u6570\u636e\u5c06\u8ffd\u52a0\u5199\u5165\u5230\u539f\u6709\u5185\u5bb9\u7684\u540e\u9762\u3002 command 2>> file \uff1a\u5c06\u547d\u4ee4 command \u6267\u884c\u7684\u9519\u8bef\u8f93\u51fa\u7ed3\u679c\u91cd\u5b9a\u5411\u5230\u6307\u5b9a\u7684\u6587\u4ef6 file \u4e2d\uff0c\u5982\u679c\u8be5\u6587\u4ef6\u4e2d\u5df2\u5305\u542b\u6570\u636e\uff0c\u65b0\u6570\u636e\u5c06\u8ffd\u52a0\u5199\u5165\u5230\u539f\u6709\u5185\u5bb9\u7684\u540e\u9762\u3002 command >> file 2>&1 \u6216\u8005 command &>> file \uff1a\u5c06\u6807\u51c6\u8f93\u51fa\u6216\u8005\u9519\u8bef\u8f93\u51fa\u5199\u5165\u5230\u6307\u5b9a\u6587\u4ef6 file \u4e2d\uff0c\u5982\u679c\u8be5\u6587\u4ef6\u4e2d\u5df2\u5305\u542b\u6570\u636e\uff0c\u65b0\u6570\u636e\u5c06\u8ffd\u52a0\u5199\u5165\u5230\u539f\u6709\u5185\u5bb9\u7684\u540e\u9762\u3002 \u6ce8\u610f\uff1a\u4e0a\u9762\u7684 file \u53ef\u4ee5\u662f\u4e00\u4e2a\u666e\u901a\u6587\u4ef6\uff0c\u4e5f\u53ef\u4ee5\u4f7f\u7528\u4e00\u4e2a\u7279\u6b8a\u7684\u6587\u4ef6 /dev/null \u3002 /dev/null \u5e76\u4e0d\u4fdd\u5b58\u6570\u636e\uff0c\u88ab\u5199\u5165 /dev/null \u7684\u6570\u636e\u6700\u7ec8\u90fd\u4f1a\u4e22\u5931\u3002 \u4e3e\u4f8b\uff1a2\u4e2apython\u6587\u4ef6\u5b58\u5728\uff0c\u5176\u4ed62\u4e2a\u65e0\u6269\u5c55\u540d\u7684\u6587\u4ef6\u4e0d\u5b58\u5728\u3002 ls file.py > out ls file 2 > out.err ls new.py >> out ls new 2 >> out.err \u53ef\u4ee5\u5f97\u5230\u9884\u671f\u7684\u7ed3\u679c\u3002\u4e24\u4e2a\u9519\u8bef\u8bb0\u5f55\u90fd\u88ab\u8ffd\u52a0\u5230 out.err \u6587\u4ef6\u4e2d\u3002\u4e24\u4e2a\u6210\u529f\u6267\u884c\u7684\u547d\u4ee4\u7684\u8fd4\u56de\u7ed3\u679c\u4e5f\u8f93\u51fa\u5230 out \u6587\u4ef6\u4e2d\u3002 $ccat out file.py new.py $ cat out.err ls: cannot access 'file' : No such file or directory ls: cannot access 'new' : No such file or directory \u4e0a\u4f8b\u547d\u4ee4\u4e5f\u53ef\u4ee5\u5408\u5e76\u3002 ls file.py > out 2 > out.err ls file >> out 2 >> out.err 2>&1 \u683c\u5f0f\u4e3e\u4f8b\uff1a $ ls file >> out.txt 2 > & 1 $ cat out.txt ls: cannot access 'file' : No such file or directory $ ls file.py & >> out.txt $ cat out.txt ls: cannot access 'file' : No such file or directory file.py 6.3.\u7279\u6b8a\u91cd\u5b9a\u5411 \u00b6 \u683c\u5f0f\uff1a command1 < <(command2) tr 'a-z' 'A-Z' < < ( echo \"Hello World\" ) \u5e94\u7528\uff1a\u4fee\u6539\u5bc6\u7801 \u5bc6\u7801\u4fdd\u5b58\u5728 passwd.txt \u6587\u4ef6\u4e2d\uff0c\u5e76\u4e25\u683c\u9650\u5236\u6539\u6587\u4ef6\u7684\u6743\u9650\u3002 \u901a\u8fc7\u53c2\u6570 --stdin \u5b9e\u73b0\u6a21\u62df\u952e\u76d8\u8f93\u5165\u64cd\u4f5c\u8f93\u5165\u7528\u6237\u540d\u3002 \u5728Rocky\u4e2d\u53ef\u4ee5\u4f7f\u7528 --stdin \u53c2\u6570\u3002 passwd --stdin vagrant < passwd.txt \u5728openSUSE\u548cUbuntu\u4e2d\uff0c --stdin \u53c2\u6570\u65e0\u6cd5\u8bc6\u522b\u3002\u53ef\u4ee5\u6539\u7528\u4e0b\u9762\u7684\u65b9\u6cd5\u3002 echo passwd.txt | chpasswd \u5176\u4e2dpasswd.txt\u7684\u683c\u5f0f\u4e3a username:password \u3002 \u53c2\u8003\uff1a Here-document(Here-doc)\uff1a\u8f93\u5165\u7684\u6587\u672c\u5757\u91cd\u5b9a\u5411\u81f3\u6807\u51c6\u8f93\u5165\u6d41\uff0c\u76f4\u81f3\u9047\u5230\u7279\u6b8a\u7684\u6587\u4ef6\u7ed3\u675f\u6807\u8bb0\u7b26\u4e3a\u6b62\uff08\u6587\u4ef6\u7ed3\u675f\u6807\u8bb0\u7b26\u53ef\u4ee5\u662f\u4efb\u610f\u7684\u552f\u4e00\u7684\u5b57\u7b26\u4e32\uff0c\u4f46\u5927\u90e8\u5206\u4eba\u90fd\u9ed8\u8ba4\u4f7f\u7528 EOF \uff09\u3002 cat < \u5c06\u547d\u4ee4\u4e0e\u6587\u4ef6\u8fde\u63a5\u8d77\u6765\uff0c\u7528\u6587\u4ef6\u6765\u63a5\u6536\u547d\u4ee4\u7684\u8f93\u51fa\uff1b\u800c\u7ba1\u9053\u7b26 | \u5c06\u547d\u4ee4\u4e0e\u547d\u4ee4\u8fde\u63a5\u8d77\u6765\uff0c\u7528\u53f3\u8fb9\u547d\u4ee4\u6765\u63a5\u6536\u5de6\u8fb9\u547d\u4ee4\u7684\u8f93\u51fa\u3002 $ ls | tr 'a-z' 'A-Z' BIN F1.TXT F2.TXT FILE.PY NEW.PY OUT OUT.ERR TEST.TXT","title":"\u7b2c\u4e8c\u7ae0 \u6587\u4ef6\u7cfb\u7edf"},{"location":"linux/SRE/02-filesystem/#_1","text":"\u6587\u4ef6\u7cfb\u7edf\u5c42\u6b21\u6807\u51c6\uff08Filesystem Hierarchy Standard, FHS\uff09\uff0c\u5b83\u662fLinux \u6807\u51c6\u5e93\uff08Linux Standards Base, LSB\uff09\u89c4\u8303\u7684\u4e00\u90e8\u5206\u3002 \u6839\u76ee\u5f55 / \u6307\u6587\u4ef6\u7cfb\u7edf\u6811\u7684\u6700\u9ad8\u5c42\u3002 \u6839\u5206\u533a\u5728\u7cfb\u7edf\u542f\u52a8\u65f6\u9996\u5148\u6302\u8f7d\u3002 \u7cfb\u7edf\u542f\u52a8\u65f6\u8fd0\u884c\u7684\u6240\u6709\u7a0b\u5e8f\u90fd\u5fc5\u987b\u5728\u6b64\u5206\u533a\u4e2d\u3002","title":"\u7b2c\u4e8c\u7ae0 \u6587\u4ef6\u7cfb\u7edf"},{"location":"linux/SRE/02-filesystem/#1","text":"\u4ee5\u4e0b\u76ee\u5f55\u5fc5\u987b\u5728\u6839\u5206\u533a\u4e2d\uff1a /bin - \u7528\u6237\u57fa\u672c\u7a0b\u5e8f\u3002 \u5305\u542b\u672a\u6302\u8f7d\u5176\u4ed6\u6587\u4ef6\u7cfb\u7edf\u65f6\u6240\u9700\u7684\u53ef\u6267\u884c\u6587\u4ef6\u3002 \u4f8b\u5982\uff0c\u7cfb\u7edf\u542f\u52a8\u3001\u5904\u7406\u6587\u4ef6\u548c\u914d\u7f6e\u6240\u9700\u7684\u7a0b\u5e8f\u3002 \u4e0d\u80fd\u5173\u8054\u5230\u72ec\u7acb\u5206\u533a\uff0c\u64cd\u4f5c\u7cfb\u7edf\u542f\u52a8\u5373\u4f1a\u8c03\u7528\u7684\u7a0b\u5e8f\u3002 /bin/bash - bash \u811a\u672c\u5904\u7406 /bin/cat - \u663e\u793a\u6587\u4ef6\u5185\u5bb9 /bin/cp - \u62f7\u8d1d\u6587\u4ef6 /bin/dd - \u62f7\u8d1d\u6587\u4ef6\uff08\u57fa\u4e8e\u5b57\u8282byte\uff09 /bin/gzip - \u538b\u7f29\u6587\u4ef6 /bin/mount - \u6302\u8f7d\u6587\u4ef6\u7cfb\u7edf /bin/rm - \u5220\u9664\u6587\u4ef6 /bin/vi - \u6587\u4ef6\u7f16\u8f91 /sbin - \u7cfb\u7edf\u57fa\u672c\u7a0b\u5e8f\u3002 \u5305\u542b\u57fa\u672c\u7cfb\u7edf\u7ba1\u7406\u7684\u7a0b\u5e8f\u3002 \u9ed8\u8ba4\u662froot\u7528\u6237\u6709\u6743\u9650\u6267\u884c\uff0c\u56e0\u6b64\u5b83\u4e0d\u5728\u5e38\u89c4\u7528\u6237\u8def\u5f84\u4e2d\u3002 \u4e0d\u80fd\u5173\u8054\u5230\u72ec\u7acb\u5206\u533a\uff0c\u64cd\u4f5c\u7cfb\u7edf\u542f\u52a8\u5373\u4f1a\u8c03\u7528\u7684\u7a0b\u5e8f \u4e00\u4e9b\u91cd\u8981\u7ba1\u7406\u7a0b\u5e8f\uff1a /sbin/fdisk* - \u7ba1\u7406\u786c\u76d8\u5206\u533a /sbin/fsck* - \u6587\u4ef6\u7cfb\u7edf\u68c0\u67e5\u3002\u4e0d\u80fd\u5728\u8fd0\u884c\u7684\u7cfb\u7edf\u4e0a\u9762\u76f4\u63a5\u6267\u884c fsck \uff0c\u635f\u574f\u6839\u6587\u4ef6\u7cfb\u7edf\uff0c\u6267\u884c\u524d\u9700\u8981 umount \u3002 /sbin/mkfs - \u521b\u5efa\u6587\u4ef6\u7cfb\u7edf /sbin/shutdown - \u5173\u95ed\u7cfb\u7edf /dev - \u8bbe\u5907\u6587\u4ef6 \u4ee5\u592a\u7f51\u5361\u662f\u5185\u6838\u6a21\u5757\uff0c\u5176\u4ed6\u786c\u4ef6\u90fd\u4ee5\u8bbe\u5907dev\u7684\u65b9\u5f0f\u5c55\u73b0\u3002 \u5e94\u7528\u7a0b\u5e8f\u8bfb\u53d6\u548c\u5199\u5165\u8fd9\u4e9b\u6587\u4ef6\u4ee5\u64cd\u4f5c\u4f7f\u7528\u786c\u4ef6\u7ec4\u4ef6\u3002 \u4e24\u79cd\u7c7b\u578b\u8bbe\u5907\u6587\u4ef6\uff1a \u5b57\u7b26\u8bbe\u5907\uff08Character-oriented\uff09\u2013 \u5e8f\u5217\u8bbe\u5907\uff08\u6253\u5370\u673a\uff0c\u78c1\u5e26\u673a\uff0c\u9f20\u6807\u7b49\uff09 \u5757\u8bbe\u5907\uff08Block-oriented\uff09\u2013 \u786c\u76d8\uff0cDVD\u7b49 \u4e0e\u8bbe\u5907\u9a71\u52a8\u7a0b\u5e8f\u7684\u8fde\u63a5\u901a\u8fc7\u5185\u6838\u4e2d\u79f0\u4e3a\u4e3b\u8bbe\u5907\u53f7\u7684\u901a\u9053\u5b9e\u73b0\u3002 \u8fc7\u53bb\uff0c\u8fd9\u4e9b\u6587\u4ef6\u662f\u4f7f\u7528 mknod \u547d\u4ee4\u624b\u52a8\u521b\u5efa\u7684\u3002 \u73b0\u5728\u5f53\u5185\u6838\u53d1\u73b0\u8bbe\u5907\u65f6\uff0c\u5b83\u4eec\u4f1a\u7531 udev \u81ea\u52a8\u521b\u5efa\u3002 \u4e00\u4e9b\u91cd\u8981\u7684\u8bbe\u5907\u6587\u4ef6\uff1a Null\u8bbe\u5907: - /dev/null Zero\u8bbe\u5907: - /dev/zero \u7cfb\u7edf\u7ec8\u7aef: - /dev/console \u865a\u62df\u7ec8\u7aef: - /dev/tty1 \u4e32\u884c\u7aef\u53e3 - /dev/ttyS0 \u5e76\u884c\u7aef\u53e3: - /dev/lp0 \u8f6f\u76d8\u9a71\u52a8\u5668: - /dev/fd0 \u786c\u76d8\u9a71\u52a8\u5668: - /dev/sda \u786c\u76d8\u5206\u533a: - /dev/sda1 CD-ROM\u9a71\u52a8\u5668: - /dev/scd0 /etc - \u914d\u7f6e\u6587\u4ef6 \u5b58\u653e\u7cfb\u7edf\u548c\u670d\u52a1\u7684\u914d\u7f6e\u6587\u4ef6\u3002 \u5927\u90e8\u5206\u90fd\u662fASCII\u6587\u4ef6 \u666e\u901a\u7528\u6237\u53ef\u4ee5\u9ed8\u8ba4\u8bfb\u53d6\u5176\u4e2d\u7684\u5927\u90e8\u5206\u5185\u5bb9\u3002 \u8fd9\u4f1a\u5e26\u6765\u4e00\u4e2a\u6f5c\u5728\u7684\u5168\u95ee\u9898\uff0c\u56e0\u4e3a\u5176\u4e2d\u4e00\u4e9b\u6587\u4ef6\u5305\u542b\u5bc6\u7801\uff0c\u56e0\u6b64\u91cd\u8981\u7684\u662f\u8981\u786e\u4fdd\u8fd9\u4e9b\u6587\u4ef6\u53ea\u80fd\u7531root\u7528\u6237\u8bfb\u53d6\u3002 \u6839\u636eFHS\u6807\u51c6\uff0c\u6b64\u5904\u4e0d\u80fd\u653e\u7f6e\u4efb\u4f55\u53ef\u6267\u884c\u6587\u4ef6\uff0c\u4f46\u5b50\u76ee\u5f55\u53ef\u80fd\u5305\u542bshell\u811a\u672c\u3002 \u51e0\u4e4e\u6bcf\u4e2a\u5df2\u5b89\u88c5\u7684\u670d\u52a1\u5728 /etc \u6216\u5176\u5b50\u76ee\u5f55\u4e2d\u81f3\u5c11\u6709\u4e00\u4e2a\u914d\u7f6e\u6587\u4ef6\u3002 \u4e00\u4e9b\u91cd\u8981\u7684\u914d\u7f6e\u6587\u4ef6: /etc/os-release - \u7cfb\u7edf\u7248\u672c\u4fe1\u606f /etc/DIR_COLORS - ls \u547d\u4ee4\u4e2d\u7684\u989c\u8272\u914d\u7f6e\u4fe1\u606f\uff08openSUSE\u548cRocky\uff09 /etc/fstab - \u914d\u7f6e\u8981\u6302\u8f7d\u7684\u6587\u4ef6\u7cfb\u7edf /etc/profile - Shell\u767b\u5f55\u811a\u672c /etc/passwd - \u7528\u6237\u4fe1\u606f\u96c6\u5408\uff08\u4e0d\u542b\u5bc6\u7801\uff09 /etc/shadow - \u5bc6\u7801\u548c\u76f8\u5173\u4fe1\u606f /etc/group - \u7528\u6237\u7ec4\u4fe1\u606f\u96c6\u5408 /etc/cups/* - \u7528\u4e8eCUPS\u6253\u5370\u7cfb\u7edf\uff08CUPS=Common UNIX Printing System\uff09 /etc/hosts - \u4e3b\u673a\u540d\u673a\u5668IP\u5730\u5740 /etc/motd - \u767b\u5f55\u540e\u663e\u793a\u7684\u6b22\u8fce\u4fe1\u606f /etc/issue - \u767b\u5f55\u524d\u663e\u793a\u7684\u6b22\u8fce\u4fe1\u606f /etc/sysconfig/* - \u7cfb\u7edf\u914d\u7f6e\u6587\u4ef6 /lib - \u5e93\uff08Libraries\uff09 \u8bb8\u591a\u7a0b\u5e8f\u90fd\u5177\u6709\u4e00\u4e9b\u901a\u7528\u529f\u80fd\u3002 \u8fd9\u4e9b\u901a\u7528\u529f\u80fd\u53ef\u4ee5\u4fdd\u5b58\u5728\u5171\u4eab\u5e93\u4e2d\u3002 \u5171\u4eab\u5e93\u4e2d\u6587\u4ef6\u7684\u6269\u5c55\u540d\u662f .so \u3002 \u76ee\u5f55 /lib \u5305\u542b\u7684\u5171\u4eab\u5e93\u6587\u4ef6\u4e3b\u8981\u662f\u88ab /bin \u548c /sbin \u76ee\u5f55\u5305\u542b\u7684\u7a0b\u5e8f\u6240\u8c03\u7528\u3002 \u76ee\u5f55 /lib \u7684\u5b50\u76ee\u5f55\u5305\u542b\u4e00\u4e9b\u989d\u5916\u9700\u8981\u7684\u5171\u4eab\u5e93\u3002 \u5185\u6838\u6a21\u5757\u5b58\u50a8\u5728\u76ee\u5f55 /lib/modules \u3002 /lib64 - 64\u4f4d\u5171\u4eab\u5e93\uff0864-Bit Libraries\uff09\uff0c\u7c7b\u4f3c\u76ee\u5f55 /lib \u3002 \u8fd9\u4e2a\u76ee\u5f55\u56e0\u7cfb\u7edf\u67b6\u6784\u4e0d\u540c\u800c\u4e0d\u540c\u3002 \u4e00\u4e9b\u7cfb\u7edf\u652f\u6301\u4e0d\u540c\u7684\u4e8c\u8fdb\u5236\u683c\u5f0f\u5e76\u4fdd\u7559\u540c\u4e00\u4e2a\u5171\u4eab\u5e93\u7684\u4e0d\u540c\u7248\u672c\u3002 /usr - \u5305\u542b\u5e94\u7528\u7a0b\u5e8f\u3001\u56fe\u5f62\u754c\u9762\u6587\u4ef6\u3001\u5e93\u3001\u672c\u5730\u7a0b\u5e8f\u3001\u6587\u6863\u7b49\u3002 /usr \u5373 Unix System Resources. \u4f8b\u5982\uff1a /usr/X11R6/ - X Window \u7cfb\u7edf\u6587\u4ef6 /usr/bin/ - \u51e0\u4e4e\u5305\u542b\u6240\u6709\u53ef\u6267\u884c\u6587\u4ef6 /usr/lib/ - \u5305\u542b\u5e93\u548c\u5e94\u7528\u7a0b\u5e8f /usr/lib64/ - \u5305\u542b64\u4f4d\u5e93\u548c\u5e94\u7528\u7a0b\u5e8f /usr/include/ - \u5305\u542bC\u7a0b\u5e8f\u7684\u5934\u6587\u4ef6\uff08head file\uff09 /usr/local/ - \u5305\u542b\u672c\u5730\u5b89\u88c5\u7a0b\u5e8f\u3002\u8fd9\u4e2a\u76ee\u5f55\u4e0b\u7684\u5185\u5bb9\u4e0d\u4f1a\u88ab\u7cfb\u7edf\u5347\u7ea7\u6240\u8986\u76d6\u3002\u4e0b\u97623\u4e2a\u76ee\u5f55\u5728\u521d\u59cb\u5b89\u88c5\u540e\u662f\u7a7a\u7684\u3002 /usr/local/bin - /usr/local/sbin - /usr/local/lib - /usr/sbin/ - \u7cfb\u7edf\u7ba1\u7406\u7a0b\u5e8f /usr/src/ - \u5185\u6838\u548c\u5e94\u7528\u7a0b\u5e8f\u7684\u6e90\u4ee3\u7801 /usr/src/linux - /usr/share/ - \u7ed3\u6784\u5316\u72ec\u7acb\u6570\u636e /usr/share/doc/ - \u6587\u6863 /usr/share/man/ - man \u547d\u4ee4\u4f7f\u7528\u7684\u5185\u5bb9 /opt - \u7b2c\u4e09\u65b9\u5e94\u7528\u7a0b\u5e8f\u76ee\u5f55 \u5404\u53d1\u884c\u7248\u5305\u542b\u7684\u5e94\u7528\u7a0b\u5e8f\u4e00\u822c\u5b58\u50a8\u5728\u76ee\u5f55 /usr/lib/ \u3002 \u5404\u53d1\u884c\u7248\u53ef\u9009\u7a0b\u5e8f\uff0c\u6216\u7b2c\u4e09\u65b9\u5e94\u7528\u7a0b\u5e8f\u5219\u5b58\u50a8\u5728\u76ee\u5f55 /opt \u3002 \u5728\u5b89\u88c5\u65f6\uff0c\u4f1a\u4e3a\u6bcf\u4e2a\u5e94\u7528\u7a0b\u5e8f\u7684\u6587\u4ef6\u521b\u5efa\u4e00\u4e2a\u76ee\u5f55\uff0c\u5176\u4e2d\u5305\u542b\u5e94\u7528\u7a0b\u5e8f\u7684\u540d\u79f0\u3002\u6bd4\u5982\uff1a /opt/novell - /boot - \u5f15\u5bfc\u76ee\u5f55 /boot/grub2 - \u5305\u542bGRUB2\u7684\u9759\u6001\u5f15\u5bfc\u52a0\u8f7d\u7a0b\u5e8f\u6587\u4ef6\uff08GRUB = Grand Unified Boot Loader\uff09\u3002 \u5305\u542b\u4ee5\u94fe\u63a5 vmlinuz \u548c initrd \u6807\u8bc6\u7684\u5185\u6838\u548c initrd \u6587\u4ef6\u3002 /root - \u7ba1\u7406\u5458\u7684\u4e3b\u76ee\u5f55\uff08home directory\uff09\u3002 root \u7528\u6237\u7684\u4e3b\u76ee\u5f55\u3002\u5176\u4ed6\u7528\u6237\u7684\u4e3b\u76ee\u5f55\u662f\u5728\u76ee\u5f55 /home \u4e0b\u3002 root \u7528\u6237\u7684\u767b\u5f55\u73af\u5883\u914d\u7f6e\u4fdd\u5b58\u81f3 /root \u5206\u533a\u4e2d\u3002 /home - \u7528\u6237\u4e3b\u76ee\u5f55 \u6bcf\u4e2a\u7cfb\u7edf\u7528\u6237\u90fd\u6709\u4e00\u4e2a\u5206\u914d\u7684\u6587\u4ef6\u533a\u57df\uff0c\u8be5\u6587\u4ef6\u533a\u57df\u5728\u767b\u5f55\u540e\u6210\u4e3a\u5f53\u524d\u5de5\u4f5c\u76ee\u5f55\u3002 \u9ed8\u8ba4\u60c5\u51b5\u4e0b\uff0c\u5b83\u4eec\u5b58\u5728\u4e8e /home \u4e2d\u3002 /home \u4e2d\u7684\u6587\u4ef6\u548c\u76ee\u5f55\u53ef\u4ee5\u4f4d\u4e8e\u5355\u72ec\u7684\u5206\u533a\u4e2d\uff0c\u4e5f\u53ef\u4ee5\u4f4d\u4e8e\u7f51\u7edc\u4e0a\u7684\u53e6\u4e00\u53f0\u8ba1\u7b97\u673a\u4e0a\u3002 \u7528\u6237\u914d\u7f6e\u4fe1\u606f\u548c\u914d\u7f6e\u6587\u4ef6\uff08user profile and configuration files\uff09\u4e3b\u8981\u6709\uff1a .profile - \u7528\u6237\u79c1\u6709\u767b\u5f55\u811a\u672c .bashrc - bash \u7684\u914d\u7f6e\u6587\u4ef6 .bash_history - bash \u73af\u5883\u4e0b\u4fdd\u6301\u547d\u4ee4\u5386\u53f2\u8bb0\u5f55 run - \u5e94\u7528\u7a0b\u5e8f\u72b6\u6001\u6587\u4ef6 \u4e3a\u5e94\u7528\u7a0b\u5e8f\u63d0\u4f9b\u4e86\u4e00\u4e2a\u6807\u51c6\u4f4d\u7f6e\u6765\u5b58\u50a8\u5b83\u4eec\u9700\u8981\u7684\u4e34\u65f6\u6587\u4ef6\uff0c\u4f8b\u5982\u5957\u63a5\u5b57\u548c\u8fdb\u7a0bID\u3002 \u8fd9\u4e9b\u6587\u4ef6\u4e0d\u80fd\u5b58\u50a8\u5728 /tmp \u4e2d\uff0c\u56e0\u4e3a /tmp \u4e2d\u7684\u6587\u4ef6\u53ef\u80fd\u4f1a\u88ab\u5220\u9664\u3002 /run/media//* - \u53ef\u79fb\u52a8\u8bbe\u5907\u7684\u6302\u8f7d\u70b9\uff0c\u4f8b\u5982\uff1a /run/media/media_name/ /run/media/cdrom/ - /run/media/dvd/ - /run/media/usbdisk/ - /mnt - \u6587\u4ef6\u7cfb\u7edf\u4e34\u65f6\u6302\u8f7d\u70b9 \u7528\u4e8e\u6302\u8f7d\u4e34\u65f6\u4f7f\u7528\u7684\u6587\u4ef6\u7cfb\u7edf\u7684\u76ee\u5f55\u3002 \u6587\u4ef6\u7cfb\u7edf\u4f7f\u7528 mount \u547d\u4ee4\u6302\u8f7d\uff0c\u4f7f\u7528 umount \u547d\u4ee4\u5220\u9664\u3002 \u5b50\u76ee\u5f55\u9ed8\u8ba4\u4e0d\u5b58\u5728\uff0c\u4e5f\u4e0d\u4f1a\u81ea\u52a8\u521b\u5efa\u3002 /srv - \u670d\u52a1\u6570\u636e\u76ee\u5f55 \u5b58\u653e\u5404\u79cd\u670d\u52a1\u7684\u6570\u636e\uff0c\u6bd4\u5982\uff1a /srv/www - \u7528\u4e8e\u5b58\u653e Apache Web Server \u7684\u6570\u636e /srv/ftp - \u7528\u4e8e\u5b58\u653e FTP server \u7684\u6570\u636e /var - \u53ef\u53d8\u6587\u4ef6\uff08Variable Files\uff09 \u5728\u7cfb\u7edf\u8fd0\u884c\u8fc7\u7a0b\u4e2d\u4f1a\u88ab\u4fee\u6539\u7684\u6587\u4ef6 Important subdirectories: /var/lib/ - \u53ef\u53d8\u5e93\u6587\u4ef6\uff0c\u5e94\u7528\u7a0b\u5e8f\u72b6\u6001\u4fe1\u606f\u6570\u636e /var/log/ - \u65e5\u5fd7\u6587\u4ef6 /var/run/ - \u8fd0\u884c\u4e2d\u7684\u8fdb\u7a0b\u7684\u4fe1\u606f /var/lock/ - \u591a\u7528\u6237\u8bbf\u95ee\u65f6\u7684\u9501\u6587\u4ef6 /var/cache - \u5e94\u7528\u7a0b\u5e8f\u7f13\u5b58\u6570\u636e\u76ee\u5f55 /var/opt - \u4e13\u4e3a /opt \u4e0b\u7684\u5e94\u7528\u7a0b\u5e8f\u5b58\u50a8\u53ef\u53d8\u6570\u636e /var/mail - /var/spool/ - \u5e94\u7528\u7a0b\u5e8f\u6570\u636e\u6c60\uff0c\u6bd4\u5982\uff1a\u6253\u5370\u673a\uff0c\u90ae\u4ef6 /var/spool/mail - /var/spool/cron - /tmp - \u4e34\u65f6\u6587\u4ef6 \u7a0b\u5e8f\u5728\u8fd0\u884c\u65f6\u521b\u5efa\u4e34\u65f6\u6587\u4ef6\u7684\u4f4d\u7f6e /proc - \u8fdb\u7a0b\u6587\u4ef6 \u865a\u62df\u6587\u4ef6\u7cfb\u7edf\uff0c\u4e0d\u5360\u7a7a\u95f4\uff0c\u5927\u5c0f\u59cb\u7ec8\u4e3a\u96f6\uff0c\u4fdd\u6301\u5f53\u524d\u8fdb\u7a0b\u7684\u72b6\u6001\u4fe1\u606f \u5305\u542b\u6709\u5173\u5404\u4e2a\u8fdb\u7a0b\u7684\u4fe1\u606f\u7684\u76ee\u5f55\uff0c\u6839\u636e\u8fdb\u7a0b\u7684 PID \u53f7\u547d\u540d \u6709\u4e9b\u503c\u53ef\u4ee5\u4e34\u65f6\u5728\u7ebf\u66f4\u6539\u751f\u6548\uff0c\u4f46\u91cd\u542f\u540e\u4e22\u5931 /proc/cpuinfo/ - Processor information /proc/dma/ - Use of DMA ports /proc/interrupts/ - Use of interrupts /proc/ioports/ - Use of I/O ports /proc/filesystems/ - File system formats the kernel knows /proc/modules/ - Active modules /proc/mounts/ - Mounted file systems /proc/net/* - Network information and statistics /proc/partitions/ - Existing partitions /proc/bus/pci/ - Connected PCI devices /proc/bus/scsi/ - Connected SCSI devices /proc/sys/* - System and kernel information /proc/version - Kernel version /sys - \u7cfb\u7edf\u4fe1\u606f\u76ee\u5f55 \u865a\u62df\u6587\u4ef6\u7cfb\u7edf\uff0c\u4ec5\u5b58\u5728\u4e8e\u5185\u5b58\u4e2d\uff0c\u6587\u4ef6\u5927\u5c0f\u4e3a\u96f6\u3002\u4e3b\u8981\u63d0\u4f9b\u5982\u4e0b\u4fe1\u606f\uff1a \u786c\u4ef6\u603b\u7ebf\uff08hardware buses\uff09 \u786c\u4ef6\u8bbe\u5907\uff08hardware devices\uff09 \u6709\u6e90\u8bbe\u5907\uff08active devices\uff09 \u9a71\u52a8\u7a0b\u5e8f\uff08drivers\uff09","title":"1.\u4e3b\u8981\u76ee\u5f55"},{"location":"linux/SRE/02-filesystem/#2","text":"","title":"2.\u6587\u4ef6\u64cd\u4f5c\u547d\u4ee4"},{"location":"linux/SRE/02-filesystem/#21","text":"pwd\u547d\u4ee4\uff08print working directory\uff09: -L: \u663e\u793a\u94fe\u63a5\u8def\u5f84 -P\uff1a\u663e\u793a\u771f\u5b9e\u7269\u7406\u8def\u5f84","title":"2.1.\u663e\u793a\u5f53\u524d\u5de5\u4f5c\u76ee\u5f55"},{"location":"linux/SRE/02-filesystem/#22","text":"\u5bf9\u4e8e\u7edd\u5bf9\u8def\u5f84 /etc/firewalld/policies \uff0c\u53ef\u4ee5\u901a\u8fc7\u4e0b\u9762\u547d\u4ee4\u5f97\u5230\u8be5\u8def\u5f84\u7684\u57fa\u540d policies \u548c\u76ee\u5f55\u540d /etc/firewalld \u3002 basename /etc/firewalld/policies dirname /etc/firewalld/policies","title":"2.2.\u76f8\u5bf9\u548c\u7edd\u5bf9\u8def\u5f84"},{"location":"linux/SRE/02-filesystem/#23","text":". \u6307\u5f53\u524d\u76ee\u5f55\uff0c\u5373 pwd \u547d\u4ee4\u6240\u8fd4\u56de\u7684\u76ee\u5f55\u3002 .. \u6307\u5f53\u524d\u76ee\u5f55\u7684\u4e0a\u4e00\u7ea7\u76ee\u5f55\uff0c\u53ca\u5f53\u524d\u76ee\u5f55\u7684\u7236\u76ee\u5f55\u3002 \u5207\u6362\u81f3\u7236\u76ee\u5f55\uff1a cd .. \u5207\u6362\u81f3\u5f53\u524d\u7528\u6237\u4e3b\u76ee\u5f55\uff1a cd ~ \u5207\u6362\u81f3\u4e0a\u6b21\u5de5\u4f5c\u76ee\u5f55\uff1a cd - echo $PWD \uff1a\u5f53\u524d\u5de5\u4f5c\u76ee\u5f55 echo $OLDPWD \uff1a\u4e0a\u6b21\u5de5\u4f5c\u76ee\u5f55","title":"2.3.\u66f4\u6539\u76ee\u5f55"},{"location":"linux/SRE/02-filesystem/#24","text":"ls \u547d\u4ee4\uff1a -a \u663e\u793a\u6240\u6709\u6587\u4ef6\u53ca\u76ee\u5f55 (. \u5f00\u5934\u7684\u9690\u85cf\u6587\u4ef6\u4e5f\u4f1a\u5217\u51fa) -A \u540c -a \uff0c\u4f46\u4e0d\u5217\u51fa . (\u76ee\u524d\u76ee\u5f55) \u53ca .. (\u7236\u76ee\u5f55) -l \u9664\u6587\u4ef6\u540d\u79f0\u5916\uff0c\u4ea6\u5c06\u6587\u4ef6\u578b\u6001\u3001\u6743\u9650\u3001\u62e5\u6709\u8005\u3001\u6587\u4ef6\u5927\u5c0f\u7b49\u8d44\u8baf\u8be6\u7ec6\u5217\u51fa -r \u5c06\u6587\u4ef6\u4ee5\u76f8\u53cd\u6b21\u5e8f\u663e\u793a(\u539f\u5b9a\u4f9d\u82f1\u6587\u5b57\u6bcd\u6b21\u5e8f) -t \u5c06\u6587\u4ef6\u4f9d\u5efa\u7acb\u65f6\u95f4\u4e4b\u5148\u540e\u6b21\u5e8f\u5217\u51fa -F \u5728\u5217\u51fa\u7684\u6587\u4ef6\u540d\u79f0\u540e\u52a0\u4e00\u7b26\u53f7\uff1b\u4f8b\u5982\u53ef\u6267\u884c\u6863\u5219\u52a0 \"*\", \u76ee\u5f55\u5219\u52a0 \"/\" -R \u9012\u5f52\u5217\u51fa\u5b50\u76ee\u5f55 -S \u6309\u6587\u4ef6\u5927\u5c0f\u6392\u5e8f\uff0c\u4ece\u5927\u5230\u5c0f -1 \u6309\u4e00\u4e2a\u6587\u4ef6\u4e00\u884c\u5217\u51fa -t \u6309\u6587\u4ef6\u65f6\u95f4\u6392\u5e8f\uff0c\u6700\u65b0\u7684\u5728\u524d -U \u4e0d\u6392\u5e8f\u8f93\u51fa\uff0c\u6309\u76ee\u5f55\u5b58\u653e\u987a\u5e8f\u5217\u51fa -u \u914d\u5408 -lt \uff0c\u6309\u8bbf\u95ee\u65f6\u95f4\u6392\u5e8f\u5e76\u663e\u793a\uff1b\u914d\u5408 -l \uff0c\u663e\u793a\u8bbf\u95ee\u65f6\u95f4\u5e76\u6309\u540d\u79f0\u6392\u5e8f\uff1b \u5426\u5219\u6309\u8bbf\u95ee\u65f6\u95f4\u6392\u5e8f\uff0c\u6700\u65b0\u7684\u5728\u524d -X \u6309\u6587\u4ef6\u6269\u5c55\u540d\u5b57\u6bcd\u987a\u5e8f\u6392\u5e8f\u8f93\u51fa -F \u5bf9\u4e0d\u540c\u7c7b\u578b\u6587\u4ef6\u663e\u793a\u65f6\u9644\u52a0\u4e0d\u540c\u7684\u7b26\u53f7\uff0c * / = > @ | \u4e4b\u4e00 ls \u547d\u4ee4\u67e5\u770b\u4e0d\u540c\u6587\u4ef6\u662f\u7684\u989c\u8272\uff0c\u7531 /etc/DIR_COLORS \u548c\u53d8\u91cf @LS_COLORS \u5b9a\u4e49\u3002","title":"2.4.\u5217\u51fa\u76ee\u5f55\u5185\u5bb9"},{"location":"linux/SRE/02-filesystem/#25stat","text":"\u6bcf\u4e2a\u6587\u4ef6\u6709\u4e09\u4e2a\u65f6\u95f4\u6233\uff1a \u8bbf\u95ee\u65f6\u95f4 Access Time atime : \u8bfb\u53d6\u6587\u4ef6\u5185\u5bb9\u3002 \u4fee\u6539\u65f6\u95f4 Modify Time mtime : \u6539\u53d8\u6587\u4ef6\u5185\u5bb9\uff08\u6570\u636e\uff09\u3002 \u6539\u53d8\u65f6\u95f4 Change Time ctime : \u5143\u6570\u636e\u53d1\u751f\u6539\u53d8\u3002 \u8bfb\u53d6\u4e09\u4e2a\u65f6\u95f4\u6233\u7684\u547d\u4ee4 stat \uff1a stat /etc/fstab \u8f93\u51fa\u7ed3\u679c\uff1a File: /etc/fstab Size: 927 Blocks: 8 IO Block: 4096 regular file Device: 30h/48d Inode: 263 Links: 1 Access: (0644/-rw-r--r--) Uid: ( 0/ root) Gid: ( 0/ root) Access: 2022-10-31 10:26:34.987466959 +0800 Modify: 2022-06-24 14:50:24.387992912 +0800 Change: 2022-06-24 14:50:24.387992912 +0800 Birth: 2022-06-24 14:50:23.755992937 +0800","title":"2.5.\u6587\u4ef6\u72b6\u6001stat"},{"location":"linux/SRE/02-filesystem/#26","text":"\u547d\u4ee4 file \u68c0\u67e5\u6587\u4ef6\u7c7b\u578b\u3002 -b \uff1a\u5217\u51fa\u8fa8\u8bc6\u7ed3\u679c\u65f6\uff0c\u4e0d\u663e\u793a\u6587\u4ef6\u540d\u79f0\u3002 -c \uff1a\u8be6\u7ec6\u663e\u793a\u6307\u4ee4\u6267\u884c\u8fc7\u7a0b\uff0c\u4fbf\u4e8e\u6392\u9519\u6216\u5206\u6790\u7a0b\u5e8f\u6267\u884c\u7684\u60c5\u5f62\u3002 -f <\u540d\u79f0\u6587\u4ef6> \uff1a\u6307\u5b9a\u540d\u79f0\u6587\u4ef6\uff0c\u5176\u5185\u5bb9\u6709\u4e00\u4e2a\u6216\u591a\u4e2a\u6587\u4ef6\u540d\u79f0\u65f6\uff0c\u8ba9file\u4f9d\u5e8f\u8fa8\u8bc6\u8fd9\u4e9b\u6587\u4ef6\uff0c\u683c\u5f0f\u4e3a\u6bcf\u5217\u4e00\u4e2a\u6587\u4ef6\u540d\u79f0\u3002 -L \uff1a \u76f4\u63a5\u663e\u793a\u7b26\u53f7\u8fde\u63a5\u6240\u6307\u5411\u7684\u6587\u4ef6\u7684\u7c7b\u522b\u3002 -v \uff1a \u663e\u793a\u7248\u672c\u4fe1\u606f\u3002 -z \uff1a \u5c1d\u8bd5\u53bb\u89e3\u8bfb\u538b\u7f29\u6587\u4ef6\u7684\u5185\u5bb9\u3002 \u7f16\u8f91\u6587\u4ef6 list.txt \u5305\u542b\u4e00\u4e0b\u5185\u5bb9\uff1a /etc/ /bin /etc/issue \u8fd0\u884c\u547d\u4ee4 file -f list.txt \uff0c\u7ed3\u679c\u5982\u4e0b\uff1a /etc/: directory /bin: directory /etc/issue: symbolic link to ../run/issue","title":"2.6.\u786e\u5b9a\u6587\u4ef6\u7c7b\u578b"},{"location":"linux/SRE/02-filesystem/#27","text":"iconv \u547d\u4ee4\u7528\u4e8e\u5c06\u4e00\u79cd\u7f16\u7801\u4e2d\u7684\u67d0\u4e9b\u6587\u672c\u8f6c\u6362\u4e3a\u53e6\u4e00\u79cd\u7f16\u7801\u3002 \u5982\u679c\u6ca1\u6709\u63d0\u4f9b\u8f93\u5165\u6587\u4ef6\uff0c\u5219\u5b83\u4ece\u6807\u51c6\u8f93\u5165\u4e2d\u8bfb\u53d6\u3002 \u540c\u6837\uff0c\u5982\u679c\u6ca1\u6709\u7ed9\u51fa\u8f93\u51fa\u6587\u4ef6\uff0c\u90a3\u4e48\u5b83\u4f1a\u5199\u5165\u6807\u51c6\u8f93\u51fa\u3002 \u5982\u679c\u6ca1\u6709\u63d0\u4f9b from-encoding \u6216 to-encoding \uff0c\u5219\u5b83\u4f7f\u7528\u5f53\u524d\u672c\u5730\u7684\u5b57\u7b26\u7f16\u7801\u3002 \u5c06\u6587\u672c\u4ece ISO 8859-15 \u5b57\u7b26\u7f16\u7801\u8f6c\u6362\u4e3a UTF-8\uff0c\u8bfb\u5165 input.txt \uff0c\u8f93\u51fa output.txt \u3002 iconv -f ISO-8859-15 -t UTF-8 < input.txt > output.txt \u4ece UTF-8 \u8f6c\u6362\u4e3a ASCII\uff0c\u5c3d\u53ef\u80fd\u8fdb\u884c\u97f3\u8bd1\uff08transliterating\uff09\uff1a echo abc \u00df \u03b1 \u20ac \u00e0\u1e03\u00e7 | iconv -f UTF-8 -t ASCII//TRANSLIT \u8fd0\u884c\u7ed3\u679c\uff1a abc ss ? EUR abc","title":"2.7.\u6587\u4ef6\u7f16\u7801\u8f6c\u6362"},{"location":"linux/SRE/02-filesystem/#28","text":"\u901a\u914d\u7b26\uff0c\u6307\u5305\u542b\u8fd9\u4e9b\u5b57\u7b26\u7684\u5b57\u7b26\u4e32 ? \uff1a\u8868\u793a\u4efb\u610f\u4e00\u4e2a\u5b57\u7b26 * \uff1a\u8868\u793a\u4efb\u610f\u957f\u5ea6\u7684\u4efb\u610f\u5b57\u7b26 [] \uff1a\u5339\u914d\u6307\u5b9a\u8303\u56f4\u5185\u4efb\u610f\u4e00\u4e2a\u5b57\u7b26 [abcd] \uff1a\u5339\u914dabcd\u4e2d\u7684\u4efb\u4f55\u4e00\u4e2a\u5b57\u7b26 [a-z] \uff1a\u5339\u914d\u8303\u56f4a\u5230z\u5185\u4efb\u610f\u4e00\u4e2a\u5b57\u7b26 [!abcd] \uff1a\u4e0d\u5339\u914d\u62ec\u53f7\u91cc\u9762\u4efb\u4f55\u4e00\u4e2a\u5b57\u7b26 {} \uff1a\u8868\u793a\u751f\u6210\u5e8f\u5217\uff0c\u4ee5\u9017\u53f7\u5206\u5272\uff0c\u4e0d\u80fd\u6709\u7a7a\u683c \u793a\u4f8b\uff1a $ touch file_ { a..z } .txt $ touch file_ { A..Z } .txt $ ls file_a.txt file_C.txt file_f.txt file_H.txt file_k.txt file_M.txt file_p.txt file_R.txt file_u.txt file_W.txt file_z.txt file_A.txt file_d.txt file_F.txt file_i.txt file_K.txt file_n.txt file_P.txt file_s.txt file_U.txt file_x.txt file_Z.txt file_b.txt file_D.txt file_g.txt file_I.txt file_l.txt file_N.txt file_q.txt file_S.txt file_v.txt file_X.txt file_B.txt file_e.txt file_G.txt file_j.txt file_L.txt file_o.txt file_Q.txt file_t.txt file_V.txt file_y.txt file_c.txt file_E.txt file_h.txt file_J.txt file_m.txt file_O.txt file_r.txt file_T.txt file_w.txt file_Y.txt $ ls file_ [ a..d ] .* file_a.txt file_d.txt $ ls file_ [ a...d ] .* file_a.txt file_d.txt $ ls file_ [ ad ] .* file_a.txt file_d.txt $ ls file_ [ a-c ] .* file_a.txt file_A.txt file_b.txt file_B.txt file_c.txt $ ls file_ [ a-C ] .* file_a.txt file_A.txt file_b.txt file_B.txt file_c.txt file_C.txt $ ls file_ [ !d-W ] .* file_a.txt file_b.txt file_c.txt file_x.txt file_y.txt file_z.txt file_A.txt file_B.txt file_C.txt file_X.txt file_Y.txt file_Z.txt \u6bd4\u8f83\u6709\u65e0 * \u7684\u533a\u522b\uff1a $ ls -a * file_a.txt file_D.txt file_h.txt file_K.txt file_o.txt file_R.txt file_v.txt file_Y.txt file_A.txt file_e.txt file_H.txt file_l.txt file_O.txt file_s.txt file_V.txt file_z.txt file_b.txt file_E.txt file_i.txt file_L.txt file_p.txt file_S.txt file_w.txt file_Z.txt file_B.txt file_f.txt file_I.txt file_m.txt file_P.txt file_t.txt file_W.txt file_c.txt file_F.txt file_j.txt file_M.txt file_q.txt file_T.txt file_x.txt file_C.txt file_g.txt file_J.txt file_n.txt file_Q.txt file_u.txt file_X.txt file_d.txt file_G.txt file_k.txt file_N.txt file_r.txt file_U.txt file_y.txt $ ls -a . file_C.txt file_g.txt file_J.txt file_n.txt file_Q.txt file_u.txt file_X.txt .. file_d.txt file_G.txt file_k.txt file_N.txt file_r.txt file_U.txt file_y.txt file_a.txt file_D.txt file_h.txt file_K.txt file_o.txt file_R.txt file_v.txt file_Y.txt file_A.txt file_e.txt file_H.txt file_l.txt file_O.txt file_s.txt file_V.txt file_z.txt file_b.txt file_E.txt file_i.txt file_L.txt file_p.txt file_S.txt file_w.txt file_Z.txt file_B.txt file_f.txt file_I.txt file_m.txt file_P.txt file_t.txt file_W.txt file_c.txt file_F.txt file_j.txt file_M.txt file_q.txt file_T.txt file_x.txt","title":"2.8.\u901a\u914d\u7b26"},{"location":"linux/SRE/02-filesystem/#29","text":"[:alpha:] \uff1a\u8868\u793a\u6240\u6709\u7684\u5b57\u6bcd\uff08\u4e0d\u533a\u5206\u5927\u5c0f\u5199\uff09\uff0c\u6548\u679c\u540c [a-z] [:digit:] \uff1a\u8868\u793a\u4efb\u610f\u5355\u4e2a\u6570\u5b57\uff0c\u6548\u679c\u540c [0-9] [:xdigit:] \uff1a\u8868\u793a\u5341\u516d\u8fdb\u5236\u6570\u5b57 [:lower:] \uff1a\u8868\u793a\u4efb\u610f\u5355\u4e2a\u5c0f\u5199\u5b57\u6bcd [:upper:] \uff1a\u8868\u793a\u4efb\u610f\u5355\u4e2a\u5927\u5199\u5b57\u6bcd [:alnum:] \uff1a\u8868\u793a\u4efb\u610f\u5355\u4e2a\u5b57\u6bcd\u6216\u6570\u5b57 [:blank:] \uff1a\u8868\u793a\u7a7a\u767d\u5b57\u7b26\uff08\u7a7a\u683c\u548c\u5236\u8868\u7b26\uff09 [:space:] \uff1a\u8868\u793a\u5305\u62ec\u7a7a\u683c\u3001\u5236\u8868\u7b26\uff08\u6c34\u5e73\u548c\u5782\u76f4\uff09\u3001\u6362\u884c\u7b26\u3001\u56de\u8f66\u7b26\u7b49\u5404\u79cd\u7c7b\u578b\u7684\u7a7a\u767d\uff0c\u6bd4 [:blank:] \u8303\u56f4\u66f4\u5e7f [:cntrl:] \uff1a\u8868\u793a\u4e0d\u53ef\u6253\u5370\u7684\u63a7\u5236\u5b57\u7b26\uff08\u9000\u683c\u3001\u5220\u9664\u3001\u8b66\u94c3\u7b49\uff09 [:graph:] \uff1a\u8868\u793a\u53ef\u6253\u5370\u7684\u975e\u7a7a\u767d\u5b57\u7b26 [:print:] \uff1a\u8868\u793a\u53ef\u6253\u5370\u5b57\u7b26 [:punct:] \uff1a\u8868\u793a\u6807\u70b9\u7b26\u53f7 \u4e3e\u4f8b\uff1a ls -d [[:alpha:]] \u5373 ls -d [a-Z] \uff1a\u663e\u793a\u5f53\u524d\u76ee\u5f55\u4e0b\u6240\u6709\u5355\u4e2a\u5b57\u6bcd\u7684\u76ee\u5f55\u548c\u6587\u4ef6 ls -d *[[:digit:]] \u5373 ls -d *[0-9] \uff1a\u663e\u793a\u5f53\u524d\u76ee\u5f55\u4e0b\u6240\u6709\u4ee5\u6570\u5b57\u7ed3\u5c3e\u7684\u76ee\u5f55\u548c\u6587\u4ef6 ls [[:lower:]].txt \uff1a\u663e\u793a\u5f53\u524d\u76ee\u5f55\u4e0b\u6240\u6709\u4ee5\u5355\u4e2a\u5c0f\u5199\u5b57\u6bcd\u4e3a\u540d\u7684.txt\u683c\u5f0f\u7684\u6587\u4ef6 ls -d [[:alnum:]] \uff1a\u663e\u793a\u5f53\u524d\u76ee\u5f55\u4e0b\u6240\u6709\u5355\u4e2a\u5b57\u6bcd\uff08\u4e0d\u533a\u5206\u5927\u5c0f\u5199\uff09\u6216\u6570\u5b57\u4e3a\u540d\u7684\u76ee\u5f55\u6216\u6587\u4ef6","title":"2.9.\u5b57\u7b26\u96c6"},{"location":"linux/SRE/02-filesystem/#210","text":"| \uff1a\u7ba1\u9053\u7b26\uff0c\u6216\u8005\uff08\u6b63\u5219\uff09 > \uff1a\u8f93\u51fa\u91cd\u5b9a\u5411 >> \uff1a\u8f93\u51fa\u8ffd\u52a0\u91cd\u5b9a\u5411 < \uff1a\u8f93\u5165\u91cd\u5b9a\u5411 << \uff1a\u8ffd\u52a0\u8f93\u5165\u91cd\u5b9a\u5411 ~ \uff1a\u5f53\u524d\u7528\u6237\u5bb6\u76ee\u5f55 $() \uff1a\u5f15\u7528\u547d\u4ee4\u88ab\u6267\u884c\u540e\u7684\u7ed3\u679c $ \uff1a\u4ee5...\u7ed3\u5c3e\uff08\u6b63\u5219\uff09 ^ \uff1a\u4ee5...\u5f00\u5934\uff08\u6b63\u5219\uff09 * \uff1a\u5339\u914d\u5168\u90e8\u5b57\u7b26\uff0c\u901a\u914d\u7b26 ? \uff1a\u4efb\u610f\u4e00\u4e2a\u5b57\u7b26\uff0c\u901a\u914d\u7b26 # \uff1a\u6ce8\u91ca & \uff1a\u8ba9\u7a0b\u5e8f\u6216\u811a\u672c\u5207\u6362\u5230\u540e\u53f0\u6267\u884c && \uff1a\u5e76\u4e14\uff0c\u540c\u65f6\u6210\u7acb [] \uff1a\u8868\u793a\u4e00\u4e2a\u8303\u56f4\uff08\u6b63\u5219\uff0c\u901a\u914d\u7b26\uff09 {} \uff1a\u4ea7\u751f\u4e00\u4e2a\u5e8f\u5217\uff08\u901a\u914d\u7b26\uff09 . \uff1a\u5f53\u524d\u76ee\u5f55\u7684\u786c\u94fe\u63a5 .. \uff1a\u4e0a\u7ea7\u76ee\u5f55\u7684\u786c\u94fe\u63a5","title":"2.10.\u7279\u6b8a\u7b26\u53f7"},{"location":"linux/SRE/02-filesystem/#211touch","text":"touch \u547d\u4ee4\u53ef\u4ee5\u521b\u5efa\u7a7a\u6587\u4ef6\uff0c\u4e5f\u53ef\u4ee5\u5237\u65b0\u6587\u4ef6\u65f6\u95f4\u3002\u53c2\u6570\u5982\u4e0b\uff1a -a \uff1a\u4ec5\u6539\u53d8 atime \u548c ctime -m \uff1a\u4ec5\u6539\u53d8 mtime \u548c ctime -t [[CC]YY]MMDDhhmm[.ss] \uff1a\u6307\u5b9a atime \u548c mtime -c \uff1a\u5982\u679c\u6587\u4ef6\u4e0d\u5b58\u5728\uff0c\u5219\u4e0d\u521b\u5efa $ touch file1 $ touch file2 $ ll -rw-r--r--. 1 vagrant wheel 5 Nov 8 20 :49 file1 -rw-r--r--. 1 vagrant wheel 0 Nov 8 20 :28 file2 \u521b\u5efa\u6587\u4ef6file-non.log\uff0c\u5982\u679c\u4e0d\u5b58\u5728\u5219\u4e0d\u521b\u5efa\u3002 touch -c file-non.log \u66f4\u65b0 file1 \u7684\u65f6\u95f4\u548c file2 \u4e00\u81f4\u3002 $ touch -r file1 file2 $ ll -rw-r--r--. 1 vagrant wheel 5 Nov 8 20 :49 file1 -rw-r--r--. 1 vagrant wheel 0 Nov 8 20 :49 file2 \u6307\u5b9a file2 \u7684\u65f6\u95f4\u3002 202210012135.25 \u4ee3\u8868 YYYYMMDDHHMM.SS \u3002 $ touch -t 202210012135 .25 file2 $ ll -rw-r--r--. 1 vagrant wheel 5 Nov 8 20 :49 file1 -rw-r--r--. 1 vagrant wheel 0 Oct 1 21 :35 file2 $ stat file2 File: file2 Size: 0 Blocks: 0 IO Block: 4096 regular empty file Device: fd02h/64770d Inode: 140 Links: 1 Access: ( 0644 /-rw-r--r-- ) Uid: ( 1000 / vagrant ) Gid: ( 10 / wheel ) Context: unconfined_u:object_r:user_home_t:s0 Access: 2022 -10-01 21 :35:25.000000000 +0800 Modify: 2022 -10-01 21 :35:25.000000000 +0800 Change: 2022 -11-08 20 :56:18.306315887 +0800 Birth: 2022 -11-08 20 :28:37.809551441 +0800","title":"2.11.\u5237\u65b0\u6587\u4ef6\u65f6\u95f4touch"},{"location":"linux/SRE/02-filesystem/#212cp","text":"cp \u547d\u4ee4\uff1aCopy SOURCE to DEST, or multiple SOURCE(s) to DIRECTORY. \u5e38\u7528\u53c2\u6570\uff1a -a \uff1a\u5f52\u6863\uff0c\u76f8\u5f53\u4e8e -dR --preserv=all \u53c2\u6570\u7ec4\u5408\uff0c\u5e38\u7528\u4e8e\u5907\u4efd\u3002 -d \uff1a\u4e0d\u590d\u5236\u539f\u6587\u4ef6\uff0c\u53ea\u590d\u5236\u94fe\u63a5\u540d\u3002\u76f8\u5f53\u4e8e --no-dereference --preserve=links \u53c2\u6570\u7ec4\u5408\u3002 -f \uff1a\u8986\u76d6\u5df2\u7ecf\u5b58\u5728\u7684\u76ee\u6807\u6587\u4ef6\u3002 -i \uff1a\u8986\u76d6\u76ee\u6807\u6587\u4ef6\u4e4b\u524d\u7ed9\u51fa\u63d0\u793a\u3002 -p \uff1a\u9664\u590d\u5236\u6587\u4ef6\u7684\u5185\u5bb9\u5916\uff0c\u4e5f\u590d\u5236\u6587\u4ef6\u6743\u9650\uff0c\u65f6\u95f4\u6233\uff0c\u5c5e\u4e3b\u5c5e\u7ec4\u3002\u76f8\u5f53\u4e8e --preserve=mode,ownership,timestamps \u3002 -r, -R, --recursive \uff1a\u9012\u5f52\u590d\u5236\u76ee\u5f55\u6240\u5305\u542b\u7684\u5168\u90e8\u5185\u5bb9\u3002 -l \uff1a\u4e0d\u590d\u5236\u6587\u4ef6\uff0c\u53ea\u662f\u751f\u6210\u786c\u94fe\u63a5\u6587\u4ef6\u3002 \u53c2\u6570 --preserv \u53ef\u9009\u9879\uff1a mode\uff1a\u6743\u9650 ownership\uff1a\u5c5e\u4e3b\u5c5e\u7ec4 timestamp links xattr context all \u521b\u5efa\u6d4b\u8bd5\u76ee\u5f55\u3002 cd ~ mkdir test \u5bf9\u6bd4\u53c2\u6570 -p \u7684\u5dee\u522b\u3002 $ cp /etc/issue ~/test/issue1 $ cp -p /etc/issue ~/test/issue1 $ sudo cp /etc/issue ~/test/issue3 $ sudo cp -p /etc/issue ~/test/issue4 $ ll ~/test -rw-r--r--. 1 vagrant wheel 23 Nov 8 22 :25 issue1 -rw-r--r--. 1 vagrant wheel 23 Jul 21 01 :10 issue2 -rw-r--r--. 1 root root 23 Nov 8 22 :43 issue3 -rw-r--r--. 1 root root 23 Jul 21 01 :10 issue4 $ ll /etc/issue -rw-r--r--. 1 root root 23 Jul 21 01 :10 /etc/issue \u5bf9\u6bd4\u53c2\u6570 -r \u3002 $ sudo cp /etc/sysconfig/ ~/test cp: -r not specified ; omitting directory '/etc/sysconfig/' $ sudo cp -r /etc/sysconfig/ ~/test $ tree -L 2 ~/test /home/vagrant/test \u251c\u2500\u2500 issue1 \u251c\u2500\u2500 issue2 \u251c\u2500\u2500 issue3 \u251c\u2500\u2500 issue4 \u2514\u2500\u2500 sysconfig \u251c\u2500\u2500 anaconda \u251c\u2500\u2500 atd \u251c\u2500\u2500 chronyd \u251c\u2500\u2500 cpupower \u251c\u2500\u2500 crond \u251c\u2500\u2500 firewalld \u251c\u2500\u2500 irqbalance \u251c\u2500\u2500 kdump \u251c\u2500\u2500 kernel \u251c\u2500\u2500 man-db \u251c\u2500\u2500 network \u251c\u2500\u2500 network-scripts \u251c\u2500\u2500 nftables.conf \u251c\u2500\u2500 raid-check \u251c\u2500\u2500 rsyslog \u251c\u2500\u2500 run-parts \u251c\u2500\u2500 samba \u251c\u2500\u2500 selinux -> ../selinux/config \u251c\u2500\u2500 smartmontools \u2514\u2500\u2500 sshd \u53c2\u6570 -b \uff0c\u5982\u679c\u76ee\u6807\u6587\u4ef6\u5b58\u5728\uff0c\u590d\u5236\u524d\u5148\u5c06\u539f\u6587\u4ef6\u590d\u5236\u5e76\u4ee5 ~ \u7ed3\u5c3e\u3002 $ ll /etc/motd -rw-r--r--. 1 root root 0 Jun 23 2020 /etc/motd $ ll ~/test/issue1 -rw-r--r--. 1 vagrant wheel 23 Nov 8 22 :25 /home/vagrant/test/issue1 $ cp -b /etc/motd ~/test/issue $ cp -b /etc/motd ~/test/issue1 $ ll ~/test -rw-r--r--. 1 vagrant wheel 0 Nov 8 23 :00 issue -rw-r--r--. 1 vagrant wheel 0 Nov 8 22 :57 issue1 -rw-r--r--. 1 vagrant wheel 23 Nov 8 22 :25 issue1~ -rw-r--r--. 1 vagrant wheel 23 Jul 21 01 :10 issue2 -rw-r--r--. 1 root root 23 Nov 8 22 :43 issue3 -rw-r--r--. 1 root root 23 Jul 21 01 :10 issue4 drwxr-xr-x. 3 root root 4096 Nov 8 22 :49 sysconfig \u53c2\u6570 --backup=numbered \u4f1a\u5728\u590d\u5236\u539f\u6587\u4ef6\u65f6\u52a0\u4e0a\u6570\u5b57\u5e8f\u53f7\uff0c\u5e8f\u53f71\u4ee3\u8868\u539f\u59cb\u7684\u6587\u4ef6\u3002 $ cp --backup = numbered /etc/motd ~/test/issue2 $ cp --backup = numbered /etc/motd ~/test/issue2 $ cp --backup = numbered /etc/motd ~/test/issue2 $ ll ~/test -rw-r--r--. 1 vagrant wheel 0 Nov 8 23 :00 issue -rw-r--r--. 1 vagrant wheel 0 Nov 8 22 :57 issue1 -rw-r--r--. 1 vagrant wheel 23 Nov 8 22 :25 issue1~ -rw-r--r--. 1 vagrant wheel 0 Nov 8 23 :09 issue2 -rw-r--r--. 1 vagrant wheel 23 Jul 21 01 :10 issue2.~1~ -rw-r--r--. 1 vagrant wheel 0 Nov 8 23 :09 issue2.~2~ -rw-r--r--. 1 vagrant wheel 0 Nov 8 23 :09 issue2.~3~ -rw-r--r--. 1 root root 23 Nov 8 22 :43 issue3 -rw-r--r--. 1 root root 23 Jul 21 01 :10 issue4 drwxr-xr-x. 3 root root 4096 Nov 8 22 :49 sysconfig","title":"2.12.\u590d\u5236\u6587\u4ef6\u548c\u76ee\u5f55cp"},{"location":"linux/SRE/02-filesystem/#213mv","text":"mv \u547d\u4ee4\u3002Rename SOURCE to DEST, or move SOURCE(s) to DIRECTORY. \u5e38\u7528\u53c2\u6570\uff1a -v \uff1a\u663e\u793a\u547d\u4ee4\u6267\u884c\u7684\u4fe1\u606f\u3002 -i \uff1a\u4ea4\u4e92\u5f0f\uff0c\u6bd4\u5982\uff0c\u91cd\u540d\u8986\u76d6\u65f6\u4f1a\u63d0\u5347\u662f\u5426\u786e\u8ba4\u3002 -b \uff1a\u8986\u76d6\u65f6\u521b\u5efa\u5907\u4efd\u3002\u9ed8\u8ba4\u60c5\u51b5\u4e0b\uff0c\u79fb\u52a8\u6587\u4ef6\u5c06\u4f1a\u8986\u76d6\u5df2\u5b58\u5728\u7684\u76ee\u6807\u6587\u4ef6\u3002 \u79fb\u52a8\u591a\u4e2a\u6587\u4ef6\u5230\u67d0\u4e2a\u76ee\u5f55\u3002 mv file1 file2 file3 ~/dest mv file* ~/dest \u79fb\u52a8\u76ee\u5f55\u3002 mv ~/test ~/dest/new/one/ \u91cd\u547d\u540d\u6587\u4ef6\u548c\u76ee\u5f55\u3002 mv file1 file2 mv ~/test ~/dest","title":"2.13.\u79fb\u52a8\u6587\u4ef6\u548c\u76ee\u5f55mv"},{"location":"linux/SRE/02-filesystem/#214rename","text":"rename \u547d\u4ee4\u3002\u5206\u4e3aperl\u7248\u672c\u548cC\u8bed\u8a00\u7248\u672c\u3002 \u533a\u5206\u65b9\u6cd5: rename --version \u3002\u5982\u679c\u8fd4\u56de\u7ed3\u679c\u4e2d\u5305\u542b util-linux \uff0c\u8bf4\u660e\u662fC\u8bed\u8a00\u7248\u672c, \u53cd\u4e4b\u662fPerl\u7248\u672c\u3002 openSUSE\u548cRocy\u662fC\u8bed\u8a00\u7248\u672c\uff0cUbuntu\u662fPerl\u7248\u672c\u3002 \u4e3e\u4f8b\uff1a\u4fee\u6539\u5f53\u524d\u76ee\u5f55\u6240\u6709\u6269\u5c55\u540d\u4e3a s \u7684\u6587\u4ef6\u6539\u4e3a\u6269\u5c55\u540d\u4e3a gz \u3002 $ touch file { 1 ..3 } .s $ rename -v '.s' '.gz' *.s $ rename -v \".s\" \".gz\" *.s ` file1.txt ' -> `file1.html' ` file2.txt ' -> `file2.html' ` file3.txt ' -> `file3.html' \u5728Ubuntu\u4e0a\u5b8c\u6210\u540c\u6837\u4efb\u52a1\uff0c\u5219\u9700\u8981\u4f7f\u7528\u6b63\u5219\u3002 rename -v \"s/s/gz/g\" *.s","title":"2.14.\u91cd\u547d\u540d\u6587\u4ef6\u548c\u76ee\u5f55rename"},{"location":"linux/SRE/02-filesystem/#215rm","text":"rm \u547d\u4ee4\u3002\u5efa\u8bae\u4f7f\u7528 mv \u547d\u4ee4\u4ee3\u66ff rm \u547d\u4ee4\u3002","title":"2.15.\u5220\u9664\u6587\u4ef6rm"},{"location":"linux/SRE/02-filesystem/#216","text":"\u521b\u5efa\u76ee\u5f55\uff1a mkdir \u5220\u9664\u7a7a\u76ee\u5f55\uff1a rmdir \u5220\u9664\u975e\u7a7a\u76ee\u5f55\uff1a rm -r \u663e\u793a\u76ee\u5f55\u6811\uff1a tree","title":"2.16.\u76ee\u5f55\u64cd\u4f5c\u547d\u4ee4"},{"location":"linux/SRE/02-filesystem/#217","text":"\u663e\u793a /etc \u76ee\u5f55\u4e0b\u6240\u6709\u4ee5 l \u5f00\u5934\uff0c\u4ee5\u4e00\u4e2a\u5c0f\u5199\u5b57\u6bcd\u7ed3\u5c3e\uff0c\u4e14\u4e2d\u95f4\u51fa\u73b0\u81f3\u5c11\u4e00\u4f4d\u6570\u5b57\u7684\u6587\u4ef6\u6216\u76ee\u5f55\u5217\u8868\u3002 ls -d /etc/l* [ 0 -9 ] * [ a-z ] ls -d /etc/l* [[ :digit: ]] * [[ :lower: ]] \u5982\u679c\u65e0\u7b26\u5408\u6761\u4ef6\u7684\u8bb0\u5f55\u8fd4\u56de\uff0c\u53ef\u4ee5\u624b\u5de5\u521b\u5efa\u4e00\u4e2a\u7b26\u5408\u6761\u4ef6\u7684\u6587\u4ef6\u548c\u76ee\u5f55\u3002 sudo touch /etc/lam4you sudo mkdir /etc/lam5you \u9a8c\u8bc1\u540e\u5220\u9664\u3002 sudo rm /etc/lam4you sudo rm -rf /etc/lam5you \u663e\u793a /etc \u76ee\u5f55\u4e0b\u4ee5\u4efb\u610f\u4e00\u4f4d\u6570\u5b57\u5f00\u5934\uff0c\u4e14\u4ee5\u975e\u6570\u5b57\u7ed3\u5c3e\u7684\u6587\u4ef6\u6216\u76ee\u5f55\u5217\u8868\u3002 ls /etc/ [ 0 -9 ] * [ !0-9 ] ls /etc/ [[ :digit: ]] * [ ^ [ :digit: ]] \u5982\u679c\u65e0\u7b26\u5408\u6761\u4ef6\u7684\u8bb0\u5f55\u8fd4\u56de\uff0c\u53ef\u4ee5\u624b\u5de5\u521b\u5efa\u4e00\u4e2a\u7b26\u5408\u6761\u4ef6\u7684\u6587\u4ef6\u548c\u76ee\u5f55\u3002 sudo touch /etc/5am4yo. sudo mkdir /etc/5am5yo. \u9a8c\u8bc1\u540e\u5220\u9664\u3002 sudo rm /etc/5am4yo. sudo rm -rf /etc/5am5yo. \u663e\u793a /etc \u76ee\u5f55\u4e0b\u4ee5\u975e\u5b57\u6bcd\u5f00\u5934\uff0c\u540e\u9762\u8ddf\u4e86\u4e00\u4e2a\u5b57\u6bcd\u53ca\u5176\u5b83\u4efb\u610f\u957f\u5ea6\u4efb\u610f\u5b57\u7b26\u7684\u6587\u4ef6\u6216\u76ee\u5f55\u5217\u8868\u3002 ls /etc/ [ !a-zA-Z ][ a-zA-Z ] * ls /etc/ [ ^ [ :alpha: ]][[ :alpha: ]] * \u5982\u679c\u65e0\u7b26\u5408\u6761\u4ef6\u7684\u8bb0\u5f55\u8fd4\u56de\uff0c\u53ef\u4ee5\u624b\u5de5\u521b\u5efa\u4e00\u4e2a\u7b26\u5408\u6761\u4ef6\u7684\u6587\u4ef6\u548c\u76ee\u5f55\u3002 sudo touch /etc/5Ato3 sudo mkdir /etc/6dog6 \u9a8c\u8bc1\u540e\u5220\u9664\u3002 sudo rm /etc/5Ato3 sudo rm -rf /etc/6dog6 \u663e\u793a /etc \u76ee\u5f55\u4e0b\uff0c\u6240\u6709\u4ee5 rc \u5f00\u5934\uff0c\u5e76\u540e\u9762\u662f0-6\u4e4b\u95f4\u7684\u6570\u5b57\uff0c\u5176\u5b83\u4e3a\u4efb\u610f\u5b57\u7b26\u7684\u6587\u4ef6\u6216\u76ee\u5f55\u5217\u8868\u3002 ls /etc/rc [ 0 -6 ] * \u5982\u679c\u65e0\u7b26\u5408\u6761\u4ef6\u7684\u8bb0\u5f55\u8fd4\u56de\uff0c\u53ef\u4ee5\u624b\u5de5\u521b\u5efa\u4e00\u4e2a\u7b26\u5408\u6761\u4ef6\u7684\u6587\u4ef6\u548c\u76ee\u5f55\u3002 sudo touch /etc/rc5come sudo mkdir /etc/rc0123 \u9a8c\u8bc1\u540e\u5220\u9664\u3002 sudo rm /etc/rc5come sudo rm -rf /etc/rc0123 \u663e\u793a /etc \u76ee\u5f55\u4e0b\uff0c\u6240\u6709\u4ee5 .conf \u7ed3\u5c3e\uff0c\u4e14\u4ee5 m \u3001 n \u3001 r \u3001 p \u5f00\u5934\u7684\u6587\u4ef6\u6216\u76ee\u5f55\u5217\u8868\u3002 ls /etc/ [ mnrp ] *.conf \u53ea\u663e\u793a /root \u4e0b\u7684\u9690\u85cf\u6587\u4ef6\u548c\u76ee\u5f55\u5217\u8868\u3002 ls .* \u53ea\u663e\u793a/etc\u4e0b\u975e\u9690\u85cf\u76ee\u5f55\u5217\u8868\u3002 ls /etc/ [ ^. ] */ \u5c06 /etc \u76ee\u5f55\u4e0b\u6240\u6709\u6587\u4ef6\uff0c\u5907\u4efd\u5230 ~/test/ \u76ee\u5f55\u4e0b\uff0c\u5e76\u8981\u6c42\u5b50\u76ee\u5f55\u683c\u5f0f\u4e3a backupYYYY-mm-dd \uff0c\u5907\u4efd\u8fc7\u7a0b\u53ef\u89c1\u3002 sudo cp -av /etc/ ~/test/backup ` date +%F ` sudo cp -av /etc/ ~/test/backup ` date +%F_%H-%M-%S ` \u521b\u5efa\u76ee\u5f55 ~/testdir/dir1/x \uff0c ~/testdir/dir1/y \uff0c ~/testdir/dir1/x/a \uff0c ~/testdir/dir1/x/b \uff0c ~/testdir/dir1/y/a \uff0c ~/testdir/dir1/y/b \u3002 $ mkdir -p ~/testdir/dir1/ { x,y } / { a,b } $ tree ~/testdir/dir1/ /home/vagrant/testdir/dir1/ \u251c\u2500\u2500 x \u2502 \u251c\u2500\u2500 a \u2502 \u2514\u2500\u2500 b \u2514\u2500\u2500 y \u251c\u2500\u2500 a \u2514\u2500\u2500 b \u521b\u5efa\u76ee\u5f55 ~/testdir/dir2/x \uff0c ~/testdir/dir2/y \uff0c ~/testdir/dir2/x/a \uff0c ~/testdir/dir2/x/b \u3002 $ mkdir -p ~/testdir/dir2/ { x/ { a,b } ,y } $ tree ~/testdir/dir2/ /home/vagrant/testdir/dir2/ \u251c\u2500\u2500 x \u2502 \u251c\u2500\u2500 a \u2502 \u2514\u2500\u2500 b \u2514\u2500\u2500 y \u521b\u5efa\u76ee\u5f55 ~/testdir/dir3 \u3001 ~/testdir/dir4 \u3001 ~/testdir/dir5 \u3001 ~/testdir/dir5/dir6 \u3001 ~/testdir/dir5/dir7 \u3002 $ mkdir -p ~/testdir/dir { 3 ,4,5/dir { 6 ,7 }} $ tree ~/testdir /home/vagrant/testdir \u251c\u2500\u2500 dir1 \u2502 \u251c\u2500\u2500 x \u2502 \u2502 \u251c\u2500\u2500 a \u2502 \u2502 \u2514\u2500\u2500 b \u2502 \u2514\u2500\u2500 y \u2502 \u251c\u2500\u2500 a \u2502 \u2514\u2500\u2500 b \u251c\u2500\u2500 dir2 \u2502 \u251c\u2500\u2500 x \u2502 \u2502 \u251c\u2500\u2500 a \u2502 \u2502 \u2514\u2500\u2500 b \u2502 \u2514\u2500\u2500 y \u251c\u2500\u2500 dir3 \u251c\u2500\u2500 dir4 \u2514\u2500\u2500 dir5 \u251c\u2500\u2500 dir6 \u2514\u2500\u2500 dir7","title":"2.17.\u7ec3\u4e60"},{"location":"linux/SRE/02-filesystem/#3","text":"\u666e\u901a\u6587\u4ef6\uff08Normal Files\uff09 ASCII \u6587\u672c\u6587\u4ef6 \u53ef\u6267\u884c\u6587\u4ef6 \u56fe\u5f62\u6587\u4ef6 \u76ee\u5f55\uff08Directories\uff09 \u7ec4\u7ec7\u89c4\u5212\u78c1\u76d8\u4e0a\u7684\u6587\u4ef6 \u5305\u542b\u6587\u4ef6\u548c\u5b50\u76ee\u5f55 \u5b9e\u73b0\u5206\u5c42\u6587\u4ef6\u7cfb\u7edf \u94fe\u63a5\uff08Links\uff09 \u786c\u94fe\u63a5\uff08Hard links\uff09 \u78c1\u76d8\u4e0a\u6587\u4ef6\u7684\u8f85\u52a9\u6587\u4ef6\u540d \u591a\u4e2a\u6587\u4ef6\u540d\u5f15\u7528\u5355\u4e2a inode \u5f15\u7528\u7684\u6587\u4ef6\u5fc5\u987b\u5b58\u5728\u4e8e\u540c\u4e00\u4e2a\u6587\u4ef6\u7cfb\u7edf\u4e2d \u7b26\u53f7\u94fe\u63a5\uff08Symbolic links\uff09 \u5bf9\u78c1\u76d8\u4e0a\u5176\u4ed6\u6587\u4ef6\u7684\u5f15\u7528 inode \u5305\u542b\u5bf9\u53e6\u4e00\u4e2a\u6587\u4ef6\u540d\u7684\u5f15\u7528 \u88ab\u5f15\u7528\u7684\u6587\u4ef6\u53ef\u4ee5\u5b58\u5728\u4e8e\u540c\u4e00\u4e2a\u6587\u4ef6\u7cfb\u7edf\u4e2d\uff0c\u4e5f\u53ef\u4ee5\u5b58\u5728\u4e8e\u5176\u4ed6\u6587\u4ef6\u7cfb\u7edf\u4e2d \u7b26\u53f7\u94fe\u63a5\u53ef\u4ee5\u5f15\u7528\u4e0d\u5b58\u5728\u7684\u6587\u4ef6\uff08\u65ad\u5f00\u7684\u94fe\u63a5\uff09 \u5957\u63a5\u5b57Sockets - \u7528\u4e8e\u8fdb\u7a0b\u4e4b\u95f4\u7684\u53cc\u5411\u901a\u4fe1\u3002 \u7ba1\u9053\uff08Pipes\uff09(FIFOs) - \u7528\u4e8e\u4ece\u4e00\u4e2a\u8fdb\u7a0b\u5230\u53e6\u4e00\u4e2a\u8fdb\u7a0b\u7684\u5355\u5411\u901a\u4fe1\u3002 \u5757\u8bbe\u5907\uff08Block Devices\uff09 \u5b57\u7b26\u8bbe\u5907\uff08Character Devices\uff09","title":"3.\u4e03\u79cd\u6587\u4ef6\u7c7b\u578b"},{"location":"linux/SRE/02-filesystem/#31inode","text":"\u6587\u4ef6\u50a8\u5b58\u5728\u786c\u76d8\u4e0a\uff0c\u786c\u76d8\u7684\u6700\u5c0f\u5b58\u50a8\u5355\u4f4d\u53eb\u505a\u201c\u6247\u533a\u201d\uff08Sector\uff09\u3002\u6bcf\u4e2a\u6247\u533a\u50a8\u5b58512\u5b57\u8282\uff08\u76f8\u5f53\u4e8e0.5KB\uff09\u3002 \u64cd\u4f5c\u7cfb\u7edf\u8bfb\u53d6\u786c\u76d8\u7684\u65f6\u5019\uff0c\u4e0d\u662f\u4e00\u4e2a\u4e00\u4e2a\u6247\u533a\u8bfb\u53d6\uff0c\u800c\u662f\u4e00\u6b21\u6027\u8fde\u7eed\u8bfb\u53d6\u591a\u4e2a\u6247\u533a\uff0c\u6211\u4eec\u79f0\u4e3a\u8bfb\u53d6\u4e00\u4e2a\u201c\u5757\u201d\uff08block\uff09\u3002 \u5e38\u89c1\u7684block\u7684\u5927\u5c0f\u662f4KB\uff08\u8fde\u7eed\u516b\u4e2asector\u7ec4\u6210\u4e00\u4e2ablock\uff09\u3002 \u591a\u4e2a\u6247\u533a\u7ec4\u6210\u7684block\u662f\u6587\u4ef6\u5b58\u53d6\u7684*\u6700\u5c0f\u5355\u4f4d*\u3002 \u6587\u4ef6\u6570\u636e\u50a8\u5b58\u5728block\u4e2d\uff0c\u6587\u4ef6\u7684\u5143\u4fe1\u606f\uff0c\u6bd4\u5982\u6587\u4ef6\u7684\u521b\u5efa\u8005\u3001\u521b\u5efa\u65e5\u671f\u3001\u6587\u5927\u5c0f\u7b49\uff0c\u5b58\u50a8\u5728inode\uff0c\u5373\u201c\u7d22\u5f15\u8282\u70b9\u201d\u3002 \u6bcf\u4e00\u4e2a\u6587\u4ef6\u90fd\u6709\u5bf9\u5e94\u7684inode\uff0c\u91cc\u9762\u5305\u542b\u4e86\u4e0e\u8be5\u6587\u4ef6\u6709\u5173\u7684\u4e00\u4e9b\u4fe1\u606f\u3002\u6ce8\u610f\uff0c\u9664\u4e86\u6587\u4ef6\u540d\u4ee5\u5916\u7684\u5176\u5b83\u6587\u4ef6\u4fe1\u606f\uff0c\u90fd\u5b58\u5728inode\u4e4b\u4e2d\u3002 inode\u5305\u542b\u6587\u4ef6\u7684\u5143\u4fe1\u606f\u4e3b\u8981\u6709\uff1a \u6587\u4ef6\u7684\u5b57\u8282\u6570 \u6587\u4ef6\u62e5\u6709\u8005\u7684 User ID \u6587\u4ef6\u7684 Group ID \u6587\u4ef6\u7684\u8bfb\u3001\u5199\u3001\u6267\u884c\u6743\u9650 \u6587\u4ef6\u7684\u65f6\u95f4\u6233\uff0c\u5171\u6709\u4e09\u4e2a\uff1actime\u6307inode\u4e0a\u4e00\u6b21\u53d8\u52a8\u7684\u65f6\u95f4\uff0cmtime\u6307\u6587\u4ef6\u5185\u5bb9\u4e0a\u4e00\u6b21\u53d8\u52a8\u7684\u65f6\u95f4\uff0catime\u6307\u6587\u4ef6\u4e0a\u4e00\u6b21\u6253\u5f00\u7684\u65f6\u95f4\u3002 \u94fe\u63a5\u6570\uff0c\u5373\u6709\u591a\u5c11\u6587\u4ef6\u540d\u6307\u5411\u8fd9\u4e2ainode \u6587\u4ef6\u6570\u636eblock\u7684\u4f4d\u7f6e \u67e5\u770binode\u4fe1\u606f\u7684\u547d\u4ee4 stat \uff1a $ stat file1 File: file1 Size: 5 Blocks: 8 IO Block: 4096 regular file Device: fd02h/64770d Inode: 143 Links: 1 Access: ( 0644 /-rw-r--r-- ) Uid: ( 1000 / vagrant ) Gid: ( 10 / wheel ) Context: unconfined_u:object_r:user_home_t:s0 Access: 2022 -11-08 20 :49:26.019678244 +0800 Modify: 2022 -11-08 20 :49:26.019678244 +0800 Change: 2022 -11-08 20 :49:26.028678455 +0800 Birth: 2022 -11-08 20 :49:26.019678244 +0800 \u683c\u5f0f\u5316\u786c\u76d8\u65f6\uff0c\u64cd\u4f5c\u7cfb\u7edf\u4f1a\u81ea\u52a8\u5c06\u786c\u76d8\u5206\u6210\u4e24\u4e2a\u533a\u57df\u3002\u4e00\u4e2a\u662f\u6570\u636e\u533a\uff0c\u5b58\u653e\u6587\u4ef6\u6570\u636e\u3002\u53e6\u4e00\u4e2a\u662finode\u533a\uff08inode table\uff09\uff0c\u5b58\u653einode\u6240\u5305\u542b\u7684\u6587\u4ef6\u7684\u5143\u4fe1\u606f\u3002 \u6bcf\u4e2ainode\u8282\u70b9\u7684\u5927\u5c0f\uff0c\u4e00\u822c\u662f128\u5b57\u8282\u6216256\u5b57\u8282\u3002inode\u8282\u70b9\u7684\u603b\u6570\uff0c\u5728\u683c\u5f0f\u5316\u65f6\u5c31\u786e\u5b9a\u4e86\uff0c\u4e00\u822c\u662f\u6bcf1KB\u6216\u6bcf2KB\u5c31\u8bbe\u7f6e\u4e00\u4e2ainode\u3002 \u5047\u5b9a\u4e00\u57571GB\u7684\u786c\u76d8\uff0c\u5982\u679c\u6bcf\u4e2ainode\u8282\u70b9\u7684\u5927\u5c0f\u4e3a128\u5b57\u8282\uff0c\u4e14\u6bcf1KB\u5c31\u8bbe\u7f6e\u4e00\u4e2ainode\uff0c\u5219inode table\u7684\u5927\u5c0f\u5c31\u4f1a\u8fbe\u5230128MB\uff0c\u5360\u6574\u5757\u786c\u76d8\u768412.8%\u3002 \u901a\u8fc7 df \u547d\u4ee4\u67e5\u770b\u6bcf\u4e2a\u786c\u76d8\u5206\u533a\u7684inode\u603b\u6570\u548c\u5df2\u7ecf\u4f7f\u7528\u7684\u6570\u91cf\u3002 \u7531\u4e8e\u6bcf\u4e2a\u6587\u4ef6\u90fd\u5fc5\u987b\u6709\u4e00\u4e2ainode\uff0c\u56e0\u6b64\u6709\u53ef\u80fd\u53d1\u751finode\u5df2\u7ecf\u7528\u5149\uff0c\u4f46\u662f\u786c\u76d8\u8fd8\u672a\u5b58\u6ee1\u7684\u60c5\u51b5\uff0c\u4e5f\u5c31\u65e0\u6cd5\u5728\u786c\u76d8\u4e0a\u521b\u5efa\u65b0\u6587\u4ef6\u3002 $ df -i Filesystem Inodes IUsed IFree IUse% Mounted on tmpfs 497897 872 497025 1 % /run /dev/mapper/ubuntu--vg-ubuntu--lv 3211264 81473 3129791 3 % / tmpfs 497897 1 497896 1 % /dev/shm tmpfs 497897 3 497894 1 % /run/lock /dev/sda2 131072 316 130756 1 % /boot tmpfs 99579 25 99554 1 % /run/user/1000 \u4e0b\u9762\u547d\u4ee4\u53ef\u4ee5\u67e5\u770b\u6bcf\u4e2ainode\u8282\u70b9\u7684\u5927\u5c0f\uff1a $ sudo dumpe2fs -h /dev/sda2 | grep \"Inode size\" dumpe2fs 1 .46.5 ( 30 -Dec-2021 ) Inode size: 256 \u6bcf\u4e2ainode\u90fd\u6709\u4e00\u4e2a\u53f7\u7801\uff0c\u64cd\u4f5c\u7cfb\u7edf\u7528inode\u53f7\u7801\u6765\u8bc6\u522b\u4e0d\u540c\u7684\u6587\u4ef6\uff0c\u6ce8\u610f\uff0c\u4e0d\u662f\u901a\u8fc7\u6587\u4ef6\u540d\u6765\u8bc6\u522b\u4e0d\u540c\u6587\u4ef6\u3002\u4ece\u64cd\u4f5c\u7cfb\u7edf\u89d2\u5ea6\u770b\uff0c\u6587\u4ef6\u540d\u53ea\u662finode\u53f7\u7801\u5bf9\u4e00\u4e2a\u522b\u540d\u3002 \u7528\u6237\u901a\u8fc7\u6587\u4ef6\u540d\uff0c\u6253\u5f00\u67d0\u4e2a\u6587\u4ef6\u7684\u8fc7\u7a0b\uff0c\u64cd\u4f5c\u7cfb\u7edf\u5206\u6210\u4e09\u6b65\u5b8c\u6210\uff1a \u9996\u5148\uff0c\u7cfb\u7edf\u627e\u5230\u8fd9\u4e2a\u6587\u4ef6\u540d\u5bf9\u5e94\u7684inode\u53f7\u7801\u3002 \u5176\u6b21\uff0c\u901a\u8fc7inode\u53f7\uff0c\u83b7\u53d6inode\u4fe1\u606f\u3002 \u7b2c\u4e09\uff0c\u901a\u8fc7inode\u4fe1\u606f\uff0c\u627e\u5230\u6587\u4ef6\u6570\u636e\u6240\u5728\u7684block\uff0c\u8bfb\u51fa\u6570\u636e\u3002 \u901a\u8fc7 ls -i \u547d\u4ee4\uff0c\u53ef\u4ee5\u5f97\u5230\u6587\u4ef6\u5bf9\u5e94\u7684inode\u53f7\uff1a $ ls -i file1 143 file1 \u76ee\u5f55\uff08directory\uff09\u4e5f\u662f\u4e00\u79cd\u6587\u4ef6\u3002\u6253\u5f00\u76ee\u5f55\uff0c\u5b9e\u9645\u4e0a\u5c31\u662f\u6253\u5f00\u76ee\u5f55\u6587\u4ef6\u3002 \u76ee\u5f55\u6587\u4ef6\u7684\u7ed3\u6784\u662f\u7531\u4e00\u4e2a\u5305\u542b\u4e00\u7cfb\u5217\u76ee\u5f55\u9879\uff08dirent\uff09\u7684\u5217\u8868\u7ec4\u6210\u3002 \u6bcf\u4e2a\u76ee\u5f55\u9879\u7531\u4e24\u90e8\u5206\u7ec4\u6210\uff1a\u6240\u5305\u542b\u6587\u4ef6\u7684\u6587\u4ef6\u540d\uff0c\u4ee5\u53ca\u8be5\u6587\u4ef6\u540d\u5bf9\u5e94\u7684inode\u53f7\u3002 \u547d\u4ee4 ls -i \u5217\u51fa\u6574\u4e2a\u76ee\u5f55\u6587\u4ef6\uff0c\u5373\u6587\u4ef6\u540d\u548cinode\u53f7\uff1a $ ls -i 143 file1 140 file2 139 test $ ls -il 143 -rw-r--r--. 1 vagrant wheel 5 Nov 8 20 :49 file1 140 -rw-r--r--. 1 vagrant wheel 0 Oct 1 21 :35 file2 139 drwxr-xr-x. 5 vagrant wheel 4096 Nov 9 22 :00 test","title":"3.1.inode\u7ed3\u6784"},{"location":"linux/SRE/02-filesystem/#32","text":"\u786c\u94fe\u63a5 \uff08Hard links\uff09\u786c\u94fe\u63a5\u662f\u5b58\u50a8\u5377\u4e0a\u6587\u4ef6\u7684\u76ee\u5f55\u5f15\u7528\u6216\u6307\u9488\u3002 \u6587\u4ef6\u540d\u662f\u5b58\u50a8\u5728\u76ee\u5f55\u7ed3\u6784\u4e2d\u7684\u6807\u7b7e\uff0c\u76ee\u5f55\u7ed3\u6784\u6307\u5411\u6587\u4ef6\u6570\u636e\u3002 \u56e0\u6b64\uff0c\u53ef\u4ee5\u5c06\u591a\u4e2a\u6587\u4ef6\u540d\u4e0e\u540c\u4e00\u6587\u4ef6\u5173\u8054\u3002 \u901a\u8fc7\u4e0d\u540c\u7684\u6587\u4ef6\u540d\u8bbf\u95ee\u65f6\uff0c\u6240\u505a\u7684\u4efb\u4f55\u66f4\u6539\u90fd\u662f\u9488\u5bf9\u6e90\u6587\u4ef6\u6570\u636e\u3002 \u7b26\u53f7\u94fe\u63a5 \uff08Symbolic links\uff09: \u7b26\u53f7\u94fe\u63a5\u5305\u542b\u4e00\u4e2a\u6587\u672c\u5b57\u7b26\u4e32\uff0c\u64cd\u4f5c\u7cfb\u7edf\u5c06\u5176\u89e3\u91ca\u4e3a\u53e6\u4e00\u4e2a\u6587\u4ef6\u6216\u76ee\u5f55\u3002 \u5b83\u672c\u8eab\u5c31\u662f\u4e00\u4e2a\u6587\u4ef6\uff0c\u53ef\u4ee5\u72ec\u7acb\u4e8e\u76ee\u6807\u800c\u5b58\u5728\u3002 \u5982\u679c\u5220\u9664\u4e86\u7b26\u53f7\u94fe\u63a5\uff0c\u5219\u5176\u76ee\u6807\u6587\u4ef6\u6216\u76ee\u5f55\u4e0d\u53d7\u5f71\u54cd\u3002 \u5982\u679c\u79fb\u52a8\uff0c\u91cd\u547d\u540d\u6216\u5220\u9664\u76ee\u6807\u6587\u4ef6\u6216\u76ee\u5f55\uff0c\u5219\u7528\u4e8e\u6307\u5411\u5b83\u7684\u4efb\u4f55\u7b26\u53f7\u94fe\u63a5\u5c06\u7ee7\u7eed\u5b58\u5728\uff0c\u4f46\u6307\u5411\u7684\u662f\u4e00\u4e2a\u4e0d\u5b58\u5728\u7684\u6587\u4ef6\u3002 \u4ec5\u5f53\u6587\u4ef6\u548c\u94fe\u63a5\u6587\u4ef6\u4f4d\u4e8e\u540c\u4e00\u6587\u4ef6\u7cfb\u7edf\uff08\u5728\u540c\u4e00\u5206\u533a\u4e0a\uff09\u65f6\uff0c\u624d\u80fd\u4f7f\u7528\u786c\u94fe\u63a5\uff0c\u56e0\u4e3ainode\u7f16\u53f7\u5728\u540c\u4e00\u6587\u4ef6\u7cfb\u7edf\u4e2d\u4ec5\u662f\u552f\u4e00\u7684\u3002 \u53ef\u4ee5\u4f7f\u7528 ln \u547d\u4ee4\u521b\u5efa\u786c\u94fe\u63a5\uff0c\u6307\u5411\u5df2\u5b58\u5728\u6587\u4ef6\u7684inode\uff0c\u53ef\u4ee5\u901a\u8fc7\u6587\u4ef6\u540d\u6216\u8005\u786c\u94fe\u63a5\u540d\u8bbf\u95ee\u6587\u4ef6\u3002 \u53ef\u4ee5\u4f7f\u7528 ln -s \u9009\u9879\u521b\u5efa\u7b26\u53f7\u94fe\u63a5\u3002 \u4e00\u4e2a\u7b26\u53f7\u94fe\u63a5\u4f1a\u88ab\u5206\u914d\u4e00\u4e2a\u5355\u72ec\u7684inode\uff0c\u5e76\u6307\u5411\u4e00\u4e2a\u6587\u4ef6\uff0c\u6240\u4ee5\u53ef\u4ee5\u660e\u663e\u533a\u5206\u7b26\u53f7\u94fe\u63a5\u6587\u4ef6\u548c\u5b9e\u9645\u6587\u4ef6\u3002 \u6587\u4ef6\u7cfb\u7edf\u672c\u8d28\u4e0a\u662f\u4e00\u4e2a\u7528\u4e8e\u8ddf\u8e2a\u5206\u533a\u5377\u4e2d\u7684\u6587\u4ef6\u7684\u6570\u636e\u5e93\u3002 \u5bf9\u4e8e\u666e\u901a\u6587\u4ef6\uff0c\u5206\u914d\u6570\u636e\u5757\u4ee5\u5b58\u50a8\u6587\u4ef6\u7684\u6570\u636e\uff0c\u5206\u914dinode\u4ee5\u6307\u5411\u6570\u636e\u5757\u4ee5\u53ca\u5b58\u50a8\u5173\u4e8e\u6587\u4ef6\u7684\u5143\u6570\u636e\uff0c\u7136\u540e\u5c06\u6587\u4ef6\u540d\u5206\u914d\u7ed9inode\u3002 \u786c\u94fe\u63a5\u662f\u4e0e\u73b0\u6709inode\u5173\u8054\u7684\u8f85\u52a9\u6587\u4ef6\u540d\u3002 \u5bf9\u4e8e\u7b26\u53f7\u94fe\u63a5\uff0c\u5c06\u4e3a\u65b0\u7684inode\u5206\u914d\u4e00\u4e2a\u4e0e\u4e4b\u5173\u8054\u7684\u65b0\u6587\u4ef6\u540d\uff0c\u4f46inode\u5f15\u7528\u53e6\u4e00\u4e2a\u6587\u4ef6\u540d\u800c\u4e0d\u662f\u5f15\u7528\u6570\u636e\u5757\u3002 \u67e5\u770b\u6587\u4ef6\u540d\u548cinode\u4e4b\u95f4\u5173\u7cfb\u7684\u4e00\u4e2a\u65b9\u6cd5\u662f\u4f7f\u7528 ls -il \u547d\u4ee4\u3002inode\u7684\u5178\u578b\u5927\u5c0f\u4e3a128\u4f4d\uff0c\u6570\u636e\u5757\u7684\u5927\u5c0f\u8303\u56f4\u53ef\u4ee5\u662f1k\uff0c2k\uff0c4k\u6216\u66f4\u5927\uff0c\u5177\u4f53\u53d6\u51b3\u4e8e\u6587\u4ef6\u7cfb\u7edf\u7c7b\u578b\u3002 \u8f6f\u8fde\u63a5\u53ef\u4ee5\u9488\u5bf9\u76ee\u5f55\uff0c\u786c\u8fde\u63a5\u53ea\u80fd\u9488\u5bf9\u6587\u4ef6\u3002 \u786c\u94fe\u63a5\u76f8\u5f53\u4e8e\u589e\u52a0\u4e86\u4e00\u4e2a\u767b\u8bb0\u9879\uff0c\u4f7f\u5f97\u539f\u6765\u7684\u6587\u4ef6\u591a\u4e86\u4e00\u4e2a\u540d\u5b57\uff0c\u81f3\u4e8einode\u90fd\u6ca1\u53d8\u3002\u6240\u8c13\u7684\u767b\u8bb0\u9879\u5176\u5b9e\u662f\u76ee\u5f55\u6587\u4ef6\u4e2d\u7684\u4e00\u4e2a\u6761\u76ee(\u76ee\u5f55\u9879)\uff0c\u4f7f\u7528hard link \u662f\u8ba9\u591a\u4e2a\u4e0d\u540c\u7684\u76ee\u5f55\u9879\u6307\u5411\u540c\u4e00\u4e2a\u6587\u4ef6\u7684inode\uff0c\u6ca1\u6709\u591a\u4f59\u7684\u5185\u5bb9\u9700\u8981\u5b58\u50a8\u5728\u78c1\u76d8\u6247\u533a\u4e2d\uff0c\u6240\u4ee5hardlink\u4e0d\u5360\u7528\u989d\u5916\u7684\u7a7a\u95f4\u3002 \u7b26\u53f7\u94fe\u63a5\u6709\u5355\u72ec\u7684inode\uff0c\u5728inode\u4e2d\u5b58\u653e\u53e6\u4e00\u4e2a\u6587\u4ef6\u7684\u8def\u5f84\u800c\u4e0d\u662f\u6587\u4ef6\u6570\u636e\uff0c\u6240\u4ee5\u7b26\u53f7\u94fe\u63a5\u4f1a\u5360\u7528\u989d\u5916\u7684\u7a7a\u95f4\u3002 \u7279\u5f81 \u786c\u94fe\u63a5 \u7b26\u53f7\u94fe\u63a5 \u672c\u8d28 \u540c\u4e00\u4e2a\u6587\u4ef6 \u4e0d\u662f\u540c\u4e00\u4e2a\u6587\u4ef6 \u8de8\u8bbe\u5907 \u4e0d\u652f\u6301 \u652f\u6301 inode \u76f8\u540c \u4e0d\u540c \u94fe\u63a5\u6570 \u521b\u5efa\u786c\u94fe\u63a5\uff0c\u94fe\u63a5\u6570\u4f1a\u589e\u52a0\uff0c\u5220\u9664\u5219\u51cf\u5c11 \u521b\u5efa\u6216\u5220\u9664\uff0c\u94fe\u63a5\u6570\u90fd\u4e0d\u53d8 \u6587\u4ef6\u5939 \u4e0d\u652f\u6301 \u652f\u6301 \u76f8\u5bf9\u8def\u5f84 \u539f\u59cb\u6587\u4ef6\u7684\u76f8\u5bf9\u8def\u5f84\u662f\u76f8\u5bf9\u4e8e\u5f53\u524d\u5de5\u4f5c\u76ee\u5f55 \u539f\u59cb\u6587\u4ef6\u7684\u76f8\u5bf9\u8def\u5f84\u662f\u76f8\u5bf9\u4e8e\u94fe\u63a5\u6587\u4ef6\u7684\u76f8\u5bf9\u8def\u5f84 \u5220\u9664\u6e90\u6587\u4ef6 \u53ea\u662f\u94fe\u63a5\u6570\u51cf\u5c11\uff0c\u94fe\u63a5\u6587\u4ef6\u8bbf\u95ee\u4e0d\u53d7\u5f71\u54cd \u94fe\u63a5\u6587\u4ef6\u5c06\u65e0\u6cd5\u8bbf\u95ee \u6587\u4ef6\u7c7b\u578b \u548c\u6e90\u6587\u4ef6\u76f8\u540c \u94fe\u63a5\u6587\u4ef6\uff0c\u548c\u6e90\u6587\u4ef6\u65e0\u5173 \u6587\u4ef6\u5927\u5c0f \u548c\u6e90\u6587\u4ef6\u76f8\u540c \u6e90\u6587\u4ef6\u7684\u8def\u5f84\u7684\u957f\u5ea6","title":"3.2.\u94fe\u63a5\u7c7b\u578b"},{"location":"linux/SRE/02-filesystem/#33","text":"\u8bbe\u5907\u6587\u4ef6 \uff08Device File\uff09\u8868\u793a\u786c\u4ef6\uff08\u7f51\u5361\u9664\u5916\uff09\u3002 \u6bcf\u4e2a\u786c\u4ef6\u90fd\u7531\u4e00\u4e2a\u8bbe\u5907\u6587\u4ef6\u8868\u793a\u3002 \u7f51\u5361\u662f\u63a5\u53e3\u3002 \u8bbe\u5907\u6587\u4ef6\u628a\u5185\u6838\u9a71\u52a8\u548c\u7269\u7406\u786c\u4ef6\u8bbe\u5907\u8fde\u63a5\u8d77\u6765\u3002 \u5185\u6838\u9a71\u52a8\u7a0b\u5e8f\u901a\u8fc7\u5bf9\u8bbe\u5907\u6587\u4ef6\u8fdb\u884c\u8bfb\u5199\uff08\u6b63\u786e\u7684\u683c\u5f0f\uff09\u6765\u5b9e\u73b0\u5bf9\u786c\u4ef6\u7684\u8bfb\u5199\u3002 \u7c7b\u578b\uff1a \u5757\u8bbe\u5907\uff08Block Devices\uff09\uff1a\u5757\u8bbe\u5907\uff08\u901a\u5e38\uff09\u5728512\u5b57\u8282\u7684\u5927\u5757\u4e2d\u8bfb\u53d6/\u5199\u5165\u4fe1\u606f\u3002 \u5b57\u7b26\u8bbe\u5907\uff08Character Devices\uff09\uff1a\u5b57\u7b26\u8bbe\u5907\u4ee5\u5b57\u7b26\u65b9\u5f0f\u8bfb\u53d6/\u5199\u5165\u4fe1\u606f\u3002 \u5b57\u7b26\u8bbe\u5907\u76f4\u63a5\u63d0\u4f9b\u5bf9\u786c\u4ef6\u8bbe\u5907\u7684\u65e0\u7f13\u51b2\u8bbf\u95ee\u3002 \u6709\u65f6\u79f0\u4e3a\u88f8\u8bbe\u5907\uff08raw devices\uff09\u3002\uff08\u6ce8\u610f\uff1a\u88f8\u8bbe\u5907\u88ab\u89c6\u4e3a\u5b57\u7b26\u8bbe\u5907\uff0c\u4e0d\u662f\u5757\u8bbe\u5907\uff09 \u901a\u8fc7\u8f85\u4ee5\u4e0d\u540c\u9009\u9879\uff0c\u53ef\u4ee5\u5e7f\u6cdb\u800c\u591a\u6837\u5730\u5e94\u7528\u548c\u4f7f\u7528\u5b57\u7b26\u8bbe\u5907\u3002 \u5f53\u5185\u6838\u53d1\u73b0\u8bbe\u5907\u65f6\u7531\u64cd\u4f5c\u7cfb\u7edf udev \u81ea\u52a8\u521b\u5efa\u3002","title":"3.3.\u8bbe\u5907\u6587\u4ef6"},{"location":"linux/SRE/02-filesystem/#34","text":"\u76ee\u6807\uff1a\u4ee5Rocky 9\u4e3a\u4f8b\u3002 \u67e5\u770b\u8f6f/\u786c\u94fe\u63a5\u6587\u4ef6\u7684\u7279\u5f81\u3002 \u67e5\u770b\u76ee\u5f55\u7ed3\u6784\u3002 \u53ef\u4ee5\u901a\u8fc7\u4e0b\u9762\u547d\u4ee4\u5f97\u5230\u5f53\u524d\u7cfb\u7edf\u76842\u7ea7\u76ee\u5f55\u7684\u7ed3\u6784\u3002 tree -L 2 -d / \u521b\u5efa\u7ec3\u4e60\u76ee\u5f55\u3002 mkdir data mkdir -p data/typelink cd data \u521b\u5efa\u786c\u94fe\u63a5\u3002\u6ce8\u610f\uff1a file \u3001 hardlinkfile1 \u3001 hardlinkfile2 \u6587\u4ef6\u7684\u94fe\u63a5\u4f4d\u7f6e\u7684\u6570\u503c\u7684\u53d8\u5316) echo \"it's original file\" > file ln file hardlinkfile1 ln -s file symlinkfile1 ln -s file symlinkfile2 \u6267\u884c ls -l \u547d\u4ee4\u53ef\u4ee5\u5f97\u5230\u4e0b\u9762\u7684\u7ed3\u679c\uff1a -rw-r--r--. 2 vagrant wheel 19 Nov 1 10 :42 file -rw-r--r--. 2 vagrant wheel 19 Nov 1 10 :42 hardlinkfile1 lrwxrwxrwx. 1 vagrant wheel 4 Nov 1 10 :43 symlinkfile1 -> file lrwxrwxrwx. 1 vagrant wheel 4 Nov 1 10 :43 symlinkfile2 -> file \u521b\u5efa\u53e6\u5916\u4e00\u4e2a\u786c\u94fe\u63a5\u3002 ln file hardlinkfile2 \u6267\u884c ls -l \u547d\u4ee4\u53ef\u4ee5\u5f97\u5230\u4e0b\u9762\u7684\u7ed3\u679c\uff1a -rw-r--r--. 3 vagrant wheel 19 Nov 1 10 :42 file -rw-r--r--. 3 vagrant wheel 19 Nov 1 10 :42 hardlinkfile1 -rw-r--r--. 3 vagrant wheel 19 Nov 1 10 :42 hardlinkfile2 lrwxrwxrwx. 1 vagrant wheel 4 Nov 1 10 :43 symlinkfile1 -> file lrwxrwxrwx. 1 vagrant wheel 4 Nov 1 10 :43 symlinkfile2 -> file \u4fee\u6539 file \u6587\u4ef6\u7684\u5185\u5bb9\u3002 echo \"add oneline\" >> file \u901a\u8fc7\u547d\u4ee4 cat file \u67e5\u770b\u5f53\u524d file \u7684\u5185\u5bb9\u3002 it ' s original file add oneline \u901a\u8fc7\u4e0b\u9762\u7684\u547d\u4ee4\uff0c\u53ef\u4ee5\u770b\u5230\u6240\u4ee5\u8f6f/\u786c\u94fe\u63a5\u6587\u4ef6\u5185\u5bb9\u90fd\u66f4\u65b0\u4e86\uff0c\u548c file \u6587\u4ef6\u66f4\u65b0\u540e\u7684\u5185\u5bb9\u4fdd\u6301\u4e00\u81f4\u3002 cat hardlinkfile1 cat hardlinkfile2 cat symlinkfile1 cat symlinkfile2 \u5bf9\u6587\u4ef6 symlinkfile1 \u518d\u521b\u5efa\u65b0\u7684\u8f6f\u8fde\u63a5\u3002 ln -s symlinkfile1 symlinkfile1-1 \u901a\u8fc7\u547d\u4ee4 ls -il \u67e5\u770b\u73b0\u5728\u7684\u76ee\u5f55\u4fe1\u606f\u3002 67274680 -rw-r--r--. 3 vagrant wheel 31 Nov 1 11 :14 file 67274680 -rw-r--r--. 3 vagrant wheel 31 Nov 1 11 :14 hardlinkfile1 67274680 -rw-r--r--. 3 vagrant wheel 31 Nov 1 11 :14 hardlinkfile2 67274681 lrwxrwxrwx. 1 vagrant wheel 4 Nov 1 10 :43 symlinkfile1 -> file 67274683 lrwxrwxrwx. 1 vagrant wheel 12 Nov 1 11 :20 symlinkfile1-1 -> symlinkfile1 67274682 lrwxrwxrwx. 1 vagrant wheel 4 Nov 1 10 :43 symlinkfile2 -> file \u8bfb\u53d6\u8f6f\u94fe\u63a5\u6587\u4ef6\u7684\u6e90\u6587\u4ef6\u4fe1\u606f readlink symlinkfile1 readlink symlinkfile2 \u6ce8\u610f\uff0c\u5bf9\u4e8e symlinkfile1-1 \u7684\u60c5\u51b5\u6709\u4e9b\u4e0d\u540c\u3002 readlink symlinkfile1-1 \u4e0a\u9762\u547d\u4ee4\u8fd4\u56de\u7ed3\u679c symlinkfile1 \u4ecd\u7136\u662f\u4e00\u4e2a\u7b26\u53f7\u94fe\u63a5\u6587\u4ef6\u3002\u901a\u8fc7 readlink -f \u53ef\u4ee5\u76f4\u63a5\u5b9a\u4f4d\u771f\u6b63\u7684\u6e90\u6587\u4ef6\u3002 readlink -f symlinkfile1-1 \u4e0a\u9762\u7684\u8fd4\u56de\u7ed3\u679c /data/linktype/file \u662f symlinkfile1-1 \u771f\u6b63\u7684\u6e90\u6587\u4ef6\u3002 \u663e\u793a data \u76ee\u5f55\u4e0b\u7684\u6587\u4ef6\u548c\u5b50\u76ee\u5f55\uff1a cd ~ tree ./data \u8fd0\u884c\u7ed3\u679c\uff1a ./data \u251c\u2500\u2500 file \u251c\u2500\u2500 hardlinkfile1 \u251c\u2500\u2500 hardlinkfile2 \u251c\u2500\u2500 symlinkfile1 -> file \u251c\u2500\u2500 symlinkfile1-1 -> symlinkfile1 \u251c\u2500\u2500 symlinkfile2 -> file \u2514\u2500\u2500 typelink \u53ea\u663e\u793a data \u76ee\u5f55\u4e0b\u7684\u5b50\u76ee\u5f55\uff1a tree -d ./data \u8fd0\u884c\u7ed3\u679c\uff1a ./data \u2514\u2500\u2500 typelink \u663e\u793a data \u76ee\u5f55\u4e0b\u7684\u6587\u4ef6\u548c\u5b50\u76ee\u5f55\uff0c\u5305\u542b\u5168\u76ee\u5f55\uff1a tree -f ./data \u8fd0\u884c\u7ed3\u679c\uff1a ./data \u251c\u2500\u2500 ./data/file \u251c\u2500\u2500 ./data/hardlinkfile1 \u251c\u2500\u2500 ./data/hardlinkfile2 \u251c\u2500\u2500 ./data/symlinkfile1 -> file \u251c\u2500\u2500 ./data/symlinkfile1-1 -> symlinkfile1 \u251c\u2500\u2500 ./data/symlinkfile2 -> file \u2514\u2500\u2500 ./data/typelink","title":"3.4.\u7ec3\u4e60"},{"location":"linux/SRE/02-filesystem/#4","text":"\u6267\u884c\u547d\u4ee4 ls -ihl \uff0c\u53ef\u4ee5\u5f97\u5230\u4e0b\u9762\u7684\u8f93\u51fa\u7ed3\u679c\uff08Rocky 9\uff09\u3002 67274680 -rw-r--r--. 3 vagrant wheel 31 Nov 1 11 :14 file 67274680 -rw-r--r--. 3 vagrant wheel 31 Nov 1 11 :14 hardlinkfile1 67274680 -rw-r--r--. 3 vagrant wheel 31 Nov 1 11 :14 hardlinkfile2 67274681 lrwxrwxrwx. 1 vagrant wheel 4 Nov 1 10 :43 symlinkfile1 -> file 67274683 lrwxrwxrwx. 1 vagrant wheel 12 Nov 1 11 :20 symlinkfile1-1 -> symlinkfile1 67274682 lrwxrwxrwx. 1 vagrant wheel 4 Nov 1 10 :43 symlinkfile2 -> file 33555262 drwxr-xr-x. 2 vagrant wheel 6 Nov 1 11 :30 typelink \u4ee5 67274680 -rw-r--r--. 3 vagrant wheel 31 Nov 1 11:14 file \u4e3a\u4f8b\uff1a 67274680 : inode \u7d22\u5f15\u8282\u70b9\u7f16\u53f7\u3002 -rw-r--r-- \uff1a\u6587\u4ef6\u7c7b\u578b\u53ca\u6743\u9650 - \uff1a\u6587\u4ef6\u7c7b\u578b\uff0c\u4f8b\u5b50\u4e2d\u51fa\u73b0\u4e86\u4e09\u79cd\uff0c - \uff0c l \u548c d \u3002 - \uff1a\u666e\u901a\u6587\u4ef6 d \uff1a\u76ee\u5f55 l \uff1a\u7b26\u53f7\u94fe\u63a5\u6587\u4ef6\uff08link\uff09 b \uff1a\u5757\u8bbe\u5907\uff08block\uff09 c \uff1a\u5b57\u7b26\u8bbe\u5907\uff08character\uff09 p \uff1a\u7ba1\u9053\u6587\u4ef6\uff08pipe\uff09 s \uff1a\u5957\u63a5\u5b57\u6587\u4ef6\uff08socket\uff09 rw-r--r-- \uff1a\u6587\u4ef6\u6743\u9650\uff0c\u4ece\u5de6\u5230\u53f3\u4f9d\u6b21\u4e3a\uff1a rw- \uff1a\u6587\u4ef6\u5c5e\u4e3b\u6743\u9650\uff0c\u4f8b\u5b50\u4e2d\u662f vagrant \u3002 r-- \uff1a\u6587\u4ef6\u5c5e\u7ec4\u7684\u6743\u9650\uff0c\u4f8b\u5b50\u4e2d\u662f wheel \u3002 r-- \uff1a\u5176\u4ed6\u7ec4\u7684\u6743\u9650\u3002 . \uff1a\u8fd9\u4e2a\u70b9\u8868\u793a\u6587\u4ef6\u5e26\u6709SELinux\u7684\u5b89\u5168\u4e0a\u4e0b\u6587\uff08SELinux Contexts\uff09\u3002\u5173\u95edSELinux\uff0c\u65b0\u521b\u5efa\u7684\u6587\u4ef6\u5c31\u4e0d\u4f1a\u518d\u6709\u8fd9\u4e2a\u70b9\u4e86\u3002\u4f46\u662f\uff0c\u4ee5\u524d\u521b\u5efa\u7684\u6587\u4ef6\u672c\u6765\u6709\u8fd9\u4e2a\u70b9\u7684\u8fd8\u4f1a\u663e\u793a\u8fd9\u4e2a\u70b9\uff08\u867d\u7136SELinux\u4e0d\u8d77\u4f5c\u7528\u4e86\uff09\u3002 3 \uff1a\u786c\u94fe\u63a5\u6570\uff0c\u4f8b\u5b50\u4e2d file \u548c hardlinkfile1 \u548c hardlinkfile2 \u4e4b\u95f4\u662f\u786c\u94fe\u63a5\uff0c\u6240\u4ee5\u8fd9\u4e09\u4e2a\u6587\u4ef6\u7684\u786c\u94fe\u63a5\u6570\u90fd\u662f 3 \u3002 vagrant \uff1a\u6587\u4ef6\u5c5e\u4e3b wheel \uff1a\u6587\u4ef6\u5c5e\u7ec4 31 \uff1a\u6587\u4ef6\u6216\u76ee\u5f55\u7684\u5927\u5c0f Nov 1 11:14 \uff1a\u6587\u4ef6\u6216\u76ee\u5f55\u7684\u521b\u5efa\u65e5\u671f\u548c\u65f6\u95f4 file \uff1a\u6587\u4ef6\u6216\u76ee\u5f55\u540d\u79f0 \u4e0b\u9762\u662f\u547d\u4ee4 ls -ihl \u5728openSUSE\u548cUbuntu\u4e0a\u7684\u663e\u793a\u7ed3\u679c\u3002 $ ls -ihl 233647 -rw-r--r-- 3 vagrant wheel 31 Nov 1 15 :52 file 233647 -rw-r--r-- 3 vagrant wheel 31 Nov 1 15 :52 hardlinkfile1 233647 -rw-r--r-- 3 vagrant wheel 31 Nov 1 15 :52 hardlinkfile2 233648 lrwxrwxrwx 1 vagrant wheel 4 Nov 1 15 :52 symlinkfile1 -> file 233650 lrwxrwxrwx 1 vagrant wheel 12 Nov 1 15 :52 symlinkfile1-1 -> symlinkfile1 233649 lrwxrwxrwx 1 vagrant wheel 4 Nov 1 15 :52 symlinkfile2 -> file 233646 drwxr-xr-x 1 vagrant wheel 0 Nov 1 15 :51 typelink","title":"4.\u6587\u4ef6\u5c5e\u6027\u8bf4\u660e"},{"location":"linux/SRE/02-filesystem/#5","text":"\u6807\u51c6\u8f93\u5165\u8f93\u51fa\uff0c\u5373I/O\uff0cI/O\u7684I\u662fInput\uff0cO\u662foutput\u3002 I\uff1a\u4ece\u5916\u90e8\u8bbe\u5907\u8f93\u5165\u5230\u5185\u5b58 O\uff1a\u4ece\u5185\u5b58\u8f93\u51fa\u5230\u5916\u90e8\u8bbe\u5907 \u6807\u51c6\u8f93\u5165\u548c\u6807\u51c6\u8f93\u51fa\u662f\u7528\u4e8eIO\u7684\uff0c\u5b83\u4eec\u5c5e\u4e8e\u5916\u90e8\u8bbe\u5907\uff08\u903b\u8f91\u4e0a\u7684\u5916\u90e8\u8bbe\u5907\uff09\uff0c\u4e0d\u662f\u5185\u5b58\u3002 linux\u4e2d\u4e00\u5207\u8bbe\u5907\u7686\u662f\u6587\u4ef6\uff01\u56e0\u6b64\u6807\u51c6\u8f93\u5165\u548c\u8f93\u51fa\u672c\u8d28\u5c31\u662f\u6587\u4ef6\uff0c\u5916\u90e8\u8bbe\u5907\u4ee5\u6587\u4ef6\u5f62\u5f0f\u8868\u73b0\u3002 \u5728Linux\u7cfb\u7edf\u4e2d\uff0c\u6807\u51c6\u8f93\u5165\u548c\u6807\u51c6\u8f93\u51fa\u5bf9\u5e94\u7684\u6587\u4ef6\u662f /dev/stdin \u548c /dev/stdout \u8fd9\u4e24\u4e2a\u6587\u4ef6\u3002 \u4ece\u6807\u51c6\u8f93\u5165\u8bfb\uff0c\u4ece\u903b\u8f91\u4e0a\u8bb2\uff0c\u5c31\u662f\u6253\u5f00 /dev/stdin \u8fd9\u4e2a\u6587\u4ef6\uff0c\u5e76\u8bfb\u5165\u6587\u4ef6\u5185\u5bb9\u3002 \u8f93\u51fa\u5230\u6807\u51c6\u8f93\u51fa\uff0c\u4ece\u903b\u8f91\u4e0a\u8bb2\uff0c\u5c31\u662f\u6253\u5f00 /dev/stdout \u8fd9\u4e2a\u6587\u4ef6\uff0c\u5e76\u628a\u5185\u5bb9\u8f93\u51fa\u5230\u8fd9\u4e2a\u6587\u4ef6\u91cc\u53bb\u3002 \u8fd9\u91cc\u5f3a\u8c03\u7684\u662f\u201c\u903b\u8f91\u4e0a\u201d\uff0c\u56e0\u4e3a /dev/stdin \u548c /dev/stdout \u8fd92\u4e2a\u6587\u4ef6\u672c\u8eab\u4e0d\u662f\u8bbe\u5907\u6587\u4ef6\u3002Linux\u4e2d\u8bbe\u5907\u662f\u6587\u4ef6\uff0c\u4f46\u662f\u6587\u4ef6\u4e0d\u4e00\u5b9a\u662f\u8bbe\u5907\u3002 \u56e0\u6b64\uff0c\u64cd\u4f5c /dev/stdin \u548c/dev/stdout`\u8fd92\u4e2a\u6587\u4ef6\uff0c\u5b9e\u9645\u4e0a\u662f\u64cd\u4f5c\u4e24\u4e2a\u6587\u4ef6\u5b58\u653e\u5730\u5740\u5bf9\u5e94\u7684\u8bbe\u5907\u6587\u4ef6\u3002 \u901a\u8fc7\u4e0b\u9762\u547d\u4ee4\u53ef\u4ee5\u770b\u5230\u6807\u51c6\u8f93\u5165\u8f93\u51fa\u6587\u4ef6\u7684\u7279\u70b9\uff0c\u4ed6\u4eec\u867d\u7136\u5728 /dev \u76ee\u5f55\u4e0b\uff0c\u90fd\u662f\u4ee5 l \u5f00\u5934\u7684\u94fe\u63a5\u6587\u4ef6\uff0c\u6307\u5411\u7684\u662f\u53e6\u4e00\u4e2a\u6587\u4ef6\u7684\u5730\u5740\u3002 $ ls -l /dev/std* lrwxrwxrwx 1 root root 15 Nov 13 10 :39 /dev/stderr -> /proc/self/fd/2 lrwxrwxrwx 1 root root 15 Nov 13 10 :39 /dev/stdin -> /proc/self/fd/0 lrwxrwxrwx 1 root root 15 Nov 13 10 :39 /dev/stdout -> /proc/self/fd/1 # Rocky $ ll /proc/self/fd/ lrwx------. 1 vagrant wheel 64 Nov 13 22 :38 0 -> /dev/pts/0 lrwx------. 1 vagrant wheel 64 Nov 13 22 :38 1 -> /dev/pts/0 lrwx------. 1 vagrant wheel 64 Nov 13 22 :38 2 -> /dev/pts/0 lr-x------. 1 vagrant wheel 64 Nov 13 22 :38 3 -> /proc/1702/fd # Ubuntu $ ll /proc/self/fd/ lrwx------ 1 vagrant sudo 64 Nov 13 14 :38 0 -> /dev/pts/0 lrwx------ 1 vagrant sudo 64 Nov 13 14 :38 1 -> /dev/pts/0 lrwx------ 1 vagrant sudo 64 Nov 13 14 :38 2 -> /dev/pts/0 lr-x------ 1 vagrant sudo 64 Nov 13 14 :38 3 -> /proc/2062/fd/ # openSUSE $ ll /proc/self/fd/* ls: cannot access '/proc/self/fd/255' : No such file or directory ls: cannot access '/proc/self/fd/3' : No such file or directory lrwx------ 1 vagrant wheel 64 Nov 13 22 :37 /proc/self/fd/0 -> /dev/pts/0 lrwx------ 1 vagrant wheel 64 Nov 13 22 :37 /proc/self/fd/1 -> /dev/pts/0 lrwx------ 1 vagrant wheel 64 Nov 13 22 :37 /proc/self/fd/2 -> /dev/pts/0 Linux\u8fdb\u7a0b\u9ed8\u8ba4\u4f1a\u6253\u5f00\u7684\u4e09\u4e2a\u6587\u4ef6\uff1a \u6807\u51c6\u8f93\u5165 /dev/stdin \uff0c\u63cf\u8ff0\u7b26\u4e3a 0\uff0c\u9ed8\u8ba4\u662f\u952e\u76d8\u8f93\u5165\u3002 \u6807\u51c6\u8f93\u51fa /dev/stdout \uff0c\u63cf\u8ff0\u7b26\u4e3a 1\uff0c\u9ed8\u8ba4\u662f\u8f93\u51fa\u5230\u5c4f\u5e55\u3002 \u6807\u51c6\u8f93\u51fa /dev/stderr \uff0c\u63cf\u8ff0\u7b26\u4e3a 2\uff0c\u9ed8\u8ba4\u662f\u8f93\u51fa\u5230\u5c4f\u5e55\u3002 \u4ee5Rocky\u4e3a\u4f8b\uff0c\u521b\u5efa file.py \u6587\u4ef6\u3002 $ cat > file.py < test.txt \u8fd0\u884c file.py \u7a0b\u5e8f\u3002 python3 file.py \u6253\u5f00\u65b0\u7684\u7ec8\u7aef\u7a97\u53e3\uff0c\u6267\u884c\u4e0b\u9762\u547d\u4ee4\uff0c\u5f97\u5230python3\u8fd9\u4e2a\u7a0b\u5e8f\u8fd0\u884c\u7684process ID\u3002\u5176\u4e2d\u53ef\u4ee5\u770b\u5230\u6709\u4e00\u4e2a\u6765\u81ea\u6587\u4ef6test.txt\u88ab\u7a0b\u5e8ffile.py\u6253\u5f00\uff08\u8f93\u5165\uff09\u3002 $ pidof python3 1739 788 $ sudo ls -l /proc/788/fd/ lr-x------. 1 root root 64 Nov 13 23 :00 0 -> /dev/null l-wx------. 1 root root 64 Nov 13 23 :00 1 -> /dev/null lrwx------. 1 root root 64 Nov 13 23 :00 10 -> 'socket:[24677]' lrwx------. 1 root root 64 Nov 13 23 :00 11 -> 'socket:[24678]' l-wx------. 1 root root 64 Nov 13 23 :00 2 -> /dev/null l-wx------. 1 root root 64 Nov 13 10 :41 3 -> /var/log/firewalld lrwx------. 1 root root 64 Nov 13 23 :00 4 -> 'socket:[23421]' lrwx------. 1 root root 64 Nov 13 23 :00 5 -> 'anon_inode:[eventfd]' lrwx------. 1 root root 64 Nov 13 23 :00 6 -> 'socket:[24586]' lr-x------. 1 root root 64 Nov 13 23 :00 7 -> anon_inode:inotify lrwx------. 1 root root 64 Nov 13 23 :00 8 -> 'anon_inode:[eventfd]' lrwx------. 1 root root 64 Nov 13 23 :00 9 -> '/memfd:libffi (deleted)' $ sudo ls -l /proc/1739/fd/ lrwx------. 1 vagrant wheel 64 Nov 13 23 :00 0 -> /dev/pts/0 lrwx------. 1 vagrant wheel 64 Nov 13 23 :00 1 -> /dev/pts/0 lrwx------. 1 vagrant wheel 64 Nov 13 23 :00 2 -> /dev/pts/0 lr-x------. 1 vagrant wheel 64 Nov 13 23 :00 3 -> /home/vagrant/test.txt \u5728Ubuntu\u4e2d\u8fd0\u884c file.py \u7a0b\u5e8f\uff0cpidof\u4f1a\u53d6\u5f973\u4e2aprocess IDs\u3002 $ pidof python3 2128 924 873 $ sudo ls -l /proc/2128/fd/ lrwx------ 1 vagrant sudo 64 Nov 13 15 :10 0 -> /dev/pts/0 lrwx------ 1 vagrant sudo 64 Nov 13 15 :10 1 -> /dev/pts/0 lrwx------ 1 vagrant sudo 64 Nov 13 15 :10 2 -> /dev/pts/0 lr-x------ 1 vagrant sudo 64 Nov 13 15 :10 3 -> /home/vagrant/test.txt $ sudo ls -l /proc/924/fd/ lr-x------ 1 root root 64 Nov 13 15 :11 0 -> /dev/null lrwx------ 1 root root 64 Nov 13 15 :11 1 -> 'socket:[31593]' lrwx------ 1 root root 64 Nov 13 15 :11 2 -> 'socket:[31593]' l-wx------ 1 root root 64 Nov 13 02 :40 3 -> /var/log/unattended-upgrades/unattended-upgrades-shutdown.log lrwx------ 1 root root 64 Nov 13 15 :11 4 -> 'socket:[31652]' lrwx------ 1 root root 64 Nov 13 15 :11 5 -> 'anon_inode:[eventfd]' lrwx------ 1 root root 64 Nov 13 15 :11 6 -> 'anon_inode:[eventfd]' lrwx------ 1 root root 64 Nov 13 15 :11 7 -> 'socket:[31657]' l-wx------ 1 root root 64 Nov 13 15 :11 8 -> /run/systemd/inhibit/1.ref lrwx------ 1 root root 64 Nov 13 15 :11 9 -> 'socket:[31658]' $ sudo ls -l /proc/873/fd/ lr-x------ 1 root root 64 Nov 13 15 :11 0 -> /dev/null lrwx------ 1 root root 64 Nov 13 15 :11 1 -> 'socket:[31412]' lrwx------ 1 root root 64 Nov 13 15 :11 2 -> 'socket:[31412]' lrwx------ 1 root root 64 Nov 13 02 :40 3 -> 'socket:[31650]' lrwx------ 1 root root 64 Nov 13 15 :11 4 -> 'anon_inode:[eventfd]' lrwx------ 1 root root 64 Nov 13 15 :11 5 -> 'socket:[31663]' lrwx------ 1 root root 64 Nov 13 15 :11 6 -> 'socket:[31664]' openSUSE\u9700\u8981\u5b89\u88c5\u5305 sysvinit-tools \u624d\u80fd\u4f7f\u7528 pidof \u547d\u4ee4\u3002 sudo zypper in sysvinit-tools \u7531\u4e8eopenSUSE\u4e2dpidof python3\u53ea\u8fd4\u56de\u4e00\u4e2aprocess ID\uff0c\u6240\u4ee5\u53ef\u4ee5\u7b80\u5316\u547d\u4ee4\u884c\u5f97\u5230process ID\u7684\u8be6\u7ec6\u4fe1\u606f\u3002 $ sudo ls -l /proc/ ` pidof python3 ` /fd/ lrwx------ 1 vagrant wheel 64 Nov 13 23 :21 0 -> /dev/pts/0 lrwx------ 1 vagrant wheel 64 Nov 13 23 :21 1 -> /dev/pts/0 lrwx------ 1 vagrant wheel 64 Nov 13 23 :21 2 -> /dev/pts/0 lr-x------ 1 vagrant wheel 64 Nov 13 23 :21 3 -> /home/vagrant/test.txt \u53c2\u8003\uff1a \u5f53\u952e\u76d8\u548c\u9f20\u6807\u7b49\u8bbe\u5907\u901a\u8fc7\u4e32\u53e3\u76f4\u63a5\u8fde\u63a5\u5230\u8ba1\u7b97\u673a\u65f6\uff0c\u8fd9\u79cd\u8fde\u63a5\u79f0\u4e3aTTY\u3002 \u4f2a\u7ec8\u7aefpseudoterminal\uff08\u7f29\u5199\u4e3a\u201cpty\u201d\uff09\u662f\u4e00\u5bf9\u63d0\u4f9b\u53cc\u5411\u901a\u4fe1\u901a\u9053\u7684\u865a\u62df\u5b57\u7b26\u8bbe\u5907\u3002 \u901a\u9053\u7684\u4e00\u7aef\u79f0\u4e3a\u4e3b\u7aefmaster\uff1b \u53e6\u4e00\u7aef\u79f0\u4e3a\u4ece\u7aefslave\u3002 /dev/pts \u8868\u793a\u4e0e\u4f2a\u7ec8\u7aefpseudoterminal\u7684\u4e3b\u7aefmaster\u6216\u4ece\u7aefslave\u76f8\u5173\u7684master\u6587\u4ef6\uff0c\u64cd\u4f5c\u7cfb\u7edf\u5c06\u5176\u4fdd\u5b58\u4e3a /dev/ptmx \u6587\u4ef6\u3002 telnet \u548c ssh \u7b49\u7a0b\u5e8f\u80fd\u591f\u4eff \u7aef\u7528\u6237> \u4e0e\u5b83\u4eec\u7684\u4ea4\u4e92\uff0c\u867d\u7136\u672c\u8d28\u4e0a\u662f\u4e0e\u6587\u4ef6 /dev/ptmx \u8fdb\u884c\u4ea4\u4e92\uff0c\u4f46\u5448\u73b0\u7ed9\u7528\u6237\u7684\u5374\u662f\u597d\u50cf\u8fd0\u884c\u5728\u771f\u6b63\u7684\u7ec8\u7aef\u7a97\u53e3\u4e00\u6837\uff0c\u4ece\u7aef\u7684\u6587\u4ef6\u662f\u4e3b\u7aef\u7684\u8f93\u5165\u3002 \u4f2a\u7ec8\u7aef\u8fdb\u7a0b\u5728Linux\u4e2d\u88ab\u5b58\u50a8\u5728 /dev/pts/ \u76ee\u5f55\u4e0b\u3002 /dev/pts/ \u76ee\u5f55\u4e0b\u7684\u5185\u5bb9\u662f\u4e00\u4e9b\u7279\u6b8a\u7684\u76ee\u5f55\uff0c\u7531Linux\u5185\u6838\u6240\u521b\u5efa\u3002 \u6bcf\u4e2a\u552f\u4e00\u7684\u7ec8\u7aef\u7a97\u53e3\u90fd\u4e0e /dev/pts \u7cfb\u7edf\u4e2d\u7684\u4e00\u4e2aLinux pts \u6761\u76ee\u76f8\u5173\u3002 \u4e0b\u9762\u8fd4\u56de\u7684\u7ed3\u679c\u8bf4\u660e\u67092\u4e2a\u8fdc\u7a0b\u7ec8\u7aef\u8fde\u63a5\u5230\u5f53\u524d\u7684\u673a\u5668\u3002 $ ll /dev/pts/ crw--w----. 1 vagrant tty 136 , 0 Nov 13 23 :18 0 crw--w----. 1 vagrant tty 136 , 1 Nov 13 23 :48 1 c---------. 1 root root 5 , 2 Nov 13 10 :41 ptmx \u4e5f\u53ef\u4ee5\u901a\u8fc7 w \u547d\u4ee4\u770b\u52302\u4e2a\u7ec8\u7aef\u8fdb\u7a0b\u3002 $ w 23 :55:05 up 13 :14, 2 users, load average: 0 .00, 0 .00, 0 .00 USER TTY LOGIN@ IDLE JCPU PCPU WHAT vagrant pts/0 10 :51 37 :03 0 .05s 0 .05s -bash vagrant pts/1 23 :48 0 .00s 0 .03s 0 .00s w \u5355\u4e2a\u4f2a\u7ec8\u7aefpseudoterminal\u53ef\u4ee5\u540c\u65f6\u63a5\u6536\u6765\u81ea\u4e0d\u540c\u7684\u7a0b\u5e8f\u7684\u8f93\u51fa\u3002 \u591a\u4e2a\u7a0b\u5e8f\u540c\u65f6\u5bf9\u4e00\u4e2a\u4f2a\u7ec8\u7aefpseudoterminal\u8fdb\u884c\u8bfb\u53d6\u4f1a\u5f15\u8d77\u6df7\u6dc6\u3002 \u5b58\u50a8\u5728 /dev/pts \u76ee\u5f55\u4e2d\u7684\u6587\u4ef6\u662f\u62bd\u8c61\u6587\u4ef6\u800c\u4e0d\u662f\u771f\u5b9e\u6587\u4ef6\uff0c\u662f\u4f2a\u7ec8\u7aef\u4e2d\u6267\u884c\u7a0b\u5e8f\u65f6\u4e34\u65f6\u5b58\u50a8\u7684\u6570\u636e\u3002 \u6253\u5f00 /dev/pts \u4e0b\u7684\u6587\u4ef6\u901a\u5e38\u6ca1\u6709\u4ec0\u4e48\u5b9e\u9645\u610f\u4e49\u3002","title":"5.\u6807\u51c6\u8f93\u5165\u8f93\u51fa"},{"location":"linux/SRE/02-filesystem/#6","text":"","title":"6.\u91cd\u5b9a\u5411\u548c\u7ba1\u9053"},{"location":"linux/SRE/02-filesystem/#61","text":"\u5e38\u7528\u547d\u4ee4\u683c\u5f0f\uff1a command < file \uff1a\u5c06\u6307\u5b9a\u6587\u4ef6 file \u4f5c\u4e3a\u547d\u4ee4\u7684\u8f93\u5165\u8bbe\u5907\u3002 command << delimiter \uff1a\u8868\u793a\u4ece\u6807\u51c6\u8f93\u5165\u8bbe\u5907\uff08\u952e\u76d8\uff09\u4e2d\u8bfb\u5165\uff0c\u76f4\u5230\u9047\u5230\u5206\u754c\u7b26 delimiter \u505c\u6b62\uff08\u8bfb\u5165\u7684\u6570\u636e\u4e0d\u5305\u62ec\u5206\u754c\u7b26\uff09\uff0c\u8fd9\u91cc\u7684\u5206\u754c\u7b26\u53ef\u4ee5\u7406\u89e3\u4e3a\u81ea\u5b9a\u4e49\u7684\u5b57\u7b26\u4e32\u3002 command < file1 > file2 \uff1a\u5c06 file1 \u4f5c\u4e3a\u547d\u4ee4\u7684\u8f93\u5165\u8bbe\u5907\uff0c\u8be5\u547d\u4ee4\u7684\u6267\u884c\u7ed3\u679c\u8f93\u51fa\u5230 file2 \u4e2d\u3002 # \u8f93\u51fa\u6587\u4ef6file.py\u5185\u5bb9\uff08\u8f93\u5165\u8bbe\u5907\u662f\u952e\u76d8\uff09 $ cat file.py # \u8f93\u51fa\u6587\u4ef6file.py\u5185\u5bb9\uff08\u8f93\u5165\u8bbe\u5907\u662f\u6587\u4ef6file.py\uff09 $ cat < file.py # \u6307\u5b9a\u5206\u754c\u7b26\uff08\u8fd9\u91cc\u662fEOF\uff09\uff0c\u8bfb\u53d6\u952e\u76d8\u8f93\u5165\u5185\u5bb9\uff0c\u76f4\u5230\u9047\u5230\u6307\u5b9a\u5206\u754c\u7b26\u4e3a\u6b62\uff0c\u5c06\u6240\u8bfb\u53d6\u7684\u5185\u5bb9\u8f93\u51fa\u5230\u6587\u4ef6file.py\u3002 $ cat > file.py < new.py","title":"6.1.\u8f93\u5165\u91cd\u5b9a\u5411"},{"location":"linux/SRE/02-filesystem/#62","text":"\u8f93\u51fa\u91cd\u5b9a\u5411\u5206\u4e3a\u6807\u51c6\u8f93\u51fa\u91cd\u5b9a\u5411\u548c\u9519\u8bef\u8f93\u51fa\u91cd\u5b9a\u5411\u4e24\u79cd\u3002 \u5e38\u7528\u547d\u4ee4\u683c\u5f0f\uff1a command > file \uff1a\u5c06\u547d\u4ee4 command \u6267\u884c\u7684\u6807\u51c6\u8f93\u51fa\u7ed3\u679c\u91cd\u5b9a\u5411\u8f93\u51fa\u5230\u6307\u5b9a\u7684\u6587\u4ef6 file \u4e2d\uff0c\u5982\u679c\u8be5\u6587\u4ef6\u5df2\u5305\u542b\u6570\u636e\uff0c\u4f1a\u6e05\u7a7a\u539f\u6709\u6570\u636e\uff0c\u518d\u5199\u5165\u65b0\u6570\u636e\u3002 command 2> file \uff1a\u5c06\u547d\u4ee4 command \u6267\u884c\u7684\u9519\u8bef\u8f93\u51fa\u7ed3\u679c\u91cd\u5b9a\u5411\u5230\u6307\u5b9a\u7684\u6587\u4ef6 file \u4e2d\uff0c\u5982\u679c\u8be5\u6587\u4ef6\u4e2d\u5df2\u5305\u542b\u6570\u636e\uff0c\u4f1a\u6e05\u7a7a\u539f\u6709\u6570\u636e\uff0c\u518d\u5199\u5165\u65b0\u6570\u636e\u3002 command >> file \uff1a\u5c06\u547d\u4ee4 command \u6267\u884c\u7684\u6807\u51c6\u8f93\u51fa\u7ed3\u679c\u91cd\u5b9a\u5411\u8f93\u51fa\u5230\u6307\u5b9a\u7684\u6587\u4ef6 file \u4e2d\uff0c\u5982\u679c\u8be5\u6587\u4ef6\u5df2\u5305\u542b\u6570\u636e\uff0c\u65b0\u6570\u636e\u5c06\u8ffd\u52a0\u5199\u5165\u5230\u539f\u6709\u5185\u5bb9\u7684\u540e\u9762\u3002 command 2>> file \uff1a\u5c06\u547d\u4ee4 command \u6267\u884c\u7684\u9519\u8bef\u8f93\u51fa\u7ed3\u679c\u91cd\u5b9a\u5411\u5230\u6307\u5b9a\u7684\u6587\u4ef6 file \u4e2d\uff0c\u5982\u679c\u8be5\u6587\u4ef6\u4e2d\u5df2\u5305\u542b\u6570\u636e\uff0c\u65b0\u6570\u636e\u5c06\u8ffd\u52a0\u5199\u5165\u5230\u539f\u6709\u5185\u5bb9\u7684\u540e\u9762\u3002 command >> file 2>&1 \u6216\u8005 command &>> file \uff1a\u5c06\u6807\u51c6\u8f93\u51fa\u6216\u8005\u9519\u8bef\u8f93\u51fa\u5199\u5165\u5230\u6307\u5b9a\u6587\u4ef6 file \u4e2d\uff0c\u5982\u679c\u8be5\u6587\u4ef6\u4e2d\u5df2\u5305\u542b\u6570\u636e\uff0c\u65b0\u6570\u636e\u5c06\u8ffd\u52a0\u5199\u5165\u5230\u539f\u6709\u5185\u5bb9\u7684\u540e\u9762\u3002 \u6ce8\u610f\uff1a\u4e0a\u9762\u7684 file \u53ef\u4ee5\u662f\u4e00\u4e2a\u666e\u901a\u6587\u4ef6\uff0c\u4e5f\u53ef\u4ee5\u4f7f\u7528\u4e00\u4e2a\u7279\u6b8a\u7684\u6587\u4ef6 /dev/null \u3002 /dev/null \u5e76\u4e0d\u4fdd\u5b58\u6570\u636e\uff0c\u88ab\u5199\u5165 /dev/null \u7684\u6570\u636e\u6700\u7ec8\u90fd\u4f1a\u4e22\u5931\u3002 \u4e3e\u4f8b\uff1a2\u4e2apython\u6587\u4ef6\u5b58\u5728\uff0c\u5176\u4ed62\u4e2a\u65e0\u6269\u5c55\u540d\u7684\u6587\u4ef6\u4e0d\u5b58\u5728\u3002 ls file.py > out ls file 2 > out.err ls new.py >> out ls new 2 >> out.err \u53ef\u4ee5\u5f97\u5230\u9884\u671f\u7684\u7ed3\u679c\u3002\u4e24\u4e2a\u9519\u8bef\u8bb0\u5f55\u90fd\u88ab\u8ffd\u52a0\u5230 out.err \u6587\u4ef6\u4e2d\u3002\u4e24\u4e2a\u6210\u529f\u6267\u884c\u7684\u547d\u4ee4\u7684\u8fd4\u56de\u7ed3\u679c\u4e5f\u8f93\u51fa\u5230 out \u6587\u4ef6\u4e2d\u3002 $ccat out file.py new.py $ cat out.err ls: cannot access 'file' : No such file or directory ls: cannot access 'new' : No such file or directory \u4e0a\u4f8b\u547d\u4ee4\u4e5f\u53ef\u4ee5\u5408\u5e76\u3002 ls file.py > out 2 > out.err ls file >> out 2 >> out.err 2>&1 \u683c\u5f0f\u4e3e\u4f8b\uff1a $ ls file >> out.txt 2 > & 1 $ cat out.txt ls: cannot access 'file' : No such file or directory $ ls file.py & >> out.txt $ cat out.txt ls: cannot access 'file' : No such file or directory file.py","title":"6.2.\u8f93\u51fa\u91cd\u5b9a\u5411"},{"location":"linux/SRE/02-filesystem/#63","text":"\u683c\u5f0f\uff1a command1 < <(command2) tr 'a-z' 'A-Z' < < ( echo \"Hello World\" ) \u5e94\u7528\uff1a\u4fee\u6539\u5bc6\u7801 \u5bc6\u7801\u4fdd\u5b58\u5728 passwd.txt \u6587\u4ef6\u4e2d\uff0c\u5e76\u4e25\u683c\u9650\u5236\u6539\u6587\u4ef6\u7684\u6743\u9650\u3002 \u901a\u8fc7\u53c2\u6570 --stdin \u5b9e\u73b0\u6a21\u62df\u952e\u76d8\u8f93\u5165\u64cd\u4f5c\u8f93\u5165\u7528\u6237\u540d\u3002 \u5728Rocky\u4e2d\u53ef\u4ee5\u4f7f\u7528 --stdin \u53c2\u6570\u3002 passwd --stdin vagrant < passwd.txt \u5728openSUSE\u548cUbuntu\u4e2d\uff0c --stdin \u53c2\u6570\u65e0\u6cd5\u8bc6\u522b\u3002\u53ef\u4ee5\u6539\u7528\u4e0b\u9762\u7684\u65b9\u6cd5\u3002 echo passwd.txt | chpasswd \u5176\u4e2dpasswd.txt\u7684\u683c\u5f0f\u4e3a username:password \u3002 \u53c2\u8003\uff1a Here-document(Here-doc)\uff1a\u8f93\u5165\u7684\u6587\u672c\u5757\u91cd\u5b9a\u5411\u81f3\u6807\u51c6\u8f93\u5165\u6d41\uff0c\u76f4\u81f3\u9047\u5230\u7279\u6b8a\u7684\u6587\u4ef6\u7ed3\u675f\u6807\u8bb0\u7b26\u4e3a\u6b62\uff08\u6587\u4ef6\u7ed3\u675f\u6807\u8bb0\u7b26\u53ef\u4ee5\u662f\u4efb\u610f\u7684\u552f\u4e00\u7684\u5b57\u7b26\u4e32\uff0c\u4f46\u5927\u90e8\u5206\u4eba\u90fd\u9ed8\u8ba4\u4f7f\u7528 EOF \uff09\u3002 cat < \u5c06\u547d\u4ee4\u4e0e\u6587\u4ef6\u8fde\u63a5\u8d77\u6765\uff0c\u7528\u6587\u4ef6\u6765\u63a5\u6536\u547d\u4ee4\u7684\u8f93\u51fa\uff1b\u800c\u7ba1\u9053\u7b26 | \u5c06\u547d\u4ee4\u4e0e\u547d\u4ee4\u8fde\u63a5\u8d77\u6765\uff0c\u7528\u53f3\u8fb9\u547d\u4ee4\u6765\u63a5\u6536\u5de6\u8fb9\u547d\u4ee4\u7684\u8f93\u51fa\u3002 $ ls | tr 'a-z' 'A-Z' BIN F1.TXT F2.TXT FILE.PY NEW.PY OUT OUT.ERR TEST.TXT","title":"7.\u7ba1\u9053"},{"location":"linux/SRE/03-identity-security/","text":"\u7b2c\u4e09\u7ae0 \u8eab\u4efd\u4e0e\u5b89\u5168 \u00b6 1.\u7528\u6237\u3001\u7ec4\u3001\u6743\u9650 \u00b6 \u7528\u6237\u548c\u7ec4 \u7528\u6237user\u548c\u7ec4group\u5728Linux\u7cfb\u7edf\u4e2d\u4ee5\u6570\u5b57\u5f62\u5f0f\u8fdb\u884c\u7ba1\u7406\u3002 \u7528\u6237\u88ab\u5206\u914d\u7684\u53f7\u7801\u79f0\u4e3a\u7528\u6237ID\uff08UID\uff09\u3002 \u6bcf\u4e2aLinux\u7cfb\u7edf\u90fd\u6709\u4e00\u4e2a\u7279\u6743\u7528\u6237\uff0c\u5373 root \u7528\u6237\u3002 root \u662f\u7cfb\u7edf\u7ba1\u7406\u5458\u3002 \u6b64\u7528\u6237\u7684UID\u59cb\u7ec8\u4e3a0\u3002 \u666e\u901a\u7528\u6237\u7684UID\u7f16\u53f7\uff08\u9ed8\u8ba4\u60c5\u51b5\u4e0b\uff09\u4e3a1000\u3002 \u6bcf\u4e2a\u7ec4\u4e5f\u5206\u914d\u4e86\u4e00\u4e2a\u79f0\u4e3a\u7ec4ID\uff08GID\uff09\u7684\u7f16\u53f7\u3002 \u6bcf\u4e2a\u7528\u6237\u6709\u4e00\u4e2a\u4e3b\u8981\u7ec4\uff08primary group\uff09\uff0c\u6709\u96f6\u4e2a\u6216\u8005\u4efb\u610f\u4e2a\u9644\u52a0\u7ec4\uff08supplementary group\uff09\u3002 \u4ee5openSUSE\u4e3a\u4f8b\uff1a UID 0: root 1 \u2013 99: System 100 \u2013 499: System accounts \u2265 1000: Normal (unprivileged) accounts GID 0: root 1 \u2013 99: System Groups 100 \u2013 499: Dynamically Allocated System Groups \u2265 1000: Normal Groups \u4e3e\u4f8b\uff1a $ id postfix uid = 51 ( postfix ) gid = 51 ( postfix ) groups = 482 ( mail ) ,59 ( maildrop ) ,51 ( postfix ) $ id vagrant uid = 1000 ( vagrant ) gid = 478 ( wheel ) groups = 0 ( root ) ,478 ( wheel ) \u63d0\u793a\uff1a UID\u548cGID\u7b49\u7f16\u53f7\u89c4\u5219\uff0c\u662f\u5728\u6587\u4ef6 /etc/login.defs \u4e2d\u7ea6\u5b9a\u7684\u3002 2.SELinux \u00b6 Security-Enhanced Linux (SELinux) \u662f\u4e00\u79cdLinux\u7cfb\u7edf\u7684\u5b89\u5168\u67b6\u6784\uff0c\u5b83\u5141\u8bb8\u7ba1\u7406\u5458\u66f4\u597d\u5730\u63a7\u5236\u8c01\u53ef\u4ee5\u8bbf\u95ee\u7cfb\u7edf\u3002 SELinux\u4e8e2000\u5e74\u5411\u5f00\u6e90\u793e\u533a\u53d1\u5e03\uff0c\u5e76\u4e8e2003\u5e74\u96c6\u6210\u5230\u4e0a\u6e38 Linux \u5185\u6838\u4e2d\u3002 SELinux\u4e3a\u7cfb\u7edf\u4e0a\u7684\u5e94\u7528\u7a0b\u5e8f\u3001\u8fdb\u7a0b\u548c\u6587\u4ef6\u5b9a\u4e49\u4e86\u8bbf\u95ee\u63a7\u5236\u3002 \u5b83\u4f7f\u7528\u5b89\u5168\u7b56\u7565\uff08\u4e00\u7ec4\u89c4\u5219\u544a\u8bc9SELinux\u4ec0\u4e48\u53ef\u4ee5\u8bbf\u95ee\u6216\u4e0d\u53ef\u4ee5\u8bbf\u95ee\uff09\u6765\u5f3a\u5236\u6267\u884c\u7b56\u7565\u5141\u8bb8\u7684\u8bbf\u95ee\u3002 \u5f53\u79f0\u4e3a\u4e3b\u4f53\uff08subject\uff09\u7684\u5e94\u7528\u7a0b\u5e8f\u6216\u8fdb\u7a0b\u8bf7\u6c42\u8bbf\u95ee\u5bf9\u8c61\uff08\u5982\u6587\u4ef6\uff09\u65f6\uff0cSELinux\u4f1a\u68c0\u67e5\u8bbf\u95ee\u5411\u91cf\u7f13\u5b58(AVC, Access Vector Cache)\uff0c\u5176\u4e2d\u7f13\u5b58\u4e86\u4e3b\u4f53\u548c\u5bf9\u8c61\u7684\u6743\u9650\u3002 \u5982\u679cSELinux\u65e0\u6cd5\u6839\u636e\u7f13\u5b58\u7684\u6743\u9650\u505a\u51fa\u8bbf\u95ee\u51b3\u5b9a\uff0c\u5b83\u4f1a\u5c06\u8bf7\u6c42\u53d1\u9001\u5230\u5b89\u5168\u670d\u52a1\u5668\u3002 \u5b89\u5168\u670d\u52a1\u5668\u68c0\u67e5\u5e94\u7528\u7a0b\u5e8f\u6216\u8fdb\u7a0b\u548c\u6587\u4ef6\u7684\u5b89\u5168\u4e0a\u4e0b\u6587\u3002 \u4eceSELinux\u7b56\u7565\u6570\u636e\u5e93\u5e94\u7528\u5b89\u5168\u4e0a\u4e0b\u6587\uff08Security context\uff09\uff0c\u7136\u540e\u6388\u4e88\u6216\u62d2\u7edd\u8bb8\u53ef\u3002 \u5982\u679c\u6743\u9650\u88ab\u62d2\u7edd\uff0c avc: denied \u6d88\u606f\u5c06\u5728 /var/log.messages \u4e2d\u4f53\u73b0\u3002 \u4f20\u7edf\u4e0a\uff0cLinux\u548cUNIX\u7cfb\u7edf\u90fd\u4f7f\u7528DAC\uff08Discretionary Access Control\uff09\u3002 SELinux\u662fLinux\u7684MAC\uff08Mandatory Access Control\uff09\u7cfb\u7edf\u7684\u4e00\u4e2a\u793a\u4f8b\u3002 \u5728DAC\u65b9\u5f0f\u4e0b\uff0c\u6587\u4ef6\u548c\u8fdb\u7a0b\u6709\u81ea\u5df1\u7684\u5c5e\u4e3b\uff08\u6240\u6709\u8005\uff09\u3002 \u7528\u6237\u53ef\u4ee5\u62e5\u6709\u4e00\u4e2a\u6587\u4ef6\uff0c\u4e00\u4e2a\u7ec4\u4e5f\u53ef\u4ee5\u62e5\u6709\u4e00\u4e2a\u6587\u4ef6\uff0c\u6216\u8005\u5176\u4ed6\u4eba\u3002 \u7528\u6237\u53ef\u4ee5\u66f4\u6539\u81ea\u5df1\u6587\u4ef6\u7684\u6743\u9650\u3002 root \u7528\u6237\u5bf9DAC\u7cfb\u7edf\u5177\u6709\u5b8c\u5168\u8bbf\u95ee\u63a7\u5236\u6743\u3002 \u4f46\u662f\u5728\u50cfSELinux\u8fd9\u6837\u7684MAC\u7cfb\u7edf\u4e0a\uff0c\u5bf9\u4e8e\u8bbf\u95ee\u7684\u7ba1\u7406\u662f\u901a\u8fc7\u8bbe\u7f6e\u7b56\u7565\u6765\u5b9e\u73b0\u7684\u3002\u5373\u4f7f\u7528\u6237\u4e3b\u76ee\u5f55\u4e0a\u7684DAC\u8bbe\u7f6e\u53d1\u751f\u66f4\u6539\uff0c\u7528\u4e8e\u9632\u6b62\u5176\u4ed6\u7528\u6237\u6216\u8fdb\u7a0b\u8bbf\u95ee\u8be5\u76ee\u5f55\u7684SELinux\u7b56\u7565\u4e5f\u5c06\u7ee7\u7eed\u786e\u4fdd\u7cfb\u7edf\u5b89\u5168\u3002 MAC\u65b9\u5f0f\u662f\u63a7\u5236\u4e00\u4e2a\u8fdb\u7a0b\u5bf9\u5177\u4f53\u6587\u4ef6\u7cfb\u7edf\u4e0a\u9762\u7684\u6587\u4ef6\u6216\u76ee\u5f55\u662f\u5426\u62e5\u6709\u8bbf\u95ee\u6743\u9650\u3002\u5224\u65ad\u8fdb\u7a0b\u662f\u5426\u53ef\u4ee5\u8bbf\u95ee\u6587\u4ef6\u6216\u76ee\u5f55\u7684\u4f9d\u636e\uff0c\u53d6\u51b3\u4e8eSELinux\u4e2d\u8bbe\u5b9a\u7684\u5f88\u591a\u7b56\u7565\u89c4\u5219\u3002 \u8bbf\u95ee\u63a7\u5236\u5217\u8868 (ACL\uff0cAccess Control List) \u4e3a\u6587\u4ef6\u7cfb\u7edf\u63d0\u4f9b\u4e86\u4e00\u79cd\u989d\u5916\u7684\u3001\u66f4\u7075\u6d3b\u7684\u6743\u9650\u673a\u5236\u3002 \u5b83\u65e8\u5728\u534f\u52a9 UNIX \u6587\u4ef6\u6743\u9650\u3002ACL\u5141\u8bb8\u6388\u4e88\u4efb\u4f55\u7528\u6237\u6216\u7ec4\u5bf9\u4efb\u4f55\u78c1\u76d8\u8d44\u6e90\u7684\u6743\u9650\u3002ACL\u9002\u7528\u4e8e\u5728\u4e0d\u4f7f\u67d0\u4e2a\u7528\u6237\u6210\u4e3a\u7ec4\u6210\u5458\u7684\u60c5\u51b5\u4e0b\uff0c\u4ecd\u65e7\u6388\u4e88\u4e00\u4e9b\u8bfb\u6216\u5199\u8bbf\u95ee\u6743\u9650\u3002 \u4e0b\u9762\u793a\u4f8b\u5bf9\u6bd4\u8bf4\u660e\u4e86SELinux\u548cACL\u5728\u6587\u4ef6\u5c5e\u6027\u5c55\u73b0\u4e0a\u7684\u7279\u70b9\u3002 -rwxr-xr-- vagrant wheel \uff1a\u6ca1\u6709selinux\u4e0a\u4e0b\u6587\uff0c\u6ca1\u6709ACL -rwx--xr-x+ vagrant wheel \uff1a\u53ea\u6709ACL\uff0c\u6ca1\u6709selinux\u4e0a\u4e0b\u6587 -rw-r--r--. vagrant wheel \uff1a\u53ea\u6709selinux\u4e0a\u4e0b\u6587\uff0c\u6ca1\u6709ACL -rwxrwxr--+ vagrant wheel \uff1a\u6709selinux\u4e0a\u4e0b\u6587\uff0c\u6709ACL 2.1.SELinux\u4e3b\u8981\u6982\u5ff5 \u00b6 \u7528\u6237(Users)\uff1a SELinux\u7684\u7528\u6237\u4e0d\u7b49\u540c\u4e0eLinux\u7528\u6237\u3002 SELinux\u7528\u6237\u4ee5\u540e\u7f00 _u \u7ed3\u5c3e\u3002 \u89d2\u8272(Roles)\uff1a \u89d2\u8272Roles\u662f\u7531\u7b56\u7565Policies\u5b9a\u4e49\u7684\uff0c\u89d2\u8272\u51b3\u5b9a\u4e86\u4f7f\u7528\u54ea\u4e2a\u7b56\u7565\u3002 SELinux\u89d2\u8272\u4ee5\u540e\u7f00 _r \u7ed3\u5c3e\u3002 \u7c7b\u578b(Types)\uff1a SELinux\u662f\u7c7b\u578b\u5f3a\u5236\u7684\uff0c\u7c7b\u578bTypes\u51b3\u5b9a\u8fdb\u7a0b\u80fd\u5426\u8bbf\u95ee\u67d0\u4e2a\u6587\u4ef6\u3002 SELinux\u7c7b\u578b\u662f\u4ee5\u540e\u7f00 _t \u7ed3\u5c3e\u3002 \u4e0a\u4e0b\u6587(Contexts)\uff1a \u7528\u6765\u6807\u8bb0\u8fdb\u7a0b\u548c\u6587\u4ef6\u3002\u5206\u522b\u662f\u7528\u6237Users\uff0c\u89d2\u8272Roles\uff0c\u7c7b\u578bTypes\uff0c\u8303\u56f4Ranges\u3002 \u683c\u5f0f\uff1a user:role:type:range \u6587\u4ef6\u7c7b\u578b(Object Classes)\uff1a \u6bcf\u4e2a\u6587\u4ef6\u7c7b\u578bTypes\u90fd\u5bf9\u5e94\u4e00\u5957\u7b56\u7565Policies\u3002\u7b56\u7565Policies\u51b3\u5b9a\u4e86\u8fdb\u7a0b\u5bf9\u8fd9\u7c7b\u6587\u4ef6\u7684\u8bbf\u95ee\u6743\u9650\u3002 \u8bbf\u95ee\u6743\u9650\u67094\u79cd\uff1a \u521b\u5efacreate \u8bfb\u53d6read \u5199\u5165write \u5220\u9664unlink\uff08\u6ce8\u610f\uff0c\u8fd9\u91cc\u4e0d\u662f\u94fe\u63a5\u7684\u610f\u601d\uff09 \u89c4\u5219(Rules) \u683c\u5f0f\uff1a allow user_t user_home_t:file {create read write unlink}; \u542b\u4e49\uff1a user_t \u7c7b\u578b\u5bf9 user_home_t \u7c7b\u578b\u6709\u521b\u5efacreate\uff0c\u8bfb\u53d6read\uff0c\u5199\u5165write\uff0c\u5220\u9664unlink\u6743\u9650\u3002 2.2.SELinux in openSUSE \u00b6 \u4f5c\u4e3aSELinux\u7684\u66ff\u4ee3\u54c1\uff0c2005\u5e74\u88abNovell\u6536\u8d2d\u7684Immunix\u516c\u53f8\u5f00\u53d1\u4e86AppArmor\u3002SUSE\u5728openSUSE Leap\u4e2d\u63d0\u4f9b\u5bf9SELinux\u6846\u67b6\u7684\u652f\u6301\u3002\u8fd9\u5e76\u4e0d\u610f\u5473\u7740openSUSE Leap\u7684\u9ed8\u8ba4\u5b89\u88c5\u4f1a\u5728\u4e0d\u4e45\u7684\u5c06\u6765\u4eceAppArmor\u5207\u6362\u5230SELinux\u3002 \u6dfb\u52a0SELinux\u7684\u6e90\u3002\u53ef\u4ee5\u4ece https://download.opensuse.org/repositories/security:/SELinux/ \u4e0b\u8f7d\u5bf9\u5e94\u7684\u7b56\u7565policy\u3002 sudo zypper ar -f https://download.opensuse.org/repositories/security:/SELinux/openSUSE_Factory/ Security-SELinux \u5b89\u88c5C++\u7b49\u57fa\u7840\u5f00\u53d1\u5305\uff1a # \u5217\u51fa\u5f53\u524d\u53ef\u5b89\u88c5\u7684Pattern sudo zypper pt # \u5b89\u88c5\u4e0b\u9762\u51e0\u4e2a\u5f00\u53d1\u76f8\u5173\u7684Pattern sudo zypper in -t pattern devel_C_C++ devel_basis devel_kernel \u5b89\u88c5SELinux packages\uff1a zypper se --search-descriptions selinux sudo zypper in restorecond policycoreutils setools-console sudo zypper in selinux-tools libselinux-devel \u5b89\u88c5SELinux policy\uff1a sudo zypper in selinux-policy-targeted selinux-policy-devel selinux-autorelabel \u66f4\u65b0GRUB2 bootloader\uff08GRUB2\u5f15\u5bfc\u52a0\u8f7d\u7a0b\u5e8f\uff09\uff1a \u7f16\u8f91\u6587\u4ef6 /etc/default/grub \uff0c\u6dfb\u52a0\u4e0b\u9762\u5185\u5bb9\u5230 GRUB_CMDLINE_LINUX_DEFAULT= \u8fd9\u4e00\u884c\uff1a security = selinux selinux = 1 \u8bb0\u5f55\u8fd9\u4e00\u884c\u7684\u539f\u59cb\u4fe1\u606f\uff1a GRUB_CMDLINE_LINUX_DEFAULT = \"splash=silent resume=/dev/disk/by-uuid/47c36ad7-f49f-4ecd-9b72-4801c5bb3a04 preempt=full mitigations=auto quiet security=apparmor\" \u8fd0\u884c\u4e0b\u9762\u7684\u547d\u4ee4\u751f\u6210\u65b0\u7684GRUB2\u5f15\u5bfc\u52a0\u8f7d\u7a0b\u5e8f\u914d\u7f6e\u6587\u4ef6\u3002 sudo grub2-mkconfig -o /boot/grub2/grub.cfg \u7f16\u8f91\u6587\u4ef6 /etc/selinux/config \u5e76\u8bbe\u7f6e SELINUX=permissive \u6765\u542f\u7528SElinux\u3002\u8fd9\u4e0e\u524d\u9762GRUB2\u7684\u542f\u52a8\u914d\u7f6e\u662f\u4e00\u81f4\u7684\u3002 \u5982\u6587\u4ef6\u4e0d\u5b58\u5728\uff0c\u5219\u521b\u5efa\u3002 $ sudo cat /etc/selinux/config SELINUX = permissive SELINUXTYPE = targeted \u91cd\u542f\u7cfb\u7edf\u3002\u7cfb\u7edf\u542f\u52a8\u53ef\u80fd\u9700\u8981\u4e00\u4e9b\u65f6\u95f4\uff0cSELinux\u9700\u8981\u7ed9\u6574\u4e2a\u6587\u4ef6\u7cfb\u7edf\u91cd\u65b0\u8fdb\u884c\u6807\u7b7e\u5316\u3002 \u91cd\u542f\u540e\uff0c\u8fd0\u884c\u4e0b\u9762\u7684\u547d\u4ee4\u6765\u67e5\u770bSELinux\u662f\u5426\u8fd0\u884c\u6b63\u5e38\u3002 $ sudo getenforce Permissive $ sudo sestatus -v SELinux status: enabled SELinuxfs mount: /sys/fs/selinux SELinux root directory: /etc/selinux Loaded policy name: targeted Current mode: permissive Mode from config file: permissive Policy MLS status: enabled Policy deny_unknown status: allowed Memory protection checking: requested ( insecure ) Max kernel policy version: 33 Process contexts: Current context: unconfined_u:unconfined_r:unconfined_t:s0 Init context: system_u:system_r:kernel_t:s0 /sbin/agetty system_u:system_r:kernel_t:s0 /usr/sbin/sshd system_u:system_r:kernel_t:s0 File contexts: Controlling terminal: unconfined_u:object_r:devpts_t:s0 /etc/passwd system_u:object_r:unlabeled_t:s0 /etc/shadow system_u:object_r:unlabeled_t:s0 /bin/bash system_u:object_r:unlabeled_t:s0 -> system_u:object_r:unlabeled_t:s0 /bin/login system_u:object_r:unlabeled_t:s0 /bin/sh system_u:object_r:unlabeled_t:s0 -> system_u:object_r:unlabeled_t:s0 /sbin/agetty system_u:object_r:unlabeled_t:s0 -> system_u:object_r:unlabeled_t:s0 /sbin/init system_u:object_r:unlabeled_t:s0 -> system_u:object_r:unlabeled_t:s0 /usr/sbin/sshd system_u:object_r:unlabeled_t:s0 \u53c2\u8003\uff1a GRUB2\u5f15\u5bfc\u52a0\u8f7d\u7a0b\u5e8f\u4e2d\u6dfb\u52a0\u7684\u4e09\u4e2a\u53c2\u6570\u7684\u89e3\u91ca\uff1a security=selinux : This option tells the kernel to use SELinux and not AppArmor. selinux=1 : This option switches on SELinux. enforcing=0 : This option puts SELinux in permissive mode. In this mode, SELinux is fully functional, but does not enforce any of the security settings in the policy. Use this mode for testing and configuring your system. To switch on SELinux protection, when the system is fully operational, change the option to enforcing=1 and add SELINUX=enforcing in /etc/selinux/config . \u5c0f\u8d34\u58eb\uff1a \u5728\u9996\u6b21\u542f\u7528SELinux\u540e\uff0c\u5982\u679c\u53ea\u5728grub2\u91cc\u9762\u6dfb\u52a0selinux=1\uff0c\u901a\u8fc7 getenforce \u547d\u4ee4\u770b\u7684SELinux\u4e00\u76f4\u5c31\u662fdisabled\u7684\u72b6\u6001\uff0c\u9700\u8981\u624b\u5de5\u521b\u5efa/etc/selinux/config\u6587\u4ef6\u6dfb\u52a0\u914d\u7f6e\u624d\u884c\u3002\u611f\u89c9grub2\u91cc\u9762\u65e0\u9700\u8bbe\u7f6e\uff0c\u76f4\u63a5\u914d\u7f6e/etc/selinux/config\u6587\u4ef6\u3002\u4e0d\u786e\u5b9a\u8fd9\u4e2a\u60f3\u6cd5\u662f\u5426\u6b63\u786e\u3002 \u5728grub2\u4e2d\u8bbe\u5b9aselinux=1\uff0c\u5728/etc/selinux/config\u6587\u4ef6\u4e2d\uff1a \u8bbe\u5b9aSELINUX=permissive\uff0c\u91cd\u542f\u540e\u901a\u8fc7 getenforce \u547d\u4ee4\u770b\u5230\u7684\u662fpermissive\u3002 \u8bbe\u5b9aSELINUX=disabled\uff0c\u5219\u91cd\u542f\u540e getenforce \u547d\u4ee4\u770b\u5230\u7684\u662fdisabled\u3002 \u8fd9\u8bf4\u660e\u914d\u7f6e\u6587\u4ef6\u540e\u542f\u52a8\uff0c\u8986\u76d6\u4e86\u5185\u6838\u8bbe\u7f6e\u3002 \u6ce8\u610f\uff0c\u5982\u679c\u4ec5\u4ec5\u5b8c\u6210\u4e86\u4e0a\u9762\u7684enable SELinux\uff0c\u7acb\u523b\u8bbe\u5b9aSELINUX=enforcing\uff0c\u4f1a\u5f15\u8d77ssh\u65e0\u6cd5\u767b\u5f55\uff0c\u9519\u8bef\u4fe1\u606f\u662f /bin/bash: Permission denied \u3002 \u914d\u7f6eSELinux\u3002 $ sudo semanage boolean -l Failed to use semanage \u6dfb\u52a0\u4e0b\u9762\u5185\u5bb9\u5230.bashrc\u6587\u4ef6\u3002 export PATH = /usr/local/bin:/home/ $USER /.local/bin: $PATH \u66f4\u65b0pip3. pip3 install --upgrade pip \u5b89\u88c5\u4e0b\u9762\u51e0\u4e2a\u5305 sudo zypper in libselinux libselinux-devel sudo zypper in python3-semanage sudo zypper in libsemanage-devel libsemanage-devel-static sudo zypper in policycoreutils-python-utils sudo zypper in cross-x86_64-linux-glibc-devel glibc-utils glibc-profile sudo zypper in policycoreutils-devel 2.3.SELinux in Ubuntu \u00b6 2.4.SELinux in Rocky \u00b6 3.\u7528\u6237\u548c\u7ec4\u7684\u914d\u7f6e\u6587\u4ef6 \u00b6 /etc/passwd \uff1a\u7528\u6237\u53ca\u5176\u5c5e\u6027\u4fe1\u606f\uff08\u7528\u6237\u540d\uff0cUID\uff0c\u4e3b\u7ec4ID\u7b49\uff09 /etc/shadow \uff1a\u7528\u6237\u5bc6\u7801\u673a\u5668\u5c5e\u6027 /etc/group \uff1a\u7ec4\u53ca\u5176\u5c5e\u6027 /etc/gshadow \uff1a\u7ec4\u5bc6\u7801\u53ca\u5176\u5c5e\u6027 3.1./etc/passwd \u00b6 \u683c\u5f0f\u8bf4\u660e\uff1a vagrant:x:1001:474:vagrant:/home/vagrant:/bin/bash [ ----- ] - [ -- ] [ - ] [ ----- ] [ ----------- ] [ ------- ] | | | | | | +--------> 7 . Login shell | | | | | +--------------------> 6 . Home directory | | | | +-------------------------------> 5 . GECOS or the full name of the user | | | +-------------------------------------> 4 . GID | | +------------------------------------------> 3 . UID | +---------------------------------------------> 2 . Password +--------------------------------------------------> 1 . Username 3.2./etc/shadow \u00b6 \u683c\u5f0f\u8bf4\u660e\uff1a vagrant: $6 $.n.:17736:0:99999:7::: [ ----- ] [ ---- ] [ --- ] - [ --- ] ---- | | | | | || | +-----------> 9 . Unused | | | | | || +------------> 8 . Expiration date since Jan 1 , 1970 | | | | | | +-------------> 7 . Inactivity period \u5bc6\u7801\u8fc7\u671f\u540e\u7684\u5bbd\u9650\u671f | | | | | +--------------> 6 . Warning period, default 7 days | | | | +------------------> 5 . Maximum password age | | | +----------------------> 4 . Minimum password age | | +--------------------------> 3 . Last password change since Jan 1 , 1970 | +---------------------------------> 2 . Encrypted Password +-------------------------------------------> 1 . Username 3.3./etc/group \u00b6 \u683c\u5f0f\u8bf4\u660e\uff1a audio:x:492:pulse [ --- ] - [ - ] [ --- ] | | | +----> 4 . username-list, who have this group as their supplementary | | +---------> 3 . GID | +------------> 2 . group-password. Real password is in /etc/gshadow +----------------> 1 . groupname 3.4./etc/gshadow \u00b6 \u683c\u5f0f\u8bf4\u660e\uff1a general:!!:shelley:juan,bob [ ----- ] -- [ ----- ] [ ------ ] | | | +-------> 4 . group members ( in a comma delimited list ) | | +---------------> 3 . group adminstrators ( in a comma delimited list ) | +---------------------> 2 . encrypted password. ` ! ` , ` !! ` , and null +---------------------------> 1 . group name Encrypted password ! \uff1ano user is allowed to access the group using the newgrp command. !! \uff1athe same as a value of ! \u2014 however, it also indicates that a password has never been set before. null\uff1aonly group members can log into the group. 3.5.\u751f\u6210\u968f\u673a\u5bc6\u7801 \u00b6 # \u901a\u8fc7`/dev/urandom`\u751f\u6210\u968f\u673a\u6570\uff0c\u901a\u8fc7`tr -dc`\u8fc7\u6ee4\u968f\u673a\u6570\uff0c\u53ea\u4fdd\u7559\u5b57\u6bcd\u548c\u6570\u5b57\uff0c\u901a\u8fc7`head -c`\u4fdd\u7559\u6307\u5b9a\u4f4d\u6570 $ tr -dc '[:alnum:]' < /dev/urandom | head -c 12 xFw7vfma54D8 $ openssl rand -base64 9 I5TZXJfpd3Pg 3.6.vipw/vigr/pwck/grpck\u547d\u4ee4 \u00b6 vipw \u548c vigr \u547d\u4ee4\u5206\u522b\u7f16\u8f91\u6587\u4ef6 /etc/passwd \u548c /etc/group \u3002 \u5982\u679c\u6307\u5b9a\u4e86 -s \u6807\u5fd7\uff0c\u8fd9\u4e9b\u547d\u4ee4\u5c06\u5206\u522b\u7f16\u8f91\u5176\u6587\u4ef6\u7684\u5f71\u5b50\uff08\u5b89\u5168\uff09\u7248\u672c\uff1a /etc/shadow \u548c /etc/gshadow \u3002 vipw \u548c vigr \u547d\u4ee4\u5728\u7f16\u8f91\u6587\u4ef6\u65f6\u4f1a\u8bbe\u7f6e\u9501\u4ee5\u9632\u6b62\u6587\u4ef6\u635f\u574f\u3002 vipw \u548c vigr \u547d\u4ee4\u4f1a\u9996\u5148\u5c1d\u8bd5\u73af\u5883\u53d8\u91cf $VISUAL \uff0c\u7136\u540e\u662f\u73af\u5883\u53d8\u91cf $EDITOR \uff0c\u6700\u540e\u662f\u9ed8\u8ba4\u7f16\u8f91\u5668 vi \u3002 sudo vipw sudo vipw -s sudo vigr sudo vigr -s pwck \u547d\u4ee4\u5b9e\u73b0\u9a8c\u8bc1\u7cfb\u7edf\u8ba4\u8bc1\u4fe1\u606f\u7684\u5b8c\u6574\u6027\u3002 \u68c0\u67e5 /etc/passwd \u548c /etc/shadow \u4e2d\u7684\u6240\u6709\u6761\u76ee\u6bcf\u4e2a\u5b57\u6bb5\u662f\u5426\u5177\u6709\u6b63\u786e\u7684\u683c\u5f0f\u548c\u6709\u6548\u6570\u636e\u3002 \u7cfb\u7edf\u4f1a\u63d0\u793a\u7528\u6237\u5220\u9664\u683c\u5f0f\u4e0d\u6b63\u786e\u6216\u5b58\u5728\u5176\u4ed6\u9519\u8bef\u7684\u6761\u76ee\u3002 pwck \u8fd4\u56de\u503c\uff1a 0 : success 1 : invalid command syntax 2 : one or more bad password entries 3 : can\u2019t open password files 4 : can\u2019t lock password files 5 : can\u2019t update password files grpck \u547d\u4ee4\u5b9e\u73b0\u9a8c\u8bc1\u7cfb\u7edf\u8ba4\u8bc1\u4fe1\u606f\u7684\u5b8c\u6574\u6027\u3002 \u68c0\u67e5 /etc/group \u548c /etc/gshadow \u4e2d\u7684\u6240\u6709\u6761\u76ee\u6bcf\u4e2a\u5b57\u6bb5\u662f\u5426\u5177\u6709\u6b63\u786e\u7684\u683c\u5f0f\u548c\u6709\u6548\u6570\u636e\u3002 \u7cfb\u7edf\u4f1a\u63d0\u793a\u7528\u6237\u5220\u9664\u683c\u5f0f\u4e0d\u6b63\u786e\u6216\u5b58\u5728\u5176\u4ed6\u9519\u8bef\u7684\u6761\u76ee\u3002 grpck \u8fd4\u56de\u503c\uff1a 0 : success 1 : invalid command syntax 2 : one or more bad group entries 3 : can\u2019t open group files 4 : can\u2019t lock group files 5 : can\u2019t update group files 4.\u7528\u6237\u7ba1\u7406 \u00b6 \u7528\u6237\u7ba1\u7406\u547d\u4ee4\uff1a useradd usermod userdel 4.1.\u521b\u5efa\u7528\u6237 useradd \u00b6 \u4e3e\u4f8b\uff1a # \u666e\u901a\u7528\u6237 $ useradd -m -g wheel -G root -c \"vagrant\" vagrant # \u975e\u4ea4\u4e92\u7528\u6237 $ useradd -r -u 48 -g apache -d /var/www -s /sbin/nologin -g postfix -c \"Apache\" apache 2 >/dev/null useradd \u547d\u4ee4\u7684\u9ed8\u8ba4\u503c\u662f\u5728 /etc/default/useradd \u6587\u4ef6\u4e2d\u8bbe\u5b9a\u3002 openSUSE\u7684 /etc/default/useradd \u6587\u4ef6\u5185\u5bb9\uff1a GROUP = 100 HOME = /home INACTIVE = -1 # \u5bf9\u5e94/etc/shadow\u6587\u4ef6\u7b2c7\u5217\uff0cInactivity period\uff0c\u5bc6\u7801\u8fc7\u671f\u540e\u7684\u5bbd\u9650\u671f\uff0c-1\u8868\u793a\u4e0d\u9650\u5236 EXPIRE = # \u5bf9\u5e94/etc/shadow\u6587\u4ef6\u7b2c8\u5217\uff0cExpiration date since Jan 1, 1970\uff0c\u5373\u8d26\u53f7\u6709\u6548\u671f SHELL = /bin/bash SKEL = /etc/skel # \u7528\u4e8e\u751f\u6210\u7528\u6237\u4e3b\u76ee\u5f55\u7684\u6a21\u7248\u6587\u4ef6 USRSKEL = /usr/etc/skel CREATE_MAIL_SPOOL = yes Rocky\u7684 /etc/default/useradd \u6587\u4ef6\u5185\u5bb9\uff1a GROUP = 100 HOME = /home INACTIVE = -1 EXPIRE = SHELL = /bin/bash SKEL = /etc/skel CREATE_MAIL_SPOOL = yes \u5728Ubuntu\u4e2d /etc/default/useradd \u6587\u4ef6\u53ea\u6709\u4e0b\u9762\u8fd9\u4e00\u884c\u3002 SHELL = /bin/sh 4.1.1.\u6279\u91cf\u521b\u5efa\u7528\u6237 newusers \u00b6 \u683c\u5f0f\uff1a newusers \u3002\u5176\u4e2d\u6587\u4ef6 \u7684\u683c\u5f0f\u5982\u4e0b\uff1a :::::: \u4e3e\u4f8b\uff0c\u521b\u5efa\u6587\u4ef6 users.txt \uff1a $ cat ~/users.txt tester1:123:600:1530: \"Test User1,testuser1@abc.com\" :/home/tester1:/bin/bash tester2:123:601:1529:::/bin/bash tester3:123::::: tester4:123::::/home/tester4:/bin/tsh \u770b\u7ed3\u679c\uff1a $ cat /etc/passwd | grep tester tester1:x:600:1530: \"Test User1,testuser1@abc.com\" :/home/tester1:/bin/bash tester2:x:601:1529:::/bin/bash tester3:x:1001:1001::: tester4:x:1002:1002::/home/tester4:/bin/tsh $ cat /etc/group | grep tester tester1:*:1530: tester2:*:1529: tester3:*:1001: tester4:*:1002: $ sudo cat /etc/shadow | grep tester tester1:!:19321:0:99999:7::: tester2:!:19321:0:99999:7::: tester3:!:19321:0:99999:7::: tester4:!:19321:0:99999:7::: $ ls -ld /home/tester* drwxr-xr-x. 1 tester1 tester1 0 Nov 26 00 :32 /home/tester1 drwxr-xr-x. 1 tester4 tester4 0 Nov 26 00 :32 /home/tester4 4.1.2.\u6279\u91cf\u4fee\u6539\u5bc6\u7801 chpasswd \u00b6 \u4e0d\u540c\u65b9\u6cd5\uff1a echo username:password | chpasswd chpasswd < file.txt # file.txt\u6bcf\u884c\u7684\u683c\u5f0f\u662fusername:password paste -d \":\" user.txt passwd.txt | chpasswd \u53c2\u6570 -e \uff1a\u53e3\u4ee4\u4ee5\u52a0\u5bc6\u7684\u65b9\u5f0f\u4f20\u9012\u3002\u5426\u5219\u53e3\u4ee4\u4ee5\u660e\u6587\u7684\u5f62\u5f0f\u4f20\u9012\u3002 \u6ce8\u610f\uff1a \u7528\u6237\u540dusername\u5fc5\u987b\u662f\u5df2\u5b58\u5728\u7684\u7528\u6237 \u666e\u901a\u7528\u6237\u6ca1\u6709\u4f7f\u7528\u8fd9\u4e2a\u6307\u4ee4\u7684\u6743\u9650 \u5982\u679c\u8f93\u5165\u6587\u4ef6\u662f\u6309\u975e\u52a0\u5bc6\u65b9\u5f0f\u4f20\u9012\u7684\u8bdd\uff0c\u8bf7\u5bf9\u8be5\u6587\u4ef6\u8fdb\u884c\u9002\u5f53\u7684\u52a0\u5bc6\u3002 \u6307\u4ee4\u6587\u4ef6\u4e0d\u80fd\u6709\u7a7a\u884c \u4e3e\u4f8b\uff1a echo tester1:112233 | sudo chpasswd $ cat chpasswd.txt tester1:112233 tester2:33445566 $ sudo chpasswd < chpasswd.txt 4.1.3.\u751f\u6210\u52a0\u5bc6\u5bc6\u7801 openssl passwd \u00b6 \u547d\u4ee4 openssl passwd \u683c\u5f0f\u53ef\u4ee5\u5982\u4e0b\u65b9\u6cd5\u83b7\u5f97\u3002 $ man -f passwd passwd ( 1 ) - change user password passwd ( 1ssl ) - compute password hashes passwd ( 5 ) - password file $ man passwd Man: find all matching manual pages ( set MAN_POSIXLY_CORRECT to avoid this ) * passwd ( 1 ) passwd ( 5 ) passwd ( 1ssl ) Man: What manual page do you want? Man: 1ssl \u4e3e\u4f8b\uff08\u8fd9\u91cc\u7528 \u4ee3\u66ff\u5b9e\u9645\u5bc6\u7801\uff09\uff1a # \u57fa\u4e8e\u7ed9\u5b9a\u5b57\u4e32newpasswd\u751f\u6210sha256\u52a0\u5bc6\u7801\uff0c $ openssl passwd -6 newpasswd # \u521b\u5efa\u65b0\u7528\u6237tester5\uff0c\u8d4b\u4e88\u52a0\u5bc6\u5bc6\u7801 $ useradd -p '' tester1 # \u8bfb\u53d6\u7528\u6237tester5\u7684\u5bc6\u7801\uff0c\u53ef\u4ee5\u9a8c\u8bc1\u662f\u5426\u548c\u4e4b\u524d\u7684\u4e00\u81f4 $ sudo getent shadow tester5 tester5::19321:0:99999:7::: 4.2.\u4fee\u6539\u7528\u6237\u5c5e\u6027 usermod \u00b6 \u6dfb\u52a0\u7528\u6237\u5230\u9644\u52a0\u7ec4 usermod -a -G GROUP USER usermod -a -G GROUP1,GROUP2,GROUP3 USER \u4fee\u6539\u7528\u6237\u4e3b\u7ec4 usermod -a -g GROUP USER \u4fee\u6539\u7528\u6237\u4fe1\u606f usermod -c \"GECOS Comments\" USER \u4fee\u6539\u7528\u6237\u4e3b\u76ee\u5f55\uff0c\u4f7f\u7528\u7edd\u5bf9\u8def\u5f84\uff0c -m \u53c2\u6570\u4f1a\u628a\u539f\u4e3b\u76ee\u5f55\u7684\u5185\u5bb9\u79fb\u52a8\u5230\u65b0\u4e3b\u76ee\u5f55\u3002 usermod -d NEW_HOME_DIR USER usermod -d NEW_HOME_DIR -m USER \u4fee\u6539\u7528\u6237shell usermod -s SHELL USER \u4fee\u6539\u7528\u6237UID usermod -u UID USER \u4fee\u6539\u7528\u6237\u540d\uff08\u4e0d\u5e38\u7528\uff09\uff0c\u540c\u65f6\u4e5f\u9700\u8981\u4fee\u6539\u7528\u6237\u4e3b\u76ee\u5f55\u3002 usermod -l NEW_USER USER \u4fee\u6539\u7528\u6237\u8fc7\u671f\u5c5e\u6027\uff0c\u65e5\u671f\u683c\u5f0f\u662f YYYY-MM-DD usermod -e DATE USER \u5982\u679c\u8bbe\u5b9a\u6c38\u4e0d\u8fc7\u671f\uff0c\u5219\u7f6e\u7a7a\u65e5\u671f\uff1a usermod -e \"\" USER \u67e5\u770b\u5f53\u524d\u7528\u6237\u7684\u8fc7\u671f\u65e5\u671f $ sudo chage -l vagrant Last password change : Oct 30 , 2022 Password expires : never Password inactive : never Account expires : never Minimum number of days between password change : 0 Maximum number of days between password change : 99999 Number of days of warning before password expires : 7 \u9501\u5b9a\u7528\u6237\u3002 \u6b64\u547d\u4ee4\u5c06\u5728\u52a0\u5bc6\u5bc6\u7801\u524d\u63d2\u5165\u4e00\u4e2a\u611f\u53f9\u53f7 (!) \u6807\u8bb0\u3002 \u5f53 /etc/shadow \u6587\u4ef6\u4e2d\u7684\u5bc6\u7801\u5b57\u6bb5\u5305\u542b\u611f\u53f9\u53f7\u65f6\uff0c\u7528\u6237\u5c06\u65e0\u6cd5\u4f7f\u7528\u5bc6\u7801\u9a8c\u8bc1\u767b\u5f55\u7cfb\u7edf\u3002 \u5176\u4ed6\u767b\u5f55\u65b9\u6cd5\u4ecd\u7136\u5141\u8bb8\uff0c\u4f8b\u5982\u57fa\u4e8e\u5bc6\u94a5\u7684\u8eab\u4efd\u9a8c\u8bc1\u6216\u5207\u6362\u5230\u7528\u6237\u3002 \u5982\u679c\u8981\u9501\u5b9a\u8d26\u6237\u5e76\u7981\u7528\u6240\u6709\u767b\u5f55\u65b9\u5f0f\uff0c\u8fd8\u9700\u8981\u5c06\u5230\u671f\u65e5\u671f\u8bbe\u7f6e\u4e3a1\u3002 usermod -L USER usermod -L -e 1 USER \u89e3\u9501\u7528\u6237 usermod -U USER 4.3.\u5220\u9664\u7528\u6237 userdel \u00b6 userdel \u547d\u4ee4\u6267\u884c\u65f6\uff0c\u4f1a\u8bfb\u53d6 /etc/login.defs \u6587\u4ef6\u7684\u5185\u5bb9\u3002 \u6b64\u6587\u4ef6\u4e2d\u5b9a\u4e49\u7684\u5c5e\u6027\u4f1a\u8986\u76d6 userdel \u7684\u9ed8\u8ba4\u884c\u4e3a\u3002 \u5982\u679c\u5728\u6b64\u6587\u4ef6\u4e2d\u5c06 USERGROUPS_ENAB \u8bbe\u7f6e\u4e3a yes \uff0c userdel \u5c06\u5220\u9664\u4e0e\u7528\u6237\u540c\u540d\u7684\u7ec4\uff0c\u524d\u63d0\u662f\u6ca1\u6709\u5176\u4ed6\u7528\u6237\u662f\u8be5\u7ec4\u7684\u6210\u5458\u3002 userdel \u547d\u4ee4\u4ece /etc/passwd \u548c /etc/shadow \u6587\u4ef6\u4e2d\u5220\u9664\u7528\u6237\u6761\u76ee\u3002 userdel \u547d\u4ee4\u5220\u9664\u7528\u6237\u5e10\u6237\u65f6\uff0c\u4e00\u822c\u4e0d\u4f1a\u5220\u9664\u7528\u6237\u4e3b\u76ee\u5f55\u548c\u90ae\u4ef6\u5047\u8131\u673amail spool\u76ee\u5f55\u3002 \u4f7f\u7528 -r \u9009\u9879\u5f3a\u5236\u5220\u9664\u7528\u6237\u7684\u4e3b\u76ee\u5f55\u548c\u90ae\u4ef6\u5047\u8131\u673a\u76ee\u5f55\u3002 \u5982\u679c\u8981\u5220\u9664\u7684\u7528\u6237\u4ecd\u7136\u5904\u4e8e\u767b\u5f55\u72b6\u6001\uff0c\u6216\u8005\u6709\u5c5e\u4e8e\u8be5\u7528\u6237\u7684\u6b63\u5728\u8fd0\u884c\u7684\u8fdb\u7a0b\uff0c\u5219 userdel \u547d\u4ee4\u4e0d\u5141\u8bb8\u5220\u9664\u8be5\u7528\u6237\u3002 \u4f7f\u7528 -f \u9009\u9879\u5f3a\u5236\u5220\u9664\u7528\u6237\u5e10\u6237\uff0c\u5373\u4f7f\u7528\u6237\u4ecd\u7136\u767b\u5f55\u6216\u6709\u5c5e\u4e8e\u8be5\u7528\u6237\u7684\u6b63\u5728\u8fd0\u884c\u7684\u8fdb\u7a0b\u4e5f\u662f\u5982\u6b64\u3002 userdel USER userdel -r USER 4.4.\u67e5\u770b\u7528\u6237\u4fe1\u606f id \u00b6 \u7c7bUnix\u64cd\u4f5c\u7cfb\u7edf\u4e2d\u7684\u6bcf\u4e2a\u7528\u6237\u90fd\u7531\u4e00\u4e2a\u4e0d\u540c\u7684\u6574\u6570\u6807\u8bc6\uff0c\u8fd9\u4e2a\u552f\u4e00\u7684\u6570\u5b57\u79f0\u4e3aUserID\u3002 \u4e3a\u8fdb\u7a0bprocess\u5b9a\u4e49\u4e86\u4e09\u79cd\u7c7b\u578b\u7684UID\uff0c\u53ef\u4ee5\u6839\u636e\u4efb\u52a1\u7684\u6743\u9650\u52a8\u6001\u66f4\u6539\u3002 \u5b9a\u4e49\u7684\u4e09\u79cd\u4e0d\u540c\u7c7b\u578b\u7684UID\u662f\uff1a \u771f\u5b9e\u7528\u6237ID\uff08Real UserId\uff09\uff1a\u5bf9\u4e8e\u4e00\u4e2a\u8fdb\u7a0b\uff0cReal UserId\u5c31\u662f\u542f\u52a8\u5b83\u7684\u7528\u6237\u7684 UserID\u3002 \u5b83\u5b9a\u4e49\u4e86\u8fd9\u4e2a\u8fdb\u7a0b\u53ef\u4ee5\u8bbf\u95ee\u54ea\u4e9b\u6587\u4ef6\u3002 \u6709\u6548\u7528\u6237\u540d\uff08Effective UserID\uff09\uff1a\u5b83\u901a\u5e38\u4e0e Real UserID \u76f8\u540c\uff0c\u4f46\u6709\u65f6\u4f1a\u66f4\u6539\u4e3a\u4f7f\u975e\u7279\u6743\u7528\u6237\u80fd\u591f\u8bbf\u95ee\u90a3\u4e9b\u53ea\u80fd\u7531\u7279\u6743\u7528\u6237\uff08\u5982 root \uff09\u8bbf\u95ee\u7684\u6587\u4ef6\u3002 \u4fdd\u5b58\u7684\u7528\u6237ID\uff08Saved UserID\uff09 \uff1a\u5f53\u4e00\u4e2a\u4ee5\u63d0\u5347\u7684\u6743\u9650\uff08\u901a\u5e38\u662f root \uff09\u8fd0\u884c\u7684\u8fdb\u7a0b\u9700\u8981\u505a\u4e00\u4e9b\u4f4e\u6743\u9650\u7684\u4efb\u52a1\u65f6\u4f7f\u7528\uff0c\u53ef\u4ee5\u901a\u8fc7\u4e34\u65f6\u5207\u6362\u5230\u975e\u7279\u6743\u5e10\u6237\u6765\u5b9e\u73b0\u3002\u5728\u6267\u884c\u4f4e\u6743\u9650\u4efb\u52a1\u65f6\uff0c\u6709\u6548\u7684 UID \u88ab\u66f4\u6539\u4e3a\u67d0\u4e2a\u8f83\u4f4e\u6743\u9650\u7684\u503c\uff0c\u5e76\u4e14 euid \u88ab\u4fdd\u5b58\u5230\u5df2\u4fdd\u5b58\u7684 userID (suid)\u4e2d\uff0c\u4ee5\u4fbf\u5728\u4efb\u52a1\u5b8c\u6210\u65f6\u7528\u4e8e\u5207\u6362\u56de\u7279\u6743\u5e10\u6237\u3002 \u5728\u4e00\u4e2a\u7ec8\u7aef\u7a97\u53e3\u6267\u884c\u4e0b\u9762\u547d\u4ee4\uff0c\u6682\u505c\u5728\u65b0\u5bc6\u7801\u8f93\u5165\u8fd9\u4e00\u6b65\u3002 $ ls -ltr /usr/bin/passwd -rwsr-xr-x. 1 root shadow 65208 May 8 2022 /usr/bin/passwd $ passwd Changing password for vagrant. Current password: New password: \u65b0\u5f00\u4e00\u4e2a\u7ec8\u7aef\u7a97\u53e3\u3002 $ ps -a | grep passwd 3040 pts/0 00 :00:00 passwd $ ps -eo pid,euid,ruid | grep 3040 3040 0 1000 \u4e0a\u9762\u8f93\u51fa\u53ef\u4ee5\u770b\u51fa\uff0c passwd \u8fd9\u4e2a\u8fdb\u7a0b\u7684Effective UserID\u662f 0 \u3002Real UserId\u662f 1000 . id \u547d\u4ee4\u67e5\u770b\u7528\u6237\u6709\u6548\u7684UID\u548cGID\u3002 \u67e5\u770b\u5f53\u524d\u7528\u6237\u7684\u4fe1\u606f\uff1a $ id uid = 1000 ( vagrant ) gid = 478 ( wheel ) groups = 478 ( wheel ) ,0 ( root ) context = unconfined_u:unconfined_r:unconfined_t:s0 \u67e5\u770b\u6307\u5b9a\u7528\u6237\u7684\u4fe1\u606f\uff1a $ id vagrant uid = 1000 ( vagrant ) gid = 478 ( wheel ) groups = 0 ( root ) ,478 ( wheel ) \u67e5\u770b\u5f53\u524d\u7528\u6237\u7684GID\uff1a $ id -g 478 \u67e5\u770b\u5f53\u524d\u7528\u6237\u7684UID\uff1a $ id -u 1000 \u67e5\u770b\u5f53\u524d\u7528\u6237\u6240\u6709\u7ec4\u7684GID\uff1a $ id -G 478 0 \u67e5\u770b\u5f53\u524d\u7528\u6237\u540d\uff1a $ id -un vagrant \u67e5\u770b\u5f53\u524d\u7528\u6237\u7684GID $ id -ur 1000 \u53ea\u6709SELinux\u6fc0\u6d3b\u540e\u624d\u6709 $ id -Z unconfined_u:unconfined_r:unconfined_t:s0 \u7c7b\u4f3c\u4e8e whoami \u547d\u4ee4 $ id -znG wheelroot 4.5.\u5207\u6362\u7528\u6237 su \u00b6 \u547d\u4ee4 su - username \u662f\u767b\u5f55\u5f0f\u5207\u6362\u7528\u6237\u3002\u4f1a\u8bfb\u53d6\u76ee\u6807\u7528\u6237\u7684\u914d\u7f6e\u6587\u4ef6\uff0c\u5207\u6362\u81f3\u76ee\u6807\u7528\u6237\u7684\u4e3b\u76ee\u5f55\u3002 \u547d\u4ee4 su username \u662f\u975e\u767b\u5f55\u5f0f\u5207\u6362\u7528\u6237\u3002\u4e0d\u8bfb\u53d6\u76ee\u6807\u7528\u6237\u7684\u914d\u7f6e\u6587\u4ef6\uff0c\u4e0d\u6539\u53d8\u5f53\u524d\u5de5\u4f5c\u76ee\u5f55\u3002 \u5207\u6362\u6210root\u7528\u6237\uff0c\u5e76\u4f7f\u7528zsh shell\u3002 su -s /usr/bin/zsh su -s /usr/bin/zsh root \u5207\u6362\u6210tester1\u7528\u6237\uff0c\u4f7f\u7528bash shell su - tester1 -s /bin/bash su - -s /bin/bash tester1 \u4fdd\u7559\u5f53\u524d\u7528\u6237\u73af\u5883\u4e0d\u53d8\u3002 su -p root \u4e0d\u4ea4\u4e92\u5f0f\u5207\u6362\u7528\u6237\uff0c\u53ea\u7528\u76ee\u6807\u7528\u6237\u6267\u884c\u67d0\u4e9b\u547d\u4ee4\u3002 su -c ps su - root -c \"getent passwd\" su - root -s /bin/bash -c \"getent passwd\" root \u7528\u6237\u5207\u6362\u81f3\u5176\u4ed6\u7528\u6237\u4e0d\u9700\u8981\u5bc6\u7801\uff0c\u975e root \u7528\u6237\u5207\u6362\u5176\u4ed6\u7528\u6237\u9700\u8981\u5bc6\u7801\u3002 4.6.\u8bbe\u7f6e\u5bc6\u7801 \u00b6 4.6.1. passwd \u00b6 \u4fee\u6539\u5f53\u524d\u7528\u6237\u81ea\u5df1\u7684\u5bc6\u7801\uff1a passwd \u4fee\u6539\u5176\u4ed6\u7528\u6237\u7684\u5bc6\u7801\uff1a sudo passwd root \u67e5\u770b\u67d0\u4e2a\u7528\u6237\u5bc6\u7801\u72b6\u6001\uff1a $ sudo passwd -S root root P 10 /30/2022 -1 -1 -1 -1 $ sudo passwd -S vagrant vagrant P 10 /30/2022 0 99999 7 -1 \u68c0\u67e5\u5168\u90e8\u7528\u6237\u7684\u5bc6\u7801\u72b6\u6001\uff1a sudo passwd -Sa \u5bc6\u7801\u72b6\u6001\u8bf4\u660e\uff1a Username Status Date Last Changed Minimum Age Maximum Age Warning Period Inactivity Period vagrant P 10 /30/2022 0 99999 7 -1 root P 10 /30/2022 -1 -1 -1 -1 Status\u7684\u63cf\u8ff0\uff1a P : Usable password NP : No password L : Locked password Age\u7684\u4e00\u4e9b\u7279\u6b8a\u503c\uff1a 9999 : Never expires 0 : Can be changed at anytime -1 : Not active \u5f3a\u5236\u8981\u6c42\u7528\u6237\u4e0b\u6b21\u767b\u5f55\u65f6\u4fee\u6539\u5bc6\u7801\uff1a $ sudo passwd -e tester1 $ sudo passwd -S tester1 tester1 P 01 /01/1970 0 99999 7 -1 \u7528\u6237tester1\u7684\u5bc6\u7801\u65e5\u671f\u5df2\u7ecf\u88ab\u6539\u6210 01/01/1970 \u4e86\u3002\u8fd9\u4e2a\u65e5\u671f\u7b97\u662fUnix\u7684\u201c\u7eaa\u5143\uff08epoch\uff09\u201d\u65e5\u671f\uff0c\u610f\u5473\u7740Unix\u7684\u65e5\u671f\u8d77\u70b9\uff0c0\u5929\u3002 \u9501\u5b9a\u67d0\u4e2a\u7528\u6237\uff1a $ sudo passwd -l tester1 $ sudo passwd -S tester1 tester1 L 01 /01/1970 0 99999 7 -1 \u6b64\u65f6\u7528\u6237 tester1 \u7684\u72b6\u6001\u680f\u5df2\u7ecf\u53d8\u6210\u4e86 L \uff0c\u9501\u5b9a\u72b6\u6001\u3002 \u89e3\u9501\u67d0\u4e2a\u7528\u6237\uff1a $ sudo passwd -u tester1 $ sudo passwd -S tester1 tester1 P 01 /01/1970 0 99999 7 -1 \u6b64\u65f6\u7528\u6237 tester1 \u7684\u72b6\u6001\u680f\u5df2\u7ecf\u4ece L \u53d8\u56de\u4e86 P \uff0c\u89e3\u9664\u4e86\u9501\u5b9a\u72b6\u6001\u3002 \u5220\u9664\u7528\u6237\u5bc6\u7801\u3002\u8fd9\u4e2a\u64cd\u4f5c\u614e\u91cd\uff0c\u5bc6\u7801\u5220\u9664\u540e\u8be5\u7528\u6237\u53ef\u4ee5\u4e0d\u9700\u8981\u5bc6\u7801\u5c31\u80fd\u8bbf\u95ee\u7cfb\u7edf\u3002 $ sudo passwd -d tester1 $ sudo passwd -S tester1 tester1 NP 01 /01/1970 0 99999 7 -1 \u6b64\u65f6\u7528\u6237 tester1 \u7684\u72b6\u6001\u680f\u662f NP \u3002 4.6.2. pwgen \u00b6 \u5b89\u88c5\u5305\u3002 mkpasswd\u547d\u4ee4\u6709\u6b67\u4e49\uff0c2\u4e2a\u540c\u540d\u547d\u4ee4\u5b9e\u73b0\u4e0d\u540c\u529f\u80fd\uff0c\u751f\u6210\u968f\u673a\u5bc6\u7801\u5efa\u8bae\u4f7f\u7528 pwgen \u547d\u4ee4\u3002Rocky9\u6ca1\u6709\u627e\u5230pwgen\u5305\u3002 sudo zypper in pwgen sudo apt install pwgen \u968f\u673a\u751f\u6210\u957f\u5ea68\u4f4d\u5b89\u5168\u5bc6\u7801\u3002 pwgen -s -1 \u968f\u673a\u751f\u6210\u957f\u5ea614\u4f4d\u5b89\u5168\u5bc6\u7801\u3002 pwgen -s -1 14 \u968f\u673a\u751f\u62102\u4e2a\u957f\u5ea615\u4f4d\u5b89\u5168\u5bc6\u7801\u3002 pwgen -s -1 15 2 \u968f\u673a\u751f\u62105\u4e2a\u5bc6\u7801\uff0c\u957f\u5ea610\u4f4d\uff0c\u6bcf\u4e2a\u5bc6\u7801\u81f3\u5c11\u542b\u4e00\u4e2a\u7279\u6b8a\u5b57\u7b26\uff0c\u7ed3\u679c\u4ee5\u5217\u5f62\u5f0f\u8f93\u51fa\u3002 pwgen -s -1 -y 10 5 \u751f\u6210\u957f\u5ea68\uff0c\u542b\u6709\u6570\u5b57\uff0c\u542b\u6709\u5927\u5c0f\u5199\u5b57\u6bcd\u7684\u5bc6\u78014\u4e2a\uff0c\u5217\u6253\u5370 pwgen -s -n -c -C -1 8 4 \u751f\u6210\u957f\u5ea68\uff0c\u4e0d\u542b\u6570\u5b57\uff0c\u53ea\u542b\u5c0f\u5199\u5b57\u6bcd\uff0c\u5217\u6253\u5370 pwgen -s -c -A -0 -1 8 4 \u751f\u6210\u957f\u5ea616\uff0c\u542b\u6709\u6570\u5b57\uff0c\u542b\u6709\u5927\u5c0f\u5199\u5b57\u6bcd\uff0c\u542b\u6709\u7279\u6b8a\u5b57\u7b26\u7684\u5bc6\u78013\u4e2a\uff0c\u884c\u6253\u5370 pwgen -s -n -c -y -1 16 3 \u751f\u6210\u957f\u5ea680\uff0c\u4e0d\u542b\u5143\u97f3\u548c\u6570\u5b57\uff0c\u81f3\u5c11\u542b\u6709\u4e00\u4e2a\u5927\u5199\u5b57\u6bcd\uff0c\u884c\u6253\u5370 pwgen -s -v -c -0 80 1 4.6.3.\u975e\u4ea4\u4e92\u5f0f\u8bbe\u7f6e\u5bc6\u7801 \u00b6 \u65b9\u6cd51\uff1a $ echo -e '123456\\n123456' | sudo passwd tester1 New password: BAD PASSWORD: it is too simplistic/systematic BAD PASSWORD: is too simple Retype new password: passwd: password updated successfully \u65b9\u6cd52\uff1a Rocky\u4e2d\u53ef\u4ee5\u4f7f\u7528\u4e0b\u9762\u65b9\u6cd5\u3002 pwgen -ncy1 16 1 | tee passwd.txt | sudo passwd --stdin tester1 openSUSE\u548cUbuntu\u53ef\u4ee5\u7528\u4e0b\u9762\u65b9\u6cd5\u3002 echo \"tester1:\" ` pwgen -ncy1 16 1 ` | tee passwd.txt | sudo chpasswd \u65b9\u6cd53\uff1a\u6839\u636e\u9884\u5148\u7ed9\u5b9a\u7684\u7528\u6237\u5217\u8868\uff0c\u6279\u91cf\u751f\u6210\u5bc6\u7801\u3002 $ cat > user-list.txt < user.txt < file 67274683 lrwxrwxrwx. 1 vagrant wheel 12 Nov 1 11 :20 symlinkfile1-1 -> symlinkfile1 67274682 lrwxrwxrwx. 1 vagrant wheel 4 Nov 1 10 :43 symlinkfile2 -> file 33555262 drwxr-xr-x. 2 vagrant wheel 6 Nov 1 11 :30 typelink \u4ee5 67274680 -rw-r--r--. 3 vagrant wheel 31 Nov 1 11:14 file \u4e3a\u4f8b\uff1a 67274680 : inode \u7d22\u5f15\u8282\u70b9\u7f16\u53f7\u3002 -rw-r--r-- \uff1a\u6587\u4ef6\u7c7b\u578b\u53ca\u6743\u9650 - \uff1a\u6587\u4ef6\u7c7b\u578b\uff0c\u4f8b\u5b50\u4e2d\u51fa\u73b0\u4e86\u4e09\u79cd\uff0c - \uff0c l \u548c d \u3002 - \uff1a\u666e\u901a\u6587\u4ef6 d \uff1a\u76ee\u5f55 l \uff1a\u7b26\u53f7\u94fe\u63a5\u6587\u4ef6\uff08link\uff09 b \uff1a\u5757\u8bbe\u5907\uff08block\uff09 c \uff1a\u5b57\u7b26\u8bbe\u5907\uff08character\uff09 p \uff1a\u7ba1\u9053\u6587\u4ef6\uff08pipe\uff09 s \uff1a\u5957\u63a5\u5b57\u6587\u4ef6\uff08socket\uff09 rw-r--r-- \uff1a\u6587\u4ef6\u6743\u9650\uff0c\u4ece\u5de6\u5230\u53f3\u4f9d\u6b21\u4e3a\uff1a\uff08\u7528\u6237\u7684\u6700\u7ec8\u6743\u9650\uff0c\u662f\u4ece\u5de6\u5411\u53f3\u5339\u914d\uff0c\u4e00\u65e6\u5339\u914d\u5219\u6743\u9650\u7acb\u5373\u751f\u6548\uff0c\u4e0d\u518d\u5411\u53f3\u7ee7\u7eed\u5339\u914d\uff09 rw- \uff1a\u6587\u4ef6\u5c5e\u4e3b\u6743\u9650\uff08u\uff09\uff0c\u4f8b\u5b50\u4e2d\u662f vagrant \u3002 r-- \uff1a\u6587\u4ef6\u5c5e\u7ec4\u7684\u6743\u9650\uff08g\uff09\uff0c\u4f8b\u5b50\u4e2d\u662f wheel \u3002 r-- \uff1a\u5176\u4ed6\u7ec4\u7684\u6743\u9650\uff08o\uff09\u3002 . \uff1a\u8fd9\u4e2a\u70b9\u8868\u793a\u6587\u4ef6\u5e26\u6709SELinux\u7684\u5b89\u5168\u4e0a\u4e0b\u6587\uff08SELinux Contexts\uff09\u3002\u5173\u95edSELinux\uff0c\u65b0\u521b\u5efa\u7684\u6587\u4ef6\u5c31\u4e0d\u4f1a\u518d\u6709\u8fd9\u4e2a\u70b9\u4e86\u3002\u4f46\u662f\uff0c\u4ee5\u524d\u521b\u5efa\u7684\u6587\u4ef6\u672c\u6765\u6709\u8fd9\u4e2a\u70b9\u7684\u8fd8\u4f1a\u663e\u793a\u8fd9\u4e2a\u70b9\uff08\u867d\u7136SELinux\u4e0d\u8d77\u4f5c\u7528\u4e86\uff09\u3002 3 \uff1a\u786c\u94fe\u63a5\u6570\uff0c\u4f8b\u5b50\u4e2d file \u548c hardlinkfile1 \u548c hardlinkfile2 \u4e4b\u95f4\u662f\u786c\u94fe\u63a5\uff0c\u6240\u4ee5\u8fd9\u4e09\u4e2a\u6587\u4ef6\u7684\u786c\u94fe\u63a5\u6570\u90fd\u662f 3 \u3002 vagrant \uff1a\u6587\u4ef6\u5c5e\u4e3bowner wheel \uff1a\u6587\u4ef6\u5c5e\u7ec4group 31 \uff1a\u6587\u4ef6\u6216\u76ee\u5f55\u7684\u5927\u5c0f Nov 1 11:14 \uff1a\u6587\u4ef6\u6216\u76ee\u5f55\u7684\u521b\u5efa\u65e5\u671f\u548c\u65f6\u95f4 file \uff1a\u6587\u4ef6\u6216\u76ee\u5f55\u540d\u79f0 \u4e0b\u9762\u662f\u547d\u4ee4 ls -ihl \u5728openSUSE\u548cUbuntu\u4e0a\u7684\u663e\u793a\u7ed3\u679c\u3002 $ ls -ihl 233647 -rw-r--r-- 3 vagrant wheel 31 Nov 1 15 :52 file 233647 -rw-r--r-- 3 vagrant wheel 31 Nov 1 15 :52 hardlinkfile1 233647 -rw-r--r-- 3 vagrant wheel 31 Nov 1 15 :52 hardlinkfile2 233648 lrwxrwxrwx 1 vagrant wheel 4 Nov 1 15 :52 symlinkfile1 -> file 233650 lrwxrwxrwx 1 vagrant wheel 12 Nov 1 15 :52 symlinkfile1-1 -> symlinkfile1 233649 lrwxrwxrwx 1 vagrant wheel 4 Nov 1 15 :52 symlinkfile2 -> file 233646 drwxr-xr-x 1 vagrant wheel 0 Nov 1 15 :51 typelink 7.1.\u4fee\u6539\u5c5e\u4e3b chown \u00b6 chown \u547d\u4ee4\u4fee\u6539\u6587\u4ef6\u5c5e\u4e3b\uff08\u6240\u6709\u8005\uff0cowner\uff09\u3002 \u4fee\u6539\u6587\u4ef6\u5c5e\u4e3b\u4e3aroot\u3002 $ ll f1.txt -rw-r--r--. 1 vagrant wheel 41 Nov 14 22 :23 f1.txt $ sudo chown root f1.txt $ ll f1.txt -rw-r--r--. 1 root wheel 41 Nov 14 22 :23 f1.txt \u4fee\u6539\u6587\u4ef6\u7684\u5c5e\u7ec4\u4e3abin\u3002 $ sudo chown :bin f1.txt $ ll f1.txt -rw-r--r--. 1 root bin 41 Nov 14 22 :23 f1.txt \u540c\u65f6\u4fee\u6539\u6587\u4ef6\u7684\u5c5e\u4e3b\u548c\u5c5e\u7ec4\u3002 $ sudo chown vagrant.wheel f1.txt $ ll f1.txt -rw-r--r--. 1 vagrant wheel 41 Nov 14 22 :23 f1.txt \u53c2\u7167\u67d0\u6587\u4ef6\u4fee\u6539\u53e6\u4e00\u6587\u4ef6\u7684\u5c5e\u6027\u3002 $ ll file.py -rw-r--r--. 1 vagrant wheel 56 Nov 13 22 :50 file.py $ ll user.txt -rw-r--r--. 1 root bin 21 Nov 27 23 :59 user.txt $ sudo chown root.bin user.txt $ sudo chown --reference = user.txt file.py $ ll file.py -rw-r--r--. 1 root bin 56 Nov 13 22 :50 file.py \u9012\u5f52\u4fee\u6539\u6240\u6709\u5b50\u76ee\u5f55\u53ca\u6587\u4ef6\u7684\u5c5e\u4e3b\u548c\u5c5e\u7ec4\u3002 sudo chown -R vagrant.wheel ~ 7.2.\u4fee\u6539\u5c5e\u7ec4 chgrp \u00b6 \u4fee\u6539\u76ee\u5f55\u7684\u5c5e\u7ec4\u3002 sudo chgrp bin ~~ \u4fee\u6539\u76ee\u5f55\u53ca\u5b50\u76ee\u5f55\u53ca\u6587\u4ef6\u7684\u5c5e\u7ec4\u3002 sudo chgrp -R bin ~~ 7.3.\u6587\u4ef6\u548c\u76ee\u5f55\u6743\u9650 \u00b6 \u6587\u4ef6\uff1a r \uff1a\u53ef\u4ee5\u8bfb\u53d6\u8be5\u6587\u4ef6\u5185\u5bb9\uff0c\u6bd4\u5982\u901a\u8fc7 cat \u547d\u4ee4\u3002 w \uff1a\u53ef\u4ee5\u4fee\u6539\u8be5\u6587\u4ef6\u5185\u5bb9\uff0c\u53ef\u4ee5\u53ea\u6709 w \u800c\u6ca1\u6709 r \u3002 x \uff1a\u53ef\u4ee5\u628a\u8be5\u6587\u4ef6\u63d0\u8bf7\u5185\u6838\u542f\u52a8\u4e3a\u4e00\u4e2a\u8fdb\u7a0b\uff0c\u5373\u53ef\u4ee5\u6267\u884c\u8be5\u6587\u4ef6\uff08\u8be5\u6587\u4ef6\u7684\u5185\u5bb9\u5fc5\u987b\u662f\u53ef\u4ee5\u6267\u884c\uff09\u3002 \u76ee\u5f55\uff1a\uff08\u5bf9\u76ee\u5f55\u800c\u8a00\uff0c\u901a\u5e38\u9700\u8981\u7ed9 r \u548c x \u6743\u9650\uff09\uff08\u4ece\u76ee\u5f55\u89d2\u5ea6\u770b\uff0c\u76ee\u5f55\u5185\u6587\u4ef6\u5217\u8868\u7b49\u4e8e\u76ee\u5f55\u8282\u70b9\u7684\u5185\u5bb9\uff09 r \uff1a\u80fd\u770b\u6587\u4ef6\u5217\u8868\uff0c\u4f46\u4e0d\u80fd\u8bbf\u95ee\u6240\u542b\u6587\u4ef6\u7684\u5185\u5bb9\u53ca\u5176\u5c5e\u6027\u4fe1\u606f\uff0c\u5305\u62ecinode\u53f7\u3002 w \uff1a\u80fd\u5728\u8be5\u76ee\u5f55\u5185\u521b\u5efa\u548c\u5220\u9664\u6587\u4ef6\uff0c\u4e0d\u7531\u76ee\u5f55\u5185\u6587\u4ef6\u672c\u8eab\u7684\u6743\u9650\u51b3\u5b9a\u3002 x \uff1a\u80fdcd\u8fdb\u76ee\u5f55\uff0c\u80fd\u901a\u8fc7 ls -l file \u548c stat file \u67e5\u770b\u8be5\u76ee\u5f55\u4e2d\u5236\u5b9a\u6587\u4ef6\u7684\u5143\u6570\u636e\u3002 X \uff1a\u8868\u793a\u53ea\u6709\u5f53\u8be5\u6587\u4ef6\u662f\u4e2a\u5b50\u76ee\u5f55\u6216\u8005\u8be5\u6587\u4ef6\u5df2\u7ecf\u88ab\u8bbe\u5b9a\u8fc7\u4e3a\u53ef\u6267\u884c\u3002 \u6709\u53ea\u8bfb\u6743\u9650\u7684\u7528\u6237\u4e0d\u80fd\u7528cd\u8fdb\u5165\u8be5\u76ee\u5f55\uff0c\u8fd8\u5fc5\u987b\u6709\u6267\u884c\u6743\u9650\u624d\u80fd\u8fdb\u5165\u3002 \u6709\u6267\u884c\u6743\u9650\u7684\u7528\u6237\u53ea\u6709\u5728\u77e5\u9053\u6587\u4ef6\u540d\uff0c\u5e76\u62e5\u6709\u8bfb\u6743\u5229\u7684\u60c5\u51b5\u4e0b\u624d\u53ef\u4ee5\u8bbf\u95ee\u76ee\u5f55\u4e0b\u7684\u6587\u4ef6\u3002 \u5fc5\u987b\u6709\u8bfb\u548c\u6267\u884c\u6743\u9650\u624d\u53ef\u4ee5ls\u5217\u51fa\u76ee\u5f55\u6e05\u5355\uff0c\u6216\u4f7f\u7528cd\u547d\u4ee4\u8fdb\u5165\u76ee\u5f55\u3002 \u6709\u76ee\u5f55\u7684\u5199\u6743\u9650\uff0c\u53ef\u4ee5\u521b\u5efa\u3001\u5220\u9664\u6216\u4fee\u6539\u76ee\u5f55\u4e0b\u7684\u4efb\u4f55\u6587\u4ef6\u6216\u5b50\u76ee\u5f55\uff0c\u5373\u4f7f\u4f7f\u8be5\u6587\u4ef6\u6216\u5b50\u76ee\u5f55\u5c5e\u4e8e\u5176\u4ed6\u7528\u6237\u4e5f\u662f\u5982\u6b64\u3002 \u5e38\u7528\u6743\u9650\u4f8b\u5b50\uff1a -rw------- ( 600 ) \u53ea\u6709\u6240\u6709\u8005\u624d\u6709\u8bfb\u548c\u5199\u7684\u6743\u9650 -rw-r--r-- ( 644 ) \u53ea\u6709\u6240\u6709\u8005\u624d\u6709\u8bfb\u548c\u5199\u7684\u6743\u9650\uff0c\u7ec4\u548c\u5176\u4ed6\u4eba\u53ea\u6709\u8bfb\u7684\u6743\u9650 -rwx------ ( 700 ) \u53ea\u6709\u6240\u6709\u8005\u624d\u6709\u8bfb\uff0c\u5199\uff0c\u6267\u884c\u7684\u6743\u9650 -rwxr-xr-x ( 755 ) \u53ea\u6709\u6240\u6709\u8005\u624d\u6709\u8bfb\uff0c\u5199\uff0c\u6267\u884c\u7684\u6743\u9650\uff0c\u7ec4\u548c\u5176\u4ed6\u4eba\u53ea\u6709\u8bfb\u548c\u6267\u884c\u7684\u6743\u9650 -rwx--x--x ( 711 ) \u53ea\u6709\u6240\u6709\u8005\u624d\u6709\u8bfb\uff0c\u5199\uff0c\u6267\u884c\u7684\u6743\u9650\uff0c\u7ec4\u548c\u5176\u4ed6\u4eba\u53ea\u6709\u6267\u884c\u7684\u6743\u9650 -rw-rw-rw- ( 666 ) \u6bcf\u4e2a\u4eba\u90fd\u6709\u8bfb\u5199\u7684\u6743\u9650 -rwxrwxrwx ( 777 ) \u6bcf\u4e2a\u4eba\u90fd\u6709\u8bfb\u5199\u548c\u6267\u884c\u7684\u6743\u9650 7.4.\u6743\u9650\u4fee\u6539 chmod \u00b6 \u547d\u4ee4\u683c\u5f0f\uff1a chmod [ -cfvR ] [ --help ] [ --version ] mode file mode \u5b57\u4e32\u683c\u5f0f\u4e3a\uff1a [ ugoa ][ +- =][ rwxXst ] who: u \u6587\u4ef6\u6240\u6709\u8005 g \u6587\u4ef6\u6240\u6709\u8005\u6240\u5728\u7ec4 o \u5176\u4ed6\u7528\u6237 a \u6240\u6709\u7528\u6237\uff0c\u76f8\u5f53\u4e8e ugo operator: + \u4e3a\u6307\u5b9a\u7684\u7528\u6237\u7c7b\u578b\u589e\u52a0\u6743\u9650 - \u53bb\u9664\u6307\u5b9a\u7528\u6237\u7c7b\u578b\u7684\u6743\u9650 = \u8bbe\u7f6e\u6307\u5b9a\u7528\u6237\u6743\u9650\u7684\u8bbe\u7f6e\uff0c\u5373\u5c06\u7528\u6237\u7c7b\u578b\u7684\u6240\u6709\u6743\u9650\u91cd\u65b0\u8bbe\u7f6e permission: r \u8bbe\u7f6e\u4e3a\u53ef\u8bfb\u6743\u9650 w \u8bbe\u7f6e\u4e3a\u53ef\u5199\u6743\u9650 x \u8bbe\u7f6e\u4e3a\u53ef\u6267\u884c\u6743\u9650 X \u7279\u6b8a\u6267\u884c\u6743\u9650\uff0c\u53ea\u6709\u5f53\u6587\u4ef6\u4e3a\u76ee\u5f55\u6587\u4ef6\uff0c\u6216\u8005\u5176\u4ed6\u7c7b\u578b\u7684\u7528\u6237\u6709\u53ef\u6267\u884c\u6743\u9650\u65f6\uff0c\u624d\u5c06\u6587\u4ef6\u6743\u9650\u8bbe\u7f6e\u53ef\u6267\u884c s \u5f53\u6587\u4ef6\u88ab\u6267\u884c\u65f6\uff0c\u6839\u636ewho\u53c2\u6570\u6307\u5b9a\u7684\u7528\u6237\u7c7b\u578b\u8bbe\u7f6e\u6587\u4ef6\u7684 setuid \u6216\u8005 setgid \u6743\u9650 t \u8bbe\u7f6e\u7c98\u8d34\u4f4d\uff0c\u53ea\u6709\u8d85\u7ea7\u7528\u6237\u53ef\u4ee5\u8bbe\u7f6e\u8be5\u4f4d\uff0c\u53ea\u6709\u6587\u4ef6\u6240\u6709\u8005u\u53ef\u4ee5\u4f7f\u7528\u8be5\u4f4d\u3002 \u793a\u4f8b\uff1a \u5c06\u6587\u4ef6 file1.txt \u8bbe\u4e3a\u6240\u6709\u4eba\u7686\u53ef\u8bfb\u53d6\u3002 chmod ugo+r file1.txt \u5c06\u6587\u4ef6 file1.txt \u8bbe\u4e3a\u6240\u6709\u4eba\u7686\u53ef\u8bfb\u53d6\u3002 chmod a+r file1.txt \u5c06\u6587\u4ef6 file1.txt \u4e0e file2.txt \u8bbe\u4e3a\u8be5\u6587\u4ef6\u5c5e\u4e3b\u548c\u5c5e\u7ec4\u90fd\u53ef\u5199\u5165\uff0c\u4f46\u5176\u4ed6\u7528\u6237\u4e0d\u53ef\u5199\u5165\u3002 chmod ug+w,o-w file1.txt file2.txt \u4e3a ex1.py \u6587\u4ef6\u5c5e\u4e3b\u589e\u52a0\u53ef\u6267\u884c\u6743\u9650\u3002 chmod u+x ex1.py \u5c06\u76ee\u524d\u76ee\u5f55\u4e0b\u7684\u6240\u6709\u6587\u4ef6\u4e0e\u5b50\u76ee\u5f55\u7686\u8bbe\u4e3a\u4efb\u4f55\u4eba\u53ef\u8bfb\u53d6\u3002 chmod -R a+r * \u7ed9 file \u7684\u6240\u6709\u7528\u6237\u589e\u52a0\u8bfb\u6743\u9650 chmod a+r file \u5220\u9664 file \u7684\u6240\u6709\u7528\u6237\u7684\u6267\u884c\u6743\u9650 chmod a-x file \u7ed9 file \u7684\u6240\u6709\u7528\u6237\u589e\u52a0\u8bfb\u5199\u6743\u9650 chmod a+rw file \u7ed9 file \u7684\u6240\u6709\u7528\u6237\u589e\u52a0\u8bfb\u5199\u6267\u884c\u6743\u9650 chmod +rwx file \u5bf9 file \u7684\u5c5e\u4e3b\u8bbe\u7f6e\u8bfb\u5199\u6743\u9650\uff0c\u6e05\u7a7a\u5c5e\u7ec4\u548c\u5176\u4ed6\u7528\u6237\u5bf9 file \u7684\u6240\u6709\u6743\u9650\uff08\u7a7a\u683c\u4ee3\u8868\u65e0\u6743\u9650\uff09 chmod u = rw,go = file \u5bf9\u76ee\u5f55 docs \u548c\u5176\u5b50\u76ee\u5f55\u4e2d\u7684\u6240\u6709\u6587\u4ef6\u7ed9\u5c5e\u4e3b\u589e\u52a0\u8bfb\u6743\u9650\uff0c\u800c\u5bf9\u5c5e\u7ec4\u548c\u5176\u4ed6\u7528\u6237\u5220\u9664\u8bfb\u6743\u9650 chmod -R u+r,go-r docs \u5bf9 file \u7684\u5c5e\u4e3b\u548c\u5c5e\u7ec4\u8bbe\u7f6e\u8bfb\u5199\u6743\u9650, \u4e3a\u5176\u4ed6\u7528\u6237\u8bbe\u7f6e\u8bfb\u6743\u9650 chmod 664 file \u5bf9 file \u7684\u5c5e\u4e3b\u8bbe\u7f6e\u8bfb\u5199\u6267\u884c\u6743\u9650\uff0c\u76f8\u5f53\u4e8e u=rwx (4+2+1)\uff0c\u8bbe\u7f6e\u5c5e\u7ec4\u8bfb\u548c\u6267\u884c\u6743\u9650\uff0c\u76f8\u5f53\u4e8e go=rx (4+1 & 4+1)\u3002 0 \u6ca1\u6709\u7279\u6b8a\u6a21\u5f0f chmod 0755 file 4 \u8bbe\u7f6e\u4e86\u8bbe\u7f6e\u7528\u6237ID\u4f4d\uff0c\u5269\u4e0b\u7684\u76f8\u5f53\u4e8e u=rwx (4+2+1)\u548c go=rx (4+1 & 4+1)\u3002 chmod 4755 file \u5220\u9664\u53ef\u6267\u884c\u6743\u9650\u5bf9 path/ \u4ee5\u53ca\u5176\u6240\u6709\u7684\u76ee\u5f55\uff08\u4e0d\u5305\u62ec\u6587\u4ef6\uff09\u7684\u6240\u6709\u7528\u6237\uff0c\u4f7f\u7528 -type f \u5339\u914d\u6587\u4ef6 find path/ -type d -exec chmod a-x {} \\; \u5141\u8bb8\u6240\u6709\u7528\u6237\u6d4f\u89c8\u6216\u901a\u8fc7\u76ee\u5f55 path/ find path/ -type d -exec chmod a+x {} \\; 7.5.\u9ed8\u8ba4\u6743\u9650 umask \u00b6 umask \u7684\u503c\uff0c\u5b9a\u4e49\u4e86\u6240\u6709\u65b0\u5efa\u7684\u6587\u4ef6\u548c\u76ee\u5f55\u7684\u521d\u59cb\u6743\u9650\u7684\u3002 \u67e5\u770b\u5f53\u524d\u6743\u9650\u63a9\u7801\uff1a $ umask 0022 \u5728\u4e0d\u8003\u8651 umask \u7684\u60c5\u51b5\u4e0b\uff0c\u6587\u4ef6\u7684\u9ed8\u8ba4\u6743\u9650\u662f 666 (rw-rw-rw-)\uff0c\u76ee\u5f55\u7684\u9ed8\u8ba4\u6743\u9650\u662f 777 (rwxrwxrwx)\u3002 \u5728 umask \u7684\u503c\u4e3a 0022 \u7684\u60c5\u51b5\u4e0b\uff0c\u6587\u4ef6\u7684\u9ed8\u8ba4\u6743\u9650\u662f 644 (rw-r--r--)\uff0c\u76ee\u5f55\u7684\u9ed8\u8ba4\u6743\u9650\u662f 755 (rwxr-xr-x)\u3002 \u8ba1\u7b97\u65b9\u6cd5\uff1a Files: ( Default ) 6 6 6 ( umask ) 0 2 2 ---------------- ( Result ) 6 4 4 Directories: ( Default ) 7 7 7 ( umask ) 0 2 2 ---------------- ( Result ) 7 5 5 \u5982\u679c umask \u7684\u503c\u4e3a 0077 \u7684\u60c5\u51b5\u4e0b\uff0c\u6587\u4ef6\u7684\u9ed8\u8ba4\u6743\u9650\u662f 600 (rw-------)\uff0c\u76ee\u5f55\u7684\u9ed8\u8ba4\u6743\u9650\u662f 700 (rwx------)\u3002 \u8ba1\u7b97\u65b9\u6cd5\uff1a Files: ( Default ) 6 6 6 ( umask ) 0 7 7 ---------------- ( Result ) 6 0 0 Directories: ( Default ) 7 7 7 ( umask ) 0 7 7 ---------------- ( Result ) 7 0 0 \u4e3e\u4f8b\uff1a $ umask 022 $ touch file2 $ ll file2 -rw-r--r--. 1 vagrant wheel 0 Nov 28 23 :13 file2 $ umask 077 $ touch file1 $ ll file1 -rw-------. 1 vagrant wheel 0 Nov 28 23 :12 file1 $ umask 022 $ mkdir ./tmp1 $ umask 077 $ mkdir ./tmp2 $ ls -dl tmp* drwxr-xr-x. 1 vagrant wheel 0 Nov 28 23 :14 tmp1 drwx------. 1 vagrant wheel 0 Nov 28 23 :14 tmp2 7.6.\u7279\u6b8a\u6743\u9650 \u00b6 \u9664\u4e86\u4e09\u79cd\u5e38\u89c1\u7684\u6743\u9650rwx\uff0c\u8fd8\u6709\u4e09\u79cd\u7279\u6b8a\u6743\u9650\uff1aSUID\uff0cSGID\uff0cSticky\u3002 SUID\uff1a\u5c5e\u4e3bs\u6743\u9650\uff0c\u79f0\u4e3aSet UID \u524d\u63d0\uff1a\u8fdb\u7a0b\u6709\u5c5e\u4e3b\u548c\u5c5e\u7ec4\uff0c\u6587\u4ef6\u6709\u5c5e\u4e3b\u548c\u5c5e\u7ec4 \u4efb\u4f55\u53ef\u6267\u884c\u7a0b\u5e8f\u6587\u4ef6\u80fd\u4e0d\u80fd\u542f\u52a8\u4e3a\u8fdb\u7a0b\uff0c\u53d6\u51b3\u4e8e\u53d1\u8d77\u8005\u5bf9\u7a0b\u5e8f\u6587\u4ef6\u662f\u5426\u62e5\u6709\u6267\u884c\u6743\u9650\u3002 \u542f\u52a8\u4e3a\u8fdb\u7a0b\u4e4b\u540e\uff0c\u5176\u8fdb\u7a0b\u7684\u5c5e\u4e3b\u4e3a\u53d1\u8d77\u8005\u3002 \u8fdb\u7a0b\u8bbf\u95ee\u6587\u4ef6\u662f\u7684\u6743\u9650\uff0c\u53d6\u51b3\u4e8e\u8fdb\u7a0b\u7684\u53d1\u8d77\u8005\u3002 \u53ea\u5bf9\u4e8c\u8fdb\u5236\u53ef\u6267\u884c\u7a0b\u5e8f\u6587\u4ef6\u6709\u6548\u3002\u5f53\u6267\u884c\u8be5\u6587\u4ef6\u65f6\uff0c\u53d1\u8d77\u8005\u5c06\u81ea\u52a8\u5177\u6709\u8be5\u6587\u4ef6\u6240\u6709\u8005\u7684\u6743\u9650\u3002 \u5bf9\u76ee\u5f55\u65e0\u6548\u3002 $ ll file1 -rw-------. 1 vagrant wheel 0 Nov 28 23 :12 file1 $ sudo chmod u+s file1 $ ll file1 -rwS------. 1 vagrant wheel 0 Nov 28 23 :12 file1 \u5982\u679c\u5c5e\u4e3b\u7684 x \u4f4d\u4e0a\u662f-\uff0c\u5219\u5728\u5c5e\u4e3b\u7684 x \u4f4d\u4e0a\u6807\u8bb0\u5927\u5199 S \uff0c\u5426\u5219\u6807\u8bb0\u5c0f\u5199 s \u3002\u5982\u4e0b\uff1a $ chmod 777 file1 $ ll file1 -rwxrwxrwx. 1 vagrant wheel 0 Nov 28 23 :12 file1 $ sudo chmod u+s file1 $ ll file1 -rwsrwxrwx. 1 vagrant wheel 0 Nov 28 23 :12 file1 \u4e0b\u97622\u7ec4\u547d\u4ee4\u5b9e\u73b0\u540c\u6837\u6548\u679c\u3002 sudo chmod 4xxx file1 chmod 777 file1 sudo chmod u+s file1 \u53d6\u6d88SUID\u3002 sudo chmod u-s file1 SGID\uff1a\u5c5e\u7ec4s\u6743\u9650\uff0c\u79f0\u4e3aSet GID \u5982\u679c\u4f5c\u7528\u4e8e\u4e8c\u8fdb\u5236\u53ef\u6267\u884c\u6587\u4ef6\u4e0a\uff0c\u5f53\u6267\u884c\u8be5\u6587\u4ef6\u4e3a\u8fdb\u7a0b\u4e4b\u540e\uff0c\u53d1\u8d77\u8005\u5c06\u81ea\u52a8\u5177\u6709\u8be5\u6587\u4ef6\u6240\u5c5e\u7ec4\u7684\u6743\u9650\uff0c\u8fdb\u7a0b\u7684\u5c5e\u7ec4\u4e3a\u53d1\u8d77\u8005\u7684\u5c5e\u7ec4\u3002 \u5982\u679c\u4f5c\u7528\u4e8e\u76ee\u5f55\u4e0a\uff0c\u5219\u8be5\u76ee\u5f55\u4e0b\u65b0\u5efa\u7acb\u7684\u76ee\u5f55\u548c\u6587\u4ef6\u90fd\u81ea\u52a8\u4ece\u6b64\u76ee\u5f55\u7ee7\u627f\u3002 $ sudo chmod g+s file2 $ ll file2 -rw-r-Sr--. 1 vagrant wheel 0 Nov 28 23 :13 file2 \u5982\u679c\u5c5e\u7ec4\u7684 x \u4f4d\u4e0a\u662f-\uff0c\u5219\u5728\u5c5e\u7ec4\u7684 x \u4f4d\u4e0a\u6807\u8bb0\u5927\u5199 S \uff0c\u5426\u5219\u6807\u8bb0\u5c0f\u5199 s \u3002\u5982\u4e0b\uff1a $ chmod 777 file2 $ ll file2 -rwxrwxrwx. 1 vagrant wheel 0 Nov 28 23 :13 file2 $ sudo chmod g+s file2 $ ll file2 -rwxrwsrwx. 1 vagrant wheel 0 Nov 28 23 :13 file2 \u4e0b\u97622\u7ec4\u547d\u4ee4\u5b9e\u73b0\u540c\u6837\u6548\u679c\u3002 sudo chmod 2xxx file2 chmod 777 file2 sudo chmod g+s file2 \u53d6\u6d88SGID\u3002 sudo chmod g-s file2 \u5bf9\u4e8e\u76ee\u5f55\uff0c\u4e0b\u9762\u6f14\u793a\u53ef\u4ee5\u770b\u5230\u76ee\u5f55\u4e0b\u7684\u6587\u4ef6\u548c\u5b50\u76ee\u5f55\u7684\u7ee7\u627f\u6027\u3002 $ ll -d data drwxr-xr-x. 1 vagrant bin 0 Nov 28 20 :55 data $ sudo chmod g+s .~ $ ll -d data drwxr-sr-x. 1 vagrant bin 0 Nov 28 20 :55 data $ cd data $ touch file2 $ ll file2 -rw-r--r--. 1 vagrant bin 0 Nov 29 21 :10 file2 $ mkdir tmp3 $ ll -d tmp3 drwxr-sr-x. 1 vagrant bin 0 Nov 29 21 :10 tmp3 Sticky Bit\uff1a\u7b80\u79f0\u4e3aSBIT\u6743\u9650 \u53ea\u9488\u5bf9\u76ee\u5f55\u6709\u6548\u3002\u5b83\u8868\u793a\u53ea\u80fd\u8ba9\u5176\u5c5e\u4e3b\u4ee5\u53caroot\u53ef\u4ee5\u5220\u9664\u3001\u91cd\u547d\u540d\u3001\u79fb\u52a8\u8be5\u76ee\u5f55\u4e0b\u7684\u6587\u4ef6\u3002 Sticky\u8bbe\u7f6e\u5728\u6587\u4ef6\u4e0a\u65e0\u610f\u4e49\u3002 \u5982\u679c\u5176\u4ed6\u7684 x \u4f4d\u4e0a\u662f-\uff0c\u5219\u5728\u5176\u4ed6\u7684 x \u4f4d\u4e0a\u6807\u8bb0\u5927\u5199 T \uff0c\u5426\u5219\u6807\u8bb0\u5c0f\u5199 t \u3002 $ ll -d .~ drwxr-sr-x. 1 vagrant bin 18 Nov 29 21 :10 .~ $ sudo chmod o+t .~ $ ll -d .~ drwxr-sr-t. 1 vagrant bin 18 Nov 29 21 :10 .~ $ cd data $ touch file1 $ mkdir tmp1 $ ll file1 -rw-r--r--. 1 vagrant bin 0 Nov 29 21 :37 file1 $ ll -d tmp1 drwxr-sr-x. 1 vagrant bin 0 Nov 29 21 :37 tmp1 \u7279\u6b8a\u6743\u9650\u8bbe\u7f6e\u6570\u5b57\u6cd5\uff1a \u8bbe\u7f6eSUID User Group Others r w s r w s r w x r w S BIN 100 1 1 1 1 1 1 1 1 1 1 1 0 OCT 4 7 7 7 6 \u8bbe\u7f6eSGID User Group Others r w x r w s r w x r w S BIN 010 1 1 1 1 1 1 1 1 1 1 1 0 OCT 2 7 7 7 6 \u8bbe\u7f6eSticky Bit - SBIT User Group Others r w x r w x r w t r w T BIN 001 1 1 1 1 1 1 1 1 1 1 1 0 OCT 1 7 7 7 6 7.7.\u8bbe\u5b9a\u6587\u4ef6\u7279\u6b8a\u5c5e\u6027 chattr \u00b6 \u547d\u4ee4\u683c\u5f0f\uff1a chattr [ -RVf ] [ -v version ] [ mode ] files... \u5176\u4e2dmode\u7684\u5b57\u4e32\u683c\u5f0f\uff1a {+|-|=}[aAcCdDeijsStTu] \u5c5e\u6027 i \uff1a \u5982\u679c\u5bf9\u6587\u4ef6\u8bbe\u7f6e i \u5c5e\u6027\uff0c\u90a3\u4e48\u4e0d\u5141\u8bb8\u5bf9\u6587\u4ef6\u8fdb\u884c\u5220\u9664\u3001\u6539\u540d\uff0c\u4e5f\u4e0d\u80fd\u6dfb\u52a0\u548c\u4fee\u6539\u6570\u636e\uff1b \u5982\u679c\u5bf9\u76ee\u5f55\u8bbe\u7f6e i \u5c5e\u6027\uff0c\u90a3\u4e48\u53ea\u80fd\u4fee\u6539\u76ee\u5f55\u4e0b\u6587\u4ef6\u4e2d\u7684\u6570\u636e\uff0c\u4f46\u4e0d\u5141\u8bb8\u5efa\u7acb\u548c\u5220\u9664\u6587\u4ef6\uff1b \u5728openSUSE\u4e0b\u6267\u884c\uff0c\u5206\u533a\u6587\u4ef6\u7c7b\u578b\u662fbtrfs\u683c\u5f0f\u3002 $ touch filetest $ lsattr filetest ---------------------- filetest $ chattr +i filetest chattr: Operation not permitted while setting flags on filetest $ sudo chattr +i filetest $ lsattr filetest ----i----------------- filetest $ rm filetest rm: cannot remove 'filetest' : Operation not permitted $ sudo rm filetest rm: cannot remove 'filetest' : Operation not permitted $ echo \"test\" >> filetest -bash: filetest: Operation not permitted $ sudo echo \"test\" >> filetest -bash: filetest: Operation not permitted $ sudo chattr -i filetest \u5c5e\u6027 a \uff1a \u5982\u679c\u5bf9\u6587\u4ef6\u8bbe\u7f6e a \u5c5e\u6027\uff0c\u90a3\u4e48\u53ea\u80fd\u5728\u6587\u4ef6\u4e2d\u5897\u52a0\u6570\u636e\uff0c\u4f46\u662f\u4e0d\u80fd\u5220\u9664\u548c\u4fee\u6539\u6570\u636e\uff1b \u5982\u679c\u5bf9\u76ee\u5f55\u8bbe\u7f6e a \u5c5e\u6027\uff0c\u90a3\u4e48\u53ea\u5141\u8bb8\u5728\u76ee\u5f55\u4e2d\u5efa\u7acb\u548c\u4fee\u6539\u6587\u4ef6\uff0c\u4f46\u662f\u4e0d\u5141\u8bb8\u5220\u9664\u6587\u4ef6\uff1b \u5728openSUSE\u4e0b\u6267\u884c\uff0c\u5206\u533a\u6587\u4ef6\u7c7b\u578b\u662fbtrfs\u683c\u5f0f\u3002 lsattr filetest ---------------------- filetest $ chattr +a filetest chattr: Operation not permitted while setting flags on filetest $ sudo chattr +a filetest $ echo \"test\" >> filetest $ rm filetest rm: cannot remove 'filetest' : Operation not permitted $ sudo rm filetest rm: cannot remove 'filetest' : Operation not permitted $ sudo chattr -a filetest \u5c5e\u6027 u \uff1a \u8bbe\u7f6e\u6b64\u5c5e\u6027\u7684\u6587\u4ef6\u6216\u76ee\u5f55\uff0c\u5728\u5220\u9664\u65f6\uff0c\u5176\u5185\u5bb9\u4f1a\u88ab\u4fdd\u5b58\uff0c\u4ee5\u4fdd\u8bc1\u540e\u671f\u80fd\u591f\u6062\u590d\uff0c\u5e38\u7528\u6765\u9632\u6b62\u610f\u5916\u5220\u9664\u6587\u4ef6\u6216\u76ee\u5f55\u3002 \u5728Ubuntu\u4e0b\u6267\u884c\uff0c\u5206\u533a\u6587\u4ef6\u7c7b\u578b\u662fext4\u683c\u5f0f\u3002 $ touch filetest $ sudo chattr +u filetest $ lsattr filetest -u------------e------- filetest $ rm filetest \u5c5e\u6027 s \uff1a \u548c u \u76f8\u53cd\uff0c\u5220\u9664\u6587\u4ef6\u6216\u76ee\u5f55\u65f6\uff0c\u4f1a\u88ab\u5f7b\u5e95\u5220\u9664\uff08\u76f4\u63a5\u4ece\u786c\u76d8\u4e0a\u5220\u9664\uff0c\u7136\u540e\u75280\u586b\u5145\u6240\u5360\u7528\u7684\u533a\u57df\uff09\uff0c\u4e0d\u53ef\u6062\u590d\u3002 \u63d0\u793a\uff1a \u547d\u4ee4 chattr \u548c lsattr \u7684\u53ef\u64cd\u4f5c\u5c5e\u6027\u4f9d\u8d56\u4e8e\u6587\u4ef6\u6240\u5904\u5206\u533a\u7684\u6587\u4ef6\u7cfb\u7edf\u7c7b\u578b\uff0c\u4f8b\u5982\uff0cext4\u548cxfs\u7684\u7ed3\u679c\u4f1a\u6709\u4e0d\u540c\u3002 \u5386\u53f2\uff1a\u547d\u4ee4 chattr \uff08\u7528\u4e8e\u64cd\u4f5c\u5c5e\u6027\uff09\u548c lsattr \uff08\u7528\u4e8e\u5217\u51fa\u5c5e\u6027\uff09\u6700\u521d\u4e13\u7528\u4e8e\u7b2c\u4e8c\u4e2a\u6269\u5c55\u6587\u4ef6\u7cfb\u7edf\u7cfb\u5217\uff08ext2\u3001ext3\u3001ext4\uff09\uff0c\u5e76\u4e14\u4f5c\u4e3a e2fsprogs \u5305\u7684\u4e00\u90e8\u5206\u63d0\u4f9b\u3002\u7136\u800c\uff0c\u6b64\u529f\u80fd\u5df2\u5168\u90e8\u6216\u90e8\u5206\u6269\u5c55\u5230\u8bb8\u591a\u5176\u4ed6\u7cfb\u7edf\uff0c\u5305\u62ec XFS\u3001ReiserFS\u3001JFS \u548c OCFS2\u3002 btrfs \u6587\u4ef6\u7cfb\u7edf\u5305\u62ec\u5c5e\u6027\u529f\u80fd\uff0c\u5305\u62ec C \u6807\u5fd7\uff0c\u7531\u4e8e\u4e0e CoW \u76f8\u5173\u7684\u6027\u80fd\u8f83\u6162\uff0c\u5b83\u5173\u95ed\u4e86btrfs\u7684\u5185\u7f6e\u5199\u65f6\u590d\u5236 (CoW) \u529f\u80fd\u3002 8.\u8bbf\u95ee\u63a7\u5236\u5217\u8868ACL \u00b6 8.1.ACL \u00b6 ACL\u7684\u5168\u79f0\u662fAccess Control List\u3002 \u4f20\u7edf\u7684POSIX\u6743\u9650\u6982\u5ff5\u4f7f\u7528\u4e09\u79cd\u7528\u6237\u7c7b\u578b\u6765\u5206\u914d\u6587\u4ef6\u7cfb\u7edf\u4e2d\u7684\u6743\u9650\uff1a\u6240\u6709\u8005Owning Owner\uff0c\u6240\u6709\u8005\u7ec4Owning Group\u548c\u5176\u4ed6\u7528\u6237Other Users\u3002\u53ef\u4ee5\u4e3a\u6bcf\u4e2a\u7528\u6237\u7c7b\u578b\u8bbe\u7f6e\u4e09\u4e2a\u6743\u9650\u4f4d\uff0c\u8d4b\u4e88\u8bfb\uff08r\uff09\uff0c\u5199\uff08w\uff09\u548c\u6267\u884c\uff08x\uff09\u7684\u6743\u9650\u3002 \u6240\u6709\u8005Owning Owner\u6743\u9650\uff08\u5c5e\u4e3b\u6743\u9650\uff09 \u5c5e\u7ec4Owning Group\u6743\u9650 \u5176\u4ed6\uff08\u7ecf\u8fc7\u8eab\u4efd\u9a8c\u8bc1\u7684\uff09\u7528\u6237Other Users\u7684\u6743\u9650 \u4f20\u7edf\u7684\u4e09\u79cd\u6743\u9650\u9002\u7528\u4e8e\u5927\u591a\u6570\u5b9e\u9645\u6848\u4f8b\u3002\u4f46\u662f\uff0c\u5bf9\u4e8e\u66f4\u590d\u6742\u7684\u573a\u666f\u6216\u66f4\u9ad8\u7ea7\u7684\u5e94\u7528\u7a0b\u5e8f\uff0c\u7cfb\u7edf\u7ba1\u7406\u5458\u5fc5\u987b\u4f7f\u7528\u8bb8\u591a\u6280\u5de7\u6765\u89c4\u907f\u4f20\u7edf\u6743\u9650\u7684\u9650\u5236\u3002 \u8bbf\u95ee\u63a7\u5236\u5217\u8868ACL\u63d0\u4f9b\u4e86\u5bf9\u4f20\u7edf\u6587\u4ef6\u6743\u9650\u6982\u5ff5\u7684\u6269\u5c55\u3002\u5b83\u4eec\u5141\u8bb8\u6211\u4eec\u4e3a\u5355\u4e2a\u7528\u6237\u6216\u7ec4\u5206\u914d\u6743\u9650\uff0c\u5373\u4f7f\u8fd9\u4e9b\u7528\u6237\u6216\u7ec4\u4e0e\u539f\u59cb\u6240\u6709\u8005\u6216\u5c5e\u7ec4\u4e0d\u5bf9\u5e94\u3002 ACL\u662fLinux\u5185\u6838\u7684\u4e00\u9879\u529f\u80fd\uff0c\u652f\u6301Ext\u2154/4\uff0cXFS\u548cBtrFS\u6587\u4ef6\u7cfb\u7edf\u4ee5\u53ca\u5176\u4ed6\u6587\u4ef6\u7cfb\u7edf\u3002 \u4f7f\u7528ACL\uff0c\u6211\u4eec\u53ef\u4ee5\u521b\u5efa\u590d\u6742\u7684\u65b9\u6848\uff0c\u800c\u65e0\u9700\u5728\u5e94\u7528\u7a0b\u5e8f\u7ea7\u522b\u4e0a\u53bb\u5b9e\u73b0\u590d\u6742\u7684\u6743\u9650\u6a21\u578b\u3002\u5728\u4f7f\u7528\u63d0\u4f9bSamba\u6587\u4ef6\u548c\u6253\u5370\u670d\u52a1\u7684Linux\u670d\u52a1\u5668\u66ff\u6362Windows\u670d\u52a1\u5668\u7684\u60c5\u51b5\u4e0b\uff0cACL\u7684\u4f18\u52bf\u975e\u5e38\u660e\u663e\u3002\u7531\u4e8eSamba\u652f\u6301ACL\uff0c\u56e0\u6b64\u53ef\u4ee5\u5728Linux\u670d\u52a1\u5668\u548cWindows\u4e2d\u914d\u7f6e\u7528\u6237\u6743\u9650\u3002 \u901a\u8fc7ACL\u6765\u5141\u8bb8\u5bf9\u6240\u6709\u8005\u7528\u6237\u4e4b\u5916\u7684\u5355\u4e2a\u7528\u6237\u8fdb\u884c\u6587\u4ef6\u5199\u6743\u9650\u662f\u4e00\u79cd\u7b80\u5355\u7684\u65b9\u6848\u3002\u4f7f\u7528\u4f20\u7edf\u65b9\u6cd5\uff0c\u6211\u4eec\u5fc5\u987b\u521b\u5efa\u4e00\u4e2a\u65b0\u7ec4\uff0c\u4f7f\u4e24\u4e2a\u7528\u6237\u6210\u4e3a\u8be5\u7ec4\u7684\u6210\u5458\uff0c\u5c06\u8be5\u6587\u4ef6\u7684\u6240\u6709\u7ec4\u66f4\u6539\u4e3a\u65b0\u7ec4\uff0c\u7136\u540e\u6388\u4e88\u8be5\u7ec4\u6587\u4ef6\u7684\u5199\u6743\u9650\u3002\u521b\u5efa\u7ec4\u5e76\u4f7f\u4e24\u4e2a\u7528\u6237\u6210\u4e3a\u8be5\u7ec4\u7684\u6210\u5458\u5219\u9700\u8981\u5229\u7528root\u6743\u9650\u6765\u5b9e\u73b0\u3002 \u4f7f\u7528ACL\uff0c\u6211\u4eec\u53ef\u4ee5\u901a\u8fc7\u4f7f\u6240\u6709\u8005\u548c\u6307\u5b9a\u7528\u6237\u5bf9\u6587\u4ef6\u5177\u6709\u5199\u6743\u9650\u6765\u5b9e\u73b0\u76f8\u540c\u7684\u7ed3\u679c\u3002 \u6b64\u65b9\u6cd5\u7684\u53e6\u4e00\u4e2a\u4f18\u70b9\u662f\u7cfb\u7edf\u7ba1\u7406\u5458\u65e0\u9700\u53c2\u4e0e\u521b\u5efa\u7ec4\u3002\u7528\u6237\u53ef\u4ee5\u81ea\u5df1\u51b3\u5b9a\u6388\u4e88\u8c01\u8bbf\u95ee\u5176\u6587\u4ef6\u7684\u6743\u9650\u3002 \u63d0\u793a\uff1a \u4f7f\u7528ACL\u65f6 ls \u7684\u8f93\u51fa\u7ed3\u679c\u4f1a\u53d1\u751f\u53d8\u5316\u3002\u6dfb\u52a0\u4e00\u4e2a\u52a0\u53f7+ \u6765\u8bf4\u660e\u5df2\u4e3a\u6b64\u6587\u4ef6\u5b9a\u4e49ACL\uff0c\u4e14\u5b9a\u4e49ACL\u540e\uff0c\u6240\u663e\u793a\u7684\u5c5e\u7ec4\u6743\u9650\u662fACL\u63a9\u7801\u7684\u503c\uff0c\u800c\u4e0d\u518d\u662f\u539f\u6765\u5c5e\u7ec4\u7684\u6743\u9650\u3002 8.2.ACL\u7684\u57fa\u672c\u7c7b\u578b \u00b6 Minimal ACLs\uff08\u6700\u5c0fACL\uff09\uff08\u5b9e\u9645\u7528\u9014\uff1a\u4e0ePOSIX\u6743\u9650\u76f8\u540c\uff09 \u4e0e\u6587\u4ef6\u6a21\u5f0f\u6743\u9650\u4f4d\u7b49\u6548\u7684ACL\u79f0\u4e3a\u6700\u5c0fACL \u5206\u4e09\u79cd\u7c7b\u578b\u7684ACL\u6761\u76ee\uff0c\u8fd9\u4e9b\u5bf9\u5e94\u4e8e\u6587\u4ef6\u548c\u76ee\u5f55\u7684\u4f20\u7edf\u6743\u9650\u4f4d Owning User \u6240\u6709\u8005 Owning Group \u6240\u6709\u8005\u7ec4 Others \u5176\u4ed6\u7ec4 Extended ACLs\uff08\u6269\u5c55ACL\uff09 \u5177\u6709\u591a\u4e8e\u4e0a\u8ff0\u4e09\u4e2aACL\u6761\u76ee\u7684ACL\u79f0\u4e3a\u6269\u5c55ACL \u6269\u5c55ACL\u8fd8\u5305\u542b\u63a9\u7801\u6761\u76ee\uff0c\u53ef\u4ee5\u5305\u542b\u4efb\u610f\u6570\u91cf\u7684\u6307\u5b9a\u7528\u6237\u548c\u6307\u5b9a\u7ec4\u6761\u76ee 8.3.ACL\u672f\u8bed \u00b6 \u7528\u6237\u7c7b\uff08User classes\uff09\u3002 \u4f20\u7edf\u7684POSIX\u6743\u9650\u6982\u5ff5\u4f7f\u7528\u4e09\u79cd\u7528\u6237\u7c7b\u6765\u5206\u914d\u6587\u4ef6\u7cfb\u7edf\u4e2d\u7684\u6743\u9650\uff1a\u6240\u6709\u8005Owning Owner\uff0c\u6240\u6709\u8005\u7ec4Owning Group\u548c\u5176\u4ed6\u7528\u6237Other Users\u3002\u53ef\u4ee5\u4e3a\u6bcf\u4e2a\u7528\u6237\u7c7b\u578b\u8bbe\u7f6e\u4e09\u4e2a\u6743\u9650\u4f4d\uff0c\u8d4b\u4e88\u8bfb\uff08r\uff09\uff0c\u5199\uff08w\uff09\u548c\u6267\u884c\uff08x\uff09\u7684\u6743\u9650\u3002 Owner class \u6240\u6709\u8005\u7c7b Group class \u7ec4\u7c7b Other class \u5176\u4ed6\u7c7b ACL\u8bbf\u95ee\u6743\u9650\uff08Access ACL\uff09\uff1a\u786e\u5b9a\u5404\u79cd\u6587\u4ef6\u7cfb\u7edf\u5bf9\u8c61\uff08\u6587\u4ef6\u548c\u76ee\u5f55\uff09\u7684\u7528\u6237\u548c\u7ec4\u7684\u8bbf\u95ee\u6743\u9650\u3002 \u9ed8\u8ba4ACL\uff08Default ACL\uff09\uff1a\u53ea\u80fd\u5e94\u7528\u4e8e\u76ee\u5f55\u3002 \u5b83\u4eec\u786e\u5b9a\u6587\u4ef6\u7cfb\u7edf\u5bf9\u8c61\u5728\u521b\u5efa\u65f6\u4ece\u5176\u7236\u76ee\u5f55\u7ee7\u627f\u7684\u6743\u9650\u3002 ACL\u6761\u76ee\uff08ACL entry\uff09\uff1a \u6bcf\u4e2aACL\u7531\u4e00\u7ec4ACL\u6761\u76ee\u7ec4\u6210\u3002 ACL\u6761\u76ee\u5305\u542b\u7c7b\u578b\uff08type\uff09\uff0c\u6761\u76ee\u5f15\u7528\u7684\u7528\u6237\u6216\u7ec4\u7684\u9650\u5b9a\u7b26\uff08qualifier\uff09\uff0c\u4ee5\u53ca\u4e00\u7ec4\u6743\u9650\uff08permissions\uff09\u3002 \u5bf9\u4e8e\u67d0\u4e9b\u6761\u76ee\u7c7b\u578b\uff0c\u672a\u5b9a\u4e49\u7ec4\u6216\u7528\u6237\u7684\u9650\u5b9a\u7b26\u3002 8.4.ACL\u6743\u9650\u5206\u7c7b \u00b6 Named user \u6307\u5b9a\u7528\u6237: Lets you assign permissions to individual users. \u5141\u8bb8\u6211\u4eec\u4e3a\u6307\u5b9a\u7528\u6237\u5206\u914d\u6743\u9650\u3002 Named group \u6307\u5b9a\u7ec4: Lets you assign permissions to individual groups. \u5141\u8bb8\u6211\u4eec\u4e3a\u5236\u5b9a\u7ec4\u5206\u914d\u6743\u9650\u3002 Mask \u63a9\u7801: Lets you limit the permissions granted to named users or groups. \u5141\u8bb8\u6211\u4eec\u9650\u5236\u7ed9\u4e88\u6307\u5b9a\u7528\u6237\u6216\u6307\u5b9a\u7ec4\u7684\u6743\u9650\u3002 \u6240\u4ee5\u53ef\u80fd\u7684ACL\u7c7b\u578b Type Text Form owner user::rwx named user user:name:rwx owning group group::rwx named group group:name:rwx mask mask::rwx other other::rwx \u4e0ePOSIX.1\u6743\u9650\u6a21\u578b\u4e0d\u540c\uff0c\u7ec4\u7c7bgroup class\u53ef\u4ee5\u5305\u542b\u5177\u6709\u4e0d\u540c\u6743\u9650\u96c6\u7684ACL\u6761\u76ee\uff0c\u56e0\u6b64\u5355\u72ec\u7684\u7ec4\u7c7b\u6743\u9650\u4e0d\u518d\u8db3\u4ee5\u8868\u793a\u5b83\u5305\u542b\u7684\u6240\u6709ACL\u6761\u76ee\u7684\u6240\u6709\u8be6\u7ec6\u6743\u9650\u3002 \u56e0\u6b64\uff0c\u7ec4\u7c7b\u578b\u6743\u9650\u7684\u542b\u4e49\u88ab\u91cd\u65b0\u5b9a\u4e49\u3002\u5728\u65b0\u8bed\u4e49\u4e0b\uff0c\u7ec4\u7c7b\u578b\u6743\u9650\u8868\u793a\u7ec4\u7c7b\u4e2d\u7684\u4efb\u4f55\u6761\u76ee\u5c06\u6388\u4e88\u7684\u6743\u9650\u7684**\u4e0a\u9650**\uff08upper bound\uff09\u3002 \u6b64\u4e0a\u9650\u5c5e\u6027\u53ef\u786e\u4fdd\u5728\u4f7f\u7528ACL\u63a7\u5236\u540e\uff0c\u5e94\u7528\u7a0b\u5e8f\u4e0d\u4f1a\u7a81\u7136\u6216\u8005\u610f\u5916\u5730\u6388\u4e88\u989d\u5916\u7684\u6743\u9650\u3002 \u5728\u6700\u5c0fACL\u4e2d\uff0c\u7ec4\u7c7b\u6743\u9650\u4e0e\u6240\u6709\u8005\u7ec4\u6743\u9650\u76f8\u540c\u3002\u5728\u6269\u5c55ACL\u4e2d\uff0c\u7ec4\u7c7b\u53ef\u4ee5\u5305\u542b\u5176\u4ed6\u7528\u6237\u6216\u7ec4\u7684\u6761\u76ee\u3002\u8fd9\u4f1a\u5bfc\u81f4\u4e00\u4e2a\u95ee\u9898\uff1a\u8fd9\u4e9b\u9644\u52a0\u6761\u76ee\u4e2d\u7684\u4e00\u4e9b\u53ef\u80fd\u62e5\u6709\u672a\u5305\u542b\u5728\u6240\u6709\u8005\u7ec4\u6761\u76ee\uff08owning group entry\uff09\u4e2d\u7684\u6743\u9650\uff0c\u56e0\u6b64\u6240\u6709\u8005\u7ec4\u6761\u76ee\u6743\u9650\u53ef\u80fd\u4e0e\u7ec4\u7c7b\u6743\u9650\uff08group class\uff09\u4e0d\u540c\u3002 \u901a\u8fc7\u63a9\u7801\uff08mask entry\uff09\u89e3\u51b3\u4e86\u8fd9\u4e2a\u95ee\u9898\u3002 \u4f7f\u7528\u6700\u5c0fACL\uff0c\u7ec4\u7c7b\u6743\u9650\u6620\u5c04\u5230\u6240\u6709\u8005\u7ec4\u6761\u76ee\u6743\u9650\u3002With minimal ACLs, the group class permissions map to the owning group entry permissions. \u4f7f\u7528\u6269\u5c55ACL\u65f6\uff0c\u7ec4\u7c7b\u6743\u9650\u6620\u5c04\u5230\u63a9\u7801\u6761\u76ee\u6743\u9650\uff0c\u800c\u6240\u6709\u8005\u7ec4\u6761\u76ee\u4ecd\u5b9a\u4e49\u62e5\u6709\u7ec4\u6743\u9650\u3002With extended ACLs, the group class permissions map to the mask entry permissions, whereas the owning group entry still defines the owning group permissions. 8.5.ACL\u64cd\u4f5c\u547d\u4ee4 \u00b6 \u8bbe\u5b9aACL\u6743\u9650\uff1a setfacl Syntax: setfacl [OPTIONS] [ACL-ENTRIES] Option Description -m : Add or modify an ACL entry -x : Remove an ACL entry -d : Set a default ACL -b : Remove all extended ACL entries -M : restore ACLs that have been written to a file \u6ce8\u610f\uff1a--set\u9009\u9879\u4f1a\u628a\u539f\u6709\u7684ACL\u9879\u90fd\u5220\u9664\uff0c\u7528\u65b0\u7684\u66ff\u4ee3\uff0c\u6240\u4ee5\u4e00\u5b9a\u8981\u5305\u542bUGO\u7684\u8bbe\u7f6e\uff0c\u4e0d\u80fd\u50cf-m\u533b\u9662\u53ea\u6dfb\u52a0ACL\u3002 setfacl --set u::rw,u:vagrant:rw,g::r,o::- file1 \u8bfb\u53d6ACL\u6743\u9650\uff1a getfacl Syntax: getfacl [OPTIONS] Option Description -a : Display the file access control list -d : Display the default access control list -R : List the ACLs of all files and directories recursively 8.6.ACL\u5b9e\u4f8b\u89e3\u6790 \u00b6 8.6.1.\u5b9e\u4f8b\u63cf\u8ff0 \u00b6 \u9879\u76ee\u76ee\u5f55 ~/project1 \u9879\u76ee\u7ecf\u7406 pm1 \u5bf9\u8fd9\u4e2a\u76ee\u5f55\u62e5\u6709\u8bbf\u95ee\u548c\u4fee\u6539\u6743\u9650 \u9879\u76ee\u6210\u5458 tm1 \u53ef\u4ee5\u8bbf\u95ee\u548c\u4fee\u6539\u8fd9\u4e2a\u76ee\u5f55 \u975e\u9879\u76ee\u6210\u5458 tm2 \u4e0d\u80fd\u8bbf\u95ee ~/project1 \u76ee\u5f55\u3002 \u9879\u76ee\u76ee\u5f55 ~/project1 \u7684\u6743\u9650\u89c4\u5212 \u9879\u76ee\u7ecf\u7406 pm1 \u662f\u8fd9\u4e2a\u76ee\u5f55\u7684\u5c5e\u4e3b\uff0c\u6743\u9650\u4e3a rwx \u9879\u76ee\u7ecf\u7406 pm1 \u5c5e\u4e8e project1 \u7ec4 \u9879\u76ee\u6210\u5458 tm1 \u4e0e pm1 \u5728\u540c\u4e00\u4e2a project1 \u7ec4\uff0c\u6743\u9650\u662f rw \u5176\u4ed6\u4eba\u7684\u6743\u9650\u8bbe\u5b9a\u4e3a 0 \u9879\u76ee\u4e34\u65f6\u6210\u5458tm2\u7684\u6743\u9650\u9700\u6c42 \u80fd\u8bbf\u95ee project1 \u76ee\u5f55\uff0c\u4f46\u53ea\u80fd\u5177\u6709 r \u548c x \u6743\u9650 \u89e3\u51b3\u65b9\u6cd5 \u5f53\u51fa\u73b0\u8fd9\u79cd\u60c5\u51b5\u65f6\uff0c\u666e\u901a\u6743\u9650\u4e2d\u7684\u4e09\u79cd\u8eab\u4efd\uff08owner\uff0cgroup\uff0cothers\uff09\u5c31\u4e0d\u80fd\u89e3\u51b3\u8fd9\u4e2a\u95ee\u9898\uff0c\u800cACL\u6743\u9650\u53ef\u4ee5\u3002 \u5728\u4f7f\u7528ACL\u6743\u9650\u7ed9\u7528\u6237 tm2 \u965a\u4e88\u6743\u9650\u65f6\uff0c tm2 \u65e2\u4e0d\u662f ~/project1 \u76ee\u5f55\u7684\u5c5e\u4e3b\uff0c\u4e5f\u4e0d\u662f\u5c5e\u7ec4\uff0c\u4ec5\u4ec5\u8d4b\u4e88\u7528\u6237 tm2 \u9488\u5bf9 ~/project1 \u76ee\u5f55\u7684r-x\u6743\u9650\uff0c \u5c5e\u4e8e\u5355\u72ec\u6307\u5b9a\u7528\u6237\u5e76\u5355\u72ec\u5206\u914d\u6743\u9650\uff0c\u89e3\u51b3\u4e86\u7528\u6237\u8eab\u4efd\u4e0d\u8db3\u7684\u95ee\u9898\u3002 \u62d3\u5c55\u95ee\u9898 \u7ed9 ~/project1 \u76ee\u5f55\u6dfb\u52a0\u5176\u4ed6\u7ec4 project2 \u7684\u8bbf\u95ee\u6743\u9650 \u901a\u8fc7 mask \u6765\u8c03\u6574\u7528\u6237 tm2 \u5b9e\u9645\u6709\u6548\u6743\u9650 \u9ed8\u8ba4ACL\u6743\u9650 \u9012\u5f52ACL\u6743\u9650 \u5220\u9664ACL\u6743\u9650 8.6.2.\u521d\u59cb\u5316\u73af\u5883 \u00b6 \u521b\u5efa\u6d4b\u8bd5\u7528\u6237 $ whoami vagrant $ sudo groupadd project1 $ sudo groupadd project2 $ sudo useradd -m -g project1 pm1 $ sudo useradd -m -g project1 tm1 $ sudo useradd -m -g project2 tm2 $ sudo passwd pm1 $ sudo passwd tm1 $ sudo passwd tm2 $ cat /etc/group ...... project1:x:1535: project2:x:1536: ...... $ cat /etc/passwd ...... pm1:x:2003:1535::/home/pm1:/bin/bash tm1:x:2004:1535::/home/tm1:/bin/bash tm2:x:2005:1536::/home/tm2:/bin/bash ...... \u521b\u5efa\u6d4b\u8bd5\u76ee\u5f55 project1 , \u6307\u5b9a project1 \u76ee\u5f55\u7684\u6743\u9650\uff0c\u521b\u5efa\u6d4b\u8bd5\u6587\u4ef6 file1 \u3002 $ su - pm1 $ cd ~ $ mkdir project1 $ ls -dl project1 drwxr-xr-x. 1 pm1 project1 0 Dec 4 06 :25 project1 $ chmod 770 project1/ $ ls -dl project1 drwxrwx---. 1 pm1 project1 0 Dec 4 06 :25 project1 $ echo \"hello from $USER \" > ./project1/file1 $ cat ./project1/file1 hello from pm1 \u76ee\u5f55 project1 \u5f53\u524d\u6743\u9650\u5feb\u7167 \u5c5e\u4e3b\uff1a pm1 \uff0c\u5bf9 ~/project1 \u76ee\u5f55\u6709 rwx \u6743\u9650 \u5c5e\u7ec4\uff1a project1 \uff0c\u5305\u542b\u7528\u6237 pm1 \u548c tm1 \uff0c\u5bf9 ~/project1 \u76ee\u5f55\u6709 rwx \u6743\u9650 \u5176\u4ed6\u7ec4\uff1a\u6ca1\u6709\u8bbf\u95ee\u6743\u9650 \u76ee\u5f55 ~/project1 \u5f53\u524d\u7684ACL\u5feb\u7167 $ getfacl ./project1/ # file: home/pm1/project1/ # owner: pm1 # group: project1 user::rwx group::rwx other::--- 8.6.3.\u6dfb\u52a0ACL\u6743\u9650 \u00b6 \u7ed9 ~/project1 \u76ee\u5f55\u6dfb\u52a0\u65b0\u7528\u6237 tm2 \uff0c\u6743\u9650\u4e3a rwx \u3002\u76ee\u5f55 ~/project1 \u7684\u66f4\u65b0\u540e\u7684\u6743\u9650\u4f4d\u53d8\u6210\u4e86 drwxrwx---+ \u3002 $ su - pm1 $ setfacl -m u:tm2:rx ./project1/ $ ls -dl ./project1 drwxrwx---+ 1 pm1 project1 0 Dec 4 06 :25 project1 $ getfacl ~/project1/ # file: project1 \uff08\u6587\u4ef6\u540d\uff09 # owner: pm1 \uff08Owner \u6587\u4ef6\u5c5e\u4e3b\uff09 # group: project1 \uff08Owing Group \u6587\u4ef6\u5c5e\u7ec4\uff09 user::rwx \uff08Ower\u6587\u4ef6\u5c5e\u4e3b\u7684\u6743\u9650\uff0c\u7528\u6237\u540d\u680f\u662f\u7a7a\u7684\uff0c\u8bf4\u660e\u662f\u5c5e\u4e3bOwner\u7684\u6743\u9650\uff09 user:tm2:r-x \uff08Named User \u6307\u5b9a\u7528\u6237\u7684\u6743\u9650\uff0c\u7528\u6237tm2\u7684\u6743\u9650\uff09 group::rwx \uff08Owing Group \u6587\u4ef6\u5c5e\u7ec4\u7684\u6743\u9650\uff0c\u7ec4\u540d\u680f\u662f\u7a7a\u7684\uff0c\u8bf4\u660e\u662f\u5c5e\u7ec4\u7684\u6743\u9650\uff09 \uff08Named Group \u6307\u5b9a\u7528\u6237\u7ec4\u7684\u6743\u9650\uff0c\u6b64\u65f6\u672a\u6307\u5b9a\uff09 mask::rwx \uff08mask\u6743\u9650\uff09 other::--- \uff08\u5176\u4ed6\u4ebaother\u7684\u6743\u9650\uff09 \u7ed9 ~/project1 \u76ee\u5f55\u6dfb\u52a0\u65b0\u7ec4 project2 \u7684\u6743\u9650 rwx $ su - pm1 $ setfacl -m g:project2:rwx ./project1/ $ ls -dl ./project1 drwxrwx---+ 1 pm1 project1 0 Dec 4 06 :46 ./project1 $ getfacl ./project1 # file: project1 # owner: pm1 # group: project1 user::rwx user:tm2:r-x ( \u7528\u6237tm2\u62e5\u6709\u4e86r-x\u6743\u9650\uff09 group::rwx group:project2:rwx ( \u7528\u6237\u7ec4project2\u62e5\u6709\u4e86rwx\u6743\u9650\uff09 mask::rwx other::--- \u6709\u6548\u6743\u9650\u7684\u8ba1\u7b97\uff1a \u5f53\u524d ~/project1 \u76ee\u5f55\u7684 mask \u662f rwx \uff0c tm2 \u7684\u6743\u9650\u662f r-x \uff0c\u4e8c\u8005\u8fdb\u884cAND\u64cd\u4f5c\uff0c tm2 \u7684\u5b9e\u9645\u6743\u9650\u662f r-x tm2: r - x ( 1 0 1 ) mask: r w x ( 1 1 1 ) --------------------- result: r - x ( 1 0 1 ) \u5bf9\u7167\u4e0b\u9762\u7684\u89c4\u5219\uff0c\u9a8c\u8bc1\u7528\u6237 tm2 \u5bf9 ~/project1 \u76ee\u5f55\u7684\u5b9e\u9645\u6743\u9650\u3002 su - tm2 \u80fd\u8fdb\u5165\u76ee\u5f55 project1 \uff0c\u8bf4\u660e\u5f53\u524d\u7528\u6237\u5177\u6709\u76ee\u5f55 project1 \u7684 r-x \u6743\u9650\u3002 $ whoami tm2 $ cd /home/pm1/project1/ \u80fd\u5217\u51fa\u76ee\u5f55 project1 \u4e0b\u6587\u4ef6\u5217\u8868\uff0c\u53ef\u4ee5\u67e5\u770b\u6587\u4ef6 file \u7684\u5185\u5bb9\uff0c\u8bf4\u660e\u5f53\u524d\u7528\u6237\u5177\u6709\u76ee\u5f55 project1 \u7684 r-x \u6743\u9650\u3002 $ pwd /home/pm1/project1 $ whoami tm2 $ ls -l -rw-r--r--. 1 pm1 project1 15 Dec 4 07 :15 file1 $ cat file1 hello from pm1 \u5bf9\u76ee\u5f55 project1 \u4e0d\u5177\u6709 w \u6743\u9650\uff0c\u6240\u4ee5\u65e0\u6cd5\u521b\u5efa\u3001\u5220\u9664\u6216\u4fee\u6539\u76ee\u5f55\u4e0b\u7684\u4efb\u4f55\u6587\u4ef6\u6216\u5b50\u76ee\u5f55\u3002 $ pwd /home/pm1/project1 $ whoami tm2 $ touch file2 touch: cannot touch 'file2' : Permission denied $ echo \"hello from $USER \" >> file1 -bash: file1: Permission denied 8.6.4.\u4fee\u6539mask\u6743\u9650 \u00b6 \u8c03\u6574 ~/project1 \u76ee\u5f55\u7684 mask \u4e3a r-- \uff0c\u5219 tm2 \u7684\u5b9e\u9645\u6743\u9650\u662f r-- $ su - pm1 $ cd ~ $ setfacl -m m::r ./project1/ $ getfacl ./project1/ # file: project1/ # owner: pm1 # group: project1 user::rwx user:tm2:r-x #effective:r-- (\u7528\u6237tm2\u7684\u5b9e\u9645\u6709\u6548\u6743\u9650\u53d8\u4e3ar--) group::rwx #effective:r-- (\u5c5e\u7ec4project1\u7ec4\u7684\u5b9e\u9645\u6709\u6548\u6743\u9650\u53d8\u4e3ar--) group:project2:rwx #effective:r-- (\u5176\u4ed6\u7ec4project2\u7ec4\u7684\u5b9e\u9645\u6709\u6548\u6743\u9650\u53d8\u4e3ar--) mask::r-- ( mask\u53d8\u5316\uff0c\u5bfc\u81f4\u4e0a\u8ff0\u4e24\u4e2agroup\u7684\u6709\u6548\u6743\u9650\u90fd\u53d1\u751f\u4e86\u53d8\u5316 ) other::--- \u6709\u6548\u6743\u9650\u7684\u8ba1\u7b97\uff1a \u5f53\u524d ~/project1 \u76ee\u5f55\u7684 mask \u662f r-- \uff0c\u7528\u6237 tm2 \u3001\u7ec4 project2 \u7684\u5b9e\u9645\u6743\u9650\u662f r-- \u3002 tm2: r - w ( 1 0 1 ) mask: r - - ( 1 0 0 ) --------------------- result: r - - ( 1 0 0 ) \u63d0\u793a\uff1a \u7528\u6237\u548c\u7528\u6237\u7ec4\u6240\u8bbe\u5b9a\u7684\u6743\u9650\u5fc5\u987b\u5728mask\u6743\u9650\u8bbe\u5b9a\u7684\u8303\u56f4\u4e4b\u5185\u624d\u80fd\u751f\u6548\uff0cmask\u6743\u9650\u5c31\u662f\u6700\u5927\u6709\u6548\u6743\u9650\u3002 8.6.5.\u6709\u6548\u6743\u9650\u5206\u6790 \u00b6 \u5728POSIX\u6743\u9650\u6a21\u578b\u548cACL\u6743\u9650\u53e0\u52a0\u4f5c\u7528\u4e0b\uff0c\u7528\u6237\u7684\u5b9e\u9645\u6743\u9650\u5206\u6790\u3002 $ getfacl ./project1/ # file: project1/ # owner: pm1 <----Owner # group: project1 <----owning group user::rwx <----owner 's permissions user:tm2:r-x #effective:r-- <----named user' s permissions group::rwx #effective:r-- <----owning group's permissions group:project2:rwx #effective:r-- <----named group's permissions mask::r-- <----masks for named user and named group other::--- default:user::rwx default:user:tm2:r-x default:group::rwx default:mask::rwx default:other::--- \u6240\u6709\u8005ower\u548c\u5176\u4ed6\u7528\u6237other\u6761\u76ee\u4e2d\u5b9a\u4e49\u7684\u6743\u9650\u603b\u662f\u6709\u6548\u7684\u3002\u4e0a\u4f8b\u4e2d\u7684user\u6761\u76ee\u548cother\u6761\u76ee\u3002 \u9664\u4e86\u63a9\u7801\u6761\u76ee\uff0c\u6240\u6709\u5176\u4ed6\u6761\u76ee\uff08\u6bd4\u5982\u6307\u5b9a\u7528\u6237named user\uff09\u53ef\u4ee5\u662f\u6709\u6548\u7684\u6216\u88ab\u5c4f\u853d\u7684\u3002 \u6307\u5b9a\u7528\u6237\uff08named user\uff09\uff0c\u6240\u6709\u8005\u7ec4\uff08owning group\uff09\u6216\u6307\u5b9a\u7ec4\uff08named group\uff09\u4ee5\u53ca\u63a9\u7801mask\u6761\u76ee\u4e2d\u5b9a\u4e49\u7684\u6743\u9650\uff0c\u6709\u6548\u6743\u9650\u662f\u4ed6\u4eec\u6743\u9650\u8fdb\u884c\u903b\u8f91AND\u540e\u7684\u7ed3\u679c\uff0c\u800c\u4e0d\u662f\u5355\u72ec\u7684\u63a9\u7801\u4e2d\u5b9a\u4e49\u7684\u6743\u9650\u6216\u8005\u5404\u81ea\u6761\u76ee\u4e2d\u5b9a\u4e49\u7684\u6743\u3002 \u6709\u6548\u6743\u9650\u8ba1\u7b97\u65b9\u6cd5\u5982\u4e0b\uff0c\u6ce8\u610f\uff0c ls \u547d\u4ee4\u4e2d\u663e\u793a\u51fa\u6765\u7684\u6743\u9650\uff0c\u4e0e\u5b9e\u9645\u7684ACL\u6743\u9650\u662f\u6709\u5dee\u522b\u7684\u3002 tm2: r - w ( 1 0 1 ) group: r w x ( 1 1 1 ) named group: r w x ( 1 1 1 ) mask: r - - ( 1 0 0 ) --------------------------- result: r - - ( 1 0 0 ) \u5c0f\u8d34\u58eb\uff1a \u4e0e\u6587\u4ef6\u6a21\u5f0f\u6743\u9650\u4f4d\u7b49\u6548\u7684ACL\u79f0\u4e3a\u6700\u5c0fACL\uff0c\u5373POSIX\u4f20\u7edf\u6743\u9650\u3002 \u542b\u63a9\u7801mask\u7b49\u5176\u4ed6\u6743\u9650\u6761\u76ee\u7684ACL\u79f0\u4e3a\u6269\u5c55ACL\u3002 \u5728\u6700\u5c0f\u548c\u6269\u5c55ACL\u60c5\u5f62\u4e0b\uff0c\u6240\u6709\u8005\u7c7b\u6743\u9650\uff08owner\uff09\u90fd\u662f\u6620\u5c04\u5230ACL\u7684\u6240\u6709\u8005\u6761\u76ee\u3002 \u5176\u4ed6\u7c7b\u6743\u9650\u6620\u5c04\u5230\u5176\u5404\u81ea\u7684ACL\u6761\u76ee\u3002 \u5728\u6269\u5c55ACL\u60c5\u5f62\u4e0b\uff0c\u7ec4\u7c7b\u6743\u9650\u7684\u6620\u5c04\u662f\u4e0d\u540c\u7684\u3002 \u5bf9\u4e8e\u6ca1\u6709\u63a9\u7801\u7684\u6700\u5c0fACL\uff0c\u7ec4\u7c7b\u6743\u9650\u5c06\u6620\u5c04\u5230ACL\u6240\u6709\u8005\u7ec4\u6761\u76ee\u3002 \u5bf9\u4e8e\u5e26\u6709\u63a9\u7801\u7684\u6269\u5c55ACL\uff0c\u7ec4\u7c7b\u6743\u9650\u5c06\u6620\u5c04\u5230\u63a9\u7801\u6761\u76ee\u3002 \u901a\u8fc7\u6743\u9650\u4f4d\u8fdb\u884c\u5206\u914d\u7684\u6743\u9650\u4ee3\u8868\u4e86\u901a\u8fc7ACL\u8fdb\u884c\u5206\u914d\u7684\u6743\u9650\u7684\u4e0a\u9650\u3002 \u6ca1\u6709\u5728\u8fd9\u91cc\u4f53\u73b0\u7684\u4efb\u4f55\u6743\u9650\uff0c\u8981\u4e48\u4e0d\u5728ACL\u4e2d\uff0c\u8981\u4e48\u65e0\u6548\u3002 \u5bf9\u6743\u9650\u4f4d\u6240\u505a\u7684\u66f4\u6539\u5c06\u7531ACL\u53cd\u6620\uff0c\u53cd\u4e4b\u4ea6\u7136\u3002 8.6.6.\u9ed8\u8ba4ACL\u6743\u9650 \u00b6 $ su - pm1 $ touch ./project1/file2 $ mkdir ./project1/cloud $ ll ./project1/ drwxr-xr-x. 1 pm1 project1 0 Dec 4 08 :52 cloud -rw-r--r--. 1 pm1 project1 15 Dec 4 07 :15 file1 -rw-r--r--. 1 pm1 project1 0 Dec 4 08 :52 file2 $ ll -d project1/ drwxr-----+ 1 pm1 project1 30 Dec 4 08 :52 project1/ \u6587\u4ef6 file1 \u548c\u76ee\u5f55 cloud \u6ca1\u6709\u7ee7\u627f project1 \u76ee\u5f55\u7684ACL\u6743\u9650\u3002 \u63d0\u793a\uff1a \u9ed8\u8ba4 ACL\u9650\u53ea\u5bf9\u76ee\u5f55\u751f\u6548\u3002 \u9ed8\u8ba4ACL\u6743\u9650\u7684\u4f5c\u7528\u662f\uff1a\u5982\u679c\u7ed9\u7236\u76ee\u5f55\u8bbe\u5b9a\u4e86\u9ed8\u8ba4 ACL \u6743\u9650\uff0c\u90a3\u4e48\u7236\u76ee\u5f55\u4e2d\u6240\u6709\u65b0\u5efa\u7684\u5b50\u6587\u4ef6\u90fd\u4f1a\u7ee7\u627f\u7236\u76ee\u5f55\u7684ACL\u6743\u9650\u3002 \u4e0b\u9762\u589e\u52a0 ~/project1 \u76ee\u5f55\u7684\u9ed8\u8ba4ACL\u6743\u9650\u3002 $ su - pm1 $ cd ~ $ getfacl ./project1/ # file: project1/ # owner: pm1 # group: project1 user::rwx user:tm2:r-x #effective:r-- group::rwx #effective:r-- group:project2:rwx #effective:r-- mask::r-- other::--- $ setfacl -m d:u:tm2:rx ./project1/ $ getfacl ./project1/ # file: project1/ # owner: pm1 # group: project1 user::rwx user:tm2:r-x #effective:r-- group::rwx #effective:r-- group:project2:rwx #effective:r-- mask::r-- other::--- default:user::rwx default:user:tm2:r-x default:group::rwx default:mask::rwx default:other::--- \u521b\u5efa\u65b0\u5b50\u76ee\u5f55 leonardo \uff0c\u5c31\u7ee7\u627f\u4e86 ~/project1 \u76ee\u5f55\u7684default ACL\u6743\u9650\u8bbe\u5b9a\u3002 \u6ce8\u610f\uff0c\u9ed8\u8ba4ACL\u6743\u9650\u662f\u9488\u5bf9\u65b0\u5efa\u7acb\u7684\u6587\u4ef6\u751f\u6548\u7684\uff0c\u76ee\u5f55cloud\u548c\u6587\u4ef6file1\u5e76\u6ca1\u6709\u56e0\u4e3a\u589e\u52a0\u4e86\u7236\u76ee\u5f55\u7684\u9ed8\u8ba4ACL\u8bbe\u5b9a\u800c\u7ee7\u627f\u9ed8\u8ba4ACL\u6743\u9650\u8bbe\u5b9a. $ su - pm1 $ cd ~ $ mkdir ./project1/leonardo $ ll ./project1/ drwxr-xr-x. 1 pm1 project1 0 Dec 4 08 :52 cloud -rw-r--r--. 1 pm1 project1 15 Dec 4 07 :15 file1 -rw-r--r--. 1 pm1 project1 0 Dec 4 08 :52 file2 drwxrwx---+ 1 pm1 project1 0 Dec 4 09 :07 leonardo 8.6.7.\u9012\u5f52ACL\u6743\u9650 \u00b6 \u9012\u5f52 ACL \u6743\u9650\uff0c\u662f\u6307\u7236\u76ee\u5f55\u5728\u8bbe\u5b9aACL\u6743\u9650\u65f6\uff0c\u6240\u6709\u7684\u5b50\u76ee\u5f55\u4e5f\u4f1a\u62e5\u6709\u76f8\u540c\u7684ACL\u6743\u9650\u3002 $ su - pm1 $ cd ~ $ getfacl ./project1/ # file: project1/ # owner: pm1 # group: project1 user::rwx user:tm2:r-x #effective:r-- group::rwx #effective:r-- group:project2:rwx #effective:r-- mask::r-- other::--- default:user::rwx default:user:tm2:r-x default:group::rwx default:mask::rwx default:other::--- $ setfacl -m d:u:tm2:rx -R ./project1/ $ ll ./project1 drwxr-xr-x+ 1 pm1 project1 0 Dec 4 08 :52 cloud -rw-r--r--. 1 pm1 project1 15 Dec 4 07 :15 file1 -rw-r--r--. 1 pm1 project1 0 Dec 4 08 :52 file2 drwxrwx---+ 1 pm1 project1 0 Dec 4 09 :07 leonardo 8.6.8.\u5220\u9664ACL\u6743\u9650 \u00b6 \u5220\u9664\u7528\u6237 tm2 \u7684ACL\u6743\u9650\u3002 $ su - pm1 $ cd ~ $ setfacl -x u:tm2 ./project1/ $ getfacl ./project1/ # file: project1/ # owner: pm1 # group: project1 user::rwx group::rwx group:project2:rwx mask::rwx other::--- default:user::rwx default:user:tm2:r-x default:group::rwx default:mask::rwx default:other::--- \u5220\u9664\u6240\u6709\u7684ACL\u6743\u9650\u3002 $ setfacl -b ./project1 $ getfacl ./project1 # file: project1/ # owner: pm1 # group: project1 user::rwx group::rwx other::--- $ ll ./project1 drwxr-xr-x+ 1 pm1 project1 0 Dec 4 08 :52 cloud -rw-r--r--. 1 pm1 project1 15 Dec 4 07 :15 file1 -rw-r--r--. 1 pm1 project1 0 Dec 4 08 :52 file2 drwxrwx---+ 1 pm1 project1 0 Dec 4 09 :07 leonardo \u9012\u5f52\u5220\u9664\u5168\u90e8ACL\u6743\u9650\u3002 $ setfacl -b -R ./project1 $ ll ./project1/ total 4 drwxr-xr-x. 1 pm1 project1 0 Dec 4 08 :52 cloud -rw-r--r--. 1 pm1 project1 15 Dec 4 07 :15 file1 -rw-r--r--. 1 pm1 project1 0 Dec 4 08 :52 file2 drwxrwx---. 1 pm1 project1 0 Dec 4 09 :07 leonardo 8.7.ACL\u76ee\u5f55\u5b9e\u4f8b\u89e3\u6790 \u00b6 8.7.1.\u76ee\u5f55ACL \u00b6 \u5207\u6362\u5230pm1\u7528\u6237\uff0c\u5728\u5176\u4e3b\u76ee\u5f55\u4e2d\uff0c\u57fa\u4e8e\u4e0d\u540c\u7684\u63a9\u7801\u521b\u5efa2\u4e2a\u5b50\u76ee\u5f55\u3002 $ su - pm1 $ umask 0022 $ mkdir mydir1 $ umask 0027 $ mkdir mydir2 $ ll -d mydir* drwxr-xr-x. 1 pm1 project1 0 Dec 4 12 :30 mydir1 drwxr-x---. 1 pm1 project1 0 Dec 4 12 :31 mydir2 \u8fd92\u4e2a\u76ee\u5f55\u5f53\u524d\u7684ACL\u72b6\u6001\u5982\u4e0b\uff1a $ getfacl mydir1 # file: mydir1 # owner: pm1 # group: project1 user::rwx group::r-x other::r-x $ getfacl mydir2 # file: mydir2 # owner: pm1 # group: project1 user::rwx group::r-x other::--- \u4fee\u6539\u76ee\u5f55 mydir2 \u7684ACL\u3002 $ setfacl -m u:tm2:rwx,g:project2:rwx mydir2 $ getfacl mydir2 getfacl mydir2 # file: mydir2 # owner: pm1 # group: project1 user::rwx user:tm2:rwx group::r-x group:project2:rwx mask::rwx other::--- $ ll -d mydir2 drwxrwx---+ 1 pm1 project1 0 Dec 4 12 :31 mydir2 \u73b0\u5728\uff0c\u7528\u6237 tm2 \u548c\u7ec4 project2 \u5bf9\u76ee\u5f55 mydir2 \u90fd\u5177\u6709rwx\u6743\u9650\uff0c\u4f20\u7edfPOSIX\u6743\u9650\u548cACL\u6743\u9650\u4e00\u81f4\u3002 \u73b0\u5728\u5bf9mydir2\u76ee\u5f55\u7ec4\u6743\u9650\u64a4\u9500w\u6743\u9650\u3002 \u7528\u6237 tm2 \u548c\u7ec4 project2 \u5bf9\u76ee\u5f55 mydir2 \u7684\u6709\u6548\u6743\u9650\u53d8\u6210\u4e86 r-x \u3002 mask\u4e5f\u53d7\u7ec4\u6743\u9650\u53d8\u5316\u5f71\u54cd\uff0c\u53d8\u6210\u4e86 r-x \u3002 $ chmod g-w mydir2 $ ll -d mydir2 drwxr-x---+ 1 pm1 project1 0 Dec 4 12 :31 mydir2 $ getfacl mydir2 # file: mydir2 # owner: pm1 # group: project1 user::rwx user:tm2:rwx #effective:r-x group::r-x group:project2:rwx #effective:r-x mask::r-x other::--- \u901a\u8fc7 chmod \u548c setfacl \u4e24\u79cd\u4e0d\u540c\u7684\u65b9\u6cd5\u5bf9\u76ee\u5f55 mydir2 \u7684\u7ec4\u6743\u9650\u8fdb\u884c\u4fee\u6539\uff0c\u5728ls\u547d\u4ee4\u4e2d\u4f53\u73b0\u662f\u4e00\u6837\u7684\uff0c\u5bf9\u7ec4\u7684\u5b9e\u9645\u6709\u6548\u6743\u9650\u7684\u5f71\u54cd\u4e5f\u662f\u4e00\u6837\u7684\u3002 chmod \u4fee\u6539\u7684\u662f mask \uff0c mask \u53ea\u5f71\u54cd\u9664\u6240\u6709\u8005\u548cother\u7684\u4e4b\u5916\u7684\u4eba\u548c\u7ec4\u7684\u6700\u5927\u6743\u9650\uff0c mask \u9700\u8981\u4e0e\u7528\u6237\u7684\u6743\u9650\u8fdb\u884c\u903b\u8f91\u4e0e\u8fd0\u7b97\u540e\uff0c\u624d\u80fd\u53d8\u6210\u6709\u6548\u6743\u9650\uff0c\u7528\u6237\u6216\u7ec4\u7684\u8bbe\u7f6e\u5fc5\u987b\u5728mask\u6743\u9650\u8bbe\u5b9a\u8303\u56f4\u5185\u624d\u4f1a\u751f\u6548\u3002 setfacl \u53ef\u4ee5\u4e0d\u4fee\u6539mask\u7684\u60c5\u51b5\u4e0b\u53ea\u4fee\u6539 owning group \u7684\u6743\u9650\uff0c\u4e0b\u9762\u7684\u4f8b\u5b50\u8bf4\u660e\u4e86\u8fd9\u4e00\u60c5\u51b5\u3002POSIX\u7ec4\u6743\u9650\u4ecd\u7136\u662f rwx \uff0c\u4f46ACL\u4e2d\u6240\u6709\u8005\u7ec4\u7684\u6743\u9650\u53d8\u6210\u4e86 r-- \u3002 $ setfacl -m g::r mydir2 $ ll -d mydir2 drwxrwx---+ 1 pm1 project1 0 Dec 4 12 :31 mydir2 $ getfacl mydir2 # file: mydir2 # owner: pm1 # group: project1 user::rwx user:tm2:rwx group::r-- group:project2:rwx mask::rwx other::--- 8.7.2.\u76ee\u5f55\u7684\u9ed8\u8ba4ACL \u00b6 \u76ee\u5f55\u53ef\u4ee5\u5177\u6709\u9ed8\u8ba4ACL\uff0c\u8fd9\u662f\u4e00\u79cd\u7279\u6b8a\u7684ACL\uff0c\u7528\u4e8e\u5b9a\u4e49\u76ee\u5f55\u4e0b\u7684\u5bf9\u8c61\u5728\u521b\u5efa\u65f6\u7ee7\u627f\u7684\u8bbf\u95ee\u6743\u9650\u3002\u9ed8\u8ba4ACL\u4f1a\u5f71\u54cd\u5b50\u76ee\u5f55\u548c\u6587\u4ef6\u3002 \u76ee\u5f55\u7684\u9ed8\u8ba4ACL\u7684\u6743\u9650\u6709\u4e24\u79cd\u4e0d\u540c\u7684\u65b9\u5f0f\u4f20\u9012\u7ed9\u5176\u4e2d\u7684\u6587\u4ef6\u548c\u5b50\u76ee\u5f55\uff1a \u5b50\u76ee\u5f55\u7ee7\u627f\u7236\u76ee\u5f55\u7684\u9ed8\u8ba4ACL\uff0c\u65e2\u4f5c\u4e3a\u81ea\u5df1\u7684\u9ed8\u8ba4ACL\uff0c\u53c8\u4f5c\u4e3a\u81ea\u5df1\u7684\u8bbf\u95eeACL\u3002 \u6587\u4ef6\u7ee7\u627f\u76ee\u5f55\u9ed8\u8ba4ACL\u4f5c\u4e3a\u5176\u81ea\u5df1\u7684\u8bbf\u95eeACL\u3002 \u521b\u5efa\u6587\u4ef6\u7cfb\u7edf\u5bf9\u8c61\u7684\u6240\u6709\u7cfb\u7edf\u51fd\u6570\u90fd\u4f7f\u7528mode\u53c2\u6570\uff0c\u8be5\u53c2\u6570\u5b9a\u4e49\u4e86\u65b0\u521b\u5efa\u7684\u6587\u4ef6\u7cfb\u7edf\u5bf9\u8c61\u7684\u8bbf\u95ee\u6743\u9650\u3002 \u5982\u679c\u7236\u76ee\u5f55\u6ca1\u6709\u9ed8\u8ba4ACL\uff0c\u5219\u6839\u636eumask\u7684\u8bbe\u7f6e\u8bbe\u7f6e\u6743\u9650\u4f4d\u3002 \u5982\u679c\u7236\u76ee\u5f55\u5b58\u5728\u9ed8\u8ba4ACL\uff0c\u5219\u5206\u914d\u7ed9\u65b0\u5bf9\u8c61\u7684\u6743\u9650\u4f4d\u5219\u662fmode\u53c2\u6570\u6743\u9650\u4e0e\u9ed8\u8ba4ACL\u4e2d\u5b9a\u4e49\u7684\u6743\u9650\u7684\u903b\u8f91\u4e0e\u7684\u7ed3\u679c\u3002\u5728\u8fd9\u79cd\u60c5\u51b5\u4e0b\uff0c\u5ffd\u7565umask\u547d\u4ee4\u3002 \u9ed8\u8ba4ACL\u4e0d\u4f1a\u7acb\u5373\u5f71\u54cd\u8bbf\u95ee\u6743\u9650\u3002\u5b83\u4eec\u4ec5\u5728\u521b\u5efa\u6587\u4ef6\u7cfb\u7edf\u5bf9\u8c61\u65f6\u624d\u8d77\u4f5c\u7528\u3002\u8fd9\u4e9b\u65b0\u5bf9\u8c61\u4ec5\u4ece\u5176\u7236\u76ee\u5f55\u7684\u9ed8\u8ba4ACL\u7ee7\u627f\u6743\u9650\u3002 \u547d\u4ee4 mkdir \u5728\u521b\u5efa\u76ee\u5f55\u65f6\u4f1a\u7ee7\u627f\u9ed8\u8ba4ACL\u3002 $ su - pm1 $ getfacl mydir2 # file: mydir2 # owner: pm1 # group: project1 user::rwx user:tm2:rwx group::r-- group:project2:rwx mask::rwx other::--- $ mkdir ./mydir2/sub1 $ ll ./mydir2 drwxr-x---. 1 pm1 project1 0 Dec 4 13 :23 sub1 $ setfacl -d -m g:project2:-w- mydir2 $ mkdir ./mydir2/sub2 $ ll ./mydir2 drwxr-x---. 1 pm1 project1 0 Dec 4 13 :23 sub1 drwxrw----+ 1 pm1 project1 0 Dec 4 13 :27 sub2 $ getfacl ./mydir2/sub2 # file: mydir2/sub2 # owner: pm1 # group: project1 user::rwx group::r-- group:project2:-w- mask::rw- other::--- default:user::rwx default:group::r-- default:group:project2:-w- default:mask::rw- default:other::--- \u5728\u5bf9 mydir2 \u76ee\u5f55\u6dfb\u52a0\u9ed8\u8ba4ACL\u524d\uff0c\u521b\u5efa\u5b50\u76ee\u5f55 sub1 \uff0c\u6dfb\u52a0\u540e\u521b\u5efa\u5b50\u76ee\u5f55 sub2 \u3002\u53ef\u4ee5\u89c2\u5bdf\u5230 sub2 \u5230\u7ee7\u627f\u4e86 mydir2 \u7684\u9ed8\u8ba4ACL\u3002 $ su - tm2 $ cd /home/pm1/mydir2/sub2 -bash: cd: /home/pm1/mydir2/sub2: Permission denied \u4e0a\u4f8b\u4e2d\uff0c\u9ed8\u8ba4ACL\u4e2d\u6307\u5b9a\u7ec4 project2 \u53ea\u5177\u6709w\u6743\u9650\uff0c\u6240\u4ee5\u65e0\u6cd5\u6267\u884c cd \u547d\u4ee4\u8fdb\u5165\u8be5\u76ee\u5f55\u3002 \u8fd9\u8bf4\u660e\u6a21\u5f0f\u503cmode\u4e2d\u7ed9\u4e88\u7684\u6743\u9650 r \u88ab\u5c4f\u853d\u4e86\uff0c\u53ea\u4fdd\u7559\u4e86ACL\u4e2d\u6700\u5c0f\u7684\u6743\u9650 w \u3002 8.8.ACL\u68c0\u67e5\u903b\u8f91 \u00b6 ACL\u68c0\u67e5\u987a\u5e8f\uff1a Owner Named user Owning group Named group Other If \u8fdb\u7a0b\u7684\u7528\u6237\u6807\u8bc6\u662fOwner\uff0c\u5219owner\u7684ACL\u6761\u76ee\u51b3\u5b9a\u8bbf\u95ee\u6743\u9650 else if \u8fdb\u7a0b\u7684\u7528\u6237\u6807\u8bc6\u662fnamed user\uff0c\u5219name user\u7684ACL\u6761\u76ee\u7684\u6743\u9650\u51b3\u5b9a\u7533\u8bf7\u7684\u8bbf\u95ee\u6743\u9650 else if \u8fdb\u7a0b\u7684\u7ec4\u5c5e\u4e8eowning group\uff0c\u4e14owning group\u7684ACL\u6761\u76ee\u5305\u542b\u6240\u8bf7\u6c42\u7684\u8bbf\u95ee\u6743\u9650\uff0c\u5219\u6388\u4e88\u6240\u8bf7\u6c42\u7684\u6743\u9650 else if \u8fdb\u7a0b\u7684\u7ec4\u5c5e\u4e8enamed group\uff0c\u4e14named group\u7684ACL\u6761\u76ee\u5305\u542b\u6240\u8bf7\u6c42\u7684\u8bbf\u95ee\u6743\u9650\uff0c\u5219\u6388\u4e88\u6240\u8bf7\u6c42\u7684\u6743\u9650 else if \u8fdb\u7a0b\u7684\u7ec4\u5c5e\u4e8eowning group\u6216\u8005named group\uff0c\u4f46owning group\u6216\u8005named group\u7684ACL\u6761\u76ee\u4e0d\u5305\u542b\u6240\u8bf7\u6c42\u7684\u8bbf\u95ee\u6743\u9650\uff0c\u5219\u62d2\u7edd\u6240\u8bf7\u6c42\u7684\u6743\u9650 else ACL\u4e2d\u7684other\u6761\u76ee\u5904\u7406\u7533\u8bf7\u7684\u6743\u9650 If \u5982\u679c\u8fdb\u7a0b\u5339\u914d\u5230owner\u6216\u8005other\u6761\u76ee\u4e2d\u5305\u542b\u6240\u7533\u8bf7\u7684\u6743\u9650\uff0c\u5219\u6388\u4e88\u6743\u9650 else if \u5982\u679c\u8fdb\u7a0b\u5339\u914d\u5230named user\uff0cowning group\uff0c\u6216\u8005named group\u6761\u76ee\u4e2d\u5305\u542b\u6240\u7533\u8bf7\u7684\u6743\u9650\uff0c\u4e14maks\u6761\u76ee\u4e5f\u5305\u542b\u6240\u7533\u8bf7\u7684\u6743\u9650\uff0c\u5219\u6388\u4e88\u6743\u9650 else \u62d2\u7edd\u6743\u9650\u7533\u8bf7 \u5b9e\u9645\u5e94\u7528\u4e3e\u4f8b\uff1a udev\u4f7f\u7528ACL\u7ed9\u4e88\u767b\u5f55\u5230\u56fe\u5f62\u754c\u9762\u7684\u7528\u6237\u8bbf\u95ee\u8bbe\u5907\u7684\u6743\u9650\uff0c\u4f8b\u5982DVD\u9a71\u52a8\u5668 \u67d0\u4e9b\u5e94\u7528\u7a0b\u5e8f\u4e0d\u652f\u6301ACL Star Archiver\u662f\u4e00\u4e2a\u5b8c\u5168\u4fdd\u7559ACL\u7684\u5907\u4efd\u5e94\u7528\u7a0b\u5e8f\uff0c\u5176\u4ed6\u4eba\u53ef\u80fd\u4f1a\u4e5f\u53ef\u80fd\u4e0d\u4f1a\u4fdd\u7559\u5b83 \u8bb8\u591a\u7f16\u8f91\u5668\u548c\u6587\u4ef6\u7ba1\u7406\u5668\u4e0d\u5141\u8bb8\u5728\u5e94\u7528\u7a0b\u5e8f\u4e2d\u67e5\u770b\u6216\u8bbe\u7f6eACL","title":"\u7b2c\u4e09\u7ae0 \u8eab\u4efd\u4e0e\u5b89\u5168"},{"location":"linux/SRE/03-identity-security/#_1","text":"","title":"\u7b2c\u4e09\u7ae0 \u8eab\u4efd\u4e0e\u5b89\u5168"},{"location":"linux/SRE/03-identity-security/#1","text":"\u7528\u6237\u548c\u7ec4 \u7528\u6237user\u548c\u7ec4group\u5728Linux\u7cfb\u7edf\u4e2d\u4ee5\u6570\u5b57\u5f62\u5f0f\u8fdb\u884c\u7ba1\u7406\u3002 \u7528\u6237\u88ab\u5206\u914d\u7684\u53f7\u7801\u79f0\u4e3a\u7528\u6237ID\uff08UID\uff09\u3002 \u6bcf\u4e2aLinux\u7cfb\u7edf\u90fd\u6709\u4e00\u4e2a\u7279\u6743\u7528\u6237\uff0c\u5373 root \u7528\u6237\u3002 root \u662f\u7cfb\u7edf\u7ba1\u7406\u5458\u3002 \u6b64\u7528\u6237\u7684UID\u59cb\u7ec8\u4e3a0\u3002 \u666e\u901a\u7528\u6237\u7684UID\u7f16\u53f7\uff08\u9ed8\u8ba4\u60c5\u51b5\u4e0b\uff09\u4e3a1000\u3002 \u6bcf\u4e2a\u7ec4\u4e5f\u5206\u914d\u4e86\u4e00\u4e2a\u79f0\u4e3a\u7ec4ID\uff08GID\uff09\u7684\u7f16\u53f7\u3002 \u6bcf\u4e2a\u7528\u6237\u6709\u4e00\u4e2a\u4e3b\u8981\u7ec4\uff08primary group\uff09\uff0c\u6709\u96f6\u4e2a\u6216\u8005\u4efb\u610f\u4e2a\u9644\u52a0\u7ec4\uff08supplementary group\uff09\u3002 \u4ee5openSUSE\u4e3a\u4f8b\uff1a UID 0: root 1 \u2013 99: System 100 \u2013 499: System accounts \u2265 1000: Normal (unprivileged) accounts GID 0: root 1 \u2013 99: System Groups 100 \u2013 499: Dynamically Allocated System Groups \u2265 1000: Normal Groups \u4e3e\u4f8b\uff1a $ id postfix uid = 51 ( postfix ) gid = 51 ( postfix ) groups = 482 ( mail ) ,59 ( maildrop ) ,51 ( postfix ) $ id vagrant uid = 1000 ( vagrant ) gid = 478 ( wheel ) groups = 0 ( root ) ,478 ( wheel ) \u63d0\u793a\uff1a UID\u548cGID\u7b49\u7f16\u53f7\u89c4\u5219\uff0c\u662f\u5728\u6587\u4ef6 /etc/login.defs \u4e2d\u7ea6\u5b9a\u7684\u3002","title":"1.\u7528\u6237\u3001\u7ec4\u3001\u6743\u9650"},{"location":"linux/SRE/03-identity-security/#2selinux","text":"Security-Enhanced Linux (SELinux) \u662f\u4e00\u79cdLinux\u7cfb\u7edf\u7684\u5b89\u5168\u67b6\u6784\uff0c\u5b83\u5141\u8bb8\u7ba1\u7406\u5458\u66f4\u597d\u5730\u63a7\u5236\u8c01\u53ef\u4ee5\u8bbf\u95ee\u7cfb\u7edf\u3002 SELinux\u4e8e2000\u5e74\u5411\u5f00\u6e90\u793e\u533a\u53d1\u5e03\uff0c\u5e76\u4e8e2003\u5e74\u96c6\u6210\u5230\u4e0a\u6e38 Linux \u5185\u6838\u4e2d\u3002 SELinux\u4e3a\u7cfb\u7edf\u4e0a\u7684\u5e94\u7528\u7a0b\u5e8f\u3001\u8fdb\u7a0b\u548c\u6587\u4ef6\u5b9a\u4e49\u4e86\u8bbf\u95ee\u63a7\u5236\u3002 \u5b83\u4f7f\u7528\u5b89\u5168\u7b56\u7565\uff08\u4e00\u7ec4\u89c4\u5219\u544a\u8bc9SELinux\u4ec0\u4e48\u53ef\u4ee5\u8bbf\u95ee\u6216\u4e0d\u53ef\u4ee5\u8bbf\u95ee\uff09\u6765\u5f3a\u5236\u6267\u884c\u7b56\u7565\u5141\u8bb8\u7684\u8bbf\u95ee\u3002 \u5f53\u79f0\u4e3a\u4e3b\u4f53\uff08subject\uff09\u7684\u5e94\u7528\u7a0b\u5e8f\u6216\u8fdb\u7a0b\u8bf7\u6c42\u8bbf\u95ee\u5bf9\u8c61\uff08\u5982\u6587\u4ef6\uff09\u65f6\uff0cSELinux\u4f1a\u68c0\u67e5\u8bbf\u95ee\u5411\u91cf\u7f13\u5b58(AVC, Access Vector Cache)\uff0c\u5176\u4e2d\u7f13\u5b58\u4e86\u4e3b\u4f53\u548c\u5bf9\u8c61\u7684\u6743\u9650\u3002 \u5982\u679cSELinux\u65e0\u6cd5\u6839\u636e\u7f13\u5b58\u7684\u6743\u9650\u505a\u51fa\u8bbf\u95ee\u51b3\u5b9a\uff0c\u5b83\u4f1a\u5c06\u8bf7\u6c42\u53d1\u9001\u5230\u5b89\u5168\u670d\u52a1\u5668\u3002 \u5b89\u5168\u670d\u52a1\u5668\u68c0\u67e5\u5e94\u7528\u7a0b\u5e8f\u6216\u8fdb\u7a0b\u548c\u6587\u4ef6\u7684\u5b89\u5168\u4e0a\u4e0b\u6587\u3002 \u4eceSELinux\u7b56\u7565\u6570\u636e\u5e93\u5e94\u7528\u5b89\u5168\u4e0a\u4e0b\u6587\uff08Security context\uff09\uff0c\u7136\u540e\u6388\u4e88\u6216\u62d2\u7edd\u8bb8\u53ef\u3002 \u5982\u679c\u6743\u9650\u88ab\u62d2\u7edd\uff0c avc: denied \u6d88\u606f\u5c06\u5728 /var/log.messages \u4e2d\u4f53\u73b0\u3002 \u4f20\u7edf\u4e0a\uff0cLinux\u548cUNIX\u7cfb\u7edf\u90fd\u4f7f\u7528DAC\uff08Discretionary Access Control\uff09\u3002 SELinux\u662fLinux\u7684MAC\uff08Mandatory Access Control\uff09\u7cfb\u7edf\u7684\u4e00\u4e2a\u793a\u4f8b\u3002 \u5728DAC\u65b9\u5f0f\u4e0b\uff0c\u6587\u4ef6\u548c\u8fdb\u7a0b\u6709\u81ea\u5df1\u7684\u5c5e\u4e3b\uff08\u6240\u6709\u8005\uff09\u3002 \u7528\u6237\u53ef\u4ee5\u62e5\u6709\u4e00\u4e2a\u6587\u4ef6\uff0c\u4e00\u4e2a\u7ec4\u4e5f\u53ef\u4ee5\u62e5\u6709\u4e00\u4e2a\u6587\u4ef6\uff0c\u6216\u8005\u5176\u4ed6\u4eba\u3002 \u7528\u6237\u53ef\u4ee5\u66f4\u6539\u81ea\u5df1\u6587\u4ef6\u7684\u6743\u9650\u3002 root \u7528\u6237\u5bf9DAC\u7cfb\u7edf\u5177\u6709\u5b8c\u5168\u8bbf\u95ee\u63a7\u5236\u6743\u3002 \u4f46\u662f\u5728\u50cfSELinux\u8fd9\u6837\u7684MAC\u7cfb\u7edf\u4e0a\uff0c\u5bf9\u4e8e\u8bbf\u95ee\u7684\u7ba1\u7406\u662f\u901a\u8fc7\u8bbe\u7f6e\u7b56\u7565\u6765\u5b9e\u73b0\u7684\u3002\u5373\u4f7f\u7528\u6237\u4e3b\u76ee\u5f55\u4e0a\u7684DAC\u8bbe\u7f6e\u53d1\u751f\u66f4\u6539\uff0c\u7528\u4e8e\u9632\u6b62\u5176\u4ed6\u7528\u6237\u6216\u8fdb\u7a0b\u8bbf\u95ee\u8be5\u76ee\u5f55\u7684SELinux\u7b56\u7565\u4e5f\u5c06\u7ee7\u7eed\u786e\u4fdd\u7cfb\u7edf\u5b89\u5168\u3002 MAC\u65b9\u5f0f\u662f\u63a7\u5236\u4e00\u4e2a\u8fdb\u7a0b\u5bf9\u5177\u4f53\u6587\u4ef6\u7cfb\u7edf\u4e0a\u9762\u7684\u6587\u4ef6\u6216\u76ee\u5f55\u662f\u5426\u62e5\u6709\u8bbf\u95ee\u6743\u9650\u3002\u5224\u65ad\u8fdb\u7a0b\u662f\u5426\u53ef\u4ee5\u8bbf\u95ee\u6587\u4ef6\u6216\u76ee\u5f55\u7684\u4f9d\u636e\uff0c\u53d6\u51b3\u4e8eSELinux\u4e2d\u8bbe\u5b9a\u7684\u5f88\u591a\u7b56\u7565\u89c4\u5219\u3002 \u8bbf\u95ee\u63a7\u5236\u5217\u8868 (ACL\uff0cAccess Control List) \u4e3a\u6587\u4ef6\u7cfb\u7edf\u63d0\u4f9b\u4e86\u4e00\u79cd\u989d\u5916\u7684\u3001\u66f4\u7075\u6d3b\u7684\u6743\u9650\u673a\u5236\u3002 \u5b83\u65e8\u5728\u534f\u52a9 UNIX \u6587\u4ef6\u6743\u9650\u3002ACL\u5141\u8bb8\u6388\u4e88\u4efb\u4f55\u7528\u6237\u6216\u7ec4\u5bf9\u4efb\u4f55\u78c1\u76d8\u8d44\u6e90\u7684\u6743\u9650\u3002ACL\u9002\u7528\u4e8e\u5728\u4e0d\u4f7f\u67d0\u4e2a\u7528\u6237\u6210\u4e3a\u7ec4\u6210\u5458\u7684\u60c5\u51b5\u4e0b\uff0c\u4ecd\u65e7\u6388\u4e88\u4e00\u4e9b\u8bfb\u6216\u5199\u8bbf\u95ee\u6743\u9650\u3002 \u4e0b\u9762\u793a\u4f8b\u5bf9\u6bd4\u8bf4\u660e\u4e86SELinux\u548cACL\u5728\u6587\u4ef6\u5c5e\u6027\u5c55\u73b0\u4e0a\u7684\u7279\u70b9\u3002 -rwxr-xr-- vagrant wheel \uff1a\u6ca1\u6709selinux\u4e0a\u4e0b\u6587\uff0c\u6ca1\u6709ACL -rwx--xr-x+ vagrant wheel \uff1a\u53ea\u6709ACL\uff0c\u6ca1\u6709selinux\u4e0a\u4e0b\u6587 -rw-r--r--. vagrant wheel \uff1a\u53ea\u6709selinux\u4e0a\u4e0b\u6587\uff0c\u6ca1\u6709ACL -rwxrwxr--+ vagrant wheel \uff1a\u6709selinux\u4e0a\u4e0b\u6587\uff0c\u6709ACL","title":"2.SELinux"},{"location":"linux/SRE/03-identity-security/#21selinux","text":"\u7528\u6237(Users)\uff1a SELinux\u7684\u7528\u6237\u4e0d\u7b49\u540c\u4e0eLinux\u7528\u6237\u3002 SELinux\u7528\u6237\u4ee5\u540e\u7f00 _u \u7ed3\u5c3e\u3002 \u89d2\u8272(Roles)\uff1a \u89d2\u8272Roles\u662f\u7531\u7b56\u7565Policies\u5b9a\u4e49\u7684\uff0c\u89d2\u8272\u51b3\u5b9a\u4e86\u4f7f\u7528\u54ea\u4e2a\u7b56\u7565\u3002 SELinux\u89d2\u8272\u4ee5\u540e\u7f00 _r \u7ed3\u5c3e\u3002 \u7c7b\u578b(Types)\uff1a SELinux\u662f\u7c7b\u578b\u5f3a\u5236\u7684\uff0c\u7c7b\u578bTypes\u51b3\u5b9a\u8fdb\u7a0b\u80fd\u5426\u8bbf\u95ee\u67d0\u4e2a\u6587\u4ef6\u3002 SELinux\u7c7b\u578b\u662f\u4ee5\u540e\u7f00 _t \u7ed3\u5c3e\u3002 \u4e0a\u4e0b\u6587(Contexts)\uff1a \u7528\u6765\u6807\u8bb0\u8fdb\u7a0b\u548c\u6587\u4ef6\u3002\u5206\u522b\u662f\u7528\u6237Users\uff0c\u89d2\u8272Roles\uff0c\u7c7b\u578bTypes\uff0c\u8303\u56f4Ranges\u3002 \u683c\u5f0f\uff1a user:role:type:range \u6587\u4ef6\u7c7b\u578b(Object Classes)\uff1a \u6bcf\u4e2a\u6587\u4ef6\u7c7b\u578bTypes\u90fd\u5bf9\u5e94\u4e00\u5957\u7b56\u7565Policies\u3002\u7b56\u7565Policies\u51b3\u5b9a\u4e86\u8fdb\u7a0b\u5bf9\u8fd9\u7c7b\u6587\u4ef6\u7684\u8bbf\u95ee\u6743\u9650\u3002 \u8bbf\u95ee\u6743\u9650\u67094\u79cd\uff1a \u521b\u5efacreate \u8bfb\u53d6read \u5199\u5165write \u5220\u9664unlink\uff08\u6ce8\u610f\uff0c\u8fd9\u91cc\u4e0d\u662f\u94fe\u63a5\u7684\u610f\u601d\uff09 \u89c4\u5219(Rules) \u683c\u5f0f\uff1a allow user_t user_home_t:file {create read write unlink}; \u542b\u4e49\uff1a user_t \u7c7b\u578b\u5bf9 user_home_t \u7c7b\u578b\u6709\u521b\u5efacreate\uff0c\u8bfb\u53d6read\uff0c\u5199\u5165write\uff0c\u5220\u9664unlink\u6743\u9650\u3002","title":"2.1.SELinux\u4e3b\u8981\u6982\u5ff5"},{"location":"linux/SRE/03-identity-security/#22selinux-in-opensuse","text":"\u4f5c\u4e3aSELinux\u7684\u66ff\u4ee3\u54c1\uff0c2005\u5e74\u88abNovell\u6536\u8d2d\u7684Immunix\u516c\u53f8\u5f00\u53d1\u4e86AppArmor\u3002SUSE\u5728openSUSE Leap\u4e2d\u63d0\u4f9b\u5bf9SELinux\u6846\u67b6\u7684\u652f\u6301\u3002\u8fd9\u5e76\u4e0d\u610f\u5473\u7740openSUSE Leap\u7684\u9ed8\u8ba4\u5b89\u88c5\u4f1a\u5728\u4e0d\u4e45\u7684\u5c06\u6765\u4eceAppArmor\u5207\u6362\u5230SELinux\u3002 \u6dfb\u52a0SELinux\u7684\u6e90\u3002\u53ef\u4ee5\u4ece https://download.opensuse.org/repositories/security:/SELinux/ \u4e0b\u8f7d\u5bf9\u5e94\u7684\u7b56\u7565policy\u3002 sudo zypper ar -f https://download.opensuse.org/repositories/security:/SELinux/openSUSE_Factory/ Security-SELinux \u5b89\u88c5C++\u7b49\u57fa\u7840\u5f00\u53d1\u5305\uff1a # \u5217\u51fa\u5f53\u524d\u53ef\u5b89\u88c5\u7684Pattern sudo zypper pt # \u5b89\u88c5\u4e0b\u9762\u51e0\u4e2a\u5f00\u53d1\u76f8\u5173\u7684Pattern sudo zypper in -t pattern devel_C_C++ devel_basis devel_kernel \u5b89\u88c5SELinux packages\uff1a zypper se --search-descriptions selinux sudo zypper in restorecond policycoreutils setools-console sudo zypper in selinux-tools libselinux-devel \u5b89\u88c5SELinux policy\uff1a sudo zypper in selinux-policy-targeted selinux-policy-devel selinux-autorelabel \u66f4\u65b0GRUB2 bootloader\uff08GRUB2\u5f15\u5bfc\u52a0\u8f7d\u7a0b\u5e8f\uff09\uff1a \u7f16\u8f91\u6587\u4ef6 /etc/default/grub \uff0c\u6dfb\u52a0\u4e0b\u9762\u5185\u5bb9\u5230 GRUB_CMDLINE_LINUX_DEFAULT= \u8fd9\u4e00\u884c\uff1a security = selinux selinux = 1 \u8bb0\u5f55\u8fd9\u4e00\u884c\u7684\u539f\u59cb\u4fe1\u606f\uff1a GRUB_CMDLINE_LINUX_DEFAULT = \"splash=silent resume=/dev/disk/by-uuid/47c36ad7-f49f-4ecd-9b72-4801c5bb3a04 preempt=full mitigations=auto quiet security=apparmor\" \u8fd0\u884c\u4e0b\u9762\u7684\u547d\u4ee4\u751f\u6210\u65b0\u7684GRUB2\u5f15\u5bfc\u52a0\u8f7d\u7a0b\u5e8f\u914d\u7f6e\u6587\u4ef6\u3002 sudo grub2-mkconfig -o /boot/grub2/grub.cfg \u7f16\u8f91\u6587\u4ef6 /etc/selinux/config \u5e76\u8bbe\u7f6e SELINUX=permissive \u6765\u542f\u7528SElinux\u3002\u8fd9\u4e0e\u524d\u9762GRUB2\u7684\u542f\u52a8\u914d\u7f6e\u662f\u4e00\u81f4\u7684\u3002 \u5982\u6587\u4ef6\u4e0d\u5b58\u5728\uff0c\u5219\u521b\u5efa\u3002 $ sudo cat /etc/selinux/config SELINUX = permissive SELINUXTYPE = targeted \u91cd\u542f\u7cfb\u7edf\u3002\u7cfb\u7edf\u542f\u52a8\u53ef\u80fd\u9700\u8981\u4e00\u4e9b\u65f6\u95f4\uff0cSELinux\u9700\u8981\u7ed9\u6574\u4e2a\u6587\u4ef6\u7cfb\u7edf\u91cd\u65b0\u8fdb\u884c\u6807\u7b7e\u5316\u3002 \u91cd\u542f\u540e\uff0c\u8fd0\u884c\u4e0b\u9762\u7684\u547d\u4ee4\u6765\u67e5\u770bSELinux\u662f\u5426\u8fd0\u884c\u6b63\u5e38\u3002 $ sudo getenforce Permissive $ sudo sestatus -v SELinux status: enabled SELinuxfs mount: /sys/fs/selinux SELinux root directory: /etc/selinux Loaded policy name: targeted Current mode: permissive Mode from config file: permissive Policy MLS status: enabled Policy deny_unknown status: allowed Memory protection checking: requested ( insecure ) Max kernel policy version: 33 Process contexts: Current context: unconfined_u:unconfined_r:unconfined_t:s0 Init context: system_u:system_r:kernel_t:s0 /sbin/agetty system_u:system_r:kernel_t:s0 /usr/sbin/sshd system_u:system_r:kernel_t:s0 File contexts: Controlling terminal: unconfined_u:object_r:devpts_t:s0 /etc/passwd system_u:object_r:unlabeled_t:s0 /etc/shadow system_u:object_r:unlabeled_t:s0 /bin/bash system_u:object_r:unlabeled_t:s0 -> system_u:object_r:unlabeled_t:s0 /bin/login system_u:object_r:unlabeled_t:s0 /bin/sh system_u:object_r:unlabeled_t:s0 -> system_u:object_r:unlabeled_t:s0 /sbin/agetty system_u:object_r:unlabeled_t:s0 -> system_u:object_r:unlabeled_t:s0 /sbin/init system_u:object_r:unlabeled_t:s0 -> system_u:object_r:unlabeled_t:s0 /usr/sbin/sshd system_u:object_r:unlabeled_t:s0 \u53c2\u8003\uff1a GRUB2\u5f15\u5bfc\u52a0\u8f7d\u7a0b\u5e8f\u4e2d\u6dfb\u52a0\u7684\u4e09\u4e2a\u53c2\u6570\u7684\u89e3\u91ca\uff1a security=selinux : This option tells the kernel to use SELinux and not AppArmor. selinux=1 : This option switches on SELinux. enforcing=0 : This option puts SELinux in permissive mode. In this mode, SELinux is fully functional, but does not enforce any of the security settings in the policy. Use this mode for testing and configuring your system. To switch on SELinux protection, when the system is fully operational, change the option to enforcing=1 and add SELINUX=enforcing in /etc/selinux/config . \u5c0f\u8d34\u58eb\uff1a \u5728\u9996\u6b21\u542f\u7528SELinux\u540e\uff0c\u5982\u679c\u53ea\u5728grub2\u91cc\u9762\u6dfb\u52a0selinux=1\uff0c\u901a\u8fc7 getenforce \u547d\u4ee4\u770b\u7684SELinux\u4e00\u76f4\u5c31\u662fdisabled\u7684\u72b6\u6001\uff0c\u9700\u8981\u624b\u5de5\u521b\u5efa/etc/selinux/config\u6587\u4ef6\u6dfb\u52a0\u914d\u7f6e\u624d\u884c\u3002\u611f\u89c9grub2\u91cc\u9762\u65e0\u9700\u8bbe\u7f6e\uff0c\u76f4\u63a5\u914d\u7f6e/etc/selinux/config\u6587\u4ef6\u3002\u4e0d\u786e\u5b9a\u8fd9\u4e2a\u60f3\u6cd5\u662f\u5426\u6b63\u786e\u3002 \u5728grub2\u4e2d\u8bbe\u5b9aselinux=1\uff0c\u5728/etc/selinux/config\u6587\u4ef6\u4e2d\uff1a \u8bbe\u5b9aSELINUX=permissive\uff0c\u91cd\u542f\u540e\u901a\u8fc7 getenforce \u547d\u4ee4\u770b\u5230\u7684\u662fpermissive\u3002 \u8bbe\u5b9aSELINUX=disabled\uff0c\u5219\u91cd\u542f\u540e getenforce \u547d\u4ee4\u770b\u5230\u7684\u662fdisabled\u3002 \u8fd9\u8bf4\u660e\u914d\u7f6e\u6587\u4ef6\u540e\u542f\u52a8\uff0c\u8986\u76d6\u4e86\u5185\u6838\u8bbe\u7f6e\u3002 \u6ce8\u610f\uff0c\u5982\u679c\u4ec5\u4ec5\u5b8c\u6210\u4e86\u4e0a\u9762\u7684enable SELinux\uff0c\u7acb\u523b\u8bbe\u5b9aSELINUX=enforcing\uff0c\u4f1a\u5f15\u8d77ssh\u65e0\u6cd5\u767b\u5f55\uff0c\u9519\u8bef\u4fe1\u606f\u662f /bin/bash: Permission denied \u3002 \u914d\u7f6eSELinux\u3002 $ sudo semanage boolean -l Failed to use semanage \u6dfb\u52a0\u4e0b\u9762\u5185\u5bb9\u5230.bashrc\u6587\u4ef6\u3002 export PATH = /usr/local/bin:/home/ $USER /.local/bin: $PATH \u66f4\u65b0pip3. pip3 install --upgrade pip \u5b89\u88c5\u4e0b\u9762\u51e0\u4e2a\u5305 sudo zypper in libselinux libselinux-devel sudo zypper in python3-semanage sudo zypper in libsemanage-devel libsemanage-devel-static sudo zypper in policycoreutils-python-utils sudo zypper in cross-x86_64-linux-glibc-devel glibc-utils glibc-profile sudo zypper in policycoreutils-devel","title":"2.2.SELinux in openSUSE"},{"location":"linux/SRE/03-identity-security/#23selinux-in-ubuntu","text":"","title":"2.3.SELinux in Ubuntu"},{"location":"linux/SRE/03-identity-security/#24selinux-in-rocky","text":"","title":"2.4.SELinux in Rocky"},{"location":"linux/SRE/03-identity-security/#3","text":"/etc/passwd \uff1a\u7528\u6237\u53ca\u5176\u5c5e\u6027\u4fe1\u606f\uff08\u7528\u6237\u540d\uff0cUID\uff0c\u4e3b\u7ec4ID\u7b49\uff09 /etc/shadow \uff1a\u7528\u6237\u5bc6\u7801\u673a\u5668\u5c5e\u6027 /etc/group \uff1a\u7ec4\u53ca\u5176\u5c5e\u6027 /etc/gshadow \uff1a\u7ec4\u5bc6\u7801\u53ca\u5176\u5c5e\u6027","title":"3.\u7528\u6237\u548c\u7ec4\u7684\u914d\u7f6e\u6587\u4ef6"},{"location":"linux/SRE/03-identity-security/#31etcpasswd","text":"\u683c\u5f0f\u8bf4\u660e\uff1a vagrant:x:1001:474:vagrant:/home/vagrant:/bin/bash [ ----- ] - [ -- ] [ - ] [ ----- ] [ ----------- ] [ ------- ] | | | | | | +--------> 7 . Login shell | | | | | +--------------------> 6 . Home directory | | | | +-------------------------------> 5 . GECOS or the full name of the user | | | +-------------------------------------> 4 . GID | | +------------------------------------------> 3 . UID | +---------------------------------------------> 2 . Password +--------------------------------------------------> 1 . Username","title":"3.1./etc/passwd"},{"location":"linux/SRE/03-identity-security/#32etcshadow","text":"\u683c\u5f0f\u8bf4\u660e\uff1a vagrant: $6 $.n.:17736:0:99999:7::: [ ----- ] [ ---- ] [ --- ] - [ --- ] ---- | | | | | || | +-----------> 9 . Unused | | | | | || +------------> 8 . Expiration date since Jan 1 , 1970 | | | | | | +-------------> 7 . Inactivity period \u5bc6\u7801\u8fc7\u671f\u540e\u7684\u5bbd\u9650\u671f | | | | | +--------------> 6 . Warning period, default 7 days | | | | +------------------> 5 . Maximum password age | | | +----------------------> 4 . Minimum password age | | +--------------------------> 3 . Last password change since Jan 1 , 1970 | +---------------------------------> 2 . Encrypted Password +-------------------------------------------> 1 . Username","title":"3.2./etc/shadow"},{"location":"linux/SRE/03-identity-security/#33etcgroup","text":"\u683c\u5f0f\u8bf4\u660e\uff1a audio:x:492:pulse [ --- ] - [ - ] [ --- ] | | | +----> 4 . username-list, who have this group as their supplementary | | +---------> 3 . GID | +------------> 2 . group-password. Real password is in /etc/gshadow +----------------> 1 . groupname","title":"3.3./etc/group"},{"location":"linux/SRE/03-identity-security/#34etcgshadow","text":"\u683c\u5f0f\u8bf4\u660e\uff1a general:!!:shelley:juan,bob [ ----- ] -- [ ----- ] [ ------ ] | | | +-------> 4 . group members ( in a comma delimited list ) | | +---------------> 3 . group adminstrators ( in a comma delimited list ) | +---------------------> 2 . encrypted password. ` ! ` , ` !! ` , and null +---------------------------> 1 . group name Encrypted password ! \uff1ano user is allowed to access the group using the newgrp command. !! \uff1athe same as a value of ! \u2014 however, it also indicates that a password has never been set before. null\uff1aonly group members can log into the group.","title":"3.4./etc/gshadow"},{"location":"linux/SRE/03-identity-security/#35","text":"# \u901a\u8fc7`/dev/urandom`\u751f\u6210\u968f\u673a\u6570\uff0c\u901a\u8fc7`tr -dc`\u8fc7\u6ee4\u968f\u673a\u6570\uff0c\u53ea\u4fdd\u7559\u5b57\u6bcd\u548c\u6570\u5b57\uff0c\u901a\u8fc7`head -c`\u4fdd\u7559\u6307\u5b9a\u4f4d\u6570 $ tr -dc '[:alnum:]' < /dev/urandom | head -c 12 xFw7vfma54D8 $ openssl rand -base64 9 I5TZXJfpd3Pg","title":"3.5.\u751f\u6210\u968f\u673a\u5bc6\u7801"},{"location":"linux/SRE/03-identity-security/#36vipwvigrpwckgrpck","text":"vipw \u548c vigr \u547d\u4ee4\u5206\u522b\u7f16\u8f91\u6587\u4ef6 /etc/passwd \u548c /etc/group \u3002 \u5982\u679c\u6307\u5b9a\u4e86 -s \u6807\u5fd7\uff0c\u8fd9\u4e9b\u547d\u4ee4\u5c06\u5206\u522b\u7f16\u8f91\u5176\u6587\u4ef6\u7684\u5f71\u5b50\uff08\u5b89\u5168\uff09\u7248\u672c\uff1a /etc/shadow \u548c /etc/gshadow \u3002 vipw \u548c vigr \u547d\u4ee4\u5728\u7f16\u8f91\u6587\u4ef6\u65f6\u4f1a\u8bbe\u7f6e\u9501\u4ee5\u9632\u6b62\u6587\u4ef6\u635f\u574f\u3002 vipw \u548c vigr \u547d\u4ee4\u4f1a\u9996\u5148\u5c1d\u8bd5\u73af\u5883\u53d8\u91cf $VISUAL \uff0c\u7136\u540e\u662f\u73af\u5883\u53d8\u91cf $EDITOR \uff0c\u6700\u540e\u662f\u9ed8\u8ba4\u7f16\u8f91\u5668 vi \u3002 sudo vipw sudo vipw -s sudo vigr sudo vigr -s pwck \u547d\u4ee4\u5b9e\u73b0\u9a8c\u8bc1\u7cfb\u7edf\u8ba4\u8bc1\u4fe1\u606f\u7684\u5b8c\u6574\u6027\u3002 \u68c0\u67e5 /etc/passwd \u548c /etc/shadow \u4e2d\u7684\u6240\u6709\u6761\u76ee\u6bcf\u4e2a\u5b57\u6bb5\u662f\u5426\u5177\u6709\u6b63\u786e\u7684\u683c\u5f0f\u548c\u6709\u6548\u6570\u636e\u3002 \u7cfb\u7edf\u4f1a\u63d0\u793a\u7528\u6237\u5220\u9664\u683c\u5f0f\u4e0d\u6b63\u786e\u6216\u5b58\u5728\u5176\u4ed6\u9519\u8bef\u7684\u6761\u76ee\u3002 pwck \u8fd4\u56de\u503c\uff1a 0 : success 1 : invalid command syntax 2 : one or more bad password entries 3 : can\u2019t open password files 4 : can\u2019t lock password files 5 : can\u2019t update password files grpck \u547d\u4ee4\u5b9e\u73b0\u9a8c\u8bc1\u7cfb\u7edf\u8ba4\u8bc1\u4fe1\u606f\u7684\u5b8c\u6574\u6027\u3002 \u68c0\u67e5 /etc/group \u548c /etc/gshadow \u4e2d\u7684\u6240\u6709\u6761\u76ee\u6bcf\u4e2a\u5b57\u6bb5\u662f\u5426\u5177\u6709\u6b63\u786e\u7684\u683c\u5f0f\u548c\u6709\u6548\u6570\u636e\u3002 \u7cfb\u7edf\u4f1a\u63d0\u793a\u7528\u6237\u5220\u9664\u683c\u5f0f\u4e0d\u6b63\u786e\u6216\u5b58\u5728\u5176\u4ed6\u9519\u8bef\u7684\u6761\u76ee\u3002 grpck \u8fd4\u56de\u503c\uff1a 0 : success 1 : invalid command syntax 2 : one or more bad group entries 3 : can\u2019t open group files 4 : can\u2019t lock group files 5 : can\u2019t update group files","title":"3.6.vipw/vigr/pwck/grpck\u547d\u4ee4"},{"location":"linux/SRE/03-identity-security/#4","text":"\u7528\u6237\u7ba1\u7406\u547d\u4ee4\uff1a useradd usermod userdel","title":"4.\u7528\u6237\u7ba1\u7406"},{"location":"linux/SRE/03-identity-security/#41useradd","text":"\u4e3e\u4f8b\uff1a # \u666e\u901a\u7528\u6237 $ useradd -m -g wheel -G root -c \"vagrant\" vagrant # \u975e\u4ea4\u4e92\u7528\u6237 $ useradd -r -u 48 -g apache -d /var/www -s /sbin/nologin -g postfix -c \"Apache\" apache 2 >/dev/null useradd \u547d\u4ee4\u7684\u9ed8\u8ba4\u503c\u662f\u5728 /etc/default/useradd \u6587\u4ef6\u4e2d\u8bbe\u5b9a\u3002 openSUSE\u7684 /etc/default/useradd \u6587\u4ef6\u5185\u5bb9\uff1a GROUP = 100 HOME = /home INACTIVE = -1 # \u5bf9\u5e94/etc/shadow\u6587\u4ef6\u7b2c7\u5217\uff0cInactivity period\uff0c\u5bc6\u7801\u8fc7\u671f\u540e\u7684\u5bbd\u9650\u671f\uff0c-1\u8868\u793a\u4e0d\u9650\u5236 EXPIRE = # \u5bf9\u5e94/etc/shadow\u6587\u4ef6\u7b2c8\u5217\uff0cExpiration date since Jan 1, 1970\uff0c\u5373\u8d26\u53f7\u6709\u6548\u671f SHELL = /bin/bash SKEL = /etc/skel # \u7528\u4e8e\u751f\u6210\u7528\u6237\u4e3b\u76ee\u5f55\u7684\u6a21\u7248\u6587\u4ef6 USRSKEL = /usr/etc/skel CREATE_MAIL_SPOOL = yes Rocky\u7684 /etc/default/useradd \u6587\u4ef6\u5185\u5bb9\uff1a GROUP = 100 HOME = /home INACTIVE = -1 EXPIRE = SHELL = /bin/bash SKEL = /etc/skel CREATE_MAIL_SPOOL = yes \u5728Ubuntu\u4e2d /etc/default/useradd \u6587\u4ef6\u53ea\u6709\u4e0b\u9762\u8fd9\u4e00\u884c\u3002 SHELL = /bin/sh","title":"4.1.\u521b\u5efa\u7528\u6237useradd"},{"location":"linux/SRE/03-identity-security/#411newusers","text":"\u683c\u5f0f\uff1a newusers \u3002\u5176\u4e2d\u6587\u4ef6 \u7684\u683c\u5f0f\u5982\u4e0b\uff1a :::::: \u4e3e\u4f8b\uff0c\u521b\u5efa\u6587\u4ef6 users.txt \uff1a $ cat ~/users.txt tester1:123:600:1530: \"Test User1,testuser1@abc.com\" :/home/tester1:/bin/bash tester2:123:601:1529:::/bin/bash tester3:123::::: tester4:123::::/home/tester4:/bin/tsh \u770b\u7ed3\u679c\uff1a $ cat /etc/passwd | grep tester tester1:x:600:1530: \"Test User1,testuser1@abc.com\" :/home/tester1:/bin/bash tester2:x:601:1529:::/bin/bash tester3:x:1001:1001::: tester4:x:1002:1002::/home/tester4:/bin/tsh $ cat /etc/group | grep tester tester1:*:1530: tester2:*:1529: tester3:*:1001: tester4:*:1002: $ sudo cat /etc/shadow | grep tester tester1:!:19321:0:99999:7::: tester2:!:19321:0:99999:7::: tester3:!:19321:0:99999:7::: tester4:!:19321:0:99999:7::: $ ls -ld /home/tester* drwxr-xr-x. 1 tester1 tester1 0 Nov 26 00 :32 /home/tester1 drwxr-xr-x. 1 tester4 tester4 0 Nov 26 00 :32 /home/tester4","title":"4.1.1.\u6279\u91cf\u521b\u5efa\u7528\u6237newusers"},{"location":"linux/SRE/03-identity-security/#412chpasswd","text":"\u4e0d\u540c\u65b9\u6cd5\uff1a echo username:password | chpasswd chpasswd < file.txt # file.txt\u6bcf\u884c\u7684\u683c\u5f0f\u662fusername:password paste -d \":\" user.txt passwd.txt | chpasswd \u53c2\u6570 -e \uff1a\u53e3\u4ee4\u4ee5\u52a0\u5bc6\u7684\u65b9\u5f0f\u4f20\u9012\u3002\u5426\u5219\u53e3\u4ee4\u4ee5\u660e\u6587\u7684\u5f62\u5f0f\u4f20\u9012\u3002 \u6ce8\u610f\uff1a \u7528\u6237\u540dusername\u5fc5\u987b\u662f\u5df2\u5b58\u5728\u7684\u7528\u6237 \u666e\u901a\u7528\u6237\u6ca1\u6709\u4f7f\u7528\u8fd9\u4e2a\u6307\u4ee4\u7684\u6743\u9650 \u5982\u679c\u8f93\u5165\u6587\u4ef6\u662f\u6309\u975e\u52a0\u5bc6\u65b9\u5f0f\u4f20\u9012\u7684\u8bdd\uff0c\u8bf7\u5bf9\u8be5\u6587\u4ef6\u8fdb\u884c\u9002\u5f53\u7684\u52a0\u5bc6\u3002 \u6307\u4ee4\u6587\u4ef6\u4e0d\u80fd\u6709\u7a7a\u884c \u4e3e\u4f8b\uff1a echo tester1:112233 | sudo chpasswd $ cat chpasswd.txt tester1:112233 tester2:33445566 $ sudo chpasswd < chpasswd.txt","title":"4.1.2.\u6279\u91cf\u4fee\u6539\u5bc6\u7801chpasswd"},{"location":"linux/SRE/03-identity-security/#413openssl-passwd","text":"\u547d\u4ee4 openssl passwd \u683c\u5f0f\u53ef\u4ee5\u5982\u4e0b\u65b9\u6cd5\u83b7\u5f97\u3002 $ man -f passwd passwd ( 1 ) - change user password passwd ( 1ssl ) - compute password hashes passwd ( 5 ) - password file $ man passwd Man: find all matching manual pages ( set MAN_POSIXLY_CORRECT to avoid this ) * passwd ( 1 ) passwd ( 5 ) passwd ( 1ssl ) Man: What manual page do you want? Man: 1ssl \u4e3e\u4f8b\uff08\u8fd9\u91cc\u7528 \u4ee3\u66ff\u5b9e\u9645\u5bc6\u7801\uff09\uff1a # \u57fa\u4e8e\u7ed9\u5b9a\u5b57\u4e32newpasswd\u751f\u6210sha256\u52a0\u5bc6\u7801\uff0c $ openssl passwd -6 newpasswd # \u521b\u5efa\u65b0\u7528\u6237tester5\uff0c\u8d4b\u4e88\u52a0\u5bc6\u5bc6\u7801 $ useradd -p '' tester1 # \u8bfb\u53d6\u7528\u6237tester5\u7684\u5bc6\u7801\uff0c\u53ef\u4ee5\u9a8c\u8bc1\u662f\u5426\u548c\u4e4b\u524d\u7684\u4e00\u81f4 $ sudo getent shadow tester5 tester5::19321:0:99999:7:::","title":"4.1.3.\u751f\u6210\u52a0\u5bc6\u5bc6\u7801openssl passwd"},{"location":"linux/SRE/03-identity-security/#42usermod","text":"\u6dfb\u52a0\u7528\u6237\u5230\u9644\u52a0\u7ec4 usermod -a -G GROUP USER usermod -a -G GROUP1,GROUP2,GROUP3 USER \u4fee\u6539\u7528\u6237\u4e3b\u7ec4 usermod -a -g GROUP USER \u4fee\u6539\u7528\u6237\u4fe1\u606f usermod -c \"GECOS Comments\" USER \u4fee\u6539\u7528\u6237\u4e3b\u76ee\u5f55\uff0c\u4f7f\u7528\u7edd\u5bf9\u8def\u5f84\uff0c -m \u53c2\u6570\u4f1a\u628a\u539f\u4e3b\u76ee\u5f55\u7684\u5185\u5bb9\u79fb\u52a8\u5230\u65b0\u4e3b\u76ee\u5f55\u3002 usermod -d NEW_HOME_DIR USER usermod -d NEW_HOME_DIR -m USER \u4fee\u6539\u7528\u6237shell usermod -s SHELL USER \u4fee\u6539\u7528\u6237UID usermod -u UID USER \u4fee\u6539\u7528\u6237\u540d\uff08\u4e0d\u5e38\u7528\uff09\uff0c\u540c\u65f6\u4e5f\u9700\u8981\u4fee\u6539\u7528\u6237\u4e3b\u76ee\u5f55\u3002 usermod -l NEW_USER USER \u4fee\u6539\u7528\u6237\u8fc7\u671f\u5c5e\u6027\uff0c\u65e5\u671f\u683c\u5f0f\u662f YYYY-MM-DD usermod -e DATE USER \u5982\u679c\u8bbe\u5b9a\u6c38\u4e0d\u8fc7\u671f\uff0c\u5219\u7f6e\u7a7a\u65e5\u671f\uff1a usermod -e \"\" USER \u67e5\u770b\u5f53\u524d\u7528\u6237\u7684\u8fc7\u671f\u65e5\u671f $ sudo chage -l vagrant Last password change : Oct 30 , 2022 Password expires : never Password inactive : never Account expires : never Minimum number of days between password change : 0 Maximum number of days between password change : 99999 Number of days of warning before password expires : 7 \u9501\u5b9a\u7528\u6237\u3002 \u6b64\u547d\u4ee4\u5c06\u5728\u52a0\u5bc6\u5bc6\u7801\u524d\u63d2\u5165\u4e00\u4e2a\u611f\u53f9\u53f7 (!) \u6807\u8bb0\u3002 \u5f53 /etc/shadow \u6587\u4ef6\u4e2d\u7684\u5bc6\u7801\u5b57\u6bb5\u5305\u542b\u611f\u53f9\u53f7\u65f6\uff0c\u7528\u6237\u5c06\u65e0\u6cd5\u4f7f\u7528\u5bc6\u7801\u9a8c\u8bc1\u767b\u5f55\u7cfb\u7edf\u3002 \u5176\u4ed6\u767b\u5f55\u65b9\u6cd5\u4ecd\u7136\u5141\u8bb8\uff0c\u4f8b\u5982\u57fa\u4e8e\u5bc6\u94a5\u7684\u8eab\u4efd\u9a8c\u8bc1\u6216\u5207\u6362\u5230\u7528\u6237\u3002 \u5982\u679c\u8981\u9501\u5b9a\u8d26\u6237\u5e76\u7981\u7528\u6240\u6709\u767b\u5f55\u65b9\u5f0f\uff0c\u8fd8\u9700\u8981\u5c06\u5230\u671f\u65e5\u671f\u8bbe\u7f6e\u4e3a1\u3002 usermod -L USER usermod -L -e 1 USER \u89e3\u9501\u7528\u6237 usermod -U USER","title":"4.2.\u4fee\u6539\u7528\u6237\u5c5e\u6027usermod"},{"location":"linux/SRE/03-identity-security/#43userdel","text":"userdel \u547d\u4ee4\u6267\u884c\u65f6\uff0c\u4f1a\u8bfb\u53d6 /etc/login.defs \u6587\u4ef6\u7684\u5185\u5bb9\u3002 \u6b64\u6587\u4ef6\u4e2d\u5b9a\u4e49\u7684\u5c5e\u6027\u4f1a\u8986\u76d6 userdel \u7684\u9ed8\u8ba4\u884c\u4e3a\u3002 \u5982\u679c\u5728\u6b64\u6587\u4ef6\u4e2d\u5c06 USERGROUPS_ENAB \u8bbe\u7f6e\u4e3a yes \uff0c userdel \u5c06\u5220\u9664\u4e0e\u7528\u6237\u540c\u540d\u7684\u7ec4\uff0c\u524d\u63d0\u662f\u6ca1\u6709\u5176\u4ed6\u7528\u6237\u662f\u8be5\u7ec4\u7684\u6210\u5458\u3002 userdel \u547d\u4ee4\u4ece /etc/passwd \u548c /etc/shadow \u6587\u4ef6\u4e2d\u5220\u9664\u7528\u6237\u6761\u76ee\u3002 userdel \u547d\u4ee4\u5220\u9664\u7528\u6237\u5e10\u6237\u65f6\uff0c\u4e00\u822c\u4e0d\u4f1a\u5220\u9664\u7528\u6237\u4e3b\u76ee\u5f55\u548c\u90ae\u4ef6\u5047\u8131\u673amail spool\u76ee\u5f55\u3002 \u4f7f\u7528 -r \u9009\u9879\u5f3a\u5236\u5220\u9664\u7528\u6237\u7684\u4e3b\u76ee\u5f55\u548c\u90ae\u4ef6\u5047\u8131\u673a\u76ee\u5f55\u3002 \u5982\u679c\u8981\u5220\u9664\u7684\u7528\u6237\u4ecd\u7136\u5904\u4e8e\u767b\u5f55\u72b6\u6001\uff0c\u6216\u8005\u6709\u5c5e\u4e8e\u8be5\u7528\u6237\u7684\u6b63\u5728\u8fd0\u884c\u7684\u8fdb\u7a0b\uff0c\u5219 userdel \u547d\u4ee4\u4e0d\u5141\u8bb8\u5220\u9664\u8be5\u7528\u6237\u3002 \u4f7f\u7528 -f \u9009\u9879\u5f3a\u5236\u5220\u9664\u7528\u6237\u5e10\u6237\uff0c\u5373\u4f7f\u7528\u6237\u4ecd\u7136\u767b\u5f55\u6216\u6709\u5c5e\u4e8e\u8be5\u7528\u6237\u7684\u6b63\u5728\u8fd0\u884c\u7684\u8fdb\u7a0b\u4e5f\u662f\u5982\u6b64\u3002 userdel USER userdel -r USER","title":"4.3.\u5220\u9664\u7528\u6237userdel"},{"location":"linux/SRE/03-identity-security/#44id","text":"\u7c7bUnix\u64cd\u4f5c\u7cfb\u7edf\u4e2d\u7684\u6bcf\u4e2a\u7528\u6237\u90fd\u7531\u4e00\u4e2a\u4e0d\u540c\u7684\u6574\u6570\u6807\u8bc6\uff0c\u8fd9\u4e2a\u552f\u4e00\u7684\u6570\u5b57\u79f0\u4e3aUserID\u3002 \u4e3a\u8fdb\u7a0bprocess\u5b9a\u4e49\u4e86\u4e09\u79cd\u7c7b\u578b\u7684UID\uff0c\u53ef\u4ee5\u6839\u636e\u4efb\u52a1\u7684\u6743\u9650\u52a8\u6001\u66f4\u6539\u3002 \u5b9a\u4e49\u7684\u4e09\u79cd\u4e0d\u540c\u7c7b\u578b\u7684UID\u662f\uff1a \u771f\u5b9e\u7528\u6237ID\uff08Real UserId\uff09\uff1a\u5bf9\u4e8e\u4e00\u4e2a\u8fdb\u7a0b\uff0cReal UserId\u5c31\u662f\u542f\u52a8\u5b83\u7684\u7528\u6237\u7684 UserID\u3002 \u5b83\u5b9a\u4e49\u4e86\u8fd9\u4e2a\u8fdb\u7a0b\u53ef\u4ee5\u8bbf\u95ee\u54ea\u4e9b\u6587\u4ef6\u3002 \u6709\u6548\u7528\u6237\u540d\uff08Effective UserID\uff09\uff1a\u5b83\u901a\u5e38\u4e0e Real UserID \u76f8\u540c\uff0c\u4f46\u6709\u65f6\u4f1a\u66f4\u6539\u4e3a\u4f7f\u975e\u7279\u6743\u7528\u6237\u80fd\u591f\u8bbf\u95ee\u90a3\u4e9b\u53ea\u80fd\u7531\u7279\u6743\u7528\u6237\uff08\u5982 root \uff09\u8bbf\u95ee\u7684\u6587\u4ef6\u3002 \u4fdd\u5b58\u7684\u7528\u6237ID\uff08Saved UserID\uff09 \uff1a\u5f53\u4e00\u4e2a\u4ee5\u63d0\u5347\u7684\u6743\u9650\uff08\u901a\u5e38\u662f root \uff09\u8fd0\u884c\u7684\u8fdb\u7a0b\u9700\u8981\u505a\u4e00\u4e9b\u4f4e\u6743\u9650\u7684\u4efb\u52a1\u65f6\u4f7f\u7528\uff0c\u53ef\u4ee5\u901a\u8fc7\u4e34\u65f6\u5207\u6362\u5230\u975e\u7279\u6743\u5e10\u6237\u6765\u5b9e\u73b0\u3002\u5728\u6267\u884c\u4f4e\u6743\u9650\u4efb\u52a1\u65f6\uff0c\u6709\u6548\u7684 UID \u88ab\u66f4\u6539\u4e3a\u67d0\u4e2a\u8f83\u4f4e\u6743\u9650\u7684\u503c\uff0c\u5e76\u4e14 euid \u88ab\u4fdd\u5b58\u5230\u5df2\u4fdd\u5b58\u7684 userID (suid)\u4e2d\uff0c\u4ee5\u4fbf\u5728\u4efb\u52a1\u5b8c\u6210\u65f6\u7528\u4e8e\u5207\u6362\u56de\u7279\u6743\u5e10\u6237\u3002 \u5728\u4e00\u4e2a\u7ec8\u7aef\u7a97\u53e3\u6267\u884c\u4e0b\u9762\u547d\u4ee4\uff0c\u6682\u505c\u5728\u65b0\u5bc6\u7801\u8f93\u5165\u8fd9\u4e00\u6b65\u3002 $ ls -ltr /usr/bin/passwd -rwsr-xr-x. 1 root shadow 65208 May 8 2022 /usr/bin/passwd $ passwd Changing password for vagrant. Current password: New password: \u65b0\u5f00\u4e00\u4e2a\u7ec8\u7aef\u7a97\u53e3\u3002 $ ps -a | grep passwd 3040 pts/0 00 :00:00 passwd $ ps -eo pid,euid,ruid | grep 3040 3040 0 1000 \u4e0a\u9762\u8f93\u51fa\u53ef\u4ee5\u770b\u51fa\uff0c passwd \u8fd9\u4e2a\u8fdb\u7a0b\u7684Effective UserID\u662f 0 \u3002Real UserId\u662f 1000 . id \u547d\u4ee4\u67e5\u770b\u7528\u6237\u6709\u6548\u7684UID\u548cGID\u3002 \u67e5\u770b\u5f53\u524d\u7528\u6237\u7684\u4fe1\u606f\uff1a $ id uid = 1000 ( vagrant ) gid = 478 ( wheel ) groups = 478 ( wheel ) ,0 ( root ) context = unconfined_u:unconfined_r:unconfined_t:s0 \u67e5\u770b\u6307\u5b9a\u7528\u6237\u7684\u4fe1\u606f\uff1a $ id vagrant uid = 1000 ( vagrant ) gid = 478 ( wheel ) groups = 0 ( root ) ,478 ( wheel ) \u67e5\u770b\u5f53\u524d\u7528\u6237\u7684GID\uff1a $ id -g 478 \u67e5\u770b\u5f53\u524d\u7528\u6237\u7684UID\uff1a $ id -u 1000 \u67e5\u770b\u5f53\u524d\u7528\u6237\u6240\u6709\u7ec4\u7684GID\uff1a $ id -G 478 0 \u67e5\u770b\u5f53\u524d\u7528\u6237\u540d\uff1a $ id -un vagrant \u67e5\u770b\u5f53\u524d\u7528\u6237\u7684GID $ id -ur 1000 \u53ea\u6709SELinux\u6fc0\u6d3b\u540e\u624d\u6709 $ id -Z unconfined_u:unconfined_r:unconfined_t:s0 \u7c7b\u4f3c\u4e8e whoami \u547d\u4ee4 $ id -znG wheelroot","title":"4.4.\u67e5\u770b\u7528\u6237\u4fe1\u606fid"},{"location":"linux/SRE/03-identity-security/#45su","text":"\u547d\u4ee4 su - username \u662f\u767b\u5f55\u5f0f\u5207\u6362\u7528\u6237\u3002\u4f1a\u8bfb\u53d6\u76ee\u6807\u7528\u6237\u7684\u914d\u7f6e\u6587\u4ef6\uff0c\u5207\u6362\u81f3\u76ee\u6807\u7528\u6237\u7684\u4e3b\u76ee\u5f55\u3002 \u547d\u4ee4 su username \u662f\u975e\u767b\u5f55\u5f0f\u5207\u6362\u7528\u6237\u3002\u4e0d\u8bfb\u53d6\u76ee\u6807\u7528\u6237\u7684\u914d\u7f6e\u6587\u4ef6\uff0c\u4e0d\u6539\u53d8\u5f53\u524d\u5de5\u4f5c\u76ee\u5f55\u3002 \u5207\u6362\u6210root\u7528\u6237\uff0c\u5e76\u4f7f\u7528zsh shell\u3002 su -s /usr/bin/zsh su -s /usr/bin/zsh root \u5207\u6362\u6210tester1\u7528\u6237\uff0c\u4f7f\u7528bash shell su - tester1 -s /bin/bash su - -s /bin/bash tester1 \u4fdd\u7559\u5f53\u524d\u7528\u6237\u73af\u5883\u4e0d\u53d8\u3002 su -p root \u4e0d\u4ea4\u4e92\u5f0f\u5207\u6362\u7528\u6237\uff0c\u53ea\u7528\u76ee\u6807\u7528\u6237\u6267\u884c\u67d0\u4e9b\u547d\u4ee4\u3002 su -c ps su - root -c \"getent passwd\" su - root -s /bin/bash -c \"getent passwd\" root \u7528\u6237\u5207\u6362\u81f3\u5176\u4ed6\u7528\u6237\u4e0d\u9700\u8981\u5bc6\u7801\uff0c\u975e root \u7528\u6237\u5207\u6362\u5176\u4ed6\u7528\u6237\u9700\u8981\u5bc6\u7801\u3002","title":"4.5.\u5207\u6362\u7528\u6237su"},{"location":"linux/SRE/03-identity-security/#46","text":"","title":"4.6.\u8bbe\u7f6e\u5bc6\u7801"},{"location":"linux/SRE/03-identity-security/#461passwd","text":"\u4fee\u6539\u5f53\u524d\u7528\u6237\u81ea\u5df1\u7684\u5bc6\u7801\uff1a passwd \u4fee\u6539\u5176\u4ed6\u7528\u6237\u7684\u5bc6\u7801\uff1a sudo passwd root \u67e5\u770b\u67d0\u4e2a\u7528\u6237\u5bc6\u7801\u72b6\u6001\uff1a $ sudo passwd -S root root P 10 /30/2022 -1 -1 -1 -1 $ sudo passwd -S vagrant vagrant P 10 /30/2022 0 99999 7 -1 \u68c0\u67e5\u5168\u90e8\u7528\u6237\u7684\u5bc6\u7801\u72b6\u6001\uff1a sudo passwd -Sa \u5bc6\u7801\u72b6\u6001\u8bf4\u660e\uff1a Username Status Date Last Changed Minimum Age Maximum Age Warning Period Inactivity Period vagrant P 10 /30/2022 0 99999 7 -1 root P 10 /30/2022 -1 -1 -1 -1 Status\u7684\u63cf\u8ff0\uff1a P : Usable password NP : No password L : Locked password Age\u7684\u4e00\u4e9b\u7279\u6b8a\u503c\uff1a 9999 : Never expires 0 : Can be changed at anytime -1 : Not active \u5f3a\u5236\u8981\u6c42\u7528\u6237\u4e0b\u6b21\u767b\u5f55\u65f6\u4fee\u6539\u5bc6\u7801\uff1a $ sudo passwd -e tester1 $ sudo passwd -S tester1 tester1 P 01 /01/1970 0 99999 7 -1 \u7528\u6237tester1\u7684\u5bc6\u7801\u65e5\u671f\u5df2\u7ecf\u88ab\u6539\u6210 01/01/1970 \u4e86\u3002\u8fd9\u4e2a\u65e5\u671f\u7b97\u662fUnix\u7684\u201c\u7eaa\u5143\uff08epoch\uff09\u201d\u65e5\u671f\uff0c\u610f\u5473\u7740Unix\u7684\u65e5\u671f\u8d77\u70b9\uff0c0\u5929\u3002 \u9501\u5b9a\u67d0\u4e2a\u7528\u6237\uff1a $ sudo passwd -l tester1 $ sudo passwd -S tester1 tester1 L 01 /01/1970 0 99999 7 -1 \u6b64\u65f6\u7528\u6237 tester1 \u7684\u72b6\u6001\u680f\u5df2\u7ecf\u53d8\u6210\u4e86 L \uff0c\u9501\u5b9a\u72b6\u6001\u3002 \u89e3\u9501\u67d0\u4e2a\u7528\u6237\uff1a $ sudo passwd -u tester1 $ sudo passwd -S tester1 tester1 P 01 /01/1970 0 99999 7 -1 \u6b64\u65f6\u7528\u6237 tester1 \u7684\u72b6\u6001\u680f\u5df2\u7ecf\u4ece L \u53d8\u56de\u4e86 P \uff0c\u89e3\u9664\u4e86\u9501\u5b9a\u72b6\u6001\u3002 \u5220\u9664\u7528\u6237\u5bc6\u7801\u3002\u8fd9\u4e2a\u64cd\u4f5c\u614e\u91cd\uff0c\u5bc6\u7801\u5220\u9664\u540e\u8be5\u7528\u6237\u53ef\u4ee5\u4e0d\u9700\u8981\u5bc6\u7801\u5c31\u80fd\u8bbf\u95ee\u7cfb\u7edf\u3002 $ sudo passwd -d tester1 $ sudo passwd -S tester1 tester1 NP 01 /01/1970 0 99999 7 -1 \u6b64\u65f6\u7528\u6237 tester1 \u7684\u72b6\u6001\u680f\u662f NP \u3002","title":"4.6.1.passwd"},{"location":"linux/SRE/03-identity-security/#462pwgen","text":"\u5b89\u88c5\u5305\u3002 mkpasswd\u547d\u4ee4\u6709\u6b67\u4e49\uff0c2\u4e2a\u540c\u540d\u547d\u4ee4\u5b9e\u73b0\u4e0d\u540c\u529f\u80fd\uff0c\u751f\u6210\u968f\u673a\u5bc6\u7801\u5efa\u8bae\u4f7f\u7528 pwgen \u547d\u4ee4\u3002Rocky9\u6ca1\u6709\u627e\u5230pwgen\u5305\u3002 sudo zypper in pwgen sudo apt install pwgen \u968f\u673a\u751f\u6210\u957f\u5ea68\u4f4d\u5b89\u5168\u5bc6\u7801\u3002 pwgen -s -1 \u968f\u673a\u751f\u6210\u957f\u5ea614\u4f4d\u5b89\u5168\u5bc6\u7801\u3002 pwgen -s -1 14 \u968f\u673a\u751f\u62102\u4e2a\u957f\u5ea615\u4f4d\u5b89\u5168\u5bc6\u7801\u3002 pwgen -s -1 15 2 \u968f\u673a\u751f\u62105\u4e2a\u5bc6\u7801\uff0c\u957f\u5ea610\u4f4d\uff0c\u6bcf\u4e2a\u5bc6\u7801\u81f3\u5c11\u542b\u4e00\u4e2a\u7279\u6b8a\u5b57\u7b26\uff0c\u7ed3\u679c\u4ee5\u5217\u5f62\u5f0f\u8f93\u51fa\u3002 pwgen -s -1 -y 10 5 \u751f\u6210\u957f\u5ea68\uff0c\u542b\u6709\u6570\u5b57\uff0c\u542b\u6709\u5927\u5c0f\u5199\u5b57\u6bcd\u7684\u5bc6\u78014\u4e2a\uff0c\u5217\u6253\u5370 pwgen -s -n -c -C -1 8 4 \u751f\u6210\u957f\u5ea68\uff0c\u4e0d\u542b\u6570\u5b57\uff0c\u53ea\u542b\u5c0f\u5199\u5b57\u6bcd\uff0c\u5217\u6253\u5370 pwgen -s -c -A -0 -1 8 4 \u751f\u6210\u957f\u5ea616\uff0c\u542b\u6709\u6570\u5b57\uff0c\u542b\u6709\u5927\u5c0f\u5199\u5b57\u6bcd\uff0c\u542b\u6709\u7279\u6b8a\u5b57\u7b26\u7684\u5bc6\u78013\u4e2a\uff0c\u884c\u6253\u5370 pwgen -s -n -c -y -1 16 3 \u751f\u6210\u957f\u5ea680\uff0c\u4e0d\u542b\u5143\u97f3\u548c\u6570\u5b57\uff0c\u81f3\u5c11\u542b\u6709\u4e00\u4e2a\u5927\u5199\u5b57\u6bcd\uff0c\u884c\u6253\u5370 pwgen -s -v -c -0 80 1","title":"4.6.2.pwgen"},{"location":"linux/SRE/03-identity-security/#463","text":"\u65b9\u6cd51\uff1a $ echo -e '123456\\n123456' | sudo passwd tester1 New password: BAD PASSWORD: it is too simplistic/systematic BAD PASSWORD: is too simple Retype new password: passwd: password updated successfully \u65b9\u6cd52\uff1a Rocky\u4e2d\u53ef\u4ee5\u4f7f\u7528\u4e0b\u9762\u65b9\u6cd5\u3002 pwgen -ncy1 16 1 | tee passwd.txt | sudo passwd --stdin tester1 openSUSE\u548cUbuntu\u53ef\u4ee5\u7528\u4e0b\u9762\u65b9\u6cd5\u3002 echo \"tester1:\" ` pwgen -ncy1 16 1 ` | tee passwd.txt | sudo chpasswd \u65b9\u6cd53\uff1a\u6839\u636e\u9884\u5148\u7ed9\u5b9a\u7684\u7528\u6237\u5217\u8868\uff0c\u6279\u91cf\u751f\u6210\u5bc6\u7801\u3002 $ cat > user-list.txt < user.txt < file 67274683 lrwxrwxrwx. 1 vagrant wheel 12 Nov 1 11 :20 symlinkfile1-1 -> symlinkfile1 67274682 lrwxrwxrwx. 1 vagrant wheel 4 Nov 1 10 :43 symlinkfile2 -> file 33555262 drwxr-xr-x. 2 vagrant wheel 6 Nov 1 11 :30 typelink \u4ee5 67274680 -rw-r--r--. 3 vagrant wheel 31 Nov 1 11:14 file \u4e3a\u4f8b\uff1a 67274680 : inode \u7d22\u5f15\u8282\u70b9\u7f16\u53f7\u3002 -rw-r--r-- \uff1a\u6587\u4ef6\u7c7b\u578b\u53ca\u6743\u9650 - \uff1a\u6587\u4ef6\u7c7b\u578b\uff0c\u4f8b\u5b50\u4e2d\u51fa\u73b0\u4e86\u4e09\u79cd\uff0c - \uff0c l \u548c d \u3002 - \uff1a\u666e\u901a\u6587\u4ef6 d \uff1a\u76ee\u5f55 l \uff1a\u7b26\u53f7\u94fe\u63a5\u6587\u4ef6\uff08link\uff09 b \uff1a\u5757\u8bbe\u5907\uff08block\uff09 c \uff1a\u5b57\u7b26\u8bbe\u5907\uff08character\uff09 p \uff1a\u7ba1\u9053\u6587\u4ef6\uff08pipe\uff09 s \uff1a\u5957\u63a5\u5b57\u6587\u4ef6\uff08socket\uff09 rw-r--r-- \uff1a\u6587\u4ef6\u6743\u9650\uff0c\u4ece\u5de6\u5230\u53f3\u4f9d\u6b21\u4e3a\uff1a\uff08\u7528\u6237\u7684\u6700\u7ec8\u6743\u9650\uff0c\u662f\u4ece\u5de6\u5411\u53f3\u5339\u914d\uff0c\u4e00\u65e6\u5339\u914d\u5219\u6743\u9650\u7acb\u5373\u751f\u6548\uff0c\u4e0d\u518d\u5411\u53f3\u7ee7\u7eed\u5339\u914d\uff09 rw- \uff1a\u6587\u4ef6\u5c5e\u4e3b\u6743\u9650\uff08u\uff09\uff0c\u4f8b\u5b50\u4e2d\u662f vagrant \u3002 r-- \uff1a\u6587\u4ef6\u5c5e\u7ec4\u7684\u6743\u9650\uff08g\uff09\uff0c\u4f8b\u5b50\u4e2d\u662f wheel \u3002 r-- \uff1a\u5176\u4ed6\u7ec4\u7684\u6743\u9650\uff08o\uff09\u3002 . \uff1a\u8fd9\u4e2a\u70b9\u8868\u793a\u6587\u4ef6\u5e26\u6709SELinux\u7684\u5b89\u5168\u4e0a\u4e0b\u6587\uff08SELinux Contexts\uff09\u3002\u5173\u95edSELinux\uff0c\u65b0\u521b\u5efa\u7684\u6587\u4ef6\u5c31\u4e0d\u4f1a\u518d\u6709\u8fd9\u4e2a\u70b9\u4e86\u3002\u4f46\u662f\uff0c\u4ee5\u524d\u521b\u5efa\u7684\u6587\u4ef6\u672c\u6765\u6709\u8fd9\u4e2a\u70b9\u7684\u8fd8\u4f1a\u663e\u793a\u8fd9\u4e2a\u70b9\uff08\u867d\u7136SELinux\u4e0d\u8d77\u4f5c\u7528\u4e86\uff09\u3002 3 \uff1a\u786c\u94fe\u63a5\u6570\uff0c\u4f8b\u5b50\u4e2d file \u548c hardlinkfile1 \u548c hardlinkfile2 \u4e4b\u95f4\u662f\u786c\u94fe\u63a5\uff0c\u6240\u4ee5\u8fd9\u4e09\u4e2a\u6587\u4ef6\u7684\u786c\u94fe\u63a5\u6570\u90fd\u662f 3 \u3002 vagrant \uff1a\u6587\u4ef6\u5c5e\u4e3bowner wheel \uff1a\u6587\u4ef6\u5c5e\u7ec4group 31 \uff1a\u6587\u4ef6\u6216\u76ee\u5f55\u7684\u5927\u5c0f Nov 1 11:14 \uff1a\u6587\u4ef6\u6216\u76ee\u5f55\u7684\u521b\u5efa\u65e5\u671f\u548c\u65f6\u95f4 file \uff1a\u6587\u4ef6\u6216\u76ee\u5f55\u540d\u79f0 \u4e0b\u9762\u662f\u547d\u4ee4 ls -ihl \u5728openSUSE\u548cUbuntu\u4e0a\u7684\u663e\u793a\u7ed3\u679c\u3002 $ ls -ihl 233647 -rw-r--r-- 3 vagrant wheel 31 Nov 1 15 :52 file 233647 -rw-r--r-- 3 vagrant wheel 31 Nov 1 15 :52 hardlinkfile1 233647 -rw-r--r-- 3 vagrant wheel 31 Nov 1 15 :52 hardlinkfile2 233648 lrwxrwxrwx 1 vagrant wheel 4 Nov 1 15 :52 symlinkfile1 -> file 233650 lrwxrwxrwx 1 vagrant wheel 12 Nov 1 15 :52 symlinkfile1-1 -> symlinkfile1 233649 lrwxrwxrwx 1 vagrant wheel 4 Nov 1 15 :52 symlinkfile2 -> file 233646 drwxr-xr-x 1 vagrant wheel 0 Nov 1 15 :51 typelink","title":"7.\u6743\u9650\u7ba1\u7406"},{"location":"linux/SRE/03-identity-security/#71chown","text":"chown \u547d\u4ee4\u4fee\u6539\u6587\u4ef6\u5c5e\u4e3b\uff08\u6240\u6709\u8005\uff0cowner\uff09\u3002 \u4fee\u6539\u6587\u4ef6\u5c5e\u4e3b\u4e3aroot\u3002 $ ll f1.txt -rw-r--r--. 1 vagrant wheel 41 Nov 14 22 :23 f1.txt $ sudo chown root f1.txt $ ll f1.txt -rw-r--r--. 1 root wheel 41 Nov 14 22 :23 f1.txt \u4fee\u6539\u6587\u4ef6\u7684\u5c5e\u7ec4\u4e3abin\u3002 $ sudo chown :bin f1.txt $ ll f1.txt -rw-r--r--. 1 root bin 41 Nov 14 22 :23 f1.txt \u540c\u65f6\u4fee\u6539\u6587\u4ef6\u7684\u5c5e\u4e3b\u548c\u5c5e\u7ec4\u3002 $ sudo chown vagrant.wheel f1.txt $ ll f1.txt -rw-r--r--. 1 vagrant wheel 41 Nov 14 22 :23 f1.txt \u53c2\u7167\u67d0\u6587\u4ef6\u4fee\u6539\u53e6\u4e00\u6587\u4ef6\u7684\u5c5e\u6027\u3002 $ ll file.py -rw-r--r--. 1 vagrant wheel 56 Nov 13 22 :50 file.py $ ll user.txt -rw-r--r--. 1 root bin 21 Nov 27 23 :59 user.txt $ sudo chown root.bin user.txt $ sudo chown --reference = user.txt file.py $ ll file.py -rw-r--r--. 1 root bin 56 Nov 13 22 :50 file.py \u9012\u5f52\u4fee\u6539\u6240\u6709\u5b50\u76ee\u5f55\u53ca\u6587\u4ef6\u7684\u5c5e\u4e3b\u548c\u5c5e\u7ec4\u3002 sudo chown -R vagrant.wheel ~","title":"7.1.\u4fee\u6539\u5c5e\u4e3bchown"},{"location":"linux/SRE/03-identity-security/#72chgrp","text":"\u4fee\u6539\u76ee\u5f55\u7684\u5c5e\u7ec4\u3002 sudo chgrp bin ~~ \u4fee\u6539\u76ee\u5f55\u53ca\u5b50\u76ee\u5f55\u53ca\u6587\u4ef6\u7684\u5c5e\u7ec4\u3002 sudo chgrp -R bin ~~","title":"7.2.\u4fee\u6539\u5c5e\u7ec4chgrp"},{"location":"linux/SRE/03-identity-security/#73","text":"\u6587\u4ef6\uff1a r \uff1a\u53ef\u4ee5\u8bfb\u53d6\u8be5\u6587\u4ef6\u5185\u5bb9\uff0c\u6bd4\u5982\u901a\u8fc7 cat \u547d\u4ee4\u3002 w \uff1a\u53ef\u4ee5\u4fee\u6539\u8be5\u6587\u4ef6\u5185\u5bb9\uff0c\u53ef\u4ee5\u53ea\u6709 w \u800c\u6ca1\u6709 r \u3002 x \uff1a\u53ef\u4ee5\u628a\u8be5\u6587\u4ef6\u63d0\u8bf7\u5185\u6838\u542f\u52a8\u4e3a\u4e00\u4e2a\u8fdb\u7a0b\uff0c\u5373\u53ef\u4ee5\u6267\u884c\u8be5\u6587\u4ef6\uff08\u8be5\u6587\u4ef6\u7684\u5185\u5bb9\u5fc5\u987b\u662f\u53ef\u4ee5\u6267\u884c\uff09\u3002 \u76ee\u5f55\uff1a\uff08\u5bf9\u76ee\u5f55\u800c\u8a00\uff0c\u901a\u5e38\u9700\u8981\u7ed9 r \u548c x \u6743\u9650\uff09\uff08\u4ece\u76ee\u5f55\u89d2\u5ea6\u770b\uff0c\u76ee\u5f55\u5185\u6587\u4ef6\u5217\u8868\u7b49\u4e8e\u76ee\u5f55\u8282\u70b9\u7684\u5185\u5bb9\uff09 r \uff1a\u80fd\u770b\u6587\u4ef6\u5217\u8868\uff0c\u4f46\u4e0d\u80fd\u8bbf\u95ee\u6240\u542b\u6587\u4ef6\u7684\u5185\u5bb9\u53ca\u5176\u5c5e\u6027\u4fe1\u606f\uff0c\u5305\u62ecinode\u53f7\u3002 w \uff1a\u80fd\u5728\u8be5\u76ee\u5f55\u5185\u521b\u5efa\u548c\u5220\u9664\u6587\u4ef6\uff0c\u4e0d\u7531\u76ee\u5f55\u5185\u6587\u4ef6\u672c\u8eab\u7684\u6743\u9650\u51b3\u5b9a\u3002 x \uff1a\u80fdcd\u8fdb\u76ee\u5f55\uff0c\u80fd\u901a\u8fc7 ls -l file \u548c stat file \u67e5\u770b\u8be5\u76ee\u5f55\u4e2d\u5236\u5b9a\u6587\u4ef6\u7684\u5143\u6570\u636e\u3002 X \uff1a\u8868\u793a\u53ea\u6709\u5f53\u8be5\u6587\u4ef6\u662f\u4e2a\u5b50\u76ee\u5f55\u6216\u8005\u8be5\u6587\u4ef6\u5df2\u7ecf\u88ab\u8bbe\u5b9a\u8fc7\u4e3a\u53ef\u6267\u884c\u3002 \u6709\u53ea\u8bfb\u6743\u9650\u7684\u7528\u6237\u4e0d\u80fd\u7528cd\u8fdb\u5165\u8be5\u76ee\u5f55\uff0c\u8fd8\u5fc5\u987b\u6709\u6267\u884c\u6743\u9650\u624d\u80fd\u8fdb\u5165\u3002 \u6709\u6267\u884c\u6743\u9650\u7684\u7528\u6237\u53ea\u6709\u5728\u77e5\u9053\u6587\u4ef6\u540d\uff0c\u5e76\u62e5\u6709\u8bfb\u6743\u5229\u7684\u60c5\u51b5\u4e0b\u624d\u53ef\u4ee5\u8bbf\u95ee\u76ee\u5f55\u4e0b\u7684\u6587\u4ef6\u3002 \u5fc5\u987b\u6709\u8bfb\u548c\u6267\u884c\u6743\u9650\u624d\u53ef\u4ee5ls\u5217\u51fa\u76ee\u5f55\u6e05\u5355\uff0c\u6216\u4f7f\u7528cd\u547d\u4ee4\u8fdb\u5165\u76ee\u5f55\u3002 \u6709\u76ee\u5f55\u7684\u5199\u6743\u9650\uff0c\u53ef\u4ee5\u521b\u5efa\u3001\u5220\u9664\u6216\u4fee\u6539\u76ee\u5f55\u4e0b\u7684\u4efb\u4f55\u6587\u4ef6\u6216\u5b50\u76ee\u5f55\uff0c\u5373\u4f7f\u4f7f\u8be5\u6587\u4ef6\u6216\u5b50\u76ee\u5f55\u5c5e\u4e8e\u5176\u4ed6\u7528\u6237\u4e5f\u662f\u5982\u6b64\u3002 \u5e38\u7528\u6743\u9650\u4f8b\u5b50\uff1a -rw------- ( 600 ) \u53ea\u6709\u6240\u6709\u8005\u624d\u6709\u8bfb\u548c\u5199\u7684\u6743\u9650 -rw-r--r-- ( 644 ) \u53ea\u6709\u6240\u6709\u8005\u624d\u6709\u8bfb\u548c\u5199\u7684\u6743\u9650\uff0c\u7ec4\u548c\u5176\u4ed6\u4eba\u53ea\u6709\u8bfb\u7684\u6743\u9650 -rwx------ ( 700 ) \u53ea\u6709\u6240\u6709\u8005\u624d\u6709\u8bfb\uff0c\u5199\uff0c\u6267\u884c\u7684\u6743\u9650 -rwxr-xr-x ( 755 ) \u53ea\u6709\u6240\u6709\u8005\u624d\u6709\u8bfb\uff0c\u5199\uff0c\u6267\u884c\u7684\u6743\u9650\uff0c\u7ec4\u548c\u5176\u4ed6\u4eba\u53ea\u6709\u8bfb\u548c\u6267\u884c\u7684\u6743\u9650 -rwx--x--x ( 711 ) \u53ea\u6709\u6240\u6709\u8005\u624d\u6709\u8bfb\uff0c\u5199\uff0c\u6267\u884c\u7684\u6743\u9650\uff0c\u7ec4\u548c\u5176\u4ed6\u4eba\u53ea\u6709\u6267\u884c\u7684\u6743\u9650 -rw-rw-rw- ( 666 ) \u6bcf\u4e2a\u4eba\u90fd\u6709\u8bfb\u5199\u7684\u6743\u9650 -rwxrwxrwx ( 777 ) \u6bcf\u4e2a\u4eba\u90fd\u6709\u8bfb\u5199\u548c\u6267\u884c\u7684\u6743\u9650","title":"7.3.\u6587\u4ef6\u548c\u76ee\u5f55\u6743\u9650"},{"location":"linux/SRE/03-identity-security/#74chmod","text":"\u547d\u4ee4\u683c\u5f0f\uff1a chmod [ -cfvR ] [ --help ] [ --version ] mode file mode \u5b57\u4e32\u683c\u5f0f\u4e3a\uff1a [ ugoa ][ +- =][ rwxXst ] who: u \u6587\u4ef6\u6240\u6709\u8005 g \u6587\u4ef6\u6240\u6709\u8005\u6240\u5728\u7ec4 o \u5176\u4ed6\u7528\u6237 a \u6240\u6709\u7528\u6237\uff0c\u76f8\u5f53\u4e8e ugo operator: + \u4e3a\u6307\u5b9a\u7684\u7528\u6237\u7c7b\u578b\u589e\u52a0\u6743\u9650 - \u53bb\u9664\u6307\u5b9a\u7528\u6237\u7c7b\u578b\u7684\u6743\u9650 = \u8bbe\u7f6e\u6307\u5b9a\u7528\u6237\u6743\u9650\u7684\u8bbe\u7f6e\uff0c\u5373\u5c06\u7528\u6237\u7c7b\u578b\u7684\u6240\u6709\u6743\u9650\u91cd\u65b0\u8bbe\u7f6e permission: r \u8bbe\u7f6e\u4e3a\u53ef\u8bfb\u6743\u9650 w \u8bbe\u7f6e\u4e3a\u53ef\u5199\u6743\u9650 x \u8bbe\u7f6e\u4e3a\u53ef\u6267\u884c\u6743\u9650 X \u7279\u6b8a\u6267\u884c\u6743\u9650\uff0c\u53ea\u6709\u5f53\u6587\u4ef6\u4e3a\u76ee\u5f55\u6587\u4ef6\uff0c\u6216\u8005\u5176\u4ed6\u7c7b\u578b\u7684\u7528\u6237\u6709\u53ef\u6267\u884c\u6743\u9650\u65f6\uff0c\u624d\u5c06\u6587\u4ef6\u6743\u9650\u8bbe\u7f6e\u53ef\u6267\u884c s \u5f53\u6587\u4ef6\u88ab\u6267\u884c\u65f6\uff0c\u6839\u636ewho\u53c2\u6570\u6307\u5b9a\u7684\u7528\u6237\u7c7b\u578b\u8bbe\u7f6e\u6587\u4ef6\u7684 setuid \u6216\u8005 setgid \u6743\u9650 t \u8bbe\u7f6e\u7c98\u8d34\u4f4d\uff0c\u53ea\u6709\u8d85\u7ea7\u7528\u6237\u53ef\u4ee5\u8bbe\u7f6e\u8be5\u4f4d\uff0c\u53ea\u6709\u6587\u4ef6\u6240\u6709\u8005u\u53ef\u4ee5\u4f7f\u7528\u8be5\u4f4d\u3002 \u793a\u4f8b\uff1a \u5c06\u6587\u4ef6 file1.txt \u8bbe\u4e3a\u6240\u6709\u4eba\u7686\u53ef\u8bfb\u53d6\u3002 chmod ugo+r file1.txt \u5c06\u6587\u4ef6 file1.txt \u8bbe\u4e3a\u6240\u6709\u4eba\u7686\u53ef\u8bfb\u53d6\u3002 chmod a+r file1.txt \u5c06\u6587\u4ef6 file1.txt \u4e0e file2.txt \u8bbe\u4e3a\u8be5\u6587\u4ef6\u5c5e\u4e3b\u548c\u5c5e\u7ec4\u90fd\u53ef\u5199\u5165\uff0c\u4f46\u5176\u4ed6\u7528\u6237\u4e0d\u53ef\u5199\u5165\u3002 chmod ug+w,o-w file1.txt file2.txt \u4e3a ex1.py \u6587\u4ef6\u5c5e\u4e3b\u589e\u52a0\u53ef\u6267\u884c\u6743\u9650\u3002 chmod u+x ex1.py \u5c06\u76ee\u524d\u76ee\u5f55\u4e0b\u7684\u6240\u6709\u6587\u4ef6\u4e0e\u5b50\u76ee\u5f55\u7686\u8bbe\u4e3a\u4efb\u4f55\u4eba\u53ef\u8bfb\u53d6\u3002 chmod -R a+r * \u7ed9 file \u7684\u6240\u6709\u7528\u6237\u589e\u52a0\u8bfb\u6743\u9650 chmod a+r file \u5220\u9664 file \u7684\u6240\u6709\u7528\u6237\u7684\u6267\u884c\u6743\u9650 chmod a-x file \u7ed9 file \u7684\u6240\u6709\u7528\u6237\u589e\u52a0\u8bfb\u5199\u6743\u9650 chmod a+rw file \u7ed9 file \u7684\u6240\u6709\u7528\u6237\u589e\u52a0\u8bfb\u5199\u6267\u884c\u6743\u9650 chmod +rwx file \u5bf9 file \u7684\u5c5e\u4e3b\u8bbe\u7f6e\u8bfb\u5199\u6743\u9650\uff0c\u6e05\u7a7a\u5c5e\u7ec4\u548c\u5176\u4ed6\u7528\u6237\u5bf9 file \u7684\u6240\u6709\u6743\u9650\uff08\u7a7a\u683c\u4ee3\u8868\u65e0\u6743\u9650\uff09 chmod u = rw,go = file \u5bf9\u76ee\u5f55 docs \u548c\u5176\u5b50\u76ee\u5f55\u4e2d\u7684\u6240\u6709\u6587\u4ef6\u7ed9\u5c5e\u4e3b\u589e\u52a0\u8bfb\u6743\u9650\uff0c\u800c\u5bf9\u5c5e\u7ec4\u548c\u5176\u4ed6\u7528\u6237\u5220\u9664\u8bfb\u6743\u9650 chmod -R u+r,go-r docs \u5bf9 file \u7684\u5c5e\u4e3b\u548c\u5c5e\u7ec4\u8bbe\u7f6e\u8bfb\u5199\u6743\u9650, \u4e3a\u5176\u4ed6\u7528\u6237\u8bbe\u7f6e\u8bfb\u6743\u9650 chmod 664 file \u5bf9 file \u7684\u5c5e\u4e3b\u8bbe\u7f6e\u8bfb\u5199\u6267\u884c\u6743\u9650\uff0c\u76f8\u5f53\u4e8e u=rwx (4+2+1)\uff0c\u8bbe\u7f6e\u5c5e\u7ec4\u8bfb\u548c\u6267\u884c\u6743\u9650\uff0c\u76f8\u5f53\u4e8e go=rx (4+1 & 4+1)\u3002 0 \u6ca1\u6709\u7279\u6b8a\u6a21\u5f0f chmod 0755 file 4 \u8bbe\u7f6e\u4e86\u8bbe\u7f6e\u7528\u6237ID\u4f4d\uff0c\u5269\u4e0b\u7684\u76f8\u5f53\u4e8e u=rwx (4+2+1)\u548c go=rx (4+1 & 4+1)\u3002 chmod 4755 file \u5220\u9664\u53ef\u6267\u884c\u6743\u9650\u5bf9 path/ \u4ee5\u53ca\u5176\u6240\u6709\u7684\u76ee\u5f55\uff08\u4e0d\u5305\u62ec\u6587\u4ef6\uff09\u7684\u6240\u6709\u7528\u6237\uff0c\u4f7f\u7528 -type f \u5339\u914d\u6587\u4ef6 find path/ -type d -exec chmod a-x {} \\; \u5141\u8bb8\u6240\u6709\u7528\u6237\u6d4f\u89c8\u6216\u901a\u8fc7\u76ee\u5f55 path/ find path/ -type d -exec chmod a+x {} \\;","title":"7.4.\u6743\u9650\u4fee\u6539chmod"},{"location":"linux/SRE/03-identity-security/#75umask","text":"umask \u7684\u503c\uff0c\u5b9a\u4e49\u4e86\u6240\u6709\u65b0\u5efa\u7684\u6587\u4ef6\u548c\u76ee\u5f55\u7684\u521d\u59cb\u6743\u9650\u7684\u3002 \u67e5\u770b\u5f53\u524d\u6743\u9650\u63a9\u7801\uff1a $ umask 0022 \u5728\u4e0d\u8003\u8651 umask \u7684\u60c5\u51b5\u4e0b\uff0c\u6587\u4ef6\u7684\u9ed8\u8ba4\u6743\u9650\u662f 666 (rw-rw-rw-)\uff0c\u76ee\u5f55\u7684\u9ed8\u8ba4\u6743\u9650\u662f 777 (rwxrwxrwx)\u3002 \u5728 umask \u7684\u503c\u4e3a 0022 \u7684\u60c5\u51b5\u4e0b\uff0c\u6587\u4ef6\u7684\u9ed8\u8ba4\u6743\u9650\u662f 644 (rw-r--r--)\uff0c\u76ee\u5f55\u7684\u9ed8\u8ba4\u6743\u9650\u662f 755 (rwxr-xr-x)\u3002 \u8ba1\u7b97\u65b9\u6cd5\uff1a Files: ( Default ) 6 6 6 ( umask ) 0 2 2 ---------------- ( Result ) 6 4 4 Directories: ( Default ) 7 7 7 ( umask ) 0 2 2 ---------------- ( Result ) 7 5 5 \u5982\u679c umask \u7684\u503c\u4e3a 0077 \u7684\u60c5\u51b5\u4e0b\uff0c\u6587\u4ef6\u7684\u9ed8\u8ba4\u6743\u9650\u662f 600 (rw-------)\uff0c\u76ee\u5f55\u7684\u9ed8\u8ba4\u6743\u9650\u662f 700 (rwx------)\u3002 \u8ba1\u7b97\u65b9\u6cd5\uff1a Files: ( Default ) 6 6 6 ( umask ) 0 7 7 ---------------- ( Result ) 6 0 0 Directories: ( Default ) 7 7 7 ( umask ) 0 7 7 ---------------- ( Result ) 7 0 0 \u4e3e\u4f8b\uff1a $ umask 022 $ touch file2 $ ll file2 -rw-r--r--. 1 vagrant wheel 0 Nov 28 23 :13 file2 $ umask 077 $ touch file1 $ ll file1 -rw-------. 1 vagrant wheel 0 Nov 28 23 :12 file1 $ umask 022 $ mkdir ./tmp1 $ umask 077 $ mkdir ./tmp2 $ ls -dl tmp* drwxr-xr-x. 1 vagrant wheel 0 Nov 28 23 :14 tmp1 drwx------. 1 vagrant wheel 0 Nov 28 23 :14 tmp2","title":"7.5.\u9ed8\u8ba4\u6743\u9650umask"},{"location":"linux/SRE/03-identity-security/#76","text":"\u9664\u4e86\u4e09\u79cd\u5e38\u89c1\u7684\u6743\u9650rwx\uff0c\u8fd8\u6709\u4e09\u79cd\u7279\u6b8a\u6743\u9650\uff1aSUID\uff0cSGID\uff0cSticky\u3002 SUID\uff1a\u5c5e\u4e3bs\u6743\u9650\uff0c\u79f0\u4e3aSet UID \u524d\u63d0\uff1a\u8fdb\u7a0b\u6709\u5c5e\u4e3b\u548c\u5c5e\u7ec4\uff0c\u6587\u4ef6\u6709\u5c5e\u4e3b\u548c\u5c5e\u7ec4 \u4efb\u4f55\u53ef\u6267\u884c\u7a0b\u5e8f\u6587\u4ef6\u80fd\u4e0d\u80fd\u542f\u52a8\u4e3a\u8fdb\u7a0b\uff0c\u53d6\u51b3\u4e8e\u53d1\u8d77\u8005\u5bf9\u7a0b\u5e8f\u6587\u4ef6\u662f\u5426\u62e5\u6709\u6267\u884c\u6743\u9650\u3002 \u542f\u52a8\u4e3a\u8fdb\u7a0b\u4e4b\u540e\uff0c\u5176\u8fdb\u7a0b\u7684\u5c5e\u4e3b\u4e3a\u53d1\u8d77\u8005\u3002 \u8fdb\u7a0b\u8bbf\u95ee\u6587\u4ef6\u662f\u7684\u6743\u9650\uff0c\u53d6\u51b3\u4e8e\u8fdb\u7a0b\u7684\u53d1\u8d77\u8005\u3002 \u53ea\u5bf9\u4e8c\u8fdb\u5236\u53ef\u6267\u884c\u7a0b\u5e8f\u6587\u4ef6\u6709\u6548\u3002\u5f53\u6267\u884c\u8be5\u6587\u4ef6\u65f6\uff0c\u53d1\u8d77\u8005\u5c06\u81ea\u52a8\u5177\u6709\u8be5\u6587\u4ef6\u6240\u6709\u8005\u7684\u6743\u9650\u3002 \u5bf9\u76ee\u5f55\u65e0\u6548\u3002 $ ll file1 -rw-------. 1 vagrant wheel 0 Nov 28 23 :12 file1 $ sudo chmod u+s file1 $ ll file1 -rwS------. 1 vagrant wheel 0 Nov 28 23 :12 file1 \u5982\u679c\u5c5e\u4e3b\u7684 x \u4f4d\u4e0a\u662f-\uff0c\u5219\u5728\u5c5e\u4e3b\u7684 x \u4f4d\u4e0a\u6807\u8bb0\u5927\u5199 S \uff0c\u5426\u5219\u6807\u8bb0\u5c0f\u5199 s \u3002\u5982\u4e0b\uff1a $ chmod 777 file1 $ ll file1 -rwxrwxrwx. 1 vagrant wheel 0 Nov 28 23 :12 file1 $ sudo chmod u+s file1 $ ll file1 -rwsrwxrwx. 1 vagrant wheel 0 Nov 28 23 :12 file1 \u4e0b\u97622\u7ec4\u547d\u4ee4\u5b9e\u73b0\u540c\u6837\u6548\u679c\u3002 sudo chmod 4xxx file1 chmod 777 file1 sudo chmod u+s file1 \u53d6\u6d88SUID\u3002 sudo chmod u-s file1 SGID\uff1a\u5c5e\u7ec4s\u6743\u9650\uff0c\u79f0\u4e3aSet GID \u5982\u679c\u4f5c\u7528\u4e8e\u4e8c\u8fdb\u5236\u53ef\u6267\u884c\u6587\u4ef6\u4e0a\uff0c\u5f53\u6267\u884c\u8be5\u6587\u4ef6\u4e3a\u8fdb\u7a0b\u4e4b\u540e\uff0c\u53d1\u8d77\u8005\u5c06\u81ea\u52a8\u5177\u6709\u8be5\u6587\u4ef6\u6240\u5c5e\u7ec4\u7684\u6743\u9650\uff0c\u8fdb\u7a0b\u7684\u5c5e\u7ec4\u4e3a\u53d1\u8d77\u8005\u7684\u5c5e\u7ec4\u3002 \u5982\u679c\u4f5c\u7528\u4e8e\u76ee\u5f55\u4e0a\uff0c\u5219\u8be5\u76ee\u5f55\u4e0b\u65b0\u5efa\u7acb\u7684\u76ee\u5f55\u548c\u6587\u4ef6\u90fd\u81ea\u52a8\u4ece\u6b64\u76ee\u5f55\u7ee7\u627f\u3002 $ sudo chmod g+s file2 $ ll file2 -rw-r-Sr--. 1 vagrant wheel 0 Nov 28 23 :13 file2 \u5982\u679c\u5c5e\u7ec4\u7684 x \u4f4d\u4e0a\u662f-\uff0c\u5219\u5728\u5c5e\u7ec4\u7684 x \u4f4d\u4e0a\u6807\u8bb0\u5927\u5199 S \uff0c\u5426\u5219\u6807\u8bb0\u5c0f\u5199 s \u3002\u5982\u4e0b\uff1a $ chmod 777 file2 $ ll file2 -rwxrwxrwx. 1 vagrant wheel 0 Nov 28 23 :13 file2 $ sudo chmod g+s file2 $ ll file2 -rwxrwsrwx. 1 vagrant wheel 0 Nov 28 23 :13 file2 \u4e0b\u97622\u7ec4\u547d\u4ee4\u5b9e\u73b0\u540c\u6837\u6548\u679c\u3002 sudo chmod 2xxx file2 chmod 777 file2 sudo chmod g+s file2 \u53d6\u6d88SGID\u3002 sudo chmod g-s file2 \u5bf9\u4e8e\u76ee\u5f55\uff0c\u4e0b\u9762\u6f14\u793a\u53ef\u4ee5\u770b\u5230\u76ee\u5f55\u4e0b\u7684\u6587\u4ef6\u548c\u5b50\u76ee\u5f55\u7684\u7ee7\u627f\u6027\u3002 $ ll -d data drwxr-xr-x. 1 vagrant bin 0 Nov 28 20 :55 data $ sudo chmod g+s .~ $ ll -d data drwxr-sr-x. 1 vagrant bin 0 Nov 28 20 :55 data $ cd data $ touch file2 $ ll file2 -rw-r--r--. 1 vagrant bin 0 Nov 29 21 :10 file2 $ mkdir tmp3 $ ll -d tmp3 drwxr-sr-x. 1 vagrant bin 0 Nov 29 21 :10 tmp3 Sticky Bit\uff1a\u7b80\u79f0\u4e3aSBIT\u6743\u9650 \u53ea\u9488\u5bf9\u76ee\u5f55\u6709\u6548\u3002\u5b83\u8868\u793a\u53ea\u80fd\u8ba9\u5176\u5c5e\u4e3b\u4ee5\u53caroot\u53ef\u4ee5\u5220\u9664\u3001\u91cd\u547d\u540d\u3001\u79fb\u52a8\u8be5\u76ee\u5f55\u4e0b\u7684\u6587\u4ef6\u3002 Sticky\u8bbe\u7f6e\u5728\u6587\u4ef6\u4e0a\u65e0\u610f\u4e49\u3002 \u5982\u679c\u5176\u4ed6\u7684 x \u4f4d\u4e0a\u662f-\uff0c\u5219\u5728\u5176\u4ed6\u7684 x \u4f4d\u4e0a\u6807\u8bb0\u5927\u5199 T \uff0c\u5426\u5219\u6807\u8bb0\u5c0f\u5199 t \u3002 $ ll -d .~ drwxr-sr-x. 1 vagrant bin 18 Nov 29 21 :10 .~ $ sudo chmod o+t .~ $ ll -d .~ drwxr-sr-t. 1 vagrant bin 18 Nov 29 21 :10 .~ $ cd data $ touch file1 $ mkdir tmp1 $ ll file1 -rw-r--r--. 1 vagrant bin 0 Nov 29 21 :37 file1 $ ll -d tmp1 drwxr-sr-x. 1 vagrant bin 0 Nov 29 21 :37 tmp1 \u7279\u6b8a\u6743\u9650\u8bbe\u7f6e\u6570\u5b57\u6cd5\uff1a \u8bbe\u7f6eSUID User Group Others r w s r w s r w x r w S BIN 100 1 1 1 1 1 1 1 1 1 1 1 0 OCT 4 7 7 7 6 \u8bbe\u7f6eSGID User Group Others r w x r w s r w x r w S BIN 010 1 1 1 1 1 1 1 1 1 1 1 0 OCT 2 7 7 7 6 \u8bbe\u7f6eSticky Bit - SBIT User Group Others r w x r w x r w t r w T BIN 001 1 1 1 1 1 1 1 1 1 1 1 0 OCT 1 7 7 7 6","title":"7.6.\u7279\u6b8a\u6743\u9650"},{"location":"linux/SRE/03-identity-security/#77chattr","text":"\u547d\u4ee4\u683c\u5f0f\uff1a chattr [ -RVf ] [ -v version ] [ mode ] files... \u5176\u4e2dmode\u7684\u5b57\u4e32\u683c\u5f0f\uff1a {+|-|=}[aAcCdDeijsStTu] \u5c5e\u6027 i \uff1a \u5982\u679c\u5bf9\u6587\u4ef6\u8bbe\u7f6e i \u5c5e\u6027\uff0c\u90a3\u4e48\u4e0d\u5141\u8bb8\u5bf9\u6587\u4ef6\u8fdb\u884c\u5220\u9664\u3001\u6539\u540d\uff0c\u4e5f\u4e0d\u80fd\u6dfb\u52a0\u548c\u4fee\u6539\u6570\u636e\uff1b \u5982\u679c\u5bf9\u76ee\u5f55\u8bbe\u7f6e i \u5c5e\u6027\uff0c\u90a3\u4e48\u53ea\u80fd\u4fee\u6539\u76ee\u5f55\u4e0b\u6587\u4ef6\u4e2d\u7684\u6570\u636e\uff0c\u4f46\u4e0d\u5141\u8bb8\u5efa\u7acb\u548c\u5220\u9664\u6587\u4ef6\uff1b \u5728openSUSE\u4e0b\u6267\u884c\uff0c\u5206\u533a\u6587\u4ef6\u7c7b\u578b\u662fbtrfs\u683c\u5f0f\u3002 $ touch filetest $ lsattr filetest ---------------------- filetest $ chattr +i filetest chattr: Operation not permitted while setting flags on filetest $ sudo chattr +i filetest $ lsattr filetest ----i----------------- filetest $ rm filetest rm: cannot remove 'filetest' : Operation not permitted $ sudo rm filetest rm: cannot remove 'filetest' : Operation not permitted $ echo \"test\" >> filetest -bash: filetest: Operation not permitted $ sudo echo \"test\" >> filetest -bash: filetest: Operation not permitted $ sudo chattr -i filetest \u5c5e\u6027 a \uff1a \u5982\u679c\u5bf9\u6587\u4ef6\u8bbe\u7f6e a \u5c5e\u6027\uff0c\u90a3\u4e48\u53ea\u80fd\u5728\u6587\u4ef6\u4e2d\u5897\u52a0\u6570\u636e\uff0c\u4f46\u662f\u4e0d\u80fd\u5220\u9664\u548c\u4fee\u6539\u6570\u636e\uff1b \u5982\u679c\u5bf9\u76ee\u5f55\u8bbe\u7f6e a \u5c5e\u6027\uff0c\u90a3\u4e48\u53ea\u5141\u8bb8\u5728\u76ee\u5f55\u4e2d\u5efa\u7acb\u548c\u4fee\u6539\u6587\u4ef6\uff0c\u4f46\u662f\u4e0d\u5141\u8bb8\u5220\u9664\u6587\u4ef6\uff1b \u5728openSUSE\u4e0b\u6267\u884c\uff0c\u5206\u533a\u6587\u4ef6\u7c7b\u578b\u662fbtrfs\u683c\u5f0f\u3002 lsattr filetest ---------------------- filetest $ chattr +a filetest chattr: Operation not permitted while setting flags on filetest $ sudo chattr +a filetest $ echo \"test\" >> filetest $ rm filetest rm: cannot remove 'filetest' : Operation not permitted $ sudo rm filetest rm: cannot remove 'filetest' : Operation not permitted $ sudo chattr -a filetest \u5c5e\u6027 u \uff1a \u8bbe\u7f6e\u6b64\u5c5e\u6027\u7684\u6587\u4ef6\u6216\u76ee\u5f55\uff0c\u5728\u5220\u9664\u65f6\uff0c\u5176\u5185\u5bb9\u4f1a\u88ab\u4fdd\u5b58\uff0c\u4ee5\u4fdd\u8bc1\u540e\u671f\u80fd\u591f\u6062\u590d\uff0c\u5e38\u7528\u6765\u9632\u6b62\u610f\u5916\u5220\u9664\u6587\u4ef6\u6216\u76ee\u5f55\u3002 \u5728Ubuntu\u4e0b\u6267\u884c\uff0c\u5206\u533a\u6587\u4ef6\u7c7b\u578b\u662fext4\u683c\u5f0f\u3002 $ touch filetest $ sudo chattr +u filetest $ lsattr filetest -u------------e------- filetest $ rm filetest \u5c5e\u6027 s \uff1a \u548c u \u76f8\u53cd\uff0c\u5220\u9664\u6587\u4ef6\u6216\u76ee\u5f55\u65f6\uff0c\u4f1a\u88ab\u5f7b\u5e95\u5220\u9664\uff08\u76f4\u63a5\u4ece\u786c\u76d8\u4e0a\u5220\u9664\uff0c\u7136\u540e\u75280\u586b\u5145\u6240\u5360\u7528\u7684\u533a\u57df\uff09\uff0c\u4e0d\u53ef\u6062\u590d\u3002 \u63d0\u793a\uff1a \u547d\u4ee4 chattr \u548c lsattr \u7684\u53ef\u64cd\u4f5c\u5c5e\u6027\u4f9d\u8d56\u4e8e\u6587\u4ef6\u6240\u5904\u5206\u533a\u7684\u6587\u4ef6\u7cfb\u7edf\u7c7b\u578b\uff0c\u4f8b\u5982\uff0cext4\u548cxfs\u7684\u7ed3\u679c\u4f1a\u6709\u4e0d\u540c\u3002 \u5386\u53f2\uff1a\u547d\u4ee4 chattr \uff08\u7528\u4e8e\u64cd\u4f5c\u5c5e\u6027\uff09\u548c lsattr \uff08\u7528\u4e8e\u5217\u51fa\u5c5e\u6027\uff09\u6700\u521d\u4e13\u7528\u4e8e\u7b2c\u4e8c\u4e2a\u6269\u5c55\u6587\u4ef6\u7cfb\u7edf\u7cfb\u5217\uff08ext2\u3001ext3\u3001ext4\uff09\uff0c\u5e76\u4e14\u4f5c\u4e3a e2fsprogs \u5305\u7684\u4e00\u90e8\u5206\u63d0\u4f9b\u3002\u7136\u800c\uff0c\u6b64\u529f\u80fd\u5df2\u5168\u90e8\u6216\u90e8\u5206\u6269\u5c55\u5230\u8bb8\u591a\u5176\u4ed6\u7cfb\u7edf\uff0c\u5305\u62ec XFS\u3001ReiserFS\u3001JFS \u548c OCFS2\u3002 btrfs \u6587\u4ef6\u7cfb\u7edf\u5305\u62ec\u5c5e\u6027\u529f\u80fd\uff0c\u5305\u62ec C \u6807\u5fd7\uff0c\u7531\u4e8e\u4e0e CoW \u76f8\u5173\u7684\u6027\u80fd\u8f83\u6162\uff0c\u5b83\u5173\u95ed\u4e86btrfs\u7684\u5185\u7f6e\u5199\u65f6\u590d\u5236 (CoW) \u529f\u80fd\u3002","title":"7.7.\u8bbe\u5b9a\u6587\u4ef6\u7279\u6b8a\u5c5e\u6027chattr"},{"location":"linux/SRE/03-identity-security/#8acl","text":"","title":"8.\u8bbf\u95ee\u63a7\u5236\u5217\u8868ACL"},{"location":"linux/SRE/03-identity-security/#81acl","text":"ACL\u7684\u5168\u79f0\u662fAccess Control List\u3002 \u4f20\u7edf\u7684POSIX\u6743\u9650\u6982\u5ff5\u4f7f\u7528\u4e09\u79cd\u7528\u6237\u7c7b\u578b\u6765\u5206\u914d\u6587\u4ef6\u7cfb\u7edf\u4e2d\u7684\u6743\u9650\uff1a\u6240\u6709\u8005Owning Owner\uff0c\u6240\u6709\u8005\u7ec4Owning Group\u548c\u5176\u4ed6\u7528\u6237Other Users\u3002\u53ef\u4ee5\u4e3a\u6bcf\u4e2a\u7528\u6237\u7c7b\u578b\u8bbe\u7f6e\u4e09\u4e2a\u6743\u9650\u4f4d\uff0c\u8d4b\u4e88\u8bfb\uff08r\uff09\uff0c\u5199\uff08w\uff09\u548c\u6267\u884c\uff08x\uff09\u7684\u6743\u9650\u3002 \u6240\u6709\u8005Owning Owner\u6743\u9650\uff08\u5c5e\u4e3b\u6743\u9650\uff09 \u5c5e\u7ec4Owning Group\u6743\u9650 \u5176\u4ed6\uff08\u7ecf\u8fc7\u8eab\u4efd\u9a8c\u8bc1\u7684\uff09\u7528\u6237Other Users\u7684\u6743\u9650 \u4f20\u7edf\u7684\u4e09\u79cd\u6743\u9650\u9002\u7528\u4e8e\u5927\u591a\u6570\u5b9e\u9645\u6848\u4f8b\u3002\u4f46\u662f\uff0c\u5bf9\u4e8e\u66f4\u590d\u6742\u7684\u573a\u666f\u6216\u66f4\u9ad8\u7ea7\u7684\u5e94\u7528\u7a0b\u5e8f\uff0c\u7cfb\u7edf\u7ba1\u7406\u5458\u5fc5\u987b\u4f7f\u7528\u8bb8\u591a\u6280\u5de7\u6765\u89c4\u907f\u4f20\u7edf\u6743\u9650\u7684\u9650\u5236\u3002 \u8bbf\u95ee\u63a7\u5236\u5217\u8868ACL\u63d0\u4f9b\u4e86\u5bf9\u4f20\u7edf\u6587\u4ef6\u6743\u9650\u6982\u5ff5\u7684\u6269\u5c55\u3002\u5b83\u4eec\u5141\u8bb8\u6211\u4eec\u4e3a\u5355\u4e2a\u7528\u6237\u6216\u7ec4\u5206\u914d\u6743\u9650\uff0c\u5373\u4f7f\u8fd9\u4e9b\u7528\u6237\u6216\u7ec4\u4e0e\u539f\u59cb\u6240\u6709\u8005\u6216\u5c5e\u7ec4\u4e0d\u5bf9\u5e94\u3002 ACL\u662fLinux\u5185\u6838\u7684\u4e00\u9879\u529f\u80fd\uff0c\u652f\u6301Ext\u2154/4\uff0cXFS\u548cBtrFS\u6587\u4ef6\u7cfb\u7edf\u4ee5\u53ca\u5176\u4ed6\u6587\u4ef6\u7cfb\u7edf\u3002 \u4f7f\u7528ACL\uff0c\u6211\u4eec\u53ef\u4ee5\u521b\u5efa\u590d\u6742\u7684\u65b9\u6848\uff0c\u800c\u65e0\u9700\u5728\u5e94\u7528\u7a0b\u5e8f\u7ea7\u522b\u4e0a\u53bb\u5b9e\u73b0\u590d\u6742\u7684\u6743\u9650\u6a21\u578b\u3002\u5728\u4f7f\u7528\u63d0\u4f9bSamba\u6587\u4ef6\u548c\u6253\u5370\u670d\u52a1\u7684Linux\u670d\u52a1\u5668\u66ff\u6362Windows\u670d\u52a1\u5668\u7684\u60c5\u51b5\u4e0b\uff0cACL\u7684\u4f18\u52bf\u975e\u5e38\u660e\u663e\u3002\u7531\u4e8eSamba\u652f\u6301ACL\uff0c\u56e0\u6b64\u53ef\u4ee5\u5728Linux\u670d\u52a1\u5668\u548cWindows\u4e2d\u914d\u7f6e\u7528\u6237\u6743\u9650\u3002 \u901a\u8fc7ACL\u6765\u5141\u8bb8\u5bf9\u6240\u6709\u8005\u7528\u6237\u4e4b\u5916\u7684\u5355\u4e2a\u7528\u6237\u8fdb\u884c\u6587\u4ef6\u5199\u6743\u9650\u662f\u4e00\u79cd\u7b80\u5355\u7684\u65b9\u6848\u3002\u4f7f\u7528\u4f20\u7edf\u65b9\u6cd5\uff0c\u6211\u4eec\u5fc5\u987b\u521b\u5efa\u4e00\u4e2a\u65b0\u7ec4\uff0c\u4f7f\u4e24\u4e2a\u7528\u6237\u6210\u4e3a\u8be5\u7ec4\u7684\u6210\u5458\uff0c\u5c06\u8be5\u6587\u4ef6\u7684\u6240\u6709\u7ec4\u66f4\u6539\u4e3a\u65b0\u7ec4\uff0c\u7136\u540e\u6388\u4e88\u8be5\u7ec4\u6587\u4ef6\u7684\u5199\u6743\u9650\u3002\u521b\u5efa\u7ec4\u5e76\u4f7f\u4e24\u4e2a\u7528\u6237\u6210\u4e3a\u8be5\u7ec4\u7684\u6210\u5458\u5219\u9700\u8981\u5229\u7528root\u6743\u9650\u6765\u5b9e\u73b0\u3002 \u4f7f\u7528ACL\uff0c\u6211\u4eec\u53ef\u4ee5\u901a\u8fc7\u4f7f\u6240\u6709\u8005\u548c\u6307\u5b9a\u7528\u6237\u5bf9\u6587\u4ef6\u5177\u6709\u5199\u6743\u9650\u6765\u5b9e\u73b0\u76f8\u540c\u7684\u7ed3\u679c\u3002 \u6b64\u65b9\u6cd5\u7684\u53e6\u4e00\u4e2a\u4f18\u70b9\u662f\u7cfb\u7edf\u7ba1\u7406\u5458\u65e0\u9700\u53c2\u4e0e\u521b\u5efa\u7ec4\u3002\u7528\u6237\u53ef\u4ee5\u81ea\u5df1\u51b3\u5b9a\u6388\u4e88\u8c01\u8bbf\u95ee\u5176\u6587\u4ef6\u7684\u6743\u9650\u3002 \u63d0\u793a\uff1a \u4f7f\u7528ACL\u65f6 ls \u7684\u8f93\u51fa\u7ed3\u679c\u4f1a\u53d1\u751f\u53d8\u5316\u3002\u6dfb\u52a0\u4e00\u4e2a\u52a0\u53f7+ \u6765\u8bf4\u660e\u5df2\u4e3a\u6b64\u6587\u4ef6\u5b9a\u4e49ACL\uff0c\u4e14\u5b9a\u4e49ACL\u540e\uff0c\u6240\u663e\u793a\u7684\u5c5e\u7ec4\u6743\u9650\u662fACL\u63a9\u7801\u7684\u503c\uff0c\u800c\u4e0d\u518d\u662f\u539f\u6765\u5c5e\u7ec4\u7684\u6743\u9650\u3002","title":"8.1.ACL"},{"location":"linux/SRE/03-identity-security/#82acl","text":"Minimal ACLs\uff08\u6700\u5c0fACL\uff09\uff08\u5b9e\u9645\u7528\u9014\uff1a\u4e0ePOSIX\u6743\u9650\u76f8\u540c\uff09 \u4e0e\u6587\u4ef6\u6a21\u5f0f\u6743\u9650\u4f4d\u7b49\u6548\u7684ACL\u79f0\u4e3a\u6700\u5c0fACL \u5206\u4e09\u79cd\u7c7b\u578b\u7684ACL\u6761\u76ee\uff0c\u8fd9\u4e9b\u5bf9\u5e94\u4e8e\u6587\u4ef6\u548c\u76ee\u5f55\u7684\u4f20\u7edf\u6743\u9650\u4f4d Owning User \u6240\u6709\u8005 Owning Group \u6240\u6709\u8005\u7ec4 Others \u5176\u4ed6\u7ec4 Extended ACLs\uff08\u6269\u5c55ACL\uff09 \u5177\u6709\u591a\u4e8e\u4e0a\u8ff0\u4e09\u4e2aACL\u6761\u76ee\u7684ACL\u79f0\u4e3a\u6269\u5c55ACL \u6269\u5c55ACL\u8fd8\u5305\u542b\u63a9\u7801\u6761\u76ee\uff0c\u53ef\u4ee5\u5305\u542b\u4efb\u610f\u6570\u91cf\u7684\u6307\u5b9a\u7528\u6237\u548c\u6307\u5b9a\u7ec4\u6761\u76ee","title":"8.2.ACL\u7684\u57fa\u672c\u7c7b\u578b"},{"location":"linux/SRE/03-identity-security/#83acl","text":"\u7528\u6237\u7c7b\uff08User classes\uff09\u3002 \u4f20\u7edf\u7684POSIX\u6743\u9650\u6982\u5ff5\u4f7f\u7528\u4e09\u79cd\u7528\u6237\u7c7b\u6765\u5206\u914d\u6587\u4ef6\u7cfb\u7edf\u4e2d\u7684\u6743\u9650\uff1a\u6240\u6709\u8005Owning Owner\uff0c\u6240\u6709\u8005\u7ec4Owning Group\u548c\u5176\u4ed6\u7528\u6237Other Users\u3002\u53ef\u4ee5\u4e3a\u6bcf\u4e2a\u7528\u6237\u7c7b\u578b\u8bbe\u7f6e\u4e09\u4e2a\u6743\u9650\u4f4d\uff0c\u8d4b\u4e88\u8bfb\uff08r\uff09\uff0c\u5199\uff08w\uff09\u548c\u6267\u884c\uff08x\uff09\u7684\u6743\u9650\u3002 Owner class \u6240\u6709\u8005\u7c7b Group class \u7ec4\u7c7b Other class \u5176\u4ed6\u7c7b ACL\u8bbf\u95ee\u6743\u9650\uff08Access ACL\uff09\uff1a\u786e\u5b9a\u5404\u79cd\u6587\u4ef6\u7cfb\u7edf\u5bf9\u8c61\uff08\u6587\u4ef6\u548c\u76ee\u5f55\uff09\u7684\u7528\u6237\u548c\u7ec4\u7684\u8bbf\u95ee\u6743\u9650\u3002 \u9ed8\u8ba4ACL\uff08Default ACL\uff09\uff1a\u53ea\u80fd\u5e94\u7528\u4e8e\u76ee\u5f55\u3002 \u5b83\u4eec\u786e\u5b9a\u6587\u4ef6\u7cfb\u7edf\u5bf9\u8c61\u5728\u521b\u5efa\u65f6\u4ece\u5176\u7236\u76ee\u5f55\u7ee7\u627f\u7684\u6743\u9650\u3002 ACL\u6761\u76ee\uff08ACL entry\uff09\uff1a \u6bcf\u4e2aACL\u7531\u4e00\u7ec4ACL\u6761\u76ee\u7ec4\u6210\u3002 ACL\u6761\u76ee\u5305\u542b\u7c7b\u578b\uff08type\uff09\uff0c\u6761\u76ee\u5f15\u7528\u7684\u7528\u6237\u6216\u7ec4\u7684\u9650\u5b9a\u7b26\uff08qualifier\uff09\uff0c\u4ee5\u53ca\u4e00\u7ec4\u6743\u9650\uff08permissions\uff09\u3002 \u5bf9\u4e8e\u67d0\u4e9b\u6761\u76ee\u7c7b\u578b\uff0c\u672a\u5b9a\u4e49\u7ec4\u6216\u7528\u6237\u7684\u9650\u5b9a\u7b26\u3002","title":"8.3.ACL\u672f\u8bed"},{"location":"linux/SRE/03-identity-security/#84acl","text":"Named user \u6307\u5b9a\u7528\u6237: Lets you assign permissions to individual users. \u5141\u8bb8\u6211\u4eec\u4e3a\u6307\u5b9a\u7528\u6237\u5206\u914d\u6743\u9650\u3002 Named group \u6307\u5b9a\u7ec4: Lets you assign permissions to individual groups. \u5141\u8bb8\u6211\u4eec\u4e3a\u5236\u5b9a\u7ec4\u5206\u914d\u6743\u9650\u3002 Mask \u63a9\u7801: Lets you limit the permissions granted to named users or groups. \u5141\u8bb8\u6211\u4eec\u9650\u5236\u7ed9\u4e88\u6307\u5b9a\u7528\u6237\u6216\u6307\u5b9a\u7ec4\u7684\u6743\u9650\u3002 \u6240\u4ee5\u53ef\u80fd\u7684ACL\u7c7b\u578b Type Text Form owner user::rwx named user user:name:rwx owning group group::rwx named group group:name:rwx mask mask::rwx other other::rwx \u4e0ePOSIX.1\u6743\u9650\u6a21\u578b\u4e0d\u540c\uff0c\u7ec4\u7c7bgroup class\u53ef\u4ee5\u5305\u542b\u5177\u6709\u4e0d\u540c\u6743\u9650\u96c6\u7684ACL\u6761\u76ee\uff0c\u56e0\u6b64\u5355\u72ec\u7684\u7ec4\u7c7b\u6743\u9650\u4e0d\u518d\u8db3\u4ee5\u8868\u793a\u5b83\u5305\u542b\u7684\u6240\u6709ACL\u6761\u76ee\u7684\u6240\u6709\u8be6\u7ec6\u6743\u9650\u3002 \u56e0\u6b64\uff0c\u7ec4\u7c7b\u578b\u6743\u9650\u7684\u542b\u4e49\u88ab\u91cd\u65b0\u5b9a\u4e49\u3002\u5728\u65b0\u8bed\u4e49\u4e0b\uff0c\u7ec4\u7c7b\u578b\u6743\u9650\u8868\u793a\u7ec4\u7c7b\u4e2d\u7684\u4efb\u4f55\u6761\u76ee\u5c06\u6388\u4e88\u7684\u6743\u9650\u7684**\u4e0a\u9650**\uff08upper bound\uff09\u3002 \u6b64\u4e0a\u9650\u5c5e\u6027\u53ef\u786e\u4fdd\u5728\u4f7f\u7528ACL\u63a7\u5236\u540e\uff0c\u5e94\u7528\u7a0b\u5e8f\u4e0d\u4f1a\u7a81\u7136\u6216\u8005\u610f\u5916\u5730\u6388\u4e88\u989d\u5916\u7684\u6743\u9650\u3002 \u5728\u6700\u5c0fACL\u4e2d\uff0c\u7ec4\u7c7b\u6743\u9650\u4e0e\u6240\u6709\u8005\u7ec4\u6743\u9650\u76f8\u540c\u3002\u5728\u6269\u5c55ACL\u4e2d\uff0c\u7ec4\u7c7b\u53ef\u4ee5\u5305\u542b\u5176\u4ed6\u7528\u6237\u6216\u7ec4\u7684\u6761\u76ee\u3002\u8fd9\u4f1a\u5bfc\u81f4\u4e00\u4e2a\u95ee\u9898\uff1a\u8fd9\u4e9b\u9644\u52a0\u6761\u76ee\u4e2d\u7684\u4e00\u4e9b\u53ef\u80fd\u62e5\u6709\u672a\u5305\u542b\u5728\u6240\u6709\u8005\u7ec4\u6761\u76ee\uff08owning group entry\uff09\u4e2d\u7684\u6743\u9650\uff0c\u56e0\u6b64\u6240\u6709\u8005\u7ec4\u6761\u76ee\u6743\u9650\u53ef\u80fd\u4e0e\u7ec4\u7c7b\u6743\u9650\uff08group class\uff09\u4e0d\u540c\u3002 \u901a\u8fc7\u63a9\u7801\uff08mask entry\uff09\u89e3\u51b3\u4e86\u8fd9\u4e2a\u95ee\u9898\u3002 \u4f7f\u7528\u6700\u5c0fACL\uff0c\u7ec4\u7c7b\u6743\u9650\u6620\u5c04\u5230\u6240\u6709\u8005\u7ec4\u6761\u76ee\u6743\u9650\u3002With minimal ACLs, the group class permissions map to the owning group entry permissions. \u4f7f\u7528\u6269\u5c55ACL\u65f6\uff0c\u7ec4\u7c7b\u6743\u9650\u6620\u5c04\u5230\u63a9\u7801\u6761\u76ee\u6743\u9650\uff0c\u800c\u6240\u6709\u8005\u7ec4\u6761\u76ee\u4ecd\u5b9a\u4e49\u62e5\u6709\u7ec4\u6743\u9650\u3002With extended ACLs, the group class permissions map to the mask entry permissions, whereas the owning group entry still defines the owning group permissions.","title":"8.4.ACL\u6743\u9650\u5206\u7c7b"},{"location":"linux/SRE/03-identity-security/#85acl","text":"\u8bbe\u5b9aACL\u6743\u9650\uff1a setfacl Syntax: setfacl [OPTIONS] [ACL-ENTRIES] Option Description -m : Add or modify an ACL entry -x : Remove an ACL entry -d : Set a default ACL -b : Remove all extended ACL entries -M : restore ACLs that have been written to a file \u6ce8\u610f\uff1a--set\u9009\u9879\u4f1a\u628a\u539f\u6709\u7684ACL\u9879\u90fd\u5220\u9664\uff0c\u7528\u65b0\u7684\u66ff\u4ee3\uff0c\u6240\u4ee5\u4e00\u5b9a\u8981\u5305\u542bUGO\u7684\u8bbe\u7f6e\uff0c\u4e0d\u80fd\u50cf-m\u533b\u9662\u53ea\u6dfb\u52a0ACL\u3002 setfacl --set u::rw,u:vagrant:rw,g::r,o::- file1 \u8bfb\u53d6ACL\u6743\u9650\uff1a getfacl Syntax: getfacl [OPTIONS] Option Description -a : Display the file access control list -d : Display the default access control list -R : List the ACLs of all files and directories recursively","title":"8.5.ACL\u64cd\u4f5c\u547d\u4ee4"},{"location":"linux/SRE/03-identity-security/#86acl","text":"","title":"8.6.ACL\u5b9e\u4f8b\u89e3\u6790"},{"location":"linux/SRE/03-identity-security/#861","text":"\u9879\u76ee\u76ee\u5f55 ~/project1 \u9879\u76ee\u7ecf\u7406 pm1 \u5bf9\u8fd9\u4e2a\u76ee\u5f55\u62e5\u6709\u8bbf\u95ee\u548c\u4fee\u6539\u6743\u9650 \u9879\u76ee\u6210\u5458 tm1 \u53ef\u4ee5\u8bbf\u95ee\u548c\u4fee\u6539\u8fd9\u4e2a\u76ee\u5f55 \u975e\u9879\u76ee\u6210\u5458 tm2 \u4e0d\u80fd\u8bbf\u95ee ~/project1 \u76ee\u5f55\u3002 \u9879\u76ee\u76ee\u5f55 ~/project1 \u7684\u6743\u9650\u89c4\u5212 \u9879\u76ee\u7ecf\u7406 pm1 \u662f\u8fd9\u4e2a\u76ee\u5f55\u7684\u5c5e\u4e3b\uff0c\u6743\u9650\u4e3a rwx \u9879\u76ee\u7ecf\u7406 pm1 \u5c5e\u4e8e project1 \u7ec4 \u9879\u76ee\u6210\u5458 tm1 \u4e0e pm1 \u5728\u540c\u4e00\u4e2a project1 \u7ec4\uff0c\u6743\u9650\u662f rw \u5176\u4ed6\u4eba\u7684\u6743\u9650\u8bbe\u5b9a\u4e3a 0 \u9879\u76ee\u4e34\u65f6\u6210\u5458tm2\u7684\u6743\u9650\u9700\u6c42 \u80fd\u8bbf\u95ee project1 \u76ee\u5f55\uff0c\u4f46\u53ea\u80fd\u5177\u6709 r \u548c x \u6743\u9650 \u89e3\u51b3\u65b9\u6cd5 \u5f53\u51fa\u73b0\u8fd9\u79cd\u60c5\u51b5\u65f6\uff0c\u666e\u901a\u6743\u9650\u4e2d\u7684\u4e09\u79cd\u8eab\u4efd\uff08owner\uff0cgroup\uff0cothers\uff09\u5c31\u4e0d\u80fd\u89e3\u51b3\u8fd9\u4e2a\u95ee\u9898\uff0c\u800cACL\u6743\u9650\u53ef\u4ee5\u3002 \u5728\u4f7f\u7528ACL\u6743\u9650\u7ed9\u7528\u6237 tm2 \u965a\u4e88\u6743\u9650\u65f6\uff0c tm2 \u65e2\u4e0d\u662f ~/project1 \u76ee\u5f55\u7684\u5c5e\u4e3b\uff0c\u4e5f\u4e0d\u662f\u5c5e\u7ec4\uff0c\u4ec5\u4ec5\u8d4b\u4e88\u7528\u6237 tm2 \u9488\u5bf9 ~/project1 \u76ee\u5f55\u7684r-x\u6743\u9650\uff0c \u5c5e\u4e8e\u5355\u72ec\u6307\u5b9a\u7528\u6237\u5e76\u5355\u72ec\u5206\u914d\u6743\u9650\uff0c\u89e3\u51b3\u4e86\u7528\u6237\u8eab\u4efd\u4e0d\u8db3\u7684\u95ee\u9898\u3002 \u62d3\u5c55\u95ee\u9898 \u7ed9 ~/project1 \u76ee\u5f55\u6dfb\u52a0\u5176\u4ed6\u7ec4 project2 \u7684\u8bbf\u95ee\u6743\u9650 \u901a\u8fc7 mask \u6765\u8c03\u6574\u7528\u6237 tm2 \u5b9e\u9645\u6709\u6548\u6743\u9650 \u9ed8\u8ba4ACL\u6743\u9650 \u9012\u5f52ACL\u6743\u9650 \u5220\u9664ACL\u6743\u9650","title":"8.6.1.\u5b9e\u4f8b\u63cf\u8ff0"},{"location":"linux/SRE/03-identity-security/#862","text":"\u521b\u5efa\u6d4b\u8bd5\u7528\u6237 $ whoami vagrant $ sudo groupadd project1 $ sudo groupadd project2 $ sudo useradd -m -g project1 pm1 $ sudo useradd -m -g project1 tm1 $ sudo useradd -m -g project2 tm2 $ sudo passwd pm1 $ sudo passwd tm1 $ sudo passwd tm2 $ cat /etc/group ...... project1:x:1535: project2:x:1536: ...... $ cat /etc/passwd ...... pm1:x:2003:1535::/home/pm1:/bin/bash tm1:x:2004:1535::/home/tm1:/bin/bash tm2:x:2005:1536::/home/tm2:/bin/bash ...... \u521b\u5efa\u6d4b\u8bd5\u76ee\u5f55 project1 , \u6307\u5b9a project1 \u76ee\u5f55\u7684\u6743\u9650\uff0c\u521b\u5efa\u6d4b\u8bd5\u6587\u4ef6 file1 \u3002 $ su - pm1 $ cd ~ $ mkdir project1 $ ls -dl project1 drwxr-xr-x. 1 pm1 project1 0 Dec 4 06 :25 project1 $ chmod 770 project1/ $ ls -dl project1 drwxrwx---. 1 pm1 project1 0 Dec 4 06 :25 project1 $ echo \"hello from $USER \" > ./project1/file1 $ cat ./project1/file1 hello from pm1 \u76ee\u5f55 project1 \u5f53\u524d\u6743\u9650\u5feb\u7167 \u5c5e\u4e3b\uff1a pm1 \uff0c\u5bf9 ~/project1 \u76ee\u5f55\u6709 rwx \u6743\u9650 \u5c5e\u7ec4\uff1a project1 \uff0c\u5305\u542b\u7528\u6237 pm1 \u548c tm1 \uff0c\u5bf9 ~/project1 \u76ee\u5f55\u6709 rwx \u6743\u9650 \u5176\u4ed6\u7ec4\uff1a\u6ca1\u6709\u8bbf\u95ee\u6743\u9650 \u76ee\u5f55 ~/project1 \u5f53\u524d\u7684ACL\u5feb\u7167 $ getfacl ./project1/ # file: home/pm1/project1/ # owner: pm1 # group: project1 user::rwx group::rwx other::---","title":"8.6.2.\u521d\u59cb\u5316\u73af\u5883"},{"location":"linux/SRE/03-identity-security/#863acl","text":"\u7ed9 ~/project1 \u76ee\u5f55\u6dfb\u52a0\u65b0\u7528\u6237 tm2 \uff0c\u6743\u9650\u4e3a rwx \u3002\u76ee\u5f55 ~/project1 \u7684\u66f4\u65b0\u540e\u7684\u6743\u9650\u4f4d\u53d8\u6210\u4e86 drwxrwx---+ \u3002 $ su - pm1 $ setfacl -m u:tm2:rx ./project1/ $ ls -dl ./project1 drwxrwx---+ 1 pm1 project1 0 Dec 4 06 :25 project1 $ getfacl ~/project1/ # file: project1 \uff08\u6587\u4ef6\u540d\uff09 # owner: pm1 \uff08Owner \u6587\u4ef6\u5c5e\u4e3b\uff09 # group: project1 \uff08Owing Group \u6587\u4ef6\u5c5e\u7ec4\uff09 user::rwx \uff08Ower\u6587\u4ef6\u5c5e\u4e3b\u7684\u6743\u9650\uff0c\u7528\u6237\u540d\u680f\u662f\u7a7a\u7684\uff0c\u8bf4\u660e\u662f\u5c5e\u4e3bOwner\u7684\u6743\u9650\uff09 user:tm2:r-x \uff08Named User \u6307\u5b9a\u7528\u6237\u7684\u6743\u9650\uff0c\u7528\u6237tm2\u7684\u6743\u9650\uff09 group::rwx \uff08Owing Group \u6587\u4ef6\u5c5e\u7ec4\u7684\u6743\u9650\uff0c\u7ec4\u540d\u680f\u662f\u7a7a\u7684\uff0c\u8bf4\u660e\u662f\u5c5e\u7ec4\u7684\u6743\u9650\uff09 \uff08Named Group \u6307\u5b9a\u7528\u6237\u7ec4\u7684\u6743\u9650\uff0c\u6b64\u65f6\u672a\u6307\u5b9a\uff09 mask::rwx \uff08mask\u6743\u9650\uff09 other::--- \uff08\u5176\u4ed6\u4ebaother\u7684\u6743\u9650\uff09 \u7ed9 ~/project1 \u76ee\u5f55\u6dfb\u52a0\u65b0\u7ec4 project2 \u7684\u6743\u9650 rwx $ su - pm1 $ setfacl -m g:project2:rwx ./project1/ $ ls -dl ./project1 drwxrwx---+ 1 pm1 project1 0 Dec 4 06 :46 ./project1 $ getfacl ./project1 # file: project1 # owner: pm1 # group: project1 user::rwx user:tm2:r-x ( \u7528\u6237tm2\u62e5\u6709\u4e86r-x\u6743\u9650\uff09 group::rwx group:project2:rwx ( \u7528\u6237\u7ec4project2\u62e5\u6709\u4e86rwx\u6743\u9650\uff09 mask::rwx other::--- \u6709\u6548\u6743\u9650\u7684\u8ba1\u7b97\uff1a \u5f53\u524d ~/project1 \u76ee\u5f55\u7684 mask \u662f rwx \uff0c tm2 \u7684\u6743\u9650\u662f r-x \uff0c\u4e8c\u8005\u8fdb\u884cAND\u64cd\u4f5c\uff0c tm2 \u7684\u5b9e\u9645\u6743\u9650\u662f r-x tm2: r - x ( 1 0 1 ) mask: r w x ( 1 1 1 ) --------------------- result: r - x ( 1 0 1 ) \u5bf9\u7167\u4e0b\u9762\u7684\u89c4\u5219\uff0c\u9a8c\u8bc1\u7528\u6237 tm2 \u5bf9 ~/project1 \u76ee\u5f55\u7684\u5b9e\u9645\u6743\u9650\u3002 su - tm2 \u80fd\u8fdb\u5165\u76ee\u5f55 project1 \uff0c\u8bf4\u660e\u5f53\u524d\u7528\u6237\u5177\u6709\u76ee\u5f55 project1 \u7684 r-x \u6743\u9650\u3002 $ whoami tm2 $ cd /home/pm1/project1/ \u80fd\u5217\u51fa\u76ee\u5f55 project1 \u4e0b\u6587\u4ef6\u5217\u8868\uff0c\u53ef\u4ee5\u67e5\u770b\u6587\u4ef6 file \u7684\u5185\u5bb9\uff0c\u8bf4\u660e\u5f53\u524d\u7528\u6237\u5177\u6709\u76ee\u5f55 project1 \u7684 r-x \u6743\u9650\u3002 $ pwd /home/pm1/project1 $ whoami tm2 $ ls -l -rw-r--r--. 1 pm1 project1 15 Dec 4 07 :15 file1 $ cat file1 hello from pm1 \u5bf9\u76ee\u5f55 project1 \u4e0d\u5177\u6709 w \u6743\u9650\uff0c\u6240\u4ee5\u65e0\u6cd5\u521b\u5efa\u3001\u5220\u9664\u6216\u4fee\u6539\u76ee\u5f55\u4e0b\u7684\u4efb\u4f55\u6587\u4ef6\u6216\u5b50\u76ee\u5f55\u3002 $ pwd /home/pm1/project1 $ whoami tm2 $ touch file2 touch: cannot touch 'file2' : Permission denied $ echo \"hello from $USER \" >> file1 -bash: file1: Permission denied","title":"8.6.3.\u6dfb\u52a0ACL\u6743\u9650"},{"location":"linux/SRE/03-identity-security/#864mask","text":"\u8c03\u6574 ~/project1 \u76ee\u5f55\u7684 mask \u4e3a r-- \uff0c\u5219 tm2 \u7684\u5b9e\u9645\u6743\u9650\u662f r-- $ su - pm1 $ cd ~ $ setfacl -m m::r ./project1/ $ getfacl ./project1/ # file: project1/ # owner: pm1 # group: project1 user::rwx user:tm2:r-x #effective:r-- (\u7528\u6237tm2\u7684\u5b9e\u9645\u6709\u6548\u6743\u9650\u53d8\u4e3ar--) group::rwx #effective:r-- (\u5c5e\u7ec4project1\u7ec4\u7684\u5b9e\u9645\u6709\u6548\u6743\u9650\u53d8\u4e3ar--) group:project2:rwx #effective:r-- (\u5176\u4ed6\u7ec4project2\u7ec4\u7684\u5b9e\u9645\u6709\u6548\u6743\u9650\u53d8\u4e3ar--) mask::r-- ( mask\u53d8\u5316\uff0c\u5bfc\u81f4\u4e0a\u8ff0\u4e24\u4e2agroup\u7684\u6709\u6548\u6743\u9650\u90fd\u53d1\u751f\u4e86\u53d8\u5316 ) other::--- \u6709\u6548\u6743\u9650\u7684\u8ba1\u7b97\uff1a \u5f53\u524d ~/project1 \u76ee\u5f55\u7684 mask \u662f r-- \uff0c\u7528\u6237 tm2 \u3001\u7ec4 project2 \u7684\u5b9e\u9645\u6743\u9650\u662f r-- \u3002 tm2: r - w ( 1 0 1 ) mask: r - - ( 1 0 0 ) --------------------- result: r - - ( 1 0 0 ) \u63d0\u793a\uff1a \u7528\u6237\u548c\u7528\u6237\u7ec4\u6240\u8bbe\u5b9a\u7684\u6743\u9650\u5fc5\u987b\u5728mask\u6743\u9650\u8bbe\u5b9a\u7684\u8303\u56f4\u4e4b\u5185\u624d\u80fd\u751f\u6548\uff0cmask\u6743\u9650\u5c31\u662f\u6700\u5927\u6709\u6548\u6743\u9650\u3002","title":"8.6.4.\u4fee\u6539mask\u6743\u9650"},{"location":"linux/SRE/03-identity-security/#865","text":"\u5728POSIX\u6743\u9650\u6a21\u578b\u548cACL\u6743\u9650\u53e0\u52a0\u4f5c\u7528\u4e0b\uff0c\u7528\u6237\u7684\u5b9e\u9645\u6743\u9650\u5206\u6790\u3002 $ getfacl ./project1/ # file: project1/ # owner: pm1 <----Owner # group: project1 <----owning group user::rwx <----owner 's permissions user:tm2:r-x #effective:r-- <----named user' s permissions group::rwx #effective:r-- <----owning group's permissions group:project2:rwx #effective:r-- <----named group's permissions mask::r-- <----masks for named user and named group other::--- default:user::rwx default:user:tm2:r-x default:group::rwx default:mask::rwx default:other::--- \u6240\u6709\u8005ower\u548c\u5176\u4ed6\u7528\u6237other\u6761\u76ee\u4e2d\u5b9a\u4e49\u7684\u6743\u9650\u603b\u662f\u6709\u6548\u7684\u3002\u4e0a\u4f8b\u4e2d\u7684user\u6761\u76ee\u548cother\u6761\u76ee\u3002 \u9664\u4e86\u63a9\u7801\u6761\u76ee\uff0c\u6240\u6709\u5176\u4ed6\u6761\u76ee\uff08\u6bd4\u5982\u6307\u5b9a\u7528\u6237named user\uff09\u53ef\u4ee5\u662f\u6709\u6548\u7684\u6216\u88ab\u5c4f\u853d\u7684\u3002 \u6307\u5b9a\u7528\u6237\uff08named user\uff09\uff0c\u6240\u6709\u8005\u7ec4\uff08owning group\uff09\u6216\u6307\u5b9a\u7ec4\uff08named group\uff09\u4ee5\u53ca\u63a9\u7801mask\u6761\u76ee\u4e2d\u5b9a\u4e49\u7684\u6743\u9650\uff0c\u6709\u6548\u6743\u9650\u662f\u4ed6\u4eec\u6743\u9650\u8fdb\u884c\u903b\u8f91AND\u540e\u7684\u7ed3\u679c\uff0c\u800c\u4e0d\u662f\u5355\u72ec\u7684\u63a9\u7801\u4e2d\u5b9a\u4e49\u7684\u6743\u9650\u6216\u8005\u5404\u81ea\u6761\u76ee\u4e2d\u5b9a\u4e49\u7684\u6743\u3002 \u6709\u6548\u6743\u9650\u8ba1\u7b97\u65b9\u6cd5\u5982\u4e0b\uff0c\u6ce8\u610f\uff0c ls \u547d\u4ee4\u4e2d\u663e\u793a\u51fa\u6765\u7684\u6743\u9650\uff0c\u4e0e\u5b9e\u9645\u7684ACL\u6743\u9650\u662f\u6709\u5dee\u522b\u7684\u3002 tm2: r - w ( 1 0 1 ) group: r w x ( 1 1 1 ) named group: r w x ( 1 1 1 ) mask: r - - ( 1 0 0 ) --------------------------- result: r - - ( 1 0 0 ) \u5c0f\u8d34\u58eb\uff1a \u4e0e\u6587\u4ef6\u6a21\u5f0f\u6743\u9650\u4f4d\u7b49\u6548\u7684ACL\u79f0\u4e3a\u6700\u5c0fACL\uff0c\u5373POSIX\u4f20\u7edf\u6743\u9650\u3002 \u542b\u63a9\u7801mask\u7b49\u5176\u4ed6\u6743\u9650\u6761\u76ee\u7684ACL\u79f0\u4e3a\u6269\u5c55ACL\u3002 \u5728\u6700\u5c0f\u548c\u6269\u5c55ACL\u60c5\u5f62\u4e0b\uff0c\u6240\u6709\u8005\u7c7b\u6743\u9650\uff08owner\uff09\u90fd\u662f\u6620\u5c04\u5230ACL\u7684\u6240\u6709\u8005\u6761\u76ee\u3002 \u5176\u4ed6\u7c7b\u6743\u9650\u6620\u5c04\u5230\u5176\u5404\u81ea\u7684ACL\u6761\u76ee\u3002 \u5728\u6269\u5c55ACL\u60c5\u5f62\u4e0b\uff0c\u7ec4\u7c7b\u6743\u9650\u7684\u6620\u5c04\u662f\u4e0d\u540c\u7684\u3002 \u5bf9\u4e8e\u6ca1\u6709\u63a9\u7801\u7684\u6700\u5c0fACL\uff0c\u7ec4\u7c7b\u6743\u9650\u5c06\u6620\u5c04\u5230ACL\u6240\u6709\u8005\u7ec4\u6761\u76ee\u3002 \u5bf9\u4e8e\u5e26\u6709\u63a9\u7801\u7684\u6269\u5c55ACL\uff0c\u7ec4\u7c7b\u6743\u9650\u5c06\u6620\u5c04\u5230\u63a9\u7801\u6761\u76ee\u3002 \u901a\u8fc7\u6743\u9650\u4f4d\u8fdb\u884c\u5206\u914d\u7684\u6743\u9650\u4ee3\u8868\u4e86\u901a\u8fc7ACL\u8fdb\u884c\u5206\u914d\u7684\u6743\u9650\u7684\u4e0a\u9650\u3002 \u6ca1\u6709\u5728\u8fd9\u91cc\u4f53\u73b0\u7684\u4efb\u4f55\u6743\u9650\uff0c\u8981\u4e48\u4e0d\u5728ACL\u4e2d\uff0c\u8981\u4e48\u65e0\u6548\u3002 \u5bf9\u6743\u9650\u4f4d\u6240\u505a\u7684\u66f4\u6539\u5c06\u7531ACL\u53cd\u6620\uff0c\u53cd\u4e4b\u4ea6\u7136\u3002","title":"8.6.5.\u6709\u6548\u6743\u9650\u5206\u6790"},{"location":"linux/SRE/03-identity-security/#866acl","text":"$ su - pm1 $ touch ./project1/file2 $ mkdir ./project1/cloud $ ll ./project1/ drwxr-xr-x. 1 pm1 project1 0 Dec 4 08 :52 cloud -rw-r--r--. 1 pm1 project1 15 Dec 4 07 :15 file1 -rw-r--r--. 1 pm1 project1 0 Dec 4 08 :52 file2 $ ll -d project1/ drwxr-----+ 1 pm1 project1 30 Dec 4 08 :52 project1/ \u6587\u4ef6 file1 \u548c\u76ee\u5f55 cloud \u6ca1\u6709\u7ee7\u627f project1 \u76ee\u5f55\u7684ACL\u6743\u9650\u3002 \u63d0\u793a\uff1a \u9ed8\u8ba4 ACL\u9650\u53ea\u5bf9\u76ee\u5f55\u751f\u6548\u3002 \u9ed8\u8ba4ACL\u6743\u9650\u7684\u4f5c\u7528\u662f\uff1a\u5982\u679c\u7ed9\u7236\u76ee\u5f55\u8bbe\u5b9a\u4e86\u9ed8\u8ba4 ACL \u6743\u9650\uff0c\u90a3\u4e48\u7236\u76ee\u5f55\u4e2d\u6240\u6709\u65b0\u5efa\u7684\u5b50\u6587\u4ef6\u90fd\u4f1a\u7ee7\u627f\u7236\u76ee\u5f55\u7684ACL\u6743\u9650\u3002 \u4e0b\u9762\u589e\u52a0 ~/project1 \u76ee\u5f55\u7684\u9ed8\u8ba4ACL\u6743\u9650\u3002 $ su - pm1 $ cd ~ $ getfacl ./project1/ # file: project1/ # owner: pm1 # group: project1 user::rwx user:tm2:r-x #effective:r-- group::rwx #effective:r-- group:project2:rwx #effective:r-- mask::r-- other::--- $ setfacl -m d:u:tm2:rx ./project1/ $ getfacl ./project1/ # file: project1/ # owner: pm1 # group: project1 user::rwx user:tm2:r-x #effective:r-- group::rwx #effective:r-- group:project2:rwx #effective:r-- mask::r-- other::--- default:user::rwx default:user:tm2:r-x default:group::rwx default:mask::rwx default:other::--- \u521b\u5efa\u65b0\u5b50\u76ee\u5f55 leonardo \uff0c\u5c31\u7ee7\u627f\u4e86 ~/project1 \u76ee\u5f55\u7684default ACL\u6743\u9650\u8bbe\u5b9a\u3002 \u6ce8\u610f\uff0c\u9ed8\u8ba4ACL\u6743\u9650\u662f\u9488\u5bf9\u65b0\u5efa\u7acb\u7684\u6587\u4ef6\u751f\u6548\u7684\uff0c\u76ee\u5f55cloud\u548c\u6587\u4ef6file1\u5e76\u6ca1\u6709\u56e0\u4e3a\u589e\u52a0\u4e86\u7236\u76ee\u5f55\u7684\u9ed8\u8ba4ACL\u8bbe\u5b9a\u800c\u7ee7\u627f\u9ed8\u8ba4ACL\u6743\u9650\u8bbe\u5b9a. $ su - pm1 $ cd ~ $ mkdir ./project1/leonardo $ ll ./project1/ drwxr-xr-x. 1 pm1 project1 0 Dec 4 08 :52 cloud -rw-r--r--. 1 pm1 project1 15 Dec 4 07 :15 file1 -rw-r--r--. 1 pm1 project1 0 Dec 4 08 :52 file2 drwxrwx---+ 1 pm1 project1 0 Dec 4 09 :07 leonardo","title":"8.6.6.\u9ed8\u8ba4ACL\u6743\u9650"},{"location":"linux/SRE/03-identity-security/#867acl","text":"\u9012\u5f52 ACL \u6743\u9650\uff0c\u662f\u6307\u7236\u76ee\u5f55\u5728\u8bbe\u5b9aACL\u6743\u9650\u65f6\uff0c\u6240\u6709\u7684\u5b50\u76ee\u5f55\u4e5f\u4f1a\u62e5\u6709\u76f8\u540c\u7684ACL\u6743\u9650\u3002 $ su - pm1 $ cd ~ $ getfacl ./project1/ # file: project1/ # owner: pm1 # group: project1 user::rwx user:tm2:r-x #effective:r-- group::rwx #effective:r-- group:project2:rwx #effective:r-- mask::r-- other::--- default:user::rwx default:user:tm2:r-x default:group::rwx default:mask::rwx default:other::--- $ setfacl -m d:u:tm2:rx -R ./project1/ $ ll ./project1 drwxr-xr-x+ 1 pm1 project1 0 Dec 4 08 :52 cloud -rw-r--r--. 1 pm1 project1 15 Dec 4 07 :15 file1 -rw-r--r--. 1 pm1 project1 0 Dec 4 08 :52 file2 drwxrwx---+ 1 pm1 project1 0 Dec 4 09 :07 leonardo","title":"8.6.7.\u9012\u5f52ACL\u6743\u9650"},{"location":"linux/SRE/03-identity-security/#868acl","text":"\u5220\u9664\u7528\u6237 tm2 \u7684ACL\u6743\u9650\u3002 $ su - pm1 $ cd ~ $ setfacl -x u:tm2 ./project1/ $ getfacl ./project1/ # file: project1/ # owner: pm1 # group: project1 user::rwx group::rwx group:project2:rwx mask::rwx other::--- default:user::rwx default:user:tm2:r-x default:group::rwx default:mask::rwx default:other::--- \u5220\u9664\u6240\u6709\u7684ACL\u6743\u9650\u3002 $ setfacl -b ./project1 $ getfacl ./project1 # file: project1/ # owner: pm1 # group: project1 user::rwx group::rwx other::--- $ ll ./project1 drwxr-xr-x+ 1 pm1 project1 0 Dec 4 08 :52 cloud -rw-r--r--. 1 pm1 project1 15 Dec 4 07 :15 file1 -rw-r--r--. 1 pm1 project1 0 Dec 4 08 :52 file2 drwxrwx---+ 1 pm1 project1 0 Dec 4 09 :07 leonardo \u9012\u5f52\u5220\u9664\u5168\u90e8ACL\u6743\u9650\u3002 $ setfacl -b -R ./project1 $ ll ./project1/ total 4 drwxr-xr-x. 1 pm1 project1 0 Dec 4 08 :52 cloud -rw-r--r--. 1 pm1 project1 15 Dec 4 07 :15 file1 -rw-r--r--. 1 pm1 project1 0 Dec 4 08 :52 file2 drwxrwx---. 1 pm1 project1 0 Dec 4 09 :07 leonardo","title":"8.6.8.\u5220\u9664ACL\u6743\u9650"},{"location":"linux/SRE/03-identity-security/#87acl","text":"","title":"8.7.ACL\u76ee\u5f55\u5b9e\u4f8b\u89e3\u6790"},{"location":"linux/SRE/03-identity-security/#871acl","text":"\u5207\u6362\u5230pm1\u7528\u6237\uff0c\u5728\u5176\u4e3b\u76ee\u5f55\u4e2d\uff0c\u57fa\u4e8e\u4e0d\u540c\u7684\u63a9\u7801\u521b\u5efa2\u4e2a\u5b50\u76ee\u5f55\u3002 $ su - pm1 $ umask 0022 $ mkdir mydir1 $ umask 0027 $ mkdir mydir2 $ ll -d mydir* drwxr-xr-x. 1 pm1 project1 0 Dec 4 12 :30 mydir1 drwxr-x---. 1 pm1 project1 0 Dec 4 12 :31 mydir2 \u8fd92\u4e2a\u76ee\u5f55\u5f53\u524d\u7684ACL\u72b6\u6001\u5982\u4e0b\uff1a $ getfacl mydir1 # file: mydir1 # owner: pm1 # group: project1 user::rwx group::r-x other::r-x $ getfacl mydir2 # file: mydir2 # owner: pm1 # group: project1 user::rwx group::r-x other::--- \u4fee\u6539\u76ee\u5f55 mydir2 \u7684ACL\u3002 $ setfacl -m u:tm2:rwx,g:project2:rwx mydir2 $ getfacl mydir2 getfacl mydir2 # file: mydir2 # owner: pm1 # group: project1 user::rwx user:tm2:rwx group::r-x group:project2:rwx mask::rwx other::--- $ ll -d mydir2 drwxrwx---+ 1 pm1 project1 0 Dec 4 12 :31 mydir2 \u73b0\u5728\uff0c\u7528\u6237 tm2 \u548c\u7ec4 project2 \u5bf9\u76ee\u5f55 mydir2 \u90fd\u5177\u6709rwx\u6743\u9650\uff0c\u4f20\u7edfPOSIX\u6743\u9650\u548cACL\u6743\u9650\u4e00\u81f4\u3002 \u73b0\u5728\u5bf9mydir2\u76ee\u5f55\u7ec4\u6743\u9650\u64a4\u9500w\u6743\u9650\u3002 \u7528\u6237 tm2 \u548c\u7ec4 project2 \u5bf9\u76ee\u5f55 mydir2 \u7684\u6709\u6548\u6743\u9650\u53d8\u6210\u4e86 r-x \u3002 mask\u4e5f\u53d7\u7ec4\u6743\u9650\u53d8\u5316\u5f71\u54cd\uff0c\u53d8\u6210\u4e86 r-x \u3002 $ chmod g-w mydir2 $ ll -d mydir2 drwxr-x---+ 1 pm1 project1 0 Dec 4 12 :31 mydir2 $ getfacl mydir2 # file: mydir2 # owner: pm1 # group: project1 user::rwx user:tm2:rwx #effective:r-x group::r-x group:project2:rwx #effective:r-x mask::r-x other::--- \u901a\u8fc7 chmod \u548c setfacl \u4e24\u79cd\u4e0d\u540c\u7684\u65b9\u6cd5\u5bf9\u76ee\u5f55 mydir2 \u7684\u7ec4\u6743\u9650\u8fdb\u884c\u4fee\u6539\uff0c\u5728ls\u547d\u4ee4\u4e2d\u4f53\u73b0\u662f\u4e00\u6837\u7684\uff0c\u5bf9\u7ec4\u7684\u5b9e\u9645\u6709\u6548\u6743\u9650\u7684\u5f71\u54cd\u4e5f\u662f\u4e00\u6837\u7684\u3002 chmod \u4fee\u6539\u7684\u662f mask \uff0c mask \u53ea\u5f71\u54cd\u9664\u6240\u6709\u8005\u548cother\u7684\u4e4b\u5916\u7684\u4eba\u548c\u7ec4\u7684\u6700\u5927\u6743\u9650\uff0c mask \u9700\u8981\u4e0e\u7528\u6237\u7684\u6743\u9650\u8fdb\u884c\u903b\u8f91\u4e0e\u8fd0\u7b97\u540e\uff0c\u624d\u80fd\u53d8\u6210\u6709\u6548\u6743\u9650\uff0c\u7528\u6237\u6216\u7ec4\u7684\u8bbe\u7f6e\u5fc5\u987b\u5728mask\u6743\u9650\u8bbe\u5b9a\u8303\u56f4\u5185\u624d\u4f1a\u751f\u6548\u3002 setfacl \u53ef\u4ee5\u4e0d\u4fee\u6539mask\u7684\u60c5\u51b5\u4e0b\u53ea\u4fee\u6539 owning group \u7684\u6743\u9650\uff0c\u4e0b\u9762\u7684\u4f8b\u5b50\u8bf4\u660e\u4e86\u8fd9\u4e00\u60c5\u51b5\u3002POSIX\u7ec4\u6743\u9650\u4ecd\u7136\u662f rwx \uff0c\u4f46ACL\u4e2d\u6240\u6709\u8005\u7ec4\u7684\u6743\u9650\u53d8\u6210\u4e86 r-- \u3002 $ setfacl -m g::r mydir2 $ ll -d mydir2 drwxrwx---+ 1 pm1 project1 0 Dec 4 12 :31 mydir2 $ getfacl mydir2 # file: mydir2 # owner: pm1 # group: project1 user::rwx user:tm2:rwx group::r-- group:project2:rwx mask::rwx other::---","title":"8.7.1.\u76ee\u5f55ACL"},{"location":"linux/SRE/03-identity-security/#872acl","text":"\u76ee\u5f55\u53ef\u4ee5\u5177\u6709\u9ed8\u8ba4ACL\uff0c\u8fd9\u662f\u4e00\u79cd\u7279\u6b8a\u7684ACL\uff0c\u7528\u4e8e\u5b9a\u4e49\u76ee\u5f55\u4e0b\u7684\u5bf9\u8c61\u5728\u521b\u5efa\u65f6\u7ee7\u627f\u7684\u8bbf\u95ee\u6743\u9650\u3002\u9ed8\u8ba4ACL\u4f1a\u5f71\u54cd\u5b50\u76ee\u5f55\u548c\u6587\u4ef6\u3002 \u76ee\u5f55\u7684\u9ed8\u8ba4ACL\u7684\u6743\u9650\u6709\u4e24\u79cd\u4e0d\u540c\u7684\u65b9\u5f0f\u4f20\u9012\u7ed9\u5176\u4e2d\u7684\u6587\u4ef6\u548c\u5b50\u76ee\u5f55\uff1a \u5b50\u76ee\u5f55\u7ee7\u627f\u7236\u76ee\u5f55\u7684\u9ed8\u8ba4ACL\uff0c\u65e2\u4f5c\u4e3a\u81ea\u5df1\u7684\u9ed8\u8ba4ACL\uff0c\u53c8\u4f5c\u4e3a\u81ea\u5df1\u7684\u8bbf\u95eeACL\u3002 \u6587\u4ef6\u7ee7\u627f\u76ee\u5f55\u9ed8\u8ba4ACL\u4f5c\u4e3a\u5176\u81ea\u5df1\u7684\u8bbf\u95eeACL\u3002 \u521b\u5efa\u6587\u4ef6\u7cfb\u7edf\u5bf9\u8c61\u7684\u6240\u6709\u7cfb\u7edf\u51fd\u6570\u90fd\u4f7f\u7528mode\u53c2\u6570\uff0c\u8be5\u53c2\u6570\u5b9a\u4e49\u4e86\u65b0\u521b\u5efa\u7684\u6587\u4ef6\u7cfb\u7edf\u5bf9\u8c61\u7684\u8bbf\u95ee\u6743\u9650\u3002 \u5982\u679c\u7236\u76ee\u5f55\u6ca1\u6709\u9ed8\u8ba4ACL\uff0c\u5219\u6839\u636eumask\u7684\u8bbe\u7f6e\u8bbe\u7f6e\u6743\u9650\u4f4d\u3002 \u5982\u679c\u7236\u76ee\u5f55\u5b58\u5728\u9ed8\u8ba4ACL\uff0c\u5219\u5206\u914d\u7ed9\u65b0\u5bf9\u8c61\u7684\u6743\u9650\u4f4d\u5219\u662fmode\u53c2\u6570\u6743\u9650\u4e0e\u9ed8\u8ba4ACL\u4e2d\u5b9a\u4e49\u7684\u6743\u9650\u7684\u903b\u8f91\u4e0e\u7684\u7ed3\u679c\u3002\u5728\u8fd9\u79cd\u60c5\u51b5\u4e0b\uff0c\u5ffd\u7565umask\u547d\u4ee4\u3002 \u9ed8\u8ba4ACL\u4e0d\u4f1a\u7acb\u5373\u5f71\u54cd\u8bbf\u95ee\u6743\u9650\u3002\u5b83\u4eec\u4ec5\u5728\u521b\u5efa\u6587\u4ef6\u7cfb\u7edf\u5bf9\u8c61\u65f6\u624d\u8d77\u4f5c\u7528\u3002\u8fd9\u4e9b\u65b0\u5bf9\u8c61\u4ec5\u4ece\u5176\u7236\u76ee\u5f55\u7684\u9ed8\u8ba4ACL\u7ee7\u627f\u6743\u9650\u3002 \u547d\u4ee4 mkdir \u5728\u521b\u5efa\u76ee\u5f55\u65f6\u4f1a\u7ee7\u627f\u9ed8\u8ba4ACL\u3002 $ su - pm1 $ getfacl mydir2 # file: mydir2 # owner: pm1 # group: project1 user::rwx user:tm2:rwx group::r-- group:project2:rwx mask::rwx other::--- $ mkdir ./mydir2/sub1 $ ll ./mydir2 drwxr-x---. 1 pm1 project1 0 Dec 4 13 :23 sub1 $ setfacl -d -m g:project2:-w- mydir2 $ mkdir ./mydir2/sub2 $ ll ./mydir2 drwxr-x---. 1 pm1 project1 0 Dec 4 13 :23 sub1 drwxrw----+ 1 pm1 project1 0 Dec 4 13 :27 sub2 $ getfacl ./mydir2/sub2 # file: mydir2/sub2 # owner: pm1 # group: project1 user::rwx group::r-- group:project2:-w- mask::rw- other::--- default:user::rwx default:group::r-- default:group:project2:-w- default:mask::rw- default:other::--- \u5728\u5bf9 mydir2 \u76ee\u5f55\u6dfb\u52a0\u9ed8\u8ba4ACL\u524d\uff0c\u521b\u5efa\u5b50\u76ee\u5f55 sub1 \uff0c\u6dfb\u52a0\u540e\u521b\u5efa\u5b50\u76ee\u5f55 sub2 \u3002\u53ef\u4ee5\u89c2\u5bdf\u5230 sub2 \u5230\u7ee7\u627f\u4e86 mydir2 \u7684\u9ed8\u8ba4ACL\u3002 $ su - tm2 $ cd /home/pm1/mydir2/sub2 -bash: cd: /home/pm1/mydir2/sub2: Permission denied \u4e0a\u4f8b\u4e2d\uff0c\u9ed8\u8ba4ACL\u4e2d\u6307\u5b9a\u7ec4 project2 \u53ea\u5177\u6709w\u6743\u9650\uff0c\u6240\u4ee5\u65e0\u6cd5\u6267\u884c cd \u547d\u4ee4\u8fdb\u5165\u8be5\u76ee\u5f55\u3002 \u8fd9\u8bf4\u660e\u6a21\u5f0f\u503cmode\u4e2d\u7ed9\u4e88\u7684\u6743\u9650 r \u88ab\u5c4f\u853d\u4e86\uff0c\u53ea\u4fdd\u7559\u4e86ACL\u4e2d\u6700\u5c0f\u7684\u6743\u9650 w \u3002","title":"8.7.2.\u76ee\u5f55\u7684\u9ed8\u8ba4ACL"},{"location":"linux/SRE/03-identity-security/#88acl","text":"ACL\u68c0\u67e5\u987a\u5e8f\uff1a Owner Named user Owning group Named group Other If \u8fdb\u7a0b\u7684\u7528\u6237\u6807\u8bc6\u662fOwner\uff0c\u5219owner\u7684ACL\u6761\u76ee\u51b3\u5b9a\u8bbf\u95ee\u6743\u9650 else if \u8fdb\u7a0b\u7684\u7528\u6237\u6807\u8bc6\u662fnamed user\uff0c\u5219name user\u7684ACL\u6761\u76ee\u7684\u6743\u9650\u51b3\u5b9a\u7533\u8bf7\u7684\u8bbf\u95ee\u6743\u9650 else if \u8fdb\u7a0b\u7684\u7ec4\u5c5e\u4e8eowning group\uff0c\u4e14owning group\u7684ACL\u6761\u76ee\u5305\u542b\u6240\u8bf7\u6c42\u7684\u8bbf\u95ee\u6743\u9650\uff0c\u5219\u6388\u4e88\u6240\u8bf7\u6c42\u7684\u6743\u9650 else if \u8fdb\u7a0b\u7684\u7ec4\u5c5e\u4e8enamed group\uff0c\u4e14named group\u7684ACL\u6761\u76ee\u5305\u542b\u6240\u8bf7\u6c42\u7684\u8bbf\u95ee\u6743\u9650\uff0c\u5219\u6388\u4e88\u6240\u8bf7\u6c42\u7684\u6743\u9650 else if \u8fdb\u7a0b\u7684\u7ec4\u5c5e\u4e8eowning group\u6216\u8005named group\uff0c\u4f46owning group\u6216\u8005named group\u7684ACL\u6761\u76ee\u4e0d\u5305\u542b\u6240\u8bf7\u6c42\u7684\u8bbf\u95ee\u6743\u9650\uff0c\u5219\u62d2\u7edd\u6240\u8bf7\u6c42\u7684\u6743\u9650 else ACL\u4e2d\u7684other\u6761\u76ee\u5904\u7406\u7533\u8bf7\u7684\u6743\u9650 If \u5982\u679c\u8fdb\u7a0b\u5339\u914d\u5230owner\u6216\u8005other\u6761\u76ee\u4e2d\u5305\u542b\u6240\u7533\u8bf7\u7684\u6743\u9650\uff0c\u5219\u6388\u4e88\u6743\u9650 else if \u5982\u679c\u8fdb\u7a0b\u5339\u914d\u5230named user\uff0cowning group\uff0c\u6216\u8005named group\u6761\u76ee\u4e2d\u5305\u542b\u6240\u7533\u8bf7\u7684\u6743\u9650\uff0c\u4e14maks\u6761\u76ee\u4e5f\u5305\u542b\u6240\u7533\u8bf7\u7684\u6743\u9650\uff0c\u5219\u6388\u4e88\u6743\u9650 else \u62d2\u7edd\u6743\u9650\u7533\u8bf7 \u5b9e\u9645\u5e94\u7528\u4e3e\u4f8b\uff1a udev\u4f7f\u7528ACL\u7ed9\u4e88\u767b\u5f55\u5230\u56fe\u5f62\u754c\u9762\u7684\u7528\u6237\u8bbf\u95ee\u8bbe\u5907\u7684\u6743\u9650\uff0c\u4f8b\u5982DVD\u9a71\u52a8\u5668 \u67d0\u4e9b\u5e94\u7528\u7a0b\u5e8f\u4e0d\u652f\u6301ACL Star Archiver\u662f\u4e00\u4e2a\u5b8c\u5168\u4fdd\u7559ACL\u7684\u5907\u4efd\u5e94\u7528\u7a0b\u5e8f\uff0c\u5176\u4ed6\u4eba\u53ef\u80fd\u4f1a\u4e5f\u53ef\u80fd\u4e0d\u4f1a\u4fdd\u7559\u5b83 \u8bb8\u591a\u7f16\u8f91\u5668\u548c\u6587\u4ef6\u7ba1\u7406\u5668\u4e0d\u5141\u8bb8\u5728\u5e94\u7528\u7a0b\u5e8f\u4e2d\u67e5\u770b\u6216\u8bbe\u7f6eACL","title":"8.8.ACL\u68c0\u67e5\u903b\u8f91"},{"location":"linux/SRE/04-TextTools/","text":"\u7b2c\u56db\u7ae0 \u6587\u672c\u7f16\u8f91 \u00b6 1.\u6587\u672c\u7f16\u8f91\u5668 \u00b6 1.1.vim\u5de5\u5177 \u00b6 vim\u547d\u4ee4\u683c\u5f0f\uff1a +# file : \u6253\u5f00\u6587\u4ef6\u540e\uff0c\u8ba9\u5149\u6807\u5904\u4e8e\u7b2c#\u884c\u9996\uff0c+\u9ed8\u8ba4\u884c\u5c3e +/PATTERN file : \u6253\u5f00\u6587\u4ef6\u6709\uff0c\u8ba9\u5149\u6807\u5904\u4e8e\u7b2c\u4e00\u4e2a\u88abPATTERN\u5339\u914d\u5230\u7684\u884c\u9996 -b file : \u4e8c\u8fdb\u5236\u65b9\u5f0f\u6253\u5f00\u6587\u4ef6 -d file1 file2 ... : \u6bd4\u8f83\u591a\u4e2a\u6587\u4ef6\uff0c\u76f8\u5f53\u4e8e vimdiff -m file : \u53ea\u8bfb\u65b9\u5f0f\u6253\u5f00\u6587\u4ef6 -e file : \u8fdb\u5165ex\u6a21\u5f0f\uff0c\u76f8\u5f53\u4e8e ex file -y file : vim\u4e09\u79cd\u5e38\u89c1\u6a21\u5f0f\uff1a \u666e\u901a\u6a21\u5f0fNormal\u6216\u547d\u4ee4\u6a21\u5f0f \u63d2\u5165Insert\u6216\u7f16\u8f91\u6a21\u5f0f \u6269\u5c55\u547d\u4ee4\u6a21\u5f0fExtended Command \u4e09\u79cd\u6a21\u5f0f\u5207\u6362 \u547d\u4ee4\u6a21\u5f0f\u2192\u63d2\u5165\u6a21\u5f0f i\uff1ainsert\uff0c\u5728\u5149\u6807\u5904\u8f93\u5165 I\uff1a\u5728\u5149\u6807\u6240\u5728\u884c\u9996\u8f93\u5165 a\uff1aappend\uff0c\u5728\u5149\u6807\u5904\u540e\u9762\u8f93\u5165 A\uff1a\u5728\u5149\u6807\u6240\u5728\u884c\u5c3e\u8f93\u5165 o\uff1a\u5728\u5149\u6807\u6240\u5728\u884c\u7684\u4e0b\u65b9\u6253\u5f00\u4e00\u4e2a\u65b0\u884c O\uff1a\u5728\u5149\u6807\u6240\u5728\u884c\u7684\u4e0a\u65b9\u6253\u5f00\u4e00\u4e2a\u65b0\u884c \u63d2\u5165\u6a21\u5f0f\u2192 ESC \u2192 \u547d\u4ee4\u6a21\u5f0f \u547d\u4ee4\u6a21\u5f0f\u2192 : \u2192 \u6269\u5c55\u547d\u4ee4\u6a21\u5f0f \u6269\u5c55\u547d\u4ee4\u6a21\u5f0f\u2192 ESC, enter \u2192 \u547d\u4ee4\u6a21\u5f0f \u6269\u5c55\u547d\u4ee4\u6a21\u5f0f\u5e38\u7528\u547d\u4ee4\uff1a :wq : \u4fdd\u5b58\u6587\u4ef6\u5e76\u9000\u51fa :w : \u4fdd\u5b58\u6587\u4ef6 :w filename : \u5199\u5165\u6307\u5b9a\u6587\u4ef6\uff0c\u76f8\u5f53\u4e8e\u53e6\u5b58\u4e3a :q! : \u653e\u5f03\u4efb\u4f55\u4fee\u6539\u5e76\u9000\u51fa ZQ : \u65e0\u6761\u4ef6\u9000\u51fa :join : \u5408\u5e76\u591a\u884c J : \u5408\u5e76\u4e24\u884c \u8bbe\u7f6e\uff1a\uff08\u53ef\u4ee5\u5728 /etc/vimrc \u6587\u4ef6\u4e2d\u914d\u7f6e\uff09 :set textwidth : \u8bbe\u7f6e\u6587\u672c\u5bbd\u5ea6\uff08\u4ece\u5de6\u5411\u53f3\u8ba1\u6570\uff09 :set wrapmargin=# : \u8bbe\u7f6e\u884c\u8fb9\u8ddd\uff08\u4ece\u53f3\u5411\u5de6\u8ba1\u6570\uff09 :set endofline : \u8bbe\u7f6e\u6587\u4ef6\u7ed3\u675f\u7b26 :set noendofline : \u53d6\u6d88\u6587\u4ef6\u7ed3\u675f\u7b26 :set wrap : \u81ea\u52a8\u6362\u884c :set nowrap : \u53d6\u6d88\u81ea\u52a8\u6362\u884c :set number : \u663e\u793a\u884c\u53f7 :set nonumber : \u53d6\u6d88\u663e\u793a\u884c\u53f7 :set list : \u8fdb\u5165List Mode\uff0c\u663e\u793aTab ^I\uff0c\u6362\u884c\u7b26\uff0c\u548c$\u663e\u793a :set nolist : \u9000\u51faList Mode :set ignorecase : \u5ffd\u7565\u5b57\u7b26\u7684\u5927\u5c0f\u5199 :set noic : \u4e0d\u5ffd\u7565\u5b57\u7b26\u5927\u5c0f\u5199 :set autoindent : \u542f\u7528\u81ea\u52a8\u7f29\u8fdb :set noai : \u5173\u95ed\u81ea\u52a8\u7f29\u8fdb :set hlsearch : \u542f\u7528\u9ad8\u4eae\u641c\u7d22 :set nohlsearch : \u5173\u95ed\u9ad8\u4eae\u641c\u7d22 :set fileformat=dos : \u542f\u7528windows\u683c\u5f0f :set fileformat=unix : \u542f\u7528unix\u683c\u5f0f :set expandtab : \u542f\u7528\u7a7a\u683c\u4ee3\u66ffTAB\uff0c\u9ed8\u8ba48\u4e2a\u7a7a\u683c\u4ee3\u66ff\u4e00\u4e2aTAB :set noexpandtab : \u5173\u95ed\u7a7a\u683c\u4ee3\u66ffTAB :set tabstop=# : \u6307\u5b9a#\u4e2a\u7a7a\u683c\u4ee3\u66ff\u4e00\u4e2aTAB :set shiftwidth=# : \u8bbe\u7f6e#\u4e2a\u7f29\u8fdb\u5bbd\u5ea6 :set cursorline : \u8bbe\u7f6e\u5149\u6807\u6240\u5728\u884c\u7684\u8868\u793a\u7ebf :set cursorline : \u5173\u95ed\u5149\u6807\u6240\u5728\u884c\u7684\u8868\u793a\u7ebf :set key=PASSWORD : \u542f\u7528\u5bc6\u7801\u4fdd\u62a4 :set key= : \u5173\u95ed\u5bc6\u7801\u4fdd\u62a4 :help option-list : \u83b7\u53d6\u5e2e\u52a9 \u67e5\u627e /pattern : \u4ece\u5149\u6807\u5f00\u59cb\u5904\u5411\u6587\u4ef6\u5c3e\u641c\u7d22pattern ?pattern : \u4ece\u5149\u6807\u5f00\u59cb\u5904\u5411\u6587\u4ef6\u9996\u641c\u7d22pattern n : \u5728\u540c\u4e00\u65b9\u5411\u91cd\u590d\u4e0a\u4e00\u6b21\u641c\u7d22\u547d\u4ee4 N : \u5728\u53cd\u65b9\u5411\u4e0a\u91cd\u590d\u4e0a\u4e00\u6b21\u641c\u7d22\u547d\u4ee4 # : \u5411\u4e0a\u5b8c\u6574\u5339\u914d\u5149\u6807\u4e0b\u7684\u5355\u8bcd, \u76f8\u5f53\u4e8e\uff1fword * : \u5411\u4e0b\u5b8c\u6574\u5339\u914d\u5149\u6807\u4e0b\u7684\u5355\u8bcd, \u76f8\u5f53\u4e8e/word % : \u67e5\u627e\u5bf9\u5e94\u7684( [ {\u5339\u914d nfx : \u5728\u5f53\u524d\u884c\u67e5\u627e\u5149\u6807\u540e\u7b2cn\u4e2ax\uff08\u4e00\u822c\u76f4\u63a5fx\uff09 \u66ff\u6362 :%s/\\n//g : \u5220\u9664\u6362\u884c\u7b26 :s/p1/p2/g : \u5c06\u5f53\u524d\u884c\u4e2d\u6240\u6709p1\u5747\u7528p2\u66ff\u4ee3, \u65e0g\uff0c\u5219\u53ea\u66ff\u6362\u7b2c\u4e00\u4e2a :s/p1/p2/c : \u67e5\u627e\u66ff\u6362\u8981\u6c42\u786e\u8ba4 :n1,n2s/p1/p2/g : \u5c06\u7b2cn1\u81f3n2\u884c\u4e2d\u6240\u6709p1\u5747\u7528p2\u66ff\u4ee3 :%s/p1/p2/g : \u5168\u5c40\uff0c\u4f7f\u7528p2\u66ff\u6362p1 :%s/p1/p2/gc : \u66ff\u6362\u524d\u8be2\u95ee :n,$s/vivian/sky/ : \u66ff\u6362\u7b2cn\u884c\u5f00\u59cb\u5230\u6700\u540e\u4e00\u884c\u4e2d\u6bcf\u4e00\u884c\u7684\u7b2c\u4e00\u4e2avivian\u4e3asky\uff0cn\u4e3a\u6570\u5b57 :.,$s/vivian/sky/g : \u66ff\u6362\u5f53\u524d\u884c\u5f00\u59cb\u5230\u6700\u540e\u4e00\u884c\u4e2d\u6bcf\u4e00\u884c\u6240\u6709vivian\u4e3asky :s/vivian\\//sky\\// : \u66ff\u6362\u5f53\u524d\u884c\u7b2c\u4e00\u4e2avivian/\u4e3asky/\uff0c\u53ef\u4ee5\u4f7f\u7528\\\u4f5c\u4e3a\u8f6c\u4e49\u7b26 :1,$s/^/some string/ : \u5728\u6587\u4ef6\u7684\u7b2c\u4e00\u884c\u81f3\u6700\u540e\u4e00\u884c\u7684\u884c\u9996\u524d\u63d2\u5165some string :%s/$/some string/g : \u5728\u6574\u4e2a\u6587\u4ef6\u6bcf\u4e00\u884c\u7684\u884c\u5c3e\u6dfb\u52a0some string :%s/\\s\\+$// : \u53bb\u6389\u6240\u6709\u7684\u884c\u5c3e\u7a7a\u683c\uff0c\u201c\\s\u201d\u8868\u793a\u7a7a\u767d\u5b57\u7b26\uff08\u7a7a\u683c\u548c\u5236\u8868\u7b26\uff09\uff0c\u201c+\u201d\u5bf9\u524d\u9762\u7684\u5b57\u7b26\u5339\u914d\u4e00\u6b21\u6216\u591a\u6b21\uff08\u8d8a\u591a\u8d8a\u597d\uff09\uff0c\u201c \\(\u201d\u5339\u914d\u884c\u5c3e\uff08\u4f7f\u7528\u201c\\$\u201d\u8868\u793a\u5355\u7eaf\u7684\u201c\\) \u201d\u5b57\u7b26\uff09 :%s/\\s\u2217\\n\\+/\\r/ : \u53bb\u6389\u6240\u6709\u7684\u7a7a\u767d\u884c\uff0c\u201c \\(\u201d\u548c\u201c\\) \u201d\u5bf9\u8868\u8fbe\u5f0f\u8fdb\u884c\u5206\u7ec4\uff0c\u4f7f\u5176\u88ab\u89c6\u4f5c\u4e00\u4e2a\u4e0d\u53ef\u5206\u5272\u7684\u6574\u4f53 :%s!\\s*//.*!! : \u53bb\u6389\u6240\u6709\u7684\u201c//\u201d\u6ce8\u91ca :%s!\\s*/\\*\\_.\\{-}\\*/\\s*!!g : \u53bb\u6389\u6240\u6709\u7684\u201c/**/\u201d\u6ce8\u91ca :%s= *$== : \u5c06\u6240\u6709\u884c\u5c3e\u591a\u4f59\u7684\u7a7a\u683c\u5220\u9664 :g/^\\s*$/d : \u5c06\u6240\u6709\u4e0d\u5305\u542b\u5b57\u7b26(\u7a7a\u683c\u4e5f\u4e0d\u5305\u542b)\u7684\u7a7a\u884c\u5220\u9664 r : \u66ff\u6362\u5f53\u524d\u5b57\u7b26 R : \u66ff\u6362\u5f53\u524d\u5b57\u7b26\u53ca\u5176\u540e\u7684\u5b57\u7b26\uff0c\u76f4\u81f3\u6309ESC\u952e \u7f16\u8f91 h : \u5149\u6807\u5de6\u79fb\u4e00\u4e2a\u5b57\u7b26[\u56de\u9000\u952eBackspace] l : \u5149\u6807\u53f3\u79fb\u4e00\u4e2a\u5b57\u7b26[\u7a7a\u683c\u952eSpace] K : \u5149\u6807\u4e0a\u79fb\u4e00\u884c j : \u5149\u6807\u4e0b\u79fb\u4e00\u884c w : \u5149\u6807\u8df3\u5230\u4e0b\u4e2aword\u7684\u7b2c\u4e00\u4e2a\u5b57\u6bcd(\u5305\u62ec\u6807\u70b9\u7b26\u53f7) [\u5e38\u7528] W : \u79fb\u5230\u4e0b\u4e00\u4e2a\u5b57\u7684\u5f00\u5934\uff0c\u5ffd\u7565\u6807\u70b9\u7b26\u53f7 B : \u5149\u6807\u56de\u5230\u4e0a\u4e2aword\u7684\u7b2c\u4e00\u4e2a\u5b57\u6bcd B : \u79fb\u5230\u524d\u4e00\u4e2a\u5b57\u7684\u5f00\u5934\uff0c\u5ffd\u7565\u6807\u70b9\u7b26\u53f7 BACK E : \u5149\u6807\u8df3\u5230\u4e0b\u4e2aword\u7684\u6700\u540e\u4e00\u4e2a\u5b57\u6bcd E : \u79fb\u5230\u4e0b\u4e00\u4e2a\u5b57\u7684\u7ed3\u5c3e\uff0c\u5ffd\u7565\u6807\u70b9\u7b26\u53f7 END 0 : \u79fb\u5230\u5f53\u524d\u4e00\u884c\u7684\u5f00\u59cb[Home] $ : \u79fb\u5230\u5f53\u524d\u4e00\u884c\u7684\u6700\u540e[End] ^ : \u547d\u4ee4\u5c06\u5149\u6807\u79fb\u52a8\u5230\u5f53\u524d\u884c\u7684\u7b2c\u4e00\u4e2a\u975e\u7a7a\u767d\u5b57\u7b26\u4e0a g_ : \u5230\u672c\u884c\u6700\u540e\u4e00\u4e2a\u4e0d\u662fblank\u5b57\u7b26\u7684\u4f4d\u7f6e Enter : \u5149\u6807\u4e0b\u79fb\u4e00\u884c n+ : \u5149\u6807\u4e0b\u79fbn\u884c\u3010\u6309\u4e0a\u6863\u952e \u6570\u5b57shift +\u3011 n- : \u5149\u6807\u4e0a\u79fbn\u884c G : \u79fb\u5230\u6587\u4ef6\u7684\u6700\u540e\u4e00\u884c nG \u6216\u8005 :n : \u79fb\u5230\u6587\u4ef6\u7684\u7b2cn\u884c\ue5e5\ue5e5\ue5e5 gg : \u79fb\u52a8\u5230\u6587\u6863\u7684\u5f00\u59cb [[ : \u6587\u4ef6\u5f00\u59cb\u4f4d\u7f6e\u2014\u2014\u5f00\u59cb\u884c ]] : \u6587\u4ef6\u7ed3\u675f\u4f4d\u7f6e\u2014\u2014\u672b\u5c3e\u884c H : \u5149\u6807\u79fb\u81f3\u5c4f\u5e55\u9876\u884cHEAD\u3002\u5149\u6807\u5b9a\u4f4d\u5728\u663e\u793a\u5c4f\u7684\u7b2c\u4e00\u884c M : \u79fb\u5230\u5c4f\u5e55\u7684\u4e2d\u95f4\u884c\u5f00\u5934 Middle\u3002\u5149\u6807\u5b9a\u4f4d\u5728\u663e\u793a\u5c4f\u7684\u4e2d\u95f4 L : \u79fb\u5230\u5c4f\u5e55\u7684\u6700\u540e\u4e00\u884cLAST\u3002\u5149\u6807\u5b9a\u4f4d\u5728\u663e\u793a\u5c4f\u7684\u6700\u540e\u4e00\u884c ( : \u5149\u6807\u79fb\u81f3\u53e5\u9996 ) : \u5149\u6807\u79fb\u81f3\u53e5\u5c3e { : \u79fb\u5230\u6bb5\u843d\u7684\u5f00\u5934 } : \u79fb\u5230\u4e0b\u4e00\u4e2a\u6bb5\u843d\u7684\u5f00\u5934 % : \u5339\u914d\u62ec\u53f7\u79fb\u52a8\uff0c\u5305\u62ec (, {, [.\uff08\u9700\u8981\u628a\u5149\u6807\u5148\u79fb\u5230\u62ec\u53f7\u4e0a\uff09\u8df3\u8f6c\u5230\u4e0e\u4e4b\u5339\u914d\u7684\u62ec\u53f7\u5904 * \u548c # : \u5339\u914d\u5149\u6807\u5f53\u524d\u6240\u5728\u7684\u5355\u8bcd\uff0c\u79fb\u52a8\u5149\u6807\u5230\u4e0b\u4e00\u4e2a\uff08\u6216\u4e0a\u4e00\u4e2a\uff09\u5339\u914d\u5355\u8bcd\uff08*\u662f\u4e0b\u4e00\u4e2a\uff0c#\u662f\u4e0a\u4e00\u4e2a\uff09 zf : \u6298\u53e0\uff08\u9700\u52a0\u65b9\u5411\u952e\uff09 zo : \u5c55\u5f00\uff08\u7a7a\u683c\u4e5f\u53ef\u4ee5\u5c55\u5f00\uff09 CTRL+u : \u5411\u6587\u4ef6\u9996\u7ffb\u534a\u5c4fup CTRL+d : \u5411\u6587\u4ef6\u5c3e\u7ffb\u534a\u5c4fdown CTRL+f : \u5411\u6587\u4ef6\u5c3e\u7ffb\u4e00\u5c4f forward (fact\u6574\u5c4f\u53bb\u4e24\u884c) CTRL+b : \u5411\u6587\u4ef6\u9996\u7ffb\u4e00\u5c4fback (fact\u6574\u5c4f\u53bb\u4e24\u884c) CTRL-] : \u8df3\u8f6c\u5230\u5f53\u524d\u5149\u6807\u6240\u5728\u5355\u8bcd\u5bf9\u5e94\u7684\u4e3b\u9898 CTRL-O : \u56de\u5230\u524d\u4e00\u4e2a\u4f4d\u7f6e SHIFT+V : \u9009\u62e9\u6574\u884c zz : \u547d\u4ee4\u4f1a\u628a\u5f53\u524d\u884c\u7f6e\u4e3a\u5c4f\u5e55\u6b63\u4e2d\u592e(z\u5b57\u53d6\u5176\u8c61\u5f62\u610f\u4e49\u6a21\u62df\u4e00\u5f20\u7eb8\u7684\u6298\u53e0\u53ca\u53d8\u5f62\u4f4d\u7f6e\u91cd\u7f6e) zt : \u547d\u4ee4\u4f1a\u628a\u5f53\u524d\u884c\u7f6e\u4e8e\u5c4f\u5e55\u9876\u7aef(top) zb : \u547d\u4ee4\u4f1a\u628a\u5f53\u524d\u884c\u7f6e\u4e8e\u5c4f\u5e55\u5e95\u7aef(bottom) 50% : \u5149\u6807\u5b9a\u4f4d\u5728\u6587\u4ef6\u7684\u4e2d\u95f4 ` : \u8df3\u8f6c\u5230\u6700\u8fd1\u5149\u6807\u5b9a\u4f4d\u7684\u4f4d\u7f6e\uff08\u53ea\u80fd\u8bb0\u5fc6\u6700\u8fd1\u4e24\u4e2a\u4f4d\u7f6e\uff09 \u53cd\u5f15\u53f7 I : \u5728\u5149\u6807\u524d\u5f00\u59cb\u63d2\u5165\u5b57\u7b26 insert I : \u5728\u5f53\u524d\u884c\u9996\u5f00\u59cb\u63d2\u5165\u5b57\u7b26 A : \u5728\u5149\u6807\u4f4d\u7f6e\u540e\u5f00\u59cb\u52a0\u5b57 append A : \u5728\u5149\u6807\u6240\u5728\u884c\u7684\u6700\u540e\u9762\u5f00\u59cb\u52a0\u5b57 O : \u5728\u5149\u6807\u4e0b\u52a0\u4e00\u7a7a\u767d\u884c\u5e76\u5f00\u59cb\u52a0\u5b57 open O : \u5728\u5149\u6807\u4e0a\u52a0\u4e00\u7a7a\u767d\u884c\u5e76\u5f00\u59cb\u52a0\u5b57 R : \u66ff\u6362\u5f53\u524d\u5b57\u7b26 R : \u66ff\u6362\u5f53\u524d\u5b57\u7b26\u53ca\u5176\u540e\u7684\u5b57\u7b26\u3010\u5f53\u524d\u53ca\u5176\u540e\u5b57\u7b26\u88ab\u8986\u76d6\u3011 S : \u9ed8\u8ba4\u5220\u9664\u5149\u6807\u6240\u5728\u5b57\u7b26\uff0c\u8f93\u5165\u5185\u5bb9\u63d2\u5165\u4e4b= xi S : \u9ed8\u8ba4\u5220\u9664\u5f53\u524d\u884c\u5185\u5bb9\uff0c\u8f93\u5165\u5185\u5bb9\u4f5c\u4e3a\u5f53\u524d\u884c\u65b0\u5185\u5bb9= dd+o nx : \u5220\u9664\u7531\u5149\u6807\u4f4d\u7f6e\u8d77\u59cb\u540e\u7684n\u4e2a\u5b57\u7b26\uff08\u542b\u5149\u6807\u4f4d\u7f6e\uff09x =dl(\u5220\u9664\u5f53\u524d\u5149\u6807\u4e0b\u7684\u5b57\u7b26) nX : \u5220\u9664\u7531\u5149\u6807\u4f4d\u7f6e\u8d77\u59cb\u524d\u7684n\u4e2a\u5b57\u7b26\uff08\u542b\u5149\u6807\u4f4d\u7f6e\uff09X =dh(\u5220\u9664\u5f53\u524d\u5149\u6807\u5de6\u8fb9\u7684\u5b57\u7b26) d0 : \u5220\u81f3\u884c\u9996 d$ : \u5220\u81f3\u884c\u5c3e dfa : \u8868\u793a\u5220\u9664\u4ece\u5f53\u524d\u5149\u6807\u5230\u5149\u6807\u540e\u9762\u7684\u7b2c\u4e00\u4e2aa\u5b57\u7b26\u4e4b\u95f4\u7684\u5185\u5bb9 D : \u4ee3\u8868d$(\u5220\u9664\u5230\u884c\u5c3e\u7684\u5185\u5bb9) C : \u4ee3\u8868c$(\u4fee\u6539\u5230\u884c\u5c3e\u7684\u5185\u5bb9) ndw : \u5220\u9664\u5149\u6807\u5904\u5f00\u59cb\u53ca\u5176\u540e\u7684n-1\u4e2a\u5b57 ndb : \u5220\u9664\u5149\u6807\u5904\u5f00\u59cb\u53ca\u5176\u524d\u7684n-1\u4e2a\u5b57 diw : \u5220\u9664\u5f53\u524d\u5149\u6807\u6240\u5728\u7684word(\u4e0d\u5305\u62ec\u7a7a\u767d\u5b57\u7b26)\uff0c\u610f\u4e3aDelete Inner Word \u4e24\u4e2a\u7b26\u53f7\u4e4b\u95f4\u7684\u5355\u8bcd daw : \u5220\u9664\u5f53\u524d\u5149\u6807\u6240\u5728\u7684word(\u5305\u62ec\u7a7a\u767d\u5b57\u7b26)\uff0c\u610f\u4e3aDelete A Word ndd : \u5220\u9664\u5f53\u524d\u884c\u53ca\u5176\u540en-1\u884c :n1,n2 d : \u5c06 n1\u884c\u5230n2\u884c\u4e4b\u95f4\u7684\u5185\u5bb9\u5220\u9664 dG : \u5220\u9664\u5f53\u524d\u884c\u81f3\u6587\u4ef6\u5c3e\u7684\u5185\u5bb9 Dgg : \u5220\u9664\u5f53\u524d\u884c\u81f3\u6587\u4ef6\u5934\u7684\u5185\u5bb9 d+enter : \u5220\u96642\u884c\u3010\u5305\u62ec\u5149\u6807\u4e00\u884c\u3011 cw : \u5220\u9664\u5f53\u524d\u5b57\uff0c\u5e76\u8fdb\u5165\u8f93\u5165\u6a21\u5f0f\u3010\u5f88\u597d\u7528\uff0c\u5feb\u901f\u66f4\u6539\u4e00\u4e2a\u5355\u8bcd\u3011\u76f8\u5f53\u4e8edw+i ncw : \u5220\u9664\u5f53\u524d\u5b57\u53ca\u5176\u540e\u7684n-1\u4e2a\u5b57\uff0c\u5e76\u8fdb\u5165\u8f93\u5165\u6a21\u5f0f\\\u4fee\u6539\u6307\u5b9a\u6570\u76ee\u7684\u5b57 cc : \u5220\u9664\u5f53\u524d\u884c\uff0c\u5e76\u8fdb\u5165\u8f93\u5165\u6a21\u5f0f ncc : \u5220\u9664\u5f53\u524d\u884c\u53ca\u5176\u540e\u7684n-1\u884c\uff0c\u5e76\u8fdb\u5165\u8f93\u5165\u6a21\u5f0f guw : \u5149\u6807\u4e0b\u7684\u5355\u8bcd\u53d8\u4e3a\u5c0f\u5199 gUw : \u5149\u6807\u4e0b\u7684\u5355\u8bcd\u53d8\u4e3a\u5927\u5199 xp : \u5de6\u53f3\u4ea4\u6362\u5149\u6807\u5904\u4e24\u5b57\u7b26\u7684\u4f4d\u7f6e ga : \u663e\u793a\u5149\u6807\u4e0b\u7684\u5b57\u7b26\u5728\u5f53\u524d\u4f7f\u7528\u7684encoding\u4e0b\u7684\u5185\u7801 nyl : \u590d\u5236n\u4e2a\u5b57\u7b26(\u4e5f\u53efnyh) yw : \u590d\u5236\u4e00\u4e2a\u5355\u8bcd y0 : \u8868\u793a\u62f7\u8d1d\u4ece\u5f53\u524d\u5149\u6807\u5230\u5149\u6807\u6240\u5728\u884c\u9996\u7684\u5185\u5bb9 y$ : \u590d\u5236\u4ece\u5f53\u524d\u4f4d\u7f6e\u5230\u884c\u5c3e yfa : \u8868\u793a\u62f7\u8d1d\u4ece\u5f53\u524d\u5149\u6807\u5230\u5149\u6807\u540e\u9762\u7684\u7b2c\u4e00\u4e2aa\u5b57\u7b26\u4e4b\u95f4\u7684\u5185\u5bb9 yG : \u590d\u5236\u4ece\u6240\u5728\u884c\u5230\u6700\u540e\u4e00\u884c nyy : \u5c06\u5149\u6807\u6240\u5728\u4f4d\u7f6e\u5f00\u59cb\u7684n\u884c\u6570\u636e\u590d\u5236\u6682\u5b58, \u590d\u5236\u4e00\u6574\u884c CTRL+v \u65b9\u5411y : \u5217\u9009\u62e9\u6a21\u5f0f\uff0c\u590d\u5236\u9009\u62e9\u7684\u5f88\u591a\u884c\uff1a\u5148\u4f7f\u7528V\u8fdb\u5165visual\u6a21\u5f0f\uff0c\u7136\u540ej\u5411\u4e0b\u79fb\u52a8\u5230\u4f60\u60f3\u590d\u5236\u7684\u884c\u4e3a\u6b62\uff0c\u7136\u540ey p : \u590d\u5236\u6682\u5b58\u6570\u636e\u5728\u5149\u6807\u7684\u4e0b\u4e00\u884c P : \u590d\u5236\u6682\u5b58\u6570\u636e\u5728\u5149\u6807\u7684\u4e0a\u4e00\u884c :n1,n2 co n3 : \u5c06n1\u884c\u5230n2\u884c\u4e4b\u95f4\u7684\u5185\u5bb9\u62f7\u8d1d\u5230\u7b2cn3+1\u884c\u3010n3\u884c\u7684\u4e0b\u4e00\u884c\u3011 :n1,n2 m n3 : \u5c06n1\u884c\u5230n2\u884c\u4e4b\u95f4\u7684\u5185\u5bb9\u79fb\u81f3\u5230\u7b2cn3\u884c\u4e0b J : \u628a\u4e0b\u4e00\u884c\u7684\u6570\u636e\u8fde\u63a5\u5230\u672c\u884c\u4e4b\u540e, \u591a\u4e00\u7a7a\u683c ~ : \u6539\u53d8\u5f53\u524d\u5149\u6807\u4e0b\u5b57\u7b26\u7684\u5927\u5c0f\u5199 \u5176\u4ed6 . : \u91cd\u590d\u524d\u4e00\u6307\u4ee4 u : \u53d6\u6d88\u524d\u4e00\u6307\u4ee4undo, :u\u4e5f\u884c\uff0c\u4e00\u822c\u4e0d\u7528\uff0c\u64cd\u4f5c\u592a\u591a Ctrl + r : \u6062\u590d\u3010\u53ea\u5bf9u\u6709\u6548\u3011redo Ctrl + l : \u5237\u65b0\u5c4f\u5e55\u663e\u793a Ctrl+v \u7136\u540e ctrl+A\u662f^A Ctrl+I\u662f\\t : \u8f93\u5165\u7279\u6b8a\u5b57\u7b26 Ctrl+v\u7136\u540e\u7528j\u3001k\u3001l\u3001h\u6216\u65b9\u5411\u952e\u4e0a\u4e0b\u9009\u4e2d\u591a\u5217\uff0c\u4e4b\u540e I I a A r x\u7b49\uff0c\u6700\u540e\u6309esc\uff0c\u751f\u6548 : Vim\u5217\u64cd\u4f5c 2.\u6587\u672c\u5904\u7406\u5de5\u5177 \u00b6 2.1.\u663e\u793a\u6587\u672c\u5185\u5bb9 cat \u00b6 \u547d\u4ee4 cat \u4e3b\u8981\u53c2\u6570\u8bf4\u660e\uff1a -E \uff1a\u663e\u793a\u884c\u7ed3\u675f\u7b26 $ -A \uff1a\u663e\u793a\u6240\u6709\u63a7\u5236\u7b26 -n \uff1a\u5bf9\u663e\u793a\u51fa\u7684\u6bcf\u4e00\u884c\u8fdb\u884c\u7f16\u53f7 -b \uff1a\u975e\u7a7a\u884c\u7f16\u53f7 -s \uff1a\u538b\u7f29\u8fde\u7eed\u7684\u7a7a\u884c\u6210\u4e00\u884c \u4e3e\u4f8b\uff1a cat -nA user-list.txt 1 user0$ 2 user1$ 3 user2$ 4 user3$ 5 user4$ 6 user5$ 7 user6$ 8 user7$ 9 user8$ 10 user9$ 2.2.\u663e\u793a\u6587\u672c\u884c\u53f7 nl \u00b6 \u76f8\u5f53\u4e8e\u547d\u4ee4 cat -b \u3002 \u547d\u4ee4 nl \u4e3b\u8981\u53c2\u6570\u8bf4\u660e\uff1a -b \uff1a\u6307\u5b9a\u884c\u53f7\u6307\u5b9a\u7684\u65b9\u5f0f\uff0c\u4e3b\u8981\u6709\u4e24\u79cd\uff1a -b a \uff1a\u8868\u793a\u4e0d\u8bba\u662f\u5426\u4e3a\u7a7a\u884c\uff0c\u4e5f\u540c\u6837\u5217\u51fa\u884c\u53f7\uff08\u7c7b\u4f3c cat -n\uff09\uff1b -b t \uff1a\u5982\u679c\u6709\u7a7a\u884c\uff0c\u7a7a\u7684\u90a3\u4e00\u884c\u4e0d\u8981\u5217\u51fa\u884c\u53f7\uff08\u9ed8\u8ba4\u503c\uff09\uff1b -n \uff1a\u5217\u51fa\u884c\u53f7\u8868\u793a\u7684\u65b9\u6cd5\uff0c\u4e3b\u8981\u6709\u4e09\u79cd\uff1a -n ln \uff1a\u884c\u53f7\u5728\u5c4f\u5e55\u7684\u6700\u5de6\u65b9\u663e\u793a\uff1b\u6ca1\u6709\u524d\u5bfc0\uff1b -n rn \uff1a\u884c\u53f7\u5728\u81ea\u5df1\u680f\u4f4d\u7684\u6700\u53f3\u65b9\u663e\u793a\uff0c\u6ca1\u6709\u524d\u5bfc0\uff1b -n rz \uff1a\u884c\u53f7\u5728\u81ea\u5df1\u680f\u4f4d\u7684\u6700\u53f3\u65b9\u663e\u793a\uff0c\u6709\u524d\u5bfc0\uff1b -w \uff1a\u884c\u53f7\u680f\u4f4d\u7684\u5360\u7528\u7684\u4f4d\u6570\u3002 -p \uff1a\u5728\u903b\u8f91\u5b9a\u754c\u7b26\u5904\u4e0d\u91cd\u65b0\u5f00\u59cb\u8ba1 \u4e3e\u4f8b\uff1a $ nl -b a -n rz user-list.txt 000001 user0 000002 user1 000003 user2 000004 user3 000005 user4 000006 user5 000007 user6 000008 user7 000009 user8 000010 user9 2.3.\u9006\u5411\u663e\u793a\u6587\u672c\u5185\u5bb9 tac \u00b6 \u547d\u4ee4 tac \u9006\u5411\u663e\u793a\u6587\u672c\u5185\u5bb9\u3002 \u4e3e\u4f8b\uff1a $ tac user-list.txt user9 user8 user7 user6 user5 user4 user3 user2 user1 user0 \u4e3e\u4f8b\uff1a $ seq 10 | tac 10 9 8 7 6 5 4 3 2 1 2.4.\u9006\u5411\u663e\u793a\u540c\u884c\u5185\u5bb9 rev \u00b6 \u547d\u4ee4 rev \u9006\u5411\u663e\u793a\u540c\u4e00\u884c\u7684\u5185\u5bb9\u3002 \u4e3e\u4f8b\uff1a $ rev user-list.txt 0resu 1resu 2resu 3resu 4resu 5resu 6resu 7resu 8resu 9resu \u4e3e\u4f8b\uff1a $ echo { 1 ..10 } | rev 01 9 8 7 6 5 4 3 2 1 2.5.\u663e\u793a\u975e\u6587\u672c\u6587\u4ef6\u5185\u5bb9 hexdump \u00b6 \u547d\u4ee4 hexdump \u547d\u4ee4\u4e00\u822c\u7528\u6765\u67e5\u770b\u201c\u4e8c\u8fdb\u5236\u201d\u6587\u4ef6\u7684\u5341\u516d\u8fdb\u5236\u7f16\u7801 \u4e3e\u4f8b\uff1a $ hexdump -C -n 32 cp 00000000 7f 45 4c 46 02 01 01 00 00 00 00 00 00 00 00 00 | .ELF............ | 00000010 03 00 3e 00 01 00 00 00 e0 48 00 00 00 00 00 00 | ..>......H...... | 00000020 2.6.\u5206\u9875\u67e5\u770b\u6587\u4ef6\u5185\u5bb9 \u00b6 \u547d\u4ee4 more \u548c less \u53ef\u4ee5\u5b9e\u73b0\u5206\u9875\u67e5\u770b\u6587\u4ef6\u5185\u5bb9\u3002 \u547d\u4ee4 less \u914d\u5408\u7ba1\u9053\u7b26\u4f7f\u7528\u3002 tree -d /etc | less 2.7.\u663e\u793a\u6587\u4ef6\u5934\u90e8\u5185\u5bb9 head \u00b6 \u547d\u4ee4 head \u663e\u793a\u6587\u4ef6\u5934\u90e8\u5185\u5bb9\u3002 head -c 20 cp : \u663e\u793a\u6587\u4ef6\u524d20\u5b57\u8282\u5185\u5bb9 head -n 20 zdiff : \u663e\u793a\u6587\u4ef6\u524d20\u884c\u5185\u5bb9 head -20 zdiff : \u663e\u793a\u6587\u4ef6\u524d20\u884c\u5185\u5bb9 $ echo \"\u6211\u662f\u8c01\" | head -c3 \u6211 $ echo \"\u6211\u662f\u8c01\" | head -c6 \u6211\u662f cat /dev/urandom | tr -dc '[:alnum]' | head -c 10 | tee passwd.txt $ cat user-list.txt user0 user1 user2 user3 user4 user5 user6 user7 user8 user9 $ head -n -3 user-list.txt user0 user1 user2 user3 user4 user5 user6 2.8.\u663e\u793a\u6587\u4ef6\u5c3e\u90e8\u5185\u5bb9 tail \u00b6 \u547d\u4ee4 tail \u663e\u793a\u6587\u4ef6\u5934\u90e8\u5185\u5bb9\u3002 tail -c 200 cp : \u663e\u793a\u6587\u4ef6\u5c3e\u90e8200\u4e2a\u5b57\u8282\u7684\u5185\u5bb9 tail -n 3 user-list.txt : \u663e\u793a\u6587\u4ef6\u6700\u540e3\u884c tail -n -3 user-list.txt : \u663e\u793a\u4ece-3\u884c\u5230\u6587\u4ef6\u7ed3\u675f\uff08\u5373\u6700\u540e\u4e09\u884c\uff09 tail -3 user-list.txt : \u663e\u793a\u6587\u4ef6\u6700\u540e3\u884c tail -f /var/log/messages : \u8ddf\u8e2a\u663e\u793a\u6587\u4ef6redo.log\u6587\u4ef6\u5185\u5bb9\uff0c\u5f53\u6587\u4ef6\u5220\u9664\uff0c\u518d\u5efa\u540c\u540d\u6587\u4ef6\uff0c\u65e0\u6cd5\u7ee7\u7eed\u8ffd\u8e2a tail -F /var/log/messages : \u8ddf\u8e2a\u663e\u793a\u6587\u4ef6redo.log\u6587\u4ef6\u5185\u5bb9\uff0c\u5f53\u6587\u4ef6\u5220\u9664\uff0c\u518d\u5efa\u540c\u540d\u6587\u4ef6\uff0c\u7ee7\u7eed\u8ffd\u8e2a 2.9.\u6309\u5217\u62bd\u53d6\u6587\u672c cut \u00b6 \u547d\u4ee4 cut \u53ef\u4ee5\u63d0\u53d6\u6587\u672c\u6587\u4ef6\u6216\u8005stdin\u6570\u636e\u7684\u6307\u5b9a\u5217\u5185\u5bb9\u3002 \u9009\u9879\uff1a -f : \u901a\u8fc7\u6307\u5b9a\u54ea\u4e00\u4e2a\u5b57\u6bb5\u8fdb\u884c\u63d0\u53d6\u3002cut\u547d\u4ee4\u4f7f\u7528\u201cTAB\u201d\u4f5c\u4e3a\u9ed8\u8ba4\u7684\u5b57\u6bb5\u5206\u9694\u7b26 -d : \u201cTAB\u201d\u662f\u9ed8\u8ba4\u7684\u5206\u9694\u7b26\uff0c\u4f7f\u7528\u6b64\u9009\u9879\u53ef\u4ee5\u66f4\u6539\u4e3a\u5176\u4ed6\u7684\u5206\u9694\u7b26 --complement : \u6b64\u9009\u9879\u7528\u4e8e\u6392\u9664\u6240\u6307\u5b9a\u7684\u5b57\u6bb5 --output-delimiter=STRING : \u6307\u5b9a\u8f93\u51fa\u5185\u5bb9\u7684\u5206\u9694\u7b26 -c : \u6309\u5b57\u7b26\u5207\u5272 \u53d6/etc/passwd\u6587\u4ef6\u7b2c1\u5217\u5185\u5bb9\uff0c\u4ee5 : \u4e3a\u5206\u9694\u7b26\uff08\u53ea\u53d6\u524d\u4e09\u884c\uff09 $ cut -d ':' -f 1 /etc/passwd | head -3 root messagebus systemd-network \u53d6/etc/passwd\u6587\u4ef6\u7b2c1\u548c6\u5217\u5185\u5bb9\uff0c\u4ee5 : \u4e3a\u5206\u9694\u7b26\uff08\u53ea\u53d6\u524d\u4e09\u884c\uff09 cut -d ':' -f 1 ,6 /etc/passwd | head -3 root:/root messagebus:/run/dbus systemd-network:/ \u53d6/etc/passwd\u6587\u4ef6\u7b2c1\u52303\u5217\u4ee5\u53ca\u7b2c6\u5217\u5185\u5bb9\uff0c\u4ee5 : \u4e3a\u5206\u9694\u7b26\uff08\u53ea\u53d6\u524d\u4e09\u884c\uff09 $ cut -d ':' -f 1 -3,6 /etc/passwd | head -3 root:x:0:/root messagebus:x:499:/run/dbus systemd-network:x:497:/ \u4e0b\u9762\u4f7f\u7528 --output-delimiter \u9009\u9879\uff0c\u628a\u8f93\u51fa\u7ed3\u679c\u4e2d\u7684\u5206\u9694\u7b26 : \u5168\u90e8\u66ff\u6362\u6210 --- \u3002 $ cat /etc/passwd | sort | head -3 admin3:x:1020:100::/home/admin3:/bin/bash at:x:25:25:Batch jobs daemon:/var/spool/atjobs:/usr/sbin/nologin bin:x:1:1:bin:/bin:/usr/sbin/nologin $ cut -d \":\" -f 1 ,7 /etc/passwd | sort | head -3 admin3:/bin/bash at:/usr/sbin/nologin bin:/usr/sbin/nologin $ cut -d \":\" -f 1 ,7 --output-delimiter = \"---\" /etc/passwd | sort | head -3 admin3---/bin/bash at---/usr/sbin/nologin bin---/usr/sbin/nologin --output-delimiter \u9009\u9879\u4e5f\u53ef\u4ee5\u5229\u7528\u6765\u8fdb\u884c\u8ba1\u7b97\u3002 $ echo { 1 ..10 } | cut -d \" \" -f 1 -10 --output-delimiter = \"+\" | bc 55 \u4ece ifconfig \u547d\u4ee4\u4e2d\u622a\u53d6\u5f53\u524d\u4e3b\u673a\u7684ip\u5730\u5740\u3002\uff08openSUSE\u9700\u8981\u5b89\u88c5\u5305 net-tools-deprecated \uff09 $ ifconfig | head -2 | tail -1 inet 192 .168.10.210 netmask 255 .255.255.0 broadcast 192 .168.10.255 $ ifconfig | head -2 | tail -1 | cut -d \" \" -f 10 192 .168.10.210 \u6216\u8005 $ ip addr list | grep eth0 | tail -1 | cut -d \" \" -f 6 192 .168.10.210/24 \u57fa\u4e8e\u4e0a\u9762\u7ed3\u679c\uff0c\u53ef\u4ee5\u5c1d\u8bd5\u901a\u8fc7 --complement \u53c2\u6570\uff0c\u4ee5 / \u4e3a\u5206\u9694\u7b26\uff0c\u6392\u9664\u7b2c\u4e8c\u5217 24 \uff0c\u53ea\u8f93\u51fa\u7b2c\u4e00\u5217IP\u5730\u5740\u3002 ip addr list | grep eth0 | tail -1 | cut -d \" \" -f 6 | cut -d \"/\" --complement -f 2 192 .168.10.210 \u663e\u793a df \u547d\u4ee4\u8f93\u51fa\u4e2d\u7684\u5206\u533a\u4f7f\u7528\u7387\u3002 $ df | tr -s ' ' | cut -d ' ' -f 5 | tr -d % Use 0 0 2 0 8 8 8 8 8 8 8 8 8 8 8 0 \u65b9\u6cd52\uff1a\u5148\u628a\u7a7a\u683c\u5168\u90e8\u66ff\u6362\u6210%\uff0c\u518d\u53bb\u91cd\u3002 df | tr -s ' ' % | cut -d % -f 5 Use 0 0 2 0 8 8 8 8 8 8 8 8 8 8 8 0 2.10.\u5408\u5e76\u591a\u4e2a\u6587\u4ef6 paste \u00b6 \u547d\u4ee4 paste \u5e38\u7528\u9009\u9879\uff1a -d \uff1a\u6307\u5b9a\u5206\u9694\u7b26\uff0c\u9ed8\u8ba4\u662fTAB -s \uff1a\u6240\u6709\u884c\u5408\u6210\u4e00\u884c\u663e\u793a \u751f\u6210 alpha.log \u548c seq.log \u3002 for i in { a..z } ; do echo $i >> alpha.log ; done seq 10 > seq.log \u7528 paste \u547d\u4ee4\u5408\u5e76\u8fd92\u4e2a\u6587\u4ef6\u3002 $ paste alpha.log seq.log a 1 b 2 c 3 d 4 e 5 f 6 g 7 h 8 i 9 j 10 k l m n o p q r s t u v w x y z $ paste -d \":\" alpha.log seq.log a:1 b:2 c:3 d:4 e:5 f:6 g:7 h:8 i:9 j:10 k: l: m: n: o: p: q: r: s: t: u: v: w: x: y: z: \u539f\u6587\u4ef6\u90fd\u662f\u5217\u8f93\u51fa\uff0c\u6539\u6210\u884c\u8f93\u51fa\u3002 $ paste -d \"-\" -s alpha.log a-b-c-d-e-f-g-h-i-j-k-l-m-n-o-p-q-r-s-t-u-v-w-x-y-z $ paste -d \"-\" -s seq.log $ paste -d \":\" -s alpha.log seq.log a:b:c:d:e:f:g:h:i:j:k:l:m:n:o:p:q:r:s:t:u:v:w:x:y:z 1 :2:3:4:5:6:7:8:9:10 $ paste -d \":\" -s seq.log alpha.log 1 :2:3:4:5:6:7:8:9:10 a:b:c:d:e:f:g:h:i:j:k:l:m:n:o:p:q:r:s:t:u:v:w:x:y:z 2.11.\u6587\u672c\u7edf\u8ba1\u6570\u636e wc \u00b6 \u5e38\u7528\u9009\u9879\uff1a -l \uff1a\u53ea\u8ba1\u6570\u884c\u6570 -w \uff1a\u53ea\u8ba1\u6570\u5355\u8bcd\u603b\u6570 -c \uff1a\u53ea\u8ba1\u6570\u5b57\u8282\u603b\u6570 -m \uff1a\u53ea\u8ba1\u6570\u5b57\u7b26\u603b\u6570 -L \uff1a\u663e\u793a\u6587\u4ef6\u4e2d\u6700\u957f\u884c\u7684\u957f\u5ea6 $ cat text Tom, 20 , Shanghai Jack, 30 , Beijing Smith, 40 , Guangzhou $ wc text # \u884c\u6570 \u5355\u8bcd\u6570 \u5b57\u8282\u6570 3 9 57 text $ wc -l text 3 text $ wc -w text 9 text $ wc -c text 57 text $ wc -m text 57 text $ wc -L text 20 text \u5bf9\u6bd4\u4e24\u79cd\u4e0d\u540c\u5408\u5e76\u7684\u65b9\u6cd5\u3002 $ cat text1 text2 Tom, 20 , Shanghai Jack, 30 , Beijing Smith, 40 , Guangzhou Tom, 20 , Shanghai Jack, 30 , Beijing Leo, 40 , Guangzhou $ paste text1 text2 Tom, 20 , Shanghai Tom, 20 , Shanghai Jack, 30 , Beijing Jack, 30 , Beijing Smith, 40 , Guangzhou Leo, 40 , Guangzhou 2.12.\u6587\u672c\u6392\u5e8f sort \u00b6 \u547d\u4ee4 sort \u628a\u6574\u7406\u8fc7\u7684\u6587\u672c\u663e\u793a\u5728stdout\u4e0a\uff0c\u4e0d\u6539\u53d8\u539f\u6587\u4ef6\u3002 \u5e38\u7528\u9009\u9879\uff1a -r \uff1a\u6267\u884c\u53cd\u65b9\u5411\uff08\u4ece\u4e0a\u81f3\u4e0b\uff09\u6392\u5e8f -R \uff1a\u968f\u673a\u6392\u5e8f -n \uff1a\u6309\u6570\u5b57\u5927\u5c0f\u6392\u5e8f -h \uff1a\u4eba\u7c7b\u53ef\u8bfb\u6392\u5e8f\uff0c\u5982\uff1a2K\uff0c1G -f \uff1a\u6392\u5e8f\u65f6\u5c06\u5c0f\u5199\u5b57\u6bcd\u89c6\u4e3a\u5927\u5199\u5b57\u6bcd -u \uff1a\u6392\u5e8f\u65f6\u5408\u5e76\u91cd\u590d\u9879 -t c \uff1a\u4f7f\u7528c\u4f5c\u4e3a\u5b57\u6bb5\u5206\u9694\u7b26 -k # \uff1a\u6309\u7167\u4ee5c\u4e3a\u5206\u9694\u7b26\u7684\u7b2c#\u5217\u6765\u6392\u5e8f \u4e3e\u4f8b\uff1a\u4ee5 , \u4e3a\u5206\u9694\u7b26\uff0c\u8bfb\u53d6 text \u6587\u4ef6\u5185\u5bb9\u4e2d\u7b2c1\uff0c3\u5217\uff0c\u5bf9\u8f93\u51fa\u7ed3\u679c\u4ee5 , \u4e3a\u5206\u9694\u7b26\uff0c\u6309\u7b2c\u4e8c\u5217\u6392\u5e8f\uff08\u6b63\u5e8f\u548c\u53cd\u5e8f\uff09\u3002 $ cat text Tom, 20 , Shanghai Jack, 30 , Beijing Smith, 40 , Guangzhou $ cut -d \",\" -f 1 ,3 text | sort -t \",\" -k 1 Jack, Beijing Smith, Guangzhou Tom, Shanghai $ cut -d \",\" -f 1 ,3 text | sort -t \",\" -k 1 -r Tom, Shanghai Smith, Guangzhou Jack, Beijing \u628a\u6587\u4ef6text1\u548c\u6587\u4ef6text2\u5408\u5e76\u540e\u53bb\u91cd\u8f93\u51fa\u3002 $ cat text2 Tom, 20 , Shanghai Jack, 30 , Beijing Leo, 40 , Guangzhou $ cat text1 Tom, 20 , Shanghai Jack, 30 , Beijing Smith, 40 , Guangzhou $ cat text1 text2 Tom, 20 , Shanghai Jack, 30 , Beijing Smith, 40 , Guangzhou Tom, 20 , Shanghai Jack, 30 , Beijing Leo, 40 , Guangzhou \u5e76\u96c6\uff0c\u91cd\u590d\u884c\u53ea\u4fdd\u7559\u4e00\u884c\u3002\u524d\u97622\u4e2a\u547d\u4ee4\u662f\u540c\u6837\u542b\u4e49\uff08\u76f8\u540c\u7684\u6392\u5e8f\u5217\uff09\uff0c\u7b2c\u4e09\u4e2a\u547d\u4ee4\u4e2d\u5bf9\u4e0d\u540c\u5217\u8fdb\u884c\u4e86\u6392\u5e8f\uff0c\u5bfc\u81f4\u53bb\u91cd\u7ed3\u679c\u4e0d\u540c\u3002 $ cat text1 text2 | sort -u Jack, 30 , Beijing Leo, 40 , Guangzhou Smith, 40 , Guangzhou Tom, 20 , Shanghai $ cat text1 text2 | sort -t \",\" -k 1 -u Jack, 30 , Beijing Leo, 40 , Guangzhou Smith, 40 , Guangzhou Tom, 20 , Shanghai $ cat text1 text2 | sort -t \",\" -k 2 -u Tom, 20 , Shanghai Jack, 30 , Beijing Smith, 40 , Guangzhou 2.13.\u53bb\u91cd uniq \u00b6 \u547d\u4ee4 uniq \u4ece\u8f93\u5165\u4e2d\u5220\u9664\u524d\u540e\u76f8\u90bb\u91cd\u590d\u7684\u884c\u3002\u7ecf\u5e38\u4e0e sort \u547d\u4ee4\u7ed3\u5408\u4f7f\u7528\u3002 \u4e3b\u8981\u53c2\u6570\uff1a -c \uff1a\u663e\u793a\u6bcf\u884c\u91cd\u590d\u51fa\u73b0\u7684\u6b21\u6570 -d \uff1a\u4ec5\u663e\u793a\u91cd\u590d\u7684\u884c -u \uff1a\u4ec5\u663e\u793a\u4e0d\u91cd\u590d\u7684\u884c \u4e3e\u4f8b\uff0c\u6ce8\u610f\u53ea\u6709\u5bf9\u76f8\u90bb\u884c\u8fdb\u884c\u53bb\u91cd\u3002 $ cat text3 test 30 Hello 95 Hello 95 Linux 85 Linux 85 Hello 95 test 30 $ uniq text3 test 30 Hello 95 Linux 85 Hello 95 test 30 \u628a\u6587\u4ef6text1\u548c\u6587\u4ef6text2\u5408\u5e76\u540e\uff0c\u8fdb\u884c\u4ea4\u96c6\u548c\u5e76\u96c6\uff0c\u5e76\u53bb\u91cd\u3002 $ cat text1 Tom, 20 , Shanghai Jack, 30 , Beijing Smith, 40 , Guangzhou $ cat text2 Tom, 20 , Shanghai Jack, 30 , Beijing Leo, 40 , Guangzhou # \u5e76\u96c6\uff0c\u6309\u9996\u5217\u6392\u5e8f\u53bb\u91cd $ cat text1 text2 | sort | uniq Jack, 30 , Beijing Leo, 40 , Guangzhou Smith, 40 , Guangzhou Tom, 20 , Shanghai # \u4ea4\u96c6 $ cat text1 text2 | sort | uniq -d Jack, 30 , Beijing Tom, 20 , Shanghai # \u5dee\u96c6 $ cat text1 text2 | sort | uniq -u Leo, 40 , Guangzhou Smith, 40 , Guangzhou \u67e5\u770b\u5e76\u53d1\u8fde\u63a5\u6570\u6700\u591a\u7684\u8fdc\u7a0b\u4e3b\u673aIP\u3002 $ ss -nt State Recv-Q Send-Q Local Address:Port Peer Address:Port Process ESTAB 0 0 192 .168.10.210:22 192 .168.10.210:41650 ESTAB 0 0 192 .168.10.210:22 192 .168.10.201:65330 ESTAB 0 64 192 .168.10.210:22 192 .168.10.201:63289 ESTAB 0 0 192 .168.10.210:41650 192 .168.10.210:22 ESTAB 0 0 192 .168.10.210:47992 192 .168.10.210:22 ESTAB 0 0 192 .168.10.210:60268 192 .168.10.210:22 ESTAB 0 0 192 .168.10.210:22 192 .168.10.201:65327 ESTAB 0 0 192 .168.10.210:35758 192 .168.10.220:22 ESTAB 0 0 192 .168.10.210:22 192 .168.10.210:56818 ESTAB 0 0 192 .168.10.210:56818 192 .168.10.210:22 ESTAB 0 0 192 .168.10.210:48006 192 .168.10.210:22 ESTAB 0 0 192 .168.10.210:22 192 .168.10.210:60268 ESTAB 0 0 192 .168.10.210:22 192 .168.10.220:33896 ESTAB 0 0 192 .168.10.210:22 192 .168.10.201:65324 ESTAB 0 0 192 .168.10.210:22 192 .168.10.210:47992 ESTAB 0 0 192 .168.10.210:59554 192 .168.10.210:22 ESTAB 0 0 192 .168.10.210:22 192 .168.10.210:59554 ESTAB 0 0 192 .168.10.210:22 192 .168.10.210:48006 $ ss -nt | tr -s \" \" \":\" | cut -d \":\" -f 6 ,7 | sort | uniq -c | sort -nr | head -n 1 6 192 .168.10.210:22 2.14.\u6587\u672c\u6bd4\u8f83 \u00b6 2.14.1. diff \u00b6 \u547d\u4ee4 diff \u6bd4\u8f83\u4e24\u4e2a\u6587\u4ef6\u4e4b\u95f4\u7684\u533a\u522b\u3002 \u5e38\u7528\u9009\u9879\uff1a -u \uff1a\u4ee5\u7edf\u4e00\u7684\u65b9\u5f0f\u6765\u663e\u793a\u6587\u4ef6\u5185\u5bb9\u7684\u4e0d\u540c -y \uff1a\u4ee5\u5e76\u5217\u7684\u65b9\u5f0f\u663e\u793a\u6587\u4ef6\u7684\u5f02\u540c\u4e4b\u5904 -W \uff1a\u5728\u4f7f\u7528-y\u53c2\u6570\u65f6\uff0c\u6307\u5b9a\u680f\u5bbd -c \uff1a\u663e\u793a\u5168\u90e8\u5185\u6587\uff0c\u5e76\u6807\u51fa\u4e0d\u540c\u4e4b\u5904 -N \uff1a\u7f3a\u5931\u6587\u4ef6\u4ee5\u7a7a\u6587\u4ef6\u5904\u7406 \u4e3e\u4f8b\uff1a $ cat text5 # \u6587\u4ef6\u5c3e\u90e8\u6ca1\u6709\u7a7a\u884c 1001 1002 1003 $ cat text6 # \u6587\u4ef6\u5c3e\u90e8\u6ca1\u6709\u7a7a\u884c 1001 1002 1003a 1004 \u663e\u793a\u4e0d\u540c\u3002 3c3,4 \u4ee3\u8868\u4e24\u4e2a\u6587\u4ef6\u5728\u7b2c3\uff0c4\u884c\u6709\u4e0d\u540c\u3002 $ diff text5 text6 3c3,4 < 1003 --- > 1003a > 1004 \u4ee5\u7edf\u4e00\u683c\u5f0f\u8f93\u51fa\u6bd4\u8f83\u7ed3\u679c\u3002 \u524d2\u884c\u662f\u6587\u4ef6\u4fe1\u606f\u3002\u5176\u4e2d --- \u8868\u793a\u53d8\u52a8\u524d\u7684\u6587\u4ef6\uff0c +++ \u8868\u793a\u53d8\u52a8\u540e\u7684\u6587\u4ef6\u3002 \u53d8\u52a8\u7684\u4f4d\u7f6e\u7528\u4e24\u4e2a@\u4f5c\u4e3a\u8d77\u9996\u548c\u7ed3\u675f\uff0c @@ -1,3 +1,4 @@ \u3002 -1,3 \u4e2d\uff0c - \u8868\u793a\u7b2c\u4e00\u4e2a\u6587\u4ef6\uff0c\u5373 text5 \u3002\u7b2c\u4e00\u4e2a\u6587\u4ef6\u4ece\u7b2c1\u884c\u5f00\u59cb\u8fde\u7eed3\u884c\u3002 +1,4 \u4e2d\uff0c + \u8868\u793a\u7b2c\u4e8c\u4e2a\u6587\u4ef6\uff0c\u5373 text6 \u3002\u5373\uff0c\u7b2c\u4e8c\u4e2a\u6587\u4ef6\u4ece\u7b2c1\u884c\u5f00\u59cb\u8fde\u7eed4\u884c\u3002 $ diff -u text5 text6 --- text5 2022 -12-07 08 :07:05.927805722 +0800 +++ text6 2022 -12-07 08 :07:24.692234585 +0800 @@ -1,3 +1,4 @@ 1001 1002 -1003 +1003a +1004 \u4ee5\u4e0a\u4e0b\u6587\u65b9\u5f0f\u8f93\u51fa\u6bd4\u8f83\u7ed3\u679c\u3002\u6807\u6709 ! \u4ee3\u8868\u5dee\u5f02\u884c\u3002 $ diff -c text5 text6 *** text5 2022 -12-07 08 :24:08.867168414 +0800 --- text6 2022 -12-07 08 :24:13.939284243 +0800 *************** *** 1 ,3 **** 1001 1002 ! 1003 --- 1 ,4 ---- 1001 1002 ! 1003a ! 1004 \u5e76\u6392\u683c\u5f0f\u8f93\u51fa\u6bd4\u8f83\u7ed3\u679c\u3002 | \u8868\u793a\u524d\u540e2\u4e2a\u6587\u4ef6\u5185\u5bb9\u6709\u4e0d\u540c < \u8868\u793a\u540e\u9762\u6587\u4ef6\u6bd4\u524d\u9762\u6587\u4ef6\u5c11\u4e861\u884c\u5185\u5bb9 > \u8868\u793a\u540e\u9762\u6587\u4ef6\u6bd4\u524d\u9762\u6587\u4ef6\u591a\u4e861\u884c\u5185\u5bb9 $ diff -y -W 50 text5 text6 1001 1001 1002 1002 1003 | 1003a > 1004 \u6bd4\u8f83\u6587\u4ef6\u5939\u5185\u5bb9\u3002\u6ce8\u610f\uff0c\u53ea\u6bd4\u8f83\u5185\u5bb9\uff0c\u4e0d\u6bd4\u8f83\u65f6\u95f4\u6233\u3002 $ mkdir dir1 $ mkdir dir2 $ cd dir1 $ touch file1 $ touch file2 $ cp file1 file2 ../dir2/ $ echo \"hello\" > file3 $ cd ../dir2 $ touch file3 $ touch file4 $ diff dir1 dir2 1d0 < hello Only in dir2: file4 2.14.2. patch \u00b6 \u547d\u4ee4 patch \u590d\u5236\u5176\u4ed6\u6587\u4ef6\u4e2d\u7684\u5185\u5bb9\u3002\u547d\u4ee4\u683c\u5f0f\uff1a patch -p [ num ] < patchfile patch [ options ] originalfile patchfile \u5f53\u7279\u5b9a\u8f6f\u4ef6\u6709\u53ef\u7528\u7684\u5b89\u5168\u4fee\u590d\u7a0b\u5e8f\u65f6\uff0c\u6211\u4eec\u901a\u5e38\u4f1a\u4f7f\u7528 yum \u6216 apt-get \u6216 zypper \u7b49\u5305\u7ba1\u7406\u5de5\u5177\u8fdb\u884c\u4e8c\u8fdb\u5236\u5347\u7ea7\u3002 \u4f46\u5982\u679c\u6211\u4eec\u662f\u901a\u8fc7\u4ece\u6e90\u4ee3\u7801\u7f16\u8bd1\u5b89\u88c5\u8f6f\u4ef6\u7684\u60c5\u51b5\u4e0b\uff0c\u6211\u4eec\u9700\u8981\u4e0b\u8f7d\u5b89\u5168\u8865\u4e01\u5e76\u5c06\u5176\u5e94\u7528\u4e8e\u539f\u59cb\u6e90\u4ee3\u7801\u5e76\u91cd\u65b0\u7f16\u8bd1\u8f6f\u4ef6\u3002 \u8fd9\u5c31\u662f\u6211\u4eec\u4f7f\u7528 diff \u521b\u5efa\u8865\u4e01\u6587\u4ef6\uff08patch file\uff09\uff0c\u5e76\u4f7f\u7528 patch \u547d\u4ee4\u5e94\u7528\u5b83\u3002 \u8865\u4e01\u6587\u4ef6\u662f\u4e00\u4e2a\u6587\u672c\u6587\u4ef6\uff0c\u5176\u4e2d\u5305\u542b\u540c\u4e00\u6587\u4ef6\uff08\u6216\u540c\u4e00\u6e90\u4ee3\u7801\u6811\uff09\u7684\u4e24\u4e2a\u7248\u672c\u4e4b\u95f4\u7684\u5dee\u5f02\u3002 \u8865\u4e01\u6587\u4ef6\u662f\u4f7f\u7528 diff \u547d\u4ee4\u521b\u5efa\u7684\u3002 \u7ee7\u7eed\u4e0a\u4f8b\u3002 \u5c06\u6587\u4ef6 text5 \u7684\u5185\u5bb9\u540c\u6b65\u5230\u6587\u4ef6 text6 \uff0c\u7136\u540e\u64a4\u9500\u8865\u4e01\u3002\u6ce8\u610f\u533a\u5206\u6e90\u6587\u4ef6\u548c\u76ee\u6807\u6587\u4ef6\u3002 $ cat text5 1001 1002 1003 $ cat text6 1001 1002 1003a 1004 # \u751f\u6210\u8865\u4e01\u6587\u4ef6 $ diff -ruN text5 text6 > patchfile $ cat patchfile --- text5 2022 -12-07 08 :24:08.867168414 +0800 +++ text6 2022 -12-07 08 :24:13.939284243 +0800 @@ -1,3 +1,4 @@ 1001 1002 -1003 +1003a +1004 # \u4e0d\u6307\u660e\u76ee\u6807\u6587\u4ef6\uff0c\u5219\u9ed8\u8ba4\u7ed9diff\u547d\u4ee4\u4e2d\u7684\u6e90\u6587\u4ef6\u8fdb\u884c\u6253\u8865\u4e01 $ patch < patchfile patching file text5 $ cat text5 1001 1002 1003a 1004 $ cat text6 1001 1002 1003a 1004 # \u64a4\u9500\u8865\u4e01 patch -R < patchfile patching file text5 # cat text5 1001 1002 1003 # \u7ed9text6\u6587\u4ef6\u6253\u8865\u4e01\uff08\u7528text5\u7684\u6587\u4ef6\u5185\u5bb9\u8986\u76d6text6\u7684\u5185\u5bb9\uff09 $ patch text6 patchfile patching file text6 Reversed ( or previously applied ) patch detected! Assume -R? [ n ] y $ cat text6 1001 1002 1003 # \u64a4\u9500\u7ed9text6\u6587\u4ef6\u6253\u7684\u8865\u4e01\uff08\u6062\u590dtext6\u6587\u4ef6\u8865\u4e01\u524d\u7684\u5185\u5bb9\uff09 $ patch -R text6 patchfile patching file text6 Unreversed patch detected! Ignore -R? [ n ] y $ cat text6 1001 1002 1003a 1004 \u4f7f\u7528 -b \u53c2\u6570\uff0c\u5728patch\u524d\u5148\u5907\u4efd\u6e90\u6587\u4ef6\u3002 $ patch -b < patchfile patching file text5 $ cat text5 1001 1002 1003a 1004 $ cat text5.orig 1001 1002 1003 $ cat text6.orig 1001 1002 1003 $ patch -R < patchfile patching file text5 \u5728-b\u53c2\u6570\u4e2d\u52a0\u5165-V\u53c2\u6570\uff0c\u6307\u5b9a\u5907\u4efd\u6587\u4ef6\u540d\u7684\u683c\u5f0f\uff0c\u5982\u4e0b\uff0c\u4f1a\u5f97\u5230\u6587\u4ef6 text5.~1~ \u3002 $patch -b -V numbered < patchfile patching file text5 $ cat text5 1001 1002 1003a 1004 $ cat text5.~1~ 1001 1002 1003 \u8bd5\u8fd0\u884c\uff0c\u4e0d\u505a\u5b9e\u9645\u66f4\u6539\u3002 patch --dry-run < patchfile \u5bf9\u76ee\u5f55\u6253\u8865\u4e01\u3002 \u6267\u884c diff \u548c patch \u547d\u4ee4\u662f\u5728\u5f53\u524d\u7528\u6237 vagrant \u7684\u4e3b\u76ee\u5f55\u4e0b\uff0c\u7edd\u5bf9\u8def\u5f84\u662f /home/vagrant \u3002 diff \u547d\u4ee4\u4e2d\uff0c\u6e90\u76ee\u5f55\u662f /home/vagrant/dir1 \u3002\u76ee\u6807\u76ee\u5f55\u662f /home/vagrant/dir2 \u3002 -p3 \u662f\u544a\u8bc9 patch \u547d\u4ee4\u5ffd\u7565\u4e0a\u9762\u7edd\u5bf9\u8def\u5f84\u4e2d\u524d\u4e09\u4e2a\u659c\u6760 / \u3002 patch \u547d\u4ee4\u4e2d\u7528 diff \u7684\u76ee\u6807\u76ee\u5f55\u53bb\u8986\u76d6\u6e90\u76ee\u5f55\u3002\u4e92\u6362\u4f1a\u62a5\u9519\u3002 -R \uff1a\u64a4\u9500\u8865\u4e01\u3002 # file3\u548cfile4\u6709\u5185\u5bb9 $ tree ./dir1 ./dir1 \u251c\u2500\u2500 file1 \u251c\u2500\u2500 file2 \u251c\u2500\u2500 file3 \u2514\u2500\u2500 subdir1 \u2514\u2500\u2500 file4 \u90fd\u662f\u7a7a\u6587\u4ef6 $ tree ./dir2 ./dir2 \u251c\u2500\u2500 file1 \u251c\u2500\u2500 file2 \u251c\u2500\u2500 file3 \u2514\u2500\u2500 subdir1 \u2514\u2500\u2500 file4 $ diff -ruN /home/vagrant/dir1 /home/vagrant/dir2 > patchdir $ cat patchdir diff -ruN /home/vagrant/dir1/file3 /home/vagrant/dir2/file3 --- /home/vagrant/dir1/file3 2022 -12-07 08 :42:33.108418336 +0800 +++ /home/vagrant/dir2/file3 2022 -12-07 21 :25:48.156056360 +0800 @@ -1 +0,0 @@ -hello diff -ruN /home/vagrant/dir1/subdir1/file4 /home/vagrant/dir2/subdir1/file4 --- /home/vagrant/dir1/subdir1/file4 2022 -12-07 21 :15:09.689912160 +0800 +++ /home/vagrant/dir2/subdir1/file4 2022 -12-07 21 :26:55.405546177 +0800 @@ -1 +0,0 @@ -/home/vagrant/dir1/subdir1 # \u7528dir2\u7684\u5185\u5bb9\u8986\u76d6dir1\u7684\u5185\u5bb9 $ patch -p3 < patchdir patching file dir1/file3 patching file dir1/subdir1/file4 # \u73b0\u5728dir1\u76ee\u5f55\u4e0b\u7684\u5185\u5bb9\u5df2\u7ecf\u88abdir2\u76ee\u5f55\u8986\u76d6\u4e86\u3002file3\u548cfile4\u90fd\u662f\u7a7a\u6587\u4ef6 $ ll ./dir1 total 0 -rw-r--r--. 1 vagrant wheel 0 Dec 7 08 :34 file1 -rw-r--r--. 1 vagrant wheel 0 Dec 7 08 :35 file2 -rw-r--r--. 1 vagrant wheel 0 Dec 7 21 :40 file3 drwxr-xr-x. 1 vagrant wheel 10 Dec 7 21 :40 subdir1 $ ll ./dir1/subdir1 total 0 -rw-r--r--. 1 vagrant wheel 0 Dec 7 21 :40 file4 # \u64a4\u9500\u8865\u4e01\uff0cfile3\u548cfile4\u5df2\u7ecf\u6062\u590d\u4e3a\u539f\u6587\u4ef6 $ patch -R -p3 < patchdir patching file dir1/file3 patching file dir1/subdir1/file4 $ ll ./dir1 -rw-r--r--. 1 vagrant wheel 0 Dec 7 08 :34 file1 -rw-r--r--. 1 vagrant wheel 0 Dec 7 08 :35 file2 -rw-r--r--. 1 vagrant wheel 6 Dec 7 21 :45 file3 drwxr-xr-x. 1 vagrant wheel 10 Dec 7 21 :45 subdir1 $ ll ./dir1/subdir1 -rw-r--r--. 1 vagrant wheel 27 Dec 7 21 :45 file4 # \u7528dir1\u7684\u5185\u5bb9\u8986\u76d6dir2\u7684\u5185\u5bb9\uff0c\u7cfb\u7edf\u62d2\u7edd\u3002 patch dir2 -p3 < patchdir File dir2 is not a regular file -- refusing to patch 1 out of 1 hunk ignored -- saving rejects to file dir2.rej File dir2 is not a regular file -- refusing to patch 1 out of 1 hunk ignored -- saving rejects to file dir2.rej $ patch /home/vagrant/dir2 -p3 < patchdir File /home/vagrant/dir2 is not a regular file -- refusing to patch 1 out of 1 hunk ignored -- saving rejects to file /home/vagrant/dir2.rej File /home/vagrant/dir2 is not a regular file -- refusing to patch 1 out of 1 hunk ignored -- saving rejects to file /home/vagrant/dir2.rej 2.14.3. vimdiff \u00b6 \u547d\u4ee4 vimdiff \u76f8\u5f53\u4e8e vim -d \u3002 \u4e3e\u4f8b\uff1a vimdiff text1 text2 2.14.4. cmp \u00b6 \u547d\u4ee4 cmp \u67e5\u770b\u4e8c\u8fdb\u5236\u6587\u4ef6\u7684\u4e0d\u540c\u3002 $ cmp cp grep cp grep differ: byte 25 , line 1 $ cmp /usr/bin/ls /usr/bin/dir /usr/bin/ls /usr/bin/dir differ: byte 613 , line 1 # \u8df3\u8fc7\u524d735\u4e2a\u5b57\u8282\uff0c\u8f93\u51fa\u540e\u976230\u4e2a\u5b57\u8282\u5185\u5bb9 $ hexdump -s 735 -Cn 30 /usr/bin/ls 000002df 00 00 00 00 00 5d 00 00 00 50 00 00 00 68 00 00 | ..... ] ...P...h.. | 000002ef 00 6a 00 00 00 4f 00 00 00 00 00 00 00 1d | .j...O........ | 000002fd $ hexdump -s 735 -Cn 30 /usr/bin/dir 000002df 00 00 00 00 00 5d 00 00 00 50 00 00 00 68 00 00 | ..... ] ...P...h.. | 000002ef 00 6a 00 00 00 4f 00 00 00 00 00 00 00 1d | .j...O........ | 000002fd","title":"\u7b2c\u56db\u7ae0 \u6587\u672c\u7f16\u8f91"},{"location":"linux/SRE/04-TextTools/#_1","text":"","title":"\u7b2c\u56db\u7ae0 \u6587\u672c\u7f16\u8f91"},{"location":"linux/SRE/04-TextTools/#1","text":"","title":"1.\u6587\u672c\u7f16\u8f91\u5668"},{"location":"linux/SRE/04-TextTools/#11vim","text":"vim\u547d\u4ee4\u683c\u5f0f\uff1a +# file : \u6253\u5f00\u6587\u4ef6\u540e\uff0c\u8ba9\u5149\u6807\u5904\u4e8e\u7b2c#\u884c\u9996\uff0c+\u9ed8\u8ba4\u884c\u5c3e +/PATTERN file : \u6253\u5f00\u6587\u4ef6\u6709\uff0c\u8ba9\u5149\u6807\u5904\u4e8e\u7b2c\u4e00\u4e2a\u88abPATTERN\u5339\u914d\u5230\u7684\u884c\u9996 -b file : \u4e8c\u8fdb\u5236\u65b9\u5f0f\u6253\u5f00\u6587\u4ef6 -d file1 file2 ... : \u6bd4\u8f83\u591a\u4e2a\u6587\u4ef6\uff0c\u76f8\u5f53\u4e8e vimdiff -m file : \u53ea\u8bfb\u65b9\u5f0f\u6253\u5f00\u6587\u4ef6 -e file : \u8fdb\u5165ex\u6a21\u5f0f\uff0c\u76f8\u5f53\u4e8e ex file -y file : vim\u4e09\u79cd\u5e38\u89c1\u6a21\u5f0f\uff1a \u666e\u901a\u6a21\u5f0fNormal\u6216\u547d\u4ee4\u6a21\u5f0f \u63d2\u5165Insert\u6216\u7f16\u8f91\u6a21\u5f0f \u6269\u5c55\u547d\u4ee4\u6a21\u5f0fExtended Command \u4e09\u79cd\u6a21\u5f0f\u5207\u6362 \u547d\u4ee4\u6a21\u5f0f\u2192\u63d2\u5165\u6a21\u5f0f i\uff1ainsert\uff0c\u5728\u5149\u6807\u5904\u8f93\u5165 I\uff1a\u5728\u5149\u6807\u6240\u5728\u884c\u9996\u8f93\u5165 a\uff1aappend\uff0c\u5728\u5149\u6807\u5904\u540e\u9762\u8f93\u5165 A\uff1a\u5728\u5149\u6807\u6240\u5728\u884c\u5c3e\u8f93\u5165 o\uff1a\u5728\u5149\u6807\u6240\u5728\u884c\u7684\u4e0b\u65b9\u6253\u5f00\u4e00\u4e2a\u65b0\u884c O\uff1a\u5728\u5149\u6807\u6240\u5728\u884c\u7684\u4e0a\u65b9\u6253\u5f00\u4e00\u4e2a\u65b0\u884c \u63d2\u5165\u6a21\u5f0f\u2192 ESC \u2192 \u547d\u4ee4\u6a21\u5f0f \u547d\u4ee4\u6a21\u5f0f\u2192 : \u2192 \u6269\u5c55\u547d\u4ee4\u6a21\u5f0f \u6269\u5c55\u547d\u4ee4\u6a21\u5f0f\u2192 ESC, enter \u2192 \u547d\u4ee4\u6a21\u5f0f \u6269\u5c55\u547d\u4ee4\u6a21\u5f0f\u5e38\u7528\u547d\u4ee4\uff1a :wq : \u4fdd\u5b58\u6587\u4ef6\u5e76\u9000\u51fa :w : \u4fdd\u5b58\u6587\u4ef6 :w filename : \u5199\u5165\u6307\u5b9a\u6587\u4ef6\uff0c\u76f8\u5f53\u4e8e\u53e6\u5b58\u4e3a :q! : \u653e\u5f03\u4efb\u4f55\u4fee\u6539\u5e76\u9000\u51fa ZQ : \u65e0\u6761\u4ef6\u9000\u51fa :join : \u5408\u5e76\u591a\u884c J : \u5408\u5e76\u4e24\u884c \u8bbe\u7f6e\uff1a\uff08\u53ef\u4ee5\u5728 /etc/vimrc \u6587\u4ef6\u4e2d\u914d\u7f6e\uff09 :set textwidth : \u8bbe\u7f6e\u6587\u672c\u5bbd\u5ea6\uff08\u4ece\u5de6\u5411\u53f3\u8ba1\u6570\uff09 :set wrapmargin=# : \u8bbe\u7f6e\u884c\u8fb9\u8ddd\uff08\u4ece\u53f3\u5411\u5de6\u8ba1\u6570\uff09 :set endofline : \u8bbe\u7f6e\u6587\u4ef6\u7ed3\u675f\u7b26 :set noendofline : \u53d6\u6d88\u6587\u4ef6\u7ed3\u675f\u7b26 :set wrap : \u81ea\u52a8\u6362\u884c :set nowrap : \u53d6\u6d88\u81ea\u52a8\u6362\u884c :set number : \u663e\u793a\u884c\u53f7 :set nonumber : \u53d6\u6d88\u663e\u793a\u884c\u53f7 :set list : \u8fdb\u5165List Mode\uff0c\u663e\u793aTab ^I\uff0c\u6362\u884c\u7b26\uff0c\u548c$\u663e\u793a :set nolist : \u9000\u51faList Mode :set ignorecase : \u5ffd\u7565\u5b57\u7b26\u7684\u5927\u5c0f\u5199 :set noic : \u4e0d\u5ffd\u7565\u5b57\u7b26\u5927\u5c0f\u5199 :set autoindent : \u542f\u7528\u81ea\u52a8\u7f29\u8fdb :set noai : \u5173\u95ed\u81ea\u52a8\u7f29\u8fdb :set hlsearch : \u542f\u7528\u9ad8\u4eae\u641c\u7d22 :set nohlsearch : \u5173\u95ed\u9ad8\u4eae\u641c\u7d22 :set fileformat=dos : \u542f\u7528windows\u683c\u5f0f :set fileformat=unix : \u542f\u7528unix\u683c\u5f0f :set expandtab : \u542f\u7528\u7a7a\u683c\u4ee3\u66ffTAB\uff0c\u9ed8\u8ba48\u4e2a\u7a7a\u683c\u4ee3\u66ff\u4e00\u4e2aTAB :set noexpandtab : \u5173\u95ed\u7a7a\u683c\u4ee3\u66ffTAB :set tabstop=# : \u6307\u5b9a#\u4e2a\u7a7a\u683c\u4ee3\u66ff\u4e00\u4e2aTAB :set shiftwidth=# : \u8bbe\u7f6e#\u4e2a\u7f29\u8fdb\u5bbd\u5ea6 :set cursorline : \u8bbe\u7f6e\u5149\u6807\u6240\u5728\u884c\u7684\u8868\u793a\u7ebf :set cursorline : \u5173\u95ed\u5149\u6807\u6240\u5728\u884c\u7684\u8868\u793a\u7ebf :set key=PASSWORD : \u542f\u7528\u5bc6\u7801\u4fdd\u62a4 :set key= : \u5173\u95ed\u5bc6\u7801\u4fdd\u62a4 :help option-list : \u83b7\u53d6\u5e2e\u52a9 \u67e5\u627e /pattern : \u4ece\u5149\u6807\u5f00\u59cb\u5904\u5411\u6587\u4ef6\u5c3e\u641c\u7d22pattern ?pattern : \u4ece\u5149\u6807\u5f00\u59cb\u5904\u5411\u6587\u4ef6\u9996\u641c\u7d22pattern n : \u5728\u540c\u4e00\u65b9\u5411\u91cd\u590d\u4e0a\u4e00\u6b21\u641c\u7d22\u547d\u4ee4 N : \u5728\u53cd\u65b9\u5411\u4e0a\u91cd\u590d\u4e0a\u4e00\u6b21\u641c\u7d22\u547d\u4ee4 # : \u5411\u4e0a\u5b8c\u6574\u5339\u914d\u5149\u6807\u4e0b\u7684\u5355\u8bcd, \u76f8\u5f53\u4e8e\uff1fword * : \u5411\u4e0b\u5b8c\u6574\u5339\u914d\u5149\u6807\u4e0b\u7684\u5355\u8bcd, \u76f8\u5f53\u4e8e/word % : \u67e5\u627e\u5bf9\u5e94\u7684( [ {\u5339\u914d nfx : \u5728\u5f53\u524d\u884c\u67e5\u627e\u5149\u6807\u540e\u7b2cn\u4e2ax\uff08\u4e00\u822c\u76f4\u63a5fx\uff09 \u66ff\u6362 :%s/\\n//g : \u5220\u9664\u6362\u884c\u7b26 :s/p1/p2/g : \u5c06\u5f53\u524d\u884c\u4e2d\u6240\u6709p1\u5747\u7528p2\u66ff\u4ee3, \u65e0g\uff0c\u5219\u53ea\u66ff\u6362\u7b2c\u4e00\u4e2a :s/p1/p2/c : \u67e5\u627e\u66ff\u6362\u8981\u6c42\u786e\u8ba4 :n1,n2s/p1/p2/g : \u5c06\u7b2cn1\u81f3n2\u884c\u4e2d\u6240\u6709p1\u5747\u7528p2\u66ff\u4ee3 :%s/p1/p2/g : \u5168\u5c40\uff0c\u4f7f\u7528p2\u66ff\u6362p1 :%s/p1/p2/gc : \u66ff\u6362\u524d\u8be2\u95ee :n,$s/vivian/sky/ : \u66ff\u6362\u7b2cn\u884c\u5f00\u59cb\u5230\u6700\u540e\u4e00\u884c\u4e2d\u6bcf\u4e00\u884c\u7684\u7b2c\u4e00\u4e2avivian\u4e3asky\uff0cn\u4e3a\u6570\u5b57 :.,$s/vivian/sky/g : \u66ff\u6362\u5f53\u524d\u884c\u5f00\u59cb\u5230\u6700\u540e\u4e00\u884c\u4e2d\u6bcf\u4e00\u884c\u6240\u6709vivian\u4e3asky :s/vivian\\//sky\\// : \u66ff\u6362\u5f53\u524d\u884c\u7b2c\u4e00\u4e2avivian/\u4e3asky/\uff0c\u53ef\u4ee5\u4f7f\u7528\\\u4f5c\u4e3a\u8f6c\u4e49\u7b26 :1,$s/^/some string/ : \u5728\u6587\u4ef6\u7684\u7b2c\u4e00\u884c\u81f3\u6700\u540e\u4e00\u884c\u7684\u884c\u9996\u524d\u63d2\u5165some string :%s/$/some string/g : \u5728\u6574\u4e2a\u6587\u4ef6\u6bcf\u4e00\u884c\u7684\u884c\u5c3e\u6dfb\u52a0some string :%s/\\s\\+$// : \u53bb\u6389\u6240\u6709\u7684\u884c\u5c3e\u7a7a\u683c\uff0c\u201c\\s\u201d\u8868\u793a\u7a7a\u767d\u5b57\u7b26\uff08\u7a7a\u683c\u548c\u5236\u8868\u7b26\uff09\uff0c\u201c+\u201d\u5bf9\u524d\u9762\u7684\u5b57\u7b26\u5339\u914d\u4e00\u6b21\u6216\u591a\u6b21\uff08\u8d8a\u591a\u8d8a\u597d\uff09\uff0c\u201c \\(\u201d\u5339\u914d\u884c\u5c3e\uff08\u4f7f\u7528\u201c\\$\u201d\u8868\u793a\u5355\u7eaf\u7684\u201c\\) \u201d\u5b57\u7b26\uff09 :%s/\\s\u2217\\n\\+/\\r/ : \u53bb\u6389\u6240\u6709\u7684\u7a7a\u767d\u884c\uff0c\u201c \\(\u201d\u548c\u201c\\) \u201d\u5bf9\u8868\u8fbe\u5f0f\u8fdb\u884c\u5206\u7ec4\uff0c\u4f7f\u5176\u88ab\u89c6\u4f5c\u4e00\u4e2a\u4e0d\u53ef\u5206\u5272\u7684\u6574\u4f53 :%s!\\s*//.*!! : \u53bb\u6389\u6240\u6709\u7684\u201c//\u201d\u6ce8\u91ca :%s!\\s*/\\*\\_.\\{-}\\*/\\s*!!g : \u53bb\u6389\u6240\u6709\u7684\u201c/**/\u201d\u6ce8\u91ca :%s= *$== : \u5c06\u6240\u6709\u884c\u5c3e\u591a\u4f59\u7684\u7a7a\u683c\u5220\u9664 :g/^\\s*$/d : \u5c06\u6240\u6709\u4e0d\u5305\u542b\u5b57\u7b26(\u7a7a\u683c\u4e5f\u4e0d\u5305\u542b)\u7684\u7a7a\u884c\u5220\u9664 r : \u66ff\u6362\u5f53\u524d\u5b57\u7b26 R : \u66ff\u6362\u5f53\u524d\u5b57\u7b26\u53ca\u5176\u540e\u7684\u5b57\u7b26\uff0c\u76f4\u81f3\u6309ESC\u952e \u7f16\u8f91 h : \u5149\u6807\u5de6\u79fb\u4e00\u4e2a\u5b57\u7b26[\u56de\u9000\u952eBackspace] l : \u5149\u6807\u53f3\u79fb\u4e00\u4e2a\u5b57\u7b26[\u7a7a\u683c\u952eSpace] K : \u5149\u6807\u4e0a\u79fb\u4e00\u884c j : \u5149\u6807\u4e0b\u79fb\u4e00\u884c w : \u5149\u6807\u8df3\u5230\u4e0b\u4e2aword\u7684\u7b2c\u4e00\u4e2a\u5b57\u6bcd(\u5305\u62ec\u6807\u70b9\u7b26\u53f7) [\u5e38\u7528] W : \u79fb\u5230\u4e0b\u4e00\u4e2a\u5b57\u7684\u5f00\u5934\uff0c\u5ffd\u7565\u6807\u70b9\u7b26\u53f7 B : \u5149\u6807\u56de\u5230\u4e0a\u4e2aword\u7684\u7b2c\u4e00\u4e2a\u5b57\u6bcd B : \u79fb\u5230\u524d\u4e00\u4e2a\u5b57\u7684\u5f00\u5934\uff0c\u5ffd\u7565\u6807\u70b9\u7b26\u53f7 BACK E : \u5149\u6807\u8df3\u5230\u4e0b\u4e2aword\u7684\u6700\u540e\u4e00\u4e2a\u5b57\u6bcd E : \u79fb\u5230\u4e0b\u4e00\u4e2a\u5b57\u7684\u7ed3\u5c3e\uff0c\u5ffd\u7565\u6807\u70b9\u7b26\u53f7 END 0 : \u79fb\u5230\u5f53\u524d\u4e00\u884c\u7684\u5f00\u59cb[Home] $ : \u79fb\u5230\u5f53\u524d\u4e00\u884c\u7684\u6700\u540e[End] ^ : \u547d\u4ee4\u5c06\u5149\u6807\u79fb\u52a8\u5230\u5f53\u524d\u884c\u7684\u7b2c\u4e00\u4e2a\u975e\u7a7a\u767d\u5b57\u7b26\u4e0a g_ : \u5230\u672c\u884c\u6700\u540e\u4e00\u4e2a\u4e0d\u662fblank\u5b57\u7b26\u7684\u4f4d\u7f6e Enter : \u5149\u6807\u4e0b\u79fb\u4e00\u884c n+ : \u5149\u6807\u4e0b\u79fbn\u884c\u3010\u6309\u4e0a\u6863\u952e \u6570\u5b57shift +\u3011 n- : \u5149\u6807\u4e0a\u79fbn\u884c G : \u79fb\u5230\u6587\u4ef6\u7684\u6700\u540e\u4e00\u884c nG \u6216\u8005 :n : \u79fb\u5230\u6587\u4ef6\u7684\u7b2cn\u884c\ue5e5\ue5e5\ue5e5 gg : \u79fb\u52a8\u5230\u6587\u6863\u7684\u5f00\u59cb [[ : \u6587\u4ef6\u5f00\u59cb\u4f4d\u7f6e\u2014\u2014\u5f00\u59cb\u884c ]] : \u6587\u4ef6\u7ed3\u675f\u4f4d\u7f6e\u2014\u2014\u672b\u5c3e\u884c H : \u5149\u6807\u79fb\u81f3\u5c4f\u5e55\u9876\u884cHEAD\u3002\u5149\u6807\u5b9a\u4f4d\u5728\u663e\u793a\u5c4f\u7684\u7b2c\u4e00\u884c M : \u79fb\u5230\u5c4f\u5e55\u7684\u4e2d\u95f4\u884c\u5f00\u5934 Middle\u3002\u5149\u6807\u5b9a\u4f4d\u5728\u663e\u793a\u5c4f\u7684\u4e2d\u95f4 L : \u79fb\u5230\u5c4f\u5e55\u7684\u6700\u540e\u4e00\u884cLAST\u3002\u5149\u6807\u5b9a\u4f4d\u5728\u663e\u793a\u5c4f\u7684\u6700\u540e\u4e00\u884c ( : \u5149\u6807\u79fb\u81f3\u53e5\u9996 ) : \u5149\u6807\u79fb\u81f3\u53e5\u5c3e { : \u79fb\u5230\u6bb5\u843d\u7684\u5f00\u5934 } : \u79fb\u5230\u4e0b\u4e00\u4e2a\u6bb5\u843d\u7684\u5f00\u5934 % : \u5339\u914d\u62ec\u53f7\u79fb\u52a8\uff0c\u5305\u62ec (, {, [.\uff08\u9700\u8981\u628a\u5149\u6807\u5148\u79fb\u5230\u62ec\u53f7\u4e0a\uff09\u8df3\u8f6c\u5230\u4e0e\u4e4b\u5339\u914d\u7684\u62ec\u53f7\u5904 * \u548c # : \u5339\u914d\u5149\u6807\u5f53\u524d\u6240\u5728\u7684\u5355\u8bcd\uff0c\u79fb\u52a8\u5149\u6807\u5230\u4e0b\u4e00\u4e2a\uff08\u6216\u4e0a\u4e00\u4e2a\uff09\u5339\u914d\u5355\u8bcd\uff08*\u662f\u4e0b\u4e00\u4e2a\uff0c#\u662f\u4e0a\u4e00\u4e2a\uff09 zf : \u6298\u53e0\uff08\u9700\u52a0\u65b9\u5411\u952e\uff09 zo : \u5c55\u5f00\uff08\u7a7a\u683c\u4e5f\u53ef\u4ee5\u5c55\u5f00\uff09 CTRL+u : \u5411\u6587\u4ef6\u9996\u7ffb\u534a\u5c4fup CTRL+d : \u5411\u6587\u4ef6\u5c3e\u7ffb\u534a\u5c4fdown CTRL+f : \u5411\u6587\u4ef6\u5c3e\u7ffb\u4e00\u5c4f forward (fact\u6574\u5c4f\u53bb\u4e24\u884c) CTRL+b : \u5411\u6587\u4ef6\u9996\u7ffb\u4e00\u5c4fback (fact\u6574\u5c4f\u53bb\u4e24\u884c) CTRL-] : \u8df3\u8f6c\u5230\u5f53\u524d\u5149\u6807\u6240\u5728\u5355\u8bcd\u5bf9\u5e94\u7684\u4e3b\u9898 CTRL-O : \u56de\u5230\u524d\u4e00\u4e2a\u4f4d\u7f6e SHIFT+V : \u9009\u62e9\u6574\u884c zz : \u547d\u4ee4\u4f1a\u628a\u5f53\u524d\u884c\u7f6e\u4e3a\u5c4f\u5e55\u6b63\u4e2d\u592e(z\u5b57\u53d6\u5176\u8c61\u5f62\u610f\u4e49\u6a21\u62df\u4e00\u5f20\u7eb8\u7684\u6298\u53e0\u53ca\u53d8\u5f62\u4f4d\u7f6e\u91cd\u7f6e) zt : \u547d\u4ee4\u4f1a\u628a\u5f53\u524d\u884c\u7f6e\u4e8e\u5c4f\u5e55\u9876\u7aef(top) zb : \u547d\u4ee4\u4f1a\u628a\u5f53\u524d\u884c\u7f6e\u4e8e\u5c4f\u5e55\u5e95\u7aef(bottom) 50% : \u5149\u6807\u5b9a\u4f4d\u5728\u6587\u4ef6\u7684\u4e2d\u95f4 ` : \u8df3\u8f6c\u5230\u6700\u8fd1\u5149\u6807\u5b9a\u4f4d\u7684\u4f4d\u7f6e\uff08\u53ea\u80fd\u8bb0\u5fc6\u6700\u8fd1\u4e24\u4e2a\u4f4d\u7f6e\uff09 \u53cd\u5f15\u53f7 I : \u5728\u5149\u6807\u524d\u5f00\u59cb\u63d2\u5165\u5b57\u7b26 insert I : \u5728\u5f53\u524d\u884c\u9996\u5f00\u59cb\u63d2\u5165\u5b57\u7b26 A : \u5728\u5149\u6807\u4f4d\u7f6e\u540e\u5f00\u59cb\u52a0\u5b57 append A : \u5728\u5149\u6807\u6240\u5728\u884c\u7684\u6700\u540e\u9762\u5f00\u59cb\u52a0\u5b57 O : \u5728\u5149\u6807\u4e0b\u52a0\u4e00\u7a7a\u767d\u884c\u5e76\u5f00\u59cb\u52a0\u5b57 open O : \u5728\u5149\u6807\u4e0a\u52a0\u4e00\u7a7a\u767d\u884c\u5e76\u5f00\u59cb\u52a0\u5b57 R : \u66ff\u6362\u5f53\u524d\u5b57\u7b26 R : \u66ff\u6362\u5f53\u524d\u5b57\u7b26\u53ca\u5176\u540e\u7684\u5b57\u7b26\u3010\u5f53\u524d\u53ca\u5176\u540e\u5b57\u7b26\u88ab\u8986\u76d6\u3011 S : \u9ed8\u8ba4\u5220\u9664\u5149\u6807\u6240\u5728\u5b57\u7b26\uff0c\u8f93\u5165\u5185\u5bb9\u63d2\u5165\u4e4b= xi S : \u9ed8\u8ba4\u5220\u9664\u5f53\u524d\u884c\u5185\u5bb9\uff0c\u8f93\u5165\u5185\u5bb9\u4f5c\u4e3a\u5f53\u524d\u884c\u65b0\u5185\u5bb9= dd+o nx : \u5220\u9664\u7531\u5149\u6807\u4f4d\u7f6e\u8d77\u59cb\u540e\u7684n\u4e2a\u5b57\u7b26\uff08\u542b\u5149\u6807\u4f4d\u7f6e\uff09x =dl(\u5220\u9664\u5f53\u524d\u5149\u6807\u4e0b\u7684\u5b57\u7b26) nX : \u5220\u9664\u7531\u5149\u6807\u4f4d\u7f6e\u8d77\u59cb\u524d\u7684n\u4e2a\u5b57\u7b26\uff08\u542b\u5149\u6807\u4f4d\u7f6e\uff09X =dh(\u5220\u9664\u5f53\u524d\u5149\u6807\u5de6\u8fb9\u7684\u5b57\u7b26) d0 : \u5220\u81f3\u884c\u9996 d$ : \u5220\u81f3\u884c\u5c3e dfa : \u8868\u793a\u5220\u9664\u4ece\u5f53\u524d\u5149\u6807\u5230\u5149\u6807\u540e\u9762\u7684\u7b2c\u4e00\u4e2aa\u5b57\u7b26\u4e4b\u95f4\u7684\u5185\u5bb9 D : \u4ee3\u8868d$(\u5220\u9664\u5230\u884c\u5c3e\u7684\u5185\u5bb9) C : \u4ee3\u8868c$(\u4fee\u6539\u5230\u884c\u5c3e\u7684\u5185\u5bb9) ndw : \u5220\u9664\u5149\u6807\u5904\u5f00\u59cb\u53ca\u5176\u540e\u7684n-1\u4e2a\u5b57 ndb : \u5220\u9664\u5149\u6807\u5904\u5f00\u59cb\u53ca\u5176\u524d\u7684n-1\u4e2a\u5b57 diw : \u5220\u9664\u5f53\u524d\u5149\u6807\u6240\u5728\u7684word(\u4e0d\u5305\u62ec\u7a7a\u767d\u5b57\u7b26)\uff0c\u610f\u4e3aDelete Inner Word \u4e24\u4e2a\u7b26\u53f7\u4e4b\u95f4\u7684\u5355\u8bcd daw : \u5220\u9664\u5f53\u524d\u5149\u6807\u6240\u5728\u7684word(\u5305\u62ec\u7a7a\u767d\u5b57\u7b26)\uff0c\u610f\u4e3aDelete A Word ndd : \u5220\u9664\u5f53\u524d\u884c\u53ca\u5176\u540en-1\u884c :n1,n2 d : \u5c06 n1\u884c\u5230n2\u884c\u4e4b\u95f4\u7684\u5185\u5bb9\u5220\u9664 dG : \u5220\u9664\u5f53\u524d\u884c\u81f3\u6587\u4ef6\u5c3e\u7684\u5185\u5bb9 Dgg : \u5220\u9664\u5f53\u524d\u884c\u81f3\u6587\u4ef6\u5934\u7684\u5185\u5bb9 d+enter : \u5220\u96642\u884c\u3010\u5305\u62ec\u5149\u6807\u4e00\u884c\u3011 cw : \u5220\u9664\u5f53\u524d\u5b57\uff0c\u5e76\u8fdb\u5165\u8f93\u5165\u6a21\u5f0f\u3010\u5f88\u597d\u7528\uff0c\u5feb\u901f\u66f4\u6539\u4e00\u4e2a\u5355\u8bcd\u3011\u76f8\u5f53\u4e8edw+i ncw : \u5220\u9664\u5f53\u524d\u5b57\u53ca\u5176\u540e\u7684n-1\u4e2a\u5b57\uff0c\u5e76\u8fdb\u5165\u8f93\u5165\u6a21\u5f0f\\\u4fee\u6539\u6307\u5b9a\u6570\u76ee\u7684\u5b57 cc : \u5220\u9664\u5f53\u524d\u884c\uff0c\u5e76\u8fdb\u5165\u8f93\u5165\u6a21\u5f0f ncc : \u5220\u9664\u5f53\u524d\u884c\u53ca\u5176\u540e\u7684n-1\u884c\uff0c\u5e76\u8fdb\u5165\u8f93\u5165\u6a21\u5f0f guw : \u5149\u6807\u4e0b\u7684\u5355\u8bcd\u53d8\u4e3a\u5c0f\u5199 gUw : \u5149\u6807\u4e0b\u7684\u5355\u8bcd\u53d8\u4e3a\u5927\u5199 xp : \u5de6\u53f3\u4ea4\u6362\u5149\u6807\u5904\u4e24\u5b57\u7b26\u7684\u4f4d\u7f6e ga : \u663e\u793a\u5149\u6807\u4e0b\u7684\u5b57\u7b26\u5728\u5f53\u524d\u4f7f\u7528\u7684encoding\u4e0b\u7684\u5185\u7801 nyl : \u590d\u5236n\u4e2a\u5b57\u7b26(\u4e5f\u53efnyh) yw : \u590d\u5236\u4e00\u4e2a\u5355\u8bcd y0 : \u8868\u793a\u62f7\u8d1d\u4ece\u5f53\u524d\u5149\u6807\u5230\u5149\u6807\u6240\u5728\u884c\u9996\u7684\u5185\u5bb9 y$ : \u590d\u5236\u4ece\u5f53\u524d\u4f4d\u7f6e\u5230\u884c\u5c3e yfa : \u8868\u793a\u62f7\u8d1d\u4ece\u5f53\u524d\u5149\u6807\u5230\u5149\u6807\u540e\u9762\u7684\u7b2c\u4e00\u4e2aa\u5b57\u7b26\u4e4b\u95f4\u7684\u5185\u5bb9 yG : \u590d\u5236\u4ece\u6240\u5728\u884c\u5230\u6700\u540e\u4e00\u884c nyy : \u5c06\u5149\u6807\u6240\u5728\u4f4d\u7f6e\u5f00\u59cb\u7684n\u884c\u6570\u636e\u590d\u5236\u6682\u5b58, \u590d\u5236\u4e00\u6574\u884c CTRL+v \u65b9\u5411y : \u5217\u9009\u62e9\u6a21\u5f0f\uff0c\u590d\u5236\u9009\u62e9\u7684\u5f88\u591a\u884c\uff1a\u5148\u4f7f\u7528V\u8fdb\u5165visual\u6a21\u5f0f\uff0c\u7136\u540ej\u5411\u4e0b\u79fb\u52a8\u5230\u4f60\u60f3\u590d\u5236\u7684\u884c\u4e3a\u6b62\uff0c\u7136\u540ey p : \u590d\u5236\u6682\u5b58\u6570\u636e\u5728\u5149\u6807\u7684\u4e0b\u4e00\u884c P : \u590d\u5236\u6682\u5b58\u6570\u636e\u5728\u5149\u6807\u7684\u4e0a\u4e00\u884c :n1,n2 co n3 : \u5c06n1\u884c\u5230n2\u884c\u4e4b\u95f4\u7684\u5185\u5bb9\u62f7\u8d1d\u5230\u7b2cn3+1\u884c\u3010n3\u884c\u7684\u4e0b\u4e00\u884c\u3011 :n1,n2 m n3 : \u5c06n1\u884c\u5230n2\u884c\u4e4b\u95f4\u7684\u5185\u5bb9\u79fb\u81f3\u5230\u7b2cn3\u884c\u4e0b J : \u628a\u4e0b\u4e00\u884c\u7684\u6570\u636e\u8fde\u63a5\u5230\u672c\u884c\u4e4b\u540e, \u591a\u4e00\u7a7a\u683c ~ : \u6539\u53d8\u5f53\u524d\u5149\u6807\u4e0b\u5b57\u7b26\u7684\u5927\u5c0f\u5199 \u5176\u4ed6 . : \u91cd\u590d\u524d\u4e00\u6307\u4ee4 u : \u53d6\u6d88\u524d\u4e00\u6307\u4ee4undo, :u\u4e5f\u884c\uff0c\u4e00\u822c\u4e0d\u7528\uff0c\u64cd\u4f5c\u592a\u591a Ctrl + r : \u6062\u590d\u3010\u53ea\u5bf9u\u6709\u6548\u3011redo Ctrl + l : \u5237\u65b0\u5c4f\u5e55\u663e\u793a Ctrl+v \u7136\u540e ctrl+A\u662f^A Ctrl+I\u662f\\t : \u8f93\u5165\u7279\u6b8a\u5b57\u7b26 Ctrl+v\u7136\u540e\u7528j\u3001k\u3001l\u3001h\u6216\u65b9\u5411\u952e\u4e0a\u4e0b\u9009\u4e2d\u591a\u5217\uff0c\u4e4b\u540e I I a A r x\u7b49\uff0c\u6700\u540e\u6309esc\uff0c\u751f\u6548 : Vim\u5217\u64cd\u4f5c","title":"1.1.vim\u5de5\u5177"},{"location":"linux/SRE/04-TextTools/#2","text":"","title":"2.\u6587\u672c\u5904\u7406\u5de5\u5177"},{"location":"linux/SRE/04-TextTools/#21cat","text":"\u547d\u4ee4 cat \u4e3b\u8981\u53c2\u6570\u8bf4\u660e\uff1a -E \uff1a\u663e\u793a\u884c\u7ed3\u675f\u7b26 $ -A \uff1a\u663e\u793a\u6240\u6709\u63a7\u5236\u7b26 -n \uff1a\u5bf9\u663e\u793a\u51fa\u7684\u6bcf\u4e00\u884c\u8fdb\u884c\u7f16\u53f7 -b \uff1a\u975e\u7a7a\u884c\u7f16\u53f7 -s \uff1a\u538b\u7f29\u8fde\u7eed\u7684\u7a7a\u884c\u6210\u4e00\u884c \u4e3e\u4f8b\uff1a cat -nA user-list.txt 1 user0$ 2 user1$ 3 user2$ 4 user3$ 5 user4$ 6 user5$ 7 user6$ 8 user7$ 9 user8$ 10 user9$","title":"2.1.\u663e\u793a\u6587\u672c\u5185\u5bb9cat"},{"location":"linux/SRE/04-TextTools/#22nl","text":"\u76f8\u5f53\u4e8e\u547d\u4ee4 cat -b \u3002 \u547d\u4ee4 nl \u4e3b\u8981\u53c2\u6570\u8bf4\u660e\uff1a -b \uff1a\u6307\u5b9a\u884c\u53f7\u6307\u5b9a\u7684\u65b9\u5f0f\uff0c\u4e3b\u8981\u6709\u4e24\u79cd\uff1a -b a \uff1a\u8868\u793a\u4e0d\u8bba\u662f\u5426\u4e3a\u7a7a\u884c\uff0c\u4e5f\u540c\u6837\u5217\u51fa\u884c\u53f7\uff08\u7c7b\u4f3c cat -n\uff09\uff1b -b t \uff1a\u5982\u679c\u6709\u7a7a\u884c\uff0c\u7a7a\u7684\u90a3\u4e00\u884c\u4e0d\u8981\u5217\u51fa\u884c\u53f7\uff08\u9ed8\u8ba4\u503c\uff09\uff1b -n \uff1a\u5217\u51fa\u884c\u53f7\u8868\u793a\u7684\u65b9\u6cd5\uff0c\u4e3b\u8981\u6709\u4e09\u79cd\uff1a -n ln \uff1a\u884c\u53f7\u5728\u5c4f\u5e55\u7684\u6700\u5de6\u65b9\u663e\u793a\uff1b\u6ca1\u6709\u524d\u5bfc0\uff1b -n rn \uff1a\u884c\u53f7\u5728\u81ea\u5df1\u680f\u4f4d\u7684\u6700\u53f3\u65b9\u663e\u793a\uff0c\u6ca1\u6709\u524d\u5bfc0\uff1b -n rz \uff1a\u884c\u53f7\u5728\u81ea\u5df1\u680f\u4f4d\u7684\u6700\u53f3\u65b9\u663e\u793a\uff0c\u6709\u524d\u5bfc0\uff1b -w \uff1a\u884c\u53f7\u680f\u4f4d\u7684\u5360\u7528\u7684\u4f4d\u6570\u3002 -p \uff1a\u5728\u903b\u8f91\u5b9a\u754c\u7b26\u5904\u4e0d\u91cd\u65b0\u5f00\u59cb\u8ba1 \u4e3e\u4f8b\uff1a $ nl -b a -n rz user-list.txt 000001 user0 000002 user1 000003 user2 000004 user3 000005 user4 000006 user5 000007 user6 000008 user7 000009 user8 000010 user9","title":"2.2.\u663e\u793a\u6587\u672c\u884c\u53f7nl"},{"location":"linux/SRE/04-TextTools/#23tac","text":"\u547d\u4ee4 tac \u9006\u5411\u663e\u793a\u6587\u672c\u5185\u5bb9\u3002 \u4e3e\u4f8b\uff1a $ tac user-list.txt user9 user8 user7 user6 user5 user4 user3 user2 user1 user0 \u4e3e\u4f8b\uff1a $ seq 10 | tac 10 9 8 7 6 5 4 3 2 1","title":"2.3.\u9006\u5411\u663e\u793a\u6587\u672c\u5185\u5bb9tac"},{"location":"linux/SRE/04-TextTools/#24rev","text":"\u547d\u4ee4 rev \u9006\u5411\u663e\u793a\u540c\u4e00\u884c\u7684\u5185\u5bb9\u3002 \u4e3e\u4f8b\uff1a $ rev user-list.txt 0resu 1resu 2resu 3resu 4resu 5resu 6resu 7resu 8resu 9resu \u4e3e\u4f8b\uff1a $ echo { 1 ..10 } | rev 01 9 8 7 6 5 4 3 2 1","title":"2.4.\u9006\u5411\u663e\u793a\u540c\u884c\u5185\u5bb9rev"},{"location":"linux/SRE/04-TextTools/#25hexdump","text":"\u547d\u4ee4 hexdump \u547d\u4ee4\u4e00\u822c\u7528\u6765\u67e5\u770b\u201c\u4e8c\u8fdb\u5236\u201d\u6587\u4ef6\u7684\u5341\u516d\u8fdb\u5236\u7f16\u7801 \u4e3e\u4f8b\uff1a $ hexdump -C -n 32 cp 00000000 7f 45 4c 46 02 01 01 00 00 00 00 00 00 00 00 00 | .ELF............ | 00000010 03 00 3e 00 01 00 00 00 e0 48 00 00 00 00 00 00 | ..>......H...... | 00000020","title":"2.5.\u663e\u793a\u975e\u6587\u672c\u6587\u4ef6\u5185\u5bb9hexdump"},{"location":"linux/SRE/04-TextTools/#26","text":"\u547d\u4ee4 more \u548c less \u53ef\u4ee5\u5b9e\u73b0\u5206\u9875\u67e5\u770b\u6587\u4ef6\u5185\u5bb9\u3002 \u547d\u4ee4 less \u914d\u5408\u7ba1\u9053\u7b26\u4f7f\u7528\u3002 tree -d /etc | less","title":"2.6.\u5206\u9875\u67e5\u770b\u6587\u4ef6\u5185\u5bb9"},{"location":"linux/SRE/04-TextTools/#27head","text":"\u547d\u4ee4 head \u663e\u793a\u6587\u4ef6\u5934\u90e8\u5185\u5bb9\u3002 head -c 20 cp : \u663e\u793a\u6587\u4ef6\u524d20\u5b57\u8282\u5185\u5bb9 head -n 20 zdiff : \u663e\u793a\u6587\u4ef6\u524d20\u884c\u5185\u5bb9 head -20 zdiff : \u663e\u793a\u6587\u4ef6\u524d20\u884c\u5185\u5bb9 $ echo \"\u6211\u662f\u8c01\" | head -c3 \u6211 $ echo \"\u6211\u662f\u8c01\" | head -c6 \u6211\u662f cat /dev/urandom | tr -dc '[:alnum]' | head -c 10 | tee passwd.txt $ cat user-list.txt user0 user1 user2 user3 user4 user5 user6 user7 user8 user9 $ head -n -3 user-list.txt user0 user1 user2 user3 user4 user5 user6","title":"2.7.\u663e\u793a\u6587\u4ef6\u5934\u90e8\u5185\u5bb9head"},{"location":"linux/SRE/04-TextTools/#28tail","text":"\u547d\u4ee4 tail \u663e\u793a\u6587\u4ef6\u5934\u90e8\u5185\u5bb9\u3002 tail -c 200 cp : \u663e\u793a\u6587\u4ef6\u5c3e\u90e8200\u4e2a\u5b57\u8282\u7684\u5185\u5bb9 tail -n 3 user-list.txt : \u663e\u793a\u6587\u4ef6\u6700\u540e3\u884c tail -n -3 user-list.txt : \u663e\u793a\u4ece-3\u884c\u5230\u6587\u4ef6\u7ed3\u675f\uff08\u5373\u6700\u540e\u4e09\u884c\uff09 tail -3 user-list.txt : \u663e\u793a\u6587\u4ef6\u6700\u540e3\u884c tail -f /var/log/messages : \u8ddf\u8e2a\u663e\u793a\u6587\u4ef6redo.log\u6587\u4ef6\u5185\u5bb9\uff0c\u5f53\u6587\u4ef6\u5220\u9664\uff0c\u518d\u5efa\u540c\u540d\u6587\u4ef6\uff0c\u65e0\u6cd5\u7ee7\u7eed\u8ffd\u8e2a tail -F /var/log/messages : \u8ddf\u8e2a\u663e\u793a\u6587\u4ef6redo.log\u6587\u4ef6\u5185\u5bb9\uff0c\u5f53\u6587\u4ef6\u5220\u9664\uff0c\u518d\u5efa\u540c\u540d\u6587\u4ef6\uff0c\u7ee7\u7eed\u8ffd\u8e2a","title":"2.8.\u663e\u793a\u6587\u4ef6\u5c3e\u90e8\u5185\u5bb9tail"},{"location":"linux/SRE/04-TextTools/#29cut","text":"\u547d\u4ee4 cut \u53ef\u4ee5\u63d0\u53d6\u6587\u672c\u6587\u4ef6\u6216\u8005stdin\u6570\u636e\u7684\u6307\u5b9a\u5217\u5185\u5bb9\u3002 \u9009\u9879\uff1a -f : \u901a\u8fc7\u6307\u5b9a\u54ea\u4e00\u4e2a\u5b57\u6bb5\u8fdb\u884c\u63d0\u53d6\u3002cut\u547d\u4ee4\u4f7f\u7528\u201cTAB\u201d\u4f5c\u4e3a\u9ed8\u8ba4\u7684\u5b57\u6bb5\u5206\u9694\u7b26 -d : \u201cTAB\u201d\u662f\u9ed8\u8ba4\u7684\u5206\u9694\u7b26\uff0c\u4f7f\u7528\u6b64\u9009\u9879\u53ef\u4ee5\u66f4\u6539\u4e3a\u5176\u4ed6\u7684\u5206\u9694\u7b26 --complement : \u6b64\u9009\u9879\u7528\u4e8e\u6392\u9664\u6240\u6307\u5b9a\u7684\u5b57\u6bb5 --output-delimiter=STRING : \u6307\u5b9a\u8f93\u51fa\u5185\u5bb9\u7684\u5206\u9694\u7b26 -c : \u6309\u5b57\u7b26\u5207\u5272 \u53d6/etc/passwd\u6587\u4ef6\u7b2c1\u5217\u5185\u5bb9\uff0c\u4ee5 : \u4e3a\u5206\u9694\u7b26\uff08\u53ea\u53d6\u524d\u4e09\u884c\uff09 $ cut -d ':' -f 1 /etc/passwd | head -3 root messagebus systemd-network \u53d6/etc/passwd\u6587\u4ef6\u7b2c1\u548c6\u5217\u5185\u5bb9\uff0c\u4ee5 : \u4e3a\u5206\u9694\u7b26\uff08\u53ea\u53d6\u524d\u4e09\u884c\uff09 cut -d ':' -f 1 ,6 /etc/passwd | head -3 root:/root messagebus:/run/dbus systemd-network:/ \u53d6/etc/passwd\u6587\u4ef6\u7b2c1\u52303\u5217\u4ee5\u53ca\u7b2c6\u5217\u5185\u5bb9\uff0c\u4ee5 : \u4e3a\u5206\u9694\u7b26\uff08\u53ea\u53d6\u524d\u4e09\u884c\uff09 $ cut -d ':' -f 1 -3,6 /etc/passwd | head -3 root:x:0:/root messagebus:x:499:/run/dbus systemd-network:x:497:/ \u4e0b\u9762\u4f7f\u7528 --output-delimiter \u9009\u9879\uff0c\u628a\u8f93\u51fa\u7ed3\u679c\u4e2d\u7684\u5206\u9694\u7b26 : \u5168\u90e8\u66ff\u6362\u6210 --- \u3002 $ cat /etc/passwd | sort | head -3 admin3:x:1020:100::/home/admin3:/bin/bash at:x:25:25:Batch jobs daemon:/var/spool/atjobs:/usr/sbin/nologin bin:x:1:1:bin:/bin:/usr/sbin/nologin $ cut -d \":\" -f 1 ,7 /etc/passwd | sort | head -3 admin3:/bin/bash at:/usr/sbin/nologin bin:/usr/sbin/nologin $ cut -d \":\" -f 1 ,7 --output-delimiter = \"---\" /etc/passwd | sort | head -3 admin3---/bin/bash at---/usr/sbin/nologin bin---/usr/sbin/nologin --output-delimiter \u9009\u9879\u4e5f\u53ef\u4ee5\u5229\u7528\u6765\u8fdb\u884c\u8ba1\u7b97\u3002 $ echo { 1 ..10 } | cut -d \" \" -f 1 -10 --output-delimiter = \"+\" | bc 55 \u4ece ifconfig \u547d\u4ee4\u4e2d\u622a\u53d6\u5f53\u524d\u4e3b\u673a\u7684ip\u5730\u5740\u3002\uff08openSUSE\u9700\u8981\u5b89\u88c5\u5305 net-tools-deprecated \uff09 $ ifconfig | head -2 | tail -1 inet 192 .168.10.210 netmask 255 .255.255.0 broadcast 192 .168.10.255 $ ifconfig | head -2 | tail -1 | cut -d \" \" -f 10 192 .168.10.210 \u6216\u8005 $ ip addr list | grep eth0 | tail -1 | cut -d \" \" -f 6 192 .168.10.210/24 \u57fa\u4e8e\u4e0a\u9762\u7ed3\u679c\uff0c\u53ef\u4ee5\u5c1d\u8bd5\u901a\u8fc7 --complement \u53c2\u6570\uff0c\u4ee5 / \u4e3a\u5206\u9694\u7b26\uff0c\u6392\u9664\u7b2c\u4e8c\u5217 24 \uff0c\u53ea\u8f93\u51fa\u7b2c\u4e00\u5217IP\u5730\u5740\u3002 ip addr list | grep eth0 | tail -1 | cut -d \" \" -f 6 | cut -d \"/\" --complement -f 2 192 .168.10.210 \u663e\u793a df \u547d\u4ee4\u8f93\u51fa\u4e2d\u7684\u5206\u533a\u4f7f\u7528\u7387\u3002 $ df | tr -s ' ' | cut -d ' ' -f 5 | tr -d % Use 0 0 2 0 8 8 8 8 8 8 8 8 8 8 8 0 \u65b9\u6cd52\uff1a\u5148\u628a\u7a7a\u683c\u5168\u90e8\u66ff\u6362\u6210%\uff0c\u518d\u53bb\u91cd\u3002 df | tr -s ' ' % | cut -d % -f 5 Use 0 0 2 0 8 8 8 8 8 8 8 8 8 8 8 0","title":"2.9.\u6309\u5217\u62bd\u53d6\u6587\u672ccut"},{"location":"linux/SRE/04-TextTools/#210paste","text":"\u547d\u4ee4 paste \u5e38\u7528\u9009\u9879\uff1a -d \uff1a\u6307\u5b9a\u5206\u9694\u7b26\uff0c\u9ed8\u8ba4\u662fTAB -s \uff1a\u6240\u6709\u884c\u5408\u6210\u4e00\u884c\u663e\u793a \u751f\u6210 alpha.log \u548c seq.log \u3002 for i in { a..z } ; do echo $i >> alpha.log ; done seq 10 > seq.log \u7528 paste \u547d\u4ee4\u5408\u5e76\u8fd92\u4e2a\u6587\u4ef6\u3002 $ paste alpha.log seq.log a 1 b 2 c 3 d 4 e 5 f 6 g 7 h 8 i 9 j 10 k l m n o p q r s t u v w x y z $ paste -d \":\" alpha.log seq.log a:1 b:2 c:3 d:4 e:5 f:6 g:7 h:8 i:9 j:10 k: l: m: n: o: p: q: r: s: t: u: v: w: x: y: z: \u539f\u6587\u4ef6\u90fd\u662f\u5217\u8f93\u51fa\uff0c\u6539\u6210\u884c\u8f93\u51fa\u3002 $ paste -d \"-\" -s alpha.log a-b-c-d-e-f-g-h-i-j-k-l-m-n-o-p-q-r-s-t-u-v-w-x-y-z $ paste -d \"-\" -s seq.log $ paste -d \":\" -s alpha.log seq.log a:b:c:d:e:f:g:h:i:j:k:l:m:n:o:p:q:r:s:t:u:v:w:x:y:z 1 :2:3:4:5:6:7:8:9:10 $ paste -d \":\" -s seq.log alpha.log 1 :2:3:4:5:6:7:8:9:10 a:b:c:d:e:f:g:h:i:j:k:l:m:n:o:p:q:r:s:t:u:v:w:x:y:z","title":"2.10.\u5408\u5e76\u591a\u4e2a\u6587\u4ef6paste"},{"location":"linux/SRE/04-TextTools/#211wc","text":"\u5e38\u7528\u9009\u9879\uff1a -l \uff1a\u53ea\u8ba1\u6570\u884c\u6570 -w \uff1a\u53ea\u8ba1\u6570\u5355\u8bcd\u603b\u6570 -c \uff1a\u53ea\u8ba1\u6570\u5b57\u8282\u603b\u6570 -m \uff1a\u53ea\u8ba1\u6570\u5b57\u7b26\u603b\u6570 -L \uff1a\u663e\u793a\u6587\u4ef6\u4e2d\u6700\u957f\u884c\u7684\u957f\u5ea6 $ cat text Tom, 20 , Shanghai Jack, 30 , Beijing Smith, 40 , Guangzhou $ wc text # \u884c\u6570 \u5355\u8bcd\u6570 \u5b57\u8282\u6570 3 9 57 text $ wc -l text 3 text $ wc -w text 9 text $ wc -c text 57 text $ wc -m text 57 text $ wc -L text 20 text \u5bf9\u6bd4\u4e24\u79cd\u4e0d\u540c\u5408\u5e76\u7684\u65b9\u6cd5\u3002 $ cat text1 text2 Tom, 20 , Shanghai Jack, 30 , Beijing Smith, 40 , Guangzhou Tom, 20 , Shanghai Jack, 30 , Beijing Leo, 40 , Guangzhou $ paste text1 text2 Tom, 20 , Shanghai Tom, 20 , Shanghai Jack, 30 , Beijing Jack, 30 , Beijing Smith, 40 , Guangzhou Leo, 40 , Guangzhou","title":"2.11.\u6587\u672c\u7edf\u8ba1\u6570\u636ewc"},{"location":"linux/SRE/04-TextTools/#212sort","text":"\u547d\u4ee4 sort \u628a\u6574\u7406\u8fc7\u7684\u6587\u672c\u663e\u793a\u5728stdout\u4e0a\uff0c\u4e0d\u6539\u53d8\u539f\u6587\u4ef6\u3002 \u5e38\u7528\u9009\u9879\uff1a -r \uff1a\u6267\u884c\u53cd\u65b9\u5411\uff08\u4ece\u4e0a\u81f3\u4e0b\uff09\u6392\u5e8f -R \uff1a\u968f\u673a\u6392\u5e8f -n \uff1a\u6309\u6570\u5b57\u5927\u5c0f\u6392\u5e8f -h \uff1a\u4eba\u7c7b\u53ef\u8bfb\u6392\u5e8f\uff0c\u5982\uff1a2K\uff0c1G -f \uff1a\u6392\u5e8f\u65f6\u5c06\u5c0f\u5199\u5b57\u6bcd\u89c6\u4e3a\u5927\u5199\u5b57\u6bcd -u \uff1a\u6392\u5e8f\u65f6\u5408\u5e76\u91cd\u590d\u9879 -t c \uff1a\u4f7f\u7528c\u4f5c\u4e3a\u5b57\u6bb5\u5206\u9694\u7b26 -k # \uff1a\u6309\u7167\u4ee5c\u4e3a\u5206\u9694\u7b26\u7684\u7b2c#\u5217\u6765\u6392\u5e8f \u4e3e\u4f8b\uff1a\u4ee5 , \u4e3a\u5206\u9694\u7b26\uff0c\u8bfb\u53d6 text \u6587\u4ef6\u5185\u5bb9\u4e2d\u7b2c1\uff0c3\u5217\uff0c\u5bf9\u8f93\u51fa\u7ed3\u679c\u4ee5 , \u4e3a\u5206\u9694\u7b26\uff0c\u6309\u7b2c\u4e8c\u5217\u6392\u5e8f\uff08\u6b63\u5e8f\u548c\u53cd\u5e8f\uff09\u3002 $ cat text Tom, 20 , Shanghai Jack, 30 , Beijing Smith, 40 , Guangzhou $ cut -d \",\" -f 1 ,3 text | sort -t \",\" -k 1 Jack, Beijing Smith, Guangzhou Tom, Shanghai $ cut -d \",\" -f 1 ,3 text | sort -t \",\" -k 1 -r Tom, Shanghai Smith, Guangzhou Jack, Beijing \u628a\u6587\u4ef6text1\u548c\u6587\u4ef6text2\u5408\u5e76\u540e\u53bb\u91cd\u8f93\u51fa\u3002 $ cat text2 Tom, 20 , Shanghai Jack, 30 , Beijing Leo, 40 , Guangzhou $ cat text1 Tom, 20 , Shanghai Jack, 30 , Beijing Smith, 40 , Guangzhou $ cat text1 text2 Tom, 20 , Shanghai Jack, 30 , Beijing Smith, 40 , Guangzhou Tom, 20 , Shanghai Jack, 30 , Beijing Leo, 40 , Guangzhou \u5e76\u96c6\uff0c\u91cd\u590d\u884c\u53ea\u4fdd\u7559\u4e00\u884c\u3002\u524d\u97622\u4e2a\u547d\u4ee4\u662f\u540c\u6837\u542b\u4e49\uff08\u76f8\u540c\u7684\u6392\u5e8f\u5217\uff09\uff0c\u7b2c\u4e09\u4e2a\u547d\u4ee4\u4e2d\u5bf9\u4e0d\u540c\u5217\u8fdb\u884c\u4e86\u6392\u5e8f\uff0c\u5bfc\u81f4\u53bb\u91cd\u7ed3\u679c\u4e0d\u540c\u3002 $ cat text1 text2 | sort -u Jack, 30 , Beijing Leo, 40 , Guangzhou Smith, 40 , Guangzhou Tom, 20 , Shanghai $ cat text1 text2 | sort -t \",\" -k 1 -u Jack, 30 , Beijing Leo, 40 , Guangzhou Smith, 40 , Guangzhou Tom, 20 , Shanghai $ cat text1 text2 | sort -t \",\" -k 2 -u Tom, 20 , Shanghai Jack, 30 , Beijing Smith, 40 , Guangzhou","title":"2.12.\u6587\u672c\u6392\u5e8fsort"},{"location":"linux/SRE/04-TextTools/#213uniq","text":"\u547d\u4ee4 uniq \u4ece\u8f93\u5165\u4e2d\u5220\u9664\u524d\u540e\u76f8\u90bb\u91cd\u590d\u7684\u884c\u3002\u7ecf\u5e38\u4e0e sort \u547d\u4ee4\u7ed3\u5408\u4f7f\u7528\u3002 \u4e3b\u8981\u53c2\u6570\uff1a -c \uff1a\u663e\u793a\u6bcf\u884c\u91cd\u590d\u51fa\u73b0\u7684\u6b21\u6570 -d \uff1a\u4ec5\u663e\u793a\u91cd\u590d\u7684\u884c -u \uff1a\u4ec5\u663e\u793a\u4e0d\u91cd\u590d\u7684\u884c \u4e3e\u4f8b\uff0c\u6ce8\u610f\u53ea\u6709\u5bf9\u76f8\u90bb\u884c\u8fdb\u884c\u53bb\u91cd\u3002 $ cat text3 test 30 Hello 95 Hello 95 Linux 85 Linux 85 Hello 95 test 30 $ uniq text3 test 30 Hello 95 Linux 85 Hello 95 test 30 \u628a\u6587\u4ef6text1\u548c\u6587\u4ef6text2\u5408\u5e76\u540e\uff0c\u8fdb\u884c\u4ea4\u96c6\u548c\u5e76\u96c6\uff0c\u5e76\u53bb\u91cd\u3002 $ cat text1 Tom, 20 , Shanghai Jack, 30 , Beijing Smith, 40 , Guangzhou $ cat text2 Tom, 20 , Shanghai Jack, 30 , Beijing Leo, 40 , Guangzhou # \u5e76\u96c6\uff0c\u6309\u9996\u5217\u6392\u5e8f\u53bb\u91cd $ cat text1 text2 | sort | uniq Jack, 30 , Beijing Leo, 40 , Guangzhou Smith, 40 , Guangzhou Tom, 20 , Shanghai # \u4ea4\u96c6 $ cat text1 text2 | sort | uniq -d Jack, 30 , Beijing Tom, 20 , Shanghai # \u5dee\u96c6 $ cat text1 text2 | sort | uniq -u Leo, 40 , Guangzhou Smith, 40 , Guangzhou \u67e5\u770b\u5e76\u53d1\u8fde\u63a5\u6570\u6700\u591a\u7684\u8fdc\u7a0b\u4e3b\u673aIP\u3002 $ ss -nt State Recv-Q Send-Q Local Address:Port Peer Address:Port Process ESTAB 0 0 192 .168.10.210:22 192 .168.10.210:41650 ESTAB 0 0 192 .168.10.210:22 192 .168.10.201:65330 ESTAB 0 64 192 .168.10.210:22 192 .168.10.201:63289 ESTAB 0 0 192 .168.10.210:41650 192 .168.10.210:22 ESTAB 0 0 192 .168.10.210:47992 192 .168.10.210:22 ESTAB 0 0 192 .168.10.210:60268 192 .168.10.210:22 ESTAB 0 0 192 .168.10.210:22 192 .168.10.201:65327 ESTAB 0 0 192 .168.10.210:35758 192 .168.10.220:22 ESTAB 0 0 192 .168.10.210:22 192 .168.10.210:56818 ESTAB 0 0 192 .168.10.210:56818 192 .168.10.210:22 ESTAB 0 0 192 .168.10.210:48006 192 .168.10.210:22 ESTAB 0 0 192 .168.10.210:22 192 .168.10.210:60268 ESTAB 0 0 192 .168.10.210:22 192 .168.10.220:33896 ESTAB 0 0 192 .168.10.210:22 192 .168.10.201:65324 ESTAB 0 0 192 .168.10.210:22 192 .168.10.210:47992 ESTAB 0 0 192 .168.10.210:59554 192 .168.10.210:22 ESTAB 0 0 192 .168.10.210:22 192 .168.10.210:59554 ESTAB 0 0 192 .168.10.210:22 192 .168.10.210:48006 $ ss -nt | tr -s \" \" \":\" | cut -d \":\" -f 6 ,7 | sort | uniq -c | sort -nr | head -n 1 6 192 .168.10.210:22","title":"2.13.\u53bb\u91cduniq"},{"location":"linux/SRE/04-TextTools/#214","text":"","title":"2.14.\u6587\u672c\u6bd4\u8f83"},{"location":"linux/SRE/04-TextTools/#2141diff","text":"\u547d\u4ee4 diff \u6bd4\u8f83\u4e24\u4e2a\u6587\u4ef6\u4e4b\u95f4\u7684\u533a\u522b\u3002 \u5e38\u7528\u9009\u9879\uff1a -u \uff1a\u4ee5\u7edf\u4e00\u7684\u65b9\u5f0f\u6765\u663e\u793a\u6587\u4ef6\u5185\u5bb9\u7684\u4e0d\u540c -y \uff1a\u4ee5\u5e76\u5217\u7684\u65b9\u5f0f\u663e\u793a\u6587\u4ef6\u7684\u5f02\u540c\u4e4b\u5904 -W \uff1a\u5728\u4f7f\u7528-y\u53c2\u6570\u65f6\uff0c\u6307\u5b9a\u680f\u5bbd -c \uff1a\u663e\u793a\u5168\u90e8\u5185\u6587\uff0c\u5e76\u6807\u51fa\u4e0d\u540c\u4e4b\u5904 -N \uff1a\u7f3a\u5931\u6587\u4ef6\u4ee5\u7a7a\u6587\u4ef6\u5904\u7406 \u4e3e\u4f8b\uff1a $ cat text5 # \u6587\u4ef6\u5c3e\u90e8\u6ca1\u6709\u7a7a\u884c 1001 1002 1003 $ cat text6 # \u6587\u4ef6\u5c3e\u90e8\u6ca1\u6709\u7a7a\u884c 1001 1002 1003a 1004 \u663e\u793a\u4e0d\u540c\u3002 3c3,4 \u4ee3\u8868\u4e24\u4e2a\u6587\u4ef6\u5728\u7b2c3\uff0c4\u884c\u6709\u4e0d\u540c\u3002 $ diff text5 text6 3c3,4 < 1003 --- > 1003a > 1004 \u4ee5\u7edf\u4e00\u683c\u5f0f\u8f93\u51fa\u6bd4\u8f83\u7ed3\u679c\u3002 \u524d2\u884c\u662f\u6587\u4ef6\u4fe1\u606f\u3002\u5176\u4e2d --- \u8868\u793a\u53d8\u52a8\u524d\u7684\u6587\u4ef6\uff0c +++ \u8868\u793a\u53d8\u52a8\u540e\u7684\u6587\u4ef6\u3002 \u53d8\u52a8\u7684\u4f4d\u7f6e\u7528\u4e24\u4e2a@\u4f5c\u4e3a\u8d77\u9996\u548c\u7ed3\u675f\uff0c @@ -1,3 +1,4 @@ \u3002 -1,3 \u4e2d\uff0c - \u8868\u793a\u7b2c\u4e00\u4e2a\u6587\u4ef6\uff0c\u5373 text5 \u3002\u7b2c\u4e00\u4e2a\u6587\u4ef6\u4ece\u7b2c1\u884c\u5f00\u59cb\u8fde\u7eed3\u884c\u3002 +1,4 \u4e2d\uff0c + \u8868\u793a\u7b2c\u4e8c\u4e2a\u6587\u4ef6\uff0c\u5373 text6 \u3002\u5373\uff0c\u7b2c\u4e8c\u4e2a\u6587\u4ef6\u4ece\u7b2c1\u884c\u5f00\u59cb\u8fde\u7eed4\u884c\u3002 $ diff -u text5 text6 --- text5 2022 -12-07 08 :07:05.927805722 +0800 +++ text6 2022 -12-07 08 :07:24.692234585 +0800 @@ -1,3 +1,4 @@ 1001 1002 -1003 +1003a +1004 \u4ee5\u4e0a\u4e0b\u6587\u65b9\u5f0f\u8f93\u51fa\u6bd4\u8f83\u7ed3\u679c\u3002\u6807\u6709 ! \u4ee3\u8868\u5dee\u5f02\u884c\u3002 $ diff -c text5 text6 *** text5 2022 -12-07 08 :24:08.867168414 +0800 --- text6 2022 -12-07 08 :24:13.939284243 +0800 *************** *** 1 ,3 **** 1001 1002 ! 1003 --- 1 ,4 ---- 1001 1002 ! 1003a ! 1004 \u5e76\u6392\u683c\u5f0f\u8f93\u51fa\u6bd4\u8f83\u7ed3\u679c\u3002 | \u8868\u793a\u524d\u540e2\u4e2a\u6587\u4ef6\u5185\u5bb9\u6709\u4e0d\u540c < \u8868\u793a\u540e\u9762\u6587\u4ef6\u6bd4\u524d\u9762\u6587\u4ef6\u5c11\u4e861\u884c\u5185\u5bb9 > \u8868\u793a\u540e\u9762\u6587\u4ef6\u6bd4\u524d\u9762\u6587\u4ef6\u591a\u4e861\u884c\u5185\u5bb9 $ diff -y -W 50 text5 text6 1001 1001 1002 1002 1003 | 1003a > 1004 \u6bd4\u8f83\u6587\u4ef6\u5939\u5185\u5bb9\u3002\u6ce8\u610f\uff0c\u53ea\u6bd4\u8f83\u5185\u5bb9\uff0c\u4e0d\u6bd4\u8f83\u65f6\u95f4\u6233\u3002 $ mkdir dir1 $ mkdir dir2 $ cd dir1 $ touch file1 $ touch file2 $ cp file1 file2 ../dir2/ $ echo \"hello\" > file3 $ cd ../dir2 $ touch file3 $ touch file4 $ diff dir1 dir2 1d0 < hello Only in dir2: file4","title":"2.14.1.diff"},{"location":"linux/SRE/04-TextTools/#2142patch","text":"\u547d\u4ee4 patch \u590d\u5236\u5176\u4ed6\u6587\u4ef6\u4e2d\u7684\u5185\u5bb9\u3002\u547d\u4ee4\u683c\u5f0f\uff1a patch -p [ num ] < patchfile patch [ options ] originalfile patchfile \u5f53\u7279\u5b9a\u8f6f\u4ef6\u6709\u53ef\u7528\u7684\u5b89\u5168\u4fee\u590d\u7a0b\u5e8f\u65f6\uff0c\u6211\u4eec\u901a\u5e38\u4f1a\u4f7f\u7528 yum \u6216 apt-get \u6216 zypper \u7b49\u5305\u7ba1\u7406\u5de5\u5177\u8fdb\u884c\u4e8c\u8fdb\u5236\u5347\u7ea7\u3002 \u4f46\u5982\u679c\u6211\u4eec\u662f\u901a\u8fc7\u4ece\u6e90\u4ee3\u7801\u7f16\u8bd1\u5b89\u88c5\u8f6f\u4ef6\u7684\u60c5\u51b5\u4e0b\uff0c\u6211\u4eec\u9700\u8981\u4e0b\u8f7d\u5b89\u5168\u8865\u4e01\u5e76\u5c06\u5176\u5e94\u7528\u4e8e\u539f\u59cb\u6e90\u4ee3\u7801\u5e76\u91cd\u65b0\u7f16\u8bd1\u8f6f\u4ef6\u3002 \u8fd9\u5c31\u662f\u6211\u4eec\u4f7f\u7528 diff \u521b\u5efa\u8865\u4e01\u6587\u4ef6\uff08patch file\uff09\uff0c\u5e76\u4f7f\u7528 patch \u547d\u4ee4\u5e94\u7528\u5b83\u3002 \u8865\u4e01\u6587\u4ef6\u662f\u4e00\u4e2a\u6587\u672c\u6587\u4ef6\uff0c\u5176\u4e2d\u5305\u542b\u540c\u4e00\u6587\u4ef6\uff08\u6216\u540c\u4e00\u6e90\u4ee3\u7801\u6811\uff09\u7684\u4e24\u4e2a\u7248\u672c\u4e4b\u95f4\u7684\u5dee\u5f02\u3002 \u8865\u4e01\u6587\u4ef6\u662f\u4f7f\u7528 diff \u547d\u4ee4\u521b\u5efa\u7684\u3002 \u7ee7\u7eed\u4e0a\u4f8b\u3002 \u5c06\u6587\u4ef6 text5 \u7684\u5185\u5bb9\u540c\u6b65\u5230\u6587\u4ef6 text6 \uff0c\u7136\u540e\u64a4\u9500\u8865\u4e01\u3002\u6ce8\u610f\u533a\u5206\u6e90\u6587\u4ef6\u548c\u76ee\u6807\u6587\u4ef6\u3002 $ cat text5 1001 1002 1003 $ cat text6 1001 1002 1003a 1004 # \u751f\u6210\u8865\u4e01\u6587\u4ef6 $ diff -ruN text5 text6 > patchfile $ cat patchfile --- text5 2022 -12-07 08 :24:08.867168414 +0800 +++ text6 2022 -12-07 08 :24:13.939284243 +0800 @@ -1,3 +1,4 @@ 1001 1002 -1003 +1003a +1004 # \u4e0d\u6307\u660e\u76ee\u6807\u6587\u4ef6\uff0c\u5219\u9ed8\u8ba4\u7ed9diff\u547d\u4ee4\u4e2d\u7684\u6e90\u6587\u4ef6\u8fdb\u884c\u6253\u8865\u4e01 $ patch < patchfile patching file text5 $ cat text5 1001 1002 1003a 1004 $ cat text6 1001 1002 1003a 1004 # \u64a4\u9500\u8865\u4e01 patch -R < patchfile patching file text5 # cat text5 1001 1002 1003 # \u7ed9text6\u6587\u4ef6\u6253\u8865\u4e01\uff08\u7528text5\u7684\u6587\u4ef6\u5185\u5bb9\u8986\u76d6text6\u7684\u5185\u5bb9\uff09 $ patch text6 patchfile patching file text6 Reversed ( or previously applied ) patch detected! Assume -R? [ n ] y $ cat text6 1001 1002 1003 # \u64a4\u9500\u7ed9text6\u6587\u4ef6\u6253\u7684\u8865\u4e01\uff08\u6062\u590dtext6\u6587\u4ef6\u8865\u4e01\u524d\u7684\u5185\u5bb9\uff09 $ patch -R text6 patchfile patching file text6 Unreversed patch detected! Ignore -R? [ n ] y $ cat text6 1001 1002 1003a 1004 \u4f7f\u7528 -b \u53c2\u6570\uff0c\u5728patch\u524d\u5148\u5907\u4efd\u6e90\u6587\u4ef6\u3002 $ patch -b < patchfile patching file text5 $ cat text5 1001 1002 1003a 1004 $ cat text5.orig 1001 1002 1003 $ cat text6.orig 1001 1002 1003 $ patch -R < patchfile patching file text5 \u5728-b\u53c2\u6570\u4e2d\u52a0\u5165-V\u53c2\u6570\uff0c\u6307\u5b9a\u5907\u4efd\u6587\u4ef6\u540d\u7684\u683c\u5f0f\uff0c\u5982\u4e0b\uff0c\u4f1a\u5f97\u5230\u6587\u4ef6 text5.~1~ \u3002 $patch -b -V numbered < patchfile patching file text5 $ cat text5 1001 1002 1003a 1004 $ cat text5.~1~ 1001 1002 1003 \u8bd5\u8fd0\u884c\uff0c\u4e0d\u505a\u5b9e\u9645\u66f4\u6539\u3002 patch --dry-run < patchfile \u5bf9\u76ee\u5f55\u6253\u8865\u4e01\u3002 \u6267\u884c diff \u548c patch \u547d\u4ee4\u662f\u5728\u5f53\u524d\u7528\u6237 vagrant \u7684\u4e3b\u76ee\u5f55\u4e0b\uff0c\u7edd\u5bf9\u8def\u5f84\u662f /home/vagrant \u3002 diff \u547d\u4ee4\u4e2d\uff0c\u6e90\u76ee\u5f55\u662f /home/vagrant/dir1 \u3002\u76ee\u6807\u76ee\u5f55\u662f /home/vagrant/dir2 \u3002 -p3 \u662f\u544a\u8bc9 patch \u547d\u4ee4\u5ffd\u7565\u4e0a\u9762\u7edd\u5bf9\u8def\u5f84\u4e2d\u524d\u4e09\u4e2a\u659c\u6760 / \u3002 patch \u547d\u4ee4\u4e2d\u7528 diff \u7684\u76ee\u6807\u76ee\u5f55\u53bb\u8986\u76d6\u6e90\u76ee\u5f55\u3002\u4e92\u6362\u4f1a\u62a5\u9519\u3002 -R \uff1a\u64a4\u9500\u8865\u4e01\u3002 # file3\u548cfile4\u6709\u5185\u5bb9 $ tree ./dir1 ./dir1 \u251c\u2500\u2500 file1 \u251c\u2500\u2500 file2 \u251c\u2500\u2500 file3 \u2514\u2500\u2500 subdir1 \u2514\u2500\u2500 file4 \u90fd\u662f\u7a7a\u6587\u4ef6 $ tree ./dir2 ./dir2 \u251c\u2500\u2500 file1 \u251c\u2500\u2500 file2 \u251c\u2500\u2500 file3 \u2514\u2500\u2500 subdir1 \u2514\u2500\u2500 file4 $ diff -ruN /home/vagrant/dir1 /home/vagrant/dir2 > patchdir $ cat patchdir diff -ruN /home/vagrant/dir1/file3 /home/vagrant/dir2/file3 --- /home/vagrant/dir1/file3 2022 -12-07 08 :42:33.108418336 +0800 +++ /home/vagrant/dir2/file3 2022 -12-07 21 :25:48.156056360 +0800 @@ -1 +0,0 @@ -hello diff -ruN /home/vagrant/dir1/subdir1/file4 /home/vagrant/dir2/subdir1/file4 --- /home/vagrant/dir1/subdir1/file4 2022 -12-07 21 :15:09.689912160 +0800 +++ /home/vagrant/dir2/subdir1/file4 2022 -12-07 21 :26:55.405546177 +0800 @@ -1 +0,0 @@ -/home/vagrant/dir1/subdir1 # \u7528dir2\u7684\u5185\u5bb9\u8986\u76d6dir1\u7684\u5185\u5bb9 $ patch -p3 < patchdir patching file dir1/file3 patching file dir1/subdir1/file4 # \u73b0\u5728dir1\u76ee\u5f55\u4e0b\u7684\u5185\u5bb9\u5df2\u7ecf\u88abdir2\u76ee\u5f55\u8986\u76d6\u4e86\u3002file3\u548cfile4\u90fd\u662f\u7a7a\u6587\u4ef6 $ ll ./dir1 total 0 -rw-r--r--. 1 vagrant wheel 0 Dec 7 08 :34 file1 -rw-r--r--. 1 vagrant wheel 0 Dec 7 08 :35 file2 -rw-r--r--. 1 vagrant wheel 0 Dec 7 21 :40 file3 drwxr-xr-x. 1 vagrant wheel 10 Dec 7 21 :40 subdir1 $ ll ./dir1/subdir1 total 0 -rw-r--r--. 1 vagrant wheel 0 Dec 7 21 :40 file4 # \u64a4\u9500\u8865\u4e01\uff0cfile3\u548cfile4\u5df2\u7ecf\u6062\u590d\u4e3a\u539f\u6587\u4ef6 $ patch -R -p3 < patchdir patching file dir1/file3 patching file dir1/subdir1/file4 $ ll ./dir1 -rw-r--r--. 1 vagrant wheel 0 Dec 7 08 :34 file1 -rw-r--r--. 1 vagrant wheel 0 Dec 7 08 :35 file2 -rw-r--r--. 1 vagrant wheel 6 Dec 7 21 :45 file3 drwxr-xr-x. 1 vagrant wheel 10 Dec 7 21 :45 subdir1 $ ll ./dir1/subdir1 -rw-r--r--. 1 vagrant wheel 27 Dec 7 21 :45 file4 # \u7528dir1\u7684\u5185\u5bb9\u8986\u76d6dir2\u7684\u5185\u5bb9\uff0c\u7cfb\u7edf\u62d2\u7edd\u3002 patch dir2 -p3 < patchdir File dir2 is not a regular file -- refusing to patch 1 out of 1 hunk ignored -- saving rejects to file dir2.rej File dir2 is not a regular file -- refusing to patch 1 out of 1 hunk ignored -- saving rejects to file dir2.rej $ patch /home/vagrant/dir2 -p3 < patchdir File /home/vagrant/dir2 is not a regular file -- refusing to patch 1 out of 1 hunk ignored -- saving rejects to file /home/vagrant/dir2.rej File /home/vagrant/dir2 is not a regular file -- refusing to patch 1 out of 1 hunk ignored -- saving rejects to file /home/vagrant/dir2.rej","title":"2.14.2.patch"},{"location":"linux/SRE/04-TextTools/#2143vimdiff","text":"\u547d\u4ee4 vimdiff \u76f8\u5f53\u4e8e vim -d \u3002 \u4e3e\u4f8b\uff1a vimdiff text1 text2","title":"2.14.3.vimdiff"},{"location":"linux/SRE/04-TextTools/#2144cmp","text":"\u547d\u4ee4 cmp \u67e5\u770b\u4e8c\u8fdb\u5236\u6587\u4ef6\u7684\u4e0d\u540c\u3002 $ cmp cp grep cp grep differ: byte 25 , line 1 $ cmp /usr/bin/ls /usr/bin/dir /usr/bin/ls /usr/bin/dir differ: byte 613 , line 1 # \u8df3\u8fc7\u524d735\u4e2a\u5b57\u8282\uff0c\u8f93\u51fa\u540e\u976230\u4e2a\u5b57\u8282\u5185\u5bb9 $ hexdump -s 735 -Cn 30 /usr/bin/ls 000002df 00 00 00 00 00 5d 00 00 00 50 00 00 00 68 00 00 | ..... ] ...P...h.. | 000002ef 00 6a 00 00 00 4f 00 00 00 00 00 00 00 1d | .j...O........ | 000002fd $ hexdump -s 735 -Cn 30 /usr/bin/dir 000002df 00 00 00 00 00 5d 00 00 00 50 00 00 00 68 00 00 | ..... ] ...P...h.. | 000002ef 00 6a 00 00 00 4f 00 00 00 00 00 00 00 1d | .j...O........ | 000002fd","title":"2.14.4.cmp"},{"location":"linux/SRE/05-RegExpress/","text":"\u7b2c\u4e94\u7ae0 \u6b63\u5219\u8868\u8fbe\u5f0f \u00b6 \u6b63\u5219\u8868\u8fbe\u5f0f\u5206\u4e24\u7c7b\uff1a \u57fa\u672c\u6b63\u5219\u8868\u8fbe\u5f0f\uff08Basic Regular Expression\uff0c \u53c8\u53ebBasic RegEx\uff0c\u7b80\u79f0BREs\uff09 \u6269\u5c55\u6b63\u5219\u8868\u8fbe\u5f0f\uff08Extended Regular Expression\uff0c \u53c8\u53ebExtended RegEx\uff0c\u7b80\u79f0EREs\uff09 Perl\u6b63\u5219\u8868\u8fbe\u5f0f\uff08Perl Regular Expression\uff0c \u53c8\u53ebPerl RegEx \u7b80\u79f0PREs \u57fa\u672c\u7684\u6b63\u5219\u8868\u8fbe\u5f0f\u548c\u6269\u5c55\u6b63\u5219\u8868\u8fbe\u5f0f\u7684\u533a\u522b\u5c31\u662f\u5143\u5b57\u7b26\u7684\u4e0d\u540c\u3002 5.1.\u57fa\u672c\u6b63\u5219\u8868\u8fbe\u5f0f\u7b26\u53f7 \u00b6 ^ \uff1a\u8868\u793a\u4ee5\u67d0\u4e2a\u5b57\u7b26\u5f00\u59cb $ \uff1a\u8868\u793a\u4ee5\u67d0\u4e2a\u5b57\u7b26\u7ed3\u5c3e . \uff1a\u8868\u793a\u5339\u914d\u4e00\u4e2a\u4e14\u53ea\u5339\u914d\u4e00\u4e2a\u5b57\u7b26 * \uff1a\u8868\u793a\u5339\u914d\u524d\u8fb9\u4e00\u4e2a\u5b57\u7b26\u51fa\u73b00\u6b21\u6216\u8005\u591a\u6b21 [] \uff1a\u8868\u793a\u5339\u914d\u62ec\u53f7\u5185\u7684\u591a\u4e2a\u5b57\u7b26\u4fe1\u606f,\u4e00\u4e2a\u4e00\u4e2a\u5339\u914d .* \uff1a\u8868\u793a\u5339\u914d\u6240\u6709\uff0c\u7a7a\u884c\u4e5f\u4f1a\u8fdb\u884c\u5339\u914d [^] \uff1a\u8868\u793a\u4e0d\u5339\u914d\u62ec\u53f7\u5185\u7684\u6bcf\u4e00\u4e2a\u5b57\u7b26 ^$ \uff1a\u8868\u793a\u5339\u914d\u7a7a\u884c\u4fe1\u606f \\ \uff1a\u5c06\u6709\u7279\u6b8a\u542b\u4e49\u7684\u5b57\u7b26\u8f6c\u4e49\u4e3a\u901a\u914d\u7b26 5.2.\u6269\u5c55\u6b63\u5219\u8868\u8fbe\u5f0f\u7b26\u53f7 \u00b6 + \uff1a\u8868\u793a\u524d\u4e00\u4e2a\u5b57\u7b26\u51fa\u73b0\u4e00\u6b21\u6216\u4e00\u6b21\u4ee5\u4e0a ? \uff1a\u8868\u793a\u524d\u4e00\u4e2a\u5b57\u7b26\u51fa\u73b00\u6b21\u6216\u8005\u4e00\u6b21\u4ee5\u4e0a | \uff1a\u8868\u793a\u6216\u8005\u7684\u5173\u7cfb,\u5339\u914d\u591a\u4e2a\u4fe1\u606f () \uff1a\u5339\u914d\u4e00\u4e2a\u6574\u4f53\u4fe1\u606f\uff0c\u4e5f\u53ef\u4ee5\u63a5\u540e\u9879\u5f15\u7528 {} \uff1a\u5b9a\u4e49\u524d\u8fb9\u5b57\u7b26\u51fa\u73b0\u51e0\u6b21 \u63d0\u793a\uff1a grep -E \u6216\u8005 egrep \u53ea\u662f\u8868\u793a\u6269\u5c55\u6b63\u5219\uff0c\u4e0d\u4ee3\u8868\u52a0\u4e86e\u5c31\u8868\u793a\u8f6c\u4e49\u4e86\u3002 \u5f53 grep \u4f7f\u7528\u6269\u5c55\u6b63\u5219\u7684\u7b26\u53f7\u65f6\u5019\u9700\u8981\u7528 \\ \u8f6c\u4e49\u4e3a\u901a\u914d\u7b26\u624d\u80fd\u4f7f\u7528\u3002 5.3.\u5b57\u7b26\u5339\u914d \u00b6 [:alpha:] \uff1a\u8868\u793a\u6240\u6709\u7684\u5b57\u6bcd\uff08\u4e0d\u533a\u5206\u5927\u5c0f\u5199\uff09\uff0c\u6548\u679c\u540c [a-z] [:digit:] \uff1a\u8868\u793a\u4efb\u610f\u5355\u4e2a\u6570\u5b57\uff0c\u6548\u679c\u540c [0-9] [:xdigit:] \uff1a\u8868\u793a\u5341\u516d\u8fdb\u5236\u6570\u5b57 [:lower:] \uff1a\u8868\u793a\u4efb\u610f\u5355\u4e2a\u5c0f\u5199\u5b57\u6bcd [:upper:] \uff1a\u8868\u793a\u4efb\u610f\u5355\u4e2a\u5927\u5199\u5b57\u6bcd [:alnum:] \uff1a\u8868\u793a\u4efb\u610f\u5355\u4e2a\u5b57\u6bcd\u6216\u6570\u5b57 [:blank:] \uff1a\u8868\u793a\u7a7a\u767d\u5b57\u7b26\uff08\u7a7a\u683c\u548c\u5236\u8868\u7b26\uff09 [:space:] \uff1a\u8868\u793a\u5305\u62ec\u7a7a\u683c\u3001\u5236\u8868\u7b26\uff08\u6c34\u5e73\u548c\u5782\u76f4\uff09\u3001\u6362\u884c\u7b26\u3001\u56de\u8f66\u7b26\u7b49\u5404\u79cd\u7c7b\u578b\u7684\u7a7a\u767d\uff0c\u6bd4 [:blank:] \u8303\u56f4\u66f4\u5e7f [:cntrl:] \uff1a\u8868\u793a\u4e0d\u53ef\u6253\u5370\u7684\u63a7\u5236\u5b57\u7b26\uff08\u9000\u683c\u3001\u5220\u9664\u3001\u8b66\u94c3\u7b49\uff09 [:graph:] \uff1a\u8868\u793a\u53ef\u6253\u5370\u7684\u975e\u7a7a\u767d\u5b57\u7b26 [:print:] \uff1a\u8868\u793a\u53ef\u6253\u5370\u5b57\u7b26 [:punct:] \uff1a\u8868\u793a\u6807\u70b9\u7b26\u53f7 5.4.\u4f4d\u7f6e\u6807\u8bb0 \u00b6 \u4f4d\u7f6e\u6807\u8bb0\u951a\u70b9\uff08position marker anchor\uff09\u662f\u6807\u8bc6\u5b57\u7b26\u4e32\u4f4d\u7f6e\u7684\u6b63\u5219\u8868\u8fbe\u5f0f\u3002\u9ed8\u8ba4\u60c5\u51b5\u4e0b\uff0c\u6b63\u5219\u8868\u8fbe\u5f0f\u6240\u5339\u914d\u7684\u5b57\u7b26\u53ef\u4ee5\u51fa\u73b0\u5728\u5b57\u7b26\u4e32\u4e2d\u4efb\u4f55\u4f4d\u7f6e\u3002 ^ \uff1a\u884c\u9996\u951a\u5b9a\uff0c\u6307\u5b9a\u4e86\u5339\u914d\u6b63\u5219\u8868\u8fbe\u5f0f\u7684\u6587\u672c\u5fc5\u987b\u8d77\u59cb\u4e8e\u5b57\u7b26\u4e32\u7684\u9996\u90e8\u3002 \u4f8b\u5982\uff1a ^tux \u80fd\u591f\u5339\u914d\u4ee5 tux \u8d77\u59cb\u7684\u884c $ \uff1a\u884c\u5c3e\u951a\u5b9a\uff0c\u6307\u5b9a\u4e86\u5339\u914d\u6b63\u5219\u8868\u8fbe\u5f0f\u7684\u6587\u672c\u5fc5\u987b\u7ed3\u675f\u4e8e\u76ee\u6807\u5b57\u7b26\u4e32\u7684\u5c3e\u90e8\u3002 \\< \u6216 \\b \uff1a\u8bcd\u9996\u951a\u5b9a\uff0c\u7528\u4e8e\u5355\u8bcd\u6a21\u5f0f\u5339\u914d\u5de6\u4fa7\u3002\uff08\u5355\u8bcd\u662f\u6709\u5b57\u6bcd\u3001\u6570\u5b57\u3001\u4e0b\u5212\u7ebf\u7ec4\u6210\uff09 \\> \u6216 \\b \uff1a\u8bcd\u5c3e\u951a\u5b9a\uff0c\u7528\u4e8e\u5355\u8bcd\u6a21\u5f0f\u5339\u914d\u53f3\u4fa7\u3002\uff08\u5355\u8bcd\u662f\u6709\u5b57\u6bcd\u3001\u6570\u5b57\u3001\u4e0b\u5212\u7ebf\u7ec4\u6210\uff09 ^PATTERN$ \uff1a\u7528\u6a21\u5f0fPATTERN\u5339\u914d\u6574\u884c\u3002 ^$ \uff1a\u5339\u914d\u7a7a\u884c\u3002 ^[[:space:]]*$ \uff1a\u5339\u914d\u7a7a\u767d\u884c\uff08\u6574\u884c\uff09\u3002 \\ \uff1a\u5339\u914d\u6574\u4e2a\u5355\u8bcd\u3002\uff08\u5355\u8bcd\u662f\u6709\u5b57\u6bcd\u3001\u6570\u5b57\u3001\u4e0b\u5212\u7ebf\u7ec4\u6210\uff09 \u5173\u4e8e\u884c\u9996\u951a\u5b9a\u548c\u8bcd\u9996\u951a\u5b9a\uff0c\u5bf9\u6bd4\u4e0b\u9762\u4f8b\u5b50\u3002\u8bcd\u5c3e\u951a\u5b9a\u4e5f\u662f\u7c7b\u4f3c\u60c5\u51b5\u3002 ; \u548c - \u90fd\u88ab\u8ba4\u5b9a\u4e3a\u5355\u8bcd\u5206\u9694\u7b26\u3002 # \u7b26\u5408\u8bcd\u9996\u5339\u914d $ echo \"tux_01-tux02\" | grep '\\ mtu 1500 inet 192 .168.10.210 netmask 255 .255.255.0 broadcast 192 .168.10.255 inet6 fe80::20c:29ff:fea4:e17a prefixlen 64 scopeid 0x20 ether 00 :0c:29:a4:e1:7a txqueuelen 1000 ( Ethernet ) RX packets 7654 bytes 635932 ( 621 .0 KiB ) RX errors 0 dropped 1 overruns 0 frame 0 TX packets 1934 bytes 279649 ( 273 .0 KiB ) TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0 $ ifconfig eth0 | grep netmask | grep -o '[0-9]\\{1,3\\}\\.[0-9]\\{1,3\\}\\.[0-9]\\{1,3\\}\\.[0-9]\\{1,3\\}' 192 .168.10.210 255 .255.255.0 192 .168.10.255 $ ifconfig eth0 | grep netmask | grep -o '[0-9]\\{1,3\\}\\.[0-9]\\{1,3\\}\\.[0-9]\\{1,3\\}\\.[0-9]\\{1,3\\}' | head -n 1 192 .168.10.210 $ ifconfig eth0 | grep -o '[0-9]\\{1,3\\}\\.[0-9]\\{1,3\\}\\.[0-9]\\{1,3\\}\\.[0-9]\\{1,3\\}' 192 .168.10.210 255 .255.255.0 192 .168.10.255 ifconfig eth0 | grep -o '[0-9]\\{1,3\\}\\.[0-9]\\{1,3\\}\\.[0-9]\\{1,3\\}\\.[0-9]\\{1,3\\}' | head -n 1 192 .168.10.210 \u5339\u914d\u7a7a\u884c\u548c\u975e\u7a7a\u884c\uff1a grep '^$' /etc/profile grep -v '^$' /etc/profile \u5339\u914d\u975e\u7a7a\u884c\u548c\u975e#\u5f00\u5934\u7684\u884c\uff1a\uff08\u4e09\u79cd\u65b9\u6cd5\uff09 grep -v '^$' /etc/profile | grep -v '^#' grep -v '^$\\|#' /etc/profile grep '^[^$#]' /etc/profile \u6ce8\u610f\uff0c\u5982\u679c\u5199\u6210\u4e0b\u9762\u8fd9\u6837\uff0c\u5219\u4e0d\u4f1a\u8fc7\u6ee4\u6389\u7a7a\u884c\uff0c [$] \u4f1a\u88ab\u89c6\u4e3a $ \u7b26\u53f7\u3002 \u6240\u4ee5\u6b63\u5219\u8868\u8fbe\u5f0f\u7684\u5143\u5b57\u7b26\u653e\u5728\u4e2d\u62ec\u53f7 [] \u5185\u5c31\u88ab\u89c6\u4e3a\u666e\u901a\u5b57\u7b26\u3002 grep -v '^[$#]' /etc/profile 5.8.\u4e09\u5251\u5ba2 grep \u547d\u4ee4 \u00b6 \u683c\u5f0f\uff1a grep [OPTIONS] PATTERN [FILE...] grep [OPTIONS] -e PATTERN ... [FILE...] grep [OPTIONS] -f FILE ... [FILE...] \u53c2\u6570\uff1a -n \uff1a\u663e\u793a\u8fc7\u6ee4\u51fa\u6765\u7684\u6587\u4ef6\u5728\u6587\u4ef6\u5f53\u4e2d\u7684\u884c\u53f7 -c \uff1a\u663e\u793a\u5339\u914d\u5230\u7684\u884c\u6570 -o \uff1a\u53ea\u663e\u793a\u5339\u914d\u5230\u7684\u5185\u5bb9 -q \uff1a\u9759\u9ed8\u8f93\u51fa\uff08\u4e00\u822c\u7528\u5728shell\u811a\u672c\u5f53\u4e2d\uff0c\u901a\u8fc7 echo $? \u67e5\u770b\u547d\u4ee4\u6267\u884c\u7ed3\u679c\uff0c0\u8868\u793a\u6210\u529f\uff0c\u975e0\u8868\u793a\u5931\u8d25\uff09\uff09 -i \uff1a\u5ffd\u7565\u5927\u5c0f\u5199 -v \uff1a\u53cd\u5411\u67e5\u627e -w \uff1a\u5339\u914d\u67d0\u4e2a\u8bcd\u8bcd\uff1a\u5728Linux\u4e2d\uff0c\u8bcd\u4e3a\u4e00\u8fde\u4e32\u5b57\u6bcd\u3001\u6570\u5b57\u548c\u4e0b\u5212\u7ebf\u7ec4\u6210\u7684\u5b57\u7b26\u4e32 -E \uff1a\u4f7f\u7528\u6269\u5c55\u6b63\u5219 -R \uff1a\u9012\u5f52\u67e5\u8be2 -l \uff1a\u53ea\u6253\u5370\u6587\u4ef6\u8def\u5f84 \u6269\u5c55\u53c2\u6570\uff1a -A \uff1a\u663e\u793a\u5339\u914d\u5230\u7684\u6570\u636e\u7684\u540e\u51e0n\u884c -B \uff1a\u663e\u793a\u5339\u914d\u5230\u7684\u6570\u636e\u7684\u524d\u51e0n\u884c -C \uff1a\u663e\u793a\u5339\u914d\u5230\u7684\u6570\u636e\u7684\u524d\u540e\u5404\u51e0n\u884c \u793a\u4f8b\uff1a \u5339\u914d\u7528\u6237\uff1a grep root /etc/passwd root:x:0:0:root:/root:/bin/bash $ grep \"USER\" /etc/passwd $ grep \" $USER \" /etc/passwd vagrant:x:1000:478:vagrant:/home/vagrant:/bin/bash $ grep '$USER' /etc/passwd \u5339\u914d\u5173\u952e\u5b57\uff1a $ grep processor /proc/cpuinfo processor : 0 processor : 1 $ grep -o processor /proc/cpuinfo processor processor $ grep \"cpu family\" /proc/cpuinfo cpu family : 6 cpu family : 6 $ grep -o \"cpu family\" /proc/cpuinfo cpu family cpu family \u901a\u8fc7grep\u8fdb\u884c\u6587\u4ef6\u6bd4\u8f83\u3002 # \u6700\u540e\u4e00\u884c\u662f\u7a7a\u884c $ cat f1 a b 1 c # \u6700\u540e\u4e00\u884c\u662f\u7a7a\u884c $ cat f2 b e f c 1 2 # \u9ad8\u4eae\u663e\u793a\u76f8\u540c\u5185\u5bb9\u7684\u884c\uff0c\u5305\u542b\u6700\u540e\u4e00\u884c\u7a7a\u884c $ grep -f f1 f2 b e f c 1 2 # \u53ea\u663e\u793a\u76f8\u540c\u5185\u5bb9\u7684\u884c\uff0c\u5305\u542b\u6700\u540e\u4e00\u884c\u7a7a\u884c $ grep -wf f1 f2 b c 1 # \u53ea\u663e\u793a\u4e0d\u540c\u5185\u5bb9\u7684\u884c $ grep -wvf f1 f2 e f 2 \u63d0\u793a\uff1a grep -wvf f1 f2 \u6216\u8005 grep -w -v -f f1 f2 \u4e2d\uff0c -f \u53ea\u80fd\u4f5c\u4e3a\u6700\u540e\u4e00\u4e2a\u53c2\u6570\uff0c\u5426\u5219\u4f1a\u62a5\u9519\u3002 \u4f53\u4f1a\u57fa\u672c\u6b63\u5219\u548c\u6269\u5c55\u6b63\u5219\u7684\u5dee\u5f02\u3002 \u4f8b1\uff1a\u8f6c\u4e49\u3002 # \u4e0b\u9762\u51e0\u4e2a\u547d\u4ee4\u8fd4\u56de\u7684\u7ed3\u679c\u662f\u4e00\u6837\u7684\u3002 $ grep \"root\\|bash\" /etc/passwd $ grep -E \"root|bash\" /etc/passwd $ grep -e \"root\" -e \"bash\" /etc/passwd # \u4e0b\u9762\u7684\u547d\u4ee4\u6ca1\u6709\u5339\u914d\u7ed3\u679c\u8fd4\u56de\u3002 $ grep \"root|bash\" /etc/passwd \u4f8b2\uff1a\u4e0b\u97624\u4e2a\u547d\u4ee4\u8fd4\u56de\u540c\u6837\u7684\u7ed3\u679c\u3002 grep \"root\" /etc/passwd grep -E \"root\" /etc/passwd grep \"\\\" /etc/passwd grep -E \"\\\" /etc/passwd \u4f8b3\uff1a\u884c\u9996\u884c\u5c3e\u951a\u5b9a\u3002 $ grep \"^\\(.*\\)\\>.*\\<\\1 $ \" /etc/passwd $ grep -E \"^(.*)\\>.*\\<\\1 $ \" /etc/passwd $ egrep \"^(.*)\\>.*\\<\\1 $ \" /etc/passwd sync:x:5:0:sync:/sbin:/bin/sync shutdown:x:6:0:shutdown:/sbin:/sbin/shutdown halt:x:7:0:halt:/sbin:/sbin/halt \u4f8b4\uff1a\u4e09\u79cd\u65b9\u6cd5\u6c42\u548c\u8ba1\u7b97\uff0c\u8fd0\u7528 grep \uff0c cut \uff0c bc \u548c paste \u547d\u4ee4\u3002 $cat age Jason = 20 Tom = 30 Jack = 40 # \u65b9\u6cd51 $ cat age | cut -d \"=\" -f 2 | tr \"\\n\" + | grep -Eo \".*[0-9]\" | bc 90 # \u65b9\u6cd52 $ grep -Eo \"[0-9]+\" age | tr \"\\n\" + | grep -Eo \".*[0-9]\" | bc 90 # \u65b9\u6cd53 $ grep -Eo \"[0-9]+\" age | paste -s -d \"+\" | bc 90 5.9.\u4e09\u5251\u5ba2 sed \u547d\u4ee4 \u00b6 sed \u662fstream editor\u7684\u7f29\u5199\uff0c\u4e2d\u6587\u79f0\u4e4b\u4e3a\u201c\u6d41\u7f16\u8f91\u5668\u201d\u3002 sed \u547d\u4ee4\u662f\u4e00\u4e2a\u9762\u5411\u884c\u5904\u7406\u7684\u5de5\u5177\uff0c\u5b83\u4ee5\u201c\u884c\u201d\u4e3a\u5904\u7406\u5355\u4f4d\uff0c\u9488\u5bf9\u6bcf\u4e00\u884c\u8fdb\u884c\u5904\u7406\uff0c\u5904\u7406\u540e\u7684\u7ed3\u679c\u4f1a\u8f93\u51fa\u5230\u6807\u51c6\u8f93\u51fa STDOUT \uff0c\u4e0d\u4f1a\u5bf9\u8bfb\u53d6\u7684\u6587\u4ef6\u505a\u4efb\u4f55\u4fee\u6539\u3002 sed \u7684\u5de5\u4f5c\u539f\u7406\uff1a sed \u547d\u4ee4\u662f\u9762\u5411\u201c\u884c\u201d\u8fdb\u884c\u5904\u7406\u7684\uff0c\u6bcf\u4e00\u6b21\u5904\u7406\u4e00\u884c\u5185\u5bb9\u3002 \u5904\u7406\u65f6\uff0c sed \u4f1a\u628a\u8981\u5904\u7406\u7684\u884c\u5b58\u50a8\u5728\u7f13\u51b2\u533a\u4e2d\uff0c\u63a5\u7740\u7528 sed \u547d\u4ee4\u5904\u7406\u7f13\u51b2\u533a\u4e2d\u7684\u5185\u5bb9\uff0c\u5904\u7406\u5b8c\u6210\u540e\uff0c\u628a\u7f13\u51b2\u533a\u7684\u5185\u5bb9\u9001\u5f80\u5c4f\u5e55\u3002\u63a5\u7740\u5904\u7406\u4e0b\u4e00\u884c\uff0c\u8fd9\u6837\u4e0d\u65ad\u91cd\u590d\uff0c\u76f4\u5230\u6587\u4ef6\u672b\u5c3e\u3002\u8fd9\u4e2a\u7f13\u51b2\u533a\u88ab\u79f0\u4e3a\u201c \u6a21\u5f0f\u7a7a\u95f4 \u201d\uff08pattern space\uff09\u3002 \u4fdd\u6301\u7a7a\u95f4(hold space) sed \u7684\u4fdd\u6301\u7a7a\u95f4\u50cf\u4e00\u4e2a\u957f\u671f\u50a8\u5b58\uff0c \u53ef\u4ee5\u628a\u83b7\u53d6\u7684\u4fe1\u606f\u50a8\u5b58\u5230\u5176\u4e2d\uff0c\u5f85\u540e\u7eed\u8c03\u7528\u3002\u4e0d\u80fd\u76f4\u63a5\u5bf9\u4fdd\u6301\u7a7a\u95f4\u8fdb\u884c\u64cd\u4f5c\uff0c \u800c\u662f\u5c06\u4fdd\u6301\u7a7a\u95f4\u7684\u5185\u5bb9\u590d\u5236\u6216\u8005\u6dfb\u52a0\u5230\u6a21\u5f0f\u7a7a\u95f4\u8fdb\u884c\u64cd\u4f5c\u3002 \u975e\u4ea4\u4e92\u5f0f\u6279\u91cf\u4fee\u6539\u6587\u4ef6\u3002 sed \u547d\u4ee4\u683c\u5f0f\uff1a sed [ option ] command file option \u5e38\u7528\u9009\u9879\uff1a -n \uff1a\u4e0d\u8f93\u51fa\u6a21\u5f0fpattern\u7684\u5185\u5bb9\u5230\u5c4f\u5e55\uff08\u5373\u4e0d\u81ea\u52a8\u6253\u5370\uff09 -e \uff1a\u591a\u70b9\u7f16\u8f91 -f filename \uff1a\u4ece\u6307\u5b9a\u6587\u4ef6\u8bfb\u53d6\u7f16\u8f91\u811a\u672c -r \uff0c -E \uff1a\u4f7f\u7528\u6269\u5c55\u6b63\u5219\u8868\u8fbe\u5f0f -i .bak \uff1a\u5907\u4efd\u6587\u4ef6\u5e76\u539f\u5904\u7f16\u8f91 -s \uff1a\u5c06\u591a\u4e2a\u6587\u4ef6\u89c6\u4e3a\u72ec\u7acb\u6587\u4ef6\uff0c\u800c\u4e0d\u662f\u5355\u4e2a\u8fde\u7eed\u7684\u957f\u6587\u4ef6\u6d41 -ir \uff1a \u4e0d\u652f\u6301 -i -r \uff1a \u652f\u6301 -ri \uff1a \u652f\u6301 -ni \uff1a \u5371\u9669\u9009\u9879\uff0c\u4f1a\u6e05\u7a7a\u6587\u4ef6 command \u90e8\u5206\u53ef\u4ee5\u5206\u4e3a\u4e24\u90e8\u5206\uff1a \u8303\u56f4\u8bbe\u5b9a\uff0c\u53ef\u4ee5\u91c7\u7528\u4e24\u79cd\u4e0d\u540c\u7684\u65b9\u5f0f\u6765\u8868\u8fbe\uff1a \u6307\u5b9a\u884c\u6570\uff1a\u5982\uff1a 3,5 \u8868\u793a\u7b2c3\u30014\u30015\u884c 5,$ \u8868\u793a\u7b2c5\u884c\u81f3\u6587\u4ef6\u6700\u540e\u4e00\u884c \u6a21\u5f0f\u5339\u914d\uff1a\u5982\uff1a /^[^dD]/ \u8868\u793a\u5339\u914d\u884c\u9996\u4e0d\u662f\u4ee5 d \u6216 D \u5f00\u5934\u7684\u884c \u52a8\u4f5c\u5904\u7406\uff0c\u4e0b\u9762\u662f\u5e38\u7528\u7684\u52a8\u4f5c\uff1a a \uff1a\u65b0\u589e\uff0c a \u540e\u9762\u7684\u5b57\u4e32\u4f1a\u5728\u65b0\u7684\u4e00\u884c\u51fa\u73b0\uff08\u5f53\u524d\u884c\u7684\u4e0b\u4e00\u884c\uff09 i \uff1a\u63d2\u5165\uff0c i \u540e\u9762\u7684\u5b57\u4e32\u4f1a\u5728\u65b0\u7684\u4e00\u884c\u51fa\u73b0\uff08\u5f53\u524d\u884c\u7684\u4e0a\u4e00\u884c\uff09 r filename \uff1a\u8bfb\u53d6\u6307\u5b9a\u6587\u4ef6 fllename \u7684\u5185\u5bb9\uff0c\u8ffd\u52a0\u5230\u5f53\u524d\u884c\u7684\u4e0b\u4e00\u884c R filename \uff1a\u8bfb\u53d6\u6307\u5b9a\u6587\u4ef6 fllename \u7684\u4e00\u884c\uff0c\u8ffd\u52a0\u5230\u5f53\u524d\u884c\u7684\u4e0b\u4e00\u884c d \uff1a\u5220\u9664\u8be5\u884c p \uff1a\u6253\u5370\u8be5\u884c Ip \uff1a\u5ffd\u7565\u5927\u5c0f\u5199\u8f93\u51fa w filename \uff1a\u5199\u5165\u5230\u6307\u5b9a\u6587\u4ef6filename\u4e2d\u3002 s/regexp/replacement/ \uff1a\u53d6\u4ee3\uff0c\u7528replacement\u53d6\u4ee3\u6b63\u5219regexp\u5339\u914d\u5230\u7684\u5185\u5bb9 = \uff1a\u4e3a\u6a21\u5f0fpattern\u4e2d\u7684\u5339\u914d\u884c\u6253\u5370\u884c\u53f7 ! \uff1a\u4e3a\u6a21\u5f0fpattern\u4e2d\u7684\u5339\u914d\u884c\u53d6\u53cd\u64cd\u4f5c q \uff1a\u7ed3\u675f\u6216\u9000\u51fased \u521b\u5efa\u4e00\u4e2a testfile \u6587\u4ef6\u3002 $ cat < testfile HELLO LINUX! Linux is a free unix-type opterating system. This is a linux testfile! Linux test Google Taobao Banbooob Tesetfile Wiki EOF \u5339\u914d\u5b9a\u4f4d\u6587\u4ef6 testfile \u7b2c\u4e8c\u884c\uff0c\u5e76\u8f93\u51fa\uff08\u5305\u542b\u5339\u914d\u7b2c\u4e8c\u884c\u548c\u8f93\u51fa\u7b2c\u4e8c\u884c\uff09\u3002 # nl testfile | sed '2p' 1 HELLO LINUX! 2 Linux is a free unix-type opterating system. 2 Linux is a free unix-type opterating system. 3 This is a linux testfile! 4 Linux test 5 Google 6 Taobao 7 Banbooob 8 Tesetfile 9 Wiki \u5339\u914d\u5b9a\u4f4d\u6587\u4ef6 testfile \u7b2c\u4e8c\u884c\uff0c\u4e0d\u8f93\u51fa\u3002 # nl testfile | sed -n '2p' 2 Linux is a free unix-type opterating system. \u5339\u914d\u5b9a\u4f4d\u6587\u4ef6 testfile \u6700\u540e\u4e00\u884c\u3002 $ nl testfile | sed -n '$p' 9 Wiki \u5339\u914d\u5b9a\u4f4d\u6587\u4ef6 testfile \u5012\u6570\u7b2c\u4e8c\u884c\u3002 # sed -n \"$(echo $[`cat testfile | wc -l`-1])p\" testfile Tesetfile \u5c06 testfile \u7684\u5185\u5bb9\u5217\u51fa\u7b2c2\uff5e3\u884c\uff0c\u5e76\u4e14\u6253\u5370\u884c\u53f7\u3002 $ nl testfile | sed -n '2,3p' 2 Linux is a free unix-type opterating system. 3 This is a linux testfile! \u5c06 testfile \u7684\u5185\u5bb9\u4ece\u7b2c2\u884c\u5f00\u59cb\uff0c\u5411\u540e\u8f93\u51fa\u989d\u5916\u76843\u884c\uff0c\u5e76\u4e14\u6253\u5370\u884c\u53f7\u3002 $ nl testfile | sed -n '2,+3p' 2 Linux is a free unix-type opterating system. 3 This is a linux testfile! 4 Linux test 5 Google \u5c06 testfile \u7684\u5185\u5bb9\u4ece\u7b2c2\u884c\u5f00\u59cb\uff0c\u5411\u540e\u4ee52\u4e3a\u6b65\u8fdb\u5355\u4f4d\u8f93\u51fa\u6240\u6709\u5339\u914d\u884c\uff0c\u5e76\u4e14\u6253\u5370\u884c\u53f7\uff08\u5373\uff0c\u4ece\u7b2c2\u884c\u5f00\u59cb\u8f93\u51fa\u5076\u6570\u884c\uff09\u3002 nl testfile | sed -n '2~2p' 2 Linux is a free unix-type opterating system. 4 Linux test 6 Taobao 8 Tesetfile \u5c06 testfile \u7684\u5185\u5bb9\u4ece\u7b2c2\u884c\u5f00\u59cb\uff0c\u5411\u540e\u4ee52\u4e3a\u6b65\u8fdb\u5355\u4f4d\u5220\u9664\u6240\u6709\u5339\u914d\u884c\uff0c\u8f93\u51fa\u5269\u4f59\u884c\uff0c\u5e76\u4e14\u6253\u5370\u884c\u53f7\uff08\u5373\uff0c\u4ece\u7b2c2\u884c\u5f00\u59cb\u5220\u9664\u5076\u6570\u884c\uff0c\u8f93\u51fa\u5947\u6570\u884c\uff09\u3002 $ nl testfile | sed '2~2d' 1 HELLO LINUX! 3 This is a linux testfile! 5 Google 7 Banbooob 9 Wiki \u5c06 testfile \u7684\u5185\u5bb9\u8f93\u51fa\uff0c\u5220\u9664\u7b2c2\u884c\u548c\u7b2c5\u884c\uff0c\u5e76\u6253\u5370\u884c\u53f7\u3002 $ nl testfile | sed -e '2d' -e '5d' $ nl testfile | sed -e '2d;5d' $ nl testfile | sed '2d;5d' 1 HELLO LINUX! 3 This is a linux testfile! 4 Linux test 6 Taobao 7 Banbooob 8 Tesetfile 9 Wiki \u5c06 testfile \u7684\u5185\u5bb9\u8f93\u51fa\uff0c\u8f93\u51fa\u533a\u95f4\u662f\u4ece\u884c\u9996 L \u7684\u884c\u5230\u884c\u9996 G \u7684\u884c\u7ed3\u675f\u3002\u4e0d\u4fee\u6539\u539f\u6587\u4ef6\u3002 \u5982\u679c\u884c\u9996\u5339\u914d\u4e0d\u5230\uff0c\u5219\u65e0\u7ed3\u679c\u8f93\u51fa\uff1b\u5982\u679c\u884c\u5c3e\u5339\u914d\u4e0d\u5230\uff0c\u5219\u8f93\u51fa\u5230\u6587\u4ef6\u7ed3\u675f\u3002 $ sed -n '/^L/,/^G/p' testfile Linux is a free unix-type opterating system. This is a linux testfile! Linux test Google \u5c06 testfile \u7684\u5185\u5bb9\u8f93\u51fa\uff0c\u4e14\u5728\u7b2c6\u884c\u540e\u52a0\u4e0a I love Linux \u3002\u4e0d\u4fee\u6539\u539f\u6587\u4ef6\u3002 $ sed -e '6a I love Linux' testfile HELLO LINUX! Linux is a free unix-type opterating system. This is a linux testfile! Linux test Google Taobao I love Linux Banbooob Tesetfile Wiki \u5c06 testfile \u7684\u5185\u5bb9\u5217\u51fa\u5e76\u4e14\u6253\u5370\u884c\u53f7\uff0c\u4e14\u5728\u7b2c6\u884c\u540e\u6dfb\u52a0 I love Linux \u3002\u4e0d\u4fee\u6539\u539f\u6587\u4ef6\u3002 $ nl testfile | sed '6a I love Linux' $ nl testfile | sed '6a\\I love Linux' 1 HELLO LINUX! 2 Linux is a free unix-type opterating system. 3 This is a linux testfile! 4 Linux test 5 Google 6 Taobao I love Linux 7 Banbooob 8 Tesetfile 9 Wiki \u5c06 testfile \u7684\u5185\u5bb9\u5217\u51fa\u5e76\u4e14\u6253\u5370\u884c\u53f7\uff0c\u4e14\u5728\u7b2c3\u884c\u524d\u6dfb\u52a0 I am a journer learner \u3002\u4e0d\u4fee\u6539\u539f\u6587\u4ef6\u3002 $ nl testfile | sed '3i\\I am a journer learner' 1 HELLO LINUX! 2 Linux is a free unix-type opterating system. I am a journer learner 3 This is a linux testfile! 4 Linux test 5 Google 6 Taobao 7 Banbooob 8 Tesetfile 9 Wiki \u5c06 testfile \u7684\u5185\u5bb9\u5217\u51fa\u5e76\u4e14\u6253\u5370\u884c\u53f7\uff0c\u4e14\u5728\u7b2c3\u884c\u524d\u6dfb\u52a0\u4e09\u884c\u5185\u5bb9 Add line 1 \uff0c Add line 2 \uff0c Add line 3 \u3002\u7528\u7b26\u5408 \\ \u8fdb\u884c\u6362\u884c\u3002\u4e0d\u4fee\u6539\u539f\u6587\u4ef6\u3002 $ nl testfile | sed '3i\\Add line 1 \\ Add line 2 \\ Add line 3' 1 HELLO LINUX! 2 Linux is a free unix-type opterating system. Add line 1 Add line 2 Add line 3 3 This is a linux testfile! 4 Linux test 5 Google 6 Taobao 7 Banbooob 8 Tesetfile 9 Wiki \u5c06 testfile \u7684\u5185\u5bb9\u5217\u51fa\u5e76\u4e14\u6253\u5370\u884c\u53f7\uff0c\u4e14\u5c06\u7b2c2-5\u884c\u7684\u5185\u5bb9\u53d6\u4ee3\u6210\u4e3a replaced \u3002\u4e0d\u4fee\u6539\u539f\u6587\u4ef6\u3002 $ nl testfile | sed '2,5c\\replaced' $ nl testfile | sed '2,5c replaced' $ nl testfile | sed '2,5creplaced' 1 HELLO LINUX! replaced 6 Taobao 7 Banbooob 8 Tesetfile 9 Wiki \u5c06 testfile \u7684\u5185\u5bb9\u5217\u51fa\u5e76\u4e14\u6253\u5370\u884c\u53f7\uff0c\u4e14\u5220\u9664\u7b2c2~5\u884c\u3002\u4e0d\u4fee\u6539\u539f\u6587\u4ef6\u3002 $ nl testfile | sed '2,5d' 1 HELLO LINUX! 6 Taobao 7 Banbooob 8 Tesetfile 9 Wiki \u5c06 testfile \u7684\u5185\u5bb9\u5217\u51fa\u5e76\u4e14\u6253\u5370\u884c\u53f7\uff0c\u4e14\u5220\u9664\u7b2c5\u884c\u5230\u6700\u540e\u4e00\u884c\u3002 $ nl testfile | sed '5,$d' 1 HELLO LINUX! 2 Linux is a free unix-type opterating system. 3 This is a linux testfile! 4 Linux test \u5339\u914d\u5b9a\u4f4d\u6587\u4ef6 testfile \u4e2d\u5305\u542b\u5173\u952e\u5b57 linux \u7684\u884c\u3002 $ sed -n '/linux/p' testfile This is a linux testfile! \u5339\u914d\u5b9a\u4f4d\u547d\u4ee4 df \u8f93\u51fa\u4e2d\u4ee5 /dev/sd \u5173\u952e\u5b57\u5f00\u5934\u7684\u884c\u3002\uff08\u9700\u8981\u8f6c\u4e49\u7b26 \\ \uff09 $ df | sed -n '/^\\/dev\\/sd/p' /dev/sda2 102750208 7077280 92055312 8 % / /dev/sda2 102750208 7077280 92055312 8 % /.snapshots /dev/sda2 102750208 7077280 92055312 8 % /home /dev/sda2 102750208 7077280 92055312 8 % /opt /dev/sda2 102750208 7077280 92055312 8 % /root /dev/sda2 102750208 7077280 92055312 8 % /boot/grub2/x86_64-efi /dev/sda2 102750208 7077280 92055312 8 % /boot/grub2/i386-pc /dev/sda2 102750208 7077280 92055312 8 % /srv /dev/sda2 102750208 7077280 92055312 8 % /tmp /dev/sda2 102750208 7077280 92055312 8 % /usr/local /dev/sda2 102750208 7077280 92055312 8 % /var \u5339\u914d\u5b9a\u4f4d\u547d\u4ee4 df \u8f93\u51fa\u4e2d\u4e0d\u4ee5 /dev/sd \u5173\u952e\u5b57\u5f00\u5934\u7684\u884c\u3002\u901a\u8fc7 !p \u8fdb\u884c\u6c42\u53cd\u8f93\u51fa\u3002 $ df | sed -n '/^\\/dev\\/sd/!p' Filesystem 1K-blocks Used Available Use% Mounted on devtmpfs 4096 0 4096 0 % /dev tmpfs 1971208 0 1971208 0 % /dev/shm tmpfs 788484 9612 778872 2 % /run tmpfs 4096 0 4096 0 % /sys/fs/cgroup tmpfs 394240 0 394240 0 % /run/user/1000 \u5339\u914d\u5b9a\u4f4d\u547d\u4ee4 df \u8f93\u51fa\u4e2d\u4e0d\u4ee5 /dev/sd \u548c tmp \u5173\u952e\u5b57\u5f00\u5934\u7684\u884c\u3002 $ df | sed '/^\\/dev\\/sd/d;/^tmp/d' Filesystem 1K-blocks Used Available Use% Mounted on devtmpfs 4096 0 4096 0 % /dev $ df | grep -Ev '^\\/dev\\/sd|^tmp' Filesystem 1K-blocks Used Available Use% Mounted on devtmpfs 4096 0 4096 0 % /dev \u641c\u7d22\u6587\u4ef6 testfile \u6240\u6709\u5305\u542b oo \u5173\u952e\u5b57\u7684\u884c\u5e76\u5339\u914d\u8f93\u51fa\u3002\u4e0d\u4fee\u6539\u539f\u6587\u4ef6\u3002 $ sed -n '/ooo/p' testfile Banbooob $ sed -n '/oo/p' testfile Google Banbooob \u641c\u7d22\u6587\u4ef6 testfile \u6240\u6709\u5305\u542b oo \u5173\u952e\u5b57\u7684\u884c\u5e76\u5220\u9664\u3002\u4e0d\u4fee\u6539\u539f\u6587\u4ef6\u3002 $ sed '/oo/d' testfile HELLO LINUX! Linux is a free unix-type opterating system. This is a linux testfile! Linux test Taobao Tesetfile Wiki \u641c\u7d22\u6587\u4ef6 testfile \u6240\u6709\u5305\u542b oo \u7684\u884c\uff0c\u628a oo \u66ff\u6362\u4e3a kk \uff0c\u518d\u8f93\u51fa\u8fd9\u884c\u3002\u4e0d\u4fee\u6539\u539f\u6587\u4ef6\u3002 $ sed -n '/oo/{s/oo/kk/;p;q}' testfile $ sed -ne '/oo/{s/oo/kk/;p;q}' testfile Gkkgle \u5c06 testfile \u7684\u6bcf\u884c\u4e2d\u7b2c\u4e00\u6b21\u51fa\u73b0 ao \u7684\u66ff\u6362\u6210 HH \u3002 $ sed 's/ao/HH/' testfile HELLO LINUX! Linux is a free unix-type opterating system. This is a linux testfile! Linux test Google THHbao Banbooob Tesetfile Wiki \u4e0b\u9762\u662f\u628a testfile \u7684\u5339\u914d\u5230 ao \u7684\u884c\u66ff\u6362\u6210 HH \u3002 sed '/ao/cHH' testfile HELLO LINUX! SUSE This is a linux testfile! SUSE Google Taobao Banbooob Tesetfile Wiki \u641c\u7d22\u6587\u4ef6 testfile \u6240\u6709\u5305\u542b ao \u7684\u5168\u90e8\u66ff\u6362\u6210 HH \u3002 g \u8868\u793a\u5168\u5c40\u5339\u914d\u3002\u4e0d\u4fee\u6539\u539f\u6587\u4ef6\u3002 $ sed -e 's/ao/HH/g' testfile $ sed 's/ao/HH/g' testfile HELLO LINUX! Linux is a free unix-type opterating system. This is a linux testfile! Linux test Google THHbHH Banbooob Tesetfile Wiki \u5728\u6587\u4ef6 /etc/passwd \u4e2d\u67e5\u627e\u5339\u914d\u6240\u6709\u7b26\u5408 r \u5f00\u5934 t \u7ed3\u5c3e\u4e14\u4e2d\u95f4\u542b\u4efb\u610f\u4e24\u4e2a\u5b57\u7b26\u7684\u884c\uff0c\u5e76\u5728 t \u5b57\u6bcd\u540e\u6dfb\u52a0 er \u3002 $ sed -nr 's/r..t/&er/gp' /etc/passwd rooter:x:0:0:rooter:/rooter:/bin/bash lp:x:493:487:Printering daemon:/var/spool/lpd:/usr/sbin/nologin tftp:x:487:474:TFTP account:/srv/terftpboot:/bin/false vagranter:x:1000:478:vagranter:/home/vagranter:/bin/bash tester1:x:600:1530: \"Test User1,terestuser1@abc.com\" :/home/tester1:/bin/bash \u5c06\u4e0a\u8ff0\u7ed3\u679c\u548c\u539f\u59cb\u5185\u5bb9\u8fdb\u884c\u5bf9\u6bd4\uff0c\u80fd\u66f4\u597d\u7684\u7406\u89e3 s/r..t/&er \u7684\u64cd\u4f5c\u3002 rooter:x:0:0:rooter:/rooter:/bin/bash root:x:0:0:root:/root:/bin/bash lp:x:493:487:Printering daemon:/var/spool/lpd:/usr/sbin/nologin lp:x:493:487:Printing daemon:/var/spool/lpd:/usr/sbin/nologin tftp:x:487:474:TFTP account:/srv/terftpboot:/bin/false tftp:x:487:474:TFTP account:/srv/tftpboot:/bin/false vagranter:x:1000:478:vagranter:/home/vagranter:/bin/bash vagrant:x:1000:478:vagrant:/home/vagrant:/bin/bash tester1:x:600:1530: \"Test User1,terestuser1@abc.com\" :/home/tester1:/bin/bash tester1:x:600:1530: \"Test User1,testuser1@abc.com\" :/home/tester1:/bin/bash \u4f53\u4f1a & \u7684\u4f4d\u7f6e\u4e0d\u540c\u7684\u4e0d\u540c\u542b\u4e49\u3002 # \u9644\u52a0\u5728root\u5355\u8bcd\u540e $ sed -n 's/root/&superman/p' /etc/passwd rootsuperman:x:0:0:root:/root:/bin/bash # \u9644\u52a0\u5728root\u5355\u8bcd\u524d $ sed -n 's/root/superman&/p' /etc/passwd supermanroot:x:0:0:root:/root:/bin/bash \u4f7f\u7528\u53c2\u6570 -i \u8fdb\u884c\u6e90\u6587\u4ef6\u4fee\u6539\u3002 $ sed -i 's/ao/HH/' testfile $ cat testfile HELLO LINUX! Linux is a free unix-type opterating system. This is a linux testfile! Linux test Google THHbao Banbooob Tesetfile Wiki \u6e90\u6587\u4ef6\u4fee\u6539\u524d\uff0c\u5907\u4efd\u5728\u65b0\u6587\u4ef6 testfile.new \u3002 $ sed -i.new 's/ao/HH/' testfile $ cat testfile.new HELLO LINUX! Linux is a free unix-type opterating system. This is a linux testfile! Linux test Google Taobao Banbooob Tesetfile Wiki $ cat testfile HELLO LINUX! Linux is a free unix-type opterating system. This is a linux testfile! Linux test Google THHbao Banbooob Tesetfile Wiki \u8303\u4f8b\uff1a\u9664\u6307\u5b9a\u6587\u4ef6\u5916\uff0c\u5176\u4f59\u90fd\u5220\u9664\u3002 $ touch { 1 ..9 } file.txt $ ls 1file.txt 2file.txt 3file.txt 4file.txt 5file.txt 6file.txt 7file.txt 8file.txt 9file.txt $ ls | grep -E '(3|5|7)file\\.txt' 3file.txt 5file.txt 7file.txt $ ls | grep -Ev '(3|5|7)file\\.txt' 1file.txt 2file.txt 4file.txt 6file.txt 8file.txt 9file.txt \u4e0b\u9762\u56db\u79cd\u65b9\u6cd5\u5b9e\u73b0\u540c\u6837\u7684\u529f\u80fd $ rm ` ls | grep -Ev '(3|5|7)file\\.txt' ` $ ls | sed -n '/^[357]file.txt/!p' | xargs rm $ ls | grep -Ev '(3|5|7)file\\.txt' | sed -n 's/.*/rm &/p' | bash $ ls | grep -Ev '(3|5|7)file\\.txt' | sed -En 's/(.*)/rm &/p' | bash $ ls | grep -Ev '(3|5|7)file\\.txt' | sed -En 's/(.*)/rm \\1/p' | bash $ ls 3file.txt 5file.txt 7file.txt \u540e\u5411\u5f15\u7528 \\0 \\1 \\2 \u7b49\u3002 $ $echo 123456789 | sed -nE 's/(123)(456)(789)/\\1/p' 123 $ echo 123456789 | sed -nE 's/(123)(456)(789)/\\2/p' 456 $ echo 123456789 | sed -nE 's/(123)(456)(789)/\\3/p' 789 $ echo 123456789 | sed -nE 's/(123)(456)(789)/\\3\\1\\2/p' 789123456 $ echo 123456789 | sed -nE 's/(123)(456)(789)/\\1xyz\\2/p' 123xyz456 \u8303\u4f8b\uff1a\u83b7\u53d6\u5206\u533a\u5229\u7528\u7387 $ df | sed -En '/^\\/dev\\/sd/p' /dev/sda2 102750208 7079236 92053692 8 % / /dev/sda2 102750208 7079236 92053692 8 % /.snapshots /dev/sda2 102750208 7079236 92053692 8 % /boot/grub2/i386-pc /dev/sda2 102750208 7079236 92053692 8 % /boot/grub2/x86_64-efi /dev/sda2 102750208 7079236 92053692 8 % /home /dev/sda2 102750208 7079236 92053692 8 % /opt /dev/sda2 102750208 7079236 92053692 8 % /root /dev/sda2 102750208 7079236 92053692 8 % /srv /dev/sda2 102750208 7079236 92053692 8 % /usr/local /dev/sda2 102750208 7079236 92053692 8 % /tmp /dev/sda2 102750208 7079236 92053692 8 % /var $ df | sed -En '/^\\/dev\\/sd/s@.*([0-9]+)%.*@\\1@p' $ df | sed -En '/^\\/dev\\/sd/s#.*([0-9]+)%.*#\\1#p' # df | sed -En '/^\\/dev\\/sd/s/.*([0-9]+)%.*/\\1/p' 8 8 8 8 8 8 8 8 8 8 8 \u4f53\u4f1a\u4e0b\u9762\u7a7a\u683c\u548c\u62ec\u5f27\u5e26\u6765\u7684\u4e0d\u540c\u3002 $ df | sed -En '/^\\/dev\\/sd/s# .*([0-9]+)%.*# \\1#p' /dev/sda2 8 /dev/sda2 8 /dev/sda2 8 /dev/sda2 8 /dev/sda2 8 /dev/sda2 8 /dev/sda2 8 /dev/sda2 8 /dev/sda2 8 /dev/sda2 8 /dev/sda2 8 $ df | sed -En '/^\\/dev\\/sd/s#( .*)([0-9]+)%.*# \\1#p' /dev/sda2 102750208 7079804 92053156 /dev/sda2 102750208 7079804 92053156 /dev/sda2 102750208 7079804 92053156 /dev/sda2 102750208 7079804 92053156 /dev/sda2 102750208 7079804 92053156 /dev/sda2 102750208 7079804 92053156 /dev/sda2 102750208 7079804 92053156 /dev/sda2 102750208 7079804 92053156 /dev/sda2 102750208 7079804 92053156 /dev/sda2 102750208 7079804 92053156 /dev/sda2 102750208 7079804 92053156 $ df | sed -En '/^\\/dev\\/sd/s#( .*)([0-9]+)%.*# \\2#p' /dev/sda2 8 /dev/sda2 8 /dev/sda2 8 /dev/sda2 8 /dev/sda2 8 /dev/sda2 8 /dev/sda2 8 /dev/sda2 8 /dev/sda2 8 /dev/sda2 8 /dev/sda2 8 \u8303\u4f8b\uff1a\u53d6\u5f97\u5f53\u524dIP\u5730\u5740\u3002 $ ifconfig eth0 eth0: flags = 4163 mtu 1500 inet 192 .168.10.210 netmask 255 .255.255.0 broadcast 192 .168.10.255 inet6 fe80::20c:29ff:fea4:e17a prefixlen 64 scopeid 0x20 ether 00 :0c:29:a4:e1:7a txqueuelen 1000 ( Ethernet ) RX packets 22923 bytes 1658298 ( 1 .5 MiB ) RX errors 0 dropped 0 overruns 0 frame 0 TX packets 3763 bytes 442641 ( 432 .2 KiB ) TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0 $ ip addr show eth0 2 : eth0: mtu 1500 qdisc pfifo_fast state UP group default qlen 1000 link/ether 00 :0c:29:a4:e1:7a brd ff:ff:ff:ff:ff:ff altname enp2s1 altname ens33 inet 192 .168.10.210/24 brd 192 .168.10.255 scope global eth0 valid_lft forever preferred_lft forever inet6 fe80::20c:29ff:fea4:e17a/64 scope link valid_lft forever preferred_lft forever $ ifconfig eth0 | sed -En '2s/[^0-9]+([0-9.]+).*/\\1/p' $ ifconfig eth0 | sed -En '2s/^[^0-9]+([0-9.]{7,15}).*/\\1/p' $ ifconfig eth0 | sed -En '2s/^[^0-9]+([0-9.]{7,15}).*$/\\1/p' $ ifconfig eth0 | sed -n '2s/^.*inet //p' | sed -n 's/netmask.*//p' $ ifconfig eth0 | sed -n '2s/^.*inet //;s/ netmask.*//p' $ ifconfig eth0 | sed -En '2s/(.*inet )([0-9].*)(netmask.*)/\\2/p' 192 .168.10.210 192 .168.10.210 192 .168.10.210 \u4f7f\u7528 \\0 \u8f93\u51fa\u5168\u90e8\u53d8\u91cf\u3002 $ ifconfig eth0 | sed -En '2s/(.*inet )([0-9].*)(netmask.*)/\\0/p' inet 192 .168.10.210 netmask 255 .255.255.0 broadcast 192 .168.10.255 $ ifconfig eth0 | sed -En '2s/(.*inet )([0-9].*)(netmask.*)/\\1/p' inet $ ifconfig eth0 | sed -En '2s/(.*inet )([0-9].*)(netmask.*)/\\2/p' 192 .168.10.210 $ ifconfig eth0 | sed -En '2s/(.*inet )([0-9].*)(netmask.*)/\\3/p' netmask 255 .255.255.0 broadcast 192 .168.10.255 \u5bf9\u6bd4\u4e0b\u9762\u4e24\u4e2a\u6307\u4ee4\u7684\u5339\u914d\u5dee\u5f02\u3002 $ ifconfig eth0 | sed -n '2s/^.*inet //p' | sed -n 's/ netmask.*//p' 192 .168.10.210 $ ifconfig eth0 | sed -n '2s/^.*inet //p' | sed -n 's/netmask.* //p' 192 .168.10.210 192 .168.10.255 $ ifconfig eth0 | sed -n '2s/^.*inet //p' | sed -n 's/netmask .*//p' 192 .168.10.210 $ ifconfig eth0 | sed -n '2s/^.*inet //p' | sed -n 's/netmask.*//p' 192 .168.10.210 \u8303\u4f8b\uff1a\u53d6\u57fa\u540d\u548c\u76ee\u5f55\u540d\u3002 \uff08 /etc/sysconfig/network-scripts/ \u76ee\u5f55\u5728Rocky9\u4e2d\u9ed8\u8ba4\u5df2\u521b\u5efa\uff0c\u5728openSUSE\u548cUbuntu\u4e2d\u6ca1\u6709\uff09 # \u53d6\u76ee\u5f55\u540d $ echo \"/etc/sysconfig/network-scripts/\" | sed -E 's#(^/.*/)([^/]+/?)#\\1#' $ echo \"/etc/sysconfig/network-scripts/\" | sed -E 's/(^\\/.*\\/)([^\\/]+\\/?)/\\1/' /etc/sysconfig/ # \u53d6\u57fa\u540d $ echo \"/etc/sysconfig/network-scripts/\" | sed -E 's#(^/.*/)([^/]+/?)#\\2#' $ echo \"/etc/sysconfig/network-scripts/\" | sed -E 's/(^\\/.*\\/)([^\\/]+\\/?)/\\2/' network-scripts/ # \u53d6\u76ee\u5f55\u540d $ echo \"/etc/sysconfig/network-scripts/dummyfile\" | sed -E 's#(^/.*/)([^/]+/?)#\\1#' $ echo \"/etc/sysconfig/network-scripts/dummyfille\" | sed -E 's/(^\\/.*\\/)([^\\/]+\\/?)/\\1/' /etc/sysconfig/network-scripts/ # \u53d6\u57fa\u540d $ echo \"/etc/sysconfig/network-scripts/dummyfile\" | sed -E 's#(^/.*/)([^/]+/?)#\\2#' $ echo \"/etc/sysconfig/network-scripts/dummyfille\" | sed -E 's/(^\\/.*\\/)([^\\/]+\\/?)/\\2/' dummyfille \u8303\u4f8b\uff1a\u53d6\u6587\u4ef6\u540d\u548c\u6587\u4ef6\u6269\u5c55\u540d $ echo 1_.file.tar.gz | sed -En 's/(.*)\\.([^.]+)$/\\1/p' $ echo 1_.file.tar.gz | sed -En 's@(.*)\\.([^.]+)$@\\1@p' 1_.file.tar $ echo 1_.file.tar.gz | sed -En 's/(.*)\\.([^.]+)$/\\2/p' $ echo 1_.file.tar.gz | sed -En 's@(.*)\\.([^.]+)$@\\2@p' gz $ echo 1_.file.tar.gz | grep -Eo '.*\\.' 1_.file.tar. $ echo 1_.file.tar.gz | grep -Eo '[^.]+$' gz \u8303\u4f8b\uff1a\u5c06\u975e # \u5f00\u5934\u7684\u884c\u6dfb\u52a0 # $ cat < testfile HELLO LINUX! Linux is a free unix-type opterating system. This is a linux testfile! Linux test Google Taobao Banbooob #Tesetfile #Wiki EOF $ sed -En 's/^[^#]/#&/p' testfile $ sed -En 's/^[^#](.*)/#\\1/p' testfile #HELLO LINUX! #Linux is a free unix-type opterating system. #This is a linux testfile! #Linux test #Google #Taobao #Banbooob \u8303\u4f8b\uff1a\u5c06 # \u5f00\u5934\u7684\u884c\u5220\u9664 # $ cat < testfile HELLO LINUX! Linux is a free unix-type opterating system. This is a linux testfile! Linux test Google Taobao Banbooob #Tesetfile #Wiki EOF $ sed -Ei.bak '/^#/s/^#//' testfile $ cat testfile HELLO LINUX! Linux is a free unix-type opterating system. This is a linux testfile! Linux test Google Taobao Banbooob Tesetfile Wiki sed \u4fdd\u6301\u7a7a\u95f4\uff08hold space\uff09\u7684\u4f8b\u5b50\uff1a d \uff1a\u5220\u9664pattern space\u7684\u5185\u5bb9\uff0c\u5f00\u59cb\u4e0b\u4e00\u4e2a\u5faa\u73af\u3002 D \uff1a\u5982\u679c\u6a21\u5f0f\u7a7a\u95f4\u4fdd\u62a4\u6362\u884c\u7b26\uff0c\u5219\u5220\u9664\u76f4\u5230\u7b2c\u4e00\u4e2a\u6362\u884c\u7b26\u5230\u6a21\u5f0f\u7a7a\u95f4\u4e2d\u7684\u6587\u672c\uff0c\u5e76\u4e0d\u8bfb\u53d6\u65b0\u7684\u8f93\u5165\u884c\uff0c\u800c\u4f7f\u7528\u5408\u6210\u7684\u6a21\u5f0f\u7a7a\u95f4\u91cd\u65b0\u542f\u52a8\u5faa\u73af\u3002\u5982\u679c\u6a21\u5f0f\u7a7a\u95f4\u4e0d\u5305\u542b\u6362\u884c\u7b26\uff0c\u5219\u7c7b\u4f3c d \u547d\u4ee4\u542f\u52a8\u6b63\u5e38\u7684\u65b0\u5faa\u73af\u3002 h \u3001 H \uff1a\u590d\u5236/\u8ffd\u52a0\u6a21\u5f0f\u7a7a\u95f4\u7684\u5185\u5bb9\u5230\u4fdd\u6301\u7a7a\u95f4\u3002 g \u3001 G \uff1a\u590d\u5236/\u8ffd\u52a0\u4fdd\u6301\u7a7a\u95f4\u7684\u5185\u5bb9\u5230\u6a21\u5f0f\u7a7a\u95f4\u3002 n \u3001 N \uff1a\u590d\u5236/\u8ffd\u52a0\u5339\u914d\u5230\u7684\u4e0b\u4e00\u884c\u5230\u6a21\u5f0f\u7a7a\u95f4\u3002 p\uff1a\u6253\u5370\u5f53\u524d\u6a21\u5f0f\u7a7a\u95f4\u5185\u5bb9\u3002 P\uff1a\u6253\u5370\u6a21\u5f0f\u7a7a\u95f4\u5f00\u5934\u81f3 \\n \u7684\u5185\u5bb9\uff0c\u5e76\u8ffd\u52a0\u5230\u9ed8\u8ba4\u8f93\u51fa\u4e4b\u524d\u3002 x \uff1a\u4ea4\u6362\u4fdd\u6301\u7a7a\u95f4\u548c\u6a21\u5f0f\u7a7a\u95f4\u7684\u5185\u5bb9. \u4e3e\u4f8b\u89e3\u8bfb1\uff1a seq 10 \u547d\u4ee4\u8f93\u51fa1\uff5e10\u4e2a\u6570\u5b57\uff0c\u6bcf\u4e2a\u6570\u5b57\u4e00\u884c\u3002 sed \u547d\u4ee4\u8bfb\u53d6\u7b2c\u4e00\u884c 1 \u5230\u6a21\u5f0f\u7a7a\u95f4\u3002\u56e0\u4e3a\u53c2\u6570 -n \uff0c\u6240\u4ee5\u8bfb\u53d6\u5230\u7684 1 \u4e0d\u6253\u5370\u5230\u5c4f\u5e55\u3002 \u6267\u884c n \u547d\u4ee4\uff0c\u5373\u8bfb\u53d6\u5339\u914d\u5230\u7684\u4e0b\u4e00\u884c\u5230\u6a21\u5f0f\u7a7a\u95f4\uff0c\u5373\u628a\u7b2c\u4e8c\u884c\u7684 2 \u8bfb\u53d6\u5e76\u8986\u76d6\u5230\u6a21\u5f0f\u7a7a\u95f4\u3002 \u6267\u884c p \u547d\u4ee4\uff0c\u628a 2 \u8f93\u51fa\u5230\u5c4f\u5e55\u3002 \u4ee5\u6b64\u7c7b\u63a8\uff0c\u8bfb\u53d6\u7b2c\u4e09\u884c\u7684 3 \u5230\u6a21\u5f0f\u7a7a\u95f4\uff0c\u6267\u884c n \u547d\u4ee4\uff0c\u5c06\u7b2c\u56db\u884c\u7684 4 \u8bfb\u53d6\u5e76\u8986\u76d6\u5230\u6a21\u5f0f\u7a7a\u95f4\u3002\u6267\u884c p \u547d\u4ee4\uff0c\u8f93\u51fa 4 \u5230\u5c4f\u5e55\u3002 \u4ee5\u6b64\u7c7b\u63a8\u3002 $ seq 10 | sed -n 'n;p' 2 4 6 8 10 seq 10 | sed 'n;p' 1 2 2 3 4 4 5 6 6 7 8 8 9 10 10 \u4e3e\u4f8b\u89e3\u8bfb2\uff1a seq 10 \u547d\u4ee4\u8f93\u51fa1\uff5e10\u4e2a\u6570\u5b57\uff0c\u6bcf\u4e2a\u6570\u5b57\u4e00\u884c\u3002 sed \u547d\u4ee4\u8bfb\u53d6\u7b2c\u4e00\u884c\u5230 1 \u5230\u6a21\u5f0f\u7a7a\u95f4\uff08\u8986\u76d6\uff09\u3002 \u6267\u884c\u547d\u4ee4 N \uff0c\u5373\u8bfb\u53d6\u4e0b\u4e00\u884c\uff0c\u5373\u7b2c\u4e8c\u884c\u7684 2 \uff0c\u8ffd\u52a0\u5230\u6a21\u5f0f\u7a7a\u95f4\u3002\u6240\u4ee5\u5f53\u524d\u6a21\u5f0f\u7a7a\u95f4\u6709 1 \u548c 2 \u8fd92\u884c\u8bb0\u5f55\u3002 \u6267\u884c s/\\n// \uff0c\u628a\u6a21\u5f0f\u7a7a\u95f4\u4e2d\u7684\u7b2c\u4e00\u884c\u7684 1 \u540e\u9762\u7684 \\n \u66ff\u6362\u4e3a\u7a7a\uff0c\u5373\uff0c\u539f\u6765\u6a21\u5f0f\u7a7a\u95f4\u7684\u4e24\u884c 1 \u548c 2 \u73b0\u5728\u5408\u5e76\u4e3a\u4e00\u884c\uff0c\u5373 12 \u3002 \u8bfb\u53d6\u7b2c\u4e09\u884c\u7684 3 \u5230\u6a21\u5f0f\u7a7a\u95f4\uff08\u8986\u76d6\uff09\u3002 \u6267\u884c\u547d\u4ee4 N \uff0c\u5373\u8bfb\u53d6\u4e0b\u4e00\u884c\uff0c\u5373\u7b2c\u56db\u884c\u7684 4 \uff0c\u8ffd\u52a0\u5230\u6a21\u5f0f\u7a7a\u95f4\u3002\u6240\u4ee5\u5f53\u524d\u6a21\u5f0f\u7a7a\u95f4\u6709 3 \u548c 4 \u8fd92\u884c\u8bb0\u5f55\u3002 \u6267\u884c s/\\n// \uff0c\u628a\u6a21\u5f0f\u7a7a\u95f4\u4e2d\u7684\u7b2c\u4e00\u884c 3 \u540e\u9762\u7684 \\n \u66ff\u6362\u4e3a\u7a7a\uff0c\u5373\uff0c\u539f\u6765\u6a21\u5f0f\u7a7a\u95f4\u7684\u4e24\u884c 3 \u548c 4 \u73b0\u5728\u5408\u5e76\u4e3a\u4e00\u884c\uff0c\u5373 34 \u3002 \u4ee5\u6b64\u7c7b\u63a8\u3002 $ seq 10 | sed 'N;s/\\n//' 12 34 56 78 910 \u4e3e\u4f8b\u89e3\u8bfb3\uff1a seq 10 \u547d\u4ee4\u8f93\u51fa1\uff5e10\u4e2a\u6570\u5b57\uff0c\u6bcf\u4e2a\u6570\u5b57\u4e00\u884c\u3002 sed \u547d\u4ee4\u8bfb\u53d6\u7b2c\u4e00\u884c\u5230 1 \u5230\u6a21\u5f0f\u7a7a\u95f4\uff08\u8986\u76d6\uff09\u3002 \u6267\u884c !G \uff0c\u5373\u5bf9\u7b2c\u4e00\u884c\u7684 1 \u4e0d\u6267\u884c G \u547d\u4ee4\u3002 \u6267\u884c h \u547d\u4ee4\uff0c\u5373\u628a 1 \u4ece\u6a21\u5f0f\u7a7a\u95f4\u8986\u76d6\u81f3\u4fdd\u6301\u7a7a\u95f4\u3002\u81f3\u6b64\uff0c\u4fdd\u6301\u7a7a\u95f4\u548c\u6a21\u5f0f\u7a7a\u95f4\u90fd\u5b58\u6709 1 \u3002 \u6267\u884c $!d \uff0c\u5373\u4e0d\u662f\u6700\u540e\u4e00\u884c\u5c31\u4ece\u6a21\u5f0f\u7a7a\u95f4\u5220\u9664\uff0c\u6240\u4ee5\u628a 1 \u4ece\u6a21\u5f0f\u7a7a\u95f4\u4e2d\u5220\u9664\u3002 sed \u547d\u4ee4\u8bfb\u53d6\u7b2c\u4e8c\u884c\u5230 2 \u5230\u6a21\u5f0f\u7a7a\u95f4\uff08\u8986\u76d6\uff09\u3002 \u6267\u884c !G \uff0c\u5373\u5bf9\u7b2c\u4e8c\u884c\u7684 2 \u6267\u884c G \u547d\u4ee4\uff0c\u628a 1 \u4ece\u4fdd\u6301\u7a7a\u95f4\u8ffd\u52a0\u5230\u6a21\u5f0f\u7a7a\u95f4\u3002\u81f3\u6b64\uff0c\u4fdd\u6301\u7a7a\u95f4\u5b58\u6709 1 \uff0c\u6a21\u5f0f\u7a7a\u95f4\u5b58\u6709 2 \u548c 1 \u3002 \u6267\u884c h \u547d\u4ee4\uff0c\u5373\u628a 2 \u548c 1 \u4ece\u6a21\u5f0f\u7a7a\u95f4\u8986\u76d6\u81f3\u4fdd\u6301\u7a7a\u95f4\u3002\u81f3\u6b64\uff0c\u4fdd\u6301\u7a7a\u95f4\u548c\u6a21\u5f0f\u7a7a\u95f4\u90fd\u5b58\u6709 2 \u548c 1 \u3002 \u6267\u884c $!d \uff0c\u5373\u4e0d\u662f\u6700\u540e\u4e00\u884c\u5c31\u4ece\u6a21\u5f0f\u7a7a\u95f4\u5220\u9664\uff0c\u6240\u4ee5\u628a 2 \u548c 1 \u4ece\u6a21\u5f0f\u7a7a\u95f4\u4e2d\u5220\u9664\u3002 \u4ee5\u6b64\u7c7b\u63a8\uff0c\u76f4\u81f3\u8bfb\u53d6\u6700\u540e\u4e00\u884c10\u3002\u6b64\u65f6\uff0c\u6a21\u5f0f\u7a7a\u95f4\u662f 10 \uff0c\u4fdd\u6301\u7a7a\u95f4\u5b58\u6709 9 \u3001 8 \u3001 7 \u3001 6 \u3001 5 \u3001 4 \u3001 3 \u3001 2 \u3001 1 \u3002 \u6267\u884c !G \uff0c\u5373\u5bf9\u6700\u540e\u4e00\u884c\u7684 10 \u6267\u884c G \u547d\u4ee4\uff0c\u628a 9 \u3001 8 \u3001 7 \u3001 6 \u3001 5 \u3001 4 \u3001 3 \u3001 2 \u3001 1 \u4ece\u4fdd\u6301\u7a7a\u95f4\u8ffd\u52a0\u5230\u6a21\u5f0f\u7a7a\u95f4\u3002\u81f3\u6b64\uff0c\u4fdd\u6301\u7a7a\u95f4\u5b58\u6709 9 \u3001 8 \u3001 7 \u3001 6 \u3001 5 \u3001 4 \u3001 3 \u3001 2 \u3001 1 \u3002\uff0c\u6a21\u5f0f\u7a7a\u95f4\u5b58\u6709 10 \u3001 9 \u3001 8 \u3001 7 \u3001 6 \u3001 5 \u3001 4 \u3001 3 \u3001 2 \u3001 1 \u3002 \u6267\u884c h \u547d\u4ee4\uff0c\u5373\u628a 10 \u3001 9 \u3001 8 \u3001 7 \u3001 6 \u3001 5 \u3001 4 \u3001 3 \u3001 2 \u3001 1 \u4ece\u6a21\u5f0f\u7a7a\u95f4\u8986\u76d6\u81f3\u4fdd\u6301\u7a7a\u95f4\u3002\u81f3\u6b64\uff0c\u4fdd\u6301\u7a7a\u95f4\u548c\u6a21\u5f0f\u7a7a\u95f4\u90fd\u5b58\u6709 10 \u3001 9 \u3001 8 \u3001 7 \u3001 6 \u3001 5 \u3001 4 \u3001 3 \u3001 2 \u3001 1 \u3002 \u6267\u884c $!d \uff0c\u5f53\u524d\u662f\u6700\u540e\u4e00\u884c\uff0c\u6240\u4ee5\u4e0d\u4ece\u6a21\u5f0f\u7a7a\u95f4\u5220\u9664\u5f53\u524d\u5185\u5bb9\u3002 \u8f93\u51fa\u6a21\u5f0f\u7a7a\u95f4\u5185\u5bb9\u81f3\u5c4f\u5e55\u3002\u537310\uff5e1\u3002 $ seq 10 | sed '1!G;h;$!d' 10 9 8 7 6 5 4 3 2 1 \u5176\u4ed6\u4e00\u4e9b\u4f8b\u5b50\uff1a $ seq 10 | sed -n '/3/{g;1!p;};h' 2 $ seq 10 | sed -nr '/3/{n;p}' 4 $ seq 10 | sed 'N;D' 10 $ seq 10 | sed '3h;9G;9!d' 9 3 $ seq 10 | sed '$!N;$!D' 9 10 $ seq 10 | sed '$!d' 10 $ seq 10 | sed 'G' 1 2 3 4 5 6 7 8 9 10 $ seq 10 | sed 'g' $ seq 10 | sed '/^$/d;G' 1 2 3 4 5 6 7 8 9 10 $ seq 10 | sed 'n;d' 1 3 5 7 9 $ seq 10 | sed -n '1!G;h;$p' 10 9 8 7 6 5 4 3 2 1 5.10.\u4e09\u5251\u5ba2 awk \u547d\u4ee4 \u00b6 awk \u662f\u4e00\u4e2a\u6587\u672c\u5206\u6790\u5de5\u5177\u3002 grep \u64c5\u957f\u67e5\u627e\uff0c sed \u64c5\u957f\u7f16\u8f91\uff0c awk \u64c5\u957f\u6570\u636e\u5206\u6790\u5e76\u751f\u6210\u62a5\u544a\u3002 awk \u7684\u540d\u79f0\u5f97\u81ea\u4e8e\u5b83\u7684\u521b\u59cb\u4ebaAlfred Aho \u3001Peter Weinberger \u548c Brian Kernighan \u59d3\u6c0f\u7684\u9996\u4e2a\u5b57\u6bcd\u3002 awk \u67093\u4e2a\u4e0d\u540c\u7248\u672c: awk \u3001 nawk \u548c gawk \u3002\u6211\u4eec\u8bf4\u7684 awk \u4e00\u822c\u6307 gawk \u3002 gawk \u662f awk \u7684GNU\u7248\u672c\u3002 awk \u628a\u6587\u4ef6\u9010\u884c\u8bfb\u5165\uff0c\u4ee5\u7a7a\u683c\u4e3a\u9ed8\u8ba4\u5206\u9694\u7b26\u5c06\u6bcf\u884c\u5207\u7247\uff0c\u518d\u5bf9\u5207\u7247\u8fdb\u884c\u5206\u6790\u5904\u7406\u3002 5.10.1.\u547d\u4ee4\u683c\u5f0f \u00b6 awk 'pattern{action statements;...}' {filenames} pattern \u8868\u793a awk \u5728\u6570\u636e\u4e2d\u67e5\u627e\u7684\u5185\u5bb9\u3002\u662f\u8981\u8868\u793a\u7684\u6b63\u5219\u8868\u8fbe\u5f0f\uff0c\u7528\u659c\u6760\u62ec\u8d77\u6765\u3002 action \u662f\u5728\u627e\u5230\u5339\u914d\u5185\u5bb9\u65f6\u6240\u6267\u884c\u7684\u4e00\u7cfb\u5217\u547d\u4ee4\u3002 -F \uff1a\u6307\u5b9a\u5206\u9694\u7b26\uff0c\u540e\u9762\u7d27\u8ddf\u5355\u5f15\u53f7\uff0c\u5355\u5f15\u53f7\u5185\u662f\u5206\u9694\u7b26\u3002\u5982\u4e0d\u52a0 -F \u9009\u9879\uff0c\u5219\u4ee5\u7a7a\u683c\u6216\u8005tab\u4f5c\u4e3a\u5206\u9694\u7b26\u3002 -v \uff1avar=value\uff0c\u53d8\u91cf\u8d4b\u503c\u3002 \u63d0\u793a\uff1a -F \"\" \u6307\u5b9a\u7a7a\u5b57\u7b26\u4e32\u4f5c\u4e3a\u5b57\u6bb5\u5206\u9694\u7b26\uff0c\u4ece\u800c\u5c06\u8f93\u5165\u5b57\u7b26\u4e32\u4e2d\u7684\u6bcf\u4e2a\u5b57\u7b26\u4f5c\u4e3a\u4e00\u4e2a\u72ec\u7acb\u7684\u5b57\u6bb5\u8fdb\u884c\u5904\u7406\u3002\u7136\u540e\uff0c\u4f7f\u7528\u5faa\u73af\u904d\u5386\u6bcf\u4e2a\u5b57\u6bb5\uff0c\u5982\u679c\u5b57\u6bb5\u4e2d\u5305\u542b\u6570\u5b57\uff0c\u5219\u5c06\u5176\u6dfb\u52a0\u5230str1\u53d8\u91cf\u4e2d\u3002\u6700\u540e\uff0c\u6253\u5370str1\u7684\u503c\u3002 -F '' \u4e2d\u7684\u4e24\u4e2a\u5355\u5f15\u53f7\u4e4b\u95f4\u6ca1\u6709\u63d0\u4f9b\u6709\u6548\u7684\u5b57\u6bb5\u5206\u9694\u7b26\u3002\u5728awk\u4e2d\uff0c\u5b57\u6bb5\u5206\u9694\u7b26\u5fc5\u987b\u662f\u4e00\u4e2a\u975e\u7a7a\u5b57\u7b26\u4e32\u3002 \u793a\u4f8b\uff1a\u7b2c\u4e00\u4e2a\u548c\u7b2c\u4e09\u4e2a\u547d\u4ee4\u662f\u6b63\u786e\u7684\u3002 $ echo 'Yd$@C#M05MD9&8923+Vip3wZ!33*44&55' | awk -F \"\" '{for(i=1;i<=NF;i++){if($i ~ /[[:digit:]]/){str=$i;str1=(str1 str)}};print str1}' 05989233334455 $ echo 'Yd$@C#M05MD9&8923+Vip3wZ!33*44&55' | awk -F \"\" '{for(i=1;i<=NF;i++){if($i ~ /[[:digit:]]/){str=$i;str1=(str1 str)}};print str1}' $ echo 'Yd$@C#M05MD9&8923+Vip3wZ!33*44&55' | awk -F '' '{for(i=1;i<=NF;i++){if($i ~ /[[:digit:]]/){str=$i;str1=(str1 str)}};print str1}' 05989233334455 $ echo 'Yd$@C#M05MD9&8923+Vip3wZ!33*44&55' | awk -F '' '{for(i=1;i<=NF;i++){if($i ~ /[[:digit:]]/){str=$i;str1=(str1 str)}};print str1}' 5.10.2.\u5de5\u4f5c\u8fc7\u7a0b \u00b6 \u6267\u884cBEGIN{action;...}\u8bed\u53e5\u5757\u4e2d\u7684\u8bed\u53e5\u3002 BEGIN\u8bed\u53e5\u5757\u518dawk\u8bfb\u5165\u8f93\u5165\u6d41\u4e4b\u524d\u88ab\u6267\u884c\u3002 \u662f\u53ef\u9009\u8bed\u53e5\u5757\u3002 \u5305\u542b\u521d\u59cb\u5316\u53d8\u91cf\uff0c\u6253\u5370\u8f93\u51fa\u8868\u683c\u7684\u8868\u5934\u7b49\u8bed\u53e5\u3002 \u4ece\u6587\u4ef6\u6216\u8005\u6807\u51c6\u8f93\u5165stdin\u8bfb\u53d6\u4e00\u884c\uff0c\u7136\u540e\u6267\u884cpattern{action;...}\u8bed\u53e5\u5757\u3002\u4ece\u7b2c\u4e00\u884c\u5f00\u59cb\u5230\u6700\u540e\u4e00\u884c\uff0c\u9010\u884c\u626b\u63cf\u6587\u4ef6\uff0c\u91cd\u590d\u8fd9\u4e2a\u52a8\u4f5c\uff0c\u76f4\u5230\u6587\u4ef6\u6216\u8005\u8f93\u5165\u6d41\u5168\u90e8\u88ab\u8bfb\u53d6\u5b8c\u6bd5\u3002 \u53ef\u9009\u8bed\u53e5\u5757\u3002 \u5982\u679c\u6ca1\u6709\u63d0\u4f9bpattern\u8bed\u53e5\u5757\uff0c\u5219\u9ed8\u8ba4\u6267\u884c{print}\u3002 \u5f53\u8bfb\u81f3\u6587\u4ef6\u6216\u8005\u8f93\u5165\u6d41\u672b\u5c3e\u65f6\uff0c\u6267\u884cEND{action;...}\u8bed\u53e5\u5757\uff0c\u6bd4\u5982\u6253\u5370\u6240\u6709\u884c\u7684\u5206\u6790\u7ed3\u679c\u8fd9\u7c7b\u6c47\u603b\u4fe1\u606f\u3002\u4e5f\u662f\u4e00\u4e2a\u53ef\u9009\u8bed\u53e5\u5757\u3002 5.10.3.\u5206\u9694\u7b26\u3001\u57df\u548c\u8bb0\u5f55 \u00b6 \u6709\u5206\u9694\u7b26\u5206\u9694\u7684\u5b57\u6bb5\uff08\u5217column\uff0c\u57dffield\uff09\uff0c\u6807\u8bb0 $1 \u3001 $2 \u3001 $3 \u3001...\u3001 $n \u79f0\u4e3a\u57df\u6807\u8bc6\uff0c $0 \u4e3a\u6240\u6709\u57df\u3002\u6ce8\u610f\uff0c\u548cshell\u53d8\u91cf\u4e2d\u7684 $ \u4e0d\u540c\u3002 \u6bcf\u4e00\u884c\u6210\u4e3a\u8bb0\u5f55\uff08record\uff09\u3002 \u5982\u679c\u7701\u7565action\uff0c\u5219\u9ed8\u8ba4\u6267\u884c print $0 \u64cd\u4f5c\u3002 5.10.4.\u5e38\u7528action\u5206\u7c7b \u00b6 Output statements: print , printf Expressions: \u7b97\u672f\u3001\u6bd4\u8f83\u8868\u8fbe\u5f0f Compund statements: \u7ec4\u5408\u8bed\u53e5 Control statements: if , while \u8bed\u53e5 Input statements: \u52a8\u4f5c print \u683c\u5f0f\uff1a print item1, item2, ... \u8bf4\u660e\uff1a \u9017\u53f7\u5206\u9694\u7b26 \u8f93\u51faitem\u53ef\u4ee5\u662f\u5b57\u7b26\u4e32\uff0c\u4e5f\u53ef\u4ee5\u662f\u6570\u503c\uff0c\u662f\u5f53\u524d\u8bb0\u5f55\u7684\u5b57\u6bb5\u3001\u53d8\u91cf\u6216 awk \u8868\u8fbe\u5f0f\u3002 \u5982\u679c\u7701\u7565item\uff0c\u76f8\u5f53\u4e8e print $0 \u56fa\u5b9a\u5b57\u7b26\u9700\u8981\u7528\u53cc\u5f15\u53f7\uff0c\u800c\u53d8\u91cf\u548c\u6570\u5b57\u4e0d\u9700\u8981\u3002 \u793a\u4f8b\uff1a $ seq 5 | awk '{print \"hello awk\"}' hello awk hello awk hello awk hello awk hello awk $ seq 5 | awk '{print 3*5}' 15 15 15 15 15 $ awk -F ':' '{print \"hello\"}' /etc/passwd | head -5 hello hello hello hello hello $ awk -F ':' '{print}' /etc/passwd | head -5 root:x:0:0:root:/root:/bin/bash messagebus:x:499:499:User for D-Bus:/run/dbus:/usr/bin/false systemd-network:x:497:497:systemd Network Management:/:/usr/sbin/nologin systemd-timesync:x:496:496:systemd Time Synchronization:/:/usr/sbin/nologin nobody:x:65534:65534:nobody:/var/lib/nobody:/bin/bash $ awk -F ':' '{print $0}' /etc/passwd | head -5 root:x:0:0:root:/root:/bin/bash messagebus:x:499:499:User for D-Bus:/run/dbus:/usr/bin/false systemd-network:x:497:497:systemd Network Management:/:/usr/sbin/nologin systemd-timesync:x:496:496:systemd Time Synchronization:/:/usr/sbin/nologin nobody:x:65534:65534:nobody:/var/lib/nobody:/bin/bash $ awk -F ':' '{print $1,$3}' /etc/passwd | head -5 root 0 messagebus 499 systemd-network 497 systemd-timesync 496 nobody 65534 $ awk -F ':' '{print $1\"\\t\"$3}' /etc/passwd | head -5 root 0 messagebus 499 systemd-network 497 systemd-timesync 496 nobody 65534 $ grep \"^UUID\" /etc/fstab | awk '{print $2,$3}' / btrfs /var btrfs /usr/local btrfs /tmp btrfs /srv btrfs /root btrfs /opt btrfs /home btrfs /boot/grub2/x86_64-efi btrfs /boot/grub2/i386-pc btrfs /.snapshots btrfs swap swap \u793a\u4f8b\uff1a\u8bfb\u53d6\u5206\u533a\u5229\u7528\u7387\u3002 \u5206\u9694\u7b26\u4e2d\u7684\u5b9a\u4e49 [[:space:]]+|% \u7684\u542b\u4e49\uff0c\u4e00\u4e2a\u6216\u591a\u4e2a\u7a7a\u683c\u6216\u8005 % \u4f5c\u4e3a\u5206\u9694\u7b26\u3002 $ df | awk '{print $1,$5}' Filesystem Use% devtmpfs 0 % tmpfs 0 % tmpfs 2 % tmpfs 0 % /dev/sda2 8 % /dev/sda2 8 % /dev/sda2 8 % /dev/sda2 8 % /dev/sda2 8 % /dev/sda2 8 % /dev/sda2 8 % /dev/sda2 8 % /dev/sda2 8 % /dev/sda2 8 % /dev/sda2 8 % tmpfs 0 % $ df | grep '^/dev/sd' | awk -F '[[:space:]]+|%' '{print $1,$5}' $ df | grep '^/dev/sd' | awk -F ' +|%' '{print $1,$5}' /dev/sda2 8 /dev/sda2 8 /dev/sda2 8 /dev/sda2 8 /dev/sda2 8 /dev/sda2 8 /dev/sda2 8 /dev/sda2 8 /dev/sda2 8 /dev/sda2 8 /dev/sda2 8 \u793a\u4f8b\uff1a\u8bfb\u53d6ifconfig\u8f93\u51fa\u7ed3\u679c\u4e2d\u7684ip\u5730\u5740\u3002 $ ifconfig eth0 | sed -n '2p' | awk '/netmask/{print $2}' 192 .168.10.210 $ ifconfig eth0 | sed -n '2p' | awk '{print $2}' 192 .168.10.210 5.10.5.\u6a21\u5f0fPattern \u00b6 \u6839\u636epattern\u6761\u4ef6\uff0c\u8fc7\u6ee4\u5339\u914d\u7684\u884c\uff0c\u518d\u505a\u5904\u7406\u3002 \u5982\u679c\u672a\u6307\u5b9a\uff0c\u5373\u7a7a\u6a21\u5f0f\uff0c\u5219\u5339\u914d\u6bcf\u4e00\u884c\u3002 /regular expression/ \uff0c\u4ec5\u5904\u7406\u80fd\u591f\u6a21\u5f0f\u5339\u914d\u5230\u7684\u884c\uff08\u5373\u7ed3\u679c\u4e3a\u771f\uff09\uff0c\u9700\u8981\u7528 / \u8fdb\u884c\u62ec\u8d77\u6765\u3002 \u7ed3\u679c\u4e3a\u771f\uff0c\u5373\u975e0\u503c\u3001\u975e\u7a7a\u5b57\u7b26\u4e32 \u7ed3\u679c\u4e3a\u5047\uff0c\u53730\u503c\u3001\u7a7a\u5b57\u7b26\u4e32 \u793a\u4f8b\uff1a\u7a7a\u6a21\u5f0f awk -F \":\" '{print $1, $3}' /etc/passwd | head -n5 root 0 messagebus 499 systemd-network 497 systemd-timesync 496 nobody 65534 \u793a\u4f8b\uff1a\u975e\u7a7a\u6a21\u5f0f $ seq 5 | awk '0' $ seq 5 | awk '1' 1 2 3 4 5 $ seq 5 | awk '2' 1 2 3 4 5 $ seq 5 | awk '\"true\"' 1 2 3 4 5 $ seq 5 | awk '\"false\"' 1 2 3 4 5 $ seq 5 | awk 'true' $ seq 5 | awk 'false' $ seq 5 | awk '' $ seq 5 | awk '\"\"' $ seq 5 | awk '\"0\"' 1 2 3 4 5 \u4f53\u4f1a\u4e0b\u9762\u53d8\u91cf\u7684\u503c\u548c\u6b63\u786e\u4f7f\u7528\u53d8\u91cf\uff08\u5b57\u7b26\u4e32\u8fd8\u662f\u53d8\u91cf\uff1f\uff09 $ seq 5 | awk '\"test\"' 1 2 3 4 5 $ seq 5 | awk 'test' $ seq 5 | awk -v test = 0 '\"test\"' $ seq 5 | awk -v test = 0 'test' $ seq 5 | awk -v test = \"0\" 'test' $ seq 5 | awk -v test = \"0\" '\"test\"' 1 2 3 4 5 $ seq 5 | awk -v test = 1 'test' 1 2 3 4 5 \u4f53\u4f1a\u4e0b\u9762\u7684\u4e0e\u975e\u5224\u65ad\u3002 $ awk '1' /etc/passwd | head -n3 root:x:0:0:root:/root:/bin/bash messagebus:x:499:499:User for D-Bus:/run/dbus:/usr/bin/false systemd-network:x:497:497:systemd Network Management:/:/usr/sbin/nologin $ awk '0' /etc/passwd | head -n3 $ awk '!1' /etc/passwd | head -n3 $ awk '!0' /etc/passwd | head -n3 root:x:0:0:root:/root:/bin/bash messagebus:x:499:499:User for D-Bus:/run/dbus:/usr/bin/false systemd-network:x:497:497:systemd Network Management:/:/usr/sbin/nologin # i\u6ca1\u6709\u8d4b\u503c\uff0c\u4e3a\u5047\uff0c\u6ca1\u6709\u8f93\u51fa $ seq 5 | awk 'i' # i\u8d4b\u503c\u4e3a0\uff0c\u4e3a\u5047\uff0c\u6ca1\u6709\u8f93\u51fa $ seq 5 | awk 'i=0' # i\u8d4b\u503c\u4e3a1\uff0c\u4e3a\u771f\uff0c\u8f93\u51fa\u7b2c\u4e00\u884c\u7ed3\u679c\uff0c\u4ee5\u6b64\u7c7b\u63a8\uff0c\u6bcf\u884c\u90fd\u4e3a\u771f\uff0c\u8f93\u51fa\u5168\u90e8seq\u7684\u7ed3\u679c $ seq 5 | awk 'i=1' 1 2 3 4 5 # \u7b2c\u4e00\u6b21\u521d\u59cbi\u672a\u8d4b\u503c\uff0c\u4e3a\u5047\uff0c!i\u5219\u4e3a\u771f\uff0c\u8d4b\u503c\u7ed9i\uff0c\u6240\u4ee5i\u4e3a\u771f,\u8f93\u51faseq\u7b2c1\u884c\u7ed3\u679c # \u7b2c\u4e8c\u6b21\u521d\u59cbi\u4e3a\u771f\uff0c!i\u5219\u4e3a\u5047\uff0c\u8d4b\u503c\u7ed9i\uff0c\u6240\u4ee5i\u4e3a\u5047\uff0c\u4e0d\u8f93\u51faseq\u7b2c2\u884c\u7ed3\u679c # \u7b2c\u4e09\u6b21\u521d\u59cbi\u4e3a\u5047\uff0c!i\u5219\u4e3a\u771f\uff0c\u8d4b\u503c\u7ed9i\uff0c\u6240\u4ee5i\u4e3a\u771f\uff0c\u8f93\u51faseq\u7b2c3\u884c\u7ed3\u679c # \u4ee5\u6b64\u7c7b\u63a8\uff0c\u8f93\u51faseq\u7ed3\u679c\u7684\u5947\u6570\u884c $ seq 5 | awk 'i=!i' 1 3 5 # \u4e0e\u4e0a\u4f8b\u7684\u533a\u522b\u5728\u4e8ei\u521d\u59cb\u503c\u672a\u771f\uff0c\u7b2c\u4e00\u6b21\u7684i\u503c\u4e3a\u5047\uff0c\u4e0d\u8f93\u51faseq\u7b2c1\u884c\u7ed3\u679c # \u7b2c\u4e8c\u6b21i\u7684\u521d\u59cb\u503c\u4e3a\u5047\uff0c\u901a\u8fc7i=!i\u53d8\u4e3a\u771f\uff0c\u6240\u4ee5\u8f93\u51faseq\u7684\u7b2c2\u884c\u7ed3\u679c # \u4ee5\u6b64\u7c7b\u63a8\uff0c\u8f93\u51faseq\u7ed3\u679c\u7684\u5076\u6570\u884c $ seq 5 | awk -v i = 1 'i=!i' 2 4 # \u8f93\u51fa\u8ba1\u6570\u884c $ seq 5 | awk -v i = 0 'i=!i' 1 3 5 # \u53ea\u8f93\u51fai\u7684\u503c\uff0c\u4e0d\u8f93\u51faseq\u7684\u503c $ seq 5 | awk '{i=!i;print i}' 1 0 1 0 1 $ seq 5 | awk '{i=!i}' $ seq 5 | awk '(i=!i)' 1 3 5 $ seq 5 | awk '!(i=!i)' 2 4 5.10.6.\u622a\u53d6\u7247\u6bb5 \u00b6 \u793a\u4f8b\uff1a $ head -n2 /etc/passwd | awk -F ':' '{print $0}' root:x:0:0:root:/root:/bin/bash messagebus:x:499:499:User for D-Bus:/run/dbus:/usr/bin/false $ head -n2 /etc/passwd | awk -F ':' '{print $2}' x x $ head -n2 /etc/passwd | awk -F ':' '{print $1}' root messagebus $ head -n2 /etc/passwd | awk -F ':' '{print $1\"#\"$2\"#\"$3\"#\"$4}' root#x#0#0 messagebus#x#499#499 5.10.7.\u64cd\u4f5c\u7b26 \u00b6 5.10.7.1.\u7b97\u6570\u64cd\u4f5c\u7b26 \u00b6 x+y \uff0c x-y \uff0c x*y \uff0c x/y \uff0c x^y \uff0c x%y \u3002 -x \uff1a\u8f6c\u6362\u4e3a\u8d1f\u6570 +x \uff1a\u5c06\u5b57\u7b26\u4e32\u8f6c\u6362\u4e3a\u6570\u503c \u5217\u503c\u4e4b\u95f4\u8fdb\u884c\u7b97\u672f\u8fd0\u7b97\u3002 $ awk -F ':' '{$7=$3+$4;print $1,$3,$4,$7}' /etc/passwd | head -n5 root 0 0 0 messagebus 499 499 998 systemd-network 497 497 994 systemd-timesync 496 496 992 nobody 65534 65534 131068 \u8ba1\u7b97\u67d0\u4e2a\u5217\u7684\u603b\u548c\u3002 END \u8868\u793a\u6240\u6709\u7684\u884c\u90fd\u5df2\u7ecf\u6267\u884c\u3002 $ awk -F ':' '{(total=total+$3)}; END {print total}' /etc/passwd 103011 5.10.7.2.\u5b57\u7b26\u4e32\u64cd\u4f5c\u7b26 \u00b6 \u6ca1\u6709\u64cd\u4f5c\u7b26\u53f7\uff0c\u5b57\u7b26\u4e32\u8fde\u63a5\u3002 5.10.7.3.\u8d4b\u503c\u64cd\u4f5c\u7b26 \u00b6 = \uff0c += \uff0c -= \uff0c *= \uff0c /= \uff0c %= \uff0c ^= \uff0c ++ \uff0c -- \u3002 \u793a\u4f8b\uff1a $ awk 'BEGIN{print i}' $ awk 'BEGIN{print i++}' #\u4ece0\u5f00\u59cb 0 $ awk 'BEGIN{print ++i}' 1 $ awk 'BEGIN{print i++, i}' 0 1 $ awk 'BEGIN{i=0;print i++, i}' 0 1 $ awk 'BEGIN{print ++i, i}' 1 1 $ awk 'BEGIN{i=0;print ++i, i}' 1 1 $ awk 'BEGIN{i=0;print i, i++}' 0 0 $ awk 'BEGIN{i=0;print i, ++i}' 0 1 $ seq 10 1 2 3 4 5 6 7 8 9 10 # n\u4ece0\u5f00\u59cb\u8ba1\u6570\uff0c\u8f93\u51fa\u7684\u662fn\u503c\uff0c\u4e0d\u662fseq\u7684\u8f93\u51fa\u7ed3\u679c $ seq 10 | awk '{print n++}' 0 1 2 3 4 5 6 7 8 9 # seq=1\u65f6\uff0c\u521d\u59cbn\u672a\u8d4b\u503c\uff0c\u4e3a\u5047\uff0c\u4e0d\u8f93\u51faseq\u7ed3\u679c\uff0cn++\u4e3a\u771f # seq=2\u65f6\uff0cn\u4e3a\u771f\uff0c\u8f93\u51faseq\u7ed3\u679c\uff0cn++\u4e3a\u771f # \u540e\u7eedn++\u90fd\u4e3a\u771f\uff0c\u6240\u4ee5seq\u7684\u7ed3\u679c\u51fa\u4e86\u7b2c\u4e00\u884c\u7531\u4e8en\u4e3a\u5047\u6ca1\u6709\u8f93\u51fa\uff0c\u5176\u4ed6\u884c\u90fd\u8f93\u51fa $ seq 10 | awk 'n++' 2 3 4 5 6 7 8 9 10 # \u53c2\u8003\u4e0a\u4f8b\uff0cn\u521d\u59cb\u672a\u8d4b\u503c\uff0c\u4f46\u6267\u884c++n\u540e\u4e3a\u771f\uff0c\u6240\u4ee5\u8f93\u51fa\u7b2c\u4e00\u884c\uff0c\u540e\u7eed\u884c\u90fd\u8f93\u51fa\u56e0\u4e3an\u4e00\u76f4\u4e3a\u771f $ seq 10 | awk '++n' 1 2 3 4 5 6 7 8 9 10 # n=0\u65f6++n=1\uff0c!++n=0\uff0c\u8f93\u51fa\u7b2c0\u884c $ awk -v n = 0 '!++n' /etc/passwd # n=0\u65f6n++=1\uff0c!n++=1\uff0c\u8f93\u51fa\u7b2c1\u884c $ awk -v n = 0 '!n++' /etc/passwd root:x:0:0:root:/root:/bin/bash $ awk -v n = 0 '!n++{print n}' /etc/passwd 1 # \u65e0\u7ed3\u679c\u8f93\u51fa $ awk -v n = 0 '!++n{print n}' /etc/passwd $ awk -v n = 1 '!n++{print n}' /etc/passwd $ awk -v n = 0 '!n++' /etc/passwd root:x:0:0:root:/root:/bin/bash # \u65e0\u7ed3\u679c\u8f93\u51fa $ awk -v n = 1 '!n++' /etc/passwd $ awk -v n = 2 '!n++' /etc/passwd 5.10.7.4.\u6bd4\u8f83\u64cd\u4f5c\u7b26 \u00b6 \u4f7f\u7528 == \u4ee3\u8868\u7b49\u4e8e\uff0c\u5373\u7cbe\u786e\u5339\u914d\u3002\u7c7b\u4f3c\u8fd8\u6709 > \u3001 >= \u3001 < \u3001 <= \u3001 != \u7b26\u53f7\u3002 \u4ee5 : \u4e3a\u5206\u9694\u7b26\uff0c\u5339\u914d\u7b2c\u4e09\u5217\u7684\u503c\u4e3a 1000 \u7684\u884c\u3002 $ awk -F ':' '$3==\"100\"' /etc/passwd vagrant:x:1000:478:vagrant:/home/vagrant:/bin/bash \u5728\u548c\u6570\u5b57\u6bd4\u8f83\u65f6\uff0c\u82e5\u628a\u8981\u6bd4\u8f83\u7684\u6570\u5b57\u7528\u53cc\u5f15\u53f7\u5f15\u8d77\u6765\uff0c awk \u4f1a\u6309\u5b57\u7b26\u5904\u7406\uff0c\u4e0d\u52a0\u53cc\u5f15\u53f7\uff0c\u5219\u4f1a\u6309\u6570\u5b57\u5904\u7406\u3002 $ awk -F ':' '$3<=\"100\"' /etc/passwd root:x:0:0:root:/root:/bin/bash bin:x:1:1:bin:/bin:/usr/sbin/nologin $ awk -F ':' '$3<=100' /etc/passwd root:x:0:0:root:/root:/bin/bash postfix:x:51:51:Postfix Daemon:/var/spool/postfix:/usr/sbin/nologin man:x:13:62:Manual pages viewer:/var/lib/empty:/usr/sbin/nologin daemon:x:2:2:Daemon:/sbin:/usr/sbin/nologin at:x:25:25:Batch jobs daemon:/var/spool/atjobs:/usr/sbin/nologin bin:x:1:1:bin:/bin:/usr/sbin/nologin awk -F ':' '{if ($1==\"root\") {print $0}}' /etc/passwd awk -F ':' '$7!=\"/bin/false\"' /etc/passwd awk -F ':' '$3<$2' /etc/passwd 5.10.7.5.\u903b\u8f91\u64cd\u4f5c\u7b26 \u00b6 && \u8868\u793a\u201c\u5e76\u4e14\u201d || \u8868\u793a\u201c\u6216\u8005\u201d ! \u8868\u793a\u201c\u975e\u201d\uff08\u53d6\u53cd\uff09 awk -F ':' '$3>10 && $3<100' /etc/passwd awk -F ':' '$3>10 || $3<100' /etc/passwd awk -F ':' '($3==0)' /etc/passwd awk -F ':' '!($3==0)' /etc/passwd \u6ce8\u610f\u4e0b\u9762\u5bf9\u5b57\u7b26\u548c\u6570\u503c\u8fdb\u884c\u53d6\u53cd\u64cd\u4f5c\u7684\u7ed3\u679c\u3002 $ awk 'BEGIN{print i}' $ awk 'BEGIN{print !i}' 1 $ awk -v i = 10 'BEGIN{print i}' 10 $ awk -v i = 10 'BEGIN{print !i}' 0 $ awk -v i = -5 'BEGIN{print i}' -5 $ awk -v i = -5 'BEGIN{print !i}' 0 $ awk -v i = \"abc\" 'BEGIN{print i}' abc $ awk -v i = \"abc\" 'BEGIN{print !i}' 0 $ awk -v i = abc 'BEGIN{print i}' abc $ awk -v i = abc 'BEGIN{print !i}' 0 $ awk -v i = \"\" 'BEGIN{print i}' $ awk -v i = \"\" 'BEGIN{print !i}' 1 \u5728\u5206\u9694\u7b26\u5b9a\u4e49\u4e2d\u4f7f\u7528\u6b63\u5219\u8868\u8fbe\u5f0f\u3002 $ df | awk -F \" +|%\" '{print $5}' Use 0 0 2 0 8 8 8 8 8 8 8 8 8 8 8 0 $ df | awk -F \"[[:space:]]+|%\" '{print $5}' Use 0 0 2 0 8 8 8 8 8 8 8 8 8 8 8 0 5.10.7.6.\u4e09\u76ee\u6761\u4ef6\u8868\u8fbe\u5f0f \u00b6 \u683c\u5f0f\uff1a selector?if-true-expression:if-false-expression $ awk -F ':' '{$3>1000?usertype=\"Common User\":usertype=\"Superuser\";printf\"%-20s:%12s\\n\", $1, usertype}' /etc/passwd | head -n5 root : Superuser messagebus : Superuser systemd-network : Superuser systemd-timesync : Superuser nobody : Common User 5.10.7.8.\u6a21\u5f0f\u5339\u914d\u7b26 \u00b6 ~ \uff1a\u5de6\u53f3\u662f\u5426\u5339\u914d !~ \uff1a\u5de6\u53f3\u662f\u5426\u4e0d\u5339\u914d \u793a\u4f8b\uff1a \u5339\u914d\u6587\u4ef6\u4e2d\u6307\u5b9a\u5b57\u7b26\u4e32 root \u7684\u6240\u6709\u884c\uff0c\u7c7b\u4f3cgrep\u547d\u4ee4\uff0c\u4f46\u6ca1\u6709\u9ad8\u4eae\u663e\u793a\u3002 $ awk '/root/' /etc/passwd root:x:0:0:root:/root:/bin/bash \u4ee5 : \u4e3a\u5206\u9694\u7b26\uff0c\u5339\u914d\u7b2c\u4e00\u5217 $1 \u4e2d\u5305\u542b\u6307\u5b9a\u5b57\u7b26\u4e32 oo \u7684\u884c\u3002 ~ \u662f\u4ee3\u8868\u5de6\u53f3\u5339\u914d\u3002 $ awk -F ':' '$1 ~/oo/' /etc/passwd root:x:0:0:root:/root:/bin/bash gentoo:x:1014:100:Gentoo Distribution:/home/gentoo:/bin/csh \u4ee5 : \u4e3a\u5206\u9694\u7b26\uff0c\u5339\u914d\u6240\u6709\u5217 $0 \uff08\u6574\u884c\uff09\u4e2d\u5305\u542b root \u884c\u7684\u7b2c\u4e00\u5217 $1 \u3002 $ awk -F: '$0 ~/root/{print $1}' /etc/passwd $ awk -F: '$0 ~\"root\"{print $1}' /etc/passwd root daemon _cvmsroot \u4ee5 : \u4e3a\u5206\u9694\u7b26\uff0c\u5339\u914d\u6240\u6709\u5217 $0 \uff08\u6574\u884c\uff09\u4e2d\u4ee5 root \u5f00\u5934\u884c\u7684\u7b2c\u4e00\u5217 $1 \u3002 $ awk -F: '$0 ~\"^root\"{print $1}' /etc/passwd $ awk -F: '$0 ~/^root/{print $1}' /etc/passwd root \u4ee5 : \u4e3a\u5206\u9694\u7b26\uff0c\u5339\u914d\u6240\u6709\u5217 $0 \uff08\u6574\u884c\uff09\u4e2d\u4e0d\u4ee5 root \u5f00\u5934\u884c\u7684\u7b2c\u4e00\u5217 $1 \u3002 awk -F: '$0 !~/^root/{print $1}' /etc/passwd awk -F: '$0 ~/^[^root]/{print $1}' /etc/passwd \u591a\u6761\u4ef6\u5339\u914d\uff0c\u4ee5 : \u4e3a\u5206\u9694\u7b26\uff0c\u5339\u914d\u6240\u6709\u542b\u6709 root \u6216 ftp \u7684\u884c\uff0c\u5e76\u6253\u5370\u7b2c1\u30013\u5217\u3002 awk -F ':' '/root/ {print $1,$3} /bin/ {print $1,$3}' /etc/passwd \u591a\u6761\u4ef6\u5339\u914d\uff0c\u4ee5 : \u4e3a\u5206\u9694\u7b26\uff0c\u5339\u914d\u7b2c\u4e00\u5217\u4e2d\u542b\u6709 root \u6216 bin \u7684\u884c\uff0c\u5e76\u6253\u5370\u7b2c1\u30013\u5217\u3002 $ awk -F ':' '$1 ~/root/ {print $1,$3} $1 ~/bin/ {print $1,$3}' /etc/passwd root 0 bin 1 \u4ee5 : \u4e3a\u5206\u9694\u7b26\uff0c\u5339\u914d\u7b2c\u4e09\u5217 $3 \u4e2d\u503c\u4e3a 0 \u7684\u884c\u3002 $ awk -F \":\" '$3==0' /etc/passwd root:x:0:0:root:/root:/bin/bash \u4ee5\u81f3\u5c11\u4e00\u4e2a\u7a7a\u683c\u6216%\u4e3a\u5206\u9694\u7b26\uff0c\u5339\u914d\u4ee5 /dev/sd \u5f00\u5934\u7684\u884c\uff0c\u6253\u5370\u7b2c\u4e94\u5217\u3002 $ df | awk -F \"[[:space:]]+|%\" '$0 ~ /^\\/dev\\/sd/{print $5}' 8 8 8 8 8 8 8 8 8 8 8 \u8bfb\u53d6 ifconfig eth0 \u8f93\u51fa\u7ed3\u679c\u7684\u7b2c\u4e8c\u884c NR==2 \u7684\u7b2c\u4e8c\u5217 $2 \u3002 $ ifconfig eth0 | awk 'NR==2{print $2}' 192 .168.10.210 5.10.8.\u53d8\u91cf \u00b6 5.10.8.1.\u5185\u7f6e\u53d8\u91cf \u00b6 awk \u5e38\u7528\u7684\u53d8\u91cf\u6709 FS \u3001 OFS \u3001 NF \u548c NR \u3002 FS \u7528\u6765\u5b9a\u4e49\u8f93\u5165\u5b57\u6bb5\u5206\u9694\u7b26\uff0c\u9ed8\u8ba4\u4e3a\u7a7a\u767d\u5b57\u7b26\u3002\u4e0e -F \u9009\u9879\u529f\u80fd\u7c7b\u4f3c\uff0c\u540c\u65f6\u4f7f\u7528\u4f1a\u62a5\u9519\u3002 OFS \u7528\u6765\u5b9a\u4e49\u8f93\u51fa\u5b57\u6bb5\u5206\u9694\u7b26\uff0c\u9ed8\u8ba4\u4e3a\u7a7a\u767d\u5b57\u7b26\u3002 RS \u6307\u5b9a\u8f93\u5165\u65f6\u7684\u6362\u884c\u7b26\u3002 ORS \u6307\u5b9a\u7b26\u53f7\u5728\u8f93\u51fa\u65f6\u66ff\u6362\u6362\u884c\u7b26\u3002 NF \u8868\u793a\u7528\u5206\u9694\u7b26\u5206\u9694\u540e\u4e00\u5171\u6709\u591a\u5c11\u5217\u3002 NR \u8868\u793a\u884c\u53f7\u3002 FNR \u8868\u793a\u4e2a\u6587\u4ef6\u5206\u522b\u8ba1\u6570\u5404\u81ea\u8bb0\u5f55\u7684\u7f16\u53f7\u3002 FILENAME \u8868\u793a\u5f53\u524d\u6587\u4ef6\u540d\u3002 ARGC \u8868\u793a\u547d\u4ee4\u884c\u53c2\u6570\u7684\u4e2a\u6570\u3002 ARVC \u4ee5\u6570\u7ec4\u5f62\u5f0f\u4fdd\u5b58\u547d\u4ee4\u884c\u6240\u7ed9\u5b9a\u7684\u5404\u53c2\u6570\uff0c\u6bcf\u4e2a\u53c2\u6570\uff1a ARGV[0] \uff0c......\u3002 FS \u7684\u7528\u6cd5\uff1a $ awk -v FS = ':' '{print $1, FS, $3}' /etc/passwd | head -n5 root : 0 messagebus : 499 systemd-network : 497 $ awk -F: '{print $1FS$3}' /etc/passwd | head -n3 root:0 messagebus:499 systemd-network:497 $ S = : ; awk -v FS = $S '{print $1FS$3}' /etc/passwd | head -n3 root:0 messagebus:499 systemd-network:497 systemd-timesync:496 nobody:65534 $ S = : ; awk -F $S '{print $1FS$3}' /etc/passwd | head -n3 root:0 messagebus:499 systemd-network:497 FS \u548c -F \u9009\u9879\u529f\u540c\u65f6\u4f7f\u7528\u4f1a\u51b2\u7a81\uff0c -F \u7684\u4f18\u5148\u7ea7\u66f4\u9ad8\u3002 $ awk -v FS = ':' -F ';' '{print $1FS$3}' /etc/passwd | head -n3 root:x:0:0:root:/root:/bin/bash ; messagebus:x:499:499:User for D-Bus:/run/dbus:/usr/bin/false ; systemd-network:x:497:497:systemd Network Management:/:/usr/sbin/nologin ; $ awk -v FS = ';' -F ':' '{print $1FS$3}' /etc/passwd | head -n3 root:0 messagebus:499 systemd-network:497 OFS \u7684\u7528\u6cd5\uff1a \u4ee5 : \u4e3a\u5206\u9694\u7b26\uff0c\u6253\u5370\u7b2c1\u30013\u30014\u5217\u7b2c\u5185\u5bb9\uff0c\u5e76\u4ee5 # \u4e3a\u5206\u9694\u7b26\u3002 $ awk -F ':' '{OFS=\"#\"} {print $1,$3,$4}' /etc/passwd | head -n5 root#0#0 messagebus#499#499 systemd-network#497#497 systemd-timesync#496#496 nobody#65534#65534 $ awk -v FS = ':' -v OFS = '#' '{print $1,$3,$4}' /etc/passwd | head -n5 root#0#0 messagebus#499#499 systemd-network#497#497 systemd-timesync#496#496 nobody#65534#65534 \u4ee5 : \u4e3a\u5206\u9694\u7b26\uff0c\u5f53\u7b2c\u4e09\u5217\u5927\u4e8e\u7b49\u4e8e5000\u65f6\uff0c\u6253\u5370\u7b2c1\u30012\u30013\u30014\u5217\u7b2c\u5185\u5bb9\uff0c\u5e76\u4ee5 # \u4e3a\u5206\u9694\u7b26\u3002 $ awk -F ':' '{OFS=\"#\"} {if ($3>=5000) {print $1,$2,$3,$4}}' /etc/passwd nobody#x#65534#65534 RS \u7684\u7528\u6cd5\uff1a # \u4ee5\u7a7a\u683c\u4e3a\u6362\u884c\u6807\u5fd7 $ awk -v RS = ' ' '{print $0}' /etc/passwd | head -n3 root:x:0:0:root:/root:/bin/bash messagebus:x:499:499:User for # \u4ee5\u5192\u53f7\u4e3a\u6362\u884c\u6807\u5fd7 $ awk -v RS = ':' '{print $0}' /etc/passwd | head -n3 root x 0 ORS \u7684\u7528\u6cd5\uff1a # \u4ee5\u5192\u53f7\u4e3a\u6362\u884c\u6807\u5fd7\uff0c\u66ff\u6362\u6210### $ awk -v RS = ':' -v ORS = '###' '{print $0}' /etc/passwd | head -n3 root###x###0###0###root###/root###/bin/bash messagebus###x###499###499###User for D-Bus###/run/dbus###/usr/bin/false systemd-network###x###497###497###systemd Network Management###/###/usr/sbin/nologin NF \u7684\u7528\u6cd5\uff1a \u5176\u4e2d NF \u662f\u591a\u5c11\u5217\uff0c $NF \u662f\u6700\u540e\u4e00\u5217\u7684\u503c\u3002 \u4e0b\u4f8b\u4e2d\u4ee5 : \u4e3a\u5206\u9694\u7b26\u4e00\u5171\u5206\u4e3a7\u5217\uff0c\u6700\u540e\u4e00\u5217\u7684\u503c\u662f $NF \u3002 $ awk -F ':' '{print $NF}' /etc/passwd | head -n2 /bin/bash /usr/bin/false $ awk -F ':' '{print NF}' /etc/passwd | head -n2 7 7 $ ss -nt | grep \"^ESTAB\" | awk -F \"[[:space:]]+|:\" '{print $(NF-2)}' 192 .168.10.103 $ ss -nt | awk -F \"[[:space:]]+|:\" '/^ESTAB/{print $(NF-2)}' 192 .168.10.103 NR \u7684\u7528\u6cd5\uff1a \u901a\u8fc7 NR \u8f93\u51fa\u884c\u53f7\u3002\u4ee5 : \u4e3a\u5206\u9694\u7b26\uff0c\u6253\u5370\u524d\u4e09\u884c\u7684\u884c\u53f7\u3002 $ awk -F ':' '{print NR}' /etc/passwd | head -n3 1 2 3 \u53d6\u5947\u3001\u5076\u6570\u884c\u3002 $ seq 10 | awk 'NR%2==0' 2 4 6 8 10 $ seq 10 | awk 'NR%2==1' 1 3 5 7 9 \u901a\u8fc7 NR \u8bbe\u5b9a\u884c\u53f7\u6761\u4ef6\u3002\u4ee5 : \u4e3a\u5206\u9694\u7b26\uff0c\u6253\u5370\u7b2c40\u884c\u4ee5\u540e\u7684\u884c\u5185\u5bb9\u3002 $ awk 'NR>45' /etc/passwd admin3:x:1020:100::/home/admin3:/bin/bash smith:x:2002:0:,,,:/home/admin2:/bin/bash pm1:x:2003:1535::/home/pm1:/bin/bash tm1:x:2004:1535::/home/tm1:/bin/bash tm2:x:2005:1536::/home/tm2:/bin/bash $ awk -F ':' 'NR>45' /etc/passwd admin3:x:1020:100::/home/admin3:/bin/bash smith:x:2002:0:,,,:/home/admin2:/bin/bash pm1:x:2003:1535::/home/pm1:/bin/bash tm1:x:2004:1535::/home/tm1:/bin/bash tm2:x:2005:1536::/home/tm2:/bin/bash $ awk -F ':' 'NR>45 {print NR,$1,$3}' /etc/passwd 46 admin3 1020 47 smith 2002 48 pm1 2003 49 tm1 2004 50 tm2 2005 $ awk -F ':' 'BEGIN{print NR}' /etc/passwd 0 $ awk -F ':' 'END{print NR}' /etc/passwd 50 $ ifconfig eth0 | awk '/netmask/{print $0}' inet 192 .168.10.210 netmask 255 .255.255.0 broadcast 192 .168.10.255 $ ifconfig eth0 | awk '/netmask/{print $1}' inet $ ifconfig eth0 | awk '/netmask/{print $2}' 192 .168.10.210 $ ifconfig eth0 | awk 'NR==2{print $0}' inet 192 .168.10.210 netmask 255 .255.255.0 broadcast 192 .168.10.255 $ ifconfig eth0 | awk 'NR==2{print $1}' inet $ ifconfig eth0 | awk 'NR==2{print $2}' 192 .168.10.210 \u901a\u8fc7 NR \u4e0e\u5217\u5339\u914d\u4e00\u8d77\u4f7f\u7528\u3002 $ awk -F ':' 'NR<5 && $1 ~/roo/' /etc/passwd root:x:0:0:root:/root:/bin/bash FNR \u7684\u7528\u6cd5\uff1a $ awk '{print FNR}' /etc/fstab /etc/networks 1 2 3 4 5 6 7 8 9 10 11 12 1 2 3 4 5 6 7 8 9 10 $ awk '{print NR, $0}' /etc/fstab /etc/networks 1 UUID = 5ffa8dbd-473e-4308-804a-0033c3b5f7af / btrfs defaults 0 0 2 UUID = 5ffa8dbd-473e-4308-804a-0033c3b5f7af /var btrfs subvol = /@/var 0 0 3 UUID = 5ffa8dbd-473e-4308-804a-0033c3b5f7af /usr/local btrfs subvol = /@/usr/local 0 0 4 UUID = 5ffa8dbd-473e-4308-804a-0033c3b5f7af /tmp btrfs subvol = /@/tmp 0 0 5 UUID = 5ffa8dbd-473e-4308-804a-0033c3b5f7af /srv btrfs subvol = /@/srv 0 0 6 UUID = 5ffa8dbd-473e-4308-804a-0033c3b5f7af /root btrfs subvol = /@/root 0 0 7 UUID = 5ffa8dbd-473e-4308-804a-0033c3b5f7af /opt btrfs subvol = /@/opt 0 0 8 UUID = 5ffa8dbd-473e-4308-804a-0033c3b5f7af /home btrfs subvol = /@/home 0 0 9 UUID = 5ffa8dbd-473e-4308-804a-0033c3b5f7af /boot/grub2/x86_64-efi btrfs subvol = /@/boot/grub2/x86_64-efi 0 0 10 UUID = 5ffa8dbd-473e-4308-804a-0033c3b5f7af /boot/grub2/i386-pc btrfs subvol = /@/boot/grub2/i386-pc 0 0 11 UUID = 5ffa8dbd-473e-4308-804a-0033c3b5f7af /.snapshots btrfs subvol = /@/.snapshots 0 0 12 UUID = 47c36ad7-f49f-4ecd-9b72-4801c5bb3a04 swap swap defaults 0 0 13 # 14 # networks This file describes a number of netname-to-address 15 # mappings for the TCP/IP subsystem. It is mostly 16 # used at boot time, when no name servers are running. 17 # 18 19 loopback 127 .0.0.0 20 link-local 169 .254.0.0 21 22 # End. $ awk '{print FNR, $0}' /etc/fstab /etc/networks 1 UUID = 5ffa8dbd-473e-4308-804a-0033c3b5f7af / btrfs defaults 0 0 2 UUID = 5ffa8dbd-473e-4308-804a-0033c3b5f7af /var btrfs subvol = /@/var 0 0 3 UUID = 5ffa8dbd-473e-4308-804a-0033c3b5f7af /usr/local btrfs subvol = /@/usr/local 0 0 4 UUID = 5ffa8dbd-473e-4308-804a-0033c3b5f7af /tmp btrfs subvol = /@/tmp 0 0 5 UUID = 5ffa8dbd-473e-4308-804a-0033c3b5f7af /srv btrfs subvol = /@/srv 0 0 6 UUID = 5ffa8dbd-473e-4308-804a-0033c3b5f7af /root btrfs subvol = /@/root 0 0 7 UUID = 5ffa8dbd-473e-4308-804a-0033c3b5f7af /opt btrfs subvol = /@/opt 0 0 8 UUID = 5ffa8dbd-473e-4308-804a-0033c3b5f7af /home btrfs subvol = /@/home 0 0 9 UUID = 5ffa8dbd-473e-4308-804a-0033c3b5f7af /boot/grub2/x86_64-efi btrfs subvol = /@/boot/grub2/x86_64-efi 0 0 10 UUID = 5ffa8dbd-473e-4308-804a-0033c3b5f7af /boot/grub2/i386-pc btrfs subvol = /@/boot/grub2/i386-pc 0 0 11 UUID = 5ffa8dbd-473e-4308-804a-0033c3b5f7af /.snapshots btrfs subvol = /@/.snapshots 0 0 12 UUID = 47c36ad7-f49f-4ecd-9b72-4801c5bb3a04 swap swap defaults 0 0 1 # 2 # networks This file describes a number of netname-to-address 3 # mappings for the TCP/IP subsystem. It is mostly 4 # used at boot time, when no name servers are running. 5 # 6 7 loopback 127 .0.0.0 8 link-local 169 .254.0.0 9 10 # End. FILENAME \u7684\u7528\u6cd5\uff1a $ awk '{print FILENAME}' /etc/fstab /etc/fstab /etc/fstab /etc/fstab /etc/fstab /etc/fstab /etc/fstab /etc/fstab /etc/fstab /etc/fstab /etc/fstab /etc/fstab /etc/fstab $ awk '{print FNR, FILENAME, $0}' /etc/fstab /etc/networks 1 /etc/fstab UUID = 5ffa8dbd-473e-4308-804a-0033c3b5f7af / btrfs defaults 0 0 2 /etc/fstab UUID = 5ffa8dbd-473e-4308-804a-0033c3b5f7af /var btrfs subvol = /@/var 0 0 3 /etc/fstab UUID = 5ffa8dbd-473e-4308-804a-0033c3b5f7af /usr/local btrfs subvol = /@/usr/local 0 0 4 /etc/fstab UUID = 5ffa8dbd-473e-4308-804a-0033c3b5f7af /tmp btrfs subvol = /@/tmp 0 0 5 /etc/fstab UUID = 5ffa8dbd-473e-4308-804a-0033c3b5f7af /srv btrfs subvol = /@/srv 0 0 6 /etc/fstab UUID = 5ffa8dbd-473e-4308-804a-0033c3b5f7af /root btrfs subvol = /@/root 0 0 7 /etc/fstab UUID = 5ffa8dbd-473e-4308-804a-0033c3b5f7af /opt btrfs subvol = /@/opt 0 0 8 /etc/fstab UUID = 5ffa8dbd-473e-4308-804a-0033c3b5f7af /home btrfs subvol = /@/home 0 0 9 /etc/fstab UUID = 5ffa8dbd-473e-4308-804a-0033c3b5f7af /boot/grub2/x86_64-efi btrfs subvol = /@/boot/grub2/x86_64-efi 0 0 10 /etc/fstab UUID = 5ffa8dbd-473e-4308-804a-0033c3b5f7af /boot/grub2/i386-pc btrfs subvol = /@/boot/grub2/i386-pc 0 0 11 /etc/fstab UUID = 5ffa8dbd-473e-4308-804a-0033c3b5f7af /.snapshots btrfs subvol = /@/.snapshots 0 0 12 /etc/fstab UUID = 47c36ad7-f49f-4ecd-9b72-4801c5bb3a04 swap swap defaults 0 0 1 /etc/networks # 2 /etc/networks # networks This file describes a number of netname-to-address 3 /etc/networks # mappings for the TCP/IP subsystem. It is mostly 4 /etc/networks # used at boot time, when no name servers are running. 5 /etc/networks # 6 /etc/networks 7 /etc/networks loopback 127 .0.0.0 8 /etc/networks link-local 169 .254.0.0 9 /etc/networks 10 /etc/networks # End. ARGC \u7684\u7528\u6cd5\uff1a \u6bcf\u4e2a\u53d8\u91cf\u7684\u540d\u5b57\u901a\u8fc7 ARGV \u83b7\u53d6\u3002 $ awk '{print ARGC}' /etc/fstab /etc/issue 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 $ awk 'BEGIN{print ARGC}' /etc/fstab /etc/issue 3 ARGV \u7684\u7528\u6cd5\uff1a $ awk 'BEGIN{print ARGV[0]}' /etc/fstab /etc/issue awk $ awk 'BEGIN{print ARGV[1]}' /etc/fstab /etc/issue /etc/fstab $ awk 'BEGIN{print ARGV[2]}' /etc/fstab /etc/issue /etc/issue $ awk 'BEGIN{print ARGV[3]}' /etc/fstab /etc/issue 5.10.8.2.\u81ea\u5b9a\u4e49\u53d8\u91cf \u00b6 \u81ea\u5b9a\u4e49\u53d8\u91cf\u662f\u533a\u5206\u5b57\u7b26\u5927\u5c0f\u5199\u7684\uff0c\u4f7f\u7528\u4e0b\u9762\u7684\u65b9\u5f0f\u8fdb\u884c\u8d4b\u503c\u3002 -v var=value \u5728program\u4e2d\u76f4\u63a5\u5b9a\u4e49 \u4e3e\u4f8b\uff1a $ awk -v t1 = t2 = \"hello awk\" 'BEGIN{print t1, t2}' t2 = hello awk $ awk -v t1 = t2 = \"hello awk\" 'BEGIN{t1=t2=\"gawk\"; print t1, t2}' gawk gawk $ awk 'BEGIN{t1=t2=\"hello awk\"; print t1, t2}' hello awk hello awk $ awk -v t1 = \"hello awk\" '{print t1}' /etc/issue hello awk hello awk hello awk hello awk hello awk $ awk -v t1 = \"hello awk\" 'BEGIN{print t1}' /etc/issue hello awk $ awk -v t1 = \"hello awk\" 'BEGIN{print t1}' hello awk $ awk -F: '{sex=\"male\"; print $1, sex, age; age=28}' /etc/passwd | head -n3 root male messagebus male 28 systemd-network male 28 $ cat < awkscript {print script,$1,$2} EOF $ awk -F: -f awkscript script = \"awk\" /etc/passwd | head -n2 awk root x awk messagebus x \u52a8\u4f5c printf \u3002 \u52a8\u4f5cprintf\u53ef\u4ee5\u5b9e\u73b0\u683c\u5f0f\u5316\u8f93\u51fa\u3002 \u683c\u5f0f\uff1a printf \"FORMAT\", item1, item2, ...... \u8bf4\u660e\uff1a \u5fc5\u987b\u6307\u5b9aFORMAT \u4e0d\u4f1a\u81ea\u52a8\u6362\u884c\uff0c\u9700\u8981\u663e\u5f0f\u7ed9\u51fa\u6362\u884c\u63a7\u5236\u7b26 \\n \u3002 FORMAT\u4e2d\u9700\u8981\u5206\u522b\u4e3a\u540e\u9762\u6bcf\u4e2aitem\u6307\u5b9a\u683c\u5f0f\u7b26\u3002 \u683c\u5f0f\u7b26\uff1a\u4e0eitem\u662f\u4e00\u4e00\u5bf9\u5e94\u7684 %s \uff1a\u663e\u793a\u5b57\u7b26\u4e32 %d , %i \uff1a\u663e\u793a\u5341\u8fdb\u5236\u6574\u6570 %f \uff1a\u663e\u793a\u4e3a\u6d6e\u70b9\u6570 %e , %E \uff1a\u663e\u793a\u79d1\u5b66\u8ba1\u6570\u6cd5\u6570\u503c %c \uff1a\u663e\u793a\u5b57\u7b26\u7684ASCII\u7801 %g , %G \uff1a\u4ee5\u79d1\u5b66\u8ba1\u6570\u6cd5\u6216\u6d6e\u70b9\u5f62\u5f0f\u663e\u793a\u6570\u503c %u \uff1a\u65e0\u7b26\u53f7\u6574\u6570 %% \uff1a\u663e\u793a % \u81ea\u8eab \u4fee\u9970\u7b26\uff1a #[.#] \uff1a\u7b2c\u4e00\u4e2a\u6570\u5b57\u63a7\u5236\u663e\u793a\u7684\u5bbd\u5ea6\uff0c\u7b2c\u4e8c\u4e2a#\u8868\u793a\u5c0f\u6570\u70b9\u540e\u7cbe\u5ea6\uff0c\u5982 %3.1f - \uff1a\u5de6\u5bf9\u9f50\uff08\u9ed8\u8ba4\u53f3\u5bf9\u9f50\uff09\uff0c\u5982 %-15s + \uff1a\u663e\u793a\u6570\u503c\u7684\u6b63\u8d1f\u7b26\u53f7\uff0c\u5982 %+d \u793a\u4f8b\uff1a $ awk -F: '{printf \"%s\", $1}' /etc/passwd | head -n3 rootmessagebussystemd-networksystemd-timesyncnobodymailchronypostfixmanlpgamesftpdaemonrpcnscdpolkitdattftpftpsecurebinstatdsshdvagrantpesignsvntester1tester2tester3tester4tester5user0user1user2user3user4user5user6user7user8user9gentoonginxvarnishmysqlwebuseradmin3smithpm1tm1tm2 $ awk -F: '{printf \"%s\\n\", $1}' /etc/passwd | head -n3 root messagebus systemd-network $ awk -F: '{printf \"%20s\\n\", $1}' /etc/passwd | head -n3 root messagebus systemd-network $ awk -F: '{printf \"%-20s\\n\", $1}' /etc/passwd | head -n3 root messagebus systemd-network $ awk -F: '{printf \"%-20s %10d\\n\", $1, $3}' /etc/passwd | head -n3 root 0 messagebus 499 systemd-network 497 $ awk -F: '{printf \"Username: %s\\n\", $1}' /etc/passwd | head -n3 Username: root Username: messagebus Username: systemd-network $ awk -F: '{printf \"Username: %s UID:%d\\n\", $1, $3}' /etc/passwd | head -n3 Username: root UID:0 Username: messagebus UID:499 Username: systemd-network UID:497 $ awk -F: '{printf \"Username: %25s UID:%d\\n\", $1, $3}' /etc/passwd | head -n3 Username: root UID:0 Username: messagebus UID:499 Username: systemd-network UID:497 $ awk -F: '{printf \"Username: %-25s UID:%d\\n\", $1, $3}' /etc/passwd | head -n3 Username: root UID:0 Username: messagebus UID:499 Username: systemd-network UID:497 5.10.9.BEGIN/END \u00b6 \u793a\u4f8b\uff1a awk -F \":\" 'BEGIN{printf \"--------------------------------\\n%-20s|%10s|\\n--------------------------------\\n\", \"Username\", \"UID\"}{printf \"%-20s|%-10d|\\n--------------------------------\\n\", $1, $3}END{print \"end\"}' /etc/passwd -------------------------------- Username | UID | -------------------------------- root | 0 | -------------------------------- daemon | 1 | -------------------------------- bin | 2 | ------------------------------- ... ... -------------------------------- mfe | 997 | -------------------------------- end 5.10.10.\u5e38\u7528\u63a7\u5236\u8bed\u53e5 \u00b6 {statements;...} \u7ec4\u5408\u8bed\u53e5 if(condition){statements;...} if(condition){statements;...} else(statements;...) switch(expression){case VALUE1 or /REGEXP/: statement1; case VALUE2 or /REGEXP2/: statement2;......;default: statementn} while(condition){statements;...} do(statements;...) while{condition} for(expr1;expr2;expr3) {statements;...} break continue exit if-else\u793a\u4f8b\uff1a $ cat < score.txt Name Score Tom 100 Jack 91 Bill 81 Jim 51 EOF $ awk 'NR!=1{score=$2;if($2>=80){print $1, \"Good\"}else if($2>=60){print $1, \"Pass\"}else{print $1, \"failed\"}}' score.txt Tom Good Jack Good Bill Good Jim failed switch\u793a\u4f8b\uff1a $ awk 'NR!=1{switch($2){case 100:print $1,\"good\"; case 60:print $1,\"Pass\"; default:print $1,\"others\"}}' score.txt Tom good Tom Pass Tom others Jack others Bill others Jim others while\u793a\u4f8b\uff1a $ awk 'BEGIN{i=0;sum=0;while(i<=100){sum+=i;i++};print sum}' 5050 do-while\u793a\u4f8b\uff1a $ awk 'BEGIN{i=0;sum=0;do{sum+=i;i++}while(i<101);print sum}' 5050 for\u793a\u4f8b\uff1a $ awk 'BEGIN{i=0;sum=0;for(i=1;i<=100;i++){sum+=i};print sum}' 5050 \u547d\u4ee4\u6548\u7387\u6bd4\u8f83\uff1a $ time ( awk 'BEGIN{i=0;sum=0;while(i<=100000){sum+=i;i++};print sum}' ) 5000050000 real 0m0.028s user 0m0.027s sys 0m0.001s $ time ( seq -s+ 1000000 | bc ) 500000500000 real 0m0.329s user 0m0.240s sys 0m0.094s $ time ( awk 'BEGIN{i=0;sum=0;for(i=1;i<=1000000;i++){sum+=i};print sum}' ) 500000500000 real 0m0.050s user 0m0.046s sys 0m0.004s contine\u793a\u4f8b\uff1a\u4e2d\u65ad\u5f53\u524d\u5faa\u73af\uff0c\u8fdb\u5165\u4e0b\u4e00\u6b21\u5faa\u73af\u3002 $ awk 'BEGIN{i=0;sum=0;for(i=1;i<=100;i++){if(i==50)continue;sum+=i};print sum}' 5000 contine\u793a\u4f8b\uff1a\u4e2d\u65ad\u6574\u4e2a\u5faa\u73af\u3002 $ awk 'BEGIN{i=0;sum=0;for(i=1;i<=100;i++){if(i==50)break;sum+=i};print sum}' 1225 next\u793a\u4f8b\uff1a\u63d0\u524d\u7ed3\u675f\u5bf9\u672c\u884c\u5904\u7406\uff0c\u76f4\u63a5\u8fdb\u5165\u4e0b\u4e00\u884c\u5904\u7406\uff08\u6ce8\uff0cawk\u81ea\u5faa\u73af\uff0c\u5e76\u975e\u524d\u9762\u7684for\u6216while\u5faa\u73af\uff09 $ awk -F: '{if($3%2!=0)next;print $1,$3}' /etc/passwd # \u5947\u6570\u884c\u6253\u5370 root 0 systemd-timesync 496 nobody 65534 chrony 494 games 492 daemon 2 rpc 490 polkitd 488 ftpsecure 486 sshd 484 vagrant 1000 svn 482 tester1 600 tester4 1002 user0 1004 user2 1006 user4 1008 user6 1010 user8 1012 gentoo 1014 varnish 1016 webuser 666 admin3 1020 smith 2002 tm1 2004 $ awk -F: '{if($3%2==0)next;print $1,$3}' /etc/passwd # \u5076\u6570\u884c\u6253\u5370 messagebus 499 systemd-network 497 mail 495 postfix 51 man 13 lp 493 ftp 491 nscd 489 at 25 tftp 487 bin 1 statd 485 pesign 483 tester2 601 tester3 1001 tester5 1003 user1 1005 user3 1007 user5 1009 user7 1011 user9 1013 nginx 1015 mysql 1017 pm1 2003 tm2 2005 5.10.11.\u6570\u7ec4 \u00b6 \u5173\u8054\u6570\u7ec4\u662f\u4e00\u79cd\u6570\u636e\u7ed3\u6784\uff0c\u4e5f\u79f0\u4e3a\u5b57\u5178\u6216\u6620\u5c04\u3002\u4e0e\u4f20\u7edf\u7684\u6570\u7ec4\u4e0d\u540c\uff0c\u5173\u8054\u6570\u7ec4\u7684\u7d22\u5f15\u53ef\u4ee5\u662f\u4efb\u4f55\u7c7b\u578b\u7684\u6570\u636e\uff0c\u4f8b\u5982\u5b57\u7b26\u4e32\u6216\u5bf9\u8c61\uff0c\u800c\u4e0d\u4ec5\u4ec5\u662f\u6574\u6570\u3002 \u63d0\u793a\uff1a \u5728\u8ba1\u7b97\u673a\u7f16\u7a0b\u4e2d\uff0c\u9664\u4e86\u5173\u8054\u6570\u7ec4\uff0c\u8fd8\u6709\u5176\u4ed6\u51e0\u79cd\u5e38\u89c1\u7684\u6570\u7ec4\u7c7b\u578b\uff0c\u5305\u62ec\uff1a \u7ebf\u6027\u6570\u7ec4\uff08\u6216\u79f0\u4e3a\u7d22\u5f15\u6570\u7ec4\uff09\uff1a\u8fd9\u662f\u6700\u5e38\u89c1\u7684\u6570\u7ec4\u7c7b\u578b\uff0c\u5176\u4e2d\u6bcf\u4e2a\u5143\u7d20\u90fd\u6709\u4e00\u4e2a\u6570\u5b57\u7d22\u5f15\uff0c\u53ef\u4ee5\u7528\u6765\u5feb\u901f\u8bbf\u95ee\u6570\u7ec4\u4e2d\u7684\u5143\u7d20\u3002\u4f8b\u5982\uff0c\u5728C\u8bed\u8a00\u4e2d\uff0c\u6570\u7ec4\u7684\u6bcf\u4e2a\u5143\u7d20\u90fd\u53ef\u4ee5\u901a\u8fc7\u6570\u7ec4\u4e0b\u6807\u6765\u8bbf\u95ee\u3002 \u591a\u7ef4\u6570\u7ec4\uff1a\u591a\u7ef4\u6570\u7ec4\u662f\u4e00\u79cd\u6570\u7ec4\uff0c\u5176\u4e2d\u6bcf\u4e2a\u5143\u7d20\u4e5f\u662f\u4e00\u4e2a\u6570\u7ec4\u3002\u5728\u4e8c\u7ef4\u6570\u7ec4\u4e2d\uff0c\u6bcf\u4e2a\u5143\u7d20\u90fd\u6709\u4e24\u4e2a\u7d22\u5f15\uff08\u4f8b\u5982\uff0c\u884c\u548c\u5217\uff09\uff0c\u53ef\u4ee5\u7528\u4e8e\u8bbf\u95ee\u6570\u7ec4\u4e2d\u7684\u5143\u7d20\u3002\u5728\u9ad8\u7ef4\u6570\u7ec4\u4e2d\uff0c\u6bcf\u4e2a\u5143\u7d20\u90fd\u5177\u6709\u66f4\u591a\u7684\u7d22\u5f15\u3002 \u52a8\u6001\u6570\u7ec4\uff1a\u52a8\u6001\u6570\u7ec4\u662f\u4e00\u79cd\u53ef\u4ee5\u52a8\u6001\u8c03\u6574\u5927\u5c0f\u7684\u6570\u7ec4\u3002\u5728\u8bb8\u591a\u7f16\u7a0b\u8bed\u8a00\u4e2d\uff0c\u52a8\u6001\u6570\u7ec4\u53ef\u4ee5\u52a8\u6001\u5206\u914d\u5185\u5b58\uff0c\u4ee5\u4fbf\u5728\u7a0b\u5e8f\u8fd0\u884c\u65f6\u6839\u636e\u9700\u8981\u8c03\u6574\u6570\u7ec4\u7684\u5927\u5c0f\u3002 \u5411\u91cf\uff1a\u5411\u91cf\u662f\u4e00\u79cd\u6570\u7ec4\uff0c\u5176\u4e2d\u6bcf\u4e2a\u5143\u7d20\u90fd\u662f\u76f8\u540c\u7684\u6570\u636e\u7c7b\u578b\u3002\u5411\u91cf\u901a\u5e38\u7528\u4e8e\u6267\u884c\u6570\u5b66\u8fd0\u7b97\u6216\u5904\u7406\u5927\u91cf\u6570\u5b57\u6570\u636e\u3002 \u5728 awk \u4e2d\u4f7f\u7528\u6570\u7ec4\u65f6\uff0c\u901a\u5e38\u4f1a\u5c06\u67d0\u4e9b\u503c\u4e0e\u4e00\u4e2a\u5b57\u7b26\u4e32\u76f8\u5173\u8054\uff0c\u4ee5\u4fbf\u5728\u9700\u8981\u65f6\u53ef\u4ee5\u901a\u8fc7\u8be5\u5b57\u7b26\u4e32\u5feb\u901f\u5730\u68c0\u7d22\u8be5\u503c\u3002 awk \u7684\u6570\u7ec4\u662f\u4e00\u4e2a\u5173\u8054\u6570\u7ec4\uff0c\u5176\u4e2d\u6bcf\u4e2a\u5143\u7d20\u90fd\u7531\u4e00\u4e2a\u552f\u4e00\u7684\u952e\u503c\u548c\u4e00\u4e2a\u5bf9\u5e94\u7684\u503c\u7ec4\u6210\u3002\u952e\u503c\uff08\u6216\u79f0\u4e3a\u7d22\u5f15\uff09\u53ef\u4ee5\u662f\u4efb\u4f55\u7c7b\u578b\u7684\u5b57\u7b26\u4e32\u3002 \u6570\u7ec4\u53ef\u4ee5\u901a\u8fc7\u4ee5\u4e0b\u8bed\u6cd5\u8fdb\u884c\u58f0\u660e\uff1a array_name [ index ] = value \u5176\u4e2d\uff0c array_name \u662f\u6570\u7ec4\u7684\u540d\u79f0\uff0c index \u662f\u5143\u7d20\u7684\u7d22\u5f15\u503c\uff0c value \u662f\u5143\u7d20\u7684\u503c\u3002 \u4f8b\u5982\uff0c\u4ee5\u4e0b\u662f\u4e00\u4e2a\u5305\u542b\u4e09\u4e2a\u5143\u7d20\u7684\u5173\u8054\u6570\u7ec4\u7684\u793a\u4f8b\uff1a array [ \"apple\" ] = 1 array [ \"banana\" ] = 2 array [ \"orange\" ] = 3 \u5728\u4e0a\u9762\u7684\u793a\u4f8b\u4e2d\uff0c array \u662f\u4e00\u4e2a\u5173\u8054\u6570\u7ec4\uff0c\u5176\u7d22\u5f15\u4e3a\u5b57\u7b26\u4e32\u7c7b\u578b\uff0c\u800c\u503c\u4e3a\u6574\u6570\u7c7b\u578b\u3002\u53ef\u4ee5\u4f7f\u7528\u4ee5\u4e0b\u7684\u65b9\u5f0f\u8bbf\u95ee\u8be5\u6570\u7ec4\u4e2d\u7684\u5143\u7d20\uff1a value = array [ \"apple\" ] \u5728\u4e0a\u9762\u7684\u793a\u4f8b\u4e2d\uff0c value \u7684\u503c\u5c06\u4e3a 1 \uff0c\u56e0\u4e3a array[\"apple\"] \u7684\u503c\u4e3a 1 \u3002 \u4ee5\u4e0b\u662f\u7528 awk \u547d\u4ee4\u6765\u521b\u5efa\u4e0a\u9762\u90a3\u4e2a\u5305\u542b\u4e09\u4e2a\u5143\u7d20\u7684\u5173\u8054\u6570\u7ec4\uff0c\u904d\u5386\u5e76\u8f93\u51fa\u6570\u7ec4\u503c\uff1a awk 'BEGIN { array[\"apple\"]=1; array[\"banana\"]=2; array[\"orange\"]=3; for(i in array){print array[i]}}' 3 1 2 \u4e0b\u9762\u4f8b\u5b50\u4e2d\uff0c\u6211\u4eec\u4e92\u6362\u4e86\u6570\u7ec4\u7684\u952e\u548c\u503c\u3002 $ awk 'BEGIN {arr[1]=\"apple\";arr[2]=\"banana\";arr[3]=\"orange\";for(i in arr){print arr[i]}}' apple banana orange \u5728\u4e0a\u9762\u7684\u793a\u4f8b\u4e2d\uff0c i \u662f\u6570\u7ec4 arr \u7684\u7d22\u5f15\u503c\uff0c arr[i] \u662f\u6570\u7ec4\u4e2d\u5bf9\u5e94\u7684\u5143\u7d20\u503c\u3002\u901a\u8fc7\u8fd9\u79cd\u65b9\u5f0f\u53ef\u4ee5\u5faa\u73af\u904d\u5386\u6574\u4e2a\u6570\u7ec4\uff0c\u5e76\u8f93\u51fa\u5176\u4e2d\u7684\u5143\u7d20\u3002 \u9664\u4e86\u4f7f\u7528\u5faa\u73af\u904d\u5386\u6570\u7ec4\u4e4b\u5916\uff0c\u8fd8\u53ef\u4ee5\u4f7f\u7528 length \u51fd\u6570\u83b7\u53d6\u6570\u7ec4\u4e2d\u5143\u7d20\u7684\u6570\u91cf\u3002\u4f8b\u5982\uff1a $ awk 'BEGIN { arr[1]=\"apple\"; arr[2]=\"banana\"; arr[3]=\"orange\"; print length(arr) }' 3 \u4e0a\u9762\u7684\u793a\u4f8b\u5c06\u8f93\u51fa\u6570\u5b573\uff0c\u8868\u793a\u6570\u7ec4 arr \u4e2d\u5305\u542b\u4e09\u4e2a\u5143\u7d20\u3002 \u4e3e\u4f8b\uff1a\u53bb\u91cd\u590d\u8bb0\u5f55\u3002 line \u662f\u6570\u7ec4\u540d\uff0c $0 \u662f awk \u8bfb\u53d6\u7684\u5f53\u524d\u884c\u7684\u5185\u5bb9\u3002 line[$0] \u7b49\u4ef7\u4e8e line[\"a\"] \uff0c line[\"b\"] \uff0c......\u3002 \u6211\u4eec\u770b\u6267\u884c\u8fc7\u7a0b\uff1a awk\u8bfb\u5165\u7b2c1\u884c\uff1b \u6267\u884c line[\"a\"] \uff0c\u503c\u4e3a\u7a7a\uff1b \u6c42\u53cd\uff0c\u5219\u7b2c\u4e00\u884c\u7684\u503c\u53d8\u4e3a true \uff0c\u5373 !line[\"a\"]=true \uff1b \u5f53 !line[\"a\"] \u4e3a true \uff0c\u5219\u6253\u5370\u5f53\u524d\u884c\uff0c\u5373\u8f93\u51fa a \u5230\u5c4f\u5e55\uff1b \u6267\u884c line[\"a\"]++ \uff0c\u6ce8\u610f\u7b2c2\u6b65\u4e2d line[\"a\"] \u7684\u503c\u662f\u7a7a\uff0c\u6267\u884c ++ \u540e\u503c\u53d8\u4e3a 1 \u3002 \u540c\u7406\uff0c\u6211\u4eec\u53ef\u4ee5\u770b\u5230\u7b2c2\uff0c3\uff0c4\u884c\u90fd\u8f93\u51fa\u4e86\u3002 \u5f53\u8bfb\u5165\u7b2c5\u884c\u65f6\uff08\u7b2c\u4e8c\u4e2a a \uff09\uff0c\u6267\u884c line[\"a\"] \uff0c\u503c\u4e3a 1 \uff1b !line[\"a\"]=0 \uff0c\u5373false\uff1b\u5219\u4e0d\u6253\u5370\u5f53\u524d\u884c\uff0c\u5373\u4e0d\u8f93\u51fa a \u5230\u5c4f\u5e55\uff1b\u6267\u884c ++ \u540e\u503c\u53d8\u4e3a 2 \u5f53\u8bfb\u5165\u7b2c8\u884c\u65f6\uff08\u7b2c\u4e09\u4e2a a \uff09\uff0c\u6267\u884c line[\"a\"] \uff0c\u503c\u4e3a 2 \uff1b !line[\"a\"]=0 \uff0c\u5373false\uff1b\u5219\u4e0d\u6253\u5370\u5f53\u524d\u884c\uff0c\u5373\u4e0d\u8f93\u51fa a \u5230\u5c4f\u5e55\uff1b\u6267\u884c ++ \u540e\u503c\u53d8\u4e3a 3 \u4ee5\u6b64\u7c7b\u63a8\uff0c\u8bfb\u5165\u7b2c\u4e8c\u4e2a b \uff0c c \uff0c d \uff0c e \uff0c\u90fd\u4e0d\u4f1a\u518d\u8f93\u51fa\u5230\u5c4f\u5e55\uff0c\u4ece\u800c\u5b9e\u73b0\u53bb\u91cd\u8f93\u51fa\u5230\u529f\u80fd\u3002 $ cat > test << EOF a b c d a c d a b b e EOF $ awk '!line[$0]++' test a b c d e \u4e3e\u4f8b\uff1a\u5224\u65ad\u6570\u7ec4\u7d22\u5f15\u662f\u5426\u5b58\u5728\u3002 \u65b9\u6cd5\uff1a in array \uff0c 0 \u8868\u793a\u4e0d\u5b58\u5728\uff0c 1 \u8868\u793a\u5b58\u5728\u3002 $ awk 'BEGIN{array[\"i\"]=\"x\";array[\"j\"]=\"j\";print \"i\" in array, \"y\" in array}' 1 0 $ awk 'BEGIN{array[\"i\"]=\"x\";array[\"j\"]=\"j\";if(\"i\" in array){print \"exits!\"}else{print \"not exists!\"}}' exits! $ awk 'BEGIN{array[\"i\"]=\"x\";array[\"j\"]=\"j\";if(\"abc\" in array){print \"exits!\"}else{print \"not exists!\"}}' not exists! \u4e3e\u4f8b\uff1a\u904d\u5386\u6570\u7ec4\u4e2d\u6bcf\u4e2a\u5143\u7d20\u3002 \u65b9\u6cd5\uff1a for(your_var in array){your_for_body} \uff0c\u6ce8\u610f\uff0cyour_var\u4f1a\u904d\u5386\u6bcf\u4e2a\u7d22\u5f15\u3002 $ awk 'BEGIN{weekday[\"mon\"]=\"Monday\";weekday[\"tue\"]=\"Tuesday\";for(i in weekday){print i,weekday[i]}}' tue Tuesday mon Monday $ awk 'BEGIN{weekday[\"mon\"]=\"Monday\";weekday[\"tue\"]=\"Tuesday\";for(i in weekday){print i\": \"weekday[i]}}' tue: Tuesday mon: Monday \u6ce8\u610f\u4e0b\u9762\u7684\u6362\u884c\u5199\u6cd5\uff0c\u4e0d\u9700\u8981\u53cd\u659c\u6760 \\ \u3002 $ awk 'BEGIN{ arr[\"x\"]=\"welcome\" arr[\"y\"]=\"to\" arr[\"z\"]=\"Shanghai\" for (i in arr) { print i, arr[i] } }' x welcome y to z Shanghai \u793a\u4f8b\uff1a\u683c\u5f0f\u5316\u8f93\u51fa\u7528\u6237\u540d\u548c\u5bc6\u7801\u3002 $ awk -F: '{user[$1]=$3}END{for (i in user){print \"Username: \" i, \"UID: \" user[i]}}' /etc/passwd Username: sshd UID: 476 Username: rpc UID: 482 Username: tftp UID: 488 Username: usbmux UID: 480 Username: srvGeoClue UID: 487 ...... \u793a\u4f8b\uff1a\u663e\u793a\u4e3b\u673a\u8fde\u63a5\u72b6\u6001\u51fa\u73b0\u7684\u6b21\u6570\u3002 # \u4f20\u7edf\u65b9\u6cd5 $ ss -ant | awk 'NR>=2{print $1}' | sort | uniq -c $ ss -ant | awk 'NR!=1{print $1}' | sort | uniq -c 1 ESTAB 6 LISTEN # \u4f7f\u7528awk\u6570\u7ec4 $ ss -ant | awk 'NR>=2{state[$1]++}END{for(i in state){print state[i], i}}' $ ss -ant | awk 'NR!=1{state[$1]++}END{for(i in state){print state[i], i}}' 6 LISTEN 1 ESTAB 5.10.12.awk\u51fd\u6570 \u00b6 \u53c2\u8003\uff1a awk \u51fd\u6570\u5b98\u7f51 5.10.12.1.\u5185\u7f6e\u51fd\u6570 \u00b6 \u5728 awk \u4e2d\uff0c\u51fd\u6570\u662f\u4e00\u79cd\u7528\u4e8e\u6267\u884c\u7279\u5b9a\u4efb\u52a1\u6216\u8ba1\u7b97\u7279\u5b9a\u503c\u7684\u53ef\u91cd\u7528\u4ee3\u7801\u5757\u3002 awk \u63d0\u4f9b\u4e86\u8bb8\u591a\u5185\u7f6e\u51fd\u6570\uff0c\u53ef\u4ee5\u7528\u4e8e\u5904\u7406\u6587\u672c\u6570\u636e\u3001\u6267\u884c\u6570\u5b66\u8fd0\u7b97\u3001\u64cd\u4f5c\u5b57\u7b26\u4e32\u7b49\u3002 \u4ee5\u4e0b\u662f\u4e00\u4e9b\u5e38\u7528\u7684awk\u51fd\u6570\u793a\u4f8b\uff1a length(string) \uff1a\u8fd4\u56de\u5b57\u7b26\u4e32\u7684\u957f\u5ea6\u3002 $ awk 'BEGIN { str = \"Hello World\"; len = length(str); print len }' 11 $ cut -d: -f1 /etc/passwd | awk '{print length($1)}' | head -3 4 10 15 substr(string, start, length) \uff1a\u4ece\u6307\u5b9a\u4f4d\u7f6e\u5f00\u59cb\u63d0\u53d6\u5b57\u7b26\u4e32\u7684\u5b50\u4e32\u3002 $ awk 'BEGIN { str = \"Hello World\"; substring = substr(str, 7, 5); print substring }' World sub(regexp, replacement [, target]) \uff1a\u4ece\u5b57\u7b26\u4e32target\u4e2d\u641c\u7d22\u5339\u914dregexp\u7684\u5185\u5bb9\uff0c\u5e76\u628a\u7b2c\u4e00\u4e2a\u5339\u914d\u7684\u5185\u5bb9\u66ff\u6362\u4e3areplacement\u3002\u61d2\u60f0\u6a21\u5f0f\u3002 \u6ce8\u610f\uff1a sub() \u51fd\u6570\u5728\u539f\u59cb\u5b57\u7b26\u4e32\u4e0a\u8fdb\u884c\u66ff\u6362\u64cd\u4f5c\uff0c\u5e76\u8fd4\u56de\u66ff\u6362\u7684\u6b21\u6570\u3002 # \u5728\u539f\u59cb\u5b57\u7b26\u4e32\u4e2d\uff0c\u7b2c\u4e00\u4e2a\u5339\u914d\u5230\u7684\"at\"\u88ab\u66ff\u6362\u4e3a\"ith\"\uff0c\u56e0\u6b64\u8f93\u51fa\u7ed3\u679c\u4e2d\u7684\"at\"\u53d8\u4e3a\"ith\"\uff0c\u5176\u4ed6\u5730\u65b9\u7684\"at\"\u4fdd\u6301\u4e0d\u53d8 $ awk 'BEGIN { str = \"water, water, everywhere\"; sub(/at/, \"ith\", str); print str }' wither, water, everywhere # \u8fd4\u56de\u5339\u914d\u6b21\u6570 $ awk 'BEGIN { str = \"water, water, everywhere\"; str_new = sub(/at/, \"ith\", str); print str_new }' 1 $ echo \"2023:15:35 08:15:26\" | awk 'sub(/:/, \"-\", $0)' 2023 -15:35 08 :15:26 $ echo \"2023:15:35 08:15:26\" | awk 'sub(/:/, \"-\", $1)' 2023 -15:35 08 :15:26 $ echo \"2023:15:35 08:15:26\" | awk 'sub(/:/, \"-\", $2)' 2023 :15:35 08 -15:26 gsub(regexp, replacement [, target])\uff1a\u4ece\u5b57\u7b26\u4e32target\u4e2d\u641c\u7d22\u5339\u914dregexp\u7684\u5185\u5bb9\uff0c\u5e76\u628a\u5168\u90e8\u5339\u914d\u7684\u5185\u5bb9\u66ff\u6362\u4e3areplacement\u3002\u8d2a\u5a6a\u6a21\u5f0f\u3002 # \u5728\u539f\u59cb\u5b57\u7b26\u4e32\u4e2d\uff0c\u5c06\u6240\u6709\u5339\u914d\u5230\u7684\"at\"\u88ab\u66ff\u6362\u4e3a\"ith\" $ awk 'BEGIN { str = \"water, water, everywhere\"; gsub(/at/, \"ith\", str); print str }' wither, wither, everywhere # \u8fd4\u56de\u5339\u914d\u6b21\u6570 $ awk 'BEGIN { str = \"water, water, everywhere\"; str_new = gsub(/at/, \"ith\", str); print str_new }' 2 $ echo \"2023:15:35 08:15:26\" | awk 'gsub(/:/, \"-\", $0)' 2023 -15-35 08 -15-26 $ echo \"2023:15:35 08:15:26\" | awk 'gsub(/:/, \"-\", $1)' 2023 -15-35 08 :15:26 $ echo \"2023:15:35 08:15:26\" | awk 'gsub(/:/, \"-\", $2)' 2023 :15:35 08 -15-26 split(string, array, delimiter) \uff1a\u5c06\u5b57\u7b26\u4e32string\u6309\u6307\u5b9a\u5206\u9694\u7b26delimiter\u62c6\u5206\u6210\u6570\u7ec4array\u7684\u5143\u7d20\u3002 \u6ce8\u610f\uff1a\u7b2c\u4e00\u4e2a\u7d22\u5f15\u503c\u4e3a 1 \uff0c\u7b2c\u4e8c\u4e2a\u7d22\u5f15\u503c\u4e3a 2 . $ awk 'BEGIN { str = \"apple,banana,orange\"; split(str, fruits, \",\"); print fruits[2] }' banana $ head -n2 /etc/passwd | awk '{split($0, array, \":\")}END{print array[1]}' messagebus $ head -n2 /etc/passwd | awk '{split($0, array, \":\")}END{print array[2]}' x $ head -n2 /etc/passwd | awk '{split($0, array, \":\")}END{print array[3]}' 499 $ head -n2 /etc/passwd | awk '{split($0, array, \":\")}END{print array[7]}' /usr/bin/false index(string, search) \uff1a\u5728\u5b57\u7b26\u4e32\u4e2d\u67e5\u627e\u6307\u5b9a\u5b50\u4e32\u7684\u4f4d\u7f6e\u3002 $ awk 'BEGIN { str = \"Hello World\"; pos = index(str, \"World\"); print pos }' 7 sprintf(format, expression) \uff1a\u6839\u636e\u6307\u5b9a\u7684\u683c\u5f0f\u5c06\u8868\u8fbe\u5f0f\u8f6c\u6362\u4e3a\u5b57\u7b26\u4e32\u3002 $ awk 'BEGIN { num = 3.14159; str = sprintf(\"%.2f\", num); print str }' 3 .14 rand() \uff1a\u8fd4\u56de\u4e00\u4e2a\u968f\u673a\u6570\uff0c\u503c\u5728 0 \u548c 1 \u4e4b\u95f4\u5747\u5300\u5206\u5e03\u3002\u8fd9\u4e2a\u503c\u53ef\u4ee5\u662f 0 \uff0c\u4f46\u4e0d\u4f1a\u662f 1 \u3002\u4ece\u4e0b\u9762\u7684\u4f8b\u5b50\u53ef\u4ee5\u770b\u51fa\uff0c\u8fd0\u884c\u7ed3\u679c\u90fd\u662f\u4e00\u6837\u7684\uff0c\u6240\u4ee5\u4ea7\u751f\u968f\u673a\u6570\u7684\u79cd\u5b50\u662f\u4e00\u6837\u7684\u3002 $ awk 'BEGIN{print rand()}' 0 .924046 $ awk 'BEGIN{print rand()}' 0 .924046 $ awk 'BEGIN{print rand()}' 0 .924046 srand() \uff1a\u914d\u5408 rand() \u51fd\u6570\uff0c\u751f\u6210\u968f\u673a\u6570\u79cd\u5b50\u3002 $ awk 'BEGIN{srand();print rand()}' 0 .112006 $ awk 'BEGIN{srand();print rand()}' 0 .663431 $ awk 'BEGIN{srand();print rand()}' 0 .541305 int() \uff1a\u8fd4\u56de\u6574\u6570\u3002 $ awk 'BEGIN{srand();print int(rand()*100)}' 84 $ awk 'BEGIN{srand();print int(rand()*100)}' 66 $ awk 'BEGIN{srand();print int(rand()*100)}' 8 system(command) \uff1a\u6267\u884ccommand\u547d\u4ee4\uff08\u53ef\u4ee5\u662f\u4efb\u4f55\u6709\u6548\u7684Shell\u547d\u4ee4\uff09\u5e76\u8fd4\u56de\u547d\u4ee4\u7684\u9000\u51fa\u72b6\u6001\u7801\u3002\u5141\u8bb8\u5728 awk \u811a\u672c\u4e2d\u6267\u884c\u5916\u90e8\u547d\u4ee4\uff0c\u5e76\u83b7\u53d6\u547d\u4ee4\u6267\u884c\u7684\u7ed3\u679c\u3002 # \u6267\u884cls -l\u547d\u4ee4\uff0c\u5e76\u5c06\u547d\u4ee4\u7684\u9000\u51fa\u72b6\u6001\u7801\u5b58\u50a8\u5728status\u53d8\u91cf\u4e2d\uff0c\u5e76\u6253\u5370status\u53d8\u91cf\u7684\u503c $ awk 'BEGIN { status = system(\"ls -l\"); print \"Exit status:\", status }' total 0 drwxr-xr-x 1 vagrant users 70 Jan 2 15 :54 Desktop drwxr-xr-x 1 vagrant users 0 Jan 2 15 :54 Documents drwxr-xr-x 1 vagrant users 0 Jan 2 15 :54 Downloads drwxr-xr-x 1 vagrant users 0 Jan 2 15 :54 Music drwxr-xr-x 1 vagrant users 0 Jan 2 15 :54 Pictures drwxr-xr-x 1 vagrant users 0 Jan 2 15 :54 Public drwxr-xr-x 1 vagrant users 0 Jan 2 15 :54 Templates drwxr-xr-x 1 vagrant users 0 Jan 2 15 :54 Videos drwxr-xr-x 1 vagrant users 0 Mar 15 2022 bin Exit status: 0 $ awk 'BEGIN{score=100; system(\"echo your score is \" score)}' your score is 100 systime() \uff1a\u5f53\u524d\u65f6\u95f4\u52301970\u5e741\u67081\u65e5\u5230\u79d2\u6570 $ awk 'BEGIN{print systime()}' 1684158395 strftime(format, timestamp) \uff1a\u5c06\u65f6\u95f4\u6233timestamp\u8f6c\u6362\u4e3a\u6307\u5b9a\u683c\u5f0fformat\u7684\u65e5\u671f\u548c\u65f6\u95f4\u5b57\u7b26\u4e32\u3002timestamp\u901a\u5e38\u662f\u4e00\u4e2a\u4ee5\u79d2\u4e3a\u5355\u4f4d\u8868\u793a\u7684\u6574\u6570\u3002 \u5e38\u89c1\u7684\u683c\u5f0f\u5316\u5b57\u7b26\u4e32\u9009\u9879\uff1a %Y \uff1a\u56db\u4f4d\u6570\u7684\u5e74\u4efd\uff08\u4f8b\u5982\uff1a2023\uff09 %m \uff1a\u4e24\u4f4d\u6570\u7684\u6708\u4efd\uff0801-12\uff09 %d \uff1a\u4e24\u4f4d\u6570\u7684\u65e5\u671f\uff0801-31\uff09 %H \uff1a\u4e24\u4f4d\u6570\u7684\u5c0f\u65f6\uff0800-23\uff09 %M \uff1a\u4e24\u4f4d\u6570\u7684\u5206\u949f\uff0800-59\uff09 %S \uff1a\u4e24\u4f4d\u6570\u7684\u79d2\uff0800-60\uff09 %Z \uff1a\u65f6\u533a\u540d\u79f0\uff08\u4f8b\u5982\uff1aGMT\uff09 # \u5c06\u5f53\u524d\u65f6\u95f4\u6233\u8f6c\u6362\u4e3a\u683c\u5f0f\u4e3a\"YYYY-MM-DD HH:MM:SS\"\u7684\u65e5\u671f\u548c\u65f6\u95f4\u5b57\u7b26\u4e32 $ awk 'BEGIN { timestamp = systime(); str = strftime(\"%Y-%m-%d %H:%M:%S\", timestamp); print str }' 2023 -05-15 22 :01:35 # \u5c06\u5f53\u524d\u65f6\u95f4\u6233\u7684\u524d\u4e00\u5c0f\u65f6\uff083600\u79d2\uff09\u8f6c\u6362\u4e3a\u683c\u5f0f\u4e3a\"YYYY-MM-DD HH:MM:SS\"\u7684\u65e5\u671f\u548c\u65f6\u95f4\u5b57\u7b26\u4e32 $ awk 'BEGIN { timestamp = systime()-3600; str = strftime(\"%Y-%m-%d %H:%M:%S\", timestamp); print str }' 2023 -05-15 21 :01:43 5.10.12.2.\u81ea\u5b9a\u4e49\u51fd\u6570 \u00b6 \u4e3e\u4f8b\uff1a $ cat > func.awk << EOF function max(x,y){ x>y?var=x:var=y return var } BEGIN{print max(a,b)} EOF $ awk -v a = 30 -v b = 20 -f func.awk 30 \u4e3e\u4f8b\uff1a \u5728\u4e0b\u9762\u7684\u4f8b\u5b50\u4e2d\uff0c\u6211\u4eec\u5b9a\u4e49\u4e86\u4e00\u4e2a\u540d\u4e3a square() \u7684\u81ea\u5b9a\u4e49\u51fd\u6570\uff0c\u5b83\u63a5\u53d7\u4e00\u4e2a\u53c2\u6570 x \uff0c\u5e76\u8fd4\u56de x \u7684\u5e73\u65b9\u3002\u7136\u540e\uff0c\u5728\u4e3b\u4ee3\u7801\u5757\u4e2d\uff0c\u6211\u4eec\u58f0\u660e\u4e86\u4e00\u4e2a\u53d8\u91cf num \u5e76\u8d4b\u503c\u4e3a 5 \u3002\u63a5\u4e0b\u6765\uff0c\u6211\u4eec\u8c03\u7528\u4e86\u81ea\u5b9a\u4e49\u51fd\u6570 square() \uff0c\u4f20\u9012 num \u4f5c\u4e3a\u53c2\u6570\uff0c\u5e76\u5c06\u8fd4\u56de\u503c\u5b58\u50a8\u5728\u53d8\u91cf result \u4e2d\u3002\u6700\u540e\uff0c\u6211\u4eec\u6253\u5370\u51fa result \u7684\u503c\u3002 $ cat > func.awk << EOF # \u81ea\u5b9a\u4e49\u51fd\u6570\uff1a\u8ba1\u7b97\u5e73\u65b9 function square(x) { return x * x; } # \u4f7f\u7528\u81ea\u5b9a\u4e49\u51fd\u6570 { num = 5; result = square(num); print \"\u5e73\u65b9\u7ed3\u679c\uff1a\" result; } EOF $ awk -f func.awk \u5e73\u65b9\u7ed3\u679c\uff1a25 \u4e3e\u4f8b\uff1a $ cat > func.awk << EOF # \u81ea\u5b9a\u4e49\u51fd\u6570\uff1a\u8ba1\u7b97\u6570\u7ec4\u5e73\u5747\u503c function calculateAverage(arr, size) { sum = 0; for (i = 1; i <= size; i++) { sum += arr[i]; } return sum / size; } # \u4f7f\u7528\u81ea\u5b9a\u4e49\u51fd\u6570 { # \u5b9a\u4e49\u6570\u7ec4 numbers[1] = 10; numbers[2] = 20; numbers[3] = 30; numbers[4] = 40; numbers[5] = 50; # \u8ba1\u7b97\u6570\u7ec4\u7684\u5e73\u5747\u503c size = 5; average = calculateAverage(numbers, size); print \"\u6570\u7ec4\u7684\u5e73\u5747\u503c\uff1a\" average; } EOF $ awk -f func.awk \u6570\u7ec4\u7684\u5e73\u5747\u503c\uff1a30 5.10.12.3.awk\u811a\u672c \u00b6 \u4e3e\u4f8b\uff1a # \u6ce8\u610f\u8f6c\u4e49 $ cat > passwd.awk << EOF {if(\\$3>=1000)print \\$1,\\$3} EOF $ awk -F: -f passwd.awk /etc/passwd nobody 65534 vagrant 1000 \u4e0a\u9762\u4f8b\u5b50\u4e5f\u53ef\u4ee5\u5199\u6210\u5982\u4e0b\u811a\u6b65\u683c\u5f0f\u3002 $ cat > test.awk << EOF #!/bin/awk -f # This is an awk script {if(\\$3>=1000)print \\$1,\\$3} EOF $ chmod +x test.awk $ ./test.awk -F: /etc/passwd nobody 65534 vagrant 1000 \u5411awk\u811a\u672c\u4f20\u9012\u53c2\u6570\uff1a \u683c\u5f0f\uff1a awkfile var=value var2=value2 ... inputfile \u8bf4\u660e\uff1a \u4e0a\u9762\u683c\u5f0f\u53d8\u91cf\u5728 BEGIN \u8fc7\u7a0b\u4e2d\u4e0d\u53ef\u7528\uff0c\u76f4\u5230\u9996\u884c\u8f93\u5165\u5b8c\u6210\u4ee5\u540e\uff0c\u53d8\u91cf\u624d\u53ef\u7528\u3002 \u53ef\u4ee5\u901a\u8fc7 -v \u53c2\u6570\uff0c\u8ba9 awk \u5728\u6267\u884c BEGIN \u4e4b\u524d\u5f97\u5230\u53d8\u91cf\u3002 \u547d\u4ee4\u884c\u4e2d\u6bcf\u4e00\u4e2a\u6307\u5b9a\u7684\u53d8\u91cf\u90fd\u9700\u8981\u4e00\u4e2a -v \u53c2\u6570\u3002 \u4e3e\u4f8b\uff1a # x=100\u5728BEGIN{print x}\u533a\u6bb5\u53ef\u7528 $ awk -v x = 100 'BEGIN{print x}{print x+100}' /etc/hosts 100 200 200 200 200 200 200 200 200 200 200 200 200 200 200 200 200 200 200 200 200 200 200 200 # \u4e0d\u52a0-v\u5219x=100\u5728BEGIN{print x}\u533a\u6bb5\u4e0d\u53ef\u7528 $ awk x = 100 'BEGIN{print x}{print x+100}' /etc/hosts awk: fatal: cannot open file ` BEGIN { print x }{ print x+100 } ' for reading (No such file or directory) # \u4fee\u6b63\u4e0a\u9762\u7684\u9519\u8bef\uff0c\u5c06x=100\u653e\u5728\u540e\u9762\uff0c\u56e0\u4e3a\u6ca1\u6709-v\uff0c\u6240\u4ee5x=100\u5728BEGIN{print x}\u533a\u6bb5\u4e0d\u53ef\u7528\uff0c\u7b2c\u4e00\u884c\u8f93\u51fa\u7a7a\u767d $ awk ' BEGIN { print x }{ print x+100 } ' x = 100 /etc/hosts 200 200 200 200 200 200 200 200 200 200 200 200 200 200 200 200 200 200 200 200 200 200 200 5.11.\u5c0f\u7ec3\u4e60 \u00b6 \u663e\u793a /proc/meminfo \u6587\u4ef6\u4e2d\u4ee5\u5927\u5c0fs\u5f00\u5934\u7684\u884c\uff0c\u8981\u6c42\u4f7f\u7528\u4e24\u79cd\u65b9\u6cd5\u3002 cat /proc/meminfo | grep -i \"^s\" cat /proc/meminfo | grep \"^[sS]\" \u663e\u793a /etc/passwd \u6587\u4ef6\u4e2d\u4e0d\u4ee5 /bin/bash \u7ed3\u5c3e\u7684\u884c\u3002 grep -v \"/bin/bash $ \" /etc/passwd \u663e\u793a\u7528\u6237 rpc \u9ed8\u8ba4\u7684shell\u7a0b\u5e8f\u3002 $ grep \"rpc\" /etc/passwd | cut -d \":\" -f 7 /sbin/nologin \u627e\u51fa /etc/passwd \u4e2d\u7684\u4e24\u4f4d\u6216\u4e09\u4f4d\u6570\u3002 grep -Eo \"[:digit:]{2,3}\" /etc/passwd grep -Eo \"[0-9]{2,3}\" /etc/passwd \u8fd9\u91cc\u7528\u5230\u4e86 {} \uff0c\u5c5e\u4e8e\u6269\u5c55\u6b63\u5219\u7b26\u53f7\uff0c\u6240\u4ee5\u8981\u7528 -E \u3002 \u663e\u793aRocky 9\u7684 /etc/grub2.cfg \u6587\u4ef6\u4e2d\uff0c\u81f3\u5c11\u4ee5\u4e00\u4e2a\u7a7a\u767d\u5b57\u7b26\u5f00\u5934\u7684\u4e14\u540e\u9762\u6709\u975e\u7a7a\u767d\u5b57\u7b26\u7684\u884c\u3002\uff08\u6ce8\uff1a /etc/grub2.cfg \u5728openSUSE\u548cUbuntu\u4e2d\u6ca1\u6709\uff09 # \u4e0d\u542b\u9996\u5b57\u7b26\u4e3atab $ sudo grep \"^ \" /etc/grub2.cfg # \u5305\u542b\u9996\u5b57\u7b26\u4e3atab $ sudo grep \"^[[:space:]]\" /etc/grub2.cfg \u627e\u51fa netstat -tan \u547d\u4ee4\u7ed3\u679c\u4e2d\u4ee5 LISTEN \u540e\u8ddf\u4efb\u610f\u591a\u4e2a\u7a7a\u767d\u5b57\u7b26\u7ed3\u5c3e\u7684\u884c\u3002 netstat -tan | grep -E \"LISTEN[[:space:]]+\" \u663e\u793aRocky 9\u4e0a\u6240\u6709UID\u5c0f\u4e8e1000\u4ee5\u5185\u7684\u7528\u6237\u540d\u548cUID\u3002 cat /etc/passwd | cut -d \":\" -f 1 ,3 | grep -E \"\\:[0-9]{1,3} $ \" grep -E \"\\:[0-9]{1,3}\\:[0-9]{1,}\" /etc/passwd | cut -d \":\" -f 1 ,3 \u5728Rocky 9\u4e0a\u663e\u793a\u6587\u4ef6 /etc/passwd \u7528\u6237\u540d\u548cshell\u540c\u540d\u7684\u884c\u3002 $ grep -E \"^([[:alnum:]]+\\b).*\\1 $ \" /etc/passwd sync:x:5:0:sync:/sbin:/bin/sync shutdown:x:6:0:shutdown:/sbin:/sbin/shutdown halt:x:7:0:halt:/sbin:/sbin/halt \u5229\u7528 df \u548c grep \uff0c\u53d6\u51fa\u78c1\u76d8\u5404\u5206\u533a\u5229\u7528\u7387,\u5e76\u4ece\u5927\u5230\u5c0f\u6392\u5e8f\u3002 $ df | tr -s \" \" | cut -d \" \" -f 1 ,5 | sort -n -t \" \" -k 2 devtmpfs 0 % Filesystem Use% tmpfs 0 % tmpfs 0 % /dev/mapper/rl-home 1 % tmpfs 2 % /dev/mapper/rl-root 5 % /dev/nvme0n1p1 23 % \u663e\u793a\u4e09\u4e2a\u7528\u6237 root \uff0c sync \uff0c bin \u7684UID\u548c\u9ed8\u8ba4shell\u3002 $ grep \"^root:\\|^sync:\\|^bin:\" /etc/passwd | cut -d \":\" -f 1 ,7 root:/bin/bash bin:/usr/sbin/nologin \u4f7f\u7528 egrep \u53d6\u51fa /etc/default-1/text_2/local.3/grub \u4e2d\u5176\u57fa\u540d\u548c\u76ee\u5f55\u540d\u3002 # \u57fa\u540d $ echo \"/etc/default-1/text_2/local.3/grub\" | egrep -io \"[[:alpha:]]+ $ \" grub # \u76ee\u5f55\u540d $ echo \"/etc/default-1/text_2/local.3/grub\" | egrep -io \"/([[:alpha:]]+.|_?[[:alpha:]]|[[:alnum:]]+/){7}\" /etc/default-1/text_2/local.3/ \u7edf\u8ba1 last \u547d\u4ee4\u4e2d\u4ee5 vagrant \u767b\u5f55\u7684\u6bcf\u4e2a\u4e3b\u673aIP\u5730\u5740\u767b\u5f55\u6b21\u6570\u3002 $ last | grep vagrant | tr -s \" \" | cut -d \" \" -f 3 | grep -E \"([0-9]{1,3}\\.){1,3}[0-9]{1,3}\" | sort -n | uniq -c 24 192 .168.10.107 38 192 .168.10.109 17 192 .168.10.201 6 192 .168.10.210 2 192 .168.10.220 \u5229\u7528\u6269\u5c55\u6b63\u5219\u8868\u8fbe\u5f0f\u5206\u522b\u8868\u793a0-9\u300110-99\u3001100-199\u3001200-249\u3001250-255\u3002 [ 0 -9 ] | [ 0 -9 ]{ 2 } | 1 [ 0 -9 ]{ 2 } | 2 [ 0 -4 ][ 0 -9 ] | 25 [ 0 -5 ] \u663e\u793a ifconfig \u547d\u4ee4\u7ed3\u679c\u4e2d\u6240\u6709IPv4\u5730\u5740\u3002 $ ifconfig | grep -Eo \"([0-9]{1,3}\\.){3}[0-9]{1,3}\" | grep -v \"^255\" 192 .168.10.210 192 .168.10.255 127 .0.0.1 \u663e\u793a ip addr \u547d\u4ee4\u7ed3\u679c\u4e2d\u6240\u6709IPv4\u5730\u5740\u3002 $ ip addr show eth0 | grep inet | grep eth0 | tr -s \" \" | cut -d \" \" -f 3 | cut -d \"/\" -f 1 192 .168.10.210 $ ip addr show | grep -Eo \"([0-9]{1,3}\\.){3}[0-9]{1,3}\" | grep -v \"^255\" 127 .0.0.1 192 .168.10.210 192 .168.10.255 \u5c06\u6b64\u5b57\u7b26\u4e32Welcome to the linux world\u4e2d\u7684\u6bcf\u4e2a\u5b57\u7b26\u53bb\u91cd\u5e76\u6392\u5e8f\uff0c\u91cd\u590d\u6b21\u6570\u591a\u7684\u6392\u5230\u524d\u9762\u3002 $ echo \"Welcome to the linux world\" | grep -o [[ :alpha: ]] | sort | uniq -c | sort -nr 3 o 3 l 3 e 2 t 1 x 1 W 1 w 1 u 1 r 1 n 1 m 1 i 1 h 1 d 1 c \u5220\u9664 /etc/default/grub \u6587\u4ef6\u4e2d\u6240\u6709\u4ee5\u7a7a\u767d\u5f00\u5934\u7684\u884c\u884c\u9996\u7684\u7a7a\u767d\u5b57\u7b26\u3002 sed '/^$/d' /etc/default/grub \u5220\u9664 /etc/default/grub \u6587\u4ef6\u4e2d\u6240\u6709\u4ee5 # \u5f00\u5934\uff0c\u540e\u9762\u81f3\u5c11\u8ddf\u4e00\u4e2a\u7a7a\u767d\u5b57\u7b26\u7684\u884c\u7684\u884c\u9996\u7684 # \u548c\u7a7a\u767d\u5b57\u7b26\u3002 sed -r '/#[[:space:]]+/d;/#/d' /etc/default/grub \u4e0a\u9762\u8f93\u51fa\u7ed3\u679c\u4e2d\u5305\u542b\u7a7a\u767d\u884c\u3002 \u82e5\u8f93\u51fa\u4e2d\u5220\u9664\u7a7a\u767d\u884c\uff0c\u5219\uff1a sed -r '/#[[:space:]]+/d;/#/d;/^$/d' /etc/default/grub \u5728 /etc/fstab \u6bcf\u4e00\u884c\u884c\u9996\u589e\u52a0 # \u53f7\u3002 sed -r 's/(.*)/#&/' /etc/fstab \u5728 /etc/fstab \u6587\u4ef6\u4e2d\u4e0d\u4ee5 # \u5f00\u5934\u7684\u884c\u7684\u884c\u9996\u589e\u52a0 # \u53f7\uff08\u5305\u62ec\u7a7a\u884c\uff09\u3002 sed -r 's/^[^#].*/#&/' -r 's/^$/#/' /etc/default/grub \u901a\u8fc7\u547d\u4ee4 rpm -qa --last |awk -F ' ' '{print $1}' \u5f97\u5230\u6700\u65b0\u5b89\u88c5\u7684\u5305\u5217\u8868\u3002\u7edf\u8ba1\u6240\u6709 x86_64 \u7ed3\u5c3e\u7684\u5b89\u88c5\u5305\u540d\u4ee5 . \u5206\u9694\u5012\u6570\u7b2c\u4e8c\u4e2a\u5b57\u6bb5\u7684\u91cd\u590d\u6b21\u6570\u3002 $ rpm -qa --last | awk -F ' ' '{print $1}' | sed -nr '/x86_64$/s@.*\\.(.*)\\.x86_64@\\1@p' | sort -r | uniq -c 75 el9_0 563 el9 3 7 1 5 2 4 2 3 10 2 29 1 \u5728openSUSE\u4e2d\u7edf\u8ba1 /etc/rc.status \u6587\u4ef6\u4e2d\u6bcf\u4e2a\u5355\u8bcd\u7684\u51fa\u73b0\u6b21\u6570\uff0c\u5e76\u6392\u5e8f\uff08\u7528grep\u548csed\u4e24\u79cd\u65b9\u6cd5\u5206\u522b\u5b9e\u73b0\uff09\u3002 grep -Eo \"[a-zA-Z]+\" /etc/rc.status | sort | uniq -c cat /etc/rc.status | sed -r 's/[^[:alpha:]]+/\\n/g' | sed '/^$/d' | sort | uniq -c | sort -nr \u5c06\u6587\u672c\u6587\u4ef6\u7684n\u548cn+1\u884c\u5408\u5e76\u4e3a\u4e00\u884c\uff0cn\u4e3a\u5947\u6570\u884c\u3002 $ cat < sed.txt 1aa 2bb 3cc 4dd 5ee 6ff 7gg EOF $ sed -n 'N;s/\\n//p' sed.txt 1aa2bb 3cc4dd 5ee6ff $ sed 'N;s/\\n//' sed.txt 1aa2bb 3cc4dd 5ee6ff 7gg \u5bf9\u4e00\u4e32\u6570\u5b57\u8fdb\u884c\u6c42\u548c\u3002 $ cat < number.txt 1 2 3 4 5 6 EOF $ tr ' ' + < number.txt | bc 21 $ sum = 0 ; for i in ` cat number.txt ` ; do let sum += i ; done ; echo $sum 21 $ awk '{sum=0;for(i=1;i<=NF;i++){sum+=i};print sum}' number.txt 21 \u53d6\u51fa\u5b57\u7b26\u4e32\u4e2d\u7684\u6570\u5b57\u3002 $ echo 'kdajl;3k8jd33la5kj23f90ld02sakjflakjdslf' | awk -F \"\" ' { for(i=1;i<=NF;i++) { if($i ~ /[0-9]/) { str=(str $i) } }; print str }' 38335239002 host.log \u6587\u4ef6\u5185\u5bb9\u5982\u4e0b\uff0c\u63d0\u53d6 .edu.cn \u524d\u9762\u7684\u4e3b\u673a\u540d\uff0c\u5e76\u56de\u5199\u5230\u8be5\u6587\u4ef6\u4e2d\u3002 $ cat > host.log << EOF 1 www.edu.cn 2 blog.edu.cn 3 learning.edu.cn 4 java.edu.cn 5 nodejs.edu.cn 6 k8s.eud.cn 7 linux.edu.cn 8 python.edu.cn 9 learning.edu.cn 10 java.edu.cn 11 nodejs.edu.cn 12 www.edu.cn EOF # \u5bf9\u6bd4 $ awk -F '[ .]' '{print $1}' host.log 1 2 3 4 5 6 7 8 9 10 11 12 $ awk -F '[ .]' '{print $2}' host.log www blog learning java nodejs k8s linux python learning java nodejs www # \u4ee5\u7a7a\u683c\u6216\u8005.\u4e3a\u5206\u9694\u7b26\uff0c\u6253\u5370\u7b2c\u4e8c\u5217\uff08\u4e3b\u673a\u540d\uff09\uff0c\u8ffd\u52a0\u5199\u5165\u539f\u6587\u4ef6 $ awk -F '[ .]' '{print $2}' host.log >> host.log $ cat host.log 1 www.edu.cn 2 blog.edu.cn 3 learning.edu.cn 4 java.edu.cn 5 nodejs.edu.cn 6 k8s.eud.cn 7 linux.edu.cn 8 python.edu.cn 9 learning.edu.cn 10 java.edu.cn 11 nodejs.edu.cn 12 www.edu.cn www blog learning java nodejs k8s linux python learning java nodejs www \u7edf\u8ba1\u6587\u4ef6 /etc/fstab \u4e2d\u6bcf\u4e2a\u6587\u4ef6\u7cfb\u7edf\u7c7b\u578b\u51fa\u73b0\u7684\u6b21\u6570\u3002 # \u4ee5UUID\u5f00\u5934\uff0c\u4e00\u4e2a\u6216\u591a\u4e2a\u7a7a\u683c\u4e3a\u5206\u9694\u7b26\uff0c\u8bfb\u53d6\u7b2c\u4e09\u5217\uff08\u5373\u6587\u4ef6\u7cfb\u7edf\u7c7b\u578b\uff09\u5e76\u8ba1\u6570\u3002 $ awk -F ' +' '/^UUID/{fs[$3]++}END{for(i in fs){print i, fs[i]}}' /etc/fstab swap 1 btrfs 10 vfat 1 # \u65b9\u6cd52 $ awk -F ' +' '/^UUID/{print $3}' /etc/fstab | uniq -c 10 btrfs 1 swap 1 vfat \u7edf\u8ba1\u6587\u4ef6 /etc/fstab \u4e2d\u6bcf\u4e2a\u5355\u8bcd\u51fa\u73b0\u7684\u6b21\u6570\u3002 $ awk -F \"[^[:alpha:]]\" '{for(i=1;i<=NF;i++)word[$i]++}END{for(a in word)if(a!=\"\")print a,word[a]}' /etc/fstab swap 2 B 1 srv 2 btrfs 10 snapshots 2 vfat 1 opt 2 cbaef 10 UUID 12 E 1 ecf 1 CD 1 cf 1 arm 2 a 11 c 2 tmp 2 usr 2 var 2 afa 20 home 2 d 10 utf 1 e 2 efi 3 grub 2 boot 3 subvol 9 root 2 local 2 defaults 2 f 10 \u63d0\u53d6\u5b57\u7b26\u4e32 Yd$@C#M05MD9&8923+Vip3wZ!33*44&55 \u4e2d\u6240\u6709\u7684\u6570\u5b57\u3002 # \u5bf9\u6bd4\u5355\u5f15\u53f7\u548c\u53cc\u5f15\u53f7\u7684\u533a\u522b\u3002 $ echo \"Yd $@ C#M05MD9&8923+Vip3wZ!33*44&55\" echo \"Yd $@ C#M05MD9&8923+Vip3wZcgcreate -g cpu:mygroup44&55\" YdC#M05MD9 & 8923 +Vip3wZcgcreate -g cpu:mygroup44 & 55 $ echo 'Yd$@C#M05MD9&8923+Vip3wZ!33*44&55' Yd $@ C#M05MD9 & 8923 +Vip3wZ!33*44 & 55 $ echo 'Yd$@C#M05MD9&8923+Vip3wZ!33*44&55' | awk '{gsub(/[^0-9]/,\"\");print $0}' 05989233334455 $ echo 'Yd$@C#M05MD9&8923+Vip3wZ!33*44&55' | awk -F '[^0-9]' '{for(i=1;i<=NF;i++){printf \"%s\", $i}}' 05989233334455 $ echo 'Yd$@C#M05MD9&8923+Vip3wZ!33*44&55' | awk -F \"\" '{for(i=1;i<=NF;i++){if($i ~ /[[:digit:]]/){str=$i;str1=(str1 str)}};print str1}' 05989233334455 $ echo 'Yd$@C#M05MD9&8923+Vip3wZ!33*44&55' | awk -F '' '{for(i=1;i<=NF;i++){if($i ~ /[[:digit:]]/){str=$i;str1=(str1 str)}};print str1}' # \u6ce8\u610f\uff0c\u5982\u679c\u5199\u6210\u5982\u4e0b\u683c\u5f0f\uff0c\u5219\u62a5\u9519\u3002 $ echo 'Yd$@C#M05MD9&8923+Vip3wZ!33*44&55' | awk -F '' '{for(i=1;i<=NF;i++){if($i ~ /[[:digit:]]/){str=$i;str1=(str1 str)}};print str1}' # \u6ce8\u610f\uff0c\u5982\u679c\u5199\u6210\u5982\u4e0b\u683c\u5f0f\uff0c\u5219\u8f93\u51fa\u539f\u5b57\u7b26\u4e32\u3002 $ echo 'Yd$@C#M05MD9&8923+Vip3wZ!33*44&55' | awk -F ' ' '{for(i=1;i<=NF;i++){if($i ~ /[[:digit:]]/){str=$i;str1=(str1 str)}};print str1}' \u751f\u6210500\u4e2a\u968f\u673a\u6570\uff0c\u4fdd\u5b58\u5230\u6587\u4ef6random.txt\u4e2d\uff0c\u683c\u5f0f\u4e3a 100,20,61,98... \uff0c\u53d6\u51fa\u5176\u4e2d\u6700\u5927\u6574\u6570\u548c\u6700\u5c0f\u6574\u6570\u3002 $ str = \"\" ; for (( i = 1 ; i< = 500 ; i++ )) ; do if [ $i -ne 500 ] ; then str += \" $RANDOM ,\" ; else str += \" $RANDOM \" ; fi ; done ; echo \" $str \" > random.txt $ cat random.txt 11308 ,8764,2075,9411,...... $ awk -F, '{max=$1;min=$1;for(i=1;i<=NF;i++){if($i>max){max=$i}else{if($i200){system(\"iptables -A INPUT -s \" i \" -j REJECT;\")}}}' \u5c06\u4e0b\u9762\u5185\u5bb9\u4e2dFQDN\u53d6\u51fa\uff0c\u5e76\u6839\u636e\u5176\u8fdb\u884c\u8ba1\u6570\uff0c\u4ece\u9ad8\u5230\u4f4e\u6392\u5e8f\u3002 $ cat > fqdn.txt << EOF http://mail.edu.com/index.html http://www.edu.com/test.html http://study.edu.com/index.html http://blog.edu.com/index.html http://www.edu.com/images/logo.jpg http://blog.edu.com/20080102.html EOF $ awk -F \"/\" '{url[$3]++}END{for(i in url){print url[i], i}}' fqdn.txt | sort -nr 2 www.edu.com 2 blog.edu.com 1 study.edu.com 1 mail.edu.com \u5c06\u4ee5\u4e0b\u2f42\u672c\u4ee5inode\u4e3a\u6807\u8bb0\uff0c\u5bf9inode\u76f8\u540c\u7684counts\u8fdb\u2f8f\u7d2f\u52a0\uff0c\u5e76\u4e14\u7edf\u8ba1\u51fa\u540c\u4e00inode\u4e2d\uff0cbeginnumber\u7684\u6700\u5c0f\u503c\u548cendnumber\u7684\u6700\u5927\u503c\u3002 inode | beginnumber | endnumber | counts | 106 | 3363120000 | 3363129999 | 10000 | 106 | 3368560000 | 3368579999 | 20000 | 310 | 3337000000 | 3337000100 | 101 | 310 | 3342950000 | 3342959999 | 10000 | 310 | 3362120960 | 3362120961 | 2 | 311 | 3313460102 | 3313469999 | 9898 | 311 | 3313470000 | 3313499999 | 30000 | 311 | 3362120962 | 3362120963 | 2 | \u8f93\u51fa\u7684\u7ed3\u679c\u683c\u5f0f\u4e3a\uff1a 310 | 3337000000 | 3362120961 | 10103 | 311 | 3313460102 | 3362120963 | 39900 | 106 | 3363120000 | 3368579999 | 30000 | $ cat > inode.text << EOF inode|beginnumber|endnumber|counts| 106|3363120000|3363129999|10000| 106|3368560000|3368579999|20000| 310|3337000000|3337000100|101| 310|3342950000|3342959999|10000| 310|3362120960|3362120961|2| 311|3313460102|3313469999|9898| 311|3313470000|3313499999|30000| 311|3362120962|3362120963|2| EOF $ awk -F '|' -v OFS = '|' '/^[0-9]/{inode[$1]++; if(!bn[$1]){bn[$1]=$2}else if(bn[$1]>$2) {bn[$1]=$2}; if(en[$1]<$3)en[$1]=$3;cnt[$1]+=$(NF-1)} END{for(i in inode)print i,bn[i],en[i],cnt[i]}' inode.text 106 | 3363120000 | 3368579999 | 30000 310 | 3337000000 | 3362120961 | 10103 311 | 3313460102 | 3362120963 | 39900","title":"\u7b2c\u4e94\u7ae0 \u6b63\u5219\u8868\u8fbe\u5f0f"},{"location":"linux/SRE/05-RegExpress/#_1","text":"\u6b63\u5219\u8868\u8fbe\u5f0f\u5206\u4e24\u7c7b\uff1a \u57fa\u672c\u6b63\u5219\u8868\u8fbe\u5f0f\uff08Basic Regular Expression\uff0c \u53c8\u53ebBasic RegEx\uff0c\u7b80\u79f0BREs\uff09 \u6269\u5c55\u6b63\u5219\u8868\u8fbe\u5f0f\uff08Extended Regular Expression\uff0c \u53c8\u53ebExtended RegEx\uff0c\u7b80\u79f0EREs\uff09 Perl\u6b63\u5219\u8868\u8fbe\u5f0f\uff08Perl Regular Expression\uff0c \u53c8\u53ebPerl RegEx \u7b80\u79f0PREs \u57fa\u672c\u7684\u6b63\u5219\u8868\u8fbe\u5f0f\u548c\u6269\u5c55\u6b63\u5219\u8868\u8fbe\u5f0f\u7684\u533a\u522b\u5c31\u662f\u5143\u5b57\u7b26\u7684\u4e0d\u540c\u3002","title":"\u7b2c\u4e94\u7ae0 \u6b63\u5219\u8868\u8fbe\u5f0f"},{"location":"linux/SRE/05-RegExpress/#51","text":"^ \uff1a\u8868\u793a\u4ee5\u67d0\u4e2a\u5b57\u7b26\u5f00\u59cb $ \uff1a\u8868\u793a\u4ee5\u67d0\u4e2a\u5b57\u7b26\u7ed3\u5c3e . \uff1a\u8868\u793a\u5339\u914d\u4e00\u4e2a\u4e14\u53ea\u5339\u914d\u4e00\u4e2a\u5b57\u7b26 * \uff1a\u8868\u793a\u5339\u914d\u524d\u8fb9\u4e00\u4e2a\u5b57\u7b26\u51fa\u73b00\u6b21\u6216\u8005\u591a\u6b21 [] \uff1a\u8868\u793a\u5339\u914d\u62ec\u53f7\u5185\u7684\u591a\u4e2a\u5b57\u7b26\u4fe1\u606f,\u4e00\u4e2a\u4e00\u4e2a\u5339\u914d .* \uff1a\u8868\u793a\u5339\u914d\u6240\u6709\uff0c\u7a7a\u884c\u4e5f\u4f1a\u8fdb\u884c\u5339\u914d [^] \uff1a\u8868\u793a\u4e0d\u5339\u914d\u62ec\u53f7\u5185\u7684\u6bcf\u4e00\u4e2a\u5b57\u7b26 ^$ \uff1a\u8868\u793a\u5339\u914d\u7a7a\u884c\u4fe1\u606f \\ \uff1a\u5c06\u6709\u7279\u6b8a\u542b\u4e49\u7684\u5b57\u7b26\u8f6c\u4e49\u4e3a\u901a\u914d\u7b26","title":"5.1.\u57fa\u672c\u6b63\u5219\u8868\u8fbe\u5f0f\u7b26\u53f7"},{"location":"linux/SRE/05-RegExpress/#52","text":"+ \uff1a\u8868\u793a\u524d\u4e00\u4e2a\u5b57\u7b26\u51fa\u73b0\u4e00\u6b21\u6216\u4e00\u6b21\u4ee5\u4e0a ? \uff1a\u8868\u793a\u524d\u4e00\u4e2a\u5b57\u7b26\u51fa\u73b00\u6b21\u6216\u8005\u4e00\u6b21\u4ee5\u4e0a | \uff1a\u8868\u793a\u6216\u8005\u7684\u5173\u7cfb,\u5339\u914d\u591a\u4e2a\u4fe1\u606f () \uff1a\u5339\u914d\u4e00\u4e2a\u6574\u4f53\u4fe1\u606f\uff0c\u4e5f\u53ef\u4ee5\u63a5\u540e\u9879\u5f15\u7528 {} \uff1a\u5b9a\u4e49\u524d\u8fb9\u5b57\u7b26\u51fa\u73b0\u51e0\u6b21 \u63d0\u793a\uff1a grep -E \u6216\u8005 egrep \u53ea\u662f\u8868\u793a\u6269\u5c55\u6b63\u5219\uff0c\u4e0d\u4ee3\u8868\u52a0\u4e86e\u5c31\u8868\u793a\u8f6c\u4e49\u4e86\u3002 \u5f53 grep \u4f7f\u7528\u6269\u5c55\u6b63\u5219\u7684\u7b26\u53f7\u65f6\u5019\u9700\u8981\u7528 \\ \u8f6c\u4e49\u4e3a\u901a\u914d\u7b26\u624d\u80fd\u4f7f\u7528\u3002","title":"5.2.\u6269\u5c55\u6b63\u5219\u8868\u8fbe\u5f0f\u7b26\u53f7"},{"location":"linux/SRE/05-RegExpress/#53","text":"[:alpha:] \uff1a\u8868\u793a\u6240\u6709\u7684\u5b57\u6bcd\uff08\u4e0d\u533a\u5206\u5927\u5c0f\u5199\uff09\uff0c\u6548\u679c\u540c [a-z] [:digit:] \uff1a\u8868\u793a\u4efb\u610f\u5355\u4e2a\u6570\u5b57\uff0c\u6548\u679c\u540c [0-9] [:xdigit:] \uff1a\u8868\u793a\u5341\u516d\u8fdb\u5236\u6570\u5b57 [:lower:] \uff1a\u8868\u793a\u4efb\u610f\u5355\u4e2a\u5c0f\u5199\u5b57\u6bcd [:upper:] \uff1a\u8868\u793a\u4efb\u610f\u5355\u4e2a\u5927\u5199\u5b57\u6bcd [:alnum:] \uff1a\u8868\u793a\u4efb\u610f\u5355\u4e2a\u5b57\u6bcd\u6216\u6570\u5b57 [:blank:] \uff1a\u8868\u793a\u7a7a\u767d\u5b57\u7b26\uff08\u7a7a\u683c\u548c\u5236\u8868\u7b26\uff09 [:space:] \uff1a\u8868\u793a\u5305\u62ec\u7a7a\u683c\u3001\u5236\u8868\u7b26\uff08\u6c34\u5e73\u548c\u5782\u76f4\uff09\u3001\u6362\u884c\u7b26\u3001\u56de\u8f66\u7b26\u7b49\u5404\u79cd\u7c7b\u578b\u7684\u7a7a\u767d\uff0c\u6bd4 [:blank:] \u8303\u56f4\u66f4\u5e7f [:cntrl:] \uff1a\u8868\u793a\u4e0d\u53ef\u6253\u5370\u7684\u63a7\u5236\u5b57\u7b26\uff08\u9000\u683c\u3001\u5220\u9664\u3001\u8b66\u94c3\u7b49\uff09 [:graph:] \uff1a\u8868\u793a\u53ef\u6253\u5370\u7684\u975e\u7a7a\u767d\u5b57\u7b26 [:print:] \uff1a\u8868\u793a\u53ef\u6253\u5370\u5b57\u7b26 [:punct:] \uff1a\u8868\u793a\u6807\u70b9\u7b26\u53f7","title":"5.3.\u5b57\u7b26\u5339\u914d"},{"location":"linux/SRE/05-RegExpress/#54","text":"\u4f4d\u7f6e\u6807\u8bb0\u951a\u70b9\uff08position marker anchor\uff09\u662f\u6807\u8bc6\u5b57\u7b26\u4e32\u4f4d\u7f6e\u7684\u6b63\u5219\u8868\u8fbe\u5f0f\u3002\u9ed8\u8ba4\u60c5\u51b5\u4e0b\uff0c\u6b63\u5219\u8868\u8fbe\u5f0f\u6240\u5339\u914d\u7684\u5b57\u7b26\u53ef\u4ee5\u51fa\u73b0\u5728\u5b57\u7b26\u4e32\u4e2d\u4efb\u4f55\u4f4d\u7f6e\u3002 ^ \uff1a\u884c\u9996\u951a\u5b9a\uff0c\u6307\u5b9a\u4e86\u5339\u914d\u6b63\u5219\u8868\u8fbe\u5f0f\u7684\u6587\u672c\u5fc5\u987b\u8d77\u59cb\u4e8e\u5b57\u7b26\u4e32\u7684\u9996\u90e8\u3002 \u4f8b\u5982\uff1a ^tux \u80fd\u591f\u5339\u914d\u4ee5 tux \u8d77\u59cb\u7684\u884c $ \uff1a\u884c\u5c3e\u951a\u5b9a\uff0c\u6307\u5b9a\u4e86\u5339\u914d\u6b63\u5219\u8868\u8fbe\u5f0f\u7684\u6587\u672c\u5fc5\u987b\u7ed3\u675f\u4e8e\u76ee\u6807\u5b57\u7b26\u4e32\u7684\u5c3e\u90e8\u3002 \\< \u6216 \\b \uff1a\u8bcd\u9996\u951a\u5b9a\uff0c\u7528\u4e8e\u5355\u8bcd\u6a21\u5f0f\u5339\u914d\u5de6\u4fa7\u3002\uff08\u5355\u8bcd\u662f\u6709\u5b57\u6bcd\u3001\u6570\u5b57\u3001\u4e0b\u5212\u7ebf\u7ec4\u6210\uff09 \\> \u6216 \\b \uff1a\u8bcd\u5c3e\u951a\u5b9a\uff0c\u7528\u4e8e\u5355\u8bcd\u6a21\u5f0f\u5339\u914d\u53f3\u4fa7\u3002\uff08\u5355\u8bcd\u662f\u6709\u5b57\u6bcd\u3001\u6570\u5b57\u3001\u4e0b\u5212\u7ebf\u7ec4\u6210\uff09 ^PATTERN$ \uff1a\u7528\u6a21\u5f0fPATTERN\u5339\u914d\u6574\u884c\u3002 ^$ \uff1a\u5339\u914d\u7a7a\u884c\u3002 ^[[:space:]]*$ \uff1a\u5339\u914d\u7a7a\u767d\u884c\uff08\u6574\u884c\uff09\u3002 \\ \uff1a\u5339\u914d\u6574\u4e2a\u5355\u8bcd\u3002\uff08\u5355\u8bcd\u662f\u6709\u5b57\u6bcd\u3001\u6570\u5b57\u3001\u4e0b\u5212\u7ebf\u7ec4\u6210\uff09 \u5173\u4e8e\u884c\u9996\u951a\u5b9a\u548c\u8bcd\u9996\u951a\u5b9a\uff0c\u5bf9\u6bd4\u4e0b\u9762\u4f8b\u5b50\u3002\u8bcd\u5c3e\u951a\u5b9a\u4e5f\u662f\u7c7b\u4f3c\u60c5\u51b5\u3002 ; \u548c - \u90fd\u88ab\u8ba4\u5b9a\u4e3a\u5355\u8bcd\u5206\u9694\u7b26\u3002 # \u7b26\u5408\u8bcd\u9996\u5339\u914d $ echo \"tux_01-tux02\" | grep '\\ mtu 1500 inet 192 .168.10.210 netmask 255 .255.255.0 broadcast 192 .168.10.255 inet6 fe80::20c:29ff:fea4:e17a prefixlen 64 scopeid 0x20 ether 00 :0c:29:a4:e1:7a txqueuelen 1000 ( Ethernet ) RX packets 7654 bytes 635932 ( 621 .0 KiB ) RX errors 0 dropped 1 overruns 0 frame 0 TX packets 1934 bytes 279649 ( 273 .0 KiB ) TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0 $ ifconfig eth0 | grep netmask | grep -o '[0-9]\\{1,3\\}\\.[0-9]\\{1,3\\}\\.[0-9]\\{1,3\\}\\.[0-9]\\{1,3\\}' 192 .168.10.210 255 .255.255.0 192 .168.10.255 $ ifconfig eth0 | grep netmask | grep -o '[0-9]\\{1,3\\}\\.[0-9]\\{1,3\\}\\.[0-9]\\{1,3\\}\\.[0-9]\\{1,3\\}' | head -n 1 192 .168.10.210 $ ifconfig eth0 | grep -o '[0-9]\\{1,3\\}\\.[0-9]\\{1,3\\}\\.[0-9]\\{1,3\\}\\.[0-9]\\{1,3\\}' 192 .168.10.210 255 .255.255.0 192 .168.10.255 ifconfig eth0 | grep -o '[0-9]\\{1,3\\}\\.[0-9]\\{1,3\\}\\.[0-9]\\{1,3\\}\\.[0-9]\\{1,3\\}' | head -n 1 192 .168.10.210 \u5339\u914d\u7a7a\u884c\u548c\u975e\u7a7a\u884c\uff1a grep '^$' /etc/profile grep -v '^$' /etc/profile \u5339\u914d\u975e\u7a7a\u884c\u548c\u975e#\u5f00\u5934\u7684\u884c\uff1a\uff08\u4e09\u79cd\u65b9\u6cd5\uff09 grep -v '^$' /etc/profile | grep -v '^#' grep -v '^$\\|#' /etc/profile grep '^[^$#]' /etc/profile \u6ce8\u610f\uff0c\u5982\u679c\u5199\u6210\u4e0b\u9762\u8fd9\u6837\uff0c\u5219\u4e0d\u4f1a\u8fc7\u6ee4\u6389\u7a7a\u884c\uff0c [$] \u4f1a\u88ab\u89c6\u4e3a $ \u7b26\u53f7\u3002 \u6240\u4ee5\u6b63\u5219\u8868\u8fbe\u5f0f\u7684\u5143\u5b57\u7b26\u653e\u5728\u4e2d\u62ec\u53f7 [] \u5185\u5c31\u88ab\u89c6\u4e3a\u666e\u901a\u5b57\u7b26\u3002 grep -v '^[$#]' /etc/profile","title":"5.7.\u5206\u7ec4"},{"location":"linux/SRE/05-RegExpress/#58grep","text":"\u683c\u5f0f\uff1a grep [OPTIONS] PATTERN [FILE...] grep [OPTIONS] -e PATTERN ... [FILE...] grep [OPTIONS] -f FILE ... [FILE...] \u53c2\u6570\uff1a -n \uff1a\u663e\u793a\u8fc7\u6ee4\u51fa\u6765\u7684\u6587\u4ef6\u5728\u6587\u4ef6\u5f53\u4e2d\u7684\u884c\u53f7 -c \uff1a\u663e\u793a\u5339\u914d\u5230\u7684\u884c\u6570 -o \uff1a\u53ea\u663e\u793a\u5339\u914d\u5230\u7684\u5185\u5bb9 -q \uff1a\u9759\u9ed8\u8f93\u51fa\uff08\u4e00\u822c\u7528\u5728shell\u811a\u672c\u5f53\u4e2d\uff0c\u901a\u8fc7 echo $? \u67e5\u770b\u547d\u4ee4\u6267\u884c\u7ed3\u679c\uff0c0\u8868\u793a\u6210\u529f\uff0c\u975e0\u8868\u793a\u5931\u8d25\uff09\uff09 -i \uff1a\u5ffd\u7565\u5927\u5c0f\u5199 -v \uff1a\u53cd\u5411\u67e5\u627e -w \uff1a\u5339\u914d\u67d0\u4e2a\u8bcd\u8bcd\uff1a\u5728Linux\u4e2d\uff0c\u8bcd\u4e3a\u4e00\u8fde\u4e32\u5b57\u6bcd\u3001\u6570\u5b57\u548c\u4e0b\u5212\u7ebf\u7ec4\u6210\u7684\u5b57\u7b26\u4e32 -E \uff1a\u4f7f\u7528\u6269\u5c55\u6b63\u5219 -R \uff1a\u9012\u5f52\u67e5\u8be2 -l \uff1a\u53ea\u6253\u5370\u6587\u4ef6\u8def\u5f84 \u6269\u5c55\u53c2\u6570\uff1a -A \uff1a\u663e\u793a\u5339\u914d\u5230\u7684\u6570\u636e\u7684\u540e\u51e0n\u884c -B \uff1a\u663e\u793a\u5339\u914d\u5230\u7684\u6570\u636e\u7684\u524d\u51e0n\u884c -C \uff1a\u663e\u793a\u5339\u914d\u5230\u7684\u6570\u636e\u7684\u524d\u540e\u5404\u51e0n\u884c \u793a\u4f8b\uff1a \u5339\u914d\u7528\u6237\uff1a grep root /etc/passwd root:x:0:0:root:/root:/bin/bash $ grep \"USER\" /etc/passwd $ grep \" $USER \" /etc/passwd vagrant:x:1000:478:vagrant:/home/vagrant:/bin/bash $ grep '$USER' /etc/passwd \u5339\u914d\u5173\u952e\u5b57\uff1a $ grep processor /proc/cpuinfo processor : 0 processor : 1 $ grep -o processor /proc/cpuinfo processor processor $ grep \"cpu family\" /proc/cpuinfo cpu family : 6 cpu family : 6 $ grep -o \"cpu family\" /proc/cpuinfo cpu family cpu family \u901a\u8fc7grep\u8fdb\u884c\u6587\u4ef6\u6bd4\u8f83\u3002 # \u6700\u540e\u4e00\u884c\u662f\u7a7a\u884c $ cat f1 a b 1 c # \u6700\u540e\u4e00\u884c\u662f\u7a7a\u884c $ cat f2 b e f c 1 2 # \u9ad8\u4eae\u663e\u793a\u76f8\u540c\u5185\u5bb9\u7684\u884c\uff0c\u5305\u542b\u6700\u540e\u4e00\u884c\u7a7a\u884c $ grep -f f1 f2 b e f c 1 2 # \u53ea\u663e\u793a\u76f8\u540c\u5185\u5bb9\u7684\u884c\uff0c\u5305\u542b\u6700\u540e\u4e00\u884c\u7a7a\u884c $ grep -wf f1 f2 b c 1 # \u53ea\u663e\u793a\u4e0d\u540c\u5185\u5bb9\u7684\u884c $ grep -wvf f1 f2 e f 2 \u63d0\u793a\uff1a grep -wvf f1 f2 \u6216\u8005 grep -w -v -f f1 f2 \u4e2d\uff0c -f \u53ea\u80fd\u4f5c\u4e3a\u6700\u540e\u4e00\u4e2a\u53c2\u6570\uff0c\u5426\u5219\u4f1a\u62a5\u9519\u3002 \u4f53\u4f1a\u57fa\u672c\u6b63\u5219\u548c\u6269\u5c55\u6b63\u5219\u7684\u5dee\u5f02\u3002 \u4f8b1\uff1a\u8f6c\u4e49\u3002 # \u4e0b\u9762\u51e0\u4e2a\u547d\u4ee4\u8fd4\u56de\u7684\u7ed3\u679c\u662f\u4e00\u6837\u7684\u3002 $ grep \"root\\|bash\" /etc/passwd $ grep -E \"root|bash\" /etc/passwd $ grep -e \"root\" -e \"bash\" /etc/passwd # \u4e0b\u9762\u7684\u547d\u4ee4\u6ca1\u6709\u5339\u914d\u7ed3\u679c\u8fd4\u56de\u3002 $ grep \"root|bash\" /etc/passwd \u4f8b2\uff1a\u4e0b\u97624\u4e2a\u547d\u4ee4\u8fd4\u56de\u540c\u6837\u7684\u7ed3\u679c\u3002 grep \"root\" /etc/passwd grep -E \"root\" /etc/passwd grep \"\\\" /etc/passwd grep -E \"\\\" /etc/passwd \u4f8b3\uff1a\u884c\u9996\u884c\u5c3e\u951a\u5b9a\u3002 $ grep \"^\\(.*\\)\\>.*\\<\\1 $ \" /etc/passwd $ grep -E \"^(.*)\\>.*\\<\\1 $ \" /etc/passwd $ egrep \"^(.*)\\>.*\\<\\1 $ \" /etc/passwd sync:x:5:0:sync:/sbin:/bin/sync shutdown:x:6:0:shutdown:/sbin:/sbin/shutdown halt:x:7:0:halt:/sbin:/sbin/halt \u4f8b4\uff1a\u4e09\u79cd\u65b9\u6cd5\u6c42\u548c\u8ba1\u7b97\uff0c\u8fd0\u7528 grep \uff0c cut \uff0c bc \u548c paste \u547d\u4ee4\u3002 $cat age Jason = 20 Tom = 30 Jack = 40 # \u65b9\u6cd51 $ cat age | cut -d \"=\" -f 2 | tr \"\\n\" + | grep -Eo \".*[0-9]\" | bc 90 # \u65b9\u6cd52 $ grep -Eo \"[0-9]+\" age | tr \"\\n\" + | grep -Eo \".*[0-9]\" | bc 90 # \u65b9\u6cd53 $ grep -Eo \"[0-9]+\" age | paste -s -d \"+\" | bc 90","title":"5.8.\u4e09\u5251\u5ba2grep\u547d\u4ee4"},{"location":"linux/SRE/05-RegExpress/#59sed","text":"sed \u662fstream editor\u7684\u7f29\u5199\uff0c\u4e2d\u6587\u79f0\u4e4b\u4e3a\u201c\u6d41\u7f16\u8f91\u5668\u201d\u3002 sed \u547d\u4ee4\u662f\u4e00\u4e2a\u9762\u5411\u884c\u5904\u7406\u7684\u5de5\u5177\uff0c\u5b83\u4ee5\u201c\u884c\u201d\u4e3a\u5904\u7406\u5355\u4f4d\uff0c\u9488\u5bf9\u6bcf\u4e00\u884c\u8fdb\u884c\u5904\u7406\uff0c\u5904\u7406\u540e\u7684\u7ed3\u679c\u4f1a\u8f93\u51fa\u5230\u6807\u51c6\u8f93\u51fa STDOUT \uff0c\u4e0d\u4f1a\u5bf9\u8bfb\u53d6\u7684\u6587\u4ef6\u505a\u4efb\u4f55\u4fee\u6539\u3002 sed \u7684\u5de5\u4f5c\u539f\u7406\uff1a sed \u547d\u4ee4\u662f\u9762\u5411\u201c\u884c\u201d\u8fdb\u884c\u5904\u7406\u7684\uff0c\u6bcf\u4e00\u6b21\u5904\u7406\u4e00\u884c\u5185\u5bb9\u3002 \u5904\u7406\u65f6\uff0c sed \u4f1a\u628a\u8981\u5904\u7406\u7684\u884c\u5b58\u50a8\u5728\u7f13\u51b2\u533a\u4e2d\uff0c\u63a5\u7740\u7528 sed \u547d\u4ee4\u5904\u7406\u7f13\u51b2\u533a\u4e2d\u7684\u5185\u5bb9\uff0c\u5904\u7406\u5b8c\u6210\u540e\uff0c\u628a\u7f13\u51b2\u533a\u7684\u5185\u5bb9\u9001\u5f80\u5c4f\u5e55\u3002\u63a5\u7740\u5904\u7406\u4e0b\u4e00\u884c\uff0c\u8fd9\u6837\u4e0d\u65ad\u91cd\u590d\uff0c\u76f4\u5230\u6587\u4ef6\u672b\u5c3e\u3002\u8fd9\u4e2a\u7f13\u51b2\u533a\u88ab\u79f0\u4e3a\u201c \u6a21\u5f0f\u7a7a\u95f4 \u201d\uff08pattern space\uff09\u3002 \u4fdd\u6301\u7a7a\u95f4(hold space) sed \u7684\u4fdd\u6301\u7a7a\u95f4\u50cf\u4e00\u4e2a\u957f\u671f\u50a8\u5b58\uff0c \u53ef\u4ee5\u628a\u83b7\u53d6\u7684\u4fe1\u606f\u50a8\u5b58\u5230\u5176\u4e2d\uff0c\u5f85\u540e\u7eed\u8c03\u7528\u3002\u4e0d\u80fd\u76f4\u63a5\u5bf9\u4fdd\u6301\u7a7a\u95f4\u8fdb\u884c\u64cd\u4f5c\uff0c \u800c\u662f\u5c06\u4fdd\u6301\u7a7a\u95f4\u7684\u5185\u5bb9\u590d\u5236\u6216\u8005\u6dfb\u52a0\u5230\u6a21\u5f0f\u7a7a\u95f4\u8fdb\u884c\u64cd\u4f5c\u3002 \u975e\u4ea4\u4e92\u5f0f\u6279\u91cf\u4fee\u6539\u6587\u4ef6\u3002 sed \u547d\u4ee4\u683c\u5f0f\uff1a sed [ option ] command file option \u5e38\u7528\u9009\u9879\uff1a -n \uff1a\u4e0d\u8f93\u51fa\u6a21\u5f0fpattern\u7684\u5185\u5bb9\u5230\u5c4f\u5e55\uff08\u5373\u4e0d\u81ea\u52a8\u6253\u5370\uff09 -e \uff1a\u591a\u70b9\u7f16\u8f91 -f filename \uff1a\u4ece\u6307\u5b9a\u6587\u4ef6\u8bfb\u53d6\u7f16\u8f91\u811a\u672c -r \uff0c -E \uff1a\u4f7f\u7528\u6269\u5c55\u6b63\u5219\u8868\u8fbe\u5f0f -i .bak \uff1a\u5907\u4efd\u6587\u4ef6\u5e76\u539f\u5904\u7f16\u8f91 -s \uff1a\u5c06\u591a\u4e2a\u6587\u4ef6\u89c6\u4e3a\u72ec\u7acb\u6587\u4ef6\uff0c\u800c\u4e0d\u662f\u5355\u4e2a\u8fde\u7eed\u7684\u957f\u6587\u4ef6\u6d41 -ir \uff1a \u4e0d\u652f\u6301 -i -r \uff1a \u652f\u6301 -ri \uff1a \u652f\u6301 -ni \uff1a \u5371\u9669\u9009\u9879\uff0c\u4f1a\u6e05\u7a7a\u6587\u4ef6 command \u90e8\u5206\u53ef\u4ee5\u5206\u4e3a\u4e24\u90e8\u5206\uff1a \u8303\u56f4\u8bbe\u5b9a\uff0c\u53ef\u4ee5\u91c7\u7528\u4e24\u79cd\u4e0d\u540c\u7684\u65b9\u5f0f\u6765\u8868\u8fbe\uff1a \u6307\u5b9a\u884c\u6570\uff1a\u5982\uff1a 3,5 \u8868\u793a\u7b2c3\u30014\u30015\u884c 5,$ \u8868\u793a\u7b2c5\u884c\u81f3\u6587\u4ef6\u6700\u540e\u4e00\u884c \u6a21\u5f0f\u5339\u914d\uff1a\u5982\uff1a /^[^dD]/ \u8868\u793a\u5339\u914d\u884c\u9996\u4e0d\u662f\u4ee5 d \u6216 D \u5f00\u5934\u7684\u884c \u52a8\u4f5c\u5904\u7406\uff0c\u4e0b\u9762\u662f\u5e38\u7528\u7684\u52a8\u4f5c\uff1a a \uff1a\u65b0\u589e\uff0c a \u540e\u9762\u7684\u5b57\u4e32\u4f1a\u5728\u65b0\u7684\u4e00\u884c\u51fa\u73b0\uff08\u5f53\u524d\u884c\u7684\u4e0b\u4e00\u884c\uff09 i \uff1a\u63d2\u5165\uff0c i \u540e\u9762\u7684\u5b57\u4e32\u4f1a\u5728\u65b0\u7684\u4e00\u884c\u51fa\u73b0\uff08\u5f53\u524d\u884c\u7684\u4e0a\u4e00\u884c\uff09 r filename \uff1a\u8bfb\u53d6\u6307\u5b9a\u6587\u4ef6 fllename \u7684\u5185\u5bb9\uff0c\u8ffd\u52a0\u5230\u5f53\u524d\u884c\u7684\u4e0b\u4e00\u884c R filename \uff1a\u8bfb\u53d6\u6307\u5b9a\u6587\u4ef6 fllename \u7684\u4e00\u884c\uff0c\u8ffd\u52a0\u5230\u5f53\u524d\u884c\u7684\u4e0b\u4e00\u884c d \uff1a\u5220\u9664\u8be5\u884c p \uff1a\u6253\u5370\u8be5\u884c Ip \uff1a\u5ffd\u7565\u5927\u5c0f\u5199\u8f93\u51fa w filename \uff1a\u5199\u5165\u5230\u6307\u5b9a\u6587\u4ef6filename\u4e2d\u3002 s/regexp/replacement/ \uff1a\u53d6\u4ee3\uff0c\u7528replacement\u53d6\u4ee3\u6b63\u5219regexp\u5339\u914d\u5230\u7684\u5185\u5bb9 = \uff1a\u4e3a\u6a21\u5f0fpattern\u4e2d\u7684\u5339\u914d\u884c\u6253\u5370\u884c\u53f7 ! \uff1a\u4e3a\u6a21\u5f0fpattern\u4e2d\u7684\u5339\u914d\u884c\u53d6\u53cd\u64cd\u4f5c q \uff1a\u7ed3\u675f\u6216\u9000\u51fased \u521b\u5efa\u4e00\u4e2a testfile \u6587\u4ef6\u3002 $ cat < testfile HELLO LINUX! Linux is a free unix-type opterating system. This is a linux testfile! Linux test Google Taobao Banbooob Tesetfile Wiki EOF \u5339\u914d\u5b9a\u4f4d\u6587\u4ef6 testfile \u7b2c\u4e8c\u884c\uff0c\u5e76\u8f93\u51fa\uff08\u5305\u542b\u5339\u914d\u7b2c\u4e8c\u884c\u548c\u8f93\u51fa\u7b2c\u4e8c\u884c\uff09\u3002 # nl testfile | sed '2p' 1 HELLO LINUX! 2 Linux is a free unix-type opterating system. 2 Linux is a free unix-type opterating system. 3 This is a linux testfile! 4 Linux test 5 Google 6 Taobao 7 Banbooob 8 Tesetfile 9 Wiki \u5339\u914d\u5b9a\u4f4d\u6587\u4ef6 testfile \u7b2c\u4e8c\u884c\uff0c\u4e0d\u8f93\u51fa\u3002 # nl testfile | sed -n '2p' 2 Linux is a free unix-type opterating system. \u5339\u914d\u5b9a\u4f4d\u6587\u4ef6 testfile \u6700\u540e\u4e00\u884c\u3002 $ nl testfile | sed -n '$p' 9 Wiki \u5339\u914d\u5b9a\u4f4d\u6587\u4ef6 testfile \u5012\u6570\u7b2c\u4e8c\u884c\u3002 # sed -n \"$(echo $[`cat testfile | wc -l`-1])p\" testfile Tesetfile \u5c06 testfile \u7684\u5185\u5bb9\u5217\u51fa\u7b2c2\uff5e3\u884c\uff0c\u5e76\u4e14\u6253\u5370\u884c\u53f7\u3002 $ nl testfile | sed -n '2,3p' 2 Linux is a free unix-type opterating system. 3 This is a linux testfile! \u5c06 testfile \u7684\u5185\u5bb9\u4ece\u7b2c2\u884c\u5f00\u59cb\uff0c\u5411\u540e\u8f93\u51fa\u989d\u5916\u76843\u884c\uff0c\u5e76\u4e14\u6253\u5370\u884c\u53f7\u3002 $ nl testfile | sed -n '2,+3p' 2 Linux is a free unix-type opterating system. 3 This is a linux testfile! 4 Linux test 5 Google \u5c06 testfile \u7684\u5185\u5bb9\u4ece\u7b2c2\u884c\u5f00\u59cb\uff0c\u5411\u540e\u4ee52\u4e3a\u6b65\u8fdb\u5355\u4f4d\u8f93\u51fa\u6240\u6709\u5339\u914d\u884c\uff0c\u5e76\u4e14\u6253\u5370\u884c\u53f7\uff08\u5373\uff0c\u4ece\u7b2c2\u884c\u5f00\u59cb\u8f93\u51fa\u5076\u6570\u884c\uff09\u3002 nl testfile | sed -n '2~2p' 2 Linux is a free unix-type opterating system. 4 Linux test 6 Taobao 8 Tesetfile \u5c06 testfile \u7684\u5185\u5bb9\u4ece\u7b2c2\u884c\u5f00\u59cb\uff0c\u5411\u540e\u4ee52\u4e3a\u6b65\u8fdb\u5355\u4f4d\u5220\u9664\u6240\u6709\u5339\u914d\u884c\uff0c\u8f93\u51fa\u5269\u4f59\u884c\uff0c\u5e76\u4e14\u6253\u5370\u884c\u53f7\uff08\u5373\uff0c\u4ece\u7b2c2\u884c\u5f00\u59cb\u5220\u9664\u5076\u6570\u884c\uff0c\u8f93\u51fa\u5947\u6570\u884c\uff09\u3002 $ nl testfile | sed '2~2d' 1 HELLO LINUX! 3 This is a linux testfile! 5 Google 7 Banbooob 9 Wiki \u5c06 testfile \u7684\u5185\u5bb9\u8f93\u51fa\uff0c\u5220\u9664\u7b2c2\u884c\u548c\u7b2c5\u884c\uff0c\u5e76\u6253\u5370\u884c\u53f7\u3002 $ nl testfile | sed -e '2d' -e '5d' $ nl testfile | sed -e '2d;5d' $ nl testfile | sed '2d;5d' 1 HELLO LINUX! 3 This is a linux testfile! 4 Linux test 6 Taobao 7 Banbooob 8 Tesetfile 9 Wiki \u5c06 testfile \u7684\u5185\u5bb9\u8f93\u51fa\uff0c\u8f93\u51fa\u533a\u95f4\u662f\u4ece\u884c\u9996 L \u7684\u884c\u5230\u884c\u9996 G \u7684\u884c\u7ed3\u675f\u3002\u4e0d\u4fee\u6539\u539f\u6587\u4ef6\u3002 \u5982\u679c\u884c\u9996\u5339\u914d\u4e0d\u5230\uff0c\u5219\u65e0\u7ed3\u679c\u8f93\u51fa\uff1b\u5982\u679c\u884c\u5c3e\u5339\u914d\u4e0d\u5230\uff0c\u5219\u8f93\u51fa\u5230\u6587\u4ef6\u7ed3\u675f\u3002 $ sed -n '/^L/,/^G/p' testfile Linux is a free unix-type opterating system. This is a linux testfile! Linux test Google \u5c06 testfile \u7684\u5185\u5bb9\u8f93\u51fa\uff0c\u4e14\u5728\u7b2c6\u884c\u540e\u52a0\u4e0a I love Linux \u3002\u4e0d\u4fee\u6539\u539f\u6587\u4ef6\u3002 $ sed -e '6a I love Linux' testfile HELLO LINUX! Linux is a free unix-type opterating system. This is a linux testfile! Linux test Google Taobao I love Linux Banbooob Tesetfile Wiki \u5c06 testfile \u7684\u5185\u5bb9\u5217\u51fa\u5e76\u4e14\u6253\u5370\u884c\u53f7\uff0c\u4e14\u5728\u7b2c6\u884c\u540e\u6dfb\u52a0 I love Linux \u3002\u4e0d\u4fee\u6539\u539f\u6587\u4ef6\u3002 $ nl testfile | sed '6a I love Linux' $ nl testfile | sed '6a\\I love Linux' 1 HELLO LINUX! 2 Linux is a free unix-type opterating system. 3 This is a linux testfile! 4 Linux test 5 Google 6 Taobao I love Linux 7 Banbooob 8 Tesetfile 9 Wiki \u5c06 testfile \u7684\u5185\u5bb9\u5217\u51fa\u5e76\u4e14\u6253\u5370\u884c\u53f7\uff0c\u4e14\u5728\u7b2c3\u884c\u524d\u6dfb\u52a0 I am a journer learner \u3002\u4e0d\u4fee\u6539\u539f\u6587\u4ef6\u3002 $ nl testfile | sed '3i\\I am a journer learner' 1 HELLO LINUX! 2 Linux is a free unix-type opterating system. I am a journer learner 3 This is a linux testfile! 4 Linux test 5 Google 6 Taobao 7 Banbooob 8 Tesetfile 9 Wiki \u5c06 testfile \u7684\u5185\u5bb9\u5217\u51fa\u5e76\u4e14\u6253\u5370\u884c\u53f7\uff0c\u4e14\u5728\u7b2c3\u884c\u524d\u6dfb\u52a0\u4e09\u884c\u5185\u5bb9 Add line 1 \uff0c Add line 2 \uff0c Add line 3 \u3002\u7528\u7b26\u5408 \\ \u8fdb\u884c\u6362\u884c\u3002\u4e0d\u4fee\u6539\u539f\u6587\u4ef6\u3002 $ nl testfile | sed '3i\\Add line 1 \\ Add line 2 \\ Add line 3' 1 HELLO LINUX! 2 Linux is a free unix-type opterating system. Add line 1 Add line 2 Add line 3 3 This is a linux testfile! 4 Linux test 5 Google 6 Taobao 7 Banbooob 8 Tesetfile 9 Wiki \u5c06 testfile \u7684\u5185\u5bb9\u5217\u51fa\u5e76\u4e14\u6253\u5370\u884c\u53f7\uff0c\u4e14\u5c06\u7b2c2-5\u884c\u7684\u5185\u5bb9\u53d6\u4ee3\u6210\u4e3a replaced \u3002\u4e0d\u4fee\u6539\u539f\u6587\u4ef6\u3002 $ nl testfile | sed '2,5c\\replaced' $ nl testfile | sed '2,5c replaced' $ nl testfile | sed '2,5creplaced' 1 HELLO LINUX! replaced 6 Taobao 7 Banbooob 8 Tesetfile 9 Wiki \u5c06 testfile \u7684\u5185\u5bb9\u5217\u51fa\u5e76\u4e14\u6253\u5370\u884c\u53f7\uff0c\u4e14\u5220\u9664\u7b2c2~5\u884c\u3002\u4e0d\u4fee\u6539\u539f\u6587\u4ef6\u3002 $ nl testfile | sed '2,5d' 1 HELLO LINUX! 6 Taobao 7 Banbooob 8 Tesetfile 9 Wiki \u5c06 testfile \u7684\u5185\u5bb9\u5217\u51fa\u5e76\u4e14\u6253\u5370\u884c\u53f7\uff0c\u4e14\u5220\u9664\u7b2c5\u884c\u5230\u6700\u540e\u4e00\u884c\u3002 $ nl testfile | sed '5,$d' 1 HELLO LINUX! 2 Linux is a free unix-type opterating system. 3 This is a linux testfile! 4 Linux test \u5339\u914d\u5b9a\u4f4d\u6587\u4ef6 testfile \u4e2d\u5305\u542b\u5173\u952e\u5b57 linux \u7684\u884c\u3002 $ sed -n '/linux/p' testfile This is a linux testfile! \u5339\u914d\u5b9a\u4f4d\u547d\u4ee4 df \u8f93\u51fa\u4e2d\u4ee5 /dev/sd \u5173\u952e\u5b57\u5f00\u5934\u7684\u884c\u3002\uff08\u9700\u8981\u8f6c\u4e49\u7b26 \\ \uff09 $ df | sed -n '/^\\/dev\\/sd/p' /dev/sda2 102750208 7077280 92055312 8 % / /dev/sda2 102750208 7077280 92055312 8 % /.snapshots /dev/sda2 102750208 7077280 92055312 8 % /home /dev/sda2 102750208 7077280 92055312 8 % /opt /dev/sda2 102750208 7077280 92055312 8 % /root /dev/sda2 102750208 7077280 92055312 8 % /boot/grub2/x86_64-efi /dev/sda2 102750208 7077280 92055312 8 % /boot/grub2/i386-pc /dev/sda2 102750208 7077280 92055312 8 % /srv /dev/sda2 102750208 7077280 92055312 8 % /tmp /dev/sda2 102750208 7077280 92055312 8 % /usr/local /dev/sda2 102750208 7077280 92055312 8 % /var \u5339\u914d\u5b9a\u4f4d\u547d\u4ee4 df \u8f93\u51fa\u4e2d\u4e0d\u4ee5 /dev/sd \u5173\u952e\u5b57\u5f00\u5934\u7684\u884c\u3002\u901a\u8fc7 !p \u8fdb\u884c\u6c42\u53cd\u8f93\u51fa\u3002 $ df | sed -n '/^\\/dev\\/sd/!p' Filesystem 1K-blocks Used Available Use% Mounted on devtmpfs 4096 0 4096 0 % /dev tmpfs 1971208 0 1971208 0 % /dev/shm tmpfs 788484 9612 778872 2 % /run tmpfs 4096 0 4096 0 % /sys/fs/cgroup tmpfs 394240 0 394240 0 % /run/user/1000 \u5339\u914d\u5b9a\u4f4d\u547d\u4ee4 df \u8f93\u51fa\u4e2d\u4e0d\u4ee5 /dev/sd \u548c tmp \u5173\u952e\u5b57\u5f00\u5934\u7684\u884c\u3002 $ df | sed '/^\\/dev\\/sd/d;/^tmp/d' Filesystem 1K-blocks Used Available Use% Mounted on devtmpfs 4096 0 4096 0 % /dev $ df | grep -Ev '^\\/dev\\/sd|^tmp' Filesystem 1K-blocks Used Available Use% Mounted on devtmpfs 4096 0 4096 0 % /dev \u641c\u7d22\u6587\u4ef6 testfile \u6240\u6709\u5305\u542b oo \u5173\u952e\u5b57\u7684\u884c\u5e76\u5339\u914d\u8f93\u51fa\u3002\u4e0d\u4fee\u6539\u539f\u6587\u4ef6\u3002 $ sed -n '/ooo/p' testfile Banbooob $ sed -n '/oo/p' testfile Google Banbooob \u641c\u7d22\u6587\u4ef6 testfile \u6240\u6709\u5305\u542b oo \u5173\u952e\u5b57\u7684\u884c\u5e76\u5220\u9664\u3002\u4e0d\u4fee\u6539\u539f\u6587\u4ef6\u3002 $ sed '/oo/d' testfile HELLO LINUX! Linux is a free unix-type opterating system. This is a linux testfile! Linux test Taobao Tesetfile Wiki \u641c\u7d22\u6587\u4ef6 testfile \u6240\u6709\u5305\u542b oo \u7684\u884c\uff0c\u628a oo \u66ff\u6362\u4e3a kk \uff0c\u518d\u8f93\u51fa\u8fd9\u884c\u3002\u4e0d\u4fee\u6539\u539f\u6587\u4ef6\u3002 $ sed -n '/oo/{s/oo/kk/;p;q}' testfile $ sed -ne '/oo/{s/oo/kk/;p;q}' testfile Gkkgle \u5c06 testfile \u7684\u6bcf\u884c\u4e2d\u7b2c\u4e00\u6b21\u51fa\u73b0 ao \u7684\u66ff\u6362\u6210 HH \u3002 $ sed 's/ao/HH/' testfile HELLO LINUX! Linux is a free unix-type opterating system. This is a linux testfile! Linux test Google THHbao Banbooob Tesetfile Wiki \u4e0b\u9762\u662f\u628a testfile \u7684\u5339\u914d\u5230 ao \u7684\u884c\u66ff\u6362\u6210 HH \u3002 sed '/ao/cHH' testfile HELLO LINUX! SUSE This is a linux testfile! SUSE Google Taobao Banbooob Tesetfile Wiki \u641c\u7d22\u6587\u4ef6 testfile \u6240\u6709\u5305\u542b ao \u7684\u5168\u90e8\u66ff\u6362\u6210 HH \u3002 g \u8868\u793a\u5168\u5c40\u5339\u914d\u3002\u4e0d\u4fee\u6539\u539f\u6587\u4ef6\u3002 $ sed -e 's/ao/HH/g' testfile $ sed 's/ao/HH/g' testfile HELLO LINUX! Linux is a free unix-type opterating system. This is a linux testfile! Linux test Google THHbHH Banbooob Tesetfile Wiki \u5728\u6587\u4ef6 /etc/passwd \u4e2d\u67e5\u627e\u5339\u914d\u6240\u6709\u7b26\u5408 r \u5f00\u5934 t \u7ed3\u5c3e\u4e14\u4e2d\u95f4\u542b\u4efb\u610f\u4e24\u4e2a\u5b57\u7b26\u7684\u884c\uff0c\u5e76\u5728 t \u5b57\u6bcd\u540e\u6dfb\u52a0 er \u3002 $ sed -nr 's/r..t/&er/gp' /etc/passwd rooter:x:0:0:rooter:/rooter:/bin/bash lp:x:493:487:Printering daemon:/var/spool/lpd:/usr/sbin/nologin tftp:x:487:474:TFTP account:/srv/terftpboot:/bin/false vagranter:x:1000:478:vagranter:/home/vagranter:/bin/bash tester1:x:600:1530: \"Test User1,terestuser1@abc.com\" :/home/tester1:/bin/bash \u5c06\u4e0a\u8ff0\u7ed3\u679c\u548c\u539f\u59cb\u5185\u5bb9\u8fdb\u884c\u5bf9\u6bd4\uff0c\u80fd\u66f4\u597d\u7684\u7406\u89e3 s/r..t/&er \u7684\u64cd\u4f5c\u3002 rooter:x:0:0:rooter:/rooter:/bin/bash root:x:0:0:root:/root:/bin/bash lp:x:493:487:Printering daemon:/var/spool/lpd:/usr/sbin/nologin lp:x:493:487:Printing daemon:/var/spool/lpd:/usr/sbin/nologin tftp:x:487:474:TFTP account:/srv/terftpboot:/bin/false tftp:x:487:474:TFTP account:/srv/tftpboot:/bin/false vagranter:x:1000:478:vagranter:/home/vagranter:/bin/bash vagrant:x:1000:478:vagrant:/home/vagrant:/bin/bash tester1:x:600:1530: \"Test User1,terestuser1@abc.com\" :/home/tester1:/bin/bash tester1:x:600:1530: \"Test User1,testuser1@abc.com\" :/home/tester1:/bin/bash \u4f53\u4f1a & \u7684\u4f4d\u7f6e\u4e0d\u540c\u7684\u4e0d\u540c\u542b\u4e49\u3002 # \u9644\u52a0\u5728root\u5355\u8bcd\u540e $ sed -n 's/root/&superman/p' /etc/passwd rootsuperman:x:0:0:root:/root:/bin/bash # \u9644\u52a0\u5728root\u5355\u8bcd\u524d $ sed -n 's/root/superman&/p' /etc/passwd supermanroot:x:0:0:root:/root:/bin/bash \u4f7f\u7528\u53c2\u6570 -i \u8fdb\u884c\u6e90\u6587\u4ef6\u4fee\u6539\u3002 $ sed -i 's/ao/HH/' testfile $ cat testfile HELLO LINUX! Linux is a free unix-type opterating system. This is a linux testfile! Linux test Google THHbao Banbooob Tesetfile Wiki \u6e90\u6587\u4ef6\u4fee\u6539\u524d\uff0c\u5907\u4efd\u5728\u65b0\u6587\u4ef6 testfile.new \u3002 $ sed -i.new 's/ao/HH/' testfile $ cat testfile.new HELLO LINUX! Linux is a free unix-type opterating system. This is a linux testfile! Linux test Google Taobao Banbooob Tesetfile Wiki $ cat testfile HELLO LINUX! Linux is a free unix-type opterating system. This is a linux testfile! Linux test Google THHbao Banbooob Tesetfile Wiki \u8303\u4f8b\uff1a\u9664\u6307\u5b9a\u6587\u4ef6\u5916\uff0c\u5176\u4f59\u90fd\u5220\u9664\u3002 $ touch { 1 ..9 } file.txt $ ls 1file.txt 2file.txt 3file.txt 4file.txt 5file.txt 6file.txt 7file.txt 8file.txt 9file.txt $ ls | grep -E '(3|5|7)file\\.txt' 3file.txt 5file.txt 7file.txt $ ls | grep -Ev '(3|5|7)file\\.txt' 1file.txt 2file.txt 4file.txt 6file.txt 8file.txt 9file.txt \u4e0b\u9762\u56db\u79cd\u65b9\u6cd5\u5b9e\u73b0\u540c\u6837\u7684\u529f\u80fd $ rm ` ls | grep -Ev '(3|5|7)file\\.txt' ` $ ls | sed -n '/^[357]file.txt/!p' | xargs rm $ ls | grep -Ev '(3|5|7)file\\.txt' | sed -n 's/.*/rm &/p' | bash $ ls | grep -Ev '(3|5|7)file\\.txt' | sed -En 's/(.*)/rm &/p' | bash $ ls | grep -Ev '(3|5|7)file\\.txt' | sed -En 's/(.*)/rm \\1/p' | bash $ ls 3file.txt 5file.txt 7file.txt \u540e\u5411\u5f15\u7528 \\0 \\1 \\2 \u7b49\u3002 $ $echo 123456789 | sed -nE 's/(123)(456)(789)/\\1/p' 123 $ echo 123456789 | sed -nE 's/(123)(456)(789)/\\2/p' 456 $ echo 123456789 | sed -nE 's/(123)(456)(789)/\\3/p' 789 $ echo 123456789 | sed -nE 's/(123)(456)(789)/\\3\\1\\2/p' 789123456 $ echo 123456789 | sed -nE 's/(123)(456)(789)/\\1xyz\\2/p' 123xyz456 \u8303\u4f8b\uff1a\u83b7\u53d6\u5206\u533a\u5229\u7528\u7387 $ df | sed -En '/^\\/dev\\/sd/p' /dev/sda2 102750208 7079236 92053692 8 % / /dev/sda2 102750208 7079236 92053692 8 % /.snapshots /dev/sda2 102750208 7079236 92053692 8 % /boot/grub2/i386-pc /dev/sda2 102750208 7079236 92053692 8 % /boot/grub2/x86_64-efi /dev/sda2 102750208 7079236 92053692 8 % /home /dev/sda2 102750208 7079236 92053692 8 % /opt /dev/sda2 102750208 7079236 92053692 8 % /root /dev/sda2 102750208 7079236 92053692 8 % /srv /dev/sda2 102750208 7079236 92053692 8 % /usr/local /dev/sda2 102750208 7079236 92053692 8 % /tmp /dev/sda2 102750208 7079236 92053692 8 % /var $ df | sed -En '/^\\/dev\\/sd/s@.*([0-9]+)%.*@\\1@p' $ df | sed -En '/^\\/dev\\/sd/s#.*([0-9]+)%.*#\\1#p' # df | sed -En '/^\\/dev\\/sd/s/.*([0-9]+)%.*/\\1/p' 8 8 8 8 8 8 8 8 8 8 8 \u4f53\u4f1a\u4e0b\u9762\u7a7a\u683c\u548c\u62ec\u5f27\u5e26\u6765\u7684\u4e0d\u540c\u3002 $ df | sed -En '/^\\/dev\\/sd/s# .*([0-9]+)%.*# \\1#p' /dev/sda2 8 /dev/sda2 8 /dev/sda2 8 /dev/sda2 8 /dev/sda2 8 /dev/sda2 8 /dev/sda2 8 /dev/sda2 8 /dev/sda2 8 /dev/sda2 8 /dev/sda2 8 $ df | sed -En '/^\\/dev\\/sd/s#( .*)([0-9]+)%.*# \\1#p' /dev/sda2 102750208 7079804 92053156 /dev/sda2 102750208 7079804 92053156 /dev/sda2 102750208 7079804 92053156 /dev/sda2 102750208 7079804 92053156 /dev/sda2 102750208 7079804 92053156 /dev/sda2 102750208 7079804 92053156 /dev/sda2 102750208 7079804 92053156 /dev/sda2 102750208 7079804 92053156 /dev/sda2 102750208 7079804 92053156 /dev/sda2 102750208 7079804 92053156 /dev/sda2 102750208 7079804 92053156 $ df | sed -En '/^\\/dev\\/sd/s#( .*)([0-9]+)%.*# \\2#p' /dev/sda2 8 /dev/sda2 8 /dev/sda2 8 /dev/sda2 8 /dev/sda2 8 /dev/sda2 8 /dev/sda2 8 /dev/sda2 8 /dev/sda2 8 /dev/sda2 8 /dev/sda2 8 \u8303\u4f8b\uff1a\u53d6\u5f97\u5f53\u524dIP\u5730\u5740\u3002 $ ifconfig eth0 eth0: flags = 4163 mtu 1500 inet 192 .168.10.210 netmask 255 .255.255.0 broadcast 192 .168.10.255 inet6 fe80::20c:29ff:fea4:e17a prefixlen 64 scopeid 0x20 ether 00 :0c:29:a4:e1:7a txqueuelen 1000 ( Ethernet ) RX packets 22923 bytes 1658298 ( 1 .5 MiB ) RX errors 0 dropped 0 overruns 0 frame 0 TX packets 3763 bytes 442641 ( 432 .2 KiB ) TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0 $ ip addr show eth0 2 : eth0: mtu 1500 qdisc pfifo_fast state UP group default qlen 1000 link/ether 00 :0c:29:a4:e1:7a brd ff:ff:ff:ff:ff:ff altname enp2s1 altname ens33 inet 192 .168.10.210/24 brd 192 .168.10.255 scope global eth0 valid_lft forever preferred_lft forever inet6 fe80::20c:29ff:fea4:e17a/64 scope link valid_lft forever preferred_lft forever $ ifconfig eth0 | sed -En '2s/[^0-9]+([0-9.]+).*/\\1/p' $ ifconfig eth0 | sed -En '2s/^[^0-9]+([0-9.]{7,15}).*/\\1/p' $ ifconfig eth0 | sed -En '2s/^[^0-9]+([0-9.]{7,15}).*$/\\1/p' $ ifconfig eth0 | sed -n '2s/^.*inet //p' | sed -n 's/netmask.*//p' $ ifconfig eth0 | sed -n '2s/^.*inet //;s/ netmask.*//p' $ ifconfig eth0 | sed -En '2s/(.*inet )([0-9].*)(netmask.*)/\\2/p' 192 .168.10.210 192 .168.10.210 192 .168.10.210 \u4f7f\u7528 \\0 \u8f93\u51fa\u5168\u90e8\u53d8\u91cf\u3002 $ ifconfig eth0 | sed -En '2s/(.*inet )([0-9].*)(netmask.*)/\\0/p' inet 192 .168.10.210 netmask 255 .255.255.0 broadcast 192 .168.10.255 $ ifconfig eth0 | sed -En '2s/(.*inet )([0-9].*)(netmask.*)/\\1/p' inet $ ifconfig eth0 | sed -En '2s/(.*inet )([0-9].*)(netmask.*)/\\2/p' 192 .168.10.210 $ ifconfig eth0 | sed -En '2s/(.*inet )([0-9].*)(netmask.*)/\\3/p' netmask 255 .255.255.0 broadcast 192 .168.10.255 \u5bf9\u6bd4\u4e0b\u9762\u4e24\u4e2a\u6307\u4ee4\u7684\u5339\u914d\u5dee\u5f02\u3002 $ ifconfig eth0 | sed -n '2s/^.*inet //p' | sed -n 's/ netmask.*//p' 192 .168.10.210 $ ifconfig eth0 | sed -n '2s/^.*inet //p' | sed -n 's/netmask.* //p' 192 .168.10.210 192 .168.10.255 $ ifconfig eth0 | sed -n '2s/^.*inet //p' | sed -n 's/netmask .*//p' 192 .168.10.210 $ ifconfig eth0 | sed -n '2s/^.*inet //p' | sed -n 's/netmask.*//p' 192 .168.10.210 \u8303\u4f8b\uff1a\u53d6\u57fa\u540d\u548c\u76ee\u5f55\u540d\u3002 \uff08 /etc/sysconfig/network-scripts/ \u76ee\u5f55\u5728Rocky9\u4e2d\u9ed8\u8ba4\u5df2\u521b\u5efa\uff0c\u5728openSUSE\u548cUbuntu\u4e2d\u6ca1\u6709\uff09 # \u53d6\u76ee\u5f55\u540d $ echo \"/etc/sysconfig/network-scripts/\" | sed -E 's#(^/.*/)([^/]+/?)#\\1#' $ echo \"/etc/sysconfig/network-scripts/\" | sed -E 's/(^\\/.*\\/)([^\\/]+\\/?)/\\1/' /etc/sysconfig/ # \u53d6\u57fa\u540d $ echo \"/etc/sysconfig/network-scripts/\" | sed -E 's#(^/.*/)([^/]+/?)#\\2#' $ echo \"/etc/sysconfig/network-scripts/\" | sed -E 's/(^\\/.*\\/)([^\\/]+\\/?)/\\2/' network-scripts/ # \u53d6\u76ee\u5f55\u540d $ echo \"/etc/sysconfig/network-scripts/dummyfile\" | sed -E 's#(^/.*/)([^/]+/?)#\\1#' $ echo \"/etc/sysconfig/network-scripts/dummyfille\" | sed -E 's/(^\\/.*\\/)([^\\/]+\\/?)/\\1/' /etc/sysconfig/network-scripts/ # \u53d6\u57fa\u540d $ echo \"/etc/sysconfig/network-scripts/dummyfile\" | sed -E 's#(^/.*/)([^/]+/?)#\\2#' $ echo \"/etc/sysconfig/network-scripts/dummyfille\" | sed -E 's/(^\\/.*\\/)([^\\/]+\\/?)/\\2/' dummyfille \u8303\u4f8b\uff1a\u53d6\u6587\u4ef6\u540d\u548c\u6587\u4ef6\u6269\u5c55\u540d $ echo 1_.file.tar.gz | sed -En 's/(.*)\\.([^.]+)$/\\1/p' $ echo 1_.file.tar.gz | sed -En 's@(.*)\\.([^.]+)$@\\1@p' 1_.file.tar $ echo 1_.file.tar.gz | sed -En 's/(.*)\\.([^.]+)$/\\2/p' $ echo 1_.file.tar.gz | sed -En 's@(.*)\\.([^.]+)$@\\2@p' gz $ echo 1_.file.tar.gz | grep -Eo '.*\\.' 1_.file.tar. $ echo 1_.file.tar.gz | grep -Eo '[^.]+$' gz \u8303\u4f8b\uff1a\u5c06\u975e # \u5f00\u5934\u7684\u884c\u6dfb\u52a0 # $ cat < testfile HELLO LINUX! Linux is a free unix-type opterating system. This is a linux testfile! Linux test Google Taobao Banbooob #Tesetfile #Wiki EOF $ sed -En 's/^[^#]/#&/p' testfile $ sed -En 's/^[^#](.*)/#\\1/p' testfile #HELLO LINUX! #Linux is a free unix-type opterating system. #This is a linux testfile! #Linux test #Google #Taobao #Banbooob \u8303\u4f8b\uff1a\u5c06 # \u5f00\u5934\u7684\u884c\u5220\u9664 # $ cat < testfile HELLO LINUX! Linux is a free unix-type opterating system. This is a linux testfile! Linux test Google Taobao Banbooob #Tesetfile #Wiki EOF $ sed -Ei.bak '/^#/s/^#//' testfile $ cat testfile HELLO LINUX! Linux is a free unix-type opterating system. This is a linux testfile! Linux test Google Taobao Banbooob Tesetfile Wiki sed \u4fdd\u6301\u7a7a\u95f4\uff08hold space\uff09\u7684\u4f8b\u5b50\uff1a d \uff1a\u5220\u9664pattern space\u7684\u5185\u5bb9\uff0c\u5f00\u59cb\u4e0b\u4e00\u4e2a\u5faa\u73af\u3002 D \uff1a\u5982\u679c\u6a21\u5f0f\u7a7a\u95f4\u4fdd\u62a4\u6362\u884c\u7b26\uff0c\u5219\u5220\u9664\u76f4\u5230\u7b2c\u4e00\u4e2a\u6362\u884c\u7b26\u5230\u6a21\u5f0f\u7a7a\u95f4\u4e2d\u7684\u6587\u672c\uff0c\u5e76\u4e0d\u8bfb\u53d6\u65b0\u7684\u8f93\u5165\u884c\uff0c\u800c\u4f7f\u7528\u5408\u6210\u7684\u6a21\u5f0f\u7a7a\u95f4\u91cd\u65b0\u542f\u52a8\u5faa\u73af\u3002\u5982\u679c\u6a21\u5f0f\u7a7a\u95f4\u4e0d\u5305\u542b\u6362\u884c\u7b26\uff0c\u5219\u7c7b\u4f3c d \u547d\u4ee4\u542f\u52a8\u6b63\u5e38\u7684\u65b0\u5faa\u73af\u3002 h \u3001 H \uff1a\u590d\u5236/\u8ffd\u52a0\u6a21\u5f0f\u7a7a\u95f4\u7684\u5185\u5bb9\u5230\u4fdd\u6301\u7a7a\u95f4\u3002 g \u3001 G \uff1a\u590d\u5236/\u8ffd\u52a0\u4fdd\u6301\u7a7a\u95f4\u7684\u5185\u5bb9\u5230\u6a21\u5f0f\u7a7a\u95f4\u3002 n \u3001 N \uff1a\u590d\u5236/\u8ffd\u52a0\u5339\u914d\u5230\u7684\u4e0b\u4e00\u884c\u5230\u6a21\u5f0f\u7a7a\u95f4\u3002 p\uff1a\u6253\u5370\u5f53\u524d\u6a21\u5f0f\u7a7a\u95f4\u5185\u5bb9\u3002 P\uff1a\u6253\u5370\u6a21\u5f0f\u7a7a\u95f4\u5f00\u5934\u81f3 \\n \u7684\u5185\u5bb9\uff0c\u5e76\u8ffd\u52a0\u5230\u9ed8\u8ba4\u8f93\u51fa\u4e4b\u524d\u3002 x \uff1a\u4ea4\u6362\u4fdd\u6301\u7a7a\u95f4\u548c\u6a21\u5f0f\u7a7a\u95f4\u7684\u5185\u5bb9. \u4e3e\u4f8b\u89e3\u8bfb1\uff1a seq 10 \u547d\u4ee4\u8f93\u51fa1\uff5e10\u4e2a\u6570\u5b57\uff0c\u6bcf\u4e2a\u6570\u5b57\u4e00\u884c\u3002 sed \u547d\u4ee4\u8bfb\u53d6\u7b2c\u4e00\u884c 1 \u5230\u6a21\u5f0f\u7a7a\u95f4\u3002\u56e0\u4e3a\u53c2\u6570 -n \uff0c\u6240\u4ee5\u8bfb\u53d6\u5230\u7684 1 \u4e0d\u6253\u5370\u5230\u5c4f\u5e55\u3002 \u6267\u884c n \u547d\u4ee4\uff0c\u5373\u8bfb\u53d6\u5339\u914d\u5230\u7684\u4e0b\u4e00\u884c\u5230\u6a21\u5f0f\u7a7a\u95f4\uff0c\u5373\u628a\u7b2c\u4e8c\u884c\u7684 2 \u8bfb\u53d6\u5e76\u8986\u76d6\u5230\u6a21\u5f0f\u7a7a\u95f4\u3002 \u6267\u884c p \u547d\u4ee4\uff0c\u628a 2 \u8f93\u51fa\u5230\u5c4f\u5e55\u3002 \u4ee5\u6b64\u7c7b\u63a8\uff0c\u8bfb\u53d6\u7b2c\u4e09\u884c\u7684 3 \u5230\u6a21\u5f0f\u7a7a\u95f4\uff0c\u6267\u884c n \u547d\u4ee4\uff0c\u5c06\u7b2c\u56db\u884c\u7684 4 \u8bfb\u53d6\u5e76\u8986\u76d6\u5230\u6a21\u5f0f\u7a7a\u95f4\u3002\u6267\u884c p \u547d\u4ee4\uff0c\u8f93\u51fa 4 \u5230\u5c4f\u5e55\u3002 \u4ee5\u6b64\u7c7b\u63a8\u3002 $ seq 10 | sed -n 'n;p' 2 4 6 8 10 seq 10 | sed 'n;p' 1 2 2 3 4 4 5 6 6 7 8 8 9 10 10 \u4e3e\u4f8b\u89e3\u8bfb2\uff1a seq 10 \u547d\u4ee4\u8f93\u51fa1\uff5e10\u4e2a\u6570\u5b57\uff0c\u6bcf\u4e2a\u6570\u5b57\u4e00\u884c\u3002 sed \u547d\u4ee4\u8bfb\u53d6\u7b2c\u4e00\u884c\u5230 1 \u5230\u6a21\u5f0f\u7a7a\u95f4\uff08\u8986\u76d6\uff09\u3002 \u6267\u884c\u547d\u4ee4 N \uff0c\u5373\u8bfb\u53d6\u4e0b\u4e00\u884c\uff0c\u5373\u7b2c\u4e8c\u884c\u7684 2 \uff0c\u8ffd\u52a0\u5230\u6a21\u5f0f\u7a7a\u95f4\u3002\u6240\u4ee5\u5f53\u524d\u6a21\u5f0f\u7a7a\u95f4\u6709 1 \u548c 2 \u8fd92\u884c\u8bb0\u5f55\u3002 \u6267\u884c s/\\n// \uff0c\u628a\u6a21\u5f0f\u7a7a\u95f4\u4e2d\u7684\u7b2c\u4e00\u884c\u7684 1 \u540e\u9762\u7684 \\n \u66ff\u6362\u4e3a\u7a7a\uff0c\u5373\uff0c\u539f\u6765\u6a21\u5f0f\u7a7a\u95f4\u7684\u4e24\u884c 1 \u548c 2 \u73b0\u5728\u5408\u5e76\u4e3a\u4e00\u884c\uff0c\u5373 12 \u3002 \u8bfb\u53d6\u7b2c\u4e09\u884c\u7684 3 \u5230\u6a21\u5f0f\u7a7a\u95f4\uff08\u8986\u76d6\uff09\u3002 \u6267\u884c\u547d\u4ee4 N \uff0c\u5373\u8bfb\u53d6\u4e0b\u4e00\u884c\uff0c\u5373\u7b2c\u56db\u884c\u7684 4 \uff0c\u8ffd\u52a0\u5230\u6a21\u5f0f\u7a7a\u95f4\u3002\u6240\u4ee5\u5f53\u524d\u6a21\u5f0f\u7a7a\u95f4\u6709 3 \u548c 4 \u8fd92\u884c\u8bb0\u5f55\u3002 \u6267\u884c s/\\n// \uff0c\u628a\u6a21\u5f0f\u7a7a\u95f4\u4e2d\u7684\u7b2c\u4e00\u884c 3 \u540e\u9762\u7684 \\n \u66ff\u6362\u4e3a\u7a7a\uff0c\u5373\uff0c\u539f\u6765\u6a21\u5f0f\u7a7a\u95f4\u7684\u4e24\u884c 3 \u548c 4 \u73b0\u5728\u5408\u5e76\u4e3a\u4e00\u884c\uff0c\u5373 34 \u3002 \u4ee5\u6b64\u7c7b\u63a8\u3002 $ seq 10 | sed 'N;s/\\n//' 12 34 56 78 910 \u4e3e\u4f8b\u89e3\u8bfb3\uff1a seq 10 \u547d\u4ee4\u8f93\u51fa1\uff5e10\u4e2a\u6570\u5b57\uff0c\u6bcf\u4e2a\u6570\u5b57\u4e00\u884c\u3002 sed \u547d\u4ee4\u8bfb\u53d6\u7b2c\u4e00\u884c\u5230 1 \u5230\u6a21\u5f0f\u7a7a\u95f4\uff08\u8986\u76d6\uff09\u3002 \u6267\u884c !G \uff0c\u5373\u5bf9\u7b2c\u4e00\u884c\u7684 1 \u4e0d\u6267\u884c G \u547d\u4ee4\u3002 \u6267\u884c h \u547d\u4ee4\uff0c\u5373\u628a 1 \u4ece\u6a21\u5f0f\u7a7a\u95f4\u8986\u76d6\u81f3\u4fdd\u6301\u7a7a\u95f4\u3002\u81f3\u6b64\uff0c\u4fdd\u6301\u7a7a\u95f4\u548c\u6a21\u5f0f\u7a7a\u95f4\u90fd\u5b58\u6709 1 \u3002 \u6267\u884c $!d \uff0c\u5373\u4e0d\u662f\u6700\u540e\u4e00\u884c\u5c31\u4ece\u6a21\u5f0f\u7a7a\u95f4\u5220\u9664\uff0c\u6240\u4ee5\u628a 1 \u4ece\u6a21\u5f0f\u7a7a\u95f4\u4e2d\u5220\u9664\u3002 sed \u547d\u4ee4\u8bfb\u53d6\u7b2c\u4e8c\u884c\u5230 2 \u5230\u6a21\u5f0f\u7a7a\u95f4\uff08\u8986\u76d6\uff09\u3002 \u6267\u884c !G \uff0c\u5373\u5bf9\u7b2c\u4e8c\u884c\u7684 2 \u6267\u884c G \u547d\u4ee4\uff0c\u628a 1 \u4ece\u4fdd\u6301\u7a7a\u95f4\u8ffd\u52a0\u5230\u6a21\u5f0f\u7a7a\u95f4\u3002\u81f3\u6b64\uff0c\u4fdd\u6301\u7a7a\u95f4\u5b58\u6709 1 \uff0c\u6a21\u5f0f\u7a7a\u95f4\u5b58\u6709 2 \u548c 1 \u3002 \u6267\u884c h \u547d\u4ee4\uff0c\u5373\u628a 2 \u548c 1 \u4ece\u6a21\u5f0f\u7a7a\u95f4\u8986\u76d6\u81f3\u4fdd\u6301\u7a7a\u95f4\u3002\u81f3\u6b64\uff0c\u4fdd\u6301\u7a7a\u95f4\u548c\u6a21\u5f0f\u7a7a\u95f4\u90fd\u5b58\u6709 2 \u548c 1 \u3002 \u6267\u884c $!d \uff0c\u5373\u4e0d\u662f\u6700\u540e\u4e00\u884c\u5c31\u4ece\u6a21\u5f0f\u7a7a\u95f4\u5220\u9664\uff0c\u6240\u4ee5\u628a 2 \u548c 1 \u4ece\u6a21\u5f0f\u7a7a\u95f4\u4e2d\u5220\u9664\u3002 \u4ee5\u6b64\u7c7b\u63a8\uff0c\u76f4\u81f3\u8bfb\u53d6\u6700\u540e\u4e00\u884c10\u3002\u6b64\u65f6\uff0c\u6a21\u5f0f\u7a7a\u95f4\u662f 10 \uff0c\u4fdd\u6301\u7a7a\u95f4\u5b58\u6709 9 \u3001 8 \u3001 7 \u3001 6 \u3001 5 \u3001 4 \u3001 3 \u3001 2 \u3001 1 \u3002 \u6267\u884c !G \uff0c\u5373\u5bf9\u6700\u540e\u4e00\u884c\u7684 10 \u6267\u884c G \u547d\u4ee4\uff0c\u628a 9 \u3001 8 \u3001 7 \u3001 6 \u3001 5 \u3001 4 \u3001 3 \u3001 2 \u3001 1 \u4ece\u4fdd\u6301\u7a7a\u95f4\u8ffd\u52a0\u5230\u6a21\u5f0f\u7a7a\u95f4\u3002\u81f3\u6b64\uff0c\u4fdd\u6301\u7a7a\u95f4\u5b58\u6709 9 \u3001 8 \u3001 7 \u3001 6 \u3001 5 \u3001 4 \u3001 3 \u3001 2 \u3001 1 \u3002\uff0c\u6a21\u5f0f\u7a7a\u95f4\u5b58\u6709 10 \u3001 9 \u3001 8 \u3001 7 \u3001 6 \u3001 5 \u3001 4 \u3001 3 \u3001 2 \u3001 1 \u3002 \u6267\u884c h \u547d\u4ee4\uff0c\u5373\u628a 10 \u3001 9 \u3001 8 \u3001 7 \u3001 6 \u3001 5 \u3001 4 \u3001 3 \u3001 2 \u3001 1 \u4ece\u6a21\u5f0f\u7a7a\u95f4\u8986\u76d6\u81f3\u4fdd\u6301\u7a7a\u95f4\u3002\u81f3\u6b64\uff0c\u4fdd\u6301\u7a7a\u95f4\u548c\u6a21\u5f0f\u7a7a\u95f4\u90fd\u5b58\u6709 10 \u3001 9 \u3001 8 \u3001 7 \u3001 6 \u3001 5 \u3001 4 \u3001 3 \u3001 2 \u3001 1 \u3002 \u6267\u884c $!d \uff0c\u5f53\u524d\u662f\u6700\u540e\u4e00\u884c\uff0c\u6240\u4ee5\u4e0d\u4ece\u6a21\u5f0f\u7a7a\u95f4\u5220\u9664\u5f53\u524d\u5185\u5bb9\u3002 \u8f93\u51fa\u6a21\u5f0f\u7a7a\u95f4\u5185\u5bb9\u81f3\u5c4f\u5e55\u3002\u537310\uff5e1\u3002 $ seq 10 | sed '1!G;h;$!d' 10 9 8 7 6 5 4 3 2 1 \u5176\u4ed6\u4e00\u4e9b\u4f8b\u5b50\uff1a $ seq 10 | sed -n '/3/{g;1!p;};h' 2 $ seq 10 | sed -nr '/3/{n;p}' 4 $ seq 10 | sed 'N;D' 10 $ seq 10 | sed '3h;9G;9!d' 9 3 $ seq 10 | sed '$!N;$!D' 9 10 $ seq 10 | sed '$!d' 10 $ seq 10 | sed 'G' 1 2 3 4 5 6 7 8 9 10 $ seq 10 | sed 'g' $ seq 10 | sed '/^$/d;G' 1 2 3 4 5 6 7 8 9 10 $ seq 10 | sed 'n;d' 1 3 5 7 9 $ seq 10 | sed -n '1!G;h;$p' 10 9 8 7 6 5 4 3 2 1","title":"5.9.\u4e09\u5251\u5ba2sed\u547d\u4ee4"},{"location":"linux/SRE/05-RegExpress/#510awk","text":"awk \u662f\u4e00\u4e2a\u6587\u672c\u5206\u6790\u5de5\u5177\u3002 grep \u64c5\u957f\u67e5\u627e\uff0c sed \u64c5\u957f\u7f16\u8f91\uff0c awk \u64c5\u957f\u6570\u636e\u5206\u6790\u5e76\u751f\u6210\u62a5\u544a\u3002 awk \u7684\u540d\u79f0\u5f97\u81ea\u4e8e\u5b83\u7684\u521b\u59cb\u4ebaAlfred Aho \u3001Peter Weinberger \u548c Brian Kernighan \u59d3\u6c0f\u7684\u9996\u4e2a\u5b57\u6bcd\u3002 awk \u67093\u4e2a\u4e0d\u540c\u7248\u672c: awk \u3001 nawk \u548c gawk \u3002\u6211\u4eec\u8bf4\u7684 awk \u4e00\u822c\u6307 gawk \u3002 gawk \u662f awk \u7684GNU\u7248\u672c\u3002 awk \u628a\u6587\u4ef6\u9010\u884c\u8bfb\u5165\uff0c\u4ee5\u7a7a\u683c\u4e3a\u9ed8\u8ba4\u5206\u9694\u7b26\u5c06\u6bcf\u884c\u5207\u7247\uff0c\u518d\u5bf9\u5207\u7247\u8fdb\u884c\u5206\u6790\u5904\u7406\u3002","title":"5.10.\u4e09\u5251\u5ba2awk\u547d\u4ee4"},{"location":"linux/SRE/05-RegExpress/#5101","text":"awk 'pattern{action statements;...}' {filenames} pattern \u8868\u793a awk \u5728\u6570\u636e\u4e2d\u67e5\u627e\u7684\u5185\u5bb9\u3002\u662f\u8981\u8868\u793a\u7684\u6b63\u5219\u8868\u8fbe\u5f0f\uff0c\u7528\u659c\u6760\u62ec\u8d77\u6765\u3002 action \u662f\u5728\u627e\u5230\u5339\u914d\u5185\u5bb9\u65f6\u6240\u6267\u884c\u7684\u4e00\u7cfb\u5217\u547d\u4ee4\u3002 -F \uff1a\u6307\u5b9a\u5206\u9694\u7b26\uff0c\u540e\u9762\u7d27\u8ddf\u5355\u5f15\u53f7\uff0c\u5355\u5f15\u53f7\u5185\u662f\u5206\u9694\u7b26\u3002\u5982\u4e0d\u52a0 -F \u9009\u9879\uff0c\u5219\u4ee5\u7a7a\u683c\u6216\u8005tab\u4f5c\u4e3a\u5206\u9694\u7b26\u3002 -v \uff1avar=value\uff0c\u53d8\u91cf\u8d4b\u503c\u3002 \u63d0\u793a\uff1a -F \"\" \u6307\u5b9a\u7a7a\u5b57\u7b26\u4e32\u4f5c\u4e3a\u5b57\u6bb5\u5206\u9694\u7b26\uff0c\u4ece\u800c\u5c06\u8f93\u5165\u5b57\u7b26\u4e32\u4e2d\u7684\u6bcf\u4e2a\u5b57\u7b26\u4f5c\u4e3a\u4e00\u4e2a\u72ec\u7acb\u7684\u5b57\u6bb5\u8fdb\u884c\u5904\u7406\u3002\u7136\u540e\uff0c\u4f7f\u7528\u5faa\u73af\u904d\u5386\u6bcf\u4e2a\u5b57\u6bb5\uff0c\u5982\u679c\u5b57\u6bb5\u4e2d\u5305\u542b\u6570\u5b57\uff0c\u5219\u5c06\u5176\u6dfb\u52a0\u5230str1\u53d8\u91cf\u4e2d\u3002\u6700\u540e\uff0c\u6253\u5370str1\u7684\u503c\u3002 -F '' \u4e2d\u7684\u4e24\u4e2a\u5355\u5f15\u53f7\u4e4b\u95f4\u6ca1\u6709\u63d0\u4f9b\u6709\u6548\u7684\u5b57\u6bb5\u5206\u9694\u7b26\u3002\u5728awk\u4e2d\uff0c\u5b57\u6bb5\u5206\u9694\u7b26\u5fc5\u987b\u662f\u4e00\u4e2a\u975e\u7a7a\u5b57\u7b26\u4e32\u3002 \u793a\u4f8b\uff1a\u7b2c\u4e00\u4e2a\u548c\u7b2c\u4e09\u4e2a\u547d\u4ee4\u662f\u6b63\u786e\u7684\u3002 $ echo 'Yd$@C#M05MD9&8923+Vip3wZ!33*44&55' | awk -F \"\" '{for(i=1;i<=NF;i++){if($i ~ /[[:digit:]]/){str=$i;str1=(str1 str)}};print str1}' 05989233334455 $ echo 'Yd$@C#M05MD9&8923+Vip3wZ!33*44&55' | awk -F \"\" '{for(i=1;i<=NF;i++){if($i ~ /[[:digit:]]/){str=$i;str1=(str1 str)}};print str1}' $ echo 'Yd$@C#M05MD9&8923+Vip3wZ!33*44&55' | awk -F '' '{for(i=1;i<=NF;i++){if($i ~ /[[:digit:]]/){str=$i;str1=(str1 str)}};print str1}' 05989233334455 $ echo 'Yd$@C#M05MD9&8923+Vip3wZ!33*44&55' | awk -F '' '{for(i=1;i<=NF;i++){if($i ~ /[[:digit:]]/){str=$i;str1=(str1 str)}};print str1}'","title":"5.10.1.\u547d\u4ee4\u683c\u5f0f"},{"location":"linux/SRE/05-RegExpress/#5102","text":"\u6267\u884cBEGIN{action;...}\u8bed\u53e5\u5757\u4e2d\u7684\u8bed\u53e5\u3002 BEGIN\u8bed\u53e5\u5757\u518dawk\u8bfb\u5165\u8f93\u5165\u6d41\u4e4b\u524d\u88ab\u6267\u884c\u3002 \u662f\u53ef\u9009\u8bed\u53e5\u5757\u3002 \u5305\u542b\u521d\u59cb\u5316\u53d8\u91cf\uff0c\u6253\u5370\u8f93\u51fa\u8868\u683c\u7684\u8868\u5934\u7b49\u8bed\u53e5\u3002 \u4ece\u6587\u4ef6\u6216\u8005\u6807\u51c6\u8f93\u5165stdin\u8bfb\u53d6\u4e00\u884c\uff0c\u7136\u540e\u6267\u884cpattern{action;...}\u8bed\u53e5\u5757\u3002\u4ece\u7b2c\u4e00\u884c\u5f00\u59cb\u5230\u6700\u540e\u4e00\u884c\uff0c\u9010\u884c\u626b\u63cf\u6587\u4ef6\uff0c\u91cd\u590d\u8fd9\u4e2a\u52a8\u4f5c\uff0c\u76f4\u5230\u6587\u4ef6\u6216\u8005\u8f93\u5165\u6d41\u5168\u90e8\u88ab\u8bfb\u53d6\u5b8c\u6bd5\u3002 \u53ef\u9009\u8bed\u53e5\u5757\u3002 \u5982\u679c\u6ca1\u6709\u63d0\u4f9bpattern\u8bed\u53e5\u5757\uff0c\u5219\u9ed8\u8ba4\u6267\u884c{print}\u3002 \u5f53\u8bfb\u81f3\u6587\u4ef6\u6216\u8005\u8f93\u5165\u6d41\u672b\u5c3e\u65f6\uff0c\u6267\u884cEND{action;...}\u8bed\u53e5\u5757\uff0c\u6bd4\u5982\u6253\u5370\u6240\u6709\u884c\u7684\u5206\u6790\u7ed3\u679c\u8fd9\u7c7b\u6c47\u603b\u4fe1\u606f\u3002\u4e5f\u662f\u4e00\u4e2a\u53ef\u9009\u8bed\u53e5\u5757\u3002","title":"5.10.2.\u5de5\u4f5c\u8fc7\u7a0b"},{"location":"linux/SRE/05-RegExpress/#5103","text":"\u6709\u5206\u9694\u7b26\u5206\u9694\u7684\u5b57\u6bb5\uff08\u5217column\uff0c\u57dffield\uff09\uff0c\u6807\u8bb0 $1 \u3001 $2 \u3001 $3 \u3001...\u3001 $n \u79f0\u4e3a\u57df\u6807\u8bc6\uff0c $0 \u4e3a\u6240\u6709\u57df\u3002\u6ce8\u610f\uff0c\u548cshell\u53d8\u91cf\u4e2d\u7684 $ \u4e0d\u540c\u3002 \u6bcf\u4e00\u884c\u6210\u4e3a\u8bb0\u5f55\uff08record\uff09\u3002 \u5982\u679c\u7701\u7565action\uff0c\u5219\u9ed8\u8ba4\u6267\u884c print $0 \u64cd\u4f5c\u3002","title":"5.10.3.\u5206\u9694\u7b26\u3001\u57df\u548c\u8bb0\u5f55"},{"location":"linux/SRE/05-RegExpress/#5104action","text":"Output statements: print , printf Expressions: \u7b97\u672f\u3001\u6bd4\u8f83\u8868\u8fbe\u5f0f Compund statements: \u7ec4\u5408\u8bed\u53e5 Control statements: if , while \u8bed\u53e5 Input statements: \u52a8\u4f5c print \u683c\u5f0f\uff1a print item1, item2, ... \u8bf4\u660e\uff1a \u9017\u53f7\u5206\u9694\u7b26 \u8f93\u51faitem\u53ef\u4ee5\u662f\u5b57\u7b26\u4e32\uff0c\u4e5f\u53ef\u4ee5\u662f\u6570\u503c\uff0c\u662f\u5f53\u524d\u8bb0\u5f55\u7684\u5b57\u6bb5\u3001\u53d8\u91cf\u6216 awk \u8868\u8fbe\u5f0f\u3002 \u5982\u679c\u7701\u7565item\uff0c\u76f8\u5f53\u4e8e print $0 \u56fa\u5b9a\u5b57\u7b26\u9700\u8981\u7528\u53cc\u5f15\u53f7\uff0c\u800c\u53d8\u91cf\u548c\u6570\u5b57\u4e0d\u9700\u8981\u3002 \u793a\u4f8b\uff1a $ seq 5 | awk '{print \"hello awk\"}' hello awk hello awk hello awk hello awk hello awk $ seq 5 | awk '{print 3*5}' 15 15 15 15 15 $ awk -F ':' '{print \"hello\"}' /etc/passwd | head -5 hello hello hello hello hello $ awk -F ':' '{print}' /etc/passwd | head -5 root:x:0:0:root:/root:/bin/bash messagebus:x:499:499:User for D-Bus:/run/dbus:/usr/bin/false systemd-network:x:497:497:systemd Network Management:/:/usr/sbin/nologin systemd-timesync:x:496:496:systemd Time Synchronization:/:/usr/sbin/nologin nobody:x:65534:65534:nobody:/var/lib/nobody:/bin/bash $ awk -F ':' '{print $0}' /etc/passwd | head -5 root:x:0:0:root:/root:/bin/bash messagebus:x:499:499:User for D-Bus:/run/dbus:/usr/bin/false systemd-network:x:497:497:systemd Network Management:/:/usr/sbin/nologin systemd-timesync:x:496:496:systemd Time Synchronization:/:/usr/sbin/nologin nobody:x:65534:65534:nobody:/var/lib/nobody:/bin/bash $ awk -F ':' '{print $1,$3}' /etc/passwd | head -5 root 0 messagebus 499 systemd-network 497 systemd-timesync 496 nobody 65534 $ awk -F ':' '{print $1\"\\t\"$3}' /etc/passwd | head -5 root 0 messagebus 499 systemd-network 497 systemd-timesync 496 nobody 65534 $ grep \"^UUID\" /etc/fstab | awk '{print $2,$3}' / btrfs /var btrfs /usr/local btrfs /tmp btrfs /srv btrfs /root btrfs /opt btrfs /home btrfs /boot/grub2/x86_64-efi btrfs /boot/grub2/i386-pc btrfs /.snapshots btrfs swap swap \u793a\u4f8b\uff1a\u8bfb\u53d6\u5206\u533a\u5229\u7528\u7387\u3002 \u5206\u9694\u7b26\u4e2d\u7684\u5b9a\u4e49 [[:space:]]+|% \u7684\u542b\u4e49\uff0c\u4e00\u4e2a\u6216\u591a\u4e2a\u7a7a\u683c\u6216\u8005 % \u4f5c\u4e3a\u5206\u9694\u7b26\u3002 $ df | awk '{print $1,$5}' Filesystem Use% devtmpfs 0 % tmpfs 0 % tmpfs 2 % tmpfs 0 % /dev/sda2 8 % /dev/sda2 8 % /dev/sda2 8 % /dev/sda2 8 % /dev/sda2 8 % /dev/sda2 8 % /dev/sda2 8 % /dev/sda2 8 % /dev/sda2 8 % /dev/sda2 8 % /dev/sda2 8 % tmpfs 0 % $ df | grep '^/dev/sd' | awk -F '[[:space:]]+|%' '{print $1,$5}' $ df | grep '^/dev/sd' | awk -F ' +|%' '{print $1,$5}' /dev/sda2 8 /dev/sda2 8 /dev/sda2 8 /dev/sda2 8 /dev/sda2 8 /dev/sda2 8 /dev/sda2 8 /dev/sda2 8 /dev/sda2 8 /dev/sda2 8 /dev/sda2 8 \u793a\u4f8b\uff1a\u8bfb\u53d6ifconfig\u8f93\u51fa\u7ed3\u679c\u4e2d\u7684ip\u5730\u5740\u3002 $ ifconfig eth0 | sed -n '2p' | awk '/netmask/{print $2}' 192 .168.10.210 $ ifconfig eth0 | sed -n '2p' | awk '{print $2}' 192 .168.10.210","title":"5.10.4.\u5e38\u7528action\u5206\u7c7b"},{"location":"linux/SRE/05-RegExpress/#5105pattern","text":"\u6839\u636epattern\u6761\u4ef6\uff0c\u8fc7\u6ee4\u5339\u914d\u7684\u884c\uff0c\u518d\u505a\u5904\u7406\u3002 \u5982\u679c\u672a\u6307\u5b9a\uff0c\u5373\u7a7a\u6a21\u5f0f\uff0c\u5219\u5339\u914d\u6bcf\u4e00\u884c\u3002 /regular expression/ \uff0c\u4ec5\u5904\u7406\u80fd\u591f\u6a21\u5f0f\u5339\u914d\u5230\u7684\u884c\uff08\u5373\u7ed3\u679c\u4e3a\u771f\uff09\uff0c\u9700\u8981\u7528 / \u8fdb\u884c\u62ec\u8d77\u6765\u3002 \u7ed3\u679c\u4e3a\u771f\uff0c\u5373\u975e0\u503c\u3001\u975e\u7a7a\u5b57\u7b26\u4e32 \u7ed3\u679c\u4e3a\u5047\uff0c\u53730\u503c\u3001\u7a7a\u5b57\u7b26\u4e32 \u793a\u4f8b\uff1a\u7a7a\u6a21\u5f0f awk -F \":\" '{print $1, $3}' /etc/passwd | head -n5 root 0 messagebus 499 systemd-network 497 systemd-timesync 496 nobody 65534 \u793a\u4f8b\uff1a\u975e\u7a7a\u6a21\u5f0f $ seq 5 | awk '0' $ seq 5 | awk '1' 1 2 3 4 5 $ seq 5 | awk '2' 1 2 3 4 5 $ seq 5 | awk '\"true\"' 1 2 3 4 5 $ seq 5 | awk '\"false\"' 1 2 3 4 5 $ seq 5 | awk 'true' $ seq 5 | awk 'false' $ seq 5 | awk '' $ seq 5 | awk '\"\"' $ seq 5 | awk '\"0\"' 1 2 3 4 5 \u4f53\u4f1a\u4e0b\u9762\u53d8\u91cf\u7684\u503c\u548c\u6b63\u786e\u4f7f\u7528\u53d8\u91cf\uff08\u5b57\u7b26\u4e32\u8fd8\u662f\u53d8\u91cf\uff1f\uff09 $ seq 5 | awk '\"test\"' 1 2 3 4 5 $ seq 5 | awk 'test' $ seq 5 | awk -v test = 0 '\"test\"' $ seq 5 | awk -v test = 0 'test' $ seq 5 | awk -v test = \"0\" 'test' $ seq 5 | awk -v test = \"0\" '\"test\"' 1 2 3 4 5 $ seq 5 | awk -v test = 1 'test' 1 2 3 4 5 \u4f53\u4f1a\u4e0b\u9762\u7684\u4e0e\u975e\u5224\u65ad\u3002 $ awk '1' /etc/passwd | head -n3 root:x:0:0:root:/root:/bin/bash messagebus:x:499:499:User for D-Bus:/run/dbus:/usr/bin/false systemd-network:x:497:497:systemd Network Management:/:/usr/sbin/nologin $ awk '0' /etc/passwd | head -n3 $ awk '!1' /etc/passwd | head -n3 $ awk '!0' /etc/passwd | head -n3 root:x:0:0:root:/root:/bin/bash messagebus:x:499:499:User for D-Bus:/run/dbus:/usr/bin/false systemd-network:x:497:497:systemd Network Management:/:/usr/sbin/nologin # i\u6ca1\u6709\u8d4b\u503c\uff0c\u4e3a\u5047\uff0c\u6ca1\u6709\u8f93\u51fa $ seq 5 | awk 'i' # i\u8d4b\u503c\u4e3a0\uff0c\u4e3a\u5047\uff0c\u6ca1\u6709\u8f93\u51fa $ seq 5 | awk 'i=0' # i\u8d4b\u503c\u4e3a1\uff0c\u4e3a\u771f\uff0c\u8f93\u51fa\u7b2c\u4e00\u884c\u7ed3\u679c\uff0c\u4ee5\u6b64\u7c7b\u63a8\uff0c\u6bcf\u884c\u90fd\u4e3a\u771f\uff0c\u8f93\u51fa\u5168\u90e8seq\u7684\u7ed3\u679c $ seq 5 | awk 'i=1' 1 2 3 4 5 # \u7b2c\u4e00\u6b21\u521d\u59cbi\u672a\u8d4b\u503c\uff0c\u4e3a\u5047\uff0c!i\u5219\u4e3a\u771f\uff0c\u8d4b\u503c\u7ed9i\uff0c\u6240\u4ee5i\u4e3a\u771f,\u8f93\u51faseq\u7b2c1\u884c\u7ed3\u679c # \u7b2c\u4e8c\u6b21\u521d\u59cbi\u4e3a\u771f\uff0c!i\u5219\u4e3a\u5047\uff0c\u8d4b\u503c\u7ed9i\uff0c\u6240\u4ee5i\u4e3a\u5047\uff0c\u4e0d\u8f93\u51faseq\u7b2c2\u884c\u7ed3\u679c # \u7b2c\u4e09\u6b21\u521d\u59cbi\u4e3a\u5047\uff0c!i\u5219\u4e3a\u771f\uff0c\u8d4b\u503c\u7ed9i\uff0c\u6240\u4ee5i\u4e3a\u771f\uff0c\u8f93\u51faseq\u7b2c3\u884c\u7ed3\u679c # \u4ee5\u6b64\u7c7b\u63a8\uff0c\u8f93\u51faseq\u7ed3\u679c\u7684\u5947\u6570\u884c $ seq 5 | awk 'i=!i' 1 3 5 # \u4e0e\u4e0a\u4f8b\u7684\u533a\u522b\u5728\u4e8ei\u521d\u59cb\u503c\u672a\u771f\uff0c\u7b2c\u4e00\u6b21\u7684i\u503c\u4e3a\u5047\uff0c\u4e0d\u8f93\u51faseq\u7b2c1\u884c\u7ed3\u679c # \u7b2c\u4e8c\u6b21i\u7684\u521d\u59cb\u503c\u4e3a\u5047\uff0c\u901a\u8fc7i=!i\u53d8\u4e3a\u771f\uff0c\u6240\u4ee5\u8f93\u51faseq\u7684\u7b2c2\u884c\u7ed3\u679c # \u4ee5\u6b64\u7c7b\u63a8\uff0c\u8f93\u51faseq\u7ed3\u679c\u7684\u5076\u6570\u884c $ seq 5 | awk -v i = 1 'i=!i' 2 4 # \u8f93\u51fa\u8ba1\u6570\u884c $ seq 5 | awk -v i = 0 'i=!i' 1 3 5 # \u53ea\u8f93\u51fai\u7684\u503c\uff0c\u4e0d\u8f93\u51faseq\u7684\u503c $ seq 5 | awk '{i=!i;print i}' 1 0 1 0 1 $ seq 5 | awk '{i=!i}' $ seq 5 | awk '(i=!i)' 1 3 5 $ seq 5 | awk '!(i=!i)' 2 4","title":"5.10.5.\u6a21\u5f0fPattern"},{"location":"linux/SRE/05-RegExpress/#5106","text":"\u793a\u4f8b\uff1a $ head -n2 /etc/passwd | awk -F ':' '{print $0}' root:x:0:0:root:/root:/bin/bash messagebus:x:499:499:User for D-Bus:/run/dbus:/usr/bin/false $ head -n2 /etc/passwd | awk -F ':' '{print $2}' x x $ head -n2 /etc/passwd | awk -F ':' '{print $1}' root messagebus $ head -n2 /etc/passwd | awk -F ':' '{print $1\"#\"$2\"#\"$3\"#\"$4}' root#x#0#0 messagebus#x#499#499","title":"5.10.6.\u622a\u53d6\u7247\u6bb5"},{"location":"linux/SRE/05-RegExpress/#5107","text":"","title":"5.10.7.\u64cd\u4f5c\u7b26"},{"location":"linux/SRE/05-RegExpress/#51071","text":"x+y \uff0c x-y \uff0c x*y \uff0c x/y \uff0c x^y \uff0c x%y \u3002 -x \uff1a\u8f6c\u6362\u4e3a\u8d1f\u6570 +x \uff1a\u5c06\u5b57\u7b26\u4e32\u8f6c\u6362\u4e3a\u6570\u503c \u5217\u503c\u4e4b\u95f4\u8fdb\u884c\u7b97\u672f\u8fd0\u7b97\u3002 $ awk -F ':' '{$7=$3+$4;print $1,$3,$4,$7}' /etc/passwd | head -n5 root 0 0 0 messagebus 499 499 998 systemd-network 497 497 994 systemd-timesync 496 496 992 nobody 65534 65534 131068 \u8ba1\u7b97\u67d0\u4e2a\u5217\u7684\u603b\u548c\u3002 END \u8868\u793a\u6240\u6709\u7684\u884c\u90fd\u5df2\u7ecf\u6267\u884c\u3002 $ awk -F ':' '{(total=total+$3)}; END {print total}' /etc/passwd 103011","title":"5.10.7.1.\u7b97\u6570\u64cd\u4f5c\u7b26"},{"location":"linux/SRE/05-RegExpress/#51072","text":"\u6ca1\u6709\u64cd\u4f5c\u7b26\u53f7\uff0c\u5b57\u7b26\u4e32\u8fde\u63a5\u3002","title":"5.10.7.2.\u5b57\u7b26\u4e32\u64cd\u4f5c\u7b26"},{"location":"linux/SRE/05-RegExpress/#51073","text":"= \uff0c += \uff0c -= \uff0c *= \uff0c /= \uff0c %= \uff0c ^= \uff0c ++ \uff0c -- \u3002 \u793a\u4f8b\uff1a $ awk 'BEGIN{print i}' $ awk 'BEGIN{print i++}' #\u4ece0\u5f00\u59cb 0 $ awk 'BEGIN{print ++i}' 1 $ awk 'BEGIN{print i++, i}' 0 1 $ awk 'BEGIN{i=0;print i++, i}' 0 1 $ awk 'BEGIN{print ++i, i}' 1 1 $ awk 'BEGIN{i=0;print ++i, i}' 1 1 $ awk 'BEGIN{i=0;print i, i++}' 0 0 $ awk 'BEGIN{i=0;print i, ++i}' 0 1 $ seq 10 1 2 3 4 5 6 7 8 9 10 # n\u4ece0\u5f00\u59cb\u8ba1\u6570\uff0c\u8f93\u51fa\u7684\u662fn\u503c\uff0c\u4e0d\u662fseq\u7684\u8f93\u51fa\u7ed3\u679c $ seq 10 | awk '{print n++}' 0 1 2 3 4 5 6 7 8 9 # seq=1\u65f6\uff0c\u521d\u59cbn\u672a\u8d4b\u503c\uff0c\u4e3a\u5047\uff0c\u4e0d\u8f93\u51faseq\u7ed3\u679c\uff0cn++\u4e3a\u771f # seq=2\u65f6\uff0cn\u4e3a\u771f\uff0c\u8f93\u51faseq\u7ed3\u679c\uff0cn++\u4e3a\u771f # \u540e\u7eedn++\u90fd\u4e3a\u771f\uff0c\u6240\u4ee5seq\u7684\u7ed3\u679c\u51fa\u4e86\u7b2c\u4e00\u884c\u7531\u4e8en\u4e3a\u5047\u6ca1\u6709\u8f93\u51fa\uff0c\u5176\u4ed6\u884c\u90fd\u8f93\u51fa $ seq 10 | awk 'n++' 2 3 4 5 6 7 8 9 10 # \u53c2\u8003\u4e0a\u4f8b\uff0cn\u521d\u59cb\u672a\u8d4b\u503c\uff0c\u4f46\u6267\u884c++n\u540e\u4e3a\u771f\uff0c\u6240\u4ee5\u8f93\u51fa\u7b2c\u4e00\u884c\uff0c\u540e\u7eed\u884c\u90fd\u8f93\u51fa\u56e0\u4e3an\u4e00\u76f4\u4e3a\u771f $ seq 10 | awk '++n' 1 2 3 4 5 6 7 8 9 10 # n=0\u65f6++n=1\uff0c!++n=0\uff0c\u8f93\u51fa\u7b2c0\u884c $ awk -v n = 0 '!++n' /etc/passwd # n=0\u65f6n++=1\uff0c!n++=1\uff0c\u8f93\u51fa\u7b2c1\u884c $ awk -v n = 0 '!n++' /etc/passwd root:x:0:0:root:/root:/bin/bash $ awk -v n = 0 '!n++{print n}' /etc/passwd 1 # \u65e0\u7ed3\u679c\u8f93\u51fa $ awk -v n = 0 '!++n{print n}' /etc/passwd $ awk -v n = 1 '!n++{print n}' /etc/passwd $ awk -v n = 0 '!n++' /etc/passwd root:x:0:0:root:/root:/bin/bash # \u65e0\u7ed3\u679c\u8f93\u51fa $ awk -v n = 1 '!n++' /etc/passwd $ awk -v n = 2 '!n++' /etc/passwd","title":"5.10.7.3.\u8d4b\u503c\u64cd\u4f5c\u7b26"},{"location":"linux/SRE/05-RegExpress/#51074","text":"\u4f7f\u7528 == \u4ee3\u8868\u7b49\u4e8e\uff0c\u5373\u7cbe\u786e\u5339\u914d\u3002\u7c7b\u4f3c\u8fd8\u6709 > \u3001 >= \u3001 < \u3001 <= \u3001 != \u7b26\u53f7\u3002 \u4ee5 : \u4e3a\u5206\u9694\u7b26\uff0c\u5339\u914d\u7b2c\u4e09\u5217\u7684\u503c\u4e3a 1000 \u7684\u884c\u3002 $ awk -F ':' '$3==\"100\"' /etc/passwd vagrant:x:1000:478:vagrant:/home/vagrant:/bin/bash \u5728\u548c\u6570\u5b57\u6bd4\u8f83\u65f6\uff0c\u82e5\u628a\u8981\u6bd4\u8f83\u7684\u6570\u5b57\u7528\u53cc\u5f15\u53f7\u5f15\u8d77\u6765\uff0c awk \u4f1a\u6309\u5b57\u7b26\u5904\u7406\uff0c\u4e0d\u52a0\u53cc\u5f15\u53f7\uff0c\u5219\u4f1a\u6309\u6570\u5b57\u5904\u7406\u3002 $ awk -F ':' '$3<=\"100\"' /etc/passwd root:x:0:0:root:/root:/bin/bash bin:x:1:1:bin:/bin:/usr/sbin/nologin $ awk -F ':' '$3<=100' /etc/passwd root:x:0:0:root:/root:/bin/bash postfix:x:51:51:Postfix Daemon:/var/spool/postfix:/usr/sbin/nologin man:x:13:62:Manual pages viewer:/var/lib/empty:/usr/sbin/nologin daemon:x:2:2:Daemon:/sbin:/usr/sbin/nologin at:x:25:25:Batch jobs daemon:/var/spool/atjobs:/usr/sbin/nologin bin:x:1:1:bin:/bin:/usr/sbin/nologin awk -F ':' '{if ($1==\"root\") {print $0}}' /etc/passwd awk -F ':' '$7!=\"/bin/false\"' /etc/passwd awk -F ':' '$3<$2' /etc/passwd","title":"5.10.7.4.\u6bd4\u8f83\u64cd\u4f5c\u7b26"},{"location":"linux/SRE/05-RegExpress/#51075","text":"&& \u8868\u793a\u201c\u5e76\u4e14\u201d || \u8868\u793a\u201c\u6216\u8005\u201d ! \u8868\u793a\u201c\u975e\u201d\uff08\u53d6\u53cd\uff09 awk -F ':' '$3>10 && $3<100' /etc/passwd awk -F ':' '$3>10 || $3<100' /etc/passwd awk -F ':' '($3==0)' /etc/passwd awk -F ':' '!($3==0)' /etc/passwd \u6ce8\u610f\u4e0b\u9762\u5bf9\u5b57\u7b26\u548c\u6570\u503c\u8fdb\u884c\u53d6\u53cd\u64cd\u4f5c\u7684\u7ed3\u679c\u3002 $ awk 'BEGIN{print i}' $ awk 'BEGIN{print !i}' 1 $ awk -v i = 10 'BEGIN{print i}' 10 $ awk -v i = 10 'BEGIN{print !i}' 0 $ awk -v i = -5 'BEGIN{print i}' -5 $ awk -v i = -5 'BEGIN{print !i}' 0 $ awk -v i = \"abc\" 'BEGIN{print i}' abc $ awk -v i = \"abc\" 'BEGIN{print !i}' 0 $ awk -v i = abc 'BEGIN{print i}' abc $ awk -v i = abc 'BEGIN{print !i}' 0 $ awk -v i = \"\" 'BEGIN{print i}' $ awk -v i = \"\" 'BEGIN{print !i}' 1 \u5728\u5206\u9694\u7b26\u5b9a\u4e49\u4e2d\u4f7f\u7528\u6b63\u5219\u8868\u8fbe\u5f0f\u3002 $ df | awk -F \" +|%\" '{print $5}' Use 0 0 2 0 8 8 8 8 8 8 8 8 8 8 8 0 $ df | awk -F \"[[:space:]]+|%\" '{print $5}' Use 0 0 2 0 8 8 8 8 8 8 8 8 8 8 8 0","title":"5.10.7.5.\u903b\u8f91\u64cd\u4f5c\u7b26"},{"location":"linux/SRE/05-RegExpress/#51076","text":"\u683c\u5f0f\uff1a selector?if-true-expression:if-false-expression $ awk -F ':' '{$3>1000?usertype=\"Common User\":usertype=\"Superuser\";printf\"%-20s:%12s\\n\", $1, usertype}' /etc/passwd | head -n5 root : Superuser messagebus : Superuser systemd-network : Superuser systemd-timesync : Superuser nobody : Common User","title":"5.10.7.6.\u4e09\u76ee\u6761\u4ef6\u8868\u8fbe\u5f0f"},{"location":"linux/SRE/05-RegExpress/#51078","text":"~ \uff1a\u5de6\u53f3\u662f\u5426\u5339\u914d !~ \uff1a\u5de6\u53f3\u662f\u5426\u4e0d\u5339\u914d \u793a\u4f8b\uff1a \u5339\u914d\u6587\u4ef6\u4e2d\u6307\u5b9a\u5b57\u7b26\u4e32 root \u7684\u6240\u6709\u884c\uff0c\u7c7b\u4f3cgrep\u547d\u4ee4\uff0c\u4f46\u6ca1\u6709\u9ad8\u4eae\u663e\u793a\u3002 $ awk '/root/' /etc/passwd root:x:0:0:root:/root:/bin/bash \u4ee5 : \u4e3a\u5206\u9694\u7b26\uff0c\u5339\u914d\u7b2c\u4e00\u5217 $1 \u4e2d\u5305\u542b\u6307\u5b9a\u5b57\u7b26\u4e32 oo \u7684\u884c\u3002 ~ \u662f\u4ee3\u8868\u5de6\u53f3\u5339\u914d\u3002 $ awk -F ':' '$1 ~/oo/' /etc/passwd root:x:0:0:root:/root:/bin/bash gentoo:x:1014:100:Gentoo Distribution:/home/gentoo:/bin/csh \u4ee5 : \u4e3a\u5206\u9694\u7b26\uff0c\u5339\u914d\u6240\u6709\u5217 $0 \uff08\u6574\u884c\uff09\u4e2d\u5305\u542b root \u884c\u7684\u7b2c\u4e00\u5217 $1 \u3002 $ awk -F: '$0 ~/root/{print $1}' /etc/passwd $ awk -F: '$0 ~\"root\"{print $1}' /etc/passwd root daemon _cvmsroot \u4ee5 : \u4e3a\u5206\u9694\u7b26\uff0c\u5339\u914d\u6240\u6709\u5217 $0 \uff08\u6574\u884c\uff09\u4e2d\u4ee5 root \u5f00\u5934\u884c\u7684\u7b2c\u4e00\u5217 $1 \u3002 $ awk -F: '$0 ~\"^root\"{print $1}' /etc/passwd $ awk -F: '$0 ~/^root/{print $1}' /etc/passwd root \u4ee5 : \u4e3a\u5206\u9694\u7b26\uff0c\u5339\u914d\u6240\u6709\u5217 $0 \uff08\u6574\u884c\uff09\u4e2d\u4e0d\u4ee5 root \u5f00\u5934\u884c\u7684\u7b2c\u4e00\u5217 $1 \u3002 awk -F: '$0 !~/^root/{print $1}' /etc/passwd awk -F: '$0 ~/^[^root]/{print $1}' /etc/passwd \u591a\u6761\u4ef6\u5339\u914d\uff0c\u4ee5 : \u4e3a\u5206\u9694\u7b26\uff0c\u5339\u914d\u6240\u6709\u542b\u6709 root \u6216 ftp \u7684\u884c\uff0c\u5e76\u6253\u5370\u7b2c1\u30013\u5217\u3002 awk -F ':' '/root/ {print $1,$3} /bin/ {print $1,$3}' /etc/passwd \u591a\u6761\u4ef6\u5339\u914d\uff0c\u4ee5 : \u4e3a\u5206\u9694\u7b26\uff0c\u5339\u914d\u7b2c\u4e00\u5217\u4e2d\u542b\u6709 root \u6216 bin \u7684\u884c\uff0c\u5e76\u6253\u5370\u7b2c1\u30013\u5217\u3002 $ awk -F ':' '$1 ~/root/ {print $1,$3} $1 ~/bin/ {print $1,$3}' /etc/passwd root 0 bin 1 \u4ee5 : \u4e3a\u5206\u9694\u7b26\uff0c\u5339\u914d\u7b2c\u4e09\u5217 $3 \u4e2d\u503c\u4e3a 0 \u7684\u884c\u3002 $ awk -F \":\" '$3==0' /etc/passwd root:x:0:0:root:/root:/bin/bash \u4ee5\u81f3\u5c11\u4e00\u4e2a\u7a7a\u683c\u6216%\u4e3a\u5206\u9694\u7b26\uff0c\u5339\u914d\u4ee5 /dev/sd \u5f00\u5934\u7684\u884c\uff0c\u6253\u5370\u7b2c\u4e94\u5217\u3002 $ df | awk -F \"[[:space:]]+|%\" '$0 ~ /^\\/dev\\/sd/{print $5}' 8 8 8 8 8 8 8 8 8 8 8 \u8bfb\u53d6 ifconfig eth0 \u8f93\u51fa\u7ed3\u679c\u7684\u7b2c\u4e8c\u884c NR==2 \u7684\u7b2c\u4e8c\u5217 $2 \u3002 $ ifconfig eth0 | awk 'NR==2{print $2}' 192 .168.10.210","title":"5.10.7.8.\u6a21\u5f0f\u5339\u914d\u7b26"},{"location":"linux/SRE/05-RegExpress/#5108","text":"","title":"5.10.8.\u53d8\u91cf"},{"location":"linux/SRE/05-RegExpress/#51081","text":"awk \u5e38\u7528\u7684\u53d8\u91cf\u6709 FS \u3001 OFS \u3001 NF \u548c NR \u3002 FS \u7528\u6765\u5b9a\u4e49\u8f93\u5165\u5b57\u6bb5\u5206\u9694\u7b26\uff0c\u9ed8\u8ba4\u4e3a\u7a7a\u767d\u5b57\u7b26\u3002\u4e0e -F \u9009\u9879\u529f\u80fd\u7c7b\u4f3c\uff0c\u540c\u65f6\u4f7f\u7528\u4f1a\u62a5\u9519\u3002 OFS \u7528\u6765\u5b9a\u4e49\u8f93\u51fa\u5b57\u6bb5\u5206\u9694\u7b26\uff0c\u9ed8\u8ba4\u4e3a\u7a7a\u767d\u5b57\u7b26\u3002 RS \u6307\u5b9a\u8f93\u5165\u65f6\u7684\u6362\u884c\u7b26\u3002 ORS \u6307\u5b9a\u7b26\u53f7\u5728\u8f93\u51fa\u65f6\u66ff\u6362\u6362\u884c\u7b26\u3002 NF \u8868\u793a\u7528\u5206\u9694\u7b26\u5206\u9694\u540e\u4e00\u5171\u6709\u591a\u5c11\u5217\u3002 NR \u8868\u793a\u884c\u53f7\u3002 FNR \u8868\u793a\u4e2a\u6587\u4ef6\u5206\u522b\u8ba1\u6570\u5404\u81ea\u8bb0\u5f55\u7684\u7f16\u53f7\u3002 FILENAME \u8868\u793a\u5f53\u524d\u6587\u4ef6\u540d\u3002 ARGC \u8868\u793a\u547d\u4ee4\u884c\u53c2\u6570\u7684\u4e2a\u6570\u3002 ARVC \u4ee5\u6570\u7ec4\u5f62\u5f0f\u4fdd\u5b58\u547d\u4ee4\u884c\u6240\u7ed9\u5b9a\u7684\u5404\u53c2\u6570\uff0c\u6bcf\u4e2a\u53c2\u6570\uff1a ARGV[0] \uff0c......\u3002 FS \u7684\u7528\u6cd5\uff1a $ awk -v FS = ':' '{print $1, FS, $3}' /etc/passwd | head -n5 root : 0 messagebus : 499 systemd-network : 497 $ awk -F: '{print $1FS$3}' /etc/passwd | head -n3 root:0 messagebus:499 systemd-network:497 $ S = : ; awk -v FS = $S '{print $1FS$3}' /etc/passwd | head -n3 root:0 messagebus:499 systemd-network:497 systemd-timesync:496 nobody:65534 $ S = : ; awk -F $S '{print $1FS$3}' /etc/passwd | head -n3 root:0 messagebus:499 systemd-network:497 FS \u548c -F \u9009\u9879\u529f\u540c\u65f6\u4f7f\u7528\u4f1a\u51b2\u7a81\uff0c -F \u7684\u4f18\u5148\u7ea7\u66f4\u9ad8\u3002 $ awk -v FS = ':' -F ';' '{print $1FS$3}' /etc/passwd | head -n3 root:x:0:0:root:/root:/bin/bash ; messagebus:x:499:499:User for D-Bus:/run/dbus:/usr/bin/false ; systemd-network:x:497:497:systemd Network Management:/:/usr/sbin/nologin ; $ awk -v FS = ';' -F ':' '{print $1FS$3}' /etc/passwd | head -n3 root:0 messagebus:499 systemd-network:497 OFS \u7684\u7528\u6cd5\uff1a \u4ee5 : \u4e3a\u5206\u9694\u7b26\uff0c\u6253\u5370\u7b2c1\u30013\u30014\u5217\u7b2c\u5185\u5bb9\uff0c\u5e76\u4ee5 # \u4e3a\u5206\u9694\u7b26\u3002 $ awk -F ':' '{OFS=\"#\"} {print $1,$3,$4}' /etc/passwd | head -n5 root#0#0 messagebus#499#499 systemd-network#497#497 systemd-timesync#496#496 nobody#65534#65534 $ awk -v FS = ':' -v OFS = '#' '{print $1,$3,$4}' /etc/passwd | head -n5 root#0#0 messagebus#499#499 systemd-network#497#497 systemd-timesync#496#496 nobody#65534#65534 \u4ee5 : \u4e3a\u5206\u9694\u7b26\uff0c\u5f53\u7b2c\u4e09\u5217\u5927\u4e8e\u7b49\u4e8e5000\u65f6\uff0c\u6253\u5370\u7b2c1\u30012\u30013\u30014\u5217\u7b2c\u5185\u5bb9\uff0c\u5e76\u4ee5 # \u4e3a\u5206\u9694\u7b26\u3002 $ awk -F ':' '{OFS=\"#\"} {if ($3>=5000) {print $1,$2,$3,$4}}' /etc/passwd nobody#x#65534#65534 RS \u7684\u7528\u6cd5\uff1a # \u4ee5\u7a7a\u683c\u4e3a\u6362\u884c\u6807\u5fd7 $ awk -v RS = ' ' '{print $0}' /etc/passwd | head -n3 root:x:0:0:root:/root:/bin/bash messagebus:x:499:499:User for # \u4ee5\u5192\u53f7\u4e3a\u6362\u884c\u6807\u5fd7 $ awk -v RS = ':' '{print $0}' /etc/passwd | head -n3 root x 0 ORS \u7684\u7528\u6cd5\uff1a # \u4ee5\u5192\u53f7\u4e3a\u6362\u884c\u6807\u5fd7\uff0c\u66ff\u6362\u6210### $ awk -v RS = ':' -v ORS = '###' '{print $0}' /etc/passwd | head -n3 root###x###0###0###root###/root###/bin/bash messagebus###x###499###499###User for D-Bus###/run/dbus###/usr/bin/false systemd-network###x###497###497###systemd Network Management###/###/usr/sbin/nologin NF \u7684\u7528\u6cd5\uff1a \u5176\u4e2d NF \u662f\u591a\u5c11\u5217\uff0c $NF \u662f\u6700\u540e\u4e00\u5217\u7684\u503c\u3002 \u4e0b\u4f8b\u4e2d\u4ee5 : \u4e3a\u5206\u9694\u7b26\u4e00\u5171\u5206\u4e3a7\u5217\uff0c\u6700\u540e\u4e00\u5217\u7684\u503c\u662f $NF \u3002 $ awk -F ':' '{print $NF}' /etc/passwd | head -n2 /bin/bash /usr/bin/false $ awk -F ':' '{print NF}' /etc/passwd | head -n2 7 7 $ ss -nt | grep \"^ESTAB\" | awk -F \"[[:space:]]+|:\" '{print $(NF-2)}' 192 .168.10.103 $ ss -nt | awk -F \"[[:space:]]+|:\" '/^ESTAB/{print $(NF-2)}' 192 .168.10.103 NR \u7684\u7528\u6cd5\uff1a \u901a\u8fc7 NR \u8f93\u51fa\u884c\u53f7\u3002\u4ee5 : \u4e3a\u5206\u9694\u7b26\uff0c\u6253\u5370\u524d\u4e09\u884c\u7684\u884c\u53f7\u3002 $ awk -F ':' '{print NR}' /etc/passwd | head -n3 1 2 3 \u53d6\u5947\u3001\u5076\u6570\u884c\u3002 $ seq 10 | awk 'NR%2==0' 2 4 6 8 10 $ seq 10 | awk 'NR%2==1' 1 3 5 7 9 \u901a\u8fc7 NR \u8bbe\u5b9a\u884c\u53f7\u6761\u4ef6\u3002\u4ee5 : \u4e3a\u5206\u9694\u7b26\uff0c\u6253\u5370\u7b2c40\u884c\u4ee5\u540e\u7684\u884c\u5185\u5bb9\u3002 $ awk 'NR>45' /etc/passwd admin3:x:1020:100::/home/admin3:/bin/bash smith:x:2002:0:,,,:/home/admin2:/bin/bash pm1:x:2003:1535::/home/pm1:/bin/bash tm1:x:2004:1535::/home/tm1:/bin/bash tm2:x:2005:1536::/home/tm2:/bin/bash $ awk -F ':' 'NR>45' /etc/passwd admin3:x:1020:100::/home/admin3:/bin/bash smith:x:2002:0:,,,:/home/admin2:/bin/bash pm1:x:2003:1535::/home/pm1:/bin/bash tm1:x:2004:1535::/home/tm1:/bin/bash tm2:x:2005:1536::/home/tm2:/bin/bash $ awk -F ':' 'NR>45 {print NR,$1,$3}' /etc/passwd 46 admin3 1020 47 smith 2002 48 pm1 2003 49 tm1 2004 50 tm2 2005 $ awk -F ':' 'BEGIN{print NR}' /etc/passwd 0 $ awk -F ':' 'END{print NR}' /etc/passwd 50 $ ifconfig eth0 | awk '/netmask/{print $0}' inet 192 .168.10.210 netmask 255 .255.255.0 broadcast 192 .168.10.255 $ ifconfig eth0 | awk '/netmask/{print $1}' inet $ ifconfig eth0 | awk '/netmask/{print $2}' 192 .168.10.210 $ ifconfig eth0 | awk 'NR==2{print $0}' inet 192 .168.10.210 netmask 255 .255.255.0 broadcast 192 .168.10.255 $ ifconfig eth0 | awk 'NR==2{print $1}' inet $ ifconfig eth0 | awk 'NR==2{print $2}' 192 .168.10.210 \u901a\u8fc7 NR \u4e0e\u5217\u5339\u914d\u4e00\u8d77\u4f7f\u7528\u3002 $ awk -F ':' 'NR<5 && $1 ~/roo/' /etc/passwd root:x:0:0:root:/root:/bin/bash FNR \u7684\u7528\u6cd5\uff1a $ awk '{print FNR}' /etc/fstab /etc/networks 1 2 3 4 5 6 7 8 9 10 11 12 1 2 3 4 5 6 7 8 9 10 $ awk '{print NR, $0}' /etc/fstab /etc/networks 1 UUID = 5ffa8dbd-473e-4308-804a-0033c3b5f7af / btrfs defaults 0 0 2 UUID = 5ffa8dbd-473e-4308-804a-0033c3b5f7af /var btrfs subvol = /@/var 0 0 3 UUID = 5ffa8dbd-473e-4308-804a-0033c3b5f7af /usr/local btrfs subvol = /@/usr/local 0 0 4 UUID = 5ffa8dbd-473e-4308-804a-0033c3b5f7af /tmp btrfs subvol = /@/tmp 0 0 5 UUID = 5ffa8dbd-473e-4308-804a-0033c3b5f7af /srv btrfs subvol = /@/srv 0 0 6 UUID = 5ffa8dbd-473e-4308-804a-0033c3b5f7af /root btrfs subvol = /@/root 0 0 7 UUID = 5ffa8dbd-473e-4308-804a-0033c3b5f7af /opt btrfs subvol = /@/opt 0 0 8 UUID = 5ffa8dbd-473e-4308-804a-0033c3b5f7af /home btrfs subvol = /@/home 0 0 9 UUID = 5ffa8dbd-473e-4308-804a-0033c3b5f7af /boot/grub2/x86_64-efi btrfs subvol = /@/boot/grub2/x86_64-efi 0 0 10 UUID = 5ffa8dbd-473e-4308-804a-0033c3b5f7af /boot/grub2/i386-pc btrfs subvol = /@/boot/grub2/i386-pc 0 0 11 UUID = 5ffa8dbd-473e-4308-804a-0033c3b5f7af /.snapshots btrfs subvol = /@/.snapshots 0 0 12 UUID = 47c36ad7-f49f-4ecd-9b72-4801c5bb3a04 swap swap defaults 0 0 13 # 14 # networks This file describes a number of netname-to-address 15 # mappings for the TCP/IP subsystem. It is mostly 16 # used at boot time, when no name servers are running. 17 # 18 19 loopback 127 .0.0.0 20 link-local 169 .254.0.0 21 22 # End. $ awk '{print FNR, $0}' /etc/fstab /etc/networks 1 UUID = 5ffa8dbd-473e-4308-804a-0033c3b5f7af / btrfs defaults 0 0 2 UUID = 5ffa8dbd-473e-4308-804a-0033c3b5f7af /var btrfs subvol = /@/var 0 0 3 UUID = 5ffa8dbd-473e-4308-804a-0033c3b5f7af /usr/local btrfs subvol = /@/usr/local 0 0 4 UUID = 5ffa8dbd-473e-4308-804a-0033c3b5f7af /tmp btrfs subvol = /@/tmp 0 0 5 UUID = 5ffa8dbd-473e-4308-804a-0033c3b5f7af /srv btrfs subvol = /@/srv 0 0 6 UUID = 5ffa8dbd-473e-4308-804a-0033c3b5f7af /root btrfs subvol = /@/root 0 0 7 UUID = 5ffa8dbd-473e-4308-804a-0033c3b5f7af /opt btrfs subvol = /@/opt 0 0 8 UUID = 5ffa8dbd-473e-4308-804a-0033c3b5f7af /home btrfs subvol = /@/home 0 0 9 UUID = 5ffa8dbd-473e-4308-804a-0033c3b5f7af /boot/grub2/x86_64-efi btrfs subvol = /@/boot/grub2/x86_64-efi 0 0 10 UUID = 5ffa8dbd-473e-4308-804a-0033c3b5f7af /boot/grub2/i386-pc btrfs subvol = /@/boot/grub2/i386-pc 0 0 11 UUID = 5ffa8dbd-473e-4308-804a-0033c3b5f7af /.snapshots btrfs subvol = /@/.snapshots 0 0 12 UUID = 47c36ad7-f49f-4ecd-9b72-4801c5bb3a04 swap swap defaults 0 0 1 # 2 # networks This file describes a number of netname-to-address 3 # mappings for the TCP/IP subsystem. It is mostly 4 # used at boot time, when no name servers are running. 5 # 6 7 loopback 127 .0.0.0 8 link-local 169 .254.0.0 9 10 # End. FILENAME \u7684\u7528\u6cd5\uff1a $ awk '{print FILENAME}' /etc/fstab /etc/fstab /etc/fstab /etc/fstab /etc/fstab /etc/fstab /etc/fstab /etc/fstab /etc/fstab /etc/fstab /etc/fstab /etc/fstab /etc/fstab $ awk '{print FNR, FILENAME, $0}' /etc/fstab /etc/networks 1 /etc/fstab UUID = 5ffa8dbd-473e-4308-804a-0033c3b5f7af / btrfs defaults 0 0 2 /etc/fstab UUID = 5ffa8dbd-473e-4308-804a-0033c3b5f7af /var btrfs subvol = /@/var 0 0 3 /etc/fstab UUID = 5ffa8dbd-473e-4308-804a-0033c3b5f7af /usr/local btrfs subvol = /@/usr/local 0 0 4 /etc/fstab UUID = 5ffa8dbd-473e-4308-804a-0033c3b5f7af /tmp btrfs subvol = /@/tmp 0 0 5 /etc/fstab UUID = 5ffa8dbd-473e-4308-804a-0033c3b5f7af /srv btrfs subvol = /@/srv 0 0 6 /etc/fstab UUID = 5ffa8dbd-473e-4308-804a-0033c3b5f7af /root btrfs subvol = /@/root 0 0 7 /etc/fstab UUID = 5ffa8dbd-473e-4308-804a-0033c3b5f7af /opt btrfs subvol = /@/opt 0 0 8 /etc/fstab UUID = 5ffa8dbd-473e-4308-804a-0033c3b5f7af /home btrfs subvol = /@/home 0 0 9 /etc/fstab UUID = 5ffa8dbd-473e-4308-804a-0033c3b5f7af /boot/grub2/x86_64-efi btrfs subvol = /@/boot/grub2/x86_64-efi 0 0 10 /etc/fstab UUID = 5ffa8dbd-473e-4308-804a-0033c3b5f7af /boot/grub2/i386-pc btrfs subvol = /@/boot/grub2/i386-pc 0 0 11 /etc/fstab UUID = 5ffa8dbd-473e-4308-804a-0033c3b5f7af /.snapshots btrfs subvol = /@/.snapshots 0 0 12 /etc/fstab UUID = 47c36ad7-f49f-4ecd-9b72-4801c5bb3a04 swap swap defaults 0 0 1 /etc/networks # 2 /etc/networks # networks This file describes a number of netname-to-address 3 /etc/networks # mappings for the TCP/IP subsystem. It is mostly 4 /etc/networks # used at boot time, when no name servers are running. 5 /etc/networks # 6 /etc/networks 7 /etc/networks loopback 127 .0.0.0 8 /etc/networks link-local 169 .254.0.0 9 /etc/networks 10 /etc/networks # End. ARGC \u7684\u7528\u6cd5\uff1a \u6bcf\u4e2a\u53d8\u91cf\u7684\u540d\u5b57\u901a\u8fc7 ARGV \u83b7\u53d6\u3002 $ awk '{print ARGC}' /etc/fstab /etc/issue 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 $ awk 'BEGIN{print ARGC}' /etc/fstab /etc/issue 3 ARGV \u7684\u7528\u6cd5\uff1a $ awk 'BEGIN{print ARGV[0]}' /etc/fstab /etc/issue awk $ awk 'BEGIN{print ARGV[1]}' /etc/fstab /etc/issue /etc/fstab $ awk 'BEGIN{print ARGV[2]}' /etc/fstab /etc/issue /etc/issue $ awk 'BEGIN{print ARGV[3]}' /etc/fstab /etc/issue","title":"5.10.8.1.\u5185\u7f6e\u53d8\u91cf"},{"location":"linux/SRE/05-RegExpress/#51082","text":"\u81ea\u5b9a\u4e49\u53d8\u91cf\u662f\u533a\u5206\u5b57\u7b26\u5927\u5c0f\u5199\u7684\uff0c\u4f7f\u7528\u4e0b\u9762\u7684\u65b9\u5f0f\u8fdb\u884c\u8d4b\u503c\u3002 -v var=value \u5728program\u4e2d\u76f4\u63a5\u5b9a\u4e49 \u4e3e\u4f8b\uff1a $ awk -v t1 = t2 = \"hello awk\" 'BEGIN{print t1, t2}' t2 = hello awk $ awk -v t1 = t2 = \"hello awk\" 'BEGIN{t1=t2=\"gawk\"; print t1, t2}' gawk gawk $ awk 'BEGIN{t1=t2=\"hello awk\"; print t1, t2}' hello awk hello awk $ awk -v t1 = \"hello awk\" '{print t1}' /etc/issue hello awk hello awk hello awk hello awk hello awk $ awk -v t1 = \"hello awk\" 'BEGIN{print t1}' /etc/issue hello awk $ awk -v t1 = \"hello awk\" 'BEGIN{print t1}' hello awk $ awk -F: '{sex=\"male\"; print $1, sex, age; age=28}' /etc/passwd | head -n3 root male messagebus male 28 systemd-network male 28 $ cat < awkscript {print script,$1,$2} EOF $ awk -F: -f awkscript script = \"awk\" /etc/passwd | head -n2 awk root x awk messagebus x \u52a8\u4f5c printf \u3002 \u52a8\u4f5cprintf\u53ef\u4ee5\u5b9e\u73b0\u683c\u5f0f\u5316\u8f93\u51fa\u3002 \u683c\u5f0f\uff1a printf \"FORMAT\", item1, item2, ...... \u8bf4\u660e\uff1a \u5fc5\u987b\u6307\u5b9aFORMAT \u4e0d\u4f1a\u81ea\u52a8\u6362\u884c\uff0c\u9700\u8981\u663e\u5f0f\u7ed9\u51fa\u6362\u884c\u63a7\u5236\u7b26 \\n \u3002 FORMAT\u4e2d\u9700\u8981\u5206\u522b\u4e3a\u540e\u9762\u6bcf\u4e2aitem\u6307\u5b9a\u683c\u5f0f\u7b26\u3002 \u683c\u5f0f\u7b26\uff1a\u4e0eitem\u662f\u4e00\u4e00\u5bf9\u5e94\u7684 %s \uff1a\u663e\u793a\u5b57\u7b26\u4e32 %d , %i \uff1a\u663e\u793a\u5341\u8fdb\u5236\u6574\u6570 %f \uff1a\u663e\u793a\u4e3a\u6d6e\u70b9\u6570 %e , %E \uff1a\u663e\u793a\u79d1\u5b66\u8ba1\u6570\u6cd5\u6570\u503c %c \uff1a\u663e\u793a\u5b57\u7b26\u7684ASCII\u7801 %g , %G \uff1a\u4ee5\u79d1\u5b66\u8ba1\u6570\u6cd5\u6216\u6d6e\u70b9\u5f62\u5f0f\u663e\u793a\u6570\u503c %u \uff1a\u65e0\u7b26\u53f7\u6574\u6570 %% \uff1a\u663e\u793a % \u81ea\u8eab \u4fee\u9970\u7b26\uff1a #[.#] \uff1a\u7b2c\u4e00\u4e2a\u6570\u5b57\u63a7\u5236\u663e\u793a\u7684\u5bbd\u5ea6\uff0c\u7b2c\u4e8c\u4e2a#\u8868\u793a\u5c0f\u6570\u70b9\u540e\u7cbe\u5ea6\uff0c\u5982 %3.1f - \uff1a\u5de6\u5bf9\u9f50\uff08\u9ed8\u8ba4\u53f3\u5bf9\u9f50\uff09\uff0c\u5982 %-15s + \uff1a\u663e\u793a\u6570\u503c\u7684\u6b63\u8d1f\u7b26\u53f7\uff0c\u5982 %+d \u793a\u4f8b\uff1a $ awk -F: '{printf \"%s\", $1}' /etc/passwd | head -n3 rootmessagebussystemd-networksystemd-timesyncnobodymailchronypostfixmanlpgamesftpdaemonrpcnscdpolkitdattftpftpsecurebinstatdsshdvagrantpesignsvntester1tester2tester3tester4tester5user0user1user2user3user4user5user6user7user8user9gentoonginxvarnishmysqlwebuseradmin3smithpm1tm1tm2 $ awk -F: '{printf \"%s\\n\", $1}' /etc/passwd | head -n3 root messagebus systemd-network $ awk -F: '{printf \"%20s\\n\", $1}' /etc/passwd | head -n3 root messagebus systemd-network $ awk -F: '{printf \"%-20s\\n\", $1}' /etc/passwd | head -n3 root messagebus systemd-network $ awk -F: '{printf \"%-20s %10d\\n\", $1, $3}' /etc/passwd | head -n3 root 0 messagebus 499 systemd-network 497 $ awk -F: '{printf \"Username: %s\\n\", $1}' /etc/passwd | head -n3 Username: root Username: messagebus Username: systemd-network $ awk -F: '{printf \"Username: %s UID:%d\\n\", $1, $3}' /etc/passwd | head -n3 Username: root UID:0 Username: messagebus UID:499 Username: systemd-network UID:497 $ awk -F: '{printf \"Username: %25s UID:%d\\n\", $1, $3}' /etc/passwd | head -n3 Username: root UID:0 Username: messagebus UID:499 Username: systemd-network UID:497 $ awk -F: '{printf \"Username: %-25s UID:%d\\n\", $1, $3}' /etc/passwd | head -n3 Username: root UID:0 Username: messagebus UID:499 Username: systemd-network UID:497","title":"5.10.8.2.\u81ea\u5b9a\u4e49\u53d8\u91cf"},{"location":"linux/SRE/05-RegExpress/#5109beginend","text":"\u793a\u4f8b\uff1a awk -F \":\" 'BEGIN{printf \"--------------------------------\\n%-20s|%10s|\\n--------------------------------\\n\", \"Username\", \"UID\"}{printf \"%-20s|%-10d|\\n--------------------------------\\n\", $1, $3}END{print \"end\"}' /etc/passwd -------------------------------- Username | UID | -------------------------------- root | 0 | -------------------------------- daemon | 1 | -------------------------------- bin | 2 | ------------------------------- ... ... -------------------------------- mfe | 997 | -------------------------------- end","title":"5.10.9.BEGIN/END"},{"location":"linux/SRE/05-RegExpress/#51010","text":"{statements;...} \u7ec4\u5408\u8bed\u53e5 if(condition){statements;...} if(condition){statements;...} else(statements;...) switch(expression){case VALUE1 or /REGEXP/: statement1; case VALUE2 or /REGEXP2/: statement2;......;default: statementn} while(condition){statements;...} do(statements;...) while{condition} for(expr1;expr2;expr3) {statements;...} break continue exit if-else\u793a\u4f8b\uff1a $ cat < score.txt Name Score Tom 100 Jack 91 Bill 81 Jim 51 EOF $ awk 'NR!=1{score=$2;if($2>=80){print $1, \"Good\"}else if($2>=60){print $1, \"Pass\"}else{print $1, \"failed\"}}' score.txt Tom Good Jack Good Bill Good Jim failed switch\u793a\u4f8b\uff1a $ awk 'NR!=1{switch($2){case 100:print $1,\"good\"; case 60:print $1,\"Pass\"; default:print $1,\"others\"}}' score.txt Tom good Tom Pass Tom others Jack others Bill others Jim others while\u793a\u4f8b\uff1a $ awk 'BEGIN{i=0;sum=0;while(i<=100){sum+=i;i++};print sum}' 5050 do-while\u793a\u4f8b\uff1a $ awk 'BEGIN{i=0;sum=0;do{sum+=i;i++}while(i<101);print sum}' 5050 for\u793a\u4f8b\uff1a $ awk 'BEGIN{i=0;sum=0;for(i=1;i<=100;i++){sum+=i};print sum}' 5050 \u547d\u4ee4\u6548\u7387\u6bd4\u8f83\uff1a $ time ( awk 'BEGIN{i=0;sum=0;while(i<=100000){sum+=i;i++};print sum}' ) 5000050000 real 0m0.028s user 0m0.027s sys 0m0.001s $ time ( seq -s+ 1000000 | bc ) 500000500000 real 0m0.329s user 0m0.240s sys 0m0.094s $ time ( awk 'BEGIN{i=0;sum=0;for(i=1;i<=1000000;i++){sum+=i};print sum}' ) 500000500000 real 0m0.050s user 0m0.046s sys 0m0.004s contine\u793a\u4f8b\uff1a\u4e2d\u65ad\u5f53\u524d\u5faa\u73af\uff0c\u8fdb\u5165\u4e0b\u4e00\u6b21\u5faa\u73af\u3002 $ awk 'BEGIN{i=0;sum=0;for(i=1;i<=100;i++){if(i==50)continue;sum+=i};print sum}' 5000 contine\u793a\u4f8b\uff1a\u4e2d\u65ad\u6574\u4e2a\u5faa\u73af\u3002 $ awk 'BEGIN{i=0;sum=0;for(i=1;i<=100;i++){if(i==50)break;sum+=i};print sum}' 1225 next\u793a\u4f8b\uff1a\u63d0\u524d\u7ed3\u675f\u5bf9\u672c\u884c\u5904\u7406\uff0c\u76f4\u63a5\u8fdb\u5165\u4e0b\u4e00\u884c\u5904\u7406\uff08\u6ce8\uff0cawk\u81ea\u5faa\u73af\uff0c\u5e76\u975e\u524d\u9762\u7684for\u6216while\u5faa\u73af\uff09 $ awk -F: '{if($3%2!=0)next;print $1,$3}' /etc/passwd # \u5947\u6570\u884c\u6253\u5370 root 0 systemd-timesync 496 nobody 65534 chrony 494 games 492 daemon 2 rpc 490 polkitd 488 ftpsecure 486 sshd 484 vagrant 1000 svn 482 tester1 600 tester4 1002 user0 1004 user2 1006 user4 1008 user6 1010 user8 1012 gentoo 1014 varnish 1016 webuser 666 admin3 1020 smith 2002 tm1 2004 $ awk -F: '{if($3%2==0)next;print $1,$3}' /etc/passwd # \u5076\u6570\u884c\u6253\u5370 messagebus 499 systemd-network 497 mail 495 postfix 51 man 13 lp 493 ftp 491 nscd 489 at 25 tftp 487 bin 1 statd 485 pesign 483 tester2 601 tester3 1001 tester5 1003 user1 1005 user3 1007 user5 1009 user7 1011 user9 1013 nginx 1015 mysql 1017 pm1 2003 tm2 2005","title":"5.10.10.\u5e38\u7528\u63a7\u5236\u8bed\u53e5"},{"location":"linux/SRE/05-RegExpress/#51011","text":"\u5173\u8054\u6570\u7ec4\u662f\u4e00\u79cd\u6570\u636e\u7ed3\u6784\uff0c\u4e5f\u79f0\u4e3a\u5b57\u5178\u6216\u6620\u5c04\u3002\u4e0e\u4f20\u7edf\u7684\u6570\u7ec4\u4e0d\u540c\uff0c\u5173\u8054\u6570\u7ec4\u7684\u7d22\u5f15\u53ef\u4ee5\u662f\u4efb\u4f55\u7c7b\u578b\u7684\u6570\u636e\uff0c\u4f8b\u5982\u5b57\u7b26\u4e32\u6216\u5bf9\u8c61\uff0c\u800c\u4e0d\u4ec5\u4ec5\u662f\u6574\u6570\u3002 \u63d0\u793a\uff1a \u5728\u8ba1\u7b97\u673a\u7f16\u7a0b\u4e2d\uff0c\u9664\u4e86\u5173\u8054\u6570\u7ec4\uff0c\u8fd8\u6709\u5176\u4ed6\u51e0\u79cd\u5e38\u89c1\u7684\u6570\u7ec4\u7c7b\u578b\uff0c\u5305\u62ec\uff1a \u7ebf\u6027\u6570\u7ec4\uff08\u6216\u79f0\u4e3a\u7d22\u5f15\u6570\u7ec4\uff09\uff1a\u8fd9\u662f\u6700\u5e38\u89c1\u7684\u6570\u7ec4\u7c7b\u578b\uff0c\u5176\u4e2d\u6bcf\u4e2a\u5143\u7d20\u90fd\u6709\u4e00\u4e2a\u6570\u5b57\u7d22\u5f15\uff0c\u53ef\u4ee5\u7528\u6765\u5feb\u901f\u8bbf\u95ee\u6570\u7ec4\u4e2d\u7684\u5143\u7d20\u3002\u4f8b\u5982\uff0c\u5728C\u8bed\u8a00\u4e2d\uff0c\u6570\u7ec4\u7684\u6bcf\u4e2a\u5143\u7d20\u90fd\u53ef\u4ee5\u901a\u8fc7\u6570\u7ec4\u4e0b\u6807\u6765\u8bbf\u95ee\u3002 \u591a\u7ef4\u6570\u7ec4\uff1a\u591a\u7ef4\u6570\u7ec4\u662f\u4e00\u79cd\u6570\u7ec4\uff0c\u5176\u4e2d\u6bcf\u4e2a\u5143\u7d20\u4e5f\u662f\u4e00\u4e2a\u6570\u7ec4\u3002\u5728\u4e8c\u7ef4\u6570\u7ec4\u4e2d\uff0c\u6bcf\u4e2a\u5143\u7d20\u90fd\u6709\u4e24\u4e2a\u7d22\u5f15\uff08\u4f8b\u5982\uff0c\u884c\u548c\u5217\uff09\uff0c\u53ef\u4ee5\u7528\u4e8e\u8bbf\u95ee\u6570\u7ec4\u4e2d\u7684\u5143\u7d20\u3002\u5728\u9ad8\u7ef4\u6570\u7ec4\u4e2d\uff0c\u6bcf\u4e2a\u5143\u7d20\u90fd\u5177\u6709\u66f4\u591a\u7684\u7d22\u5f15\u3002 \u52a8\u6001\u6570\u7ec4\uff1a\u52a8\u6001\u6570\u7ec4\u662f\u4e00\u79cd\u53ef\u4ee5\u52a8\u6001\u8c03\u6574\u5927\u5c0f\u7684\u6570\u7ec4\u3002\u5728\u8bb8\u591a\u7f16\u7a0b\u8bed\u8a00\u4e2d\uff0c\u52a8\u6001\u6570\u7ec4\u53ef\u4ee5\u52a8\u6001\u5206\u914d\u5185\u5b58\uff0c\u4ee5\u4fbf\u5728\u7a0b\u5e8f\u8fd0\u884c\u65f6\u6839\u636e\u9700\u8981\u8c03\u6574\u6570\u7ec4\u7684\u5927\u5c0f\u3002 \u5411\u91cf\uff1a\u5411\u91cf\u662f\u4e00\u79cd\u6570\u7ec4\uff0c\u5176\u4e2d\u6bcf\u4e2a\u5143\u7d20\u90fd\u662f\u76f8\u540c\u7684\u6570\u636e\u7c7b\u578b\u3002\u5411\u91cf\u901a\u5e38\u7528\u4e8e\u6267\u884c\u6570\u5b66\u8fd0\u7b97\u6216\u5904\u7406\u5927\u91cf\u6570\u5b57\u6570\u636e\u3002 \u5728 awk \u4e2d\u4f7f\u7528\u6570\u7ec4\u65f6\uff0c\u901a\u5e38\u4f1a\u5c06\u67d0\u4e9b\u503c\u4e0e\u4e00\u4e2a\u5b57\u7b26\u4e32\u76f8\u5173\u8054\uff0c\u4ee5\u4fbf\u5728\u9700\u8981\u65f6\u53ef\u4ee5\u901a\u8fc7\u8be5\u5b57\u7b26\u4e32\u5feb\u901f\u5730\u68c0\u7d22\u8be5\u503c\u3002 awk \u7684\u6570\u7ec4\u662f\u4e00\u4e2a\u5173\u8054\u6570\u7ec4\uff0c\u5176\u4e2d\u6bcf\u4e2a\u5143\u7d20\u90fd\u7531\u4e00\u4e2a\u552f\u4e00\u7684\u952e\u503c\u548c\u4e00\u4e2a\u5bf9\u5e94\u7684\u503c\u7ec4\u6210\u3002\u952e\u503c\uff08\u6216\u79f0\u4e3a\u7d22\u5f15\uff09\u53ef\u4ee5\u662f\u4efb\u4f55\u7c7b\u578b\u7684\u5b57\u7b26\u4e32\u3002 \u6570\u7ec4\u53ef\u4ee5\u901a\u8fc7\u4ee5\u4e0b\u8bed\u6cd5\u8fdb\u884c\u58f0\u660e\uff1a array_name [ index ] = value \u5176\u4e2d\uff0c array_name \u662f\u6570\u7ec4\u7684\u540d\u79f0\uff0c index \u662f\u5143\u7d20\u7684\u7d22\u5f15\u503c\uff0c value \u662f\u5143\u7d20\u7684\u503c\u3002 \u4f8b\u5982\uff0c\u4ee5\u4e0b\u662f\u4e00\u4e2a\u5305\u542b\u4e09\u4e2a\u5143\u7d20\u7684\u5173\u8054\u6570\u7ec4\u7684\u793a\u4f8b\uff1a array [ \"apple\" ] = 1 array [ \"banana\" ] = 2 array [ \"orange\" ] = 3 \u5728\u4e0a\u9762\u7684\u793a\u4f8b\u4e2d\uff0c array \u662f\u4e00\u4e2a\u5173\u8054\u6570\u7ec4\uff0c\u5176\u7d22\u5f15\u4e3a\u5b57\u7b26\u4e32\u7c7b\u578b\uff0c\u800c\u503c\u4e3a\u6574\u6570\u7c7b\u578b\u3002\u53ef\u4ee5\u4f7f\u7528\u4ee5\u4e0b\u7684\u65b9\u5f0f\u8bbf\u95ee\u8be5\u6570\u7ec4\u4e2d\u7684\u5143\u7d20\uff1a value = array [ \"apple\" ] \u5728\u4e0a\u9762\u7684\u793a\u4f8b\u4e2d\uff0c value \u7684\u503c\u5c06\u4e3a 1 \uff0c\u56e0\u4e3a array[\"apple\"] \u7684\u503c\u4e3a 1 \u3002 \u4ee5\u4e0b\u662f\u7528 awk \u547d\u4ee4\u6765\u521b\u5efa\u4e0a\u9762\u90a3\u4e2a\u5305\u542b\u4e09\u4e2a\u5143\u7d20\u7684\u5173\u8054\u6570\u7ec4\uff0c\u904d\u5386\u5e76\u8f93\u51fa\u6570\u7ec4\u503c\uff1a awk 'BEGIN { array[\"apple\"]=1; array[\"banana\"]=2; array[\"orange\"]=3; for(i in array){print array[i]}}' 3 1 2 \u4e0b\u9762\u4f8b\u5b50\u4e2d\uff0c\u6211\u4eec\u4e92\u6362\u4e86\u6570\u7ec4\u7684\u952e\u548c\u503c\u3002 $ awk 'BEGIN {arr[1]=\"apple\";arr[2]=\"banana\";arr[3]=\"orange\";for(i in arr){print arr[i]}}' apple banana orange \u5728\u4e0a\u9762\u7684\u793a\u4f8b\u4e2d\uff0c i \u662f\u6570\u7ec4 arr \u7684\u7d22\u5f15\u503c\uff0c arr[i] \u662f\u6570\u7ec4\u4e2d\u5bf9\u5e94\u7684\u5143\u7d20\u503c\u3002\u901a\u8fc7\u8fd9\u79cd\u65b9\u5f0f\u53ef\u4ee5\u5faa\u73af\u904d\u5386\u6574\u4e2a\u6570\u7ec4\uff0c\u5e76\u8f93\u51fa\u5176\u4e2d\u7684\u5143\u7d20\u3002 \u9664\u4e86\u4f7f\u7528\u5faa\u73af\u904d\u5386\u6570\u7ec4\u4e4b\u5916\uff0c\u8fd8\u53ef\u4ee5\u4f7f\u7528 length \u51fd\u6570\u83b7\u53d6\u6570\u7ec4\u4e2d\u5143\u7d20\u7684\u6570\u91cf\u3002\u4f8b\u5982\uff1a $ awk 'BEGIN { arr[1]=\"apple\"; arr[2]=\"banana\"; arr[3]=\"orange\"; print length(arr) }' 3 \u4e0a\u9762\u7684\u793a\u4f8b\u5c06\u8f93\u51fa\u6570\u5b573\uff0c\u8868\u793a\u6570\u7ec4 arr \u4e2d\u5305\u542b\u4e09\u4e2a\u5143\u7d20\u3002 \u4e3e\u4f8b\uff1a\u53bb\u91cd\u590d\u8bb0\u5f55\u3002 line \u662f\u6570\u7ec4\u540d\uff0c $0 \u662f awk \u8bfb\u53d6\u7684\u5f53\u524d\u884c\u7684\u5185\u5bb9\u3002 line[$0] \u7b49\u4ef7\u4e8e line[\"a\"] \uff0c line[\"b\"] \uff0c......\u3002 \u6211\u4eec\u770b\u6267\u884c\u8fc7\u7a0b\uff1a awk\u8bfb\u5165\u7b2c1\u884c\uff1b \u6267\u884c line[\"a\"] \uff0c\u503c\u4e3a\u7a7a\uff1b \u6c42\u53cd\uff0c\u5219\u7b2c\u4e00\u884c\u7684\u503c\u53d8\u4e3a true \uff0c\u5373 !line[\"a\"]=true \uff1b \u5f53 !line[\"a\"] \u4e3a true \uff0c\u5219\u6253\u5370\u5f53\u524d\u884c\uff0c\u5373\u8f93\u51fa a \u5230\u5c4f\u5e55\uff1b \u6267\u884c line[\"a\"]++ \uff0c\u6ce8\u610f\u7b2c2\u6b65\u4e2d line[\"a\"] \u7684\u503c\u662f\u7a7a\uff0c\u6267\u884c ++ \u540e\u503c\u53d8\u4e3a 1 \u3002 \u540c\u7406\uff0c\u6211\u4eec\u53ef\u4ee5\u770b\u5230\u7b2c2\uff0c3\uff0c4\u884c\u90fd\u8f93\u51fa\u4e86\u3002 \u5f53\u8bfb\u5165\u7b2c5\u884c\u65f6\uff08\u7b2c\u4e8c\u4e2a a \uff09\uff0c\u6267\u884c line[\"a\"] \uff0c\u503c\u4e3a 1 \uff1b !line[\"a\"]=0 \uff0c\u5373false\uff1b\u5219\u4e0d\u6253\u5370\u5f53\u524d\u884c\uff0c\u5373\u4e0d\u8f93\u51fa a \u5230\u5c4f\u5e55\uff1b\u6267\u884c ++ \u540e\u503c\u53d8\u4e3a 2 \u5f53\u8bfb\u5165\u7b2c8\u884c\u65f6\uff08\u7b2c\u4e09\u4e2a a \uff09\uff0c\u6267\u884c line[\"a\"] \uff0c\u503c\u4e3a 2 \uff1b !line[\"a\"]=0 \uff0c\u5373false\uff1b\u5219\u4e0d\u6253\u5370\u5f53\u524d\u884c\uff0c\u5373\u4e0d\u8f93\u51fa a \u5230\u5c4f\u5e55\uff1b\u6267\u884c ++ \u540e\u503c\u53d8\u4e3a 3 \u4ee5\u6b64\u7c7b\u63a8\uff0c\u8bfb\u5165\u7b2c\u4e8c\u4e2a b \uff0c c \uff0c d \uff0c e \uff0c\u90fd\u4e0d\u4f1a\u518d\u8f93\u51fa\u5230\u5c4f\u5e55\uff0c\u4ece\u800c\u5b9e\u73b0\u53bb\u91cd\u8f93\u51fa\u5230\u529f\u80fd\u3002 $ cat > test << EOF a b c d a c d a b b e EOF $ awk '!line[$0]++' test a b c d e \u4e3e\u4f8b\uff1a\u5224\u65ad\u6570\u7ec4\u7d22\u5f15\u662f\u5426\u5b58\u5728\u3002 \u65b9\u6cd5\uff1a in array \uff0c 0 \u8868\u793a\u4e0d\u5b58\u5728\uff0c 1 \u8868\u793a\u5b58\u5728\u3002 $ awk 'BEGIN{array[\"i\"]=\"x\";array[\"j\"]=\"j\";print \"i\" in array, \"y\" in array}' 1 0 $ awk 'BEGIN{array[\"i\"]=\"x\";array[\"j\"]=\"j\";if(\"i\" in array){print \"exits!\"}else{print \"not exists!\"}}' exits! $ awk 'BEGIN{array[\"i\"]=\"x\";array[\"j\"]=\"j\";if(\"abc\" in array){print \"exits!\"}else{print \"not exists!\"}}' not exists! \u4e3e\u4f8b\uff1a\u904d\u5386\u6570\u7ec4\u4e2d\u6bcf\u4e2a\u5143\u7d20\u3002 \u65b9\u6cd5\uff1a for(your_var in array){your_for_body} \uff0c\u6ce8\u610f\uff0cyour_var\u4f1a\u904d\u5386\u6bcf\u4e2a\u7d22\u5f15\u3002 $ awk 'BEGIN{weekday[\"mon\"]=\"Monday\";weekday[\"tue\"]=\"Tuesday\";for(i in weekday){print i,weekday[i]}}' tue Tuesday mon Monday $ awk 'BEGIN{weekday[\"mon\"]=\"Monday\";weekday[\"tue\"]=\"Tuesday\";for(i in weekday){print i\": \"weekday[i]}}' tue: Tuesday mon: Monday \u6ce8\u610f\u4e0b\u9762\u7684\u6362\u884c\u5199\u6cd5\uff0c\u4e0d\u9700\u8981\u53cd\u659c\u6760 \\ \u3002 $ awk 'BEGIN{ arr[\"x\"]=\"welcome\" arr[\"y\"]=\"to\" arr[\"z\"]=\"Shanghai\" for (i in arr) { print i, arr[i] } }' x welcome y to z Shanghai \u793a\u4f8b\uff1a\u683c\u5f0f\u5316\u8f93\u51fa\u7528\u6237\u540d\u548c\u5bc6\u7801\u3002 $ awk -F: '{user[$1]=$3}END{for (i in user){print \"Username: \" i, \"UID: \" user[i]}}' /etc/passwd Username: sshd UID: 476 Username: rpc UID: 482 Username: tftp UID: 488 Username: usbmux UID: 480 Username: srvGeoClue UID: 487 ...... \u793a\u4f8b\uff1a\u663e\u793a\u4e3b\u673a\u8fde\u63a5\u72b6\u6001\u51fa\u73b0\u7684\u6b21\u6570\u3002 # \u4f20\u7edf\u65b9\u6cd5 $ ss -ant | awk 'NR>=2{print $1}' | sort | uniq -c $ ss -ant | awk 'NR!=1{print $1}' | sort | uniq -c 1 ESTAB 6 LISTEN # \u4f7f\u7528awk\u6570\u7ec4 $ ss -ant | awk 'NR>=2{state[$1]++}END{for(i in state){print state[i], i}}' $ ss -ant | awk 'NR!=1{state[$1]++}END{for(i in state){print state[i], i}}' 6 LISTEN 1 ESTAB","title":"5.10.11.\u6570\u7ec4"},{"location":"linux/SRE/05-RegExpress/#51012awk","text":"\u53c2\u8003\uff1a awk \u51fd\u6570\u5b98\u7f51","title":"5.10.12.awk\u51fd\u6570"},{"location":"linux/SRE/05-RegExpress/#510121","text":"\u5728 awk \u4e2d\uff0c\u51fd\u6570\u662f\u4e00\u79cd\u7528\u4e8e\u6267\u884c\u7279\u5b9a\u4efb\u52a1\u6216\u8ba1\u7b97\u7279\u5b9a\u503c\u7684\u53ef\u91cd\u7528\u4ee3\u7801\u5757\u3002 awk \u63d0\u4f9b\u4e86\u8bb8\u591a\u5185\u7f6e\u51fd\u6570\uff0c\u53ef\u4ee5\u7528\u4e8e\u5904\u7406\u6587\u672c\u6570\u636e\u3001\u6267\u884c\u6570\u5b66\u8fd0\u7b97\u3001\u64cd\u4f5c\u5b57\u7b26\u4e32\u7b49\u3002 \u4ee5\u4e0b\u662f\u4e00\u4e9b\u5e38\u7528\u7684awk\u51fd\u6570\u793a\u4f8b\uff1a length(string) \uff1a\u8fd4\u56de\u5b57\u7b26\u4e32\u7684\u957f\u5ea6\u3002 $ awk 'BEGIN { str = \"Hello World\"; len = length(str); print len }' 11 $ cut -d: -f1 /etc/passwd | awk '{print length($1)}' | head -3 4 10 15 substr(string, start, length) \uff1a\u4ece\u6307\u5b9a\u4f4d\u7f6e\u5f00\u59cb\u63d0\u53d6\u5b57\u7b26\u4e32\u7684\u5b50\u4e32\u3002 $ awk 'BEGIN { str = \"Hello World\"; substring = substr(str, 7, 5); print substring }' World sub(regexp, replacement [, target]) \uff1a\u4ece\u5b57\u7b26\u4e32target\u4e2d\u641c\u7d22\u5339\u914dregexp\u7684\u5185\u5bb9\uff0c\u5e76\u628a\u7b2c\u4e00\u4e2a\u5339\u914d\u7684\u5185\u5bb9\u66ff\u6362\u4e3areplacement\u3002\u61d2\u60f0\u6a21\u5f0f\u3002 \u6ce8\u610f\uff1a sub() \u51fd\u6570\u5728\u539f\u59cb\u5b57\u7b26\u4e32\u4e0a\u8fdb\u884c\u66ff\u6362\u64cd\u4f5c\uff0c\u5e76\u8fd4\u56de\u66ff\u6362\u7684\u6b21\u6570\u3002 # \u5728\u539f\u59cb\u5b57\u7b26\u4e32\u4e2d\uff0c\u7b2c\u4e00\u4e2a\u5339\u914d\u5230\u7684\"at\"\u88ab\u66ff\u6362\u4e3a\"ith\"\uff0c\u56e0\u6b64\u8f93\u51fa\u7ed3\u679c\u4e2d\u7684\"at\"\u53d8\u4e3a\"ith\"\uff0c\u5176\u4ed6\u5730\u65b9\u7684\"at\"\u4fdd\u6301\u4e0d\u53d8 $ awk 'BEGIN { str = \"water, water, everywhere\"; sub(/at/, \"ith\", str); print str }' wither, water, everywhere # \u8fd4\u56de\u5339\u914d\u6b21\u6570 $ awk 'BEGIN { str = \"water, water, everywhere\"; str_new = sub(/at/, \"ith\", str); print str_new }' 1 $ echo \"2023:15:35 08:15:26\" | awk 'sub(/:/, \"-\", $0)' 2023 -15:35 08 :15:26 $ echo \"2023:15:35 08:15:26\" | awk 'sub(/:/, \"-\", $1)' 2023 -15:35 08 :15:26 $ echo \"2023:15:35 08:15:26\" | awk 'sub(/:/, \"-\", $2)' 2023 :15:35 08 -15:26 gsub(regexp, replacement [, target])\uff1a\u4ece\u5b57\u7b26\u4e32target\u4e2d\u641c\u7d22\u5339\u914dregexp\u7684\u5185\u5bb9\uff0c\u5e76\u628a\u5168\u90e8\u5339\u914d\u7684\u5185\u5bb9\u66ff\u6362\u4e3areplacement\u3002\u8d2a\u5a6a\u6a21\u5f0f\u3002 # \u5728\u539f\u59cb\u5b57\u7b26\u4e32\u4e2d\uff0c\u5c06\u6240\u6709\u5339\u914d\u5230\u7684\"at\"\u88ab\u66ff\u6362\u4e3a\"ith\" $ awk 'BEGIN { str = \"water, water, everywhere\"; gsub(/at/, \"ith\", str); print str }' wither, wither, everywhere # \u8fd4\u56de\u5339\u914d\u6b21\u6570 $ awk 'BEGIN { str = \"water, water, everywhere\"; str_new = gsub(/at/, \"ith\", str); print str_new }' 2 $ echo \"2023:15:35 08:15:26\" | awk 'gsub(/:/, \"-\", $0)' 2023 -15-35 08 -15-26 $ echo \"2023:15:35 08:15:26\" | awk 'gsub(/:/, \"-\", $1)' 2023 -15-35 08 :15:26 $ echo \"2023:15:35 08:15:26\" | awk 'gsub(/:/, \"-\", $2)' 2023 :15:35 08 -15-26 split(string, array, delimiter) \uff1a\u5c06\u5b57\u7b26\u4e32string\u6309\u6307\u5b9a\u5206\u9694\u7b26delimiter\u62c6\u5206\u6210\u6570\u7ec4array\u7684\u5143\u7d20\u3002 \u6ce8\u610f\uff1a\u7b2c\u4e00\u4e2a\u7d22\u5f15\u503c\u4e3a 1 \uff0c\u7b2c\u4e8c\u4e2a\u7d22\u5f15\u503c\u4e3a 2 . $ awk 'BEGIN { str = \"apple,banana,orange\"; split(str, fruits, \",\"); print fruits[2] }' banana $ head -n2 /etc/passwd | awk '{split($0, array, \":\")}END{print array[1]}' messagebus $ head -n2 /etc/passwd | awk '{split($0, array, \":\")}END{print array[2]}' x $ head -n2 /etc/passwd | awk '{split($0, array, \":\")}END{print array[3]}' 499 $ head -n2 /etc/passwd | awk '{split($0, array, \":\")}END{print array[7]}' /usr/bin/false index(string, search) \uff1a\u5728\u5b57\u7b26\u4e32\u4e2d\u67e5\u627e\u6307\u5b9a\u5b50\u4e32\u7684\u4f4d\u7f6e\u3002 $ awk 'BEGIN { str = \"Hello World\"; pos = index(str, \"World\"); print pos }' 7 sprintf(format, expression) \uff1a\u6839\u636e\u6307\u5b9a\u7684\u683c\u5f0f\u5c06\u8868\u8fbe\u5f0f\u8f6c\u6362\u4e3a\u5b57\u7b26\u4e32\u3002 $ awk 'BEGIN { num = 3.14159; str = sprintf(\"%.2f\", num); print str }' 3 .14 rand() \uff1a\u8fd4\u56de\u4e00\u4e2a\u968f\u673a\u6570\uff0c\u503c\u5728 0 \u548c 1 \u4e4b\u95f4\u5747\u5300\u5206\u5e03\u3002\u8fd9\u4e2a\u503c\u53ef\u4ee5\u662f 0 \uff0c\u4f46\u4e0d\u4f1a\u662f 1 \u3002\u4ece\u4e0b\u9762\u7684\u4f8b\u5b50\u53ef\u4ee5\u770b\u51fa\uff0c\u8fd0\u884c\u7ed3\u679c\u90fd\u662f\u4e00\u6837\u7684\uff0c\u6240\u4ee5\u4ea7\u751f\u968f\u673a\u6570\u7684\u79cd\u5b50\u662f\u4e00\u6837\u7684\u3002 $ awk 'BEGIN{print rand()}' 0 .924046 $ awk 'BEGIN{print rand()}' 0 .924046 $ awk 'BEGIN{print rand()}' 0 .924046 srand() \uff1a\u914d\u5408 rand() \u51fd\u6570\uff0c\u751f\u6210\u968f\u673a\u6570\u79cd\u5b50\u3002 $ awk 'BEGIN{srand();print rand()}' 0 .112006 $ awk 'BEGIN{srand();print rand()}' 0 .663431 $ awk 'BEGIN{srand();print rand()}' 0 .541305 int() \uff1a\u8fd4\u56de\u6574\u6570\u3002 $ awk 'BEGIN{srand();print int(rand()*100)}' 84 $ awk 'BEGIN{srand();print int(rand()*100)}' 66 $ awk 'BEGIN{srand();print int(rand()*100)}' 8 system(command) \uff1a\u6267\u884ccommand\u547d\u4ee4\uff08\u53ef\u4ee5\u662f\u4efb\u4f55\u6709\u6548\u7684Shell\u547d\u4ee4\uff09\u5e76\u8fd4\u56de\u547d\u4ee4\u7684\u9000\u51fa\u72b6\u6001\u7801\u3002\u5141\u8bb8\u5728 awk \u811a\u672c\u4e2d\u6267\u884c\u5916\u90e8\u547d\u4ee4\uff0c\u5e76\u83b7\u53d6\u547d\u4ee4\u6267\u884c\u7684\u7ed3\u679c\u3002 # \u6267\u884cls -l\u547d\u4ee4\uff0c\u5e76\u5c06\u547d\u4ee4\u7684\u9000\u51fa\u72b6\u6001\u7801\u5b58\u50a8\u5728status\u53d8\u91cf\u4e2d\uff0c\u5e76\u6253\u5370status\u53d8\u91cf\u7684\u503c $ awk 'BEGIN { status = system(\"ls -l\"); print \"Exit status:\", status }' total 0 drwxr-xr-x 1 vagrant users 70 Jan 2 15 :54 Desktop drwxr-xr-x 1 vagrant users 0 Jan 2 15 :54 Documents drwxr-xr-x 1 vagrant users 0 Jan 2 15 :54 Downloads drwxr-xr-x 1 vagrant users 0 Jan 2 15 :54 Music drwxr-xr-x 1 vagrant users 0 Jan 2 15 :54 Pictures drwxr-xr-x 1 vagrant users 0 Jan 2 15 :54 Public drwxr-xr-x 1 vagrant users 0 Jan 2 15 :54 Templates drwxr-xr-x 1 vagrant users 0 Jan 2 15 :54 Videos drwxr-xr-x 1 vagrant users 0 Mar 15 2022 bin Exit status: 0 $ awk 'BEGIN{score=100; system(\"echo your score is \" score)}' your score is 100 systime() \uff1a\u5f53\u524d\u65f6\u95f4\u52301970\u5e741\u67081\u65e5\u5230\u79d2\u6570 $ awk 'BEGIN{print systime()}' 1684158395 strftime(format, timestamp) \uff1a\u5c06\u65f6\u95f4\u6233timestamp\u8f6c\u6362\u4e3a\u6307\u5b9a\u683c\u5f0fformat\u7684\u65e5\u671f\u548c\u65f6\u95f4\u5b57\u7b26\u4e32\u3002timestamp\u901a\u5e38\u662f\u4e00\u4e2a\u4ee5\u79d2\u4e3a\u5355\u4f4d\u8868\u793a\u7684\u6574\u6570\u3002 \u5e38\u89c1\u7684\u683c\u5f0f\u5316\u5b57\u7b26\u4e32\u9009\u9879\uff1a %Y \uff1a\u56db\u4f4d\u6570\u7684\u5e74\u4efd\uff08\u4f8b\u5982\uff1a2023\uff09 %m \uff1a\u4e24\u4f4d\u6570\u7684\u6708\u4efd\uff0801-12\uff09 %d \uff1a\u4e24\u4f4d\u6570\u7684\u65e5\u671f\uff0801-31\uff09 %H \uff1a\u4e24\u4f4d\u6570\u7684\u5c0f\u65f6\uff0800-23\uff09 %M \uff1a\u4e24\u4f4d\u6570\u7684\u5206\u949f\uff0800-59\uff09 %S \uff1a\u4e24\u4f4d\u6570\u7684\u79d2\uff0800-60\uff09 %Z \uff1a\u65f6\u533a\u540d\u79f0\uff08\u4f8b\u5982\uff1aGMT\uff09 # \u5c06\u5f53\u524d\u65f6\u95f4\u6233\u8f6c\u6362\u4e3a\u683c\u5f0f\u4e3a\"YYYY-MM-DD HH:MM:SS\"\u7684\u65e5\u671f\u548c\u65f6\u95f4\u5b57\u7b26\u4e32 $ awk 'BEGIN { timestamp = systime(); str = strftime(\"%Y-%m-%d %H:%M:%S\", timestamp); print str }' 2023 -05-15 22 :01:35 # \u5c06\u5f53\u524d\u65f6\u95f4\u6233\u7684\u524d\u4e00\u5c0f\u65f6\uff083600\u79d2\uff09\u8f6c\u6362\u4e3a\u683c\u5f0f\u4e3a\"YYYY-MM-DD HH:MM:SS\"\u7684\u65e5\u671f\u548c\u65f6\u95f4\u5b57\u7b26\u4e32 $ awk 'BEGIN { timestamp = systime()-3600; str = strftime(\"%Y-%m-%d %H:%M:%S\", timestamp); print str }' 2023 -05-15 21 :01:43","title":"5.10.12.1.\u5185\u7f6e\u51fd\u6570"},{"location":"linux/SRE/05-RegExpress/#510122","text":"\u4e3e\u4f8b\uff1a $ cat > func.awk << EOF function max(x,y){ x>y?var=x:var=y return var } BEGIN{print max(a,b)} EOF $ awk -v a = 30 -v b = 20 -f func.awk 30 \u4e3e\u4f8b\uff1a \u5728\u4e0b\u9762\u7684\u4f8b\u5b50\u4e2d\uff0c\u6211\u4eec\u5b9a\u4e49\u4e86\u4e00\u4e2a\u540d\u4e3a square() \u7684\u81ea\u5b9a\u4e49\u51fd\u6570\uff0c\u5b83\u63a5\u53d7\u4e00\u4e2a\u53c2\u6570 x \uff0c\u5e76\u8fd4\u56de x \u7684\u5e73\u65b9\u3002\u7136\u540e\uff0c\u5728\u4e3b\u4ee3\u7801\u5757\u4e2d\uff0c\u6211\u4eec\u58f0\u660e\u4e86\u4e00\u4e2a\u53d8\u91cf num \u5e76\u8d4b\u503c\u4e3a 5 \u3002\u63a5\u4e0b\u6765\uff0c\u6211\u4eec\u8c03\u7528\u4e86\u81ea\u5b9a\u4e49\u51fd\u6570 square() \uff0c\u4f20\u9012 num \u4f5c\u4e3a\u53c2\u6570\uff0c\u5e76\u5c06\u8fd4\u56de\u503c\u5b58\u50a8\u5728\u53d8\u91cf result \u4e2d\u3002\u6700\u540e\uff0c\u6211\u4eec\u6253\u5370\u51fa result \u7684\u503c\u3002 $ cat > func.awk << EOF # \u81ea\u5b9a\u4e49\u51fd\u6570\uff1a\u8ba1\u7b97\u5e73\u65b9 function square(x) { return x * x; } # \u4f7f\u7528\u81ea\u5b9a\u4e49\u51fd\u6570 { num = 5; result = square(num); print \"\u5e73\u65b9\u7ed3\u679c\uff1a\" result; } EOF $ awk -f func.awk \u5e73\u65b9\u7ed3\u679c\uff1a25 \u4e3e\u4f8b\uff1a $ cat > func.awk << EOF # \u81ea\u5b9a\u4e49\u51fd\u6570\uff1a\u8ba1\u7b97\u6570\u7ec4\u5e73\u5747\u503c function calculateAverage(arr, size) { sum = 0; for (i = 1; i <= size; i++) { sum += arr[i]; } return sum / size; } # \u4f7f\u7528\u81ea\u5b9a\u4e49\u51fd\u6570 { # \u5b9a\u4e49\u6570\u7ec4 numbers[1] = 10; numbers[2] = 20; numbers[3] = 30; numbers[4] = 40; numbers[5] = 50; # \u8ba1\u7b97\u6570\u7ec4\u7684\u5e73\u5747\u503c size = 5; average = calculateAverage(numbers, size); print \"\u6570\u7ec4\u7684\u5e73\u5747\u503c\uff1a\" average; } EOF $ awk -f func.awk \u6570\u7ec4\u7684\u5e73\u5747\u503c\uff1a30","title":"5.10.12.2.\u81ea\u5b9a\u4e49\u51fd\u6570"},{"location":"linux/SRE/05-RegExpress/#510123awk","text":"\u4e3e\u4f8b\uff1a # \u6ce8\u610f\u8f6c\u4e49 $ cat > passwd.awk << EOF {if(\\$3>=1000)print \\$1,\\$3} EOF $ awk -F: -f passwd.awk /etc/passwd nobody 65534 vagrant 1000 \u4e0a\u9762\u4f8b\u5b50\u4e5f\u53ef\u4ee5\u5199\u6210\u5982\u4e0b\u811a\u6b65\u683c\u5f0f\u3002 $ cat > test.awk << EOF #!/bin/awk -f # This is an awk script {if(\\$3>=1000)print \\$1,\\$3} EOF $ chmod +x test.awk $ ./test.awk -F: /etc/passwd nobody 65534 vagrant 1000 \u5411awk\u811a\u672c\u4f20\u9012\u53c2\u6570\uff1a \u683c\u5f0f\uff1a awkfile var=value var2=value2 ... inputfile \u8bf4\u660e\uff1a \u4e0a\u9762\u683c\u5f0f\u53d8\u91cf\u5728 BEGIN \u8fc7\u7a0b\u4e2d\u4e0d\u53ef\u7528\uff0c\u76f4\u5230\u9996\u884c\u8f93\u5165\u5b8c\u6210\u4ee5\u540e\uff0c\u53d8\u91cf\u624d\u53ef\u7528\u3002 \u53ef\u4ee5\u901a\u8fc7 -v \u53c2\u6570\uff0c\u8ba9 awk \u5728\u6267\u884c BEGIN \u4e4b\u524d\u5f97\u5230\u53d8\u91cf\u3002 \u547d\u4ee4\u884c\u4e2d\u6bcf\u4e00\u4e2a\u6307\u5b9a\u7684\u53d8\u91cf\u90fd\u9700\u8981\u4e00\u4e2a -v \u53c2\u6570\u3002 \u4e3e\u4f8b\uff1a # x=100\u5728BEGIN{print x}\u533a\u6bb5\u53ef\u7528 $ awk -v x = 100 'BEGIN{print x}{print x+100}' /etc/hosts 100 200 200 200 200 200 200 200 200 200 200 200 200 200 200 200 200 200 200 200 200 200 200 200 # \u4e0d\u52a0-v\u5219x=100\u5728BEGIN{print x}\u533a\u6bb5\u4e0d\u53ef\u7528 $ awk x = 100 'BEGIN{print x}{print x+100}' /etc/hosts awk: fatal: cannot open file ` BEGIN { print x }{ print x+100 } ' for reading (No such file or directory) # \u4fee\u6b63\u4e0a\u9762\u7684\u9519\u8bef\uff0c\u5c06x=100\u653e\u5728\u540e\u9762\uff0c\u56e0\u4e3a\u6ca1\u6709-v\uff0c\u6240\u4ee5x=100\u5728BEGIN{print x}\u533a\u6bb5\u4e0d\u53ef\u7528\uff0c\u7b2c\u4e00\u884c\u8f93\u51fa\u7a7a\u767d $ awk ' BEGIN { print x }{ print x+100 } ' x = 100 /etc/hosts 200 200 200 200 200 200 200 200 200 200 200 200 200 200 200 200 200 200 200 200 200 200 200","title":"5.10.12.3.awk\u811a\u672c"},{"location":"linux/SRE/05-RegExpress/#511","text":"\u663e\u793a /proc/meminfo \u6587\u4ef6\u4e2d\u4ee5\u5927\u5c0fs\u5f00\u5934\u7684\u884c\uff0c\u8981\u6c42\u4f7f\u7528\u4e24\u79cd\u65b9\u6cd5\u3002 cat /proc/meminfo | grep -i \"^s\" cat /proc/meminfo | grep \"^[sS]\" \u663e\u793a /etc/passwd \u6587\u4ef6\u4e2d\u4e0d\u4ee5 /bin/bash \u7ed3\u5c3e\u7684\u884c\u3002 grep -v \"/bin/bash $ \" /etc/passwd \u663e\u793a\u7528\u6237 rpc \u9ed8\u8ba4\u7684shell\u7a0b\u5e8f\u3002 $ grep \"rpc\" /etc/passwd | cut -d \":\" -f 7 /sbin/nologin \u627e\u51fa /etc/passwd \u4e2d\u7684\u4e24\u4f4d\u6216\u4e09\u4f4d\u6570\u3002 grep -Eo \"[:digit:]{2,3}\" /etc/passwd grep -Eo \"[0-9]{2,3}\" /etc/passwd \u8fd9\u91cc\u7528\u5230\u4e86 {} \uff0c\u5c5e\u4e8e\u6269\u5c55\u6b63\u5219\u7b26\u53f7\uff0c\u6240\u4ee5\u8981\u7528 -E \u3002 \u663e\u793aRocky 9\u7684 /etc/grub2.cfg \u6587\u4ef6\u4e2d\uff0c\u81f3\u5c11\u4ee5\u4e00\u4e2a\u7a7a\u767d\u5b57\u7b26\u5f00\u5934\u7684\u4e14\u540e\u9762\u6709\u975e\u7a7a\u767d\u5b57\u7b26\u7684\u884c\u3002\uff08\u6ce8\uff1a /etc/grub2.cfg \u5728openSUSE\u548cUbuntu\u4e2d\u6ca1\u6709\uff09 # \u4e0d\u542b\u9996\u5b57\u7b26\u4e3atab $ sudo grep \"^ \" /etc/grub2.cfg # \u5305\u542b\u9996\u5b57\u7b26\u4e3atab $ sudo grep \"^[[:space:]]\" /etc/grub2.cfg \u627e\u51fa netstat -tan \u547d\u4ee4\u7ed3\u679c\u4e2d\u4ee5 LISTEN \u540e\u8ddf\u4efb\u610f\u591a\u4e2a\u7a7a\u767d\u5b57\u7b26\u7ed3\u5c3e\u7684\u884c\u3002 netstat -tan | grep -E \"LISTEN[[:space:]]+\" \u663e\u793aRocky 9\u4e0a\u6240\u6709UID\u5c0f\u4e8e1000\u4ee5\u5185\u7684\u7528\u6237\u540d\u548cUID\u3002 cat /etc/passwd | cut -d \":\" -f 1 ,3 | grep -E \"\\:[0-9]{1,3} $ \" grep -E \"\\:[0-9]{1,3}\\:[0-9]{1,}\" /etc/passwd | cut -d \":\" -f 1 ,3 \u5728Rocky 9\u4e0a\u663e\u793a\u6587\u4ef6 /etc/passwd \u7528\u6237\u540d\u548cshell\u540c\u540d\u7684\u884c\u3002 $ grep -E \"^([[:alnum:]]+\\b).*\\1 $ \" /etc/passwd sync:x:5:0:sync:/sbin:/bin/sync shutdown:x:6:0:shutdown:/sbin:/sbin/shutdown halt:x:7:0:halt:/sbin:/sbin/halt \u5229\u7528 df \u548c grep \uff0c\u53d6\u51fa\u78c1\u76d8\u5404\u5206\u533a\u5229\u7528\u7387,\u5e76\u4ece\u5927\u5230\u5c0f\u6392\u5e8f\u3002 $ df | tr -s \" \" | cut -d \" \" -f 1 ,5 | sort -n -t \" \" -k 2 devtmpfs 0 % Filesystem Use% tmpfs 0 % tmpfs 0 % /dev/mapper/rl-home 1 % tmpfs 2 % /dev/mapper/rl-root 5 % /dev/nvme0n1p1 23 % \u663e\u793a\u4e09\u4e2a\u7528\u6237 root \uff0c sync \uff0c bin \u7684UID\u548c\u9ed8\u8ba4shell\u3002 $ grep \"^root:\\|^sync:\\|^bin:\" /etc/passwd | cut -d \":\" -f 1 ,7 root:/bin/bash bin:/usr/sbin/nologin \u4f7f\u7528 egrep \u53d6\u51fa /etc/default-1/text_2/local.3/grub \u4e2d\u5176\u57fa\u540d\u548c\u76ee\u5f55\u540d\u3002 # \u57fa\u540d $ echo \"/etc/default-1/text_2/local.3/grub\" | egrep -io \"[[:alpha:]]+ $ \" grub # \u76ee\u5f55\u540d $ echo \"/etc/default-1/text_2/local.3/grub\" | egrep -io \"/([[:alpha:]]+.|_?[[:alpha:]]|[[:alnum:]]+/){7}\" /etc/default-1/text_2/local.3/ \u7edf\u8ba1 last \u547d\u4ee4\u4e2d\u4ee5 vagrant \u767b\u5f55\u7684\u6bcf\u4e2a\u4e3b\u673aIP\u5730\u5740\u767b\u5f55\u6b21\u6570\u3002 $ last | grep vagrant | tr -s \" \" | cut -d \" \" -f 3 | grep -E \"([0-9]{1,3}\\.){1,3}[0-9]{1,3}\" | sort -n | uniq -c 24 192 .168.10.107 38 192 .168.10.109 17 192 .168.10.201 6 192 .168.10.210 2 192 .168.10.220 \u5229\u7528\u6269\u5c55\u6b63\u5219\u8868\u8fbe\u5f0f\u5206\u522b\u8868\u793a0-9\u300110-99\u3001100-199\u3001200-249\u3001250-255\u3002 [ 0 -9 ] | [ 0 -9 ]{ 2 } | 1 [ 0 -9 ]{ 2 } | 2 [ 0 -4 ][ 0 -9 ] | 25 [ 0 -5 ] \u663e\u793a ifconfig \u547d\u4ee4\u7ed3\u679c\u4e2d\u6240\u6709IPv4\u5730\u5740\u3002 $ ifconfig | grep -Eo \"([0-9]{1,3}\\.){3}[0-9]{1,3}\" | grep -v \"^255\" 192 .168.10.210 192 .168.10.255 127 .0.0.1 \u663e\u793a ip addr \u547d\u4ee4\u7ed3\u679c\u4e2d\u6240\u6709IPv4\u5730\u5740\u3002 $ ip addr show eth0 | grep inet | grep eth0 | tr -s \" \" | cut -d \" \" -f 3 | cut -d \"/\" -f 1 192 .168.10.210 $ ip addr show | grep -Eo \"([0-9]{1,3}\\.){3}[0-9]{1,3}\" | grep -v \"^255\" 127 .0.0.1 192 .168.10.210 192 .168.10.255 \u5c06\u6b64\u5b57\u7b26\u4e32Welcome to the linux world\u4e2d\u7684\u6bcf\u4e2a\u5b57\u7b26\u53bb\u91cd\u5e76\u6392\u5e8f\uff0c\u91cd\u590d\u6b21\u6570\u591a\u7684\u6392\u5230\u524d\u9762\u3002 $ echo \"Welcome to the linux world\" | grep -o [[ :alpha: ]] | sort | uniq -c | sort -nr 3 o 3 l 3 e 2 t 1 x 1 W 1 w 1 u 1 r 1 n 1 m 1 i 1 h 1 d 1 c \u5220\u9664 /etc/default/grub \u6587\u4ef6\u4e2d\u6240\u6709\u4ee5\u7a7a\u767d\u5f00\u5934\u7684\u884c\u884c\u9996\u7684\u7a7a\u767d\u5b57\u7b26\u3002 sed '/^$/d' /etc/default/grub \u5220\u9664 /etc/default/grub \u6587\u4ef6\u4e2d\u6240\u6709\u4ee5 # \u5f00\u5934\uff0c\u540e\u9762\u81f3\u5c11\u8ddf\u4e00\u4e2a\u7a7a\u767d\u5b57\u7b26\u7684\u884c\u7684\u884c\u9996\u7684 # \u548c\u7a7a\u767d\u5b57\u7b26\u3002 sed -r '/#[[:space:]]+/d;/#/d' /etc/default/grub \u4e0a\u9762\u8f93\u51fa\u7ed3\u679c\u4e2d\u5305\u542b\u7a7a\u767d\u884c\u3002 \u82e5\u8f93\u51fa\u4e2d\u5220\u9664\u7a7a\u767d\u884c\uff0c\u5219\uff1a sed -r '/#[[:space:]]+/d;/#/d;/^$/d' /etc/default/grub \u5728 /etc/fstab \u6bcf\u4e00\u884c\u884c\u9996\u589e\u52a0 # \u53f7\u3002 sed -r 's/(.*)/#&/' /etc/fstab \u5728 /etc/fstab \u6587\u4ef6\u4e2d\u4e0d\u4ee5 # \u5f00\u5934\u7684\u884c\u7684\u884c\u9996\u589e\u52a0 # \u53f7\uff08\u5305\u62ec\u7a7a\u884c\uff09\u3002 sed -r 's/^[^#].*/#&/' -r 's/^$/#/' /etc/default/grub \u901a\u8fc7\u547d\u4ee4 rpm -qa --last |awk -F ' ' '{print $1}' \u5f97\u5230\u6700\u65b0\u5b89\u88c5\u7684\u5305\u5217\u8868\u3002\u7edf\u8ba1\u6240\u6709 x86_64 \u7ed3\u5c3e\u7684\u5b89\u88c5\u5305\u540d\u4ee5 . \u5206\u9694\u5012\u6570\u7b2c\u4e8c\u4e2a\u5b57\u6bb5\u7684\u91cd\u590d\u6b21\u6570\u3002 $ rpm -qa --last | awk -F ' ' '{print $1}' | sed -nr '/x86_64$/s@.*\\.(.*)\\.x86_64@\\1@p' | sort -r | uniq -c 75 el9_0 563 el9 3 7 1 5 2 4 2 3 10 2 29 1 \u5728openSUSE\u4e2d\u7edf\u8ba1 /etc/rc.status \u6587\u4ef6\u4e2d\u6bcf\u4e2a\u5355\u8bcd\u7684\u51fa\u73b0\u6b21\u6570\uff0c\u5e76\u6392\u5e8f\uff08\u7528grep\u548csed\u4e24\u79cd\u65b9\u6cd5\u5206\u522b\u5b9e\u73b0\uff09\u3002 grep -Eo \"[a-zA-Z]+\" /etc/rc.status | sort | uniq -c cat /etc/rc.status | sed -r 's/[^[:alpha:]]+/\\n/g' | sed '/^$/d' | sort | uniq -c | sort -nr \u5c06\u6587\u672c\u6587\u4ef6\u7684n\u548cn+1\u884c\u5408\u5e76\u4e3a\u4e00\u884c\uff0cn\u4e3a\u5947\u6570\u884c\u3002 $ cat < sed.txt 1aa 2bb 3cc 4dd 5ee 6ff 7gg EOF $ sed -n 'N;s/\\n//p' sed.txt 1aa2bb 3cc4dd 5ee6ff $ sed 'N;s/\\n//' sed.txt 1aa2bb 3cc4dd 5ee6ff 7gg \u5bf9\u4e00\u4e32\u6570\u5b57\u8fdb\u884c\u6c42\u548c\u3002 $ cat < number.txt 1 2 3 4 5 6 EOF $ tr ' ' + < number.txt | bc 21 $ sum = 0 ; for i in ` cat number.txt ` ; do let sum += i ; done ; echo $sum 21 $ awk '{sum=0;for(i=1;i<=NF;i++){sum+=i};print sum}' number.txt 21 \u53d6\u51fa\u5b57\u7b26\u4e32\u4e2d\u7684\u6570\u5b57\u3002 $ echo 'kdajl;3k8jd33la5kj23f90ld02sakjflakjdslf' | awk -F \"\" ' { for(i=1;i<=NF;i++) { if($i ~ /[0-9]/) { str=(str $i) } }; print str }' 38335239002 host.log \u6587\u4ef6\u5185\u5bb9\u5982\u4e0b\uff0c\u63d0\u53d6 .edu.cn \u524d\u9762\u7684\u4e3b\u673a\u540d\uff0c\u5e76\u56de\u5199\u5230\u8be5\u6587\u4ef6\u4e2d\u3002 $ cat > host.log << EOF 1 www.edu.cn 2 blog.edu.cn 3 learning.edu.cn 4 java.edu.cn 5 nodejs.edu.cn 6 k8s.eud.cn 7 linux.edu.cn 8 python.edu.cn 9 learning.edu.cn 10 java.edu.cn 11 nodejs.edu.cn 12 www.edu.cn EOF # \u5bf9\u6bd4 $ awk -F '[ .]' '{print $1}' host.log 1 2 3 4 5 6 7 8 9 10 11 12 $ awk -F '[ .]' '{print $2}' host.log www blog learning java nodejs k8s linux python learning java nodejs www # \u4ee5\u7a7a\u683c\u6216\u8005.\u4e3a\u5206\u9694\u7b26\uff0c\u6253\u5370\u7b2c\u4e8c\u5217\uff08\u4e3b\u673a\u540d\uff09\uff0c\u8ffd\u52a0\u5199\u5165\u539f\u6587\u4ef6 $ awk -F '[ .]' '{print $2}' host.log >> host.log $ cat host.log 1 www.edu.cn 2 blog.edu.cn 3 learning.edu.cn 4 java.edu.cn 5 nodejs.edu.cn 6 k8s.eud.cn 7 linux.edu.cn 8 python.edu.cn 9 learning.edu.cn 10 java.edu.cn 11 nodejs.edu.cn 12 www.edu.cn www blog learning java nodejs k8s linux python learning java nodejs www \u7edf\u8ba1\u6587\u4ef6 /etc/fstab \u4e2d\u6bcf\u4e2a\u6587\u4ef6\u7cfb\u7edf\u7c7b\u578b\u51fa\u73b0\u7684\u6b21\u6570\u3002 # \u4ee5UUID\u5f00\u5934\uff0c\u4e00\u4e2a\u6216\u591a\u4e2a\u7a7a\u683c\u4e3a\u5206\u9694\u7b26\uff0c\u8bfb\u53d6\u7b2c\u4e09\u5217\uff08\u5373\u6587\u4ef6\u7cfb\u7edf\u7c7b\u578b\uff09\u5e76\u8ba1\u6570\u3002 $ awk -F ' +' '/^UUID/{fs[$3]++}END{for(i in fs){print i, fs[i]}}' /etc/fstab swap 1 btrfs 10 vfat 1 # \u65b9\u6cd52 $ awk -F ' +' '/^UUID/{print $3}' /etc/fstab | uniq -c 10 btrfs 1 swap 1 vfat \u7edf\u8ba1\u6587\u4ef6 /etc/fstab \u4e2d\u6bcf\u4e2a\u5355\u8bcd\u51fa\u73b0\u7684\u6b21\u6570\u3002 $ awk -F \"[^[:alpha:]]\" '{for(i=1;i<=NF;i++)word[$i]++}END{for(a in word)if(a!=\"\")print a,word[a]}' /etc/fstab swap 2 B 1 srv 2 btrfs 10 snapshots 2 vfat 1 opt 2 cbaef 10 UUID 12 E 1 ecf 1 CD 1 cf 1 arm 2 a 11 c 2 tmp 2 usr 2 var 2 afa 20 home 2 d 10 utf 1 e 2 efi 3 grub 2 boot 3 subvol 9 root 2 local 2 defaults 2 f 10 \u63d0\u53d6\u5b57\u7b26\u4e32 Yd$@C#M05MD9&8923+Vip3wZ!33*44&55 \u4e2d\u6240\u6709\u7684\u6570\u5b57\u3002 # \u5bf9\u6bd4\u5355\u5f15\u53f7\u548c\u53cc\u5f15\u53f7\u7684\u533a\u522b\u3002 $ echo \"Yd $@ C#M05MD9&8923+Vip3wZ!33*44&55\" echo \"Yd $@ C#M05MD9&8923+Vip3wZcgcreate -g cpu:mygroup44&55\" YdC#M05MD9 & 8923 +Vip3wZcgcreate -g cpu:mygroup44 & 55 $ echo 'Yd$@C#M05MD9&8923+Vip3wZ!33*44&55' Yd $@ C#M05MD9 & 8923 +Vip3wZ!33*44 & 55 $ echo 'Yd$@C#M05MD9&8923+Vip3wZ!33*44&55' | awk '{gsub(/[^0-9]/,\"\");print $0}' 05989233334455 $ echo 'Yd$@C#M05MD9&8923+Vip3wZ!33*44&55' | awk -F '[^0-9]' '{for(i=1;i<=NF;i++){printf \"%s\", $i}}' 05989233334455 $ echo 'Yd$@C#M05MD9&8923+Vip3wZ!33*44&55' | awk -F \"\" '{for(i=1;i<=NF;i++){if($i ~ /[[:digit:]]/){str=$i;str1=(str1 str)}};print str1}' 05989233334455 $ echo 'Yd$@C#M05MD9&8923+Vip3wZ!33*44&55' | awk -F '' '{for(i=1;i<=NF;i++){if($i ~ /[[:digit:]]/){str=$i;str1=(str1 str)}};print str1}' # \u6ce8\u610f\uff0c\u5982\u679c\u5199\u6210\u5982\u4e0b\u683c\u5f0f\uff0c\u5219\u62a5\u9519\u3002 $ echo 'Yd$@C#M05MD9&8923+Vip3wZ!33*44&55' | awk -F '' '{for(i=1;i<=NF;i++){if($i ~ /[[:digit:]]/){str=$i;str1=(str1 str)}};print str1}' # \u6ce8\u610f\uff0c\u5982\u679c\u5199\u6210\u5982\u4e0b\u683c\u5f0f\uff0c\u5219\u8f93\u51fa\u539f\u5b57\u7b26\u4e32\u3002 $ echo 'Yd$@C#M05MD9&8923+Vip3wZ!33*44&55' | awk -F ' ' '{for(i=1;i<=NF;i++){if($i ~ /[[:digit:]]/){str=$i;str1=(str1 str)}};print str1}' \u751f\u6210500\u4e2a\u968f\u673a\u6570\uff0c\u4fdd\u5b58\u5230\u6587\u4ef6random.txt\u4e2d\uff0c\u683c\u5f0f\u4e3a 100,20,61,98... \uff0c\u53d6\u51fa\u5176\u4e2d\u6700\u5927\u6574\u6570\u548c\u6700\u5c0f\u6574\u6570\u3002 $ str = \"\" ; for (( i = 1 ; i< = 500 ; i++ )) ; do if [ $i -ne 500 ] ; then str += \" $RANDOM ,\" ; else str += \" $RANDOM \" ; fi ; done ; echo \" $str \" > random.txt $ cat random.txt 11308 ,8764,2075,9411,...... $ awk -F, '{max=$1;min=$1;for(i=1;i<=NF;i++){if($i>max){max=$i}else{if($i200){system(\"iptables -A INPUT -s \" i \" -j REJECT;\")}}}' \u5c06\u4e0b\u9762\u5185\u5bb9\u4e2dFQDN\u53d6\u51fa\uff0c\u5e76\u6839\u636e\u5176\u8fdb\u884c\u8ba1\u6570\uff0c\u4ece\u9ad8\u5230\u4f4e\u6392\u5e8f\u3002 $ cat > fqdn.txt << EOF http://mail.edu.com/index.html http://www.edu.com/test.html http://study.edu.com/index.html http://blog.edu.com/index.html http://www.edu.com/images/logo.jpg http://blog.edu.com/20080102.html EOF $ awk -F \"/\" '{url[$3]++}END{for(i in url){print url[i], i}}' fqdn.txt | sort -nr 2 www.edu.com 2 blog.edu.com 1 study.edu.com 1 mail.edu.com \u5c06\u4ee5\u4e0b\u2f42\u672c\u4ee5inode\u4e3a\u6807\u8bb0\uff0c\u5bf9inode\u76f8\u540c\u7684counts\u8fdb\u2f8f\u7d2f\u52a0\uff0c\u5e76\u4e14\u7edf\u8ba1\u51fa\u540c\u4e00inode\u4e2d\uff0cbeginnumber\u7684\u6700\u5c0f\u503c\u548cendnumber\u7684\u6700\u5927\u503c\u3002 inode | beginnumber | endnumber | counts | 106 | 3363120000 | 3363129999 | 10000 | 106 | 3368560000 | 3368579999 | 20000 | 310 | 3337000000 | 3337000100 | 101 | 310 | 3342950000 | 3342959999 | 10000 | 310 | 3362120960 | 3362120961 | 2 | 311 | 3313460102 | 3313469999 | 9898 | 311 | 3313470000 | 3313499999 | 30000 | 311 | 3362120962 | 3362120963 | 2 | \u8f93\u51fa\u7684\u7ed3\u679c\u683c\u5f0f\u4e3a\uff1a 310 | 3337000000 | 3362120961 | 10103 | 311 | 3313460102 | 3362120963 | 39900 | 106 | 3363120000 | 3368579999 | 30000 | $ cat > inode.text << EOF inode|beginnumber|endnumber|counts| 106|3363120000|3363129999|10000| 106|3368560000|3368579999|20000| 310|3337000000|3337000100|101| 310|3342950000|3342959999|10000| 310|3362120960|3362120961|2| 311|3313460102|3313469999|9898| 311|3313470000|3313499999|30000| 311|3362120962|3362120963|2| EOF $ awk -F '|' -v OFS = '|' '/^[0-9]/{inode[$1]++; if(!bn[$1]){bn[$1]=$2}else if(bn[$1]>$2) {bn[$1]=$2}; if(en[$1]<$3)en[$1]=$3;cnt[$1]+=$(NF-1)} END{for(i in inode)print i,bn[i],en[i],cnt[i]}' inode.text 106 | 3363120000 | 3368579999 | 30000 310 | 3337000000 | 3362120961 | 10103 311 | 3313460102 | 3362120963 | 39900","title":"5.11.\u5c0f\u7ec3\u4e60"},{"location":"linux/SRE/06-FileLookup/","text":"\u7b2c\u516d\u7ae0 \u6587\u4ef6\u67e5\u627e \u00b6 \u5e38\u7528\u6587\u4ef6\u67e5\u627e\u547d\u4ee4\uff1a locate\u547d\u4ee4 \u00b6 locate \u662f\u4e00\u4e2a\u5728 Linux \u7cfb\u7edf\u4e0a\u7528\u4e8e\u5feb\u901f\u641c\u7d22\u6587\u4ef6\u548c\u76ee\u5f55\u7684\u547d\u4ee4\u3002\u5b83\u4f7f\u7528\u9884\u5148\u6784\u5efa\u7684\u6587\u4ef6\u6570\u636e\u5e93 /var/lib/mlocate/mlocate.db \u8fdb\u884c\u641c\u7d22\uff0c\u56e0\u6b64\u6bd4\u76f4\u63a5\u5728\u6587\u4ef6\u7cfb\u7edf\u4e0a\u641c\u7d22\u8981\u5feb\u5f97\u591a\u3002 \u4f7f\u7528 updatedb \u547d\u4ee4\u624b\u52a8\u66f4\u65b0\u6587\u4ef6\u6570\u636e\u5e93 /var/lib/mlocate/mlocate.db \uff0c\u7d22\u5f15\u6784\u5efa\u8fc7\u7a0b\u9700\u8981\u904d\u5386\u6574\u4e2a\u6839\u6587\u4ef6\u7cfb\u7edf\uff0c\u5f88\u6d88\u8017\u8d44\u6e90\u3002 \u6ce8\u610f\uff0c\u7531\u4e8e locate \u4f7f\u7528\u9884\u5148\u6784\u5efa\u7684\u6587\u4ef6\u6570\u636e\u5e93\uff0c\u56e0\u6b64\u5728\u66f4\u65b0\u6587\u4ef6\u6570\u636e\u5e93\u4e4b\u524d\uff0c\u65b0\u521b\u5efa\u6216\u79fb\u52a8\u7684\u6587\u4ef6\u53ef\u80fd\u4e0d\u4f1a\u7acb\u5373\u51fa\u73b0\u5728\u641c\u7d22\u7ed3\u679c\u4e2d\u3002 \u5728openSUSE 15\u4e2d\u9ed8\u8ba4\u6ca1\u6709\u5b89\u88c5\uff0c\u9700\u8981\u624b\u52a8\u5b89\u88c5\u4e0b\u9762\u7684\u8f6f\u4ef6\u5305\u3002 sudo zypper ref sudo zypper in mlocate sudo updatedb locate \u547d\u4ee4\u7684\u7279\u70b9\uff1a \u67e5\u627e\u901f\u5ea6\u5feb \u6a21\u7cca\u67e5\u627e \u975e\u5b9e\u65f6\u67e5\u627e \u641c\u7d22\u7684\u662f\u6587\u4ef6\u7684\u5168\u8def\u5f84\uff0c\u4e0d\u4ec5\u4ec5\u662f\u6587\u4ef6\u540d \u53ef\u80fd\u53ea\u641c\u7d22\u5f53\u524d\u7528\u6237\u5177\u5907\u8bfb\u53d6 r \u548c\u6267\u884c x \u6743\u9650\u7684\u76ee\u5f55 locate \u547d\u4ee4\u7684\u683c\u5f0f\uff1a locate [OPTIONS] PATTERN \u5e38\u7528\u9009\u9879\uff1a -i \uff1a\u5ffd\u7565\u5927\u5c0f\u5199\u3002 -r \uff1a\u4f7f\u7528\u6b63\u5219\u8868\u8fbe\u5f0f\u8fdb\u884c\u6a21\u5f0f\u5339\u914d\u3002 -l \uff1a\u4ec5\u663e\u793a\u6587\u4ef6\u8def\u5f84\uff0c\u800c\u4e0d\u663e\u793a\u6587\u4ef6\u540d\u3002 -c \uff1a\u4ec5\u663e\u793a\u5339\u914d\u7ed3\u679c\u7684\u8ba1\u6570\u3002 -b \uff1a\u53ea\u5339\u914d\u57fa\u672c\u540d\u79f0\u800c\u4e0d\u662f\u5168\u8def\u5f84\u540d\u3002 -n N \uff1a\u53ea\u5217\u4e3e\u524dN\u4e2a\u5339\u914d\u9879\u76ee\u3002 -q \uff1a\u5b89\u9759\u6a21\u5f0f\uff0c\u4e0d\u663e\u793a\u4efb\u4f55\u9519\u8bef\u4fe1\u606f\u3002 man locate \u83b7\u53d6\u66f4\u591a\u8be6\u7ec6\u4fe1\u606f\u548c\u9009\u9879\u8bf4\u660e\u3002 \u4e3e\u4f8b\uff1a\u641c\u7d22\u540d\u4e3a bashrc \u7684\u6587\u4ef6\uff0c\u6ce8\u610f\uff0c\u8fd9\u91cc\u662f\u641c\u7d22\u6587\u4ef6\u540d\u6216\u8def\u5f84\u540d\u4e2d\u5305\u542b bashrc \u7684\u6587\u4ef6 $ locate bashrc /etc/bash.bashrc /etc/skel/.bashrc /home/vagrant/.bashrc \u8981\u641c\u7d22\u4ee5 \"image\" \u5f00\u5934\u7684\u6587\u4ef6\uff0c\u5ffd\u7565\u5927\u5c0f\u5199\uff1a locate -i '^image' \u4e3e\u4f8b\uff1a\u4f7f\u7528\u6b63\u5219\u8868\u8fbe\u5f0f\u641c\u7d22\u4ee5 .conf \u4e3a\u6269\u5c55\u540d\u7684\u6587\u4ef6\uff1a locate -r '\\.conf$' find\u547d\u4ee4 \u00b6 find \u547d\u4ee4\u662f\u5b9e\u65f6\u67e5\u627e\u5de5\u5177\uff0c\u901a\u8fc7\u904d\u5386\u6307\u5b9a\u8def\u5f84\u5b8c\u6210\u6587\u4ef6\u67e5\u627e\u3002 \u7279\u70b9\uff1a \u67e5\u627e\u901f\u5ea6\u7565\u6162 \u7cbe\u786e\u67e5\u627e \u5b9e\u65f6\u67e5\u627e \u67e5\u627e\u6761\u4ef6\u4e30\u5bcc \u53ef\u80fd\u53ea\u641c\u7d22\u5f53\u524d\u7528\u6237\u5177\u5907\u8bfb\u53d6 r \u548c\u6267\u884c x \u6743\u9650\u7684\u76ee\u5f55 find \u547d\u4ee4\u7684\u683c\u5f0f\uff1a find [OPTIONS] [PATH] [CONDITIONS] [ACTIONS] [PATH]\uff1a\u6307\u5b9a\u5177\u4f53\u76ee\u6807\u8def\u5f84\uff0c\u9ed8\u8ba4\u4e3a\u5f53\u524d\u76ee\u5f55\u3002 [CONDITIONS]\uff1a\u6307\u5b9a\u67e5\u627e\u6807\u51c6\uff0c\u53ef\u4ee5\u662f\u6587\u4ef6\u540d\u3001\u6587\u4ef6\u5927\u5c0f\u3001\u6587\u4ef6\u7c7b\u578b\u3001\u6743\u9650\u7b49\uff0c\u9ed8\u8ba4\u4e3a\u627e\u51fa\u6307\u5b9a\u8def\u5f84\u4e0b\u6240\u6709\u6587\u4ef6\u3002 [ACTIONS]\uff1a\u5bf9\u7b26\u5408\u6761\u4ef6\u7684\u6587\u4ef6\u6267\u884c\u7684\u64cd\u4f5c\uff0c\u9ed8\u8ba4\u8f93\u51fa\u5230\u5c4f\u5e55\u3002 -maxdepth level \uff1a\u6700\u5927\u641c\u7d22\u76ee\u5f55\u6df1\u5ea6\uff0c\u6307\u5b9a\u76ee\u5f55\u4e0b\u7684\u6587\u4ef6\u4e3a\u7b2c\u4e00\u7ea7\u3002 -mindepth level \uff1a\u6700\u5c0f\u641c\u7d22\u76ee\u5f55\u6df1\u5ea6\u3002 \u4e3e\u4f8b\uff1a\u53ea\u641c\u7d22 /etc \u76ee\u5f55\u7b2c\u4e8c\u7ea7\u3002 find /etc -maxdepth 2 -mindepth 2 find \u547d\u4ee4\u9ed8\u8ba4\u662f\u5148\u5904\u7406\u76ee\u5f55\uff0c\u518d\u5904\u7406\u76ee\u5f55\u5185\u90e8\u7684\u6587\u4ef6\u3002\u9009\u9879 -depth \u4f1a\u4fee\u6539 find \u547d\u4ee4\u5904\u7406\u4f18\u5148\u987a\u5e8f\uff0c\u5148\u5904\u7406\u76ee\u5f55\u5185\u90e8\u7684\u6587\u4ef6\uff0c\u518d\u5904\u7406\u76ee\u5f55\u3002 \u6839\u636e\u6587\u4ef6\u540d\u548cinode\u67e5\u627e\uff1a -name \"FILENAME\" \uff1a\u652f\u6301\u4f7f\u7528\u901a\u914d\u7b26\uff0c\u5982 * \uff0c \uff1f \uff0c [] \uff0c [^] \uff0c\u6ce8\u610f\uff0c\u901a\u914d\u7b26\u8981\u7528\u53cc\u5f15\u53f7\u3002 -iname \"FILENAME\" \uff1a\u4e0d\u533a\u5206\u5b57\u6bcd\u5927\u5c0f\u5199\u3002 -inum N \uff1a\u6309inode\u53f7\u67e5\u627e\u3002 -samefile NAME \uff1a\u67e5\u627e\u76f8\u540cinode\u53f7\u7684\u6587\u4ef6\u3002 -links N \uff1a\u94fe\u63a5\u6570\u4e3a N \u7684\u6587\u4ef6\u3002 -regex \"PATTERN\" \uff1a\u4ee5PATTERN\u5339\u914d\u6574\u4e2a\u6587\u4ef6\u8def\u5f84\uff0c\u800c\u975e\u6587\u4ef6\u540d\u79f0\u3002 xargs\u547d\u4ee4 \u00b6","title":"\u7b2c\u516d\u7ae0 \u6587\u4ef6\u67e5\u627e"},{"location":"linux/SRE/06-FileLookup/#_1","text":"\u5e38\u7528\u6587\u4ef6\u67e5\u627e\u547d\u4ee4\uff1a","title":"\u7b2c\u516d\u7ae0 \u6587\u4ef6\u67e5\u627e"},{"location":"linux/SRE/06-FileLookup/#locate","text":"locate \u662f\u4e00\u4e2a\u5728 Linux \u7cfb\u7edf\u4e0a\u7528\u4e8e\u5feb\u901f\u641c\u7d22\u6587\u4ef6\u548c\u76ee\u5f55\u7684\u547d\u4ee4\u3002\u5b83\u4f7f\u7528\u9884\u5148\u6784\u5efa\u7684\u6587\u4ef6\u6570\u636e\u5e93 /var/lib/mlocate/mlocate.db \u8fdb\u884c\u641c\u7d22\uff0c\u56e0\u6b64\u6bd4\u76f4\u63a5\u5728\u6587\u4ef6\u7cfb\u7edf\u4e0a\u641c\u7d22\u8981\u5feb\u5f97\u591a\u3002 \u4f7f\u7528 updatedb \u547d\u4ee4\u624b\u52a8\u66f4\u65b0\u6587\u4ef6\u6570\u636e\u5e93 /var/lib/mlocate/mlocate.db \uff0c\u7d22\u5f15\u6784\u5efa\u8fc7\u7a0b\u9700\u8981\u904d\u5386\u6574\u4e2a\u6839\u6587\u4ef6\u7cfb\u7edf\uff0c\u5f88\u6d88\u8017\u8d44\u6e90\u3002 \u6ce8\u610f\uff0c\u7531\u4e8e locate \u4f7f\u7528\u9884\u5148\u6784\u5efa\u7684\u6587\u4ef6\u6570\u636e\u5e93\uff0c\u56e0\u6b64\u5728\u66f4\u65b0\u6587\u4ef6\u6570\u636e\u5e93\u4e4b\u524d\uff0c\u65b0\u521b\u5efa\u6216\u79fb\u52a8\u7684\u6587\u4ef6\u53ef\u80fd\u4e0d\u4f1a\u7acb\u5373\u51fa\u73b0\u5728\u641c\u7d22\u7ed3\u679c\u4e2d\u3002 \u5728openSUSE 15\u4e2d\u9ed8\u8ba4\u6ca1\u6709\u5b89\u88c5\uff0c\u9700\u8981\u624b\u52a8\u5b89\u88c5\u4e0b\u9762\u7684\u8f6f\u4ef6\u5305\u3002 sudo zypper ref sudo zypper in mlocate sudo updatedb locate \u547d\u4ee4\u7684\u7279\u70b9\uff1a \u67e5\u627e\u901f\u5ea6\u5feb \u6a21\u7cca\u67e5\u627e \u975e\u5b9e\u65f6\u67e5\u627e \u641c\u7d22\u7684\u662f\u6587\u4ef6\u7684\u5168\u8def\u5f84\uff0c\u4e0d\u4ec5\u4ec5\u662f\u6587\u4ef6\u540d \u53ef\u80fd\u53ea\u641c\u7d22\u5f53\u524d\u7528\u6237\u5177\u5907\u8bfb\u53d6 r \u548c\u6267\u884c x \u6743\u9650\u7684\u76ee\u5f55 locate \u547d\u4ee4\u7684\u683c\u5f0f\uff1a locate [OPTIONS] PATTERN \u5e38\u7528\u9009\u9879\uff1a -i \uff1a\u5ffd\u7565\u5927\u5c0f\u5199\u3002 -r \uff1a\u4f7f\u7528\u6b63\u5219\u8868\u8fbe\u5f0f\u8fdb\u884c\u6a21\u5f0f\u5339\u914d\u3002 -l \uff1a\u4ec5\u663e\u793a\u6587\u4ef6\u8def\u5f84\uff0c\u800c\u4e0d\u663e\u793a\u6587\u4ef6\u540d\u3002 -c \uff1a\u4ec5\u663e\u793a\u5339\u914d\u7ed3\u679c\u7684\u8ba1\u6570\u3002 -b \uff1a\u53ea\u5339\u914d\u57fa\u672c\u540d\u79f0\u800c\u4e0d\u662f\u5168\u8def\u5f84\u540d\u3002 -n N \uff1a\u53ea\u5217\u4e3e\u524dN\u4e2a\u5339\u914d\u9879\u76ee\u3002 -q \uff1a\u5b89\u9759\u6a21\u5f0f\uff0c\u4e0d\u663e\u793a\u4efb\u4f55\u9519\u8bef\u4fe1\u606f\u3002 man locate \u83b7\u53d6\u66f4\u591a\u8be6\u7ec6\u4fe1\u606f\u548c\u9009\u9879\u8bf4\u660e\u3002 \u4e3e\u4f8b\uff1a\u641c\u7d22\u540d\u4e3a bashrc \u7684\u6587\u4ef6\uff0c\u6ce8\u610f\uff0c\u8fd9\u91cc\u662f\u641c\u7d22\u6587\u4ef6\u540d\u6216\u8def\u5f84\u540d\u4e2d\u5305\u542b bashrc \u7684\u6587\u4ef6 $ locate bashrc /etc/bash.bashrc /etc/skel/.bashrc /home/vagrant/.bashrc \u8981\u641c\u7d22\u4ee5 \"image\" \u5f00\u5934\u7684\u6587\u4ef6\uff0c\u5ffd\u7565\u5927\u5c0f\u5199\uff1a locate -i '^image' \u4e3e\u4f8b\uff1a\u4f7f\u7528\u6b63\u5219\u8868\u8fbe\u5f0f\u641c\u7d22\u4ee5 .conf \u4e3a\u6269\u5c55\u540d\u7684\u6587\u4ef6\uff1a locate -r '\\.conf$'","title":"locate\u547d\u4ee4"},{"location":"linux/SRE/06-FileLookup/#find","text":"find \u547d\u4ee4\u662f\u5b9e\u65f6\u67e5\u627e\u5de5\u5177\uff0c\u901a\u8fc7\u904d\u5386\u6307\u5b9a\u8def\u5f84\u5b8c\u6210\u6587\u4ef6\u67e5\u627e\u3002 \u7279\u70b9\uff1a \u67e5\u627e\u901f\u5ea6\u7565\u6162 \u7cbe\u786e\u67e5\u627e \u5b9e\u65f6\u67e5\u627e \u67e5\u627e\u6761\u4ef6\u4e30\u5bcc \u53ef\u80fd\u53ea\u641c\u7d22\u5f53\u524d\u7528\u6237\u5177\u5907\u8bfb\u53d6 r \u548c\u6267\u884c x \u6743\u9650\u7684\u76ee\u5f55 find \u547d\u4ee4\u7684\u683c\u5f0f\uff1a find [OPTIONS] [PATH] [CONDITIONS] [ACTIONS] [PATH]\uff1a\u6307\u5b9a\u5177\u4f53\u76ee\u6807\u8def\u5f84\uff0c\u9ed8\u8ba4\u4e3a\u5f53\u524d\u76ee\u5f55\u3002 [CONDITIONS]\uff1a\u6307\u5b9a\u67e5\u627e\u6807\u51c6\uff0c\u53ef\u4ee5\u662f\u6587\u4ef6\u540d\u3001\u6587\u4ef6\u5927\u5c0f\u3001\u6587\u4ef6\u7c7b\u578b\u3001\u6743\u9650\u7b49\uff0c\u9ed8\u8ba4\u4e3a\u627e\u51fa\u6307\u5b9a\u8def\u5f84\u4e0b\u6240\u6709\u6587\u4ef6\u3002 [ACTIONS]\uff1a\u5bf9\u7b26\u5408\u6761\u4ef6\u7684\u6587\u4ef6\u6267\u884c\u7684\u64cd\u4f5c\uff0c\u9ed8\u8ba4\u8f93\u51fa\u5230\u5c4f\u5e55\u3002 -maxdepth level \uff1a\u6700\u5927\u641c\u7d22\u76ee\u5f55\u6df1\u5ea6\uff0c\u6307\u5b9a\u76ee\u5f55\u4e0b\u7684\u6587\u4ef6\u4e3a\u7b2c\u4e00\u7ea7\u3002 -mindepth level \uff1a\u6700\u5c0f\u641c\u7d22\u76ee\u5f55\u6df1\u5ea6\u3002 \u4e3e\u4f8b\uff1a\u53ea\u641c\u7d22 /etc \u76ee\u5f55\u7b2c\u4e8c\u7ea7\u3002 find /etc -maxdepth 2 -mindepth 2 find \u547d\u4ee4\u9ed8\u8ba4\u662f\u5148\u5904\u7406\u76ee\u5f55\uff0c\u518d\u5904\u7406\u76ee\u5f55\u5185\u90e8\u7684\u6587\u4ef6\u3002\u9009\u9879 -depth \u4f1a\u4fee\u6539 find \u547d\u4ee4\u5904\u7406\u4f18\u5148\u987a\u5e8f\uff0c\u5148\u5904\u7406\u76ee\u5f55\u5185\u90e8\u7684\u6587\u4ef6\uff0c\u518d\u5904\u7406\u76ee\u5f55\u3002 \u6839\u636e\u6587\u4ef6\u540d\u548cinode\u67e5\u627e\uff1a -name \"FILENAME\" \uff1a\u652f\u6301\u4f7f\u7528\u901a\u914d\u7b26\uff0c\u5982 * \uff0c \uff1f \uff0c [] \uff0c [^] \uff0c\u6ce8\u610f\uff0c\u901a\u914d\u7b26\u8981\u7528\u53cc\u5f15\u53f7\u3002 -iname \"FILENAME\" \uff1a\u4e0d\u533a\u5206\u5b57\u6bcd\u5927\u5c0f\u5199\u3002 -inum N \uff1a\u6309inode\u53f7\u67e5\u627e\u3002 -samefile NAME \uff1a\u67e5\u627e\u76f8\u540cinode\u53f7\u7684\u6587\u4ef6\u3002 -links N \uff1a\u94fe\u63a5\u6570\u4e3a N \u7684\u6587\u4ef6\u3002 -regex \"PATTERN\" \uff1a\u4ee5PATTERN\u5339\u914d\u6574\u4e2a\u6587\u4ef6\u8def\u5f84\uff0c\u800c\u975e\u6587\u4ef6\u540d\u79f0\u3002","title":"find\u547d\u4ee4"},{"location":"linux/SRE/06-FileLookup/#xargs","text":"","title":"xargs\u547d\u4ee4"},{"location":"linux/SRE/07-FilePacking/","text":"\u7b2c\u4e03\u7ae0 \u6587\u4ef6\u6253\u5305\u548c\u89e3\u5305 \u00b6 \u5e38\u7528\u6587\u4ef6\u6253\u5305\u548c\u89e3\u5305\u547d\u4ee4\uff1a compress\u548cuncompress gzip\u548cgunzip bzip2\u548cbunzip2 xz\u548cunxz zip\u548cunzip tar","title":"\u7b2c\u4e03\u7ae0 \u6587\u4ef6\u6253\u5305\u548c\u89e3\u5305"},{"location":"linux/SRE/07-FilePacking/#_1","text":"\u5e38\u7528\u6587\u4ef6\u6253\u5305\u548c\u89e3\u5305\u547d\u4ee4\uff1a compress\u548cuncompress gzip\u548cgunzip bzip2\u548cbunzip2 xz\u548cunxz zip\u548cunzip tar","title":"\u7b2c\u4e03\u7ae0 \u6587\u4ef6\u6253\u5305\u548c\u89e3\u5305"},{"location":"python/","text":"Content \u00b6 Memo Python\u5b66\u4e60\u7684\u7b14\u8bb0\u3002 Python\u57fa\u7840\u77e5\u8bc6\uff0c\u6765\u6e90\u4e8e\u53c2\u52a0\u7684\u5404\u79cd\u5728\u7ebf\u57fa\u7840\u8bfe\u7a0b\u6c47\u96c6\u800c\u6210\u3002 \u300a\u5229\u7528Python\u8fdb\u884c\u6570\u636e\u5206\u6790\uff08\u539f\u4e66\u7b2c2\u7248\uff09\u300b\uff08Python for Data Analysis, 2rd Edition\uff09\u5b66\u4e60\u7b14\u8bb0 Git: Python For Data Analysis \u300a\u6570\u636e\u7ed3\u6784\uff08Python\u8bed\u8a00\u63cf\u8ff0\uff09\uff08\u7b2c2\u7248\uff09\u300b\uff08Fundamentals of Python: Data Structures 2 nd Edition\uff09\u5b66\u4e60\u7b14\u8bb0\u3002 \u300aEffective Python\uff1a\u7f16\u5199\u9ad8\u8d28\u91cfPython\u4ee3\u7801\u768490\u4e2a\u6709\u6548\u65b9\u6cd5\uff08\u539f\u4e66\u7b2c2\u7248\uff09\u300b\uff08Effective Python: 90 Specific Ways to Write Better Python, Second Edition\uff09 Git: Effective Python \u5c0f\u7a0b\u5e8f\u6f14\u793a\uff0c\u6765\u6e90\u4e8e\u53c2\u52a0\u7684\u5404\u79cd\u5728\u7ebf\u57fa\u7840\u8bfe\u7a0b\u3002","title":"Index"},{"location":"python/#content","text":"Memo Python\u5b66\u4e60\u7684\u7b14\u8bb0\u3002 Python\u57fa\u7840\u77e5\u8bc6\uff0c\u6765\u6e90\u4e8e\u53c2\u52a0\u7684\u5404\u79cd\u5728\u7ebf\u57fa\u7840\u8bfe\u7a0b\u6c47\u96c6\u800c\u6210\u3002 \u300a\u5229\u7528Python\u8fdb\u884c\u6570\u636e\u5206\u6790\uff08\u539f\u4e66\u7b2c2\u7248\uff09\u300b\uff08Python for Data Analysis, 2rd Edition\uff09\u5b66\u4e60\u7b14\u8bb0 Git: Python For Data Analysis \u300a\u6570\u636e\u7ed3\u6784\uff08Python\u8bed\u8a00\u63cf\u8ff0\uff09\uff08\u7b2c2\u7248\uff09\u300b\uff08Fundamentals of Python: Data Structures 2 nd Edition\uff09\u5b66\u4e60\u7b14\u8bb0\u3002 \u300aEffective Python\uff1a\u7f16\u5199\u9ad8\u8d28\u91cfPython\u4ee3\u7801\u768490\u4e2a\u6709\u6548\u65b9\u6cd5\uff08\u539f\u4e66\u7b2c2\u7248\uff09\u300b\uff08Effective Python: 90 Specific Ways to Write Better Python, Second Edition\uff09 Git: Effective Python \u5c0f\u7a0b\u5e8f\u6f14\u793a\uff0c\u6765\u6e90\u4e8e\u53c2\u52a0\u7684\u5404\u79cd\u5728\u7ebf\u57fa\u7840\u8bfe\u7a0b\u3002","title":"Content"},{"location":"python/DataAnalysis/ch01/","text":"NumPy\u57fa\u7840 \u00b6 \u5305\u542b\u4ee5\u4e0b\u5185\u5bb9\uff1a \u591a\u7ef4\u6570\u7ec4\u5bf9\u8c61 \u901a\u7528\u51fd\u6570 \u9762\u5411\u6570\u7ec4\u7f16\u7a0b \u4f7f\u7528\u6570\u7ec4\u8fdb\u884c\u6587\u4ef6\u8f93\u5165\u548c\u8f93\u51fa \u7ebf\u6027\u4ee3\u6570 \u4f2a\u968f\u673a\u6570\u751f\u6210 \u793a\u4f8b\uff1a\u968f\u673a\u6f2b\u6b65 \u591a\u7ef4\u6570\u7ec4\u5bf9\u8c61ndarry \u00b6 \u522b\u540d\u7ea6\u5b9a \u00b6 import numpy as np import pandas as pd import matplotlib.pyplot as plt \u5b89\u88c5matplotlib\u4e2d\u6587\u5b57\u4f53 \u00b6 \u67e5\u770b\u5b57\u4f53\u8def\u5f84 >>> import matplotlib >>> print(matplotlib.matplotlib_fname()) /home/james/.local/lib/python3.6/site-packages/matplotlib/mpl-data/matplotlibrc \u4e0b\u8f7d\u4e2d\u6587\u5b57\u4f53\u3002\u7f51\u5740 https://www.fontpalace.com/font-download/SimHei/,\u5e76\u62f7\u8d1d\u5230\u4e0b\u9762\u7684\u8def\u5f84\u4e0b james@lizard:~/Downloads> cp SimHei.ttf /home/james/.local/lib/python3.6/site-packages/matplotlib/mpl-data/fonts/ttf/ \u67e5\u770bmatplotlib\u7684\u5b57\u4f53\u7f13\u5b58\u76ee\u5f55\u3002 >>> import matplotlib >>> print(matplotlib.get_cachedir()) /home/james/.cache/matplotlib \u5220\u9664\u8fd9\u4e2a\u76ee\u5f55 james@lizard:~> rm -rf /home/james/.cache/matplotlib \u7f16\u8f91matplotlibrc\u6587\u4ef6 /home/james/.local/lib/python3.6/site-packages/matplotlib/mpl-data/matplotlibrc \uff0c\u505a\u5982\u4e0b\u4fee\u6539\u3002 \u5b9a\u4f4d\u8fd9\u4e00\u884c\uff0c\u53bb\u6389\u6ce8\u91ca\u7b26 # font.family: sans-serif \u5b9a\u4f4d\u8fd9\u4e00\u884c\uff0c\u53bb\u6389\u6ce8\u91ca\u7b26 # \uff0c\u5e76\u6dfb\u52a0 SimHei \uff0c\u4fee\u6539\u540e\u4e3a font.serif: SimHei, DejaVu Serif, Bitstream Vera Serif, Computer Modern Roman, New Century Schoolbook, Century Schoolbook L, Utopia, ITC Bookman, Bookman, Nimbus Roman No9 L, Times New Roman, Times, Palatino, Charter, serif \u5b9a\u4f4d\u8fd9\u4e00\u884c\uff0c\u53bb\u6389\u6ce8\u91ca\u7b26 # \uff0c\u5e76\u6dfb\u52a0 SimHei \uff0c\u4fee\u6539\u540e\u4e3a font.sans-serif: SimHei, DejaVu Sans, Bitstream Vera Sans, Computer Modern Sans Serif, Lucida Grande, Verdana, Geneva, Lucid, Arial, Helvetica, Avant Garde, sans-serif \u5b9a\u4f4d\u8fd9\u4e00\u884c\uff0c\u53bb\u6389\u6ce8\u91ca\u7b26 # \uff0c\u5e76\u628a True \u6539\u4e3a False \uff0c\u4fee\u6539\u540e\u4e3a axes.unicode_minus: False \u8bbe\u7f6ematplotlib\u540e\u7aef\u6e32\u67d3\u5668 \u00b6 \u5728\u4f7f\u7528matplotlib\u8f93\u51fa\u56fe\u50cf\u65f6\uff0c\u5982\u679c\u9047\u5230\u65e0\u6cd5\u663e\u793a\u56fe\u50cf\u7684\u9519\u8bef UserWarning: Matplotlib is currently using agg, which is a non-GUI backend, so cannot show the figure\u3002 \uff0c\u53ef\u4ee5\u5c1d\u8bd5\u4e0b\u9762\u7684\u6b65\u9aa4\u89e3\u51b3\u3002 \u5b89\u88c5 python3-tk \u5305 james@lizard:~> sudo zypper in python3-tk \u6216\u8005\u901a\u8fc7 pip \u5b89\u88c5 tk \u5305 james@lizard:~> pip3 install tk Defaulting to user installation because normal site-packages is not writeable Collecting tk Downloading tk-0.1.0-py3-none-any.whl (3.9 kB) Installing collected packages: tk Successfully installed tk-0.1.0 \u4e00\u822c\u5b8c\u6210\u4e0a\u9762\u5b89\u88c5\u540e\uff0c\u7a0b\u5e8f\u5c31\u80fd\u81ea\u52a8\u663e\u793a\u56fe\u4e86\uff0c\u5982\u679c\u8fd8\u662f\u4e0d\u80fd\u663e\u793a\uff0c\u518d\u5c1d\u8bd5\u91cd\u65b0\u5b89\u88c5 matplotlib \u3002 pip3 ininstall matplotlib pip3 install matplotlib ndarray: N-\u7ef4\u6570\u7ec4\u5bf9\u8c61 \u00b6 \u4e00\u4e2andarray\u662f\u4e00\u4e2a\u901a\u7528\u7684\u591a\u7ef4\u540c\u7c7b\u6570\u636e\u5bb9\u5668\uff0c\u4e5f\u5c31\u662f\u8bf4\uff0c\u5b83\u5305\u542b\u7684\u6bcf\u4e00\u4e2a\u5143\u7d20\u5747\u4e3a**\u76f8\u540c\u7c7b\u578b**\uff1b \u6bcf\u4e00\u4e2a\u6570\u7ec4\u90fd\u6709\u4e00\u4e2ashape\u5c5e\u6027\uff0c\u7528\u6765\u8868\u5f81\u6570\u7ec4\u6bcf\u4e00\u7ef4\u5ea6\u7684\u6570\u91cf\uff1b \u6bcf\u4e00\u4e2a\u6570\u7ec4\u90fd\u6709\u4e00\u4e2adtype\u5c5e\u6027\uff0c\u7528\u6765\u63cf\u8ff0\u6570\u7ec4\u7684\u6570\u636e\u7c7b\u578b\uff1b \u4e0b\u9762\u662f\u6807\u51c6\u6570\u7ec4\u7684\u751f\u6210\u51fd\u6570 array: \u5c06\u8f93\u5165\u6570\u636e\uff08\u5217\u8868\u3001\u5143\u7ec4\u3001\u6570\u7ec4\uff0c\u5176\u4ed6\u5e8f\u5217\uff09\u8f6c\u6362\u4e3andarray\uff0c\u5982\u679c\u4e0d\u663e\u5f0f\u6307\u660e\u6570\u636e\u7c7b\u578b\uff0c\u5c06\u81ea\u52a8\u63a8\u65ad\uff1b\u9ed8\u8ba4\u590d\u5236\u6240\u6709\u7684\u8f93\u5165\u6570\u636e\u3002 asarray\uff1a\u5c06\u8f93\u5165\u8f6c\u6362\u4e3andarray\uff0c\u4f46\u5982\u679c\u8f93\u5165\u5df2\u7ecf\u662fndarray\u5219\u4e0d\u518d\u590d\u5236\u3002 arange\uff1aPython\u5185\u7f6e\u51fd\u6570range\u7684\u6570\u7ec4\u7248\uff0c\u8fd4\u56de\u4e00\u4e2a\u6570\u7ec4\u3002 \u4e0b\u9762\u662f\u7528 Numpy.random() \u4e00\u4e2a\u751f\u6210\u4e00\u4e2a\u968f\u673a\u6570\u7ec4\u7684\u4f8b\u5b50\uff0c\u6ce8\u610f data01 \u7684\u7c7b\u578b\u662f'numpy.ndarray'\u3002\u53ef\u4ee5\u5728ndarray\u7c7b\u578b\u6570\u7ec4\u4e0a\u53e0\u52a0\u4e00\u4e0b\u6570\u5b66\u64cd\u4f5c\u3002 data01 = np.random.randn(2, 3) print(type(data01)) # print(data01) # [[ 0.12047302 -1.13499045 -0.39311368] # [ 1.54046881 0.01254838 -3.65090952]] print(data01 * 10) # \u7ed9data\u52a0\u4e0a\u4e00\u4e2a\u6570\u5b66\u64cd\u4f5c, \u6240\u6709\u7684\u5143\u7d20\u90fd\u540c\u65f6\u4e58\u4ee5\u4e8610 # [[ 1.20473022 -11.3499045 -3.93113676] # [ 15.40468806 0.12548383 -36.50909515]] print(data01 + data01) # \u7ed9data\u52a0\u4e0a\u4e00\u4e2a\u6570\u5b66\u64cd\u4f5c, \u6570\u7ec4\u4e2d\u7684\u5bf9\u5e94\u5143\u7d20\u8fdb\u884c\u4e86\u76f8\u52a0 # [[ 0.24094604 -2.2699809 -0.78622735] # [ 3.08093761 0.02509677 -7.30181903]] print(data01.shape) # (2, 3) print(data01.dtype) # float64 \u5f53\u8868\u8fbe\u201c\u6570\u7ec4\u201d\u3001\u201cNumPy\u6570\u7ec4\u201d\u6216\u201cndarray\u201d\u65f6\uff0c\u90fd\u8868\u793a\u540c\u4e00\u4e2a\u5bf9\u8c61\uff1andarray\u5bf9\u8c61\u3002 \u770b\u4e0b\u9762\u7684\u4f8b\u5b50\uff1a data01 \u662f\u4e00\u4e2a\u5217\u8868\uff08list\uff09\u7c7b\u578b\uff0c\u901a\u8fc7 Numpy.array \u8f6c\u6362\u6210Numpy\u7684 ndarray \u7c7b\u578b\u3002 \u5728 np.array \u4e2d\uff0c\u9664\u975e\u663e\u5f0f\u5730\u6307\u5b9a\uff0c\u5982 np.array(data01, dtype=np.int8) \uff0c\u5426\u5219np.array\u4f1a\u81ea\u52a8\u63a8\u65ad\u751f\u6210\u6570\u7ec4\u7684\u6570\u636e\u7c7b\u578b array01.dtype \u3002 \u4f7f\u7528 astype() \u65b9\u6cd5\u663e\u5f0f\u5730\u8f6c\u6362\u6570\u7ec4\u7684\u6570\u636e\u7c7b\u578b\u3002\u4f7f\u7528 astype() \u65f6\u603b\u662f\u751f\u6210\u4e00\u4e2a*\u65b0\u7684\u6570\u7ec4*\uff0c\u5373\u4f7f\u4f60\u4f20\u5165\u7684dtype\u4e0e\u4e4b\u524d\u4e00\u6837\u3002 data02 \u662f\u4e00\u4e2a\u5d4c\u5957\u5217\u8868 [[1, 2, 3, 4], [5, 6, 7, 8]] \uff0c\u901a\u8fc7np.array()\u65b9\u6cd5\u8f6c\u6362\u6210\u591a\u7ef4\u6570\u7ec4\uff0c\u524d\u63d0\u662f\u6bcf\u4e2a\u5b50\u5217\u8868\u7684\u957f\u5ea6\u8981\u4e00\u81f4\u3002 data01 = [6, 7.5, 8, 0, 1] print(data01) # [6, 7.5, 8, 0, 1] print(type(data01)) # array01 = np.array(data01) print(\"\u77e9\u9635\u7c7b\u578b\", type(array01)) # \u77e9\u9635\u7c7b\u578b print(\"\u6837\u672c\u77e9\u9635\", array01) # \u6837\u672c\u77e9\u9635 [6. 7.5 8. 0. 1. ] print(\"\u6570\u7ec4\u7ef4\u5ea6\", array01.ndim) # \u6570\u7ec4\u7ef4\u5ea6 1 print(\"\u77e9\u9635\u5f62\u72b6\", array01.shape) # \u77e9\u9635\u5f62\u72b6 (5,) \u4e00\u884c\u4e94\u5217 print(\"\u77e9\u9635\u6570\u636e\u7c7b\u578b\", array01.dtype) # float64 data02 = [[1, 2, 3, 4], [5, 6, 7, 8]] array02 = np.array(data02) print(\"\u6837\u672c\u77e9\u9635\\n\", array02) # \u6837\u672c\u77e9\u9635 # [[1 2 3 4] # [5 6 7 8]] print(\"\u6570\u7ec4\u7ef4\u5ea6\", array02.ndim) # \u6570\u7ec4\u7ef4\u5ea6 2 print(\"\u77e9\u9635\u5f62\u72b6\", array02.shape) # \u77e9\u9635\u5f62\u72b6 (2, 4) print(\"\u77e9\u9635\u6570\u636e\u7c7b\u578b\", array02.dtype) # \u77e9\u9635\u6570\u636e\u7c7b\u578b int64 print(\"\u77e9\u96350\u8f74\u5411\u6c42\u548c\", array02.sum(axis=0)) # \u77e9\u96350\u8f74\u5411\u6c42\u548c [ 6 8 10 12] print(\"\u77e9\u96351\u8f74\u5411\u6c42\u548c\", array02.sum(axis=1)) # \u77e9\u96351\u8f74\u5411\u6c42\u548c [10 26] array03 = array02.astype(np.float64) print(array03.dtype) # float64 print(array03) # [[1. 2. 3. 4.] # [5. 6. 7. 8.]] zeros() \u65b9\u6cd5\u53ef\u4ee5\u4e00\u6b21\u6027\u521b\u9020\u51680\u6570\u7ec4\u3002 print(np.zeros(10)) # [0. 0. 0. 0. 0. 0. 0. 0. 0. 0.] ones() \u65b9\u6cd5\u53ef\u4ee5\u4e00\u6b21\u6027\u521b\u9020\u51681\u6570\u7ec4\u3002\u6ce8\u610f\uff0c\u4f20\u53c2shape\u662f\u4e00\u4e2a\u5143\u7ec4 (3, 5) \u3002 print(np.ones((3, 5))) # [[1. 1. 1. 1. 1.] # [1. 1. 1. 1. 1.] # [1. 1. 1. 1. 1.]] empty() \u65b9\u6cd5\u53ef\u4ee5\u521b\u5efa\u4e00\u4e2a\u6ca1\u6709\u521d\u59cb\u5316\u6570\u503c\u7684\u6570\u7ec4\u3002\u4f46\u662f\uff0c\u4f7f\u7528np.empty\u6765\u751f\u6210\u4e00\u4e2a\u51680\u6570\u7ec4\uff0c\u5e76\u4e0d\u53ef\u9760\uff0c\u6709\u4e9b\u65f6\u5019\u5b83\u53ef\u80fd\u4f1a\u8fd4\u56de\u672a\u521d\u59cb\u5316\u7684\u5783\u573e\u6570\u503c print(np.empty((2, 3, 2))) # [[[2.30116964e-316 0.00000000e+000] # [2.10077583e-312 6.79038654e-313] # [2.22809558e-312 2.14321575e-312]] # # [[2.35541533e-312 6.79038654e-313] # [2.22809558e-312 2.14321575e-312] # [2.46151512e-312 2.41907520e-312]]] NumPy\u8f74 \u00b6 \u4e00\u53e5\u8bdd\u603b\u7ed3\uff1a\u5c06NumPy\u8f74\u89c6\u4e3a\u6211\u4eec\u53ef\u4ee5\u6267\u884c\u64cd\u4f5c\u7684\u65b9\u5411\u3002 \u770b\u4e0b\u9762\u7684\u4f8b\u5b50\uff1a arr_1 = np.array([[1, 1, 1], [1, 1, 1]]) arr_2 = np.array([[9, 9, 9], [9, 9, 9]]) print(arr_1) # [[1 1 1] # [1 1 1]] print(arr_2) # [[9 9 9] # [9 9 9]] \u6cbf0\u8f74\u5408\u5e76\u7684\u601d\u8def\u662f\uff0c\u4e24\u4e2a\u6570\u7ec4\u6cbf0\u8f74\u65b9\u5411\uff0c\u54110\u8f74\u201c\u584c\u7f29\u201d\uff08collapse\uff09\u3002 result = np.concatenate([arr_1, arr_2], axis=0) print(result) # [[1 1 1] # [1 1 1] # [9 9 9] # [9 9 9]] \u6cbf1\u8f74\u5408\u5e76\u7684\u601d\u8def\u662f\uff0c\u4e24\u4e2a\u6570\u7ec4\u6cbf1\u8f74\u65b9\u5411\uff0c\u54111\u8f74\u201c\u584c\u7f29\u201d result = np.concatenate([arr_1, arr_2], axis=1) print(result) # [[1 1 1 9 9 9] # [1 1 1 9 9 9]] \u6211\u4eec\u6765\u770bNumPy\u7684\u4e09\u7ef4\u6570\u7ec4\u3002 array1 = np.arange(36).reshape((3, 3, 4)) print(array1) # [[[ 0 1 2 3] # [ 4 5 6 7] # [ 8 9 10 11]] # # [[12 13 14 15] # [16 17 18 19] # [20 21 22 23]] # # [[24 25 26 27] # [28 29 30 31] # [32 33 34 35]]] \u8fd9\u6837\u770b\u4f1a\u5bb9\u6613\u7406\u89e3\u4e00\u4e9b\uff0c0\u8f74\u67093\u884c\uff0c1\u8f74\u67093\u5217\uff0c2\u8f74\u67094\u4e2a\u5143\u7d20\uff1a [[[ 0 1 2 3], [ 4 5 6 7], [ 8 9 10 11]] [[12 13 14 15], [16 17 18 19], [20 21 22 23]] [[24 25 26 27], [28 29 30 31], [32 33 34 35]]] \u8f93\u51fa\uff1a\u8f740\u7d22\u5f15\u53f7\uff1a0\uff1b\u8f741\u7d22\u5f15\u53f7\uff1a0\uff1b\u8f742\u7d22\u5f15\u53f7\uff1a\u5168\u90e8 print(array1[0, 0, :]) # [0 1 2 3] \u8f93\u51fa\uff1a\u8f740\u7d22\u5f15\u53f7\uff1a0\uff1b\u8f741\u7d22\u5f15\u53f7\uff1a0\uff1b\u8f742\u7d22\u5f15\u53f7\uff1a1 print(array1[0, 0, 1]) # 1 NumPy\u6570\u7ec4\u7b97\u672f \u00b6 \u4e00\u4e2a**\u6807\u91cf**\u5c31\u662f\u4e00\u4e2a\u5355\u72ec\u7684\u6570\u3002\u4e00\u4e2a\u5411\u91cf\u5c31\u662f\u4e00\u5217\u6570\uff0c\u8fd9\u4e9b\u6570\u662f\u6709\u5e8f\u6392\u5217\u7684\u3002 \u77e9\u9635\u662f\u4e8c\u7ef4\u6570\u7ec4\uff0c\u5176\u4e2d\u7684\u6bcf\u4e00\u4e2a\u5143\u7d20\u88ab\u4e24\u4e2a\u7d22\u5f15\u800c\u975e\u4e00\u4e2a\u6240\u786e\u5b9a\u3002 \u51e0\u4f55\u4ee3\u6570\u4e2d\u5b9a\u4e49\u7684**\u5f20\u91cf**\u662f\u57fa\u4e8e\u5411\u91cf\u548c\u77e9\u9635\u7684\u63a8\u5e7f\uff0c\u6211\u4eec\u53ef\u4ee5**\u5c06\u6807\u91cf\u89c6\u4e3a\u96f6\u9636\u5f20\u91cf**\uff0c \u77e2\u91cf**\u89c6\u4e3a\u4e00\u9636\u5f20\u91cf\uff0c\u90a3\u4e48**\u77e9\u9635\u5c31\u662f\u4e8c\u9636\u5f20\u91cf \u3002 \u5e26\u6709\u6807\u91cf\u8ba1\u7b97\u7684\u7b97\u672f\u64cd\u4f5c\uff0c\u4f1a\u628a\u8ba1\u7b97\u53c2\u6570\u4f20\u9012\u7ed9\u6570\u7ec4\u7684\u6bcf\u4e00\u4e2a\u5143\u7d20\u3002 \u540c\u5c3a\u5bf8\u6570\u7ec4\u4e4b\u95f4\u7684\u6bd4\u8f83 array04 == array04 \uff0c\u4f1a\u4ea7\u751f\u4e00\u4e2a\u5e03\u5c14\u503c\u6570\u7ec4 \u4e0d\u540c\u5c3a\u5bf8\u7684\u6570\u7ec4\u95f4\u7684\u64cd\u4f5c\uff0c\u5c06\u4f1a\u7528\u5230 \u5e7f\u64ad\u7279\u6027\uff08broadcasting\uff09 \u3002 array04 = np.array([ [1, 2, 3, 4, 5], [3, 4, 5, 6, 7], [5, 6, 7, 8, 9] ], dtype=int) print(array04 + array04) # [[ 2 4 6 8 10] # [ 6 8 10 12 14] # [10 12 14 16 18]] print(array04 - array04) # [[0 0 0 0 0] # [0 0 0 0 0] # [0 0 0 0 0]] print(array04 * array04) # [[ 1 4 9 16 25] # [ 9 16 25 36 49] # [25 36 49 64 81]] print(array04 / array04) # [[1. 1. 1. 1. 1.] # [1. 1. 1. 1. 1.] # [1. 1. 1. 1. 1.]] print(1 / array04) # [[1. 0.5 0.33333333 0.25 0.2 ] # [0.33333333 0.25 0.2 0.16666667 0.14285714] # [0.2 0.16666667 0.14285714 0.125 0.11111111]] print(array04 == array04) # [[ True True True True True] # [ True True True True True] # [ True True True True True]] \u57fa\u7840\u7d22\u5f15\u4e0e\u5207\u7247 \u00b6 ndarray\u5bf9\u8c61\u7684\u5185\u5bb9\u53ef\u4ee5\u901a\u8fc7\u7d22\u5f15\uff08indexing\uff09\u6216\u5207\u7247\uff08slicing\uff09\u6765\u8bbf\u95ee\u548c\u4fee\u6539\uff0cndarray\u5bf9\u8c61\u4e2d\u7684\u5143\u7d20\u7d22\u5f15\u4ece\u96f6\u5f00\u59cb\u3002 \u6709\u4e09\u79cd\u53ef\u7528\u7684\u7d22\u5f15\u65b9\u6cd5\uff1a\u5b57\u6bb5\u8bbf\u95ee\uff0c\u57fa\u672c\u5207\u7247\u548c\u9ad8\u7ea7\u7d22\u5f15\u3002 \u7d22\u5f15\uff08indexing\uff09\uff1a\u83b7\u53d6\u6570\u7ec4\u4e2d\u7279\u5b9a\u4f4d\u7f6e\u5143\u7d20\u7684\u8fc7\u7a0b\u3002 \u5207\u7247\uff08slicing\uff09\uff1a\u83b7\u53d6\u6570\u7ec4\u5143\u7d20\u5b50\u96c6\u7684\u8fc7\u7a0b\u3002\u6570\u7ec4\u7684\u5207\u7247\u662f\u539f\u6570\u7ec4\u7684\u89c6\u56fe\u3002\u8fd9\u610f\u5473\u7740\u4efb\u4f55**\u5bf9\u4e8e\u89c6\u56fe\u7684\u4fee\u6539\u90fd\u4f1a\u53cd\u6620\u5230\u539f\u6570\u7ec4\u4e0a**\u3002\u6570\u7ec4\u7684\u5207\u7247, \u8fd4\u56de\u7684\u5bf9\u8c61\u662f\u964d\u4f4e\u4e00\u4e2a\u7ef4\u5ea6\u7684\u6570\u7ec4\u3002 \u4e00\u7ef4\u6570\u7ec4\u7684\u7d22\u5f15\u548c\u5207\u7247\uff1a\u4e0ePython\u7684\u5217\u8868\u7c7b\u4f3c\uff1a a[n] \uff1a\u8fd4\u56de\u7b2c n+1 \u4e2a\u5143\u7d20\u3002\u5982\u679c n \u4e3a\u8d1f\u6570\uff0c\u5219\u8fd4\u56de\u5012\u6570\u7b2c n \u4e2a\u5143\u7d20\u3002 a[n:m:k] \uff1a\u8d77\u59cb\u7f16\u53f7 n \uff0c\u7ec8\u6b62\u7f16\u53f7 m \uff0c\u6b65\u957f k \uff0c\u7528\u5192\u53f7\u5206\u5272\u3002 \u9075\u5faa\u5de6\u95ed\u53f3\u5f00\u7684\u539f\u5219 \uff0c\u5373 [n, m) \u3002\u5982\u679c n \u4e3a\u7a7a\uff0c\u5373 n = 0 \uff1b\u5982\u679c m \u4e3a\u7a7a\uff0c\u5373 m = len(a) \u3002 \u591a\u7ef4\u6570\u7ec4\u7684\u7d22\u5f15\u548c\u5207\u7247\uff1a a[n,m,k,...] \uff1a\u6bcf\u4e2a\u7ef4\u5ea6\u4e00\u4e2a\u7d22\u5f15\u503c\uff0c\u6700\u5916\u5c42\u5217\u8868\uff08list\uff09\u4e2d\u7b2c n \u4e2a\u5143\u7d20\uff0c\u6b21\u5916\u5c42\u5217\u8868\uff08list\uff09\u4e2d\u7b2c m \u4e2a\u5143\u7d20\uff0c\u4ee5\u6b64\u7c7b\u63a8\u3002\u5982\u679c n \u4e3a\u8d1f\u6570\uff0c\u5219\u8fd4\u56de\u5012\u6570\u7b2c n \u4e2a\u5143\u7d20\u3002 a[n1:m1:k1,n2:m2:k2,n3:m3:k3,...] \uff1a\u6bcf\u4e2a\u7ef4\u5ea6\u7684\u5207\u7247\u65b9\u6cd5\u4e0e\u4e00\u7ef4\u6570\u7ec4\u76f8\u540c\u3002\u987a\u5e8f\u4e3a\u4ece\u5916\u5230\u5185\u3002 array05 = np.arange(10) print(array05) # [0 1 2 3 4 5 6 7 8 9] # \u4ece\u7d22\u5f15\u503c5\u5f00\u59cb\u5230\u7d22\u5f15\u503c7\u7684\u4e00\u4e2a\u5207\u7247\u3002 print(array05[5:8]) # [5 6 7] array06 = array05[5:8] # \u4f20\u5165\u4e00\u4e2a\u6570\u503c\u7ed9\u6570\u7ec4\u7684\u5207\u7247\uff0c\u6570\u503c\u88ab\u4f20\u9012\u7ed9\u4e86\u6574\u4e2a\u5207\u7247\u3002\u4e0d\u5199\u5207\u7247\u503c\u7684[:]\u5c06\u4f1a\u5f15\u7528\u6570\u7ec4\u7684\u6240\u6709\u503c array06[:] = 12 print(array06) # [12 12 12] # \u5207\u7247\u7684\u4fee\u6539\u4f1a\u53cd\u6620\u5230\u539f\u6570\u7ec4\u4e0a print(array05) # [ 0 1 2 3 4 12 12 12 8 9] # \u8f93\u51fa3\u7ef4\u77e9\u9635\uff0c3\u884c3\u5217\uff0c\u51719\u4e2a\u5143\u7d20\uff0c\u6bcf\u4e2a\u5143\u7d20\u662f\u4e00\u4e2a\u542b3\u4e2a\u5143\u7d20\u7684\u5217\u8868 array07 = np.array([ [[0, 1, 2], [3, 4, 5], [6, 7, 8]], [[9, 0, 1], [2, 3, 4], [5, 6, 7]], [[8, 9, 0], [1, 2, 3], [4, 5, 6]], ]) # \u8f93\u51fa3\u7ef4\u77e9\u9635\uff0c\u663e\u793a\u539f\u77e9\u9635\u7684\u7b2c1\uff0c2\u884c\u76842\uff0c3\u5217\u5143\u7d20\uff0c\u4e0d\u8981\u628a\u7d22\u5f15\u53f7\u548c\u8fd9\u91cc\u7684\u8868\u8ff0\u884c\u53f7\u6df7\u6dc6\u3002 print(array07[:2, 1:]) # [[[3 4 5] [6 7 8]] # [[2 3 4] [5 6 7]]] print(array07[:2, 1:].shape) # (2, 2, 3) # \u964d\u7ef4\uff0c\u8f93\u51fa\u539f\u77e9\u9635\u7684\u7b2c3\u884c print(array07[2]) # [[8 9 0] [1 2 3] [4 5 6]] print(array07[2].shape) # (3, 3) # \u964d\u7ef4\uff0c\u8f93\u51fa\u539f\u77e9\u9635\u7684\u7b2c3\u884c print(array07[2, :]) # [[8 9 0] [1 2 3] [4 5 6]] print(array07[2, :].shape) # (3, 3) # \u964d\u7ef4\uff0c\u8f93\u51fa\u539f\u77e9\u9635\u7684\u7b2c3\u884c\uff08\u53ea\u6709\u4e09\u884c\uff0c\u6240\u4ee5[2:, :]\u7b49\u540c\u4e8e[2, :]\uff09 print(array07[2:, :]) # [[[8 9 0] [1 2 3] [4 5 6]]] print(array07[2:, :].shape) # (1, 3, 3) # \u8f93\u51fa\u539f\u77e9\u9635\u76841\uff0c2\u5217 print(array07[:, :2]) # [[[0 1 2] [3 4 5]] # [[9 0 1] [2 3 4]] # [[8 9 0] [1 2 3]]] print(array07[:, :2].shape) # (3, 2, 3) # \u964d\u7ef4\uff0c\u8f93\u51fa\u539f\u77e9\u9635\u7684\u7b2c2\u884c\u524d2\u4e2a\u5143\u7d20 print(array07[1, :2]) # [[9 0 1] [2 3 4]] print(array07[1, :2].shape) # (2, 3) # \u8f93\u51fa\u539f\u77e9\u9635\u7684\u7b2c2\u884c\u524d2\u4e2a\u5143\u7d20 print(array07[1:2, :2]) # [[[9 0 1] [2 3 4]]] print(array07[1:2, :2].shape) # (1, 2, 3) # \u5c06\u539f\u77e9\u9635\u7684\u7b2c2\u884c\u8d4b\u503c\u7ed9\u53d8\u91cf old_value = array07[2].copy() print(old_value) # [[8 9 0] [1 2 3] [4 5 6]] # \u4fee\u6539\u539f\u77e9\u9635\u7684\u7b2c2\u884c\u7684\u503c\uff0c\u6807\u91cf\u548c\u6570\u7ec4\u90fd\u53ef\u4ee5\u4f20\u9012\u7ed9 array07[2] array07[2] = 25 print(array07) # [[[ 0 1 2] [ 3 4 5] [ 6 7 8]] # [[ 9 0 1] [ 2 3 4] [ 5 6 7]] # [[25 25 25] [25 25 25] [25 25 25]]] # \u5c06\u53d8\u91cf\u503c\u8d4b\u503c\u7ed9\u539f\u77e9\u9635\u7684\u7b2c2\u884c array07[2] = old_value print(array07) # [[[0 1 2] [3 4 5] [6 7 8]] # [[9 0 1] [2 3 4] [5 6 7]] # [[8 9 0] [1 2 3] [4 5 6]]] \u5e03\u5c14\u7d22\u5f15 \u00b6 \u5e03\u5c14\u503c\u7d22\u5f15\uff08Boolean indexing\uff09\u662f\u901a\u8fc7\u4e00\u4e2a\u5e03\u5c14\u6570\u7ec4\u6765\u7d22\u5f15\u76ee\u6807\u6570\u7ec4\uff0c\u4ee5\u6b64\u627e\u51fa\u4e0e\u5e03\u5c14\u6570\u7ec4\u4e2d\u503c\u4e3aTrue\u7684\u5bf9\u5e94\u7684\u76ee\u6807\u6570\u7ec4\u4e2d\u7684\u6570\u636e\u3002\u5e03\u5c14\u6570\u7ec4\u7684\u957f\u5ea6\u5fc5\u987b\u4e0e\u76ee\u6807\u6570\u7ec4\u5bf9\u5e94\u7684\u8f74\u7684\u957f\u5ea6\u4e00\u81f4\u3002 \u4f7f\u7528\u5e03\u5c14\u503c\u7d22\u5f15\uff08Boolean indexing\uff09\u9009\u62e9\u6570\u636e\u65f6\uff0c\u603b\u662f\u751f\u6210\u6570\u636e\u7684\u62f7\u8d1d\uff0c\u5373\u4f7f\u8fd4\u56de\u7684\u6570\u7ec4\u5e76\u6ca1\u6709\u4efb\u4f55\u53d8\u5316\u3002 \u5047\u8bbe\u6211\u4eec\u7684\u6570\u636e\u90fd\u5728\u6570\u7ec4\u4e2d\uff0c\u5e76\u4e14\u6570\u7ec4\u4e2d\u7684\u6570\u636e\u662f\u4e00\u4e9b\u5b58\u5728\u91cd\u590d\u7684\u4eba\u540d\u3002\u7528randn\u51fd\u6570\u751f\u6210\u4e00\u4e9b\u6807\u51c6\u6b63\u6001(standard normal)\u5206\u5e03\u7684\u6570\u636e\u3002\u5047\u8bbe\u6bcf\u4e2a\u4eba\u540d\u90fd\u548cdata\u6570\u7ec4\u4e2d\u7684\u4e00\u884c\u76f8\u5bf9\u5e94\uff0c\u5e76\u4e14\u6211\u4eec\u60f3\u8981\u9009\u4e2d\u6240\u6709\u2019Bob\u2019\u5bf9\u5e94\u7684\u884c\u3002 names = np.array(['Bob', 'Joe', 'Will', 'Bob', 'Will', 'Joe', 'Joe'], dtype=' # \u56fe\u50cf\u6807\u9898 plt.title(\"$\\sqrt{x^2 + y^2}$ \u8ba1\u7b97\u503c\u7684\u7f51\u683c\u56fe\") # \u8f93\u51fa\u56fe\u50cf plt.show() \u8f93\u51fa\u56fe\u50cf\u4e3a\uff1a \u901a\u8fc7\u6761\u4ef6\u903b\u8f91\u64cd\u4f5c\u6570\u7ec4 \u00b6 numpy.where \u51fd\u6570\u662f\u4e09\u5143\u8868\u8fbe\u5f0f x if condition else y \u7684\u5411\u91cf\u5316\u7248\u672c\u3002 np.where \u7684\u7b2c\u4e8c\u4e2a\u548c\u7b2c\u4e09\u4e2a\u53c2\u6570\u5e76\u4e0d\u9700\u8981\u662f\u6570\u7ec4\uff0c\u5b83\u4eec\u53ef\u4ee5\u662f\u6807\u91cf\u3002 np.where \u5728\u6570\u636e\u5206\u6790\u4e2d\u7684\u4e00\u4e2a\u5178\u578b\u7528\u6cd5\u662f\u6839\u636e\u4e00\u4e2a\u6570\u7ec4\u6765\u751f\u6210\u4e00\u4e2a\u65b0\u7684\u6570\u7ec4\u3002 \u5047\u8bbe\u6211\u4eec\u6709\u4e00\u4e2a\u5e03\u5c14\u503c\u6570\u7ec4\u548c\u4e24\u4e2a\u6570\u503c\u6570\u7ec4\u3002\u5047\u8bbe cond \u4e2d\u7684\u5143\u7d20\u4e3a True \u65f6\uff0c\u6211\u4eec\u53d6 xarr \u4e2d\u7684\u5bf9\u5e94\u5143\u7d20\u503c\uff0c\u5426\u5219\u53d6 yarr \u4e2d\u7684\u5143\u7d20\u3002 xarray = np.array([1.1, 1.2, 1.3, 1.4, 1.5]) yarray = np.array([2.1, 2.2, 2.3, 2.4, 2.5]) cond = np.array([True, False, True, True, False]) \u901a\u8fc7\u5217\u8868\u63a8\u5bfc\u5f0f\u6765\u5b9e\u73b0\u4e0a\u8ff0\u9700\u6c42\u3002 \u7f3a\u70b9: \u9996\u5148\uff0c\u5982\u679c\u6570\u7ec4\u5f88\u5927\u7684\u8bdd\uff0c\u901f\u5ea6\u4f1a\u5f88\u6162\uff08\u56e0\u4e3a\u6240\u6709\u7684\u5de5\u4f5c\u90fd\u662f\u901a\u8fc7\u89e3\u91ca\u5668\u6765\u89e3\u91caPython\u4ee3\u7801\u5b8c\u6210\uff09\u3002 \u5176\u6b21\uff0c\u5f53\u6570\u7ec4\u662f\u591a\u7ef4\u65f6\uff0c\u5c31\u65e0\u6cd5\u51d1\u6548\u4e86\u3002 # \u901a\u8fc7\u5217\u8868\u63a8\u5bfc\u5f0f\u6765\u5b9e\u73b0 result = [(x if c else y) for x, y, c in zip(xarray, yarray, cond)] print(result) # [1.1, 2.2, 1.3, 1.4, 2.5] \u901a\u8fc7 np.where \u6765\u5b9e\u73b0\u4e0a\u8ff0\u9700\u6c42\u3002 result = np.where(cond, xarray, yarray) print(result) # [1.1 2.2 1.3 1.4 2.5] \u5047\u8bbe\u6709\u4e00\u4e2a\u968f\u673a\u751f\u6210\u7684\u77e9\u9635\u6570\u636e\uff0c\u4e0b\u9762\u4f7f\u7528np.where\u5b9e\u73b0\u66ff\u6362\u3002 array = np.random.randn(4, 4) print(\"\u6837\u672c\u77e9\u9635 \\n\", array) print(\"\u77e9\u9635\u5143\u7d20\u662f\u5426\u5927\u4e8e0 \\n\", array > 0) # \u5c06\u5176\u4e2d\u7684\u6b63\u503c\u90fd\u66ff\u6362\u4e3a2\uff0c\u5c06\u6240\u6709\u7684\u8d1f\u503c\u66ff\u6362\u4e3a-2 result03 = np.where(array > 0, 2, -2) print(\"\u5c06\u5176\u4e2d\u7684\u6b63\u503c\u90fd\u66ff\u6362\u4e3a2\uff0c\u5c06\u6240\u6709\u7684\u8d1f\u503c\u66ff\u6362\u4e3a-2 \\n\", result03) # \u4ec5\u5c06\u5176\u4e2d\u7684\u6b63\u503c\u90fd\u66ff\u6362\u4e3a2 result04 = np.where(array > 0, 2, array) print(\"\u4ec5\u5c06\u5176\u4e2d\u7684\u6b63\u503c\u90fd\u66ff\u6362\u4e3a2 \\n\", result04) # \u6837\u672c\u77e9\u9635 # [[-0.57177422 -0.34917512 2.20268075 1.99959296] # [ 0.67966599 2.67915099 -0.40528454 -0.80339907] # [-0.74406888 2.33802717 -0.74582936 0.59347128] # [ 0.68624473 0.65953112 -0.40871415 -0.68698878]] # \u77e9\u9635\u5143\u7d20\u662f\u5426\u5927\u4e8e0 # [[False False True True] # [ True True False False] # [False True False True] # [ True True False False]] # \u5c06\u5176\u4e2d\u7684\u6b63\u503c\u90fd\u66ff\u6362\u4e3a2\uff0c\u5c06\u6240\u6709\u7684\u8d1f\u503c\u66ff\u6362\u4e3a-2 # [[-2 -2 2 2] # [ 2 2 -2 -2] # [-2 2 -2 2] # [ 2 2 -2 -2]] # \u4ec5\u5c06\u5176\u4e2d\u7684\u6b63\u503c\u90fd\u66ff\u6362\u4e3a2 # [[-0.57177422 -0.34917512 2. 2. ] # [ 2. 2. -0.40528454 -0.80339907] # [-0.74406888 2. -0.74582936 2. ] # [ 2. 2. -0.40871415 -0.68698878]] \u6570\u5b66\u548c\u7edf\u8ba1\u65b9\u6cd5 \u00b6 NumPy\u6709\u4e00\u4e9b\u4e13\u95e8\u7684\u6570\u5b66\u51fd\u6570\uff0c\u7528\u6765\u8ba1\u7b97\u6574\u4e2a\u6570\u7ec4\u7edf\u8ba1\u503c\u6216\u8f74\u5411\u6570\u636e\u7684\u8ba1\u7b97\u3002\u4f8b\u5982\uff0c\u805a\u5408\u51fd\u6570\uff08\u901a\u5e38\u4e5f\u53eb\u7f29\u51cf\u51fd\u6570\uff09\uff0c\u5982sum\u3001mean\u548cstd\uff08\u6807\u51c6\u5dee\uff09\u3002 \u65e2\u53ef\u4ee5\u76f4\u63a5\u8c03\u7528\u6570\u7ec4\u5b9e\u4f8b\u7684\u65b9\u6cd5\uff0c\u4e5f\u53ef\u4ee5\u4f7f\u7528\u9876\u5c42\u7684NumPy\u51fd\u6570\u3002 \u4e3e\u4f8b\uff1a\u751f\u6210\u4e00\u4e9b\u6b63\u6001\u5206\u5e03\u7684\u968f\u673a\u6570\uff0c\u8ba1\u7b97\u90e8\u5206\u805a\u5408\u7edf\u8ba1\u6570\u636e\u3002 \u8fd9\u91cc\u518d\u5bf9\u8f74\u5411\u505a\u4e2a\u89e3\u91ca\uff0c np.random.randn(5, 4) \u4ea7\u751f\u7684\u4e8c\u7ef4\u6570\u7ec4\u662f\uff1a0\u8f74\u54115\u4e2a\u5143\u7d20, 1\u8f74\u54114\u4e2a\u5143\u7d20\u3002 # \u751f\u62102\u8f74\u6570\u7ec4 array = np.random.randn(5, 4) print(\"\u6837\u672c\u77e9\u9635 \\n\", array) print(\"\u77e9\u9635\u5143\u7d20\u5e73\u5747\u503c\", array.mean()) print(\"\u77e9\u9635\u5143\u7d20\u5e73\u5747\u503c\", np.mean(array)) print(\"\u77e9\u9635\u5143\u7d20\u548c\", array.sum()) print(\"\u77e9\u9635\u5143\u7d20\u548c\", np.sum(array)) print(\"0\u8f74\u5411\u7684\u7d2f\u548c\", array.sum(axis=0)) print(\"1\u8f74\u5411\u7684\u7d2f\u548c\", array.sum(axis=1)) print(\"1\u8f74\u5411\u7684\u5e73\u5747\u503c\", array.mean(axis=1)) # \u6837\u672c\u77e9\u9635 shape=(5, 4) 0\u8f74\u54115\u4e2a\u5143\u7d20, 1\u8f74\u54114\u4e2a\u5143\u7d20 # [[ 0.32532911 -0.00177984 -1.59432632 1.58375133] # [ 1.48921763 0.25202456 0.44076148 -1.02277289] # [-0.73490219 0.19197171 -0.22374362 0.52610852] # [-1.03531076 1.0595528 -0.11566501 0.34063544] # [-0.2122241 -0.81348187 1.70989712 -0.00732696]] # \u77e9\u9635\u5143\u7d20\u5e73\u5747\u503c 0.10788580775057008 # \u77e9\u9635\u5143\u7d20\u5e73\u5747\u503c 0.10788580775057008 # \u77e9\u9635\u5143\u7d20\u548c 2.1577161550114017 # \u77e9\u9635\u5143\u7d20\u548c 2.1577161550114017 # 0\u8f74\u5411\u7684\u7d2f\u548c [-0.16789031 0.68828737 0.21692365 1.42039545] # 1\u8f74\u5411\u7684\u7d2f\u548c [ 0.31297429 1.15923078 -0.24056558 0.24921247 0.67686419] # 1\u8f74\u5411\u7684\u5e73\u5747\u503c [ 0.07824357 0.28980769 -0.06014139 0.06230312 0.16921605] \u4e0b\u9762\u5217\u4e3e\u4e86\u5e38\u7528\u7684\u57fa\u7840\u6570\u7ec4\u7edf\u8ba1\u65b9\u6cd5\u3002 array = np.array([ [1, 2, 3, 4, 5], [3, 4, 5, 6, 7], [5, 6, 7, 8, 9] ], dtype=int) print(\"\u6837\u672c\u77e9\u9635 \\n\", array) print(\"\u8f74\u5411\u6c42\u548c\", array.sum()) print(\"\u8f74\u5411\u6c42\u548c\", array.sum(axis=0)) print(\"\u6570\u5b66\u5e73\u5747\", array.mean()) print(\"\u8f74\u5411\u6570\u5b66\u5e73\u5747\", array.mean(axis=0)) print(\"\u6807\u51c6\u5dee\", array.std(), \"\u65b9\u5dee\", array.var()) print(\"\u8f74\u5411\u6807\u51c6\u5dee\", array.std(axis=0), \"\u8f74\u5411\u65b9\u5dee\", array.var(axis=0)) print(\"\u6700\u5c0f\u503c\", array.min(), \"\u6700\u5927\u503c\", array.max()) print(\"\u8f74\u5411\u6700\u5c0f\u503c\", array.min(axis=0), \"\u8f74\u5411\u6700\u5927\u503c\", array.max(axis=0)) print(\"\u6700\u5c0f\u503c\u4f4d\u7f6e\", array.argmin(), \"\u6700\u5927\u503c\u4f4d\u7f6e\", array.argmax()) print(\"\u8f74\u5411\u6700\u5c0f\u503c\u4f4d\u7f6e\", array.argmin(axis=0), \"\u8f74\u5411\u6700\u5927\u503c\u4f4d\u7f6e\", array.argmax(axis=0)) print(\"\u7d2f\u79ef\u548c \\n\", array.cumsum()) print(\"\u8f74\u5411\u7d2f\u79ef\u548c \\n\", array.cumsum(axis=1)) print(\"\u7d2f\u79ef\u4e58\u79ef \\n\", array.cumprod()) print(\"\u8f74\u5411\u7d2f\u79ef\u4e58\u79ef \\n\", array.cumprod(axis=1)) # \u6837\u672c\u77e9\u9635 # [[1 2 3 4 5] # [3 4 5 6 7] # [5 6 7 8 9]] # \u8f74\u5411\u6c42\u548c 75 # \u8f74\u5411\u6c42\u548c [ 9 12 15 18 21] # \u6570\u5b66\u5e73\u5747 5.0 # \u8f74\u5411\u6570\u5b66\u5e73\u5747 [3. 4. 5. 6. 7.] # \u6807\u51c6\u5dee 2.160246899469287 \u65b9\u5dee 4.666666666666667 # \u8f74\u5411\u6807\u51c6\u5dee [1.63299316 1.63299316 1.63299316 1.63299316 1.63299316] \u8f74\u5411\u65b9\u5dee [2.66666667 2.66666667 2.66666667 2.66666667 2.66666667] # \u6700\u5c0f\u503c 1 \u6700\u5927\u503c 9 # \u8f74\u5411\u6700\u5c0f\u503c [1 2 3 4 5] \u8f74\u5411\u6700\u5927\u503c [5 6 7 8 9] # \u6700\u5c0f\u503c\u4f4d\u7f6e 0 \u6700\u5927\u503c\u4f4d\u7f6e 14 # \u8f74\u5411\u6700\u5c0f\u503c\u4f4d\u7f6e [0 0 0 0 0] \u8f74\u5411\u6700\u5927\u503c\u4f4d\u7f6e [2 2 2 2 2] # \u7d2f\u79ef\u548c # [ 1 3 6 10 15 18 22 27 33 40 45 51 58 66 75] # \u8f74\u5411\u7d2f\u79ef\u548c # [[ 1 3 6 10 15] # [ 3 7 12 18 25] # [ 5 11 18 26 35]] # \u7d2f\u79ef\u4e58\u79ef # [ 1 2 6 24 120 360 # 1440 7200 43200 302400 1512000 9072000 # 63504000 508032000 4572288000] # \u8f74\u5411\u7d2f\u79ef\u4e58\u79ef # [[ 1 2 6 24 120] # [ 3 12 60 360 2520] # [ 5 30 210 1680 15120]] \u5e03\u5c14\u503c\u6570\u7ec4(Boolean Array)\u7684\u65b9\u6cd5 \u00b6 \u5e03\u5c14\u503c\u6570\u7ec4\uff0c\u6709\u4e24\u4e2a\u975e\u5e38\u6709\u7528\u7684\u65b9\u6cd5any\u548call\u3002 * any\u68c0\u67e5\u6570\u7ec4\u4e2d\u662f\u5426\u81f3\u5c11\u6709\u4e00\u4e2aTrue\uff0c * all\u68c0\u67e5\u662f\u5426\u6bcf\u4e2a\u503c\u90fd\u662fTrue bools = np.array([False, False, True, False]) print(bools.any()) # True print(bools.all()) # False \u4e0b\u9762\u662f\u4e00\u4e2a\u8fd0\u7528\u5e03\u5c14\u503c\u6570\u7ec4\uff08Boolean Array\uff09\u8fdb\u884c\u6c42\u548c\u7684\u4e00\u4e2a\u4f8b\u5b50\uff0c\u5176\u4e2d (array > 0) \u672c\u8eab\u662f\u4e00\u4e2a\u5e03\u5c14\u578b\u7684\u6570\u7ec4\u3002 array = np.random.randn(100) result = (array > 0).sum() # \u8ba1\u7b97\u6b63\u503c\u7684\u4e2a\u6570 print(result) # 59 \u4e0b\u9762\u662f\u8fd0\u7528\u5e03\u5c14\u503c\u6570\u7ec4\u7684\u751f\u6210\u65b0\u6570\u7ec4\u7684\u4f8b\u5b50\u3002 arr = [[8, 9, 10, 11], [0, 1, 2, 3], [4, 5, 6, 7]] arr = np.array(arr) print(arr.shape) # (3, 4) print(arr) # [[ 8 9 10 11] # [ 0 1 2 3] # [ 4 5 6 7]] idx = [[1, 0, 0, 0], [0, 1, 0, 0], [0, 0, 1, 0]] idx = np.array(idx) print(idx.shape) # (3, 4) print(idx) # [[1 0 0 0] # [0 1 0 0] # [0 0 1 0]] result = arr[idx] # print(result.shape) # (3, 4, 4) print(result) # [[[ 0 1 2 3] # [ 8 9 10 11] # [ 8 9 10 11] # [ 8 9 10 11]] # [[ 8 9 10 11] # [ 0 1 2 3] # [ 8 9 10 11] # [ 8 9 10 11]] # [[ 8 9 10 11] # [ 8 9 10 11] # [ 0 1 2 3] # [ 8 9 10 11]]] result = arr[idx == 1] print(result.shape) print(result) # [8 1 6] \u6392\u5e8f \u00b6 \u548cPython\u7684\u5185\u5efa\u5217\u8868\u7c7b\u578b\u76f8\u4f3c\uff0cNumPy\u6570\u7ec4\u53ef\u4ee5\u4f7f\u7528sort\u65b9\u6cd5\u6309\u4f4d\u7f6e\u6392\u5e8f\u3002 \u9876\u5c42\u7684np.sort\u65b9\u6cd5\u8fd4\u56de\u7684\u662f\u5df2\u7ecf\u6392\u5e8f\u597d\u7684\u6570\u7ec4*\u62f7\u8d1d*\uff0c\u800c\u4e0d\u662f\u5bf9\u539f\u6570\u7ec4\u6309\u4f4d\u7f6e\u6392\u5e8f\u3002 array = np.random.randn(6) print(\"\u6837\u672c\u77e9\u9635\", array) array.sort() print(\"\u6392\u5e8f\u540e\u77e9\u9635\", array) # \u6837\u672c\u77e9\u9635 [-0.03119521 0.01839556 0.79238537 -2.46622775 0.62522211 0.22430846] # \u6392\u5e8f\u540e\u77e9\u9635 [-2.46622775 -0.03119521 0.01839556 0.22430846 0.62522211 0.79238537] \u591a\u7ef4\u6570\u7ec4\u4e2d\u6839\u636e\u4f20\u9012\u7684axis\u503c\uff0c\u6cbf\u7740\u8f74\u5411\u5bf9\u6bcf\u4e2a\u4e00\u7ef4\u6570\u636e\u6bb5\u8fdb\u884c\u6392\u5e8f\u3002 array = np.random.randn(5, 3) print(\"\u6837\u672c\u77e9\u9635 \\n\", array) array.sort(1) print(\"\u5bf91\u8f74\u6392\u5e8f\u540e\u77e9\u9635 \\n\", array) # \u6837\u672c\u77e9\u9635 # [[-0.88057833 0.30160954 -2.08788148] # [ 0.27969618 0.62923028 -0.58157581] # [-1.87194465 -1.1102104 1.09589605] # [ 0.1467938 -1.01558304 -0.25905165] # [-0.17294279 0.62369511 0.17947059]] # \u5bf91\u8f74\u6392\u5e8f\u540e\u77e9\u9635 # [[-2.08788148 -0.88057833 0.30160954] # [-0.58157581 0.27969618 0.62923028] # [-1.87194465 -1.1102104 1.09589605] # [-1.01558304 -0.25905165 0.1467938 ] # [-0.17294279 0.17947059 0.62369511]] \u552f\u4e00\u503c\u4e0e\u5176\u4ed6\u96c6\u5408\u903b\u8f91 \u00b6 NumPy\u5305\u542b\u4e00\u4e9b\u9488\u5bf9\u4e00\u7ef4 ndarray \u6570\u7ec4\u7684\u57fa\u7840\u96c6\u5408\u64cd\u4f5c\u3002 np.unique(x, y) \u8ba1\u7b97x\u7684\u552f\u4e00\u503c\uff0c\u5e76\u6392\u5e8f\u3002 names = np.array(['Bob', 'Joe', 'Will', 'Bob', 'Will', 'Joe', 'Joe']) result = np.unique(names) # NumPy\u5b9e\u73b0 print(result) # ['Bob' 'Joe' 'Will'] result = sorted(set(names)) # \u7eafPython\u5b9e\u73b0 print(result) # ['Bob' 'Joe' 'Will'] inits = np.array([3, 3, 3, 2, 2, 1, 1, 5, 5]) result = np.unique(inits) print(result) # [1 2 3 5] np.in1d(x, y) \u8ba1\u7b97x\u4e2d\u7684\u5143\u7d20\u662f\u5426\u5305\u542b\u5728y\u4e2d\uff0c\u5e76\u8fd4\u56de\u4e00\u4e2a\u5e03\u5c14\u503c\u6570\u7ec4\u3002 inits = np.array([3, 3, 3, 2, 2, 1, 1, 5, 5]) print(np.in1d(inits, [3, 4, 5])) # [ True True True False False False False True True] np.intersect1d(x, y) \uff0c\u8ba1\u7b97x\u548cy\u7684\u4ea4\u96c6\uff0c\u5e76\u6392\u5e8f\u3002 inits = np.array([3, 3, 3, 2, 2, 1, 1, 5, 5]) print(np.intersect1d(inits, [3, 4, 5])) # [3 5] np.union1d(x, y) \u8ba1\u7b97x\u548cy\u7684\u5e76\u96c6\uff0c\u5e76\u6392\u5e8f\u3002 inits = np.array([3, 3, 3, 2, 2, 1, 1, 5, 5]) print(np.union1d(inits, [3, 4, 5])) # [1 2 3 4 5] np.setdiff1d(x, y) \u5dee\u96c6\uff0c\u5728x\u4e2d\u4f46\u4e0d\u5728y\u4e2d\u7684\u5143\u7d20\u3002 inits = np.array([3, 3, 3, 2, 2, 1, 1, 5, 5]) print(np.setdiff1d(inits, [3, 4, 5])) # [1 2] np.setxor1d(x, y) \u5f02\u6216\u96c6\uff0c\u5728x\u6216\u8005y\u4e2d\uff0c\u4f46\u4e0d\u5c5e\u4e8ex\uff0cy\u4ea4\u96c6\u7684\u5143\u7d20\u3002 inits = np.array([3, 3, 3, 2, 2, 1, 1, 5, 5]) print(np.setxor1d(inits, [3, 4, 5])) # [1 2 4] \u4f7f\u7528\u6570\u7ec4\u8fdb\u884c\u6587\u4ef6\u8f93\u5165\u548c\u8f93\u51fa \u00b6 NumPy\u53ef\u4ee5\u5728\u786c\u76d8\u4e2d\u5c06\u6570\u636e\u4ee5\u6587\u672c\u6216\u4e8c\u8fdb\u5236\u6587\u4ef6\u7684\u5f62\u5f0f\u8fdb\u884c\u5b58\u5165\u786c\u76d8\u6216\u7531\u786c\u76d8\u8f7d\u5165\u3002 \u5f53\u524d\u53ea\u5173\u6ce8NumPy\u7684\u5185\u5efa\u4e8c\u8fdb\u5236\u683c\u5f0f\uff0c\u56e0\u4e3a\u5927\u90e8\u5206\u7528\u6237\u66f4\u503e\u5411\u4e8e\u4f7f\u7528pandas\u6216\u5176\u4ed6\u5de5\u5177\u6765\u8f7d\u5165\u6587\u672c\u6216\u8868\u683c\u578b\u6570\u636e\u3002 np.save \u548c np.load \u662f\u9ad8\u6548\u5b58\u53d6\u786c\u76d8\u6570\u636e\u7684\u4e24\u5927\u5de5\u5177\u51fd\u6570\u3002\u6570\u7ec4\u5728\u9ed8\u8ba4\u60c5\u51b5\u4e0b\u662f\u4ee5*\u672a\u538b\u7f29*\u7684\u683c\u5f0f\u8fdb\u884c\u5b58\u50a8\u7684\uff0c\u540e\u7f00\u540d\u662f.npy\u3002 import numpy as np array1 = np.arange(10) array2 = np.arange(15).reshape(3, 5) array3 = np.arange(30).reshape(3, 2, 5) print(array1) # [0 1 2 3 4 5 6 7 8 9] print(array2) # [[ 0 1 2 3 4] # [ 5 6 7 8 9] # [10 11 12 13 14]] print(array3) # [[[ 0 1 2 3 4] # [ 5 6 7 8 9]] # [[10 11 12 13 14] # [15 16 17 18 19]] # [[20 21 22 23 24] # [25 26 27 28 29]]] # \u67e5\u770b\u5f53\u524d\u8def\u5f84 os.getcwd() # '/opt/myProject/mySite' # \u66f4\u6539\u9ed8\u8ba4\u8def\u5f84 os.chdir('/opt/myProject/mySite/docs/python/datasets/examples') # \u4fdd\u5b58\u5230\u9ed8\u8ba4\u8def\u5f84\u3002npy\u540e\u7f00\u540d\u4f1a\u88ab\u81ea\u52a8\u52a0\u4e0a np.save('some_array', array1) # \u8bfb\u53d6\u6240\u4fdd\u5b58\u7684\u6587\u4ef6 result = np.load('some_array.npy') # \u5bf9\u6bd4\u7ed3\u679c\u4e00\u81f4\u3002 print(result) # [0 1 2 3 4 5 6 7 8 9] # \u5c06\u591a\u4e2a\u6570\u7ec4\u4fdd\u5b58\u5230\u672a\u538b\u7f29\u7684\u5355\u4e2a\u6587\u4ef6\u4e2d\uff0c.npz\u683c\u5f0f np.savez('some_array_archive.npz', a=array2, b=array3) result = np.load('some_array_archive.npz') # reslt\u662f\u4e00\u4e2a\u5b57\u5178\u578b\u7684\u5bf9\u8c61 print(result['b']) # \u8f7d\u5165\u5355\u4e2a\u6570\u7ec4b # [[[ 0 1 2 3 4] # [ 5 6 7 8 9]] # [[10 11 12 13 14] # [15 16 17 18 19]] # [[20 21 22 23 24] # [25 26 27 28 29]]] \u7ebf\u6027\u4ee3\u6570 \u00b6 \u53c2\u8003\u94fe\u63a5\uff1a https://www.numpy.org.cn/reference/routines/linalg.html https://github.com/teadocs/numpy-cn \u5e0c\u814a\u5b57\u6bcd: \u0391 \u03b1 /'\u00e6lf\u0259/ alpha \u0392 \u03b2 /'bi:t\u0259/ beta \u0393 \u03b3 /'g\u00e6m\u0259/ gamma \u0394 \u03b4 /'delt\u0259/ delta \u0395 \u03b5 /'eps\u026al\u0252n/ epsilon \u0396 \u03b6 /'zi:t\u0259/ zeta \u0397 \u03b7 /'i:t\u0259/ eta \u0398 \u03b8 /'\u03b8i:t\u0259/ theta \u0399 \u03b9 /'a\u026a\u0259\u028at\u0259/ iota \u039a \u03ba /'k\u00e6p\u0259/ kappa \u2227 \u03bb /'l\u00e6md\u0259/ lambda \u039c \u03bc /mju:/ mu \u039d \u03bd /nju:/ nu \u039e \u03be /ksi/ xi \u039f \u03bf /\u0259u\u02c8maikr\u0259n/ omicron \u220f \u03c0 /pa\u026a/ pi \u03a1 \u03c1 /r\u0259\u028a/ rho \u2211 \u03c3 /'s\u026a\u0261m\u0259/ sigma \u03a4 \u03c4 /t\u0254:/ tau \u03a5 \u03c5 /\u02c8ips\u026alon/ upsilon \u03a6 \u03c6 /fa\u026a/ phi \u03a7 \u03c7 /ka\u026a/ chi \u03a8 \u03c8 /psa\u026a/ psi \u03a9 \u03c9 /'\u0259\u028am\u026a\u0261\u0259/ omega numpy.linalg \u6a21\u5757\u5305\u542b\u7ebf\u6027\u4ee3\u6570\u7684\u51fd\u6570\u3002\u4f7f\u7528\u8fd9\u4e2a\u6a21\u5757\uff0c\u53ef\u4ee5\u8ba1\u7b97\u9006\u77e9\u9635\u3001\u6c42\u7279\u5f81\u503c\u3001\u89e3\u7ebf\u6027\u65b9\u7a0b\u7ec4\u4ee5\u53ca\u6c42\u89e3\u884c\u5217\u5f0f\u7b49\u3002 import numpy as np from numpy import linalg as LA from numpy import * from numpy.linalg import inv import matplotlib.pyplot as plt diag \u00b6 np.diag \u5c06\u4e00\u4e2a\u65b9\u9635\u7684\u5bf9\u89d2\uff08\u6216\u975e\u5bf9\u89d2\uff09\u5143\u7d20\u4f5c\u4e3a\u4e00\u7ef4\u6570\u7ec4\u8fd4\u56de\uff0c\u6216\u8005\u5c06\u4e00\u7ef4\u6570\u7ec4\u8f6c\u6362\u6210\u4e00\u4e2a\u65b9\u9635\uff0c\u5e76\u4e14\u5728\u975e\u5bf9\u89d2\u7ebf\u4e0a\u6709\u96f6\u70b9\u3002 a1 = np.arange(9, dtype=float).reshape((3, 3)) r1 = np.diag(a1) r2 = np.diag(a1, k=1) r3 = np.diag(a1, k=-1) r4 = np.diag(np.diag(a1)) # \u5bf9\u89d2\u77e9\u9635 print(\"\u6837\u672c\u77e9\u9635 \\n\", a1) print(\"\u77e9\u9635\u5bf9\u89d2\u7ebf\", r1) print(\"\u77e9\u9635\u5bf9\u89d2\u7ebf\u5411\u4e0a\u504f\u79fb\", r2) print(\"\u77e9\u9635\u5bf9\u89d2\u7ebf\u5411\u4e0b\u504f\u79fb\", r3) print(\"\u5bf9\u89d2\u77e9\u9635 \\n\", r4) # \u6837\u672c\u77e9\u9635 # [[0. 1. 2.] # [3. 4. 5.] # [6. 7. 8.]] # \u77e9\u9635\u5bf9\u89d2\u7ebf [0. 4. 8.] # \u77e9\u9635\u5bf9\u89d2\u7ebf\u5411\u4e0a\u504f\u79fb [1. 5.] # \u77e9\u9635\u5bf9\u89d2\u7ebf\u5411\u4e0b\u504f\u79fb [3. 7.] # \u5bf9\u89d2\u77e9\u9635 # [[0. 0. 0.] # [0. 4. 0.] # [0. 0. 8.]] dot \u00b6 np.dot \u5c06\u5411\u91cf\u4e2d\u5bf9\u5e94\u5143\u7d20\u76f8\u4e58\uff0c\u518d\u76f8\u52a0\u6240\u5f97\u3002\u5373\u666e\u901a\u7684\u5411\u91cf\u4e58\u6cd5\u8fd0\u7b97\uff0c\u6216**\u77e9\u9635\u70b9\u4e58**\u3002 a1 = np.dot(3, 4) print(a1) # 12 a2 = np.arange(9, dtype=float).reshape((3, 3)) r2 = np.dot(a2, a2) print(a2) # [[0. 1. 2.] # [3. 4. 5.] # [6. 7. 8.]] print(r2) # [[ 15. 18. 21.] # [ 42. 54. 66.] # [ 69. 90. 111.]] r3 = np.dot([2j, 3j], [2j, 3j]) print(r3) # (-13+0j) trace \u00b6 np.trace \u8ba1\u7b97\u5bf9\u89d2\u5143\u7d20\u548c\u3002 a1 = np.arange(9, dtype=float).reshape((3, 3)) print(\"\u6837\u672c\u77e9\u9635 \\n\", a1) r1 = np.trace(a1) print(\"\u5bf9\u89d2\u7ebf\u5143\u7d20\u6c42\u548c\", r1) a2 = np.arange(24, dtype=float).reshape((2, 3, 4)) r2 = np.trace(a2) print(\"\u6837\u672c\u77e9\u9635 \\n\", a2) print(\"\u5bf9\u89d2\u7ebf\u5143\u7d20\u6c42\u548c\", r2) # \u6837\u672c\u77e9\u9635 # [[0. 1. 2.] # [3. 4. 5.] # [6. 7. 8.]] # \u5bf9\u89d2\u7ebf\u5143\u7d20\u6c42\u548c 12.0 # \u6837\u672c\u77e9\u9635 # [[[ 0. 1. 2. 3.] # [ 4. 5. 6. 7.] # [ 8. 9. 10. 11.]] # # [[12. 13. 14. 15.] # [16. 17. 18. 19.] # [20. 21. 22. 23.]]] # \u5bf9\u89d2\u7ebf\u5143\u7d20\u6c42\u548c [16. 18. 20. 22.] det \u00b6 np.det \u8ba1\u7b97\u77e9\u9635\u7684\u884c\u5217\u5f0f\uff08\u65b9\u9635\uff09\u3002 \u4e8c\u9636\u884c\u5217\u5f0f[[a, b], [c, d]]\u7684\u503c\u662fad - bc \u4e09\u9636\u884c\u5217\u5f0f [[a, b, c], [d, e, f], [g, h, i]]\u7684\u503c\u662f aei + bfd + cdh - ceg - bdi - afh \u4e09\u9636\u884c\u5217\u5f0f\u7684\u6027\u8d28 \u6027\u8d281\uff1a\u884c\u5217\u5f0f\u4e0e\u5b83\u7684\u8f6c\u7f6e\u884c\u5217\u5f0f\u76f8\u7b49\u3002 \u6027\u8d282\uff1a\u4e92\u6362\u884c\u5217\u5f0f\u7684\u4e24\u884c(\u5217)\uff0c\u884c\u5217\u5f0f\u53d8\u53f7\u3002 \u63a8\u8bba\uff1a\u5982\u679c\u884c\u5217\u5f0f\u6709\u4e24\u884c(\u5217)\u5b8c\u5168\u76f8\u540c\uff0c\u5219\u6b64\u884c\u5217\u5f0f\u4e3a\u96f6\u3002 \u6027\u8d283\uff1a\u884c\u5217\u5f0f\u7684\u67d0\u4e00\u884c(\u5217)\u4e2d\u6240\u6709\u7684\u5143\u7d20\u90fd\u4e58\u4ee5\u540c\u4e00\u6570k\uff0c\u7b49\u4e8e\u7528\u6570k\u4e58\u6b64\u884c\u5217\u5f0f\u3002 \u63a8\u8bba\uff1a\u884c\u5217\u5f0f\u4e2d\u67d0\u4e00\u884c(\u5217)\u7684\u6240\u6709\u5143\u7d20\u7684\u516c\u56e0\u5b50\u53ef\u4ee5\u63d0\u5230\u884c\u5217\u5f0f\u7b26\u53f7\u7684\u5916\u9762\u3002 \u6027\u8d284\uff1a\u884c\u5217\u5f0f\u4e2d\u5982\u679c\u6709\u4e24\u884c(\u5217)\u5143\u7d20\u6210\u6bd4\u4f8b\uff0c\u5219\u6b64\u884c\u5217\u5f0f\u7b49\u4e8e\u96f6\u3002 \u6027\u8d285\uff1a\u628a\u884c\u5217\u5f0f\u7684\u67d0\u4e00\u5217(\u884c)\u7684\u5404\u5143\u7d20\u4e58\u4ee5\u540c\u4e00\u6570\u7136\u540e\u52a0\u5230\u53e6\u4e00\u5217(\u884c)\u5bf9\u5e94\u7684\u5143\u7d20\u4e0a\u53bb\uff0c\u884c\u5217\u5f0f\u4e0d\u53d8\u3002 a1 = np.array([[1, 2], [3, 4]]) r1 = np.linalg.det(a1) print(\"\u4e8c\u9636\u65b9\u9635 \\n\", a1) print(\"\u4e8c\u9636\u884c\u5217\u5f0f\u7684\u503c\", r1) # \u4e8c\u9636\u65b9\u9635 # [[1 2] # [3 4]] # \u4e8c\u9636\u884c\u5217\u5f0f\u7684\u503c -2.0000000000000004 # \u5e0c\u814a\u5b57\u6bcd # \u03b1, \u03b2, \u03b3,\u03b4, \u03b5, \u03b6, \u03b7, \u03b8, \u03b9, \u03ba, \u03bb, \u03bc, \u03bd, # \u03be, \u03bf, \u03c0, \u03c1, \u03c2, \u03c3, \u03c4, \u03c5, \u03c6, \u03c7, \u03c8, \u03c9, a2 = np.arange(9).reshape(3, 3) r2 = np.linalg.det(a2) print(\"\u4e09\u9636\u65b9\u9635 \\n\", a2) print(\"\u4e09\u9636\u884c\u5217\u5f0f\u7684\u503c\", r2) # \u4e09\u9636\u65b9\u9635 # [[0 1 2] # [3 4 5] # [6 7 8]] # \u4e09\u9636\u884c\u5217\u5f0f\u7684\u503c 0.0 a3 = np.arange(16).reshape(4, 4) r3 = np.linalg.det(a3) print(\"\u56db\u9636\u65b9\u9635 \\n\", a3) print(\"\u56db\u9636\u884c\u5217\u5f0f\u7684\u503c\", r3) # \u56db\u9636\u65b9\u9635 # [[ 0 1 2 3] # [ 4 5 6 7] # [ 8 9 10 11]# \u5e0c\u814a\u5b57\u6bcd # \u03b1, \u03b2, \u03b3,\u03b4, \u03b5, \u03b6, \u03b7, \u03b8, \u03b9, \u03ba, \u03bb, \u03bc, \u03bd, # \u03be, \u03bf, \u03c0, \u03c1, \u03c2, \u03c3, \u03c4, \u03c5, \u03c6, \u03c7, \u03c8, \u03c9, # [12 13 14 15]] # \u56db\u9636\u884c\u5217\u5f0f\u7684\u503c 0.0 eig \u00b6 np.eig \u8ba1\u7b97\u65b9\u9635\u7684\u7279\u5f81\u503c\u548c\u7279\u5f81\u5411\u91cf\u3002 \u7279\u5f81\u503c\u4e0e\u7279\u5f81\u5411\u91cf\u7684\u5b9a\u4e49\uff1a\u8bbeA\u662fn\u9636\u65b9\u9635\uff0c\u82e5\u6570\u03bb\u548cn\u7ef4\u975e\u96f6\u5217\u5411\u91cfx\uff0c\u4f7f\u5f97Ax = \u03bbx\u6210\u7acb\uff0c\u5219\u79f0\u03bb\u662f\u65b9\u9635A\u7684\u4e00\u4e2a\u7279\u5f81\u503c\uff0cx\u4e3a\u65b9\u9635A\u7684\u5bf9\u5e94\u4e8e\u7279\u5f81\u503c\u03bb\u7684\u4e00\u4e2a\u7279\u5f81\u5411\u91cf\u3002 A\u662f\u65b9\u9635\u3002\uff08\u5bf9\u4e8e\u975e\u65b9\u9635\uff0c\u662f\u6ca1\u6709\u7279\u5f81\u503c\u7684\uff0c\u4f46\u4f1a\u6709\u6761\u4ef6\u6570\u3002\uff09\u7279\u5f81\u5411\u91cfx\u4e3a\u975e\u96f6\u5217\u5411\u91cf\u3002 v_eigenvectors, v_eigenvalues = LA.eig(np.diag((1, 2, 3))) print(\"\u7279\u5f81\u5411\u91cf\", v_eigenvectors) print(\"\u7279\u5f81\u503c \\n\", v_eigenvalues) # \u7279\u5f81\u5411\u91cf [1. 2. 3.] # \u7279\u5f81\u503c # [[1. 0. 0.] # [0. 1. 0.] # [0. 0. 1.]] v_eigenvectors, v_eigenvalues = LA.eig(np.array([[1, -1], [1, 1]])) print(\"\u7279\u5f81\u5411\u91cf\", v_eigenvectors) print(\"\u7279\u5f81\u503c \\n\", v_eigenvalues) # \u7279\u5f81\u5411\u91cf [1.+1.j 1.-1.j] # \u7279\u5f81\u503c # [[0.70710678+0.j 0.70710678-0.j ] # [0. -0.70710678j 0. +0.70710678j]] inv \u00b6 np.inv \u8ba1\u7b97\u65b9\u9635\u7684\u9006\u77e9\u9635\u3002 a1 = np.array([[1, 2], [3, 4]]) r1 = inv(a1) r2 = inv(np.matrix(a1)) print(\"\u539f\u77e9\u9635 \\n\", a1) print(\"\u9006\u77e9\u9635 \\n\", r1) print(\"\u9006\u77e9\u9635 \\n\", r2) # \u539f\u77e9\u9635 # [[1 2] # [3 4]] # \u9006\u77e9\u9635 # [[-2. 1. ] # [ 1.5 -0.5]] # \u9006\u77e9\u9635 # [[-2. 1. ] # [ 1.5 -0.5]] pinv \u00b6 np.pinv \u8ba1\u7b97\u77e9\u9635\u7684Moore-Penrose\u4f2a\u9006(\u6469\u5c14\uff0d\u5f6d\u82e5\u65af\u5e7f\u4e49\u9006)\u3002 \u4e0b\u9762\u7684\u4f8b\u5b50\u68c0\u9a8c a * a+ * a == a \u548c a+ * a * a+ == a+ a = np.random.randn(9, 6) B = np.linalg.pinv(a) r1 = np.allclose(a, np.dot(a, np.dot(B, a))) r2 = np.allclose(B, np.dot(B, np.dot(a, B))) print(a) print(B) print(r1) # True print(r2) # True # a: # [[-2.30316101 -0.63217332 1.24134743 -0.72492307 0.12456801 -0.14192548] # [ 1.37573495 0.07626697 -0.71870843 1.26824984 -0.79485727 -0.24630455] # [ 0.29003175 -1.23931665 -0.50864107 -0.31140718 0.45467649 -2.44973999] # [-0.70748664 -1.2995059 0.85126149 -1.10918804 -2.10042342 0.75942293] # [ 1.91765238 1.23892103 1.58516486 -1.65520154 0.11894439 0.84536298] # [ 1.03220791 0.1715148 0.85595408 0.58569706 1.34066384 -1.5782386 ] # [-0.54432889 -0.0114189 1.55403934 0.89852512 1.15586365 -0.30733805] # [-0.80874673 0.14602121 1.04680044 1.98722514 0.39766383 0.75178788] # [ 0.01664663 0.06243353 -0.50725334 -0.37707204 -1.76701091 -0.33866559]] # B: # [[-0.25055838 0.13963115 0.08990923 0.16280282 0.12997291 0.05088469 -0.01541299 -0.01656133 -0.21731387] # [ 0.22862622 -0.05108109 -0.2639602 -0.47835978 0.11776862 0.09324694 0.00436756 -0.00609393 0.61995597] # [ 0.10422554 0.03985857 0.00198025 0.15139023 0.17165026 0.15697725 0.17360246 0.13150089 0.08378135] # [-0.07021378 0.17665487 -0.04109252 0.0015022 -0.11998477 0.0543575 0.08649033 0.21190785 0.04065729] # [-0.08110336 -0.15274536 0.05601496 -0.07967802 -0.02454705 -0.04152356 0.00071268 -0.05981012 -0.43996066] # [-0.17998537 -0.03160871 -0.12587707 0.16856246 0.00565094 -0.21038026 -0.06060039 0.04322126 -0.42038066]] qr \u00b6 np.qr \u8ba1\u7b97QR\u5206\u89e3\u3002QR\uff08\u6b63\u4ea4\u4e09\u89d2\uff09\u5206\u89e3\u6cd5\u662f\u6c42\u4e00\u822c\u77e9\u9635\u5168\u90e8\u7279\u5f81\u503c\u7684\u6700\u6709\u6548\u5e76\u5e7f\u6cdb\u5e94\u7528\u7684\u65b9\u6cd5\u3002 \u4e00\u822c\u77e9\u9635\u5148\u7ecf\u8fc7\u6b63\u4ea4\u76f8\u4f3c\u53d8\u5316\u6210\u4e3aHessenberg\u77e9\u9635\uff0c\u7136\u540e\u518d\u5e94\u7528QR\u65b9\u6cd5\u6c42\u7279\u5f81\u503c\u548c\u7279\u5f81\u5411\u91cf\u3002QR\u5206\u89e3\u6cd5\u662f\u5c06\u77e9\u9635\u5206\u89e3\u6210\u4e00\u4e2a\u6b63\u89c4\u6b63\u4ea4\u77e9\u9635Q\u4e0e\u4e0a\u4e09\u89d2\u5f62\u77e9\u9635R\uff0c\u6240\u4ee5\u79f0\u4e3aQR\u5206\u89e3\u6cd5\u3002 a = np.arange(9).reshape(3, 3) q, r = np.linalg.qr(a) print(\"\u539f\u77e9\u9635 \\n\", a) print(\"\u6b63\u4ea4\u77e9\u9635 \\n\", q) print(\"\u4e0a\u4e09\u89d2\u77e9\u9635 \\n\", r) # \u539f\u77e9\u9635 # [[0 1 2] # [3 4 5] # [6 7 8]] # \u6b63\u4ea4\u77e9\u9635 # [[ 0. 0.91287093 0.40824829] # [-0.4472136 0.36514837 -0.81649658] # [-0.89442719 -0.18257419 0.40824829]] # \u4e0a\u4e09\u89d2\u77e9\u9635 # [[-6.70820393e+00 -8.04984472e+00 -9.39148551e+00] # [ 0.00000000e+00 1.09544512e+00 2.19089023e+00] # [ 0.00000000e+00 0.00000000e+00 -8.88178420e-16]] svd \u00b6 np.svd \u8ba1\u7b97\u5947\u5f02\u503c\u5206\u89e3\uff08SVD\uff09\u3002 \u51e0\u4f55\u610f\u4e49\uff1aSVD\u5206\u89e3\u7684\u51e0\u4f55\u610f\u4e49\u662f\u4efb\u4f55\u4e00\u4e2a\u77e9\u9635A\u5728\u4e00\u7cfb\u5217\u65cb\u8f6c\u548c\u5e73\u79fb\u4e0b\u90fd\u80fd\u8f6c\u5316\u6210\u4e00\u4e2a\u5bf9\u89d2\u77e9\u9635\u2211 , \u5176\u4e2d\u9149\u9635U, V\u7684\u51e0\u4f55\u610f\u4e49\u5c31\u662f\u4e00\u7cfb\u5217\u65cb\u8f6c\u548c\u5e73\u79fb\u7684\u53e0\u52a0\u3002 a = mat([[1, 2, 3],[4, 5, 6]]) U, sigma, V = np.linalg.svd(a) print(\"\u539f\u77e9\u9635 \\n\", a) print(\"\u5de6\u5947\u5f02\u503cU \\n\", U) print(\"\u5947\u5f02\u503cSigma \\n\", sigma) print(\"\u53f3\u5947\u5f02\u503cV \\n\", V) # \u539f\u77e9\u9635 # [[1 2 3] # [4 5 6]] # \u5de6\u5947\u5f02\u503cU # [[-0.3863177 -0.92236578] # [-0.92236578 0.3863177 ]] # \u5947\u5f02\u503cSigma # [9.508032 0.77286964] # \u53f3\u5947\u5f02\u503cV # [[-0.42866713 -0.56630692 -0.7039467 ] # [ 0.80596391 0.11238241 -0.58119908] # [ 0.40824829 -0.81649658 0.40824829]] solve \u00b6 np.solve \u6c42\u89e3x\u7684\u7ebf\u6027\u7cfb\u7edfAx = b\uff0c\u5176\u4e2dA\u662f\u65b9\u9635\u3002 \u89e3\u65b9\u7a0b\u7ec4\uff1a x + 2y = 1 3x + 5y = 2 a = np.array([[1, 2], [3, 5]]) b = np.array([1, 2]) x = np.linalg.solve(a, b) print(x) # [-1. 1.] lstsq \u00b6 np.lstsq \u8ba1\u7b97Ax = b\u7684\u6700\u5c0f\u4e8c\u4e58\u89e3\u3002 \u7528\u6700\u5c0f\u4e8c\u4e58\u6cd5\u62df\u5408\u6570\u636e\u5f97\u5230\u4e00\u4e2a\u5f62\u5982y = mx + c\u7684\u7ebf\u6027\u65b9\u7a0b\uff08Return the least-squares solution to a linear matrix equation\uff09\u3002 x = np.array([0, 1, 2, 3]) # \u539f\u59cb\u6570\u636e\u70b9\u7684\u6a2a\u5750\u6807 y = np.array([-1, 0.2, 0.9, 2.1]) # \u539f\u59cb\u6570\u636e\u70b9\u7684\u7eb5\u5750\u6807 print(x) # [0 1 2 3] print(y) # [-1. 0.2 0.9 2.1] A = np.vstack([x, np.ones(len(x))]).T # \u6784\u9020\u7cfb\u6570\u77e9\u9635 print(A) # [[0. 1.] # [1. 1.] # [2. 1.] # [3. 1.]] m, c = np.linalg.lstsq(A, y, rcond=None)[0] # \u89e3\u51fa\u659c\u7387a\u548c\u7eb5\u622a\u8dddc plt.plot(x, y, 'o', label='Original data', markersize=10) # \u505a\u51fa\u539f\u59cb\u6570\u636e\u6563\u70b9\u56fe plt.plot(x, m*x + c, 'r', label='Fitted line') # \u7528\u4e0a\u9762\u89e3\u51fa\u7684\u53c2\u6570\u505a\u51fa\u62df\u5408\u66f2\u7ebfy=mx+c plt.legend() plt.show() \u4f2a\u968f\u673a\u6570\u751f\u6210 \u00b6 numpy.random \u6a21\u5757\u586b\u8865\u4e86Python\u5185\u5efa\u7684 random \u6a21\u5757\u7684\u4e0d\u8db3\uff0c\u53ef\u4ee5\u9ad8\u6548\u5730\u751f\u6210\u591a\u79cd\u6982\u7387\u5206\u5e03\u4e0b\u7684\u5b8c\u6574\u6837\u672c\u503c\u6570\u7ec4\u3002 numpy.random \u4e2d\u7684\u6570\u636e\u751f\u6210\u51fd\u6570\u516c\u7528\u4e86\u4e00\u4e2a\u5168\u5c40\u7684\u968f\u673a\u6570\u79cd\u5b50\u3002 \u4f7f\u7528 numpy.random.RandomState \u751f\u6210\u4e00\u4e2a\u968f\u673a\u6570\u751f\u6210\u5668\uff0c\u4f7f\u6570\u636e\u72ec\u7acb\u4e8e\u5176\u4ed6\u7684\u968f\u673a\u6570\u72b6\u6001\u3002 \u901a\u8fc7 np.random.seed \u66f4\u6539NumPy\u7684\u968f\u673a\u6570\u79cd\u5b50\u3002 numpy.random \u4e2d\u7684\u90e8\u5206\u51fd\u6570\u5217\u8868 seed: \u5411\u968f\u673a\u6570\u751f\u6210\u5668\u4f20\u9012\u968f\u673a\u72b6\u6001\u79cd\u5b50 permutation: \u8fd4\u56de\u4e00\u4e2a\u5e8f\u5217\u7684\u968f\u673a\u6392\u5217\uff0c\u6216\u8005\u8fd4\u56de\u4e00\u4e2a\u4e71\u5e8f\u7684\u6574\u6570\u8303\u56f4\u5e8f\u5217 shuffle: \u968f\u673a\u6392\u5217\u4e00\u4e2a\u5e8f\u5217 rand: \u4ece\u5747\u5300\u5206\u5e03\u4e2d\u62bd\u53d6\u6837\u672c randint: \u6839\u636e\u7ed9\u5b9a\u7684\u7531\u4f4e\u5230\u9ad8\u7684\u8303\u56f4\u62bd\u53d6\u968f\u673a\u6574\u6570 randn: \u4ece\u5747\u503c0\u65b9\u5dee1\u7684\u6b63\u6001\u5206\u5e03\u4e2d\u62bd\u53d6\u6837\u672c(MATLAB\u578b\u63a5\u53e3\uff09 binomial: \u4ece\u4e8c\u9879\u5206\u5e03\u4e2d\u62bd\u53d6\u6837\u672c normal: \u4ece\u6b63\u6001\uff08\u9ad8\u65af\uff09\u5206\u5e03\u4e2d\u62bd\u53d6\u6837\u672c beta\u4ecebeta: \u5206\u5e03\u4e2d\u62bd\u53d6\u6837\u672c chisquare: \u4ece\u5361\u65b9\u5206\u5e03\u4e2d\u62bd\u53d6\u6837\u672c \u4f8b\u5982\uff0c\u4f7f\u7528normal\u6765\u83b7\u5f97\u4e00\u4e2a4\u00d74\u7684\u6b63\u6001\u5206\u5e03\u6837\u672c\u6570\u7ec4\uff0c\u79f0\u4e3a\u4f2a\u968f\u673a\u6570\u3002 import numpy as np samples = np.random.normal(size=(4, 4)) print(samples) # [[ 0.78583658 -0.27462104 -0.53027675 -0.62675004] # [ 0.39054781 1.20503691 -0.0057432 0.17243182] # [-0.41516669 -0.93335854 0.01996088 -0.12707275] # [ 0.42952379 2.56998319 0.14848737 -0.42871493]] \u793a\u4f8b\uff1a\u968f\u673a\u6f2b\u6b65 \u00b6 import matplotlib.pyplot as plt import numpy as np position = 0 walk = [position] nwalks = 5000 nsteps = 1000 draws = np.random.randint(0, 2, size=(nwalks, nsteps)) steps = np.where(draws > 0, 1, -1) walks = steps.cumsum() plt.plot(walks[:500000000000000000000000000]) plt.show() \u8f93\u51fa\u56fe\u50cf\uff1a","title":"NumPy\u57fa\u7840"},{"location":"python/DataAnalysis/ch01/#numpy","text":"\u5305\u542b\u4ee5\u4e0b\u5185\u5bb9\uff1a \u591a\u7ef4\u6570\u7ec4\u5bf9\u8c61 \u901a\u7528\u51fd\u6570 \u9762\u5411\u6570\u7ec4\u7f16\u7a0b \u4f7f\u7528\u6570\u7ec4\u8fdb\u884c\u6587\u4ef6\u8f93\u5165\u548c\u8f93\u51fa \u7ebf\u6027\u4ee3\u6570 \u4f2a\u968f\u673a\u6570\u751f\u6210 \u793a\u4f8b\uff1a\u968f\u673a\u6f2b\u6b65","title":"NumPy\u57fa\u7840"},{"location":"python/DataAnalysis/ch01/#ndarry","text":"","title":"\u591a\u7ef4\u6570\u7ec4\u5bf9\u8c61ndarry"},{"location":"python/DataAnalysis/ch01/#_1","text":"import numpy as np import pandas as pd import matplotlib.pyplot as plt","title":"\u522b\u540d\u7ea6\u5b9a"},{"location":"python/DataAnalysis/ch01/#matplotlib","text":"\u67e5\u770b\u5b57\u4f53\u8def\u5f84 >>> import matplotlib >>> print(matplotlib.matplotlib_fname()) /home/james/.local/lib/python3.6/site-packages/matplotlib/mpl-data/matplotlibrc \u4e0b\u8f7d\u4e2d\u6587\u5b57\u4f53\u3002\u7f51\u5740 https://www.fontpalace.com/font-download/SimHei/,\u5e76\u62f7\u8d1d\u5230\u4e0b\u9762\u7684\u8def\u5f84\u4e0b james@lizard:~/Downloads> cp SimHei.ttf /home/james/.local/lib/python3.6/site-packages/matplotlib/mpl-data/fonts/ttf/ \u67e5\u770bmatplotlib\u7684\u5b57\u4f53\u7f13\u5b58\u76ee\u5f55\u3002 >>> import matplotlib >>> print(matplotlib.get_cachedir()) /home/james/.cache/matplotlib \u5220\u9664\u8fd9\u4e2a\u76ee\u5f55 james@lizard:~> rm -rf /home/james/.cache/matplotlib \u7f16\u8f91matplotlibrc\u6587\u4ef6 /home/james/.local/lib/python3.6/site-packages/matplotlib/mpl-data/matplotlibrc \uff0c\u505a\u5982\u4e0b\u4fee\u6539\u3002 \u5b9a\u4f4d\u8fd9\u4e00\u884c\uff0c\u53bb\u6389\u6ce8\u91ca\u7b26 # font.family: sans-serif \u5b9a\u4f4d\u8fd9\u4e00\u884c\uff0c\u53bb\u6389\u6ce8\u91ca\u7b26 # \uff0c\u5e76\u6dfb\u52a0 SimHei \uff0c\u4fee\u6539\u540e\u4e3a font.serif: SimHei, DejaVu Serif, Bitstream Vera Serif, Computer Modern Roman, New Century Schoolbook, Century Schoolbook L, Utopia, ITC Bookman, Bookman, Nimbus Roman No9 L, Times New Roman, Times, Palatino, Charter, serif \u5b9a\u4f4d\u8fd9\u4e00\u884c\uff0c\u53bb\u6389\u6ce8\u91ca\u7b26 # \uff0c\u5e76\u6dfb\u52a0 SimHei \uff0c\u4fee\u6539\u540e\u4e3a font.sans-serif: SimHei, DejaVu Sans, Bitstream Vera Sans, Computer Modern Sans Serif, Lucida Grande, Verdana, Geneva, Lucid, Arial, Helvetica, Avant Garde, sans-serif \u5b9a\u4f4d\u8fd9\u4e00\u884c\uff0c\u53bb\u6389\u6ce8\u91ca\u7b26 # \uff0c\u5e76\u628a True \u6539\u4e3a False \uff0c\u4fee\u6539\u540e\u4e3a axes.unicode_minus: False","title":"\u5b89\u88c5matplotlib\u4e2d\u6587\u5b57\u4f53"},{"location":"python/DataAnalysis/ch01/#matplotlib_1","text":"\u5728\u4f7f\u7528matplotlib\u8f93\u51fa\u56fe\u50cf\u65f6\uff0c\u5982\u679c\u9047\u5230\u65e0\u6cd5\u663e\u793a\u56fe\u50cf\u7684\u9519\u8bef UserWarning: Matplotlib is currently using agg, which is a non-GUI backend, so cannot show the figure\u3002 \uff0c\u53ef\u4ee5\u5c1d\u8bd5\u4e0b\u9762\u7684\u6b65\u9aa4\u89e3\u51b3\u3002 \u5b89\u88c5 python3-tk \u5305 james@lizard:~> sudo zypper in python3-tk \u6216\u8005\u901a\u8fc7 pip \u5b89\u88c5 tk \u5305 james@lizard:~> pip3 install tk Defaulting to user installation because normal site-packages is not writeable Collecting tk Downloading tk-0.1.0-py3-none-any.whl (3.9 kB) Installing collected packages: tk Successfully installed tk-0.1.0 \u4e00\u822c\u5b8c\u6210\u4e0a\u9762\u5b89\u88c5\u540e\uff0c\u7a0b\u5e8f\u5c31\u80fd\u81ea\u52a8\u663e\u793a\u56fe\u4e86\uff0c\u5982\u679c\u8fd8\u662f\u4e0d\u80fd\u663e\u793a\uff0c\u518d\u5c1d\u8bd5\u91cd\u65b0\u5b89\u88c5 matplotlib \u3002 pip3 ininstall matplotlib pip3 install matplotlib","title":"\u8bbe\u7f6ematplotlib\u540e\u7aef\u6e32\u67d3\u5668"},{"location":"python/DataAnalysis/ch01/#ndarray-n-","text":"\u4e00\u4e2andarray\u662f\u4e00\u4e2a\u901a\u7528\u7684\u591a\u7ef4\u540c\u7c7b\u6570\u636e\u5bb9\u5668\uff0c\u4e5f\u5c31\u662f\u8bf4\uff0c\u5b83\u5305\u542b\u7684\u6bcf\u4e00\u4e2a\u5143\u7d20\u5747\u4e3a**\u76f8\u540c\u7c7b\u578b**\uff1b \u6bcf\u4e00\u4e2a\u6570\u7ec4\u90fd\u6709\u4e00\u4e2ashape\u5c5e\u6027\uff0c\u7528\u6765\u8868\u5f81\u6570\u7ec4\u6bcf\u4e00\u7ef4\u5ea6\u7684\u6570\u91cf\uff1b \u6bcf\u4e00\u4e2a\u6570\u7ec4\u90fd\u6709\u4e00\u4e2adtype\u5c5e\u6027\uff0c\u7528\u6765\u63cf\u8ff0\u6570\u7ec4\u7684\u6570\u636e\u7c7b\u578b\uff1b \u4e0b\u9762\u662f\u6807\u51c6\u6570\u7ec4\u7684\u751f\u6210\u51fd\u6570 array: \u5c06\u8f93\u5165\u6570\u636e\uff08\u5217\u8868\u3001\u5143\u7ec4\u3001\u6570\u7ec4\uff0c\u5176\u4ed6\u5e8f\u5217\uff09\u8f6c\u6362\u4e3andarray\uff0c\u5982\u679c\u4e0d\u663e\u5f0f\u6307\u660e\u6570\u636e\u7c7b\u578b\uff0c\u5c06\u81ea\u52a8\u63a8\u65ad\uff1b\u9ed8\u8ba4\u590d\u5236\u6240\u6709\u7684\u8f93\u5165\u6570\u636e\u3002 asarray\uff1a\u5c06\u8f93\u5165\u8f6c\u6362\u4e3andarray\uff0c\u4f46\u5982\u679c\u8f93\u5165\u5df2\u7ecf\u662fndarray\u5219\u4e0d\u518d\u590d\u5236\u3002 arange\uff1aPython\u5185\u7f6e\u51fd\u6570range\u7684\u6570\u7ec4\u7248\uff0c\u8fd4\u56de\u4e00\u4e2a\u6570\u7ec4\u3002 \u4e0b\u9762\u662f\u7528 Numpy.random() \u4e00\u4e2a\u751f\u6210\u4e00\u4e2a\u968f\u673a\u6570\u7ec4\u7684\u4f8b\u5b50\uff0c\u6ce8\u610f data01 \u7684\u7c7b\u578b\u662f'numpy.ndarray'\u3002\u53ef\u4ee5\u5728ndarray\u7c7b\u578b\u6570\u7ec4\u4e0a\u53e0\u52a0\u4e00\u4e0b\u6570\u5b66\u64cd\u4f5c\u3002 data01 = np.random.randn(2, 3) print(type(data01)) # print(data01) # [[ 0.12047302 -1.13499045 -0.39311368] # [ 1.54046881 0.01254838 -3.65090952]] print(data01 * 10) # \u7ed9data\u52a0\u4e0a\u4e00\u4e2a\u6570\u5b66\u64cd\u4f5c, \u6240\u6709\u7684\u5143\u7d20\u90fd\u540c\u65f6\u4e58\u4ee5\u4e8610 # [[ 1.20473022 -11.3499045 -3.93113676] # [ 15.40468806 0.12548383 -36.50909515]] print(data01 + data01) # \u7ed9data\u52a0\u4e0a\u4e00\u4e2a\u6570\u5b66\u64cd\u4f5c, \u6570\u7ec4\u4e2d\u7684\u5bf9\u5e94\u5143\u7d20\u8fdb\u884c\u4e86\u76f8\u52a0 # [[ 0.24094604 -2.2699809 -0.78622735] # [ 3.08093761 0.02509677 -7.30181903]] print(data01.shape) # (2, 3) print(data01.dtype) # float64 \u5f53\u8868\u8fbe\u201c\u6570\u7ec4\u201d\u3001\u201cNumPy\u6570\u7ec4\u201d\u6216\u201cndarray\u201d\u65f6\uff0c\u90fd\u8868\u793a\u540c\u4e00\u4e2a\u5bf9\u8c61\uff1andarray\u5bf9\u8c61\u3002 \u770b\u4e0b\u9762\u7684\u4f8b\u5b50\uff1a data01 \u662f\u4e00\u4e2a\u5217\u8868\uff08list\uff09\u7c7b\u578b\uff0c\u901a\u8fc7 Numpy.array \u8f6c\u6362\u6210Numpy\u7684 ndarray \u7c7b\u578b\u3002 \u5728 np.array \u4e2d\uff0c\u9664\u975e\u663e\u5f0f\u5730\u6307\u5b9a\uff0c\u5982 np.array(data01, dtype=np.int8) \uff0c\u5426\u5219np.array\u4f1a\u81ea\u52a8\u63a8\u65ad\u751f\u6210\u6570\u7ec4\u7684\u6570\u636e\u7c7b\u578b array01.dtype \u3002 \u4f7f\u7528 astype() \u65b9\u6cd5\u663e\u5f0f\u5730\u8f6c\u6362\u6570\u7ec4\u7684\u6570\u636e\u7c7b\u578b\u3002\u4f7f\u7528 astype() \u65f6\u603b\u662f\u751f\u6210\u4e00\u4e2a*\u65b0\u7684\u6570\u7ec4*\uff0c\u5373\u4f7f\u4f60\u4f20\u5165\u7684dtype\u4e0e\u4e4b\u524d\u4e00\u6837\u3002 data02 \u662f\u4e00\u4e2a\u5d4c\u5957\u5217\u8868 [[1, 2, 3, 4], [5, 6, 7, 8]] \uff0c\u901a\u8fc7np.array()\u65b9\u6cd5\u8f6c\u6362\u6210\u591a\u7ef4\u6570\u7ec4\uff0c\u524d\u63d0\u662f\u6bcf\u4e2a\u5b50\u5217\u8868\u7684\u957f\u5ea6\u8981\u4e00\u81f4\u3002 data01 = [6, 7.5, 8, 0, 1] print(data01) # [6, 7.5, 8, 0, 1] print(type(data01)) # array01 = np.array(data01) print(\"\u77e9\u9635\u7c7b\u578b\", type(array01)) # \u77e9\u9635\u7c7b\u578b print(\"\u6837\u672c\u77e9\u9635\", array01) # \u6837\u672c\u77e9\u9635 [6. 7.5 8. 0. 1. ] print(\"\u6570\u7ec4\u7ef4\u5ea6\", array01.ndim) # \u6570\u7ec4\u7ef4\u5ea6 1 print(\"\u77e9\u9635\u5f62\u72b6\", array01.shape) # \u77e9\u9635\u5f62\u72b6 (5,) \u4e00\u884c\u4e94\u5217 print(\"\u77e9\u9635\u6570\u636e\u7c7b\u578b\", array01.dtype) # float64 data02 = [[1, 2, 3, 4], [5, 6, 7, 8]] array02 = np.array(data02) print(\"\u6837\u672c\u77e9\u9635\\n\", array02) # \u6837\u672c\u77e9\u9635 # [[1 2 3 4] # [5 6 7 8]] print(\"\u6570\u7ec4\u7ef4\u5ea6\", array02.ndim) # \u6570\u7ec4\u7ef4\u5ea6 2 print(\"\u77e9\u9635\u5f62\u72b6\", array02.shape) # \u77e9\u9635\u5f62\u72b6 (2, 4) print(\"\u77e9\u9635\u6570\u636e\u7c7b\u578b\", array02.dtype) # \u77e9\u9635\u6570\u636e\u7c7b\u578b int64 print(\"\u77e9\u96350\u8f74\u5411\u6c42\u548c\", array02.sum(axis=0)) # \u77e9\u96350\u8f74\u5411\u6c42\u548c [ 6 8 10 12] print(\"\u77e9\u96351\u8f74\u5411\u6c42\u548c\", array02.sum(axis=1)) # \u77e9\u96351\u8f74\u5411\u6c42\u548c [10 26] array03 = array02.astype(np.float64) print(array03.dtype) # float64 print(array03) # [[1. 2. 3. 4.] # [5. 6. 7. 8.]] zeros() \u65b9\u6cd5\u53ef\u4ee5\u4e00\u6b21\u6027\u521b\u9020\u51680\u6570\u7ec4\u3002 print(np.zeros(10)) # [0. 0. 0. 0. 0. 0. 0. 0. 0. 0.] ones() \u65b9\u6cd5\u53ef\u4ee5\u4e00\u6b21\u6027\u521b\u9020\u51681\u6570\u7ec4\u3002\u6ce8\u610f\uff0c\u4f20\u53c2shape\u662f\u4e00\u4e2a\u5143\u7ec4 (3, 5) \u3002 print(np.ones((3, 5))) # [[1. 1. 1. 1. 1.] # [1. 1. 1. 1. 1.] # [1. 1. 1. 1. 1.]] empty() \u65b9\u6cd5\u53ef\u4ee5\u521b\u5efa\u4e00\u4e2a\u6ca1\u6709\u521d\u59cb\u5316\u6570\u503c\u7684\u6570\u7ec4\u3002\u4f46\u662f\uff0c\u4f7f\u7528np.empty\u6765\u751f\u6210\u4e00\u4e2a\u51680\u6570\u7ec4\uff0c\u5e76\u4e0d\u53ef\u9760\uff0c\u6709\u4e9b\u65f6\u5019\u5b83\u53ef\u80fd\u4f1a\u8fd4\u56de\u672a\u521d\u59cb\u5316\u7684\u5783\u573e\u6570\u503c print(np.empty((2, 3, 2))) # [[[2.30116964e-316 0.00000000e+000] # [2.10077583e-312 6.79038654e-313] # [2.22809558e-312 2.14321575e-312]] # # [[2.35541533e-312 6.79038654e-313] # [2.22809558e-312 2.14321575e-312] # [2.46151512e-312 2.41907520e-312]]]","title":"ndarray: N-\u7ef4\u6570\u7ec4\u5bf9\u8c61"},{"location":"python/DataAnalysis/ch01/#numpy_1","text":"\u4e00\u53e5\u8bdd\u603b\u7ed3\uff1a\u5c06NumPy\u8f74\u89c6\u4e3a\u6211\u4eec\u53ef\u4ee5\u6267\u884c\u64cd\u4f5c\u7684\u65b9\u5411\u3002 \u770b\u4e0b\u9762\u7684\u4f8b\u5b50\uff1a arr_1 = np.array([[1, 1, 1], [1, 1, 1]]) arr_2 = np.array([[9, 9, 9], [9, 9, 9]]) print(arr_1) # [[1 1 1] # [1 1 1]] print(arr_2) # [[9 9 9] # [9 9 9]] \u6cbf0\u8f74\u5408\u5e76\u7684\u601d\u8def\u662f\uff0c\u4e24\u4e2a\u6570\u7ec4\u6cbf0\u8f74\u65b9\u5411\uff0c\u54110\u8f74\u201c\u584c\u7f29\u201d\uff08collapse\uff09\u3002 result = np.concatenate([arr_1, arr_2], axis=0) print(result) # [[1 1 1] # [1 1 1] # [9 9 9] # [9 9 9]] \u6cbf1\u8f74\u5408\u5e76\u7684\u601d\u8def\u662f\uff0c\u4e24\u4e2a\u6570\u7ec4\u6cbf1\u8f74\u65b9\u5411\uff0c\u54111\u8f74\u201c\u584c\u7f29\u201d result = np.concatenate([arr_1, arr_2], axis=1) print(result) # [[1 1 1 9 9 9] # [1 1 1 9 9 9]] \u6211\u4eec\u6765\u770bNumPy\u7684\u4e09\u7ef4\u6570\u7ec4\u3002 array1 = np.arange(36).reshape((3, 3, 4)) print(array1) # [[[ 0 1 2 3] # [ 4 5 6 7] # [ 8 9 10 11]] # # [[12 13 14 15] # [16 17 18 19] # [20 21 22 23]] # # [[24 25 26 27] # [28 29 30 31] # [32 33 34 35]]] \u8fd9\u6837\u770b\u4f1a\u5bb9\u6613\u7406\u89e3\u4e00\u4e9b\uff0c0\u8f74\u67093\u884c\uff0c1\u8f74\u67093\u5217\uff0c2\u8f74\u67094\u4e2a\u5143\u7d20\uff1a [[[ 0 1 2 3], [ 4 5 6 7], [ 8 9 10 11]] [[12 13 14 15], [16 17 18 19], [20 21 22 23]] [[24 25 26 27], [28 29 30 31], [32 33 34 35]]] \u8f93\u51fa\uff1a\u8f740\u7d22\u5f15\u53f7\uff1a0\uff1b\u8f741\u7d22\u5f15\u53f7\uff1a0\uff1b\u8f742\u7d22\u5f15\u53f7\uff1a\u5168\u90e8 print(array1[0, 0, :]) # [0 1 2 3] \u8f93\u51fa\uff1a\u8f740\u7d22\u5f15\u53f7\uff1a0\uff1b\u8f741\u7d22\u5f15\u53f7\uff1a0\uff1b\u8f742\u7d22\u5f15\u53f7\uff1a1 print(array1[0, 0, 1]) # 1","title":"NumPy\u8f74"},{"location":"python/DataAnalysis/ch01/#numpy_2","text":"\u4e00\u4e2a**\u6807\u91cf**\u5c31\u662f\u4e00\u4e2a\u5355\u72ec\u7684\u6570\u3002\u4e00\u4e2a\u5411\u91cf\u5c31\u662f\u4e00\u5217\u6570\uff0c\u8fd9\u4e9b\u6570\u662f\u6709\u5e8f\u6392\u5217\u7684\u3002 \u77e9\u9635\u662f\u4e8c\u7ef4\u6570\u7ec4\uff0c\u5176\u4e2d\u7684\u6bcf\u4e00\u4e2a\u5143\u7d20\u88ab\u4e24\u4e2a\u7d22\u5f15\u800c\u975e\u4e00\u4e2a\u6240\u786e\u5b9a\u3002 \u51e0\u4f55\u4ee3\u6570\u4e2d\u5b9a\u4e49\u7684**\u5f20\u91cf**\u662f\u57fa\u4e8e\u5411\u91cf\u548c\u77e9\u9635\u7684\u63a8\u5e7f\uff0c\u6211\u4eec\u53ef\u4ee5**\u5c06\u6807\u91cf\u89c6\u4e3a\u96f6\u9636\u5f20\u91cf**\uff0c \u77e2\u91cf**\u89c6\u4e3a\u4e00\u9636\u5f20\u91cf\uff0c\u90a3\u4e48**\u77e9\u9635\u5c31\u662f\u4e8c\u9636\u5f20\u91cf \u3002 \u5e26\u6709\u6807\u91cf\u8ba1\u7b97\u7684\u7b97\u672f\u64cd\u4f5c\uff0c\u4f1a\u628a\u8ba1\u7b97\u53c2\u6570\u4f20\u9012\u7ed9\u6570\u7ec4\u7684\u6bcf\u4e00\u4e2a\u5143\u7d20\u3002 \u540c\u5c3a\u5bf8\u6570\u7ec4\u4e4b\u95f4\u7684\u6bd4\u8f83 array04 == array04 \uff0c\u4f1a\u4ea7\u751f\u4e00\u4e2a\u5e03\u5c14\u503c\u6570\u7ec4 \u4e0d\u540c\u5c3a\u5bf8\u7684\u6570\u7ec4\u95f4\u7684\u64cd\u4f5c\uff0c\u5c06\u4f1a\u7528\u5230 \u5e7f\u64ad\u7279\u6027\uff08broadcasting\uff09 \u3002 array04 = np.array([ [1, 2, 3, 4, 5], [3, 4, 5, 6, 7], [5, 6, 7, 8, 9] ], dtype=int) print(array04 + array04) # [[ 2 4 6 8 10] # [ 6 8 10 12 14] # [10 12 14 16 18]] print(array04 - array04) # [[0 0 0 0 0] # [0 0 0 0 0] # [0 0 0 0 0]] print(array04 * array04) # [[ 1 4 9 16 25] # [ 9 16 25 36 49] # [25 36 49 64 81]] print(array04 / array04) # [[1. 1. 1. 1. 1.] # [1. 1. 1. 1. 1.] # [1. 1. 1. 1. 1.]] print(1 / array04) # [[1. 0.5 0.33333333 0.25 0.2 ] # [0.33333333 0.25 0.2 0.16666667 0.14285714] # [0.2 0.16666667 0.14285714 0.125 0.11111111]] print(array04 == array04) # [[ True True True True True] # [ True True True True True] # [ True True True True True]]","title":"NumPy\u6570\u7ec4\u7b97\u672f"},{"location":"python/DataAnalysis/ch01/#_2","text":"ndarray\u5bf9\u8c61\u7684\u5185\u5bb9\u53ef\u4ee5\u901a\u8fc7\u7d22\u5f15\uff08indexing\uff09\u6216\u5207\u7247\uff08slicing\uff09\u6765\u8bbf\u95ee\u548c\u4fee\u6539\uff0cndarray\u5bf9\u8c61\u4e2d\u7684\u5143\u7d20\u7d22\u5f15\u4ece\u96f6\u5f00\u59cb\u3002 \u6709\u4e09\u79cd\u53ef\u7528\u7684\u7d22\u5f15\u65b9\u6cd5\uff1a\u5b57\u6bb5\u8bbf\u95ee\uff0c\u57fa\u672c\u5207\u7247\u548c\u9ad8\u7ea7\u7d22\u5f15\u3002 \u7d22\u5f15\uff08indexing\uff09\uff1a\u83b7\u53d6\u6570\u7ec4\u4e2d\u7279\u5b9a\u4f4d\u7f6e\u5143\u7d20\u7684\u8fc7\u7a0b\u3002 \u5207\u7247\uff08slicing\uff09\uff1a\u83b7\u53d6\u6570\u7ec4\u5143\u7d20\u5b50\u96c6\u7684\u8fc7\u7a0b\u3002\u6570\u7ec4\u7684\u5207\u7247\u662f\u539f\u6570\u7ec4\u7684\u89c6\u56fe\u3002\u8fd9\u610f\u5473\u7740\u4efb\u4f55**\u5bf9\u4e8e\u89c6\u56fe\u7684\u4fee\u6539\u90fd\u4f1a\u53cd\u6620\u5230\u539f\u6570\u7ec4\u4e0a**\u3002\u6570\u7ec4\u7684\u5207\u7247, \u8fd4\u56de\u7684\u5bf9\u8c61\u662f\u964d\u4f4e\u4e00\u4e2a\u7ef4\u5ea6\u7684\u6570\u7ec4\u3002 \u4e00\u7ef4\u6570\u7ec4\u7684\u7d22\u5f15\u548c\u5207\u7247\uff1a\u4e0ePython\u7684\u5217\u8868\u7c7b\u4f3c\uff1a a[n] \uff1a\u8fd4\u56de\u7b2c n+1 \u4e2a\u5143\u7d20\u3002\u5982\u679c n \u4e3a\u8d1f\u6570\uff0c\u5219\u8fd4\u56de\u5012\u6570\u7b2c n \u4e2a\u5143\u7d20\u3002 a[n:m:k] \uff1a\u8d77\u59cb\u7f16\u53f7 n \uff0c\u7ec8\u6b62\u7f16\u53f7 m \uff0c\u6b65\u957f k \uff0c\u7528\u5192\u53f7\u5206\u5272\u3002 \u9075\u5faa\u5de6\u95ed\u53f3\u5f00\u7684\u539f\u5219 \uff0c\u5373 [n, m) \u3002\u5982\u679c n \u4e3a\u7a7a\uff0c\u5373 n = 0 \uff1b\u5982\u679c m \u4e3a\u7a7a\uff0c\u5373 m = len(a) \u3002 \u591a\u7ef4\u6570\u7ec4\u7684\u7d22\u5f15\u548c\u5207\u7247\uff1a a[n,m,k,...] \uff1a\u6bcf\u4e2a\u7ef4\u5ea6\u4e00\u4e2a\u7d22\u5f15\u503c\uff0c\u6700\u5916\u5c42\u5217\u8868\uff08list\uff09\u4e2d\u7b2c n \u4e2a\u5143\u7d20\uff0c\u6b21\u5916\u5c42\u5217\u8868\uff08list\uff09\u4e2d\u7b2c m \u4e2a\u5143\u7d20\uff0c\u4ee5\u6b64\u7c7b\u63a8\u3002\u5982\u679c n \u4e3a\u8d1f\u6570\uff0c\u5219\u8fd4\u56de\u5012\u6570\u7b2c n \u4e2a\u5143\u7d20\u3002 a[n1:m1:k1,n2:m2:k2,n3:m3:k3,...] \uff1a\u6bcf\u4e2a\u7ef4\u5ea6\u7684\u5207\u7247\u65b9\u6cd5\u4e0e\u4e00\u7ef4\u6570\u7ec4\u76f8\u540c\u3002\u987a\u5e8f\u4e3a\u4ece\u5916\u5230\u5185\u3002 array05 = np.arange(10) print(array05) # [0 1 2 3 4 5 6 7 8 9] # \u4ece\u7d22\u5f15\u503c5\u5f00\u59cb\u5230\u7d22\u5f15\u503c7\u7684\u4e00\u4e2a\u5207\u7247\u3002 print(array05[5:8]) # [5 6 7] array06 = array05[5:8] # \u4f20\u5165\u4e00\u4e2a\u6570\u503c\u7ed9\u6570\u7ec4\u7684\u5207\u7247\uff0c\u6570\u503c\u88ab\u4f20\u9012\u7ed9\u4e86\u6574\u4e2a\u5207\u7247\u3002\u4e0d\u5199\u5207\u7247\u503c\u7684[:]\u5c06\u4f1a\u5f15\u7528\u6570\u7ec4\u7684\u6240\u6709\u503c array06[:] = 12 print(array06) # [12 12 12] # \u5207\u7247\u7684\u4fee\u6539\u4f1a\u53cd\u6620\u5230\u539f\u6570\u7ec4\u4e0a print(array05) # [ 0 1 2 3 4 12 12 12 8 9] # \u8f93\u51fa3\u7ef4\u77e9\u9635\uff0c3\u884c3\u5217\uff0c\u51719\u4e2a\u5143\u7d20\uff0c\u6bcf\u4e2a\u5143\u7d20\u662f\u4e00\u4e2a\u542b3\u4e2a\u5143\u7d20\u7684\u5217\u8868 array07 = np.array([ [[0, 1, 2], [3, 4, 5], [6, 7, 8]], [[9, 0, 1], [2, 3, 4], [5, 6, 7]], [[8, 9, 0], [1, 2, 3], [4, 5, 6]], ]) # \u8f93\u51fa3\u7ef4\u77e9\u9635\uff0c\u663e\u793a\u539f\u77e9\u9635\u7684\u7b2c1\uff0c2\u884c\u76842\uff0c3\u5217\u5143\u7d20\uff0c\u4e0d\u8981\u628a\u7d22\u5f15\u53f7\u548c\u8fd9\u91cc\u7684\u8868\u8ff0\u884c\u53f7\u6df7\u6dc6\u3002 print(array07[:2, 1:]) # [[[3 4 5] [6 7 8]] # [[2 3 4] [5 6 7]]] print(array07[:2, 1:].shape) # (2, 2, 3) # \u964d\u7ef4\uff0c\u8f93\u51fa\u539f\u77e9\u9635\u7684\u7b2c3\u884c print(array07[2]) # [[8 9 0] [1 2 3] [4 5 6]] print(array07[2].shape) # (3, 3) # \u964d\u7ef4\uff0c\u8f93\u51fa\u539f\u77e9\u9635\u7684\u7b2c3\u884c print(array07[2, :]) # [[8 9 0] [1 2 3] [4 5 6]] print(array07[2, :].shape) # (3, 3) # \u964d\u7ef4\uff0c\u8f93\u51fa\u539f\u77e9\u9635\u7684\u7b2c3\u884c\uff08\u53ea\u6709\u4e09\u884c\uff0c\u6240\u4ee5[2:, :]\u7b49\u540c\u4e8e[2, :]\uff09 print(array07[2:, :]) # [[[8 9 0] [1 2 3] [4 5 6]]] print(array07[2:, :].shape) # (1, 3, 3) # \u8f93\u51fa\u539f\u77e9\u9635\u76841\uff0c2\u5217 print(array07[:, :2]) # [[[0 1 2] [3 4 5]] # [[9 0 1] [2 3 4]] # [[8 9 0] [1 2 3]]] print(array07[:, :2].shape) # (3, 2, 3) # \u964d\u7ef4\uff0c\u8f93\u51fa\u539f\u77e9\u9635\u7684\u7b2c2\u884c\u524d2\u4e2a\u5143\u7d20 print(array07[1, :2]) # [[9 0 1] [2 3 4]] print(array07[1, :2].shape) # (2, 3) # \u8f93\u51fa\u539f\u77e9\u9635\u7684\u7b2c2\u884c\u524d2\u4e2a\u5143\u7d20 print(array07[1:2, :2]) # [[[9 0 1] [2 3 4]]] print(array07[1:2, :2].shape) # (1, 2, 3) # \u5c06\u539f\u77e9\u9635\u7684\u7b2c2\u884c\u8d4b\u503c\u7ed9\u53d8\u91cf old_value = array07[2].copy() print(old_value) # [[8 9 0] [1 2 3] [4 5 6]] # \u4fee\u6539\u539f\u77e9\u9635\u7684\u7b2c2\u884c\u7684\u503c\uff0c\u6807\u91cf\u548c\u6570\u7ec4\u90fd\u53ef\u4ee5\u4f20\u9012\u7ed9 array07[2] array07[2] = 25 print(array07) # [[[ 0 1 2] [ 3 4 5] [ 6 7 8]] # [[ 9 0 1] [ 2 3 4] [ 5 6 7]] # [[25 25 25] [25 25 25] [25 25 25]]] # \u5c06\u53d8\u91cf\u503c\u8d4b\u503c\u7ed9\u539f\u77e9\u9635\u7684\u7b2c2\u884c array07[2] = old_value print(array07) # [[[0 1 2] [3 4 5] [6 7 8]] # [[9 0 1] [2 3 4] [5 6 7]] # [[8 9 0] [1 2 3] [4 5 6]]]","title":"\u57fa\u7840\u7d22\u5f15\u4e0e\u5207\u7247"},{"location":"python/DataAnalysis/ch01/#_3","text":"\u5e03\u5c14\u503c\u7d22\u5f15\uff08Boolean indexing\uff09\u662f\u901a\u8fc7\u4e00\u4e2a\u5e03\u5c14\u6570\u7ec4\u6765\u7d22\u5f15\u76ee\u6807\u6570\u7ec4\uff0c\u4ee5\u6b64\u627e\u51fa\u4e0e\u5e03\u5c14\u6570\u7ec4\u4e2d\u503c\u4e3aTrue\u7684\u5bf9\u5e94\u7684\u76ee\u6807\u6570\u7ec4\u4e2d\u7684\u6570\u636e\u3002\u5e03\u5c14\u6570\u7ec4\u7684\u957f\u5ea6\u5fc5\u987b\u4e0e\u76ee\u6807\u6570\u7ec4\u5bf9\u5e94\u7684\u8f74\u7684\u957f\u5ea6\u4e00\u81f4\u3002 \u4f7f\u7528\u5e03\u5c14\u503c\u7d22\u5f15\uff08Boolean indexing\uff09\u9009\u62e9\u6570\u636e\u65f6\uff0c\u603b\u662f\u751f\u6210\u6570\u636e\u7684\u62f7\u8d1d\uff0c\u5373\u4f7f\u8fd4\u56de\u7684\u6570\u7ec4\u5e76\u6ca1\u6709\u4efb\u4f55\u53d8\u5316\u3002 \u5047\u8bbe\u6211\u4eec\u7684\u6570\u636e\u90fd\u5728\u6570\u7ec4\u4e2d\uff0c\u5e76\u4e14\u6570\u7ec4\u4e2d\u7684\u6570\u636e\u662f\u4e00\u4e9b\u5b58\u5728\u91cd\u590d\u7684\u4eba\u540d\u3002\u7528randn\u51fd\u6570\u751f\u6210\u4e00\u4e9b\u6807\u51c6\u6b63\u6001(standard normal)\u5206\u5e03\u7684\u6570\u636e\u3002\u5047\u8bbe\u6bcf\u4e2a\u4eba\u540d\u90fd\u548cdata\u6570\u7ec4\u4e2d\u7684\u4e00\u884c\u76f8\u5bf9\u5e94\uff0c\u5e76\u4e14\u6211\u4eec\u60f3\u8981\u9009\u4e2d\u6240\u6709\u2019Bob\u2019\u5bf9\u5e94\u7684\u884c\u3002 names = np.array(['Bob', 'Joe', 'Will', 'Bob', 'Will', 'Joe', 'Joe'], dtype=' # \u56fe\u50cf\u6807\u9898 plt.title(\"$\\sqrt{x^2 + y^2}$ \u8ba1\u7b97\u503c\u7684\u7f51\u683c\u56fe\") # \u8f93\u51fa\u56fe\u50cf plt.show() \u8f93\u51fa\u56fe\u50cf\u4e3a\uff1a","title":"\u9762\u5411\u6570\u7ec4\u7f16\u7a0b"},{"location":"python/DataAnalysis/ch01/#_8","text":"numpy.where \u51fd\u6570\u662f\u4e09\u5143\u8868\u8fbe\u5f0f x if condition else y \u7684\u5411\u91cf\u5316\u7248\u672c\u3002 np.where \u7684\u7b2c\u4e8c\u4e2a\u548c\u7b2c\u4e09\u4e2a\u53c2\u6570\u5e76\u4e0d\u9700\u8981\u662f\u6570\u7ec4\uff0c\u5b83\u4eec\u53ef\u4ee5\u662f\u6807\u91cf\u3002 np.where \u5728\u6570\u636e\u5206\u6790\u4e2d\u7684\u4e00\u4e2a\u5178\u578b\u7528\u6cd5\u662f\u6839\u636e\u4e00\u4e2a\u6570\u7ec4\u6765\u751f\u6210\u4e00\u4e2a\u65b0\u7684\u6570\u7ec4\u3002 \u5047\u8bbe\u6211\u4eec\u6709\u4e00\u4e2a\u5e03\u5c14\u503c\u6570\u7ec4\u548c\u4e24\u4e2a\u6570\u503c\u6570\u7ec4\u3002\u5047\u8bbe cond \u4e2d\u7684\u5143\u7d20\u4e3a True \u65f6\uff0c\u6211\u4eec\u53d6 xarr \u4e2d\u7684\u5bf9\u5e94\u5143\u7d20\u503c\uff0c\u5426\u5219\u53d6 yarr \u4e2d\u7684\u5143\u7d20\u3002 xarray = np.array([1.1, 1.2, 1.3, 1.4, 1.5]) yarray = np.array([2.1, 2.2, 2.3, 2.4, 2.5]) cond = np.array([True, False, True, True, False]) \u901a\u8fc7\u5217\u8868\u63a8\u5bfc\u5f0f\u6765\u5b9e\u73b0\u4e0a\u8ff0\u9700\u6c42\u3002 \u7f3a\u70b9: \u9996\u5148\uff0c\u5982\u679c\u6570\u7ec4\u5f88\u5927\u7684\u8bdd\uff0c\u901f\u5ea6\u4f1a\u5f88\u6162\uff08\u56e0\u4e3a\u6240\u6709\u7684\u5de5\u4f5c\u90fd\u662f\u901a\u8fc7\u89e3\u91ca\u5668\u6765\u89e3\u91caPython\u4ee3\u7801\u5b8c\u6210\uff09\u3002 \u5176\u6b21\uff0c\u5f53\u6570\u7ec4\u662f\u591a\u7ef4\u65f6\uff0c\u5c31\u65e0\u6cd5\u51d1\u6548\u4e86\u3002 # \u901a\u8fc7\u5217\u8868\u63a8\u5bfc\u5f0f\u6765\u5b9e\u73b0 result = [(x if c else y) for x, y, c in zip(xarray, yarray, cond)] print(result) # [1.1, 2.2, 1.3, 1.4, 2.5] \u901a\u8fc7 np.where \u6765\u5b9e\u73b0\u4e0a\u8ff0\u9700\u6c42\u3002 result = np.where(cond, xarray, yarray) print(result) # [1.1 2.2 1.3 1.4 2.5] \u5047\u8bbe\u6709\u4e00\u4e2a\u968f\u673a\u751f\u6210\u7684\u77e9\u9635\u6570\u636e\uff0c\u4e0b\u9762\u4f7f\u7528np.where\u5b9e\u73b0\u66ff\u6362\u3002 array = np.random.randn(4, 4) print(\"\u6837\u672c\u77e9\u9635 \\n\", array) print(\"\u77e9\u9635\u5143\u7d20\u662f\u5426\u5927\u4e8e0 \\n\", array > 0) # \u5c06\u5176\u4e2d\u7684\u6b63\u503c\u90fd\u66ff\u6362\u4e3a2\uff0c\u5c06\u6240\u6709\u7684\u8d1f\u503c\u66ff\u6362\u4e3a-2 result03 = np.where(array > 0, 2, -2) print(\"\u5c06\u5176\u4e2d\u7684\u6b63\u503c\u90fd\u66ff\u6362\u4e3a2\uff0c\u5c06\u6240\u6709\u7684\u8d1f\u503c\u66ff\u6362\u4e3a-2 \\n\", result03) # \u4ec5\u5c06\u5176\u4e2d\u7684\u6b63\u503c\u90fd\u66ff\u6362\u4e3a2 result04 = np.where(array > 0, 2, array) print(\"\u4ec5\u5c06\u5176\u4e2d\u7684\u6b63\u503c\u90fd\u66ff\u6362\u4e3a2 \\n\", result04) # \u6837\u672c\u77e9\u9635 # [[-0.57177422 -0.34917512 2.20268075 1.99959296] # [ 0.67966599 2.67915099 -0.40528454 -0.80339907] # [-0.74406888 2.33802717 -0.74582936 0.59347128] # [ 0.68624473 0.65953112 -0.40871415 -0.68698878]] # \u77e9\u9635\u5143\u7d20\u662f\u5426\u5927\u4e8e0 # [[False False True True] # [ True True False False] # [False True False True] # [ True True False False]] # \u5c06\u5176\u4e2d\u7684\u6b63\u503c\u90fd\u66ff\u6362\u4e3a2\uff0c\u5c06\u6240\u6709\u7684\u8d1f\u503c\u66ff\u6362\u4e3a-2 # [[-2 -2 2 2] # [ 2 2 -2 -2] # [-2 2 -2 2] # [ 2 2 -2 -2]] # \u4ec5\u5c06\u5176\u4e2d\u7684\u6b63\u503c\u90fd\u66ff\u6362\u4e3a2 # [[-0.57177422 -0.34917512 2. 2. ] # [ 2. 2. -0.40528454 -0.80339907] # [-0.74406888 2. -0.74582936 2. ] # [ 2. 2. -0.40871415 -0.68698878]]","title":"\u901a\u8fc7\u6761\u4ef6\u903b\u8f91\u64cd\u4f5c\u6570\u7ec4"},{"location":"python/DataAnalysis/ch01/#_9","text":"NumPy\u6709\u4e00\u4e9b\u4e13\u95e8\u7684\u6570\u5b66\u51fd\u6570\uff0c\u7528\u6765\u8ba1\u7b97\u6574\u4e2a\u6570\u7ec4\u7edf\u8ba1\u503c\u6216\u8f74\u5411\u6570\u636e\u7684\u8ba1\u7b97\u3002\u4f8b\u5982\uff0c\u805a\u5408\u51fd\u6570\uff08\u901a\u5e38\u4e5f\u53eb\u7f29\u51cf\u51fd\u6570\uff09\uff0c\u5982sum\u3001mean\u548cstd\uff08\u6807\u51c6\u5dee\uff09\u3002 \u65e2\u53ef\u4ee5\u76f4\u63a5\u8c03\u7528\u6570\u7ec4\u5b9e\u4f8b\u7684\u65b9\u6cd5\uff0c\u4e5f\u53ef\u4ee5\u4f7f\u7528\u9876\u5c42\u7684NumPy\u51fd\u6570\u3002 \u4e3e\u4f8b\uff1a\u751f\u6210\u4e00\u4e9b\u6b63\u6001\u5206\u5e03\u7684\u968f\u673a\u6570\uff0c\u8ba1\u7b97\u90e8\u5206\u805a\u5408\u7edf\u8ba1\u6570\u636e\u3002 \u8fd9\u91cc\u518d\u5bf9\u8f74\u5411\u505a\u4e2a\u89e3\u91ca\uff0c np.random.randn(5, 4) \u4ea7\u751f\u7684\u4e8c\u7ef4\u6570\u7ec4\u662f\uff1a0\u8f74\u54115\u4e2a\u5143\u7d20, 1\u8f74\u54114\u4e2a\u5143\u7d20\u3002 # \u751f\u62102\u8f74\u6570\u7ec4 array = np.random.randn(5, 4) print(\"\u6837\u672c\u77e9\u9635 \\n\", array) print(\"\u77e9\u9635\u5143\u7d20\u5e73\u5747\u503c\", array.mean()) print(\"\u77e9\u9635\u5143\u7d20\u5e73\u5747\u503c\", np.mean(array)) print(\"\u77e9\u9635\u5143\u7d20\u548c\", array.sum()) print(\"\u77e9\u9635\u5143\u7d20\u548c\", np.sum(array)) print(\"0\u8f74\u5411\u7684\u7d2f\u548c\", array.sum(axis=0)) print(\"1\u8f74\u5411\u7684\u7d2f\u548c\", array.sum(axis=1)) print(\"1\u8f74\u5411\u7684\u5e73\u5747\u503c\", array.mean(axis=1)) # \u6837\u672c\u77e9\u9635 shape=(5, 4) 0\u8f74\u54115\u4e2a\u5143\u7d20, 1\u8f74\u54114\u4e2a\u5143\u7d20 # [[ 0.32532911 -0.00177984 -1.59432632 1.58375133] # [ 1.48921763 0.25202456 0.44076148 -1.02277289] # [-0.73490219 0.19197171 -0.22374362 0.52610852] # [-1.03531076 1.0595528 -0.11566501 0.34063544] # [-0.2122241 -0.81348187 1.70989712 -0.00732696]] # \u77e9\u9635\u5143\u7d20\u5e73\u5747\u503c 0.10788580775057008 # \u77e9\u9635\u5143\u7d20\u5e73\u5747\u503c 0.10788580775057008 # \u77e9\u9635\u5143\u7d20\u548c 2.1577161550114017 # \u77e9\u9635\u5143\u7d20\u548c 2.1577161550114017 # 0\u8f74\u5411\u7684\u7d2f\u548c [-0.16789031 0.68828737 0.21692365 1.42039545] # 1\u8f74\u5411\u7684\u7d2f\u548c [ 0.31297429 1.15923078 -0.24056558 0.24921247 0.67686419] # 1\u8f74\u5411\u7684\u5e73\u5747\u503c [ 0.07824357 0.28980769 -0.06014139 0.06230312 0.16921605] \u4e0b\u9762\u5217\u4e3e\u4e86\u5e38\u7528\u7684\u57fa\u7840\u6570\u7ec4\u7edf\u8ba1\u65b9\u6cd5\u3002 array = np.array([ [1, 2, 3, 4, 5], [3, 4, 5, 6, 7], [5, 6, 7, 8, 9] ], dtype=int) print(\"\u6837\u672c\u77e9\u9635 \\n\", array) print(\"\u8f74\u5411\u6c42\u548c\", array.sum()) print(\"\u8f74\u5411\u6c42\u548c\", array.sum(axis=0)) print(\"\u6570\u5b66\u5e73\u5747\", array.mean()) print(\"\u8f74\u5411\u6570\u5b66\u5e73\u5747\", array.mean(axis=0)) print(\"\u6807\u51c6\u5dee\", array.std(), \"\u65b9\u5dee\", array.var()) print(\"\u8f74\u5411\u6807\u51c6\u5dee\", array.std(axis=0), \"\u8f74\u5411\u65b9\u5dee\", array.var(axis=0)) print(\"\u6700\u5c0f\u503c\", array.min(), \"\u6700\u5927\u503c\", array.max()) print(\"\u8f74\u5411\u6700\u5c0f\u503c\", array.min(axis=0), \"\u8f74\u5411\u6700\u5927\u503c\", array.max(axis=0)) print(\"\u6700\u5c0f\u503c\u4f4d\u7f6e\", array.argmin(), \"\u6700\u5927\u503c\u4f4d\u7f6e\", array.argmax()) print(\"\u8f74\u5411\u6700\u5c0f\u503c\u4f4d\u7f6e\", array.argmin(axis=0), \"\u8f74\u5411\u6700\u5927\u503c\u4f4d\u7f6e\", array.argmax(axis=0)) print(\"\u7d2f\u79ef\u548c \\n\", array.cumsum()) print(\"\u8f74\u5411\u7d2f\u79ef\u548c \\n\", array.cumsum(axis=1)) print(\"\u7d2f\u79ef\u4e58\u79ef \\n\", array.cumprod()) print(\"\u8f74\u5411\u7d2f\u79ef\u4e58\u79ef \\n\", array.cumprod(axis=1)) # \u6837\u672c\u77e9\u9635 # [[1 2 3 4 5] # [3 4 5 6 7] # [5 6 7 8 9]] # \u8f74\u5411\u6c42\u548c 75 # \u8f74\u5411\u6c42\u548c [ 9 12 15 18 21] # \u6570\u5b66\u5e73\u5747 5.0 # \u8f74\u5411\u6570\u5b66\u5e73\u5747 [3. 4. 5. 6. 7.] # \u6807\u51c6\u5dee 2.160246899469287 \u65b9\u5dee 4.666666666666667 # \u8f74\u5411\u6807\u51c6\u5dee [1.63299316 1.63299316 1.63299316 1.63299316 1.63299316] \u8f74\u5411\u65b9\u5dee [2.66666667 2.66666667 2.66666667 2.66666667 2.66666667] # \u6700\u5c0f\u503c 1 \u6700\u5927\u503c 9 # \u8f74\u5411\u6700\u5c0f\u503c [1 2 3 4 5] \u8f74\u5411\u6700\u5927\u503c [5 6 7 8 9] # \u6700\u5c0f\u503c\u4f4d\u7f6e 0 \u6700\u5927\u503c\u4f4d\u7f6e 14 # \u8f74\u5411\u6700\u5c0f\u503c\u4f4d\u7f6e [0 0 0 0 0] \u8f74\u5411\u6700\u5927\u503c\u4f4d\u7f6e [2 2 2 2 2] # \u7d2f\u79ef\u548c # [ 1 3 6 10 15 18 22 27 33 40 45 51 58 66 75] # \u8f74\u5411\u7d2f\u79ef\u548c # [[ 1 3 6 10 15] # [ 3 7 12 18 25] # [ 5 11 18 26 35]] # \u7d2f\u79ef\u4e58\u79ef # [ 1 2 6 24 120 360 # 1440 7200 43200 302400 1512000 9072000 # 63504000 508032000 4572288000] # \u8f74\u5411\u7d2f\u79ef\u4e58\u79ef # [[ 1 2 6 24 120] # [ 3 12 60 360 2520] # [ 5 30 210 1680 15120]]","title":"\u6570\u5b66\u548c\u7edf\u8ba1\u65b9\u6cd5"},{"location":"python/DataAnalysis/ch01/#boolean-array","text":"\u5e03\u5c14\u503c\u6570\u7ec4\uff0c\u6709\u4e24\u4e2a\u975e\u5e38\u6709\u7528\u7684\u65b9\u6cd5any\u548call\u3002 * any\u68c0\u67e5\u6570\u7ec4\u4e2d\u662f\u5426\u81f3\u5c11\u6709\u4e00\u4e2aTrue\uff0c * all\u68c0\u67e5\u662f\u5426\u6bcf\u4e2a\u503c\u90fd\u662fTrue bools = np.array([False, False, True, False]) print(bools.any()) # True print(bools.all()) # False \u4e0b\u9762\u662f\u4e00\u4e2a\u8fd0\u7528\u5e03\u5c14\u503c\u6570\u7ec4\uff08Boolean Array\uff09\u8fdb\u884c\u6c42\u548c\u7684\u4e00\u4e2a\u4f8b\u5b50\uff0c\u5176\u4e2d (array > 0) \u672c\u8eab\u662f\u4e00\u4e2a\u5e03\u5c14\u578b\u7684\u6570\u7ec4\u3002 array = np.random.randn(100) result = (array > 0).sum() # \u8ba1\u7b97\u6b63\u503c\u7684\u4e2a\u6570 print(result) # 59 \u4e0b\u9762\u662f\u8fd0\u7528\u5e03\u5c14\u503c\u6570\u7ec4\u7684\u751f\u6210\u65b0\u6570\u7ec4\u7684\u4f8b\u5b50\u3002 arr = [[8, 9, 10, 11], [0, 1, 2, 3], [4, 5, 6, 7]] arr = np.array(arr) print(arr.shape) # (3, 4) print(arr) # [[ 8 9 10 11] # [ 0 1 2 3] # [ 4 5 6 7]] idx = [[1, 0, 0, 0], [0, 1, 0, 0], [0, 0, 1, 0]] idx = np.array(idx) print(idx.shape) # (3, 4) print(idx) # [[1 0 0 0] # [0 1 0 0] # [0 0 1 0]] result = arr[idx] # print(result.shape) # (3, 4, 4) print(result) # [[[ 0 1 2 3] # [ 8 9 10 11] # [ 8 9 10 11] # [ 8 9 10 11]] # [[ 8 9 10 11] # [ 0 1 2 3] # [ 8 9 10 11] # [ 8 9 10 11]] # [[ 8 9 10 11] # [ 8 9 10 11] # [ 0 1 2 3] # [ 8 9 10 11]]] result = arr[idx == 1] print(result.shape) print(result) # [8 1 6]","title":"\u5e03\u5c14\u503c\u6570\u7ec4(Boolean Array)\u7684\u65b9\u6cd5"},{"location":"python/DataAnalysis/ch01/#_10","text":"\u548cPython\u7684\u5185\u5efa\u5217\u8868\u7c7b\u578b\u76f8\u4f3c\uff0cNumPy\u6570\u7ec4\u53ef\u4ee5\u4f7f\u7528sort\u65b9\u6cd5\u6309\u4f4d\u7f6e\u6392\u5e8f\u3002 \u9876\u5c42\u7684np.sort\u65b9\u6cd5\u8fd4\u56de\u7684\u662f\u5df2\u7ecf\u6392\u5e8f\u597d\u7684\u6570\u7ec4*\u62f7\u8d1d*\uff0c\u800c\u4e0d\u662f\u5bf9\u539f\u6570\u7ec4\u6309\u4f4d\u7f6e\u6392\u5e8f\u3002 array = np.random.randn(6) print(\"\u6837\u672c\u77e9\u9635\", array) array.sort() print(\"\u6392\u5e8f\u540e\u77e9\u9635\", array) # \u6837\u672c\u77e9\u9635 [-0.03119521 0.01839556 0.79238537 -2.46622775 0.62522211 0.22430846] # \u6392\u5e8f\u540e\u77e9\u9635 [-2.46622775 -0.03119521 0.01839556 0.22430846 0.62522211 0.79238537] \u591a\u7ef4\u6570\u7ec4\u4e2d\u6839\u636e\u4f20\u9012\u7684axis\u503c\uff0c\u6cbf\u7740\u8f74\u5411\u5bf9\u6bcf\u4e2a\u4e00\u7ef4\u6570\u636e\u6bb5\u8fdb\u884c\u6392\u5e8f\u3002 array = np.random.randn(5, 3) print(\"\u6837\u672c\u77e9\u9635 \\n\", array) array.sort(1) print(\"\u5bf91\u8f74\u6392\u5e8f\u540e\u77e9\u9635 \\n\", array) # \u6837\u672c\u77e9\u9635 # [[-0.88057833 0.30160954 -2.08788148] # [ 0.27969618 0.62923028 -0.58157581] # [-1.87194465 -1.1102104 1.09589605] # [ 0.1467938 -1.01558304 -0.25905165] # [-0.17294279 0.62369511 0.17947059]] # \u5bf91\u8f74\u6392\u5e8f\u540e\u77e9\u9635 # [[-2.08788148 -0.88057833 0.30160954] # [-0.58157581 0.27969618 0.62923028] # [-1.87194465 -1.1102104 1.09589605] # [-1.01558304 -0.25905165 0.1467938 ] # [-0.17294279 0.17947059 0.62369511]]","title":"\u6392\u5e8f"},{"location":"python/DataAnalysis/ch01/#_11","text":"NumPy\u5305\u542b\u4e00\u4e9b\u9488\u5bf9\u4e00\u7ef4 ndarray \u6570\u7ec4\u7684\u57fa\u7840\u96c6\u5408\u64cd\u4f5c\u3002 np.unique(x, y) \u8ba1\u7b97x\u7684\u552f\u4e00\u503c\uff0c\u5e76\u6392\u5e8f\u3002 names = np.array(['Bob', 'Joe', 'Will', 'Bob', 'Will', 'Joe', 'Joe']) result = np.unique(names) # NumPy\u5b9e\u73b0 print(result) # ['Bob' 'Joe' 'Will'] result = sorted(set(names)) # \u7eafPython\u5b9e\u73b0 print(result) # ['Bob' 'Joe' 'Will'] inits = np.array([3, 3, 3, 2, 2, 1, 1, 5, 5]) result = np.unique(inits) print(result) # [1 2 3 5] np.in1d(x, y) \u8ba1\u7b97x\u4e2d\u7684\u5143\u7d20\u662f\u5426\u5305\u542b\u5728y\u4e2d\uff0c\u5e76\u8fd4\u56de\u4e00\u4e2a\u5e03\u5c14\u503c\u6570\u7ec4\u3002 inits = np.array([3, 3, 3, 2, 2, 1, 1, 5, 5]) print(np.in1d(inits, [3, 4, 5])) # [ True True True False False False False True True] np.intersect1d(x, y) \uff0c\u8ba1\u7b97x\u548cy\u7684\u4ea4\u96c6\uff0c\u5e76\u6392\u5e8f\u3002 inits = np.array([3, 3, 3, 2, 2, 1, 1, 5, 5]) print(np.intersect1d(inits, [3, 4, 5])) # [3 5] np.union1d(x, y) \u8ba1\u7b97x\u548cy\u7684\u5e76\u96c6\uff0c\u5e76\u6392\u5e8f\u3002 inits = np.array([3, 3, 3, 2, 2, 1, 1, 5, 5]) print(np.union1d(inits, [3, 4, 5])) # [1 2 3 4 5] np.setdiff1d(x, y) \u5dee\u96c6\uff0c\u5728x\u4e2d\u4f46\u4e0d\u5728y\u4e2d\u7684\u5143\u7d20\u3002 inits = np.array([3, 3, 3, 2, 2, 1, 1, 5, 5]) print(np.setdiff1d(inits, [3, 4, 5])) # [1 2] np.setxor1d(x, y) \u5f02\u6216\u96c6\uff0c\u5728x\u6216\u8005y\u4e2d\uff0c\u4f46\u4e0d\u5c5e\u4e8ex\uff0cy\u4ea4\u96c6\u7684\u5143\u7d20\u3002 inits = np.array([3, 3, 3, 2, 2, 1, 1, 5, 5]) print(np.setxor1d(inits, [3, 4, 5])) # [1 2 4]","title":"\u552f\u4e00\u503c\u4e0e\u5176\u4ed6\u96c6\u5408\u903b\u8f91"},{"location":"python/DataAnalysis/ch01/#_12","text":"NumPy\u53ef\u4ee5\u5728\u786c\u76d8\u4e2d\u5c06\u6570\u636e\u4ee5\u6587\u672c\u6216\u4e8c\u8fdb\u5236\u6587\u4ef6\u7684\u5f62\u5f0f\u8fdb\u884c\u5b58\u5165\u786c\u76d8\u6216\u7531\u786c\u76d8\u8f7d\u5165\u3002 \u5f53\u524d\u53ea\u5173\u6ce8NumPy\u7684\u5185\u5efa\u4e8c\u8fdb\u5236\u683c\u5f0f\uff0c\u56e0\u4e3a\u5927\u90e8\u5206\u7528\u6237\u66f4\u503e\u5411\u4e8e\u4f7f\u7528pandas\u6216\u5176\u4ed6\u5de5\u5177\u6765\u8f7d\u5165\u6587\u672c\u6216\u8868\u683c\u578b\u6570\u636e\u3002 np.save \u548c np.load \u662f\u9ad8\u6548\u5b58\u53d6\u786c\u76d8\u6570\u636e\u7684\u4e24\u5927\u5de5\u5177\u51fd\u6570\u3002\u6570\u7ec4\u5728\u9ed8\u8ba4\u60c5\u51b5\u4e0b\u662f\u4ee5*\u672a\u538b\u7f29*\u7684\u683c\u5f0f\u8fdb\u884c\u5b58\u50a8\u7684\uff0c\u540e\u7f00\u540d\u662f.npy\u3002 import numpy as np array1 = np.arange(10) array2 = np.arange(15).reshape(3, 5) array3 = np.arange(30).reshape(3, 2, 5) print(array1) # [0 1 2 3 4 5 6 7 8 9] print(array2) # [[ 0 1 2 3 4] # [ 5 6 7 8 9] # [10 11 12 13 14]] print(array3) # [[[ 0 1 2 3 4] # [ 5 6 7 8 9]] # [[10 11 12 13 14] # [15 16 17 18 19]] # [[20 21 22 23 24] # [25 26 27 28 29]]] # \u67e5\u770b\u5f53\u524d\u8def\u5f84 os.getcwd() # '/opt/myProject/mySite' # \u66f4\u6539\u9ed8\u8ba4\u8def\u5f84 os.chdir('/opt/myProject/mySite/docs/python/datasets/examples') # \u4fdd\u5b58\u5230\u9ed8\u8ba4\u8def\u5f84\u3002npy\u540e\u7f00\u540d\u4f1a\u88ab\u81ea\u52a8\u52a0\u4e0a np.save('some_array', array1) # \u8bfb\u53d6\u6240\u4fdd\u5b58\u7684\u6587\u4ef6 result = np.load('some_array.npy') # \u5bf9\u6bd4\u7ed3\u679c\u4e00\u81f4\u3002 print(result) # [0 1 2 3 4 5 6 7 8 9] # \u5c06\u591a\u4e2a\u6570\u7ec4\u4fdd\u5b58\u5230\u672a\u538b\u7f29\u7684\u5355\u4e2a\u6587\u4ef6\u4e2d\uff0c.npz\u683c\u5f0f np.savez('some_array_archive.npz', a=array2, b=array3) result = np.load('some_array_archive.npz') # reslt\u662f\u4e00\u4e2a\u5b57\u5178\u578b\u7684\u5bf9\u8c61 print(result['b']) # \u8f7d\u5165\u5355\u4e2a\u6570\u7ec4b # [[[ 0 1 2 3 4] # [ 5 6 7 8 9]] # [[10 11 12 13 14] # [15 16 17 18 19]] # [[20 21 22 23 24] # [25 26 27 28 29]]]","title":"\u4f7f\u7528\u6570\u7ec4\u8fdb\u884c\u6587\u4ef6\u8f93\u5165\u548c\u8f93\u51fa"},{"location":"python/DataAnalysis/ch01/#_13","text":"\u53c2\u8003\u94fe\u63a5\uff1a https://www.numpy.org.cn/reference/routines/linalg.html https://github.com/teadocs/numpy-cn \u5e0c\u814a\u5b57\u6bcd: \u0391 \u03b1 /'\u00e6lf\u0259/ alpha \u0392 \u03b2 /'bi:t\u0259/ beta \u0393 \u03b3 /'g\u00e6m\u0259/ gamma \u0394 \u03b4 /'delt\u0259/ delta \u0395 \u03b5 /'eps\u026al\u0252n/ epsilon \u0396 \u03b6 /'zi:t\u0259/ zeta \u0397 \u03b7 /'i:t\u0259/ eta \u0398 \u03b8 /'\u03b8i:t\u0259/ theta \u0399 \u03b9 /'a\u026a\u0259\u028at\u0259/ iota \u039a \u03ba /'k\u00e6p\u0259/ kappa \u2227 \u03bb /'l\u00e6md\u0259/ lambda \u039c \u03bc /mju:/ mu \u039d \u03bd /nju:/ nu \u039e \u03be /ksi/ xi \u039f \u03bf /\u0259u\u02c8maikr\u0259n/ omicron \u220f \u03c0 /pa\u026a/ pi \u03a1 \u03c1 /r\u0259\u028a/ rho \u2211 \u03c3 /'s\u026a\u0261m\u0259/ sigma \u03a4 \u03c4 /t\u0254:/ tau \u03a5 \u03c5 /\u02c8ips\u026alon/ upsilon \u03a6 \u03c6 /fa\u026a/ phi \u03a7 \u03c7 /ka\u026a/ chi \u03a8 \u03c8 /psa\u026a/ psi \u03a9 \u03c9 /'\u0259\u028am\u026a\u0261\u0259/ omega numpy.linalg \u6a21\u5757\u5305\u542b\u7ebf\u6027\u4ee3\u6570\u7684\u51fd\u6570\u3002\u4f7f\u7528\u8fd9\u4e2a\u6a21\u5757\uff0c\u53ef\u4ee5\u8ba1\u7b97\u9006\u77e9\u9635\u3001\u6c42\u7279\u5f81\u503c\u3001\u89e3\u7ebf\u6027\u65b9\u7a0b\u7ec4\u4ee5\u53ca\u6c42\u89e3\u884c\u5217\u5f0f\u7b49\u3002 import numpy as np from numpy import linalg as LA from numpy import * from numpy.linalg import inv import matplotlib.pyplot as plt","title":"\u7ebf\u6027\u4ee3\u6570"},{"location":"python/DataAnalysis/ch01/#diag","text":"np.diag \u5c06\u4e00\u4e2a\u65b9\u9635\u7684\u5bf9\u89d2\uff08\u6216\u975e\u5bf9\u89d2\uff09\u5143\u7d20\u4f5c\u4e3a\u4e00\u7ef4\u6570\u7ec4\u8fd4\u56de\uff0c\u6216\u8005\u5c06\u4e00\u7ef4\u6570\u7ec4\u8f6c\u6362\u6210\u4e00\u4e2a\u65b9\u9635\uff0c\u5e76\u4e14\u5728\u975e\u5bf9\u89d2\u7ebf\u4e0a\u6709\u96f6\u70b9\u3002 a1 = np.arange(9, dtype=float).reshape((3, 3)) r1 = np.diag(a1) r2 = np.diag(a1, k=1) r3 = np.diag(a1, k=-1) r4 = np.diag(np.diag(a1)) # \u5bf9\u89d2\u77e9\u9635 print(\"\u6837\u672c\u77e9\u9635 \\n\", a1) print(\"\u77e9\u9635\u5bf9\u89d2\u7ebf\", r1) print(\"\u77e9\u9635\u5bf9\u89d2\u7ebf\u5411\u4e0a\u504f\u79fb\", r2) print(\"\u77e9\u9635\u5bf9\u89d2\u7ebf\u5411\u4e0b\u504f\u79fb\", r3) print(\"\u5bf9\u89d2\u77e9\u9635 \\n\", r4) # \u6837\u672c\u77e9\u9635 # [[0. 1. 2.] # [3. 4. 5.] # [6. 7. 8.]] # \u77e9\u9635\u5bf9\u89d2\u7ebf [0. 4. 8.] # \u77e9\u9635\u5bf9\u89d2\u7ebf\u5411\u4e0a\u504f\u79fb [1. 5.] # \u77e9\u9635\u5bf9\u89d2\u7ebf\u5411\u4e0b\u504f\u79fb [3. 7.] # \u5bf9\u89d2\u77e9\u9635 # [[0. 0. 0.] # [0. 4. 0.] # [0. 0. 8.]]","title":"diag"},{"location":"python/DataAnalysis/ch01/#dot","text":"np.dot \u5c06\u5411\u91cf\u4e2d\u5bf9\u5e94\u5143\u7d20\u76f8\u4e58\uff0c\u518d\u76f8\u52a0\u6240\u5f97\u3002\u5373\u666e\u901a\u7684\u5411\u91cf\u4e58\u6cd5\u8fd0\u7b97\uff0c\u6216**\u77e9\u9635\u70b9\u4e58**\u3002 a1 = np.dot(3, 4) print(a1) # 12 a2 = np.arange(9, dtype=float).reshape((3, 3)) r2 = np.dot(a2, a2) print(a2) # [[0. 1. 2.] # [3. 4. 5.] # [6. 7. 8.]] print(r2) # [[ 15. 18. 21.] # [ 42. 54. 66.] # [ 69. 90. 111.]] r3 = np.dot([2j, 3j], [2j, 3j]) print(r3) # (-13+0j)","title":"dot"},{"location":"python/DataAnalysis/ch01/#trace","text":"np.trace \u8ba1\u7b97\u5bf9\u89d2\u5143\u7d20\u548c\u3002 a1 = np.arange(9, dtype=float).reshape((3, 3)) print(\"\u6837\u672c\u77e9\u9635 \\n\", a1) r1 = np.trace(a1) print(\"\u5bf9\u89d2\u7ebf\u5143\u7d20\u6c42\u548c\", r1) a2 = np.arange(24, dtype=float).reshape((2, 3, 4)) r2 = np.trace(a2) print(\"\u6837\u672c\u77e9\u9635 \\n\", a2) print(\"\u5bf9\u89d2\u7ebf\u5143\u7d20\u6c42\u548c\", r2) # \u6837\u672c\u77e9\u9635 # [[0. 1. 2.] # [3. 4. 5.] # [6. 7. 8.]] # \u5bf9\u89d2\u7ebf\u5143\u7d20\u6c42\u548c 12.0 # \u6837\u672c\u77e9\u9635 # [[[ 0. 1. 2. 3.] # [ 4. 5. 6. 7.] # [ 8. 9. 10. 11.]] # # [[12. 13. 14. 15.] # [16. 17. 18. 19.] # [20. 21. 22. 23.]]] # \u5bf9\u89d2\u7ebf\u5143\u7d20\u6c42\u548c [16. 18. 20. 22.]","title":"trace"},{"location":"python/DataAnalysis/ch01/#det","text":"np.det \u8ba1\u7b97\u77e9\u9635\u7684\u884c\u5217\u5f0f\uff08\u65b9\u9635\uff09\u3002 \u4e8c\u9636\u884c\u5217\u5f0f[[a, b], [c, d]]\u7684\u503c\u662fad - bc \u4e09\u9636\u884c\u5217\u5f0f [[a, b, c], [d, e, f], [g, h, i]]\u7684\u503c\u662f aei + bfd + cdh - ceg - bdi - afh \u4e09\u9636\u884c\u5217\u5f0f\u7684\u6027\u8d28 \u6027\u8d281\uff1a\u884c\u5217\u5f0f\u4e0e\u5b83\u7684\u8f6c\u7f6e\u884c\u5217\u5f0f\u76f8\u7b49\u3002 \u6027\u8d282\uff1a\u4e92\u6362\u884c\u5217\u5f0f\u7684\u4e24\u884c(\u5217)\uff0c\u884c\u5217\u5f0f\u53d8\u53f7\u3002 \u63a8\u8bba\uff1a\u5982\u679c\u884c\u5217\u5f0f\u6709\u4e24\u884c(\u5217)\u5b8c\u5168\u76f8\u540c\uff0c\u5219\u6b64\u884c\u5217\u5f0f\u4e3a\u96f6\u3002 \u6027\u8d283\uff1a\u884c\u5217\u5f0f\u7684\u67d0\u4e00\u884c(\u5217)\u4e2d\u6240\u6709\u7684\u5143\u7d20\u90fd\u4e58\u4ee5\u540c\u4e00\u6570k\uff0c\u7b49\u4e8e\u7528\u6570k\u4e58\u6b64\u884c\u5217\u5f0f\u3002 \u63a8\u8bba\uff1a\u884c\u5217\u5f0f\u4e2d\u67d0\u4e00\u884c(\u5217)\u7684\u6240\u6709\u5143\u7d20\u7684\u516c\u56e0\u5b50\u53ef\u4ee5\u63d0\u5230\u884c\u5217\u5f0f\u7b26\u53f7\u7684\u5916\u9762\u3002 \u6027\u8d284\uff1a\u884c\u5217\u5f0f\u4e2d\u5982\u679c\u6709\u4e24\u884c(\u5217)\u5143\u7d20\u6210\u6bd4\u4f8b\uff0c\u5219\u6b64\u884c\u5217\u5f0f\u7b49\u4e8e\u96f6\u3002 \u6027\u8d285\uff1a\u628a\u884c\u5217\u5f0f\u7684\u67d0\u4e00\u5217(\u884c)\u7684\u5404\u5143\u7d20\u4e58\u4ee5\u540c\u4e00\u6570\u7136\u540e\u52a0\u5230\u53e6\u4e00\u5217(\u884c)\u5bf9\u5e94\u7684\u5143\u7d20\u4e0a\u53bb\uff0c\u884c\u5217\u5f0f\u4e0d\u53d8\u3002 a1 = np.array([[1, 2], [3, 4]]) r1 = np.linalg.det(a1) print(\"\u4e8c\u9636\u65b9\u9635 \\n\", a1) print(\"\u4e8c\u9636\u884c\u5217\u5f0f\u7684\u503c\", r1) # \u4e8c\u9636\u65b9\u9635 # [[1 2] # [3 4]] # \u4e8c\u9636\u884c\u5217\u5f0f\u7684\u503c -2.0000000000000004 # \u5e0c\u814a\u5b57\u6bcd # \u03b1, \u03b2, \u03b3,\u03b4, \u03b5, \u03b6, \u03b7, \u03b8, \u03b9, \u03ba, \u03bb, \u03bc, \u03bd, # \u03be, \u03bf, \u03c0, \u03c1, \u03c2, \u03c3, \u03c4, \u03c5, \u03c6, \u03c7, \u03c8, \u03c9, a2 = np.arange(9).reshape(3, 3) r2 = np.linalg.det(a2) print(\"\u4e09\u9636\u65b9\u9635 \\n\", a2) print(\"\u4e09\u9636\u884c\u5217\u5f0f\u7684\u503c\", r2) # \u4e09\u9636\u65b9\u9635 # [[0 1 2] # [3 4 5] # [6 7 8]] # \u4e09\u9636\u884c\u5217\u5f0f\u7684\u503c 0.0 a3 = np.arange(16).reshape(4, 4) r3 = np.linalg.det(a3) print(\"\u56db\u9636\u65b9\u9635 \\n\", a3) print(\"\u56db\u9636\u884c\u5217\u5f0f\u7684\u503c\", r3) # \u56db\u9636\u65b9\u9635 # [[ 0 1 2 3] # [ 4 5 6 7] # [ 8 9 10 11]# \u5e0c\u814a\u5b57\u6bcd # \u03b1, \u03b2, \u03b3,\u03b4, \u03b5, \u03b6, \u03b7, \u03b8, \u03b9, \u03ba, \u03bb, \u03bc, \u03bd, # \u03be, \u03bf, \u03c0, \u03c1, \u03c2, \u03c3, \u03c4, \u03c5, \u03c6, \u03c7, \u03c8, \u03c9, # [12 13 14 15]] # \u56db\u9636\u884c\u5217\u5f0f\u7684\u503c 0.0","title":"det"},{"location":"python/DataAnalysis/ch01/#eig","text":"np.eig \u8ba1\u7b97\u65b9\u9635\u7684\u7279\u5f81\u503c\u548c\u7279\u5f81\u5411\u91cf\u3002 \u7279\u5f81\u503c\u4e0e\u7279\u5f81\u5411\u91cf\u7684\u5b9a\u4e49\uff1a\u8bbeA\u662fn\u9636\u65b9\u9635\uff0c\u82e5\u6570\u03bb\u548cn\u7ef4\u975e\u96f6\u5217\u5411\u91cfx\uff0c\u4f7f\u5f97Ax = \u03bbx\u6210\u7acb\uff0c\u5219\u79f0\u03bb\u662f\u65b9\u9635A\u7684\u4e00\u4e2a\u7279\u5f81\u503c\uff0cx\u4e3a\u65b9\u9635A\u7684\u5bf9\u5e94\u4e8e\u7279\u5f81\u503c\u03bb\u7684\u4e00\u4e2a\u7279\u5f81\u5411\u91cf\u3002 A\u662f\u65b9\u9635\u3002\uff08\u5bf9\u4e8e\u975e\u65b9\u9635\uff0c\u662f\u6ca1\u6709\u7279\u5f81\u503c\u7684\uff0c\u4f46\u4f1a\u6709\u6761\u4ef6\u6570\u3002\uff09\u7279\u5f81\u5411\u91cfx\u4e3a\u975e\u96f6\u5217\u5411\u91cf\u3002 v_eigenvectors, v_eigenvalues = LA.eig(np.diag((1, 2, 3))) print(\"\u7279\u5f81\u5411\u91cf\", v_eigenvectors) print(\"\u7279\u5f81\u503c \\n\", v_eigenvalues) # \u7279\u5f81\u5411\u91cf [1. 2. 3.] # \u7279\u5f81\u503c # [[1. 0. 0.] # [0. 1. 0.] # [0. 0. 1.]] v_eigenvectors, v_eigenvalues = LA.eig(np.array([[1, -1], [1, 1]])) print(\"\u7279\u5f81\u5411\u91cf\", v_eigenvectors) print(\"\u7279\u5f81\u503c \\n\", v_eigenvalues) # \u7279\u5f81\u5411\u91cf [1.+1.j 1.-1.j] # \u7279\u5f81\u503c # [[0.70710678+0.j 0.70710678-0.j ] # [0. -0.70710678j 0. +0.70710678j]]","title":"eig"},{"location":"python/DataAnalysis/ch01/#inv","text":"np.inv \u8ba1\u7b97\u65b9\u9635\u7684\u9006\u77e9\u9635\u3002 a1 = np.array([[1, 2], [3, 4]]) r1 = inv(a1) r2 = inv(np.matrix(a1)) print(\"\u539f\u77e9\u9635 \\n\", a1) print(\"\u9006\u77e9\u9635 \\n\", r1) print(\"\u9006\u77e9\u9635 \\n\", r2) # \u539f\u77e9\u9635 # [[1 2] # [3 4]] # \u9006\u77e9\u9635 # [[-2. 1. ] # [ 1.5 -0.5]] # \u9006\u77e9\u9635 # [[-2. 1. ] # [ 1.5 -0.5]]","title":"inv"},{"location":"python/DataAnalysis/ch01/#pinv","text":"np.pinv \u8ba1\u7b97\u77e9\u9635\u7684Moore-Penrose\u4f2a\u9006(\u6469\u5c14\uff0d\u5f6d\u82e5\u65af\u5e7f\u4e49\u9006)\u3002 \u4e0b\u9762\u7684\u4f8b\u5b50\u68c0\u9a8c a * a+ * a == a \u548c a+ * a * a+ == a+ a = np.random.randn(9, 6) B = np.linalg.pinv(a) r1 = np.allclose(a, np.dot(a, np.dot(B, a))) r2 = np.allclose(B, np.dot(B, np.dot(a, B))) print(a) print(B) print(r1) # True print(r2) # True # a: # [[-2.30316101 -0.63217332 1.24134743 -0.72492307 0.12456801 -0.14192548] # [ 1.37573495 0.07626697 -0.71870843 1.26824984 -0.79485727 -0.24630455] # [ 0.29003175 -1.23931665 -0.50864107 -0.31140718 0.45467649 -2.44973999] # [-0.70748664 -1.2995059 0.85126149 -1.10918804 -2.10042342 0.75942293] # [ 1.91765238 1.23892103 1.58516486 -1.65520154 0.11894439 0.84536298] # [ 1.03220791 0.1715148 0.85595408 0.58569706 1.34066384 -1.5782386 ] # [-0.54432889 -0.0114189 1.55403934 0.89852512 1.15586365 -0.30733805] # [-0.80874673 0.14602121 1.04680044 1.98722514 0.39766383 0.75178788] # [ 0.01664663 0.06243353 -0.50725334 -0.37707204 -1.76701091 -0.33866559]] # B: # [[-0.25055838 0.13963115 0.08990923 0.16280282 0.12997291 0.05088469 -0.01541299 -0.01656133 -0.21731387] # [ 0.22862622 -0.05108109 -0.2639602 -0.47835978 0.11776862 0.09324694 0.00436756 -0.00609393 0.61995597] # [ 0.10422554 0.03985857 0.00198025 0.15139023 0.17165026 0.15697725 0.17360246 0.13150089 0.08378135] # [-0.07021378 0.17665487 -0.04109252 0.0015022 -0.11998477 0.0543575 0.08649033 0.21190785 0.04065729] # [-0.08110336 -0.15274536 0.05601496 -0.07967802 -0.02454705 -0.04152356 0.00071268 -0.05981012 -0.43996066] # [-0.17998537 -0.03160871 -0.12587707 0.16856246 0.00565094 -0.21038026 -0.06060039 0.04322126 -0.42038066]]","title":"pinv"},{"location":"python/DataAnalysis/ch01/#qr","text":"np.qr \u8ba1\u7b97QR\u5206\u89e3\u3002QR\uff08\u6b63\u4ea4\u4e09\u89d2\uff09\u5206\u89e3\u6cd5\u662f\u6c42\u4e00\u822c\u77e9\u9635\u5168\u90e8\u7279\u5f81\u503c\u7684\u6700\u6709\u6548\u5e76\u5e7f\u6cdb\u5e94\u7528\u7684\u65b9\u6cd5\u3002 \u4e00\u822c\u77e9\u9635\u5148\u7ecf\u8fc7\u6b63\u4ea4\u76f8\u4f3c\u53d8\u5316\u6210\u4e3aHessenberg\u77e9\u9635\uff0c\u7136\u540e\u518d\u5e94\u7528QR\u65b9\u6cd5\u6c42\u7279\u5f81\u503c\u548c\u7279\u5f81\u5411\u91cf\u3002QR\u5206\u89e3\u6cd5\u662f\u5c06\u77e9\u9635\u5206\u89e3\u6210\u4e00\u4e2a\u6b63\u89c4\u6b63\u4ea4\u77e9\u9635Q\u4e0e\u4e0a\u4e09\u89d2\u5f62\u77e9\u9635R\uff0c\u6240\u4ee5\u79f0\u4e3aQR\u5206\u89e3\u6cd5\u3002 a = np.arange(9).reshape(3, 3) q, r = np.linalg.qr(a) print(\"\u539f\u77e9\u9635 \\n\", a) print(\"\u6b63\u4ea4\u77e9\u9635 \\n\", q) print(\"\u4e0a\u4e09\u89d2\u77e9\u9635 \\n\", r) # \u539f\u77e9\u9635 # [[0 1 2] # [3 4 5] # [6 7 8]] # \u6b63\u4ea4\u77e9\u9635 # [[ 0. 0.91287093 0.40824829] # [-0.4472136 0.36514837 -0.81649658] # [-0.89442719 -0.18257419 0.40824829]] # \u4e0a\u4e09\u89d2\u77e9\u9635 # [[-6.70820393e+00 -8.04984472e+00 -9.39148551e+00] # [ 0.00000000e+00 1.09544512e+00 2.19089023e+00] # [ 0.00000000e+00 0.00000000e+00 -8.88178420e-16]]","title":"qr"},{"location":"python/DataAnalysis/ch01/#svd","text":"np.svd \u8ba1\u7b97\u5947\u5f02\u503c\u5206\u89e3\uff08SVD\uff09\u3002 \u51e0\u4f55\u610f\u4e49\uff1aSVD\u5206\u89e3\u7684\u51e0\u4f55\u610f\u4e49\u662f\u4efb\u4f55\u4e00\u4e2a\u77e9\u9635A\u5728\u4e00\u7cfb\u5217\u65cb\u8f6c\u548c\u5e73\u79fb\u4e0b\u90fd\u80fd\u8f6c\u5316\u6210\u4e00\u4e2a\u5bf9\u89d2\u77e9\u9635\u2211 , \u5176\u4e2d\u9149\u9635U, V\u7684\u51e0\u4f55\u610f\u4e49\u5c31\u662f\u4e00\u7cfb\u5217\u65cb\u8f6c\u548c\u5e73\u79fb\u7684\u53e0\u52a0\u3002 a = mat([[1, 2, 3],[4, 5, 6]]) U, sigma, V = np.linalg.svd(a) print(\"\u539f\u77e9\u9635 \\n\", a) print(\"\u5de6\u5947\u5f02\u503cU \\n\", U) print(\"\u5947\u5f02\u503cSigma \\n\", sigma) print(\"\u53f3\u5947\u5f02\u503cV \\n\", V) # \u539f\u77e9\u9635 # [[1 2 3] # [4 5 6]] # \u5de6\u5947\u5f02\u503cU # [[-0.3863177 -0.92236578] # [-0.92236578 0.3863177 ]] # \u5947\u5f02\u503cSigma # [9.508032 0.77286964] # \u53f3\u5947\u5f02\u503cV # [[-0.42866713 -0.56630692 -0.7039467 ] # [ 0.80596391 0.11238241 -0.58119908] # [ 0.40824829 -0.81649658 0.40824829]]","title":"svd"},{"location":"python/DataAnalysis/ch01/#solve","text":"np.solve \u6c42\u89e3x\u7684\u7ebf\u6027\u7cfb\u7edfAx = b\uff0c\u5176\u4e2dA\u662f\u65b9\u9635\u3002 \u89e3\u65b9\u7a0b\u7ec4\uff1a x + 2y = 1 3x + 5y = 2 a = np.array([[1, 2], [3, 5]]) b = np.array([1, 2]) x = np.linalg.solve(a, b) print(x) # [-1. 1.]","title":"solve"},{"location":"python/DataAnalysis/ch01/#lstsq","text":"np.lstsq \u8ba1\u7b97Ax = b\u7684\u6700\u5c0f\u4e8c\u4e58\u89e3\u3002 \u7528\u6700\u5c0f\u4e8c\u4e58\u6cd5\u62df\u5408\u6570\u636e\u5f97\u5230\u4e00\u4e2a\u5f62\u5982y = mx + c\u7684\u7ebf\u6027\u65b9\u7a0b\uff08Return the least-squares solution to a linear matrix equation\uff09\u3002 x = np.array([0, 1, 2, 3]) # \u539f\u59cb\u6570\u636e\u70b9\u7684\u6a2a\u5750\u6807 y = np.array([-1, 0.2, 0.9, 2.1]) # \u539f\u59cb\u6570\u636e\u70b9\u7684\u7eb5\u5750\u6807 print(x) # [0 1 2 3] print(y) # [-1. 0.2 0.9 2.1] A = np.vstack([x, np.ones(len(x))]).T # \u6784\u9020\u7cfb\u6570\u77e9\u9635 print(A) # [[0. 1.] # [1. 1.] # [2. 1.] # [3. 1.]] m, c = np.linalg.lstsq(A, y, rcond=None)[0] # \u89e3\u51fa\u659c\u7387a\u548c\u7eb5\u622a\u8dddc plt.plot(x, y, 'o', label='Original data', markersize=10) # \u505a\u51fa\u539f\u59cb\u6570\u636e\u6563\u70b9\u56fe plt.plot(x, m*x + c, 'r', label='Fitted line') # \u7528\u4e0a\u9762\u89e3\u51fa\u7684\u53c2\u6570\u505a\u51fa\u62df\u5408\u66f2\u7ebfy=mx+c plt.legend() plt.show()","title":"lstsq"},{"location":"python/DataAnalysis/ch01/#_14","text":"numpy.random \u6a21\u5757\u586b\u8865\u4e86Python\u5185\u5efa\u7684 random \u6a21\u5757\u7684\u4e0d\u8db3\uff0c\u53ef\u4ee5\u9ad8\u6548\u5730\u751f\u6210\u591a\u79cd\u6982\u7387\u5206\u5e03\u4e0b\u7684\u5b8c\u6574\u6837\u672c\u503c\u6570\u7ec4\u3002 numpy.random \u4e2d\u7684\u6570\u636e\u751f\u6210\u51fd\u6570\u516c\u7528\u4e86\u4e00\u4e2a\u5168\u5c40\u7684\u968f\u673a\u6570\u79cd\u5b50\u3002 \u4f7f\u7528 numpy.random.RandomState \u751f\u6210\u4e00\u4e2a\u968f\u673a\u6570\u751f\u6210\u5668\uff0c\u4f7f\u6570\u636e\u72ec\u7acb\u4e8e\u5176\u4ed6\u7684\u968f\u673a\u6570\u72b6\u6001\u3002 \u901a\u8fc7 np.random.seed \u66f4\u6539NumPy\u7684\u968f\u673a\u6570\u79cd\u5b50\u3002 numpy.random \u4e2d\u7684\u90e8\u5206\u51fd\u6570\u5217\u8868 seed: \u5411\u968f\u673a\u6570\u751f\u6210\u5668\u4f20\u9012\u968f\u673a\u72b6\u6001\u79cd\u5b50 permutation: \u8fd4\u56de\u4e00\u4e2a\u5e8f\u5217\u7684\u968f\u673a\u6392\u5217\uff0c\u6216\u8005\u8fd4\u56de\u4e00\u4e2a\u4e71\u5e8f\u7684\u6574\u6570\u8303\u56f4\u5e8f\u5217 shuffle: \u968f\u673a\u6392\u5217\u4e00\u4e2a\u5e8f\u5217 rand: \u4ece\u5747\u5300\u5206\u5e03\u4e2d\u62bd\u53d6\u6837\u672c randint: \u6839\u636e\u7ed9\u5b9a\u7684\u7531\u4f4e\u5230\u9ad8\u7684\u8303\u56f4\u62bd\u53d6\u968f\u673a\u6574\u6570 randn: \u4ece\u5747\u503c0\u65b9\u5dee1\u7684\u6b63\u6001\u5206\u5e03\u4e2d\u62bd\u53d6\u6837\u672c(MATLAB\u578b\u63a5\u53e3\uff09 binomial: \u4ece\u4e8c\u9879\u5206\u5e03\u4e2d\u62bd\u53d6\u6837\u672c normal: \u4ece\u6b63\u6001\uff08\u9ad8\u65af\uff09\u5206\u5e03\u4e2d\u62bd\u53d6\u6837\u672c beta\u4ecebeta: \u5206\u5e03\u4e2d\u62bd\u53d6\u6837\u672c chisquare: \u4ece\u5361\u65b9\u5206\u5e03\u4e2d\u62bd\u53d6\u6837\u672c \u4f8b\u5982\uff0c\u4f7f\u7528normal\u6765\u83b7\u5f97\u4e00\u4e2a4\u00d74\u7684\u6b63\u6001\u5206\u5e03\u6837\u672c\u6570\u7ec4\uff0c\u79f0\u4e3a\u4f2a\u968f\u673a\u6570\u3002 import numpy as np samples = np.random.normal(size=(4, 4)) print(samples) # [[ 0.78583658 -0.27462104 -0.53027675 -0.62675004] # [ 0.39054781 1.20503691 -0.0057432 0.17243182] # [-0.41516669 -0.93335854 0.01996088 -0.12707275] # [ 0.42952379 2.56998319 0.14848737 -0.42871493]]","title":"\u4f2a\u968f\u673a\u6570\u751f\u6210"},{"location":"python/DataAnalysis/ch01/#_15","text":"import matplotlib.pyplot as plt import numpy as np position = 0 walk = [position] nwalks = 5000 nsteps = 1000 draws = np.random.randint(0, 2, size=(nwalks, nsteps)) steps = np.where(draws > 0, 1, -1) walks = steps.cumsum() plt.plot(walks[:500000000000000000000000000]) plt.show() \u8f93\u51fa\u56fe\u50cf\uff1a","title":"\u793a\u4f8b\uff1a\u968f\u673a\u6f2b\u6b65"},{"location":"python/DataAnalysis/ch02/","text":"Pandas\u5165\u95e8 \u00b6 \u7ea6\u5b9a\uff1a import numpy as np import pandas as pd from pandas import Series, DataFrame import pandas_datareader as web pandas\u6570\u636e\u7ed3\u6784\u4ecb\u7ecd \u00b6 Series \u00b6 Series\u662f\u4e00\u79cd\u4e00\u7ef4\u7684\u6570\u7ec4\u578b\u5bf9\u8c61\uff0c\u5b83\u5305\u542b\u4e86\u4e00\u4e2a\u503c\u5e8f\u5217\uff08\u4e0eNumPy\u4e2d\u7684\u7c7b\u578b\u76f8\u4f3c\uff09\uff0c\u5e76\u4e14\u5305\u542b\u4e86\u6570\u636e\u6807\u7b7e\uff0c\u79f0\u4e3a**\u7d22\u5f15\uff08index\uff09 \u3002 \u4ece\u53e6\u4e00\u4e2a\u89d2\u5ea6\u8003\u8651Series\uff0c\u53ef\u4ee5\u8ba4\u4e3a\u5b83\u662f\u4e00\u4e2a**\u957f\u5ea6\u56fa\u5b9a\u4e14\u6709\u5e8f\u7684\u5b57\u5178 \uff0c\u56e0\u4e3a\u5b83\u5c06\u7d22\u5f15\u503c\u548c\u6570\u636e\u503c\u6309\u4f4d\u7f6e\u914d\u5bf9\u3002\u7d22\u5f15\u5728\u5de6\u8fb9\uff0c\u503c\u5728\u53f3\u8fb9\u3002 obj = pd.Series([4, 7, -5, 3]) print(obj) # 0 4 # 1 7 # 2 -5 # 3 3 # dtype: int64 print(obj.values) # [ 4 7 -5 3 print(obj.index) # RangeIndex(start=0, stop=4, step=1) \u81ea\u5b9a\u4e49index obj = pd.Series([4, 7, -5, 3], index=['d', 'b', 'a', 'c']) print(obj) # d 4 # b 7 # a -5 # c 3 # dtype: int64 print(obj.values) # [ 4 7 -5 3] print(obj.index) # Index(['d', 'b', 'a', 'c'], dtype='object') # \u8f93\u51fa\u7d22\u5f15\u503c\u4e3a'a'\u7684Series\u503c print(obj['a']) # -5 # \u4f7f\u7528\u5e03\u5c14\u503c\u6570\u7ec4\u8fdb\u884c\u8fc7\u6ee4Series\u503c print(obj[obj > 3]) # d 4 # b 7 # dtype: int64 # \u5bf9Series\u503c\u8fdb\u884c\u7b97\u672f\u8fd0\u7b97 print(obj * 2) # d 8 # b 14 # a -10 # c 6 # dtype: int64 # \u5bf9Series\u503c\u8fdb\u884c\u7b97\u672f\u8fd0\u7b97 print(np.exp(obj)) # d 54.598150 # b 1096.633158 # a 0.006738 # c 20.085537 # dtype: float64 # \u66f4\u65b0Series\u6570\u7ec4\u503c obj['a'] = 9 # \u8f93\u51fa\u6307\u5b9a\u7d22\u5f15\u503c\u7684Series\u503c\uff0c\u6ce8\u610f\uff0c\u7d22\u5f15\u6761\u4ef6\u662f\u5217\u8868 print(obj[['a', 'b', 'c']]) # a 9 # b 7 # c 3 # dtype: int64 # \u6ce8\u610f\uff0c\u4e0b\u9762\u7684\u5224\u65ad\u662f\u7d22\u5f15\u503c\uff0c\u975eSeries\u503c print(obj) print(7 in obj) # False print('a' in obj) # True \u901a\u8fc7\u5b57\u5178\u751f\u6210\u4e00\u4e2aSeries\u3002 NaN \uff08not a number\uff09\uff0c\u8fd9\u662fpandas\u4e2d\u6807\u8bb0\u7f3a\u5931\u503c\u6216NA\u503c\u7684\u65b9\u5f0f\u3002 \u5f53\u628a\u5b57\u5178\u4f20\u9012\u7ed9Series\u6784\u9020\u51fd\u6570\u65f6\uff0c\u4ea7\u751f\u7684Series\u7684\u7d22\u5f15\u5c06\u662f\u6392\u5e8f\u597d\u7684\u5b57\u5178\u952e\u3002\u53ef\u4ee5\u5c06\u5b57\u5178\u952e\u6309\u7167\u4f60\u6240\u60f3\u8981\u7684\u987a\u5e8f\u4f20\u9012\u7ed9\u6784\u9020\u51fd\u6570\uff0c\u4ece\u800c\u4f7f\u751f\u6210\u7684Series\u7684\u7d22\u5f15\u987a\u5e8f\u7b26\u5408\u9884\u671f\u3002 \u770b\u4e0b\u4f8b\uff0c\u901a\u8fc7\u5b57\u5178sdata\u751f\u6210Series\u3002 sdata = {'Ohio': 35000, 'Texas': 71000, 'Oregon': 16000, 'Utah': 5000} obj3 = pd.Series(sdata) print(sdata) # {'Ohio': 35000, 'Texas': 71000, 'Oregon': 16000, 'Utah': 5000} print(obj3) # Ohio 35000 # Texas 71000 # Oregon 16000 # Utah 5000 # dtype: int64 \u901a\u8fc7\u6307\u5b9a\u7d22\u5f15states\u53bb\u5339\u914d\u5b57\u5178sdata\u751f\u6210\u57fa\u4e8e\u65b0\u7d22\u5f15states\u7684Series\u3002 states = ['California', 'Ohio', 'Oregon', 'Texas'] obj4 = pd.Series(sdata, index=states) print(obj4) # California NaN # Ohio 35000.0 # Oregon 16000.0 # Texas 71000.0 # dtype: float64 \u5bf9Series\u8fdb\u884c\u5e03\u5c14\u503c\u5224\u65ad\u3002 print(pd.isnull(obj4)) # California True # Ohio False # Oregon False # Texas False # dtype: bool print(pd.notnull(obj4)) # California False # Ohio True # Oregon True # Texas True # dtype: bool \u5bf9Series\u8fdb\u884c\u5e03\u5c14\u503c\u5224\u65ad\u3002 print(obj4.isnull) # print(obj4.notnull) # Series\u7684\u81ea\u52a8\u5bf9\u9f50\u7d22\u5f15\uff0c\u4e0e\u6570\u636e\u5e93\u7684join\u64cd\u4f5c\u662f\u975e\u5e38\u76f8\u4f3c\u3002 print(\"obj3 \\n\", obj3) # obj3 # Ohio 35000 # Texas 71000 # Oregon 16000 # Utah 5000 # dtype: int64 print(\"obj4 \\n\", obj4) # obj4 # California NaN # Ohio 35000.0 # Oregon 16000.0 # Texas 71000.0 # dtype: float64 print(\"obj3+obj4 \\n\", obj3 + obj4) # obj3+obj4 # California NaN # Ohio 70000.0 # Oregon 32000.0 # Texas 142000.0 # Utah NaN # dtype: float64 # \u4e0b\u9762\u662fobj3\u548cobj4\u7684\u503c\uff0c\u5e2e\u52a9\u7406\u89e3\u4e0a\u9762obj3 + obj4\u7684\u64cd\u4f5c\u3002 # obj3 obj4 # Ohio 35000 California NaN # Texas 71000 Ohio 35000.0 # Oregon 16000 Oregon 16000.0 # Utah 5000 Texas 71000.0 # dtype: int64 dtype: float64 Series\u5bf9\u8c61\u81ea\u8eab\u548c\u5176\u7d22\u5f15\u90fd\u6709name\u5c5e\u6027\u3002 obj4.name = 'population' obj4.index.name = 'state' print(obj4) # state # California NaN # Ohio 35000.0 # Oregon 16000.0 # Texas 71000.0 # Name: population, dtype: float64 \u66ff\u6362Series\u7684\u7d22\u5f15\u540d\u3002 obj = pd.Series([4, 7, -5, 3], index=['d', 'b', 'a', 'c']) print(obj) obj.index = ['Bob', 'Steve', 'Jeff', 'Ryan'] print(obj) # Bob 4 # Steve 7 # Jeff -5 # Ryan 3 # dtype: int64 DataFrame \u00b6 DataFrame\u8868\u793a\u7684\u662f\u77e9\u9635\u7684\u6570\u636e\u8868\uff0c\u5b83\u5305\u542b\u5df2\u6392\u5e8f\u7684\u5217\u96c6\u5408\uff0c\u6bcf\u4e00\u5217\u53ef\u4ee5\u662f\u4e0d\u540c\u7684\u503c\u7c7b\u578b\uff08\u6570\u503c\u3001\u5b57\u7b26\u4e32\u3001\u5e03\u5c14\u503c\u7b49\uff09\u3002 DataFrame\u65e2\u6709\u884c\u7d22\u5f15\u4e5f\u6709\u5217\u7d22\u5f15\uff0c\u5b83\u53ef\u4ee5\u88ab\u89c6\u4e3a\u4e00\u4e2a\u5171\u4eab\u76f8\u540c\u7d22\u5f15\u7684Series\u7684\u5b57\u5178\uff0c\u6bd4\u5982\u6240\u6709\u5217\u5171\u4eab\u540c\u4e00\u4e2a\u5217\u7d22\u5f15\u3002 \u5728DataFrame\u4e2d\uff0c\u6570\u636e\u88ab\u5b58\u50a8\u4e3a\u4e00\u4e2a\u4ee5\u4e0a\u7684\u4e8c\u7ef4\u5757\uff0c\u800c\u4e0d\u662f\u5217\u8868\u3001\u5b57\u5178\u6216\u5176\u4ed6\u4e00\u7ef4\u6570\u7ec4\u7684\u96c6\u5408\u3002 DataFrame\u662f\u4e8c\u7ef4\u7684\uff0c\u4f46\u53ef\u4ee5\u5229\u7528**\u5206\u5c42\u7d22\u5f15**\u5728DataFrame\u4e2d\u5c55\u73b0\u66f4\u9ad8\u7ef4\u5ea6\u7684\u6570\u636e\u3002 \u4eceDataFrame\u4e2d\u9009\u53d6\u7684\u5217\u662f\u6570\u636e\u7684\u89c6\u56fe\uff0c\u800c\u4e0d\u662f\u62f7\u8d1d \u3002\u56e0\u6b64\uff0c\u5bf9Series\u7684\u4fee\u6539\u4f1a\u6620\u5c04\u5230DataFrame\u4e2d\u3002\u5982\u679c\u9700\u8981\u590d\u5236\uff0c\u5219\u5e94\u5f53\u663e\u5f0f\u5730\u4f7f\u7528Series\u7684copy\u65b9\u6cd5\u3002 \u7531\u5b57\u5178\u6784\u6210DataFrame \u00b6 \u57fa\u4e8e\u5b57\u5178 data \u4ea7\u751f\u7684DataFrame\u4f1a\u81ea\u52a8\u4e3aSereies\u5206\u914d\u7d22\u5f15\uff0c\u5e76\u4e14\u5217\u4f1a\u6309\u7167\u6392\u5e8f\u7684\u987a\u5e8f\u6392\u5217\u3002 data = { 'state': ['Ohio', 'Ohio', 'Ohio', 'Nevada', 'Nevada', 'Nevada'], 'year': [2000, 2001, 2002, 2001, 2002, 2003], 'pop': [1.5, 1.7, 3.6, 2.4, 2.9, 3.2] } frame = pd.DataFrame(data) print(frame) # state year pop # 0 Ohio 2000 1.5 # 1 Ohio 2001 1.7 # 2 Ohio 2002 3.6 # 3 Nevada 2001 2.4 # 4 Nevada 2002 2.9 # 5 Nevada 2003 3.2 # \u5bf9\u4e8e\u5927\u578bDataFrame, head\u65b9\u6cd5\u5c06\u4f1a\u53ea\u9009\u51fa\u5934\u90e8\u7684\u82e5\u5e72\u884c, \u9ed8\u8ba4\u662f\u524d\u4e94\u884c\u3002 print(frame.head(3)) # state year pop # 0 Ohio 2000 1.5 # 1 Ohio 2001 1.7 # 2 Ohio 2002 3.6 \u5982\u679c\u6307\u5b9a\u4e86\u5217\u7684\u987a\u5e8f\uff0cDataFrame\u7684\u5217\u5c06\u4f1a\u6309\u7167\u6307\u5b9a\u987a\u5e8f\u6392\u5217\u3002 frame = pd.DataFrame(data, columns=['year', 'state', 'pop']) print(frame) # year state pop # 0 2000 Ohio 1.5 # 1 2001 Ohio 1.7 # 2 2002 Ohio 3.6 # 3 2001 Nevada 2.4 # 4 2002 Nevada 2.9 # 5 2003 Nevada 3.2 \u5982\u679c\u4f20\u7684\u5217\uff08 debt \uff09\u4e0d\u5305\u542b\u5728\u5b57\u5178\uff08 data \uff09\u4e2d\uff0c\u5c06\u4f1a\u5728\u7ed3\u679c\u4e2d\u51fa\u73b0\u7f3a\u5931\u503c\u3002 frame2 = pd.DataFrame( data, columns=['year', 'state', 'pop', 'debt'], index=['one', 'two', 'three', 'four', 'five', 'six'] ) print(frame2) # year state pop debt # one 2000 Ohio 1.5 NaN # two 2001 Ohio 1.7 NaN # three 2002 Ohio 3.6 NaN # four 2001 Nevada 2.4 NaN # five 2002 Nevada 2.9 NaN # six 2003 Nevada 3.2 NaN \u9009\u53d6\u884c, \u53ef\u4ee5\u901a\u8fc7\u4f4d\u7f6e\u6216\u884c\u7d22\u5f15\u6807\u7b7e loc \u8fdb\u884c\u9009\u53d6\u3002 print(frame2.loc['three']) # year 2002 # state Ohio # pop 3.6 # debt NaN # Name: three, dtype: object DataFrame\u4e2d\u7684\u4e00\u5217\uff0c\u53ef\u4ee5\u6309\u5b57\u5178\u578b\u6807\u8bb0\u6216\u5c5e\u6027\u90a3\u6837\u68c0\u7d22\u4e3aSeries\u3002 frame2[colunm] \u5bf9\u4e8e\u4efb\u610f\u5217\u540d\u5747\u6709\u6548\uff0c\u4f46\u662f frame2.column \u53ea\u5728\u5217\u540d\u662f\u6709\u6548\u7684Python\u53d8\u91cf\u540d\u65f6\u6709\u6548\u3002 \u8fd4\u56de\u7684Series\u4e0e\u539fDataFrame\u6709\u76f8\u540c\u7684\u7d22\u5f15\uff0c\u4e14Series\u7684 name \u5c5e\u6027\u4e5f\u4f1a\u88ab\u5408\u7406\u5730\u8bbe\u7f6e\u3002 print(frame2['state']) # one Ohio # two Ohio # three Ohio # four Nevada # five Nevada # six Nevada # Name: state, dtype: object print(frame2.state) # \u5c5e\u6027\u578b\u8fde\u63a5 # one Ohio # two Ohio # three Ohio # four Nevada # five Nevada # six Nevada # Name: state, dtype: object \u5217\u7684\u5f15\u7528\u662f\u53ef\u4ee5\u4fee\u6539\u7684\u3002\u503c\u7684\u957f\u5ea6\u5fc5\u987b\u548cDataFrame\u7684\u957f\u5ea6\u76f8\u5339\u914d,\u6bd4\u5982\uff0c\u4e0b\u4f8b\u4e2d np.arange(6.) \u548c frame2['debt'] \u7684\u957f\u5ea6\u90fd\u662f6\u3002 frame2['debt'] = 16.5 print(frame2) # Name: state, dtype: object # year state pop debt # one 2000 Ohio 1.5 16.5 # two 2001 Ohio 1.7 16.5 # three 2002 Ohio 3.6 16.5 # four 2001 Nevada 2.4 16.5 # five 2002 Nevada 2.9 16.5 # six 2003 Nevada 3.2 16.5 frame2['debt'] = np.arange(6.) print(frame2) # year state pop debt # one 2000 Ohio 1.5 0.0 # two 2001 Ohio 1.7 1.0 # three 2002 Ohio 3.6 2.0 # four 2001 Nevada 2.4 3.0 # five 2002 Nevada 2.9 4.0 # six 2003 Nevada 3.2 5.0 \u5982\u679c\u5c06Series\u8d4b\u503c\u7ed9\u4e00\u5217\u65f6\uff0cSeries\u7684\u7d22\u5f15\u5c06\u4f1a\u6309\u7167DataFrame\u7684\u7d22\u5f15\u91cd\u65b0\u6392\u5217\uff0c\u5e76\u5728\u7a7a\u7f3a\u7684\u5730\u65b9\u586b\u5145\u7f3a\u5931\u503c val = pd.Series([-1.2, -1.5, -1.7], index=['two', 'four', 'five']) frame2['debt'] = val print(frame2) # year state pop debt # one 2000 Ohio 1.5 NaN # two 2001 Ohio 1.7 -1.2 # three 2002 Ohio 3.6 NaN # four 2001 Nevada 2.4 -1.5 # five 2002 Nevada 2.9 -1.7 # six 2003 Nevada 3.2 NaN \u5982\u679c\u88ab\u8d4b\u503c\u7684\u5217( eastern \u5217)\u5e76\u4e0d\u5b58\u5728\uff0c\u5219\u4f1a\u751f\u6210\u4e00\u4e2a\u65b0\u7684\u5217\u3002 frame2.state == 'Ohio' \u8fd4\u56de\u7684\u662f\u5e03\u5c14\u503c\uff0c\u8d4b\u503c\u7ed9 eastern \u3002 frame2['eastern'] = frame2.state == 'Ohio' print(frame2) # year state pop debt eastern # one 2000 Ohio 1.5 NaN True # two 2001 Ohio 1.7 -1.2 True # three 2002 Ohio 3.6 NaN True # four 2001 Nevada 2.4 -1.5 False # five 2002 Nevada 2.9 -1.7 False # six 2003 Nevada 3.2 NaN False print(frame2.eastern) # one True # two True # three True # four False # five False # six False # Name: eastern, dtype: bool del \u5173\u952e\u5b57\u53ef\u4ee5\u50cf\u5728\u5b57\u5178\u4e2d\u90a3\u6837\u5bf9DataFrame\u5220\u9664\u5217\u3002 del frame2['eastern'] print(frame2.columns) # Index(['year', 'state', 'pop', 'debt'], dtype='object') \u4f7f\u7528\u5d4c\u5957\u5b57\u5178\u6784\u5efaDataFrame \u00b6 pandas\u4f1a\u5c06\u5b57\u5178\u7684\u952e\u4f5c\u4e3a\u5217('Nevada', etc.)\uff0c\u5c06\u5185\u90e8\u5b57\u5178\u7684\u952e\u4f5c\u4e3a\u884c\u7d22\u5f15(2001, etc.) pop = { 'Nevada': { 2001: 2.4, 2002: 2.9 }, 'Ohio': { 2000: 1.5, 2001: 1.7, 2002: 3.6 } } # \u4e0d\u6307\u5b9a\u7d22\u5f15\uff0c\u9ed8\u8ba4\u4f7f\u7528\u5b57\u5178\u7d22\u5f15 frame3 = pd.DataFrame(pop) print(frame3) # Nevada Ohio # 2001 2.4 1.7 # 2002 2.9 3.6 # 2000 NaN 1.5 # \u6307\u5b9a\u5b57\u5178\u67d0\u5217\u4f5c\u4e3a\u7d22\u5f15 print(pd.DataFrame(pop, index=[2001, 2002, 2003])) # Nevada Ohio # 2001 2.4 1.7 # 2002 2.9 3.6 # 2003 NaN NaN # \u6307\u5b9a\u4e0d\u76f8\u5e72\u7d22\u5f15 print(pd.DataFrame(pop, index=['a', 'b', 'c'])) # Nevada Ohio # a NaN NaN # b NaN NaN # c NaN NaN \u8f6c\u7f6e\u64cd\u4f5c\uff08\u8c03\u6362\u884c\u548c\u5217\uff09 print(frame3.T) # 2001 2002 2000 # Nevada 2.4 2.9 NaN # Ohio 1.7 3.6 1.5 \u4f7f\u7528\u542bSeries\u7684\u5b57\u5178\u6784\u9020DataFrame \u00b6 frame3['Ohio'][:-1] \u662f\u503c\u4e3a Ohio \u7684Series\u76840~\u5012\u6570\u7b2c\u4e00\u4e2a\u5143\u7d20\uff08\u4e0d\u542b\uff09\uff0c\u4e00\u51713\u4e2a\u3002 frame3['Nevada'][:2] \u662f\u503c\u4e3a Nevada \u7684Series\u7684\u524d2\u4e2a\u5143\u7d20\u3002 pdata = { 'Ohio': frame3['Ohio'][:-1], 'Nevada': frame3['Nevada'][:2] } print(pd.DataFrame(pdata)) # Ohio Nevada # 2001 1.7 2.4 # 2002 3.6 2.9 \u6307\u5b9aDataframe frame3 \u7684\u5217\u540d\u3002 frame3.index.name = 'year' frame3.columns.name = 'state' print(frame3) # state Nevada Ohio # year # 2001 2.4 1.7 # 2002 2.9 3.6 # 2000 NaN 1.5 \u53ea\u8f93\u51faDataframe\u7684\u503c frame3.values \uff0c\u662f\u4e00\u4e2a\u4e8c\u7ef4\u6570\u7ec4\u3002 print(frame3.values) # [[2.4 1.7] # [2.9 3.6] # [nan 1.5]] \u53ea\u8f93\u51faDataframe\u7684\u503c frame2.values \uff0c\u662f\u4e00\u4e2a\u4e8c\u7ef4\u6570\u7ec4\u3002 print(frame2) # year state pop debt # one 2000 Ohio 1.5 NaN # two 2001 Ohio 1.7 -1.2 # three 2002 Ohio 3.6 NaN # four 2001 Nevada 2.4 -1.5 # five 2002 Nevada 2.9 -1.7 # six 2003 Nevada 3.2 NaN print(frame2.values) # [[2000 'Ohio' 1.5 nan] # [2001 'Ohio' 1.7 -1.2] # [2002 'Ohio' 3.6 nan] # [2001 'Nevada' 2.4 -1.5] # [2002 'Nevada' 2.9 -1.7] # [2003 'Nevada' 3.2 nan]] \u7d22\u5f15\u5bf9\u8c61 \u00b6 pandas\u4e2d\u7684**\u7d22\u5f15\u5bf9\u8c61**\u662f\u7528\u4e8e\u5b58\u50a8\u8f74\u6807\u7b7e\u548c\u5176\u4ed6\u5143\u6570\u636e\u7684\uff08\u4f8b\u5982\u8f74\u540d\u79f0\u6216\u6807\u7b7e\uff09\u3002 \u5728\u6784\u9020Series\u6216DataFrame\u65f6\uff0c\u4f60\u6240\u4f7f\u7528\u7684\u4efb\u610f\u6570\u7ec4\u6216\u6807\u7b7e\u5e8f\u5217\u90fd\u53ef\u4ee5\u5728\u5185\u90e8\u8f6c\u6362\u4e3a\u7d22\u5f15\u5bf9\u8c61\u3002 \u7d22\u5f15\u5bf9\u8c61\u662f\u4e0d\u53ef\u53d8\u7684\u3002 \u9664\u4e86\u7c7b\u4f3c\u6570\u7ec4\uff0c\u7d22\u5f15\u5bf9\u8c61\u4e5f\u50cf\u4e00\u4e2a\u56fa\u5b9a\u5927\u5c0f\u7684\u96c6\u5408\u3002\u4e0ePython\u96c6\u5408\u4e0d\u540c\uff0c pandas\u7d22\u5f15\u5bf9\u8c61\u53ef\u4ee5\u5305\u542b\u91cd\u590d\u6807\u7b7e \u3002 \u56e0\u4e3a\u4e00\u4e9b\u64cd\u4f5c\u4f1a\u4ea7\u751f\u5305\u542b\u7d22\u5f15\u5316\u6570\u636e\u7684\u7ed3\u679c\uff0c\u7406\u89e3\u7d22\u5f15\u5982\u4f55\u5de5\u4f5c\u8fd8\u662f\u5f88\u91cd\u8981\u7684\u3002 \u4e0b\u4f8b\u6f14\u793a\u4e86\u5982\u4f55\u8bfb\u53d6Dataframe\u7684\u7d22\u5f15\u503c\u3002 obj = pd.Series(range(3), index=['a', 'b', 'c']) index = obj.index print(obj) # a 0 # b 1 # c 2 # dtype: int64 print(index) # Index(['a', 'b', 'c'], dtype='object') print(index[1:]) # Index(['b', 'c'], dtype='object') \u4e0b\u4f8b\u6f14\u793a\u4e86\u901a\u8fc7\u4e00\u4e2a\u6307\u5b9a\u7684Dataframe\u7d22\u5f15 labels \u6765\u751f\u6210Dataframe obj2 \u3002 labels = pd.Index(np.arange(3)) print(labels) # Int64Index([0, 1, 2], dtype='int64') obj2 = pd.Series([1.5, -2.5, 0], index=labels) print(obj2) # 0 1.5 # 1 -2.5 # 2 0.0 # dtype: float64 print(obj2.index is labels) # True \u4e0b\u4f8b\u6f14\u793a\u4e86\u4e0d\u6307\u5b9a\u7d22\u5f15\uff0c\u9ed8\u8ba4\u4f7f\u7528\u5b57\u5178\u7d22\u5f15\u6765\u521b\u5efaDataframe\u3002 pop = { 'Nevada': { 2001: 2.4, 2002: 2.9 }, 'Ohio': { 2000: 1.5, 2001: 1.7, 2002: 3.6 } } frame3 = pd.DataFrame(pop) print(frame3) # Nevada Ohio # 2001 2.4 1.7 # 2002 2.9 3.6 # 2000 NaN 1.5 print(frame3) # state Nevada Ohio # year # 2001 2.4 1.7 # 2002 2.9 3.6 # 2000 NaN 1.5 print(frame3.columns) # Index(['Nevada', 'Ohio'], dtype='object', name='state') print(frame3.index) # Int64Index([2001, 2002, 2000], dtype='int64', name='year') print('Ohio' in frame3.columns) # True print(2003 in frame3.index) # False pandas\u7d22\u5f15\u5bf9\u8c61\u5141\u8bb8\u5305\u542b\u91cd\u590d\u6807\u7b7e\u3002\u6839\u636e\u91cd\u590d\u6807\u7b7e\u8fdb\u884c\u7b5b\u9009\uff0c\u4f1a\u9009\u53d6\u6240\u6709\u91cd\u590d\u6807\u7b7e\u5bf9\u5e94\u7684\u6570\u636e\u3002 dup_labels = pd.Index(['foo', 'foo', 'bar', 'bar']) print(dup_labels) # Index(['foo', 'foo', 'bar', 'bar'], dtype='object') \u4e00\u4e9b\u5e38\u7528\u7d22\u5f15\u5bf9\u8c61\u7684\u65b9\u6cd5\u548c\u5c5e\u6027\u3002 obj1 = pd.Series(range(3), index=['a', 'b', 'c']) index1 = obj1.index obj2 = pd.Series(range(3), index=['c', 'f', 'g']) index2 = obj2.index print(index1) # Index(['a', 'b', 'c'], dtype='object') print(index2) # Index(['c', 'f', 'g'], dtype='object') append \u65b9\u6cd5\uff1a\u5c06\u5916\u90e8\u7684\u7d22\u5f15\u5bf9\u8c61\u7c98\u8d34\u5230\u539f\u7d22\u5f15\u540e\uff0c\u4ea7\u751f\u4e00\u4e2a\u65b0\u7684\u7d22\u5f15\u3002 \u63a5\u4e0a\u4f8b\uff0c\u628a index2 \u5bf9\u8c61\u8ffd\u52a0\u5230 index1 \u5bf9\u8c61\u3002 print(index1.append(index2)) # Index(['a', 'b', 'c', 'c', 'f', 'g'], dtype='object') difference \u65b9\u6cd5: \u8ba1\u7b972\u4e2a\u7d22\u5f15\u7684\u5dee\u96c6\u3002 print(index1.difference(index2)) # Index(['a', 'b'], dtype='object') intersection \u65b9\u6cd5: \u8ba1\u7b972\u4e2a\u7d22\u5f15\u7684\u4ea4\u96c6\u3002 print(index1.intersection(index2)) # Index(['c'], dtype='object') union \u65b9\u6cd5: \u8ba1\u7b972\u4e2a\u7d22\u5f15\u7684\u5e76\u96c6\uff08\u53bb\u91cd\uff09\u3002 print(index1.union(index2)) # Index(['a', 'b', 'c', 'f', 'g'], dtype='object') isin \u65b9\u6cd5: \u8ba1\u7b97\u8868\u793a\u6bcf\u4e00\u4e2a\u503c\u662f\u5426\u5728\u4f20\u503c\u5bb9\u5668\u4e2d\uff0c\u8fd4\u56de\u7684\u662f\u4e00\u4e2a\u5e03\u5c14\u6570\u7ec4\u3002 print(index1.isin(index2)) # [False False True] delete \u65b9\u6cd5: \u5c06\u4f4d\u7f6ei\uff08\u4ece0\u5f00\u59cb\u7f16\u53f7\uff09\u7684\u5143\u7d20\u5220\u9664\uff0c\u5e76\u4ea7\u751f\u65b0\u7684\u7d22\u5f15\u3002 print(index1.delete('b')) # IndexError: arrays used as indices must be of integer (or boolean) type print(index1.delete(1)) # Index(['a', 'c'], dtype='object') print(index1) # Index(['a', 'b', 'c'], dtype='object') drop \u65b9\u6cd5: \u6839\u636e\u4f20\u53c2\u5220\u9664\u6307\u5b9a\u7d22\u5f15\u503c\uff0c\u5e76\u4ea7\u751f\u65b0\u7684\u7d22\u5f15, \u5bf9\u6bd4\u548cdelete\u7684\u533a\u522b\uff0c delete \u65b9\u6cd5\u662f\u8f93\u5165\u4f4d\u7f6e\uff0c drop \u65b9\u6cd5\u662f\u8f93\u5165\u7d22\u5f15\u540d\u79f0\u3002 print(index2.drop(1)) # KeyError: '[1] not found in axis' print(index2.drop('f')) # Index(['c', 'g'], dtype='object') print(index2) # Index(['c', 'f', 'g'], dtype='object') insert \u65b9\u6cd5: \u5728\u4f4d\u7f6e i \u63d2\u5165\u5143\u7d20\uff0c\u5e76\u4ea7\u751f\u65b0\u7684\u7d22\u5f15\u3002 print(index1.insert(1, 'e')) # Index(['a', 'e', 'b', 'c'], dtype='object') print(index1) # Index(['a', 'b', 'c'], dtype='object') is_monotonic \u65b9\u6cd5: \u5982\u679c\u7d22\u5f15\u5e8f\u5217\u9012\u589e\uff0c\u5219\u8fd4\u56de True \u3002 print(index1.is_monotonic) # True print(index1.insert(1, 'e').is_monotonic) # False is_unique \u65b9\u6cd5: \u5982\u679c\u7d22\u5f15\u5e8f\u5217\u552f\u4e00\u5219\u8fd4\u56de True \u3002 print(index1.is_unique) # True print(index1.append(index2).is_unique) # False unique \u65b9\u6cd5: \u8ba1\u7b97\u7d22\u5f15\u7684\u552f\u4e00\u503c\u5e8f\u5217\uff08\u5bf9\u6bd4Union\uff09\u3002 print(index1.unique()) # Index(['a', 'b', 'c'], dtype='object') print(index1.append(index2).unique()) # Index(['a', 'b', 'c', 'f', 'g'], dtype='object') pandas\u57fa\u672c\u529f\u80fd \u00b6 \u91cd\u5efa\u7d22\u5f15 \u00b6 Series\u8c03\u7528 reindex \u65b9\u6cd5\u65f6\uff0c\u4f1a\u5c06\u6570\u636e\u6309\u7167\u65b0\u7684\u7d22\u5f15\u8fdb\u884c\u6392\u5217\uff0c\u5982\u679c\u67d0\u4e2a\u7d22\u5f15\u503c\u4e4b\u524d\u5e76\u4e0d\u5b58\u5728\uff0c\u5219\u4f1a\u5f15\u5165\u7f3a\u5931\u503c\u3002 \u4e0b\u4f8b\u4e2d\uff0c\u5bf9 obj1 \u505a reindex \uff0c reindex \u65b9\u6cd5\u4f1a\u521b\u5efa\u4e00\u4e2a\u65b0\u7d22\u5f15\u5bf9\u8c61 obj2 \uff0c\u7d22\u5f15\u503c e \u4e4b\u524d\u5e76\u4e0d\u5b58\u5728\uff0c\u6240\u4ee5\u586b\u5165\u7f3a\u5931\u503c\u3002 \u5982\u679c\u5bf9obj1\u505a reindex \u65f6\u6307\u5b9a method='ffill' \uff0c\u4f1a\u62a5\u9519 index must be monotonic increasing or decreasing \u3002 obj1 = pd.Series([4.5, 7.2, -5.3, 3.6], index=['d', 'b', 'a', 'c']) print(obj1) # d 4.5 # b 7.2 # a -5.3 # c 3.6 # dtype: float64 obj2 = obj1.reindex(['a', 'b', 'c', 'd', 'e']) print(obj2) # a -5.3 # b 7.2 # c 3.6 # d 4.5 # e NaN # dtype: float64 obj2 = obj1.reindex(['a', 'b', 'c', 'd', 'e'], method='ffill') # ValueError: index must be monotonic increasing or decreasing \u5bf9\u4e8e\u987a\u5e8f\u6570\u636e\uff0c\u6bd4\u5982\u65f6\u95f4\u5e8f\u5217\uff0c\u5728\u91cd\u5efa\u7d22\u5f15\u65f6\u53ef\u80fd\u4f1a\u9700\u8981\u8fdb\u884c\u63d2\u503c\u6216\u586b\u503c\u3002 ffill \u65b9\u6cd5\u5728\u91cd\u5efa\u7d22\u5f15\u65f6\u63d2\u503c\uff0c\u5c06\u503c\u524d\u5411\u586b\u5145\u3002 obj3 = pd.Series(['blue', 'purple', 'yellow'], index=[0, 2, 4]) print(obj3.reindex(range(6), method='ffill')) # 0 blue # 1 blue # 2 purple # 3 purple # 4 yellow # 5 yellow # dtype: object \u5728DataFrame\u4e2d\uff0c reindex \u53ef\u4ee5\u6539\u53d8\u884c\u7d22\u5f15\u3001\u5217\u7d22\u5f15\uff0c\u4e5f\u53ef\u4ee5\u540c\u65f6\u6539\u53d8\u4e8c\u8005\u3002\u5f53\u4ec5\u4f20\u5165\u4e00\u4e2a\u5e8f\u5217\u65f6\uff0c\u4f1a\u91cd\u5efa\u884c\u7d22\u5f15\u3002 \u4e0b\u4f8b\u4e2d\uff0c\u901a\u8fc7 indexes \u521b\u5efaDataframe frame \u3002 \u901a\u8fc7 frame.reindex(['a', 'b', 'c', 'd'])\u91cd\u5efa\u884c\u7d22\u5f15 \u3002 \u901a\u8fc7 frame2.reindex(columns=['Ohio', 'Uta', 'California']) \u91cd\u5efa\u5217\u7d22\u5f15\u3002 \u7f3a\u5931\u7684\u7d22\u5f15\u5217\u586b\u5165\u7f3a\u5931\u503c\u3002 indexes = index = ['a', 'b', 'c'] states = ['Ohio', 'Texas', 'California'] frame = pd.DataFrame( np.arange(9).reshape(3, 3), index=indexes, columns=states ) print(frame) # Ohio Texas California # a 0 1 2 # b 3 4 5 # c 6 7 8 frame2 = frame.reindex(['a', 'b', 'c', 'd']) # \u91cd\u5efa\u884c\u7d22\u5f15 print(frame2) # Ohio Texas California # a 0.0 1.0 2.0 # b 3.0 4.0 5.0 # c 6.0 7.0 8.0 # d NaN NaN NaN frame3 = frame2.reindex(columns=['Ohio', 'Uta', 'California']) # \u91cd\u5efa\u5217\u7d22\u5f15 print(frame3) # Ohio Uta California # a 0.0 NaN 2.0 # b 3.0 NaN 5.0 # c 6.0 NaN 8.0 # d NaN NaN NaN \u4f7f\u7528 loc \u8fdb\u884c\u66f4\u4e3a\u7b80\u6d01\u7684\u884c\u3001\u5217\u6807\u7b7e\u7d22\u5f15\u3002\u4e0b\u4f8b\u901a\u8fc7\u7b5b\u9009\u884c\u7d22\u5f15\u548c\u5217\u7d22\u5f15\u4ea7\u751f\u65b0\u7684Dataframe\u3002 frame4 = frame.loc[['a', 'b'], states] print(frame4) # Ohio Texas California # a 0 1 2 # b 3 4 5 \u8f74\u5411\u7d22\u5f15\u5220\u9664\u6761\u76ee \u00b6 set_index() , dropna() , fillna() , reset_index() , drop() , replace() \u8fd9\u4e9b\u65b9\u6cd5\u7684 inplace \u5c5e\u6027\u8bbe\u4e3a True \u65f6\uff0c\u8fd9\u4e9b\u65b9\u6cd5\u4f1a\u4fee\u6539Series\u6216DataFrame\u7684\u5c3a\u5bf8\u6216\u5f62\u72b6\uff0c*\u76f4\u63a5*\u64cd\u4f5c\u539f\u5bf9\u8c61\u800c\u4e0d\u8fd4\u56de\u65b0\u5bf9\u8c61\u3002 obj = pd.Series(np.arange(5), index=['a', 'b', 'c', 'd', 'e']) print(obj) # a 0 # b 1 # c 2 # d 3 # e 4 # dtype: int64 obj1 = obj.drop('c') print(obj1) # a 0 # b 1 # d 3 # e 4 # dtype: int64 print(obj1.drop(['d', 'e'])) # a 0 # b 1 # dtype: int64 \u5bf9\u6bd4 inplace=True \u548c False \u7684\u533a\u522b\u3002 inplace=False \u65f6\uff0c obj \u7684\u503c\u6ca1\u6709\u53d8\u5316\u3002 obj = pd.Series(np.arange(5), index=['a', 'b', 'c', 'd', 'e']) print(obj.drop('c', inplace=False)) # \u8bf4\u660e\u751f\u6210\u4e86\u65b0\u5bf9\u8c61 # a 0 # b 1 # d 3 # e 4 # dtype: int64 print(obj) # a 0 # b 1 # c 2 # d 3 # e 4 # dtype: int64 obj.drop('c', inplace=True) \u8f93\u51fa\u662f None \uff0c\u8bf4\u660e\u6ca1\u6709\u751f\u6210\u65b0\u5bf9\u8c61\uff0c\u53d8\u5316\u76f4\u63a5\u4f5c\u7528\u5230 obj \u4e0a\u3002 obj = pd.Series(np.arange(5), index=['a', 'b', 'c', 'd', 'e']) print(obj) print(obj.drop('c', inplace=True)) # \u8bf4\u660e\u6ca1\u6709\u751f\u6210\u65b0\u5bf9\u8c61 # None print(obj) # a 0 # b 1 # d 3 # e 4 # dtype: int64 \u4e0b\u4f8b\u6f14\u793a\u4e86\u8f74\u5411\u7684\u6548\u679c\u3002 \u5982\u679c\u4e0d\u6307\u5b9a\u8f74\u5411axis\uff0c drop() \u4f1a\u9ed8\u8ba4\u6cbf axis=0 \u8fdb\u884c\uff0c\u6240\u4ee5\uff0c\u57280\u8f74\u4e0a\u6267\u884c data.drop(['one', 'two']) \u4f1a\u62a5\u9519\u3002 axis='columns \u4e0e\u6307\u5b9a axis=1 \u540c\u6837\u6548\u679c\u3002 data = pd.DataFrame( np.arange(16).reshape(4, 4), index=['Ohio', 'Colorado', 'Utah', 'New York'], columns=['one', 'two', 'three', 'four'] ) print(data) # one two three four # Ohio 0 1 2 3 # Colorado 4 5 6 7 # Utah 8 9 10 11 # New York 12 13 14 15 # \u6cbf0\u8f74\u64cd\u4f5c\uff0c\u5220\u9664\u7b26\u5408\u6761\u4ef6\u7684\u884c\u8bb0\u5f55 print(data.drop(['Ohio', 'Colorado'])) # one two three four # Utah 8 9 10 11 # New York 12 13 14 15 print(data.drop(['one', 'two'])) # KeyError: \"['one' 'two'] not found in axis\" # \u6cbf1\u8f74\u64cd\u4f5c\uff0c\u5220\u9664\u7b26\u5408\u6761\u4ef6\u7684\u5217\u8bb0\u5f55 print(data.drop(['one', 'two'], axis=1)) # three four # Ohio 2 3 # Colorado 6 7 # Utah 10 11 # New York 14 15 print(data.drop(['one', 'two'], axis='columns')) # three four # Ohio 2 3 # Colorado 6 7 # Utah 10 11 # New York 14 15 \u518d\u901a\u8fc7\u4e0b\u4f8b\u4f53\u4f1a\u4e00\u4e0b inplace \u53c2\u6570\u7684\u4e0d\u540c\u6548\u679c\u3002 data = pd.DataFrame( { 'Name': ['Shobhit', 'vaibhav', 'vimal', 'Sourabh'], 'class': [11, 12, 10, 9], 'Age': [18, 20, 21, 17] } ) print(data) # Name class Age # 0 Shobhit 11 18 # 1 vaibhav 12 20 # 2 vimal 10 21 # 3 Sourabh 9 17 print(data.rename(columns={'Name': 'FirstName'}, inplace=False)) # FirstName class Age # 0 Shobhit 11 18 # 1 vaibhav 12 20 # 2 vimal 10 21 # 3 Sourabh 9 17 print(data) # Name class Age # 0 Shobhit 11 18 # 1 vaibhav 12 20 # 2 vimal 10 21 # 3 Sourabh 9 17 print(data.rename(columns={'Name': 'FirstName'}, inplace=True)) # \u6ca1\u6709\u751f\u6210\u65b0\u5bf9\u8c61 # None print(data) # FirstName class Age # 0 Shobhit 11 18 # 1 vaibhav 12 20 # 2 vimal 10 21 # 3 Sourabh 9 17 \u7d22\u5f15\u3001\u9009\u62e9\u4e0e\u8fc7\u6ee4 \u00b6 Series\u7684\u7d22\u5f15 obj[...] \u4e0eNumPy\u6570\u7ec4\u7d22\u5f15\u7684\u529f\u80fd\u7c7b\u4f3c\uff0c\u53ea\u4e0d\u8fc7Series\u7684\u7d22\u5f15\u503c\u53ef\u4ee5\u4e0d\u4ec5\u4ec5\u662f\u6574\u6570\u3002 \u4e0b\u4f8b\u4e2d\uff1a obj[1] \u901a\u8fc7\u7d22\u5f15\u4f4d 1 \u68c0\u7d22\uff0c\u8f93\u51fa\u5bf9\u5e94Series\u7684\u503c\u3002 obj[1] \u901a\u8fc7\u7d22\u5f15\u4f4d [1] \u68c0\u7d22\uff0c\u8f93\u51faSeries\u3002 obj['b'] \u901a\u8fc7\u7d22\u5f15\u503c 'b' \u68c0\u7d22\uff0c\u8f93\u51fa\u5bf9\u5e94Series\u7684\u503c\u3002 obj[['b']] \u901a\u8fc7\u7d22\u5f15\u503c ['b'] \u68c0\u7d22\uff0c\u8f93\u51faSeries\u3002 obj = pd.Series(['Shobhit', 'vaibhav', 'vimal', 'Sourabh'], index=['a', 'b', 'c', 'd']) print(obj) # a Shobhit # b vaibhav # c vimal # d Sourabh # dtype: object print(obj[1]) # \u901a\u8fc7\u7d22\u5f15\u4f4d\u68c0\u7d22\uff0c\u8f93\u51fa\u5bf9\u5e94Series\u7684\u503c # vaibhav print(obj[[1]]) # b vaibhav # dtype: object print(obj['b']) # \u901a\u8fc7\u7d22\u5f15\u503c\u68c0\u7d22\uff0c\u8f93\u51fa\u5bf9\u5e94Series\u7684\u503c # vaibhav print(obj[['b']]) # \u901a\u8fc7\u7d22\u5f15\u503c\u68c0\u7d22\uff0c\u8f93\u51faSeries # b vaibhav # dtype: object \u4e0b\u9762\u4e00\u7ec4\u7684\u8f93\u51fa\u4e2d\uff0c\u6ce8\u610f\u5bf9\u6bd4\u666e\u901aPython\u5207\u7247\u4e0eSeries\u7684\u5207\u7247\u7684\u5dee\u5f02\u3002 obj = pd.Series(['Shobhit', 'vaibhav', 'vimal', 'Sourabh'], index=['a', 'b', 'c', 'd']) print(obj[1]) # vaibhav print(obj[[1]]) # b vaibhav # dtype: object print(obj[1:3]) # b vaibhav # c vimal # dtype: object print(obj['b':'d']) # b vaibhav # c vimal # d Sourabh # dtype: object Series\u7684\u5207\u7247\u7684\u503c\u66f4\u65b0\u3002 obj['b': 'c'] = 5 \u662f\u901a\u8fc7\u7d22\u5f15\u503c\u8fdb\u884c\u66f4\u65b0\uff0c\u76f4\u63a5\u4f5c\u7528\u5728 obj \u3002 obj[1: 3] = 6 \u662f\u901a\u8fc7\u7d22\u5f15\u4f4d\u7f6e\u6765\u66f4\u65b0 obj \u3002 obj = pd.Series(['Shobhit', 'vaibhav', 'vimal', 'Sourabh'], index=['a', 'b', 'c', 'd']) obj['b': 'c'] = 5 print(obj) # a Shobhit # b 5 # c 5 # d Sourabh # dtype: object obj[1: 3] = 6 print(obj) # a Shobhit # b 6 # c 6 # d Sourabh # dtype: object DataFrame\u7684\u7d22\u5f15\u4e0e\u5207\u7247\u3002 data[['Three', 'Two']] \u9009\u53d6\u6307\u5b9a\u5217\uff0c\u6ce8\u610f\u8f93\u5165\u5217\u6761\u4ef6\u662f\u5217\u8868 ['Three', 'Two'] \u3002 data = pd.DataFrame( np.arange(16).reshape(4, 4), index=['Ohio', 'Colorado', 'Utah', 'New York'], columns=['One', 'Two', 'Three', 'Four'] ) print(data) # One Two Three Four # Ohio 0 1 2 3 # Colorado 4 5 6 7 # Utah 8 9 10 11 # New York 12 13 14 15 print(data['Two']) # Ohio 1 # Colorado 5 # Utah 9 # New York 13 # Name: Two, dtype: int64 print(data[['Three', 'Two']]) # Three Two # Ohio 2 1 # Colorado 6 5 # Utah 10 9 # New York 14 13 print(data[:2]) # One Two Three Four # Ohio 0 1 2 3 # Colorado 4 5 6 7 \u5d4c\u5957\uff1a\u6839\u636e\u4e00\u4e2a\u5e03\u5c14\u503c\u6570\u7ec4\u5207\u7247\u6216\u9009\u62e9\u6570\u636e\u3002 data['Three'] > 5 \u662f\u4e00\u4e2a\u5e03\u5c14\u503c\u5e8f\u5217\u3002 data[data['Three'] > 5] \u8f93\u51fa\u6761\u4ef6\u4e3aTrue\u7684\u7ed3\u679c\u96c6\u3002 print(data['Three'] > 5) # Ohio False # Colorado True # Utah True # New York True # Name: Three, dtype: bool print(data[data['Three'] > 5]) # One Two Three Four # Colorado 4 5 6 7 # Utah 8 9 10 11 # New York 12 13 14 15 \u4f7f\u7528\u5e03\u5c14\u503cDataFrame\u8fdb\u884c\u7d22\u5f15\uff0c\u5df2\u7ecf\u66f4\u65b0\u3002 \u5728\u4e0b\u9762\u8fd9\u4e2a\u4f8b\u5b50\u4e2d\uff0c\u8fd9\u79cd\u7d22\u5f15\u65b9\u5f0f\u4f7f\u5f97DataFrame\u5728\u8bed\u6cd5\u4e0a\u66f4\u50cf\u662fNumPy\u4e8c\u7ef4\u6570\u7ec4\u3002 print(data < 5) # One Two Three Four # Ohio True True True True # Colorado True False False False # Utah False False False False # New York False False False False data[data < 5] = 0 print(data) # One Two Three Four # Ohio 0 0 0 0 # Colorado 0 5 6 7 # Utah 8 9 10 11 # New York 12 13 14 15 \u4f7f\u7528loc\u548ciloc\u9009\u62e9\u6570\u636e\u3002 \u4f7f\u7528\u6807\u7b7e\u540d loc \u6216\u6807\u7b7e\u4f4d\u7f6e iloc \u4ee5NumPy\u98ce\u683c\u7684\u8bed\u6cd5\u4eceDataFrame\u4e2d\u9009\u51faDataframe\u7684\u884c\u548c\u5217\u7684\u5b50\u96c6\u3002 data = pd.DataFrame( np.arange(16).reshape(4, 4), index=['Ohio', 'Colorado', 'Utah', 'New York'], columns=['One', 'Two', 'Three', 'Four'] ) print(data) # One Two Three Four # Ohio 0 1 2 3 # Colorado 4 5 6 7 # Utah 8 9 10 11 # New York 12 13 14 15 \u4e0b\u4f8b\u901a\u8fc7loc\u5bf9\u6807\u7b7e\u540d\u7b5b\u9009\u884c\u6216\u5217\u6570\u636e\u3002\u4f8b\u5982\uff0c\u8f93\u51fa Colorado \u884c\u6807\u7b7e\u7684 Two \u548c Three \u8fd9\u4e24\u5217\u7684\u503c\uff0c\u4ee5\u884c\u8bb0\u5f55\u7684\u65b9\u5f0f\u5c55\u73b0\u3002 print(data.loc['Colorado', ['Two', 'Three']]) # \u5207\u7247: # Two 5 # Three 6 # Name: Colorado, dtype: int64 print(data.loc[:'Ohio', :'Two']) # \u5207\u7247: 0\u884c\uff0c0,1\u5217 # One Two # Ohio 0 1 \u4e0b\u4f8b\u901a\u8fc7\u6807\u7b7e\u4f4d\u7f6e iloc \u8fdb\u884c\u7c7b\u4f3c\u7684\u6570\u636e\u9009\u62e9\u3002 data.iloc[:3, :2][data > 4] \u6309\u6307\u5b9a\u6761\u4ef6\u8fdb\u884c\u884c\u3001\u5217\u7b5b\u9009\uff0c\u7b26\u5408\u6761\u4ef6 [data > 4] \u7684\u8f93\u51faDataframe\u503c\uff0c\u4e0d\u7b26\u5408\u6761\u4ef6\u7684\u8f93\u51faNaN\u3002 print(data.iloc[[0]]) # 0\u884c # One Two Three Four # Ohio 0 1 2 3 print(data.iloc[[0], [1]]) # \u5207\u7247: 0\u884c\uff0c1\u5217 # Two # Ohio 1 print(data.iloc[1:2, 1:2]) # \u5207\u7247: 1\u884c\uff0c2\u5217 # Two # Ohio 1 print(data.iloc[2, [3, 0, 1]]) # \u5207\u7247: 2\u884c\uff0c\u4f9d\u6b21\u53d63\uff0c0\uff0c1\u5217 # Four 11 # One 8 # Two 9 # Name: Utah, dtype: int64 print(data.iloc[:3, :2][data > 4]) # One Two # Ohio NaN NaN # Colorado NaN 5.0 # Utah 8.0 9.0 \u6574\u6570\u7d22\u5f15 \u00b6 Pandas\u7684Series\u7684\u7d22\u5f15\u503c\u662f\u6574\u6570\u7d22\u5f15\u3002 data = np.arange(3.) ser = pd.Series(data) print(ser) # 0 0.0 # 1 1.0 # 2 2.0 # dtype: float64 print(ser[:1]) # 0 0.0 # dtype: float64 print(ser.loc[:1]) # loc\u7528\u4e8e\u6807\u7b7e\u540d # 0 0.0 # 1 1.0 # dtype: float64 print(ser.iloc[:1]) # iloc\u7528\u4e8e\u6807\u7b7e\u4f4d\u7f6e # 0 0.0 # dtype: float64 data = ['1', 'b', 'e', 3] ser = pd.Series(data) print(ser) # 0 1 # 1 b # 2 e # 3 3 # dtype: object print(ser[:1]) # 0 1 # dtype: object print(ser.loc[:1]) # 0 1 # 1 b # dtype: object print(ser.iloc[:1]) # 0 1 # dtype: object \u5bf9DataFrame\u7684\u66f4\u65b0\u3002 df1 = pd.DataFrame(np.arange(4).reshape((2, 2)), columns=list('ab')) print(df1) # a b # 0 0 1 # 1 2 3 # \u6309\u6807\u7b7e\u540d\u66f4\u65b0 df1.loc[1, :'b'] = np.nan print(df1) # a b # 0 0.0 1.0 # 1 NaN NaN \u7b97\u672f\u548c\u6570\u636e\u5bf9\u9f50 \u00b6 Pandas\u652f\u6301\u5728Series\u6216\u8005DataFrame\u5bf9\u8c61\u4e4b\u95f4\u8fdb\u884c\u7b97\u672f\u8fd0\u7b97\u3002 \u4f8b\uff1a\u4e24\u4e2aSeries\u505a\u7b97\u672f\u52a0\u6cd5\u3002 \u8fd4\u56de\u7684\u7ed3\u679c\u4e5f\u662f\u4e00\u4e2aSeries\u3002 \u8fd4\u56de\u7ed3\u679c\u7684\u7d22\u5f15\u662f\u6bcf\u4e2aSeries\u7684\u7d22\u5f15\u7684\u5e76\u96c6\u3002 \u51e1\u662f\u6ca1\u6709\u5728\u4e24\u4e2aSeries\u90fd\u51fa\u73b0\u7684\u7d22\u5f15\u4f4d\u7f6e\uff0c\u5185\u90e8\u6570\u636e\u5bf9\u9f50\u4f1a\u586b\u5145\u7f3a\u5931\u503cNaN\u3002\u7f3a\u5931\u503c\u4f1a\u5728\u540e\u7eed\u7684\u5176\u5b83\u7b97\u672f\u64cd\u4f5c\u4e0a\u4ea7\u751f\u5f71\u54cd\u3002 \u540c\u65f6\u51fa\u73b0\u5728\u4e24\u4e2aSeries\u7684\u7d22\u5f15\u4f4d\u7f6e\uff0cSeries\u7684\u503c\u505a\u7b97\u672f\u76f8\u52a0\u3002 s1 = pd.Series( [7.3, -2.5, 3.4, 1.5], index=['a', 'c', 'd', 'e'] ) s2 = pd.Series( [-2.1, 3.6, -1.5, 4, 3.1], index=['a', 'c', 'e', 'f', 'g'] ) print(s1) # a 7.3 # c -2.5 # d 3.4 # e 1.5 # dtype: float64 print(s2) # a -2.1 # c 3.6 # e -1.5 # f 4.0 # g 3.1 # dtype: float64 print(s1 + s2) # a 5.2 # c 1.1 # d NaN # e 0.0 # f NaN # g NaN # dtype: float64 \u4f8b\uff1a\u4e24\u4e2aDataframe\u505a\u7b97\u672f\u52a0\u6cd5 \u8fd4\u56de\u7ed3\u679c\u4e5f\u662f\u4e00\u4e2aDataframe\u3002 \u8fd4\u56de\u7ed3\u679c\u7684\u884c\u5217\u7d22\u5f15\u662f\u6bcf\u4e2aDataFrame\u7684\u884c\u5217\u7d22\u5f15\u7684\u5e76\u96c6\u3002 \u51e1\u662f\u6ca1\u6709\u5728\u4e24\u4e2aDataFrame\u90fd\u51fa\u73b0\u7684\u4f4d\u7f6e\u5c31\u4f1a\u88ab\u7f6e\u4e3aNaN\u3002 \u4e24\u4e2aDataFrame\u90fd\u51fa\u73b0\u7684\u4f4d\u7f6e\uff0c\u5bf9Dataframe\u7684\u503c\u505a\u7b97\u672f\u52a0\u6cd5\u3002 df1 = pd.DataFrame( np.arange(9).reshape((3, 3)), columns=list('bcd'), index=['Ohio', 'Texas', 'Colorado'] ) df2 = pd.DataFrame( np.arange(12).reshape((4, 3)), columns=list('bde'), index=['Utah', 'Ohio', 'Texas', 'Oregon'] ) print(df1) # b c d # Ohio 0 1 2 # Texas 3 4 5 # Colorado 6 7 8 print(df2) # b d e # Utah 0 1 2 # Ohio 3 4 5 # Texas 6 7 8 # Oregon 9 10 11 print(df1 + df2) # b c d e # Colorado NaN NaN NaN NaN # Ohio 3.0 NaN 6.0 NaN # Oregon NaN NaN NaN NaN # Texas 9.0 NaN 12.0 NaN # Utah NaN NaN NaN NaN \u5728Series\u6216\u8005DataFrame\u5bf9\u8c61\u4e4b\u95f4\u8fdb\u884c\u7b97\u672f\u64cd\u4f5c\u65f6\uff0c\u6709\u65f6\u9700\u8981\u5bf9\u7f3a\u5931\u503c\u6307\u5b9a\u586b\u5145\u503c\uff0c\u6bd4\u5982\u5f53\u8f74\u6807\u7b7e\u5728\u4e00\u4e2a\u5bf9\u8c61\u4e2d\u5b58\u5728\uff0c\u5728\u53e6\u4e00\u4e2a\u5bf9\u8c61\u4e2d\u4e0d\u5b58\u5728\u65f6\uff0c\u5c06\u7f3a\u5931\u503c\u586b\u5145\u4e3a0\u3002\u4e5f\u5c31\u662f\u8bf4\uff0c\u5982\u679c\u5728\u4e24\u4e2aDataFrame\u90fd\u7f3a\u5931\uff0c\u90a3\u4e48\u4f9d\u7136\u8fd8\u4f1a\u662fNaN\u3002 \u4e0b\u4f8b\u4e2da2\u662f\u5728 df1 \u548c df2 \u90fd\u7f3a\u5931\u7684\u4f4d\u7f6e\uff0c\u6240\u4ee5\u5373\u4f7f fill_value=0 \uff0ca2\u4ecd\u7136\u662fNaN\u3002 df1 = pd.DataFrame( np.arange(4).reshape((2, 2)), columns=list('ab') ) df2 = pd.DataFrame( np.arange(9).reshape((3, 3)), columns=list('bcd') ) print(df1) # a b # 0 0 1 # 1 2 3 print(df2) # b c d # 0 0 1 2 # 1 3 4 5 # 2 6 7 8 # \u5bf9df1\u548cdf2\u5c31\u7b97\u672f\u548c\uff0c\u5bf9\u5e94\u6ca1\u6709\u884c\u5217\u5171\u540c\u7684\u4ea4\u96c6\u7684\u5730\u65b9\u586b\u5145\u7a7a\u503cNaN\uff0c\u6709\u4ea4\u96c6\u7684\u5730\u65b9\u6c42\u7b97\u672f\u548c\u3002 print(df1.add(df2)) # a b c d # 0 NaN 1.0 NaN NaN # 1 NaN 6.0 NaN NaN # 2 NaN NaN NaN NaN # \u5bf9df1\u548cdf2\u5c31\u7b97\u672f\u548c\uff0c\u5bf9\u5e94\u6ca1\u6709\u884c\u5217\u5171\u540c\u7684\u4ea4\u96c6\u7684\u5730\u65b9\u586b\u5145\u7a7a\u503c0\uff0c\u6709\u4ea4\u96c6\u7684\u5730\u65b9\u6c42\u7b97\u672f\u548c\u3002 print(df1.add(df2, fill_value=0)) # df2.add(df1, fill_value=0) \u8fd4\u56de\u540c\u6837\u7684\u7ed3\u679c # a b c d # 0 0.0 1.0 1.0 2.0 # 1 2.0 6.0 4.0 5.0 # 2 NaN 6.0 7.0 8.0 \u4e0b\u4f8b\u4e2db2\u662f\u5728 df1 \u548c df2 \u90fd\u7f3a\u5931\u7684\u4f4d\u7f6e\uff0c\u6240\u4ee5\u5373\u4f7f fill_value=0 \uff0cb2\u4ecd\u7136\u662fNaN\u3002 df1 = pd.DataFrame( np.arange(4).reshape((2, 2)), columns=list('ab') ) df2 = pd.DataFrame( np.arange(9).reshape((3, 3)), columns=list('acd') ) print(df1) # a b # 0 0 1 # 1 2 3 print(df2) # a c d # 0 0 1 2 # 1 3 4 5 # 2 6 7 8 print(df1.add(df2, fill_value=0)) # a b c d # 0 0.0 1.0 1.0 2.0 # 1 5.0 3.0 4.0 5.0 # 2 6.0 NaN 7.0 8.0 \u4e0b\u4f8b\u4e2d\u6ca1\u6709\u4e24\u4e2aDataFrame\u5171\u540c\u7f3a\u5931\u7684\u60c5\u51b5\u3002 df1 = pd.DataFrame( np.arange(4).reshape((2, 2)), columns=list('ab') ) df2 = pd.DataFrame( np.arange(9).reshape((3, 3)), columns=list('abd') ) print(df1) # a b # 0 0 1 # 1 2 3 print(df2) # a b d # 0 0 1 2 # 1 3 4 5 # 2 6 7 8 print(df1.add(df2, fill_value=0)) # a b d # 0 0.0 2.0 2.0 # 1 5.0 7.0 5.0 # 2 6.0 7.0 8.0 \u4e0b\u9762\u662fSeries\u548cDataFrame\u7684\u7b97\u672f\u65b9\u6cd5\u3002 add\uff0cradd\uff1a\u52a0\u6cd5(+) sub\uff0crsub\uff1a\u51cf\u6cd5(-) div\uff0crdiv\uff1a\u9664\u6cd5(/) floordiv\uff0crfloordiv\uff1a\u6574\u9664(//) mul\uff0crmul\uff1a\u4e58\u6cd5(*) pow\uff0crpow\uff1a\u5e42\u6b21\u65b9(**) \u4e0a\u8ff0\u6bcf\u4e2a\u65b9\u6cd5\u90fd\u6709\u4e00\u4e2a\u4ee5r\u5f00\u5934\u7684\u526f\u672c\uff0c\u8fd9\u4e9b\u526f\u672c\u65b9\u6cd5\u7684\u53c2\u6570\u662f\u7ffb\u8f6c\u7684\u3002\u6bd4\u5982\uff0c\u6c42DataFrame\u5f53\u4e2d\u6240\u6709\u5143\u7d20\u7684\u5012\u6570 1/df \uff0c\u53ef\u4ee5\u5199\u6210df.rdiv(1)\u3002 df1 = pd.DataFrame( np.arange(4).reshape((2, 2)), columns=list('ab') ) df2 = pd.DataFrame( np.arange(9).reshape((3, 3)), columns=list('abd') ) print(df1) # a b # 0 0 1 # 1 2 3 print(df2) # a b d # 0 0 1 2 # 1 3 4 5 # 2 6 7 8 print(df1.radd(df2, fill_value=0)) # a b d # 0 0.0 2.0 2.0 # 1 5.0 7.0 5.0 # 2 6.0 7.0 8.0 print(df1.sub(df2, fill_value=0)) # a b d # 0 0.0 0.0 -2.0 # 1 -1.0 -1.0 -5.0 # 2 -6.0 -7.0 -8.0 print(df1.div(df2, fill_value=0)) # a b d # 0 NaN 1.00 0.0 # 1 0.666667 0.75 0.0 # 2 0.000000 0.00 0.0 print(df1.floordiv(df2, fill_value=0)) # a b d # 0 NaN 1.0 0.0 # 1 0.0 0.0 0.0 # 2 0.0 0.0 0.0 print(df1.mul(df2, fill_value=0)) # a b d # 0 0.0 1.0 0.0 # 1 6.0 12.0 0.0 # 2 0.0 0.0 0.0 print(df1.pow(df2, fill_value=0)) # a b d # 0 1.0 1.0 0.0 # 1 8.0 81.0 0.0 # 2 0.0 0.0 0.0 DataFrame\u548cSeries\u95f4\u7684\u7b97\u672f\u64cd\u4f5c \u00b6 DataFrame\u548cSeries\u95f4\u7684\u7b97\u672f\u64cd\u4f5c\u4e0eNumPy\u4e2d\u4e0d\u540c\u7ef4\u5ea6\u6570\u7ec4\u95f4\u7684\u64cd\u4f5c\u7c7b\u4f3c\u3002 \u4e0d\u540c\u7ef4\u5ea6NumPy\u6570\u7ec4\u95f4\u7684\u7b97\u672f\u64cd\u4f5c \u00b6 \u4ecearr\u4e2d\u51cf\u53bbarr[0]\u65f6\uff0c\u51cf\u6cd5\u6cbf0\u8f74\u5728\u6bcf\u4e00\u884c\u90fd\u8fdb\u884c\u4e86\u64cd\u4f5c\u3002\u8fd9\u5c31\u662f\u6240\u8c13\u7684\u5e7f\u64ad\u673a\u5236\u3002 arr = np.arange(12).reshape((3, 4)) print(arr) # [[ 0 1 2 3] # [ 4 5 6 7] # [ 8 9 10 11]] print(arr[0]) # [0 1 2 3] print(arr - arr[0]) # [[0 0 0 0] # [4 4 4 4] # [8 8 8 8]] DataFrame\u548cSeries\u95f4\u7684\u7b97\u672f\u64cd\u4f5c \u00b6 \u9ed8\u8ba4\u60c5\u51b5\u4e0b\uff0cDataFrame\u548cSeries\u7684\u6570\u5b66\u64cd\u4f5c\u4e2d\u4f1a\u5c06Series\u7684\u7d22\u5f15\u548cDataFrame\u7684*\u5217*\u8fdb\u884c\u5339\u914d\uff0c\u5e76*\u5e7f\u64ad\u5230\u5404\u884c*. \u5982\u679c\u4e00\u4e2a\u7d22\u5f15\u503c\u4e0d\u5728DataFrame\u7684\u5217\u4e2d\uff0c\u4e5f\u4e0d\u5728Series\u7684\u7d22\u5f15\u4e2d\uff0c\u5219\u65b0\u5bf9\u8c61\u4f1a\u6784\u5efa\u5e76\u96c6\u7d22\u5f15\u3002 frame = pd.DataFrame( np.arange(12).reshape((4, 3)), columns=list('bde'), index=['Utah', 'Ohio', 'Texas', 'Oregon'] ) print(frame) # b d e # Utah 0 1 2 # Ohio 3 4 5 # Texas 6 7 8 # Oregon 9 10 11 # \u622a\u53d6frame\u7684\u7b2c0\u884c\uff0c\u5217\u6807\u7b7e\u53d8\u6210\u65b0Serise\u7684\u7d22\u5f15\u3002 series = frame.iloc[0] print(series) # b 0 # d 1 # e 2 # Name: Utah, dtype: int64 series2 = pd.Series( range(3), index=list('bef') ) print(series2) # b 0 # e 1 # f 2 # dtype: int64 # \u622a\u53d6frame\u7684d\u5217\uff0c\u884c\u6807\u7b7e\u53d8\u6210\u65b0Serise\u7684\u7d22\u5f15\u3002 series3 = frame['d'] print(series3) # Utah 1 # Ohio 4 # Texas 7 # Oregon 10 # Name: d, dtype: int64 # \u5c06Series\u7684\u7d22\u5f15\u548cDataFrame\u7684\u5217\u6807\u7b7e\u8fdb\u884c\u5339\u914d\uff0cSeries\u7684\u503c\u6cbfDataFrame\u76840\u8f74\u5e7f\u64ad\u5230\u5404\u4e2a\u884c\u3002 print(frame - series) # frame: series Result: # b d e # b 0 # b d e # Utah 0 1 2 # d 1 # Utah 0 0 0 # Ohio 3 4 5 # e 2 # Ohio 3 3 3 # Texas 6 7 8 # Name: Utah, dtype: int64 # Texas 6 6 6 # Oregon 9 10 11 # Oregon 9 9 9 # \u5c06Series\u7684\u7d22\u5f15\u548cDataFrame\u7684\u5217\u6807\u7b7e\u8fdb\u884c\u5339\u914d\uff0cSeries\u7684\u503c\u6cbfDataFrame\u76840\u8f74\u5e7f\u64ad\u5230\u5404\u4e2a\u884c\uff0c\u7f3a\u5931\u4f4d\u7f6e\u586b\u5145\u7a7a\u503cNaN\u3002 print(frame - series2) # frame: series2 Result: # b d e # b 0 # b d e f # Utah 0 1 2 # e 1 # Utah 0.0 NaN 1.0 NaN # Ohio 3 4 5 # f 2 # Ohio 3.0 NaN 4.0 NaN # Texas 6 7 8 # dtype: int64 # Texas 6.0 NaN 7.0 NaN # Oregon 9 10 11 # Oregon 9.0 NaN 10.0 NaN # \u6539\u4e3a\u5728\u5217\u4e0a\u8fdb\u884c\u5e7f\u64ad\uff0c\u5728\u884c\u4e0a\u5339\u914d\uff0c\u5fc5\u987b\u4f5c\u7528\u5728\u67d0\u79cd\u7b97\u672f\u65b9\u6cd5\u4e0a\u3002\u4e0b\u4f8b\u4e2dSeries\u7684\u503c\u6cbfDataFrame\u76840\u8f74\u5e7f\u64ad\u5230\u5404\u4e2a\u884c\uff08\u6309index\u5339\u914d\u8fdb\u884c\u884c\u64cd\u4f5c\uff09\u3002 print(frame.sub(series3, axis='index')) # \u6216axis=0 # frame: series3 Result: # b d e # Utah 1 # b d e # Utah 0 1 2 # Ohio 4 # Utah -1 0 1 # Ohio 3 4 5 # Texas 7 # Ohio -1 0 1 # Texas 6 7 8 # Oregon 10 # Texas -1 0 1 # Oregon 9 10 11 # Name: d, dtype: int64 # Oregon -1 0 1 \u51fd\u6570\u5e94\u7528\u548c\u6620\u5c04 \u00b6 NumPy\u7684\u901a\u7528\u51fd\u6570\uff08\u9010\u5143\u7d20\u6570\u7ec4\u65b9\u6cd5\uff09\u5bf9pandas\u5bf9\u8c61\uff08DataFrame\u548cSeries\uff09\u4e5f\u6709\u6548\u3002 frame = pd.DataFrame( np.random.randn(4, 3), columns=list('bde'), index=['Utah', 'Ohio', 'Texas', 'Oregon'] ) print(frame) # b d e # Utah 2.737734 -0.379977 0.758933 # Ohio 0.847497 0.839583 -2.192021 # Texas -0.907544 -0.457436 -1.907396 # Oregon 0.389362 0.250170 1.065889 # \u5bf9DataFrame\u5bf9\u8c61\u8ba1\u7b97\u7edd\u5bf9\u503c\u3002 print(np.abs(frame)) # b d e # Utah 2.737734 0.379977 0.758933 # Ohio 0.847497 0.839583 2.192021 # Texas 0.907544 0.457436 1.907396 # Oregon 0.389362 0.250170 1.065889 # f\u8fd4\u56de\u4e00\u4e2a\u6807\u91cf\u503c f = lambda x: x.max() - x.min() # \u6cbf0\u8f74\u5e94\u7528f\uff08\u5bf9\u6bcf\u5217\u7684\u6240\u6709\u884c\u5143\u7d20\u8fdb\u884cf\u8ba1\u7b97\uff09, \u9ed8\u8ba4axis=0 print(frame.apply(f)) # b 3.645278 # d 1.297019 # e 3.257911 # dtype: float64 # \u6cbf1\u8f74\u5e94\u7528f\uff08\u5bf9\u6bcf\u884c\u7684\u6240\u6709\u5217\u5143\u7d20\u8fdb\u884cf\u8ba1\u7b97\uff09 print(frame.apply(f, axis=1)) # Utah 3.117711 # Ohio 3.039518 # Texas 1.449961 # Oregon 0.815720 # dtype: float64 # \u5b9a\u4e49\u51fd\u6570f\uff0c\u8fd4\u56de\u5e26\u6709\u591a\u4e2a\u503c\u7684Series\u3002 def f(x): return pd.Series( [x.min(), x.max()], index=['min', 'max'] ) print(frame.apply(f)) # b d e # min -0.907544 -0.457436 -2.192021 # max 2.737734 0.839583 1.065889 # \u5b9a\u4e49\u51fd\u6570f\uff0c\u4f7f\u7528applymap\u65b9\u6cd5\u683c\u5f0f\u5316\u5b57\u7b26\uff0c\u5c06\u4e00\u4e2a\u9010\u5143\u7d20\u7684\u51fd\u6570\u5e94\u7528\u5230Series\u4e0a\u3002 f = lambda x: '%.2f' % x print(frame.applymap(f)) # # b d e # Utah 2.74 -0.38 0.76 # Ohio 0.85 0.84 -2.19 # Texas -0.91 -0.46 -1.91 # Oregon 0.39 0.25 1.07 print(frame['e'].map(f)) # Utah 0.76 # Ohio -2.19 # Texas -1.91 # Oregon 1.07 # Name: e, dtype: object \u6392\u5e8f\u548c\u6392\u540d \u00b6 \u4f7f\u7528sort_index\u65b9\u6cd5\uff0c\u6309\u884c\u6216\u5217\u7d22\u5f15\u8fdb\u884c\u5b57\u5178\u578b\u6392\u5e8f\uff0c\u8fd4\u56de\u4e00\u4e2a\u65b0\u7684\u6392\u5e8f\u597d\u7684Pandas\u5bf9\u8c61\u3002 Series\u6392\u5e8f \u00b6 \u5bf9Series\u8fdb\u884c\u7d22\u5f15\u6392\u5e8f\u548c\u503c\u6392\u5e8f\u3002 obj = pd.Series( range(4), index=list('dabc') ) print(obj) # d 0 # a 1 # b 2 # c 3 # dtype: int64 print(obj.sort_index()) # a 1 # b 2 # c 3 # d 0 # dtype: int64 # print(obj.sort_values()) # d 0 # a 1 # b 2 # c 3 # dtype: int64 \u9ed8\u8ba4\u60c5\u51b5\u4e0b\uff0c\u6240\u6709\u7684\u7f3a\u5931\u503c\u90fd\u4f1a\u88ab\u6392\u5e8f\u81f3Series\u7684\u5c3e\u90e8\u3002 obj = pd.Series([4, np.nan, 7, np.nan, -3, 2]) print(obj) # 0 4.0 # 1 NaN # 2 7.0 # 3 NaN # 4 -3.0 # 5 2.0 # dtype: float64 print(obj.sort_values()) # 4 -3.0 # 5 2.0 # 0 4.0 # 2 7.0 # 1 NaN # 3 NaN # dtype: float64 DataFrame\u6392\u5e8f \u00b6 frame = pd.DataFrame( [[0, 1, 10, 3], [4, 5, 6, 21], [8, 9, 2, 21]], index=['three', 'one', 'five'], columns=list('dabc') ) print(frame) # d a b c # three 0 1 10 3 # one 4 5 6 21 # five 8 9 2 21 print(frame.index) # Index(['three', 'one', 'five'], dtype='object') # \u9ed8\u8ba40\u8f74\uff0c\u6240\u6709\u884c\u8fdb\u884c\u7d22\u5f15\u9996\u5b57\u6bcd\u5347\u5e8f print(frame.sort_index()) # d a b c # five 8 9 2 21 # one 4 5 6 21 # three 0 1 10 3 # \u6307\u5b9a0\u8f74\uff0c\u6240\u6709\u884c\u8fdb\u884c\u7d22\u5f15\u9996\u5b57\u6bcd\u5347\u5e8f print(frame.sort_index(axis=0)) # d a b c # five 8 9 2 21 # one 4 5 6 21 # three 0 1 10 3 # \u6307\u5b9a0\u8f74\uff0c\u6240\u6709\u884c\u8fdb\u884c\u7d22\u5f15\u9996\u5b57\u6bcd\u964d\u5e8f print(frame.sort_index(axis=0, ascending=False)) # d a b c # three 0 1 10 3 # one 4 5 6 21 # five 8 9 2 21 # \u6307\u5b9a1\u8f74\uff0c\u6240\u6709\u5217\u8fdb\u5217\u7d22\u5f15\u9996\u5b57\u6bcd\u5347\u5e8f print(frame.sort_index(axis=1)) # a b c d # three 1 10 3 0 # one 5 6 21 4 # five 9 2 21 8 # \u6307\u5b9a1\u8f74\uff0c\u6240\u6709\u5217\u8fdb\u5217\u7d22\u5f15\u9996\u5b57\u6bcd\u964d\u5e8f print(frame.sort_index(axis=1, ascending=False)) # d c b a # three 0 3 10 1 # one 4 21 6 5 # five 8 21 2 9 # \u6309\u6307\u5b9a\u5355\u5217\u8fdb\u884c\u503c\u6392\u5e8f\uff08\u964d\u5e8f\uff09 print(frame.sort_values(by=['c'], ascending=False)) # d a b c # one 4 5 6 21 # five 8 9 2 21 # three 0 1 10 3 # \u6309\u6307\u5b9a\u591a\u5217\u8fdb\u884c\u503c\u6392\u5e8f\uff08\u964d\u5e8f\uff09\uff0c\u5148\u5bf9b\u964d\u5e8f\uff0c\u518d\u5bf9d\u964d\u5e8f print(frame.sort_values(by=['c', 'd'], ascending=False)) # d a b c # five 8 9 2 21 # one 4 5 6 21 # three 0 1 10 3 \u6392\u540d \u00b6 **\u6392\u540d**\u662f\u6307\u5bf9\u6570\u7ec4\u4ece1\u5230\u6709\u6548\u6570\u636e\u70b9\u603b\u6570\u5206\u914d\u540d\u6b21\u7684\u64cd\u4f5c\u3002 Series\u548cDataFrame\u7684 rank \u65b9\u6cd5\u662f\u5b9e\u73b0\u6392\u540d\u7684\u65b9\u6cd5\uff0c df.rank(ascending=False, method='max') \u3002 ascending \uff1a\u6392\u540d\u65b9\u5f0f\uff0c\u9ed8\u8ba4\u4ece\u4f4e\u5230\u9ad8\uff0c ascending=False \u8868\u793a\u4ece\u9ad8\u5230\u4f4e\uff1b method \uff1a\u6392\u540d\u65b9\u5f0f\uff0c\u5305\u62ec\uff1a average:\u9ed8\u8ba4\uff0c\u5728\u76f8\u7b49\u5206\u7ec4\u4e2d\uff0c\u4e3a\u5404\u4e2a\u503c\u5206\u914d\u5e73\u5747\u6392\u540d\uff0c\u5373\u76f8\u540c\u503c\u7684\u548c\u9664\u4ee5\u8be5\u503c\u7684\u4e2a\u6570\uff0c\u5373\u4e3a\u8be5\u503c\u7684\u540d\u6b21\u3002 min:\u4f7f\u7528\u6574\u4e2a\u5206\u7ec4\u7684\u6700\u5c0f\u6392\u540d\uff0c\u5373\uff0c\u5bf9\u5e94\u76f8\u540c\u503c\uff0c\u53d6\u5728\u987a\u5e8f\u6392\u540d\u4e2d\u6700\u5c0f\u7684\u90a3\u4e2a\u6392\u540d\u4f5c\u4e3a\u6240\u6709\u8be5\u503c\u7684\u6392\u540d\u3002 max:\u4f7f\u7528\u6574\u4e2a\u5206\u7ec4\u7684\u6700\u5927\u6392\u540d\uff0c\u5373\uff0c\u5bf9\u5e94\u76f8\u540c\u503c\uff0c\u53d6\u5728\u987a\u5e8f\u6392\u540d\u4e2d\u6700\u5927\u7684\u90a3\u4e2a\u6392\u540d\u4f5c\u4e3a\u6240\u6709\u8be5\u503c\u7684\u6392\u540d\u3002 first:\u6309\u503c\u518d\u539f\u59cb\u6570\u636e\u4e2d\u51fa\u73b0\u987a\u5e8f\u5206\u914d\u6392\u540d\uff0c\u8c01\u51fa\u73b0\u7684\u4f4d\u7f6e\u9760\u524d\uff0c\u8c01\u7684\u6392\u540d\u9760\u524d\u3002 dense:\u7c7b\u4f3cmin\u65b9\u6cd5\uff0c\u4f46\u6392\u540d\u603b\u662f\u5728\u7ec4\u95f4\u589e\u52a01\uff0c\u800c\u4e0d\u662f\u7ec4\u4e2d\u76f8\u540c\u7684\u5143\u7d20\u6570\uff0c\u5373\u76f8\u540c\u503c\u7684\u6392\u540d\u76f8\u540c\uff0c\u5176\u4ed6\u4f9d\u6b21\u52a01\u5373\u53ef\u3002 \u9ed8\u8ba4\u60c5\u51b5\u4e0b\uff0crank\u662f\u901a\u8fc7\u201c\u4e3a\u5404\u7ec4\u5206\u914d\u4e00\u4e2a\u5e73\u5747\u6392\u540d\u201d\u7684\u65b9\u5f0f\u7834\u574f\u5e73\u7ea7\u5173\u7cfb # \u6309\u7167\u6bcf\u4e2a\u5143\u7d20\u7684\u5927\u5c0f\u987a\u5e8f\u7ed9\u51fa\u4e00\u4e2a\u5e73\u5747\u6392\u540d obj = pd.Series([7, -5, 7, 4, 2, 0, 4]) print(obj) # 0 7 # 1 -5 # 2 7 # 3 4 # 4 2 # 5 0 # 6 4 # dtype: int64 print(obj.rank()) # 0 6.5 # 1 1.0 # 2 6.5 # 3 4.5 # 4 3.0 # 5 2.0 # 6 4.5 # dtype: float64 # index value rank # 2 -5 1 # 6 0 2 # 5 2 3 # 4 4 4.5 # 7 4 4.5 # 1 7 6.5 # 3 7 6.5 # \u6839\u636e\u5143\u7d20\u7684\u89c2\u5bdf\u987a\u5e8f\u8fdb\u884c\u5206\u914d\u3002\u5143\u7d200\u548c2\u6ca1\u6709\u4f7f\u7528\u5e73\u5747\u6392\u540d6.5\uff0c\u5b83\u4eec\u88ab\u8bbe\u6210\u4e866\u548c7\uff0c\u56e0\u4e3a\u6570\u636e\u4e2d\u6807\u7b7e0\u4f4d\u4e8e\u6807\u7b7e2\u7684\u524d\u9762\u3002 print(obj.rank(method='first')) # 0 6.0 # 1 1.0 # 2 7.0 # 3 4.0 # 4 3.0 # 5 2.0 # 6 5.0 # dtype: float64 # \u6309\u7167max\u8fdb\u884c\u5347\u5e8f\u548c\u964d\u5e8f print(obj.rank(ascending=False, method='max')) print(obj.rank(ascending=True, method='max')) # Original Series Max with inc Max with dec # 0 7 # 0 2.0 (\u6700\u5c0f) # 0 7.0 (\u6700\u5927) # 1 -5 # 1 7.0 (\u6700\u5927) # 1 1.0 (\u6700\u5c0f) # 2 7 # 2 2.0 (\u6700\u5c0f) # 2 7.0 (\u6700\u5927) # 3 4 # 3 4.0 # 3 5.0 # 4 2 # 4 5.0 # 4 3.0 # 5 0 # 5 6.0 # 5 2.0 # 6 4 # 6 4.0 # 6 5.0 # dtype: float64 # dtype: float64 # dtype: float64 frame = pd.DataFrame( {'b': [4.3, 7, -3, 2], 'a': [0, 1, 0, 1], 'c': [-2, 5, 8, -2]} ) print(frame) # b a c # 0 4.3 0 -2 # 1 7.0 1 5 # 2 -3.0 0 8 # 3 2.0 1 -2 # \u6cbf1\u8f74\u5bf9DataFrame\u8fdb\u884crank\u64cd\u4f5c\uff0c\u5373\uff0c\u6bcf\u4e00\u884c\u5404\u5143\u7d20\u8fdb\u884crank\u3002 print(frame.rank(axis='columns')) # axis=1 # b a c # 0 3.0 2.0 1.0 # 1 3.0 1.0 2.0 # 2 1.0 2.0 3.0 # 3 3.0 2.0 1.0 \u542b\u6709\u91cd\u590d\u6807\u7b7e\u7684\u8f74\u7d22\u5f15 \u00b6 \u5c3d\u7ba1\u5f88\u591apandas\u51fd\u6570\uff08\u6bd4\u5982reindex\uff09\u9700\u8981\u6807\u7b7e\u662f\u552f\u4e00\u7684\uff0c\u4f46\u8fd9\u4e2a\u5e76\u4e0d\u662f\u5f3a\u5236\u6027\u7684\u3002 \u7d22\u5f15\u7684is_unique\u5c5e\u6027\u53ef\u4ee5\u68c0\u67e5\u6807\u7b7e\u662f\u5426\u552f\u4e00\u3002 \u5e26\u6709\u91cd\u590d\u7d22\u5f15\u7684\u60c5\u51b5\u4e0b\uff0c\u4e00\u4e2a\u7d22\u5f15\u6807\u7b7e\u4f1a\u4ee5\u5e8f\u5217\u65b9\u5f0f\u8fd4\u56de\u591a\u4e2a\u6761\u76ee\u3002\u4e0d\u91cd\u590d\u7684\u7d22\u5f15\u5219\u4f1a\u4ee5\u6807\u91cf\u503c\u7684\u5f62\u5f0f\u8fd4\u56de\u5355\u4e2a\u6761\u76ee\uff0c\u8fd9\u53ef\u80fd\u4f1a\u4f7f\u4ee3\u7801\u66f4\u590d\u6742\u3002 obj = pd.Series(range(5), index=['a', 'b', 'a', 'c', 'b']) print(obj) # a 0 # b 1 # a 2 # c 3 # b 4 # dtype: int64 print(obj.is_unique) # True print(obj.index.is_unique) # False # \u8fd4\u56de\u91cd\u590d\u7d22\u5f15\u5bf9\u5e94\u503c\u7684\u5e8f\u5217\u3002 print(obj['a']) # a 0 # a 2 # dtype: int64 df = pd.DataFrame(np.random.randn(4, 3), index=['a', 'a', 'b', 'b']) print(df) # 0 1 2 # a -0.726164 0.531540 -0.521611 # a -1.539807 -0.710880 -0.992789 # b -0.975970 -0.470725 0.121958 # b -0.301495 1.072322 -1.542296 print(df.index.is_unique) # False print(df.loc['b']) # 0 1 2 # b -0.520008 0.052574 0.638529 # b -1.928705 -1.099534 -1.605296 \u63cf\u8ff0\u6027\u7edf\u8ba1\u6982\u8ff0\u4e0e\u8ba1\u7b97 \u00b6 pandas\u5305\u542b\u4e86\u4e00\u4e9b\u5e38\u7528\u6570\u5b66\u3001\u7edf\u8ba1\u5b66\u65b9\u6cd5\u3002\u5176\u4e2d\u5927\u90e8\u5206\u5c5e\u4e8e\u5f52\u7ea6\u6216\u6c47\u603b\u7edf\u8ba1\u7684\u7c7b\u522b\uff0c\u8fd9\u4e9b\u65b9\u6cd5\u4eceDataFrame\u7684\u884c\u6216\u5217\u4e2d\u62bd\u53d6\u4e00\u4e2aSeries\u6216\u4e00\u7cfb\u5217\u503c\uff08\u5982\u603b\u548c\u6216\u5e73\u5747\u503c\uff09\u3002 \u4e0eNumPy\u6570\u7ec4\u4e2d\u7684\u7c7b\u4f3c\u65b9\u6cd5\u76f8\u6bd4\uff0cpandas\u5185\u5efa\u4e86\u5904\u7406\u7f3a\u5931\u503c\u7684\u529f\u80fd\u3002 \u5f52\u7ea6\u65b9\u6cd5: sum() \u79ef\u7d2f\u578b\u65b9\u6cd5: cumsun() \u65e2\u4e0d\u662f\u5f52\u7ea6\u578b\u65b9\u6cd5\u4e5f\u4e0d\u662f\u79ef\u7d2f\u578b\u65b9\u6cd5: describe() df = pd.DataFrame( [[1.4, np.nan], [7.1, -4.5], [np.nan, np.nan], [0.75, -1.3]], index=list('abcd'), columns=['one', 'two'] ) print(df) # one two # a 1.40 NaN # b 7.10 -4.5 # c NaN NaN # d 0.75 -1.3 # axis=0, \u8fd4\u56de\u4e00\u4e2a\u6bcf\u5217\u7b97\u672f\u548c\u7684Series print(df.sum()) # one 9.25 # two -5.80 # dtype: float64 # axis=1\u4e14skipna=True, \u8fd4\u56de\u4e00\u4e2a\u6bcf\u884c\u548c\u7684Series, \u5ffd\u7565NA\u503c, \u586b0\u3002 print(df.sum(axis=1)) # a 1.40 # b 2.60 # c 0.00 # d -0.55 # dtype: float64 # \u4e0d\u5ffd\u7565NA\u503c\uff0c\u586bNaN\u3002 print(df.sum(axis=1, skipna=False)) # a NaN # b 2.60 # c NaN # d -0.55 # dtype: float64 # \u53ea\u67091\u7ea7\u7d22\u5f15\uff0c\u6240\u4ee5level=0\u548c\u539f\u7d22\u5f15\u6ca1\u6709\u533a\u522b\uff0cNaN\u586b\u51450\u3002 print(df.groupby(level=0).sum()) # one two # a 1.40 0.0 # b 7.10 -4.5 # c 0.00 0.0 # d 0.75 -1.3 # \u5217one\u7684\u6700\u5927\u503c\u662f\u5728\u7d22\u5f15b, \u5217two\u7684\u6700\u5927\u503c\u662f\u5728\u7d22\u5f15d print(df.idxmax()) # one b # two d # dtype: object print(df.idxmin()) # one d # two b # dtype: object # cumsun\u7684\u610f\u601d\u662f\u7b2cn\u6b21\u7684\u548c\u662fn-1\u6b21\u7684\u548c\u4e0en\u7684\u548c\uff0cone\u5217d\u884c\u7684\u548c\u5c31\u662fone\u5217a\u3001b\u3001c\u3001d\u503c\u7684\u603b\u548c\u3002 print(df.cumsum()) # one two # a 1.40 NaN # b 8.50 -4.5 # c NaN NaN # d 9.25 -5.8 \u901a\u8fc7describe\u4ea7\u751f\u7edf\u8ba1\u4fe1\u606f\uff0c\u6ce8\u610f\uff0c\u6570\u503c\u578b\u548c\u975e\u6570\u503c\u578b\u7684describe\u7684\u4fe1\u606f\u662f\u4e0d\u540c\u7684\u3002 # \u4e00\u6b21\u6027\u4ea7\u751f\u591a\u4e2a\u6c47\u603b\u7edf\u8ba1 print(df.describe()) # one two # count 3.000000 2.000000 # mean 3.083333 -2.900000 # std 3.493685 2.262742 # min 0.750000 -4.500000 # 25% 1.075000 -3.700000 # 50% 1.400000 -2.900000 # 75% 4.250000 -2.100000 # max 7.100000 -1.300000 obj = pd.Series(['a', 'a', 'b', 'c'] * 4) print(obj) # 0 a # 1 a # 2 b # 3 c # 4 a # 5 a # 6 b # 7 c # 8 a # 9 a # 10 b # 11 c # 12 a # 13 a # 14 b # 15 c # dtype: object # \u9488\u5bf9\u975e\u6570\u503c\u578b\u6570\u636e\uff0cdescribe\u4ea7\u751f\u53e6\u4e00\u79cd\u6c47\u603b\u7edf\u8ba1 print(obj.describe()) # count 16 # unique 3 # top a # freq 8 # dtype: object \u76f8\u5173\u6027\u548c\u534f\u65b9\u5dee \u00b6 \u534f\u65b9\u5dee\u4e0e\u76f8\u5173\u7cfb\u6570\u4e5f\u662f\u5728\u65f6\u57df\u5206\u6790\u65f6\u5e38\u89c1\u7684\u4e24\u4e2a\u6982\u5ff5\uff0c\u4ed6\u4eec\u90fd\u662f\u7528\u6765\u63cf\u8ff0\u6570\u636e\u201c\u50cf\u4e0d\u50cf\u201d\u7684\u3002 \u534f\u65b9\u5dee\u7684\u901a\u4fd7\u7406\u89e3\uff1a \u4e24\u4e2a\u53d8\u91cf\u5728\u53d8\u5316\u8fc7\u7a0b\u4e2d\u662f\u540c\u65b9\u5411\u53d8\u5316\u8fd8\u662f\u53cd\u65b9\u5411\u53d8\u5316\uff1f\u76f8\u540c\u6216\u8005\u76f8\u53cd\u7a0b\u5ea6\u5982\u4f55\uff1f \u4f60\u53d8\u5927\uff0c\u540c\u65f6\u6211\u53d8\u5927\uff0c\u8bf4\u660e\u4e24\u4e2a\u53d8\u91cf\u662f\u540c\u5411\u53d8\u5316\uff0c\u8fd9\u65f6\u534f\u65b9\u5dee\u5c31\u662f\u6b63\u7684\u3002 \u4f60\u53d8\u5927\uff0c\u540c\u65f6\u6211\u53d8\u5c0f\uff0c\u8bf4\u660e\u4e24\u4e2a\u53d8\u91cf\u662f\u53cd\u5411\u53d8\u5316\uff0c\u8fd9\u65f6\u534f\u65b9\u5dee\u5c31\u662f\u8d1f\u7684\u3002 \u4ece\u6570\u503c\u770b\uff0c\u534f\u65b9\u5dee\u7684\u6570\u503c\u8d8a\u5927\uff0c\u4e24\u4e2a\u53d8\u91cf\u540c\u5411\u7a0b\u5ea6\u4e5f\u5c31\u8d8a\u5927\u3002\u53cd\u4e4b\u4ea6\u7136\u3002 \u76f8\u5173\u7cfb\u6570\u7684\u901a\u4fd7\u7406\u89e3\uff1a \u7528X\uff0cY\u7684\u534f\u65b9\u5dee\u9664\u4ee5X\u7684\u6807\u51c6\u5dee\u548cY\u7684\u6807\u51c6\u5dee\u3002\u76f8\u5173\u7cfb\u6570\u4e5f\u53ef\u4ee5\u770b\u6210\u534f\u65b9\u5dee\uff0c\u4e00\u79cd\u63d0\u51fa\u4e86\u4e24\u4e2a\u53d8\u91cf\u91cf\u7eb2\u5f71\u54cd\u3001\u6807\u51c6\u5316\u540e\u7684\u7279\u6b8a\u534f\u65b9\u5dee\u3002\u6240\u4ee5\uff1a\u4e5f\u53ef\u4ee5\u53cd\u6620\u4e24\u4e2a\u53d8\u91cf\u53d8\u5316\u65f6\u662f\u540c\u5411\u8fd8\u662f\u53cd\u5411\uff0c\u5982\u679c\u540c\u5411\u53d8\u5316\u5c31\u4e3a\u6b63\uff0c\u53cd\u5411\u53d8\u5316\u5c31\u4e3a\u8d1f\u3002 \u7531\u4e8e\u662f\u6807\u51c6\u7248\u540e\u7684\u534f\u65b9\u5dee\uff0c\u76f8\u5173\u7cfb\u6570\u6d88\u9664\u4e86\u4e24\u4e2a\u53d8\u91cf\u53d8\u5316\u5e45\u5ea6\u7684\u5f71\u54cd\uff0c\u800c\u53ea\u662f\u5355\u7eaf\u53cd\u5e94\u4e24\u4e2a\u53d8\u91cf\u6bcf\u5355\u4f4d\u53d8\u5316\u65f6\u7684\u76f8\u4f3c\u7a0b\u5ea6\u3002 \u603b\u7ed3\uff1a \u5bf9\u4e8e\u4e24\u4e2a\u53d8\u91cfX\u3001Y\uff0c \u5f53\u4ed6\u4eec\u7684\u76f8\u5173\u7cfb\u6570\u4e3a1\u65f6\uff0c\u8bf4\u660e\u4e24\u4e2a\u53d8\u91cf\u53d8\u5316\u65f6\u7684\u6b63\u5411\u76f8\u4f3c\u5ea6\u6700\u5927\u3002 \u5f53\u4ed6\u4eec\u7684\u76f8\u5173\u7cfb\u6570\u4e3a\uff0d1\u65f6\uff0c\u8bf4\u660e\u4e24\u4e2a\u53d8\u91cf\u53d8\u5316\u7684\u53cd\u5411\u76f8\u4f3c\u5ea6\u6700\u5927\u3002 \u968f\u7740\u4ed6\u4eec\u76f8\u5173\u7cfb\u6570\u51cf\u5c0f\uff0c\u4e24\u4e2a\u53d8\u91cf\u53d8\u5316\u65f6\u7684\u76f8\u4f3c\u5ea6\u4e5f\u53d8\u5c0f\uff0c\u5f53\u76f8\u5173\u7cfb\u6570\u4e3a0\u65f6\uff0c\u4e24\u4e2a\u53d8\u91cf\u7684\u53d8\u5316\u8fc7\u7a0b\u6ca1\u6709\u4efb\u4f55\u76f8\u4f3c\u5ea6\uff0c\u4e5f\u5373\u4e24\u4e2a\u53d8\u91cf\u65e0\u5173\u3002 \u5f53\u76f8\u5173\u7cfb\u6570\u7ee7\u7eed\u53d8\u5c0f\uff0c\u5c0f\u4e8e0\u65f6\uff0c\u4e24\u4e2a\u53d8\u91cf\u5f00\u59cb\u51fa\u73b0\u53cd\u5411\u7684\u76f8\u4f3c\u5ea6\uff0c\u968f\u7740\u76f8\u5173\u7cfb\u6570\u7ee7\u7eed\u53d8\u5c0f\uff0c\u53cd\u5411\u76f8\u4f3c\u5ea6\u4f1a\u9010\u6e10\u53d8\u5927\u3002 \u4e0b\u9762\u7684\u4f8b\u5b50\u4f7f\u7528 pandas-datareader\uff1a https://pypi.org/project/pandas-datareader/ https://pydata.github.io/pandas-datareader/) \u5728\u6240\u6709\u4f8b\u5b50\u4e2d\uff0c\u5728\u8ba1\u7b97\u76f8\u5173\u6027\u4e4b\u524d\uff0c\u6570\u636e\u70b9\u5df2\u7ecf\u6309\u6807\u7b7e\u8fdb\u884c\u4e86\u5bf9\u9f50\u3002 \u4e0b\u4f8b\u9700\u8981\u901a\u8fc7pandas-datareader\u5e93\u4eceYahoo! Finance\u4e0a\u83b7\u53d6\u7684\u5305\u542b\u80a1\u4ef7\u548c\u4ea4\u6613\u91cf\u7684DataFrame\u3002 import pandas_datareader.data as web all_data = { ticker: web.get_data_yahoo(ticker) for ticker in ['AAPL', 'IBM', 'MSFT', 'GOOG'] } price = pd.DataFrame( { ticker: data['Adj Close'] for ticker, data in all_data.items() } ) volume = pd.DataFrame( { ticker: data['Volume'] for ticker, data in all_data.items() } ) returns = price.pct_change() print(returns.tail()) # AAPL IBM MSFT GOOG # Date # 2021-08-09 -0.000342 -0.008424 -0.003904 0.007049 # 2021-08-10 -0.003354 0.000920 -0.006555 0.000685 # 2021-08-11 0.001786 0.005305 0.001781 -0.002947 # 2021-08-12 0.020773 0.006614 0.009967 0.005084 # 2021-08-13 0.001410 0.000769 0.010490 0.000119 Series\u7684corr\u65b9\u6cd5\u8ba1\u7b97\u7684\u662f\u4e24\u4e2aSeries\u4e2d\u91cd\u53e0\u7684\u3001\u975eNA\u7684\u3001\u6309\u7d22\u5f15\u5bf9\u9f50\u7684\u503c\u7684\u76f8\u5173\u6027\u3002\u76f8\u5e94\u5730\uff0ccov\u8ba1\u7b97\u7684\u662f\u534f\u65b9\u5dee print(returns['MSFT']) # Date # 2016-08-15 NaN # 2016-08-16 -0.005540 # 2016-08-17 0.002089 # 2016-08-18 0.000695 # 2016-08-19 0.000347 # ... # 2021-08-09 -0.003904 # 2021-08-10 -0.006555 # 2021-08-11 0.001781 # 2021-08-12 0.009967 # 2021-08-13 0.010490 # Name: MSFT, Length: 1259, dtype: float64 # Series\u7684corr\u65b9\u6cd5\u8ba1\u7b97\u7684\u662f\u4e24\u4e2aSeries\u4e2d\u91cd\u53e0\u7684\u3001\u975eNA\u7684\u3001\u6309\u7d22\u5f15\u5bf9\u9f50\u7684\u503c\u7684\u76f8\u5173\u6027\u3002 print(returns['MSFT'].corr(returns['IBM'])) # 0.5175237180581937 # \u7b49\u540c\u5199\u6cd5\uff0cMSFT\u662f\u4e00\u4e2a\u6709\u6548\u7684Python\u5c5e\u6027 print(returns.MSFT.corr(returns.IBM)) # 0.5175237180581937 # Series\u7684cov\u65b9\u6cd5\u8ba1\u7b97\u7684\u662f\u4e24\u4e2aSeries\u4e2d\u503c\u7684\u534f\u65b9\u5dee\u3002 print(returns['MSFT'].cov(returns['IBM'])) # 0.0001452224236764915 DataFrame\u7684corr\u548ccov\u65b9\u6cd5\u4f1a\u5206\u522b\u4ee5DataFrame\u7684\u5f62\u5f0f\u8fd4\u56de\u76f8\u5173\u6027\u548c\u534f\u65b9\u5dee\u77e9\u9635\u3002 print(returns.corr()) # AAPL IBM MSFT GOOG # AAPL 1.000000 0.441111 0.735539 0.661961 # IBM 0.441111 1.000000 0.517524 0.484230 # MSFT 0.735539 0.517524 1.000000 0.775756 # GOOG 0.661961 0.484230 0.775756 1.000000 # \u7ed9corrwith\u65b9\u6cd5\uff0c\u4f20\u5165\u4e00\u4e2aSeries\u65f6\uff0c\u4f1a\u8fd4\u56de\u4e00\u4e2a\u542b\u6709\u4e3a\u6bcf\u5217\u8ba1\u7b97\u76f8\u5173\u6027\u503c\u7684Series print(returns.corrwith(returns['IBM'])) # AAPL 0.441111 # IBM 1.000000 # MSFT 0.517524 # GOOG 0.484230 # dtype: float64 # \u7ed9corrwith\u65b9\u6cd5\uff0c\u4f20\u5165\u4e00\u4e2aDataFrame\u65f6\uff0c\u4f1a\u8ba1\u7b97\u5339\u914d\u5230\u5217\u540d\u7684\u76f8\u5173\u6027\u6570\u503c\u3002\u4e0b\u9762\u662f\u8ba1\u7b97\u4ea4\u6613\u91cf\u767e\u5206\u6bd4\u53d8\u5316\u7684\u76f8\u5173\u6027 print(returns.corrwith(volume)) # AAPL -0.063111 # IBM -0.103721 # MSFT -0.056842 # GOOG -0.119026 # dtype: float64 print(returns.cov()) # AAPL IBM MSFT GOOG # AAPL 0.000361 0.000137 0.000240 0.000211 # IBM 0.000137 0.000268 0.000145 0.000133 # MSFT 0.000240 0.000145 0.000294 0.000224 # GOOG 0.000211 0.000133 0.000224 0.000282 \u552f\u4e00\u503c\u3001\u8ba1\u6570\u548c\u6210\u5458\u5c5e\u6027 \u00b6 obj = pd.Series(['c', 'a', 'd', 'a', 'a', 'a', 'b', 'b', 'c', 'c']) print(obj) # 0 c # 1 a # 2 d # 3 a # 4 a # 5 a # 6 b # 7 b # 8 c # 9 c # dtype: object \u51fd\u6570 unique \u7ed9\u51faSeries\u4e2d\u7684\u552f\u4e00\u503c\u3002 print(obj.unique()) # ['c' 'a' 'd' 'b'] print(obj.sort_values().unique()) # ['a' 'b' 'c' 'd'] # value_counts\u8ba1\u7b97Series\u5305\u542b\u7684\u503c\u7684\u4e2a\u6570 print(obj.value_counts()) # a 4 # c 3 # b 2 # d 1 # dtype: int64 # \u8fd9\u91ccvalue_counts\u4e0d\u662fSeries\u7684\u65b9\u6cd5\uff0c\u662fpandas\u9876\u5c42\u65b9\u6cd5 print(pd.value_counts(obj.values, sort=True)) # a 4 # c 3 # b 2 # d 1 # dtype: int64 print(obj.isin(['b', 'c'])) # 0 True # 1 False # 2 False # 3 False # 4 False # 5 False # 6 True # 7 True # 8 True # 9 True # dtype: bool # \u5c06\u4e0a\u9762\u7684\u7ed3\u679c\u4f5c\u4e3a\u5217\u8868\u8f93\u5165\u7684\u6761\u4ef6\uff0c\u8f93\u51fa\u4e3aTrue\u7684\u7ed3\u679c print(obj[obj.isin(['b', 'c'])]) # 0 c # 6 b # 7 b # 8 c # 9 c # dtype: object \u53c2\u8003: pandas.Index.get_indexer obj1 = pd.Series(['c', 'a', 'd', 'a', 'a', 'a', 'b', 'b', 'c', 'c']) obj2 = pd.Series(['c', 'a', 'b']) print(pd.Index(obj1)) # Index(['c', 'a', 'd', 'a', 'a', 'a', 'b', 'b', 'c', 'c'], dtype='object') print(pd.Index(obj2)) # Index(['c', 'a', 'b'], dtype='object') # \u8fd9\u91cc0\u5bf9\u5e94obj2\u91cc\u9762\u7684c\u5728job1\u7684\u4f4d\u7f6e\uff0c\u4ee5\u6b64\u7c7b\u63a8\uff0c\u751f\u6210\u65b0\u7684\u7d22\u5f15\u5217\u8868 print(pd.Index(obj2).get_indexer(obj1)) # [ 0 1 -1 1 1 1 2 2 0 0] \u8ba1\u7b97DataFrame\u591a\u4e2a\u76f8\u5173\u5217\u7684\u76f4\u65b9\u56fe\u3002 data = pd.DataFrame( { 'Que1': [1, 3, 4, 3, 4], 'Que2': [2, 3, 1, 2, 3], 'Que3': [1, 5, 2, 4, 4], } ) print(data) # Que1 Que2 Que3 # 0 1 2 1 # 1 3 3 5 # 2 4 1 2 # 3 3 2 4 # 4 4 3 4 result = data.apply(pd.value_counts).fillna(0) # \u4e0b\u9762\u7ed3\u679c\u4e2d\u7684\u884c\u6807\u7b7e\u662f\u6240\u6709\u5217\u4e2d\u51fa\u73b0\u7684\u4e0d\u540c\u503c\uff0c\u6570\u503c\u5219\u662f\u8fd9\u4e9b\u4e0d\u540c\u503c\u5728\u6bcf\u4e2a\u5217\u4e2d\u51fa\u73b0\u7684\u6b21\u6570\uff0c\u4f8b\u5982\uff1a\u6570\u5b575\u53ea\u5728Que3\u91cc\u9762\u51fa\u73b0\u4e86\u4e00\u6b21 print(result) # Que1 Que2 Que3 # 1 1.0 1.0 1.0 # 2 0.0 2.0 1.0 # 3 2.0 2.0 0.0 # 4 2.0 0.0 2.0 # 5 0.0 0.0 1.0","title":"Pandas\u5165\u95e8"},{"location":"python/DataAnalysis/ch02/#pandas","text":"\u7ea6\u5b9a\uff1a import numpy as np import pandas as pd from pandas import Series, DataFrame import pandas_datareader as web","title":"Pandas\u5165\u95e8"},{"location":"python/DataAnalysis/ch02/#pandas_1","text":"","title":"pandas\u6570\u636e\u7ed3\u6784\u4ecb\u7ecd"},{"location":"python/DataAnalysis/ch02/#series","text":"Series\u662f\u4e00\u79cd\u4e00\u7ef4\u7684\u6570\u7ec4\u578b\u5bf9\u8c61\uff0c\u5b83\u5305\u542b\u4e86\u4e00\u4e2a\u503c\u5e8f\u5217\uff08\u4e0eNumPy\u4e2d\u7684\u7c7b\u578b\u76f8\u4f3c\uff09\uff0c\u5e76\u4e14\u5305\u542b\u4e86\u6570\u636e\u6807\u7b7e\uff0c\u79f0\u4e3a**\u7d22\u5f15\uff08index\uff09 \u3002 \u4ece\u53e6\u4e00\u4e2a\u89d2\u5ea6\u8003\u8651Series\uff0c\u53ef\u4ee5\u8ba4\u4e3a\u5b83\u662f\u4e00\u4e2a**\u957f\u5ea6\u56fa\u5b9a\u4e14\u6709\u5e8f\u7684\u5b57\u5178 \uff0c\u56e0\u4e3a\u5b83\u5c06\u7d22\u5f15\u503c\u548c\u6570\u636e\u503c\u6309\u4f4d\u7f6e\u914d\u5bf9\u3002\u7d22\u5f15\u5728\u5de6\u8fb9\uff0c\u503c\u5728\u53f3\u8fb9\u3002 obj = pd.Series([4, 7, -5, 3]) print(obj) # 0 4 # 1 7 # 2 -5 # 3 3 # dtype: int64 print(obj.values) # [ 4 7 -5 3 print(obj.index) # RangeIndex(start=0, stop=4, step=1) \u81ea\u5b9a\u4e49index obj = pd.Series([4, 7, -5, 3], index=['d', 'b', 'a', 'c']) print(obj) # d 4 # b 7 # a -5 # c 3 # dtype: int64 print(obj.values) # [ 4 7 -5 3] print(obj.index) # Index(['d', 'b', 'a', 'c'], dtype='object') # \u8f93\u51fa\u7d22\u5f15\u503c\u4e3a'a'\u7684Series\u503c print(obj['a']) # -5 # \u4f7f\u7528\u5e03\u5c14\u503c\u6570\u7ec4\u8fdb\u884c\u8fc7\u6ee4Series\u503c print(obj[obj > 3]) # d 4 # b 7 # dtype: int64 # \u5bf9Series\u503c\u8fdb\u884c\u7b97\u672f\u8fd0\u7b97 print(obj * 2) # d 8 # b 14 # a -10 # c 6 # dtype: int64 # \u5bf9Series\u503c\u8fdb\u884c\u7b97\u672f\u8fd0\u7b97 print(np.exp(obj)) # d 54.598150 # b 1096.633158 # a 0.006738 # c 20.085537 # dtype: float64 # \u66f4\u65b0Series\u6570\u7ec4\u503c obj['a'] = 9 # \u8f93\u51fa\u6307\u5b9a\u7d22\u5f15\u503c\u7684Series\u503c\uff0c\u6ce8\u610f\uff0c\u7d22\u5f15\u6761\u4ef6\u662f\u5217\u8868 print(obj[['a', 'b', 'c']]) # a 9 # b 7 # c 3 # dtype: int64 # \u6ce8\u610f\uff0c\u4e0b\u9762\u7684\u5224\u65ad\u662f\u7d22\u5f15\u503c\uff0c\u975eSeries\u503c print(obj) print(7 in obj) # False print('a' in obj) # True \u901a\u8fc7\u5b57\u5178\u751f\u6210\u4e00\u4e2aSeries\u3002 NaN \uff08not a number\uff09\uff0c\u8fd9\u662fpandas\u4e2d\u6807\u8bb0\u7f3a\u5931\u503c\u6216NA\u503c\u7684\u65b9\u5f0f\u3002 \u5f53\u628a\u5b57\u5178\u4f20\u9012\u7ed9Series\u6784\u9020\u51fd\u6570\u65f6\uff0c\u4ea7\u751f\u7684Series\u7684\u7d22\u5f15\u5c06\u662f\u6392\u5e8f\u597d\u7684\u5b57\u5178\u952e\u3002\u53ef\u4ee5\u5c06\u5b57\u5178\u952e\u6309\u7167\u4f60\u6240\u60f3\u8981\u7684\u987a\u5e8f\u4f20\u9012\u7ed9\u6784\u9020\u51fd\u6570\uff0c\u4ece\u800c\u4f7f\u751f\u6210\u7684Series\u7684\u7d22\u5f15\u987a\u5e8f\u7b26\u5408\u9884\u671f\u3002 \u770b\u4e0b\u4f8b\uff0c\u901a\u8fc7\u5b57\u5178sdata\u751f\u6210Series\u3002 sdata = {'Ohio': 35000, 'Texas': 71000, 'Oregon': 16000, 'Utah': 5000} obj3 = pd.Series(sdata) print(sdata) # {'Ohio': 35000, 'Texas': 71000, 'Oregon': 16000, 'Utah': 5000} print(obj3) # Ohio 35000 # Texas 71000 # Oregon 16000 # Utah 5000 # dtype: int64 \u901a\u8fc7\u6307\u5b9a\u7d22\u5f15states\u53bb\u5339\u914d\u5b57\u5178sdata\u751f\u6210\u57fa\u4e8e\u65b0\u7d22\u5f15states\u7684Series\u3002 states = ['California', 'Ohio', 'Oregon', 'Texas'] obj4 = pd.Series(sdata, index=states) print(obj4) # California NaN # Ohio 35000.0 # Oregon 16000.0 # Texas 71000.0 # dtype: float64 \u5bf9Series\u8fdb\u884c\u5e03\u5c14\u503c\u5224\u65ad\u3002 print(pd.isnull(obj4)) # California True # Ohio False # Oregon False # Texas False # dtype: bool print(pd.notnull(obj4)) # California False # Ohio True # Oregon True # Texas True # dtype: bool \u5bf9Series\u8fdb\u884c\u5e03\u5c14\u503c\u5224\u65ad\u3002 print(obj4.isnull) # print(obj4.notnull) # Series\u7684\u81ea\u52a8\u5bf9\u9f50\u7d22\u5f15\uff0c\u4e0e\u6570\u636e\u5e93\u7684join\u64cd\u4f5c\u662f\u975e\u5e38\u76f8\u4f3c\u3002 print(\"obj3 \\n\", obj3) # obj3 # Ohio 35000 # Texas 71000 # Oregon 16000 # Utah 5000 # dtype: int64 print(\"obj4 \\n\", obj4) # obj4 # California NaN # Ohio 35000.0 # Oregon 16000.0 # Texas 71000.0 # dtype: float64 print(\"obj3+obj4 \\n\", obj3 + obj4) # obj3+obj4 # California NaN # Ohio 70000.0 # Oregon 32000.0 # Texas 142000.0 # Utah NaN # dtype: float64 # \u4e0b\u9762\u662fobj3\u548cobj4\u7684\u503c\uff0c\u5e2e\u52a9\u7406\u89e3\u4e0a\u9762obj3 + obj4\u7684\u64cd\u4f5c\u3002 # obj3 obj4 # Ohio 35000 California NaN # Texas 71000 Ohio 35000.0 # Oregon 16000 Oregon 16000.0 # Utah 5000 Texas 71000.0 # dtype: int64 dtype: float64 Series\u5bf9\u8c61\u81ea\u8eab\u548c\u5176\u7d22\u5f15\u90fd\u6709name\u5c5e\u6027\u3002 obj4.name = 'population' obj4.index.name = 'state' print(obj4) # state # California NaN # Ohio 35000.0 # Oregon 16000.0 # Texas 71000.0 # Name: population, dtype: float64 \u66ff\u6362Series\u7684\u7d22\u5f15\u540d\u3002 obj = pd.Series([4, 7, -5, 3], index=['d', 'b', 'a', 'c']) print(obj) obj.index = ['Bob', 'Steve', 'Jeff', 'Ryan'] print(obj) # Bob 4 # Steve 7 # Jeff -5 # Ryan 3 # dtype: int64","title":"Series"},{"location":"python/DataAnalysis/ch02/#dataframe","text":"DataFrame\u8868\u793a\u7684\u662f\u77e9\u9635\u7684\u6570\u636e\u8868\uff0c\u5b83\u5305\u542b\u5df2\u6392\u5e8f\u7684\u5217\u96c6\u5408\uff0c\u6bcf\u4e00\u5217\u53ef\u4ee5\u662f\u4e0d\u540c\u7684\u503c\u7c7b\u578b\uff08\u6570\u503c\u3001\u5b57\u7b26\u4e32\u3001\u5e03\u5c14\u503c\u7b49\uff09\u3002 DataFrame\u65e2\u6709\u884c\u7d22\u5f15\u4e5f\u6709\u5217\u7d22\u5f15\uff0c\u5b83\u53ef\u4ee5\u88ab\u89c6\u4e3a\u4e00\u4e2a\u5171\u4eab\u76f8\u540c\u7d22\u5f15\u7684Series\u7684\u5b57\u5178\uff0c\u6bd4\u5982\u6240\u6709\u5217\u5171\u4eab\u540c\u4e00\u4e2a\u5217\u7d22\u5f15\u3002 \u5728DataFrame\u4e2d\uff0c\u6570\u636e\u88ab\u5b58\u50a8\u4e3a\u4e00\u4e2a\u4ee5\u4e0a\u7684\u4e8c\u7ef4\u5757\uff0c\u800c\u4e0d\u662f\u5217\u8868\u3001\u5b57\u5178\u6216\u5176\u4ed6\u4e00\u7ef4\u6570\u7ec4\u7684\u96c6\u5408\u3002 DataFrame\u662f\u4e8c\u7ef4\u7684\uff0c\u4f46\u53ef\u4ee5\u5229\u7528**\u5206\u5c42\u7d22\u5f15**\u5728DataFrame\u4e2d\u5c55\u73b0\u66f4\u9ad8\u7ef4\u5ea6\u7684\u6570\u636e\u3002 \u4eceDataFrame\u4e2d\u9009\u53d6\u7684\u5217\u662f\u6570\u636e\u7684\u89c6\u56fe\uff0c\u800c\u4e0d\u662f\u62f7\u8d1d \u3002\u56e0\u6b64\uff0c\u5bf9Series\u7684\u4fee\u6539\u4f1a\u6620\u5c04\u5230DataFrame\u4e2d\u3002\u5982\u679c\u9700\u8981\u590d\u5236\uff0c\u5219\u5e94\u5f53\u663e\u5f0f\u5730\u4f7f\u7528Series\u7684copy\u65b9\u6cd5\u3002","title":"DataFrame"},{"location":"python/DataAnalysis/ch02/#dataframe_1","text":"\u57fa\u4e8e\u5b57\u5178 data \u4ea7\u751f\u7684DataFrame\u4f1a\u81ea\u52a8\u4e3aSereies\u5206\u914d\u7d22\u5f15\uff0c\u5e76\u4e14\u5217\u4f1a\u6309\u7167\u6392\u5e8f\u7684\u987a\u5e8f\u6392\u5217\u3002 data = { 'state': ['Ohio', 'Ohio', 'Ohio', 'Nevada', 'Nevada', 'Nevada'], 'year': [2000, 2001, 2002, 2001, 2002, 2003], 'pop': [1.5, 1.7, 3.6, 2.4, 2.9, 3.2] } frame = pd.DataFrame(data) print(frame) # state year pop # 0 Ohio 2000 1.5 # 1 Ohio 2001 1.7 # 2 Ohio 2002 3.6 # 3 Nevada 2001 2.4 # 4 Nevada 2002 2.9 # 5 Nevada 2003 3.2 # \u5bf9\u4e8e\u5927\u578bDataFrame, head\u65b9\u6cd5\u5c06\u4f1a\u53ea\u9009\u51fa\u5934\u90e8\u7684\u82e5\u5e72\u884c, \u9ed8\u8ba4\u662f\u524d\u4e94\u884c\u3002 print(frame.head(3)) # state year pop # 0 Ohio 2000 1.5 # 1 Ohio 2001 1.7 # 2 Ohio 2002 3.6 \u5982\u679c\u6307\u5b9a\u4e86\u5217\u7684\u987a\u5e8f\uff0cDataFrame\u7684\u5217\u5c06\u4f1a\u6309\u7167\u6307\u5b9a\u987a\u5e8f\u6392\u5217\u3002 frame = pd.DataFrame(data, columns=['year', 'state', 'pop']) print(frame) # year state pop # 0 2000 Ohio 1.5 # 1 2001 Ohio 1.7 # 2 2002 Ohio 3.6 # 3 2001 Nevada 2.4 # 4 2002 Nevada 2.9 # 5 2003 Nevada 3.2 \u5982\u679c\u4f20\u7684\u5217\uff08 debt \uff09\u4e0d\u5305\u542b\u5728\u5b57\u5178\uff08 data \uff09\u4e2d\uff0c\u5c06\u4f1a\u5728\u7ed3\u679c\u4e2d\u51fa\u73b0\u7f3a\u5931\u503c\u3002 frame2 = pd.DataFrame( data, columns=['year', 'state', 'pop', 'debt'], index=['one', 'two', 'three', 'four', 'five', 'six'] ) print(frame2) # year state pop debt # one 2000 Ohio 1.5 NaN # two 2001 Ohio 1.7 NaN # three 2002 Ohio 3.6 NaN # four 2001 Nevada 2.4 NaN # five 2002 Nevada 2.9 NaN # six 2003 Nevada 3.2 NaN \u9009\u53d6\u884c, \u53ef\u4ee5\u901a\u8fc7\u4f4d\u7f6e\u6216\u884c\u7d22\u5f15\u6807\u7b7e loc \u8fdb\u884c\u9009\u53d6\u3002 print(frame2.loc['three']) # year 2002 # state Ohio # pop 3.6 # debt NaN # Name: three, dtype: object DataFrame\u4e2d\u7684\u4e00\u5217\uff0c\u53ef\u4ee5\u6309\u5b57\u5178\u578b\u6807\u8bb0\u6216\u5c5e\u6027\u90a3\u6837\u68c0\u7d22\u4e3aSeries\u3002 frame2[colunm] \u5bf9\u4e8e\u4efb\u610f\u5217\u540d\u5747\u6709\u6548\uff0c\u4f46\u662f frame2.column \u53ea\u5728\u5217\u540d\u662f\u6709\u6548\u7684Python\u53d8\u91cf\u540d\u65f6\u6709\u6548\u3002 \u8fd4\u56de\u7684Series\u4e0e\u539fDataFrame\u6709\u76f8\u540c\u7684\u7d22\u5f15\uff0c\u4e14Series\u7684 name \u5c5e\u6027\u4e5f\u4f1a\u88ab\u5408\u7406\u5730\u8bbe\u7f6e\u3002 print(frame2['state']) # one Ohio # two Ohio # three Ohio # four Nevada # five Nevada # six Nevada # Name: state, dtype: object print(frame2.state) # \u5c5e\u6027\u578b\u8fde\u63a5 # one Ohio # two Ohio # three Ohio # four Nevada # five Nevada # six Nevada # Name: state, dtype: object \u5217\u7684\u5f15\u7528\u662f\u53ef\u4ee5\u4fee\u6539\u7684\u3002\u503c\u7684\u957f\u5ea6\u5fc5\u987b\u548cDataFrame\u7684\u957f\u5ea6\u76f8\u5339\u914d,\u6bd4\u5982\uff0c\u4e0b\u4f8b\u4e2d np.arange(6.) \u548c frame2['debt'] \u7684\u957f\u5ea6\u90fd\u662f6\u3002 frame2['debt'] = 16.5 print(frame2) # Name: state, dtype: object # year state pop debt # one 2000 Ohio 1.5 16.5 # two 2001 Ohio 1.7 16.5 # three 2002 Ohio 3.6 16.5 # four 2001 Nevada 2.4 16.5 # five 2002 Nevada 2.9 16.5 # six 2003 Nevada 3.2 16.5 frame2['debt'] = np.arange(6.) print(frame2) # year state pop debt # one 2000 Ohio 1.5 0.0 # two 2001 Ohio 1.7 1.0 # three 2002 Ohio 3.6 2.0 # four 2001 Nevada 2.4 3.0 # five 2002 Nevada 2.9 4.0 # six 2003 Nevada 3.2 5.0 \u5982\u679c\u5c06Series\u8d4b\u503c\u7ed9\u4e00\u5217\u65f6\uff0cSeries\u7684\u7d22\u5f15\u5c06\u4f1a\u6309\u7167DataFrame\u7684\u7d22\u5f15\u91cd\u65b0\u6392\u5217\uff0c\u5e76\u5728\u7a7a\u7f3a\u7684\u5730\u65b9\u586b\u5145\u7f3a\u5931\u503c val = pd.Series([-1.2, -1.5, -1.7], index=['two', 'four', 'five']) frame2['debt'] = val print(frame2) # year state pop debt # one 2000 Ohio 1.5 NaN # two 2001 Ohio 1.7 -1.2 # three 2002 Ohio 3.6 NaN # four 2001 Nevada 2.4 -1.5 # five 2002 Nevada 2.9 -1.7 # six 2003 Nevada 3.2 NaN \u5982\u679c\u88ab\u8d4b\u503c\u7684\u5217( eastern \u5217)\u5e76\u4e0d\u5b58\u5728\uff0c\u5219\u4f1a\u751f\u6210\u4e00\u4e2a\u65b0\u7684\u5217\u3002 frame2.state == 'Ohio' \u8fd4\u56de\u7684\u662f\u5e03\u5c14\u503c\uff0c\u8d4b\u503c\u7ed9 eastern \u3002 frame2['eastern'] = frame2.state == 'Ohio' print(frame2) # year state pop debt eastern # one 2000 Ohio 1.5 NaN True # two 2001 Ohio 1.7 -1.2 True # three 2002 Ohio 3.6 NaN True # four 2001 Nevada 2.4 -1.5 False # five 2002 Nevada 2.9 -1.7 False # six 2003 Nevada 3.2 NaN False print(frame2.eastern) # one True # two True # three True # four False # five False # six False # Name: eastern, dtype: bool del \u5173\u952e\u5b57\u53ef\u4ee5\u50cf\u5728\u5b57\u5178\u4e2d\u90a3\u6837\u5bf9DataFrame\u5220\u9664\u5217\u3002 del frame2['eastern'] print(frame2.columns) # Index(['year', 'state', 'pop', 'debt'], dtype='object')","title":"\u7531\u5b57\u5178\u6784\u6210DataFrame"},{"location":"python/DataAnalysis/ch02/#dataframe_2","text":"pandas\u4f1a\u5c06\u5b57\u5178\u7684\u952e\u4f5c\u4e3a\u5217('Nevada', etc.)\uff0c\u5c06\u5185\u90e8\u5b57\u5178\u7684\u952e\u4f5c\u4e3a\u884c\u7d22\u5f15(2001, etc.) pop = { 'Nevada': { 2001: 2.4, 2002: 2.9 }, 'Ohio': { 2000: 1.5, 2001: 1.7, 2002: 3.6 } } # \u4e0d\u6307\u5b9a\u7d22\u5f15\uff0c\u9ed8\u8ba4\u4f7f\u7528\u5b57\u5178\u7d22\u5f15 frame3 = pd.DataFrame(pop) print(frame3) # Nevada Ohio # 2001 2.4 1.7 # 2002 2.9 3.6 # 2000 NaN 1.5 # \u6307\u5b9a\u5b57\u5178\u67d0\u5217\u4f5c\u4e3a\u7d22\u5f15 print(pd.DataFrame(pop, index=[2001, 2002, 2003])) # Nevada Ohio # 2001 2.4 1.7 # 2002 2.9 3.6 # 2003 NaN NaN # \u6307\u5b9a\u4e0d\u76f8\u5e72\u7d22\u5f15 print(pd.DataFrame(pop, index=['a', 'b', 'c'])) # Nevada Ohio # a NaN NaN # b NaN NaN # c NaN NaN \u8f6c\u7f6e\u64cd\u4f5c\uff08\u8c03\u6362\u884c\u548c\u5217\uff09 print(frame3.T) # 2001 2002 2000 # Nevada 2.4 2.9 NaN # Ohio 1.7 3.6 1.5","title":"\u4f7f\u7528\u5d4c\u5957\u5b57\u5178\u6784\u5efaDataFrame"},{"location":"python/DataAnalysis/ch02/#seriesdataframe","text":"frame3['Ohio'][:-1] \u662f\u503c\u4e3a Ohio \u7684Series\u76840~\u5012\u6570\u7b2c\u4e00\u4e2a\u5143\u7d20\uff08\u4e0d\u542b\uff09\uff0c\u4e00\u51713\u4e2a\u3002 frame3['Nevada'][:2] \u662f\u503c\u4e3a Nevada \u7684Series\u7684\u524d2\u4e2a\u5143\u7d20\u3002 pdata = { 'Ohio': frame3['Ohio'][:-1], 'Nevada': frame3['Nevada'][:2] } print(pd.DataFrame(pdata)) # Ohio Nevada # 2001 1.7 2.4 # 2002 3.6 2.9 \u6307\u5b9aDataframe frame3 \u7684\u5217\u540d\u3002 frame3.index.name = 'year' frame3.columns.name = 'state' print(frame3) # state Nevada Ohio # year # 2001 2.4 1.7 # 2002 2.9 3.6 # 2000 NaN 1.5 \u53ea\u8f93\u51faDataframe\u7684\u503c frame3.values \uff0c\u662f\u4e00\u4e2a\u4e8c\u7ef4\u6570\u7ec4\u3002 print(frame3.values) # [[2.4 1.7] # [2.9 3.6] # [nan 1.5]] \u53ea\u8f93\u51faDataframe\u7684\u503c frame2.values \uff0c\u662f\u4e00\u4e2a\u4e8c\u7ef4\u6570\u7ec4\u3002 print(frame2) # year state pop debt # one 2000 Ohio 1.5 NaN # two 2001 Ohio 1.7 -1.2 # three 2002 Ohio 3.6 NaN # four 2001 Nevada 2.4 -1.5 # five 2002 Nevada 2.9 -1.7 # six 2003 Nevada 3.2 NaN print(frame2.values) # [[2000 'Ohio' 1.5 nan] # [2001 'Ohio' 1.7 -1.2] # [2002 'Ohio' 3.6 nan] # [2001 'Nevada' 2.4 -1.5] # [2002 'Nevada' 2.9 -1.7] # [2003 'Nevada' 3.2 nan]]","title":"\u4f7f\u7528\u542bSeries\u7684\u5b57\u5178\u6784\u9020DataFrame"},{"location":"python/DataAnalysis/ch02/#_1","text":"pandas\u4e2d\u7684**\u7d22\u5f15\u5bf9\u8c61**\u662f\u7528\u4e8e\u5b58\u50a8\u8f74\u6807\u7b7e\u548c\u5176\u4ed6\u5143\u6570\u636e\u7684\uff08\u4f8b\u5982\u8f74\u540d\u79f0\u6216\u6807\u7b7e\uff09\u3002 \u5728\u6784\u9020Series\u6216DataFrame\u65f6\uff0c\u4f60\u6240\u4f7f\u7528\u7684\u4efb\u610f\u6570\u7ec4\u6216\u6807\u7b7e\u5e8f\u5217\u90fd\u53ef\u4ee5\u5728\u5185\u90e8\u8f6c\u6362\u4e3a\u7d22\u5f15\u5bf9\u8c61\u3002 \u7d22\u5f15\u5bf9\u8c61\u662f\u4e0d\u53ef\u53d8\u7684\u3002 \u9664\u4e86\u7c7b\u4f3c\u6570\u7ec4\uff0c\u7d22\u5f15\u5bf9\u8c61\u4e5f\u50cf\u4e00\u4e2a\u56fa\u5b9a\u5927\u5c0f\u7684\u96c6\u5408\u3002\u4e0ePython\u96c6\u5408\u4e0d\u540c\uff0c pandas\u7d22\u5f15\u5bf9\u8c61\u53ef\u4ee5\u5305\u542b\u91cd\u590d\u6807\u7b7e \u3002 \u56e0\u4e3a\u4e00\u4e9b\u64cd\u4f5c\u4f1a\u4ea7\u751f\u5305\u542b\u7d22\u5f15\u5316\u6570\u636e\u7684\u7ed3\u679c\uff0c\u7406\u89e3\u7d22\u5f15\u5982\u4f55\u5de5\u4f5c\u8fd8\u662f\u5f88\u91cd\u8981\u7684\u3002 \u4e0b\u4f8b\u6f14\u793a\u4e86\u5982\u4f55\u8bfb\u53d6Dataframe\u7684\u7d22\u5f15\u503c\u3002 obj = pd.Series(range(3), index=['a', 'b', 'c']) index = obj.index print(obj) # a 0 # b 1 # c 2 # dtype: int64 print(index) # Index(['a', 'b', 'c'], dtype='object') print(index[1:]) # Index(['b', 'c'], dtype='object') \u4e0b\u4f8b\u6f14\u793a\u4e86\u901a\u8fc7\u4e00\u4e2a\u6307\u5b9a\u7684Dataframe\u7d22\u5f15 labels \u6765\u751f\u6210Dataframe obj2 \u3002 labels = pd.Index(np.arange(3)) print(labels) # Int64Index([0, 1, 2], dtype='int64') obj2 = pd.Series([1.5, -2.5, 0], index=labels) print(obj2) # 0 1.5 # 1 -2.5 # 2 0.0 # dtype: float64 print(obj2.index is labels) # True \u4e0b\u4f8b\u6f14\u793a\u4e86\u4e0d\u6307\u5b9a\u7d22\u5f15\uff0c\u9ed8\u8ba4\u4f7f\u7528\u5b57\u5178\u7d22\u5f15\u6765\u521b\u5efaDataframe\u3002 pop = { 'Nevada': { 2001: 2.4, 2002: 2.9 }, 'Ohio': { 2000: 1.5, 2001: 1.7, 2002: 3.6 } } frame3 = pd.DataFrame(pop) print(frame3) # Nevada Ohio # 2001 2.4 1.7 # 2002 2.9 3.6 # 2000 NaN 1.5 print(frame3) # state Nevada Ohio # year # 2001 2.4 1.7 # 2002 2.9 3.6 # 2000 NaN 1.5 print(frame3.columns) # Index(['Nevada', 'Ohio'], dtype='object', name='state') print(frame3.index) # Int64Index([2001, 2002, 2000], dtype='int64', name='year') print('Ohio' in frame3.columns) # True print(2003 in frame3.index) # False pandas\u7d22\u5f15\u5bf9\u8c61\u5141\u8bb8\u5305\u542b\u91cd\u590d\u6807\u7b7e\u3002\u6839\u636e\u91cd\u590d\u6807\u7b7e\u8fdb\u884c\u7b5b\u9009\uff0c\u4f1a\u9009\u53d6\u6240\u6709\u91cd\u590d\u6807\u7b7e\u5bf9\u5e94\u7684\u6570\u636e\u3002 dup_labels = pd.Index(['foo', 'foo', 'bar', 'bar']) print(dup_labels) # Index(['foo', 'foo', 'bar', 'bar'], dtype='object') \u4e00\u4e9b\u5e38\u7528\u7d22\u5f15\u5bf9\u8c61\u7684\u65b9\u6cd5\u548c\u5c5e\u6027\u3002 obj1 = pd.Series(range(3), index=['a', 'b', 'c']) index1 = obj1.index obj2 = pd.Series(range(3), index=['c', 'f', 'g']) index2 = obj2.index print(index1) # Index(['a', 'b', 'c'], dtype='object') print(index2) # Index(['c', 'f', 'g'], dtype='object') append \u65b9\u6cd5\uff1a\u5c06\u5916\u90e8\u7684\u7d22\u5f15\u5bf9\u8c61\u7c98\u8d34\u5230\u539f\u7d22\u5f15\u540e\uff0c\u4ea7\u751f\u4e00\u4e2a\u65b0\u7684\u7d22\u5f15\u3002 \u63a5\u4e0a\u4f8b\uff0c\u628a index2 \u5bf9\u8c61\u8ffd\u52a0\u5230 index1 \u5bf9\u8c61\u3002 print(index1.append(index2)) # Index(['a', 'b', 'c', 'c', 'f', 'g'], dtype='object') difference \u65b9\u6cd5: \u8ba1\u7b972\u4e2a\u7d22\u5f15\u7684\u5dee\u96c6\u3002 print(index1.difference(index2)) # Index(['a', 'b'], dtype='object') intersection \u65b9\u6cd5: \u8ba1\u7b972\u4e2a\u7d22\u5f15\u7684\u4ea4\u96c6\u3002 print(index1.intersection(index2)) # Index(['c'], dtype='object') union \u65b9\u6cd5: \u8ba1\u7b972\u4e2a\u7d22\u5f15\u7684\u5e76\u96c6\uff08\u53bb\u91cd\uff09\u3002 print(index1.union(index2)) # Index(['a', 'b', 'c', 'f', 'g'], dtype='object') isin \u65b9\u6cd5: \u8ba1\u7b97\u8868\u793a\u6bcf\u4e00\u4e2a\u503c\u662f\u5426\u5728\u4f20\u503c\u5bb9\u5668\u4e2d\uff0c\u8fd4\u56de\u7684\u662f\u4e00\u4e2a\u5e03\u5c14\u6570\u7ec4\u3002 print(index1.isin(index2)) # [False False True] delete \u65b9\u6cd5: \u5c06\u4f4d\u7f6ei\uff08\u4ece0\u5f00\u59cb\u7f16\u53f7\uff09\u7684\u5143\u7d20\u5220\u9664\uff0c\u5e76\u4ea7\u751f\u65b0\u7684\u7d22\u5f15\u3002 print(index1.delete('b')) # IndexError: arrays used as indices must be of integer (or boolean) type print(index1.delete(1)) # Index(['a', 'c'], dtype='object') print(index1) # Index(['a', 'b', 'c'], dtype='object') drop \u65b9\u6cd5: \u6839\u636e\u4f20\u53c2\u5220\u9664\u6307\u5b9a\u7d22\u5f15\u503c\uff0c\u5e76\u4ea7\u751f\u65b0\u7684\u7d22\u5f15, \u5bf9\u6bd4\u548cdelete\u7684\u533a\u522b\uff0c delete \u65b9\u6cd5\u662f\u8f93\u5165\u4f4d\u7f6e\uff0c drop \u65b9\u6cd5\u662f\u8f93\u5165\u7d22\u5f15\u540d\u79f0\u3002 print(index2.drop(1)) # KeyError: '[1] not found in axis' print(index2.drop('f')) # Index(['c', 'g'], dtype='object') print(index2) # Index(['c', 'f', 'g'], dtype='object') insert \u65b9\u6cd5: \u5728\u4f4d\u7f6e i \u63d2\u5165\u5143\u7d20\uff0c\u5e76\u4ea7\u751f\u65b0\u7684\u7d22\u5f15\u3002 print(index1.insert(1, 'e')) # Index(['a', 'e', 'b', 'c'], dtype='object') print(index1) # Index(['a', 'b', 'c'], dtype='object') is_monotonic \u65b9\u6cd5: \u5982\u679c\u7d22\u5f15\u5e8f\u5217\u9012\u589e\uff0c\u5219\u8fd4\u56de True \u3002 print(index1.is_monotonic) # True print(index1.insert(1, 'e').is_monotonic) # False is_unique \u65b9\u6cd5: \u5982\u679c\u7d22\u5f15\u5e8f\u5217\u552f\u4e00\u5219\u8fd4\u56de True \u3002 print(index1.is_unique) # True print(index1.append(index2).is_unique) # False unique \u65b9\u6cd5: \u8ba1\u7b97\u7d22\u5f15\u7684\u552f\u4e00\u503c\u5e8f\u5217\uff08\u5bf9\u6bd4Union\uff09\u3002 print(index1.unique()) # Index(['a', 'b', 'c'], dtype='object') print(index1.append(index2).unique()) # Index(['a', 'b', 'c', 'f', 'g'], dtype='object')","title":"\u7d22\u5f15\u5bf9\u8c61"},{"location":"python/DataAnalysis/ch02/#pandas_2","text":"","title":"pandas\u57fa\u672c\u529f\u80fd"},{"location":"python/DataAnalysis/ch02/#_2","text":"Series\u8c03\u7528 reindex \u65b9\u6cd5\u65f6\uff0c\u4f1a\u5c06\u6570\u636e\u6309\u7167\u65b0\u7684\u7d22\u5f15\u8fdb\u884c\u6392\u5217\uff0c\u5982\u679c\u67d0\u4e2a\u7d22\u5f15\u503c\u4e4b\u524d\u5e76\u4e0d\u5b58\u5728\uff0c\u5219\u4f1a\u5f15\u5165\u7f3a\u5931\u503c\u3002 \u4e0b\u4f8b\u4e2d\uff0c\u5bf9 obj1 \u505a reindex \uff0c reindex \u65b9\u6cd5\u4f1a\u521b\u5efa\u4e00\u4e2a\u65b0\u7d22\u5f15\u5bf9\u8c61 obj2 \uff0c\u7d22\u5f15\u503c e \u4e4b\u524d\u5e76\u4e0d\u5b58\u5728\uff0c\u6240\u4ee5\u586b\u5165\u7f3a\u5931\u503c\u3002 \u5982\u679c\u5bf9obj1\u505a reindex \u65f6\u6307\u5b9a method='ffill' \uff0c\u4f1a\u62a5\u9519 index must be monotonic increasing or decreasing \u3002 obj1 = pd.Series([4.5, 7.2, -5.3, 3.6], index=['d', 'b', 'a', 'c']) print(obj1) # d 4.5 # b 7.2 # a -5.3 # c 3.6 # dtype: float64 obj2 = obj1.reindex(['a', 'b', 'c', 'd', 'e']) print(obj2) # a -5.3 # b 7.2 # c 3.6 # d 4.5 # e NaN # dtype: float64 obj2 = obj1.reindex(['a', 'b', 'c', 'd', 'e'], method='ffill') # ValueError: index must be monotonic increasing or decreasing \u5bf9\u4e8e\u987a\u5e8f\u6570\u636e\uff0c\u6bd4\u5982\u65f6\u95f4\u5e8f\u5217\uff0c\u5728\u91cd\u5efa\u7d22\u5f15\u65f6\u53ef\u80fd\u4f1a\u9700\u8981\u8fdb\u884c\u63d2\u503c\u6216\u586b\u503c\u3002 ffill \u65b9\u6cd5\u5728\u91cd\u5efa\u7d22\u5f15\u65f6\u63d2\u503c\uff0c\u5c06\u503c\u524d\u5411\u586b\u5145\u3002 obj3 = pd.Series(['blue', 'purple', 'yellow'], index=[0, 2, 4]) print(obj3.reindex(range(6), method='ffill')) # 0 blue # 1 blue # 2 purple # 3 purple # 4 yellow # 5 yellow # dtype: object \u5728DataFrame\u4e2d\uff0c reindex \u53ef\u4ee5\u6539\u53d8\u884c\u7d22\u5f15\u3001\u5217\u7d22\u5f15\uff0c\u4e5f\u53ef\u4ee5\u540c\u65f6\u6539\u53d8\u4e8c\u8005\u3002\u5f53\u4ec5\u4f20\u5165\u4e00\u4e2a\u5e8f\u5217\u65f6\uff0c\u4f1a\u91cd\u5efa\u884c\u7d22\u5f15\u3002 \u4e0b\u4f8b\u4e2d\uff0c\u901a\u8fc7 indexes \u521b\u5efaDataframe frame \u3002 \u901a\u8fc7 frame.reindex(['a', 'b', 'c', 'd'])\u91cd\u5efa\u884c\u7d22\u5f15 \u3002 \u901a\u8fc7 frame2.reindex(columns=['Ohio', 'Uta', 'California']) \u91cd\u5efa\u5217\u7d22\u5f15\u3002 \u7f3a\u5931\u7684\u7d22\u5f15\u5217\u586b\u5165\u7f3a\u5931\u503c\u3002 indexes = index = ['a', 'b', 'c'] states = ['Ohio', 'Texas', 'California'] frame = pd.DataFrame( np.arange(9).reshape(3, 3), index=indexes, columns=states ) print(frame) # Ohio Texas California # a 0 1 2 # b 3 4 5 # c 6 7 8 frame2 = frame.reindex(['a', 'b', 'c', 'd']) # \u91cd\u5efa\u884c\u7d22\u5f15 print(frame2) # Ohio Texas California # a 0.0 1.0 2.0 # b 3.0 4.0 5.0 # c 6.0 7.0 8.0 # d NaN NaN NaN frame3 = frame2.reindex(columns=['Ohio', 'Uta', 'California']) # \u91cd\u5efa\u5217\u7d22\u5f15 print(frame3) # Ohio Uta California # a 0.0 NaN 2.0 # b 3.0 NaN 5.0 # c 6.0 NaN 8.0 # d NaN NaN NaN \u4f7f\u7528 loc \u8fdb\u884c\u66f4\u4e3a\u7b80\u6d01\u7684\u884c\u3001\u5217\u6807\u7b7e\u7d22\u5f15\u3002\u4e0b\u4f8b\u901a\u8fc7\u7b5b\u9009\u884c\u7d22\u5f15\u548c\u5217\u7d22\u5f15\u4ea7\u751f\u65b0\u7684Dataframe\u3002 frame4 = frame.loc[['a', 'b'], states] print(frame4) # Ohio Texas California # a 0 1 2 # b 3 4 5","title":"\u91cd\u5efa\u7d22\u5f15"},{"location":"python/DataAnalysis/ch02/#_3","text":"set_index() , dropna() , fillna() , reset_index() , drop() , replace() \u8fd9\u4e9b\u65b9\u6cd5\u7684 inplace \u5c5e\u6027\u8bbe\u4e3a True \u65f6\uff0c\u8fd9\u4e9b\u65b9\u6cd5\u4f1a\u4fee\u6539Series\u6216DataFrame\u7684\u5c3a\u5bf8\u6216\u5f62\u72b6\uff0c*\u76f4\u63a5*\u64cd\u4f5c\u539f\u5bf9\u8c61\u800c\u4e0d\u8fd4\u56de\u65b0\u5bf9\u8c61\u3002 obj = pd.Series(np.arange(5), index=['a', 'b', 'c', 'd', 'e']) print(obj) # a 0 # b 1 # c 2 # d 3 # e 4 # dtype: int64 obj1 = obj.drop('c') print(obj1) # a 0 # b 1 # d 3 # e 4 # dtype: int64 print(obj1.drop(['d', 'e'])) # a 0 # b 1 # dtype: int64 \u5bf9\u6bd4 inplace=True \u548c False \u7684\u533a\u522b\u3002 inplace=False \u65f6\uff0c obj \u7684\u503c\u6ca1\u6709\u53d8\u5316\u3002 obj = pd.Series(np.arange(5), index=['a', 'b', 'c', 'd', 'e']) print(obj.drop('c', inplace=False)) # \u8bf4\u660e\u751f\u6210\u4e86\u65b0\u5bf9\u8c61 # a 0 # b 1 # d 3 # e 4 # dtype: int64 print(obj) # a 0 # b 1 # c 2 # d 3 # e 4 # dtype: int64 obj.drop('c', inplace=True) \u8f93\u51fa\u662f None \uff0c\u8bf4\u660e\u6ca1\u6709\u751f\u6210\u65b0\u5bf9\u8c61\uff0c\u53d8\u5316\u76f4\u63a5\u4f5c\u7528\u5230 obj \u4e0a\u3002 obj = pd.Series(np.arange(5), index=['a', 'b', 'c', 'd', 'e']) print(obj) print(obj.drop('c', inplace=True)) # \u8bf4\u660e\u6ca1\u6709\u751f\u6210\u65b0\u5bf9\u8c61 # None print(obj) # a 0 # b 1 # d 3 # e 4 # dtype: int64 \u4e0b\u4f8b\u6f14\u793a\u4e86\u8f74\u5411\u7684\u6548\u679c\u3002 \u5982\u679c\u4e0d\u6307\u5b9a\u8f74\u5411axis\uff0c drop() \u4f1a\u9ed8\u8ba4\u6cbf axis=0 \u8fdb\u884c\uff0c\u6240\u4ee5\uff0c\u57280\u8f74\u4e0a\u6267\u884c data.drop(['one', 'two']) \u4f1a\u62a5\u9519\u3002 axis='columns \u4e0e\u6307\u5b9a axis=1 \u540c\u6837\u6548\u679c\u3002 data = pd.DataFrame( np.arange(16).reshape(4, 4), index=['Ohio', 'Colorado', 'Utah', 'New York'], columns=['one', 'two', 'three', 'four'] ) print(data) # one two three four # Ohio 0 1 2 3 # Colorado 4 5 6 7 # Utah 8 9 10 11 # New York 12 13 14 15 # \u6cbf0\u8f74\u64cd\u4f5c\uff0c\u5220\u9664\u7b26\u5408\u6761\u4ef6\u7684\u884c\u8bb0\u5f55 print(data.drop(['Ohio', 'Colorado'])) # one two three four # Utah 8 9 10 11 # New York 12 13 14 15 print(data.drop(['one', 'two'])) # KeyError: \"['one' 'two'] not found in axis\" # \u6cbf1\u8f74\u64cd\u4f5c\uff0c\u5220\u9664\u7b26\u5408\u6761\u4ef6\u7684\u5217\u8bb0\u5f55 print(data.drop(['one', 'two'], axis=1)) # three four # Ohio 2 3 # Colorado 6 7 # Utah 10 11 # New York 14 15 print(data.drop(['one', 'two'], axis='columns')) # three four # Ohio 2 3 # Colorado 6 7 # Utah 10 11 # New York 14 15 \u518d\u901a\u8fc7\u4e0b\u4f8b\u4f53\u4f1a\u4e00\u4e0b inplace \u53c2\u6570\u7684\u4e0d\u540c\u6548\u679c\u3002 data = pd.DataFrame( { 'Name': ['Shobhit', 'vaibhav', 'vimal', 'Sourabh'], 'class': [11, 12, 10, 9], 'Age': [18, 20, 21, 17] } ) print(data) # Name class Age # 0 Shobhit 11 18 # 1 vaibhav 12 20 # 2 vimal 10 21 # 3 Sourabh 9 17 print(data.rename(columns={'Name': 'FirstName'}, inplace=False)) # FirstName class Age # 0 Shobhit 11 18 # 1 vaibhav 12 20 # 2 vimal 10 21 # 3 Sourabh 9 17 print(data) # Name class Age # 0 Shobhit 11 18 # 1 vaibhav 12 20 # 2 vimal 10 21 # 3 Sourabh 9 17 print(data.rename(columns={'Name': 'FirstName'}, inplace=True)) # \u6ca1\u6709\u751f\u6210\u65b0\u5bf9\u8c61 # None print(data) # FirstName class Age # 0 Shobhit 11 18 # 1 vaibhav 12 20 # 2 vimal 10 21 # 3 Sourabh 9 17","title":"\u8f74\u5411\u7d22\u5f15\u5220\u9664\u6761\u76ee"},{"location":"python/DataAnalysis/ch02/#_4","text":"Series\u7684\u7d22\u5f15 obj[...] \u4e0eNumPy\u6570\u7ec4\u7d22\u5f15\u7684\u529f\u80fd\u7c7b\u4f3c\uff0c\u53ea\u4e0d\u8fc7Series\u7684\u7d22\u5f15\u503c\u53ef\u4ee5\u4e0d\u4ec5\u4ec5\u662f\u6574\u6570\u3002 \u4e0b\u4f8b\u4e2d\uff1a obj[1] \u901a\u8fc7\u7d22\u5f15\u4f4d 1 \u68c0\u7d22\uff0c\u8f93\u51fa\u5bf9\u5e94Series\u7684\u503c\u3002 obj[1] \u901a\u8fc7\u7d22\u5f15\u4f4d [1] \u68c0\u7d22\uff0c\u8f93\u51faSeries\u3002 obj['b'] \u901a\u8fc7\u7d22\u5f15\u503c 'b' \u68c0\u7d22\uff0c\u8f93\u51fa\u5bf9\u5e94Series\u7684\u503c\u3002 obj[['b']] \u901a\u8fc7\u7d22\u5f15\u503c ['b'] \u68c0\u7d22\uff0c\u8f93\u51faSeries\u3002 obj = pd.Series(['Shobhit', 'vaibhav', 'vimal', 'Sourabh'], index=['a', 'b', 'c', 'd']) print(obj) # a Shobhit # b vaibhav # c vimal # d Sourabh # dtype: object print(obj[1]) # \u901a\u8fc7\u7d22\u5f15\u4f4d\u68c0\u7d22\uff0c\u8f93\u51fa\u5bf9\u5e94Series\u7684\u503c # vaibhav print(obj[[1]]) # b vaibhav # dtype: object print(obj['b']) # \u901a\u8fc7\u7d22\u5f15\u503c\u68c0\u7d22\uff0c\u8f93\u51fa\u5bf9\u5e94Series\u7684\u503c # vaibhav print(obj[['b']]) # \u901a\u8fc7\u7d22\u5f15\u503c\u68c0\u7d22\uff0c\u8f93\u51faSeries # b vaibhav # dtype: object \u4e0b\u9762\u4e00\u7ec4\u7684\u8f93\u51fa\u4e2d\uff0c\u6ce8\u610f\u5bf9\u6bd4\u666e\u901aPython\u5207\u7247\u4e0eSeries\u7684\u5207\u7247\u7684\u5dee\u5f02\u3002 obj = pd.Series(['Shobhit', 'vaibhav', 'vimal', 'Sourabh'], index=['a', 'b', 'c', 'd']) print(obj[1]) # vaibhav print(obj[[1]]) # b vaibhav # dtype: object print(obj[1:3]) # b vaibhav # c vimal # dtype: object print(obj['b':'d']) # b vaibhav # c vimal # d Sourabh # dtype: object Series\u7684\u5207\u7247\u7684\u503c\u66f4\u65b0\u3002 obj['b': 'c'] = 5 \u662f\u901a\u8fc7\u7d22\u5f15\u503c\u8fdb\u884c\u66f4\u65b0\uff0c\u76f4\u63a5\u4f5c\u7528\u5728 obj \u3002 obj[1: 3] = 6 \u662f\u901a\u8fc7\u7d22\u5f15\u4f4d\u7f6e\u6765\u66f4\u65b0 obj \u3002 obj = pd.Series(['Shobhit', 'vaibhav', 'vimal', 'Sourabh'], index=['a', 'b', 'c', 'd']) obj['b': 'c'] = 5 print(obj) # a Shobhit # b 5 # c 5 # d Sourabh # dtype: object obj[1: 3] = 6 print(obj) # a Shobhit # b 6 # c 6 # d Sourabh # dtype: object DataFrame\u7684\u7d22\u5f15\u4e0e\u5207\u7247\u3002 data[['Three', 'Two']] \u9009\u53d6\u6307\u5b9a\u5217\uff0c\u6ce8\u610f\u8f93\u5165\u5217\u6761\u4ef6\u662f\u5217\u8868 ['Three', 'Two'] \u3002 data = pd.DataFrame( np.arange(16).reshape(4, 4), index=['Ohio', 'Colorado', 'Utah', 'New York'], columns=['One', 'Two', 'Three', 'Four'] ) print(data) # One Two Three Four # Ohio 0 1 2 3 # Colorado 4 5 6 7 # Utah 8 9 10 11 # New York 12 13 14 15 print(data['Two']) # Ohio 1 # Colorado 5 # Utah 9 # New York 13 # Name: Two, dtype: int64 print(data[['Three', 'Two']]) # Three Two # Ohio 2 1 # Colorado 6 5 # Utah 10 9 # New York 14 13 print(data[:2]) # One Two Three Four # Ohio 0 1 2 3 # Colorado 4 5 6 7 \u5d4c\u5957\uff1a\u6839\u636e\u4e00\u4e2a\u5e03\u5c14\u503c\u6570\u7ec4\u5207\u7247\u6216\u9009\u62e9\u6570\u636e\u3002 data['Three'] > 5 \u662f\u4e00\u4e2a\u5e03\u5c14\u503c\u5e8f\u5217\u3002 data[data['Three'] > 5] \u8f93\u51fa\u6761\u4ef6\u4e3aTrue\u7684\u7ed3\u679c\u96c6\u3002 print(data['Three'] > 5) # Ohio False # Colorado True # Utah True # New York True # Name: Three, dtype: bool print(data[data['Three'] > 5]) # One Two Three Four # Colorado 4 5 6 7 # Utah 8 9 10 11 # New York 12 13 14 15 \u4f7f\u7528\u5e03\u5c14\u503cDataFrame\u8fdb\u884c\u7d22\u5f15\uff0c\u5df2\u7ecf\u66f4\u65b0\u3002 \u5728\u4e0b\u9762\u8fd9\u4e2a\u4f8b\u5b50\u4e2d\uff0c\u8fd9\u79cd\u7d22\u5f15\u65b9\u5f0f\u4f7f\u5f97DataFrame\u5728\u8bed\u6cd5\u4e0a\u66f4\u50cf\u662fNumPy\u4e8c\u7ef4\u6570\u7ec4\u3002 print(data < 5) # One Two Three Four # Ohio True True True True # Colorado True False False False # Utah False False False False # New York False False False False data[data < 5] = 0 print(data) # One Two Three Four # Ohio 0 0 0 0 # Colorado 0 5 6 7 # Utah 8 9 10 11 # New York 12 13 14 15 \u4f7f\u7528loc\u548ciloc\u9009\u62e9\u6570\u636e\u3002 \u4f7f\u7528\u6807\u7b7e\u540d loc \u6216\u6807\u7b7e\u4f4d\u7f6e iloc \u4ee5NumPy\u98ce\u683c\u7684\u8bed\u6cd5\u4eceDataFrame\u4e2d\u9009\u51faDataframe\u7684\u884c\u548c\u5217\u7684\u5b50\u96c6\u3002 data = pd.DataFrame( np.arange(16).reshape(4, 4), index=['Ohio', 'Colorado', 'Utah', 'New York'], columns=['One', 'Two', 'Three', 'Four'] ) print(data) # One Two Three Four # Ohio 0 1 2 3 # Colorado 4 5 6 7 # Utah 8 9 10 11 # New York 12 13 14 15 \u4e0b\u4f8b\u901a\u8fc7loc\u5bf9\u6807\u7b7e\u540d\u7b5b\u9009\u884c\u6216\u5217\u6570\u636e\u3002\u4f8b\u5982\uff0c\u8f93\u51fa Colorado \u884c\u6807\u7b7e\u7684 Two \u548c Three \u8fd9\u4e24\u5217\u7684\u503c\uff0c\u4ee5\u884c\u8bb0\u5f55\u7684\u65b9\u5f0f\u5c55\u73b0\u3002 print(data.loc['Colorado', ['Two', 'Three']]) # \u5207\u7247: # Two 5 # Three 6 # Name: Colorado, dtype: int64 print(data.loc[:'Ohio', :'Two']) # \u5207\u7247: 0\u884c\uff0c0,1\u5217 # One Two # Ohio 0 1 \u4e0b\u4f8b\u901a\u8fc7\u6807\u7b7e\u4f4d\u7f6e iloc \u8fdb\u884c\u7c7b\u4f3c\u7684\u6570\u636e\u9009\u62e9\u3002 data.iloc[:3, :2][data > 4] \u6309\u6307\u5b9a\u6761\u4ef6\u8fdb\u884c\u884c\u3001\u5217\u7b5b\u9009\uff0c\u7b26\u5408\u6761\u4ef6 [data > 4] \u7684\u8f93\u51faDataframe\u503c\uff0c\u4e0d\u7b26\u5408\u6761\u4ef6\u7684\u8f93\u51faNaN\u3002 print(data.iloc[[0]]) # 0\u884c # One Two Three Four # Ohio 0 1 2 3 print(data.iloc[[0], [1]]) # \u5207\u7247: 0\u884c\uff0c1\u5217 # Two # Ohio 1 print(data.iloc[1:2, 1:2]) # \u5207\u7247: 1\u884c\uff0c2\u5217 # Two # Ohio 1 print(data.iloc[2, [3, 0, 1]]) # \u5207\u7247: 2\u884c\uff0c\u4f9d\u6b21\u53d63\uff0c0\uff0c1\u5217 # Four 11 # One 8 # Two 9 # Name: Utah, dtype: int64 print(data.iloc[:3, :2][data > 4]) # One Two # Ohio NaN NaN # Colorado NaN 5.0 # Utah 8.0 9.0","title":"\u7d22\u5f15\u3001\u9009\u62e9\u4e0e\u8fc7\u6ee4"},{"location":"python/DataAnalysis/ch02/#_5","text":"Pandas\u7684Series\u7684\u7d22\u5f15\u503c\u662f\u6574\u6570\u7d22\u5f15\u3002 data = np.arange(3.) ser = pd.Series(data) print(ser) # 0 0.0 # 1 1.0 # 2 2.0 # dtype: float64 print(ser[:1]) # 0 0.0 # dtype: float64 print(ser.loc[:1]) # loc\u7528\u4e8e\u6807\u7b7e\u540d # 0 0.0 # 1 1.0 # dtype: float64 print(ser.iloc[:1]) # iloc\u7528\u4e8e\u6807\u7b7e\u4f4d\u7f6e # 0 0.0 # dtype: float64 data = ['1', 'b', 'e', 3] ser = pd.Series(data) print(ser) # 0 1 # 1 b # 2 e # 3 3 # dtype: object print(ser[:1]) # 0 1 # dtype: object print(ser.loc[:1]) # 0 1 # 1 b # dtype: object print(ser.iloc[:1]) # 0 1 # dtype: object \u5bf9DataFrame\u7684\u66f4\u65b0\u3002 df1 = pd.DataFrame(np.arange(4).reshape((2, 2)), columns=list('ab')) print(df1) # a b # 0 0 1 # 1 2 3 # \u6309\u6807\u7b7e\u540d\u66f4\u65b0 df1.loc[1, :'b'] = np.nan print(df1) # a b # 0 0.0 1.0 # 1 NaN NaN","title":"\u6574\u6570\u7d22\u5f15"},{"location":"python/DataAnalysis/ch02/#_6","text":"Pandas\u652f\u6301\u5728Series\u6216\u8005DataFrame\u5bf9\u8c61\u4e4b\u95f4\u8fdb\u884c\u7b97\u672f\u8fd0\u7b97\u3002 \u4f8b\uff1a\u4e24\u4e2aSeries\u505a\u7b97\u672f\u52a0\u6cd5\u3002 \u8fd4\u56de\u7684\u7ed3\u679c\u4e5f\u662f\u4e00\u4e2aSeries\u3002 \u8fd4\u56de\u7ed3\u679c\u7684\u7d22\u5f15\u662f\u6bcf\u4e2aSeries\u7684\u7d22\u5f15\u7684\u5e76\u96c6\u3002 \u51e1\u662f\u6ca1\u6709\u5728\u4e24\u4e2aSeries\u90fd\u51fa\u73b0\u7684\u7d22\u5f15\u4f4d\u7f6e\uff0c\u5185\u90e8\u6570\u636e\u5bf9\u9f50\u4f1a\u586b\u5145\u7f3a\u5931\u503cNaN\u3002\u7f3a\u5931\u503c\u4f1a\u5728\u540e\u7eed\u7684\u5176\u5b83\u7b97\u672f\u64cd\u4f5c\u4e0a\u4ea7\u751f\u5f71\u54cd\u3002 \u540c\u65f6\u51fa\u73b0\u5728\u4e24\u4e2aSeries\u7684\u7d22\u5f15\u4f4d\u7f6e\uff0cSeries\u7684\u503c\u505a\u7b97\u672f\u76f8\u52a0\u3002 s1 = pd.Series( [7.3, -2.5, 3.4, 1.5], index=['a', 'c', 'd', 'e'] ) s2 = pd.Series( [-2.1, 3.6, -1.5, 4, 3.1], index=['a', 'c', 'e', 'f', 'g'] ) print(s1) # a 7.3 # c -2.5 # d 3.4 # e 1.5 # dtype: float64 print(s2) # a -2.1 # c 3.6 # e -1.5 # f 4.0 # g 3.1 # dtype: float64 print(s1 + s2) # a 5.2 # c 1.1 # d NaN # e 0.0 # f NaN # g NaN # dtype: float64 \u4f8b\uff1a\u4e24\u4e2aDataframe\u505a\u7b97\u672f\u52a0\u6cd5 \u8fd4\u56de\u7ed3\u679c\u4e5f\u662f\u4e00\u4e2aDataframe\u3002 \u8fd4\u56de\u7ed3\u679c\u7684\u884c\u5217\u7d22\u5f15\u662f\u6bcf\u4e2aDataFrame\u7684\u884c\u5217\u7d22\u5f15\u7684\u5e76\u96c6\u3002 \u51e1\u662f\u6ca1\u6709\u5728\u4e24\u4e2aDataFrame\u90fd\u51fa\u73b0\u7684\u4f4d\u7f6e\u5c31\u4f1a\u88ab\u7f6e\u4e3aNaN\u3002 \u4e24\u4e2aDataFrame\u90fd\u51fa\u73b0\u7684\u4f4d\u7f6e\uff0c\u5bf9Dataframe\u7684\u503c\u505a\u7b97\u672f\u52a0\u6cd5\u3002 df1 = pd.DataFrame( np.arange(9).reshape((3, 3)), columns=list('bcd'), index=['Ohio', 'Texas', 'Colorado'] ) df2 = pd.DataFrame( np.arange(12).reshape((4, 3)), columns=list('bde'), index=['Utah', 'Ohio', 'Texas', 'Oregon'] ) print(df1) # b c d # Ohio 0 1 2 # Texas 3 4 5 # Colorado 6 7 8 print(df2) # b d e # Utah 0 1 2 # Ohio 3 4 5 # Texas 6 7 8 # Oregon 9 10 11 print(df1 + df2) # b c d e # Colorado NaN NaN NaN NaN # Ohio 3.0 NaN 6.0 NaN # Oregon NaN NaN NaN NaN # Texas 9.0 NaN 12.0 NaN # Utah NaN NaN NaN NaN \u5728Series\u6216\u8005DataFrame\u5bf9\u8c61\u4e4b\u95f4\u8fdb\u884c\u7b97\u672f\u64cd\u4f5c\u65f6\uff0c\u6709\u65f6\u9700\u8981\u5bf9\u7f3a\u5931\u503c\u6307\u5b9a\u586b\u5145\u503c\uff0c\u6bd4\u5982\u5f53\u8f74\u6807\u7b7e\u5728\u4e00\u4e2a\u5bf9\u8c61\u4e2d\u5b58\u5728\uff0c\u5728\u53e6\u4e00\u4e2a\u5bf9\u8c61\u4e2d\u4e0d\u5b58\u5728\u65f6\uff0c\u5c06\u7f3a\u5931\u503c\u586b\u5145\u4e3a0\u3002\u4e5f\u5c31\u662f\u8bf4\uff0c\u5982\u679c\u5728\u4e24\u4e2aDataFrame\u90fd\u7f3a\u5931\uff0c\u90a3\u4e48\u4f9d\u7136\u8fd8\u4f1a\u662fNaN\u3002 \u4e0b\u4f8b\u4e2da2\u662f\u5728 df1 \u548c df2 \u90fd\u7f3a\u5931\u7684\u4f4d\u7f6e\uff0c\u6240\u4ee5\u5373\u4f7f fill_value=0 \uff0ca2\u4ecd\u7136\u662fNaN\u3002 df1 = pd.DataFrame( np.arange(4).reshape((2, 2)), columns=list('ab') ) df2 = pd.DataFrame( np.arange(9).reshape((3, 3)), columns=list('bcd') ) print(df1) # a b # 0 0 1 # 1 2 3 print(df2) # b c d # 0 0 1 2 # 1 3 4 5 # 2 6 7 8 # \u5bf9df1\u548cdf2\u5c31\u7b97\u672f\u548c\uff0c\u5bf9\u5e94\u6ca1\u6709\u884c\u5217\u5171\u540c\u7684\u4ea4\u96c6\u7684\u5730\u65b9\u586b\u5145\u7a7a\u503cNaN\uff0c\u6709\u4ea4\u96c6\u7684\u5730\u65b9\u6c42\u7b97\u672f\u548c\u3002 print(df1.add(df2)) # a b c d # 0 NaN 1.0 NaN NaN # 1 NaN 6.0 NaN NaN # 2 NaN NaN NaN NaN # \u5bf9df1\u548cdf2\u5c31\u7b97\u672f\u548c\uff0c\u5bf9\u5e94\u6ca1\u6709\u884c\u5217\u5171\u540c\u7684\u4ea4\u96c6\u7684\u5730\u65b9\u586b\u5145\u7a7a\u503c0\uff0c\u6709\u4ea4\u96c6\u7684\u5730\u65b9\u6c42\u7b97\u672f\u548c\u3002 print(df1.add(df2, fill_value=0)) # df2.add(df1, fill_value=0) \u8fd4\u56de\u540c\u6837\u7684\u7ed3\u679c # a b c d # 0 0.0 1.0 1.0 2.0 # 1 2.0 6.0 4.0 5.0 # 2 NaN 6.0 7.0 8.0 \u4e0b\u4f8b\u4e2db2\u662f\u5728 df1 \u548c df2 \u90fd\u7f3a\u5931\u7684\u4f4d\u7f6e\uff0c\u6240\u4ee5\u5373\u4f7f fill_value=0 \uff0cb2\u4ecd\u7136\u662fNaN\u3002 df1 = pd.DataFrame( np.arange(4).reshape((2, 2)), columns=list('ab') ) df2 = pd.DataFrame( np.arange(9).reshape((3, 3)), columns=list('acd') ) print(df1) # a b # 0 0 1 # 1 2 3 print(df2) # a c d # 0 0 1 2 # 1 3 4 5 # 2 6 7 8 print(df1.add(df2, fill_value=0)) # a b c d # 0 0.0 1.0 1.0 2.0 # 1 5.0 3.0 4.0 5.0 # 2 6.0 NaN 7.0 8.0 \u4e0b\u4f8b\u4e2d\u6ca1\u6709\u4e24\u4e2aDataFrame\u5171\u540c\u7f3a\u5931\u7684\u60c5\u51b5\u3002 df1 = pd.DataFrame( np.arange(4).reshape((2, 2)), columns=list('ab') ) df2 = pd.DataFrame( np.arange(9).reshape((3, 3)), columns=list('abd') ) print(df1) # a b # 0 0 1 # 1 2 3 print(df2) # a b d # 0 0 1 2 # 1 3 4 5 # 2 6 7 8 print(df1.add(df2, fill_value=0)) # a b d # 0 0.0 2.0 2.0 # 1 5.0 7.0 5.0 # 2 6.0 7.0 8.0 \u4e0b\u9762\u662fSeries\u548cDataFrame\u7684\u7b97\u672f\u65b9\u6cd5\u3002 add\uff0cradd\uff1a\u52a0\u6cd5(+) sub\uff0crsub\uff1a\u51cf\u6cd5(-) div\uff0crdiv\uff1a\u9664\u6cd5(/) floordiv\uff0crfloordiv\uff1a\u6574\u9664(//) mul\uff0crmul\uff1a\u4e58\u6cd5(*) pow\uff0crpow\uff1a\u5e42\u6b21\u65b9(**) \u4e0a\u8ff0\u6bcf\u4e2a\u65b9\u6cd5\u90fd\u6709\u4e00\u4e2a\u4ee5r\u5f00\u5934\u7684\u526f\u672c\uff0c\u8fd9\u4e9b\u526f\u672c\u65b9\u6cd5\u7684\u53c2\u6570\u662f\u7ffb\u8f6c\u7684\u3002\u6bd4\u5982\uff0c\u6c42DataFrame\u5f53\u4e2d\u6240\u6709\u5143\u7d20\u7684\u5012\u6570 1/df \uff0c\u53ef\u4ee5\u5199\u6210df.rdiv(1)\u3002 df1 = pd.DataFrame( np.arange(4).reshape((2, 2)), columns=list('ab') ) df2 = pd.DataFrame( np.arange(9).reshape((3, 3)), columns=list('abd') ) print(df1) # a b # 0 0 1 # 1 2 3 print(df2) # a b d # 0 0 1 2 # 1 3 4 5 # 2 6 7 8 print(df1.radd(df2, fill_value=0)) # a b d # 0 0.0 2.0 2.0 # 1 5.0 7.0 5.0 # 2 6.0 7.0 8.0 print(df1.sub(df2, fill_value=0)) # a b d # 0 0.0 0.0 -2.0 # 1 -1.0 -1.0 -5.0 # 2 -6.0 -7.0 -8.0 print(df1.div(df2, fill_value=0)) # a b d # 0 NaN 1.00 0.0 # 1 0.666667 0.75 0.0 # 2 0.000000 0.00 0.0 print(df1.floordiv(df2, fill_value=0)) # a b d # 0 NaN 1.0 0.0 # 1 0.0 0.0 0.0 # 2 0.0 0.0 0.0 print(df1.mul(df2, fill_value=0)) # a b d # 0 0.0 1.0 0.0 # 1 6.0 12.0 0.0 # 2 0.0 0.0 0.0 print(df1.pow(df2, fill_value=0)) # a b d # 0 1.0 1.0 0.0 # 1 8.0 81.0 0.0 # 2 0.0 0.0 0.0","title":"\u7b97\u672f\u548c\u6570\u636e\u5bf9\u9f50"},{"location":"python/DataAnalysis/ch02/#dataframeseries","text":"DataFrame\u548cSeries\u95f4\u7684\u7b97\u672f\u64cd\u4f5c\u4e0eNumPy\u4e2d\u4e0d\u540c\u7ef4\u5ea6\u6570\u7ec4\u95f4\u7684\u64cd\u4f5c\u7c7b\u4f3c\u3002","title":"DataFrame\u548cSeries\u95f4\u7684\u7b97\u672f\u64cd\u4f5c"},{"location":"python/DataAnalysis/ch02/#numpy","text":"\u4ecearr\u4e2d\u51cf\u53bbarr[0]\u65f6\uff0c\u51cf\u6cd5\u6cbf0\u8f74\u5728\u6bcf\u4e00\u884c\u90fd\u8fdb\u884c\u4e86\u64cd\u4f5c\u3002\u8fd9\u5c31\u662f\u6240\u8c13\u7684\u5e7f\u64ad\u673a\u5236\u3002 arr = np.arange(12).reshape((3, 4)) print(arr) # [[ 0 1 2 3] # [ 4 5 6 7] # [ 8 9 10 11]] print(arr[0]) # [0 1 2 3] print(arr - arr[0]) # [[0 0 0 0] # [4 4 4 4] # [8 8 8 8]]","title":"\u4e0d\u540c\u7ef4\u5ea6NumPy\u6570\u7ec4\u95f4\u7684\u7b97\u672f\u64cd\u4f5c"},{"location":"python/DataAnalysis/ch02/#dataframeseries_1","text":"\u9ed8\u8ba4\u60c5\u51b5\u4e0b\uff0cDataFrame\u548cSeries\u7684\u6570\u5b66\u64cd\u4f5c\u4e2d\u4f1a\u5c06Series\u7684\u7d22\u5f15\u548cDataFrame\u7684*\u5217*\u8fdb\u884c\u5339\u914d\uff0c\u5e76*\u5e7f\u64ad\u5230\u5404\u884c*. \u5982\u679c\u4e00\u4e2a\u7d22\u5f15\u503c\u4e0d\u5728DataFrame\u7684\u5217\u4e2d\uff0c\u4e5f\u4e0d\u5728Series\u7684\u7d22\u5f15\u4e2d\uff0c\u5219\u65b0\u5bf9\u8c61\u4f1a\u6784\u5efa\u5e76\u96c6\u7d22\u5f15\u3002 frame = pd.DataFrame( np.arange(12).reshape((4, 3)), columns=list('bde'), index=['Utah', 'Ohio', 'Texas', 'Oregon'] ) print(frame) # b d e # Utah 0 1 2 # Ohio 3 4 5 # Texas 6 7 8 # Oregon 9 10 11 # \u622a\u53d6frame\u7684\u7b2c0\u884c\uff0c\u5217\u6807\u7b7e\u53d8\u6210\u65b0Serise\u7684\u7d22\u5f15\u3002 series = frame.iloc[0] print(series) # b 0 # d 1 # e 2 # Name: Utah, dtype: int64 series2 = pd.Series( range(3), index=list('bef') ) print(series2) # b 0 # e 1 # f 2 # dtype: int64 # \u622a\u53d6frame\u7684d\u5217\uff0c\u884c\u6807\u7b7e\u53d8\u6210\u65b0Serise\u7684\u7d22\u5f15\u3002 series3 = frame['d'] print(series3) # Utah 1 # Ohio 4 # Texas 7 # Oregon 10 # Name: d, dtype: int64 # \u5c06Series\u7684\u7d22\u5f15\u548cDataFrame\u7684\u5217\u6807\u7b7e\u8fdb\u884c\u5339\u914d\uff0cSeries\u7684\u503c\u6cbfDataFrame\u76840\u8f74\u5e7f\u64ad\u5230\u5404\u4e2a\u884c\u3002 print(frame - series) # frame: series Result: # b d e # b 0 # b d e # Utah 0 1 2 # d 1 # Utah 0 0 0 # Ohio 3 4 5 # e 2 # Ohio 3 3 3 # Texas 6 7 8 # Name: Utah, dtype: int64 # Texas 6 6 6 # Oregon 9 10 11 # Oregon 9 9 9 # \u5c06Series\u7684\u7d22\u5f15\u548cDataFrame\u7684\u5217\u6807\u7b7e\u8fdb\u884c\u5339\u914d\uff0cSeries\u7684\u503c\u6cbfDataFrame\u76840\u8f74\u5e7f\u64ad\u5230\u5404\u4e2a\u884c\uff0c\u7f3a\u5931\u4f4d\u7f6e\u586b\u5145\u7a7a\u503cNaN\u3002 print(frame - series2) # frame: series2 Result: # b d e # b 0 # b d e f # Utah 0 1 2 # e 1 # Utah 0.0 NaN 1.0 NaN # Ohio 3 4 5 # f 2 # Ohio 3.0 NaN 4.0 NaN # Texas 6 7 8 # dtype: int64 # Texas 6.0 NaN 7.0 NaN # Oregon 9 10 11 # Oregon 9.0 NaN 10.0 NaN # \u6539\u4e3a\u5728\u5217\u4e0a\u8fdb\u884c\u5e7f\u64ad\uff0c\u5728\u884c\u4e0a\u5339\u914d\uff0c\u5fc5\u987b\u4f5c\u7528\u5728\u67d0\u79cd\u7b97\u672f\u65b9\u6cd5\u4e0a\u3002\u4e0b\u4f8b\u4e2dSeries\u7684\u503c\u6cbfDataFrame\u76840\u8f74\u5e7f\u64ad\u5230\u5404\u4e2a\u884c\uff08\u6309index\u5339\u914d\u8fdb\u884c\u884c\u64cd\u4f5c\uff09\u3002 print(frame.sub(series3, axis='index')) # \u6216axis=0 # frame: series3 Result: # b d e # Utah 1 # b d e # Utah 0 1 2 # Ohio 4 # Utah -1 0 1 # Ohio 3 4 5 # Texas 7 # Ohio -1 0 1 # Texas 6 7 8 # Oregon 10 # Texas -1 0 1 # Oregon 9 10 11 # Name: d, dtype: int64 # Oregon -1 0 1","title":"DataFrame\u548cSeries\u95f4\u7684\u7b97\u672f\u64cd\u4f5c"},{"location":"python/DataAnalysis/ch02/#_7","text":"NumPy\u7684\u901a\u7528\u51fd\u6570\uff08\u9010\u5143\u7d20\u6570\u7ec4\u65b9\u6cd5\uff09\u5bf9pandas\u5bf9\u8c61\uff08DataFrame\u548cSeries\uff09\u4e5f\u6709\u6548\u3002 frame = pd.DataFrame( np.random.randn(4, 3), columns=list('bde'), index=['Utah', 'Ohio', 'Texas', 'Oregon'] ) print(frame) # b d e # Utah 2.737734 -0.379977 0.758933 # Ohio 0.847497 0.839583 -2.192021 # Texas -0.907544 -0.457436 -1.907396 # Oregon 0.389362 0.250170 1.065889 # \u5bf9DataFrame\u5bf9\u8c61\u8ba1\u7b97\u7edd\u5bf9\u503c\u3002 print(np.abs(frame)) # b d e # Utah 2.737734 0.379977 0.758933 # Ohio 0.847497 0.839583 2.192021 # Texas 0.907544 0.457436 1.907396 # Oregon 0.389362 0.250170 1.065889 # f\u8fd4\u56de\u4e00\u4e2a\u6807\u91cf\u503c f = lambda x: x.max() - x.min() # \u6cbf0\u8f74\u5e94\u7528f\uff08\u5bf9\u6bcf\u5217\u7684\u6240\u6709\u884c\u5143\u7d20\u8fdb\u884cf\u8ba1\u7b97\uff09, \u9ed8\u8ba4axis=0 print(frame.apply(f)) # b 3.645278 # d 1.297019 # e 3.257911 # dtype: float64 # \u6cbf1\u8f74\u5e94\u7528f\uff08\u5bf9\u6bcf\u884c\u7684\u6240\u6709\u5217\u5143\u7d20\u8fdb\u884cf\u8ba1\u7b97\uff09 print(frame.apply(f, axis=1)) # Utah 3.117711 # Ohio 3.039518 # Texas 1.449961 # Oregon 0.815720 # dtype: float64 # \u5b9a\u4e49\u51fd\u6570f\uff0c\u8fd4\u56de\u5e26\u6709\u591a\u4e2a\u503c\u7684Series\u3002 def f(x): return pd.Series( [x.min(), x.max()], index=['min', 'max'] ) print(frame.apply(f)) # b d e # min -0.907544 -0.457436 -2.192021 # max 2.737734 0.839583 1.065889 # \u5b9a\u4e49\u51fd\u6570f\uff0c\u4f7f\u7528applymap\u65b9\u6cd5\u683c\u5f0f\u5316\u5b57\u7b26\uff0c\u5c06\u4e00\u4e2a\u9010\u5143\u7d20\u7684\u51fd\u6570\u5e94\u7528\u5230Series\u4e0a\u3002 f = lambda x: '%.2f' % x print(frame.applymap(f)) # # b d e # Utah 2.74 -0.38 0.76 # Ohio 0.85 0.84 -2.19 # Texas -0.91 -0.46 -1.91 # Oregon 0.39 0.25 1.07 print(frame['e'].map(f)) # Utah 0.76 # Ohio -2.19 # Texas -1.91 # Oregon 1.07 # Name: e, dtype: object","title":"\u51fd\u6570\u5e94\u7528\u548c\u6620\u5c04"},{"location":"python/DataAnalysis/ch02/#_8","text":"\u4f7f\u7528sort_index\u65b9\u6cd5\uff0c\u6309\u884c\u6216\u5217\u7d22\u5f15\u8fdb\u884c\u5b57\u5178\u578b\u6392\u5e8f\uff0c\u8fd4\u56de\u4e00\u4e2a\u65b0\u7684\u6392\u5e8f\u597d\u7684Pandas\u5bf9\u8c61\u3002","title":"\u6392\u5e8f\u548c\u6392\u540d"},{"location":"python/DataAnalysis/ch02/#series_1","text":"\u5bf9Series\u8fdb\u884c\u7d22\u5f15\u6392\u5e8f\u548c\u503c\u6392\u5e8f\u3002 obj = pd.Series( range(4), index=list('dabc') ) print(obj) # d 0 # a 1 # b 2 # c 3 # dtype: int64 print(obj.sort_index()) # a 1 # b 2 # c 3 # d 0 # dtype: int64 # print(obj.sort_values()) # d 0 # a 1 # b 2 # c 3 # dtype: int64 \u9ed8\u8ba4\u60c5\u51b5\u4e0b\uff0c\u6240\u6709\u7684\u7f3a\u5931\u503c\u90fd\u4f1a\u88ab\u6392\u5e8f\u81f3Series\u7684\u5c3e\u90e8\u3002 obj = pd.Series([4, np.nan, 7, np.nan, -3, 2]) print(obj) # 0 4.0 # 1 NaN # 2 7.0 # 3 NaN # 4 -3.0 # 5 2.0 # dtype: float64 print(obj.sort_values()) # 4 -3.0 # 5 2.0 # 0 4.0 # 2 7.0 # 1 NaN # 3 NaN # dtype: float64","title":"Series\u6392\u5e8f"},{"location":"python/DataAnalysis/ch02/#dataframe_3","text":"frame = pd.DataFrame( [[0, 1, 10, 3], [4, 5, 6, 21], [8, 9, 2, 21]], index=['three', 'one', 'five'], columns=list('dabc') ) print(frame) # d a b c # three 0 1 10 3 # one 4 5 6 21 # five 8 9 2 21 print(frame.index) # Index(['three', 'one', 'five'], dtype='object') # \u9ed8\u8ba40\u8f74\uff0c\u6240\u6709\u884c\u8fdb\u884c\u7d22\u5f15\u9996\u5b57\u6bcd\u5347\u5e8f print(frame.sort_index()) # d a b c # five 8 9 2 21 # one 4 5 6 21 # three 0 1 10 3 # \u6307\u5b9a0\u8f74\uff0c\u6240\u6709\u884c\u8fdb\u884c\u7d22\u5f15\u9996\u5b57\u6bcd\u5347\u5e8f print(frame.sort_index(axis=0)) # d a b c # five 8 9 2 21 # one 4 5 6 21 # three 0 1 10 3 # \u6307\u5b9a0\u8f74\uff0c\u6240\u6709\u884c\u8fdb\u884c\u7d22\u5f15\u9996\u5b57\u6bcd\u964d\u5e8f print(frame.sort_index(axis=0, ascending=False)) # d a b c # three 0 1 10 3 # one 4 5 6 21 # five 8 9 2 21 # \u6307\u5b9a1\u8f74\uff0c\u6240\u6709\u5217\u8fdb\u5217\u7d22\u5f15\u9996\u5b57\u6bcd\u5347\u5e8f print(frame.sort_index(axis=1)) # a b c d # three 1 10 3 0 # one 5 6 21 4 # five 9 2 21 8 # \u6307\u5b9a1\u8f74\uff0c\u6240\u6709\u5217\u8fdb\u5217\u7d22\u5f15\u9996\u5b57\u6bcd\u964d\u5e8f print(frame.sort_index(axis=1, ascending=False)) # d c b a # three 0 3 10 1 # one 4 21 6 5 # five 8 21 2 9 # \u6309\u6307\u5b9a\u5355\u5217\u8fdb\u884c\u503c\u6392\u5e8f\uff08\u964d\u5e8f\uff09 print(frame.sort_values(by=['c'], ascending=False)) # d a b c # one 4 5 6 21 # five 8 9 2 21 # three 0 1 10 3 # \u6309\u6307\u5b9a\u591a\u5217\u8fdb\u884c\u503c\u6392\u5e8f\uff08\u964d\u5e8f\uff09\uff0c\u5148\u5bf9b\u964d\u5e8f\uff0c\u518d\u5bf9d\u964d\u5e8f print(frame.sort_values(by=['c', 'd'], ascending=False)) # d a b c # five 8 9 2 21 # one 4 5 6 21 # three 0 1 10 3","title":"DataFrame\u6392\u5e8f"},{"location":"python/DataAnalysis/ch02/#_9","text":"**\u6392\u540d**\u662f\u6307\u5bf9\u6570\u7ec4\u4ece1\u5230\u6709\u6548\u6570\u636e\u70b9\u603b\u6570\u5206\u914d\u540d\u6b21\u7684\u64cd\u4f5c\u3002 Series\u548cDataFrame\u7684 rank \u65b9\u6cd5\u662f\u5b9e\u73b0\u6392\u540d\u7684\u65b9\u6cd5\uff0c df.rank(ascending=False, method='max') \u3002 ascending \uff1a\u6392\u540d\u65b9\u5f0f\uff0c\u9ed8\u8ba4\u4ece\u4f4e\u5230\u9ad8\uff0c ascending=False \u8868\u793a\u4ece\u9ad8\u5230\u4f4e\uff1b method \uff1a\u6392\u540d\u65b9\u5f0f\uff0c\u5305\u62ec\uff1a average:\u9ed8\u8ba4\uff0c\u5728\u76f8\u7b49\u5206\u7ec4\u4e2d\uff0c\u4e3a\u5404\u4e2a\u503c\u5206\u914d\u5e73\u5747\u6392\u540d\uff0c\u5373\u76f8\u540c\u503c\u7684\u548c\u9664\u4ee5\u8be5\u503c\u7684\u4e2a\u6570\uff0c\u5373\u4e3a\u8be5\u503c\u7684\u540d\u6b21\u3002 min:\u4f7f\u7528\u6574\u4e2a\u5206\u7ec4\u7684\u6700\u5c0f\u6392\u540d\uff0c\u5373\uff0c\u5bf9\u5e94\u76f8\u540c\u503c\uff0c\u53d6\u5728\u987a\u5e8f\u6392\u540d\u4e2d\u6700\u5c0f\u7684\u90a3\u4e2a\u6392\u540d\u4f5c\u4e3a\u6240\u6709\u8be5\u503c\u7684\u6392\u540d\u3002 max:\u4f7f\u7528\u6574\u4e2a\u5206\u7ec4\u7684\u6700\u5927\u6392\u540d\uff0c\u5373\uff0c\u5bf9\u5e94\u76f8\u540c\u503c\uff0c\u53d6\u5728\u987a\u5e8f\u6392\u540d\u4e2d\u6700\u5927\u7684\u90a3\u4e2a\u6392\u540d\u4f5c\u4e3a\u6240\u6709\u8be5\u503c\u7684\u6392\u540d\u3002 first:\u6309\u503c\u518d\u539f\u59cb\u6570\u636e\u4e2d\u51fa\u73b0\u987a\u5e8f\u5206\u914d\u6392\u540d\uff0c\u8c01\u51fa\u73b0\u7684\u4f4d\u7f6e\u9760\u524d\uff0c\u8c01\u7684\u6392\u540d\u9760\u524d\u3002 dense:\u7c7b\u4f3cmin\u65b9\u6cd5\uff0c\u4f46\u6392\u540d\u603b\u662f\u5728\u7ec4\u95f4\u589e\u52a01\uff0c\u800c\u4e0d\u662f\u7ec4\u4e2d\u76f8\u540c\u7684\u5143\u7d20\u6570\uff0c\u5373\u76f8\u540c\u503c\u7684\u6392\u540d\u76f8\u540c\uff0c\u5176\u4ed6\u4f9d\u6b21\u52a01\u5373\u53ef\u3002 \u9ed8\u8ba4\u60c5\u51b5\u4e0b\uff0crank\u662f\u901a\u8fc7\u201c\u4e3a\u5404\u7ec4\u5206\u914d\u4e00\u4e2a\u5e73\u5747\u6392\u540d\u201d\u7684\u65b9\u5f0f\u7834\u574f\u5e73\u7ea7\u5173\u7cfb # \u6309\u7167\u6bcf\u4e2a\u5143\u7d20\u7684\u5927\u5c0f\u987a\u5e8f\u7ed9\u51fa\u4e00\u4e2a\u5e73\u5747\u6392\u540d obj = pd.Series([7, -5, 7, 4, 2, 0, 4]) print(obj) # 0 7 # 1 -5 # 2 7 # 3 4 # 4 2 # 5 0 # 6 4 # dtype: int64 print(obj.rank()) # 0 6.5 # 1 1.0 # 2 6.5 # 3 4.5 # 4 3.0 # 5 2.0 # 6 4.5 # dtype: float64 # index value rank # 2 -5 1 # 6 0 2 # 5 2 3 # 4 4 4.5 # 7 4 4.5 # 1 7 6.5 # 3 7 6.5 # \u6839\u636e\u5143\u7d20\u7684\u89c2\u5bdf\u987a\u5e8f\u8fdb\u884c\u5206\u914d\u3002\u5143\u7d200\u548c2\u6ca1\u6709\u4f7f\u7528\u5e73\u5747\u6392\u540d6.5\uff0c\u5b83\u4eec\u88ab\u8bbe\u6210\u4e866\u548c7\uff0c\u56e0\u4e3a\u6570\u636e\u4e2d\u6807\u7b7e0\u4f4d\u4e8e\u6807\u7b7e2\u7684\u524d\u9762\u3002 print(obj.rank(method='first')) # 0 6.0 # 1 1.0 # 2 7.0 # 3 4.0 # 4 3.0 # 5 2.0 # 6 5.0 # dtype: float64 # \u6309\u7167max\u8fdb\u884c\u5347\u5e8f\u548c\u964d\u5e8f print(obj.rank(ascending=False, method='max')) print(obj.rank(ascending=True, method='max')) # Original Series Max with inc Max with dec # 0 7 # 0 2.0 (\u6700\u5c0f) # 0 7.0 (\u6700\u5927) # 1 -5 # 1 7.0 (\u6700\u5927) # 1 1.0 (\u6700\u5c0f) # 2 7 # 2 2.0 (\u6700\u5c0f) # 2 7.0 (\u6700\u5927) # 3 4 # 3 4.0 # 3 5.0 # 4 2 # 4 5.0 # 4 3.0 # 5 0 # 5 6.0 # 5 2.0 # 6 4 # 6 4.0 # 6 5.0 # dtype: float64 # dtype: float64 # dtype: float64 frame = pd.DataFrame( {'b': [4.3, 7, -3, 2], 'a': [0, 1, 0, 1], 'c': [-2, 5, 8, -2]} ) print(frame) # b a c # 0 4.3 0 -2 # 1 7.0 1 5 # 2 -3.0 0 8 # 3 2.0 1 -2 # \u6cbf1\u8f74\u5bf9DataFrame\u8fdb\u884crank\u64cd\u4f5c\uff0c\u5373\uff0c\u6bcf\u4e00\u884c\u5404\u5143\u7d20\u8fdb\u884crank\u3002 print(frame.rank(axis='columns')) # axis=1 # b a c # 0 3.0 2.0 1.0 # 1 3.0 1.0 2.0 # 2 1.0 2.0 3.0 # 3 3.0 2.0 1.0","title":"\u6392\u540d"},{"location":"python/DataAnalysis/ch02/#_10","text":"\u5c3d\u7ba1\u5f88\u591apandas\u51fd\u6570\uff08\u6bd4\u5982reindex\uff09\u9700\u8981\u6807\u7b7e\u662f\u552f\u4e00\u7684\uff0c\u4f46\u8fd9\u4e2a\u5e76\u4e0d\u662f\u5f3a\u5236\u6027\u7684\u3002 \u7d22\u5f15\u7684is_unique\u5c5e\u6027\u53ef\u4ee5\u68c0\u67e5\u6807\u7b7e\u662f\u5426\u552f\u4e00\u3002 \u5e26\u6709\u91cd\u590d\u7d22\u5f15\u7684\u60c5\u51b5\u4e0b\uff0c\u4e00\u4e2a\u7d22\u5f15\u6807\u7b7e\u4f1a\u4ee5\u5e8f\u5217\u65b9\u5f0f\u8fd4\u56de\u591a\u4e2a\u6761\u76ee\u3002\u4e0d\u91cd\u590d\u7684\u7d22\u5f15\u5219\u4f1a\u4ee5\u6807\u91cf\u503c\u7684\u5f62\u5f0f\u8fd4\u56de\u5355\u4e2a\u6761\u76ee\uff0c\u8fd9\u53ef\u80fd\u4f1a\u4f7f\u4ee3\u7801\u66f4\u590d\u6742\u3002 obj = pd.Series(range(5), index=['a', 'b', 'a', 'c', 'b']) print(obj) # a 0 # b 1 # a 2 # c 3 # b 4 # dtype: int64 print(obj.is_unique) # True print(obj.index.is_unique) # False # \u8fd4\u56de\u91cd\u590d\u7d22\u5f15\u5bf9\u5e94\u503c\u7684\u5e8f\u5217\u3002 print(obj['a']) # a 0 # a 2 # dtype: int64 df = pd.DataFrame(np.random.randn(4, 3), index=['a', 'a', 'b', 'b']) print(df) # 0 1 2 # a -0.726164 0.531540 -0.521611 # a -1.539807 -0.710880 -0.992789 # b -0.975970 -0.470725 0.121958 # b -0.301495 1.072322 -1.542296 print(df.index.is_unique) # False print(df.loc['b']) # 0 1 2 # b -0.520008 0.052574 0.638529 # b -1.928705 -1.099534 -1.605296","title":"\u542b\u6709\u91cd\u590d\u6807\u7b7e\u7684\u8f74\u7d22\u5f15"},{"location":"python/DataAnalysis/ch02/#_11","text":"pandas\u5305\u542b\u4e86\u4e00\u4e9b\u5e38\u7528\u6570\u5b66\u3001\u7edf\u8ba1\u5b66\u65b9\u6cd5\u3002\u5176\u4e2d\u5927\u90e8\u5206\u5c5e\u4e8e\u5f52\u7ea6\u6216\u6c47\u603b\u7edf\u8ba1\u7684\u7c7b\u522b\uff0c\u8fd9\u4e9b\u65b9\u6cd5\u4eceDataFrame\u7684\u884c\u6216\u5217\u4e2d\u62bd\u53d6\u4e00\u4e2aSeries\u6216\u4e00\u7cfb\u5217\u503c\uff08\u5982\u603b\u548c\u6216\u5e73\u5747\u503c\uff09\u3002 \u4e0eNumPy\u6570\u7ec4\u4e2d\u7684\u7c7b\u4f3c\u65b9\u6cd5\u76f8\u6bd4\uff0cpandas\u5185\u5efa\u4e86\u5904\u7406\u7f3a\u5931\u503c\u7684\u529f\u80fd\u3002 \u5f52\u7ea6\u65b9\u6cd5: sum() \u79ef\u7d2f\u578b\u65b9\u6cd5: cumsun() \u65e2\u4e0d\u662f\u5f52\u7ea6\u578b\u65b9\u6cd5\u4e5f\u4e0d\u662f\u79ef\u7d2f\u578b\u65b9\u6cd5: describe() df = pd.DataFrame( [[1.4, np.nan], [7.1, -4.5], [np.nan, np.nan], [0.75, -1.3]], index=list('abcd'), columns=['one', 'two'] ) print(df) # one two # a 1.40 NaN # b 7.10 -4.5 # c NaN NaN # d 0.75 -1.3 # axis=0, \u8fd4\u56de\u4e00\u4e2a\u6bcf\u5217\u7b97\u672f\u548c\u7684Series print(df.sum()) # one 9.25 # two -5.80 # dtype: float64 # axis=1\u4e14skipna=True, \u8fd4\u56de\u4e00\u4e2a\u6bcf\u884c\u548c\u7684Series, \u5ffd\u7565NA\u503c, \u586b0\u3002 print(df.sum(axis=1)) # a 1.40 # b 2.60 # c 0.00 # d -0.55 # dtype: float64 # \u4e0d\u5ffd\u7565NA\u503c\uff0c\u586bNaN\u3002 print(df.sum(axis=1, skipna=False)) # a NaN # b 2.60 # c NaN # d -0.55 # dtype: float64 # \u53ea\u67091\u7ea7\u7d22\u5f15\uff0c\u6240\u4ee5level=0\u548c\u539f\u7d22\u5f15\u6ca1\u6709\u533a\u522b\uff0cNaN\u586b\u51450\u3002 print(df.groupby(level=0).sum()) # one two # a 1.40 0.0 # b 7.10 -4.5 # c 0.00 0.0 # d 0.75 -1.3 # \u5217one\u7684\u6700\u5927\u503c\u662f\u5728\u7d22\u5f15b, \u5217two\u7684\u6700\u5927\u503c\u662f\u5728\u7d22\u5f15d print(df.idxmax()) # one b # two d # dtype: object print(df.idxmin()) # one d # two b # dtype: object # cumsun\u7684\u610f\u601d\u662f\u7b2cn\u6b21\u7684\u548c\u662fn-1\u6b21\u7684\u548c\u4e0en\u7684\u548c\uff0cone\u5217d\u884c\u7684\u548c\u5c31\u662fone\u5217a\u3001b\u3001c\u3001d\u503c\u7684\u603b\u548c\u3002 print(df.cumsum()) # one two # a 1.40 NaN # b 8.50 -4.5 # c NaN NaN # d 9.25 -5.8 \u901a\u8fc7describe\u4ea7\u751f\u7edf\u8ba1\u4fe1\u606f\uff0c\u6ce8\u610f\uff0c\u6570\u503c\u578b\u548c\u975e\u6570\u503c\u578b\u7684describe\u7684\u4fe1\u606f\u662f\u4e0d\u540c\u7684\u3002 # \u4e00\u6b21\u6027\u4ea7\u751f\u591a\u4e2a\u6c47\u603b\u7edf\u8ba1 print(df.describe()) # one two # count 3.000000 2.000000 # mean 3.083333 -2.900000 # std 3.493685 2.262742 # min 0.750000 -4.500000 # 25% 1.075000 -3.700000 # 50% 1.400000 -2.900000 # 75% 4.250000 -2.100000 # max 7.100000 -1.300000 obj = pd.Series(['a', 'a', 'b', 'c'] * 4) print(obj) # 0 a # 1 a # 2 b # 3 c # 4 a # 5 a # 6 b # 7 c # 8 a # 9 a # 10 b # 11 c # 12 a # 13 a # 14 b # 15 c # dtype: object # \u9488\u5bf9\u975e\u6570\u503c\u578b\u6570\u636e\uff0cdescribe\u4ea7\u751f\u53e6\u4e00\u79cd\u6c47\u603b\u7edf\u8ba1 print(obj.describe()) # count 16 # unique 3 # top a # freq 8 # dtype: object","title":"\u63cf\u8ff0\u6027\u7edf\u8ba1\u6982\u8ff0\u4e0e\u8ba1\u7b97"},{"location":"python/DataAnalysis/ch02/#_12","text":"\u534f\u65b9\u5dee\u4e0e\u76f8\u5173\u7cfb\u6570\u4e5f\u662f\u5728\u65f6\u57df\u5206\u6790\u65f6\u5e38\u89c1\u7684\u4e24\u4e2a\u6982\u5ff5\uff0c\u4ed6\u4eec\u90fd\u662f\u7528\u6765\u63cf\u8ff0\u6570\u636e\u201c\u50cf\u4e0d\u50cf\u201d\u7684\u3002 \u534f\u65b9\u5dee\u7684\u901a\u4fd7\u7406\u89e3\uff1a \u4e24\u4e2a\u53d8\u91cf\u5728\u53d8\u5316\u8fc7\u7a0b\u4e2d\u662f\u540c\u65b9\u5411\u53d8\u5316\u8fd8\u662f\u53cd\u65b9\u5411\u53d8\u5316\uff1f\u76f8\u540c\u6216\u8005\u76f8\u53cd\u7a0b\u5ea6\u5982\u4f55\uff1f \u4f60\u53d8\u5927\uff0c\u540c\u65f6\u6211\u53d8\u5927\uff0c\u8bf4\u660e\u4e24\u4e2a\u53d8\u91cf\u662f\u540c\u5411\u53d8\u5316\uff0c\u8fd9\u65f6\u534f\u65b9\u5dee\u5c31\u662f\u6b63\u7684\u3002 \u4f60\u53d8\u5927\uff0c\u540c\u65f6\u6211\u53d8\u5c0f\uff0c\u8bf4\u660e\u4e24\u4e2a\u53d8\u91cf\u662f\u53cd\u5411\u53d8\u5316\uff0c\u8fd9\u65f6\u534f\u65b9\u5dee\u5c31\u662f\u8d1f\u7684\u3002 \u4ece\u6570\u503c\u770b\uff0c\u534f\u65b9\u5dee\u7684\u6570\u503c\u8d8a\u5927\uff0c\u4e24\u4e2a\u53d8\u91cf\u540c\u5411\u7a0b\u5ea6\u4e5f\u5c31\u8d8a\u5927\u3002\u53cd\u4e4b\u4ea6\u7136\u3002 \u76f8\u5173\u7cfb\u6570\u7684\u901a\u4fd7\u7406\u89e3\uff1a \u7528X\uff0cY\u7684\u534f\u65b9\u5dee\u9664\u4ee5X\u7684\u6807\u51c6\u5dee\u548cY\u7684\u6807\u51c6\u5dee\u3002\u76f8\u5173\u7cfb\u6570\u4e5f\u53ef\u4ee5\u770b\u6210\u534f\u65b9\u5dee\uff0c\u4e00\u79cd\u63d0\u51fa\u4e86\u4e24\u4e2a\u53d8\u91cf\u91cf\u7eb2\u5f71\u54cd\u3001\u6807\u51c6\u5316\u540e\u7684\u7279\u6b8a\u534f\u65b9\u5dee\u3002\u6240\u4ee5\uff1a\u4e5f\u53ef\u4ee5\u53cd\u6620\u4e24\u4e2a\u53d8\u91cf\u53d8\u5316\u65f6\u662f\u540c\u5411\u8fd8\u662f\u53cd\u5411\uff0c\u5982\u679c\u540c\u5411\u53d8\u5316\u5c31\u4e3a\u6b63\uff0c\u53cd\u5411\u53d8\u5316\u5c31\u4e3a\u8d1f\u3002 \u7531\u4e8e\u662f\u6807\u51c6\u7248\u540e\u7684\u534f\u65b9\u5dee\uff0c\u76f8\u5173\u7cfb\u6570\u6d88\u9664\u4e86\u4e24\u4e2a\u53d8\u91cf\u53d8\u5316\u5e45\u5ea6\u7684\u5f71\u54cd\uff0c\u800c\u53ea\u662f\u5355\u7eaf\u53cd\u5e94\u4e24\u4e2a\u53d8\u91cf\u6bcf\u5355\u4f4d\u53d8\u5316\u65f6\u7684\u76f8\u4f3c\u7a0b\u5ea6\u3002 \u603b\u7ed3\uff1a \u5bf9\u4e8e\u4e24\u4e2a\u53d8\u91cfX\u3001Y\uff0c \u5f53\u4ed6\u4eec\u7684\u76f8\u5173\u7cfb\u6570\u4e3a1\u65f6\uff0c\u8bf4\u660e\u4e24\u4e2a\u53d8\u91cf\u53d8\u5316\u65f6\u7684\u6b63\u5411\u76f8\u4f3c\u5ea6\u6700\u5927\u3002 \u5f53\u4ed6\u4eec\u7684\u76f8\u5173\u7cfb\u6570\u4e3a\uff0d1\u65f6\uff0c\u8bf4\u660e\u4e24\u4e2a\u53d8\u91cf\u53d8\u5316\u7684\u53cd\u5411\u76f8\u4f3c\u5ea6\u6700\u5927\u3002 \u968f\u7740\u4ed6\u4eec\u76f8\u5173\u7cfb\u6570\u51cf\u5c0f\uff0c\u4e24\u4e2a\u53d8\u91cf\u53d8\u5316\u65f6\u7684\u76f8\u4f3c\u5ea6\u4e5f\u53d8\u5c0f\uff0c\u5f53\u76f8\u5173\u7cfb\u6570\u4e3a0\u65f6\uff0c\u4e24\u4e2a\u53d8\u91cf\u7684\u53d8\u5316\u8fc7\u7a0b\u6ca1\u6709\u4efb\u4f55\u76f8\u4f3c\u5ea6\uff0c\u4e5f\u5373\u4e24\u4e2a\u53d8\u91cf\u65e0\u5173\u3002 \u5f53\u76f8\u5173\u7cfb\u6570\u7ee7\u7eed\u53d8\u5c0f\uff0c\u5c0f\u4e8e0\u65f6\uff0c\u4e24\u4e2a\u53d8\u91cf\u5f00\u59cb\u51fa\u73b0\u53cd\u5411\u7684\u76f8\u4f3c\u5ea6\uff0c\u968f\u7740\u76f8\u5173\u7cfb\u6570\u7ee7\u7eed\u53d8\u5c0f\uff0c\u53cd\u5411\u76f8\u4f3c\u5ea6\u4f1a\u9010\u6e10\u53d8\u5927\u3002 \u4e0b\u9762\u7684\u4f8b\u5b50\u4f7f\u7528 pandas-datareader\uff1a https://pypi.org/project/pandas-datareader/ https://pydata.github.io/pandas-datareader/) \u5728\u6240\u6709\u4f8b\u5b50\u4e2d\uff0c\u5728\u8ba1\u7b97\u76f8\u5173\u6027\u4e4b\u524d\uff0c\u6570\u636e\u70b9\u5df2\u7ecf\u6309\u6807\u7b7e\u8fdb\u884c\u4e86\u5bf9\u9f50\u3002 \u4e0b\u4f8b\u9700\u8981\u901a\u8fc7pandas-datareader\u5e93\u4eceYahoo! Finance\u4e0a\u83b7\u53d6\u7684\u5305\u542b\u80a1\u4ef7\u548c\u4ea4\u6613\u91cf\u7684DataFrame\u3002 import pandas_datareader.data as web all_data = { ticker: web.get_data_yahoo(ticker) for ticker in ['AAPL', 'IBM', 'MSFT', 'GOOG'] } price = pd.DataFrame( { ticker: data['Adj Close'] for ticker, data in all_data.items() } ) volume = pd.DataFrame( { ticker: data['Volume'] for ticker, data in all_data.items() } ) returns = price.pct_change() print(returns.tail()) # AAPL IBM MSFT GOOG # Date # 2021-08-09 -0.000342 -0.008424 -0.003904 0.007049 # 2021-08-10 -0.003354 0.000920 -0.006555 0.000685 # 2021-08-11 0.001786 0.005305 0.001781 -0.002947 # 2021-08-12 0.020773 0.006614 0.009967 0.005084 # 2021-08-13 0.001410 0.000769 0.010490 0.000119 Series\u7684corr\u65b9\u6cd5\u8ba1\u7b97\u7684\u662f\u4e24\u4e2aSeries\u4e2d\u91cd\u53e0\u7684\u3001\u975eNA\u7684\u3001\u6309\u7d22\u5f15\u5bf9\u9f50\u7684\u503c\u7684\u76f8\u5173\u6027\u3002\u76f8\u5e94\u5730\uff0ccov\u8ba1\u7b97\u7684\u662f\u534f\u65b9\u5dee print(returns['MSFT']) # Date # 2016-08-15 NaN # 2016-08-16 -0.005540 # 2016-08-17 0.002089 # 2016-08-18 0.000695 # 2016-08-19 0.000347 # ... # 2021-08-09 -0.003904 # 2021-08-10 -0.006555 # 2021-08-11 0.001781 # 2021-08-12 0.009967 # 2021-08-13 0.010490 # Name: MSFT, Length: 1259, dtype: float64 # Series\u7684corr\u65b9\u6cd5\u8ba1\u7b97\u7684\u662f\u4e24\u4e2aSeries\u4e2d\u91cd\u53e0\u7684\u3001\u975eNA\u7684\u3001\u6309\u7d22\u5f15\u5bf9\u9f50\u7684\u503c\u7684\u76f8\u5173\u6027\u3002 print(returns['MSFT'].corr(returns['IBM'])) # 0.5175237180581937 # \u7b49\u540c\u5199\u6cd5\uff0cMSFT\u662f\u4e00\u4e2a\u6709\u6548\u7684Python\u5c5e\u6027 print(returns.MSFT.corr(returns.IBM)) # 0.5175237180581937 # Series\u7684cov\u65b9\u6cd5\u8ba1\u7b97\u7684\u662f\u4e24\u4e2aSeries\u4e2d\u503c\u7684\u534f\u65b9\u5dee\u3002 print(returns['MSFT'].cov(returns['IBM'])) # 0.0001452224236764915 DataFrame\u7684corr\u548ccov\u65b9\u6cd5\u4f1a\u5206\u522b\u4ee5DataFrame\u7684\u5f62\u5f0f\u8fd4\u56de\u76f8\u5173\u6027\u548c\u534f\u65b9\u5dee\u77e9\u9635\u3002 print(returns.corr()) # AAPL IBM MSFT GOOG # AAPL 1.000000 0.441111 0.735539 0.661961 # IBM 0.441111 1.000000 0.517524 0.484230 # MSFT 0.735539 0.517524 1.000000 0.775756 # GOOG 0.661961 0.484230 0.775756 1.000000 # \u7ed9corrwith\u65b9\u6cd5\uff0c\u4f20\u5165\u4e00\u4e2aSeries\u65f6\uff0c\u4f1a\u8fd4\u56de\u4e00\u4e2a\u542b\u6709\u4e3a\u6bcf\u5217\u8ba1\u7b97\u76f8\u5173\u6027\u503c\u7684Series print(returns.corrwith(returns['IBM'])) # AAPL 0.441111 # IBM 1.000000 # MSFT 0.517524 # GOOG 0.484230 # dtype: float64 # \u7ed9corrwith\u65b9\u6cd5\uff0c\u4f20\u5165\u4e00\u4e2aDataFrame\u65f6\uff0c\u4f1a\u8ba1\u7b97\u5339\u914d\u5230\u5217\u540d\u7684\u76f8\u5173\u6027\u6570\u503c\u3002\u4e0b\u9762\u662f\u8ba1\u7b97\u4ea4\u6613\u91cf\u767e\u5206\u6bd4\u53d8\u5316\u7684\u76f8\u5173\u6027 print(returns.corrwith(volume)) # AAPL -0.063111 # IBM -0.103721 # MSFT -0.056842 # GOOG -0.119026 # dtype: float64 print(returns.cov()) # AAPL IBM MSFT GOOG # AAPL 0.000361 0.000137 0.000240 0.000211 # IBM 0.000137 0.000268 0.000145 0.000133 # MSFT 0.000240 0.000145 0.000294 0.000224 # GOOG 0.000211 0.000133 0.000224 0.000282","title":"\u76f8\u5173\u6027\u548c\u534f\u65b9\u5dee"},{"location":"python/DataAnalysis/ch02/#_13","text":"obj = pd.Series(['c', 'a', 'd', 'a', 'a', 'a', 'b', 'b', 'c', 'c']) print(obj) # 0 c # 1 a # 2 d # 3 a # 4 a # 5 a # 6 b # 7 b # 8 c # 9 c # dtype: object \u51fd\u6570 unique \u7ed9\u51faSeries\u4e2d\u7684\u552f\u4e00\u503c\u3002 print(obj.unique()) # ['c' 'a' 'd' 'b'] print(obj.sort_values().unique()) # ['a' 'b' 'c' 'd'] # value_counts\u8ba1\u7b97Series\u5305\u542b\u7684\u503c\u7684\u4e2a\u6570 print(obj.value_counts()) # a 4 # c 3 # b 2 # d 1 # dtype: int64 # \u8fd9\u91ccvalue_counts\u4e0d\u662fSeries\u7684\u65b9\u6cd5\uff0c\u662fpandas\u9876\u5c42\u65b9\u6cd5 print(pd.value_counts(obj.values, sort=True)) # a 4 # c 3 # b 2 # d 1 # dtype: int64 print(obj.isin(['b', 'c'])) # 0 True # 1 False # 2 False # 3 False # 4 False # 5 False # 6 True # 7 True # 8 True # 9 True # dtype: bool # \u5c06\u4e0a\u9762\u7684\u7ed3\u679c\u4f5c\u4e3a\u5217\u8868\u8f93\u5165\u7684\u6761\u4ef6\uff0c\u8f93\u51fa\u4e3aTrue\u7684\u7ed3\u679c print(obj[obj.isin(['b', 'c'])]) # 0 c # 6 b # 7 b # 8 c # 9 c # dtype: object \u53c2\u8003: pandas.Index.get_indexer obj1 = pd.Series(['c', 'a', 'd', 'a', 'a', 'a', 'b', 'b', 'c', 'c']) obj2 = pd.Series(['c', 'a', 'b']) print(pd.Index(obj1)) # Index(['c', 'a', 'd', 'a', 'a', 'a', 'b', 'b', 'c', 'c'], dtype='object') print(pd.Index(obj2)) # Index(['c', 'a', 'b'], dtype='object') # \u8fd9\u91cc0\u5bf9\u5e94obj2\u91cc\u9762\u7684c\u5728job1\u7684\u4f4d\u7f6e\uff0c\u4ee5\u6b64\u7c7b\u63a8\uff0c\u751f\u6210\u65b0\u7684\u7d22\u5f15\u5217\u8868 print(pd.Index(obj2).get_indexer(obj1)) # [ 0 1 -1 1 1 1 2 2 0 0] \u8ba1\u7b97DataFrame\u591a\u4e2a\u76f8\u5173\u5217\u7684\u76f4\u65b9\u56fe\u3002 data = pd.DataFrame( { 'Que1': [1, 3, 4, 3, 4], 'Que2': [2, 3, 1, 2, 3], 'Que3': [1, 5, 2, 4, 4], } ) print(data) # Que1 Que2 Que3 # 0 1 2 1 # 1 3 3 5 # 2 4 1 2 # 3 3 2 4 # 4 4 3 4 result = data.apply(pd.value_counts).fillna(0) # \u4e0b\u9762\u7ed3\u679c\u4e2d\u7684\u884c\u6807\u7b7e\u662f\u6240\u6709\u5217\u4e2d\u51fa\u73b0\u7684\u4e0d\u540c\u503c\uff0c\u6570\u503c\u5219\u662f\u8fd9\u4e9b\u4e0d\u540c\u503c\u5728\u6bcf\u4e2a\u5217\u4e2d\u51fa\u73b0\u7684\u6b21\u6570\uff0c\u4f8b\u5982\uff1a\u6570\u5b575\u53ea\u5728Que3\u91cc\u9762\u51fa\u73b0\u4e86\u4e00\u6b21 print(result) # Que1 Que2 Que3 # 1 1.0 1.0 1.0 # 2 0.0 2.0 1.0 # 3 2.0 2.0 0.0 # 4 2.0 0.0 2.0 # 5 0.0 0.0 1.0","title":"\u552f\u4e00\u503c\u3001\u8ba1\u6570\u548c\u6210\u5458\u5c5e\u6027"},{"location":"python/DataAnalysis/ch03/","text":"\u6570\u636e\u8f7d\u5165\u3001\u5b58\u50a8\u53ca\u6587\u4ef6\u683c\u5f0f \u00b6 \u6587\u672c\u683c\u5f0f\u6570\u636e\u7684\u8bfb\u5199 \u00b6 import numpy as np import pandas as pd import sys import csv import json \u5c06\u8868\u683c\u578b\u6570\u636e\u8bfb\u53d6\u4e3aDataFrame\u5bf9\u8c61\u662fpandas\u7684\u91cd\u8981\u7279\u6027\u3002 \u4e0b\u9762\u662f\u90e8\u5206\u5b9e\u73b0\u6587\u4ef6\u8bfb\u53d6\u529f\u80fd\u7684\u51fd\u6570\uff0cread_csv\u548cread_table\u53ef\u80fd\u662f\u540e\u671f\u6211\u4eec\u4f7f\u7528\u6700\u591a\u7684\u51fd\u6570\u3002 \u8fd9\u4e9b\u51fd\u6570\u7684\u53ef\u9009\u53c2\u6570\u4e3b\u8981\u6709\u4ee5\u4e0b\u51e0\u79cd\u7c7b\u578b\uff1a \u7d22\u5f15\uff1a\u53ef\u4ee5\u5c06\u4e00\u5217\u6216\u591a\u4e2a\u5217\u4f5c\u4e3a\u8fd4\u56de\u7684DataFrame\uff0c\u4ece\u6587\u4ef6\u6216\u7528\u6237\u5904\u83b7\u5f97\u5217\u540d\uff0c\u6216\u8005\u6ca1\u6709\u5217\u540d\u3002 \u7c7b\u578b\u63a8\u65ad\u548c\u6570\u636e\u8f6c\u6362\uff1a\u5305\u62ec\u7528\u6237\u81ea\u5b9a\u4e49\u7684\u503c\u8f6c\u6362\u548c\u81ea\u5b9a\u4e49\u7684\u7f3a\u5931\u503c\u7b26\u53f7\u5217\u8868\u3002 \u65e5\u671f\u65f6\u95f4\u89e3\u6790\uff1a\u5305\u62ec\u7ec4\u5408\u529f\u80fd\uff0c\u4e5f\u5305\u62ec\u5c06\u5206\u6563\u5728\u591a\u4e2a\u5217\u4e0a\u7684\u65e5\u671f\u548c\u65f6\u95f4\u4fe1\u606f\u7ec4\u5408\u6210\u7ed3\u679c\u4e2d\u7684\u5355\u4e2a\u5217\u3002 \u8fed\u4ee3\uff1a\u652f\u6301\u5bf9\u5927\u578b\u6587\u4ef6\u7684\u5206\u5757\u8fed\u4ee3\u3002 \u672a\u6e05\u6d17\u6570\u636e\u95ee\u9898\uff1a\u8df3\u8fc7\u884c\u3001\u9875\u811a\u3001\u6ce8\u91ca\u4ee5\u53ca\u5176\u4ed6\u6b21\u8981\u6570\u636e\uff0c\u6bd4\u5982\u4f7f\u7528\u9017\u53f7\u5206\u9694\u5343\u4f4d\u7684\u6570\u5b57\u3002 file01 = '../examples/ex1.csv' # \u4f7f\u7528read_csv\u5c06\u6587\u4ef6\u8bfb\u5165\u4e00\u4e2aDataFrame df = pd.read_csv(file01) print(df) # 1 2 3 4 hello # 0 5 6 7 8 world # 1 9 10 11 12 foo df = pd.read_csv(file01, header=None) # \u4f7f\u7528pandas\u81ea\u52a8\u5206\u914d\u9ed8\u8ba4\u5217\u540d print(df) # 0 1 2 3 4 # 0 1 2 3 4 hello # 1 5 6 7 8 world # 2 9 10 11 12 foo df = pd.read_csv(file01, names=['aa', 'bb', 'cc', 'dd', 'message']) # \u81ea\u5df1\u6307\u5b9a\u5217\u540d print(df) # aa bb cc dd ee # 0 1 2 3 4 hello # 1 5 6 7 8 world # 2 9 10 11 12 foo # \u4f7f\u7528read_table\uff0c\u5e76\u6307\u5b9a\u5206\u9694\u7b26\uff0c\u5c06\u6587\u4ef6\u8bfb\u5165\u4e00\u4e2aDataFrame df = pd.read_table(file01, sep=',') print(df) # a b c d message # 0 1 2 3 4 hello # 1 5 6 7 8 world # 2 9 10 11 12 foo \u4ece\u591a\u4e2a\u5217\u4e2d\u5f62\u6210\u4e00\u4e2a\u5206\u5c42\u7d22\u5f15 parased = pd.read_csv('../examples/csv_mindex.csv', index_col=['key1', 'key2']) print(parased) # value1 value2 # key1 key2 # one a 1 2 # b 3 4 # c 5 6 # d 7 8 # two a 9 10 # b 11 12 # c 13 14 # d 15 16 \u4e0b\u4f8b\u4e2d\uff0c\u7531\u4e8e\u5217\u540d\u7684\u6570\u91cf\u6bd4\u6570\u636e\u7684\u5217\u6570\u5c11\u4e00\u4e2a\uff0c\u56e0\u6b64read_table\u63a8\u65ad\u7b2c\u4e00\u5217\u5e94\u5f53\u4f5c\u4e3aDataFrame\u7684\u7d22\u5f15\u3002 ex3.txt\u539f\u59cb\u6587\u4ef6\u5185\u5bb9 A B C aaa -0.264438 -1.026059 -0.619500 bbb 0.927272 0.302904 -0.032399 ccc -0.264273 -0.386314 -0.217601 ddd -0.871858 -0.348382 1.100491 result = pd.read_table('../examples/ex3.txt') # \u76f4\u63a5\u8bfb\u53d6 print(result) # A B C # aaa -0.264438 -1.026059 -0.619500 # bbb 0.927272 0.302904 -0.032399 NaN # ccc -0.264273 -0.386314 -0.217601 # ddd -0.871858 -0.348382 1.100491 result = pd.read_table('../examples/ex3.txt', sep='\\s+') # \u5411read_table\u6b63\u5219\u8868\u8fbe\u5f0f\u4e3a\\s+\u6765\u683c\u5f0f\u5316\u6587\u4ef6 print(result) # A B C # aaa -0.264438 -1.026059 -0.619500 # bbb 0.927272 0.302904 -0.032399 # ccc -0.264273 -0.386314 -0.217601 # ddd -0.871858 -0.348382 1.100491 \u4e0b\u4f8b\u4e2dex4.csv\u539f\u59cb\u6587\u4ef6\u5185\u5bb9 # hey! a,b,c,d,message # just wanted to make things more difficult for you # who reads CSV files with computers, anyway? 1,2,3,4,hello 5,6,7,8,world 9,10,11,12,foo result = pd.read_csv('../examples/ex4.csv', skiprows=[0, 2, 3]) # \u4f7f\u7528skiprows\u6765\u8df3\u8fc7\u7b2c\u4e00\u884c\u3001\u7b2c\u4e09\u884c\u548c\u7b2c\u56db\u884c print(result) # a b c d message # 0 1 2 3 4 hello # 1 5 6 7 8 world # 2 9 10 11 12 foo \u7f3a\u5931\u503c\u5904\u7406 \u9ed8\u8ba4\u60c5\u51b5\u4e0b\uff0cpandas\u4f7f\u7528\u4e00\u4e9b\u5e38\u89c1\u7684\u6807\u8bc6\uff0c\u4f8b\u5982 NA \u548c NULL \u4e0b\u4f8b\u4e2dex5.csv\u539f\u59cb\u6587\u4ef6\u5185\u5bb9 something,a,b,c,d,message one,1,2,3,4,NA two,5,6,,8,world three,9,10,11,12,foo result = pd.read_csv('../examples/ex5.csv') print(result) # something a b c d message # 0 one 1 2 3.0 4 NaN # 1 two 5 6 NaN 8 world # 2 three 9 10 11.0 12 foo print(pd.isnull(result)) # something a b c d message # 0 False False False False False True # 1 False False False True False False # 2 False False False False False False result = pd.read_csv('../examples/ex5.csv', na_values=['NULL']) print(result) # something a b c d message # 0 one 1 2 3.0 4 NaN # 1 two 5 6 NaN 8 world # 2 three 9 10 11.0 12 foo \u5b9a\u4e49\u66ff\u6362\u89c4\u5219 sentinels = { 'message': ['foo', 'NA'], 'something': ['two'] } result = pd.read_csv('../examples/ex5.csv', na_values=sentinels) \u628amessage\u5217\u6240\u6709\u503c\u4e3afoo\u6216NA\u7684\u66ff\u6362\u4e3aNull \u628asomething\u5217\u6240\u6709\u503c\u4e3atwo\u7684\u66ff\u6362\u4e3aNull print(result) # something a b c d message # 0 one 1 2 3.0 4 NaN # 1 NaN 5 6 NaN 8 world # 2 three 9 10 11.0 12 NaN \u5206\u5757\u8bfb\u5165\u6587\u672c\u6587\u4ef6 \u00b6 pd.options.display.max_rows = 10 result = pd.read_csv('../examples/ex6.csv') # \u8bfb\u53d6\u5168\u90e8\u8bb0\u5f55 print(result) result = pd.read_csv('../examples/ex6.csv', nrows=5) # \u8bfb\u53d6\u524d5\u884c\u8bb0\u5f55 print(result) # [10000 rows x 5 columns] # one two three four key # 0 0.467976 -0.038649 -0.295344 -1.824726 L # 1 -0.358893 1.404453 0.704965 -0.200638 B # 2 -0.501840 0.659254 -0.421691 -0.057688 G # 3 0.204886 1.074134 1.388361 -0.982404 R # 4 0.354628 -0.133116 0.283763 -0.837063 Q result = pd.read_csv('../examples/ex6.csv', chunksize=1000) # \u5206\u5757\u8bfb\u5165\u6587\u4ef6\uff0c\u6bcf\u57571000\u884c print(result) # \u8fd4\u56de\u7684\u662f\u4e00\u4e2aTextParser\u5bf9\u8c61, \u5141\u8bb8\u4f60\u6839\u636echunksize\u904d\u5386\u6587\u4ef6\u3002 # \u53ef\u4ee5\u904d\u5386 ex6.csv \uff0c\u5e76\u5bf9 key \u5217\u805a\u5408\u83b7\u5f97\u8ba1\u6570\u503c tot = pd.Series([], dtype=float) # \u8fd9\u91cc\u9700\u8981\u663e\u5f0f\u6307\u5b9adtype\uff0c\u540e\u7eedPython\u4f1a\u5c06\u9ed8\u8ba4\u503c\u4ecefloat64\u53d8\u6210object\uff0c\u76ee\u524d\u9ed8\u8ba4\u662ffloat64 for piece in result: tot = tot.add(piece['key'].value_counts(), fill_value=0) tot = tot.sort_values(ascending=False) print(tot[:10]) # E 368.0 # X 364.0 # L 346.0 # O 343.0 # Q 340.0 # M 338.0 # J 337.0 # F 335.0 # K 334.0 # H 330.0 # dtype: float64 \u5c06\u6570\u636e\u5199\u5165\u6587\u672c\u683c\u5f0f \u00b6 data = pd.read_csv('../examples/ex5.csv') print(data) # something a b c d message # 0 one 1 2 3.0 4 NaN # 1 two 5 6 NaN 8 world # 2 three 9 10 11.0 12 foo \u4f7f\u7528DataFrame\u7684 to_csv \u65b9\u6cd5\uff0c\u5c06\u6570\u636e\u5bfc\u51fa\u4e3a\u9017\u53f7\u5206\u9694\u7684\u6587\u4ef6 data.to_csv('../examples/out.csv') # \u8f93\u51faout.csv\u7684\u5185\u5bb9 # ,something,a,b,c,d,message # 0,one,1,2,3.0,4, # 1,two,5,6,,8,world # 2,three,9,10,11.0,12,foo \u4f7f\u7528DataFrame\u7684 to_csv \u65b9\u6cd5\uff0c\u5c06\u6570\u636e\u5bfc\u51fa\u4e3a\u5176\u4ed6\u7684\u5206\u9694\u7b26\u7684\u6587\u4ef6 data.to_csv(sys.stdout, sep='|') # |something|a|b|c|d|message # 0|one|1|2|3.0|4| # 1|two|5|6||8|world # 2|three|9|10|11.0|12|foo data.to_csv(sys.stdout, sep=',') # ,something,a,b,c,d,message # 0,one,1,2,3.0,4, # 1,two,5,6,,8,world # 2,three,9,10,11.0,12,foo data.to_csv(sys.stdout, sep=',', na_rep='NULL') # \u8bbe\u5b9a\u7f3a\u5931\u503c\u5728\u8f93\u51fa\u65f6\u4ee5\u7a7a\u5b57\u7b26\u4e32\u51fa\u73b0 # ,something,a,b,c,d,message # 0,one,1,2,3.0,4,NULL # 1,two,5,6,NULL,8,world # 2,three,9,10,11.0,12,foo data.to_csv(sys.stdout, sep=',', na_rep='NULL', index=False, header=False) # \u4e0d\u8f93\u51fa\u884c\u548c\u5217\u7684\u6807\u7b7e\uff08index\uff0cheader\uff09 # one,1,2,3.0,4,NULL # two,5,6,NULL,8,world # three,9,10,11.0,12,foo data.to_csv(sys.stdout, sep=',', na_rep='NULL', index=False, header=False, columns=['a', 'b', 'c']) # \u6309\u7167\u81ea\u5b9a\u7684\u987a\u5e8f\u8f93\u51fa\u5b50\u96c6 # 1,2,3.0 # 5,6,NULL # 9,10,11.0 Series\u4e5f\u6709 to_csv \u65b9\u6cd5 dates = pd.date_range('1/1/2000', periods=7) ts = pd.Series(np.arange(7), index=dates) ts.to_csv('../examples/tseries.csv', header=False) # \u8f93\u51fatseries.csv\u6587\u4ef6\u5185\u5bb9 # 2000-01-01,0 # 2000-01-02,1 # 2000-01-03,2 # 2000-01-04,3 # 2000-01-05,4 # 2000-01-06,5 # 2000-01-07,6 \u4f7f\u7528\u5206\u9694\u683c\u5f0f \u00b6 \u7edd\u5927\u591a\u6570\u7684\u8868\u578b\u6570\u636e\u90fd\u53ef\u4ee5\u4f7f\u7528\u51fd\u6570 pandas.read_table \u4ece\u786c\u76d8\u4e2d\u8bfb\u53d6\u3002 \u7136\u800c\uff0c\u5728\u67d0\u4e9b\u60c5\u51b5\u4e0b\uff0c\u63a5\u6536\u4e00\u4e2a\u5e26\u6709\u4e00\u884c\u6216\u591a\u884c\u9519\u8bef\u7684\u6587\u4ef6\u5e76\u4e0d\u5c11\u89c1\uff0c read_table \u4e5f\u65e0\u6cd5\u89e3\u51b3\u8fd9\u79cd\u60c5\u51b5\u3002 ex7.csv \u6587\u4ef6\u5185\u5bb9 \"a\",\"b\",\"c\" \"1\",\"2\",\"3\" \"1\",\"2\",\"3\" f = open('../examples/ex7.csv') # \u4f7f\u7528Python\u7684\u5185\u5efacsv\u6a21\u5757 reader = csv.reader(f) # \u5c06\u4efb\u4e00\u6253\u5f00\u7684\u6587\u4ef6\u6216\u6587\u4ef6\u578b\u5bf9\u8c61\u4f20\u7ed9csv.reader for line in reader: # # \u904d\u5386reader\uff0c\u4ea7\u751f\u5143\u7ec4\uff0c\u5143\u7ec4\u7684\u503c\u4e3a\u5220\u9664\u4e86\u5f15\u53f7\u7684\u5b57\u7b26 print(line) f.close() # ['a', 'b', 'c'] # ['1', '2', '3'] # ['1', '2', '3'] with open('../examples/ex7.csv') as f: lines = list(csv.reader(f)) # \u9996\u5148\uff0c\u5c06\u6587\u4ef6\u8bfb\u53d6\u4e3a\u884c\u7684\u5217\u8868 header, values = lines[0], lines[1:] # \u5176\u6b21\uff0c\u5c06\u6570\u636e\u62c6\u5206\u4e3a\u5217\u540d\u884c\u548c\u6570\u636e\u884c data_dict = { h: v for h, v in zip(header, zip(*values)) # \u518d\u7136\u540e\uff0c\u4f7f\u7528\u5b57\u5178\u63a8\u5bfc\u5f0f\u548c\u8868\u8fbe\u5f0fzip(*values)\u751f\u6210\u4e00\u4e2a\u5305\u542b\u6570\u636e\u5217\u7684\u5b57\u5178\uff0c\u5b57\u5178\u4e2d\u884c\u8f6c\u7f6e\u6210\u5217 } print(data_dict) # \u8f93\u51fa\u7ed3\u679c # {'a': ('1', '1'), 'b': ('2', '2'), 'c': ('3', '3')} \u5982\u679c\u9700\u6839\u636e\u4e0d\u540c\u7684\u5206\u9694\u7b26\u3001\u5b57\u7b26\u4e32\u5f15\u7528\u7ea6\u5b9a\u6216\u884c\u7ec8\u6b62\u7b26\u5b9a\u4e49\u4e00\u79cd\u65b0\u7684\u683c\u5f0f\u65f6\uff0c\u53ef\u4ee5: \u65b9\u6cd51\uff1a\u4f7f\u7528csv.Dialect\u5b9a\u4e49\u4e00\u4e2a\u7b80\u5355\u7684\u5b50\u7c7b class my_dialect(csv.Dialect): lineterminator = '\\n' delimiter = ';' # \u8fd9\u91cc\u53ea\u80fd\u662f\u4e00\u4e2a\u5b57\u7b26 quotechar = '\"' quoting = csv.QUOTE_MINIMAL f = open('../examples/ex7.csv') reader = csv.reader(f, dialect=my_dialect) for line in reader: # \u904d\u5386reader\uff0c\u4ea7\u751f\u5143\u7ec4\uff0c\u5143\u7ec4\u7684\u503c\u4e3a\u5220\u9664\u4e86\u5f15\u53f7\u7684\u5b57\u7b26 print(line) f.close() # ['a,\"b\",\"c\"'] # ['1,\"2\",\"3\"'] # ['1,\"2\",\"3\"'] \u65b9\u6cd52\uff1a\u76f4\u63a5\u5c06CSV\u65b9\u8a00\u53c2\u6570(dialect)\u4f20\u5165csv.reader\u7684\u5173\u952e\u5b57\u53c2\u6570\u3002 \u6bd4\u8f83\u8be6\u7ec6\u7684 \u4ecb\u7ecd\u65b9\u8a00\u548c\u5206\u9694\u7b26 f = open('../examples/ex7.csv') reader = csv.reader(f, delimiter='|') for line in reader: # \u904d\u5386reader\uff0c\u4ea7\u751f\u5143\u7ec4\uff0c\u5143\u7ec4\u7684\u503c\u4e3a\u5220\u9664\u4e86\u5f15\u53f7\u7684\u5b57\u7b26 print(line) f.close() # ['a,\"b\",\"c\"'] # ['1,\"2\",\"3\"'] # ['1,\"2\",\"3\"'] \u5bf9\u4e8e\u5177\u6709\u66f4\u590d\u6742\u6216\u56fa\u5b9a\u7684\u591a\u5b57\u7b26\u5206\u9694\u7b26\u7684\u6587\u4ef6\uff0c\u5c06\u65e0\u6cd5\u4f7f\u7528csv\u6a21\u5757\u3002 \u5728\u6b64\u7c7b\u60c5\u51b5\u4e0b\uff0c\u5c06\u4f7f\u7528\u5b57\u7b26\u4e32\u7684split\u65b9\u6cd5\u6216\u6b63\u5219\u8868\u8fbe\u5f0f\u65b9\u6cd5re.split\u8fdb\u884c\u884c\u62c6\u5206\u548c\u5176\u4ed6\u6e05\u7406\u5de5\u4f5c\u3002 \u9700\u8981\u624b\u52a8\u5199\u5165\u88ab\u5206\u9694\u7684\u6587\u4ef6\u65f6\uff0c\u4f60\u53ef\u4ee5\u4f7f\u7528csv.writer\u3002 \u8fd9\u4e2a\u51fd\u6570\u63a5\u6536\u4e00\u4e2a\u5df2\u7ecf\u6253\u5f00\u7684\u53ef\u5199\u5165\u6587\u4ef6\u5bf9\u8c61\u4ee5\u53ca\u548ccsv.reader\u76f8\u540c\u7684CSV\u65b9\u8a00\u3001\u683c\u5f0f\u9009\u9879. with open('../examples/mydata.csv', 'w') as f: writer = csv.writer(f, dialect=my_dialect) writer.writerow(('1', '2', '3')) writer.writerow(('4', '5', '6')) writer.writerow(('7', '8', '9')) writer.writerow(('10', '11', '12')) # mydata.csv \u6587\u4ef6\u5185\u5bb9 # 1;2;3 # 4;5;6 # 7;8;9 # 10;11;12 JSON\u6570\u636e \u00b6 obj = \"\"\" { \"name\": \"Wes\", \"places_lived\": [\"United States\", \"Spain\", \"Germany\"], \"pet\": null, \"siblings\": [ { \"name\": \"Scott\", \"age\": 30, \"pets\": [\"Zeus\", \"Zuko\"] }, { \"name\": \"Katie\", \"age\": 38, \"pets\": [\"Sixes\", \"Stache\", \"Cisco\"] } ] } \"\"\" \u5c06JSON\u5b57\u7b26\u4e32\u8f6c\u6362\u4e3aPython\u5f62\u5f0f\u65f6\uff0c\u4f7f\u7528json.loads\u65b9\u6cd5 result = json.loads(obj) print(result) # {'name': 'Wes', 'places_lived': ['United States', 'Spain', 'Germany'], 'pet': None, 'siblings': [{'name': 'Scott', 'age': 30, 'pets': ['Zeus', 'Zuko']}, {'name': 'Katie', 'age': 38, 'pets': ['Sixes', 'Stache', 'Cisco']}]} \u53e6\u4e00\u65b9\u9762\uff0cjson.dumps\u53ef\u4ee5\u5c06Python\u5bf9\u8c61\u8f6c\u6362\u56deJSON asjson = json.dumps(result) print(asjson) # {\"name\": \"Wes\", \"places_lived\": [\"United States\", \"Spain\", \"Germany\"], \"pet\": null, \"siblings\": [{\"name\": \"Scott\", \"age\": 30, \"pets\": [\"Zeus\", \"Zuko\"]}, {\"name\": \"Katie\", \"age\": 38, \"pets\": [\"Sixes\", \"Stache\", \"Cisco\"]}]} \u5c06JSON\u5bf9\u8c61\u6216\u5bf9\u8c61\u5217\u8868\u8f6c\u6362\u4e3aDataFrame\u6216\u5176\u4ed6\u6570\u636e\u7ed3\u6784\u3002 \u6bd4\u8f83\u65b9\u4fbf\u7684\u65b9\u5f0f\u662f\u5c06\u5b57\u5178\u6784\u6210\u7684\u5217\u8868\uff08\u4e4b\u524d\u662fJSON\u5bf9\u8c61\uff09\u4f20\u5165DataFrame\u6784\u9020\u51fd\u6570\uff0c\u5e76\u9009\u51fa\u6570\u636e\u5b57\u6bb5\u7684\u5b50\u96c6\u3002 siblings = pd.DataFrame(result['siblings'], columns=['name', 'age']) print(siblings) # name age # 0 Scott 30 # 1 Katie 38 pandas.read_json\u53ef\u4ee5\u81ea\u52a8\u5c06JSON\u6570\u636e\u96c6\u6309\u7167\u6307\u5b9a\u6b21\u5e8f\u8f6c\u6362\u4e3aSeries\u6216DataFrame\u3002 pandas.read_json\u7684\u9ed8\u8ba4\u9009\u9879\u662f\u5047\u8bbeJSON\u6570\u7ec4\u4e2d\u7684\u6bcf\u4e2a\u5bf9\u8c61\u662f\u8868\u91cc\u7684\u4e00\u884c\u3002 \u4f8b\u5982\u8bfb\u53d6 data = pd.read_json('../examples/example_new.json') data = pd.read_json('../examples/example.json') print(data) # a b c # 0 1 2 3 # 1 4 5 6 # 2 7 8 9 print(data.to_json()) # {\"a\":{\"0\":1,\"1\":4,\"2\":7},\"b\":{\"0\":2,\"1\":5,\"2\":8},\"c\":{\"0\":3,\"1\":6,\"2\":9}} print(data.to_json(orient='records')) # [{\"a\":1,\"b\":2,\"c\":3},{\"a\":4,\"b\":5,\"c\":6},{\"a\":7,\"b\":8,\"c\":9}] XML\u548cHTML\uff1a\u7f51\u7edc\u6293\u53d6 \u00b6 pandas\u7684\u5185\u5efa\u51fd\u6570read_html\u53ef\u4ee5\u4f7f\u7528lxml\u548cBeautiful Soup\u7b49\u5e93\u5c06HTML\u4e2d\u7684\u8868\u81ea\u52a8\u89e3\u6790\u4e3aDataFrame\u5bf9\u8c61\u3002 tables = pd.read_html('../examples/fdic_failed_bank_list.html') print(len(tables)) # 1 failures = tables[0] # //*[@id=\"table\"] print(failures.head()) # \u8bfb\u53d6\u524d5\u884c\u8bb0\u5f55 # Bank Name ... Updated Date # 0 Allied Bank ... November 17, 2016 # 1 The Woodbury Banking Company ... November 17, 2016 # 2 First CornerStone Bank ... September 6, 2016 # 3 Trust Company Bank ... September 6, 2016 # 4 North Milwaukee State Bank ... June 16, 2016 # # [5 rows x 7 columns] close_timestamps = pd.to_datetime(failures['Closing Date']) # \u8ba1\u7b97\u6bcf\u5e74\u94f6\u884c\u5012\u95ed\u7684\u6570\u91cf print(close_timestamps.dt.year.value_counts()) # 2010 157 # 2009 140 # 2011 92 # 2012 51 # 2008 25 # ... # 2004 4 # 2001 4 # 2007 3 # 2003 3 # 2000 2 # Name: Closing Date, Length: 15, dtype: int64 \u4e8c\u8fdb\u5236\u683c\u5f0f \u00b6 \u4e0eWeb API\u4ea4\u4e92 \u00b6 \u4e0e\u6570\u636e\u5e93\u4ea4\u4e92 \u00b6","title":"\u6570\u636e\u8f7d\u5165\u3001\u5b58\u50a8\u53ca\u6587\u4ef6\u683c\u5f0f"},{"location":"python/DataAnalysis/ch03/#_1","text":"","title":"\u6570\u636e\u8f7d\u5165\u3001\u5b58\u50a8\u53ca\u6587\u4ef6\u683c\u5f0f"},{"location":"python/DataAnalysis/ch03/#_2","text":"import numpy as np import pandas as pd import sys import csv import json \u5c06\u8868\u683c\u578b\u6570\u636e\u8bfb\u53d6\u4e3aDataFrame\u5bf9\u8c61\u662fpandas\u7684\u91cd\u8981\u7279\u6027\u3002 \u4e0b\u9762\u662f\u90e8\u5206\u5b9e\u73b0\u6587\u4ef6\u8bfb\u53d6\u529f\u80fd\u7684\u51fd\u6570\uff0cread_csv\u548cread_table\u53ef\u80fd\u662f\u540e\u671f\u6211\u4eec\u4f7f\u7528\u6700\u591a\u7684\u51fd\u6570\u3002 \u8fd9\u4e9b\u51fd\u6570\u7684\u53ef\u9009\u53c2\u6570\u4e3b\u8981\u6709\u4ee5\u4e0b\u51e0\u79cd\u7c7b\u578b\uff1a \u7d22\u5f15\uff1a\u53ef\u4ee5\u5c06\u4e00\u5217\u6216\u591a\u4e2a\u5217\u4f5c\u4e3a\u8fd4\u56de\u7684DataFrame\uff0c\u4ece\u6587\u4ef6\u6216\u7528\u6237\u5904\u83b7\u5f97\u5217\u540d\uff0c\u6216\u8005\u6ca1\u6709\u5217\u540d\u3002 \u7c7b\u578b\u63a8\u65ad\u548c\u6570\u636e\u8f6c\u6362\uff1a\u5305\u62ec\u7528\u6237\u81ea\u5b9a\u4e49\u7684\u503c\u8f6c\u6362\u548c\u81ea\u5b9a\u4e49\u7684\u7f3a\u5931\u503c\u7b26\u53f7\u5217\u8868\u3002 \u65e5\u671f\u65f6\u95f4\u89e3\u6790\uff1a\u5305\u62ec\u7ec4\u5408\u529f\u80fd\uff0c\u4e5f\u5305\u62ec\u5c06\u5206\u6563\u5728\u591a\u4e2a\u5217\u4e0a\u7684\u65e5\u671f\u548c\u65f6\u95f4\u4fe1\u606f\u7ec4\u5408\u6210\u7ed3\u679c\u4e2d\u7684\u5355\u4e2a\u5217\u3002 \u8fed\u4ee3\uff1a\u652f\u6301\u5bf9\u5927\u578b\u6587\u4ef6\u7684\u5206\u5757\u8fed\u4ee3\u3002 \u672a\u6e05\u6d17\u6570\u636e\u95ee\u9898\uff1a\u8df3\u8fc7\u884c\u3001\u9875\u811a\u3001\u6ce8\u91ca\u4ee5\u53ca\u5176\u4ed6\u6b21\u8981\u6570\u636e\uff0c\u6bd4\u5982\u4f7f\u7528\u9017\u53f7\u5206\u9694\u5343\u4f4d\u7684\u6570\u5b57\u3002 file01 = '../examples/ex1.csv' # \u4f7f\u7528read_csv\u5c06\u6587\u4ef6\u8bfb\u5165\u4e00\u4e2aDataFrame df = pd.read_csv(file01) print(df) # 1 2 3 4 hello # 0 5 6 7 8 world # 1 9 10 11 12 foo df = pd.read_csv(file01, header=None) # \u4f7f\u7528pandas\u81ea\u52a8\u5206\u914d\u9ed8\u8ba4\u5217\u540d print(df) # 0 1 2 3 4 # 0 1 2 3 4 hello # 1 5 6 7 8 world # 2 9 10 11 12 foo df = pd.read_csv(file01, names=['aa', 'bb', 'cc', 'dd', 'message']) # \u81ea\u5df1\u6307\u5b9a\u5217\u540d print(df) # aa bb cc dd ee # 0 1 2 3 4 hello # 1 5 6 7 8 world # 2 9 10 11 12 foo # \u4f7f\u7528read_table\uff0c\u5e76\u6307\u5b9a\u5206\u9694\u7b26\uff0c\u5c06\u6587\u4ef6\u8bfb\u5165\u4e00\u4e2aDataFrame df = pd.read_table(file01, sep=',') print(df) # a b c d message # 0 1 2 3 4 hello # 1 5 6 7 8 world # 2 9 10 11 12 foo \u4ece\u591a\u4e2a\u5217\u4e2d\u5f62\u6210\u4e00\u4e2a\u5206\u5c42\u7d22\u5f15 parased = pd.read_csv('../examples/csv_mindex.csv', index_col=['key1', 'key2']) print(parased) # value1 value2 # key1 key2 # one a 1 2 # b 3 4 # c 5 6 # d 7 8 # two a 9 10 # b 11 12 # c 13 14 # d 15 16 \u4e0b\u4f8b\u4e2d\uff0c\u7531\u4e8e\u5217\u540d\u7684\u6570\u91cf\u6bd4\u6570\u636e\u7684\u5217\u6570\u5c11\u4e00\u4e2a\uff0c\u56e0\u6b64read_table\u63a8\u65ad\u7b2c\u4e00\u5217\u5e94\u5f53\u4f5c\u4e3aDataFrame\u7684\u7d22\u5f15\u3002 ex3.txt\u539f\u59cb\u6587\u4ef6\u5185\u5bb9 A B C aaa -0.264438 -1.026059 -0.619500 bbb 0.927272 0.302904 -0.032399 ccc -0.264273 -0.386314 -0.217601 ddd -0.871858 -0.348382 1.100491 result = pd.read_table('../examples/ex3.txt') # \u76f4\u63a5\u8bfb\u53d6 print(result) # A B C # aaa -0.264438 -1.026059 -0.619500 # bbb 0.927272 0.302904 -0.032399 NaN # ccc -0.264273 -0.386314 -0.217601 # ddd -0.871858 -0.348382 1.100491 result = pd.read_table('../examples/ex3.txt', sep='\\s+') # \u5411read_table\u6b63\u5219\u8868\u8fbe\u5f0f\u4e3a\\s+\u6765\u683c\u5f0f\u5316\u6587\u4ef6 print(result) # A B C # aaa -0.264438 -1.026059 -0.619500 # bbb 0.927272 0.302904 -0.032399 # ccc -0.264273 -0.386314 -0.217601 # ddd -0.871858 -0.348382 1.100491 \u4e0b\u4f8b\u4e2dex4.csv\u539f\u59cb\u6587\u4ef6\u5185\u5bb9 # hey! a,b,c,d,message # just wanted to make things more difficult for you # who reads CSV files with computers, anyway? 1,2,3,4,hello 5,6,7,8,world 9,10,11,12,foo result = pd.read_csv('../examples/ex4.csv', skiprows=[0, 2, 3]) # \u4f7f\u7528skiprows\u6765\u8df3\u8fc7\u7b2c\u4e00\u884c\u3001\u7b2c\u4e09\u884c\u548c\u7b2c\u56db\u884c print(result) # a b c d message # 0 1 2 3 4 hello # 1 5 6 7 8 world # 2 9 10 11 12 foo \u7f3a\u5931\u503c\u5904\u7406 \u9ed8\u8ba4\u60c5\u51b5\u4e0b\uff0cpandas\u4f7f\u7528\u4e00\u4e9b\u5e38\u89c1\u7684\u6807\u8bc6\uff0c\u4f8b\u5982 NA \u548c NULL \u4e0b\u4f8b\u4e2dex5.csv\u539f\u59cb\u6587\u4ef6\u5185\u5bb9 something,a,b,c,d,message one,1,2,3,4,NA two,5,6,,8,world three,9,10,11,12,foo result = pd.read_csv('../examples/ex5.csv') print(result) # something a b c d message # 0 one 1 2 3.0 4 NaN # 1 two 5 6 NaN 8 world # 2 three 9 10 11.0 12 foo print(pd.isnull(result)) # something a b c d message # 0 False False False False False True # 1 False False False True False False # 2 False False False False False False result = pd.read_csv('../examples/ex5.csv', na_values=['NULL']) print(result) # something a b c d message # 0 one 1 2 3.0 4 NaN # 1 two 5 6 NaN 8 world # 2 three 9 10 11.0 12 foo \u5b9a\u4e49\u66ff\u6362\u89c4\u5219 sentinels = { 'message': ['foo', 'NA'], 'something': ['two'] } result = pd.read_csv('../examples/ex5.csv', na_values=sentinels) \u628amessage\u5217\u6240\u6709\u503c\u4e3afoo\u6216NA\u7684\u66ff\u6362\u4e3aNull \u628asomething\u5217\u6240\u6709\u503c\u4e3atwo\u7684\u66ff\u6362\u4e3aNull print(result) # something a b c d message # 0 one 1 2 3.0 4 NaN # 1 NaN 5 6 NaN 8 world # 2 three 9 10 11.0 12 NaN","title":"\u6587\u672c\u683c\u5f0f\u6570\u636e\u7684\u8bfb\u5199"},{"location":"python/DataAnalysis/ch03/#_3","text":"pd.options.display.max_rows = 10 result = pd.read_csv('../examples/ex6.csv') # \u8bfb\u53d6\u5168\u90e8\u8bb0\u5f55 print(result) result = pd.read_csv('../examples/ex6.csv', nrows=5) # \u8bfb\u53d6\u524d5\u884c\u8bb0\u5f55 print(result) # [10000 rows x 5 columns] # one two three four key # 0 0.467976 -0.038649 -0.295344 -1.824726 L # 1 -0.358893 1.404453 0.704965 -0.200638 B # 2 -0.501840 0.659254 -0.421691 -0.057688 G # 3 0.204886 1.074134 1.388361 -0.982404 R # 4 0.354628 -0.133116 0.283763 -0.837063 Q result = pd.read_csv('../examples/ex6.csv', chunksize=1000) # \u5206\u5757\u8bfb\u5165\u6587\u4ef6\uff0c\u6bcf\u57571000\u884c print(result) # \u8fd4\u56de\u7684\u662f\u4e00\u4e2aTextParser\u5bf9\u8c61, \u5141\u8bb8\u4f60\u6839\u636echunksize\u904d\u5386\u6587\u4ef6\u3002 # \u53ef\u4ee5\u904d\u5386 ex6.csv \uff0c\u5e76\u5bf9 key \u5217\u805a\u5408\u83b7\u5f97\u8ba1\u6570\u503c tot = pd.Series([], dtype=float) # \u8fd9\u91cc\u9700\u8981\u663e\u5f0f\u6307\u5b9adtype\uff0c\u540e\u7eedPython\u4f1a\u5c06\u9ed8\u8ba4\u503c\u4ecefloat64\u53d8\u6210object\uff0c\u76ee\u524d\u9ed8\u8ba4\u662ffloat64 for piece in result: tot = tot.add(piece['key'].value_counts(), fill_value=0) tot = tot.sort_values(ascending=False) print(tot[:10]) # E 368.0 # X 364.0 # L 346.0 # O 343.0 # Q 340.0 # M 338.0 # J 337.0 # F 335.0 # K 334.0 # H 330.0 # dtype: float64","title":"\u5206\u5757\u8bfb\u5165\u6587\u672c\u6587\u4ef6"},{"location":"python/DataAnalysis/ch03/#_4","text":"data = pd.read_csv('../examples/ex5.csv') print(data) # something a b c d message # 0 one 1 2 3.0 4 NaN # 1 two 5 6 NaN 8 world # 2 three 9 10 11.0 12 foo \u4f7f\u7528DataFrame\u7684 to_csv \u65b9\u6cd5\uff0c\u5c06\u6570\u636e\u5bfc\u51fa\u4e3a\u9017\u53f7\u5206\u9694\u7684\u6587\u4ef6 data.to_csv('../examples/out.csv') # \u8f93\u51faout.csv\u7684\u5185\u5bb9 # ,something,a,b,c,d,message # 0,one,1,2,3.0,4, # 1,two,5,6,,8,world # 2,three,9,10,11.0,12,foo \u4f7f\u7528DataFrame\u7684 to_csv \u65b9\u6cd5\uff0c\u5c06\u6570\u636e\u5bfc\u51fa\u4e3a\u5176\u4ed6\u7684\u5206\u9694\u7b26\u7684\u6587\u4ef6 data.to_csv(sys.stdout, sep='|') # |something|a|b|c|d|message # 0|one|1|2|3.0|4| # 1|two|5|6||8|world # 2|three|9|10|11.0|12|foo data.to_csv(sys.stdout, sep=',') # ,something,a,b,c,d,message # 0,one,1,2,3.0,4, # 1,two,5,6,,8,world # 2,three,9,10,11.0,12,foo data.to_csv(sys.stdout, sep=',', na_rep='NULL') # \u8bbe\u5b9a\u7f3a\u5931\u503c\u5728\u8f93\u51fa\u65f6\u4ee5\u7a7a\u5b57\u7b26\u4e32\u51fa\u73b0 # ,something,a,b,c,d,message # 0,one,1,2,3.0,4,NULL # 1,two,5,6,NULL,8,world # 2,three,9,10,11.0,12,foo data.to_csv(sys.stdout, sep=',', na_rep='NULL', index=False, header=False) # \u4e0d\u8f93\u51fa\u884c\u548c\u5217\u7684\u6807\u7b7e\uff08index\uff0cheader\uff09 # one,1,2,3.0,4,NULL # two,5,6,NULL,8,world # three,9,10,11.0,12,foo data.to_csv(sys.stdout, sep=',', na_rep='NULL', index=False, header=False, columns=['a', 'b', 'c']) # \u6309\u7167\u81ea\u5b9a\u7684\u987a\u5e8f\u8f93\u51fa\u5b50\u96c6 # 1,2,3.0 # 5,6,NULL # 9,10,11.0 Series\u4e5f\u6709 to_csv \u65b9\u6cd5 dates = pd.date_range('1/1/2000', periods=7) ts = pd.Series(np.arange(7), index=dates) ts.to_csv('../examples/tseries.csv', header=False) # \u8f93\u51fatseries.csv\u6587\u4ef6\u5185\u5bb9 # 2000-01-01,0 # 2000-01-02,1 # 2000-01-03,2 # 2000-01-04,3 # 2000-01-05,4 # 2000-01-06,5 # 2000-01-07,6","title":"\u5c06\u6570\u636e\u5199\u5165\u6587\u672c\u683c\u5f0f"},{"location":"python/DataAnalysis/ch03/#_5","text":"\u7edd\u5927\u591a\u6570\u7684\u8868\u578b\u6570\u636e\u90fd\u53ef\u4ee5\u4f7f\u7528\u51fd\u6570 pandas.read_table \u4ece\u786c\u76d8\u4e2d\u8bfb\u53d6\u3002 \u7136\u800c\uff0c\u5728\u67d0\u4e9b\u60c5\u51b5\u4e0b\uff0c\u63a5\u6536\u4e00\u4e2a\u5e26\u6709\u4e00\u884c\u6216\u591a\u884c\u9519\u8bef\u7684\u6587\u4ef6\u5e76\u4e0d\u5c11\u89c1\uff0c read_table \u4e5f\u65e0\u6cd5\u89e3\u51b3\u8fd9\u79cd\u60c5\u51b5\u3002 ex7.csv \u6587\u4ef6\u5185\u5bb9 \"a\",\"b\",\"c\" \"1\",\"2\",\"3\" \"1\",\"2\",\"3\" f = open('../examples/ex7.csv') # \u4f7f\u7528Python\u7684\u5185\u5efacsv\u6a21\u5757 reader = csv.reader(f) # \u5c06\u4efb\u4e00\u6253\u5f00\u7684\u6587\u4ef6\u6216\u6587\u4ef6\u578b\u5bf9\u8c61\u4f20\u7ed9csv.reader for line in reader: # # \u904d\u5386reader\uff0c\u4ea7\u751f\u5143\u7ec4\uff0c\u5143\u7ec4\u7684\u503c\u4e3a\u5220\u9664\u4e86\u5f15\u53f7\u7684\u5b57\u7b26 print(line) f.close() # ['a', 'b', 'c'] # ['1', '2', '3'] # ['1', '2', '3'] with open('../examples/ex7.csv') as f: lines = list(csv.reader(f)) # \u9996\u5148\uff0c\u5c06\u6587\u4ef6\u8bfb\u53d6\u4e3a\u884c\u7684\u5217\u8868 header, values = lines[0], lines[1:] # \u5176\u6b21\uff0c\u5c06\u6570\u636e\u62c6\u5206\u4e3a\u5217\u540d\u884c\u548c\u6570\u636e\u884c data_dict = { h: v for h, v in zip(header, zip(*values)) # \u518d\u7136\u540e\uff0c\u4f7f\u7528\u5b57\u5178\u63a8\u5bfc\u5f0f\u548c\u8868\u8fbe\u5f0fzip(*values)\u751f\u6210\u4e00\u4e2a\u5305\u542b\u6570\u636e\u5217\u7684\u5b57\u5178\uff0c\u5b57\u5178\u4e2d\u884c\u8f6c\u7f6e\u6210\u5217 } print(data_dict) # \u8f93\u51fa\u7ed3\u679c # {'a': ('1', '1'), 'b': ('2', '2'), 'c': ('3', '3')} \u5982\u679c\u9700\u6839\u636e\u4e0d\u540c\u7684\u5206\u9694\u7b26\u3001\u5b57\u7b26\u4e32\u5f15\u7528\u7ea6\u5b9a\u6216\u884c\u7ec8\u6b62\u7b26\u5b9a\u4e49\u4e00\u79cd\u65b0\u7684\u683c\u5f0f\u65f6\uff0c\u53ef\u4ee5: \u65b9\u6cd51\uff1a\u4f7f\u7528csv.Dialect\u5b9a\u4e49\u4e00\u4e2a\u7b80\u5355\u7684\u5b50\u7c7b class my_dialect(csv.Dialect): lineterminator = '\\n' delimiter = ';' # \u8fd9\u91cc\u53ea\u80fd\u662f\u4e00\u4e2a\u5b57\u7b26 quotechar = '\"' quoting = csv.QUOTE_MINIMAL f = open('../examples/ex7.csv') reader = csv.reader(f, dialect=my_dialect) for line in reader: # \u904d\u5386reader\uff0c\u4ea7\u751f\u5143\u7ec4\uff0c\u5143\u7ec4\u7684\u503c\u4e3a\u5220\u9664\u4e86\u5f15\u53f7\u7684\u5b57\u7b26 print(line) f.close() # ['a,\"b\",\"c\"'] # ['1,\"2\",\"3\"'] # ['1,\"2\",\"3\"'] \u65b9\u6cd52\uff1a\u76f4\u63a5\u5c06CSV\u65b9\u8a00\u53c2\u6570(dialect)\u4f20\u5165csv.reader\u7684\u5173\u952e\u5b57\u53c2\u6570\u3002 \u6bd4\u8f83\u8be6\u7ec6\u7684 \u4ecb\u7ecd\u65b9\u8a00\u548c\u5206\u9694\u7b26 f = open('../examples/ex7.csv') reader = csv.reader(f, delimiter='|') for line in reader: # \u904d\u5386reader\uff0c\u4ea7\u751f\u5143\u7ec4\uff0c\u5143\u7ec4\u7684\u503c\u4e3a\u5220\u9664\u4e86\u5f15\u53f7\u7684\u5b57\u7b26 print(line) f.close() # ['a,\"b\",\"c\"'] # ['1,\"2\",\"3\"'] # ['1,\"2\",\"3\"'] \u5bf9\u4e8e\u5177\u6709\u66f4\u590d\u6742\u6216\u56fa\u5b9a\u7684\u591a\u5b57\u7b26\u5206\u9694\u7b26\u7684\u6587\u4ef6\uff0c\u5c06\u65e0\u6cd5\u4f7f\u7528csv\u6a21\u5757\u3002 \u5728\u6b64\u7c7b\u60c5\u51b5\u4e0b\uff0c\u5c06\u4f7f\u7528\u5b57\u7b26\u4e32\u7684split\u65b9\u6cd5\u6216\u6b63\u5219\u8868\u8fbe\u5f0f\u65b9\u6cd5re.split\u8fdb\u884c\u884c\u62c6\u5206\u548c\u5176\u4ed6\u6e05\u7406\u5de5\u4f5c\u3002 \u9700\u8981\u624b\u52a8\u5199\u5165\u88ab\u5206\u9694\u7684\u6587\u4ef6\u65f6\uff0c\u4f60\u53ef\u4ee5\u4f7f\u7528csv.writer\u3002 \u8fd9\u4e2a\u51fd\u6570\u63a5\u6536\u4e00\u4e2a\u5df2\u7ecf\u6253\u5f00\u7684\u53ef\u5199\u5165\u6587\u4ef6\u5bf9\u8c61\u4ee5\u53ca\u548ccsv.reader\u76f8\u540c\u7684CSV\u65b9\u8a00\u3001\u683c\u5f0f\u9009\u9879. with open('../examples/mydata.csv', 'w') as f: writer = csv.writer(f, dialect=my_dialect) writer.writerow(('1', '2', '3')) writer.writerow(('4', '5', '6')) writer.writerow(('7', '8', '9')) writer.writerow(('10', '11', '12')) # mydata.csv \u6587\u4ef6\u5185\u5bb9 # 1;2;3 # 4;5;6 # 7;8;9 # 10;11;12","title":"\u4f7f\u7528\u5206\u9694\u683c\u5f0f"},{"location":"python/DataAnalysis/ch03/#json","text":"obj = \"\"\" { \"name\": \"Wes\", \"places_lived\": [\"United States\", \"Spain\", \"Germany\"], \"pet\": null, \"siblings\": [ { \"name\": \"Scott\", \"age\": 30, \"pets\": [\"Zeus\", \"Zuko\"] }, { \"name\": \"Katie\", \"age\": 38, \"pets\": [\"Sixes\", \"Stache\", \"Cisco\"] } ] } \"\"\" \u5c06JSON\u5b57\u7b26\u4e32\u8f6c\u6362\u4e3aPython\u5f62\u5f0f\u65f6\uff0c\u4f7f\u7528json.loads\u65b9\u6cd5 result = json.loads(obj) print(result) # {'name': 'Wes', 'places_lived': ['United States', 'Spain', 'Germany'], 'pet': None, 'siblings': [{'name': 'Scott', 'age': 30, 'pets': ['Zeus', 'Zuko']}, {'name': 'Katie', 'age': 38, 'pets': ['Sixes', 'Stache', 'Cisco']}]} \u53e6\u4e00\u65b9\u9762\uff0cjson.dumps\u53ef\u4ee5\u5c06Python\u5bf9\u8c61\u8f6c\u6362\u56deJSON asjson = json.dumps(result) print(asjson) # {\"name\": \"Wes\", \"places_lived\": [\"United States\", \"Spain\", \"Germany\"], \"pet\": null, \"siblings\": [{\"name\": \"Scott\", \"age\": 30, \"pets\": [\"Zeus\", \"Zuko\"]}, {\"name\": \"Katie\", \"age\": 38, \"pets\": [\"Sixes\", \"Stache\", \"Cisco\"]}]} \u5c06JSON\u5bf9\u8c61\u6216\u5bf9\u8c61\u5217\u8868\u8f6c\u6362\u4e3aDataFrame\u6216\u5176\u4ed6\u6570\u636e\u7ed3\u6784\u3002 \u6bd4\u8f83\u65b9\u4fbf\u7684\u65b9\u5f0f\u662f\u5c06\u5b57\u5178\u6784\u6210\u7684\u5217\u8868\uff08\u4e4b\u524d\u662fJSON\u5bf9\u8c61\uff09\u4f20\u5165DataFrame\u6784\u9020\u51fd\u6570\uff0c\u5e76\u9009\u51fa\u6570\u636e\u5b57\u6bb5\u7684\u5b50\u96c6\u3002 siblings = pd.DataFrame(result['siblings'], columns=['name', 'age']) print(siblings) # name age # 0 Scott 30 # 1 Katie 38 pandas.read_json\u53ef\u4ee5\u81ea\u52a8\u5c06JSON\u6570\u636e\u96c6\u6309\u7167\u6307\u5b9a\u6b21\u5e8f\u8f6c\u6362\u4e3aSeries\u6216DataFrame\u3002 pandas.read_json\u7684\u9ed8\u8ba4\u9009\u9879\u662f\u5047\u8bbeJSON\u6570\u7ec4\u4e2d\u7684\u6bcf\u4e2a\u5bf9\u8c61\u662f\u8868\u91cc\u7684\u4e00\u884c\u3002 \u4f8b\u5982\u8bfb\u53d6 data = pd.read_json('../examples/example_new.json') data = pd.read_json('../examples/example.json') print(data) # a b c # 0 1 2 3 # 1 4 5 6 # 2 7 8 9 print(data.to_json()) # {\"a\":{\"0\":1,\"1\":4,\"2\":7},\"b\":{\"0\":2,\"1\":5,\"2\":8},\"c\":{\"0\":3,\"1\":6,\"2\":9}} print(data.to_json(orient='records')) # [{\"a\":1,\"b\":2,\"c\":3},{\"a\":4,\"b\":5,\"c\":6},{\"a\":7,\"b\":8,\"c\":9}]","title":"JSON\u6570\u636e"},{"location":"python/DataAnalysis/ch03/#xmlhtml","text":"pandas\u7684\u5185\u5efa\u51fd\u6570read_html\u53ef\u4ee5\u4f7f\u7528lxml\u548cBeautiful Soup\u7b49\u5e93\u5c06HTML\u4e2d\u7684\u8868\u81ea\u52a8\u89e3\u6790\u4e3aDataFrame\u5bf9\u8c61\u3002 tables = pd.read_html('../examples/fdic_failed_bank_list.html') print(len(tables)) # 1 failures = tables[0] # //*[@id=\"table\"] print(failures.head()) # \u8bfb\u53d6\u524d5\u884c\u8bb0\u5f55 # Bank Name ... Updated Date # 0 Allied Bank ... November 17, 2016 # 1 The Woodbury Banking Company ... November 17, 2016 # 2 First CornerStone Bank ... September 6, 2016 # 3 Trust Company Bank ... September 6, 2016 # 4 North Milwaukee State Bank ... June 16, 2016 # # [5 rows x 7 columns] close_timestamps = pd.to_datetime(failures['Closing Date']) # \u8ba1\u7b97\u6bcf\u5e74\u94f6\u884c\u5012\u95ed\u7684\u6570\u91cf print(close_timestamps.dt.year.value_counts()) # 2010 157 # 2009 140 # 2011 92 # 2012 51 # 2008 25 # ... # 2004 4 # 2001 4 # 2007 3 # 2003 3 # 2000 2 # Name: Closing Date, Length: 15, dtype: int64","title":"XML\u548cHTML\uff1a\u7f51\u7edc\u6293\u53d6"},{"location":"python/DataAnalysis/ch03/#_6","text":"","title":"\u4e8c\u8fdb\u5236\u683c\u5f0f"},{"location":"python/DataAnalysis/ch03/#web-api","text":"","title":"\u4e0eWeb API\u4ea4\u4e92"},{"location":"python/DataAnalysis/ch03/#_7","text":"","title":"\u4e0e\u6570\u636e\u5e93\u4ea4\u4e92"},{"location":"python/DataAnalysis/ch04/","text":"\u6570\u636e\u6e05\u6d17\u4e0e\u51c6\u5907 \u00b6 \u5904\u7406\u7f3a\u5931\u503c \u00b6 import pandas as pd import numpy as np from numpy import nan as NA \u5bf9\u4e8e\u6570\u503c\u578b\u6570\u636e\uff0cpandas\u4f7f\u7528\u6d6e\u70b9\u503c NaN \uff08Not a Number\u6765\u8868\u793a\u7f3a\u5931\u503c\uff09\u3002 \u5728pandas\u4e2d\uff0c\u91c7\u7528\u4e86R\u8bed\u8a00\u4e2d\u7684\u7f16\u7a0b\u60ef\u4f8b\uff0c\u5c06\u7f3a\u5931\u503c\u6210\u4e3a NA \uff0c\u610f\u601d\u662fnotavailable\uff08\u4e0d\u53ef\u7528\uff09\u3002 Python\u5185\u5efa\u7684 None \u503c\u5728\u5bf9\u8c61\u6570\u7ec4\u4e2d\u4e5f\u88ab\u5f53\u4f5c NA \u5904\u7406\u3002 NA\u5904\u7406\u65b9\u6cd5\uff1a dropna :\u6839\u636e\u6bcf\u4e2a\u6807\u7b7e\u7684\u503c\u662f\u5426\u662f\u786e\u5b9e\u6570\u636e\u6765\u7b5b\u9009\u8f74\u6807\u7b7e\uff0c\u5e76\u6839\u636e\u5141\u8bb8\u4e22\u5931\u7684\u6570\u636e\u91cf\u6765\u786e\u5b9a\u9608\u503c fillna :\u7528\u67d0\u4e9b\u503c\u586b\u5145\u786e\u5b9e\u7684\u6570\u636e\u6216\u4f7f\u7528\u63d2\u503c\u65b9\u6cd5\uff0c\u5982 ffill \u6216 bfill isnull :\u8fd4\u56de\u8868\u660e\u54ea\u4e9b\u503c\u662f\u7f3a\u5931\u503c\u7684\u5e03\u5c14\u503c notnull :\u662f isnull \u7684\u53cd\u51fd\u6570 string_data = pd.Series(['aardvark', 'artichoke', np.nan, 'avocado']) print(string_data) # 0 aardvark # 1 artichoke # 2 NaN # 3 avocado # dtype: object print(string_data.isnull()) # 0 False # 1 False # 2 True # 3 False # dtype: bool string_data[0] = None print(string_data.isnull()) # 0 True # 1 False # 2 True # 3 False # dtype: bool \u8fc7\u6ee4\u7f3a\u5931\u503c \u00b6 \u5904\u7406Series \u00b6 \u5728Series\u4e0a\u4f7f\u7528 dropna \uff0c\u5b83\u4f1a\u8fd4\u56deSeries\u4e2d\u6240\u6709\u7684\u975e\u7a7a\u6570\u636e\u53ca\u5176\u7d22\u5f15\u503c\u3002 data = pd.Series([1, NA, 3.5, NA, 7]) print(data.dropna()) # 0 1.0 # 2 3.5 # 4 7.0 # dtype: float64 print(data[data.notnull()]) # \u4e0e\u4e0a\u9762\u7b49\u4ef7 # 0 1.0 # 2 3.5 # 4 7.0 # dtype: float64 \u5904\u7406DataFrame \u00b6 data = pd.DataFrame( [[1., 6.5, 3.], [1., NA, NA], [NA, NA, NA], [NA, 6.5, 3.]] ) print(data) # 0 1 2 # 0 1.0 6.5 3.0 # 1 1.0 NaN NaN # 2 NaN NaN NaN # 3 NaN 6.5 3.0 cleaned = data.dropna() # dropna\u9ed8\u8ba4\u60c5\u51b5\u4e0b\u4f1a\u5220\u9664\u5305\u542b\u7f3a\u5931\u503c\u7684\u884c print(cleaned) # 0 1 2 # 0 1.0 6.5 3.0 cleaned = data.dropna(how='all') # \u4f20\u5165how='all\u2019\u65f6\uff0c\u5c06\u5220\u9664\u6240\u6709\u503c\u5747\u4e3aNA\u7684\u884c print(cleaned) # 0 1 2 # 0 1.0 6.5 3.0 # 1 1.0 NaN NaN # 3 NaN 6.5 3.0 data[4] = NA print(data) # 0 1 2 4 # 0 1.0 6.5 3.0 NaN # 1 1.0 NaN NaN NaN # 2 NaN NaN NaN NaN # 3 NaN 6.5 3.0 NaN cleaned = data.dropna(axis=1, how='all') # \u5220\u9664\u5168NA\u7684\u5217 print(cleaned) # 0 1 2 # 0 1.0 6.5 3.0 # 1 1.0 NaN NaN # 2 NaN NaN NaN # 3 NaN 6.5 3.0 df = pd.DataFrame(np.random.randn(7, 3)) print(df) # 0 1 2 # 0 -1.069771 -0.777921 0.181956 # 1 -0.399504 -0.641737 -0.946327 # 2 -1.013920 -0.247588 -0.760146 # 3 1.076946 -1.263203 0.494077 # 4 0.460985 -1.241870 0.283006 # 5 1.168149 1.033752 0.900095 # 6 -1.208514 -1.049546 -0.783680 df.iloc[:4, 1] = NA # \u6807\u7b7e1\uff0c\u524d4\u4e2a\u5143\u7d20 df.iloc[:2, 2] = NA # \u6807\u7b7e2\uff0c\u524d2\u4e2a\u5143\u7d20 print(df) # 0 1 2 # 0 -1.069771 NaN NaN # 1 -0.399504 NaN NaN # 2 -1.013920 NaN -0.760146 # 3 1.076946 NaN 0.494077 # 4 0.460985 -1.241870 0.283006 # 5 1.168149 1.033752 0.900095 # 6 -1.208514 -1.049546 -0.783680 cleaned = df.dropna() print(cleaned) # 0 1 2 # 4 0.033663 0.291886 0.736448 # 5 -0.433380 0.397104 1.252005 # 6 -1.999018 0.303866 1.430109 cleaned = df.dropna(thresh=2) # \u4fdd\u75592\u884c\u542bNA\u7684\u89c2\u5bdf\u503c print(cleaned) # 0 1 2 # 2 -1.413976 NaN 0.222274 # 3 -0.644266 NaN 0.324180 # 4 -0.122160 -2.244880 -0.406562 # 5 -0.140326 0.101133 -0.764048 # 6 -1.809141 0.139091 -0.819175 \u8865\u5168\u7f3a\u5931\u503c \u00b6 fillna \u51fd\u6570\u53c2\u6570\uff1a value\uff1a\u6807\u91cf\u503c\u6216\u5b57\u5178\u578b\u5bf9\u8c61\u7528\u4e8e\u586b\u5145\u7f3a\u5931\u503c method\uff1a\u63d2\u503c\u65b9\u6cd5\uff0c\u5982\u679c\u6ca1\u6709\u5176\u4ed6\u53c2\u6570\uff0c\u9ed8\u8ba4\u662f'ffill' axis\uff1a\u9700\u8981\u586b\u5145\u7684\u8f74\uff0c\u9ed8\u8ba4axis=0 inplace\uff1a\u4fee\u6539\u88ab\u8c03\u7528\u5bf9\u8c61\uff0c\u800c\u4e0d\u662f\u751f\u6210\u4e00\u4e2a\u5907\u4efd limit\uff1a\u7528\u4e8e\u524d\u5411\u6216\u540e\u5411\u586b\u5145\u65f6\u6700\u5927\u7684\u586b\u5145\u8303\u56f4 df = pd.DataFrame(np.random.randn(7, 3)) df.iloc[:4, 1] = NA # \u6807\u7b7e1\uff0c\u524d4\u4e2a\u5143\u7d20 df.iloc[:2, 2] = NA # \u6807\u7b7e2\uff0c\u524d2\u4e2a\u5143\u7d20 print(df) # 0 1 2 # 0 -0.181196 NaN NaN # 1 -1.657668 NaN NaN # 2 -0.053454 NaN 0.391461 # 3 -0.539307 NaN -0.668400 # 4 -0.433439 0.839713 -0.295273 # 5 0.749930 1.661641 -0.495165 # 6 0.591810 1.017372 0.932367 result = df.fillna(0) # \u8c03\u7528fillna\u65f6\uff0c\u53ef\u4ee5\u4f7f\u7528\u4e00\u4e2a\u5e38\u6570\u6765\u66ff\u4ee3\u7f3a\u5931\u503c print(result) # 0 1 2 # 0 -0.430926 0.000000 0.000000 # 1 0.448061 0.000000 0.000000 # 2 -0.059910 0.000000 -1.532646 # 3 -0.315793 0.000000 -0.196546 # 4 -0.546106 0.135108 -0.332309 # 5 1.083075 0.346070 -0.773104 # 6 -0.186511 1.055337 -1.168303 result = df.fillna({1: 0.5, 2: 0}) # \u8c03\u7528fillna\u65f6\u4f7f\u7528\u5b57\u5178\uff0c\u53ef\u4ee5\u4e3a\u4e0d\u540c\u5217\u8bbe\u5b9a\u4e0d\u540c\u7684\u586b\u5145\u503c print(result) # 0 1 2 # 0 -0.794344 0.500000 0.000000 # 1 -0.960917 0.500000 0.000000 # 2 1.494351 0.500000 0.100878 # 3 -0.554765 0.500000 1.118801 # 4 -0.866117 0.523615 1.217478 # 5 -0.706966 -0.681776 0.797690 # 6 -1.456366 1.205518 -0.402432 fillna \u8fd4\u56de\u7684\u662f\u4e00\u4e2a\u65b0\u7684\u5bf9\u8c61\uff0c\u4f46\u4e5f\u53ef\u4ee5\u4fee\u6539\u5df2\u7ecf\u5b58\u5728\u7684\u5bf9\u8c61 _ = df.fillna(0, inplace=True) # inplace=True\u6307\u5b9a\u5728\u5df2\u6709\u5bf9\u8c61\u4e0a\u76f4\u63a5\u4fee\u6539 print(df) # 0 1 2 # 0 -1.176124 0.000000 0.000000 # 1 0.120458 0.000000 0.000000 # 2 -1.206408 0.000000 0.551693 # 3 0.224563 0.000000 1.145156 # 4 -0.557836 0.081135 -0.075282 # 5 2.378837 -0.876145 1.430386 # 6 -0.152662 1.278364 0.479686 df = pd.DataFrame(np.random.randn(6, 3)) df.iloc[2:, 1] = NA # \u6807\u7b7e1\uff0c\u524d4\u4e2a\u5143\u7d20 df.iloc[4:, 2] = NA # \u6807\u7b7e2\uff0c\u524d2\u4e2a\u5143\u7d20 print(df) # 0 1 2 # 0 1.154788 0.033949 -0.122807 # 1 0.258684 -0.580244 1.636514 # 2 1.503756 NaN -1.224203 # 3 0.824049 NaN -0.364345 # 4 -1.247609 NaN NaN # 5 -1.019980 NaN NaN result = df.fillna(method='ffill') # \u5411\u540e\u586b\u5145 print(result) # 0 1 2 # 0 2.082449 0.398874 0.359772 # 1 0.233129 0.385347 1.953533 # 2 0.396555 0.385347 0.592784 # 3 -0.957249 0.385347 0.169815 # 4 0.854452 0.385347 0.169815 # 5 -0.105982 0.385347 0.169815 result = df.fillna(method='ffill', limit=3) # \u6bcf\u5217\u6700\u591a\u586b3\u4e2a print(result) result = df.fillna(df[0].max()) # \u75280\u5217\u7684\u6700\u5927\u503c\u586b\u5145\u6240\u6709\u7684NA print(result) # 0 1 2 # 0 -0.377697 -0.852891 -0.705489 # 1 -0.611759 -0.013237 -0.295764 # 2 -0.389974 1.057881 1.041957 # 3 -0.016845 1.057881 -1.149954 # 4 1.057881 1.057881 1.057881 # 5 -0.463471 1.057881 1.057881 \u6570\u636e\u8f6c\u6362 \u00b6 import pandas as pd import numpy as np from numpy import nan as NA \u5220\u9664\u91cd\u590d\u503c \u00b6 data = pd.DataFrame( { 'k1': ['one', 'two'] * 3 + ['two'], 'k2': [1, 1, 2, 3, 4, 4, 4] } ) print(data) # \u91cd\u590d\u51fa\u73b02\u6b21\u7684\u8bb0\u5f55\uff1atwo 4 # k1 k2 # 0 one 1 # 1 two 1 # 2 one 2 # 3 two 3 # 4 one 4 # 5 two 4 # 6 two 4 DataFrame\u7684 duplicated \u65b9\u6cd5\u8fd4\u56de\u7684\u662f\u4e00\u4e2a\u5e03\u5c14\u503cSeries\uff0c\u8fd9\u4e2aSeries\u53cd\u6620\u7684\u662f\u6bcf\u4e00\u884c\u662f\u5426\u5b58\u5728\u91cd\u590d\uff08\u4e0e\u4e4b\u524d\u51fa\u73b0\u8fc7\u7684\u884c\u76f8\u540c\uff09\u60c5\u51b5\uff0c\u9ed8\u8ba4\u662f\u5bf9\u5217\u8fdb\u884c\u64cd\u4f5c\u3002 print(data.duplicated()) # 0 False # 1 False # 2 False # 3 False # 4 False # 5 False # 6 True # dtype: bool drop_duplicates \u8fd4\u56de\u7684\u662fDataFrame\uff0c\u5185\u5bb9\u662f duplicated \u8fd4\u56de\u6570\u7ec4\u4e2d\u4e3a False \u7684\u90e8\u5206\u3002\u9ed8\u8ba4\u662f\u5bf9\u5217\u8fdb\u884c\u64cd\u4f5c\u3002 print(data.drop_duplicates()) # k1 k2 # 0 one 1 # 1 two 1 # 2 one 2 # 3 two 3 # 4 one 4 # 5 two 4 \u53ef\u4ee5\u6307\u5b9a\u6570\u636e\u7684\u4efb\u4f55\u5b50\u96c6\u6765\u68c0\u6d4b\u662f\u5426\u6709\u91cd\u590d\u3002\u5047\u8bbe\u6211\u4eec\u6709\u4e00\u4e2a\u989d\u5916\u7684\u5217\uff0c\u5e76\u60f3\u57fa\u4e8e\u2019k1\u2019\u5217\u53bb\u9664\u91cd\u590d\u503c\u3002 data['v1'] = range(7) print(data) # k1 k2 v1 # 0 one 1 0 # 1 two 1 1 # 2 one 2 2 # 3 two 3 3 # 4 one 4 4 # 5 two 4 5 # 6 two 4 6 print(data.drop_duplicates(['k1'])) # \u4fdd\u7559\u7b2c\u4e00\u4e2a\u89c2\u6d4b\u5230\u7684one\u548ctwo\uff0c\u5176\u4f59\u4e22\u5f03 # k1 k2 v1 # 0 one 1 0 # 1 two 1 1 duplicated \u548c drop_duplicates \u9ed8\u8ba4\u90fd\u662f\u4fdd\u7559\u7b2c\u4e00\u4e2a\u89c2\u6d4b\u5230\u7684\u503c\u3002\u4f20\u5165\u53c2\u6570keep='last\u2019\u5c06\u4f1a\u8fd4\u56de\u6700\u540e\u4e00\u4e2a\u3002 print(data.drop_duplicates(['k1'], keep='last')) # \u4fdd\u7559\u6700\u540e\u4e00\u4e2a\u89c2\u6d4b\u5230\u7684one\u548ctwo # k1 k2 v1 # 4 one 4 4 # 6 two 4 6 \u4f7f\u7528\u51fd\u6570\u6216\u6620\u5c04\u8fdb\u884c\u6570\u636e\u8f6c\u6362 \u00b6 \u4f7f\u7528 map \u662f\u4e00\u79cd\u53ef\u4ee5\u4fbf\u6377\u6267\u884c\u6309\u5143\u7d20\u8f6c\u6362\u53ca\u5176\u4ed6\u6e05\u6d17\u76f8\u5173\u64cd\u4f5c\u7684\u65b9\u6cd5\u3002 data = pd.DataFrame( { 'food': ['bacon', 'pulled pork', 'bacon', 'Pastrami', 'corned beef', 'Bacon', 'pastrami', 'honey ham', 'nova lox'], 'ounces': [4, 3, 12, 6, 7.5, 8, 3, 5, 6] } ) print(data) # food ounces # 0 bacon 4.0 # 1 pulled pork 3.0 # 2 bacon 12.0 # 3 Pastrami 6.0 # 4 corned beef 7.5 # 5 Bacon 8.0 # 6 pastrami 3.0 # 7 honey ham 5.0 # 8 nova lox 6.0 \u6dfb\u52a0\u4e00\u5217\u7528\u4e8e\u8868\u660e\u6bcf\u79cd\u98df\u7269\u7684\u52a8\u7269\u8089\u7c7b\u578b\u3002 \u5148\u521b\u5efa\u4e00\u4e2a\u98df\u7269\u548c\u8089\u7c7b\u7684\u6620\u5c04\u3002 meat_to_animal = { 'bacon': 'pig', 'pulled pork': 'pig', 'pastrami': 'cow', 'corned beef': 'cow', 'honey ham': 'pig', 'nova lox': 'salmon' } lowercased = data['food'].str.lower() # \u4f7f\u7528Series\u7684str.lower\u65b9\u6cd5\u5c06food\u7684\u6bcf\u4e2a\u503c\u90fd\u8f6c\u6362\u4e3a\u5c0f\u5199 print(lowercased) # 0 bacon # 1 pulled pork # 2 bacon # 3 pastrami # 4 corned beef # 5 bacon # 6 pastrami # 7 honey ham # 8 nova lox # Name: food, dtype: object data['animal'] = lowercased.map(meat_to_animal) print(data) # food ounces animal # 0 bacon 4.0 pig # 1 pulled pork 3.0 pig # 2 bacon 12.0 pig # 3 Pastrami 6.0 cow # 4 corned beef 7.5 cow # 5 Bacon 8.0 pig # 6 pastrami 3.0 cow # 7 honey ham 5.0 pig # 8 nova lox 6.0 salmon \u4e5f\u53ef\u4ee5\u4f20\u5165\u4e00\u4e2a\u51fd\u6570\uff0c\u5b8c\u6210\u4e0a\u9762\u6240\u6709\u529f\u80fd\u3002 data = pd.DataFrame( { 'food': ['bacon', 'pulled pork', 'bacon', 'Pastrami', 'corned beef', 'Bacon', 'pastrami', 'honey ham', 'nova lox'], 'ounces': [4, 3, 12, 6, 7.5, 8, 3, 5, 6] } ) result = data['food'].map(lambda x: meat_to_animal[x.lower()]) print(result) # 0 pig # 1 pig # 2 pig # 3 cow # 4 cow # 5 pig # 6 cow # 7 pig # 8 salmon # Name: food, dtype: object \u66ff\u4ee3\u503c \u00b6 \u4f7f\u7528 fillna \u586b\u5145\u7f3a\u5931\u503c\u662f\u901a\u7528\u503c\u66ff\u6362\u7684\u7279\u6b8a\u6848\u4f8b\u3002 map \u53ef\u4ee5\u7528\u6765\u4fee\u6539\u4e00\u4e2a\u5bf9\u8c61\u4e2d\u7684\u5b50\u96c6\u7684\u503c\uff0c\u4f46\u662f replace \u63d0\u4f9b\u4e86\u66f4\u4e3a\u7b80\u5355\u7075\u6d3b\u7684\u5b9e\u73b0\u3002 data.replace \u65b9\u6cd5\u4e0e data.str.replace \u65b9\u6cd5\u662f\u4e0d\u540c\u7684\uff0c data.str.replace \u662f\u5bf9\u5b57\u7b26\u4e32\u8fdb\u884c\u6309\u5143\u7d20\u66ff\u4ee3\u7684\u3002 \u4e0b\u9762\u7684Series\uff0c -999 \u53ef\u80fd\u662f\u7f3a\u5931\u503c\u7684\u6807\u8bc6\u3002\u5982\u679c\u8981\u4f7f\u7528 NA \u6765\u66ff\u4ee3\u8fd9\u4e9b\u503c\uff0c\u53ef\u4ee5\u4f7f\u7528 replace \u65b9\u6cd5\u751f\u6210\u65b0\u7684Series\uff08\u9664\u975e\u4f20\u5165\u4e86 inplace=True \uff09 data = pd.Series([1., -999., 2., -999., -1000., 3.]) print(data) # 0 1.0 # 1 -999.0 # 2 2.0 # 3 -999.0 # 4 -1000.0 # 5 3.0 # dtype: float64 result = data.replace(-999, np.nan) print(result) # 0 1.0 # 1 NaN # 2 2.0 # 3 NaN # 4 -1000.0 # 5 3.0 # dtype: float64 \u8981\u5c06\u4e0d\u540c\u7684\u503c\u66ff\u6362\u4e3a\u4e0d\u540c\u7684\u503c\uff0c\u53ef\u4ee5\u4f20\u5165\u66ff\u4ee3\u503c\u7684\u5217\u8868 result = data.replace([-999, -1000], [np.nan, 0]) print(result) # 0 1.0 # 1 NaN # 2 2.0 # 3 NaN # 4 0.0 # 5 3.0 # dtype: float64 \u4e5f\u53ef\u4ee5\u4f20\u5165\u66ff\u4ee3\u503c\u7684\u5b57\u5178 result = data.replace({-999: np.nan, -1000: 0}) print(result) # 0 1.0 # 1 NaN # 2 2.0 # 3 NaN # 4 0.0 # 5 3.0 # dtype: float64 \u91cd\u547d\u540d\u8f74\u7d22\u5f15 \u00b6 \u548cSeries\u4e2d\u503c\u66ff\u6362\u7c7b\u4f3c\uff0c\u53ef\u4ee5\u901a\u8fc7\u51fd\u6570\u6216\u6620\u5c04\u5bf9\u8f74\u6807\u7b7e\u8fdb\u884c\u7c7b\u4f3c\u7684\u8f6c\u6362\uff0c\u751f\u6210\u65b0\u7684\u4e14\u5e26\u6709\u4e0d\u540c\u6807\u7b7e\u7684\u5bf9\u8c61\u3002 data = pd.DataFrame( np.arange(12).reshape((3, 4)), index=['Ohio', 'Colorado', 'New York'], columns=['one', 'two', 'three', 'four'] ) print(data) # one two three four # Ohio 0 1 2 3 # Colorado 4 5 6 7 # New York 8 9 10 11 \u4e0eSeries\u7c7b\u4f3c\uff0c\u8f74\u7d22\u5f15\u4e5f\u6709\u4e00\u4e2a map \u65b9\u6cd5\u3002 transform = lambda x: x[:4].upper() # \u622a\u53d6index\u7684\u524d\u56db\u4f4d\u5e76\u8f6c\u5316\u4e3a\u5927\u5199\u683c\u5f0f result = data.index.map(transform) print(result) # Index(['OHIO', 'COLO', 'NEW '], dtype='object') \u8d4b\u503c\u7ed9 index \uff0c\u4fee\u6539DataFrame\u3002 data.index = data.index.map(transform) print(data) # one two three four # OHIO 0 1 2 3 # COLO 4 5 6 7 # NEW 8 9 10 11 \u521b\u5efa\u6570\u636e\u96c6\u8f6c\u6362\u540e\u7684\u7248\u672c\uff0c\u5e76\u4e14\u4e0d\u4fee\u6539\u539f\u6709\u7684\u6570\u636e\u96c6\uff0c\u4e00\u4e2a\u6709\u7528\u7684\u65b9\u6cd5\u662f rename \u3002 result = data.rename(index=str.title, columns=str.upper) print(result) # ONE TWO THREE FOUR # Ohio 0 1 2 3 # Colo 4 5 6 7 # New 8 9 10 11 print(data) # \u539f\u6709\u7684\u6570\u636e\u96c6\u672a\u88ab\u4fee\u6539 # one two three four # OHIO 0 1 2 3 # COLO 4 5 6 7 # NEW 8 9 10 11 rename \u53ef\u4ee5\u7ed3\u5408\u5b57\u5178\u578b\u5bf9\u8c61\u4f7f\u7528\uff0c\u4e3a\u8f74\u6807\u7b7e\u7684\u5b50\u96c6\u63d0\u4f9b\u65b0\u7684\u503c\u3002 result = data.rename(index={'OHIO': 'INDIANA'}, columns={'three': 'peekaboo'}) print(result) # one two peekaboo four # INDIANA 0 1 2 3 # COLO 4 5 6 7 # NEW 8 9 10 11 \u5982\u679c\u8981\u4fee\u6539\u539f\u6709\u7684\u6570\u636e\u96c6\uff0c\u4f20\u5165 inplace=True \u3002 data.rename(index={'OHIO': 'INDIANA'}, columns={'three': 'peekaboo'}, inplace=True) print(data) # one two peekaboo four # INDIANA 0 1 2 3 # COLO 4 5 6 7 # NEW 8 9 10 11 \u79bb\u6563\u5316\u548c\u5206\u7bb1 \u00b6 \u8fde\u7eed\u503c\u7ecf\u5e38\u9700\u8981\u79bb\u6563\u5316\uff0c\u6216\u8005\u5206\u79bb\u6210\u201d\u7bb1\u5b50\u201c\u8fdb\u884c\u5206\u6790\u3002 \u5047\u8bbe\u6709\u4e00\u7ec4\u4eba\u7fa4\u7684\u6570\u636e\uff0c\u60f3\u5c06\u4ed6\u4eec\u8fdb\u884c\u5206\u7ec4\uff0c\u653e\u5165\u79bb\u6563\u7684\u5e74\u9f84\u6846\u4e2d\u3002 ages = [20, 22, 25, 27, 21, 23, 37, 31, 61, 45, 41, 32] \u5c06\u8fd9\u4e9b\u5e74\u9f84\u5206\u4e3a18\uff5e25\u300126\uff5e35\u300136\uff5e60\u4ee5\u53ca61\u53ca\u4ee5\u4e0a\u7b49\u82e5\u5e72\u7ec4\uff0c\u4f7f\u7528pandas\u4e2d\u7684 cut \u3002 bins = [18, 25, 35, 60, 100] cats = pd.cut(ages, bins) print(cats) # [(18, 25], (18, 25], (18, 25], (25, 35], (18, 25], ..., (25, 35], (60, 100], (35, 60], (35, 60], (25, 35]] # Length: 12 # Categories (4, interval[int64, right]): [(18, 25] < (25, 35] < (35, 60] < (60, 100]] pandas\u8fd4\u56de\u7684\u5bf9\u8c61\u662f\u4e00\u4e2a\u7279\u6b8a\u7684 Categorical \u5bf9\u8c61\u3002 \u4f60\u770b\u5230\u7684\u8f93\u51fa\u63cf\u8ff0\u4e86\u7531 pandas.cut \u8ba1\u7b97\u51fa\u7684\u7bb1\u3002 \u4f60\u53ef\u4ee5\u5c06\u5b83\u5f53\u4f5c\u4e00\u4e2a\u8868\u793a\u7bb1\u540d\u7684\u5b57\u7b26\u4e32\u6570\u7ec4\uff1b\u5b83\u5728\u5185\u90e8\u5305\u542b\u4e00\u4e2a categories \uff08\u7c7b\u522b\uff09\u6570\u7ec4\uff0c\u5b83\u6307\u5b9a\u4e86\u4e0d\u540c\u7684\u7c7b\u522b\u540d\u79f0\u4ee5\u53ca codes \u5c5e\u6027\u4e2d\u7684 ages \uff08\u5e74\u9f84\uff09\u6570\u636e\u6807\u7b7e\u3002 print(cats.categories) # \u56db\u4e2a\u533a\u95f4\u7ec4 # IntervalIndex([(18, 25], (25, 35], (35, 60], (60, 100]], dtype='interval[int64, right]') print(cats.codes) # 61\u5c81\u843d\u5728\u7b2c3\u7ec4\uff08\u7ec4\u7f16\u53f7\u4ece0\u5f00\u59cb\uff09 # [0 0 0 1 0 0 2 1 3 2 2 1] \u6ce8\u610f\uff0c pd.value_counts(cats) \u662f\u5bf9 pandas.cut \u7684\u7ed3\u679c\u4e2d\u7684\u7bb1\u6570\u91cf\u7684\u8ba1\u6570\u3002 result = pd.value_counts(cats) print(result) # (18, 25] 5 # (25, 35] 3 # (35, 60] 3 # (60, 100] 1 # dtype: int64 \u4e0e\u533a\u95f4\u7684\u6570\u5b66\u7b26\u53f7\u4e00\u81f4\uff0c\u5c0f\u62ec\u53f7\u8868\u793a\u8fb9\u662f\u5f00\u653e\u7684\uff0c\u4e2d\u62ec\u53f7\u8868\u793a\u5b83\u662f\u5c01\u95ed\u7684\uff08\u5305\u62ec\u8fb9\uff09\u3002\u53ef\u4ee5\u901a\u8fc7\u4f20\u9012 right=False \u6765\u6539\u53d8\u54ea\u4e00\u8fb9\u662f\u5c01\u95ed\u7684\u3002\u9ed8\u8ba4 right=True \u3002 result = pd.cut(ages, [18, 26, 36, 61, 100], right=False) print(result) # [[18, 26), [18, 26), [18, 26), [26, 36), [18, 26), ..., [26, 36), [61, 100), [36, 61), [36, 61), [26, 36)] # Length: 12 # Categories (4, interval[int64, left]): [[18, 26) < [26, 36) < [36, 61) < [61, 100)] \u901a\u8fc7\u5411 labels \u9009\u9879\u4f20\u9012\u4e00\u4e2a\u5217\u8868\u6216\u6570\u7ec4\u6765\u4f20\u5165\u81ea\u5b9a\u4e49\u7684\u7bb1\u540d\u3002 group_name = ['Youth', 'YoungAdult', 'MiddleAged', 'Senior'] result = pd.cut(ages, bins, labels=group_name) print(result) # ['Youth', 'Youth', 'Youth', 'YoungAdult', 'Youth', ..., 'YoungAdult', 'Senior', 'MiddleAged', 'MiddleAged', 'YoungAdult'] # Length: 12 # Categories (4, object): ['Youth' < 'YoungAdult' < 'MiddleAged' < 'Senior'] result = pd.value_counts(pd.cut(ages, bins, labels=group_name)) # \u6807\u7b7e\u8f93\u51fa print(result) # Youth 5 # YoungAdult 3 # MiddleAged 3 # Senior 1 # dtype: int64 result = pd.value_counts(pd.cut(ages, bins)) # \u533a\u95f4\u8f93\u51fa print(result) # (18, 25] 5 # (25, 35] 3 # (35, 60] 3 # (60, 100] 1 # dtype: int64 \u5982\u679c\u4f20\u7ed9 cut \u6574\u6570\u4e2a\u7684\u7bb1\u6765\u4ee3\u66ff\u663e\u5f0f\u7684\u7bb1\u8fb9\uff0cpandas\u5c06\u6839\u636e\u6570\u636e\u4e2d\u7684\u6700\u5c0f\u503c\u548c\u6700\u5927\u503c\u8ba1\u7b97\u51fa\u7b49\u957f\u7684\u7bb1\u3002 \u4e0b\u9762\u7684\u4f8b\u5b50\u662f\u8003\u8651\u4e00\u4e9b\u5747\u5300\u5206\u5e03\u7684\u6570\u636e\u88ab\u5207\u6210\u56db\u4efd\u7684\u60c5\u51b5\u3002 data = np.random.rand(20) result = pd.cut(data, 4, precision=2) # precision=2\u7684\u9009\u9879\u5c06\u5341\u8fdb\u5236\u7cbe\u5ea6\u9650\u5236\u5728\u4e24\u4f4d\u3002 print(result) # [(0.44, 0.66], (0.0063, 0.23], (0.23, 0.44], (0.0063, 0.23], (0.23, 0.44], ..., (0.23, 0.44], (0.0063, 0.23], (0.23, 0.44], (0.66, 0.88], (0.23, 0.44]] # Length: 20 # Categories (4, interval[float64, right]): [(0.0063, 0.23] < (0.23, 0.44] < (0.44, 0.66] < (0.66, 0.88]] qcut \u662f\u4e00\u4e2a\u4e0e\u5206\u7bb1\u5bc6\u5207\u76f8\u5173\u7684\u51fd\u6570\uff0c\u5b83\u57fa\u4e8e\u6837\u672c\u5206\u4f4d\u6570\u8fdb\u884c\u5206\u7bb1\u3002 \u53d6\u51b3\u4e8e\u6570\u636e\u7684\u5206\u5e03\uff0c\u4f7f\u7528 cut \u901a\u5e38\u4e0d\u4f1a\u4f7f\u6bcf\u4e2a\u7bb1\u5177\u6709\u76f8\u540c\u6570\u636e\u91cf\u7684\u6570\u636e\u70b9\u3002 \u7531\u4e8eqcut\u4f7f\u7528\u6837\u672c\u7684\u5206\u4f4d\u6570\uff0c\u4f60\u53ef\u4ee5\u901a\u8fc7qcut\u83b7\u5f97\u7b49\u957f\u7684\u7bb1\u3002 data = np.random.randn(1000) # \u6b63\u6001\u5206\u5e03 cats = pd.qcut(data, 4) # \u5207\u62104\u4efd print(cats) # [(-0.00329, 0.644], (-0.00329, 0.644], (-0.659, -0.00329], (-0.659, -0.00329], (0.644, 3.468], ..., (0.644, 3.468], (-3.9619999999999997, -0.659], (-3.9619999999999997, -0.659], (-0.00329, 0.644], (-0.00329, 0.644]] # Length: 1000 # Categories (4, interval[float64, right]): [(-3.9619999999999997, -0.659] < (-0.659, -0.00329] < (-0.00329, 0.644] < (0.644, 3.468]] result = pd.value_counts(cats) print(result) # (-3.9619999999999997, -0.659] 250 # (-0.659, -0.00329] 250 # (-0.00329, 0.644] 250 # (0.644, 3.468] 250 # dtype: int64 \u4e0e cut \u7c7b\u4f3c\uff0c\u53ef\u4ee5\u4f20\u5165\u81ea\u5b9a\u4e49\u7684\u5206\u4f4d\u6570\uff080\u548c1\u4e4b\u95f4\u7684\u6570\u636e\uff0c\u5305\u62ec\u8fb9\uff09\u3002 result = pd.qcut(data, [0, 0.1, 0.5, 0.9, 1.]) print(result) # [(-0.00329, 1.234], (-0.00329, 1.234], (-1.321, -0.00329], (-1.321, -0.00329], (-0.00329, 1.234], ..., (-0.00329, 1.234], (-1.321, -0.00329], (-1.321, -0.00329], (-0.00329, 1.234], (-0.00329, 1.234]] # Length: 1000 # Categories (4, interval[float64, right]): [(-3.9619999999999997, -1.321] < (-1.321, -0.00329] < (-0.00329, 1.234] < (1.234, 3.468]] \u68c0\u6d4b\u548c\u8fc7\u6ee4\u5f02\u5e38\u503c \u00b6 \u8fc7\u6ee4\u6216\u8f6c\u6362\u5f02\u5e38\u503c\u5728\u5f88\u5927\u7a0b\u5ea6\u4e0a\u662f\u5e94\u7528\u6570\u7ec4\u64cd\u4f5c\u7684\u4e8b\u60c5\u3002 \u8003\u8651\u4e00\u4e2a\u5177\u6709\u6b63\u6001\u5206\u5e03\u6570\u636e\u7684DataFrame\u3002 data = pd.DataFrame(np.random.randn(1000, 4)) print(data.describe()) # 0 1 2 3 # count 1000.000000 1000.000000 1000.000000 1000.000000 # mean 0.008124 -0.008050 -0.013403 -0.008261 # std 0.979236 0.992982 0.998819 1.038760 # min -3.231914 -3.441270 -3.345210 -4.320565 # 25% -0.634801 -0.599852 -0.656481 -0.677611 # 50% -0.033252 0.000060 -0.040634 -0.015463 # 75% 0.649340 0.644312 0.678101 0.683849 # max 3.292099 2.758754 2.911447 3.371729 \u627e\u51fa\u4e00\u5217\u4e2d\u7edd\u5bf9\u503c\u5927\u4e8e\u4e09\u7684\u503c\u3002 col = data[2] result = col[np.abs(col) > 3] print(result) # 519 -3.035355 # 536 -3.345210 # Name: 2, dtype: float64 \u9009\u51fa\u6240\u6709\u503c\u5927\u4e8e3\u6216\u5c0f\u4e8e-3\u7684\u884c\uff0c\u53ef\u4ee5\u5bf9\u5e03\u5c14\u503cDataFrame\u4f7f\u7528 any \u65b9\u6cd5\u3002 result = data[(np.abs(data) > 3).any(1)] print(result) # 0 1 2 3 # 116 -0.080907 -3.441270 -0.163263 0.392800 # 139 -1.294440 1.828397 1.178897 -3.469466 # 241 -0.486292 0.150443 0.264172 -3.013440 # 295 3.292099 -0.339284 0.732829 -0.475202 # 355 0.307577 -3.053322 0.967497 0.896363 # 359 3.264981 -1.172096 0.207622 -0.281803 # 519 -0.448987 1.623843 -3.035355 -0.436833 # 533 -1.022616 -0.212597 1.030969 3.371729 # 536 1.067598 -1.306839 -3.345210 0.620834 # 541 -0.952760 -2.157970 -0.403199 -4.320565 # 690 0.006821 -3.104117 0.484881 -0.132613 # 750 -3.231914 1.017712 0.070430 0.631447 # 771 -3.007622 0.257960 -0.118179 -1.283365 # 976 1.684760 -0.003295 -0.249843 3.169371 \u6839\u636e\u8fd9\u4e9b\u6807\u51c6\u6765\u8bbe\u7f6e\u6765\u9650\u5b9a\u503c\uff0c\u4e0b\u9762\u4ee3\u7801\u9650\u5236\u4e86-3\u52303\u4e4b\u95f4\u7684\u6570\u503c\u3002 \u8bed\u53e5 np.sign(data) \u6839\u636e\u6570\u636e\u4e2d\u7684\u503c\u7684\u6b63\u8d1f\u5206\u522b\u751f\u62101\u548c-1\u7684\u6570\u503c\u3002 result = data[(np.abs(data) > 3)] = np.sign(data) * 3 print(result.describe()) # 0 1 2 3 # count 1000.000000 1000.000000 1000.000000 1000.000000 # mean -0.036000 0.000000 -0.084000 -0.048000 # std 3.001285 3.001501 3.000324 3.001117 # min -3.000000 -3.000000 -3.000000 -3.000000 # 25% -3.000000 -3.000000 -3.000000 -3.000000 # 50% -3.000000 0.000000 -3.000000 -3.000000 # 75% 3.000000 3.000000 3.000000 3.000000 # max 3.000000 3.000000 3.000000 3.000000 print(result.head()) # 0 1 2 3 # 0 -3.0 3.0 -3.0 -3.0 # 1 -3.0 -3.0 -3.0 -3.0 # 2 3.0 3.0 -3.0 3.0 # 3 3.0 -3.0 3.0 -3.0 # 4 3.0 -3.0 -3.0 -3.0 \u7f6e\u6362\u548c\u968f\u673a\u62bd\u6837 \u00b6 \u4f7f\u7528 numpy.random.permutation \u5bf9DataFrame\u4e2d\u7684Series\u6216\u884c\u8fdb\u884c\u7f6e\u6362\uff08\u968f\u673a\u91cd\u6392\u5e8f\uff09\u3002 \u5728\u8c03\u7528 permutation \u65f6\u6839\u636e\u4f60\u60f3\u8981\u7684\u8f74\u957f\u5ea6\u53ef\u4ee5\u4ea7\u751f\u4e00\u4e2a\u8868\u793a\u65b0\u987a\u5e8f\u7684\u6574\u6570\u6570\u7ec4\u3002 df = pd.DataFrame(np.arange(5 * 4).reshape((5, 4))) sampler = np.random.permutation(5) print(sampler) # \u8fd4\u56dearray # [1 4 3 0 2] print(df) # 0 1 2 3 # 0 0 1 2 3 # 1 4 5 6 7 # 2 8 9 10 11 # 3 12 13 14 15 # 4 16 17 18 19 \u4e0a\u9762\u8fd4\u56de\u7684 sampler \u6574\u6570\u6570\u7ec4 [1 4 3 0 2] \u7528\u5728\u57fa\u4e8e iloc \u7684\u7d22\u5f15\u6216\u7b49\u4ef7\u7684 take \u51fd\u6570\u4e2d\uff0c\u91cd\u65b0\u6392\u5217\u884c\u987a\u5e8f\u3002 print(df.take(sampler)) # 0 1 2 3 # 1 4 5 6 7 # 4 16 17 18 19 # 3 12 13 14 15 # 0 0 1 2 3 # 2 8 9 10 11 \u9009\u51fa\u4e00\u4e2a\u4e0d\u542b\u6709\u66ff\u4ee3\u503c\u7684\u968f\u673a\u5b50\u96c6\uff0c\u53ef\u4ee5\u4f7f\u7528Series\u548cDataFrame\u7684 sample \u65b9\u6cd5\u3002 result = df.sample(n=3) print(result) # 0 1 2 3 # 0 0 1 2 3 # 2 8 9 10 11 # 1 4 5 6 7 \u8981\u751f\u6210\u4e00\u4e2a\u5e26\u6709\u66ff\u4ee3\u503c\u7684\u6837\u672c\uff08\u5141\u8bb8\u6709\u91cd\u590d\u9009\u62e9\uff09\uff0c\u5c06 replace=True \u4f20\u5165 sample \u65b9\u6cd5\u3002 choice = pd.Series([5, 7, -1, 6, 4]) draws = choice.sample(n=10, replace=True) print(choice) # 0 5 # 1 7 # 2 -1 # 3 6 # 4 4 # dtype: int64 print(draws) # 4 4 # 0 5 # 0 5 # 3 6 # 4 4 # 0 5 # 1 7 # 3 6 # 2 -1 # 0 5 # dtype: int64 \u8ba1\u7b97\u6307\u6807/\u865a\u62df\u53d8\u91cf \u00b6 \u5c06\u5206\u7c7b\u53d8\u91cf\u8f6c\u6362\u4e3a\u201c\u865a\u62df\u201d\u6216\u201c\u6307\u6807\u201d\u77e9\u9635\u662f\u53e6\u4e00\u79cd\u7528\u4e8e\u7edf\u8ba1\u5efa\u6a21\u6216\u673a\u5668\u5b66\u4e60\u7684\u8f6c\u6362\u64cd\u4f5c\u3002 \u5982\u679cDataFrame\u4e2d\u7684\u4e00\u5217\u6709 k \u4e2a\u4e0d\u540c\u7684\u503c\uff0c\u5219\u53ef\u4ee5\u884d\u751f\u4e00\u4e2a k \u5217\u7684\u503c\u4e3a 1 \u548c 0 \u7684\u77e9\u9635\u6216DataFrame\u3002 pandas\u6709\u4e00\u4e2aget_dummies\u51fd\u6570\u7528\u4e8e\u5b9e\u73b0\u8be5\u529f\u80fd\u3002 df = pd.DataFrame( { 'key': ['b', 'b', 'a', 'c', 'a', 'b'], 'data1': range(6) } ) print(df) # key data1 # 0 b 0 # 1 b 1 # 2 a 2 # 3 c 3 # 4 a 4 # 5 b 5 \u5728\u6307\u6807DataFrame\u7684\u5217\u4e0a\u52a0\u5165\u524d\u7f00\uff0c\u7136\u540e\u4e0e\u5176\u4ed6\u6570\u636e\u5408\u5e76\u3002\u5728 get_dummies \u65b9\u6cd5\u4e2d\u6709\u4e00\u4e2a\u524d\u7f00\u53c2\u6570\u7528\u4e8e\u5b9e\u73b0\u8be5\u529f\u80fd\u3002 \u901a\u8fc7 get_dummies \u65b9\u6cd5\uff0c\u628a\u4e0a\u9762 df \u6570\u636e\u6309\u7167 key \u8fdb\u884c\u4e86\u5206\u7ec4\uff0c\u5e76\u901a\u8fc7\u4e0d\u540c\u5217\u6765\u5c55\u73b0\u5206\u7ec4\u540e\u7684\u5bf9\u5e94\u5173\u7cfb\u3002\u4f8b\u5982\uff0c key \u5217\u7684 a \uff0c\u5bf9\u5e94\u503c 2 \u548c 4 \u3002 dummies = pd.get_dummies(df['key'], prefix='key') print(dummies) # key_a key_b key_c # 0 0 1 0 # 1 0 1 0 # 2 1 0 0 # 3 0 0 1 # 4 1 0 0 # 5 0 1 0 df_with_dummy = df[['data1']].join(dummies) print(df_with_dummy) # data1 key_a key_b key_c # 0 0 0 1 0 # 1 1 0 1 0 # 2 2 1 0 0 # 3 3 0 0 1 # 4 4 1 0 0 # 5 5 0 1 0 \u66f4\u4e3a\u590d\u6742\u7684\u60c5\u51b5\uff0cDataFrame\u4e2d\u7684\u4e00\u884c\u5c5e\u4e8e\u591a\u4e2a\u7c7b\u522b\u3002 \u4ee5MovieLens\u76841M\u6570\u636e\u96c6\u4e3a\u4f8b\u3002\u589e\u52a0\u53c2\u6570 encoding='unicode_escape' \u907f\u514d\u51fa\u73b0\u4e0b\u9762\u7684\u9519\u8bef\uff1a UnicodeDecodeError: 'utf-8' codec can't decode byte 0xe9 in position 3114: invalid continuation byte \u589e\u52a0\u53c2\u6570 engine='python' \u907f\u514d\u51fa\u73b0\u4e0b\u9762\u7684\u9519\u8bef\uff1a ParserWarning: Falling back to the 'python' engine because the 'c' engine does not support regex separators (separators > 1 char and different from '\\s+' are interpreted as regex); you can avoid this warning by specifying engine='python'. mnames = ['movie_id', 'title', 'genres'] movies = pd.read_table( '../datasets/movielens/movies.dat', sep='::', header=None, names=mnames, encoding='unicode_escape', engine='python' ) print(movies[:10]) # movie_id title genres # 0 1 Toy Story (1995) Animation|Children's|Comedy # 1 2 Jumanji (1995) Adventure|Children's|Fantasy # 2 3 Grumpier Old Men (1995) Comedy|Romance # 3 4 Waiting to Exhale (1995) Comedy|Drama # 4 5 Father of the Bride Part II (1995) Comedy # 5 6 Heat (1995) Action|Crime|Thriller # 6 7 Sabrina (1995) Comedy|Romance # 7 8 Tom and Huck (1995) Adventure|Children's # 8 9 Sudden Death (1995) Action # 9 10 GoldenEye (1995) Action|Adventure|Thriller \u4e3a\u6bcf\u4e2a\u7535\u5f71\u6d41\u6d3e\u6dfb\u52a0\u6307\u6807\u53d8\u91cf\u9700\u8981\u8fdb\u884c\u4e00\u4e9b\u6570\u636e\u5904\u7406\u3002 \u9996\u5148\uff0c\u6211\u4eec\u4ece\u6570\u636e\u96c6\u4e2d\u63d0\u53d6\u51fa\u6240\u6709\u4e0d\u540c\u7684\u6d41\u6d3e\u7684\u5217\u8868\u3002 all_genres = [] for x in movies.genres: all_genres.extend(x.split('|')) genres = pd.unique(all_genres) print(genres) # ['Animation' \"Children's\" 'Comedy' 'Adventure' 'Fantasy' 'Romance' 'Drama' # 'Action' 'Crime' 'Thriller' 'Horror' 'Sci-Fi' 'Documentary' 'War' # 'Musical' 'Mystery' 'Film-Noir' 'Western'] \u4f7f\u7528\u51680\u7684DataFrame\u662f\u6784\u5efa\u6307\u6807DataFrame\u7684\u4e00\u79cd\u65b9\u5f0f\u3002 zero_matrix = np.zeros((len(movies), len(genres))) dummies = pd.DataFrame(zero_matrix, columns=genres) print(zero_matrix) # [[0. 0. 0. ... 0. 0. 0.] # [0. 0. 0. ... 0. 0. 0.] # [0. 0. 0. ... 0. 0. 0.] # ... # [0. 0. 0. ... 0. 0. 0.] # [0. 0. 0. ... 0. 0. 0.] # [0. 0. 0. ... 0. 0. 0.]] print(dummies.head(n=10)) # Animation Children's Comedy ... Mystery Film-Noir Western # 0 0.0 0.0 0.0 ... 0.0 0.0 0.0 # 1 0.0 0.0 0.0 ... 0.0 0.0 0.0 # 2 0.0 0.0 0.0 ... 0.0 0.0 0.0 # 3 0.0 0.0 0.0 ... 0.0 0.0 0.0 # 4 0.0 0.0 0.0 ... 0.0 0.0 0.0 # 5 0.0 0.0 0.0 ... 0.0 0.0 0.0 # 6 0.0 0.0 0.0 ... 0.0 0.0 0.0 # 7 0.0 0.0 0.0 ... 0.0 0.0 0.0 # 8 0.0 0.0 0.0 ... 0.0 0.0 0.0 # 9 0.0 0.0 0.0 ... 0.0 0.0 0.0 # # [10 rows x 18 columns] \u904d\u5386\u6bcf\u4e00\u90e8\u7535\u5f71\uff0c\u5c06 dummies \u6bcf\u4e00\u884c\u7684\u6761\u76ee\u8bbe\u7f6e\u4e3a 1 \u3002\u4f7f\u7528 dummies.columns \u6765\u8ba1\u7b97\u6bcf\u4e00\u4e2a\u6d41\u6d3e\u7684\u5217\u6307\u6807\u3002 gen = movies.genres[0] print(gen.split('|')) # ['Animation', \"Children's\", 'Comedy'] result = dummies.columns.get_indexer(gen.split('|')) print(result) # [0 1 2] \u4f7f\u7528 .loc \u6839\u636e\u8fd9\u4e9b\u6307\u6807\u6765\u8bbe\u7f6e\u503c\u3002 for i, gen in enumerate(movies.genres): indices = dummies.columns.get_indexer(gen.split('|')) dummies.iloc[i, indices] = 1 \u5c06\u7ed3\u679c\u4e0e movies \u8fdb\u884c\u5408\u5e76\u3002 movies_windic = movies.join(dummies.add_prefix('Genre_')) print(movies_windic.iloc[0]) # movie_id 1 # title Toy Story (1995) # genres Animation|Children's|Comedy # Genre_Animation 1.0 # Genre_Children's 1.0 # Genre_Comedy 1.0 # Genre_Adventure 0.0 # Genre_Fantasy 0.0 # Genre_Romance 0.0 # Genre_Drama 0.0 # Genre_Action 0.0 # Genre_Crime 0.0 # Genre_Thriller 0.0 # Genre_Horror 0.0 # Genre_Sci-Fi 0.0 # Genre_Documentary 0.0 # Genre_War 0.0 # Genre_Musical 0.0 # Genre_Mystery 0.0 # Genre_Film-Noir 0.0 # Genre_Western 0.0 # Name: 0, dtype: object \u5bf9\u4e8e\u66f4\u5927\u7684\u6570\u636e\uff0c\u4e0a\u9762\u8fd9\u79cd\u4f7f\u7528\u591a\u6210\u5458\u6784\u5efa\u6307\u6807\u53d8\u91cf\u5e76\u4e0d\u662f\u7279\u522b\u5feb\u901f\u3002 \u66f4\u597d\u7684\u65b9\u6cd5\u662f\u5199\u4e00\u4e2a\u76f4\u63a5\u5c06\u6570\u636e\u5199\u4e3aNumPy\u6570\u7ec4\u7684\u5e95\u5c42\u51fd\u6570\uff0c\u7136\u540e\u5c06\u7ed3\u679c\u5c01\u88c5\u8fdbDataFrame\u3002 \u5c06 get_dummies \u4e0e cut \u7b49\u79bb\u6563\u5316\u51fd\u6570\u7ed3\u5408\u4f7f\u7528\u662f\u7edf\u8ba1\u5e94\u7528\u7684\u4e00\u4e2a\u6709\u7528\u65b9\u6cd5\u3002 np.random.seed(12345) # \u4f7f\u7528numpy.random.seed\u6765\u8bbe\u7f6e\u968f\u673a\u79cd\u5b50\u4ee5\u786e\u4fdd\u793a\u4f8b\u7684\u786e\u5b9a\u6027 values = np.random.rand(10) print(values) # [0.92961609 0.31637555 0.18391881 0.20456028 0.56772503 0.5955447 # 0.96451452 0.6531771 0.74890664 0.65356987] bins = [0, 0.2, 0.4, 0.6, 0.8, 1] result = pd.get_dummies(pd.cut(values, bins)) print(result) # (0.0, 0.2] (0.2, 0.4] (0.4, 0.6] (0.6, 0.8] (0.8, 1.0] # 0 0 0 0 0 1 # 1 0 1 0 0 0 # 2 1 0 0 0 0 # 3 0 1 0 0 0 # 4 0 0 1 0 0 # 5 0 0 1 0 0 # 6 0 0 0 0 1 # 7 0 0 0 1 0 # 8 0 0 0 1 0 # 9 0 0 0 1 0 \u5b57\u7b26\u4e32\u64cd\u4f5c \u00b6 import re pandas\u5141\u8bb8\u5c06\u5b57\u7b26\u4e32\u548c\u6b63\u5219\u8868\u8fbe\u5f0f\u7b80\u6d01\u5730\u5e94\u7528\u5230\u6574\u4e2a\u6570\u636e\u6570\u7ec4\u4e0a\uff0c\u6b64\u5916\u8fd8\u80fd\u5904\u7406\u6570\u636e\u7f3a\u5931\u3002 \u5b57\u7b26\u4e32\u5bf9\u8c61\u65b9\u6cd5 \u00b6 \u5b57\u4e32\u62c6\u5206\u5408\u5e76\u65b9\u6cd5\u3002\u5728\u5f88\u591a\u5b57\u7b26\u4e32\u5904\u7406\u548c\u811a\u672c\u5e94\u7528\u4e2d\uff0c\u5185\u5efa\u7684\u5b57\u7b26\u4e32\u65b9\u6cd5\u662f\u8db3\u591f\u7684\u3002 \u4f8b\u5982\uff0c\u4e00\u4e2a\u9017\u53f7\u5206\u9694\u7684\u5b57\u7b26\u4e32\u53ef\u4ee5\u4f7f\u7528split\u65b9\u6cd5\u62c6\u5206\u6210\u591a\u5757\u3002 import numpy as np import pandas as pd val = 'a, b, guido' result = val.split(',') print(result) # ['a', ' b', ' guido'] count \uff1a\u8fd4\u56de\u5b50\u5b57\u7b26\u4e32\u5728\u5b57\u7b26\u4e32\u4e2d\u7684\u975e\u91cd\u53e0\u51fa\u73b0\u6b21\u6570\u3002 result = val.count(',') print(result) # 2 endswith \uff1a\u5982\u679c\u5b57\u7b26\u4e32\u4ee5\u540e\u7f00\u7ed3\u5c3e\u5219\u8fd4\u56de True \u3002 startswith \uff1a\u5982\u679c\u5b57\u7b26\u4e32\u4ee5\u540e\u7f00\u7ed3\u5c3e\u5219\u8fd4\u56de True \u3002 result = val.endswith('b') print(result) # False result = val.endswith('o') print(result) # True result = val.startswith('a') print(result) # True split \u5e38\u548c strip \u4e00\u8d77\u4f7f\u7528\uff0c\u7528\u4e8e\u6e05\u9664\u7a7a\u683c\uff08\u5305\u62ec\u6362\u884c\uff09\u3002 split \uff1a\u4f7f\u7528\u5206\u9694\u7b26\u8bb2\u5b57\u7b26\u4e32\u62c6\u5206\u6210\u5b50\u5b57\u7b26\u4e32\u7684\u5217\u8868\u3002 strip \uff0c rstrip \uff0c lstrip \uff1a\u4fee\u526a\u7a7a\u767d\uff0c\u5305\u62ec\u6362\u884c\u7b26\uff1b\u76f8\u5f53\u4e8e\u5bf9\u6bcf\u4e2a\u5143\u7d20\u8fdb\u884c x.strip() (\u4ee5\u53ca rstrip \uff0c lstrip )\u3002 pieces = [x.strip() for x in val.split(',')] print(pieces) # ['a', 'b', 'guido'] \u8fd9\u4e9b\u5b50\u5b57\u7b26\u4e32\u53ef\u4ee5\u4f7f\u7528\u52a0\u6cd5\u4e0e\u4e24\u4e2a\u5192\u53f7\u5206\u9694\u7b26\u8fde\u63a5\u5728\u4e00\u8d77\u3002 first, second, third = pieces result = first + '::' + second + '::' + third print(result) # a::b::guido \u4f46\u662f\u8fd9\u5e76\u4e0d\u662f\u4e00\u4e2a\u5b9e\u7528\u7684\u901a\u7528\u65b9\u6cd5\u3002 \u5728\u5b57\u7b26\u4e32 ': :' \u7684 join \u65b9\u6cd5\u4e2d\u4f20\u5165\u4e00\u4e2a\u5217\u8868\u6216\u5143\u7ec4\u662f\u4e00\u79cd\u66f4\u5feb\u4e14\u66f4\u52a0Pythonic\uff08Python\u98ce\u683c\u5316\uff09\u7684\u65b9\u6cd5\u3002 join : \u4f7f\u7528\u5b57\u7b26\u4e32\u5ea7\u4f4d\u95f4\u9694\u7b26\uff0c\u7528\u4e8e\u7c98\u5408\u5176\u4ed6\u5b57\u7b26\u4e32\u7684\u5e8f\u5217\u3002 result = '::'.join(pieces) print(result) # a::b::guido \u5b9a\u4f4d\u5b50\u5b57\u7b26\u4e32\u7684\u65b9\u6cd5\u3002 \u4f7f\u7528Python\u7684 in \u5173\u952e\u5b57\u662f\u68c0\u6d4b\u5b50\u5b57\u7b26\u4e32\u7684\u6700\u4f73\u65b9\u6cd5\uff0c\u5c3d\u7ba1 index \u548c find \u4e5f\u80fd\u5b9e\u73b0\u540c\u6837\u7684\u529f\u80fd\u3002 result = 'guido' in val print(result) # True index \uff1a\u5982\u679c\u5728\u5b57\u7b26\u4e32\u4e2d\u627e\u5230\uff0c\u5219\u8fd4\u56de\u5b50\u5b57\u7b26\u4e32\u4e2d\u7b2c\u4e00\u4e2a\u5b57\u7b26\u7684\u4f4d\u7f6e\uff0c\u5982\u679c\u627e\u4e0d\u5230\u5219\u89e6\u53d1\u4e00\u4e2a ValueError \u3002 find \uff1a\u8fd4\u56de\u5b57\u7b26\u4e32\u4e2d\u7b2c\u4e00\u4e2a\u51fa\u73b0\u5b50\u5b57\u7b26\u7684\u7b2c\u4e00\u4e2a\u5b57\u7b26\u7684\u4f4d\u7f6e\uff0c\u7c7b\u4f3c index \uff0c\u5982\u679c\u6ca1\u6709\u627e\u5230\uff0c\u5219\u8fd4\u56de -1 \u3002 rfind \uff1a\u8fd4\u56de\u5b57\u7b26\u4e32\u4e2d\u5b50\u5b57\u7b26\u6700\u540e\u4e00\u6b21\u51fa\u73b0\u65f6\u7b2c\u4e00\u4e2a\u5b57\u7b26\u7684\u4f4d\u7f6e\uff0c\u5982\u679c\u6ca1\u6709\u627e\u5230\uff0c\u5219\u8fd4\u56de -1 \u3002 result = val.index(',') print(result) # 1 result = val.find(',') print(result) # 1 # result = val.index(':') print(result) # ValueError: substring not found result = val.find(':') print(result) # -1 result = val.rfind(',') print(result) # 4 replace \u5c06\u7528\u4e00\u79cd\u6a21\u5f0f\u66ff\u4ee3\u53e6\u4e00\u79cd\u6a21\u5f0f\u3002\u5b83\u4e5f\u7528\u4e8e\u4f20\u5165\u7a7a\u5b57\u7b26\u4e32\u6765\u5220\u9664\u67d0\u4e2a\u6a21\u5f0f\u3002 result = val.replace(',', '::') print(result) # a:: b:: guido result = val.replace(', ', '') print(result) # abguido result = val.replace(',', '') print(result) # a b guido lower \uff1a\u5c06\u5927\u5199\u5b57\u6bcd\u8f6c\u6362\u4e3a\u5c0f\u5199\u5b57\u6bcd\u3002 upper \uff1a\u5c06\u5c0f\u5199\u5b57\u6bcd\u8f6c\u6362\u4e3a\u5927\u5199\u5b57\u6bcd\u3002 uppers = val.upper() print(uppers) # A, B, GUIDO casefold \uff1a\u548c lower \u7c7b\u4f3c\uff0c\u5c06\u5b57\u7b26\u4e32\u4e2d\u7684\u5143\u7d20\u53d8\u6210\u5c0f\u5199\uff0c lower \u51fd\u6570\u53ea\u652f\u6301 ascill \u8868\u4e2d\u7684\u5b57\u7b26\uff0c casefold \u652f\u6301\u5f88\u591a\u4e0d\u540c\u79cd\u7c7b\u7684\u8bed\u8a00\u3002 str1 = \"Jan Wei\u03b2@cN\u4e0a\u6d77\" result = str1.casefold() print(result) # jan wei\u03b2@cn\u4e0a\u6d77 result = str1.lower() print(result) # jan wei\u03b2@cn\u4e0a\u6d77 ljust \uff0c rjust \uff1a\u5de6\u5bf9\u9f50\u6216\u8005\u53f3\u5bf9\u9f50\uff1b\u7528\u7a7a\u683c\u6216\u8005\u5176\u5b83\u4e00\u4e9b\u5b57\u7b26\u586b\u5145\u5b57\u7b26\u4e32\u7684\u76f8\u53cd\u4fa7\uff0c\u4ee5\u8fd4\u56de\u5177\u6709\u6700\u5c0f\u5bbd\u5ea6\u7684\u5b57\u7b26\u4e32 str1 = 'https://docs.python.org/3/' str2 = 'https://packagehub.suse.com/package-categories/python/' print(str1.ljust(60, '*')) print(str2.ljust(60, '*')) # https://docs.python.org/3/********************************** # https://packagehub.suse.com/package-categories/python/****** print(str1.rjust(60, '*')) print(str2.rjust(60, '*')) # **********************************https://docs.python.org/3/ # ******https://packagehub.suse.com/package-categories/python/ print(str1.rjust(60)) print(str2.rjust(60)) \u6b63\u5219\u8868\u8fbe\u5f0f \u00b6 Python\u5185\u5efa\u7684 re \u6a21\u5757\u662f\u7528\u4e8e\u5c06\u6b63\u5219\u8868\u8fbe\u5f0f\u5e94\u7528\u5230\u5b57\u7b26\u4e32\u4e0a\u7684\u5e93\u3002 re \u6a21\u5757\u4e3b\u8981\u6709\u4e09\u4e2a\u4e3b\u9898\uff1a\u6a21\u5f0f\u5339\u914d\u3001\u66ff\u4ee3\u3001\u62c6\u5206\u3002 \u770b\u4e00\u4e2a\u7b80\u5355\u7684\u793a\u4f8b\uff1a\u5047\u8bbe\u6211\u4eec\u60f3\u5c06\u542b\u6709\u591a\u79cd\u7a7a\u767d\u5b57\u7b26\uff08\u5236\u8868\u7b26\u3001\u7a7a\u683c\u3001\u6362\u884c\u7b26\uff09\u7684\u5b57\u7b26\u4e32\u62c6\u5206\u5f00\u3002 \u63cf\u8ff0\u4e00\u4e2a\u6216\u591a\u4e2a\u7a7a\u767d\u5b57\u7b26\u7684\u6b63\u5219\u8868\u8fbe\u5f0f\u662f \\s+ \u3002 \u5f53\u8c03\u7528 re.split('\\s+', text) \uff0c\u6b63\u5219\u8868\u8fbe\u5f0f\u9996\u5148\u4f1a\u88ab\u7f16\u8bd1\uff0c\u7136\u540e\u6b63\u5219\u8868\u8fbe\u5f0f\u7684 split \u65b9\u6cd5\u5728\u4f20\u5165\u6587\u672c\u4e0a\u88ab\u8c03\u7528\u3002 text = \"foo bar\\t baz \\tqux\" result = re.split('\\s+', text) print(result) # ['foo', 'bar', 'baz', 'qux'] \u53ef\u4ee5\u4f7f\u7528 re.compile \u81ea\u884c\u7f16\u8bd1\uff0c\u5f62\u6210\u4e00\u4e2a\u53ef\u590d\u7528\u7684\u6b63\u5219\u8868\u8fbe\u5f0f\u5bf9\u8c61\u3002 regex = re.compile('\\s+') result = regex.split(text) print(result) # ['foo', 'bar', 'baz', 'qux'] \u5982\u679c\u60f3\u83b7\u5f97\u7684\u662f\u4e00\u4e2a\u6240\u6709\u5339\u914d\u6b63\u5219\u8868\u8fbe\u5f0f\u7684\u6a21\u5f0f\u7684\u5217\u8868\uff0c\u4f60\u53ef\u4ee5\u4f7f\u7528 findall \u65b9\u6cd5\u3002 result = regex.findall(text) print(result) # [' ', '\\t ', ' \\t'] \u4e3a\u4e86\u5728\u6b63\u5219\u8868\u8fbe\u5f0f\u4e2d\u907f\u514d\u8f6c\u4e49\u7b26 \\ \u7684\u5f71\u54cd\uff0c\u53ef\u4ee5\u4f7f\u7528\u539f\u751f\u5b57\u7b26\u4e32\u8bed\u6cd5\uff0c\u6bd4\u5982 r'C:\\x' \u6216\u8005\u7528\u7b49\u4ef7\u7684 'C:\\\\x'\\ \u3002 \u5982\u679c\u9700\u8981\u5c06\u76f8\u540c\u7684\u8868\u8fbe\u5f0f\u5e94\u7528\u5230\u591a\u4e2a\u5b57\u7b26\u4e32\u4e0a\uff0c\u63a8\u8350\u4f7f\u7528 re.compile \u521b\u5efa\u4e00\u4e2a\u6b63\u5219\u8868\u8fbe\u5f0f\u5bf9\u8c61\uff0c\u8fd9\u6837\u505a\u6709\u5229\u4e8e\u8282\u7ea6CPU\u5468\u671f\u3002 match \u548c search \u4e0e findall \u76f8\u5173\u6027\u5f88\u5927\u3002 findall \u8fd4\u56de\u7684\u662f\u5b57\u7b26\u4e32\u4e2d\u6240\u6709\u7684\u5339\u914d\u9879\uff0c\u800c search \u8fd4\u56de\u7684\u4ec5\u4ec5\u662f\u7b2c\u4e00\u4e2a\u5339\u914d\u9879\u3002 match \u66f4\u4e3a\u4e25\u683c\uff0c\u5b83\u53ea\u5728\u5b57\u7b26\u4e32\u7684\u8d77\u59cb\u4f4d\u7f6e\u8fdb\u884c\u5339\u914d\u3002 text = \"\"\"Dave dave@google.com Steve steve@gmail.com Rob rob@gmail.com Ryan ryan@yahoo.com \"\"\" pattern = r'[A-Z0-9._%+-]+@[A-Z0-9.-]+\\.[A-Z]{2,4}' regex = re.compile(pattern, flags=re.IGNORECASE) # flags=re.IGNORECASE \u4f7f\u6b63\u5219\u8868\u8fbe\u5f0f\u4e0d\u533a\u5206\u5927\u5c0f\u5199 m = regex.findall(text) # findall\u4f1a\u751f\u6210\u4e00\u4e2a\u7535\u5b50\u90ae\u4ef6\u5730\u5740\u7684\u5217\u8868 print(m) # ['dave@google.com', 'steve@gmail.com', 'rob@gmail.com', 'ryan@yahoo.com'] search \u8fd4\u56de\u7684\u662f\u6587\u672c\u4e2d\u7b2c\u4e00\u4e2a\u5339\u914d\u5230\u7684\u7535\u5b50\u90ae\u4ef6\u5730\u5740\u3002 \u5bf9\u4e8e\u524d\u9762\u63d0\u5230\u7684\u6b63\u5219\u8868\u8fbe\u5f0f\uff0c\u5339\u914d\u5bf9\u8c61\u53ea\u80fd\u544a\u8bc9\u6211\u4eec\u6a21\u5f0f\u5728\u5b57\u7b26\u4e32\u4e2d\u8d77\u59cb\u548c\u7ed3\u675f\u7684\u4f4d\u7f6e\u3002 m = regex.search(text) print(m) # print(text[m.start():m.end()]) # dave@google.com regex.match \u53ea\u5728\u6a21\u5f0f\u51fa\u73b0\u4e8e\u5b57\u7b26\u4e32\u8d77\u59cb\u4f4d\u7f6e\u65f6\u8fdb\u884c\u5339\u914d\uff0c\u5982\u679c\u6ca1\u6709\u5339\u914d\u5230\uff0c\u8fd4\u56de None \u3002 m = regex.match(text) print(m) # None m = regex.match('rob@gmail.com') print(m) # print(m.group()) # rob@gmail.com print(m.groups()) # () regex.sub \u4f1a\u8fd4\u56de\u4e00\u4e2a\u65b0\u7684\u5b57\u7b26\u4e32\uff0c\u539f\u5b57\u7b26\u4e32\u4e2d\u7684\u6a21\u5f0f\u4f1a\u88ab\u4e00\u4e2a\u65b0\u7684\u5b57\u7b26\u4e32\u66ff\u4ee3\u3002 m = regex.sub('REDACTED', text) print(m) # Dave REDACTED # Steve REDACTED # Rob REDACTED # Ryan REDACTED \u67e5\u627e\u7535\u5b50\u90ae\u4ef6\u5730\u5740\uff0c\u5e76\u5c06\u6bcf\u4e2a\u5730\u5740\u5206\u4e3a\u4e09\u4e2a\u90e8\u5206\uff1a\u7528\u6237\u540d\uff0c\u57df\u540d\u548c\u57df\u540d\u540e\u7f00\u3002\u8981\u5b9e\u73b0\u8fd9\u4e00\u70b9\uff0c\u53ef\u4ee5\u7528\u62ec\u53f7\u5c06 pattern \u5305\u8d77\u6765\u3002 \u4fee\u6539\u540e\u7684\u6b63\u5219\u8868\u8fbe\u5f0f\u4ea7\u751f\u7684\u5339\u914d\u5bf9\u8c61\u7684 groups \u65b9\u6cd5\uff0c\u8fd4\u56de\u7684\u662f\u6a21\u5f0f\u7ec4\u4ef6\u7684\u5143\u7ec4\u3002 text = \"\"\"Dave dave@google.com Steve steve@gmail.com Rob rob@gmail.com Ryan ryan@yahoo.com \"\"\" pattern = r'([A-Z0-9._%+-]+)@([A-Z0-9.-]+)\\.([A-Z]{2,4})' regex = re.compile(pattern, flags=re.IGNORECASE) m = regex.findall(text) # \u5f53pattern\u53ef\u4ee5\u5206\u7ec4\u65f6\uff0cfindall\u8fd4\u56de\u7684\u662f\u5305\u542b\u5143\u7ec4\u7684\u5217\u8868 print(m) # [('dave', 'google', 'com'), ('steve', 'gmail', 'com'), ('rob', 'gmail', 'com'), ('ryan', 'yahoo', 'com')] m = regex.search(text) print(m) # print(text[m.start():m.end()]) # dave@google.com m = regex.match('rob@gmail.com') print(m) # print(m.group()) # rob@gmail.com print(m.groups()) # ('rob', 'gmail', 'com') m = regex.sub('REDACTED', text) print(m) # Dave REDACTED # Steve REDACTED # Rob REDACTED # Ryan REDACTED m = regex.sub(r'Username: \\1, Domain: \\2, Suffix: \\3', text) print(m) # Dave Username: dave, Domain: google, Suffix: com # Steve Username: steve, Domain: gmail, Suffix: com # Rob Username: rob, Domain: gmail, Suffix: com # Ryan Username: ryan, Domain: yahoo, Suffix: com pandas\u4e2d\u7684\u5411\u91cf\u5316\u5b57\u7b26\u4e32\u51fd\u6570 \u00b6 \u6e05\u7406\u6742\u4e71\u7684\u6570\u636e\u96c6\u7528\u4e8e\u5206\u6790\u901a\u5e38\u9700\u8981\u5927\u91cf\u7684\u5b57\u7b26\u4e32\u5904\u7406\u548c\u6b63\u5219\u5316\u3002 data = { 'Dave': 'dave@gmail.com', 'Steve': 'steve@gmail.com', 'Rob': 'rob@gmail.com', 'Wes': np.nan } data = pd.Series(data) print(data) # Dave dave@gmail.com # Steve steve@gmail.com # Rob rob@gmail.com # Wes NaN # dtype: object print(data.isnull()) # Dave False # Steve False # Rob False # Wes True # dtype: bool \u53ef\u4ee5\u4f7f\u7528 data.map \u5c06\u5b57\u7b26\u4e32\u548c\u6709\u6548\u7684\u6b63\u5219\u8868\u8fbe\u5f0f\u65b9\u6cd5\uff08\u4ee5 lambda \u6216\u5176\u4ed6\u51fd\u6570\u7684\u65b9\u5f0f\u4f20\u9012\uff09\u5e94\u7528\u5230\u6bcf\u4e2a\u503c\u4e0a\uff0c\u4f46\u662f\u5728 NA \uff08 null \uff09\u503c\u4e0a\u4f1a\u5931\u8d25\u3002 \u4e3a\u4e86\u89e3\u51b3\u8fd9\u4e2a\u95ee\u9898\uff0cSeries\u6709\u9762\u5411\u6570\u7ec4\u7684\u65b9\u6cd5\u7528\u4e8e\u8df3\u8fc7 NA \u503c\u7684\u5b57\u7b26\u4e32\u64cd\u4f5c\u3002\u8fd9\u4e9b\u65b9\u6cd5\u901a\u8fc7Series\u7684 str \u5c5e\u6027\u8fdb\u884c\u8c03\u7528\u3002 \u4f8b\u5982\uff0c\u53ef\u4ee5\u901a\u8fc7 str.contains \u6765\u68c0\u67e5\u6bcf\u4e2a\u7535\u5b50\u90ae\u4ef6\u5730\u5740\u662f\u5426\u542b\u6709 'gmail' \u3002 m = data.str.contains('gmail') print(m) # Dave True # Steve True # Rob True # Wes NaN # dtype: object \u6b63\u5219\u8868\u8fbe\u5f0f\u4e5f\u53ef\u4ee5\u7ed3\u5408\u4efb\u610f\u7684 re \u6a21\u5757\u9009\u9879\u4f7f\u7528\uff0c\u4f8b\u5982 IGNORECASE \u3002 print(pattern) # ([A-Z0-9._%+-]+)@([A-Z0-9.-]+)\\.([A-Z]{2,4}) m = data.str.findall(pattern, flags=re.IGNORECASE) print(m) # Dave [(dave, gmail, com)] # Steve [(steve, gmail, com)] # Rob [(rob, gmail, com)] # Wes NaN # dtype: object \u4f7f\u7528 str.get \u6216\u5728 str \u5c5e\u6027\u5185\u90e8\u7d22\u5f15\uff0c\u8fdb\u884c\u5411\u91cf\u5316\u7684\u5143\u7d20\u68c0\u7d22\u3002 m = data.str.match(pattern, flags=re.IGNORECASE) print(m) # Dave True # Steve True # Rob True # Wes NaN # dtype: object m = data.str.findall(pattern, flags=re.IGNORECASE) print(m.str.get(1)) # Dave NaN # Steve NaN # Rob NaN # Wes NaN # dtype: float64 print(m.str[0]) # Dave (dave, gmail, com) # Steve (steve, gmail, com) # Rob (rob, gmail, com) # Wes NaN # dtype: object \u4f7f\u7528\u5b57\u7b26\u4e32\u5207\u7247\u7684\u7c7b\u4f3c\u8bed\u6cd5\u8fdb\u884c\u5411\u91cf\u5316\u5207\u7247\u3002 print(data.str[:]) # Dave dave@gmail.com # Steve steve@gmail.com # Rob rob@gmail.com # Wes NaN # dtype: object print(data.str[:5]) # Dave dave@ # Steve steve # Rob rob@g # Wes NaN # dtype: object","title":"\u6570\u636e\u6e05\u6d17\u4e0e\u51c6\u5907"},{"location":"python/DataAnalysis/ch04/#_1","text":"","title":"\u6570\u636e\u6e05\u6d17\u4e0e\u51c6\u5907"},{"location":"python/DataAnalysis/ch04/#_2","text":"import pandas as pd import numpy as np from numpy import nan as NA \u5bf9\u4e8e\u6570\u503c\u578b\u6570\u636e\uff0cpandas\u4f7f\u7528\u6d6e\u70b9\u503c NaN \uff08Not a Number\u6765\u8868\u793a\u7f3a\u5931\u503c\uff09\u3002 \u5728pandas\u4e2d\uff0c\u91c7\u7528\u4e86R\u8bed\u8a00\u4e2d\u7684\u7f16\u7a0b\u60ef\u4f8b\uff0c\u5c06\u7f3a\u5931\u503c\u6210\u4e3a NA \uff0c\u610f\u601d\u662fnotavailable\uff08\u4e0d\u53ef\u7528\uff09\u3002 Python\u5185\u5efa\u7684 None \u503c\u5728\u5bf9\u8c61\u6570\u7ec4\u4e2d\u4e5f\u88ab\u5f53\u4f5c NA \u5904\u7406\u3002 NA\u5904\u7406\u65b9\u6cd5\uff1a dropna :\u6839\u636e\u6bcf\u4e2a\u6807\u7b7e\u7684\u503c\u662f\u5426\u662f\u786e\u5b9e\u6570\u636e\u6765\u7b5b\u9009\u8f74\u6807\u7b7e\uff0c\u5e76\u6839\u636e\u5141\u8bb8\u4e22\u5931\u7684\u6570\u636e\u91cf\u6765\u786e\u5b9a\u9608\u503c fillna :\u7528\u67d0\u4e9b\u503c\u586b\u5145\u786e\u5b9e\u7684\u6570\u636e\u6216\u4f7f\u7528\u63d2\u503c\u65b9\u6cd5\uff0c\u5982 ffill \u6216 bfill isnull :\u8fd4\u56de\u8868\u660e\u54ea\u4e9b\u503c\u662f\u7f3a\u5931\u503c\u7684\u5e03\u5c14\u503c notnull :\u662f isnull \u7684\u53cd\u51fd\u6570 string_data = pd.Series(['aardvark', 'artichoke', np.nan, 'avocado']) print(string_data) # 0 aardvark # 1 artichoke # 2 NaN # 3 avocado # dtype: object print(string_data.isnull()) # 0 False # 1 False # 2 True # 3 False # dtype: bool string_data[0] = None print(string_data.isnull()) # 0 True # 1 False # 2 True # 3 False # dtype: bool","title":"\u5904\u7406\u7f3a\u5931\u503c"},{"location":"python/DataAnalysis/ch04/#_3","text":"","title":"\u8fc7\u6ee4\u7f3a\u5931\u503c"},{"location":"python/DataAnalysis/ch04/#series","text":"\u5728Series\u4e0a\u4f7f\u7528 dropna \uff0c\u5b83\u4f1a\u8fd4\u56deSeries\u4e2d\u6240\u6709\u7684\u975e\u7a7a\u6570\u636e\u53ca\u5176\u7d22\u5f15\u503c\u3002 data = pd.Series([1, NA, 3.5, NA, 7]) print(data.dropna()) # 0 1.0 # 2 3.5 # 4 7.0 # dtype: float64 print(data[data.notnull()]) # \u4e0e\u4e0a\u9762\u7b49\u4ef7 # 0 1.0 # 2 3.5 # 4 7.0 # dtype: float64","title":"\u5904\u7406Series"},{"location":"python/DataAnalysis/ch04/#dataframe","text":"data = pd.DataFrame( [[1., 6.5, 3.], [1., NA, NA], [NA, NA, NA], [NA, 6.5, 3.]] ) print(data) # 0 1 2 # 0 1.0 6.5 3.0 # 1 1.0 NaN NaN # 2 NaN NaN NaN # 3 NaN 6.5 3.0 cleaned = data.dropna() # dropna\u9ed8\u8ba4\u60c5\u51b5\u4e0b\u4f1a\u5220\u9664\u5305\u542b\u7f3a\u5931\u503c\u7684\u884c print(cleaned) # 0 1 2 # 0 1.0 6.5 3.0 cleaned = data.dropna(how='all') # \u4f20\u5165how='all\u2019\u65f6\uff0c\u5c06\u5220\u9664\u6240\u6709\u503c\u5747\u4e3aNA\u7684\u884c print(cleaned) # 0 1 2 # 0 1.0 6.5 3.0 # 1 1.0 NaN NaN # 3 NaN 6.5 3.0 data[4] = NA print(data) # 0 1 2 4 # 0 1.0 6.5 3.0 NaN # 1 1.0 NaN NaN NaN # 2 NaN NaN NaN NaN # 3 NaN 6.5 3.0 NaN cleaned = data.dropna(axis=1, how='all') # \u5220\u9664\u5168NA\u7684\u5217 print(cleaned) # 0 1 2 # 0 1.0 6.5 3.0 # 1 1.0 NaN NaN # 2 NaN NaN NaN # 3 NaN 6.5 3.0 df = pd.DataFrame(np.random.randn(7, 3)) print(df) # 0 1 2 # 0 -1.069771 -0.777921 0.181956 # 1 -0.399504 -0.641737 -0.946327 # 2 -1.013920 -0.247588 -0.760146 # 3 1.076946 -1.263203 0.494077 # 4 0.460985 -1.241870 0.283006 # 5 1.168149 1.033752 0.900095 # 6 -1.208514 -1.049546 -0.783680 df.iloc[:4, 1] = NA # \u6807\u7b7e1\uff0c\u524d4\u4e2a\u5143\u7d20 df.iloc[:2, 2] = NA # \u6807\u7b7e2\uff0c\u524d2\u4e2a\u5143\u7d20 print(df) # 0 1 2 # 0 -1.069771 NaN NaN # 1 -0.399504 NaN NaN # 2 -1.013920 NaN -0.760146 # 3 1.076946 NaN 0.494077 # 4 0.460985 -1.241870 0.283006 # 5 1.168149 1.033752 0.900095 # 6 -1.208514 -1.049546 -0.783680 cleaned = df.dropna() print(cleaned) # 0 1 2 # 4 0.033663 0.291886 0.736448 # 5 -0.433380 0.397104 1.252005 # 6 -1.999018 0.303866 1.430109 cleaned = df.dropna(thresh=2) # \u4fdd\u75592\u884c\u542bNA\u7684\u89c2\u5bdf\u503c print(cleaned) # 0 1 2 # 2 -1.413976 NaN 0.222274 # 3 -0.644266 NaN 0.324180 # 4 -0.122160 -2.244880 -0.406562 # 5 -0.140326 0.101133 -0.764048 # 6 -1.809141 0.139091 -0.819175","title":"\u5904\u7406DataFrame"},{"location":"python/DataAnalysis/ch04/#_4","text":"fillna \u51fd\u6570\u53c2\u6570\uff1a value\uff1a\u6807\u91cf\u503c\u6216\u5b57\u5178\u578b\u5bf9\u8c61\u7528\u4e8e\u586b\u5145\u7f3a\u5931\u503c method\uff1a\u63d2\u503c\u65b9\u6cd5\uff0c\u5982\u679c\u6ca1\u6709\u5176\u4ed6\u53c2\u6570\uff0c\u9ed8\u8ba4\u662f'ffill' axis\uff1a\u9700\u8981\u586b\u5145\u7684\u8f74\uff0c\u9ed8\u8ba4axis=0 inplace\uff1a\u4fee\u6539\u88ab\u8c03\u7528\u5bf9\u8c61\uff0c\u800c\u4e0d\u662f\u751f\u6210\u4e00\u4e2a\u5907\u4efd limit\uff1a\u7528\u4e8e\u524d\u5411\u6216\u540e\u5411\u586b\u5145\u65f6\u6700\u5927\u7684\u586b\u5145\u8303\u56f4 df = pd.DataFrame(np.random.randn(7, 3)) df.iloc[:4, 1] = NA # \u6807\u7b7e1\uff0c\u524d4\u4e2a\u5143\u7d20 df.iloc[:2, 2] = NA # \u6807\u7b7e2\uff0c\u524d2\u4e2a\u5143\u7d20 print(df) # 0 1 2 # 0 -0.181196 NaN NaN # 1 -1.657668 NaN NaN # 2 -0.053454 NaN 0.391461 # 3 -0.539307 NaN -0.668400 # 4 -0.433439 0.839713 -0.295273 # 5 0.749930 1.661641 -0.495165 # 6 0.591810 1.017372 0.932367 result = df.fillna(0) # \u8c03\u7528fillna\u65f6\uff0c\u53ef\u4ee5\u4f7f\u7528\u4e00\u4e2a\u5e38\u6570\u6765\u66ff\u4ee3\u7f3a\u5931\u503c print(result) # 0 1 2 # 0 -0.430926 0.000000 0.000000 # 1 0.448061 0.000000 0.000000 # 2 -0.059910 0.000000 -1.532646 # 3 -0.315793 0.000000 -0.196546 # 4 -0.546106 0.135108 -0.332309 # 5 1.083075 0.346070 -0.773104 # 6 -0.186511 1.055337 -1.168303 result = df.fillna({1: 0.5, 2: 0}) # \u8c03\u7528fillna\u65f6\u4f7f\u7528\u5b57\u5178\uff0c\u53ef\u4ee5\u4e3a\u4e0d\u540c\u5217\u8bbe\u5b9a\u4e0d\u540c\u7684\u586b\u5145\u503c print(result) # 0 1 2 # 0 -0.794344 0.500000 0.000000 # 1 -0.960917 0.500000 0.000000 # 2 1.494351 0.500000 0.100878 # 3 -0.554765 0.500000 1.118801 # 4 -0.866117 0.523615 1.217478 # 5 -0.706966 -0.681776 0.797690 # 6 -1.456366 1.205518 -0.402432 fillna \u8fd4\u56de\u7684\u662f\u4e00\u4e2a\u65b0\u7684\u5bf9\u8c61\uff0c\u4f46\u4e5f\u53ef\u4ee5\u4fee\u6539\u5df2\u7ecf\u5b58\u5728\u7684\u5bf9\u8c61 _ = df.fillna(0, inplace=True) # inplace=True\u6307\u5b9a\u5728\u5df2\u6709\u5bf9\u8c61\u4e0a\u76f4\u63a5\u4fee\u6539 print(df) # 0 1 2 # 0 -1.176124 0.000000 0.000000 # 1 0.120458 0.000000 0.000000 # 2 -1.206408 0.000000 0.551693 # 3 0.224563 0.000000 1.145156 # 4 -0.557836 0.081135 -0.075282 # 5 2.378837 -0.876145 1.430386 # 6 -0.152662 1.278364 0.479686 df = pd.DataFrame(np.random.randn(6, 3)) df.iloc[2:, 1] = NA # \u6807\u7b7e1\uff0c\u524d4\u4e2a\u5143\u7d20 df.iloc[4:, 2] = NA # \u6807\u7b7e2\uff0c\u524d2\u4e2a\u5143\u7d20 print(df) # 0 1 2 # 0 1.154788 0.033949 -0.122807 # 1 0.258684 -0.580244 1.636514 # 2 1.503756 NaN -1.224203 # 3 0.824049 NaN -0.364345 # 4 -1.247609 NaN NaN # 5 -1.019980 NaN NaN result = df.fillna(method='ffill') # \u5411\u540e\u586b\u5145 print(result) # 0 1 2 # 0 2.082449 0.398874 0.359772 # 1 0.233129 0.385347 1.953533 # 2 0.396555 0.385347 0.592784 # 3 -0.957249 0.385347 0.169815 # 4 0.854452 0.385347 0.169815 # 5 -0.105982 0.385347 0.169815 result = df.fillna(method='ffill', limit=3) # \u6bcf\u5217\u6700\u591a\u586b3\u4e2a print(result) result = df.fillna(df[0].max()) # \u75280\u5217\u7684\u6700\u5927\u503c\u586b\u5145\u6240\u6709\u7684NA print(result) # 0 1 2 # 0 -0.377697 -0.852891 -0.705489 # 1 -0.611759 -0.013237 -0.295764 # 2 -0.389974 1.057881 1.041957 # 3 -0.016845 1.057881 -1.149954 # 4 1.057881 1.057881 1.057881 # 5 -0.463471 1.057881 1.057881","title":"\u8865\u5168\u7f3a\u5931\u503c"},{"location":"python/DataAnalysis/ch04/#_5","text":"import pandas as pd import numpy as np from numpy import nan as NA","title":"\u6570\u636e\u8f6c\u6362"},{"location":"python/DataAnalysis/ch04/#_6","text":"data = pd.DataFrame( { 'k1': ['one', 'two'] * 3 + ['two'], 'k2': [1, 1, 2, 3, 4, 4, 4] } ) print(data) # \u91cd\u590d\u51fa\u73b02\u6b21\u7684\u8bb0\u5f55\uff1atwo 4 # k1 k2 # 0 one 1 # 1 two 1 # 2 one 2 # 3 two 3 # 4 one 4 # 5 two 4 # 6 two 4 DataFrame\u7684 duplicated \u65b9\u6cd5\u8fd4\u56de\u7684\u662f\u4e00\u4e2a\u5e03\u5c14\u503cSeries\uff0c\u8fd9\u4e2aSeries\u53cd\u6620\u7684\u662f\u6bcf\u4e00\u884c\u662f\u5426\u5b58\u5728\u91cd\u590d\uff08\u4e0e\u4e4b\u524d\u51fa\u73b0\u8fc7\u7684\u884c\u76f8\u540c\uff09\u60c5\u51b5\uff0c\u9ed8\u8ba4\u662f\u5bf9\u5217\u8fdb\u884c\u64cd\u4f5c\u3002 print(data.duplicated()) # 0 False # 1 False # 2 False # 3 False # 4 False # 5 False # 6 True # dtype: bool drop_duplicates \u8fd4\u56de\u7684\u662fDataFrame\uff0c\u5185\u5bb9\u662f duplicated \u8fd4\u56de\u6570\u7ec4\u4e2d\u4e3a False \u7684\u90e8\u5206\u3002\u9ed8\u8ba4\u662f\u5bf9\u5217\u8fdb\u884c\u64cd\u4f5c\u3002 print(data.drop_duplicates()) # k1 k2 # 0 one 1 # 1 two 1 # 2 one 2 # 3 two 3 # 4 one 4 # 5 two 4 \u53ef\u4ee5\u6307\u5b9a\u6570\u636e\u7684\u4efb\u4f55\u5b50\u96c6\u6765\u68c0\u6d4b\u662f\u5426\u6709\u91cd\u590d\u3002\u5047\u8bbe\u6211\u4eec\u6709\u4e00\u4e2a\u989d\u5916\u7684\u5217\uff0c\u5e76\u60f3\u57fa\u4e8e\u2019k1\u2019\u5217\u53bb\u9664\u91cd\u590d\u503c\u3002 data['v1'] = range(7) print(data) # k1 k2 v1 # 0 one 1 0 # 1 two 1 1 # 2 one 2 2 # 3 two 3 3 # 4 one 4 4 # 5 two 4 5 # 6 two 4 6 print(data.drop_duplicates(['k1'])) # \u4fdd\u7559\u7b2c\u4e00\u4e2a\u89c2\u6d4b\u5230\u7684one\u548ctwo\uff0c\u5176\u4f59\u4e22\u5f03 # k1 k2 v1 # 0 one 1 0 # 1 two 1 1 duplicated \u548c drop_duplicates \u9ed8\u8ba4\u90fd\u662f\u4fdd\u7559\u7b2c\u4e00\u4e2a\u89c2\u6d4b\u5230\u7684\u503c\u3002\u4f20\u5165\u53c2\u6570keep='last\u2019\u5c06\u4f1a\u8fd4\u56de\u6700\u540e\u4e00\u4e2a\u3002 print(data.drop_duplicates(['k1'], keep='last')) # \u4fdd\u7559\u6700\u540e\u4e00\u4e2a\u89c2\u6d4b\u5230\u7684one\u548ctwo # k1 k2 v1 # 4 one 4 4 # 6 two 4 6","title":"\u5220\u9664\u91cd\u590d\u503c"},{"location":"python/DataAnalysis/ch04/#_7","text":"\u4f7f\u7528 map \u662f\u4e00\u79cd\u53ef\u4ee5\u4fbf\u6377\u6267\u884c\u6309\u5143\u7d20\u8f6c\u6362\u53ca\u5176\u4ed6\u6e05\u6d17\u76f8\u5173\u64cd\u4f5c\u7684\u65b9\u6cd5\u3002 data = pd.DataFrame( { 'food': ['bacon', 'pulled pork', 'bacon', 'Pastrami', 'corned beef', 'Bacon', 'pastrami', 'honey ham', 'nova lox'], 'ounces': [4, 3, 12, 6, 7.5, 8, 3, 5, 6] } ) print(data) # food ounces # 0 bacon 4.0 # 1 pulled pork 3.0 # 2 bacon 12.0 # 3 Pastrami 6.0 # 4 corned beef 7.5 # 5 Bacon 8.0 # 6 pastrami 3.0 # 7 honey ham 5.0 # 8 nova lox 6.0 \u6dfb\u52a0\u4e00\u5217\u7528\u4e8e\u8868\u660e\u6bcf\u79cd\u98df\u7269\u7684\u52a8\u7269\u8089\u7c7b\u578b\u3002 \u5148\u521b\u5efa\u4e00\u4e2a\u98df\u7269\u548c\u8089\u7c7b\u7684\u6620\u5c04\u3002 meat_to_animal = { 'bacon': 'pig', 'pulled pork': 'pig', 'pastrami': 'cow', 'corned beef': 'cow', 'honey ham': 'pig', 'nova lox': 'salmon' } lowercased = data['food'].str.lower() # \u4f7f\u7528Series\u7684str.lower\u65b9\u6cd5\u5c06food\u7684\u6bcf\u4e2a\u503c\u90fd\u8f6c\u6362\u4e3a\u5c0f\u5199 print(lowercased) # 0 bacon # 1 pulled pork # 2 bacon # 3 pastrami # 4 corned beef # 5 bacon # 6 pastrami # 7 honey ham # 8 nova lox # Name: food, dtype: object data['animal'] = lowercased.map(meat_to_animal) print(data) # food ounces animal # 0 bacon 4.0 pig # 1 pulled pork 3.0 pig # 2 bacon 12.0 pig # 3 Pastrami 6.0 cow # 4 corned beef 7.5 cow # 5 Bacon 8.0 pig # 6 pastrami 3.0 cow # 7 honey ham 5.0 pig # 8 nova lox 6.0 salmon \u4e5f\u53ef\u4ee5\u4f20\u5165\u4e00\u4e2a\u51fd\u6570\uff0c\u5b8c\u6210\u4e0a\u9762\u6240\u6709\u529f\u80fd\u3002 data = pd.DataFrame( { 'food': ['bacon', 'pulled pork', 'bacon', 'Pastrami', 'corned beef', 'Bacon', 'pastrami', 'honey ham', 'nova lox'], 'ounces': [4, 3, 12, 6, 7.5, 8, 3, 5, 6] } ) result = data['food'].map(lambda x: meat_to_animal[x.lower()]) print(result) # 0 pig # 1 pig # 2 pig # 3 cow # 4 cow # 5 pig # 6 cow # 7 pig # 8 salmon # Name: food, dtype: object","title":"\u4f7f\u7528\u51fd\u6570\u6216\u6620\u5c04\u8fdb\u884c\u6570\u636e\u8f6c\u6362"},{"location":"python/DataAnalysis/ch04/#_8","text":"\u4f7f\u7528 fillna \u586b\u5145\u7f3a\u5931\u503c\u662f\u901a\u7528\u503c\u66ff\u6362\u7684\u7279\u6b8a\u6848\u4f8b\u3002 map \u53ef\u4ee5\u7528\u6765\u4fee\u6539\u4e00\u4e2a\u5bf9\u8c61\u4e2d\u7684\u5b50\u96c6\u7684\u503c\uff0c\u4f46\u662f replace \u63d0\u4f9b\u4e86\u66f4\u4e3a\u7b80\u5355\u7075\u6d3b\u7684\u5b9e\u73b0\u3002 data.replace \u65b9\u6cd5\u4e0e data.str.replace \u65b9\u6cd5\u662f\u4e0d\u540c\u7684\uff0c data.str.replace \u662f\u5bf9\u5b57\u7b26\u4e32\u8fdb\u884c\u6309\u5143\u7d20\u66ff\u4ee3\u7684\u3002 \u4e0b\u9762\u7684Series\uff0c -999 \u53ef\u80fd\u662f\u7f3a\u5931\u503c\u7684\u6807\u8bc6\u3002\u5982\u679c\u8981\u4f7f\u7528 NA \u6765\u66ff\u4ee3\u8fd9\u4e9b\u503c\uff0c\u53ef\u4ee5\u4f7f\u7528 replace \u65b9\u6cd5\u751f\u6210\u65b0\u7684Series\uff08\u9664\u975e\u4f20\u5165\u4e86 inplace=True \uff09 data = pd.Series([1., -999., 2., -999., -1000., 3.]) print(data) # 0 1.0 # 1 -999.0 # 2 2.0 # 3 -999.0 # 4 -1000.0 # 5 3.0 # dtype: float64 result = data.replace(-999, np.nan) print(result) # 0 1.0 # 1 NaN # 2 2.0 # 3 NaN # 4 -1000.0 # 5 3.0 # dtype: float64 \u8981\u5c06\u4e0d\u540c\u7684\u503c\u66ff\u6362\u4e3a\u4e0d\u540c\u7684\u503c\uff0c\u53ef\u4ee5\u4f20\u5165\u66ff\u4ee3\u503c\u7684\u5217\u8868 result = data.replace([-999, -1000], [np.nan, 0]) print(result) # 0 1.0 # 1 NaN # 2 2.0 # 3 NaN # 4 0.0 # 5 3.0 # dtype: float64 \u4e5f\u53ef\u4ee5\u4f20\u5165\u66ff\u4ee3\u503c\u7684\u5b57\u5178 result = data.replace({-999: np.nan, -1000: 0}) print(result) # 0 1.0 # 1 NaN # 2 2.0 # 3 NaN # 4 0.0 # 5 3.0 # dtype: float64","title":"\u66ff\u4ee3\u503c"},{"location":"python/DataAnalysis/ch04/#_9","text":"\u548cSeries\u4e2d\u503c\u66ff\u6362\u7c7b\u4f3c\uff0c\u53ef\u4ee5\u901a\u8fc7\u51fd\u6570\u6216\u6620\u5c04\u5bf9\u8f74\u6807\u7b7e\u8fdb\u884c\u7c7b\u4f3c\u7684\u8f6c\u6362\uff0c\u751f\u6210\u65b0\u7684\u4e14\u5e26\u6709\u4e0d\u540c\u6807\u7b7e\u7684\u5bf9\u8c61\u3002 data = pd.DataFrame( np.arange(12).reshape((3, 4)), index=['Ohio', 'Colorado', 'New York'], columns=['one', 'two', 'three', 'four'] ) print(data) # one two three four # Ohio 0 1 2 3 # Colorado 4 5 6 7 # New York 8 9 10 11 \u4e0eSeries\u7c7b\u4f3c\uff0c\u8f74\u7d22\u5f15\u4e5f\u6709\u4e00\u4e2a map \u65b9\u6cd5\u3002 transform = lambda x: x[:4].upper() # \u622a\u53d6index\u7684\u524d\u56db\u4f4d\u5e76\u8f6c\u5316\u4e3a\u5927\u5199\u683c\u5f0f result = data.index.map(transform) print(result) # Index(['OHIO', 'COLO', 'NEW '], dtype='object') \u8d4b\u503c\u7ed9 index \uff0c\u4fee\u6539DataFrame\u3002 data.index = data.index.map(transform) print(data) # one two three four # OHIO 0 1 2 3 # COLO 4 5 6 7 # NEW 8 9 10 11 \u521b\u5efa\u6570\u636e\u96c6\u8f6c\u6362\u540e\u7684\u7248\u672c\uff0c\u5e76\u4e14\u4e0d\u4fee\u6539\u539f\u6709\u7684\u6570\u636e\u96c6\uff0c\u4e00\u4e2a\u6709\u7528\u7684\u65b9\u6cd5\u662f rename \u3002 result = data.rename(index=str.title, columns=str.upper) print(result) # ONE TWO THREE FOUR # Ohio 0 1 2 3 # Colo 4 5 6 7 # New 8 9 10 11 print(data) # \u539f\u6709\u7684\u6570\u636e\u96c6\u672a\u88ab\u4fee\u6539 # one two three four # OHIO 0 1 2 3 # COLO 4 5 6 7 # NEW 8 9 10 11 rename \u53ef\u4ee5\u7ed3\u5408\u5b57\u5178\u578b\u5bf9\u8c61\u4f7f\u7528\uff0c\u4e3a\u8f74\u6807\u7b7e\u7684\u5b50\u96c6\u63d0\u4f9b\u65b0\u7684\u503c\u3002 result = data.rename(index={'OHIO': 'INDIANA'}, columns={'three': 'peekaboo'}) print(result) # one two peekaboo four # INDIANA 0 1 2 3 # COLO 4 5 6 7 # NEW 8 9 10 11 \u5982\u679c\u8981\u4fee\u6539\u539f\u6709\u7684\u6570\u636e\u96c6\uff0c\u4f20\u5165 inplace=True \u3002 data.rename(index={'OHIO': 'INDIANA'}, columns={'three': 'peekaboo'}, inplace=True) print(data) # one two peekaboo four # INDIANA 0 1 2 3 # COLO 4 5 6 7 # NEW 8 9 10 11","title":"\u91cd\u547d\u540d\u8f74\u7d22\u5f15"},{"location":"python/DataAnalysis/ch04/#_10","text":"\u8fde\u7eed\u503c\u7ecf\u5e38\u9700\u8981\u79bb\u6563\u5316\uff0c\u6216\u8005\u5206\u79bb\u6210\u201d\u7bb1\u5b50\u201c\u8fdb\u884c\u5206\u6790\u3002 \u5047\u8bbe\u6709\u4e00\u7ec4\u4eba\u7fa4\u7684\u6570\u636e\uff0c\u60f3\u5c06\u4ed6\u4eec\u8fdb\u884c\u5206\u7ec4\uff0c\u653e\u5165\u79bb\u6563\u7684\u5e74\u9f84\u6846\u4e2d\u3002 ages = [20, 22, 25, 27, 21, 23, 37, 31, 61, 45, 41, 32] \u5c06\u8fd9\u4e9b\u5e74\u9f84\u5206\u4e3a18\uff5e25\u300126\uff5e35\u300136\uff5e60\u4ee5\u53ca61\u53ca\u4ee5\u4e0a\u7b49\u82e5\u5e72\u7ec4\uff0c\u4f7f\u7528pandas\u4e2d\u7684 cut \u3002 bins = [18, 25, 35, 60, 100] cats = pd.cut(ages, bins) print(cats) # [(18, 25], (18, 25], (18, 25], (25, 35], (18, 25], ..., (25, 35], (60, 100], (35, 60], (35, 60], (25, 35]] # Length: 12 # Categories (4, interval[int64, right]): [(18, 25] < (25, 35] < (35, 60] < (60, 100]] pandas\u8fd4\u56de\u7684\u5bf9\u8c61\u662f\u4e00\u4e2a\u7279\u6b8a\u7684 Categorical \u5bf9\u8c61\u3002 \u4f60\u770b\u5230\u7684\u8f93\u51fa\u63cf\u8ff0\u4e86\u7531 pandas.cut \u8ba1\u7b97\u51fa\u7684\u7bb1\u3002 \u4f60\u53ef\u4ee5\u5c06\u5b83\u5f53\u4f5c\u4e00\u4e2a\u8868\u793a\u7bb1\u540d\u7684\u5b57\u7b26\u4e32\u6570\u7ec4\uff1b\u5b83\u5728\u5185\u90e8\u5305\u542b\u4e00\u4e2a categories \uff08\u7c7b\u522b\uff09\u6570\u7ec4\uff0c\u5b83\u6307\u5b9a\u4e86\u4e0d\u540c\u7684\u7c7b\u522b\u540d\u79f0\u4ee5\u53ca codes \u5c5e\u6027\u4e2d\u7684 ages \uff08\u5e74\u9f84\uff09\u6570\u636e\u6807\u7b7e\u3002 print(cats.categories) # \u56db\u4e2a\u533a\u95f4\u7ec4 # IntervalIndex([(18, 25], (25, 35], (35, 60], (60, 100]], dtype='interval[int64, right]') print(cats.codes) # 61\u5c81\u843d\u5728\u7b2c3\u7ec4\uff08\u7ec4\u7f16\u53f7\u4ece0\u5f00\u59cb\uff09 # [0 0 0 1 0 0 2 1 3 2 2 1] \u6ce8\u610f\uff0c pd.value_counts(cats) \u662f\u5bf9 pandas.cut \u7684\u7ed3\u679c\u4e2d\u7684\u7bb1\u6570\u91cf\u7684\u8ba1\u6570\u3002 result = pd.value_counts(cats) print(result) # (18, 25] 5 # (25, 35] 3 # (35, 60] 3 # (60, 100] 1 # dtype: int64 \u4e0e\u533a\u95f4\u7684\u6570\u5b66\u7b26\u53f7\u4e00\u81f4\uff0c\u5c0f\u62ec\u53f7\u8868\u793a\u8fb9\u662f\u5f00\u653e\u7684\uff0c\u4e2d\u62ec\u53f7\u8868\u793a\u5b83\u662f\u5c01\u95ed\u7684\uff08\u5305\u62ec\u8fb9\uff09\u3002\u53ef\u4ee5\u901a\u8fc7\u4f20\u9012 right=False \u6765\u6539\u53d8\u54ea\u4e00\u8fb9\u662f\u5c01\u95ed\u7684\u3002\u9ed8\u8ba4 right=True \u3002 result = pd.cut(ages, [18, 26, 36, 61, 100], right=False) print(result) # [[18, 26), [18, 26), [18, 26), [26, 36), [18, 26), ..., [26, 36), [61, 100), [36, 61), [36, 61), [26, 36)] # Length: 12 # Categories (4, interval[int64, left]): [[18, 26) < [26, 36) < [36, 61) < [61, 100)] \u901a\u8fc7\u5411 labels \u9009\u9879\u4f20\u9012\u4e00\u4e2a\u5217\u8868\u6216\u6570\u7ec4\u6765\u4f20\u5165\u81ea\u5b9a\u4e49\u7684\u7bb1\u540d\u3002 group_name = ['Youth', 'YoungAdult', 'MiddleAged', 'Senior'] result = pd.cut(ages, bins, labels=group_name) print(result) # ['Youth', 'Youth', 'Youth', 'YoungAdult', 'Youth', ..., 'YoungAdult', 'Senior', 'MiddleAged', 'MiddleAged', 'YoungAdult'] # Length: 12 # Categories (4, object): ['Youth' < 'YoungAdult' < 'MiddleAged' < 'Senior'] result = pd.value_counts(pd.cut(ages, bins, labels=group_name)) # \u6807\u7b7e\u8f93\u51fa print(result) # Youth 5 # YoungAdult 3 # MiddleAged 3 # Senior 1 # dtype: int64 result = pd.value_counts(pd.cut(ages, bins)) # \u533a\u95f4\u8f93\u51fa print(result) # (18, 25] 5 # (25, 35] 3 # (35, 60] 3 # (60, 100] 1 # dtype: int64 \u5982\u679c\u4f20\u7ed9 cut \u6574\u6570\u4e2a\u7684\u7bb1\u6765\u4ee3\u66ff\u663e\u5f0f\u7684\u7bb1\u8fb9\uff0cpandas\u5c06\u6839\u636e\u6570\u636e\u4e2d\u7684\u6700\u5c0f\u503c\u548c\u6700\u5927\u503c\u8ba1\u7b97\u51fa\u7b49\u957f\u7684\u7bb1\u3002 \u4e0b\u9762\u7684\u4f8b\u5b50\u662f\u8003\u8651\u4e00\u4e9b\u5747\u5300\u5206\u5e03\u7684\u6570\u636e\u88ab\u5207\u6210\u56db\u4efd\u7684\u60c5\u51b5\u3002 data = np.random.rand(20) result = pd.cut(data, 4, precision=2) # precision=2\u7684\u9009\u9879\u5c06\u5341\u8fdb\u5236\u7cbe\u5ea6\u9650\u5236\u5728\u4e24\u4f4d\u3002 print(result) # [(0.44, 0.66], (0.0063, 0.23], (0.23, 0.44], (0.0063, 0.23], (0.23, 0.44], ..., (0.23, 0.44], (0.0063, 0.23], (0.23, 0.44], (0.66, 0.88], (0.23, 0.44]] # Length: 20 # Categories (4, interval[float64, right]): [(0.0063, 0.23] < (0.23, 0.44] < (0.44, 0.66] < (0.66, 0.88]] qcut \u662f\u4e00\u4e2a\u4e0e\u5206\u7bb1\u5bc6\u5207\u76f8\u5173\u7684\u51fd\u6570\uff0c\u5b83\u57fa\u4e8e\u6837\u672c\u5206\u4f4d\u6570\u8fdb\u884c\u5206\u7bb1\u3002 \u53d6\u51b3\u4e8e\u6570\u636e\u7684\u5206\u5e03\uff0c\u4f7f\u7528 cut \u901a\u5e38\u4e0d\u4f1a\u4f7f\u6bcf\u4e2a\u7bb1\u5177\u6709\u76f8\u540c\u6570\u636e\u91cf\u7684\u6570\u636e\u70b9\u3002 \u7531\u4e8eqcut\u4f7f\u7528\u6837\u672c\u7684\u5206\u4f4d\u6570\uff0c\u4f60\u53ef\u4ee5\u901a\u8fc7qcut\u83b7\u5f97\u7b49\u957f\u7684\u7bb1\u3002 data = np.random.randn(1000) # \u6b63\u6001\u5206\u5e03 cats = pd.qcut(data, 4) # \u5207\u62104\u4efd print(cats) # [(-0.00329, 0.644], (-0.00329, 0.644], (-0.659, -0.00329], (-0.659, -0.00329], (0.644, 3.468], ..., (0.644, 3.468], (-3.9619999999999997, -0.659], (-3.9619999999999997, -0.659], (-0.00329, 0.644], (-0.00329, 0.644]] # Length: 1000 # Categories (4, interval[float64, right]): [(-3.9619999999999997, -0.659] < (-0.659, -0.00329] < (-0.00329, 0.644] < (0.644, 3.468]] result = pd.value_counts(cats) print(result) # (-3.9619999999999997, -0.659] 250 # (-0.659, -0.00329] 250 # (-0.00329, 0.644] 250 # (0.644, 3.468] 250 # dtype: int64 \u4e0e cut \u7c7b\u4f3c\uff0c\u53ef\u4ee5\u4f20\u5165\u81ea\u5b9a\u4e49\u7684\u5206\u4f4d\u6570\uff080\u548c1\u4e4b\u95f4\u7684\u6570\u636e\uff0c\u5305\u62ec\u8fb9\uff09\u3002 result = pd.qcut(data, [0, 0.1, 0.5, 0.9, 1.]) print(result) # [(-0.00329, 1.234], (-0.00329, 1.234], (-1.321, -0.00329], (-1.321, -0.00329], (-0.00329, 1.234], ..., (-0.00329, 1.234], (-1.321, -0.00329], (-1.321, -0.00329], (-0.00329, 1.234], (-0.00329, 1.234]] # Length: 1000 # Categories (4, interval[float64, right]): [(-3.9619999999999997, -1.321] < (-1.321, -0.00329] < (-0.00329, 1.234] < (1.234, 3.468]]","title":"\u79bb\u6563\u5316\u548c\u5206\u7bb1"},{"location":"python/DataAnalysis/ch04/#_11","text":"\u8fc7\u6ee4\u6216\u8f6c\u6362\u5f02\u5e38\u503c\u5728\u5f88\u5927\u7a0b\u5ea6\u4e0a\u662f\u5e94\u7528\u6570\u7ec4\u64cd\u4f5c\u7684\u4e8b\u60c5\u3002 \u8003\u8651\u4e00\u4e2a\u5177\u6709\u6b63\u6001\u5206\u5e03\u6570\u636e\u7684DataFrame\u3002 data = pd.DataFrame(np.random.randn(1000, 4)) print(data.describe()) # 0 1 2 3 # count 1000.000000 1000.000000 1000.000000 1000.000000 # mean 0.008124 -0.008050 -0.013403 -0.008261 # std 0.979236 0.992982 0.998819 1.038760 # min -3.231914 -3.441270 -3.345210 -4.320565 # 25% -0.634801 -0.599852 -0.656481 -0.677611 # 50% -0.033252 0.000060 -0.040634 -0.015463 # 75% 0.649340 0.644312 0.678101 0.683849 # max 3.292099 2.758754 2.911447 3.371729 \u627e\u51fa\u4e00\u5217\u4e2d\u7edd\u5bf9\u503c\u5927\u4e8e\u4e09\u7684\u503c\u3002 col = data[2] result = col[np.abs(col) > 3] print(result) # 519 -3.035355 # 536 -3.345210 # Name: 2, dtype: float64 \u9009\u51fa\u6240\u6709\u503c\u5927\u4e8e3\u6216\u5c0f\u4e8e-3\u7684\u884c\uff0c\u53ef\u4ee5\u5bf9\u5e03\u5c14\u503cDataFrame\u4f7f\u7528 any \u65b9\u6cd5\u3002 result = data[(np.abs(data) > 3).any(1)] print(result) # 0 1 2 3 # 116 -0.080907 -3.441270 -0.163263 0.392800 # 139 -1.294440 1.828397 1.178897 -3.469466 # 241 -0.486292 0.150443 0.264172 -3.013440 # 295 3.292099 -0.339284 0.732829 -0.475202 # 355 0.307577 -3.053322 0.967497 0.896363 # 359 3.264981 -1.172096 0.207622 -0.281803 # 519 -0.448987 1.623843 -3.035355 -0.436833 # 533 -1.022616 -0.212597 1.030969 3.371729 # 536 1.067598 -1.306839 -3.345210 0.620834 # 541 -0.952760 -2.157970 -0.403199 -4.320565 # 690 0.006821 -3.104117 0.484881 -0.132613 # 750 -3.231914 1.017712 0.070430 0.631447 # 771 -3.007622 0.257960 -0.118179 -1.283365 # 976 1.684760 -0.003295 -0.249843 3.169371 \u6839\u636e\u8fd9\u4e9b\u6807\u51c6\u6765\u8bbe\u7f6e\u6765\u9650\u5b9a\u503c\uff0c\u4e0b\u9762\u4ee3\u7801\u9650\u5236\u4e86-3\u52303\u4e4b\u95f4\u7684\u6570\u503c\u3002 \u8bed\u53e5 np.sign(data) \u6839\u636e\u6570\u636e\u4e2d\u7684\u503c\u7684\u6b63\u8d1f\u5206\u522b\u751f\u62101\u548c-1\u7684\u6570\u503c\u3002 result = data[(np.abs(data) > 3)] = np.sign(data) * 3 print(result.describe()) # 0 1 2 3 # count 1000.000000 1000.000000 1000.000000 1000.000000 # mean -0.036000 0.000000 -0.084000 -0.048000 # std 3.001285 3.001501 3.000324 3.001117 # min -3.000000 -3.000000 -3.000000 -3.000000 # 25% -3.000000 -3.000000 -3.000000 -3.000000 # 50% -3.000000 0.000000 -3.000000 -3.000000 # 75% 3.000000 3.000000 3.000000 3.000000 # max 3.000000 3.000000 3.000000 3.000000 print(result.head()) # 0 1 2 3 # 0 -3.0 3.0 -3.0 -3.0 # 1 -3.0 -3.0 -3.0 -3.0 # 2 3.0 3.0 -3.0 3.0 # 3 3.0 -3.0 3.0 -3.0 # 4 3.0 -3.0 -3.0 -3.0","title":"\u68c0\u6d4b\u548c\u8fc7\u6ee4\u5f02\u5e38\u503c"},{"location":"python/DataAnalysis/ch04/#_12","text":"\u4f7f\u7528 numpy.random.permutation \u5bf9DataFrame\u4e2d\u7684Series\u6216\u884c\u8fdb\u884c\u7f6e\u6362\uff08\u968f\u673a\u91cd\u6392\u5e8f\uff09\u3002 \u5728\u8c03\u7528 permutation \u65f6\u6839\u636e\u4f60\u60f3\u8981\u7684\u8f74\u957f\u5ea6\u53ef\u4ee5\u4ea7\u751f\u4e00\u4e2a\u8868\u793a\u65b0\u987a\u5e8f\u7684\u6574\u6570\u6570\u7ec4\u3002 df = pd.DataFrame(np.arange(5 * 4).reshape((5, 4))) sampler = np.random.permutation(5) print(sampler) # \u8fd4\u56dearray # [1 4 3 0 2] print(df) # 0 1 2 3 # 0 0 1 2 3 # 1 4 5 6 7 # 2 8 9 10 11 # 3 12 13 14 15 # 4 16 17 18 19 \u4e0a\u9762\u8fd4\u56de\u7684 sampler \u6574\u6570\u6570\u7ec4 [1 4 3 0 2] \u7528\u5728\u57fa\u4e8e iloc \u7684\u7d22\u5f15\u6216\u7b49\u4ef7\u7684 take \u51fd\u6570\u4e2d\uff0c\u91cd\u65b0\u6392\u5217\u884c\u987a\u5e8f\u3002 print(df.take(sampler)) # 0 1 2 3 # 1 4 5 6 7 # 4 16 17 18 19 # 3 12 13 14 15 # 0 0 1 2 3 # 2 8 9 10 11 \u9009\u51fa\u4e00\u4e2a\u4e0d\u542b\u6709\u66ff\u4ee3\u503c\u7684\u968f\u673a\u5b50\u96c6\uff0c\u53ef\u4ee5\u4f7f\u7528Series\u548cDataFrame\u7684 sample \u65b9\u6cd5\u3002 result = df.sample(n=3) print(result) # 0 1 2 3 # 0 0 1 2 3 # 2 8 9 10 11 # 1 4 5 6 7 \u8981\u751f\u6210\u4e00\u4e2a\u5e26\u6709\u66ff\u4ee3\u503c\u7684\u6837\u672c\uff08\u5141\u8bb8\u6709\u91cd\u590d\u9009\u62e9\uff09\uff0c\u5c06 replace=True \u4f20\u5165 sample \u65b9\u6cd5\u3002 choice = pd.Series([5, 7, -1, 6, 4]) draws = choice.sample(n=10, replace=True) print(choice) # 0 5 # 1 7 # 2 -1 # 3 6 # 4 4 # dtype: int64 print(draws) # 4 4 # 0 5 # 0 5 # 3 6 # 4 4 # 0 5 # 1 7 # 3 6 # 2 -1 # 0 5 # dtype: int64","title":"\u7f6e\u6362\u548c\u968f\u673a\u62bd\u6837"},{"location":"python/DataAnalysis/ch04/#_13","text":"\u5c06\u5206\u7c7b\u53d8\u91cf\u8f6c\u6362\u4e3a\u201c\u865a\u62df\u201d\u6216\u201c\u6307\u6807\u201d\u77e9\u9635\u662f\u53e6\u4e00\u79cd\u7528\u4e8e\u7edf\u8ba1\u5efa\u6a21\u6216\u673a\u5668\u5b66\u4e60\u7684\u8f6c\u6362\u64cd\u4f5c\u3002 \u5982\u679cDataFrame\u4e2d\u7684\u4e00\u5217\u6709 k \u4e2a\u4e0d\u540c\u7684\u503c\uff0c\u5219\u53ef\u4ee5\u884d\u751f\u4e00\u4e2a k \u5217\u7684\u503c\u4e3a 1 \u548c 0 \u7684\u77e9\u9635\u6216DataFrame\u3002 pandas\u6709\u4e00\u4e2aget_dummies\u51fd\u6570\u7528\u4e8e\u5b9e\u73b0\u8be5\u529f\u80fd\u3002 df = pd.DataFrame( { 'key': ['b', 'b', 'a', 'c', 'a', 'b'], 'data1': range(6) } ) print(df) # key data1 # 0 b 0 # 1 b 1 # 2 a 2 # 3 c 3 # 4 a 4 # 5 b 5 \u5728\u6307\u6807DataFrame\u7684\u5217\u4e0a\u52a0\u5165\u524d\u7f00\uff0c\u7136\u540e\u4e0e\u5176\u4ed6\u6570\u636e\u5408\u5e76\u3002\u5728 get_dummies \u65b9\u6cd5\u4e2d\u6709\u4e00\u4e2a\u524d\u7f00\u53c2\u6570\u7528\u4e8e\u5b9e\u73b0\u8be5\u529f\u80fd\u3002 \u901a\u8fc7 get_dummies \u65b9\u6cd5\uff0c\u628a\u4e0a\u9762 df \u6570\u636e\u6309\u7167 key \u8fdb\u884c\u4e86\u5206\u7ec4\uff0c\u5e76\u901a\u8fc7\u4e0d\u540c\u5217\u6765\u5c55\u73b0\u5206\u7ec4\u540e\u7684\u5bf9\u5e94\u5173\u7cfb\u3002\u4f8b\u5982\uff0c key \u5217\u7684 a \uff0c\u5bf9\u5e94\u503c 2 \u548c 4 \u3002 dummies = pd.get_dummies(df['key'], prefix='key') print(dummies) # key_a key_b key_c # 0 0 1 0 # 1 0 1 0 # 2 1 0 0 # 3 0 0 1 # 4 1 0 0 # 5 0 1 0 df_with_dummy = df[['data1']].join(dummies) print(df_with_dummy) # data1 key_a key_b key_c # 0 0 0 1 0 # 1 1 0 1 0 # 2 2 1 0 0 # 3 3 0 0 1 # 4 4 1 0 0 # 5 5 0 1 0 \u66f4\u4e3a\u590d\u6742\u7684\u60c5\u51b5\uff0cDataFrame\u4e2d\u7684\u4e00\u884c\u5c5e\u4e8e\u591a\u4e2a\u7c7b\u522b\u3002 \u4ee5MovieLens\u76841M\u6570\u636e\u96c6\u4e3a\u4f8b\u3002\u589e\u52a0\u53c2\u6570 encoding='unicode_escape' \u907f\u514d\u51fa\u73b0\u4e0b\u9762\u7684\u9519\u8bef\uff1a UnicodeDecodeError: 'utf-8' codec can't decode byte 0xe9 in position 3114: invalid continuation byte \u589e\u52a0\u53c2\u6570 engine='python' \u907f\u514d\u51fa\u73b0\u4e0b\u9762\u7684\u9519\u8bef\uff1a ParserWarning: Falling back to the 'python' engine because the 'c' engine does not support regex separators (separators > 1 char and different from '\\s+' are interpreted as regex); you can avoid this warning by specifying engine='python'. mnames = ['movie_id', 'title', 'genres'] movies = pd.read_table( '../datasets/movielens/movies.dat', sep='::', header=None, names=mnames, encoding='unicode_escape', engine='python' ) print(movies[:10]) # movie_id title genres # 0 1 Toy Story (1995) Animation|Children's|Comedy # 1 2 Jumanji (1995) Adventure|Children's|Fantasy # 2 3 Grumpier Old Men (1995) Comedy|Romance # 3 4 Waiting to Exhale (1995) Comedy|Drama # 4 5 Father of the Bride Part II (1995) Comedy # 5 6 Heat (1995) Action|Crime|Thriller # 6 7 Sabrina (1995) Comedy|Romance # 7 8 Tom and Huck (1995) Adventure|Children's # 8 9 Sudden Death (1995) Action # 9 10 GoldenEye (1995) Action|Adventure|Thriller \u4e3a\u6bcf\u4e2a\u7535\u5f71\u6d41\u6d3e\u6dfb\u52a0\u6307\u6807\u53d8\u91cf\u9700\u8981\u8fdb\u884c\u4e00\u4e9b\u6570\u636e\u5904\u7406\u3002 \u9996\u5148\uff0c\u6211\u4eec\u4ece\u6570\u636e\u96c6\u4e2d\u63d0\u53d6\u51fa\u6240\u6709\u4e0d\u540c\u7684\u6d41\u6d3e\u7684\u5217\u8868\u3002 all_genres = [] for x in movies.genres: all_genres.extend(x.split('|')) genres = pd.unique(all_genres) print(genres) # ['Animation' \"Children's\" 'Comedy' 'Adventure' 'Fantasy' 'Romance' 'Drama' # 'Action' 'Crime' 'Thriller' 'Horror' 'Sci-Fi' 'Documentary' 'War' # 'Musical' 'Mystery' 'Film-Noir' 'Western'] \u4f7f\u7528\u51680\u7684DataFrame\u662f\u6784\u5efa\u6307\u6807DataFrame\u7684\u4e00\u79cd\u65b9\u5f0f\u3002 zero_matrix = np.zeros((len(movies), len(genres))) dummies = pd.DataFrame(zero_matrix, columns=genres) print(zero_matrix) # [[0. 0. 0. ... 0. 0. 0.] # [0. 0. 0. ... 0. 0. 0.] # [0. 0. 0. ... 0. 0. 0.] # ... # [0. 0. 0. ... 0. 0. 0.] # [0. 0. 0. ... 0. 0. 0.] # [0. 0. 0. ... 0. 0. 0.]] print(dummies.head(n=10)) # Animation Children's Comedy ... Mystery Film-Noir Western # 0 0.0 0.0 0.0 ... 0.0 0.0 0.0 # 1 0.0 0.0 0.0 ... 0.0 0.0 0.0 # 2 0.0 0.0 0.0 ... 0.0 0.0 0.0 # 3 0.0 0.0 0.0 ... 0.0 0.0 0.0 # 4 0.0 0.0 0.0 ... 0.0 0.0 0.0 # 5 0.0 0.0 0.0 ... 0.0 0.0 0.0 # 6 0.0 0.0 0.0 ... 0.0 0.0 0.0 # 7 0.0 0.0 0.0 ... 0.0 0.0 0.0 # 8 0.0 0.0 0.0 ... 0.0 0.0 0.0 # 9 0.0 0.0 0.0 ... 0.0 0.0 0.0 # # [10 rows x 18 columns] \u904d\u5386\u6bcf\u4e00\u90e8\u7535\u5f71\uff0c\u5c06 dummies \u6bcf\u4e00\u884c\u7684\u6761\u76ee\u8bbe\u7f6e\u4e3a 1 \u3002\u4f7f\u7528 dummies.columns \u6765\u8ba1\u7b97\u6bcf\u4e00\u4e2a\u6d41\u6d3e\u7684\u5217\u6307\u6807\u3002 gen = movies.genres[0] print(gen.split('|')) # ['Animation', \"Children's\", 'Comedy'] result = dummies.columns.get_indexer(gen.split('|')) print(result) # [0 1 2] \u4f7f\u7528 .loc \u6839\u636e\u8fd9\u4e9b\u6307\u6807\u6765\u8bbe\u7f6e\u503c\u3002 for i, gen in enumerate(movies.genres): indices = dummies.columns.get_indexer(gen.split('|')) dummies.iloc[i, indices] = 1 \u5c06\u7ed3\u679c\u4e0e movies \u8fdb\u884c\u5408\u5e76\u3002 movies_windic = movies.join(dummies.add_prefix('Genre_')) print(movies_windic.iloc[0]) # movie_id 1 # title Toy Story (1995) # genres Animation|Children's|Comedy # Genre_Animation 1.0 # Genre_Children's 1.0 # Genre_Comedy 1.0 # Genre_Adventure 0.0 # Genre_Fantasy 0.0 # Genre_Romance 0.0 # Genre_Drama 0.0 # Genre_Action 0.0 # Genre_Crime 0.0 # Genre_Thriller 0.0 # Genre_Horror 0.0 # Genre_Sci-Fi 0.0 # Genre_Documentary 0.0 # Genre_War 0.0 # Genre_Musical 0.0 # Genre_Mystery 0.0 # Genre_Film-Noir 0.0 # Genre_Western 0.0 # Name: 0, dtype: object \u5bf9\u4e8e\u66f4\u5927\u7684\u6570\u636e\uff0c\u4e0a\u9762\u8fd9\u79cd\u4f7f\u7528\u591a\u6210\u5458\u6784\u5efa\u6307\u6807\u53d8\u91cf\u5e76\u4e0d\u662f\u7279\u522b\u5feb\u901f\u3002 \u66f4\u597d\u7684\u65b9\u6cd5\u662f\u5199\u4e00\u4e2a\u76f4\u63a5\u5c06\u6570\u636e\u5199\u4e3aNumPy\u6570\u7ec4\u7684\u5e95\u5c42\u51fd\u6570\uff0c\u7136\u540e\u5c06\u7ed3\u679c\u5c01\u88c5\u8fdbDataFrame\u3002 \u5c06 get_dummies \u4e0e cut \u7b49\u79bb\u6563\u5316\u51fd\u6570\u7ed3\u5408\u4f7f\u7528\u662f\u7edf\u8ba1\u5e94\u7528\u7684\u4e00\u4e2a\u6709\u7528\u65b9\u6cd5\u3002 np.random.seed(12345) # \u4f7f\u7528numpy.random.seed\u6765\u8bbe\u7f6e\u968f\u673a\u79cd\u5b50\u4ee5\u786e\u4fdd\u793a\u4f8b\u7684\u786e\u5b9a\u6027 values = np.random.rand(10) print(values) # [0.92961609 0.31637555 0.18391881 0.20456028 0.56772503 0.5955447 # 0.96451452 0.6531771 0.74890664 0.65356987] bins = [0, 0.2, 0.4, 0.6, 0.8, 1] result = pd.get_dummies(pd.cut(values, bins)) print(result) # (0.0, 0.2] (0.2, 0.4] (0.4, 0.6] (0.6, 0.8] (0.8, 1.0] # 0 0 0 0 0 1 # 1 0 1 0 0 0 # 2 1 0 0 0 0 # 3 0 1 0 0 0 # 4 0 0 1 0 0 # 5 0 0 1 0 0 # 6 0 0 0 0 1 # 7 0 0 0 1 0 # 8 0 0 0 1 0 # 9 0 0 0 1 0","title":"\u8ba1\u7b97\u6307\u6807/\u865a\u62df\u53d8\u91cf"},{"location":"python/DataAnalysis/ch04/#_14","text":"import re pandas\u5141\u8bb8\u5c06\u5b57\u7b26\u4e32\u548c\u6b63\u5219\u8868\u8fbe\u5f0f\u7b80\u6d01\u5730\u5e94\u7528\u5230\u6574\u4e2a\u6570\u636e\u6570\u7ec4\u4e0a\uff0c\u6b64\u5916\u8fd8\u80fd\u5904\u7406\u6570\u636e\u7f3a\u5931\u3002","title":"\u5b57\u7b26\u4e32\u64cd\u4f5c"},{"location":"python/DataAnalysis/ch04/#_15","text":"\u5b57\u4e32\u62c6\u5206\u5408\u5e76\u65b9\u6cd5\u3002\u5728\u5f88\u591a\u5b57\u7b26\u4e32\u5904\u7406\u548c\u811a\u672c\u5e94\u7528\u4e2d\uff0c\u5185\u5efa\u7684\u5b57\u7b26\u4e32\u65b9\u6cd5\u662f\u8db3\u591f\u7684\u3002 \u4f8b\u5982\uff0c\u4e00\u4e2a\u9017\u53f7\u5206\u9694\u7684\u5b57\u7b26\u4e32\u53ef\u4ee5\u4f7f\u7528split\u65b9\u6cd5\u62c6\u5206\u6210\u591a\u5757\u3002 import numpy as np import pandas as pd val = 'a, b, guido' result = val.split(',') print(result) # ['a', ' b', ' guido'] count \uff1a\u8fd4\u56de\u5b50\u5b57\u7b26\u4e32\u5728\u5b57\u7b26\u4e32\u4e2d\u7684\u975e\u91cd\u53e0\u51fa\u73b0\u6b21\u6570\u3002 result = val.count(',') print(result) # 2 endswith \uff1a\u5982\u679c\u5b57\u7b26\u4e32\u4ee5\u540e\u7f00\u7ed3\u5c3e\u5219\u8fd4\u56de True \u3002 startswith \uff1a\u5982\u679c\u5b57\u7b26\u4e32\u4ee5\u540e\u7f00\u7ed3\u5c3e\u5219\u8fd4\u56de True \u3002 result = val.endswith('b') print(result) # False result = val.endswith('o') print(result) # True result = val.startswith('a') print(result) # True split \u5e38\u548c strip \u4e00\u8d77\u4f7f\u7528\uff0c\u7528\u4e8e\u6e05\u9664\u7a7a\u683c\uff08\u5305\u62ec\u6362\u884c\uff09\u3002 split \uff1a\u4f7f\u7528\u5206\u9694\u7b26\u8bb2\u5b57\u7b26\u4e32\u62c6\u5206\u6210\u5b50\u5b57\u7b26\u4e32\u7684\u5217\u8868\u3002 strip \uff0c rstrip \uff0c lstrip \uff1a\u4fee\u526a\u7a7a\u767d\uff0c\u5305\u62ec\u6362\u884c\u7b26\uff1b\u76f8\u5f53\u4e8e\u5bf9\u6bcf\u4e2a\u5143\u7d20\u8fdb\u884c x.strip() (\u4ee5\u53ca rstrip \uff0c lstrip )\u3002 pieces = [x.strip() for x in val.split(',')] print(pieces) # ['a', 'b', 'guido'] \u8fd9\u4e9b\u5b50\u5b57\u7b26\u4e32\u53ef\u4ee5\u4f7f\u7528\u52a0\u6cd5\u4e0e\u4e24\u4e2a\u5192\u53f7\u5206\u9694\u7b26\u8fde\u63a5\u5728\u4e00\u8d77\u3002 first, second, third = pieces result = first + '::' + second + '::' + third print(result) # a::b::guido \u4f46\u662f\u8fd9\u5e76\u4e0d\u662f\u4e00\u4e2a\u5b9e\u7528\u7684\u901a\u7528\u65b9\u6cd5\u3002 \u5728\u5b57\u7b26\u4e32 ': :' \u7684 join \u65b9\u6cd5\u4e2d\u4f20\u5165\u4e00\u4e2a\u5217\u8868\u6216\u5143\u7ec4\u662f\u4e00\u79cd\u66f4\u5feb\u4e14\u66f4\u52a0Pythonic\uff08Python\u98ce\u683c\u5316\uff09\u7684\u65b9\u6cd5\u3002 join : \u4f7f\u7528\u5b57\u7b26\u4e32\u5ea7\u4f4d\u95f4\u9694\u7b26\uff0c\u7528\u4e8e\u7c98\u5408\u5176\u4ed6\u5b57\u7b26\u4e32\u7684\u5e8f\u5217\u3002 result = '::'.join(pieces) print(result) # a::b::guido \u5b9a\u4f4d\u5b50\u5b57\u7b26\u4e32\u7684\u65b9\u6cd5\u3002 \u4f7f\u7528Python\u7684 in \u5173\u952e\u5b57\u662f\u68c0\u6d4b\u5b50\u5b57\u7b26\u4e32\u7684\u6700\u4f73\u65b9\u6cd5\uff0c\u5c3d\u7ba1 index \u548c find \u4e5f\u80fd\u5b9e\u73b0\u540c\u6837\u7684\u529f\u80fd\u3002 result = 'guido' in val print(result) # True index \uff1a\u5982\u679c\u5728\u5b57\u7b26\u4e32\u4e2d\u627e\u5230\uff0c\u5219\u8fd4\u56de\u5b50\u5b57\u7b26\u4e32\u4e2d\u7b2c\u4e00\u4e2a\u5b57\u7b26\u7684\u4f4d\u7f6e\uff0c\u5982\u679c\u627e\u4e0d\u5230\u5219\u89e6\u53d1\u4e00\u4e2a ValueError \u3002 find \uff1a\u8fd4\u56de\u5b57\u7b26\u4e32\u4e2d\u7b2c\u4e00\u4e2a\u51fa\u73b0\u5b50\u5b57\u7b26\u7684\u7b2c\u4e00\u4e2a\u5b57\u7b26\u7684\u4f4d\u7f6e\uff0c\u7c7b\u4f3c index \uff0c\u5982\u679c\u6ca1\u6709\u627e\u5230\uff0c\u5219\u8fd4\u56de -1 \u3002 rfind \uff1a\u8fd4\u56de\u5b57\u7b26\u4e32\u4e2d\u5b50\u5b57\u7b26\u6700\u540e\u4e00\u6b21\u51fa\u73b0\u65f6\u7b2c\u4e00\u4e2a\u5b57\u7b26\u7684\u4f4d\u7f6e\uff0c\u5982\u679c\u6ca1\u6709\u627e\u5230\uff0c\u5219\u8fd4\u56de -1 \u3002 result = val.index(',') print(result) # 1 result = val.find(',') print(result) # 1 # result = val.index(':') print(result) # ValueError: substring not found result = val.find(':') print(result) # -1 result = val.rfind(',') print(result) # 4 replace \u5c06\u7528\u4e00\u79cd\u6a21\u5f0f\u66ff\u4ee3\u53e6\u4e00\u79cd\u6a21\u5f0f\u3002\u5b83\u4e5f\u7528\u4e8e\u4f20\u5165\u7a7a\u5b57\u7b26\u4e32\u6765\u5220\u9664\u67d0\u4e2a\u6a21\u5f0f\u3002 result = val.replace(',', '::') print(result) # a:: b:: guido result = val.replace(', ', '') print(result) # abguido result = val.replace(',', '') print(result) # a b guido lower \uff1a\u5c06\u5927\u5199\u5b57\u6bcd\u8f6c\u6362\u4e3a\u5c0f\u5199\u5b57\u6bcd\u3002 upper \uff1a\u5c06\u5c0f\u5199\u5b57\u6bcd\u8f6c\u6362\u4e3a\u5927\u5199\u5b57\u6bcd\u3002 uppers = val.upper() print(uppers) # A, B, GUIDO casefold \uff1a\u548c lower \u7c7b\u4f3c\uff0c\u5c06\u5b57\u7b26\u4e32\u4e2d\u7684\u5143\u7d20\u53d8\u6210\u5c0f\u5199\uff0c lower \u51fd\u6570\u53ea\u652f\u6301 ascill \u8868\u4e2d\u7684\u5b57\u7b26\uff0c casefold \u652f\u6301\u5f88\u591a\u4e0d\u540c\u79cd\u7c7b\u7684\u8bed\u8a00\u3002 str1 = \"Jan Wei\u03b2@cN\u4e0a\u6d77\" result = str1.casefold() print(result) # jan wei\u03b2@cn\u4e0a\u6d77 result = str1.lower() print(result) # jan wei\u03b2@cn\u4e0a\u6d77 ljust \uff0c rjust \uff1a\u5de6\u5bf9\u9f50\u6216\u8005\u53f3\u5bf9\u9f50\uff1b\u7528\u7a7a\u683c\u6216\u8005\u5176\u5b83\u4e00\u4e9b\u5b57\u7b26\u586b\u5145\u5b57\u7b26\u4e32\u7684\u76f8\u53cd\u4fa7\uff0c\u4ee5\u8fd4\u56de\u5177\u6709\u6700\u5c0f\u5bbd\u5ea6\u7684\u5b57\u7b26\u4e32 str1 = 'https://docs.python.org/3/' str2 = 'https://packagehub.suse.com/package-categories/python/' print(str1.ljust(60, '*')) print(str2.ljust(60, '*')) # https://docs.python.org/3/********************************** # https://packagehub.suse.com/package-categories/python/****** print(str1.rjust(60, '*')) print(str2.rjust(60, '*')) # **********************************https://docs.python.org/3/ # ******https://packagehub.suse.com/package-categories/python/ print(str1.rjust(60)) print(str2.rjust(60))","title":"\u5b57\u7b26\u4e32\u5bf9\u8c61\u65b9\u6cd5"},{"location":"python/DataAnalysis/ch04/#_16","text":"Python\u5185\u5efa\u7684 re \u6a21\u5757\u662f\u7528\u4e8e\u5c06\u6b63\u5219\u8868\u8fbe\u5f0f\u5e94\u7528\u5230\u5b57\u7b26\u4e32\u4e0a\u7684\u5e93\u3002 re \u6a21\u5757\u4e3b\u8981\u6709\u4e09\u4e2a\u4e3b\u9898\uff1a\u6a21\u5f0f\u5339\u914d\u3001\u66ff\u4ee3\u3001\u62c6\u5206\u3002 \u770b\u4e00\u4e2a\u7b80\u5355\u7684\u793a\u4f8b\uff1a\u5047\u8bbe\u6211\u4eec\u60f3\u5c06\u542b\u6709\u591a\u79cd\u7a7a\u767d\u5b57\u7b26\uff08\u5236\u8868\u7b26\u3001\u7a7a\u683c\u3001\u6362\u884c\u7b26\uff09\u7684\u5b57\u7b26\u4e32\u62c6\u5206\u5f00\u3002 \u63cf\u8ff0\u4e00\u4e2a\u6216\u591a\u4e2a\u7a7a\u767d\u5b57\u7b26\u7684\u6b63\u5219\u8868\u8fbe\u5f0f\u662f \\s+ \u3002 \u5f53\u8c03\u7528 re.split('\\s+', text) \uff0c\u6b63\u5219\u8868\u8fbe\u5f0f\u9996\u5148\u4f1a\u88ab\u7f16\u8bd1\uff0c\u7136\u540e\u6b63\u5219\u8868\u8fbe\u5f0f\u7684 split \u65b9\u6cd5\u5728\u4f20\u5165\u6587\u672c\u4e0a\u88ab\u8c03\u7528\u3002 text = \"foo bar\\t baz \\tqux\" result = re.split('\\s+', text) print(result) # ['foo', 'bar', 'baz', 'qux'] \u53ef\u4ee5\u4f7f\u7528 re.compile \u81ea\u884c\u7f16\u8bd1\uff0c\u5f62\u6210\u4e00\u4e2a\u53ef\u590d\u7528\u7684\u6b63\u5219\u8868\u8fbe\u5f0f\u5bf9\u8c61\u3002 regex = re.compile('\\s+') result = regex.split(text) print(result) # ['foo', 'bar', 'baz', 'qux'] \u5982\u679c\u60f3\u83b7\u5f97\u7684\u662f\u4e00\u4e2a\u6240\u6709\u5339\u914d\u6b63\u5219\u8868\u8fbe\u5f0f\u7684\u6a21\u5f0f\u7684\u5217\u8868\uff0c\u4f60\u53ef\u4ee5\u4f7f\u7528 findall \u65b9\u6cd5\u3002 result = regex.findall(text) print(result) # [' ', '\\t ', ' \\t'] \u4e3a\u4e86\u5728\u6b63\u5219\u8868\u8fbe\u5f0f\u4e2d\u907f\u514d\u8f6c\u4e49\u7b26 \\ \u7684\u5f71\u54cd\uff0c\u53ef\u4ee5\u4f7f\u7528\u539f\u751f\u5b57\u7b26\u4e32\u8bed\u6cd5\uff0c\u6bd4\u5982 r'C:\\x' \u6216\u8005\u7528\u7b49\u4ef7\u7684 'C:\\\\x'\\ \u3002 \u5982\u679c\u9700\u8981\u5c06\u76f8\u540c\u7684\u8868\u8fbe\u5f0f\u5e94\u7528\u5230\u591a\u4e2a\u5b57\u7b26\u4e32\u4e0a\uff0c\u63a8\u8350\u4f7f\u7528 re.compile \u521b\u5efa\u4e00\u4e2a\u6b63\u5219\u8868\u8fbe\u5f0f\u5bf9\u8c61\uff0c\u8fd9\u6837\u505a\u6709\u5229\u4e8e\u8282\u7ea6CPU\u5468\u671f\u3002 match \u548c search \u4e0e findall \u76f8\u5173\u6027\u5f88\u5927\u3002 findall \u8fd4\u56de\u7684\u662f\u5b57\u7b26\u4e32\u4e2d\u6240\u6709\u7684\u5339\u914d\u9879\uff0c\u800c search \u8fd4\u56de\u7684\u4ec5\u4ec5\u662f\u7b2c\u4e00\u4e2a\u5339\u914d\u9879\u3002 match \u66f4\u4e3a\u4e25\u683c\uff0c\u5b83\u53ea\u5728\u5b57\u7b26\u4e32\u7684\u8d77\u59cb\u4f4d\u7f6e\u8fdb\u884c\u5339\u914d\u3002 text = \"\"\"Dave dave@google.com Steve steve@gmail.com Rob rob@gmail.com Ryan ryan@yahoo.com \"\"\" pattern = r'[A-Z0-9._%+-]+@[A-Z0-9.-]+\\.[A-Z]{2,4}' regex = re.compile(pattern, flags=re.IGNORECASE) # flags=re.IGNORECASE \u4f7f\u6b63\u5219\u8868\u8fbe\u5f0f\u4e0d\u533a\u5206\u5927\u5c0f\u5199 m = regex.findall(text) # findall\u4f1a\u751f\u6210\u4e00\u4e2a\u7535\u5b50\u90ae\u4ef6\u5730\u5740\u7684\u5217\u8868 print(m) # ['dave@google.com', 'steve@gmail.com', 'rob@gmail.com', 'ryan@yahoo.com'] search \u8fd4\u56de\u7684\u662f\u6587\u672c\u4e2d\u7b2c\u4e00\u4e2a\u5339\u914d\u5230\u7684\u7535\u5b50\u90ae\u4ef6\u5730\u5740\u3002 \u5bf9\u4e8e\u524d\u9762\u63d0\u5230\u7684\u6b63\u5219\u8868\u8fbe\u5f0f\uff0c\u5339\u914d\u5bf9\u8c61\u53ea\u80fd\u544a\u8bc9\u6211\u4eec\u6a21\u5f0f\u5728\u5b57\u7b26\u4e32\u4e2d\u8d77\u59cb\u548c\u7ed3\u675f\u7684\u4f4d\u7f6e\u3002 m = regex.search(text) print(m) # print(text[m.start():m.end()]) # dave@google.com regex.match \u53ea\u5728\u6a21\u5f0f\u51fa\u73b0\u4e8e\u5b57\u7b26\u4e32\u8d77\u59cb\u4f4d\u7f6e\u65f6\u8fdb\u884c\u5339\u914d\uff0c\u5982\u679c\u6ca1\u6709\u5339\u914d\u5230\uff0c\u8fd4\u56de None \u3002 m = regex.match(text) print(m) # None m = regex.match('rob@gmail.com') print(m) # print(m.group()) # rob@gmail.com print(m.groups()) # () regex.sub \u4f1a\u8fd4\u56de\u4e00\u4e2a\u65b0\u7684\u5b57\u7b26\u4e32\uff0c\u539f\u5b57\u7b26\u4e32\u4e2d\u7684\u6a21\u5f0f\u4f1a\u88ab\u4e00\u4e2a\u65b0\u7684\u5b57\u7b26\u4e32\u66ff\u4ee3\u3002 m = regex.sub('REDACTED', text) print(m) # Dave REDACTED # Steve REDACTED # Rob REDACTED # Ryan REDACTED \u67e5\u627e\u7535\u5b50\u90ae\u4ef6\u5730\u5740\uff0c\u5e76\u5c06\u6bcf\u4e2a\u5730\u5740\u5206\u4e3a\u4e09\u4e2a\u90e8\u5206\uff1a\u7528\u6237\u540d\uff0c\u57df\u540d\u548c\u57df\u540d\u540e\u7f00\u3002\u8981\u5b9e\u73b0\u8fd9\u4e00\u70b9\uff0c\u53ef\u4ee5\u7528\u62ec\u53f7\u5c06 pattern \u5305\u8d77\u6765\u3002 \u4fee\u6539\u540e\u7684\u6b63\u5219\u8868\u8fbe\u5f0f\u4ea7\u751f\u7684\u5339\u914d\u5bf9\u8c61\u7684 groups \u65b9\u6cd5\uff0c\u8fd4\u56de\u7684\u662f\u6a21\u5f0f\u7ec4\u4ef6\u7684\u5143\u7ec4\u3002 text = \"\"\"Dave dave@google.com Steve steve@gmail.com Rob rob@gmail.com Ryan ryan@yahoo.com \"\"\" pattern = r'([A-Z0-9._%+-]+)@([A-Z0-9.-]+)\\.([A-Z]{2,4})' regex = re.compile(pattern, flags=re.IGNORECASE) m = regex.findall(text) # \u5f53pattern\u53ef\u4ee5\u5206\u7ec4\u65f6\uff0cfindall\u8fd4\u56de\u7684\u662f\u5305\u542b\u5143\u7ec4\u7684\u5217\u8868 print(m) # [('dave', 'google', 'com'), ('steve', 'gmail', 'com'), ('rob', 'gmail', 'com'), ('ryan', 'yahoo', 'com')] m = regex.search(text) print(m) # print(text[m.start():m.end()]) # dave@google.com m = regex.match('rob@gmail.com') print(m) # print(m.group()) # rob@gmail.com print(m.groups()) # ('rob', 'gmail', 'com') m = regex.sub('REDACTED', text) print(m) # Dave REDACTED # Steve REDACTED # Rob REDACTED # Ryan REDACTED m = regex.sub(r'Username: \\1, Domain: \\2, Suffix: \\3', text) print(m) # Dave Username: dave, Domain: google, Suffix: com # Steve Username: steve, Domain: gmail, Suffix: com # Rob Username: rob, Domain: gmail, Suffix: com # Ryan Username: ryan, Domain: yahoo, Suffix: com","title":"\u6b63\u5219\u8868\u8fbe\u5f0f"},{"location":"python/DataAnalysis/ch04/#pandas","text":"\u6e05\u7406\u6742\u4e71\u7684\u6570\u636e\u96c6\u7528\u4e8e\u5206\u6790\u901a\u5e38\u9700\u8981\u5927\u91cf\u7684\u5b57\u7b26\u4e32\u5904\u7406\u548c\u6b63\u5219\u5316\u3002 data = { 'Dave': 'dave@gmail.com', 'Steve': 'steve@gmail.com', 'Rob': 'rob@gmail.com', 'Wes': np.nan } data = pd.Series(data) print(data) # Dave dave@gmail.com # Steve steve@gmail.com # Rob rob@gmail.com # Wes NaN # dtype: object print(data.isnull()) # Dave False # Steve False # Rob False # Wes True # dtype: bool \u53ef\u4ee5\u4f7f\u7528 data.map \u5c06\u5b57\u7b26\u4e32\u548c\u6709\u6548\u7684\u6b63\u5219\u8868\u8fbe\u5f0f\u65b9\u6cd5\uff08\u4ee5 lambda \u6216\u5176\u4ed6\u51fd\u6570\u7684\u65b9\u5f0f\u4f20\u9012\uff09\u5e94\u7528\u5230\u6bcf\u4e2a\u503c\u4e0a\uff0c\u4f46\u662f\u5728 NA \uff08 null \uff09\u503c\u4e0a\u4f1a\u5931\u8d25\u3002 \u4e3a\u4e86\u89e3\u51b3\u8fd9\u4e2a\u95ee\u9898\uff0cSeries\u6709\u9762\u5411\u6570\u7ec4\u7684\u65b9\u6cd5\u7528\u4e8e\u8df3\u8fc7 NA \u503c\u7684\u5b57\u7b26\u4e32\u64cd\u4f5c\u3002\u8fd9\u4e9b\u65b9\u6cd5\u901a\u8fc7Series\u7684 str \u5c5e\u6027\u8fdb\u884c\u8c03\u7528\u3002 \u4f8b\u5982\uff0c\u53ef\u4ee5\u901a\u8fc7 str.contains \u6765\u68c0\u67e5\u6bcf\u4e2a\u7535\u5b50\u90ae\u4ef6\u5730\u5740\u662f\u5426\u542b\u6709 'gmail' \u3002 m = data.str.contains('gmail') print(m) # Dave True # Steve True # Rob True # Wes NaN # dtype: object \u6b63\u5219\u8868\u8fbe\u5f0f\u4e5f\u53ef\u4ee5\u7ed3\u5408\u4efb\u610f\u7684 re \u6a21\u5757\u9009\u9879\u4f7f\u7528\uff0c\u4f8b\u5982 IGNORECASE \u3002 print(pattern) # ([A-Z0-9._%+-]+)@([A-Z0-9.-]+)\\.([A-Z]{2,4}) m = data.str.findall(pattern, flags=re.IGNORECASE) print(m) # Dave [(dave, gmail, com)] # Steve [(steve, gmail, com)] # Rob [(rob, gmail, com)] # Wes NaN # dtype: object \u4f7f\u7528 str.get \u6216\u5728 str \u5c5e\u6027\u5185\u90e8\u7d22\u5f15\uff0c\u8fdb\u884c\u5411\u91cf\u5316\u7684\u5143\u7d20\u68c0\u7d22\u3002 m = data.str.match(pattern, flags=re.IGNORECASE) print(m) # Dave True # Steve True # Rob True # Wes NaN # dtype: object m = data.str.findall(pattern, flags=re.IGNORECASE) print(m.str.get(1)) # Dave NaN # Steve NaN # Rob NaN # Wes NaN # dtype: float64 print(m.str[0]) # Dave (dave, gmail, com) # Steve (steve, gmail, com) # Rob (rob, gmail, com) # Wes NaN # dtype: object \u4f7f\u7528\u5b57\u7b26\u4e32\u5207\u7247\u7684\u7c7b\u4f3c\u8bed\u6cd5\u8fdb\u884c\u5411\u91cf\u5316\u5207\u7247\u3002 print(data.str[:]) # Dave dave@gmail.com # Steve steve@gmail.com # Rob rob@gmail.com # Wes NaN # dtype: object print(data.str[:5]) # Dave dave@ # Steve steve # Rob rob@g # Wes NaN # dtype: object","title":"pandas\u4e2d\u7684\u5411\u91cf\u5316\u5b57\u7b26\u4e32\u51fd\u6570"},{"location":"python/DataAnalysis/ch05/","text":"\u6570\u636e\u89c4\u6574\uff1a\u8fde\u63a5\u3001\u8054\u5408\u4e0e\u91cd\u5851 \u00b6 \u5206\u5c42\u7d22\u5f15 \u00b6 import pandas as pd import numpy as np import re \u5206\u5c42\u7d22\u5f15\u662fpandas\u7684\u91cd\u8981\u7279\u6027\uff0c\u5141\u8bb8\u4f60\u5728\u4e00\u4e2a\u8f74\u5411\u4e0a\u62e5\u6709\u591a\u4e2a\uff08\u4e24\u4e2a\u6216\u4e24\u4e2a\u4ee5\u4e0a\uff09\u7d22\u5f15\u5c42\u7ea7\u3002 \u5206\u5c42\u7d22 import re \u5f15\u63d0\u4f9b\u4e86\u4e00\u79cd\u5728\u66f4\u4f4e\u7ef4\u5ea6\u7684\u5f62\u5f0f\u4e2d\u5904\u7406\u66f4\u9ad8\u7ef4\u5ea6\u6570\u636e\u7684\u65b9\u5f0f\u3002 Series\u7d22\u5f15\u5206\u5c42 \u00b6 data = pd.Series( np.random.randn(9), index=[['a', 'a', 'a', 'b', 'b', 'c', 'c', 'd', 'd'], [1, 2, 3, 1, 3, 1, 2, 2, 3]] ) \u8f93\u51fa\u662f\u4e00\u4e2a\u4ee5 MultiIndex \u4f5c\u4e3a\u7d22\u5f15\u7684Series\u7684\u7f8e\u5316\u89c6\u56fe\u3002 \u7d22\u5f15\u4e2d\u7684\"\u95f4\u9699\"\u8868\u793a\"\u76f4\u63a5\u4f7f\u7528\u4e0a\u9762\u7684\u6807\u7b7e\"\u3002 print(data) # a 1 0.163468 # 2 -1.525926 # 3 -0.210247 # b 1 -0.956063 # 3 -1.839111 # c 1 -0.398905 # 2 0.595279 # d 2 0.034305 # 3 -0.896078 # dtype: float64 print(data.index) # MultiIndex([('a', 1), # ('a', 2), # ('a', 3), # ('b', 1), # ('b', 3), # ('c', 1), # ('c', 2), # ('d', 2), # ('d', 3)], # ) \u901a\u8fc7\u5206\u5c42\u7d22\u5f15\u5bf9\u8c61\uff0c\u4e5f\u53ef\u4ee5\u79f0\u4e3a\u90e8\u5206\u7d22\u5f15\uff0c\u53ef\u4ee5\u7b80\u6d01\u5730\u9009\u62e9\u51fa\u6570\u636e\u7684\u5b50\u96c6\u3002 m = data['b'] print(m) # 1 -0.956063 # 3 -1.839111 # dtype: float64 m = data['b': 'c'] print(m) # b 1 -0.956063 # 3 -1.839111 # c 1 -0.398905 # 2 0.595279 # dtype: float64 m = data.loc[['b', 'c']] print(m) # b 1 -0.956063 # 3 -1.839111 # c 1 -0.398905 # 2 0.595279 # dtype: float64 m = data.loc[:, 2] print(m) # a -1.525926 # c 0.595279 # d 0.034305 # dtype: float64 \u5206\u5c42\u7d22\u5f15\u5728\u91cd\u5851\u6570\u636e\u548c\u6570\u7ec4\u900f\u89c6\u8868\u7b49\u5206\u7ec4\u64cd\u4f5c\u4e2d\u626e\u6f14\u4e86\u91cd\u8981\u89d2\u8272\u3002 \u4f8b\u5982\uff0c\u4f60\u53ef\u4ee5\u4f7f\u7528 unstack \u65b9\u6cd5\u5c06\u6570\u636e\u5728DataFrame\u4e2d\u91cd\u65b0\u6392\u5217\u3002 m = data.unstack() print(m) # 1 2 3 # a 0.163468 -1.525926 -0.210247 # b -0.956063 NaN -1.839111 # c -0.398905 0.595279 NaN # d NaN 0.034305 -0.896078 n = m.stack() print(n) # \u6216\u8005 print(data.unstack().stack()) # a 1 0.163468 # 2 -1.525926 # 3 -0.210247 # b 1 -0.956063 # 3 -1.839111 # c 1 -0.398905 # 2 0.595279 # d 2 0.034305 # 3 -0.896078 # dtype: float64 DataFrame\u7d22\u5f15\u5206\u5c42 \u00b6 \u5728DataFrame\u4e2d\uff0c\u6bcf\u4e2a\u8f74\u90fd\u53ef\u4ee5\u62e5\u6709\u5206\u5c42\u7d22\u5f15\u3002 \u53c2\u8003 \u65b9\u6cd51\uff1a\u76f4\u63a5\u521b\u5efa \u00b6 \u76f4\u63a5\u901a\u8fc7\u7ed9 index \uff08columns\uff09\u53c2\u6570\u4f20\u9012\u591a\u7ef4\u6570\u7ec4\uff0c\u8fdb\u800c\u6784\u5efa\u591a\u7ef4\u7d22\u5f15\u3002 \u6570\u7ec4\u4e2d\u6bcf\u4e2a\u7ef4\u5ea6\u5bf9\u5e94\u4f4d\u7f6e\u7684\u5143\u7d20\uff0c\u7ec4\u6210\u6bcf\u4e2a\u7d22\u5f15\u503c\u3002 frame = pd.DataFrame( np.arange(12).reshape((4, 3)), index=[['a', 'a', 'b', 'b'], [1, 2, 1, 2]], columns=[['Ohio', 'Ohio', 'Colorado'], ['Green', 'Red', 'Green']] ) print(frame) # Ohio Colorado # Green Red Green # a 1 0 1 2 # 2 3 4 5 # b 1 6 7 8 # 2 9 10 11 \u4e0a\u9762\u8f93\u51fa\u4e2d\u76842\u4e2a\u5c42\u7ea7\u662f\u6ca1\u6709\u540d\u5b57\u3002 \u5206\u5c42\u7684\u5c42\u7ea7\u53ef\u4ee5\u6709\u540d\u79f0\uff08\u53ef\u4ee5\u662f\u5b57\u7b26\u4e32\u6216Python\u5bf9\u8c61\uff09\u3002 \u5982\u679c\u5c42\u7ea7\u6709\u540d\u79f0\uff0c\u8fd9\u4e9b\u540d\u79f0\u4f1a\u5728\u63a7\u5236\u53f0\u8f93\u51fa\u4e2d\u663e\u793a\u3002 print(frame.index.names) # [None, None] print(frame.columns.names) # [None, None] \u7ed9\u5c42\u7ea7\u8d4b\u4e88\u540d\u79f0\u3002\u6ce8\u610f\u533a\u5206\u884c\u6807\u7b7e\u4e2d\u7684\u7d22\u5f15\u540d\u79f0 state \u548c color \u3002 frame.index.names = ['key1', 'key2'] frame.columns.names = ['state', 'color'] print(frame) # state Ohio Colorado # color Green Red Green # key1 key2 # a 1 0 1 2 # 2 3 4 5 # b 1 6 7 8 # 2 9 10 11 print(frame['Ohio']) # color Green Red # key1 key2 # a 1 0 1 # 2 3 4 # b 1 6 7 # 2 9 10 print(frame.index) # MultiIndex([('a', 1), # ('a', 2), # ('b', 1), # ('b', 2)], # names=['key1', 'key2']) \u901a\u8fc7 MultiIndex \u7c7b\u7684\u76f8\u5173\u65b9\u6cd5\uff0c\u9884\u5148\u521b\u5efa\u4e00\u4e2a MultiIndex \u5bf9\u8c61\uff0c\u7136\u540e\u4f5c\u4e3aSeries\u4e0eDataFrame\u4e2d\u7684 index \uff08\u6216columns\uff09\u53c2\u6570\u503c\u3002\u540c\u65f6\uff0c\u53ef\u4ee5\u901a\u8fc7 names \u53c2\u6570\u6307\u5b9a\u591a\u5c42\u7d22\u5f15\u7684\u540d\u79f0\u3002 \u65b9\u6cd52\uff1afrom_arrays \u00b6 from_arrays \uff1a\u63a5\u6536\u4e00\u4e2a\u591a\u7ef4\u6570\u7ec4\u53c2\u6570\uff0c\u9ad8\u7ef4\u6307\u5b9a\u9ad8\u5c42\u7d22\u5f15\uff0c\u4f4e\u7ef4\u6307\u5b9a\u5e95\u5c42\u7d22\u5f15\u3002 mindex = pd.MultiIndex.from_arrays( [['a', 'a', 'b', 'b'], [1, 2, 1, 2]], names=['key1', 'key2'] ) frame = pd.DataFrame( np.arange(12).reshape((4, 3)), index=mindex, columns=[['Ohio', 'Ohio', 'Colorado'], ['Green', 'Red', 'Green']] ) frame.columns.names = ['state', 'color'] print(frame) # state Ohio Colorado # color Green Red Green # key1 key2 # a 1 0 1 2 # 2 3 4 5 # b 1 6 7 8 # 2 9 10 11 \u65b9\u6cd53\uff1afrom_tuples \u00b6 from_tuples \uff1a\u63a5\u6536\u4e00\u4e2a\u5143\u7ec4\u7684\u5217\u8868\uff0c\u6bcf\u4e2a\u5143\u7ec4\u6307\u5b9a\u6bcf\u4e2a\u7d22\u5f15\uff08\u9ad8\u7ef4\u7d22\u5f15\uff0c\u4f4e\u7ef4\u7d22\u5f15\uff09\u3002 mindex = pd.MultiIndex.from_tuples( [('a', 1), ('a', 2), ('b', 1), ('b', 2)] ) frame = pd.DataFrame( np.arange(12).reshape((4, 3)), index=mindex, columns=[['Ohio', 'Ohio', 'Colorado'], ['Green', 'Red', 'Green']] ) frame.index.names = ['key1', 'key2'] frame.columns.names = ['state', 'color'] print(frame) # state Ohio Colorado # color Green Red Green # key1 key2 # a 1 0 1 2 # 2 3 4 5 # b 1 6 7 8 # 2 9 10 11 \u65b9\u6cd54\uff1afrom_product \u00b6 from_product \uff1a\u63a5\u6536\u4e00\u4e2a\u53ef\u8fed\u4ee3\u5bf9\u8c61\u7684\u5217\u8868\uff0c\u6839\u636e\u591a\u4e2a\u53ef\u8fed\u4ee3\u5bf9\u8c61\u5143\u7d20\u7684\u7b1b\u5361\u5c14\u79ef\u8fdb\u884c\u521b\u5efa\u7d22\u5f15\u3002 \u4f7f\u7528\u7b1b\u5361\u5c14\u79ef\u7684\u65b9\u5f0f\u6765\u521b\u5efa\u591a\u5c42\u7d22\u5f15\u3002\u53c2\u6570\u4e3a\u5d4c\u5957\u7684\u53ef\u8fed\u4ee3\u5bf9\u8c61\u3002\u7ed3\u679c\u4e3a\u4f7f\u7528\u6bcf\u4e2a\u4e00\u7ef4\u6570\u7ec4\u4e2d\u7684\u5143\u7d20\u4e0e\u5176\u4ed6\u4e00\u7ef4\u6570\u7ec4\u4e2d\u7684\u5143\u7d20\u6765\u751f\u6210\u3002 \u7b1b\u5361\u5c14\u79ef\u7684\u65b9\u5f0f\u7684\u5c40\u9650\uff1a\u4e24\u4e24\u7ec4\u5408\u5fc5\u987b\u90fd\u5b58\u5728\uff0c\u5426\u5219\uff0c\u5c31\u4e0d\u80fd\u4f7f\u7528\u8fd9\u79cd\u65b9\u5f0f\u3002 mindex = pd.MultiIndex.from_product( [['a', 'b'], ['1', '2']], names=['key1', 'key2'] ) frame = pd.DataFrame( np.arange(12).reshape((4, 3)), index=mindex, columns=[['Ohio', 'Ohio', 'Colorado'], ['Green', 'Red', 'Green']] ) frame.columns.names = ['state', 'color'] print(frame) # state Ohio Colorado # color Green Red Green # key1 key2 # a 1 0 1 2 # 2 3 4 5 # b 1 6 7 8 # 2 9 10 11 \u91cd\u6392\u5e8f\u548c\u5c42\u7ea7\u6392\u5e8f \u00b6 \u5982\u679c\u9700\u8981\u91cd\u65b0\u6392\u5217\u8f74\u4e0a\u7684\u5c42\u7ea7\u987a\u5e8f\uff0c\u6216\u8005\u6309\u7167\u7279\u5b9a\u5c42\u7ea7\u7684\u503c\u5bf9\u6570\u636e\u8fdb\u884c\u6392\u5e8f\uff0c \u53ef\u4ee5\u901a\u8fc7swaplevel\u63a5\u6536\u4e24\u4e2a\u5c42\u7ea7\u5e8f\u53f7\u6216\u5c42\u7ea7\u540d\u79f0\uff0c\u8fd4\u56de\u4e00\u4e2a\u8fdb\u884c\u4e86\u5c42\u7ea7\u53d8\u66f4\u7684\u65b0\u5bf9\u8c61\uff08\u4f46\u662f\u6570\u636e\u662f\u4e0d\u53d8\u7684\uff09\u3002 print(frame) # state Ohio Colorado # color Green Red Green # key1 key2 # a 1 0 1 2 # 2 3 4 5 # b 1 6 7 8 # 2 9 10 11 m = frame.swaplevel('key1', 'key2') print(m) # state Ohio Colorado # color Green Red Green # key2 key1 # 1 a 0 1 2 # 2 a 3 4 5 # 1 b 6 7 8 # 2 b 9 10 11 sort_index \u53ea\u80fd\u5728\u5355\u4e00\u5c42\u7ea7\u4e0a\u5bf9\u6570\u636e\u8fdb\u884c\u6392\u5e8f\u3002 \u5728\u8fdb\u884c\u5c42\u7ea7\u53d8\u6362\u65f6\uff0c\u4f7f\u7528 sort_index \u4ee5\u4f7f\u5f97\u7ed3\u679c\u6309\u7167\u5c42\u7ea7\u8fdb\u884c\u5b57\u5178\u6392\u5e8f\u3002 m = frame.sort_index(level=1) # \u5bf9key2\u6392\u5e8f\uff0c\u5e95\u5c42\u7d22\u5f15 print(m) # state Ohio Colorado # color Green Red Green # key1 key2 # a 1 0 1 2 # b 1 6 7 8 # a 2 3 4 5 # b 2 9 10 11 m = frame.sort_index(level=0) # \u5bf9key1\u6392\u5e8f\uff0c\u9ad8\u5c42\u7d22\u5f15 print(m) # state Ohio Colorado # color Green Red Green # key1 key2 # a 1 0 1 2 # 2 3 4 5 # b 1 6 7 8 # 2 9 10 11 m = frame.swaplevel(0, 1).sort_index(level=1) # swaplevel(0, 1)\u7b49\u540c\u4e8eswaplevel(key1, key2)\uff0c\u4ea4\u6362\u540ekey1\u53d8\u6210\u4e86\u5e95\u5c42\u7d22\u5f15 print(m) # state Ohio Colorado # color Green Red Green # key2 key1 # 1 a 0 1 2 # 2 a 3 4 5 # 1 b 6 7 8 # 2 b 9 10 11 \u6309\u5c42\u7ea7\u8fdb\u884c\u6c47\u603b\u7edf\u8ba1 \u00b6 DataFrame\u548cSeries\u4e2d\u5f88\u591a\u63cf\u8ff0\u6027\u548c\u6c47\u603b\u6027\u7edf\u8ba1\u6709\u4e00\u4e2a level \u9009\u9879\uff0c\u901a\u8fc7 level \u9009\u9879\u4f60\u53ef\u4ee5\u6307\u5b9a\u4f60\u60f3\u8981\u5728\u67d0\u4e2a\u7279\u5b9a\u7684\u8f74\u4e0a\u8fdb\u884c\u805a\u5408\u3002 print(frame) # state Ohio Colorado # color Green Red Green # key1 key2 # a 1 0 1 2 # 2 3 4 5 # b 1 6 7 8 # 2 9 10 11 m = frame.groupby(level='key2').sum() print(m) # state Ohio Colorado # color Green Red Green # key2 # 1 6 8 10 # 2 12 14 16 m = frame.groupby(level='color', axis=1).sum() print(m) # color Green Red # key1 key2 # a 1 2 1 # 2 8 4 # b 1 14 7 # 2 20 10 \u4f7f\u7528DataFrame\u7684\u5217\u8fdb\u884c\u7d22\u5f15 \u00b6 \u901a\u5e38\u6211\u4eec\u4e0d\u4f1a\u4f7f\u7528DataFrame\u4e2d\u4e00\u4e2a\u6216\u591a\u4e2a\u5217\u4f5c\u4e3a\u884c\u7d22\u5f15\uff1b\u53cd\u800c\u4f60\u53ef\u80fd\u60f3\u8981\u5c06\u884c\u7d22\u5f15\u79fb\u52a8\u5230DataFrame\u7684\u5217\u4e2d\u3002 frame = pd.DataFrame( {'a': range(7), 'b': range(7, 0, -1), 'c': ['one', 'one', 'one', 'two', 'two', 'two', 'two'], 'd': [0, 1, 2, 0, 1, 2, 3] } ) print(frame) # a b c d # 0 0 7 one 0 # 1 1 6 one 1 # 2 2 5 one 2 # 3 3 4 two 0 # 4 4 3 two 1 # 5 5 2 two 2 # 6 6 1 two 3 DataFrame\u7684 set_index \u51fd\u6570\u4f1a\u751f\u6210\u4e00\u4e2a\u65b0\u7684DataFrame\uff0c\u65b0\u7684DataFrame\u4f7f\u7528\u4e00\u4e2a\u6216\u591a\u4e2a\u5217\u4f5c\u4e3a\u7d22\u5f15\u3002 \u9ed8\u8ba4\u60c5\u51b5\u4e0b\u8fd9\u4e9b\u7d22\u5f15\u5217\u4f1a\u4eceDataFrame\u4e2d\u79fb\u9664\uff0c\u4e5f\u53ef\u4ee5\u5c06\u5b83\u4eec\u7559\u5728DataFrame\u4e2d\u3002 frame2 = frame.set_index(['c', 'd'], drop=False) print(frame2) # a b c d # c d # one 0 0 7 one 0 # 1 1 6 one 1 # 2 2 5 one 2 # two 0 3 4 two 0 # 1 4 3 two 1 # 2 5 2 two 2 # 3 6 1 two 3 frame2 = frame.set_index(['c', 'd']) print(frame2) # a b # c d # one 0 0 7 # 1 1 6 # 2 2 5 # two 0 3 4 # 1 4 3 # 2 5 2 # 3 6 1 reset_index \u662f set_index \u7684\u53cd\u64cd\u4f5c\uff0c\u5206\u5c42\u7d22\u5f15\u7684\u7d22\u5f15\u5c42\u7ea7\u4f1a\u88ab\u79fb\u52a8\u5230\u5217\u4e2d\u3002 \u6ce8\u610f\uff1a\u5982\u679c\u5728 set_index \u65f6\u4f7f\u7528\u4e86 drop=False \uff0c\u5728\u4f7f\u7528 reset_index \u4f1a\u62a5\u9519\u3002 m = frame2.reset_index() print(m) # c d a b # 0 one 0 0 7 # 1 one 1 1 6 # 2 one 2 2 5 # 3 two 0 3 4 # 4 two 1 4 3 # 5 two 2 5 2 # 6 two 3 6 1 \u8054\u5408\u4e0e\u5408\u5e76\u6570\u636e\u96c6 \u00b6 \u5305\u542b\u5728pandas\u5bf9\u8c61\u7684\u6570\u636e\u53ef\u4ee5\u901a\u8fc7\u591a\u79cd\u65b9\u5f0f\u8054\u5408\u5728\u4e00\u8d77\uff1a pandas.merge \u6839\u636e\u4e00\u4e2a\u6216\u591a\u4e2a\u952e\u5c06\u884c\u8fdb\u884c\u8fde\u63a5\u3002\u5bf9\u4e8eSQL\u6216\u5176\u4ed6\u5173\u7cfb\u578b\u6570\u636e\u5e93\u7684\u7528\u6237\u6765\u8bf4\uff0c\u8fd9\u79cd\u65b9\u5f0f\u6bd4\u8f83\u719f\u6089\uff0c\u5b83\u5b9e\u73b0\u7684\u662f\u6570\u636e\u5e93\u7684\u8fde\u63a5\u64cd\u4f5c\u3002 pandas.concat \u4f7f\u5bf9\u8c61\u5728\u8f74\u5411\u4e0a\u8fdb\u884c\u9ecf\u5408\u6216\u201c\u5806\u53e0\u201d\u3002 combine_first \u5b9e\u4f8b\u65b9\u6cd5\u5141\u8bb8\u5c06\u91cd\u53e0\u7684\u6570\u636e\u62fc\u63a5\u5728\u4e00\u8d77\uff0c\u4ee5\u4f7f\u7528\u4e00\u4e2a\u5bf9\u8c61\u4e2d\u7684\u503c\u586b\u5145\u53e6\u4e00\u4e2a\u5bf9\u8c61\u4e2d\u7684\u7f3a\u5931\u503c\u3002 \u6570\u636e\u5e93\u98ce\u683c\u7684DataFrame\u8fde\u63a5 \u00b6 \u5408\u5e76\u6216\u8fde\u63a5\u64cd\u4f5c\u901a\u8fc7\u4e00\u4e2a\u6216\u591a\u4e2a\u952e\u8fde\u63a5\u884c\u6765\u8054\u5408\u6570\u636e\u96c6\u3002 \u8fd9\u4e9b\u64cd\u4f5c\u662f\u5173\u7cfb\u578b\u6570\u636e\u5e93\u7684\u6838\u5fc3\u5185\u5bb9\uff08\u4f8b\u5982\u57fa\u4e8eSQL\u7684\u6570\u636e\u5e93\uff09\u3002 pandas\u4e2d\u7684 merge \u51fd\u6570\u4e3b\u8981\u7528\u4e8e\u5c06\u5404\u79cd join \u64cd\u4f5c\u7b97\u6cd5\u8fd0\u7528\u5728\u6570\u636e\u4e0a\u3002 \u5728\u8fdb\u884c\u5217-\u5217\u8fde\u63a5\u65f6\uff0c\u4f20\u9012\u7684DataFrame\u7d22\u5f15\u5bf9\u8c61\u4f1a\u88ab\u4e22\u5f03\u3002 \u5408\u5e76\u64cd\u4f5c\u4e5f\u8981\u8003\u8651\u5982\u4f55\u5904\u7406\u91cd\u53e0\u7684\u5217\u540d( suffixes \u540e\u7f00\u9009\u9879)\u3002 \u4e0b\u9762\u662f\u4e00\u4e2a\u591a\u5bf9\u4e00\u8fde\u63a5\u7684\u4f8b\u5b50\u3002 df1 \u7684\u6570\u636e\u6709\u591a\u4e2a\u884c\u7684\u6807\u7b7e\u4e3a a \u548c b \uff0c\u800c df2 \u5728 key \u5217\u4e2d\u6bcf\u4e2a\u503c\u4ec5\u6709\u4e00\u884c\u3002 df1 = pd.DataFrame( { 'key': ['b', 'b', 'a', 'c', 'a', 'a', 'b'], 'data1': range(7) } ) df2 = pd.DataFrame( { 'key': ['a', 'b', 'd'], 'data1': range(3) } ) print(df1) # key data1 # 0 b 0 # 1 b 1 # 2 a 2 # 3 c 3 # 4 a 4 # 5 a 5 # 6 b 6 print(df2) # key data1 # 0 a 0 # 1 b 1 # 2 d 2 \u8c03\u7528 merge \u5904\u7406\uff0c\u63a8\u8350\u663e\u5f0f\u5730\u6307\u5b9a\u8fde\u63a5\u952e\u3002 result = pd.merge(df1, df2) print(result) # key data1 # 0 b 1 result = pd.merge(df1, df2, on=['key', 'data1']) print(result) # key data1 # 0 b 1 result = pd.merge(df1, df2, on='key') print(result) # key data1_x data1_y # 0 b 0 1 # 1 b 1 1 # 2 b 6 1 # 3 a 2 0 # 4 a 4 0 # 5 a 5 0 \u5982\u679c\u6bcf\u4e2a\u5bf9\u8c61\u7684\u5217\u540d\u662f\u4e0d\u540c\u7684\uff0c\u53ef\u4ee5\u5206\u522b\u4e3a\u5b83\u4eec\u6307\u5b9a\u5217\u540d\u3002 df3 = pd.DataFrame( { 'lkey': ['b', 'b', 'a', 'c', 'a', 'a', 'b'], 'data1': range(7) } ) df4 = pd.DataFrame( { 'rkey': ['a', 'b', 'd'], 'data2': range(3) } ) print(df3) # lkey data1 # 0 b 0 # 1 b 1 # 2 a 2 # 3 c 3 # 4 a 4 # 5 a 5 # 6 b 6 print(df4) # rkey data2 # 0 a 0 # 1 b 1 # 2 d 2 \u9ed8\u8ba4\u60c5\u51b5\u4e0b\uff0c merge \u505a\u7684\u662f\u5185\u8fde\u63a5\uff08'inner' join\uff09\uff0c\u7ed3\u679c\u4e2d\u7684\u952e\u662f\u4e24\u5f20\u8868\u7684\u4ea4\u96c6\u3002 result = pd.merge(df3, df4, left_on='lkey', right_on='rkey') # df4\u7684[a,0]\u5bf9\u5e94df3\u7684\u6240\u6709[a,?]\u8bb0\u5f55\uff08\u901a\u8fc7\u91cd\u590d\u6765\u586b\u5145\u4e0d\u8db3\uff09 print(result) # lkey data1 rkey data2 # 0 b 0 b 1 # 1 b 1 b 1 # 2 b 6 b 1 # 3 a 2 a 0 # 4 a 4 a 0 # 5 a 5 a 0 \u5916\u8fde\u63a5\uff08outer join\uff09\u662f\u952e\u7684\u5e76\u96c6\uff0c\u8054\u5408\u4e86\u5de6\u8fde\u63a5\u548c\u53f3\u8fde\u63a5\u7684\u6548\u679c\u3002 \u591a\u5bf9\u591a\u8fde\u63a5\u662f\u884c\u7684\u7b1b\u5361\u5c14\u79ef\u3002 df1 = pd.DataFrame( { 'key': ['b', 'b', 'a', 'c', 'a', 'b'], 'data1': range(6) } ) df2 = pd.DataFrame( { 'key': ['a', 'b', 'a', 'b', 'd'], 'data2': range(5) } ) print(df1.sort_values(by='key')) # key data1 # 2 a 2 # 4 a 4 # 0 b 0 # 1 b 1 # 5 b 5 # 3 c 3 print(df2.sort_values(by='key')) # key data2 # 0 a 0 # 2 a 2 # 1 b 1 # 3 b 3 # 4 d 4 result = pd.merge(df1, df2, on='key', how='left') print(result.sort_values(by='key')) # key data1 data2 # 4 a 2 0.0 # 5 a 2 2.0 # 7 a 4 0.0 # 8 a 4 2.0 # 0 b 0 1.0 # 1 b 0 3.0 # 2 b 1 1.0 # 3 b 1 3.0 # 9 b 5 1.0 # 10 b 5 3.0 # 6 c 3 NaN result = pd.merge(df1, df2, on='key', how='outer') # \u591a\u5bf9\u591a\u8fde\u63a5 print(result.sort_values(by='key')) # key data1 data2 # 6 a 2.0 0.0 # 7 a 2.0 2.0 # 8 a 4.0 0.0 # 9 a 4.0 2.0 # 0 b 0.0 1.0 # 1 b 0.0 3.0 # 2 b 1.0 1.0 # 3 b 1.0 3.0 # 4 b 5.0 1.0 # 5 b 5.0 3.0 # 10 c 3.0 NaN # 11 d NaN 4.0 \u591a\u952e\u5408\u5e76\u3002 df1 = pd.DataFrame( { 'key1': ['foo', 'foo', 'bar'], 'key2': ['one', 'two', 'one'], 'lval': [1, 2, 3] } ) df2 = pd.DataFrame( { 'key1': ['foo', 'foo', 'bar', 'bar'], 'key2': ['one', 'one', 'one', 'two'], 'rval': [4, 5, 6, 7] } ) print(df1.sort_values(by=['key1', 'key2'])) # key1 key2 lval # 2 bar one 3 # 0 foo one 1 # 1 foo two 2 print(df2.sort_values(by=['key1', 'key2'])) # key1 key2 rval # 2 bar one 6 # 3 bar two 7 # 0 foo one 4 # 1 foo one 5 result = pd.merge(df1, df2, on=['key1', 'key2'], how='outer') print(result.sort_values(by=['key1', 'key2'])) # key1 key2 lval rval # 3 bar one 3.0 6.0 # 4 bar two NaN 7.0 # 0 foo one 1.0 4.0 # \u91cd\u590d\u586b\u5145 # 1 foo one 1.0 5.0 # \u91cd\u590d\u586b\u5145 # 2 foo two 2.0 NaN \u5904\u7406\u91cd\u53e0\u5217\u540d\u3002 result = pd.merge(df1, df2, on='key1') print(result.sort_values(by='key1')) # key1 key2_x lval key2_y rval # 4 bar one 3 one 6 # 5 bar one 3 two 7 # 0 foo one 1 one 4 # 1 foo one 1 one 5 # 2 foo two 2 one 4 # 3 foo two 2 one 5 result = pd.merge(df1, df2, on='key1', suffixes=('_left', '_right')) print(result.sort_values(by='key1')) # key1 key2_left lval key2_right rval # 4 bar one 3 one 6 # 5 bar one 3 two 7 # 0 foo one 1 one 4 # 1 foo one 1 one 5 # 2 foo two 2 one 4 # 3 foo two 2 one 5 \u6839\u636e\u7d22\u5f15\u5408\u5e76 \u00b6 \u5728\u67d0\u4e9b\u60c5\u51b5\u4e0b\uff0cDataFrame\u4e2d\u7528\u4e8e\u5408\u5e76\u7684\u952e\u662f\u5b83\u7684\u7d22\u5f15\u3002\u53ef\u4ee5\u4f20\u9012 left_index=True \u6216 right_index=True \uff08\u6216\u8005\u90fd\u4f20\uff09\u6765\u8868\u793a\u7d22\u5f15\u9700\u8981\u7528\u6765\u4f5c\u4e3a\u5408\u5e76\u7684\u952e\u3002 df1 = pd.DataFrame( { 'key1': ['foo', 'foo', 'bar'], 'key2': ['one', 'two', 'one'], 'lval': [1, 2, 3] } ) df2 = pd.DataFrame( { 'key1': ['foo', 'foo', 'bar', 'bar'], 'key2': ['one', 'one', 'one', 'two'], 'rval': [4, 5, 6, 7] }, index=['foo', 'foo', 'bar', 'bar'] ) print(df1) # key1 key2 lval # 0 foo one 1 # 1 foo two 2 # 2 bar one 3 print(df2) # key1 key2 rval # foo foo one 4 # foo foo one 5 # bar bar one 6 # bar bar two 7 result = pd.merge(df1, df2, left_on='key1', right_index=True, suffixes=('_left', '_right')) print(result.sort_index()) # key1 key1_left key2_left lval key1_right key2_right rval # 0 foo foo one 1 foo one 4 # 0 foo foo one 1 foo one 5 # 1 foo foo two 2 foo one 4 # 1 foo foo two 2 foo one 5 # 2 bar bar one 3 bar one 6 # 2 bar bar one 3 bar two 7 result = pd.merge(df1, df2, left_on='key1', right_index=True, how='outer', suffixes=('_left', '_right')) # \u548c\u4e0a\u8ff0\u7ed3\u679c\u4e00\u6837 print(result.sort_index()) # key1 key1_left key2_left lval key1_right key2_right rval # 0 foo foo one 1 foo one 4 # 0 foo foo one 1 foo one 5 # 1 foo foo two 2 foo one 4 # 1 foo foo two 2 foo one 5 # 2 bar bar one 3 bar one 6 # 2 bar bar one 3 bar two 7 \u5728\u66f4\u590d\u6742\u591a\u5c42\u7d22\u5f15\u6570\u636e\u7684\u591a\u952e\u5408\u5e76\uff0c\u5728\u7d22\u5f15\u4e0a\u8fde\u63a5\u662f\u4e00\u4e2a\u9690\u5f0f\u7684\u591a\u952e\u5408\u5e76\u3002 \u5fc5\u987b\u4ee5\u5217\u8868\u7684\u65b9\u5f0f\u6307\u660e\u5408\u5e76\u6240\u9700\u591a\u4e2a\u5217\uff08\u6ce8\u610f\u4f7f\u7528 how='outer' \u5904\u7406\u91cd\u590d\u7684\u7d22\u5f15\u503c\uff09\u3002 df1 = pd.DataFrame( { 'key1': ['Ohio', 'Ohio', 'Ohio', 'Nevada', 'Nevada'], 'key2': [2000, 2001, 2002, 2001, 2002], 'data': np.arange(5.) } ) df2 = pd.DataFrame( np.arange(12).reshape((6, 2)), index=[ ['Nevada', 'Nevada', 'Ohio', 'Ohio', 'Ohio', 'Ohio'], [2001, 2000, 2000, 2000, 2001, 2002] ], columns=['event1', 'event2'] ) print(df1) # key1 key2 data # 0 Ohio 2000 0.0 # 1 Ohio 2001 1.0 # 2 Ohio 2002 2.0 # 3 Nevada 2001 3.0 # 4 Nevada 2002 4.0 print(df2) # event1 event2 # Nevada 2001 0 1 # 2000 2 3 # Ohio 2000 4 5 # 2000 6 7 # 2001 8 9 # 2002 10 11 result = pd.merge(df1, df2, left_on=['key1', 'key2'], right_index=True) print(result) # key1 key2 data event1 event2 # 0 Ohio 2000 0.0 4 5 # 0 Ohio 2000 0.0 6 7 # 1 Ohio 2001 1.0 8 9 # 2 Ohio 2002 2.0 10 11 # 3 Nevada 2001 3.0 0 1 result = pd.merge(df1, df2, left_on=['key1', 'key2'], right_index=True, how='outer') print(result) # key1 key2 data event1 event2 # 0 Ohio 2000 0.0 4.0 5.0 # 0 Ohio 2000 0.0 6.0 7.0 # 1 Ohio 2001 1.0 8.0 9.0 # 2 Ohio 2002 2.0 10.0 11.0 # 3 Nevada 2001 3.0 0.0 1.0 # 4 Nevada 2002 4.0 NaN NaN # 4 Nevada 2000 NaN 2.0 3.0 \u4f7f\u7528\u4e24\u8fb9\u7684\u7d22\u5f15\u8fdb\u884c\u5408\u5e76\u4e5f\u662f\u53ef\u4ee5\u7684\uff0c\u524d\u63d0\u662f\u7528\u4e24\u8fb9\u7528\u6765\u5408\u5e76\u7684\u7d22\u5f15\u6709\u4ea4\u96c6\uff08\u516c\u5171\u90e8\u5206\uff09\u3002 \u5728\u4f7f\u7528 merge \u65f6\uff0c\u53c2\u6570 on=['key1', 'key2'] \u4e0d\u80fd\u548c left_index=True , right_index=True \u540c\u65f6\u5b58\u5728\u3002 \u5bf9\u4e8e\u91cd\u590d\u7d22\u5f15\uff0c\u5982\u679c\u503c\u4e0d\u540c\uff0c\u5219\u591a\u884c\u663e\u793a\uff0c\u548c\u6570\u636e\u5e93SQL\u7684 full join \u7c7b\u4f3c\u6982\u5ff5\u3002 \u5982\u679c\u51fa\u73b0\u76f8\u540c\u5217\u540d\uff0c\u5219\u4f1a\u81ea\u52a8\u6dfb\u52a0\u540e\u7f00\u5b57\u7b26\u4ee5\u793a\u533a\u522b\u3002 df1 = pd.DataFrame( [[1, 2], [3, 4], [5, 6]], index=['a', 'c', 'e'], columns=['Ohio', 'Nevada'] ) print(df1) # Ohio Nevada # a 1 2 # c 3 4 # e 5 6 df2 = pd.DataFrame( [[7, 8], [9, 10], [11, 12], [13, 14]], index=['b', 'c', 'c', 'e'], columns=['Missouri', 'Alabama'] ) print(df2) # Missouri Alabama # b 7 8 # c 9 10 # c 11 12 # e 13 14 df3 = pd.DataFrame( [[7, 8], [9, 10], [11, 12], [13, 14]], index=['a', 'c', 'e', 'f'], columns=['Nevada', 'Alabama'] ) print(df3) # Nevada Alabama # a 7 8 # c 9 10 # e 11 12 # f 13 14 result = pd.merge(df1, df2, left_index=True, right_index=True, how='outer') print(result) # Ohio Nevada Missouri Alabama # a 1.0 2.0 NaN NaN # b NaN NaN 7.0 8.0 # c 3.0 4.0 9.0 10.0 # c 3.0 4.0 11.0 12.0 # e 5.0 6.0 13.0 14.0 result = pd.merge(df1, df3, left_index=True, right_index=True, how='outer') print(result) # Ohio Nevada_x Nevada_y Alabama # a 1.0 2.0 7 8 # c 3.0 4.0 9 10 # e 5.0 6.0 11 12 # f NaN NaN 13 14 \u53e6\u4e00\u79cd\u5199\u6cd5\uff1a result = df1.join(df2, how='outer') print(result) # Ohio Nevada Missouri Alabama # a 1.0 2.0 NaN NaN # b NaN NaN 7.0 8.0 # c 3.0 4.0 9.0 10.0 # c 3.0 4.0 11.0 12.0 # e 5.0 6.0 13.0 14.0 \u4e5f\u53ef\u4ee5\u5411 join \u65b9\u6cd5\u4f20\u5165\u4e00\u4e2aDataFrame\u5217\u8868\uff0c\u7c7b\u4f3c\u4e8e\u5bf9\u4e09\u4e2a\u6570\u636e\u96c6\u8fdb\u884c join \u64cd\u4f5c\u3002 result = df1.join([df2, df3]) print(result) # Ohio Nevada_x Missouri Alabama_x Nevada_y Alabama_y # a 1 2 NaN NaN 7 8 # c 3 4 9.0 10.0 9 10 # c 3 4 11.0 12.0 9 10 # e 5 6 13.0 14.0 11 12 \u6cbf\u8f74\u5411\u8fde\u63a5 \u00b6 \u53e6\u4e00\u79cd\u6570\u636e\u7ec4\u5408\u64cd\u4f5c\u53ef\u79f0\u4e3a\u62fc\u63a5\u3001\u7ed1\u5b9a\u6216\u5806\u53e0\u3002NumPy\u7684 concatenate \u51fd\u6570\u53ef\u4ee5\u5728NumPy\u6570\u7ec4\u4e0a\u5b9e\u73b0\u8be5\u529f\u80fd\u3002 \u57fa\u4e8eSeries\u7684pandas\u7684 concat \u51fd\u6570\u7684\u5de5\u4f5c\u673a\u5236\u5206\u6790\u3002 \u4e0b\u9762\u4e09\u4e2a\u7d22\u5f15\u4e0d\u91cd\u53e0\u7684Series\u3002 s1 = pd.Series([0, 1], index=['a', 'b']) s2 = pd.Series([2, 3, 4], index=['c', 'd', 'e']) s3 = pd.Series([5, 6], index=['f', 'g']) \u7528\u5217\u8868\u4e2d\u7684\u8fd9\u4e9b\u5bf9\u8c61\u8c03\u7528 concat \u65b9\u6cd5\u4f1a\u5c06\u503c\u548c\u7d22\u5f15\u7c98\u5728\u4e00\u8d77\uff1a \u9ed8\u8ba4\u60c5\u51b5\u4e0b\uff0c concat \u65b9\u6cd5\u662f\u6cbf\u7740 axis=0 \u7684\u8f74\u5411\u751f\u6548\u7684\uff0c\u751f\u6210\u53e6\u4e00\u4e2aSeries\u3002 \u5982\u679c\u4f20\u9012 axis=1 \uff0c\u8fd4\u56de\u7684\u7ed3\u679c\u5219\u662f\u4e00\u4e2aDataFrame\uff08 axis=1 \u65f6\u662f\u5217\uff09\u3002 result = pd.concat([s1, s2, s3]) print(result) # a 0 # b 1 # c 2 # d 3 # e 4 # f 5 # g 6 # dtype: int64 result = pd.concat([s1, s2, s3], keys=['one', 'two', 'three']) # \u901a\u8fc7keys\u53c2\u6570\uff0c\u5728\u8fde\u63a5\u8f74\u5411\u4e0a\u521b\u5efa\u4e00\u4e2a\u591a\u5c42\u7d22\u5f15\uff0c\u4ee5\u4fbf\u5728\u7ed3\u679c\u4e2d\u533a\u5206\u5404\u90e8\u5206 print(result) # one a 0 # b 1 # two c 2 # d 3 # e 4 # three f 5 # g 6 # dtype: int64 print(result.unstack()) # \u628a\u539f\u7d22\u5f15\u4f5c\u4e3a\u5217\u6807\u7b7e\u5c55\u5f00 # a b c d e f g # one 0.0 1.0 NaN NaN NaN NaN NaN # two NaN NaN 2.0 3.0 4.0 NaN NaN # three NaN NaN NaN NaN NaN 5.0 6.0 result = pd.concat([s1, s2, s3], axis=1) # \u5728\u8fd9\u4e2a\u6848\u4f8b\u4e2daxis=1\u8f74\u5411\u4e0a\u5e76\u6ca1\u6709\u91cd\u53e0 print(result) # 0 1 2 # a 0.0 NaN NaN # b 1.0 NaN NaN # c NaN 2.0 NaN # d NaN 3.0 NaN # e NaN 4.0 NaN # f NaN NaN 5.0 # g NaN NaN 6.0 result = pd.concat([s1, s2, s3], axis=1, keys=['one', 'two', 'three']) # \u5728\u8fd9\u4e2a\u6848\u4f8b\u4e2daxis=1\u8f74\u5411\u4e0a\u5e76\u6ca1\u6709\u91cd\u53e0 print(result) # one two three # a 0.0 NaN NaN # b 1.0 NaN NaN # c NaN 2.0 NaN # d NaN 3.0 NaN # e NaN 4.0 NaN # f NaN NaN 5.0 # g NaN NaN 6.0 print(result.unstack()) # \u5bf9\u6bd4axis=0\u7684\u591a\u5c42\u7d22\u5f15\uff0c\u5f53axis=1\u65f6\u5bf9\u8f93\u51fa\u5404index\u7684\u5e76\u96c6\u505a\u4e86\u5206\u7ec4\u3002 # one a 0.0 # b 1.0 # c NaN # d NaN # e NaN # f NaN # g NaN # two a NaN # b NaN # c 2.0 # d 3.0 # e 4.0 # f NaN # g NaN # three a NaN # b NaN # c NaN # d NaN # e NaN # f 5.0 # g 6.0 # dtype: float64 s4 = pd.concat([s1, s3]) print(s4) # a 0 # b 1 # f 5 # g 6 # dtype: int64 result = pd.concat([s1, s4]) print(result) # a 0 # b 1 # a 0 # b 1 # f 5 # g 6 # dtype: int64 result = pd.concat([s1, s4], axis=1) # \u73b0\u5728\u5728\u4e2daxis=1\u8f74\u5411\u4e0a\u6709\u91cd\u53e0 print(result) # 0 1 # a 0.0 0 # b 1.0 1 # f NaN 5 # g NaN 6 result = pd.concat([s1, s4], axis=1, keys=['one', 'two', 'three']) print(result) # one two # a 0.0 0 # b 1.0 1 # f NaN 5 # g NaN 6 result = pd.concat([s1, s4], axis=0, keys=['one', 'two', 'three']) # \u901a\u8fc7keys\u53c2\u6570\uff0c\u5728\u8fde\u63a5\u8f74\u5411\u4e0a\u521b\u5efa\u4e00\u4e2a\u591a\u5c42\u7d22\u5f15 print(result) # one a 0 # b 1 # two a 0 # b 1 # f 5 # g 6 # dtype: int64 result = pd.concat([s1, s4], axis=1, join='inner') # \u5185\u8fde\u63a5\u65b9\u5f0f\u5408\u5e76\u7d22\u5f15\uff08\u7d22\u5f15\u4ea4\u96c6\uff09 print(result) # 0 1 # a 0 0 # b 1 1 result = pd.concat([s1, s4], axis=1).reindex(['a', 'c', 'b', 'e']) # \u4f7f\u7528join_axes(\u5df2\u88ab\u66ff\u6362\u6210reindex)\u6765\u6307\u5b9a\u7528\u4e8e\u8fde\u63a5\u5176\u4ed6\u8f74\u5411\u7684\u8f74 print(result) # 0 1 # a 0.0 0.0 # c NaN NaN # b 1.0 1.0 # e NaN NaN \u57fa\u4e8eDataFrame\u7684pandas\u7684 concat \u51fd\u6570\u7684\u5de5\u4f5c\u673a\u5236\u5206\u6790\u3002 df1 = pd.DataFrame( np.arange(12).reshape((6, 2)), index=[ ['Ohio', 'Ohio', 'Ohio', 'Nevada', 'Nevada', 'Nevada'], [2000, 2001, 2002, 2000, 2001, 2002] ], columns=['event1', 'event2'] ) df2 = pd.DataFrame( np.arange(12).reshape((6, 2)), index=[ ['Ohio', 'Ohio', 'Ohio', 'Nevada', 'Nevada', 'Nevada'], [2000, 2001, 2002, 2000, 2001, 2002] ], columns=['event3', 'event4'] ) print(df1) # event1 event2 # Ohio 2000 0 1 # 2001 2 3 # 2002 4 5 # Nevada 2000 6 7 # 2001 8 9 # 2002 10 11 print(df2) # event3 event4 # Ohio 2000 0 1 # 2001 2 3 # 2002 4 5 # Nevada 2000 6 7 # 2001 8 9 # 2002 10 11 result = np.concatenate([df1, df2], axis=0) # \u6cbf0\u8f74\u62fc\u63a5 print(result) # [[ 0 1] # [ 2 3] # [ 4 5] # [ 6 7] # [ 8 9] # [10 11] # [ 0 1] # [ 2 3] # [ 4 5] # [ 6 7] # [ 8 9] # [10 11]] result = np.concatenate([df1, df2], axis=1) # \u6cbf1\u8f74\u62fc\u63a5 print(result) # [[ 0 1 0 1] # [ 2 3 2 3] # [ 4 5 4 5] # [ 6 7 6 7] # [ 8 9 8 9] # [10 11 10 11]] result = np.concatenate([df1, df2], axis=None) # \u5c06\u6570\u7ec4\u5c55\u5e73 print(result) # [ 0 1 2 3 4 5 6 7 8 9 10 11 0 1 2 3 4 5 6 7 8 9 10 11] \u8054\u5408\u91cd\u53e0\u6570\u636e \u00b6 \u53e6\u4e00\u4e2a\u6570\u636e\u8054\u5408\u573a\u666f\uff0c\u65e2\u4e0d\u662f\u5408\u5e76\u64cd\u4f5c\uff0c\u4e5f\u4e0d\u662f\u8fde\u63a5\u64cd\u4f5c\u3002 \u5047\u5982\u6709\u4e24\u4e2a\u6570\u636e\u96c6\uff0c\u8fd9\u4e24\u4e2a\u6570\u636e\u96c6\u7684\u7d22\u5f15\u5168\u90e8\u6216\u90e8\u5206\u91cd\u53e0\uff0c\u901a\u8fc7NumPy\u7684 where \u51fd\u6570\u53ef\u4ee5\u8fdb\u884c\u9762\u5411\u6570\u7ec4\u7684if-else\u7b49\u4ef7\u64cd\u4f5c\u3002 s1 = pd.Series( [np.nan, 2.5, 0.0, 3.5, 4.5, np.nan], index=['f', 'e', 'd', 'c', 'b', 'a'] ) s2 = pd.Series( [0.0, np.nan, 2.0, np.nan, np.nan, 5.0], index=['a', 'b', 'c', 'd', 'e', 'f'] ) print(s1) # f NaN # e 2.5 # d 0.0 # c 3.5 # b 4.5 # a NaN # dtype: float64 print(s2) # a 0.0 # b NaN # c 2.0 # d NaN # e NaN # f 5.0 # dtype: float64 \u65b9\u6cd51\uff0c\u901a\u8fc7Numpy\u7684 where \u51fd\u6570\u3002 result = np.where(pd.isnull(s1), s2, s1) # An array with elements from 'x'(s2) where 'condition'(isnull(s1)) is True, and elements from 'y'(s1) elsewhere. print(result) # [0. 2.5 0. 3.5 4.5 5. ] # s1 # s2 # result # f NaN # a 0.0 0. \u6761\u4ef6\u4e2ds1\u8be5\u5143\u7d20\u4e3anull\uff0c\u6240\u4ee5where\u51fd\u6570\u53d6\u5bf9\u5e94x(s2)\u7684\u5143\u7d20\uff08\u6ce8\u610f\uff0c\u4e0e\u7d22\u5f15\u987a\u5e8f\u65e0\u5173\uff09 # e 2.5 # b NaN 2.5 \u6761\u4ef6\u4e2ds1\u8be5\u5143\u7d20\u4e0d\u4e3anull\uff0c\u6240\u4ee5where\u51fd\u6570\u53d6\u5bf9\u5e94y(s1)\u7684\u5143\u7d20 # d 0.0 # c 2.0 0. # c 3.5 # d NaN 3.5 # b 4.5 # e NaN 4.5 # a NaN # f 5.0 5.0 \u6761\u4ef6\u4e2ds1\u8be5\u5143\u7d20\u4e3anull\uff0c\u6240\u4ee5where\u51fd\u6570\u53d6\u5bf9\u5e94x(s2)\u7684\u5143\u7d20 result = np.where(pd.isnull(s2), s1, s2) print(result) # [0. 2.5 2. 3.5 4.5 5. ] \u65b9\u6cd52\uff0c\u901a\u8fc7Series\u7684 combine_first \u65b9\u6cd5\u3002 result = s2.combine_first(s1) # \u6ce8\u610f\uff0ccombine_first\u662f\u6309\u7167s2\u7684\u7d22\u5f15\u987a\u5e8f\u68c0\u7d22\u7684\uff0c\u76f8\u540c\u7d22\u5f15\u7684s1\u7684\u503c\u4f1a\u586b\u5145\u5bf9\u5e94s2\u7684null print(result) # a 0.0 # b 4.5 # c 2.0 # d 0.0 # e 2.5 # f 5.0 # dtype: float64 \u65b9\u6cd53\uff1aPandas\u7684 combine_first \u65b9\u6cd5\u3002 df1 = pd.DataFrame( { 'a': [1.0, np.nan, 5.0, np.nan], 'b': [np.nan, 2.0, np.nan, 6.0], 'c': [2.0, 6.0, 10.0, 15.0] } ) df2 = pd.DataFrame( { 'a': [5.0, 4.0, np.nan, 3.0, 7.0], 'b': [np.nan, 3.0, 4.0, 6.0, 8.0] } ) print(df1) # a b c # 0 1.0 NaN 2.0 # 1 NaN 2.0 6.0 # 2 5.0 NaN 10.0 # 3 NaN 6.0 15.0 print(df2) # a b # 0 5.0 NaN # 1 4.0 3.0 # 2 NaN 4.0 # 3 3.0 6.0 # 4 7.0 8.0 result = df2.combine_first(df1) # \u7528df1\u7684\u503c\u53bb\u586b\u5145df2\u5bf9\u5e94\u7d22\u5f15\u4f4d\u7f6e\u7684null\u503c print(result) # a b c # 0 5.0 NaN 2.0 # 1 4.0 3.0 6.0 # 2 5.0 4.0 10.0 # 3 3.0 6.0 15.0 # 4 7.0 8.0 NaN \u91cd\u5851\u548c\u900f\u89c6 \u00b6 \u91cd\u65b0\u6392\u5217\u8868\u683c\u578b\u6570\u636e\u6709\u591a\u79cd\u57fa\u7840\u64cd\u4f5c\u3002\u8fd9\u4e9b\u64cd\u4f5c\u88ab\u79f0\u4e3a\u91cd\u5851\u6216\u900f\u89c6\u3002 import numpy as np import pandas as pd \u4f7f\u7528\u591a\u5c42\u7d22\u5f15\u8fdb\u884c\u91cd\u5851 \u00b6 \u591a\u5c42\u7d22\u5f15\u5728DataFrame\u4e2d\u63d0\u4f9b\u4e86\u4e00\u79cd\u4e00\u81f4\u6027\u65b9\u5f0f\u7528\u4e8e\u91cd\u6392\u5217\u6570\u636e\u3002\u4ee5\u4e0b\u662f\u4e24\u4e2a\u57fa\u7840\u64cd\u4f5c\uff1a statck\uff08\u5806\u53e0\uff09\u8be5\u64cd\u4f5c\u4f1a\u201c\u65cb\u8f6c\u201d\u6216\u5c06\u5217\u4e2d\u7684\u6570\u636e\u900f\u89c6\u5230\u884c\u3002 unstack\uff08\u62c6\u5806\uff09\u8be5\u64cd\u4f5c\u4f1a\u5c06\u884c\u4e2d\u7684\u6570\u636e\u900f\u89c6\u5230\u5217\u3002 df = pd.DataFrame( np.arange(6).reshape((2, 3)), index=pd.Index(['Ohio', 'Colorado'], name='state'), columns=pd.Index(['one', 'two', 'three'], name='number') ) print(df) # number one two three # state # Ohio 0 1 2 # Colorado 3 4 5 \u5728\u8fd9\u4efd\u6570\u636e\u4e0a\u4f7f\u7528stack\u65b9\u6cd5\u4f1a\u5c06\u5217\u900f\u89c6\u5230\u884c\uff0c\u4ea7\u751f\u4e00\u4e2a\u65b0\u7684Series\uff1a result = df.stack() print(result) # state number # Ohio one 0 # two 1 # three 2 # Colorado one 3 # two 4 # three 5 # dtype: int64 \u4ece\u4e00\u4e2a\u591a\u5c42\u7d22\u5f15\u5e8f\u5217\u4e2d\uff0c\u4f60\u53ef\u4ee5\u4f7f\u7528 unstack \u65b9\u6cd5\u5c06\u6570\u636e\u91cd\u6392\u5217\u540e\u653e\u5165\u4e00\u4e2aDataFrame\u4e2d\uff1a print(result.unstack()) # number one two three # state # Ohio 0 1 2 # Colorado 3 4 5 print(result.unstack(0)) # \u53ef\u4ee5\u4f20\u5165\u4e00\u4e2a\u5c42\u7ea7\u5e8f\u53f7\u6216\u540d\u79f0\u6765\u62c6\u5206\u4e00\u4e2a\u4e0d\u540c\u7684\u5c42\u7ea7 # state Ohio Colorado # number # one 0 3 # two 1 4 # three 2 5 print(result.unstack(1)) # number one two three # state # Ohio 0 1 2 # Colorado 3 4 5 print(result.unstack('state')) # \u8f93\u51fa\u7ed3\u679c\u548c\u4f20\u5165\u5c42\u7ea70\u4e00\u6837 # state Ohio Colorado # number # one 0 3 # two 1 4 # three 2 5 print(result.unstack('number')) # \u8f93\u51fa\u7ed3\u679c\u548c\u4f20\u5165\u5c42\u7ea71\u4e00\u6837 # number one two three # state # Ohio 0 1 2 # Colorado 3 4 5 \u5982\u679c\u5c42\u7ea7\u4e2d\u7684\u6240\u6709\u503c\u5e76\u672a\u5305\u542b\u4e8e\u6bcf\u4e2a\u5b50\u5206\u7ec4\u4e2d\u65f6\uff0c\u62c6\u5206\u53ef\u80fd\u4f1a\u5f15\u5165\u7f3a\u5931\u503c\uff1a s1 = pd.Series([0, 1, 2, 3], index=['a', 'b', 'c', 'd']) s2 = pd.Series([4, 5, 6], index=['c', 'd', 'e']) s3 = pd.concat([s1, s2], keys=['one', 'two']) print(s3) # one a 0 # b 1 # c 2 # d 3 # two c 4 # d 5 # e 6 # dtype: int64 print(s3.unstack(0)) # one two # a 0.0 NaN # b 1.0 NaN # c 2.0 4.0 # d 3.0 5.0 # e NaN 6.0 print(s3.unstack(1)) print(s3.unstack()) # a b c d e # one 0.0 1.0 2.0 3.0 NaN # two NaN NaN 4.0 5.0 6.0 \u9ed8\u8ba4\u60c5\u51b5\u4e0b\uff0c\u5806\u53e0\u4f1a\u8fc7\u6ee4\u51fa\u7f3a\u5931\u503c\uff0c\u56e0\u6b64\u5806\u53e0\u62c6\u5806\u7684\u64cd\u4f5c\u662f\u53ef\u9006\u7684\u3002 print(s3.unstack().stack()) # one a 0.0 # b 1.0 # c 2.0 # d 3.0 # two c 4.0 # d 5.0 # e 6.0 # dtype: float64 print(s3.unstack().stack(dropna=False)) # one a 0.0 # b 1.0 # c 2.0 # d 3.0 # e NaN # two a NaN # b NaN # c 4.0 # d 5.0 # e 6.0 # dtype: float64 \u5728DataFrame\u4e2d\u62c6\u5806\u65f6\uff0c\u88ab\u62c6\u5806\u7684\u5c42\u7ea7\u4f1a\u53d8\u4e3a\u7ed3\u679c\u4e2d\u6700\u4f4e\u7684\u5c42\u7ea7\u3002 \u5728\u8c03\u7528 stack \u65b9\u6cd5\u65f6\uff0c\u6211\u4eec\u53ef\u4ee5\u6307\u660e\u9700\u8981\u5806\u53e0\u7684\u8f74\u5411\u540d\u79f0\u3002 df = pd.DataFrame( {'left': result, 'right': result + 5}, columns=pd.Index(['left', 'right'], name='side') ) print(df) # side left right # state number # Ohio one 0 5 # two 1 6 # three 2 7 # Colorado one 3 8 # two 4 9 # three 5 10 print(df.unstack()) # side left right # number one two three one two three # state # Ohio 0 1 2 5 6 7 # Colorado 3 4 5 8 9 10 print(df.unstack('state')) # \u88ab\u62c6\u5806\u7684\u5c42\u7ea7(state)\u4f1a\u53d8\u4e3a\u7ed3\u679c\u4e2d\u6700\u4f4e\u7684\u5c42\u7ea7 # side left right # state Ohio Colorado Ohio Colorado # number # one 0 3 5 8 # two 1 4 6 9 # three 2 5 7 10 \u5728\u8c03\u7528 stack \u65b9\u6cd5\u65f6\uff0c\u53ef\u4ee5\u6307\u660e\u9700\u8981\u5806\u53e0\u7684\u8f74\u5411\u540d\u79f0\uff1a print(df.unstack('state').stack('side')) # state Colorado Ohio # number side # one left 3 0 # right 8 5 # two left 4 1 # right 9 6 # three left 5 2 # right 10 7 \u5c06\u201c\u957f\u201d\u900f\u89c6\u4e3a\u201c\u5bbd\u201d \u00b6 \u5728\u6570\u636e\u5e93\u548cCSV\u4e2d\u5b58\u50a8\u591a\u65f6\u95f4\u5e8f\u5217\u7684\u65b9\u5f0f\u5c31\u662f\u6240\u8c13\u7684\u957f\u683c\u5f0f\u6216\u5806\u53e0\u683c\u5f0f\u3002 data = pd.read_csv('../examples/macrodata.csv') print(data.head(3)) # year quarter realgdp realcons ... unemp pop infl realint # 0 1959.0 1.0 2710.349 1707.4 ... 5.8 177.146 0.00 0.00 # 1 1959.0 2.0 2778.801 1733.7 ... 5.1 177.830 2.34 0.74 # 2 1959.0 3.0 2775.488 1751.8 ... 5.3 178.657 2.74 1.09 # ...... # [3 rows x 14 columns] # PeriodIndex\u5c06year\u548cquarter\u7b49\u5217\u8fdb\u884c\u8054\u5408\u5e76\u751f\u6210\u4e86\u4e00\u79cd\u65f6\u95f4\u95f4\u9694\u7c7b\u578b periods = pd.PeriodIndex( year=data.year, quarter=data.quarter, name='date' ) columns = pd.Index( ['realgdp', 'infl', 'unemp'], name='item' ) data = data.reindex(columns=columns) print(data) # item realgdp infl unemp # 0 2710.349 0.00 5.8 # 1 2778.801 2.34 5.1 # 2 2775.488 2.74 5.3 # ...... # [203 rows x 3 columns] data.index = periods.to_timestamp('D', 'end') print(data.index) # DatetimeIndex(['1959-03-31 23:59:59.999999999', # '1959-06-30 23:59:59.999999999', # ... # '2009-06-30 23:59:59.999999999', # '2009-09-30 23:59:59.999999999'], # dtype='datetime64[ns]', name='date', length=203, freq=None) \u4e0b\u9762\u662fldata\u7684\u6570\u636e\u6837\u672c\u3002 \u8fd9\u79cd\u6570\u636e\u5373\u6240\u8c13\u7684\u591a\u65f6\u95f4\u5e8f\u5217\u7684\u957f\u683c\u5f0f\uff0c\u6216\u79f0\u4e3a\u5177\u6709\u4e24\u4e2a\u6216\u66f4\u591a\u4e2a\u952e\u7684\u5176\u4ed6\u89c2\u6d4b\u6570\u636e\uff08\u8fd9\u91cc\uff0c\u6211\u4eec\u7684\u952e\u662fdate\u548citem\uff09\u3002 \u8868\u4e2d\u7684\u6bcf\u4e00\u884c\u8868\u793a\u4e00\u4e2a\u65f6\u95f4\u70b9\u4e0a\u7684\u5355\u4e2a\u89c2\u6d4b\u503c\u3002 ldata = data.stack().reset_index().rename(columns={0: 'value'}) print(ldata) # date item value # 0 1959-03-31 23:59:59.999999999 realgdp 2710.349 # 1 1959-03-31 23:59:59.999999999 infl 0.000 # 2 1959-03-31 23:59:59.999999999 unemp 5.800 # 3 1959-06-30 23:59:59.999999999 realgdp 2778.801 # 4 1959-06-30 23:59:59.999999999 infl 2.340 # .. ... ... ... # 604 2009-06-30 23:59:59.999999999 infl 3.370 # 605 2009-06-30 23:59:59.999999999 unemp 9.200 # 606 2009-09-30 23:59:59.999999999 realgdp 12990.341 # 607 2009-09-30 23:59:59.999999999 infl 3.560 # 608 2009-09-30 23:59:59.999999999 unemp 9.600 # [609 rows x 3 columns] \u5728\u4e0a\u9762\u7684\u4f8b\u5b50\u4e2d\uff1a \u6570\u636e\u901a\u5e38\u4ee5\u8fd9\u79cd\u65b9\u5f0f\u5b58\u50a8\u5728\u5173\u7cfb\u578b\u6570\u636e\u5e93\u4e2d\uff0c\u6bd4\u5982MySQL\uff0c\u56e0\u4e3a\u56fa\u5b9a\u6a21\u5f0f\uff08\u5217\u540d\u79f0\u548c\u6570\u636e\u7c7b\u578b\uff09\u5141\u8bb8 item \u5217\u4e2d\u4e0d\u540c\u503c\u7684\u6570\u91cf\u968f\u7740\u6570\u636e\u88ab\u6dfb\u52a0\u5230\u8868\u4e2d\u800c\u6539\u53d8\u3002 date \u548c item \u901a\u5e38\u662f\u4e3b\u952e\uff08\u4f7f\u7528\u5173\u7cfb\u578b\u6570\u636e\u5e93\u7684\u8bf4\u6cd5\uff09\uff0c\u63d0\u4f9b\u4e86\u5173\u7cfb\u5b8c\u6574\u6027\u548c\u66f4\u7b80\u5355\u7684\u8fde\u63a5\u3002 \u5728\u67d0\u4e9b\u60c5\u51b5\u4e0b\uff0c\u5904\u7406\u8fd9\u79cd\u683c\u5f0f\u7684\u6570\u636e\u66f4\u4e3a\u56f0\u96be\u3002\u53ef\u80fd\u66f4\u503e\u5411\u4e8e\u83b7\u53d6\u4e00\u4e2a\u6309 date \u5217\u65f6\u95f4\u6233\u7d22\u5f15\u7684\u4e14\u6bcf\u4e2a\u4e0d\u540c\u7684 item \u72ec\u7acb\u4e00\u5217\u7684DataFrame\u3002 DataFrame\u7684pivot\u65b9\u6cd5\u5c31\u662f\u8fdb\u884c\u8fd9\u79cd\u8f6c\u6362\u7684\uff1a \u4e0b\u9762\u4f8b\u5b50\u4e2d\uff0c\u4f20\u9012\u7684\u524d\u4e24\u4e2a\u503c\u662f\u5206\u522b\u7528\u4f5c\u884c\u548c\u5217\u7d22\u5f15\u7684\u5217\uff0c\u7136\u540e\u662f\u53ef\u9009\u7684\u6570\u503c\u5217\u4ee5\u586b\u5145DataFrame\u3002 \u6ce8\u610f\uff0c pivot \u65b9\u6cd5\u7b49\u4ef7\u4e8e\u4f7f\u7528 set_index \u521b\u5efa\u5206\u5c42\u7d22\u5f15\uff0c\u7136\u540e\u8c03\u7528unstack\u3002 pivoted = ldata.pivot('date', 'item', 'value') print(pivoted) # item infl realgdp unemp # date # 1959-03-31 23:59:59.999999999 0.00 2710.349 5.8 # 1959-06-30 23:59:59.999999999 2.34 2778.801 5.1 # ... ... ... ... # 2009-06-30 23:59:59.999999999 3.37 12901.504 9.2 # 2009-09-30 23:59:59.999999999 3.56 12990.341 9.6 # [203 rows x 3 columns] ldata['value2'] = np.random.randn(len(ldata)) print(ldata[:5]) # date item value value2 # 0 1959-03-31 23:59:59.999999999 realgdp 2710.349 -1.268405 # 1 1959-03-31 23:59:59.999999999 infl 0.000 0.377691 # 2 1959-03-31 23:59:59.999999999 unemp 5.800 -0.342492 # 3 1959-06-30 23:59:59.999999999 realgdp 2778.801 0.132797 # 4 1959-06-30 23:59:59.999999999 infl 2.340 0.180290 \u6b64\u65f6 ldata \u5df2\u7ecf\u6dfb\u52a0\u4e86\u4e00\u5217\u3002\u5982\u679c\u9057\u6f0f\u6700\u540e\u4e00\u4e2a\u53c2\u6570\uff0c\u4f1a\u5f97\u5230\u4e00\u4e2a\u542b\u6709\u591a\u5c42\u5217\u7684DataFrame\uff0c\u5982\u4e0b\uff1a pivoted = ldata.pivot('date', 'item') print(pivoted) # value ... value2 # item infl realgdp ... realgdp unemp # date ... # 1959-03-31 23:59:59.999999999 0.00 2710.349 ... 0.157467 -0.222464 # 1959-06-30 23:59:59.999999999 2.34 2778.801 ... 0.861501 0.368855 # ... ... ... ... ... ... # 2009-06-30 23:59:59.999999999 3.37 12901.504 ... 0.279988 0.934972 # 2009-09-30 23:59:59.999999999 3.56 12990.341 ... 0.547914 1.842967 # [203 rows x 6 columns] \u6ce8\u610f\uff0c pivot \u65b9\u6cd5\u7b49\u4ef7\u4e8e\u4f7f\u7528 set_index \u521b\u5efa\u5206\u5c42\u7d22\u5f15\uff0c\u7136\u540e\u8c03\u7528 unstack \u3002 unstacked = ldata.set_index(['date', 'item']).unstack('item') print(unstacked[:5]) # value ... value2 # item infl realgdp ... realgdp unemp # date ... # 1959-03-31 23:59:59.999999999 0.00 2710.349 ... 0.213120 -0.248004 # 1959-06-30 23:59:59.999999999 2.34 2778.801 ... 0.697763 0.112388 # 1959-09-30 23:59:59.999999999 2.74 2775.488 ... 1.291884 -1.046142 # 1959-12-31 23:59:59.999999999 0.27 2785.204 ... 0.363339 -0.307364 # 1960-03-31 23:59:59.999999999 2.31 2847.699 ... 0.377330 2.272980 # [5 rows x 6 columns] \u5c06\u201c\u5bbd\u201d\u900f\u89c6\u4e3a\u201c\u957f\u201d \u00b6 \u5728DataFrame\u4e2d\uff0cpivot\u65b9\u6cd5\u7684\u53cd\u64cd\u4f5c\u662f pandas.melt \u3002 \u4e0e\u5c06\u4e00\u5217\u53d8\u6362\u4e3a\u65b0\u7684DataFrame\u4e2d\u7684\u591a\u5217\u4e0d\u540c\uff0c\u5b83\u5c06\u591a\u5217\u5408\u5e76\u6210\u4e00\u5217\uff0c\u4ea7\u751f\u4e00\u4e2a\u65b0\u7684DataFrame\uff0c\u5176\u957f\u5ea6\u6bd4\u8f93\u5165\u66f4\u957f\u3002 df = pd.DataFrame( { 'key': ['foo', 'bar', 'baz'], 'A': [1, 2, 3], 'B': [4, 5, 6], 'C': [7, 8, 9] } ) print(df) # key A B C # 0 foo 1 4 7 # 1 bar 2 5 8 # 2 baz 3 6 9 key \u5217\u53ef\u4ee5\u4f5c\u4e3a\u5206\u7ec4\u6307\u6807\uff0c\u5176\u4ed6\u5217\u5747\u4e3a\u6570\u636e\u503c\u3002 \u5f53\u4f7f\u7528 pandas.melt \u65f6\uff0c\u6211\u4eec\u5fc5\u987b\u6307\u660e\u54ea\u4e9b\u5217\u662f\u5206\u7ec4\u6307\u6807\uff08\u5982\u679c\u6709\u7684\u8bdd\uff09\u3002 \u6b64\u5904\uff0c\u8ba9\u6211\u4eec\u4f7f\u7528 key \u4f5c\u4e3a\u552f\u4e00\u7684\u5206\u7ec4\u6307\u6807\uff1a melted = pd.melt(df, ['key']) print(melted) # key variable value # 0 foo A 1 # 1 bar A 2 # 2 baz A 3 # 3 foo B 4 # 4 bar B 5 # 5 baz B 6 # 6 foo C 7 # 7 bar C 8 # 8 baz C 9 \u4f7f\u7528 pivot \u65b9\u6cd5\uff0c\u6211\u4eec\u53ef\u4ee5\u5c06\u6570\u636e\u91cd\u5851\u56de\u539f\u5148\u7684\u5e03\u5c40\u3002 reshaped = melted.pivot('key', 'variable', 'value') print(reshaped) # variable A B C # key # bar 2 5 8 # baz 3 6 9 # foo 1 4 7 \u7531\u4e8e pivot \u7684\u7ed3\u679c\u6839\u636e\u4f5c\u4e3a\u884c\u6807\u7b7e\u7684\u5217\u751f\u6210\u4e86\u7d22\u5f15\uff0c\u53ef\u4f7f\u7528 reset_index \u6765\u5c06\u6570\u636e\u56de\u79fb\u4e00\u5217\uff1a print(reshaped.reset_index()) # variable key A B C # 0 bar 2 5 8 # 1 baz 3 6 9 # 2 foo 1 4 7 pandas.melt \u7684\u4f7f\u7528\u4e5f\u53ef\u4ee5\u65e0\u987b\u4efb\u4f55\u5206\u7ec4\u6307\u6807\u3002 result = pd.melt(df, value_vars=['A', 'B', 'C']) print(result) # variable value # 0 A 1 # 1 A 2 # 2 A 3 # 3 B 4 # 4 B 5 # 5 B 6 # 6 C 7 # 7 C 8 # 8 C 9 result = pd.melt(df, value_vars=['key', 'B', 'C']) print(result) # variable value # 0 key foo # 1 key bar # 2 key baz # 3 B 4 # 4 B 5 # 5 B 6 # 6 C 7 # 7 C 8 # 8 C 9","title":"\u6570\u636e\u89c4\u6574\uff1a\u8fde\u63a5\u3001\u8054\u5408\u4e0e\u91cd\u5851"},{"location":"python/DataAnalysis/ch05/#_1","text":"","title":"\u6570\u636e\u89c4\u6574\uff1a\u8fde\u63a5\u3001\u8054\u5408\u4e0e\u91cd\u5851"},{"location":"python/DataAnalysis/ch05/#_2","text":"import pandas as pd import numpy as np import re \u5206\u5c42\u7d22\u5f15\u662fpandas\u7684\u91cd\u8981\u7279\u6027\uff0c\u5141\u8bb8\u4f60\u5728\u4e00\u4e2a\u8f74\u5411\u4e0a\u62e5\u6709\u591a\u4e2a\uff08\u4e24\u4e2a\u6216\u4e24\u4e2a\u4ee5\u4e0a\uff09\u7d22\u5f15\u5c42\u7ea7\u3002 \u5206\u5c42\u7d22 import re \u5f15\u63d0\u4f9b\u4e86\u4e00\u79cd\u5728\u66f4\u4f4e\u7ef4\u5ea6\u7684\u5f62\u5f0f\u4e2d\u5904\u7406\u66f4\u9ad8\u7ef4\u5ea6\u6570\u636e\u7684\u65b9\u5f0f\u3002","title":"\u5206\u5c42\u7d22\u5f15"},{"location":"python/DataAnalysis/ch05/#series","text":"data = pd.Series( np.random.randn(9), index=[['a', 'a', 'a', 'b', 'b', 'c', 'c', 'd', 'd'], [1, 2, 3, 1, 3, 1, 2, 2, 3]] ) \u8f93\u51fa\u662f\u4e00\u4e2a\u4ee5 MultiIndex \u4f5c\u4e3a\u7d22\u5f15\u7684Series\u7684\u7f8e\u5316\u89c6\u56fe\u3002 \u7d22\u5f15\u4e2d\u7684\"\u95f4\u9699\"\u8868\u793a\"\u76f4\u63a5\u4f7f\u7528\u4e0a\u9762\u7684\u6807\u7b7e\"\u3002 print(data) # a 1 0.163468 # 2 -1.525926 # 3 -0.210247 # b 1 -0.956063 # 3 -1.839111 # c 1 -0.398905 # 2 0.595279 # d 2 0.034305 # 3 -0.896078 # dtype: float64 print(data.index) # MultiIndex([('a', 1), # ('a', 2), # ('a', 3), # ('b', 1), # ('b', 3), # ('c', 1), # ('c', 2), # ('d', 2), # ('d', 3)], # ) \u901a\u8fc7\u5206\u5c42\u7d22\u5f15\u5bf9\u8c61\uff0c\u4e5f\u53ef\u4ee5\u79f0\u4e3a\u90e8\u5206\u7d22\u5f15\uff0c\u53ef\u4ee5\u7b80\u6d01\u5730\u9009\u62e9\u51fa\u6570\u636e\u7684\u5b50\u96c6\u3002 m = data['b'] print(m) # 1 -0.956063 # 3 -1.839111 # dtype: float64 m = data['b': 'c'] print(m) # b 1 -0.956063 # 3 -1.839111 # c 1 -0.398905 # 2 0.595279 # dtype: float64 m = data.loc[['b', 'c']] print(m) # b 1 -0.956063 # 3 -1.839111 # c 1 -0.398905 # 2 0.595279 # dtype: float64 m = data.loc[:, 2] print(m) # a -1.525926 # c 0.595279 # d 0.034305 # dtype: float64 \u5206\u5c42\u7d22\u5f15\u5728\u91cd\u5851\u6570\u636e\u548c\u6570\u7ec4\u900f\u89c6\u8868\u7b49\u5206\u7ec4\u64cd\u4f5c\u4e2d\u626e\u6f14\u4e86\u91cd\u8981\u89d2\u8272\u3002 \u4f8b\u5982\uff0c\u4f60\u53ef\u4ee5\u4f7f\u7528 unstack \u65b9\u6cd5\u5c06\u6570\u636e\u5728DataFrame\u4e2d\u91cd\u65b0\u6392\u5217\u3002 m = data.unstack() print(m) # 1 2 3 # a 0.163468 -1.525926 -0.210247 # b -0.956063 NaN -1.839111 # c -0.398905 0.595279 NaN # d NaN 0.034305 -0.896078 n = m.stack() print(n) # \u6216\u8005 print(data.unstack().stack()) # a 1 0.163468 # 2 -1.525926 # 3 -0.210247 # b 1 -0.956063 # 3 -1.839111 # c 1 -0.398905 # 2 0.595279 # d 2 0.034305 # 3 -0.896078 # dtype: float64","title":"Series\u7d22\u5f15\u5206\u5c42"},{"location":"python/DataAnalysis/ch05/#dataframe","text":"\u5728DataFrame\u4e2d\uff0c\u6bcf\u4e2a\u8f74\u90fd\u53ef\u4ee5\u62e5\u6709\u5206\u5c42\u7d22\u5f15\u3002 \u53c2\u8003","title":"DataFrame\u7d22\u5f15\u5206\u5c42"},{"location":"python/DataAnalysis/ch05/#1","text":"\u76f4\u63a5\u901a\u8fc7\u7ed9 index \uff08columns\uff09\u53c2\u6570\u4f20\u9012\u591a\u7ef4\u6570\u7ec4\uff0c\u8fdb\u800c\u6784\u5efa\u591a\u7ef4\u7d22\u5f15\u3002 \u6570\u7ec4\u4e2d\u6bcf\u4e2a\u7ef4\u5ea6\u5bf9\u5e94\u4f4d\u7f6e\u7684\u5143\u7d20\uff0c\u7ec4\u6210\u6bcf\u4e2a\u7d22\u5f15\u503c\u3002 frame = pd.DataFrame( np.arange(12).reshape((4, 3)), index=[['a', 'a', 'b', 'b'], [1, 2, 1, 2]], columns=[['Ohio', 'Ohio', 'Colorado'], ['Green', 'Red', 'Green']] ) print(frame) # Ohio Colorado # Green Red Green # a 1 0 1 2 # 2 3 4 5 # b 1 6 7 8 # 2 9 10 11 \u4e0a\u9762\u8f93\u51fa\u4e2d\u76842\u4e2a\u5c42\u7ea7\u662f\u6ca1\u6709\u540d\u5b57\u3002 \u5206\u5c42\u7684\u5c42\u7ea7\u53ef\u4ee5\u6709\u540d\u79f0\uff08\u53ef\u4ee5\u662f\u5b57\u7b26\u4e32\u6216Python\u5bf9\u8c61\uff09\u3002 \u5982\u679c\u5c42\u7ea7\u6709\u540d\u79f0\uff0c\u8fd9\u4e9b\u540d\u79f0\u4f1a\u5728\u63a7\u5236\u53f0\u8f93\u51fa\u4e2d\u663e\u793a\u3002 print(frame.index.names) # [None, None] print(frame.columns.names) # [None, None] \u7ed9\u5c42\u7ea7\u8d4b\u4e88\u540d\u79f0\u3002\u6ce8\u610f\u533a\u5206\u884c\u6807\u7b7e\u4e2d\u7684\u7d22\u5f15\u540d\u79f0 state \u548c color \u3002 frame.index.names = ['key1', 'key2'] frame.columns.names = ['state', 'color'] print(frame) # state Ohio Colorado # color Green Red Green # key1 key2 # a 1 0 1 2 # 2 3 4 5 # b 1 6 7 8 # 2 9 10 11 print(frame['Ohio']) # color Green Red # key1 key2 # a 1 0 1 # 2 3 4 # b 1 6 7 # 2 9 10 print(frame.index) # MultiIndex([('a', 1), # ('a', 2), # ('b', 1), # ('b', 2)], # names=['key1', 'key2']) \u901a\u8fc7 MultiIndex \u7c7b\u7684\u76f8\u5173\u65b9\u6cd5\uff0c\u9884\u5148\u521b\u5efa\u4e00\u4e2a MultiIndex \u5bf9\u8c61\uff0c\u7136\u540e\u4f5c\u4e3aSeries\u4e0eDataFrame\u4e2d\u7684 index \uff08\u6216columns\uff09\u53c2\u6570\u503c\u3002\u540c\u65f6\uff0c\u53ef\u4ee5\u901a\u8fc7 names \u53c2\u6570\u6307\u5b9a\u591a\u5c42\u7d22\u5f15\u7684\u540d\u79f0\u3002","title":"\u65b9\u6cd51\uff1a\u76f4\u63a5\u521b\u5efa"},{"location":"python/DataAnalysis/ch05/#2from_arrays","text":"from_arrays \uff1a\u63a5\u6536\u4e00\u4e2a\u591a\u7ef4\u6570\u7ec4\u53c2\u6570\uff0c\u9ad8\u7ef4\u6307\u5b9a\u9ad8\u5c42\u7d22\u5f15\uff0c\u4f4e\u7ef4\u6307\u5b9a\u5e95\u5c42\u7d22\u5f15\u3002 mindex = pd.MultiIndex.from_arrays( [['a', 'a', 'b', 'b'], [1, 2, 1, 2]], names=['key1', 'key2'] ) frame = pd.DataFrame( np.arange(12).reshape((4, 3)), index=mindex, columns=[['Ohio', 'Ohio', 'Colorado'], ['Green', 'Red', 'Green']] ) frame.columns.names = ['state', 'color'] print(frame) # state Ohio Colorado # color Green Red Green # key1 key2 # a 1 0 1 2 # 2 3 4 5 # b 1 6 7 8 # 2 9 10 11","title":"\u65b9\u6cd52\uff1afrom_arrays"},{"location":"python/DataAnalysis/ch05/#3from_tuples","text":"from_tuples \uff1a\u63a5\u6536\u4e00\u4e2a\u5143\u7ec4\u7684\u5217\u8868\uff0c\u6bcf\u4e2a\u5143\u7ec4\u6307\u5b9a\u6bcf\u4e2a\u7d22\u5f15\uff08\u9ad8\u7ef4\u7d22\u5f15\uff0c\u4f4e\u7ef4\u7d22\u5f15\uff09\u3002 mindex = pd.MultiIndex.from_tuples( [('a', 1), ('a', 2), ('b', 1), ('b', 2)] ) frame = pd.DataFrame( np.arange(12).reshape((4, 3)), index=mindex, columns=[['Ohio', 'Ohio', 'Colorado'], ['Green', 'Red', 'Green']] ) frame.index.names = ['key1', 'key2'] frame.columns.names = ['state', 'color'] print(frame) # state Ohio Colorado # color Green Red Green # key1 key2 # a 1 0 1 2 # 2 3 4 5 # b 1 6 7 8 # 2 9 10 11","title":"\u65b9\u6cd53\uff1afrom_tuples"},{"location":"python/DataAnalysis/ch05/#4from_product","text":"from_product \uff1a\u63a5\u6536\u4e00\u4e2a\u53ef\u8fed\u4ee3\u5bf9\u8c61\u7684\u5217\u8868\uff0c\u6839\u636e\u591a\u4e2a\u53ef\u8fed\u4ee3\u5bf9\u8c61\u5143\u7d20\u7684\u7b1b\u5361\u5c14\u79ef\u8fdb\u884c\u521b\u5efa\u7d22\u5f15\u3002 \u4f7f\u7528\u7b1b\u5361\u5c14\u79ef\u7684\u65b9\u5f0f\u6765\u521b\u5efa\u591a\u5c42\u7d22\u5f15\u3002\u53c2\u6570\u4e3a\u5d4c\u5957\u7684\u53ef\u8fed\u4ee3\u5bf9\u8c61\u3002\u7ed3\u679c\u4e3a\u4f7f\u7528\u6bcf\u4e2a\u4e00\u7ef4\u6570\u7ec4\u4e2d\u7684\u5143\u7d20\u4e0e\u5176\u4ed6\u4e00\u7ef4\u6570\u7ec4\u4e2d\u7684\u5143\u7d20\u6765\u751f\u6210\u3002 \u7b1b\u5361\u5c14\u79ef\u7684\u65b9\u5f0f\u7684\u5c40\u9650\uff1a\u4e24\u4e24\u7ec4\u5408\u5fc5\u987b\u90fd\u5b58\u5728\uff0c\u5426\u5219\uff0c\u5c31\u4e0d\u80fd\u4f7f\u7528\u8fd9\u79cd\u65b9\u5f0f\u3002 mindex = pd.MultiIndex.from_product( [['a', 'b'], ['1', '2']], names=['key1', 'key2'] ) frame = pd.DataFrame( np.arange(12).reshape((4, 3)), index=mindex, columns=[['Ohio', 'Ohio', 'Colorado'], ['Green', 'Red', 'Green']] ) frame.columns.names = ['state', 'color'] print(frame) # state Ohio Colorado # color Green Red Green # key1 key2 # a 1 0 1 2 # 2 3 4 5 # b 1 6 7 8 # 2 9 10 11","title":"\u65b9\u6cd54\uff1afrom_product"},{"location":"python/DataAnalysis/ch05/#_3","text":"\u5982\u679c\u9700\u8981\u91cd\u65b0\u6392\u5217\u8f74\u4e0a\u7684\u5c42\u7ea7\u987a\u5e8f\uff0c\u6216\u8005\u6309\u7167\u7279\u5b9a\u5c42\u7ea7\u7684\u503c\u5bf9\u6570\u636e\u8fdb\u884c\u6392\u5e8f\uff0c \u53ef\u4ee5\u901a\u8fc7swaplevel\u63a5\u6536\u4e24\u4e2a\u5c42\u7ea7\u5e8f\u53f7\u6216\u5c42\u7ea7\u540d\u79f0\uff0c\u8fd4\u56de\u4e00\u4e2a\u8fdb\u884c\u4e86\u5c42\u7ea7\u53d8\u66f4\u7684\u65b0\u5bf9\u8c61\uff08\u4f46\u662f\u6570\u636e\u662f\u4e0d\u53d8\u7684\uff09\u3002 print(frame) # state Ohio Colorado # color Green Red Green # key1 key2 # a 1 0 1 2 # 2 3 4 5 # b 1 6 7 8 # 2 9 10 11 m = frame.swaplevel('key1', 'key2') print(m) # state Ohio Colorado # color Green Red Green # key2 key1 # 1 a 0 1 2 # 2 a 3 4 5 # 1 b 6 7 8 # 2 b 9 10 11 sort_index \u53ea\u80fd\u5728\u5355\u4e00\u5c42\u7ea7\u4e0a\u5bf9\u6570\u636e\u8fdb\u884c\u6392\u5e8f\u3002 \u5728\u8fdb\u884c\u5c42\u7ea7\u53d8\u6362\u65f6\uff0c\u4f7f\u7528 sort_index \u4ee5\u4f7f\u5f97\u7ed3\u679c\u6309\u7167\u5c42\u7ea7\u8fdb\u884c\u5b57\u5178\u6392\u5e8f\u3002 m = frame.sort_index(level=1) # \u5bf9key2\u6392\u5e8f\uff0c\u5e95\u5c42\u7d22\u5f15 print(m) # state Ohio Colorado # color Green Red Green # key1 key2 # a 1 0 1 2 # b 1 6 7 8 # a 2 3 4 5 # b 2 9 10 11 m = frame.sort_index(level=0) # \u5bf9key1\u6392\u5e8f\uff0c\u9ad8\u5c42\u7d22\u5f15 print(m) # state Ohio Colorado # color Green Red Green # key1 key2 # a 1 0 1 2 # 2 3 4 5 # b 1 6 7 8 # 2 9 10 11 m = frame.swaplevel(0, 1).sort_index(level=1) # swaplevel(0, 1)\u7b49\u540c\u4e8eswaplevel(key1, key2)\uff0c\u4ea4\u6362\u540ekey1\u53d8\u6210\u4e86\u5e95\u5c42\u7d22\u5f15 print(m) # state Ohio Colorado # color Green Red Green # key2 key1 # 1 a 0 1 2 # 2 a 3 4 5 # 1 b 6 7 8 # 2 b 9 10 11","title":"\u91cd\u6392\u5e8f\u548c\u5c42\u7ea7\u6392\u5e8f"},{"location":"python/DataAnalysis/ch05/#_4","text":"DataFrame\u548cSeries\u4e2d\u5f88\u591a\u63cf\u8ff0\u6027\u548c\u6c47\u603b\u6027\u7edf\u8ba1\u6709\u4e00\u4e2a level \u9009\u9879\uff0c\u901a\u8fc7 level \u9009\u9879\u4f60\u53ef\u4ee5\u6307\u5b9a\u4f60\u60f3\u8981\u5728\u67d0\u4e2a\u7279\u5b9a\u7684\u8f74\u4e0a\u8fdb\u884c\u805a\u5408\u3002 print(frame) # state Ohio Colorado # color Green Red Green # key1 key2 # a 1 0 1 2 # 2 3 4 5 # b 1 6 7 8 # 2 9 10 11 m = frame.groupby(level='key2').sum() print(m) # state Ohio Colorado # color Green Red Green # key2 # 1 6 8 10 # 2 12 14 16 m = frame.groupby(level='color', axis=1).sum() print(m) # color Green Red # key1 key2 # a 1 2 1 # 2 8 4 # b 1 14 7 # 2 20 10","title":"\u6309\u5c42\u7ea7\u8fdb\u884c\u6c47\u603b\u7edf\u8ba1"},{"location":"python/DataAnalysis/ch05/#dataframe_1","text":"\u901a\u5e38\u6211\u4eec\u4e0d\u4f1a\u4f7f\u7528DataFrame\u4e2d\u4e00\u4e2a\u6216\u591a\u4e2a\u5217\u4f5c\u4e3a\u884c\u7d22\u5f15\uff1b\u53cd\u800c\u4f60\u53ef\u80fd\u60f3\u8981\u5c06\u884c\u7d22\u5f15\u79fb\u52a8\u5230DataFrame\u7684\u5217\u4e2d\u3002 frame = pd.DataFrame( {'a': range(7), 'b': range(7, 0, -1), 'c': ['one', 'one', 'one', 'two', 'two', 'two', 'two'], 'd': [0, 1, 2, 0, 1, 2, 3] } ) print(frame) # a b c d # 0 0 7 one 0 # 1 1 6 one 1 # 2 2 5 one 2 # 3 3 4 two 0 # 4 4 3 two 1 # 5 5 2 two 2 # 6 6 1 two 3 DataFrame\u7684 set_index \u51fd\u6570\u4f1a\u751f\u6210\u4e00\u4e2a\u65b0\u7684DataFrame\uff0c\u65b0\u7684DataFrame\u4f7f\u7528\u4e00\u4e2a\u6216\u591a\u4e2a\u5217\u4f5c\u4e3a\u7d22\u5f15\u3002 \u9ed8\u8ba4\u60c5\u51b5\u4e0b\u8fd9\u4e9b\u7d22\u5f15\u5217\u4f1a\u4eceDataFrame\u4e2d\u79fb\u9664\uff0c\u4e5f\u53ef\u4ee5\u5c06\u5b83\u4eec\u7559\u5728DataFrame\u4e2d\u3002 frame2 = frame.set_index(['c', 'd'], drop=False) print(frame2) # a b c d # c d # one 0 0 7 one 0 # 1 1 6 one 1 # 2 2 5 one 2 # two 0 3 4 two 0 # 1 4 3 two 1 # 2 5 2 two 2 # 3 6 1 two 3 frame2 = frame.set_index(['c', 'd']) print(frame2) # a b # c d # one 0 0 7 # 1 1 6 # 2 2 5 # two 0 3 4 # 1 4 3 # 2 5 2 # 3 6 1 reset_index \u662f set_index \u7684\u53cd\u64cd\u4f5c\uff0c\u5206\u5c42\u7d22\u5f15\u7684\u7d22\u5f15\u5c42\u7ea7\u4f1a\u88ab\u79fb\u52a8\u5230\u5217\u4e2d\u3002 \u6ce8\u610f\uff1a\u5982\u679c\u5728 set_index \u65f6\u4f7f\u7528\u4e86 drop=False \uff0c\u5728\u4f7f\u7528 reset_index \u4f1a\u62a5\u9519\u3002 m = frame2.reset_index() print(m) # c d a b # 0 one 0 0 7 # 1 one 1 1 6 # 2 one 2 2 5 # 3 two 0 3 4 # 4 two 1 4 3 # 5 two 2 5 2 # 6 two 3 6 1","title":"\u4f7f\u7528DataFrame\u7684\u5217\u8fdb\u884c\u7d22\u5f15"},{"location":"python/DataAnalysis/ch05/#_5","text":"\u5305\u542b\u5728pandas\u5bf9\u8c61\u7684\u6570\u636e\u53ef\u4ee5\u901a\u8fc7\u591a\u79cd\u65b9\u5f0f\u8054\u5408\u5728\u4e00\u8d77\uff1a pandas.merge \u6839\u636e\u4e00\u4e2a\u6216\u591a\u4e2a\u952e\u5c06\u884c\u8fdb\u884c\u8fde\u63a5\u3002\u5bf9\u4e8eSQL\u6216\u5176\u4ed6\u5173\u7cfb\u578b\u6570\u636e\u5e93\u7684\u7528\u6237\u6765\u8bf4\uff0c\u8fd9\u79cd\u65b9\u5f0f\u6bd4\u8f83\u719f\u6089\uff0c\u5b83\u5b9e\u73b0\u7684\u662f\u6570\u636e\u5e93\u7684\u8fde\u63a5\u64cd\u4f5c\u3002 pandas.concat \u4f7f\u5bf9\u8c61\u5728\u8f74\u5411\u4e0a\u8fdb\u884c\u9ecf\u5408\u6216\u201c\u5806\u53e0\u201d\u3002 combine_first \u5b9e\u4f8b\u65b9\u6cd5\u5141\u8bb8\u5c06\u91cd\u53e0\u7684\u6570\u636e\u62fc\u63a5\u5728\u4e00\u8d77\uff0c\u4ee5\u4f7f\u7528\u4e00\u4e2a\u5bf9\u8c61\u4e2d\u7684\u503c\u586b\u5145\u53e6\u4e00\u4e2a\u5bf9\u8c61\u4e2d\u7684\u7f3a\u5931\u503c\u3002","title":"\u8054\u5408\u4e0e\u5408\u5e76\u6570\u636e\u96c6"},{"location":"python/DataAnalysis/ch05/#dataframe_2","text":"\u5408\u5e76\u6216\u8fde\u63a5\u64cd\u4f5c\u901a\u8fc7\u4e00\u4e2a\u6216\u591a\u4e2a\u952e\u8fde\u63a5\u884c\u6765\u8054\u5408\u6570\u636e\u96c6\u3002 \u8fd9\u4e9b\u64cd\u4f5c\u662f\u5173\u7cfb\u578b\u6570\u636e\u5e93\u7684\u6838\u5fc3\u5185\u5bb9\uff08\u4f8b\u5982\u57fa\u4e8eSQL\u7684\u6570\u636e\u5e93\uff09\u3002 pandas\u4e2d\u7684 merge \u51fd\u6570\u4e3b\u8981\u7528\u4e8e\u5c06\u5404\u79cd join \u64cd\u4f5c\u7b97\u6cd5\u8fd0\u7528\u5728\u6570\u636e\u4e0a\u3002 \u5728\u8fdb\u884c\u5217-\u5217\u8fde\u63a5\u65f6\uff0c\u4f20\u9012\u7684DataFrame\u7d22\u5f15\u5bf9\u8c61\u4f1a\u88ab\u4e22\u5f03\u3002 \u5408\u5e76\u64cd\u4f5c\u4e5f\u8981\u8003\u8651\u5982\u4f55\u5904\u7406\u91cd\u53e0\u7684\u5217\u540d( suffixes \u540e\u7f00\u9009\u9879)\u3002 \u4e0b\u9762\u662f\u4e00\u4e2a\u591a\u5bf9\u4e00\u8fde\u63a5\u7684\u4f8b\u5b50\u3002 df1 \u7684\u6570\u636e\u6709\u591a\u4e2a\u884c\u7684\u6807\u7b7e\u4e3a a \u548c b \uff0c\u800c df2 \u5728 key \u5217\u4e2d\u6bcf\u4e2a\u503c\u4ec5\u6709\u4e00\u884c\u3002 df1 = pd.DataFrame( { 'key': ['b', 'b', 'a', 'c', 'a', 'a', 'b'], 'data1': range(7) } ) df2 = pd.DataFrame( { 'key': ['a', 'b', 'd'], 'data1': range(3) } ) print(df1) # key data1 # 0 b 0 # 1 b 1 # 2 a 2 # 3 c 3 # 4 a 4 # 5 a 5 # 6 b 6 print(df2) # key data1 # 0 a 0 # 1 b 1 # 2 d 2 \u8c03\u7528 merge \u5904\u7406\uff0c\u63a8\u8350\u663e\u5f0f\u5730\u6307\u5b9a\u8fde\u63a5\u952e\u3002 result = pd.merge(df1, df2) print(result) # key data1 # 0 b 1 result = pd.merge(df1, df2, on=['key', 'data1']) print(result) # key data1 # 0 b 1 result = pd.merge(df1, df2, on='key') print(result) # key data1_x data1_y # 0 b 0 1 # 1 b 1 1 # 2 b 6 1 # 3 a 2 0 # 4 a 4 0 # 5 a 5 0 \u5982\u679c\u6bcf\u4e2a\u5bf9\u8c61\u7684\u5217\u540d\u662f\u4e0d\u540c\u7684\uff0c\u53ef\u4ee5\u5206\u522b\u4e3a\u5b83\u4eec\u6307\u5b9a\u5217\u540d\u3002 df3 = pd.DataFrame( { 'lkey': ['b', 'b', 'a', 'c', 'a', 'a', 'b'], 'data1': range(7) } ) df4 = pd.DataFrame( { 'rkey': ['a', 'b', 'd'], 'data2': range(3) } ) print(df3) # lkey data1 # 0 b 0 # 1 b 1 # 2 a 2 # 3 c 3 # 4 a 4 # 5 a 5 # 6 b 6 print(df4) # rkey data2 # 0 a 0 # 1 b 1 # 2 d 2 \u9ed8\u8ba4\u60c5\u51b5\u4e0b\uff0c merge \u505a\u7684\u662f\u5185\u8fde\u63a5\uff08'inner' join\uff09\uff0c\u7ed3\u679c\u4e2d\u7684\u952e\u662f\u4e24\u5f20\u8868\u7684\u4ea4\u96c6\u3002 result = pd.merge(df3, df4, left_on='lkey', right_on='rkey') # df4\u7684[a,0]\u5bf9\u5e94df3\u7684\u6240\u6709[a,?]\u8bb0\u5f55\uff08\u901a\u8fc7\u91cd\u590d\u6765\u586b\u5145\u4e0d\u8db3\uff09 print(result) # lkey data1 rkey data2 # 0 b 0 b 1 # 1 b 1 b 1 # 2 b 6 b 1 # 3 a 2 a 0 # 4 a 4 a 0 # 5 a 5 a 0 \u5916\u8fde\u63a5\uff08outer join\uff09\u662f\u952e\u7684\u5e76\u96c6\uff0c\u8054\u5408\u4e86\u5de6\u8fde\u63a5\u548c\u53f3\u8fde\u63a5\u7684\u6548\u679c\u3002 \u591a\u5bf9\u591a\u8fde\u63a5\u662f\u884c\u7684\u7b1b\u5361\u5c14\u79ef\u3002 df1 = pd.DataFrame( { 'key': ['b', 'b', 'a', 'c', 'a', 'b'], 'data1': range(6) } ) df2 = pd.DataFrame( { 'key': ['a', 'b', 'a', 'b', 'd'], 'data2': range(5) } ) print(df1.sort_values(by='key')) # key data1 # 2 a 2 # 4 a 4 # 0 b 0 # 1 b 1 # 5 b 5 # 3 c 3 print(df2.sort_values(by='key')) # key data2 # 0 a 0 # 2 a 2 # 1 b 1 # 3 b 3 # 4 d 4 result = pd.merge(df1, df2, on='key', how='left') print(result.sort_values(by='key')) # key data1 data2 # 4 a 2 0.0 # 5 a 2 2.0 # 7 a 4 0.0 # 8 a 4 2.0 # 0 b 0 1.0 # 1 b 0 3.0 # 2 b 1 1.0 # 3 b 1 3.0 # 9 b 5 1.0 # 10 b 5 3.0 # 6 c 3 NaN result = pd.merge(df1, df2, on='key', how='outer') # \u591a\u5bf9\u591a\u8fde\u63a5 print(result.sort_values(by='key')) # key data1 data2 # 6 a 2.0 0.0 # 7 a 2.0 2.0 # 8 a 4.0 0.0 # 9 a 4.0 2.0 # 0 b 0.0 1.0 # 1 b 0.0 3.0 # 2 b 1.0 1.0 # 3 b 1.0 3.0 # 4 b 5.0 1.0 # 5 b 5.0 3.0 # 10 c 3.0 NaN # 11 d NaN 4.0 \u591a\u952e\u5408\u5e76\u3002 df1 = pd.DataFrame( { 'key1': ['foo', 'foo', 'bar'], 'key2': ['one', 'two', 'one'], 'lval': [1, 2, 3] } ) df2 = pd.DataFrame( { 'key1': ['foo', 'foo', 'bar', 'bar'], 'key2': ['one', 'one', 'one', 'two'], 'rval': [4, 5, 6, 7] } ) print(df1.sort_values(by=['key1', 'key2'])) # key1 key2 lval # 2 bar one 3 # 0 foo one 1 # 1 foo two 2 print(df2.sort_values(by=['key1', 'key2'])) # key1 key2 rval # 2 bar one 6 # 3 bar two 7 # 0 foo one 4 # 1 foo one 5 result = pd.merge(df1, df2, on=['key1', 'key2'], how='outer') print(result.sort_values(by=['key1', 'key2'])) # key1 key2 lval rval # 3 bar one 3.0 6.0 # 4 bar two NaN 7.0 # 0 foo one 1.0 4.0 # \u91cd\u590d\u586b\u5145 # 1 foo one 1.0 5.0 # \u91cd\u590d\u586b\u5145 # 2 foo two 2.0 NaN \u5904\u7406\u91cd\u53e0\u5217\u540d\u3002 result = pd.merge(df1, df2, on='key1') print(result.sort_values(by='key1')) # key1 key2_x lval key2_y rval # 4 bar one 3 one 6 # 5 bar one 3 two 7 # 0 foo one 1 one 4 # 1 foo one 1 one 5 # 2 foo two 2 one 4 # 3 foo two 2 one 5 result = pd.merge(df1, df2, on='key1', suffixes=('_left', '_right')) print(result.sort_values(by='key1')) # key1 key2_left lval key2_right rval # 4 bar one 3 one 6 # 5 bar one 3 two 7 # 0 foo one 1 one 4 # 1 foo one 1 one 5 # 2 foo two 2 one 4 # 3 foo two 2 one 5","title":"\u6570\u636e\u5e93\u98ce\u683c\u7684DataFrame\u8fde\u63a5"},{"location":"python/DataAnalysis/ch05/#_6","text":"\u5728\u67d0\u4e9b\u60c5\u51b5\u4e0b\uff0cDataFrame\u4e2d\u7528\u4e8e\u5408\u5e76\u7684\u952e\u662f\u5b83\u7684\u7d22\u5f15\u3002\u53ef\u4ee5\u4f20\u9012 left_index=True \u6216 right_index=True \uff08\u6216\u8005\u90fd\u4f20\uff09\u6765\u8868\u793a\u7d22\u5f15\u9700\u8981\u7528\u6765\u4f5c\u4e3a\u5408\u5e76\u7684\u952e\u3002 df1 = pd.DataFrame( { 'key1': ['foo', 'foo', 'bar'], 'key2': ['one', 'two', 'one'], 'lval': [1, 2, 3] } ) df2 = pd.DataFrame( { 'key1': ['foo', 'foo', 'bar', 'bar'], 'key2': ['one', 'one', 'one', 'two'], 'rval': [4, 5, 6, 7] }, index=['foo', 'foo', 'bar', 'bar'] ) print(df1) # key1 key2 lval # 0 foo one 1 # 1 foo two 2 # 2 bar one 3 print(df2) # key1 key2 rval # foo foo one 4 # foo foo one 5 # bar bar one 6 # bar bar two 7 result = pd.merge(df1, df2, left_on='key1', right_index=True, suffixes=('_left', '_right')) print(result.sort_index()) # key1 key1_left key2_left lval key1_right key2_right rval # 0 foo foo one 1 foo one 4 # 0 foo foo one 1 foo one 5 # 1 foo foo two 2 foo one 4 # 1 foo foo two 2 foo one 5 # 2 bar bar one 3 bar one 6 # 2 bar bar one 3 bar two 7 result = pd.merge(df1, df2, left_on='key1', right_index=True, how='outer', suffixes=('_left', '_right')) # \u548c\u4e0a\u8ff0\u7ed3\u679c\u4e00\u6837 print(result.sort_index()) # key1 key1_left key2_left lval key1_right key2_right rval # 0 foo foo one 1 foo one 4 # 0 foo foo one 1 foo one 5 # 1 foo foo two 2 foo one 4 # 1 foo foo two 2 foo one 5 # 2 bar bar one 3 bar one 6 # 2 bar bar one 3 bar two 7 \u5728\u66f4\u590d\u6742\u591a\u5c42\u7d22\u5f15\u6570\u636e\u7684\u591a\u952e\u5408\u5e76\uff0c\u5728\u7d22\u5f15\u4e0a\u8fde\u63a5\u662f\u4e00\u4e2a\u9690\u5f0f\u7684\u591a\u952e\u5408\u5e76\u3002 \u5fc5\u987b\u4ee5\u5217\u8868\u7684\u65b9\u5f0f\u6307\u660e\u5408\u5e76\u6240\u9700\u591a\u4e2a\u5217\uff08\u6ce8\u610f\u4f7f\u7528 how='outer' \u5904\u7406\u91cd\u590d\u7684\u7d22\u5f15\u503c\uff09\u3002 df1 = pd.DataFrame( { 'key1': ['Ohio', 'Ohio', 'Ohio', 'Nevada', 'Nevada'], 'key2': [2000, 2001, 2002, 2001, 2002], 'data': np.arange(5.) } ) df2 = pd.DataFrame( np.arange(12).reshape((6, 2)), index=[ ['Nevada', 'Nevada', 'Ohio', 'Ohio', 'Ohio', 'Ohio'], [2001, 2000, 2000, 2000, 2001, 2002] ], columns=['event1', 'event2'] ) print(df1) # key1 key2 data # 0 Ohio 2000 0.0 # 1 Ohio 2001 1.0 # 2 Ohio 2002 2.0 # 3 Nevada 2001 3.0 # 4 Nevada 2002 4.0 print(df2) # event1 event2 # Nevada 2001 0 1 # 2000 2 3 # Ohio 2000 4 5 # 2000 6 7 # 2001 8 9 # 2002 10 11 result = pd.merge(df1, df2, left_on=['key1', 'key2'], right_index=True) print(result) # key1 key2 data event1 event2 # 0 Ohio 2000 0.0 4 5 # 0 Ohio 2000 0.0 6 7 # 1 Ohio 2001 1.0 8 9 # 2 Ohio 2002 2.0 10 11 # 3 Nevada 2001 3.0 0 1 result = pd.merge(df1, df2, left_on=['key1', 'key2'], right_index=True, how='outer') print(result) # key1 key2 data event1 event2 # 0 Ohio 2000 0.0 4.0 5.0 # 0 Ohio 2000 0.0 6.0 7.0 # 1 Ohio 2001 1.0 8.0 9.0 # 2 Ohio 2002 2.0 10.0 11.0 # 3 Nevada 2001 3.0 0.0 1.0 # 4 Nevada 2002 4.0 NaN NaN # 4 Nevada 2000 NaN 2.0 3.0 \u4f7f\u7528\u4e24\u8fb9\u7684\u7d22\u5f15\u8fdb\u884c\u5408\u5e76\u4e5f\u662f\u53ef\u4ee5\u7684\uff0c\u524d\u63d0\u662f\u7528\u4e24\u8fb9\u7528\u6765\u5408\u5e76\u7684\u7d22\u5f15\u6709\u4ea4\u96c6\uff08\u516c\u5171\u90e8\u5206\uff09\u3002 \u5728\u4f7f\u7528 merge \u65f6\uff0c\u53c2\u6570 on=['key1', 'key2'] \u4e0d\u80fd\u548c left_index=True , right_index=True \u540c\u65f6\u5b58\u5728\u3002 \u5bf9\u4e8e\u91cd\u590d\u7d22\u5f15\uff0c\u5982\u679c\u503c\u4e0d\u540c\uff0c\u5219\u591a\u884c\u663e\u793a\uff0c\u548c\u6570\u636e\u5e93SQL\u7684 full join \u7c7b\u4f3c\u6982\u5ff5\u3002 \u5982\u679c\u51fa\u73b0\u76f8\u540c\u5217\u540d\uff0c\u5219\u4f1a\u81ea\u52a8\u6dfb\u52a0\u540e\u7f00\u5b57\u7b26\u4ee5\u793a\u533a\u522b\u3002 df1 = pd.DataFrame( [[1, 2], [3, 4], [5, 6]], index=['a', 'c', 'e'], columns=['Ohio', 'Nevada'] ) print(df1) # Ohio Nevada # a 1 2 # c 3 4 # e 5 6 df2 = pd.DataFrame( [[7, 8], [9, 10], [11, 12], [13, 14]], index=['b', 'c', 'c', 'e'], columns=['Missouri', 'Alabama'] ) print(df2) # Missouri Alabama # b 7 8 # c 9 10 # c 11 12 # e 13 14 df3 = pd.DataFrame( [[7, 8], [9, 10], [11, 12], [13, 14]], index=['a', 'c', 'e', 'f'], columns=['Nevada', 'Alabama'] ) print(df3) # Nevada Alabama # a 7 8 # c 9 10 # e 11 12 # f 13 14 result = pd.merge(df1, df2, left_index=True, right_index=True, how='outer') print(result) # Ohio Nevada Missouri Alabama # a 1.0 2.0 NaN NaN # b NaN NaN 7.0 8.0 # c 3.0 4.0 9.0 10.0 # c 3.0 4.0 11.0 12.0 # e 5.0 6.0 13.0 14.0 result = pd.merge(df1, df3, left_index=True, right_index=True, how='outer') print(result) # Ohio Nevada_x Nevada_y Alabama # a 1.0 2.0 7 8 # c 3.0 4.0 9 10 # e 5.0 6.0 11 12 # f NaN NaN 13 14 \u53e6\u4e00\u79cd\u5199\u6cd5\uff1a result = df1.join(df2, how='outer') print(result) # Ohio Nevada Missouri Alabama # a 1.0 2.0 NaN NaN # b NaN NaN 7.0 8.0 # c 3.0 4.0 9.0 10.0 # c 3.0 4.0 11.0 12.0 # e 5.0 6.0 13.0 14.0 \u4e5f\u53ef\u4ee5\u5411 join \u65b9\u6cd5\u4f20\u5165\u4e00\u4e2aDataFrame\u5217\u8868\uff0c\u7c7b\u4f3c\u4e8e\u5bf9\u4e09\u4e2a\u6570\u636e\u96c6\u8fdb\u884c join \u64cd\u4f5c\u3002 result = df1.join([df2, df3]) print(result) # Ohio Nevada_x Missouri Alabama_x Nevada_y Alabama_y # a 1 2 NaN NaN 7 8 # c 3 4 9.0 10.0 9 10 # c 3 4 11.0 12.0 9 10 # e 5 6 13.0 14.0 11 12","title":"\u6839\u636e\u7d22\u5f15\u5408\u5e76"},{"location":"python/DataAnalysis/ch05/#_7","text":"\u53e6\u4e00\u79cd\u6570\u636e\u7ec4\u5408\u64cd\u4f5c\u53ef\u79f0\u4e3a\u62fc\u63a5\u3001\u7ed1\u5b9a\u6216\u5806\u53e0\u3002NumPy\u7684 concatenate \u51fd\u6570\u53ef\u4ee5\u5728NumPy\u6570\u7ec4\u4e0a\u5b9e\u73b0\u8be5\u529f\u80fd\u3002 \u57fa\u4e8eSeries\u7684pandas\u7684 concat \u51fd\u6570\u7684\u5de5\u4f5c\u673a\u5236\u5206\u6790\u3002 \u4e0b\u9762\u4e09\u4e2a\u7d22\u5f15\u4e0d\u91cd\u53e0\u7684Series\u3002 s1 = pd.Series([0, 1], index=['a', 'b']) s2 = pd.Series([2, 3, 4], index=['c', 'd', 'e']) s3 = pd.Series([5, 6], index=['f', 'g']) \u7528\u5217\u8868\u4e2d\u7684\u8fd9\u4e9b\u5bf9\u8c61\u8c03\u7528 concat \u65b9\u6cd5\u4f1a\u5c06\u503c\u548c\u7d22\u5f15\u7c98\u5728\u4e00\u8d77\uff1a \u9ed8\u8ba4\u60c5\u51b5\u4e0b\uff0c concat \u65b9\u6cd5\u662f\u6cbf\u7740 axis=0 \u7684\u8f74\u5411\u751f\u6548\u7684\uff0c\u751f\u6210\u53e6\u4e00\u4e2aSeries\u3002 \u5982\u679c\u4f20\u9012 axis=1 \uff0c\u8fd4\u56de\u7684\u7ed3\u679c\u5219\u662f\u4e00\u4e2aDataFrame\uff08 axis=1 \u65f6\u662f\u5217\uff09\u3002 result = pd.concat([s1, s2, s3]) print(result) # a 0 # b 1 # c 2 # d 3 # e 4 # f 5 # g 6 # dtype: int64 result = pd.concat([s1, s2, s3], keys=['one', 'two', 'three']) # \u901a\u8fc7keys\u53c2\u6570\uff0c\u5728\u8fde\u63a5\u8f74\u5411\u4e0a\u521b\u5efa\u4e00\u4e2a\u591a\u5c42\u7d22\u5f15\uff0c\u4ee5\u4fbf\u5728\u7ed3\u679c\u4e2d\u533a\u5206\u5404\u90e8\u5206 print(result) # one a 0 # b 1 # two c 2 # d 3 # e 4 # three f 5 # g 6 # dtype: int64 print(result.unstack()) # \u628a\u539f\u7d22\u5f15\u4f5c\u4e3a\u5217\u6807\u7b7e\u5c55\u5f00 # a b c d e f g # one 0.0 1.0 NaN NaN NaN NaN NaN # two NaN NaN 2.0 3.0 4.0 NaN NaN # three NaN NaN NaN NaN NaN 5.0 6.0 result = pd.concat([s1, s2, s3], axis=1) # \u5728\u8fd9\u4e2a\u6848\u4f8b\u4e2daxis=1\u8f74\u5411\u4e0a\u5e76\u6ca1\u6709\u91cd\u53e0 print(result) # 0 1 2 # a 0.0 NaN NaN # b 1.0 NaN NaN # c NaN 2.0 NaN # d NaN 3.0 NaN # e NaN 4.0 NaN # f NaN NaN 5.0 # g NaN NaN 6.0 result = pd.concat([s1, s2, s3], axis=1, keys=['one', 'two', 'three']) # \u5728\u8fd9\u4e2a\u6848\u4f8b\u4e2daxis=1\u8f74\u5411\u4e0a\u5e76\u6ca1\u6709\u91cd\u53e0 print(result) # one two three # a 0.0 NaN NaN # b 1.0 NaN NaN # c NaN 2.0 NaN # d NaN 3.0 NaN # e NaN 4.0 NaN # f NaN NaN 5.0 # g NaN NaN 6.0 print(result.unstack()) # \u5bf9\u6bd4axis=0\u7684\u591a\u5c42\u7d22\u5f15\uff0c\u5f53axis=1\u65f6\u5bf9\u8f93\u51fa\u5404index\u7684\u5e76\u96c6\u505a\u4e86\u5206\u7ec4\u3002 # one a 0.0 # b 1.0 # c NaN # d NaN # e NaN # f NaN # g NaN # two a NaN # b NaN # c 2.0 # d 3.0 # e 4.0 # f NaN # g NaN # three a NaN # b NaN # c NaN # d NaN # e NaN # f 5.0 # g 6.0 # dtype: float64 s4 = pd.concat([s1, s3]) print(s4) # a 0 # b 1 # f 5 # g 6 # dtype: int64 result = pd.concat([s1, s4]) print(result) # a 0 # b 1 # a 0 # b 1 # f 5 # g 6 # dtype: int64 result = pd.concat([s1, s4], axis=1) # \u73b0\u5728\u5728\u4e2daxis=1\u8f74\u5411\u4e0a\u6709\u91cd\u53e0 print(result) # 0 1 # a 0.0 0 # b 1.0 1 # f NaN 5 # g NaN 6 result = pd.concat([s1, s4], axis=1, keys=['one', 'two', 'three']) print(result) # one two # a 0.0 0 # b 1.0 1 # f NaN 5 # g NaN 6 result = pd.concat([s1, s4], axis=0, keys=['one', 'two', 'three']) # \u901a\u8fc7keys\u53c2\u6570\uff0c\u5728\u8fde\u63a5\u8f74\u5411\u4e0a\u521b\u5efa\u4e00\u4e2a\u591a\u5c42\u7d22\u5f15 print(result) # one a 0 # b 1 # two a 0 # b 1 # f 5 # g 6 # dtype: int64 result = pd.concat([s1, s4], axis=1, join='inner') # \u5185\u8fde\u63a5\u65b9\u5f0f\u5408\u5e76\u7d22\u5f15\uff08\u7d22\u5f15\u4ea4\u96c6\uff09 print(result) # 0 1 # a 0 0 # b 1 1 result = pd.concat([s1, s4], axis=1).reindex(['a', 'c', 'b', 'e']) # \u4f7f\u7528join_axes(\u5df2\u88ab\u66ff\u6362\u6210reindex)\u6765\u6307\u5b9a\u7528\u4e8e\u8fde\u63a5\u5176\u4ed6\u8f74\u5411\u7684\u8f74 print(result) # 0 1 # a 0.0 0.0 # c NaN NaN # b 1.0 1.0 # e NaN NaN \u57fa\u4e8eDataFrame\u7684pandas\u7684 concat \u51fd\u6570\u7684\u5de5\u4f5c\u673a\u5236\u5206\u6790\u3002 df1 = pd.DataFrame( np.arange(12).reshape((6, 2)), index=[ ['Ohio', 'Ohio', 'Ohio', 'Nevada', 'Nevada', 'Nevada'], [2000, 2001, 2002, 2000, 2001, 2002] ], columns=['event1', 'event2'] ) df2 = pd.DataFrame( np.arange(12).reshape((6, 2)), index=[ ['Ohio', 'Ohio', 'Ohio', 'Nevada', 'Nevada', 'Nevada'], [2000, 2001, 2002, 2000, 2001, 2002] ], columns=['event3', 'event4'] ) print(df1) # event1 event2 # Ohio 2000 0 1 # 2001 2 3 # 2002 4 5 # Nevada 2000 6 7 # 2001 8 9 # 2002 10 11 print(df2) # event3 event4 # Ohio 2000 0 1 # 2001 2 3 # 2002 4 5 # Nevada 2000 6 7 # 2001 8 9 # 2002 10 11 result = np.concatenate([df1, df2], axis=0) # \u6cbf0\u8f74\u62fc\u63a5 print(result) # [[ 0 1] # [ 2 3] # [ 4 5] # [ 6 7] # [ 8 9] # [10 11] # [ 0 1] # [ 2 3] # [ 4 5] # [ 6 7] # [ 8 9] # [10 11]] result = np.concatenate([df1, df2], axis=1) # \u6cbf1\u8f74\u62fc\u63a5 print(result) # [[ 0 1 0 1] # [ 2 3 2 3] # [ 4 5 4 5] # [ 6 7 6 7] # [ 8 9 8 9] # [10 11 10 11]] result = np.concatenate([df1, df2], axis=None) # \u5c06\u6570\u7ec4\u5c55\u5e73 print(result) # [ 0 1 2 3 4 5 6 7 8 9 10 11 0 1 2 3 4 5 6 7 8 9 10 11]","title":"\u6cbf\u8f74\u5411\u8fde\u63a5"},{"location":"python/DataAnalysis/ch05/#_8","text":"\u53e6\u4e00\u4e2a\u6570\u636e\u8054\u5408\u573a\u666f\uff0c\u65e2\u4e0d\u662f\u5408\u5e76\u64cd\u4f5c\uff0c\u4e5f\u4e0d\u662f\u8fde\u63a5\u64cd\u4f5c\u3002 \u5047\u5982\u6709\u4e24\u4e2a\u6570\u636e\u96c6\uff0c\u8fd9\u4e24\u4e2a\u6570\u636e\u96c6\u7684\u7d22\u5f15\u5168\u90e8\u6216\u90e8\u5206\u91cd\u53e0\uff0c\u901a\u8fc7NumPy\u7684 where \u51fd\u6570\u53ef\u4ee5\u8fdb\u884c\u9762\u5411\u6570\u7ec4\u7684if-else\u7b49\u4ef7\u64cd\u4f5c\u3002 s1 = pd.Series( [np.nan, 2.5, 0.0, 3.5, 4.5, np.nan], index=['f', 'e', 'd', 'c', 'b', 'a'] ) s2 = pd.Series( [0.0, np.nan, 2.0, np.nan, np.nan, 5.0], index=['a', 'b', 'c', 'd', 'e', 'f'] ) print(s1) # f NaN # e 2.5 # d 0.0 # c 3.5 # b 4.5 # a NaN # dtype: float64 print(s2) # a 0.0 # b NaN # c 2.0 # d NaN # e NaN # f 5.0 # dtype: float64 \u65b9\u6cd51\uff0c\u901a\u8fc7Numpy\u7684 where \u51fd\u6570\u3002 result = np.where(pd.isnull(s1), s2, s1) # An array with elements from 'x'(s2) where 'condition'(isnull(s1)) is True, and elements from 'y'(s1) elsewhere. print(result) # [0. 2.5 0. 3.5 4.5 5. ] # s1 # s2 # result # f NaN # a 0.0 0. \u6761\u4ef6\u4e2ds1\u8be5\u5143\u7d20\u4e3anull\uff0c\u6240\u4ee5where\u51fd\u6570\u53d6\u5bf9\u5e94x(s2)\u7684\u5143\u7d20\uff08\u6ce8\u610f\uff0c\u4e0e\u7d22\u5f15\u987a\u5e8f\u65e0\u5173\uff09 # e 2.5 # b NaN 2.5 \u6761\u4ef6\u4e2ds1\u8be5\u5143\u7d20\u4e0d\u4e3anull\uff0c\u6240\u4ee5where\u51fd\u6570\u53d6\u5bf9\u5e94y(s1)\u7684\u5143\u7d20 # d 0.0 # c 2.0 0. # c 3.5 # d NaN 3.5 # b 4.5 # e NaN 4.5 # a NaN # f 5.0 5.0 \u6761\u4ef6\u4e2ds1\u8be5\u5143\u7d20\u4e3anull\uff0c\u6240\u4ee5where\u51fd\u6570\u53d6\u5bf9\u5e94x(s2)\u7684\u5143\u7d20 result = np.where(pd.isnull(s2), s1, s2) print(result) # [0. 2.5 2. 3.5 4.5 5. ] \u65b9\u6cd52\uff0c\u901a\u8fc7Series\u7684 combine_first \u65b9\u6cd5\u3002 result = s2.combine_first(s1) # \u6ce8\u610f\uff0ccombine_first\u662f\u6309\u7167s2\u7684\u7d22\u5f15\u987a\u5e8f\u68c0\u7d22\u7684\uff0c\u76f8\u540c\u7d22\u5f15\u7684s1\u7684\u503c\u4f1a\u586b\u5145\u5bf9\u5e94s2\u7684null print(result) # a 0.0 # b 4.5 # c 2.0 # d 0.0 # e 2.5 # f 5.0 # dtype: float64 \u65b9\u6cd53\uff1aPandas\u7684 combine_first \u65b9\u6cd5\u3002 df1 = pd.DataFrame( { 'a': [1.0, np.nan, 5.0, np.nan], 'b': [np.nan, 2.0, np.nan, 6.0], 'c': [2.0, 6.0, 10.0, 15.0] } ) df2 = pd.DataFrame( { 'a': [5.0, 4.0, np.nan, 3.0, 7.0], 'b': [np.nan, 3.0, 4.0, 6.0, 8.0] } ) print(df1) # a b c # 0 1.0 NaN 2.0 # 1 NaN 2.0 6.0 # 2 5.0 NaN 10.0 # 3 NaN 6.0 15.0 print(df2) # a b # 0 5.0 NaN # 1 4.0 3.0 # 2 NaN 4.0 # 3 3.0 6.0 # 4 7.0 8.0 result = df2.combine_first(df1) # \u7528df1\u7684\u503c\u53bb\u586b\u5145df2\u5bf9\u5e94\u7d22\u5f15\u4f4d\u7f6e\u7684null\u503c print(result) # a b c # 0 5.0 NaN 2.0 # 1 4.0 3.0 6.0 # 2 5.0 4.0 10.0 # 3 3.0 6.0 15.0 # 4 7.0 8.0 NaN","title":"\u8054\u5408\u91cd\u53e0\u6570\u636e"},{"location":"python/DataAnalysis/ch05/#_9","text":"\u91cd\u65b0\u6392\u5217\u8868\u683c\u578b\u6570\u636e\u6709\u591a\u79cd\u57fa\u7840\u64cd\u4f5c\u3002\u8fd9\u4e9b\u64cd\u4f5c\u88ab\u79f0\u4e3a\u91cd\u5851\u6216\u900f\u89c6\u3002 import numpy as np import pandas as pd","title":"\u91cd\u5851\u548c\u900f\u89c6"},{"location":"python/DataAnalysis/ch05/#_10","text":"\u591a\u5c42\u7d22\u5f15\u5728DataFrame\u4e2d\u63d0\u4f9b\u4e86\u4e00\u79cd\u4e00\u81f4\u6027\u65b9\u5f0f\u7528\u4e8e\u91cd\u6392\u5217\u6570\u636e\u3002\u4ee5\u4e0b\u662f\u4e24\u4e2a\u57fa\u7840\u64cd\u4f5c\uff1a statck\uff08\u5806\u53e0\uff09\u8be5\u64cd\u4f5c\u4f1a\u201c\u65cb\u8f6c\u201d\u6216\u5c06\u5217\u4e2d\u7684\u6570\u636e\u900f\u89c6\u5230\u884c\u3002 unstack\uff08\u62c6\u5806\uff09\u8be5\u64cd\u4f5c\u4f1a\u5c06\u884c\u4e2d\u7684\u6570\u636e\u900f\u89c6\u5230\u5217\u3002 df = pd.DataFrame( np.arange(6).reshape((2, 3)), index=pd.Index(['Ohio', 'Colorado'], name='state'), columns=pd.Index(['one', 'two', 'three'], name='number') ) print(df) # number one two three # state # Ohio 0 1 2 # Colorado 3 4 5 \u5728\u8fd9\u4efd\u6570\u636e\u4e0a\u4f7f\u7528stack\u65b9\u6cd5\u4f1a\u5c06\u5217\u900f\u89c6\u5230\u884c\uff0c\u4ea7\u751f\u4e00\u4e2a\u65b0\u7684Series\uff1a result = df.stack() print(result) # state number # Ohio one 0 # two 1 # three 2 # Colorado one 3 # two 4 # three 5 # dtype: int64 \u4ece\u4e00\u4e2a\u591a\u5c42\u7d22\u5f15\u5e8f\u5217\u4e2d\uff0c\u4f60\u53ef\u4ee5\u4f7f\u7528 unstack \u65b9\u6cd5\u5c06\u6570\u636e\u91cd\u6392\u5217\u540e\u653e\u5165\u4e00\u4e2aDataFrame\u4e2d\uff1a print(result.unstack()) # number one two three # state # Ohio 0 1 2 # Colorado 3 4 5 print(result.unstack(0)) # \u53ef\u4ee5\u4f20\u5165\u4e00\u4e2a\u5c42\u7ea7\u5e8f\u53f7\u6216\u540d\u79f0\u6765\u62c6\u5206\u4e00\u4e2a\u4e0d\u540c\u7684\u5c42\u7ea7 # state Ohio Colorado # number # one 0 3 # two 1 4 # three 2 5 print(result.unstack(1)) # number one two three # state # Ohio 0 1 2 # Colorado 3 4 5 print(result.unstack('state')) # \u8f93\u51fa\u7ed3\u679c\u548c\u4f20\u5165\u5c42\u7ea70\u4e00\u6837 # state Ohio Colorado # number # one 0 3 # two 1 4 # three 2 5 print(result.unstack('number')) # \u8f93\u51fa\u7ed3\u679c\u548c\u4f20\u5165\u5c42\u7ea71\u4e00\u6837 # number one two three # state # Ohio 0 1 2 # Colorado 3 4 5 \u5982\u679c\u5c42\u7ea7\u4e2d\u7684\u6240\u6709\u503c\u5e76\u672a\u5305\u542b\u4e8e\u6bcf\u4e2a\u5b50\u5206\u7ec4\u4e2d\u65f6\uff0c\u62c6\u5206\u53ef\u80fd\u4f1a\u5f15\u5165\u7f3a\u5931\u503c\uff1a s1 = pd.Series([0, 1, 2, 3], index=['a', 'b', 'c', 'd']) s2 = pd.Series([4, 5, 6], index=['c', 'd', 'e']) s3 = pd.concat([s1, s2], keys=['one', 'two']) print(s3) # one a 0 # b 1 # c 2 # d 3 # two c 4 # d 5 # e 6 # dtype: int64 print(s3.unstack(0)) # one two # a 0.0 NaN # b 1.0 NaN # c 2.0 4.0 # d 3.0 5.0 # e NaN 6.0 print(s3.unstack(1)) print(s3.unstack()) # a b c d e # one 0.0 1.0 2.0 3.0 NaN # two NaN NaN 4.0 5.0 6.0 \u9ed8\u8ba4\u60c5\u51b5\u4e0b\uff0c\u5806\u53e0\u4f1a\u8fc7\u6ee4\u51fa\u7f3a\u5931\u503c\uff0c\u56e0\u6b64\u5806\u53e0\u62c6\u5806\u7684\u64cd\u4f5c\u662f\u53ef\u9006\u7684\u3002 print(s3.unstack().stack()) # one a 0.0 # b 1.0 # c 2.0 # d 3.0 # two c 4.0 # d 5.0 # e 6.0 # dtype: float64 print(s3.unstack().stack(dropna=False)) # one a 0.0 # b 1.0 # c 2.0 # d 3.0 # e NaN # two a NaN # b NaN # c 4.0 # d 5.0 # e 6.0 # dtype: float64 \u5728DataFrame\u4e2d\u62c6\u5806\u65f6\uff0c\u88ab\u62c6\u5806\u7684\u5c42\u7ea7\u4f1a\u53d8\u4e3a\u7ed3\u679c\u4e2d\u6700\u4f4e\u7684\u5c42\u7ea7\u3002 \u5728\u8c03\u7528 stack \u65b9\u6cd5\u65f6\uff0c\u6211\u4eec\u53ef\u4ee5\u6307\u660e\u9700\u8981\u5806\u53e0\u7684\u8f74\u5411\u540d\u79f0\u3002 df = pd.DataFrame( {'left': result, 'right': result + 5}, columns=pd.Index(['left', 'right'], name='side') ) print(df) # side left right # state number # Ohio one 0 5 # two 1 6 # three 2 7 # Colorado one 3 8 # two 4 9 # three 5 10 print(df.unstack()) # side left right # number one two three one two three # state # Ohio 0 1 2 5 6 7 # Colorado 3 4 5 8 9 10 print(df.unstack('state')) # \u88ab\u62c6\u5806\u7684\u5c42\u7ea7(state)\u4f1a\u53d8\u4e3a\u7ed3\u679c\u4e2d\u6700\u4f4e\u7684\u5c42\u7ea7 # side left right # state Ohio Colorado Ohio Colorado # number # one 0 3 5 8 # two 1 4 6 9 # three 2 5 7 10 \u5728\u8c03\u7528 stack \u65b9\u6cd5\u65f6\uff0c\u53ef\u4ee5\u6307\u660e\u9700\u8981\u5806\u53e0\u7684\u8f74\u5411\u540d\u79f0\uff1a print(df.unstack('state').stack('side')) # state Colorado Ohio # number side # one left 3 0 # right 8 5 # two left 4 1 # right 9 6 # three left 5 2 # right 10 7","title":"\u4f7f\u7528\u591a\u5c42\u7d22\u5f15\u8fdb\u884c\u91cd\u5851"},{"location":"python/DataAnalysis/ch05/#_11","text":"\u5728\u6570\u636e\u5e93\u548cCSV\u4e2d\u5b58\u50a8\u591a\u65f6\u95f4\u5e8f\u5217\u7684\u65b9\u5f0f\u5c31\u662f\u6240\u8c13\u7684\u957f\u683c\u5f0f\u6216\u5806\u53e0\u683c\u5f0f\u3002 data = pd.read_csv('../examples/macrodata.csv') print(data.head(3)) # year quarter realgdp realcons ... unemp pop infl realint # 0 1959.0 1.0 2710.349 1707.4 ... 5.8 177.146 0.00 0.00 # 1 1959.0 2.0 2778.801 1733.7 ... 5.1 177.830 2.34 0.74 # 2 1959.0 3.0 2775.488 1751.8 ... 5.3 178.657 2.74 1.09 # ...... # [3 rows x 14 columns] # PeriodIndex\u5c06year\u548cquarter\u7b49\u5217\u8fdb\u884c\u8054\u5408\u5e76\u751f\u6210\u4e86\u4e00\u79cd\u65f6\u95f4\u95f4\u9694\u7c7b\u578b periods = pd.PeriodIndex( year=data.year, quarter=data.quarter, name='date' ) columns = pd.Index( ['realgdp', 'infl', 'unemp'], name='item' ) data = data.reindex(columns=columns) print(data) # item realgdp infl unemp # 0 2710.349 0.00 5.8 # 1 2778.801 2.34 5.1 # 2 2775.488 2.74 5.3 # ...... # [203 rows x 3 columns] data.index = periods.to_timestamp('D', 'end') print(data.index) # DatetimeIndex(['1959-03-31 23:59:59.999999999', # '1959-06-30 23:59:59.999999999', # ... # '2009-06-30 23:59:59.999999999', # '2009-09-30 23:59:59.999999999'], # dtype='datetime64[ns]', name='date', length=203, freq=None) \u4e0b\u9762\u662fldata\u7684\u6570\u636e\u6837\u672c\u3002 \u8fd9\u79cd\u6570\u636e\u5373\u6240\u8c13\u7684\u591a\u65f6\u95f4\u5e8f\u5217\u7684\u957f\u683c\u5f0f\uff0c\u6216\u79f0\u4e3a\u5177\u6709\u4e24\u4e2a\u6216\u66f4\u591a\u4e2a\u952e\u7684\u5176\u4ed6\u89c2\u6d4b\u6570\u636e\uff08\u8fd9\u91cc\uff0c\u6211\u4eec\u7684\u952e\u662fdate\u548citem\uff09\u3002 \u8868\u4e2d\u7684\u6bcf\u4e00\u884c\u8868\u793a\u4e00\u4e2a\u65f6\u95f4\u70b9\u4e0a\u7684\u5355\u4e2a\u89c2\u6d4b\u503c\u3002 ldata = data.stack().reset_index().rename(columns={0: 'value'}) print(ldata) # date item value # 0 1959-03-31 23:59:59.999999999 realgdp 2710.349 # 1 1959-03-31 23:59:59.999999999 infl 0.000 # 2 1959-03-31 23:59:59.999999999 unemp 5.800 # 3 1959-06-30 23:59:59.999999999 realgdp 2778.801 # 4 1959-06-30 23:59:59.999999999 infl 2.340 # .. ... ... ... # 604 2009-06-30 23:59:59.999999999 infl 3.370 # 605 2009-06-30 23:59:59.999999999 unemp 9.200 # 606 2009-09-30 23:59:59.999999999 realgdp 12990.341 # 607 2009-09-30 23:59:59.999999999 infl 3.560 # 608 2009-09-30 23:59:59.999999999 unemp 9.600 # [609 rows x 3 columns] \u5728\u4e0a\u9762\u7684\u4f8b\u5b50\u4e2d\uff1a \u6570\u636e\u901a\u5e38\u4ee5\u8fd9\u79cd\u65b9\u5f0f\u5b58\u50a8\u5728\u5173\u7cfb\u578b\u6570\u636e\u5e93\u4e2d\uff0c\u6bd4\u5982MySQL\uff0c\u56e0\u4e3a\u56fa\u5b9a\u6a21\u5f0f\uff08\u5217\u540d\u79f0\u548c\u6570\u636e\u7c7b\u578b\uff09\u5141\u8bb8 item \u5217\u4e2d\u4e0d\u540c\u503c\u7684\u6570\u91cf\u968f\u7740\u6570\u636e\u88ab\u6dfb\u52a0\u5230\u8868\u4e2d\u800c\u6539\u53d8\u3002 date \u548c item \u901a\u5e38\u662f\u4e3b\u952e\uff08\u4f7f\u7528\u5173\u7cfb\u578b\u6570\u636e\u5e93\u7684\u8bf4\u6cd5\uff09\uff0c\u63d0\u4f9b\u4e86\u5173\u7cfb\u5b8c\u6574\u6027\u548c\u66f4\u7b80\u5355\u7684\u8fde\u63a5\u3002 \u5728\u67d0\u4e9b\u60c5\u51b5\u4e0b\uff0c\u5904\u7406\u8fd9\u79cd\u683c\u5f0f\u7684\u6570\u636e\u66f4\u4e3a\u56f0\u96be\u3002\u53ef\u80fd\u66f4\u503e\u5411\u4e8e\u83b7\u53d6\u4e00\u4e2a\u6309 date \u5217\u65f6\u95f4\u6233\u7d22\u5f15\u7684\u4e14\u6bcf\u4e2a\u4e0d\u540c\u7684 item \u72ec\u7acb\u4e00\u5217\u7684DataFrame\u3002 DataFrame\u7684pivot\u65b9\u6cd5\u5c31\u662f\u8fdb\u884c\u8fd9\u79cd\u8f6c\u6362\u7684\uff1a \u4e0b\u9762\u4f8b\u5b50\u4e2d\uff0c\u4f20\u9012\u7684\u524d\u4e24\u4e2a\u503c\u662f\u5206\u522b\u7528\u4f5c\u884c\u548c\u5217\u7d22\u5f15\u7684\u5217\uff0c\u7136\u540e\u662f\u53ef\u9009\u7684\u6570\u503c\u5217\u4ee5\u586b\u5145DataFrame\u3002 \u6ce8\u610f\uff0c pivot \u65b9\u6cd5\u7b49\u4ef7\u4e8e\u4f7f\u7528 set_index \u521b\u5efa\u5206\u5c42\u7d22\u5f15\uff0c\u7136\u540e\u8c03\u7528unstack\u3002 pivoted = ldata.pivot('date', 'item', 'value') print(pivoted) # item infl realgdp unemp # date # 1959-03-31 23:59:59.999999999 0.00 2710.349 5.8 # 1959-06-30 23:59:59.999999999 2.34 2778.801 5.1 # ... ... ... ... # 2009-06-30 23:59:59.999999999 3.37 12901.504 9.2 # 2009-09-30 23:59:59.999999999 3.56 12990.341 9.6 # [203 rows x 3 columns] ldata['value2'] = np.random.randn(len(ldata)) print(ldata[:5]) # date item value value2 # 0 1959-03-31 23:59:59.999999999 realgdp 2710.349 -1.268405 # 1 1959-03-31 23:59:59.999999999 infl 0.000 0.377691 # 2 1959-03-31 23:59:59.999999999 unemp 5.800 -0.342492 # 3 1959-06-30 23:59:59.999999999 realgdp 2778.801 0.132797 # 4 1959-06-30 23:59:59.999999999 infl 2.340 0.180290 \u6b64\u65f6 ldata \u5df2\u7ecf\u6dfb\u52a0\u4e86\u4e00\u5217\u3002\u5982\u679c\u9057\u6f0f\u6700\u540e\u4e00\u4e2a\u53c2\u6570\uff0c\u4f1a\u5f97\u5230\u4e00\u4e2a\u542b\u6709\u591a\u5c42\u5217\u7684DataFrame\uff0c\u5982\u4e0b\uff1a pivoted = ldata.pivot('date', 'item') print(pivoted) # value ... value2 # item infl realgdp ... realgdp unemp # date ... # 1959-03-31 23:59:59.999999999 0.00 2710.349 ... 0.157467 -0.222464 # 1959-06-30 23:59:59.999999999 2.34 2778.801 ... 0.861501 0.368855 # ... ... ... ... ... ... # 2009-06-30 23:59:59.999999999 3.37 12901.504 ... 0.279988 0.934972 # 2009-09-30 23:59:59.999999999 3.56 12990.341 ... 0.547914 1.842967 # [203 rows x 6 columns] \u6ce8\u610f\uff0c pivot \u65b9\u6cd5\u7b49\u4ef7\u4e8e\u4f7f\u7528 set_index \u521b\u5efa\u5206\u5c42\u7d22\u5f15\uff0c\u7136\u540e\u8c03\u7528 unstack \u3002 unstacked = ldata.set_index(['date', 'item']).unstack('item') print(unstacked[:5]) # value ... value2 # item infl realgdp ... realgdp unemp # date ... # 1959-03-31 23:59:59.999999999 0.00 2710.349 ... 0.213120 -0.248004 # 1959-06-30 23:59:59.999999999 2.34 2778.801 ... 0.697763 0.112388 # 1959-09-30 23:59:59.999999999 2.74 2775.488 ... 1.291884 -1.046142 # 1959-12-31 23:59:59.999999999 0.27 2785.204 ... 0.363339 -0.307364 # 1960-03-31 23:59:59.999999999 2.31 2847.699 ... 0.377330 2.272980 # [5 rows x 6 columns]","title":"\u5c06\u201c\u957f\u201d\u900f\u89c6\u4e3a\u201c\u5bbd\u201d"},{"location":"python/DataAnalysis/ch05/#_12","text":"\u5728DataFrame\u4e2d\uff0cpivot\u65b9\u6cd5\u7684\u53cd\u64cd\u4f5c\u662f pandas.melt \u3002 \u4e0e\u5c06\u4e00\u5217\u53d8\u6362\u4e3a\u65b0\u7684DataFrame\u4e2d\u7684\u591a\u5217\u4e0d\u540c\uff0c\u5b83\u5c06\u591a\u5217\u5408\u5e76\u6210\u4e00\u5217\uff0c\u4ea7\u751f\u4e00\u4e2a\u65b0\u7684DataFrame\uff0c\u5176\u957f\u5ea6\u6bd4\u8f93\u5165\u66f4\u957f\u3002 df = pd.DataFrame( { 'key': ['foo', 'bar', 'baz'], 'A': [1, 2, 3], 'B': [4, 5, 6], 'C': [7, 8, 9] } ) print(df) # key A B C # 0 foo 1 4 7 # 1 bar 2 5 8 # 2 baz 3 6 9 key \u5217\u53ef\u4ee5\u4f5c\u4e3a\u5206\u7ec4\u6307\u6807\uff0c\u5176\u4ed6\u5217\u5747\u4e3a\u6570\u636e\u503c\u3002 \u5f53\u4f7f\u7528 pandas.melt \u65f6\uff0c\u6211\u4eec\u5fc5\u987b\u6307\u660e\u54ea\u4e9b\u5217\u662f\u5206\u7ec4\u6307\u6807\uff08\u5982\u679c\u6709\u7684\u8bdd\uff09\u3002 \u6b64\u5904\uff0c\u8ba9\u6211\u4eec\u4f7f\u7528 key \u4f5c\u4e3a\u552f\u4e00\u7684\u5206\u7ec4\u6307\u6807\uff1a melted = pd.melt(df, ['key']) print(melted) # key variable value # 0 foo A 1 # 1 bar A 2 # 2 baz A 3 # 3 foo B 4 # 4 bar B 5 # 5 baz B 6 # 6 foo C 7 # 7 bar C 8 # 8 baz C 9 \u4f7f\u7528 pivot \u65b9\u6cd5\uff0c\u6211\u4eec\u53ef\u4ee5\u5c06\u6570\u636e\u91cd\u5851\u56de\u539f\u5148\u7684\u5e03\u5c40\u3002 reshaped = melted.pivot('key', 'variable', 'value') print(reshaped) # variable A B C # key # bar 2 5 8 # baz 3 6 9 # foo 1 4 7 \u7531\u4e8e pivot \u7684\u7ed3\u679c\u6839\u636e\u4f5c\u4e3a\u884c\u6807\u7b7e\u7684\u5217\u751f\u6210\u4e86\u7d22\u5f15\uff0c\u53ef\u4f7f\u7528 reset_index \u6765\u5c06\u6570\u636e\u56de\u79fb\u4e00\u5217\uff1a print(reshaped.reset_index()) # variable key A B C # 0 bar 2 5 8 # 1 baz 3 6 9 # 2 foo 1 4 7 pandas.melt \u7684\u4f7f\u7528\u4e5f\u53ef\u4ee5\u65e0\u987b\u4efb\u4f55\u5206\u7ec4\u6307\u6807\u3002 result = pd.melt(df, value_vars=['A', 'B', 'C']) print(result) # variable value # 0 A 1 # 1 A 2 # 2 A 3 # 3 B 4 # 4 B 5 # 5 B 6 # 6 C 7 # 7 C 8 # 8 C 9 result = pd.melt(df, value_vars=['key', 'B', 'C']) print(result) # variable value # 0 key foo # 1 key bar # 2 key baz # 3 B 4 # 4 B 5 # 5 B 6 # 6 C 7 # 7 C 8 # 8 C 9","title":"\u5c06\u201c\u5bbd\u201d\u900f\u89c6\u4e3a\u201c\u957f\u201d"},{"location":"python/DataAnalysis/ch06/","text":"\u7ed8\u56fe\u4e0e\u53ef\u89c6\u5316 \u00b6 \u7b80\u660ematplotlib API\u5165\u95e8 \u00b6 import matplotlib as mpl import matplotlib.pyplot as plt import numpy as np import pandas as pd from io import BytesIO \u6267\u884c plt.show() \u65f6\u62a5\u9519\uff1a UserWarning: Matplotlib is currently using agg, which is a non-GUI backend, so cannot show the figure. \u6267\u884c\u4e0b\u9762\u547d\u4ee4\uff0c\u5f97\u5230 plt \u7684 backend \u662f\u7528 agg \u3002 plt.get_backend() \u4f8b\u5982\uff1a\u4e0b\u9762\u4e24\u79cd\u8868\u8fbe\u65b9\u5f0f\u6548\u679c\u4e00\u6837\u3002 ax.plot(x, y, 'g--') ax.plot(x, y, linestyle='--', color='g') Out[6]: 'agg' \u5b89\u88c5\u4e0b\u9762\u51e0\u4e2a\u5305\uff1a sudo zypper in python-tk python3-tk sudo zypper in plplot-tcltk-devel plplot-tcltk-libs pip install tk \u6dfb\u52a0\u4e0b\u9762\u5230python\u4ee3\u7801\u4e2d\u3002 import matplotlib.pyplot as plt mpl.use('TkAgg') \u6267\u884c\u540e\u62a5\u4e0b\u9762\u9519\u8bef\uff1a your Python may not be configured for Tk \u8fdb\u5165python\u6e90\u7801\u76ee\u5f55\uff0c\u91cd\u65b0\u7f16\u8bd1\u4f8b\u5982\uff1a\u4e0b\u9762\u4e24\u79cd\u8868\u8fbe\u65b9\u5f0f\u6548\u679c\u4e00\u6837\u3002 ax.plot(x, y, 'g--') ax.plot(x, y, linestyle='--', color='g') james@lizard:/opt/Python-3.9.6> sudo make james@lizard:/opt/Python-3.9.6> sudo make install \u95ee\u9898\u89e3\u51b3\uff0c\u5373\u4f7f\u4e0d\u52a0\u5165 mpl.use('TkAgg') \uff0c\u6267\u884c plt.show() \u4e5f\u662f\u53ef\u4ee5\u8f93\u51fa\u56fe\u50cf\u3002 \u56fe\u7247\u4e0e\u5b50\u56fe \u00b6 matplotlib \u6240\u7ed8\u5236\u7684\u56fe\u4f4d\u4e8e\u56fe\u7247\uff08Figure\uff09\u5bf9\u8c61\u4e2d\u3002\u53ef\u4ee5\u4f7f\u7528 plt.figure \u751f\u6210\u4e00\u4e2a\u65b0\u7684\u56fe\u7247\u3002 \u4f7f\u7528 add_subplot \u521b\u5efa\u4e00\u4e2a\u6216\u591a\u4e2a\u5b50\u56fe\uff08subplot\uff09\u3002 plt \u4e0e ax \u7ed8\u56fe\u3002 fig = plt.figure() # plt: \u5148\u751f\u6210\u4e86\u4e00\u4e2a\u753b\u5e03\uff0c\u7136\u540e\u5728\u8fd9\u4e2a\u753b\u5e03\u4e0a\u9690\u5f0f\u7684\u751f\u6210\u4e00\u4e2a\u753b\u56fe\u533a\u57df\u6765\u8fdb\u884c\u753b\u56fe # plt.plot([1, 2, 3, 4]) # plt.show() # ax: \u5148\u751f\u6210\u4e00\u4e2a\u753b\u5e03\uff082\u00d72\u7684\u533a\u57df\uff0c\u6700\u591a\u653e\u56db\u4e2a\u56fe\u5f62\uff09\uff0c\u7136\u540e\u5728\u6b64\u753b\u5e03\u4e0a\uff0c\u9009\u5b9a\u4e00\u4e2a\u5b50\u533a\u57df\u753b\u4e86\u4e00\u4e2a\u5b50\u56fe\uff08\u5e8f\u53f71\u4ee3\u8868\u7b2c\u4e00\u4e2a\u533a\u57df\uff09 ax1 = fig.add_subplot(2, 2, 1) # \u4e5f\u53ef\u4ee5\u5199\u6210fig.add_subplot(221) ax1.plot([1, 2, 3, 4], [1, 4, 3, 2]) # \u8f93\u51fa\u56fe\u7247\u5230\u7b2c\u4e00\u4e2a\u533a\u57df\u3002 # \u7b2c\u4e00\u4e2a\u53c2\u6570\u662f\u6570\u636e\u96c6\u91cc\u5404\u4e2a\u6570\u636e\u70b9\u7684X\u503c\u7684\u96c6\u5408 # \u7b2c\u4e8c\u4e2a\u53c2\u6570\u6570\u636e\u96c6\u91cc\u5404\u4e2a\u6570\u636e\u70b9\u7684Y\u503c\u7684\u96c6\u5408\u3002 # \u4e0d\u662f\u6570\u5b66\u4e0a\u5e38\u89c1\u7684\u6210\u5bf9\u5750\u6807\u70b9\u5982(x1,y1)\u3001(x2,y2)\u3001...\u3001(xn,yn)\u7684\u683c\u5f0f\uff0c\u800c\u662f (x1,x2,...,xn)\u548c(y1,y2,...,yn) \u3002 plt.show() \u770b\u4e0b\u9762\u4f8b\u5b50\uff0c\u589e\u52a0\u5b50\u56fe\u540e\u7684\u6570\u636e\u53ef\u89c6\u5316\u6548\u679c\u3002 fig = plt.figure() ax1 = fig.add_subplot(2, 2, 1) ax2 = fig.add_subplot(2, 2, 2) ax3 = fig.add_subplot(2, 2, 3) ax1.plot(np.random.randn(50).cumsum(), 'k--') # \u5728\u7b2c\u4e09\u4e2a\u533a\u57df\u8f93\u51fa\u56fe\u50cf\u3002'k--\u2019\u662f\u7528\u4e8e\u7ed8\u5236\u9ed1\u8272\u5206\u6bb5\u7ebf\u7684style\u9009\u9879\u3002 ax2.hist(np.random.randn(100), bins=20, color='k', alpha=0.3) ax3.scatter(np.arange(30), np.arange(30) + 3 * np.random.randn(30)) plt.show() plt.subplots \u901a\u8fc7 matplotlib \u7684 subplots \u65b9\u6cd5\uff0c\u4f7f\u7528\u5b50\u56fe\u7f51\u683c\u521b\u5efa\u56fe\u7247\uff0c\u7136\u540e\u8fd4\u56de\u5305\u542b\u4e86\u5df2\u751f\u6210\u5b50\u56fe\u5bf9\u8c61\u7684NumPy\u6570\u7ec4\u3002 \u6570\u7ec4 axes \u53ef\u4ee5\u50cf\u4e8c\u7ef4\u6570\u7ec4\u90a3\u6837\u65b9\u4fbf\u5730\u8fdb\u884c\u7d22\u5f15\uff0c\u4f8b\u5982\uff0c axes[0, 1] \u3002 plt.subplots \u53c2\u6570\u9009\u9879\uff1a nrows\uff1a\u53ef\u9009\u7684\uff0c\u6574\u578b\uff0c\u9ed8\u8ba4\u4e3a1\u3002\u5b50\u56fe\u7f51\u683c\u7684\u884c\u6570\u3002 ncols\uff1a\u53ef\u9009\u7684\uff0c\u6574\u578b\uff0c\u9ed8\u8ba4\u4e3a1\u3002\u5b50\u56fe\u7f51\u683c\u7684\u5217\u6570\u3002 sharex\uff1a\u53ef\u9009\u7684\uff0c\u9ed8\u8ba4\u4e3aFalse\u3002\u53ef\u9009\u503c\u5982\u4e0b\uff1a True\u6216all\uff0c\u6240\u6709\u5b50\u56fe\u5171\u4eabx\u8f74 False\u6216none\uff0c\u6bcf\u4e2a\u5b50\u56fe\u7684x\u8f74\u90fd\u662f\u72ec\u7acb\u7684 row\uff0c\u6bcf\u884c\u5b50\u56fe\u5171\u4eab\u4e00\u4e2ax\u8f74 col\uff0c\u6bcf\u5217\u5b50\u56fe\u5171\u4eab\u4e00\u4e2ax\u8f74 sharey\uff1a\u7c7b\u4f3c\u4e8esharex\uff0c\u8bbe\u7f6ey\u8f74\u7684\u5171\u4eab\u65b9\u5f0f\u3002\u5f53\u67d0\u5217\u5171\u4eab\u4e00\u4e2ax\u8f74\u65f6\uff0c\u53ea\u6709\u5e95\u90e8\u7684\u5b50\u56fe\u4f1a\u521b\u5efax\u8f74\u6807\u8bb0\u3002\u540c\u6837\u7684\uff0c\u5982\u679c\u67d0\u884c\u5171\u4eab\u4e00\u4e2ay\u8f74\u65f6\uff0c\u53ea\u6709\u884c\u7684\u7b2c\u4e00\u5217\u5b50\u56fe\u4f1a\u521b\u5efay\u8f74\u6807\u8bb0\u3002 squeeze \uff1a\u53ef\u9009\u7684\uff0c\u5e03\u5c14\u578b\uff0c\u9ed8\u8ba4\u4e3aTrue\u3002\u662f\u5426\u538b\u7f29\u8fd4\u56de\u7684Axes\u6570\u7ec4\u3002\u5982\u679c\u4e3aTrue\uff0c\u5f53\u53ea\u6709\u4e00\u4e2a\u5b50\u56fe\uff0c\u5373nrows\u548cncols\u5747\u4e3a1\u65f6\uff0c\u8fd4\u56de\u4e00\u4e2a\u5355\u72ec\u7684Axes\u5bf9\u8c61\uff0c\u5f53\u6709N*1\u548c1*M\u4e2a\u5b50\u56fe\u65f6\uff0c\u8fd4\u56de\u4e00\u4e2a\u4e00\u7ef4Axes\u5bf9\u8c61\u6570\u7ec4\u3002\u5f53\u6709N*M\u4e2a\u5b50\u56fe\uff08N>1\uff0cM>1\uff09\u65f6\uff0c\u8fd4\u56de\u4e8c\u7ef4\u6570\u7ec4\u3002\u5982\u679c\u4e3aFalse\uff0c\u5219\u603b\u662f\u8fd4\u56de\u4e8c\u7ef4\u6570\u7ec4\u3002 num\uff1a\u53ef\u9009\u7684\uff0c\u6574\u578b\u6216\u5b57\u7b26\u4e32\uff0c\u9ed8\u8ba4\u4e3aNone\u3002\u662fmatplotlib.pyplot.figure\u7684\u5173\u952e\u5b57\uff0c\u7528\u4e8e\u8bbe\u7f6e\u56fe\u50cf\u6570\u5b57\u6216\u6807\u7b7e\u3002\u5982\u679c\u672a\u8bbe\u7f6e\u6b64\u53c2\u6570\uff0c\u4f1a\u521b\u5efa\u4e00\u4e2a\u65b0\u7684\u56fe\u50cf\uff0c\u5e76\u9012\u589e\u56fe\u50cf\u7f16\u53f7\uff0cfigure\u5bf9\u8c61\u4f1a\u5c06\u7f16\u53f7\u4fdd\u5b58\u5728number\u5c5e\u6027\u4e2d\u3002\u5982\u679c\u8bbe\u7f6e\u4e86\u6b64\u53c2\u6570\uff0c\u5e76\u4e14\u5b58\u5728\u53c2\u6570\u6307\u5b9a\u7684\u56fe\u50cf\uff0c\u5219\u4f1a\u8fd4\u56de\u6b64\u56fe\u50cf\u7684\u5f15\u7528\uff0c\u5982\u679c\u4e0d\u5b58\u5728\u5219\u4f1a\u521b\u5efa\u65b0\u7684\u56fe\u50cf\u5e76\u8fd4\u56de\u5b83\u7684\u5f15\u7528\u3002\u5982\u679c\u662f\u5b57\u7b26\u4e32\uff0c\u5219\u7a97\u53e3\u6807\u9898\u4f1a\u88ab\u8bbe\u7f6e\u4e3a\u6b64\u5b57\u7b26\u4e32\u7684\u503c\u3002 subplot_kw\uff1a\u53ef\u9009\u7684\uff0c\u5b57\u5178\u7c7b\u578b\u3002\u5305\u542b\u4f20\u9012\u7ed9\u7528\u4e8e\u521b\u5efa\u5b50\u56fe\u7684\u8c03\u7528add_subplot\u7684\u5173\u952e\u5b57\u53c2\u6570\u3002 gridspec_kw\uff1a\u53ef\u9009\u7684\uff0c\u5b57\u5178\u7c7b\u578b\u3002\u5305\u542b\u4f20\u9012\u7ed9\u7528\u4e8e\u521b\u5efa\u5b50\u56fe\u7f51\u683c\u7684GridSpec\u6784\u9020\u51fd\u6570\u7684\u5173\u952e\u5b57\u53c2\u6570\u3002 fig, axes = plt.subplots(2, 3) print(axes) # \u5c06\u751f\u6210\u7684axes\u5bf9\u8c61\u653e\u5165NumPy\u6570\u7ec4\u3002 # [[ ] # [ ]] \u8c03\u6574\u5b50\u56fe\u5468\u56f4\u7684\u95f4\u8ddd\u3002 \u9ed8\u8ba4\u60c5\u51b5\u4e0b\uff0c matplotlib \u4f1a\u5728\u5b50\u56fe\u7684\u5916\u90e8\u548c\u5b50\u56fe\u4e4b\u95f4\u7559\u51fa\u4e00\u5b9a\u7684\u95f4\u8ddd\u3002 \u8fd9\u4e2a\u95f4\u8ddd\u90fd\u662f\u76f8\u5bf9\u4e8e\u56fe\u7684\u9ad8\u5ea6\u548c\u5bbd\u5ea6\u6765\u6307\u5b9a\u7684\uff0c\u624b\u52a8\u8c03\u6574\u56fe\u7684\u5927\u5c0f\uff0c\u90a3\u4e48\u95f4\u8ddd\u4f1a\u81ea\u52a8\u8c03\u6574\u3002 \u4e5f\u53ef\u4ee5\u4f7f\u7528\u56fe\u5bf9\u8c61\u4e0a\u7684 subplots_adjust \u65b9\u6cd5\u66f4\u6539\u95f4\u8ddd\uff0c\u4e5f\u53ef\u4ee5\u7528\u4f5c\u9876\u5c42\u51fd\u6570\u3002 fig, axes = plt.subplots(2, 2, sharex=True, sharey=True) for i in range(2): for j in range(2): axes[i, j].hist(np.random.randn(500), bins=50, color='k', alpha=0.5) plt.subplots_adjust(wspace=0, hspace=0) plt.show() \u4e0a\u9762\u8f93\u51fa\u56fe\u50cf\u7684\u8f74\u6807\u7b7e\u662f\u5b58\u5728\u91cd\u53e0\u7684\u3002 matplotlib \u5e76\u4e0d\u68c0\u67e5\u6807\u7b7e\u662f\u5426\u91cd\u53e0\uff0c\u56e0\u6b64\u5728\u7c7b\u4f3c\u60c5\u51b5\u4e0b\u4f60\u9700\u8981\u901a\u8fc7\u663e\u5f0f\u6307\u5b9a\u523b\u5ea6\u4f4d\u7f6e\u548c\u523b\u5ea6\u6807\u7b7e\u7684\u65b9\u6cd5\u6765\u4fee\u590d\u8f74\u6807\u7b7e\u3002 \u989c\u8272\u3001\u6807\u8bb0\u548c\u7ebf\u7c7b\u578b \u00b6 matplotlib \u7684\u4e3b\u51fd\u6570 plot \u63a5\u6536\u5e26\u6709 x \u548c y \u8f74\u7684\u6570\u7ec4\u4ee5\u53ca\u4e00\u4e9b\u53ef\u9009\u7684\u5b57\u7b26\u4e32\u7f29\u5199\u53c2\u6570\u6765\u6307\u660e\u989c\u8272\u548c\u7ebf\u7c7b\u578b\u3002 \u4f8b\u5982\uff1a\u4e0b\u9762\u4e24\u79cd\u8868\u8fbe\u65b9\u5f0f\u6548\u679c\u4e00\u6837\u3002 ax.plot(x, y, 'g--') ax.plot(x, y, linestyle='--', color='g') data = np.random.randn(30).cumsum() plt.plot(data, 'ko--') plt.show() # \u4e0a\u9762\u7684\u4ee3\u7801\u53ef\u4ee5\u5199\u5f97\u66f4\u4e3a\u663e\u5f0f\uff1a plt.plot(data, color='k', linestyle='dashed', marker='o') plt.show() plt.plot(data, color='k', linestyle='dashed', marker='o', label='Default') plt.show() plt.plot(data, color='k', linestyle='dashed', marker='o', label='steps-post', drawstyle='steps-post') plt.show() \u523b\u5ea6\u3001\u6807\u7b7e\u548c\u56fe\u4f8b \u00b6 \u5bf9\u4e8e\u5927\u591a\u6570\u56fe\u8868\u4fee\u9970\u5de5\u4f5c\uff0c\u6709\u4e24\u79cd\u4e3b\u8981\u7684\u65b9\u5f0f\uff1a\u4f7f\u7528\u7a0b\u5e8f\u6027\u7684pyplot\u63a5\u53e3\uff08\u5373matplotlib.pyplot\uff09\u548c\u66f4\u591a\u9762\u5411\u5bf9\u8c61\u7684\u539f\u751fmatplotlib API\u3002 pyplot \u63a5\u53e3\u8bbe\u8ba1\u4e3a\u4ea4\u4e92\u5f0f\u4f7f\u7528\uff0c\u5305\u542b\u4e86\u50cf xlim \u3001 xticks \u548c xticklabels \u7b49\u65b9\u6cd5\u3002\u8fd9\u4e9b\u65b9\u6cd5\u5206\u522b\u63a7\u5236\u4e86\u7ed8\u56fe\u8303\u56f4\u3001\u523b\u5ea6\u4f4d\u7f6e\u4ee5\u53ca\u523b\u5ea6\u6807\u7b7e\u3002 \u5728\u6ca1\u6709\u51fd\u6570\u53c2\u6570\u7684\u60c5\u51b5\u4e0b\u8c03\u7528\uff0c\u8fd4\u56de\u5f53\u524d\u7684\u53c2\u6570\u503c\uff08\u4f8b\u5982 plt.xlim() \u8fd4\u56de\u5f53\u524d\u7684x\u8f74\u7ed8\u56fe\u8303\u56f4\uff09\u3002 \u4f20\u5165\u53c2\u6570\u7684\u60c5\u51b5\u4e0b\u8c03\u7528\uff0c\u5e76\u8bbe\u7f6e\u53c2\u6570\u503c\uff08\u4f8b\u5982 plt.xlim\uff08[0, 10]\uff09 \u4f1a\u5c06 x \u8f74\u7684\u8303\u56f4\u8bbe\u7f6e\u4e3a0\u523010\uff09\u3002 \u6240\u6709\u7684\u8fd9\u4e9b\u65b9\u6cd5\u90fd\u4f1a\u5728\u5f53\u524d\u6d3b\u52a8\u7684\u6216\u6700\u8fd1\u521b\u5efa\u7684 AxesSubplot \u4e0a\u751f\u6548\u3002 \u8fd9\u4e9b\u65b9\u6cd5\u4e2d\u7684\u6bcf\u4e00\u4e2a\u5bf9\u5e94\u4e8e\u5b50\u56fe\u81ea\u8eab\u7684\u4e24\u4e2a\u65b9\u6cd5\u3002\u6bd4\u5982 xlim \u5bf9\u5e94\u4e8e ax.get_lim \u548c ax.set_lim \u3002 \u63a8\u8350\u4f7f\u7528 subplot \u7684\u5b9e\u4f8b\u65b9\u6cd5\uff0c\u56e0\u4e3a\u8fd9\u6837\u66f4\u4e3a\u663e\u5f0f\uff08\u5c24\u5176\u662f\u5728\u5904\u7406\u591a\u4e2a\u5b50\u56fe\u65f6\uff09\u3002 data = np.random.randn(1000).cumsum() fig = plt.figure() # \u8bbe\u5b9a\u5b50\u56fe ax = fig.add_subplot(1, 1, 1) # \u8bbe\u5b9ax\u8f74\u5bf9\u5e94\u53c2\u6570\uff1a # \u8bbe\u5b9ax\u8f74\u523b\u5ea6 ax.set_xticks([0, 250, 500, 750, 1000]) # \u8bbe\u5b9ax\u8f74\u6807\u7b7e ax.set_xticklabels(['one(0)', 'two(250)', 'three(500)', 'four(750)', 'five(1000)'], rotation=30, fontsize='small') # \u7ed9x\u8f74\u4e00\u4e2a\u540d\u79f0 ax.set_xlabel('Stages') # \u8bbe\u5b9ay\u8f74\u5bf9\u5e94\u53c2\u6570\uff1a # \u672a\u6307\u5b9a\u7684\u53c2\u6570\u7531\u7cfb\u7edf\u9ed8\u8ba4\u4ea7\u751f\u3002 ax.set_ylabel('Steps') # \u7ed9\u5b50\u56fe\u6dfb\u52a0\u4e00\u4e2a\u6807\u9898 ax.set_title('My first matplotlib plot') # \u7ed9\u5b50\u56fe\u6dfb\u52a0\u4e00\u4e2a\u56fe\u4f8b\uff08\u5982\uff1a\u7ed9\u5b50\u56fe\u5185\u4e00\u4e2a\u56fe\u5f62\u66f2\u7ebf\u6dfb\u52a0\u4e00\u4e2alabel\uff09 ax.plot(data, 'k--', label='Label One') # loc\u53c2\u6570\u544a\u8bc9matplotlib\u5728\u54ea\u91cc\u653e\u7f6e\u56fe\u8868\u3002legend\u65b9\u6cd5\u6709\u591a\u4e2a\u5176\u4ed6\u7684\u4f4d\u7f6e\u53c2\u6570loc\u3002 ax.legend(loc='best') # \u6216\u8005plt.legend(loc='best') \u3002 # \u5728\u56fe\u5f62\u5750\u6807\u4e3a(0, 0)\u7684\u4f4d\u7f6e\u6dfb\u52a0\u4e00\u4e2alable ax.text(0, 0, 'Hello World1', family='monospace', fontsize=10) # \u7ed9\u5b50\u56fe\u6dfb\u52a0annotate\u3002\u7528\u4e00\u4e2a\u7bad\u5934\u6307\u5411\u8981\u6ce8\u91ca\u7684\u5730\u65b9\uff0c\u518d\u5199\u4e0a\u4e00\u6bb5\u8bdd\u7684\u884c\u4e3a\uff0c\u53eb\u505aannotate\u3002 # * s: \u6ce8\u91ca\u7684\u5185\u5bb9\uff0c\u4e00\u6bb5\u6587\u5b57\uff1b # * xytext: \u8fd9\u6bb5\u6587\u5b57\u6240\u5904\u7684\u4f4d\u7f6e; # * xy: \u7bad\u5934\u6307\u5411\u7684\u4f4d\u7f6e\uff1b # * arrowprops: \u901a\u8fc7arrowstyle\u8868\u660e\u7bad\u5934\u7684\u98ce\u683c\u6216\u79cd\u7c7b\u3002 ax.annotate('Zero is here!', xytext=(20, 20), xy=(1, 1), arrowprops=dict(arrowstyle='->')) # \u7ed9\u5b50\u56fe\u6dfb\u52a0\u4e00\u4e9b\u56fe\u5f62 # matplotlib\u542b\u6709\u8868\u793a\u591a\u79cd\u5e38\u89c1\u56fe\u5f62\u7684\u5bf9\u8c61\uff0c\u8fd9\u4e9b\u5bf9\u8c61\u7684\u5f15\u7528\u662fpatches\u3002 # \u4e00\u4e9b\u56fe\u5f62\uff0c\u6bd4\u5982Rectangle\uff08\u77e9\u5f62\uff09\u548cCircle\uff08\u5706\u5f62\uff09\uff0c\u53ef\u4ee5\u5728matplotlib.pyplot\u4e2d\u627e\u5230\uff0c\u4f46\u56fe\u5f62\u7684\u5168\u96c6\u4f4d\u4e8ematplotlib.patches\u3002 rect = plt.Rectangle((10, 5), 100, 15, color='k', alpha=0.3) circ = plt.Circle((200, 9), 95, color='b', alpha=0.3) pgon = plt.Polygon([[500, 5], [600, -5], [700, 30]], color='g', alpha=0.5) ax.add_patch(rect) ax.add_patch(circ) ax.add_patch(pgon) # \u5c06\u56fe\u7247\u4fdd\u5b58\u5230\u6587\u4ef6 # \u6587\u4ef6\u7c7b\u578b\u662f\u4ece\u6587\u4ef6\u6269\u5c55\u540d\u4e2d\u63a8\u65ad\u51fa\u6765\u7684\u3002\u6240\u4ee5\u5982\u679c\u4f60\u4f7f\u7528\uff0epdf\uff0c\u5219\u4f1a\u5f97\u5230\u4e00\u4e2aPDF\u3002 # \u51e0\u4e2a\u91cd\u8981\u7684\u9009\u9879\uff1adpi\uff0c\u5b83\u63a7\u5236\u6bcf\u82f1\u5bf8\u70b9\u6570\u7684\u5206\u8fa8\u7387\uff1bbbox_inches\uff0c\u53ef\u4ee5\u4fee\u526a\u5b9e\u9645\u56fe\u5f62\u7684\u7a7a\u767d\u3002 plt.savefig('../examples/figpath.png', dpi=400, bbox_inches='tight') # saveifg\u5e76\u975e\u4e00\u5b9a\u662f\u5199\u5230\u786c\u76d8\u7684\uff0c\u5b83\u53ef\u4ee5\u5c06\u56fe\u7247\u5199\u5165\u5230\u6240\u6709\u7684\u6587\u4ef6\u578b\u5bf9\u8c61\u4e2d\uff0c\u4f8b\u5982BytesIO buffer = BytesIO() plt.savefig(buffer) plot_data = buffer.getvalue() plt.show() matplotlib\u8bbe\u7f6e \u00b6 matplotlib \u914d\u7f6e\u4e86\u914d\u8272\u65b9\u6848\u548c\u9ed8\u8ba4\u8bbe\u7f6e\uff0c\u901a\u8fc7\u5168\u5c40\u53c2\u6570\u6765\u5b9a\u5236\uff0c\u5305\u62ec\u56fe\u5f62\u5927\u5c0f\u3001\u5b50\u56fe\u95f4\u8ddd\u3001\u989c\u8272\u3001\u5b57\u4f53\u5927\u5c0f\u548c\u7f51\u683c\u6837\u5f0f\u7b49\u7b49\u3002 \u4f7f\u7528 rc \u65b9\u6cd5\u662f\u4f7f\u7528Python\u7f16\u7a0b\u4fee\u6539\u914d\u7f6e\u7684\u4e00\u79cd\u65b9\u5f0f\u3002 rc \u7684\u7b2c\u4e00\u4e2a\u53c2\u6570\u662f\u4f60\u60f3\u8981\u81ea\u5b9a\u4e49\u7684\u7ec4\u4ef6\uff0c\u6bd4\u5982 'figure'\u3001'axes'\u3001'xtick'\u3001'ytick'\u3001'grid'\u3001'legend' \u7b49\u7b49\u3002 \u4e4b\u540e\uff0c\u53ef\u4ee5\u6309\u7167\u5173\u952e\u5b57\u53c2\u6570\u7684\u5e8f\u5217\u6307\u5b9a\u65b0\u53c2\u6570\u3002 \u5b57\u5178\u662f\u4e00\u79cd\u5728\u7a0b\u5e8f\u4e2d\u8bbe\u7f6e\u9009\u9879\u7684\u7b80\u5355\u65b9\u5f0f\u3002\u6bd4\u5982\uff1a plt.rc('figure', figsize=(10, 10)) font_options = { 'family': 'monospace', 'weight': 'bold', 'size': 'small' } plt.rc('font', **font_options) \u4f7f\u7528pandas\u548cseaborn\u7ed8\u56fe \u00b6 pandas\u81ea\u8eab\u6709\u5f88\u591a\u5185\u5efa\u65b9\u6cd5\u53ef\u4ee5\u7b80\u5316\u4eceDataFrame\u548cSeries\u5bf9\u8c61\u751f\u6210\u53ef\u89c6\u5316\u7684\u8fc7\u7a0b\u3002 \u53e6\u4e00\u4e2a\u5e93\u662f seaborn \u3002 seaborn \u7b80\u5316\u4e86\u5f88\u591a\u5e38\u7528\u53ef\u89c6\u5316\u7c7b\u578b\u7684\u751f\u6210\u3002 \u5bfc\u5165 seaborn \u4f1a\u4fee\u6539\u9ed8\u8ba4\u7684matplotlib\u914d\u8272\u65b9\u6848\u548c\u7ed8\u56fe\u6837\u5f0f\uff0c\u8fd9\u4f1a\u63d0\u9ad8\u56fe\u8868\u7684\u53ef\u8bfb\u6027\u548c\u7f8e\u89c2\u6027\u3002 \u5373\u4f7f\u4e0d\u4f7f\u7528seaborn\u7684API\uff0c\u4e5f\u53ef\u4ee5\u5bfc\u5165seaborn\u6765\u4e3a\u901a\u7528matplotlib\u56fe\u8868\u63d0\u4f9b\u66f4\u597d\u7684\u89c6\u89c9\u7f8e\u89c2\u5ea6\u3002 import pandas as pd import numpy as np import matplotlib.pyplot as plt import seaborn as sns \u6298\u7ebf\u56fe \u00b6 Series\u548cDataFrame\u90fd\u6709\u4e00\u4e2a plot \u5c5e\u6027\uff0c\u7528\u4e8e\u7ed8\u5236\u57fa\u672c\u7684\u56fe\u5f62\u3002\u9ed8\u8ba4\u60c5\u51b5\u4e0b\uff0c plot() \u7ed8\u5236\u7684\u662f\u6298\u7ebf\u56fe\u3002 Series\u7684 plot \u53c2\u6570\uff1a ax: matplotlib\u5b50\u56fe\u5bf9\u8c61axes\uff0c\u5982\u679c\u6ca1\u6709\u4f20\u503c\uff0c\u5219\u4f7f\u7528\u5f53\u524d\u6d3b\u52a8\u7684\u5b50\u56fe\u9ed8\u8ba4\u4f7f\u7528gca() alpha: \u56fe\u7247\u4e0d\u900f\u660e\u5ea6\uff080\u52301\uff09 data: \u6570\u636e\u5e8f\u5217Series figsize: \u56fe\u50cf\u5c3a\u5bf8\uff0ctuple(\u5bbd\u5ea6\uff0c\u9ad8\u5ea6)\uff0c\u6ce8\u610f\u8fd9\u91cc\u7684\u5355\u4f4d\u662f\u82f1\u5bf8 fontsize: \u8bbe\u7f6e\u523b\u5ea6\u6807\u7b7e\uff08xticks, yticks\uff09\u7684\u5927\u5c0f grid: \u7f51\u683c\u7ebf\uff08\u9ed8\u8ba4\u662f\u6253\u5f00\u7684\uff09 kind: \u56fe\u7c7b\u578b\uff1a\u6298\u7ebf\u56fe\uff0c\u67f1\u5f62\u56fe\uff0c\u6a2a\u5411\u67f1\u5f62\u56fe\uff0c\u76f4\u65b9\u56fe\uff0c\u7bb1\u7ebf\u56fe\uff0c\u5bc6\u5ea6\u56fe\uff0c\u9762\u79ef\u56fe\uff0c\u997c\u56fe label: \u5217\u7684\u522b\u540d\uff0c\u4f5c\u7528\u5728\u56fe\u4f8b\u4e0a legend: \u56fe\u4f8b loglog: x,y\u8f74\u90fd\u4f7f\u7528\u5bf9\u6570\u523b\u5ea6 logx: x\u8f74\u4f7f\u7528\u5bf9\u6570\u523b\u5ea6 logy: y\u8f74\u4f7f\u7528\u5bf9\u6570\u523b\u5ea6 mark_right: \u53cc y \u8f74\u65f6\uff0c\u5728\u56fe\u4f8b\u4e2d\u7684\u5217\u6807\u7b7e\u65c1\u589e\u52a0\u663e\u793a (right) \u6807\u8bc6 position: \u67f1\u5f62\u56fe\u7684\u67f1\u5b50\u7684\u4f4d\u7f6e\u8bbe\u7f6e rot: \u6539\u53d8\u523b\u5ea6\u6807\u7b7e\uff08xticks, yticks\uff09\u7684\u65cb\u8f6c\u5ea6\uff080\u5230360\uff09 secondary_y: \u53cc y \u8f74\uff0c\u5728\u53f3\u8fb9\u7684\u7b2c\u4e8c\u4e2a y \u8f74 style: \u7ebf\u7684\u6837\u5f0f\uff0c\u6bd4\u5982'ko--' table: \u5c06\u6570\u636e\u4ee5\u8868\u683c\u7684\u5f62\u5f0f\u5c55\u793a\u51fa\u6765 title: \u6807\u9898 use_index: \u662f\u5426\u4f7f\u7528\u7d22\u5f15\u4f5c\u4e3ax\u523b\u5ea6\u6807\u7b7e xerr: \u5e26\u8bef\u5dee\u7ebf\u7684\u67f1\u5f62\u56fe xlim: \u6a2a\u8f74\u5750\u6807\u523b\u5ea6\u7684\u53d6\u503c\u8303\u56f4 xticks: x\u8f74\u523b\u5ea6\u6807\u7b7e yerr: \u5e26\u8bef\u5dee\u7ebf\u7684\u67f1\u5f62\u56fe ylim: \u7eb5\u8f74\u5750\u6807\u523b\u5ea6\u7684\u53d6\u503c\u8303\u56f4 yticks: y\u8f74\u523b\u5ea6\u6807\u7b7e **kwds: matplotlib plot\u65b9\u6cd5\u7684\u5176\u4ed6\u53c2\u6570 DataFrame\u7684 plot \u53c2\u6570\uff1a x : \u6307\u6570\u636e\u6846\u5217\u7684\u6807\u7b7e\u6216\u4f4d\u7f6e\u53c2\u6570 y : \u6307\u6570\u636e\u6846\u5217\u7684\u6807\u7b7e\u6216\u4f4d\u7f6e\u53c2\u6570 kind : 'line' : \u6298\u7ebf\u56fe 'bar' : \u6761\u5f62\u56fe 'barh' : \u6a2a\u5411\u6761\u5f62\u56fe 'hist' : \u67f1\u72b6\u56fe 'box' : \u7bb1\u7ebf\u56fe 'kde' : Kernel\u7684\u5bc6\u5ea6\u4f30\u8ba1\u56fe\uff0c\u4e3b\u8981\u5bf9\u67f1\u72b6\u56fe\u6dfb\u52a0Kernel \u6982\u7387\u5bc6\u5ea6\u7ebf 'density' : 'kde' 'area' : area plot 'pie' : \u997c\u56fe 'scatter' : \u6563\u70b9\u56fe \u9700\u8981\u4f20\u5165columns\u65b9\u5411\u7684\u7d22\u5f15 'hexbin' : hexbin plot ax : \u5b50\u56fe(axes, \u4e5f\u53ef\u4ee5\u7406\u89e3\u6210\u5750\u6807\u8f74) \u8981\u5728\u5176\u4e0a\u8fdb\u884c\u7ed8\u5236\u7684matplotlib subplot\u5bf9\u8c61\u3002\u5982\u679c\u6ca1\u6709\u8bbe\u7f6e\uff0c\u5219\u4f7f\u7528\u5f53\u524dmatplotlib subplot\u3002\u5176\u4e2d\uff0c\u53d8\u91cf\u548c\u51fd\u6570\u901a\u8fc7\u6539\u53d8figure\u548caxes\u4e2d\u7684\u5143\u7d20\uff08\u4f8b\u5982\uff1atitle,label,\u70b9\u548c\u7ebf\u7b49\u7b49\uff09\u4e00\u8d77\u63cf\u8ff0figure\u548caxes\uff0c\u4e5f\u5c31\u662f\u5728\u753b\u5e03\u4e0a\u7ed8\u56fe\u3002 subplots : \u5224\u65ad\u56fe\u7247\u4e2d\u662f\u5426\u6709\u5b50\u56fe sharex : \u5982\u679c\u6709\u5b50\u56fe\uff0c\u5b50\u56fe\u5171x\u8f74\u523b\u5ea6\uff0c\u6807\u7b7e sharey : \u5982\u679c\u6709\u5b50\u56fe\uff0c\u5b50\u56fe\u5171y\u8f74\u523b\u5ea6\uff0c\u6807\u7b7e layout : \u5b50\u56fe\u7684\u884c\u5217\u5e03\u5c40 figsize : \u56fe\u7247\u5c3a\u5bf8\u5927\u5c0f use_index : \u9ed8\u8ba4\u7528\u7d22\u5f15\u505ax\u8f74 title : \u56fe\u7247\u7684\u6807\u9898\u7528\u5b57\u7b26\u4e32 grid : \u56fe\u7247\u662f\u5426\u6709\u7f51\u683c legend : \u5b50\u56fe\u7684\u56fe\u4f8b\uff0c\u6dfb\u52a0\u4e00\u4e2asubplot\u56fe\u4f8b(\u9ed8\u8ba4\u4e3aTrue) style : \u5bf9\u6bcf\u5217\u6298\u7ebf\u56fe\u8bbe\u7f6e\u7ebf\u7684\u7c7b\u578b logx : \u8bbe\u7f6ex\u8f74\u523b\u5ea6\u662f\u5426\u53d6\u5bf9\u6570 logy : \u8bbe\u7f6ey\u8f74\u523b\u5ea6\u662f\u5426\u53d6\u5bf9\u6570 loglog : \u540c\u65f6\u8bbe\u7f6ex\uff0cy\u8f74\u523b\u5ea6\u662f\u5426\u53d6\u5bf9\u6570 xticks : \u8bbe\u7f6ex\u8f74\u523b\u5ea6\u503c\uff0c\u5e8f\u5217\u5f62\u5f0f\uff08\u6bd4\u5982\u5217\u8868\uff09 yticks : \u8bbe\u7f6ey\u8f74\u523b\u5ea6\uff0c\u5e8f\u5217\u5f62\u5f0f\uff08\u6bd4\u5982\u5217\u8868\uff09 xlim : \u8bbe\u7f6e\u5750\u6807\u8f74x\u7684\u8303\u56f4\uff0c\u5217\u8868\u6216\u5143\u7ec4\u5f62\u5f0f ylim : \u8bbe\u7f6e\u5750\u6807\u8f74y\u7684\u8303\u56f4\uff0c\u5217\u8868\u6216\u5143\u7ec4\u5f62\u5f0f rot : \u8bbe\u7f6e\u8f74\u6807\u7b7e\uff08\u8f74\u523b\u5ea6\uff09\u7684\u663e\u793a\u65cb\u8f6c\u5ea6\u6570 fontsize : \u8bbe\u7f6e\u8f74\u523b\u5ea6\u7684\u5b57\u4f53\u5927\u5c0f colormap : \u8bbe\u7f6e\u56fe\u7684\u533a\u57df\u989c\u8272 colorbar : \u56fe\u7247\u67f1\u5b50 position : Specify relative alignments for bar plot layout. From 0 (left/bottom-end) to 1 (right/top-end). Default is 0.5 (center) layout : \u5e03\u5c40(rows, columns) for the layout of the plot table : \u5982\u679c\u4e3a\u6b63\uff0c\u5219\u9009\u62e9DataFrame\u7c7b\u578b\u7684\u6570\u636e\u5e76\u4e14\u8f6c\u6362\u5339\u914dmatplotlib\u7684\u5e03\u5c40 yerr : \u5e26\u8bef\u5dee\u7ebf\u7684\u67f1\u5f62\u56fe xerr : \u5e26\u8bef\u5dee\u7ebf\u7684\u67f1\u5f62\u56fe stacked : \u751f\u6210\u5806\u79ef\u67f1\u72b6\u56fe sort_columns : \u4ee5\u5b57\u6bcd\u8868\u987a\u5e8f\u7ed8\u5236\u5404\u5217\uff0c\u9ed8\u8ba4\u4f7f\u7528\u524d\u5217\u987a\u5e8f secondary_y : \u8bbe\u7f6e\u7b2c\u4e8c\u4e2ay\u8f74\uff08\u53f3y\u8f74\uff09 mark_right : When using a secondary_y axis, automatically mark the column labels with \u201c(right)\u201d in the legend kwds : Options to pass to matplotlib plotting method Series data1 = np.random.randn(10).cumsum(0) s1 = pd.Series( data1, index=np.arange(0, 100, 10), ) print(s1) fig, axes = plt.subplots(3, 1) # 3\u4e2a\u5b50\u56fe s1.plot.bar(ax=axes[0], color='k', alpha=0.7) # \u6761\u5f62\u56fe(\u5b50\u56fe0)\uff0ccolor='k\u2019(\u67f1\u5b50\u7684\u989c\u8272\u8bbe\u7f6e\u4e3a\u9ed1\u8272)\uff0calpha=0.7(\u56fe\u50cf\u7684\u586b\u5145\u8272\u8bbe\u7f6e\u4e3a\u90e8\u5206\u900f\u660e) s1.plot.barh(ax=axes[1], color='k', alpha=0.7) # \u6a2a\u5411\u6761\u5f62\u56fe(\u5b50\u56fe1) s1.value_counts().plot.pie(ax=axes[2]) # \u901a\u8fc7value_counts()\u5bf9Series\u503c\u9891\u7387\u8fdb\u884c\u53ef\u89c6\u5316 plt.show() DataFrame data2 = np.random.randn(10, 4).cumsum(0) df1 = pd.DataFrame( data2, columns=pd.Index(['A', 'B', 'C', 'D'], name='Genus'), index=np.arange(0, 100, 10) ) print(df1) fig, axes = plt.subplots(2, 1) # 2\u4e2a\u5b50\u56fe df1.plot.kde(ax=axes[0], alpha=0.7, grid='True', title='KDE Figure', sharex=True) df1.plot.bar(ax=axes[1], grid='True', title='Line Figure', sharex=True, use_index=False, stacked=True) # \u56e0\u4e3a\u5171\u4eabx\u8f74\uff0c\u6240\u4ee5\u5728KDE\u5b50\u56fe\u4e2d\u6307\u5b9ause_index=False\u770b\u4e0d\u51fa\u6548\u679c\u3002 # DataFrame\u7684\u5217\u540d\u79f0\"Genus\"\u88ab\u7528\u4f5c\u4e86\u56fe\u4f8b\u6807\u9898 # stacked=True\u6765\u751f\u6210\u5806\u79ef\u67f1\u72b6\u56fe plt.show() \u5b9e\u4f8b\uff1a\u7ed8\u5236\u4e00\u4e2a\u5806\u79ef\u67f1\u72b6\u56fe\uff0c\u7528\u4e8e\u5c55\u793a\u6bcf\u4e2a\u6d3e\u5bf9\u5728\u6bcf\u5929\u7684\u6570\u636e\u70b9\u5360\u6bd4\u3002 \u4ea4\u53c9\u8868 \u662f\u4e00\u79cd\u5e38\u7528\u7684\u5206\u7c7b\u6c47\u603b\u8868\u683c\uff0c\u7528\u4e8e\u9891\u6570\u5206\u5e03\u7edf\u8ba1\uff0c\u4e3b\u8981\u4ef7\u503c\u5728\u4e8e\u63cf\u8ff0\u4e86\u53d8\u91cf\u95f4\u5173\u7cfb\u7684\u6df1\u523b\u542b\u4e49\u3002 \u867d\u7136\u4e24\u4e2a\uff08\u6216\u4ee5\u4e0a\uff09\u53d8\u91cf\u53ef\u4ee5\u662f\u5206\u7c7b\u7684\u6216\u6570\u91cf\u7684\uff0c\u4f46\u662f\u4ee5\u90fd\u662f\u5206\u7c7b\u7684\u60c5\u5f62\u6700\u4e3a\u5e38\u89c1\u3002 Pandas\u7684 crosstab() \u65b9\u6cd5\u80fd\u591f\u5feb\u901f\u6784\u5efa\u4ea4\u53c9\u8868\uff0c\u5e76\u53ef\u4ee5\u901a\u8fc7\u53c2\u6570\u52a0\u4ee5\u4e2a\u6027\u5316\u7684\u8bbe\u7f6e\u3002\u5176\u4e2d\uff0c\u7b2c\u4e00\u4e2a\u53c2\u6570\u5c06\u6784\u6210\u4ea4\u53c9\u8868\u7684\u884c\uff0c\u7b2c\u4e8c\u4e2a\u53c2\u6570\u5c06\u6784\u6210\u4ea4\u53c9\u8868\u7684\u5217\u3002 tips = pd.read_csv('../examples/tips.csv') print(tips) # total_bill tip smoker day time size # 0 16.99 1.01 No Sun Dinner 2 # 1 10.34 1.66 No Sun Dinner 3 # 2 21.01 3.50 No Sun Dinner 3 # 3 23.68 3.31 No Sun Dinner 2 # 4 24.59 3.61 No Sun Dinner 4 # .. ... ... ... ... ... ... # 239 29.03 5.92 No Sat Dinner 3 # 240 27.18 2.00 Yes Sat Dinner 2 # 241 22.67 2.00 Yes Sat Dinner 2 # 242 17.82 1.75 No Sat Dinner 2 # 243 18.78 3.00 No Thur Dinner 2 # [244 rows x 6 columns] party_counts = pd.crosstab(tips['day'], tips['size']) # \u5bf9\u539f\u59cb\u6570\u636e\u7684day\u548csize\u8fdb\u884c\u805a\u5408\uff0c\u5e76\u6784\u5efa\u4ea4\u53c9\u8868\uff0cday\u4f5c\u4e3a\u884c\uff0csize\u4f5c\u4e3a\u5217\u3002 print(party_counts) # size 1 2 3 4 5 6 # day # Fri 1 16 1 1 0 0 # Sat 2 53 18 13 1 0 # Sun 0 39 15 18 3 1 # Thur 1 48 4 5 1 3 # \u6ca1\u6709\u592a\u591a\u76841\u4eba\u548c6\u4eba\u6d3e\u5bf9\uff0c\u820d\u5f03\u8fd9\u4e9b\u6570\u636e party_counts = party_counts.loc[:, 2:5] print(party_counts) # size 2 3 4 5 # day # Fri 16 1 1 0 # Sat 53 18 13 1 # Sun 39 15 18 3 # Thur 48 4 5 1 # \u6807\u51c6\u5316\u81f3\u548c\u4e3a1\uff1a\u6cbf0\u8f74\uff08\u884c\uff09\u5bf9\u6bcf\u5217\u6c42\u548c\uff0c\u6bcf\u884c\u5404\u503c\u9664\u4ee5\u548c\uff0c\u4ee5\u786e\u4fdd\u6bcf\u4e00\u884c\u7684\u503c\u548c\u4e3a1\uff0c\u7136\u540e\u8fdb\u884c\u7ed8\u56fe party_pcts = party_counts.div(party_counts.sum(1), axis=0) print(party_pcts) # size 2 3 4 5 # day # Fri 0.888889 0.055556 0.055556 0.000000 # Sat 0.623529 0.211765 0.152941 0.011765 # Sun 0.520000 0.200000 0.240000 0.040000 # Thur 0.827586 0.068966 0.086207 0.017241 party_counts.plot.bar() plt.show() \u53ef\u4ee5\u770b\u5230\u672c\u6570\u636e\u96c6\u4e2d\u7684\u6d3e\u5bf9\u6570\u91cf\u5728\u5468\u672b\u4f1a\u589e\u52a0\u3002 \u5b9e\u4f8b\uff1a\u4f7f\u7528seaborn\u8fdb\u884c\u6309\u661f\u671f\u65e5\u671f\u8ba1\u7b97\u5c0f\u8d39\u767e\u5206\u6bd4\u3002 Seaborn\u8981\u6c42\u6570\u636e\u7684\u8f93\u5165\u7c7b\u578b\u4e3apandas\u7684Dataframe\u6216Numpy\u6570\u7ec4\u3002 tips['tip_pct'] = tips['tip'] / (tips['total_bill'] - tips['tip']) print(tips) # total_bill tip smoker day time size tip_pct # 0 16.99 1.01 No Sun Dinner 2 0.063204 # 1 10.34 1.66 No Sun Dinner 3 0.191244 # 2 21.01 3.50 No Sun Dinner 3 0.199886 # 3 23.68 3.31 No Sun Dinner 2 0.162494 # 4 24.59 3.61 No Sun Dinner 4 0.172069 # .. ... ... ... ... ... ... ... # 239 29.03 5.92 No Sat Dinner 3 0.256166 # 240 27.18 2.00 Yes Sat Dinner 2 0.079428 # 241 22.67 2.00 Yes Sat Dinner 2 0.096759 # 242 17.82 1.75 No Sat Dinner 2 0.108899 # 243 18.78 3.00 No Thur Dinner 2 0.190114 # [244 rows x 7 columns] # barplot: \u5c06\u70b9\u4f30\u8ba1\u548c\u7f6e\u4fe1\u533a\u95f4\u663e\u793a\u4e3a\u77e9\u5f62\u6761\u3002\u6761\u5f62\u56fe\u8868\u793a\u5177\u6709\u6bcf\u4e2a\u77e9\u5f62\u7684\u9ad8\u5ea6\u7684\u6570\u503c\u53d8\u91cf\u7684\u96c6\u4e2d\u8d8b\u52bf\u7684\u4f30\u8ba1\uff0c\u5e76\u4e14\u4f7f\u7528\u8bef\u5dee\u6761\u63d0\u4f9b\u56f4\u7ed5\u8be5\u4f30\u8ba1\u7684\u4e0d\u786e\u5b9a\u6027\u7684\u4e00\u4e9b\u6307\u793a # \u67f1\u5b50\u7684\u503c\u662ftip_pct\u7684\u5e73\u5747\u503c # \u67f1\u5b50\u4e0a\u753b\u51fa\u7684\u9ed1\u7ebf\u4ee3\u8868\u7684\u662f95%\u7684\u7f6e\u4fe1\u533a\u95f4\uff08\u7f6e\u4fe1\u533a\u95f4\u53ef\u4ee5\u901a\u8fc7\u53ef\u9009\u53c2\u6570\u8fdb\u884c\u8bbe\u7f6e\uff09 # hue\u9009\u9879\uff0c\u5141\u8bb8\u6211\u4eec\u901a\u8fc7\u4e00\u4e2a\u989d\u5916\u7684\u5206\u7c7b\u503c\u5c06\u6570\u636e\u5206\u79bb # \u5e26\u53c2\u6570hue='time'\u65f6\uff0c\u56db\u4e2a\u4e0d\u540c\u989c\u8272\u7684\u67f1\u5b50\uff0c\u6bcf\u4e2a\u67f1\u5b50\u4e0a\u6709\u7f6e\u4fe1\u533a\u95f4\u7684\u9ed1\u7ebf\uff0c\u523b\u5ea60.00~0.30\uff0c\u6b65\u957f0.05 # \u4e0d\u5e26\u53c2\u6570hue='time'\u65f6\uff0c\u4e24\u4e2a\u4e0d\u540c\u989c\u8272\u7684\u67f1\u5b50\uff0c\u5206\u522b\u4ee3\u8868Dinner\u548cLunch\uff0c\u4e0d\u662f\u6bcf\u4e2a\u67f1\u5b50\u4e0a\u90fd\u6709\u7f6e\u4fe1\u533a\u95f4\u7684\u9ed1\u7ebf\uff0c\u523b\u5ea60.00~0.30\uff0c\u6b65\u957f0.05 sns.barplot(x='tip_pct', y='day', data=tips, hue='time', orient='h') # \u6839\u636e\u661f\u671f\u65e5\u671f\u548c\u65f6\u95f4\u8ba1\u7b97\u7684\u5c0f\u8d39\u767e\u5206\u6bd4 # sns.barplot(x='tip_pct', y='day', data=tips, orient='h') sns.set(style=\"darkgrid\", palette=\"deep\") # style=\"whitegrid\" plt.show() \u76f4\u65b9\u56fe\u548c\u5bc6\u5ea6\u56fe \u00b6 \u76f4\u65b9\u56fe\u662f\u4e00\u79cd\u6761\u5f62\u56fe\uff0c\u7528\u4e8e\u7ed9\u51fa\u503c\u9891\u7387\u7684\u79bb\u6563\u663e\u793a\u3002\u6570\u636e\u70b9\u88ab\u5206\u6210\u79bb\u6563\u7684\uff0c\u5747\u5300\u95f4\u9694\u7684\u7bb1\uff0c\u5e76\u4e14\u7ed8\u5236\u6bcf\u4e2a\u7bb1\u4e2d\u6570\u636e\u70b9\u7684\u6570\u91cf\u3002 tips['tip_pct'].plot.hist(bins=50) # \u5c0f\u8d39\u767e\u5206\u6bd4\u7684\u76f4\u65b9\u56fe plt.show() \u5bc6\u5ea6\u56fe\u662f\u4e00\u79cd\u4e0e\u76f4\u65b9\u56fe\u76f8\u5173\u7684\u56fe\u8868\u7c7b\u578b\uff0c\u5b83\u901a\u8fc7\u8ba1\u7b97\u53ef\u80fd\u4ea7\u751f\u89c2\u6d4b\u6570\u636e\u7684\u8fde\u7eed\u6982\u7387\u5206\u5e03\u4f30\u8ba1\u800c\u4ea7\u751f\u3002 \u901a\u5e38\u7684\u505a\u6cd5\u662f\u5c06\u8fd9\u79cd\u5206\u5e03\u8fd1\u4f3c\u4e3a\u201c\u5185\u6838\u201d\u7684\u6df7\u5408\uff0c\u4e5f\u5c31\u662f\u50cf\u6b63\u6001\u5206\u5e03\u90a3\u6837\u7b80\u5355\u7684\u5206\u5e03\u3002 \u56e0\u6b64\uff0c\u5bc6\u5ea6\u56fe\u4e5f\u88ab\u79f0\u4e3a\u5185\u6838\u5bc6\u5ea6\u4f30\u8ba1\u56fe\uff08KDE\uff09\u3002 tips['tip_pct'].plot.density() # \u5c0f\u8d39\u767e\u5206\u6bd4\u5bc6\u5ea6\u56fe plt.show() \u7ed8\u5236\u76f4\u65b9\u56fe\u548c\u8fde\u7eed\u5bc6\u5ea6\u4f30\u8ba1 sns.displot() \u3002 sns.distplot(tips['tip_pct'], bins=100, color='k') plt.show() # FutureWarning: `distplot` is a deprecated function and will be removed in a future version. # Please adapt your code to use either `displot` (a figure-level function with similar flexibility) # or `histplot` (an axes-level function for histograms). \u6563\u70b9\u56fe\u6216\u70b9\u56fe \u00b6 \u70b9\u56fe\u6216\u6563\u70b9\u56fe\u53ef\u4ee5\u7528\u4e8e\u68c0\u9a8c\u4e24\u4e2a\u4e00\u7ef4\u6570\u636e\u5e8f\u5217\u4e4b\u95f4\u7684\u5173\u7cfb\u3002 \u5b9e\u4f8b\uff1a\u4ece statsmodels \u9879\u76ee\u4e2d\u8f7d\u5165\u4e86macrodata\u6570\u636e\u96c6\uff0c\u5e76\u9009\u62e9\u4e86\u4e00\u4e9b\u53d8\u91cf\uff0c\u4e4b\u540e\u8ba1\u7b97\u5bf9\u6570\u5dee\u3002 macro = pd.read_csv('../examples/macrodata.csv') print(macro.head(5)) # year quarter realgdp realcons ... unemp pop infl realint # 0 1959.0 1.0 2710.349 1707.4 ... 5.8 177.146 0.00 0.00 # 1 1959.0 2.0 2778.801 1733.7 ... 5.1 177.830 2.34 0.74 # 2 1959.0 3.0 2775.488 1751.8 ... 5.3 178.657 2.74 1.09 # 3 1959.0 4.0 2785.204 1753.7 ... 5.6 179.386 0.27 4.06 # 4 1960.0 1.0 2847.699 1770.5 ... 5.2 180.007 2.31 1.19 # [5 rows x 14 columns] data = macro[['cpi', 'm1', 'tbilrate', 'unemp']] print(data.head(5)) # cpi m1 tbilrate unemp # 0 28.98 139.7 2.82 5.8 # 1 29.15 141.7 3.08 5.1 # 2 29.35 140.5 3.82 5.3 # 3 29.37 140.0 4.33 5.6 # 4 29.54 139.6 3.50 5.2 trans_data = np.log(data).diff().dropna() print(trans_data[-5:]) # cpi m1 tbilrate unemp # 198 -0.007904 0.045361 -0.396881 0.105361 # 199 -0.021979 0.066753 -2.277267 0.139762 # 200 0.002340 0.010286 0.606136 0.160343 # 201 0.008419 0.037461 -0.200671 0.127339 # 202 0.008894 0.012202 -0.405465 0.042560 \u7528 seaborn \u7684 regplot \u65b9\u6cd5\u7ed8\u5236\u6563\u70b9\u56fe\uff0c\u5e76\u62df\u5408\u51fa\u4e00\u4e2a\u6761\u7ebf\u6027\u56de\u5f52\u7ebf\u3002( seaborn\u6587\u6863 ) sns.regplot('m1', 'unemp', data=trans_data) plt.title('Changes in log %s versus log %s ' % ('m1', 'unemp')) plt.show() \u5728\u63a2\u7d22\u6027\u6570\u636e\u5206\u6790\u4e2d\uff0c\u80fd\u591f\u67e5\u770b\u4e00\u7ec4\u53d8\u91cf\u4e2d\u7684\u6240\u6709\u6563\u70b9\u56fe\u662f\u6709\u5e2e\u52a9\u7684\uff0c\u8fd9\u88ab\u79f0\u4e3a\u6210\u5bf9\u56fe\u6216\u6563\u70b9\u56fe\u77e9\u9635\u3002 Seaborn\u6709\u4e00\u4e2a\u65b9\u4fbf\u7684 pairplot \u51fd\u6570\uff0c\u5b83\u652f\u6301\u5728\u5bf9\u89d2\u7ebf\u4e0a\u653e\u7f6e\u6bcf\u4e2a\u53d8\u91cf\u7684\u76f4\u65b9\u56fe\u6216\u5bc6\u5ea6\u4f30\u8ba1\u503c\u3002 plot_ksw \u53c2\u6570\u80fd\u591f\u5c06\u914d\u7f6e\u9009\u9879\u4f20\u9012\u7ed9\u975e\u5bf9\u89d2\u5143\u7d20\u4e0a\u7684\u5404\u4e2a\u7ed8\u56fe\u8c03\u7528\u3002 sns.pairplot(trans_data, diag_kind='kde', plot_kws={'alpha': 0.2}) plt.show() \u5206\u9762\u7f51\u683c\u548c\u5206\u7c7b\u6570\u636e \u00b6 \u5982\u679c\u6570\u636e\u96c6\u6709\u989d\u5916\u7684\u5206\u7ec4\u7ef4\u5ea6\u600e\u4e48\u529e\uff1f\u4f7f\u7528\u5206\u9762\u7f51\u683c\u662f\u5229\u7528\u591a\u79cd\u5206\u7ec4\u53d8\u91cf\u5bf9\u6570\u636e\u8fdb\u884c\u53ef\u89c6\u5316\u7684\u65b9\u5f0f\u3002 seaborn\u62e5\u6709\u4e00\u4e2a\u6709\u6548\u7684\u5185\u5efa\u51fd\u6570 factorplot \uff0c\u5b83\u53ef\u4ee5\u7b80\u5316\u591a\u79cd\u5206\u9762\u7ed8\u56fe\u3002 sns.factorplot(x='day', y='tip_pct', hue='time', col='smoker', kind='bar', data=tips[tips.tip_pct < 1]) plt.show() # UserWarning: The `factorplot` function has been renamed to `catplot`. # The original name will be removed in a future release. Please update your code. # Note that the default `kind` in `factorplot` (`'point'`) has changed `'strip'` in `catplot`. sns.catplot(x='day', y='tip_pct', hue='time', col='smoker', kind='box', data=tips[tips.tip_pct < 0.5]) plt.show() \u5176\u4ed6Python\u53ef\u89c6\u5316\u5de5\u5177 \u00b6 \u81ea2010\u5e74\u4ee5\u6765\uff0c\u5f88\u591a\u5f00\u53d1\u5de5\u4f5c\u90fd\u96c6\u4e2d\u5728\u521b\u5efaweb\u4ea4\u4e92\u5f0f\u56fe\u5f62\u4e0a\u3002 \u501f\u52a9\u50cf Bokeh \u548c Plotly \u8fd9\u6837\u7684\u5de5\u5177\uff0c\u5728web\u6d4f\u89c8\u5668\u4e2d\u521b\u5efa\u52a8\u6001\u7684\u3001\u4ea4\u4e92\u5f0f\u56fe\u50cf\u7684\u5de5\u4f5c\u73b0\u5728\u5df2\u7ecf\u53ef\u4ee5\u5b9e\u73b0\u3002 \u53ef\u89c6\u5316\u662f\u4e00\u4e2a\u6d3b\u8dc3\u7684\u7814\u7a76\u9886\u57df\u3002","title":"\u7ed8\u56fe\u4e0e\u53ef\u89c6\u5316"},{"location":"python/DataAnalysis/ch06/#_1","text":"","title":"\u7ed8\u56fe\u4e0e\u53ef\u89c6\u5316"},{"location":"python/DataAnalysis/ch06/#matplotlib-api","text":"import matplotlib as mpl import matplotlib.pyplot as plt import numpy as np import pandas as pd from io import BytesIO \u6267\u884c plt.show() \u65f6\u62a5\u9519\uff1a UserWarning: Matplotlib is currently using agg, which is a non-GUI backend, so cannot show the figure. \u6267\u884c\u4e0b\u9762\u547d\u4ee4\uff0c\u5f97\u5230 plt \u7684 backend \u662f\u7528 agg \u3002 plt.get_backend() \u4f8b\u5982\uff1a\u4e0b\u9762\u4e24\u79cd\u8868\u8fbe\u65b9\u5f0f\u6548\u679c\u4e00\u6837\u3002 ax.plot(x, y, 'g--') ax.plot(x, y, linestyle='--', color='g') Out[6]: 'agg' \u5b89\u88c5\u4e0b\u9762\u51e0\u4e2a\u5305\uff1a sudo zypper in python-tk python3-tk sudo zypper in plplot-tcltk-devel plplot-tcltk-libs pip install tk \u6dfb\u52a0\u4e0b\u9762\u5230python\u4ee3\u7801\u4e2d\u3002 import matplotlib.pyplot as plt mpl.use('TkAgg') \u6267\u884c\u540e\u62a5\u4e0b\u9762\u9519\u8bef\uff1a your Python may not be configured for Tk \u8fdb\u5165python\u6e90\u7801\u76ee\u5f55\uff0c\u91cd\u65b0\u7f16\u8bd1\u4f8b\u5982\uff1a\u4e0b\u9762\u4e24\u79cd\u8868\u8fbe\u65b9\u5f0f\u6548\u679c\u4e00\u6837\u3002 ax.plot(x, y, 'g--') ax.plot(x, y, linestyle='--', color='g') james@lizard:/opt/Python-3.9.6> sudo make james@lizard:/opt/Python-3.9.6> sudo make install \u95ee\u9898\u89e3\u51b3\uff0c\u5373\u4f7f\u4e0d\u52a0\u5165 mpl.use('TkAgg') \uff0c\u6267\u884c plt.show() \u4e5f\u662f\u53ef\u4ee5\u8f93\u51fa\u56fe\u50cf\u3002","title":"\u7b80\u660ematplotlib API\u5165\u95e8"},{"location":"python/DataAnalysis/ch06/#_2","text":"matplotlib \u6240\u7ed8\u5236\u7684\u56fe\u4f4d\u4e8e\u56fe\u7247\uff08Figure\uff09\u5bf9\u8c61\u4e2d\u3002\u53ef\u4ee5\u4f7f\u7528 plt.figure \u751f\u6210\u4e00\u4e2a\u65b0\u7684\u56fe\u7247\u3002 \u4f7f\u7528 add_subplot \u521b\u5efa\u4e00\u4e2a\u6216\u591a\u4e2a\u5b50\u56fe\uff08subplot\uff09\u3002 plt \u4e0e ax \u7ed8\u56fe\u3002 fig = plt.figure() # plt: \u5148\u751f\u6210\u4e86\u4e00\u4e2a\u753b\u5e03\uff0c\u7136\u540e\u5728\u8fd9\u4e2a\u753b\u5e03\u4e0a\u9690\u5f0f\u7684\u751f\u6210\u4e00\u4e2a\u753b\u56fe\u533a\u57df\u6765\u8fdb\u884c\u753b\u56fe # plt.plot([1, 2, 3, 4]) # plt.show() # ax: \u5148\u751f\u6210\u4e00\u4e2a\u753b\u5e03\uff082\u00d72\u7684\u533a\u57df\uff0c\u6700\u591a\u653e\u56db\u4e2a\u56fe\u5f62\uff09\uff0c\u7136\u540e\u5728\u6b64\u753b\u5e03\u4e0a\uff0c\u9009\u5b9a\u4e00\u4e2a\u5b50\u533a\u57df\u753b\u4e86\u4e00\u4e2a\u5b50\u56fe\uff08\u5e8f\u53f71\u4ee3\u8868\u7b2c\u4e00\u4e2a\u533a\u57df\uff09 ax1 = fig.add_subplot(2, 2, 1) # \u4e5f\u53ef\u4ee5\u5199\u6210fig.add_subplot(221) ax1.plot([1, 2, 3, 4], [1, 4, 3, 2]) # \u8f93\u51fa\u56fe\u7247\u5230\u7b2c\u4e00\u4e2a\u533a\u57df\u3002 # \u7b2c\u4e00\u4e2a\u53c2\u6570\u662f\u6570\u636e\u96c6\u91cc\u5404\u4e2a\u6570\u636e\u70b9\u7684X\u503c\u7684\u96c6\u5408 # \u7b2c\u4e8c\u4e2a\u53c2\u6570\u6570\u636e\u96c6\u91cc\u5404\u4e2a\u6570\u636e\u70b9\u7684Y\u503c\u7684\u96c6\u5408\u3002 # \u4e0d\u662f\u6570\u5b66\u4e0a\u5e38\u89c1\u7684\u6210\u5bf9\u5750\u6807\u70b9\u5982(x1,y1)\u3001(x2,y2)\u3001...\u3001(xn,yn)\u7684\u683c\u5f0f\uff0c\u800c\u662f (x1,x2,...,xn)\u548c(y1,y2,...,yn) \u3002 plt.show() \u770b\u4e0b\u9762\u4f8b\u5b50\uff0c\u589e\u52a0\u5b50\u56fe\u540e\u7684\u6570\u636e\u53ef\u89c6\u5316\u6548\u679c\u3002 fig = plt.figure() ax1 = fig.add_subplot(2, 2, 1) ax2 = fig.add_subplot(2, 2, 2) ax3 = fig.add_subplot(2, 2, 3) ax1.plot(np.random.randn(50).cumsum(), 'k--') # \u5728\u7b2c\u4e09\u4e2a\u533a\u57df\u8f93\u51fa\u56fe\u50cf\u3002'k--\u2019\u662f\u7528\u4e8e\u7ed8\u5236\u9ed1\u8272\u5206\u6bb5\u7ebf\u7684style\u9009\u9879\u3002 ax2.hist(np.random.randn(100), bins=20, color='k', alpha=0.3) ax3.scatter(np.arange(30), np.arange(30) + 3 * np.random.randn(30)) plt.show() plt.subplots \u901a\u8fc7 matplotlib \u7684 subplots \u65b9\u6cd5\uff0c\u4f7f\u7528\u5b50\u56fe\u7f51\u683c\u521b\u5efa\u56fe\u7247\uff0c\u7136\u540e\u8fd4\u56de\u5305\u542b\u4e86\u5df2\u751f\u6210\u5b50\u56fe\u5bf9\u8c61\u7684NumPy\u6570\u7ec4\u3002 \u6570\u7ec4 axes \u53ef\u4ee5\u50cf\u4e8c\u7ef4\u6570\u7ec4\u90a3\u6837\u65b9\u4fbf\u5730\u8fdb\u884c\u7d22\u5f15\uff0c\u4f8b\u5982\uff0c axes[0, 1] \u3002 plt.subplots \u53c2\u6570\u9009\u9879\uff1a nrows\uff1a\u53ef\u9009\u7684\uff0c\u6574\u578b\uff0c\u9ed8\u8ba4\u4e3a1\u3002\u5b50\u56fe\u7f51\u683c\u7684\u884c\u6570\u3002 ncols\uff1a\u53ef\u9009\u7684\uff0c\u6574\u578b\uff0c\u9ed8\u8ba4\u4e3a1\u3002\u5b50\u56fe\u7f51\u683c\u7684\u5217\u6570\u3002 sharex\uff1a\u53ef\u9009\u7684\uff0c\u9ed8\u8ba4\u4e3aFalse\u3002\u53ef\u9009\u503c\u5982\u4e0b\uff1a True\u6216all\uff0c\u6240\u6709\u5b50\u56fe\u5171\u4eabx\u8f74 False\u6216none\uff0c\u6bcf\u4e2a\u5b50\u56fe\u7684x\u8f74\u90fd\u662f\u72ec\u7acb\u7684 row\uff0c\u6bcf\u884c\u5b50\u56fe\u5171\u4eab\u4e00\u4e2ax\u8f74 col\uff0c\u6bcf\u5217\u5b50\u56fe\u5171\u4eab\u4e00\u4e2ax\u8f74 sharey\uff1a\u7c7b\u4f3c\u4e8esharex\uff0c\u8bbe\u7f6ey\u8f74\u7684\u5171\u4eab\u65b9\u5f0f\u3002\u5f53\u67d0\u5217\u5171\u4eab\u4e00\u4e2ax\u8f74\u65f6\uff0c\u53ea\u6709\u5e95\u90e8\u7684\u5b50\u56fe\u4f1a\u521b\u5efax\u8f74\u6807\u8bb0\u3002\u540c\u6837\u7684\uff0c\u5982\u679c\u67d0\u884c\u5171\u4eab\u4e00\u4e2ay\u8f74\u65f6\uff0c\u53ea\u6709\u884c\u7684\u7b2c\u4e00\u5217\u5b50\u56fe\u4f1a\u521b\u5efay\u8f74\u6807\u8bb0\u3002 squeeze \uff1a\u53ef\u9009\u7684\uff0c\u5e03\u5c14\u578b\uff0c\u9ed8\u8ba4\u4e3aTrue\u3002\u662f\u5426\u538b\u7f29\u8fd4\u56de\u7684Axes\u6570\u7ec4\u3002\u5982\u679c\u4e3aTrue\uff0c\u5f53\u53ea\u6709\u4e00\u4e2a\u5b50\u56fe\uff0c\u5373nrows\u548cncols\u5747\u4e3a1\u65f6\uff0c\u8fd4\u56de\u4e00\u4e2a\u5355\u72ec\u7684Axes\u5bf9\u8c61\uff0c\u5f53\u6709N*1\u548c1*M\u4e2a\u5b50\u56fe\u65f6\uff0c\u8fd4\u56de\u4e00\u4e2a\u4e00\u7ef4Axes\u5bf9\u8c61\u6570\u7ec4\u3002\u5f53\u6709N*M\u4e2a\u5b50\u56fe\uff08N>1\uff0cM>1\uff09\u65f6\uff0c\u8fd4\u56de\u4e8c\u7ef4\u6570\u7ec4\u3002\u5982\u679c\u4e3aFalse\uff0c\u5219\u603b\u662f\u8fd4\u56de\u4e8c\u7ef4\u6570\u7ec4\u3002 num\uff1a\u53ef\u9009\u7684\uff0c\u6574\u578b\u6216\u5b57\u7b26\u4e32\uff0c\u9ed8\u8ba4\u4e3aNone\u3002\u662fmatplotlib.pyplot.figure\u7684\u5173\u952e\u5b57\uff0c\u7528\u4e8e\u8bbe\u7f6e\u56fe\u50cf\u6570\u5b57\u6216\u6807\u7b7e\u3002\u5982\u679c\u672a\u8bbe\u7f6e\u6b64\u53c2\u6570\uff0c\u4f1a\u521b\u5efa\u4e00\u4e2a\u65b0\u7684\u56fe\u50cf\uff0c\u5e76\u9012\u589e\u56fe\u50cf\u7f16\u53f7\uff0cfigure\u5bf9\u8c61\u4f1a\u5c06\u7f16\u53f7\u4fdd\u5b58\u5728number\u5c5e\u6027\u4e2d\u3002\u5982\u679c\u8bbe\u7f6e\u4e86\u6b64\u53c2\u6570\uff0c\u5e76\u4e14\u5b58\u5728\u53c2\u6570\u6307\u5b9a\u7684\u56fe\u50cf\uff0c\u5219\u4f1a\u8fd4\u56de\u6b64\u56fe\u50cf\u7684\u5f15\u7528\uff0c\u5982\u679c\u4e0d\u5b58\u5728\u5219\u4f1a\u521b\u5efa\u65b0\u7684\u56fe\u50cf\u5e76\u8fd4\u56de\u5b83\u7684\u5f15\u7528\u3002\u5982\u679c\u662f\u5b57\u7b26\u4e32\uff0c\u5219\u7a97\u53e3\u6807\u9898\u4f1a\u88ab\u8bbe\u7f6e\u4e3a\u6b64\u5b57\u7b26\u4e32\u7684\u503c\u3002 subplot_kw\uff1a\u53ef\u9009\u7684\uff0c\u5b57\u5178\u7c7b\u578b\u3002\u5305\u542b\u4f20\u9012\u7ed9\u7528\u4e8e\u521b\u5efa\u5b50\u56fe\u7684\u8c03\u7528add_subplot\u7684\u5173\u952e\u5b57\u53c2\u6570\u3002 gridspec_kw\uff1a\u53ef\u9009\u7684\uff0c\u5b57\u5178\u7c7b\u578b\u3002\u5305\u542b\u4f20\u9012\u7ed9\u7528\u4e8e\u521b\u5efa\u5b50\u56fe\u7f51\u683c\u7684GridSpec\u6784\u9020\u51fd\u6570\u7684\u5173\u952e\u5b57\u53c2\u6570\u3002 fig, axes = plt.subplots(2, 3) print(axes) # \u5c06\u751f\u6210\u7684axes\u5bf9\u8c61\u653e\u5165NumPy\u6570\u7ec4\u3002 # [[ ] # [ ]] \u8c03\u6574\u5b50\u56fe\u5468\u56f4\u7684\u95f4\u8ddd\u3002 \u9ed8\u8ba4\u60c5\u51b5\u4e0b\uff0c matplotlib \u4f1a\u5728\u5b50\u56fe\u7684\u5916\u90e8\u548c\u5b50\u56fe\u4e4b\u95f4\u7559\u51fa\u4e00\u5b9a\u7684\u95f4\u8ddd\u3002 \u8fd9\u4e2a\u95f4\u8ddd\u90fd\u662f\u76f8\u5bf9\u4e8e\u56fe\u7684\u9ad8\u5ea6\u548c\u5bbd\u5ea6\u6765\u6307\u5b9a\u7684\uff0c\u624b\u52a8\u8c03\u6574\u56fe\u7684\u5927\u5c0f\uff0c\u90a3\u4e48\u95f4\u8ddd\u4f1a\u81ea\u52a8\u8c03\u6574\u3002 \u4e5f\u53ef\u4ee5\u4f7f\u7528\u56fe\u5bf9\u8c61\u4e0a\u7684 subplots_adjust \u65b9\u6cd5\u66f4\u6539\u95f4\u8ddd\uff0c\u4e5f\u53ef\u4ee5\u7528\u4f5c\u9876\u5c42\u51fd\u6570\u3002 fig, axes = plt.subplots(2, 2, sharex=True, sharey=True) for i in range(2): for j in range(2): axes[i, j].hist(np.random.randn(500), bins=50, color='k', alpha=0.5) plt.subplots_adjust(wspace=0, hspace=0) plt.show() \u4e0a\u9762\u8f93\u51fa\u56fe\u50cf\u7684\u8f74\u6807\u7b7e\u662f\u5b58\u5728\u91cd\u53e0\u7684\u3002 matplotlib \u5e76\u4e0d\u68c0\u67e5\u6807\u7b7e\u662f\u5426\u91cd\u53e0\uff0c\u56e0\u6b64\u5728\u7c7b\u4f3c\u60c5\u51b5\u4e0b\u4f60\u9700\u8981\u901a\u8fc7\u663e\u5f0f\u6307\u5b9a\u523b\u5ea6\u4f4d\u7f6e\u548c\u523b\u5ea6\u6807\u7b7e\u7684\u65b9\u6cd5\u6765\u4fee\u590d\u8f74\u6807\u7b7e\u3002","title":"\u56fe\u7247\u4e0e\u5b50\u56fe"},{"location":"python/DataAnalysis/ch06/#_3","text":"matplotlib \u7684\u4e3b\u51fd\u6570 plot \u63a5\u6536\u5e26\u6709 x \u548c y \u8f74\u7684\u6570\u7ec4\u4ee5\u53ca\u4e00\u4e9b\u53ef\u9009\u7684\u5b57\u7b26\u4e32\u7f29\u5199\u53c2\u6570\u6765\u6307\u660e\u989c\u8272\u548c\u7ebf\u7c7b\u578b\u3002 \u4f8b\u5982\uff1a\u4e0b\u9762\u4e24\u79cd\u8868\u8fbe\u65b9\u5f0f\u6548\u679c\u4e00\u6837\u3002 ax.plot(x, y, 'g--') ax.plot(x, y, linestyle='--', color='g') data = np.random.randn(30).cumsum() plt.plot(data, 'ko--') plt.show() # \u4e0a\u9762\u7684\u4ee3\u7801\u53ef\u4ee5\u5199\u5f97\u66f4\u4e3a\u663e\u5f0f\uff1a plt.plot(data, color='k', linestyle='dashed', marker='o') plt.show() plt.plot(data, color='k', linestyle='dashed', marker='o', label='Default') plt.show() plt.plot(data, color='k', linestyle='dashed', marker='o', label='steps-post', drawstyle='steps-post') plt.show()","title":"\u989c\u8272\u3001\u6807\u8bb0\u548c\u7ebf\u7c7b\u578b"},{"location":"python/DataAnalysis/ch06/#_4","text":"\u5bf9\u4e8e\u5927\u591a\u6570\u56fe\u8868\u4fee\u9970\u5de5\u4f5c\uff0c\u6709\u4e24\u79cd\u4e3b\u8981\u7684\u65b9\u5f0f\uff1a\u4f7f\u7528\u7a0b\u5e8f\u6027\u7684pyplot\u63a5\u53e3\uff08\u5373matplotlib.pyplot\uff09\u548c\u66f4\u591a\u9762\u5411\u5bf9\u8c61\u7684\u539f\u751fmatplotlib API\u3002 pyplot \u63a5\u53e3\u8bbe\u8ba1\u4e3a\u4ea4\u4e92\u5f0f\u4f7f\u7528\uff0c\u5305\u542b\u4e86\u50cf xlim \u3001 xticks \u548c xticklabels \u7b49\u65b9\u6cd5\u3002\u8fd9\u4e9b\u65b9\u6cd5\u5206\u522b\u63a7\u5236\u4e86\u7ed8\u56fe\u8303\u56f4\u3001\u523b\u5ea6\u4f4d\u7f6e\u4ee5\u53ca\u523b\u5ea6\u6807\u7b7e\u3002 \u5728\u6ca1\u6709\u51fd\u6570\u53c2\u6570\u7684\u60c5\u51b5\u4e0b\u8c03\u7528\uff0c\u8fd4\u56de\u5f53\u524d\u7684\u53c2\u6570\u503c\uff08\u4f8b\u5982 plt.xlim() \u8fd4\u56de\u5f53\u524d\u7684x\u8f74\u7ed8\u56fe\u8303\u56f4\uff09\u3002 \u4f20\u5165\u53c2\u6570\u7684\u60c5\u51b5\u4e0b\u8c03\u7528\uff0c\u5e76\u8bbe\u7f6e\u53c2\u6570\u503c\uff08\u4f8b\u5982 plt.xlim\uff08[0, 10]\uff09 \u4f1a\u5c06 x \u8f74\u7684\u8303\u56f4\u8bbe\u7f6e\u4e3a0\u523010\uff09\u3002 \u6240\u6709\u7684\u8fd9\u4e9b\u65b9\u6cd5\u90fd\u4f1a\u5728\u5f53\u524d\u6d3b\u52a8\u7684\u6216\u6700\u8fd1\u521b\u5efa\u7684 AxesSubplot \u4e0a\u751f\u6548\u3002 \u8fd9\u4e9b\u65b9\u6cd5\u4e2d\u7684\u6bcf\u4e00\u4e2a\u5bf9\u5e94\u4e8e\u5b50\u56fe\u81ea\u8eab\u7684\u4e24\u4e2a\u65b9\u6cd5\u3002\u6bd4\u5982 xlim \u5bf9\u5e94\u4e8e ax.get_lim \u548c ax.set_lim \u3002 \u63a8\u8350\u4f7f\u7528 subplot \u7684\u5b9e\u4f8b\u65b9\u6cd5\uff0c\u56e0\u4e3a\u8fd9\u6837\u66f4\u4e3a\u663e\u5f0f\uff08\u5c24\u5176\u662f\u5728\u5904\u7406\u591a\u4e2a\u5b50\u56fe\u65f6\uff09\u3002 data = np.random.randn(1000).cumsum() fig = plt.figure() # \u8bbe\u5b9a\u5b50\u56fe ax = fig.add_subplot(1, 1, 1) # \u8bbe\u5b9ax\u8f74\u5bf9\u5e94\u53c2\u6570\uff1a # \u8bbe\u5b9ax\u8f74\u523b\u5ea6 ax.set_xticks([0, 250, 500, 750, 1000]) # \u8bbe\u5b9ax\u8f74\u6807\u7b7e ax.set_xticklabels(['one(0)', 'two(250)', 'three(500)', 'four(750)', 'five(1000)'], rotation=30, fontsize='small') # \u7ed9x\u8f74\u4e00\u4e2a\u540d\u79f0 ax.set_xlabel('Stages') # \u8bbe\u5b9ay\u8f74\u5bf9\u5e94\u53c2\u6570\uff1a # \u672a\u6307\u5b9a\u7684\u53c2\u6570\u7531\u7cfb\u7edf\u9ed8\u8ba4\u4ea7\u751f\u3002 ax.set_ylabel('Steps') # \u7ed9\u5b50\u56fe\u6dfb\u52a0\u4e00\u4e2a\u6807\u9898 ax.set_title('My first matplotlib plot') # \u7ed9\u5b50\u56fe\u6dfb\u52a0\u4e00\u4e2a\u56fe\u4f8b\uff08\u5982\uff1a\u7ed9\u5b50\u56fe\u5185\u4e00\u4e2a\u56fe\u5f62\u66f2\u7ebf\u6dfb\u52a0\u4e00\u4e2alabel\uff09 ax.plot(data, 'k--', label='Label One') # loc\u53c2\u6570\u544a\u8bc9matplotlib\u5728\u54ea\u91cc\u653e\u7f6e\u56fe\u8868\u3002legend\u65b9\u6cd5\u6709\u591a\u4e2a\u5176\u4ed6\u7684\u4f4d\u7f6e\u53c2\u6570loc\u3002 ax.legend(loc='best') # \u6216\u8005plt.legend(loc='best') \u3002 # \u5728\u56fe\u5f62\u5750\u6807\u4e3a(0, 0)\u7684\u4f4d\u7f6e\u6dfb\u52a0\u4e00\u4e2alable ax.text(0, 0, 'Hello World1', family='monospace', fontsize=10) # \u7ed9\u5b50\u56fe\u6dfb\u52a0annotate\u3002\u7528\u4e00\u4e2a\u7bad\u5934\u6307\u5411\u8981\u6ce8\u91ca\u7684\u5730\u65b9\uff0c\u518d\u5199\u4e0a\u4e00\u6bb5\u8bdd\u7684\u884c\u4e3a\uff0c\u53eb\u505aannotate\u3002 # * s: \u6ce8\u91ca\u7684\u5185\u5bb9\uff0c\u4e00\u6bb5\u6587\u5b57\uff1b # * xytext: \u8fd9\u6bb5\u6587\u5b57\u6240\u5904\u7684\u4f4d\u7f6e; # * xy: \u7bad\u5934\u6307\u5411\u7684\u4f4d\u7f6e\uff1b # * arrowprops: \u901a\u8fc7arrowstyle\u8868\u660e\u7bad\u5934\u7684\u98ce\u683c\u6216\u79cd\u7c7b\u3002 ax.annotate('Zero is here!', xytext=(20, 20), xy=(1, 1), arrowprops=dict(arrowstyle='->')) # \u7ed9\u5b50\u56fe\u6dfb\u52a0\u4e00\u4e9b\u56fe\u5f62 # matplotlib\u542b\u6709\u8868\u793a\u591a\u79cd\u5e38\u89c1\u56fe\u5f62\u7684\u5bf9\u8c61\uff0c\u8fd9\u4e9b\u5bf9\u8c61\u7684\u5f15\u7528\u662fpatches\u3002 # \u4e00\u4e9b\u56fe\u5f62\uff0c\u6bd4\u5982Rectangle\uff08\u77e9\u5f62\uff09\u548cCircle\uff08\u5706\u5f62\uff09\uff0c\u53ef\u4ee5\u5728matplotlib.pyplot\u4e2d\u627e\u5230\uff0c\u4f46\u56fe\u5f62\u7684\u5168\u96c6\u4f4d\u4e8ematplotlib.patches\u3002 rect = plt.Rectangle((10, 5), 100, 15, color='k', alpha=0.3) circ = plt.Circle((200, 9), 95, color='b', alpha=0.3) pgon = plt.Polygon([[500, 5], [600, -5], [700, 30]], color='g', alpha=0.5) ax.add_patch(rect) ax.add_patch(circ) ax.add_patch(pgon) # \u5c06\u56fe\u7247\u4fdd\u5b58\u5230\u6587\u4ef6 # \u6587\u4ef6\u7c7b\u578b\u662f\u4ece\u6587\u4ef6\u6269\u5c55\u540d\u4e2d\u63a8\u65ad\u51fa\u6765\u7684\u3002\u6240\u4ee5\u5982\u679c\u4f60\u4f7f\u7528\uff0epdf\uff0c\u5219\u4f1a\u5f97\u5230\u4e00\u4e2aPDF\u3002 # \u51e0\u4e2a\u91cd\u8981\u7684\u9009\u9879\uff1adpi\uff0c\u5b83\u63a7\u5236\u6bcf\u82f1\u5bf8\u70b9\u6570\u7684\u5206\u8fa8\u7387\uff1bbbox_inches\uff0c\u53ef\u4ee5\u4fee\u526a\u5b9e\u9645\u56fe\u5f62\u7684\u7a7a\u767d\u3002 plt.savefig('../examples/figpath.png', dpi=400, bbox_inches='tight') # saveifg\u5e76\u975e\u4e00\u5b9a\u662f\u5199\u5230\u786c\u76d8\u7684\uff0c\u5b83\u53ef\u4ee5\u5c06\u56fe\u7247\u5199\u5165\u5230\u6240\u6709\u7684\u6587\u4ef6\u578b\u5bf9\u8c61\u4e2d\uff0c\u4f8b\u5982BytesIO buffer = BytesIO() plt.savefig(buffer) plot_data = buffer.getvalue() plt.show()","title":"\u523b\u5ea6\u3001\u6807\u7b7e\u548c\u56fe\u4f8b"},{"location":"python/DataAnalysis/ch06/#matplotlib","text":"matplotlib \u914d\u7f6e\u4e86\u914d\u8272\u65b9\u6848\u548c\u9ed8\u8ba4\u8bbe\u7f6e\uff0c\u901a\u8fc7\u5168\u5c40\u53c2\u6570\u6765\u5b9a\u5236\uff0c\u5305\u62ec\u56fe\u5f62\u5927\u5c0f\u3001\u5b50\u56fe\u95f4\u8ddd\u3001\u989c\u8272\u3001\u5b57\u4f53\u5927\u5c0f\u548c\u7f51\u683c\u6837\u5f0f\u7b49\u7b49\u3002 \u4f7f\u7528 rc \u65b9\u6cd5\u662f\u4f7f\u7528Python\u7f16\u7a0b\u4fee\u6539\u914d\u7f6e\u7684\u4e00\u79cd\u65b9\u5f0f\u3002 rc \u7684\u7b2c\u4e00\u4e2a\u53c2\u6570\u662f\u4f60\u60f3\u8981\u81ea\u5b9a\u4e49\u7684\u7ec4\u4ef6\uff0c\u6bd4\u5982 'figure'\u3001'axes'\u3001'xtick'\u3001'ytick'\u3001'grid'\u3001'legend' \u7b49\u7b49\u3002 \u4e4b\u540e\uff0c\u53ef\u4ee5\u6309\u7167\u5173\u952e\u5b57\u53c2\u6570\u7684\u5e8f\u5217\u6307\u5b9a\u65b0\u53c2\u6570\u3002 \u5b57\u5178\u662f\u4e00\u79cd\u5728\u7a0b\u5e8f\u4e2d\u8bbe\u7f6e\u9009\u9879\u7684\u7b80\u5355\u65b9\u5f0f\u3002\u6bd4\u5982\uff1a plt.rc('figure', figsize=(10, 10)) font_options = { 'family': 'monospace', 'weight': 'bold', 'size': 'small' } plt.rc('font', **font_options)","title":"matplotlib\u8bbe\u7f6e"},{"location":"python/DataAnalysis/ch06/#pandasseaborn","text":"pandas\u81ea\u8eab\u6709\u5f88\u591a\u5185\u5efa\u65b9\u6cd5\u53ef\u4ee5\u7b80\u5316\u4eceDataFrame\u548cSeries\u5bf9\u8c61\u751f\u6210\u53ef\u89c6\u5316\u7684\u8fc7\u7a0b\u3002 \u53e6\u4e00\u4e2a\u5e93\u662f seaborn \u3002 seaborn \u7b80\u5316\u4e86\u5f88\u591a\u5e38\u7528\u53ef\u89c6\u5316\u7c7b\u578b\u7684\u751f\u6210\u3002 \u5bfc\u5165 seaborn \u4f1a\u4fee\u6539\u9ed8\u8ba4\u7684matplotlib\u914d\u8272\u65b9\u6848\u548c\u7ed8\u56fe\u6837\u5f0f\uff0c\u8fd9\u4f1a\u63d0\u9ad8\u56fe\u8868\u7684\u53ef\u8bfb\u6027\u548c\u7f8e\u89c2\u6027\u3002 \u5373\u4f7f\u4e0d\u4f7f\u7528seaborn\u7684API\uff0c\u4e5f\u53ef\u4ee5\u5bfc\u5165seaborn\u6765\u4e3a\u901a\u7528matplotlib\u56fe\u8868\u63d0\u4f9b\u66f4\u597d\u7684\u89c6\u89c9\u7f8e\u89c2\u5ea6\u3002 import pandas as pd import numpy as np import matplotlib.pyplot as plt import seaborn as sns","title":"\u4f7f\u7528pandas\u548cseaborn\u7ed8\u56fe"},{"location":"python/DataAnalysis/ch06/#_5","text":"Series\u548cDataFrame\u90fd\u6709\u4e00\u4e2a plot \u5c5e\u6027\uff0c\u7528\u4e8e\u7ed8\u5236\u57fa\u672c\u7684\u56fe\u5f62\u3002\u9ed8\u8ba4\u60c5\u51b5\u4e0b\uff0c plot() \u7ed8\u5236\u7684\u662f\u6298\u7ebf\u56fe\u3002 Series\u7684 plot \u53c2\u6570\uff1a ax: matplotlib\u5b50\u56fe\u5bf9\u8c61axes\uff0c\u5982\u679c\u6ca1\u6709\u4f20\u503c\uff0c\u5219\u4f7f\u7528\u5f53\u524d\u6d3b\u52a8\u7684\u5b50\u56fe\u9ed8\u8ba4\u4f7f\u7528gca() alpha: \u56fe\u7247\u4e0d\u900f\u660e\u5ea6\uff080\u52301\uff09 data: \u6570\u636e\u5e8f\u5217Series figsize: \u56fe\u50cf\u5c3a\u5bf8\uff0ctuple(\u5bbd\u5ea6\uff0c\u9ad8\u5ea6)\uff0c\u6ce8\u610f\u8fd9\u91cc\u7684\u5355\u4f4d\u662f\u82f1\u5bf8 fontsize: \u8bbe\u7f6e\u523b\u5ea6\u6807\u7b7e\uff08xticks, yticks\uff09\u7684\u5927\u5c0f grid: \u7f51\u683c\u7ebf\uff08\u9ed8\u8ba4\u662f\u6253\u5f00\u7684\uff09 kind: \u56fe\u7c7b\u578b\uff1a\u6298\u7ebf\u56fe\uff0c\u67f1\u5f62\u56fe\uff0c\u6a2a\u5411\u67f1\u5f62\u56fe\uff0c\u76f4\u65b9\u56fe\uff0c\u7bb1\u7ebf\u56fe\uff0c\u5bc6\u5ea6\u56fe\uff0c\u9762\u79ef\u56fe\uff0c\u997c\u56fe label: \u5217\u7684\u522b\u540d\uff0c\u4f5c\u7528\u5728\u56fe\u4f8b\u4e0a legend: \u56fe\u4f8b loglog: x,y\u8f74\u90fd\u4f7f\u7528\u5bf9\u6570\u523b\u5ea6 logx: x\u8f74\u4f7f\u7528\u5bf9\u6570\u523b\u5ea6 logy: y\u8f74\u4f7f\u7528\u5bf9\u6570\u523b\u5ea6 mark_right: \u53cc y \u8f74\u65f6\uff0c\u5728\u56fe\u4f8b\u4e2d\u7684\u5217\u6807\u7b7e\u65c1\u589e\u52a0\u663e\u793a (right) \u6807\u8bc6 position: \u67f1\u5f62\u56fe\u7684\u67f1\u5b50\u7684\u4f4d\u7f6e\u8bbe\u7f6e rot: \u6539\u53d8\u523b\u5ea6\u6807\u7b7e\uff08xticks, yticks\uff09\u7684\u65cb\u8f6c\u5ea6\uff080\u5230360\uff09 secondary_y: \u53cc y \u8f74\uff0c\u5728\u53f3\u8fb9\u7684\u7b2c\u4e8c\u4e2a y \u8f74 style: \u7ebf\u7684\u6837\u5f0f\uff0c\u6bd4\u5982'ko--' table: \u5c06\u6570\u636e\u4ee5\u8868\u683c\u7684\u5f62\u5f0f\u5c55\u793a\u51fa\u6765 title: \u6807\u9898 use_index: \u662f\u5426\u4f7f\u7528\u7d22\u5f15\u4f5c\u4e3ax\u523b\u5ea6\u6807\u7b7e xerr: \u5e26\u8bef\u5dee\u7ebf\u7684\u67f1\u5f62\u56fe xlim: \u6a2a\u8f74\u5750\u6807\u523b\u5ea6\u7684\u53d6\u503c\u8303\u56f4 xticks: x\u8f74\u523b\u5ea6\u6807\u7b7e yerr: \u5e26\u8bef\u5dee\u7ebf\u7684\u67f1\u5f62\u56fe ylim: \u7eb5\u8f74\u5750\u6807\u523b\u5ea6\u7684\u53d6\u503c\u8303\u56f4 yticks: y\u8f74\u523b\u5ea6\u6807\u7b7e **kwds: matplotlib plot\u65b9\u6cd5\u7684\u5176\u4ed6\u53c2\u6570 DataFrame\u7684 plot \u53c2\u6570\uff1a x : \u6307\u6570\u636e\u6846\u5217\u7684\u6807\u7b7e\u6216\u4f4d\u7f6e\u53c2\u6570 y : \u6307\u6570\u636e\u6846\u5217\u7684\u6807\u7b7e\u6216\u4f4d\u7f6e\u53c2\u6570 kind : 'line' : \u6298\u7ebf\u56fe 'bar' : \u6761\u5f62\u56fe 'barh' : \u6a2a\u5411\u6761\u5f62\u56fe 'hist' : \u67f1\u72b6\u56fe 'box' : \u7bb1\u7ebf\u56fe 'kde' : Kernel\u7684\u5bc6\u5ea6\u4f30\u8ba1\u56fe\uff0c\u4e3b\u8981\u5bf9\u67f1\u72b6\u56fe\u6dfb\u52a0Kernel \u6982\u7387\u5bc6\u5ea6\u7ebf 'density' : 'kde' 'area' : area plot 'pie' : \u997c\u56fe 'scatter' : \u6563\u70b9\u56fe \u9700\u8981\u4f20\u5165columns\u65b9\u5411\u7684\u7d22\u5f15 'hexbin' : hexbin plot ax : \u5b50\u56fe(axes, \u4e5f\u53ef\u4ee5\u7406\u89e3\u6210\u5750\u6807\u8f74) \u8981\u5728\u5176\u4e0a\u8fdb\u884c\u7ed8\u5236\u7684matplotlib subplot\u5bf9\u8c61\u3002\u5982\u679c\u6ca1\u6709\u8bbe\u7f6e\uff0c\u5219\u4f7f\u7528\u5f53\u524dmatplotlib subplot\u3002\u5176\u4e2d\uff0c\u53d8\u91cf\u548c\u51fd\u6570\u901a\u8fc7\u6539\u53d8figure\u548caxes\u4e2d\u7684\u5143\u7d20\uff08\u4f8b\u5982\uff1atitle,label,\u70b9\u548c\u7ebf\u7b49\u7b49\uff09\u4e00\u8d77\u63cf\u8ff0figure\u548caxes\uff0c\u4e5f\u5c31\u662f\u5728\u753b\u5e03\u4e0a\u7ed8\u56fe\u3002 subplots : \u5224\u65ad\u56fe\u7247\u4e2d\u662f\u5426\u6709\u5b50\u56fe sharex : \u5982\u679c\u6709\u5b50\u56fe\uff0c\u5b50\u56fe\u5171x\u8f74\u523b\u5ea6\uff0c\u6807\u7b7e sharey : \u5982\u679c\u6709\u5b50\u56fe\uff0c\u5b50\u56fe\u5171y\u8f74\u523b\u5ea6\uff0c\u6807\u7b7e layout : \u5b50\u56fe\u7684\u884c\u5217\u5e03\u5c40 figsize : \u56fe\u7247\u5c3a\u5bf8\u5927\u5c0f use_index : \u9ed8\u8ba4\u7528\u7d22\u5f15\u505ax\u8f74 title : \u56fe\u7247\u7684\u6807\u9898\u7528\u5b57\u7b26\u4e32 grid : \u56fe\u7247\u662f\u5426\u6709\u7f51\u683c legend : \u5b50\u56fe\u7684\u56fe\u4f8b\uff0c\u6dfb\u52a0\u4e00\u4e2asubplot\u56fe\u4f8b(\u9ed8\u8ba4\u4e3aTrue) style : \u5bf9\u6bcf\u5217\u6298\u7ebf\u56fe\u8bbe\u7f6e\u7ebf\u7684\u7c7b\u578b logx : \u8bbe\u7f6ex\u8f74\u523b\u5ea6\u662f\u5426\u53d6\u5bf9\u6570 logy : \u8bbe\u7f6ey\u8f74\u523b\u5ea6\u662f\u5426\u53d6\u5bf9\u6570 loglog : \u540c\u65f6\u8bbe\u7f6ex\uff0cy\u8f74\u523b\u5ea6\u662f\u5426\u53d6\u5bf9\u6570 xticks : \u8bbe\u7f6ex\u8f74\u523b\u5ea6\u503c\uff0c\u5e8f\u5217\u5f62\u5f0f\uff08\u6bd4\u5982\u5217\u8868\uff09 yticks : \u8bbe\u7f6ey\u8f74\u523b\u5ea6\uff0c\u5e8f\u5217\u5f62\u5f0f\uff08\u6bd4\u5982\u5217\u8868\uff09 xlim : \u8bbe\u7f6e\u5750\u6807\u8f74x\u7684\u8303\u56f4\uff0c\u5217\u8868\u6216\u5143\u7ec4\u5f62\u5f0f ylim : \u8bbe\u7f6e\u5750\u6807\u8f74y\u7684\u8303\u56f4\uff0c\u5217\u8868\u6216\u5143\u7ec4\u5f62\u5f0f rot : \u8bbe\u7f6e\u8f74\u6807\u7b7e\uff08\u8f74\u523b\u5ea6\uff09\u7684\u663e\u793a\u65cb\u8f6c\u5ea6\u6570 fontsize : \u8bbe\u7f6e\u8f74\u523b\u5ea6\u7684\u5b57\u4f53\u5927\u5c0f colormap : \u8bbe\u7f6e\u56fe\u7684\u533a\u57df\u989c\u8272 colorbar : \u56fe\u7247\u67f1\u5b50 position : Specify relative alignments for bar plot layout. From 0 (left/bottom-end) to 1 (right/top-end). Default is 0.5 (center) layout : \u5e03\u5c40(rows, columns) for the layout of the plot table : \u5982\u679c\u4e3a\u6b63\uff0c\u5219\u9009\u62e9DataFrame\u7c7b\u578b\u7684\u6570\u636e\u5e76\u4e14\u8f6c\u6362\u5339\u914dmatplotlib\u7684\u5e03\u5c40 yerr : \u5e26\u8bef\u5dee\u7ebf\u7684\u67f1\u5f62\u56fe xerr : \u5e26\u8bef\u5dee\u7ebf\u7684\u67f1\u5f62\u56fe stacked : \u751f\u6210\u5806\u79ef\u67f1\u72b6\u56fe sort_columns : \u4ee5\u5b57\u6bcd\u8868\u987a\u5e8f\u7ed8\u5236\u5404\u5217\uff0c\u9ed8\u8ba4\u4f7f\u7528\u524d\u5217\u987a\u5e8f secondary_y : \u8bbe\u7f6e\u7b2c\u4e8c\u4e2ay\u8f74\uff08\u53f3y\u8f74\uff09 mark_right : When using a secondary_y axis, automatically mark the column labels with \u201c(right)\u201d in the legend kwds : Options to pass to matplotlib plotting method Series data1 = np.random.randn(10).cumsum(0) s1 = pd.Series( data1, index=np.arange(0, 100, 10), ) print(s1) fig, axes = plt.subplots(3, 1) # 3\u4e2a\u5b50\u56fe s1.plot.bar(ax=axes[0], color='k', alpha=0.7) # \u6761\u5f62\u56fe(\u5b50\u56fe0)\uff0ccolor='k\u2019(\u67f1\u5b50\u7684\u989c\u8272\u8bbe\u7f6e\u4e3a\u9ed1\u8272)\uff0calpha=0.7(\u56fe\u50cf\u7684\u586b\u5145\u8272\u8bbe\u7f6e\u4e3a\u90e8\u5206\u900f\u660e) s1.plot.barh(ax=axes[1], color='k', alpha=0.7) # \u6a2a\u5411\u6761\u5f62\u56fe(\u5b50\u56fe1) s1.value_counts().plot.pie(ax=axes[2]) # \u901a\u8fc7value_counts()\u5bf9Series\u503c\u9891\u7387\u8fdb\u884c\u53ef\u89c6\u5316 plt.show() DataFrame data2 = np.random.randn(10, 4).cumsum(0) df1 = pd.DataFrame( data2, columns=pd.Index(['A', 'B', 'C', 'D'], name='Genus'), index=np.arange(0, 100, 10) ) print(df1) fig, axes = plt.subplots(2, 1) # 2\u4e2a\u5b50\u56fe df1.plot.kde(ax=axes[0], alpha=0.7, grid='True', title='KDE Figure', sharex=True) df1.plot.bar(ax=axes[1], grid='True', title='Line Figure', sharex=True, use_index=False, stacked=True) # \u56e0\u4e3a\u5171\u4eabx\u8f74\uff0c\u6240\u4ee5\u5728KDE\u5b50\u56fe\u4e2d\u6307\u5b9ause_index=False\u770b\u4e0d\u51fa\u6548\u679c\u3002 # DataFrame\u7684\u5217\u540d\u79f0\"Genus\"\u88ab\u7528\u4f5c\u4e86\u56fe\u4f8b\u6807\u9898 # stacked=True\u6765\u751f\u6210\u5806\u79ef\u67f1\u72b6\u56fe plt.show() \u5b9e\u4f8b\uff1a\u7ed8\u5236\u4e00\u4e2a\u5806\u79ef\u67f1\u72b6\u56fe\uff0c\u7528\u4e8e\u5c55\u793a\u6bcf\u4e2a\u6d3e\u5bf9\u5728\u6bcf\u5929\u7684\u6570\u636e\u70b9\u5360\u6bd4\u3002 \u4ea4\u53c9\u8868 \u662f\u4e00\u79cd\u5e38\u7528\u7684\u5206\u7c7b\u6c47\u603b\u8868\u683c\uff0c\u7528\u4e8e\u9891\u6570\u5206\u5e03\u7edf\u8ba1\uff0c\u4e3b\u8981\u4ef7\u503c\u5728\u4e8e\u63cf\u8ff0\u4e86\u53d8\u91cf\u95f4\u5173\u7cfb\u7684\u6df1\u523b\u542b\u4e49\u3002 \u867d\u7136\u4e24\u4e2a\uff08\u6216\u4ee5\u4e0a\uff09\u53d8\u91cf\u53ef\u4ee5\u662f\u5206\u7c7b\u7684\u6216\u6570\u91cf\u7684\uff0c\u4f46\u662f\u4ee5\u90fd\u662f\u5206\u7c7b\u7684\u60c5\u5f62\u6700\u4e3a\u5e38\u89c1\u3002 Pandas\u7684 crosstab() \u65b9\u6cd5\u80fd\u591f\u5feb\u901f\u6784\u5efa\u4ea4\u53c9\u8868\uff0c\u5e76\u53ef\u4ee5\u901a\u8fc7\u53c2\u6570\u52a0\u4ee5\u4e2a\u6027\u5316\u7684\u8bbe\u7f6e\u3002\u5176\u4e2d\uff0c\u7b2c\u4e00\u4e2a\u53c2\u6570\u5c06\u6784\u6210\u4ea4\u53c9\u8868\u7684\u884c\uff0c\u7b2c\u4e8c\u4e2a\u53c2\u6570\u5c06\u6784\u6210\u4ea4\u53c9\u8868\u7684\u5217\u3002 tips = pd.read_csv('../examples/tips.csv') print(tips) # total_bill tip smoker day time size # 0 16.99 1.01 No Sun Dinner 2 # 1 10.34 1.66 No Sun Dinner 3 # 2 21.01 3.50 No Sun Dinner 3 # 3 23.68 3.31 No Sun Dinner 2 # 4 24.59 3.61 No Sun Dinner 4 # .. ... ... ... ... ... ... # 239 29.03 5.92 No Sat Dinner 3 # 240 27.18 2.00 Yes Sat Dinner 2 # 241 22.67 2.00 Yes Sat Dinner 2 # 242 17.82 1.75 No Sat Dinner 2 # 243 18.78 3.00 No Thur Dinner 2 # [244 rows x 6 columns] party_counts = pd.crosstab(tips['day'], tips['size']) # \u5bf9\u539f\u59cb\u6570\u636e\u7684day\u548csize\u8fdb\u884c\u805a\u5408\uff0c\u5e76\u6784\u5efa\u4ea4\u53c9\u8868\uff0cday\u4f5c\u4e3a\u884c\uff0csize\u4f5c\u4e3a\u5217\u3002 print(party_counts) # size 1 2 3 4 5 6 # day # Fri 1 16 1 1 0 0 # Sat 2 53 18 13 1 0 # Sun 0 39 15 18 3 1 # Thur 1 48 4 5 1 3 # \u6ca1\u6709\u592a\u591a\u76841\u4eba\u548c6\u4eba\u6d3e\u5bf9\uff0c\u820d\u5f03\u8fd9\u4e9b\u6570\u636e party_counts = party_counts.loc[:, 2:5] print(party_counts) # size 2 3 4 5 # day # Fri 16 1 1 0 # Sat 53 18 13 1 # Sun 39 15 18 3 # Thur 48 4 5 1 # \u6807\u51c6\u5316\u81f3\u548c\u4e3a1\uff1a\u6cbf0\u8f74\uff08\u884c\uff09\u5bf9\u6bcf\u5217\u6c42\u548c\uff0c\u6bcf\u884c\u5404\u503c\u9664\u4ee5\u548c\uff0c\u4ee5\u786e\u4fdd\u6bcf\u4e00\u884c\u7684\u503c\u548c\u4e3a1\uff0c\u7136\u540e\u8fdb\u884c\u7ed8\u56fe party_pcts = party_counts.div(party_counts.sum(1), axis=0) print(party_pcts) # size 2 3 4 5 # day # Fri 0.888889 0.055556 0.055556 0.000000 # Sat 0.623529 0.211765 0.152941 0.011765 # Sun 0.520000 0.200000 0.240000 0.040000 # Thur 0.827586 0.068966 0.086207 0.017241 party_counts.plot.bar() plt.show() \u53ef\u4ee5\u770b\u5230\u672c\u6570\u636e\u96c6\u4e2d\u7684\u6d3e\u5bf9\u6570\u91cf\u5728\u5468\u672b\u4f1a\u589e\u52a0\u3002 \u5b9e\u4f8b\uff1a\u4f7f\u7528seaborn\u8fdb\u884c\u6309\u661f\u671f\u65e5\u671f\u8ba1\u7b97\u5c0f\u8d39\u767e\u5206\u6bd4\u3002 Seaborn\u8981\u6c42\u6570\u636e\u7684\u8f93\u5165\u7c7b\u578b\u4e3apandas\u7684Dataframe\u6216Numpy\u6570\u7ec4\u3002 tips['tip_pct'] = tips['tip'] / (tips['total_bill'] - tips['tip']) print(tips) # total_bill tip smoker day time size tip_pct # 0 16.99 1.01 No Sun Dinner 2 0.063204 # 1 10.34 1.66 No Sun Dinner 3 0.191244 # 2 21.01 3.50 No Sun Dinner 3 0.199886 # 3 23.68 3.31 No Sun Dinner 2 0.162494 # 4 24.59 3.61 No Sun Dinner 4 0.172069 # .. ... ... ... ... ... ... ... # 239 29.03 5.92 No Sat Dinner 3 0.256166 # 240 27.18 2.00 Yes Sat Dinner 2 0.079428 # 241 22.67 2.00 Yes Sat Dinner 2 0.096759 # 242 17.82 1.75 No Sat Dinner 2 0.108899 # 243 18.78 3.00 No Thur Dinner 2 0.190114 # [244 rows x 7 columns] # barplot: \u5c06\u70b9\u4f30\u8ba1\u548c\u7f6e\u4fe1\u533a\u95f4\u663e\u793a\u4e3a\u77e9\u5f62\u6761\u3002\u6761\u5f62\u56fe\u8868\u793a\u5177\u6709\u6bcf\u4e2a\u77e9\u5f62\u7684\u9ad8\u5ea6\u7684\u6570\u503c\u53d8\u91cf\u7684\u96c6\u4e2d\u8d8b\u52bf\u7684\u4f30\u8ba1\uff0c\u5e76\u4e14\u4f7f\u7528\u8bef\u5dee\u6761\u63d0\u4f9b\u56f4\u7ed5\u8be5\u4f30\u8ba1\u7684\u4e0d\u786e\u5b9a\u6027\u7684\u4e00\u4e9b\u6307\u793a # \u67f1\u5b50\u7684\u503c\u662ftip_pct\u7684\u5e73\u5747\u503c # \u67f1\u5b50\u4e0a\u753b\u51fa\u7684\u9ed1\u7ebf\u4ee3\u8868\u7684\u662f95%\u7684\u7f6e\u4fe1\u533a\u95f4\uff08\u7f6e\u4fe1\u533a\u95f4\u53ef\u4ee5\u901a\u8fc7\u53ef\u9009\u53c2\u6570\u8fdb\u884c\u8bbe\u7f6e\uff09 # hue\u9009\u9879\uff0c\u5141\u8bb8\u6211\u4eec\u901a\u8fc7\u4e00\u4e2a\u989d\u5916\u7684\u5206\u7c7b\u503c\u5c06\u6570\u636e\u5206\u79bb # \u5e26\u53c2\u6570hue='time'\u65f6\uff0c\u56db\u4e2a\u4e0d\u540c\u989c\u8272\u7684\u67f1\u5b50\uff0c\u6bcf\u4e2a\u67f1\u5b50\u4e0a\u6709\u7f6e\u4fe1\u533a\u95f4\u7684\u9ed1\u7ebf\uff0c\u523b\u5ea60.00~0.30\uff0c\u6b65\u957f0.05 # \u4e0d\u5e26\u53c2\u6570hue='time'\u65f6\uff0c\u4e24\u4e2a\u4e0d\u540c\u989c\u8272\u7684\u67f1\u5b50\uff0c\u5206\u522b\u4ee3\u8868Dinner\u548cLunch\uff0c\u4e0d\u662f\u6bcf\u4e2a\u67f1\u5b50\u4e0a\u90fd\u6709\u7f6e\u4fe1\u533a\u95f4\u7684\u9ed1\u7ebf\uff0c\u523b\u5ea60.00~0.30\uff0c\u6b65\u957f0.05 sns.barplot(x='tip_pct', y='day', data=tips, hue='time', orient='h') # \u6839\u636e\u661f\u671f\u65e5\u671f\u548c\u65f6\u95f4\u8ba1\u7b97\u7684\u5c0f\u8d39\u767e\u5206\u6bd4 # sns.barplot(x='tip_pct', y='day', data=tips, orient='h') sns.set(style=\"darkgrid\", palette=\"deep\") # style=\"whitegrid\" plt.show()","title":"\u6298\u7ebf\u56fe"},{"location":"python/DataAnalysis/ch06/#_6","text":"\u76f4\u65b9\u56fe\u662f\u4e00\u79cd\u6761\u5f62\u56fe\uff0c\u7528\u4e8e\u7ed9\u51fa\u503c\u9891\u7387\u7684\u79bb\u6563\u663e\u793a\u3002\u6570\u636e\u70b9\u88ab\u5206\u6210\u79bb\u6563\u7684\uff0c\u5747\u5300\u95f4\u9694\u7684\u7bb1\uff0c\u5e76\u4e14\u7ed8\u5236\u6bcf\u4e2a\u7bb1\u4e2d\u6570\u636e\u70b9\u7684\u6570\u91cf\u3002 tips['tip_pct'].plot.hist(bins=50) # \u5c0f\u8d39\u767e\u5206\u6bd4\u7684\u76f4\u65b9\u56fe plt.show() \u5bc6\u5ea6\u56fe\u662f\u4e00\u79cd\u4e0e\u76f4\u65b9\u56fe\u76f8\u5173\u7684\u56fe\u8868\u7c7b\u578b\uff0c\u5b83\u901a\u8fc7\u8ba1\u7b97\u53ef\u80fd\u4ea7\u751f\u89c2\u6d4b\u6570\u636e\u7684\u8fde\u7eed\u6982\u7387\u5206\u5e03\u4f30\u8ba1\u800c\u4ea7\u751f\u3002 \u901a\u5e38\u7684\u505a\u6cd5\u662f\u5c06\u8fd9\u79cd\u5206\u5e03\u8fd1\u4f3c\u4e3a\u201c\u5185\u6838\u201d\u7684\u6df7\u5408\uff0c\u4e5f\u5c31\u662f\u50cf\u6b63\u6001\u5206\u5e03\u90a3\u6837\u7b80\u5355\u7684\u5206\u5e03\u3002 \u56e0\u6b64\uff0c\u5bc6\u5ea6\u56fe\u4e5f\u88ab\u79f0\u4e3a\u5185\u6838\u5bc6\u5ea6\u4f30\u8ba1\u56fe\uff08KDE\uff09\u3002 tips['tip_pct'].plot.density() # \u5c0f\u8d39\u767e\u5206\u6bd4\u5bc6\u5ea6\u56fe plt.show() \u7ed8\u5236\u76f4\u65b9\u56fe\u548c\u8fde\u7eed\u5bc6\u5ea6\u4f30\u8ba1 sns.displot() \u3002 sns.distplot(tips['tip_pct'], bins=100, color='k') plt.show() # FutureWarning: `distplot` is a deprecated function and will be removed in a future version. # Please adapt your code to use either `displot` (a figure-level function with similar flexibility) # or `histplot` (an axes-level function for histograms).","title":"\u76f4\u65b9\u56fe\u548c\u5bc6\u5ea6\u56fe"},{"location":"python/DataAnalysis/ch06/#_7","text":"\u70b9\u56fe\u6216\u6563\u70b9\u56fe\u53ef\u4ee5\u7528\u4e8e\u68c0\u9a8c\u4e24\u4e2a\u4e00\u7ef4\u6570\u636e\u5e8f\u5217\u4e4b\u95f4\u7684\u5173\u7cfb\u3002 \u5b9e\u4f8b\uff1a\u4ece statsmodels \u9879\u76ee\u4e2d\u8f7d\u5165\u4e86macrodata\u6570\u636e\u96c6\uff0c\u5e76\u9009\u62e9\u4e86\u4e00\u4e9b\u53d8\u91cf\uff0c\u4e4b\u540e\u8ba1\u7b97\u5bf9\u6570\u5dee\u3002 macro = pd.read_csv('../examples/macrodata.csv') print(macro.head(5)) # year quarter realgdp realcons ... unemp pop infl realint # 0 1959.0 1.0 2710.349 1707.4 ... 5.8 177.146 0.00 0.00 # 1 1959.0 2.0 2778.801 1733.7 ... 5.1 177.830 2.34 0.74 # 2 1959.0 3.0 2775.488 1751.8 ... 5.3 178.657 2.74 1.09 # 3 1959.0 4.0 2785.204 1753.7 ... 5.6 179.386 0.27 4.06 # 4 1960.0 1.0 2847.699 1770.5 ... 5.2 180.007 2.31 1.19 # [5 rows x 14 columns] data = macro[['cpi', 'm1', 'tbilrate', 'unemp']] print(data.head(5)) # cpi m1 tbilrate unemp # 0 28.98 139.7 2.82 5.8 # 1 29.15 141.7 3.08 5.1 # 2 29.35 140.5 3.82 5.3 # 3 29.37 140.0 4.33 5.6 # 4 29.54 139.6 3.50 5.2 trans_data = np.log(data).diff().dropna() print(trans_data[-5:]) # cpi m1 tbilrate unemp # 198 -0.007904 0.045361 -0.396881 0.105361 # 199 -0.021979 0.066753 -2.277267 0.139762 # 200 0.002340 0.010286 0.606136 0.160343 # 201 0.008419 0.037461 -0.200671 0.127339 # 202 0.008894 0.012202 -0.405465 0.042560 \u7528 seaborn \u7684 regplot \u65b9\u6cd5\u7ed8\u5236\u6563\u70b9\u56fe\uff0c\u5e76\u62df\u5408\u51fa\u4e00\u4e2a\u6761\u7ebf\u6027\u56de\u5f52\u7ebf\u3002( seaborn\u6587\u6863 ) sns.regplot('m1', 'unemp', data=trans_data) plt.title('Changes in log %s versus log %s ' % ('m1', 'unemp')) plt.show() \u5728\u63a2\u7d22\u6027\u6570\u636e\u5206\u6790\u4e2d\uff0c\u80fd\u591f\u67e5\u770b\u4e00\u7ec4\u53d8\u91cf\u4e2d\u7684\u6240\u6709\u6563\u70b9\u56fe\u662f\u6709\u5e2e\u52a9\u7684\uff0c\u8fd9\u88ab\u79f0\u4e3a\u6210\u5bf9\u56fe\u6216\u6563\u70b9\u56fe\u77e9\u9635\u3002 Seaborn\u6709\u4e00\u4e2a\u65b9\u4fbf\u7684 pairplot \u51fd\u6570\uff0c\u5b83\u652f\u6301\u5728\u5bf9\u89d2\u7ebf\u4e0a\u653e\u7f6e\u6bcf\u4e2a\u53d8\u91cf\u7684\u76f4\u65b9\u56fe\u6216\u5bc6\u5ea6\u4f30\u8ba1\u503c\u3002 plot_ksw \u53c2\u6570\u80fd\u591f\u5c06\u914d\u7f6e\u9009\u9879\u4f20\u9012\u7ed9\u975e\u5bf9\u89d2\u5143\u7d20\u4e0a\u7684\u5404\u4e2a\u7ed8\u56fe\u8c03\u7528\u3002 sns.pairplot(trans_data, diag_kind='kde', plot_kws={'alpha': 0.2}) plt.show()","title":"\u6563\u70b9\u56fe\u6216\u70b9\u56fe"},{"location":"python/DataAnalysis/ch06/#_8","text":"\u5982\u679c\u6570\u636e\u96c6\u6709\u989d\u5916\u7684\u5206\u7ec4\u7ef4\u5ea6\u600e\u4e48\u529e\uff1f\u4f7f\u7528\u5206\u9762\u7f51\u683c\u662f\u5229\u7528\u591a\u79cd\u5206\u7ec4\u53d8\u91cf\u5bf9\u6570\u636e\u8fdb\u884c\u53ef\u89c6\u5316\u7684\u65b9\u5f0f\u3002 seaborn\u62e5\u6709\u4e00\u4e2a\u6709\u6548\u7684\u5185\u5efa\u51fd\u6570 factorplot \uff0c\u5b83\u53ef\u4ee5\u7b80\u5316\u591a\u79cd\u5206\u9762\u7ed8\u56fe\u3002 sns.factorplot(x='day', y='tip_pct', hue='time', col='smoker', kind='bar', data=tips[tips.tip_pct < 1]) plt.show() # UserWarning: The `factorplot` function has been renamed to `catplot`. # The original name will be removed in a future release. Please update your code. # Note that the default `kind` in `factorplot` (`'point'`) has changed `'strip'` in `catplot`. sns.catplot(x='day', y='tip_pct', hue='time', col='smoker', kind='box', data=tips[tips.tip_pct < 0.5]) plt.show()","title":"\u5206\u9762\u7f51\u683c\u548c\u5206\u7c7b\u6570\u636e"},{"location":"python/DataAnalysis/ch06/#python","text":"\u81ea2010\u5e74\u4ee5\u6765\uff0c\u5f88\u591a\u5f00\u53d1\u5de5\u4f5c\u90fd\u96c6\u4e2d\u5728\u521b\u5efaweb\u4ea4\u4e92\u5f0f\u56fe\u5f62\u4e0a\u3002 \u501f\u52a9\u50cf Bokeh \u548c Plotly \u8fd9\u6837\u7684\u5de5\u5177\uff0c\u5728web\u6d4f\u89c8\u5668\u4e2d\u521b\u5efa\u52a8\u6001\u7684\u3001\u4ea4\u4e92\u5f0f\u56fe\u50cf\u7684\u5de5\u4f5c\u73b0\u5728\u5df2\u7ecf\u53ef\u4ee5\u5b9e\u73b0\u3002 \u53ef\u89c6\u5316\u662f\u4e00\u4e2a\u6d3b\u8dc3\u7684\u7814\u7a76\u9886\u57df\u3002","title":"\u5176\u4ed6Python\u53ef\u89c6\u5316\u5de5\u5177"},{"location":"python/DataAnalysis/ch07/","text":"\u6570\u636e\u805a\u5408\u4e0e\u5206\u7ec4\u64cd\u4f5c \u00b6 GroupBy\u673a\u5236 \u00b6 import pandas as pd import numpy as np \u5206\u7ec4\u673a\u5236 \u00b6 \u5206\u7ec4\u64cd\u4f5c\u7b2c\u4e00\u6b65\uff0c\u6570\u636e\u5305\u542b\u5728pandas\u5bf9\u8c61\u4e2d\uff0c\u53ef\u4ee5\u662fSeries\u3001DataFrame\u6216\u5176\u4ed6\u6570\u636e\u7ed3\u6784\u3002\u4e4b\u540e\u6839\u636e\u63d0\u4f9b\u7684\u4e00\u4e2a\u6216\u591a\u4e2a\u952e\u5206\u79bb\u5230\u5404\u4e2a\u7ec4\u4e2d\u3002 \u5206\u7ec4\u952e\u53ef\u662f\u591a\u79cd\u5f62\u5f0f\u7684\uff0c\u5e76\u4e14\u952e\u4e0d\u4e00\u5b9a\u662f\u5b8c\u5168\u76f8\u540c\u7684\u7c7b\u578b(\u6ce8\u610f\u540e\u9762\u4ecb\u7ecd\u7684\u4e09\u4e2a\u65b9\u6cd5\u662f\u53ef\u4ee5\u4ea7\u751f\u7528\u4e8e\u5206\u9694\u5bf9\u8c61\u7684\u503c\u6570\u7ec4\u7684\u5feb\u6377\u65b9\u5f0f)\uff1a \u4e0e\u9700\u8981\u5206\u7ec4\u7684\u8f74\u5411\u957f\u5ea6\u4e00\u81f4\u7684\u503c\u5217\u8868\u6216\u503c\u6570\u7ec4\u3002\u9ed8\u8ba4\u60c5\u51b5\u4e0b\uff0cgroupby\u5728axis=0\u7684\u8f74\u5411\u4e0a\u5206\u7ec4\u3002 DataFrame\u7684\u5217\u540d\u7684\u503c\u3002 \u53ef\u4ee5\u5c06\u5206\u7ec4\u8f74\u5411\u4e0a\u7684\u503c\u548c\u5206\u7ec4\u540d\u79f0\u76f8\u5339\u914d\u7684\u5b57\u5178\u6216Series\u3002 \u53ef\u4ee5\u5728\u8f74\u7d22\u5f15\u6216\u7d22\u5f15\u4e2d\u7684\u5355\u4e2a\u6807\u7b7e\u4e0a\u8c03\u7528\u7684\u51fd\u6570\u3002 \u8bf7\u6ce8\u610f\uff0c\u5206\u7ec4\u952e\u4e2d\u7684\u4efb\u4f55\u7f3a\u5931\u503c\u5c06\u88ab\u6392\u9664\u5728\u7ed3\u679c\u4e4b\u5916\u3002 \u5206\u79bb\u64cd\u4f5c\u662f\u5728\u6570\u636e\u5bf9\u8c61\u7684\u7279\u5b9a\u8f74\u5411\u4e0a\u8fdb\u884c\u7684\u3002\u4f8b\u5982\uff0cDataFrame\u53ef\u4ee5\u5728\u5b83\u7684\u884c\u65b9\u5411\uff08axis=0\uff09\u6216\u5217\u65b9\u5411\uff08axis=1\uff09\u8fdb\u884c\u5206\u7ec4\u3002 \u5206\u7ec4\u64cd\u4f5c\u540e\uff0c\u4e00\u4e2a\u51fd\u6570\u5c31\u53ef\u4ee5\u5e94\u7528\u5230\u5404\u4e2a\u7ec4\u4e2d\uff0c\u4ea7\u751f\u65b0\u7684\u503c\u3002\u6700\u7ec8\uff0c\u6240\u6709\u51fd\u6570\u7684\u5e94\u7528\u7ed3\u679c\u4f1a\u8054\u5408\u4e3a\u4e00\u4e2a\u7ed3\u679c\u5bf9\u8c61\u3002 df = pd.DataFrame( { 'key1': ['a', 'a', 'b', 'b', 'a'], 'key2': ['one', 'two', 'one', 'two', 'one'], 'data1': [1, 3, 5, 7, 9], 'data2': [2, 4, 6, 8, 10] } ) \u6839\u636ekey1\u6807\u7b7e\u8ba1\u7b97data1\u5217\u7684\u5747\u503c\uff0c\u65b9\u6cd5\u4e00\uff0c\u8bbf\u95ee data1 \u5e76\u4f7f\u7528 key1 \u5217\uff08\u5b83\u662f\u4e00\u4e2aSeries\uff09\u8c03\u7528 groupby \u65b9\u6cd5\uff1a grouped = df['data1'].groupby(df['key1']) print(grouped) # grouped \u53d8\u91cf\u73b0\u5728\u662f\u4e00\u4e2a GroupBy \u5bf9\u8c61\uff0c\u5b83\u5b9e\u9645\u4e0a\u8fd8\u6ca1\u6709\u8fdb\u884c\u4efb\u4f55\u8ba1\u7b97\uff0c\u62e5\u6709\u4e00\u4e9b\u5173\u4e8e\u5206\u7ec4\u952edf['key1']\u7684\u4e00\u4e9b\u4e2d\u95f4\u6570\u636e\u7684\u4fe1\u606f\u3002 \u4e0b\u9762\u5bf9 grouped \u5bf9\u8c61\u505a\u4e00\u4e9b\u64cd\u4f5c\uff1a result = grouped.mean() # \u8ba1\u7b97\u5e73\u5747\u503c print(result) # key1 # a 4.333333 # b 6.000000 # Name: data1, dtype: float64 grouped_means = df['data1'].groupby([df['key1'], df['key2']]).mean() print(grouped_means) # key1 key2 # a one 5.0 # two 3.0 # b one 5.0 # two 7.0 # Name: data1, dtype: float64 \u4e0a\u9762\u4f8b\u5b50\u4f7f\u7528\u4e86\u4e24\u4e2a\u952e\u5bf9\u6570\u636e\u8fdb\u884c\u5206\u7ec4\uff0c\u5e76\u4e14\u7ed3\u679cSeries\u73b0\u5728\u62e5\u6709\u4e00\u4e2a\u5305\u542b\u552f\u4e00\u952e\u5bf9\u7684\u591a\u5c42\u7d22\u5f15\u3002 \u4e0b\u9762\u5bf9\u8ba1\u7b97\u7684\u5e73\u5747\u503c\uff08mean\uff09\u8fdb\u884c\u91cd\u5851\uff08unstack\uff09\u3002 print(grouped_means.unstack()) # key2 one two # key1 # a 5.0 3.0 # b 5.0 7.0 \u5206\u7ec4\u4fe1\u606f\u901a\u5e38\u5305\u542b\u5728\u540c\u4e00\u4e2aDataFrame\u4e2d\u3002\u5728\u8fd9\u79cd\u60c5\u51b5\u4e0b\uff0c\u53ef\u4ee5\u4f20\u9012\u5217\u540d\uff08\u65e0\u8bba\u90a3\u4e9b\u5217\u540d\u662f\u5b57\u7b26\u4e32\u3001\u6570\u5b57\u6216\u5176\u4ed6Python\u5bf9\u8c61\uff09\u4f5c\u4e3a\u5206\u7ec4\u952e\uff1a \u4e0b\u9762\u4f8b\u5b50\u4e2d df.groupby('key1').mean() \u7684\u7ed3\u679c\u91cc\u5e76\u6ca1\u6709 key2 \u5217\u3002\u8fd9\u662f\u56e0\u4e3a df['key2'] \u5e76\u4e0d\u662f\u6570\u503c\u6570\u636e\uff0c\u5373 df['key2'] \u662f\u4e00\u4e2a\u5197\u4f59\u5217\uff0c\u56e0\u6b64\u88ab\u6392\u9664\u5728\u7ed3\u679c\u4e4b\u5916\u3002 result = df.groupby('key1').mean() print(result) # data1 data2 # key1 # a 4.333333 5.333333 # b 6.000000 7.000000 result = df.groupby(['key1', 'key2']).mean() print(result) # data1 data2 # key1 key2 # a one 5.0 6.0 # two 3.0 4.0 # b one 5.0 6.0 # two 7.0 8.0 result = df.groupby(['key1', 'key2']).size() print(result) # key1 key # a one 2 # two 1 # b one 1 # two 1 # dtype: int64 \u904d\u5386\u5404\u5206\u7ec4 \u00b6 GroupBy \u5bf9\u8c61\u652f\u6301\u8fed\u4ee3\uff0c\u4f1a\u751f\u6210\u4e00\u4e2a\u5305\u542b\u7ec4\u540d\u548c\u6570\u636e\u5757\u76842\u7ef4\u5143\u7ec4\u5e8f\u5217\u3002 df = pd.DataFrame( { 'key1': ['a', 'a', 'b', 'b', 'a'], 'key2': ['one', 'two', 'one', 'two', 'one'], 'data1': [1, 3, 5, 7, 9], 'data2': [2, 4, 6, 8, 10] } ) \u5355\u4e2a\u5206\u7ec4\u952e\u7684\u60c5\u51b5: for name, group in df.groupby('key1'): print(name) print(group) # a # key1 key2 data1 data2 # 0 a one 1 2 # 1 a two 3 4 # 4 a one 9 10 # b # key1 key2 data1 data2 # 2 b one 5 6 # 3 b two 7 8 \u591a\u4e2a\u5206\u7ec4\u952e\u7684\u60c5\u51b5: \u5143\u7ec4\u4e2d\u7684\u7b2c\u4e00\u4e2a\u5143\u7d20\u662f\u952e\u503c\u7684\u5143\u7ec4\u3002 for (k1, k2), group in df.groupby(['key1', 'key2']): print((k1, k2)) print(group) # ('a', 'one') # key1 key2 data1 data2 # 0 a one 1 2 # 4 a one 9 10 # ('a', 'two') # key1 key2 data1 data2 # 1 a two 3 4 # ('b', 'one') # key1 key2 data1 data2 # 2 b one 5 6 # ('b', 'two') # key1 key2 data1 data2 # 3 b two 7 8 result = dict(list(df.groupby('key1'))) print(result) # df.groupby('key1')\u7684\u7ed3\u679c\u662f\u4e00\u4e2a\u5bf9\u8c61 # # list(df.groupby('key1'))\u7684\u7ed3\u679c\u662f\u5305\u542bFrameData\u7684\u7ed3\u6784\u7684\u5217\u8868list: # [ # ('a', key1 key2 data1 data2 # 0 a one 1 2 # 1 a two 3 4 # 4 a one 9 10), # ('b', key1 key2 data1 data2 # 2 b one 5 6 # 3 b two 7 8) # ] # dict(list(df.groupby('key1')))\u7684\u7ed3\u679c\u662f\u5305\u542bFrameData\u7684\u7ed3\u6784\u7684\u5b57\u5178dict # { # 'a': key1 key2 data1 data2 # 0 a one 1 2 # 1 a two 3 4 # 4 a one 9 10, # 'b': key1 key2 data1 data2 # 2 b one 5 6 # 3 b two 7 8 # } print(result['b']) # key1 key2 data1 data2 # 2 b one 5 6 # 3 b two 7 8 \u9ed8\u8ba4\u60c5\u51b5\u4e0b\uff0c groupby \u5728 axis=0 \u7684\u8f74\u5411\u4e0a\u5206\u7ec4\uff0c\u4e5f\u53ef\u4ee5\u5728\u5176\u4ed6\u4efb\u610f\u8f74\u5411\u4e0a\u8fdb\u884c\u5206\u7ec4\u3002 print(df.dtypes) # key1 object # key2 object # data1 int64 # data2 int64 # dtype: object grouped = df.groupby(df.dtypes, axis=1) print(grouped) # print(list(grouped)) # [ # (dtype('int64'), data1 data2 # 0 1 2 # 1 3 4 # 2 5 6 # 3 7 8 # 4 9 10), # (dtype('O'), key1 key2 # 0 a one # 1 a two # 2 b one # 3 b two # 4 a one) # ] \u6253\u5370\u5404\u5206\u7ec4\u5982\u4e0b\uff1a for dtype, group in grouped: print(dtype) print(group) # int64 # data1 data2 # 0 1 2 # 1 3 4 # 2 5 6 # 3 7 8 # 4 9 10 # object # key1 key2 # 0 a one # 1 a two # 2 b one # 3 b two # 4 a one \u9009\u62e9\u4e00\u5217\u6216\u6240\u6709\u5217\u7684\u5b50\u96c6 \u00b6 \u5bf9\u4e8e\u4eceDataFrame\u521b\u5efa\u7684 GroupBy \u5bf9\u8c61\uff0c\u7528\u5217\u540d\u79f0\u6216\u5217\u540d\u79f0\u6570\u7ec4\u8fdb\u884c\u7d22\u5f15\u65f6\uff0c\u4f1a\u4ea7\u751f\u7528\u4e8e\u805a\u5408\u7684\u5217\u5b50\u96c6\u7684\u6548\u679c\u3002 \u5982\u679c\u4f20\u9012\u7684\u662f\u5217\u8868\u6216\u6570\u7ec4\uff0c\u5219\u6b64\u7d22\u5f15\u64cd\u4f5c\u8fd4\u56de\u7684\u5bf9\u8c61\u662f\u5206\u7ec4\u7684DataFrame\uff1b\u5982\u679c\u53ea\u6709\u5355\u4e2a\u5217\u540d\u4f5c\u4e3a\u6807\u91cf\u4f20\u9012\uff0c\u5219\u4e3a\u5206\u7ec4\u7684Series\uff1b \u5bf9\u6bd4\u4e0b\u97624\u53e5\uff1a result = df.groupby('key1')['data1'] # \u5355\u4e2a\u5217\u540d print(result) # for key, data in result: print(key) print(data) result = df['data1'].groupby(df['key1']) # \u5355\u4e2a\u5217\u540d print(result) # for key, data in result: print(key) print(data) # a # 0 1 # 1 3 # 4 9 # Name: data1, dtype: int64 # b # 2 5 # 3 7 # Name: data1, dtype: int64 result = df.groupby('key1')[['data1']] # \u5217\u8868\u6216\u6570\u7ec4 print(result) # for key, data in result: print(key) print(data) # a # key1 key2 data1 data2 # 0 a one 1 2 # 1 a two 3 4 # 4 a one 9 10 # b # key1 key2 data1 data2 # 2 b one 5 6 # 3 b two 7 8 result = df[['data1']].groupby(df['key1']) # \u5217\u8868\u6216\u6570\u7ec4 print(result) # for key, data in result: print(key) print(data) # a # data1 # 0 1 # 1 3 # 4 9 # b # data1 # 2 5 # 3 7 \u4f7f\u7528\u5b57\u5178\u548cSeries\u5206\u7ec4 \u00b6 \u5206\u7ec4\u4fe1\u606f\u53ef\u80fd\u4f1a\u4ee5\u975e\u6570\u7ec4\u5f62\u5f0f\u5b58\u5728\u3002 \u751f\u6210\u4e00\u4e2a\u793a\u4f8bDataFrame\u3002 people = pd.DataFrame( [[1, 3, 5, 7, 9], [0, 2, 4, 6, 8], [0, 2, 4, 6, 8], [1, 3, 5, 7, 9], [1, 2, 3, 4, 5]], columns=['a', 'b', 'c', 'd', 'e'], index=['Joe', 'Steve', 'Wes', 'Jim', 'Travis'] ) \u6dfb\u52a0\u4e00\u4e9bNA\u503c\u3002 people.iloc[2:3, [1, 2]] = np.nan print(people) # a b c d e # Joe 1 3.0 5.0 7 9 # Steve 0 2.0 4.0 6 8 # Wes 0 NaN NaN 6 8 # Jim 1 3.0 5.0 7 9 # Travis 1 2.0 3.0 4 5 \u5047\u8bbe\u6709\u5982\u4e0b\u5404\u5217\u7684\u5206\u7ec4\u5bf9\u5e94\u5173\u7cfb\uff0c\u5e76\u4e14\u60f3\u628a\u5404\u5217\u6309\u7ec4\u7d2f\u52a0\u3002 mapping = { 'a': 'red', 'b': 'red', 'c': 'blue', 'd': 'blue', 'e': 'red', 'f': 'orange' # \u6ce8\u610f\uff1a\u5065f\u867d\u7136\u6ca1\u6709\u88ab\u7528\u5230\uff0c\u4f46\u4e0d\u5f71\u54cd\u5728\u8fd9\u91cc\u5b9a\u4e49\u3002 } \u628a mapping \u8fd9\u4e2a\u5b57\u5178\u4f20\u7ed9 groupby() \u3002 by_column = people.groupby(mapping, axis=1) print(by_column.sum()) # blue red # Joe 12.0 13.0 # Steve 10.0 10.0 # Wes 6.0 8.0 # Jim 12.0 13.0 # Travis 7.0 8.0 Series\u4e5f\u6709\u76f8\u540c\u7684\u529f\u80fd\uff0c\u53ef\u4ee5\u89c6\u4e3a\u56fa\u5b9a\u5927\u5c0f\u7684\u6620\u5c04\u3002 map_services = pd.Series(mapping) print(map_services) # a red # b red # c blue # d blue # e red # f orange # dtype: object result = people.groupby(map_services, axis=1).count() print(result) # blue red # Joe 2 3 # Steve 2 3 # Wes 1 2 # Jim 2 3 # Travis 2 3 \u4f7f\u7528\u51fd\u6570\u5206\u7ec4 \u00b6 \u4e0e\u4f7f\u7528\u5b57\u5178\u6216Series\u5206\u7ec4\u76f8\u6bd4\uff0c\u4f7f\u7528Python\u51fd\u6570\u662f\u5b9a\u4e49\u5206\u7ec4\u5173\u7cfb\u7684\u4e00\u79cd\u66f4\u4e3a\u901a\u7528\u7684\u65b9\u5f0f\u3002 \u4f5c\u4e3a\u5206\u7ec4\u952e\u4f20\u9012\u7684\u51fd\u6570\u5c06\u4f1a\u6309\u7167\u6bcf\u4e2a\u7d22\u5f15\u503c\u8c03\u7528\u4e00\u6b21\uff0c\u540c\u65f6\u8fd4\u56de\u503c\u4f1a\u88ab\u7528\u4f5c\u5206\u7ec4\u540d\u79f0\u3002\u6ce8\u610f\uff1a\u51fd\u6570\u662f\u4f5c\u7528\u5728\u7d22\u5f15\u4e0a\u3002 result = people.groupby(len).sum() # \u4eba\u7684\u540d\u5b57\u662f\u7d22\u5f15\u503c\uff0c\u6839\u636e\u540d\u5b57\u7684\u957f\u5ea6\u6765\u8fdb\u884c\u5206\u7ec4 print(result) # a b c d e # 3 2 6.0 10.0 20 26 # 5 0 2.0 4.0 6 8 # 6 1 2.0 3.0 4 5 \u53ef\u4ee5\u5c06\u51fd\u6570\u4e0e\u6570\u7ec4\u3001\u5b57\u5178\u6216Series\u8fdb\u884c\u6df7\u5408\uff0c\u6240\u6709\u7684\u5bf9\u8c61\u90fd\u4f1a\u5728\u5185\u90e8\u8f6c\u6362\u4e3a\u6570\u7ec4\u3002 key_list = ['one', 'one', 'one', 'two', 'two'] result = people.groupby([len, key_list]).min() print(result) # a b c d e # 3 one 0 3.0 5.0 6 8 # two 1 3.0 5.0 7 9 # 5 one 0 2.0 4.0 6 8 # 6 two 1 2.0 3.0 4 5 \u6839\u636e\u7d22\u5f15\u5c42\u7ea7\u5206\u7ec4 \u00b6 \u6839\u636e\u5c42\u7ea7\u5206\u7ec4\u65f6\uff0c\u5c06\u5c42\u7ea7\u6570\u503c\u6216\u5c42\u7ea7\u540d\u79f0\u4f20\u9012\u7ed9 level \u5173\u952e\u5b57\u3002 columns = pd.MultiIndex.from_arrays( [['US', 'US', 'US', 'JP', 'JP'], [1, 3, 5, 1, 3]], names=['cty', 'tenor'] ) hier_df = pd.DataFrame( [[1, 3, 5, 7, 9], [0, 2, 4, 6, 8], [1, 3, 5, 7, 9], [1, 2, 3, 4, 5]], columns=columns ) print(hier_df) # cty US JP # tenor 1 3 5 1 3 # 0 1 3 5 7 9 # 1 0 2 4 6 8 # 2 1 3 5 7 9 # 3 1 2 3 4 5 result = hier_df.groupby(level='cty', axis=1).count() print(result) # cty JP US # 0 2 3 # 1 2 3 # 2 2 3 # 3 2 3 \u6570\u636e\u805a\u5408 \u00b6 \u805a\u5408\u662f\u6307\u6240\u6709\u6839\u636e\u6570\u7ec4\u4ea7\u751f\u6807\u91cf\u503c\u7684\u6570\u636e\u8f6c\u6362\u8fc7\u7a0b\uff0c\u6bd4\u5982\uff1a mean \u3001 count \u3001 min \u548c sum \u7b49\u4e00\u4e9b\u805a\u5408\u64cd\u4f5c\u3002 import pandas as pd import numpy as np \u9884\u5907\u77e5\u8bc6\uff1a \u5206\u4f4d\u6570\uff08Quantile\uff09\uff0c\u4e5f\u79f0\u5206\u4f4d\u70b9\uff0c\u662f\u6307\u5c06\u4e00\u4e2a\u968f\u673a\u53d8\u91cf\u7684\u6982\u7387\u5206\u5e03\u8303\u56f4\u5206\u4e3a\u51e0\u4e2a\u7b49\u4efd\u7684\u6570\u503c\u70b9\uff0c\u5206\u6790\u5176\u6570\u636e\u53d8\u91cf\u7684\u8d8b\u52bf\u3002 \u5e38\u7528\u7684\u5206\u4f4d\u6570\u6709 \u4e2d\u4f4d\u6570\u3001\u56db\u5206\u4f4d\u6570\u3001\u767e\u5206\u4f4d\u6570\u7b49\u3002 \u4e2d\u4f4d\u6570\uff08Medians\uff09\u662f\u4e00\u4e2a\u7edf\u8ba1\u5b66\u7684\u4e13\u6709\u540d\u8bcd\uff0c\u4ee3\u8868\u4e00\u4e2a\u6837\u672c\u3001\u79cd\u7fa4\u6216\u6982\u7387\u5206\u5e03\u4e2d\u7684\u4e00\u4e2a\u6570\u503c\uff0c\u53ef\u4ee5\u5c06\u6570\u503c\u96c6\u5408\u5212\u5206\u4e3a\u76f8\u7b49\u7684\u4e24\u90e8\u5206\u3002 \u5229\u7528pandas\u5e93\u8ba1\u7b97 data = [6, 47, 49, 15, 42, 41, 7, 39, 43, 40, 36] \u7684\u5206\u4f4d\u6570\u3002 \u786e\u5b9a p \u5206\u4f4d\u6570\u4f4d\u7f6e\u7684\u4e24\u79cd\u65b9\u6cd5( n \u4e3a\u6570\u636e\u7684\u603b\u4e2a\u6570\uff0c p \u4e3a 0-1 \u4e4b\u95f4\u7684\u503c)\u3002\u5728python\u4e2d\u8ba1\u7b97\u5206\u4f4d\u6570\u4f4d\u7f6e\u7684\u65b9\u6848\u91c7\u7528 position=1+(n-1)*p \uff1a position = (n+1)*p position = 1 + (n-1)*p \u6848\u4f8b1 data = pd.Series(np.array([6, 47, 49, 15, 42, 41, 7, 39, 43, 40, 36])) print(\"\u6570\u636e\u683c\u5f0f\uff1a\") print(np.sort(data)) # \u5fc5\u987b\u8981\u6392\u5e8f print('Q1:', data.quantile(.25)) print('Q2:', data.quantile(.5)) print('Q3:', data.quantile(.75)) # \u6570\u636e\u683c\u5f0f\uff1a # [ 6 7 15 36 39 40 41 42 43 47 49] # Q1: 25.5 # Q2: 40.0 # Q3: 42.5 # \u624b\u7b97\u8ba1\u7b97\u7ed3\u679c\uff1a # Q1\u7684p\u5206\u4f4d\u6570(0.25)\u4f4d\u7f6eposition = 1+(11-1)*0.25 = 3.5(\u53d6\u7b2c3\u4f4d) (p=0.25) Q1=15+(36-15)*0.5=25.5 (\u7b2c3\u30014\u4f4d\u7684\u5dee\u4e58\u4ee5\u4f59\u65700.5) # Q2\u7684p\u5206\u4f4d\u6570(0.5)\u4f4d\u7f6eposition = 1+(11-1)*0.5 = 6 (p=0.5) Q2=40 # Q3\u7684p\u5206\u4f4d\u6570(0.75)\u4f4d\u7f6eposition = 1+(11-1)*0.75 = 9 (p=0.75) Q3=42+(43-42)*0.5=42.5 # IQR = Q3 - Q1 = 17 \u6848\u4f8b2 df = pd.DataFrame(np.array([[1, 1], [2, 10], [3, 100], [4, 100]]), columns=['a', 'b']) print(\"\u6570\u636e\u539f\u59cb\u683c\u5f0f\uff1a\") print(df) print(\"\u8ba1\u7b97p=0.1\u65f6\uff0ca\u5217\u548cb\u5217\u7684\u5206\u4f4d\u6570\") print(df.quantile(.1)) # \u6570\u636e\u539f\u59cb\u683c\u5f0f\uff1a # a b # 0 1 1 # 1 2 10 # 2 3 100 # 3 4 100 # \u8ba1\u7b97p=0.1\u65f6\uff0ca\u5217\u548cb\u5217\u7684\u5206\u4f4d\u6570 # a 1.3 # b 3.7 # Name: 0.1, dtype: float64 # \u624b\u7b97\u8ba1\u7b97\u7ed3\u679c\uff1a # \u8ba1\u7b97a\u5217 # position=1+(4-1)*0.1=1.3 (\u53d6\u7b2c1\u4f4d) # Q1=1+(2-1)*0.3=1.3 (\u7b2c1\u30012\u4f4d\u7684\u5dee\u4e58\u4ee5\u4f59\u65700.3) # \u8ba1\u7b97b\u5217 # position=1+(4-1)*0.1=1.3 (\u53d6\u7b2c1\u4f4d) # Q1=1+(10-1)*0.3=3.7 (\u7b2c1\u30012\u4f4d\u7684\u5dee\u4e58\u4ee5\u4f59\u65700.3) \u4f18\u5316\u7684 groupby \u65b9\u6cd5\uff1a count: \u5206\u7ec4\u4e2d\u975eNA\u503c\u7684\u6570\u91cf sum: \u975eNA\u503c\u7684\u7d2f\u52a0\u548c mean: \u975eNA\u503c\u7684\u5e73\u5747\u503c median: \u975eNA\u503c\u7684\u7b97\u672f\u4e2d\u4f4d\u6570 std, var: \u65e0\u504f\u7684(n-1\u5206\u6bcd)\u6807\u51c6\u5dee\u548c\u65b9\u5dee min, max: \u975eNA\u503c\u7684\u6700\u5c0f\u503c\u3001\u6700\u5927\u503c prod: \u975eNA\u503c\u7684\u4e58\u79ef first, last: \u975eNA\u503c\u7684\u7b2c\u4e00\u4e2a\u3001\u6700\u540e\u4e00\u4e2a\u503c df = pd.DataFrame( { 'key1': ['a', 'a', 'b', 'b', 'a'], 'key2': ['one', 'two', 'one', 'two', 'one'], 'data1': [1, 3, 5, 7, 9], 'data2': [2, 4, 6, 8, 10] } ) print(df) # key1 key2 data1 data2 # 0 a one 1 2 # 1 a two 3 4 # 2 b one 5 6 # 3 b two 7 8 # 4 a one 9 10 grouped = df.groupby('key1') result = grouped['data1'] for i in result: print(i) # ('a', 0 1 # 1 3 # 4 9 # Name: data1, dtype: int64) # ('b', 2 5 # 3 7 # Name: data1, dtype: int64) result = grouped['data1'].quantile(0.9) # quantile\u5206\u4f4d\u6570 print(result) # key1 # a 7.8 # b 6.8 # Name: data1, dtype: float64 # \u624b\u7b97\u8ba1\u7b97\u7ed3\u679c\uff1a # \u8ba1\u7b97a\u5217 # position=1+(3-1)*0.9=2.8 # Q1=3+(9-3)*0.8=7.8 # \u8ba1\u7b97b\u5217 # position=1+(2-1)*0.9=1.9 # Q1=5+(7-5)*0.9=6.8 \u4f7f\u7528\u81ea\u884c\u5236\u5b9a\u7684\u805a\u5408\uff0c\u5e76\u518d\u8c03\u7528\u5df2\u7ecf\u5728\u5206\u7ec4\u5bf9\u8c61\u4e0a\u5b9a\u4e49\u597d\u7684\u65b9\u6cd5\u3002 def peak_to_peak(arr): return arr.max() - arr.min() result = grouped.agg(peak_to_peak) print(result) # data1 data2 # key1 # a 8 8 # b 2 2 result = grouped.describe() print(result) # data1 ... data2 # count mean std min 25% ... min 25% 50% 75% max # key1 ... # a 3.0 4.333333 4.163332 1.0 2.0 ... 2.0 3.0 4.0 7.0 10.0 # b 2.0 6.000000 1.414214 5.0 5.5 ... 6.0 6.5 7.0 7.5 8.0 \u9010\u5217\u53ca\u591a\u51fd\u6570\u5e94\u7528 \u00b6 tips = pd.read_csv('../examples/tips.csv') tips['tip_pct'] = tips['tip'] / (tips['total_bill'] - tips['tip']) print(tips.head(5)) # total_bill tip smoker day time size tip_pct # 0 16.99 1.01 No Sun Dinner 2 0.063204 # 1 10.34 1.66 No Sun Dinner 3 0.191244 # 2 21.01 3.50 No Sun Dinner 3 0.199886 # 3 23.68 3.31 No Sun Dinner 2 0.162494 # 4 24.59 3.61 No Sun Dinner 4 0.172069 \u6839\u636e\u5404\u5217\u540c\u65f6\u4f7f\u7528\u591a\u4e2a\u51fd\u6570\u8fdb\u884c\u805a\u5408 grouped = tips.groupby(['day', 'smoker']) # for i in grouped: # print(i) # (('Fri', 'No'), total_bill tip smoker day time size tip_pct # 91 22.49 3.50 No Fri Dinner 2 0.184308 # ...... # 223 15.98 3.00 No Fri Lunch 3 0.231125) # (('Fri', 'Yes'), total_bill tip smoker day time size tip_pct # 90 28.97 3.00 Yes Fri Dinner 2 0.115518 # ...... # 226 10.09 2.00 Yes Fri Lunch 2 0.247219) # ...... grouped_pct = grouped['tip_pct'] for i in grouped_pct: print(i) # (('Fri', 'No'), 91 0.184308 # 94 0.166667 # ...... # Name: tip_pct, dtype: float64) # (('Fri', 'Yes'), 90 0.115518 # 92 0.210526 # ...... # Name: tip_pct, dtype: float64) # ...... \u5c06\u51fd\u6570\u540d\u4ee5\u5b57\u7b26\u4e32\u5f62\u5f0f\u4f20\u9012\u3002 result = grouped_pct.agg('mean') print(result) # day smoker # Fri No 0.179740 # Yes 0.216293 # Sat No 0.190412 # Yes 0.179833 # Sun No 0.193617 # Yes 0.322021 # Thur No 0.193424 # Yes 0.198508 # Name: tip_pct, dtype: float64 \u5982\u679c\u4f20\u9012\u7684\u662f\u51fd\u6570\u6216\u8005\u51fd\u6570\u540d\u7684\u5217\u8868\uff0c\u4f1a\u5f97\u5230\u4e00\u4e2a\u5217\u540d\u662f\u8fd9\u4e9b\u51fd\u6570\u540d\u7684DataFrame\u3002 \u4e0b\u9762\u4f20\u9012\u4e86\u805a\u5408\u51fd\u6570\u7684\u5217\u8868\u7ed9agg\u65b9\u6cd5\uff0c\u8fd9\u4e9b\u51fd\u6570\u4f1a\u5404\u81ea\u8fd0\u7528\u4e8e\u6570\u636e\u5206\u7ec4\u3002 result = grouped_pct.agg(['mean', 'std', peak_to_peak]) print(result) # mean std peak_to_peak # day smoker # Fri No 0.179740 0.039458 0.094263 # Yes 0.216293 0.077530 0.242219 # Sat No 0.190412 0.058626 0.352192 # Yes 0.179833 0.089496 0.446137 # Sun No 0.193617 0.060302 0.274897 # Yes 0.322021 0.538061 2.382107 # Thur No 0.193424 0.056065 0.284273 # Yes 0.198508 0.057170 0.219047 \u5982\u679c\u4f20\u9012\u7684\u662f (name, function) \u5143\u7ec4\u7684\u5217\u8868\uff0c\u6bcf\u4e2a\u5143\u7ec4\u7684\u7b2c\u4e00\u4e2a\u5143\u7d20\u5c06\u4f5c\u4e3aDataFrame\u7684\u5217\u540d\uff08\u53ef\u4ee5\u8ba4\u4e3a\u4e8c\u5143\u5143\u7ec4\u7684\u5217\u8868\u662f\u4e00\u79cd\u6709\u5e8f\u7684\u5bf9\u5e94\u5173\u7cfb\uff09\uff1a result = grouped_pct.agg([('foo', 'mean'), ('bar', np.std)]) # foo\u662fmean\u503c\u7684\u5217\u540d print(result) # foo bar # day smoker # Fri No 0.179740 0.039458 # Yes 0.216293 0.077530 # Sat No 0.190412 0.058626 # Yes 0.179833 0.089496 # Sun No 0.193617 0.060302 # Yes 0.322021 0.538061 # Thur No 0.193424 0.056065 # Yes 0.198508 0.057170 \u53ef\u4ee5\u6307\u5b9a\u5e94\u7528\u5230\u6240\u6709\u5217\u4e0a\u7684\u51fd\u6570\u5217\u8868\u6216\u6bcf\u4e00\u5217\u4e0a\u8981\u5e94\u7528\u7684\u4e0d\u540c\u51fd\u6570\u3002 \u4e0b\u9762\u4ea7\u751f\u7684DataFrame\u62e5\u6709\u5206\u5c42\u5217\uff0c\u4e0e\u5206\u522b\u805a\u5408\u6bcf\u4e00\u5217\uff0c\u518d\u4ee5\u5217\u540d\u4f5c\u4e3a keys \u53c2\u6570\u4f7f\u7528 concat \u5c06\u7ed3\u679c\u62fc\u63a5\u5728\u4e00\u8d77\u7684\u7ed3\u679c\u76f8\u540c\u3002 functions = ['count', 'mean', 'max'] result = grouped[['tip_pct', 'total_bill']].agg(functions) print(result) # tip_pct total_bill # count mean max count mean max # day smoker # Fri No 4 0.179740 0.231125 4 18.420000 22.75 # Yes 15 0.216293 0.357737 15 16.813333 40.17 # Sat No 45 0.190412 0.412409 45 19.661778 48.33 # Yes 42 0.179833 0.483092 42 21.276667 50.81 # Sun No 57 0.193617 0.338101 57 20.506667 48.17 # Yes 19 0.322021 2.452381 19 24.120000 45.35 # Thur No 45 0.193424 0.362976 45 17.113111 41.19 # Yes 17 0.198508 0.317965 17 19.190588 43.11 # \u628a['tip_pct', 'total_bill']\u6539\u6210[['tip_pct', 'total_bill']]\uff0c\u5c31\u53ef\u4ee5\u907f\u514d\u62a5\u9519 # FutureWarning: Indexing with multiple keys (implicitly converted to a tuple of keys) will be deprecated, use a list instead. # result = grouped['tip_pct', 'total_bill'].agg(functions) print(result['tip_pct']) # count mean max # day smoker # Fri No 4 0.179740 0.231125 # Yes 15 0.216293 0.357737 # Sat No 45 0.190412 0.412409 # Yes 42 0.179833 0.483092 # Sun No 57 0.193617 0.338101 # Yes 19 0.322021 2.452381 # Thur No 45 0.193424 0.362976 # Yes 17 0.198508 0.317965 \u4e5f\u540c\u6837\u53ef\u4ee5\u4f20\u9012\u5177\u6709\u81ea\u5b9a\u4e49\u540d\u79f0\u7684\u5143\u7ec4\u5217\u8868\uff1a ftuples = [('Durchschnitt', 'mean'), ('Abweichung', np.var)] result = grouped[['tip_pct', 'total_bill']].agg(ftuples) print(result) # tip_pct total_bill # Durchschnitt Abweichung Durchschnitt Abweichung # day smoker # Fri No 0.179740 0.001557 18.420000 25.596333 # Yes 0.216293 0.006011 16.813333 82.562438 # Sat No 0.190412 0.003437 19.661778 79.908965 # Yes 0.179833 0.008010 21.276667 101.387535 # Sun No 0.193617 0.003636 20.506667 66.099980 # Yes 0.322021 0.289509 24.120000 109.046044 # Thur No 0.193424 0.003143 17.113111 59.625081 # Yes 0.198508 0.003268 19.190588 69.808518 \u8981\u5c06\u4e0d\u540c\u7684\u51fd\u6570\u5e94\u7528\u5230\u4e00\u4e2a\u6216\u591a\u4e2a\u5217\u4e0a\uff0c\u9700\u8981\u5c06\u542b\u6709\u5217\u540d\u4e0e\u51fd\u6570\u5bf9\u5e94\u5173\u7cfb\u7684\u5b57\u5178\u4f20\u9012\u7ed9 agg \uff1a result = grouped.agg({'tip': np.max, 'size': 'sum'}) print(result) # tip size # day smoker # Fri No 3.50 9 # Yes 4.73 31 # Sat No 9.00 115 # Yes 10.00 104 # Sun No 6.00 167 # Yes 6.50 49 # Thur No 6.70 112 # Yes 5.00 40 result = grouped.agg({'tip_pct': ['min', 'max', 'mean', 'std']}) print(result) # tip_pct # min max mean std # day smoker # Fri No 0.136861 0.231125 0.179740 0.039458 # Yes 0.115518 0.357737 0.216293 0.077530 # Sat No 0.060217 0.412409 0.190412 0.058626 # Yes 0.036955 0.483092 0.179833 0.089496 # Sun No 0.063204 0.338101 0.193617 0.060302 # Yes 0.070274 2.452381 0.322021 0.538061 # Thur No 0.078704 0.362976 0.193424 0.056065 # Yes 0.098918 0.317965 0.198508 0.057170 \u53ea\u6709\u591a\u4e2a\u51fd\u6570\u5e94\u7528\u4e8e\u81f3\u5c11\u4e00\u4e2a\u5217\u65f6\uff0cDataFrame\u624d\u5177\u6709\u5206\u5c42\u5217\u3002 \u8fd4\u56de\u4e0d\u542b\u884c\u7d22\u5f15\u7684\u805a\u5408\u6570\u636e \u00b6 \u5728\u524d\u9762\u6240\u6709\u7684\u4f8b\u5b50\u4e2d\uff0c\u805a\u5408\u6570\u636e\u8fd4\u56de\u65f6\u90fd\u662f\u5e26\u6709\u7d22\u5f15\u7684\uff0c\u6709\u65f6\u7d22\u5f15\u662f\u5206\u5c42\u7684\uff0c\u7531\u552f\u4e00\u7684\u5206\u7ec4\u952e\u8054\u5408\u5f62\u6210\u3002 \u56e0\u4e3a\u4e0d\u662f\u6240\u6709\u7684\u60c5\u51b5\u4e0b\u90fd\u9700\u8981\u7d22\u5f15\uff0c\u6240\u4ee5\u5728\u5927\u591a\u6570\u60c5\u51b5\u4e0b\u53ef\u4ee5\u901a\u8fc7\u5411groupby\u4f20\u9012as_index=False\u6765\u7981\u7528\u5206\u7ec4\u952e\u4f5c\u4e3a\u7d22\u5f15\u7684\u884c\u4e3a\uff1a result = tips.groupby(['day', 'smoker'], as_index=False).mean() print(result) # day smoker total_bill tip size tip_pct # 0 Fri No 18.420000 2.812500 2.250000 0.179740 # 1 Fri Yes 16.813333 2.714000 2.066667 0.216293 # 2 Sat No 19.661778 3.102889 2.555556 0.190412 # 3 Sat Yes 21.276667 2.875476 2.476190 0.179833 # 4 Sun No 20.506667 3.167895 2.929825 0.193617 # 5 Sun Yes 24.120000 3.516842 2.578947 0.322021 # 6 Thur No 17.113111 2.673778 2.488889 0.193424 # 7 Thur Yes 19.190588 3.030000 2.352941 0.198508 \u901a\u8fc7\u5728\u7ed3\u679c\u4e0a\u8c03\u7528reset_index\u4e5f\u53ef\u4ee5\u83b7\u5f97\u540c\u6837\u7684\u7ed3\u679c\u3002\u4f7f\u7528as_index=False\u53ef\u4ee5\u907f\u514d\u4e00\u4e9b\u4e0d\u5fc5\u8981\u7684\u8ba1\u7b97\u3002 result = tips.groupby(['day', 'smoker']).mean() print(result.reset_index()) # day smoker total_bill tip size tip_pct # 0 Fri No 18.420000 2.812500 2.250000 0.179740 # 1 Fri Yes 16.813333 2.714000 2.066667 0.216293 # 2 Sat No 19.661778 3.102889 2.555556 0.190412 # 3 Sat Yes 21.276667 2.875476 2.476190 0.179833 # 4 Sun No 20.506667 3.167895 2.929825 0.193617 # 5 Sun Yes 24.120000 3.516842 2.578947 0.322021 # 6 Thur No 17.113111 2.673778 2.488889 0.193424 # 7 Thur Yes 19.190588 3.030000 2.352941 0.198508 print(result) # total_bill tip size tip_pct # day smoker # Fri No 18.420000 2.812500 2.250000 0.179740 # Yes 16.813333 2.714000 2.066667 0.216293 # Sat No 19.661778 3.102889 2.555556 0.190412 # Yes 21.276667 2.875476 2.476190 0.179833 # Sun No 20.506667 3.167895 2.929825 0.193617 # Yes 24.120000 3.516842 2.578947 0.322021 # Thur No 17.113111 2.673778 2.488889 0.193424 # Yes 19.190588 3.030000 2.352941 0.198508 \u5e94\u7528\uff1a\u901a\u7528\u62c6\u5206-\u5e94\u7528-\u8054\u5408 \u00b6 import pandas as pd import numpy as np import statsmodels.api as sm GroupBy \u65b9\u6cd5\u6700\u5e38\u89c1\u7684\u76ee\u7684\u662f apply \uff08\u5e94\u7528\uff09\u3002 apply \u5c06\u5bf9\u8c61\u62c6\u5206\u6210\u591a\u5757\uff0c\u7136\u540e\u5728\u6bcf\u4e00\u5757\u4e0a\u8c03\u7528\u4f20\u9012\u7684\u51fd\u6570\uff0c\u4e4b\u540e\u5c1d\u8bd5\u5c06\u6bcf\u4e00\u5757\u62fc\u63a5\u5230\u4e00\u8d77\u3002 \u6839\u636e\u4e0b\u9762\u7684\u5c0f\u8d39\u6570\u636e\u96c6\uff0c\u6309\u7ec4\u9009\u51fa\u5c0f\u8d39\u767e\u5206\u6bd4\uff08tip-pct\uff09\u6700\u9ad8\u7684\u4e94\u7ec4\u3002 tips = pd.read_csv('../examples/tips.csv') tips['tip_pct'] = tips['tip'] / (tips['total_bill'] - tips['tip']) \u6837\u672c\u6570\u636e print(tips.head(5)) # total_bill tip smoker day time size tip_pct # 0 16.99 1.01 No Sun Dinner 2 0.063204 # 1 10.34 1.66 No Sun Dinner 3 0.191244 # 2 21.01 3.50 No Sun Dinner 3 0.199886 # 3 23.68 3.31 No Sun Dinner 2 0.162494 # 4 24.59 3.61 No Sun Dinner 4 0.172069 \u9996\u5148\uff0c\u5199\u4e00\u4e2a\u53ef\u4ee5\u5728\u7279\u5b9a\u5217\u4e2d\u9009\u51fa\u6700\u5927\u503c\u6240\u5728\u884c\u7684\u51fd\u6570\uff1a \u6dfb\u52a0\u4e86\u5347\u5e8f\uff0c\u7ed3\u679c\u8f93\u51fa\u6700\u540e5\u884c\uff08\u6700\u540e\u76845\u884c\u4e5f\u662f\u6700\u5927\u76845\u4e2a tip_tcp \u8bb0\u5f55\uff09\u3002 def top(df, n=5, column='tip_pct'): return df.sort_values(by=column, ascending=True)[-n:] result = top(tips, n=6) print(result) # \u7b49\u4ef7\u65b9\u5f0f\uff1a # result = tips.sort_values('tip_pct')[-6:] # print(result) # total_bill tip smoker day time size tip_pct # 109 14.31 4.00 Yes Sat Dinner 2 0.387973 # 183 23.17 6.50 Yes Sun Dinner 4 0.389922 # 232 11.61 3.39 No Sat Dinner 2 0.412409 # 67 3.07 1.00 Yes Sat Dinner 1 0.483092 # 178 9.60 4.00 Yes Sun Dinner 2 0.714286 # 172 7.25 5.15 Yes Sun Dinner 2 2.452381 \u5982\u679c\u6309\u7167 smoker \u8fdb\u884c\u5206\u7ec4\uff0c\u4e4b\u540e\u8c03\u7528 apply \uff0c\u4f1a\u5f97\u5230\u4ee5\u4e0b\u7ed3\u679c\uff1a top \u51fd\u6570\u5728DataFrame\u7684\u6bcf\u4e00\u884c\u5206\u7ec4\u4e0a\u88ab\u8c03\u7528\uff0c\u4e4b\u540e\u4f7f\u7528 pandas.concat \u5c06\u51fd\u6570\u7ed3\u679c\u7c98\u8d34\u5728\u4e00\u8d77\uff0c\u5e76\u4f7f\u7528\u5206\u7ec4\u540d\u4f5c\u4e3a\u5404\u7ec4\u7684\u6807\u7b7e\u3002 \u56e0\u6b64\u7ed3\u679c\u5305\u542b\u4e00\u4e2a\u5206\u5c42\u7d22\u5f15\uff0c\u8be5\u5206\u5c42\u7d22\u5f15\u7684\u5185\u90e8\u5c42\u7ea7\u5305\u542b\u539fDataFrame\u7684\u7d22\u5f15\u503c\u3002 result = tips.groupby('smoker').apply(top) print(result) # total_bill tip smoker day time size tip_pct # smoker # No 88 24.71 5.85 No Thur Lunch 2 0.310180 # 185 20.69 5.00 No Sun Dinner 5 0.318674 # 51 10.29 2.60 No Sun Dinner 2 0.338101 # 149 7.51 2.00 No Thur Lunch 2 0.362976 # 232 11.61 3.39 No Sat Dinner 2 0.412409 # Yes 109 14.31 4.00 Yes Sat Dinner 2 0.387973 # 183 23.17 6.50 Yes Sun Dinner 4 0.389922 # 67 3.07 1.00 Yes Sat Dinner 1 0.483092 # 178 9.60 4.00 Yes Sun Dinner 2 0.714286 # 172 7.25 5.15 Yes Sun Dinner 2 2.452381 \u5982\u679c\u9664\u4e86\u5411 apply \u4f20\u9012\u51fd\u6570\uff0c\u8fd8\u4f20\u9012\u5176\u4ed6\u53c2\u6570\u6216\u5173\u952e\u5b57\u7684\u8bdd\uff0c\u4f60\u53ef\u4ee5\u628a\u8fd9\u4e9b\u653e\u5728\u51fd\u6570\u540e\u8fdb\u884c\u4f20\u9012\u3002 result = tips.groupby('smoker').apply(top, n=1, column='total_bill') print(result) # \u8fd92\u884c\u90fd\u662fsmoker\u662fyes\u548cno\u65f6\u6700\u5927total_bill\u503c\u6240\u5728\u884c\u3002 # total_bill tip smoker day time size tip_pct # smoker # No 212 48.33 9.0 No Sat Dinner 4 0.228833 # Yes 170 50.81 10.0 Yes Sat Dinner 3 0.245038 \u5728 GroupBy \u5bf9\u8c61\u4e0a\u8c03\u7528 describe \u65b9\u6cd5\u3002 result = tips.groupby('smoker')['tip_pct'].describe() print(result) # count mean std ... 50% 75% max # smoker ... # No 151.0 0.192237 0.057665 ... 0.184308 0.227015 0.412409 # Yes 93.0 0.218176 0.254295 ... 0.181818 0.242326 2.452381 # [2 rows x 8 columns] print(result.unstack('smoker')) # \u7c7b\u4f3c\u4e8e\u8f6c\u7f6e # smoker # count No 151.000000 # Yes 93.000000 # mean No 0.192237 # Yes 0.218176 # std No 0.057665 # Yes 0.254295 # min No 0.060217 # Yes 0.036955 # 25% No 0.158622 # Yes 0.119534 # 50% No 0.184308 # Yes 0.181818 # 75% No 0.227015 # Yes 0.242326 # max No 0.412409 # Yes 2.452381 # dtype: float64 \u5728 GroupBy \u5bf9\u8c61\u7684\u5185\u90e8\uff0c\u5f53\u8c03\u7528\u50cf describe \u8fd9\u6837\u7684\u65b9\u6cd5\u65f6\uff0c\u5b9e\u9645\u4e0a\u662f\u4ee5\u4e0b\u4ee3\u7801\u7684\u7b80\u5199\uff1a grouped = tips.groupby(['smoker']) f = lambda x: x.describe() result = grouped.apply(f) print(result) # total_bill tip size tip_pct # smoker # No count 151.000000 151.000000 151.000000 151.000000 # mean 19.188278 2.991854 2.668874 0.192237 # std 8.255582 1.377190 1.017984 0.057665 # min 7.250000 1.000000 1.000000 0.060217 # 25% 13.325000 2.000000 2.000000 0.158622 # 50% 17.590000 2.740000 2.000000 0.184308 # 75% 22.755000 3.505000 3.000000 0.227015 # max 48.330000 9.000000 6.000000 0.412409 # Yes count 93.000000 93.000000 93.000000 93.000000 # mean 20.756344 3.008710 2.408602 0.218176 # std 9.832154 1.401468 0.810751 0.254295 # min 3.070000 1.000000 1.000000 0.036955 # 25% 13.420000 2.000000 2.000000 0.119534 # 50% 17.920000 3.000000 2.000000 0.181818 # 75% 26.860000 3.680000 3.000000 0.242326 # max 50.810000 10.000000 5.000000 2.452381 \u538b\u7f29\u5206\u7ec4\u952e \u00b6 \u5728\u524d\u9762\u7684\u4f8b\u5b50\u4e2d\u6240\u5f97\u5230\u7684\u5bf9\u8c61\uff0c\u90fd\u5177\u6709\u5206\u7ec4\u952e\u6240\u5f62\u6210\u7684\u5206\u5c42\u7d22\u5f15\u4ee5\u53ca\u6bcf\u4e2a\u539f\u59cb\u5bf9\u8c61\u7684\u7d22\u5f15\u3002 \u4e5f\u53ef\u4ee5\u901a\u8fc7\u5411 groupby \u4f20\u9012 group_keys=False \u6765\u7981\u7528\u8fd9\u4e2a\u529f\u80fd\u3002 result = tips.groupby('smoker', group_keys=True).apply(top) print(result) # total_bill tip smoker day time size tip_pct # smoker # No 88 24.71 5.85 No Thur Lunch 2 0.310180 # 185 20.69 5.00 No Sun Dinner 5 0.318674 # 51 10.29 2.60 No Sun Dinner 2 0.338101 # 149 7.51 2.00 No Thur Lunch 2 0.362976 # 232 11.61 3.39 No Sat Dinner 2 0.412409 # Yes 109 14.31 4.00 Yes Sat Dinner 2 0.387973 # 183 23.17 6.50 Yes Sun Dinner 4 0.389922 # 67 3.07 1.00 Yes Sat Dinner 1 0.483092 # 178 9.60 4.00 Yes Sun Dinner 2 0.714286 # 172 7.25 5.15 Yes Sun Dinner 2 2.452381 result = tips.groupby('smoker', group_keys=False).apply(top) print(result) # total_bill tip smoker day time size tip_pct # 88 24.71 5.85 No Thur Lunch 2 0.310180 # 185 20.69 5.00 No Sun Dinner 5 0.318674 # 51 10.29 2.60 No Sun Dinner 2 0.338101 # 149 7.51 2.00 No Thur Lunch 2 0.362976 # 232 11.61 3.39 No Sat Dinner 2 0.412409 # 109 14.31 4.00 Yes Sat Dinner 2 0.387973 # 183 23.17 6.50 Yes Sun Dinner 4 0.389922 # 67 3.07 1.00 Yes Sat Dinner 1 0.483092 # 178 9.60 4.00 Yes Sun Dinner 2 0.714286 # 172 7.25 5.15 Yes Sun Dinner 2 2.452381 \u5206\u4f4d\u6570\u4e0e\u6876\u5206\u6790 \u00b6 \u7b2c8\u7ae0\u4e2d\uff0cpandas\u6709\u4e00\u4e9b\u5de5\u5177\uff0c\u5c24\u5176\u662f cut \u548c qcut \uff0c\u7528\u4e8e\u5c06\u6570\u636e\u6309\u7167\u4f60\u9009\u62e9\u7684\u7bb1\u4f4d\u6216\u6837\u672c\u5206\u4f4d\u6570\u8fdb\u884c\u5206\u6876\u3002 \u4e0e groupby \u65b9\u6cd5\u4e00\u8d77\u4f7f\u7528\u8fd9\u4e9b\u51fd\u6570\u53ef\u4ee5\u5bf9\u6570\u636e\u96c6\u66f4\u65b9\u4fbf\u5730\u8fdb\u884c\u5206\u6876\u6216\u5206\u4f4d\u5206\u6790\u3002 \u590d\u4e60\uff1a\u673a\u68b0\u5b66\u4e60\u4e2d\u7684\u5206\u7bb1\u5904\u7406\u3002 \u5728\u673a\u68b0\u5b66\u4e60\u4e2d\u7ecf\u5e38\u4f1a\u5bf9\u6570\u636e\u8fdb\u884c\u5206\u7bb1\u5904\u7406\u7684\u64cd\u4f5c\uff0c \u4e5f\u5c31\u662f\u628a\u4e00\u6bb5\u8fde\u7eed\u7684\u503c\u5207\u5206\u6210\u82e5\u5e72\u6bb5\uff0c\u6bcf\u4e00\u6bb5\u7684\u503c\u770b\u6210\u4e00\u4e2a\u5206\u7c7b\u3002\u8fd9\u4e2a\u628a\u8fde\u7eed\u503c\u8f6c\u6362\u6210\u79bb\u6563\u503c\u7684\u8fc7\u7a0b\uff0c\u6211\u4eec\u53eb\u505a\u5206\u7bb1\u5904\u7406\u3002 \u6bd4\u5982\uff0c\u628a\u5e74\u9f84\u630915\u5c81\u5212\u5206\u6210\u4e00\u7ec4\uff0c0-15\u5c81\u53eb\u505a\u5c11\u5e74\uff0c16-30\u5c81\u53eb\u505a\u9752\u5e74\uff0c31-45\u5c81\u53eb\u505a\u58ee\u5e74\u3002\u5728\u8fd9\u4e2a\u8fc7\u7a0b\u4e2d\uff0c\u6211\u4eec\u628a\u8fde\u7eed\u7684\u5e74\u9f84\u5206\u6210\u4e86\u4e09\u4e2a\u7c7b\u522b\uff0c\u201c\u5c11\u5e74\u201d\uff0c\u201c\u9752\u5e74\u201d\u548c\u201c\u58ee\u5e74\u201d\u5c31\u662f\u5404\u4e2a\u7c7b\u522b\u7684\u540d\u79f0\uff0c\u6216\u8005\u53eb\u505a\u6807\u7b7e\u3002 \u5728pandas\u4e2d\uff0c cut \u548c qcut \u51fd\u6570\u90fd\u53ef\u4ee5\u8fdb\u884c\u5206\u7bb1\u5904\u7406\u64cd\u4f5c\u3002 cut() \u6309\u7167\u53d8\u91cf\u7684\u503c\u5bf9\u53d8\u91cf\u8fdb\u884c\u5206\u5272\uff0c\u6bcf\u4e2a\u5206\u7ec4\u91cc\u6570\u636e\u7684\u4e2a\u6570\u5e76\u4e0d\u4e00\u6837\u3002 qcut() \u662f\u6309\u53d8\u91cf\u7684\u6570\u91cf\u6765\u5bf9\u53d8\u91cf\u8fdb\u884c\u5206\u5272\uff0c\u5e76\u4e14\u5c3d\u91cf\u4fdd\u8bc1\u6bcf\u4e2a\u5206\u7ec4\u91cc\u53d8\u91cf\u7684\u4e2a\u6570\u76f8\u540c\u3002 \u8003\u8651\u4e0b\u9762\u4e00\u4e2a\u7b80\u5355\u7684\u968f\u673a\u6570\u636e\u96c6\u548c\u4e00\u4e2a\u4f7f\u7528 cut \u7684\u7b49\u957f\u6876\u5206\u7c7b\uff1a df = pd.DataFrame( { 'data1': np.random.randn(1000), 'data2': np.random.randn(1000) } ) quartiles = pd.cut(df.data1, 4) # \u6309\u7167data1\u503c\u7531\u5c0f\u5230\u5927\u7684\u987a\u5e8f\u5c06\u6570\u636e\u5206\u62104\u4efd\uff0c\u5e76\u4e14\u4f7f\u6bcf\u7ec4\u503c\u7684\u8303\u56f4\u5927\u81f4\u76f8\u7b49\u3002 print(quartiles[:10]) # 0 (-0.0743, 1.729] # 1 (-0.0743, 1.729] # 2 (-0.0743, 1.729] # 3 (-0.0743, 1.729] # 4 (-1.877, -0.0743] # 5 (-0.0743, 1.729] # 6 (-0.0743, 1.729] # 7 (-0.0743, 1.729] # 8 (-1.877, -0.0743] # 9 (-0.0743, 1.729] # Name: data1, dtype: category # Categories ( # 4, # interval[float64, right]): [ # (-3.687, -1.877] < (-1.877, -0.0743] < (-0.0743, 1.729] < (1.729, 3.531] # ] \u4e0a\u9762 cut \u8fd4\u56de\u7684 Categorical \u5bf9\u8c61\u53ef\u4ee5\u76f4\u63a5\u4f20\u9012\u7ed9 groupby \u3002\u5229\u7528\u5b83\u8ba1\u7b97\u51fa data2 \u5217\u7684\u4e00\u4e2a\u7edf\u8ba1\u503c\u96c6\u5408\uff0c\u5982\u4e0b\uff1a def get_stats(group): return { 'min': group.min(), 'max': group.max(), 'count': group.count(), 'mean': group.mean() } grouped = df.data2.groupby(quartiles) for i in grouped: print(i) result = grouped.apply(get_stats).unstack() print(result) # min max count mean # data1 # (-3.145, -1.424] -1.759377 2.484321 77.0 -0.127900 # (-1.424, 0.29] -3.142344 2.830654 524.0 -0.081931 # (0.29, 2.005] -3.557136 3.261635 376.0 0.015715 # (2.005, 3.719] -2.829458 1.766352 23.0 -0.198780 \u4f7f\u7528 qcut \uff0c\u6839\u636e\u6837\u672c\u5206\u4f4d\u6570\u8ba1\u7b97\u51fa\u7b49\u5927\u5c0f\u7684\u6876\uff0c\u5c31\u662f\u7b49\u957f\u6876\u3002\u901a\u8fc7\u4f20\u9012 labels=False \u6765\u83b7\u5f97\u5206\u4f4d\u6570\u6570\u503c\u3002 grouping = pd.qcut(df.data1, 10, labels=False) grouped = df.data2.groupby(grouping) result = grouped.apply(get_stats).unstack() print(result) # min max count mean # data1 # 0 -3.678934 3.022862 100.0 0.029658 # 1 -2.319813 2.646502 100.0 0.094035 # 2 -2.873727 2.470840 100.0 0.023866 # 3 -2.196701 2.042251 100.0 0.021232 # 4 -2.154161 2.020809 100.0 0.110834 # 5 -2.723061 2.415626 100.0 0.057365 # 6 -2.291470 2.536159 100.0 0.020866 # 7 -2.064083 1.799356 100.0 -0.081025 # 8 -3.405679 1.792581 100.0 -0.009705 # 9 -2.469285 2.600849 100.0 -0.061721 \u793a\u4f8b\uff1a\u4f7f\u7528\u6307\u5b9a\u5206\u7ec4\u503c\u586b\u5145\u7f3a\u5931\u503c \u00b6 \u5728\u6e05\u9664\u7f3a\u5931\u503c\u65f6\uff0c\u6709\u65f6\u4f1a\u4f7f\u7528 dropna \u6765\u53bb\u9664\u7f3a\u5931\u503c\uff0c\u6709\u65f6\u4f7f\u7528\u4fee\u6b63\u503c\u6216\u6765\u81ea\u4e8e\u5176\u4ed6\u6570\u636e\u7684\u503c\u6765\u8f93\u5165\uff08\u586b\u5145\uff09\u5230 null \u503c\uff08 NA \uff09\u3002 fillna \u662f\u4e00\u4e2a\u53ef\u4ee5\u4f7f\u7528\u7684\u6b63\u786e\u5de5\u5177\u3002 \u4f8b\u5982\u4e0b\u9762\u4f8b\u5b50\u4e2d\u4f7f\u7528\u4f7f\u7528\u5e73\u5747\u503c\u6765\u586b\u5145NA\u503c\uff1a data = (100, 110, 120, 130, 140, 150) s = pd.Series(data) print(s) # 0 100 # 1 110 # 2 120 # 3 130 # 4 140 # 5 150 # dtype: float64 \u5c06\u6570\u636e\u4e2d\u7684\u4e00\u4e9b\u503c\u8bbe\u7f6e\u4e3a\u7f3a\u5931\u503c\uff1a s[::2] = np.nan print(s) # 0 NaN # 1 110.0 # 2 NaN # 3 130.0 # 4 NaN # 5 150.0 # dtype: float64 result = s.fillna(s.mean()) # 110, 130, 150\u7684\u5e73\u5747\u503c\u662f130 print(result) # 0 130.0 # 1 110.0 # 2 130.0 # 3 130.0 # 4 130.0 # 5 150.0 # dtype: float64 \u4e0b\u9762\u7684\u4f8b\u5b50\u662f\u6309\u7ec4\u586b\u5145NA\u503c\uff1a \u65b9\u6cd51,\u5bf9\u6570\u636e\u5206\u7ec4\u540e\u4f7f\u7528 apply \u3002 \u65b9\u6cd52,\u5728\u6bcf\u4e2a\u6570\u636e\u5757\u4e0a\u90fd\u8c03\u7528 fillna \u7684\u51fd\u6570\u3002 data = (100, 110, 120, 130, 140, 150, 160, 170) states = ['Ohio', 'New York', 'Vermont', 'Florida', 'Oregon', 'Nevada', 'California', 'Idaho'] group_key = ['East'] * 4 + ['West'] * 4 # 4\u4e2aEast\u548c4\u4e2aWest\u62fc\u63a5\u7684\u5217\u8868list s = pd.Series(data, index=states) print(s) # Ohio 100 # New York 110 # Vermont 120 # Florida 130 # Oregon 140 # Nevada 150 # California 160 # Idaho 170 # dtype: int64 \u5c06\u6570\u636e\u4e2d\u7684\u4e00\u4e9b\u503c\u8bbe\u7f6e\u4e3a\u7f3a\u5931\u503c\uff1a s[['Vermont', 'Nevada', 'Idaho']] = np.nan print(s) # Ohio 100.0 # New York 110.0 # Vermont NaN # Florida 130.0 # Oregon 140.0 # Nevada NaN # California 160.0 # Idaho NaN # dtype: float64 result = s.groupby(group_key).mean() print(result) # East 113.333333 # West 150.000000 # dtype: float64 \u7528\u4e0a\u9762\u5f97\u51fa\u7684\u5206\u7ec4\u5e73\u5747\u503c\u6765\u586b\u5145NA\u3002 fill_mean = lambda g: g.fillna(g.mean()) result = s.groupby(group_key).apply(fill_mean) print(result) # Ohio 100.000000 # New York 110.000000 # Vermont 113.333333 # Florida 130.000000 # Oregon 140.000000 # Nevada 150.000000 # California 160.000000 # Idaho 150.000000 # dtype: float64 \u5982\u679c\u5df2\u7ecf\u5728\u4ee3\u7801\u4e2d\u4e3a\u6bcf\u4e2a\u5206\u7ec4\u9884\u5b9a\u4e49\u4e86\u586b\u5145\u503c\uff0c\u53ef\u4ee5\u5229\u7528\u6bcf\u4e2a\u5206\u7ec4\u90fd\u6709\u7684\u5185\u7f6e\u7684 name \u5c5e\u6027\uff0c\u5b9e\u73b0\u586b\u5145 NA \u3002 fill_value = {'East': 0.5, 'West': -1} fill_func = lambda g: g.fillna(fill_value[g.name]) result = s.groupby(group_key).apply(fill_func) print(result) # Ohio 100.0 # New York 110.0 # Vermont 0.5 # Florida 130.0 # Oregon 140.0 # Nevada -1.0 # California 160.0 # Idaho -1.0 # dtype: float64 \u793a\u4f8b\uff1a\u968f\u673a\u91c7\u6837\u4e0e\u6392\u5217 \u00b6 \u5047\u8bbe\u60f3\u4ece\u5927\u6570\u636e\u96c6\u4e2d\u62bd\u53d6\u968f\u673a\u6837\u672c\uff08\u6709\u6216\u6ca1\u6709\u66ff\u6362\uff09\u4ee5\u7528\u4e8e\u8499\u7279\u5361\u7f57\u6a21\u62df\u76ee\u7684\u6216\u67d0\u4e9b\u5176\u4ed6\u5e94\u7528\u7a0b\u5e8f\u3002 \u6709\u5f88\u591a\u65b9\u6cd5\u6765\u6267\u884c\u201c\u62bd\u53d6\u201d\uff0c\u8fd9\u91cc\u4f7f\u7528Series\u7684sample\u65b9\u6cd5\u3002 \u4e3a\u4e86\u6f14\u793a\uff0c\u8fd9\u91cc\u4ecb\u7ecd\u4e00\u79cd\u6784\u9020\u4e00\u526f\u82f1\u5f0f\u6251\u514b\u724c\u7684\u65b9\u6cd5\uff1a # \u6885\u82b1clubs\u3001\u65b9\u5757diamonds\u3001\u7ea2\u6843hearts\u3001\u9ed1\u6843spades\u3002 suits = ['H', 'S', 'C', 'D'] card_val = (list(range(1, 11)) + [10] * 3) * 4 # card_val [ # 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 10, 10, 10, # 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 10, 10, 10, # 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 10, 10, 10, # 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 10, 10, 10 # ] base_names = ['A'] + list(range(2, 11)) + ['J', 'K', 'Q'] # base_names\uff1a ['A', 2, 3, 4, 5, 6, 7, 8, 9, 10, 'J', 'K', 'Q'] \u751f\u6210\u4e86\u4e00\u4e2a\u957f\u5ea6\u4e3a 52 \u7684Series, Series\u7684\u7d22\u5f15\u5305\u542b\u4e86\u724c\u540d\uff0cSeries\u7684\u503c\u53ef\u4ee5\u7528\u6e38\u620f\uff08\u4e3a\u4e86\u4fdd\u6301\u7b80\u5355\uff0c\u8ba9\u2019A\u2019\u4e3a1 \uff09\uff1a cards = [] for suit in ['H', 'S', 'C', 'D']: cards.extend(str(num) + suit for num in base_names) deck = pd.Series(card_val, index=cards) print(deck) # AH 1 # 2H 2 # 3H 3 # 4H 4 # 5H 5 # 6H 6 # 7H 7 # 8H 8 # 9H 9 # 10H 10 # JH 10 # KH 10 # QH 10 # AS 1 # 2S 2 # 3S 3 # 4S 4 # 5S 5 # 6S 6 # 7S 7 # 8S 8 # 9S 9 # 10S 10 # JS 10 # KS 10 # QS 10 # AC 1 # 2C 2 # 3C 3 # 4C 4 # 5C 5 # 6C 6 # 7C 7 # 8C 8 # 9C 9 # 10C 10 # JC 10 # KC 10 # QC 10 # AD 1 # 2D 2 # 3D 3 # 4D 4 # 5D 5 # 6D 6 # 7D 7 # 8D 8 # 9D 9 # 10D 10 # JD 10 # KD 10 # QD 10 # dtype: int64 \u4ece\u8fd9\u526f\u724c\u4e2d\u62ff\u51fa\u4e94\u5f20\u724c\u53ef\u4ee5\u5199\u6210\uff1a def draw(_deck, n=5): return _deck.sample(n) print(draw(deck)) # KD 10 # 2S 2 # 5C 5 # 6C 6 # QD 10 # dtype: int64 \u5047\u8bbe\u8981\u4ece\u6bcf\u4e2a\u82b1\u8272\u4e2d\u968f\u673a\u62bd\u53d6\u4e24\u5f20\u724c\u3002\u7531\u4e8e\u82b1\u8272\u662f\u724c\u540d\u7684\u6700\u540e\u4e24\u4e2a\u5b57\u7b26\uff0c\u53ef\u4ee5\u57fa\u4e8e\u8fd9\u70b9\u8fdb\u884c\u5206\u7ec4\uff0c\u5e76\u4f7f\u7528 apply \uff1a get_suit = lambda card: card[-1] # \u6700\u540e\u4e00\u4e2a\u5b57\u6bcd\u662f\u82b1\u8272 result = deck.groupby(get_suit).apply(draw, n=2) print(result) # C 10C 10 # 3C 3 # D KD 10 # AD 1 # H 5H 5 # 7H 7 # S 3S 3 # 5S 5 # dtype: int64 \u6216\u8005\u4e5f\u53ef\u4ee5\u5199\u6210\uff1a result = deck.groupby(get_suit, group_keys=False).apply(draw, n=2) print(result) # JC 10 # 8C 8 # QD 10 # 4D 4 # 10H 10 # 6H 6 # 7S 7 # KS 10 # dtype: int64 \u793a\u4f8b\uff1a\u5206\u7ec4\u52a0\u6743\u5e73\u5747\u548c\u76f8\u5173\u6027 \u00b6 \u5728 groupby \u7684\u62c6\u5206-\u5e94\u7528-\u8054\u5408\u7684\u8303\u5f0f\u4e0b\uff0cDataFrame\u7684\u5217\u95f4\u64cd\u4f5c\u6216\u4e24\u4e2aSeriese\u4e4b\u95f4\u7684\u64cd\u4f5c\uff0c\u4f8b\u5982\u5b9e\u73b0\u5206\u7ec4\u52a0\u6743\u5e73\u5747\u3002 \u4e0b\u9762\u4f8b\u5b50\uff0c\u4f7f\u7528\u4e00\u4e2a\u5305\u542b\u5206\u7ec4\u952e\u548c\u6743\u91cd\u503c\u7684\u6570\u636e\u96c6\uff1a dt = np.random.randn(8) wt = np.random.randn(8) df = pd.DataFrame( { 'category': ['a', 'a', 'a', 'a', 'b', 'b', 'b', 'b'], 'data': dt, 'weight': wt } ) print(df) # category data weight # 0 a -0.250764 -0.085285 # 1 a 0.167155 -1.361254 # 2 a 0.399306 1.755542 # 3 a -0.514477 0.270124 # 4 b -0.005558 0.886514 # 5 b 0.607596 -1.384315 # 6 b -1.029627 -0.845340 # 7 b -0.294204 1.253965 \u901a\u8fc7 category \u8fdb\u884c\u5206\u7ec4\u52a0\u6743\u5e73\u5747\u5982\u4e0b\uff1a grouped = df.groupby('category') get_wavg = lambda g: np.average(g['data'], weights=g['weight']) result = grouped.apply(get_wavg) print(result) # category # a 0.614499 # b 3.863947 # dtype: float64 \u53e6\u4e00\u4e2a\u4f8b\u5b50\uff0c\u4e00\u4e2a\u4ece\u96c5\u864e\u8d22\u7ecf\u4e0a\u83b7\u5f97\u7684\u6570\u636e\u96c6\uff0c\u8be5\u6570\u636e\u96c6\u5305\u542b\u4e00\u4e9b\u6807\u666e500 \uff08SPX\u7b26\u53f7\uff09\u548c\u80a1\u7968\u7684\u6536\u76d8\u4ef7\uff1a close_px = pd.read_csv('../examples/stock_px_2.csv', parse_dates=True, index_col=0) print(close_px.info()) # # DatetimeIndex: 2214 entries, 2003-01-02 to 2011-10-14 # Data columns (total 4 columns): # # Column Non-Null Count Dtype # --- ------ -------------- ----- # 0 AAPL 2214 non-null float64 # 1 MSFT 2214 non-null float64 # 2 XOM 2214 non-null float64 # 3 SPX 2214 non-null float64 # dtypes: float64(4) # memory usage: 86.5 KB # None print(close_px[-4:]) # AAPL MSFT XOM SPX # 2011-10-11 400.29 27.00 76.27 1195.54 # 2011-10-12 402.19 26.96 77.16 1207.25 # 2011-10-13 408.43 27.18 76.37 1203.66 # 2011-10-14 422.00 27.27 78.11 1224.58 \u76ee\u6807\u4efb\u52a1\uff1a\u8ba1\u7b97\u4e00\u4e2aDataFrame\uff0c\u5b83\u5305\u542b\u6807\u666e\u6307\u6570\uff08SPX\uff09\u6bcf\u65e5\u6536\u76ca\u7684\u5e74\u5ea6\u76f8\u5173\u6027\uff08\u901a\u8fc7\u767e\u5206\u6bd4\u53d8\u5316\u8ba1\u7b97\uff09\u3002 \u9996\u5148\u521b\u5efa\u4e00\u4e2a\u8ba1\u7b97\u6bcf\u5217\u4e0e\u2019SPX\u2019\u5217\u6210\u5bf9\u5173\u8054\u7684\u51fd\u6570\uff1a spx_corr = lambda x: x.corrwith(x['SPX']) \u4e4b\u540e\uff0c\u4f7f\u7528 pct_change \u8ba1\u7b97 close-px \u767e\u5206\u6bd4\u7684\u53d8\u5316\uff1a rets = close_px.pct_change().dropna() # Percentage change between the current and a prior element. print(rets) # AAPL MSFT XOM SPX # 2003-01-03 0.006757 0.001421 0.000684 -0.000484 # 2003-01-06 0.000000 0.017975 0.024624 0.022474 # ... ... ... ... ... # 2011-10-14 0.033225 0.003311 0.022784 0.017380 # [2213 rows x 4 columns] \u6700\u540e\uff0c\u6309\u5e74\u5bf9\u767e\u5206\u6bd4\u53d8\u5316\u8fdb\u884c\u5206\u7ec4\uff0c\u53ef\u4ee5\u4f7f\u7528\u5355\u884c\u51fd\u6570\u4ece\u6bcf\u4e2a\u884c\u6807\u7b7e\u4e2d\u63d0\u53d6\u6bcf\u4e2a datetime \u6807\u7b7e\u7684 year \u5c5e\u6027\uff1a get_year = lambda x: x.year by_year = rets.groupby(get_year) result = by_year.apply(spx_corr) print(result) # AAPL MSFT XOM SPX # 2003 0.541124 0.745174 0.661265 1.0 # 2004 0.374283 0.588531 0.557742 1.0 # 2005 0.467540 0.562374 0.631010 1.0 # 2006 0.428267 0.406126 0.518514 1.0 # 2007 0.508118 0.658770 0.786264 1.0 # 2008 0.681434 0.804626 0.828303 1.0 # 2009 0.707103 0.654902 0.797921 1.0 # 2010 0.710105 0.730118 0.839057 1.0 # 2011 0.691931 0.800996 0.859975 1.0 \u53ef\u4ee5\u8ba1\u7b97\u5185\u90e8\u5217\u76f8\u5173\u6027\u3002\u8fd9\u91cc\u8ba1\u7b97\u4e86\u82f9\u679c\u548c\u5fae\u8f6f\u7684\u5e74\u5ea6\u76f8\u5173\u6027\uff1a result = by_year.apply(lambda g: g['AAPL'].corr(g['MSFT'])) print(result) # 2003 0.480868 # 2004 0.259024 # 2005 0.300093 # 2006 0.161735 # 2007 0.417738 # 2008 0.611901 # 2009 0.432738 # 2010 0.571946 # 2011 0.581987 # dtype: float64 \u793a\u4f8b\uff1a\u9010\u7ec4\u7ebf\u6027\u56de\u5f52 \u00b6 \u5b9a\u4e49\u4ee5\u4e0b regress \uff08\u56de\u5f52\uff09\u51fd\u6570\uff08\u4f7f\u7528 statsmodels \u8ba1\u91cf\u7ecf\u6d4e\u5b66\u5e93\uff09\uff0c\u8be5\u51fd\u6570\u5bf9\u6bcf\u4e2a\u6570\u636e\u5757\u6267\u884c\u666e\u901a\u6700\u5c0f\u4e8c\u4e58\uff08OLS\uff09\u56de\u5f52\uff1a def regress(data, yvar, xvars): Y = data[yvar] X = data[xvars] X['intercept'] = 1. result = sm.OLS(Y, X).fit() return result.params \u73b0\u5728\u8981\u8ba1\u7b97AAPL\u5728SPX\u56de\u62a5\u4e0a\u7684\u5e74\u5ea6\u7ebf\u6027\u56de\u5f52\uff1a result = by_year.apply(regress, 'AAPL', ['SPX']) print(result) # SPX intercept # 2003 1.195406 0.000710 # 2004 1.363463 0.004201 # 2005 1.766415 0.003246 # 2006 1.645496 0.000080 # 2007 1.198761 0.003438 # 2008 0.968016 -0.001110 # 2009 0.879103 0.002954 # 2010 1.052608 0.001261 # 2011 0.806605 0.001514 \u6570\u636e\u900f\u89c6\u8868\u4e0e\u4ea4\u53c9\u8868 \u00b6 \u6570\u636e\u900f\u89c6\u8868 \u00b6 \u6570\u636e\u900f\u89c6\u8868\u662f\u7535\u5b50\u8868\u683c\u7a0b\u5e8f\u548c\u5176\u4ed6\u6570\u636e\u5206\u6790\u8f6f\u4ef6\u4e2d\u5e38\u89c1\u7684\u6570\u636e\u6c47\u603b\u5de5\u5177\u3002 \u5b83\u6839\u636e\u4e00\u4e2a\u6216\u591a\u4e2a\u952e\u805a\u5408\u4e00\u5f20\u8868\u7684\u6570\u636e\uff0c\u5c06\u6570\u636e\u5728\u77e9\u5f62\u683c\u5f0f\u4e2d\u6392\u5217\uff0c\u5176\u4e2d\u4e00\u4e9b\u5206\u7ec4\u952e\u662f\u6cbf\u7740\u884c\u7684\uff0c\u53e6\u4e00\u4e9b\u662f\u6cbf\u7740\u5217\u7684\u3002 Python\u4e2d\u7684pandas\u900f\u89c6\u8868\u662f\u901a\u8fc7\u8fd9\u91cc\u6240\u4ecb\u7ecd\u7684groupby\u5de5\u5177\u4ee5\u53ca\u4f7f\u7528\u5206\u5c42\u7d22\u5f15\u7684\u91cd\u5851\u64cd\u4f5c\u5b9e\u73b0\u7684\u3002 DataFrame\u62e5\u6709\u4e00\u4e2a pivot_table \u65b9\u6cd5\uff0c\u5e76\u4e14\u8fd8\u6709\u8fd8\u4e00\u4e2a\u9876\u5c42\u7684 pandas.pivot_table \u51fd\u6570\u3002 \u9664\u4e86\u4e3a groupby \u63d0\u4f9b\u4e00\u4e2a\u65b9\u4fbf\u63a5\u53e3\uff0c pivot_table \u8fd8\u53ef\u4ee5\u6dfb\u52a0\u90e8\u5206\u603b\u8ba1\uff0c\u4e5f\u79f0\u4f5c\u8fb9\u8ddd\u3002 import pandas as pd import numpy as np \u6839\u636e\u4e0b\u9762\u7684\u5c0f\u8d39\u6570\u636e\u96c6\uff0c\u8ba1\u7b97\u4e00\u5f20\u5728\u884c\u65b9\u5411\u4e0a\u6309 day \u548c smoker \u6392\u5217\u7684\u5206\u7ec4\u5e73\u5747\u503c\uff08\u9ed8\u8ba4\u7684 pivot_table \u805a\u5408\u7c7b\u578b\uff09\u7684\u8868\u3002 pivot_table \u9009\u9879\uff1a values: \u9700\u8981\u805a\u5408\u7684\u5217\u540d\uff0c\u9ed8\u8ba4\u60c5\u51b5\u4e0b\u805a\u5408\u6240\u6709\u6570\u503c\u578b\u7684\u5217\u3002 index: \u5728\u7ed3\u679c\u900f\u89c6\u8868\u7684\u884c\u4e0a\u8fdb\u884c\u5206\u7ec4\u7684\u5217\u540d\u6216\u8005\u5176\u4ed6\u5206\u7ec4\u952e\u3002 tips = pd.read_csv('../examples/tips.csv') tips['tip_pct'] = tips['tip'] / (tips['total_bill'] - tips['tip']) \u6837\u672c\u6570\u636e\u3002 print(tips.head(5)) # total_bill tip smoker day time size tip_pct # 0 16.99 1.01 No Sun Dinner 2 0.063204 # 1 10.34 1.66 No Sun Dinner 3 0.191244 # 2 21.01 3.50 No Sun Dinner 3 0.199886 # 3 23.68 3.31 No Sun Dinner 2 0.162494 # 4 24.59 3.61 No Sun Dinner 4 0.172069 \u8ba1\u7b97\u5728\u884c\u65b9\u5411\u4e0a\u6309 day \u548c smoker \u6392\u5217\u7684\u5206\u7ec4\u5e73\u5747\u503c\u3002\u4e5f\u53ef\u4ee5\u76f4\u63a5\u4f7f\u7528 groupby \u5b9e\u73b0\u3002 result = tips.pivot_table(index=['day', 'smoker']) print(result) # size tip tip_pct total_bill # day smoker # Fri No 2.250000 2.812500 0.179740 18.420000 # Yes 2.066667 2.714000 0.216293 16.813333 # Sat No 2.555556 3.102889 0.190412 19.661778 # Yes 2.476190 2.875476 0.179833 21.276667 # Sun No 2.929825 3.167895 0.193617 20.506667 # Yes 2.578947 3.516842 0.322021 24.120000 # Thur No 2.488889 2.673778 0.193424 17.113111 # Yes 2.352941 3.030000 0.198508 19.190588 \u5728 tip_pct \u548c size \u4e0a\u8fdb\u884c\u805a\u5408\uff0c\u5e76\u6839\u636e time \u5206\u7ec4\u3002\u5c06\u628a smoker \u653e\u5165\u8868\u7684\u5217\uff0c\u800c\u5c06 day \u653e\u5165\u8868\u7684\u884c\uff1a result = tips.pivot_table( ['tip_pct', 'size'], index=['time', 'day'], columns='smoker' ) print(result) # size tip_pct # smoker No Yes No Yes # time day # Dinner Fri 2.000000 2.222222 0.162612 0.202545 # Sat 2.555556 2.476190 0.190412 0.179833 # Sun 2.929825 2.578947 0.193617 0.322021 # Thur 2.000000 NaN 0.190114 NaN # Lunch Fri 3.000000 1.833333 0.231125 0.236915 # Thur 2.500000 2.352941 0.193499 0.198508 \u901a\u8fc7\u4f20\u9012 margins=True \u6765\u6269\u5145\u8fd9\u4e2a\u8868\u6765\u5305\u542b\u90e8\u5206\u603b\u8ba1\u3002\u8fd9\u4f1a\u6dfb\u52a0 All \u884c\u548c\u5217\u6807\u7b7e\uff0c\u5176\u4e2d\u76f8\u5e94\u7684\u503c\u662f\u5355\u5c42\u4e2d\u6240\u6709\u6570\u636e\u7684\u5206\u7ec4\u7edf\u8ba1\u503c\u3002 \u8fd9\u91cc All \u7684\u503c\u662f\u5747\u503c\uff0c\u4e14\u8be5\u5747\u503c\u662f\u4e0d\u8003\u8651\u5438\u70df\u8005\u4e0e\u975e\u5438\u70df\u8005\uff08 All \u5217\uff09\u6216\u884c\u5206\u7ec4\u4e2d\u4efb\u4f55\u4e24\u7ea7\u7684\uff08 All \u884c\uff09\u3002 result = tips.pivot_table( ['tip_pct', 'size'], index=['time', 'day'], columns='smoker', margins=True ) print(result) # size tip_pct # smoker No Yes All No Yes All # time day # Dinner Fri 2.000000 2.222222 2.166667 0.162612 0.202545 0.192562 # Sat 2.555556 2.476190 2.517241 0.190412 0.179833 0.185305 # Sun 2.929825 2.578947 2.842105 0.193617 0.322021 0.225718 # Thur 2.000000 NaN 2.000000 0.190114 NaN 0.190114 # Lunch Fri 3.000000 1.833333 2.000000 0.231125 0.236915 0.236088 # Thur 2.500000 2.352941 2.459016 0.193499 0.198508 0.194895 # All 2.668874 2.408602 2.569672 0.192237 0.218176 0.202123 \u8981\u4f7f\u7528\u4e0d\u540c\u7684\u805a\u5408\u51fd\u6570\u65f6\uff0c\u5c06\u51fd\u6570\u4f20\u9012\u7ed9 aggfunc \u3002\u4f8b\u5982\uff0c count \u6216\u8005 len \u5c06\u7ed9\u51fa\u4e00\u5f20\u5206\u7ec4\u5927\u5c0f\u7684\u4ea4\u53c9\u8868\uff08\u8ba1\u6570\u6216\u51fa\u73b0\u9891\u7387\uff09\uff1a result = tips.pivot_table( ['tip_pct', 'size'], index=['time', 'day'], columns='smoker', aggfunc=len, margins=True ) print(result) # size tip_pct # smoker No Yes All No Yes All # time day # Dinner Fri 3.0 9.0 12 3.0 9.0 12 # Sat 45.0 42.0 87 45.0 42.0 87 # Sun 57.0 19.0 76 57.0 19.0 76 # Thur 1.0 NaN 1 1.0 NaN 1 # Lunch Fri 1.0 6.0 7 1.0 6.0 7 # Thur 44.0 17.0 61 44.0 17.0 61 # All 151.0 93.0 244 151.0 93.0 244 \u5bf9\u4e8e\u7a7a\u503c NA \uff0c\u4f20\u9012\u4e00\u4e2a fill_value \u3002 result = tips.pivot_table( ['tip_pct', 'size'], index=['time', 'day'], columns='smoker', aggfunc='mean', fill_value=0, margins=True ) print(result) # size tip_pct # smoker No Yes All No Yes All # time day # Dinner Fri 2.000000 2.222222 2.166667 0.162612 0.202545 0.192562 # Sat 2.555556 2.476190 2.517241 0.190412 0.179833 0.185305 # Sun 2.929825 2.578947 2.842105 0.193617 0.322021 0.225718 # Thur 2.000000 0.000000 2.000000 0.190114 0.000000 0.190114 # Lunch Fri 3.000000 1.833333 2.000000 0.231125 0.236915 0.236088 # Thur 2.500000 2.352941 2.459016 0.193499 0.198508 0.194895 # All 2.668874 2.408602 2.569672 0.192237 0.218176 0.202123 \u4ea4\u53c9\u8868\uff1acrosstab \u00b6 \u4ea4\u53c9\u8868\uff08\u7b80\u5199\u4e3acrosstab\uff09\u662f\u6570\u636e\u900f\u89c6\u8868\u7684\u4e00\u4e2a\u7279\u6b8a\u60c5\u51b5\uff0c\u8ba1\u7b97\u7684\u662f\u5206\u7ec4\u4e2d\u7684\u9891\u7387\u3002 crosstab \u7684\u524d\u4e24\u4e2a\u53c2\u6570\u53ef\u662f\u6570\u7ec4\u3001Series\u6216\u6570\u7ec4\u7684\u5217\u8868\u3002 sample = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10] nationality = ['USA', 'Japan', 'USA', 'Japan', 'Japan', 'Japan', 'USA', 'USA', 'Japan', 'USA'] handedness = ['Right-handed', 'Left-handed', 'Right-handed', 'Right-handed', 'Left-handed', 'Right-handed', 'Right-handed', 'Left-handed', 'Right-handed', 'Right-handed'] df = pd.DataFrame( { 'sample': sample, 'nationality': nationality, 'handedness': handedness } ) print(df) # sample nationality handedness # 0 1 USA Right-handed # 1 2 Japan Left-handed # 2 3 USA Right-handed # 3 4 Japan Right-handed # 4 5 Japan Left-handed # 5 6 Japan Right-handed # 6 7 USA Right-handed # 7 8 USA Left-handed # 8 9 Japan Right-handed # 9 10 USA Right-handed \u6309\u7167\u56fd\u7c4d\u548c\u60ef\u7528\u6027\u6765\u603b\u7ed3\u8fd9\u4e9b\u6570\u636e\uff0c\u53ef\u4ee5\u4f7f\u7528 pivot_table \u6765\u5b9e\u73b0\u8fd9\u4e2a\u529f\u80fd\uff0c\u4f46\u662f pandas.crosstable \u51fd\u6570\u66f4\u4e3a\u65b9\u4fbf\uff1a result = pd.crosstab(df.nationality, df.handedness, margins=True) print(result) # handedness Left-handed Right-handed All # nationality # Japan 2 3 5 # USA 1 4 5 # All 3 7 10 \u5728\u5c0f\u8d39\u6570\u636e\u4e2d\u53ef\u4ee5\u8fd9\u4e48\u505a\uff1a result = pd.crosstab(['tips.time', tips.day], tips.smoker, margins=True) print(result) # smoker No Yes All # row_0 day # tips.time Fri 4 15 19 # Sat 45 42 87 # Sun 57 19 76 # Thur 45 17 62 # All 151 93 244","title":"\u6570\u636e\u805a\u5408\u4e0e\u5206\u7ec4\u64cd\u4f5c"},{"location":"python/DataAnalysis/ch07/#_1","text":"","title":"\u6570\u636e\u805a\u5408\u4e0e\u5206\u7ec4\u64cd\u4f5c"},{"location":"python/DataAnalysis/ch07/#groupby","text":"import pandas as pd import numpy as np","title":"GroupBy\u673a\u5236"},{"location":"python/DataAnalysis/ch07/#_2","text":"\u5206\u7ec4\u64cd\u4f5c\u7b2c\u4e00\u6b65\uff0c\u6570\u636e\u5305\u542b\u5728pandas\u5bf9\u8c61\u4e2d\uff0c\u53ef\u4ee5\u662fSeries\u3001DataFrame\u6216\u5176\u4ed6\u6570\u636e\u7ed3\u6784\u3002\u4e4b\u540e\u6839\u636e\u63d0\u4f9b\u7684\u4e00\u4e2a\u6216\u591a\u4e2a\u952e\u5206\u79bb\u5230\u5404\u4e2a\u7ec4\u4e2d\u3002 \u5206\u7ec4\u952e\u53ef\u662f\u591a\u79cd\u5f62\u5f0f\u7684\uff0c\u5e76\u4e14\u952e\u4e0d\u4e00\u5b9a\u662f\u5b8c\u5168\u76f8\u540c\u7684\u7c7b\u578b(\u6ce8\u610f\u540e\u9762\u4ecb\u7ecd\u7684\u4e09\u4e2a\u65b9\u6cd5\u662f\u53ef\u4ee5\u4ea7\u751f\u7528\u4e8e\u5206\u9694\u5bf9\u8c61\u7684\u503c\u6570\u7ec4\u7684\u5feb\u6377\u65b9\u5f0f)\uff1a \u4e0e\u9700\u8981\u5206\u7ec4\u7684\u8f74\u5411\u957f\u5ea6\u4e00\u81f4\u7684\u503c\u5217\u8868\u6216\u503c\u6570\u7ec4\u3002\u9ed8\u8ba4\u60c5\u51b5\u4e0b\uff0cgroupby\u5728axis=0\u7684\u8f74\u5411\u4e0a\u5206\u7ec4\u3002 DataFrame\u7684\u5217\u540d\u7684\u503c\u3002 \u53ef\u4ee5\u5c06\u5206\u7ec4\u8f74\u5411\u4e0a\u7684\u503c\u548c\u5206\u7ec4\u540d\u79f0\u76f8\u5339\u914d\u7684\u5b57\u5178\u6216Series\u3002 \u53ef\u4ee5\u5728\u8f74\u7d22\u5f15\u6216\u7d22\u5f15\u4e2d\u7684\u5355\u4e2a\u6807\u7b7e\u4e0a\u8c03\u7528\u7684\u51fd\u6570\u3002 \u8bf7\u6ce8\u610f\uff0c\u5206\u7ec4\u952e\u4e2d\u7684\u4efb\u4f55\u7f3a\u5931\u503c\u5c06\u88ab\u6392\u9664\u5728\u7ed3\u679c\u4e4b\u5916\u3002 \u5206\u79bb\u64cd\u4f5c\u662f\u5728\u6570\u636e\u5bf9\u8c61\u7684\u7279\u5b9a\u8f74\u5411\u4e0a\u8fdb\u884c\u7684\u3002\u4f8b\u5982\uff0cDataFrame\u53ef\u4ee5\u5728\u5b83\u7684\u884c\u65b9\u5411\uff08axis=0\uff09\u6216\u5217\u65b9\u5411\uff08axis=1\uff09\u8fdb\u884c\u5206\u7ec4\u3002 \u5206\u7ec4\u64cd\u4f5c\u540e\uff0c\u4e00\u4e2a\u51fd\u6570\u5c31\u53ef\u4ee5\u5e94\u7528\u5230\u5404\u4e2a\u7ec4\u4e2d\uff0c\u4ea7\u751f\u65b0\u7684\u503c\u3002\u6700\u7ec8\uff0c\u6240\u6709\u51fd\u6570\u7684\u5e94\u7528\u7ed3\u679c\u4f1a\u8054\u5408\u4e3a\u4e00\u4e2a\u7ed3\u679c\u5bf9\u8c61\u3002 df = pd.DataFrame( { 'key1': ['a', 'a', 'b', 'b', 'a'], 'key2': ['one', 'two', 'one', 'two', 'one'], 'data1': [1, 3, 5, 7, 9], 'data2': [2, 4, 6, 8, 10] } ) \u6839\u636ekey1\u6807\u7b7e\u8ba1\u7b97data1\u5217\u7684\u5747\u503c\uff0c\u65b9\u6cd5\u4e00\uff0c\u8bbf\u95ee data1 \u5e76\u4f7f\u7528 key1 \u5217\uff08\u5b83\u662f\u4e00\u4e2aSeries\uff09\u8c03\u7528 groupby \u65b9\u6cd5\uff1a grouped = df['data1'].groupby(df['key1']) print(grouped) # grouped \u53d8\u91cf\u73b0\u5728\u662f\u4e00\u4e2a GroupBy \u5bf9\u8c61\uff0c\u5b83\u5b9e\u9645\u4e0a\u8fd8\u6ca1\u6709\u8fdb\u884c\u4efb\u4f55\u8ba1\u7b97\uff0c\u62e5\u6709\u4e00\u4e9b\u5173\u4e8e\u5206\u7ec4\u952edf['key1']\u7684\u4e00\u4e9b\u4e2d\u95f4\u6570\u636e\u7684\u4fe1\u606f\u3002 \u4e0b\u9762\u5bf9 grouped \u5bf9\u8c61\u505a\u4e00\u4e9b\u64cd\u4f5c\uff1a result = grouped.mean() # \u8ba1\u7b97\u5e73\u5747\u503c print(result) # key1 # a 4.333333 # b 6.000000 # Name: data1, dtype: float64 grouped_means = df['data1'].groupby([df['key1'], df['key2']]).mean() print(grouped_means) # key1 key2 # a one 5.0 # two 3.0 # b one 5.0 # two 7.0 # Name: data1, dtype: float64 \u4e0a\u9762\u4f8b\u5b50\u4f7f\u7528\u4e86\u4e24\u4e2a\u952e\u5bf9\u6570\u636e\u8fdb\u884c\u5206\u7ec4\uff0c\u5e76\u4e14\u7ed3\u679cSeries\u73b0\u5728\u62e5\u6709\u4e00\u4e2a\u5305\u542b\u552f\u4e00\u952e\u5bf9\u7684\u591a\u5c42\u7d22\u5f15\u3002 \u4e0b\u9762\u5bf9\u8ba1\u7b97\u7684\u5e73\u5747\u503c\uff08mean\uff09\u8fdb\u884c\u91cd\u5851\uff08unstack\uff09\u3002 print(grouped_means.unstack()) # key2 one two # key1 # a 5.0 3.0 # b 5.0 7.0 \u5206\u7ec4\u4fe1\u606f\u901a\u5e38\u5305\u542b\u5728\u540c\u4e00\u4e2aDataFrame\u4e2d\u3002\u5728\u8fd9\u79cd\u60c5\u51b5\u4e0b\uff0c\u53ef\u4ee5\u4f20\u9012\u5217\u540d\uff08\u65e0\u8bba\u90a3\u4e9b\u5217\u540d\u662f\u5b57\u7b26\u4e32\u3001\u6570\u5b57\u6216\u5176\u4ed6Python\u5bf9\u8c61\uff09\u4f5c\u4e3a\u5206\u7ec4\u952e\uff1a \u4e0b\u9762\u4f8b\u5b50\u4e2d df.groupby('key1').mean() \u7684\u7ed3\u679c\u91cc\u5e76\u6ca1\u6709 key2 \u5217\u3002\u8fd9\u662f\u56e0\u4e3a df['key2'] \u5e76\u4e0d\u662f\u6570\u503c\u6570\u636e\uff0c\u5373 df['key2'] \u662f\u4e00\u4e2a\u5197\u4f59\u5217\uff0c\u56e0\u6b64\u88ab\u6392\u9664\u5728\u7ed3\u679c\u4e4b\u5916\u3002 result = df.groupby('key1').mean() print(result) # data1 data2 # key1 # a 4.333333 5.333333 # b 6.000000 7.000000 result = df.groupby(['key1', 'key2']).mean() print(result) # data1 data2 # key1 key2 # a one 5.0 6.0 # two 3.0 4.0 # b one 5.0 6.0 # two 7.0 8.0 result = df.groupby(['key1', 'key2']).size() print(result) # key1 key # a one 2 # two 1 # b one 1 # two 1 # dtype: int64","title":"\u5206\u7ec4\u673a\u5236"},{"location":"python/DataAnalysis/ch07/#_3","text":"GroupBy \u5bf9\u8c61\u652f\u6301\u8fed\u4ee3\uff0c\u4f1a\u751f\u6210\u4e00\u4e2a\u5305\u542b\u7ec4\u540d\u548c\u6570\u636e\u5757\u76842\u7ef4\u5143\u7ec4\u5e8f\u5217\u3002 df = pd.DataFrame( { 'key1': ['a', 'a', 'b', 'b', 'a'], 'key2': ['one', 'two', 'one', 'two', 'one'], 'data1': [1, 3, 5, 7, 9], 'data2': [2, 4, 6, 8, 10] } ) \u5355\u4e2a\u5206\u7ec4\u952e\u7684\u60c5\u51b5: for name, group in df.groupby('key1'): print(name) print(group) # a # key1 key2 data1 data2 # 0 a one 1 2 # 1 a two 3 4 # 4 a one 9 10 # b # key1 key2 data1 data2 # 2 b one 5 6 # 3 b two 7 8 \u591a\u4e2a\u5206\u7ec4\u952e\u7684\u60c5\u51b5: \u5143\u7ec4\u4e2d\u7684\u7b2c\u4e00\u4e2a\u5143\u7d20\u662f\u952e\u503c\u7684\u5143\u7ec4\u3002 for (k1, k2), group in df.groupby(['key1', 'key2']): print((k1, k2)) print(group) # ('a', 'one') # key1 key2 data1 data2 # 0 a one 1 2 # 4 a one 9 10 # ('a', 'two') # key1 key2 data1 data2 # 1 a two 3 4 # ('b', 'one') # key1 key2 data1 data2 # 2 b one 5 6 # ('b', 'two') # key1 key2 data1 data2 # 3 b two 7 8 result = dict(list(df.groupby('key1'))) print(result) # df.groupby('key1')\u7684\u7ed3\u679c\u662f\u4e00\u4e2a\u5bf9\u8c61 # # list(df.groupby('key1'))\u7684\u7ed3\u679c\u662f\u5305\u542bFrameData\u7684\u7ed3\u6784\u7684\u5217\u8868list: # [ # ('a', key1 key2 data1 data2 # 0 a one 1 2 # 1 a two 3 4 # 4 a one 9 10), # ('b', key1 key2 data1 data2 # 2 b one 5 6 # 3 b two 7 8) # ] # dict(list(df.groupby('key1')))\u7684\u7ed3\u679c\u662f\u5305\u542bFrameData\u7684\u7ed3\u6784\u7684\u5b57\u5178dict # { # 'a': key1 key2 data1 data2 # 0 a one 1 2 # 1 a two 3 4 # 4 a one 9 10, # 'b': key1 key2 data1 data2 # 2 b one 5 6 # 3 b two 7 8 # } print(result['b']) # key1 key2 data1 data2 # 2 b one 5 6 # 3 b two 7 8 \u9ed8\u8ba4\u60c5\u51b5\u4e0b\uff0c groupby \u5728 axis=0 \u7684\u8f74\u5411\u4e0a\u5206\u7ec4\uff0c\u4e5f\u53ef\u4ee5\u5728\u5176\u4ed6\u4efb\u610f\u8f74\u5411\u4e0a\u8fdb\u884c\u5206\u7ec4\u3002 print(df.dtypes) # key1 object # key2 object # data1 int64 # data2 int64 # dtype: object grouped = df.groupby(df.dtypes, axis=1) print(grouped) # print(list(grouped)) # [ # (dtype('int64'), data1 data2 # 0 1 2 # 1 3 4 # 2 5 6 # 3 7 8 # 4 9 10), # (dtype('O'), key1 key2 # 0 a one # 1 a two # 2 b one # 3 b two # 4 a one) # ] \u6253\u5370\u5404\u5206\u7ec4\u5982\u4e0b\uff1a for dtype, group in grouped: print(dtype) print(group) # int64 # data1 data2 # 0 1 2 # 1 3 4 # 2 5 6 # 3 7 8 # 4 9 10 # object # key1 key2 # 0 a one # 1 a two # 2 b one # 3 b two # 4 a one","title":"\u904d\u5386\u5404\u5206\u7ec4"},{"location":"python/DataAnalysis/ch07/#_4","text":"\u5bf9\u4e8e\u4eceDataFrame\u521b\u5efa\u7684 GroupBy \u5bf9\u8c61\uff0c\u7528\u5217\u540d\u79f0\u6216\u5217\u540d\u79f0\u6570\u7ec4\u8fdb\u884c\u7d22\u5f15\u65f6\uff0c\u4f1a\u4ea7\u751f\u7528\u4e8e\u805a\u5408\u7684\u5217\u5b50\u96c6\u7684\u6548\u679c\u3002 \u5982\u679c\u4f20\u9012\u7684\u662f\u5217\u8868\u6216\u6570\u7ec4\uff0c\u5219\u6b64\u7d22\u5f15\u64cd\u4f5c\u8fd4\u56de\u7684\u5bf9\u8c61\u662f\u5206\u7ec4\u7684DataFrame\uff1b\u5982\u679c\u53ea\u6709\u5355\u4e2a\u5217\u540d\u4f5c\u4e3a\u6807\u91cf\u4f20\u9012\uff0c\u5219\u4e3a\u5206\u7ec4\u7684Series\uff1b \u5bf9\u6bd4\u4e0b\u97624\u53e5\uff1a result = df.groupby('key1')['data1'] # \u5355\u4e2a\u5217\u540d print(result) # for key, data in result: print(key) print(data) result = df['data1'].groupby(df['key1']) # \u5355\u4e2a\u5217\u540d print(result) # for key, data in result: print(key) print(data) # a # 0 1 # 1 3 # 4 9 # Name: data1, dtype: int64 # b # 2 5 # 3 7 # Name: data1, dtype: int64 result = df.groupby('key1')[['data1']] # \u5217\u8868\u6216\u6570\u7ec4 print(result) # for key, data in result: print(key) print(data) # a # key1 key2 data1 data2 # 0 a one 1 2 # 1 a two 3 4 # 4 a one 9 10 # b # key1 key2 data1 data2 # 2 b one 5 6 # 3 b two 7 8 result = df[['data1']].groupby(df['key1']) # \u5217\u8868\u6216\u6570\u7ec4 print(result) # for key, data in result: print(key) print(data) # a # data1 # 0 1 # 1 3 # 4 9 # b # data1 # 2 5 # 3 7","title":"\u9009\u62e9\u4e00\u5217\u6216\u6240\u6709\u5217\u7684\u5b50\u96c6"},{"location":"python/DataAnalysis/ch07/#series","text":"\u5206\u7ec4\u4fe1\u606f\u53ef\u80fd\u4f1a\u4ee5\u975e\u6570\u7ec4\u5f62\u5f0f\u5b58\u5728\u3002 \u751f\u6210\u4e00\u4e2a\u793a\u4f8bDataFrame\u3002 people = pd.DataFrame( [[1, 3, 5, 7, 9], [0, 2, 4, 6, 8], [0, 2, 4, 6, 8], [1, 3, 5, 7, 9], [1, 2, 3, 4, 5]], columns=['a', 'b', 'c', 'd', 'e'], index=['Joe', 'Steve', 'Wes', 'Jim', 'Travis'] ) \u6dfb\u52a0\u4e00\u4e9bNA\u503c\u3002 people.iloc[2:3, [1, 2]] = np.nan print(people) # a b c d e # Joe 1 3.0 5.0 7 9 # Steve 0 2.0 4.0 6 8 # Wes 0 NaN NaN 6 8 # Jim 1 3.0 5.0 7 9 # Travis 1 2.0 3.0 4 5 \u5047\u8bbe\u6709\u5982\u4e0b\u5404\u5217\u7684\u5206\u7ec4\u5bf9\u5e94\u5173\u7cfb\uff0c\u5e76\u4e14\u60f3\u628a\u5404\u5217\u6309\u7ec4\u7d2f\u52a0\u3002 mapping = { 'a': 'red', 'b': 'red', 'c': 'blue', 'd': 'blue', 'e': 'red', 'f': 'orange' # \u6ce8\u610f\uff1a\u5065f\u867d\u7136\u6ca1\u6709\u88ab\u7528\u5230\uff0c\u4f46\u4e0d\u5f71\u54cd\u5728\u8fd9\u91cc\u5b9a\u4e49\u3002 } \u628a mapping \u8fd9\u4e2a\u5b57\u5178\u4f20\u7ed9 groupby() \u3002 by_column = people.groupby(mapping, axis=1) print(by_column.sum()) # blue red # Joe 12.0 13.0 # Steve 10.0 10.0 # Wes 6.0 8.0 # Jim 12.0 13.0 # Travis 7.0 8.0 Series\u4e5f\u6709\u76f8\u540c\u7684\u529f\u80fd\uff0c\u53ef\u4ee5\u89c6\u4e3a\u56fa\u5b9a\u5927\u5c0f\u7684\u6620\u5c04\u3002 map_services = pd.Series(mapping) print(map_services) # a red # b red # c blue # d blue # e red # f orange # dtype: object result = people.groupby(map_services, axis=1).count() print(result) # blue red # Joe 2 3 # Steve 2 3 # Wes 1 2 # Jim 2 3 # Travis 2 3","title":"\u4f7f\u7528\u5b57\u5178\u548cSeries\u5206\u7ec4"},{"location":"python/DataAnalysis/ch07/#_5","text":"\u4e0e\u4f7f\u7528\u5b57\u5178\u6216Series\u5206\u7ec4\u76f8\u6bd4\uff0c\u4f7f\u7528Python\u51fd\u6570\u662f\u5b9a\u4e49\u5206\u7ec4\u5173\u7cfb\u7684\u4e00\u79cd\u66f4\u4e3a\u901a\u7528\u7684\u65b9\u5f0f\u3002 \u4f5c\u4e3a\u5206\u7ec4\u952e\u4f20\u9012\u7684\u51fd\u6570\u5c06\u4f1a\u6309\u7167\u6bcf\u4e2a\u7d22\u5f15\u503c\u8c03\u7528\u4e00\u6b21\uff0c\u540c\u65f6\u8fd4\u56de\u503c\u4f1a\u88ab\u7528\u4f5c\u5206\u7ec4\u540d\u79f0\u3002\u6ce8\u610f\uff1a\u51fd\u6570\u662f\u4f5c\u7528\u5728\u7d22\u5f15\u4e0a\u3002 result = people.groupby(len).sum() # \u4eba\u7684\u540d\u5b57\u662f\u7d22\u5f15\u503c\uff0c\u6839\u636e\u540d\u5b57\u7684\u957f\u5ea6\u6765\u8fdb\u884c\u5206\u7ec4 print(result) # a b c d e # 3 2 6.0 10.0 20 26 # 5 0 2.0 4.0 6 8 # 6 1 2.0 3.0 4 5 \u53ef\u4ee5\u5c06\u51fd\u6570\u4e0e\u6570\u7ec4\u3001\u5b57\u5178\u6216Series\u8fdb\u884c\u6df7\u5408\uff0c\u6240\u6709\u7684\u5bf9\u8c61\u90fd\u4f1a\u5728\u5185\u90e8\u8f6c\u6362\u4e3a\u6570\u7ec4\u3002 key_list = ['one', 'one', 'one', 'two', 'two'] result = people.groupby([len, key_list]).min() print(result) # a b c d e # 3 one 0 3.0 5.0 6 8 # two 1 3.0 5.0 7 9 # 5 one 0 2.0 4.0 6 8 # 6 two 1 2.0 3.0 4 5","title":"\u4f7f\u7528\u51fd\u6570\u5206\u7ec4"},{"location":"python/DataAnalysis/ch07/#_6","text":"\u6839\u636e\u5c42\u7ea7\u5206\u7ec4\u65f6\uff0c\u5c06\u5c42\u7ea7\u6570\u503c\u6216\u5c42\u7ea7\u540d\u79f0\u4f20\u9012\u7ed9 level \u5173\u952e\u5b57\u3002 columns = pd.MultiIndex.from_arrays( [['US', 'US', 'US', 'JP', 'JP'], [1, 3, 5, 1, 3]], names=['cty', 'tenor'] ) hier_df = pd.DataFrame( [[1, 3, 5, 7, 9], [0, 2, 4, 6, 8], [1, 3, 5, 7, 9], [1, 2, 3, 4, 5]], columns=columns ) print(hier_df) # cty US JP # tenor 1 3 5 1 3 # 0 1 3 5 7 9 # 1 0 2 4 6 8 # 2 1 3 5 7 9 # 3 1 2 3 4 5 result = hier_df.groupby(level='cty', axis=1).count() print(result) # cty JP US # 0 2 3 # 1 2 3 # 2 2 3 # 3 2 3","title":"\u6839\u636e\u7d22\u5f15\u5c42\u7ea7\u5206\u7ec4"},{"location":"python/DataAnalysis/ch07/#_7","text":"\u805a\u5408\u662f\u6307\u6240\u6709\u6839\u636e\u6570\u7ec4\u4ea7\u751f\u6807\u91cf\u503c\u7684\u6570\u636e\u8f6c\u6362\u8fc7\u7a0b\uff0c\u6bd4\u5982\uff1a mean \u3001 count \u3001 min \u548c sum \u7b49\u4e00\u4e9b\u805a\u5408\u64cd\u4f5c\u3002 import pandas as pd import numpy as np \u9884\u5907\u77e5\u8bc6\uff1a \u5206\u4f4d\u6570\uff08Quantile\uff09\uff0c\u4e5f\u79f0\u5206\u4f4d\u70b9\uff0c\u662f\u6307\u5c06\u4e00\u4e2a\u968f\u673a\u53d8\u91cf\u7684\u6982\u7387\u5206\u5e03\u8303\u56f4\u5206\u4e3a\u51e0\u4e2a\u7b49\u4efd\u7684\u6570\u503c\u70b9\uff0c\u5206\u6790\u5176\u6570\u636e\u53d8\u91cf\u7684\u8d8b\u52bf\u3002 \u5e38\u7528\u7684\u5206\u4f4d\u6570\u6709 \u4e2d\u4f4d\u6570\u3001\u56db\u5206\u4f4d\u6570\u3001\u767e\u5206\u4f4d\u6570\u7b49\u3002 \u4e2d\u4f4d\u6570\uff08Medians\uff09\u662f\u4e00\u4e2a\u7edf\u8ba1\u5b66\u7684\u4e13\u6709\u540d\u8bcd\uff0c\u4ee3\u8868\u4e00\u4e2a\u6837\u672c\u3001\u79cd\u7fa4\u6216\u6982\u7387\u5206\u5e03\u4e2d\u7684\u4e00\u4e2a\u6570\u503c\uff0c\u53ef\u4ee5\u5c06\u6570\u503c\u96c6\u5408\u5212\u5206\u4e3a\u76f8\u7b49\u7684\u4e24\u90e8\u5206\u3002 \u5229\u7528pandas\u5e93\u8ba1\u7b97 data = [6, 47, 49, 15, 42, 41, 7, 39, 43, 40, 36] \u7684\u5206\u4f4d\u6570\u3002 \u786e\u5b9a p \u5206\u4f4d\u6570\u4f4d\u7f6e\u7684\u4e24\u79cd\u65b9\u6cd5( n \u4e3a\u6570\u636e\u7684\u603b\u4e2a\u6570\uff0c p \u4e3a 0-1 \u4e4b\u95f4\u7684\u503c)\u3002\u5728python\u4e2d\u8ba1\u7b97\u5206\u4f4d\u6570\u4f4d\u7f6e\u7684\u65b9\u6848\u91c7\u7528 position=1+(n-1)*p \uff1a position = (n+1)*p position = 1 + (n-1)*p \u6848\u4f8b1 data = pd.Series(np.array([6, 47, 49, 15, 42, 41, 7, 39, 43, 40, 36])) print(\"\u6570\u636e\u683c\u5f0f\uff1a\") print(np.sort(data)) # \u5fc5\u987b\u8981\u6392\u5e8f print('Q1:', data.quantile(.25)) print('Q2:', data.quantile(.5)) print('Q3:', data.quantile(.75)) # \u6570\u636e\u683c\u5f0f\uff1a # [ 6 7 15 36 39 40 41 42 43 47 49] # Q1: 25.5 # Q2: 40.0 # Q3: 42.5 # \u624b\u7b97\u8ba1\u7b97\u7ed3\u679c\uff1a # Q1\u7684p\u5206\u4f4d\u6570(0.25)\u4f4d\u7f6eposition = 1+(11-1)*0.25 = 3.5(\u53d6\u7b2c3\u4f4d) (p=0.25) Q1=15+(36-15)*0.5=25.5 (\u7b2c3\u30014\u4f4d\u7684\u5dee\u4e58\u4ee5\u4f59\u65700.5) # Q2\u7684p\u5206\u4f4d\u6570(0.5)\u4f4d\u7f6eposition = 1+(11-1)*0.5 = 6 (p=0.5) Q2=40 # Q3\u7684p\u5206\u4f4d\u6570(0.75)\u4f4d\u7f6eposition = 1+(11-1)*0.75 = 9 (p=0.75) Q3=42+(43-42)*0.5=42.5 # IQR = Q3 - Q1 = 17 \u6848\u4f8b2 df = pd.DataFrame(np.array([[1, 1], [2, 10], [3, 100], [4, 100]]), columns=['a', 'b']) print(\"\u6570\u636e\u539f\u59cb\u683c\u5f0f\uff1a\") print(df) print(\"\u8ba1\u7b97p=0.1\u65f6\uff0ca\u5217\u548cb\u5217\u7684\u5206\u4f4d\u6570\") print(df.quantile(.1)) # \u6570\u636e\u539f\u59cb\u683c\u5f0f\uff1a # a b # 0 1 1 # 1 2 10 # 2 3 100 # 3 4 100 # \u8ba1\u7b97p=0.1\u65f6\uff0ca\u5217\u548cb\u5217\u7684\u5206\u4f4d\u6570 # a 1.3 # b 3.7 # Name: 0.1, dtype: float64 # \u624b\u7b97\u8ba1\u7b97\u7ed3\u679c\uff1a # \u8ba1\u7b97a\u5217 # position=1+(4-1)*0.1=1.3 (\u53d6\u7b2c1\u4f4d) # Q1=1+(2-1)*0.3=1.3 (\u7b2c1\u30012\u4f4d\u7684\u5dee\u4e58\u4ee5\u4f59\u65700.3) # \u8ba1\u7b97b\u5217 # position=1+(4-1)*0.1=1.3 (\u53d6\u7b2c1\u4f4d) # Q1=1+(10-1)*0.3=3.7 (\u7b2c1\u30012\u4f4d\u7684\u5dee\u4e58\u4ee5\u4f59\u65700.3) \u4f18\u5316\u7684 groupby \u65b9\u6cd5\uff1a count: \u5206\u7ec4\u4e2d\u975eNA\u503c\u7684\u6570\u91cf sum: \u975eNA\u503c\u7684\u7d2f\u52a0\u548c mean: \u975eNA\u503c\u7684\u5e73\u5747\u503c median: \u975eNA\u503c\u7684\u7b97\u672f\u4e2d\u4f4d\u6570 std, var: \u65e0\u504f\u7684(n-1\u5206\u6bcd)\u6807\u51c6\u5dee\u548c\u65b9\u5dee min, max: \u975eNA\u503c\u7684\u6700\u5c0f\u503c\u3001\u6700\u5927\u503c prod: \u975eNA\u503c\u7684\u4e58\u79ef first, last: \u975eNA\u503c\u7684\u7b2c\u4e00\u4e2a\u3001\u6700\u540e\u4e00\u4e2a\u503c df = pd.DataFrame( { 'key1': ['a', 'a', 'b', 'b', 'a'], 'key2': ['one', 'two', 'one', 'two', 'one'], 'data1': [1, 3, 5, 7, 9], 'data2': [2, 4, 6, 8, 10] } ) print(df) # key1 key2 data1 data2 # 0 a one 1 2 # 1 a two 3 4 # 2 b one 5 6 # 3 b two 7 8 # 4 a one 9 10 grouped = df.groupby('key1') result = grouped['data1'] for i in result: print(i) # ('a', 0 1 # 1 3 # 4 9 # Name: data1, dtype: int64) # ('b', 2 5 # 3 7 # Name: data1, dtype: int64) result = grouped['data1'].quantile(0.9) # quantile\u5206\u4f4d\u6570 print(result) # key1 # a 7.8 # b 6.8 # Name: data1, dtype: float64 # \u624b\u7b97\u8ba1\u7b97\u7ed3\u679c\uff1a # \u8ba1\u7b97a\u5217 # position=1+(3-1)*0.9=2.8 # Q1=3+(9-3)*0.8=7.8 # \u8ba1\u7b97b\u5217 # position=1+(2-1)*0.9=1.9 # Q1=5+(7-5)*0.9=6.8 \u4f7f\u7528\u81ea\u884c\u5236\u5b9a\u7684\u805a\u5408\uff0c\u5e76\u518d\u8c03\u7528\u5df2\u7ecf\u5728\u5206\u7ec4\u5bf9\u8c61\u4e0a\u5b9a\u4e49\u597d\u7684\u65b9\u6cd5\u3002 def peak_to_peak(arr): return arr.max() - arr.min() result = grouped.agg(peak_to_peak) print(result) # data1 data2 # key1 # a 8 8 # b 2 2 result = grouped.describe() print(result) # data1 ... data2 # count mean std min 25% ... min 25% 50% 75% max # key1 ... # a 3.0 4.333333 4.163332 1.0 2.0 ... 2.0 3.0 4.0 7.0 10.0 # b 2.0 6.000000 1.414214 5.0 5.5 ... 6.0 6.5 7.0 7.5 8.0","title":"\u6570\u636e\u805a\u5408"},{"location":"python/DataAnalysis/ch07/#_8","text":"tips = pd.read_csv('../examples/tips.csv') tips['tip_pct'] = tips['tip'] / (tips['total_bill'] - tips['tip']) print(tips.head(5)) # total_bill tip smoker day time size tip_pct # 0 16.99 1.01 No Sun Dinner 2 0.063204 # 1 10.34 1.66 No Sun Dinner 3 0.191244 # 2 21.01 3.50 No Sun Dinner 3 0.199886 # 3 23.68 3.31 No Sun Dinner 2 0.162494 # 4 24.59 3.61 No Sun Dinner 4 0.172069 \u6839\u636e\u5404\u5217\u540c\u65f6\u4f7f\u7528\u591a\u4e2a\u51fd\u6570\u8fdb\u884c\u805a\u5408 grouped = tips.groupby(['day', 'smoker']) # for i in grouped: # print(i) # (('Fri', 'No'), total_bill tip smoker day time size tip_pct # 91 22.49 3.50 No Fri Dinner 2 0.184308 # ...... # 223 15.98 3.00 No Fri Lunch 3 0.231125) # (('Fri', 'Yes'), total_bill tip smoker day time size tip_pct # 90 28.97 3.00 Yes Fri Dinner 2 0.115518 # ...... # 226 10.09 2.00 Yes Fri Lunch 2 0.247219) # ...... grouped_pct = grouped['tip_pct'] for i in grouped_pct: print(i) # (('Fri', 'No'), 91 0.184308 # 94 0.166667 # ...... # Name: tip_pct, dtype: float64) # (('Fri', 'Yes'), 90 0.115518 # 92 0.210526 # ...... # Name: tip_pct, dtype: float64) # ...... \u5c06\u51fd\u6570\u540d\u4ee5\u5b57\u7b26\u4e32\u5f62\u5f0f\u4f20\u9012\u3002 result = grouped_pct.agg('mean') print(result) # day smoker # Fri No 0.179740 # Yes 0.216293 # Sat No 0.190412 # Yes 0.179833 # Sun No 0.193617 # Yes 0.322021 # Thur No 0.193424 # Yes 0.198508 # Name: tip_pct, dtype: float64 \u5982\u679c\u4f20\u9012\u7684\u662f\u51fd\u6570\u6216\u8005\u51fd\u6570\u540d\u7684\u5217\u8868\uff0c\u4f1a\u5f97\u5230\u4e00\u4e2a\u5217\u540d\u662f\u8fd9\u4e9b\u51fd\u6570\u540d\u7684DataFrame\u3002 \u4e0b\u9762\u4f20\u9012\u4e86\u805a\u5408\u51fd\u6570\u7684\u5217\u8868\u7ed9agg\u65b9\u6cd5\uff0c\u8fd9\u4e9b\u51fd\u6570\u4f1a\u5404\u81ea\u8fd0\u7528\u4e8e\u6570\u636e\u5206\u7ec4\u3002 result = grouped_pct.agg(['mean', 'std', peak_to_peak]) print(result) # mean std peak_to_peak # day smoker # Fri No 0.179740 0.039458 0.094263 # Yes 0.216293 0.077530 0.242219 # Sat No 0.190412 0.058626 0.352192 # Yes 0.179833 0.089496 0.446137 # Sun No 0.193617 0.060302 0.274897 # Yes 0.322021 0.538061 2.382107 # Thur No 0.193424 0.056065 0.284273 # Yes 0.198508 0.057170 0.219047 \u5982\u679c\u4f20\u9012\u7684\u662f (name, function) \u5143\u7ec4\u7684\u5217\u8868\uff0c\u6bcf\u4e2a\u5143\u7ec4\u7684\u7b2c\u4e00\u4e2a\u5143\u7d20\u5c06\u4f5c\u4e3aDataFrame\u7684\u5217\u540d\uff08\u53ef\u4ee5\u8ba4\u4e3a\u4e8c\u5143\u5143\u7ec4\u7684\u5217\u8868\u662f\u4e00\u79cd\u6709\u5e8f\u7684\u5bf9\u5e94\u5173\u7cfb\uff09\uff1a result = grouped_pct.agg([('foo', 'mean'), ('bar', np.std)]) # foo\u662fmean\u503c\u7684\u5217\u540d print(result) # foo bar # day smoker # Fri No 0.179740 0.039458 # Yes 0.216293 0.077530 # Sat No 0.190412 0.058626 # Yes 0.179833 0.089496 # Sun No 0.193617 0.060302 # Yes 0.322021 0.538061 # Thur No 0.193424 0.056065 # Yes 0.198508 0.057170 \u53ef\u4ee5\u6307\u5b9a\u5e94\u7528\u5230\u6240\u6709\u5217\u4e0a\u7684\u51fd\u6570\u5217\u8868\u6216\u6bcf\u4e00\u5217\u4e0a\u8981\u5e94\u7528\u7684\u4e0d\u540c\u51fd\u6570\u3002 \u4e0b\u9762\u4ea7\u751f\u7684DataFrame\u62e5\u6709\u5206\u5c42\u5217\uff0c\u4e0e\u5206\u522b\u805a\u5408\u6bcf\u4e00\u5217\uff0c\u518d\u4ee5\u5217\u540d\u4f5c\u4e3a keys \u53c2\u6570\u4f7f\u7528 concat \u5c06\u7ed3\u679c\u62fc\u63a5\u5728\u4e00\u8d77\u7684\u7ed3\u679c\u76f8\u540c\u3002 functions = ['count', 'mean', 'max'] result = grouped[['tip_pct', 'total_bill']].agg(functions) print(result) # tip_pct total_bill # count mean max count mean max # day smoker # Fri No 4 0.179740 0.231125 4 18.420000 22.75 # Yes 15 0.216293 0.357737 15 16.813333 40.17 # Sat No 45 0.190412 0.412409 45 19.661778 48.33 # Yes 42 0.179833 0.483092 42 21.276667 50.81 # Sun No 57 0.193617 0.338101 57 20.506667 48.17 # Yes 19 0.322021 2.452381 19 24.120000 45.35 # Thur No 45 0.193424 0.362976 45 17.113111 41.19 # Yes 17 0.198508 0.317965 17 19.190588 43.11 # \u628a['tip_pct', 'total_bill']\u6539\u6210[['tip_pct', 'total_bill']]\uff0c\u5c31\u53ef\u4ee5\u907f\u514d\u62a5\u9519 # FutureWarning: Indexing with multiple keys (implicitly converted to a tuple of keys) will be deprecated, use a list instead. # result = grouped['tip_pct', 'total_bill'].agg(functions) print(result['tip_pct']) # count mean max # day smoker # Fri No 4 0.179740 0.231125 # Yes 15 0.216293 0.357737 # Sat No 45 0.190412 0.412409 # Yes 42 0.179833 0.483092 # Sun No 57 0.193617 0.338101 # Yes 19 0.322021 2.452381 # Thur No 45 0.193424 0.362976 # Yes 17 0.198508 0.317965 \u4e5f\u540c\u6837\u53ef\u4ee5\u4f20\u9012\u5177\u6709\u81ea\u5b9a\u4e49\u540d\u79f0\u7684\u5143\u7ec4\u5217\u8868\uff1a ftuples = [('Durchschnitt', 'mean'), ('Abweichung', np.var)] result = grouped[['tip_pct', 'total_bill']].agg(ftuples) print(result) # tip_pct total_bill # Durchschnitt Abweichung Durchschnitt Abweichung # day smoker # Fri No 0.179740 0.001557 18.420000 25.596333 # Yes 0.216293 0.006011 16.813333 82.562438 # Sat No 0.190412 0.003437 19.661778 79.908965 # Yes 0.179833 0.008010 21.276667 101.387535 # Sun No 0.193617 0.003636 20.506667 66.099980 # Yes 0.322021 0.289509 24.120000 109.046044 # Thur No 0.193424 0.003143 17.113111 59.625081 # Yes 0.198508 0.003268 19.190588 69.808518 \u8981\u5c06\u4e0d\u540c\u7684\u51fd\u6570\u5e94\u7528\u5230\u4e00\u4e2a\u6216\u591a\u4e2a\u5217\u4e0a\uff0c\u9700\u8981\u5c06\u542b\u6709\u5217\u540d\u4e0e\u51fd\u6570\u5bf9\u5e94\u5173\u7cfb\u7684\u5b57\u5178\u4f20\u9012\u7ed9 agg \uff1a result = grouped.agg({'tip': np.max, 'size': 'sum'}) print(result) # tip size # day smoker # Fri No 3.50 9 # Yes 4.73 31 # Sat No 9.00 115 # Yes 10.00 104 # Sun No 6.00 167 # Yes 6.50 49 # Thur No 6.70 112 # Yes 5.00 40 result = grouped.agg({'tip_pct': ['min', 'max', 'mean', 'std']}) print(result) # tip_pct # min max mean std # day smoker # Fri No 0.136861 0.231125 0.179740 0.039458 # Yes 0.115518 0.357737 0.216293 0.077530 # Sat No 0.060217 0.412409 0.190412 0.058626 # Yes 0.036955 0.483092 0.179833 0.089496 # Sun No 0.063204 0.338101 0.193617 0.060302 # Yes 0.070274 2.452381 0.322021 0.538061 # Thur No 0.078704 0.362976 0.193424 0.056065 # Yes 0.098918 0.317965 0.198508 0.057170 \u53ea\u6709\u591a\u4e2a\u51fd\u6570\u5e94\u7528\u4e8e\u81f3\u5c11\u4e00\u4e2a\u5217\u65f6\uff0cDataFrame\u624d\u5177\u6709\u5206\u5c42\u5217\u3002","title":"\u9010\u5217\u53ca\u591a\u51fd\u6570\u5e94\u7528"},{"location":"python/DataAnalysis/ch07/#_9","text":"\u5728\u524d\u9762\u6240\u6709\u7684\u4f8b\u5b50\u4e2d\uff0c\u805a\u5408\u6570\u636e\u8fd4\u56de\u65f6\u90fd\u662f\u5e26\u6709\u7d22\u5f15\u7684\uff0c\u6709\u65f6\u7d22\u5f15\u662f\u5206\u5c42\u7684\uff0c\u7531\u552f\u4e00\u7684\u5206\u7ec4\u952e\u8054\u5408\u5f62\u6210\u3002 \u56e0\u4e3a\u4e0d\u662f\u6240\u6709\u7684\u60c5\u51b5\u4e0b\u90fd\u9700\u8981\u7d22\u5f15\uff0c\u6240\u4ee5\u5728\u5927\u591a\u6570\u60c5\u51b5\u4e0b\u53ef\u4ee5\u901a\u8fc7\u5411groupby\u4f20\u9012as_index=False\u6765\u7981\u7528\u5206\u7ec4\u952e\u4f5c\u4e3a\u7d22\u5f15\u7684\u884c\u4e3a\uff1a result = tips.groupby(['day', 'smoker'], as_index=False).mean() print(result) # day smoker total_bill tip size tip_pct # 0 Fri No 18.420000 2.812500 2.250000 0.179740 # 1 Fri Yes 16.813333 2.714000 2.066667 0.216293 # 2 Sat No 19.661778 3.102889 2.555556 0.190412 # 3 Sat Yes 21.276667 2.875476 2.476190 0.179833 # 4 Sun No 20.506667 3.167895 2.929825 0.193617 # 5 Sun Yes 24.120000 3.516842 2.578947 0.322021 # 6 Thur No 17.113111 2.673778 2.488889 0.193424 # 7 Thur Yes 19.190588 3.030000 2.352941 0.198508 \u901a\u8fc7\u5728\u7ed3\u679c\u4e0a\u8c03\u7528reset_index\u4e5f\u53ef\u4ee5\u83b7\u5f97\u540c\u6837\u7684\u7ed3\u679c\u3002\u4f7f\u7528as_index=False\u53ef\u4ee5\u907f\u514d\u4e00\u4e9b\u4e0d\u5fc5\u8981\u7684\u8ba1\u7b97\u3002 result = tips.groupby(['day', 'smoker']).mean() print(result.reset_index()) # day smoker total_bill tip size tip_pct # 0 Fri No 18.420000 2.812500 2.250000 0.179740 # 1 Fri Yes 16.813333 2.714000 2.066667 0.216293 # 2 Sat No 19.661778 3.102889 2.555556 0.190412 # 3 Sat Yes 21.276667 2.875476 2.476190 0.179833 # 4 Sun No 20.506667 3.167895 2.929825 0.193617 # 5 Sun Yes 24.120000 3.516842 2.578947 0.322021 # 6 Thur No 17.113111 2.673778 2.488889 0.193424 # 7 Thur Yes 19.190588 3.030000 2.352941 0.198508 print(result) # total_bill tip size tip_pct # day smoker # Fri No 18.420000 2.812500 2.250000 0.179740 # Yes 16.813333 2.714000 2.066667 0.216293 # Sat No 19.661778 3.102889 2.555556 0.190412 # Yes 21.276667 2.875476 2.476190 0.179833 # Sun No 20.506667 3.167895 2.929825 0.193617 # Yes 24.120000 3.516842 2.578947 0.322021 # Thur No 17.113111 2.673778 2.488889 0.193424 # Yes 19.190588 3.030000 2.352941 0.198508","title":"\u8fd4\u56de\u4e0d\u542b\u884c\u7d22\u5f15\u7684\u805a\u5408\u6570\u636e"},{"location":"python/DataAnalysis/ch07/#-","text":"import pandas as pd import numpy as np import statsmodels.api as sm GroupBy \u65b9\u6cd5\u6700\u5e38\u89c1\u7684\u76ee\u7684\u662f apply \uff08\u5e94\u7528\uff09\u3002 apply \u5c06\u5bf9\u8c61\u62c6\u5206\u6210\u591a\u5757\uff0c\u7136\u540e\u5728\u6bcf\u4e00\u5757\u4e0a\u8c03\u7528\u4f20\u9012\u7684\u51fd\u6570\uff0c\u4e4b\u540e\u5c1d\u8bd5\u5c06\u6bcf\u4e00\u5757\u62fc\u63a5\u5230\u4e00\u8d77\u3002 \u6839\u636e\u4e0b\u9762\u7684\u5c0f\u8d39\u6570\u636e\u96c6\uff0c\u6309\u7ec4\u9009\u51fa\u5c0f\u8d39\u767e\u5206\u6bd4\uff08tip-pct\uff09\u6700\u9ad8\u7684\u4e94\u7ec4\u3002 tips = pd.read_csv('../examples/tips.csv') tips['tip_pct'] = tips['tip'] / (tips['total_bill'] - tips['tip']) \u6837\u672c\u6570\u636e print(tips.head(5)) # total_bill tip smoker day time size tip_pct # 0 16.99 1.01 No Sun Dinner 2 0.063204 # 1 10.34 1.66 No Sun Dinner 3 0.191244 # 2 21.01 3.50 No Sun Dinner 3 0.199886 # 3 23.68 3.31 No Sun Dinner 2 0.162494 # 4 24.59 3.61 No Sun Dinner 4 0.172069 \u9996\u5148\uff0c\u5199\u4e00\u4e2a\u53ef\u4ee5\u5728\u7279\u5b9a\u5217\u4e2d\u9009\u51fa\u6700\u5927\u503c\u6240\u5728\u884c\u7684\u51fd\u6570\uff1a \u6dfb\u52a0\u4e86\u5347\u5e8f\uff0c\u7ed3\u679c\u8f93\u51fa\u6700\u540e5\u884c\uff08\u6700\u540e\u76845\u884c\u4e5f\u662f\u6700\u5927\u76845\u4e2a tip_tcp \u8bb0\u5f55\uff09\u3002 def top(df, n=5, column='tip_pct'): return df.sort_values(by=column, ascending=True)[-n:] result = top(tips, n=6) print(result) # \u7b49\u4ef7\u65b9\u5f0f\uff1a # result = tips.sort_values('tip_pct')[-6:] # print(result) # total_bill tip smoker day time size tip_pct # 109 14.31 4.00 Yes Sat Dinner 2 0.387973 # 183 23.17 6.50 Yes Sun Dinner 4 0.389922 # 232 11.61 3.39 No Sat Dinner 2 0.412409 # 67 3.07 1.00 Yes Sat Dinner 1 0.483092 # 178 9.60 4.00 Yes Sun Dinner 2 0.714286 # 172 7.25 5.15 Yes Sun Dinner 2 2.452381 \u5982\u679c\u6309\u7167 smoker \u8fdb\u884c\u5206\u7ec4\uff0c\u4e4b\u540e\u8c03\u7528 apply \uff0c\u4f1a\u5f97\u5230\u4ee5\u4e0b\u7ed3\u679c\uff1a top \u51fd\u6570\u5728DataFrame\u7684\u6bcf\u4e00\u884c\u5206\u7ec4\u4e0a\u88ab\u8c03\u7528\uff0c\u4e4b\u540e\u4f7f\u7528 pandas.concat \u5c06\u51fd\u6570\u7ed3\u679c\u7c98\u8d34\u5728\u4e00\u8d77\uff0c\u5e76\u4f7f\u7528\u5206\u7ec4\u540d\u4f5c\u4e3a\u5404\u7ec4\u7684\u6807\u7b7e\u3002 \u56e0\u6b64\u7ed3\u679c\u5305\u542b\u4e00\u4e2a\u5206\u5c42\u7d22\u5f15\uff0c\u8be5\u5206\u5c42\u7d22\u5f15\u7684\u5185\u90e8\u5c42\u7ea7\u5305\u542b\u539fDataFrame\u7684\u7d22\u5f15\u503c\u3002 result = tips.groupby('smoker').apply(top) print(result) # total_bill tip smoker day time size tip_pct # smoker # No 88 24.71 5.85 No Thur Lunch 2 0.310180 # 185 20.69 5.00 No Sun Dinner 5 0.318674 # 51 10.29 2.60 No Sun Dinner 2 0.338101 # 149 7.51 2.00 No Thur Lunch 2 0.362976 # 232 11.61 3.39 No Sat Dinner 2 0.412409 # Yes 109 14.31 4.00 Yes Sat Dinner 2 0.387973 # 183 23.17 6.50 Yes Sun Dinner 4 0.389922 # 67 3.07 1.00 Yes Sat Dinner 1 0.483092 # 178 9.60 4.00 Yes Sun Dinner 2 0.714286 # 172 7.25 5.15 Yes Sun Dinner 2 2.452381 \u5982\u679c\u9664\u4e86\u5411 apply \u4f20\u9012\u51fd\u6570\uff0c\u8fd8\u4f20\u9012\u5176\u4ed6\u53c2\u6570\u6216\u5173\u952e\u5b57\u7684\u8bdd\uff0c\u4f60\u53ef\u4ee5\u628a\u8fd9\u4e9b\u653e\u5728\u51fd\u6570\u540e\u8fdb\u884c\u4f20\u9012\u3002 result = tips.groupby('smoker').apply(top, n=1, column='total_bill') print(result) # \u8fd92\u884c\u90fd\u662fsmoker\u662fyes\u548cno\u65f6\u6700\u5927total_bill\u503c\u6240\u5728\u884c\u3002 # total_bill tip smoker day time size tip_pct # smoker # No 212 48.33 9.0 No Sat Dinner 4 0.228833 # Yes 170 50.81 10.0 Yes Sat Dinner 3 0.245038 \u5728 GroupBy \u5bf9\u8c61\u4e0a\u8c03\u7528 describe \u65b9\u6cd5\u3002 result = tips.groupby('smoker')['tip_pct'].describe() print(result) # count mean std ... 50% 75% max # smoker ... # No 151.0 0.192237 0.057665 ... 0.184308 0.227015 0.412409 # Yes 93.0 0.218176 0.254295 ... 0.181818 0.242326 2.452381 # [2 rows x 8 columns] print(result.unstack('smoker')) # \u7c7b\u4f3c\u4e8e\u8f6c\u7f6e # smoker # count No 151.000000 # Yes 93.000000 # mean No 0.192237 # Yes 0.218176 # std No 0.057665 # Yes 0.254295 # min No 0.060217 # Yes 0.036955 # 25% No 0.158622 # Yes 0.119534 # 50% No 0.184308 # Yes 0.181818 # 75% No 0.227015 # Yes 0.242326 # max No 0.412409 # Yes 2.452381 # dtype: float64 \u5728 GroupBy \u5bf9\u8c61\u7684\u5185\u90e8\uff0c\u5f53\u8c03\u7528\u50cf describe \u8fd9\u6837\u7684\u65b9\u6cd5\u65f6\uff0c\u5b9e\u9645\u4e0a\u662f\u4ee5\u4e0b\u4ee3\u7801\u7684\u7b80\u5199\uff1a grouped = tips.groupby(['smoker']) f = lambda x: x.describe() result = grouped.apply(f) print(result) # total_bill tip size tip_pct # smoker # No count 151.000000 151.000000 151.000000 151.000000 # mean 19.188278 2.991854 2.668874 0.192237 # std 8.255582 1.377190 1.017984 0.057665 # min 7.250000 1.000000 1.000000 0.060217 # 25% 13.325000 2.000000 2.000000 0.158622 # 50% 17.590000 2.740000 2.000000 0.184308 # 75% 22.755000 3.505000 3.000000 0.227015 # max 48.330000 9.000000 6.000000 0.412409 # Yes count 93.000000 93.000000 93.000000 93.000000 # mean 20.756344 3.008710 2.408602 0.218176 # std 9.832154 1.401468 0.810751 0.254295 # min 3.070000 1.000000 1.000000 0.036955 # 25% 13.420000 2.000000 2.000000 0.119534 # 50% 17.920000 3.000000 2.000000 0.181818 # 75% 26.860000 3.680000 3.000000 0.242326 # max 50.810000 10.000000 5.000000 2.452381","title":"\u5e94\u7528\uff1a\u901a\u7528\u62c6\u5206-\u5e94\u7528-\u8054\u5408"},{"location":"python/DataAnalysis/ch07/#_10","text":"\u5728\u524d\u9762\u7684\u4f8b\u5b50\u4e2d\u6240\u5f97\u5230\u7684\u5bf9\u8c61\uff0c\u90fd\u5177\u6709\u5206\u7ec4\u952e\u6240\u5f62\u6210\u7684\u5206\u5c42\u7d22\u5f15\u4ee5\u53ca\u6bcf\u4e2a\u539f\u59cb\u5bf9\u8c61\u7684\u7d22\u5f15\u3002 \u4e5f\u53ef\u4ee5\u901a\u8fc7\u5411 groupby \u4f20\u9012 group_keys=False \u6765\u7981\u7528\u8fd9\u4e2a\u529f\u80fd\u3002 result = tips.groupby('smoker', group_keys=True).apply(top) print(result) # total_bill tip smoker day time size tip_pct # smoker # No 88 24.71 5.85 No Thur Lunch 2 0.310180 # 185 20.69 5.00 No Sun Dinner 5 0.318674 # 51 10.29 2.60 No Sun Dinner 2 0.338101 # 149 7.51 2.00 No Thur Lunch 2 0.362976 # 232 11.61 3.39 No Sat Dinner 2 0.412409 # Yes 109 14.31 4.00 Yes Sat Dinner 2 0.387973 # 183 23.17 6.50 Yes Sun Dinner 4 0.389922 # 67 3.07 1.00 Yes Sat Dinner 1 0.483092 # 178 9.60 4.00 Yes Sun Dinner 2 0.714286 # 172 7.25 5.15 Yes Sun Dinner 2 2.452381 result = tips.groupby('smoker', group_keys=False).apply(top) print(result) # total_bill tip smoker day time size tip_pct # 88 24.71 5.85 No Thur Lunch 2 0.310180 # 185 20.69 5.00 No Sun Dinner 5 0.318674 # 51 10.29 2.60 No Sun Dinner 2 0.338101 # 149 7.51 2.00 No Thur Lunch 2 0.362976 # 232 11.61 3.39 No Sat Dinner 2 0.412409 # 109 14.31 4.00 Yes Sat Dinner 2 0.387973 # 183 23.17 6.50 Yes Sun Dinner 4 0.389922 # 67 3.07 1.00 Yes Sat Dinner 1 0.483092 # 178 9.60 4.00 Yes Sun Dinner 2 0.714286 # 172 7.25 5.15 Yes Sun Dinner 2 2.452381","title":"\u538b\u7f29\u5206\u7ec4\u952e"},{"location":"python/DataAnalysis/ch07/#_11","text":"\u7b2c8\u7ae0\u4e2d\uff0cpandas\u6709\u4e00\u4e9b\u5de5\u5177\uff0c\u5c24\u5176\u662f cut \u548c qcut \uff0c\u7528\u4e8e\u5c06\u6570\u636e\u6309\u7167\u4f60\u9009\u62e9\u7684\u7bb1\u4f4d\u6216\u6837\u672c\u5206\u4f4d\u6570\u8fdb\u884c\u5206\u6876\u3002 \u4e0e groupby \u65b9\u6cd5\u4e00\u8d77\u4f7f\u7528\u8fd9\u4e9b\u51fd\u6570\u53ef\u4ee5\u5bf9\u6570\u636e\u96c6\u66f4\u65b9\u4fbf\u5730\u8fdb\u884c\u5206\u6876\u6216\u5206\u4f4d\u5206\u6790\u3002 \u590d\u4e60\uff1a\u673a\u68b0\u5b66\u4e60\u4e2d\u7684\u5206\u7bb1\u5904\u7406\u3002 \u5728\u673a\u68b0\u5b66\u4e60\u4e2d\u7ecf\u5e38\u4f1a\u5bf9\u6570\u636e\u8fdb\u884c\u5206\u7bb1\u5904\u7406\u7684\u64cd\u4f5c\uff0c \u4e5f\u5c31\u662f\u628a\u4e00\u6bb5\u8fde\u7eed\u7684\u503c\u5207\u5206\u6210\u82e5\u5e72\u6bb5\uff0c\u6bcf\u4e00\u6bb5\u7684\u503c\u770b\u6210\u4e00\u4e2a\u5206\u7c7b\u3002\u8fd9\u4e2a\u628a\u8fde\u7eed\u503c\u8f6c\u6362\u6210\u79bb\u6563\u503c\u7684\u8fc7\u7a0b\uff0c\u6211\u4eec\u53eb\u505a\u5206\u7bb1\u5904\u7406\u3002 \u6bd4\u5982\uff0c\u628a\u5e74\u9f84\u630915\u5c81\u5212\u5206\u6210\u4e00\u7ec4\uff0c0-15\u5c81\u53eb\u505a\u5c11\u5e74\uff0c16-30\u5c81\u53eb\u505a\u9752\u5e74\uff0c31-45\u5c81\u53eb\u505a\u58ee\u5e74\u3002\u5728\u8fd9\u4e2a\u8fc7\u7a0b\u4e2d\uff0c\u6211\u4eec\u628a\u8fde\u7eed\u7684\u5e74\u9f84\u5206\u6210\u4e86\u4e09\u4e2a\u7c7b\u522b\uff0c\u201c\u5c11\u5e74\u201d\uff0c\u201c\u9752\u5e74\u201d\u548c\u201c\u58ee\u5e74\u201d\u5c31\u662f\u5404\u4e2a\u7c7b\u522b\u7684\u540d\u79f0\uff0c\u6216\u8005\u53eb\u505a\u6807\u7b7e\u3002 \u5728pandas\u4e2d\uff0c cut \u548c qcut \u51fd\u6570\u90fd\u53ef\u4ee5\u8fdb\u884c\u5206\u7bb1\u5904\u7406\u64cd\u4f5c\u3002 cut() \u6309\u7167\u53d8\u91cf\u7684\u503c\u5bf9\u53d8\u91cf\u8fdb\u884c\u5206\u5272\uff0c\u6bcf\u4e2a\u5206\u7ec4\u91cc\u6570\u636e\u7684\u4e2a\u6570\u5e76\u4e0d\u4e00\u6837\u3002 qcut() \u662f\u6309\u53d8\u91cf\u7684\u6570\u91cf\u6765\u5bf9\u53d8\u91cf\u8fdb\u884c\u5206\u5272\uff0c\u5e76\u4e14\u5c3d\u91cf\u4fdd\u8bc1\u6bcf\u4e2a\u5206\u7ec4\u91cc\u53d8\u91cf\u7684\u4e2a\u6570\u76f8\u540c\u3002 \u8003\u8651\u4e0b\u9762\u4e00\u4e2a\u7b80\u5355\u7684\u968f\u673a\u6570\u636e\u96c6\u548c\u4e00\u4e2a\u4f7f\u7528 cut \u7684\u7b49\u957f\u6876\u5206\u7c7b\uff1a df = pd.DataFrame( { 'data1': np.random.randn(1000), 'data2': np.random.randn(1000) } ) quartiles = pd.cut(df.data1, 4) # \u6309\u7167data1\u503c\u7531\u5c0f\u5230\u5927\u7684\u987a\u5e8f\u5c06\u6570\u636e\u5206\u62104\u4efd\uff0c\u5e76\u4e14\u4f7f\u6bcf\u7ec4\u503c\u7684\u8303\u56f4\u5927\u81f4\u76f8\u7b49\u3002 print(quartiles[:10]) # 0 (-0.0743, 1.729] # 1 (-0.0743, 1.729] # 2 (-0.0743, 1.729] # 3 (-0.0743, 1.729] # 4 (-1.877, -0.0743] # 5 (-0.0743, 1.729] # 6 (-0.0743, 1.729] # 7 (-0.0743, 1.729] # 8 (-1.877, -0.0743] # 9 (-0.0743, 1.729] # Name: data1, dtype: category # Categories ( # 4, # interval[float64, right]): [ # (-3.687, -1.877] < (-1.877, -0.0743] < (-0.0743, 1.729] < (1.729, 3.531] # ] \u4e0a\u9762 cut \u8fd4\u56de\u7684 Categorical \u5bf9\u8c61\u53ef\u4ee5\u76f4\u63a5\u4f20\u9012\u7ed9 groupby \u3002\u5229\u7528\u5b83\u8ba1\u7b97\u51fa data2 \u5217\u7684\u4e00\u4e2a\u7edf\u8ba1\u503c\u96c6\u5408\uff0c\u5982\u4e0b\uff1a def get_stats(group): return { 'min': group.min(), 'max': group.max(), 'count': group.count(), 'mean': group.mean() } grouped = df.data2.groupby(quartiles) for i in grouped: print(i) result = grouped.apply(get_stats).unstack() print(result) # min max count mean # data1 # (-3.145, -1.424] -1.759377 2.484321 77.0 -0.127900 # (-1.424, 0.29] -3.142344 2.830654 524.0 -0.081931 # (0.29, 2.005] -3.557136 3.261635 376.0 0.015715 # (2.005, 3.719] -2.829458 1.766352 23.0 -0.198780 \u4f7f\u7528 qcut \uff0c\u6839\u636e\u6837\u672c\u5206\u4f4d\u6570\u8ba1\u7b97\u51fa\u7b49\u5927\u5c0f\u7684\u6876\uff0c\u5c31\u662f\u7b49\u957f\u6876\u3002\u901a\u8fc7\u4f20\u9012 labels=False \u6765\u83b7\u5f97\u5206\u4f4d\u6570\u6570\u503c\u3002 grouping = pd.qcut(df.data1, 10, labels=False) grouped = df.data2.groupby(grouping) result = grouped.apply(get_stats).unstack() print(result) # min max count mean # data1 # 0 -3.678934 3.022862 100.0 0.029658 # 1 -2.319813 2.646502 100.0 0.094035 # 2 -2.873727 2.470840 100.0 0.023866 # 3 -2.196701 2.042251 100.0 0.021232 # 4 -2.154161 2.020809 100.0 0.110834 # 5 -2.723061 2.415626 100.0 0.057365 # 6 -2.291470 2.536159 100.0 0.020866 # 7 -2.064083 1.799356 100.0 -0.081025 # 8 -3.405679 1.792581 100.0 -0.009705 # 9 -2.469285 2.600849 100.0 -0.061721","title":"\u5206\u4f4d\u6570\u4e0e\u6876\u5206\u6790"},{"location":"python/DataAnalysis/ch07/#_12","text":"\u5728\u6e05\u9664\u7f3a\u5931\u503c\u65f6\uff0c\u6709\u65f6\u4f1a\u4f7f\u7528 dropna \u6765\u53bb\u9664\u7f3a\u5931\u503c\uff0c\u6709\u65f6\u4f7f\u7528\u4fee\u6b63\u503c\u6216\u6765\u81ea\u4e8e\u5176\u4ed6\u6570\u636e\u7684\u503c\u6765\u8f93\u5165\uff08\u586b\u5145\uff09\u5230 null \u503c\uff08 NA \uff09\u3002 fillna \u662f\u4e00\u4e2a\u53ef\u4ee5\u4f7f\u7528\u7684\u6b63\u786e\u5de5\u5177\u3002 \u4f8b\u5982\u4e0b\u9762\u4f8b\u5b50\u4e2d\u4f7f\u7528\u4f7f\u7528\u5e73\u5747\u503c\u6765\u586b\u5145NA\u503c\uff1a data = (100, 110, 120, 130, 140, 150) s = pd.Series(data) print(s) # 0 100 # 1 110 # 2 120 # 3 130 # 4 140 # 5 150 # dtype: float64 \u5c06\u6570\u636e\u4e2d\u7684\u4e00\u4e9b\u503c\u8bbe\u7f6e\u4e3a\u7f3a\u5931\u503c\uff1a s[::2] = np.nan print(s) # 0 NaN # 1 110.0 # 2 NaN # 3 130.0 # 4 NaN # 5 150.0 # dtype: float64 result = s.fillna(s.mean()) # 110, 130, 150\u7684\u5e73\u5747\u503c\u662f130 print(result) # 0 130.0 # 1 110.0 # 2 130.0 # 3 130.0 # 4 130.0 # 5 150.0 # dtype: float64 \u4e0b\u9762\u7684\u4f8b\u5b50\u662f\u6309\u7ec4\u586b\u5145NA\u503c\uff1a \u65b9\u6cd51,\u5bf9\u6570\u636e\u5206\u7ec4\u540e\u4f7f\u7528 apply \u3002 \u65b9\u6cd52,\u5728\u6bcf\u4e2a\u6570\u636e\u5757\u4e0a\u90fd\u8c03\u7528 fillna \u7684\u51fd\u6570\u3002 data = (100, 110, 120, 130, 140, 150, 160, 170) states = ['Ohio', 'New York', 'Vermont', 'Florida', 'Oregon', 'Nevada', 'California', 'Idaho'] group_key = ['East'] * 4 + ['West'] * 4 # 4\u4e2aEast\u548c4\u4e2aWest\u62fc\u63a5\u7684\u5217\u8868list s = pd.Series(data, index=states) print(s) # Ohio 100 # New York 110 # Vermont 120 # Florida 130 # Oregon 140 # Nevada 150 # California 160 # Idaho 170 # dtype: int64 \u5c06\u6570\u636e\u4e2d\u7684\u4e00\u4e9b\u503c\u8bbe\u7f6e\u4e3a\u7f3a\u5931\u503c\uff1a s[['Vermont', 'Nevada', 'Idaho']] = np.nan print(s) # Ohio 100.0 # New York 110.0 # Vermont NaN # Florida 130.0 # Oregon 140.0 # Nevada NaN # California 160.0 # Idaho NaN # dtype: float64 result = s.groupby(group_key).mean() print(result) # East 113.333333 # West 150.000000 # dtype: float64 \u7528\u4e0a\u9762\u5f97\u51fa\u7684\u5206\u7ec4\u5e73\u5747\u503c\u6765\u586b\u5145NA\u3002 fill_mean = lambda g: g.fillna(g.mean()) result = s.groupby(group_key).apply(fill_mean) print(result) # Ohio 100.000000 # New York 110.000000 # Vermont 113.333333 # Florida 130.000000 # Oregon 140.000000 # Nevada 150.000000 # California 160.000000 # Idaho 150.000000 # dtype: float64 \u5982\u679c\u5df2\u7ecf\u5728\u4ee3\u7801\u4e2d\u4e3a\u6bcf\u4e2a\u5206\u7ec4\u9884\u5b9a\u4e49\u4e86\u586b\u5145\u503c\uff0c\u53ef\u4ee5\u5229\u7528\u6bcf\u4e2a\u5206\u7ec4\u90fd\u6709\u7684\u5185\u7f6e\u7684 name \u5c5e\u6027\uff0c\u5b9e\u73b0\u586b\u5145 NA \u3002 fill_value = {'East': 0.5, 'West': -1} fill_func = lambda g: g.fillna(fill_value[g.name]) result = s.groupby(group_key).apply(fill_func) print(result) # Ohio 100.0 # New York 110.0 # Vermont 0.5 # Florida 130.0 # Oregon 140.0 # Nevada -1.0 # California 160.0 # Idaho -1.0 # dtype: float64","title":"\u793a\u4f8b\uff1a\u4f7f\u7528\u6307\u5b9a\u5206\u7ec4\u503c\u586b\u5145\u7f3a\u5931\u503c"},{"location":"python/DataAnalysis/ch07/#_13","text":"\u5047\u8bbe\u60f3\u4ece\u5927\u6570\u636e\u96c6\u4e2d\u62bd\u53d6\u968f\u673a\u6837\u672c\uff08\u6709\u6216\u6ca1\u6709\u66ff\u6362\uff09\u4ee5\u7528\u4e8e\u8499\u7279\u5361\u7f57\u6a21\u62df\u76ee\u7684\u6216\u67d0\u4e9b\u5176\u4ed6\u5e94\u7528\u7a0b\u5e8f\u3002 \u6709\u5f88\u591a\u65b9\u6cd5\u6765\u6267\u884c\u201c\u62bd\u53d6\u201d\uff0c\u8fd9\u91cc\u4f7f\u7528Series\u7684sample\u65b9\u6cd5\u3002 \u4e3a\u4e86\u6f14\u793a\uff0c\u8fd9\u91cc\u4ecb\u7ecd\u4e00\u79cd\u6784\u9020\u4e00\u526f\u82f1\u5f0f\u6251\u514b\u724c\u7684\u65b9\u6cd5\uff1a # \u6885\u82b1clubs\u3001\u65b9\u5757diamonds\u3001\u7ea2\u6843hearts\u3001\u9ed1\u6843spades\u3002 suits = ['H', 'S', 'C', 'D'] card_val = (list(range(1, 11)) + [10] * 3) * 4 # card_val [ # 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 10, 10, 10, # 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 10, 10, 10, # 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 10, 10, 10, # 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 10, 10, 10 # ] base_names = ['A'] + list(range(2, 11)) + ['J', 'K', 'Q'] # base_names\uff1a ['A', 2, 3, 4, 5, 6, 7, 8, 9, 10, 'J', 'K', 'Q'] \u751f\u6210\u4e86\u4e00\u4e2a\u957f\u5ea6\u4e3a 52 \u7684Series, Series\u7684\u7d22\u5f15\u5305\u542b\u4e86\u724c\u540d\uff0cSeries\u7684\u503c\u53ef\u4ee5\u7528\u6e38\u620f\uff08\u4e3a\u4e86\u4fdd\u6301\u7b80\u5355\uff0c\u8ba9\u2019A\u2019\u4e3a1 \uff09\uff1a cards = [] for suit in ['H', 'S', 'C', 'D']: cards.extend(str(num) + suit for num in base_names) deck = pd.Series(card_val, index=cards) print(deck) # AH 1 # 2H 2 # 3H 3 # 4H 4 # 5H 5 # 6H 6 # 7H 7 # 8H 8 # 9H 9 # 10H 10 # JH 10 # KH 10 # QH 10 # AS 1 # 2S 2 # 3S 3 # 4S 4 # 5S 5 # 6S 6 # 7S 7 # 8S 8 # 9S 9 # 10S 10 # JS 10 # KS 10 # QS 10 # AC 1 # 2C 2 # 3C 3 # 4C 4 # 5C 5 # 6C 6 # 7C 7 # 8C 8 # 9C 9 # 10C 10 # JC 10 # KC 10 # QC 10 # AD 1 # 2D 2 # 3D 3 # 4D 4 # 5D 5 # 6D 6 # 7D 7 # 8D 8 # 9D 9 # 10D 10 # JD 10 # KD 10 # QD 10 # dtype: int64 \u4ece\u8fd9\u526f\u724c\u4e2d\u62ff\u51fa\u4e94\u5f20\u724c\u53ef\u4ee5\u5199\u6210\uff1a def draw(_deck, n=5): return _deck.sample(n) print(draw(deck)) # KD 10 # 2S 2 # 5C 5 # 6C 6 # QD 10 # dtype: int64 \u5047\u8bbe\u8981\u4ece\u6bcf\u4e2a\u82b1\u8272\u4e2d\u968f\u673a\u62bd\u53d6\u4e24\u5f20\u724c\u3002\u7531\u4e8e\u82b1\u8272\u662f\u724c\u540d\u7684\u6700\u540e\u4e24\u4e2a\u5b57\u7b26\uff0c\u53ef\u4ee5\u57fa\u4e8e\u8fd9\u70b9\u8fdb\u884c\u5206\u7ec4\uff0c\u5e76\u4f7f\u7528 apply \uff1a get_suit = lambda card: card[-1] # \u6700\u540e\u4e00\u4e2a\u5b57\u6bcd\u662f\u82b1\u8272 result = deck.groupby(get_suit).apply(draw, n=2) print(result) # C 10C 10 # 3C 3 # D KD 10 # AD 1 # H 5H 5 # 7H 7 # S 3S 3 # 5S 5 # dtype: int64 \u6216\u8005\u4e5f\u53ef\u4ee5\u5199\u6210\uff1a result = deck.groupby(get_suit, group_keys=False).apply(draw, n=2) print(result) # JC 10 # 8C 8 # QD 10 # 4D 4 # 10H 10 # 6H 6 # 7S 7 # KS 10 # dtype: int64","title":"\u793a\u4f8b\uff1a\u968f\u673a\u91c7\u6837\u4e0e\u6392\u5217"},{"location":"python/DataAnalysis/ch07/#_14","text":"\u5728 groupby \u7684\u62c6\u5206-\u5e94\u7528-\u8054\u5408\u7684\u8303\u5f0f\u4e0b\uff0cDataFrame\u7684\u5217\u95f4\u64cd\u4f5c\u6216\u4e24\u4e2aSeriese\u4e4b\u95f4\u7684\u64cd\u4f5c\uff0c\u4f8b\u5982\u5b9e\u73b0\u5206\u7ec4\u52a0\u6743\u5e73\u5747\u3002 \u4e0b\u9762\u4f8b\u5b50\uff0c\u4f7f\u7528\u4e00\u4e2a\u5305\u542b\u5206\u7ec4\u952e\u548c\u6743\u91cd\u503c\u7684\u6570\u636e\u96c6\uff1a dt = np.random.randn(8) wt = np.random.randn(8) df = pd.DataFrame( { 'category': ['a', 'a', 'a', 'a', 'b', 'b', 'b', 'b'], 'data': dt, 'weight': wt } ) print(df) # category data weight # 0 a -0.250764 -0.085285 # 1 a 0.167155 -1.361254 # 2 a 0.399306 1.755542 # 3 a -0.514477 0.270124 # 4 b -0.005558 0.886514 # 5 b 0.607596 -1.384315 # 6 b -1.029627 -0.845340 # 7 b -0.294204 1.253965 \u901a\u8fc7 category \u8fdb\u884c\u5206\u7ec4\u52a0\u6743\u5e73\u5747\u5982\u4e0b\uff1a grouped = df.groupby('category') get_wavg = lambda g: np.average(g['data'], weights=g['weight']) result = grouped.apply(get_wavg) print(result) # category # a 0.614499 # b 3.863947 # dtype: float64 \u53e6\u4e00\u4e2a\u4f8b\u5b50\uff0c\u4e00\u4e2a\u4ece\u96c5\u864e\u8d22\u7ecf\u4e0a\u83b7\u5f97\u7684\u6570\u636e\u96c6\uff0c\u8be5\u6570\u636e\u96c6\u5305\u542b\u4e00\u4e9b\u6807\u666e500 \uff08SPX\u7b26\u53f7\uff09\u548c\u80a1\u7968\u7684\u6536\u76d8\u4ef7\uff1a close_px = pd.read_csv('../examples/stock_px_2.csv', parse_dates=True, index_col=0) print(close_px.info()) # # DatetimeIndex: 2214 entries, 2003-01-02 to 2011-10-14 # Data columns (total 4 columns): # # Column Non-Null Count Dtype # --- ------ -------------- ----- # 0 AAPL 2214 non-null float64 # 1 MSFT 2214 non-null float64 # 2 XOM 2214 non-null float64 # 3 SPX 2214 non-null float64 # dtypes: float64(4) # memory usage: 86.5 KB # None print(close_px[-4:]) # AAPL MSFT XOM SPX # 2011-10-11 400.29 27.00 76.27 1195.54 # 2011-10-12 402.19 26.96 77.16 1207.25 # 2011-10-13 408.43 27.18 76.37 1203.66 # 2011-10-14 422.00 27.27 78.11 1224.58 \u76ee\u6807\u4efb\u52a1\uff1a\u8ba1\u7b97\u4e00\u4e2aDataFrame\uff0c\u5b83\u5305\u542b\u6807\u666e\u6307\u6570\uff08SPX\uff09\u6bcf\u65e5\u6536\u76ca\u7684\u5e74\u5ea6\u76f8\u5173\u6027\uff08\u901a\u8fc7\u767e\u5206\u6bd4\u53d8\u5316\u8ba1\u7b97\uff09\u3002 \u9996\u5148\u521b\u5efa\u4e00\u4e2a\u8ba1\u7b97\u6bcf\u5217\u4e0e\u2019SPX\u2019\u5217\u6210\u5bf9\u5173\u8054\u7684\u51fd\u6570\uff1a spx_corr = lambda x: x.corrwith(x['SPX']) \u4e4b\u540e\uff0c\u4f7f\u7528 pct_change \u8ba1\u7b97 close-px \u767e\u5206\u6bd4\u7684\u53d8\u5316\uff1a rets = close_px.pct_change().dropna() # Percentage change between the current and a prior element. print(rets) # AAPL MSFT XOM SPX # 2003-01-03 0.006757 0.001421 0.000684 -0.000484 # 2003-01-06 0.000000 0.017975 0.024624 0.022474 # ... ... ... ... ... # 2011-10-14 0.033225 0.003311 0.022784 0.017380 # [2213 rows x 4 columns] \u6700\u540e\uff0c\u6309\u5e74\u5bf9\u767e\u5206\u6bd4\u53d8\u5316\u8fdb\u884c\u5206\u7ec4\uff0c\u53ef\u4ee5\u4f7f\u7528\u5355\u884c\u51fd\u6570\u4ece\u6bcf\u4e2a\u884c\u6807\u7b7e\u4e2d\u63d0\u53d6\u6bcf\u4e2a datetime \u6807\u7b7e\u7684 year \u5c5e\u6027\uff1a get_year = lambda x: x.year by_year = rets.groupby(get_year) result = by_year.apply(spx_corr) print(result) # AAPL MSFT XOM SPX # 2003 0.541124 0.745174 0.661265 1.0 # 2004 0.374283 0.588531 0.557742 1.0 # 2005 0.467540 0.562374 0.631010 1.0 # 2006 0.428267 0.406126 0.518514 1.0 # 2007 0.508118 0.658770 0.786264 1.0 # 2008 0.681434 0.804626 0.828303 1.0 # 2009 0.707103 0.654902 0.797921 1.0 # 2010 0.710105 0.730118 0.839057 1.0 # 2011 0.691931 0.800996 0.859975 1.0 \u53ef\u4ee5\u8ba1\u7b97\u5185\u90e8\u5217\u76f8\u5173\u6027\u3002\u8fd9\u91cc\u8ba1\u7b97\u4e86\u82f9\u679c\u548c\u5fae\u8f6f\u7684\u5e74\u5ea6\u76f8\u5173\u6027\uff1a result = by_year.apply(lambda g: g['AAPL'].corr(g['MSFT'])) print(result) # 2003 0.480868 # 2004 0.259024 # 2005 0.300093 # 2006 0.161735 # 2007 0.417738 # 2008 0.611901 # 2009 0.432738 # 2010 0.571946 # 2011 0.581987 # dtype: float64","title":"\u793a\u4f8b\uff1a\u5206\u7ec4\u52a0\u6743\u5e73\u5747\u548c\u76f8\u5173\u6027"},{"location":"python/DataAnalysis/ch07/#_15","text":"\u5b9a\u4e49\u4ee5\u4e0b regress \uff08\u56de\u5f52\uff09\u51fd\u6570\uff08\u4f7f\u7528 statsmodels \u8ba1\u91cf\u7ecf\u6d4e\u5b66\u5e93\uff09\uff0c\u8be5\u51fd\u6570\u5bf9\u6bcf\u4e2a\u6570\u636e\u5757\u6267\u884c\u666e\u901a\u6700\u5c0f\u4e8c\u4e58\uff08OLS\uff09\u56de\u5f52\uff1a def regress(data, yvar, xvars): Y = data[yvar] X = data[xvars] X['intercept'] = 1. result = sm.OLS(Y, X).fit() return result.params \u73b0\u5728\u8981\u8ba1\u7b97AAPL\u5728SPX\u56de\u62a5\u4e0a\u7684\u5e74\u5ea6\u7ebf\u6027\u56de\u5f52\uff1a result = by_year.apply(regress, 'AAPL', ['SPX']) print(result) # SPX intercept # 2003 1.195406 0.000710 # 2004 1.363463 0.004201 # 2005 1.766415 0.003246 # 2006 1.645496 0.000080 # 2007 1.198761 0.003438 # 2008 0.968016 -0.001110 # 2009 0.879103 0.002954 # 2010 1.052608 0.001261 # 2011 0.806605 0.001514","title":"\u793a\u4f8b\uff1a\u9010\u7ec4\u7ebf\u6027\u56de\u5f52"},{"location":"python/DataAnalysis/ch07/#_16","text":"","title":"\u6570\u636e\u900f\u89c6\u8868\u4e0e\u4ea4\u53c9\u8868"},{"location":"python/DataAnalysis/ch07/#_17","text":"\u6570\u636e\u900f\u89c6\u8868\u662f\u7535\u5b50\u8868\u683c\u7a0b\u5e8f\u548c\u5176\u4ed6\u6570\u636e\u5206\u6790\u8f6f\u4ef6\u4e2d\u5e38\u89c1\u7684\u6570\u636e\u6c47\u603b\u5de5\u5177\u3002 \u5b83\u6839\u636e\u4e00\u4e2a\u6216\u591a\u4e2a\u952e\u805a\u5408\u4e00\u5f20\u8868\u7684\u6570\u636e\uff0c\u5c06\u6570\u636e\u5728\u77e9\u5f62\u683c\u5f0f\u4e2d\u6392\u5217\uff0c\u5176\u4e2d\u4e00\u4e9b\u5206\u7ec4\u952e\u662f\u6cbf\u7740\u884c\u7684\uff0c\u53e6\u4e00\u4e9b\u662f\u6cbf\u7740\u5217\u7684\u3002 Python\u4e2d\u7684pandas\u900f\u89c6\u8868\u662f\u901a\u8fc7\u8fd9\u91cc\u6240\u4ecb\u7ecd\u7684groupby\u5de5\u5177\u4ee5\u53ca\u4f7f\u7528\u5206\u5c42\u7d22\u5f15\u7684\u91cd\u5851\u64cd\u4f5c\u5b9e\u73b0\u7684\u3002 DataFrame\u62e5\u6709\u4e00\u4e2a pivot_table \u65b9\u6cd5\uff0c\u5e76\u4e14\u8fd8\u6709\u8fd8\u4e00\u4e2a\u9876\u5c42\u7684 pandas.pivot_table \u51fd\u6570\u3002 \u9664\u4e86\u4e3a groupby \u63d0\u4f9b\u4e00\u4e2a\u65b9\u4fbf\u63a5\u53e3\uff0c pivot_table \u8fd8\u53ef\u4ee5\u6dfb\u52a0\u90e8\u5206\u603b\u8ba1\uff0c\u4e5f\u79f0\u4f5c\u8fb9\u8ddd\u3002 import pandas as pd import numpy as np \u6839\u636e\u4e0b\u9762\u7684\u5c0f\u8d39\u6570\u636e\u96c6\uff0c\u8ba1\u7b97\u4e00\u5f20\u5728\u884c\u65b9\u5411\u4e0a\u6309 day \u548c smoker \u6392\u5217\u7684\u5206\u7ec4\u5e73\u5747\u503c\uff08\u9ed8\u8ba4\u7684 pivot_table \u805a\u5408\u7c7b\u578b\uff09\u7684\u8868\u3002 pivot_table \u9009\u9879\uff1a values: \u9700\u8981\u805a\u5408\u7684\u5217\u540d\uff0c\u9ed8\u8ba4\u60c5\u51b5\u4e0b\u805a\u5408\u6240\u6709\u6570\u503c\u578b\u7684\u5217\u3002 index: \u5728\u7ed3\u679c\u900f\u89c6\u8868\u7684\u884c\u4e0a\u8fdb\u884c\u5206\u7ec4\u7684\u5217\u540d\u6216\u8005\u5176\u4ed6\u5206\u7ec4\u952e\u3002 tips = pd.read_csv('../examples/tips.csv') tips['tip_pct'] = tips['tip'] / (tips['total_bill'] - tips['tip']) \u6837\u672c\u6570\u636e\u3002 print(tips.head(5)) # total_bill tip smoker day time size tip_pct # 0 16.99 1.01 No Sun Dinner 2 0.063204 # 1 10.34 1.66 No Sun Dinner 3 0.191244 # 2 21.01 3.50 No Sun Dinner 3 0.199886 # 3 23.68 3.31 No Sun Dinner 2 0.162494 # 4 24.59 3.61 No Sun Dinner 4 0.172069 \u8ba1\u7b97\u5728\u884c\u65b9\u5411\u4e0a\u6309 day \u548c smoker \u6392\u5217\u7684\u5206\u7ec4\u5e73\u5747\u503c\u3002\u4e5f\u53ef\u4ee5\u76f4\u63a5\u4f7f\u7528 groupby \u5b9e\u73b0\u3002 result = tips.pivot_table(index=['day', 'smoker']) print(result) # size tip tip_pct total_bill # day smoker # Fri No 2.250000 2.812500 0.179740 18.420000 # Yes 2.066667 2.714000 0.216293 16.813333 # Sat No 2.555556 3.102889 0.190412 19.661778 # Yes 2.476190 2.875476 0.179833 21.276667 # Sun No 2.929825 3.167895 0.193617 20.506667 # Yes 2.578947 3.516842 0.322021 24.120000 # Thur No 2.488889 2.673778 0.193424 17.113111 # Yes 2.352941 3.030000 0.198508 19.190588 \u5728 tip_pct \u548c size \u4e0a\u8fdb\u884c\u805a\u5408\uff0c\u5e76\u6839\u636e time \u5206\u7ec4\u3002\u5c06\u628a smoker \u653e\u5165\u8868\u7684\u5217\uff0c\u800c\u5c06 day \u653e\u5165\u8868\u7684\u884c\uff1a result = tips.pivot_table( ['tip_pct', 'size'], index=['time', 'day'], columns='smoker' ) print(result) # size tip_pct # smoker No Yes No Yes # time day # Dinner Fri 2.000000 2.222222 0.162612 0.202545 # Sat 2.555556 2.476190 0.190412 0.179833 # Sun 2.929825 2.578947 0.193617 0.322021 # Thur 2.000000 NaN 0.190114 NaN # Lunch Fri 3.000000 1.833333 0.231125 0.236915 # Thur 2.500000 2.352941 0.193499 0.198508 \u901a\u8fc7\u4f20\u9012 margins=True \u6765\u6269\u5145\u8fd9\u4e2a\u8868\u6765\u5305\u542b\u90e8\u5206\u603b\u8ba1\u3002\u8fd9\u4f1a\u6dfb\u52a0 All \u884c\u548c\u5217\u6807\u7b7e\uff0c\u5176\u4e2d\u76f8\u5e94\u7684\u503c\u662f\u5355\u5c42\u4e2d\u6240\u6709\u6570\u636e\u7684\u5206\u7ec4\u7edf\u8ba1\u503c\u3002 \u8fd9\u91cc All \u7684\u503c\u662f\u5747\u503c\uff0c\u4e14\u8be5\u5747\u503c\u662f\u4e0d\u8003\u8651\u5438\u70df\u8005\u4e0e\u975e\u5438\u70df\u8005\uff08 All \u5217\uff09\u6216\u884c\u5206\u7ec4\u4e2d\u4efb\u4f55\u4e24\u7ea7\u7684\uff08 All \u884c\uff09\u3002 result = tips.pivot_table( ['tip_pct', 'size'], index=['time', 'day'], columns='smoker', margins=True ) print(result) # size tip_pct # smoker No Yes All No Yes All # time day # Dinner Fri 2.000000 2.222222 2.166667 0.162612 0.202545 0.192562 # Sat 2.555556 2.476190 2.517241 0.190412 0.179833 0.185305 # Sun 2.929825 2.578947 2.842105 0.193617 0.322021 0.225718 # Thur 2.000000 NaN 2.000000 0.190114 NaN 0.190114 # Lunch Fri 3.000000 1.833333 2.000000 0.231125 0.236915 0.236088 # Thur 2.500000 2.352941 2.459016 0.193499 0.198508 0.194895 # All 2.668874 2.408602 2.569672 0.192237 0.218176 0.202123 \u8981\u4f7f\u7528\u4e0d\u540c\u7684\u805a\u5408\u51fd\u6570\u65f6\uff0c\u5c06\u51fd\u6570\u4f20\u9012\u7ed9 aggfunc \u3002\u4f8b\u5982\uff0c count \u6216\u8005 len \u5c06\u7ed9\u51fa\u4e00\u5f20\u5206\u7ec4\u5927\u5c0f\u7684\u4ea4\u53c9\u8868\uff08\u8ba1\u6570\u6216\u51fa\u73b0\u9891\u7387\uff09\uff1a result = tips.pivot_table( ['tip_pct', 'size'], index=['time', 'day'], columns='smoker', aggfunc=len, margins=True ) print(result) # size tip_pct # smoker No Yes All No Yes All # time day # Dinner Fri 3.0 9.0 12 3.0 9.0 12 # Sat 45.0 42.0 87 45.0 42.0 87 # Sun 57.0 19.0 76 57.0 19.0 76 # Thur 1.0 NaN 1 1.0 NaN 1 # Lunch Fri 1.0 6.0 7 1.0 6.0 7 # Thur 44.0 17.0 61 44.0 17.0 61 # All 151.0 93.0 244 151.0 93.0 244 \u5bf9\u4e8e\u7a7a\u503c NA \uff0c\u4f20\u9012\u4e00\u4e2a fill_value \u3002 result = tips.pivot_table( ['tip_pct', 'size'], index=['time', 'day'], columns='smoker', aggfunc='mean', fill_value=0, margins=True ) print(result) # size tip_pct # smoker No Yes All No Yes All # time day # Dinner Fri 2.000000 2.222222 2.166667 0.162612 0.202545 0.192562 # Sat 2.555556 2.476190 2.517241 0.190412 0.179833 0.185305 # Sun 2.929825 2.578947 2.842105 0.193617 0.322021 0.225718 # Thur 2.000000 0.000000 2.000000 0.190114 0.000000 0.190114 # Lunch Fri 3.000000 1.833333 2.000000 0.231125 0.236915 0.236088 # Thur 2.500000 2.352941 2.459016 0.193499 0.198508 0.194895 # All 2.668874 2.408602 2.569672 0.192237 0.218176 0.202123","title":"\u6570\u636e\u900f\u89c6\u8868"},{"location":"python/DataAnalysis/ch07/#crosstab","text":"\u4ea4\u53c9\u8868\uff08\u7b80\u5199\u4e3acrosstab\uff09\u662f\u6570\u636e\u900f\u89c6\u8868\u7684\u4e00\u4e2a\u7279\u6b8a\u60c5\u51b5\uff0c\u8ba1\u7b97\u7684\u662f\u5206\u7ec4\u4e2d\u7684\u9891\u7387\u3002 crosstab \u7684\u524d\u4e24\u4e2a\u53c2\u6570\u53ef\u662f\u6570\u7ec4\u3001Series\u6216\u6570\u7ec4\u7684\u5217\u8868\u3002 sample = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10] nationality = ['USA', 'Japan', 'USA', 'Japan', 'Japan', 'Japan', 'USA', 'USA', 'Japan', 'USA'] handedness = ['Right-handed', 'Left-handed', 'Right-handed', 'Right-handed', 'Left-handed', 'Right-handed', 'Right-handed', 'Left-handed', 'Right-handed', 'Right-handed'] df = pd.DataFrame( { 'sample': sample, 'nationality': nationality, 'handedness': handedness } ) print(df) # sample nationality handedness # 0 1 USA Right-handed # 1 2 Japan Left-handed # 2 3 USA Right-handed # 3 4 Japan Right-handed # 4 5 Japan Left-handed # 5 6 Japan Right-handed # 6 7 USA Right-handed # 7 8 USA Left-handed # 8 9 Japan Right-handed # 9 10 USA Right-handed \u6309\u7167\u56fd\u7c4d\u548c\u60ef\u7528\u6027\u6765\u603b\u7ed3\u8fd9\u4e9b\u6570\u636e\uff0c\u53ef\u4ee5\u4f7f\u7528 pivot_table \u6765\u5b9e\u73b0\u8fd9\u4e2a\u529f\u80fd\uff0c\u4f46\u662f pandas.crosstable \u51fd\u6570\u66f4\u4e3a\u65b9\u4fbf\uff1a result = pd.crosstab(df.nationality, df.handedness, margins=True) print(result) # handedness Left-handed Right-handed All # nationality # Japan 2 3 5 # USA 1 4 5 # All 3 7 10 \u5728\u5c0f\u8d39\u6570\u636e\u4e2d\u53ef\u4ee5\u8fd9\u4e48\u505a\uff1a result = pd.crosstab(['tips.time', tips.day], tips.smoker, margins=True) print(result) # smoker No Yes All # row_0 day # tips.time Fri 4 15 19 # Sat 45 42 87 # Sun 57 19 76 # Thur 45 17 62 # All 151 93 244","title":"\u4ea4\u53c9\u8868\uff1acrosstab"},{"location":"python/DataAnalysis/ch08/","text":"\u65f6\u95f4\u5e8f\u5217 \u00b6 \u65e5\u671f\u548c\u65f6\u95f4\u6570\u636e\u7684\u7c7b\u578b\u53ca\u5de5\u5177 \u00b6 \u65f6\u95f4\u5e8f\u5217\u6570\u636e\u5728\u5f88\u591a\u9886\u57df\u90fd\u662f\u91cd\u8981\u7684\u7ed3\u6784\u5316\u6570\u636e\u5f62\u5f0f\u3002\u5728\u591a\u4e2a\u65f6\u95f4\u70b9\u89c2\u6d4b\u6216\u6d4b\u91cf\u7684\u6570\u636e\u5f62\u6210\u4e86\u65f6\u95f4\u5e8f\u5217\u3002 \u8bb8\u591a\u65f6\u95f4\u5e8f\u5217\u662f\u56fa\u5b9a\u9891\u7387\u7684\uff0c\u4e5f\u5c31\u662f\u8bf4\u6570\u636e\u662f\u6839\u636e\u76f8\u540c\u7684\u89c4\u5219\u5b9a\u671f\u51fa\u73b0\u7684\uff0c\u4f8b\u5982\u6bcf15\u79d2\u3001\u6bcf5\u5206\u949f\u6216\u6bcf\u67081\u6b21\u3002 \u65f6\u95f4\u5e8f\u5217\u4e5f\u53ef\u4ee5\u662f\u4e0d\u89c4\u5219\u7684\uff0c\u6ca1\u6709\u56fa\u5b9a\u7684\u65f6\u95f4\u5355\u4f4d\u6216\u5355\u4f4d\u95f4\u7684\u504f\u79fb\u91cf\u3002 \u5982\u4f55\u6807\u8bb0\u548c\u5f15\u7528\u65f6\u95f4\u5e8f\u5217\u6570\u636e\u53d6\u51b3\u4e8e\u5e94\u7528\u7a0b\u5e8f\uff0c\u65f6\u95f4\u5e8f\u5217\u5305\u62ec\uff1a \u65f6\u95f4\u6233\uff0c\u5177\u4f53\u7684\u65f6\u523b\u3002 \u56fa\u5b9a\u7684\u65f6\u95f4\u533a\u95f4\uff0c\u4f8b\u59822007\u76841\u6708\u6216\u6574\u4e2a2010\u5e74\u3002 \u65f6\u95f4\u95f4\u9694\uff0c\u7531\u5f00\u59cb\u548c\u7ed3\u675f\u65f6\u95f4\u6233\u8868\u793a\u3002\u65f6\u95f4\u533a\u95f4\u53ef\u4ee5\u88ab\u8ba4\u4e3a\u662f\u95f4\u9694\u7684\u7279\u6b8a\u60c5\u51b5\u3002 \u5b9e\u9a8c\u65f6\u95f4\u6216\u6d88\u8017\u65f6\u95f4\u3002\u6bcf\u4e2a\u65f6\u95f4\u6233\u662f\u76f8\u5bf9\u4e8e\u7279\u5b9a\u5f00\u59cb\u65f6\u95f4\u7684\u65f6\u95f4\u7684\u91cf\u5ea6\uff08\u4f8b\u5982\uff0c\u81ea\u4ece\u88ab\u653e\u7f6e\u5728\u70e4\u7bb1\u4e2d\u6bcf\u79d2\u70d8\u70e4\u7684\u997c\u5e72\u7684\u76f4\u5f84\uff09\u3002 \u76ee\u524d\u4e3b\u8981\u5173\u6ce8\u524d\u4e09\u7c7b\u4e2d\u7684\u65f6\u95f4\u5e8f\u5217\u3002 from datetime import datetime, timedelta import datetime as dt from dateutil.parser import parse import pandas as pd datetime \u00b6 datetime\u683c\u5f0f\u7b26\uff1a %a \u661f\u671f\u7684\u82f1\u6587\u5355\u8bcd\u7684\u7f29\u5199\uff1a\u5982\u661f\u671f\u4e00\uff0c \u5219\u8fd4\u56de Mon %A \u661f\u671f\u7684\u82f1\u6587\u5355\u8bcd\u7684\u5168\u62fc\uff1a\u5982\u661f\u671f\u4e00\uff0c\u8fd4\u56de Monday %b \u6708\u4efd\u7684\u82f1\u6587\u5355\u8bcd\u7684\u7f29\u5199\uff1a\u5982\u4e00\u6708\uff0c \u5219\u8fd4\u56de Jan %B \u6708\u4efd\u7684\u5f15\u6587\u5355\u8bcd\u7684\u7f29\u5199\uff1a\u5982\u4e00\u6708\uff0c \u5219\u8fd4\u56de January %c \u8fd4\u56dedatetime\u7684\u5b57\u7b26\u4e32\u8868\u793a\uff0c\u598203/08/15 23:01:26 %d \u8fd4\u56de\u7684\u662f\u5f53\u524d\u65f6\u95f4\u662f\u5f53\u524d\u6708\u7684\u7b2c\u51e0\u5929 %f \u5fae\u79d2\u7684\u8868\u793a\uff1a \u8303\u56f4: [0,999999] %H \u4ee524\u5c0f\u65f6\u5236\u8868\u793a\u5f53\u524d\u5c0f\u65f6 %I \u4ee512\u5c0f\u65f6\u5236\u8868\u793a\u5f53\u524d\u5c0f\u65f6 %m \u8fd4\u56de\u6708\u4efd \u8303\u56f4[0,12] %M \u8fd4\u56de\u5206\u949f\u6570 \u8303\u56f4 [0,59] %P \u8fd4\u56de\u662f\u4e0a\u5348\u8fd8\u662f\u4e0b\u5348\u2013AM or PM %S \u8fd4\u56de\u79d2\u6570 \u8303\u56f4 [0,61]\u3002\u3002\u3002\u624b\u518c\u8bf4\u660e\u7684 %U \u8fd4\u56de\u5f53\u5468\u662f\u5f53\u5e74\u7684\u7b2c\u51e0\u5468 \u4ee5\u5468\u65e5\u4e3a\u7b2c\u4e00\u5929 %W \u8fd4\u56de\u5f53\u5468\u662f\u5f53\u5e74\u7684\u7b2c\u51e0\u5468 \u4ee5\u5468\u4e00\u4e3a\u7b2c\u4e00\u5929 %w \u5f53\u5929\u5728\u5f53\u5468\u7684\u5929\u6570\uff0c\u8303\u56f4\u4e3a[0, 6]\uff0c6\u8868\u793a\u661f\u671f\u5929 %x \u65e5\u671f\u7684\u5b57\u7b26\u4e32\u8868\u793a \uff1a03/08/15 %X \u65f6\u95f4\u7684\u5b57\u7b26\u4e32\u8868\u793a \uff1a23:22:08 %y \u4e24\u4e2a\u6570\u5b57\u8868\u793a\u7684\u5e74\u4efd 15 %Y \u56db\u4e2a\u6570\u5b57\u8868\u793a\u7684\u5e74\u4efd 2015 %z \u4e0eutc\u65f6\u95f4\u7684\u95f4\u9694 \uff08\u5982\u679c\u662f\u672c\u5730\u65f6\u95f4\uff0c\u8fd4\u56de\u7a7a\u5b57\u7b26\u4e32\uff09 %Z \u65f6\u533a\u540d\u79f0\uff08\u5982\u679c\u662f\u672c\u5730\u65f6\u95f4\uff0c\u8fd4\u56de\u7a7a\u5b57\u7b26\u4e32\uff09 datestrs = ['2020/5/6', '2021/10/1'] # \u6ce8\u610f\u533a\u5206datetime\u6a21\u5757\u548cdatetime\u7c7b\uff0c\u540d\u5b57\u76f8\u540c\uff0c\u5bb9\u6613\u5f15\u8d77\u9519\u8bef\u3002 # \u6bd4\u5982datetime.datetime\u5c31\u62a5\u9519type object 'datetime.datetime' has no attribute 'datetime' print(datetime) # print(dt) # Python\u6807\u51c6\u5e93\u5305\u542b\u4e86\u65e5\u671f\u548c\u65f6\u95f4\u6570\u636e\u7684\u7c7b\u578b\u3002 datetime \u3001 time \u548c calendar \u6a21\u5757\u662f\u5f00\u59cb\u5904\u7406\u65f6\u95f4\u6570\u636e\u7684\u4e3b\u8981\u5185\u5bb9\u3002 datetime.datetime \u7c7b\u578b\uff0c\u6216\u7b80\u5199\u4e3a datetime \uff0c\u662f\u5e7f\u6cdb\u4f7f\u7528\u7684\u3002 now = datetime.now() print(now) # 2021-10-07 20:24:43.834293 result = dt.datetime(2021, 10, 7, 20, 26, 00, 72973) print(result) # 2021-10-07 20:26:00.072973 datetime \u65e2\u5b58\u50a8\u4e86\u65e5\u671f\uff0c\u4e5f\u5b58\u50a8\u4e86\u7ec6\u5316\u5230\u5fae\u79d2\u7684\u65f6\u95f4\u3002 timedelta \u8868\u793a\u4e24\u4e2a datetime \u5bf9\u8c61\u7684\u65f6\u95f4\u5dee\u3002 delta = datetime(2021, 10, 7) - datetime(2021, 9, 7) print(delta) # 30 days, 0:00:00 print(delta.days) # 30 print(delta.seconds) # 0 result = dt.timedelta(926, 56700) print(result) # 926 days, 15:45:00 \u53ef\u4ee5\u4e3a\u4e00\u4e2a datetime \u5bf9\u8c61\u52a0\u4e0a\uff08\u6216\u51cf\u53bb\uff09\u4e00\u4e2a timedelta \u6216\u5176\u6574\u6570\u500d\u6765\u4ea7\u751f\u4e00\u4e2a\u65b0\u7684 datetime \u5bf9\u8c61\u3002 start = datetime(2021, 10, 7) result = start + timedelta(12) print(result) # 2021-10-19 00:00:00 result = start - 2 * timedelta(5) print(result) # 2021-09-27 00:00:00 \u5b57\u7b26\u4e32\u4e0edatetime\u4e92\u76f8\u8f6c\u6362 \u00b6 \u4f7f\u7528 str \u65b9\u6cd5\u6216\u4f20\u9012\u4e00\u4e2a\u6307\u5b9a\u7684\u683c\u5f0f\u7ed9 strftime \u65b9\u6cd5\u6765\u5bf9 datetime \u5bf9\u8c61\u548cpandas\u7684 Timestamp \u5bf9\u8c61\u8fdb\u884c\u683c\u5f0f\u5316\u3002 stamp = datetime(2021, 10, 7) result = str(stamp) print(result) # 2021-10-07 00:00:00 \u4f7f\u7528 datetime.srtptime \u548c datetime \u683c\u5f0f\u7b26\uff0c\u628a\u5b57\u7b26\u4e32\u8f6c\u6362\u65e5\u671f\u3002 datetime.strptime \u662f\u5728\u5df2\u77e5\u683c\u5f0f\u7684\u60c5\u51b5\u4e0b\u8f6c\u6362\u65e5\u671f\u7684\u597d\u65b9\u5f0f\u3002 value = '2021-10-7' result = datetime.strptime(value, '%Y-%m-%d') print(result) # 2021-10-07 00:00:00 datestrs = ['2020/5/6', '2021/10/1'] result = [datetime.strptime(x, '%Y/%m/%d') for x in datestrs] print(result) # [datetime.datetime(2020, 5, 6, 0, 0), datetime.datetime(2021, 10, 1, 0, 0)] dateutil \u89e3\u6790\u901a\u7528\u65e5\u671f\u683c\u5f0f\uff1a print(parse('2020/5/6')) # 2020-05-06 00:00:00 print(parse('Jan 31, 2021 10:25 AM')) # 2021-01-31 10:25:00 print(parse('5/6/2021', dayfirst=True)) # \u65e5\u671f\u51fa\u73b0\u5728\u6708\u4efd\u4e4b\u524d # 2021-06-05 00:00:00 pandas\u4e3b\u8981\u662f\u9762\u5411\u5904\u7406\u65e5\u671f\u6570\u7ec4\u7684\uff0c\u65e0\u8bba\u662f\u7528\u4f5c\u8f74\u7d22\u5f15\u8fd8\u662f\u7528\u4f5cDataFrame\u4e2d\u7684\u5217\u3002 to_datetime \u65b9\u6cd5\u53ef\u4ee5\u8f6c\u6362\u5f88\u591a\u4e0d\u540c\u7684\u65e5\u671f\u8868\u793a\u683c\u5f0f\u3002 to_datetime \u65b9\u6cd5\u8fd8\u53ef\u4ee5\u5904\u7406\u90a3\u4e9b\u88ab\u8ba4\u4e3a\u662f\u7f3a\u5931\u503c\u7684\u503c\uff08None\u3001\u7a7a\u5b57\u7b26\u4e32\u7b49\uff09\u3002 NaT \uff08Not a time\uff09\u662fpandas\u4e2d\u65f6\u95f4\u6233\u6570\u636e\u7684\u662fnull\u503c\u3002 datestrs = ['2020/5/6 12:00:00', '2021/10/1 09:00:00'] result = pd.to_datetime(datestrs) print(result) # DatetimeIndex(['2020-05-06 12:00:00', '2021-10-01 09:00:00'], dtype='datetime64[ns]', freq=None) idx = pd.to_datetime(datestrs + [None]) print(idx) # DatetimeIndex(['2020-05-06 12:00:00', '2021-10-01 09:00:00', 'NaT'], dtype='datetime64[ns]', freq=None) print(idx[2]) # NaT print(pd.isnull(idx)) # [False False True] \u65f6\u95f4\u5e8f\u5217\u57fa\u7840 \u00b6 from datetime import datetime import pandas as pd import numpy as np DatetimeIndex \u00b6 pandas\u4e2d\u7684\u57fa\u7840\u65f6\u95f4\u5e8f\u5217\u79cd\u7c7b\u662f\u7531\u65f6\u95f4\u6233\u7d22\u5f15\u7684Series\uff0c\u5728pandas\u5916\u90e8\u5219\u901a\u5e38\u8868\u793a\u4e3aPython\u5b57\u7b26\u4e32\u6216 datetime \u5bf9\u8c61\u3002 \u6240\u6709\u4f7f\u7528 datetime \u5bf9\u8c61\u7684\u5730\u65b9\u90fd\u53ef\u4ee5\u7528 Timestamp \u3002 dates = [ datetime(2021, 10, 1), datetime(2021, 10, 3), datetime(2021, 10, 5), datetime(2021, 10, 7), datetime(2021, 10, 9), datetime(2021, 10, 11) ] data = np.random.rand(6) ts = pd.Series(data, index=dates) print(ts) # 2021-10-01 0.678297 # 2021-10-03 0.538631 # 2021-10-05 0.934413 # 2021-10-07 0.018534 # 2021-10-09 0.938441 # 2021-10-11 0.173329 # dtype: float64 \u8fd9\u4e9b datetime \u5bf9\u8c61\u88ab\u653e\u5165 DatetimeIndex \u4e2d\u3002 print(ts.index) # DatetimeIndex(['2021-10-01', '2021-10-03', '2021-10-05', '2021-10-07', # '2021-10-09', '2021-10-11'], # dtype='datetime64[ns]', freq=None) DatetimeIndex \u4e2d\u7684\u6807\u91cf\u503c\u662f pandas \u7684 Timestamp \u5bf9\u8c61\uff1a stamp = ts.index[0] print(stamp) # 2021-10-01 00:00:00 \u548c\u5176\u4ed6Series\u7c7b\u4f3c\uff0c\u4e0d\u540c\u7d22\u5f15\u7684\u65f6\u95f4\u5e8f\u5217\u4e4b\u95f4\u7684\u7b97\u672f\u8fd0\u7b97\u5728\u65e5\u671f\u4e0a\u81ea\u52a8\u5bf9\u9f50\uff1a print(ts + ts[::2]) # ts[::2]\u4f1a\u5c06ts\u4e2d\u6bcf\u9694\u4e00\u4e2a\u7684\u5143\u7d20\u9009\u62e9\u51fa # 2021-10-01 1.356595 # 2021-10-03 NaN # 2021-10-05 1.868825 # 2021-10-07 NaN # 2021-10-09 1.876883 # 2021-10-11 NaN # dtype: float64 pandas\u4f7f\u7528NumPy\u7684 datetime64 \u6570\u636e\u7c7b\u578b\u5728\u7eb3\u79d2\u7ea7\u7684\u5206\u8fa8\u7387\u4e0b\u5b58\u50a8\u65f6\u95f4\u6233 print(ts.index.dtype) # datetime64[ns] \u7d22\u5f15\u3001\u9009\u62e9\u3001\u5b50\u96c6 \u00b6 \u5f53\u57fa\u4e8e\u6807\u7b7e\u8fdb\u884c\u7d22\u5f15\u548c\u9009\u62e9\u65f6\uff0c\u65f6\u95f4\u5e8f\u5217\u7684\u884c\u4e3a\u548c\u5176\u4ed6\u7684pandas.Series\u7c7b\u4f3c\uff1a stamp = ts.index[2] print(ts[stamp]) # 0.9344125159374457 \u5bf9\u5e942021-10-05 \u4e5f\u53ef\u4ee5\u4f20\u9012\u4e00\u4e2a\u80fd\u89e3\u91ca\u4e3a\u65e5\u671f\u7684\u5b57\u7b26\u4e32\uff1a print(ts['10/9/2021']) print(ts['20211003']) \u5bf9\u4e00\u4e2a\u957f\u7684\u65f6\u95f4\u5e8f\u5217\uff0c\u53ef\u4ee5\u4f20\u9012\u4e00\u4e2a\u5e74\u4efd\u6216\u4e00\u4e2a\u5e74\u4efd\u548c\u6708\u4efd\u6765\u9009\u62e9\u6570\u636e\u5207\u7247\uff1a data = np.random.randn(1000) longer_ts = pd.Series( data, index=pd.date_range('1/1/2021', periods=1000) ) print(longer_ts) # 2021-01-01 -0.009192 # 2021-01-02 -1.079068 # 2021-01-03 -1.851176 # 2021-01-04 1.347109 # 2021-01-05 -0.236394 # ... # 2023-09-23 -1.317943 # 2023-09-24 0.201741 # 2023-09-25 0.442282 # 2023-09-26 0.176137 # 2023-09-27 1.146437 # Freq: D, Length: 1000, dtype: float64 \u5b57\u7b26\u4e32\u20192001\u2019\u88ab\u89e3\u91ca\u4e3a\u4e00\u4e2a\u5e74\u4efd\uff0c\u5e76\u9009\u62e9\u4e86\u76f8\u5e94\u7684\u65f6\u95f4\u533a\u95f4\u3002 print(longer_ts['2021']) # 2021-01-01 2.170411 # 2021-01-02 1.186933 # 2021-01-03 0.399262 # 2021-01-04 -1.042606 # 2021-01-05 2.082112 # ... # 2021-12-27 -0.988282 # 2021-12-28 0.598683 # 2021-12-29 2.770580 # 2021-12-30 -1.463262 # 2021-12-31 -1.642846 # Freq: D, Length: 365, dtype: float64 \u6307\u5b9a\u4e86\u5e74\u4efd\u548c\u6708\u4efd\u4e5f\u662f\u6709\u6548\u7684\u3002 print(longer_ts['2021-10']) # 2021-10-01 0.712265 # 2021-10-02 1.195221 # 2021-10-03 -1.930220 # 2021-10-04 -0.720816 # 2021-10-05 0.081777 # 2021-10-06 -0.037466 # 2021-10-07 3.737303 # 2021-10-08 1.620383 # 2021-10-09 0.990797 # 2021-10-10 0.507850 # 2021-10-11 0.846935 # 2021-10-12 0.996947 # 2021-10-13 -1.078558 # 2021-10-14 0.871832 # 2021-10-15 -0.591698 # 2021-10-16 -0.805463 # 2021-10-17 0.160528 # 2021-10-18 -0.028474 # 2021-10-19 2.305579 # 2021-10-20 -1.132288 # 2021-10-21 0.649980 # 2021-10-22 0.615327 # 2021-10-23 0.185108 # 2021-10-24 0.857199 # 2021-10-25 -1.473752 # 2021-10-26 -0.895161 # 2021-10-27 -0.432717 # 2021-10-28 0.734504 # 2021-10-29 1.892493 # 2021-10-30 0.456619 # 2021-10-31 -0.255288 # Freq: D, dtype: float64 \u4f7f\u7528 datetime \u5bf9\u8c61\u8fdb\u884c\u5207\u7247\u4e5f\u662f\u53ef\u4ee5\u7684\uff1a print(longer_ts[datetime(2023, 1, 6):]) # 2023-01-06 0.952591 # 2023-01-07 -0.900259 # 2023-01-08 0.925332 # 2023-01-09 0.173215 # 2023-01-10 -0.507791 # ... # 2023-09-23 -0.319989 # 2023-09-24 -1.105417 # 2023-09-25 -2.118769 # 2023-09-26 0.009420 # 2023-09-27 -0.310281 # Freq: D, Length: 265, dtype: float64 \u56e0\u4e3a\u5927\u90e8\u5206\u7684\u65f6\u95f4\u5e8f\u5217\u6570\u636e\u662f\u6309\u65f6\u95f4\u987a\u5e8f\u6392\u5e8f\u7684\uff0c\u53ef\u4ee5\u4f7f\u7528\u4e0d\u5305\u542b\u5728\u65f6\u95f4\u5e8f\u5217\u4e2d\u7684\u65f6\u95f4\u6233\u8fdb\u884c\u5207\u7247\uff0c\u4ee5\u6267\u884c\u8303\u56f4\u67e5\u8be2\uff1a print(longer_ts['2021/10/1':'2021/10/5']) # 2021-10-01 -0.591853 # 2021-10-02 -1.554564 # 2021-10-03 -0.712585 # 2021-10-04 -0.326657 # 2021-10-05 1.044887 # Freq: D, dtype: float64 \u4f7f\u7528 truncate \u5728\u4e24\u4e2a\u65e5\u671f\u95f4\u5bf9Series\u8fdb\u884c\u5207\u7247\uff1a print(longer_ts.truncate(after='2021/10/1')) # 2021-01-01 -0.906685 # 2021-01-02 -0.470732 # 2021-01-03 -0.041316 # 2021-01-04 -0.287356 # 2021-01-05 0.104268 # ... # 2021-09-27 -0.669198 # 2021-09-28 -2.222169 # 2021-09-29 -0.653814 # 2021-09-30 -0.625868 # 2021-10-01 0.872684 # Freq: D, Length: 274, dtype: float64 \u4e0a\u9762\u8fd9\u4e9b\u64cd\u4f5c\u4e5f\u90fd\u9002\u7528\u4e8eDataFrame\uff0c\u5e76\u5728\u5176\u884c\u4e0a\u8fdb\u884c\u7d22\u5f15\uff1a dates = pd.date_range('10/1/2020', periods=100, freq='W-WED') data = np.random.randn(100, 4) long_df = pd.DataFrame( data, index=dates, columns=['Colorado', 'Texas', 'New York', 'Ohio'] ) print(long_df) # Colorado Texas New York Ohio # 2020-10-07 -1.186789 2.020634 0.300076 -0.955234 # 2020-10-14 1.502838 0.965368 -0.797539 -0.292833 # ... ... ... ... ... # 2022-08-24 -0.253116 -0.263307 0.602425 0.370599 # 2022-08-31 0.907918 0.091939 0.789694 2.781535 # [100 rows x 4 columns] print(long_df.loc['10-2020']) # Colorado Texas New York Ohio # 2020-10-07 1.031616 -1.812038 -0.446577 0.395656 # 2020-10-14 -0.673167 0.198804 -0.439141 0.086004 # 2020-10-21 -1.139786 0.716820 0.006516 -0.284335 # 2020-10-28 -0.637939 1.647810 -0.750786 0.140637 \u542b\u6709\u91cd\u590d\u7d22\u5f15\u7684\u65f6\u95f4\u5e8f\u5217 \u00b6 \u5728\u67d0\u4e9b\u5e94\u7528\u4e2d\uff0c\u53ef\u80fd\u4f1a\u6709\u591a\u4e2a\u6570\u636e\u89c2\u5bdf\u503c\u843d\u5728\u7279\u5b9a\u7684\u65f6\u95f4\u6233\u4e0a\u3002\u4e0b\u9762\u662f\u4e2a\u4f8b\u5b50\uff1a dates = pd.DatetimeIndex( ['2021/1/1', '2021/1/2', '2021/1/2', '2021/1/2', '2021/1/3'] ) dup_ts = pd.Series( np.arange(5), index=dates ) print(dup_ts) # 2021-01-01 0 # 2021-01-02 1 # 2021-01-02 2 # 2021-01-02 3 # 2021-01-03 4 # dtype: int64 \u901a\u8fc7\u68c0\u67e5\u7d22\u5f15\u7684 is_unique \u5c5e\u6027\uff0c\u53ef\u4ee5\u770b\u51fa\u7d22\u5f15\u5e76\u4e0d\u662f\u552f\u4e00\u7684\uff1a print(dup_ts.index.is_unique) # False \u5bf9\u4e0a\u9762\u7684Series\u8fdb\u884c\u7d22\u5f15\uff0c\u7ed3\u679c\u662f\u6807\u91cf\u503c\u8fd8\u662fSeries\u5207\u7247\u53d6\u51b3\u4e8e\u662f\u5426\u6709\u65f6\u95f4\u6233\u662f\u91cd\u590d\u7684\uff1a result = dup_ts['2021/1/3'] print(result) # 4 result = dup_ts['2021/1/2'] print(result) # 2021-01-02 1 # 2021-01-02 2 # 2021-01-02 3 # dtype: int64 \u5047\u8bbe\u60f3\u8981\u805a\u5408\u542b\u6709\u975e\u552f\u4e00\u65f6\u95f4\u6233\u7684\u6570\u636e\u3002\u4e00\u79cd\u65b9\u5f0f\u5c31\u662f\u4f7f\u7528 groupby \u5e76\u4f20\u9012 level=0 \uff1a grouped = dup_ts.groupby(level=0) result = grouped.mean() print(result) # 2021-01-01 0.0 # 2021-01-02 2.0 # 2021-01-03 4.0 # dtype: float64 result = grouped.count() print(result) # 2021-01-01 1 # 2021-01-02 3 # 2021-01-03 1 # dtype: int64 \u65e5\u671f\u8303\u56f4\u3001\u9891\u7387\u548c\u79fb\u4f4d \u00b6 from datetime import datetime, timedelta import pandas as pd import numpy as np from pandas.tseries.offsets import Hour, Minute, Day, MonthEnd pandas\u7684\u901a\u7528\u65f6\u95f4\u5e8f\u5217\u662f\u4e0d\u89c4\u5219\u7684\uff0c\u5373\u65f6\u95f4\u5e8f\u5217\u7684\u9891\u7387\u4e0d\u662f\u56fa\u5b9a\u7684\u3002 \u4f46\u6709\u65f6\u9700\u8981\u5904\u7406\u56fa\u5b9a\u9891\u7387\u7684\u573a\u666f\uff0c\u4f8b\u5982\u6bcf\u65e5\u7684\u3001\u6bcf\u6708\u7684\u6216\u6bcf15\u5206\u949f\u7684\u65f6\u95f4\u5e8f\u5217\u6570\u636e\u3002 \u53ef\u4ee5\u901a\u8fc7\u8c03\u7528resample\u65b9\u6cd5\u5c06\u6837\u672c\u65f6\u95f4\u5e8f\u5217\u8f6c\u6362\u4e3a\u56fa\u5b9a\u7684\u6bcf\u65e5\u9891\u7387\u6570\u636e\u3002 \u5728\u9891\u7387\u95f4\u8f6c\u6362\uff0c\u53c8\u79f0\u4e3a\u91cd\u65b0\u91c7\u6837\u3002 dates = [ datetime(2021, 10, 1), datetime(2021, 10, 3), datetime(2021, 10, 5), datetime(2021, 10, 7), datetime(2021, 10, 9), datetime(2021, 10, 11) ] data = np.random.rand(6) ts = pd.Series(data, index=dates) print(ts) # 2021-10-01 0.956685 # 2021-10-03 0.817168 # 2021-10-05 0.275543 # 2021-10-07 0.614226 # 2021-10-09 0.061377 # 2021-10-11 0.357080 # dtype: float64 resampler = ts.resample('D') # \u5b57\u7b26\u4e32\u2019D\u2019\u88ab\u89e3\u91ca\u4e3a\u6bcf\u65e5\u9891\u7387 print(resampler) # DatetimeIndexResampler [freq=, axis=0, closed=left, label=left, convention=start, origin=start_day] \u751f\u6210\u65e5\u671f\u8303\u56f4 \u00b6 pandas.date_range \u662f\u7528\u4e8e\u6839\u636e\u7279\u5b9a\u9891\u7387\u751f\u6210\u6307\u5b9a\u957f\u5ea6\u7684 DatetimeIndex \u3002 \u9ed8\u8ba4\u60c5\u51b5\u4e0b\uff0c date_range \u751f\u6210\u7684\u662f\u6bcf\u65e5\u7684\u65f6\u95f4\u6233\u3002\u5982\u679c\u53ea\u4f20\u9012\u4e00\u4e2a\u8d77\u59cb\u6216\u7ed3\u5c3e\u65e5\u671f\uff0c\u4f60\u5fc5\u987b\u4f20\u9012\u4e00\u4e2a\u7528\u4e8e\u751f\u6210\u8303\u56f4\u7684\u6570\u5b57\u3002 \u5f00\u59cb\u65e5\u671f\u548c\u7ed3\u675f\u65e5\u671f\u4e25\u683c\u5b9a\u4e49\u4e86\u751f\u6210\u65e5\u671f\u7d22\u5f15\u7684\u8fb9\u754c\u3002 index = pd.date_range('2021/1/1', '2021/1/30') print(index) index = pd.date_range(start='2021/1/1', periods=30) print(index) index = pd.date_range(end='2021/1/30', periods=30) print(index) # DatetimeIndex(['2021-01-01', '2021-01-02', '2021-01-03', '2021-01-04', # '2021-01-05', '2021-01-06', '2021-01-07', '2021-01-08', # '2021-01-09', '2021-01-10', '2021-01-11', '2021-01-12', # '2021-01-13', '2021-01-14', '2021-01-15', '2021-01-16', # '2021-01-17', '2021-01-18', '2021-01-19', '2021-01-20', # '2021-01-21', '2021-01-22', '2021-01-23', '2021-01-24', # '2021-01-25', '2021-01-26', '2021-01-27', '2021-01-28', # '2021-01-29', '2021-01-30'], # dtype='datetime64[ns]', freq='D') \u9ed8\u8ba4\u60c5\u51b5\u4e0b\uff0c date_range \u4fdd\u7559\u5f00\u59cb\u6216\u7ed3\u675f\u65f6\u95f4\u6233\u7684\u65f6\u95f4\uff08\u5982\u679c\u6709\u7684\u8bdd\uff09\u3002 normalize \u9009\u9879\u53ef\u4ee5\u5b9e\u73b0\u751f\u6210\u7684\u662f\u6807\u51c6\u5316\u4e3a\u96f6\u70b9\u7684\u65f6\u95f4\u6233\u3002 index = pd.date_range('2021/1/1 12:56:30', periods=5) print(index) # DatetimeIndex(['2021-01-01 12:56:30', '2021-01-02 12:56:30', # '2021-01-03 12:56:30', '2021-01-04 12:56:30', # '2021-01-05 12:56:30'], # dtype='datetime64[ns]', freq='D') index = pd.date_range('2021/1/1 12:56:30', periods=5, normalize=True) print(index) # DatetimeIndex(['2021-01-01', '2021-01-02', '2021-01-03', '2021-01-04', # '2021-01-05'], # dtype='datetime64[ns]', freq='D') Pandas\u65f6\u95f4\u5e8f\u5217\uff1a\u9891\u7387\u548c\u65e5\u671f\u504f\u79fb\u91cf\u3002 pandas\u4e2d\u7684\u9891\u7387\u662f\u7531\u4e00\u4e2a\u57fa\u7840\u9891\u7387(\u4f8b\u5982\u201c\u65e5\u201d\u3001\u201c\u6708\u201d)\u548c\u4e00\u4e2a\u4e58\u6570\u7ec4\u6210\u3002 \u57fa\u7840\u9891\u7387\u901a\u5e38\u4ee5\u4e00\u4e2a\u5b57\u7b26\u4e32\u522b\u540d\u8868\u793a\uff0c\u6bd4\u5982\u201cD\u201d\u8868\u793a\u65e5\uff0c\u201cM\u201d\u8868\u793a\u6708\u3002 \u5bf9\u4e8e\u6bcf\u4e2a\u57fa\u7840\u9891\u7387\uff0c\u90fd\u6709\u4e00\u4e2a\u88ab\u79f0\u4e3a\u65e5\u671f\u504f\u79fb\u91cf(dateoffset)\u7684\u5bf9\u8c61\u4e0e\u4e4b\u5bf9\u5e94\uff0c\u6bd4\u5982\u65e5\u671f\u504f\u79fb\u91cf Hour \u5bf9\u5e94\u7684\u9891\u7387\u662f H \u3002 \u5e38\u7528\u9891\u7387\u4e0e\u65e5\u671f\u504f\u79fb\u91cf\u3002 \u9891\u7387 \u65e5\u671f\u504f\u79fb\u91cf \u8bf4\u660e D Day \u65e5\u5386\u65e5 B BusinessDay \u5de5\u4f5c\u65e5 H Hour \u5c0f\u65f6 T/min Minute \u5206 S Second \u79d2 L/ms Milli \u6beb\u79d2 U Micro \u5fae\u79d2 M MonthEnd \u6bcf\u6708\u6700\u540e\u4e00\u4e2a\u65e5\u5386\u65e5 BM BusinessMonthEnd \u6bcf\u6708\u6700\u540e\u4e00\u4e2a\u5de5\u4f5c\u65e5 MS MonthBegin \u6bcf\u6708\u7b2c\u4e00\u4e2a\u65e5\u5386\u65e5 BMS BussinessMonthBegin \u6bcf\u6708\u7b2c\u4e00\u4e2a\u5de5\u4f5c\u65e5 W-MON, W-TUE, ... Week \u6307\u5b9a\u661f\u671f\u51e0(MON,TUE,WED,THU,FRI,SAT,SUN) WOM-1MON,WOM-2MON, ... WeekOfMonth \u4ea7\u751f\u6bcf\u6708\u7b2c\u4e00,\u7b2c\u4e8c,\u7b2c\u4e09\u6216\u7b2c\u56db\u5468\u7684\u661f\u671f\u51e0\u3002\u4f8b\u5982WOM-3FRI\u8868\u793a\u6bcf\u6708\u7b2c3\u4e2a\u661f\u671f\u4e94 Q-JAN,Q-FEB, ... QuarterEnd \u4ee5\u6307\u5b9a\u6708\u4efd\u7ed3\u675f\u7684\u5e74\u5ea6\uff0c\u6bcf\u5b63\u5ea6\u6700\u540e\u4e00\u4e2a\u6708\u7684\u6700\u540e\u4e00\u4e2a\u65e5\u5386\u65e5 BQ-JAN,BQ-FEB, ... BusinessQuarterEnd \u4ee5\u6307\u5b9a\u6708\u4efd\u7ed3\u675f\u7684\u5e74\u5ea6\uff0c\u6bcf\u5b63\u5ea6\u6700\u540e\u4e00\u4e2a\u6708\u7684\u6700\u540e\u4e00\u4e2a\u5de5\u4f5c\u65e5 QS-JAN,QS-FEB, ... QuarterBegin \u4ee5\u6307\u5b9a\u6708\u4efd\u7ed3\u675f\u7684\u5e74\u5ea6\uff0c\u6bcf\u5b63\u5ea6\u6700\u540e\u4e00\u4e2a\u6708\u7684\u7b2c\u4e00\u4e2a\u65e5\u5386\u65e5 BQS-JAN,BQS-FEB, ... BusinessQuarterBegin \u4ee5\u6307\u5b9a\u6708\u4efd\u7ed3\u675f\u7684\u5e74\u5ea6\uff0c\u6bcf\u5b63\u5ea6\u6700\u540e\u4e00\u4e2a\u6708\u7684\u7b2c\u4e00\u4e2a\u5de5\u4f5c\u65e5 A-JAN,A-FEB, ... YearEnd \u6bcf\u5e74\u6307\u5b9a\u6708\u4efd\u7684\u6700\u540e\u4e00\u4e2a\u65e5\u5386\u65e5 BA-JAN,BA-FEB, ... BusinessYearEnd \u6bcf\u5e74\u6307\u5b9a\u6708\u4efd\u7684\u6700\u540e\u4e00\u4e2a\u5de5\u4f5c\u65e5 AS-JAN,AS-FEB, ... YearBegin \u6bcf\u5e74\u6307\u5b9a\u6708\u4efd\u7684\u7b2c\u4e00\u4e2a\u65e5\u5386\u65e5 BAS-JAN,BAS-FEB, ... BusinessYearBegin \u6bcf\u5e74\u6307\u5b9a\u6708\u4efd\u7684\u7b2c\u4e00\u4e2a\u5de5\u4f5c\u65e5 \u9891\u7387\u548c\u65e5\u671f\u504f\u7f6e \u00b6 pandas\u4e2d\u7684\u9891\u7387\u662f\u7531\u57fa\u7840\u9891\u7387\u548c\u500d\u6570\u7ec4\u6210\u7684\u3002 \u57fa\u7840\u9891\u7387\u901a\u5e38\u4f1a\u6709\u5b57\u7b26\u4e32\u522b\u540d\uff0c\u4f8b\u5982 M \u4ee3\u8868\u6bcf\u6708\uff0c H \u4ee3\u8868\u6bcf\u5c0f\u65f6\u3002 \u5bf9\u4e8e\u6bcf\u4e2a\u57fa\u7840\u9891\u7387\uff0c\u90fd\u6709\u4e00\u4e2a\u5bf9\u8c61\u53ef\u4ee5\u88ab\u7528\u4e8e\u5b9a\u4e49\u65e5\u671f\u504f\u7f6e\u3002 \u4f8b\u5982\uff0c\u6bcf\u5c0f\u65f6\u7684\u9891\u7387\u53ef\u4ee5\u4f7f\u7528 Hour \u7c7b\u6765\u8868\u793a\uff1a ```hour = Hour() print(hour) \u00b6 \u53ef\u4ee5\u4f20\u9012\u4e00\u4e2a\u6574\u6570\u6765\u5b9a\u4e49\u504f\u7f6e\u91cf\u7684\u500d\u6570\uff1a four_hours = Hour(4) print(four_hours) <4 * Hours> \u00b6 \u5728\u5927\u591a\u6570\u5e94\u7528\u4e2d\uff0c\u4e0d\u9700\u8981\u663e\u5f0f\u5730\u521b\u5efa\u8fd9\u4e9b\u5bf9\u8c61\uff0c\u800c\u662f\u4f7f\u7528\u5b57\u7b26\u4e32\u522b\u540d\uff0c\u5982`H`\u6216`4H`\u3002\u5728\u57fa\u7840\u9891\u7387\u524d\u653e\u4e00\u4e2a\u6574\u6570\u5c31\u53ef\u4ee5\u751f\u6210\u500d\u6570\uff1a ts = pd.date_range('2021/1/1', '2021/\u00bd 23:59', freq='4h') print(ts) DatetimeIndex(['2021-01-01 00:00:00', '2021-01-01 04:00:00', \u00b6 '2021-01-01 08:00:00', '2021-01-01 12:00:00', \u00b6 '2021-01-01 16:00:00', '2021-01-01 20:00:00', \u00b6 '2021-01-02 00:00:00', '2021-01-02 04:00:00', \u00b6 '2021-01-02 08:00:00', '2021-01-02 12:00:00', \u00b6 '2021-01-02 16:00:00', '2021-01-02 20:00:00'], \u00b6 dtype='datetime64[ns]', freq='4H') \u00b6 \u591a\u4e2a\u504f\u7f6e\u53ef\u4ee5\u901a\u8fc7\u52a0\u6cd5\u8fdb\u884c\u8054\u5408\uff1a print(Hour(2) + Minute(30)) <150 * Minutes> \u00b6 \u7c7b\u4f3c\u5730\uff0c\u53ef\u4ee5\u4f20\u9012\u9891\u7387\u5b57\u7b26\u4e32\uff1a ts = pd.date_range('2021/1/1', '2021/1/1 23:59', freq='4h30min') print(ts) DatetimeIndex(['2021-01-01 00:00:00', '2021-01-01 04:30:00', \u00b6 '2021-01-01 09:00:00', '2021-01-01 13:30:00', \u00b6 '2021-01-01 18:00:00', '2021-01-01 22:30:00'], \u00b6 dtype='datetime64[ns]', freq='270T') \u00b6 \u6709\u4e9b\u9891\u7387\u63cf\u8ff0\u70b9\u7684\u65f6\u95f4\u5e76\u4e0d\u662f\u5747\u5300\u5206\u9694\u7684\u3002\u4f8b\u5982\uff0c`M`\uff08\u65e5\u5386\u6708\u672b\uff09\u548c`BM`\uff08\u6708\u5185\u6700\u540e\u5de5\u4f5c\u65e5\uff09\u53d6\u51b3\u4e8e\u5f53\u6708\u5929\u6570\uff0c\u6708\u672b\u662f\u5426\u662f\u5468\u672b\u3002\u6211\u4eec\u5c06\u8fd9\u4e9b\u65e5\u671f\u79f0\u4e3a\u951a\u5b9a\u504f\u7f6e\u91cf\u3002 #### \u6708\u4e2d\u67d0\u661f\u671f\u7684\u65e5\u671f \"\u6708\u4e2d\u67d0\u661f\u671f\"\uff08week of month \uff09\u7684\u65e5\u671f\u662f\u4e00\u4e2a\u6709\u7528\u7684\u9891\u7387\u7c7b\uff0c\u4ee5`WOM`\u5f00\u59cb\u3002 rng = pd.date_range('2021-1-1', '2021-9-1', freq='WOM-3FRI') # \u6bcf\u6708\u7b2c\u4e09\u4e2a\u661f\u671f\u4e94 print(rng) DatetimeIndex(['2021-01-15', '2021-02-19', '2021-03-19', '2021-04-16', \u00b6 '2021-05-21', '2021-06-18', '2021-07-16', '2021-08-20'], \u00b6 dtype='datetime64[ns]', freq='WOM-3FRI') \u00b6 ### \u79fb\u4f4d\uff08\u524d\u5411\u548c\u540e\u5411\uff09\u65e5\u671f \"\u79fb\u4f4d\"\u662f\u6307\u5c06\u65e5\u671f\u6309\u65f6\u95f4\u5411\u524d\u79fb\u52a8\u6216\u5411\u540e\u79fb\u52a8\u3002 Series\u548cDataFrame\u90fd\u6709\u4e00\u4e2a`shift`\u65b9\u6cd5\u7528\u4e8e\u8fdb\u884c\u7b80\u5355\u7684\u524d\u5411\u6216\u540e\u5411\u79fb\u4f4d\uff0c\u800c\u4e0d\u6539\u53d8\u7d22\u5f15\u3002 \u8fdb\u884c\u79fb\u4f4d\u65f6\uff0c\u4f1a\u5728\u65f6\u95f4\u5e8f\u5217\u7684\u8d77\u59cb\u4f4d\u6216\u7ed3\u675f\u4f4d\u5f15\u5165\u7f3a\u5931\u503c\u3002 data = [0.882972, 1.363282, -0.687750, -0.048117] ts = pd.Series(data, index=pd.date_range('2021-1-1', periods=4, freq='M')) print(ts) 2021-01-31 0.882972 \u00b6 2021-02-28 1.363282 \u00b6 2021-03-31 -0.687750 \u00b6 2021-04-30 -0.048117 \u00b6 Freq: M, dtype: float64 \u00b6 print(ts.shift(2)) 2021-01-31 NaN \u00b6 2021-02-28 NaN \u00b6 2021-03-31 0.882972 \u00b6 2021-04-30 1.363282 \u00b6 Freq: M, dtype: float64 \u00b6 print(ts.shift(-2)) 2021-01-31 -0.687750 \u00b6 2021-02-28 -0.048117 \u00b6 2021-03-31 NaN \u00b6 2021-04-30 NaN \u00b6 Freq: M, dtype: float64 \u00b6 `shift`\u5e38\u7528\u4e8e\u8ba1\u7b97\u65f6\u95f4\u5e8f\u5217\u6216DataFrame\u591a\u5217\u65f6\u95f4\u5e8f\u5217\u7684\u767e\u5206\u6bd4\u53d8\u5316\uff1a print(ts/ts.shift(1)) 2021-01-31 NaN \u00b6 2021-02-28 1.543970 \u00b6 2021-03-31 -0.504481 \u00b6 2021-04-30 0.069963 \u00b6 Freq: M, dtype: float64 \u00b6 print(ts/ts.shift(1) - 1) 2021-01-31 NaN \u00b6 2021-02-28 0.543970 \u00b6 2021-03-31 -1.504481 \u00b6 2021-04-30 -0.930037 \u00b6 Freq: M, dtype: float64 \u00b6 \u5982\u679c\u9891\u7387\u662f\u5df2\u77e5\u7684\uff0c\u5219\u53ef\u4ee5\u5c06\u9891\u7387\u4f20\u9012\u7ed9`shift`\u6765\u63a8\u79fb\u65f6\u95f4\u6233\uff1a print(ts.shift(2, freq='M')) # \u539f\u59cb\u6570\u636e\u7684\u201c\u6708\u201c\u589e\u52a0\u4e86\u504f\u79fb\u503c 2021-03-31 0.882972 \u00b6 2022021-10-31 00:00:001-04-30 1.363282 \u00b6 2021-05-31 -0.687750 \u00b6 2021-06-30 -0.048117 \u00b6 Freq: M, dtype: float64 \u00b6 print(ts.shift(2, freq='D')) # \u539f\u59cb\u6570\u636e\u7684\u201c\u65e5\u201c\u589e\u52a0\u4e86\u504f\u79fb\u503c 2021-02-02 0.882972 \u00b6 2021-03-02 1.363282 \u00b6 2021-04-02 -0.687750 \u00b6 2021-05-02 -0.048117 \u00b6 dtype: float64 \u00b6 print(ts.shift(2, freq='90T')) # \u539f\u59cb\u6570\u636e\u7684\u201c\u5c0f\u65f6\u201c\u589e\u52a0\u4e86\u504f\u79fb\u503c 2021-01-31 03:00:00 0.882972 \u00b6 2021-02-28 03:00:00 1.363282 \u00b6 2021-03-31 03:00:00 -0.687750 \u00b6 2021-04-30 03:00:00 -0.048117 \u00b6 dtype: float64 \u00b6 #### \u4f7f\u7528\u504f\u7f6e\u8fdb\u884c\u79fb\u4f4d\u65e5\u671f pandas\u65e5\u671f\u504f\u7f6e\u4e5f\u53ef\u4ee5\u4f7f\u7528`datetime`\u6216`Timestamp`\u5bf9\u8c61\u5b8c\u6210\uff1a now = datetime(2021, 10, 9) print(now) 2021-10-09 00:00:00 \u00b6 print(now + 3 * Day()) 2021-10-12 00:00:00 \u00b6 \u951a\u5b9a\u504f\u7f6e\u53ef\u4ee5\u4f7f\u7528`rollforward`\u548c`rollback`\u5206\u522b\u663e\u5f0f\u5730\u5c06\u65e5\u671f\u5411\u524d\u6216\u5411\u540e\"\u6eda\u52a8\"\u3002 \u5982\u679c\u6dfb\u52a0\u4e86\u4e00\u4e2a\u951a\u5b9a\u504f\u7f6e\u91cf\uff0c\u6bd4\u5982`MonthEnd`\uff0c\u6839\u636e\u9891\u7387\u89c4\u5219\uff0c\u7b2c\u4e00\u4e2a\u589e\u91cf\u4f1a\u5c06\u65e5\u671f\u201c\u524d\u6eda\u201d\u5230\u4e0b\u4e00\u4e2a\u65e5\u671f\uff1a print(now + MonthEnd()) # \u201c\u524d\u6eda\u201d\u5230\u5f53\u524d\u6708\u7684\u6708\u5e95 2021-10-31 00:00:00 \u00b6 print(now + MonthEnd(2)) # \u6ce8\u610f\u8fd9\u91cc\u7684\u5e8f\u5217\u53f7\uff0c\u5f53\u524d\u6708\u662f1,\u4e0b\u4e2a\u6708\u662f2 2021-11-30 00:00:00 \u00b6 offset = MonthEnd() print(offset.rollback(now)) 2021-09-30 00:00:00 \u00b6 print(offset.rollforward(now)) 2021-10-31 00:00:00 \u00b6 \u5c06\u79fb\u4f4d\u65b9\u6cd5\u4e0e`groupby`\u4e00\u8d77\u4f7f\u7528\u662f\u65e5\u671f\u504f\u7f6e\u7684\u4e00\u79cd\u521b\u9020\u6027\u7528\u6cd5\uff1a ts = pd.Series( np.random.randn(20), index=pd.date_range('2021/1/1', periods=20, freq='4d') ) print(ts) 2021-01-01 0.674348 \u00b6 2021-01-05 -1.437803 \u00b6 2021-01-09 -0.079218 \u00b6 2021-01-13 -1.444890 \u00b6 2021-01-17 0.643279 \u00b6 2021-01-21 1.089965 \u00b6 2021-01-25 0.021876 \u00b6 2021-01-29 0.692138 \u00b6 2021-02-02 0.833496 \u00b6 2021-02-06 1.082616 \u00b6 2021-02-10 -0.729415 \u00b6 2021-02-14 0.271186 \u00b6 2021-02-18 -1.416218 \u00b6 2021-02-22 -0.780402 \u00b6 2021-02-26 -0.113773 \u00b6 2021-03-02 2.095338 \u00b6 2021-03-06 -0.302612 \u00b6 2021-03-10 1.113632 \u00b6 2021-03-14 -1.314581 \u00b6 2021-03-18 0.947746 \u00b6 Freq: 4D, dtype: float64 \u00b6 print(ts.groupby(offset.rollforward).mean()) # \u524d\u6eda\u81f3\u5f53\u6708\u6708\u5e95\uff0c\u8ba1\u7b97\u5f53\u6708\u5e73\u5747\u503c 2021-01-31 0.019962 \u00b6 2021-02-28 -0.121787 \u00b6 2021-03-31 0.507905 \u00b6 dtype: float64 \u00b6 \u4f7f\u7528resample\u662f\u66f4\u7b80\u5355\u66f4\u5feb\u6377\u7684\u65b9\u6cd5 \u00b6 print(ts.resample('M').mean()) 2021-01-31 0.019962 \u00b6 2021-02-28 -0.121787 \u00b6 2021-03-31 0.507905 \u00b6 Freq: M, dtype: float64 \u00b6 ## \u65f6\u533a\u5904\u7406 \u65f6\u533a\u901a\u5e38\u88ab\u8868\u793a\u4e3aUTC\u7684\u504f\u7f6e\u3002 \u5728Python\u8bed\u8a00\u4e2d\uff0c\u65f6\u533a\u4fe1\u606f\u6765\u6e90\u4e8e\u7b2c\u4e09\u65b9\u5e93pytz\uff08\u53ef\u4ee5\u4f7f\u7528pip\u6216conda\u5b89\u88c5\uff09\uff0c\u5176\u4e2d\u516c\u5f00\u4e86Olson\u6570\u636e\u5e93\uff0c\u8fd9\u662f\u4e16\u754c\u65f6\u533a\u4fe1\u606f\u7684\u6c47\u7f16\u3002 pandas\u5c01\u88c5\u4e86pytz\u7684\u529f\u80fd\u3002 from datetime import datetime, timedelta import pandas as pd import numpy as np from pandas.tseries.offsets import Hour, Minute, Day, MonthEnd import pytz #### common_timezones tz = pytz.common_timezones[-5:] # \u8bfb\u53d6common_timezones\u8fd9\u4e2a\u5217\u8868\u7684\u6700\u540e5\u4e2a\u5143\u7d20 print(tz) ['US/Eastern', 'US/Hawaii', 'US/Mountain', 'US/Pacific', 'UTC'] \u00b6 \u8981\u83b7\u5f97pytz\u7684\u65f6\u533a\u5bf9\u8c61\uff0c\u53ef\u4f7f\u7528pytz.timezone\uff1a tz = pytz.timezone('Asia/Shanghai') print(tz) #### \u65f6\u533a\u7684\u672c\u5730\u5316\u548c\u8f6c\u6362 \u9ed8\u8ba4\u60c5\u51b5\u4e0b\uff0cpandas\u4e2d\u7684\u65f6\u95f4\u5e8f\u5217\u662f\u65f6\u533a\u7b80\u5355\u578b\u7684\u3002 rng = pd.date_range('2021/1/1 9:30', periods=6, freq='D') ts = pd.Series(np.random.randn(len(rng)), index=rng) print(rng) DatetimeIndex(['2021-01-01 09:30:00', '2021-01-02 09:30:00', \u00b6 '2021-01-03 09:30:00', '2021-01-04 09:30:00', \u00b6 '2021-01-05 09:30:00', '2021-01-06 09:30:00'], \u00b6 dtype='datetime64[ns]', freq='D') \u00b6 print(ts) 2021-01-01 09:30:00 0.339822 \u00b6 2021-01-02 09:30:00 1.356382 \u00b6 2021-01-03 09:30:00 0.475429 \u00b6 2021-01-04 09:30:00 1.826654 \u00b6 2021-01-05 09:30:00 -0.245510 \u00b6 2021-01-06 09:30:00 0.705274 \u00b6 Freq: D, dtype: float64 \u00b6 print(ts.index.tz) # \u7d22\u5f15\u7684tz\u5c5e\u6027\u662fNone None \u00b6 \u65e5\u671f\u8303\u56f4\u53ef\u4ee5\u901a\u8fc7\u65f6\u533a\u96c6\u5408\u6765\u751f\u6210\uff1a rng = pd.date_range('2021/3/1', periods=10, freq='D', tz='UTC') print(rng) DatetimeIndex(['2021-03-01 00:00:00+00:00', '2021-03-02 00:00:00+00:00', \u00b6 '2021-03-03 00:00:00+00:00', '2021-03-04 00:00:00+00:00', \u00b6 '2021-03-05 00:00:00+00:00', '2021-03-06 00:00:00+00:00', \u00b6 '2021-03-07 00:00:00+00:00', '2021-03-08 00:00:00+00:00', \u00b6 '2021-03-09 00:00:00+00:00', '2021-03-10 00:00:00+00:00'], \u00b6 dtype='datetime64[ns, UTC]', freq='D') \u00b6 \u4f7f\u7528`tz_localize`\u65b9\u6cd5\u53ef\u4ee5\u4ece\u7b80\u5355\u65f6\u533a\u8f6c\u6362\u5230\u672c\u5730\u5316\u65f6\u533a\uff1a print(ts) 2021-01-01 09:30:00 0.294647 \u00b6 2021-01-02 09:30:00 0.958414 \u00b6 2021-01-03 09:30:00 0.424235 \u00b6 2021-01-04 09:30:00 -1.714333 \u00b6 2021-01-05 09:30:00 -0.030319 \u00b6 2021-01-06 09:30:00 -0.744940 \u00b6 Freq: D, dtype: float64 \u00b6 print(ts.tz_localize('UTC')) 2021-01-01 09:30:00+00:00 0.294647 \u00b6 2021-01-02 09:30:00+00:00 0.958414 \u00b6 2021-01-03 09:30:00+00:00 0.424235 \u00b6 2021-01-04 09:30:00+00:00 -1.714333 \u00b6 2021-01-05 09:30:00+00:00 -0.030319 \u00b6 2021-01-06 09:30:00+00:00 -0.744940 \u00b6 Freq: D, dtype: float64 \u00b6 print(ts.tz_localize('Asia/Shanghai')) 2021-01-01 09:30:00+08:00 0.052521 \u00b6 2021-01-02 09:30:00+08:00 -0.305417 \u00b6 2021-01-03 09:30:00+08:00 0.150215 \u00b6 2021-01-04 09:30:00+08:00 -0.953715 \u00b6 2021-01-05 09:30:00+08:00 0.543622 \u00b6 2021-01-06 09:30:00+08:00 0.222422 \u00b6 dtype: float64 \u00b6 print(ts.tz_localize('Asia/Shanghai').index) DatetimeIndex(['2021-01-01 09:30:00+08:00', '2021-01-02 09:30:00+08:00', \u00b6 '2021-01-03 09:30:00+08:00', '2021-01-04 09:30:00+08:00', \u00b6 '2021-01-05 09:30:00+08:00', '2021-01-06 09:30:00+08:00'], \u00b6 dtype='datetime64[ns, Asia/Shanghai]', freq=None) \u00b6 \u4e00\u65e6\u65f6\u95f4\u5e8f\u5217\u88ab\u672c\u5730\u5316\u4e3a\u67d0\u4e2a\u7279\u5b9a\u7684\u65f6\u533a\uff0c\u5219\u53ef\u4ee5\u901a\u8fc7`tz_convert`\u5c06\u5176\u8f6c\u6362\u4e3a\u53e6\u4e00\u4e2a\u65f6\u533a\uff1a tz_sha = ts.tz_localize('Asia/Shanghai') tz_utc = tz_sha.tz_convert('UTC') print(tz_sha) 2021-01-01 09:30:00+08:00 0.095689 \u00b6 2021-01-02 09:30:00+08:00 -0.392730 \u00b6 2021-01-03 09:30:00+08:00 0.151468 \u00b6 2021-01-04 09:30:00+08:00 0.027467 \u00b6 2021-01-05 09:30:00+08:00 0.393709 \u00b6 2021-01-06 09:30:00+08:00 0.872914 \u00b6 dtype: float64 \u00b6 print(tz_utc) 2021-01-01 01:30:00+00:00 0.095689 \u00b6 2021-01-02 01:30:00+00:00 -0.392730 \u00b6 2021-01-03 01:30:00+00:00 0.151468 \u00b6 2021-01-04 01:30:00+00:00 0.027467 \u00b6 2021-01-05 01:30:00+00:00 0.393709 \u00b6 2021-01-06 01:30:00+00:00 0.872914 \u00b6 dtype: float64 \u00b6 tz_localize\u548ctz_convert\u4e5f\u662fDatetimeIndex\u7684\u5b9e\u4f8b\u65b9\u6cd5\uff1a \u00b6 print(ts.index.tz_localize('Asia/Shanghai')) DatetimeIndex(['2021-01-01 09:30:00+08:00', '2021-01-02 09:30:00+08:00', \u00b6 '2021-01-03 09:30:00+08:00', '2021-01-04 09:30:00+08:00', \u00b6 '2021-01-05 09:30:00+08:00', '2021-01-06 09:30:00+08:00'], \u00b6 dtype='datetime64[ns, Asia/Shanghai]', freq=None) \u00b6 ### \u65f6\u533a\u611f\u77e5\u65f6\u95f4\u6233\u5bf9\u8c61\u7684\u64cd\u4f5c \u4e0e\u65f6\u95f4\u5e8f\u5217\u548c\u65e5\u671f\u8303\u56f4\u7c7b\u4f3c\uff0c\u5355\u72ec\u7684`Timestamp`\u5bf9\u8c61\u4e5f\u53ef\u4ee5\u4ece\u7b80\u5355\u65f6\u95f4\u6233\u672c\u5730\u5316\u4e3a\u65f6\u533a\u611f\u77e5\u65f6\u95f4\u6233\uff0c\u5e76\u4ece\u4e00\u4e2a\u65f6\u533a\u8f6c\u6362\u4e3a\u53e6\u4e00\u4e2a\u65f6\u533a\uff1a stamp = pd.Timestamp('2021-5-1 05:30') print(stamp) 2021-05-01 05:30:00 \u00b6 stamp_utc = stamp.tz_localize('utc') print(stamp_utc) 2021-05-01 05:30:00+00:00 \u00b6 stamp_sha = stamp_utc.tz_convert('Asia/Shanghai') print(stamp_sha) 2021-05-01 13:30:00+08:00 \u00b6 \u4e5f\u53ef\u4ee5\u5728\u521b\u5efa`Timestamp`\u7684\u65f6\u5019\u4f20\u9012\u4e00\u4e2a\u65f6\u533a\uff1a stamp_sha = pd.Timestamp('2021-5-1 05:30', tz='Asia/Shanghai') print(stamp_sha) 2021-05-01 05:30:00+08:00 \u00b6 `Timestamp`\u5bf9\u8c61\u5185\u90e8\u5b58\u50a8\u4e86\u4e00\u4e2aUnix\u7eaa\u5143(1970\u5e741\u67081\u65e5)\u81f3\u4eca\u7684\u7eb3\u79d2\u6570\u91cfUTC\u65f6\u95f4\u6233\u6570\u503c\uff0c\u8be5\u6570\u503c\u5728\u65f6\u533a\u8f6c\u6362\u4e2d\u662f\u4e0d\u53d8\u7684\uff1a print(stamp_utc.value) 1619847000000000000 \u00b6 print(stamp_utc.tz_convert('Asia/Shanghai').value) 1619847000000000000 \u00b6 \u5728\u4f7f\u7528pandas\u7684`DateOffset`\u8fdb\u884c\u65f6\u95f4\u7b97\u672f\u65f6\uff0cpandas\u5c3d\u53ef\u80fd\u9075\u4ece\u590f\u65f6\u5236\u3002 \u9996\u5148\uff0c\u6784\u9020\u8f6c\u6362\u5230DST\u4e4b\u524d\u768430\u5206\u949f\u7684\u65f6\u95f4\uff1a stamp = pd.Timestamp('2012-3-12 1:30', tz='US/Eastern') print(stamp) 2012-03-12 01:30:00-04:00 \u00b6 print(stamp + Hour()) 2012-03-12 02:30:00-04:00 \u00b6 \u4e4b\u540e\uff0c\u6784\u5efa\u4eceDST\u8fdb\u884c\u8f6c\u6362\u524d\u768490\u5206\u949f\uff1a stamp = pd.Timestamp('2012-11-04 0:30-04:00', tz='US/Eastern') print(stamp) 2012-11-04 00:30:00-04:00 \u00b6 print(stamp + 2 * Hour()) # \u53ea\u589e\u52a0\u4e86\u4e00\u5c0f\u65f6 2012-11-04 01:30:00-05:00 \u00b6 ### \u4e0d\u540c\u65f6\u533a\u95f4\u7684\u64cd\u4f5c \u5982\u679c\u4e24\u4e2a\u65f6\u533a\u4e0d\u540c\u7684\u65f6\u95f4\u5e8f\u5217\u9700\u8981\u8054\u5408\uff0c\u90a3\u4e48\u7ed3\u679c\u5c06\u662fUTC\u65f6\u95f4\u7684\uff0c\u56e0\u4e3a\u65f6\u95f4\u6233\u4ee5UTC\u683c\u5f0f\u5b58\u50a8\u3002 rng = pd.date_range('2021/1/1 9:30', periods=9, freq='B') ts = pd.Series(np.random.randn(len(rng)), index=rng) print(ts) 2021-01-01 09:30:00 0.715681 \u00b6 2021-01-04 09:30:00 0.524563 \u00b6 2021-01-05 09:30:00 -0.482199 \u00b6 2021-01-06 09:30:00 -0.661303 \u00b6 2021-01-07 09:30:00 1.750010 \u00b6 2021-01-08 09:30:00 0.251478 \u00b6 2021-01-11 09:30:00 -1.487268 \u00b6 2021-01-12 09:30:00 -0.224024 \u00b6 2021-01-13 09:30:00 -1.621853 \u00b6 Freq: B, dtype: float64 \u00b6 ts1 = ts[:7].tz_localize('Europe/London') ts2 = ts1[2:].tz_convert('Europe/Moscow') result = ts1 + ts2 print(ts1) 2021-01-01 09:30:00+00:00 -1.393445 \u00b6 2021-01-04 09:30:00+00:00 -1.179614 \u00b6 2021-01-05 09:30:00+00:00 0.716669 \u00b6 2021-01-06 09:30:00+00:00 -0.485656 \u00b6 2021-01-07 09:30:00+00:00 0.433000 \u00b6 2021-01-08 09:30:00+00:00 1.540745 \u00b6 2021-01-11 09:30:00+00:00 0.343751 \u00b6 dtype: float64 \u00b6 print(ts2) 2021-01-05 12:30:00+03:00 0.716669 \u00b6 2021-01-06 12:30:00+03:00 -0.485656 \u00b6 2021-01-07 12:30:00+03:00 0.433000 \u00b6 2021-01-08 12:30:00+03:00 1.540745 \u00b6 2021-01-11 12:30:00+03:00 0.343751 \u00b6 dtype: float64 \u00b6 print(result) 2021-01-01 09:30:00+00:00 NaN \u00b6 2021-01-04 09:30:00+00:00 NaN \u00b6 2021-01-05 09:30:00+00:00 1.433337 \u00b6 2021-01-06 09:30:00+00:00 -0.971312 \u00b6 2021-01-07 09:30:00+00:00 0.866000 \u00b6 2021-01-08 09:30:00+00:00 3.081489 \u00b6 2021-01-11 09:30:00+00:00 0.687502 \u00b6 dtype: float64 \u00b6 ## \u65f6\u95f4\u533a\u95f4\u548c\u533a\u95f4\u7b97\u672f from datetime import datetime, timedelta import pandas as pd import numpy as np from pandas.tseries.offsets import Hour, Minute, Day, MonthEnd import pytz \u65f6\u95f4\u533a\u95f4\u8868\u793a\u7684\u662f\u65f6\u95f4\u8303\u56f4\u901a\u8fc7\u539f\u7d22\u5f151~202\uff0c\u628a`year`\u548c`quarter`\u8054\u5408\u8d77\u6765\uff0c\u751f\u6210\u65b0\u7d22\u5f15\uff0c\u5e76\u66ff\u6362\u539f\u7d22\u5f15\uff0c\u6bd4\u5982\u4e00\u4e9b\u5929\u3001\u4e00\u4e9b\u6708\u3001\u4e00\u4e9b\u5b63\u5ea6\u6216\u8005\u662f\u4e00\u4e9b\u5e74\u3002 `Period`\u7c7b\u8868\u793a\u7684\u6b63\u662f\u8fd9\u79cd\u6570\u636e\u7c7b\u578b\uff0c\u9700\u8981\u4e00\u4e2a\u5b57\u7b26\u4e32\u6216\u6570\u5b57\u4ee5\u53ca\u9891\u7387\u3002 \u5728\u8fd9\u4e2a\u4f8b\u5b50\u4e2d\uff0c`Period`\u5bf9\u8c61\u8868\u793a\u7684\u662f\u4ece2007\u5e741\u67081\u65e5\u52302007\u5e7412\u670831\u65e5\uff08\u5305\u542b\u5728\u5185\uff09\u7684\u65f6\u95f4\u6bb5\u3002 \u5728\u65f6\u95f4\u6bb5\u4e0a\u589e\u52a0\u6216\u51cf\u53bb\u6574\u6570\u53ef\u4ee5\u65b9\u4fbf\u5730\u6839\u636e\u5b83\u4eec\u7684\u9891\u7387\u8fdb\u884c\u79fb\u4f4d\u3002 p = pd.Period(2020, freq='A-DEC') print(p) 2020 \u00b6 print(p + 5) 2025 \u00b6 print(p - 5) 2015 \u00b6 \u5982\u679c\u4e24\u4e2a\u533a\u95f4\u62e5\u6709\u76f8\u540c\u7684\u9891\u7387\uff0c\u5219\u5b83\u4eec\u7684\u5dee\u662f\u5b83\u4eec\u4e4b\u95f4\u7684\u5355\u4f4d\u6570\u3002 p1 = pd.Period(2020, freq='A-DEC') p2 = pd.Period(2010, freq='A-DEC') print(p1 - p2) <10 * YearEnds: month=12> \u00b6 p1 = pd.Period(2020, freq='Q-DEC') p2 = pd.Period(2010, freq='Q-DEC') print(p1 - p2) <40 * QuarterEnds: startingMonth=12> \u00b6 \u4f7f\u7528`period_range`\u51fd\u6570\u53ef\u4ee5\u6784\u9020\u89c4\u5219\u533a\u95f4\u5e8f\u5217\u3002`PeriodIndex`\u7c7b\u5b58\u50a8\u7684\u662f\u533a\u95f4\u7684\u5e8f\u5217\uff0c\u53ef\u4ee5\u4f5c\u4e3a\u4efb\u610fpandas\u6570\u636e\u7ed3\u6784\u7684\u8f74\u7d22\u5f15\u3002 data = np.random.randn(6) strings = ['2021Q1', '2021Q2', '2021Q3', '2021Q4', '2022Q1', '2022Q2'] rng = pd.period_range('2001-1-1', '2001-6-30', freq='M') ts = pd.Series(data, index=rng) print(ts) 2001-01 -0.481408 \u00b6 2001-02 -0.297590 \u00b6 2001-03 -0.860354 \u00b6 2001-04 1.281540 \u00b6 2001-05 1.036551 \u00b6 2001-06 -0.522592 \u00b6 Freq: M, dtype: float64 \u00b6 rng = pd.PeriodIndex(strings, freq='Q-DEC') # \u5b57\u7b26\u4e32\u6570\u7ec4\u4e5f\u53ef\u4ee5\u4f7f\u7528PeriodIndex\u7c7b ts = pd.Series(data, index=rng) print(ts) 2021Q1 -2.077200 \u00b6 2021Q2 -0.948796 \u00b6 2021Q3 -1.104737 \u00b6 2021Q4 0.090281 \u00b6 2022Q1 0.431517 \u00b6 2022Q2 1.537045 \u00b6 Freq: Q-DEC, dtype: float64 \u00b6 ### \u533a\u95f4\u9891\u7387\u8f6c\u6362 \u4f7f\u7528`asfreq`\u53ef\u4ee5\u5c06\u533a\u95f4\u548c`PeriodIndex`\u5bf9\u8c61\u8f6c\u6362\u4e3a\u5176\u4ed6\u7684\u9891\u7387\u3002 \u4f8b\u5982\uff0c\u5047\u8bbe\u6211\u4eec\u6709\u4e00\u4e2a\u5e74\u5ea6\u533a\u95f4\uff0c\u5e76\u4e14\u60f3\u8981\u5728\u4e00\u5e74\u7684\u5f00\u59cb\u6216\u7ed3\u675f\u65f6\u5c06\u5176\u8f6c\u6362\u4e3a\u6708\u5ea6\u533a\u95f4\u3002 \u53ef\u4ee5\u5c06`Period('2020', 'A-DEC')`\u770b\u4f5c\u4e00\u6bb5\u65f6\u95f4\u4e2d\u7684\u4e00\u79cd\u6e38\u6807\uff0c\u5c06\u65f6\u95f4\u6309\u6708\u4efd\u5212\u5206\u3002 p = pd.Period(2020, freq='A-DEC') print(p.asfreq('M', how='start')) 2020-01 \u00b6 print(p.asfreq('M', how='end')) 2020-12 \u00b6 \u5982\u679c\u8d22\u5e74\u7ed3\u675f\u4e0d\u572812\u6708\uff0c\u5219\u6bcf\u6708\u5206\u671f\u4f1a\u81ea\u52a8\u8c03\u6574\u3002 \u6309\u5f53\u5e74\u8d22\u5e74\u7ed3\u675f\u8ba1\u7b97\uff0c\u8d77\u59cb\u5e74\u4efd\u5c31\u662f\u4e0a\u4e00\u5e74\u4e86\u3002 p = pd.Period(2020, freq='A-JUN') print(p.asfreq('M', how='start')) 2019-07 \u00b6 print(p.asfreq('M', how='end')) 2020-06 \u00b6 \u5f53\u4ece\u9ad8\u9891\u7387\u5411\u4f4e\u9891\u7387\u8f6c\u6362\u65f6\uff0cpandas\u6839\u636e\u5b50\u533a\u95f4\u7684\"\u6240\u5c5e\"\u6765\u51b3\u5b9a\u7236\u533a\u95f4\u3002 \u4f8b\u5982\uff0c\u5728A-JUN\u9891\u7387\u4e2d\uff0cAug-2020\u662f2020\u533a\u95f4\u7684\u4e00\u90e8\u5206\uff1a print(p.asfreq('A-JUN')) 2020\u901a\u8fc7\u539f\u7d22\u5f151~202\uff0c\u628a`year`\u548c`quarter`\u8054\u5408\u8d77\u6765\uff0c\u751f\u6210\u65b0\u7d22\u5f15\uff0c\u5e76\u66ff\u6362\u539f\u7d22\u5f15\u3002 \u5b8c\u6574\u7684`PeriodIndex`\u5bf9\u8c61\u6216\u65f6\u95f4\u5e8f\u5217\u53ef\u4ee5\u6309\u7167\u76f8\u540c\u7684\u8bed\u4e49\u8fdb\u884c\u8f6c\u6362\uff1a rng = pd.period_range('2018', '2021', freq='A-DEC') data = np.random.randn(len(rng)) ts = pd.Series(data, index=rng) print(ts) 2018 0.221634 \u00b6 2019 -0.392724 \u00b6 2020 -0.355022 \u00b6 2021 0.114000 \u00b6 Freq: A-DEC, dtype: float64 \u00b6 \u4e0b\u9762\u5e74\u5ea6\u533a\u95f4\u5c06\u901a\u8fc7`asfreq`\u88ab\u66ff\u6362\u4e3a\u5bf9\u5e94\u4e8e\u6bcf\u4e2a\u5e74\u5ea6\u533a\u95f4\u5185\u7684\u7b2c\u4e00\u4e2a\u6708\u7684\u6708\u5ea6\u533a\u95f4\u3002 print(ts.asfreq('M', how='start')) 2018-01 0.681874 \u00b6 2019-01 -1.006585 \u00b6 2020-01 -0.619142 \u00b6 2021-01 1.445820 \u00b6 Freq: M, dtype: float64 \u00b6 \u5982\u679c\u6211\u4eec\u60f3\u8981\u6bcf\u5e74\u6700\u540e\u4e00\u4e2a\u5de5\u4f5c\u65e5\uff0c\u6211\u4eec\u53ef\u4ee5\u4f7f\u7528`B`\u9891\u7387\u6765\u8868\u793a\u6211\u4eec\u60f3\u8981\u7684\u662f\u533a\u95f4\u7684\u672b\u7aef\u3002 print(ts.asfreq('B', how='end')) 2018-12-31 -1.520316 \u00b6 2019-12-31 -0.425544 \u00b6 2020-12-31 -0.658073 \u00b6 2021-12-31 1.206881 \u00b6 Freq: B, dtype: float64 \u00b6 ### \u5b63\u5ea6\u533a\u95f4\u9891\u7387 \u5b63\u5ea6\u6570\u636e\u662f\u4f1a\u8ba1\u3001\u91d1\u878d\u548c\u5176\u4ed6\u9886\u57df\u7684\u6807\u51c6\u3002 \u5f88\u591a\u5b63\u5ea6\u6570\u636e\u662f\u5728\u8d22\u5e74\u7ed3\u5c3e\u62a5\u544a\u7684\uff0c\u901a\u5e38\u662f\u4e00\u5e7412\u4e2a\u6708\u4e2d\u7684\u6700\u540e\u4e00\u4e2a\u65e5\u5386\u65e5\u6216\u5de5\u4f5c\u65e5\u3002 pandas\u652f\u6301\u6240\u6709\u7684\u53ef\u80fd\u768412\u4e2a\u5b63\u5ea6\u9891\u7387\u4eceQ-JAN\u5230Q-DEC\uff1a \u4e0b\u4f8b\u4e2d\uff0c\u8d22\u5e74\u7ed3\u675f\u4e8e1\u6708\uff0c2020Q4\u884c\u65f6\u95f4\u4e3a\u4e0a\u4e00\u5e7411\u6708\u81f3\u5f53\u5e741\u6708\u3002\u53ef\u4ee5\u901a\u8fc7\u8f6c\u6362\u4e3a\u6bcf\u65e5\u9891\u7387\uff08asfreq\uff09\u8fdb\u884c\u68c0\u67e5\u3002 p = pd.Period('2020Q4', freq='Q-JAN') print(p) 2020Q4 \u00b6 print(p.asfreq('D', 'start')) 2019-11-01 \u00b6 print(p.asfreq('D', 'end')) 2020-01-31 \u00b6 \u5047\u5982\u8d22\u5e74\u7ed3\u675f\u4e8e2\u6708\uff0c2020Q4\u884c\u65f6\u95f4\u4e3a\u4e0a\u4e00\u5e7412\u6708\u81f3\u5f53\u5e742\u6708\u3002 p = pd.Period('2020Q4', freq='Q-FEB') print(p) 2020Q4 \u00b6 print(p.asfreq('D', 'start')) 2019-11-01 \u00b6 print(p.asfreq('D', 'end')) 2020-01-31 \u00b6 \u5047\u5982\u8d22\u5e74\u7ed3\u675f\u4e8e4\u6708\uff0c2020Q4\u884c\u65f6\u95f4\u4e3a\u4e0a\u4e00\u5e7412\u6708\u81f3\u5f53\u5e742\u6708\u3002 p = pd.Period('2020Q4', freq='Q-APR') print(p) 2020Q4 \u00b6 print(p.asfreq('D', 'start')) 2020-02-01 \u00b6 print(p.asfreq('D', 'end')) 2020-04-30 \u00b6 \u53ef\u4ee5\u5bf9\u533a\u95f4\u6570\u636e\u505a\u7b97\u672f\u64cd\u4f5c\u3002\u4f8b\u5982\uff0c\u8981\u83b7\u53d6\u5728\u5b63\u5ea6\u5012\u6570\u7b2c\u4e8c\u4e2a\u5de5\u4f5c\u65e5\u4e0b\u53484\u70b9\u7684\u65f6\u95f4\u6233\uff0c\u53ef\u4ee5\u8fd9\u4e48\u505a\uff1a(\u7591\u95ee\uff1a\u8fd9\u91cc\u7684\u53c2\u6570e\u4ee3\u8868\u4ec0\u4e48 ???) p4pm = (p.asfreq('B', 'e') - 1).asfreq('T', 's') + 16 * 60 print(p4pm) 2020-04-29 16:00 \u00b6 print(p4pm.to_timestamp()) 2020-04-29 16:00:00 \u00b6 \u53ef\u4ee5\u4f7f\u7528`peroid_range`\u751f\u6210\u5b63\u5ea6\u5e8f\u5217\u3002\u5b83\u7684\u7b97\u672f\u4e5f\u662f\u4e00\u6837\u7684\uff1a rng = pd.period_range('2000Q3', '2001Q4', freq='Q-JAN') ts = pd.Series(np.arange(len(rng)), index=rng) print(ts) 2000Q3 0 \u00b6 2000Q4 1 \u00b6 2001Q1 2 \u00b6 2001Q2 3 \u00b6 2001Q3 4 \u00b6 2001Q4 5 \u00b6 Freq: Q-JAN, dtype: int64 \u00b6 new_rng = (rng.asfreq('B', 'e') - 1).asfreq('T', 's') + 16 * 60 ts.index = new_rng.to_timestamp() print(ts) 1999-10-28 16:00:00 0 \u00b6 2000-01-28 16:00:00 1 \u00b6 2000-04-27 16:00:00 2 \u00b6 2000-07-28 16:00:00 3 \u00b6 2000-10-30 16:00:00 4 \u00b6 2001-01-30 16:00:00 5 \u00b6 dtype: int64 \u00b6 ### \u5c06\u65f6\u95f4\u6233\u8f6c\u6362\u4e3a\u533a\u95f4\uff08\u4ee5\u53ca\u9006\u8f6c\u6362\uff09 \u901a\u8fc7\u65f6\u95f4\u6233\u7d22\u5f15\u7684Series\u548cDataFrame\u53ef\u4ee5\u88ab`to_period`\u65b9\u6cd5\u8f6c\u6362\u4e3a\u533a\u95f4\uff1a rng = pd.date_range('2020-01-01', periods=3, freq='M') ts = pd.Series(np.random.randn(3), index=rng) print(ts) 2020-01-31 -0.567097 \u00b6 2020-02-29 0.63452\u901a\u8fc7\u539f\u7d22\u5f151~202\uff0c\u628ayear\u548cquarter\u8054\u5408\u8d77\u6765\uff0c\u751f\u6210\u65b0\u7d22\u5f15\uff0c\u5e76\u66ff\u6362\u539f\u7d22\u5f152 \u00b6 2020-03-31 0.297777 \u00b6 Freq: M, dtype: float64 \u00b6 pts = ts.to_period() print(pts) 2020-01 -0.567097 \u00b6 2020-02 0.634522 \u00b6 2020-03 0.297777 \u00b6 Freq: M, dtype: float64 \u00b6 \u7531\u4e8e\u533a\u95f4\u662f\u975e\u91cd\u53e0\u65f6\u95f4\u8303\u56f4\uff0c\u4e00\u4e2a\u65f6\u95f4\u6233\u53ea\u80fd\u5c5e\u4e8e\u7ed9\u5b9a\u9891\u7387\u7684\u5355\u4e2a\u533a\u95f4\u3002 \u5c3d\u7ba1\u9ed8\u8ba4\u60c5\u51b5\u4e0b\u6839\u636e\u65f6\u95f4\u6233\u63a8\u65ad\u51fa\u65b0`PeriodIndex`\u7684\u9891\u7387\uff0c\u4f46\u53ef\u4ee5\u6307\u5b9a\u4efb\u4f55\u60f3\u8981\u7684\u9891\u7387\u3002 \u5728\u7ed3\u679c\u4e2d\u5305\u542b\u91cd\u590d\u7684\u533a\u95f4\u4e5f\u662f\u6ca1\u6709\u95ee\u9898\u7684\u3002 rng = pd.date_range('2020-01-01', periods=6, freq='D') ts = pd.Series(np.random.randn(6), index=rng) print(ts) 2020-01-01 -0.111287 \u00b6 2020-01-02 1.442234 \u00b6 2020-01-03 -0.767553 \u00b6 2020-01-04 -0.265064 \u00b6 2020-01-05 1.200312 \u00b6 2020-01-06 -1.782557 \u00b6 Freq: D, dtype: float64 \u00b6 ts_m = ts.to_period('M') # \u6307\u5b9aperiod\u7684\u9891\u7387\uff08M\uff09,\u8f93\u51fa\u7ed3\u679c\u5305\u542b\u91cd\u590dperiod print(ts_m) 2020-01 -0.111287 \u00b6 2020-01 1.442234 \u00b6 2020-01 -0.767553 \u00b6 2020-01 -0.265064 \u00b6 2020-01 1.200312 \u00b6 2020-01 -1.782557 \u00b6 Freq: M, dtype: float64 \u00b6 \u4f7f\u7528`to_timestamp`\u53ef\u4ee5\u5c06\u533a\u95f4\u518d\u8f6c\u6362\u4e3a\u65f6\u95f4\u6233\uff1a print(ts_m.to_timestamp(how='end')) 2020-01-31 23:59:59.999999999 -0.111287 \u00b6 2020-01-31 23:59:59.999999999 1.442234 \u00b6 2020-01-31 23:59:59.999999999 -0.767553 \u00b6 2020-01-31 23:59:59.999999999 -0.265064 \u00b6 2020-01-31 23:59:59.999999999 1.200312 \u00b6 2020-01-31 23:59:59.999999999 -1.782557 \u00b6 dtype: float64 \u00b6 print(ts_m.to_timestamp(how='start')) 2020-01-01 -0.111287 \u00b6 2020-01-01 1.442234 \u00b6 2020-01-01 -0.767553 \u00b6 2020-01-01 -0.265064 \u00b6 2020-01-01 1.200312 \u00b6 2020-01-01 -1.782557 \u00b6 dtype: float64 \u00b6 ### \u4ece\u6570\u7ec4\u751f\u6210PeriodIndex \u56fa\u5b9a\u9891\u7387\u6570\u636e\u96c6\u6709\u65f6\u5b58\u50a8\u5728\u8de8\u8d8a\u591a\u5217\u7684\u65f6\u95f4\u8303\u56f4\u4fe1\u606f\u4e2d\u3002\u4f8b\u5982\uff0c\u5728\u8fd9\u4e2a\u5b8f\u89c2\u7ecf\u6d4e\u6570\u636e\u96c6\u4e2d\uff0c\u5e74\u4efd\u548c\u5b63\u5ea6\u5728\u4e0d\u540c\u5217\u4e2d\uff1a data = pd.read_csv('../examples/macrodata.csv') print(data.head(5)) year quarter realgdp realcons ... unemp pop infl realint \u00b6 0 1959.0 1.0 2710.349 1707.4 ... 5.8 177.146 0.00 0.00 \u00b6 1 1959.0 2.0 2778.801 1733.7 ... 5.1 177.830 2.34 0.74 \u00b6 2 1959.0 3.0 2775.488 1751.8 ... 5.3 178.657 2.74 1.09 \u00b6 3 1959.0 4.0 2785.204 1753.7 ... 5.6 179.386 0.27 4.06 \u00b6 4 1960.0 1.0 2847.699 1770.5 ... 5.2 180.007 2.31 1.19 \u00b6 print(data.year) 0 1959.0 \u00b6 1 1959.0 \u00b6 2 1959.0 \u00b6 3 1959.0 \u00b6 4 1960.0 \u00b6 ... \u00b6 198 2008.0 \u00b6 199 2008.0 \u00b6 200 2009.0 \u00b6 201 2009.0 \u00b6 202 2009.0 \u00b6 Name: year, Length: 203, dtype: float64 \u00b6 print(data.quarter) 0 1.0 \u00b6 1 2.0 \u00b6 2 3.0 \u00b6 3 4.0 \u00b6 4 1.0 \u00b6 ... \u00b6 198 3.0 \u00b6 199 4.0 \u00b6 200 1.0 \u00b6 201 2.0 \u00b6 202 3.0 \u00b6 Name: quarter, Length: 203, dtype: float64 \u00b6 \u901a\u8fc7\u5c06\u8fd9\u4e9b\u6570\u7ec4\u548c\u9891\u7387\u4f20\u9012\u7ed9`PeriodIndex`\uff0c\u53ef\u4ee5\u8054\u5408\u5f62\u6210DataFrame\u7684\u7d22\u5f15 index = pd.PeriodIndex(year=data.year, quarter=data.quarter, freq='Q-DEC') print(index) PeriodIndex(['1959Q1', '1959Q2', '1959Q3', '1959Q4', '1960Q1', '1960Q2', \u00b6 '1960Q3', '1960Q4', '1961Q1', '1961Q2', \u00b6 ... \u00b6 '2007Q2', '2007Q3', '2007Q4', '2008Q1', '2008Q2', '2008Q3', \u00b6 '2008Q4', '2009Q1', '2009Q2', '2009Q3'], \u00b6 dtype='period[Q-DEC]', length=203) \u00b6 data.index = index # \u901a\u8fc7\u539f\u7d22\u5f151~202\uff0c\u628ayear\u548cquarter\u8054\u5408\u8d77\u6765\uff0c\u751f\u6210\u65b0\u7d22\u5f15\uff0c\u5e76\u66ff\u6362\u539f\u7d22\u5f15 print(data.infl) 1959Q1 0.00 \u00b6 1959Q2 2.34 \u00b6 1959Q3 2.74 \u00b6 1959Q4 0.27 \u00b6 1960Q1 2.31 \u00b6 ... \u00b6 2008Q3 -3.16 \u00b6 2008Q4 -8.79 \u00b6 2009Q1 0.94 \u00b6 2009Q2 3.37 \u00b6 2009Q3 3.56 \u00b6 Freq: Q-DEC, Name: infl, Length: 203, dtype: float64 \u00b6 ## \u91cd\u65b0\u91c7\u6837\u9891\u7387\u8f6c\u6362 import pandas as pd import numpy as np from pandas.tseries.frequencies import to_offset \u91cd\u65b0\u91c7\u6837\u662f\u6307\u5c06\u65f6\u95f4\u5e8f\u5217\u4ece\u4e00\u4e2a\u9891\u7387\u8f6c\u6362\u4e3a\u53e6\u4e00\u4e2a\u9891\u7387\u7684\u8fc7\u7a0b\u3002 \u5c06\u66f4\u9ad8\u9891\u7387\u7684\u6570\u636e\u805a\u5408\u5230\u4f4e\u9891\u7387\u88ab\u79f0\u4e3a\u5411\u4e0b\u91c7\u6837\uff0c\u800c\u4ece\u4f4e\u9891\u7387\u8f6c\u6362\u5230\u9ad8\u9891\u7387\u79f0\u4e3a\u5411\u4e0a\u91c7\u6837\u3002 \u5e76\u4e0d\u662f\u6240\u6709\u7684\u91cd\u65b0\u91c7\u6837\u90fd\u5c5e\u4e8e\u4e0a\u9762\u8bf4\u7684\u4e24\u7c7b\u3002\u4f8b\u5982\uff0c\u5c06W-WED\uff08weekly on Wednesday\uff0c\u6bcf\u5468\u4e09\uff09\u8f6c\u6362\u5230W-FRI\uff08\u6bcf\u5468\u4e94\uff09\u65e2\u4e0d\u662f\u5411\u4e0a\u91c7\u6837\u4e5f\u4e0d\u662f\u5411\u4e0b\u91c7\u6837\u3002 pandas\u5bf9\u8c61\u90fd\u914d\u6709`resample`\u65b9\u6cd5\uff0c\u8be5\u65b9\u6cd5\u662f\u6240\u6709\u9891\u7387\u8f6c\u6362\u7684\u5de5\u5177\u51fd\u6570\u3002`resample`\u62e5\u6709\u7c7b\u4f3c\u4e8e`groupby`\u7684API\uff1b\u8c03\u7528`resample`\u5bf9\u6570\u636e\u5206\u7ec4\uff0c\u4e4b\u540e\u518d\u8c03\u7528\u805a\u5408\u51fd\u6570\uff1a ### resample\u65b9\u6cd5\u53c2\u6570 \u53c2\u6570 * freq: \u8868\u793a\u91cd\u91c7\u6837\u9891\u7387\uff0c\u4f8b\u5982\u2018M'\u3001\u20185min'\uff0cSecond(15) * how='mean': \u7528\u4e8e\u4ea7\u751f\u805a\u5408\u503c\u7684\u51fd\u6570\u540d\u6216\u6570\u7ec4\u51fd\u6570\uff0c\u4f8b\u5982\u2018mean'\u3001\u2018ohlc'\u3001np.max\u7b49\uff0c\u9ed8\u8ba4\u662f\u2018mean'\uff0c\u5176\u4ed6\u5e38\u7528\u7684\u503c\u7531\uff1a\u2018first'\u3001\u2018last'\u3001\u2018median'\u3001\u2018max'\u3001\u2018min' * axis=0: \u9ed8\u8ba4\u662f\u7eb5\u8f74\uff0c\u6a2a\u8f74\u8bbe\u7f6eaxis=1 * fill_method = None: \u5347\u91c7\u6837\u65f6\u5982\u4f55\u63d2\u503c\uff0c\u6bd4\u5982\u2018ffill'\u3001\u2018bfill'\u7b49 * closed = \u2018right': \u5728\u964d\u91c7\u6837\u65f6\uff0c\u5404\u65f6\u95f4\u6bb5\u7684\u54ea\u4e00\u6bb5\u662f\u95ed\u5408\u7684\uff0c\u2018right'\u6216\u2018left'\uff0c\u9ed8\u8ba4\u2018right' * label= \u2018right': \u5728\u964d\u91c7\u6837\u65f6\uff0c\u5982\u4f55\u8bbe\u7f6e\u805a\u5408\u503c\u7684\u6807\u7b7e\uff0c\u4f8b\u5982\uff0c9\uff1a30-9\uff1a35\u4f1a\u88ab\u6807\u8bb0\u62109\uff1a30\u8fd8\u662f9\uff1a35,\u9ed8\u8ba49\uff1a35 * loffset = None: \u9762\u5143\u6807\u7b7e\u7684\u65f6\u95f4\u6821\u6b63\u503c\uff0c\u6bd4\u5982\u2018-1s'\u6216Second(-1)\u7528\u4e8e\u5c06\u805a\u5408\u6807\u7b7e\u8c03\u65e91\u79d2 * limit=None: \u5728\u5411\u524d\u6216\u5411\u540e\u586b\u5145\u65f6\uff0c\u5141\u8bb8\u586b\u5145\u7684\u6700\u5927\u65f6\u671f\u6570 * kind = None: \u805a\u5408\u5230\u65f6\u671f\uff08\u2018period'\uff09\u6216\u65f6\u95f4\u6233\uff08\u2018timestamp'\uff09\uff0c\u9ed8\u8ba4\u805a\u5408\u5230\u65f6\u95f4\u5e8f\u5217\u7684\u7d22\u5f15\u7c7b\u578b * convention = None: \u5f53\u91cd\u91c7\u6837\u65f6\u671f\u65f6\uff0c\u5c06\u4f4e\u9891\u7387\u8f6c\u6362\u5230\u9ad8\u9891\u7387\u6240\u91c7\u7528\u7684\u7ea6\u5b9a\uff08start\u6216end\uff09\u3002\u9ed8\u8ba4\u2018end' rng = pd.date_range('2020-1-1', periods=100, freq='D') ts = pd.Series(np.random.randn(len(rng)), index=rng) print(ts) 2020-01-01 0.802409 \u00b6 2020-01-02 -1.147130 \u00b6 2020-01-03 -1.076115 \u00b6 2020-01-04 -2.097443 \u00b6 2020-01-05 0.577671 \u00b6 ... \u00b6 2020-04-05 -0.110747 \u00b6 2020-04-06 0.132867 \u00b6 2020-04-07 -0.294061 \u00b6 2020-04-08 -0.246155 \u00b6 2020-04-09 0.927194 \u00b6 Freq: D, Length: 100, dtype: float64 \u00b6 print(ts.resample('M')) DatetimeIndexResampler [freq= , axis=0, closed=right, label=right, convention=start, origin=start_day] \u00b6 print(ts.resample('M').mean()) # \u628a100\u5929\u7684\u6570\u636e\u6309\u6708groupby\uff0c\u5e76\u8f93\u51fa\u6708\u672b\u6700\u540e\u4e00\u5929\uff0c\u8ba1\u7b97\u5e73\u5747\u503c 2020-01-31 -0.311714 \u00b6 2020-02-29 0.121526 \u00b6 2020-03-31 -0.051131 \u00b6 2020-04-30 -0.273113 \u00b6 Freq: M, dtype: float64 \u00b6 print(ts.resample('M', kind='period').mean()) # # \u628a100\u5929\u7684\u6570\u636e\u6309\u6708groupby\uff0c\u5e76\u8f93\u51fa\u6708\u4efd\uff08\u53c2\u6570period\uff09\uff0c\u8ba1\u7b97\u5e73\u5747\u503c 2020-01 -0.311714 \u00b6 2020-02 0.121526 \u00b6 2020-03 -0.051131 \u00b6 2020-04 -0.273113 \u00b6 Freq: M, dtype: float64 \u00b6 ### \u5411\u4e0b\u91c7\u6837 \u5c06\u6570\u636e\u805a\u5408\u5230\u4e00\u4e2a\u89c4\u5219\u7684\u4f4e\u9891\u7387\u4e0a\u662f\u4e00\u4e2a\u5e38\u89c1\u7684\u65f6\u95f4\u5e8f\u5217\u4efb\u52a1\u3002 \u8981\u805a\u5408\u7684\u6570\u636e\u4e0d\u5fc5\u662f\u56fa\u5b9a\u9891\u7387\u7684\u3002 \u671f\u671b\u7684\u9891\u7387\u5b9a\u4e49\u4e86\u7528\u4e8e\u5bf9\u65f6\u95f4\u5e8f\u5217\u5207\u7247\u4ee5\u805a\u5408\u7684\u7bb1\u4f53\u8fb9\u754c\u3002\u4f8b\u5982\uff0c\u8981\u5c06\u65f6\u95f4\u8f6c\u6362\u4e3a\u6bcf\u6708\uff0c`M`\u6216`BM`\uff0c\u5219\u9700\u8981\u5c06\u6570\u636e\u5206\u6210\u4e00\u4e2a\u6708\u7684\u65f6\u95f4\u95f4\u9694\u3002 \u6bcf\u4e2a\u95f4\u9694\u662f\u534a\u95ed\u5408\u7684\uff0c\u4e00\u4e2a\u6570\u636e\u70b9\u53ea\u80fd\u5c5e\u4e8e\u4e00\u4e2a\u65f6\u95f4\u95f4\u9694\uff0c\u65f6\u95f4\u95f4\u9694\u7684\u5e76\u96c6\u5fc5\u987b\u662f\u6574\u4e2a\u65f6\u95f4\u5e27\u3002 \u5728\u4f7f\u7528resample\u8fdb\u884c\u5411\u4e0b\u91c7\u6837\u6570\u636e\u65f6\u6709\u4e9b\u4e8b\u60c5\u9700\u8981\u8003\u8651\uff1a * \u6bcf\u6bb5\u95f4\u9694\u7684\u54ea\u4e00\u8fb9\u662f\u95ed\u5408\u7684\u3002 * \u5982\u4f55\u5728\u95f4\u9694\u7684\u8d77\u59cb\u6216\u7ed3\u675f\u4f4d\u7f6e\u6807\u8bb0\u6bcf\u4e2a\u5df2\u805a\u5408\u7684\u7bb1\u4f53\u3002 rng = pd.date_range('2020-1-1', periods=12, freq='T') ts = pd.Series(np.arange(12), index=rng) print(ts) 2020-01-01 00:00:00 0 \u00b6 2020-01-01 00:01:00 1 \u00b6 2020-01-01 00:02:00 2 \u00b6 2020-01-01 00:03:00 3 \u00b6 2020-01-01 00:04:00 4 \u00b6 2020-01-01 00:05:00 5 \u00b6 2020-01-01 00:06:00 6 \u00b6 2020-01-01 00:07:00 7 \u00b6 2020-01-01 00:08:00 8 \u00b6 2020-01-01 00:09:00 9 \u00b6 2020-01-01 00:10:00 10 \u00b6 2020-01-01 00:11:00 11 \u00b6 Freq: T, dtype: int64 \u00b6 \u6309\u4e94\u5206\u949f\u9891\u7387\u805a\u5408\u5206\u7ec4\uff0c\u8ba1\u7b97\u6bcf\u4e00\u7ec4\u7684\u52a0\u548c\u3002\u9891\u7387\u6309\u4e94\u5206\u949f\u7684\u589e\u91cf\u5b9a\u4e49\u4e86\u7bb1\u4f53\u8fb9\u754c\u3002 \u9ed8\u8ba4\u60c5\u51b5\u4e0b\uff0c\u5de6\u7bb1\u4f53\u8fb9\u754c\u662f\u5305\u542b\u7684\uff0c\u56e0\u6b6400:00\u7684\u503c\u662f\u5305\u542b\u572800:00\u523000:05\u95f4\u9694\u5185\u7684\u3002 \u4f20\u9012`closed='right'`\u5c06\u95f4\u9694\u7684\u95ed\u5408\u7aef\u6539\u4e3a\u4e86\u53f3\u8fb9\u3002 \u5206\u7ec4\uff1a * left: [00:00,00:01,00:02,00:03,00:04],[00:05,00:06,00:07,00:08,00:09],[00:10,00:11] * right:[00:00],[00:01,00:02,00:03,00:04,00:05],[00:06,00:07,00:08,00:09,00:10],[00:11] result = ts.resample('5min', closed='right').sum() print(result) 2019-12-31 23:55:00 0 \u00b6 2020-01-01 00:00:00 15 \u00b6 2020-01-01 00:05:00 40 \u00b6 2020-01-01 00:10:00 11 \u00b6 Freq: 5T, dtype: int64 \u00b6 result = ts.resample('5min', closed='left').sum() print(result) 2020-01-01 00:00:00 10 \u00b6 2020-01-01 00:05:00 35 \u00b6 2020-01-01 00:10:00 21 \u00b6 Freq: 5T, dtype: int64 \u00b6 \u6700\u540e\uff0c\u5c06\u7ed3\u679c\u7d22\u5f15\u79fb\u52a8\u4e00\u5b9a\u7684\u6570\u91cf\uff0c\u4f8b\u5982\u4ece\u53f3\u8fb9\u7f18\u51cf\u53bb\u4e00\u79d2\uff0c\u4ee5\u4f7f\u5176\u66f4\u6e05\u695a\u5730\u8868\u660e\u65f6\u95f4\u6233\u6240\u6307\u7684\u95f4\u9694\u3002 \u8981\u5b9e\u73b0\u8fd9\u4e2a\u529f\u80fd\uff0c\u5411`loffset`\u4f20\u9012\u5b57\u7b26\u4e32\u6216\u65e5\u671f\u504f\u7f6e\uff1a result = ts.resample('5min', closed='right', label='right', loffset='-1s').sum() print(result) 2019-12-31 23:59:59 0 \u00b6 2020-01-01 00:04:59 15 \u00b6 2020-01-01 00:09:59 40 \u00b6 2020-01-01 00:14:59 11 \u00b6 Freq: 5T, dtype: int64 \u00b6 FutureWarning: 'loffset' in .resample() and in Grouper() is deprecated. \u00b6 >>> df.resample(freq=\"3s\", loffset=\"8H\") \u00b6 becomes: \u00b6 >>> from pandas.tseries.frequencies import to_offset \u00b6 >>> df = df.resample(freq=\"3s\").mean() \u00b6 >>> df.index = df.index.to_timestamp() + to_offset(\"8H\") \u00b6 #### \u5f00\u7aef-\u5cf0\u503c-\u8c37\u503c-\u7ed3\u675f\uff08OHLC\uff09\u91cd\u65b0\u91c7\u6837 \u5728\u91d1\u878d\u4e2d\uff0c\u4e3a\u6bcf\u4e2a\u6570\u636e\u6876\u8ba1\u7b97\u56db\u4e2a\u503c\u662f\u4e00\u79cd\u6d41\u884c\u7684\u65f6\u95f4\u5e8f\u5217\u805a\u5408\u65b9\u6cd5\uff1a\u7b2c\u4e00\u4e2a\u503c\uff08\u5f00\u7aef\uff09\u3001\u6700\u540e\u4e00\u4e2a\u503c\uff08\u7ed3\u675f\uff09\u3001\u6700\u5927\u503c\uff08\u5cf0\u503c\uff09\u548c\u6700\u5c0f\u503c\uff08\u8c37\u503c\uff09\u3002 \u901a\u8fc7\u4f7f\u7528`ohlc`\u805a\u5408\u51fd\u6570\u53d6\u5f97\u5305\u542b\u56db\u79cd\u805a\u5408\u503c\u5217\u7684DataFrame\uff0c\u8fd9\u4e9b\u503c\u5728\u6570\u636e\u7684\u5355\u6b21\u626b\u63cf\u4e2d\u88ab\u9ad8\u6548\u8ba1\u7b97\uff1a result = ts.resample('5min').ohlc() print(result) open high low close \u00b6 2020-01-01 00:00:00 0 4 0 4 \u00b6 2020-01-01 00:05:00 5 9 5 9 \u00b6 2020-01-01 00:10:00 10 11 10 11 \u00b6 ### \u5411\u4e0a\u91c7\u6837\u4e0e\u63d2\u503c \u5f53\u4ece\u4f4e\u9891\u7387\u8f6c\u6362\u4e3a\u9ad8\u9891\u7387\u65f6\uff0c\u5e76\u4e0d\u9700\u8981\u4efb\u4f55\u805a\u5408\u3002 df = pd.DataFrame( np.random.randn(2, 4), index=pd.date_range('2020/1/1', periods=2, freq='W-WED'), columns=['Colorado', 'Texas', 'New York', 'Ohio'] ) print(df) Colorado Texas New York Ohio \u00b6 2020-01-01 -0.228758 -0.758718 -0.025410 -1.001819 \u00b6 2020-01-08 -0.704541 -0.261414 -0.863335 0.267101 \u00b6 df_daily = df.resample('W-WED').sum() print(df_daily) Colorado Texas New York Ohio \u00b6 2020-01-01 -0.228758 -0.758718 -0.025410 -1.001819 \u00b6 2020-01-08 -0.704541 -0.261414 -0.863335 0.267101 \u00b6 df_daily = df.resample('D').sum() print(df_daily) Colorado Texas New York Ohio \u00b6 2020-01-01 -0.228758 -0.758718 -0.025410 -1.001819 \u00b6 2020-01-02 0.000000 0.000000 0.000000 0.000000 \u00b6 2020-01-03 0.000000 0.000000 0.000000 0.000000 \u00b6 2020-01-04 0.000000 0.000000 0.000000 0.000000 \u00b6 2020-01-05 0.000000 0.000000 0.000000 0.000000 \u00b6 2020-01-06 0.000000 0.000000 0.000000 0.000000 \u00b6 2020-01-07 0.000000 0.000000 0.000000 0.000000 \u00b6 2020-01-08 -0.704541 -0.261414 -0.863335 0.267101 \u00b6 \u5f53\u5bf9\u8fd9\u4e9b\u6570\u636e\u4f7f\u7528\u805a\u5408\u51fd\u6570\u65f6\uff0c\u6bcf\u4e00\u7ec4\u53ea\u6709\u4e00\u4e2a\u503c\uff0c\u5e76\u4e14\u4f1a\u5728\u95f4\u9699\u4e2d\u4ea7\u751f\u7f3a\u5931\u503c\u3002 \u4f7f\u7528`asfreq`\u65b9\u6cd5\u5728\u4e0d\u805a\u5408\u7684\u60c5\u51b5\u4e0b\u8f6c\u6362\u5230\u9ad8\u9891\u7387\uff1a df_daily = df.resample('D').asfreq() print(df_daily) Colorado Texas New York Ohio \u00b6 2020-01-01 -0.228758 -0.758718 -0.025410 -1.001819 \u00b6 2020-01-02 NaN NaN NaN NaN \u00b6 2020-01-03 NaN NaN NaN NaN \u00b6 2020-01-04 NaN NaN NaN NaN \u00b6 2020-01-05 NaN NaN NaN NaN \u00b6 2020-01-06 NaN NaN NaN NaN \u00b6 2020-01-07 NaN NaN NaN NaN \u00b6 2020-01-08 -0.704541 -0.261414 -0.863335 0.267101 \u00b6 \u5728\u975e\u661f\u671f\u4e09\u7684\u65e5\u671f\u4e0a\u5411\u524d\u586b\u5145\u6bcf\u5468\u6570\u503c\u3002`fillna`\u548c`reindex`\u65b9\u6cd5\u4e2d\u53ef\u7528\u7684\u586b\u5145\u6216\u63d2\u503c\u65b9\u6cd5\u53ef\u7528\u4e8e\u91cd\u91c7\u6837\uff1a df_daily = df.resample('D').ffill() print(df_daily) Colorado Texas New York Ohio \u00b6 2020-01-01 -0.228758 -0.758718 -0.025410 -1.001819 \u00b6 2020-01-02 -0.228758 -0.758718 -0.025410 -1.001819 \u00b6 2020-01-03 -0.228758 -0.758718 -0.025410 -1.001819 \u00b6 2020-01-04 -0.228758 -0.758718 -0.025410 -1.001819 \u00b6 2020-01-05 -0.228758 -0.758718 -0.025410 -1.001819 \u00b6 2020-01-06 -0.228758 -0.758718 -0.025410 -1.001819 \u00b6 2020-01-07 -0.228758 -0.758718 -0.025410 -1.001819 \u00b6 2020-01-08 -0.704541 -0.261414 -0.863335 0.267101 \u00b6 \u53ef\u4ee5\u540c\u6837\u9009\u62e9\u4ec5\u5411\u524d\u586b\u5145\u4e00\u5b9a\u6570\u91cf\u7684\u533a\u95f4\uff0c\u4ee5\u9650\u5236\u7ee7\u7eed\u4f7f\u7528\u89c2\u6d4b\u503c\u7684\u65f6\u8ddd\uff1a df_daily = df.resample('D').ffill(limit=2) print(df_daily) Colorado Texas New York Ohio \u00b6 2020-01-01 -0.228758 -0.758718 -0.025410 -1.001819 \u00b6 2020-01-02 -0.228758 -0.758718 -0.025410 -1.001819 \u00b6 2020-01-03 -0.228758 -0.758718 -0.025410 -1.001819 \u00b6 2020-01-04 NaN NaN NaN NaN \u00b6 2020-01-05 NaN NaN NaN NaN \u00b6 2020-01-06 NaN NaN NaN NaN \u00b6 2020-01-07 NaN NaN NaN NaN \u00b6 2020-01-08 -0.704541 -0.261414 -0.863335 0.267101 \u00b6 \u6ce8\u610f\uff0c\u65b0\u7684\u65e5\u671f\u7d22\u5f15\u4e0d\u9700\u8981\u4e0e\u65e7\u7684\u7d22\u5f15\u91cd\u53e0\uff0c\u548c\u539f\u6765`df`\u7684\u503c\u4e00\u6837\uff0c\u53ea\u662f\u65e5\u671f\u7d22\u5f15\u53d8\u4e86\u3002 df_new = df.resample('W-THU').ffill() print(df_new) Colorado Texas New York Ohio \u00b6 2020-01-02 -0.228758 -0.758718 -0.025410 -1.001819 \u00b6 2020-01-09 -0.704541 -0.261414 -0.863335 0.267101 \u00b6 ### \u4f7f\u7528\u533a\u95f4\u8fdb\u884c\u91cd\u65b0\u91c7\u6837 \u5bf9\u4ee5\u533a\u95f4\u4e3a\u7d22\u5f15\u7684\u6570\u636e\u8fdb\u884c\u91c7\u6837\u4e0e\u65f6\u95f4\u6233\u7684\u60c5\u51b5\u7c7b\u4f3c\uff1a df = pd.DataFrame( np.random.randn(24, 4), index=pd.period_range('2020-1', periods=24, freq='M'), columns=['Colorado', 'Texas', 'New York', 'Ohio'] ) print(df) 2020-01 0.721395 -1.492674 0.707410 1.641890 \u00b6 2020-02 -0.894880 0.032823 -0.676158 0.029203 \u00b6 2020-03 2.147365 -0.176796 0.562695 -0.747656 \u00b6 2020-04 1.496037 -0.797119 -0.495601 0.774147 \u00b6 2020-05 -0.309839 0.502563 0.237244 0.910624 \u00b6 2020-06 1.231869 -0.105227 1.315759 0.217701 \u00b6 2020-07 1.447419 0.263876 -0.342045 -0.768907 \u00b6 2020-08 -2.567162 -1.008827 0.391085 1.259560 \u00b6 2020-09 -0.772501 1.183532 0.450374 0.450714 \u00b6 2020-10 0.228974 0.461224 1.393178 0.175243 \u00b6 2020-11 -0.725193 -1.544131 1.372029 -0.659224 \u00b6 2020-12 0.718195 0.862024 -0.166460 -0.940191 \u00b6 2021-01 -0.617054 -0.887312 0.338451 -1.392838 \u00b6 2021-02 -0.081140 0.634730 -0.868051 -1.277167 \u00b6 2021-03 -0.999642 -1.959715 -0.930662 0.748687 \u00b6 2021-04 1.851453 1.561669 -0.688822 -0.371255 \u00b6 2021-05 -0.540777 -0.890403 -1.204188 0.243480 \u00b6 2021-06 1.318905 1.247457 0.518969 0.799793 \u00b6 2021-07 0.223238 0.747177 -0.410889 0.904593 \u00b6 2021-08 -0.652551 -0.254351 -0.464604 -0.676923 \u00b6 2021-09 0.562312 0.182099 0.018617 0.573331 \u00b6 2021-10 0.429490 -0.045959 -0.356292 -0.295776 \u00b6 2021-11 2.552155 0.801299 1.378421 1.232792 \u00b6 2021-12 1.102288 0.850280 -0.767015 -0.519840 \u00b6 df_annual = df.resample('A-DEC').mean() print(df_annual) Colorado Texas New York Ohio \u00b6 2020 0.226807 -0.151561 0.395793 0.195259 \u00b6 2021 0.429056 0.165581 -0.286339 -0.002594 \u00b6 \u5411\u4e0a\u91c7\u6837\u66f4\u4e3a\u7ec6\u81f4\uff0c\u56e0\u4e3a\u5fc5\u987b\u5728\u91cd\u65b0\u91c7\u6837\u524d\u51b3\u5b9a\u65b0\u9891\u7387\u4e2d\u5728\u65f6\u95f4\u6bb5\u7684\u54ea\u4e00\u7aef\u653e\u7f6e\u6570\u503c\uff0c\u5c31\u50cfasfreq\u65b9\u6cd5\u4e00\u6837\u3002 `convention`\u53c2\u6570\u9ed8\u8ba4\u503c\u662f`start`\uff0c\u4f46\u4e5f\u53ef\u4ee5\u662f`end`\uff1a result = df_annual.resample('Q-DEC').ffill() print(result) Colorado Texas New York Ohio \u00b6 2020Q1 0.226807 -0.151561 0.395793 0.195259 \u00b6 2020Q2 0.226807 -0.151561 0.395793 0.195259 \u00b6 2020Q3 0.226807 -0.151561 0.395793 0.195259 \u00b6 2020Q4 0.226807 -0.151561 0.395793 0.195259 \u00b6 2021Q1 0.429056 0.165581 -0.286339 -0.002594 \u00b6 2021Q2 0.429056 0.165581 -0.286339 -0.002594 \u00b6 2021Q3 0.429056 0.165581 -0.286339 -0.002594 \u00b6 2021Q4 0.429056 0.165581 -0.286339 -0.002594 \u00b6 result = df_annual.resample('Q-DEC', convention='end').ffill() print(result) Colorado Texas New York Ohio \u00b6 2020Q4 0.226807 -0.151561 0.395793 0.195259 \u00b6 2021Q1 0.226807 -0.151561 0.395793 0.195259 \u00b6 2021Q2 0.226807 -0.151561 0.395793 0.195259 \u00b6 2021Q3 0.226807 -0.151561 0.395793 0.195259 \u00b6 2021Q4 0.429056 0.165581 -0.286339 -0.002594 \u00b6 \u7531\u4e8e\u533a\u95f4\u6d89\u53ca\u65f6\u95f4\u8303\u56f4\uff0c\u5411\u4e0a\u91c7\u6837\u548c\u5411\u4e0b\u91c7\u6837\u5c31\u66f4\u4e3a\u4e25\u683c\uff1a * \u5728\u5411\u4e0b\u91c7\u6837\u4e2d\uff0c\u76ee\u6807\u9891\u7387\u5fc5\u987b\u662f\u539f\u9891\u7387\u7684\u5b50\u533a\u95f4\u3002 * \u5728\u5411\u4e0a\u91c7\u6837\u4e2d\uff0c\u76ee\u6807\u9891\u7387\u5fc5\u987b\u662f\u539f\u9891\u7387\u7684\u7236\u533a\u95f4\u3002 \u5982\u679c\u4e0d\u6ee1\u8db3\u8fd9\u4e9b\u89c4\u5219\uff0c\u5c06\u4f1a\u5f15\u8d77\u5f02\u5e38\u3002\u8fd9\u4e3b\u8981\u4f1a\u5f71\u54cd\u6bcf\u5b63\u5ea6\u3001\u6bcf\u5e74\u548c\u6bcf\u5468\u7684\u9891\u7387\u3002 \u4f8b\u5982\uff0c\u6839\u636eQ-MAR\u5b9a\u4e49\u7684\u65f6\u95f4\u8303\u56f4\u5c06\u53ea\u548cA-MAR\u3001A-JUN\u3001A-SEP\u548cA-DEC\u4fdd\u6301\u4e00\u81f4\uff1a result = df_annual.resample('Q-MAR').ffill() print(result) Colorado Texas New York Ohio \u00b6 2020Q4 0.226807 -0.151561 0.395793 0.195259 \u00b6 2021Q1 0.226807 -0.151561 0.395793 0.195259 \u00b6 2021Q2 0.226807 -0.151561 0.395793 0.195259 \u00b6 2021Q3 0.226807 -0.151561 0.395793 0.195259 \u00b6 2021Q4 0.429056 0.165581 -0.286339 -0.002594 \u00b6 2022Q1 0.429056 0.165581 -0.286339 -0.002594 \u00b6 2022Q2 0.429056 0.165581 -0.286339 -0.002594 \u00b6 2022Q3 0.429056 0.165581 -0.286339 -0.002594 \u00b6 ## \u79fb\u52a8\u7a97\u53e3\u51fd\u6570 \u7edf\u8ba1\u90a3\u4e9b\u901a\u8fc7\u79fb\u52a8\u7a97\u53e3\u6216\u6307\u6570\u8870\u51cf\u800c\u8fd0\u884c\u7684\u51fd\u6570\uff0c\u662f\u7528\u4e8e\u65f6\u95f4\u5e8f\u5217\u64cd\u4f5c\u7684\u6570\u7ec4\u53d8\u6362\u7684\u4e00\u4e2a\u91cd\u8981\u7c7b\u522b\u3002 \u8fd9\u5bf9\u5e73\u6ed1\u566a\u58f0\u6216\u7c97\u7cd9\u7684\u6570\u636e\u975e\u5e38\u6709\u7528\u3002\u79f0\u8fd9\u4e9b\u51fd\u6570\u4e3a\u79fb\u52a8\u7a97\u53e3\u51fd\u6570\uff0c\u5c3d\u7ba1\u5b83\u4e5f\u5305\u542b\u4e86\u4e00\u4e9b\u6ca1\u6709\u56fa\u5b9a\u957f\u5ea6\u7a97\u53e3\u7684\u51fd\u6570\uff0c\u6bd4\u5982\u6307\u6570\u52a0\u6743\u79fb\u52a8\u5e73\u5747\u3002 \u4e0e\u5176\u4ed6\u7684\u7edf\u8ba1\u51fd\u6570\u7c7b\u4f3c\uff0c\u8fd9\u4e9b\u51fd\u6570\u4f1a\u81ea\u52a8\u6392\u9664\u7f3a\u5931\u6570\u636e\u3002 import matplotlib.pyplot as plt import pandas as pd from scipy.stats import percentileofscore import numpy as np from pandas.tseries.offsets import Hour, Minute, Day, MonthEnd import pytz \u5728\u6df1\u5165\u4e86\u89e3\u4e4b\u524d\uff0c\u6211\u4eec\u53ef\u4ee5\u5148\u8f7d\u5165\u4e00\u4e9b\u65f6\u95f4\u5e8f\u5217\u6570\u636e\u5e76\u6309\u7167\u5de5\u4f5c\u65e5\u9891\u7387\u8fdb\u884c\u91cd\u65b0\u91c7\u6837\uff1a close_px_all = pd.read_csv( '../examples/stock_px_2.csv', parse_dates = True, index_col=0 ) print(close_px_all.head(5)) AAPL MSFT XOM SPX \u00b6 2003-01-02 7.40 21.11 29.22 909.03 \u00b6 2003-01-03 7.45 21.14 29.24 908.59 \u00b6 2003-01-06 7.45 21.52 29.96 929.01 \u00b6 2003-01-07 7.43 21.93 28.95 922.93 \u00b6 2003-01-08 7.28 21.31 28.83 909.93 \u00b6 close_px = close_px_all[ ['AAPL', 'MSFT', 'XOM'] ] close_px = close_px.resample('B').ffill() print(close_px) AAPL MSFT XOM \u00b6 2003-01-02 7.40 21.11 29.22 \u00b6 2003-01-03 7.45 21.14 29.24 \u00b6 ... ... ... ... \u00b6 2011-10-13 408.43 27.18 76.37 \u00b6 2011-10-14 422.00 27.27 78.11 \u00b6 [2292 rows x 3 columns] \u00b6 `rolling`\u7b97\u5b50\uff0c\u5b83\u7684\u884c\u4e3a\u4e0e`resample`\u548c`groupby`\u7c7b\u4f3c\u3002 `rolling`\u53ef\u4ee5\u5728Series\u6216DataFrame\u4e0a\u901a\u8fc7\u4e00\u4e2awindow\uff08\u4ee5\u4e00\u4e2a\u533a\u95f4\u7684\u6570\u5b57\u6765\u8868\u793a\uff09\u8fdb\u884c\u8c03\u7528\u3002 close_px.AAPL.plot() \u8868\u8fbe\u5f0f`rolling(250)`\u4e0e`groupby`\u7684\u884c\u4e3a\u7c7b\u4f3c\uff0c\u4f46\u662f\u5b83\u521b\u5efa\u7684\u5bf9\u8c61\u662f\u6839\u636e250\u65e5\u6ed1\u52a8\u7a97\u53e3\u5206\u7ec4\u7684\u800c\u4e0d\u662f\u76f4\u63a5\u5206\u7ec4\u3002 \u56e0\u6b64\u8fd9\u91cc\u6211\u4eec\u83b7\u5f97\u4e86\u82f9\u679c\u516c\u53f8\u80a1\u7968\u4ef7\u683c\u7684250\u65e5\u79fb\u52a8\u7a97\u53e3\u5e73\u5747\u503c\u3002 close_px.AAPL.rolling(250).mean().plot() plt.show() \u9ed8\u8ba4\u60c5\u51b5\u4e0b\uff0c\u6eda\u52a8\u51fd\u6570\u9700\u8981\u7a97\u53e3\u4e2d\u6240\u6709\u7684\u503c\u5fc5\u987b\u662f\u975e`NA`\u503c\u3002 \u7531\u4e8e\u5b58\u5728\u7f3a\u5931\u503c\u8fd9\u79cd\u884c\u4e3a\u4f1a\u53d1\u751f\u6539\u53d8\uff0c\u5c24\u5176\u662f\u5728\u65f6\u95f4\u5e8f\u5217\u7684\u8d77\u59cb\u4f4d\u7f6e\u4f60\u62e5\u6709\u7684\u6570\u636e\u662f\u5c11\u4e8e\u7a97\u53e3\u533a\u95f4\u7684 apple_std250 = close_px.AAPL.rolling(250, min_periods=10).std() # \u82f9\u679c\u516c\u53f8250\u65e5\u6bcf\u65e5\u8fd4\u56de\u6807\u51c6\u5dee print(apple_std250[5:12]) 2003-01-09 NaN \u00b6 2003-01-10 NaN \u00b6 2003-01-13 NaN \u00b6 2003-01-14 NaN \u00b6 2003-01-15 0.077496 \u00b6 2003-01-16 0.074760 \u00b6 2003-01-17 0.112368 \u00b6 Freq: B, Name: AAPL, dtype: float64 \u00b6 apple_std250.plot() plt.show() expanding_mean = apple_std250.expanding().mean() print(expanding_mean[5:12]) 2003-01-09 NaN \u00b6 2003-01-10 NaN \u00b6 2003-01-13 NaN \u00b6 2003-01-14 NaN \u00b6 2003-01-15 0.077496 \u00b6 2003-01-16 0.076128 \u00b6 2003-01-17 0.088208 \u00b6 Freq: B, Name: AAPL, dtype: float64 \u00b6 expanding_mean.plot() plt.show() \u5728DataFrame\u4e0a\u8c03\u7528\u4e00\u4e2a\u79fb\u52a8\u7a97\u53e3\u51fd\u6570\u4f1a\u5c06\u53d8\u6362\u5e94\u7528\u5230\u6bcf\u4e00\u5217\u4e0a: close_px.rolling(60).mean().plot(logy=True) # \u80a1\u7968\u4ef7\u683c60\u65e5MA\uff08Y\u8f74\u53d6\u5bf9\u6570\uff09 plt.show() `rolling`\u51fd\u6570\u4e5f\u63a5\u6536\u8868\u793a\u56fa\u5b9a\u5927\u5c0f\u7684\u65f6\u95f4\u504f\u7f6e\u5b57\u7b26\u4e32\uff0c\u800c\u4e0d\u53ea\u662f\u4e00\u4e2a\u533a\u95f4\u7684\u96c6\u5408\u6570\u5b57\u3002 \u5bf9\u4e0d\u89c4\u5219\u65f6\u95f4\u5e8f\u5217\u4f7f\u7528\u6ce8\u91ca\u975e\u5e38\u6709\u7528\u3002\u8fd9\u4e9b\u5b57\u7b26\u4e32\u53ef\u4ee5\u4f20\u9012\u7ed9`resample`\u3002 \u4f8b\u5982\uff0c\u6211\u4eec\u53ef\u4ee5\u50cf\u8fd9\u6837\u8ba1\u7b9720\u5929\u7684\u6eda\u52a8\u5e73\u5747\u503c\uff1a result = close_px.rolling('20D').mean() print(result) AAPL MSFT XOM \u00b6 2003-01-02 7.400000 21.110000 29.220000 \u00b6 ... ... ... ... \u00b6 2011-10-14 391.038000 26.048667 74.185333 \u00b6 [2292 rows x 3 columns] \u00b6 result.plot() plt.show() ### \u6307\u6570\u52a0\u6743\u51fd\u6570 \u6307\u5b9a\u4e00\u4e2a\u5e38\u6570\u8870\u51cf\u56e0\u5b50\u4ee5\u5411\u66f4\u591a\u8fd1\u671f\u89c2\u6d4b\u503c\u63d0\u4f9b\u66f4\u591a\u6743\u91cd\uff0c\u53ef\u4ee5\u66ff\u4ee3\u4f7f\u7528\u5177\u6709\u76f8\u7b49\u52a0\u6743\u89c2\u5bdf\u503c\u7684\u9759\u6001\u7a97\u53e3\u5c3a\u5bf8\u7684\u65b9\u6cd5\u3002 \u6709\u591a\u79cd\u65b9\u5f0f\u53ef\u4ee5\u6307\u5b9a\u8870\u51cf\u56e0\u5b50\u3002\u5176\u4e2d\u4e00\u79cd\u6d41\u884c\u7684\u65b9\u5f0f\u662f\u4f7f\u7528\u4e00\u4e2aspan\uff08\u8de8\u5ea6\uff09\uff0c\u8fd9\u4f7f\u5f97\u7ed3\u679c\u4e0e\u7a97\u53e3\u5927\u5c0f\u7b49\u4e8e\u8de8\u5ea6\u7684\u7b80\u5355\u79fb\u52a8\u7a97\u53e3\u51fd\u6570\u3002 \u7531\u4e8e\u6307\u6570\u52a0\u6743\u7edf\u8ba1\u503c\u7ed9\u66f4\u8fd1\u671f\u7684\u89c2\u6d4b\u503c\u4ee5\u66f4\u591a\u7684\u6743\u91cd\uff0c\u4e0e\u7b49\u6743\u91cd\u7684\u7248\u672c\u76f8\u6bd4\uff0c\u5b83\u5bf9\u53d8\u5316\u201c\u9002\u5e94\u201d\u5f97\u66f4\u5feb\u3002 pandas\u62e5\u6709`ewm`\u7b97\u5b50\uff0c\u540c`rolling`\u3001`expanding`\u7b97\u5b50\u4e00\u8d77\u4f7f\u7528\u3002 \u4ee5\u4e0b\u662f\u5c06\u82f9\u679c\u516c\u53f8\u80a1\u7968\u4ef7\u683c\u768460\u65e5\u5747\u7ebf\u4e0e`span=60`\u7684EW\u79fb\u52a8\u5e73\u5747\u7ebf\u8fdb\u884c\u6bd4\u8f83\u7684\u4f8b\u5b50\uff1a aapl_ex = close_px.AAPL['2006':'2007'] ma60 = aapl_ex.rolling(30, min_periods=20).mean() ewma60 = aapl_ex.ewm(span=30).mean() ma60.plot(style='k--', label='Simple MA') ewma60.plot(style='k-', label='EWMA') plt.legend() plt.show() ### \u4e8c\u5143\u79fb\u52a8\u7a97\u53e3\u51fd\u6570 \u4e00\u4e9b\u7edf\u8ba1\u7b97\u5b50\uff0c\u4f8b\u5982\u76f8\u5173\u5ea6\u548c\u534f\u65b9\u5dee\uff0c\u9700\u8981\u64cd\u4f5c\u4e24\u4e2a\u65f6\u95f4\u5e8f\u5217\u3002 \u4f8b\u5982\uff0c\u91d1\u878d\u5206\u6790\u5e08\u7ecf\u5e38\u5bf9\u80a1\u7968\u4e0e\u57fa\u51c6\u6307\u6570\uff08\u5982\u6807\u666e500\uff09\u7684\u5173\u8054\u6027\u611f\u5174\u8da3\u3002 \u6211\u4eec\u9996\u5148\u8ba1\u7b97\u6240\u6709\u6211\u4eec\u611f\u5174\u8da3\u7684\u65f6\u95f4\u5e8f\u5217\u7684\u767e\u5206\u6bd4\u53d8\u5316\uff1a spx_px = close_px_all['SPX'] spx_rets = spx_px.pct_change() returns = close_px.pct_change() \u5728\u8c03\u7528rolling\u540e\uff0ccorr\u805a\u5408\u51fd\u6570\u53ef\u4ee5\u6839\u636espx_rets\u8ba1\u7b97\u6eda\u52a8\u76f8\u5173\u6027\uff1a \u00b6 corr = returns.AAPL.rolling(125, min_periods=100).corr(spx_rets) # \u82f9\u679c\u516c\u53f8\u4e0e\u6807\u666e500\u7684\u516d\u4e2a\u6708\u7684\u6536\u76ca\u76f8\u5173\u6027 corr.plot() plt.show() corr = returns.rolling(125, min_periods=100).corr(spx_rets) # \u591a\u53ea\u80a1\u7968\u4e0e\u6807\u666e500\u7684\u516d\u4e2a\u6708\u6536\u76ca\u76f8\u5173\u6027 corr.plot() plt.show() ### \u7528\u6237\u81ea\u5b9a\u4e49\u7684\u79fb\u52a8\u7a97\u53e3\u51fd\u6570 \u5728`rolling`\u53ca\u5176\u76f8\u5173\u65b9\u6cd5\u4e0a\u4f7f\u7528apply\u65b9\u6cd5\u63d0\u4f9b\u4e86\u4e00\u79cd\u5728\u79fb\u52a8\u7a97\u53e3\u4e2d\u5e94\u7528\u4f60\u81ea\u5df1\u8bbe\u8ba1\u7684\u6570\u7ec4\u51fd\u6570\u7684\u65b9\u6cd5\u3002 \u552f\u4e00\u7684\u8981\u6c42\u662f\u8be5\u51fd\u6570\u4ece\u6bcf\u4e2a\u6570\u7ec4\u4e2d\u4ea7\u751f\u4e00\u4e2a\u5355\u503c\uff08\u7f29\u805a\uff09\u3002 \u4f8b\u5982\uff0c\u5c3d\u7ba1\u6211\u4eec\u53ef\u4ee5\u4f7f\u7528`rolling(...).quantile(q)`\u8ba1\u7b97\u6837\u672c\u7684\u5206\u4f4d\u6570\uff0c\u4f46\u6211\u4eec\u53ef\u80fd\u4f1a\u5bf9\u6837\u672c\u4e2d\u7279\u5b9a\u503c\u7684\u767e\u5206\u4f4d\u6570\u611f\u5174\u8da3\u3002 `scipy.stats.percentileofscore`\u51fd\u6570\u5c31\u662f\u5b9e\u73b0\u8fd9\u4e2a\u529f\u80fd\u7684\uff1a score_at_2percent = lambda x: percentileofscore(x, 0.02) result = returns.AAPL.rolling(250).apply(score_at_2percent) # \u4e00\u5e74\u7a97\u53e3\u4e0b\u82f9\u679c\u516c\u53f8\u80a1\u4ef72%\u6536\u76ca\u7684\u767e\u5206\u4f4d\u7b49\u7ea7 result.plot() plt.show() result = returns.rolling(250).apply(score_at_2percent) # \u4e00\u5e74\u7a97\u53e3\u4e0b\u6240\u6709\u516c\u53f8\u80a1\u4ef72%\u6536\u76ca\u7684\u767e\u5206\u4f4d\u7b49\u7ea7 result.plot() plt.show() ```","title":"\u65f6\u95f4\u5e8f\u5217"},{"location":"python/DataAnalysis/ch08/#_1","text":"","title":"\u65f6\u95f4\u5e8f\u5217"},{"location":"python/DataAnalysis/ch08/#_2","text":"\u65f6\u95f4\u5e8f\u5217\u6570\u636e\u5728\u5f88\u591a\u9886\u57df\u90fd\u662f\u91cd\u8981\u7684\u7ed3\u6784\u5316\u6570\u636e\u5f62\u5f0f\u3002\u5728\u591a\u4e2a\u65f6\u95f4\u70b9\u89c2\u6d4b\u6216\u6d4b\u91cf\u7684\u6570\u636e\u5f62\u6210\u4e86\u65f6\u95f4\u5e8f\u5217\u3002 \u8bb8\u591a\u65f6\u95f4\u5e8f\u5217\u662f\u56fa\u5b9a\u9891\u7387\u7684\uff0c\u4e5f\u5c31\u662f\u8bf4\u6570\u636e\u662f\u6839\u636e\u76f8\u540c\u7684\u89c4\u5219\u5b9a\u671f\u51fa\u73b0\u7684\uff0c\u4f8b\u5982\u6bcf15\u79d2\u3001\u6bcf5\u5206\u949f\u6216\u6bcf\u67081\u6b21\u3002 \u65f6\u95f4\u5e8f\u5217\u4e5f\u53ef\u4ee5\u662f\u4e0d\u89c4\u5219\u7684\uff0c\u6ca1\u6709\u56fa\u5b9a\u7684\u65f6\u95f4\u5355\u4f4d\u6216\u5355\u4f4d\u95f4\u7684\u504f\u79fb\u91cf\u3002 \u5982\u4f55\u6807\u8bb0\u548c\u5f15\u7528\u65f6\u95f4\u5e8f\u5217\u6570\u636e\u53d6\u51b3\u4e8e\u5e94\u7528\u7a0b\u5e8f\uff0c\u65f6\u95f4\u5e8f\u5217\u5305\u62ec\uff1a \u65f6\u95f4\u6233\uff0c\u5177\u4f53\u7684\u65f6\u523b\u3002 \u56fa\u5b9a\u7684\u65f6\u95f4\u533a\u95f4\uff0c\u4f8b\u59822007\u76841\u6708\u6216\u6574\u4e2a2010\u5e74\u3002 \u65f6\u95f4\u95f4\u9694\uff0c\u7531\u5f00\u59cb\u548c\u7ed3\u675f\u65f6\u95f4\u6233\u8868\u793a\u3002\u65f6\u95f4\u533a\u95f4\u53ef\u4ee5\u88ab\u8ba4\u4e3a\u662f\u95f4\u9694\u7684\u7279\u6b8a\u60c5\u51b5\u3002 \u5b9e\u9a8c\u65f6\u95f4\u6216\u6d88\u8017\u65f6\u95f4\u3002\u6bcf\u4e2a\u65f6\u95f4\u6233\u662f\u76f8\u5bf9\u4e8e\u7279\u5b9a\u5f00\u59cb\u65f6\u95f4\u7684\u65f6\u95f4\u7684\u91cf\u5ea6\uff08\u4f8b\u5982\uff0c\u81ea\u4ece\u88ab\u653e\u7f6e\u5728\u70e4\u7bb1\u4e2d\u6bcf\u79d2\u70d8\u70e4\u7684\u997c\u5e72\u7684\u76f4\u5f84\uff09\u3002 \u76ee\u524d\u4e3b\u8981\u5173\u6ce8\u524d\u4e09\u7c7b\u4e2d\u7684\u65f6\u95f4\u5e8f\u5217\u3002 from datetime import datetime, timedelta import datetime as dt from dateutil.parser import parse import pandas as pd","title":"\u65e5\u671f\u548c\u65f6\u95f4\u6570\u636e\u7684\u7c7b\u578b\u53ca\u5de5\u5177"},{"location":"python/DataAnalysis/ch08/#datetime","text":"datetime\u683c\u5f0f\u7b26\uff1a %a \u661f\u671f\u7684\u82f1\u6587\u5355\u8bcd\u7684\u7f29\u5199\uff1a\u5982\u661f\u671f\u4e00\uff0c \u5219\u8fd4\u56de Mon %A \u661f\u671f\u7684\u82f1\u6587\u5355\u8bcd\u7684\u5168\u62fc\uff1a\u5982\u661f\u671f\u4e00\uff0c\u8fd4\u56de Monday %b \u6708\u4efd\u7684\u82f1\u6587\u5355\u8bcd\u7684\u7f29\u5199\uff1a\u5982\u4e00\u6708\uff0c \u5219\u8fd4\u56de Jan %B \u6708\u4efd\u7684\u5f15\u6587\u5355\u8bcd\u7684\u7f29\u5199\uff1a\u5982\u4e00\u6708\uff0c \u5219\u8fd4\u56de January %c \u8fd4\u56dedatetime\u7684\u5b57\u7b26\u4e32\u8868\u793a\uff0c\u598203/08/15 23:01:26 %d \u8fd4\u56de\u7684\u662f\u5f53\u524d\u65f6\u95f4\u662f\u5f53\u524d\u6708\u7684\u7b2c\u51e0\u5929 %f \u5fae\u79d2\u7684\u8868\u793a\uff1a \u8303\u56f4: [0,999999] %H \u4ee524\u5c0f\u65f6\u5236\u8868\u793a\u5f53\u524d\u5c0f\u65f6 %I \u4ee512\u5c0f\u65f6\u5236\u8868\u793a\u5f53\u524d\u5c0f\u65f6 %m \u8fd4\u56de\u6708\u4efd \u8303\u56f4[0,12] %M \u8fd4\u56de\u5206\u949f\u6570 \u8303\u56f4 [0,59] %P \u8fd4\u56de\u662f\u4e0a\u5348\u8fd8\u662f\u4e0b\u5348\u2013AM or PM %S \u8fd4\u56de\u79d2\u6570 \u8303\u56f4 [0,61]\u3002\u3002\u3002\u624b\u518c\u8bf4\u660e\u7684 %U \u8fd4\u56de\u5f53\u5468\u662f\u5f53\u5e74\u7684\u7b2c\u51e0\u5468 \u4ee5\u5468\u65e5\u4e3a\u7b2c\u4e00\u5929 %W \u8fd4\u56de\u5f53\u5468\u662f\u5f53\u5e74\u7684\u7b2c\u51e0\u5468 \u4ee5\u5468\u4e00\u4e3a\u7b2c\u4e00\u5929 %w \u5f53\u5929\u5728\u5f53\u5468\u7684\u5929\u6570\uff0c\u8303\u56f4\u4e3a[0, 6]\uff0c6\u8868\u793a\u661f\u671f\u5929 %x \u65e5\u671f\u7684\u5b57\u7b26\u4e32\u8868\u793a \uff1a03/08/15 %X \u65f6\u95f4\u7684\u5b57\u7b26\u4e32\u8868\u793a \uff1a23:22:08 %y \u4e24\u4e2a\u6570\u5b57\u8868\u793a\u7684\u5e74\u4efd 15 %Y \u56db\u4e2a\u6570\u5b57\u8868\u793a\u7684\u5e74\u4efd 2015 %z \u4e0eutc\u65f6\u95f4\u7684\u95f4\u9694 \uff08\u5982\u679c\u662f\u672c\u5730\u65f6\u95f4\uff0c\u8fd4\u56de\u7a7a\u5b57\u7b26\u4e32\uff09 %Z \u65f6\u533a\u540d\u79f0\uff08\u5982\u679c\u662f\u672c\u5730\u65f6\u95f4\uff0c\u8fd4\u56de\u7a7a\u5b57\u7b26\u4e32\uff09 datestrs = ['2020/5/6', '2021/10/1'] # \u6ce8\u610f\u533a\u5206datetime\u6a21\u5757\u548cdatetime\u7c7b\uff0c\u540d\u5b57\u76f8\u540c\uff0c\u5bb9\u6613\u5f15\u8d77\u9519\u8bef\u3002 # \u6bd4\u5982datetime.datetime\u5c31\u62a5\u9519type object 'datetime.datetime' has no attribute 'datetime' print(datetime) # print(dt) # Python\u6807\u51c6\u5e93\u5305\u542b\u4e86\u65e5\u671f\u548c\u65f6\u95f4\u6570\u636e\u7684\u7c7b\u578b\u3002 datetime \u3001 time \u548c calendar \u6a21\u5757\u662f\u5f00\u59cb\u5904\u7406\u65f6\u95f4\u6570\u636e\u7684\u4e3b\u8981\u5185\u5bb9\u3002 datetime.datetime \u7c7b\u578b\uff0c\u6216\u7b80\u5199\u4e3a datetime \uff0c\u662f\u5e7f\u6cdb\u4f7f\u7528\u7684\u3002 now = datetime.now() print(now) # 2021-10-07 20:24:43.834293 result = dt.datetime(2021, 10, 7, 20, 26, 00, 72973) print(result) # 2021-10-07 20:26:00.072973 datetime \u65e2\u5b58\u50a8\u4e86\u65e5\u671f\uff0c\u4e5f\u5b58\u50a8\u4e86\u7ec6\u5316\u5230\u5fae\u79d2\u7684\u65f6\u95f4\u3002 timedelta \u8868\u793a\u4e24\u4e2a datetime \u5bf9\u8c61\u7684\u65f6\u95f4\u5dee\u3002 delta = datetime(2021, 10, 7) - datetime(2021, 9, 7) print(delta) # 30 days, 0:00:00 print(delta.days) # 30 print(delta.seconds) # 0 result = dt.timedelta(926, 56700) print(result) # 926 days, 15:45:00 \u53ef\u4ee5\u4e3a\u4e00\u4e2a datetime \u5bf9\u8c61\u52a0\u4e0a\uff08\u6216\u51cf\u53bb\uff09\u4e00\u4e2a timedelta \u6216\u5176\u6574\u6570\u500d\u6765\u4ea7\u751f\u4e00\u4e2a\u65b0\u7684 datetime \u5bf9\u8c61\u3002 start = datetime(2021, 10, 7) result = start + timedelta(12) print(result) # 2021-10-19 00:00:00 result = start - 2 * timedelta(5) print(result) # 2021-09-27 00:00:00","title":"datetime"},{"location":"python/DataAnalysis/ch08/#datetime_1","text":"\u4f7f\u7528 str \u65b9\u6cd5\u6216\u4f20\u9012\u4e00\u4e2a\u6307\u5b9a\u7684\u683c\u5f0f\u7ed9 strftime \u65b9\u6cd5\u6765\u5bf9 datetime \u5bf9\u8c61\u548cpandas\u7684 Timestamp \u5bf9\u8c61\u8fdb\u884c\u683c\u5f0f\u5316\u3002 stamp = datetime(2021, 10, 7) result = str(stamp) print(result) # 2021-10-07 00:00:00 \u4f7f\u7528 datetime.srtptime \u548c datetime \u683c\u5f0f\u7b26\uff0c\u628a\u5b57\u7b26\u4e32\u8f6c\u6362\u65e5\u671f\u3002 datetime.strptime \u662f\u5728\u5df2\u77e5\u683c\u5f0f\u7684\u60c5\u51b5\u4e0b\u8f6c\u6362\u65e5\u671f\u7684\u597d\u65b9\u5f0f\u3002 value = '2021-10-7' result = datetime.strptime(value, '%Y-%m-%d') print(result) # 2021-10-07 00:00:00 datestrs = ['2020/5/6', '2021/10/1'] result = [datetime.strptime(x, '%Y/%m/%d') for x in datestrs] print(result) # [datetime.datetime(2020, 5, 6, 0, 0), datetime.datetime(2021, 10, 1, 0, 0)] dateutil \u89e3\u6790\u901a\u7528\u65e5\u671f\u683c\u5f0f\uff1a print(parse('2020/5/6')) # 2020-05-06 00:00:00 print(parse('Jan 31, 2021 10:25 AM')) # 2021-01-31 10:25:00 print(parse('5/6/2021', dayfirst=True)) # \u65e5\u671f\u51fa\u73b0\u5728\u6708\u4efd\u4e4b\u524d # 2021-06-05 00:00:00 pandas\u4e3b\u8981\u662f\u9762\u5411\u5904\u7406\u65e5\u671f\u6570\u7ec4\u7684\uff0c\u65e0\u8bba\u662f\u7528\u4f5c\u8f74\u7d22\u5f15\u8fd8\u662f\u7528\u4f5cDataFrame\u4e2d\u7684\u5217\u3002 to_datetime \u65b9\u6cd5\u53ef\u4ee5\u8f6c\u6362\u5f88\u591a\u4e0d\u540c\u7684\u65e5\u671f\u8868\u793a\u683c\u5f0f\u3002 to_datetime \u65b9\u6cd5\u8fd8\u53ef\u4ee5\u5904\u7406\u90a3\u4e9b\u88ab\u8ba4\u4e3a\u662f\u7f3a\u5931\u503c\u7684\u503c\uff08None\u3001\u7a7a\u5b57\u7b26\u4e32\u7b49\uff09\u3002 NaT \uff08Not a time\uff09\u662fpandas\u4e2d\u65f6\u95f4\u6233\u6570\u636e\u7684\u662fnull\u503c\u3002 datestrs = ['2020/5/6 12:00:00', '2021/10/1 09:00:00'] result = pd.to_datetime(datestrs) print(result) # DatetimeIndex(['2020-05-06 12:00:00', '2021-10-01 09:00:00'], dtype='datetime64[ns]', freq=None) idx = pd.to_datetime(datestrs + [None]) print(idx) # DatetimeIndex(['2020-05-06 12:00:00', '2021-10-01 09:00:00', 'NaT'], dtype='datetime64[ns]', freq=None) print(idx[2]) # NaT print(pd.isnull(idx)) # [False False True]","title":"\u5b57\u7b26\u4e32\u4e0edatetime\u4e92\u76f8\u8f6c\u6362"},{"location":"python/DataAnalysis/ch08/#_3","text":"from datetime import datetime import pandas as pd import numpy as np","title":"\u65f6\u95f4\u5e8f\u5217\u57fa\u7840"},{"location":"python/DataAnalysis/ch08/#datetimeindex","text":"pandas\u4e2d\u7684\u57fa\u7840\u65f6\u95f4\u5e8f\u5217\u79cd\u7c7b\u662f\u7531\u65f6\u95f4\u6233\u7d22\u5f15\u7684Series\uff0c\u5728pandas\u5916\u90e8\u5219\u901a\u5e38\u8868\u793a\u4e3aPython\u5b57\u7b26\u4e32\u6216 datetime \u5bf9\u8c61\u3002 \u6240\u6709\u4f7f\u7528 datetime \u5bf9\u8c61\u7684\u5730\u65b9\u90fd\u53ef\u4ee5\u7528 Timestamp \u3002 dates = [ datetime(2021, 10, 1), datetime(2021, 10, 3), datetime(2021, 10, 5), datetime(2021, 10, 7), datetime(2021, 10, 9), datetime(2021, 10, 11) ] data = np.random.rand(6) ts = pd.Series(data, index=dates) print(ts) # 2021-10-01 0.678297 # 2021-10-03 0.538631 # 2021-10-05 0.934413 # 2021-10-07 0.018534 # 2021-10-09 0.938441 # 2021-10-11 0.173329 # dtype: float64 \u8fd9\u4e9b datetime \u5bf9\u8c61\u88ab\u653e\u5165 DatetimeIndex \u4e2d\u3002 print(ts.index) # DatetimeIndex(['2021-10-01', '2021-10-03', '2021-10-05', '2021-10-07', # '2021-10-09', '2021-10-11'], # dtype='datetime64[ns]', freq=None) DatetimeIndex \u4e2d\u7684\u6807\u91cf\u503c\u662f pandas \u7684 Timestamp \u5bf9\u8c61\uff1a stamp = ts.index[0] print(stamp) # 2021-10-01 00:00:00 \u548c\u5176\u4ed6Series\u7c7b\u4f3c\uff0c\u4e0d\u540c\u7d22\u5f15\u7684\u65f6\u95f4\u5e8f\u5217\u4e4b\u95f4\u7684\u7b97\u672f\u8fd0\u7b97\u5728\u65e5\u671f\u4e0a\u81ea\u52a8\u5bf9\u9f50\uff1a print(ts + ts[::2]) # ts[::2]\u4f1a\u5c06ts\u4e2d\u6bcf\u9694\u4e00\u4e2a\u7684\u5143\u7d20\u9009\u62e9\u51fa # 2021-10-01 1.356595 # 2021-10-03 NaN # 2021-10-05 1.868825 # 2021-10-07 NaN # 2021-10-09 1.876883 # 2021-10-11 NaN # dtype: float64 pandas\u4f7f\u7528NumPy\u7684 datetime64 \u6570\u636e\u7c7b\u578b\u5728\u7eb3\u79d2\u7ea7\u7684\u5206\u8fa8\u7387\u4e0b\u5b58\u50a8\u65f6\u95f4\u6233 print(ts.index.dtype) # datetime64[ns]","title":"DatetimeIndex"},{"location":"python/DataAnalysis/ch08/#_4","text":"\u5f53\u57fa\u4e8e\u6807\u7b7e\u8fdb\u884c\u7d22\u5f15\u548c\u9009\u62e9\u65f6\uff0c\u65f6\u95f4\u5e8f\u5217\u7684\u884c\u4e3a\u548c\u5176\u4ed6\u7684pandas.Series\u7c7b\u4f3c\uff1a stamp = ts.index[2] print(ts[stamp]) # 0.9344125159374457 \u5bf9\u5e942021-10-05 \u4e5f\u53ef\u4ee5\u4f20\u9012\u4e00\u4e2a\u80fd\u89e3\u91ca\u4e3a\u65e5\u671f\u7684\u5b57\u7b26\u4e32\uff1a print(ts['10/9/2021']) print(ts['20211003']) \u5bf9\u4e00\u4e2a\u957f\u7684\u65f6\u95f4\u5e8f\u5217\uff0c\u53ef\u4ee5\u4f20\u9012\u4e00\u4e2a\u5e74\u4efd\u6216\u4e00\u4e2a\u5e74\u4efd\u548c\u6708\u4efd\u6765\u9009\u62e9\u6570\u636e\u5207\u7247\uff1a data = np.random.randn(1000) longer_ts = pd.Series( data, index=pd.date_range('1/1/2021', periods=1000) ) print(longer_ts) # 2021-01-01 -0.009192 # 2021-01-02 -1.079068 # 2021-01-03 -1.851176 # 2021-01-04 1.347109 # 2021-01-05 -0.236394 # ... # 2023-09-23 -1.317943 # 2023-09-24 0.201741 # 2023-09-25 0.442282 # 2023-09-26 0.176137 # 2023-09-27 1.146437 # Freq: D, Length: 1000, dtype: float64 \u5b57\u7b26\u4e32\u20192001\u2019\u88ab\u89e3\u91ca\u4e3a\u4e00\u4e2a\u5e74\u4efd\uff0c\u5e76\u9009\u62e9\u4e86\u76f8\u5e94\u7684\u65f6\u95f4\u533a\u95f4\u3002 print(longer_ts['2021']) # 2021-01-01 2.170411 # 2021-01-02 1.186933 # 2021-01-03 0.399262 # 2021-01-04 -1.042606 # 2021-01-05 2.082112 # ... # 2021-12-27 -0.988282 # 2021-12-28 0.598683 # 2021-12-29 2.770580 # 2021-12-30 -1.463262 # 2021-12-31 -1.642846 # Freq: D, Length: 365, dtype: float64 \u6307\u5b9a\u4e86\u5e74\u4efd\u548c\u6708\u4efd\u4e5f\u662f\u6709\u6548\u7684\u3002 print(longer_ts['2021-10']) # 2021-10-01 0.712265 # 2021-10-02 1.195221 # 2021-10-03 -1.930220 # 2021-10-04 -0.720816 # 2021-10-05 0.081777 # 2021-10-06 -0.037466 # 2021-10-07 3.737303 # 2021-10-08 1.620383 # 2021-10-09 0.990797 # 2021-10-10 0.507850 # 2021-10-11 0.846935 # 2021-10-12 0.996947 # 2021-10-13 -1.078558 # 2021-10-14 0.871832 # 2021-10-15 -0.591698 # 2021-10-16 -0.805463 # 2021-10-17 0.160528 # 2021-10-18 -0.028474 # 2021-10-19 2.305579 # 2021-10-20 -1.132288 # 2021-10-21 0.649980 # 2021-10-22 0.615327 # 2021-10-23 0.185108 # 2021-10-24 0.857199 # 2021-10-25 -1.473752 # 2021-10-26 -0.895161 # 2021-10-27 -0.432717 # 2021-10-28 0.734504 # 2021-10-29 1.892493 # 2021-10-30 0.456619 # 2021-10-31 -0.255288 # Freq: D, dtype: float64 \u4f7f\u7528 datetime \u5bf9\u8c61\u8fdb\u884c\u5207\u7247\u4e5f\u662f\u53ef\u4ee5\u7684\uff1a print(longer_ts[datetime(2023, 1, 6):]) # 2023-01-06 0.952591 # 2023-01-07 -0.900259 # 2023-01-08 0.925332 # 2023-01-09 0.173215 # 2023-01-10 -0.507791 # ... # 2023-09-23 -0.319989 # 2023-09-24 -1.105417 # 2023-09-25 -2.118769 # 2023-09-26 0.009420 # 2023-09-27 -0.310281 # Freq: D, Length: 265, dtype: float64 \u56e0\u4e3a\u5927\u90e8\u5206\u7684\u65f6\u95f4\u5e8f\u5217\u6570\u636e\u662f\u6309\u65f6\u95f4\u987a\u5e8f\u6392\u5e8f\u7684\uff0c\u53ef\u4ee5\u4f7f\u7528\u4e0d\u5305\u542b\u5728\u65f6\u95f4\u5e8f\u5217\u4e2d\u7684\u65f6\u95f4\u6233\u8fdb\u884c\u5207\u7247\uff0c\u4ee5\u6267\u884c\u8303\u56f4\u67e5\u8be2\uff1a print(longer_ts['2021/10/1':'2021/10/5']) # 2021-10-01 -0.591853 # 2021-10-02 -1.554564 # 2021-10-03 -0.712585 # 2021-10-04 -0.326657 # 2021-10-05 1.044887 # Freq: D, dtype: float64 \u4f7f\u7528 truncate \u5728\u4e24\u4e2a\u65e5\u671f\u95f4\u5bf9Series\u8fdb\u884c\u5207\u7247\uff1a print(longer_ts.truncate(after='2021/10/1')) # 2021-01-01 -0.906685 # 2021-01-02 -0.470732 # 2021-01-03 -0.041316 # 2021-01-04 -0.287356 # 2021-01-05 0.104268 # ... # 2021-09-27 -0.669198 # 2021-09-28 -2.222169 # 2021-09-29 -0.653814 # 2021-09-30 -0.625868 # 2021-10-01 0.872684 # Freq: D, Length: 274, dtype: float64 \u4e0a\u9762\u8fd9\u4e9b\u64cd\u4f5c\u4e5f\u90fd\u9002\u7528\u4e8eDataFrame\uff0c\u5e76\u5728\u5176\u884c\u4e0a\u8fdb\u884c\u7d22\u5f15\uff1a dates = pd.date_range('10/1/2020', periods=100, freq='W-WED') data = np.random.randn(100, 4) long_df = pd.DataFrame( data, index=dates, columns=['Colorado', 'Texas', 'New York', 'Ohio'] ) print(long_df) # Colorado Texas New York Ohio # 2020-10-07 -1.186789 2.020634 0.300076 -0.955234 # 2020-10-14 1.502838 0.965368 -0.797539 -0.292833 # ... ... ... ... ... # 2022-08-24 -0.253116 -0.263307 0.602425 0.370599 # 2022-08-31 0.907918 0.091939 0.789694 2.781535 # [100 rows x 4 columns] print(long_df.loc['10-2020']) # Colorado Texas New York Ohio # 2020-10-07 1.031616 -1.812038 -0.446577 0.395656 # 2020-10-14 -0.673167 0.198804 -0.439141 0.086004 # 2020-10-21 -1.139786 0.716820 0.006516 -0.284335 # 2020-10-28 -0.637939 1.647810 -0.750786 0.140637","title":"\u7d22\u5f15\u3001\u9009\u62e9\u3001\u5b50\u96c6"},{"location":"python/DataAnalysis/ch08/#_5","text":"\u5728\u67d0\u4e9b\u5e94\u7528\u4e2d\uff0c\u53ef\u80fd\u4f1a\u6709\u591a\u4e2a\u6570\u636e\u89c2\u5bdf\u503c\u843d\u5728\u7279\u5b9a\u7684\u65f6\u95f4\u6233\u4e0a\u3002\u4e0b\u9762\u662f\u4e2a\u4f8b\u5b50\uff1a dates = pd.DatetimeIndex( ['2021/1/1', '2021/1/2', '2021/1/2', '2021/1/2', '2021/1/3'] ) dup_ts = pd.Series( np.arange(5), index=dates ) print(dup_ts) # 2021-01-01 0 # 2021-01-02 1 # 2021-01-02 2 # 2021-01-02 3 # 2021-01-03 4 # dtype: int64 \u901a\u8fc7\u68c0\u67e5\u7d22\u5f15\u7684 is_unique \u5c5e\u6027\uff0c\u53ef\u4ee5\u770b\u51fa\u7d22\u5f15\u5e76\u4e0d\u662f\u552f\u4e00\u7684\uff1a print(dup_ts.index.is_unique) # False \u5bf9\u4e0a\u9762\u7684Series\u8fdb\u884c\u7d22\u5f15\uff0c\u7ed3\u679c\u662f\u6807\u91cf\u503c\u8fd8\u662fSeries\u5207\u7247\u53d6\u51b3\u4e8e\u662f\u5426\u6709\u65f6\u95f4\u6233\u662f\u91cd\u590d\u7684\uff1a result = dup_ts['2021/1/3'] print(result) # 4 result = dup_ts['2021/1/2'] print(result) # 2021-01-02 1 # 2021-01-02 2 # 2021-01-02 3 # dtype: int64 \u5047\u8bbe\u60f3\u8981\u805a\u5408\u542b\u6709\u975e\u552f\u4e00\u65f6\u95f4\u6233\u7684\u6570\u636e\u3002\u4e00\u79cd\u65b9\u5f0f\u5c31\u662f\u4f7f\u7528 groupby \u5e76\u4f20\u9012 level=0 \uff1a grouped = dup_ts.groupby(level=0) result = grouped.mean() print(result) # 2021-01-01 0.0 # 2021-01-02 2.0 # 2021-01-03 4.0 # dtype: float64 result = grouped.count() print(result) # 2021-01-01 1 # 2021-01-02 3 # 2021-01-03 1 # dtype: int64","title":"\u542b\u6709\u91cd\u590d\u7d22\u5f15\u7684\u65f6\u95f4\u5e8f\u5217"},{"location":"python/DataAnalysis/ch08/#_6","text":"from datetime import datetime, timedelta import pandas as pd import numpy as np from pandas.tseries.offsets import Hour, Minute, Day, MonthEnd pandas\u7684\u901a\u7528\u65f6\u95f4\u5e8f\u5217\u662f\u4e0d\u89c4\u5219\u7684\uff0c\u5373\u65f6\u95f4\u5e8f\u5217\u7684\u9891\u7387\u4e0d\u662f\u56fa\u5b9a\u7684\u3002 \u4f46\u6709\u65f6\u9700\u8981\u5904\u7406\u56fa\u5b9a\u9891\u7387\u7684\u573a\u666f\uff0c\u4f8b\u5982\u6bcf\u65e5\u7684\u3001\u6bcf\u6708\u7684\u6216\u6bcf15\u5206\u949f\u7684\u65f6\u95f4\u5e8f\u5217\u6570\u636e\u3002 \u53ef\u4ee5\u901a\u8fc7\u8c03\u7528resample\u65b9\u6cd5\u5c06\u6837\u672c\u65f6\u95f4\u5e8f\u5217\u8f6c\u6362\u4e3a\u56fa\u5b9a\u7684\u6bcf\u65e5\u9891\u7387\u6570\u636e\u3002 \u5728\u9891\u7387\u95f4\u8f6c\u6362\uff0c\u53c8\u79f0\u4e3a\u91cd\u65b0\u91c7\u6837\u3002 dates = [ datetime(2021, 10, 1), datetime(2021, 10, 3), datetime(2021, 10, 5), datetime(2021, 10, 7), datetime(2021, 10, 9), datetime(2021, 10, 11) ] data = np.random.rand(6) ts = pd.Series(data, index=dates) print(ts) # 2021-10-01 0.956685 # 2021-10-03 0.817168 # 2021-10-05 0.275543 # 2021-10-07 0.614226 # 2021-10-09 0.061377 # 2021-10-11 0.357080 # dtype: float64 resampler = ts.resample('D') # \u5b57\u7b26\u4e32\u2019D\u2019\u88ab\u89e3\u91ca\u4e3a\u6bcf\u65e5\u9891\u7387 print(resampler) # DatetimeIndexResampler [freq=, axis=0, closed=left, label=left, convention=start, origin=start_day]","title":"\u65e5\u671f\u8303\u56f4\u3001\u9891\u7387\u548c\u79fb\u4f4d"},{"location":"python/DataAnalysis/ch08/#_7","text":"pandas.date_range \u662f\u7528\u4e8e\u6839\u636e\u7279\u5b9a\u9891\u7387\u751f\u6210\u6307\u5b9a\u957f\u5ea6\u7684 DatetimeIndex \u3002 \u9ed8\u8ba4\u60c5\u51b5\u4e0b\uff0c date_range \u751f\u6210\u7684\u662f\u6bcf\u65e5\u7684\u65f6\u95f4\u6233\u3002\u5982\u679c\u53ea\u4f20\u9012\u4e00\u4e2a\u8d77\u59cb\u6216\u7ed3\u5c3e\u65e5\u671f\uff0c\u4f60\u5fc5\u987b\u4f20\u9012\u4e00\u4e2a\u7528\u4e8e\u751f\u6210\u8303\u56f4\u7684\u6570\u5b57\u3002 \u5f00\u59cb\u65e5\u671f\u548c\u7ed3\u675f\u65e5\u671f\u4e25\u683c\u5b9a\u4e49\u4e86\u751f\u6210\u65e5\u671f\u7d22\u5f15\u7684\u8fb9\u754c\u3002 index = pd.date_range('2021/1/1', '2021/1/30') print(index) index = pd.date_range(start='2021/1/1', periods=30) print(index) index = pd.date_range(end='2021/1/30', periods=30) print(index) # DatetimeIndex(['2021-01-01', '2021-01-02', '2021-01-03', '2021-01-04', # '2021-01-05', '2021-01-06', '2021-01-07', '2021-01-08', # '2021-01-09', '2021-01-10', '2021-01-11', '2021-01-12', # '2021-01-13', '2021-01-14', '2021-01-15', '2021-01-16', # '2021-01-17', '2021-01-18', '2021-01-19', '2021-01-20', # '2021-01-21', '2021-01-22', '2021-01-23', '2021-01-24', # '2021-01-25', '2021-01-26', '2021-01-27', '2021-01-28', # '2021-01-29', '2021-01-30'], # dtype='datetime64[ns]', freq='D') \u9ed8\u8ba4\u60c5\u51b5\u4e0b\uff0c date_range \u4fdd\u7559\u5f00\u59cb\u6216\u7ed3\u675f\u65f6\u95f4\u6233\u7684\u65f6\u95f4\uff08\u5982\u679c\u6709\u7684\u8bdd\uff09\u3002 normalize \u9009\u9879\u53ef\u4ee5\u5b9e\u73b0\u751f\u6210\u7684\u662f\u6807\u51c6\u5316\u4e3a\u96f6\u70b9\u7684\u65f6\u95f4\u6233\u3002 index = pd.date_range('2021/1/1 12:56:30', periods=5) print(index) # DatetimeIndex(['2021-01-01 12:56:30', '2021-01-02 12:56:30', # '2021-01-03 12:56:30', '2021-01-04 12:56:30', # '2021-01-05 12:56:30'], # dtype='datetime64[ns]', freq='D') index = pd.date_range('2021/1/1 12:56:30', periods=5, normalize=True) print(index) # DatetimeIndex(['2021-01-01', '2021-01-02', '2021-01-03', '2021-01-04', # '2021-01-05'], # dtype='datetime64[ns]', freq='D') Pandas\u65f6\u95f4\u5e8f\u5217\uff1a\u9891\u7387\u548c\u65e5\u671f\u504f\u79fb\u91cf\u3002 pandas\u4e2d\u7684\u9891\u7387\u662f\u7531\u4e00\u4e2a\u57fa\u7840\u9891\u7387(\u4f8b\u5982\u201c\u65e5\u201d\u3001\u201c\u6708\u201d)\u548c\u4e00\u4e2a\u4e58\u6570\u7ec4\u6210\u3002 \u57fa\u7840\u9891\u7387\u901a\u5e38\u4ee5\u4e00\u4e2a\u5b57\u7b26\u4e32\u522b\u540d\u8868\u793a\uff0c\u6bd4\u5982\u201cD\u201d\u8868\u793a\u65e5\uff0c\u201cM\u201d\u8868\u793a\u6708\u3002 \u5bf9\u4e8e\u6bcf\u4e2a\u57fa\u7840\u9891\u7387\uff0c\u90fd\u6709\u4e00\u4e2a\u88ab\u79f0\u4e3a\u65e5\u671f\u504f\u79fb\u91cf(dateoffset)\u7684\u5bf9\u8c61\u4e0e\u4e4b\u5bf9\u5e94\uff0c\u6bd4\u5982\u65e5\u671f\u504f\u79fb\u91cf Hour \u5bf9\u5e94\u7684\u9891\u7387\u662f H \u3002 \u5e38\u7528\u9891\u7387\u4e0e\u65e5\u671f\u504f\u79fb\u91cf\u3002 \u9891\u7387 \u65e5\u671f\u504f\u79fb\u91cf \u8bf4\u660e D Day \u65e5\u5386\u65e5 B BusinessDay \u5de5\u4f5c\u65e5 H Hour \u5c0f\u65f6 T/min Minute \u5206 S Second \u79d2 L/ms Milli \u6beb\u79d2 U Micro \u5fae\u79d2 M MonthEnd \u6bcf\u6708\u6700\u540e\u4e00\u4e2a\u65e5\u5386\u65e5 BM BusinessMonthEnd \u6bcf\u6708\u6700\u540e\u4e00\u4e2a\u5de5\u4f5c\u65e5 MS MonthBegin \u6bcf\u6708\u7b2c\u4e00\u4e2a\u65e5\u5386\u65e5 BMS BussinessMonthBegin \u6bcf\u6708\u7b2c\u4e00\u4e2a\u5de5\u4f5c\u65e5 W-MON, W-TUE, ... Week \u6307\u5b9a\u661f\u671f\u51e0(MON,TUE,WED,THU,FRI,SAT,SUN) WOM-1MON,WOM-2MON, ... WeekOfMonth \u4ea7\u751f\u6bcf\u6708\u7b2c\u4e00,\u7b2c\u4e8c,\u7b2c\u4e09\u6216\u7b2c\u56db\u5468\u7684\u661f\u671f\u51e0\u3002\u4f8b\u5982WOM-3FRI\u8868\u793a\u6bcf\u6708\u7b2c3\u4e2a\u661f\u671f\u4e94 Q-JAN,Q-FEB, ... QuarterEnd \u4ee5\u6307\u5b9a\u6708\u4efd\u7ed3\u675f\u7684\u5e74\u5ea6\uff0c\u6bcf\u5b63\u5ea6\u6700\u540e\u4e00\u4e2a\u6708\u7684\u6700\u540e\u4e00\u4e2a\u65e5\u5386\u65e5 BQ-JAN,BQ-FEB, ... BusinessQuarterEnd \u4ee5\u6307\u5b9a\u6708\u4efd\u7ed3\u675f\u7684\u5e74\u5ea6\uff0c\u6bcf\u5b63\u5ea6\u6700\u540e\u4e00\u4e2a\u6708\u7684\u6700\u540e\u4e00\u4e2a\u5de5\u4f5c\u65e5 QS-JAN,QS-FEB, ... QuarterBegin \u4ee5\u6307\u5b9a\u6708\u4efd\u7ed3\u675f\u7684\u5e74\u5ea6\uff0c\u6bcf\u5b63\u5ea6\u6700\u540e\u4e00\u4e2a\u6708\u7684\u7b2c\u4e00\u4e2a\u65e5\u5386\u65e5 BQS-JAN,BQS-FEB, ... BusinessQuarterBegin \u4ee5\u6307\u5b9a\u6708\u4efd\u7ed3\u675f\u7684\u5e74\u5ea6\uff0c\u6bcf\u5b63\u5ea6\u6700\u540e\u4e00\u4e2a\u6708\u7684\u7b2c\u4e00\u4e2a\u5de5\u4f5c\u65e5 A-JAN,A-FEB, ... YearEnd \u6bcf\u5e74\u6307\u5b9a\u6708\u4efd\u7684\u6700\u540e\u4e00\u4e2a\u65e5\u5386\u65e5 BA-JAN,BA-FEB, ... BusinessYearEnd \u6bcf\u5e74\u6307\u5b9a\u6708\u4efd\u7684\u6700\u540e\u4e00\u4e2a\u5de5\u4f5c\u65e5 AS-JAN,AS-FEB, ... YearBegin \u6bcf\u5e74\u6307\u5b9a\u6708\u4efd\u7684\u7b2c\u4e00\u4e2a\u65e5\u5386\u65e5 BAS-JAN,BAS-FEB, ... BusinessYearBegin \u6bcf\u5e74\u6307\u5b9a\u6708\u4efd\u7684\u7b2c\u4e00\u4e2a\u5de5\u4f5c\u65e5","title":"\u751f\u6210\u65e5\u671f\u8303\u56f4"},{"location":"python/DataAnalysis/ch08/#_8","text":"pandas\u4e2d\u7684\u9891\u7387\u662f\u7531\u57fa\u7840\u9891\u7387\u548c\u500d\u6570\u7ec4\u6210\u7684\u3002 \u57fa\u7840\u9891\u7387\u901a\u5e38\u4f1a\u6709\u5b57\u7b26\u4e32\u522b\u540d\uff0c\u4f8b\u5982 M \u4ee3\u8868\u6bcf\u6708\uff0c H \u4ee3\u8868\u6bcf\u5c0f\u65f6\u3002 \u5bf9\u4e8e\u6bcf\u4e2a\u57fa\u7840\u9891\u7387\uff0c\u90fd\u6709\u4e00\u4e2a\u5bf9\u8c61\u53ef\u4ee5\u88ab\u7528\u4e8e\u5b9a\u4e49\u65e5\u671f\u504f\u7f6e\u3002 \u4f8b\u5982\uff0c\u6bcf\u5c0f\u65f6\u7684\u9891\u7387\u53ef\u4ee5\u4f7f\u7528 Hour \u7c7b\u6765\u8868\u793a\uff1a ```hour = Hour() print(hour)","title":"\u9891\u7387\u548c\u65e5\u671f\u504f\u7f6e"},{"location":"python/DataAnalysis/ch08/#_9","text":"\u53ef\u4ee5\u4f20\u9012\u4e00\u4e2a\u6574\u6570\u6765\u5b9a\u4e49\u504f\u7f6e\u91cf\u7684\u500d\u6570\uff1a four_hours = Hour(4) print(four_hours)","title":""},{"location":"python/DataAnalysis/ch08/#4-hours","text":"\u5728\u5927\u591a\u6570\u5e94\u7528\u4e2d\uff0c\u4e0d\u9700\u8981\u663e\u5f0f\u5730\u521b\u5efa\u8fd9\u4e9b\u5bf9\u8c61\uff0c\u800c\u662f\u4f7f\u7528\u5b57\u7b26\u4e32\u522b\u540d\uff0c\u5982`H`\u6216`4H`\u3002\u5728\u57fa\u7840\u9891\u7387\u524d\u653e\u4e00\u4e2a\u6574\u6570\u5c31\u53ef\u4ee5\u751f\u6210\u500d\u6570\uff1a ts = pd.date_range('2021/1/1', '2021/\u00bd 23:59', freq='4h') print(ts)","title":"<4 * Hours>"},{"location":"python/DataAnalysis/ch08/#datetimeindex2021-01-01-000000-2021-01-01-040000","text":"","title":"DatetimeIndex(['2021-01-01 00:00:00', '2021-01-01 04:00:00',"},{"location":"python/DataAnalysis/ch08/#2021-01-01-080000-2021-01-01-120000","text":"","title":"'2021-01-01 08:00:00', '2021-01-01 12:00:00',"},{"location":"python/DataAnalysis/ch08/#2021-01-01-160000-2021-01-01-200000","text":"","title":"'2021-01-01 16:00:00', '2021-01-01 20:00:00',"},{"location":"python/DataAnalysis/ch08/#2021-01-02-000000-2021-01-02-040000","text":"","title":"'2021-01-02 00:00:00', '2021-01-02 04:00:00',"},{"location":"python/DataAnalysis/ch08/#2021-01-02-080000-2021-01-02-120000","text":"","title":"'2021-01-02 08:00:00', '2021-01-02 12:00:00',"},{"location":"python/DataAnalysis/ch08/#2021-01-02-160000-2021-01-02-200000","text":"","title":"'2021-01-02 16:00:00', '2021-01-02 20:00:00'],"},{"location":"python/DataAnalysis/ch08/#dtypedatetime64ns-freq4h","text":"\u591a\u4e2a\u504f\u7f6e\u53ef\u4ee5\u901a\u8fc7\u52a0\u6cd5\u8fdb\u884c\u8054\u5408\uff1a print(Hour(2) + Minute(30))","title":"dtype='datetime64[ns]', freq='4H')"},{"location":"python/DataAnalysis/ch08/#150-minutes","text":"\u7c7b\u4f3c\u5730\uff0c\u53ef\u4ee5\u4f20\u9012\u9891\u7387\u5b57\u7b26\u4e32\uff1a ts = pd.date_range('2021/1/1', '2021/1/1 23:59', freq='4h30min') print(ts)","title":"<150 * Minutes>"},{"location":"python/DataAnalysis/ch08/#datetimeindex2021-01-01-000000-2021-01-01-043000","text":"","title":"DatetimeIndex(['2021-01-01 00:00:00', '2021-01-01 04:30:00',"},{"location":"python/DataAnalysis/ch08/#2021-01-01-090000-2021-01-01-133000","text":"","title":"'2021-01-01 09:00:00', '2021-01-01 13:30:00',"},{"location":"python/DataAnalysis/ch08/#2021-01-01-180000-2021-01-01-223000","text":"","title":"'2021-01-01 18:00:00', '2021-01-01 22:30:00'],"},{"location":"python/DataAnalysis/ch08/#dtypedatetime64ns-freq270t","text":"\u6709\u4e9b\u9891\u7387\u63cf\u8ff0\u70b9\u7684\u65f6\u95f4\u5e76\u4e0d\u662f\u5747\u5300\u5206\u9694\u7684\u3002\u4f8b\u5982\uff0c`M`\uff08\u65e5\u5386\u6708\u672b\uff09\u548c`BM`\uff08\u6708\u5185\u6700\u540e\u5de5\u4f5c\u65e5\uff09\u53d6\u51b3\u4e8e\u5f53\u6708\u5929\u6570\uff0c\u6708\u672b\u662f\u5426\u662f\u5468\u672b\u3002\u6211\u4eec\u5c06\u8fd9\u4e9b\u65e5\u671f\u79f0\u4e3a\u951a\u5b9a\u504f\u7f6e\u91cf\u3002 #### \u6708\u4e2d\u67d0\u661f\u671f\u7684\u65e5\u671f \"\u6708\u4e2d\u67d0\u661f\u671f\"\uff08week of month \uff09\u7684\u65e5\u671f\u662f\u4e00\u4e2a\u6709\u7528\u7684\u9891\u7387\u7c7b\uff0c\u4ee5`WOM`\u5f00\u59cb\u3002 rng = pd.date_range('2021-1-1', '2021-9-1', freq='WOM-3FRI') # \u6bcf\u6708\u7b2c\u4e09\u4e2a\u661f\u671f\u4e94 print(rng)","title":"dtype='datetime64[ns]', freq='270T')"},{"location":"python/DataAnalysis/ch08/#datetimeindex2021-01-15-2021-02-19-2021-03-19-2021-04-16","text":"","title":"DatetimeIndex(['2021-01-15', '2021-02-19', '2021-03-19', '2021-04-16',"},{"location":"python/DataAnalysis/ch08/#2021-05-21-2021-06-18-2021-07-16-2021-08-20","text":"","title":"'2021-05-21', '2021-06-18', '2021-07-16', '2021-08-20'],"},{"location":"python/DataAnalysis/ch08/#dtypedatetime64ns-freqwom-3fri","text":"### \u79fb\u4f4d\uff08\u524d\u5411\u548c\u540e\u5411\uff09\u65e5\u671f \"\u79fb\u4f4d\"\u662f\u6307\u5c06\u65e5\u671f\u6309\u65f6\u95f4\u5411\u524d\u79fb\u52a8\u6216\u5411\u540e\u79fb\u52a8\u3002 Series\u548cDataFrame\u90fd\u6709\u4e00\u4e2a`shift`\u65b9\u6cd5\u7528\u4e8e\u8fdb\u884c\u7b80\u5355\u7684\u524d\u5411\u6216\u540e\u5411\u79fb\u4f4d\uff0c\u800c\u4e0d\u6539\u53d8\u7d22\u5f15\u3002 \u8fdb\u884c\u79fb\u4f4d\u65f6\uff0c\u4f1a\u5728\u65f6\u95f4\u5e8f\u5217\u7684\u8d77\u59cb\u4f4d\u6216\u7ed3\u675f\u4f4d\u5f15\u5165\u7f3a\u5931\u503c\u3002 data = [0.882972, 1.363282, -0.687750, -0.048117] ts = pd.Series(data, index=pd.date_range('2021-1-1', periods=4, freq='M')) print(ts)","title":"dtype='datetime64[ns]', freq='WOM-3FRI')"},{"location":"python/DataAnalysis/ch08/#2021-01-31-0882972","text":"","title":"2021-01-31 0.882972"},{"location":"python/DataAnalysis/ch08/#2021-02-28-1363282","text":"","title":"2021-02-28 1.363282"},{"location":"python/DataAnalysis/ch08/#2021-03-31-0687750","text":"","title":"2021-03-31 -0.687750"},{"location":"python/DataAnalysis/ch08/#2021-04-30-0048117","text":"","title":"2021-04-30 -0.048117"},{"location":"python/DataAnalysis/ch08/#freq-m-dtype-float64","text":"print(ts.shift(2))","title":"Freq: M, dtype: float64"},{"location":"python/DataAnalysis/ch08/#2021-01-31-nan","text":"","title":"2021-01-31 NaN"},{"location":"python/DataAnalysis/ch08/#2021-02-28-nan","text":"","title":"2021-02-28 NaN"},{"location":"python/DataAnalysis/ch08/#2021-03-31-0882972","text":"","title":"2021-03-31 0.882972"},{"location":"python/DataAnalysis/ch08/#2021-04-30-1363282","text":"","title":"2021-04-30 1.363282"},{"location":"python/DataAnalysis/ch08/#freq-m-dtype-float64_1","text":"print(ts.shift(-2))","title":"Freq: M, dtype: float64"},{"location":"python/DataAnalysis/ch08/#2021-01-31-0687750","text":"","title":"2021-01-31 -0.687750"},{"location":"python/DataAnalysis/ch08/#2021-02-28-0048117","text":"","title":"2021-02-28 -0.048117"},{"location":"python/DataAnalysis/ch08/#2021-03-31-nan","text":"","title":"2021-03-31 NaN"},{"location":"python/DataAnalysis/ch08/#2021-04-30-nan","text":"","title":"2021-04-30 NaN"},{"location":"python/DataAnalysis/ch08/#freq-m-dtype-float64_2","text":"`shift`\u5e38\u7528\u4e8e\u8ba1\u7b97\u65f6\u95f4\u5e8f\u5217\u6216DataFrame\u591a\u5217\u65f6\u95f4\u5e8f\u5217\u7684\u767e\u5206\u6bd4\u53d8\u5316\uff1a print(ts/ts.shift(1))","title":"Freq: M, dtype: float64"},{"location":"python/DataAnalysis/ch08/#2021-01-31-nan_1","text":"","title":"2021-01-31 NaN"},{"location":"python/DataAnalysis/ch08/#2021-02-28-1543970","text":"","title":"2021-02-28 1.543970"},{"location":"python/DataAnalysis/ch08/#2021-03-31-0504481","text":"","title":"2021-03-31 -0.504481"},{"location":"python/DataAnalysis/ch08/#2021-04-30-0069963","text":"","title":"2021-04-30 0.069963"},{"location":"python/DataAnalysis/ch08/#freq-m-dtype-float64_3","text":"print(ts/ts.shift(1) - 1)","title":"Freq: M, dtype: float64"},{"location":"python/DataAnalysis/ch08/#2021-01-31-nan_2","text":"","title":"2021-01-31 NaN"},{"location":"python/DataAnalysis/ch08/#2021-02-28-0543970","text":"","title":"2021-02-28 0.543970"},{"location":"python/DataAnalysis/ch08/#2021-03-31-1504481","text":"","title":"2021-03-31 -1.504481"},{"location":"python/DataAnalysis/ch08/#2021-04-30-0930037","text":"","title":"2021-04-30 -0.930037"},{"location":"python/DataAnalysis/ch08/#freq-m-dtype-float64_4","text":"\u5982\u679c\u9891\u7387\u662f\u5df2\u77e5\u7684\uff0c\u5219\u53ef\u4ee5\u5c06\u9891\u7387\u4f20\u9012\u7ed9`shift`\u6765\u63a8\u79fb\u65f6\u95f4\u6233\uff1a print(ts.shift(2, freq='M')) # \u539f\u59cb\u6570\u636e\u7684\u201c\u6708\u201c\u589e\u52a0\u4e86\u504f\u79fb\u503c","title":"Freq: M, dtype: float64"},{"location":"python/DataAnalysis/ch08/#2021-03-31-0882972_1","text":"","title":"2021-03-31 0.882972"},{"location":"python/DataAnalysis/ch08/#2022021-10-31-0000001-04-30-1363282","text":"","title":"2022021-10-31 00:00:001-04-30 1.363282"},{"location":"python/DataAnalysis/ch08/#2021-05-31-0687750","text":"","title":"2021-05-31 -0.687750"},{"location":"python/DataAnalysis/ch08/#2021-06-30-0048117","text":"","title":"2021-06-30 -0.048117"},{"location":"python/DataAnalysis/ch08/#freq-m-dtype-float64_5","text":"print(ts.shift(2, freq='D')) # \u539f\u59cb\u6570\u636e\u7684\u201c\u65e5\u201c\u589e\u52a0\u4e86\u504f\u79fb\u503c","title":"Freq: M, dtype: float64"},{"location":"python/DataAnalysis/ch08/#2021-02-02-0882972","text":"","title":"2021-02-02 0.882972"},{"location":"python/DataAnalysis/ch08/#2021-03-02-1363282","text":"","title":"2021-03-02 1.363282"},{"location":"python/DataAnalysis/ch08/#2021-04-02-0687750","text":"","title":"2021-04-02 -0.687750"},{"location":"python/DataAnalysis/ch08/#2021-05-02-0048117","text":"","title":"2021-05-02 -0.048117"},{"location":"python/DataAnalysis/ch08/#dtype-float64","text":"print(ts.shift(2, freq='90T')) # \u539f\u59cb\u6570\u636e\u7684\u201c\u5c0f\u65f6\u201c\u589e\u52a0\u4e86\u504f\u79fb\u503c","title":"dtype: float64"},{"location":"python/DataAnalysis/ch08/#2021-01-31-030000-0882972","text":"","title":"2021-01-31 03:00:00 0.882972"},{"location":"python/DataAnalysis/ch08/#2021-02-28-030000-1363282","text":"","title":"2021-02-28 03:00:00 1.363282"},{"location":"python/DataAnalysis/ch08/#2021-03-31-030000-0687750","text":"","title":"2021-03-31 03:00:00 -0.687750"},{"location":"python/DataAnalysis/ch08/#2021-04-30-030000-0048117","text":"","title":"2021-04-30 03:00:00 -0.048117"},{"location":"python/DataAnalysis/ch08/#dtype-float64_1","text":"#### \u4f7f\u7528\u504f\u7f6e\u8fdb\u884c\u79fb\u4f4d\u65e5\u671f pandas\u65e5\u671f\u504f\u7f6e\u4e5f\u53ef\u4ee5\u4f7f\u7528`datetime`\u6216`Timestamp`\u5bf9\u8c61\u5b8c\u6210\uff1a now = datetime(2021, 10, 9) print(now)","title":"dtype: float64"},{"location":"python/DataAnalysis/ch08/#2021-10-09-000000","text":"print(now + 3 * Day())","title":"2021-10-09 00:00:00"},{"location":"python/DataAnalysis/ch08/#2021-10-12-000000","text":"\u951a\u5b9a\u504f\u7f6e\u53ef\u4ee5\u4f7f\u7528`rollforward`\u548c`rollback`\u5206\u522b\u663e\u5f0f\u5730\u5c06\u65e5\u671f\u5411\u524d\u6216\u5411\u540e\"\u6eda\u52a8\"\u3002 \u5982\u679c\u6dfb\u52a0\u4e86\u4e00\u4e2a\u951a\u5b9a\u504f\u7f6e\u91cf\uff0c\u6bd4\u5982`MonthEnd`\uff0c\u6839\u636e\u9891\u7387\u89c4\u5219\uff0c\u7b2c\u4e00\u4e2a\u589e\u91cf\u4f1a\u5c06\u65e5\u671f\u201c\u524d\u6eda\u201d\u5230\u4e0b\u4e00\u4e2a\u65e5\u671f\uff1a print(now + MonthEnd()) # \u201c\u524d\u6eda\u201d\u5230\u5f53\u524d\u6708\u7684\u6708\u5e95","title":"2021-10-12 00:00:00"},{"location":"python/DataAnalysis/ch08/#2021-10-31-000000","text":"print(now + MonthEnd(2)) # \u6ce8\u610f\u8fd9\u91cc\u7684\u5e8f\u5217\u53f7\uff0c\u5f53\u524d\u6708\u662f1,\u4e0b\u4e2a\u6708\u662f2","title":"2021-10-31 00:00:00"},{"location":"python/DataAnalysis/ch08/#2021-11-30-000000","text":"offset = MonthEnd() print(offset.rollback(now))","title":"2021-11-30 00:00:00"},{"location":"python/DataAnalysis/ch08/#2021-09-30-000000","text":"print(offset.rollforward(now))","title":"2021-09-30 00:00:00"},{"location":"python/DataAnalysis/ch08/#2021-10-31-000000_1","text":"\u5c06\u79fb\u4f4d\u65b9\u6cd5\u4e0e`groupby`\u4e00\u8d77\u4f7f\u7528\u662f\u65e5\u671f\u504f\u7f6e\u7684\u4e00\u79cd\u521b\u9020\u6027\u7528\u6cd5\uff1a ts = pd.Series( np.random.randn(20), index=pd.date_range('2021/1/1', periods=20, freq='4d') ) print(ts)","title":"2021-10-31 00:00:00"},{"location":"python/DataAnalysis/ch08/#2021-01-01-0674348","text":"","title":"2021-01-01 0.674348"},{"location":"python/DataAnalysis/ch08/#2021-01-05-1437803","text":"","title":"2021-01-05 -1.437803"},{"location":"python/DataAnalysis/ch08/#2021-01-09-0079218","text":"","title":"2021-01-09 -0.079218"},{"location":"python/DataAnalysis/ch08/#2021-01-13-1444890","text":"","title":"2021-01-13 -1.444890"},{"location":"python/DataAnalysis/ch08/#2021-01-17-0643279","text":"","title":"2021-01-17 0.643279"},{"location":"python/DataAnalysis/ch08/#2021-01-21-1089965","text":"","title":"2021-01-21 1.089965"},{"location":"python/DataAnalysis/ch08/#2021-01-25-0021876","text":"","title":"2021-01-25 0.021876"},{"location":"python/DataAnalysis/ch08/#2021-01-29-0692138","text":"","title":"2021-01-29 0.692138"},{"location":"python/DataAnalysis/ch08/#2021-02-02-0833496","text":"","title":"2021-02-02 0.833496"},{"location":"python/DataAnalysis/ch08/#2021-02-06-1082616","text":"","title":"2021-02-06 1.082616"},{"location":"python/DataAnalysis/ch08/#2021-02-10-0729415","text":"","title":"2021-02-10 -0.729415"},{"location":"python/DataAnalysis/ch08/#2021-02-14-0271186","text":"","title":"2021-02-14 0.271186"},{"location":"python/DataAnalysis/ch08/#2021-02-18-1416218","text":"","title":"2021-02-18 -1.416218"},{"location":"python/DataAnalysis/ch08/#2021-02-22-0780402","text":"","title":"2021-02-22 -0.780402"},{"location":"python/DataAnalysis/ch08/#2021-02-26-0113773","text":"","title":"2021-02-26 -0.113773"},{"location":"python/DataAnalysis/ch08/#2021-03-02-2095338","text":"","title":"2021-03-02 2.095338"},{"location":"python/DataAnalysis/ch08/#2021-03-06-0302612","text":"","title":"2021-03-06 -0.302612"},{"location":"python/DataAnalysis/ch08/#2021-03-10-1113632","text":"","title":"2021-03-10 1.113632"},{"location":"python/DataAnalysis/ch08/#2021-03-14-1314581","text":"","title":"2021-03-14 -1.314581"},{"location":"python/DataAnalysis/ch08/#2021-03-18-0947746","text":"","title":"2021-03-18 0.947746"},{"location":"python/DataAnalysis/ch08/#freq-4d-dtype-float64","text":"print(ts.groupby(offset.rollforward).mean()) # \u524d\u6eda\u81f3\u5f53\u6708\u6708\u5e95\uff0c\u8ba1\u7b97\u5f53\u6708\u5e73\u5747\u503c","title":"Freq: 4D, dtype: float64"},{"location":"python/DataAnalysis/ch08/#2021-01-31-0019962","text":"","title":"2021-01-31 0.019962"},{"location":"python/DataAnalysis/ch08/#2021-02-28-0121787","text":"","title":"2021-02-28 -0.121787"},{"location":"python/DataAnalysis/ch08/#2021-03-31-0507905","text":"","title":"2021-03-31 0.507905"},{"location":"python/DataAnalysis/ch08/#dtype-float64_2","text":"","title":"dtype: float64"},{"location":"python/DataAnalysis/ch08/#resample","text":"print(ts.resample('M').mean())","title":"\u4f7f\u7528resample\u662f\u66f4\u7b80\u5355\u66f4\u5feb\u6377\u7684\u65b9\u6cd5"},{"location":"python/DataAnalysis/ch08/#2021-01-31-0019962_1","text":"","title":"2021-01-31 0.019962"},{"location":"python/DataAnalysis/ch08/#2021-02-28-0121787_1","text":"","title":"2021-02-28 -0.121787"},{"location":"python/DataAnalysis/ch08/#2021-03-31-0507905_1","text":"","title":"2021-03-31 0.507905"},{"location":"python/DataAnalysis/ch08/#freq-m-dtype-float64_6","text":"## \u65f6\u533a\u5904\u7406 \u65f6\u533a\u901a\u5e38\u88ab\u8868\u793a\u4e3aUTC\u7684\u504f\u7f6e\u3002 \u5728Python\u8bed\u8a00\u4e2d\uff0c\u65f6\u533a\u4fe1\u606f\u6765\u6e90\u4e8e\u7b2c\u4e09\u65b9\u5e93pytz\uff08\u53ef\u4ee5\u4f7f\u7528pip\u6216conda\u5b89\u88c5\uff09\uff0c\u5176\u4e2d\u516c\u5f00\u4e86Olson\u6570\u636e\u5e93\uff0c\u8fd9\u662f\u4e16\u754c\u65f6\u533a\u4fe1\u606f\u7684\u6c47\u7f16\u3002 pandas\u5c01\u88c5\u4e86pytz\u7684\u529f\u80fd\u3002 from datetime import datetime, timedelta import pandas as pd import numpy as np from pandas.tseries.offsets import Hour, Minute, Day, MonthEnd import pytz #### common_timezones tz = pytz.common_timezones[-5:] # \u8bfb\u53d6common_timezones\u8fd9\u4e2a\u5217\u8868\u7684\u6700\u540e5\u4e2a\u5143\u7d20 print(tz)","title":"Freq: M, dtype: float64"},{"location":"python/DataAnalysis/ch08/#useastern-ushawaii-usmountain-uspacific-utc","text":"\u8981\u83b7\u5f97pytz\u7684\u65f6\u533a\u5bf9\u8c61\uff0c\u53ef\u4f7f\u7528pytz.timezone\uff1a tz = pytz.timezone('Asia/Shanghai') print(tz) #### \u65f6\u533a\u7684\u672c\u5730\u5316\u548c\u8f6c\u6362 \u9ed8\u8ba4\u60c5\u51b5\u4e0b\uff0cpandas\u4e2d\u7684\u65f6\u95f4\u5e8f\u5217\u662f\u65f6\u533a\u7b80\u5355\u578b\u7684\u3002 rng = pd.date_range('2021/1/1 9:30', periods=6, freq='D') ts = pd.Series(np.random.randn(len(rng)), index=rng) print(rng)","title":"['US/Eastern', 'US/Hawaii', 'US/Mountain', 'US/Pacific', 'UTC']"},{"location":"python/DataAnalysis/ch08/#datetimeindex2021-01-01-093000-2021-01-02-093000","text":"","title":"DatetimeIndex(['2021-01-01 09:30:00', '2021-01-02 09:30:00',"},{"location":"python/DataAnalysis/ch08/#2021-01-03-093000-2021-01-04-093000","text":"","title":"'2021-01-03 09:30:00', '2021-01-04 09:30:00',"},{"location":"python/DataAnalysis/ch08/#2021-01-05-093000-2021-01-06-093000","text":"","title":"'2021-01-05 09:30:00', '2021-01-06 09:30:00'],"},{"location":"python/DataAnalysis/ch08/#dtypedatetime64ns-freqd","text":"print(ts)","title":"dtype='datetime64[ns]', freq='D')"},{"location":"python/DataAnalysis/ch08/#2021-01-01-093000-0339822","text":"","title":"2021-01-01 09:30:00 0.339822"},{"location":"python/DataAnalysis/ch08/#2021-01-02-093000-1356382","text":"","title":"2021-01-02 09:30:00 1.356382"},{"location":"python/DataAnalysis/ch08/#2021-01-03-093000-0475429","text":"","title":"2021-01-03 09:30:00 0.475429"},{"location":"python/DataAnalysis/ch08/#2021-01-04-093000-1826654","text":"","title":"2021-01-04 09:30:00 1.826654"},{"location":"python/DataAnalysis/ch08/#2021-01-05-093000-0245510","text":"","title":"2021-01-05 09:30:00 -0.245510"},{"location":"python/DataAnalysis/ch08/#2021-01-06-093000-0705274","text":"","title":"2021-01-06 09:30:00 0.705274"},{"location":"python/DataAnalysis/ch08/#freq-d-dtype-float64","text":"print(ts.index.tz) # \u7d22\u5f15\u7684tz\u5c5e\u6027\u662fNone","title":"Freq: D, dtype: float64"},{"location":"python/DataAnalysis/ch08/#none","text":"\u65e5\u671f\u8303\u56f4\u53ef\u4ee5\u901a\u8fc7\u65f6\u533a\u96c6\u5408\u6765\u751f\u6210\uff1a rng = pd.date_range('2021/3/1', periods=10, freq='D', tz='UTC') print(rng)","title":"None"},{"location":"python/DataAnalysis/ch08/#datetimeindex2021-03-01-0000000000-2021-03-02-0000000000","text":"","title":"DatetimeIndex(['2021-03-01 00:00:00+00:00', '2021-03-02 00:00:00+00:00',"},{"location":"python/DataAnalysis/ch08/#2021-03-03-0000000000-2021-03-04-0000000000","text":"","title":"'2021-03-03 00:00:00+00:00', '2021-03-04 00:00:00+00:00',"},{"location":"python/DataAnalysis/ch08/#2021-03-05-0000000000-2021-03-06-0000000000","text":"","title":"'2021-03-05 00:00:00+00:00', '2021-03-06 00:00:00+00:00',"},{"location":"python/DataAnalysis/ch08/#2021-03-07-0000000000-2021-03-08-0000000000","text":"","title":"'2021-03-07 00:00:00+00:00', '2021-03-08 00:00:00+00:00',"},{"location":"python/DataAnalysis/ch08/#2021-03-09-0000000000-2021-03-10-0000000000","text":"","title":"'2021-03-09 00:00:00+00:00', '2021-03-10 00:00:00+00:00'],"},{"location":"python/DataAnalysis/ch08/#dtypedatetime64ns-utc-freqd","text":"\u4f7f\u7528`tz_localize`\u65b9\u6cd5\u53ef\u4ee5\u4ece\u7b80\u5355\u65f6\u533a\u8f6c\u6362\u5230\u672c\u5730\u5316\u65f6\u533a\uff1a print(ts)","title":"dtype='datetime64[ns, UTC]', freq='D')"},{"location":"python/DataAnalysis/ch08/#2021-01-01-093000-0294647","text":"","title":"2021-01-01 09:30:00 0.294647"},{"location":"python/DataAnalysis/ch08/#2021-01-02-093000-0958414","text":"","title":"2021-01-02 09:30:00 0.958414"},{"location":"python/DataAnalysis/ch08/#2021-01-03-093000-0424235","text":"","title":"2021-01-03 09:30:00 0.424235"},{"location":"python/DataAnalysis/ch08/#2021-01-04-093000-1714333","text":"","title":"2021-01-04 09:30:00 -1.714333"},{"location":"python/DataAnalysis/ch08/#2021-01-05-093000-0030319","text":"","title":"2021-01-05 09:30:00 -0.030319"},{"location":"python/DataAnalysis/ch08/#2021-01-06-093000-0744940","text":"","title":"2021-01-06 09:30:00 -0.744940"},{"location":"python/DataAnalysis/ch08/#freq-d-dtype-float64_1","text":"print(ts.tz_localize('UTC'))","title":"Freq: D, dtype: float64"},{"location":"python/DataAnalysis/ch08/#2021-01-01-0930000000-0294647","text":"","title":"2021-01-01 09:30:00+00:00 0.294647"},{"location":"python/DataAnalysis/ch08/#2021-01-02-0930000000-0958414","text":"","title":"2021-01-02 09:30:00+00:00 0.958414"},{"location":"python/DataAnalysis/ch08/#2021-01-03-0930000000-0424235","text":"","title":"2021-01-03 09:30:00+00:00 0.424235"},{"location":"python/DataAnalysis/ch08/#2021-01-04-0930000000-1714333","text":"","title":"2021-01-04 09:30:00+00:00 -1.714333"},{"location":"python/DataAnalysis/ch08/#2021-01-05-0930000000-0030319","text":"","title":"2021-01-05 09:30:00+00:00 -0.030319"},{"location":"python/DataAnalysis/ch08/#2021-01-06-0930000000-0744940","text":"","title":"2021-01-06 09:30:00+00:00 -0.744940"},{"location":"python/DataAnalysis/ch08/#freq-d-dtype-float64_2","text":"print(ts.tz_localize('Asia/Shanghai'))","title":"Freq: D, dtype: float64"},{"location":"python/DataAnalysis/ch08/#2021-01-01-0930000800-0052521","text":"","title":"2021-01-01 09:30:00+08:00 0.052521"},{"location":"python/DataAnalysis/ch08/#2021-01-02-0930000800-0305417","text":"","title":"2021-01-02 09:30:00+08:00 -0.305417"},{"location":"python/DataAnalysis/ch08/#2021-01-03-0930000800-0150215","text":"","title":"2021-01-03 09:30:00+08:00 0.150215"},{"location":"python/DataAnalysis/ch08/#2021-01-04-0930000800-0953715","text":"","title":"2021-01-04 09:30:00+08:00 -0.953715"},{"location":"python/DataAnalysis/ch08/#2021-01-05-0930000800-0543622","text":"","title":"2021-01-05 09:30:00+08:00 0.543622"},{"location":"python/DataAnalysis/ch08/#2021-01-06-0930000800-0222422","text":"","title":"2021-01-06 09:30:00+08:00 0.222422"},{"location":"python/DataAnalysis/ch08/#dtype-float64_3","text":"print(ts.tz_localize('Asia/Shanghai').index)","title":"dtype: float64"},{"location":"python/DataAnalysis/ch08/#datetimeindex2021-01-01-0930000800-2021-01-02-0930000800","text":"","title":"DatetimeIndex(['2021-01-01 09:30:00+08:00', '2021-01-02 09:30:00+08:00',"},{"location":"python/DataAnalysis/ch08/#2021-01-03-0930000800-2021-01-04-0930000800","text":"","title":"'2021-01-03 09:30:00+08:00', '2021-01-04 09:30:00+08:00',"},{"location":"python/DataAnalysis/ch08/#2021-01-05-0930000800-2021-01-06-0930000800","text":"","title":"'2021-01-05 09:30:00+08:00', '2021-01-06 09:30:00+08:00'],"},{"location":"python/DataAnalysis/ch08/#dtypedatetime64ns-asiashanghai-freqnone","text":"\u4e00\u65e6\u65f6\u95f4\u5e8f\u5217\u88ab\u672c\u5730\u5316\u4e3a\u67d0\u4e2a\u7279\u5b9a\u7684\u65f6\u533a\uff0c\u5219\u53ef\u4ee5\u901a\u8fc7`tz_convert`\u5c06\u5176\u8f6c\u6362\u4e3a\u53e6\u4e00\u4e2a\u65f6\u533a\uff1a tz_sha = ts.tz_localize('Asia/Shanghai') tz_utc = tz_sha.tz_convert('UTC') print(tz_sha)","title":"dtype='datetime64[ns, Asia/Shanghai]', freq=None)"},{"location":"python/DataAnalysis/ch08/#2021-01-01-0930000800-0095689","text":"","title":"2021-01-01 09:30:00+08:00 0.095689"},{"location":"python/DataAnalysis/ch08/#2021-01-02-0930000800-0392730","text":"","title":"2021-01-02 09:30:00+08:00 -0.392730"},{"location":"python/DataAnalysis/ch08/#2021-01-03-0930000800-0151468","text":"","title":"2021-01-03 09:30:00+08:00 0.151468"},{"location":"python/DataAnalysis/ch08/#2021-01-04-0930000800-0027467","text":"","title":"2021-01-04 09:30:00+08:00 0.027467"},{"location":"python/DataAnalysis/ch08/#2021-01-05-0930000800-0393709","text":"","title":"2021-01-05 09:30:00+08:00 0.393709"},{"location":"python/DataAnalysis/ch08/#2021-01-06-0930000800-0872914","text":"","title":"2021-01-06 09:30:00+08:00 0.872914"},{"location":"python/DataAnalysis/ch08/#dtype-float64_4","text":"print(tz_utc)","title":"dtype: float64"},{"location":"python/DataAnalysis/ch08/#2021-01-01-0130000000-0095689","text":"","title":"2021-01-01 01:30:00+00:00 0.095689"},{"location":"python/DataAnalysis/ch08/#2021-01-02-0130000000-0392730","text":"","title":"2021-01-02 01:30:00+00:00 -0.392730"},{"location":"python/DataAnalysis/ch08/#2021-01-03-0130000000-0151468","text":"","title":"2021-01-03 01:30:00+00:00 0.151468"},{"location":"python/DataAnalysis/ch08/#2021-01-04-0130000000-0027467","text":"","title":"2021-01-04 01:30:00+00:00 0.027467"},{"location":"python/DataAnalysis/ch08/#2021-01-05-0130000000-0393709","text":"","title":"2021-01-05 01:30:00+00:00 0.393709"},{"location":"python/DataAnalysis/ch08/#2021-01-06-0130000000-0872914","text":"","title":"2021-01-06 01:30:00+00:00 0.872914"},{"location":"python/DataAnalysis/ch08/#dtype-float64_5","text":"","title":"dtype: float64"},{"location":"python/DataAnalysis/ch08/#tz_localizetz_convertdatetimeindex","text":"print(ts.index.tz_localize('Asia/Shanghai'))","title":"tz_localize\u548ctz_convert\u4e5f\u662fDatetimeIndex\u7684\u5b9e\u4f8b\u65b9\u6cd5\uff1a"},{"location":"python/DataAnalysis/ch08/#datetimeindex2021-01-01-0930000800-2021-01-02-0930000800_1","text":"","title":"DatetimeIndex(['2021-01-01 09:30:00+08:00', '2021-01-02 09:30:00+08:00',"},{"location":"python/DataAnalysis/ch08/#2021-01-03-0930000800-2021-01-04-0930000800_1","text":"","title":"'2021-01-03 09:30:00+08:00', '2021-01-04 09:30:00+08:00',"},{"location":"python/DataAnalysis/ch08/#2021-01-05-0930000800-2021-01-06-0930000800_1","text":"","title":"'2021-01-05 09:30:00+08:00', '2021-01-06 09:30:00+08:00'],"},{"location":"python/DataAnalysis/ch08/#dtypedatetime64ns-asiashanghai-freqnone_1","text":"### \u65f6\u533a\u611f\u77e5\u65f6\u95f4\u6233\u5bf9\u8c61\u7684\u64cd\u4f5c \u4e0e\u65f6\u95f4\u5e8f\u5217\u548c\u65e5\u671f\u8303\u56f4\u7c7b\u4f3c\uff0c\u5355\u72ec\u7684`Timestamp`\u5bf9\u8c61\u4e5f\u53ef\u4ee5\u4ece\u7b80\u5355\u65f6\u95f4\u6233\u672c\u5730\u5316\u4e3a\u65f6\u533a\u611f\u77e5\u65f6\u95f4\u6233\uff0c\u5e76\u4ece\u4e00\u4e2a\u65f6\u533a\u8f6c\u6362\u4e3a\u53e6\u4e00\u4e2a\u65f6\u533a\uff1a stamp = pd.Timestamp('2021-5-1 05:30') print(stamp)","title":"dtype='datetime64[ns, Asia/Shanghai]', freq=None)"},{"location":"python/DataAnalysis/ch08/#2021-05-01-053000","text":"stamp_utc = stamp.tz_localize('utc') print(stamp_utc)","title":"2021-05-01 05:30:00"},{"location":"python/DataAnalysis/ch08/#2021-05-01-0530000000","text":"stamp_sha = stamp_utc.tz_convert('Asia/Shanghai') print(stamp_sha)","title":"2021-05-01 05:30:00+00:00"},{"location":"python/DataAnalysis/ch08/#2021-05-01-1330000800","text":"\u4e5f\u53ef\u4ee5\u5728\u521b\u5efa`Timestamp`\u7684\u65f6\u5019\u4f20\u9012\u4e00\u4e2a\u65f6\u533a\uff1a stamp_sha = pd.Timestamp('2021-5-1 05:30', tz='Asia/Shanghai') print(stamp_sha)","title":"2021-05-01 13:30:00+08:00"},{"location":"python/DataAnalysis/ch08/#2021-05-01-0530000800","text":"`Timestamp`\u5bf9\u8c61\u5185\u90e8\u5b58\u50a8\u4e86\u4e00\u4e2aUnix\u7eaa\u5143(1970\u5e741\u67081\u65e5)\u81f3\u4eca\u7684\u7eb3\u79d2\u6570\u91cfUTC\u65f6\u95f4\u6233\u6570\u503c\uff0c\u8be5\u6570\u503c\u5728\u65f6\u533a\u8f6c\u6362\u4e2d\u662f\u4e0d\u53d8\u7684\uff1a print(stamp_utc.value)","title":"2021-05-01 05:30:00+08:00"},{"location":"python/DataAnalysis/ch08/#1619847000000000000","text":"print(stamp_utc.tz_convert('Asia/Shanghai').value)","title":"1619847000000000000"},{"location":"python/DataAnalysis/ch08/#1619847000000000000_1","text":"\u5728\u4f7f\u7528pandas\u7684`DateOffset`\u8fdb\u884c\u65f6\u95f4\u7b97\u672f\u65f6\uff0cpandas\u5c3d\u53ef\u80fd\u9075\u4ece\u590f\u65f6\u5236\u3002 \u9996\u5148\uff0c\u6784\u9020\u8f6c\u6362\u5230DST\u4e4b\u524d\u768430\u5206\u949f\u7684\u65f6\u95f4\uff1a stamp = pd.Timestamp('2012-3-12 1:30', tz='US/Eastern') print(stamp)","title":"1619847000000000000"},{"location":"python/DataAnalysis/ch08/#2012-03-12-013000-0400","text":"print(stamp + Hour())","title":"2012-03-12 01:30:00-04:00"},{"location":"python/DataAnalysis/ch08/#2012-03-12-023000-0400","text":"\u4e4b\u540e\uff0c\u6784\u5efa\u4eceDST\u8fdb\u884c\u8f6c\u6362\u524d\u768490\u5206\u949f\uff1a stamp = pd.Timestamp('2012-11-04 0:30-04:00', tz='US/Eastern') print(stamp)","title":"2012-03-12 02:30:00-04:00"},{"location":"python/DataAnalysis/ch08/#2012-11-04-003000-0400","text":"print(stamp + 2 * Hour()) # \u53ea\u589e\u52a0\u4e86\u4e00\u5c0f\u65f6","title":"2012-11-04 00:30:00-04:00"},{"location":"python/DataAnalysis/ch08/#2012-11-04-013000-0500","text":"### \u4e0d\u540c\u65f6\u533a\u95f4\u7684\u64cd\u4f5c \u5982\u679c\u4e24\u4e2a\u65f6\u533a\u4e0d\u540c\u7684\u65f6\u95f4\u5e8f\u5217\u9700\u8981\u8054\u5408\uff0c\u90a3\u4e48\u7ed3\u679c\u5c06\u662fUTC\u65f6\u95f4\u7684\uff0c\u56e0\u4e3a\u65f6\u95f4\u6233\u4ee5UTC\u683c\u5f0f\u5b58\u50a8\u3002 rng = pd.date_range('2021/1/1 9:30', periods=9, freq='B') ts = pd.Series(np.random.randn(len(rng)), index=rng) print(ts)","title":"2012-11-04 01:30:00-05:00"},{"location":"python/DataAnalysis/ch08/#2021-01-01-093000-0715681","text":"","title":"2021-01-01 09:30:00 0.715681"},{"location":"python/DataAnalysis/ch08/#2021-01-04-093000-0524563","text":"","title":"2021-01-04 09:30:00 0.524563"},{"location":"python/DataAnalysis/ch08/#2021-01-05-093000-0482199","text":"","title":"2021-01-05 09:30:00 -0.482199"},{"location":"python/DataAnalysis/ch08/#2021-01-06-093000-0661303","text":"","title":"2021-01-06 09:30:00 -0.661303"},{"location":"python/DataAnalysis/ch08/#2021-01-07-093000-1750010","text":"","title":"2021-01-07 09:30:00 1.750010"},{"location":"python/DataAnalysis/ch08/#2021-01-08-093000-0251478","text":"","title":"2021-01-08 09:30:00 0.251478"},{"location":"python/DataAnalysis/ch08/#2021-01-11-093000-1487268","text":"","title":"2021-01-11 09:30:00 -1.487268"},{"location":"python/DataAnalysis/ch08/#2021-01-12-093000-0224024","text":"","title":"2021-01-12 09:30:00 -0.224024"},{"location":"python/DataAnalysis/ch08/#2021-01-13-093000-1621853","text":"","title":"2021-01-13 09:30:00 -1.621853"},{"location":"python/DataAnalysis/ch08/#freq-b-dtype-float64","text":"ts1 = ts[:7].tz_localize('Europe/London') ts2 = ts1[2:].tz_convert('Europe/Moscow') result = ts1 + ts2 print(ts1)","title":"Freq: B, dtype: float64"},{"location":"python/DataAnalysis/ch08/#2021-01-01-0930000000-1393445","text":"","title":"2021-01-01 09:30:00+00:00 -1.393445"},{"location":"python/DataAnalysis/ch08/#2021-01-04-0930000000-1179614","text":"","title":"2021-01-04 09:30:00+00:00 -1.179614"},{"location":"python/DataAnalysis/ch08/#2021-01-05-0930000000-0716669","text":"","title":"2021-01-05 09:30:00+00:00 0.716669"},{"location":"python/DataAnalysis/ch08/#2021-01-06-0930000000-0485656","text":"","title":"2021-01-06 09:30:00+00:00 -0.485656"},{"location":"python/DataAnalysis/ch08/#2021-01-07-0930000000-0433000","text":"","title":"2021-01-07 09:30:00+00:00 0.433000"},{"location":"python/DataAnalysis/ch08/#2021-01-08-0930000000-1540745","text":"","title":"2021-01-08 09:30:00+00:00 1.540745"},{"location":"python/DataAnalysis/ch08/#2021-01-11-0930000000-0343751","text":"","title":"2021-01-11 09:30:00+00:00 0.343751"},{"location":"python/DataAnalysis/ch08/#dtype-float64_6","text":"print(ts2)","title":"dtype: float64"},{"location":"python/DataAnalysis/ch08/#2021-01-05-1230000300-0716669","text":"","title":"2021-01-05 12:30:00+03:00 0.716669"},{"location":"python/DataAnalysis/ch08/#2021-01-06-1230000300-0485656","text":"","title":"2021-01-06 12:30:00+03:00 -0.485656"},{"location":"python/DataAnalysis/ch08/#2021-01-07-1230000300-0433000","text":"","title":"2021-01-07 12:30:00+03:00 0.433000"},{"location":"python/DataAnalysis/ch08/#2021-01-08-1230000300-1540745","text":"","title":"2021-01-08 12:30:00+03:00 1.540745"},{"location":"python/DataAnalysis/ch08/#2021-01-11-1230000300-0343751","text":"","title":"2021-01-11 12:30:00+03:00 0.343751"},{"location":"python/DataAnalysis/ch08/#dtype-float64_7","text":"print(result)","title":"dtype: float64"},{"location":"python/DataAnalysis/ch08/#2021-01-01-0930000000-nan","text":"","title":"2021-01-01 09:30:00+00:00 NaN"},{"location":"python/DataAnalysis/ch08/#2021-01-04-0930000000-nan","text":"","title":"2021-01-04 09:30:00+00:00 NaN"},{"location":"python/DataAnalysis/ch08/#2021-01-05-0930000000-1433337","text":"","title":"2021-01-05 09:30:00+00:00 1.433337"},{"location":"python/DataAnalysis/ch08/#2021-01-06-0930000000-0971312","text":"","title":"2021-01-06 09:30:00+00:00 -0.971312"},{"location":"python/DataAnalysis/ch08/#2021-01-07-0930000000-0866000","text":"","title":"2021-01-07 09:30:00+00:00 0.866000"},{"location":"python/DataAnalysis/ch08/#2021-01-08-0930000000-3081489","text":"","title":"2021-01-08 09:30:00+00:00 3.081489"},{"location":"python/DataAnalysis/ch08/#2021-01-11-0930000000-0687502","text":"","title":"2021-01-11 09:30:00+00:00 0.687502"},{"location":"python/DataAnalysis/ch08/#dtype-float64_8","text":"## \u65f6\u95f4\u533a\u95f4\u548c\u533a\u95f4\u7b97\u672f from datetime import datetime, timedelta import pandas as pd import numpy as np from pandas.tseries.offsets import Hour, Minute, Day, MonthEnd import pytz \u65f6\u95f4\u533a\u95f4\u8868\u793a\u7684\u662f\u65f6\u95f4\u8303\u56f4\u901a\u8fc7\u539f\u7d22\u5f151~202\uff0c\u628a`year`\u548c`quarter`\u8054\u5408\u8d77\u6765\uff0c\u751f\u6210\u65b0\u7d22\u5f15\uff0c\u5e76\u66ff\u6362\u539f\u7d22\u5f15\uff0c\u6bd4\u5982\u4e00\u4e9b\u5929\u3001\u4e00\u4e9b\u6708\u3001\u4e00\u4e9b\u5b63\u5ea6\u6216\u8005\u662f\u4e00\u4e9b\u5e74\u3002 `Period`\u7c7b\u8868\u793a\u7684\u6b63\u662f\u8fd9\u79cd\u6570\u636e\u7c7b\u578b\uff0c\u9700\u8981\u4e00\u4e2a\u5b57\u7b26\u4e32\u6216\u6570\u5b57\u4ee5\u53ca\u9891\u7387\u3002 \u5728\u8fd9\u4e2a\u4f8b\u5b50\u4e2d\uff0c`Period`\u5bf9\u8c61\u8868\u793a\u7684\u662f\u4ece2007\u5e741\u67081\u65e5\u52302007\u5e7412\u670831\u65e5\uff08\u5305\u542b\u5728\u5185\uff09\u7684\u65f6\u95f4\u6bb5\u3002 \u5728\u65f6\u95f4\u6bb5\u4e0a\u589e\u52a0\u6216\u51cf\u53bb\u6574\u6570\u53ef\u4ee5\u65b9\u4fbf\u5730\u6839\u636e\u5b83\u4eec\u7684\u9891\u7387\u8fdb\u884c\u79fb\u4f4d\u3002 p = pd.Period(2020, freq='A-DEC') print(p)","title":"dtype: float64"},{"location":"python/DataAnalysis/ch08/#2020","text":"print(p + 5)","title":"2020"},{"location":"python/DataAnalysis/ch08/#2025","text":"print(p - 5)","title":"2025"},{"location":"python/DataAnalysis/ch08/#2015","text":"\u5982\u679c\u4e24\u4e2a\u533a\u95f4\u62e5\u6709\u76f8\u540c\u7684\u9891\u7387\uff0c\u5219\u5b83\u4eec\u7684\u5dee\u662f\u5b83\u4eec\u4e4b\u95f4\u7684\u5355\u4f4d\u6570\u3002 p1 = pd.Period(2020, freq='A-DEC') p2 = pd.Period(2010, freq='A-DEC') print(p1 - p2)","title":"2015"},{"location":"python/DataAnalysis/ch08/#10-yearends-month12","text":"p1 = pd.Period(2020, freq='Q-DEC') p2 = pd.Period(2010, freq='Q-DEC') print(p1 - p2)","title":"<10 * YearEnds: month=12>"},{"location":"python/DataAnalysis/ch08/#40-quarterends-startingmonth12","text":"\u4f7f\u7528`period_range`\u51fd\u6570\u53ef\u4ee5\u6784\u9020\u89c4\u5219\u533a\u95f4\u5e8f\u5217\u3002`PeriodIndex`\u7c7b\u5b58\u50a8\u7684\u662f\u533a\u95f4\u7684\u5e8f\u5217\uff0c\u53ef\u4ee5\u4f5c\u4e3a\u4efb\u610fpandas\u6570\u636e\u7ed3\u6784\u7684\u8f74\u7d22\u5f15\u3002 data = np.random.randn(6) strings = ['2021Q1', '2021Q2', '2021Q3', '2021Q4', '2022Q1', '2022Q2'] rng = pd.period_range('2001-1-1', '2001-6-30', freq='M') ts = pd.Series(data, index=rng) print(ts)","title":"<40 * QuarterEnds: startingMonth=12>"},{"location":"python/DataAnalysis/ch08/#2001-01-0481408","text":"","title":"2001-01 -0.481408"},{"location":"python/DataAnalysis/ch08/#2001-02-0297590","text":"","title":"2001-02 -0.297590"},{"location":"python/DataAnalysis/ch08/#2001-03-0860354","text":"","title":"2001-03 -0.860354"},{"location":"python/DataAnalysis/ch08/#2001-04-1281540","text":"","title":"2001-04 1.281540"},{"location":"python/DataAnalysis/ch08/#2001-05-1036551","text":"","title":"2001-05 1.036551"},{"location":"python/DataAnalysis/ch08/#2001-06-0522592","text":"","title":"2001-06 -0.522592"},{"location":"python/DataAnalysis/ch08/#freq-m-dtype-float64_7","text":"rng = pd.PeriodIndex(strings, freq='Q-DEC') # \u5b57\u7b26\u4e32\u6570\u7ec4\u4e5f\u53ef\u4ee5\u4f7f\u7528PeriodIndex\u7c7b ts = pd.Series(data, index=rng) print(ts)","title":"Freq: M, dtype: float64"},{"location":"python/DataAnalysis/ch08/#2021q1-2077200","text":"","title":"2021Q1 -2.077200"},{"location":"python/DataAnalysis/ch08/#2021q2-0948796","text":"","title":"2021Q2 -0.948796"},{"location":"python/DataAnalysis/ch08/#2021q3-1104737","text":"","title":"2021Q3 -1.104737"},{"location":"python/DataAnalysis/ch08/#2021q4-0090281","text":"","title":"2021Q4 0.090281"},{"location":"python/DataAnalysis/ch08/#2022q1-0431517","text":"","title":"2022Q1 0.431517"},{"location":"python/DataAnalysis/ch08/#2022q2-1537045","text":"","title":"2022Q2 1.537045"},{"location":"python/DataAnalysis/ch08/#freq-q-dec-dtype-float64","text":"### \u533a\u95f4\u9891\u7387\u8f6c\u6362 \u4f7f\u7528`asfreq`\u53ef\u4ee5\u5c06\u533a\u95f4\u548c`PeriodIndex`\u5bf9\u8c61\u8f6c\u6362\u4e3a\u5176\u4ed6\u7684\u9891\u7387\u3002 \u4f8b\u5982\uff0c\u5047\u8bbe\u6211\u4eec\u6709\u4e00\u4e2a\u5e74\u5ea6\u533a\u95f4\uff0c\u5e76\u4e14\u60f3\u8981\u5728\u4e00\u5e74\u7684\u5f00\u59cb\u6216\u7ed3\u675f\u65f6\u5c06\u5176\u8f6c\u6362\u4e3a\u6708\u5ea6\u533a\u95f4\u3002 \u53ef\u4ee5\u5c06`Period('2020', 'A-DEC')`\u770b\u4f5c\u4e00\u6bb5\u65f6\u95f4\u4e2d\u7684\u4e00\u79cd\u6e38\u6807\uff0c\u5c06\u65f6\u95f4\u6309\u6708\u4efd\u5212\u5206\u3002 p = pd.Period(2020, freq='A-DEC') print(p.asfreq('M', how='start'))","title":"Freq: Q-DEC, dtype: float64"},{"location":"python/DataAnalysis/ch08/#2020-01","text":"print(p.asfreq('M', how='end'))","title":"2020-01"},{"location":"python/DataAnalysis/ch08/#2020-12","text":"\u5982\u679c\u8d22\u5e74\u7ed3\u675f\u4e0d\u572812\u6708\uff0c\u5219\u6bcf\u6708\u5206\u671f\u4f1a\u81ea\u52a8\u8c03\u6574\u3002 \u6309\u5f53\u5e74\u8d22\u5e74\u7ed3\u675f\u8ba1\u7b97\uff0c\u8d77\u59cb\u5e74\u4efd\u5c31\u662f\u4e0a\u4e00\u5e74\u4e86\u3002 p = pd.Period(2020, freq='A-JUN') print(p.asfreq('M', how='start'))","title":"2020-12"},{"location":"python/DataAnalysis/ch08/#2019-07","text":"print(p.asfreq('M', how='end'))","title":"2019-07"},{"location":"python/DataAnalysis/ch08/#2020-06","text":"\u5f53\u4ece\u9ad8\u9891\u7387\u5411\u4f4e\u9891\u7387\u8f6c\u6362\u65f6\uff0cpandas\u6839\u636e\u5b50\u533a\u95f4\u7684\"\u6240\u5c5e\"\u6765\u51b3\u5b9a\u7236\u533a\u95f4\u3002 \u4f8b\u5982\uff0c\u5728A-JUN\u9891\u7387\u4e2d\uff0cAug-2020\u662f2020\u533a\u95f4\u7684\u4e00\u90e8\u5206\uff1a print(p.asfreq('A-JUN')) 2020\u901a\u8fc7\u539f\u7d22\u5f151~202\uff0c\u628a`year`\u548c`quarter`\u8054\u5408\u8d77\u6765\uff0c\u751f\u6210\u65b0\u7d22\u5f15\uff0c\u5e76\u66ff\u6362\u539f\u7d22\u5f15\u3002 \u5b8c\u6574\u7684`PeriodIndex`\u5bf9\u8c61\u6216\u65f6\u95f4\u5e8f\u5217\u53ef\u4ee5\u6309\u7167\u76f8\u540c\u7684\u8bed\u4e49\u8fdb\u884c\u8f6c\u6362\uff1a rng = pd.period_range('2018', '2021', freq='A-DEC') data = np.random.randn(len(rng)) ts = pd.Series(data, index=rng) print(ts)","title":"2020-06"},{"location":"python/DataAnalysis/ch08/#2018-0221634","text":"","title":"2018 0.221634"},{"location":"python/DataAnalysis/ch08/#2019-0392724","text":"","title":"2019 -0.392724"},{"location":"python/DataAnalysis/ch08/#2020-0355022","text":"","title":"2020 -0.355022"},{"location":"python/DataAnalysis/ch08/#2021-0114000","text":"","title":"2021 0.114000"},{"location":"python/DataAnalysis/ch08/#freq-a-dec-dtype-float64","text":"\u4e0b\u9762\u5e74\u5ea6\u533a\u95f4\u5c06\u901a\u8fc7`asfreq`\u88ab\u66ff\u6362\u4e3a\u5bf9\u5e94\u4e8e\u6bcf\u4e2a\u5e74\u5ea6\u533a\u95f4\u5185\u7684\u7b2c\u4e00\u4e2a\u6708\u7684\u6708\u5ea6\u533a\u95f4\u3002 print(ts.asfreq('M', how='start'))","title":"Freq: A-DEC, dtype: float64"},{"location":"python/DataAnalysis/ch08/#2018-01-0681874","text":"","title":"2018-01 0.681874"},{"location":"python/DataAnalysis/ch08/#2019-01-1006585","text":"","title":"2019-01 -1.006585"},{"location":"python/DataAnalysis/ch08/#2020-01-0619142","text":"","title":"2020-01 -0.619142"},{"location":"python/DataAnalysis/ch08/#2021-01-1445820","text":"","title":"2021-01 1.445820"},{"location":"python/DataAnalysis/ch08/#freq-m-dtype-float64_8","text":"\u5982\u679c\u6211\u4eec\u60f3\u8981\u6bcf\u5e74\u6700\u540e\u4e00\u4e2a\u5de5\u4f5c\u65e5\uff0c\u6211\u4eec\u53ef\u4ee5\u4f7f\u7528`B`\u9891\u7387\u6765\u8868\u793a\u6211\u4eec\u60f3\u8981\u7684\u662f\u533a\u95f4\u7684\u672b\u7aef\u3002 print(ts.asfreq('B', how='end'))","title":"Freq: M, dtype: float64"},{"location":"python/DataAnalysis/ch08/#2018-12-31-1520316","text":"","title":"2018-12-31 -1.520316"},{"location":"python/DataAnalysis/ch08/#2019-12-31-0425544","text":"","title":"2019-12-31 -0.425544"},{"location":"python/DataAnalysis/ch08/#2020-12-31-0658073","text":"","title":"2020-12-31 -0.658073"},{"location":"python/DataAnalysis/ch08/#2021-12-31-1206881","text":"","title":"2021-12-31 1.206881"},{"location":"python/DataAnalysis/ch08/#freq-b-dtype-float64_1","text":"### \u5b63\u5ea6\u533a\u95f4\u9891\u7387 \u5b63\u5ea6\u6570\u636e\u662f\u4f1a\u8ba1\u3001\u91d1\u878d\u548c\u5176\u4ed6\u9886\u57df\u7684\u6807\u51c6\u3002 \u5f88\u591a\u5b63\u5ea6\u6570\u636e\u662f\u5728\u8d22\u5e74\u7ed3\u5c3e\u62a5\u544a\u7684\uff0c\u901a\u5e38\u662f\u4e00\u5e7412\u4e2a\u6708\u4e2d\u7684\u6700\u540e\u4e00\u4e2a\u65e5\u5386\u65e5\u6216\u5de5\u4f5c\u65e5\u3002 pandas\u652f\u6301\u6240\u6709\u7684\u53ef\u80fd\u768412\u4e2a\u5b63\u5ea6\u9891\u7387\u4eceQ-JAN\u5230Q-DEC\uff1a \u4e0b\u4f8b\u4e2d\uff0c\u8d22\u5e74\u7ed3\u675f\u4e8e1\u6708\uff0c2020Q4\u884c\u65f6\u95f4\u4e3a\u4e0a\u4e00\u5e7411\u6708\u81f3\u5f53\u5e741\u6708\u3002\u53ef\u4ee5\u901a\u8fc7\u8f6c\u6362\u4e3a\u6bcf\u65e5\u9891\u7387\uff08asfreq\uff09\u8fdb\u884c\u68c0\u67e5\u3002 p = pd.Period('2020Q4', freq='Q-JAN') print(p)","title":"Freq: B, dtype: float64"},{"location":"python/DataAnalysis/ch08/#2020q4","text":"print(p.asfreq('D', 'start'))","title":"2020Q4"},{"location":"python/DataAnalysis/ch08/#2019-11-01","text":"print(p.asfreq('D', 'end'))","title":"2019-11-01"},{"location":"python/DataAnalysis/ch08/#2020-01-31","text":"\u5047\u5982\u8d22\u5e74\u7ed3\u675f\u4e8e2\u6708\uff0c2020Q4\u884c\u65f6\u95f4\u4e3a\u4e0a\u4e00\u5e7412\u6708\u81f3\u5f53\u5e742\u6708\u3002 p = pd.Period('2020Q4', freq='Q-FEB') print(p)","title":"2020-01-31"},{"location":"python/DataAnalysis/ch08/#2020q4_1","text":"print(p.asfreq('D', 'start'))","title":"2020Q4"},{"location":"python/DataAnalysis/ch08/#2019-11-01_1","text":"print(p.asfreq('D', 'end'))","title":"2019-11-01"},{"location":"python/DataAnalysis/ch08/#2020-01-31_1","text":"\u5047\u5982\u8d22\u5e74\u7ed3\u675f\u4e8e4\u6708\uff0c2020Q4\u884c\u65f6\u95f4\u4e3a\u4e0a\u4e00\u5e7412\u6708\u81f3\u5f53\u5e742\u6708\u3002 p = pd.Period('2020Q4', freq='Q-APR') print(p)","title":"2020-01-31"},{"location":"python/DataAnalysis/ch08/#2020q4_2","text":"print(p.asfreq('D', 'start'))","title":"2020Q4"},{"location":"python/DataAnalysis/ch08/#2020-02-01","text":"print(p.asfreq('D', 'end'))","title":"2020-02-01"},{"location":"python/DataAnalysis/ch08/#2020-04-30","text":"\u53ef\u4ee5\u5bf9\u533a\u95f4\u6570\u636e\u505a\u7b97\u672f\u64cd\u4f5c\u3002\u4f8b\u5982\uff0c\u8981\u83b7\u53d6\u5728\u5b63\u5ea6\u5012\u6570\u7b2c\u4e8c\u4e2a\u5de5\u4f5c\u65e5\u4e0b\u53484\u70b9\u7684\u65f6\u95f4\u6233\uff0c\u53ef\u4ee5\u8fd9\u4e48\u505a\uff1a(\u7591\u95ee\uff1a\u8fd9\u91cc\u7684\u53c2\u6570e\u4ee3\u8868\u4ec0\u4e48 ???) p4pm = (p.asfreq('B', 'e') - 1).asfreq('T', 's') + 16 * 60 print(p4pm)","title":"2020-04-30"},{"location":"python/DataAnalysis/ch08/#2020-04-29-1600","text":"print(p4pm.to_timestamp())","title":"2020-04-29 16:00"},{"location":"python/DataAnalysis/ch08/#2020-04-29-160000","text":"\u53ef\u4ee5\u4f7f\u7528`peroid_range`\u751f\u6210\u5b63\u5ea6\u5e8f\u5217\u3002\u5b83\u7684\u7b97\u672f\u4e5f\u662f\u4e00\u6837\u7684\uff1a rng = pd.period_range('2000Q3', '2001Q4', freq='Q-JAN') ts = pd.Series(np.arange(len(rng)), index=rng) print(ts)","title":"2020-04-29 16:00:00"},{"location":"python/DataAnalysis/ch08/#2000q3-0","text":"","title":"2000Q3 0"},{"location":"python/DataAnalysis/ch08/#2000q4-1","text":"","title":"2000Q4 1"},{"location":"python/DataAnalysis/ch08/#2001q1-2","text":"","title":"2001Q1 2"},{"location":"python/DataAnalysis/ch08/#2001q2-3","text":"","title":"2001Q2 3"},{"location":"python/DataAnalysis/ch08/#2001q3-4","text":"","title":"2001Q3 4"},{"location":"python/DataAnalysis/ch08/#2001q4-5","text":"","title":"2001Q4 5"},{"location":"python/DataAnalysis/ch08/#freq-q-jan-dtype-int64","text":"new_rng = (rng.asfreq('B', 'e') - 1).asfreq('T', 's') + 16 * 60 ts.index = new_rng.to_timestamp() print(ts)","title":"Freq: Q-JAN, dtype: int64"},{"location":"python/DataAnalysis/ch08/#1999-10-28-160000-0","text":"","title":"1999-10-28 16:00:00 0"},{"location":"python/DataAnalysis/ch08/#2000-01-28-160000-1","text":"","title":"2000-01-28 16:00:00 1"},{"location":"python/DataAnalysis/ch08/#2000-04-27-160000-2","text":"","title":"2000-04-27 16:00:00 2"},{"location":"python/DataAnalysis/ch08/#2000-07-28-160000-3","text":"","title":"2000-07-28 16:00:00 3"},{"location":"python/DataAnalysis/ch08/#2000-10-30-160000-4","text":"","title":"2000-10-30 16:00:00 4"},{"location":"python/DataAnalysis/ch08/#2001-01-30-160000-5","text":"","title":"2001-01-30 16:00:00 5"},{"location":"python/DataAnalysis/ch08/#dtype-int64","text":"### \u5c06\u65f6\u95f4\u6233\u8f6c\u6362\u4e3a\u533a\u95f4\uff08\u4ee5\u53ca\u9006\u8f6c\u6362\uff09 \u901a\u8fc7\u65f6\u95f4\u6233\u7d22\u5f15\u7684Series\u548cDataFrame\u53ef\u4ee5\u88ab`to_period`\u65b9\u6cd5\u8f6c\u6362\u4e3a\u533a\u95f4\uff1a rng = pd.date_range('2020-01-01', periods=3, freq='M') ts = pd.Series(np.random.randn(3), index=rng) print(ts)","title":"dtype: int64"},{"location":"python/DataAnalysis/ch08/#2020-01-31-0567097","text":"","title":"2020-01-31 -0.567097"},{"location":"python/DataAnalysis/ch08/#2020-02-29-0634521202yearquarter2","text":"","title":"2020-02-29 0.63452\u901a\u8fc7\u539f\u7d22\u5f151~202\uff0c\u628ayear\u548cquarter\u8054\u5408\u8d77\u6765\uff0c\u751f\u6210\u65b0\u7d22\u5f15\uff0c\u5e76\u66ff\u6362\u539f\u7d22\u5f152"},{"location":"python/DataAnalysis/ch08/#2020-03-31-0297777","text":"","title":"2020-03-31 0.297777"},{"location":"python/DataAnalysis/ch08/#freq-m-dtype-float64_9","text":"pts = ts.to_period() print(pts)","title":"Freq: M, dtype: float64"},{"location":"python/DataAnalysis/ch08/#2020-01-0567097","text":"","title":"2020-01 -0.567097"},{"location":"python/DataAnalysis/ch08/#2020-02-0634522","text":"","title":"2020-02 0.634522"},{"location":"python/DataAnalysis/ch08/#2020-03-0297777","text":"","title":"2020-03 0.297777"},{"location":"python/DataAnalysis/ch08/#freq-m-dtype-float64_10","text":"\u7531\u4e8e\u533a\u95f4\u662f\u975e\u91cd\u53e0\u65f6\u95f4\u8303\u56f4\uff0c\u4e00\u4e2a\u65f6\u95f4\u6233\u53ea\u80fd\u5c5e\u4e8e\u7ed9\u5b9a\u9891\u7387\u7684\u5355\u4e2a\u533a\u95f4\u3002 \u5c3d\u7ba1\u9ed8\u8ba4\u60c5\u51b5\u4e0b\u6839\u636e\u65f6\u95f4\u6233\u63a8\u65ad\u51fa\u65b0`PeriodIndex`\u7684\u9891\u7387\uff0c\u4f46\u53ef\u4ee5\u6307\u5b9a\u4efb\u4f55\u60f3\u8981\u7684\u9891\u7387\u3002 \u5728\u7ed3\u679c\u4e2d\u5305\u542b\u91cd\u590d\u7684\u533a\u95f4\u4e5f\u662f\u6ca1\u6709\u95ee\u9898\u7684\u3002 rng = pd.date_range('2020-01-01', periods=6, freq='D') ts = pd.Series(np.random.randn(6), index=rng) print(ts)","title":"Freq: M, dtype: float64"},{"location":"python/DataAnalysis/ch08/#2020-01-01-0111287","text":"","title":"2020-01-01 -0.111287"},{"location":"python/DataAnalysis/ch08/#2020-01-02-1442234","text":"","title":"2020-01-02 1.442234"},{"location":"python/DataAnalysis/ch08/#2020-01-03-0767553","text":"","title":"2020-01-03 -0.767553"},{"location":"python/DataAnalysis/ch08/#2020-01-04-0265064","text":"","title":"2020-01-04 -0.265064"},{"location":"python/DataAnalysis/ch08/#2020-01-05-1200312","text":"","title":"2020-01-05 1.200312"},{"location":"python/DataAnalysis/ch08/#2020-01-06-1782557","text":"","title":"2020-01-06 -1.782557"},{"location":"python/DataAnalysis/ch08/#freq-d-dtype-float64_3","text":"ts_m = ts.to_period('M') # \u6307\u5b9aperiod\u7684\u9891\u7387\uff08M\uff09,\u8f93\u51fa\u7ed3\u679c\u5305\u542b\u91cd\u590dperiod print(ts_m)","title":"Freq: D, dtype: float64"},{"location":"python/DataAnalysis/ch08/#2020-01-0111287","text":"","title":"2020-01 -0.111287"},{"location":"python/DataAnalysis/ch08/#2020-01-1442234","text":"","title":"2020-01 1.442234"},{"location":"python/DataAnalysis/ch08/#2020-01-0767553","text":"","title":"2020-01 -0.767553"},{"location":"python/DataAnalysis/ch08/#2020-01-0265064","text":"","title":"2020-01 -0.265064"},{"location":"python/DataAnalysis/ch08/#2020-01-1200312","text":"","title":"2020-01 1.200312"},{"location":"python/DataAnalysis/ch08/#2020-01-1782557","text":"","title":"2020-01 -1.782557"},{"location":"python/DataAnalysis/ch08/#freq-m-dtype-float64_11","text":"\u4f7f\u7528`to_timestamp`\u53ef\u4ee5\u5c06\u533a\u95f4\u518d\u8f6c\u6362\u4e3a\u65f6\u95f4\u6233\uff1a print(ts_m.to_timestamp(how='end'))","title":"Freq: M, dtype: float64"},{"location":"python/DataAnalysis/ch08/#2020-01-31-235959999999999-0111287","text":"","title":"2020-01-31 23:59:59.999999999 -0.111287"},{"location":"python/DataAnalysis/ch08/#2020-01-31-235959999999999-1442234","text":"","title":"2020-01-31 23:59:59.999999999 1.442234"},{"location":"python/DataAnalysis/ch08/#2020-01-31-235959999999999-0767553","text":"","title":"2020-01-31 23:59:59.999999999 -0.767553"},{"location":"python/DataAnalysis/ch08/#2020-01-31-235959999999999-0265064","text":"","title":"2020-01-31 23:59:59.999999999 -0.265064"},{"location":"python/DataAnalysis/ch08/#2020-01-31-235959999999999-1200312","text":"","title":"2020-01-31 23:59:59.999999999 1.200312"},{"location":"python/DataAnalysis/ch08/#2020-01-31-235959999999999-1782557","text":"","title":"2020-01-31 23:59:59.999999999 -1.782557"},{"location":"python/DataAnalysis/ch08/#dtype-float64_9","text":"print(ts_m.to_timestamp(how='start'))","title":"dtype: float64"},{"location":"python/DataAnalysis/ch08/#2020-01-01-0111287_1","text":"","title":"2020-01-01 -0.111287"},{"location":"python/DataAnalysis/ch08/#2020-01-01-1442234","text":"","title":"2020-01-01 1.442234"},{"location":"python/DataAnalysis/ch08/#2020-01-01-0767553","text":"","title":"2020-01-01 -0.767553"},{"location":"python/DataAnalysis/ch08/#2020-01-01-0265064","text":"","title":"2020-01-01 -0.265064"},{"location":"python/DataAnalysis/ch08/#2020-01-01-1200312","text":"","title":"2020-01-01 1.200312"},{"location":"python/DataAnalysis/ch08/#2020-01-01-1782557","text":"","title":"2020-01-01 -1.782557"},{"location":"python/DataAnalysis/ch08/#dtype-float64_10","text":"### \u4ece\u6570\u7ec4\u751f\u6210PeriodIndex \u56fa\u5b9a\u9891\u7387\u6570\u636e\u96c6\u6709\u65f6\u5b58\u50a8\u5728\u8de8\u8d8a\u591a\u5217\u7684\u65f6\u95f4\u8303\u56f4\u4fe1\u606f\u4e2d\u3002\u4f8b\u5982\uff0c\u5728\u8fd9\u4e2a\u5b8f\u89c2\u7ecf\u6d4e\u6570\u636e\u96c6\u4e2d\uff0c\u5e74\u4efd\u548c\u5b63\u5ea6\u5728\u4e0d\u540c\u5217\u4e2d\uff1a data = pd.read_csv('../examples/macrodata.csv') print(data.head(5))","title":"dtype: float64"},{"location":"python/DataAnalysis/ch08/#year-quarter-realgdp-realcons-unemp-pop-infl-realint","text":"","title":"year quarter realgdp realcons ... unemp pop infl realint"},{"location":"python/DataAnalysis/ch08/#0-19590-10-2710349-17074-58-177146-000-000","text":"","title":"0 1959.0 1.0 2710.349 1707.4 ... 5.8 177.146 0.00 0.00"},{"location":"python/DataAnalysis/ch08/#1-19590-20-2778801-17337-51-177830-234-074","text":"","title":"1 1959.0 2.0 2778.801 1733.7 ... 5.1 177.830 2.34 0.74"},{"location":"python/DataAnalysis/ch08/#2-19590-30-2775488-17518-53-178657-274-109","text":"","title":"2 1959.0 3.0 2775.488 1751.8 ... 5.3 178.657 2.74 1.09"},{"location":"python/DataAnalysis/ch08/#3-19590-40-2785204-17537-56-179386-027-406","text":"","title":"3 1959.0 4.0 2785.204 1753.7 ... 5.6 179.386 0.27 4.06"},{"location":"python/DataAnalysis/ch08/#4-19600-10-2847699-17705-52-180007-231-119","text":"print(data.year)","title":"4 1960.0 1.0 2847.699 1770.5 ... 5.2 180.007 2.31 1.19"},{"location":"python/DataAnalysis/ch08/#0-19590","text":"","title":"0 1959.0"},{"location":"python/DataAnalysis/ch08/#1-19590","text":"","title":"1 1959.0"},{"location":"python/DataAnalysis/ch08/#2-19590","text":"","title":"2 1959.0"},{"location":"python/DataAnalysis/ch08/#3-19590","text":"","title":"3 1959.0"},{"location":"python/DataAnalysis/ch08/#4-19600","text":"","title":"4 1960.0"},{"location":"python/DataAnalysis/ch08/#_10","text":"","title":"..."},{"location":"python/DataAnalysis/ch08/#198-20080","text":"","title":"198 2008.0"},{"location":"python/DataAnalysis/ch08/#199-20080","text":"","title":"199 2008.0"},{"location":"python/DataAnalysis/ch08/#200-20090","text":"","title":"200 2009.0"},{"location":"python/DataAnalysis/ch08/#201-20090","text":"","title":"201 2009.0"},{"location":"python/DataAnalysis/ch08/#202-20090","text":"","title":"202 2009.0"},{"location":"python/DataAnalysis/ch08/#name-year-length-203-dtype-float64","text":"print(data.quarter)","title":"Name: year, Length: 203, dtype: float64"},{"location":"python/DataAnalysis/ch08/#0-10","text":"","title":"0 1.0"},{"location":"python/DataAnalysis/ch08/#1-20","text":"","title":"1 2.0"},{"location":"python/DataAnalysis/ch08/#2-30","text":"","title":"2 3.0"},{"location":"python/DataAnalysis/ch08/#3-40","text":"","title":"3 4.0"},{"location":"python/DataAnalysis/ch08/#4-10","text":"","title":"4 1.0"},{"location":"python/DataAnalysis/ch08/#_11","text":"","title":"..."},{"location":"python/DataAnalysis/ch08/#198-30","text":"","title":"198 3.0"},{"location":"python/DataAnalysis/ch08/#199-40","text":"","title":"199 4.0"},{"location":"python/DataAnalysis/ch08/#200-10","text":"","title":"200 1.0"},{"location":"python/DataAnalysis/ch08/#201-20","text":"","title":"201 2.0"},{"location":"python/DataAnalysis/ch08/#202-30","text":"","title":"202 3.0"},{"location":"python/DataAnalysis/ch08/#name-quarter-length-203-dtype-float64","text":"\u901a\u8fc7\u5c06\u8fd9\u4e9b\u6570\u7ec4\u548c\u9891\u7387\u4f20\u9012\u7ed9`PeriodIndex`\uff0c\u53ef\u4ee5\u8054\u5408\u5f62\u6210DataFrame\u7684\u7d22\u5f15 index = pd.PeriodIndex(year=data.year, quarter=data.quarter, freq='Q-DEC') print(index)","title":"Name: quarter, Length: 203, dtype: float64"},{"location":"python/DataAnalysis/ch08/#periodindex1959q1-1959q2-1959q3-1959q4-1960q1-1960q2","text":"","title":"PeriodIndex(['1959Q1', '1959Q2', '1959Q3', '1959Q4', '1960Q1', '1960Q2',"},{"location":"python/DataAnalysis/ch08/#1960q3-1960q4-1961q1-1961q2","text":"","title":"'1960Q3', '1960Q4', '1961Q1', '1961Q2',"},{"location":"python/DataAnalysis/ch08/#_12","text":"","title":"..."},{"location":"python/DataAnalysis/ch08/#2007q2-2007q3-2007q4-2008q1-2008q2-2008q3","text":"","title":"'2007Q2', '2007Q3', '2007Q4', '2008Q1', '2008Q2', '2008Q3',"},{"location":"python/DataAnalysis/ch08/#2008q4-2009q1-2009q2-2009q3","text":"","title":"'2008Q4', '2009Q1', '2009Q2', '2009Q3'],"},{"location":"python/DataAnalysis/ch08/#dtypeperiodq-dec-length203","text":"data.index = index # \u901a\u8fc7\u539f\u7d22\u5f151~202\uff0c\u628ayear\u548cquarter\u8054\u5408\u8d77\u6765\uff0c\u751f\u6210\u65b0\u7d22\u5f15\uff0c\u5e76\u66ff\u6362\u539f\u7d22\u5f15 print(data.infl)","title":"dtype='period[Q-DEC]', length=203)"},{"location":"python/DataAnalysis/ch08/#1959q1-000","text":"","title":"1959Q1 0.00"},{"location":"python/DataAnalysis/ch08/#1959q2-234","text":"","title":"1959Q2 2.34"},{"location":"python/DataAnalysis/ch08/#1959q3-274","text":"","title":"1959Q3 2.74"},{"location":"python/DataAnalysis/ch08/#1959q4-027","text":"","title":"1959Q4 0.27"},{"location":"python/DataAnalysis/ch08/#1960q1-231","text":"","title":"1960Q1 2.31"},{"location":"python/DataAnalysis/ch08/#_13","text":"","title":"..."},{"location":"python/DataAnalysis/ch08/#2008q3-316","text":"","title":"2008Q3 -3.16"},{"location":"python/DataAnalysis/ch08/#2008q4-879","text":"","title":"2008Q4 -8.79"},{"location":"python/DataAnalysis/ch08/#2009q1-094","text":"","title":"2009Q1 0.94"},{"location":"python/DataAnalysis/ch08/#2009q2-337","text":"","title":"2009Q2 3.37"},{"location":"python/DataAnalysis/ch08/#2009q3-356","text":"","title":"2009Q3 3.56"},{"location":"python/DataAnalysis/ch08/#freq-q-dec-name-infl-length-203-dtype-float64","text":"## \u91cd\u65b0\u91c7\u6837\u9891\u7387\u8f6c\u6362 import pandas as pd import numpy as np from pandas.tseries.frequencies import to_offset \u91cd\u65b0\u91c7\u6837\u662f\u6307\u5c06\u65f6\u95f4\u5e8f\u5217\u4ece\u4e00\u4e2a\u9891\u7387\u8f6c\u6362\u4e3a\u53e6\u4e00\u4e2a\u9891\u7387\u7684\u8fc7\u7a0b\u3002 \u5c06\u66f4\u9ad8\u9891\u7387\u7684\u6570\u636e\u805a\u5408\u5230\u4f4e\u9891\u7387\u88ab\u79f0\u4e3a\u5411\u4e0b\u91c7\u6837\uff0c\u800c\u4ece\u4f4e\u9891\u7387\u8f6c\u6362\u5230\u9ad8\u9891\u7387\u79f0\u4e3a\u5411\u4e0a\u91c7\u6837\u3002 \u5e76\u4e0d\u662f\u6240\u6709\u7684\u91cd\u65b0\u91c7\u6837\u90fd\u5c5e\u4e8e\u4e0a\u9762\u8bf4\u7684\u4e24\u7c7b\u3002\u4f8b\u5982\uff0c\u5c06W-WED\uff08weekly on Wednesday\uff0c\u6bcf\u5468\u4e09\uff09\u8f6c\u6362\u5230W-FRI\uff08\u6bcf\u5468\u4e94\uff09\u65e2\u4e0d\u662f\u5411\u4e0a\u91c7\u6837\u4e5f\u4e0d\u662f\u5411\u4e0b\u91c7\u6837\u3002 pandas\u5bf9\u8c61\u90fd\u914d\u6709`resample`\u65b9\u6cd5\uff0c\u8be5\u65b9\u6cd5\u662f\u6240\u6709\u9891\u7387\u8f6c\u6362\u7684\u5de5\u5177\u51fd\u6570\u3002`resample`\u62e5\u6709\u7c7b\u4f3c\u4e8e`groupby`\u7684API\uff1b\u8c03\u7528`resample`\u5bf9\u6570\u636e\u5206\u7ec4\uff0c\u4e4b\u540e\u518d\u8c03\u7528\u805a\u5408\u51fd\u6570\uff1a ### resample\u65b9\u6cd5\u53c2\u6570 \u53c2\u6570 * freq: \u8868\u793a\u91cd\u91c7\u6837\u9891\u7387\uff0c\u4f8b\u5982\u2018M'\u3001\u20185min'\uff0cSecond(15) * how='mean': \u7528\u4e8e\u4ea7\u751f\u805a\u5408\u503c\u7684\u51fd\u6570\u540d\u6216\u6570\u7ec4\u51fd\u6570\uff0c\u4f8b\u5982\u2018mean'\u3001\u2018ohlc'\u3001np.max\u7b49\uff0c\u9ed8\u8ba4\u662f\u2018mean'\uff0c\u5176\u4ed6\u5e38\u7528\u7684\u503c\u7531\uff1a\u2018first'\u3001\u2018last'\u3001\u2018median'\u3001\u2018max'\u3001\u2018min' * axis=0: \u9ed8\u8ba4\u662f\u7eb5\u8f74\uff0c\u6a2a\u8f74\u8bbe\u7f6eaxis=1 * fill_method = None: \u5347\u91c7\u6837\u65f6\u5982\u4f55\u63d2\u503c\uff0c\u6bd4\u5982\u2018ffill'\u3001\u2018bfill'\u7b49 * closed = \u2018right': \u5728\u964d\u91c7\u6837\u65f6\uff0c\u5404\u65f6\u95f4\u6bb5\u7684\u54ea\u4e00\u6bb5\u662f\u95ed\u5408\u7684\uff0c\u2018right'\u6216\u2018left'\uff0c\u9ed8\u8ba4\u2018right' * label= \u2018right': \u5728\u964d\u91c7\u6837\u65f6\uff0c\u5982\u4f55\u8bbe\u7f6e\u805a\u5408\u503c\u7684\u6807\u7b7e\uff0c\u4f8b\u5982\uff0c9\uff1a30-9\uff1a35\u4f1a\u88ab\u6807\u8bb0\u62109\uff1a30\u8fd8\u662f9\uff1a35,\u9ed8\u8ba49\uff1a35 * loffset = None: \u9762\u5143\u6807\u7b7e\u7684\u65f6\u95f4\u6821\u6b63\u503c\uff0c\u6bd4\u5982\u2018-1s'\u6216Second(-1)\u7528\u4e8e\u5c06\u805a\u5408\u6807\u7b7e\u8c03\u65e91\u79d2 * limit=None: \u5728\u5411\u524d\u6216\u5411\u540e\u586b\u5145\u65f6\uff0c\u5141\u8bb8\u586b\u5145\u7684\u6700\u5927\u65f6\u671f\u6570 * kind = None: \u805a\u5408\u5230\u65f6\u671f\uff08\u2018period'\uff09\u6216\u65f6\u95f4\u6233\uff08\u2018timestamp'\uff09\uff0c\u9ed8\u8ba4\u805a\u5408\u5230\u65f6\u95f4\u5e8f\u5217\u7684\u7d22\u5f15\u7c7b\u578b * convention = None: \u5f53\u91cd\u91c7\u6837\u65f6\u671f\u65f6\uff0c\u5c06\u4f4e\u9891\u7387\u8f6c\u6362\u5230\u9ad8\u9891\u7387\u6240\u91c7\u7528\u7684\u7ea6\u5b9a\uff08start\u6216end\uff09\u3002\u9ed8\u8ba4\u2018end' rng = pd.date_range('2020-1-1', periods=100, freq='D') ts = pd.Series(np.random.randn(len(rng)), index=rng) print(ts)","title":"Freq: Q-DEC, Name: infl, Length: 203, dtype: float64"},{"location":"python/DataAnalysis/ch08/#2020-01-01-0802409","text":"","title":"2020-01-01 0.802409"},{"location":"python/DataAnalysis/ch08/#2020-01-02-1147130","text":"","title":"2020-01-02 -1.147130"},{"location":"python/DataAnalysis/ch08/#2020-01-03-1076115","text":"","title":"2020-01-03 -1.076115"},{"location":"python/DataAnalysis/ch08/#2020-01-04-2097443","text":"","title":"2020-01-04 -2.097443"},{"location":"python/DataAnalysis/ch08/#2020-01-05-0577671","text":"","title":"2020-01-05 0.577671"},{"location":"python/DataAnalysis/ch08/#_14","text":"","title":"..."},{"location":"python/DataAnalysis/ch08/#2020-04-05-0110747","text":"","title":"2020-04-05 -0.110747"},{"location":"python/DataAnalysis/ch08/#2020-04-06-0132867","text":"","title":"2020-04-06 0.132867"},{"location":"python/DataAnalysis/ch08/#2020-04-07-0294061","text":"","title":"2020-04-07 -0.294061"},{"location":"python/DataAnalysis/ch08/#2020-04-08-0246155","text":"","title":"2020-04-08 -0.246155"},{"location":"python/DataAnalysis/ch08/#2020-04-09-0927194","text":"","title":"2020-04-09 0.927194"},{"location":"python/DataAnalysis/ch08/#freq-d-length-100-dtype-float64","text":"print(ts.resample('M'))","title":"Freq: D, Length: 100, dtype: float64"},{"location":"python/DataAnalysis/ch08/#datetimeindexresampler-freq-axis0-closedright-labelright-conventionstart-originstart_day","text":"print(ts.resample('M').mean()) # \u628a100\u5929\u7684\u6570\u636e\u6309\u6708groupby\uff0c\u5e76\u8f93\u51fa\u6708\u672b\u6700\u540e\u4e00\u5929\uff0c\u8ba1\u7b97\u5e73\u5747\u503c","title":"DatetimeIndexResampler [freq=, axis=0, closed=right, label=right, convention=start, origin=start_day]"},{"location":"python/DataAnalysis/ch08/#2020-01-31-0311714","text":"","title":"2020-01-31 -0.311714"},{"location":"python/DataAnalysis/ch08/#2020-02-29-0121526","text":"","title":"2020-02-29 0.121526"},{"location":"python/DataAnalysis/ch08/#2020-03-31-0051131","text":"","title":"2020-03-31 -0.051131"},{"location":"python/DataAnalysis/ch08/#2020-04-30-0273113","text":"","title":"2020-04-30 -0.273113"},{"location":"python/DataAnalysis/ch08/#freq-m-dtype-float64_12","text":"print(ts.resample('M', kind='period').mean()) # # \u628a100\u5929\u7684\u6570\u636e\u6309\u6708groupby\uff0c\u5e76\u8f93\u51fa\u6708\u4efd\uff08\u53c2\u6570period\uff09\uff0c\u8ba1\u7b97\u5e73\u5747\u503c","title":"Freq: M, dtype: float64"},{"location":"python/DataAnalysis/ch08/#2020-01-0311714","text":"","title":"2020-01 -0.311714"},{"location":"python/DataAnalysis/ch08/#2020-02-0121526","text":"","title":"2020-02 0.121526"},{"location":"python/DataAnalysis/ch08/#2020-03-0051131","text":"","title":"2020-03 -0.051131"},{"location":"python/DataAnalysis/ch08/#2020-04-0273113","text":"","title":"2020-04 -0.273113"},{"location":"python/DataAnalysis/ch08/#freq-m-dtype-float64_13","text":"### \u5411\u4e0b\u91c7\u6837 \u5c06\u6570\u636e\u805a\u5408\u5230\u4e00\u4e2a\u89c4\u5219\u7684\u4f4e\u9891\u7387\u4e0a\u662f\u4e00\u4e2a\u5e38\u89c1\u7684\u65f6\u95f4\u5e8f\u5217\u4efb\u52a1\u3002 \u8981\u805a\u5408\u7684\u6570\u636e\u4e0d\u5fc5\u662f\u56fa\u5b9a\u9891\u7387\u7684\u3002 \u671f\u671b\u7684\u9891\u7387\u5b9a\u4e49\u4e86\u7528\u4e8e\u5bf9\u65f6\u95f4\u5e8f\u5217\u5207\u7247\u4ee5\u805a\u5408\u7684\u7bb1\u4f53\u8fb9\u754c\u3002\u4f8b\u5982\uff0c\u8981\u5c06\u65f6\u95f4\u8f6c\u6362\u4e3a\u6bcf\u6708\uff0c`M`\u6216`BM`\uff0c\u5219\u9700\u8981\u5c06\u6570\u636e\u5206\u6210\u4e00\u4e2a\u6708\u7684\u65f6\u95f4\u95f4\u9694\u3002 \u6bcf\u4e2a\u95f4\u9694\u662f\u534a\u95ed\u5408\u7684\uff0c\u4e00\u4e2a\u6570\u636e\u70b9\u53ea\u80fd\u5c5e\u4e8e\u4e00\u4e2a\u65f6\u95f4\u95f4\u9694\uff0c\u65f6\u95f4\u95f4\u9694\u7684\u5e76\u96c6\u5fc5\u987b\u662f\u6574\u4e2a\u65f6\u95f4\u5e27\u3002 \u5728\u4f7f\u7528resample\u8fdb\u884c\u5411\u4e0b\u91c7\u6837\u6570\u636e\u65f6\u6709\u4e9b\u4e8b\u60c5\u9700\u8981\u8003\u8651\uff1a * \u6bcf\u6bb5\u95f4\u9694\u7684\u54ea\u4e00\u8fb9\u662f\u95ed\u5408\u7684\u3002 * \u5982\u4f55\u5728\u95f4\u9694\u7684\u8d77\u59cb\u6216\u7ed3\u675f\u4f4d\u7f6e\u6807\u8bb0\u6bcf\u4e2a\u5df2\u805a\u5408\u7684\u7bb1\u4f53\u3002 rng = pd.date_range('2020-1-1', periods=12, freq='T') ts = pd.Series(np.arange(12), index=rng) print(ts)","title":"Freq: M, dtype: float64"},{"location":"python/DataAnalysis/ch08/#2020-01-01-000000-0","text":"","title":"2020-01-01 00:00:00 0"},{"location":"python/DataAnalysis/ch08/#2020-01-01-000100-1","text":"","title":"2020-01-01 00:01:00 1"},{"location":"python/DataAnalysis/ch08/#2020-01-01-000200-2","text":"","title":"2020-01-01 00:02:00 2"},{"location":"python/DataAnalysis/ch08/#2020-01-01-000300-3","text":"","title":"2020-01-01 00:03:00 3"},{"location":"python/DataAnalysis/ch08/#2020-01-01-000400-4","text":"","title":"2020-01-01 00:04:00 4"},{"location":"python/DataAnalysis/ch08/#2020-01-01-000500-5","text":"","title":"2020-01-01 00:05:00 5"},{"location":"python/DataAnalysis/ch08/#2020-01-01-000600-6","text":"","title":"2020-01-01 00:06:00 6"},{"location":"python/DataAnalysis/ch08/#2020-01-01-000700-7","text":"","title":"2020-01-01 00:07:00 7"},{"location":"python/DataAnalysis/ch08/#2020-01-01-000800-8","text":"","title":"2020-01-01 00:08:00 8"},{"location":"python/DataAnalysis/ch08/#2020-01-01-000900-9","text":"","title":"2020-01-01 00:09:00 9"},{"location":"python/DataAnalysis/ch08/#2020-01-01-001000-10","text":"","title":"2020-01-01 00:10:00 10"},{"location":"python/DataAnalysis/ch08/#2020-01-01-001100-11","text":"","title":"2020-01-01 00:11:00 11"},{"location":"python/DataAnalysis/ch08/#freq-t-dtype-int64","text":"\u6309\u4e94\u5206\u949f\u9891\u7387\u805a\u5408\u5206\u7ec4\uff0c\u8ba1\u7b97\u6bcf\u4e00\u7ec4\u7684\u52a0\u548c\u3002\u9891\u7387\u6309\u4e94\u5206\u949f\u7684\u589e\u91cf\u5b9a\u4e49\u4e86\u7bb1\u4f53\u8fb9\u754c\u3002 \u9ed8\u8ba4\u60c5\u51b5\u4e0b\uff0c\u5de6\u7bb1\u4f53\u8fb9\u754c\u662f\u5305\u542b\u7684\uff0c\u56e0\u6b6400:00\u7684\u503c\u662f\u5305\u542b\u572800:00\u523000:05\u95f4\u9694\u5185\u7684\u3002 \u4f20\u9012`closed='right'`\u5c06\u95f4\u9694\u7684\u95ed\u5408\u7aef\u6539\u4e3a\u4e86\u53f3\u8fb9\u3002 \u5206\u7ec4\uff1a * left: [00:00,00:01,00:02,00:03,00:04],[00:05,00:06,00:07,00:08,00:09],[00:10,00:11] * right:[00:00],[00:01,00:02,00:03,00:04,00:05],[00:06,00:07,00:08,00:09,00:10],[00:11] result = ts.resample('5min', closed='right').sum() print(result)","title":"Freq: T, dtype: int64"},{"location":"python/DataAnalysis/ch08/#2019-12-31-235500-0","text":"","title":"2019-12-31 23:55:00 0"},{"location":"python/DataAnalysis/ch08/#2020-01-01-000000-15","text":"","title":"2020-01-01 00:00:00 15"},{"location":"python/DataAnalysis/ch08/#2020-01-01-000500-40","text":"","title":"2020-01-01 00:05:00 40"},{"location":"python/DataAnalysis/ch08/#2020-01-01-001000-11","text":"","title":"2020-01-01 00:10:00 11"},{"location":"python/DataAnalysis/ch08/#freq-5t-dtype-int64","text":"result = ts.resample('5min', closed='left').sum() print(result)","title":"Freq: 5T, dtype: int64"},{"location":"python/DataAnalysis/ch08/#2020-01-01-000000-10","text":"","title":"2020-01-01 00:00:00 10"},{"location":"python/DataAnalysis/ch08/#2020-01-01-000500-35","text":"","title":"2020-01-01 00:05:00 35"},{"location":"python/DataAnalysis/ch08/#2020-01-01-001000-21","text":"","title":"2020-01-01 00:10:00 21"},{"location":"python/DataAnalysis/ch08/#freq-5t-dtype-int64_1","text":"\u6700\u540e\uff0c\u5c06\u7ed3\u679c\u7d22\u5f15\u79fb\u52a8\u4e00\u5b9a\u7684\u6570\u91cf\uff0c\u4f8b\u5982\u4ece\u53f3\u8fb9\u7f18\u51cf\u53bb\u4e00\u79d2\uff0c\u4ee5\u4f7f\u5176\u66f4\u6e05\u695a\u5730\u8868\u660e\u65f6\u95f4\u6233\u6240\u6307\u7684\u95f4\u9694\u3002 \u8981\u5b9e\u73b0\u8fd9\u4e2a\u529f\u80fd\uff0c\u5411`loffset`\u4f20\u9012\u5b57\u7b26\u4e32\u6216\u65e5\u671f\u504f\u7f6e\uff1a result = ts.resample('5min', closed='right', label='right', loffset='-1s').sum() print(result)","title":"Freq: 5T, dtype: int64"},{"location":"python/DataAnalysis/ch08/#2019-12-31-235959-0","text":"","title":"2019-12-31 23:59:59 0"},{"location":"python/DataAnalysis/ch08/#2020-01-01-000459-15","text":"","title":"2020-01-01 00:04:59 15"},{"location":"python/DataAnalysis/ch08/#2020-01-01-000959-40","text":"","title":"2020-01-01 00:09:59 40"},{"location":"python/DataAnalysis/ch08/#2020-01-01-001459-11","text":"","title":"2020-01-01 00:14:59 11"},{"location":"python/DataAnalysis/ch08/#freq-5t-dtype-int64_2","text":"","title":"Freq: 5T, dtype: int64"},{"location":"python/DataAnalysis/ch08/#futurewarning-loffset-in-resample-and-in-grouper-is-deprecated","text":"","title":"FutureWarning: 'loffset' in .resample() and in Grouper() is deprecated."},{"location":"python/DataAnalysis/ch08/#dfresamplefreq3s-loffset8h","text":"","title":">>> df.resample(freq=\"3s\", loffset=\"8H\")"},{"location":"python/DataAnalysis/ch08/#becomes","text":"","title":"becomes:"},{"location":"python/DataAnalysis/ch08/#from-pandastseriesfrequencies-import-to_offset","text":"","title":">>> from pandas.tseries.frequencies import to_offset"},{"location":"python/DataAnalysis/ch08/#df-dfresamplefreq3smean","text":"","title":">>> df = df.resample(freq=\"3s\").mean()"},{"location":"python/DataAnalysis/ch08/#dfindex-dfindexto_timestamp-to_offset8h","text":"#### \u5f00\u7aef-\u5cf0\u503c-\u8c37\u503c-\u7ed3\u675f\uff08OHLC\uff09\u91cd\u65b0\u91c7\u6837 \u5728\u91d1\u878d\u4e2d\uff0c\u4e3a\u6bcf\u4e2a\u6570\u636e\u6876\u8ba1\u7b97\u56db\u4e2a\u503c\u662f\u4e00\u79cd\u6d41\u884c\u7684\u65f6\u95f4\u5e8f\u5217\u805a\u5408\u65b9\u6cd5\uff1a\u7b2c\u4e00\u4e2a\u503c\uff08\u5f00\u7aef\uff09\u3001\u6700\u540e\u4e00\u4e2a\u503c\uff08\u7ed3\u675f\uff09\u3001\u6700\u5927\u503c\uff08\u5cf0\u503c\uff09\u548c\u6700\u5c0f\u503c\uff08\u8c37\u503c\uff09\u3002 \u901a\u8fc7\u4f7f\u7528`ohlc`\u805a\u5408\u51fd\u6570\u53d6\u5f97\u5305\u542b\u56db\u79cd\u805a\u5408\u503c\u5217\u7684DataFrame\uff0c\u8fd9\u4e9b\u503c\u5728\u6570\u636e\u7684\u5355\u6b21\u626b\u63cf\u4e2d\u88ab\u9ad8\u6548\u8ba1\u7b97\uff1a result = ts.resample('5min').ohlc() print(result)","title":">>> df.index = df.index.to_timestamp() + to_offset(\"8H\")"},{"location":"python/DataAnalysis/ch08/#open-high-low-close","text":"","title":"open high low close"},{"location":"python/DataAnalysis/ch08/#2020-01-01-000000-0-4-0-4","text":"","title":"2020-01-01 00:00:00 0 4 0 4"},{"location":"python/DataAnalysis/ch08/#2020-01-01-000500-5-9-5-9","text":"","title":"2020-01-01 00:05:00 5 9 5 9"},{"location":"python/DataAnalysis/ch08/#2020-01-01-001000-10-11-10-11","text":"### \u5411\u4e0a\u91c7\u6837\u4e0e\u63d2\u503c \u5f53\u4ece\u4f4e\u9891\u7387\u8f6c\u6362\u4e3a\u9ad8\u9891\u7387\u65f6\uff0c\u5e76\u4e0d\u9700\u8981\u4efb\u4f55\u805a\u5408\u3002 df = pd.DataFrame( np.random.randn(2, 4), index=pd.date_range('2020/1/1', periods=2, freq='W-WED'), columns=['Colorado', 'Texas', 'New York', 'Ohio'] ) print(df)","title":"2020-01-01 00:10:00 10 11 10 11"},{"location":"python/DataAnalysis/ch08/#colorado-texas-new-york-ohio","text":"","title":"Colorado Texas New York Ohio"},{"location":"python/DataAnalysis/ch08/#2020-01-01-0228758-0758718-0025410-1001819","text":"","title":"2020-01-01 -0.228758 -0.758718 -0.025410 -1.001819"},{"location":"python/DataAnalysis/ch08/#2020-01-08-0704541-0261414-0863335-0267101","text":"df_daily = df.resample('W-WED').sum() print(df_daily)","title":"2020-01-08 -0.704541 -0.261414 -0.863335 0.267101"},{"location":"python/DataAnalysis/ch08/#colorado-texas-new-york-ohio_1","text":"","title":"Colorado Texas New York Ohio"},{"location":"python/DataAnalysis/ch08/#2020-01-01-0228758-0758718-0025410-1001819_1","text":"","title":"2020-01-01 -0.228758 -0.758718 -0.025410 -1.001819"},{"location":"python/DataAnalysis/ch08/#2020-01-08-0704541-0261414-0863335-0267101_1","text":"df_daily = df.resample('D').sum() print(df_daily)","title":"2020-01-08 -0.704541 -0.261414 -0.863335 0.267101"},{"location":"python/DataAnalysis/ch08/#colorado-texas-new-york-ohio_2","text":"","title":"Colorado Texas New York Ohio"},{"location":"python/DataAnalysis/ch08/#2020-01-01-0228758-0758718-0025410-1001819_2","text":"","title":"2020-01-01 -0.228758 -0.758718 -0.025410 -1.001819"},{"location":"python/DataAnalysis/ch08/#2020-01-02-0000000-0000000-0000000-0000000","text":"","title":"2020-01-02 0.000000 0.000000 0.000000 0.000000"},{"location":"python/DataAnalysis/ch08/#2020-01-03-0000000-0000000-0000000-0000000","text":"","title":"2020-01-03 0.000000 0.000000 0.000000 0.000000"},{"location":"python/DataAnalysis/ch08/#2020-01-04-0000000-0000000-0000000-0000000","text":"","title":"2020-01-04 0.000000 0.000000 0.000000 0.000000"},{"location":"python/DataAnalysis/ch08/#2020-01-05-0000000-0000000-0000000-0000000","text":"","title":"2020-01-05 0.000000 0.000000 0.000000 0.000000"},{"location":"python/DataAnalysis/ch08/#2020-01-06-0000000-0000000-0000000-0000000","text":"","title":"2020-01-06 0.000000 0.000000 0.000000 0.000000"},{"location":"python/DataAnalysis/ch08/#2020-01-07-0000000-0000000-0000000-0000000","text":"","title":"2020-01-07 0.000000 0.000000 0.000000 0.000000"},{"location":"python/DataAnalysis/ch08/#2020-01-08-0704541-0261414-0863335-0267101_2","text":"\u5f53\u5bf9\u8fd9\u4e9b\u6570\u636e\u4f7f\u7528\u805a\u5408\u51fd\u6570\u65f6\uff0c\u6bcf\u4e00\u7ec4\u53ea\u6709\u4e00\u4e2a\u503c\uff0c\u5e76\u4e14\u4f1a\u5728\u95f4\u9699\u4e2d\u4ea7\u751f\u7f3a\u5931\u503c\u3002 \u4f7f\u7528`asfreq`\u65b9\u6cd5\u5728\u4e0d\u805a\u5408\u7684\u60c5\u51b5\u4e0b\u8f6c\u6362\u5230\u9ad8\u9891\u7387\uff1a df_daily = df.resample('D').asfreq() print(df_daily)","title":"2020-01-08 -0.704541 -0.261414 -0.863335 0.267101"},{"location":"python/DataAnalysis/ch08/#colorado-texas-new-york-ohio_3","text":"","title":"Colorado Texas New York Ohio"},{"location":"python/DataAnalysis/ch08/#2020-01-01-0228758-0758718-0025410-1001819_3","text":"","title":"2020-01-01 -0.228758 -0.758718 -0.025410 -1.001819"},{"location":"python/DataAnalysis/ch08/#2020-01-02-nan-nan-nan-nan","text":"","title":"2020-01-02 NaN NaN NaN NaN"},{"location":"python/DataAnalysis/ch08/#2020-01-03-nan-nan-nan-nan","text":"","title":"2020-01-03 NaN NaN NaN NaN"},{"location":"python/DataAnalysis/ch08/#2020-01-04-nan-nan-nan-nan","text":"","title":"2020-01-04 NaN NaN NaN NaN"},{"location":"python/DataAnalysis/ch08/#2020-01-05-nan-nan-nan-nan","text":"","title":"2020-01-05 NaN NaN NaN NaN"},{"location":"python/DataAnalysis/ch08/#2020-01-06-nan-nan-nan-nan","text":"","title":"2020-01-06 NaN NaN NaN NaN"},{"location":"python/DataAnalysis/ch08/#2020-01-07-nan-nan-nan-nan","text":"","title":"2020-01-07 NaN NaN NaN NaN"},{"location":"python/DataAnalysis/ch08/#2020-01-08-0704541-0261414-0863335-0267101_3","text":"\u5728\u975e\u661f\u671f\u4e09\u7684\u65e5\u671f\u4e0a\u5411\u524d\u586b\u5145\u6bcf\u5468\u6570\u503c\u3002`fillna`\u548c`reindex`\u65b9\u6cd5\u4e2d\u53ef\u7528\u7684\u586b\u5145\u6216\u63d2\u503c\u65b9\u6cd5\u53ef\u7528\u4e8e\u91cd\u91c7\u6837\uff1a df_daily = df.resample('D').ffill() print(df_daily)","title":"2020-01-08 -0.704541 -0.261414 -0.863335 0.267101"},{"location":"python/DataAnalysis/ch08/#colorado-texas-new-york-ohio_4","text":"","title":"Colorado Texas New York Ohio"},{"location":"python/DataAnalysis/ch08/#2020-01-01-0228758-0758718-0025410-1001819_4","text":"","title":"2020-01-01 -0.228758 -0.758718 -0.025410 -1.001819"},{"location":"python/DataAnalysis/ch08/#2020-01-02-0228758-0758718-0025410-1001819","text":"","title":"2020-01-02 -0.228758 -0.758718 -0.025410 -1.001819"},{"location":"python/DataAnalysis/ch08/#2020-01-03-0228758-0758718-0025410-1001819","text":"","title":"2020-01-03 -0.228758 -0.758718 -0.025410 -1.001819"},{"location":"python/DataAnalysis/ch08/#2020-01-04-0228758-0758718-0025410-1001819","text":"","title":"2020-01-04 -0.228758 -0.758718 -0.025410 -1.001819"},{"location":"python/DataAnalysis/ch08/#2020-01-05-0228758-0758718-0025410-1001819","text":"","title":"2020-01-05 -0.228758 -0.758718 -0.025410 -1.001819"},{"location":"python/DataAnalysis/ch08/#2020-01-06-0228758-0758718-0025410-1001819","text":"","title":"2020-01-06 -0.228758 -0.758718 -0.025410 -1.001819"},{"location":"python/DataAnalysis/ch08/#2020-01-07-0228758-0758718-0025410-1001819","text":"","title":"2020-01-07 -0.228758 -0.758718 -0.025410 -1.001819"},{"location":"python/DataAnalysis/ch08/#2020-01-08-0704541-0261414-0863335-0267101_4","text":"\u53ef\u4ee5\u540c\u6837\u9009\u62e9\u4ec5\u5411\u524d\u586b\u5145\u4e00\u5b9a\u6570\u91cf\u7684\u533a\u95f4\uff0c\u4ee5\u9650\u5236\u7ee7\u7eed\u4f7f\u7528\u89c2\u6d4b\u503c\u7684\u65f6\u8ddd\uff1a df_daily = df.resample('D').ffill(limit=2) print(df_daily)","title":"2020-01-08 -0.704541 -0.261414 -0.863335 0.267101"},{"location":"python/DataAnalysis/ch08/#colorado-texas-new-york-ohio_5","text":"","title":"Colorado Texas New York Ohio"},{"location":"python/DataAnalysis/ch08/#2020-01-01-0228758-0758718-0025410-1001819_5","text":"","title":"2020-01-01 -0.228758 -0.758718 -0.025410 -1.001819"},{"location":"python/DataAnalysis/ch08/#2020-01-02-0228758-0758718-0025410-1001819_1","text":"","title":"2020-01-02 -0.228758 -0.758718 -0.025410 -1.001819"},{"location":"python/DataAnalysis/ch08/#2020-01-03-0228758-0758718-0025410-1001819_1","text":"","title":"2020-01-03 -0.228758 -0.758718 -0.025410 -1.001819"},{"location":"python/DataAnalysis/ch08/#2020-01-04-nan-nan-nan-nan_1","text":"","title":"2020-01-04 NaN NaN NaN NaN"},{"location":"python/DataAnalysis/ch08/#2020-01-05-nan-nan-nan-nan_1","text":"","title":"2020-01-05 NaN NaN NaN NaN"},{"location":"python/DataAnalysis/ch08/#2020-01-06-nan-nan-nan-nan_1","text":"","title":"2020-01-06 NaN NaN NaN NaN"},{"location":"python/DataAnalysis/ch08/#2020-01-07-nan-nan-nan-nan_1","text":"","title":"2020-01-07 NaN NaN NaN NaN"},{"location":"python/DataAnalysis/ch08/#2020-01-08-0704541-0261414-0863335-0267101_5","text":"\u6ce8\u610f\uff0c\u65b0\u7684\u65e5\u671f\u7d22\u5f15\u4e0d\u9700\u8981\u4e0e\u65e7\u7684\u7d22\u5f15\u91cd\u53e0\uff0c\u548c\u539f\u6765`df`\u7684\u503c\u4e00\u6837\uff0c\u53ea\u662f\u65e5\u671f\u7d22\u5f15\u53d8\u4e86\u3002 df_new = df.resample('W-THU').ffill() print(df_new)","title":"2020-01-08 -0.704541 -0.261414 -0.863335 0.267101"},{"location":"python/DataAnalysis/ch08/#colorado-texas-new-york-ohio_6","text":"","title":"Colorado Texas New York Ohio"},{"location":"python/DataAnalysis/ch08/#2020-01-02-0228758-0758718-0025410-1001819_2","text":"","title":"2020-01-02 -0.228758 -0.758718 -0.025410 -1.001819"},{"location":"python/DataAnalysis/ch08/#2020-01-09-0704541-0261414-0863335-0267101","text":"### \u4f7f\u7528\u533a\u95f4\u8fdb\u884c\u91cd\u65b0\u91c7\u6837 \u5bf9\u4ee5\u533a\u95f4\u4e3a\u7d22\u5f15\u7684\u6570\u636e\u8fdb\u884c\u91c7\u6837\u4e0e\u65f6\u95f4\u6233\u7684\u60c5\u51b5\u7c7b\u4f3c\uff1a df = pd.DataFrame( np.random.randn(24, 4), index=pd.period_range('2020-1', periods=24, freq='M'), columns=['Colorado', 'Texas', 'New York', 'Ohio'] ) print(df)","title":"2020-01-09 -0.704541 -0.261414 -0.863335 0.267101"},{"location":"python/DataAnalysis/ch08/#2020-01-0721395-1492674-0707410-1641890","text":"","title":"2020-01 0.721395 -1.492674 0.707410 1.641890"},{"location":"python/DataAnalysis/ch08/#2020-02-0894880-0032823-0676158-0029203","text":"","title":"2020-02 -0.894880 0.032823 -0.676158 0.029203"},{"location":"python/DataAnalysis/ch08/#2020-03-2147365-0176796-0562695-0747656","text":"","title":"2020-03 2.147365 -0.176796 0.562695 -0.747656"},{"location":"python/DataAnalysis/ch08/#2020-04-1496037-0797119-0495601-0774147","text":"","title":"2020-04 1.496037 -0.797119 -0.495601 0.774147"},{"location":"python/DataAnalysis/ch08/#2020-05-0309839-0502563-0237244-0910624","text":"","title":"2020-05 -0.309839 0.502563 0.237244 0.910624"},{"location":"python/DataAnalysis/ch08/#2020-06-1231869-0105227-1315759-0217701","text":"","title":"2020-06 1.231869 -0.105227 1.315759 0.217701"},{"location":"python/DataAnalysis/ch08/#2020-07-1447419-0263876-0342045-0768907","text":"","title":"2020-07 1.447419 0.263876 -0.342045 -0.768907"},{"location":"python/DataAnalysis/ch08/#2020-08-2567162-1008827-0391085-1259560","text":"","title":"2020-08 -2.567162 -1.008827 0.391085 1.259560"},{"location":"python/DataAnalysis/ch08/#2020-09-0772501-1183532-0450374-0450714","text":"","title":"2020-09 -0.772501 1.183532 0.450374 0.450714"},{"location":"python/DataAnalysis/ch08/#2020-10-0228974-0461224-1393178-0175243","text":"","title":"2020-10 0.228974 0.461224 1.393178 0.175243"},{"location":"python/DataAnalysis/ch08/#2020-11-0725193-1544131-1372029-0659224","text":"","title":"2020-11 -0.725193 -1.544131 1.372029 -0.659224"},{"location":"python/DataAnalysis/ch08/#2020-12-0718195-0862024-0166460-0940191","text":"","title":"2020-12 0.718195 0.862024 -0.166460 -0.940191"},{"location":"python/DataAnalysis/ch08/#2021-01-0617054-0887312-0338451-1392838","text":"","title":"2021-01 -0.617054 -0.887312 0.338451 -1.392838"},{"location":"python/DataAnalysis/ch08/#2021-02-0081140-0634730-0868051-1277167","text":"","title":"2021-02 -0.081140 0.634730 -0.868051 -1.277167"},{"location":"python/DataAnalysis/ch08/#2021-03-0999642-1959715-0930662-0748687","text":"","title":"2021-03 -0.999642 -1.959715 -0.930662 0.748687"},{"location":"python/DataAnalysis/ch08/#2021-04-1851453-1561669-0688822-0371255","text":"","title":"2021-04 1.851453 1.561669 -0.688822 -0.371255"},{"location":"python/DataAnalysis/ch08/#2021-05-0540777-0890403-1204188-0243480","text":"","title":"2021-05 -0.540777 -0.890403 -1.204188 0.243480"},{"location":"python/DataAnalysis/ch08/#2021-06-1318905-1247457-0518969-0799793","text":"","title":"2021-06 1.318905 1.247457 0.518969 0.799793"},{"location":"python/DataAnalysis/ch08/#2021-07-0223238-0747177-0410889-0904593","text":"","title":"2021-07 0.223238 0.747177 -0.410889 0.904593"},{"location":"python/DataAnalysis/ch08/#2021-08-0652551-0254351-0464604-0676923","text":"","title":"2021-08 -0.652551 -0.254351 -0.464604 -0.676923"},{"location":"python/DataAnalysis/ch08/#2021-09-0562312-0182099-0018617-0573331","text":"","title":"2021-09 0.562312 0.182099 0.018617 0.573331"},{"location":"python/DataAnalysis/ch08/#2021-10-0429490-0045959-0356292-0295776","text":"","title":"2021-10 0.429490 -0.045959 -0.356292 -0.295776"},{"location":"python/DataAnalysis/ch08/#2021-11-2552155-0801299-1378421-1232792","text":"","title":"2021-11 2.552155 0.801299 1.378421 1.232792"},{"location":"python/DataAnalysis/ch08/#2021-12-1102288-0850280-0767015-0519840","text":"df_annual = df.resample('A-DEC').mean() print(df_annual)","title":"2021-12 1.102288 0.850280 -0.767015 -0.519840"},{"location":"python/DataAnalysis/ch08/#colorado-texas-new-york-ohio_7","text":"","title":"Colorado Texas New York Ohio"},{"location":"python/DataAnalysis/ch08/#2020-0226807-0151561-0395793-0195259","text":"","title":"2020 0.226807 -0.151561 0.395793 0.195259"},{"location":"python/DataAnalysis/ch08/#2021-0429056-0165581-0286339-0002594","text":"\u5411\u4e0a\u91c7\u6837\u66f4\u4e3a\u7ec6\u81f4\uff0c\u56e0\u4e3a\u5fc5\u987b\u5728\u91cd\u65b0\u91c7\u6837\u524d\u51b3\u5b9a\u65b0\u9891\u7387\u4e2d\u5728\u65f6\u95f4\u6bb5\u7684\u54ea\u4e00\u7aef\u653e\u7f6e\u6570\u503c\uff0c\u5c31\u50cfasfreq\u65b9\u6cd5\u4e00\u6837\u3002 `convention`\u53c2\u6570\u9ed8\u8ba4\u503c\u662f`start`\uff0c\u4f46\u4e5f\u53ef\u4ee5\u662f`end`\uff1a result = df_annual.resample('Q-DEC').ffill() print(result)","title":"2021 0.429056 0.165581 -0.286339 -0.002594"},{"location":"python/DataAnalysis/ch08/#colorado-texas-new-york-ohio_8","text":"","title":"Colorado Texas New York Ohio"},{"location":"python/DataAnalysis/ch08/#2020q1-0226807-0151561-0395793-0195259","text":"","title":"2020Q1 0.226807 -0.151561 0.395793 0.195259"},{"location":"python/DataAnalysis/ch08/#2020q2-0226807-0151561-0395793-0195259","text":"","title":"2020Q2 0.226807 -0.151561 0.395793 0.195259"},{"location":"python/DataAnalysis/ch08/#2020q3-0226807-0151561-0395793-0195259","text":"","title":"2020Q3 0.226807 -0.151561 0.395793 0.195259"},{"location":"python/DataAnalysis/ch08/#2020q4-0226807-0151561-0395793-0195259","text":"","title":"2020Q4 0.226807 -0.151561 0.395793 0.195259"},{"location":"python/DataAnalysis/ch08/#2021q1-0429056-0165581-0286339-0002594","text":"","title":"2021Q1 0.429056 0.165581 -0.286339 -0.002594"},{"location":"python/DataAnalysis/ch08/#2021q2-0429056-0165581-0286339-0002594","text":"","title":"2021Q2 0.429056 0.165581 -0.286339 -0.002594"},{"location":"python/DataAnalysis/ch08/#2021q3-0429056-0165581-0286339-0002594","text":"","title":"2021Q3 0.429056 0.165581 -0.286339 -0.002594"},{"location":"python/DataAnalysis/ch08/#2021q4-0429056-0165581-0286339-0002594","text":"result = df_annual.resample('Q-DEC', convention='end').ffill() print(result)","title":"2021Q4 0.429056 0.165581 -0.286339 -0.002594"},{"location":"python/DataAnalysis/ch08/#colorado-texas-new-york-ohio_9","text":"","title":"Colorado Texas New York Ohio"},{"location":"python/DataAnalysis/ch08/#2020q4-0226807-0151561-0395793-0195259_1","text":"","title":"2020Q4 0.226807 -0.151561 0.395793 0.195259"},{"location":"python/DataAnalysis/ch08/#2021q1-0226807-0151561-0395793-0195259","text":"","title":"2021Q1 0.226807 -0.151561 0.395793 0.195259"},{"location":"python/DataAnalysis/ch08/#2021q2-0226807-0151561-0395793-0195259","text":"","title":"2021Q2 0.226807 -0.151561 0.395793 0.195259"},{"location":"python/DataAnalysis/ch08/#2021q3-0226807-0151561-0395793-0195259","text":"","title":"2021Q3 0.226807 -0.151561 0.395793 0.195259"},{"location":"python/DataAnalysis/ch08/#2021q4-0429056-0165581-0286339-0002594_1","text":"\u7531\u4e8e\u533a\u95f4\u6d89\u53ca\u65f6\u95f4\u8303\u56f4\uff0c\u5411\u4e0a\u91c7\u6837\u548c\u5411\u4e0b\u91c7\u6837\u5c31\u66f4\u4e3a\u4e25\u683c\uff1a * \u5728\u5411\u4e0b\u91c7\u6837\u4e2d\uff0c\u76ee\u6807\u9891\u7387\u5fc5\u987b\u662f\u539f\u9891\u7387\u7684\u5b50\u533a\u95f4\u3002 * \u5728\u5411\u4e0a\u91c7\u6837\u4e2d\uff0c\u76ee\u6807\u9891\u7387\u5fc5\u987b\u662f\u539f\u9891\u7387\u7684\u7236\u533a\u95f4\u3002 \u5982\u679c\u4e0d\u6ee1\u8db3\u8fd9\u4e9b\u89c4\u5219\uff0c\u5c06\u4f1a\u5f15\u8d77\u5f02\u5e38\u3002\u8fd9\u4e3b\u8981\u4f1a\u5f71\u54cd\u6bcf\u5b63\u5ea6\u3001\u6bcf\u5e74\u548c\u6bcf\u5468\u7684\u9891\u7387\u3002 \u4f8b\u5982\uff0c\u6839\u636eQ-MAR\u5b9a\u4e49\u7684\u65f6\u95f4\u8303\u56f4\u5c06\u53ea\u548cA-MAR\u3001A-JUN\u3001A-SEP\u548cA-DEC\u4fdd\u6301\u4e00\u81f4\uff1a result = df_annual.resample('Q-MAR').ffill() print(result)","title":"2021Q4 0.429056 0.165581 -0.286339 -0.002594"},{"location":"python/DataAnalysis/ch08/#colorado-texas-new-york-ohio_10","text":"","title":"Colorado Texas New York Ohio"},{"location":"python/DataAnalysis/ch08/#2020q4-0226807-0151561-0395793-0195259_2","text":"","title":"2020Q4 0.226807 -0.151561 0.395793 0.195259"},{"location":"python/DataAnalysis/ch08/#2021q1-0226807-0151561-0395793-0195259_1","text":"","title":"2021Q1 0.226807 -0.151561 0.395793 0.195259"},{"location":"python/DataAnalysis/ch08/#2021q2-0226807-0151561-0395793-0195259_1","text":"","title":"2021Q2 0.226807 -0.151561 0.395793 0.195259"},{"location":"python/DataAnalysis/ch08/#2021q3-0226807-0151561-0395793-0195259_1","text":"","title":"2021Q3 0.226807 -0.151561 0.395793 0.195259"},{"location":"python/DataAnalysis/ch08/#2021q4-0429056-0165581-0286339-0002594_2","text":"","title":"2021Q4 0.429056 0.165581 -0.286339 -0.002594"},{"location":"python/DataAnalysis/ch08/#2022q1-0429056-0165581-0286339-0002594","text":"","title":"2022Q1 0.429056 0.165581 -0.286339 -0.002594"},{"location":"python/DataAnalysis/ch08/#2022q2-0429056-0165581-0286339-0002594","text":"","title":"2022Q2 0.429056 0.165581 -0.286339 -0.002594"},{"location":"python/DataAnalysis/ch08/#2022q3-0429056-0165581-0286339-0002594","text":"## \u79fb\u52a8\u7a97\u53e3\u51fd\u6570 \u7edf\u8ba1\u90a3\u4e9b\u901a\u8fc7\u79fb\u52a8\u7a97\u53e3\u6216\u6307\u6570\u8870\u51cf\u800c\u8fd0\u884c\u7684\u51fd\u6570\uff0c\u662f\u7528\u4e8e\u65f6\u95f4\u5e8f\u5217\u64cd\u4f5c\u7684\u6570\u7ec4\u53d8\u6362\u7684\u4e00\u4e2a\u91cd\u8981\u7c7b\u522b\u3002 \u8fd9\u5bf9\u5e73\u6ed1\u566a\u58f0\u6216\u7c97\u7cd9\u7684\u6570\u636e\u975e\u5e38\u6709\u7528\u3002\u79f0\u8fd9\u4e9b\u51fd\u6570\u4e3a\u79fb\u52a8\u7a97\u53e3\u51fd\u6570\uff0c\u5c3d\u7ba1\u5b83\u4e5f\u5305\u542b\u4e86\u4e00\u4e9b\u6ca1\u6709\u56fa\u5b9a\u957f\u5ea6\u7a97\u53e3\u7684\u51fd\u6570\uff0c\u6bd4\u5982\u6307\u6570\u52a0\u6743\u79fb\u52a8\u5e73\u5747\u3002 \u4e0e\u5176\u4ed6\u7684\u7edf\u8ba1\u51fd\u6570\u7c7b\u4f3c\uff0c\u8fd9\u4e9b\u51fd\u6570\u4f1a\u81ea\u52a8\u6392\u9664\u7f3a\u5931\u6570\u636e\u3002 import matplotlib.pyplot as plt import pandas as pd from scipy.stats import percentileofscore import numpy as np from pandas.tseries.offsets import Hour, Minute, Day, MonthEnd import pytz \u5728\u6df1\u5165\u4e86\u89e3\u4e4b\u524d\uff0c\u6211\u4eec\u53ef\u4ee5\u5148\u8f7d\u5165\u4e00\u4e9b\u65f6\u95f4\u5e8f\u5217\u6570\u636e\u5e76\u6309\u7167\u5de5\u4f5c\u65e5\u9891\u7387\u8fdb\u884c\u91cd\u65b0\u91c7\u6837\uff1a close_px_all = pd.read_csv( '../examples/stock_px_2.csv', parse_dates = True, index_col=0 ) print(close_px_all.head(5))","title":"2022Q3 0.429056 0.165581 -0.286339 -0.002594"},{"location":"python/DataAnalysis/ch08/#aapl-msft-xom-spx","text":"","title":"AAPL MSFT XOM SPX"},{"location":"python/DataAnalysis/ch08/#2003-01-02-740-2111-2922-90903","text":"","title":"2003-01-02 7.40 21.11 29.22 909.03"},{"location":"python/DataAnalysis/ch08/#2003-01-03-745-2114-2924-90859","text":"","title":"2003-01-03 7.45 21.14 29.24 908.59"},{"location":"python/DataAnalysis/ch08/#2003-01-06-745-2152-2996-92901","text":"","title":"2003-01-06 7.45 21.52 29.96 929.01"},{"location":"python/DataAnalysis/ch08/#2003-01-07-743-2193-2895-92293","text":"","title":"2003-01-07 7.43 21.93 28.95 922.93"},{"location":"python/DataAnalysis/ch08/#2003-01-08-728-2131-2883-90993","text":"close_px = close_px_all[ ['AAPL', 'MSFT', 'XOM'] ] close_px = close_px.resample('B').ffill() print(close_px)","title":"2003-01-08 7.28 21.31 28.83 909.93"},{"location":"python/DataAnalysis/ch08/#aapl-msft-xom","text":"","title":"AAPL MSFT XOM"},{"location":"python/DataAnalysis/ch08/#2003-01-02-740-2111-2922","text":"","title":"2003-01-02 7.40 21.11 29.22"},{"location":"python/DataAnalysis/ch08/#2003-01-03-745-2114-2924","text":"","title":"2003-01-03 7.45 21.14 29.24"},{"location":"python/DataAnalysis/ch08/#_15","text":"","title":"... ... ... ..."},{"location":"python/DataAnalysis/ch08/#2011-10-13-40843-2718-7637","text":"","title":"2011-10-13 408.43 27.18 76.37"},{"location":"python/DataAnalysis/ch08/#2011-10-14-42200-2727-7811","text":"","title":"2011-10-14 422.00 27.27 78.11"},{"location":"python/DataAnalysis/ch08/#2292-rows-x-3-columns","text":"`rolling`\u7b97\u5b50\uff0c\u5b83\u7684\u884c\u4e3a\u4e0e`resample`\u548c`groupby`\u7c7b\u4f3c\u3002 `rolling`\u53ef\u4ee5\u5728Series\u6216DataFrame\u4e0a\u901a\u8fc7\u4e00\u4e2awindow\uff08\u4ee5\u4e00\u4e2a\u533a\u95f4\u7684\u6570\u5b57\u6765\u8868\u793a\uff09\u8fdb\u884c\u8c03\u7528\u3002 close_px.AAPL.plot() \u8868\u8fbe\u5f0f`rolling(250)`\u4e0e`groupby`\u7684\u884c\u4e3a\u7c7b\u4f3c\uff0c\u4f46\u662f\u5b83\u521b\u5efa\u7684\u5bf9\u8c61\u662f\u6839\u636e250\u65e5\u6ed1\u52a8\u7a97\u53e3\u5206\u7ec4\u7684\u800c\u4e0d\u662f\u76f4\u63a5\u5206\u7ec4\u3002 \u56e0\u6b64\u8fd9\u91cc\u6211\u4eec\u83b7\u5f97\u4e86\u82f9\u679c\u516c\u53f8\u80a1\u7968\u4ef7\u683c\u7684250\u65e5\u79fb\u52a8\u7a97\u53e3\u5e73\u5747\u503c\u3002 close_px.AAPL.rolling(250).mean().plot() plt.show() \u9ed8\u8ba4\u60c5\u51b5\u4e0b\uff0c\u6eda\u52a8\u51fd\u6570\u9700\u8981\u7a97\u53e3\u4e2d\u6240\u6709\u7684\u503c\u5fc5\u987b\u662f\u975e`NA`\u503c\u3002 \u7531\u4e8e\u5b58\u5728\u7f3a\u5931\u503c\u8fd9\u79cd\u884c\u4e3a\u4f1a\u53d1\u751f\u6539\u53d8\uff0c\u5c24\u5176\u662f\u5728\u65f6\u95f4\u5e8f\u5217\u7684\u8d77\u59cb\u4f4d\u7f6e\u4f60\u62e5\u6709\u7684\u6570\u636e\u662f\u5c11\u4e8e\u7a97\u53e3\u533a\u95f4\u7684 apple_std250 = close_px.AAPL.rolling(250, min_periods=10).std() # \u82f9\u679c\u516c\u53f8250\u65e5\u6bcf\u65e5\u8fd4\u56de\u6807\u51c6\u5dee print(apple_std250[5:12])","title":"[2292 rows x 3 columns]"},{"location":"python/DataAnalysis/ch08/#2003-01-09-nan","text":"","title":"2003-01-09 NaN"},{"location":"python/DataAnalysis/ch08/#2003-01-10-nan","text":"","title":"2003-01-10 NaN"},{"location":"python/DataAnalysis/ch08/#2003-01-13-nan","text":"","title":"2003-01-13 NaN"},{"location":"python/DataAnalysis/ch08/#2003-01-14-nan","text":"","title":"2003-01-14 NaN"},{"location":"python/DataAnalysis/ch08/#2003-01-15-0077496","text":"","title":"2003-01-15 0.077496"},{"location":"python/DataAnalysis/ch08/#2003-01-16-0074760","text":"","title":"2003-01-16 0.074760"},{"location":"python/DataAnalysis/ch08/#2003-01-17-0112368","text":"","title":"2003-01-17 0.112368"},{"location":"python/DataAnalysis/ch08/#freq-b-name-aapl-dtype-float64","text":"apple_std250.plot() plt.show() expanding_mean = apple_std250.expanding().mean() print(expanding_mean[5:12])","title":"Freq: B, Name: AAPL, dtype: float64"},{"location":"python/DataAnalysis/ch08/#2003-01-09-nan_1","text":"","title":"2003-01-09 NaN"},{"location":"python/DataAnalysis/ch08/#2003-01-10-nan_1","text":"","title":"2003-01-10 NaN"},{"location":"python/DataAnalysis/ch08/#2003-01-13-nan_1","text":"","title":"2003-01-13 NaN"},{"location":"python/DataAnalysis/ch08/#2003-01-14-nan_1","text":"","title":"2003-01-14 NaN"},{"location":"python/DataAnalysis/ch08/#2003-01-15-0077496_1","text":"","title":"2003-01-15 0.077496"},{"location":"python/DataAnalysis/ch08/#2003-01-16-0076128","text":"","title":"2003-01-16 0.076128"},{"location":"python/DataAnalysis/ch08/#2003-01-17-0088208","text":"","title":"2003-01-17 0.088208"},{"location":"python/DataAnalysis/ch08/#freq-b-name-aapl-dtype-float64_1","text":"expanding_mean.plot() plt.show() \u5728DataFrame\u4e0a\u8c03\u7528\u4e00\u4e2a\u79fb\u52a8\u7a97\u53e3\u51fd\u6570\u4f1a\u5c06\u53d8\u6362\u5e94\u7528\u5230\u6bcf\u4e00\u5217\u4e0a: close_px.rolling(60).mean().plot(logy=True) # \u80a1\u7968\u4ef7\u683c60\u65e5MA\uff08Y\u8f74\u53d6\u5bf9\u6570\uff09 plt.show() `rolling`\u51fd\u6570\u4e5f\u63a5\u6536\u8868\u793a\u56fa\u5b9a\u5927\u5c0f\u7684\u65f6\u95f4\u504f\u7f6e\u5b57\u7b26\u4e32\uff0c\u800c\u4e0d\u53ea\u662f\u4e00\u4e2a\u533a\u95f4\u7684\u96c6\u5408\u6570\u5b57\u3002 \u5bf9\u4e0d\u89c4\u5219\u65f6\u95f4\u5e8f\u5217\u4f7f\u7528\u6ce8\u91ca\u975e\u5e38\u6709\u7528\u3002\u8fd9\u4e9b\u5b57\u7b26\u4e32\u53ef\u4ee5\u4f20\u9012\u7ed9`resample`\u3002 \u4f8b\u5982\uff0c\u6211\u4eec\u53ef\u4ee5\u50cf\u8fd9\u6837\u8ba1\u7b9720\u5929\u7684\u6eda\u52a8\u5e73\u5747\u503c\uff1a result = close_px.rolling('20D').mean() print(result)","title":"Freq: B, Name: AAPL, dtype: float64"},{"location":"python/DataAnalysis/ch08/#aapl-msft-xom_1","text":"","title":"AAPL MSFT XOM"},{"location":"python/DataAnalysis/ch08/#2003-01-02-7400000-21110000-29220000","text":"","title":"2003-01-02 7.400000 21.110000 29.220000"},{"location":"python/DataAnalysis/ch08/#_16","text":"","title":"... ... ... ..."},{"location":"python/DataAnalysis/ch08/#2011-10-14-391038000-26048667-74185333","text":"","title":"2011-10-14 391.038000 26.048667 74.185333"},{"location":"python/DataAnalysis/ch08/#2292-rows-x-3-columns_1","text":"result.plot() plt.show() ### \u6307\u6570\u52a0\u6743\u51fd\u6570 \u6307\u5b9a\u4e00\u4e2a\u5e38\u6570\u8870\u51cf\u56e0\u5b50\u4ee5\u5411\u66f4\u591a\u8fd1\u671f\u89c2\u6d4b\u503c\u63d0\u4f9b\u66f4\u591a\u6743\u91cd\uff0c\u53ef\u4ee5\u66ff\u4ee3\u4f7f\u7528\u5177\u6709\u76f8\u7b49\u52a0\u6743\u89c2\u5bdf\u503c\u7684\u9759\u6001\u7a97\u53e3\u5c3a\u5bf8\u7684\u65b9\u6cd5\u3002 \u6709\u591a\u79cd\u65b9\u5f0f\u53ef\u4ee5\u6307\u5b9a\u8870\u51cf\u56e0\u5b50\u3002\u5176\u4e2d\u4e00\u79cd\u6d41\u884c\u7684\u65b9\u5f0f\u662f\u4f7f\u7528\u4e00\u4e2aspan\uff08\u8de8\u5ea6\uff09\uff0c\u8fd9\u4f7f\u5f97\u7ed3\u679c\u4e0e\u7a97\u53e3\u5927\u5c0f\u7b49\u4e8e\u8de8\u5ea6\u7684\u7b80\u5355\u79fb\u52a8\u7a97\u53e3\u51fd\u6570\u3002 \u7531\u4e8e\u6307\u6570\u52a0\u6743\u7edf\u8ba1\u503c\u7ed9\u66f4\u8fd1\u671f\u7684\u89c2\u6d4b\u503c\u4ee5\u66f4\u591a\u7684\u6743\u91cd\uff0c\u4e0e\u7b49\u6743\u91cd\u7684\u7248\u672c\u76f8\u6bd4\uff0c\u5b83\u5bf9\u53d8\u5316\u201c\u9002\u5e94\u201d\u5f97\u66f4\u5feb\u3002 pandas\u62e5\u6709`ewm`\u7b97\u5b50\uff0c\u540c`rolling`\u3001`expanding`\u7b97\u5b50\u4e00\u8d77\u4f7f\u7528\u3002 \u4ee5\u4e0b\u662f\u5c06\u82f9\u679c\u516c\u53f8\u80a1\u7968\u4ef7\u683c\u768460\u65e5\u5747\u7ebf\u4e0e`span=60`\u7684EW\u79fb\u52a8\u5e73\u5747\u7ebf\u8fdb\u884c\u6bd4\u8f83\u7684\u4f8b\u5b50\uff1a aapl_ex = close_px.AAPL['2006':'2007'] ma60 = aapl_ex.rolling(30, min_periods=20).mean() ewma60 = aapl_ex.ewm(span=30).mean() ma60.plot(style='k--', label='Simple MA') ewma60.plot(style='k-', label='EWMA') plt.legend() plt.show() ### \u4e8c\u5143\u79fb\u52a8\u7a97\u53e3\u51fd\u6570 \u4e00\u4e9b\u7edf\u8ba1\u7b97\u5b50\uff0c\u4f8b\u5982\u76f8\u5173\u5ea6\u548c\u534f\u65b9\u5dee\uff0c\u9700\u8981\u64cd\u4f5c\u4e24\u4e2a\u65f6\u95f4\u5e8f\u5217\u3002 \u4f8b\u5982\uff0c\u91d1\u878d\u5206\u6790\u5e08\u7ecf\u5e38\u5bf9\u80a1\u7968\u4e0e\u57fa\u51c6\u6307\u6570\uff08\u5982\u6807\u666e500\uff09\u7684\u5173\u8054\u6027\u611f\u5174\u8da3\u3002 \u6211\u4eec\u9996\u5148\u8ba1\u7b97\u6240\u6709\u6211\u4eec\u611f\u5174\u8da3\u7684\u65f6\u95f4\u5e8f\u5217\u7684\u767e\u5206\u6bd4\u53d8\u5316\uff1a spx_px = close_px_all['SPX'] spx_rets = spx_px.pct_change() returns = close_px.pct_change()","title":"[2292 rows x 3 columns]"},{"location":"python/DataAnalysis/ch08/#rollingcorrspx_rets","text":"corr = returns.AAPL.rolling(125, min_periods=100).corr(spx_rets) # \u82f9\u679c\u516c\u53f8\u4e0e\u6807\u666e500\u7684\u516d\u4e2a\u6708\u7684\u6536\u76ca\u76f8\u5173\u6027 corr.plot() plt.show() corr = returns.rolling(125, min_periods=100).corr(spx_rets) # \u591a\u53ea\u80a1\u7968\u4e0e\u6807\u666e500\u7684\u516d\u4e2a\u6708\u6536\u76ca\u76f8\u5173\u6027 corr.plot() plt.show() ### \u7528\u6237\u81ea\u5b9a\u4e49\u7684\u79fb\u52a8\u7a97\u53e3\u51fd\u6570 \u5728`rolling`\u53ca\u5176\u76f8\u5173\u65b9\u6cd5\u4e0a\u4f7f\u7528apply\u65b9\u6cd5\u63d0\u4f9b\u4e86\u4e00\u79cd\u5728\u79fb\u52a8\u7a97\u53e3\u4e2d\u5e94\u7528\u4f60\u81ea\u5df1\u8bbe\u8ba1\u7684\u6570\u7ec4\u51fd\u6570\u7684\u65b9\u6cd5\u3002 \u552f\u4e00\u7684\u8981\u6c42\u662f\u8be5\u51fd\u6570\u4ece\u6bcf\u4e2a\u6570\u7ec4\u4e2d\u4ea7\u751f\u4e00\u4e2a\u5355\u503c\uff08\u7f29\u805a\uff09\u3002 \u4f8b\u5982\uff0c\u5c3d\u7ba1\u6211\u4eec\u53ef\u4ee5\u4f7f\u7528`rolling(...).quantile(q)`\u8ba1\u7b97\u6837\u672c\u7684\u5206\u4f4d\u6570\uff0c\u4f46\u6211\u4eec\u53ef\u80fd\u4f1a\u5bf9\u6837\u672c\u4e2d\u7279\u5b9a\u503c\u7684\u767e\u5206\u4f4d\u6570\u611f\u5174\u8da3\u3002 `scipy.stats.percentileofscore`\u51fd\u6570\u5c31\u662f\u5b9e\u73b0\u8fd9\u4e2a\u529f\u80fd\u7684\uff1a score_at_2percent = lambda x: percentileofscore(x, 0.02) result = returns.AAPL.rolling(250).apply(score_at_2percent) # \u4e00\u5e74\u7a97\u53e3\u4e0b\u82f9\u679c\u516c\u53f8\u80a1\u4ef72%\u6536\u76ca\u7684\u767e\u5206\u4f4d\u7b49\u7ea7 result.plot() plt.show() result = returns.rolling(250).apply(score_at_2percent) # \u4e00\u5e74\u7a97\u53e3\u4e0b\u6240\u6709\u516c\u53f8\u80a1\u4ef72%\u6536\u76ca\u7684\u767e\u5206\u4f4d\u7b49\u7ea7 result.plot() plt.show() ```","title":"\u5728\u8c03\u7528rolling\u540e\uff0ccorr\u805a\u5408\u51fd\u6570\u53ef\u4ee5\u6839\u636espx_rets\u8ba1\u7b97\u6eda\u52a8\u76f8\u5173\u6027\uff1a"},{"location":"python/DataAnalysis/ch09/","text":"\u9ad8\u9636pandas \u00b6 \u5206\u7c7b\u6570\u636e \u00b6 import numpy as np import pandas as pd \u80cc\u666f\u548c\u76ee\u6807 \u00b6 \u4e00\u4e2a\u5217\u7ecf\u5e38\u4f1a\u5305\u542b\u91cd\u590d\u503c\uff0c\u8fd9\u4e9b\u91cd\u590d\u503c\u662f\u4e00\u4e2a\u5c0f\u578b\u7684\u4e0d\u540c\u503c\u7684\u96c6\u5408\u3002 unique \u548c value_counts \u8fd9\u6837\u7684\u51fd\u6570\u5141\u8bb8\u6211\u4eec\u4ece\u4e00\u4e2a\u6570\u7ec4\u4e2d\u63d0\u53d6\u4e0d\u540c\u503c\u5e76\u5206\u522b\u8ba1\u7b97\u8fd9\u4e9b\u4e0d\u540c\u503c\u7684\u9891\u7387\uff1a values = pd.Series(['apple', 'orange', 'apple', 'apple'] * 2) print(values) # 0 apple # 1 orange # 2 apple # 3 apple # 4 apple # 5 orange # 6 apple # 7 apple # dtype: object print(pd.unique(values)) # ['apple' 'orange'] print(pd.value_counts(values)) # apple 6 # orange 2 # dtype: int64 \u5728\u6570\u636e\u5165\u5e93\u7684\u64cd\u4f5c\u4e2d\uff0c\u4f7f\u7528\u7ef4\u5ea6\u8868\u662f\u4e00\u79cd\u6700\u4f73\u5b9e\u8df5\uff0c\u7ef4\u5ea6\u8868\u5305\u542b\u4e86\u4e0d\u540c\u503c\uff0c\u5e76\u5c06\u4e3b\u8981\u89c2\u6d4b\u503c\u5b58\u50a8\u4e3a\u5f15\u7528\u7ef4\u5ea6\u8868\u7684\u6574\u6570\u952e\uff1a values = pd.Series([0, 1, 0, 0] * 2) dim = pd.Series(['apple', 'oragne']) \u4f7f\u7528 take \u65b9\u6cd5\u6765\u6062\u590d\u539f\u6765\u7684\u5b57\u7b26\u4e32Series\u3002\uff080\u5bf9\u5e94\u5230apple)\u3002 \u8fd9\u79cd\u6309\u7167\u6574\u6570\u5c55\u73b0\u7684\u65b9\u5f0f\u88ab\u79f0\u4e3a\u5206\u7c7b\u6216\u5b57\u5178\u7f16\u7801\u5c55\u73b0\u3002\u4e0d\u540c\u503c\u7684\u6570\u7ec4\u53ef\u4ee5\u88ab\u79f0\u4e3a\u6570\u636e\u7684\u7c7b\u522b\u3001\u5b57\u5178\u6216\u5c42\u7ea7\u3002 print(dim.take(values)) # 0 apple # 1 oragne # 0 apple # 0 apple # 0 apple # 1 oragne # 0 apple # 0 apple # dtype: object \u5728\u505a\u6570\u636e\u5206\u6790\u65f6\uff0c\u5206\u7c7b\u5c55\u793a\u4f1a\u4ea7\u751f\u663e\u8457\u7684\u6027\u80fd\u63d0\u5347\u3002\u53ef\u4ee5\u5728\u7c7b\u522b\u4e0a\u8fdb\u884c\u8f6c\u6362\u540c\u65f6\u4e0d\u6539\u53d8\u4ee3\u7801\u3002 \u4ee5\u4e0b\u662f\u4e00\u4e9b\u76f8\u5bf9\u4f4e\u5f00\u9500\u7684\u8f6c\u6362\u793a\u4f8b\uff1a \u91cd\u547d\u540d\u7c7b\u522b \u5728\u4e0d\u6539\u53d8\u5df2\u6709\u7684\u7c7b\u522b\u987a\u5e8f\u7684\u60c5\u51b5\u4e0b\u6dfb\u52a0\u4e00\u4e2a\u65b0\u7684\u7c7b\u522b pandas\u4e2d\u7684Categorical\u7c7b\u578b \u00b6 pandas\u62e5\u6709\u7279\u6b8a\u7684 Categorical \u7c7b\u578b\uff0c\u7528\u4e8e\u627f\u8f7d\u57fa\u4e8e\u6574\u6570\u7684\u7c7b\u522b\u5c55\u793a\u6216\u7f16\u7801\u7684\u6570\u636e\u3002 fruits = ['apple', 'orange', 'apple', 'apple'] * 2 N = len(fruits) df = pd.DataFrame( { 'fruit': fruits, 'basket_id': np.arange(N), 'count': np.random.randint(3, 15, size=N), 'weight': np.random.uniform(0, 4, size=N) }, columns=['basket_id', 'fruit', 'count', 'weight'] ) print(df) # basket_id fruit count weight # 0 0 apple 8 1.288867 # 1 1 orange 4 3.414430 # 2 2 apple 7 3.222160 # 3 3 apple 14 2.724804 # 4 4 apple 8 3.548828 # 5 5 orange 10 0.918739 # 6 6 apple 4 0.784816 # 7 7 apple 10 3.140607 df['fruit'] \u662f\u4e00\u4e2aPython\u5b57\u7b26\u4e32\u5bf9\u8c61\u7ec4\u6210\u7684\u6570\u7ec4\u3002\u53ef\u4ee5\u901a\u8fc7\u8c03\u7528\u51fd\u6570\u5c06\u5b83\u8f6c\u6362\u4e3a Categorical \u5bf9\u8c61\uff1a fruit_cat = df['fruit'].astype('category') print(fruit_cat) # 0 apple # 1 orange # 2 apple # 3 apple # 4 apple # 5 orange # 6 apple # 7 apple # Name: fruit, dtype: category # Categories (2, object): ['apple', 'orange'] fruit_cat \u7684\u503c\u5e76\u4e0d\u662fNumPy\u6570\u7ec4\uff0c\u800c\u662f pandas.Categorical \u7684\u5b9e\u4f8b\uff1a c = fruit_cat.values print(type(c)) # print(c) # ['apple', 'orange', 'apple', 'apple', 'apple', 'orange', 'apple', 'apple'] # Categories (2, object): ['apple', 'orange'] Categorical \u5bf9\u8c61\u62e5\u6709 categories \u548c codes \u5c5e\u6027\uff1a print(c.categories) # Index(['apple', 'orange'], dtype='object') print(c.codes) # [0 1 0 0 0 1 0 0] \u901a\u8fc7\u5206\u914d\u5df2\u8f6c\u6362\u7684\u7ed3\u679c\u5c06DataFrame\u7684\u4e00\u5217\u8f6c\u6362\u4e3a Categorical \u5bf9\u8c61\uff1a print(df['fruit']) # 0 apple # 1 orange # 2 apple # 3 apple # 4 apple # 5 orange # 6 apple # 7 apple # Name: fruit, dtype: object df['fruit'] = df['fruit'].astype('category') print(df['fruit']) # 0 apple # 1 orange # 2 apple # 3 apple # 4 apple # 5 orange # 6 apple # 7 apple # Name: fruit, dtype: category # Categories (2, object): ['apple', 'orange'] \u4e5f\u53ef\u4ee5\u4ece\u5176\u4ed6Python\u5e8f\u5217\u7c7b\u578b\u76f4\u63a5\u751f\u6210 pandas.Categorical \uff1a my_categories = pd.Categorical(['foo', 'bar', 'baz', 'foo', 'bar']) print(my_categories) # ['foo', 'bar', 'baz', 'foo', 'bar'] # Categories (3, object): ['bar', 'baz', 'foo'] \u4e5f\u53ef\u4ee5\u4f7f\u7528 from_codes \u6784\u9020\u51fd\u6570\u6765\u8f6c\u6362\u5176\u4ed6\u6570\u636e\u6e90\u7684\u5206\u7c7b\u7f16\u7801\u6570\u636e\uff1a categories = ['foo', 'bar', 'baz'] codes = [0, 1, 2, 0, 0, 1] my_cats_2 = pd.Categorical.from_codes(codes, categories) print(my_cats_2) # ['foo', 'bar', 'baz', 'foo', 'foo', 'bar'] # Categories (3, object): ['foo', 'bar', 'baz'] \u8fd9\u4e2a\u672a\u6392\u5e8f\u7684\u5206\u7c7b\u5b9e\u4f8b\u53ef\u4ee5\u4f7f\u7528 as_ordered \u8fdb\u884c\u6392\u5e8f\uff1a print(my_cats_2.as_ordered()) # ['foo', 'bar', 'baz', 'foo', 'foo', 'bar'] # Categories (3, object): ['foo' < 'bar' < 'baz'] \u9664\u975e\u663e\u5f0f\u5730\u6307\u5b9a\uff0c\u5206\u7c7b\u8f6c\u6362\u662f\u4e0d\u4f1a\u6307\u5b9a\u7c7b\u522b\u7684\u987a\u5e8f\u7684\u3002\u56e0\u6b64 categories \u6570\u7ec4\u53ef\u80fd\u4f1a\u4e0e\u8f93\u5165\u6570\u636e\u7684\u987a\u5e8f\u4e0d\u540c\u3002 \u5f53\u4f7f\u7528 from_codes \u6216\u5176\u4ed6\u4efb\u610f\u6784\u9020\u51fd\u6570\u65f6\uff0c\u53ef\u4ee5\u4e3a\u7c7b\u522b\u6307\u5b9a\u4e00\u4e2a\u6709\u610f\u4e49\u7684\u987a\u5e8f\uff1a\u8f93\u51fa\u7684 [foo df.pipe(len) # \u4f20\u9012\u7684\u662flen\u5b9e\u4f8b # 4 def fun(df): return df * 2 fun(df) # 0 1 2 # 0 2.0 4.0 6.0 # 1 2.0 NaN NaN # 2 NaN NaN NaN # 3 NaN 4.0 6.0 df.pipe(fun) # \u4f20\u9012\u7684\u662ffun\u51fd\u6570 # 0 1 2 # 0 2.0 4.0 6.0 # 1 2.0 NaN NaN # 2 NaN NaN NaN # 3 NaN 4.0 6.0 def fun2(x, df): # \u6570\u636e\u662f\u7b2c\u4e8c\u4e2a\u53c2\u6570 return df * 3 df.pipe((fun2, 'df'), 2) # \u6ce8\u610f\u4f20\u503c # 0 1 2 # 0 3.0 6.0 9.0 # 1 3.0 NaN NaN # 2 NaN NaN NaN # 3 NaN 6.0 9.0 Series \u793a\u4f8b\uff1a \u00b6 s = pd.Series([1, 2, 3, 4, 5]) s.pipe(type) # s.pipe(len) # 5 def fun3(x, ss): return ss * 3 s.pipe((fun3, 'ss'), 2) # 0 3 # 1 6 # 2 9 # 3 12 # 4 15 # dtype: int64 GroupBy \u793a\u4f8b\uff1a \u00b6 df = pd.DataFrame({'A': 'a b a b'.split(), 'B': [1, 2, 3, 4]}) print(df) # A B # 0 a 1 # 1 b 2 # 2 a 3 # 3 b 4 \u6c42\u6bcf\u7ec4\u6700\u5927\u503c\u548c\u6700\u5c0f\u503c\u4e4b\u95f4\u7684\u5dee\u5f02\u3002 df.groupby('A').pipe(lambda x: x.max() - x.min()) # B # A # a 2 # b 2 def mean1(groupby): return groupby.mean() df.groupby(['A']).pipe(mean1) # B # A # a 2.0 # b 3.0","title":"\u9ad8\u9636pandas"},{"location":"python/DataAnalysis/ch09/#pandas","text":"","title":"\u9ad8\u9636pandas"},{"location":"python/DataAnalysis/ch09/#_1","text":"import numpy as np import pandas as pd","title":"\u5206\u7c7b\u6570\u636e"},{"location":"python/DataAnalysis/ch09/#_2","text":"\u4e00\u4e2a\u5217\u7ecf\u5e38\u4f1a\u5305\u542b\u91cd\u590d\u503c\uff0c\u8fd9\u4e9b\u91cd\u590d\u503c\u662f\u4e00\u4e2a\u5c0f\u578b\u7684\u4e0d\u540c\u503c\u7684\u96c6\u5408\u3002 unique \u548c value_counts \u8fd9\u6837\u7684\u51fd\u6570\u5141\u8bb8\u6211\u4eec\u4ece\u4e00\u4e2a\u6570\u7ec4\u4e2d\u63d0\u53d6\u4e0d\u540c\u503c\u5e76\u5206\u522b\u8ba1\u7b97\u8fd9\u4e9b\u4e0d\u540c\u503c\u7684\u9891\u7387\uff1a values = pd.Series(['apple', 'orange', 'apple', 'apple'] * 2) print(values) # 0 apple # 1 orange # 2 apple # 3 apple # 4 apple # 5 orange # 6 apple # 7 apple # dtype: object print(pd.unique(values)) # ['apple' 'orange'] print(pd.value_counts(values)) # apple 6 # orange 2 # dtype: int64 \u5728\u6570\u636e\u5165\u5e93\u7684\u64cd\u4f5c\u4e2d\uff0c\u4f7f\u7528\u7ef4\u5ea6\u8868\u662f\u4e00\u79cd\u6700\u4f73\u5b9e\u8df5\uff0c\u7ef4\u5ea6\u8868\u5305\u542b\u4e86\u4e0d\u540c\u503c\uff0c\u5e76\u5c06\u4e3b\u8981\u89c2\u6d4b\u503c\u5b58\u50a8\u4e3a\u5f15\u7528\u7ef4\u5ea6\u8868\u7684\u6574\u6570\u952e\uff1a values = pd.Series([0, 1, 0, 0] * 2) dim = pd.Series(['apple', 'oragne']) \u4f7f\u7528 take \u65b9\u6cd5\u6765\u6062\u590d\u539f\u6765\u7684\u5b57\u7b26\u4e32Series\u3002\uff080\u5bf9\u5e94\u5230apple)\u3002 \u8fd9\u79cd\u6309\u7167\u6574\u6570\u5c55\u73b0\u7684\u65b9\u5f0f\u88ab\u79f0\u4e3a\u5206\u7c7b\u6216\u5b57\u5178\u7f16\u7801\u5c55\u73b0\u3002\u4e0d\u540c\u503c\u7684\u6570\u7ec4\u53ef\u4ee5\u88ab\u79f0\u4e3a\u6570\u636e\u7684\u7c7b\u522b\u3001\u5b57\u5178\u6216\u5c42\u7ea7\u3002 print(dim.take(values)) # 0 apple # 1 oragne # 0 apple # 0 apple # 0 apple # 1 oragne # 0 apple # 0 apple # dtype: object \u5728\u505a\u6570\u636e\u5206\u6790\u65f6\uff0c\u5206\u7c7b\u5c55\u793a\u4f1a\u4ea7\u751f\u663e\u8457\u7684\u6027\u80fd\u63d0\u5347\u3002\u53ef\u4ee5\u5728\u7c7b\u522b\u4e0a\u8fdb\u884c\u8f6c\u6362\u540c\u65f6\u4e0d\u6539\u53d8\u4ee3\u7801\u3002 \u4ee5\u4e0b\u662f\u4e00\u4e9b\u76f8\u5bf9\u4f4e\u5f00\u9500\u7684\u8f6c\u6362\u793a\u4f8b\uff1a \u91cd\u547d\u540d\u7c7b\u522b \u5728\u4e0d\u6539\u53d8\u5df2\u6709\u7684\u7c7b\u522b\u987a\u5e8f\u7684\u60c5\u51b5\u4e0b\u6dfb\u52a0\u4e00\u4e2a\u65b0\u7684\u7c7b\u522b","title":"\u80cc\u666f\u548c\u76ee\u6807"},{"location":"python/DataAnalysis/ch09/#pandascategorical","text":"pandas\u62e5\u6709\u7279\u6b8a\u7684 Categorical \u7c7b\u578b\uff0c\u7528\u4e8e\u627f\u8f7d\u57fa\u4e8e\u6574\u6570\u7684\u7c7b\u522b\u5c55\u793a\u6216\u7f16\u7801\u7684\u6570\u636e\u3002 fruits = ['apple', 'orange', 'apple', 'apple'] * 2 N = len(fruits) df = pd.DataFrame( { 'fruit': fruits, 'basket_id': np.arange(N), 'count': np.random.randint(3, 15, size=N), 'weight': np.random.uniform(0, 4, size=N) }, columns=['basket_id', 'fruit', 'count', 'weight'] ) print(df) # basket_id fruit count weight # 0 0 apple 8 1.288867 # 1 1 orange 4 3.414430 # 2 2 apple 7 3.222160 # 3 3 apple 14 2.724804 # 4 4 apple 8 3.548828 # 5 5 orange 10 0.918739 # 6 6 apple 4 0.784816 # 7 7 apple 10 3.140607 df['fruit'] \u662f\u4e00\u4e2aPython\u5b57\u7b26\u4e32\u5bf9\u8c61\u7ec4\u6210\u7684\u6570\u7ec4\u3002\u53ef\u4ee5\u901a\u8fc7\u8c03\u7528\u51fd\u6570\u5c06\u5b83\u8f6c\u6362\u4e3a Categorical \u5bf9\u8c61\uff1a fruit_cat = df['fruit'].astype('category') print(fruit_cat) # 0 apple # 1 orange # 2 apple # 3 apple # 4 apple # 5 orange # 6 apple # 7 apple # Name: fruit, dtype: category # Categories (2, object): ['apple', 'orange'] fruit_cat \u7684\u503c\u5e76\u4e0d\u662fNumPy\u6570\u7ec4\uff0c\u800c\u662f pandas.Categorical \u7684\u5b9e\u4f8b\uff1a c = fruit_cat.values print(type(c)) # print(c) # ['apple', 'orange', 'apple', 'apple', 'apple', 'orange', 'apple', 'apple'] # Categories (2, object): ['apple', 'orange'] Categorical \u5bf9\u8c61\u62e5\u6709 categories \u548c codes \u5c5e\u6027\uff1a print(c.categories) # Index(['apple', 'orange'], dtype='object') print(c.codes) # [0 1 0 0 0 1 0 0] \u901a\u8fc7\u5206\u914d\u5df2\u8f6c\u6362\u7684\u7ed3\u679c\u5c06DataFrame\u7684\u4e00\u5217\u8f6c\u6362\u4e3a Categorical \u5bf9\u8c61\uff1a print(df['fruit']) # 0 apple # 1 orange # 2 apple # 3 apple # 4 apple # 5 orange # 6 apple # 7 apple # Name: fruit, dtype: object df['fruit'] = df['fruit'].astype('category') print(df['fruit']) # 0 apple # 1 orange # 2 apple # 3 apple # 4 apple # 5 orange # 6 apple # 7 apple # Name: fruit, dtype: category # Categories (2, object): ['apple', 'orange'] \u4e5f\u53ef\u4ee5\u4ece\u5176\u4ed6Python\u5e8f\u5217\u7c7b\u578b\u76f4\u63a5\u751f\u6210 pandas.Categorical \uff1a my_categories = pd.Categorical(['foo', 'bar', 'baz', 'foo', 'bar']) print(my_categories) # ['foo', 'bar', 'baz', 'foo', 'bar'] # Categories (3, object): ['bar', 'baz', 'foo'] \u4e5f\u53ef\u4ee5\u4f7f\u7528 from_codes \u6784\u9020\u51fd\u6570\u6765\u8f6c\u6362\u5176\u4ed6\u6570\u636e\u6e90\u7684\u5206\u7c7b\u7f16\u7801\u6570\u636e\uff1a categories = ['foo', 'bar', 'baz'] codes = [0, 1, 2, 0, 0, 1] my_cats_2 = pd.Categorical.from_codes(codes, categories) print(my_cats_2) # ['foo', 'bar', 'baz', 'foo', 'foo', 'bar'] # Categories (3, object): ['foo', 'bar', 'baz'] \u8fd9\u4e2a\u672a\u6392\u5e8f\u7684\u5206\u7c7b\u5b9e\u4f8b\u53ef\u4ee5\u4f7f\u7528 as_ordered \u8fdb\u884c\u6392\u5e8f\uff1a print(my_cats_2.as_ordered()) # ['foo', 'bar', 'baz', 'foo', 'foo', 'bar'] # Categories (3, object): ['foo' < 'bar' < 'baz'] \u9664\u975e\u663e\u5f0f\u5730\u6307\u5b9a\uff0c\u5206\u7c7b\u8f6c\u6362\u662f\u4e0d\u4f1a\u6307\u5b9a\u7c7b\u522b\u7684\u987a\u5e8f\u7684\u3002\u56e0\u6b64 categories \u6570\u7ec4\u53ef\u80fd\u4f1a\u4e0e\u8f93\u5165\u6570\u636e\u7684\u987a\u5e8f\u4e0d\u540c\u3002 \u5f53\u4f7f\u7528 from_codes \u6216\u5176\u4ed6\u4efb\u610f\u6784\u9020\u51fd\u6570\u65f6\uff0c\u53ef\u4ee5\u4e3a\u7c7b\u522b\u6307\u5b9a\u4e00\u4e2a\u6709\u610f\u4e49\u7684\u987a\u5e8f\uff1a\u8f93\u51fa\u7684 [foo df.pipe(len) # \u4f20\u9012\u7684\u662flen\u5b9e\u4f8b # 4 def fun(df): return df * 2 fun(df) # 0 1 2 # 0 2.0 4.0 6.0 # 1 2.0 NaN NaN # 2 NaN NaN NaN # 3 NaN 4.0 6.0 df.pipe(fun) # \u4f20\u9012\u7684\u662ffun\u51fd\u6570 # 0 1 2 # 0 2.0 4.0 6.0 # 1 2.0 NaN NaN # 2 NaN NaN NaN # 3 NaN 4.0 6.0 def fun2(x, df): # \u6570\u636e\u662f\u7b2c\u4e8c\u4e2a\u53c2\u6570 return df * 3 df.pipe((fun2, 'df'), 2) # \u6ce8\u610f\u4f20\u503c # 0 1 2 # 0 3.0 6.0 9.0 # 1 3.0 NaN NaN # 2 NaN NaN NaN # 3 NaN 6.0 9.0","title":"DataFrame\u793a\u4f8b\uff1a"},{"location":"python/DataAnalysis/ch09/#series","text":"s = pd.Series([1, 2, 3, 4, 5]) s.pipe(type) # s.pipe(len) # 5 def fun3(x, ss): return ss * 3 s.pipe((fun3, 'ss'), 2) # 0 3 # 1 6 # 2 9 # 3 12 # 4 15 # dtype: int64","title":"Series \u793a\u4f8b\uff1a"},{"location":"python/DataAnalysis/ch09/#groupby_2","text":"df = pd.DataFrame({'A': 'a b a b'.split(), 'B': [1, 2, 3, 4]}) print(df) # A B # 0 a 1 # 1 b 2 # 2 a 3 # 3 b 4 \u6c42\u6bcf\u7ec4\u6700\u5927\u503c\u548c\u6700\u5c0f\u503c\u4e4b\u95f4\u7684\u5dee\u5f02\u3002 df.groupby('A').pipe(lambda x: x.max() - x.min()) # B # A # a 2 # b 2 def mean1(groupby): return groupby.mean() df.groupby(['A']).pipe(mean1) # B # A # a 2.0 # b 3.0","title":"GroupBy \u793a\u4f8b\uff1a"},{"location":"python/DataAnalysis/ch10/","text":"NumPy\u8fdb\u9636 \u00b6 \u5305\u542b\u4ee5\u4e0b\u5185\u5bb9\uff1a ndarray\u5bf9\u8c61\u7684\u5185\u90e8\u673a\u7406 \u9ad8\u7ea7\u6570\u7ec4\u64cd\u4f5c \u91cd\u5851\u6570\u7ec4 C\u987a\u5e8f\u548cF\u987a\u5e8f \u8fde\u63a5\u548c\u5206\u9694\u6570\u7ec4 \u5806\u53e0\u52a9\u624b\uff1ar \u548cc \u91cd\u590d\u5143\u7d20\uff1atile\u548crepeat \u795e\u5947\u7d22\u5f15\u7684\u7b49\u4ef7\u65b9\u6cd5\uff1atake\u548cput \u5e7f\u64ad ufunc\u9ad8\u7ea7\u5e94\u7528 \u7ed3\u6784\u5316\u548c\u8bb0\u5f55\u5f0f\u6570\u7ec4 ndarray\u5bf9\u8c61\u7684\u5185\u90e8\u673a\u7406 \u00b6 NumPy\u7684 ndarray \u63d0\u4f9b\u4e86\u4e00\u79cd\u5c06\u540c\u8d28\u6570\u636e\u5757\uff08\u53ef\u4ee5\u662f\u8fde\u7eed\u6216\u8de8\u8d8a\uff09\u89e3\u91ca\u4e3a\u591a\u7ef4\u6570\u7ec4\u5bf9\u8c61\u7684\u65b9\u5f0f\u3002 ndarray \u7684\u6570\u636e\u7c7b\u578b dtype \u51b3\u5b9a\u4e86\u6570\u636e\u7684\u89e3\u91ca\u65b9\u5f0f\uff0c\u6bd4\u5982\u6d6e\u70b9\u6570\u3001\u6574\u6570\u3001\u5e03\u5c14\u503c\u7b49\u3002 ndarray \u7684\u6240\u6709\u6570\u7ec4\u5bf9\u8c61\u90fd\u662f\u6570\u636e\u5757\u7684\u4e00\u4e2a\u8de8\u5ea6\u89c6\u56fe\uff08strided view\uff09\u3002 \u6570\u7ec4\u89c6\u56fe arr[::2,::-1] \u4e0d\u590d\u5236\u4efb\u4f55\u6570\u636e\u7684\u539f\u56e0\u662f\u4ec0\u4e48\uff1f \u7b80\u5355\u5730\u8bf4\uff0c ndarray \u4e0d\u53ea\u662f\u4e00\u5757\u5185\u5b58\u548c\u4e00\u4e2a dtype \uff0c\u5b83\u8fd8\u6709\u8de8\u5ea6\u4fe1\u606f\uff0c\u8fd9\u4f7f\u5f97\u6570\u7ec4\u80fd\u4ee5\u5404\u79cd\u6b65\u5e45\uff08step size\uff09\u5728\u5185\u5b58\u4e2d\u79fb\u52a8\u3002 \u66f4\u51c6\u786e\u5730\u8bb2\uff0c ndarray \u5185\u90e8\u7531\u4ee5\u4e0b\u5185\u5bb9\u7ec4\u6210\uff1a \u4e00\u4e2a\u6307\u5411\u6570\u636e\uff08\u5185\u5b58\u6216\u5185\u5b58\u6620\u5c04\u6587\u4ef6\u4e2d\u7684\u4e00\u5757\u6570\u636e\uff09\u7684\u6307\u9488\u3002 \u6570\u636e\u7c7b\u578b\u6216 dtype \uff0c\u63cf\u8ff0\u5728\u6570\u7ec4\u4e2d\u7684\u56fa\u5b9a\u5927\u5c0f\u503c\u7684\u683c\u5b50\u3002 \u4e00\u4e2a\u8868\u793a\u6570\u7ec4\u5f62\u72b6\uff08shape\uff09\u7684\u5143\u7ec4\u3002 \u4e00\u4e2a\u8de8\u5ea6\u5143\u7ec4\uff08stride\uff09\uff0c\u5176\u4e2d\u7684\u6574\u6570\u6307\u7684\u662f\u4e3a\u4e86\u524d\u8fdb\u5230\u5f53\u524d\u7ef4\u5ea6\u4e0b\u4e00\u4e2a\u5143\u7d20\u9700\u8981\u201c\u8de8\u8fc7\u201d\u7684\u5b57\u8282\u6570\u3002 \u4f8b\u5982\uff0c\u4e00\u4e2a10\u00d75\u7684\u6570\u7ec4\uff0c\u5176shape\u4e3a(10, 5)\uff1a s = np.ones((10, 5)).shape print(s) # (10, 5) \u4e00\u4e2a\u5178\u578b\u7684\uff08C\u9636\uff093\u00d74\u00d75 float64\u503c\uff088\u5b57\u8282\uff09\u7684\u6570\u7ec4\u5177\u6709\u8de8\u5ea6\uff08160,40,8\uff09\uff08\u901a\u5e38\u7279\u5b9a\u8f74\u4e0a\u7684\u8de8\u5ea6\u8d8a\u5927\uff0c\u6cbf\u7740\u8be5\u8f74\u6267\u884c\u8ba1\u7b97\u7684\u4ee3\u4ef7\u8d8a\u9ad8\uff09\uff1a s = np.ones((3, 4, 5), dtype=np.float64).strides print(s) # (160, 40, 8) \u6570\u7ec4\u8de8\u5ea6\uff08strides\uff09\u662f\u6784\u5efa\u201c\u96f6\u590d\u5236\u201d\u6570\u7ec4\u89c6\u56fe\u7684\u5173\u952e\u56e0\u7d20\u3002 \u6570\u7ec4\u8de8\u5ea6\u751a\u81f3\u53ef\u4ee5\u662f\u8d1f\u7684\uff0c\u8fd9\u4f7f\u5f97\u6570\u7ec4\u80fd\u591f\u7a7f\u8fc7\u5185\u5b58\u201c\u5411\u540e\u201d\u79fb\u52a8\uff08\u4f8b\u5982\uff0c\u5728\u8bf8\u5982obj[::-1]\u6216obj[:, ::-1]\u7684\u5207\u7247\u4e2d\u5c31\u662f\u8fd9\u79cd\u60c5\u51b5\uff09\u3002 NumPy dtype\u5c42\u6b21\u7ed3\u6784 \u00b6 \u6709\u65f6\u5019\u9700\u8981\u901a\u8fc7\u4e00\u4e9b\u4ee3\u7801\u6765\u68c0\u67e5\u6570\u7ec4\u662f\u5426\u5305\u542b\u6574\u6570\u3001\u6d6e\u70b9\u6570\u3001\u5b57\u7b26\u4e32\u6216Python\u5bf9\u8c61\u3002 \u7531\u4e8e\u6d6e\u70b9\u6570\u6709\u591a\u79cd\u7c7b\u578b\uff08float16\u5230float128\uff09\uff0c\u56e0\u6b64\u68c0\u67e5dtype\u662f\u5426\u5728\u7c7b\u578b\u5217\u8868\u4e2d\u4f1a\u975e\u5e38\u9ebb\u70e6\u3002 dtype\u6709\u8d85\u7c7b\uff0c\u5982np.integer\u548cnp.floating\uff0c\u5b83\u4eec\u53ef\u4ee5\u548cnp.issubdtype\u51fd\u6570\u4e00\u8d77\u4f7f\u7528\uff1a ints = np.ones(10, dtype=np.uint16) floats = np.ones(10, dtype=np.float32) \u53ef\u4ee5\u901a\u8fc7\u8c03\u7528\u7c7b\u578b\u7684mro\u65b9\u6cd5\u6765\u67e5\u770b\u7279\u5b9adtype\u7684\u6240\u6709\u7236\u7c7b\uff1a print(np.float64.mro()) # [, # , # , # , # , # , # ] print(np.issubdtype(ints.dtype, np.integer)) # True print(np.issubdtype(floats.dtype, np.floating)) # True print(np.issubdtype(floats.dtype, np.number)) # True print(np.issubdtype(floats.dtype, np.generic)) # True \u9ad8\u7ea7\u6570\u7ec4\u64cd\u4f5c \u00b6 \u91cd\u5851\u6570\u7ec4 \u00b6 \u901a\u5e38\uff0c\u901a\u8fc7 reshape \u5c06\u6570\u7ec4\u4ece\u4e00\u4e2a\u5f62\u72b6\u8f6c\u6362\u4e3a\u53e6\u4e00\u4e2a\u5f62\u72b6\uff0c\u5e76\u4e14\u4e0d\u590d\u5236\u4efb\u4f55\u6570\u636e\u3002 reshape \u91cc\u9762\u6709\u4e24\u79cd\u91cd\u5851\u987a\u5e8f\uff0c\u6309C\u987a\u5e8f\uff08\u884c\u65b9\u5411\uff09\u7684\u91cd\u5851\u548c\u6309Fortran\u987a\u5e8f\uff08\u5217\u65b9\u5411\uff09\u7684\u91cd\u5851\u3002 \u9996\u5148\u662f\u53d6\u6570\uff0c\u7136\u540e\u662f\u653e\u6570\uff0c\u53d6\u6570\u6309\u4ec0\u4e48\u987a\u5e8f\uff0c\u653e\u6570\u5c31\u6309\u4ec0\u4e48\u987a\u5e8f\u3002 \u4e0b\u9762\u662f\u5b98\u7f51\u7684\u89e3\u91ca\uff1a \u2018C\u2019 means to read / write the elements using C-like index order, with the last axis index changing fastest, back to the first axis index changing slowest. \u2018F\u2019 means to read / write the elements using Fortran-like index order, with the first index changing fastest, and the last index changing slowest. Note that the \u2018C\u2019 and \u2018F\u2019 options take no account of the memory layout of the underlying array, and only refer to the order of indexing. \u2018A\u2019 means to read / write the elements in Fortran-like index order if a is Fortran contiguous in memory, C-like order otherwise. \u4e00\u7ef4\u6570\u7ec4\u91cd\u5851\uff1a arr = np.arange(8) print(arr) # [0 1 2 3 4 5 6 7] a = arr.reshape((4, 2), order='C') print(a) # [[0 1] # [2 3] # [4 5] # [6 7]] a = arr.reshape((4, 2), order='F') print(a) # [[0 4] # [1 5] # [2 6] # [3 7]] \u591a\u7ef4\u6570\u7ec4\u91cd\u5851\uff1a\u4f20\u9012\u7684\u5f62\u72b6\u7ef4\u5ea6\u53ef\u4ee5\u6709\u4e00\u4e2a\u503c\u662f-1\uff0c\u8868\u793a\u7ef4\u5ea6\u901a\u8fc7\u6570\u636e\u8fdb\u884c\u63a8\u65ad\uff1a a = arr.reshape((4, 2)).reshape((2, 4)) print(a) # [[0 1 2 3] # [4 5 6 7]] arr = np.arange(15) a = arr.reshape((5, -1)) # 15 / 5 = 3\u5217 print(a) # [[ 0 1 2] # [ 3 4 5] # [ 6 7 8] # [ 9 10 11] # [12 13 14]] print(a.shape) # (5, 3) \u6570\u7ec4\u7684 shape \u5c5e\u6027\u662f\u4e00\u4e2a**\u5143\u7ec4**\uff0c\u5b83\u4e5f\u53ef\u4ee5\u88ab\u4f20\u9012\u7ed9 reshape \uff0c\u63a5\u4e0a\u4f8b\uff1a other_arr = np.ones((3, 5)) print(other_arr.shape) # (3, 5) a = arr.reshape(other_arr.shape) print(a.shape) # (3, 5) reshape \u7684\u53cd\u64cd\u4f5c\u53ef\u4ee5\u5c06\u66f4\u9ad8\u7ef4\u5ea6\u7684\u6570\u7ec4\u8f6c\u6362\u4e3a\u4e00\u7ef4\u6570\u7ec4\uff0c\u8fd9\u79cd\u64cd\u4f5c\u901a\u5e38\u88ab\u6210\u4e3a\u6241\u5e73\u5316\uff08flattening\uff09\u6216\u5206\u6563\u5316\uff08raveling\uff09\u3002 \u5982\u679c\u7ed3\u679c\u4e2d\u7684\u503c\u5728\u539f\u59cb\u6570\u7ec4\u4e2d\u662f\u8fde\u7eed\u7684\uff0c\u5219 ravel \u4e0d\u4f1a\u751f\u6210\u5e95\u5c42\u6570\u503c\u7684\u526f\u672c\u3002 flatten \u65b9\u6cd5\u7684\u884c\u4e3a\u7c7b\u4f3c\u4e8e ravel \uff0c\u4f46\u5b83\u603b\u662f\u751f\u6210\u6570\u636e\u7684\u526f\u672c\u3002 arr = np.arange(15).reshape((5, 3)) print(arr) # [[ 0 1 2] # [ 3 4 5] # [ 6 7 8] # [ 9 10 11] # [12 13 14]] a = arr.ravel() print(a) # [ 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14] a = arr.flatten() print(a) # [ 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14] C\u987a\u5e8f\u548cF\u987a\u5e8f \u00b6 \u6570\u636e\u53ef\u4ee5\u6309\u7167\u4e0d\u540c\u7684\u987a\u5e8f\u8fdb\u884c\u91cd\u5851\u6216\u6241\u5e73\u5316\u3002\u9ed8\u8ba4\u60c5\u51b5\u4e0b\uff0cNumPy\u6570\u7ec4\u662f\u6309\u884c\u65b9\u5411\u987a\u5e8f\u521b\u5efa\u7684\u3002 \u5bf9\u4e8e\u4e00\u4e2a\u4e8c\u7ef4\u7684\u6570\u636e\u6570\u7ec4\uff0c**C\u987a\u5e8f**\u8bf4\u660e\u6570\u7ec4\u6bcf\u884c\u4e2d\u7684\u5143\u7d20\u5b58\u50a8\u5728\u76f8\u90bb\u7684\u5b58\u50a8\u5355\u5143\u4e2d\u3002**F\u987a\u5e8f**\u610f\u5473\u7740\u6bcf\u5217\u6570\u636e\u4e2d\u7684\u503c\u90fd\u5b58\u50a8\u5728\u76f8\u90bb\u7684\u5185\u5b58\u4f4d\u7f6e\u4e2d\u3002 \u53ef\u4ee5\u901a\u8fc7\u8bbe\u7f6e reshape \u548c ravel \u51fd\u6570\u7684 order \u53c2\u6570\u6765\u8868\u793a\u6570\u636e\u5728\u6570\u7ec4\u4e2d\u4f7f\u7528\u54ea\u79cd\u987a\u5e8f\u3002 arr = np.arange(15).reshape((5, 3)) print(arr) # [[ 0 1 2] # [ 3 4 5] # [ 6 7 8] # [ 9 10 11] # [12 13 14]] print(arr.ravel()) # [ 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14] print(arr.ravel('F')) # [ 0 3 6 9 12 1 4 7 10 13 2 5 8 11 14] C\u987a\u5e8f\u548cFortran\u987a\u5e8f\u7684\u6838\u5fc3\u533a\u522b\u5c31\u662f\u5728\u7ef4\u5ea6\u65b9\u5411\u4e0a\u904d\u5386\u7684\u65b9\u5f0f\u3002 C\u987a\u5e8f/\u884c\u65b9\u5411\u987a\u5e8f\u9996\u5148\u904d\u5386\u66f4\u9ad8\u7684\u7ef4\u5ea6\uff08\u4f8b\u5982\uff0c\u5728\u8f740\u4e0a\u884c\u8fdb\u4e4b\u524d\u5148\u5728\u8f741\u4e0a\u884c\u8fdb\uff09\u3002 Fortran\u987a\u5e8f/\u5217\u65b9\u5411\u987a\u5e8f\u6700\u540e\u904d\u5386\u66f4\u9ad8\u7684\u7ef4\u5ea6\uff08\u4f8b\u5982\uff0c\u5728\u8f741\u4e0a\u884c\u8fdb\u4e4b\u524d\u5148\u5728\u8f740\u4e0a\u884c\u8fdb\uff09\u3002 \u6570\u7ec4\u8fde\u63a5\u548c\u5206\u9694 \u00b6 numpy.concatenate \u53ef\u4ee5\u83b7\u53d6\u6570\u7ec4\u7684\u5e8f\u5217\uff08\u5143\u7ec4\u3001\u5217\u8868\u7b49\uff09\uff0c\u5e76\u6cbf\u7740\u8f93\u5165\u8f74\u5c06\u5b83\u4eec\u6309\u987a\u5e8f\u8fde\u63a5\u5728\u4e00\u8d77\uff1a arr1 = np.array( [ [1, 2, 3], [4, 5, 6] ] ) arr2 = np.array( [ [7, 8, 9], [10, 11, 12] ] ) a = np.concatenate([arr1, arr2], axis=0) print(a) # [[ 1 2 3] # [ 4 5 6] # [ 7 8 9] # [10 11 12]] a = np.concatenate([arr1, arr2], axis=1) print(a) # [[ 1 2 3 7 8 9] # [ 4 5 6 10 11 12]] \u5176\u4ed6\u7c7b\u4f3c concatenate \u7684\u51fd\u6570\u3002 vstack \u7c7b\u4f3c concatenate \u6cbf axis=0 \u64cd\u4f5c\uff0c hstack \u7c7b\u4f3c concatenate \u6cbf axis=1 \u64cd\u4f5c\u3002 a = np.vstack((arr1, arr2)) print(a) # [[ 1 2 3] # [ 4 5 6] # [ 7 8 9] # [10 11 12]] a = np.hstack((arr1, arr2)) print(a) # [[ 1 2 3 7 8 9] # [ 4 5 6 10 11 12]] split \u53ef\u4ee5\u5c06\u4e00\u4e2a\u6570\u7ec4\u6cbf\u8f74\u5411\u5207\u7247\u6210\u591a\u4e2a\u6570\u7ec4\u3002\u5148\u770b\u4e00\u7ef4\u6570\u7ec4\u3002 np.split(arr, 3) \u8868\u793a\u5c06\u6570\u7ec4\u62c6\u5206\u65f6\u7684**\u7d22\u5f15\u4f4d\u7f6e** arr = np.array(['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k']) print(arr) # ['a' 'b' 'c' 'd' 'e' 'f' 'g' 'h' 'i' 'j' 'k'] print(np.split(arr, 3)) print(np.split(arr, [3])) # \u4ece\u7d22\u5f15\u4f4d\u7f6e\u4e3a3\u8fdb\u884c\u62c6\u5206 # [array(['a', 'b', 'c'], dtype=', # , # , # , # , # , # ] print(np.issubdtype(ints.dtype, np.integer)) # True print(np.issubdtype(floats.dtype, np.floating)) # True print(np.issubdtype(floats.dtype, np.number)) # True print(np.issubdtype(floats.dtype, np.generic)) # True","title":"NumPy dtype\u5c42\u6b21\u7ed3\u6784"},{"location":"python/DataAnalysis/ch10/#_1","text":"","title":"\u9ad8\u7ea7\u6570\u7ec4\u64cd\u4f5c"},{"location":"python/DataAnalysis/ch10/#_2","text":"\u901a\u5e38\uff0c\u901a\u8fc7 reshape \u5c06\u6570\u7ec4\u4ece\u4e00\u4e2a\u5f62\u72b6\u8f6c\u6362\u4e3a\u53e6\u4e00\u4e2a\u5f62\u72b6\uff0c\u5e76\u4e14\u4e0d\u590d\u5236\u4efb\u4f55\u6570\u636e\u3002 reshape \u91cc\u9762\u6709\u4e24\u79cd\u91cd\u5851\u987a\u5e8f\uff0c\u6309C\u987a\u5e8f\uff08\u884c\u65b9\u5411\uff09\u7684\u91cd\u5851\u548c\u6309Fortran\u987a\u5e8f\uff08\u5217\u65b9\u5411\uff09\u7684\u91cd\u5851\u3002 \u9996\u5148\u662f\u53d6\u6570\uff0c\u7136\u540e\u662f\u653e\u6570\uff0c\u53d6\u6570\u6309\u4ec0\u4e48\u987a\u5e8f\uff0c\u653e\u6570\u5c31\u6309\u4ec0\u4e48\u987a\u5e8f\u3002 \u4e0b\u9762\u662f\u5b98\u7f51\u7684\u89e3\u91ca\uff1a \u2018C\u2019 means to read / write the elements using C-like index order, with the last axis index changing fastest, back to the first axis index changing slowest. \u2018F\u2019 means to read / write the elements using Fortran-like index order, with the first index changing fastest, and the last index changing slowest. Note that the \u2018C\u2019 and \u2018F\u2019 options take no account of the memory layout of the underlying array, and only refer to the order of indexing. \u2018A\u2019 means to read / write the elements in Fortran-like index order if a is Fortran contiguous in memory, C-like order otherwise. \u4e00\u7ef4\u6570\u7ec4\u91cd\u5851\uff1a arr = np.arange(8) print(arr) # [0 1 2 3 4 5 6 7] a = arr.reshape((4, 2), order='C') print(a) # [[0 1] # [2 3] # [4 5] # [6 7]] a = arr.reshape((4, 2), order='F') print(a) # [[0 4] # [1 5] # [2 6] # [3 7]] \u591a\u7ef4\u6570\u7ec4\u91cd\u5851\uff1a\u4f20\u9012\u7684\u5f62\u72b6\u7ef4\u5ea6\u53ef\u4ee5\u6709\u4e00\u4e2a\u503c\u662f-1\uff0c\u8868\u793a\u7ef4\u5ea6\u901a\u8fc7\u6570\u636e\u8fdb\u884c\u63a8\u65ad\uff1a a = arr.reshape((4, 2)).reshape((2, 4)) print(a) # [[0 1 2 3] # [4 5 6 7]] arr = np.arange(15) a = arr.reshape((5, -1)) # 15 / 5 = 3\u5217 print(a) # [[ 0 1 2] # [ 3 4 5] # [ 6 7 8] # [ 9 10 11] # [12 13 14]] print(a.shape) # (5, 3) \u6570\u7ec4\u7684 shape \u5c5e\u6027\u662f\u4e00\u4e2a**\u5143\u7ec4**\uff0c\u5b83\u4e5f\u53ef\u4ee5\u88ab\u4f20\u9012\u7ed9 reshape \uff0c\u63a5\u4e0a\u4f8b\uff1a other_arr = np.ones((3, 5)) print(other_arr.shape) # (3, 5) a = arr.reshape(other_arr.shape) print(a.shape) # (3, 5) reshape \u7684\u53cd\u64cd\u4f5c\u53ef\u4ee5\u5c06\u66f4\u9ad8\u7ef4\u5ea6\u7684\u6570\u7ec4\u8f6c\u6362\u4e3a\u4e00\u7ef4\u6570\u7ec4\uff0c\u8fd9\u79cd\u64cd\u4f5c\u901a\u5e38\u88ab\u6210\u4e3a\u6241\u5e73\u5316\uff08flattening\uff09\u6216\u5206\u6563\u5316\uff08raveling\uff09\u3002 \u5982\u679c\u7ed3\u679c\u4e2d\u7684\u503c\u5728\u539f\u59cb\u6570\u7ec4\u4e2d\u662f\u8fde\u7eed\u7684\uff0c\u5219 ravel \u4e0d\u4f1a\u751f\u6210\u5e95\u5c42\u6570\u503c\u7684\u526f\u672c\u3002 flatten \u65b9\u6cd5\u7684\u884c\u4e3a\u7c7b\u4f3c\u4e8e ravel \uff0c\u4f46\u5b83\u603b\u662f\u751f\u6210\u6570\u636e\u7684\u526f\u672c\u3002 arr = np.arange(15).reshape((5, 3)) print(arr) # [[ 0 1 2] # [ 3 4 5] # [ 6 7 8] # [ 9 10 11] # [12 13 14]] a = arr.ravel() print(a) # [ 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14] a = arr.flatten() print(a) # [ 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14]","title":"\u91cd\u5851\u6570\u7ec4"},{"location":"python/DataAnalysis/ch10/#cf","text":"\u6570\u636e\u53ef\u4ee5\u6309\u7167\u4e0d\u540c\u7684\u987a\u5e8f\u8fdb\u884c\u91cd\u5851\u6216\u6241\u5e73\u5316\u3002\u9ed8\u8ba4\u60c5\u51b5\u4e0b\uff0cNumPy\u6570\u7ec4\u662f\u6309\u884c\u65b9\u5411\u987a\u5e8f\u521b\u5efa\u7684\u3002 \u5bf9\u4e8e\u4e00\u4e2a\u4e8c\u7ef4\u7684\u6570\u636e\u6570\u7ec4\uff0c**C\u987a\u5e8f**\u8bf4\u660e\u6570\u7ec4\u6bcf\u884c\u4e2d\u7684\u5143\u7d20\u5b58\u50a8\u5728\u76f8\u90bb\u7684\u5b58\u50a8\u5355\u5143\u4e2d\u3002**F\u987a\u5e8f**\u610f\u5473\u7740\u6bcf\u5217\u6570\u636e\u4e2d\u7684\u503c\u90fd\u5b58\u50a8\u5728\u76f8\u90bb\u7684\u5185\u5b58\u4f4d\u7f6e\u4e2d\u3002 \u53ef\u4ee5\u901a\u8fc7\u8bbe\u7f6e reshape \u548c ravel \u51fd\u6570\u7684 order \u53c2\u6570\u6765\u8868\u793a\u6570\u636e\u5728\u6570\u7ec4\u4e2d\u4f7f\u7528\u54ea\u79cd\u987a\u5e8f\u3002 arr = np.arange(15).reshape((5, 3)) print(arr) # [[ 0 1 2] # [ 3 4 5] # [ 6 7 8] # [ 9 10 11] # [12 13 14]] print(arr.ravel()) # [ 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14] print(arr.ravel('F')) # [ 0 3 6 9 12 1 4 7 10 13 2 5 8 11 14] C\u987a\u5e8f\u548cFortran\u987a\u5e8f\u7684\u6838\u5fc3\u533a\u522b\u5c31\u662f\u5728\u7ef4\u5ea6\u65b9\u5411\u4e0a\u904d\u5386\u7684\u65b9\u5f0f\u3002 C\u987a\u5e8f/\u884c\u65b9\u5411\u987a\u5e8f\u9996\u5148\u904d\u5386\u66f4\u9ad8\u7684\u7ef4\u5ea6\uff08\u4f8b\u5982\uff0c\u5728\u8f740\u4e0a\u884c\u8fdb\u4e4b\u524d\u5148\u5728\u8f741\u4e0a\u884c\u8fdb\uff09\u3002 Fortran\u987a\u5e8f/\u5217\u65b9\u5411\u987a\u5e8f\u6700\u540e\u904d\u5386\u66f4\u9ad8\u7684\u7ef4\u5ea6\uff08\u4f8b\u5982\uff0c\u5728\u8f741\u4e0a\u884c\u8fdb\u4e4b\u524d\u5148\u5728\u8f740\u4e0a\u884c\u8fdb\uff09\u3002","title":"C\u987a\u5e8f\u548cF\u987a\u5e8f"},{"location":"python/DataAnalysis/ch10/#_3","text":"numpy.concatenate \u53ef\u4ee5\u83b7\u53d6\u6570\u7ec4\u7684\u5e8f\u5217\uff08\u5143\u7ec4\u3001\u5217\u8868\u7b49\uff09\uff0c\u5e76\u6cbf\u7740\u8f93\u5165\u8f74\u5c06\u5b83\u4eec\u6309\u987a\u5e8f\u8fde\u63a5\u5728\u4e00\u8d77\uff1a arr1 = np.array( [ [1, 2, 3], [4, 5, 6] ] ) arr2 = np.array( [ [7, 8, 9], [10, 11, 12] ] ) a = np.concatenate([arr1, arr2], axis=0) print(a) # [[ 1 2 3] # [ 4 5 6] # [ 7 8 9] # [10 11 12]] a = np.concatenate([arr1, arr2], axis=1) print(a) # [[ 1 2 3 7 8 9] # [ 4 5 6 10 11 12]] \u5176\u4ed6\u7c7b\u4f3c concatenate \u7684\u51fd\u6570\u3002 vstack \u7c7b\u4f3c concatenate \u6cbf axis=0 \u64cd\u4f5c\uff0c hstack \u7c7b\u4f3c concatenate \u6cbf axis=1 \u64cd\u4f5c\u3002 a = np.vstack((arr1, arr2)) print(a) # [[ 1 2 3] # [ 4 5 6] # [ 7 8 9] # [10 11 12]] a = np.hstack((arr1, arr2)) print(a) # [[ 1 2 3 7 8 9] # [ 4 5 6 10 11 12]] split \u53ef\u4ee5\u5c06\u4e00\u4e2a\u6570\u7ec4\u6cbf\u8f74\u5411\u5207\u7247\u6210\u591a\u4e2a\u6570\u7ec4\u3002\u5148\u770b\u4e00\u7ef4\u6570\u7ec4\u3002 np.split(arr, 3) \u8868\u793a\u5c06\u6570\u7ec4\u62c6\u5206\u65f6\u7684**\u7d22\u5f15\u4f4d\u7f6e** arr = np.array(['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k']) print(arr) # ['a' 'b' 'c' 'd' 'e' 'f' 'g' 'h' 'i' 'j' 'k'] print(np.split(arr, 3)) print(np.split(arr, [3])) # \u4ece\u7d22\u5f15\u4f4d\u7f6e\u4e3a3\u8fdb\u884c\u62c6\u5206 # [array(['a', 'b', 'c'], dtype='|t| [0.025 0.975] # ------------------------------------------------------------------------------ # x1 0.1783 0.053 3.364 0.001 0.073 0.283 # x2 0.2230 0.046 4.818 0.000 0.131 0.315 # x3 0.5010 0.080 6.237 0.000 0.342 0.660 # ============================================================================== # Omnibus: 4.662 Durbin-Watson: 0 -0.002327 # Prob(Omnibus): 0.097 Jarque-Bera (JB): 4.098 # Skew: 0.481 Prob(JB): 0.129 # Kurtosis: 3.243 Cond. No. 1.74 # ============================================================================== # # Notes: # [1] R\u00b2 is computed without centering (uncentered) since the model does not contain a constant. # [2] Standard Errors assume that the covariance matrix of the errors is correctly specified. \u5047\u8bbe\u6240\u6709\u6a21\u578b\u53c2\u6570\u90fd\u5728DataFrame\u4e2d\uff1a data = pd.DataFrame(X, columns=['col0', 'col1', 'col2']) data['y'] = y print(data[:5]) # col0 col1 col2 y # 0 -0.129468 -1.212753 0.504225 0.427863 # 1 0.302910 -0.435742 -0.254180 -0.673480 # 2 -0.328522 -0.025302 0.138351 -0.090878 # 3 -0.351475 -0.719605 -0.258215 -0.489494 # 4 1.243269 -0.373799 -0.522629 -0.128941 \u73b0\u5728\u53ef\u4ee5\u4f7f\u7528 statsmodels \u516c\u5f0fAPI\u548cPatsy\u516c\u5f0f\u5b57\u7b26\u4e32\u3002\u89c2\u5bdf statsmodels \u5982\u4f55\u5c06\u7ed3\u679c\u4f5c\u4e3a\u5e26\u6709DataFrame\u5217\u540d\u79f0\u7684Series\u8fd4\u56de\u3002 results = smf.ols('y ~ col0 + col1 + col2', data=data).fit() print(results.params) # Intercept 0.033559 # col0 0.176149 # col1 0.224826 # col2 0.514808 # dtype: float64 \u7ed9\u5b9a\u65b0\u7684\u6837\u672c\u5916\u6570\u636e\u540e\uff0c\u53ef\u4ee5\u6839\u636e\u4f30\u8ba1\u7684\u6a21\u578b\u53c2\u6570\u8ba1\u7b97\u9884\u6d4b\u503c\uff1a print(results.predict(data[:5])) # 0 -0.002327 # 1 -0.141904 # 2 0.041226 # 3 -0.323070 # 4 -0.100535 # dtype: float64 \u8bc4\u4f30\u65f6\u95f4\u5e8f\u5217\u5904\u7406 \u00b6 statsmodels\u4e2d\u7684\u53e6\u4e00\u7c7b\u6a21\u578b\u7528\u4e8e\u65f6\u95f4\u5e8f\u5217\u5206\u6790\u3002\u5176\u4e2d\u5305\u62ec\u81ea\u56de\u5f52\u8fc7\u7a0b\uff0c\u5361\u5c14\u66fc\u6ee4\u6ce2\u548c\u5176\u4ed6\u72b6\u6001\u7a7a\u95f4\u6a21\u578b\uff0c\u4ee5\u53ca\u591a\u53d8\u91cf\u81ea\u56de\u5f52\u6a21\u578b\u3002 \u4e0b\u4f8b\u6a21\u62df\u4e00\u4e9b\u5177\u6709\u81ea\u56de\u5f52\u7ed3\u6784\u548c\u566a\u58f0\u7684\u65f6\u95f4\u5e8f\u5217\u6570\u636e\uff0c\u8be5\u6570\u636e\u5177\u6709\u53c2\u6570\u4e3a0.8\u548c-0.4\u7684AR\uff082\uff09\u7ed3\u6784\uff08\u4e24\u4e2a\u6ede\u540e\uff09\u3002 init_x = 4 values = [init_x, init_x] N = 1000 b0 = 0.8 b1 = -0.4 noise = dnorm(0, 0.1, N) for i in range(N): new_x = values[-1] * b0 + values[-2] * b1 + noise[i] values.append(new_x) \u5f53\u62df\u5408\u4e00\u4e2aAR\u6a21\u578b\u65f6\uff0c\u4f60\u53ef\u80fd\u4e0d\u77e5\u9053\u5305\u542b\u7684\u6ede\u540e\u9879\u7684\u6570\u91cf\uff0c\u6240\u4ee5\u53ef\u4ee5\u7528\u66f4\u5927\u7684\u6ede\u540e\u6570\u6765\u62df\u5408\u8be5\u6a21\u578b\uff1a MAXLAGS = 5 model = sm.tsa.AR(values) results = model.fit(MAXLAGS) print(results.params) # NotImplementedError: AR has been removed from statsmodels and replaced with statsmodels.tsa.ar_model.AutoReg. sikit-learn\u4ecb\u7ecd \u00b6 scikit-learn\uff08http://scikit-learn.org\uff09\u662f\u4f7f\u7528\u6700\u5e7f\u6cdb\u4e14\u6700\u53d7\u4fe1\u4efb\u7684\u901a\u7528Python\u673a\u5668\u5b66\u4e60\u5e93\u3002\\ \u5b83\u5305\u542b\u5e7f\u6cdb\u7684\u6807\u51c6\u76d1\u7763\u7684\u548c\u65e0\u76d1\u7763\u7684\u673a\u5668\u5b66\u4e60\u65b9\u6cd5\uff0c\u5305\u62ec\u7528\u4e8e\u6a21\u578b\u9009\u62e9\u548c\u8bc4\u4f30\u3001\u6570\u636e\u8f6c\u6362\u3001\u6570\u636e\u52a0\u8f7d\u548c\u6a21\u578b\u6301\u4e45\u5316\u7684\u5de5\u5177\u3002\\ \u8fd9\u4e9b\u6a21\u578b\u53ef\u7528\u4e8e\u5206\u7c7b\u3001\u805a\u7c7b\u3001\u9884\u6d4b\u548c\u5176\u4ed6\u5e38\u89c1\u4efb\u52a1\u3002\\ pandas\u975e\u5e38\u9002\u5408\u5728\u6a21\u578b\u62df\u5408\u524d\u5904\u7406\u6570\u636e\u96c6\u3002 \u4e3e\u4e2a\u4f8b\u5b50\uff0c\u7528\u4e00\u4e2aKaggle\u7ade\u8d5b\u7684\u7ecf\u5178\u6570\u636e\u96c6\uff0c\u5173\u4e8e\u6cf0\u5766\u5c3c\u514b\u53f7\u4e58\u5ba2\u7684\u751f\u8fd8\u7387\u3002\u6211\u4eec\u7528pandas\u52a0\u8f7d\u6d4b\u8bd5\u548c\u8bad\u7ec3\u6570\u636e\u96c6\uff1a import pandas as pd from sklearn.linear_model import LogisticRegression from sklearn.linear_model import LogisticRegressionCV from sklearn.model_selection import cross_val_score train = pd.read_csv('../datasets/titanic/train.csv') test = pd.read_csv('../datasets/titanic/test.csv') print(train[:4]) # PassengerId Survived Pclass ... Fare Cabin Embarked # 0 1 0 3 ... 7.2500 NaN S # 1 2 1 1 ... 71.2833 C85 C # 2 3 1 3 ... 7.9250 NaN S # 3 4 1 1 ... 53.1000 C123 S \u50cfstatsmodels\u548cscikit-learn\u901a\u5e38\u4e0d\u80fd\u63d0\u4f9b\u7f3a\u5931\u6570\u636e\uff0c\u56e0\u6b64\u6211\u4eec\u8981\u68c0\u67e5\u5404\u5217\uff0c\u770b\u770b\u662f\u5426\u6709\u5305\u542b\u7f3a\u5931\u6570\u636e\uff1a print(train.isnull().sum()) # PassengerId 0 # Survived 0 # Pclass 0 # Name 0 # Sex 0 # Age 177 # SibSp 0 # Parch 0 # Ticket 0 # Fare 0 # Cabin 687 # Embarked 2 # dtype: int64 print(test.isnull().sum()) # PassengerId 0 # Pclass 0 # Name 0 # Sex 0 # Age 86 # SibSp 0 # Parch 0 # Ticket 0 # Fare 1 # Cabin 327 # Embarked 0 # dtype: int64 \u5728\u50cf\u8fd9\u6837\u7684\u7edf\u8ba1\u548c\u673a\u5668\u5b66\u4e60\u7684\u4f8b\u5b50\u4e2d\uff0c\u4e00\u4e2a\u5178\u578b\u7684\u4efb\u52a1\u662f\u6839\u636e\u6570\u636e\u4e2d\u7684\u7279\u5f81\u6765\u9884\u6d4b\u4e58\u5ba2\u662f\u5426\u80fd\u5e78\u5b58\u4e0b\u6765\u3002\\ \u5c06\u6a21\u578b\u62df\u5408\u5230\u8bad\u7ec3\u6570\u636e\u96c6\u4e0a\uff0c\u7136\u540e\u5728\u6837\u672c\u5916\u6d4b\u8bd5\u6570\u636e\u96c6\u4e0a\u8fdb\u884c\u8bc4\u4f30\u3002\\ \u5982\u679c\u7528Age\u4f5c\u4e3a\u9884\u6d4b\uff0c\u4f46\u5b83\u7f3a\u5c11\u6570\u636e\u3002\u9700\u8981\u8fdb\u884c\u7f3a\u5931\u6570\u636e\u63d2\u8865\uff08imputation\uff09\uff0c\u5e76\u4f7f\u7528\u8bad\u7ec3\u6570\u636e\u96c6\u7684\u4e2d\u95f4\u503c\u586b\u5145\u4e24\u4e2a\u8868\u4e2d\u7684\u7a7a\u503c\uff1a impute_value = train['Age'].median() train['Age'] = train['Age'].fillna(impute_value) test['Age'] = test['Age'].fillna(impute_value) \u73b0\u5728\u5efa\u7acb\u6a21\u578b\u3002\\ \u6dfb\u52a0\u4e00\u5217IsFemale\u4f5c\u4e3a\u2019Sex\u2019\u5217\u7684\u7f16\u7801\u7248\u672c\uff1a train['IsFemale'] = (train['Sex'] == 'female').astype(int) test['IsFemale'] = (test['Sex'] == 'female').astype(int) \u786e\u5b9a\u4e00\u4e9b\u6a21\u578b\u53d8\u91cf\u5e76\u521b\u5efaNumPy\u6570\u7ec4\uff1a predictors = ['Pclass', 'IsFemale', 'Age'] X_train = train[predictors].values X_test = test[predictors].values y_train = train['Survived'].values print(X_train[:5]) # [[ 3. 0. 22.] # [ 1. 1. 38.] # [ 3. 1. 26.] # [ 1. 1. 35.] # [ 3. 0. 35.]] print(y_train[:5]) # [0 1 1 1 0] \u4f7f\u7528scikit-learn\u7684LogisticRegression\u6a21\u578b\u521b\u5efa\u4e00\u4e2a\u6a21\u578b\u5b9e\u4f8b\uff1a model = LogisticRegression() \u4e0estatsmodels\u7c7b\u4f3c\uff0c\u4f7f\u7528\u6a21\u578b\u7684fit\u65b9\u6cd5\u5728\u8bad\u7ec3\u6570\u636e\u4e0a\u62df\u5408\u6a21\u578b\uff1a result = model.fit(X_train, y_train) print(result) # LogisticRegression() \u4f7f\u7528model.predict\u4e3a\u6d4b\u8bd5\u6570\u636e\u96c6\u5f62\u6210\u9884\u6d4b\uff1a y_predict = model.predict(X_test) print(y_predict[:10]) # [0 0 0 0 1 0 1 0 1 0] \u5b9e\u9645\u4e0a\uff0c\u6a21\u578b\u8bad\u7ec3\u4e2d\u7ecf\u5e38\u5b58\u5728\u8bb8\u591a\u9644\u52a0\u7684\u590d\u6742\u5c42\u6b21\u3002\\ \u8bb8\u591a\u6a21\u578b\u5177\u6709\u53ef\u4ee5\u8c03\u6574\u7684\u53c2\u6570\uff0c\u5e76\u4e14\u5b58\u5728\u53ef\u7528\u4e8e\u53c2\u6570\u8c03\u6574\u7684\u4ea4\u53c9\u9a8c\u8bc1\u7b49\u6280\u672f\u4ee5\u907f\u514d\u8fc7\u5ea6\u62df\u5408\u8bad\u7ec3\u6570\u636e\u3002\\ \u8fd9\u901a\u5e38\u53ef\u4ee5\u5728\u65b0\u6570\u636e\u4e0a\u4ea7\u751f\u66f4\u597d\u7684\u9884\u6d4b\u6027\u80fd\u6216\u7a33\u5065\u6027\u3002\u4ea4\u53c9\u9a8c\u8bc1\u901a\u8fc7\u5206\u5272\u8bad\u7ec3\u6570\u636e\u6765\u6a21\u62df\u6837\u672c\u5916\u9884\u6d4b\u3002\\ \u57fa\u4e8e\u50cf\u5747\u65b9\u8bef\u5dee\u4e4b\u7c7b\u7684\u6a21\u578b\u51c6\u786e\u5ea6\u5206\u6570\uff0c\u53ef\u4ee5\u5bf9\u6a21\u578b\u53c2\u6570\u6267\u884c\u7f51\u683c\u641c\u7d22\u3002\\ \u4e00\u4e9b\u6a21\u578b\uff0c\u5982\u903b\u8f91\u56de\u5f52\uff0c\u5177\u6709\u5185\u7f6e\u4ea4\u53c9\u9a8c\u8bc1\u7684\u4f30\u8ba1\u7c7b\u3002\\ \u4f8b\u5982\uff0cLogisticRegressionCV\u7c7b\u53ef\u4ee5\u4e0e\u4e00\u4e2a\u53c2\u6570\u4e00\u8d77\u4f7f\u7528\uff0c\u8be5\u53c2\u6570\u8868\u793a\u7f51\u683c\u641c\u7d22\u5728\u6a21\u578b\u6b63\u5219\u5316\u53c2\u6570C\u4e0a\u7684\u7ec6\u81f4\u5ea6\uff1a model_cv = LogisticRegressionCV() result = model_cv.fit(X_train, y_train) print(result) # LogisticRegressionCV() \u8981\u624b\u52a8\u8fdb\u884c\u4ea4\u53c9\u9a8c\u8bc1\uff0c\u53ef\u4ee5\u4f7f\u7528cross_val_score\u51fd\u6570\uff0c\u8be5\u51fd\u6570\u5904\u7406\u6570\u636e\u62c6\u5206\u8fc7\u7a0b\u3002\\ \u4f8b\u5982\uff0c\u4e3a\u4e86\u7528\u6211\u4eec\u7684\u6a21\u578b\u4e0e\u8bad\u7ec3\u6570\u636e\u7684\u56db\u4e2a\u975e\u91cd\u53e0\u5206\u5272\u8fdb\u884c\u4ea4\u53c9\u9a8c\u8bc1\uff0c\u53ef\u4ee5\u8fd9\u6837\u505a\uff1a model = LogisticRegression(C=10) scores = cross_val_score(model, X_train, y_train, cv=4) print(scores) # [0.77578475 0.79820628 0.77578475 0.78828829] \u9ed8\u8ba4\u8bc4\u5206\u6307\u6807\u662f\u4f9d\u8d56\u4e8e\u6a21\u578b\u7684\uff0c\u4f46\u53ef\u4ee5\u9009\u62e9\u660e\u786e\u7684\u8bc4\u5206\u51fd\u6570\u3002\u7ecf\u8fc7\u4ea4\u53c9\u9a8c\u8bc1\u7684\u6a21\u578b\u9700\u8981\u66f4\u957f\u65f6\u95f4\u7684\u8bad\u7ec3\uff0c\u4f46\u901a\u5e38\u53ef\u4ee5\u4ea7\u751f\u66f4\u597d\u7684\u6a21\u578b\u6027\u80fd\u3002","title":"Python\u5efa\u6a21\u5e93\u4ecb\u7ecd"},{"location":"python/DataAnalysis/ch11/#python","text":"","title":"Python\u5efa\u6a21\u5e93\u4ecb\u7ecd"},{"location":"python/DataAnalysis/ch11/#pandas","text":"\u4ecb\u7ecd\u4e24\u4e2a\u6d41\u884c\u7684\u5efa\u6a21\u5de5\u5177\u5305\uff1a [statsmodels]http://statsmodels.org\uff09 [scikit-learn]http://scikit-learn.org\uff09 import pandas as pd import numpy as np \u4f7f\u7528pandas\u7528\u4e8e\u6570\u636e\u8f7d\u5165\u548c\u6570\u636e\u6e05\u6d17\uff0c\u4e4b\u540e\u5207\u6362\u5230\u6a21\u578b\u5e93\u53bb\u5efa\u7acb\u6a21\u578b\u662f\u4e00\u4e2a\u5e38\u89c1\u7684\u6a21\u578b\u5f00\u53d1\u5de5\u4f5c\u6d41\u3002 \u5728\u673a\u5668\u5b66\u4e60\u4e2d\uff0c\u7279\u5f81\u5de5\u7a0b\u662f\u6a21\u578b\u5f00\u53d1\u7684\u91cd\u8981\u90e8\u5206\u4e4b\u4e00\u3002 \u7279\u5f81\u5de5\u7a0b\u662f\u6307\u4ece\u539f\u751f\u6570\u636e\u96c6\u4e2d\u63d0\u53d6\u53ef\u7528\u4e8e\u6a21\u578b\u4e0a\u4e0b\u6587\u7684\u6709\u6548\u4fe1\u606f\u7684\u6570\u636e\u8f6c\u6362\u8fc7\u7a0b\u6216\u5206\u6790\u3002 pandas\u548c\u5176\u4ed6\u5206\u6790\u5e93\u7684\u7ed3\u5408\u70b9\u901a\u5e38\u662fNumPy\u6570\u7ec4\u3002 \u8981\u5c06DataFrame\u8f6c\u6362\u4e3aNumPy\u6570\u7ec4\uff0c\u4f7f\u7528 .values \u5c5e\u6027\uff1a df = pd.DataFrame( { 'x0': [1, 2, 3, 4, 5], 'x1': [0.01, -0.01, 0.25, -4.1, 0.], 'y': [-1.5, 0., 3.6, 1.3, -2.] } ) print(df) # x0 x1 y # 0 1 0.01 -1.5 # 1 2 -0.01 0.0 # 2 3 0.25 3.6 # 3 4 -4.10 1.3 # 4 5 0.00 -2.0 print(df.columns) # Index(['x0', 'x1', 'y'], dtype='object') print(df.values) # [[ 1. 0.01 -1.5 ] # [ 2. -0.01 0. ] # [ 3. 0.25 3.6 ] # [ 4. -4.1 1.3 ] # [ 5. 0. -2. ]] \u5c06\u6570\u7ec4\u518d\u8f6c\u6362\u4e3aDataFrame\uff1a df2 = pd.DataFrame(df.values, columns=['one', 'two', 'three']) # \u9012\u4e00\u4e2a\u542b\u6709\u5217\u540d\u7684\u4e8c\u7ef4ndarray print(df2) # one two three # 0 1.0 0.01 -1.5 # 1 2.0 -0.01 0.0 # 2 3.0 0.25 3.6 # 3 4.0 -4.10 1.3 # 4 5.0 0.00 -2.0 .values \u5c5e\u6027\u4e00\u822c\u5728\u6570\u636e\u662f\u540c\u6784\u5316\u7684\u65f6\u5019\u4f7f\u7528\u2014\u2014\u4f8b\u5982\uff0c\u90fd\u662f\u6570\u5b57\u7c7b\u578b\u7684\u65f6\u5019\u3002\u5982\u679c\u6570\u636e\u662f\u5f02\u6784\u5316\u7684\uff0c\u7ed3\u679c\u5c06\u662fPython\u5bf9\u8c61\u7684 ndarray \uff1a \u6dfb\u52a0\u4e00\u4e2a\u975e\u6570\u5b57\u7c7b\u578b\u7684\u5217\u3002 df3 = df.copy() df3['category'] = pd.Categorical(['a', 'b', 'a', 'a', 'b'], categories=['a', 'b']) print(df3) # x0 x1 y category # 0 1 0.01 -1.5 a # 1 2 -0.01 0.0 b # 2 3 0.25 3.6 a # 3 4 -4.10 1.3 a # 4 5 0.00 -2.0 b print(df3.values) # [[1 0.01 -1.5 'a'] # [2 -0.01 0.0 'b'] # [3 0.25 3.6 'a'] # [4 -4.1 1.3 'a'] # [5 0.0 -2.0 'b']] \u901a\u8fc7 loc \u7d22\u5f15\u548c values \u4f7f\u7528\u4e00\u90e8\u5206\u5217\u6570\u636e\u3002 model_cols = ['x0', 'x1'] result = df.loc[:, model_cols].values print(result) # [[ 1. 0.01] # [ 2. -0.01] # [ 3. 0.25] # [ 4. -4.1 ] # [ 5. 0. ]] \u5982\u679c\u6211\u4f7f\u7528\u865a\u62df\u53d8\u91cf\u66ff\u4ee3 df3 \u7684 category \u5217\uff0c\u5148\u521b\u5efa\u865a\u62df\u53d8\u91cf\uff0c\u4e4b\u540e\u5220\u9664 categroy \u5217\uff0c\u7136\u540e\u8fde\u63a5\u7ed3\u679c\uff1a dummies = pd.get_dummies(df3.category, prefix='category') print(dummies) # category_a category_b # 0 1 0 # 1 0 1 # 2 1 0 # 3 1 0 # 4 0 1 data_with_dummies = df3.drop('category', axis=1).join(dummies) print(data_with_dummies) # x0 x1 y category_a category_b # 0 1 0.01 -1.5 1 0 # 1 2 -0.01 0.0 0 1 # 2 3 0.25 3.6 1 0 # 3 4 -4.10 1.3 1 0 # 4 5 0.00 -2.0 0 1","title":"pandas\u4e0e\u5efa\u6a21\u4ee3\u7801\u7684\u7ed3\u5408"},{"location":"python/DataAnalysis/ch11/#patsy","text":"\u6837\u672c\u7684\u8868\u793a\u5f62\u5f0f\uff1a \u5728\u6570\u636e\u6316\u6398\u8fc7\u7a0b\u4e2d\uff0c\u6837\u672c\u4ee5\u7279\u5f81\u503c\u77e9\u9635X\u548c\u76ee\u6807\u503c\u5411\u91cfY\u7684\u5f62\u5f0f\u8868\u793a\u3002 \u5bb9\u91cf\u4e3a n \uff0c\u6709 m \u4e2a\u7279\u5f81\u7684\u6837\u672c\uff0c\u5176\u7279\u5f81\u503c\u77e9\u9635X\u7531 n \u4e2a\u7ef4\u5ea6\u4e3a m \u7684\u5217\u5411\u91cf\u7ec4\u6210\uff0c\u7b2c j \u4e2a\u5217\u5411\u91cf\u4e3a\u6837\u672c\u4e2d\u7b2c j \u4e2a\u4e2a\u4f53\u7684\u7279\u5f81\u503c\u5411\u91cf\uff1b \u76ee\u6807\u503c\u5411\u91cfY\u7684\u7b2c j \u4e2a\u5206\u91cf\u4e3a\u6837\u672c\u4e2d\u7b2c j \u4e2a\u4e2a\u4f53\u7684\u76ee\u6807\u503c\u3002 \u53c2\u8003\uff1a How formulas work [Patsy](https://patsy.readthedocs.io/\uff09\u662f\u4e00\u4e2a\u7528\u4e8e\u63cf\u8ff0\u7edf\u8ba1\u6a21\u578b\uff08\u5c24\u5176\u662f\u7ebf\u6027\u6a21\u578b\uff09\u7684Python\u5e93\u3002 \u5b83\u4f7f\u7528\u4e00\u79cd\u5c0f\u578b\u57fa\u4e8e\u5b57\u7b26\u4e32\u7684\"\u516c\u5f0f\u8bed\u6cd5\"\u3002 Patsy\u80fd\u591f\u5f88\u597d\u5730\u652f\u6301 statsmodels \u4e2d\u7279\u5b9a\u7684\u7ebf\u6027\u6a21\u578b\u3002 \u50cf y ~ x0 + x1 \u8fd9\u79cd a + b \u7684\u8bed\u6cd5\u5e76\u4e0d\u4ee3\u8868\u5c06 a \u548c b \u76f8\u52a0\uff0c\u800c\u662f\u4ee3\u8868\u4e3a\u6a21\u578b\u521b\u5efa\u7684\u8bbe\u8ba1\u77e9\u9635\u7684\u672f\u8bed\uff08terms in the design matrix\uff09\u3002 patsy.dmatrices \u51fd\u6570\uff0c\u53d6\u4e00\u4e2a\u516c\u5f0f\u5b57\u7b26\u4e32\u548c\u4e00\u4e2a\u6570\u636e\u96c6\uff08\u53ef\u4ee5\u4f7fDataFrame\u6216dict\uff09\uff0c\u7136\u540e\u4e3a\u7ebf\u6027\u6a21\u578b\u4ea7\u751f\u8bbe\u8ba1\u77e9\u9635\uff1a import pandas as pd import numpy as np import patsy from patsy import dmatrices, dmatrix, demo_data df = pd.DataFrame( { 'x0': [1, 2, 3, 4, 5], 'x1': [0.01, -0.01, 0.25, -4.1, 0.], 'y': [-1.5, 0., 3.6, 1.3, -2.] } ) print(df) # x0 x1 y # 0 1 0.01 -1.5 # 1 2 -0.01 0.0 # 2 3 0.25 3.6 # 3 4 -4.10 1.3 # 4 5 0.00 -2.0 y, X = patsy.dmatrices('y ~ x0 + x1', df) print(y) # [[-1.5] # [ 0. ] # [ 3.6] # [ 1.3] # [-2. ]] print(X) # [[ 1. 1. 0.01] # [ 1. 2. -0.01] # [ 1. 3. 0.25] # [ 1. 4. -4.1 ] # [ 1. 5. 0. ]] print(np.asarray(y)) # Patsy\u7684DesignMatrix\u5b9e\u4f8b\uff0c\u542b\u6709\u9644\u52a0\u5143\u6570\u636e\u7684NumPy.ndarray # [[-1.5] # [ 0. ] # [ 3.6] # [ 1.3] # [-2. ]] print(np.asarray(X)) # Patsy\u7684DesignMatrix\u5b9e\u4f8b\uff0c\u542b\u6709\u9644\u52a0\u5143\u6570\u636e\u7684NumPy.ndarray # [[ 1. 1. 0.01] # [ 1. 2. -0.01] # [ 1. 3. 0.25] # [ 1. 4. -4.1 ] # [ 1. 5. 0. ]] \u4e0a\u9762X\u8f93\u51fa\u4e2d\u7684Intercept(\u6700\u5de6\u8fb9\u4e00\u5217)\u662f\u4ece\u54ea\u91cc\u6765\u7684\u3002 \u8fd9\u5176\u5b9e\u662f\u7ebf\u6027\u6a21\u578b\u7684\u4e00\u4e2a\u60ef\u4f8b\uff0c\u6bd4\u5982\u666e\u901a\u6700\u5c0f\u4e8c\u4e58\u56de\u5f52\u6cd5\uff08ordinary least squares regression\uff09\u3002 \u53ef\u4ee5\u53bb\u6389\u8fd9\u4e2a\u622a\u8ddd\uff08intercept\uff09\uff0c\u901a\u8fc7 y ~ x0 + x1 + 0 \u7ed9\u6a21\u578b\u3002 y, X = patsy.dmatrices('y ~ x0 + x1 + 0', df) print(X) # [[ 1. 0.01] # [ 2. -0.01] # [ 3. 0.25] # [ 4. -4.1 ] # [ 5. 0. ]] \u8fd9\u79cdPatsy\u5bf9\u8c61\u53ef\u4ee5\u76f4\u63a5\u4f20\u5165\u4e00\u4e2a\u7b97\u6cd5\uff0c\u6bd4\u5982 numpy.linalg.lstsq \uff0c\u6765\u8fdb\u884c\u666e\u901a\u6700\u5c0f\u4e8c\u4e58\u56de\u5f52\u7684\u8ba1\u7b97 coef, resid, _, _ =np.linalg.lstsq(X, y, rcond=1) # \u6700\u5c0f\u4e8c\u4e58\u6cd5 print(coef) # [[ 0.00925424] # [-0.25485421]] print(resid) # [19.72552896] coef = pd.Series(coef.squeeze(), index=X.design_info.column_names) print(coef) # x0 0.009254 # x1 -0.254854 # dtype: float64","title":"\u4f7f\u7528Patsy\u521b\u5efa\u6a21\u578b\u63cf\u8ff0"},{"location":"python/DataAnalysis/ch11/#patsy_1","text":"\u53ef\u4ee5\u5c06Python\u4ee3\u7801\u6df7\u5408\u5230\u4f60\u7684Patsy\u516c\u5f0f\u4e2d\uff0c\u5728\u6267\u884c\u516c\u5f0f\u65f6\uff0cPatsy\u5e93\u5c06\u5c1d\u8bd5\u5728\u5c01\u95ed\u4f5c\u7528\u57df\u4e2d\u5bfb\u627e\u4f60\u4f7f\u7528\u7684\u51fd\u6570\uff1a y, X = patsy.dmatrices('y ~ x0 + np.log(np.abs(x1) +1)', df) print(X) # [[1. 1. 0.00995033] # [1. 2. 0.00995033] # [1. 3. 0.22314355] # [1. 4. 1.62924054] # [1. 5. 0. ]] \u4e00\u4e9b\u5e38\u7528\u7684\u53d8\u91cf\u53d8\u6362\uff0c\u5305\u62ec\u6807\u51c6\u5316\uff08standardizing (\u5e73\u5747\u503c0\uff0c\u65b9\u5dee1\uff09\u548c\u4e2d\u5fc3\u5316\uff08\u51cf\u53bb\u5e73\u5747\u503c\uff09\u3002Patsy\u6709\u5185\u5efa\u7684\u51fd\u6570\u53ef\u4ee5\u505a\u5230\u8fd9\u4e9b\u3002 y, X = patsy.dmatrices('y ~ standardize(x0) + center(x1)', df) print(X) # [[ 1. -1.41421356 0.78 ] # [ 1. -0.70710678 0.76 ] # [ 1. 0. 1.02 ] # [ 1. 0.70710678 -3.33 ] # [ 1. 1.41421356 0.77 ]] \u4f5c\u4e3a\u5efa\u6a21\u7684\u4e00\u90e8\u5206\uff0c\u6211\u4eec\u53ef\u80fd\u4f1a\u5728\u4e00\u4e2a\u6570\u636e\u53ca\u4e0a\u8bad\u7ec3\u6a21\u578b\uff0c\u7136\u540e\u5728\u53e6\u4e00\u4e2a\u6570\u636e\u53ca\u4e0a\u8bc4\u4ef7\u6a21\u578b\u3002 \u5f53\u4f7f\u7528\u4e2d\u5fc3\u5316\u6216\u6807\u51c6\u5316\u8fd9\u6837\u7684\u8f6c\u6362\u65f6\uff0c\u6211\u4eec\u5fc5\u987b\u6ce8\u610f\uff0c\u5fc5\u987b\u7528\u6a21\u578b\u5728\u65b0\u6570\u636e\u96c6\u4e0a\u505a\u9884\u6d4b\u3002 \u8fd9\u53eb\u505a\u72b6\u6001\u53d8\u6362\uff08stateful transformations\uff09\u3002 \u56e0\u4e3a\u6211\u4eec\u5fc5\u987b\u7528\u539f\u672c\u5728\u8bad\u7ec3\u96c6\u4e0a\u5f97\u5230\u7684\u5e73\u5747\u503c\u548c\u6807\u51c6\u5dee\uff0c\u7528\u5728\u65b0\u7684\u6570\u636e\u96c6\u4e0a\u3002 new_df = pd.DataFrame( { 'x0': [6, 7, 8, 9], 'x1': [3.1, -0.5, 0, 2.3], 'y': [1, 2, 3, 4] } ) new_X = patsy.build_design_matrices([X.design_info], new_df) print(new_X) # [DesignMatrix with shape (4, 3) # Intercept standardize(x0) center(x1) # 1 2.12132 3.87 # 1 2.82843 0.27 # 1 3.53553 0.77 # 1 4.24264 3.07 # Terms: # 'Intercept' (column 0), 'standardize(x0)' (column 1), 'center(x1)' (column 2)] \u56e0\u4e3a\u52a0\u53f7\uff08+\uff09\u5728Patsy\u516c\u5f0f\u7684\u4e0a\u4e0b\u6587\u4e2d\u5e76\u4e0d\u662f\u52a0\u6cd5\u7684\u610f\u601d\uff0c\u5f53\u60f3\u8981\u5bf9\u6570\u636e\u96c6\u4e2d\u4e24\u5217\u6309\u5217\u540d\u76f8\u52a0\u65f6\uff0c\u5fc5\u987b\u5c06\u5217\u540d\u5c01\u88c5\u5230\u7279\u6b8a\u7684I\u51fd\u6570\u4e2d\uff1a y, X = patsy.dmatrices('y ~ I(x0 + x1)', df) print(X) # [[ 1. 1.01] # [ 1. 1.99] # [ 1. 3.25] # [ 1. -0.1 ] # [ 1. 5. ]]","title":"Patsy\u516c\u5f0f\u4e2d\u7684\u6570\u636e\u8f6c\u6362"},{"location":"python/DataAnalysis/ch11/#categoricalpatsy","text":"\u975e\u6570\u503c\u578b\u6570\u636e\u53ef\u4ee5\u901a\u8fc7\u5f88\u591a\u79cd\u65b9\u5f0f\u53d8\u4e3a\u4e00\u4e2a\u6a21\u578b\u8bbe\u8ba1\u77e9\u9635\u3002 \u5f53\u6211\u4eec\u5728Patsy\u516c\u5f0f\u4e2d\u4f7f\u7528\u975e\u6570\u503c\u672f\u8bed\u65f6\uff0c\u8fd9\u4e9b\u7c7b\u578b\u6570\u636e\u9ed8\u8ba4\u4f1a\u88ab\u8f6c\u6362\u4e3a\u54d1\u53d8\u91cf\u3002\u5982\u679c\u6709\u622a\u8ddd\uff0c\u4e00\u4e2a\u5c42\u7ea7\u4e0a\u7684\u622a\u8ddd\u4f1a\u88ab\u820d\u5f03\uff0c\u9632\u6b62\u51fa\u73b0\u5171\u7ebf\u6027\u3002 data = pd.DataFrame( { 'key1': ['a', 'a', 'b', 'b', 'a', 'b', 'a', 'b'], 'key2': [0, 1, 0, 1, 0, 1, 0, 0], 'v1': [1, 2, 3, 4, 5, 6, 7, 8], 'v2': [-1, 0, 2.5, -0.5, 4., -1.2, 0.2, -1.7] } ) y, X = patsy.dmatrices('v2 ~ key1', data) print(y) # [[-1. ] # [ 0. ] # [ 2.5] # [-0.5] # [ 4. ] # [-1.2] # [ 0.2] # [-1.7]] print(X) # [[1. 0.] # [1. 0.] # [1. 1.] # [1. 1.] # [1. 0.] # [1. 1.] # [1. 0.] # [1. 1.]] \u5982\u679c\u4ece\u6a21\u578b\u4e2d\u820d\u5f03\u622a\u8ddd\uff0c\u6bcf\u4e2a\u7c7b\u578b\u7684\u5217\u4f1a\u88ab\u5305\u542b\u5728\u6a21\u578b\u8bbe\u8ba1\u77e9\u9635\u4e2d\u3002 y, X = patsy.dmatrices('v2 ~ key1 + 0', data) print(X) # [[1. 0.] # [1. 0.] # [0. 1.] # [0. 1.] # [1. 0.] # [0. 1.] # [1. 0.] # [0. 1.]] \u6570\u503c\u578b\u5217\u53ef\u4ee5\u901a\u8fc7C\u51fd\u6570\uff0c\u53d8\u4e3a\u7c7b\u578b\u5217\uff1a y, X = patsy.dmatrices('v2 ~ C(key2)', data) print(X) # [[1. 0.] # [1. 1.] # [1. 0.] # [1. 1.] # [1. 0.] # [1. 1.] # [1. 0.] # [1. 0.]] \u5f53\u6211\u4eec\u5728\u4e00\u4e2a\u6a21\u578b\u4e2d\u4f7f\u7528\u591a\u4e2a\u7c7b\u578b\u672f\u8bed\u65f6\uff0c\u4f1a\u53d8\u5f97\u66f4\u590d\u6742\u4e00\u4e9b\uff0c\u4e4b\u524d\u7528key1:key2\u7684\u5f62\u5f0f\u6765\u5305\u542b\u6709\u4ea4\u96c6\u7684\u672f\u8bed\uff0c \u8fd9\u79cd\u65b9\u6cd5\u53ef\u4ee5\u7528\u4e8e\u4f7f\u7528\u591a\u4e2a\u672f\u8bed\uff0c\u4f8b\u5982\uff0c\u4e00\u4e2a\u65b9\u6cd5\u5206\u6790\u6a21\u578b\uff08analysis of variance (ANOVA) models\uff09\uff1a data['key2'] = data['key2'].map({0: 'zero', 1: 'one'}) print(data) # key1 key2 v1 v2 # 0 a zero 1 -1.0 # 1 a one 2 0.0 # 2 b zero 3 2.5 # 3 b one 4 -0.5 # 4 a zero 5 4.0 # 5 b one 6 -1.2 # 6 a zero 7 0.2 # 7 b zero 8 -1.7 y, X = patsy.dmatrices('v2 ~ key1 + key2', data) print(X) # [[1. 0. 1.] # [1. 0. 0.] # [1. 1. 1.] # [1. 1. 0.] # [1. 0. 1.] # [1. 1. 0.] # [1. 0. 1.] # [1. 1. 1.]] y, X = patsy.dmatrices('v2 ~ key1 + key2 + key1:key2', data) print(X) # [[1. 0. 1. 0.] # [1. 0. 0. 0.] # [1. 1. 1. 1.] # [1. 1. 0. 0.] # [1. 0. 1. 0.] # [1. 1. 0. 0.] # [1. 0. 1. 0.] # [1. 1. 1. 1.]]","title":"\u5206\u7c7b\u6570\u636eCategorical\u548cPatsy"},{"location":"python/DataAnalysis/ch11/#statsmodels","text":"statsmodels \u662f\u4e00\u4e2aPython\u5e93\uff0c\u7528\u4e8e\u62df\u5408\u591a\u79cd\u7edf\u8ba1\u6a21\u578b\uff0c\u6267\u884c\u7edf\u8ba1\u6d4b\u8bd5\u4ee5\u53ca\u6570\u636e\u63a2\u7d22\u548c\u53ef\u89c6\u5316\u3002 statsmodels \u5305\u542b\u66f4\u591a\u7684\u201c\u7ecf\u5178\u201d\u9891\u7387\u5b66\u6d3e\u7edf\u8ba1\u65b9\u6cd5\uff0c\u800c\u8d1d\u53f6\u65af\u65b9\u6cd5\u548c\u673a\u5668\u5b66\u4e60\u6a21\u578b\u53ef\u5728\u5176\u4ed6\u5e93\u4e2d\u627e\u5230\u3002 \u5305\u542b\u5728statsmodels\u4e2d\u7684\u4e00\u4e9b\u6a21\u578b\uff1a \u7ebf\u6027\u6a21\u578b\uff0c\u5e7f\u4e49\u7ebf\u6027\u6a21\u578b\u548c\u9c81\u68d2\u7ebf\u6027\u6a21\u578b \u7ebf\u6027\u6df7\u5408\u6548\u5e94\u6a21\u578b \u65b9\u5dee\u5206\u6790\uff08ANOVA\uff09\u65b9\u6cd5 \u65f6\u95f4\u5e8f\u5217\u8fc7\u7a0b\u548c\u72b6\u6001\u7a7a\u95f4\u6a21\u578b \u5e7f\u4e49\u7684\u77e9\u91cf\u6cd5 import pandas as pd import statsmodels.api as sm import statsmodels.formula.api as smf import numpy as np import random","title":"statsmodels\u4ecb\u7ecd"},{"location":"python/DataAnalysis/ch11/#_1","text":"\u7edf\u8ba1\u6a21\u578b\u4e2d\u6709\u51e0\u79cd\u7ebf\u6027\u56de\u5f52\u6a21\u578b\uff0c\u4ece\u8f83\u57fa\u672c\u7684\uff08\u4f8b\u5982\uff0c\u666e\u901a\u6700\u5c0f\u4e8c\u4e58\uff09\u5230\u66f4\u590d\u6742\u7684\uff08\u4f8b\u5982\uff0c\u8fed\u4ee3\u91cd\u65b0\u52a0\u6743\u7684\u6700\u5c0f\u4e8c\u4e58\uff09\u3002 tatsmodels \u4e2d\u7684\u7ebf\u6027\u6a21\u578b\u6709\u4e24\u4e2a\u4e0d\u540c\u7684\u4e3b\u8981\u63a5\u53e3\uff0c\u8fd9\u4e9b\u63a5\u53e3\u901a\u8fc7\u8fd9\u4e9bAPI\u6a21\u5757\u5bfc\u5165\u6765\u8bbf\u95ee\uff1a \u57fa\u4e8e\u6570\u7ec4 \u57fa\u4e8e\u516c\u5f0f \u4e0b\u9762\u7684\u4f8b\u5b50\u662f\u8c03\u7528\u5df2\u77e5\u53c2\u6570beta\u7684\u6a21\u578b\u3002\u5728\u8fd9\u79cd\u60c5\u51b5\u4e0b\uff0c dnorm \u662f\u7528\u4e8e\u751f\u6210\u5177\u6709\u7279\u5b9a\u5747\u503c\u548c\u65b9\u5dee\u7684\u6b63\u6001\u5206\u5e03\u6570\u636e\u7684\u8f85\u52a9\u51fd\u6570\u3002 def dnorm (mean, variance, size=1): if isinstance(size, int): size = size, return mean + np.sqrt(variance) * np.random.randn(*size) np.random.seed(12345) N = 100 X = np.c_[ dnorm(0, 0.4, size=N), dnorm(0, 0.6, size=N), dnorm(0, 0.2, size=N) ] eps = dnorm(0, 0.1, size=N) beta = [0.1, 0.3, 0.5] y = np.dot(X, beta) + eps print(X[:5]) # [[-0.12946849 -1.21275292 0.50422488] # [ 0.30291036 -0.43574176 -0.25417986] # [-0.32852189 -0.02530153 0.13835097] # [-0.35147471 -0.71960511 -0.25821463] # [ 1.2432688 -0.37379916 -0.52262905]] print(y[:5]) # [ 0.42786349 -0.67348041 -0.09087764 -0.48949442 -0.12894109] \u7ebf\u6027\u6a21\u578b\u901a\u5e38\u4e0e\u6211\u4eec\u5728Patsy\u4e2d\u770b\u5230\u7684\u622a\u8ddd\u9879\u76f8\u5339\u914d\u3002 sm.add_constant \u51fd\u6570\u53ef\u4ee5\u5c06\u622a\u8ddd\u5217\u6dfb\u52a0\u5230\u73b0\u6709\u77e9\u9635\uff1a X_model = sm.add_constant(X) print(X_model[:5]) # [[ 1. -0.12946849 -1.21275292 0.50422488] # [ 1. 0.30291036 -0.43574176 -0.25417986] # [ 1. -0.32852189 -0.02530153 0.13835097] # [ 1. -0.35147471 -0.71960511 -0.25821463] # [ 1. 1.2432688 -0.37379916 -0.52262905]] sm.OLS \u7c7b\u53ef\u4ee5\u62df\u5408\u4e00\u4e2a\u6700\u5c0f\u4e8c\u4e58\u7ebf\u6027\u56de\u5f52\uff1a model = sm.OLS(y, X) \u6a21\u578b\u7684 fit \u65b9\u6cd5\u8fd4\u56de\u4e00\u4e2a\u56de\u5f52\u7ed3\u679c\u5bf9\u8c61\uff0c\u8be5\u5bf9\u8c61\u5305\u542b\u4e86\u4f30\u8ba1\u7684\u6a21\u578b\u53c2\u6570\u548c\u5176\u4ed6\u7684\u8bca\u65ad\uff1a results = model.fit() print(results.params) # [0.17826108 0.22303962 0.50095093] \u8c03\u7528 summary \u65b9\u6cd5\u53ef\u4ee5\u6253\u5370\u51fa\u4e00\u4e2a\u6a21\u578b\u7684\u8bca\u65ad\u7ec6\u8282\uff0c\u6b64\u5904\u7684\u53c2\u6570\u540d\u79f0\u5df2\u88ab\u8d4b\u4e88\u901a\u7528\u540d\u79f0 x1 \u3001 x2 \u7b49\uff1a print(results.summary()) # OLS Regression Results # ======================================================================================= # Dep. Variable: y R-squared (uncentered): 0.430 # Model: OLS Adj. R-squared (uncentered): 0.413 # Method: Least Squares F-statistic: 24.42 # Date: Sat, 16 Oct 2021 Prob (F-statistic): 7.44e-12 # Time: 14:21:45 Log-Likelihood: -34.305 # No. Observations: 100 AIC: 74.61 # Df Residuals: 97 BIC: 82.42 # Df Model: 3 # Covariance Type: nonrobust # ============================================================================== # coef std err t P>|t| [0.025 0.975] # ------------------------------------------------------------------------------ # x1 0.1783 0.053 3.364 0.001 0.073 0.283 # x2 0.2230 0.046 4.818 0.000 0.131 0.315 # x3 0.5010 0.080 6.237 0.000 0.342 0.660 # ============================================================================== # Omnibus: 4.662 Durbin-Watson: 0 -0.002327 # Prob(Omnibus): 0.097 Jarque-Bera (JB): 4.098 # Skew: 0.481 Prob(JB): 0.129 # Kurtosis: 3.243 Cond. No. 1.74 # ============================================================================== # # Notes: # [1] R\u00b2 is computed without centering (uncentered) since the model does not contain a constant. # [2] Standard Errors assume that the covariance matrix of the errors is correctly specified. \u5047\u8bbe\u6240\u6709\u6a21\u578b\u53c2\u6570\u90fd\u5728DataFrame\u4e2d\uff1a data = pd.DataFrame(X, columns=['col0', 'col1', 'col2']) data['y'] = y print(data[:5]) # col0 col1 col2 y # 0 -0.129468 -1.212753 0.504225 0.427863 # 1 0.302910 -0.435742 -0.254180 -0.673480 # 2 -0.328522 -0.025302 0.138351 -0.090878 # 3 -0.351475 -0.719605 -0.258215 -0.489494 # 4 1.243269 -0.373799 -0.522629 -0.128941 \u73b0\u5728\u53ef\u4ee5\u4f7f\u7528 statsmodels \u516c\u5f0fAPI\u548cPatsy\u516c\u5f0f\u5b57\u7b26\u4e32\u3002\u89c2\u5bdf statsmodels \u5982\u4f55\u5c06\u7ed3\u679c\u4f5c\u4e3a\u5e26\u6709DataFrame\u5217\u540d\u79f0\u7684Series\u8fd4\u56de\u3002 results = smf.ols('y ~ col0 + col1 + col2', data=data).fit() print(results.params) # Intercept 0.033559 # col0 0.176149 # col1 0.224826 # col2 0.514808 # dtype: float64 \u7ed9\u5b9a\u65b0\u7684\u6837\u672c\u5916\u6570\u636e\u540e\uff0c\u53ef\u4ee5\u6839\u636e\u4f30\u8ba1\u7684\u6a21\u578b\u53c2\u6570\u8ba1\u7b97\u9884\u6d4b\u503c\uff1a print(results.predict(data[:5])) # 0 -0.002327 # 1 -0.141904 # 2 0.041226 # 3 -0.323070 # 4 -0.100535 # dtype: float64","title":"\u8bc4\u4f30\u7ebf\u6027\u6a21\u578b"},{"location":"python/DataAnalysis/ch11/#_2","text":"statsmodels\u4e2d\u7684\u53e6\u4e00\u7c7b\u6a21\u578b\u7528\u4e8e\u65f6\u95f4\u5e8f\u5217\u5206\u6790\u3002\u5176\u4e2d\u5305\u62ec\u81ea\u56de\u5f52\u8fc7\u7a0b\uff0c\u5361\u5c14\u66fc\u6ee4\u6ce2\u548c\u5176\u4ed6\u72b6\u6001\u7a7a\u95f4\u6a21\u578b\uff0c\u4ee5\u53ca\u591a\u53d8\u91cf\u81ea\u56de\u5f52\u6a21\u578b\u3002 \u4e0b\u4f8b\u6a21\u62df\u4e00\u4e9b\u5177\u6709\u81ea\u56de\u5f52\u7ed3\u6784\u548c\u566a\u58f0\u7684\u65f6\u95f4\u5e8f\u5217\u6570\u636e\uff0c\u8be5\u6570\u636e\u5177\u6709\u53c2\u6570\u4e3a0.8\u548c-0.4\u7684AR\uff082\uff09\u7ed3\u6784\uff08\u4e24\u4e2a\u6ede\u540e\uff09\u3002 init_x = 4 values = [init_x, init_x] N = 1000 b0 = 0.8 b1 = -0.4 noise = dnorm(0, 0.1, N) for i in range(N): new_x = values[-1] * b0 + values[-2] * b1 + noise[i] values.append(new_x) \u5f53\u62df\u5408\u4e00\u4e2aAR\u6a21\u578b\u65f6\uff0c\u4f60\u53ef\u80fd\u4e0d\u77e5\u9053\u5305\u542b\u7684\u6ede\u540e\u9879\u7684\u6570\u91cf\uff0c\u6240\u4ee5\u53ef\u4ee5\u7528\u66f4\u5927\u7684\u6ede\u540e\u6570\u6765\u62df\u5408\u8be5\u6a21\u578b\uff1a MAXLAGS = 5 model = sm.tsa.AR(values) results = model.fit(MAXLAGS) print(results.params) # NotImplementedError: AR has been removed from statsmodels and replaced with statsmodels.tsa.ar_model.AutoReg.","title":"\u8bc4\u4f30\u65f6\u95f4\u5e8f\u5217\u5904\u7406"},{"location":"python/DataAnalysis/ch11/#sikit-learn","text":"scikit-learn\uff08http://scikit-learn.org\uff09\u662f\u4f7f\u7528\u6700\u5e7f\u6cdb\u4e14\u6700\u53d7\u4fe1\u4efb\u7684\u901a\u7528Python\u673a\u5668\u5b66\u4e60\u5e93\u3002\\ \u5b83\u5305\u542b\u5e7f\u6cdb\u7684\u6807\u51c6\u76d1\u7763\u7684\u548c\u65e0\u76d1\u7763\u7684\u673a\u5668\u5b66\u4e60\u65b9\u6cd5\uff0c\u5305\u62ec\u7528\u4e8e\u6a21\u578b\u9009\u62e9\u548c\u8bc4\u4f30\u3001\u6570\u636e\u8f6c\u6362\u3001\u6570\u636e\u52a0\u8f7d\u548c\u6a21\u578b\u6301\u4e45\u5316\u7684\u5de5\u5177\u3002\\ \u8fd9\u4e9b\u6a21\u578b\u53ef\u7528\u4e8e\u5206\u7c7b\u3001\u805a\u7c7b\u3001\u9884\u6d4b\u548c\u5176\u4ed6\u5e38\u89c1\u4efb\u52a1\u3002\\ pandas\u975e\u5e38\u9002\u5408\u5728\u6a21\u578b\u62df\u5408\u524d\u5904\u7406\u6570\u636e\u96c6\u3002 \u4e3e\u4e2a\u4f8b\u5b50\uff0c\u7528\u4e00\u4e2aKaggle\u7ade\u8d5b\u7684\u7ecf\u5178\u6570\u636e\u96c6\uff0c\u5173\u4e8e\u6cf0\u5766\u5c3c\u514b\u53f7\u4e58\u5ba2\u7684\u751f\u8fd8\u7387\u3002\u6211\u4eec\u7528pandas\u52a0\u8f7d\u6d4b\u8bd5\u548c\u8bad\u7ec3\u6570\u636e\u96c6\uff1a import pandas as pd from sklearn.linear_model import LogisticRegression from sklearn.linear_model import LogisticRegressionCV from sklearn.model_selection import cross_val_score train = pd.read_csv('../datasets/titanic/train.csv') test = pd.read_csv('../datasets/titanic/test.csv') print(train[:4]) # PassengerId Survived Pclass ... Fare Cabin Embarked # 0 1 0 3 ... 7.2500 NaN S # 1 2 1 1 ... 71.2833 C85 C # 2 3 1 3 ... 7.9250 NaN S # 3 4 1 1 ... 53.1000 C123 S \u50cfstatsmodels\u548cscikit-learn\u901a\u5e38\u4e0d\u80fd\u63d0\u4f9b\u7f3a\u5931\u6570\u636e\uff0c\u56e0\u6b64\u6211\u4eec\u8981\u68c0\u67e5\u5404\u5217\uff0c\u770b\u770b\u662f\u5426\u6709\u5305\u542b\u7f3a\u5931\u6570\u636e\uff1a print(train.isnull().sum()) # PassengerId 0 # Survived 0 # Pclass 0 # Name 0 # Sex 0 # Age 177 # SibSp 0 # Parch 0 # Ticket 0 # Fare 0 # Cabin 687 # Embarked 2 # dtype: int64 print(test.isnull().sum()) # PassengerId 0 # Pclass 0 # Name 0 # Sex 0 # Age 86 # SibSp 0 # Parch 0 # Ticket 0 # Fare 1 # Cabin 327 # Embarked 0 # dtype: int64 \u5728\u50cf\u8fd9\u6837\u7684\u7edf\u8ba1\u548c\u673a\u5668\u5b66\u4e60\u7684\u4f8b\u5b50\u4e2d\uff0c\u4e00\u4e2a\u5178\u578b\u7684\u4efb\u52a1\u662f\u6839\u636e\u6570\u636e\u4e2d\u7684\u7279\u5f81\u6765\u9884\u6d4b\u4e58\u5ba2\u662f\u5426\u80fd\u5e78\u5b58\u4e0b\u6765\u3002\\ \u5c06\u6a21\u578b\u62df\u5408\u5230\u8bad\u7ec3\u6570\u636e\u96c6\u4e0a\uff0c\u7136\u540e\u5728\u6837\u672c\u5916\u6d4b\u8bd5\u6570\u636e\u96c6\u4e0a\u8fdb\u884c\u8bc4\u4f30\u3002\\ \u5982\u679c\u7528Age\u4f5c\u4e3a\u9884\u6d4b\uff0c\u4f46\u5b83\u7f3a\u5c11\u6570\u636e\u3002\u9700\u8981\u8fdb\u884c\u7f3a\u5931\u6570\u636e\u63d2\u8865\uff08imputation\uff09\uff0c\u5e76\u4f7f\u7528\u8bad\u7ec3\u6570\u636e\u96c6\u7684\u4e2d\u95f4\u503c\u586b\u5145\u4e24\u4e2a\u8868\u4e2d\u7684\u7a7a\u503c\uff1a impute_value = train['Age'].median() train['Age'] = train['Age'].fillna(impute_value) test['Age'] = test['Age'].fillna(impute_value) \u73b0\u5728\u5efa\u7acb\u6a21\u578b\u3002\\ \u6dfb\u52a0\u4e00\u5217IsFemale\u4f5c\u4e3a\u2019Sex\u2019\u5217\u7684\u7f16\u7801\u7248\u672c\uff1a train['IsFemale'] = (train['Sex'] == 'female').astype(int) test['IsFemale'] = (test['Sex'] == 'female').astype(int) \u786e\u5b9a\u4e00\u4e9b\u6a21\u578b\u53d8\u91cf\u5e76\u521b\u5efaNumPy\u6570\u7ec4\uff1a predictors = ['Pclass', 'IsFemale', 'Age'] X_train = train[predictors].values X_test = test[predictors].values y_train = train['Survived'].values print(X_train[:5]) # [[ 3. 0. 22.] # [ 1. 1. 38.] # [ 3. 1. 26.] # [ 1. 1. 35.] # [ 3. 0. 35.]] print(y_train[:5]) # [0 1 1 1 0] \u4f7f\u7528scikit-learn\u7684LogisticRegression\u6a21\u578b\u521b\u5efa\u4e00\u4e2a\u6a21\u578b\u5b9e\u4f8b\uff1a model = LogisticRegression() \u4e0estatsmodels\u7c7b\u4f3c\uff0c\u4f7f\u7528\u6a21\u578b\u7684fit\u65b9\u6cd5\u5728\u8bad\u7ec3\u6570\u636e\u4e0a\u62df\u5408\u6a21\u578b\uff1a result = model.fit(X_train, y_train) print(result) # LogisticRegression() \u4f7f\u7528model.predict\u4e3a\u6d4b\u8bd5\u6570\u636e\u96c6\u5f62\u6210\u9884\u6d4b\uff1a y_predict = model.predict(X_test) print(y_predict[:10]) # [0 0 0 0 1 0 1 0 1 0] \u5b9e\u9645\u4e0a\uff0c\u6a21\u578b\u8bad\u7ec3\u4e2d\u7ecf\u5e38\u5b58\u5728\u8bb8\u591a\u9644\u52a0\u7684\u590d\u6742\u5c42\u6b21\u3002\\ \u8bb8\u591a\u6a21\u578b\u5177\u6709\u53ef\u4ee5\u8c03\u6574\u7684\u53c2\u6570\uff0c\u5e76\u4e14\u5b58\u5728\u53ef\u7528\u4e8e\u53c2\u6570\u8c03\u6574\u7684\u4ea4\u53c9\u9a8c\u8bc1\u7b49\u6280\u672f\u4ee5\u907f\u514d\u8fc7\u5ea6\u62df\u5408\u8bad\u7ec3\u6570\u636e\u3002\\ \u8fd9\u901a\u5e38\u53ef\u4ee5\u5728\u65b0\u6570\u636e\u4e0a\u4ea7\u751f\u66f4\u597d\u7684\u9884\u6d4b\u6027\u80fd\u6216\u7a33\u5065\u6027\u3002\u4ea4\u53c9\u9a8c\u8bc1\u901a\u8fc7\u5206\u5272\u8bad\u7ec3\u6570\u636e\u6765\u6a21\u62df\u6837\u672c\u5916\u9884\u6d4b\u3002\\ \u57fa\u4e8e\u50cf\u5747\u65b9\u8bef\u5dee\u4e4b\u7c7b\u7684\u6a21\u578b\u51c6\u786e\u5ea6\u5206\u6570\uff0c\u53ef\u4ee5\u5bf9\u6a21\u578b\u53c2\u6570\u6267\u884c\u7f51\u683c\u641c\u7d22\u3002\\ \u4e00\u4e9b\u6a21\u578b\uff0c\u5982\u903b\u8f91\u56de\u5f52\uff0c\u5177\u6709\u5185\u7f6e\u4ea4\u53c9\u9a8c\u8bc1\u7684\u4f30\u8ba1\u7c7b\u3002\\ \u4f8b\u5982\uff0cLogisticRegressionCV\u7c7b\u53ef\u4ee5\u4e0e\u4e00\u4e2a\u53c2\u6570\u4e00\u8d77\u4f7f\u7528\uff0c\u8be5\u53c2\u6570\u8868\u793a\u7f51\u683c\u641c\u7d22\u5728\u6a21\u578b\u6b63\u5219\u5316\u53c2\u6570C\u4e0a\u7684\u7ec6\u81f4\u5ea6\uff1a model_cv = LogisticRegressionCV() result = model_cv.fit(X_train, y_train) print(result) # LogisticRegressionCV() \u8981\u624b\u52a8\u8fdb\u884c\u4ea4\u53c9\u9a8c\u8bc1\uff0c\u53ef\u4ee5\u4f7f\u7528cross_val_score\u51fd\u6570\uff0c\u8be5\u51fd\u6570\u5904\u7406\u6570\u636e\u62c6\u5206\u8fc7\u7a0b\u3002\\ \u4f8b\u5982\uff0c\u4e3a\u4e86\u7528\u6211\u4eec\u7684\u6a21\u578b\u4e0e\u8bad\u7ec3\u6570\u636e\u7684\u56db\u4e2a\u975e\u91cd\u53e0\u5206\u5272\u8fdb\u884c\u4ea4\u53c9\u9a8c\u8bc1\uff0c\u53ef\u4ee5\u8fd9\u6837\u505a\uff1a model = LogisticRegression(C=10) scores = cross_val_score(model, X_train, y_train, cv=4) print(scores) # [0.77578475 0.79820628 0.77578475 0.78828829] \u9ed8\u8ba4\u8bc4\u5206\u6307\u6807\u662f\u4f9d\u8d56\u4e8e\u6a21\u578b\u7684\uff0c\u4f46\u53ef\u4ee5\u9009\u62e9\u660e\u786e\u7684\u8bc4\u5206\u51fd\u6570\u3002\u7ecf\u8fc7\u4ea4\u53c9\u9a8c\u8bc1\u7684\u6a21\u578b\u9700\u8981\u66f4\u957f\u65f6\u95f4\u7684\u8bad\u7ec3\uff0c\u4f46\u901a\u5e38\u53ef\u4ee5\u4ea7\u751f\u66f4\u597d\u7684\u6a21\u578b\u6027\u80fd\u3002","title":"sikit-learn\u4ecb\u7ecd"},{"location":"python/DataStructure/01_PythonFundmantal/","text":"1.\u57fa\u7840\u77e5\u8bc6\u56de\u987e \u00b6 1.1.\u57fa\u672c\u7a0b\u5e8f\u8981\u7d20 \u00b6 \u793a\u4f8b\u4ee3\u7801 numberguess.py \u3002 import random def main (): smaller = int ( input ( \"\u8f93\u5165\u6700\u5c0f\u503c: \" )) larger = int ( input ( \"\u8f93\u5165\u6700\u5927\u503c: \" )) myNumber = random . randint ( smaller , larger ) count = 0 while True : count += 1 userNumber = int ( input ( \"\u8f93\u5165\u4f60\u731c\u7684\u503c: \" )) if userNumber < myNumber : print ( \"\u4f60\u731c\u7684\u592a\u5c0f\uff01\" ) elif userNumber > myNumber : print ( \"\u4f60\u731c\u7684\u592a\u5927\uff01\" ) else : print ( \"\u606d\u559c\uff0c\u4f60\u5728\u7b2c\" , count , \"\u6b21\u731c\u5bf9\u4e86!\" ) break if __name__ == \"__main__\" : main () \u8fd0\u884c\u4ee3\u7801\uff1a $ python3 numberguess.py Enter the smaller number: 10 Enter the larger number: 60 Enter your guess: 50 Too large Enter your guess: 40 Too large Enter your guess: 30 Too large Enter your guess: 20 Too large Enter your guess: 10 Too small Enter your guess: 15 You\u2019ve got it in 6 tries! 1.1.1.\u62fc\u5199\u548c\u547d\u540d\u60ef\u4f8b \u00b6 \u53d8\u91cf\uff1asalary\uff0choursWorked\uff0cisAbsent \u5e38\u6570\uff1aABSOLUTE_ZERO\uff0cINTEREST_RATE \u51fd\u6570\u6216\u65b9\u6cd5\uff1aprintResults\uff0ccubeRoot\uff0cinput \u7c7b\uff1aBankAccount\uff0cSortedSet \u901a\u5e38\u7ea6\u5b9a\uff1a\u53d8\u91cf\u540d\u662f\u540d\u8bcd\u3001\u5f62\u5bb9\u8bcd\uff08\u5e03\u5c14\u503c\uff09\uff0c\u51fd\u6570\u548c\u65b9\u6cd5\u662f\u52a8\u8bcd\uff08\u8868\u793a\u52a8\u4f5c\uff09\u3001\u540d\u8bcd\u3001\u6216\u5f62\u5bb9\u8bcd\uff08\u8868\u793a\u8fd4\u56de\u7684\u503c\uff09\u3002 \u8bed\u6cd5\u5143\u7d20\uff1a Python\u4f7f\u7528\u7a7a\u767d\u7b26\uff08\u7a7a\u683c\u3001\u5236\u8868\u7b26\u3001\u6216\u6362\u884c\u7b26\uff09\u6765\u8868\u793a\u4e0d\u540c\u7c7b\u578b\u7684\u8bed\u53e5\u7684\u8bed\u6cd5\u3002 \u901a\u5e38\u7ea6\u5b9a\u4f7f\u75284\u4e2a\u7a7a\u683c\u4f5c\u4e3a\u9501\u8fdb\u5bbd\u5ea6\u3002 1.1.2.\u5b57\u7b26\u4e32 \u00b6 \u5355\u5f15\u53f7 \u53cc\u5f15\u53f7 \u6210\u5bf9\u7684\u4e09\u4e2a\u53cc\u5f15\u53f7\uff08\u591a\u884c\u6587\u672c\uff09 \u6210\u5bf9\u7684\u4e09\u4e2a\u5355\u5f15\u53f7\uff08\u591a\u884c\u6587\u672c\uff09 \u8f6c\u4e49\u5b57\u7b26 \\ \uff08\u53cd\u659c\u6760\uff09 1.1.3.\u8fd0\u7b97\u7b26\u548c\u8868\u8fbe\u5f0f \u00b6 \u6807\u51c6\u8fd0\u7b97\u7b26\uff1a + \u3001 - \u3001 * \u3001 / \u3001 % \u7b97\u672f\u8868\u8fbe\u5f0f\u662f\u7528\u6807\u51c6\u8fd0\u7b97\u7b26\u548c\u4e2d\u7f00\u8868\u793a\u6cd5 \u6bd4\u8f83\u8fd0\u7b97\u7b26\uff1a < \u3001 <= \u3001 > \u3001 >= \u3001 == \u3001 != \uff0c\u7528\u4e8e\u6bd4\u8f83\u6570\u5b57\u6216\u5b57\u7b26\u4e32\uff0c\u8fd4\u56deTrue\u6216False \u8fd0\u7b97\u7b26 == \u7528\u4e8e\u6bd4\u8f83\u6570\u636e\u7ed3\u6784\u91cc\u7684\u5185\u5bb9\uff0c\u8fd0\u7b97\u7b26 is \u7528\u4e8e\u6bd4\u8f83\u4e24\u4e2a\u5bf9\u8c61\u7684\u6807\u8bc6\u662f\u5426\u4e00\u81f4 \u903b\u8f91\u8fd0\u7b97\u7b26\uff1a and \u3001 or \u3001 not \u3002\u628a0\u3001None\u3001\u7a7a\u5b57\u7b26\u4e32\u3001\u7a7a\u5217\u8868\u7b49\u89c6\u4e3aFalse\uff0c\u5927\u591a\u6570\u5176\u4ed6\u503c\u662f\u4e3aTrue \u4e0b\u6807\u8fd0\u7b97\u7b26\uff1a [] \uff0c\u4e0e\u591a\u9879\u96c6collection\u5bf9\u8c61\u4e00\u8d77\u4f7f\u7528 \u9009\u62e9\u5668\u8fd0\u7b97\u7b26\uff1a . \uff0c\u7528\u4e8e\u5f15\u7528\u4e00\u4e2a\u6a21\u5757\u3001\u7c7b\u6216\u5bf9\u8c61\u4e2d\u7684\u4e00\u4e2a\u5177\u540d\u7684\u9879 \u8fd0\u7b97\u7b26\u4f18\u5148\u7ea7\uff0c\u4f9d\u6b21\u662f\u9009\u62e9\u8fd0\u7b97\u7b26\u3001\u51fd\u6570\u8c03\u7528\u8fd0\u7b97\u7b26\u3001\u4e0b\u6807\u8fd0\u7b97\u7b26\u3001\u7b97\u672f\u8fd0\u7b97\u7b26\u3001\u6bd4\u8f83\u8fd0\u7b97\u7b26\u3001\u903b\u8f91\u8fd0\u7b97\u7b26\u3001\u8d4b\u503c\u8fd0\u7b97\u7b26\u3002\u62ec\u53f7\u7528\u4e8e\u8ba9\u5b50\u8868\u8fbe\u5f0f\u4f18\u5148\u8fd0\u884c\u3002 1.1.4.\u51fd\u6570\u8c03\u7528 \u00b6 \u51fd\u6570\u540d\u79f0\u540e\u9762\u8ddf\u7740\u7528\u62ec\u53f7\u62ec\u8d77\u6765\u7684\u53c2\u6570\u5217\u8868\uff0c\u4f8b\u5982\uff1a min(5,2) \u6807\u51c6\u51fd\u6570 \u5176\u4ed6\u6a21\u5757\u5bfc\u5165\u51fd\u6570 1.1.5.print\u51fd\u6570 \u00b6 \u81ea\u52a8\u4e3a\u6bcf\u4e2a\u53c2\u6570\u8fd0\u884c str \u51fd\u6570\uff0c\u4ee5\u5f97\u5230\u5176\u5b57\u7b26\u4e32\u8868\u793a \u5728\u8f93\u51fa\u4e4b\u524d\u4f1a\u7528\u7a7a\u683c\u5427\u6bcf\u4e2a\u5b57\u7b26\u4e32\u9694\u5f00 \u9ed8\u8ba4\u4ee5\u6362\u884c\u7b26\u4f5c\u4e3a\u7ed3\u675f 1.1.6.input\u51fd\u6570 \u00b6 \u6807\u51c6\u8f93\u5165\u51fd\u6570input\u4f1a\u4e00\u76f4\u7b49\u5f85\u7528\u6237\u901a\u8fc7\u952e\u76d8\u8f93\u5165\u6587\u672c \u63a5\u53d7\u4e00\u4e2a\u53ef\u9009\u7684\u5b57\u7b26\u4e32\u4f5c\u4e3a\u5176\u53c2\u6570 1.1.7.\u7c7b\u578b\u8f6c\u6362\u51fd\u6570\u548c\u6df7\u5408\u6a21\u5f0f\u64cd\u4f5c \u00b6 Python\u5141\u8bb8\u7b97\u672f\u8868\u8fbe\u5f0f\u4e2d\u7684\u64cd\u4f5c\u6570\u5177\u6709\u4e0d\u540c\u7684\u6570\u503c\u7c7b\u578b\u3002\u4f8b\u5982\uff0c\u628aint\u7c7b\u578b\u7684\u64cd\u4f5c\u6570\u548cfloat\u7c7b\u578b\u7684\u64cd\u4f5c\u6570\u76f8\u52a0\uff0c\u4f1a\u5f97\u5230float\u7c7b\u578b\u7684\u6570\u3002 # \u8f93\u5165\u534a\u5f84\u6c42\u5706\u9762\u79ef radius = float ( input ( \"Radius: \" )) print ( \"The area is\" , 3.14 * radius ** 2 ) 1.1.8.\u53ef\u9009\u548c\u5173\u952e\u5b57\u51fd\u6570\u53c2\u6570 \u00b6 \u5fc5\u9009\u53c2\u6570\u662f\u6ca1\u6709\u9ed8\u8ba4\u503c\u7684\uff1b\u53ef\u9009\u53c2\u6570\u6709\u9ed8\u8ba4\u503c\uff1b \u5728\u8c03\u7528\u51fd\u6570\u65f6\uff0c\u4f20\u9012\u7ed9\u5b83\u7684\u53c2\u6570\u6570\u91cf\u5fc5\u987b\u81f3\u5c11\u548c\u5fc5\u9009\u53c2\u6570\u7684\u6570\u91cf\u76f8\u540c\u3002 \u6807\u51c6\u51fd\u6570\u548cPython\u7684\u5e93\u51fd\u6570\u5728\u8c03\u7528\u65f6\u90fd\u4f1a\u5bf9\u4f20\u5165\u7684\u53c2\u6570\u8fdb\u884c\u7c7b\u578b\u68c0\u67e5 1.1.9.\u53d8\u91cf\u548c\u8d4b\u503c\u8bed\u53e5 \u00b6 \u7b80\u5355\u7684\u8d4b\u503c\u8bed\u53e5 PI = 3.1416 \u591a\u53d8\u91cf\u8d4b\u503c minValue, maxValue = 1, 100 \u53d8\u91cf\u4ea4\u6362 a, b = b, a \u8d4b\u503c\u8bed\u53e5\u5fc5\u987b\u5199\u5728\u4e00\u884c\u4ee3\u7801\u91cc\uff0c\u4f46\u662f\u53ef\u4ee5\u5728\u9017\u53f7\u3001\u5706\u62ec\u53f7\u3001\u82b1\u62ec\u53f7\u6216\u65b9\u62ec\u53f7\u4e4b\u540e\u6362\u884c\uff0c\u6216\u8005\u7528\u8f6c\u4e49\u7b26 \\ \u8fdb\u884c\u6362\u884c\u3002 \u6362\u884c\u793a\u4f8b\uff1a minValue = min ( 100 , 200 ) product = max ( 100 , 200 ) \\ * 30 1.1.10.\u6570\u636e\u7c7b\u578b \u00b6 \u53d8\u91cf\u90fd\u53ef\u4ee5\u88ab\u6307\u5b9a\u4e3a\u4efb\u4f55\u7c7b\u578b\u7684\u503c\u3002\u8fd9\u4e9b\u53d8\u91cf\u5e76\u4e0d\u50cf\u5176\u4ed6\u8bed\u8a00\u90a3\u6837\u88ab\u58f0\u660e\u4e3a\u7279\u5b9a\u7684\u7c7b\u578b\uff0c\u800c\u53ea\u662f\u88ab\u8d4b\u4e86\u4e00\u4e2a\u503c \u503c\u548c\u5bf9\u8c61\u90fd\u662f\u6709\u7c7b\u578b\u7684\uff0c\u4f1a\u5728\u8fd0\u884c\u65f6\u8fdb\u884c\u6570\u636e\u7c7b\u578b\u68c0\u67e5 1.1.11. import \u8bed\u53e5 \u00b6 import \u8bed\u53e5\u4f7f\u5f97\u4e00\u4e2a\u6a21\u5757\u4e2d\u7684\u6807\u8bc6\u7b26\u53ef\u4ee5\u88ab\u53e6\u4e00\u4e2a\u7a0b\u5e8f\u6240\u89c1\u5230\u3002\u6807\u8bc6\u7b26\u53ef\u4ee5\u662f\u5bf9\u8c61\u540d\u3001\u51fd\u6570\u540d\u6216\u7c7b\u540d \u5bfc\u5165\u6a21\u5757\u540d\u79f0\uff0c\u4f8b\u5982 import math \u5bfc\u5165\u6a21\u5757\u4e2d\u7684\u6807\u8bc6\u7b26\uff0c\u4f8b\u5982\uff1a from math import sqrt \uff0c\u6216\u8005 from math import pi, sqrt \u4e5f\u53ef\u4ee5\u4f7f\u7528\u7b26\u53f7 * \u5bfc\u5165\u4e00\u4e2a\u6a21\u5757\u4e2d\u7684\u6240\u6709\u540d\u79f0\uff0c\u4f46\u4e0d\u63a8\u8350 1.2.\u63a7\u5236\u8bed\u53e5 \u00b6 1.2.1.\u6761\u4ef6\u8bed\u53e5 \u00b6 \u5355\u5411if\u8bed\u53e5\u7684\u8bed\u6cd5 if < Boolean expression > : < sequence of statements > \u53cc\u5411if\u8bed\u53e5\u7684\u8bed\u6cd5 if < Boolean expression > : < sequence of statements > else : < sequence of statements > \u591a\u5411if\u8bed\u53e5\u7684\u8bed\u6cd5 if < Boolean expression > : < sequence of statements > elif < Boolean expression > : < sequence of statements > ... else : < sequence of statements > 1.2.2.\u4f7f\u7528if name == \" main \" \u00b6 \u793a\u4f8b\u4ee3\u7801 numberguess.py \u3002 import random def main (): smaller = int ( input ( \"\u8f93\u5165\u6700\u5c0f\u503c: \" )) larger = int ( input ( \"\u8f93\u5165\u6700\u5927\u503c: \" )) myNumber = random . randint ( smaller , larger ) count = 0 while True : count += 1 userNumber = int ( input ( \"\u8f93\u5165\u4f60\u731c\u7684\u503c: \" )) if userNumber < myNumber : print ( \"\u4f60\u731c\u7684\u592a\u5c0f\uff01\" ) elif userNumber > myNumber : print ( \"\u4f60\u731c\u7684\u592a\u5927\uff01\" ) else : print ( \"\u606d\u559c\uff0c\u4f60\u5728\u7b2c\" , count , \"\u6b21\u731c\u5bf9\u4e86!\" ) break if __name__ == \"__main__\" : main () \u4e0a\u9762\u7684if\u8bed\u53e5\u7684\u4f5c\u7528\u662f\uff0c \u8981\u4e48\u5c06\u6a21\u5757\u5f53\u4f5c\u4e00\u4e2a\u72ec\u7acb\u7684\u7a0b\u5e8f\u8fd0\u884c\uff0c\u8be5\u6a21\u5757\u7684 _name_ \u53d8\u91cf\u4f1a\u8bbe\u7f6e\u4e3a\u5b57\u7b26\u4e32 _main_ \uff0c\u624d\u4f1a\u6267\u884c main() \u51fd\u6570 \u8981\u4e48\u4ece\u53e6\u4e00\u4e2a\u6a21\u5757\u4e2d\u5bfc\u5165\uff0c\u8be5\u6a21\u5757\u7684 _name_ \u53d8\u91cf\u4f1a\u8bbe\u7f6e\u8be5\u6a21\u5757\u7684\u540d\u79f0\uff0c\u4e0a\u4f8b\u4e2d\u5373 numberguess 1.2.3.\u5faa\u73af\u8bed\u53e5 \u00b6 \u901a\u5e38\uff1a \u4e00\u822c\u4f1a\u4f7f\u7528for\u5faa\u73af\u6765\u8fed\u4ee3\u786e\u5b9a\u8303\u56f4\u7684\u503c\u6216\u503c\u7684\u5e8f\u5217 \u5982\u679c\u7ee7\u7eed\u5faa\u73af\u7684\u6761\u4ef6\u662f\u67d0\u4e2a\u5e03\u5c14\u8868\u8fbe\u5f0f\uff0c\u4e00\u822c\u4f1a\u4f7f\u7528while\u5faa\u73af while \u8bed\u6cd5\u683c\u5f0f\uff1a while < Boolean expression > : < sequence of statements > \u793a\u4f8b\uff1a # \u8ba1\u7b97\u4ece1\u523010\u7684\u4e58\u79ef\u5e76\u8f93\u51fa\u7ed3\u679c result = 1 value = 1 while value <= 10 : result *= value value += 1 print ( result , value ) # \u8fd0\u884c\u7ed3\u679c # 3628800 11 for \u8bed\u6cd5\u683c\u5f0f\uff1a for < variable > in < iterable object > : < sequence of statements > \u793a\u4f8b\uff1a # \u8ba1\u7b97\u4ece1\u523010\u7684\u4e58\u79ef\u5e76\u8f93\u51fa\u7ed3\u679c result = 1 value = 1 for value in range ( 1 , 11 ): result *= value value += 1 print ( result , value ) # \u8fd0\u884c\u7ed3\u679c # 3628800 11 1.3.\u5b57\u7b26\u4e32\u53ca\u5176\u8fd0\u7b97 \u00b6 Python\u4e2d\u7684\u5b57\u7b26\u4e32\u4e5f\u662f\u4e00\u4e2a\u590d\u5408\u5bf9\u8c61 Python\u7684\u5b57\u7b26\u4e32\u7c7b\u578b\u540d\u4e3a str \u7ea6\u5b9a\uff1a \u628a\u5355\u5b57\u7b26\u7684\u5b57\u7b26\u4e32\u7528\u5355\u5f15\u53f7\u62ec\u8d77\u6765 \u628a\u591a\u5b57\u7b26\u7684\u5b57\u7b26\u4e32\u7528\u53cc\u5f15\u53f7\u62ec\u8d77\u6765 1.3.1.\u8fd0\u7b97\u7b26 \u00b6 \u6bd4\u8f83\u8fd0\u7b97\u7b26\uff0c\u662f\u6309\u7167ASCII\u7801\u7684\u987a\u5e8f\u6bd4\u8f83\u4e24\u4e2a\u5b57\u7b26\u4e32\u4e2d\u6bcf\u4e2a\u4f4d\u7f6e\u7684\u5b57\u7b26\u5bf9 \u793a\u4f8b\uff1a print ( 'A' > 'a' ) # \u8fd0\u884c\u7ed3\u679c False print ( 'A' < 'a' ) # \u8fd0\u884c\u7ed3\u679c True + \u8fd0\u7b97\u7b26\u751f\u6210\u5e76\u8fd4\u56de\u4e00\u4e2a\u5305\u542b\u4e24\u4e2a\u64cd\u4f5c\u6570\u7684\u65b0\u5b57\u7b26\u4e32 \u793a\u4f8b\uff1a print ( \"Hello\" + \"Python\" ) # \u8fd0\u884c\u7ed3\u679c HelloPython \u4e0b\u6807\u8fd0\u7b97\u7b26\uff0c\u8303\u56f4\u662f\u4ece0\u5230\u5b57\u7b26\u4e32\u7684\u957f\u5ea6\u51cf\u53bb1\u7684\u4e00\u4e2a\u6574\u6570\u3002 \u8fd0\u7b97\u7b26\u8fd4\u56de\u5728\u5b57\u7b26\u4e32\u4e2d\u8be5\u4f4d\u7f6e\u7684\u5b57\u7b26\u3002 \u793a\u4f8b\uff1a print ( \"Greater\" [ 1 ]) # \u8fd0\u884c\u7ed3\u679c\uff1ar \u5f53\u7d22\u5f15\u4e3a\u8d1f\u503c\u65f6\uff0cPython\u4f1a\u628a\u8fd9\u4e2a\u503c\u548c\u5b57\u7b26\u4e32\u7684\u957f\u5ea6\u76f8\u52a0\uff0c\u4ee5\u786e\u5b9a\u8981\u8fd4\u56de\u7684\u5b57\u7b26\u7684\u4f4d\u7f6e\u3002\u8d1f\u7d22\u5f15\u503c\u4e0d\u5f97\u5c0f\u4e8e\u5b57\u7b26\u4e32\u957f\u5ea6\u7684\u8d1f\u503c\u3002 print ( \"Greater\" [ - 3 ]) # \u8fd0\u884c\u7ed3\u679c\uff1at print ( \"Greater\" [ - 9 ]) # \u8fd0\u884c\u7ed3\u679c\uff1aIndexError: string index out of range \u5207\u7247\u8fd0\u7b97\u7b26\uff08slice operator\uff09\uff0c\u4e0b\u6807\u8fd0\u7b97\u7b26\u7684\u4e00\u79cd\u53d8\u4f53\u3002 \u8bed\u6cd5\u683c\u5f0f\uff1a [:] \uff1a\u8303\u56f4\u662f\u4ece0\u5230\u5b57\u7b26\u4e32\u7684\u957f\u5ea6\u51cf\u53bb1\u7684\u6574\u6570 \uff1a\u8303\u56f4\u662f\u4ece0\u5230\u5b57\u7b26\u4e32\u7684\u957f\u5ea6\u7684\u6574\u6570 \u5207\u7247\u68c0\u7d22\u89c4\u5219\uff1a \u8fd4\u56de\u8fd9\u6837\u4e00\u4e2a\u5b50\u5b57\u7b26\u4e32\uff1a\u8fd9\u4e2a\u5b50\u5b57\u7b26\u4e32\u4f1a\u4ece \u7d22\u5f15\u5904\u7684\u5b57\u7b26\u5f00\u59cb\uff0c\u5230 \u7d22\u5f15\u51cf1\u7684\u4f4d\u7f6e\u4f5c\u4e3a\u7ed3\u675f\u3002 \u5982\u679c\u7701\u7565 \u7d22\u5f15\uff0c\u90a3\u4e48\u5207\u7247\u8fd0\u7b97\u7b26\u5c06\u8fd4\u56de\u4e00\u4e2a\u4ee5\u5f53\u524d\u5b57\u7b26\u4e32\u7684\u7b2c\u4e00\u4e2a\u5b57\u7b26\u4f5c\u4e3a\u5f00\u5934\u7684\u5b50\u5b57\u7b26\u4e32\u3002 \u5982\u679c\u7701\u7565 \u7d22\u5f15\uff0c\u90a3\u4e48\u5207\u7247\u8fd0\u7b97\u7b26\u5c06\u8fd4\u56de\u4e00\u4e2a\u4ee5\u5f53\u524d\u5b57\u7b26\u4e32\u7684\u6700\u540e\u4e00\u4e2a\u5b57\u7b26\u4f5c\u4e3a\u7ed3\u5c3e\u7684\u5b50\u5b57\u7b26\u4e32\u3002 \u5982\u679c\u7701\u7565\u8fd9\u4e24\u4e2a\u503c\uff0c\u90a3\u4e48\u5207\u7247\u8fd0\u7b97\u7b26\u4f1a\u8fd4\u56de\u6574\u4e2a\u5b57\u7b26\u4e32\u3002 \u793a\u4f8b\uff1a print ( \"Greater\" [:]) # \u8fd4\u56de\u5b57\u4e32 Greater print ( \"Greater\" [ 2 :]) # \u8fd4\u56de\u5b57\u4e32 eater print ( \"Greater\" [: 2 ]) # \u8fd4\u56de\u5b57\u4e32 Gr print ( \"Greater\" [ 2 : 5 ]) # \u8fd4\u56de\u5b57\u4e32 eat 1.3.2.\u5b57\u7b26\u4e32\u683c\u5f0f\u5316 \u00b6 \u683c\u5f0f\u5316\u5b57\u7b26\u4e32\u91cc\u7684\u6570\u636e\u5b57\u7b26\u4ee5\u53ca\u6ee1\u8db3\u7ed9\u5b9a\u57fa\u51c6\u7ebf\u7684\u9644\u52a0\u7a7a\u683c\u7684\u603b\u6570\u79f0\u4e3a\u5b83\u7684\u5b57\u6bb5\u5bbd\u5ea6\uff08field width\uff09\u3002 print \u51fd\u6570\u4f1a\u5728\u9047\u5230\u7b2c\u4e00\u5217\u65f6\u81ea\u52a8\u5f00\u59cb\u6253\u5370\u8f93\u51fa\u57fa\u51c6\u7ebf\u3002 \u793a\u4f8b\uff0c\u901a\u8fc7print\u8bed\u53e5\u8f93\u51fa2\u5217\u3002 for i in range ( 7 , 11 ): print ( i , 10 * i ) # \u8fd0\u884c\u7ed3\u679c # 7 70 # 8 80 # 9 90 # 10 100 Python\u7684\u901a\u7528\u683c\u5f0f\u5316\u673a\u5236 \u8bed\u6cd5\u683c\u5f0f % \u548c % (, \u2026, ) \u3002 \u683c\u5f0f\u5316\u5b57\u7b26\u4e32\u65f6\uff0c \u4f7f\u7528 %s \u8868\u793a\u6cd5\u3002\u5f53\u5b57\u6bb5\u5bbd\u5ea6\u4e3a\u6b63\u65f6\uff0c\u6570\u636e\u662f\u53f3\u5bf9\u9f50\u7684\uff1b\u5f53\u5b57\u6bb5\u5bbd\u5ea6\u4e3a\u8d1f\u65f6\uff0c\u6570\u636e\u662f\u5de6\u5bf9\u9f50\u7684\u3002 \u683c\u5f0f\u6574\u6570\u65f6\uff0c \u4f7f\u7528 %d \u8868\u793a\u6cd5\u3002 \u683c\u5f0f\u6d6e\u70b9\u6570\u65f6\uff0c \u4f7f\u7528 %.f \u8868\u793a\u6cd5\uff0c\u5176\u4e2d . \u8fd9\u4e00\u90e8\u5206\u662f\u53ef\u9009\u7684\u3002 \u793a\u4f8b\uff1a print ( \" %6s \" % \"four\" ) print ( \" %-6s \" % \"four\" ) # four # four for i in range ( 7 , 11 ): print ( \" %-3d%5d \" % ( i , 10 * i )) # 7 70 # 8 80 # 9 90 # 10 100 for i in range ( 7 , 11 ): print ( \" %-3d%5.3f \" % ( i , i / 3 )) # 7 2.333 # 8 2.667 # 9 3.000 # 10 3.333 \u4e0b\u4f8b\u5bf9\u6bd4\u4e86\u6d6e\u70b9\u6570\u5728\u4f7f\u7528\u4e86\u683c\u5f0f\u5b57\u7b26\u4e32\u548c\u6ca1\u6709\u4f7f\u7528\u683c\u5f0f\u5b57\u7b26\u4e32\u8fd9\u4e24\u79cd\u60c5\u51b5\u4e0b\u7684\u8f93\u51fa\u5dee\u5f02\u3002 salary = 100.00 print ( \"Salary: $\" + str ( salary )) # Salary: $100.0 print ( \"Salary: $ %0.2f \" % salary ) # Salary: $100.00 \u6ce8\u610f\uff0c\u4e0b\u4f8b\u4e2dPython\u7ed9\u6570\u5b57\u6dfb\u52a0\u4e86\u4e00\u4e2a\u7cbe\u5ea6\u4f4d\u6570\uff0c\u5e76\u4e14\u5176\u5de6\u4fa7\u586b\u5145\u7a7a\u683c\uff0c\u4ece\u800c\u5b9e\u73b0\u4e86\u5b57\u6bb5\u5bbd\u5ea6\u4e3a6\u3001\u7cbe\u5ea6\u4e3a3\u7684\u8bbe\u7f6e\u3002\u8fd9\u4e2a\u5bbd\u5ea6\u5305\u542b\u5c0f\u6570\u70b9\u540e\u6240\u5360\u636e\u7684\u4f4d\u7f6e\u3002 print ( \" %6.3f \" % 3.14 ) # \u5de6\u4fa7\u586b\u5145\u4e86\u7a7a\u683c # 3.140 print ( \" %-6.3f \" % 3.14 ) # 3.140 1.3.3.\u5bf9\u8c61\u548c\u65b9\u6cd5\u8c03\u7528 \u00b6 \u8bed\u6cd5\u683c\u5f0f\uff1a .() \u793a\u4f8b\uff1a print ( \"greater\" . isupper ()) # \u8fd0\u884c\u7ed3\u679c # False print ( \"greater\" . upper ()) # \u8fd0\u884c\u7ed3\u679c # GREATER print ( \"greater\" . startswith ( \"great\" )) # \u8fd0\u884c\u7ed3\u679c # True print ( len ( \"greater\" )) print ( \"greater\" . __len__ ()) # \u8fd0\u884c\u7ed3\u679c # 7 print ( \"great\" + \"er\" ) print ( \"great\" . __add__ ( \"er\" )) # \u8fd0\u884c\u7ed3\u679c # greater print ( \"e\" in \"great\" ) print ( \"great\" . __contains__ ( \"e\" )) # \u8fd0\u884c\u7ed3\u679c # True \u63d0\u793a\uff1a dir() \u65b9\u6cd5\u4f1a\u8fd4\u56de\u6240\u4f20\u9012\u7684\u5bf9\u8c61\u7684\u6709\u6548\u5c5e\u6027\uff0c\u8bed\u6cd5\u683c\u5f0f\uff1a dir(object) help() \u51fd\u6570\u67e5\u770b\u51fd\u6570\u6216\u6a21\u5757\u7528\u9014\u7684\u8be6\u7ec6\u8bf4\u660e\uff0c\u8bed\u6cd5\u683c\u5f0f\uff1a help(object) dir ( str ) help ( str . __contains__ ) 1.4.\u5185\u7f6e\u591a\u9879\u96c6\u53ca\u5176\u64cd\u4f5c \u00b6 Python\u4e2d\u7684\u591a\u9879\u96c6\uff08collections\uff09\u6307\u80fd\u591f\u5305\u542b\u5143\u7d20\u7684\u6570\u636e\u7ed3\u6784\u3002\u591a\u9879\u96c6\u6a21\u5757\u63d0\u4f9b\u4e86\u4e0d\u540c\u7c7b\u578b\u7684\u5bb9\u5668\u3002\u5bb9\u5668\u662f\u7528\u4e8e\u5b58\u50a8\u4e0d\u540c\u5bf9\u8c61\u5e76\u63d0\u4f9b\u8bbf\u95ee\u6240\u5305\u542b\u5bf9\u8c61\u4ee5\u53ca\u5bf9\u5b83\u4eec\u8fdb\u884c\u8fed\u4ee3\u7684\u65b9\u5f0f\u7684\u5bf9\u8c61\u3002\u4e00\u4e9b\u5185\u7f6e\u7684\u5bb9\u5668\u6709\u5143\u7ec4\uff08Tuple\uff09\u3001\u5217\u8868\uff08List\uff09\u3001\u5b57\u5178\uff08Dictionary\uff09\u7b49\u3002 \u4ee5\u4e0b\u662f\u7531collections\u6a21\u5757\u63d0\u4f9b\u7684\u4e0d\u540c\u5bb9\u5668\u7684\u5217\u8868\uff1a \u8ba1\u6570\u5668\uff08Counters\uff09 \u6709\u5e8f\u5b57\u5178\uff08OrderedDict\uff09 \u9ed8\u8ba4\u5b57\u5178\uff08DefaultDict\uff09 \u94fe\u6620\u5c04\uff08ChainMap\uff09 \u547d\u540d\u5143\u7ec4\uff08NamedTuple\uff09 \u53cc\u5411\u961f\u5217\uff08DeQue\uff09 \u7528\u6237\u5b57\u5178\uff08UserDict\uff09 \u7528\u6237\u5217\u8868\uff08UserList\uff09 \u7528\u6237\u5b57\u7b26\u4e32\uff08UserString\uff09 1.4.1.\u5217\u8868 \u00b6 \u5217\u8868\uff08list\uff09\u662f\u96f6\u4e2a\u6216\u591a\u4e2aPython\u5bf9\u8c61\u7684\u4e00\u4e2a\u5e8f\u5217\uff0c\u8fd9\u4e9b\u5bf9\u8c61\u901a\u5e38\u79f0\u4e3a\u9879\uff08item\uff09\u3002 \u5217\u8868\u7684\u8868\u73b0\u5f62\u5f0f\u662f\uff1a\u7528\u65b9\u62ec\u53f7\u62ec\u8d77\u6574\u4e2a\u5217\u8868\uff0c\u5e76\u7528\u9017\u53f7\u5206\u9694\u5143\u7d20\u3002 \u793a\u4f8b\uff1a [] # \u7a7a\u5217\u8868 [ \"greater\" , \"less\" , 10 ] # \u542b\u4e0d\u540c\u7c7b\u578b\u7684\u5217\u8868 [ \"greater\" , [ \"less\" , 10 ]] # \u542b\u5185\u5d4c\u5217\u8868\u7684\u5217\u8868 \u5217\u8868\u7684\u5207\u7247\u64cd\u4f5c\uff1a \u548c\u5b57\u7b26\u4e32\u7c7b\u4f3c\uff0c\u53ef\u4ee5\u901a\u8fc7\u6807\u51c6\u8fd0\u7b97\u7b26\u6267\u884c\u5207\u7247\u6216\u8fde\u63a5\u64cd\u4f5c\uff0c\u8fd4\u56de\u7ed3\u679c\u4e5f\u662f\u5217\u8868\u3002 \u548c\u5b57\u7b26\u4e32\u4e0d\u540c\uff0c\u5217\u8868\u662f\u53ef\u53d8\u7684\uff0c\u5373\uff0c\u53ef\u4ee5\u66ff\u6362\u3001\u63d2\u5165\u6216\u5220\u9664\u5217\u8868\u4e2d\u6240\u5305\u542b\u7684\u9879\u3002 \u5207\u7247\u548c\u8fde\u63a5\u8fd0\u7b97\u7b26\u6240\u8fd4\u56de\u7684\u5217\u8868\u662f\u65b0\u7684\u5217\u8868\uff0c\u800c\u4e0d\u662f\u6700\u521d\u5217\u8868\u7684\u4e00\u90e8\u5206\uff1b \u5217\u8868\u7c7b\u578b\u5305\u542b\u4e86\u51e0\u4e2a\u53eb\u4f5c\u53d8\u5f02\u5668\uff08mutator\uff09\u7684\u65b9\u6cd5\uff0c\u7528\u4e8e\u4fee\u6539\u5217\u8868\u7684\u7ed3\u6784\u3002 \u53ef\u4ee5\u901a\u8fc7 dir(list) \u6765\u67e5\u770b\u65b9\u6cd5\uff0c\u5305\u62ec\u53d8\u5f02\u5668\uff08mutator\uff09\u7684\u65b9\u6cd5\u3002 dir ( list ) # \u8fd0\u884c\u7ed3\u679c # ['__add__', '__class__', '__contains__', '__delattr__', '__delitem__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__getitem__', '__gt__', '__hash__', '__iadd__', '__imul__', '__init__', '__init_subclass__', '__iter__', '__le__', '__len__', '__lt__', '__mul__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__reversed__', '__rmul__', '__setattr__', '__setitem__', '__sizeof__', '__str__', '__subclasshook__', 'append', 'clear', 'copy', 'count', 'extend', 'index', 'insert', 'pop', 'remove', 'reverse', 'sort'] \u6700\u5e38\u7528\u7684\u5217\u8868\u53d8\u5f02\u5668\u65b9\u6cd5\u662f append \u3001 insert \u3001 pop \u3001 remove \u548c sort \u3002 \u793a\u4f8b\uff1a myList = [] # myList\u5f53\u524d\u4e3a[] myList . append ( 34 ) # myList\u5f53\u524d\u4e3a[34]\uff0c\u9ed8\u8ba4\u5c3e\u90e8\u63d2\u5165 myList . append ( 22 ) # myList\u5f53\u524d\u4e3a[34, 22]\uff0c\u9ed8\u8ba4\u5c3e\u90e8\u63d2\u5165 myList . sort () # myList\u5f53\u524d\u4e3a[22, 34] myList . pop () # \u9ed8\u8ba4\u4ece\u7d22\u5f15\u4f4d[0]\u5220\u9664\uff0c\u8fd4\u56de\u7ed3\u679c22\uff1bmyList\u5f53\u524d\u4e3a[34] myList . insert ( 0 , 22 ) # \u5728\u6307\u5b9a\u7d22\u5f15\u4f4d[0]\u63d2\u5165\uff1bmyList\u5f53\u524d\u4e3a[22, 34] myList . insert ( 1 , 55 ) # \u5728\u6307\u5b9a\u7d22\u5f15\u4f4d[1]\u63d2\u5165\uff1bmyList\u5f53\u524d\u4e3a[22, 55, 34] myList . pop ( 1 ) # \u6307\u5b9a\u7d22\u5f15\u4f4d[1]\u5220\u9664\uff0c\u8fd4\u56de\u7ed3\u679c55\uff1bmyList\u5f53\u524d\u4e3a[22, 34] myList . remove ( 22 ) # \u5220\u9664\u9996\u4e2a\u5339\u914d\u9879\u7684\u5143\u7d20[22]\uff1bmyList\u5f53\u524d\u4e3a[34] myList . remove ( 55 ) # \u62a5ValueError\u9519\uff0clist.remove(x): x not in list \u5bf9\u4e8e\u5b57\u7b26\u4e32\uff0csplit\u65b9\u6cd5\u4f1a\u4ece\u5b57\u7b26\u4e32\u91cc\u5206\u79bb\u51fa\u4e00\u4e2a\u5355\u8bcd\u5217\u8868\uff0c\u800cjoin\u65b9\u6cd5\u4f1a\u628a\u5355\u8bcd\u5217\u8868\u8fde\u5728\u4e00\u8d77\u4ece\u800c\u5f62\u6210\u5b57\u7b26\u4e32\u3002\u4f8b\u5982\uff1a print ( \"Python is cool\" . split ()) # \u8fd0\u884c\u7ed3\u679c\uff1a # ['Python', 'is', 'cool'] print ( \" \" . join ([ \"Python\" , \"is\" , \"cool\" ])) # \u8fd0\u884c\u7ed3\u679c\uff1a # Python is cool \u5bf9\u4e8e\u5217\u8868\u7279\u6027\u548c\u64cd\u4f5c\u7684\u8be6\u7ec6\u7ec3\u4e60\uff0c\u53c2\u8003 Python\u8bed\u8a00\u57fa\u7840@github \u6216\u8005 Python\u8bed\u8a00\u57fa\u7840@web \u4e2d\u201c1.3 \u5217\u8868\uff08list\uff09\u201d\u7684\u5185\u5bb9\u3002 1.4.2.\u5143\u7ec4 \u00b6 \u5143\u7ec4\uff08tuple\uff09\u662f\u4e00\u4e2a\u4e0d\u53ef\u53d8\u7684\u5143\u7d20\u5e8f\u5217\u3002 \u5143\u7ec4\uff08tuple\uff09\u5f62\u5f0f\u662f\u7528\u5706\u62ec\u53f7\u5c06\u5404\u9879\u62ec\u8d77\u6765\uff0c\u5e76\u4e14\u5fc5\u987b\u81f3\u5c11\u5305\u542b\u4e24\u4e2a\u9879\u3002 \u5143\u7ec4\u5b9e\u9645\u4e0a\u5c31\u50cf\u5217\u8868\u4e00\u6837\uff0c\u53ea\u4e0d\u8fc7\u5b83\u6ca1\u6709\u53d8\u5f02\u5668\u65b9\u6cd5\u3002 \u5982\u679c\u8981\u4f7f\u5143\u7ec4\u53ea\u5305\u542b\u4e00\u4e2a\u5143\u7d20\uff0c\u5219\u5fc5\u987b\u5728\u5143\u7ec4\u91cc\u5305\u542b\u9017\u53f7\u3002 \u5bf9\u6bd4\u4e0b\u9762\u7684\u533a\u522b\uff1a print (( 21 )) # (21)\u88ab\u89c6\u4e3a\u6574\u6570 # \u8fd0\u884c\u7ed3\u679c\uff1a # 21 print (( 21 ,)) # (21,)\u88ab\u89c6\u4e3a\u5143\u7ec4 # \u8fd0\u884c\u7ed3\u679c\uff1a # (21,) \u5bf9\u4e8e\u5217\u8868\u7279\u6027\u548c\u64cd\u4f5c\u7684\u8be6\u7ec6\u7ec3\u4e60\uff0c\u53c2\u8003 Python\u8bed\u8a00\u57fa\u7840@github \u6216\u8005 Python\u8bed\u8a00\u57fa\u7840@web \u4e2d\u201c1.6 \u5143\u7ec4\uff08tuple\uff09\u201d\u7684\u5185\u5bb9\u3002 1.4.3.\u5e8f\u5217\u904d\u5386 \u00b6 for \u5faa\u73af\u53ef\u4ee5\u7528\u6765\u904d\u5386\u5e8f\u5217\uff08\u5982\u5b57\u7b26\u4e32\u3001\u5217\u8868\u6216\u5143\u7ec4\uff09\u91cc\u7684\u6240\u6709\u5143\u7d20\u3002 \u904d\u5386\u5217\u8868\uff1a myList = [ 67 , 100 , 'Monday' , \"It's good\" ] for item in myList : print ( item ) myList = [ 67 , 100 , 'Monday' , \"It's good\" ] for idx in range ( len ( myList )): print ( myList [ idx ]) \u904d\u5386\u5143\u7ec4\uff1a myString = \"I love Python\" myList = myString . split () myTuple = tuple ( myList ) for i in myTuple : print ( i ) \u904d\u5386\u5b57\u7b26\u4e32\uff1a(\u6ce8\u610f\uff0c\u662f\u904d\u5386\u5b57\u7b26\uff0c\u4e0d\u662f\u5355\u8bcd) myString = \"I love Python\" for i in myString : print ( i ) myString = \"I love Python\" for i in range ( len ( myString )): print ( myString [ i ]) myString = \"I love Python\" for i in enumerate ( myString ): print ( i ) myString = \"I love Python\" for i , j in enumerate ( myString ): print ( i , j ) myString = \"I love Python\" for i in iter ( myString ): print ( i ) \u5982\u679c\u6309\u7167\u5355\u8bcd\u904d\u5386\u5b57\u7b26\u4e32\uff0c\u5219\u9700\u8981\u5148\u628a\u5b57\u4e32\u6309\u5355\u8bcd\u62c6\u89e3\u4e3a\u5217\u8868\u3002 myString = \"I love Python\" myList = \"I love Python\" . split () for i in myList : print ( i ) \u5bf9\u4e8e\u5217\u8868\u548c\u5143\u7ec4\u904d\u5386\u7684\u66f4\u591a\u4f8b\u5b50\uff0c\u5305\u62ec\u62c6\u5305\u904d\u5386\uff0c\u53c2\u8003 Python\u8bed\u8a00\u57fa\u7840@github \u6216\u8005 Python\u8bed\u8a00\u57fa\u7840@web \u7684\u5185\u5bb9\u3002 1.4.4.\u5b57\u5178 \u00b6 \u5b57\u5178\uff08dictionary\uff09\u5305\u542b\u96f6\u4e2a\u6216\u591a\u4e2a\u6761\u76ee\u3002 \u6bcf\u4e2a\u6761\u76ee\uff08entry\uff09\u90fd\u6709\u552f\u4e00\u7684\u952e\u548c\u5b83\u6240\u5bf9\u5e94\u7684\u503c\u76f8\u5173\u8054\u3002 \u952e\u901a\u5e38\u662f\u5b57\u7b26\u4e32\u6216\u6574\u6570\uff0c\u800c\u503c\u662f\u4efb\u610f\u7684Python\u5bf9\u8c61\u3002 \u4e0b\u6807\u8fd0\u7b97\u7b26\u53ef\u4ee5\u7528\u4e8e\u8bbf\u95ee\u4e00\u4e2a\u7ed9\u5b9a\u952e\u7684\u503c\uff0c\u7ed9\u4e00\u4e2a\u65b0\u952e\u6dfb\u52a0\u4e00\u4e2a\u503c\uff0c\u4ee5\u53ca\u66ff\u6362\u7ed9\u5b9a\u952e\u7684\u503c\u3002 pop \u65b9\u6cd5\u4f1a\u5220\u9664\u4e00\u4e2a\u6761\u76ee\u5e76\u8fd4\u56de\u7ed9\u5b9a\u952e\u6240\u5bf9\u5e94\u7684\u503c\u3002 keys \u65b9\u6cd5\u4f1a\u628a\u6240\u6709\u952e\u8fd4\u56de\u6210\u4e00\u4e2a\u53ef\u8fed\u4ee3\u5bf9\u8c61\u3002 values \u65b9\u6cd5\u4f1a\u628a\u6240\u6709\u503c\u8fd4\u56de\u6210\u4e00\u4e2a\u53ef\u8fed\u4ee3\u5bf9\u8c61\u3002 \u793a\u4f8b\uff1a {} # \u7a7a\u5b57\u5178 { \"name\" : \"Ken\" } # \u542b\u4e00\u4e2a\u6761\u76ee { \"name\" : \"Ken\" , \"age\" : 67 } # \u542b\u4e8c\u4e2a\u6761\u76ee { \"hobbies\" :[ \"reading\" , \"running\" ]} # \u542b\u4e00\u4e2a\u6761\u76ee\uff0c\u5176\u4e2d\u503c\u662f\u4e00\u4e2a\u5217\u8868 \u5b57\u5178\u672c\u8eab\u4e5f\u662f\u4e00\u4e2a\u53ef\u8fed\u4ee3\u5bf9\u8c61\u3002\u53ef\u4ee5\u901a\u8fc7for\u8bed\u53e5\u8fdb\u884c\u904d\u5386\u952e\u6216/\u548c\u503c\u3002 myDict = { 'name' : 'Ming' , 'id' : 1001 , 'age' : 35 } for keys in myDict : print ( keys , myDict [ keys ]) # \u8fd0\u884c\u7ed3\u679c\uff1a # name Ming # id 1001 # age 35 1.4.5.\u503c\u68c0\u7d22 \u00b6 \u53ef\u4ee5\u5728\u5b57\u7b26\u4e32\u5217\u8868\u3001\u5143\u7ec4\u6216\u5b57\u5178\u91cc\u901a\u8fc7 in \u8fd0\u7b97\u7b26\u6765\u5bf9\u503c\u6216\u591a\u9879\u96c6\u8fdb\u884c\u641c\u7d22\uff0c\u8fd4\u56de True \u6216 False \u3002\u5bf9\u4e8e\u5b57\u5178\u6765\u8bf4\uff0c\u641c\u7d22\u7684\u76ee\u6807\u503c\u5e94\u8be5\u662f\u4e00\u4e2a\u952e\u3002 \u5982\u679c\u5df2\u77e5\u7ed9\u5b9a\u503c\u5b58\u5728\u4e8e\u5e8f\u5217\uff08\u5b57\u7b26\u4e32\u3001\u5217\u8868\u6216\u5143\u7ec4\uff09\u91cc\uff0c\u90a3\u4e48 index \u65b9\u6cd5\u5c06\u8fd4\u56de\u8fd9\u4e2a\u503c\u6240\u51fa\u73b0\u7684\u7b2c\u4e00\u4e2a\u4f4d\u7f6e\u3002 \u5217\u8868\u68c0\u7d22\uff1a myString = \"I love Python\" myList = myString . split () print ( myList ) # \u8fd0\u884c\u7ed3\u679c\uff1a # ['I', 'love', 'Python'] print ( myList . index ( 'love' )) # \u8fd0\u884c\u7ed3\u679c\uff1a # 1 \u5143\u7ec4\u68c0\u7d22\uff1a myString = \"I love Python\" myList = myString . split () myTuple = tuple ( myList ) print ( myTuple ) print ( myTuple . index ( 'love' )) \u5b57\u5178\u68c0\u7d22\uff1a myDict = { 'name' : 'Ming' , 'id' : 1001 , 'age' : 35 } print ( myDict ) for keys in myDict : print ( keys , myDict [ keys ]) myDict . pop ( 'city' ) # \u62a5\u9519\uff0cKeyError: 'city' myDict . pop ( 'id' ) print ( myDict ) # \u8fd0\u884c\u7ed3\u679c\uff1a{'name': 'Ming', 'age': 35} 1.4.6.\u6a21\u5f0f\u5339\u914d\u8bbf\u95ee\u591a\u9879\u96c6 \u00b6 \u4e0b\u6807\u8fd0\u7b97\u7b26\u53ef\u4ee5\u7528\u6765\u8bbf\u95ee\u5217\u8868\u3001\u5143\u7ec4\u548c\u5b57\u5178\u91cc\u7684\u5143\u7d20\u3002 \u901a\u8fc7\u6a21\u5f0f\u5339\u914d\u53ef\u4ee5\u4e00\u6b21\u8bbf\u95ee\u591a\u4e2a\u5143\u7d20\u3002 \u793a\u4f8b\uff1a myTuple \u662f\u4e00\u4e2a\u542b\u5185\u5d4c\u5143\u7ec4\u7684\u5143\u7ec4\u3002 myTuple = (( 'r' , 'g' , 'b' ), 'hexString' ) print ( myTuple ) # \u8fd0\u884c\u7ed3\u679c\uff1a # (('r', 'g', 'b'), 'hexString') print ( myTuple [ 0 ]) # \u8fd0\u884c\u7ed3\u679c\uff1a # ('r', 'g', 'b') print ( myTuple [ 0 ][ 0 ]) # \u8fd0\u884c\u7ed3\u679c\uff1a # r print ( myTuple [ 0 ][ 1 ]) # \u8fd0\u884c\u7ed3\u679c\uff1a # g print ( myTuple [ 0 ][ 2 ]) # \u8fd0\u884c\u7ed3\u679c\uff1a # b print ( myTuple [ 1 ]) # \u8fd0\u884c\u7ed3\u679c\uff1a # hexString \u901a\u8fc7\u4e0a\u9762\u7684\u62c6\u89e3\uff0c\u6211\u4eec\u6e05\u695a\u4e86\u5185\u5d4c\u5143\u7ec4\u7684\u7ed3\u6784\u8be6\u7ec6\u60c5\u51b5\u3002 \u4e0b\u9762\uff0c\u6211\u4eec\u901a\u8fc7\u6a21\u5f0f\u5339\u914d\uff0c\u628a\u4e00\u4e2a\u7ed3\u6784\u5206\u914d\u7ed9\u5f62\u5f0f\u5b8c\u5168\u76f8\u540c\u7684\u53e6\u4e00\u4e2a\u7ed3\u6784\u3002\u8fd9\u91cc\u76ee\u6807\u7ed3\u6784 newTuple \u6240\u5305\u542b\u7684\u53d8\u91cf\u4ece\u6e90\u7ed3\u6784 (('r', 'g', 'b'), 'hexString') \u91cc\u7684\u76f8\u5e94\u4f4d\u7f6e\u5904\u83b7\u5f97\u5bf9\u5e94\u7684\u503c\u3002 newTuple = (( 'r' , 'g' , 'b' ), 'hexString' ) print ( newTuple [ 0 ]) # ('r', 'g', 'b') print ( newTuple [ 0 ][ 0 ]) # \u8fd0\u884c\u7ed3\u679c\uff1a # r print ( newTuple [ 0 ][ 1 ]) # \u8fd0\u884c\u7ed3\u679c\uff1a # g print ( newTuple [ 0 ][ 2 ]) # \u8fd0\u884c\u7ed3\u679c\uff1a # b print ( newTuple [ 1 ]) # \u8fd0\u884c\u7ed3\u679c\uff1a # hexString 1.5.\u521b\u5efa\u51fd\u6570 \u00b6 Python\u652f\u6301\u5b8c\u5168\u51fd\u6570\u5f0f\u7f16\u7a0b\u8bbe\u8ba1\u3002 Python\u5305\u542b\u5f88\u591a\u5185\u7f6e\u51fd\u6570\u3002 Python\u4e5f\u8fd0\u884c\u521b\u5efa\u65b0\u51fd\u6570\uff0c\u53ef\u4ee5\u4f7f\u7528\u9012\u5f52\uff0c\u628a\u51fd\u6570\u4f5c\u4e3a\u6570\u636e\u8fdb\u884c\u4f20\u9012\u548c\u8fd4\u56de\u3002 1.5.1.\u51fd\u6570\u5b9a\u4e49 \u00b6 \u51fd\u6570\u5b9a\u4e49\u8bed\u6cd5\uff1a \u547d\u540d\u51fd\u6570\u540d\u79f0\u548c\u53c2\u6570\u540d\u79f0\u7684\u89c4\u5219\u4e0e\u60ef\u4f8b\u4e0e\u547d\u540d\u53d8\u91cf\u7684\u662f\u76f8\u540c\u7684\u3002 \u5fc5\u9009\u53c2\u6570\u7684\u5217\u8868\u53ef\u4ee5\u4e3a\u7a7a\uff0c\u4e5f\u53ef\u4ee5\u5305\u542b\u7528\u9017\u53f7\u9694\u5f00\u7684\u540d\u79f0\u3002 \u4e0e\u5176\u4ed6\u7f16\u7a0b\u8bed\u8a00\u4e0d\u540c\u7684\u662f\uff0c\u53c2\u6570\u540d\u79f0\u6216\u51fd\u6570\u540d\u79f0\u672c\u8eab\u5e76\u4e0d\u4f1a\u548c\u6570\u636e\u7c7b\u578b\u8fdb\u884c\u5173\u8054\u3002 def < function name > ( < list of parameters > ): < sequence of statements > \u793a\u4f8b\uff1a \u5728\u51fd\u6570\u7684\u6807\u9898\u4e0b\u6709\u4e00\u884c\u7528\u4e09\u5f15\u53f7\u62ec\u8d77\u6765\u7684\u5b57\u7b26\u4e32 \u8fd4\u56den\u7684\u5e73\u65b9\u6570 \uff0c\u8fd9\u662f\u4e00\u4e2a\u6587\u6863\u5b57\u7b26\u4e32\uff08docstring\uff09\u3002 \u5728shell\u91cc\u9762\u8f93\u5165help(square)\u65f6\uff0c\u4f1a\u663e\u793a\u8fd9\u4e2a\u5b57\u7b26\u4e32\u3002 \u5b9a\u4e49\u7684\u6bcf\u4e00\u4e2a\u51fd\u6570\u90fd\u5e94\u8be5\u6709\u6587\u6863\u5b57\u7b26\u4e32\uff0c\u6765\u8bf4\u660e\u8be5\u51fd\u6570\u7684\u529f\u80fd\uff0c\u5e76\u63d0\u4f9b\u76f8\u5173\u7684\u6240\u6709\u53c2\u6570\u4ee5\u53ca\u8fd4\u56de\u503c\u7684\u4fe1\u606f\u3002 \u51fd\u6570\u7684\u53c2\u6570\u548c\u4e34\u65f6\u53d8\u91cf\u53ea\u4f1a\u5728\u51fd\u6570\u8c03\u7528\u7684\u751f\u5b58\u5468\u671f\u5185\u5b58\u5728\uff0c\u5e76\u4e14\u5bf9\u5176\u4ed6\u51fd\u6570\u53ca\u5176\u5916\u56f4\u7a0b\u5e8f\u90fd\u662f\u4e0d\u53ef\u89c1\u7684\u3002 n \u662f\u53c2\u6570\u3002 result \u662f\u4e34\u65f6\u53d8\u91cf\u3002 \u5982\u679c\u51fd\u6570\u4e0d\u5305\u542b return \u8bed\u53e5\u65f6\uff0c\u5b83\u5c06\u5728\u6700\u540e\u4e00\u6761\u8bed\u53e5\u6267\u884c\u4e4b\u540e\u81ea\u52a8\u8fd4\u56de None \u503c\u3002 \u7528 = \u628a\u53c2\u6570\u6307\u5b9a\u4e3a\u6709\u9ed8\u8ba4\u503c\u7684\u53ef\u9009\u53c2\u6570\u3002 \u5728\u53c2\u6570\u5217\u8868\u4e2d\uff0c\u5fc5\u9009\u53c2\u6570\uff08\u6ca1\u6709\u9ed8\u8ba4\u503c\u7684\u53c2\u6570\uff09\u5fc5\u987b\u4f4d\u4e8e\u53ef\u9009\u53c2\u6570\u4e4b\u524d\u3002 def square ( n ): \"\"\"\u8fd4\u56den\u7684\u5e73\u65b9\u6570\"\"\" result = n ** 2 return result print ( square ( 5 )) 1.5.2.\u51fd\u6570\u9012\u5f52 \u00b6 \u9012\u5f52\u51fd\u6570\uff08recursive function\uff09\u662f\u6307\u4f1a\u8c03\u7528\u81ea\u8eab\u7684\u51fd\u6570\u3002 \u4e3a\u4e86\u9632\u6b62\u51fd\u6570\u65e0\u9650\u5730\u91cd\u590d\u8c03\u7528\u81ea\u8eab\uff0c\u4ee3\u7801\u4e2d\u5fc5\u987b\u81f3\u5c11\u6709\u4e00\u6761\u7528\u6765\u67e5\u9a8c\u6761\u4ef6\u7684\u9009\u62e9\u8bed\u53e5\uff0c\u7528\u4e8e\u786e\u5b9a\u63a5\u4e0b\u6765\u8981\u7ee7\u7eed\u9012\u5f52\u8fd8\u662f\u505c\u6b62\u9012\u5f52\u3002\u8fd9\u4e2a\u68c0\u67e5\u6761\u4ef6\u8bed\u53e5\u79f0\u4e3a\u57fa\u672c\u60c5\u51b5\uff08base case\uff09\u3002 \u793a\u4f8b\uff1a\u4e0b\u9762\u662f\u901a\u8fc7\u5faa\u73af\u5b9e\u73b0\u8f93\u51fa\u4ece\u7ed9\u5b9a\u7684\u6700\u5c0f\u503c\u5230\u6700\u5927\u503c\u4e4b\u95f4\u7684\u6574\u6570\u548c\u3002 def mySum ( lower , upper ): \"\"\"\u5bf9\u7ed9\u5b9a\u7684\u6700\u5c0f\u503c\u5230\u6700\u5927\u503c\u4e4b\u95f4\u7684\u6574\u6570\u6c42\u548c; lower:\u6700\u5c0f\u503c; upper:\u6700\u5927\u503c;\"\"\" result = 0 while ( lower <= upper ): result = result + lower lower += 1 return result print ( mySum ( 1 , 10 )) # \u8fd0\u884c\u7ed3\u679c\uff1a # 55 \u7528\u9012\u5f52\u51fd\u6570\u6539\u5199\u4e0a\u8ff0\u51fd\u6570\u3002 def mySum ( lower , upper ): \"\"\"\u5bf9\u7ed9\u5b9a\u7684\u6700\u5c0f\u503c\u5230\u6700\u5927\u503c\u4e4b\u95f4\u7684\u6574\u6570\u6c42\u548c; lower:\u6700\u5c0f\u503c; upper:\u6700\u5927\u503c;\"\"\" if lower <= upper : return lower + mySum ( lower + 1 , upper ) else : return 0 print ( mySum ( 1 , 10 )) # \u8fd0\u884c\u7ed3\u679c\uff1a # 55 \u901a\u5e38\u6765\u8bf4\uff0c\u9012\u5f52\u51fd\u6570\u81f3\u5c11\u6709\u4e00\u4e2a\u53c2\u6570\u3002 \u8fd9\u4e2a\u53c2\u6570\u7684\u503c\u4f1a\u88ab\u7528\u6765\u5bf9\u9012\u5f52\u8fc7\u7a0b\u7684\u57fa\u672c\u60c5\u51b5\u8fdb\u884c\u5224\u5b9a\uff0c\u4ece\u800c\u51b3\u5b9a\u662f\u5426\u8981\u7ed3\u675f\u6574\u4e2a\u8c03\u7528\u3002 \u5728\u6bcf\u6b21\u9012\u5f52\u8c03\u7528\u4e4b\u524d\uff0c\u8fd9\u4e2a\u503c\u4e5f\u4f1a\u88ab\u8fdb\u884c\u67d0\u79cd\u65b9\u5f0f\u7684\u4fee\u6539\u3002 \u6bcf\u6b21\u5bf9\u8fd9\u4e2a\u503c\u7684\u4fee\u6539\uff0c\u90fd\u5e94\u8be5\u4ea7\u751f\u4e00\u4e2a\u65b0\u6570\u636e\u503c\uff0c\u53ef\u4ee5\u8ba9\u51fd\u6570\u6700\u7ec8\u8fbe\u5230\u57fa\u672c\u60c5\u51b5\u3002 \u4e3a\u4e86\u5bf9 mySum \u51fd\u6570\u7684\u9012\u5f52\u8fdb\u884c\u8ddf\u8e2a\uff0c\u53ef\u4ee5\u5c1d\u8bd5\u6dfb\u52a0\u4e00\u4e2a\u4ee3\u8868\u7f29\u8fdb\u8fb9\u8ddd\u7684\u53c2\u6570\u5e76\u4e14\u6dfb\u52a0\u4e00\u4e9bprint\u8bed\u53e5\u3002\u8fd9\u6837\u5728\u6bcf\u6b21\u8c03\u7528\u65f6\uff0c\u51fd\u6570\u7684\u7b2c\u4e00\u6761\u8bed\u53e5\u4f1a\u8ba1\u7b97\u7f29\u8fdb\u6570\u91cf\uff0c\u7136\u540e\u518d\u6253\u5370\u4e24\u4e2a\u53c2\u6570\u7684\u503c\uff0c\u6bcf\u6b21\u8fd4\u56de\u8c03\u7528\u4e4b\u524d\u7684\u8fd4\u56de\u503c\u65f6\u90fd\u4f7f\u7528\u76f8\u540c\u7684\u7f29\u8fdb\uff0c\u5c31\u53ef\u4ee5\u5b9e\u73b0\u5bf9\u4e24\u4e2a\u53c2\u6570\u7684\u503c\u4ee5\u53ca\u6bcf\u6b21\u8c03\u7528\u7684\u8fd4\u56de\u503c\u8fdb\u884c\u8ddf\u8e2a\u3002 def mySum ( lower , upper , margin = 0 ): \"\"\"\u5bf9\u7ed9\u5b9a\u7684\u6700\u5c0f\u503c\u5230\u6700\u5927\u503c\u4e4b\u95f4\u7684\u6574\u6570\u6c42\u548c\uff0c\u901a\u8fc7\u9636\u68af\u65b9\u5f0f\u8f93\u51fa; lower:\u6700\u5c0f\u503c; upper:\u6700\u5927\u503c;\"\"\" blanks = \" \" * margin print ( blanks , lower , upper ) if lower <= upper : result = lower + mySum ( lower + 1 , upper , margin + 4 ) print ( blanks , result ) return result else : print ( blanks , 0 ) return 0 print ( mySum ( 1 , 5 )) # \u8fd0\u884c\u7ed3\u679c\uff1a # 1 5 # 2 5 # 3 5 # 4 5 # 5 5 # 6 5 # 0 # 5 # 9 # 12 # 14 # 15 # 15 1.5.3.\u51fd\u6570\u5d4c\u5957 \u00b6 \u5d4c\u5957\u51fd\u6570\u7c7b\u4f3c\u4e8e\u5d4c\u5957\u5faa\u73af\uff0c\u5c31\u662f\u51fd\u6570\u5185\u53c8\u5d4c\u5957\u7740\u51fd\u6570\u3002\u5373\uff0c\u51fd\u6570\u7684\u5b9a\u4e49\u5d4c\u5957\u5728\u4e00\u4e2a\u51fd\u6570\u7684\u8bed\u53e5\u5e8f\u5217\u91cc\u3002 \u5148\u770b\u4e00\u4e2a\u666e\u901a\u4f8b\u5b50\uff1a # \u5b9a\u4e49inner\u51fd\u6570 def inner (): print ( '\u6211\u662finner' ) # \u5b9a\u4e49outer\u51fd\u6570\uff0couter\u51fd\u6570\u8c03\u7528inner\u51fd\u6570 def outer (): print ( '\u6211\u662fouter' ) inner () outer () # \u8fd0\u884c\u7ed3\u679c\uff1a # \u6211\u662fouter # \u6211\u662finner \u6539\u5199\u4e0a\u9762\u7684\u4ee3\u7801\uff0c\u628a inner \u51fd\u6570\u5199\u5728 outer \u51fd\u6570\u91cc\u9762\u3002 # \u5b9a\u4e49outer\u51fd\u6570\uff0couter\u51fd\u6570\u5185\u5d4cinner\u51fd\u6570\uff0c\u5e76\u8c03\u7528inner\u51fd\u6570 def outer (): print ( '\u6211\u662fouter' ) # \u5b9a\u4e49inner\u51fd\u6570 def inner (): print ( '\u6211\u662finner' ) inner () outer () # \u8fd0\u884c\u7ed3\u679c\uff1a # \u6211\u662fouter # \u6211\u662finner \u4e0a\u9762\u7684\u5916\u5c42 outer \u51fd\u6570\u548c\u5185\u5c42 inner \u51fd\u6570\u90fd\u6ca1\u6709\u53d8\u91cf\u548c\u53c2\u6570\u3002 \u73b0\u5728\u4fee\u6539\u4e0a\u9762\u7684\u4ee3\u7801\uff0c\u6211\u4eec\u4f20\u5165\u53c2\u6570\u548c\u53d8\u91cf\uff0c\u7136\u540e\u628a\u5916\u5c42\u51fd\u6570\u8fd4\u56de\u503c\u6307\u5411\u5185\u5c42\u51fd\u6570\u540d\u3002 def outer (): a = 1 print ( '\u6211\u662fouter' ) # \u5b9a\u4e49inner\u51fd\u6570 def inner (): print ( '\u6211\u662finner' ) print ( 'inner\u6253\u5370: ' , a ) # \u8fd4\u56de\u5185\u5c42inner\u51fd\u6570\u540d return inner f = outer () # \u8fd0\u884c\u7ed3\u679c\uff1a # \u6211\u662fouter f () # \u8fd0\u884c\u7ed3\u679c\uff1a # \u6211\u662finner # inner\u6253\u5370: 1 \u5728\u4e0a\u9762\u7684\u4f8b\u5b50\u4e2d\uff1a f = outer() \u8c03\u7528\u5916\u5c42 outer \u51fd\u6570\uff0c\u5e76\u628a\u7ed3\u679c\u8d4b\u503c\u7ed9 f \u3002\u6ce8\u610f\uff0cinner\u51fd\u6570\u5e76\u6ca1\u6709\u88ab\u6267\u884c\u3002 f \u5176\u5b9e\u5c31\u662f inner \uff0c\u6307\u5411 inner \u7684\u5185\u5b58\u7a7a\u95f4\u3002\u901a\u8fc7 f() \u9a8c\u8bc1\u4e86\u8fd9\u4e00\u70b9\uff0c outer \u51fd\u6570\u4e2d\u7684\u53d8\u91cf a \u88ab\u6253\u5370\u51fa\u6765\u4e86\u3002 \u4e0a\u9762\u4f8b\u5b50\u4e2d outer \u5c31\u662f\u95ed\u5305\u51fd\u6570\uff0c\u5916\u5c42\u51fd\u6570\u7684\u53d8\u91cf\u53ef\u4ee5\u88ab\u5185\u5c42\u51fd\u6570\u8c03\u7528\uff0c\u7c7b\u4f3c\u4e8e\u5c01\u88c5\u7684\u6548\u679c\u3002\u5185\u5c42\u51fd\u6570\u4e0d\u4f1a\u7acb\u523b\u88ab\u6267\u884c\uff0c\u5f53\u518d\u6b21\u8c03\u7528\u65f6\uff0c\u5185\u5c42\u51fd\u6570\u624d\u4f1a\u6267\u884c\u3002 \u95ed\u5305\u51fd\u6570\u9700\u8981\u6709\u4e09\u4e2a\u6761\u4ef6\uff1a \u5fc5\u987b\u6709\u4e00\u4e2a\u5185\u5d4c\u51fd\u6570\uff0c\u4f8b\u5982\u51fd\u6570 inner \uff1b \u5185\u90e8\u51fd\u6570\u5f15\u7528\u5916\u90e8\u51fd\u6570\u53d8\u91cf\uff0c\u4f8b\u5982\u53d8\u91cf a \uff1b \u5916\u90e8\u51fd\u6570\u5fc5\u987b\u8fd4\u56de\u5185\u5d4c\u51fd\u6570\uff0c\u4f8b\u5982 outer \u51fd\u6570\u4e2d\u7684 return inner \uff1b \u5bf9\u4e0a\u9762\u7684\u4ee3\u7801\u518d\u8fdb\u884c\u4fee\u6539\uff0c\u5728 inner \u51fd\u6570\u4e2d\u518d\u6dfb\u52a0\u4e00\u4e2a\u540c\u540d\u7684\u53d8\u91cfa\u3002\u4ece\u7ed3\u679c\u53ef\u4ee5\u5f97\u51fa\u7ed3\u8bba\uff0c inner \u51fd\u6570\u4f18\u5148\u5728\u5185\u90e8\u67e5\u627e\u53d8\u91cf a=5 \u3002 def outer (): a = 1 print ( '\u6211\u662fouter' ) # \u5b9a\u4e49inner\u51fd\u6570 def inner (): a = 5 print ( '\u6211\u662finner' ) print ( 'inner\u6253\u5370: ' , a ) return inner f = outer () # \u8fd0\u884c\u7ed3\u679c\uff1a # \u6211\u662fouter f () # \u8fd0\u884c\u7ed3\u679c\uff1a # \u6211\u662finner # inner\u6253\u5370: 5 \u7ed3\u8bba\uff1a\u5185\u5c42\u51fd\u6570\u4e2d\u8c03\u7528\u7684\u53d8\u91cf\uff1a \u9996\u5148\u4f1a\u4ece\u5185\u5c42\u51fd\u6570\u4e2d\u627e\uff0c \u627e\u4e0d\u5230\u5c31\u53bb\u5916\u5c42\u51fd\u6570\u4e2d\u627e\uff0c \u518d\u627e\u4e0d\u5230\u5c31\u5230\u51fd\u6570\u5916\u4e2d\u627e\uff0c \u518d\u627e\u4e0d\u5230\u5c31\u5230\u5185\u7f6e\u7684\u6a21\u5757\u4e2d\u627e\uff0c \u518d\u627e\u4e0d\u5230\uff0c\u5c31\u62a5\u9519\u3002 \u8fd9\u5c31\u662f\u4f5c\u7528\u57df\u7684\u6982\u5ff5\u3002 \u7ee7\u7eed\u4fee\u6539\u4e0a\u9762\u7684\u4ee3\u7801\uff0c\u5728 inner \u51fd\u6570\u4e2d\u4fee\u6539 outer \u51fd\u6570\u4e2d\u53d8\u91cf a \u7684\u503c\uff0c\u8fd0\u884c\u7ed3\u679c\u62a5\u9519\u3002\u7ed3\u8bba\uff1a\u5185\u5c42\u51fd\u6570\u4e0d\u80fd\u4fee\u6539\u5916\u5c42\u51fd\u6570\u7684\u53d8\u91cf\u503c\u3002 def outer (): a = 1 print ( '\u6211\u662fouter' ) # \u5b9a\u4e49inner\u51fd\u6570 def inner (): a += 5 print ( '\u6211\u662finner' ) print ( 'inner\u6253\u5370: ' , a ) return inner f = outer () # \u8fd0\u884c\u7ed3\u679c\uff1a # \u6211\u662fouter f () # \u8fd0\u884c\u7ed3\u679c\uff1a # UnboundLocalError: local variable 'a' referenced before assignment \u4fee\u6b63\u4e0a\u9762\u7684\u4ee3\u7801\u3002\u5728 inner \u51fd\u6570\u4e2d\u5bf9\u53d8\u91cfa\u6dfb\u52a0\u4e00\u4e2a nonlocal \u7684\u58f0\u660e\uff0c\u5c31\u53ef\u4ee5\u5728 inner \u51fd\u6570\u4e2d\u4fee\u6539\u5916\u5c42outer\u51fd\u6570\u7684\u53d8\u91cf a \u7684\u503c\u3002 def outer (): a = 1 print ( '\u6211\u662fouter' ) # \u5b9a\u4e49inner\u51fd\u6570 def inner (): nonlocal a a += 5 print ( '\u6211\u662finner' ) print ( 'inner\u6253\u5370: ' , a ) return inner f = outer () # \u8fd0\u884c\u7ed3\u679c\uff1a # \u6211\u662fouter f () # \u8fd0\u884c\u7ed3\u679c\uff1a # \u6211\u662finner # inner\u6253\u5370: 6 \u4e0b\u9762\u8fd9\u6bb5\u4ee3\u7801\u662f\u9636\u4e58\uff08factorial\uff09\u9012\u5f52\u51fd\u6570\u7684\u4e24\u4e2a\u4e0d\u540c\u7684\u5b9a\u4e49\u3002 \u7b2c\u4e00\u4e2a\u5b9a\u4e49\u4f7f\u7528\u4e86\u5d4c\u5957\u7684\u8f85\u52a9\u51fd\u6570 recurse \u6765\u5bf9\u6240\u9700\u8981\u7684\u53c2\u6570\u8fdb\u884c\u9012\u5f52\uff1b\u8fd9\u91cc\u7684 factorial \u51fd\u6570\u5c31\u662f\u95ed\u5305\u51fd\u6570\u3002 \u7b2c\u4e00\u6b65\uff1a\u7b2c\u4e00\u6b21\u8c03\u7528 factorial() \u51fd\u6570\uff0c\u5373 n=5 \uff1b \u7b2c\u4e8c\u6b65\uff1a\u7b2c\u4e00\u6b21\u8c03\u7528\u5185\u5c42\u51fd\u6570 recurse() \uff0c\u4f46\u4e0d\u4f1a\u7acb\u523b\u88ab\u6267\u884c\uff1b \u7b2c\u4e09\u6b65\uff0c\u6267\u884c return recurse(5, 1) \uff0c\u5bf9\u53c2\u6570 product \u521d\u59cb\u5316\u8d4b\u503c 1 \u7b2c\u56db\u6b65\uff1a\u6267\u884c return recurse(5, 5 * 1) \uff0c\u6b64\u65f6 n=5 \uff0c product=1 \u3002 \u7b2c\u4e94\u6b65\uff1a\u6267\u884c return recurse(4, 4 * 5) \uff0c\u6b64\u65f6 n=4 \uff0c product=5 \u3002 \u7b2c\u516d\u6b65\uff1a\u6267\u884c return recurse(3, 3 * 20) \uff0c\u6b64\u65f6 n=3 \uff0c product=20 \u3002 \u7b2c\u4e03\u6b65\uff1a\u6267\u884c return recurse(2, 2 * 60) \uff0c\u6b64\u65f6 n=2 \uff0c product=60 \u3002 \u7b2c\u516b\u6b65\uff1a\u6267\u884c return recurse(1, 1 * 120) \uff0c\u6b64\u65f6 n=1 \uff0c product=120 \u3002 \u7b2c\u4e5d\u6b65\uff1a\u6b64\u65f6 n=1 \uff0c\u6267\u884c return product \uff0c\u5373 return 120 \uff0c\u7ed3\u675f\u3002 \u7b2c\u4e8c\u4e2a\u5b9a\u4e49\u5219\u662f\u4e3a\u7b2c\u4e8c\u4e2a\u53c2\u6570\u63d0\u4f9b\u4e86\u9ed8\u8ba4\u503c\uff0c\u4ece\u800c\u7b80\u5316\u4e86\u8bbe\u8ba1\u3002 # \u7b2c\u4e00\u4e2a\u5b9a\u4e49 def factorial ( n ): \"\"\"\u8fd4\u56de n \u7684\u9636\u4e58\"\"\" def recurse ( n , product ): \"\"\"\u8ba1\u7b97\u9636\u4e58\u7684\u5e2e\u52a9\u5668\"\"\" print ( n , product ) # \u63d2\u5165\u8fd9\u4e00\u53e5\u662f\u4e3a\u4e86\u80fd\u770b\u6e05\u695a\u6bcf\u4e00\u6b21\u9012\u5f52\u8c03\u7528\u7684n\u548cproduct\u53d8\u5316 if n == 1 : return product else : return recurse ( n - 1 , n * product ) return recurse ( n , 1 ) f = factorial ( 5 ) # \u8fd0\u884c\u7ed3\u679c 5 1 4 5 3 20 2 60 1 120 # \u7b2c\u4e8c\u4e2a\u5b9a\u4e49 def factorial ( n , product = 1 ): \"\"\"\u8fd4\u56de n \u7684\u9636\u4e58\"\"\" if n == 1 : return product else : return factorial ( n - 1 , n * product ) print ( factorial ( 5 )) # \u8fd0\u884c\u7ed3\u679c # 120 1.5.4.\u9ad8\u9636\u51fd\u6570 \u00b6 \u51fd\u6570\u672c\u8eab\u4e5f\u662f\u4e00\u79cd\u72ec\u7279\u7684\u6570\u636e\u5bf9\u8c61\u3002\u53ef\u4ee5\u628a\u5b83\u4eec\u8d4b\u7ed9\u53d8\u91cf\u3001\u5b58\u50a8\u5728\u6570\u636e\u7ed3\u6784\u91cc\u3001\u4f5c\u4e3a\u53c2\u6570\u4f20\u9012\u7ed9\u5176\u4ed6\u51fd\u6570\u4ee5\u53ca\u4f5c\u4e3a\u5176\u4ed6\u51fd\u6570\u7684\u503c\u8fd4\u56de\u3002 \u9ad8\u9636\u51fd\u6570\uff08higher-order function\uff09\uff1a\u5b83\u63a5\u6536\u53e6\u4e00\u4e2a\u51fd\u6570\u4f5c\u4e3a\u53c2\u6570\uff0c\u5e76\u4e14\u4ee5\u67d0\u79cd\u65b9\u5f0f\u5e94\u7528\u8be5\u51fd\u6570\u3002 Python\u6709\u4e24\u4e2a\u5185\u7f6e\u7684\u9ad8\u9636\u51fd\u6570\uff0c\u5206\u522b\u662f map \u548c filter \uff0c\u5b83\u4eec\u53ef\u4ee5\u7528\u4e8e\u5904\u7406\u53ef\u8fed\u4ee3\u5bf9\u8c61\u3002 map \u51fd\u6570\u4f1a\u63a5\u6536\u53e6\u4e00\u4e2a\u51fd\u6570\u548c\u4e00\u4e2a\u53ef\u8fed\u4ee3\u5bf9\u8c61\u4f5c\u4e3a\u53c2\u6570\uff0c\u8fd4\u56de\u53e6\u4e00\u4e2a\u53ef\u8fed\u4ee3\u5bf9\u8c61\u3002\u8fd9\u4e2a\u51fd\u6570\u4f1a\u628a\u4f5c\u4e3a\u53c2\u6570\u4f20\u9012\u7684\u51fd\u6570\u5e94\u7528\u5728\u53ef\u8fed\u4ee3\u5bf9\u8c61\u91cc\u7684\u6bcf\u4e2a\u5143\u7d20\u4e0a\u3002\u7b80\u5355\u6765\u8bf4\uff0c map \u51fd\u6570\u4f1a\u5bf9\u53ef\u8fed\u4ee3\u5bf9\u8c61\u91cc\u7684\u6bcf\u4e2a\u5143\u7d20\u8fdb\u884c\u8f6c\u6362\u3002 filter \u4f1a\u63a5\u53d7\u4e00\u4e2a\u5e03\u5c14\u51fd\u6570\u548c\u4e00\u4e2a\u53ef\u8fed\u4ee3\u5bf9\u8c61\u4f5c\u4e3a\u53c2\u6570\uff0c\u8fd4\u56de\u8fd9\u6837\u4e00\u4e2a\u53ef\u8fed\u4ee3\u5bf9\u8c61\uff0c\u5b83\u7684\u6bcf\u4e00\u4e2a\u5143\u7d20\u90fd\u4f1a\u88ab\u4f20\u9012\u7ed9\u5e03\u5c14\u51fd\u6570\uff0c\u5982\u679c\u8fd9\u4e2a\u51fd\u6570\u8fd4\u56deTrue\uff0c\u90a3\u4e48\u8fd9\u4e2a\u5143\u7d20\u5c06\u88ab\u4fdd\u7559\u5728\u8fd4\u56de\u7684\u53ef\u8fed\u4ee3\u5bf9\u8c61\u91cc\uff1b\u5426\u5219\uff0c\u8fd9\u4e2a\u5143\u7d20\u5c06\u88ab\u5220\u9664\u3002\u7b80\u5355\u8bf4\uff0c filter \u51fd\u6570\u4f1a\u628a\u6240\u6709\u80fd\u591f\u901a\u8fc7\u68c0\u9a8c\u7684\u5143\u7d20\u4fdd\u7559\u5728\u53ef\u8fed\u4ee3\u5bf9\u8c61\u91cc\u3002 functools.reduce \u901a\u8fc7\u628a\u63a5\u6536\u4e24\u4e2a\u53c2\u6570\u7684\u51fd\u6570\u7684\u7ed3\u679c\u4ee5\u53ca\u8fed\u4ee3\u5bf9\u8c61\u7684\u4e0b\u4e00\u4e2a\u5143\u7d20\u518d\u6b21\u5e94\u7528\u4e8e\u8fd9\u4e2a\u63a5\u6536\u4e24\u4e2a\u53c2\u6570\u7684\u51fd\u6570\uff0c\u6765\u628a\u53ef\u8fed\u4ee3\u5bf9\u8c61\u8ba1\u7b97\u6210\u5355\u4e00\u7684\u503c\u3002 \u793a\u4f8b\uff1a\u628a\u4e00\u4e2a\u6574\u6570\u5217\u8868\u8f6c\u6362\u6210\u53e6\u4e00\u4e2a\u5305\u542b\u8fd9\u4e9b\u6574\u6570\u7684\u5b57\u7b26\u4e32\u5f62\u5f0f\u7684\u5217\u8868\u3002 \u4f20\u7edf\u65b9\u6cd5\u5b9e\u73b0\uff1a oldList = [ 0 , 1 , 3 , 5 , 7 , 9 ] newList = [] for i in oldList : newList . append ( str ( i )) print ( newList ) # ['0', '1', '3', '5', '7', '9'] \u7528 map \u5b9e\u73b0\uff1a oldList = [ 0 , 1 , 3 , 5 , 7 , 9 ] newList = [] newList = list ( map ( str , oldList )) print ( newList ) # ['0', '1', '3', '5', '7', '9'] \u62d3\u5c55\uff1a\u628a\u4e00\u4e2a\u6574\u6570\u5217\u8868\u4e2d\u7684\u6b63\u6574\u6570\u8f6c\u6362\u6210\u53e6\u4e00\u4e2a\u5305\u542b\u8fd9\u4e9b\u6574\u6570\u7684\u5b57\u7b26\u4e32\u5f62\u5f0f\u7684\u5217\u8868\u3002 \u4f20\u7edf\u5b9e\u73b0\uff1a oldList = [ 0 , 1 , 3 , 5 , 7 , 9 ] newList = [] for i in oldList : if i > 0 : newList . append (( str ( i ))) print ( newList ) # ['1', '3', '5', '7', '9'] \u4f7f\u7528 filter \u5b9e\u73b0\uff1a oldList = [ 0 , 1 , 3 , 5 , 7 , 9 ] newList = [] def isPositive ( n ): if n > 0 : return True # \u521b\u5efa\u4e00\u4e2a\u4e0d\u5305\u542b\u4efb\u4f55\u96f6\u7684\u53ef\u8fed\u4ee3\u5bf9\u8c61 newList = list ( filter ( isPositive , oldList )) print ( newList ) # [1, 3, 5, 7, 9] \u793a\u4f8b\uff1a\u8ba1\u7b97\u4ece1\u523010\u7684\u4e58\u79ef\u5e76\u8f93\u51fa\u7ed3\u679c\u3002 \u901a\u8fc7 for \u5faa\u73af\u5b9e\u73b0\uff1a result = 1 value = 1 for value in range ( 1 , 11 ): result *= value value += 1 print ( result ) # \u8fd0\u884c\u7ed3\u679c # 3628800 \u901a\u8fc7 functools.reduce \u5faa\u73af\u5b9e\u73b0\uff1a import functools result = functools . reduce ( lambda x , y : x * y , range ( 1 , 11 )) print ( result ) # 3628800 1.5.5.lambda\u4e0e\u533f\u540d\u51fd\u6570 \u00b6 \u8bed\u6cd5\u683c\u5f0f\uff1a lambda < argument list > : < expression > lambda\u8868\u8fbe\u5f0f\u4e0d\u80fd\u50cf\u5176\u4ed6Python\u51fd\u6570\u90a3\u6837\u5305\u542b\u4e00\u6574\u4e2a\u8bed\u53e5\u5e8f\u5217\u3002 \u62d3\u5c55\uff1a\u7528lambda\u5b9e\u73b0\u628a\u4e00\u4e2a\u6574\u6570\u5217\u8868\u4e2d\u7684\u6b63\u6574\u6570\u8f6c\u6362\u6210\u53e6\u4e00\u4e2a\u5305\u542b\u8fd9\u4e9b\u6574\u6570\u7684\u5b57\u7b26\u4e32\u5f62\u5f0f\u7684\u5217\u8868\uff0c\u5b9e\u9645\u5c31\u662f\u901a\u8fc7\u4f7f\u7528\u533f\u540d\u7684\u5e03\u5c14\u51fd\u6570\u6765\u4ece\u6574\u6570\u5217\u8868\u91cc\u5254\u9664\u6240\u6709\u4e3a\u96f6\u7684\u5143\u7d20\u3002 oldList = [ 0 , 1 , 3 , 5 , 7 , 9 ] newList = [] newList = list ( filter ( lambda i : i > 0 , oldList )) print ( newList ) # [1, 3, 5, 7, 9] 1.6.\u6355\u83b7\u5f02\u5e38 \u00b6 \u8003\u8651\u4e24\u79cd\u5f02\u5e38\u60c5\u51b5\uff1a Python\u865a\u62df\u673a\u5728\u7a0b\u5e8f\u6267\u884c\u671f\u95f4\u9047\u5230\u4e86\u8bed\u4e49\u9519\u8bef\uff0c\u5219\u4f1a\u5f97\u5230\u76f8\u5e94\u7684\u9519\u8bef\u6d88\u606f\uff0c\u4ece\u800c\u5f15\u53d1\u4e00\u4e2a\u5f02\u5e38\u5e76\u4e14\u6682\u505c\u7a0b\u5e8f\u3002\u8bed\u4e49\u9519\u8bef\u5305\u62ec\u4f8b\u5982\u672a\u5b9a\u4e49\u7684\u53d8\u91cf\u540d\u3001\u9664\u4ee50\u4ee5\u53ca\u8d85\u51fa\u5217\u8868\u8303\u56f4\u7684\u7d22\u5f15\u7b49\u3002 \u7528\u6237\u5f15\u8d77\u7684\u67d0\u4e9b\u9519\u8bef\uff0c\u4f8b\u5982\uff0c\u671f\u671b\u8f93\u5165\u6570\u5b57\u7684\u65f6\u5019\u8f93\u5165\u4e86\u5176\u4ed6\u5b57\u7b26\u3002\u5bf9\u4e8e\u5728\u8fd9\u4e9b\u60c5\u51b5\u4e0b\u4ea7\u751f\u7684\u5f02\u5e38\uff0c\u7a0b\u5e8f\u4e0d\u5e94\u8be5\u505c\u6b62\u6267\u884c\uff0c\u800c\u5e94\u8be5\u5bf9\u8fd9\u4e9b\u5f02\u5e38\u8fdb\u884c\u6355\u83b7\uff0c\u5e76\u4e14\u5141\u8bb8\u7528\u6237\u4fee\u6b63\u9519\u8bef\u3002 Python\u63d0\u4f9b\u4e86try-except\u8bed\u53e5\uff0c\u53ef\u4ee5\u8ba9\u7a0b\u5e8f\u6355\u83b7\u5f02\u5e38\u5e76\u6267\u884c\u76f8\u5e94\u7684\u6062\u590d\u64cd\u4f5c\u3002 try \u5b50\u53e5\u4e2d\u7684\u8bed\u53e5\u5c06\u5148\u88ab\u6267\u884c\u3002\u5982\u679c\u8fd9\u4e9b\u8bed\u53e5\u4e2d\u7684\u4e00\u6761\u5f15\u53d1\u4e86\u5f02\u5e38\uff0c\u90a3\u4e48\u63a7\u5236\u6743\u4f1a\u7acb\u5373\u8f6c\u79fb\u5230 except \u5b50\u53e5\u53bb\u3002 \u5982\u679c\u5f15\u53d1\u7684\u5f02\u5e38\u7c7b\u578b\u548c\u8fd9\u4e2a\u5b50\u53e5\u91cc\u7684\u7c7b\u578b\u4e00\u81f4\uff0c\u90a3\u4e48\u4f1a\u6267\u884c\u5b83\u91cc\u9762\u7684\u8bed\u53e5\uff1b \u5426\u5219\uff0c\u5c06\u8f6c\u79fb\u5230try-except\u8bed\u53e5\u7684\u8c03\u7528\u8005\uff0c\u5e76\u57fa\u4e8e\u8c03\u7528\u94fe\u5411\u4e0a\u4f20\u9012\uff0c\u76f4\u5230\u8fd9\u4e2a\u5f02\u5e38\u88ab\u6210\u529f\u6355\u83b7\uff0c\u6216\u8005\u662f\u7a0b\u5e8f\u56e0\u9519\u8bef\u6d88\u606f\u800c\u505c\u6b62\u6267\u884c\u3002 \u5982\u679c try \u5b50\u53e5\u91cc\u7684\u8bed\u53e5\u6ca1\u6709\u5f15\u53d1\u4efb\u4f55\u5f02\u5e38\uff0c\u90a3\u4e48\u4f1a\u8df3\u8fc7 except \u5b50\u53e5\u5e76\u7ee7\u7eed\u6267\u884c\uff0c\u76f4\u5230try-except\u8bed\u53e5\u7684\u672b\u5c3e\u3002 try : < statements > except < exception type > : < statements > \u901a\u5e38\u6765\u8bf4\uff0c \u5bf9\u4e8e\u5df2\u77e5\u53ef\u80fd\u4f1a\u53d1\u751f\u7684\u5f02\u5e38\u7c7b\u578b\uff0c\u5e94\u8be5\u5c3d\u53ef\u80fd\u5730\u5305\u62ec\u5728\u5728 except \u8bed\u53e5\u91cc\u3002 \u5982\u679c\u4e0d\u77e5\u9053\u5f02\u5e38\u7684\u7c7b\u578b\uff0c\u53ef\u4ee5\u5728 except \u4e2d\u7528\u66f4\u901a\u7528\u7684Exception\u7c7b\u578b\u5339\u914d\u53ef\u80fd\u4f1a\u5f15\u53d1\u7684\u4efb\u4f55\u5f02\u5e38\u3002 \u793a\u4f8b\uff1a def getYourAge ( prompt ): \"\"\"\u63d0\u793a\u7528\u6237\u8f93\u5165\u4e00\u4e2a\u6574\u6570\uff0c\u5426\u5219\u7ed9\u51fa\u9519\u8bef\u63d0\u793a\uff0c\u5e76\u7ee7\u7eed\u63d0\u793a\u7528\u6237\u8f93\u5165\u3002\"\"\" inputStr = input ( prompt ) try : number = int ( inputStr ) return number except ValueError : print ( \"Error in number format:\" , inputStr ) return getYourAge ( prompt ) if __name__ == \"__main__\" : age = getYourAge ( \"Enter your age: \" ) print ( \"Your age is\" , age ) # \u8fd0\u884c\u7ed3\u679c # Enter your age: 3a # Error in number format: 3a # Enter your age: 3.5 # Error in number format: 3.5 # Enter your age: 20 # Your age is 20 1.7.\u6587\u4ef6\u53ca\u5176\u64cd\u4f5c \u00b6 1.7.1.\u6587\u672c\u6587\u4ef6\u8bfb\u53d6 \u00b6 \u53ef\u4ee5\u628a\u6587\u672c\u6587\u4ef6\u91cc\u7684\u6570\u636e\u770b\u4f5c\u5b57\u7b26\u3001\u5355\u8bcd\u3001\u6570\u5b57\u6216\u8005\u82e5\u5e72\u884c\u6587\u672c\u3002 \u5982\u679c\u628a\u6587\u672c\u6587\u4ef6\u91cc\u7684\u6570\u636e\u5f53\u4f5c\u6574\u6570\u6216\u6d6e\u70b9\u6570\uff0c\u5c31\u5fc5\u987b\u7528\u7a7a\u767d\u5b57\u7b26\uff08\u7a7a\u683c\u3001\u5236\u8868\u7b26\u548c\u6362\u884c\u7b26\uff09\u5c06\u5176\u5206\u9694\u5f00\u3002\u8f93\u51fa\u6216\u8f93\u5165\u5230\u6587\u672c\u6587\u4ef6\u7684\u6240\u6709\u6570\u636e\u5fc5\u987b\u662f\u5b57\u7b26\u4e32\u5f62\u5f0f\u7684\uff0c\u6240\u4ee5\u5728\u8f93\u5165/\u8f93\u51fa\u65f6\u9700\u8981\u505a\u76f8\u5e94\u7684\u7c7b\u578b\u8f6c\u6362\u3002 \u5982\u4e0b\u4f8b\uff1a 34.6 22.33 66.75 77.12 21.44 99.01 Python\u7684open\u51fd\u6570\u63a5\u6536\u4e0b\u9762\u4e24\u4e2a\u4e3b\u8981\u53c2\u6570\uff0c\u6253\u5f00\u4e00\u4e2a\u4e0e\u78c1\u76d8\u6587\u4ef6\u7684\u8fde\u63a5\u5e76\u4e14\u8fd4\u56de\u76f8\u5e94\u7684\u6587\u4ef6\u5bf9\u8c61\u3002 \u6587\u4ef6\u8def\u5f84\uff1b \u6253\u5f00\u6a21\u5f0f\uff1a \u6253\u5f00\u6a21\u5f0f\uff1a r \u8868\u793a\u6587\u4ef6\u53ea\u80fd\u8bfb\u53d6\uff1b w \u8868\u793a\u6587\u4ef6\u53ea\u80fd\u5199\u5165\uff1b a \u8868\u793a\u6253\u5f00\u6587\u4ef6\uff0c\u5728\u539f\u6709\u5185\u5bb9\u7684\u57fa\u7840\u4e0a\u8ffd\u52a0\u5185\u5bb9\uff0c\u5728\u672b\u5c3e\u5199\u5165\uff1b w+ \u8868\u793a\u53ef\u4ee5\u5bf9\u6587\u4ef6\u8fdb\u884c\u8bfb\u5199\u53cc\u91cd\u64cd\u4f5c\uff1b rb \u4ee5\u4e8c\u8fdb\u5236\u683c\u5f0f\u6253\u5f00\u4e00\u4e2a\u6587\u4ef6\uff0c\u7528\u4e8e\u53ea\u8bfb\uff1b wb \u4ee5\u4e8c\u8fdb\u5236\u683c\u5f0f\u6253\u5f00\u4e00\u4e2a\u6587\u4ef6\uff0c\u7528\u4e8e\u53ea\u5199\uff1b ab \u4ee5\u4e8c\u8fdb\u5236\u683c\u5f0f\u6253\u5f00\u4e00\u4e2a\u6587\u4ef6\uff0c\u7528\u4e8e\u8ffd\u52a0\uff1b wb+ \u4ee5\u4e8c\u8fdb\u5236\u683c\u5f0f\u6253\u5f00\u4e00\u4e2a\u6587\u4ef6\uff0c\u7528\u4e8e\u8bfb\u5199\uff1b \u793a\u4f8b\uff1a \u4e3a myfile.txt \u6587\u4ef6\u6253\u5f00\u4e00\u4e2a\u7528\u6765\u8f93\u51fa\u7684\u6587\u4ef6\u5bf9\u8c61\u3002 \u5b57\u7b26\u4e32\u6570\u636e\u901a\u8fc7 write \u65b9\u6cd5\u548c\u6587\u4ef6\u5bf9\u8c61\u5199\u5165\uff08\u6216\u8f93\u51fa\uff09\u5230\u6587\u4ef6\u91cc\u3002 \u8f6c\u4e49\u7b26 \\n \u5b9e\u73b0\u6362\u884c\u3002 \u4f7f\u7528 close \u65b9\u6cd5\u5173\u95ed\u6587\u4ef6\u3002\u5982\u679c\u6ca1\u6709\u5173\u95ed\u8f93\u51fa\u6587\u4ef6\uff0c\u5219\u53ef\u80fd\u5bfc\u81f4\u6570\u636e\u4e22\u5931\u3002 f = open ( \"./docs/python/DataStructure/code/myfile.txt\" , 'w' ) f . write ( \"First line. \\n Second line. \\n \" ) f . close () \u6587\u4ef6myfile.txt\u7684\u5185\u5bb9\uff1a First line. Second line. 1.7.2.\u6587\u672c\u6587\u4ef6\u5199\u5165 \u00b6 \u6587\u4ef6\u7684 write \u65b9\u6cd5\u63a5\u6536\u4e00\u4e2a\u5b57\u7b26\u4e32\u4f5c\u4e3a\u53c2\u6570\u3002\u56e0\u6b64\uff0c\u5176\u4ed6\u7c7b\u578b\u7684\u6570\u636e\uff08\u5982\u6574\u6570\u6216\u6d6e\u70b9\u6570\uff09\u5728\u5199\u5165\u8f93\u51fa\u6587\u4ef6\u4e4b\u524d\uff0c\u90fd\u5fc5\u987b\u5148\u88ab\u8f6c\u6362\u4e3a\u5b57\u7b26\u4e32\u3002 \u5728Python\u91cc\uff0c\u53ef\u4ee5\u4f7f\u7528 str \u51fd\u6570\u628a\u7edd\u5927\u591a\u6570\u7684\u6570\u636e\u7c7b\u578b\u7684\u503c\u8f6c\u6362\u4e3a\u5b57\u7b26\u4e32\uff0c\u4ee5\u7a7a\u683c\u6216\u6362\u884c\u7b26\u4f5c\u4e3a\u5206\u9694\u7b26\uff0c\u5c06\u5176\u5199\u5165\u6587\u4ef6\u91cc\u3002 \u793a\u4f8b\uff1a\u751f\u6210500\u4e2a\u4ecb\u4e8e1\u548c500\u4e4b\u95f4\u7684\u968f\u673a\u6570\uff0c\u5e76\u8f93\u51fa\u5230\u6587\u672c\u6587\u4ef6\u3002 import random f = open ( \"./docs/python/DataStructure/code/myfile.txt\" , 'w' ) for count in range ( 500 ): number = random . randint ( 1 , 500 ) f . write ( str ( number ) + \" \\n \" ) f . close () 1.7.3.\u4ece\u6587\u672c\u6587\u4ef6\u8bfb\u53d6\u6570\u636e \u00b6 \u793a\u4f8b\uff1a\u8bfb\u53d6\u6587\u4ef6\u5185\u5bb9\u3002 import random f = open ( \"./docs/python/DataStructure/code/myfile.txt\" , 'w' ) f . write ( \"First line. \\n Second line. \\n \" ) # \u521d\u59cb\u5316\u6587\u4ef6\u5185\u5bb9 f . close () # \u6253\u5f00\u6587\u4ef6\u8bfb\u53d6\u5185\u5bb9 f = open ( \"./docs/python/DataStructure/code/myfile.txt\" , 'r' ) text1 = f . read () # \u628a\u6587\u4ef6\u7684\u5168\u90e8\u5185\u5bb9\u8f93\u5165\u5355\u4e2a\u5b57\u7b26\u4e32\u4e2d print ( text1 ) # \u8fd0\u884c\u7ed3\u679c\uff1a # First line. # Second line text2 = f . read () # \u518d\u6b21read\uff0c\u5f97\u5230\u4e00\u4e2a\u7a7a\u5b57\u4e32\uff0c\u8868\u8ff0\u5df2\u7ecf\u5230\u8fbe\u6587\u4ef6\u672b\u5c3e\u3002\u8981\u518d\u6b21\u8bfb\u53d6\u9700\u8981\u91cd\u65b0\u6253\u5f00\u6587\u4ef6 print ( \"======\" ) print ( text2 ) # \u8fd0\u884c\u7ed3\u679c\uff1a # ====== # f . close () # \u91cd\u65b0\u6253\u5f00\u6587\u4ef6\u8bfb\u53d6\u5185\u5bb9 f = open ( \"./docs/python/DataStructure/code/myfile.txt\" , 'r' ) for line in f : # \u9010\u884c\u8bfb\u53d6\u6587\u4ef6\u5185\u5bb9 print ( \"======\" ) print ( line ) # \u6bcf\u884c\u90fd\u6709\u4e00\u4e2a\u6362\u884c\u7b26\uff0c\u8fd9\u662fprint\u51fd\u6570\u9ed8\u8ba4\u884c\u4e3a # \u8fd0\u884c\u7ed3\u679c\uff1a # ====== # First line. # ====== # Second line. # f . close () # \u91cd\u65b0\u6253\u5f00\u6587\u4ef6\u8bfb\u53d6\u5185\u5bb9 f = open ( \"./docs/python/DataStructure/code/myfile.txt\" , 'r' ) while True : line = f . readline () # readline\u65b9\u6cd5\u4f1a\u4ece\u8f93\u5165\u7684\u6587\u672c\u91cc\u53ea\u83b7\u53d6\u4e00\u884c\u6570\u636e\uff0c\u5e76\u4e14\u8fd4\u56de\u8fd9\u4e2a\u5305\u542b\u6362\u884c\u7b26\u7684\u5b57\u7b26\u4e32\u3002\u5982\u679creadline\u9047\u5230\u4e86\u6587\u4ef6\u672b\u5c3e\uff0c\u90a3\u4e48\u4f1a\u8fd4\u56de\u7a7a\u5b57\u7b26\u4e32\u3002 if line == \"\" : break print ( \"******\" ) print ( line ) # \u8fd0\u884c\u7ed3\u679c\uff1a # ****** # First line. # ****** # Second line. # f . close () # \u91cd\u65b0\u6253\u5f00\u6587\u4ef6\u8bfb\u53d6\u5185\u5bb9 f = open ( \"./docs/python/DataStructure/code/myfile.txt\" , 'r' ) line = f . readlines () # readlines\u65b9\u6cd5\u5219\u662f\u8bfb\u53d6\u6240\u6709\u884c\uff0c\u8fd4\u56de\u7684\u662f\u6240\u6709\u884c\u7ec4\u6210\u7684\u5217\u8868\u3002 print ( line ) # \u8fd0\u884c\u7ed3\u679c\uff1a # ['First line.\\n', 'Second line.\\n'] f . close () 1.7.4.\u4ece\u5176\u5b83\u6587\u4ef6\u8bfb\u53d6\u6570\u636e \u00b6 \u793a\u4f8b\uff1a\u8bfb\u53d6\u6587\u4ef6\u4e2d\u7684\u6574\u6570\uff0c\u6bcf\u884c\u53ea\u6709\u4e00\u4e2a\u6574\u6570\u3002 import random f = open ( \"./docs/python/DataStructure/code/myfile.txt\" , 'w' ) # \u751f\u62100~9\u6574\u6570\uff0c\u5e76\u5199\u5165\u6587\u4ef6 for count in range ( 10 ): f . write ( str ( count ) + \" \\n \" ) f . close () # \u6253\u5f00\u6587\u4ef6 f = open ( \"./docs/python/DataStructure/code/myfile.txt\" , 'r' ) # \u4f9d\u6b21\u8bfb\u53d6\u6587\u4ef6\u4e2d\u7684\u6570\u5b57\uff0c\u5e76\u6c42\u548c theSum = 0 for line in f : line = line . strip () number = int ( line ) theSum += number print ( \"The sum is : \" , theSum ) # \u8fd0\u884c\u7ed3\u679c\uff1a # The sum is : 45 f . close () \u793a\u4f8b\uff1a\u8bfb\u53d6\u6587\u4ef6\u4e2d\u7684\u6574\u6570\uff0c\u6bcf\u884c\u6709\u591a\u4e2a\u6574\u6570\u3002\u9700\u8981\u4e8b\u5148\u628a\u4e0b\u9762\u7684\u5185\u5bb9\u5199\u5165 myfile.txt \u6587\u4ef6\u4e2d\u3002 \u6587\u4ef6 myfile.txt \u7684\u5185\u5bb9\u3002 1 3 5 7 9 2 4 6 8 10 31 200 3000 50000 import random # \u6253\u5f00\u6587\u4ef6 f = open ( \"./docs/python/DataStructure/code/myfile.txt\" , 'r' ) # \u4f9d\u6b21\u8bfb\u53d6\u6587\u4ef6\u4e2d\u7684\u6570\u5b57\uff0c\u5e76\u6c42\u548c theSum = 0 for line in f : lines = line . split () # split\u65b9\u6cd5\u4f1a\u81ea\u52a8\u5904\u7406\u6362\u884c\u7b26 for word in lines : number = int ( word ) theSum += number print ( \"The sum is : \" , theSum ) # \u8fd0\u884c\u7ed3\u679c\uff1a # The sum is : 53286 f . close () \u7b80\u5199\u4e0a\u9762\u7684\u4ee3\u7801\u3002 import random f = open ( \"./docs/python/DataStructure/code/myfile.txt\" , 'r' ) print ( \"The sum is: \" , sum ( map ( int , f . read () . split ()))) # \u8fd0\u884c\u7ed3\u679c\uff1a # The sum is : 53286 f . close () 1.7.5.\u4f7f\u7528pickle\u8bfb\u5199\u5bf9\u8c61 \u00b6 \u5728\u628a\u4efb\u4f55\u5bf9\u8c61\u4fdd\u5b58\u5230\u6587\u4ef6\u4e4b\u524d\uff0c\u6211\u4eec\u53ef\u4ee5\u5bf9\u5b83\u8fdb\u884c\u201c\u814c\u5236\u201d\uff1b\u5728\u628a\u5bf9\u8c61\u4ece\u6587\u4ef6\u52a0\u8f7d\u5230\u7a0b\u5e8f\u4e2d\u65f6\uff0c\u4e5f\u53ef\u4ee5\u5bf9\u5b83\u8fdb\u884c\u201c\u53cd\u814c\u5236\u201d\u3002 \u793a\u4f8b\uff1a \u4f7f\u7528pickle\u6a21\u5757\u7684 pickle.dump \u628a\u540d\u4e3alyst\u7684\u5217\u8868\u91cc\u7684\u6240\u6709\u5bf9\u8c61\u4fdd\u5b58\u5230\u540d\u4e3aitems.dat\u7684\u6587\u4ef6\u91cc\uff08\u201c\u814c\u5236\u201d\uff09\u3002\u6211\u4eec\u4e0d\u9700\u8981\u77e5\u9053\u5217\u8868\u91cc\u6709\u54ea\u4e9b\u7c7b\u578b\u7684\u5bf9\u8c61\uff0c\u4e5f\u4e0d\u9700\u8981\u77e5\u9053\u6709\u591a\u5c11\u4e2a\u5bf9\u8c61\u3002 import pickle myList = [ 60 , \"A string object\" , 1977 ] fObj = open ( \"./docs/python/DataStructure/code/items.dat\" , \"wb\" ) for item in myList : pickle . dump ( item , fObj ) fObj . close () \u4f7f\u7528pickle\u6a21\u5757\u7684 pickle.load \u628aitems.dat\u7684\u6587\u4ef6\u5185\u5bb9\u52a0\u8f7d\u56de\u7a0b\u5e8f\uff08\u201c\u53cd\u814c\u5236\u201d\uff09\u3002 import pickle lyst = list () fileObj = open ( \"./docs/python/DataStructure/code/items.dat\" , \"rb\" ) while True : try : item = pickle . load ( fileObj ) lyst . append ( item ) except EOFError : # \u68c0\u6d4b\u5df2\u7ecf\u5230\u8fbe\u6587\u4ef6\u672b\u5c3e fileObj . close () break print ( lyst ) # \u8fd0\u884c\u7ed3\u679c\uff1a # [60, 'A string object', 1977] 1.8.\u521b\u5efa\u7c7b \u00b6 \u7c7b\uff08class\uff09\u7528\u6765\u63cf\u8ff0\u4e0e\u4e00\u7ec4\u5bf9\u8c61\u6709\u5173\u7684\u6570\u636e\u548c\u65b9\u6cd5\u3002\u5b83\u63d0\u4f9b\u4e86\u7528\u6765\u521b\u5efa\u5bf9\u8c61\u7684\u84dd\u56fe\uff0c\u4ee5\u53ca\u5728\u5bf9\u8c61\u4e0a\u8c03\u7528\u65b9\u6cd5\u65f6\u6240\u9700\u8981\u6267\u884c\u7684\u4ee3\u7801\u3002 Python\u91cc\u7684\u6570\u636e\u7c7b\u578b\u90fd\u662f\u7c7b\uff1b \u7c7b\u540d\u6309\u7167\u60ef\u4f8b\u9996\u5b57\u6bcd\u5e94\u4e3a\u5927\u5199\u6837\u5f0f\uff1b \u5b9a\u4e49\u7c7b\u7684\u4ee3\u7801\u901a\u5e38\u4f1a\u88ab\u5b58\u653e\u5728\u9996\u5b57\u6bcd\u5c0f\u5199\u7684\u7c7b\u540d\u7684\u6a21\u5757\u6587\u4ef6\u91cc\u3002 \u76f8\u5173\u7684\u7c7b\u4e5f\u53ef\u80fd\u4f1a\u51fa\u73b0\u5728\u540c\u4e00\u4e2a\u6a21\u5757\u91cc\u3002 \u7c7b\u7684\u8bed\u6cd5\uff1a def < class name > ( < parent class name > )[ 2 ]: < class variable assignments > < instance method definitions > \u7236\u7c7b\uff08parent class\uff09\u7684\u540d\u79f0\u662f\u53ef\u9009\u7684\uff0c\u5728\u9ed8\u8ba4\u60c5\u51b5\u4e0b\uff0c\u5b83\u4f1a\u662fobject\u3002 \u6240\u6709Python\u7c7b\u5c5e\u4e8e\u4e00\u4e2a\u4ee5 object \u4f5c\u4e3a\u6839\u8282\u70b9\u7684\u5c42\u6b21\u7ed3\u6784\u3002 \u5728 object \u91cc\uff0cPython\u5b9a\u4e49\u4e86\u51e0\u79cd\u65b9\u6cd5\uff1a __str__ \u548c __eq__ \uff0c\u56e0\u6b64\u6240\u6709\u5b50\u7c7b\u4f1a\u81ea\u52a8\u7ee7\u627f\u8fd9\u4e9b\u65b9\u6cd5\u3002 \u5b9e\u4f8b\u65b9\u6cd5\uff08instance method\uff09\u662f\u5728\u7c7b\u7684\u5bf9\u8c61\u4e0a\u8fd0\u884c\u7684\u3002\u5b83\u4eec\u5305\u542b\u7528\u6765\u8bbf\u95ee\u6216\u4fee\u6539\u5b9e\u4f8b\u53d8\u91cf\u7684\u4ee3\u7801\u3002 \u5b9e\u4f8b\u53d8\u91cf\uff08instance variable\uff09\u662f\u6307\u7531\u5355\u4e2a\u5bf9\u8c61\u6240\u62e5\u6709\u7684\u5b58\u50a8\u4fe1\u606f\u3002 \u7c7b\u53d8\u91cf\uff08class variable\uff09\u662f\u6307\u7531\u7c7b\u7684\u6240\u6709\u5bf9\u8c61\u5b58\u50a8\u6240\u6709\u7684\u4fe1\u606f\u3002 \u793a\u4f8b\uff1a\u89e3\u8bfbCounter\u7c7b\u3002 Counter \u7c7b\u662f object \u7684\u5b50\u7c7b\uff1b instances \u662f\u7c7b\u53d8\u91cf\uff0c\u8ddf\u8e2a\u5df2\u521b\u5efa\u7684\u8ba1\u6570\u5668\u5bf9\u8c61\u7684\u6570\u91cf\uff1b \u5b9e\u4f8b\u65b9\u6cd5 __init__ \u4e5f\u79f0\u4e3a\u6784\u9020\u51fd\u6570\uff1b\u8fd9\u4e2a\u65b9\u6cd5\u7528\u6765\u521d\u59cb\u5316\u5b9e\u4f8b\u53d8\u91cf\uff0c\u5e76\u4e14\u5bf9\u7c7b\u53d8\u91cf\u8fdb\u884c\u66f4\u65b0\uff1b self \u662f\u6307\u5728\u8fd0\u884c\u65f6\u8fd9\u4e2a\u65b9\u6cd5\u7684\u5bf9\u8c61\u672c\u8eab\uff1b \u4f7f\u7528\u5b9e\u4f8b\u53d8\u91cf\u90fd\u4f1a\u52a0\u4e0a\u524d\u7f00 self \uff1b\u548c\u53c2\u6570\u6216\u4e34\u65f6\u53d8\u91cf\u4e0d\u540c\u7684\u5730\u65b9\u662f\uff0c\u5b9e\u4f8b\u53d8\u91cf\u5728\u7c7b\u7684\u4efb\u4f55\u65b9\u6cd5\u91cc\u662f\u53ef\u89c1\u7684\uff1b \u5176\u4ed6\u5b9e\u4f8b\u65b9\u6cd5\u53ef\u4ee5\u5206\u4e3a\u4e24\u79cd\uff1a\u53d8\u5f02\u5668\uff08mutator\uff09\u548c\u8bbf\u95ee\u5668\uff08accessor\uff09\u3002\u53d8\u5f02\u5668\u4f1a\u901a\u8fc7\u4fee\u6539\u5bf9\u8c61\u7684\u5b9e\u4f8b\u53d8\u91cf\u5bf9\u5176\u5185\u90e8\u72b6\u6001\u8fdb\u884c\u4fee\u6539\u6216\u66f4\u6539\u3002\u8bbf\u95ee\u5668\u5219\u53ea\u4f1a\u67e5\u770b\u6216\u4f7f\u7528\u5bf9\u8c61\u7684\u5b9e\u4f8b\u53d8\u91cf\u7684\u503c\uff0c\u800c\u4e0d\u4f1a\u53bb\u4fee\u6539\u5b83\u4eec\uff1b __str__ \u65b9\u6cd5\u5c06\u8986\u76d6object\u7c7b\u91cc\u7684\u8fd9\u4e2a\u65b9\u6cd5\uff1b \u5f53Python\u7684 print \u51fd\u6570\u63a5\u6536\u5230\u4e00\u4e2a\u53c2\u6570\u65f6\uff0c\u8fd9\u4e2a\u53c2\u6570\u7684 __str__ \u65b9\u6cd5\u5c06\u81ea\u52a8\u8fd0\u884c\uff0c\u4ece\u800c\u5f97\u5230\u5b83\u7684\u5b57\u7b26\u4e32\u8868\u8fbe\u5f0f\uff0c\u4ee5\u4fbf\u7528\u6765\u8f93\u51fa\uff1b \u5f53\u770b\u5230 == \u8fd0\u7b97\u7b26\u65f6\uff0cPython\u5c06\u8fd0\u884c __eq__ \u65b9\u6cd5\uff1b\u5728 object \u7c7b\u91cc\uff0c\u8fd9\u4e2a\u65b9\u6cd5\u7684\u9ed8\u8ba4\u5b9a\u4e49\u662f\u8fd0\u884c is \u8fd0\u7b97\u7b26\u3002 class Counter ( object ): # Counter\u7c7b\u662fobject\u7684\u5b50\u7c7b \"\"\"Models a counter.\"\"\" # Class variable \u7c7b\u53d8\u91cf instances = 0 # \u8ddf\u8e2a\u5df2\u521b\u5efa\u7684\u8ba1\u6570\u5668\u5bf9\u8c61\u7684\u6570\u91cf # Constructor \u6784\u9020\u5668 # \u5b9e\u4f8b\u65b9\u6cd5__init__\u4e5f\u79f0\u4e3a\u6784\u9020\u51fd\u6570\uff1b\u8fd9\u4e2a\u65b9\u6cd5\u7528\u6765\u521d\u59cb\u5316\u5b9e\u4f8b\u53d8\u91cf\uff0c\u5e76\u4e14\u5bf9\u7c7b\u53d8\u91cf\u8fdb\u884c\u66f4\u65b0\uff1b def __init__ ( self ): # self\u662f\u6307\u5728\u8fd0\u884c\u65f6\u8fd9\u4e2a\u65b9\u6cd5\u7684\u5bf9\u8c61\u672c\u8eab \"\"\"Sets up the counter.\"\"\" Counter . instances += 1 self . reset () # Mutator methods def reset ( self ): \"\"\"Sets the counter to 0.\"\"\" self . value = 0 def increment ( self , amount = 1 ): \"\"\"Adds amount to the counter.\"\"\" self . value += amount def decrement ( self , amount = 1 ): \"\"\"Subtracts amount from the counter.\"\"\" self . value -= amount # Accessor methods def getValue ( self ): \"\"\"Returns the counter's value.\"\"\" return self . value def __str__ ( self ): \"\"\"Returns the string representation of the counter.\"\"\" return str ( self . value ) def __eq__ ( self , other ): \"\"\"Returns True if self equals other or False otherwise.\"\"\" if self is other : return True if type ( self ) != type ( other ): return False return self . value == other . value c1 = Counter () print ( c1 ) # \u8fd0\u884c\u7ed3\u679c\uff1a # 0 c1 . getValue () str ( c1 ) c1 . increment () print ( c1 ) # \u8fd0\u884c\u7ed3\u679c\uff1a # 1 c1 . increment ( 5 ) print ( c1 ) # \u8fd0\u884c\u7ed3\u679c\uff1a # 6 c1 . reset () print ( c1 ) # \u8fd0\u884c\u7ed3\u679c\uff1a # 0 c2 = Counter () print ( Counter . instances ) # \u8fd0\u884c\u7ed3\u679c\uff1a # 2 print ( c1 == c1 ) # \u8fd0\u884c\u7ed3\u679c\uff1a # True print ( c1 == 0 ) # \u8fd0\u884c\u7ed3\u679c\uff1a # False print ( c1 == c2 ) # \u8fd0\u884c\u7ed3\u679c\uff1a # True c2 . increment () print ( c1 == c2 ) # \u8fd0\u884c\u7ed3\u679c\uff1a # False 1.9.\u7f16\u7a0b\u7ec3\u4e60 \u00b6 1\uff0e\u7f16\u5199\u4e00\u4e2a\u7a0b\u5e8f\uff0c\u4f7f\u4e4b\u80fd\u591f\u63a5\u6536\u7403\u4f53\u7684\u534a\u5f84\uff08\u6d6e\u70b9\u6570\uff09\uff0c\u5e76\u4e14\u53ef\u4ee5\u8f93\u51fa\u7403\u4f53\u7684\u76f4\u5f84\u3001\u5468\u957f\u3001\u8868\u9762\u79ef\u4ee5\u53ca\u4f53\u79ef\u3002 \u89e3\u7b54\uff1a PAI = 3.14 radius = float ( input ( \"\u8f93\u5165\u7403\u534a\u5f84\uff1a\" )) diameter = radius * 2 circumference = 2 * PAI * radius surfaceArea = 4 * PAI * radius ** 2 sphereVolume = 4 * ( PAI * radius ** 3 ) / 3 print ( \"\u7403\u534a\u5f84\uff1a\" , radius , \"\u7403\u76f4\u5f84\uff1a\" , diameter , \"\u7403\u8868\u9762\u79ef\uff1a\" , surfaceArea , \"\u7403\u4f53\u79ef\uff1a\" , sphereVolume ) # \u8fd0\u884c\u7ed3\u679c\uff1a # \u8f93\u5165\u7403\u534a\u5f84\uff1a3.5 # \u7403\u534a\u5f84\uff1a 3.5 \u7403\u76f4\u5f84\uff1a 7.0 \u7403\u8868\u9762\u79ef\uff1a 153.86 \u7403\u4f53\u79ef\uff1a 179.50333333333333 import math def main (): try : radius = float ( input ( \"\u8bf7\u8f93\u5165\u7403\u534a\u5f84\uff1a\" )) if radius <= 0 : print ( \"\u534a\u5f84\u5fc5\u987b\u4e3a\u6b63\u6570\uff01\" ) return diameter = 2 * radius circumference = 2 * math . pi * radius surfaceArea = 4 * math . pi * radius ** 2 volume = ( 4 / 3 ) * math . pi * radius ** 3 print ( f \"\u7403\u4f53\u7684\u76f4\u5f84\uff1a { diameter : .2f } \" ) print ( f \"\u7403\u4f53\u7684\u5468\u957f\uff1a { circumference : .2f } \" ) print ( f \"\u7403\u4f53\u7684\u8868\u9762\u79ef\uff1a { surfaceArea : .2f } \" ) print ( f \"\u7403\u4f53\u7684\u4f53\u79ef\uff1a { volume : .2f } \" ) except ValueError : print ( \"\u8bf7\u8f93\u5165\u6709\u6548\u7684\u6570\u5b57\uff01\" ) if __name__ == \"__main__\" : main () # \u8fd0\u884c\u7ed3\u679c\uff1a # \u8bf7\u8f93\u5165\u7403\u534a\u5f84\uff1a3.5 # \u7403\u4f53\u7684\u76f4\u5f84\uff1a7.00 # \u7403\u4f53\u7684\u5468\u957f\uff1a21.99 # \u7403\u4f53\u7684\u8868\u9762\u79ef\uff1a153.94 # \u7403\u4f53\u7684\u4f53\u79ef\uff1a179.59 import math class Sphere : def __init__ ( self , radius ): self . radius = radius def diameter ( self ): return 2 * self . radius def circumference ( self ): return 2 * math . pi * self . radius def surfaceArea ( self ): return 4 * math . pi * self . radius ** 2 def volume ( self ): return ( 4 / 3 ) * math . pi * self . radius ** 3 def main (): try : radius = float ( input ( \"\u8bf7\u8f93\u5165\u7403\u4f53\u7684\u534a\u5f84\uff1a\" )) if radius <= 0 : print ( \"\u534a\u5f84\u5fc5\u987b\u4e3a\u6b63\u6570\uff01\" ) return sphere = Sphere ( radius ) print ( f \"\u7403\u4f53\u7684\u76f4\u5f84\uff1a { sphere . diameter () : .2f } \" ) print ( f \"\u7403\u4f53\u7684\u5468\u957f\uff1a { sphere . circumference () : .2f } \" ) print ( f \"\u7403\u4f53\u7684\u8868\u9762\u79ef\uff1a { sphere . surfaceArea () : .2f } \" ) print ( f \"\u7403\u4f53\u7684\u4f53\u79ef\uff1a { sphere . volume () : .2f } \" ) except ValueError : print ( \"\u8bf7\u8f93\u5165\u6709\u6548\u7684\u6570\u5b57\uff01\" ) if __name__ == \"__main__\" : main () # \u8fd0\u884c\u7ed3\u679c\uff1a # \u8bf7\u8f93\u5165\u7403\u4f53\u7684\u534a\u5f84\uff1a3.5 # \u7403\u4f53\u7684\u76f4\u5f84\uff1a7.00 # \u7403\u4f53\u7684\u5468\u957f\uff1a21.99 # \u7403\u4f53\u7684\u8868\u9762\u79ef\uff1a153.94 # \u7403\u4f53\u7684\u4f53\u79ef\uff1a179.59 2\uff0e\u5458\u5de5\u7684\u5468\u5de5\u8d44\u7b49\u4e8e\u5c0f\u65f6\u5de5\u8d44\u4e58\u4ee5\u6b63\u5e38\u7684\u603b\u5de5\u4f5c\u65f6\u95f4\u518d\u52a0\u4e0a\u52a0\u73ed\u5de5\u8d44\u3002\u52a0\u73ed\u5de5\u8d44\u7b49\u4e8e\u603b\u52a0\u73ed\u65f6\u95f4\u4e58\u4ee5\u5c0f\u65f6\u5de5\u8d44\u76841.5\u500d\u3002\u7f16\u5199\u4e00\u4e2a\u7a0b\u5e8f\uff0c\u8ba9\u7528\u6237\u53ef\u4ee5\u8f93\u5165\u5c0f\u65f6\u5de5\u8d44\u3001\u6b63\u5e38\u7684\u603b\u5de5\u4f5c\u65f6\u95f4\u4ee5\u53ca\u52a0\u73ed\u603b\u65f6\u95f4\uff0c\u7136\u540e\u663e\u793a\u51fa\u5458\u5de5\u7684\u5468\u5de5\u8d44\u3002 \u89e3\u7b54\uff1a hourSalary = float ( input ( \"\u8f93\u5165\u5c0f\u65f6\u5de5\u8d44\uff08\u5143\uff09\uff1a\" )) totalWorkingHours = float ( input ( \"\u8f93\u5165\u672c\u5468\u6b63\u5e38\u603b\u5de5\u4f5c\u65f6\u95f4\uff08\u5c0f\u65f6\uff09\uff1a\" )) totalOvertimeHours = float ( input ( \"\u8f93\u5165\u672c\u5468\u603b\u52a0\u73ed\u603b\u5de5\u4f5c\u65f6\u95f4\uff08\u5c0f\u65f6\uff09\uff1a\" )) weeklySalary = hourSalary * totalWorkingHours + hourSalary * totalOvertimeHours * 1.5 print ( \"\u5458\u5de5\u7684\u5468\u5de5\u8d44\uff08\u5143\uff09\u662f\uff1a\" , weeklySalary ) # \u8fd0\u884c\u7ed3\u679c\uff1a # \u8f93\u5165\u5c0f\u65f6\u5de5\u8d44\uff08\u5143\uff09\uff1a20 # \u8f93\u5165\u672c\u5468\u6b63\u5e38\u603b\u5de5\u4f5c\u65f6\u95f4\uff08\u5c0f\u65f6\uff09\uff1a40 # \u8f93\u5165\u672c\u5468\u603b\u52a0\u73ed\u603b\u5de5\u4f5c\u65f6\u95f4\uff08\u5c0f\u65f6\uff09\uff1a10 # \u5458\u5de5\u7684\u5468\u5de5\u8d44\uff08\u5143\uff09\u662f\uff1a 1100.0 def calculate_weekly_salary ( hourly_wage , normal_hours , overtime_hours ): overtime_pay = overtime_hours * hourly_wage * 1.5 normal_pay = normal_hours * hourly_wage weekly_salary = normal_pay + overtime_pay return weekly_salary def main (): try : hourly_wage = float ( input ( \"\u8bf7\u8f93\u5165\u5c0f\u65f6\u5de5\u8d44\uff1a\" )) normal_hours = float ( input ( \"\u8bf7\u8f93\u5165\u6b63\u5e38\u7684\u603b\u5de5\u4f5c\u65f6\u95f4\uff08\u5c0f\u65f6\uff09\uff1a\" )) overtime_hours = float ( input ( \"\u8bf7\u8f93\u5165\u52a0\u73ed\u603b\u65f6\u95f4\uff08\u5c0f\u65f6\uff09\uff1a\" )) weekly_salary = calculate_weekly_salary ( hourly_wage , normal_hours , overtime_hours ) print ( f \"\u5458\u5de5\u7684\u5468\u5de5\u8d44\u4e3a\uff1a { weekly_salary : .2f } \" ) except ValueError : print ( \"\u8bf7\u8f93\u5165\u6709\u6548\u7684\u6570\u5b57\uff01\" ) if __name__ == \"__main__\" : main () # \u8fd0\u884c\u7ed3\u679c\uff1a # \u8bf7\u8f93\u5165\u5c0f\u65f6\u5de5\u8d44\uff1a20 # \u8bf7\u8f93\u5165\u6b63\u5e38\u7684\u603b\u5de5\u4f5c\u65f6\u95f4\uff08\u5c0f\u65f6\uff09\uff1a40 # \u8bf7\u8f93\u5165\u52a0\u73ed\u603b\u65f6\u95f4\uff08\u5c0f\u65f6\uff09\uff1a10 # \u5458\u5de5\u7684\u5468\u5de5\u8d44\u4e3a\uff1a1100.00 class Employee : def __init__ ( self , hourly_wage , normal_hours , overtime_hours ): self . hourly_wage = hourly_wage self . normal_hours = normal_hours self . overtime_hours = overtime_hours def calculate_weekly_salary ( self ): overtime_pay = self . overtime_hours * self . hourly_wage * 1.5 normal_pay = self . normal_hours * self . hourly_wage weekly_salary = normal_pay + overtime_pay return weekly_salary def main (): try : hourly_wage = float ( input ( \"\u8bf7\u8f93\u5165\u5c0f\u65f6\u5de5\u8d44\uff1a\" )) normal_hours = float ( input ( \"\u8bf7\u8f93\u5165\u6b63\u5e38\u7684\u603b\u5de5\u4f5c\u65f6\u95f4\uff08\u5c0f\u65f6\uff09\uff1a\" )) overtime_hours = float ( input ( \"\u8bf7\u8f93\u5165\u52a0\u73ed\u603b\u65f6\u95f4\uff08\u5c0f\u65f6\uff09\uff1a\" )) employee = Employee ( hourly_wage , normal_hours , overtime_hours ) weekly_salary = employee . calculate_weekly_salary () print ( f \"\u5458\u5de5\u7684\u5468\u5de5\u8d44\u4e3a\uff1a { weekly_salary : .2f } \" ) except ValueError : print ( \"\u8bf7\u8f93\u5165\u6709\u6548\u7684\u6570\u5b57\uff01\" ) if __name__ == \"__main__\" : main () # \u8fd0\u884c\u7ed3\u679c\uff1a # \u8bf7\u8f93\u5165\u5c0f\u65f6\u5de5\u8d44\uff1a20 # \u8bf7\u8f93\u5165\u6b63\u5e38\u7684\u603b\u5de5\u4f5c\u65f6\u95f4\uff08\u5c0f\u65f6\uff09\uff1a40 # \u8bf7\u8f93\u5165\u52a0\u73ed\u603b\u65f6\u95f4\uff08\u5c0f\u65f6\uff09\uff1a10 # \u5458\u5de5\u7684\u5468\u5de5\u8d44\u4e3a\uff1a1100.00 3\uff0e\u6709\u4e00\u4e2a\u6807\u51c6\u7684\u79d1\u5b66\u5b9e\u9a8c\uff1a\u6254\u4e00\u4e2a\u7403\uff0c\u770b\u770b\u5b83\u80fd\u53cd\u5f39\u591a\u9ad8\u3002\u4e00\u65e6\u786e\u5b9a\u4e86\u7403\u7684\u201c\u53cd\u5f39\u9ad8\u5ea6\u201d\uff0c\u8fd9\u4e2a\u6bd4\u503c\u5c31\u7ed9\u51fa\u4e86\u76f8\u5e94\u7684\u53cd\u5f39\u5ea6\u6307\u6570\u3002\u4f8b\u5982\uff0c\u5982\u679c\u4ece10ft\uff081ft=0.3048m\uff09\u9ad8\u5904\u6389\u843d\u7684\u7403\u53ef\u4ee5\u53cd\u5f39\u52306 ft\u9ad8\uff0c\u90a3\u4e48\u76f8\u5e94\u7684\u53cd\u5f39\u5ea6\u6307\u6570\u5c31\u662f0.6\uff1b\u5728\u4e00\u6b21\u53cd\u5f39\u4e4b\u540e\uff0c\u7403\u7684\u603b\u884c\u8fdb\u8ddd\u79bb\u662f16 ft\u3002\u63a5\u4e0b\u6765\uff0c\u7403\u7ee7\u7eed\u5f39\u8df3\uff0c\u90a3\u4e48\u4e24\u6b21\u5f39\u8df3\u540e\u7684\u603b\u8ddd\u79bb\u5e94\u8be5\u662f\uff1a10 ft + 6 ft + 6 ft + 3.6 ft = 25.6 ft\u3002\u53ef\u4ee5\u770b\u5230\uff0c\u6bcf\u6b21\u8fde\u7eed\u5f39\u8df3\u6240\u7ecf\u8fc7\u7684\u8ddd\u79bb\u662f\uff1a\u7403\u5230\u5730\u9762\u7684\u8ddd\u79bb\uff0c\u52a0\u4e0a\u8fd9\u4e2a\u8ddd\u79bb\u4e58\u4ee5 0.6\uff0c\u8fd9\u65f6\u7403\u53c8\u5f39\u56de\u6765\u4e86\u3002\u7f16\u5199\u4e00\u4e2a\u7a0b\u5e8f\uff0c\u53ef\u4ee5\u8ba9\u7528\u6237\u8f93\u5165\u7403\u7684\u521d\u59cb\u9ad8\u5ea6\u548c\u5141\u8bb8\u7403\u5f39\u8df3\u7684\u6b21\u6570\uff0c\u5e76\u8f93\u51fa\u7403\u6240\u7ecf\u8fc7\u7684\u603b\u8ddd\u79bb\u3002 \u89e3\u7b54\uff1a height = float ( input ( \"\u8f93\u5165\u5c0f\u7403\u521d\u59cb\u9ad8\u5ea6\uff08ft\uff09\uff1a\" )) times = float ( input ( \"\u8f93\u5165\u5141\u8bb8\u5c0f\u7403\u5f39\u8df3\u6b21\u6570\uff1a\" )) distance = 0 traceDistance = 0 while times : distance = height + 0.6 * height traceDistance += distance height = 0.6 * height times -= 1 print ( \"\u5c0f\u7403\u7ecf\u8fc7\u7684\u603b\u8ddd\u79bb\uff08ft\uff09\uff1a\" , traceDistance ) # \u8fd0\u884c\u7ed3\u679c\uff1a # \u8f93\u5165\u5c0f\u7403\u521d\u59cb\u9ad8\u5ea6\uff08ft\uff09\uff1a50 # \u8f93\u5165\u5141\u8bb8\u5c0f\u7403\u5f39\u8df3\u6b21\u6570\uff1a5 # \u5c0f\u7403\u7ecf\u8fc7\u7684\u603b\u8ddd\u79bb\uff08ft\uff09\uff1a 184.448 # \u8f93\u5165\u5c0f\u7403\u521d\u59cb\u9ad8\u5ea6\uff08ft\uff09\uff1a100 # \u8f93\u5165\u5141\u8bb8\u5c0f\u7403\u5f39\u8df3\u6b21\u6570\uff1a10 # \u5c0f\u7403\u7ecf\u8fc7\u7684\u603b\u8ddd\u79bb\uff08ft\uff09\uff1a 397.58135296000006 def calculate_total_distance ( initial_height , num_bounces ): rebound_factor = 0.6 total_distance = 0 height = initial_height for _ in range ( num_bounces + 1 ): total_distance += height height *= rebound_factor return total_distance def main (): try : initial_height = float ( input ( \"\u8bf7\u8f93\u5165\u7403\u7684\u521d\u59cb\u9ad8\u5ea6\uff08\u5355\u4f4d\uff1aft\uff09\uff1a\" )) num_bounces = int ( input ( \"\u8bf7\u8f93\u5165\u5141\u8bb8\u7403\u5f39\u8df3\u7684\u6b21\u6570\uff1a\" )) total_distance = calculate_total_distance ( initial_height , num_bounces ) print ( f \"\u7403\u6240\u7ecf\u8fc7\u7684\u603b\u8ddd\u79bb\u4e3a\uff1a { total_distance : .2f } ft\" ) except ValueError : print ( \"\u8bf7\u8f93\u5165\u6709\u6548\u7684\u6570\u5b57\uff01\" ) if __name__ == \"__main__\" : main () # \u8fd0\u884c\u7ed3\u679c\uff1a # \u8bf7\u8f93\u5165\u7403\u7684\u521d\u59cb\u9ad8\u5ea6\uff08\u5355\u4f4d\uff1aft\uff09\uff1a50 # \u8bf7\u8f93\u5165\u5141\u8bb8\u7403\u5f39\u8df3\u7684\u6b21\u6570\uff1a5 # \u7403\u6240\u7ecf\u8fc7\u7684\u603b\u8ddd\u79bb\u4e3a\uff1a119.17 ft # \u8bf7\u8f93\u5165\u7403\u7684\u521d\u59cb\u9ad8\u5ea6\uff08\u5355\u4f4d\uff1aft\uff09\uff1a100 # \u8bf7\u8f93\u5165\u5141\u8bb8\u7403\u5f39\u8df3\u7684\u6b21\u6570\uff1a10 # \u7403\u6240\u7ecf\u8fc7\u7684\u603b\u8ddd\u79bb\u4e3a\uff1a249.09 ft class BouncingBall : def __init__ ( self , initial_height , num_bounces ): self . initial_height = initial_height self . num_bounces = num_bounces self . rebound_factor = 0.6 def calculate_total_distance ( self ): total_distance = 0 height = self . initial_height for _ in range ( self . num_bounces + 1 ): total_distance += height height *= self . rebound_factor return total_distance def main (): try : initial_height = float ( input ( \"\u8bf7\u8f93\u5165\u7403\u7684\u521d\u59cb\u9ad8\u5ea6\uff08\u5355\u4f4d\uff1aft\uff09\uff1a\" )) num_bounces = int ( input ( \"\u8bf7\u8f93\u5165\u5141\u8bb8\u7403\u5f39\u8df3\u7684\u6b21\u6570\uff1a\" )) bouncing_ball = BouncingBall ( initial_height , num_bounces ) total_distance = bouncing_ball . calculate_total_distance () print ( f \"\u7403\u6240\u7ecf\u8fc7\u7684\u603b\u8ddd\u79bb\u4e3a\uff1a { total_distance : .2f } ft\" ) except ValueError : print ( \"\u8bf7\u8f93\u5165\u6709\u6548\u7684\u6570\u5b57\uff01\" ) if __name__ == \"__main__\" : main () 4\uff0e\u5fb7\u56fd\u6570\u5b66\u5bb6Gottfried Leibniz\u53d1\u660e\u4e86\u4e0b\u9762\u8fd9\u4e2a\u7528\u6765\u6c42\u03c0\u7684\u8fd1\u4f3c\u503c\u7684\u65b9\u6cd5\uff1a \u03c0/4 = 1 - 1/3 + 1/5 - 1/7 + ...... \uff0c\u8bf7\u7f16\u5199\u4e00\u4e2a\u7a0b\u5e8f\uff0c\u8ba9\u7528\u6237\u53ef\u4ee5\u6307\u5b9a\u8fd9\u4e2a\u8fd1\u4f3c\u503c\u6240\u4f7f\u7528\u7684\u8fed\u4ee3\u6b21\u6570\uff0c\u5e76\u4e14\u663e\u793a\u51fa\u7ed3\u679c\u3002 \u89e3\u7b54\uff1a n = int ( input ( \"\u8f93\u5165\u8fed\u4ee3\u6b21\u6570\uff1a\" )) mySum = 0 while n : mySum += 1 / ( 2 * n - 1 ) * (( - 1 ) ** ( n + 1 )) n -= 1 print ( \"\u03c0\u7684\u8fd1\u4f3c\u503c\u662f\uff1a\" , mySum * 4 ) # \u8fd0\u884c\u7ed3\u679c\uff1a # \u8f93\u5165\u8fed\u4ee3\u6b21\u6570\uff1a5 # \u03c0\u7684\u8fd1\u4f3c\u503c\u662f\uff1a 3.33968253968254 # \u8f93\u5165\u8fed\u4ee3\u6b21\u6570\uff1a10 # \u03c0\u7684\u8fd1\u4f3c\u503c\u662f\uff1a 3.0418396189294024 # \u8f93\u5165\u8fed\u4ee3\u6b21\u6570\uff1a20 # \u03c0\u7684\u8fd1\u4f3c\u503c\u662f\uff1a 3.0916238066678385 # \u8f93\u5165\u8fed\u4ee3\u6b21\u6570\uff1a10000000 # \u03c0\u7684\u8fd1\u4f3c\u503c\u662f\uff1a 3.1415925535897933 def calculate_pi_approximation ( iterations ): approximation = 0 sign = 1 for i in range ( 1 , iterations * 2 , 2 ): approximation += sign * ( 1 / i ) sign *= - 1 return approximation * 4 def main (): try : iterations = int ( input ( \"\u8bf7\u8f93\u5165\u8fed\u4ee3\u6b21\u6570\uff1a\" )) if iterations <= 0 : print ( \"\u8fed\u4ee3\u6b21\u6570\u5fc5\u987b\u4e3a\u6b63\u6574\u6570\uff01\" ) return pi_approximation = calculate_pi_approximation ( iterations ) print ( f \"\u03c0 \u7684\u8fd1\u4f3c\u503c\u4e3a\uff1a { pi_approximation : .10f } \" ) except ValueError : print ( \"\u8bf7\u8f93\u5165\u6709\u6548\u7684\u6574\u6570\uff01\" ) if __name__ == \"__main__\" : main () # \u8fd0\u884c\u7ed3\u679c\uff1a # \u8bf7\u8f93\u5165\u8fed\u4ee3\u6b21\u6570\uff1a5 # \u03c0 \u7684\u8fd1\u4f3c\u503c\u4e3a\uff1a3.3396825397 # \u8bf7\u8f93\u5165\u8fed\u4ee3\u6b21\u6570\uff1a10 # \u03c0 \u7684\u8fd1\u4f3c\u503c\u4e3a\uff1a3.0418396189 # \u8bf7\u8f93\u5165\u8fed\u4ee3\u6b21\u6570\uff1a20 # \u03c0 \u7684\u8fd1\u4f3c\u503c\u4e3a\uff1a3.0916238067 # \u8bf7\u8f93\u5165\u8fed\u4ee3\u6b21\u6570\uff1a10000000 # \u03c0 \u7684\u8fd1\u4f3c\u503c\u4e3a\uff1a3.1415925536 class PiApproximation : @classmethod def calculate_pi_approximation ( cls , iterations ): approximation = 0 sign = 1 for i in range ( 1 , iterations * 2 , 2 ): approximation += sign * ( 1 / i ) sign *= - 1 return approximation * 4 def main (): try : iterations = int ( input ( \"\u8bf7\u8f93\u5165\u8fed\u4ee3\u6b21\u6570\uff1a\" )) if iterations <= 0 : print ( \"\u8fed\u4ee3\u6b21\u6570\u5fc5\u987b\u4e3a\u6b63\u6574\u6570\uff01\" ) return pi_approximation = PiApproximation . calculate_pi_approximation ( iterations ) print ( f \"\u03c0 \u7684\u8fd1\u4f3c\u503c\u4e3a\uff1a { pi_approximation : .10f } \" ) except ValueError : print ( \"\u8bf7\u8f93\u5165\u6709\u6548\u7684\u6574\u6570\uff01\" ) if __name__ == \"__main__\" : main () # \u8fd0\u884c\u7ed3\u679c\uff1a # \u8f93\u5165\u8fed\u4ee3\u6b21\u6570\uff1a5 # \u03c0 \u7684\u8fd1\u4f3c\u503c\u4e3a\uff1a3.3396825397 # \u8bf7\u8f93\u5165\u8fed\u4ee3\u6b21\u6570\uff1a10 # \u03c0 \u7684\u8fd1\u4f3c\u503c\u4e3a\uff1a3.0418396189 # \u8bf7\u8f93\u5165\u8fed\u4ee3\u6b21\u6570\uff1a20 # \u03c0 \u7684\u8fd1\u4f3c\u503c\u4e3a\uff1a3.0916238067 # \u8bf7\u8f93\u5165\u8fed\u4ee3\u6b21\u6570\uff1a10000000 # \u03c0 \u7684\u8fd1\u4f3c\u503c\u4e3a\uff1a3.1415925536 5\uff0e\u67d0\u8ba1\u7b97\u673a\u5546\u5e97\u6709\u8d2d\u4e70\u8ba1\u7b97\u673a\u7684\u4fe1\u8d37\u8ba1\u5212\uff1a\u9996\u4ed810%\uff0c\u5e74\u5229\u7387\u4e3a12%\uff0c\u6bcf\u6708\u6240\u4ed8\u6b3e\u4e3a\u8d2d\u4e70\u4ef7\u683c\u51cf\u53bb\u9996\u4ed8\u4e4b\u540e\u76845%\u3002\u7f16\u5199\u4e00\u4e2a\u4ee5\u8d2d\u4e70\u4ef7\u683c\u4e3a\u8f93\u5165\u7684\u7a0b\u5e8f\uff0c\u53ef\u4ee5\u8f93\u51fa\u4e00\u4e2a\u6709\u9002\u5f53\u6807\u9898\u7684\u8868\u683c\uff0c\u663e\u793a\u8d37\u6b3e\u671f\u9650\u5185\u7684\u4ed8\u6b3e\u8ba1\u5212\u3002\u8868\u7684\u6bcf\u4e00\u884c\u90fd\u5e94\u5305\u542b\u4e0b\u9762\u5404\u9879\uff1a \u6708\u6570\uff08\u4ee51\u5f00\u5934\uff09\uff1b \u5f53\u524d\u6240\u6b20\u7684\u4f59\u989d\uff1b \u5f53\u6708\u6240\u6b20\u7684\u5229\u606f\uff1b \u5f53\u6708\u6240\u6b20\u7684\u672c\u91d1\uff1b \u5f53\u6708\u6240\u9700\u4ed8\u6b3e\u91d1\u989d\uff1b \u4ed8\u6b3e\u4e4b\u540e\u6240\u6b20\u7684\u91d1\u989d\u3002 \u4e00\u4e2a\u6708\u7684\u5229\u606f\u7b49\u4e8e\u4f59\u989d \u00d7 \u5229\u7387/12\uff1b\u4e00\u4e2a\u6708\u6240\u6b20\u7684\u672c\u91d1\u7b49\u4e8e\u5f53\u6708\u8fd8\u6b3e\u989d\u51cf\u53bb\u6240\u6b20\u7684\u5229\u606f\u3002 \u89e3\u7b54\uff1a def calculate_payment_schedule ( purchase_price ): down_payment = purchase_price * 0.1 loan_balance = purchase_price - down_payment annual_interest_rate = 0.12 monthly_interest_rate = annual_interest_rate / 12 monthly_payment = ( purchase_price - down_payment ) * 0.05 payment_schedule = [] for month in range ( 1 , 13 ): interest = loan_balance * monthly_interest_rate principal = monthly_payment - interest loan_balance -= principal payment_schedule . append (( month , loan_balance , interest , principal , monthly_payment , loan_balance + monthly_payment )) return payment_schedule def main (): try : purchase_price = float ( input ( \"\u8bf7\u8f93\u5165\u8d2d\u4e70\u4ef7\u683c\uff1a\" )) payment_schedule = calculate_payment_schedule ( purchase_price ) print ( \" {:<10} {:<15} {:<15} {:<15} {:<15} {:<15} \" . format ( \"\u6708\u6570\" , \"\u5f53\u524d\u6240\u6b20\u7684\u4f59\u989d\" , \"\u5f53\u6708\u6240\u6b20\u7684\u5229\u606f\" , \"\u5f53\u6708\u6240\u6b20\u7684\u672c\u91d1\" , \"\u5f53\u6708\u6240\u9700\u4ed8\u6b3e\u91d1\u989d\" , \"\u4ed8\u6b3e\u4e4b\u540e\u6240\u6b20\u7684\u91d1\u989d\" )) for payment in payment_schedule : month , balance , interest , principal , monthly_payment , new_balance = payment print ( \" {:<10} {:<15.2f} {:<15.2f} {:<15.2f} {:<15.2f} {:<15.2f} \" . format ( month , balance , interest , principal , monthly_payment , new_balance )) except ValueError : print ( \"\u8bf7\u8f93\u5165\u6709\u6548\u7684\u6570\u5b57\uff01\" ) if __name__ == \"__main__\" : main () # \u8fd0\u884c\u7ed3\u679c\uff1a # \u8bf7\u8f93\u5165\u8d2d\u4e70\u4ef7\u683c\uff1a5000 # \u6708\u6570 \u5f53\u524d\u6240\u6b20\u7684\u4f59\u989d \u5f53\u6708\u6240\u6b20\u7684\u5229\u606f \u5f53\u6708\u6240\u6b20\u7684\u672c\u91d1 \u5f53\u6708\u6240\u9700\u4ed8\u6b3e\u91d1\u989d \u4ed8\u6b3e\u4e4b\u540e\u6240\u6b20\u7684\u91d1\u989d # 1 4320.00 45.00 180.00 225.00 4545.00 # 2 4138.20 43.20 181.80 225.00 4363.20 # 3 3954.58 41.38 183.62 225.00 4179.58 # 4 3769.13 39.55 185.45 225.00 3994.13 # 5 3581.82 37.69 187.31 225.00 3806.82 # 6 3392.64 35.82 189.18 225.00 3617.64 # 7 3201.56 33.93 191.07 225.00 3426.56 # 8 3008.58 32.02 192.98 225.00 3233.58 # 9 2813.67 30.09 194.91 225.00 3038.67 # 10 2616.80 28.14 196.86 225.00 2841.80 # 11 2417.97 26.17 198.83 225.00 2642.97 # 12 2217.15 24.18 200.82 225.00 2442.15 class PaymentSchedule : def __init__ ( self , purchase_price ): self . purchase_price = purchase_price self . down_payment = purchase_price * 0.1 self . loan_balance = purchase_price - self . down_payment self . annual_interest_rate = 0.12 self . monthly_interest_rate = self . annual_interest_rate / 12 self . monthly_payment = ( purchase_price - self . down_payment ) * 0.05 def calculate_schedule ( self ): payment_schedule = [] for month in range ( 1 , 13 ): interest = self . loan_balance * self . monthly_interest_rate principal = self . monthly_payment - interest self . loan_balance -= principal payment_schedule . append (( month , self . loan_balance , interest , principal , self . monthly_payment , self . loan_balance + self . monthly_payment )) return payment_schedule def print_schedule_table ( self ): payment_schedule = self . calculate_schedule () print ( \" {:<10} {:<15} {:<15} {:<15} {:<15} {:<15} \" . format ( \"\u6708\u6570\" , \"\u5f53\u524d\u6240\u6b20\u7684\u4f59\u989d\" , \"\u5f53\u6708\u6240\u6b20\u7684\u5229\u606f\" , \"\u5f53\u6708\u6240\u6b20\u7684\u672c\u91d1\" , \"\u5f53\u6708\u6240\u9700\u4ed8\u6b3e\u91d1\u989d\" , \"\u4ed8\u6b3e\u4e4b\u540e\u6240\u6b20\u7684\u91d1\u989d\" )) for payment in payment_schedule : month , balance , interest , principal , monthly_payment , new_balance = payment print ( \" {:<10} {:<15.2f} {:<15.2f} {:<15.2f} {:<15.2f} {:<15.2f} \" . format ( month , balance , interest , principal , monthly_payment , new_balance )) def main (): try : purchase_price = float ( input ( \"\u8bf7\u8f93\u5165\u8d2d\u4e70\u4ef7\u683c\uff1a\" )) payment_schedule = PaymentSchedule ( purchase_price ) payment_schedule . print_schedule_table () except ValueError : print ( \"\u8bf7\u8f93\u5165\u6709\u6548\u7684\u6570\u5b57\uff01\" ) if __name__ == \"__main__\" : main () # \u8fd0\u884c\u7ed3\u679c # \u8bf7\u8f93\u5165\u8d2d\u4e70\u4ef7\u683c\uff1a5000 # \u6708\u6570 \u5f53\u524d\u6240\u6b20\u7684\u4f59\u989d \u5f53\u6708\u6240\u6b20\u7684\u5229\u606f \u5f53\u6708\u6240\u6b20\u7684\u672c\u91d1 \u5f53\u6708\u6240\u9700\u4ed8\u6b3e\u91d1\u989d \u4ed8\u6b3e\u4e4b\u540e\u6240\u6b20\u7684\u91d1\u989d # 1 4320.00 45.00 180.00 225.00 4545.00 # 2 4138.20 43.20 181.80 225.00 4363.20 # 3 3954.58 41.38 183.62 225.00 4179.58 # 4 3769.13 39.55 185.45 225.00 3994.13 # 5 3581.82 37.69 187.31 225.00 3806.82 # 6 3392.64 35.82 189.18 225.00 3617.64 # 7 3201.56 33.93 191.07 225.00 3426.56 # 8 3008.58 32.02 192.98 225.00 3233.58 # 9 2813.67 30.09 194.91 225.00 3038.67 # 10 2616.80 28.14 196.86 225.00 2841.80 # 11 2417.97 26.17 198.83 225.00 2642.97 # 12 2217.15 24.18 200.82 225.00 2442.15 6\uff0e\u8d22\u52a1\u90e8\u95e8\u5728\u6587\u672c\u6587\u4ef6\u91cc\u4fdd\u5b58\u4e86\u6240\u6709\u5458\u5de5\u5728\u6bcf\u4e2a\u5de5\u8d44\u5468\u671f\u91cc\u7684\u4fe1\u606f\u5217\u8868\u3002\u6587\u4ef6\u4e2d\u6bcf\u4e00\u884c\u7684\u683c\u5f0f\u4e3a \u3002\u8bf7\u7f16\u5199\u4e00\u4e2a\u7a0b\u5e8f\uff0c\u8ba9\u7528\u6237\u53ef\u4ee5\u8f93\u5165\u6587\u4ef6\u7684\u540d\u79f0\uff0c\u5e76\u5728\u7ec8\u7aef\u4e0a\u6253\u5370\u51fa\u7ed9\u5b9a\u65f6\u95f4\u5185\u652f\u4ed8\u7ed9\u6bcf\u4e2a\u5458\u5de5\u7684\u5de5\u8d44\u62a5\u544a\u3002\u8fd9\u4e2a\u62a5\u544a\u662f\u4e00\u4e2a\u6709\u5408\u9002\u6807\u9898\u7684\u8868\uff0c\u5176\u4e2d\u6bcf\u884c\u90fd\u5e94\u8be5\u5305\u542b\u5458\u5de5\u7684\u59d3\u540d\u3001\u5de5\u4f5c\u65f6\u957f\u4ee5\u53ca\u7ed9\u5b9a\u65f6\u95f4\u5185\u6240\u652f\u4ed8\u7684\u5de5\u8d44\u3002 \u89e3\u7b54\uff1a # \u7a0b\u5e8f\u4f1a\u63d0\u793a\u7528\u6237\u8f93\u5165\u6587\u4ef6\u540d\uff0c\u7136\u540e\u8bfb\u53d6\u6587\u4ef6\u4e2d\u7684\u5458\u5de5\u4fe1\u606f\uff0c\u8ba1\u7b97\u5de5\u8d44\u62a5\u544a\uff0c\u5e76\u6253\u5370\u51fa\u5458\u5de5\u7684\u59d3\u540d\u3001\u5de5\u4f5c\u65f6\u957f\u548c\u652f\u4ed8\u5de5\u8d44\u3002\u6ce8\u610f\uff0c\u7a0b\u5e8f\u4f1a\u68c0\u67e5\u6587\u4ef6\u662f\u5426\u5b58\u5728\uff0c\u5e76\u4f1a\u5bf9\u6587\u4ef6\u4e2d\u7684\u6bcf\u884c\u6570\u636e\u8fdb\u884c\u5904\u7406\u4ee5\u786e\u4fdd\u6b63\u786e\u89e3\u6790\u3002 class Employee : def __init__ ( self , last_name , hourly_wage , hours_worked ): self . last_name = last_name self . hourly_wage = float ( hourly_wage ) self . hours_worked = float ( hours_worked ) def calculate_salary ( self ): return self . hourly_wage * self . hours_worked def main (): try : filename = input ( \"\u8bf7\u8f93\u5165\u6587\u4ef6\u540d\uff1a\" ) with open ( filename , 'r' ) as file : employees = [] for line in file : parts = line . strip () . split () if len ( parts ) == 3 : last_name , hourly_wage , hours_worked = parts employee = Employee ( last_name , hourly_wage , hours_worked ) employees . append ( employee ) print ( \" {:<20} {:<15} {:<15} \" . format ( \"\u5458\u5de5\u59d3\u540d\" , \"\u5de5\u4f5c\u65f6\u957f\" , \"\u652f\u4ed8\u5de5\u8d44\" )) print ( \"=\" * 50 ) total_salary = 0 for employee in employees : salary = employee . calculate_salary () total_salary += salary print ( \" {:<20} {:<15.2f} {:<15.2f} \" . format ( employee . last_name , employee . hours_worked , salary )) print ( \"=\" * 50 ) print ( f \"\u603b\u652f\u4ed8\u5de5\u8d44\uff1a { total_salary : .2f } \" ) except FileNotFoundError : print ( \"\u6587\u4ef6\u4e0d\u5b58\u5728\uff01\" ) if __name__ == \"__main__\" : main () 7\uff0e\u7edf\u8ba1\u5b66\u5bb6\u5e0c\u671b\u4f7f\u7528\u4e00\u7ec4\u51fd\u6570\u8ba1\u7b97\u6570\u5b57\u5217\u8868\u7684\u4e2d\u4f4d\u6570\uff08median\uff09\u548c\u4f17\u6570\uff08mode\uff09\u3002\u4e2d\u4f4d\u6570\u662f\u6307\u5982\u679c\u5bf9\u5217\u8868\u8fdb\u884c\u6392\u5e8f\u5c06\u4f1a\u51fa\u73b0\u5728\u5217\u8868\u4e2d\u70b9\u7684\u6570\u5b57\uff0c\u4f17\u6570\u662f\u6307\u5217\u8868\u4e2d\u6700\u5e38\u51fa\u73b0\u7684\u6570\u5b57\u3002\u628a\u8fd9\u4e9b\u529f\u80fd\u5b9a\u4e49\u5728\u540d\u53ebstats.py\u7684\u6a21\u5757\u4e2d\u3002\u9664\u6b64\u4e4b\u5916\uff0c\u6a21\u5757\u8fd8\u5e94\u8be5\u5305\u542b\u4e00\u4e2a\u540d\u53ebmean\u7684\u51fd\u6570\uff0c\u7528\u6765\u8ba1\u7b97\u4e00\u7ec4\u6570\u5b57\u7684\u5e73\u5747\u503c\u3002\u6bcf\u4e2a\u51fd\u6570\u90fd\u4f1a\u63a5\u6536\u4e00\u4e2a\u6570\u5b57\u5217\u8868\u4f5c\u4e3a\u53c2\u6570\uff0c\u5e76\u8fd4\u56de\u4e00\u4e2a\u6570\u5b57\u3002 \u89e3\u7b54\uff1a def median ( numbers ): sorted_numbers = sorted ( numbers ) length = len ( sorted_numbers ) if length % 2 == 1 : return sorted_numbers [ length // 2 ] else : mid1 = sorted_numbers [ length // 2 - 1 ] mid2 = sorted_numbers [ length // 2 ] return ( mid1 + mid2 ) / 2 def mode ( numbers ): from collections import Counter counter = Counter ( numbers ) mode_list = counter . most_common () max_count = mode_list [ 0 ][ 1 ] modes = [ num for num , count in mode_list if count == max_count ] return modes def mean ( numbers ): total = sum ( numbers ) count = len ( numbers ) return total / count if __name__ == \"__main__\" : test_numbers = [ 4 , 2 , 7 , 2 , 1 , 9 , 4 , 7 ] print ( \"\u4e2d\u4f4d\u6570:\" , median ( test_numbers )) print ( \"\u4f17\u6570:\" , mode ( test_numbers )) print ( \"\u5e73\u5747\u503c:\" , mean ( test_numbers )) class Stats : @staticmethod def median ( numbers ): sorted_numbers = sorted ( numbers ) length = len ( sorted_numbers ) if length % 2 == 1 : return sorted_numbers [ length // 2 ] else : mid1 = sorted_numbers [ length // 2 - 1 ] mid2 = sorted_numbers [ length // 2 ] return ( mid1 + mid2 ) / 2 @staticmethod def mode ( numbers ): from collections import Counter counter = Counter ( numbers ) mode_list = counter . most_common () max_count = mode_list [ 0 ][ 1 ] modes = [ num for num , count in mode_list if count == max_count ] return modes @staticmethod def mean ( numbers ): total = sum ( numbers ) count = len ( numbers ) return total / count if __name__ == \"__main__\" : test_numbers = [ 4 , 2 , 7 , 2 , 1 , 9 , 4 , 7 ] print ( \"\u4e2d\u4f4d\u6570:\" , Stats . median ( test_numbers )) print ( \"\u4f17\u6570:\" , Stats . mode ( test_numbers )) print ( \"\u5e73\u5747\u503c:\" , Stats . mean ( test_numbers )) 8\uff0e\u7f16\u5199\u7a0b\u5e8f\uff0c\u8ba9\u7528\u6237\u53ef\u4ee5\u6d4f\u89c8\u6587\u4ef6\u91cc\u7684\u6587\u672c\u884c\u3002\u8fd9\u4e2a\u7a0b\u5e8f\u4f1a\u63d0\u793a\u7528\u6237\u8f93\u5165\u6587\u4ef6\u540d\uff0c\u7136\u540e\u628a\u6587\u672c\u884c\u90fd\u8f93\u5165\u5217\u8868\u3002\u63a5\u4e0b\u6765\uff0c\u8fd9\u4e2a\u7a0b\u5e8f\u4f1a\u8fdb\u5165\u4e00\u4e2a\u5faa\u73af\uff0c\u5728\u8fd9\u4e2a\u5faa\u73af\u91cc\u6253\u5370\u51fa\u6587\u4ef6\u7684\u603b\u884c\u6570\uff0c\u5e76\u63d0\u793a\u7528\u6237\u8f93\u5165\u884c\u53f7\u3002\u8fd9\u4e2a\u884c\u53f7\u7684\u8303\u56f4\u5e94\u5f53\u662f1\u5230\u6587\u4ef6\u7684\u603b\u884c\u6570\u3002\u5982\u679c\u8f93\u5165\u662f0\uff0c\u90a3\u4e48\u7a0b\u5e8f\u9000\u51fa\uff1b\u5426\u5219\uff0c\u7a0b\u5e8f\u5c06\u6253\u5370\u51fa\u884c\u53f7\u6240\u5bf9\u5e94\u7684\u6587\u672c\u884c\u3002 def read_file_lines ( filename ): try : with open ( filename , 'r' ) as file : lines = file . readlines () return lines except FileNotFoundError : print ( \"\u6587\u4ef6\u4e0d\u5b58\u5728\uff01\" ) return [] def main (): filename = input ( \"\u8bf7\u8f93\u5165\u6587\u4ef6\u540d\uff1a\" ) lines = read_file_lines ( filename ) if not lines : return total_lines = len ( lines ) while True : print ( f \"\u6587\u4ef6\u603b\u884c\u6570\uff1a { total_lines } \" ) try : line_number = int ( input ( \"\u8bf7\u8f93\u5165\u884c\u53f7\uff08\u8f93\u51650\u9000\u51fa\uff09\uff1a\" )) if line_number == 0 : break elif 1 <= line_number <= total_lines : print ( f \"\u884c\u53f7 { line_number } : { lines [ line_number - 1 ] . strip () } \" ) else : print ( \"\u65e0\u6548\u7684\u884c\u53f7\uff0c\u8bf7\u8f93\u5165\u6b63\u786e\u8303\u56f4\u5185\u7684\u884c\u53f7\uff01\" ) except ValueError : print ( \"\u8bf7\u8f93\u5165\u6709\u6548\u7684\u6570\u5b57\uff01\" ) if __name__ == \"__main__\" : main () class TextFileBrowser : @classmethod def read_file_lines ( cls , filename ): try : with open ( filename , 'r' ) as file : lines = file . readlines () return lines except FileNotFoundError : print ( \"\u6587\u4ef6\u4e0d\u5b58\u5728\uff01\" ) return [] @classmethod def browse_file ( cls , filename ): lines = cls . read_file_lines ( filename ) if not lines : return total_lines = len ( lines ) while True : print ( f \"\u6587\u4ef6\u603b\u884c\u6570\uff1a { total_lines } \" ) try : line_number = int ( input ( \"\u8bf7\u8f93\u5165\u884c\u53f7\uff08\u8f93\u51650\u9000\u51fa\uff09\uff1a\" )) if line_number == 0 : break elif 1 <= line_number <= total_lines : print ( f \"\u884c\u53f7 { line_number } : { lines [ line_number - 1 ] . strip () } \" ) else : print ( \"\u65e0\u6548\u7684\u884c\u53f7\uff0c\u8bf7\u8f93\u5165\u6b63\u786e\u8303\u56f4\u5185\u7684\u884c\u53f7\uff01\" ) except ValueError : print ( \"\u8bf7\u8f93\u5165\u6709\u6548\u7684\u6570\u5b57\uff01\" ) def main (): filename = input ( \"\u8bf7\u8f93\u5165\u6587\u4ef6\u540d\uff1a\" ) TextFileBrowser . browse_file ( filename ) if __name__ == \"__main__\" : main () 9\uff0e\u5728\u672c\u7ae0\u8ba8\u8bba\u7684numberguess\u7a0b\u5e8f\u91cc\uff0c\u8ba1\u7b97\u673a\u4f1a\u201c\u6784\u601d\u201d\u4e00\u4e2a\u6570\u5b57\uff0c\u800c\u7528\u6237\u5219\u8f93\u5165\u731c\u6d4b\u7684\u503c\uff0c\u76f4\u5230\u731c\u5bf9\u4e3a\u6b62\u3002\u7f16\u5199\u8fd9\u6837\u4e00\u4e2a\u7a0b\u5e8f\uff0c\u4f7f\u5176\u53ef\u4ee5\u8c03\u6362\u8fd9\u4e24\u4e2a\u89d2\u8272\uff0c\u4e5f\u5c31\u662f\uff1a\u7528\u6237\u53bb\u201c\u6784\u601d\u201d\u4e00\u4e2a\u6570\u5b57\uff0c\u7136\u540e\u8ba1\u7b97\u673a\u53bb\u8ba1\u7b97\u5e76\u8f93\u51fa\u731c\u6d4b\u7684\u503c\u3002\u548c\u524d\u9762\u90a3\u4e2a\u6e38\u620f\u7248\u672c\u4e00\u6837\uff0c\u5f53\u8ba1\u7b97\u673a\u731c\u9519\u65f6\uff0c\u7528\u6237\u5fc5\u987b\u7ed9\u51fa\u76f8\u5e94\u7684\u63d0\u793a\uff0c\u4f8b\u5982\u201c<\u201d\u548c\u201c>\u201d\uff08\u5206\u522b\u4ee3\u8868\u201c\u6211\u7684\u6570\u5b57\u66f4\u5c0f\u201d\u548c\u201c\u6211\u7684\u6570\u5b57\u66f4\u5927\u201d\uff09\u3002\u5f53\u8ba1\u7b97\u673a\u731c\u5bf9\u65f6\uff0c\u7528\u6237\u5e94\u8be5\u8f93\u5165\u201c=\u201d\u3002\u7528\u6237\u9700\u8981\u5728\u7a0b\u5e8f\u542f\u52a8\u7684\u65f6\u5019\u8f93\u5165\u6570\u5b57\u7684\u4e0b\u9650\u548c\u4e0a\u9650\u3002\u8ba1\u7b97\u673a\u5e94\u8be5\u5728\u6700\u591a [log2(high\u2212low)+1] \u6b21\u731c\u6d4b\u91cc\u627e\u5230\u6b63\u786e\u7684\u6570\u5b57\u3002\u7a0b\u5e8f\u5e94\u8be5\u80fd\u591f\u8ddf\u8e2a\u731c\u6d4b\u6b21\u6570\uff0c\u5982\u679c\u731c\u6d4b\u9519\u8bef\u7684\u6b21\u6570\u5230\u4e86\u5141\u8bb8\u731c\u6d4b\u7684\u6700\u5927\u503c\u4f46\u8fd8\u6ca1\u6709\u731c\u5bf9\uff0c\u5c31\u8f93\u51fa\u6d88\u606f\u201cYou're cheating\uff01\u201d\u3002\u4e0b\u9762\u662f\u548c\u8fd9\u4e2a\u7a0b\u5e8f\u8fdb\u884c\u4ea4\u4e92\u7684\u793a\u4f8b\uff1a Enter the smaller number : 1 Enter the larger number : 100 Your number is 50 Enter = , < , or > : > Your number is 75 Enter = , < , or > : < Your number is 62 Enter = , < , or > : < Your number is 56 Enter = , < , or > : = Hooray , I 've got it in 4 tries! import math class ComputerGuesser : def __init__ ( self , lower_limit , upper_limit ): self . lower_limit = lower_limit self . upper_limit = upper_limit self . max_attempts = math . floor ( math . log2 ( upper_limit - lower_limit + 1 )) + 1 self . attempts = 0 def guess ( self ): return ( self . lower_limit + self . upper_limit ) // 2 def play ( self ): print ( f \"\u8bf7\u4f60\u9009\u62e9\u4e00\u4e2a\u5728 { self . lower_limit } \u5230 { self . upper_limit } \u4e4b\u95f4\u7684\u6570\u5b57\u3002\" ) while self . attempts < self . max_attempts : guess = self . guess () print ( f \"\u6211\u7684\u731c\u6d4b\u662f\uff1a { guess } \" ) response = input ( \"\u8bf7\u8f93\u5165 =, <, \u6216 > \u6765\u6307\u793a\u662f\u5426\u731c\u5bf9\uff1a\" ) self . attempts += 1 if response == '=' : print ( f \"\u6211\u5728\u7b2c { self . attempts } \u6b21\u731c\u5bf9\u4e86\uff01\" ) break elif response == '<' : self . upper_limit = guess - 1 elif response == '>' : self . lower_limit = guess + 1 else : print ( \"\u8bf7\u8f93\u5165\u6709\u6548\u7684\u64cd\u4f5c\u7b26\uff1a=, <, \u6216 >\" ) if self . attempts >= self . max_attempts : print ( \"\u4f60\u5728\u6b3a\u9a97\u6211\uff01\" ) def main (): lower_limit = int ( input ( \"\u8bf7\u8f93\u5165\u8f83\u5c0f\u7684\u6570\u5b57\uff1a\" )) upper_limit = int ( input ( \"\u8bf7\u8f93\u5165\u8f83\u5927\u7684\u6570\u5b57\uff1a\" )) guesser = ComputerGuesser ( lower_limit , upper_limit ) guesser . play () if __name__ == \"__main__\" : main () import math class ComputerGuesser : def __init__ ( self , lower_limit , upper_limit ): self . lower_limit = lower_limit self . upper_limit = upper_limit self . max_attempts = math . floor ( math . log2 ( upper_limit - lower_limit + 1 )) + 1 self . attempts = 0 @classmethod def guess ( cls , lower_limit , upper_limit ): return ( lower_limit + upper_limit ) // 2 @classmethod def play ( cls , lower_limit , upper_limit ): print ( f \"\u8bf7\u4f60\u9009\u62e9\u4e00\u4e2a\u5728 { lower_limit } \u5230 { upper_limit } \u4e4b\u95f4\u7684\u6570\u5b57\u3002\" ) attempts = 0 while attempts < cls . max_attempts : guess = cls . guess ( lower_limit , upper_limit ) print ( f \"\u6211\u7684\u731c\u6d4b\u662f\uff1a { guess } \" ) response = input ( \"\u8bf7\u8f93\u5165 =, <, \u6216 > \u6765\u6307\u793a\u662f\u5426\u731c\u5bf9\uff1a\" ) attempts += 1 if response == '=' : print ( f \"\u6211\u5728\u7b2c { attempts } \u6b21\u731c\u5bf9\u4e86\uff01\" ) break elif response == '<' : upper_limit = guess - 1 elif response == '>' : lower_limit = guess + 1 else : print ( \"\u8bf7\u8f93\u5165\u6709\u6548\u7684\u64cd\u4f5c\u7b26\uff1a=, <, \u6216 >\" ) if attempts >= cls . max_attempts : print ( \"\u4f60\u5728\u6b3a\u9a97\u6211\uff01\" ) def main (): lower_limit = int ( input ( \"\u8bf7\u8f93\u5165\u8f83\u5c0f\u7684\u6570\u5b57\uff1a\" )) upper_limit = int ( input ( \"\u8bf7\u8f93\u5165\u8f83\u5927\u7684\u6570\u5b57\uff1a\" )) ComputerGuesser . play ( lower_limit , upper_limit ) if __name__ == \"__main__\" : main () 10\uff0e\u6709\u4e00\u4e2a\u7b80\u5355\u7684\u8bfe\u7a0b\u7ba1\u7406\u7cfb\u7edf\uff0c\u5b83\u901a\u8fc7\u4f7f\u7528\u540d\u5b57\u548c\u4e00\u7ec4\u8003\u8bd5\u5206\u6570\u6765\u6a21\u62df\u5b66\u751f\u7684\u4fe1\u606f\u3002\u8fd9\u4e2a\u7cfb\u7edf\u5e94\u8be5\u80fd\u591f\u521b\u5efa\u4e00\u4e2a\u5177\u6709\u7ed9\u5b9a\u540d\u5b57\u548c\u5206\u6570\uff08\u8d77\u521d\u5747\u4e3a0\uff09\u7684\u5b66\u751f\u5bf9\u8c61\u3002\u7cfb\u7edf\u5e94\u8be5\u80fd\u591f\u8bbf\u95ee\u548c\u66ff\u6362\u6307\u5b9a\u4f4d\u7f6e\u5904\u7684\u5206\u6570\uff08\u4ece0\u5f00\u59cb\u8ba1\u6570\uff09\u3001\u5f97\u5230\u5b66\u751f\u6709\u591a\u5c11\u6b21\u8003\u8bd5\u3001\u5f97\u5230\u7684\u6700\u9ad8\u5206\u3001\u5f97\u5230\u7684\u5e73\u5747\u5206\u4ee5\u53ca\u5b66\u751f\u7684\u59d3\u540d\u3002\u9664\u6b64\u4e4b\u5916\uff0c\u5728\u6253\u5370\u5b66\u751f\u5bf9\u8c61\u7684\u65f6\u5019\uff0c\u5e94\u8be5\u50cf\u4e0b\u9762\u8fd9\u6837\u663e\u793a\u5b66\u751f\u7684\u59d3\u540d\u548c\u5206\u6570\uff1a Name : Ken Lambert Score 1 : 88 Score 2 : 77 Score 3 : 100 \u8bf7\u5b9a\u4e49\u4e00\u4e2a\u652f\u6301\u8fd9\u4e9b\u529f\u80fd\u548c\u884c\u4e3a\u7684Student\u7c7b\uff0c\u5e76\u4e14\u7f16\u5199\u4e00\u4e2a\u521b\u5efaStudent\u5bf9\u8c61\u5e76\u8fd0\u884c\u5176\u65b9\u6cd5\u7684\u7b80\u77ed\u7684\u6d4b\u8bd5\u51fd\u6570\u3002 class Student : def __init__ ( self , name ): self . name = name self . scores = [] def add_score ( self , score ): self . scores . append ( score ) def replace_score ( self , index , score ): if 0 <= index < len ( self . scores ): self . scores [ index ] = score else : print ( \"\u65e0\u6548\u7684\u5206\u6570\u7d22\u5f15\" ) def num_scores ( self ): return len ( self . scores ) def highest_score ( self ): if self . scores : return max ( self . scores ) else : return None def average_score ( self ): if self . scores : return sum ( self . scores ) / len ( self . scores ) else : return None def display ( self ): print ( f \"Name: { self . name } \" ) for i , score in enumerate ( self . scores , start = 1 ): print ( f \"Score { i } : { score } \" ) def test_student_class (): student = Student ( \"Ken Lambert\" ) student . add_score ( 88 ) student . add_score ( 77 ) student . add_score ( 100 ) student . display () print ( f \"Total Scores: { student . num_scores () } \" ) print ( f \"Highest Score: { student . highest_score () } \" ) print ( f \"Average Score: { student . average_score () } \" ) if __name__ == \"__main__\" : test_student_class ()","title":"\u57fa\u7840\u77e5\u8bc6\u56de\u987e"},{"location":"python/DataStructure/01_PythonFundmantal/#1","text":"","title":"1.\u57fa\u7840\u77e5\u8bc6\u56de\u987e"},{"location":"python/DataStructure/01_PythonFundmantal/#11","text":"\u793a\u4f8b\u4ee3\u7801 numberguess.py \u3002 import random def main (): smaller = int ( input ( \"\u8f93\u5165\u6700\u5c0f\u503c: \" )) larger = int ( input ( \"\u8f93\u5165\u6700\u5927\u503c: \" )) myNumber = random . randint ( smaller , larger ) count = 0 while True : count += 1 userNumber = int ( input ( \"\u8f93\u5165\u4f60\u731c\u7684\u503c: \" )) if userNumber < myNumber : print ( \"\u4f60\u731c\u7684\u592a\u5c0f\uff01\" ) elif userNumber > myNumber : print ( \"\u4f60\u731c\u7684\u592a\u5927\uff01\" ) else : print ( \"\u606d\u559c\uff0c\u4f60\u5728\u7b2c\" , count , \"\u6b21\u731c\u5bf9\u4e86!\" ) break if __name__ == \"__main__\" : main () \u8fd0\u884c\u4ee3\u7801\uff1a $ python3 numberguess.py Enter the smaller number: 10 Enter the larger number: 60 Enter your guess: 50 Too large Enter your guess: 40 Too large Enter your guess: 30 Too large Enter your guess: 20 Too large Enter your guess: 10 Too small Enter your guess: 15 You\u2019ve got it in 6 tries!","title":"1.1.\u57fa\u672c\u7a0b\u5e8f\u8981\u7d20"},{"location":"python/DataStructure/01_PythonFundmantal/#111","text":"\u53d8\u91cf\uff1asalary\uff0choursWorked\uff0cisAbsent \u5e38\u6570\uff1aABSOLUTE_ZERO\uff0cINTEREST_RATE \u51fd\u6570\u6216\u65b9\u6cd5\uff1aprintResults\uff0ccubeRoot\uff0cinput \u7c7b\uff1aBankAccount\uff0cSortedSet \u901a\u5e38\u7ea6\u5b9a\uff1a\u53d8\u91cf\u540d\u662f\u540d\u8bcd\u3001\u5f62\u5bb9\u8bcd\uff08\u5e03\u5c14\u503c\uff09\uff0c\u51fd\u6570\u548c\u65b9\u6cd5\u662f\u52a8\u8bcd\uff08\u8868\u793a\u52a8\u4f5c\uff09\u3001\u540d\u8bcd\u3001\u6216\u5f62\u5bb9\u8bcd\uff08\u8868\u793a\u8fd4\u56de\u7684\u503c\uff09\u3002 \u8bed\u6cd5\u5143\u7d20\uff1a Python\u4f7f\u7528\u7a7a\u767d\u7b26\uff08\u7a7a\u683c\u3001\u5236\u8868\u7b26\u3001\u6216\u6362\u884c\u7b26\uff09\u6765\u8868\u793a\u4e0d\u540c\u7c7b\u578b\u7684\u8bed\u53e5\u7684\u8bed\u6cd5\u3002 \u901a\u5e38\u7ea6\u5b9a\u4f7f\u75284\u4e2a\u7a7a\u683c\u4f5c\u4e3a\u9501\u8fdb\u5bbd\u5ea6\u3002","title":"1.1.1.\u62fc\u5199\u548c\u547d\u540d\u60ef\u4f8b"},{"location":"python/DataStructure/01_PythonFundmantal/#112","text":"\u5355\u5f15\u53f7 \u53cc\u5f15\u53f7 \u6210\u5bf9\u7684\u4e09\u4e2a\u53cc\u5f15\u53f7\uff08\u591a\u884c\u6587\u672c\uff09 \u6210\u5bf9\u7684\u4e09\u4e2a\u5355\u5f15\u53f7\uff08\u591a\u884c\u6587\u672c\uff09 \u8f6c\u4e49\u5b57\u7b26 \\ \uff08\u53cd\u659c\u6760\uff09","title":"1.1.2.\u5b57\u7b26\u4e32"},{"location":"python/DataStructure/01_PythonFundmantal/#113","text":"\u6807\u51c6\u8fd0\u7b97\u7b26\uff1a + \u3001 - \u3001 * \u3001 / \u3001 % \u7b97\u672f\u8868\u8fbe\u5f0f\u662f\u7528\u6807\u51c6\u8fd0\u7b97\u7b26\u548c\u4e2d\u7f00\u8868\u793a\u6cd5 \u6bd4\u8f83\u8fd0\u7b97\u7b26\uff1a < \u3001 <= \u3001 > \u3001 >= \u3001 == \u3001 != \uff0c\u7528\u4e8e\u6bd4\u8f83\u6570\u5b57\u6216\u5b57\u7b26\u4e32\uff0c\u8fd4\u56deTrue\u6216False \u8fd0\u7b97\u7b26 == \u7528\u4e8e\u6bd4\u8f83\u6570\u636e\u7ed3\u6784\u91cc\u7684\u5185\u5bb9\uff0c\u8fd0\u7b97\u7b26 is \u7528\u4e8e\u6bd4\u8f83\u4e24\u4e2a\u5bf9\u8c61\u7684\u6807\u8bc6\u662f\u5426\u4e00\u81f4 \u903b\u8f91\u8fd0\u7b97\u7b26\uff1a and \u3001 or \u3001 not \u3002\u628a0\u3001None\u3001\u7a7a\u5b57\u7b26\u4e32\u3001\u7a7a\u5217\u8868\u7b49\u89c6\u4e3aFalse\uff0c\u5927\u591a\u6570\u5176\u4ed6\u503c\u662f\u4e3aTrue \u4e0b\u6807\u8fd0\u7b97\u7b26\uff1a [] \uff0c\u4e0e\u591a\u9879\u96c6collection\u5bf9\u8c61\u4e00\u8d77\u4f7f\u7528 \u9009\u62e9\u5668\u8fd0\u7b97\u7b26\uff1a . \uff0c\u7528\u4e8e\u5f15\u7528\u4e00\u4e2a\u6a21\u5757\u3001\u7c7b\u6216\u5bf9\u8c61\u4e2d\u7684\u4e00\u4e2a\u5177\u540d\u7684\u9879 \u8fd0\u7b97\u7b26\u4f18\u5148\u7ea7\uff0c\u4f9d\u6b21\u662f\u9009\u62e9\u8fd0\u7b97\u7b26\u3001\u51fd\u6570\u8c03\u7528\u8fd0\u7b97\u7b26\u3001\u4e0b\u6807\u8fd0\u7b97\u7b26\u3001\u7b97\u672f\u8fd0\u7b97\u7b26\u3001\u6bd4\u8f83\u8fd0\u7b97\u7b26\u3001\u903b\u8f91\u8fd0\u7b97\u7b26\u3001\u8d4b\u503c\u8fd0\u7b97\u7b26\u3002\u62ec\u53f7\u7528\u4e8e\u8ba9\u5b50\u8868\u8fbe\u5f0f\u4f18\u5148\u8fd0\u884c\u3002","title":"1.1.3.\u8fd0\u7b97\u7b26\u548c\u8868\u8fbe\u5f0f"},{"location":"python/DataStructure/01_PythonFundmantal/#114","text":"\u51fd\u6570\u540d\u79f0\u540e\u9762\u8ddf\u7740\u7528\u62ec\u53f7\u62ec\u8d77\u6765\u7684\u53c2\u6570\u5217\u8868\uff0c\u4f8b\u5982\uff1a min(5,2) \u6807\u51c6\u51fd\u6570 \u5176\u4ed6\u6a21\u5757\u5bfc\u5165\u51fd\u6570","title":"1.1.4.\u51fd\u6570\u8c03\u7528"},{"location":"python/DataStructure/01_PythonFundmantal/#115print","text":"\u81ea\u52a8\u4e3a\u6bcf\u4e2a\u53c2\u6570\u8fd0\u884c str \u51fd\u6570\uff0c\u4ee5\u5f97\u5230\u5176\u5b57\u7b26\u4e32\u8868\u793a \u5728\u8f93\u51fa\u4e4b\u524d\u4f1a\u7528\u7a7a\u683c\u5427\u6bcf\u4e2a\u5b57\u7b26\u4e32\u9694\u5f00 \u9ed8\u8ba4\u4ee5\u6362\u884c\u7b26\u4f5c\u4e3a\u7ed3\u675f","title":"1.1.5.print\u51fd\u6570"},{"location":"python/DataStructure/01_PythonFundmantal/#116input","text":"\u6807\u51c6\u8f93\u5165\u51fd\u6570input\u4f1a\u4e00\u76f4\u7b49\u5f85\u7528\u6237\u901a\u8fc7\u952e\u76d8\u8f93\u5165\u6587\u672c \u63a5\u53d7\u4e00\u4e2a\u53ef\u9009\u7684\u5b57\u7b26\u4e32\u4f5c\u4e3a\u5176\u53c2\u6570","title":"1.1.6.input\u51fd\u6570"},{"location":"python/DataStructure/01_PythonFundmantal/#117","text":"Python\u5141\u8bb8\u7b97\u672f\u8868\u8fbe\u5f0f\u4e2d\u7684\u64cd\u4f5c\u6570\u5177\u6709\u4e0d\u540c\u7684\u6570\u503c\u7c7b\u578b\u3002\u4f8b\u5982\uff0c\u628aint\u7c7b\u578b\u7684\u64cd\u4f5c\u6570\u548cfloat\u7c7b\u578b\u7684\u64cd\u4f5c\u6570\u76f8\u52a0\uff0c\u4f1a\u5f97\u5230float\u7c7b\u578b\u7684\u6570\u3002 # \u8f93\u5165\u534a\u5f84\u6c42\u5706\u9762\u79ef radius = float ( input ( \"Radius: \" )) print ( \"The area is\" , 3.14 * radius ** 2 )","title":"1.1.7.\u7c7b\u578b\u8f6c\u6362\u51fd\u6570\u548c\u6df7\u5408\u6a21\u5f0f\u64cd\u4f5c"},{"location":"python/DataStructure/01_PythonFundmantal/#118","text":"\u5fc5\u9009\u53c2\u6570\u662f\u6ca1\u6709\u9ed8\u8ba4\u503c\u7684\uff1b\u53ef\u9009\u53c2\u6570\u6709\u9ed8\u8ba4\u503c\uff1b \u5728\u8c03\u7528\u51fd\u6570\u65f6\uff0c\u4f20\u9012\u7ed9\u5b83\u7684\u53c2\u6570\u6570\u91cf\u5fc5\u987b\u81f3\u5c11\u548c\u5fc5\u9009\u53c2\u6570\u7684\u6570\u91cf\u76f8\u540c\u3002 \u6807\u51c6\u51fd\u6570\u548cPython\u7684\u5e93\u51fd\u6570\u5728\u8c03\u7528\u65f6\u90fd\u4f1a\u5bf9\u4f20\u5165\u7684\u53c2\u6570\u8fdb\u884c\u7c7b\u578b\u68c0\u67e5","title":"1.1.8.\u53ef\u9009\u548c\u5173\u952e\u5b57\u51fd\u6570\u53c2\u6570"},{"location":"python/DataStructure/01_PythonFundmantal/#119","text":"\u7b80\u5355\u7684\u8d4b\u503c\u8bed\u53e5 PI = 3.1416 \u591a\u53d8\u91cf\u8d4b\u503c minValue, maxValue = 1, 100 \u53d8\u91cf\u4ea4\u6362 a, b = b, a \u8d4b\u503c\u8bed\u53e5\u5fc5\u987b\u5199\u5728\u4e00\u884c\u4ee3\u7801\u91cc\uff0c\u4f46\u662f\u53ef\u4ee5\u5728\u9017\u53f7\u3001\u5706\u62ec\u53f7\u3001\u82b1\u62ec\u53f7\u6216\u65b9\u62ec\u53f7\u4e4b\u540e\u6362\u884c\uff0c\u6216\u8005\u7528\u8f6c\u4e49\u7b26 \\ \u8fdb\u884c\u6362\u884c\u3002 \u6362\u884c\u793a\u4f8b\uff1a minValue = min ( 100 , 200 ) product = max ( 100 , 200 ) \\ * 30","title":"1.1.9.\u53d8\u91cf\u548c\u8d4b\u503c\u8bed\u53e5"},{"location":"python/DataStructure/01_PythonFundmantal/#1110","text":"\u53d8\u91cf\u90fd\u53ef\u4ee5\u88ab\u6307\u5b9a\u4e3a\u4efb\u4f55\u7c7b\u578b\u7684\u503c\u3002\u8fd9\u4e9b\u53d8\u91cf\u5e76\u4e0d\u50cf\u5176\u4ed6\u8bed\u8a00\u90a3\u6837\u88ab\u58f0\u660e\u4e3a\u7279\u5b9a\u7684\u7c7b\u578b\uff0c\u800c\u53ea\u662f\u88ab\u8d4b\u4e86\u4e00\u4e2a\u503c \u503c\u548c\u5bf9\u8c61\u90fd\u662f\u6709\u7c7b\u578b\u7684\uff0c\u4f1a\u5728\u8fd0\u884c\u65f6\u8fdb\u884c\u6570\u636e\u7c7b\u578b\u68c0\u67e5","title":"1.1.10.\u6570\u636e\u7c7b\u578b"},{"location":"python/DataStructure/01_PythonFundmantal/#1111import","text":"import \u8bed\u53e5\u4f7f\u5f97\u4e00\u4e2a\u6a21\u5757\u4e2d\u7684\u6807\u8bc6\u7b26\u53ef\u4ee5\u88ab\u53e6\u4e00\u4e2a\u7a0b\u5e8f\u6240\u89c1\u5230\u3002\u6807\u8bc6\u7b26\u53ef\u4ee5\u662f\u5bf9\u8c61\u540d\u3001\u51fd\u6570\u540d\u6216\u7c7b\u540d \u5bfc\u5165\u6a21\u5757\u540d\u79f0\uff0c\u4f8b\u5982 import math \u5bfc\u5165\u6a21\u5757\u4e2d\u7684\u6807\u8bc6\u7b26\uff0c\u4f8b\u5982\uff1a from math import sqrt \uff0c\u6216\u8005 from math import pi, sqrt \u4e5f\u53ef\u4ee5\u4f7f\u7528\u7b26\u53f7 * \u5bfc\u5165\u4e00\u4e2a\u6a21\u5757\u4e2d\u7684\u6240\u6709\u540d\u79f0\uff0c\u4f46\u4e0d\u63a8\u8350","title":"1.1.11.import\u8bed\u53e5"},{"location":"python/DataStructure/01_PythonFundmantal/#12","text":"","title":"1.2.\u63a7\u5236\u8bed\u53e5"},{"location":"python/DataStructure/01_PythonFundmantal/#121","text":"\u5355\u5411if\u8bed\u53e5\u7684\u8bed\u6cd5 if < Boolean expression > : < sequence of statements > \u53cc\u5411if\u8bed\u53e5\u7684\u8bed\u6cd5 if < Boolean expression > : < sequence of statements > else : < sequence of statements > \u591a\u5411if\u8bed\u53e5\u7684\u8bed\u6cd5 if < Boolean expression > : < sequence of statements > elif < Boolean expression > : < sequence of statements > ... else : < sequence of statements >","title":"1.2.1.\u6761\u4ef6\u8bed\u53e5"},{"location":"python/DataStructure/01_PythonFundmantal/#122if-name-main","text":"\u793a\u4f8b\u4ee3\u7801 numberguess.py \u3002 import random def main (): smaller = int ( input ( \"\u8f93\u5165\u6700\u5c0f\u503c: \" )) larger = int ( input ( \"\u8f93\u5165\u6700\u5927\u503c: \" )) myNumber = random . randint ( smaller , larger ) count = 0 while True : count += 1 userNumber = int ( input ( \"\u8f93\u5165\u4f60\u731c\u7684\u503c: \" )) if userNumber < myNumber : print ( \"\u4f60\u731c\u7684\u592a\u5c0f\uff01\" ) elif userNumber > myNumber : print ( \"\u4f60\u731c\u7684\u592a\u5927\uff01\" ) else : print ( \"\u606d\u559c\uff0c\u4f60\u5728\u7b2c\" , count , \"\u6b21\u731c\u5bf9\u4e86!\" ) break if __name__ == \"__main__\" : main () \u4e0a\u9762\u7684if\u8bed\u53e5\u7684\u4f5c\u7528\u662f\uff0c \u8981\u4e48\u5c06\u6a21\u5757\u5f53\u4f5c\u4e00\u4e2a\u72ec\u7acb\u7684\u7a0b\u5e8f\u8fd0\u884c\uff0c\u8be5\u6a21\u5757\u7684 _name_ \u53d8\u91cf\u4f1a\u8bbe\u7f6e\u4e3a\u5b57\u7b26\u4e32 _main_ \uff0c\u624d\u4f1a\u6267\u884c main() \u51fd\u6570 \u8981\u4e48\u4ece\u53e6\u4e00\u4e2a\u6a21\u5757\u4e2d\u5bfc\u5165\uff0c\u8be5\u6a21\u5757\u7684 _name_ \u53d8\u91cf\u4f1a\u8bbe\u7f6e\u8be5\u6a21\u5757\u7684\u540d\u79f0\uff0c\u4e0a\u4f8b\u4e2d\u5373 numberguess","title":"1.2.2.\u4f7f\u7528if name == \"main\""},{"location":"python/DataStructure/01_PythonFundmantal/#123","text":"\u901a\u5e38\uff1a \u4e00\u822c\u4f1a\u4f7f\u7528for\u5faa\u73af\u6765\u8fed\u4ee3\u786e\u5b9a\u8303\u56f4\u7684\u503c\u6216\u503c\u7684\u5e8f\u5217 \u5982\u679c\u7ee7\u7eed\u5faa\u73af\u7684\u6761\u4ef6\u662f\u67d0\u4e2a\u5e03\u5c14\u8868\u8fbe\u5f0f\uff0c\u4e00\u822c\u4f1a\u4f7f\u7528while\u5faa\u73af while \u8bed\u6cd5\u683c\u5f0f\uff1a while < Boolean expression > : < sequence of statements > \u793a\u4f8b\uff1a # \u8ba1\u7b97\u4ece1\u523010\u7684\u4e58\u79ef\u5e76\u8f93\u51fa\u7ed3\u679c result = 1 value = 1 while value <= 10 : result *= value value += 1 print ( result , value ) # \u8fd0\u884c\u7ed3\u679c # 3628800 11 for \u8bed\u6cd5\u683c\u5f0f\uff1a for < variable > in < iterable object > : < sequence of statements > \u793a\u4f8b\uff1a # \u8ba1\u7b97\u4ece1\u523010\u7684\u4e58\u79ef\u5e76\u8f93\u51fa\u7ed3\u679c result = 1 value = 1 for value in range ( 1 , 11 ): result *= value value += 1 print ( result , value ) # \u8fd0\u884c\u7ed3\u679c # 3628800 11","title":"1.2.3.\u5faa\u73af\u8bed\u53e5"},{"location":"python/DataStructure/01_PythonFundmantal/#13","text":"Python\u4e2d\u7684\u5b57\u7b26\u4e32\u4e5f\u662f\u4e00\u4e2a\u590d\u5408\u5bf9\u8c61 Python\u7684\u5b57\u7b26\u4e32\u7c7b\u578b\u540d\u4e3a str \u7ea6\u5b9a\uff1a \u628a\u5355\u5b57\u7b26\u7684\u5b57\u7b26\u4e32\u7528\u5355\u5f15\u53f7\u62ec\u8d77\u6765 \u628a\u591a\u5b57\u7b26\u7684\u5b57\u7b26\u4e32\u7528\u53cc\u5f15\u53f7\u62ec\u8d77\u6765","title":"1.3.\u5b57\u7b26\u4e32\u53ca\u5176\u8fd0\u7b97"},{"location":"python/DataStructure/01_PythonFundmantal/#131","text":"\u6bd4\u8f83\u8fd0\u7b97\u7b26\uff0c\u662f\u6309\u7167ASCII\u7801\u7684\u987a\u5e8f\u6bd4\u8f83\u4e24\u4e2a\u5b57\u7b26\u4e32\u4e2d\u6bcf\u4e2a\u4f4d\u7f6e\u7684\u5b57\u7b26\u5bf9 \u793a\u4f8b\uff1a print ( 'A' > 'a' ) # \u8fd0\u884c\u7ed3\u679c False print ( 'A' < 'a' ) # \u8fd0\u884c\u7ed3\u679c True + \u8fd0\u7b97\u7b26\u751f\u6210\u5e76\u8fd4\u56de\u4e00\u4e2a\u5305\u542b\u4e24\u4e2a\u64cd\u4f5c\u6570\u7684\u65b0\u5b57\u7b26\u4e32 \u793a\u4f8b\uff1a print ( \"Hello\" + \"Python\" ) # \u8fd0\u884c\u7ed3\u679c HelloPython \u4e0b\u6807\u8fd0\u7b97\u7b26\uff0c\u8303\u56f4\u662f\u4ece0\u5230\u5b57\u7b26\u4e32\u7684\u957f\u5ea6\u51cf\u53bb1\u7684\u4e00\u4e2a\u6574\u6570\u3002 \u8fd0\u7b97\u7b26\u8fd4\u56de\u5728\u5b57\u7b26\u4e32\u4e2d\u8be5\u4f4d\u7f6e\u7684\u5b57\u7b26\u3002 \u793a\u4f8b\uff1a print ( \"Greater\" [ 1 ]) # \u8fd0\u884c\u7ed3\u679c\uff1ar \u5f53\u7d22\u5f15\u4e3a\u8d1f\u503c\u65f6\uff0cPython\u4f1a\u628a\u8fd9\u4e2a\u503c\u548c\u5b57\u7b26\u4e32\u7684\u957f\u5ea6\u76f8\u52a0\uff0c\u4ee5\u786e\u5b9a\u8981\u8fd4\u56de\u7684\u5b57\u7b26\u7684\u4f4d\u7f6e\u3002\u8d1f\u7d22\u5f15\u503c\u4e0d\u5f97\u5c0f\u4e8e\u5b57\u7b26\u4e32\u957f\u5ea6\u7684\u8d1f\u503c\u3002 print ( \"Greater\" [ - 3 ]) # \u8fd0\u884c\u7ed3\u679c\uff1at print ( \"Greater\" [ - 9 ]) # \u8fd0\u884c\u7ed3\u679c\uff1aIndexError: string index out of range \u5207\u7247\u8fd0\u7b97\u7b26\uff08slice operator\uff09\uff0c\u4e0b\u6807\u8fd0\u7b97\u7b26\u7684\u4e00\u79cd\u53d8\u4f53\u3002 \u8bed\u6cd5\u683c\u5f0f\uff1a [:] \uff1a\u8303\u56f4\u662f\u4ece0\u5230\u5b57\u7b26\u4e32\u7684\u957f\u5ea6\u51cf\u53bb1\u7684\u6574\u6570 \uff1a\u8303\u56f4\u662f\u4ece0\u5230\u5b57\u7b26\u4e32\u7684\u957f\u5ea6\u7684\u6574\u6570 \u5207\u7247\u68c0\u7d22\u89c4\u5219\uff1a \u8fd4\u56de\u8fd9\u6837\u4e00\u4e2a\u5b50\u5b57\u7b26\u4e32\uff1a\u8fd9\u4e2a\u5b50\u5b57\u7b26\u4e32\u4f1a\u4ece \u7d22\u5f15\u5904\u7684\u5b57\u7b26\u5f00\u59cb\uff0c\u5230 \u7d22\u5f15\u51cf1\u7684\u4f4d\u7f6e\u4f5c\u4e3a\u7ed3\u675f\u3002 \u5982\u679c\u7701\u7565 \u7d22\u5f15\uff0c\u90a3\u4e48\u5207\u7247\u8fd0\u7b97\u7b26\u5c06\u8fd4\u56de\u4e00\u4e2a\u4ee5\u5f53\u524d\u5b57\u7b26\u4e32\u7684\u7b2c\u4e00\u4e2a\u5b57\u7b26\u4f5c\u4e3a\u5f00\u5934\u7684\u5b50\u5b57\u7b26\u4e32\u3002 \u5982\u679c\u7701\u7565 \u7d22\u5f15\uff0c\u90a3\u4e48\u5207\u7247\u8fd0\u7b97\u7b26\u5c06\u8fd4\u56de\u4e00\u4e2a\u4ee5\u5f53\u524d\u5b57\u7b26\u4e32\u7684\u6700\u540e\u4e00\u4e2a\u5b57\u7b26\u4f5c\u4e3a\u7ed3\u5c3e\u7684\u5b50\u5b57\u7b26\u4e32\u3002 \u5982\u679c\u7701\u7565\u8fd9\u4e24\u4e2a\u503c\uff0c\u90a3\u4e48\u5207\u7247\u8fd0\u7b97\u7b26\u4f1a\u8fd4\u56de\u6574\u4e2a\u5b57\u7b26\u4e32\u3002 \u793a\u4f8b\uff1a print ( \"Greater\" [:]) # \u8fd4\u56de\u5b57\u4e32 Greater print ( \"Greater\" [ 2 :]) # \u8fd4\u56de\u5b57\u4e32 eater print ( \"Greater\" [: 2 ]) # \u8fd4\u56de\u5b57\u4e32 Gr print ( \"Greater\" [ 2 : 5 ]) # \u8fd4\u56de\u5b57\u4e32 eat","title":"1.3.1.\u8fd0\u7b97\u7b26"},{"location":"python/DataStructure/01_PythonFundmantal/#132","text":"\u683c\u5f0f\u5316\u5b57\u7b26\u4e32\u91cc\u7684\u6570\u636e\u5b57\u7b26\u4ee5\u53ca\u6ee1\u8db3\u7ed9\u5b9a\u57fa\u51c6\u7ebf\u7684\u9644\u52a0\u7a7a\u683c\u7684\u603b\u6570\u79f0\u4e3a\u5b83\u7684\u5b57\u6bb5\u5bbd\u5ea6\uff08field width\uff09\u3002 print \u51fd\u6570\u4f1a\u5728\u9047\u5230\u7b2c\u4e00\u5217\u65f6\u81ea\u52a8\u5f00\u59cb\u6253\u5370\u8f93\u51fa\u57fa\u51c6\u7ebf\u3002 \u793a\u4f8b\uff0c\u901a\u8fc7print\u8bed\u53e5\u8f93\u51fa2\u5217\u3002 for i in range ( 7 , 11 ): print ( i , 10 * i ) # \u8fd0\u884c\u7ed3\u679c # 7 70 # 8 80 # 9 90 # 10 100 Python\u7684\u901a\u7528\u683c\u5f0f\u5316\u673a\u5236 \u8bed\u6cd5\u683c\u5f0f % \u548c % (, \u2026, ) \u3002 \u683c\u5f0f\u5316\u5b57\u7b26\u4e32\u65f6\uff0c \u4f7f\u7528 %s \u8868\u793a\u6cd5\u3002\u5f53\u5b57\u6bb5\u5bbd\u5ea6\u4e3a\u6b63\u65f6\uff0c\u6570\u636e\u662f\u53f3\u5bf9\u9f50\u7684\uff1b\u5f53\u5b57\u6bb5\u5bbd\u5ea6\u4e3a\u8d1f\u65f6\uff0c\u6570\u636e\u662f\u5de6\u5bf9\u9f50\u7684\u3002 \u683c\u5f0f\u6574\u6570\u65f6\uff0c \u4f7f\u7528 %d \u8868\u793a\u6cd5\u3002 \u683c\u5f0f\u6d6e\u70b9\u6570\u65f6\uff0c \u4f7f\u7528 %.f \u8868\u793a\u6cd5\uff0c\u5176\u4e2d . \u8fd9\u4e00\u90e8\u5206\u662f\u53ef\u9009\u7684\u3002 \u793a\u4f8b\uff1a print ( \" %6s \" % \"four\" ) print ( \" %-6s \" % \"four\" ) # four # four for i in range ( 7 , 11 ): print ( \" %-3d%5d \" % ( i , 10 * i )) # 7 70 # 8 80 # 9 90 # 10 100 for i in range ( 7 , 11 ): print ( \" %-3d%5.3f \" % ( i , i / 3 )) # 7 2.333 # 8 2.667 # 9 3.000 # 10 3.333 \u4e0b\u4f8b\u5bf9\u6bd4\u4e86\u6d6e\u70b9\u6570\u5728\u4f7f\u7528\u4e86\u683c\u5f0f\u5b57\u7b26\u4e32\u548c\u6ca1\u6709\u4f7f\u7528\u683c\u5f0f\u5b57\u7b26\u4e32\u8fd9\u4e24\u79cd\u60c5\u51b5\u4e0b\u7684\u8f93\u51fa\u5dee\u5f02\u3002 salary = 100.00 print ( \"Salary: $\" + str ( salary )) # Salary: $100.0 print ( \"Salary: $ %0.2f \" % salary ) # Salary: $100.00 \u6ce8\u610f\uff0c\u4e0b\u4f8b\u4e2dPython\u7ed9\u6570\u5b57\u6dfb\u52a0\u4e86\u4e00\u4e2a\u7cbe\u5ea6\u4f4d\u6570\uff0c\u5e76\u4e14\u5176\u5de6\u4fa7\u586b\u5145\u7a7a\u683c\uff0c\u4ece\u800c\u5b9e\u73b0\u4e86\u5b57\u6bb5\u5bbd\u5ea6\u4e3a6\u3001\u7cbe\u5ea6\u4e3a3\u7684\u8bbe\u7f6e\u3002\u8fd9\u4e2a\u5bbd\u5ea6\u5305\u542b\u5c0f\u6570\u70b9\u540e\u6240\u5360\u636e\u7684\u4f4d\u7f6e\u3002 print ( \" %6.3f \" % 3.14 ) # \u5de6\u4fa7\u586b\u5145\u4e86\u7a7a\u683c # 3.140 print ( \" %-6.3f \" % 3.14 ) # 3.140","title":"1.3.2.\u5b57\u7b26\u4e32\u683c\u5f0f\u5316"},{"location":"python/DataStructure/01_PythonFundmantal/#133","text":"\u8bed\u6cd5\u683c\u5f0f\uff1a .() \u793a\u4f8b\uff1a print ( \"greater\" . isupper ()) # \u8fd0\u884c\u7ed3\u679c # False print ( \"greater\" . upper ()) # \u8fd0\u884c\u7ed3\u679c # GREATER print ( \"greater\" . startswith ( \"great\" )) # \u8fd0\u884c\u7ed3\u679c # True print ( len ( \"greater\" )) print ( \"greater\" . __len__ ()) # \u8fd0\u884c\u7ed3\u679c # 7 print ( \"great\" + \"er\" ) print ( \"great\" . __add__ ( \"er\" )) # \u8fd0\u884c\u7ed3\u679c # greater print ( \"e\" in \"great\" ) print ( \"great\" . __contains__ ( \"e\" )) # \u8fd0\u884c\u7ed3\u679c # True \u63d0\u793a\uff1a dir() \u65b9\u6cd5\u4f1a\u8fd4\u56de\u6240\u4f20\u9012\u7684\u5bf9\u8c61\u7684\u6709\u6548\u5c5e\u6027\uff0c\u8bed\u6cd5\u683c\u5f0f\uff1a dir(object) help() \u51fd\u6570\u67e5\u770b\u51fd\u6570\u6216\u6a21\u5757\u7528\u9014\u7684\u8be6\u7ec6\u8bf4\u660e\uff0c\u8bed\u6cd5\u683c\u5f0f\uff1a help(object) dir ( str ) help ( str . __contains__ )","title":"1.3.3.\u5bf9\u8c61\u548c\u65b9\u6cd5\u8c03\u7528"},{"location":"python/DataStructure/01_PythonFundmantal/#14","text":"Python\u4e2d\u7684\u591a\u9879\u96c6\uff08collections\uff09\u6307\u80fd\u591f\u5305\u542b\u5143\u7d20\u7684\u6570\u636e\u7ed3\u6784\u3002\u591a\u9879\u96c6\u6a21\u5757\u63d0\u4f9b\u4e86\u4e0d\u540c\u7c7b\u578b\u7684\u5bb9\u5668\u3002\u5bb9\u5668\u662f\u7528\u4e8e\u5b58\u50a8\u4e0d\u540c\u5bf9\u8c61\u5e76\u63d0\u4f9b\u8bbf\u95ee\u6240\u5305\u542b\u5bf9\u8c61\u4ee5\u53ca\u5bf9\u5b83\u4eec\u8fdb\u884c\u8fed\u4ee3\u7684\u65b9\u5f0f\u7684\u5bf9\u8c61\u3002\u4e00\u4e9b\u5185\u7f6e\u7684\u5bb9\u5668\u6709\u5143\u7ec4\uff08Tuple\uff09\u3001\u5217\u8868\uff08List\uff09\u3001\u5b57\u5178\uff08Dictionary\uff09\u7b49\u3002 \u4ee5\u4e0b\u662f\u7531collections\u6a21\u5757\u63d0\u4f9b\u7684\u4e0d\u540c\u5bb9\u5668\u7684\u5217\u8868\uff1a \u8ba1\u6570\u5668\uff08Counters\uff09 \u6709\u5e8f\u5b57\u5178\uff08OrderedDict\uff09 \u9ed8\u8ba4\u5b57\u5178\uff08DefaultDict\uff09 \u94fe\u6620\u5c04\uff08ChainMap\uff09 \u547d\u540d\u5143\u7ec4\uff08NamedTuple\uff09 \u53cc\u5411\u961f\u5217\uff08DeQue\uff09 \u7528\u6237\u5b57\u5178\uff08UserDict\uff09 \u7528\u6237\u5217\u8868\uff08UserList\uff09 \u7528\u6237\u5b57\u7b26\u4e32\uff08UserString\uff09","title":"1.4.\u5185\u7f6e\u591a\u9879\u96c6\u53ca\u5176\u64cd\u4f5c"},{"location":"python/DataStructure/01_PythonFundmantal/#141","text":"\u5217\u8868\uff08list\uff09\u662f\u96f6\u4e2a\u6216\u591a\u4e2aPython\u5bf9\u8c61\u7684\u4e00\u4e2a\u5e8f\u5217\uff0c\u8fd9\u4e9b\u5bf9\u8c61\u901a\u5e38\u79f0\u4e3a\u9879\uff08item\uff09\u3002 \u5217\u8868\u7684\u8868\u73b0\u5f62\u5f0f\u662f\uff1a\u7528\u65b9\u62ec\u53f7\u62ec\u8d77\u6574\u4e2a\u5217\u8868\uff0c\u5e76\u7528\u9017\u53f7\u5206\u9694\u5143\u7d20\u3002 \u793a\u4f8b\uff1a [] # \u7a7a\u5217\u8868 [ \"greater\" , \"less\" , 10 ] # \u542b\u4e0d\u540c\u7c7b\u578b\u7684\u5217\u8868 [ \"greater\" , [ \"less\" , 10 ]] # \u542b\u5185\u5d4c\u5217\u8868\u7684\u5217\u8868 \u5217\u8868\u7684\u5207\u7247\u64cd\u4f5c\uff1a \u548c\u5b57\u7b26\u4e32\u7c7b\u4f3c\uff0c\u53ef\u4ee5\u901a\u8fc7\u6807\u51c6\u8fd0\u7b97\u7b26\u6267\u884c\u5207\u7247\u6216\u8fde\u63a5\u64cd\u4f5c\uff0c\u8fd4\u56de\u7ed3\u679c\u4e5f\u662f\u5217\u8868\u3002 \u548c\u5b57\u7b26\u4e32\u4e0d\u540c\uff0c\u5217\u8868\u662f\u53ef\u53d8\u7684\uff0c\u5373\uff0c\u53ef\u4ee5\u66ff\u6362\u3001\u63d2\u5165\u6216\u5220\u9664\u5217\u8868\u4e2d\u6240\u5305\u542b\u7684\u9879\u3002 \u5207\u7247\u548c\u8fde\u63a5\u8fd0\u7b97\u7b26\u6240\u8fd4\u56de\u7684\u5217\u8868\u662f\u65b0\u7684\u5217\u8868\uff0c\u800c\u4e0d\u662f\u6700\u521d\u5217\u8868\u7684\u4e00\u90e8\u5206\uff1b \u5217\u8868\u7c7b\u578b\u5305\u542b\u4e86\u51e0\u4e2a\u53eb\u4f5c\u53d8\u5f02\u5668\uff08mutator\uff09\u7684\u65b9\u6cd5\uff0c\u7528\u4e8e\u4fee\u6539\u5217\u8868\u7684\u7ed3\u6784\u3002 \u53ef\u4ee5\u901a\u8fc7 dir(list) \u6765\u67e5\u770b\u65b9\u6cd5\uff0c\u5305\u62ec\u53d8\u5f02\u5668\uff08mutator\uff09\u7684\u65b9\u6cd5\u3002 dir ( list ) # \u8fd0\u884c\u7ed3\u679c # ['__add__', '__class__', '__contains__', '__delattr__', '__delitem__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__getitem__', '__gt__', '__hash__', '__iadd__', '__imul__', '__init__', '__init_subclass__', '__iter__', '__le__', '__len__', '__lt__', '__mul__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__reversed__', '__rmul__', '__setattr__', '__setitem__', '__sizeof__', '__str__', '__subclasshook__', 'append', 'clear', 'copy', 'count', 'extend', 'index', 'insert', 'pop', 'remove', 'reverse', 'sort'] \u6700\u5e38\u7528\u7684\u5217\u8868\u53d8\u5f02\u5668\u65b9\u6cd5\u662f append \u3001 insert \u3001 pop \u3001 remove \u548c sort \u3002 \u793a\u4f8b\uff1a myList = [] # myList\u5f53\u524d\u4e3a[] myList . append ( 34 ) # myList\u5f53\u524d\u4e3a[34]\uff0c\u9ed8\u8ba4\u5c3e\u90e8\u63d2\u5165 myList . append ( 22 ) # myList\u5f53\u524d\u4e3a[34, 22]\uff0c\u9ed8\u8ba4\u5c3e\u90e8\u63d2\u5165 myList . sort () # myList\u5f53\u524d\u4e3a[22, 34] myList . pop () # \u9ed8\u8ba4\u4ece\u7d22\u5f15\u4f4d[0]\u5220\u9664\uff0c\u8fd4\u56de\u7ed3\u679c22\uff1bmyList\u5f53\u524d\u4e3a[34] myList . insert ( 0 , 22 ) # \u5728\u6307\u5b9a\u7d22\u5f15\u4f4d[0]\u63d2\u5165\uff1bmyList\u5f53\u524d\u4e3a[22, 34] myList . insert ( 1 , 55 ) # \u5728\u6307\u5b9a\u7d22\u5f15\u4f4d[1]\u63d2\u5165\uff1bmyList\u5f53\u524d\u4e3a[22, 55, 34] myList . pop ( 1 ) # \u6307\u5b9a\u7d22\u5f15\u4f4d[1]\u5220\u9664\uff0c\u8fd4\u56de\u7ed3\u679c55\uff1bmyList\u5f53\u524d\u4e3a[22, 34] myList . remove ( 22 ) # \u5220\u9664\u9996\u4e2a\u5339\u914d\u9879\u7684\u5143\u7d20[22]\uff1bmyList\u5f53\u524d\u4e3a[34] myList . remove ( 55 ) # \u62a5ValueError\u9519\uff0clist.remove(x): x not in list \u5bf9\u4e8e\u5b57\u7b26\u4e32\uff0csplit\u65b9\u6cd5\u4f1a\u4ece\u5b57\u7b26\u4e32\u91cc\u5206\u79bb\u51fa\u4e00\u4e2a\u5355\u8bcd\u5217\u8868\uff0c\u800cjoin\u65b9\u6cd5\u4f1a\u628a\u5355\u8bcd\u5217\u8868\u8fde\u5728\u4e00\u8d77\u4ece\u800c\u5f62\u6210\u5b57\u7b26\u4e32\u3002\u4f8b\u5982\uff1a print ( \"Python is cool\" . split ()) # \u8fd0\u884c\u7ed3\u679c\uff1a # ['Python', 'is', 'cool'] print ( \" \" . join ([ \"Python\" , \"is\" , \"cool\" ])) # \u8fd0\u884c\u7ed3\u679c\uff1a # Python is cool \u5bf9\u4e8e\u5217\u8868\u7279\u6027\u548c\u64cd\u4f5c\u7684\u8be6\u7ec6\u7ec3\u4e60\uff0c\u53c2\u8003 Python\u8bed\u8a00\u57fa\u7840@github \u6216\u8005 Python\u8bed\u8a00\u57fa\u7840@web \u4e2d\u201c1.3 \u5217\u8868\uff08list\uff09\u201d\u7684\u5185\u5bb9\u3002","title":"1.4.1.\u5217\u8868"},{"location":"python/DataStructure/01_PythonFundmantal/#142","text":"\u5143\u7ec4\uff08tuple\uff09\u662f\u4e00\u4e2a\u4e0d\u53ef\u53d8\u7684\u5143\u7d20\u5e8f\u5217\u3002 \u5143\u7ec4\uff08tuple\uff09\u5f62\u5f0f\u662f\u7528\u5706\u62ec\u53f7\u5c06\u5404\u9879\u62ec\u8d77\u6765\uff0c\u5e76\u4e14\u5fc5\u987b\u81f3\u5c11\u5305\u542b\u4e24\u4e2a\u9879\u3002 \u5143\u7ec4\u5b9e\u9645\u4e0a\u5c31\u50cf\u5217\u8868\u4e00\u6837\uff0c\u53ea\u4e0d\u8fc7\u5b83\u6ca1\u6709\u53d8\u5f02\u5668\u65b9\u6cd5\u3002 \u5982\u679c\u8981\u4f7f\u5143\u7ec4\u53ea\u5305\u542b\u4e00\u4e2a\u5143\u7d20\uff0c\u5219\u5fc5\u987b\u5728\u5143\u7ec4\u91cc\u5305\u542b\u9017\u53f7\u3002 \u5bf9\u6bd4\u4e0b\u9762\u7684\u533a\u522b\uff1a print (( 21 )) # (21)\u88ab\u89c6\u4e3a\u6574\u6570 # \u8fd0\u884c\u7ed3\u679c\uff1a # 21 print (( 21 ,)) # (21,)\u88ab\u89c6\u4e3a\u5143\u7ec4 # \u8fd0\u884c\u7ed3\u679c\uff1a # (21,) \u5bf9\u4e8e\u5217\u8868\u7279\u6027\u548c\u64cd\u4f5c\u7684\u8be6\u7ec6\u7ec3\u4e60\uff0c\u53c2\u8003 Python\u8bed\u8a00\u57fa\u7840@github \u6216\u8005 Python\u8bed\u8a00\u57fa\u7840@web \u4e2d\u201c1.6 \u5143\u7ec4\uff08tuple\uff09\u201d\u7684\u5185\u5bb9\u3002","title":"1.4.2.\u5143\u7ec4"},{"location":"python/DataStructure/01_PythonFundmantal/#143","text":"for \u5faa\u73af\u53ef\u4ee5\u7528\u6765\u904d\u5386\u5e8f\u5217\uff08\u5982\u5b57\u7b26\u4e32\u3001\u5217\u8868\u6216\u5143\u7ec4\uff09\u91cc\u7684\u6240\u6709\u5143\u7d20\u3002 \u904d\u5386\u5217\u8868\uff1a myList = [ 67 , 100 , 'Monday' , \"It's good\" ] for item in myList : print ( item ) myList = [ 67 , 100 , 'Monday' , \"It's good\" ] for idx in range ( len ( myList )): print ( myList [ idx ]) \u904d\u5386\u5143\u7ec4\uff1a myString = \"I love Python\" myList = myString . split () myTuple = tuple ( myList ) for i in myTuple : print ( i ) \u904d\u5386\u5b57\u7b26\u4e32\uff1a(\u6ce8\u610f\uff0c\u662f\u904d\u5386\u5b57\u7b26\uff0c\u4e0d\u662f\u5355\u8bcd) myString = \"I love Python\" for i in myString : print ( i ) myString = \"I love Python\" for i in range ( len ( myString )): print ( myString [ i ]) myString = \"I love Python\" for i in enumerate ( myString ): print ( i ) myString = \"I love Python\" for i , j in enumerate ( myString ): print ( i , j ) myString = \"I love Python\" for i in iter ( myString ): print ( i ) \u5982\u679c\u6309\u7167\u5355\u8bcd\u904d\u5386\u5b57\u7b26\u4e32\uff0c\u5219\u9700\u8981\u5148\u628a\u5b57\u4e32\u6309\u5355\u8bcd\u62c6\u89e3\u4e3a\u5217\u8868\u3002 myString = \"I love Python\" myList = \"I love Python\" . split () for i in myList : print ( i ) \u5bf9\u4e8e\u5217\u8868\u548c\u5143\u7ec4\u904d\u5386\u7684\u66f4\u591a\u4f8b\u5b50\uff0c\u5305\u62ec\u62c6\u5305\u904d\u5386\uff0c\u53c2\u8003 Python\u8bed\u8a00\u57fa\u7840@github \u6216\u8005 Python\u8bed\u8a00\u57fa\u7840@web \u7684\u5185\u5bb9\u3002","title":"1.4.3.\u5e8f\u5217\u904d\u5386"},{"location":"python/DataStructure/01_PythonFundmantal/#144","text":"\u5b57\u5178\uff08dictionary\uff09\u5305\u542b\u96f6\u4e2a\u6216\u591a\u4e2a\u6761\u76ee\u3002 \u6bcf\u4e2a\u6761\u76ee\uff08entry\uff09\u90fd\u6709\u552f\u4e00\u7684\u952e\u548c\u5b83\u6240\u5bf9\u5e94\u7684\u503c\u76f8\u5173\u8054\u3002 \u952e\u901a\u5e38\u662f\u5b57\u7b26\u4e32\u6216\u6574\u6570\uff0c\u800c\u503c\u662f\u4efb\u610f\u7684Python\u5bf9\u8c61\u3002 \u4e0b\u6807\u8fd0\u7b97\u7b26\u53ef\u4ee5\u7528\u4e8e\u8bbf\u95ee\u4e00\u4e2a\u7ed9\u5b9a\u952e\u7684\u503c\uff0c\u7ed9\u4e00\u4e2a\u65b0\u952e\u6dfb\u52a0\u4e00\u4e2a\u503c\uff0c\u4ee5\u53ca\u66ff\u6362\u7ed9\u5b9a\u952e\u7684\u503c\u3002 pop \u65b9\u6cd5\u4f1a\u5220\u9664\u4e00\u4e2a\u6761\u76ee\u5e76\u8fd4\u56de\u7ed9\u5b9a\u952e\u6240\u5bf9\u5e94\u7684\u503c\u3002 keys \u65b9\u6cd5\u4f1a\u628a\u6240\u6709\u952e\u8fd4\u56de\u6210\u4e00\u4e2a\u53ef\u8fed\u4ee3\u5bf9\u8c61\u3002 values \u65b9\u6cd5\u4f1a\u628a\u6240\u6709\u503c\u8fd4\u56de\u6210\u4e00\u4e2a\u53ef\u8fed\u4ee3\u5bf9\u8c61\u3002 \u793a\u4f8b\uff1a {} # \u7a7a\u5b57\u5178 { \"name\" : \"Ken\" } # \u542b\u4e00\u4e2a\u6761\u76ee { \"name\" : \"Ken\" , \"age\" : 67 } # \u542b\u4e8c\u4e2a\u6761\u76ee { \"hobbies\" :[ \"reading\" , \"running\" ]} # \u542b\u4e00\u4e2a\u6761\u76ee\uff0c\u5176\u4e2d\u503c\u662f\u4e00\u4e2a\u5217\u8868 \u5b57\u5178\u672c\u8eab\u4e5f\u662f\u4e00\u4e2a\u53ef\u8fed\u4ee3\u5bf9\u8c61\u3002\u53ef\u4ee5\u901a\u8fc7for\u8bed\u53e5\u8fdb\u884c\u904d\u5386\u952e\u6216/\u548c\u503c\u3002 myDict = { 'name' : 'Ming' , 'id' : 1001 , 'age' : 35 } for keys in myDict : print ( keys , myDict [ keys ]) # \u8fd0\u884c\u7ed3\u679c\uff1a # name Ming # id 1001 # age 35","title":"1.4.4.\u5b57\u5178"},{"location":"python/DataStructure/01_PythonFundmantal/#145","text":"\u53ef\u4ee5\u5728\u5b57\u7b26\u4e32\u5217\u8868\u3001\u5143\u7ec4\u6216\u5b57\u5178\u91cc\u901a\u8fc7 in \u8fd0\u7b97\u7b26\u6765\u5bf9\u503c\u6216\u591a\u9879\u96c6\u8fdb\u884c\u641c\u7d22\uff0c\u8fd4\u56de True \u6216 False \u3002\u5bf9\u4e8e\u5b57\u5178\u6765\u8bf4\uff0c\u641c\u7d22\u7684\u76ee\u6807\u503c\u5e94\u8be5\u662f\u4e00\u4e2a\u952e\u3002 \u5982\u679c\u5df2\u77e5\u7ed9\u5b9a\u503c\u5b58\u5728\u4e8e\u5e8f\u5217\uff08\u5b57\u7b26\u4e32\u3001\u5217\u8868\u6216\u5143\u7ec4\uff09\u91cc\uff0c\u90a3\u4e48 index \u65b9\u6cd5\u5c06\u8fd4\u56de\u8fd9\u4e2a\u503c\u6240\u51fa\u73b0\u7684\u7b2c\u4e00\u4e2a\u4f4d\u7f6e\u3002 \u5217\u8868\u68c0\u7d22\uff1a myString = \"I love Python\" myList = myString . split () print ( myList ) # \u8fd0\u884c\u7ed3\u679c\uff1a # ['I', 'love', 'Python'] print ( myList . index ( 'love' )) # \u8fd0\u884c\u7ed3\u679c\uff1a # 1 \u5143\u7ec4\u68c0\u7d22\uff1a myString = \"I love Python\" myList = myString . split () myTuple = tuple ( myList ) print ( myTuple ) print ( myTuple . index ( 'love' )) \u5b57\u5178\u68c0\u7d22\uff1a myDict = { 'name' : 'Ming' , 'id' : 1001 , 'age' : 35 } print ( myDict ) for keys in myDict : print ( keys , myDict [ keys ]) myDict . pop ( 'city' ) # \u62a5\u9519\uff0cKeyError: 'city' myDict . pop ( 'id' ) print ( myDict ) # \u8fd0\u884c\u7ed3\u679c\uff1a{'name': 'Ming', 'age': 35}","title":"1.4.5.\u503c\u68c0\u7d22"},{"location":"python/DataStructure/01_PythonFundmantal/#146","text":"\u4e0b\u6807\u8fd0\u7b97\u7b26\u53ef\u4ee5\u7528\u6765\u8bbf\u95ee\u5217\u8868\u3001\u5143\u7ec4\u548c\u5b57\u5178\u91cc\u7684\u5143\u7d20\u3002 \u901a\u8fc7\u6a21\u5f0f\u5339\u914d\u53ef\u4ee5\u4e00\u6b21\u8bbf\u95ee\u591a\u4e2a\u5143\u7d20\u3002 \u793a\u4f8b\uff1a myTuple \u662f\u4e00\u4e2a\u542b\u5185\u5d4c\u5143\u7ec4\u7684\u5143\u7ec4\u3002 myTuple = (( 'r' , 'g' , 'b' ), 'hexString' ) print ( myTuple ) # \u8fd0\u884c\u7ed3\u679c\uff1a # (('r', 'g', 'b'), 'hexString') print ( myTuple [ 0 ]) # \u8fd0\u884c\u7ed3\u679c\uff1a # ('r', 'g', 'b') print ( myTuple [ 0 ][ 0 ]) # \u8fd0\u884c\u7ed3\u679c\uff1a # r print ( myTuple [ 0 ][ 1 ]) # \u8fd0\u884c\u7ed3\u679c\uff1a # g print ( myTuple [ 0 ][ 2 ]) # \u8fd0\u884c\u7ed3\u679c\uff1a # b print ( myTuple [ 1 ]) # \u8fd0\u884c\u7ed3\u679c\uff1a # hexString \u901a\u8fc7\u4e0a\u9762\u7684\u62c6\u89e3\uff0c\u6211\u4eec\u6e05\u695a\u4e86\u5185\u5d4c\u5143\u7ec4\u7684\u7ed3\u6784\u8be6\u7ec6\u60c5\u51b5\u3002 \u4e0b\u9762\uff0c\u6211\u4eec\u901a\u8fc7\u6a21\u5f0f\u5339\u914d\uff0c\u628a\u4e00\u4e2a\u7ed3\u6784\u5206\u914d\u7ed9\u5f62\u5f0f\u5b8c\u5168\u76f8\u540c\u7684\u53e6\u4e00\u4e2a\u7ed3\u6784\u3002\u8fd9\u91cc\u76ee\u6807\u7ed3\u6784 newTuple \u6240\u5305\u542b\u7684\u53d8\u91cf\u4ece\u6e90\u7ed3\u6784 (('r', 'g', 'b'), 'hexString') \u91cc\u7684\u76f8\u5e94\u4f4d\u7f6e\u5904\u83b7\u5f97\u5bf9\u5e94\u7684\u503c\u3002 newTuple = (( 'r' , 'g' , 'b' ), 'hexString' ) print ( newTuple [ 0 ]) # ('r', 'g', 'b') print ( newTuple [ 0 ][ 0 ]) # \u8fd0\u884c\u7ed3\u679c\uff1a # r print ( newTuple [ 0 ][ 1 ]) # \u8fd0\u884c\u7ed3\u679c\uff1a # g print ( newTuple [ 0 ][ 2 ]) # \u8fd0\u884c\u7ed3\u679c\uff1a # b print ( newTuple [ 1 ]) # \u8fd0\u884c\u7ed3\u679c\uff1a # hexString","title":"1.4.6.\u6a21\u5f0f\u5339\u914d\u8bbf\u95ee\u591a\u9879\u96c6"},{"location":"python/DataStructure/01_PythonFundmantal/#15","text":"Python\u652f\u6301\u5b8c\u5168\u51fd\u6570\u5f0f\u7f16\u7a0b\u8bbe\u8ba1\u3002 Python\u5305\u542b\u5f88\u591a\u5185\u7f6e\u51fd\u6570\u3002 Python\u4e5f\u8fd0\u884c\u521b\u5efa\u65b0\u51fd\u6570\uff0c\u53ef\u4ee5\u4f7f\u7528\u9012\u5f52\uff0c\u628a\u51fd\u6570\u4f5c\u4e3a\u6570\u636e\u8fdb\u884c\u4f20\u9012\u548c\u8fd4\u56de\u3002","title":"1.5.\u521b\u5efa\u51fd\u6570"},{"location":"python/DataStructure/01_PythonFundmantal/#151","text":"\u51fd\u6570\u5b9a\u4e49\u8bed\u6cd5\uff1a \u547d\u540d\u51fd\u6570\u540d\u79f0\u548c\u53c2\u6570\u540d\u79f0\u7684\u89c4\u5219\u4e0e\u60ef\u4f8b\u4e0e\u547d\u540d\u53d8\u91cf\u7684\u662f\u76f8\u540c\u7684\u3002 \u5fc5\u9009\u53c2\u6570\u7684\u5217\u8868\u53ef\u4ee5\u4e3a\u7a7a\uff0c\u4e5f\u53ef\u4ee5\u5305\u542b\u7528\u9017\u53f7\u9694\u5f00\u7684\u540d\u79f0\u3002 \u4e0e\u5176\u4ed6\u7f16\u7a0b\u8bed\u8a00\u4e0d\u540c\u7684\u662f\uff0c\u53c2\u6570\u540d\u79f0\u6216\u51fd\u6570\u540d\u79f0\u672c\u8eab\u5e76\u4e0d\u4f1a\u548c\u6570\u636e\u7c7b\u578b\u8fdb\u884c\u5173\u8054\u3002 def < function name > ( < list of parameters > ): < sequence of statements > \u793a\u4f8b\uff1a \u5728\u51fd\u6570\u7684\u6807\u9898\u4e0b\u6709\u4e00\u884c\u7528\u4e09\u5f15\u53f7\u62ec\u8d77\u6765\u7684\u5b57\u7b26\u4e32 \u8fd4\u56den\u7684\u5e73\u65b9\u6570 \uff0c\u8fd9\u662f\u4e00\u4e2a\u6587\u6863\u5b57\u7b26\u4e32\uff08docstring\uff09\u3002 \u5728shell\u91cc\u9762\u8f93\u5165help(square)\u65f6\uff0c\u4f1a\u663e\u793a\u8fd9\u4e2a\u5b57\u7b26\u4e32\u3002 \u5b9a\u4e49\u7684\u6bcf\u4e00\u4e2a\u51fd\u6570\u90fd\u5e94\u8be5\u6709\u6587\u6863\u5b57\u7b26\u4e32\uff0c\u6765\u8bf4\u660e\u8be5\u51fd\u6570\u7684\u529f\u80fd\uff0c\u5e76\u63d0\u4f9b\u76f8\u5173\u7684\u6240\u6709\u53c2\u6570\u4ee5\u53ca\u8fd4\u56de\u503c\u7684\u4fe1\u606f\u3002 \u51fd\u6570\u7684\u53c2\u6570\u548c\u4e34\u65f6\u53d8\u91cf\u53ea\u4f1a\u5728\u51fd\u6570\u8c03\u7528\u7684\u751f\u5b58\u5468\u671f\u5185\u5b58\u5728\uff0c\u5e76\u4e14\u5bf9\u5176\u4ed6\u51fd\u6570\u53ca\u5176\u5916\u56f4\u7a0b\u5e8f\u90fd\u662f\u4e0d\u53ef\u89c1\u7684\u3002 n \u662f\u53c2\u6570\u3002 result \u662f\u4e34\u65f6\u53d8\u91cf\u3002 \u5982\u679c\u51fd\u6570\u4e0d\u5305\u542b return \u8bed\u53e5\u65f6\uff0c\u5b83\u5c06\u5728\u6700\u540e\u4e00\u6761\u8bed\u53e5\u6267\u884c\u4e4b\u540e\u81ea\u52a8\u8fd4\u56de None \u503c\u3002 \u7528 = \u628a\u53c2\u6570\u6307\u5b9a\u4e3a\u6709\u9ed8\u8ba4\u503c\u7684\u53ef\u9009\u53c2\u6570\u3002 \u5728\u53c2\u6570\u5217\u8868\u4e2d\uff0c\u5fc5\u9009\u53c2\u6570\uff08\u6ca1\u6709\u9ed8\u8ba4\u503c\u7684\u53c2\u6570\uff09\u5fc5\u987b\u4f4d\u4e8e\u53ef\u9009\u53c2\u6570\u4e4b\u524d\u3002 def square ( n ): \"\"\"\u8fd4\u56den\u7684\u5e73\u65b9\u6570\"\"\" result = n ** 2 return result print ( square ( 5 ))","title":"1.5.1.\u51fd\u6570\u5b9a\u4e49"},{"location":"python/DataStructure/01_PythonFundmantal/#152","text":"\u9012\u5f52\u51fd\u6570\uff08recursive function\uff09\u662f\u6307\u4f1a\u8c03\u7528\u81ea\u8eab\u7684\u51fd\u6570\u3002 \u4e3a\u4e86\u9632\u6b62\u51fd\u6570\u65e0\u9650\u5730\u91cd\u590d\u8c03\u7528\u81ea\u8eab\uff0c\u4ee3\u7801\u4e2d\u5fc5\u987b\u81f3\u5c11\u6709\u4e00\u6761\u7528\u6765\u67e5\u9a8c\u6761\u4ef6\u7684\u9009\u62e9\u8bed\u53e5\uff0c\u7528\u4e8e\u786e\u5b9a\u63a5\u4e0b\u6765\u8981\u7ee7\u7eed\u9012\u5f52\u8fd8\u662f\u505c\u6b62\u9012\u5f52\u3002\u8fd9\u4e2a\u68c0\u67e5\u6761\u4ef6\u8bed\u53e5\u79f0\u4e3a\u57fa\u672c\u60c5\u51b5\uff08base case\uff09\u3002 \u793a\u4f8b\uff1a\u4e0b\u9762\u662f\u901a\u8fc7\u5faa\u73af\u5b9e\u73b0\u8f93\u51fa\u4ece\u7ed9\u5b9a\u7684\u6700\u5c0f\u503c\u5230\u6700\u5927\u503c\u4e4b\u95f4\u7684\u6574\u6570\u548c\u3002 def mySum ( lower , upper ): \"\"\"\u5bf9\u7ed9\u5b9a\u7684\u6700\u5c0f\u503c\u5230\u6700\u5927\u503c\u4e4b\u95f4\u7684\u6574\u6570\u6c42\u548c; lower:\u6700\u5c0f\u503c; upper:\u6700\u5927\u503c;\"\"\" result = 0 while ( lower <= upper ): result = result + lower lower += 1 return result print ( mySum ( 1 , 10 )) # \u8fd0\u884c\u7ed3\u679c\uff1a # 55 \u7528\u9012\u5f52\u51fd\u6570\u6539\u5199\u4e0a\u8ff0\u51fd\u6570\u3002 def mySum ( lower , upper ): \"\"\"\u5bf9\u7ed9\u5b9a\u7684\u6700\u5c0f\u503c\u5230\u6700\u5927\u503c\u4e4b\u95f4\u7684\u6574\u6570\u6c42\u548c; lower:\u6700\u5c0f\u503c; upper:\u6700\u5927\u503c;\"\"\" if lower <= upper : return lower + mySum ( lower + 1 , upper ) else : return 0 print ( mySum ( 1 , 10 )) # \u8fd0\u884c\u7ed3\u679c\uff1a # 55 \u901a\u5e38\u6765\u8bf4\uff0c\u9012\u5f52\u51fd\u6570\u81f3\u5c11\u6709\u4e00\u4e2a\u53c2\u6570\u3002 \u8fd9\u4e2a\u53c2\u6570\u7684\u503c\u4f1a\u88ab\u7528\u6765\u5bf9\u9012\u5f52\u8fc7\u7a0b\u7684\u57fa\u672c\u60c5\u51b5\u8fdb\u884c\u5224\u5b9a\uff0c\u4ece\u800c\u51b3\u5b9a\u662f\u5426\u8981\u7ed3\u675f\u6574\u4e2a\u8c03\u7528\u3002 \u5728\u6bcf\u6b21\u9012\u5f52\u8c03\u7528\u4e4b\u524d\uff0c\u8fd9\u4e2a\u503c\u4e5f\u4f1a\u88ab\u8fdb\u884c\u67d0\u79cd\u65b9\u5f0f\u7684\u4fee\u6539\u3002 \u6bcf\u6b21\u5bf9\u8fd9\u4e2a\u503c\u7684\u4fee\u6539\uff0c\u90fd\u5e94\u8be5\u4ea7\u751f\u4e00\u4e2a\u65b0\u6570\u636e\u503c\uff0c\u53ef\u4ee5\u8ba9\u51fd\u6570\u6700\u7ec8\u8fbe\u5230\u57fa\u672c\u60c5\u51b5\u3002 \u4e3a\u4e86\u5bf9 mySum \u51fd\u6570\u7684\u9012\u5f52\u8fdb\u884c\u8ddf\u8e2a\uff0c\u53ef\u4ee5\u5c1d\u8bd5\u6dfb\u52a0\u4e00\u4e2a\u4ee3\u8868\u7f29\u8fdb\u8fb9\u8ddd\u7684\u53c2\u6570\u5e76\u4e14\u6dfb\u52a0\u4e00\u4e9bprint\u8bed\u53e5\u3002\u8fd9\u6837\u5728\u6bcf\u6b21\u8c03\u7528\u65f6\uff0c\u51fd\u6570\u7684\u7b2c\u4e00\u6761\u8bed\u53e5\u4f1a\u8ba1\u7b97\u7f29\u8fdb\u6570\u91cf\uff0c\u7136\u540e\u518d\u6253\u5370\u4e24\u4e2a\u53c2\u6570\u7684\u503c\uff0c\u6bcf\u6b21\u8fd4\u56de\u8c03\u7528\u4e4b\u524d\u7684\u8fd4\u56de\u503c\u65f6\u90fd\u4f7f\u7528\u76f8\u540c\u7684\u7f29\u8fdb\uff0c\u5c31\u53ef\u4ee5\u5b9e\u73b0\u5bf9\u4e24\u4e2a\u53c2\u6570\u7684\u503c\u4ee5\u53ca\u6bcf\u6b21\u8c03\u7528\u7684\u8fd4\u56de\u503c\u8fdb\u884c\u8ddf\u8e2a\u3002 def mySum ( lower , upper , margin = 0 ): \"\"\"\u5bf9\u7ed9\u5b9a\u7684\u6700\u5c0f\u503c\u5230\u6700\u5927\u503c\u4e4b\u95f4\u7684\u6574\u6570\u6c42\u548c\uff0c\u901a\u8fc7\u9636\u68af\u65b9\u5f0f\u8f93\u51fa; lower:\u6700\u5c0f\u503c; upper:\u6700\u5927\u503c;\"\"\" blanks = \" \" * margin print ( blanks , lower , upper ) if lower <= upper : result = lower + mySum ( lower + 1 , upper , margin + 4 ) print ( blanks , result ) return result else : print ( blanks , 0 ) return 0 print ( mySum ( 1 , 5 )) # \u8fd0\u884c\u7ed3\u679c\uff1a # 1 5 # 2 5 # 3 5 # 4 5 # 5 5 # 6 5 # 0 # 5 # 9 # 12 # 14 # 15 # 15","title":"1.5.2.\u51fd\u6570\u9012\u5f52"},{"location":"python/DataStructure/01_PythonFundmantal/#153","text":"\u5d4c\u5957\u51fd\u6570\u7c7b\u4f3c\u4e8e\u5d4c\u5957\u5faa\u73af\uff0c\u5c31\u662f\u51fd\u6570\u5185\u53c8\u5d4c\u5957\u7740\u51fd\u6570\u3002\u5373\uff0c\u51fd\u6570\u7684\u5b9a\u4e49\u5d4c\u5957\u5728\u4e00\u4e2a\u51fd\u6570\u7684\u8bed\u53e5\u5e8f\u5217\u91cc\u3002 \u5148\u770b\u4e00\u4e2a\u666e\u901a\u4f8b\u5b50\uff1a # \u5b9a\u4e49inner\u51fd\u6570 def inner (): print ( '\u6211\u662finner' ) # \u5b9a\u4e49outer\u51fd\u6570\uff0couter\u51fd\u6570\u8c03\u7528inner\u51fd\u6570 def outer (): print ( '\u6211\u662fouter' ) inner () outer () # \u8fd0\u884c\u7ed3\u679c\uff1a # \u6211\u662fouter # \u6211\u662finner \u6539\u5199\u4e0a\u9762\u7684\u4ee3\u7801\uff0c\u628a inner \u51fd\u6570\u5199\u5728 outer \u51fd\u6570\u91cc\u9762\u3002 # \u5b9a\u4e49outer\u51fd\u6570\uff0couter\u51fd\u6570\u5185\u5d4cinner\u51fd\u6570\uff0c\u5e76\u8c03\u7528inner\u51fd\u6570 def outer (): print ( '\u6211\u662fouter' ) # \u5b9a\u4e49inner\u51fd\u6570 def inner (): print ( '\u6211\u662finner' ) inner () outer () # \u8fd0\u884c\u7ed3\u679c\uff1a # \u6211\u662fouter # \u6211\u662finner \u4e0a\u9762\u7684\u5916\u5c42 outer \u51fd\u6570\u548c\u5185\u5c42 inner \u51fd\u6570\u90fd\u6ca1\u6709\u53d8\u91cf\u548c\u53c2\u6570\u3002 \u73b0\u5728\u4fee\u6539\u4e0a\u9762\u7684\u4ee3\u7801\uff0c\u6211\u4eec\u4f20\u5165\u53c2\u6570\u548c\u53d8\u91cf\uff0c\u7136\u540e\u628a\u5916\u5c42\u51fd\u6570\u8fd4\u56de\u503c\u6307\u5411\u5185\u5c42\u51fd\u6570\u540d\u3002 def outer (): a = 1 print ( '\u6211\u662fouter' ) # \u5b9a\u4e49inner\u51fd\u6570 def inner (): print ( '\u6211\u662finner' ) print ( 'inner\u6253\u5370: ' , a ) # \u8fd4\u56de\u5185\u5c42inner\u51fd\u6570\u540d return inner f = outer () # \u8fd0\u884c\u7ed3\u679c\uff1a # \u6211\u662fouter f () # \u8fd0\u884c\u7ed3\u679c\uff1a # \u6211\u662finner # inner\u6253\u5370: 1 \u5728\u4e0a\u9762\u7684\u4f8b\u5b50\u4e2d\uff1a f = outer() \u8c03\u7528\u5916\u5c42 outer \u51fd\u6570\uff0c\u5e76\u628a\u7ed3\u679c\u8d4b\u503c\u7ed9 f \u3002\u6ce8\u610f\uff0cinner\u51fd\u6570\u5e76\u6ca1\u6709\u88ab\u6267\u884c\u3002 f \u5176\u5b9e\u5c31\u662f inner \uff0c\u6307\u5411 inner \u7684\u5185\u5b58\u7a7a\u95f4\u3002\u901a\u8fc7 f() \u9a8c\u8bc1\u4e86\u8fd9\u4e00\u70b9\uff0c outer \u51fd\u6570\u4e2d\u7684\u53d8\u91cf a \u88ab\u6253\u5370\u51fa\u6765\u4e86\u3002 \u4e0a\u9762\u4f8b\u5b50\u4e2d outer \u5c31\u662f\u95ed\u5305\u51fd\u6570\uff0c\u5916\u5c42\u51fd\u6570\u7684\u53d8\u91cf\u53ef\u4ee5\u88ab\u5185\u5c42\u51fd\u6570\u8c03\u7528\uff0c\u7c7b\u4f3c\u4e8e\u5c01\u88c5\u7684\u6548\u679c\u3002\u5185\u5c42\u51fd\u6570\u4e0d\u4f1a\u7acb\u523b\u88ab\u6267\u884c\uff0c\u5f53\u518d\u6b21\u8c03\u7528\u65f6\uff0c\u5185\u5c42\u51fd\u6570\u624d\u4f1a\u6267\u884c\u3002 \u95ed\u5305\u51fd\u6570\u9700\u8981\u6709\u4e09\u4e2a\u6761\u4ef6\uff1a \u5fc5\u987b\u6709\u4e00\u4e2a\u5185\u5d4c\u51fd\u6570\uff0c\u4f8b\u5982\u51fd\u6570 inner \uff1b \u5185\u90e8\u51fd\u6570\u5f15\u7528\u5916\u90e8\u51fd\u6570\u53d8\u91cf\uff0c\u4f8b\u5982\u53d8\u91cf a \uff1b \u5916\u90e8\u51fd\u6570\u5fc5\u987b\u8fd4\u56de\u5185\u5d4c\u51fd\u6570\uff0c\u4f8b\u5982 outer \u51fd\u6570\u4e2d\u7684 return inner \uff1b \u5bf9\u4e0a\u9762\u7684\u4ee3\u7801\u518d\u8fdb\u884c\u4fee\u6539\uff0c\u5728 inner \u51fd\u6570\u4e2d\u518d\u6dfb\u52a0\u4e00\u4e2a\u540c\u540d\u7684\u53d8\u91cfa\u3002\u4ece\u7ed3\u679c\u53ef\u4ee5\u5f97\u51fa\u7ed3\u8bba\uff0c inner \u51fd\u6570\u4f18\u5148\u5728\u5185\u90e8\u67e5\u627e\u53d8\u91cf a=5 \u3002 def outer (): a = 1 print ( '\u6211\u662fouter' ) # \u5b9a\u4e49inner\u51fd\u6570 def inner (): a = 5 print ( '\u6211\u662finner' ) print ( 'inner\u6253\u5370: ' , a ) return inner f = outer () # \u8fd0\u884c\u7ed3\u679c\uff1a # \u6211\u662fouter f () # \u8fd0\u884c\u7ed3\u679c\uff1a # \u6211\u662finner # inner\u6253\u5370: 5 \u7ed3\u8bba\uff1a\u5185\u5c42\u51fd\u6570\u4e2d\u8c03\u7528\u7684\u53d8\u91cf\uff1a \u9996\u5148\u4f1a\u4ece\u5185\u5c42\u51fd\u6570\u4e2d\u627e\uff0c \u627e\u4e0d\u5230\u5c31\u53bb\u5916\u5c42\u51fd\u6570\u4e2d\u627e\uff0c \u518d\u627e\u4e0d\u5230\u5c31\u5230\u51fd\u6570\u5916\u4e2d\u627e\uff0c \u518d\u627e\u4e0d\u5230\u5c31\u5230\u5185\u7f6e\u7684\u6a21\u5757\u4e2d\u627e\uff0c \u518d\u627e\u4e0d\u5230\uff0c\u5c31\u62a5\u9519\u3002 \u8fd9\u5c31\u662f\u4f5c\u7528\u57df\u7684\u6982\u5ff5\u3002 \u7ee7\u7eed\u4fee\u6539\u4e0a\u9762\u7684\u4ee3\u7801\uff0c\u5728 inner \u51fd\u6570\u4e2d\u4fee\u6539 outer \u51fd\u6570\u4e2d\u53d8\u91cf a \u7684\u503c\uff0c\u8fd0\u884c\u7ed3\u679c\u62a5\u9519\u3002\u7ed3\u8bba\uff1a\u5185\u5c42\u51fd\u6570\u4e0d\u80fd\u4fee\u6539\u5916\u5c42\u51fd\u6570\u7684\u53d8\u91cf\u503c\u3002 def outer (): a = 1 print ( '\u6211\u662fouter' ) # \u5b9a\u4e49inner\u51fd\u6570 def inner (): a += 5 print ( '\u6211\u662finner' ) print ( 'inner\u6253\u5370: ' , a ) return inner f = outer () # \u8fd0\u884c\u7ed3\u679c\uff1a # \u6211\u662fouter f () # \u8fd0\u884c\u7ed3\u679c\uff1a # UnboundLocalError: local variable 'a' referenced before assignment \u4fee\u6b63\u4e0a\u9762\u7684\u4ee3\u7801\u3002\u5728 inner \u51fd\u6570\u4e2d\u5bf9\u53d8\u91cfa\u6dfb\u52a0\u4e00\u4e2a nonlocal \u7684\u58f0\u660e\uff0c\u5c31\u53ef\u4ee5\u5728 inner \u51fd\u6570\u4e2d\u4fee\u6539\u5916\u5c42outer\u51fd\u6570\u7684\u53d8\u91cf a \u7684\u503c\u3002 def outer (): a = 1 print ( '\u6211\u662fouter' ) # \u5b9a\u4e49inner\u51fd\u6570 def inner (): nonlocal a a += 5 print ( '\u6211\u662finner' ) print ( 'inner\u6253\u5370: ' , a ) return inner f = outer () # \u8fd0\u884c\u7ed3\u679c\uff1a # \u6211\u662fouter f () # \u8fd0\u884c\u7ed3\u679c\uff1a # \u6211\u662finner # inner\u6253\u5370: 6 \u4e0b\u9762\u8fd9\u6bb5\u4ee3\u7801\u662f\u9636\u4e58\uff08factorial\uff09\u9012\u5f52\u51fd\u6570\u7684\u4e24\u4e2a\u4e0d\u540c\u7684\u5b9a\u4e49\u3002 \u7b2c\u4e00\u4e2a\u5b9a\u4e49\u4f7f\u7528\u4e86\u5d4c\u5957\u7684\u8f85\u52a9\u51fd\u6570 recurse \u6765\u5bf9\u6240\u9700\u8981\u7684\u53c2\u6570\u8fdb\u884c\u9012\u5f52\uff1b\u8fd9\u91cc\u7684 factorial \u51fd\u6570\u5c31\u662f\u95ed\u5305\u51fd\u6570\u3002 \u7b2c\u4e00\u6b65\uff1a\u7b2c\u4e00\u6b21\u8c03\u7528 factorial() \u51fd\u6570\uff0c\u5373 n=5 \uff1b \u7b2c\u4e8c\u6b65\uff1a\u7b2c\u4e00\u6b21\u8c03\u7528\u5185\u5c42\u51fd\u6570 recurse() \uff0c\u4f46\u4e0d\u4f1a\u7acb\u523b\u88ab\u6267\u884c\uff1b \u7b2c\u4e09\u6b65\uff0c\u6267\u884c return recurse(5, 1) \uff0c\u5bf9\u53c2\u6570 product \u521d\u59cb\u5316\u8d4b\u503c 1 \u7b2c\u56db\u6b65\uff1a\u6267\u884c return recurse(5, 5 * 1) \uff0c\u6b64\u65f6 n=5 \uff0c product=1 \u3002 \u7b2c\u4e94\u6b65\uff1a\u6267\u884c return recurse(4, 4 * 5) \uff0c\u6b64\u65f6 n=4 \uff0c product=5 \u3002 \u7b2c\u516d\u6b65\uff1a\u6267\u884c return recurse(3, 3 * 20) \uff0c\u6b64\u65f6 n=3 \uff0c product=20 \u3002 \u7b2c\u4e03\u6b65\uff1a\u6267\u884c return recurse(2, 2 * 60) \uff0c\u6b64\u65f6 n=2 \uff0c product=60 \u3002 \u7b2c\u516b\u6b65\uff1a\u6267\u884c return recurse(1, 1 * 120) \uff0c\u6b64\u65f6 n=1 \uff0c product=120 \u3002 \u7b2c\u4e5d\u6b65\uff1a\u6b64\u65f6 n=1 \uff0c\u6267\u884c return product \uff0c\u5373 return 120 \uff0c\u7ed3\u675f\u3002 \u7b2c\u4e8c\u4e2a\u5b9a\u4e49\u5219\u662f\u4e3a\u7b2c\u4e8c\u4e2a\u53c2\u6570\u63d0\u4f9b\u4e86\u9ed8\u8ba4\u503c\uff0c\u4ece\u800c\u7b80\u5316\u4e86\u8bbe\u8ba1\u3002 # \u7b2c\u4e00\u4e2a\u5b9a\u4e49 def factorial ( n ): \"\"\"\u8fd4\u56de n \u7684\u9636\u4e58\"\"\" def recurse ( n , product ): \"\"\"\u8ba1\u7b97\u9636\u4e58\u7684\u5e2e\u52a9\u5668\"\"\" print ( n , product ) # \u63d2\u5165\u8fd9\u4e00\u53e5\u662f\u4e3a\u4e86\u80fd\u770b\u6e05\u695a\u6bcf\u4e00\u6b21\u9012\u5f52\u8c03\u7528\u7684n\u548cproduct\u53d8\u5316 if n == 1 : return product else : return recurse ( n - 1 , n * product ) return recurse ( n , 1 ) f = factorial ( 5 ) # \u8fd0\u884c\u7ed3\u679c 5 1 4 5 3 20 2 60 1 120 # \u7b2c\u4e8c\u4e2a\u5b9a\u4e49 def factorial ( n , product = 1 ): \"\"\"\u8fd4\u56de n \u7684\u9636\u4e58\"\"\" if n == 1 : return product else : return factorial ( n - 1 , n * product ) print ( factorial ( 5 )) # \u8fd0\u884c\u7ed3\u679c # 120","title":"1.5.3.\u51fd\u6570\u5d4c\u5957"},{"location":"python/DataStructure/01_PythonFundmantal/#154","text":"\u51fd\u6570\u672c\u8eab\u4e5f\u662f\u4e00\u79cd\u72ec\u7279\u7684\u6570\u636e\u5bf9\u8c61\u3002\u53ef\u4ee5\u628a\u5b83\u4eec\u8d4b\u7ed9\u53d8\u91cf\u3001\u5b58\u50a8\u5728\u6570\u636e\u7ed3\u6784\u91cc\u3001\u4f5c\u4e3a\u53c2\u6570\u4f20\u9012\u7ed9\u5176\u4ed6\u51fd\u6570\u4ee5\u53ca\u4f5c\u4e3a\u5176\u4ed6\u51fd\u6570\u7684\u503c\u8fd4\u56de\u3002 \u9ad8\u9636\u51fd\u6570\uff08higher-order function\uff09\uff1a\u5b83\u63a5\u6536\u53e6\u4e00\u4e2a\u51fd\u6570\u4f5c\u4e3a\u53c2\u6570\uff0c\u5e76\u4e14\u4ee5\u67d0\u79cd\u65b9\u5f0f\u5e94\u7528\u8be5\u51fd\u6570\u3002 Python\u6709\u4e24\u4e2a\u5185\u7f6e\u7684\u9ad8\u9636\u51fd\u6570\uff0c\u5206\u522b\u662f map \u548c filter \uff0c\u5b83\u4eec\u53ef\u4ee5\u7528\u4e8e\u5904\u7406\u53ef\u8fed\u4ee3\u5bf9\u8c61\u3002 map \u51fd\u6570\u4f1a\u63a5\u6536\u53e6\u4e00\u4e2a\u51fd\u6570\u548c\u4e00\u4e2a\u53ef\u8fed\u4ee3\u5bf9\u8c61\u4f5c\u4e3a\u53c2\u6570\uff0c\u8fd4\u56de\u53e6\u4e00\u4e2a\u53ef\u8fed\u4ee3\u5bf9\u8c61\u3002\u8fd9\u4e2a\u51fd\u6570\u4f1a\u628a\u4f5c\u4e3a\u53c2\u6570\u4f20\u9012\u7684\u51fd\u6570\u5e94\u7528\u5728\u53ef\u8fed\u4ee3\u5bf9\u8c61\u91cc\u7684\u6bcf\u4e2a\u5143\u7d20\u4e0a\u3002\u7b80\u5355\u6765\u8bf4\uff0c map \u51fd\u6570\u4f1a\u5bf9\u53ef\u8fed\u4ee3\u5bf9\u8c61\u91cc\u7684\u6bcf\u4e2a\u5143\u7d20\u8fdb\u884c\u8f6c\u6362\u3002 filter \u4f1a\u63a5\u53d7\u4e00\u4e2a\u5e03\u5c14\u51fd\u6570\u548c\u4e00\u4e2a\u53ef\u8fed\u4ee3\u5bf9\u8c61\u4f5c\u4e3a\u53c2\u6570\uff0c\u8fd4\u56de\u8fd9\u6837\u4e00\u4e2a\u53ef\u8fed\u4ee3\u5bf9\u8c61\uff0c\u5b83\u7684\u6bcf\u4e00\u4e2a\u5143\u7d20\u90fd\u4f1a\u88ab\u4f20\u9012\u7ed9\u5e03\u5c14\u51fd\u6570\uff0c\u5982\u679c\u8fd9\u4e2a\u51fd\u6570\u8fd4\u56deTrue\uff0c\u90a3\u4e48\u8fd9\u4e2a\u5143\u7d20\u5c06\u88ab\u4fdd\u7559\u5728\u8fd4\u56de\u7684\u53ef\u8fed\u4ee3\u5bf9\u8c61\u91cc\uff1b\u5426\u5219\uff0c\u8fd9\u4e2a\u5143\u7d20\u5c06\u88ab\u5220\u9664\u3002\u7b80\u5355\u8bf4\uff0c filter \u51fd\u6570\u4f1a\u628a\u6240\u6709\u80fd\u591f\u901a\u8fc7\u68c0\u9a8c\u7684\u5143\u7d20\u4fdd\u7559\u5728\u53ef\u8fed\u4ee3\u5bf9\u8c61\u91cc\u3002 functools.reduce \u901a\u8fc7\u628a\u63a5\u6536\u4e24\u4e2a\u53c2\u6570\u7684\u51fd\u6570\u7684\u7ed3\u679c\u4ee5\u53ca\u8fed\u4ee3\u5bf9\u8c61\u7684\u4e0b\u4e00\u4e2a\u5143\u7d20\u518d\u6b21\u5e94\u7528\u4e8e\u8fd9\u4e2a\u63a5\u6536\u4e24\u4e2a\u53c2\u6570\u7684\u51fd\u6570\uff0c\u6765\u628a\u53ef\u8fed\u4ee3\u5bf9\u8c61\u8ba1\u7b97\u6210\u5355\u4e00\u7684\u503c\u3002 \u793a\u4f8b\uff1a\u628a\u4e00\u4e2a\u6574\u6570\u5217\u8868\u8f6c\u6362\u6210\u53e6\u4e00\u4e2a\u5305\u542b\u8fd9\u4e9b\u6574\u6570\u7684\u5b57\u7b26\u4e32\u5f62\u5f0f\u7684\u5217\u8868\u3002 \u4f20\u7edf\u65b9\u6cd5\u5b9e\u73b0\uff1a oldList = [ 0 , 1 , 3 , 5 , 7 , 9 ] newList = [] for i in oldList : newList . append ( str ( i )) print ( newList ) # ['0', '1', '3', '5', '7', '9'] \u7528 map \u5b9e\u73b0\uff1a oldList = [ 0 , 1 , 3 , 5 , 7 , 9 ] newList = [] newList = list ( map ( str , oldList )) print ( newList ) # ['0', '1', '3', '5', '7', '9'] \u62d3\u5c55\uff1a\u628a\u4e00\u4e2a\u6574\u6570\u5217\u8868\u4e2d\u7684\u6b63\u6574\u6570\u8f6c\u6362\u6210\u53e6\u4e00\u4e2a\u5305\u542b\u8fd9\u4e9b\u6574\u6570\u7684\u5b57\u7b26\u4e32\u5f62\u5f0f\u7684\u5217\u8868\u3002 \u4f20\u7edf\u5b9e\u73b0\uff1a oldList = [ 0 , 1 , 3 , 5 , 7 , 9 ] newList = [] for i in oldList : if i > 0 : newList . append (( str ( i ))) print ( newList ) # ['1', '3', '5', '7', '9'] \u4f7f\u7528 filter \u5b9e\u73b0\uff1a oldList = [ 0 , 1 , 3 , 5 , 7 , 9 ] newList = [] def isPositive ( n ): if n > 0 : return True # \u521b\u5efa\u4e00\u4e2a\u4e0d\u5305\u542b\u4efb\u4f55\u96f6\u7684\u53ef\u8fed\u4ee3\u5bf9\u8c61 newList = list ( filter ( isPositive , oldList )) print ( newList ) # [1, 3, 5, 7, 9] \u793a\u4f8b\uff1a\u8ba1\u7b97\u4ece1\u523010\u7684\u4e58\u79ef\u5e76\u8f93\u51fa\u7ed3\u679c\u3002 \u901a\u8fc7 for \u5faa\u73af\u5b9e\u73b0\uff1a result = 1 value = 1 for value in range ( 1 , 11 ): result *= value value += 1 print ( result ) # \u8fd0\u884c\u7ed3\u679c # 3628800 \u901a\u8fc7 functools.reduce \u5faa\u73af\u5b9e\u73b0\uff1a import functools result = functools . reduce ( lambda x , y : x * y , range ( 1 , 11 )) print ( result ) # 3628800","title":"1.5.4.\u9ad8\u9636\u51fd\u6570"},{"location":"python/DataStructure/01_PythonFundmantal/#155lambda","text":"\u8bed\u6cd5\u683c\u5f0f\uff1a lambda < argument list > : < expression > lambda\u8868\u8fbe\u5f0f\u4e0d\u80fd\u50cf\u5176\u4ed6Python\u51fd\u6570\u90a3\u6837\u5305\u542b\u4e00\u6574\u4e2a\u8bed\u53e5\u5e8f\u5217\u3002 \u62d3\u5c55\uff1a\u7528lambda\u5b9e\u73b0\u628a\u4e00\u4e2a\u6574\u6570\u5217\u8868\u4e2d\u7684\u6b63\u6574\u6570\u8f6c\u6362\u6210\u53e6\u4e00\u4e2a\u5305\u542b\u8fd9\u4e9b\u6574\u6570\u7684\u5b57\u7b26\u4e32\u5f62\u5f0f\u7684\u5217\u8868\uff0c\u5b9e\u9645\u5c31\u662f\u901a\u8fc7\u4f7f\u7528\u533f\u540d\u7684\u5e03\u5c14\u51fd\u6570\u6765\u4ece\u6574\u6570\u5217\u8868\u91cc\u5254\u9664\u6240\u6709\u4e3a\u96f6\u7684\u5143\u7d20\u3002 oldList = [ 0 , 1 , 3 , 5 , 7 , 9 ] newList = [] newList = list ( filter ( lambda i : i > 0 , oldList )) print ( newList ) # [1, 3, 5, 7, 9]","title":"1.5.5.lambda\u4e0e\u533f\u540d\u51fd\u6570"},{"location":"python/DataStructure/01_PythonFundmantal/#16","text":"\u8003\u8651\u4e24\u79cd\u5f02\u5e38\u60c5\u51b5\uff1a Python\u865a\u62df\u673a\u5728\u7a0b\u5e8f\u6267\u884c\u671f\u95f4\u9047\u5230\u4e86\u8bed\u4e49\u9519\u8bef\uff0c\u5219\u4f1a\u5f97\u5230\u76f8\u5e94\u7684\u9519\u8bef\u6d88\u606f\uff0c\u4ece\u800c\u5f15\u53d1\u4e00\u4e2a\u5f02\u5e38\u5e76\u4e14\u6682\u505c\u7a0b\u5e8f\u3002\u8bed\u4e49\u9519\u8bef\u5305\u62ec\u4f8b\u5982\u672a\u5b9a\u4e49\u7684\u53d8\u91cf\u540d\u3001\u9664\u4ee50\u4ee5\u53ca\u8d85\u51fa\u5217\u8868\u8303\u56f4\u7684\u7d22\u5f15\u7b49\u3002 \u7528\u6237\u5f15\u8d77\u7684\u67d0\u4e9b\u9519\u8bef\uff0c\u4f8b\u5982\uff0c\u671f\u671b\u8f93\u5165\u6570\u5b57\u7684\u65f6\u5019\u8f93\u5165\u4e86\u5176\u4ed6\u5b57\u7b26\u3002\u5bf9\u4e8e\u5728\u8fd9\u4e9b\u60c5\u51b5\u4e0b\u4ea7\u751f\u7684\u5f02\u5e38\uff0c\u7a0b\u5e8f\u4e0d\u5e94\u8be5\u505c\u6b62\u6267\u884c\uff0c\u800c\u5e94\u8be5\u5bf9\u8fd9\u4e9b\u5f02\u5e38\u8fdb\u884c\u6355\u83b7\uff0c\u5e76\u4e14\u5141\u8bb8\u7528\u6237\u4fee\u6b63\u9519\u8bef\u3002 Python\u63d0\u4f9b\u4e86try-except\u8bed\u53e5\uff0c\u53ef\u4ee5\u8ba9\u7a0b\u5e8f\u6355\u83b7\u5f02\u5e38\u5e76\u6267\u884c\u76f8\u5e94\u7684\u6062\u590d\u64cd\u4f5c\u3002 try \u5b50\u53e5\u4e2d\u7684\u8bed\u53e5\u5c06\u5148\u88ab\u6267\u884c\u3002\u5982\u679c\u8fd9\u4e9b\u8bed\u53e5\u4e2d\u7684\u4e00\u6761\u5f15\u53d1\u4e86\u5f02\u5e38\uff0c\u90a3\u4e48\u63a7\u5236\u6743\u4f1a\u7acb\u5373\u8f6c\u79fb\u5230 except \u5b50\u53e5\u53bb\u3002 \u5982\u679c\u5f15\u53d1\u7684\u5f02\u5e38\u7c7b\u578b\u548c\u8fd9\u4e2a\u5b50\u53e5\u91cc\u7684\u7c7b\u578b\u4e00\u81f4\uff0c\u90a3\u4e48\u4f1a\u6267\u884c\u5b83\u91cc\u9762\u7684\u8bed\u53e5\uff1b \u5426\u5219\uff0c\u5c06\u8f6c\u79fb\u5230try-except\u8bed\u53e5\u7684\u8c03\u7528\u8005\uff0c\u5e76\u57fa\u4e8e\u8c03\u7528\u94fe\u5411\u4e0a\u4f20\u9012\uff0c\u76f4\u5230\u8fd9\u4e2a\u5f02\u5e38\u88ab\u6210\u529f\u6355\u83b7\uff0c\u6216\u8005\u662f\u7a0b\u5e8f\u56e0\u9519\u8bef\u6d88\u606f\u800c\u505c\u6b62\u6267\u884c\u3002 \u5982\u679c try \u5b50\u53e5\u91cc\u7684\u8bed\u53e5\u6ca1\u6709\u5f15\u53d1\u4efb\u4f55\u5f02\u5e38\uff0c\u90a3\u4e48\u4f1a\u8df3\u8fc7 except \u5b50\u53e5\u5e76\u7ee7\u7eed\u6267\u884c\uff0c\u76f4\u5230try-except\u8bed\u53e5\u7684\u672b\u5c3e\u3002 try : < statements > except < exception type > : < statements > \u901a\u5e38\u6765\u8bf4\uff0c \u5bf9\u4e8e\u5df2\u77e5\u53ef\u80fd\u4f1a\u53d1\u751f\u7684\u5f02\u5e38\u7c7b\u578b\uff0c\u5e94\u8be5\u5c3d\u53ef\u80fd\u5730\u5305\u62ec\u5728\u5728 except \u8bed\u53e5\u91cc\u3002 \u5982\u679c\u4e0d\u77e5\u9053\u5f02\u5e38\u7684\u7c7b\u578b\uff0c\u53ef\u4ee5\u5728 except \u4e2d\u7528\u66f4\u901a\u7528\u7684Exception\u7c7b\u578b\u5339\u914d\u53ef\u80fd\u4f1a\u5f15\u53d1\u7684\u4efb\u4f55\u5f02\u5e38\u3002 \u793a\u4f8b\uff1a def getYourAge ( prompt ): \"\"\"\u63d0\u793a\u7528\u6237\u8f93\u5165\u4e00\u4e2a\u6574\u6570\uff0c\u5426\u5219\u7ed9\u51fa\u9519\u8bef\u63d0\u793a\uff0c\u5e76\u7ee7\u7eed\u63d0\u793a\u7528\u6237\u8f93\u5165\u3002\"\"\" inputStr = input ( prompt ) try : number = int ( inputStr ) return number except ValueError : print ( \"Error in number format:\" , inputStr ) return getYourAge ( prompt ) if __name__ == \"__main__\" : age = getYourAge ( \"Enter your age: \" ) print ( \"Your age is\" , age ) # \u8fd0\u884c\u7ed3\u679c # Enter your age: 3a # Error in number format: 3a # Enter your age: 3.5 # Error in number format: 3.5 # Enter your age: 20 # Your age is 20","title":"1.6.\u6355\u83b7\u5f02\u5e38"},{"location":"python/DataStructure/01_PythonFundmantal/#17","text":"","title":"1.7.\u6587\u4ef6\u53ca\u5176\u64cd\u4f5c"},{"location":"python/DataStructure/01_PythonFundmantal/#171","text":"\u53ef\u4ee5\u628a\u6587\u672c\u6587\u4ef6\u91cc\u7684\u6570\u636e\u770b\u4f5c\u5b57\u7b26\u3001\u5355\u8bcd\u3001\u6570\u5b57\u6216\u8005\u82e5\u5e72\u884c\u6587\u672c\u3002 \u5982\u679c\u628a\u6587\u672c\u6587\u4ef6\u91cc\u7684\u6570\u636e\u5f53\u4f5c\u6574\u6570\u6216\u6d6e\u70b9\u6570\uff0c\u5c31\u5fc5\u987b\u7528\u7a7a\u767d\u5b57\u7b26\uff08\u7a7a\u683c\u3001\u5236\u8868\u7b26\u548c\u6362\u884c\u7b26\uff09\u5c06\u5176\u5206\u9694\u5f00\u3002\u8f93\u51fa\u6216\u8f93\u5165\u5230\u6587\u672c\u6587\u4ef6\u7684\u6240\u6709\u6570\u636e\u5fc5\u987b\u662f\u5b57\u7b26\u4e32\u5f62\u5f0f\u7684\uff0c\u6240\u4ee5\u5728\u8f93\u5165/\u8f93\u51fa\u65f6\u9700\u8981\u505a\u76f8\u5e94\u7684\u7c7b\u578b\u8f6c\u6362\u3002 \u5982\u4e0b\u4f8b\uff1a 34.6 22.33 66.75 77.12 21.44 99.01 Python\u7684open\u51fd\u6570\u63a5\u6536\u4e0b\u9762\u4e24\u4e2a\u4e3b\u8981\u53c2\u6570\uff0c\u6253\u5f00\u4e00\u4e2a\u4e0e\u78c1\u76d8\u6587\u4ef6\u7684\u8fde\u63a5\u5e76\u4e14\u8fd4\u56de\u76f8\u5e94\u7684\u6587\u4ef6\u5bf9\u8c61\u3002 \u6587\u4ef6\u8def\u5f84\uff1b \u6253\u5f00\u6a21\u5f0f\uff1a \u6253\u5f00\u6a21\u5f0f\uff1a r \u8868\u793a\u6587\u4ef6\u53ea\u80fd\u8bfb\u53d6\uff1b w \u8868\u793a\u6587\u4ef6\u53ea\u80fd\u5199\u5165\uff1b a \u8868\u793a\u6253\u5f00\u6587\u4ef6\uff0c\u5728\u539f\u6709\u5185\u5bb9\u7684\u57fa\u7840\u4e0a\u8ffd\u52a0\u5185\u5bb9\uff0c\u5728\u672b\u5c3e\u5199\u5165\uff1b w+ \u8868\u793a\u53ef\u4ee5\u5bf9\u6587\u4ef6\u8fdb\u884c\u8bfb\u5199\u53cc\u91cd\u64cd\u4f5c\uff1b rb \u4ee5\u4e8c\u8fdb\u5236\u683c\u5f0f\u6253\u5f00\u4e00\u4e2a\u6587\u4ef6\uff0c\u7528\u4e8e\u53ea\u8bfb\uff1b wb \u4ee5\u4e8c\u8fdb\u5236\u683c\u5f0f\u6253\u5f00\u4e00\u4e2a\u6587\u4ef6\uff0c\u7528\u4e8e\u53ea\u5199\uff1b ab \u4ee5\u4e8c\u8fdb\u5236\u683c\u5f0f\u6253\u5f00\u4e00\u4e2a\u6587\u4ef6\uff0c\u7528\u4e8e\u8ffd\u52a0\uff1b wb+ \u4ee5\u4e8c\u8fdb\u5236\u683c\u5f0f\u6253\u5f00\u4e00\u4e2a\u6587\u4ef6\uff0c\u7528\u4e8e\u8bfb\u5199\uff1b \u793a\u4f8b\uff1a \u4e3a myfile.txt \u6587\u4ef6\u6253\u5f00\u4e00\u4e2a\u7528\u6765\u8f93\u51fa\u7684\u6587\u4ef6\u5bf9\u8c61\u3002 \u5b57\u7b26\u4e32\u6570\u636e\u901a\u8fc7 write \u65b9\u6cd5\u548c\u6587\u4ef6\u5bf9\u8c61\u5199\u5165\uff08\u6216\u8f93\u51fa\uff09\u5230\u6587\u4ef6\u91cc\u3002 \u8f6c\u4e49\u7b26 \\n \u5b9e\u73b0\u6362\u884c\u3002 \u4f7f\u7528 close \u65b9\u6cd5\u5173\u95ed\u6587\u4ef6\u3002\u5982\u679c\u6ca1\u6709\u5173\u95ed\u8f93\u51fa\u6587\u4ef6\uff0c\u5219\u53ef\u80fd\u5bfc\u81f4\u6570\u636e\u4e22\u5931\u3002 f = open ( \"./docs/python/DataStructure/code/myfile.txt\" , 'w' ) f . write ( \"First line. \\n Second line. \\n \" ) f . close () \u6587\u4ef6myfile.txt\u7684\u5185\u5bb9\uff1a First line. Second line.","title":"1.7.1.\u6587\u672c\u6587\u4ef6\u8bfb\u53d6"},{"location":"python/DataStructure/01_PythonFundmantal/#172","text":"\u6587\u4ef6\u7684 write \u65b9\u6cd5\u63a5\u6536\u4e00\u4e2a\u5b57\u7b26\u4e32\u4f5c\u4e3a\u53c2\u6570\u3002\u56e0\u6b64\uff0c\u5176\u4ed6\u7c7b\u578b\u7684\u6570\u636e\uff08\u5982\u6574\u6570\u6216\u6d6e\u70b9\u6570\uff09\u5728\u5199\u5165\u8f93\u51fa\u6587\u4ef6\u4e4b\u524d\uff0c\u90fd\u5fc5\u987b\u5148\u88ab\u8f6c\u6362\u4e3a\u5b57\u7b26\u4e32\u3002 \u5728Python\u91cc\uff0c\u53ef\u4ee5\u4f7f\u7528 str \u51fd\u6570\u628a\u7edd\u5927\u591a\u6570\u7684\u6570\u636e\u7c7b\u578b\u7684\u503c\u8f6c\u6362\u4e3a\u5b57\u7b26\u4e32\uff0c\u4ee5\u7a7a\u683c\u6216\u6362\u884c\u7b26\u4f5c\u4e3a\u5206\u9694\u7b26\uff0c\u5c06\u5176\u5199\u5165\u6587\u4ef6\u91cc\u3002 \u793a\u4f8b\uff1a\u751f\u6210500\u4e2a\u4ecb\u4e8e1\u548c500\u4e4b\u95f4\u7684\u968f\u673a\u6570\uff0c\u5e76\u8f93\u51fa\u5230\u6587\u672c\u6587\u4ef6\u3002 import random f = open ( \"./docs/python/DataStructure/code/myfile.txt\" , 'w' ) for count in range ( 500 ): number = random . randint ( 1 , 500 ) f . write ( str ( number ) + \" \\n \" ) f . close ()","title":"1.7.2.\u6587\u672c\u6587\u4ef6\u5199\u5165"},{"location":"python/DataStructure/01_PythonFundmantal/#173","text":"\u793a\u4f8b\uff1a\u8bfb\u53d6\u6587\u4ef6\u5185\u5bb9\u3002 import random f = open ( \"./docs/python/DataStructure/code/myfile.txt\" , 'w' ) f . write ( \"First line. \\n Second line. \\n \" ) # \u521d\u59cb\u5316\u6587\u4ef6\u5185\u5bb9 f . close () # \u6253\u5f00\u6587\u4ef6\u8bfb\u53d6\u5185\u5bb9 f = open ( \"./docs/python/DataStructure/code/myfile.txt\" , 'r' ) text1 = f . read () # \u628a\u6587\u4ef6\u7684\u5168\u90e8\u5185\u5bb9\u8f93\u5165\u5355\u4e2a\u5b57\u7b26\u4e32\u4e2d print ( text1 ) # \u8fd0\u884c\u7ed3\u679c\uff1a # First line. # Second line text2 = f . read () # \u518d\u6b21read\uff0c\u5f97\u5230\u4e00\u4e2a\u7a7a\u5b57\u4e32\uff0c\u8868\u8ff0\u5df2\u7ecf\u5230\u8fbe\u6587\u4ef6\u672b\u5c3e\u3002\u8981\u518d\u6b21\u8bfb\u53d6\u9700\u8981\u91cd\u65b0\u6253\u5f00\u6587\u4ef6 print ( \"======\" ) print ( text2 ) # \u8fd0\u884c\u7ed3\u679c\uff1a # ====== # f . close () # \u91cd\u65b0\u6253\u5f00\u6587\u4ef6\u8bfb\u53d6\u5185\u5bb9 f = open ( \"./docs/python/DataStructure/code/myfile.txt\" , 'r' ) for line in f : # \u9010\u884c\u8bfb\u53d6\u6587\u4ef6\u5185\u5bb9 print ( \"======\" ) print ( line ) # \u6bcf\u884c\u90fd\u6709\u4e00\u4e2a\u6362\u884c\u7b26\uff0c\u8fd9\u662fprint\u51fd\u6570\u9ed8\u8ba4\u884c\u4e3a # \u8fd0\u884c\u7ed3\u679c\uff1a # ====== # First line. # ====== # Second line. # f . close () # \u91cd\u65b0\u6253\u5f00\u6587\u4ef6\u8bfb\u53d6\u5185\u5bb9 f = open ( \"./docs/python/DataStructure/code/myfile.txt\" , 'r' ) while True : line = f . readline () # readline\u65b9\u6cd5\u4f1a\u4ece\u8f93\u5165\u7684\u6587\u672c\u91cc\u53ea\u83b7\u53d6\u4e00\u884c\u6570\u636e\uff0c\u5e76\u4e14\u8fd4\u56de\u8fd9\u4e2a\u5305\u542b\u6362\u884c\u7b26\u7684\u5b57\u7b26\u4e32\u3002\u5982\u679creadline\u9047\u5230\u4e86\u6587\u4ef6\u672b\u5c3e\uff0c\u90a3\u4e48\u4f1a\u8fd4\u56de\u7a7a\u5b57\u7b26\u4e32\u3002 if line == \"\" : break print ( \"******\" ) print ( line ) # \u8fd0\u884c\u7ed3\u679c\uff1a # ****** # First line. # ****** # Second line. # f . close () # \u91cd\u65b0\u6253\u5f00\u6587\u4ef6\u8bfb\u53d6\u5185\u5bb9 f = open ( \"./docs/python/DataStructure/code/myfile.txt\" , 'r' ) line = f . readlines () # readlines\u65b9\u6cd5\u5219\u662f\u8bfb\u53d6\u6240\u6709\u884c\uff0c\u8fd4\u56de\u7684\u662f\u6240\u6709\u884c\u7ec4\u6210\u7684\u5217\u8868\u3002 print ( line ) # \u8fd0\u884c\u7ed3\u679c\uff1a # ['First line.\\n', 'Second line.\\n'] f . close ()","title":"1.7.3.\u4ece\u6587\u672c\u6587\u4ef6\u8bfb\u53d6\u6570\u636e"},{"location":"python/DataStructure/01_PythonFundmantal/#174","text":"\u793a\u4f8b\uff1a\u8bfb\u53d6\u6587\u4ef6\u4e2d\u7684\u6574\u6570\uff0c\u6bcf\u884c\u53ea\u6709\u4e00\u4e2a\u6574\u6570\u3002 import random f = open ( \"./docs/python/DataStructure/code/myfile.txt\" , 'w' ) # \u751f\u62100~9\u6574\u6570\uff0c\u5e76\u5199\u5165\u6587\u4ef6 for count in range ( 10 ): f . write ( str ( count ) + \" \\n \" ) f . close () # \u6253\u5f00\u6587\u4ef6 f = open ( \"./docs/python/DataStructure/code/myfile.txt\" , 'r' ) # \u4f9d\u6b21\u8bfb\u53d6\u6587\u4ef6\u4e2d\u7684\u6570\u5b57\uff0c\u5e76\u6c42\u548c theSum = 0 for line in f : line = line . strip () number = int ( line ) theSum += number print ( \"The sum is : \" , theSum ) # \u8fd0\u884c\u7ed3\u679c\uff1a # The sum is : 45 f . close () \u793a\u4f8b\uff1a\u8bfb\u53d6\u6587\u4ef6\u4e2d\u7684\u6574\u6570\uff0c\u6bcf\u884c\u6709\u591a\u4e2a\u6574\u6570\u3002\u9700\u8981\u4e8b\u5148\u628a\u4e0b\u9762\u7684\u5185\u5bb9\u5199\u5165 myfile.txt \u6587\u4ef6\u4e2d\u3002 \u6587\u4ef6 myfile.txt \u7684\u5185\u5bb9\u3002 1 3 5 7 9 2 4 6 8 10 31 200 3000 50000 import random # \u6253\u5f00\u6587\u4ef6 f = open ( \"./docs/python/DataStructure/code/myfile.txt\" , 'r' ) # \u4f9d\u6b21\u8bfb\u53d6\u6587\u4ef6\u4e2d\u7684\u6570\u5b57\uff0c\u5e76\u6c42\u548c theSum = 0 for line in f : lines = line . split () # split\u65b9\u6cd5\u4f1a\u81ea\u52a8\u5904\u7406\u6362\u884c\u7b26 for word in lines : number = int ( word ) theSum += number print ( \"The sum is : \" , theSum ) # \u8fd0\u884c\u7ed3\u679c\uff1a # The sum is : 53286 f . close () \u7b80\u5199\u4e0a\u9762\u7684\u4ee3\u7801\u3002 import random f = open ( \"./docs/python/DataStructure/code/myfile.txt\" , 'r' ) print ( \"The sum is: \" , sum ( map ( int , f . read () . split ()))) # \u8fd0\u884c\u7ed3\u679c\uff1a # The sum is : 53286 f . close ()","title":"1.7.4.\u4ece\u5176\u5b83\u6587\u4ef6\u8bfb\u53d6\u6570\u636e"},{"location":"python/DataStructure/01_PythonFundmantal/#175pickle","text":"\u5728\u628a\u4efb\u4f55\u5bf9\u8c61\u4fdd\u5b58\u5230\u6587\u4ef6\u4e4b\u524d\uff0c\u6211\u4eec\u53ef\u4ee5\u5bf9\u5b83\u8fdb\u884c\u201c\u814c\u5236\u201d\uff1b\u5728\u628a\u5bf9\u8c61\u4ece\u6587\u4ef6\u52a0\u8f7d\u5230\u7a0b\u5e8f\u4e2d\u65f6\uff0c\u4e5f\u53ef\u4ee5\u5bf9\u5b83\u8fdb\u884c\u201c\u53cd\u814c\u5236\u201d\u3002 \u793a\u4f8b\uff1a \u4f7f\u7528pickle\u6a21\u5757\u7684 pickle.dump \u628a\u540d\u4e3alyst\u7684\u5217\u8868\u91cc\u7684\u6240\u6709\u5bf9\u8c61\u4fdd\u5b58\u5230\u540d\u4e3aitems.dat\u7684\u6587\u4ef6\u91cc\uff08\u201c\u814c\u5236\u201d\uff09\u3002\u6211\u4eec\u4e0d\u9700\u8981\u77e5\u9053\u5217\u8868\u91cc\u6709\u54ea\u4e9b\u7c7b\u578b\u7684\u5bf9\u8c61\uff0c\u4e5f\u4e0d\u9700\u8981\u77e5\u9053\u6709\u591a\u5c11\u4e2a\u5bf9\u8c61\u3002 import pickle myList = [ 60 , \"A string object\" , 1977 ] fObj = open ( \"./docs/python/DataStructure/code/items.dat\" , \"wb\" ) for item in myList : pickle . dump ( item , fObj ) fObj . close () \u4f7f\u7528pickle\u6a21\u5757\u7684 pickle.load \u628aitems.dat\u7684\u6587\u4ef6\u5185\u5bb9\u52a0\u8f7d\u56de\u7a0b\u5e8f\uff08\u201c\u53cd\u814c\u5236\u201d\uff09\u3002 import pickle lyst = list () fileObj = open ( \"./docs/python/DataStructure/code/items.dat\" , \"rb\" ) while True : try : item = pickle . load ( fileObj ) lyst . append ( item ) except EOFError : # \u68c0\u6d4b\u5df2\u7ecf\u5230\u8fbe\u6587\u4ef6\u672b\u5c3e fileObj . close () break print ( lyst ) # \u8fd0\u884c\u7ed3\u679c\uff1a # [60, 'A string object', 1977]","title":"1.7.5.\u4f7f\u7528pickle\u8bfb\u5199\u5bf9\u8c61"},{"location":"python/DataStructure/01_PythonFundmantal/#18","text":"\u7c7b\uff08class\uff09\u7528\u6765\u63cf\u8ff0\u4e0e\u4e00\u7ec4\u5bf9\u8c61\u6709\u5173\u7684\u6570\u636e\u548c\u65b9\u6cd5\u3002\u5b83\u63d0\u4f9b\u4e86\u7528\u6765\u521b\u5efa\u5bf9\u8c61\u7684\u84dd\u56fe\uff0c\u4ee5\u53ca\u5728\u5bf9\u8c61\u4e0a\u8c03\u7528\u65b9\u6cd5\u65f6\u6240\u9700\u8981\u6267\u884c\u7684\u4ee3\u7801\u3002 Python\u91cc\u7684\u6570\u636e\u7c7b\u578b\u90fd\u662f\u7c7b\uff1b \u7c7b\u540d\u6309\u7167\u60ef\u4f8b\u9996\u5b57\u6bcd\u5e94\u4e3a\u5927\u5199\u6837\u5f0f\uff1b \u5b9a\u4e49\u7c7b\u7684\u4ee3\u7801\u901a\u5e38\u4f1a\u88ab\u5b58\u653e\u5728\u9996\u5b57\u6bcd\u5c0f\u5199\u7684\u7c7b\u540d\u7684\u6a21\u5757\u6587\u4ef6\u91cc\u3002 \u76f8\u5173\u7684\u7c7b\u4e5f\u53ef\u80fd\u4f1a\u51fa\u73b0\u5728\u540c\u4e00\u4e2a\u6a21\u5757\u91cc\u3002 \u7c7b\u7684\u8bed\u6cd5\uff1a def < class name > ( < parent class name > )[ 2 ]: < class variable assignments > < instance method definitions > \u7236\u7c7b\uff08parent class\uff09\u7684\u540d\u79f0\u662f\u53ef\u9009\u7684\uff0c\u5728\u9ed8\u8ba4\u60c5\u51b5\u4e0b\uff0c\u5b83\u4f1a\u662fobject\u3002 \u6240\u6709Python\u7c7b\u5c5e\u4e8e\u4e00\u4e2a\u4ee5 object \u4f5c\u4e3a\u6839\u8282\u70b9\u7684\u5c42\u6b21\u7ed3\u6784\u3002 \u5728 object \u91cc\uff0cPython\u5b9a\u4e49\u4e86\u51e0\u79cd\u65b9\u6cd5\uff1a __str__ \u548c __eq__ \uff0c\u56e0\u6b64\u6240\u6709\u5b50\u7c7b\u4f1a\u81ea\u52a8\u7ee7\u627f\u8fd9\u4e9b\u65b9\u6cd5\u3002 \u5b9e\u4f8b\u65b9\u6cd5\uff08instance method\uff09\u662f\u5728\u7c7b\u7684\u5bf9\u8c61\u4e0a\u8fd0\u884c\u7684\u3002\u5b83\u4eec\u5305\u542b\u7528\u6765\u8bbf\u95ee\u6216\u4fee\u6539\u5b9e\u4f8b\u53d8\u91cf\u7684\u4ee3\u7801\u3002 \u5b9e\u4f8b\u53d8\u91cf\uff08instance variable\uff09\u662f\u6307\u7531\u5355\u4e2a\u5bf9\u8c61\u6240\u62e5\u6709\u7684\u5b58\u50a8\u4fe1\u606f\u3002 \u7c7b\u53d8\u91cf\uff08class variable\uff09\u662f\u6307\u7531\u7c7b\u7684\u6240\u6709\u5bf9\u8c61\u5b58\u50a8\u6240\u6709\u7684\u4fe1\u606f\u3002 \u793a\u4f8b\uff1a\u89e3\u8bfbCounter\u7c7b\u3002 Counter \u7c7b\u662f object \u7684\u5b50\u7c7b\uff1b instances \u662f\u7c7b\u53d8\u91cf\uff0c\u8ddf\u8e2a\u5df2\u521b\u5efa\u7684\u8ba1\u6570\u5668\u5bf9\u8c61\u7684\u6570\u91cf\uff1b \u5b9e\u4f8b\u65b9\u6cd5 __init__ \u4e5f\u79f0\u4e3a\u6784\u9020\u51fd\u6570\uff1b\u8fd9\u4e2a\u65b9\u6cd5\u7528\u6765\u521d\u59cb\u5316\u5b9e\u4f8b\u53d8\u91cf\uff0c\u5e76\u4e14\u5bf9\u7c7b\u53d8\u91cf\u8fdb\u884c\u66f4\u65b0\uff1b self \u662f\u6307\u5728\u8fd0\u884c\u65f6\u8fd9\u4e2a\u65b9\u6cd5\u7684\u5bf9\u8c61\u672c\u8eab\uff1b \u4f7f\u7528\u5b9e\u4f8b\u53d8\u91cf\u90fd\u4f1a\u52a0\u4e0a\u524d\u7f00 self \uff1b\u548c\u53c2\u6570\u6216\u4e34\u65f6\u53d8\u91cf\u4e0d\u540c\u7684\u5730\u65b9\u662f\uff0c\u5b9e\u4f8b\u53d8\u91cf\u5728\u7c7b\u7684\u4efb\u4f55\u65b9\u6cd5\u91cc\u662f\u53ef\u89c1\u7684\uff1b \u5176\u4ed6\u5b9e\u4f8b\u65b9\u6cd5\u53ef\u4ee5\u5206\u4e3a\u4e24\u79cd\uff1a\u53d8\u5f02\u5668\uff08mutator\uff09\u548c\u8bbf\u95ee\u5668\uff08accessor\uff09\u3002\u53d8\u5f02\u5668\u4f1a\u901a\u8fc7\u4fee\u6539\u5bf9\u8c61\u7684\u5b9e\u4f8b\u53d8\u91cf\u5bf9\u5176\u5185\u90e8\u72b6\u6001\u8fdb\u884c\u4fee\u6539\u6216\u66f4\u6539\u3002\u8bbf\u95ee\u5668\u5219\u53ea\u4f1a\u67e5\u770b\u6216\u4f7f\u7528\u5bf9\u8c61\u7684\u5b9e\u4f8b\u53d8\u91cf\u7684\u503c\uff0c\u800c\u4e0d\u4f1a\u53bb\u4fee\u6539\u5b83\u4eec\uff1b __str__ \u65b9\u6cd5\u5c06\u8986\u76d6object\u7c7b\u91cc\u7684\u8fd9\u4e2a\u65b9\u6cd5\uff1b \u5f53Python\u7684 print \u51fd\u6570\u63a5\u6536\u5230\u4e00\u4e2a\u53c2\u6570\u65f6\uff0c\u8fd9\u4e2a\u53c2\u6570\u7684 __str__ \u65b9\u6cd5\u5c06\u81ea\u52a8\u8fd0\u884c\uff0c\u4ece\u800c\u5f97\u5230\u5b83\u7684\u5b57\u7b26\u4e32\u8868\u8fbe\u5f0f\uff0c\u4ee5\u4fbf\u7528\u6765\u8f93\u51fa\uff1b \u5f53\u770b\u5230 == \u8fd0\u7b97\u7b26\u65f6\uff0cPython\u5c06\u8fd0\u884c __eq__ \u65b9\u6cd5\uff1b\u5728 object \u7c7b\u91cc\uff0c\u8fd9\u4e2a\u65b9\u6cd5\u7684\u9ed8\u8ba4\u5b9a\u4e49\u662f\u8fd0\u884c is \u8fd0\u7b97\u7b26\u3002 class Counter ( object ): # Counter\u7c7b\u662fobject\u7684\u5b50\u7c7b \"\"\"Models a counter.\"\"\" # Class variable \u7c7b\u53d8\u91cf instances = 0 # \u8ddf\u8e2a\u5df2\u521b\u5efa\u7684\u8ba1\u6570\u5668\u5bf9\u8c61\u7684\u6570\u91cf # Constructor \u6784\u9020\u5668 # \u5b9e\u4f8b\u65b9\u6cd5__init__\u4e5f\u79f0\u4e3a\u6784\u9020\u51fd\u6570\uff1b\u8fd9\u4e2a\u65b9\u6cd5\u7528\u6765\u521d\u59cb\u5316\u5b9e\u4f8b\u53d8\u91cf\uff0c\u5e76\u4e14\u5bf9\u7c7b\u53d8\u91cf\u8fdb\u884c\u66f4\u65b0\uff1b def __init__ ( self ): # self\u662f\u6307\u5728\u8fd0\u884c\u65f6\u8fd9\u4e2a\u65b9\u6cd5\u7684\u5bf9\u8c61\u672c\u8eab \"\"\"Sets up the counter.\"\"\" Counter . instances += 1 self . reset () # Mutator methods def reset ( self ): \"\"\"Sets the counter to 0.\"\"\" self . value = 0 def increment ( self , amount = 1 ): \"\"\"Adds amount to the counter.\"\"\" self . value += amount def decrement ( self , amount = 1 ): \"\"\"Subtracts amount from the counter.\"\"\" self . value -= amount # Accessor methods def getValue ( self ): \"\"\"Returns the counter's value.\"\"\" return self . value def __str__ ( self ): \"\"\"Returns the string representation of the counter.\"\"\" return str ( self . value ) def __eq__ ( self , other ): \"\"\"Returns True if self equals other or False otherwise.\"\"\" if self is other : return True if type ( self ) != type ( other ): return False return self . value == other . value c1 = Counter () print ( c1 ) # \u8fd0\u884c\u7ed3\u679c\uff1a # 0 c1 . getValue () str ( c1 ) c1 . increment () print ( c1 ) # \u8fd0\u884c\u7ed3\u679c\uff1a # 1 c1 . increment ( 5 ) print ( c1 ) # \u8fd0\u884c\u7ed3\u679c\uff1a # 6 c1 . reset () print ( c1 ) # \u8fd0\u884c\u7ed3\u679c\uff1a # 0 c2 = Counter () print ( Counter . instances ) # \u8fd0\u884c\u7ed3\u679c\uff1a # 2 print ( c1 == c1 ) # \u8fd0\u884c\u7ed3\u679c\uff1a # True print ( c1 == 0 ) # \u8fd0\u884c\u7ed3\u679c\uff1a # False print ( c1 == c2 ) # \u8fd0\u884c\u7ed3\u679c\uff1a # True c2 . increment () print ( c1 == c2 ) # \u8fd0\u884c\u7ed3\u679c\uff1a # False","title":"1.8.\u521b\u5efa\u7c7b"},{"location":"python/DataStructure/01_PythonFundmantal/#19","text":"1\uff0e\u7f16\u5199\u4e00\u4e2a\u7a0b\u5e8f\uff0c\u4f7f\u4e4b\u80fd\u591f\u63a5\u6536\u7403\u4f53\u7684\u534a\u5f84\uff08\u6d6e\u70b9\u6570\uff09\uff0c\u5e76\u4e14\u53ef\u4ee5\u8f93\u51fa\u7403\u4f53\u7684\u76f4\u5f84\u3001\u5468\u957f\u3001\u8868\u9762\u79ef\u4ee5\u53ca\u4f53\u79ef\u3002 \u89e3\u7b54\uff1a PAI = 3.14 radius = float ( input ( \"\u8f93\u5165\u7403\u534a\u5f84\uff1a\" )) diameter = radius * 2 circumference = 2 * PAI * radius surfaceArea = 4 * PAI * radius ** 2 sphereVolume = 4 * ( PAI * radius ** 3 ) / 3 print ( \"\u7403\u534a\u5f84\uff1a\" , radius , \"\u7403\u76f4\u5f84\uff1a\" , diameter , \"\u7403\u8868\u9762\u79ef\uff1a\" , surfaceArea , \"\u7403\u4f53\u79ef\uff1a\" , sphereVolume ) # \u8fd0\u884c\u7ed3\u679c\uff1a # \u8f93\u5165\u7403\u534a\u5f84\uff1a3.5 # \u7403\u534a\u5f84\uff1a 3.5 \u7403\u76f4\u5f84\uff1a 7.0 \u7403\u8868\u9762\u79ef\uff1a 153.86 \u7403\u4f53\u79ef\uff1a 179.50333333333333 import math def main (): try : radius = float ( input ( \"\u8bf7\u8f93\u5165\u7403\u534a\u5f84\uff1a\" )) if radius <= 0 : print ( \"\u534a\u5f84\u5fc5\u987b\u4e3a\u6b63\u6570\uff01\" ) return diameter = 2 * radius circumference = 2 * math . pi * radius surfaceArea = 4 * math . pi * radius ** 2 volume = ( 4 / 3 ) * math . pi * radius ** 3 print ( f \"\u7403\u4f53\u7684\u76f4\u5f84\uff1a { diameter : .2f } \" ) print ( f \"\u7403\u4f53\u7684\u5468\u957f\uff1a { circumference : .2f } \" ) print ( f \"\u7403\u4f53\u7684\u8868\u9762\u79ef\uff1a { surfaceArea : .2f } \" ) print ( f \"\u7403\u4f53\u7684\u4f53\u79ef\uff1a { volume : .2f } \" ) except ValueError : print ( \"\u8bf7\u8f93\u5165\u6709\u6548\u7684\u6570\u5b57\uff01\" ) if __name__ == \"__main__\" : main () # \u8fd0\u884c\u7ed3\u679c\uff1a # \u8bf7\u8f93\u5165\u7403\u534a\u5f84\uff1a3.5 # \u7403\u4f53\u7684\u76f4\u5f84\uff1a7.00 # \u7403\u4f53\u7684\u5468\u957f\uff1a21.99 # \u7403\u4f53\u7684\u8868\u9762\u79ef\uff1a153.94 # \u7403\u4f53\u7684\u4f53\u79ef\uff1a179.59 import math class Sphere : def __init__ ( self , radius ): self . radius = radius def diameter ( self ): return 2 * self . radius def circumference ( self ): return 2 * math . pi * self . radius def surfaceArea ( self ): return 4 * math . pi * self . radius ** 2 def volume ( self ): return ( 4 / 3 ) * math . pi * self . radius ** 3 def main (): try : radius = float ( input ( \"\u8bf7\u8f93\u5165\u7403\u4f53\u7684\u534a\u5f84\uff1a\" )) if radius <= 0 : print ( \"\u534a\u5f84\u5fc5\u987b\u4e3a\u6b63\u6570\uff01\" ) return sphere = Sphere ( radius ) print ( f \"\u7403\u4f53\u7684\u76f4\u5f84\uff1a { sphere . diameter () : .2f } \" ) print ( f \"\u7403\u4f53\u7684\u5468\u957f\uff1a { sphere . circumference () : .2f } \" ) print ( f \"\u7403\u4f53\u7684\u8868\u9762\u79ef\uff1a { sphere . surfaceArea () : .2f } \" ) print ( f \"\u7403\u4f53\u7684\u4f53\u79ef\uff1a { sphere . volume () : .2f } \" ) except ValueError : print ( \"\u8bf7\u8f93\u5165\u6709\u6548\u7684\u6570\u5b57\uff01\" ) if __name__ == \"__main__\" : main () # \u8fd0\u884c\u7ed3\u679c\uff1a # \u8bf7\u8f93\u5165\u7403\u4f53\u7684\u534a\u5f84\uff1a3.5 # \u7403\u4f53\u7684\u76f4\u5f84\uff1a7.00 # \u7403\u4f53\u7684\u5468\u957f\uff1a21.99 # \u7403\u4f53\u7684\u8868\u9762\u79ef\uff1a153.94 # \u7403\u4f53\u7684\u4f53\u79ef\uff1a179.59 2\uff0e\u5458\u5de5\u7684\u5468\u5de5\u8d44\u7b49\u4e8e\u5c0f\u65f6\u5de5\u8d44\u4e58\u4ee5\u6b63\u5e38\u7684\u603b\u5de5\u4f5c\u65f6\u95f4\u518d\u52a0\u4e0a\u52a0\u73ed\u5de5\u8d44\u3002\u52a0\u73ed\u5de5\u8d44\u7b49\u4e8e\u603b\u52a0\u73ed\u65f6\u95f4\u4e58\u4ee5\u5c0f\u65f6\u5de5\u8d44\u76841.5\u500d\u3002\u7f16\u5199\u4e00\u4e2a\u7a0b\u5e8f\uff0c\u8ba9\u7528\u6237\u53ef\u4ee5\u8f93\u5165\u5c0f\u65f6\u5de5\u8d44\u3001\u6b63\u5e38\u7684\u603b\u5de5\u4f5c\u65f6\u95f4\u4ee5\u53ca\u52a0\u73ed\u603b\u65f6\u95f4\uff0c\u7136\u540e\u663e\u793a\u51fa\u5458\u5de5\u7684\u5468\u5de5\u8d44\u3002 \u89e3\u7b54\uff1a hourSalary = float ( input ( \"\u8f93\u5165\u5c0f\u65f6\u5de5\u8d44\uff08\u5143\uff09\uff1a\" )) totalWorkingHours = float ( input ( \"\u8f93\u5165\u672c\u5468\u6b63\u5e38\u603b\u5de5\u4f5c\u65f6\u95f4\uff08\u5c0f\u65f6\uff09\uff1a\" )) totalOvertimeHours = float ( input ( \"\u8f93\u5165\u672c\u5468\u603b\u52a0\u73ed\u603b\u5de5\u4f5c\u65f6\u95f4\uff08\u5c0f\u65f6\uff09\uff1a\" )) weeklySalary = hourSalary * totalWorkingHours + hourSalary * totalOvertimeHours * 1.5 print ( \"\u5458\u5de5\u7684\u5468\u5de5\u8d44\uff08\u5143\uff09\u662f\uff1a\" , weeklySalary ) # \u8fd0\u884c\u7ed3\u679c\uff1a # \u8f93\u5165\u5c0f\u65f6\u5de5\u8d44\uff08\u5143\uff09\uff1a20 # \u8f93\u5165\u672c\u5468\u6b63\u5e38\u603b\u5de5\u4f5c\u65f6\u95f4\uff08\u5c0f\u65f6\uff09\uff1a40 # \u8f93\u5165\u672c\u5468\u603b\u52a0\u73ed\u603b\u5de5\u4f5c\u65f6\u95f4\uff08\u5c0f\u65f6\uff09\uff1a10 # \u5458\u5de5\u7684\u5468\u5de5\u8d44\uff08\u5143\uff09\u662f\uff1a 1100.0 def calculate_weekly_salary ( hourly_wage , normal_hours , overtime_hours ): overtime_pay = overtime_hours * hourly_wage * 1.5 normal_pay = normal_hours * hourly_wage weekly_salary = normal_pay + overtime_pay return weekly_salary def main (): try : hourly_wage = float ( input ( \"\u8bf7\u8f93\u5165\u5c0f\u65f6\u5de5\u8d44\uff1a\" )) normal_hours = float ( input ( \"\u8bf7\u8f93\u5165\u6b63\u5e38\u7684\u603b\u5de5\u4f5c\u65f6\u95f4\uff08\u5c0f\u65f6\uff09\uff1a\" )) overtime_hours = float ( input ( \"\u8bf7\u8f93\u5165\u52a0\u73ed\u603b\u65f6\u95f4\uff08\u5c0f\u65f6\uff09\uff1a\" )) weekly_salary = calculate_weekly_salary ( hourly_wage , normal_hours , overtime_hours ) print ( f \"\u5458\u5de5\u7684\u5468\u5de5\u8d44\u4e3a\uff1a { weekly_salary : .2f } \" ) except ValueError : print ( \"\u8bf7\u8f93\u5165\u6709\u6548\u7684\u6570\u5b57\uff01\" ) if __name__ == \"__main__\" : main () # \u8fd0\u884c\u7ed3\u679c\uff1a # \u8bf7\u8f93\u5165\u5c0f\u65f6\u5de5\u8d44\uff1a20 # \u8bf7\u8f93\u5165\u6b63\u5e38\u7684\u603b\u5de5\u4f5c\u65f6\u95f4\uff08\u5c0f\u65f6\uff09\uff1a40 # \u8bf7\u8f93\u5165\u52a0\u73ed\u603b\u65f6\u95f4\uff08\u5c0f\u65f6\uff09\uff1a10 # \u5458\u5de5\u7684\u5468\u5de5\u8d44\u4e3a\uff1a1100.00 class Employee : def __init__ ( self , hourly_wage , normal_hours , overtime_hours ): self . hourly_wage = hourly_wage self . normal_hours = normal_hours self . overtime_hours = overtime_hours def calculate_weekly_salary ( self ): overtime_pay = self . overtime_hours * self . hourly_wage * 1.5 normal_pay = self . normal_hours * self . hourly_wage weekly_salary = normal_pay + overtime_pay return weekly_salary def main (): try : hourly_wage = float ( input ( \"\u8bf7\u8f93\u5165\u5c0f\u65f6\u5de5\u8d44\uff1a\" )) normal_hours = float ( input ( \"\u8bf7\u8f93\u5165\u6b63\u5e38\u7684\u603b\u5de5\u4f5c\u65f6\u95f4\uff08\u5c0f\u65f6\uff09\uff1a\" )) overtime_hours = float ( input ( \"\u8bf7\u8f93\u5165\u52a0\u73ed\u603b\u65f6\u95f4\uff08\u5c0f\u65f6\uff09\uff1a\" )) employee = Employee ( hourly_wage , normal_hours , overtime_hours ) weekly_salary = employee . calculate_weekly_salary () print ( f \"\u5458\u5de5\u7684\u5468\u5de5\u8d44\u4e3a\uff1a { weekly_salary : .2f } \" ) except ValueError : print ( \"\u8bf7\u8f93\u5165\u6709\u6548\u7684\u6570\u5b57\uff01\" ) if __name__ == \"__main__\" : main () # \u8fd0\u884c\u7ed3\u679c\uff1a # \u8bf7\u8f93\u5165\u5c0f\u65f6\u5de5\u8d44\uff1a20 # \u8bf7\u8f93\u5165\u6b63\u5e38\u7684\u603b\u5de5\u4f5c\u65f6\u95f4\uff08\u5c0f\u65f6\uff09\uff1a40 # \u8bf7\u8f93\u5165\u52a0\u73ed\u603b\u65f6\u95f4\uff08\u5c0f\u65f6\uff09\uff1a10 # \u5458\u5de5\u7684\u5468\u5de5\u8d44\u4e3a\uff1a1100.00 3\uff0e\u6709\u4e00\u4e2a\u6807\u51c6\u7684\u79d1\u5b66\u5b9e\u9a8c\uff1a\u6254\u4e00\u4e2a\u7403\uff0c\u770b\u770b\u5b83\u80fd\u53cd\u5f39\u591a\u9ad8\u3002\u4e00\u65e6\u786e\u5b9a\u4e86\u7403\u7684\u201c\u53cd\u5f39\u9ad8\u5ea6\u201d\uff0c\u8fd9\u4e2a\u6bd4\u503c\u5c31\u7ed9\u51fa\u4e86\u76f8\u5e94\u7684\u53cd\u5f39\u5ea6\u6307\u6570\u3002\u4f8b\u5982\uff0c\u5982\u679c\u4ece10ft\uff081ft=0.3048m\uff09\u9ad8\u5904\u6389\u843d\u7684\u7403\u53ef\u4ee5\u53cd\u5f39\u52306 ft\u9ad8\uff0c\u90a3\u4e48\u76f8\u5e94\u7684\u53cd\u5f39\u5ea6\u6307\u6570\u5c31\u662f0.6\uff1b\u5728\u4e00\u6b21\u53cd\u5f39\u4e4b\u540e\uff0c\u7403\u7684\u603b\u884c\u8fdb\u8ddd\u79bb\u662f16 ft\u3002\u63a5\u4e0b\u6765\uff0c\u7403\u7ee7\u7eed\u5f39\u8df3\uff0c\u90a3\u4e48\u4e24\u6b21\u5f39\u8df3\u540e\u7684\u603b\u8ddd\u79bb\u5e94\u8be5\u662f\uff1a10 ft + 6 ft + 6 ft + 3.6 ft = 25.6 ft\u3002\u53ef\u4ee5\u770b\u5230\uff0c\u6bcf\u6b21\u8fde\u7eed\u5f39\u8df3\u6240\u7ecf\u8fc7\u7684\u8ddd\u79bb\u662f\uff1a\u7403\u5230\u5730\u9762\u7684\u8ddd\u79bb\uff0c\u52a0\u4e0a\u8fd9\u4e2a\u8ddd\u79bb\u4e58\u4ee5 0.6\uff0c\u8fd9\u65f6\u7403\u53c8\u5f39\u56de\u6765\u4e86\u3002\u7f16\u5199\u4e00\u4e2a\u7a0b\u5e8f\uff0c\u53ef\u4ee5\u8ba9\u7528\u6237\u8f93\u5165\u7403\u7684\u521d\u59cb\u9ad8\u5ea6\u548c\u5141\u8bb8\u7403\u5f39\u8df3\u7684\u6b21\u6570\uff0c\u5e76\u8f93\u51fa\u7403\u6240\u7ecf\u8fc7\u7684\u603b\u8ddd\u79bb\u3002 \u89e3\u7b54\uff1a height = float ( input ( \"\u8f93\u5165\u5c0f\u7403\u521d\u59cb\u9ad8\u5ea6\uff08ft\uff09\uff1a\" )) times = float ( input ( \"\u8f93\u5165\u5141\u8bb8\u5c0f\u7403\u5f39\u8df3\u6b21\u6570\uff1a\" )) distance = 0 traceDistance = 0 while times : distance = height + 0.6 * height traceDistance += distance height = 0.6 * height times -= 1 print ( \"\u5c0f\u7403\u7ecf\u8fc7\u7684\u603b\u8ddd\u79bb\uff08ft\uff09\uff1a\" , traceDistance ) # \u8fd0\u884c\u7ed3\u679c\uff1a # \u8f93\u5165\u5c0f\u7403\u521d\u59cb\u9ad8\u5ea6\uff08ft\uff09\uff1a50 # \u8f93\u5165\u5141\u8bb8\u5c0f\u7403\u5f39\u8df3\u6b21\u6570\uff1a5 # \u5c0f\u7403\u7ecf\u8fc7\u7684\u603b\u8ddd\u79bb\uff08ft\uff09\uff1a 184.448 # \u8f93\u5165\u5c0f\u7403\u521d\u59cb\u9ad8\u5ea6\uff08ft\uff09\uff1a100 # \u8f93\u5165\u5141\u8bb8\u5c0f\u7403\u5f39\u8df3\u6b21\u6570\uff1a10 # \u5c0f\u7403\u7ecf\u8fc7\u7684\u603b\u8ddd\u79bb\uff08ft\uff09\uff1a 397.58135296000006 def calculate_total_distance ( initial_height , num_bounces ): rebound_factor = 0.6 total_distance = 0 height = initial_height for _ in range ( num_bounces + 1 ): total_distance += height height *= rebound_factor return total_distance def main (): try : initial_height = float ( input ( \"\u8bf7\u8f93\u5165\u7403\u7684\u521d\u59cb\u9ad8\u5ea6\uff08\u5355\u4f4d\uff1aft\uff09\uff1a\" )) num_bounces = int ( input ( \"\u8bf7\u8f93\u5165\u5141\u8bb8\u7403\u5f39\u8df3\u7684\u6b21\u6570\uff1a\" )) total_distance = calculate_total_distance ( initial_height , num_bounces ) print ( f \"\u7403\u6240\u7ecf\u8fc7\u7684\u603b\u8ddd\u79bb\u4e3a\uff1a { total_distance : .2f } ft\" ) except ValueError : print ( \"\u8bf7\u8f93\u5165\u6709\u6548\u7684\u6570\u5b57\uff01\" ) if __name__ == \"__main__\" : main () # \u8fd0\u884c\u7ed3\u679c\uff1a # \u8bf7\u8f93\u5165\u7403\u7684\u521d\u59cb\u9ad8\u5ea6\uff08\u5355\u4f4d\uff1aft\uff09\uff1a50 # \u8bf7\u8f93\u5165\u5141\u8bb8\u7403\u5f39\u8df3\u7684\u6b21\u6570\uff1a5 # \u7403\u6240\u7ecf\u8fc7\u7684\u603b\u8ddd\u79bb\u4e3a\uff1a119.17 ft # \u8bf7\u8f93\u5165\u7403\u7684\u521d\u59cb\u9ad8\u5ea6\uff08\u5355\u4f4d\uff1aft\uff09\uff1a100 # \u8bf7\u8f93\u5165\u5141\u8bb8\u7403\u5f39\u8df3\u7684\u6b21\u6570\uff1a10 # \u7403\u6240\u7ecf\u8fc7\u7684\u603b\u8ddd\u79bb\u4e3a\uff1a249.09 ft class BouncingBall : def __init__ ( self , initial_height , num_bounces ): self . initial_height = initial_height self . num_bounces = num_bounces self . rebound_factor = 0.6 def calculate_total_distance ( self ): total_distance = 0 height = self . initial_height for _ in range ( self . num_bounces + 1 ): total_distance += height height *= self . rebound_factor return total_distance def main (): try : initial_height = float ( input ( \"\u8bf7\u8f93\u5165\u7403\u7684\u521d\u59cb\u9ad8\u5ea6\uff08\u5355\u4f4d\uff1aft\uff09\uff1a\" )) num_bounces = int ( input ( \"\u8bf7\u8f93\u5165\u5141\u8bb8\u7403\u5f39\u8df3\u7684\u6b21\u6570\uff1a\" )) bouncing_ball = BouncingBall ( initial_height , num_bounces ) total_distance = bouncing_ball . calculate_total_distance () print ( f \"\u7403\u6240\u7ecf\u8fc7\u7684\u603b\u8ddd\u79bb\u4e3a\uff1a { total_distance : .2f } ft\" ) except ValueError : print ( \"\u8bf7\u8f93\u5165\u6709\u6548\u7684\u6570\u5b57\uff01\" ) if __name__ == \"__main__\" : main () 4\uff0e\u5fb7\u56fd\u6570\u5b66\u5bb6Gottfried Leibniz\u53d1\u660e\u4e86\u4e0b\u9762\u8fd9\u4e2a\u7528\u6765\u6c42\u03c0\u7684\u8fd1\u4f3c\u503c\u7684\u65b9\u6cd5\uff1a \u03c0/4 = 1 - 1/3 + 1/5 - 1/7 + ...... \uff0c\u8bf7\u7f16\u5199\u4e00\u4e2a\u7a0b\u5e8f\uff0c\u8ba9\u7528\u6237\u53ef\u4ee5\u6307\u5b9a\u8fd9\u4e2a\u8fd1\u4f3c\u503c\u6240\u4f7f\u7528\u7684\u8fed\u4ee3\u6b21\u6570\uff0c\u5e76\u4e14\u663e\u793a\u51fa\u7ed3\u679c\u3002 \u89e3\u7b54\uff1a n = int ( input ( \"\u8f93\u5165\u8fed\u4ee3\u6b21\u6570\uff1a\" )) mySum = 0 while n : mySum += 1 / ( 2 * n - 1 ) * (( - 1 ) ** ( n + 1 )) n -= 1 print ( \"\u03c0\u7684\u8fd1\u4f3c\u503c\u662f\uff1a\" , mySum * 4 ) # \u8fd0\u884c\u7ed3\u679c\uff1a # \u8f93\u5165\u8fed\u4ee3\u6b21\u6570\uff1a5 # \u03c0\u7684\u8fd1\u4f3c\u503c\u662f\uff1a 3.33968253968254 # \u8f93\u5165\u8fed\u4ee3\u6b21\u6570\uff1a10 # \u03c0\u7684\u8fd1\u4f3c\u503c\u662f\uff1a 3.0418396189294024 # \u8f93\u5165\u8fed\u4ee3\u6b21\u6570\uff1a20 # \u03c0\u7684\u8fd1\u4f3c\u503c\u662f\uff1a 3.0916238066678385 # \u8f93\u5165\u8fed\u4ee3\u6b21\u6570\uff1a10000000 # \u03c0\u7684\u8fd1\u4f3c\u503c\u662f\uff1a 3.1415925535897933 def calculate_pi_approximation ( iterations ): approximation = 0 sign = 1 for i in range ( 1 , iterations * 2 , 2 ): approximation += sign * ( 1 / i ) sign *= - 1 return approximation * 4 def main (): try : iterations = int ( input ( \"\u8bf7\u8f93\u5165\u8fed\u4ee3\u6b21\u6570\uff1a\" )) if iterations <= 0 : print ( \"\u8fed\u4ee3\u6b21\u6570\u5fc5\u987b\u4e3a\u6b63\u6574\u6570\uff01\" ) return pi_approximation = calculate_pi_approximation ( iterations ) print ( f \"\u03c0 \u7684\u8fd1\u4f3c\u503c\u4e3a\uff1a { pi_approximation : .10f } \" ) except ValueError : print ( \"\u8bf7\u8f93\u5165\u6709\u6548\u7684\u6574\u6570\uff01\" ) if __name__ == \"__main__\" : main () # \u8fd0\u884c\u7ed3\u679c\uff1a # \u8bf7\u8f93\u5165\u8fed\u4ee3\u6b21\u6570\uff1a5 # \u03c0 \u7684\u8fd1\u4f3c\u503c\u4e3a\uff1a3.3396825397 # \u8bf7\u8f93\u5165\u8fed\u4ee3\u6b21\u6570\uff1a10 # \u03c0 \u7684\u8fd1\u4f3c\u503c\u4e3a\uff1a3.0418396189 # \u8bf7\u8f93\u5165\u8fed\u4ee3\u6b21\u6570\uff1a20 # \u03c0 \u7684\u8fd1\u4f3c\u503c\u4e3a\uff1a3.0916238067 # \u8bf7\u8f93\u5165\u8fed\u4ee3\u6b21\u6570\uff1a10000000 # \u03c0 \u7684\u8fd1\u4f3c\u503c\u4e3a\uff1a3.1415925536 class PiApproximation : @classmethod def calculate_pi_approximation ( cls , iterations ): approximation = 0 sign = 1 for i in range ( 1 , iterations * 2 , 2 ): approximation += sign * ( 1 / i ) sign *= - 1 return approximation * 4 def main (): try : iterations = int ( input ( \"\u8bf7\u8f93\u5165\u8fed\u4ee3\u6b21\u6570\uff1a\" )) if iterations <= 0 : print ( \"\u8fed\u4ee3\u6b21\u6570\u5fc5\u987b\u4e3a\u6b63\u6574\u6570\uff01\" ) return pi_approximation = PiApproximation . calculate_pi_approximation ( iterations ) print ( f \"\u03c0 \u7684\u8fd1\u4f3c\u503c\u4e3a\uff1a { pi_approximation : .10f } \" ) except ValueError : print ( \"\u8bf7\u8f93\u5165\u6709\u6548\u7684\u6574\u6570\uff01\" ) if __name__ == \"__main__\" : main () # \u8fd0\u884c\u7ed3\u679c\uff1a # \u8f93\u5165\u8fed\u4ee3\u6b21\u6570\uff1a5 # \u03c0 \u7684\u8fd1\u4f3c\u503c\u4e3a\uff1a3.3396825397 # \u8bf7\u8f93\u5165\u8fed\u4ee3\u6b21\u6570\uff1a10 # \u03c0 \u7684\u8fd1\u4f3c\u503c\u4e3a\uff1a3.0418396189 # \u8bf7\u8f93\u5165\u8fed\u4ee3\u6b21\u6570\uff1a20 # \u03c0 \u7684\u8fd1\u4f3c\u503c\u4e3a\uff1a3.0916238067 # \u8bf7\u8f93\u5165\u8fed\u4ee3\u6b21\u6570\uff1a10000000 # \u03c0 \u7684\u8fd1\u4f3c\u503c\u4e3a\uff1a3.1415925536 5\uff0e\u67d0\u8ba1\u7b97\u673a\u5546\u5e97\u6709\u8d2d\u4e70\u8ba1\u7b97\u673a\u7684\u4fe1\u8d37\u8ba1\u5212\uff1a\u9996\u4ed810%\uff0c\u5e74\u5229\u7387\u4e3a12%\uff0c\u6bcf\u6708\u6240\u4ed8\u6b3e\u4e3a\u8d2d\u4e70\u4ef7\u683c\u51cf\u53bb\u9996\u4ed8\u4e4b\u540e\u76845%\u3002\u7f16\u5199\u4e00\u4e2a\u4ee5\u8d2d\u4e70\u4ef7\u683c\u4e3a\u8f93\u5165\u7684\u7a0b\u5e8f\uff0c\u53ef\u4ee5\u8f93\u51fa\u4e00\u4e2a\u6709\u9002\u5f53\u6807\u9898\u7684\u8868\u683c\uff0c\u663e\u793a\u8d37\u6b3e\u671f\u9650\u5185\u7684\u4ed8\u6b3e\u8ba1\u5212\u3002\u8868\u7684\u6bcf\u4e00\u884c\u90fd\u5e94\u5305\u542b\u4e0b\u9762\u5404\u9879\uff1a \u6708\u6570\uff08\u4ee51\u5f00\u5934\uff09\uff1b \u5f53\u524d\u6240\u6b20\u7684\u4f59\u989d\uff1b \u5f53\u6708\u6240\u6b20\u7684\u5229\u606f\uff1b \u5f53\u6708\u6240\u6b20\u7684\u672c\u91d1\uff1b \u5f53\u6708\u6240\u9700\u4ed8\u6b3e\u91d1\u989d\uff1b \u4ed8\u6b3e\u4e4b\u540e\u6240\u6b20\u7684\u91d1\u989d\u3002 \u4e00\u4e2a\u6708\u7684\u5229\u606f\u7b49\u4e8e\u4f59\u989d \u00d7 \u5229\u7387/12\uff1b\u4e00\u4e2a\u6708\u6240\u6b20\u7684\u672c\u91d1\u7b49\u4e8e\u5f53\u6708\u8fd8\u6b3e\u989d\u51cf\u53bb\u6240\u6b20\u7684\u5229\u606f\u3002 \u89e3\u7b54\uff1a def calculate_payment_schedule ( purchase_price ): down_payment = purchase_price * 0.1 loan_balance = purchase_price - down_payment annual_interest_rate = 0.12 monthly_interest_rate = annual_interest_rate / 12 monthly_payment = ( purchase_price - down_payment ) * 0.05 payment_schedule = [] for month in range ( 1 , 13 ): interest = loan_balance * monthly_interest_rate principal = monthly_payment - interest loan_balance -= principal payment_schedule . append (( month , loan_balance , interest , principal , monthly_payment , loan_balance + monthly_payment )) return payment_schedule def main (): try : purchase_price = float ( input ( \"\u8bf7\u8f93\u5165\u8d2d\u4e70\u4ef7\u683c\uff1a\" )) payment_schedule = calculate_payment_schedule ( purchase_price ) print ( \" {:<10} {:<15} {:<15} {:<15} {:<15} {:<15} \" . format ( \"\u6708\u6570\" , \"\u5f53\u524d\u6240\u6b20\u7684\u4f59\u989d\" , \"\u5f53\u6708\u6240\u6b20\u7684\u5229\u606f\" , \"\u5f53\u6708\u6240\u6b20\u7684\u672c\u91d1\" , \"\u5f53\u6708\u6240\u9700\u4ed8\u6b3e\u91d1\u989d\" , \"\u4ed8\u6b3e\u4e4b\u540e\u6240\u6b20\u7684\u91d1\u989d\" )) for payment in payment_schedule : month , balance , interest , principal , monthly_payment , new_balance = payment print ( \" {:<10} {:<15.2f} {:<15.2f} {:<15.2f} {:<15.2f} {:<15.2f} \" . format ( month , balance , interest , principal , monthly_payment , new_balance )) except ValueError : print ( \"\u8bf7\u8f93\u5165\u6709\u6548\u7684\u6570\u5b57\uff01\" ) if __name__ == \"__main__\" : main () # \u8fd0\u884c\u7ed3\u679c\uff1a # \u8bf7\u8f93\u5165\u8d2d\u4e70\u4ef7\u683c\uff1a5000 # \u6708\u6570 \u5f53\u524d\u6240\u6b20\u7684\u4f59\u989d \u5f53\u6708\u6240\u6b20\u7684\u5229\u606f \u5f53\u6708\u6240\u6b20\u7684\u672c\u91d1 \u5f53\u6708\u6240\u9700\u4ed8\u6b3e\u91d1\u989d \u4ed8\u6b3e\u4e4b\u540e\u6240\u6b20\u7684\u91d1\u989d # 1 4320.00 45.00 180.00 225.00 4545.00 # 2 4138.20 43.20 181.80 225.00 4363.20 # 3 3954.58 41.38 183.62 225.00 4179.58 # 4 3769.13 39.55 185.45 225.00 3994.13 # 5 3581.82 37.69 187.31 225.00 3806.82 # 6 3392.64 35.82 189.18 225.00 3617.64 # 7 3201.56 33.93 191.07 225.00 3426.56 # 8 3008.58 32.02 192.98 225.00 3233.58 # 9 2813.67 30.09 194.91 225.00 3038.67 # 10 2616.80 28.14 196.86 225.00 2841.80 # 11 2417.97 26.17 198.83 225.00 2642.97 # 12 2217.15 24.18 200.82 225.00 2442.15 class PaymentSchedule : def __init__ ( self , purchase_price ): self . purchase_price = purchase_price self . down_payment = purchase_price * 0.1 self . loan_balance = purchase_price - self . down_payment self . annual_interest_rate = 0.12 self . monthly_interest_rate = self . annual_interest_rate / 12 self . monthly_payment = ( purchase_price - self . down_payment ) * 0.05 def calculate_schedule ( self ): payment_schedule = [] for month in range ( 1 , 13 ): interest = self . loan_balance * self . monthly_interest_rate principal = self . monthly_payment - interest self . loan_balance -= principal payment_schedule . append (( month , self . loan_balance , interest , principal , self . monthly_payment , self . loan_balance + self . monthly_payment )) return payment_schedule def print_schedule_table ( self ): payment_schedule = self . calculate_schedule () print ( \" {:<10} {:<15} {:<15} {:<15} {:<15} {:<15} \" . format ( \"\u6708\u6570\" , \"\u5f53\u524d\u6240\u6b20\u7684\u4f59\u989d\" , \"\u5f53\u6708\u6240\u6b20\u7684\u5229\u606f\" , \"\u5f53\u6708\u6240\u6b20\u7684\u672c\u91d1\" , \"\u5f53\u6708\u6240\u9700\u4ed8\u6b3e\u91d1\u989d\" , \"\u4ed8\u6b3e\u4e4b\u540e\u6240\u6b20\u7684\u91d1\u989d\" )) for payment in payment_schedule : month , balance , interest , principal , monthly_payment , new_balance = payment print ( \" {:<10} {:<15.2f} {:<15.2f} {:<15.2f} {:<15.2f} {:<15.2f} \" . format ( month , balance , interest , principal , monthly_payment , new_balance )) def main (): try : purchase_price = float ( input ( \"\u8bf7\u8f93\u5165\u8d2d\u4e70\u4ef7\u683c\uff1a\" )) payment_schedule = PaymentSchedule ( purchase_price ) payment_schedule . print_schedule_table () except ValueError : print ( \"\u8bf7\u8f93\u5165\u6709\u6548\u7684\u6570\u5b57\uff01\" ) if __name__ == \"__main__\" : main () # \u8fd0\u884c\u7ed3\u679c # \u8bf7\u8f93\u5165\u8d2d\u4e70\u4ef7\u683c\uff1a5000 # \u6708\u6570 \u5f53\u524d\u6240\u6b20\u7684\u4f59\u989d \u5f53\u6708\u6240\u6b20\u7684\u5229\u606f \u5f53\u6708\u6240\u6b20\u7684\u672c\u91d1 \u5f53\u6708\u6240\u9700\u4ed8\u6b3e\u91d1\u989d \u4ed8\u6b3e\u4e4b\u540e\u6240\u6b20\u7684\u91d1\u989d # 1 4320.00 45.00 180.00 225.00 4545.00 # 2 4138.20 43.20 181.80 225.00 4363.20 # 3 3954.58 41.38 183.62 225.00 4179.58 # 4 3769.13 39.55 185.45 225.00 3994.13 # 5 3581.82 37.69 187.31 225.00 3806.82 # 6 3392.64 35.82 189.18 225.00 3617.64 # 7 3201.56 33.93 191.07 225.00 3426.56 # 8 3008.58 32.02 192.98 225.00 3233.58 # 9 2813.67 30.09 194.91 225.00 3038.67 # 10 2616.80 28.14 196.86 225.00 2841.80 # 11 2417.97 26.17 198.83 225.00 2642.97 # 12 2217.15 24.18 200.82 225.00 2442.15 6\uff0e\u8d22\u52a1\u90e8\u95e8\u5728\u6587\u672c\u6587\u4ef6\u91cc\u4fdd\u5b58\u4e86\u6240\u6709\u5458\u5de5\u5728\u6bcf\u4e2a\u5de5\u8d44\u5468\u671f\u91cc\u7684\u4fe1\u606f\u5217\u8868\u3002\u6587\u4ef6\u4e2d\u6bcf\u4e00\u884c\u7684\u683c\u5f0f\u4e3a \u3002\u8bf7\u7f16\u5199\u4e00\u4e2a\u7a0b\u5e8f\uff0c\u8ba9\u7528\u6237\u53ef\u4ee5\u8f93\u5165\u6587\u4ef6\u7684\u540d\u79f0\uff0c\u5e76\u5728\u7ec8\u7aef\u4e0a\u6253\u5370\u51fa\u7ed9\u5b9a\u65f6\u95f4\u5185\u652f\u4ed8\u7ed9\u6bcf\u4e2a\u5458\u5de5\u7684\u5de5\u8d44\u62a5\u544a\u3002\u8fd9\u4e2a\u62a5\u544a\u662f\u4e00\u4e2a\u6709\u5408\u9002\u6807\u9898\u7684\u8868\uff0c\u5176\u4e2d\u6bcf\u884c\u90fd\u5e94\u8be5\u5305\u542b\u5458\u5de5\u7684\u59d3\u540d\u3001\u5de5\u4f5c\u65f6\u957f\u4ee5\u53ca\u7ed9\u5b9a\u65f6\u95f4\u5185\u6240\u652f\u4ed8\u7684\u5de5\u8d44\u3002 \u89e3\u7b54\uff1a # \u7a0b\u5e8f\u4f1a\u63d0\u793a\u7528\u6237\u8f93\u5165\u6587\u4ef6\u540d\uff0c\u7136\u540e\u8bfb\u53d6\u6587\u4ef6\u4e2d\u7684\u5458\u5de5\u4fe1\u606f\uff0c\u8ba1\u7b97\u5de5\u8d44\u62a5\u544a\uff0c\u5e76\u6253\u5370\u51fa\u5458\u5de5\u7684\u59d3\u540d\u3001\u5de5\u4f5c\u65f6\u957f\u548c\u652f\u4ed8\u5de5\u8d44\u3002\u6ce8\u610f\uff0c\u7a0b\u5e8f\u4f1a\u68c0\u67e5\u6587\u4ef6\u662f\u5426\u5b58\u5728\uff0c\u5e76\u4f1a\u5bf9\u6587\u4ef6\u4e2d\u7684\u6bcf\u884c\u6570\u636e\u8fdb\u884c\u5904\u7406\u4ee5\u786e\u4fdd\u6b63\u786e\u89e3\u6790\u3002 class Employee : def __init__ ( self , last_name , hourly_wage , hours_worked ): self . last_name = last_name self . hourly_wage = float ( hourly_wage ) self . hours_worked = float ( hours_worked ) def calculate_salary ( self ): return self . hourly_wage * self . hours_worked def main (): try : filename = input ( \"\u8bf7\u8f93\u5165\u6587\u4ef6\u540d\uff1a\" ) with open ( filename , 'r' ) as file : employees = [] for line in file : parts = line . strip () . split () if len ( parts ) == 3 : last_name , hourly_wage , hours_worked = parts employee = Employee ( last_name , hourly_wage , hours_worked ) employees . append ( employee ) print ( \" {:<20} {:<15} {:<15} \" . format ( \"\u5458\u5de5\u59d3\u540d\" , \"\u5de5\u4f5c\u65f6\u957f\" , \"\u652f\u4ed8\u5de5\u8d44\" )) print ( \"=\" * 50 ) total_salary = 0 for employee in employees : salary = employee . calculate_salary () total_salary += salary print ( \" {:<20} {:<15.2f} {:<15.2f} \" . format ( employee . last_name , employee . hours_worked , salary )) print ( \"=\" * 50 ) print ( f \"\u603b\u652f\u4ed8\u5de5\u8d44\uff1a { total_salary : .2f } \" ) except FileNotFoundError : print ( \"\u6587\u4ef6\u4e0d\u5b58\u5728\uff01\" ) if __name__ == \"__main__\" : main () 7\uff0e\u7edf\u8ba1\u5b66\u5bb6\u5e0c\u671b\u4f7f\u7528\u4e00\u7ec4\u51fd\u6570\u8ba1\u7b97\u6570\u5b57\u5217\u8868\u7684\u4e2d\u4f4d\u6570\uff08median\uff09\u548c\u4f17\u6570\uff08mode\uff09\u3002\u4e2d\u4f4d\u6570\u662f\u6307\u5982\u679c\u5bf9\u5217\u8868\u8fdb\u884c\u6392\u5e8f\u5c06\u4f1a\u51fa\u73b0\u5728\u5217\u8868\u4e2d\u70b9\u7684\u6570\u5b57\uff0c\u4f17\u6570\u662f\u6307\u5217\u8868\u4e2d\u6700\u5e38\u51fa\u73b0\u7684\u6570\u5b57\u3002\u628a\u8fd9\u4e9b\u529f\u80fd\u5b9a\u4e49\u5728\u540d\u53ebstats.py\u7684\u6a21\u5757\u4e2d\u3002\u9664\u6b64\u4e4b\u5916\uff0c\u6a21\u5757\u8fd8\u5e94\u8be5\u5305\u542b\u4e00\u4e2a\u540d\u53ebmean\u7684\u51fd\u6570\uff0c\u7528\u6765\u8ba1\u7b97\u4e00\u7ec4\u6570\u5b57\u7684\u5e73\u5747\u503c\u3002\u6bcf\u4e2a\u51fd\u6570\u90fd\u4f1a\u63a5\u6536\u4e00\u4e2a\u6570\u5b57\u5217\u8868\u4f5c\u4e3a\u53c2\u6570\uff0c\u5e76\u8fd4\u56de\u4e00\u4e2a\u6570\u5b57\u3002 \u89e3\u7b54\uff1a def median ( numbers ): sorted_numbers = sorted ( numbers ) length = len ( sorted_numbers ) if length % 2 == 1 : return sorted_numbers [ length // 2 ] else : mid1 = sorted_numbers [ length // 2 - 1 ] mid2 = sorted_numbers [ length // 2 ] return ( mid1 + mid2 ) / 2 def mode ( numbers ): from collections import Counter counter = Counter ( numbers ) mode_list = counter . most_common () max_count = mode_list [ 0 ][ 1 ] modes = [ num for num , count in mode_list if count == max_count ] return modes def mean ( numbers ): total = sum ( numbers ) count = len ( numbers ) return total / count if __name__ == \"__main__\" : test_numbers = [ 4 , 2 , 7 , 2 , 1 , 9 , 4 , 7 ] print ( \"\u4e2d\u4f4d\u6570:\" , median ( test_numbers )) print ( \"\u4f17\u6570:\" , mode ( test_numbers )) print ( \"\u5e73\u5747\u503c:\" , mean ( test_numbers )) class Stats : @staticmethod def median ( numbers ): sorted_numbers = sorted ( numbers ) length = len ( sorted_numbers ) if length % 2 == 1 : return sorted_numbers [ length // 2 ] else : mid1 = sorted_numbers [ length // 2 - 1 ] mid2 = sorted_numbers [ length // 2 ] return ( mid1 + mid2 ) / 2 @staticmethod def mode ( numbers ): from collections import Counter counter = Counter ( numbers ) mode_list = counter . most_common () max_count = mode_list [ 0 ][ 1 ] modes = [ num for num , count in mode_list if count == max_count ] return modes @staticmethod def mean ( numbers ): total = sum ( numbers ) count = len ( numbers ) return total / count if __name__ == \"__main__\" : test_numbers = [ 4 , 2 , 7 , 2 , 1 , 9 , 4 , 7 ] print ( \"\u4e2d\u4f4d\u6570:\" , Stats . median ( test_numbers )) print ( \"\u4f17\u6570:\" , Stats . mode ( test_numbers )) print ( \"\u5e73\u5747\u503c:\" , Stats . mean ( test_numbers )) 8\uff0e\u7f16\u5199\u7a0b\u5e8f\uff0c\u8ba9\u7528\u6237\u53ef\u4ee5\u6d4f\u89c8\u6587\u4ef6\u91cc\u7684\u6587\u672c\u884c\u3002\u8fd9\u4e2a\u7a0b\u5e8f\u4f1a\u63d0\u793a\u7528\u6237\u8f93\u5165\u6587\u4ef6\u540d\uff0c\u7136\u540e\u628a\u6587\u672c\u884c\u90fd\u8f93\u5165\u5217\u8868\u3002\u63a5\u4e0b\u6765\uff0c\u8fd9\u4e2a\u7a0b\u5e8f\u4f1a\u8fdb\u5165\u4e00\u4e2a\u5faa\u73af\uff0c\u5728\u8fd9\u4e2a\u5faa\u73af\u91cc\u6253\u5370\u51fa\u6587\u4ef6\u7684\u603b\u884c\u6570\uff0c\u5e76\u63d0\u793a\u7528\u6237\u8f93\u5165\u884c\u53f7\u3002\u8fd9\u4e2a\u884c\u53f7\u7684\u8303\u56f4\u5e94\u5f53\u662f1\u5230\u6587\u4ef6\u7684\u603b\u884c\u6570\u3002\u5982\u679c\u8f93\u5165\u662f0\uff0c\u90a3\u4e48\u7a0b\u5e8f\u9000\u51fa\uff1b\u5426\u5219\uff0c\u7a0b\u5e8f\u5c06\u6253\u5370\u51fa\u884c\u53f7\u6240\u5bf9\u5e94\u7684\u6587\u672c\u884c\u3002 def read_file_lines ( filename ): try : with open ( filename , 'r' ) as file : lines = file . readlines () return lines except FileNotFoundError : print ( \"\u6587\u4ef6\u4e0d\u5b58\u5728\uff01\" ) return [] def main (): filename = input ( \"\u8bf7\u8f93\u5165\u6587\u4ef6\u540d\uff1a\" ) lines = read_file_lines ( filename ) if not lines : return total_lines = len ( lines ) while True : print ( f \"\u6587\u4ef6\u603b\u884c\u6570\uff1a { total_lines } \" ) try : line_number = int ( input ( \"\u8bf7\u8f93\u5165\u884c\u53f7\uff08\u8f93\u51650\u9000\u51fa\uff09\uff1a\" )) if line_number == 0 : break elif 1 <= line_number <= total_lines : print ( f \"\u884c\u53f7 { line_number } : { lines [ line_number - 1 ] . strip () } \" ) else : print ( \"\u65e0\u6548\u7684\u884c\u53f7\uff0c\u8bf7\u8f93\u5165\u6b63\u786e\u8303\u56f4\u5185\u7684\u884c\u53f7\uff01\" ) except ValueError : print ( \"\u8bf7\u8f93\u5165\u6709\u6548\u7684\u6570\u5b57\uff01\" ) if __name__ == \"__main__\" : main () class TextFileBrowser : @classmethod def read_file_lines ( cls , filename ): try : with open ( filename , 'r' ) as file : lines = file . readlines () return lines except FileNotFoundError : print ( \"\u6587\u4ef6\u4e0d\u5b58\u5728\uff01\" ) return [] @classmethod def browse_file ( cls , filename ): lines = cls . read_file_lines ( filename ) if not lines : return total_lines = len ( lines ) while True : print ( f \"\u6587\u4ef6\u603b\u884c\u6570\uff1a { total_lines } \" ) try : line_number = int ( input ( \"\u8bf7\u8f93\u5165\u884c\u53f7\uff08\u8f93\u51650\u9000\u51fa\uff09\uff1a\" )) if line_number == 0 : break elif 1 <= line_number <= total_lines : print ( f \"\u884c\u53f7 { line_number } : { lines [ line_number - 1 ] . strip () } \" ) else : print ( \"\u65e0\u6548\u7684\u884c\u53f7\uff0c\u8bf7\u8f93\u5165\u6b63\u786e\u8303\u56f4\u5185\u7684\u884c\u53f7\uff01\" ) except ValueError : print ( \"\u8bf7\u8f93\u5165\u6709\u6548\u7684\u6570\u5b57\uff01\" ) def main (): filename = input ( \"\u8bf7\u8f93\u5165\u6587\u4ef6\u540d\uff1a\" ) TextFileBrowser . browse_file ( filename ) if __name__ == \"__main__\" : main () 9\uff0e\u5728\u672c\u7ae0\u8ba8\u8bba\u7684numberguess\u7a0b\u5e8f\u91cc\uff0c\u8ba1\u7b97\u673a\u4f1a\u201c\u6784\u601d\u201d\u4e00\u4e2a\u6570\u5b57\uff0c\u800c\u7528\u6237\u5219\u8f93\u5165\u731c\u6d4b\u7684\u503c\uff0c\u76f4\u5230\u731c\u5bf9\u4e3a\u6b62\u3002\u7f16\u5199\u8fd9\u6837\u4e00\u4e2a\u7a0b\u5e8f\uff0c\u4f7f\u5176\u53ef\u4ee5\u8c03\u6362\u8fd9\u4e24\u4e2a\u89d2\u8272\uff0c\u4e5f\u5c31\u662f\uff1a\u7528\u6237\u53bb\u201c\u6784\u601d\u201d\u4e00\u4e2a\u6570\u5b57\uff0c\u7136\u540e\u8ba1\u7b97\u673a\u53bb\u8ba1\u7b97\u5e76\u8f93\u51fa\u731c\u6d4b\u7684\u503c\u3002\u548c\u524d\u9762\u90a3\u4e2a\u6e38\u620f\u7248\u672c\u4e00\u6837\uff0c\u5f53\u8ba1\u7b97\u673a\u731c\u9519\u65f6\uff0c\u7528\u6237\u5fc5\u987b\u7ed9\u51fa\u76f8\u5e94\u7684\u63d0\u793a\uff0c\u4f8b\u5982\u201c<\u201d\u548c\u201c>\u201d\uff08\u5206\u522b\u4ee3\u8868\u201c\u6211\u7684\u6570\u5b57\u66f4\u5c0f\u201d\u548c\u201c\u6211\u7684\u6570\u5b57\u66f4\u5927\u201d\uff09\u3002\u5f53\u8ba1\u7b97\u673a\u731c\u5bf9\u65f6\uff0c\u7528\u6237\u5e94\u8be5\u8f93\u5165\u201c=\u201d\u3002\u7528\u6237\u9700\u8981\u5728\u7a0b\u5e8f\u542f\u52a8\u7684\u65f6\u5019\u8f93\u5165\u6570\u5b57\u7684\u4e0b\u9650\u548c\u4e0a\u9650\u3002\u8ba1\u7b97\u673a\u5e94\u8be5\u5728\u6700\u591a [log2(high\u2212low)+1] \u6b21\u731c\u6d4b\u91cc\u627e\u5230\u6b63\u786e\u7684\u6570\u5b57\u3002\u7a0b\u5e8f\u5e94\u8be5\u80fd\u591f\u8ddf\u8e2a\u731c\u6d4b\u6b21\u6570\uff0c\u5982\u679c\u731c\u6d4b\u9519\u8bef\u7684\u6b21\u6570\u5230\u4e86\u5141\u8bb8\u731c\u6d4b\u7684\u6700\u5927\u503c\u4f46\u8fd8\u6ca1\u6709\u731c\u5bf9\uff0c\u5c31\u8f93\u51fa\u6d88\u606f\u201cYou're cheating\uff01\u201d\u3002\u4e0b\u9762\u662f\u548c\u8fd9\u4e2a\u7a0b\u5e8f\u8fdb\u884c\u4ea4\u4e92\u7684\u793a\u4f8b\uff1a Enter the smaller number : 1 Enter the larger number : 100 Your number is 50 Enter = , < , or > : > Your number is 75 Enter = , < , or > : < Your number is 62 Enter = , < , or > : < Your number is 56 Enter = , < , or > : = Hooray , I 've got it in 4 tries! import math class ComputerGuesser : def __init__ ( self , lower_limit , upper_limit ): self . lower_limit = lower_limit self . upper_limit = upper_limit self . max_attempts = math . floor ( math . log2 ( upper_limit - lower_limit + 1 )) + 1 self . attempts = 0 def guess ( self ): return ( self . lower_limit + self . upper_limit ) // 2 def play ( self ): print ( f \"\u8bf7\u4f60\u9009\u62e9\u4e00\u4e2a\u5728 { self . lower_limit } \u5230 { self . upper_limit } \u4e4b\u95f4\u7684\u6570\u5b57\u3002\" ) while self . attempts < self . max_attempts : guess = self . guess () print ( f \"\u6211\u7684\u731c\u6d4b\u662f\uff1a { guess } \" ) response = input ( \"\u8bf7\u8f93\u5165 =, <, \u6216 > \u6765\u6307\u793a\u662f\u5426\u731c\u5bf9\uff1a\" ) self . attempts += 1 if response == '=' : print ( f \"\u6211\u5728\u7b2c { self . attempts } \u6b21\u731c\u5bf9\u4e86\uff01\" ) break elif response == '<' : self . upper_limit = guess - 1 elif response == '>' : self . lower_limit = guess + 1 else : print ( \"\u8bf7\u8f93\u5165\u6709\u6548\u7684\u64cd\u4f5c\u7b26\uff1a=, <, \u6216 >\" ) if self . attempts >= self . max_attempts : print ( \"\u4f60\u5728\u6b3a\u9a97\u6211\uff01\" ) def main (): lower_limit = int ( input ( \"\u8bf7\u8f93\u5165\u8f83\u5c0f\u7684\u6570\u5b57\uff1a\" )) upper_limit = int ( input ( \"\u8bf7\u8f93\u5165\u8f83\u5927\u7684\u6570\u5b57\uff1a\" )) guesser = ComputerGuesser ( lower_limit , upper_limit ) guesser . play () if __name__ == \"__main__\" : main () import math class ComputerGuesser : def __init__ ( self , lower_limit , upper_limit ): self . lower_limit = lower_limit self . upper_limit = upper_limit self . max_attempts = math . floor ( math . log2 ( upper_limit - lower_limit + 1 )) + 1 self . attempts = 0 @classmethod def guess ( cls , lower_limit , upper_limit ): return ( lower_limit + upper_limit ) // 2 @classmethod def play ( cls , lower_limit , upper_limit ): print ( f \"\u8bf7\u4f60\u9009\u62e9\u4e00\u4e2a\u5728 { lower_limit } \u5230 { upper_limit } \u4e4b\u95f4\u7684\u6570\u5b57\u3002\" ) attempts = 0 while attempts < cls . max_attempts : guess = cls . guess ( lower_limit , upper_limit ) print ( f \"\u6211\u7684\u731c\u6d4b\u662f\uff1a { guess } \" ) response = input ( \"\u8bf7\u8f93\u5165 =, <, \u6216 > \u6765\u6307\u793a\u662f\u5426\u731c\u5bf9\uff1a\" ) attempts += 1 if response == '=' : print ( f \"\u6211\u5728\u7b2c { attempts } \u6b21\u731c\u5bf9\u4e86\uff01\" ) break elif response == '<' : upper_limit = guess - 1 elif response == '>' : lower_limit = guess + 1 else : print ( \"\u8bf7\u8f93\u5165\u6709\u6548\u7684\u64cd\u4f5c\u7b26\uff1a=, <, \u6216 >\" ) if attempts >= cls . max_attempts : print ( \"\u4f60\u5728\u6b3a\u9a97\u6211\uff01\" ) def main (): lower_limit = int ( input ( \"\u8bf7\u8f93\u5165\u8f83\u5c0f\u7684\u6570\u5b57\uff1a\" )) upper_limit = int ( input ( \"\u8bf7\u8f93\u5165\u8f83\u5927\u7684\u6570\u5b57\uff1a\" )) ComputerGuesser . play ( lower_limit , upper_limit ) if __name__ == \"__main__\" : main () 10\uff0e\u6709\u4e00\u4e2a\u7b80\u5355\u7684\u8bfe\u7a0b\u7ba1\u7406\u7cfb\u7edf\uff0c\u5b83\u901a\u8fc7\u4f7f\u7528\u540d\u5b57\u548c\u4e00\u7ec4\u8003\u8bd5\u5206\u6570\u6765\u6a21\u62df\u5b66\u751f\u7684\u4fe1\u606f\u3002\u8fd9\u4e2a\u7cfb\u7edf\u5e94\u8be5\u80fd\u591f\u521b\u5efa\u4e00\u4e2a\u5177\u6709\u7ed9\u5b9a\u540d\u5b57\u548c\u5206\u6570\uff08\u8d77\u521d\u5747\u4e3a0\uff09\u7684\u5b66\u751f\u5bf9\u8c61\u3002\u7cfb\u7edf\u5e94\u8be5\u80fd\u591f\u8bbf\u95ee\u548c\u66ff\u6362\u6307\u5b9a\u4f4d\u7f6e\u5904\u7684\u5206\u6570\uff08\u4ece0\u5f00\u59cb\u8ba1\u6570\uff09\u3001\u5f97\u5230\u5b66\u751f\u6709\u591a\u5c11\u6b21\u8003\u8bd5\u3001\u5f97\u5230\u7684\u6700\u9ad8\u5206\u3001\u5f97\u5230\u7684\u5e73\u5747\u5206\u4ee5\u53ca\u5b66\u751f\u7684\u59d3\u540d\u3002\u9664\u6b64\u4e4b\u5916\uff0c\u5728\u6253\u5370\u5b66\u751f\u5bf9\u8c61\u7684\u65f6\u5019\uff0c\u5e94\u8be5\u50cf\u4e0b\u9762\u8fd9\u6837\u663e\u793a\u5b66\u751f\u7684\u59d3\u540d\u548c\u5206\u6570\uff1a Name : Ken Lambert Score 1 : 88 Score 2 : 77 Score 3 : 100 \u8bf7\u5b9a\u4e49\u4e00\u4e2a\u652f\u6301\u8fd9\u4e9b\u529f\u80fd\u548c\u884c\u4e3a\u7684Student\u7c7b\uff0c\u5e76\u4e14\u7f16\u5199\u4e00\u4e2a\u521b\u5efaStudent\u5bf9\u8c61\u5e76\u8fd0\u884c\u5176\u65b9\u6cd5\u7684\u7b80\u77ed\u7684\u6d4b\u8bd5\u51fd\u6570\u3002 class Student : def __init__ ( self , name ): self . name = name self . scores = [] def add_score ( self , score ): self . scores . append ( score ) def replace_score ( self , index , score ): if 0 <= index < len ( self . scores ): self . scores [ index ] = score else : print ( \"\u65e0\u6548\u7684\u5206\u6570\u7d22\u5f15\" ) def num_scores ( self ): return len ( self . scores ) def highest_score ( self ): if self . scores : return max ( self . scores ) else : return None def average_score ( self ): if self . scores : return sum ( self . scores ) / len ( self . scores ) else : return None def display ( self ): print ( f \"Name: { self . name } \" ) for i , score in enumerate ( self . scores , start = 1 ): print ( f \"Score { i } : { score } \" ) def test_student_class (): student = Student ( \"Ken Lambert\" ) student . add_score ( 88 ) student . add_score ( 77 ) student . add_score ( 100 ) student . display () print ( f \"Total Scores: { student . num_scores () } \" ) print ( f \"Highest Score: { student . highest_score () } \" ) print ( f \"Average Score: { student . average_score () } \" ) if __name__ == \"__main__\" : test_student_class ()","title":"1.9.\u7f16\u7a0b\u7ec3\u4e60"},{"location":"python/DataStructure/02_CollectionsOverview/","text":"2.\u591a\u9879\u96c6\u7684\u6982\u8ff0 \u00b6 \u591a\u9879\u96c6\uff08collection\uff09\u662f\u6307\u7531 0 \u4e2a\u6216\u8005\u591a\u4e2a\u5143\u7d20\u7ec4\u6210\u7684\u6982\u5ff5\u5355\u5143\u3002 \u4ece\u4e24\u4e2a\u89d2\u5ea6\u770b\u5f85\u591a\u9879\u96c6\uff1a \u591a\u9879\u96c6\u7684\u7528\u6237\u6216\u8005\u5ba2\u6237\u4f1a\u5173\u5fc3\u5b83\u4eec\u5728\u4e0d\u540c\u7684\u5e94\u7528\u7a0b\u5e8f\u91cc\u80fd\u505a\u4e9b\u4ec0\u4e48\u3002 \u591a\u9879\u96c6\u7684\u5f00\u53d1\u8005\u6216\u8005\u5b9e\u73b0\u8005\u5219\u4f1a\u5173\u5fc3\u5982\u4f55\u624d\u80fd\u8ba9\u5b83\u4eec\u6210\u4e3a\u6700\u597d\u7684\u901a\u7528\u8d44\u6e90\u4ee5\u88ab\u4f7f\u7528\u3002 \u76ee\u6807\uff1a \u5b9a\u4e49\u591a\u9879\u96c6\u76844\u4e2a\u901a\u7528\u7c7b\u578b\uff1a \u7ebf\u6027\u591a\u9879\u96c6 \u5206\u5c42\u591a\u9879\u96c6 \u56fe\u591a\u9879\u96c6 \u65e0\u5e8f\u591a\u9879\u96c6 \u4e86\u89e34\u4e2a\u591a\u9879\u96c6\u7c7b\u578b\u4e2d\u7684\u7279\u5b9a\u7c7b\u578b\uff1b \u4e86\u89e3\u8fd9\u4e9b\u591a\u9879\u96c6\u9002\u5408\u7528\u5728\u4ec0\u4e48\u7c7b\u578b\u7684\u5e94\u7528\u7a0b\u5e8f\u91cc\uff1b \u63cf\u8ff0\u6bcf\u79cd\u591a\u9879\u96c6\u7c7b\u578b\u7684\u5e38\u7528\u64cd\u4f5c\uff1b \u63cf\u8ff0\u591a\u9879\u96c6\u7684\u62bd\u8c61\u7c7b\u578b\u548c\u5b9e\u73b0\u4e4b\u95f4\u7684\u533a\u522b\uff1b 2.1.\u591a\u9879\u96c6\u7c7b\u578b \u00b6 \u5185\u7f6e\u591a\u9879\u96c6\u7c7b\u578b\uff1a \u5b57\u7b26\u4e32 str \u5217\u8868 list \u5143\u7ec4 tuple \u96c6\u5408 set \u5b57\u5178 dict \u5176\u4ed6\u591a\u9879\u96c6\u7c7b\u578b\uff1a \u6808 \u961f\u5217 \u4f18\u5148\u961f\u5217 \u4e8c\u53c9\u67e5\u627e\u6811 \u5806 \u56fe \u5305 \u6709\u5e8f\u591a\u9879\u96c6 \u591a\u9879\u96c6\u901a\u5e38\u4e0d\u662f\u9759\u6001\uff08static\uff09\u7684\uff0c\u800c\u662f\u52a8\u6001\uff08dynamic\uff09\u7684\uff0c\u53ef\u4ee5\u6839\u636e\u9700\u8981\u6765\u6269\u5927\u6216\u8005\u7f29\u5c0f\u591a\u9879\u96c6\u3002 \u4e0d\u53ef\u53d8\u591a\u9879\u96c6\uff08immutable collection\uff09\u7684\u5185\u5bb9\u5728\u7a0b\u5e8f\u8fd0\u884c\u8fc7\u7a0b\u4e2d\u662f\u4e0d\u53ef\u6539\u53d8\u7684\uff08\u5143\u7d20\u4e0d\u53ef\u4ee5\u6dfb\u52a0\u3001\u5220\u9664\u6216\u8005\u66ff\u6362\uff09\uff0c\u6bd4\u5982\u5143\u7ec4tuple\u3002 \u53ef\u53d8\u591a\u9879\u96c6\uff08mutable collection\uff09\u91cc\u7684\u5185\u5bb9\u53ef\u4ee5\u5728\u7a0b\u5e8f\u7684\u6574\u4e2a\u8fd0\u884c\u8fc7\u7a0b\u4e2d\u88ab\u6539\u53d8\uff0c\u6bd4\u5982\u5b57\u7b26\u4e32\u3001\u5217\u8868list\u3002 \u591a\u9879\u96c6\u6309\u6784\u6210\u65b9\u5f0f\u5212\u5206\u7684\u7c7b\u578b\uff1a \u7ebf\u6027\u591a\u9879\u96c6 \u5206\u5c42\u591a\u9879\u96c6 \u56fe\u591a\u9879\u96c6 \u65e0\u5e8f\u591a\u9879\u96c6 \u6709\u5e8f\u591a\u9879\u96c6 2.1.1.\u7ebf\u6027\u591a\u9879\u96c6 \u00b6 \u7ebf\u6027\u591a\u9879\u96c6\uff08linear collection\uff09\u91cc\u7684\u5143\u7d20\u6309\u7167\u4f4d\u7f6e\u8fdb\u884c\u6392\u5217\u3002 \u9664\u4e86\u7b2c\u4e00\u4e2a\u5143\u7d20\uff0c\u5176\u4ed6\u6bcf\u4e2a\u5143\u7d20\u90fd\u6709\u4e14\u53ea\u6709\u4e00\u4e2a\u524d\u5e8f\uff1b \u9664\u4e86\u6700\u540e\u4e00\u4e2a\u5143\u7d20\uff0c\u5176\u4ed6\u6bcf\u4e2a\u5143\u7d20\u90fd\u6709\u4e14\u53ea\u6709\u4e00\u4e2a\u540e\u5e8f\uff1b \u5b9e\u4f8b\uff1a\u6392\u961f\u7684\u4eba\uff0c\u8d2d\u7269\u6e05\u5355\uff0c\u5806\u53e0\u5728\u4e00\u8d77\u7684\u9910\u76d8\u7b49\u3002 2.1.2.\u5206\u5c42\u591a\u9879\u96c6 \u00b6 \u5206\u5c42\u591a\u9879\u96c6\uff08hierarchical collection\uff09\u91cc\u7684\u6570\u636e\u5143\u7d20\u4f1a\u4ee5\u7c7b\u4f3c\u4e8e\u5012\u7f6e\u7684\u6811\u7ed3\u6784\u8fdb\u884c\u6392\u5217\u3002\u9664\u4e86\u9876\u90e8\u7684\u6570\u636e\u5143\u7d20\uff0c\u5176\u4ed6\u6bcf\u4e2a\u6570\u636e\u5143\u7d20\u90fd\u6709\u4e14\u53ea\u6709\u4e00\u4e2a\u524d\u5e8f\uff0c\u88ab\u79f0\u4e3a\u7236\u5143\u7d20\uff08parent\uff09\uff0c\u4f46\u5b83\u4eec\u53ef\u4ee5\u6709\u8bb8\u591a\u7684\u540e\u5e8f\uff0c\u88ab\u79f0\u4e3a\u5b50\u5143\u7d20\uff08children\uff09\u3002 \u56fe\u4f8b\u4e2d\uff0c D3 \u7684\u524d\u5e8f\u7236\u5143\u7d20\u662f D1 \uff0c D3 \u7684\u540e\u7eed\u5b50\u5143\u7d20\u662f D4 \u3001 D5 \u3001 D6 \u3002 \u5b9e\u4f8b\uff1a\u6587\u4ef6\u76ee\u5f55\u7cfb\u7edf\u3001\u516c\u53f8\u7684\u7ec4\u7ec7\u67b6\u6784\u3001\u4e66\u7684\u76ee\u5f55\u7b49\u3002 2.1.3.\u56fe\u591a\u9879\u96c6 \u00b6 \u56fe\u591a\u9879\u96c6\uff08graph collection\uff09\u4e5f\u88ab\u79f0\u4e3a\u56fe\uff08graph\uff09\uff0c\u5b83\u662f\u8fd9\u6837\u4e00\u4e2a\u591a\u9879\u96c6\uff1a\u5b83\u7684\u6bcf\u4e00\u4e2a\u6570\u636e\u5143\u7d20\u90fd\u53ef\u4ee5\u6709\u591a\u4e2a\u524d\u5e8f\u548c\u591a\u4e2a\u540e\u5e8f\u3002 \u56fe\u4f8b\u4e2d\uff0c\u8fde\u63a5\u5230 D3 \u7684\u6240\u6709\u5143\u7d20\u4f1a\u88ab\u5f53\u4f5c\u5b83\u7684\u524d\u5e8f\u548c\u540e\u5e8f\uff0c\u5b83\u4eec\u4e5f\u56e0\u6b64\u88ab\u79f0\u4e3a D3 \u7684\u90bb\u5c45\u3002 \u5b9e\u4f8b\uff1a\u57ce\u5e02\u4e4b\u95f4\u7684\u822a\u7ebf\u56fe\u3001\u4e07\u7ef4\u7f51\u7b49\u3002 2.1.4.\u65e0\u5e8f\u591a\u9879\u96c6 \u00b6 \u65e0\u5e8f\u591a\u9879\u96c6\uff08unordered collection\uff09\u91cc\u7684\u5143\u7d20\u6ca1\u6709\u7279\u5b9a\u7684\u987a\u5e8f\uff0c\u5e76\u4e14\u4e0d\u4f1a\u7528\u4efb\u4f55\u660e\u786e\u7684\u65b9\u5f0f\u6765\u6307\u51fa\u5143\u7d20\u7684\u524d\u5e8f\u6216\u8005\u540e\u5e8f\u3002 \u5b9e\u4f8b\uff1a\u4e00\u888b\u5f39\u73e0\u7b49\u3002 2.1.5.\u6709\u5e8f\u591a\u9879\u96c6 \u00b6 \u6709\u5e8f\u591a\u9879\u96c6\uff08sorted collection\uff09\u4f1a\u5bf9\u5b83\u91cc\u9762\u7684\u5143\u7d20\u8fdb\u884c\u81ea\u7136\u6392\u5e8f\uff08natural ordering\uff09\u3002 \u8981\u8fdb\u884c\u81ea\u7136\u6392\u5e8f\uff0c\u5c31\u5fc5\u987b\u8981\u6709\u89c4\u5219\u6765\u5bf9\u6709\u5e8f\u591a\u9879\u96c6\u91cc\u7684\u5143\u7d20\u52a0\u4ee5\u6bd4\u8f83\uff0c\u4f8b\u5982 item(i) <= item(i+1) \u8fd9\u6837\u7684\u2014\u2014\u89c4\u5219\u3002 \u6709\u5e8f\u5217\u8868\u662f\u6700\u5e38\u89c1\u7684\u6709\u5e8f\u591a\u9879\u96c6\u3002\u6709\u5e8f\u591a\u9879\u96c6\u4e0d\u4e00\u5b9a\u662f\u7ebf\u6027\u7684\u6216\u8005\u6309\u7167\u4f4d\u7f6e\u8fdb\u884c\u6392\u5e8f\u7684\u3002 \u5bf9\u4e8e\u96c6\u5408\u3001\u5305\u3001\u5b57\u5178\uff0c\u867d\u7136\u4e0d\u80fd\u6309\u7167\u4f4d\u7f6e\u6765\u8bbf\u95ee\u5b83\u4eec\u7684\u5143\u7d20\uff0c\u4f46\u5b83\u4eec\u90fd\u53ef\u4ee5\u662f\u6709\u5e8f\u7684\u3002 \u7279\u6b8a\u7684\u5206\u5c42\u591a\u9879\u96c6\u7c7b\u578b\uff08\u5982\u4e8c\u53c9\u67e5\u627e\u6811\uff09\u4e5f\u4f1a\u5bf9\u5176\u4e2d\u7684\u5143\u7d20\u8fdb\u884c\u81ea\u7136\u6392\u5e8f\u3002 2.1.6.\u591a\u9879\u96c6\u7c7b\u578b\u7684\u5206\u7c7b \u00b6 \u4e0b\u9762\u5206\u7c7b\u91cc\u7684\u7c7b\u578b\u540d\u79f0\u6307\u7684\u5e76\u4e0d\u662f\u591a\u9879\u96c6\u7684\u7279\u5b9a\u5b9e\u73b0\u3002\u4e00\u79cd\u7279\u5b9a\u7c7b\u578b\u7684\u591a\u9879\u96c6\u53ef\u4ee5\u6709\u591a\u4e2a\u5b9e\u73b0\u3002 \u591a\u9879\u96c6 | ---\u56fe\u591a\u9879\u96c6 | ---\u5206\u5c42\u591a\u9879\u96c6 | | ---\u4e8c\u53c9\u67e5\u627e\u6811 | | ---\u5806 | ---\u7ebf\u6027\u591a\u9879\u96c6 | | ---\u5217\u8868 | | | ---\u6709\u5e8f\u5217\u8868 | | ---\u961f\u5217 | | | ---\u4f18\u5148\u5bf9\u5217 | | ---\u6808 | | ---\u5b57\u7b26\u4e32 | ---\u65e0\u5e8f\u591a\u9879\u96c6 | ---\u5305 | | ---\u6709\u5e8f\u5305 | ---\u5b57\u5178 | | ---\u6709\u5e8f\u5305 | ---\u96c6\u5408 | ---\u6709\u5e8f\u96c6\u5408 2.2.\u591a\u9879\u96c6\u64cd\u4f5c \u00b6 \u591a\u9879\u96c6\u64cd\u4f5c\u7c7b\u522b\uff1a \u786e\u5b9a\u5927\u5c0f\uff1a\u4f7f\u7528 len \u51fd\u6570\u83b7\u53d6\u5f53\u524d\u591a\u9879\u96c6\u91cc\u7684\u5143\u7d20\u6570\u91cf\u3002 \u68c0\u6d4b\u5143\u7d20\u6210\u5458\uff1a\u4f7f\u7528 in \u8fd0\u7b97\u7b26\u5728\u591a\u9879\u96c6\u91cc\u641c\u7d22\u6307\u5b9a\u7684\u76ee\u6807\u5143\u7d20\u3002\u5982\u679c\u627e\u5230\u4e86\u8fd9\u4e2a\u5143\u7d20\uff0c\u5219\u8fd4\u56deTrue\uff0c\u5426\u5219\u8fd4\u56deFalse\u3002 \u904d\u5386\u591a\u9879\u96c6\uff1a\u4f7f\u7528 for \u5faa\u73af\u8bbf\u95ee\u591a\u9879\u96c6\u91cc\u7684\u6b38\u4e00\u4e2a\u5143\u7d20\u3002\u5143\u7d20\u7684\u8bbf\u95ee\u987a\u5e8f\u53d6\u51b3\u4e8e\u591a\u9879\u96c6\u7684\u7c7b\u578b\u3002 \u83b7\u53d6\u591a\u9879\u96c6\u7684\u5b57\u7b26\u4e32\u8868\u793a\uff1a\u4f7f\u7528 str \u51fd\u6570\u83b7\u53d6\u591a\u9879\u96c6\u7684\u5b57\u7b26\u4e32\u8868\u793a\u3002 \u76f8\u7b49\u68c0\u6d4b\uff1a\u4f7f\u7528 == \u8fd0\u7b97\u7b26\u6765\u786e\u5b9a\u4e24\u4e2a\u591a\u9879\u96c6\u662f\u5426\u76f8\u7b49\u3002\u5982\u679c\u4e24\u4e2a\u591a\u9879\u96c6\u80b2\u6709\u76f8\u540c\u7684\u7c7b\u578b\uff0c\u5e76\u4e14\u5305\u542b\u76f8\u540c\u7684\u5143\u7d20\uff0c\u90a3\u4e48\u5b83\u4eec\u5c31\u662f\u76f8\u7b49\u7684\u3002\u6bd4\u8f83\u8fd9\u4e9b\u5143\u7d20\u5bf9\u7684\u987a\u5e8f\u53d6\u51b3\u4e8e\u591a\u9879\u96c6\u7684\u7c7b\u578b\u3002 \u8fde\u63a5\u4e24\u4e2a\u591a\u9879\u96c6\uff1a\u4f7f\u7528 + \u8fd0\u7b97\u7b26\u6765\u5f97\u5230\u4e00\u4e2a\u548c\u64cd\u4f5c\u6570\u76f8\u540c\u7c7b\u578b\u7684\u65b0\u591a\u9879\u96c6\uff0c\u5e76\u4e14\u5305\u542b\u4e24\u4e2a\u64cd\u4f5c\u6570\u91cc\u7684\u6240\u6709\u5143\u7d20\u3002 \u8f6c\u6362\u4e3a\u5176\u4ed6\u7c7b\u578b\u7684\u591a\u9879\u96c6\uff1a\u521b\u5efa\u4e00\u4e2a\u4e0e\u6e90\u591a\u9879\u96c6\u5177\u6709\u76f8\u540c\u5143\u7d20\u7684\u65b0\u591a\u9879\u96c6\u3002\u514b\u9686\u64cd\u4f5c\u65f6\u7c7b\u578b\u8f6c\u6362\u7684\u4e00\u79cd\u7279\u6b8a\u60c5\u51b5\uff0c\u56e0\u4e3a\u8f93\u5165\u8f93\u51fa\u7684\u4e24\u4e2a\u591a\u9879\u96c6\u5177\u6709\u76f8\u540c\u7c7b\u578b\u3002 \u63d2\u5165\u4e00\u4e2a\u5143\u7d20\uff1a\u5982\u679c\u53ef\u4ee5\uff0c\u5219\u5728\u7ed9\u5b9a\u7684\u4f4d\u7f6e\u5c06\u5bf9\u5e94\u7684\u5143\u7d20\u6dfb\u52a0\u5230\u591a\u9879\u96c6\u91cc\u3002 \u5220\u9664\u4e00\u4e2a\u5143\u7d20\uff1a\u5982\u679c\u53ef\u4ee5\uff0c\u5219\u5728\u7ed9\u5b9a\u7684\u4f4d\u7f6e\u5c06\u5bf9\u5e94\u7684\u5143\u7d20\u4ece\u591a\u9879\u96c6\u4e2d\u5220\u9664\u3002 \u66ff\u6362\u4e00\u4e2a\u5143\u7d20\uff1a\u5c06\u5220\u9664\u548c\u63d2\u5165\u5408\u5e76\u4e3a\u4e00\u9879\u64cd\u4f5c\u3002 \u8bbf\u95ee\u6216\u8005\u83b7\u53d6\u5143\u7d20\uff1a\u5982\u679c\u800c\u5df2\uff0c\u5219\u5728\u7ed9\u5b9a\u7684\u4f4d\u7f6e\u83b7\u53d6\u5143\u7d20\u3002 2.2.1.\u6240\u6709\u591a\u9879\u96c6\u7c7b\u578b\u4e2d\u7684\u57fa\u672c\u64cd\u4f5c \u00b6 \u5728Python\u91cc\uff0c\u4e0d\u540c\u591a\u9879\u96c6\u7c7b\u578b\u7684\u63d2\u5165\u3001\u5220\u9664\u3001\u66ff\u6362\u6216\u8005\u8bbf\u95ee\u64cd\u4f5c\u5e76\u6ca1\u6709\u7edf\u4e00\u7684\u540d\u79f0\uff0c\u4f46\u662f\u4f1a\u6709\u4e00\u4e9b\u6807\u51c6\u53d8\u4f53\u3002\u6bd4\u5982\uff0c \u65b9\u6cd5pop\u4f1a\u88ab\u7528\u6765\u4ece\u5217\u8868\u91cc\u79fb\u9664\u6307\u5b9a\u4f4d\u7f6e\u7684\u5143\u7d20\uff1b \u65b9\u6cd5pop\u4f1a\u88ab\u7528\u6765\u4ece\u5b57\u5178\u91cc\u79fb\u9664\u7ed9\u5b9a\u952e\u6240\u5bf9\u5e94\u7684\u503c\uff1b \u65b9\u6cd5remove\u4f1a\u88ab\u7528\u6765\u4ece\u5217\u8868\u6216\u8005\u67d0\u4e9b\u591a\u9879\u96c6\u91cc\u5220\u9664\u6307\u5b9a\u7684\u5143\u7d20\uff1b \u5bf9\u4e8e\u65b0\u5f00\u53d1\u51fa\u7684\u3001Python\u5c1a\u4e0d\u652f\u6301\u7684\u591a\u9879\u96c6\u7c7b\u578b\uff0c\u5c3d\u53ef\u80fd\u5730\u4f7f\u7528\u6807\u51c6\u7684\u8fd0\u7b97\u7b26\u3001\u51fd\u6570\u4ee5\u53ca\u65b9\u6cd5\u540d\u79f0\u5bf9\u5b83\u4eec\u8fdb\u884c\u64cd\u4f5c\u3002 2.2.2.\u7c7b\u578b\u8f6c\u6362 \u00b6 \u7c7b\u578b\u8f6c\u6362\uff0c\u5c06\u4e00\u79cd\u7c7b\u578b\u7684\u591a\u9879\u96c6\u8f6c\u6362\u4e3a\u53e6\u4e00\u79cd\u7c7b\u578b\u7684\u591a\u9879\u96c6\u3002\u4f8b\u5982\uff0c\u901a\u8fc7 list \u6216 tuple \u51fd\u6570\u5c06\u5b57\u7b26\u4e32\u8f6c\u6362\u4e3a\u5217\u8868\u6216\u8005\u5143\u7ec4\u3002 list \u6216 tuple \u51fd\u6570\u7684\u53c2\u6570\u4e0d\u4e00\u5b9a\u662f\u53e6\u4e00\u4e2a\u591a\u9879\u96c6\uff0c\u4e5f\u53ef\u4ee5\u662f\u4efb\u4f55\u7684\u53ef\u8fed\u4ee3\u5bf9\u8c61\uff08iterable object\uff09\u3002 \u53ef\u8fed\u4ee3\u5bf9\u8c61\u662f\u6307\uff0c\u80fd\u591f\u4f7f\u7528for\u5faa\u73af\u6765\u8bbf\u95ee\u7684\u4e00\u7cfb\u5217\u5143\u7d20\u3002\uff08\u591a\u9879\u96c6\u672c\u8eab\u4e5f\u662f\u53ef\u8fed\u4ee3\u5bf9\u8c61\uff09 2.2.3.\u514b\u9686\u548c\u76f8\u7b49\u6027 \u00b6 \u7c7b\u578b\u8f6c\u6362\u7684\u4e00\u79cd\u7279\u6b8a\u60c5\u51b5\u662f\u514b\u9686\uff0c\u5b83\u7684\u529f\u80fd\u662f\u8fd4\u56de\u8f6c\u6362\u51fd\u6570\u4e2d\u53c2\u6570\u7684\u5b8c\u6574\u526f\u672c\u3002 \u4f8b\u5982\uff1a myList1 = [ 2 , 4 , 8 ] myList2 = list ( myList1 ) myList1 is myList2 # False myList1 == myList2 # True \u6ce8\u610f\uff1a \u4e0a\u9762\u4e24\u4e2a\u5217\u8868\u4e0d\u4ec5\u6709\u76f8\u540c\u7684\u7ed3\u6784\uff0c\u5b83\u4eec\u8fd8\u6709\u76f8\u540c\u7684\u5143\u7d20\uff0c\u6bcf\u5bf9\u5143\u7d20\u5728\u4e24\u4e2a\u5217\u8868\u91cc\u7684\u4f4d\u7f6e\u90fd\u76f8\u540c\u3002\u4f46\u662f\uff0c\u4ed6\u4eec\u662f\u4e24\u4e2a\u4e0d\u540c\u7684\u5bf9\u8c61\u3002 \u4e0a\u4f8b\u4e2d list \u51fd\u6570\u5bf9\u5b83\u7684\u53c2\u6570\u5217\u8868\u8fdb\u884c\u6d45\u62f7\u8d1d\uff08shallow copy\uff09\u3002\u8fd9\u4e9b\u5143\u7d20\u7684\u672c\u8eab\u5728\u6dfb\u52a0\u5230\u65b0\u5217\u8868\u4e4b\u524d\u662f\u4e0d\u4f1a\u88ab\u514b\u9686\u7684\uff0c\u5728\u8fd9\u4e2a\u8fc7\u7a0b\u4e2d\u53ea\u4f1a\u590d\u5236\u5bf9\u8fd9\u4e9b\u5bf9\u8c61\u7684\u5f15\u7528\u3002\u5f53\u5143\u7d20\uff08\u6570\u5b57\u3001\u5b57\u7b26\u4e32\u6216\u8005Python\u7684\u5143\u7ec4\uff09\u4e0d\u53ef\u53d8\u65f6\uff0c\u8fd9\u4e2a\u7b56\u7565\u4e0d\u4f1a\u5f15\u8d77\u95ee\u9898\u3002\u4f46\u662f\uff0c\u5982\u679c\u591a\u9879\u96c6\u5305\u542b\u7684\u662f\u53ef\u53d8\u5143\u7d20\uff0c\u5c31\u53ef\u80fd\u4f1a\u4ea7\u751f\u526f\u4f5c\u7528\u3002\u4e3a\u4e86\u907f\u514d\u8fd9\u79cd\u60c5\u51b5\u7684\u53d1\u751f\uff0c\u6211\u4eec\u53ef\u4ee5\u901a\u8fc7\u5bf9\u6e90\u591a\u9879\u96c6\u7f16\u5199 for \u5faa\u73af\u6765\u521b\u5efa\u6df1\u62f7\u8d1d\uff08deep copy\uff09\uff0c\u8fd9\u4f1a\u628a\u5143\u7d20\u663e\u5f0f\u5730\u514b\u9686\u4e4b\u540e\u518d\u6dfb\u52a0\u5230\u65b0\u7684\u591a\u9879\u96c6\u91cc\u3002 2.3.\u8fed\u4ee3\u5668\u548c\u9ad8\u9636\u51fd\u6570 \u00b6 \u6bcf\u79cd\u7c7b\u578b\u7684\u591a\u9879\u96c6\u90fd\u652f\u6301\u4e00\u4e2a\u8fed\u4ee3\u5668\u6216 for \u5faa\u73af\uff0c\u8fd9\u4e2a\u64cd\u4f5c\u80fd\u591f\u8fed\u4ee3\u8fd9\u4e2a\u591a\u9879\u96c6\u7684\u6240\u6709\u5143\u7d20\u3002\u8fed\u4ee3\u5668\u662f\u591a\u9879\u96c6\u63d0\u4f9b\u7684\u6700\u5173\u952e\u7684\u64cd\u4f5c\u3002 for \u5faa\u73af\u670d\u52a1\u7684\u591a\u9879\u96c6\u4e2d\u5143\u7d20\u7684\u987a\u5e8f\u53d6\u51b3\u4e8e\u591a\u9879\u96c6\u7684\u7ec4\u7ec7\u65b9\u5f0f\u3002\u4f8b\u5982\uff1a \u5217\u8868\u91cc\u7684\u5143\u7d20\u4f1a\u4ece\u5934\u5230\u5c3e\u6309\u7167\u4f4d\u7f6e\u8fdb\u884c\u8bbf\u95ee\uff1b \u6709\u5e8f\u591a\u9879\u96c6\u91cc\u7684\u5143\u7d20\u4f1a\u6309\u4ece\u5c0f\u5230\u5927\u7684\u5347\u5e8f\u8fdb\u884c\u8bbf\u95ee\uff1b \u5bf9\u4e8e\u96c6\u5408\u6216\u8005\u5b57\u5178\u91cc\u7684\u5143\u7d20\u6765\u8bf4\uff0c\u4e0d\u4f1a\u6309\u7167\u7279\u5b9a\u7684\u987a\u5e8f\u8fdb\u884c\u8bbf\u95ee\u3002 \u8fed\u4ee3\u5668\uff08\u4f8b\u5982 for \u5faa\u73af\uff09\u8fd8\u652f\u6301\u4f7f\u7528\u9ad8\u9636\u51fd\u6570 map \u3001 filter \u548c reduce \u3002 \u8fd9\u4e9b\u9ad8\u9636\u51fd\u6570\u90fd\u4f7f\u7528\u53e6\u4e00\u4e2a\u51fd\u6570\u548c\u4e00\u4e2a\u591a\u9879\u96c6\u4f5c\u4e3a\u53c2\u6570\u3002 \u591a\u9879\u96c6\u90fd\u652f\u6301 for \u5faa\u73af\uff0c\u6240\u4ee5 map \u3001 filter \u548c reduce \u51fd\u6570\u53ef\u4ee5\u4e0e\u4efb\u4f55\u7c7b\u578b\u7684\u591a\u9879\u96c6\u4e00\u8d77\u4f7f\u7528\u3002 2.4.\u591a\u9879\u96c6\u7684\u5b9e\u73b0 \u00b6 \u4ece\u7528\u6237\uff08\u6bd4\u5982\uff0c\u7a0b\u5e8f\u5458\uff09\u7684\u89d2\u5ea6\u6765\u770b\uff0c\u591a\u9879\u96c6\u662f\u4e00\u79cd\u62bd\u8c61\uff0c\u662f\u4e00\u79cd\u4ee5\u67d0\u79cd\u9884\u5b9a\u884c\u4e3a\u6765\u5b58\u50a8\u548c\u8bbf\u95ee\u6570\u636e\u5143\u7d20\u7684\u65b9\u5f0f\uff0c\u5e76\u4e0d\u9700\u8981\u5173\u5fc3\u591a\u9879\u96c6\u5b9e\u73b0\u7684\u7ec6\u8282\u3002 \u591a\u9879\u96c6\u4e5f\u88ab\u79f0\u4e3a\u62bd\u8c61\u6570\u636e\u7c7b\u578b\uff08Abstract Data Type\uff0cADT\uff09\u3002\u62bd\u8c61\u6570\u636e\u7c7b\u578b\u7684\u7528\u6237\u53ea\u5173\u6ce8\u5b83\u7684\u63a5\u53e3\u4ee5\u53ca\u8fd9\u4e2a\u7c7b\u578b\u5bf9\u8c61\u6240\u63d0\u4f9b\u7684\u4e00\u7ec4\u64cd\u4f5c\u3002 \u5728Python\u91cc\uff0c\u51fd\u6570\u548c\u65b9\u6cd5\u662f\u6700\u5c0f\u7684\u62bd\u8c61\u5355\u5143\uff0c\u7c7b\u7684\u5927\u5c0f\u6b21\u4e4b\uff0c\u6a21\u5757\u662f\u6700\u5927\u7684\u62bd\u8c61\u5355\u5143\u3002 \u8fd9\u91cc\u4f1a\u628a\u62bd\u8c61\u591a\u9879\u96c6\u7c7b\u578b\u7684\u5b9e\u73b0\u5f53\u4f5c\u6a21\u5757\u91cc\u7684\u7c7b\u6216\u8005\u4e00\u7ec4\u76f8\u5173\u7684\u7c7b\u52a0\u4ee5\u63cf\u8ff0\u3002\u6784\u5efa\u8fd9\u4e9b\u7c7b\u5c31\u662f\u9762\u5411\u5bf9\u8c61\u7f16\u7a0b\u3002 2.5.\u5c0f\u7ed3 \u00b6 \u591a\u9879\u96c6\u662f\u5305\u542b0\u4e2a\u6216\u591a\u4e2a\u5176\u4ed6\u5bf9\u8c61\u7684\u5bf9\u8c61\u3002\u591a\u9879\u96c6\u53ef\u4ee5\u8fdb\u884c\u7684\u64cd\u4f5c\u6709\u8bbf\u95ee\u5bf9\u8c61\u3001\u63d2\u5165\u5bf9\u8c61\u3001\u5220\u9664\u5bf9\u8c61\u3001\u786e\u5b9a\u591a\u9879\u96c6\u7684\u5927\u5c0f\uff0c\u4ee5\u53ca\u904d\u5386\u6216\u8bbf\u95ee\u8fd9\u4e2a\u591a\u9879\u96c6\u7684\u5bf9\u8c61\u3002 \u591a\u9879\u96c6\u76845\u4e2a\u4e3b\u8981\u7c7b\u578b\u662f\uff1a\u7ebf\u6027\u591a\u9879\u96c6\u3001\u5206\u5c42\u591a\u9879\u96c6\u3001\u56fe\u591a\u9879\u96c6\u3001\u65e0\u5e8f\u591a\u9879\u96c6\u548c\u6709\u5e8f\u591a\u9879\u96c6\u3002 \u7ebf\u6027\u591a\u9879\u96c6\u4f1a\u6309\u7167\u4f4d\u7f6e\u5bf9\u5143\u7d20\u8fdb\u884c\u6392\u5e8f\uff0c\u5176\u4e2d\u9664\u4e86\u7b2c\u4e00\u4e2a\u5143\u7d20\uff0c\u6bcf\u4e2a\u90fd\u6709\u4e14\u53ea\u6709\u4e00\u4e2a\u524d\u5e8f\uff1b\u9664\u4e86\u6700\u540e\u4e00\u4e2a\u5143\u7d20\uff0c\u6bcf\u4e2a\u90fd\u6709\u4e14\u53ea\u6709\u4e00\u4e2a\u540e\u5e8f\u3002 \u5728\u5206\u5c42\u591a\u9879\u96c6\u91cc\uff0c\u9664\u4e86\u4e00\u4e2a\u5143\u7d20\uff0c\u5176\u4ed6\u6240\u6709\u5143\u7d20\u90fd\u6709\u4e14\u53ea\u6709\u4e00\u4e2a\u524d\u5e8f\u4ee5\u53ca0\u4e2a\u6216\u591a\u4e2a\u540e\u5e8f\u3002\u88ab\u79f0\u4e3a\u6839\u7684\u90a3\u4e2a\u989d\u5916\u5143\u7d20\u6ca1\u6709\u524d\u5e8f\u3002 \u56fe\u591a\u9879\u96c6\u91cc\u7684\u5143\u7d20\u53ef\u4ee5\u67090\u4e2a\u6216\u591a\u4e2a\u524d\u5e8f\u4ee5\u53ca0\u4e2a\u6216\u591a\u4e2a\u540e\u5e8f\u3002 \u65e0\u5e8f\u591a\u9879\u96c6\u91cc\u7684\u5143\u7d20\u6ca1\u6709\u7279\u5b9a\u7684\u987a\u5e8f\u3002 \u591a\u9879\u96c6\u662f\u53ef\u8fed\u4ee3\u7684\uff0c\u4e5f\u5c31\u662f\u8bf4\uff0c\u53ef\u4ee5\u4f7f\u7528for\u5faa\u73af\u8bbf\u95ee\u591a\u9879\u96c6\u91cc\u7684\u6240\u6709\u5143\u7d20\u3002\u7a0b\u5e8f\u5458\u4e5f\u53ef\u4ee5\u4f7f\u7528\u9ad8\u9636\u51fd\u6570map\u3001filter\u548creduce\u7b80\u5316\u591a\u9879\u96c6\u7684\u6570\u636e\u5904\u7406\u3002 \u62bd\u8c61\u6570\u636e\u7c7b\u578b\u662f\u4e00\u7ec4\u5bf9\u8c61\u548c\u5bf9\u8fd9\u4e9b\u5bf9\u8c61\u7684\u64cd\u4f5c\u3002\u56e0\u6b64\uff0c\u591a\u9879\u96c6\u662f\u62bd\u8c61\u6570\u636e\u7c7b\u578b\u3002 \u6570\u636e\u7ed3\u6784\u662f\u4e00\u4e2a\u8868\u793a\u591a\u9879\u96c6\u91cc\u5305\u542b\u7684\u6570\u636e\u7684\u5bf9\u8c61\u3002 2.6.\u590d\u4e60\u9898 \u00b6 \u7ebf\u6027\u591a\u9879\u96c6\u7684\u4e00\u4e2a\u4f8b\u5b50\u662f\uff1a \u96c6\u5408\u548c\u6811 \u5217\u8868\u548c\u6808 \u65e0\u5e8f\u591a\u9879\u96c6\u7684\u4e00\u4e2a\u4f8b\u5b50\u662f\uff1a \u961f\u5217\u548c\u5217\u8868 \u96c6\u5408\u548c\u5b57\u5178 \u5206\u5c42\u591a\u9879\u96c6\u53ef\u4ee5\u7528\u6765\u8868\u793a\uff1a \u94f6\u884c\u6392\u961f\u7684\u5ba2\u6237 \u6587\u4ef6\u76ee\u5f55\u7cfb\u7edf \u56fe\u591a\u9879\u96c6\u6700\u80fd\u4ee3\u8868\uff1a \u4e00\u7ec4\u6570\u5b57 \u57ce\u5e02\u4e4b\u95f4\u7684\u822a\u7ebf\u56fe \u5728Python\u91cc\uff0c\u4e24\u4e2a\u591a\u9879\u96c6\u95f4\u7684\u7c7b\u578b\u8f6c\u6362\u64cd\u4f5c\uff1a \u5728\u6e90\u591a\u9879\u96c6\u91cc\u521b\u5efa\u5bf9\u8c61\u7684\u526f\u672c\uff0c\u5e76\u4e14\u628a\u8fd9\u4e9b\u65b0\u5bf9\u8c61\u6dfb\u52a0\u5230\u76ee\u6807\u591a\u9879\u96c6\u7684\u65b0\u5b9e\u4f8b\u91cc \u628a\u5bf9\u6e90\u591a\u9879\u96c6\u5bf9\u8c61\u7684\u5f15\u7528\u6dfb\u52a0\u5230\u76ee\u6807\u591a\u9879\u96c6\u7684\u65b0\u5b9e\u4f8b\u91cc \u4e24\u4e2a\u5217\u8868\u7684 == \u64cd\u4f5c\u5fc5\u987b\uff1a \u6bd4\u8f83\u6bcf\u4e2a\u4f4d\u7f6e\u7684\u5143\u7d20\u5bf9\u662f\u5426\u76f8\u7b49 \u53ea\u4f1a\u9a8c\u8bc1\u4e00\u4e2a\u5217\u8868\u91cc\u7684\u6bcf\u4e00\u4e2a\u5143\u7d20\u662f\u5426\u4e5f\u5728\u53e6\u4e00\u4e2a\u5217\u8868\u91cc \u4e24\u4e2a\u96c6\u5408\u7684 == \u64cd\u4f5c\u5fc5\u987b\uff1a \u6bd4\u8f83\u6bcf\u4e2a\u4f4d\u7f6e\u7684\u5143\u7d20\u5bf9\u662f\u5426\u76f8\u7b49 \u9a8c\u8bc1\u96c6\u5408\u7684\u5927\u5c0f\u662f\u5426\u76f8\u7b49\uff0c\u5e76\u4e14\u4e00\u4e2a\u96c6\u5408\u91cc\u7684\u6bcf\u4e00\u4e2a\u5143\u7d20\u662f\u5426\u4e5f\u5728\u53e6\u4e00\u4e2a\u96c6\u5408\u91cc \u5bf9\u5217\u8868\u8fdb\u884c for \u5faa\u73af\u65f6\uff0c\u8bbf\u95ee\u5143\u7d20\u7684\u987a\u5e8f\uff1a \u4ece\u5934\u5230\u5c3e\u7684\u6240\u6709\u4f4d\u7f6e \u4e0d\u4f1a\u6309\u7167\u7279\u5b9a\u7684\u987a\u5e8f map \u51fd\u6570\u4f1a\u521b\u5efa\u4e00\u4e2a\u4ec0\u4e48\u6837\u7684\u5e8f\u5217\uff1a \u5728\u7ed9\u5b9a\u7684\u591a\u9879\u96c6\u91cc\uff0c\u901a\u8fc7\u5e03\u5c14\u6d4b\u8bd5\u7684\u5143\u7d20 \u5728\u7ed9\u5b9a\u7684\u591a\u9879\u96c6\u91cc\uff0c\u5bf9\u5143\u7d20\u6267\u884c\u51fd\u6570\u7684\u7ed3\u679c filter \u51fd\u6570\u4f1a\u521b\u5efa\u4e00\u4e2a\u4ec0\u4e48\u6837\u7684\u5e8f\u5217\uff1a \u5728\u7ed9\u5b9a\u7684\u591a\u9879\u96c6\u91cc\uff0c\u901a\u8fc7\u5e03\u5c14\u6d4b\u8bd5\u7684\u5143\u7d20 \u5728\u7ed9\u5b9a\u7684\u591a\u9879\u96c6\u91cc\uff0c\u5bf9\u5143\u7d20\u6267\u884c\u51fd\u6570\u7684\u7ed3\u679c 2.7.\u7f16\u7a0b\u7ec3\u4e60 \u00b6 1\uff0e\u5728Shell\u7a97\u53e3\u7684\u63d0\u793a\u7b26\u4e0b\u4f7f\u7528 dir \u548c help \u51fd\u6570\u6765\u63a2\u7d22Python\u7684\u5185\u7f6e\u591a\u9879\u96c6\u7c7b\u578b str \u3001 list \u3001 tuple \u3001 set \u4ee5\u53ca dict \u7684\u63a5\u53e3\u3002\u5b83\u4eec\u7684\u8bed\u6cd5\u662f dir() \u548c help() \u3002 \u89e3\u7b54\uff1a \u53ef\u4ee5\u901a\u8fc7\u4ee5\u4e0b\u65b9\u5f0f\u6765\u4e86\u89e3\u5b83\u4eec\u7684\u63a5\u53e3\uff1a \u5b57\u7b26\u4e32 ( str ) \u7c7b\u578b\uff1a # \u4f7f\u7528 dir() \u51fd\u6570\u5217\u51fa\u5b57\u7b26\u4e32\u7c7b\u578b\u7684\u6240\u6709\u65b9\u6cd5\u548c\u5c5e\u6027 dir ( str ) # \u4f7f\u7528 help() \u51fd\u6570\u83b7\u53d6\u5173\u4e8e\u5b57\u7b26\u4e32\u7c7b\u578b\u7684\u8be6\u7ec6\u4fe1\u606f help ( str ) \u5217\u8868 ( list ) \u7c7b\u578b\uff1a # \u4f7f\u7528 dir() \u51fd\u6570\u5217\u51fa\u5217\u8868\u7c7b\u578b\u7684\u6240\u6709\u65b9\u6cd5\u548c\u5c5e\u6027 dir ( list ) x # \u4f7f\u7528 help() \u51fd\u6570\u83b7\u53d6\u5173\u4e8e\u5217\u8868\u7c7b\u578b\u7684\u8be6\u7ec6\u4fe1\u606f help ( list ) \u5143\u7ec4 ( tuple ) \u7c7b\u578b\uff1a # \u4f7f\u7528 dir() \u51fd\u6570\u5217\u51fa\u5143\u7ec4\u7c7b\u578b\u7684\u6240\u6709\u65b9\u6cd5\u548c\u5c5e\u6027 dir ( tuple ) # \u4f7f\u7528 help() \u51fd\u6570\u83b7\u53d6\u5173\u4e8e\u5143\u7ec4\u7c7b\u578b\u7684\u8be6\u7ec6\u4fe1\u606f help ( tuple ) \u96c6\u5408 ( set ) \u7c7b\u578b\uff1a # \u4f7f\u7528 dir() \u51fd\u6570\u5217\u51fa\u96c6\u5408\u7c7b\u578b\u7684\u6240\u6709\u65b9\u6cd5\u548c\u5c5e\u6027 dir ( set ) # \u4f7f\u7528 help() \u51fd\u6570\u83b7\u53d6\u5173\u4e8e\u96c6\u5408\u7c7b\u578b\u7684\u8be6\u7ec6\u4fe1\u606f help ( set ) \u5b57\u5178 ( dict ) \u7c7b\u578b\uff1a # \u4f7f\u7528 dir() \u51fd\u6570\u5217\u51fa\u5b57\u5178\u7c7b\u578b\u7684\u6240\u6709\u65b9\u6cd5\u548c\u5c5e\u6027 dir ( dict ) # \u4f7f\u7528 help() \u51fd\u6570\u83b7\u53d6\u5173\u4e8e\u5b57\u5178\u7c7b\u578b\u7684\u8be6\u7ec6\u4fe1\u606f help ( dict ) dir() \u51fd\u6570\u5c06\u8fd4\u56de\u4e00\u4e2a\u5305\u542b\u6240\u6709\u65b9\u6cd5\u548c\u5c5e\u6027\u540d\u79f0\u7684\u5217\u8868\uff0c\u800c help() \u51fd\u6570\u5c06\u663e\u793a\u5173\u4e8e\u8be5\u7c7b\u578b\u7684\u8be6\u7ec6\u5e2e\u52a9\u4fe1\u606f\uff0c\u5305\u62ec\u6bcf\u4e2a\u65b9\u6cd5\u7684\u8bf4\u660e\u548c\u7528\u6cd5\u793a\u4f8b\u3002 2\uff0e\u67e5\u770b java.util \u5305\u91cc\u6240\u63d0\u4f9b\u7684Java\u591a\u9879\u96c6\u7c7b\u578b\uff0c\u5e76\u548cPython\u7684\u591a\u9879\u96c6\u7c7b\u578b\u52a0\u4ee5\u6bd4\u8f83\u3002 java.util \u5305\u4e2d\u63d0\u4f9b\u4e86\u8bb8\u591aJava\u7684\u96c6\u5408\u7c7b\u578b\uff0c\u5305\u62ec\u5217\u8868\u3001\u96c6\u5408\u3001\u6620\u5c04\u7b49\u3002\u4e0b\u9762\u5c06\u5217\u51fa\u5176\u4e2d\u4e00\u4e9b\u5e38\u7528\u7684\u591a\u9879\u96c6\u7c7b\u578b\uff0c\u5e76\u5c06\u5b83\u4eec\u4e0ePython\u4e2d\u7684\u591a\u9879\u96c6\u7c7b\u578b\u8fdb\u884c\u6bd4\u8f83\u3002 Java ArrayList vs Python List: Java ArrayList \u662f\u4e00\u4e2a\u53ef\u53d8\u5927\u5c0f\u7684\u52a8\u6001\u6570\u7ec4\u3002 Python List \u4e5f\u662f\u53ef\u53d8\u5927\u5c0f\u7684\u52a8\u6001\u6570\u7ec4\uff0c\u53ef\u4ee5\u5bb9\u7eb3\u4efb\u610f\u7c7b\u578b\u7684\u6570\u636e\u3002 Java HashSet vs Python Set: Java HashSet \u662f\u4e00\u4e2a\u4e0d\u5141\u8bb8\u91cd\u590d\u5143\u7d20\u7684\u96c6\u5408\u3002 Python Set \u4e5f\u4e0d\u5141\u8bb8\u91cd\u590d\u5143\u7d20\uff0c\u540c\u65f6\u8fd8\u6709\u4e00\u4e2a\u7279\u6b8a\u7c7b\u578b\u7684\u96c6\u5408\u53eb\u505a frozenset \uff0c\u5b83\u662f\u4e0d\u53ef\u53d8\u7684\u3002 Java LinkedHashSet vs Python OrderedDict: Java LinkedHashSet \u662f\u4e00\u4e2a\u4fdd\u6301\u5143\u7d20\u63d2\u5165\u987a\u5e8f\u7684\u96c6\u5408\uff0c\u4e0d\u5141\u8bb8\u91cd\u590d\u5143\u7d20\u3002 Python OrderedDict \u662f\u4e00\u4e2a\u6709\u5e8f\u5b57\u5178\uff0c\u4fdd\u6301\u5143\u7d20\u63d2\u5165\u987a\u5e8f\uff0c\u53ef\u4ee5\u7528\u4e8e\u521b\u5efa\u6709\u5e8f\u7684\u952e-\u503c\u5bf9\u96c6\u5408\u3002 Java TreeSet vs Python SortedSet: Java TreeSet \u662f\u4e00\u4e2a\u81ea\u7136\u6392\u5e8f\u6216\u8005\u901a\u8fc7\u63d0\u4f9b\u7684\u6bd4\u8f83\u5668\u8fdb\u884c\u6392\u5e8f\u7684\u96c6\u5408\uff0c\u4e0d\u5141\u8bb8\u91cd\u590d\u5143\u7d20\u3002 Python \u6ca1\u6709\u4e13\u95e8\u7684 SortedSet \u7c7b\uff0c\u4f46\u4f60\u53ef\u4ee5\u4f7f\u7528 sorted() \u51fd\u6570\u5bf9\u96c6\u5408\u8fdb\u884c\u6392\u5e8f\u3002 Java HashMap vs Python Dictionary: Java HashMap \u662f\u4e00\u4e2a\u65e0\u5e8f\u7684\u952e-\u503c\u5bf9\u6620\u5c04\uff0c\u4e0d\u5141\u8bb8\u91cd\u590d\u952e\u3002 Python Dictionary \u662f\u4e00\u4e2a\u65e0\u5e8f\u7684\u952e-\u503c\u5bf9\u6620\u5c04\uff0c\u952e\u662f\u552f\u4e00\u7684\u3002 Java TreeMap vs Python OrderedDict: Java TreeMap \u662f\u4e00\u4e2a\u57fa\u4e8e\u7ea2\u9ed1\u6811\u7684\u6709\u5e8f\u6620\u5c04\u3002 Python OrderedDict \u5728\u952e\u7684\u63d2\u5165\u987a\u5e8f\u4e0a\u4fdd\u6301\u6709\u5e8f\u3002 Java \u7684\u591a\u9879\u96c6\u7c7b\u578b\u548c Python \u7684\u591a\u9879\u96c6\u7c7b\u578b\u5728\u529f\u80fd\u4e0a\u975e\u5e38\u7c7b\u4f3c\uff0c\u90fd\u63d0\u4f9b\u4e86\u5404\u79cd\u4e0d\u540c\u7684\u96c6\u5408\u7c7b\u578b\u6765\u9002\u5e94\u4e0d\u540c\u7684\u9700\u6c42\u3002\u9700\u8981\u6839\u636e\u5177\u4f53\u7684\u4f7f\u7528\u60c5\u51b5\u6765\u9009\u62e9\u54ea\u79cd\u96c6\u5408\u7c7b\u578b\u66f4\u9002\u5408\u3002\u540c\u65f6\uff0cPython \u8fd8\u63d0\u4f9b\u4e86\u65b9\u4fbf\u7684\u5217\u8868\u63a8\u5bfc\u3001\u96c6\u5408\u63a8\u5bfc\u548c\u5b57\u5178\u63a8\u5bfc\u7b49\u7279\u6027\uff0c\u53ef\u4ee5\u66f4\u52a0\u4fbf\u6377\u5730\u521b\u5efa\u548c\u5904\u7406\u591a\u9879\u96c6\u3002","title":"\u591a\u9879\u96c6\u7684\u6982\u8ff0"},{"location":"python/DataStructure/02_CollectionsOverview/#2","text":"\u591a\u9879\u96c6\uff08collection\uff09\u662f\u6307\u7531 0 \u4e2a\u6216\u8005\u591a\u4e2a\u5143\u7d20\u7ec4\u6210\u7684\u6982\u5ff5\u5355\u5143\u3002 \u4ece\u4e24\u4e2a\u89d2\u5ea6\u770b\u5f85\u591a\u9879\u96c6\uff1a \u591a\u9879\u96c6\u7684\u7528\u6237\u6216\u8005\u5ba2\u6237\u4f1a\u5173\u5fc3\u5b83\u4eec\u5728\u4e0d\u540c\u7684\u5e94\u7528\u7a0b\u5e8f\u91cc\u80fd\u505a\u4e9b\u4ec0\u4e48\u3002 \u591a\u9879\u96c6\u7684\u5f00\u53d1\u8005\u6216\u8005\u5b9e\u73b0\u8005\u5219\u4f1a\u5173\u5fc3\u5982\u4f55\u624d\u80fd\u8ba9\u5b83\u4eec\u6210\u4e3a\u6700\u597d\u7684\u901a\u7528\u8d44\u6e90\u4ee5\u88ab\u4f7f\u7528\u3002 \u76ee\u6807\uff1a \u5b9a\u4e49\u591a\u9879\u96c6\u76844\u4e2a\u901a\u7528\u7c7b\u578b\uff1a \u7ebf\u6027\u591a\u9879\u96c6 \u5206\u5c42\u591a\u9879\u96c6 \u56fe\u591a\u9879\u96c6 \u65e0\u5e8f\u591a\u9879\u96c6 \u4e86\u89e34\u4e2a\u591a\u9879\u96c6\u7c7b\u578b\u4e2d\u7684\u7279\u5b9a\u7c7b\u578b\uff1b \u4e86\u89e3\u8fd9\u4e9b\u591a\u9879\u96c6\u9002\u5408\u7528\u5728\u4ec0\u4e48\u7c7b\u578b\u7684\u5e94\u7528\u7a0b\u5e8f\u91cc\uff1b \u63cf\u8ff0\u6bcf\u79cd\u591a\u9879\u96c6\u7c7b\u578b\u7684\u5e38\u7528\u64cd\u4f5c\uff1b \u63cf\u8ff0\u591a\u9879\u96c6\u7684\u62bd\u8c61\u7c7b\u578b\u548c\u5b9e\u73b0\u4e4b\u95f4\u7684\u533a\u522b\uff1b","title":"2.\u591a\u9879\u96c6\u7684\u6982\u8ff0"},{"location":"python/DataStructure/02_CollectionsOverview/#21","text":"\u5185\u7f6e\u591a\u9879\u96c6\u7c7b\u578b\uff1a \u5b57\u7b26\u4e32 str \u5217\u8868 list \u5143\u7ec4 tuple \u96c6\u5408 set \u5b57\u5178 dict \u5176\u4ed6\u591a\u9879\u96c6\u7c7b\u578b\uff1a \u6808 \u961f\u5217 \u4f18\u5148\u961f\u5217 \u4e8c\u53c9\u67e5\u627e\u6811 \u5806 \u56fe \u5305 \u6709\u5e8f\u591a\u9879\u96c6 \u591a\u9879\u96c6\u901a\u5e38\u4e0d\u662f\u9759\u6001\uff08static\uff09\u7684\uff0c\u800c\u662f\u52a8\u6001\uff08dynamic\uff09\u7684\uff0c\u53ef\u4ee5\u6839\u636e\u9700\u8981\u6765\u6269\u5927\u6216\u8005\u7f29\u5c0f\u591a\u9879\u96c6\u3002 \u4e0d\u53ef\u53d8\u591a\u9879\u96c6\uff08immutable collection\uff09\u7684\u5185\u5bb9\u5728\u7a0b\u5e8f\u8fd0\u884c\u8fc7\u7a0b\u4e2d\u662f\u4e0d\u53ef\u6539\u53d8\u7684\uff08\u5143\u7d20\u4e0d\u53ef\u4ee5\u6dfb\u52a0\u3001\u5220\u9664\u6216\u8005\u66ff\u6362\uff09\uff0c\u6bd4\u5982\u5143\u7ec4tuple\u3002 \u53ef\u53d8\u591a\u9879\u96c6\uff08mutable collection\uff09\u91cc\u7684\u5185\u5bb9\u53ef\u4ee5\u5728\u7a0b\u5e8f\u7684\u6574\u4e2a\u8fd0\u884c\u8fc7\u7a0b\u4e2d\u88ab\u6539\u53d8\uff0c\u6bd4\u5982\u5b57\u7b26\u4e32\u3001\u5217\u8868list\u3002 \u591a\u9879\u96c6\u6309\u6784\u6210\u65b9\u5f0f\u5212\u5206\u7684\u7c7b\u578b\uff1a \u7ebf\u6027\u591a\u9879\u96c6 \u5206\u5c42\u591a\u9879\u96c6 \u56fe\u591a\u9879\u96c6 \u65e0\u5e8f\u591a\u9879\u96c6 \u6709\u5e8f\u591a\u9879\u96c6","title":"2.1.\u591a\u9879\u96c6\u7c7b\u578b"},{"location":"python/DataStructure/02_CollectionsOverview/#211","text":"\u7ebf\u6027\u591a\u9879\u96c6\uff08linear collection\uff09\u91cc\u7684\u5143\u7d20\u6309\u7167\u4f4d\u7f6e\u8fdb\u884c\u6392\u5217\u3002 \u9664\u4e86\u7b2c\u4e00\u4e2a\u5143\u7d20\uff0c\u5176\u4ed6\u6bcf\u4e2a\u5143\u7d20\u90fd\u6709\u4e14\u53ea\u6709\u4e00\u4e2a\u524d\u5e8f\uff1b \u9664\u4e86\u6700\u540e\u4e00\u4e2a\u5143\u7d20\uff0c\u5176\u4ed6\u6bcf\u4e2a\u5143\u7d20\u90fd\u6709\u4e14\u53ea\u6709\u4e00\u4e2a\u540e\u5e8f\uff1b \u5b9e\u4f8b\uff1a\u6392\u961f\u7684\u4eba\uff0c\u8d2d\u7269\u6e05\u5355\uff0c\u5806\u53e0\u5728\u4e00\u8d77\u7684\u9910\u76d8\u7b49\u3002","title":"2.1.1.\u7ebf\u6027\u591a\u9879\u96c6"},{"location":"python/DataStructure/02_CollectionsOverview/#212","text":"\u5206\u5c42\u591a\u9879\u96c6\uff08hierarchical collection\uff09\u91cc\u7684\u6570\u636e\u5143\u7d20\u4f1a\u4ee5\u7c7b\u4f3c\u4e8e\u5012\u7f6e\u7684\u6811\u7ed3\u6784\u8fdb\u884c\u6392\u5217\u3002\u9664\u4e86\u9876\u90e8\u7684\u6570\u636e\u5143\u7d20\uff0c\u5176\u4ed6\u6bcf\u4e2a\u6570\u636e\u5143\u7d20\u90fd\u6709\u4e14\u53ea\u6709\u4e00\u4e2a\u524d\u5e8f\uff0c\u88ab\u79f0\u4e3a\u7236\u5143\u7d20\uff08parent\uff09\uff0c\u4f46\u5b83\u4eec\u53ef\u4ee5\u6709\u8bb8\u591a\u7684\u540e\u5e8f\uff0c\u88ab\u79f0\u4e3a\u5b50\u5143\u7d20\uff08children\uff09\u3002 \u56fe\u4f8b\u4e2d\uff0c D3 \u7684\u524d\u5e8f\u7236\u5143\u7d20\u662f D1 \uff0c D3 \u7684\u540e\u7eed\u5b50\u5143\u7d20\u662f D4 \u3001 D5 \u3001 D6 \u3002 \u5b9e\u4f8b\uff1a\u6587\u4ef6\u76ee\u5f55\u7cfb\u7edf\u3001\u516c\u53f8\u7684\u7ec4\u7ec7\u67b6\u6784\u3001\u4e66\u7684\u76ee\u5f55\u7b49\u3002","title":"2.1.2.\u5206\u5c42\u591a\u9879\u96c6"},{"location":"python/DataStructure/02_CollectionsOverview/#213","text":"\u56fe\u591a\u9879\u96c6\uff08graph collection\uff09\u4e5f\u88ab\u79f0\u4e3a\u56fe\uff08graph\uff09\uff0c\u5b83\u662f\u8fd9\u6837\u4e00\u4e2a\u591a\u9879\u96c6\uff1a\u5b83\u7684\u6bcf\u4e00\u4e2a\u6570\u636e\u5143\u7d20\u90fd\u53ef\u4ee5\u6709\u591a\u4e2a\u524d\u5e8f\u548c\u591a\u4e2a\u540e\u5e8f\u3002 \u56fe\u4f8b\u4e2d\uff0c\u8fde\u63a5\u5230 D3 \u7684\u6240\u6709\u5143\u7d20\u4f1a\u88ab\u5f53\u4f5c\u5b83\u7684\u524d\u5e8f\u548c\u540e\u5e8f\uff0c\u5b83\u4eec\u4e5f\u56e0\u6b64\u88ab\u79f0\u4e3a D3 \u7684\u90bb\u5c45\u3002 \u5b9e\u4f8b\uff1a\u57ce\u5e02\u4e4b\u95f4\u7684\u822a\u7ebf\u56fe\u3001\u4e07\u7ef4\u7f51\u7b49\u3002","title":"2.1.3.\u56fe\u591a\u9879\u96c6"},{"location":"python/DataStructure/02_CollectionsOverview/#214","text":"\u65e0\u5e8f\u591a\u9879\u96c6\uff08unordered collection\uff09\u91cc\u7684\u5143\u7d20\u6ca1\u6709\u7279\u5b9a\u7684\u987a\u5e8f\uff0c\u5e76\u4e14\u4e0d\u4f1a\u7528\u4efb\u4f55\u660e\u786e\u7684\u65b9\u5f0f\u6765\u6307\u51fa\u5143\u7d20\u7684\u524d\u5e8f\u6216\u8005\u540e\u5e8f\u3002 \u5b9e\u4f8b\uff1a\u4e00\u888b\u5f39\u73e0\u7b49\u3002","title":"2.1.4.\u65e0\u5e8f\u591a\u9879\u96c6"},{"location":"python/DataStructure/02_CollectionsOverview/#215","text":"\u6709\u5e8f\u591a\u9879\u96c6\uff08sorted collection\uff09\u4f1a\u5bf9\u5b83\u91cc\u9762\u7684\u5143\u7d20\u8fdb\u884c\u81ea\u7136\u6392\u5e8f\uff08natural ordering\uff09\u3002 \u8981\u8fdb\u884c\u81ea\u7136\u6392\u5e8f\uff0c\u5c31\u5fc5\u987b\u8981\u6709\u89c4\u5219\u6765\u5bf9\u6709\u5e8f\u591a\u9879\u96c6\u91cc\u7684\u5143\u7d20\u52a0\u4ee5\u6bd4\u8f83\uff0c\u4f8b\u5982 item(i) <= item(i+1) \u8fd9\u6837\u7684\u2014\u2014\u89c4\u5219\u3002 \u6709\u5e8f\u5217\u8868\u662f\u6700\u5e38\u89c1\u7684\u6709\u5e8f\u591a\u9879\u96c6\u3002\u6709\u5e8f\u591a\u9879\u96c6\u4e0d\u4e00\u5b9a\u662f\u7ebf\u6027\u7684\u6216\u8005\u6309\u7167\u4f4d\u7f6e\u8fdb\u884c\u6392\u5e8f\u7684\u3002 \u5bf9\u4e8e\u96c6\u5408\u3001\u5305\u3001\u5b57\u5178\uff0c\u867d\u7136\u4e0d\u80fd\u6309\u7167\u4f4d\u7f6e\u6765\u8bbf\u95ee\u5b83\u4eec\u7684\u5143\u7d20\uff0c\u4f46\u5b83\u4eec\u90fd\u53ef\u4ee5\u662f\u6709\u5e8f\u7684\u3002 \u7279\u6b8a\u7684\u5206\u5c42\u591a\u9879\u96c6\u7c7b\u578b\uff08\u5982\u4e8c\u53c9\u67e5\u627e\u6811\uff09\u4e5f\u4f1a\u5bf9\u5176\u4e2d\u7684\u5143\u7d20\u8fdb\u884c\u81ea\u7136\u6392\u5e8f\u3002","title":"2.1.5.\u6709\u5e8f\u591a\u9879\u96c6"},{"location":"python/DataStructure/02_CollectionsOverview/#216","text":"\u4e0b\u9762\u5206\u7c7b\u91cc\u7684\u7c7b\u578b\u540d\u79f0\u6307\u7684\u5e76\u4e0d\u662f\u591a\u9879\u96c6\u7684\u7279\u5b9a\u5b9e\u73b0\u3002\u4e00\u79cd\u7279\u5b9a\u7c7b\u578b\u7684\u591a\u9879\u96c6\u53ef\u4ee5\u6709\u591a\u4e2a\u5b9e\u73b0\u3002 \u591a\u9879\u96c6 | ---\u56fe\u591a\u9879\u96c6 | ---\u5206\u5c42\u591a\u9879\u96c6 | | ---\u4e8c\u53c9\u67e5\u627e\u6811 | | ---\u5806 | ---\u7ebf\u6027\u591a\u9879\u96c6 | | ---\u5217\u8868 | | | ---\u6709\u5e8f\u5217\u8868 | | ---\u961f\u5217 | | | ---\u4f18\u5148\u5bf9\u5217 | | ---\u6808 | | ---\u5b57\u7b26\u4e32 | ---\u65e0\u5e8f\u591a\u9879\u96c6 | ---\u5305 | | ---\u6709\u5e8f\u5305 | ---\u5b57\u5178 | | ---\u6709\u5e8f\u5305 | ---\u96c6\u5408 | ---\u6709\u5e8f\u96c6\u5408","title":"2.1.6.\u591a\u9879\u96c6\u7c7b\u578b\u7684\u5206\u7c7b"},{"location":"python/DataStructure/02_CollectionsOverview/#22","text":"\u591a\u9879\u96c6\u64cd\u4f5c\u7c7b\u522b\uff1a \u786e\u5b9a\u5927\u5c0f\uff1a\u4f7f\u7528 len \u51fd\u6570\u83b7\u53d6\u5f53\u524d\u591a\u9879\u96c6\u91cc\u7684\u5143\u7d20\u6570\u91cf\u3002 \u68c0\u6d4b\u5143\u7d20\u6210\u5458\uff1a\u4f7f\u7528 in \u8fd0\u7b97\u7b26\u5728\u591a\u9879\u96c6\u91cc\u641c\u7d22\u6307\u5b9a\u7684\u76ee\u6807\u5143\u7d20\u3002\u5982\u679c\u627e\u5230\u4e86\u8fd9\u4e2a\u5143\u7d20\uff0c\u5219\u8fd4\u56deTrue\uff0c\u5426\u5219\u8fd4\u56deFalse\u3002 \u904d\u5386\u591a\u9879\u96c6\uff1a\u4f7f\u7528 for \u5faa\u73af\u8bbf\u95ee\u591a\u9879\u96c6\u91cc\u7684\u6b38\u4e00\u4e2a\u5143\u7d20\u3002\u5143\u7d20\u7684\u8bbf\u95ee\u987a\u5e8f\u53d6\u51b3\u4e8e\u591a\u9879\u96c6\u7684\u7c7b\u578b\u3002 \u83b7\u53d6\u591a\u9879\u96c6\u7684\u5b57\u7b26\u4e32\u8868\u793a\uff1a\u4f7f\u7528 str \u51fd\u6570\u83b7\u53d6\u591a\u9879\u96c6\u7684\u5b57\u7b26\u4e32\u8868\u793a\u3002 \u76f8\u7b49\u68c0\u6d4b\uff1a\u4f7f\u7528 == \u8fd0\u7b97\u7b26\u6765\u786e\u5b9a\u4e24\u4e2a\u591a\u9879\u96c6\u662f\u5426\u76f8\u7b49\u3002\u5982\u679c\u4e24\u4e2a\u591a\u9879\u96c6\u80b2\u6709\u76f8\u540c\u7684\u7c7b\u578b\uff0c\u5e76\u4e14\u5305\u542b\u76f8\u540c\u7684\u5143\u7d20\uff0c\u90a3\u4e48\u5b83\u4eec\u5c31\u662f\u76f8\u7b49\u7684\u3002\u6bd4\u8f83\u8fd9\u4e9b\u5143\u7d20\u5bf9\u7684\u987a\u5e8f\u53d6\u51b3\u4e8e\u591a\u9879\u96c6\u7684\u7c7b\u578b\u3002 \u8fde\u63a5\u4e24\u4e2a\u591a\u9879\u96c6\uff1a\u4f7f\u7528 + \u8fd0\u7b97\u7b26\u6765\u5f97\u5230\u4e00\u4e2a\u548c\u64cd\u4f5c\u6570\u76f8\u540c\u7c7b\u578b\u7684\u65b0\u591a\u9879\u96c6\uff0c\u5e76\u4e14\u5305\u542b\u4e24\u4e2a\u64cd\u4f5c\u6570\u91cc\u7684\u6240\u6709\u5143\u7d20\u3002 \u8f6c\u6362\u4e3a\u5176\u4ed6\u7c7b\u578b\u7684\u591a\u9879\u96c6\uff1a\u521b\u5efa\u4e00\u4e2a\u4e0e\u6e90\u591a\u9879\u96c6\u5177\u6709\u76f8\u540c\u5143\u7d20\u7684\u65b0\u591a\u9879\u96c6\u3002\u514b\u9686\u64cd\u4f5c\u65f6\u7c7b\u578b\u8f6c\u6362\u7684\u4e00\u79cd\u7279\u6b8a\u60c5\u51b5\uff0c\u56e0\u4e3a\u8f93\u5165\u8f93\u51fa\u7684\u4e24\u4e2a\u591a\u9879\u96c6\u5177\u6709\u76f8\u540c\u7c7b\u578b\u3002 \u63d2\u5165\u4e00\u4e2a\u5143\u7d20\uff1a\u5982\u679c\u53ef\u4ee5\uff0c\u5219\u5728\u7ed9\u5b9a\u7684\u4f4d\u7f6e\u5c06\u5bf9\u5e94\u7684\u5143\u7d20\u6dfb\u52a0\u5230\u591a\u9879\u96c6\u91cc\u3002 \u5220\u9664\u4e00\u4e2a\u5143\u7d20\uff1a\u5982\u679c\u53ef\u4ee5\uff0c\u5219\u5728\u7ed9\u5b9a\u7684\u4f4d\u7f6e\u5c06\u5bf9\u5e94\u7684\u5143\u7d20\u4ece\u591a\u9879\u96c6\u4e2d\u5220\u9664\u3002 \u66ff\u6362\u4e00\u4e2a\u5143\u7d20\uff1a\u5c06\u5220\u9664\u548c\u63d2\u5165\u5408\u5e76\u4e3a\u4e00\u9879\u64cd\u4f5c\u3002 \u8bbf\u95ee\u6216\u8005\u83b7\u53d6\u5143\u7d20\uff1a\u5982\u679c\u800c\u5df2\uff0c\u5219\u5728\u7ed9\u5b9a\u7684\u4f4d\u7f6e\u83b7\u53d6\u5143\u7d20\u3002","title":"2.2.\u591a\u9879\u96c6\u64cd\u4f5c"},{"location":"python/DataStructure/02_CollectionsOverview/#221","text":"\u5728Python\u91cc\uff0c\u4e0d\u540c\u591a\u9879\u96c6\u7c7b\u578b\u7684\u63d2\u5165\u3001\u5220\u9664\u3001\u66ff\u6362\u6216\u8005\u8bbf\u95ee\u64cd\u4f5c\u5e76\u6ca1\u6709\u7edf\u4e00\u7684\u540d\u79f0\uff0c\u4f46\u662f\u4f1a\u6709\u4e00\u4e9b\u6807\u51c6\u53d8\u4f53\u3002\u6bd4\u5982\uff0c \u65b9\u6cd5pop\u4f1a\u88ab\u7528\u6765\u4ece\u5217\u8868\u91cc\u79fb\u9664\u6307\u5b9a\u4f4d\u7f6e\u7684\u5143\u7d20\uff1b \u65b9\u6cd5pop\u4f1a\u88ab\u7528\u6765\u4ece\u5b57\u5178\u91cc\u79fb\u9664\u7ed9\u5b9a\u952e\u6240\u5bf9\u5e94\u7684\u503c\uff1b \u65b9\u6cd5remove\u4f1a\u88ab\u7528\u6765\u4ece\u5217\u8868\u6216\u8005\u67d0\u4e9b\u591a\u9879\u96c6\u91cc\u5220\u9664\u6307\u5b9a\u7684\u5143\u7d20\uff1b \u5bf9\u4e8e\u65b0\u5f00\u53d1\u51fa\u7684\u3001Python\u5c1a\u4e0d\u652f\u6301\u7684\u591a\u9879\u96c6\u7c7b\u578b\uff0c\u5c3d\u53ef\u80fd\u5730\u4f7f\u7528\u6807\u51c6\u7684\u8fd0\u7b97\u7b26\u3001\u51fd\u6570\u4ee5\u53ca\u65b9\u6cd5\u540d\u79f0\u5bf9\u5b83\u4eec\u8fdb\u884c\u64cd\u4f5c\u3002","title":"2.2.1.\u6240\u6709\u591a\u9879\u96c6\u7c7b\u578b\u4e2d\u7684\u57fa\u672c\u64cd\u4f5c"},{"location":"python/DataStructure/02_CollectionsOverview/#222","text":"\u7c7b\u578b\u8f6c\u6362\uff0c\u5c06\u4e00\u79cd\u7c7b\u578b\u7684\u591a\u9879\u96c6\u8f6c\u6362\u4e3a\u53e6\u4e00\u79cd\u7c7b\u578b\u7684\u591a\u9879\u96c6\u3002\u4f8b\u5982\uff0c\u901a\u8fc7 list \u6216 tuple \u51fd\u6570\u5c06\u5b57\u7b26\u4e32\u8f6c\u6362\u4e3a\u5217\u8868\u6216\u8005\u5143\u7ec4\u3002 list \u6216 tuple \u51fd\u6570\u7684\u53c2\u6570\u4e0d\u4e00\u5b9a\u662f\u53e6\u4e00\u4e2a\u591a\u9879\u96c6\uff0c\u4e5f\u53ef\u4ee5\u662f\u4efb\u4f55\u7684\u53ef\u8fed\u4ee3\u5bf9\u8c61\uff08iterable object\uff09\u3002 \u53ef\u8fed\u4ee3\u5bf9\u8c61\u662f\u6307\uff0c\u80fd\u591f\u4f7f\u7528for\u5faa\u73af\u6765\u8bbf\u95ee\u7684\u4e00\u7cfb\u5217\u5143\u7d20\u3002\uff08\u591a\u9879\u96c6\u672c\u8eab\u4e5f\u662f\u53ef\u8fed\u4ee3\u5bf9\u8c61\uff09","title":"2.2.2.\u7c7b\u578b\u8f6c\u6362"},{"location":"python/DataStructure/02_CollectionsOverview/#223","text":"\u7c7b\u578b\u8f6c\u6362\u7684\u4e00\u79cd\u7279\u6b8a\u60c5\u51b5\u662f\u514b\u9686\uff0c\u5b83\u7684\u529f\u80fd\u662f\u8fd4\u56de\u8f6c\u6362\u51fd\u6570\u4e2d\u53c2\u6570\u7684\u5b8c\u6574\u526f\u672c\u3002 \u4f8b\u5982\uff1a myList1 = [ 2 , 4 , 8 ] myList2 = list ( myList1 ) myList1 is myList2 # False myList1 == myList2 # True \u6ce8\u610f\uff1a \u4e0a\u9762\u4e24\u4e2a\u5217\u8868\u4e0d\u4ec5\u6709\u76f8\u540c\u7684\u7ed3\u6784\uff0c\u5b83\u4eec\u8fd8\u6709\u76f8\u540c\u7684\u5143\u7d20\uff0c\u6bcf\u5bf9\u5143\u7d20\u5728\u4e24\u4e2a\u5217\u8868\u91cc\u7684\u4f4d\u7f6e\u90fd\u76f8\u540c\u3002\u4f46\u662f\uff0c\u4ed6\u4eec\u662f\u4e24\u4e2a\u4e0d\u540c\u7684\u5bf9\u8c61\u3002 \u4e0a\u4f8b\u4e2d list \u51fd\u6570\u5bf9\u5b83\u7684\u53c2\u6570\u5217\u8868\u8fdb\u884c\u6d45\u62f7\u8d1d\uff08shallow copy\uff09\u3002\u8fd9\u4e9b\u5143\u7d20\u7684\u672c\u8eab\u5728\u6dfb\u52a0\u5230\u65b0\u5217\u8868\u4e4b\u524d\u662f\u4e0d\u4f1a\u88ab\u514b\u9686\u7684\uff0c\u5728\u8fd9\u4e2a\u8fc7\u7a0b\u4e2d\u53ea\u4f1a\u590d\u5236\u5bf9\u8fd9\u4e9b\u5bf9\u8c61\u7684\u5f15\u7528\u3002\u5f53\u5143\u7d20\uff08\u6570\u5b57\u3001\u5b57\u7b26\u4e32\u6216\u8005Python\u7684\u5143\u7ec4\uff09\u4e0d\u53ef\u53d8\u65f6\uff0c\u8fd9\u4e2a\u7b56\u7565\u4e0d\u4f1a\u5f15\u8d77\u95ee\u9898\u3002\u4f46\u662f\uff0c\u5982\u679c\u591a\u9879\u96c6\u5305\u542b\u7684\u662f\u53ef\u53d8\u5143\u7d20\uff0c\u5c31\u53ef\u80fd\u4f1a\u4ea7\u751f\u526f\u4f5c\u7528\u3002\u4e3a\u4e86\u907f\u514d\u8fd9\u79cd\u60c5\u51b5\u7684\u53d1\u751f\uff0c\u6211\u4eec\u53ef\u4ee5\u901a\u8fc7\u5bf9\u6e90\u591a\u9879\u96c6\u7f16\u5199 for \u5faa\u73af\u6765\u521b\u5efa\u6df1\u62f7\u8d1d\uff08deep copy\uff09\uff0c\u8fd9\u4f1a\u628a\u5143\u7d20\u663e\u5f0f\u5730\u514b\u9686\u4e4b\u540e\u518d\u6dfb\u52a0\u5230\u65b0\u7684\u591a\u9879\u96c6\u91cc\u3002","title":"2.2.3.\u514b\u9686\u548c\u76f8\u7b49\u6027"},{"location":"python/DataStructure/02_CollectionsOverview/#23","text":"\u6bcf\u79cd\u7c7b\u578b\u7684\u591a\u9879\u96c6\u90fd\u652f\u6301\u4e00\u4e2a\u8fed\u4ee3\u5668\u6216 for \u5faa\u73af\uff0c\u8fd9\u4e2a\u64cd\u4f5c\u80fd\u591f\u8fed\u4ee3\u8fd9\u4e2a\u591a\u9879\u96c6\u7684\u6240\u6709\u5143\u7d20\u3002\u8fed\u4ee3\u5668\u662f\u591a\u9879\u96c6\u63d0\u4f9b\u7684\u6700\u5173\u952e\u7684\u64cd\u4f5c\u3002 for \u5faa\u73af\u670d\u52a1\u7684\u591a\u9879\u96c6\u4e2d\u5143\u7d20\u7684\u987a\u5e8f\u53d6\u51b3\u4e8e\u591a\u9879\u96c6\u7684\u7ec4\u7ec7\u65b9\u5f0f\u3002\u4f8b\u5982\uff1a \u5217\u8868\u91cc\u7684\u5143\u7d20\u4f1a\u4ece\u5934\u5230\u5c3e\u6309\u7167\u4f4d\u7f6e\u8fdb\u884c\u8bbf\u95ee\uff1b \u6709\u5e8f\u591a\u9879\u96c6\u91cc\u7684\u5143\u7d20\u4f1a\u6309\u4ece\u5c0f\u5230\u5927\u7684\u5347\u5e8f\u8fdb\u884c\u8bbf\u95ee\uff1b \u5bf9\u4e8e\u96c6\u5408\u6216\u8005\u5b57\u5178\u91cc\u7684\u5143\u7d20\u6765\u8bf4\uff0c\u4e0d\u4f1a\u6309\u7167\u7279\u5b9a\u7684\u987a\u5e8f\u8fdb\u884c\u8bbf\u95ee\u3002 \u8fed\u4ee3\u5668\uff08\u4f8b\u5982 for \u5faa\u73af\uff09\u8fd8\u652f\u6301\u4f7f\u7528\u9ad8\u9636\u51fd\u6570 map \u3001 filter \u548c reduce \u3002 \u8fd9\u4e9b\u9ad8\u9636\u51fd\u6570\u90fd\u4f7f\u7528\u53e6\u4e00\u4e2a\u51fd\u6570\u548c\u4e00\u4e2a\u591a\u9879\u96c6\u4f5c\u4e3a\u53c2\u6570\u3002 \u591a\u9879\u96c6\u90fd\u652f\u6301 for \u5faa\u73af\uff0c\u6240\u4ee5 map \u3001 filter \u548c reduce \u51fd\u6570\u53ef\u4ee5\u4e0e\u4efb\u4f55\u7c7b\u578b\u7684\u591a\u9879\u96c6\u4e00\u8d77\u4f7f\u7528\u3002","title":"2.3.\u8fed\u4ee3\u5668\u548c\u9ad8\u9636\u51fd\u6570"},{"location":"python/DataStructure/02_CollectionsOverview/#24","text":"\u4ece\u7528\u6237\uff08\u6bd4\u5982\uff0c\u7a0b\u5e8f\u5458\uff09\u7684\u89d2\u5ea6\u6765\u770b\uff0c\u591a\u9879\u96c6\u662f\u4e00\u79cd\u62bd\u8c61\uff0c\u662f\u4e00\u79cd\u4ee5\u67d0\u79cd\u9884\u5b9a\u884c\u4e3a\u6765\u5b58\u50a8\u548c\u8bbf\u95ee\u6570\u636e\u5143\u7d20\u7684\u65b9\u5f0f\uff0c\u5e76\u4e0d\u9700\u8981\u5173\u5fc3\u591a\u9879\u96c6\u5b9e\u73b0\u7684\u7ec6\u8282\u3002 \u591a\u9879\u96c6\u4e5f\u88ab\u79f0\u4e3a\u62bd\u8c61\u6570\u636e\u7c7b\u578b\uff08Abstract Data Type\uff0cADT\uff09\u3002\u62bd\u8c61\u6570\u636e\u7c7b\u578b\u7684\u7528\u6237\u53ea\u5173\u6ce8\u5b83\u7684\u63a5\u53e3\u4ee5\u53ca\u8fd9\u4e2a\u7c7b\u578b\u5bf9\u8c61\u6240\u63d0\u4f9b\u7684\u4e00\u7ec4\u64cd\u4f5c\u3002 \u5728Python\u91cc\uff0c\u51fd\u6570\u548c\u65b9\u6cd5\u662f\u6700\u5c0f\u7684\u62bd\u8c61\u5355\u5143\uff0c\u7c7b\u7684\u5927\u5c0f\u6b21\u4e4b\uff0c\u6a21\u5757\u662f\u6700\u5927\u7684\u62bd\u8c61\u5355\u5143\u3002 \u8fd9\u91cc\u4f1a\u628a\u62bd\u8c61\u591a\u9879\u96c6\u7c7b\u578b\u7684\u5b9e\u73b0\u5f53\u4f5c\u6a21\u5757\u91cc\u7684\u7c7b\u6216\u8005\u4e00\u7ec4\u76f8\u5173\u7684\u7c7b\u52a0\u4ee5\u63cf\u8ff0\u3002\u6784\u5efa\u8fd9\u4e9b\u7c7b\u5c31\u662f\u9762\u5411\u5bf9\u8c61\u7f16\u7a0b\u3002","title":"2.4.\u591a\u9879\u96c6\u7684\u5b9e\u73b0"},{"location":"python/DataStructure/02_CollectionsOverview/#25","text":"\u591a\u9879\u96c6\u662f\u5305\u542b0\u4e2a\u6216\u591a\u4e2a\u5176\u4ed6\u5bf9\u8c61\u7684\u5bf9\u8c61\u3002\u591a\u9879\u96c6\u53ef\u4ee5\u8fdb\u884c\u7684\u64cd\u4f5c\u6709\u8bbf\u95ee\u5bf9\u8c61\u3001\u63d2\u5165\u5bf9\u8c61\u3001\u5220\u9664\u5bf9\u8c61\u3001\u786e\u5b9a\u591a\u9879\u96c6\u7684\u5927\u5c0f\uff0c\u4ee5\u53ca\u904d\u5386\u6216\u8bbf\u95ee\u8fd9\u4e2a\u591a\u9879\u96c6\u7684\u5bf9\u8c61\u3002 \u591a\u9879\u96c6\u76845\u4e2a\u4e3b\u8981\u7c7b\u578b\u662f\uff1a\u7ebf\u6027\u591a\u9879\u96c6\u3001\u5206\u5c42\u591a\u9879\u96c6\u3001\u56fe\u591a\u9879\u96c6\u3001\u65e0\u5e8f\u591a\u9879\u96c6\u548c\u6709\u5e8f\u591a\u9879\u96c6\u3002 \u7ebf\u6027\u591a\u9879\u96c6\u4f1a\u6309\u7167\u4f4d\u7f6e\u5bf9\u5143\u7d20\u8fdb\u884c\u6392\u5e8f\uff0c\u5176\u4e2d\u9664\u4e86\u7b2c\u4e00\u4e2a\u5143\u7d20\uff0c\u6bcf\u4e2a\u90fd\u6709\u4e14\u53ea\u6709\u4e00\u4e2a\u524d\u5e8f\uff1b\u9664\u4e86\u6700\u540e\u4e00\u4e2a\u5143\u7d20\uff0c\u6bcf\u4e2a\u90fd\u6709\u4e14\u53ea\u6709\u4e00\u4e2a\u540e\u5e8f\u3002 \u5728\u5206\u5c42\u591a\u9879\u96c6\u91cc\uff0c\u9664\u4e86\u4e00\u4e2a\u5143\u7d20\uff0c\u5176\u4ed6\u6240\u6709\u5143\u7d20\u90fd\u6709\u4e14\u53ea\u6709\u4e00\u4e2a\u524d\u5e8f\u4ee5\u53ca0\u4e2a\u6216\u591a\u4e2a\u540e\u5e8f\u3002\u88ab\u79f0\u4e3a\u6839\u7684\u90a3\u4e2a\u989d\u5916\u5143\u7d20\u6ca1\u6709\u524d\u5e8f\u3002 \u56fe\u591a\u9879\u96c6\u91cc\u7684\u5143\u7d20\u53ef\u4ee5\u67090\u4e2a\u6216\u591a\u4e2a\u524d\u5e8f\u4ee5\u53ca0\u4e2a\u6216\u591a\u4e2a\u540e\u5e8f\u3002 \u65e0\u5e8f\u591a\u9879\u96c6\u91cc\u7684\u5143\u7d20\u6ca1\u6709\u7279\u5b9a\u7684\u987a\u5e8f\u3002 \u591a\u9879\u96c6\u662f\u53ef\u8fed\u4ee3\u7684\uff0c\u4e5f\u5c31\u662f\u8bf4\uff0c\u53ef\u4ee5\u4f7f\u7528for\u5faa\u73af\u8bbf\u95ee\u591a\u9879\u96c6\u91cc\u7684\u6240\u6709\u5143\u7d20\u3002\u7a0b\u5e8f\u5458\u4e5f\u53ef\u4ee5\u4f7f\u7528\u9ad8\u9636\u51fd\u6570map\u3001filter\u548creduce\u7b80\u5316\u591a\u9879\u96c6\u7684\u6570\u636e\u5904\u7406\u3002 \u62bd\u8c61\u6570\u636e\u7c7b\u578b\u662f\u4e00\u7ec4\u5bf9\u8c61\u548c\u5bf9\u8fd9\u4e9b\u5bf9\u8c61\u7684\u64cd\u4f5c\u3002\u56e0\u6b64\uff0c\u591a\u9879\u96c6\u662f\u62bd\u8c61\u6570\u636e\u7c7b\u578b\u3002 \u6570\u636e\u7ed3\u6784\u662f\u4e00\u4e2a\u8868\u793a\u591a\u9879\u96c6\u91cc\u5305\u542b\u7684\u6570\u636e\u7684\u5bf9\u8c61\u3002","title":"2.5.\u5c0f\u7ed3"},{"location":"python/DataStructure/02_CollectionsOverview/#26","text":"\u7ebf\u6027\u591a\u9879\u96c6\u7684\u4e00\u4e2a\u4f8b\u5b50\u662f\uff1a \u96c6\u5408\u548c\u6811 \u5217\u8868\u548c\u6808 \u65e0\u5e8f\u591a\u9879\u96c6\u7684\u4e00\u4e2a\u4f8b\u5b50\u662f\uff1a \u961f\u5217\u548c\u5217\u8868 \u96c6\u5408\u548c\u5b57\u5178 \u5206\u5c42\u591a\u9879\u96c6\u53ef\u4ee5\u7528\u6765\u8868\u793a\uff1a \u94f6\u884c\u6392\u961f\u7684\u5ba2\u6237 \u6587\u4ef6\u76ee\u5f55\u7cfb\u7edf \u56fe\u591a\u9879\u96c6\u6700\u80fd\u4ee3\u8868\uff1a \u4e00\u7ec4\u6570\u5b57 \u57ce\u5e02\u4e4b\u95f4\u7684\u822a\u7ebf\u56fe \u5728Python\u91cc\uff0c\u4e24\u4e2a\u591a\u9879\u96c6\u95f4\u7684\u7c7b\u578b\u8f6c\u6362\u64cd\u4f5c\uff1a \u5728\u6e90\u591a\u9879\u96c6\u91cc\u521b\u5efa\u5bf9\u8c61\u7684\u526f\u672c\uff0c\u5e76\u4e14\u628a\u8fd9\u4e9b\u65b0\u5bf9\u8c61\u6dfb\u52a0\u5230\u76ee\u6807\u591a\u9879\u96c6\u7684\u65b0\u5b9e\u4f8b\u91cc \u628a\u5bf9\u6e90\u591a\u9879\u96c6\u5bf9\u8c61\u7684\u5f15\u7528\u6dfb\u52a0\u5230\u76ee\u6807\u591a\u9879\u96c6\u7684\u65b0\u5b9e\u4f8b\u91cc \u4e24\u4e2a\u5217\u8868\u7684 == \u64cd\u4f5c\u5fc5\u987b\uff1a \u6bd4\u8f83\u6bcf\u4e2a\u4f4d\u7f6e\u7684\u5143\u7d20\u5bf9\u662f\u5426\u76f8\u7b49 \u53ea\u4f1a\u9a8c\u8bc1\u4e00\u4e2a\u5217\u8868\u91cc\u7684\u6bcf\u4e00\u4e2a\u5143\u7d20\u662f\u5426\u4e5f\u5728\u53e6\u4e00\u4e2a\u5217\u8868\u91cc \u4e24\u4e2a\u96c6\u5408\u7684 == \u64cd\u4f5c\u5fc5\u987b\uff1a \u6bd4\u8f83\u6bcf\u4e2a\u4f4d\u7f6e\u7684\u5143\u7d20\u5bf9\u662f\u5426\u76f8\u7b49 \u9a8c\u8bc1\u96c6\u5408\u7684\u5927\u5c0f\u662f\u5426\u76f8\u7b49\uff0c\u5e76\u4e14\u4e00\u4e2a\u96c6\u5408\u91cc\u7684\u6bcf\u4e00\u4e2a\u5143\u7d20\u662f\u5426\u4e5f\u5728\u53e6\u4e00\u4e2a\u96c6\u5408\u91cc \u5bf9\u5217\u8868\u8fdb\u884c for \u5faa\u73af\u65f6\uff0c\u8bbf\u95ee\u5143\u7d20\u7684\u987a\u5e8f\uff1a \u4ece\u5934\u5230\u5c3e\u7684\u6240\u6709\u4f4d\u7f6e \u4e0d\u4f1a\u6309\u7167\u7279\u5b9a\u7684\u987a\u5e8f map \u51fd\u6570\u4f1a\u521b\u5efa\u4e00\u4e2a\u4ec0\u4e48\u6837\u7684\u5e8f\u5217\uff1a \u5728\u7ed9\u5b9a\u7684\u591a\u9879\u96c6\u91cc\uff0c\u901a\u8fc7\u5e03\u5c14\u6d4b\u8bd5\u7684\u5143\u7d20 \u5728\u7ed9\u5b9a\u7684\u591a\u9879\u96c6\u91cc\uff0c\u5bf9\u5143\u7d20\u6267\u884c\u51fd\u6570\u7684\u7ed3\u679c filter \u51fd\u6570\u4f1a\u521b\u5efa\u4e00\u4e2a\u4ec0\u4e48\u6837\u7684\u5e8f\u5217\uff1a \u5728\u7ed9\u5b9a\u7684\u591a\u9879\u96c6\u91cc\uff0c\u901a\u8fc7\u5e03\u5c14\u6d4b\u8bd5\u7684\u5143\u7d20 \u5728\u7ed9\u5b9a\u7684\u591a\u9879\u96c6\u91cc\uff0c\u5bf9\u5143\u7d20\u6267\u884c\u51fd\u6570\u7684\u7ed3\u679c","title":"2.6.\u590d\u4e60\u9898"},{"location":"python/DataStructure/02_CollectionsOverview/#27","text":"1\uff0e\u5728Shell\u7a97\u53e3\u7684\u63d0\u793a\u7b26\u4e0b\u4f7f\u7528 dir \u548c help \u51fd\u6570\u6765\u63a2\u7d22Python\u7684\u5185\u7f6e\u591a\u9879\u96c6\u7c7b\u578b str \u3001 list \u3001 tuple \u3001 set \u4ee5\u53ca dict \u7684\u63a5\u53e3\u3002\u5b83\u4eec\u7684\u8bed\u6cd5\u662f dir() \u548c help() \u3002 \u89e3\u7b54\uff1a \u53ef\u4ee5\u901a\u8fc7\u4ee5\u4e0b\u65b9\u5f0f\u6765\u4e86\u89e3\u5b83\u4eec\u7684\u63a5\u53e3\uff1a \u5b57\u7b26\u4e32 ( str ) \u7c7b\u578b\uff1a # \u4f7f\u7528 dir() \u51fd\u6570\u5217\u51fa\u5b57\u7b26\u4e32\u7c7b\u578b\u7684\u6240\u6709\u65b9\u6cd5\u548c\u5c5e\u6027 dir ( str ) # \u4f7f\u7528 help() \u51fd\u6570\u83b7\u53d6\u5173\u4e8e\u5b57\u7b26\u4e32\u7c7b\u578b\u7684\u8be6\u7ec6\u4fe1\u606f help ( str ) \u5217\u8868 ( list ) \u7c7b\u578b\uff1a # \u4f7f\u7528 dir() \u51fd\u6570\u5217\u51fa\u5217\u8868\u7c7b\u578b\u7684\u6240\u6709\u65b9\u6cd5\u548c\u5c5e\u6027 dir ( list ) x # \u4f7f\u7528 help() \u51fd\u6570\u83b7\u53d6\u5173\u4e8e\u5217\u8868\u7c7b\u578b\u7684\u8be6\u7ec6\u4fe1\u606f help ( list ) \u5143\u7ec4 ( tuple ) \u7c7b\u578b\uff1a # \u4f7f\u7528 dir() \u51fd\u6570\u5217\u51fa\u5143\u7ec4\u7c7b\u578b\u7684\u6240\u6709\u65b9\u6cd5\u548c\u5c5e\u6027 dir ( tuple ) # \u4f7f\u7528 help() \u51fd\u6570\u83b7\u53d6\u5173\u4e8e\u5143\u7ec4\u7c7b\u578b\u7684\u8be6\u7ec6\u4fe1\u606f help ( tuple ) \u96c6\u5408 ( set ) \u7c7b\u578b\uff1a # \u4f7f\u7528 dir() \u51fd\u6570\u5217\u51fa\u96c6\u5408\u7c7b\u578b\u7684\u6240\u6709\u65b9\u6cd5\u548c\u5c5e\u6027 dir ( set ) # \u4f7f\u7528 help() \u51fd\u6570\u83b7\u53d6\u5173\u4e8e\u96c6\u5408\u7c7b\u578b\u7684\u8be6\u7ec6\u4fe1\u606f help ( set ) \u5b57\u5178 ( dict ) \u7c7b\u578b\uff1a # \u4f7f\u7528 dir() \u51fd\u6570\u5217\u51fa\u5b57\u5178\u7c7b\u578b\u7684\u6240\u6709\u65b9\u6cd5\u548c\u5c5e\u6027 dir ( dict ) # \u4f7f\u7528 help() \u51fd\u6570\u83b7\u53d6\u5173\u4e8e\u5b57\u5178\u7c7b\u578b\u7684\u8be6\u7ec6\u4fe1\u606f help ( dict ) dir() \u51fd\u6570\u5c06\u8fd4\u56de\u4e00\u4e2a\u5305\u542b\u6240\u6709\u65b9\u6cd5\u548c\u5c5e\u6027\u540d\u79f0\u7684\u5217\u8868\uff0c\u800c help() \u51fd\u6570\u5c06\u663e\u793a\u5173\u4e8e\u8be5\u7c7b\u578b\u7684\u8be6\u7ec6\u5e2e\u52a9\u4fe1\u606f\uff0c\u5305\u62ec\u6bcf\u4e2a\u65b9\u6cd5\u7684\u8bf4\u660e\u548c\u7528\u6cd5\u793a\u4f8b\u3002 2\uff0e\u67e5\u770b java.util \u5305\u91cc\u6240\u63d0\u4f9b\u7684Java\u591a\u9879\u96c6\u7c7b\u578b\uff0c\u5e76\u548cPython\u7684\u591a\u9879\u96c6\u7c7b\u578b\u52a0\u4ee5\u6bd4\u8f83\u3002 java.util \u5305\u4e2d\u63d0\u4f9b\u4e86\u8bb8\u591aJava\u7684\u96c6\u5408\u7c7b\u578b\uff0c\u5305\u62ec\u5217\u8868\u3001\u96c6\u5408\u3001\u6620\u5c04\u7b49\u3002\u4e0b\u9762\u5c06\u5217\u51fa\u5176\u4e2d\u4e00\u4e9b\u5e38\u7528\u7684\u591a\u9879\u96c6\u7c7b\u578b\uff0c\u5e76\u5c06\u5b83\u4eec\u4e0ePython\u4e2d\u7684\u591a\u9879\u96c6\u7c7b\u578b\u8fdb\u884c\u6bd4\u8f83\u3002 Java ArrayList vs Python List: Java ArrayList \u662f\u4e00\u4e2a\u53ef\u53d8\u5927\u5c0f\u7684\u52a8\u6001\u6570\u7ec4\u3002 Python List \u4e5f\u662f\u53ef\u53d8\u5927\u5c0f\u7684\u52a8\u6001\u6570\u7ec4\uff0c\u53ef\u4ee5\u5bb9\u7eb3\u4efb\u610f\u7c7b\u578b\u7684\u6570\u636e\u3002 Java HashSet vs Python Set: Java HashSet \u662f\u4e00\u4e2a\u4e0d\u5141\u8bb8\u91cd\u590d\u5143\u7d20\u7684\u96c6\u5408\u3002 Python Set \u4e5f\u4e0d\u5141\u8bb8\u91cd\u590d\u5143\u7d20\uff0c\u540c\u65f6\u8fd8\u6709\u4e00\u4e2a\u7279\u6b8a\u7c7b\u578b\u7684\u96c6\u5408\u53eb\u505a frozenset \uff0c\u5b83\u662f\u4e0d\u53ef\u53d8\u7684\u3002 Java LinkedHashSet vs Python OrderedDict: Java LinkedHashSet \u662f\u4e00\u4e2a\u4fdd\u6301\u5143\u7d20\u63d2\u5165\u987a\u5e8f\u7684\u96c6\u5408\uff0c\u4e0d\u5141\u8bb8\u91cd\u590d\u5143\u7d20\u3002 Python OrderedDict \u662f\u4e00\u4e2a\u6709\u5e8f\u5b57\u5178\uff0c\u4fdd\u6301\u5143\u7d20\u63d2\u5165\u987a\u5e8f\uff0c\u53ef\u4ee5\u7528\u4e8e\u521b\u5efa\u6709\u5e8f\u7684\u952e-\u503c\u5bf9\u96c6\u5408\u3002 Java TreeSet vs Python SortedSet: Java TreeSet \u662f\u4e00\u4e2a\u81ea\u7136\u6392\u5e8f\u6216\u8005\u901a\u8fc7\u63d0\u4f9b\u7684\u6bd4\u8f83\u5668\u8fdb\u884c\u6392\u5e8f\u7684\u96c6\u5408\uff0c\u4e0d\u5141\u8bb8\u91cd\u590d\u5143\u7d20\u3002 Python \u6ca1\u6709\u4e13\u95e8\u7684 SortedSet \u7c7b\uff0c\u4f46\u4f60\u53ef\u4ee5\u4f7f\u7528 sorted() \u51fd\u6570\u5bf9\u96c6\u5408\u8fdb\u884c\u6392\u5e8f\u3002 Java HashMap vs Python Dictionary: Java HashMap \u662f\u4e00\u4e2a\u65e0\u5e8f\u7684\u952e-\u503c\u5bf9\u6620\u5c04\uff0c\u4e0d\u5141\u8bb8\u91cd\u590d\u952e\u3002 Python Dictionary \u662f\u4e00\u4e2a\u65e0\u5e8f\u7684\u952e-\u503c\u5bf9\u6620\u5c04\uff0c\u952e\u662f\u552f\u4e00\u7684\u3002 Java TreeMap vs Python OrderedDict: Java TreeMap \u662f\u4e00\u4e2a\u57fa\u4e8e\u7ea2\u9ed1\u6811\u7684\u6709\u5e8f\u6620\u5c04\u3002 Python OrderedDict \u5728\u952e\u7684\u63d2\u5165\u987a\u5e8f\u4e0a\u4fdd\u6301\u6709\u5e8f\u3002 Java \u7684\u591a\u9879\u96c6\u7c7b\u578b\u548c Python \u7684\u591a\u9879\u96c6\u7c7b\u578b\u5728\u529f\u80fd\u4e0a\u975e\u5e38\u7c7b\u4f3c\uff0c\u90fd\u63d0\u4f9b\u4e86\u5404\u79cd\u4e0d\u540c\u7684\u96c6\u5408\u7c7b\u578b\u6765\u9002\u5e94\u4e0d\u540c\u7684\u9700\u6c42\u3002\u9700\u8981\u6839\u636e\u5177\u4f53\u7684\u4f7f\u7528\u60c5\u51b5\u6765\u9009\u62e9\u54ea\u79cd\u96c6\u5408\u7c7b\u578b\u66f4\u9002\u5408\u3002\u540c\u65f6\uff0cPython \u8fd8\u63d0\u4f9b\u4e86\u65b9\u4fbf\u7684\u5217\u8868\u63a8\u5bfc\u3001\u96c6\u5408\u63a8\u5bfc\u548c\u5b57\u5178\u63a8\u5bfc\u7b49\u7279\u6027\uff0c\u53ef\u4ee5\u66f4\u52a0\u4fbf\u6377\u5730\u521b\u5efa\u548c\u5904\u7406\u591a\u9879\u96c6\u3002","title":"2.7.\u7f16\u7a0b\u7ec3\u4e60"},{"location":"python/DataStructure/03_TimeComplexity/","text":"3.\u641c\u7d22\u3001\u6392\u5e8f\u4ee5\u53ca\u590d\u6742\u5ea6\u5206\u6790 \u00b6 \u7b97\u6cd5\u63cf\u8ff0\u4e86\u4e00\u4e2a\u968f\u7740\u95ee\u9898\u88ab\u89e3\u51b3\u800c\u505c\u6b62\u7684\u8ba1\u7b97\u8fc7\u7a0b\u3002 \u7b97\u6cd5\u662f\u8ba1\u7b97\u673a\u7a0b\u5e8f\u7684\u57fa\u672c\u7ec4\u6210\u90e8\u5206\u4e4b\u4e00\uff0c\u53e6\u4e00\u4e2a\u57fa\u672c\u7ec4\u6210\u90e8\u5206\u662f\u6570\u636e\u7ed3\u6784\u3002 \u5728\u7b97\u6cd5\u6267\u884c\u8fc7\u7a0b\u4e2d\u4f1a\u6d88\u8017\u4e24\u4e2a\u8d44\u6e90\uff1a\u5904\u7406\u5bf9\u8c61\u6240\u9700\u7684\u65f6\u95f4\u548c\u7a7a\u95f4\uff08\u4e5f\u5c31\u662f\u5185\u5b58\uff09\u3002\u5bf9\u4e8e\u7b97\u6cd5\u6765\u8bf4\uff0c\u603b\u4f1a\u8ffd\u6c42\u6d88\u8017\u66f4\u77ed\u7684\u65f6\u95f4\u548c\u5360\u7528\u66f4\u5c11\u7684\u7a7a\u95f4\u3002\u5728\u9009\u62e9\u7b97\u6cd5\u65f6\uff0c\u901a\u5e38\u5728\u7a7a\u95f4/\u65f6\u95f4\u4e4b\u95f4\u8fdb\u884c\u6743\u8861\u3002 \u7b97\u6cd5\u8d28\u91cf\u7684\u4e3b\u8981\u8bc4\u4f30\u6807\u51c6\uff1a \u6b63\u786e\u6027\uff0c\u5373\u7b97\u6cd5\u80fd\u591f\u771f\u6b63\u89e3\u51b3\u6240\u9488\u5bf9\u7684\u95ee\u9898\uff1b \u53ef\u8bfb\u6027\u548c\u6613\u4e8e\u7ef4\u62a4\u6027\uff1b \u8fd0\u884c\u65f6\u6027\u80fd\uff1b \u76ee\u6807\uff1a \u6839\u636e\u95ee\u9898\u7684\u89c4\u6a21\u786e\u5b9a\u7b97\u6cd5\u5de5\u4f5c\u91cf\u7684\u589e\u957f\u7387\uff1b \u4f7f\u7528\u5927O\u8868\u793a\u6cd5\u6765\u63cf\u8ff0\u7b97\u6cd5\u7684\u8fd0\u884c\u65f6\u548c\u5185\u5b58\u4f7f\u7528\u60c5\u51b5\uff1b \u8ba4\u8bc6\u5e38\u89c1\u7684\u5de5\u4f5c\u91cf\u589e\u957f\u7387\u6216\u590d\u6742\u5ea6\u7684\u7c7b\u522b\uff08\u5e38\u6570\u3001\u5bf9\u6570\u3001\u7ebf\u6027\u3001\u5e73\u65b9\u548c\u6307\u6570\uff09\uff1b \u5c06\u7b97\u6cd5\u8f6c\u6362\u4e3a\u590d\u6742\u5ea6\u4f4e\u4e00\u4e2a\u6570\u91cf\u7ea7\u7684\u66f4\u5feb\u7684\u7248\u672c\uff1b \u63cf\u8ff0\u987a\u5e8f\u641c\u7d22\u7b97\u6cd5\u548c\u4e8c\u5206\u641c\u7d22\u7b97\u6cd5\u7684\u5de5\u4f5c\u65b9\u5f0f\uff1b \u63cf\u8ff0\u9009\u62e9\u6392\u5e8f\u7b97\u6cd5\u548c\u5feb\u901f\u6392\u5e8f\u7b97\u6cd5\u7684\u5de5\u4f5c\u65b9\u5f0f\u3002 3.1.\u8861\u91cf\u7b97\u6cd5\u7684\u6548\u7387 \u00b6 \u8861\u91cf\u7b97\u6cd5\u65f6\u95f4\u6210\u672c\u7684\u4e24\u79cd\u65b9\u6cd5\uff1a \u7528\u8ba1\u7b97\u673a\u65f6\u949f\u5f97\u5230\u7b97\u6cd5\u5b9e\u9645\u7684\u8fd0\u884c\u65f6\u3002\u8fd9\u4e2a\u8fc7\u7a0b\u88ab\u79f0\u4e3a\u57fa\u51c6\u6d4b\u8bd5\uff08benchmarking\uff09\u6216\u6027\u80fd\u5206\u6790\uff08profiling\uff09\u3002\u9884\u6d4b\u7b97\u6cd5\u6267\u884c\u7684\u62bd\u8c61\u5de5\u4f5c\u91cf\u4f9d\u8d56\u4e8e\u7279\u5b9a\u7684\u786c\u4ef6\u6216\u8f6f\u4ef6\u5e73\u53f0\u3002 \u5728\u4e0d\u540c\u95ee\u9898\u89c4\u6a21\u4e0b\uff0c\u7edf\u8ba1\u9700\u8981\u6267\u884c\u7684\u6307\u4ee4\u6570\u3002\u9884\u6d4b\u7b97\u6cd5\u6267\u884c\u7684\u62bd\u8c61\u5de5\u4f5c\u91cf\u9002\u7528\u4e8e\u4e0d\u540c\u7684\u786c\u4ef6\u6216\u8f6f\u4ef6\u5e73\u53f0\u3002 3.1.1.\u8861\u91cf\u7b97\u6cd5\u7684\u8fd0\u884c\u65f6 \u00b6 import time problemSize = 10000000 print ( \" %12s%16s \" % ( \"Problem Size\" , \"Seconds\" )) for count in range ( 5 ): \"\"\" \u5728\u4e00\u4e2a\u5faa\u73af\u4e2d\uff0c\u5c06\u95ee\u9898\u89c4\u6a21\u7ffb\u500d5\u6b21\uff0c\u8bb0\u5f55\u7b97\u6cd5\u6bcf\u6b21\u8fd0\u884c\u65f6\u95f4\u3002 \"\"\" start = time . time () # \u7b97\u6cd5\u5f00\u59cb work = 1 for x in range ( problemSize ): work += 1 work -= 1 # \u7b97\u6cd5\u7ed3\u675f elapsed = time . time () - start print ( \" %12d%16.3f \" % ( problemSize , elapsed )) problemSize *= 2 # \u8fd0\u884c\u7ed3\u679c\uff1a # Problem Size Seconds # 10000000 0.689 # 20000000 1.367 # 40000000 2.644 # 80000000 5.296 # 160000000 10.622 \u4e0a\u8ff0\u6d4b\u8bd5\u7a0b\u5e8f\u4f7f\u7528\u4e86 time \u6a21\u5757\u91cc\u7684 time() \u51fd\u6570\u6765\u8bb0\u5f55\u8fd0\u884c\u65f6\uff0c\u5373 time.time() \u3002\u8fd9\u4e2a\u51fd\u6570\u4f1a\u8fd4\u56de\u8ba1\u7b97\u673a\u7684\u5f53\u524d\u65f6\u95f4\u548c1970\u5e741\u67081\u65e5\uff3b\u4e5f\u79f0\u4e3a\u7eaa\u5143\uff08epoch\uff09\uff3d\u76f8\u5dee\u7684\u79d2\u6570\u3002\u4e24\u6b21\u8c03\u7528 time.time() \u7684\u7ed3\u679c\u4e4b\u95f4\u7684\u5dee\u503c\u5c31\u4ee3\u8868\u4e86\u4e2d\u95f4\u7ecf\u5386\u4e86\u591a\u5c11\u79d2\u3002 \u4e0a\u8ff0\u6d4b\u8bd5\u7a0b\u5e8f\u5728\u6bcf\u6b21\u5faa\u73af\u7684\u65f6\u5019\u90fd\u4f1a\u6267\u884c\u4e24\u4e2a\u6269\u5c55\u7684\u8d4b\u503c\u8bed\u53e5\uff0c\u4e5f\u5c31\u662f\u6bcf\u6b21\u90fd\u6267\u884c\u7684\u5de5\u4f5c\u91cf\u662f\u56fa\u5b9a\u7684\uff0c\u4f1a\u6d88\u8017\u4e86\u4e00\u5b9a\u7684\u65f6\u95f4\u3002 \u4fee\u6539\u4e0a\u8ff0\u7b97\u6cd5\uff0c\u6211\u4eec\u53ef\u4ee5\u4ece\u4e0b\u9762\u7684\u8fd0\u884c\u7ed3\u679c\u770b\u51fa\uff0c\u5f53 problemSize \u4e3a 1,000 \u65f6\uff0c\u7b97\u6cd5\u7684\u6d88\u8017\u65f6\u95f4\u5c31\u5df2\u7ecf\u8d85\u8fc7\u4e86\u539f\u5148\u7b97\u6cd5\uff0c\u6211\u4eec\u53ef\u4ee5\u63a8\u65ad\u51fa\u7ee7\u7eed\u6d4b\u8bd5 problemSize \u4e3a 10,000,000 \u7684\u8017\u65f6\u5df2\u7ecf\u53d8\u5f97\u4e0d\u5b9e\u9645\u4e86\u3002 import time problemSize = 1000 print ( \" %12s%16s \" % ( \"Problem Size\" , \"Seconds\" )) for count in range ( 5 ): start = time . time () # \u7b97\u6cd5\u5f00\u59cb work = 1 for x in range ( problemSize ): for y in range ( problemSize ): work += 1 work -= 1 # \u7b97\u6cd5\u7ed3\u675f elapsed = time . time () - start print ( \" %12d%16.3f \" % ( problemSize , elapsed )) problemSize *= 2 # \u8fd0\u884c\u7ed3\u679c\uff1a # Problem Size Seconds # 1000 0.093 # 2000 0.350 # 4000 1.280 # 8000 5.004 # 16000 20.020 \u4e0d\u540c\u7684\u786c\u4ef6\u5e73\u53f0\u4f1a\u6709\u4e0d\u540c\u7684\u5904\u7406\u901f\u5ea6\uff0c\u7b97\u6cd5\u7684\u8fd0\u884c\u65f6\u4f1a\u56e0\u673a\u5668\u7684\u4e0d\u540c\u800c\u5b58\u5728\u5dee\u5f02\u3002 \u7a0b\u5e8f\u7684\u8fd0\u884c\u65f6\u4e5f\u4f1a\u968f\u7740\u5b83\u548c\u786c\u4ef6\u4e4b\u95f4\u7684\u64cd\u4f5c\u7cfb\u7edf\u7c7b\u578b\u7684\u4e0d\u540c\u800c\u53d8\u5316\u3002 \u4e0d\u540c\u7684\u7f16\u7a0b\u8bed\u8a00\u548c\u7f16\u8bd1\u5668\u751f\u6210\u7684\u4ee3\u7801\u7684\u6027\u80fd\u4e5f\u4f1a\u6709\u6240\u4e0d\u540c\uff0c\u56e0\u6b64\uff0c\u5728\u67d0\u4e00\u4e2a\u786c\u4ef6\u6216\u8f6f\u4ef6\u5e73\u53f0\u4e0a\u6d4b\u5f97\u7684\u8fd0\u884c\u65f6\u7ed3\u679c\u901a\u5e38\u4e0d\u80fd\u7528\u6765\u9884\u6d4b\u5728\u5176\u4ed6\u5e73\u53f0\u4e0a\u7684\u6027\u80fd\u3002 \u7528\u975e\u5e38\u5927\u7684\u6570\u636e\u96c6\u786e\u5b9a\u7b97\u6cd5\u7684\u8fd0\u884c\u65f6\u662f\u975e\u5e38\u4e0d\u5207\u5b9e\u9645\u7684\u3002\u5bf9\u4e8e\u67d0\u4e9b\u7b97\u6cd5\u6765\u8bf4\uff0c\u4e0d\u8bba\u662f\u7f16\u8bd1\u7684\u4ee3\u7801\u8fd8\u662f\u786c\u4ef6\u5904\u7406\u5668\u7684\u901f\u5ea6\u6709\u591a\u5feb\uff0c\u90fd\u6ca1\u6709\u4efb\u4f55\u7684\u533a\u522b\uff0c\u56e0\u4e3a\u5b83\u4eec\u5728\u4efb\u4f55\u8ba1\u7b97\u673a\u4e0a\u90fd\u6ca1\u529e\u6cd5\u5904\u7406\u975e\u5e38\u5927\u7684\u6570\u636e\u96c6\u3002 3.1.2.\u7edf\u8ba1\u6307\u4ee4\u6570 \u00b6 \u7edf\u8ba1\u6307\u4ee4\u6570\u65f6\uff0c\u7edf\u8ba1\u7684\u662f\u7f16\u5199\u7b97\u6cd5\u7684\u9ad8\u7ea7\u8bed\u8a00\u91cc\u7684\u6307\u4ee4\u6570\uff0c\u800c\u4e0d\u662f\u53ef\u6267\u884c\u673a\u5668\u8bed\u8a00\u7a0b\u5e8f\u91cc\u7684\u6307\u4ee4\u6570\u3002 \u901a\u8fc7\u8fd9\u79cd\u65b9\u5f0f\u5bf9\u7b97\u6cd5\u8fdb\u884c\u5206\u6790\u65f6\uff0c\u628a\u5b83\u5206\u6210\u4e24\u4e2a\u90e8\u5206\uff1a \u65e0\u8bba\u95ee\u9898\u7684\u89c4\u6a21\u5982\u4f55\u53d8\u5316\uff0c\u6307\u4ee4\u6267\u884c\u7684\u6b21\u6570\u603b\u662f\u76f8\u540c\u7684\uff1b\u6211\u4eec\u5ffd\u7565\u8fd9\u79cd\u7c7b\u578b\uff0c\u56e0\u4e3a\u5206\u6790\u6548\u7387\u65f6\u5b83\u4eec\u7684\u4f5c\u7528\u5e76\u4e0d\u660e\u663e\u3002 \u6267\u884c\u7684\u6307\u4ee4\u6570\u968f\u7740\u95ee\u9898\u89c4\u6a21\u7684\u53d8\u5316\u800c\u53d8\u5316\uff1b\u6211\u4eec\u91cd\u70b9\u5173\u6ce8\u8fd9\u79cd\u7c7b\u578b\uff0c\u8fd9\u79cd\u7c7b\u578b\u7684\u6307\u4ee4\u901a\u5e38\u53ef\u4ee5\u5728\u5faa\u73af\u6216\u8005\u9012\u5f52\u51fd\u6570\u91cc\u627e\u5230\u3002 \u6211\u4eec\u6765\u6539\u5199\u4e0a\u9762\u7684\u4f8b\u5b50\uff0c\u4ece\u7edf\u8ba1\u8fd0\u884c\u65f6\u95f4\u53d8\u4e3a\u7edf\u8ba1\u8fed\u4ee3\u6b21\u6570\u3002 \u4e0b\u9762\u7684\u7b97\u6cd5\u4e2d\uff0c\u8fed\u4ee3\u6b21\u6570\u548c\u95ee\u9898\u89c4\u6a21\u662f\u76f8\u7b49\u7684\u3002 import time problemSize = 10000000 print ( \" %12s%16s \" % ( \"Problem Size\" , \"Seconds\" )) for count in range ( 5 ): number = 0 # \u7b97\u6cd5\u5f00\u59cb work = 1 for x in range ( problemSize ): number += 1 work += 1 work -= 1 # \u7b97\u6cd5\u7ed3\u675f print ( \" %12d%16.3f \" % ( problemSize , Iterations )) problemSize *= 2 # \u8fd0\u884c\u7ed3\u679c\uff1a # Problem Size Iterations # 10000000 10000000.000 # 20000000 20000000.000 # 40000000 40000000.000 # 80000000 80000000.000 # 160000000 160000000.000 \u4e0b\u9762\u7684\u7b97\u6cd5\u4e2d\uff0c\u8fed\u4ee3\u6b21\u6570\u548c\u95ee\u9898\u89c4\u6a21\u7684\u5e73\u65b9\u3002\u8fd9\u5c31\u89e3\u91ca\u4e86\u4e3a\u4ec0\u4e48\u8fd9\u4e2a\u7b97\u6cd5\u7684\u8017\u65f6\u975e\u5e38\u5927\u3002 import time problemSize = 1000 print ( \" %12s%16s \" % ( \"Problem Size\" , \"Seconds\" )) for count in range ( 5 ): number = 0 # \u7b97\u6cd5\u5f00\u59cb work = 1 for x in range ( problemSize ): for y in range ( problemSize ): number += 1 work += 1 work -= 1 # \u7b97\u6cd5\u7ed3\u675f print ( \" %12d%16.3f \" % ( problemSize , number )) problemSize *= 2 # \u8fd0\u884c\u7ed3\u679c\uff1a # Problem Size Iterations # 1000 1000000.000 # 2000 4000000.000 # 4000 16000000.000 # 8000 64000000.000 # 16000 256000000.000 \u5728\u4e0b\u9762\u7684\u6590\u6ce2\u90a3\u5951\u9012\u5f52\u7684\u4f8b\u5b50\u4e2d\uff0c\u51fd\u6570 fib(problemSize, counter) \u4e2d counter \u53c2\u6570\u662f\u4e00\u4e2a\u5bf9\u8c61\uff0c\u6bcf\u6b21\u9012\u5f52\u8c03\u7528\u7684\u65f6\u5019\uff0c\u90fd\u4f1a\u521b\u5efa\u4e00\u4e2a\u65b0\u7684\u8ba1\u6570\u5668\u5bf9\u8c61\u3002 \u4ece\u4e0b\u9762\u7684\u8fd0\u884c\u7ed3\u679c\u53ef\u4ee5\u770b\u51fa\uff0c\u968f\u7740\u95ee\u9898\u89c4\u6a21\uff08Problem Size\uff09\u7684\u7ffb\u500d\uff0c\u6307\u4ee4\u6570\uff08\u9012\u5f52\u8c03\u7528\u7684\u6b21\u6570\uff09\u5728\u4e00\u5f00\u59cb\u7684\u65f6\u5019\u7f13\u6162\u589e\u957f\uff0c\u968f\u540e\u8fc5\u901f\u52a0\u5feb\u3002 \u7edf\u8ba1\u6307\u4ee4\u6570\u662f\u6b63\u786e\u7684\u601d\u8def\uff0c\u4f46\u4ee5\u8fd9\u79cd\u65b9\u5f0f\u8fdb\u884c\u8ddf\u8e2a\u8ba1\u6570\u7684\u95ee\u9898\u5728\u4e8e\uff0c\u5bf9\u4e8e\u67d0\u4e9b\u7b97\u6cd5\u6765\u8bf4\uff0c\u5982\u679c\u95ee\u9898\u89c4\u6a21\u975e\u5e38\u5927\uff0c\u8ba1\u7b97\u673a\u65e0\u6cd5\u4ee5\u8db3\u591f\u5feb\u7684\u901f\u5ea6\u8fd0\u884c\uff0c\u5e76\u5728\u4e00\u5b9a\u65f6\u95f4\u5185\u5f97\u5230\u7ed3\u679c\u3002 class Counter ( object ): \"\"\"Models a counter.\"\"\" # Class variable instances = 0 #Constructor def __init__ ( self ): \"\"\"Sets up the counter.\"\"\" Counter . instances += 1 self . reset () # Mutator methods def reset ( self ): \"\"\"Sets the counter to 0.\"\"\" self . _value = 0 def increment ( self , amount = 1 ): \"\"\"Adds amount to the counter.\"\"\" self . _value += amount def decrement ( self , amount = 1 ): \"\"\"Subtracts amount from the counter.\"\"\" self . _value -= amount # Accessor methods def getValue ( self ): \"\"\"Returns the counter's value.\"\"\" return self . _value def __str__ ( self ): \"\"\"Returns the string representation of the counter.\"\"\" return str ( self . _value ) def __eq__ ( self , other ): \"\"\"Returns True if self equals other or False otherwise.\"\"\" if self is other : return True if type ( self ) != type ( other ): return False return self . _value == other . _value def fib ( n , counter ): \"\"\"\u7edf\u8ba1\u6590\u6ce2\u90a3\u5951\u51fd\u6570\u88ab\u5916\u90e8\u8c03\u7528\u7684\u6b21\u6570\"\"\" counter . increment () if n < 3 : return 1 else : return fib ( n - 1 , counter ) + fib ( n - 2 , counter ) problemSize = 2 print ( \" %12s%15s \" % ( \"Problem Size\" , \"Calls\" )) for count in range ( 5 ): \"\"\"\u968f\u7740\u95ee\u9898\u89c4\u6a21\u589e\u52a0\uff0c\u8f93\u51fa\u6590\u6ce2\u90a3\u5951\u9012\u5f52\u51fd\u6570\u88ab\u5916\u90e8\u8c03\u7528\u7684\u6b21\u6570\"\"\" counter = Counter () # \u7b97\u6cd5\u5f00\u59cb fib ( problemSize , counter ) # \u7b97\u6cd5\u7ed3\u675f print ( \" %12d%15s \" % ( problemSize , counter )) problemSize *= 2 # \u8fd0\u884c\u7ed3\u679c\uff1a # Problem Size Calls # 2 1 # 4 5 # 8 41 # 16 1973 # 32 4356617 3.1.3.\u8861\u91cf\u7b97\u6cd5\u4f7f\u7528\u7684\u5185\u5b58 \u00b6 \u5bf9\u4e8e\u7b97\u6cd5\u6240\u7528\u8d44\u6e90\u7684\u5206\u6790\u4e5f\u9700\u8981\u5305\u542b\u5b83\u6240\u9700\u7684\u5185\u5b58\u91cf\u7684\u5206\u6790\u3002\u548c\u524d\u9762\u7c7b\u4f3c\u7684\u95ee\u9898\u4e5f\u4f1a\u5b58\u5728\uff0c\u4e00\u4e9b\u7b97\u6cd5\u4f1a\u968f\u7740\u95ee\u9898\u89c4\u6a21\u53d8\u5927\u800c\u9700\u8981\u989d\u5916\u66f4\u591a\u7684\u5185\u5b58\u3002 3.1.4.\u7ec3\u4e60\u9898 \u00b6 \u7f16\u5199\u4e00\u4e2a\u6d4b\u8bd5\u7a0b\u5e8f\uff0c\u8fd9\u4e2a\u7a0b\u5e8f\u7edf\u8ba1\u5e76\u663e\u793a\u51fa\u4e0b\u9762\u8fd9\u4e2a\u5faa\u73af\u7684\u8fed\u4ee3\u6b21\u6570\u3002 while problemSize > 0 : problemSize = problemSize // 2 \u89e3\u7b54\uff1a def count_iterations ( problemSize ): iterations = 0 # \u521d\u59cb\u5316\u8ba1\u6570\u5668 while problemSize > 0 : problemSize = problemSize // 2 iterations += 1 # \u6bcf\u6b21\u5faa\u73af\u8fed\u4ee3\uff0c\u8ba1\u6570\u5668\u52a0\u4e00 return iterations problemSize = 1000 # \u8bbe\u7f6e\u95ee\u9898\u89c4\u6a21 iterations = count_iterations ( problemSize ) print ( f \"Problem Size: { problemSize } \" ) print ( f \"Iterations: { iterations } \" ) # \u8fd0\u884c\u7ed3\u679c\uff1a # Problem Size: 1000 # Iterations: 10 \u5728\u95ee\u9898\u89c4\u6a21\u5206\u522b\u4e3a1000\u30012000\u30014000\u300110000\u548c100000\u65f6\uff0c\u8fd0\u884c\u5728\u7ec3\u4e601\u91cc\u6240\u521b\u5efa\u7684\u7a0b\u5e8f\u3002\u5f53\u95ee\u9898\u89c4\u6a21\u7ffb\u500d\u6216\u662f\u4e58\u4ee510\u65f6\uff0c\u8fed\u4ee3\u6b21\u6570\u4f1a\u5982\u4f55\u53d8\u5316\uff1f \u89e3\u7b54\uff1a\u5206\u522b\u4ee5\u4e0d\u540c\u7684\u95ee\u9898\u89c4\u6a21\u8fd0\u884c\u4e0a\u9762\u7684\u4ee3\u7801\uff0c\u7ed3\u679c\u5982\u4e0b\uff1a Problem Size : 1000 Iterations : 10 Problem Size : 4000 Iterations : 12 Problem Size : 8000 Iterations : 13 Problem Size : 10000 Iterations : 14 Problem Size : 100000 Iterations : 17 \u4e24\u6b21\u8c03\u7528\u51fd\u6570 time.time() \u7684\u7ed3\u679c\u4e4b\u5dee\u5c31\u662f\u8fd0\u884c\u65f6\u3002\u7531\u4e8e\u64cd\u4f5c\u7cfb\u7edf\u4e5f\u53ef\u80fd\u4f1a\u5728\u8fd9\u6bb5\u65f6\u95f4\u5185\u4f7f\u7528CPU\uff0c\u56e0\u6b64\u8fd9\u4e2a\u8fd0\u884c\u65f6\u53ef\u80fd\u5e76\u4e0d\u80fd\u53cd\u6620\u51faPython\u4ee3\u7801\u4f7f\u7528CPU\u7684\u5b9e\u9645\u65f6\u95f4\u3002\u6d4f\u89c8Python\u6587\u6863\uff0c\u627e\u51fa\u53e6\u4e00\u79cd\u53ef\u4ee5\u5b8c\u6574\u8bb0\u5f55\u5904\u7406\u65f6\u95f4\u7684\u65b9\u6cd5\uff0c\u5e76\u63cf\u8ff0\u5982\u4f55\u5b9e\u73b0\u5b83\u3002 \u89e3\u7b54\uff1a \u5728Python\u4e2d\uff0c time \u6a21\u5757\u63d0\u4f9b\u4e86\u66f4\u7cbe\u786e\u7684\u8ba1\u65f6\u529f\u80fd\uff0c\u5176\u4e2d\u7684 time.perf_counter() \u51fd\u6570\u53ef\u4ee5\u7528\u6765\u6d4b\u91cf\u65f6\u95f4\u7684\u7cbe\u786e\u95f4\u9694\u3002\u4e0e time.time() \u4e0d\u540c\uff0c time. perf_counter() \u4f1a\u5728\u5927\u591a\u6570\u5e73\u53f0\u4e0a\u63d0\u4f9b\u4e00\u4e2a\u66f4\u9ad8\u5206\u8fa8\u7387\u7684\u8ba1\u65f6\u5668\uff0c\u53ef\u4ee5\u7528\u6765\u6d4b\u91cf\u4ee3\u7801\u5757\u7684\u6267\u884c\u65f6\u95f4\u3002 time.perf_counter() \u8fd4\u56de\u4e00\u4e2a\u6d6e\u70b9\u6570\uff0c\u8868\u793a\u4ece\u67d0\u4e2a\u7279\u5b9a\u65f6\u95f4\u70b9\u5230\u73b0\u5728\u7ecf\u8fc7\u7684\u79d2\u6570\u3002\u4ee5\u4e0b\u662f\u5982\u4f55\u4f7f\u7528 time.perf_counter() \u6765\u8ba1\u7b97\u4ee3\u7801\u5757\u7684\u6267\u884c\u65f6\u95f4\uff1a import time # \u83b7\u53d6\u8d77\u59cb\u65f6\u95f4\uff08\u5305\u62ecCPU\u65f6\u95f4\u548c\u7cfb\u7edf\u65f6\u95f4\uff09 start_cpu_time = time . process_time () start_real_time = time . perf_counter () start_system_time = time . time () # \u6267\u884c\u4ee3\u7801 for i in range ( 100000000 ): _ = i * i # \u83b7\u53d6\u7ed3\u675f\u65f6\u95f4\uff08\u5305\u62ecCPU\u65f6\u95f4\u548c\u7cfb\u7edf\u65f6\u95f4\uff09 end_cpu_time = time . process_time () end_real_time = time . perf_counter () end_system_time = time . time () # \u8ba1\u7b97CPU\u65f6\u95f4\u5dee cpu_execution_time = end_cpu_time - start_cpu_time real_execution_time = end_real_time - start_real_time system_execution_time = end_system_time - start_system_time print ( f \"CPU Execution Time: { cpu_execution_time : .6f } seconds\" ) print ( f \"Real Execution Time: { real_execution_time : .6f } seconds\" ) print ( f \"System Execution Time: { system_execution_time : .6f } seconds\" ) # \u8fd0\u884c\u7ed3\u679c\uff1a # CPU Execution Time: 7.157305 seconds # Real Execution Time: 7.156638 seconds # System Execution Time: 7.156638 seconds \u5728\u4e0a\u9762\u4ee3\u7801\u4e2d\uff0c start_system_time \u548c end_system_time \u5206\u522b\u8bb0\u5f55\u4e86\u4ee3\u7801\u5757\u5f00\u59cb\u548c\u7ed3\u675f\u65f6\u7684\u7cfb\u7edf\u65f6\u95f4\u3002\u7136\u540e\uff0c\u53ef\u4ee5\u901a\u8fc7\u8ba1\u7b97 end_system_time - start_system_time \u6765\u83b7\u53d6\u7cfb\u7edf\u65f6\u95f4\u7684\u6d88\u8017\u3002 \u7cfb\u7edf\u65f6\u95f4\u7684\u8ba1\u7b97\u53ef\u80fd\u53d7\u5230\u7cfb\u7edf\u7684\u5f71\u54cd\uff0c\u53ef\u80fd\u4f1a\u56e0\u4e3a\u7cfb\u7edf\u65f6\u95f4\u7684\u53d8\u5316\u800c\u4ea7\u751f\u4e0d\u51c6\u786e\u7684\u7ed3\u679c\u3002\u5728\u8fdb\u884c\u6027\u80fd\u6d4b\u8bd5\u65f6\uff0c\u5c3d\u91cf\u4ee5CPU\u65f6\u95f4\u548c\u5b9e\u9645\u7ecf\u8fc7\u65f6\u95f4\u4e3a\u4e3b\u8981\u53c2\u8003\u6307\u6807\u3002 \u8865\u5145\uff1a CPU \u65f6\u95f4\u3001\u5b9e\u9645\u7ecf\u8fc7\u65f6\u95f4\u548c\u7cfb\u7edf\u65f6\u95f4\u4ee3\u8868\u4e86\u4e0d\u540c\u7684\u65f6\u95f4\u6307\u6807\uff0c\u5b83\u4eec\u4e4b\u95f4\u6709\u4ee5\u4e0b\u533a\u522b\uff1a CPU \u65f6\u95f4\uff1a - CPU \u65f6\u95f4\u662f\u7a0b\u5e8f\u5728 CPU \u4e0a\u6267\u884c\u7684\u65f6\u95f4\uff0c\u5305\u62ec\u4e86\u5728\u7528\u6237\u6001\uff08\u6267\u884c\u5e94\u7528\u7a0b\u5e8f\u4ee3\u7801\uff09\u548c\u5185\u6838\u6001\uff08\u6267\u884c\u64cd\u4f5c\u7cfb\u7edf\u4ee3\u7801\uff09\u7684\u65f6\u95f4\u3002\u56e0\u6b64\uff0c\u5b83\u8003\u8651\u4e86\u5e94\u7528\u7a0b\u5e8f\u548c\u64cd\u4f5c\u7cfb\u7edf\u7684\u6267\u884c\u65f6\u95f4\u3002 - CPU \u65f6\u95f4\u901a\u5e38\u7528\u4e8e\u6d4b\u91cf\u7a0b\u5e8f\u7684\u8ba1\u7b97\u5bc6\u96c6\u578b\u5de5\u4f5c\u91cf\uff0c\u5373\u5927\u91cf\u8ba1\u7b97\u64cd\u4f5c\uff0c\u6bd4\u5982\u5faa\u73af\u548c\u6570\u5b66\u8ba1\u7b97\u3002 - \u901a\u8fc7 time.process_time() \u51fd\u6570\u53ef\u4ee5\u83b7\u53d6\u5f53\u524d\u8fdb\u7a0b\u7684 CPU \u65f6\u95f4\u3002 \u5b9e\u9645\u7ecf\u8fc7\u65f6\u95f4\uff1a - \u5b9e\u9645\u7ecf\u8fc7\u65f6\u95f4\u662f\u4ece\u67d0\u4e2a\u65f6\u95f4\u70b9\u5230\u73b0\u5728\u7684\u5b9e\u9645\u7ecf\u8fc7\u7684\u65f6\u95f4\uff0c\u8003\u8651\u4e86\u6240\u6709\u56e0\u7d20\uff0c\u5305\u62ec\u4e86 CPU \u65f6\u95f4\u3001\u7b49\u5f85\u65f6\u95f4\u3001\u7cfb\u7edf\u8c03\u5ea6\u7b49\u3002 - \u5b9e\u9645\u7ecf\u8fc7\u65f6\u95f4\u7528\u4e8e\u6d4b\u91cf\u4ee3\u7801\u7684\u603b\u6267\u884c\u65f6\u95f4\uff0c\u5305\u62ec\u4e86\u8ba1\u7b97\u548c\u7b49\u5f85\u7684\u65f6\u95f4\u3002 - \u901a\u8fc7 time.perf_counter() \u51fd\u6570\u53ef\u4ee5\u83b7\u53d6\u5f53\u524d\u65f6\u95f4\u3002 \u7cfb\u7edf\u65f6\u95f4\uff1a - \u7cfb\u7edf\u65f6\u95f4\u662f\u64cd\u4f5c\u7cfb\u7edf\u5185\u90e8\u7ef4\u62a4\u7684\u4e00\u4e2a\u65f6\u95f4\u503c\uff0c\u5b83\u4ee3\u8868\u4e86\u4ece\u67d0\u4e2a\u56fa\u5b9a\u65f6\u95f4\u70b9\u5f00\u59cb\u7684\u79d2\u6570\u3002 - \u7cfb\u7edf\u65f6\u95f4\u901a\u5e38\u7528\u4e8e\u8bb0\u5f55\u4e8b\u4ef6\u548c\u8ba1\u7b97\u65f6\u95f4\u95f4\u9694\uff0c\u4e0d\u53d7\u7a0b\u5e8f\u7684\u6267\u884c\u5f71\u54cd\u3002 - \u901a\u8fc7 time.time() \u51fd\u6570\u53ef\u4ee5\u83b7\u53d6\u5f53\u524d\u7684\u7cfb\u7edf\u65f6\u95f4\u3002 \u603b\u7ed3\uff1aCPU \u65f6\u95f4\u5173\u6ce8\u7684\u662f\u7a0b\u5e8f\u5728 CPU \u4e0a\u7684\u6267\u884c\u65f6\u95f4\uff0c\u5b9e\u9645\u7ecf\u8fc7\u65f6\u95f4\u5173\u6ce8\u7684\u662f\u4ece\u4ee3\u7801\u5f00\u59cb\u5230\u7ed3\u675f\u6240\u7ecf\u8fc7\u7684\u771f\u5b9e\u65f6\u95f4\uff0c\u7cfb\u7edf\u65f6\u95f4\u662f\u7cfb\u7edf\u7ef4\u62a4\u7684\u5168\u5c40\u65f6\u95f4\u3002\u5728\u4e0d\u540c\u7684\u573a\u666f\u4e2d\uff0c\u4f60\u53ef\u4ee5\u6839\u636e\u9700\u8981\u9009\u62e9\u5408\u9002\u7684\u65f6\u95f4\u6307\u6807\u6765\u8fdb\u884c\u6027\u80fd\u6d4b\u91cf\u548c\u5206\u6790\u3002 3.2.\u590d\u6742\u5ea6\u5206\u6790 \u00b6 \u590d\u6742\u5ea6\u5206\u6790\uff08complexity analysis\uff09\u65b9\u6cd5\uff0c\u4e00\u79cd\u8bc4\u4f30\u7b97\u6cd5\u6548\u7387\u7684\u65b9\u6cd5\uff0c\u8fd9\u4e2a\u65b9\u6cd5\u53ef\u4ee5\u4e0d\u7528\u5173\u5fc3\u4e0e\u5e73\u53f0\u76f8\u5173\u7684\u65f6\u95f4\uff0c\u4e5f\u4e0d\u9700\u8981\u4f7f\u7528\u7edf\u8ba1\u6307\u4ee4\u6570\u91cf\u8fd9\u79cd\u65b9\u6cd5\u6765\u5bf9\u7b97\u6cd5\u8fdb\u884c\u8bc4\u4f30\u3002 3.2.1.\u590d\u6742\u5ea6\u7684\u9636 \u00b6 \u5728 3.1.2.\u7edf\u8ba1\u6307\u4ee4\u6570 \u4e2d\u5173\u4e8e\u8fed\u4ee3\u6b21\u6570\u548c\u95ee\u9898\u89c4\u6a21\u7684\u4e24\u4e2a\u7b97\u6cd5\uff0c\u5b83\u4eec\u590d\u6742\u5ea6\u7684\u9636\uff08order of complexity\uff09\u4e0a\u662f\u4e0d\u4e00\u6837\u7684\u3002 \u7b2c\u4e00\u4e2a\u7b97\u6cd5\u4e2d\uff0c\u8fed\u4ee3\u6b21\u6570\u548c\u95ee\u9898\u89c4\u6a21\u4e4b\u95f4\u662f\u7ebf\u6027\u5173\u7cfb\uff0c\u79f0\u5176\u590d\u6742\u5ea6\u4e3a\u7ebf\u6027\uff08linear\uff09\u9636\uff1b \u7b2c\u4e8c\u4e2a\u7b97\u6cd5\u4e2d\uff0c\u8fed\u4ee3\u6b21\u6570\u548c\u95ee\u9898\u89c4\u6a21\u4e4b\u95f4\u662f\u5e73\u65b9\u5173\u7cfb\uff0c\u79f0\u5176\u590d\u6742\u5ea6\u4e3a\u5e73\u65b9\uff08quadratic\uff09\u9636\uff1b \u5982\u679c\u7b97\u6cd5\u9700\u8981\u76f8\u540c\u6570\u91cf\u7684\u8fd0\u7b97\uff0c\u90a3\u4e48\u5b83\u7684\u6027\u80fd\u5c31\u662f\u5e38\u6570\uff08constant\uff09\u9636\u3002\u5217\u8868\u7d22\u5f15\u5c31\u662f\u4e00\u4e2a\u5e38\u6570\u65f6\u95f4\u7b97\u6cd5\u7684\u4f8b\u5b50\u3002 \u6bd4\u7ebf\u6027\u6027\u80fd\u597d\uff0c\u4f46\u6bd4\u5e38\u6570\u6027\u80fd\u5dee\u7684\u53e6\u4e00\u4e2a\u590d\u6742\u5ea6\u7684\u9636\u88ab\u79f0\u4e3a\u5bf9\u6570\uff08logarithmic\uff09\u9636\u3002\u5bf9\u6570\u7b97\u6cd5\u7684\u5de5\u4f5c\u91cf\u4e0e\u95ee\u9898\u89c4\u6a21\u7684\u4ee52\u4e3a\u5e95\u7684\u5bf9\u6570\u6210\u6b63\u6bd4\u3002\u5f53\u95ee\u9898\u89c4\u6a21\u6269\u5927\u4e00\u500d\u65f6\uff0c\u5de5\u4f5c\u91cf\u53ea\u4f1a\u52a01\u3002 \u591a\u9879\u5f0f\u65f6\u95f4\u7b97\u6cd5\uff08polynomial time algorithm\uff09\u7684\u5de5\u4f5c\u91cf\u4f1a\u4ee5 n^k \u7684\u901f\u7387\u589e\u957f\uff0c\u5176\u4e2d k \u662f\u5927\u4e8e 1 \u7684\u5e38\u6570\uff0c\u6bd4\u5982 n^2 \u3001 n^3 \u4ee5\u53ca n^10 \u3002\u4ece\u67d0\u79cd\u610f\u4e49\u4e0a\u8bb2\uff0c n^3 \u7684\u6027\u80fd\u8981\u6bd4 n^2 \u5dee\uff0c\u4f46\u90fd\u5c5e\u4e8e\u591a\u9879\u5f0f\uff08polynomial\uff09\u9636\u3002 \u6bd4\u591a\u9879\u5f0f\u8fd8\u8981\u5dee\u7684\u590d\u6742\u5ea6\u7684\u9636\u88ab\u79f0\u4e3a\u6307\u6570\uff08exponential\uff09\u9636\uff0c\u6bd4\u5982 2^n \u3002\u5bf9\u4e8e\u5927\u7684\u95ee\u9898\u89c4\u6a21\u6765\u8bf4\uff0c\u6307\u6570\u7b97\u6cd5\u662f\u4e0d\u53ef\u884c\u7684\u3002 \u4e0d\u540c\u590d\u6742\u5ea6\u9636\u7684\u7b97\u6cd5\u7684\u5de5\u4f5c\u91cf\u6bd4\u8f83\uff08\u4ece\u5c0f\u5230\u5927\uff09\uff1a\u5bf9\u6570\u9636 < \u7ebf\u6027\u9636 < \u5e73\u65b9\u9636 < \u6307\u6570\u9636\u3002\u968f\u7740\u95ee\u9898\u89c4\u6a21\u7684\u589e\u5927\uff0c\u5177\u6709\u8f83\u9ad8\u590d\u6742\u5ea6\u7684\u9636\u7684\u7b97\u6cd5\u7684\u6027\u80fd\u4f1a\u66f4\u5feb\u5730\u53d8\u5dee\u3002 3.2.2.\u5927O\u8868\u793a\u6cd5 \u00b6 \u5f88\u591a\u60c5\u51b5\u4e0b\uff0c\u7b97\u6cd5\u4e2d\u7684\u5de5\u4f5c\u91cf\u901a\u5e38\u662f\u591a\u9879\u5f0f\u91cc\u591a\u9879\u7684\u603b\u548c\uff0c\u800c\u5f53\u5de5\u4f5c\u91cf\u8868\u793a\u4e3a\u591a\u9879\u5f0f\u65f6\uff0c\u5176\u4e2d\u4e00\u9879\u662f\u4e3b\u5bfc\u9879\uff08dominant\uff09\u3002\u968f\u7740 n \u8d8a\u6765\u8d8a\u5927\uff0c\u4e3b\u5bfc\u9879\u5c06\u53d8\u5f97\u975e\u5e38\u5927\uff0c\u4ee5\u81f3\u4e8e\u53ef\u4ee5\u5ffd\u7565\u5176\u4ed6\u9879\u6240\u4ee3\u8868\u7684\u5de5\u4f5c\u91cf\u3002\u56e0\u6b64\uff0c\u5bf9\u4e8e\u591a\u9879\u5f0f n^2+n \uff0c\u53ea\u9700\u8981\u7740\u91cd\u8003\u8651\u5e73\u65b9\u9879 n^2 \uff0c\u4e5f\u5c31\u662f\u5728\u8003\u8651\u7684\u65f6\u5019\u53ef\u4ee5\u5ffd\u7565\u7ebf\u6027\u9879 n \u3002\u968f\u7740 n^2 \u53d8\u5f97\u975e\u5e38\u5927\uff0c\u591a\u9879\u5f0f\u7684\u503c\u6e10\u8fd1\u5730\u63a5\u8fd1\u6216\u8fd1\u4f3c\u4e8e\u5b83\u7684\u6700\u5927\u9879\u503c\uff0c\u8fd9\u79cd\u5f62\u5f0f\u7684\u5206\u6790\u6709\u65f6\u88ab\u79f0\u4e3a\u6e10\u8fd1\u5206\u6790\uff08asymptotic analysis\uff09\u3002 \u8ba1\u7b97\u4e2d\u7528\u6765\u8868\u793a\u7b97\u6cd5\u7684\u6548\u7387\u6216\u8ba1\u7b97\u590d\u6742\u5ea6\u7684\u4e00\u79cd\u65b9\u6cd5\u88ab\u79f0\u4e3a\u5927O\u8868\u793a\u6cd5\uff08big-O notation\uff09\u3002\u201cO\u201d\u4ee3\u8868\u201c\u5728\u2026\u2026\u9636\u201d\uff0c\u6307\u7684\u662f\u7b97\u6cd5\u5de5\u4f5c\u7684\u590d\u6742\u5ea6\u7684\u9636\u3002\u4f8b\u5982\uff1a \u5e38\u6570\u65f6\u95f4\uff1aO(1) \u7ebf\u6027\u65f6\u95f4\uff1aO(n) \u5e73\u65b9\u65f6\u95f4\uff1aO(n^2) \u7acb\u65b9\u65f6\u95f4\uff1aO(n^3) \u591a\u9879\u5f0f\u65f6\u95f4\uff1aO(n^k) 3.2.3.\u6bd4\u4f8b\u5e38\u6570\u7684\u4f5c\u7528 \u00b6 \u6bd4\u4f8b\u5e38\u6570\uff08constant of proportionality\uff09\u5305\u542b\u5728\u5927O\u5206\u6790\u4e2d\u88ab\u5ffd\u7565\u7684\u9879\u548c\u7cfb\u6570\u3002\u6bd4\u5982\uff0c\u7ebf\u6027\u65f6\u95f4\u7b97\u6cd5\u6240\u6267\u884c\u7684\u5de5\u4f5c\u91cf\u53ef\u4ee5\u8868\u793a\u4e3a\uff1a work = 2 * size \uff0c\u5176\u4e2d\u6bd4\u4f8b\u5e38\u6570\u5c31\u662f work/size \uff0c\u4e5f\u5c31\u662f 2 \u3002\u5728\u5904\u7406\u4e2d\u5c0f\u578b\u6570\u636e\u96c6\u7684\u65f6\u5019\uff0c\u5982\u679c\u8fd9\u4e9b\u5e38\u6570\u5f88\u5927\uff0c\u90a3\u4e48\u5b83\u4eec\u4e5f\u4f1a\u5f71\u54cd\u5230\u7b97\u6cd5\u6548\u7387\u3002 \u56de\u987e\u4e0b\u9762\u7684\u4f8b\u5b50\u3002 import time problemSize = 10000000 print ( \" %12s%16s \" % ( \"Problem Size\" , \"Seconds\" )) for count in range ( 5 ): number = 0 # \u7b97\u6cd5\u5f00\u59cb work = 1 for x in range ( problemSize ): number += 1 work += 1 work -= 1 # \u7b97\u6cd5\u7ed3\u675f print ( \" %12d%16.3f \" % ( problemSize , Iterations )) problemSize *= 2 # \u8fd0\u884c\u7ed3\u679c\uff1a # Problem Size Iterations # 10000000 10000000.000 # 20000000 20000000.000 # 40000000 40000000.000 # 80000000 80000000.000 # 160000000 160000000.000 \u5176\u4e2d\u7684\u7b97\u6cd5\u90e8\u5206\uff0c\u9664\u4e86\u5faa\u73af\u8bed\u53e5\u672c\u8eab\uff0c\u8fd8\u6709\u5176\u4ed63\u884c\u4ee3\u7801\uff0c\u5b83\u4eec\u90fd\u662f\u590d\u5236\u8bed\u53e5\uff0c\u90fd\u4f1a\u4ee5\u5e38\u6570\u65f6\u95f4\u8fd0\u884c\u3002\u5047\u8bbe\u5faa\u73af\u8bed\u53e5\u672c\u8eab\u4f1a\u6d88\u8017\u4e00\u4e2a\u65f6\u95f4\u5e38\u6570\uff0c\u90a3\u4e48\u8fd9\u4e2a\u7b97\u6cd5\u7684\u62bd\u8c61\u5de5\u4f5c\u65f6\u95f4\u5c31\u662f 3n+1 \u3002\u867d\u7136 3n+1 \u7684\u5de5\u4f5c\u91cf\u5927\u4e8e n \uff0c\u4f46\u4e8c\u8005\u5728\u8fd0\u884c\u65f6\u90fd\u662f\u7ebf\u6027\u589e\u52a0\uff0c\u6240\u4ee5\u4ed6\u4eec\u8fd0\u884c\u65f6\u90fd\u662f O(n) \u3002 # \u7b97\u6cd5\u5f00\u59cb work = 1 for x in range ( problemSize ): number += 1 work += 1 work -= 1 # \u7b97\u6cd5\u7ed3\u675f 3.2.4.\u7ec3\u4e60\u9898 \u00b6 \u5047\u8bbe\u4e0b\u9762\u7684\u8868\u8fbe\u5f0f\u90fd\u5206\u522b\u8868\u793a\u5bf9\u95ee\u9898\u89c4\u6a21\u4e3a n \u7684\u7b97\u6cd5\u6240\u9700\u8981\u6267\u884c\u7684\u64cd\u4f5c\u6570\uff0c\u8bf7\u6307\u51fa\u6bcf\u79cd\u7b97\u6cd5\u4e2d\u7684\u4e3b\u5bfc\u9879\uff0c\u5e76\u4f7f\u7528\u5927O\u8868\u793a\u6cd5\u5bf9\u5b83\u8fdb\u884c\u5206\u7c7b\u3002 a. 2^n - 4n + 5n b. 2n^2 + 8 c. n^3 n^2 + n \u89e3\u7b54\uff1a a. 2^n\uff0cO(n) b. n 2\uff0cO(n 2) c. n 3\uff0cO(n 3) \u5bf9\u4e8e\u89c4\u6a21\u4e3a n \u7684\u95ee\u9898\uff0c\u7b97\u6cd5A\u548cB\u5206\u522b\u4f1a\u6267\u884c n^2 \u548c (1/2)*n^2+(1/2)*n \u6761\u6307\u4ee4\u3002\u54ea\u79cd\u7b97\u6cd5\u66f4\u9ad8\u6548\uff1f\u6709\u6ca1\u6709\u4e00\u79cd\u7b97\u6cd5\u6bd4\u53e6\u4e00\u79cd\u7b97\u6cd5\u6027\u80fd\u660e\u663e\u66f4\u597d\u7684\u7279\u5b9a\u7684\u95ee\u9898\u89c4\u6a21\uff1f\u662f\u5426\u6709\u8ba9\u4e24\u79cd\u7b97\u6cd5\u90fd\u6267\u884c\u5927\u81f4\u76f8\u540c\u5de5\u4f5c\u91cf\u7684\u7279\u5b9a\u7684\u95ee\u9898\u89c4\u6a21\uff1f \u89e3\u7b54\uff1a \u5728\u6bd4\u8f83\u4e24\u79cd\u7b97\u6cd5\u7684\u6548\u7387\u65f6\uff0c\u901a\u5e38\u5173\u6ce8\u7b97\u6cd5\u6267\u884c\u65f6\u95f4\u968f\u95ee\u9898\u89c4\u6a21\u589e\u957f\u7684\u8d8b\u52bf\u3002\u9898\u76ee\u4e2d\u7684\u4e24\u79cd\u7b97\u6cd5\u7684\u6267\u884c\u6307\u4ee4\u6570\u5206\u522b\u5982\u4e0b\uff1a \u7b97\u6cd5A\uff1a\u6267\u884c n^2 \u6761\u6307\u4ee4\u3002 \u7b97\u6cd5B\uff1a\u6267\u884c (1/2)*n^2+(1/2)*n \u6761\u6307\u4ee4\u3002 \u7528\u5982\u4e0b\u4ee3\u7801\u6a21\u62df\u7b97\u6cd5A\u548c\u7b97\u6cd5B\uff0c\u53ef\u4ee5\u770b\u51fa\uff0c\u968f\u7740 n \u7684\u589e\u52a0\uff0c\u7b97\u6cd5A\u7684\u589e\u957f\u901f\u7387\u8fdc\u5927\u4e8e\u7b97\u6cd5B\u3002\u6240\u4ee5\u53ef\u4ee5\u8ba4\u4e3a\u5728 n >= 2 \u7684\u60c5\u51b5\u4e0b\uff0c\u7b97\u6cd5A\u4f18\u4e8e\u7b97\u6cd5B\u3002 n = 1 print ( \" %-15s%25s \" % ( \"ProblemSize: n\" , \"A/B\" )) while n < 1000000 : n *= 10 print ( \" %-15d%25d \" % ( n , int (( n ** 2 ) / ( 1 / 2 ) * n ** 2 + ( 1 / 2 ) * n ))) # ProblemSize: n A/B # 10 20005 # 100 200000050 # 1000 2000000000500 # 10000 20000000000005000 # 100000 200000000000000065536 # 1000000 1999999999999999966445568 \u7531\u6b64\u53ef\u5f97\uff0c\u5728\u5927\u95ee\u9898\u89c4\u6a21\u4e0b\uff0c\u7b97\u6cd5B\u7684\u589e\u957f\u901f\u7387\u4f1a\u66f4\u6162\uff0c\u56e0\u4e3a (1/2)*n^2+(1/2)*n \u4e2d\u7684 (1/2)*n \u90e8\u5206\u5bf9\u4e8e\u6574\u4f53\u589e\u957f\u6765\u8bf4\u76f8\u5bf9\u8f83\u5c0f\u3002 \u4e3a\u4e86\u8ba9\u4e24\u79cd\u7b97\u6cd5\u6267\u884c\u76f8\u8fd1\u7684\u5de5\u4f5c\u91cf\uff0c\u6211\u4eec\u53ef\u4ee5\u89e3\u4e0b\u9762\u7684\u65b9\u7a0b\uff1a ( 1 / 2 ) * n ^ 2 + ( 1 / 2 ) * n = k * n ^ 2 \u5176\u4e2d k \u662f\u4e00\u4e2a\u5e38\u6570\uff0c\u8868\u793a\u4e24\u79cd\u7b97\u6cd5\u6267\u884c\u7684\u5de5\u4f5c\u91cf\u76f8\u7b49\u65f6\u7684\u95ee\u9898\u89c4\u6a21\u3002\u901a\u8fc7\u89e3\u8fd9\u4e2a\u65b9\u7a0b\uff0c\u6211\u4eec\u53ef\u4ee5\u627e\u5230\u4e00\u4e2a\u95ee\u9898\u89c4\u6a21 k \uff0c\u5728\u8fd9\u4e2a\u95ee\u9898\u89c4\u6a21\u4e0b\uff0c\u4e24\u79cd\u7b97\u6cd5\u7684\u6267\u884c\u6307\u4ee4\u6570\u76f8\u8fd1\u3002 \u7b97\u6cd5\u7684\u6548\u7387\u5206\u6790\u5e76\u4e0d\u4ec5\u4ec5\u53d6\u51b3\u4e8e\u6307\u4ee4\u6570\uff0c\u8fd8\u53ef\u80fd\u53d7\u5230\u7b97\u6cd5\u4e2d\u5e38\u6570\u56e0\u5b50\u3001\u6570\u636e\u8bbf\u95ee\u6a21\u5f0f\u3001\u5185\u5b58\u5360\u7528\u7b49\u56e0\u7d20\u7684\u5f71\u54cd\u3002\u56e0\u6b64\uff0c\u5728\u5b9e\u9645\u5e94\u7528\u4e2d\uff0c\u901a\u5e38\u9700\u8981\u7efc\u5408\u8003\u8651\u591a\u4e2a\u56e0\u7d20\u6765\u786e\u5b9a\u6700\u4f18\u7684\u7b97\u6cd5\u9009\u62e9\u3002 \u5728\u4ec0\u4e48\u65f6\u5019\u5f00\u59cb n^4 \u7b97\u6cd5\u6bd4 2^n \u7b97\u6cd5\u8868\u73b0\u66f4\u597d\uff1f \u89e3\u7b54\uff1a\u7528\u4e0b\u9762\u7684\u7b97\u6cd5\u6a21\u62df n^4 \u7b97\u6cd5\u6bd4 2^n \u7b97\u6cd5\u6267\u884c\u5de5\u4f5c\u91cf\u3002\u4ece\u8fd0\u884c\u7ed3\u679c\u53ef\u4ee5\u770b\u51fa\uff1a n=16 \u662f\u5206\u754c\u70b9\uff0c n^4 \u7b97\u6cd5\u4e0e 2^n \u7b97\u6cd5\u5de5\u4f5c\u91cf\u76f8\u7b49\uff1b \u5f53 n<16 \u65f6\uff0c n^4 \u7b97\u6cd5\u6bd4 2^n \u7b97\u6cd5\u5de5\u4f5c\u91cf\u8981\u9ad8\uff1b \u5f53 n>16 \u65f6\uff0c n^4 \u7b97\u6cd5\u6bd4 2^n \u7b97\u6cd5\u5de5\u4f5c\u91cf\u8981\u4f4e\uff1b\u800c\u4e14 2^n \u7b97\u6cd5\u5de5\u4f5c\u91cf\u589e\u957f\u901f\u5ea6\u8fdc\u5927\u4e8e n^4 \u7b97\u6cd5\uff1b n = 1 print ( \" %-8s%10s%15s%10s \" % ( \"Size:n\" , \"A:n^4\" , \"B:2^n\" , \"B/A\" )) while n < 30 : n += 1 print ( \" %-8d%10d%15d%10.3f \" % ( n , int ( n ** 4 ), int ( 2 ** n ), ( 2 ** n ) / ( n ** 4 ))) # \u8fd0\u884c\u7ed3\u679c\uff1a # Size:n A:n^4 B:2^n B/A # 2 16 4 0.250 # 3 81 8 0.099 # 4 256 16 0.062 # 5 625 32 0.051 # 6 1296 64 0.049 # 7 2401 128 0.053 # 8 4096 256 0.062 # 9 6561 512 0.078 # 10 10000 1024 0.102 # 11 14641 2048 0.140 # 12 20736 4096 0.198 # 13 28561 8192 0.287 # 14 38416 16384 0.426 # 15 50625 32768 0.647 # 16 65536 65536 1.000 # 17 83521 131072 1.569 # 18 104976 262144 2.497 # 19 130321 524288 4.023 # 20 160000 1048576 6.554 # 21 194481 2097152 10.783 # 22 234256 4194304 17.905 # 23 279841 8388608 29.976 # 24 331776 16777216 50.568 # 25 390625 33554432 85.899 # 26 456976 67108864 146.854 # 27 531441 134217728 252.554 # 28 614656 268435456 436.725 # 29 707281 536870912 759.063 # 30 810000 1073741824 1325.607 3.3.\u641c\u7d22\u7b97\u6cd5 \u00b6 \u7ea6\u5b9a\uff1a \u4ee5\u5217\u8868\u4e3a\u4f8b\uff0c\u4ecb\u7ecd\u641c\u7d22\u548c\u6392\u5e8f\u7684\u7b97\u6cd5\uff1b \u9610\u91ca\u8fd9\u4e9b\u7b97\u6cd5\u7684\u8bbe\u8ba1\uff0c\u5e76\u628a\u5b83\u5b9e\u73b0\u4e3aPython\u51fd\u6570\uff1b \u51fd\u6570\u53ea\u5904\u7406\u5168\u90e8\u662f\u6574\u6570\u7684\u5217\u8868\uff0c\u4e0d\u540c\u5927\u5c0f\u7684\u5217\u8868\u5c06\u4f5c\u4e3a\u53c2\u6570\u4f20\u9012\u7ed9\u51fd\u6570\uff1b \u5bf9\u8fd9\u4e9b\u7b97\u6cd5\u7684\u8ba1\u7b97\u590d\u6742\u5ea6\u8fdb\u884c\u5206\u6790\uff1b 3.3.1.\u6700\u5c0f\u503c\u641c\u7d22 \u00b6 Python\u4e2d\u6709 min \u51fd\u6570\uff0c\u4f1a\u8fd4\u56de\u5217\u8868\u91cc\u7684\u6700\u5c0f\u503c\u6216\u6700\u5c0f\u5143\u7d20\uff0c\u4e0b\u9762\u5199\u4e00\u4e2a\u65b0\u7b97\u6cd5\uff0c\u6765\u5206\u6790 min \u51fd\u6570\u7684\u7b97\u6cd5\u590d\u6742\u5ea6\u3002 \u7b97\u6cd5\u76ee\u6807\uff1a\u5047\u5b9a\u5217\u8868\u4e0d\u4e3a\u7a7a\uff0c\u5e76\u4e14\u5143\u7d20\u662f\u6309\u7167\u4efb\u610f\u987a\u5e8f\u5b58\u653e\u5728\u5217\u8868\u91cc\u7684\uff0c\u7b97\u6cd5\u8fd4\u56de\u6700\u5c0f\u5143\u7d20\u7684\u7d22\u5f15\uff08index\uff09\u3002 \u7b97\u6cd5\u89e3\u6790\uff1a \u9996\u5148\u628a\u7b2c\u4e00\u4e2a\u4f4d\u7f6e\u4f5c\u4e3a\u5b58\u653e\u6700\u5c0f\u5143\u7d20\u7684\u4f4d\u7f6e\uff1b \u7136\u540e\u5411\u53f3\u4fa7\u641c\u7d22\u66f4\u5c0f\u7684\u5143\u7d20\uff1b \u5982\u679c\u627e\u5230\uff0c\u90a3\u4e48\u628a\u6700\u5c0f\u5143\u7d20\u7684\u4f4d\u7f6e\u91cd\u7f6e\u4e3a\u5f53\u524d\u4f4d\u7f6e\uff1b \u5f53\u7b97\u6cd5\u5230\u8fbe\u5217\u8868\u672b\u5c3e\u65f6\uff0c\u5b83\u5c06\u8fd4\u56de\u6700\u5c0f\u5143\u7d20\u7684\u4f4d\u7f6e\u3002 \u7b97\u6cd5\u5b9e\u73b0\uff1a def indexOfMin ( lyst ): \"\"\"\u8fd4\u56de\u6700\u5c0f\u5143\u7d20\u7684\u7d22\u5f15\uff0c\u76f8\u540c\u6700\u5c0f\u5143\u7d20\u8fd4\u56de\u7b2c\u4e00\u4e2a\u7d22\u5f15\"\"\" # \u7b97\u6cd5\u5f00\u59cb minIndex = 0 currentIndex = 1 while currentIndex < len ( lyst ): if lyst [ currentIndex ] < lyst [ minIndex ]: # \u6539\u6210<=\uff0c\u76f8\u540c\u6700\u5c0f\u5143\u7d20\u5219\u8fd4\u56de\u6700\u540e\u4e00\u4e2a\u7d22\u5f15 minIndex = currentIndex currentIndex += 1 return minIndex # \u7b97\u6cd5\u7ed3\u675f def main (): myList = [ 2 , 20 , 5 , 0 , 1 , 0 , 9 ] minIndex = indexOfMin ( myList ) print ( minIndex , myList [ minIndex ]) if __name__ == \"__main__\" : main () # \u8fd0\u7b97\u7ed3\u679c\uff1a # 3 0 # \u5982\u679c\u6539\u6210\u6539\u6210yst[currentIndex] <= lyst[minIndex]\uff0c\u5219\u76f8\u540c\u6700\u5c0f\u5143\u7d20\u5219\u8fd4\u56de\u6700\u540e\u4e00\u4e2a\u7d22\u5f15 # 5 0 \u65e0\u8bba\u5217\u8868\u7684\u5927\u5c0f\u5982\u4f55\uff0c\u5faa\u73af\u5916\u76843\u6761\u6307\u4ee4\uff082\u6761\u8d4b\u503c\u8bed\u53e5\uff0c\u4e00\u6761while\u8bed\u53e5\u672c\u8eab\uff09\u90fd\u4f1a\u6267\u884c\u76f8\u540c\u7684\u6b21\u6570\uff0c\u53ef\u4ee5\u5ffd\u7565\u5b83\u4eec\u90fd\u5f71\u54cd\u3002 \u5faa\u73af\u91cc\u8fd8\u67093\u6761\u6307\u4ee4\uff0c\u5176\u4e2d if \u8bed\u53e5\u5185\u7684\u6bd4\u8f83 lyst[currentIndex] < lyst[minIndex] \u548c currentIndex += 1 \u7684\u81ea\u589e\uff0c\u4f1a\u5728\u6bcf\u6b21\u5faa\u73af\u65f6\u90fd\u6267\u884c\uff0c\u4e14\u6ca1\u6709\u5176\u5b83\u5d4c\u5957\u6216\u9690\u85cf\u7684\u5faa\u73af\u3002 if \u8bed\u53e5\u4e2d\u7684\u6bd4\u8f83\u64cd\u4f5c\u5b9e\u73b0\u4e86\u8bbf\u95ee\u5217\u8868\u91cc\u7684\u6bcf\u4e2a\u5143\u7d20\uff0c\u4ece\u800c\u80fd\u591f\u627e\u5230\u6700\u5c0f\u5143\u7d20\u7684\u4f4d\u7f6e\u3002 \u56e0\u6b64\uff0c\u8fd9\u4e2a\u7b97\u6cd5\u5fc5\u987b\u5bf9\u5927\u5c0f\u4e3a n \u7684\u5217\u8868\u8fdb\u884c n-1 \u6b21\u6bd4\u8f83\uff0c\u5373\uff0c\u5b83\u7684\u590d\u6742\u5ea6\u4e3aO(n)\u3002 3.3.2.\u987a\u5e8f\u641c\u7d22\u5217\u8868 \u00b6 Python\u7684 in \u8fd0\u7b97\u7b26\u5728list\u7c7b\u91cc\u88ab\u5b9e\u73b0\u4e3a\u53eb\u4f5c __contains__ \u7684\u65b9\u6cd5\uff0c\u8fd9\u4e2a\u65b9\u6cd5\u4f1a\u5728\u4efb\u610f\u7684\u5143\u7d20\u5217\u8868\u91cc\u641c\u7d22\u7279\u5b9a\u7684\u5143\u7d20\uff0c\u5373\u76ee\u6807\u5143\u7d20\uff08target item\uff09\u3002 \u5728\u5217\u8868\u91cc\uff0c\u627e\u5230\u76ee\u6807\u5143\u7d20\u7684\u552f\u4e00\u65b9\u6cd5\u662f\u4ece\u4f4d\u4e8e\u7b2c\u4e00\u4e2a\u4f4d\u7f6e\u7684\u5143\u7d20\u5f00\u59cb\uff0c\u5e76\u628a\u5b83\u548c\u76ee\u6807\u5143\u7d20\u8fdb\u884c\u6bd4\u8f83\u3002\u5982\u679c\u4e24\u4e2a\u5143\u7d20\u76f8\u7b49\uff0c\u90a3\u4e48\u8fd9\u4e2a\u65b9\u6cd5\u8fd4\u56de True \uff1b\u5426\u5219\uff0c\u8fd9\u4e2a\u65b9\u6cd5\u5c06\u79fb\u52a8\u5230\u4e0b\u4e00\u4e2a\u4f4d\u7f6e\uff0c\u5e76\u628a\u5b83\u548c\u76ee\u6807\u5143\u7d20\u8fdb\u884c\u6bd4\u8f83\u3002\u5982\u679c\u8fd9\u4e2a\u65b9\u6cd5\u5230\u4e86\u6700\u540e\u4e00\u4e2a\u4f4d\u7f6e\u4ecd\u7136\u627e\u4e0d\u5230\u76ee\u6807\uff0c\u90a3\u4e48\u8fd4\u56de False \u3002\u8fd9\u79cd\u641c\u7d22\u79f0\u4e3a\u987a\u5e8f\u641c\u7d22\uff08sequential search\uff09\u6216\u7ebf\u6027\u641c\u7d22\uff08linear search\uff09\u3002 \u4e0b\u9762\u662f\u987a\u5e8f\u641c\u7d22\u51fd\u6570\u7684\u5b9e\u73b0\u3002\u82e5\u987a\u5e8f\u641c\u7d22\u7b97\u6cd5\u5728\u5217\u8868\u5f00\u5934\u5c31\u627e\u5230\u76ee\u6807\u5143\u7d20\uff0c\u90a3\u4e48\u8fd9\u65f6\u7684\u5de5\u4f5c\u91cf\u660e\u663e\u4f1a\u6bd4\u5728\u5217\u8868\u672b\u5c3e\u627e\u5230\u7684\u5de5\u4f5c\u91cf\u8981\u5c11\u3002 def sequentialSearch ( target , lyst ): \"\"\"\u627e\u5230\u76ee\u6807\u5143\u7d20\u65f6\u8fd4\u56de\u5143\u7d20\u7684\u7d22\u5f15, \u5426\u5219\u8fd4\u56de-1\"\"\" position = 0 while position < len ( lyst ): if target == lyst [ position ]: return position position += 1 return - 1 def main (): myList = [ 2 , 20 , 5 , 0 , 1 , 0 , 9 ] locatedIndex = sequentialSearch ( 9 , myList ) print ( locatedIndex , myList [ locatedIndex ]) if __name__ == \"__main__\" : main () # \u8fd0\u7b97\u7ed3\u679c\uff1a # 6 9 3.3.3.\u6700\u597d\u60c5\u51b5\u3001\u6700\u574f\u60c5\u51b5\u4ee5\u53ca\u5e73\u5747\u60c5\u51b5\u4e0b\u7684\u6027\u80fd \u00b6 \u4e00\u822c\u6765\u8bf4\uff0c\u91cd\u70b9\u5173\u6ce8\u5728\u5e73\u5747\u60c5\u51b5\u548c\u6700\u574f\u60c5\u51b5\u4e0b\u7684\u6027\u80fd\uff0c\u4e0d\u4f1a\u7279\u522b\u5173\u6ce8\u6700\u597d\u60c5\u51b5\u3002 \u5bf9\u987a\u5e8f\u641c\u7d22\u7684\u5206\u6790\u9700\u8981\u8003\u8651\u4e0b\u97623\u79cd\u60c5\u51b5\u3002 \u5728\u6700\u574f\u60c5\u51b5\u4e0b\uff0c\u76ee\u6807\u5143\u7d20\u4f4d\u4e8e\u5217\u8868\u7684\u672b\u5c3e\u6216\u8005\u6839\u672c\u5c31\u4e0d\u5728\u5217\u8868\u91cc\u3002\u8fd9\u65f6\uff0c\u8fd9\u4e2a\u7b97\u6cd5\u5c31\u5fc5\u987b\u8bbf\u95ee\u6bcf\u4e00\u4e2a\u5143\u7d20\uff0c\u5bf9\u5927\u5c0f\u4e3a n \u7684\u5217\u8868\u9700\u8981\u6267\u884c n \u6b21\u8fed\u4ee3\u3002\u56e0\u6b64\uff0c\u987a\u5e8f\u641c\u7d22\u7684\u6700\u574f\u60c5\u51b5\u7684\u590d\u6742\u5ea6\u4e3aO(n)\u3002 \u5728\u6700\u597d\u60c5\u51b5\u4e0b\uff0c\u53ea\u9700\u8981O(1)\u7684\u590d\u6742\u5ea6\uff0c\u56e0\u4e3a\u8fd9\u4e2a\u7b97\u6cd5\u5728\u4e00\u6b21\u8fed\u4ee3\u4e4b\u540e\u5c31\u4f1a\u5728\u7b2c\u4e00\u4e2a\u4f4d\u7f6e\u627e\u5230\u76ee\u6807\u5143\u7d20\u3002 \u8981\u786e\u5b9a\u5e73\u5747\u60c5\u51b5\uff0c\u5c31\u9700\u8981\u628a\u6bcf\u4e2a\u53ef\u80fd\u4f4d\u7f6e\u627e\u5230\u76ee\u6807\u6240\u9700\u8981\u7684\u8fed\u4ee3\u6b21\u6570\u76f8\u52a0\uff0c\u7136\u540e\u518d\u5c06\u5b83\u4eec\u7684\u603b\u548c\u9664\u4ee5 n \u3002\u56e0\u6b64\uff0c\u8fd9\u79cd\u60c5\u51b5\u4e0b\uff0c\u7b97\u6cd5\u4f1a\u6267\u884c (n + n\u22121 + n\u22122+ ... +1)/n \u6216 (n+1)/2 \u6b21\u8fed\u4ee3\u3002\u5bf9\u4e8e\u975e\u5e38\u5927\u7684 n \u6765\u8bf4\uff0c\u5e38\u6570\u7cfb\u65702\u662f\u53ef\u4ee5\u5ffd\u7565\u7684\uff0c\u56e0\u6b64\uff0c\u5e73\u5747\u60c5\u51b5\u7684\u590d\u6742\u5ea6\u4ecd\u7136\u662fO(2)\u3002 \u7ed3\u8bba\uff1a\u6700\u597d\u60c5\u51b5\u4e0b\u987a\u5e8f\u641c\u7d22\u7684\u6027\u80fd\u548c\u5176\u4ed6\u4e24\u79cd\u60c5\u51b5\u6bd4\u8d77\u6765\u5c0f\u5f88\u591a\uff0c\u800c\u5176\u4ed6\u4e24\u79cd\u60c5\u51b5\u4e0b\u7684\u6027\u80fd\u662f\u5dee\u4e0d\u591a\u7684\u3002 3.3.4.\u57fa\u4e8e\u6709\u5e8f\u5217\u8868\u7684\u4e8c\u5206\u641c\u7d22 \u00b6 \u5728\u6570\u636e\u65e0\u5e8f\u7684\u60c5\u51b5\u4e0b\uff0c\u4f7f\u7528\u987a\u5e8f\u641c\u7d22\u6765\u627e\u5230\u76ee\u6807\u5143\u7d20\u3002 \u5728\u6570\u636e\u6709\u5e8f\u7684\u60c5\u51b5\u4e0b\uff0c\u4f7f\u7528\u4e8c\u5206\u641c\u7d22\u6765\u627e\u5230\u76ee\u6807\u5143\u7d20\u3002 Python\u4e2d\u5b9e\u73b0\u4e8c\u5206\u641c\u7d22\u7684\u601d\u8def\uff1a \u5047\u8bbe\u5217\u8868\u91cc\u7684\u5143\u7d20\u90fd\u4ee5\u5347\u5e8f\u6392\u5e8f\u3002 \u641c\u7d22\u7b97\u6cd5\u9996\u5148\u5230\u5217\u8868\u7684\u4e2d\u95f4\u4f4d\u7f6e\uff0c\u5e76\u628a\u8fd9\u4e2a\u4f4d\u7f6e\u7684\u5143\u7d20\u4e0e\u76ee\u6807\u5143\u7d20\u8fdb\u884c\u6bd4\u8f83\uff1b \u5982\u679c\u5339\u914d\uff0c\u90a3\u4e48\u7b97\u6cd5\u5c31\u8fd4\u56de\u5f53\u524d\u4f4d\u7f6e\u3002\u5982\u679c\u76ee\u6807\u5143\u7d20\u5c0f\u4e8e\u5f53\u524d\u5143\u7d20\uff0c\u90a3\u4e48\u7b97\u6cd5\u5c06\u4f1a\u641c\u7d22\u4e2d\u95f4\u4f4d\u7f6e\u4e4b\u524d\u7684\u90e8\u5206\uff1b \u5982\u679c\u76ee\u6807\u5143\u7d20\u5927\u4e8e\u5f53\u524d\u5143\u7d20\uff0c\u5219\u641c\u7d22\u4e2d\u95f4\u4f4d\u7f6e\u4e4b\u540e\u7684\u90e8\u5206\u3002 \u5728\u627e\u5230\u4e86\u76ee\u6807\u5143\u7d20\u6216\u8005\u5f53\u524d\u5f00\u59cb\u4f4d\u7f6e\u5927\u4e8e\u5f53\u524d\u7ed3\u675f\u4f4d\u7f6e\u65f6\uff0c\u505c\u6b62\u641c\u7d22\u8fc7\u7a0b\u3002 \u4e0b\u9762\u662f\u4e8c\u5206\u641c\u7d22\u51fd\u6570\u7684\u4ee3\u7801\u3002\u4ee5\u5217\u8868 [2, 20, 5, 0, 1, 0, 9] \u4e3a\u4f8b\uff1a \u6392\u5e8f\u540e\u7684\u5217\u8868\u4e3a [0, 0, 1, 2, 5, 9, 20] \uff1b \u6392\u5e8f\u540e\u5217\u8868\u957f\u5ea6\u662f7\uff0c\u6240\u4ee5\u521d\u59cbmidpoint=3\uff0c\u5bf9\u5e94\u5217\u8868\u503c\u662f2\uff1b def binarySearch ( target , sortedLyst ): left = 0 right = len ( sortedLyst ) - 1 while left <= right : midpoint = ( left + right ) // 2 if target == sortedLyst [ midpoint ]: return midpoint elif target < sortedLyst [ midpoint ]: right = midpoint - 1 else : left = midpoint + 1 return - 1 def main (): myList = [ 2 , 20 , 5 , 0 , 1 , 0 , 9 ] sortedList = sorted ( myList ) # \u5982\u679c\u4f7f\u7528myList.sort()\uff0c\u5219\u4f1a\u4fee\u6539myList\u672c\u8eab locatedIndex = binarySearch ( 5 , sortedList ) print ( sortedList ) print ( locatedIndex , sortedList [ locatedIndex ]) if __name__ == \"__main__\" : main () # \u8fd0\u7b97\u7ed3\u679c\uff1a # [0, 0, 1, 2, 5, 9, 20] # 4 5 # \u5982\u679c\u6267\u884cbinarySearch(0, sortedList)\uff0c\u5219\u4f1a\u8fd4\u56de\u7b2c\u4e8c\u4e2a0\u7684\u7d22\u5f15 # [0, 0, 1, 2, 5, 9, 20] # 1 0 \u4e0a\u9762\u4e8c\u5206\u6cd5\u7b97\u6cd5\u590d\u6742\u5ea6\u5206\u6790\uff1a \u7b97\u6cd5\u91cc\u53ea\u6709\u4e00\u4e2a\u5faa\u73af\uff0c\u5e76\u4e14\u6ca1\u6709\u5d4c\u5957\u6216\u9690\u85cf\u7684\u5faa\u73af\u3002\u5982\u679c\u76ee\u6807\u4e0d\u5728\u5217\u8868\u91cc\uff0c\u5c31\u4f1a\u5f97\u5230\u6700\u574f\u60c5\u51b5\uff0c\u5373\u904d\u5386\u5217\u8868\u7684\u4e00\u534a\uff0c\u5373\u5faa\u73af\u5217\u8868\u5927\u5c0f\u4e0d\u65ad\u9664\u4ee52\u76f4\u81f3\u5546\u4e3a1\u7684\u6b21\u6570\u3002 \u5bf9\u4e8e\u5927\u5c0f\u4e3a n \u7684\u5217\u8868\u6765\u8bf4\uff0c\u4e5f\u5c31\u662f\u4f60\u9700\u8981\u6267\u884c n/2/2/.../2 \u6b21\uff0c\u76f4\u5230\u7ed3\u679c\u4e3a1\u3002\u5047\u8bbe k \u662f n \u53ef\u4ee5\u9664\u4ee52\u7684\u6b21\u6570\uff0c\u90a3\u4e48\u6c42\u89e3 k \u4f1a\u6709 n/(2^k)=1 \uff0c\u5373 n=2^k \uff0c\u5373 k=log(n,2) \u3002\u56e0\u6b64\uff0c\u4e8c\u5206\u641c\u7d22\u5728\u6700\u574f\u60c5\u51b5\u4e0b\u7684\u590d\u6742\u5ea6\u4e3aO(log(n,2))\u3002 3.3.5.\u6bd4\u8f83\u6570\u636e\u5143\u7d20 \u00b6 \u4e8c\u5206\u641c\u7d22\u548c\u6700\u5c0f\u503c\u641c\u7d22\u90fd\u6709\u4e00\u4e2a\u5047\u8bbe\uff0c\u90a3\u5c31\u662f\u201c\u5217\u8868\u91cc\u7684\u5143\u7d20\u5f7c\u6b64\u4e4b\u95f4\u662f\u53ef\u4ee5\u6bd4\u8f83\u7684\u201d\u3002\u5373\uff0c\u8fd9\u4e9b\u5143\u7d20\u5c5e\u4e8e\u540c\u4e00\u4e2a\u7c7b\u578b\uff0c\u5373\uff0c\u53ef\u4ee5\u4f7f\u7528\u6bd4\u8f83\u8fd0\u7b97\u7b26 == \u3001 < \u548c > \u3002 Python\u5185\u7f6e\u7684\u7c7b\u578b\u5bf9\u8c61\uff0c\u5982\u6570\u5b57\u3001\u5b57\u7b26\u4e32\u548c\u5217\u8868\uff0c\u90fd\u652f\u6301\u6bd4\u8f83\u8fd0\u7b97\u7b26\u3002 \u4e3a\u4e86\u80fd\u591f\u8ba9\u7b97\u6cd5\u5bf9\u65b0\u7684\u7c7b\u5bf9\u8c61\u4f7f\u7528\u6bd4\u8f83\u8fd0\u7b97\u7b26 == \u3001 < \u548c > \uff0c\u5e94\u8be5\u5728\u8fd9\u4e2a\u7c7b\u91cc\u5b9a\u4e49 __eq__ \u3001 __lt__ \u548c __gt__ \u65b9\u6cd5\u3002\u5728\u5b9a\u4e49\u4e86\u8fd9\u4e9b\u65b9\u6cd5\u4e4b\u540e\uff0c\u5176\u4ed6\u6bd4\u8f83\u8fd0\u7b97\u7b26\u7684\u65b9\u6cd5\u5c06\u81ea\u52a8\u751f\u6210\u3002 \u4f8b\u5982\uff0c __lt__ \u7684\u5b9a\u4e49\u5982\u4e0b\uff0c\u5982\u679c self \u5c0f\u4e8e other \uff0c\u90a3\u4e48\u8fd9\u4e2a\u65b9\u6cd5\u5c06\u8fd4\u56de True \uff1b\u5426\u5219\uff0c\u8fd4\u56de False \u3002 __lt__ \u65b9\u6cd5\u4f1a\u4e3a\u4e24\u4e2a\u8d26\u6237\u5bf9\u8c61\u7684 name \u5b57\u6bb5\u8c03\u7528\u8fd0\u7b97\u7b26 < \u3002 \u540d\u79f0\u5b57\u6bb5\u662f\u5b57\u7b26\u4e32\uff0c\u5b57\u7b26\u4e32\u7c7b\u578b\u5df2\u7ecf\u5305\u542b\u5728 __lt__ \u65b9\u6cd5\u91cc\u3002 \u5728\u4f7f\u7528\u8fd0\u7b97\u7b26 < \u65f6\uff0cPython\u4f1a\u81ea\u52a8\u8fd0\u884c\u5b57\u7b26\u4e32\u7684 __lt__ \u65b9\u6cd5\uff0c\u8fd9\u4e0e\u8c03\u7528 str \u51fd\u6570\u65f6\u81ea\u52a8\u8fd0\u884c __str__ \u65b9\u6cd5\u662f\u7c7b\u4f3c\u7684\u3002 def __lt__ ( self , other ): \u793a\u4f8b\uff1a\u8fd4\u56de\u50a8\u84c4\u8d26\u6237\u7684\u6240\u6709\u4eba\u540d\u5b57\u3001PIN\u7801\u3001\u4f59\u989d\u3002 class SavingsAccount ( object ): \"\"\"\u8fd4\u56de\u50a8\u84c4\u8d26\u6237\u7684\u6240\u6709\u4eba\u540d\u5b57\u3001PIN\u7801\u3001\u4f59\u989d\"\"\" def __init__ ( self , name , pin , balance = 0.0 ): self . name = name self . pin = pin self . balance = balance def __lt__ ( self , other ): return self . name < other . name # Other methods, including __eq__ def main (): s1 = SavingsAccount ( \"Ken\" , \"1001\" , 0 ) s2 = SavingsAccount ( \"Bill\" , \"1001\" , 30 ) s3 = SavingsAccount ( \"Ken\" , \"1000\" , 0 ) s4 = s1 print ( \"s1 < s2: \" , s1 < s2 ) print ( \"s2 < s1: \" , s2 < s1 ) print ( \"s2 > s1: \" , s2 > s1 ) print ( \"s2 == s1: \" , s2 == s1 ) print ( \"s1 == s3: \" , s1 == s3 ) print ( \"s1 == s4: \" , s1 == s4 ) if __name__ == \"__main__\" : main () # \u8fd0\u7b97\u7ed3\u679c\uff1a # s1 < s2: False # s2 < s1: True # s2 > s1: False # s2 == s1: False # s1 == s3: False # s1 == s4: True \u63d0\u793a\uff1a\u5728Python\u4e2d\uff0c\u9ed8\u8ba4\u662f\u6309\u7167ASCII\u7684\u5927\u5c0f\u6bd4\u8f83\u5b57\u7b26\u4e32\u7684\uff0c\u5373\u4ece\u5b57\u7b26\u4e32\u7684\u7b2c\u4e00\u4e2a\u5b57\u7b26\u8fdb\u884c\u6bd4\u8f83\uff0c\u5982\u679c\u76f8\u7b49\uff0c\u5219\u7ee7\u7eed\u6bd4\u8f83\u4e0b\u4e00\u4e2a\u5b57\u7b26\uff0c\u76f4\u5230\u5206\u51fa\u5927\u5c0f\uff0c\u6216\u8005\u8fd8\u6ca1\u5206\u51fa\u5927\u5c0f\uff0c\u6709\u4e00\u4e2a\u5b57\u7b26\u4e32\u5df2\u7ecf\u5230\u5934\u4e86\uff0c\u90a3\u4e48\u8f83\u957f\u7684\u90a3\u4e00\u4e2a\u5b57\u7b26\u4e32\u5927\u3002 3.3.6.\u7ec3\u4e60\u9898 \u00b6 \u5047\u8bbe\u4e00\u4e2a\u5217\u8868\u5728\u7d22\u5f150\uff5e9\u7684\u4f4d\u7f6e\u5904\u5305\u542b\u503c20\u300144\u300148\u300155\u300162\u300166\u300174\u300188\u300193\u300199\uff0c\u8bf7\u5728\u7528\u4e8c\u5206\u641c\u7d22\u67e5\u627e\u76ee\u6807\u5143\u7d2090\u7684\u65f6\u5019\uff0c\u5bf9\u53d8\u91cfleft\u3001right\u548cmidpoint\u7684\u503c\u8fdb\u884c\u8ddf\u8e2a\u3002\u6539\u53d8\u76ee\u6807\u5143\u7d20\u4e3a44\uff0c\u5e76\u91cd\u590d\u8fd9\u4e2a\u6b65\u9aa4\u3002 \u89e3\u7b54\uff1a \u4e0b\u9762\u662f\u4ee3\u7801\u548c\u8ddf\u8e2a\u7ed3\u679c\u3002 def binarySearch ( target , sortedLyst ): left = 0 right = len ( sortedLyst ) - 1 print ( \" %5s%10s%10s \" % ( \"left\" , \"midpoint\" , \"right\" )) while left <= right : midpoint = ( left + right ) // 2 print ( \" %5s%10s%10s \" % ( left , midpoint , right )) if target == sortedLyst [ midpoint ]: return midpoint elif target < sortedLyst [ midpoint ]: right = midpoint - 1 else : left = midpoint + 1 return - 1 def main (): myList = [ 20 , 44 , 48 , 55 , 62 , 66 , 74 , 88 , 93 , 99 ] sortedList = sorted ( myList ) locatedIndex = binarySearch ( 44 , sortedList ) if __name__ == \"__main__\" : main () # \u8fd0\u7b97\u7ed3\u679c\uff1a # Target = 90 # left midpoint right # 0 4 9 # 5 7 9 # 8 8 9 # # Target = 44 # left midpoint right # 0 4 9 # 0 1 3 \u901a\u5e38\u6765\u8bf4\uff0c\u67e5\u627e\u7535\u8bdd\u7c3f\u4e2d\u6761\u76ee\u7684\u65b9\u6cd5\u4e0e\u4e8c\u5206\u641c\u7d22\u5e76\u4e0d\u5b8c\u5168\u76f8\u540c\uff0c\u56e0\u4e3a\u4f7f\u7528\u7535\u8bdd\u7c3f\u7684\u65f6\u5019\uff0c\u5e76\u4e0d\u4f1a\u6bcf\u6b21\u90fd\u7ffb\u5230\u88ab\u641c\u7d22\u7684\u5b50\u5217\u8868\u7684\u4e2d\u70b9\u3002\u4e00\u822c\u6765\u8bf4\uff0c\u53ef\u4ee5\u6839\u636e\u8fd9\u4e2a\u4eba\u7684\u59d3\u6c0f\u7684\u7b2c\u4e00\u4e2a\u5b57\u6bcd\u987a\u5e8f\u6765\u4f30\u7b97\u76ee\u6807\u53ef\u80fd\u4f1a\u5728\u7684\u4f4d\u7f6e\u3002\u4f8b\u5982\uff0c\u5f53\u67e5\u627e\u201cSmith\u201d\u7684\u7535\u8bdd\u65f6\uff0c\u4f60\u4f1a\u9996\u5148\u67e5\u770b\u7535\u8bdd\u7c3f\u4e0b\u534a\u90e8\u5206\u7684\u4e2d\u95f4\uff0c\u800c\u4e0d\u662f\u6574\u4e2a\u7535\u8bdd\u7c3f\u7684\u4e2d\u95f4\u3002\u8bf7\u5bf9\u4e8c\u5206\u641c\u7d22\u7b97\u6cd5\u5c1d\u8bd5\u8fdb\u884c\u4fee\u6539\uff0c\u4ece\u800c\u53ef\u4ee5\u5728\u5904\u7406\u540d\u79f0\u5217\u8868\u7684\u65f6\u5019\u6a21\u62df\u8fd9\u4e2a\u7b56\u7565\u3002\u5b83\u7684\u8ba1\u7b97\u590d\u6742\u5ea6\u4e0e\u6807\u51c6\u7684\u4e8c\u5206\u641c\u7d22\u76f8\u6bd4\u8f83\u4f1a\u66f4\u597d\u5417\uff1f \u89e3\u7b54\uff1a\u4e0b\u9762\u662f\u4ee3\u7801\u548c\u8ffd\u8e2a\u7ed3\u679c\u3002\u901a\u8fc7\u5bf9\u6bd4\u4e0d\u540c\u6743\u91cd\u5355\u8bcd\u5230\u7684\u641c\u7d22\uff0c\u53ef\u4ee5\u53d1\u73b0\u6743\u91cd\u4e8c\u5206\u6cd5\u7684\u6548\u7387\u82e5\u8981\u4f18\u4e8e\u4f20\u7edf\u4e8c\u5206\u6cd5\uff0c\u662f\u9700\u8981\u6ee1\u8db3\u4e00\u5b9a\u7684\u6761\u4ef6\u7684\u3002 \u5728\u641c\u7d22\u7684\u7b2c\u4e00\u8f6e\u4e2d\uff0c\u4e2d\u95f4\u4f4d\u7f6e\u5c06\u53d6\u51b3\u4e8e\u5217\u8868\u7684\u5927\u5c0f\u548c\u76ee\u6807\u540d\u5b57\u7684\u7b2c\u4e00\u4e2a\u5b57\u6bcd\u7684\u987a\u5e8f\u503c\u3002\u56e0\u6b64\uff0c\u7b2c\u4e00\u8f6e\u641c\u7d22\u5c06\u6d88\u9664\u6bd4\u4ee5\u524d\u66f4\u591a\u7684\u5143\u7d20\uff0c\u5e76\u4e14\u5982\u679c\u9700\u8981\u5176\u4ed6\u8f6e\u641c\u7d22\uff0c\u5b83\u4eec\u7684\u641c\u7d22\u7a7a\u95f4\u4e5f\u4f1a\u66f4\u5c0f\u3002\u7136\u800c\uff0c\u5728\u6700\u574f\u60c5\u51b5\u4e0b\uff0c\u4fee\u6539\u540e\u7684\u7b97\u6cd5\u4ecd\u7136\u6bd4O(1)\u66f4\u63a5\u8fd1O(log n)\u3002 def binarySearch ( target , sortedLyst ): left = 0 right = len ( sortedLyst ) - 1 print ( \" %5s%10s%10s \" % ( \"left\" , \"midpoint\" , \"right\" )) while left <= right : midpoint = ( left + right ) // 2 print ( \" %5s%10s%10s \" % ( left , midpoint , right )) if target == sortedLyst [ midpoint ]: return midpoint elif target < sortedLyst [ midpoint ]: right = midpoint - 1 else : left = midpoint + 1 return - 1 def letter_position ( myLetter ): letter = myLetter . lower () # \u8f6c\u6210\u5c0f\u5199\u5b57\u6bcd alphabet = \"abcdefghijklmnopqrstuvwxyz\" if letter in alphabet : return alphabet . index ( letter ) + 1 # \u4f4d\u7f6e\u63091\uff5e26\u8ba1\u7b97 else : return None # \u975e\u5b57\u6bcd def dictSearch ( target , sortedLyst ): left = 0 right = len ( sortedLyst ) - 1 # \u9996\u5b57\u6bcd\u5728\u5b57\u6bcd\u8868\u4e2d\u7684\u767e\u5206\u4f4d letter_position_range = letter_position ( target [ 0 ]) * 100 // 26 # \u6309\u7167\u6240\u5f97\u7684\u9996\u5b57\u6bcd\u5728\u5b57\u6bcd\u8868\u4e2d\u7684\u767e\u5206\u4f4d\uff0c\u4f5c\u4e3a\u7ed9\u5b9a\u5b57\u4e32\u4e2d\u8bbe\u5b9a\u641c\u7d22\u8d77\u59cb\u767e\u5206\u4f4d midpoint = letter_position_range * ( len ( sortedLyst ) - 1 ) // 100 print ( \" %5s%10s%10s \" % ( \"left\" , \"midpoint\" , \"right\" )) while left <= right : print ( \" %5s%10s%10s \" % ( left , midpoint , right )) if target == sortedLyst [ midpoint ]: return midpoint elif target < sortedLyst [ midpoint ]: right = midpoint - 1 else : left = midpoint + 1 midpoint = ( left + right ) // 2 return - 1 def main (): myList = [ \"Bob\" , \"Charlie\" , \"Eva\" , \"Alice\" , \"Grace\" , \"David\" , \"Smith\" , \"Frank\" , \"Zoe\" , \"Jack\" ] sortedList = sorted ( myList ) print ( sortedList ) print ( \"=====call binarySearch=====\" ) locatedIndex = binarySearch ( \"Alice\" , sortedList ) print ( \"Found\" , sortedList [ locatedIndex ], \"in position\" , locatedIndex ) print ( \"=====call dictSearch=====\" ) locatedIndex = dictSearch ( \"Alice\" , sortedList ) print ( \"Found\" , sortedList [ locatedIndex ], \"in position\" , locatedIndex ) if __name__ == \"__main__\" : main () # \u8fd0\u7b97\u7ed3\u679c\uff1a # \u641c\u7d22Alice # ['Alice', 'Bob', 'Charlie', 'David', 'Eva', 'Frank', 'Grace', 'Jack', 'Smith', 'Zoe'] # =====call binarySearch===== # left midpoint right # 0 4 9 # 0 1 3 # 0 0 0 # Found Alice in position 0 # =====call dictSearch===== # left midpoint right # 0 0 9 # Found Alice in position 0 # \u641c\u7d22Bob # ['Alice', 'Bob', 'Charlie', 'David', 'Eva', 'Frank', 'Grace', 'Jack', 'Smith', 'Zoe'] # =====call binarySearch===== # left midpoint right # 0 4 9 # 0 1 3 # Found Bob in position 1 # =====call dictSearch===== # left midpoint right # 0 0 9 # 1 5 9 # 1 2 4 # 1 1 1 # Found Bob in position 1 # \u641c\u7d22Smith # ['Alice', 'Bob', 'Charlie', 'David', 'Eva', 'Frank', 'Grace', 'Jack', 'Smith', 'Zoe'] # =====call binarySearch===== # left midpoint right # 0 4 9 # 5 7 9 # 8 8 9 # Found Smith in position 8 # =====call dictSearch===== # left midpoint right # 0 6 9 # 7 8 9 # Found Smith in position 8 # \u641c\u7d22Zoe # ['Alice', 'Bob', 'Charlie', 'David', 'Eva', 'Frank', 'Grace', 'Jack', 'Smith', 'Zoe'] # =====call binarySearch===== # left midpoint right # 0 4 9 # 5 7 9 # 8 8 9 # 9 9 9 # Found Zoe in position 9 # =====call dictSearch===== # left midpoint right # 0 9 9 # Found Zoe in position 9 3.4.\u57fa\u672c\u7684\u6392\u5e8f\u7b97\u6cd5 \u00b6 \u4e0b\u9762\u662fswap\u51fd\u6570\u7684\u4f8b\u5b50\uff0c\u5b9e\u73b0\u4e86\uff1a \u5047\u8bbe\u90fd\u5728\u6574\u6570\u5217\u8868\u4e0a\u8fd0\u884c\uff1b \u4ea4\u6362\u5217\u8868\u4e2d\u4e24\u4e2a\u5143\u7d20\u7684\u4f4d\u7f6e\uff1b def swap ( lyst , i , j ): \"\"\"\u4ea4\u6362\u5143\u7d20\u4f4d\u7f6e\u4e3ai\u548cj\u7684\u5143\u7d20\"\"\" temp = lyst [ i ] lyst [ i ] = lyst [ j ] lyst [ j ] = temp def main (): myList = [ 9 , 4 , 2 , 7 , 6 , 8 , 1 ] print ( myList ) swap ( myList , 3 , 5 ) print ( myList ) if __name__ == \"__main__\" : main () # \u8fd0\u884c\u7ed3\u679c\uff1a # [9, 4, 2, 7, 6, 8, 1] # [9, 4, 2, 8, 6, 7, 1] 3.4.1.\u9009\u62e9\u6392\u5e8f \u00b6 \u9009\u62e9\u6392\u5e8f\uff08selection sort\uff09\uff1a\uff08\u4ee5\u5217\u8868\u4e3a\u4f8b\uff09 \u5728\u4e00\u4e2a\u957f\u5ea6\u4e3a N \u7684\u65e0\u5e8f\u5217\u8868\u4e2d\uff0c\u7b2c\u4e00\u6b21\u904d\u5386 n-1 \u4e2a\u6570\u627e\u5230\u6700\u5c0f\u7684\u548c\u7b2c\u4e00\u4e2a\u6570\u4ea4\u6362\u3002 \u7b2c\u4e8c\u6b21\u4ece\u4e0b\u4e00\u4e2a\u6570\u5f00\u59cb\u904d\u5386 n-2 \u4e2a\u6570\uff0c\u627e\u5230\u6700\u5c0f\u7684\u6570\u548c\u7b2c\u4e8c\u4e2a\u6570\u4ea4\u6362\u3002 \u91cd\u590d\u4ee5\u4e0a\u64cd\u4f5c\u76f4\u5230\u7b2c n-1 \u6b21\u904d\u5386\u6700\u5c0f\u7684\u6570\u548c\u7b2c n-1 \u4e2a\u6570\u4ea4\u6362\uff0c\u6392\u5e8f\u5b8c\u6210\u3002 \u8fd9\u4e2a\u7b97\u6cd5\u5728\u6bcf\u6b21\u901a\u8fc7\u4e3b\u5faa\u73af\u65f6\uff0c\u90fd\u4f1a\u9009\u62e9\u8981\u79fb\u52a8\u7684\u90a3\u4e00\u4e2a\u5143\u7d20\u3002 \u7b97\u6cd5\u590d\u6742\u5ea6\uff1a \u7b2c1\u6b21\u6267\u884c\u5916\u90e8\u5faa\u73af\u65f6\uff0c\u5185\u90e8\u5faa\u73af\u4f1a\u6267\u884cn-1\u6b21\uff1b \u7b2c2\u6b21\u6267\u884c\u5916\u90e8\u5faa\u73af\u65f6\uff0c\u5185\u90e8\u5faa\u73af\u4f1a\u6267\u884cn-2\u6b21\uff1b \u6700\u540e\u4e00\u6b21\u6267\u884c\u5916\u90e8\u5faa\u73af\u65f6\uff0c\u5185\u90e8\u5faa\u73af\u4f1a\u6267\u884c1\u6b21\uff1b \u6240\u4ee5\uff0c\u5927\u5c0f\u4e3a n \u7684\u5217\u8868\uff0c\u4e00\u5171\u9700\u8981\u7684\u6bd4\u8f83\u6b21\u6570\u662f (n-1)+(n-2)+...+1 \uff0c\u5316\u7b80\u4e3a n*(n-1)/2 \uff0c\u5373 (1/2)*n^2+(1/2)*n \u3002\u5f53 n \u6bd4\u8f83\u5927\u65f6\uff0c\u53ef\u4ee5\u9009\u62e9\u6700\u9ad8\u6b21\u7684\u9879\u5e76\u5ffd\u7565\u7cfb\u6570\uff0c\u56e0\u6b64\u5728\u6240\u6709\u60c5\u51b5\u4e0b\uff0c\u9009\u62e9\u6392\u5e8f\u7684\u590d\u6742\u5ea6\u90fd\u662fO(n^2)\u3002 \u5bf9\u4e8e\u5927\u578b\u6570\u636e\u96c6\u6765\u8bf4\uff0c\u4ea4\u6362\u5143\u7d20\u7684\u6210\u672c\u53ef\u80fd\u4f1a\u5f88\u9ad8\u3002\u56e0\u4e3a\u8fd9\u4e2a\u7b97\u6cd5\u53ea\u4f1a\u5728\u5916\u90e8\u5faa\u73af\u91cc\u5bf9\u6570\u636e\u5143\u7d20\u8fdb\u884c\u4ea4\u6362\uff0c\u6240\u4ee5\u5728\u6700\u574f\u60c5\u51b5\u548c\u5e73\u5747\u60c5\u51b5\u4e0b\uff0c\u9009\u62e9\u6392\u5e8f\u7684\u989d\u5916\u6210\u672c\u662f\u7ebf\u6027\u7684\u3002 \u7b97\u6cd5\u4ee3\u7801\uff1a def swap ( lyst , i , j ): \"\"\"\u4ea4\u6362\u5143\u7d20\u4f4d\u7f6e\u4e3ai\u548cj\u7684\u5143\u7d20\"\"\" temp = lyst [ i ] lyst [ i ] = lyst [ j ] lyst [ j ] = temp def selectionSort ( lyst ): \"\"\"\u5b9e\u73b0\u4ea4\u6362\u6392\u5e8f\u7b97\u6cd5\"\"\" i = 0 while i < len ( lyst ) - 1 : # \u5b9e\u73b0n-1\u6b21\u641c\u7d22 minIndex = i # \u6700\u5c0f\u5143\u7d20\u4f4d\u7f6e j = i + 1 while j < len ( lyst ): # \u5411\u540e\u904d\u5386\u641c\u7d22\uff0c\u66f4\u65b0\u6700\u5c0f\u5143\u7d20\u4f4d\u7f6e if lyst [ j ] < lyst [ minIndex ]: minIndex = j j += 1 if minIndex != i : # \u5982\u679c\u9700\u8981\uff0c\u5219\u4ea4\u6362\u5143\u7d20\u4f4d\u7f6e swap ( lyst , minIndex , i ) i += 1 def main (): myList = [ 9 , 4 , 2 , 7 , 6 , 8 , 1 ] print ( \"Before selection sort \" , myList ) selectionSort ( myList ) print ( \"After selection sort \" , myList ) if __name__ == \"__main__\" : main () # \u8fd0\u884c\u7ed3\u679c\uff1a # Before selection sort [9, 4, 2, 7, 6, 8, 1] # After selection sort [1, 2, 4, 6, 7, 8, 9] 3.4.2.\u5192\u6ce1\u6392\u5e8f \u00b6 \u5192\u6ce1\u6392\u5e8f\uff08Bubble Sort\uff09\uff1a \u6bd4\u8f83\u76f8\u90bb\u4e24\u4e2a\u6570\u636e\u5982\u679c\u3002\u7b2c\u4e00\u4e2a\u6bd4\u7b2c\u4e8c\u4e2a\u5927\uff0c\u5c31\u4ea4\u6362\u4e24\u4e2a\u6570\uff1b \u5bf9\u6bcf\u4e00\u4e2a\u76f8\u90bb\u7684\u6570\u505a\u540c\u68371\u7684\u5de5\u4f5c\uff0c\u8fd9\u6837\u4ece\u5f00\u59cb\u4e00\u961f\u5230\u7ed3\u5c3e\u4e00\u961f\u5728\u6700\u540e\u7684\u6570\u5c31\u662f\u6700\u5927\u7684\u6570\u3002 \u9488\u5bf9\u6240\u6709\u5143\u7d20\u4e0a\u9762\u7684\u64cd\u4f5c\uff0c\u9664\u4e86\u6700\u540e\u4e00\u4e2a\u3002 \u91cd\u590d1~3\u6b65\u9aa4\uff0c\u76f4\u81f3\u5b8c\u6210\u3002 \u7b97\u6cd5\u590d\u6742\u5ea6\uff1a \u5192\u6ce1\u6392\u5e8f\u53ea\u4f1a\u6539\u5584\u6700\u597d\u60c5\u51b5\u4e0b\u7684\u590d\u6742\u5ea6\u3002\u5bf9\u4e8e\u5e73\u5747\u60c5\u51b5\u800c\u8a00\uff0c\u7531\u4e8e\u4f9d\u7136\u662f\u53cc\u91cd\u5faa\u73af\u65f6\u95f4\uff0c\u6240\u4ee5\u590d\u6742\u5ea6\u662fO(n^2)\uff1b \u5bf9\u4e8e\u6709\u5e8f\u7684\u5217\u8868\u6765\u8bf4\uff0c\u4fee\u6539\u540e\u7684\u5192\u6ce1\u6392\u5e8f\u4f1a\u6bd4\u9009\u62e9\u6392\u5e8f\u7684\u6267\u884c\u6548\u7387\u66f4\u9ad8\u3002 \u7b97\u6cd5\u4ee3\u7801\uff1a def swap ( lyst , i , j ): \"\"\"\u4ea4\u6362\u5143\u7d20\u4f4d\u7f6e\u4e3ai\u548cj\u7684\u5143\u7d20\"\"\" temp = lyst [ i ] lyst [ i ] = lyst [ j ] lyst [ j ] = temp def selectionSort ( lyst ): \"\"\"\u5b9e\u73b0\u4ea4\u6362\u6392\u5e8f\u7b97\u6cd5\"\"\" i = 0 while i < len ( lyst ) - 1 : # \u5b9e\u73b0n-1\u6b21\u641c\u7d22 minIndex = i # \u6700\u5c0f\u5143\u7d20\u4f4d\u7f6e j = i + 1 while j < len ( lyst ): # \u5411\u540e\u904d\u5386\u641c\u7d22\uff0c\u66f4\u65b0\u6700\u5c0f\u5143\u7d20\u4f4d\u7f6e if lyst [ j ] < lyst [ minIndex ]: minIndex = j j += 1 if minIndex != i : # \u5982\u679c\u9700\u8981\uff0c\u5219\u4ea4\u6362\u5143\u7d20\u4f4d\u7f6e swap ( lyst , minIndex , i ) i += 1 def bubbleSortWithTweak ( lyst ): \"\"\"\u5b9e\u73b0\u5192\u6ce1\u6392\u5e8f\u7b97\u6cd5\"\"\" n = len ( lyst ) while n > 1 : swapped = False # \u7528\u5e03\u5c14\u6807\u5fd7\u6765\u8ffd\u8e2a\u6709\u6ca1\u6709\u53d1\u751f\u4ea4\u6362 i = 1 while i < n : if lyst [ i ] < lyst [ i - 1 ]: # \u5982\u679c\u540e\u9762\u5143\u7d20\u7684\u503c\u6bd4\u524d\u9762\u5143\u7d20\u7684\u5927\uff0c\u5219\u4ea4\u6362\u5143\u7d20\u4f4d\u7f6e\uff0c\u76f4\u81f3\u628a\u5faa\u73af\u4e2d\u7684\u6700\u5927\u5143\u7d20\u79fb\u5230\u6700\u540e swap ( lyst , i , i - 1 ) swapped = True i += 1 if not swapped : # \u5982\u679c\u4e0d\u9700\u8981\u4ea4\u6362\uff0c\u76f4\u63a5return return n -= 1 def main (): myList = [ 9 , 4 , 2 , 7 , 6 , 8 , 1 ] # \u6bd4\u8f83\u6392\u5e8f print ( \"Before selection sort \" , myList ) selectionSort ( myList ) print ( \"After selection sort \" , myList ) # \u5192\u6ce1\u6392\u5e8f myList = [ 9 , 4 , 2 , 7 , 6 , 8 , 1 ] print ( \"Before bubble sort \" , myList ) bubbleSortWithTweak ( myList ) print ( \"After bubble sort \" , myList ) if __name__ == \"__main__\" : main () # \u8fd0\u884c\u7ed3\u679c\uff1a # Before selection sort [9, 4, 2, 7, 6, 8, 1] # After selection sort [1, 2, 4, 6, 7, 8, 9] # Before bubble sort [9, 4, 2, 7, 6, 8, 1] # After bubble sort [1, 2, 4, 6, 7, 8, 9] 3.4.3.\u63d2\u5165\u6392\u5e8f \u00b6 \u63d2\u5165\u6392\u5e8f\uff08Insertion-Sort\uff09\u662f\u901a\u8fc7\u6784\u5efa\u6709\u5e8f\u5e8f\u5217\uff0c\u5bf9\u4e8e\u672a\u6392\u5e8f\u6570\u636e\uff0c\u5728\u5df2\u6392\u5e8f\u5e8f\u5217\u4e2d\u4ece\u540e\u5411\u524d\u626b\u63cf\uff0c\u627e\u5230\u76f8\u5e94\u4f4d\u7f6e\u5e76\u63d2\u5165\u3002\u63d2\u5165\u6392\u5e8f\u90fd\u91c7\u7528 in-place \u5728\u6570\u7ec4\u4e0a\u5b9e\u73b0\uff1a \u4ece\u7b2c\u4e00\u4e2a\u5143\u7d20\u5f00\u59cb\uff0c\u8be5\u5143\u7d20\u53ef\u4ee5\u8ba4\u4e3a\u5df2\u7ecf\u88ab\u6392\u5e8f\uff1b \u53d6\u51fa\u4e0b\u4e00\u4e2a\u5143\u7d20\uff0c\u5728\u5df2\u7ecf\u6392\u5e8f\u7684\u5143\u7d20\u5e8f\u5217\u4ece\u540e\u5411\u524d\u626b\u63cf\uff1b \u5982\u679c\u65b0\u5143\u7d20\u5c0f\u4e8e\u5df2\u6392\u5e8f\u7684\u5143\u7d20\uff0c\u5c06\u65b0\u5143\u7d20\u79fb\u5230\u4e0b\u4e00\u4f4d\u7f6e\uff1b \u91cd\u590d\u6b65\u9aa43\uff0c\u76f4\u5230\u627e\u5230\u5df2\u6392\u5e8f\u7684\u5143\u7d20\u5c0f\u4e8e\u6216\u8005\u7b49\u4e8e\u65b0\u5143\u7d20\u7684\u4f4d\u7f6e\uff1b \u5c06\u65b0\u5143\u7d20\u63d2\u5165\u5230\u8be5\u4f4d\u7f6e\u540e\uff1b \u91cd\u590d\u6b65\u9aa42~5\u3002 \u590d\u6742\u5ea6\uff1a \u548c\u9009\u62e9\u6392\u5e8f\u7c7b\u4f3c\uff0c\u904d\u5386\u6b21\u6570\u4e5f\u662f (1/2)*n^2+(1/2)*n \uff0c\u6240\u4ee5\u590d\u6742\u5ea6\u4e5f\u662fO(n^2)\u3002 \u5217\u8868\u91cc\u6709\u5e8f\u5143\u7d20\u8d8a\u591a\uff0c\u63d2\u5165\u6392\u5e8f\u7684\u6027\u80fd\u5c31\u4f1a\u8d8a\u597d\uff1b \u5728\u6709\u5e8f\u5217\u8868\u7684\u6700\u597d\u60c5\u51b5\u4e0b\uff0c\u6392\u5e8f\u590d\u6742\u5ea6\u662f\u7ebf\u6027\u7684\uff1b def swap ( lyst , i , j ): \"\"\"\u4ea4\u6362\u5143\u7d20\u4f4d\u7f6e\u4e3ai\u548cj\u7684\u5143\u7d20\"\"\" temp = lyst [ i ] lyst [ i ] = lyst [ j ] lyst [ j ] = temp def selectionSort ( lyst ): \"\"\"\u5b9e\u73b0\u4ea4\u6362\u6392\u5e8f\u7b97\u6cd5\"\"\" i = 0 while i < len ( lyst ) - 1 : # \u5b9e\u73b0n-1\u6b21\u641c\u7d22 minIndex = i # \u6700\u5c0f\u5143\u7d20\u4f4d\u7f6e j = i + 1 while j < len ( lyst ): # \u5411\u540e\u904d\u5386\u641c\u7d22\uff0c\u66f4\u65b0\u6700\u5c0f\u5143\u7d20\u4f4d\u7f6e if lyst [ j ] < lyst [ minIndex ]: minIndex = j j += 1 if minIndex != i : # \u5982\u679c\u9700\u8981\uff0c\u5219\u4ea4\u6362\u5143\u7d20\u4f4d\u7f6e swap ( lyst , minIndex , i ) i += 1 def bubbleSortWithTweak ( lyst ): \"\"\"\u5b9e\u73b0\u5192\u6ce1\u6392\u5e8f\u7b97\u6cd5\"\"\" n = len ( lyst ) while n > 1 : swapped = False # \u7528\u5e03\u5c14\u6807\u5fd7\u6765\u8ffd\u8e2a\u6709\u6ca1\u6709\u53d1\u751f\u4ea4\u6362 i = 1 while i < n : if lyst [ i ] < lyst [ i - 1 ]: # \u5982\u679c\u540e\u9762\u5143\u7d20\u7684\u503c\u6bd4\u524d\u9762\u5143\u7d20\u7684\u5927\uff0c\u5219\u4ea4\u6362\u5143\u7d20\u4f4d\u7f6e\uff0c\u76f4\u81f3\u628a\u5faa\u73af\u4e2d\u7684\u6700\u5927\u5143\u7d20\u79fb\u5230\u6700\u540e swap ( lyst , i , i - 1 ) swapped = True i += 1 if not swapped : # \u5982\u679c\u4e0d\u9700\u8981\u4ea4\u6362\uff0c\u76f4\u63a5return return n -= 1 def insertionSort ( lyst ): i = 1 # \u65b0\u5143\u7d20\u7684\u4f4d\u7f6e while i < len ( lyst ): itemToInsert = lyst [ i ] # \u65b0\u5143\u7d20 j = i - 1 # \u5df2\u6392\u5e8f\u7684\u5143\u7d20\u5e8f\u5217\u7684\u6700\u53f3\u4f4d\u7f6e while j >= 0 : if itemToInsert < lyst [ j ]: lyst [ j + 1 ] = lyst [ j ] # \u5982\u679c\u65b0\u5143\u7d20\u5c0f\u4e8e\u5df2\u6392\u5e8f\u5143\u7d20\uff0c\u5219\u5df2\u6392\u5e8f\u5143\u7d20\u5411\u540e\u79fb\u52a8\u4e00\u4e2a\u4f4d\u7f6e j -= 1 else : break # \u65b0\u5143\u7d20\u7b49\u4e8e\u6216\u8005\u5927\u4e8e\u5df2\u6392\u5e8f\u5143\u7d20\uff0c\u8df3\u51fa\u5faa\u73af\uff0c\u6b64\u65f6lyst[j + 1]\u662f\u548clyst[j]\u662f\u540c\u4e00\u4e2a\u5143\u7d20\u503c\uff0clyst[j + 1]\u4f4d\u7f6e\u662f\u7559\u7ed9\u65b0\u5143\u7d20\u7684 lyst [ j + 1 ] = itemToInsert # i += 1 def main (): myList = [ 9 , 4 , 2 , 7 , 6 , 8 , 1 ] # \u6bd4\u8f83\u6392\u5e8f print ( \"Before selection sort \" , myList ) selectionSort ( myList ) print ( \"After selection sort \" , myList ) # \u5192\u6ce1\u6392\u5e8f myList = [ 9 , 4 , 2 , 7 , 6 , 8 , 1 ] print ( \"Before bubble sort \" , myList ) bubbleSortWithTweak ( myList ) print ( \"After bubble sort \" , myList ) # \u63d2\u5165\u6392\u5e8f myList = [ 9 , 4 , 2 , 7 , 6 , 8 , 1 ] print ( \"Before insertion sort \" , myList ) insertionSort ( myList ) print ( \"After insertion sort \" , myList ) if __name__ == \"__main__\" : main () # \u8fd0\u884c\u7ed3\u679c\uff1a # Before selection sort [9, 4, 2, 7, 6, 8, 1] # After selection sort [1, 2, 4, 6, 7, 8, 9] # Before bubble sort [9, 4, 2, 7, 6, 8, 1] # After bubble sort [1, 2, 4, 6, 7, 8, 9] # Before insertion sort [9, 4, 2, 7, 6, 8, 1] # After insertion sort [1, 2, 4, 6, 7, 8, 9] 3.4.4.\u518d\u8bba\u6700\u597d\u60c5\u51b5\u3001\u6700\u574f\u60c5\u51b5\u4ee5\u53ca\u5e73\u5747\u60c5\u51b5\u4e0b\u7684\u6027\u80fd \u00b6 \u5bf9\u4e8e\u8bb8\u591a\u7b97\u6cd5\u6765\u8bf4\uff0c\u4e0d\u80fd\u5bf9\u6240\u6709\u60c5\u51b5\u91c7\u7528\u5355\u4e00\u7684\u590d\u6742\u5ea6\u6765\u8861\u91cf\u3002\u5f53\u9047\u5230\u7279\u5b9a\u987a\u5e8f\u7684\u6570\u636e\u65f6\uff0c\u7b97\u6cd5\u7684\u884c\u4e3a\u53ef\u80fd\u4f1a\u53d8\u5f97\u66f4\u597d\u6216\u66f4\u7cdf\u3002 \u5bf9\u7b97\u6cd5\u590d\u6742\u5ea6\u884c\u4e3a\u5206\u4e3a3\u79cd\u60c5\u51b5\uff1a \u6700\u597d\u60c5\u51b5\uff08best case\uff09\u2014\u2014\u7b97\u6cd5\u5728\u4ec0\u4e48\u60c5\u51b5\u4e0b\u53ef\u4ee5\u4ee5\u6700\u5c11\u7684\u5de5\u4f5c\u91cf\u5b8c\u6210\u5de5\u4f5c\uff1f\u5728\u6700\u597d\u60c5\u51b5\u4e0b\uff0c\u7b97\u6cd5\u7684\u590d\u6742\u5ea6\u662f\u591a\u5c11\uff1f \u6700\u574f\u60c5\u51b5\uff08worst case\uff09\u2014\u2014\u7b97\u6cd5\u5728\u4ec0\u4e48\u60c5\u51b5\u4e0b\u9700\u8981\u5b8c\u6210\u6700\u591a\u7684\u5de5\u4f5c\u91cf\uff1f\u5728\u6700\u574f\u60c5\u51b5\u4e0b\uff0c\u7b97\u6cd5\u7684\u590d\u6742\u5ea6\u662f\u591a\u5c11\uff1f \u5e73\u5747\u60c5\u51b5\uff08average case\uff09\u2014\u2014\u7b97\u6cd5\u5728\u4ec0\u4e48\u60c5\u51b5\u4e0b\u7528\u9002\u91cf\u7684\u5de5\u4f5c\u91cf\u5c31\u80fd\u5b8c\u6210\u5de5\u4f5c\uff1f\u5728\u5e73\u5747\u60c5\u51b5\u4e0b\uff0c\u7b97\u6cd5\u7684\u590d\u6742\u5ea6\u662f\u591a\u5c11\uff1f \u4e0b\u9762\u5206\u522b\u5bf9\u6700\u5c0f\u503c\u641c\u7d22\u3001\u987a\u5e8f\u641c\u7d22\u548c\u5192\u6ce1\u6392\u5e8f\u8fdb\u884c\u6700\u597d\u60c5\u51b5\u3001\u6700\u574f\u60c5\u51b5\u548c\u5e73\u5747\u60c5\u51b5\u4e0b\u7684\u6027\u80fd\u5206\u6790\uff0c\u4e0d\u8003\u8651\u5b9e\u9645\u786c\u4ef6\u548c\u7f16\u7a0b\u8bed\u8a00\u7b49\u7684\u5f71\u54cd\u3002 \u6700\u5c0f\u503c\u641c\u7d22\uff08Minimum Value Search\uff09 \u6700\u597d\u60c5\u51b5\uff1a\u6700\u5c0f\u503c\u521a\u597d\u5728\u7b2c\u4e00\u4e2a\u4f4d\u7f6e\u3002\u8fd9\u65f6\uff0c\u53ea\u9700\u8981\u4e00\u6b21\u6bd4\u8f83\u5c31\u53ef\u4ee5\u627e\u5230\u6700\u5c0f\u503c\uff0c\u65f6\u95f4\u590d\u6742\u5ea6\u4e3aO(1)\u3002 \u6700\u574f\u60c5\u51b5\uff1a\u6700\u5c0f\u503c\u5728\u6700\u540e\u4e00\u4e2a\u4f4d\u7f6e\u6216\u4e0d\u5b58\u5728\u3002\u8fd9\u65f6\uff0c\u9700\u8981\u8fdb\u884cn-1\u6b21\u6bd4\u8f83\u624d\u80fd\u786e\u5b9a\u6700\u5c0f\u503c\uff0c\u65f6\u95f4\u590d\u6742\u5ea6\u4e3aO(n)\u3002 \u5e73\u5747\u60c5\u51b5\uff1a\u5e73\u5747\u60c5\u51b5\u4e0b\uff0c\u6bcf\u4e2a\u5143\u7d20\u6709\u76f8\u7b49\u7684\u6982\u7387\u6210\u4e3a\u6700\u5c0f\u503c\u3002\u56e0\u6b64\uff0c\u5e73\u5747\u6bd4\u8f83\u6b21\u6570\u4e3a(n-1)/2\uff0c\u65f6\u95f4\u590d\u6742\u5ea6\u4e3aO(n)\u3002 \u987a\u5e8f\u641c\u7d22\uff08Sequential Search\uff09 \u6700\u597d\u60c5\u51b5\uff1a\u641c\u7d22\u7684\u5143\u7d20\u521a\u597d\u662f\u5217\u8868\u7684\u7b2c\u4e00\u4e2a\u5143\u7d20\u3002\u8fd9\u65f6\uff0c\u53ea\u9700\u8981\u4e00\u6b21\u6bd4\u8f83\u5c31\u53ef\u4ee5\u627e\u5230\u76ee\u6807\u5143\u7d20\uff0c\u65f6\u95f4\u590d\u6742\u5ea6\u4e3aO(1)\u3002 \u6700\u574f\u60c5\u51b5\uff1a\u641c\u7d22\u7684\u5143\u7d20\u5728\u5217\u8868\u7684\u6700\u540e\u4e00\u4e2a\u4f4d\u7f6e\u6216\u4e0d\u5b58\u5728\u3002\u8fd9\u65f6\uff0c\u9700\u8981\u8fdb\u884cn\u6b21\u6bd4\u8f83\u624d\u80fd\u786e\u5b9a\u76ee\u6807\u5143\u7d20\u4e0d\u5b58\u5728\uff0c\u65f6\u95f4\u590d\u6742\u5ea6\u4e3aO(n)\u3002 \u5e73\u5747\u60c5\u51b5\uff1a\u5e73\u5747\u60c5\u51b5\u4e0b\uff0c\u6bcf\u4e2a\u5143\u7d20\u6709\u76f8\u7b49\u7684\u6982\u7387\u6210\u4e3a\u76ee\u6807\u5143\u7d20\u3002\u56e0\u6b64\uff0c\u5e73\u5747\u6bd4\u8f83\u6b21\u6570\u4e3a (n+1)/2 \uff0c\u65f6\u95f4\u590d\u6742\u5ea6\u4e3aO(n)\u3002 \u5192\u6ce1\u6392\u5e8f\uff08Bubble Sort\uff09 \u6700\u597d\u60c5\u51b5\uff1a\u5982\u679c\u8f93\u5165\u5217\u8868\u5df2\u7ecf\u662f\u6709\u5e8f\u7684\uff0c\u5192\u6ce1\u6392\u5e8f\u53ea\u9700\u8981\u8fdb\u884c\u4e00\u6b21\u904d\u5386\u6765\u68c0\u6d4b\u5217\u8868\u5df2\u7ecf\u6709\u5e8f\uff0c\u65f6\u95f4\u590d\u6742\u5ea6\u4e3aO(n)\u3002\u4f46\u5b9e\u9645\u4e0a\uff0c\u901a\u5e38\u9700\u8981\u8fdb\u884c\u591a\u6b21\u904d\u5386\u6765\u5b8c\u6210\u6392\u5e8f\uff0c\u56e0\u6b64\u6700\u597d\u60c5\u51b5\u4e0b\u7684\u65f6\u95f4\u590d\u6742\u5ea6\u4ecd\u7136\u662fO(n^2)\u3002 \u6700\u574f\u60c5\u51b5\uff1a\u5982\u679c\u8f93\u5165\u5217\u8868\u662f\u9006\u5e8f\u7684\uff0c\u6bcf\u6b21\u904d\u5386\u90fd\u9700\u8981\u8fdb\u884cn-1\u6b21\u4ea4\u6362\uff0c\u603b\u5171\u9700\u8981\u8fdb\u884cn-1\u8f6e\u904d\u5386\uff0c\u65f6\u95f4\u590d\u6742\u5ea6\u4e3aO(n^2)\u3002 \u5e73\u5747\u60c5\u51b5\uff1a\u5e73\u5747\u60c5\u51b5\u4e0b\uff0c\u5192\u6ce1\u6392\u5e8f\u9700\u8981\u8fdb\u884c n(n-1)/2 \u6b21\u6bd4\u8f83\u548c\u4ea4\u6362\u64cd\u4f5c\uff0c\u65f6\u95f4\u590d\u6742\u5ea6\u4e3aO(n^2)\u3002 3.4.5.\u7ec3\u4e60\u9898 \u00b6 \u5217\u8868\u91cc\u5982\u4f55\u6392\u5217\u6570\u636e\u624d\u80fd\u8ba9\u9009\u62e9\u6392\u5e8f\u4e2d\u5143\u7d20\u4ea4\u6362\u7684\u6b21\u6570\u6700\u5c11\uff1f\u5982\u4f55\u6392\u5217\u6570\u636e\u624d\u80fd\u8ba9\u5b83\u6267\u884c\u6700\u591a\u7684\u4ea4\u6362\u6b21\u6570\uff1f \u89e3\u7b54\uff1a \u5728\u9009\u62e9\u6392\u5e8f\u4e2d\uff0c\u5143\u7d20\u7684\u4ea4\u6362\u6b21\u6570\u4e3b\u8981\u53d6\u51b3\u4e8e\u5f85\u6392\u5e8f\u5217\u8868\u7684\u521d\u59cb\u6392\u5217\uff1a \u6700\u5c0f\u5316\u4ea4\u6362\u6b21\u6570\uff1a \u8981\u6700\u5c0f\u5316\u9009\u62e9\u6392\u5e8f\u7684\u5143\u7d20\u4ea4\u6362\u6b21\u6570\uff0c\u53ef\u4ee5\u8ba9\u8f93\u5165\u5217\u8868\u5df2\u7ecf\u6309\u5347\u5e8f\u6392\u5217\u3002\u8fd9\u662f\u56e0\u4e3a\u5728\u5347\u5e8f\u6392\u5217\u7684\u60c5\u51b5\u4e0b\uff0c\u9009\u62e9\u6392\u5e8f\u6bcf\u6b21\u9009\u62e9\u6700\u5c0f\u7684\u5143\u7d20\u5e76\u5c06\u5176\u653e\u7f6e\u5728\u6b63\u786e\u7684\u4f4d\u7f6e\uff0c\u65e0\u9700\u4ea4\u6362\u3002\u56e0\u6b64\uff0c\u5143\u7d20\u4ea4\u6362\u7684\u6b21\u6570\u4e3a 0 \u3002 \u6700\u5927\u5316\u4ea4\u6362\u6b21\u6570\uff1a \u8981\u6700\u5927\u5316\u9009\u62e9\u6392\u5e8f\u7684\u5143\u7d20\u4ea4\u6362\u6b21\u6570\uff0c\u53ef\u4ee5\u8ba9\u8f93\u5165\u5217\u8868\u6309\u964d\u5e8f\u6392\u5217\u3002\u5728\u964d\u5e8f\u6392\u5217\u7684\u60c5\u51b5\u4e0b\uff0c\u9009\u62e9\u6392\u5e8f\u6bcf\u6b21\u9009\u62e9\u6700\u5927\u7684\u5143\u7d20\u5e76\u5c06\u5176\u653e\u7f6e\u5728\u6b63\u786e\u7684\u4f4d\u7f6e\uff0c\u8fd9\u5c06\u5bfc\u81f4\u5927\u91cf\u7684\u4ea4\u6362\u64cd\u4f5c\u3002\u5177\u4f53\u6765\u8bf4\uff0c\u5bf9\u4e8e\u957f\u5ea6\u4e3an\u7684\u5217\u8868\uff0c\u6700\u5927\u5316\u4ea4\u6362\u6b21\u6570\u7684\u60c5\u51b5\u4e0b\uff0c\u5c06\u6267\u884c n-1 \u6b21\u4ea4\u6362\u64cd\u4f5c\u3002 \u603b\u4e4b\uff0c\u8981\u6700\u5c0f\u5316\u9009\u62e9\u6392\u5e8f\u7684\u5143\u7d20\u4ea4\u6362\u6b21\u6570\uff0c\u8f93\u5165\u5217\u8868\u5e94\u8be5\u5df2\u7ecf\u6309\u5347\u5e8f\u6392\u5217\u3002\u8981\u6700\u5927\u5316\u4ea4\u6362\u6b21\u6570\uff0c\u8f93\u5165\u5217\u8868\u5e94\u8be5\u6309\u964d\u5e8f\u6392\u5217\u3002\u5728\u5b9e\u9645\u5e94\u7528\u4e2d\uff0c\u9009\u62e9\u6392\u5e8f\u901a\u5e38\u4e0d\u662f\u9996\u9009\u7684\u6392\u5e8f\u7b97\u6cd5\uff0c\u56e0\u4e3a\u5176\u4ea4\u6362\u6b21\u6570\u8f83\u591a\uff0c\u800c\u5176\u4ed6\u7b97\u6cd5\u5982\u5feb\u901f\u6392\u5e8f\u3001\u5f52\u5e76\u6392\u5e8f\u7b49\u5177\u6709\u66f4\u597d\u7684\u6027\u80fd\u3002 \u8bf7\u8bf4\u660e\u6570\u636e\u4ea4\u6362\u7684\u6b21\u6570\u5728\u5206\u6790\u9009\u62e9\u6392\u5e8f\u548c\u5192\u6ce1\u6392\u5e8f\u65f6\u6240\u8d77\u5230\u7684\u4f5c\u7528\u3002\u6570\u636e\u5bf9\u8c61\u7684\u89c4\u6a21\u5728\u5b83\u4eec\u4e4b\u95f4\u53d1\u6325\u7740\u4ec0\u4e48\u4f5c\u7528\uff08\u5982\u679c\u6709\u4f5c\u7528\uff09\uff1f \u89e3\u7b54\uff1a \u6570\u636e\u4ea4\u6362\u7684\u6b21\u6570\u5728\u5206\u6790\u9009\u62e9\u6392\u5e8f\u548c\u5192\u6ce1\u6392\u5e8f\u65f6\u8d77\u5230\u91cd\u8981\u4f5c\u7528\uff0c\u56e0\u4e3a\u5b83\u4eec\u76f4\u63a5\u5f71\u54cd\u5230\u6392\u5e8f\u7b97\u6cd5\u7684\u6027\u80fd\u548c\u6548\u7387\u3002 \u9009\u62e9\u6392\u5e8f\uff08Selection Sort\uff09\uff1a \u9009\u62e9\u6392\u5e8f\u7684\u6570\u636e\u4ea4\u6362\u6b21\u6570\u4e0e\u6570\u636e\u5bf9\u8c61\u7684\u89c4\u6a21\u76f4\u63a5\u76f8\u5173\u3002\u5728\u9009\u62e9\u6392\u5e8f\u4e2d\uff0c\u6bcf\u4e00\u8f6e\u90fd\u4f1a\u9009\u62e9\u672a\u6392\u5e8f\u90e8\u5206\u7684\u6700\u5c0f\u5143\u7d20\uff0c\u5e76\u5c06\u5176\u653e\u7f6e\u5728\u6b63\u786e\u7684\u4f4d\u7f6e\uff0c\u8fd9\u610f\u5473\u7740\u6bcf\u8f6e\u90fd\u9700\u8981\u4e00\u6b21\u4ea4\u6362\u64cd\u4f5c\u3002 \u9009\u62e9\u6392\u5e8f\u7684\u6570\u636e\u4ea4\u6362\u6b21\u6570\u662f\u4e0e\u8f93\u5165\u6570\u636e\u7684\u521d\u59cb\u6392\u5217\u65e0\u5173\u7684\uff0c\u56e0\u4e3a\u5b83\u603b\u662f\u4f1a\u6267\u884c\u76f8\u540c\u6570\u91cf\u7684\u4ea4\u6362\u64cd\u4f5c\uff0c\u65e0\u8bba\u6570\u636e\u662f\u5426\u6709\u5e8f\u3002 \u5bf9\u4e8e\u9009\u62e9\u6392\u5e8f\uff0c\u6570\u636e\u4ea4\u6362\u6b21\u6570\u4e3b\u8981\u53d7\u5230\u6570\u636e\u5bf9\u8c61\u7684\u89c4\u6a21\u5f71\u54cd\uff0c\u800c\u4e0d\u53d7\u6570\u636e\u7684\u5177\u4f53\u6392\u5217\u65b9\u5f0f\u7684\u5f71\u54cd\u3002\u65e0\u8bba\u6570\u636e\u7684\u6392\u5217\u5982\u4f55\uff0c\u9009\u62e9\u6392\u5e8f\u7684\u5e73\u5747\u548c\u6700\u574f\u60c5\u51b5\u4e0b\u7684\u6570\u636e\u4ea4\u6362\u6b21\u6570\u90fd\u662f\u76f8\u540c\u7684\uff0c\u5373 n-1 \u6b21\u3002 \u5192\u6ce1\u6392\u5e8f\uff08Bubble Sort\uff09\uff1a \u5192\u6ce1\u6392\u5e8f\u7684\u6570\u636e\u4ea4\u6362\u6b21\u6570\u4e5f\u4e0e\u6570\u636e\u5bf9\u8c61\u7684\u89c4\u6a21\u76f8\u5173\u3002\u5728\u5192\u6ce1\u6392\u5e8f\u4e2d\uff0c\u76f8\u90bb\u5143\u7d20\u9010\u4e00\u6bd4\u8f83\uff0c\u5982\u679c\u9006\u5e8f\u5c31\u4ea4\u6362\u4f4d\u7f6e\uff0c\u56e0\u6b64\u5192\u6ce1\u6392\u5e8f\u7684\u6570\u636e\u4ea4\u6362\u6b21\u6570\u4e0e\u9006\u5e8f\u5bf9\u7684\u6570\u91cf\u76f8\u5173\u3002 \u5192\u6ce1\u6392\u5e8f\u7684\u6570\u636e\u4ea4\u6362\u6b21\u6570\u5728\u4e0d\u540c\u7684\u6570\u636e\u6392\u5217\u60c5\u51b5\u4e0b\u53ef\u4ee5\u6709\u5f88\u5927\u5dee\u5f02\u3002\u5728\u6700\u597d\u60c5\u51b5\u4e0b\uff08\u8f93\u5165\u6570\u636e\u5df2\u7ecf\u6709\u5e8f\uff09\uff0c\u5192\u6ce1\u6392\u5e8f\u7684\u6570\u636e\u4ea4\u6362\u6b21\u6570\u4e3a 0 \u3002\u5728\u6700\u574f\u60c5\u51b5\u4e0b\uff08\u8f93\u5165\u6570\u636e\u5b8c\u5168\u9006\u5e8f\uff09\uff0c\u5192\u6ce1\u6392\u5e8f\u7684\u6570\u636e\u4ea4\u6362\u6b21\u6570\u662f\u6700\u5927\u7684\u3002 \u5192\u6ce1\u6392\u5e8f\u7684\u6570\u636e\u4ea4\u6362\u6b21\u6570\u65e2\u53d7\u5230\u6570\u636e\u5bf9\u8c61\u7684\u89c4\u6a21\u5f71\u54cd\uff0c\u53c8\u53d7\u5230\u6570\u636e\u7684\u6392\u5217\u65b9\u5f0f\u7684\u5f71\u54cd\u3002\u6700\u597d\u60c5\u51b5\u4e0b\u7684\u4ea4\u6362\u6b21\u6570\u4e3a 0 \uff0c\u6700\u574f\u60c5\u51b5\u4e0b\u7684\u4ea4\u6362\u6b21\u6570\u4e3a n*(n-1)/2 \uff0c\u5e73\u5747\u60c5\u51b5\u4e0b\u7684\u4ea4\u6362\u6b21\u6570\u53d6\u51b3\u4e8e\u6570\u636e\u6392\u5217\u7684\u968f\u673a\u6027\u3002 \u7efc\u4e0a\u6240\u8ff0\uff0c\u6570\u636e\u4ea4\u6362\u7684\u6b21\u6570\u5728\u9009\u62e9\u6392\u5e8f\u548c\u5192\u6ce1\u6392\u5e8f\u7684\u5206\u6790\u4e2d\u662f\u91cd\u8981\u7684\u6027\u80fd\u6307\u6807\u3002\u9009\u62e9\u6392\u5e8f\u7684\u4ea4\u6362\u6b21\u6570\u4e0e\u6570\u636e\u89c4\u6a21\u76f8\u5173\uff0c\u800c\u5192\u6ce1\u6392\u5e8f\u7684\u4ea4\u6362\u6b21\u6570\u65e2\u4e0e\u6570\u636e\u89c4\u6a21\u76f8\u5173\uff0c\u53c8\u53d7\u5230\u6570\u636e\u6392\u5217\u65b9\u5f0f\u7684\u5f71\u54cd\u3002\u5728\u5927\u89c4\u6a21\u6570\u636e\u96c6\u4e0a\uff0c\u5192\u6ce1\u6392\u5e8f\u901a\u5e38\u6bd4\u9009\u62e9\u6392\u5e8f\u66f4\u6162\uff0c\u56e0\u4e3a\u5b83\u7684\u4ea4\u6362\u64cd\u4f5c\u66f4\u591a\u3002\u56e0\u6b64\uff0c\u5728\u5b9e\u9645\u5e94\u7528\u4e2d\uff0c\u901a\u5e38\u9009\u62e9\u6392\u5e8f\u6bd4\u5192\u6ce1\u6392\u5e8f\u66f4\u6709\u6548\u3002\u4f46\u4e24\u8005\u90fd\u4e0d\u662f\u9996\u9009\u7684\u6392\u5e8f\u7b97\u6cd5\uff0c\u66f4\u9ad8\u6548\u7684\u6392\u5e8f\u7b97\u6cd5\u5982\u5feb\u901f\u6392\u5e8f\u3001\u5f52\u5e76\u6392\u5e8f\u7b49\u901a\u5e38\u88ab\u4f18\u5148\u8003\u8651\u3002 \u8bf7\u8bf4\u660e\u4e3a\u4ec0\u4e48\u4fee\u6539\u540e\u7684\u5192\u6ce1\u6392\u5e8f\u5728\u5e73\u5747\u60c5\u51b5\u4e0b\u6027\u80fd\u4ecd\u7136\u4e3aO(n^2)\u3002 \u89e3\u7b54\uff1a \u4fee\u6539\u540e\u7684\u5192\u6ce1\u6392\u5e8f\u5728\u5e73\u5747\u60c5\u51b5\u4e0b\u6027\u80fd\u4ecd\u7136\u4e3aO(n^2)\uff0c\u539f\u56e0\u5982\u4e0b\uff1a \u5192\u6ce1\u6392\u5e8f\u7684\u57fa\u672c\u64cd\u4f5c\u662f\u6bd4\u8f83\u76f8\u90bb\u5143\u7d20\u5e76\u4ea4\u6362\u5b83\u4eec\uff0c\u76f4\u5230\u6574\u4e2a\u5217\u8868\u6309\u7167\u5347\u5e8f\u6392\u5217\u3002\u5728\u4fee\u6539\u540e\u7684\u5192\u6ce1\u6392\u5e8f\u4e2d\uff0c\u5f53\u4e24\u4e2a\u76f8\u90bb\u5143\u7d20\u9006\u5e8f\u65f6\uff0c\u4f1a\u53d1\u751f\u4ea4\u6362\u3002\u8fd9\u4e2a\u57fa\u672c\u64cd\u4f5c\u7684\u590d\u6742\u5ea6\u662fO(1)\uff0c\u56e0\u4e3a\u5b83\u53ea\u6d89\u53ca\u4e24\u4e2a\u5143\u7d20\u7684\u6bd4\u8f83\u548c\u53ef\u80fd\u7684\u4ea4\u6362\u3002 \u4fee\u6539\u540e\u7684\u5192\u6ce1\u6392\u5e8f\u5728\u6bcf\u4e00\u8f6e\u904d\u5386\u4e2d\uff0c\u4ecd\u7136\u9700\u8981\u68c0\u67e5\u76f8\u90bb\u5143\u7d20\u7684\u6bd4\u8f83\uff0c\u5373\u4f7f\u5728\u6709\u5e8f\u90e8\u5206\uff0c\u5b83\u4ecd\u7136\u9700\u8981\u8fdb\u884c\u6bd4\u8f83\u3002\u5728\u6700\u574f\u60c5\u51b5\u4e0b\uff0c\u5b83\u4f1a\u6267\u884cn-1\u6b21\u904d\u5386\uff0c\u6bcf\u6b21\u90fd\u8981\u6bd4\u8f83\u76f8\u90bb\u5143\u7d20\u3002 \u5192\u6ce1\u6392\u5e8f\u7684\u5e73\u5747\u65f6\u95f4\u590d\u6742\u5ea6\u662fO(n^2)\uff0c\u8fd9\u662f\u56e0\u4e3a\u5b83\u4e0d\u4f1a\u5229\u7528\u8f93\u5165\u6570\u636e\u7684\u4efb\u4f55\u6709\u5e8f\u6027\u3002\u65e0\u8bba\u8f93\u5165\u6570\u636e\u662f\u6709\u5e8f\u7684\u3001\u9006\u5e8f\u7684\uff0c\u8fd8\u662f\u968f\u673a\u6392\u5217\u7684\uff0c\u90fd\u9700\u8981\u6267\u884c\u76f8\u540c\u6570\u91cf\u7684\u6bd4\u8f83\u548c\u4ea4\u6362\u64cd\u4f5c\u3002 \u603b\u4e4b\uff0c\u4fee\u6539\u540e\u7684\u5192\u6ce1\u6392\u5e8f\u867d\u7136\u51cf\u5c11\u4e86\u6570\u636e\u4ea4\u6362\u7684\u6b21\u6570\uff0c\u4f46\u5728\u5e73\u5747\u60c5\u51b5\u4e0b\u4ecd\u7136\u9700\u8981\u6267\u884c\u5927\u7ea6 n(n-1)/2 \u6b21\u6bd4\u8f83\u64cd\u4f5c\uff0c\u56e0\u6b64\u5b83\u7684\u5e73\u5747\u65f6\u95f4\u590d\u6742\u5ea6\u4ecd\u7136\u662fO(n^2)\u3002\u5192\u6ce1\u6392\u5e8f\u7684\u6027\u80fd\u4e3b\u8981\u53d7\u5230\u6570\u636e\u89c4\u6a21\u7684\u5f71\u54cd\uff0c\u800c\u4e0d\u592a\u53d7\u5230\u5177\u4f53\u6570\u636e\u6392\u5217\u65b9\u5f0f\u7684\u5f71\u54cd\u3002\u56e0\u6b64\uff0c\u5b83\u5728\u5e73\u5747\u60c5\u51b5\u4e0b\u4ecd\u7136\u5177\u6709\u4e8c\u6b21\u65f6\u95f4\u590d\u6742\u5ea6\u3002 \u8bf7\u8bf4\u660e\u4e3a\u4ec0\u4e48\u63d2\u5165\u6392\u5e8f\u5728\u90e8\u5206\u6709\u5e8f\u7684\u5217\u8868\u4e0a\u80fd\u591f\u5f88\u597d\u5730\u5de5\u4f5c\u3002 \u89e3\u7b54\uff1a \u63d2\u5165\u6392\u5e8f\u4e4b\u6240\u4ee5\u80fd\u591f\u5728\u90e8\u5206\u6709\u5e8f\u7684\u5217\u8868\u4e0a\u5f88\u597d\u5730\u5de5\u4f5c\uff0c\u662f\u56e0\u4e3a\u5b83\u7684\u6838\u5fc3\u601d\u60f3\u662f\u9010\u6b65\u6784\u5efa\u6709\u5e8f\u7684\u5b50\u5217\u8868\uff0c\u800c\u4e0d\u662f\u50cf\u9009\u62e9\u6392\u5e8f\u6216\u5192\u6ce1\u6392\u5e8f\u4e00\u6837\u603b\u662f\u8003\u8651\u6574\u4e2a\u5217\u8868\u3002\u8fd9\u4f7f\u5f97\u63d2\u5165\u6392\u5e8f\u5728\u5904\u7406\u90e8\u5206\u6709\u5e8f\u7684\u5217\u8868\u65f6\u5177\u6709\u4e00\u4e9b\u4f18\u52bf\uff1a \u5c40\u90e8\u6027\u539f\u7406\uff1a\u63d2\u5165\u6392\u5e8f\u5229\u7528\u4e86\u5c40\u90e8\u6027\u539f\u7406\uff0c\u5373\u5728\u5927\u591a\u6570\u60c5\u51b5\u4e0b\uff0c\u6570\u636e\u9879\u7684\u6b63\u786e\u4f4d\u7f6e\u79bb\u5b83\u4eec\u5f53\u524d\u7684\u4f4d\u7f6e\u5f88\u8fd1\u3002\u5728\u90e8\u5206\u6709\u5e8f\u7684\u5217\u8868\u4e2d\uff0c\u5927\u591a\u6570\u6570\u636e\u9879\u5df2\u7ecf\u63a5\u8fd1\u4e8e\u5b83\u4eec\u7684\u6700\u7ec8\u4f4d\u7f6e\uff0c\u56e0\u6b64\u53ea\u9700\u8981\u8fdb\u884c\u5c11\u91cf\u7684\u79fb\u52a8\u64cd\u4f5c\u3002 \u9002\u5e94\u6027\uff1a\u63d2\u5165\u6392\u5e8f\u662f\u4e00\u79cd\u81ea\u9002\u5e94\u6392\u5e8f\u7b97\u6cd5\uff0c\u5b83\u53ef\u4ee5\u6839\u636e\u8f93\u5165\u6570\u636e\u7684\u6709\u5e8f\u6027\u8fdb\u884c\u81ea\u52a8\u8c03\u6574\u3002\u5728\u5904\u7406\u90e8\u5206\u6709\u5e8f\u7684\u5217\u8868\u65f6\uff0c\u63d2\u5165\u6392\u5e8f\u7684\u6027\u80fd\u4f1a\u66f4\u597d\uff0c\u56e0\u4e3a\u4e0d\u9700\u8981\u6267\u884c\u592a\u591a\u7684\u6bd4\u8f83\u548c\u4ea4\u6362\u64cd\u4f5c\u3002 \u7b80\u5355\u6027\uff1a\u63d2\u5165\u6392\u5e8f\u7684\u5b9e\u73b0\u975e\u5e38\u7b80\u5355\u76f4\u89c2\uff0c\u5b83\u53ea\u6d89\u53ca\u5230\u9010\u4e2a\u63d2\u5165\u5143\u7d20\u5230\u6b63\u786e\u7684\u4f4d\u7f6e\u3002\u8fd9\u79cd\u7b80\u5355\u6027\u4f7f\u5f97\u63d2\u5165\u6392\u5e8f\u5728\u67d0\u4e9b\u60c5\u51b5\u4e0b\u6bd4\u66f4\u590d\u6742\u7684\u6392\u5e8f\u7b97\u6cd5\u66f4\u5177\u7ade\u4e89\u529b\u3002 \u867d\u7136\u63d2\u5165\u6392\u5e8f\u5728\u90e8\u5206\u6709\u5e8f\u7684\u5217\u8868\u4e0a\u8868\u73b0\u826f\u597d\uff0c\u4f46\u5728\u5904\u7406\u5927\u89c4\u6a21\u4e71\u5e8f\u6570\u636e\u96c6\u65f6\uff0c\u5b83\u7684\u6027\u80fd\u4e0d\u5982\u5feb\u901f\u6392\u5e8f\u3001\u5f52\u5e76\u6392\u5e8f\u7b49\u66f4\u9ad8\u7ea7\u7684\u6392\u5e8f\u7b97\u6cd5\u3002\u56e0\u6b64\uff0c\u5728\u5b9e\u9645\u5e94\u7528\u4e2d\uff0c\u6839\u636e\u6570\u636e\u7684\u6027\u8d28\u9009\u62e9\u9002\u5f53\u7684\u6392\u5e8f\u7b97\u6cd5\u662f\u91cd\u8981\u7684\u3002\u63d2\u5165\u6392\u5e8f\u901a\u5e38\u9002\u7528\u4e8e\u5c0f\u89c4\u6a21\u6570\u636e\u6216\u8005\u5df2\u7ecf\u90e8\u5206\u6709\u5e8f\u7684\u6570\u636e\uff0c\u800c\u4e0d\u662f\u5927\u89c4\u6a21\u4e71\u5e8f\u6570\u636e\u7684\u6392\u5e8f\u3002 3.5.\u66f4\u5feb\u7684\u6392\u5e8f \u00b6 \u5206\u6cbb\u6cd5\uff08divide-and-conquer\uff09\u7b56\u7565\uff1a\u628a\u5217\u8868\u5206\u6210\u66f4\u5c0f\u7684\u5b50\u5217\u8868\uff0c\u7136\u540e\u518d\u901a\u8fc7\u9012\u5f52\u628a\u8fd9\u4e9b\u5b50\u5217\u8868\u6392\u5e8f\u3002 \u7406\u60f3\u60c5\u51b5\u4e0b\uff0c\u5982\u679c\u8fd9\u4e9b\u88ab\u62c6\u5206\u7684\u5b50\u5217\u8868\u7684\u6570\u91cf\u662f logn \uff0c\u800c\u628a\u6bcf\u4e2a\u5b50\u5217\u8868\u8fdb\u884c\u5408\u5e76\u6240\u9700\u7684\u5de5\u4f5c\u91cf\u4e3a n \uff0c\u90a3\u4e48\u8fd9\u79cd\u6392\u5e8f\u7b97\u6cd5\u7684\u603b\u590d\u6742\u5ea6\u5c31\u662f O(nlogn) \uff0c\u76f8\u6bd4 O(n^2) \u7684\u5de5\u4f5c\u91cf\u589e\u957f\u8981\u4f4e\u5f88\u591a\u3002 3.5.1.\u5feb\u901f\u6392\u5e8f \u00b6 \u5feb\u901f\u6392\u5e8f\uff08QuickSort\uff09\u662f\u6392\u9664\u7a33\u5b9a\u6027\u56e0\u7d20\u540e\u6700\u5e38\u7528\u7684\u6392\u5e8f\u3002 \u9996\u5148\u4ece\u5217\u8868\u7684\u4e2d\u95f4\u4f4d\u7f6e\u9009\u62e9\u4e00\u4e2a\u5143\u7d20\uff0c\u8fd9\u4e2a\u5143\u7d20\u88ab\u79f0\u4e3a\u57fa\u51c6\uff08pivot\uff09\uff1b \u5bf9\u5217\u8868\u91cc\u7684\u5143\u7d20\u8fdb\u884c\u5206\u5272\uff0c\u628a\u5c0f\u4e8e\u57fa\u51c6\u7684\u6240\u6709\u5143\u7d20\u79fb\u52a8\u5230\u57fa\u51c6\u7684\u5de6\u4fa7\uff0c\u800c\u628a\u5176\u4f59\u5143\u7d20\u90fd\u79fb\u5230\u57fa\u51c6\u7684\u53f3\u4fa7\u3002 \u5982\u679c\u57fa\u51c6\u6b63\u597d\u662f\u6700\u5927\u7684\u5143\u7d20\uff0c\u90a3\u4e48\u5b83\u6700\u7ec8\u4f1a\u5904\u4e8e\u5217\u8868\u7684\u6700\u53f3\u4fa7\uff1b \u5982\u679c\u57fa\u51c6\u6b63\u597d\u662f\u6700\u5c0f\u7684\u5143\u7d20\uff0c\u90a3\u4e48\u5b83\u5c31\u4f1a\u5728\u6700\u5de6\u4fa7\uff1b \u5206\u6cbb\u6cd5\u3002\u5c06\u8fd9\u4e2a\u8fc7\u7a0b\u9012\u5f52\u5730\u5e94\u7528\u5230\u901a\u8fc7\u57fa\u51c6\u800c\u628a\u539f\u5217\u8868\u5206\u5272\u7684\u5b50\u5217\u8868\u4e0a\uff0c\u5176\u4e2d\uff1a \u4e00\u4e2a\u65b0\u7684\u5b50\u5217\u8868\u7531\u57fa\u51c6\u5de6\u4fa7\u7684\u6240\u6709\u5143\u7d20\uff08\u8f83\u5c0f\u7684\u5143\u7d20\uff09\u7ec4\u6210\uff0c \u53e6\u4e00\u4e2a\u65b0\u7684\u5b50\u5217\u8868\u7531\u57fa\u51c6\u53f3\u4fa7\u7684\u6240\u6709\u5143\u7d20\uff08\u8f83\u5927\u7684\u5143\u7d20\uff09\u7ec4\u6210\uff1b \u5f53\u5206\u51fa\u7684\u5b50\u5217\u8868\u5185\u5c11\u4e8e\u4e24\u4e2a\u5143\u7d20\u65f6\uff0c\u8fd9\u4e2a\u8fc7\u7a0b\u7ec8\u6b62\uff1b 3.5.1.1.\u5206\u5272 \u00b6 \u8fd9\u4e2a\u7b97\u6cd5\u91cc\u6700\u590d\u6742\u7684\u90e8\u5206\u662f\u5bf9\u5143\u7d20\u8fdb\u884c\u5206\u5272\u4ece\u800c\u5f97\u5230\u5b50\u5217\u8868\u7684\u64cd\u4f5c\u3002 \u5c06\u57fa\u51c6\u4e0e\u5b50\u5217\u8868\u91cc\u7684\u6700\u540e\u4e00\u4e2a\u5143\u7d20\u8fdb\u884c\u4ea4\u6362\u3002 \u5728\u5df2\u77e5\u5c0f\u4e8e\u57fa\u51c6\u7684\u5143\u7d20\u548c\u5176\u4ed6\u5143\u7d20\u4e4b\u95f4\u6784\u5efa\u4e00\u4e2a\u8fb9\u754c\u3002\u4e00\u5f00\u59cb\uff0c\u8fd9\u4e2a\u8fb9\u754c\u4f1a\u5904\u4e8e\u7b2c\u4e00\u4e2a\u5143\u7d20\u4e4b\u524d\u3002 \u4ece\u5b50\u5217\u8868\u8fb9\u754c\u4e4b\u540e\u7684\u7b2c\u4e00\u4e2a\u5143\u7d20\u5f00\u59cb\u5411\u53f3\u626b\u63cf\u3002\u5f53\u6bcf\u6b21\u9047\u5230\u5c0f\u4e8e\u57fa\u51c6\u7684\u5143\u7d20\u65f6\uff0c\u5c06\u5b83\u548c\u8fb9\u754c\u4e4b\u540e\u7684\u7b2c\u4e00\u4e2a\u5143\u7d20\u8fdb\u884c\u4ea4\u6362\uff0c\u5e76\u4e14\u5c06\u8fb9\u754c\u5411\u53f3\u79fb\u52a8\u3002 \u5728\u7ed3\u675f\u7684\u65f6\u5019\uff0c\u5c06\u57fa\u51c6\u548c\u8fb9\u754c\u4e4b\u540e\u7684\u7b2c\u4e00\u4e2a\u5143\u7d20\u8fdb\u884c\u4ea4\u6362\u3002 \u793a\u4f8b\u5217\u8868\uff1a[12,19,17,18,14,11,15,13,16]\uff0c\u4e0b\u56fe\u5c55\u793a\u4e86\u5206\u5272\u7684\u6bcf\u4e00\u6b65\u8fc7\u7a0b\u3002 3.5.1.2.\u5feb\u901f\u6392\u5e8f\u590d\u6742\u5ea6\u5206\u6790 \u00b6 \u5feb\u901f\u6392\u5e8f\uff08Quick Sort\uff09\u662f\u4e00\u79cd\u9ad8\u6548\u7684\u6392\u5e8f\u7b97\u6cd5\uff0c\u5176\u5e73\u5747\u548c\u6700\u574f\u65f6\u95f4\u590d\u6742\u5ea6\u90fd\u662f O(n log n) \u3002\u4e0b\u9762\u662f\u5feb\u901f\u6392\u5e8f\u7684\u590d\u6742\u5ea6\u5206\u6790\uff1a \u5728\u7b2c\u4e00\u6b21\u8fdb\u884c\u5206\u5272\u64cd\u4f5c\u65f6\uff0c\u6211\u4eec\u5c06\u626b\u63cf\u5217\u8868\u91cc\u4ece\u5f00\u5934\u5230\u7ed3\u5c3e\u7684\u6240\u6709\u5143\u7d20\u3002\u56e0\u6b64\uff0c\u5728\u8fd9\u4e2a\u64cd\u4f5c\u671f\u95f4\u5de5\u4f5c\u91cf\u662f\u548c\u5217\u8868\u7684\u957f\u5ea6 n \u6210\u6b63\u6bd4\u7684\u3002\u8fd9\u6b21\u5206\u5272\u4e4b\u540e\u7684\u5de5\u4f5c\u91cf\u4f1a\u548c\u5de6\u5b50\u5217\u8868\u52a0\u4e0a\u53f3\u5b50\u5217\u8868\u7684\u603b\u957f\u5ea6\u6210\u6b63\u6bd4\uff0c\u4e5f\u5c31\u662f n-1 \u3002 \u518d\u6b21\u5bf9\u8fd9\u4e24\u4e2a\u5b50\u5217\u8868\u8fdb\u884c\u5206\u5272\u4e4b\u540e\uff0c\u5c31\u4f1a\u4ea7\u751f4\u4e2a\u52a0\u8d77\u6765\u603b\u957f\u5ea6\u5927\u7ea6\u4e3a n \u7684\u5217\u8868\u6bb5\u3002\u56e0\u6b64\uff0c\u5bf9\u5b83\u4eec\u8fdb\u884c\u5206\u5272\u7684\u603b\u5de5\u4f5c\u91cf\u8fd8\u662f\u548c n \u6210\u6b63\u6bd4\u7684\u3002\u968f\u7740\u5217\u8868\u88ab\u5206\u5272\u6210\u66f4\u591a\u6bb5\uff0c\u603b\u5de5\u4f5c\u91cf\u4f1a\u4e00\u76f4\u548c n \u6210\u6b63\u6bd4\u3002 \u8981\u5b8c\u6210\u6574\u4e2a\u5206\u6790\uff0c\u8fd8\u9700\u8981\u786e\u5b9a\u5217\u8868\u88ab\u5206\u5272\u4e86\u591a\u5c11\u6b21\u3002\u6309\u7167\u6700\u4e50\u89c2\u7684\u60c5\u51b5\u6765\u8bf4\uff08\u867d\u7136\u5728\u5b9e\u9645\u64cd\u4f5c\u7684\u65f6\u5019\uff0c\u901a\u5e38\u5e76\u4e0d\u4f1a\u51fa\u73b0\u8fd9\u4e48\u597d\u7684\u60c5\u51b5\uff09\uff0c\u5047\u8bbe\u6bcf\u6b21\u65b0\u5b50\u5217\u8868\u4e4b\u95f4\u7684\u5206\u754c\u7ebf\u90fd\u5c3d\u53ef\u80fd\u5730\u9760\u8fd1\u5f53\u524d\u5217\u8868\u7684\u4e2d\u5fc3\uff0c\u901a\u5e38\u8fd9\u79cd\u60c5\u51b5\u5e76\u4e0d\u5e38\u89c1\u3002\u4ece\u4e8c\u5206\u641c\u7d22\u7b97\u6cd5\u7684\u8ba8\u8bba\u91cc\u53ef\u77e5\uff0c\u8981\u628a\u5217\u8868\u4e0d\u65ad\u5730\u5206\u6210\u4e24\u534a\uff0c\u5927\u7ea6\u5728 log n \u6b65\u7684\u65f6\u5019\u5c31\u53ea\u5269\u4e0b\u4e00\u4e2a\u5143\u7d20\u4e86\u3002 \u56e0\u6b64\uff0c\u8fd9\u4e2a\u7b97\u6cd5\u5728\u6700\u597d\u60c5\u51b5\u4e0b\u7684\u6027\u80fd\u4e3a O(n log n) \u3002\u5728\u6700\u574f\u60c5\u51b5\u4e0b\uff0c\u6211\u4eec\u6765\u8003\u8651\u6709\u5e8f\u5217\u8868\u7684\u60c5\u51b5\u3002\u5982\u679c\u9009\u62e9\u7684\u57fa\u51c6\u5143\u7d20\u662f\u7b2c\u4e00\u4e2a\u5143\u7d20\uff0c\u90a3\u4e48\u5728\u7b2c\u4e00\u6b21\u5206\u5272\u4e4b\u540e\u5b83\u7684\u53f3\u8fb9\u4f1a\u6709 n-1 \u4e2a\u5143\u7d20\uff0c\u5728\u7b2c\u4e8c\u6b21\u5206\u5272\u4e4b\u540e\u5b83\u7684\u53f3\u8fb9\u6709 n-2 \u4e2a\u5143\u7d20\uff0c\u4ee5\u6b64\u7c7b\u63a8\uff0c \u5c3d\u7ba1\u6574\u4e2a\u64cd\u4f5c\u91cc\u6ca1\u6709\u4ea4\u6362\u4efb\u4f55\u5143\u7d20\uff0c\u4f46\u5206\u5272\u603b\u5171\u4e5f\u6267\u884c\u4e86 n-1 \u6b21\uff0c\u4e8e\u662f\u6267\u884c\u7684\u6bd4\u8f83\u603b\u6570\u5c31\u662f n^2/2-n/2 \u3002\u8fd9\u4e0e\u9009\u62e9\u6392\u5e8f\u4ee5\u53ca\u5192\u6ce1\u6392\u5e8f\u7684\u60c5\u51b5\u662f\u4e00\u6837\u7684\u3002\u56e0\u6b64\uff0c\u5728\u6700\u574f\u60c5\u51b5\u4e0b\uff0c\u5feb\u901f\u6392\u5e8f\u7b97\u6cd5\u7684\u6027\u80fd\u4e3a O(n^2) \u3002\u5982\u679c\u628a\u5feb\u901f\u6392\u5e8f\u5b9e\u73b0\u6210\u9012\u5f52\u7b97\u6cd5\uff0c\u90a3\u4e48\u5728\u5bf9\u5b83\u8fdb\u884c\u5206\u6790\u65f6\u8fd8\u5fc5\u987b\u8981\u8003\u8651\u8c03\u7528\u6808\u7684\u5185\u5b58\u4f7f\u7528\u60c5\u51b5\u3002\u7531\u4e8e\u5bf9\u4e8e\u6808\u7684\u4e00\u5e27\uff0c\u6bcf\u6b21\u9012\u5f52\u8c03\u7528\u90fd\u9700\u8981\u56fa\u5b9a\u7684\u5185\u5b58\uff0c\u5e76\u4e14\u6bcf\u6b21\u5206\u5272\u4e4b\u540e\u90fd\u4f1a\u6709\u4e24\u6b21\u9012\u5f52\u8c03\u7528\u3002\u56e0\u6b64\uff0c\u5728\u6700\u597d\u60c5\u51b5\u4e0b\u5185\u5b58\u7684\u4f7f\u7528\u91cf\u4f1a\u662f O(log n) \uff0c\u800c\u6700\u574f\u60c5\u51b5\u4e0b\u7684\u5185\u5b58\u4f7f\u7528\u91cf\u662f O(n) \u3002 \u5c3d\u7ba1\u5feb\u901f\u6392\u5e8f\u5904\u4e8e\u6700\u574f\u60c5\u51b5\u4e0b\u7684\u53ef\u80fd\u6027\u5f88\u5c0f\uff0c\u6211\u4eec\u8fd8\u662f\u4f1a\u52aa\u529b\u5730\u53bb\u907f\u514d\u8fd9\u79cd\u60c5\u51b5\uff0c\u56e0\u6b64\uff0c\u5b83\u4eec\u5e76\u4e0d\u4f1a\u5728\u7b2c\u4e00\u4e2a\u6216\u6700\u540e\u4e00\u4e2a\u4f4d\u7f6e\u9009\u62e9\u57fa\u51c6\u5143\u7d20\u3002\u6709\u5176\u4ed6\u4e00\u4e9b\u9009\u62e9\u57fa\u51c6\u7684\u65b9\u6cd5\u53ef\u4ee5\u8ba9\u8fd9\u4e2a\u7b97\u6cd5\u5728\u5e73\u5747\u60c5\u51b5\u4e0b\u6709\u5927\u7ea6 O(n log n) \u7684\u6027\u80fd\uff0c\u6bd4\u5982\uff0c\u53ef\u4ee5\u9009\u62e9\u968f\u673a\u4f4d\u7f6e\u4e0a\u7684\u5143\u7d20\u4f5c\u4e3a\u57fa\u51c6\uff0c\u6216\u8005\u9009\u62e9\u6574\u4e2a\u5217\u8868\u91cc\u7b2c\u4e00\u4e2a\u4f4d\u7f6e\u3001\u4e2d\u95f4\u4f4d\u7f6e\u4ee5\u53ca\u6700\u540e\u4e00\u4e2a\u4f4d\u7f6e\u8fd93\u4e2a\u5143\u7d20\u7684\u4e2d\u4f4d\u6570\u3002 \u603b\u7ed3\uff1a \u6700\u597d\u60c5\u51b5\u65f6\u95f4\u590d\u6742\u5ea6\uff1a\u5728\u6700\u597d\u60c5\u51b5\u4e0b\uff0c\u4e5f\u5c31\u662f\u6bcf\u6b21\u9009\u62e9\u7684\u57fa\u51c6\u5143\u7d20\u90fd\u521a\u597d\u5c06\u8f93\u5165\u6570\u636e\u5206\u6210\u4e24\u4e2a\u7b49\u957f\u7684\u5b50\u6570\u7ec4\uff0c\u5feb\u901f\u6392\u5e8f\u7684\u65f6\u95f4\u590d\u6742\u5ea6\u662f O(n log n) \u3002\u8fd9\u79cd\u60c5\u51b5\u901a\u5e38\u53d1\u751f\u5728\u57fa\u51c6\u5143\u7d20\u7684\u9009\u62e9\u975e\u5e38\u5408\u7406\u7684\u60c5\u51b5\u4e0b\uff0c\u4f8b\u5982\u5728\u6bcf\u6b21\u9009\u62e9\u4e2d\u90fd\u9009\u62e9\u4e2d\u95f4\u5143\u7d20\u3002 \u5e73\u5747\u60c5\u51b5\u65f6\u95f4\u590d\u6742\u5ea6\uff1a\u5728\u5e73\u5747\u60c5\u51b5\u4e0b\uff0c\u5feb\u901f\u6392\u5e8f\u7684\u65f6\u95f4\u590d\u6742\u5ea6\u4e5f\u662f O(n log n) \u3002\u8fd9\u662f\u56e0\u4e3a\u5feb\u901f\u6392\u5e8f\u662f\u4e00\u79cd\u5206\u6cbb\u7b97\u6cd5\uff0c\u6bcf\u6b21\u5c06\u95ee\u9898\u5206\u6210\u4e24\u4e2a\u5b50\u95ee\u9898\uff0c\u7136\u540e\u9012\u5f52\u5730\u89e3\u51b3\u8fd9\u4e9b\u5b50\u95ee\u9898\u3002\u5e73\u5747\u60c5\u51b5\u4e0b\uff0c\u6bcf\u6b21\u5206\u5272\u64cd\u4f5c\u90fd\u80fd\u5c06\u95ee\u9898\u89c4\u6a21\u51cf\u534a\uff0c\u56e0\u6b64\u9700\u8981\u6267\u884c O(n log n) \u6b21\u5206\u5272\u64cd\u4f5c\uff0c\u6bcf\u6b21\u5206\u5272\u64cd\u4f5c\u7684\u65f6\u95f4\u590d\u6742\u5ea6\u662f O(n) \u3002\u56e0\u6b64\uff0c\u5e73\u5747\u65f6\u95f4\u590d\u6742\u5ea6\u662f O(n log n) \u3002 \u6700\u574f\u60c5\u51b5\u65f6\u95f4\u590d\u6742\u5ea6\uff1a\u5728\u6700\u574f\u60c5\u51b5\u4e0b\uff0c\u5feb\u901f\u6392\u5e8f\u7684\u65f6\u95f4\u590d\u6742\u5ea6\u662f O(n^2) \u3002\u6700\u574f\u60c5\u51b5\u53d1\u751f\u5728\u6bcf\u6b21\u9009\u62e9\u7684\u57fa\u51c6\u5143\u7d20\u90fd\u662f\u8f93\u5165\u6570\u636e\u4e2d\u7684\u6700\u5c0f\u6216\u6700\u5927\u5143\u7d20\uff0c\u5bfc\u81f4\u5206\u5272\u64cd\u4f5c\u4e0d\u5747\u8861\uff0c\u6bcf\u6b21\u5206\u5272\u53ea\u80fd\u5c06\u95ee\u9898\u89c4\u6a21\u51cf\u5c111\u3002\u5728\u8fd9\u79cd\u60c5\u51b5\u4e0b\uff0c\u5feb\u901f\u6392\u5e8f\u9000\u5316\u4e3a\u5192\u6ce1\u6392\u5e8f\uff0c\u65f6\u95f4\u590d\u6742\u5ea6\u4e3a O(n^2) \u3002 \u5feb\u901f\u6392\u5e8f\u7684\u5e73\u5747\u548c\u6700\u597d\u60c5\u51b5\u65f6\u95f4\u590d\u6742\u5ea6\u4e3a O(n log n) \uff0c\u5728\u5b9e\u9645\u5e94\u7528\u4e2d\u901a\u5e38\u6027\u80fd\u4f18\u8d8a\u3002\u7136\u800c\uff0c\u9700\u8981\u6ce8\u610f\u7684\u662f\uff0c\u6700\u574f\u60c5\u51b5\u4e0b\u7684\u65f6\u95f4\u590d\u6742\u5ea6\u4e3a O(n^2) \uff0c\u56e0\u6b64\u5728\u5b9e\u73b0\u5feb\u901f\u6392\u5e8f\u65f6\u9700\u8981\u7279\u522b\u6ce8\u610f\u57fa\u51c6\u5143\u7d20\u7684\u9009\u62e9\u4ee5\u907f\u514d\u6700\u574f\u60c5\u51b5\u7684\u53d1\u751f\u3002 3.5.1.3.\u5b9e\u73b0\u5feb\u901f\u6392\u5e8f \u00b6 \u4ee5\u4e0a\u9762\u56fe\u793a\u7684\u5217\u8868 [12,19,17,18,14,11,15,13,16] \u4e3a\u4f8b\uff0c\u4e0b\u9762\u662f\u5b9e\u73b0\u4ee3\u7801\uff1a import random def swap ( lyst , i , j ): \"\"\"\u4ea4\u6362\u5143\u7d20\u4f4d\u7f6e\u4e3ai\u548cj\u7684\u5143\u7d20\"\"\" temp = lyst [ i ] lyst [ i ] = lyst [ j ] lyst [ j ] = temp def quicksort ( lyst ): # left\u7684\u521d\u59cb\u503c\u662f0 # right\u7684\u521d\u59cb\u503c\u662f\u5217\u8868\u957f\u5ea6\u51cf1 quicksortHelper ( lyst , 0 , len ( lyst ) - 1 ) def quicksortHelper ( lyst , left , right ): print ( lyst ) if left < right : pivotLocation = partition ( lyst , left , right ) quicksortHelper ( lyst , left , pivotLocation - 1 ) quicksortHelper ( lyst , pivotLocation + 1 , right ) def partition ( lyst , left , right ): \"\"\"\u5bf9\u5217\u8868\u8fdb\u884c\u5206\u533a\"\"\" # \u627e\u5230\u57fa\u51c6\u5143\u7d20\uff08pivot\uff09\uff0c\u5e76\u548c\u6700\u540e\u4e00\u4e2a\u5143\u7d20\u4e92\u6362 middle = ( left + right ) // 2 pivot = lyst [ middle ] lyst [ middle ] = lyst [ right ] lyst [ right ] = pivot # \u8bbe\u5b9a\u8fb9\u754c\u5143\u7d20\uff08boundary point\uff09\uff0c\u521d\u59cb\u662f\u7b2c\u4e00\u4e2a\u5143\u7d20 boundary = left print ( \"pivot: \" , pivot , \"boundary: \" , lyst [ boundary ]) # \u628a\u6240\u6709\u5c0f\u4e8e\u57fa\u51c6\u7684\u5143\u7d20\u90fd\u79fb\u52a8\u5230\u8fb9\u754c\u7684\u5de6\u8fb9 for index in range ( left , right ): if lyst [ index ] < pivot : swap ( lyst , index , boundary ) boundary += 1 # \u4ea4\u6362\u57fa\u51c6\u5143\u7d20\u548c\u8fb9\u754c\u5143\u7d20 swap ( lyst , right , boundary ) print ( lyst ) return boundary def main ( size = 20 , sort = quicksort ): lyst = [ 12 , 19 , 17 , 18 , 14 , 11 , 15 , 13 , 16 ] sort ( lyst ) if __name__ == \"__main__\" : main () # \u8fd0\u884c\u7ed3\u679c\uff1a # [12, 19, 17, 18, 14, 11, 15, 13, 16] # pivot: 14 boundary: 12 # [12, 11, 13, 14, 16, 19, 15, 17, 18] # [12, 11, 13, 14, 16, 19, 15, 17, 18] # pivot: 11 boundary: 12 # [11, 13, 12, 14, 16, 19, 15, 17, 18] # [11, 13, 12, 14, 16, 19, 15, 17, 18] # [11, 13, 12, 14, 16, 19, 15, 17, 18] # pivot: 13 boundary: 12 # [11, 12, 13, 14, 16, 19, 15, 17, 18] # [11, 12, 13, 14, 16, 19, 15, 17, 18] # [11, 12, 13, 14, 16, 19, 15, 17, 18] # [11, 12, 13, 14, 16, 19, 15, 17, 18] # pivot: 15 boundary: 16 # [11, 12, 13, 14, 15, 19, 18, 17, 16] # [11, 12, 13, 14, 15, 19, 18, 17, 16] # [11, 12, 13, 14, 15, 19, 18, 17, 16] # pivot: 18 boundary: 19 # [11, 12, 13, 14, 15, 16, 17, 18, 19] # [11, 12, 13, 14, 15, 16, 17, 18, 19] # pivot: 16 boundary: 17 # [11, 12, 13, 14, 15, 16, 17, 18, 19] # [11, 12, 13, 14, 15, 16, 17, 18, 19] # [11, 12, 13, 14, 15, 16, 17, 18, 19] # [11, 12, 13, 14, 15, 16, 17, 18, 19] \u628amain()\u6539\u6210\u5982\u4e0b\uff0c\u5219\u53ef\u4ee5\u751f\u6210\u753120\u4e2a\u968f\u673a\u6574\u6570\u7ec4\u6210\u7684\u5217\u8868\uff1a def main ( size = 20 , sort = quicksort ): lyst = [] for count in range ( size ): lyst . append ( random . randint ( 1 , size + 1 )) print ( lyst ) sort ( lyst ) print ( lyst ) # \u8fd0\u884c\u7ed3\u679c\uff1a # \u7b2c\u4e00\u6b21\u8fd0\u884c # [3, 19, 18, 11, 2, 16, 2, 13, 14, 1, 20, 1, 1, 19, 19, 9, 16, 1, 7, 4] # [1, 1, 1, 1, 2, 2, 3, 4, 7, 9, 11, 13, 14, 16, 16, 18, 19, 19, 19, 20] # \u7b2c\u4e8c\u6b21\u8fd0\u884c # [20, 4, 1, 15, 6, 4, 3, 16, 21, 4, 12, 9, 16, 10, 3, 6, 2, 15, 21, 4] # [1, 2, 3, 3, 4, 4, 4, 4, 6, 6, 9, 10, 12, 15, 15, 16, 16, 20, 21, 21] 3.5.2.\u5f52\u5e76\u6392\u5e8f \u00b6 \u5f52\u5e76\u6392\u5e8f\u7684\u7b97\u6cd5\u4e5f\u662f\u91c7\u7528\u5206\u6cbb\u6cd5\uff08Divide and Conquer\uff09\u7684\u4e00\u4e2a\u975e\u5e38\u5178\u578b\u7684\u5e94\u7528\uff0c\u901a\u8fc7\u9012\u5f52\u548c\u5206\u6cbb\u7b56\u7565\u6765\u7a81\u7834 O(n^2) \u6027\u80fd\u74f6\u9888\u7684\u3002 \u4e0b\u9762\u662f\u5bf9\u8fd9\u4e2a\u7b97\u6cd5\u7684\u7b80\u5355\u63cf\u8ff0\u3002 \u5206\u89e3\uff08Divide\uff09\uff1a\u5c06n\u4e2a\u5143\u7d20\u5206\u6210\u4e2a\u542bn/2\u4e2a\u5143\u7d20\u7684\u5b50\u5e8f\u5217\u3002 \u89e3\u51b3\uff08Conquer\uff09\uff1a\u7528\u5408\u5e76\u6392\u5e8f\u6cd5\u5bf9\u4e24\u4e2a\u5b50\u5e8f\u5217\u9012\u5f52\u7684\u6392\u5e8f\u3002 \u5408\u5e76\uff08Combine\uff09\uff1a\u5408\u5e76\u4e24\u4e2a\u5df2\u6392\u5e8f\u7684\u5b50\u5e8f\u5217\u5df2\u5f97\u5230\u6392\u5e8f\u7ed3\u679c\u3002 \u7b97\u6cd5\u601d\u8def\uff1a \u8fed\u4ee3\u6cd5 \u7533\u8bf7\u7a7a\u95f4\uff0c\u4f7f\u5176\u5927\u5c0f\u4e3a\u4e24\u4e2a\u5df2\u7ecf\u6392\u5e8f\u5e8f\u5217\u4e4b\u548c\uff0c\u8be5\u7a7a\u95f4\u7528\u6765\u5b58\u653e\u5408\u5e76\u540e\u7684\u5e8f\u5217\uff1b \u8bbe\u5b9a\u4e24\u4e2a\u6307\u9488\uff0c\u6700\u521d\u4f4d\u7f6e\u5206\u522b\u4e3a\u4e24\u4e2a\u5df2\u7ecf\u6392\u5e8f\u5e8f\u5217\u7684\u8d77\u59cb\u4f4d\u7f6e\uff1b \u6bd4\u8f83\u4e24\u4e2a\u6307\u9488\u6240\u6307\u5411\u7684\u5143\u7d20\uff0c\u9009\u62e9\u76f8\u5bf9\u5c0f\u7684\u5143\u7d20\u653e\u5165\u5230\u5408\u5e76\u7a7a\u95f4\uff0c\u5e76\u79fb\u52a8\u6307\u9488\u5230\u4e0b\u4e00\u4f4d\u7f6e\uff1b \u91cd\u590d\u6b65\u9aa43\u76f4\u5230\u67d0\u4e00\u6307\u9488\u5230\u8fbe\u5e8f\u5217\u5c3e\uff1b \u5c06\u53e6\u4e00\u5e8f\u5217\u5269\u4e0b\u7684\u6240\u6709\u5143\u7d20\u76f4\u63a5\u590d\u5236\u5230\u5408\u5e76\u5e8f\u5217\u5c3e\uff1b \u9012\u5f52\u6cd5 \u5c06\u5e8f\u5217\u6bcf\u76f8\u90bb\u4e24\u4e2a\u6570\u5b57\u8fdb\u884c\u5f52\u5e76\u64cd\u4f5c\uff0c\u5f62\u6210 floor(n/2) \u4e2a\u5e8f\u5217\uff0c\u6392\u5e8f\u540e\u6bcf\u4e2a\u5e8f\u5217\u5305\u542b\u4e24\u4e2a\u5143\u7d20\uff1b \u5c06\u4e0a\u8ff0\u5e8f\u5217\u518d\u6b21\u5f52\u5e76\uff0c\u5f62\u6210 floor(n/4) \u4e2a\u5e8f\u5217\uff0c\u6bcf\u4e2a\u5e8f\u5217\u5305\u542b\u56db\u4e2a\u5143\u7d20\uff1b \u91cd\u590d\u6b65\u9aa42\uff0c\u76f4\u5230\u6240\u6709\u5143\u7d20\u6392\u5e8f\u5b8c\u6bd5\uff1b \u5728\u9876\u5c42\u5b9a\u4e49\u4e863\u4e2aPython\u51fd\u6570\u8fdb\u884c\u534f\u4f5c\u3002 mergeSort \uff1a\u7528\u6237\u8c03\u7528\u7684\u51fd\u6570\uff1b mergeSortHelper \uff1a\u8f85\u52a9\u51fd\u6570\uff0c\u7528\u6765\u9690\u85cf\u9012\u5f52\u8c03\u7528\u6240\u9700\u8981\u7684\u989d\u5916\u53c2\u6570\uff1b merge \uff1a\u5b9e\u73b0\u5408\u5e76\u8fc7\u7a0b\u7684\u51fd\u6570\uff1b 3.5.2.1.\u5408\u5e76\u8fc7\u7a0b\u7684\u5b9e\u73b0 \u00b6 \u5408\u5e76\u8fc7\u7a0b\u7528\u5230\u4e00\u4e2a\u4e0e\u5217\u8868\u5927\u5c0f\u76f8\u540c\u7684\u6570\u7ec4\uff0c\u8fd9\u4e2a\u6570\u7ec4\u53ef\u4ee5\u628a\u5b83\u79f0\u4e3a copyBuffer \u3002\u4e3a\u4e86\u907f\u514d\u6bcf\u6b21\u8c03\u7528 merge \u65f6\u90fd\u8981\u4e3a copyBuffer \u7684\u5206\u914d\u548c\u91ca\u653e\u4ea7\u751f\u5f00\u9500\uff0c\u8fd9\u4e2a\u7f13\u51b2\u533a\u4f1a\u5728 mergeSort \u51fd\u6570\u91cc\u5c31\u5206\u914d\u597d\uff0c\u7136\u540e\u4f5c\u4e3a\u53c2\u6570\u4f20\u9012\u7ed9 mergeSortHelper \u548c merge \u51fd\u6570\u3002\u6bcf\u6b21\u8c03\u7528 mergeSortHelper \u51fd\u6570\u65f6\uff0c\u5b83\u8fd8\u9700\u8981\u77e5\u9053\u5e94\u8be5\u4f7f\u7528\u7684\u5b50\u5217\u8868\u7684\u8303\u56f4\u3002\u8fd9\u4e2a\u8303\u56f4\u53ef\u4ee5\u7531\u53e6\u5916\u4e24\u4e2a\u53c2\u6570 low \u548c high \u6765\u63d0\u4f9b\u3002\u5177\u4f53\u5b9e\u73b0\u53c2\u8003 mergeSort \u51fd\u6570\u7684\u4ee3\u7801\u3002 \u5728\u68c0\u67e5\u4f20\u9012\u7684\u5b50\u5217\u8868\u662f\u4e0d\u662f\u81f3\u5c11\u6709\u4e24\u4e2a\u5143\u7d20\u4e4b\u540e\uff0c mergeSortHelper \u51fd\u6570\u5c06\u4f1a\u8ba1\u7b97\u8fd9\u4e2a\u5b50\u5217\u8868\u7684\u4e2d\u70b9\uff0c\u5e76\u4e14\u5bf9\u4e2d\u70b9\u5de6\u53f3\u4e24\u90e8\u5206\u8fdb\u884c\u9012\u5f52\u6392\u5e8f\uff0c\u6700\u540e\u518d\u8c03\u7528 merge \u51fd\u6570\u6765\u5408\u5e76\u7ed3\u679c\u3002\u5177\u4f53\u5b9e\u73b0\u53c2\u8003 mergeSortHelper \u51fd\u6570\u7684\u4ee3\u7801\u3002 merge \u51fd\u6570\u4f1a\u628a\u4e24\u4e2a\u5df2\u7ecf\u6392\u597d\u5e8f\u7684\u5b50\u5217\u8868\u5408\u5e76\u6210\u4e00\u4e2a\u66f4\u5927\u7684\u6709\u5e8f\u5217\u8868\u3002\u5728\u539f\u5217\u8868\u91cc\uff0c\u7b2c\u4e00\u4e2a\u5b50\u5217\u8868\u4f1a\u5728 low \u5230 middle \u4e4b\u95f4\uff1b\u7b2c\u4e8c\u4e2a\u5b50\u5217\u8868\u5219\u4f4d\u4e8e middle + 1 \u548c high \u4e4b\u95f4\u3002\u8fd9\u4e2a\u8fc7\u7a0b\u5305\u542b\u5982\u4e0b3\u4e2a\u6b65\u9aa4\u3002 \u8bbe\u7f6e\u6307\u5411\u4e24\u4e2a\u5b50\u5217\u8868\u4e2d\u7b2c\u4e00\u4e2a\u5143\u7d20\u7684\u7d22\u5f15\u6307\u9488\u3002\u5b83\u4eec\u5206\u522b\u4f4d\u4e8e low \u548c middle +1 \uff1b \u4ece\u5b50\u5217\u8868\u7684\u7b2c\u4e00\u4e2a\u5143\u7d20\u5f00\u59cb\u91cd\u590d\u6bd4\u8f83\u8fd9\u4e9b\u5143\u7d20\u3002\u628a\u66f4\u5c0f\u7684\u90a3\u4e2a\u5143\u7d20\u4ece\u5b83\u6240\u5728\u7684\u5b50\u5217\u8868\u91cc\u590d\u5236\u5230\u62f7\u8d1d\u7f13\u51b2\u533a\u53bb\uff0c\u7136\u540e\u628a\u8fd9\u4e2a\u5b50\u5217\u8868\u7684\u7d22\u5f15\u79fb\u52a8\u5230\u4e0b\u4e00\u4e2a\u5143\u7d20\uff1b \u4e0d\u65ad\u5730\u6267\u884c\u8fd9\u4e2a\u64cd\u4f5c\uff0c\u76f4\u5230\u5df2\u7ecf\u5b8c\u5168\u590d\u5236\u4e86\u4e24\u4e2a\u5b50\u5217\u8868\u91cc\u7684\u6240\u6709\u5143\u7d20\u3002\u5982\u679c\u5176\u4e2d\u4e00\u4e2a\u5b50\u5217\u8868\u5df2\u7ecf\u5230\u8fbe\u4e86\u672b\u5c3e\uff0c\u90a3\u4e48\u53ef\u4ee5\u628a\u53e6\u4e00\u4e2a\u5b50\u5217\u8868\u91cc\u7684\u5176\u4f59\u5143\u7d20\u76f4\u63a5\u590d\u5236\u8fc7\u53bb\uff1b \u628a copyBuffer \u4e2d low \u5230 high \u4e4b\u95f4\u7684\u90e8\u5206\u590d\u5236\u56de lyst \u4e2d\u7684\u76f8\u5e94\u4f4d\u7f6e\uff1b \u5b9e\u73b0\u4ee3\u7801\uff1a class Array ( object ): \"\"\" \u63cf\u8ff0\u4e00\u4e2a\u6570\u7ec4\u3002 \u6570\u7ec4\u7c7b\u4f3c\u5217\u8868\uff0c\u4f46\u6570\u7ec4\u53ea\u80fd\u4f7f\u7528[], len, iter, \u548c str\u8fd9\u4e9b\u5c5e\u6027\u3002 \u5b9e\u4f8b\u5316\u4e00\u4e2a\u6570\u7ec4\uff0c\u4f7f\u7528 = Array(, ) \u5176\u4e2dfill value\u9ed8\u8ba4\u503c\u662fNone\u3002 \"\"\" def __init__ ( self , capacity , fillValue = None ): \"\"\"Capacity\u662f\u6570\u7ec4\u7684\u5927\u5c0f. fillValue\u4f1a\u586b\u5145\u5728\u6bcf\u4e2a\u5143\u7d20\u4f4d\u7f6e, \u9ed8\u8ba4\u503c\u662fNone\"\"\" self . items = list () for count in range ( capacity ): self . items . append ( fillValue ) def __len__ ( self ): \"\"\"-> \u6570\u7ec4\u7684\u5927\u5c0f\"\"\" return len ( self . items ) def __str__ ( self ): \"\"\"-> \u5c06\u6570\u7ec4\u5b57\u7b26\u4e32\u5316\"\"\" return str ( self . items ) def __iter__ ( self ): \"\"\"\u652f\u6301for\u5faa\u73af\u5bf9\u6570\u7ec4\u8fdb\u884c\u904d\u5386.\"\"\" return iter ( self . items ) def __getitem__ ( self , index ): \"\"\"\u7528\u4e8e\u8bbf\u95ee\u7d22\u5f15\u5904\u7684\u4e0b\u6807\u8fd0\u7b97\u7b26.\"\"\" return self . items [ index ] def __setitem__ ( self , index , newItem ): \"\"\"\u4e0b\u6807\u8fd0\u7b97\u7b26\u7528\u4e8e\u5728\u7d22\u5f15\u5904\u8fdb\u884c\u66ff\u6362.\"\"\" self . items [ index ] = newItem def mergeSort ( lyst ): # lyst : \u7528\u4e8e\u6392\u5e8f\u7684\u5217\u8868 # copyBuffer : \u7528\u4e8e\u5408\u5e76\u7684\u4e34\u65f6\u7a7a\u95f4 copyBuffer = Array ( len ( lyst )) mergeSortHelper ( lyst , copyBuffer , 0 , len ( lyst ) - 1 ) def mergeSortHelper ( lyst , copyBuffer , low , high ): # lyst : \u7528\u4e8e\u6392\u5e8f\u7684\u5217\u8868 # copyBuffer : \u7528\u4e8e\u5408\u5e76\u7684\u4e34\u65f6\u7a7a\u95f4 # low, high : \u5b50\u5217\u8868\u7684\u8fb9\u754c # middle : \u5b50\u5217\u8868\u7684\u4e2d\u70b9 if low < high : middle = ( low + high ) // 2 print ( f 'low: { lyst [ low ] } , middle: { lyst [ middle ] } , high: { lyst [ high ] } , copyBuffer: { copyBuffer } ' ) # \u9012\u5f52\u5904\u7406\u7b2c\u4e00\u4e2a\u6392\u5e8f\u5b50\u5217\u8868\uff0c\u5373\u4e2d\u503c\u7684\u5de6\u6bb5\uff0c\u76f4\u81f3\u4e0d\u6ee1\u8db3low < high\u65f6\u9000\u51fa mergeSortHelper ( lyst , copyBuffer , low , middle ) # \u9012\u5f52\u5904\u7406\u7b2c\u4e8c\u4e2a\u6392\u5e8f\u5b50\u5217\u8868\uff0c\u5373\u4e2d\u503c\u7684\u53f3\u6bb5\uff0c\u76f4\u81f3\u4e0d\u6ee1\u8db3low < high\u65f6\u9000\u51fa mergeSortHelper ( lyst , copyBuffer , middle + 1 , high ) # \u5f53\u524d\u5904\u7406\u7684\u5b50\u8868\u6570\u636e\u9001\u5165copyBuffer\uff0c\u5408\u5e76\u4e14\u6392\u5e8f merge ( lyst , copyBuffer , low , middle , high ) def merge ( lyst , copyBuffer , low , middle , high ): # lyst : \u7528\u4e8e\u6392\u5e8f\u7684\u5217\u8868 # copyBuffer : \u7528\u4e8e\u5408\u5e76\u7684\u4e34\u65f6\u7a7a\u95f4 # low : \u7b2c\u4e00\u4e2a\u6392\u5e8f\u5b50\u5217\u8868\u7684\u5f00\u5934 # middle : \u7b2c\u4e00\u4e2a\u6392\u5e8f\u5b50\u5217\u8868\u7684\u7ed3\u5c3e # middle + 1 : \u7b2c\u4e8c\u4e2a\u6392\u5e8f\u5b50\u5217\u8868\u7684\u5f00\u5934 # high : \u7b2c\u4e8c\u4e2a\u6392\u5e8f\u5b50\u5217\u8868\u7684\u7ed3\u5c3e # \u5c06 i1 \u548c i2 \u521d\u59cb\u5316\u4e3a\u6bcf\u4e2a\u5b50\u5217\u8868\u4e2d\u7684\u7b2c\u4e00\u9879 i1 = low i2 = middle + 1 # \u5c06\u5b50\u5217\u8868\u4e2d\u7684\u5143\u7d20\u4ea4\u9519\u653e\u5165copyBuffer\u4e2d\uff0c\u5e76\u4fdd\u6301\u987a\u5e8f\u3002 for i in range ( low , high + 1 ): if i1 > middle : copyBuffer [ i ] = lyst [ i2 ] # \u7b2c\u4e00\u4e2a\u5b50\u5217\u8868\u5df2\u7528\u5b8c i2 += 1 elif i2 > high : copyBuffer [ i ] = lyst [ i1 ] # \u7b2c\u4e8c\u4e2a\u5b50\u5217\u8868\u5df2\u7528\u5b8c i1 += 1 elif lyst [ i1 ] < lyst [ i2 ]: copyBuffer [ i ] = lyst [ i1 ] # \u7b2c\u4e00\u4e2a\u5b50\u8868\u4e2d\u7684\u5143\u7d20 < i1 += 1 else : copyBuffer [ i ] = lyst [ i2 ] # \u7b2c\u4e8c\u4e2a\u5b50\u8868\u4e2d\u7684\u5143\u7d20 < i2 += 1 print ( \"i=\" , i , \"\" , \"i1=\" , i1 , \"i2=\" , i2 , \"copyBuffer:\" , copyBuffer ) for i in range ( low , high + 1 ): # \u5c06\u5df2\u6392\u5e8f\u7684\u5143\u7d20\u590d\u5236\u56delyst\u4e2d\u7684\u6b63\u786e\u4f4d\u7f6e lyst [ i ] = copyBuffer [ i ] def main (): lyst = [ 12 , 19 , 17 , 18 , 14 , 11 , 15 , 13 , 16 ] print ( \"Original List\" , lyst ) mergeSort ( lyst ) print ( \"Sorted List\" , lyst ) if __name__ == \"__main__\" : main () # \u8fd0\u884c\u7ed3\u679c\uff1a # Original List [12, 19, 17, 18, 14, 11, 15, 13, 16] # low: 12, middle: 14, high: 16, copyBuffer: [None, None, None, None, None, None, None, None, None] # low: 12, middle: 17, high: 14, copyBuffer: [None, None, None, None, None, None, None, None, None] # low: 12, middle: 19, high: 17, copyBuffer: [None, None, None, None, None, None, None, None, None] # low: 12, middle: 12, high: 19, copyBuffer: [None, None, None, None, None, None, None, None, None] # i= 1 i1= 1 i2= 2 copyBuffer: [12, 19, None, None, None, None, None, None, None] # i= 2 i1= 2 i2= 3 copyBuffer: [12, 17, 19, None, None, None, None, None, None] # low: 18, middle: 18, high: 14, copyBuffer: [12, 17, 19, None, None, None, None, None, None] # i= 4 i1= 4 i2= 5 copyBuffer: [12, 17, 19, 14, 18, None, None, None, None] # i= 4 i1= 3 i2= 5 copyBuffer: [12, 14, 17, 18, 19, None, None, None, None] # low: 11, middle: 15, high: 16, copyBuffer: [12, 14, 17, 18, 19, None, None, None, None] # low: 11, middle: 11, high: 15, copyBuffer: [12, 14, 17, 18, 19, None, None, None, None] # i= 6 i1= 6 i2= 7 copyBuffer: [12, 14, 17, 18, 19, 11, 15, None, None] # low: 13, middle: 13, high: 16, copyBuffer: [12, 14, 17, 18, 19, 11, 15, None, None] # i= 8 i1= 8 i2= 9 copyBuffer: [12, 14, 17, 18, 19, 11, 15, 13, 16] # i= 8 i1= 7 i2= 9 copyBuffer: [12, 14, 17, 18, 19, 11, 13, 15, 16] # i= 8 i1= 5 i2= 9 copyBuffer: [11, 12, 13, 14, 15, 16, 17, 18, 19] # Sorted List [11, 12, 13, 14, 15, 16, 17, 18, 19] \u8fd0\u884c\u7ed3\u679c\u56fe\u793a\u5206\u6790\uff1a 3.5.2.2.\u5f52\u5e76\u6392\u5e8f\u7684\u590d\u6742\u5ea6\u5206\u6790 \u00b6 merge \u51fd\u6570\u7684\u8fd0\u884c\u65f6\u7531\u4e24\u4e2a for \u8bed\u53e5\u6765\u51b3\u5b9a\uff0c\u800c\u8fd9\u4e24\u4e2a\u5faa\u73af\u90fd\u4f1a\u88ab\u8fed\u4ee3 (high \u2013 low + 1) \u6b21\uff0c\u56e0\u6b64\uff0c\u8fd9\u4e2a\u51fd\u6570\u7684\u8fd0\u884c\u65f6\u662f O(high\u2212low) \uff0c\u4e8e\u662f\u6bcf\u4e00\u5c42\u4e0a\u7684\u6240\u6709\u5408\u5e76\u603b\u5171\u9700\u8981 O(n) \u7684\u65f6\u95f4\u3002\u56e0\u4e3a mergeSortHelper \u5728\u6bcf\u4e00\u5c42\u90fd\u5c3d\u53ef\u80fd\u5747\u5300\u5730\u62c6\u5206\u5b50\u5217\u8868\uff0c\u6240\u4ee5\u5c42\u6570\u5e94\u8be5\u662f O(log n) \uff0c\u5728\u6240\u6709\u7684\u60c5\u51b5\u4e0b\u8fd9\u4e2a\u51fd\u6570\u7684\u6700\u5927\u8fd0\u884c\u65f6\u90fd\u662f O(n log n) \u3002 \u5f52\u5e76\u6392\u5e8f\u4f1a\u6709\u4e24\u4e2a\u57fa\u4e8e\u5217\u8868\u5927\u5c0f\u7684\u7a7a\u95f4\u9700\u6c42\u3002\u9996\u5148\uff0c\u5728\u8c03\u7528\u6808\u4e0a\u9700\u8981 O(log n) \u7684\u7a7a\u95f4\u6765\u652f\u6301\u9012\u5f52\u8c03\u7528\uff1b\u5176\u6b21\uff0c\u62f7\u8d1d\u7f13\u51b2\u533a\u4f1a\u7528\u5230 O(n) \u7684\u7a7a\u95f4\u3002 3.5.3.\u7ec3\u4e60\u9898 \u00b6 \u63cf\u8ff0\u5feb\u901f\u6392\u5e8f\u7684\u7b56\u7565\uff0c\u5e76\u8bf4\u660e\u4e3a\u4ec0\u4e48\u5b83\u53ef\u4ee5\u628a\u6392\u5e8f\u7684\u65f6\u95f4\u590d\u6742\u5ea6\u4ece O(n^2) \u964d\u4f4e\u5230 O(n log n) \u3002 \u89e3\u7b54\uff1a\u5feb\u901f\u6392\u5e8f\uff08Quick Sort\uff09\u662f\u4e00\u79cd\u9ad8\u6548\u7684\u6392\u5e8f\u7b97\u6cd5\uff0c\u5b83\u91c7\u7528\u5206\u6cbb\u7b56\u7565\u6765\u5c06\u4e00\u4e2a\u5927\u95ee\u9898\u5206\u89e3\u6210\u82e5\u5e72\u4e2a\u5b50\u95ee\u9898\uff0c\u7136\u540e\u9012\u5f52\u5730\u89e3\u51b3\u8fd9\u4e9b\u5b50\u95ee\u9898\u3002\u4ee5\u4e0b\u662f\u5feb\u901f\u6392\u5e8f\u7684\u7b56\u7565\u548c\u539f\u7406\uff0c\u4ee5\u53ca\u4e3a\u4ec0\u4e48\u5b83\u80fd\u591f\u5c06\u6392\u5e8f\u7684\u65f6\u95f4\u590d\u6742\u5ea6\u4ece O(n^2) \u964d\u4f4e\u5230 O(n log n) \uff1a \u5feb\u901f\u6392\u5e8f\u7684\u7b56\u7565\uff1a \u9009\u62e9\u4e3b\u5143\uff08Pivot\uff09\uff1a\u5728\u5feb\u901f\u6392\u5e8f\u4e2d\uff0c\u9996\u5148\u4ece\u5f85\u6392\u5e8f\u7684\u5143\u7d20\u4e2d\u9009\u62e9\u4e00\u4e2a\u4e3b\u5143\uff08\u901a\u5e38\u662f\u7b2c\u4e00\u4e2a\u6216\u6700\u540e\u4e00\u4e2a\u5143\u7d20\uff09\uff0c\u4e5f\u53eb\u57fa\u51c6\u5143\u7d20\u3002 \u5206\u5272\u64cd\u4f5c\uff1a\u5c06\u5143\u7d20\u5206\u4e3a\u4e24\u4e2a\u5b50\u6570\u7ec4\uff0c\u4e00\u4e2a\u5c0f\u4e8e\u4e3b\u5143\u7684\u5b50\u6570\u7ec4\uff0c\u4e00\u4e2a\u5927\u4e8e\u4e3b\u5143\u7684\u5b50\u6570\u7ec4\u3002\u8fd9\u4e2a\u8fc7\u7a0b\u79f0\u4e3a\u5206\u5272\u3002 \u9012\u5f52\u6392\u5e8f\uff1a\u9012\u5f52\u5730\u5bf9\u4e24\u4e2a\u5b50\u6570\u7ec4\u8fdb\u884c\u6392\u5e8f\u3002\u5373\uff0c\u5bf9\u5c0f\u4e8e\u4e3b\u5143\u7684\u5b50\u6570\u7ec4\u548c\u5927\u4e8e\u4e3b\u5143\u7684\u5b50\u6570\u7ec4\u5206\u522b\u8fdb\u884c\u5feb\u901f\u6392\u5e8f\u3002 \u5408\u5e76\uff1a\u5c06\u5df2\u6392\u5e8f\u7684\u5b50\u6570\u7ec4\u5408\u5e76\u6210\u6700\u7ec8\u7684\u6709\u5e8f\u6570\u7ec4\u3002 \u4e3a\u4ec0\u4e48\u5feb\u901f\u6392\u5e8f\u80fd\u591f\u964d\u4f4e\u65f6\u95f4\u590d\u6742\u5ea6\uff1a \u5feb\u901f\u6392\u5e8f\u4e4b\u6240\u4ee5\u80fd\u591f\u5c06\u6392\u5e8f\u7684\u65f6\u95f4\u590d\u6742\u5ea6\u4ece O(n^2) \u964d\u4f4e\u5230 O(n log n) \uff0c\u4e3b\u8981\u6709\u4ee5\u4e0b\u539f\u56e0\uff1a \u5206\u6cbb\u7b56\u7565\uff1a\u5feb\u901f\u6392\u5e8f\u91c7\u7528\u4e86\u5206\u6cbb\u7b56\u7565\uff0c\u5c06\u4e00\u4e2a\u5927\u95ee\u9898\u5206\u89e3\u6210\u4e24\u4e2a\u6216\u591a\u4e2a\u89c4\u6a21\u8f83\u5c0f\u7684\u5b50\u95ee\u9898\u3002\u8fd9\u79cd\u5206\u6cbb\u7b56\u7565\u80fd\u591f\u51cf\u5c0f\u95ee\u9898\u7684\u89c4\u6a21\uff0c\u4ece\u800c\u964d\u4f4e\u4e86\u89e3\u51b3\u95ee\u9898\u7684\u590d\u6742\u5ea6\u3002 \u597d\u7684\u5e73\u5747\u60c5\u51b5\uff1a\u5728\u5e73\u5747\u60c5\u51b5\u4e0b\uff0c\u5feb\u901f\u6392\u5e8f\u5bf9\u5f85\u6392\u5e8f\u7684\u6570\u636e\u8fdb\u884c\u4e86\u826f\u597d\u7684\u5e73\u5747\u5206\u5272\uff0c\u6bcf\u6b21\u5206\u5272\u90fd\u5c06\u95ee\u9898\u89c4\u6a21\u51cf\u534a\u3002\u8fd9\u4f7f\u5f97\u5e73\u5747\u65f6\u95f4\u590d\u6742\u5ea6\u4e3a O(n log n) \u3002 **\u4e0d\u7a33\u5b9a\u6027\uff1a\u5feb\u901f\u6392\u5e8f\u662f\u4e0d\u7a33\u5b9a\u7684\u6392\u5e8f\u7b97\u6cd5\uff0c\u8fd9\u610f\u5473\u7740\u76f8\u540c\u5143\u7d20\u7684\u76f8\u5bf9\u987a\u5e8f\u5728\u6392\u5e8f\u540e\u53ef\u80fd\u4f1a\u6539\u53d8\u3002\u8fd9\u79cd\u4e0d\u7a33\u5b9a\u6027\u4f7f\u5f97\u5feb\u901f\u6392\u5e8f\u53ef\u4ee5\u66f4\u5feb\u5730\u6392\u5e8f\u76f8\u540c\u5143\u7d20\u7684\u5927\u6570\u636e\u96c6\u3002 \u539f\u5730\u6392\u5e8f\uff1a\u5feb\u901f\u6392\u5e8f\u901a\u5e38\u662f\u539f\u5730\u6392\u5e8f\u7684\uff0c\u5b83\u4e0d\u9700\u8981\u989d\u5916\u7684\u5185\u5b58\u6765\u5b58\u50a8\u4e34\u65f6\u6570\u636e\u3002\u8fd9\u5bf9\u4e8e\u5185\u5b58\u5360\u7528\u6709\u9650\u7684\u60c5\u51b5\u5f88\u6709\u5229\u3002 \u6700\u574f\u60c5\u51b5\u4e0b\uff0c\u5feb\u901f\u6392\u5e8f\u7684\u65f6\u95f4\u590d\u6742\u5ea6\u4ecd\u7136\u662f O(n^2) \uff0c\u8fd9\u79cd\u60c5\u51b5\u901a\u5e38\u53d1\u751f\u5728\u4e3b\u5143\u9009\u62e9\u4e0d\u5f53\u6216\u8f93\u5165\u6570\u636e\u5df2\u7ecf\u6709\u5e8f\u7684\u60c5\u51b5\u4e0b\u3002\u5728\u5b9e\u9645\u5e94\u7528\u4e2d\uff0c\u901a\u5e38\u9700\u8981\u9009\u62e9\u4e00\u4e2a\u5408\u9002\u7684\u4e3b\u5143\u9009\u62e9\u7b56\u7565\uff0c\u4ee5\u5c3d\u91cf\u907f\u514d\u6700\u574f\u60c5\u51b5\u7684\u53d1\u751f\u3002 \u4e3a\u4ec0\u4e48\u5feb\u901f\u6392\u5e8f\u5e76\u4e0d\u5728\u6240\u6709\u60c5\u51b5\u4e0b\u90fd\u6709 O(n log n) \u7684\u590d\u6742\u5ea6\uff1f\u5bf9\u5feb\u901f\u6392\u5e8f\u7684\u6700\u574f\u60c5\u51b5\u8fdb\u884c\u63cf\u8ff0\uff0c\u5e76\u7ed9\u51fa\u4e00\u4e2a\u4f1a\u4ea7\u751f\u8fd9\u4e2a\u60c5\u51b5\u7684\u5305\u542b10\u4e2a\u6574\u6570\uff081\uff5e10\uff09\u7684\u5217\u8868\u3002 \u89e3\u7b54\uff1a\u5feb\u901f\u6392\u5e8f\u5e76\u4e0d\u5728\u6240\u6709\u60c5\u51b5\u4e0b\u90fd\u5177\u6709 O(n log n) \u7684\u65f6\u95f4\u590d\u6742\u5ea6\uff0c\u5b83\u7684\u6027\u80fd\u53d6\u51b3\u4e8e\u4e3b\u5143\uff08pivot\uff09\u7684\u9009\u62e9\u548c\u8f93\u5165\u6570\u636e\u7684\u5206\u5e03\u60c5\u51b5\u3002\u6700\u574f\u60c5\u51b5\u53d1\u751f\u5728\u4ee5\u4e0b\u60c5\u51b5\u4e0b\uff1a \u4e3b\u5143\u9009\u62e9\u4e0d\u5f53\uff1a\u5982\u679c\u6bcf\u6b21\u9009\u62e9\u7684\u4e3b\u5143\u90fd\u662f\u8f93\u5165\u6570\u636e\u4e2d\u7684\u6700\u5c0f\u6216\u6700\u5927\u5143\u7d20\uff0c\u5feb\u901f\u6392\u5e8f\u5c06\u4f1a\u4ea7\u751f\u6700\u574f\u60c5\u51b5\u3002\u5728\u8fd9\u79cd\u60c5\u51b5\u4e0b\uff0c\u5206\u5272\u64cd\u4f5c\u5c06\u5bfc\u81f4\u4e00\u4e2a\u5b50\u6570\u7ec4\u4e3a\u7a7a\uff0c\u53e6\u4e00\u4e2a\u5b50\u6570\u7ec4\u7684\u5927\u5c0f\u4e3a\u539f\u59cb\u6570\u7ec4\u5927\u5c0f\u51cf\u4e00\u3002\u8fd9\u4f7f\u5f97\u6bcf\u6b21\u5206\u5272\u64cd\u4f5c\u53ea\u51cf\u5c11\u4e00\u4e2a\u5143\u7d20\uff0c\u5bfc\u81f4\u9012\u5f52\u6df1\u5ea6\u8fbe\u5230\u6700\u5927\uff0c\u65f6\u95f4\u590d\u6742\u5ea6\u4e3a O(n^2) \u3002 \u8f93\u5165\u6570\u636e\u5df2\u7ecf\u6709\u5e8f\uff1a\u5982\u679c\u8f93\u5165\u6570\u636e\u5df2\u7ecf\u662f\u6709\u5e8f\u7684\uff0c\u4e0d\u7ba1\u662f\u5347\u5e8f\u8fd8\u662f\u964d\u5e8f\uff0c\u5feb\u901f\u6392\u5e8f\u4e5f\u4f1a\u4ea7\u751f\u6700\u574f\u60c5\u51b5\u3002\u56e0\u4e3a\u65e0\u8bba\u5982\u4f55\u9009\u62e9\u4e3b\u5143\uff0c\u5206\u5272\u64cd\u4f5c\u90fd\u5c06\u5bfc\u81f4\u4e00\u4e2a\u5b50\u6570\u7ec4\u4e3a\u7a7a\uff0c\u53e6\u4e00\u4e2a\u5b50\u6570\u7ec4\u7684\u5927\u5c0f\u4e3a\u539f\u59cb\u6570\u7ec4\u5927\u5c0f\u51cf\u4e00\u3002 \u4e0b\u9762\u662f\u4e00\u4e2a\u5305\u542b10\u4e2a\u6574\u6570\uff081\uff5e10\uff09\u7684\u5217\u8868\uff0c\u6f14\u793a\u4e86\u5bfc\u81f4\u5feb\u901f\u6392\u5e8f\u6700\u574f\u60c5\u51b5\u7684\u8f93\u5165\u6570\u636e\uff1a [ 10 , 9 , 8 , 7 , 6 , 5 , 4 , 3 , 2 , 1 ] \u5728\u8fd9\u4e2a\u793a\u4f8b\u4e2d\uff0c\u6bcf\u6b21\u9009\u62e9\u7684\u4e3b\u5143\u90fd\u662f\u6700\u5927\u7684\u5143\u7d20\uff0810\uff09\uff0c\u5bfc\u81f4\u5206\u5272\u64cd\u4f5c\u4e0d\u65ad\u51cf\u5c11\u6570\u7ec4\u7684\u5927\u5c0f\uff0c\u9012\u5f52\u6df1\u5ea6\u8fbe\u5230\u6700\u5927\uff0c\u65f6\u95f4\u590d\u6742\u5ea6\u4e3a O(n^2) \u3002 \u8981\u907f\u514d\u6700\u574f\u60c5\u51b5\uff0c\u901a\u5e38\u91c7\u7528\u4ee5\u4e0b\u7b56\u7565\uff1a \u9009\u62e9\u5408\u9002\u7684\u4e3b\u5143\uff0c\u4f8b\u5982\u9009\u62e9\u4e2d\u95f4\u5143\u7d20\uff0c\u4ee5\u786e\u4fdd\u5e73\u5747\u5206\u5272\u3002 \u968f\u673a\u9009\u62e9\u4e3b\u5143\uff0c\u4ee5\u51cf\u5c11\u51fa\u73b0\u6700\u574f\u60c5\u51b5\u7684\u6982\u7387\u3002 \u8fd9\u4e9b\u7b56\u7565\u6709\u52a9\u4e8e\u7ef4\u6301\u5feb\u901f\u6392\u5e8f\u7684\u5e73\u5747\u65f6\u95f4\u590d\u6742\u5ea6\u4e3a O(n log n) \u3002 \u5feb\u901f\u6392\u5e8f\u91cc\u7684\u5206\u5272\u64cd\u4f5c\u4f1a\u9009\u62e9\u4e2d\u70b9\u5143\u7d20\u4f5c\u4e3a\u57fa\u51c6\u3002\u8bf7\u63cf\u8ff0\u53e6\u5916\u4e24\u79cd\u9009\u62e9\u57fa\u51c6\u7684\u7b56\u7565\u3002 \u89e3\u7b54\uff1a\u5feb\u901f\u6392\u5e8f\u4e2d\u7684\u5206\u5272\u64cd\u4f5c\u53ef\u4ee5\u9009\u62e9\u4e2d\u70b9\u5143\u7d20\u4f5c\u4e3a\u57fa\u51c6\uff0c\u4f46\u8fd8\u6709\u5176\u4ed6\u4e24\u79cd\u5e38\u89c1\u7684\u9009\u62e9\u57fa\u51c6\u7684\u7b56\u7565\uff0c\u5b83\u4eec\u5206\u522b\u662f\uff1a \u968f\u673a\u9009\u62e9\u57fa\u51c6\uff08Random Pivot\uff09\uff1a\u8fd9\u79cd\u7b56\u7565\u662f\u5728\u5f85\u6392\u5e8f\u6570\u7ec4\u4e2d\u968f\u673a\u9009\u62e9\u4e00\u4e2a\u5143\u7d20\u4f5c\u4e3a\u57fa\u51c6\u3002\u968f\u673a\u9009\u62e9\u57fa\u51c6\u7684\u597d\u5904\u662f\u53ef\u4ee5\u964d\u4f4e\u51fa\u73b0\u6700\u574f\u60c5\u51b5\u7684\u6982\u7387\uff0c\u56e0\u4e3a\u5728\u5927\u591a\u6570\u60c5\u51b5\u4e0b\uff0c\u968f\u673a\u9009\u62e9\u7684\u57fa\u51c6\u4f1a\u6bd4\u56fa\u5b9a\u4f4d\u7f6e\u7684\u57fa\u51c6\u66f4\u5e73\u5747\u5730\u5212\u5206\u6570\u636e\u3002\u8fd9\u53ef\u4ee5\u63d0\u9ad8\u7b97\u6cd5\u7684\u6027\u80fd\u3002 \u4e09\u6570\u53d6\u4e2d\u6cd5\uff08Median-of-Three Pivot\uff09\uff1a\u8fd9\u79cd\u7b56\u7565\u662f\u5728\u5f85\u6392\u5e8f\u6570\u7ec4\u4e2d\u9009\u62e9\u4e09\u4e2a\u5143\u7d20\uff08\u901a\u5e38\u662f\u7b2c\u4e00\u4e2a\u3001\u4e2d\u95f4\u4e00\u4e2a\u548c\u6700\u540e\u4e00\u4e2a\u5143\u7d20\uff09\uff0c\u7136\u540e\u4ece\u8fd9\u4e09\u4e2a\u5143\u7d20\u4e2d\u9009\u62e9\u4e2d\u95f4\u503c\u4f5c\u4e3a\u57fa\u51c6\u3002\u8fd9\u4e2a\u7b56\u7565\u7684\u76ee\u7684\u662f\u5728\u5c3d\u91cf\u907f\u514d\u6700\u574f\u60c5\u51b5\u7684\u540c\u65f6\uff0c\u4fdd\u6301\u57fa\u51c6\u7684\u76f8\u5bf9\u4e2d\u95f4\u4f4d\u7f6e\u3002\u8fd9\u53ef\u4ee5\u63d0\u9ad8\u7b97\u6cd5\u7684\u5e73\u5747\u6027\u80fd\u3002 \u8fd9\u4e09\u79cd\u9009\u62e9\u57fa\u51c6\u7684\u7b56\u7565\u5404\u6709\u4f18\u52a3\uff0c\u4f46\u5b83\u4eec\u7684\u5171\u540c\u76ee\u6807\u662f\u964d\u4f4e\u6700\u574f\u60c5\u51b5\u7684\u6982\u7387\uff0c\u4ece\u800c\u63d0\u9ad8\u5feb\u901f\u6392\u5e8f\u7684\u6027\u80fd\u3002\u5728\u5b9e\u9645\u5e94\u7528\u4e2d\uff0c\u9009\u62e9\u54ea\u79cd\u7b56\u7565\u53d6\u51b3\u4e8e\u5177\u4f53\u7684\u60c5\u51b5\u548c\u5b9e\u73b0\u3002 \u5f53\u5feb\u901f\u6392\u5e8f\u91cc\u7684\u5b50\u5217\u8868\u7684\u957f\u5ea6\u5c0f\u4e8e\u67d0\u4e2a\u6570\u5b57\uff08\u598230\uff09\u65f6\uff0c\u6267\u884c\u63d2\u5165\u6392\u5e8f\u6765\u5904\u7406\u8fd9\u4e2a\u5b50\u5217\u8868\u3002\u8bf7\u8bf4\u660e\u4e3a\u4ec0\u4e48\u8fd9\u662f\u4e00\u4e2a\u597d\u65b9\u6cd5\u3002 \u89e3\u7b54\uff1a\u5728\u5feb\u901f\u6392\u5e8f\u4e2d\uff0c\u5f53\u5b50\u5217\u8868\u7684\u957f\u5ea6\u53d8\u5f97\u5f88\u5c0f\u65f6\uff08\u901a\u5e38\u5c0f\u4e8e\u67d0\u4e2a\u9884\u5b9a\u7684\u9608\u503c\uff0c\u598230\u6216\u5176\u4ed6\u7ecf\u9a8c\u503c\uff09\uff0c\u6267\u884c\u63d2\u5165\u6392\u5e8f\u6765\u5904\u7406\u8fd9\u4e2a\u5b50\u5217\u8868\u662f\u4e00\u4e2a\u597d\u65b9\u6cd5\uff0c\u4e3b\u8981\u57fa\u4e8e\u4ee5\u4e0b\u8003\u8651\uff1a \u63d2\u5165\u6392\u5e8f\u5bf9\u5c0f\u89c4\u6a21\u6570\u636e\u8868\u73b0\u826f\u597d\uff1a\u63d2\u5165\u6392\u5e8f\u662f\u4e00\u79cd\u7b80\u5355\u4f46\u9ad8\u6548\u7684\u6392\u5e8f\u7b97\u6cd5\uff0c\u7279\u522b\u9002\u7528\u4e8e\u5c0f\u89c4\u6a21\u6570\u636e\u96c6\u3002\u5b83\u7684\u65f6\u95f4\u590d\u6742\u5ea6\u4e3a O(n^2) \uff0c\u4f46\u5728\u5b9e\u9645\u5e94\u7528\u4e2d\uff0c\u5bf9\u4e8e\u5c0f\u89c4\u6a21\u7684\u6570\u636e\uff0c\u5b83\u7684\u6027\u80fd\u901a\u5e38\u5f88\u597d\u3002 \u51cf\u5c11\u9012\u5f52\u6df1\u5ea6\uff1a\u5728\u5feb\u901f\u6392\u5e8f\u4e2d\uff0c\u6bcf\u6b21\u9012\u5f52\u8c03\u7528\u90fd\u4f1a\u589e\u52a0\u9012\u5f52\u6df1\u5ea6\uff0c\u800c\u9012\u5f52\u6df1\u5ea6\u8fc7\u5927\u53ef\u80fd\u4f1a\u5bfc\u81f4\u6808\u6ea2\u51fa\u6216\u6027\u80fd\u4e0b\u964d\u3002\u5f53\u5b50\u5217\u8868\u957f\u5ea6\u5c0f\u4e8e\u67d0\u4e2a\u9608\u503c\u65f6\uff0c\u4f7f\u7528\u63d2\u5165\u6392\u5e8f\u53ef\u4ee5\u907f\u514d\u4e0d\u5fc5\u8981\u7684\u9012\u5f52\u6df1\u5ea6\uff0c\u4ece\u800c\u51cf\u5c11\u9012\u5f52\u8c03\u7528\u7684\u6b21\u6570\u3002 \u9002\u7528\u4e8e\u90e8\u5206\u6709\u5e8f\u7684\u5b50\u5217\u8868\uff1a\u5f53\u5b50\u5217\u8868\u5df2\u7ecf\u90e8\u5206\u6709\u5e8f\u65f6\uff0c\u63d2\u5165\u6392\u5e8f\u7684\u6027\u80fd\u901a\u5e38\u6bd4\u5feb\u901f\u6392\u5e8f\u66f4\u597d\u3002\u56e0\u6b64\uff0c\u5bf9\u4e8e\u53ef\u80fd\u5305\u542b\u5df2\u6392\u5e8f\u90e8\u5206\u7684\u5c0f\u5b50\u5217\u8868\uff0c\u4f7f\u7528\u63d2\u5165\u6392\u5e8f\u53ef\u4ee5\u63d0\u9ad8\u7b97\u6cd5\u7684\u6548\u7387\u3002 \u51cf\u5c11\u9012\u5f52\u5f00\u9500\uff1a\u9012\u5f52\u5f00\u9500\u662f\u5feb\u901f\u6392\u5e8f\u7684\u4e00\u4e2a\u4e0d\u53ef\u5ffd\u89c6\u7684\u56e0\u7d20\uff0c\u7279\u522b\u662f\u5728\u5904\u7406\u5c0f\u89c4\u6a21\u5b50\u5217\u8868\u65f6\u3002\u901a\u8fc7\u4f7f\u7528\u63d2\u5165\u6392\u5e8f\u6765\u5904\u7406\u8fd9\u4e9b\u5c0f\u89c4\u6a21\u5b50\u5217\u8868\uff0c\u53ef\u4ee5\u51cf\u5c11\u9012\u5f52\u5f00\u9500\uff0c\u63d0\u9ad8\u7b97\u6cd5\u7684\u6574\u4f53\u6027\u80fd\u3002 \u5c06\u63d2\u5165\u6392\u5e8f\u4e0e\u5feb\u901f\u6392\u5e8f\u7ed3\u5408\u4f7f\u7528\u662f\u4e00\u79cd\u5e38\u89c1\u7684\u4f18\u5316\u7b56\u7565\uff0c\u5b83\u53ef\u4ee5\u5728\u5904\u7406\u5c0f\u89c4\u6a21\u5b50\u5217\u8868\u65f6\u63d0\u9ad8\u7b97\u6cd5\u7684\u6548\u7387\uff0c\u540c\u65f6\u4fdd\u6301\u5feb\u901f\u6392\u5e8f\u7684\u6574\u4f53\u6027\u80fd\u3002\u8fd9\u79cd\u65b9\u6cd5\u88ab\u79f0\u4e3a\u201c\u5feb\u901f\u6392\u5e8f\u7684\u6539\u8fdb\u201d\u6216\u201c\u5feb\u901f\u6392\u5e8f\u7684\u6df7\u5408\u6392\u5e8f\u201d\u7b56\u7565\uff0c\u7528\u4e8e\u5728\u5b9e\u9645\u5e94\u7528\u4e2d\u63d0\u9ad8\u7b97\u6cd5\u7684\u6548\u7387\u3002 \u4e3a\u4ec0\u4e48\u5f52\u5e76\u6392\u5e8f\u5728\u6700\u574f\u60c5\u51b5\u4e0b\u4e5f\u662f\u4e00\u4e2a O(n log n) \u7b97\u6cd5\uff1f \u89e3\u7b54\uff1a\u5f52\u5e76\u6392\u5e8f\u5728\u6700\u574f\u60c5\u51b5\u4e0b\u4ecd\u7136\u5177\u6709 O(n log n) \u7684\u65f6\u95f4\u590d\u6742\u5ea6\uff0c\u8fd9\u662f\u56e0\u4e3a\u5f52\u5e76\u6392\u5e8f\u7684\u7b97\u6cd5\u8bbe\u8ba1\u4f7f\u5176\u80fd\u591f\u7a33\u5b9a\u5730\u4fdd\u6301\u8fd9\u79cd\u6027\u80fd\uff0c\u4e0d\u53d7\u8f93\u5165\u6570\u636e\u5206\u5e03\u7684\u5f71\u54cd\u3002 \u4ee5\u4e0b\u662f\u5f52\u5e76\u6392\u5e8f\u5728\u6700\u574f\u60c5\u51b5\u4e0b\u4ecd\u7136\u5177\u6709 O(n log n) \u65f6\u95f4\u590d\u6742\u5ea6\u7684\u539f\u56e0\uff1a \u5206\u800c\u6cbb\u4e4b\u7b56\u7565\uff1a\u5f52\u5e76\u6392\u5e8f\u91c7\u7528\u4e86\u5206\u800c\u6cbb\u4e4b\u7684\u7b56\u7565\uff0c\u5c06\u95ee\u9898\u5206\u89e3\u4e3a\u8f83\u5c0f\u7684\u5b50\u95ee\u9898\uff0c\u7136\u540e\u5408\u5e76\u8fd9\u4e9b\u5b50\u95ee\u9898\u7684\u89e3\u3002\u8fd9\u4e2a\u7b56\u7565\u786e\u4fdd\u4e86\u7b97\u6cd5\u7684\u9012\u5f52\u6df1\u5ea6\u5728 log n \u7ea7\u522b\uff0c\u56e0\u4e3a\u6bcf\u6b21\u9012\u5f52\u90fd\u5c06\u6570\u636e\u5212\u5206\u6210\u4e24\u534a\uff0c\u76f4\u5230\u6700\u5c0f\u5b50\u95ee\u9898\u7684\u5927\u5c0f\u4e3a1\u3002 \u5408\u5e76\u64cd\u4f5c\u7684\u7ebf\u6027\u65f6\u95f4\uff1a\u5f52\u5e76\u6392\u5e8f\u7684\u5173\u952e\u64cd\u4f5c\u662f\u5408\u5e76\u5df2\u6392\u5e8f\u7684\u5b50\u6570\u7ec4\u3002\u5408\u5e76\u64cd\u4f5c\u7684\u65f6\u95f4\u590d\u6742\u5ea6\u662f\u7ebf\u6027\u7684\uff0c\u4e0e\u8f93\u5165\u6570\u636e\u7684\u89c4\u6a21 n \u6210\u6b63\u6bd4\u3002\u56e0\u6b64\uff0c\u5373\u4f7f\u5728\u5408\u5e76\u9636\u6bb5\uff0c\u7b97\u6cd5\u7684\u603b\u65f6\u95f4\u590d\u6742\u5ea6\u4ecd\u7136\u53d7\u9650\u4e8e O(n log n) \u3002 \u7a33\u5b9a\u6027\uff1a\u5f52\u5e76\u6392\u5e8f\u662f\u4e00\u79cd\u7a33\u5b9a\u6392\u5e8f\u7b97\u6cd5\uff0c\u610f\u5473\u7740\u5b83\u5728\u6392\u5e8f\u76f8\u7b49\u5143\u7d20\u65f6\u4f1a\u4fdd\u6301\u5b83\u4eec\u7684\u76f8\u5bf9\u987a\u5e8f\u3002\u8fd9\u4e00\u6027\u8d28\u4f7f\u5f97\u7b97\u6cd5\u5728\u5904\u7406\u76f8\u7b49\u5143\u7d20\u6216\u8005\u5177\u6709\u7279\u5b9a\u6570\u636e\u5206\u5e03\u7684\u60c5\u51b5\u4e0b\u4ecd\u7136\u4fdd\u6301 O(n log n) \u7684\u6027\u80fd\uff0c\u800c\u4e0d\u4f1a\u51fa\u73b0\u6700\u574f\u60c5\u51b5\u3002 \u65e0\u8bba\u8f93\u5165\u6570\u636e\u5982\u4f55\u5206\u5e03\uff0c\u5f52\u5e76\u6392\u5e8f\u7684\u5206\u5272\u548c\u5408\u5e76\u64cd\u4f5c\u90fd\u662f\u786e\u5b9a\u6027\u7684\uff1a\u5f52\u5e76\u6392\u5e8f\u7684\u6bcf\u4e00\u6b65\u90fd\u662f\u786e\u5b9a\u6027\u7684\uff0c\u4e0d\u53d7\u8f93\u5165\u6570\u636e\u5206\u5e03\u7684\u5f71\u54cd\u3002\u4e0d\u50cf\u5feb\u901f\u6392\u5e8f\u5728\u6700\u574f\u60c5\u51b5\u4e0b\u53ef\u80fd\u51fa\u73b0\u5206\u5272\u6781\u4e0d\u5e73\u8861\u7684\u60c5\u51b5\uff0c\u5bfc\u81f4\u6027\u80fd\u4e0b\u964d\u3002 \u56e0\u6b64\uff0c\u5f52\u5e76\u6392\u5e8f\u5728\u6700\u574f\u60c5\u51b5\u4e0b\u4ecd\u7136\u80fd\u591f\u4fdd\u6301 O(n log n) \u7684\u65f6\u95f4\u590d\u6742\u5ea6\uff0c\u4f7f\u5176\u6210\u4e3a\u4e00\u79cd\u53ef\u9760\u7684\u6392\u5e8f\u7b97\u6cd5\uff0c\u7279\u522b\u9002\u7528\u4e8e\u5bf9\u7a33\u5b9a\u6027\u548c\u6027\u80fd\u6709\u8981\u6c42\u7684\u60c5\u51b5\u3002 3.6.\u6307\u6570\u590d\u6742\u5ea6\u7684\u7b97\u6cd5 \u00b6 \u6590\u6ce2\u90a3\u5951\u9012\u5f52\u7b97\u6cd5 \u00b6 \u4e0b\u9762\u662f\u6590\u6ce2\u90a3\u5951\u9012\u5f52\u7b97\u6cd5\u7684\u4f8b\u5b50\u3002 def fib ( n , depth = 0 ): \"\"\"\u6590\u6ce2\u90a3\u5951\u9012\u5f52\u6570\u5217\"\"\" if n <= 1 : return 1 else : print ( f 'Depth: { depth } ,fib( { n } ) calls fib( { n - 1 } ) and fib( { n - 2 } )' ) return fib ( n - 1 , depth + 1 ) + fib ( n - 2 , depth + 1 ) def main (): fib ( 6 ) if __name__ == \"__main__\" : main () # \u8fd0\u884c\u7ed3\u679c\uff1a # Depth:0,fib(6) calls fib(5) and fib(4) # Depth:1,fib(5) calls fib(4) and fib(3) # Depth:2,fib(4) calls fib(3) and fib(2) # Depth:3,fib(3) calls fib(2) and fib(1) # Depth:4,fib(2) calls fib(1) and fib(0) # Depth:3,fib(2) calls fib(1) and fib(0) # Depth:2,fib(3) calls fib(2) and fib(1) # Depth:3,fib(2) calls fib(1) and fib(0) # Depth:1,fib(4) calls fib(3) and fib(2) # Depth:2,fib(3) calls fib(2) and fib(1) # Depth:3,fib(2) calls fib(1) and fib(0) # Depth:2,fib(2) calls fib(1) and fib(0) \u4e0a\u4f8b\u53ef\u4ee5\u770b\u51fa\uff0c\u6590\u6ce2\u90a3\u5951\u9012\u5f52\u7b97\u6cd5\u7684\u8c03\u7528\u6b21\u6570\u6bd4\u95ee\u9898\u89c4\u6a21\u7684\u5e73\u65b9\u6570\u589e\u957f\u7684\u8fd8\u8981\u5feb\u5f88\u591a\u3002\u4f8b\u5982\uff0c fib(4) \u53ea\u9700\u89814\u6b21\u9012\u5f52\u8c03\u7528\uff0c\u770b\u8d77\u6765\u5b83\u597d\u50cf\u662f\u7ebf\u6027\u589e\u957f\u7684\uff0c\u4f46\u5728\u603b\u5171\u768414\u6b21\u9012\u5f52\u8c03\u7528\u91cc\uff0c fib(6) \u9700\u8981\u8c03\u75282\u6b21 fib(4) \u3002\u968f\u7740\u95ee\u9898\u89c4\u6a21\u7684\u6269\u5927\uff0c\u5de5\u4f5c\u91cf\u4f1a\u663e\u8457\u589e\u52a0\uff0c\u8fd9\u662f\u56e0\u4e3a\u5728\u8c03\u7528\u6811\uff08call tree\uff09\u91cc\u53ef\u80fd\u6709\u5f88\u591a\u91cd\u590d\u7684\u76f8\u540c\u5b50\u6811\u3002 \u5982\u679c\u8fd9\u68f5\u8c03\u7528\u6811\u662f\u5b8c\u5168\u5e73\u8861\u7684\uff0c\u5e76\u4e14\u5b8c\u5168\u586b\u5145\u4e86\u6700\u4e0b\u9762\u7684\u4e24\u5c42\u8c03\u7528\uff0c\u90a3\u4e48\u5f53\u53c2\u6570\u4e3a6\u65f6\uff0c\u4f1a\u67092 + 4 + 8 + 16 = 30\u6b21\u9012\u5f52\u8c03\u7528\u3002\u6bcf\u4e00\u5c42\u91cc\u7684\u6ee1\u8c03\u7528\u6570\u91cf\u90fd\u662f\u5b83\u4e0a\u4e00\u5c42\u76842\u500d\u3002\u56e0\u6b64\uff0c\u5728\u5b8c\u5168\u5e73\u8861\u7684\u8c03\u7528\u6811\u91cc\uff0c\u9012\u5f52\u8c03\u7528\u7684\u603b\u6570\u91cf\u901a\u5e38\u662f 2^(n+1)-2 \uff0c\u5176\u4e2d n \u662f\u8c03\u7528\u6811\u9876\u90e8\uff08\u6839\uff09\u7684\u53c2\u6570\u3002\u8fd9\u662f\u4e00\u4e2a\u6307\u6570\u7ea7\u7684\u589e\u957f\uff0c\u4e5f\u5c31\u662f O(k^n) \u7b97\u6cd5\u3002 \u5c3d\u7ba1\u5728\u9012\u5f52\u6590\u6ce2\u90a3\u5951\u8c03\u7528\u6811\u7684\u5e95\u90e8\u4e24\u5c42\u5e76\u6ca1\u6709\u88ab\u5b8c\u5168\u586b\u5145\u6ee1\uff0c\u4f46\u5b83\u7684\u8c03\u7528\u6811\u5f62\u72b6\u548c\u5b8c\u5168\u5e73\u8861\u7684\u6811\u5df2\u7ecf\u8db3\u591f\u76f8\u8fd1\u4e86\uff0c\u56e0\u6b64\uff0c\u53ef\u4ee5\u628a\u9012\u5f52\u6590\u6ce2\u90a3\u5951\u5f52\u4e3a\u6307\u6570\u7b97\u6cd5\u3002\u7ecf\u8fc7\u8ba1\u7b97\uff0c\u9012\u5f52\u6590\u6ce2\u90a3\u5951\u7684\u5e38\u6570 k \u5927\u7ea6\u662f1.63\u3002 \u6307\u6570\u7b97\u6cd5\u901a\u5e38\u53ea\u9002\u5408\u7528\u4e8e\u975e\u5e38\u5c0f\u7684\u95ee\u9898\u89c4\u6a21\u3002 \u5c06\u6590\u6ce2\u90a3\u5951\u8f6c\u6362\u4e3a\u7ebf\u6027\u7b97\u6cd5 \u00b6 \u4e0b\u9762\u7684\u4ee3\u7801\u7528\u7ebf\u6027\u7b97\u6cd5\u6539\u5199\u4e86\u4e0a\u9762\u7684\u9012\u5f52\u7b97\u6cd5\u3002\u5b83\u7684\u65f6\u95f4\u590d\u6742\u5ea6\u662fO(n)\u3002 def fibonacci_linear ( n ): if n <= 1 : return 1 prev , current = 0 , 1 for _ in range ( 2 , n + 1 ): next_value = prev + current prev , current = current , next_value return current def main (): n = 6 result = fibonacci_linear ( n ) print ( f \"Fibonacci( { n } ) = { result } \" ) if __name__ == \"__main__\" : main () # \u8fd0\u884c\u7ed3\u679c\uff1a # Fibonacci(6) = 8 3.7.\u6848\u4f8b\u7814\u7a76:\u7b97\u6cd5\u5206\u6790\u5668 \u00b6 \u76ee\u6807\uff1a\u7f16\u5199\u4e00\u4e2a\u53ef\u4ee5\u7528\u6765\u5206\u6790\u4e0d\u540c\u6392\u5e8f\u7b97\u6cd5\u7684\u7a0b\u5e8f\u3002 \u9700\u6c42\uff1a \u5206\u6790\u5668\u53ef\u4ee5\u8fd0\u884c\u6392\u5e8f\u7b97\u6cd5\u4ee5\u5bf9\u6570\u5b57\u5217\u8868\u8fdb\u884c\u6392\u5e8f\uff1b \u5206\u6790\u5668\u53ef\u4ee5\u8ffd\u8e2a\u7b97\u6cd5\u7684\u8fd0\u884c\u65f6\u3001\u6bd4\u8f83\u6b21\u6570\u4ee5\u53ca\u6267\u884c\u4ea4\u6362\u7684\u6b21\u6570\uff1b \u5f53\u7b97\u6cd5\u4ea4\u6362\u4e24\u4e2a\u503c\u7684\u65f6\u5019\uff0c\u5206\u6790\u5668\u53ef\u4ee5\u6253\u5370\u51fa\u5217\u8868\u7684\u53d8\u5316\u8f68\u8ff9\uff1b \u5141\u8bb8\u7ed9\u5206\u6790\u5668\u63d0\u4f9b\u81ea\u5b9a\u4e49\u7684\u6570\u5b57\u5217\u8868\uff0c\u6216\u8005\u751f\u6210\u4e00\u4e2a\u5927\u5c0f\u7ed9\u5b9a\u7684\u968f\u673a\u6570\u5b57\u5217\u8868\uff1b\u5141\u8bb8\u5217\u8868\u53ea\u5305\u542b\u4e00\u4e2a\u6570\u5b57\uff0c\u6216\u8005\u5305\u542b\u91cd\u590d\u6570\u503c\uff1b \u5728\u8fd0\u884c\u7b97\u6cd5\u4e4b\u524d\uff0c\u5141\u8bb8\u7528\u6237\u9009\u62e9\u4e0a\u8ff0\u8fd9\u4e9b\u529f\u80fd\uff1b \u5206\u6790\u5668\u7684\u9ed8\u8ba4\u884c\u4e3a\u662f\u5728\u4e00\u4e2a\u5305\u542b10\u4e2a\u4e0d\u91cd\u590d\u6570\u5b57\u7684\u968f\u673a\u5217\u8868\u4e0a\u8fd0\u884c\u7b97\u6cd5\uff0c\u5e76\u8bb0\u5f55\u7b97\u6cd5\u7684\u8fd0\u884c\u65f6\u3001\u6bd4\u8f83\u6b21\u6570\u4ee5\u53ca\u4ea4\u6362\u6b21\u6570\uff1b \u5b9e\u73b0\uff1a \u5206\u6790\u5668\u662f Profiler \u7c7b\u7684\u4e00\u4e2a\u5b9e\u4f8b\u3002\u6211\u4eec\u53ef\u4ee5\u901a\u8fc7\u8fd0\u884c\u5206\u6790\u5668\u91cc\u7684 test \u65b9\u6cd5\u6765\u5206\u6790\u6392\u5e8f\u51fd\u6570\uff0c\u8fd9\u4e2a\u6392\u5e8f\u51fd\u6570\u4f1a\u4f5c\u4e3a\u65b9\u6cd5\u7684\u7b2c\u4e00\u4e2a\u53c2\u6570\uff0c\u4e0a\u9762\u9700\u6c42\u4e2d\u63d0\u5230\u7684\u90a3\u4e9b\u9009\u9879\u4e5f\u4f1a\u4f5c\u4e3a\u53c2\u6570\u540c\u65f6\u4f20\u9012\u7ed9\u8fd9\u4e2a\u65b9\u6cd5\u3002 \u4e24\u4e2a\u6a21\u5757\uff1a profiler \uff1a\u8fd9\u4e2a\u6a21\u5757\u4f1a\u5b9a\u4e49 Profiler \u7c7b\u3002 algorithms \uff1a\u8fd9\u4e2a\u6a21\u5757\u5b9a\u4e49\u9488\u5bf9\u5206\u6790\u5668\u4fee\u6539\u8fc7\u7684\u6392\u5e8f\u51fd\u6570\u3002 import time import random class Profiler ( object ): \"\"\" \u5b9a\u4e49\u4e00\u4e2aProfiler\u7c7b, \u7528\u6765\u5206\u6790\u6392\u5e8f\u7b97\u6cd5\u3002 Profiler\u5bf9\u8c61\u8ddf\u8e2a\u4e00\u4e2a\u5217\u8868\u7684\u6bd4\u8f83\u6b21\u6570\u3001\u4ea4\u6362\u6b21\u6570\u3001\u548c\u8fd0\u884c\u65f6\u95f4\u3002 Profiler\u5bf9\u8c61\u4e5f\u80fd\u8f93\u51fa\u4e0a\u8ff0\u8ffd\u8e2a\u4fe1\u606f, \u5e76\u521b\u5efa\u4e00\u4e2a\u542b\u6709\u91cd\u590d\u6216\u4e0d\u91cd\u590d\u6570\u5b57\u7684\u5217\u8868\u3002 \u793a\u4f8b\uff1a from profiler import Profiler from algorithms import selectionSort p = Profiler() p.test(selectionSort, size = 15, comp = True, exch = True, trace = True) \"\"\" def test ( self , function , lyst = None , size = 10 , unique = True , comp = True , exch = True , trace = False ): \"\"\" function: \u914d\u7f6e\u7684\u7b97\u6cd5 target: \u914d\u7f6e\u7684\u641c\u7d22\u76ee\u6807 lyst: \u5141\u8bb8\u8c03\u7528\u8005\u4f7f\u7528\u7684\u5217\u8868 size: \u5217\u8868\u7684\u5927\u5c0f, \u9ed8\u8ba4\u503c\u662f10 unique: \u5982\u679c\u662fTrue, \u5219\u5217\u8868\u5305\u542b\u4e0d\u91cd\u590d\u7684\u6574\u6570 comp: \u5982\u679c\u662fTrue, \u5219\u7edf\u8ba1\u6bd4\u8f83\u6b21\u6570 exch: \u5982\u679c\u662fTrue, \u5219\u7edf\u8ba1\u4ea4\u6362\u6b21\u6570 trace: \u5982\u679c\u662fTrue, \u5219\u5728\u6bcf\u6b21\u4ea4\u6362\u540e\u90fd\u8f93\u51fa\u5217\u8868\u5185\u5bb9 \u6b64\u51fd\u6570\u4f9d\u636e\u7ed9\u5b9a\u7684\u4e0a\u8ff0\u5c5e\u6027, \u6253\u5370\u8f93\u51fa\u76f8\u5e94\u7684\u7ed3\u679c \"\"\" self . comp = comp self . exch = exch self . trace = trace if lyst != None : self . lyst = lyst elif unique : self . lyst = list ( range ( 1 , size + 1 )) random . shuffle ( self . lyst ) else : self . lyst = [] for count in range ( size ): self . lyst . append ( random . randint ( 1 , size )) self . exchCount = 0 self . cmpCount = 0 self . startClock () function ( self . lyst , self ) self . stopClock () print ( self ) def exchange ( self ): \"\"\"\u7edf\u8ba1\u4ea4\u6362\u6b21\u6570\"\"\" if self . exch : self . exchCount += 1 if self . trace : print ( self . lyst ) def comparison ( self ): \"\"\"\u7edf\u8ba1\u4ea4\u6362\u6b21\u6570\"\"\" if self . comp : self . cmpCount += 1 def startClock ( self ): \"\"\"\u8bb0\u5f55\u5f00\u59cb\u65f6\u95f4\"\"\" self . start = time . time () def stopClock ( self ): \"\"\"\u505c\u6b62\u8ba1\u65f6\u5e76\u4ee5\u79d2\u4e3a\u5355\u4f4d\u8ba1\u7b97\u6d88\u8017\u65f6\u95f4\"\"\" self . elapsedTime = round ( time . time () - self . start , 3 ) def __str__ ( self ): \"\"\"\u4ee5\u5b57\u7b26\u4e32\u65b9\u5f0f\u8fd4\u56de\u7ed3\u679c\"\"\" result = \"Problem size: \" result += str ( len ( self . lyst )) + \" \\n \" result += \"Elapsed time: \" result += str ( self . elapsedTime ) + \" \\n \" if self . comp : result += \"Comparisons: \" result += str ( self . cmpCount ) + \" \\n \" if self . exch : result += \"Exchanges: \" result += str ( self . exchCount ) + \" \\n \" return result def selectionSort ( lyst , profiler ): i = 0 while i < len ( lyst ) - 1 : minIndex = i j = i + 1 while j < len ( lyst ): profiler . comparison () # Count if lyst [ j ] < lyst [ minIndex ]: minIndex = j j += 1 if minIndex != i : swap ( lyst , minIndex , i , profiler ) i += 1 def swap ( lyst , i , j , profiler ): \"\"\"\u4ea4\u6362\u5904\u4e8e\u4f4d\u7f6ei\u548cj\u7684\u5143\u7d20\"\"\" profiler . exchange () # Count temp = lyst [ i ] lyst [ i ] = lyst [ j ] lyst [ j ] = temp def main (): p = Profiler () # \u9ed8\u8ba4\u884c\u4e3a print ( \"The result of p.test(selectionSort)\" ) p . test ( selectionSort ) print ( \"The result of p.test(selectionSort, size=5, trace=True)\" ) p . test ( selectionSort , size = 5 , trace = True ) print ( \"The result of p.test(selectionSort, size=100)\" ) p . test ( selectionSort , size = 100 ) print ( \"The result of p.test(selectionSort, size=1000)\" ) p . test ( selectionSort , size = 1000 ) print ( \"The result of p.test(selectionSort, size=10000, exch=False, comp=False)\" ) p . test ( selectionSort , size = 10000 , exch = False , comp = False ) if __name__ == \"__main__\" : main () # \u8fd0\u884c\u7ed3\u679c\uff1a # The result of p.test(selectionSort) # Problem size: 20 # Elapsed time: 0.0 # Comparisons: 190 # Exchanges: 12 # The result of p.test(selectionSort, size=5, trace=True) # [5, 1, 4, 3, 2, 1, 1, 2, 4, 4] # [1, 5, 4, 3, 2, 1, 1, 2, 4, 4] # [1, 1, 4, 3, 2, 5, 1, 2, 4, 4] # [1, 1, 1, 3, 2, 5, 4, 2, 4, 4] # [1, 1, 1, 2, 3, 5, 4, 2, 4, 4] # [1, 1, 1, 2, 2, 5, 4, 3, 4, 4] # [1, 1, 1, 2, 2, 3, 4, 5, 4, 4] # [1, 1, 1, 2, 2, 3, 4, 4, 5, 4] # Problem size: 10 # Elapsed time: 0.0 # Comparisons: 45 # Exchanges: 8 # The result of p.test(selectionSort, size=100) # Problem size: 200 # Elapsed time: 0.003 # Comparisons: 19900 # Exchanges: 195 # The result of p.test(selectionSort, size=1000) # Problem size: 2000 # Elapsed time: 0.36 # Comparisons: 1999000 # Exchanges: 1992 # The result of p.test(selectionSort, size=10000, exch=False, comp=False) # Problem size: 20000 # Elapsed time: 26.535 3.8.\u5c0f\u7ed3 \u00b6 \u6839\u636e\u6240\u9700\u8981\u7684\u65f6\u95f4\u548c\u5185\u5b58\u8d44\u6e90\uff0c\u6211\u4eec\u53ef\u4ee5\u5bf9\u89e3\u51b3\u540c\u4e00\u4e2a\u95ee\u9898\u7684\u4e0d\u540c\u7b97\u6cd5\u8fdb\u884c\u6392\u540d\u3002\u4e0e\u9700\u8981\u66f4\u591a\u8d44\u6e90\u7684\u7b97\u6cd5\u76f8\u6bd4\uff0c\u6211\u4eec\u901a\u5e38\u8ba4\u4e3a\u8017\u8d39\u66f4\u5c11\u8fd0\u884c\u65f6\u548c\u5360\u7528\u66f4\u5c11\u5185\u5b58\u7684\u7b97\u6cd5\u66f4\u597d\u3002\u4f46\u662f\uff0c\u8fd9\u4e24\u79cd\u8d44\u6e90\u4e5f\u901a\u5e38\u9700\u8981\u8fdb\u884c\u6743\u8861\u53d6\u820d\uff1a\u6709\u65f6\u4ee5\u66f4\u591a\u5185\u5b58\u4e3a\u4ee3\u4ef7\u6765\u6539\u5584\u8fd0\u884c\u65f6\uff1b\u6709\u65f6\u4ee5\u8f83\u6162\u7684\u8fd0\u884c\u65f6\u4f5c\u4e3a\u4ee3\u4ef7\u6765\u63d0\u9ad8\u5185\u5b58\u7684\u4f7f\u7528\u7387\u3002 \u53ef\u4ee5\u6839\u636e\u8ba1\u7b97\u673a\u7684\u65f6\u949f\u6309\u7167\u8fc7\u5f80\u7ecf\u9a8c\u6d4b\u7b97\u7b97\u6cd5\u7684\u8fd0\u884c\u65f6\u3002\u4f46\u662f\uff0c\u8fd9\u4e2a\u65f6\u95f4\u4f1a\u968f\u7740\u786c\u4ef6\u548c\u6240\u7528\u7f16\u7a0b\u8bed\u8a00\u7684\u4e0d\u540c\u800c\u53d8\u5316\u3002 \u7edf\u8ba1\u6307\u4ee4\u7684\u6570\u91cf\u63d0\u4f9b\u4e86\u53e6\u4e00\u79cd\u5bf9\u7b97\u6cd5\u6240\u9700\u5de5\u4f5c\u91cf\u8fdb\u884c\u7ecf\u9a8c\u6027\u5ea6\u91cf\u7684\u65b9\u5f0f\u3002\u6307\u4ee4\u7684\u8ba1\u6570\u53ef\u4ee5\u663e\u793a\u51fa\u7b97\u6cd5\u5de5\u4f5c\u91cf\u7684\u589e\u957f\u7387\u7684\u53d8\u5316\uff0c\u800c\u4e14\u8fd9\u4e2a\u6570\u636e\u548c\u786c\u4ef6\u4ee5\u53ca\u8f6f\u4ef6\u5e73\u53f0\u90fd\u6ca1\u6709\u5173\u7cfb\u3002 \u7b97\u6cd5\u5de5\u4f5c\u91cf\u7684\u589e\u957f\u7387\u53ef\u4ee5\u7528\u57fa\u4e8e\u95ee\u9898\u89c4\u6a21\u7684\u51fd\u6570\u6765\u8868\u793a\u3002\u590d\u6742\u5ea6\u5206\u6790\u67e5\u770b\u7b97\u6cd5\u91cc\u7684\u4ee3\u7801\u4ee5\u5f97\u5230\u8fd9\u4e9b\u6570\u5b66\u8868\u8fbe\u5f0f\uff0c\u4ece\u800c\u8ba9\u7a0b\u5e8f\u5458\u9884\u6d4b\u5728\u4efb\u4f55\u8ba1\u7b97\u673a\u4e0a\u6267\u884c\u8fd9\u4e2a\u7b97\u6cd5\u7684\u6548\u679c\u3002 \u5927O\u8868\u793a\u6cd5\u662f\u7528\u6765\u8868\u793a\u7b97\u6cd5\u8fd0\u884c\u65f6\u884c\u4e3a\u7684\u5e38\u7528\u65b9\u6cd5\u3002\u5b83\u7528 O(f(n)) \u7684\u5f62\u5f0f\u6765\u8868\u793a\u89e3\u51b3\u8fd9\u4e2a\u95ee\u9898\u6240\u9700\u8981\u7684\u5de5\u4f5c\u91cf\uff0c\u5176\u4e2d n \u662f\u7b97\u6cd5\u95ee\u9898\u7684\u89c4\u6a21\u3001 f(n) \u662f\u6570\u5b66\u51fd\u6570\u3002 \u8fd0\u884c\u65f6\u884c\u4e3a\u7684\u5e38\u89c1\u8868\u8fbe\u5f0f\u6709 O(log(n, 2)) \uff08\u5bf9\u6570\uff09\u3001 O(n) \uff08\u7ebf\u6027\uff09\u3001 O(n^2) \uff08\u5e73\u65b9\uff09\u4ee5\u53ca O(k^n) \uff08\u6307\u6570\uff09\u3002 \u7b97\u6cd5\u5728\u6700\u597d\u60c5\u51b5\u3001\u6700\u574f\u60c5\u51b5\u4ee5\u53ca\u5e73\u5747\u60c5\u51b5\u4e0b\u7684\u6027\u80fd\u53ef\u4ee5\u662f\u4e0d\u540c\u7684\u3002\u6bd4\u5982\uff0c\u5192\u6ce1\u6392\u5e8f\u548c\u63d2\u5165\u6392\u5e8f\u5728\u6700\u597d\u60c5\u51b5\u4e0b\u90fd\u662f\u7ebf\u6027\u590d\u6742\u5ea6\uff0c\u4f46\u662f\u5b83\u4eec\u5728\u5e73\u5747\u60c5\u51b5\u548c\u6700\u574f\u60c5\u51b5\u4e0b\u662f\u5e73\u65b9\u9636\u590d\u6742\u5ea6\u3002 \u901a\u5e38\u6765\u8bf4\uff0c\u8981\u63d0\u9ad8\u7b97\u6cd5\u7684\u6027\u80fd\u6700\u597d\u662f\u5c1d\u8bd5\u964d\u4f4e\u5b83\u7684\u8fd0\u884c\u65f6\u590d\u6742\u5ea6\u7684\u9636\u6570\uff0c\u800c\u4e0d\u662f\u5bf9\u4ee3\u7801\u8fdb\u884c\u5fae\u8c03\u3002 \u4e8c\u5206\u641c\u7d22\u4f1a\u6bd4\u987a\u5e8f\u641c\u7d22\u8981\u5feb\u5f97\u591a\u3002\u4f46\u662f\uff0c\u5728\u7528\u4e8c\u5206\u641c\u7d22\u8fdb\u884c\u641c\u7d22\u65f6\uff0c\u6570\u636e\u5fc5\u987b\u662f\u6709\u5e8f\u7684\u3002 nlogn \u6392\u5e8f\u7b97\u6cd5\u901a\u8fc7\u9012\u5f52\u3001\u5206\u6cbb\u6cd5\u7b56\u7565\u6765\u7a81\u7834 n^2 \u7684\u6027\u80fd\u969c\u788d\u3002\u5feb\u901f\u6392\u5e8f\u4f1a\u5728\u57fa\u51c6\u5143\u7d20\u5de6\u53f3\u5bf9\u5176\u4ed6\u5143\u7d20\u91cd\u65b0\u6392\u5217\uff0c\u7136\u540e\u5bf9\u57fa\u51c6\u4e24\u4fa7\u7684\u5b50\u5217\u8868\u9012\u5f52\u5730\u6392\u5e8f\u3002\u5f52\u5e76\u6392\u5e8f\u5219\u4f1a\u628a\u4e00\u4e2a\u5217\u8868\u8fdb\u884c\u62c6\u5206\uff0c\u9012\u5f52\u5730\u5bf9\u6bcf\u4e2a\u90e8\u5206\u8fdb\u884c\u6392\u5e8f\uff0c\u7136\u540e\u5408\u5e76\u51fa\u6700\u7ec8\u7ed3\u679c\u3002 \u6307\u6570\u590d\u6742\u5ea6\u7684\u7b97\u6cd5\u901a\u5e38\u53ea\u5728\u7406\u8bba\u4e0a\u88ab\u5173\u6ce8\uff0c\u5728\u5904\u7406\u5927\u578b\u95ee\u9898\u7684\u65f6\u5019\uff0c\u5b83\u4eec\u662f\u6ca1\u6709\u4f7f\u7528\u4ef7\u503c\u7684\u3002 3.9.\u590d\u4e60\u9898 \u00b6 \u5728\u4e0d\u540c\u95ee\u9898\u89c4\u6a21\u7684\u60c5\u51b5\u4e0b\u8bb0\u5f55\u7b97\u6cd5\u8fd0\u884c\u65f6\uff1a \u53ef\u4ee5\u8ba9\u4f60\u5927\u81f4\u4e86\u89e3\u7b97\u6cd5\u7684\u8fd0\u884c\u65f6\u884c\u4e3a \u53ef\u4ee5\u8ba9\u4f60\u4e86\u89e3\u7b97\u6cd5\u5728\u7279\u5b9a\u786c\u4ef6\u5e73\u53f0\u548c\u7279\u5b9a\u8f6f\u4ef6\u5e73\u53f0\u4e0a\u7684\u8fd0\u884c\u65f6\u884c\u4e3a \u7edf\u8ba1\u6307\u4ee4\u7684\u6570\u91cf\u4f1a\uff1a \u5728\u4e0d\u540c\u7684\u786c\u4ef6\u548c\u8f6f\u4ef6\u5e73\u53f0\u4e0a\u5f97\u5230\u76f8\u540c\u7684\u6570\u636e \u53ef\u4ee5\u8bc1\u660e\u5728\u95ee\u9898\u89c4\u6a21\u5f88\u5927\u7684\u60c5\u51b5\u4e0b\uff0c\u6307\u6570\u7b97\u6cd5\u662f\u6ca1\u6cd5\u4f7f\u7528\u7684 \u8868\u8fbe\u5f0f O(n) \u3001 O(n^2) \u548c O(k^n) \u5206\u522b\u4ee3\u8868\u7684\u590d\u6742\u5ea6\u662f\uff1a \u6307\u6570\u3001\u7ebf\u6027\u548c\u5e73\u65b9 \u7ebf\u6027\u3001\u5e73\u65b9\u548c\u6307\u6570 \u5bf9\u6570\u3001\u7ebf\u6027\u548c\u5e73\u65b9 \u4e8c\u5206\u641c\u7d22\u9700\u8981\u5047\u5b9a\u6570\u636e\uff1a \u6ca1\u6709\u4efb\u4f55\u7279\u522b\u7684\u987a\u5e8f\u5173\u7cfb \u6709\u5e8f\u7684 \u9009\u62e9\u6392\u5e8f\u6700\u591a\u53ef\u4ee5\u6709\uff1a n^2 \u6b21\u6570\u636e\u5143\u7d20\u7684\u4ea4\u6362 n \u6b21\u6570\u636e\u5143\u7d20\u7684\u4ea4\u6362 \u63d2\u5165\u6392\u5e8f\u548c\u4fee\u6539\u540e\u7684\u5192\u6ce1\u6392\u5e8f\u5728\u6700\u597d\u60c5\u51b5\u4e0b\u662f\uff1a \u7ebf\u6027\u7684 \u5e73\u65b9\u7684 \u6307\u6570\u7684 \u6700\u597d\u60c5\u51b5\u3001\u5e73\u5747\u60c5\u51b5\u4ee5\u53ca\u6700\u574f\u60c5\u51b5\u4e0b\u590d\u6742\u5ea6\u90fd\u76f8\u540c\u7684\u7b97\u6cd5\u662f\uff1a \u987a\u5e8f\u641c\u7d22 \u9009\u62e9\u6392\u5e8f \u5feb\u901f\u6392\u5e8f \u4e00\u822c\u6765\u8bf4\uff0c\u4e0b\u9762\u54ea\u4e2a\u9009\u62e9\u66f4\u597d\uff1a \u8c03\u6574\u7b97\u6cd5\u4ece\u800c\u8282\u7701\u82e5\u5e72\u79d2\u7684\u8fd0\u884c\u65f6 \u9009\u62e9\u8ba1\u7b97\u590d\u6742\u5ea6\u66f4\u4f4e\u7684\u7b97\u6cd5 \u5bf9\u4e8e\u9012\u5f52\u6590\u6ce2\u90a3\u5951\u51fd\u6570\uff1a \u95ee\u9898\u89c4\u6a21\u4e3a n \u7684\u65f6\u5019\uff0c\u6709 n^2 \u6b21\u9012\u5f52\u8c03\u7528 \u95ee\u9898\u89c4\u6a21\u4e3a n \u7684\u65f6\u5019\uff0c\u6709 2n \u6b21\u9012\u5f52\u8c03\u7528 \u5b8c\u5168\u586b\u5145\u7684\u4e8c\u53c9\u8c03\u7528\u6811\u91cc\u6bcf\u4e00\u5c42\uff1a \u8c03\u7528\u6b21\u6570\u662f\u4e0a\u4e00\u5c42\u8c03\u7528\u6b21\u6570\u76842\u500d \u4e0e\u4e0a\u4e00\u5c42\u76f8\u540c\u7684\u8c03\u7528\u6b21\u6570 3.10.\u7f16\u7a0b\u7ec3\u4e60 \u00b6 1\uff0e\u5bf9\u4e00\u4e2a\u6709\u5e8f\u5217\u8868\u8fdb\u884c\u987a\u5e8f\u641c\u7d22\uff0c\u5f53\u76ee\u6807\u5c0f\u4e8e\u6709\u5e8f\u5217\u8868\u91cc\u7684\u67d0\u4e2a\u5143\u7d20\u65f6\uff0c\u987a\u5e8f\u641c\u7d22\u53ef\u4ee5\u63d0\u524d\u505c\u6b62\u3002\u5b9a\u4e49\u8fd9\u4e2a\u7b97\u6cd5\u7684\u4fee\u6539\u7248\u672c\uff0c\u5e76\u4f7f\u7528\u5927O\u8868\u793a\u6cd5\u6765\u63cf\u8ff0\u5b83\u5728\u6700\u597d\u60c5\u51b5\u3001\u6700\u574f\u60c5\u51b5\u4ee5\u53ca\u5e73\u5747\u60c5\u51b5\u4e0b\u7684\u8ba1\u7b97\u590d\u6742\u5ea6\u3002 \u89e3\u7b54\uff1a \u5728\u6700\u597d\u7684\u60c5\u51b5\u4e0b\uff0c\u76ee\u6807\u5143\u7d20\u5728\u6709\u5e8f\u5217\u8868\u7684\u7b2c\u4e00\u4e2a\u4f4d\u7f6e\u3002\u5728\u8fd9\u79cd\u60c5\u51b5\u4e0b\uff0c\u51fd\u6570\u53ea\u9700\u8981\u8fdb\u884c\u4e00\u6b21\u6bd4\u8f83\u3002\u6240\u4ee5\uff0c\u6700\u4f73\u60c5\u51b5\u590d\u6742\u5ea6\u4e3a O(1) \u3002 \u5728\u6700\u574f\u7684\u60c5\u51b5\u4e0b\uff0c\u76ee\u6807\u5143\u7d20\u4e0d\u5728\u5217\u8868\u4e2d\uff0c\u5e76\u4e14\u6240\u6709\u5217\u8868\u5143\u7d20\u90fd\u5c0f\u4e8e\u76ee\u6807\u5143\u7d20\u3002\u8fd9\u5c06\u5bfc\u81f4\u51fd\u6570\u904d\u5386\u6574\u4e2a\u5217\u8868\uff0c\u6240\u4ee5\u6700\u574f\u60c5\u51b5\u590d\u6742\u5ea6\u4e3a O(n) \u3002 \u5bf9\u4e8e\u5e73\u5747\u60c5\u51b5\uff0c\u5047\u8bbe\u6709 n \u4e2a\u9879\u5728\u5217\u8868\u4e2d\uff0c\u641c\u7d22\u76ee\u6807\u4f1a\u5728\u5217\u8868\u524d n/2 \u4e2a\u9879\u6216\u8005\u4e0d\u5728\u6240\u6709\u3002\u5728\u8fd9\u4e2a\u7ea6\u5b9a\u4e0b\uff0c\u5e73\u5747\u6211\u4eec\u9700\u8981\u5bfb\u627e n/2 \u4e2a\u9879\uff0c\u56e0\u6b64\u590d\u6742\u5ea6\u4e3a O(n) \u3002\u4e4b\u6240\u4ee5\u662f n/2 \uff0c\u662f\u56e0\u4e3a\u8fd9\u4e2a\u4efb\u52a1\u53ef\u80fd\u4f1a\u5728\u4efb\u4f55\u5730\u65b9\u88ab\u505c\u6b62\uff0c\u6211\u4eec\u5bf9\u6b64\u505a\u5e73\u5747\u5904\u7406\u3002\u7136\u800c\u5728\u5927O\u6807\u8bb0\u6cd5\u4e2d\uff0c\u5e38\u6570\u5c06\u88ab\u9057\u5fd8\uff0c\u6240\u4ee5\u5b83\u4ecd\u7136\u662f O(n) \u3002 \u4ee3\u7801\u5982\u4e0b\uff1a def ordered_sequential_search ( arr , target ): comparisons = 0 # \u7528\u4e8e\u7edf\u8ba1\u6bd4\u8f83\u6b21\u6570 index = 0 while index < len ( arr ): comparisons += 1 if arr [ index ] == target : return comparisons , index # \u627e\u5230\u76ee\u6807\u5e76\u8fd4\u56de\u6bd4\u8f83\u6b21\u6570\u548c\u7d22\u5f15 elif arr [ index ] > target : break # \u5982\u679c\u76ee\u6807\u5c0f\u4e8e\u5f53\u524d\u5143\u7d20\uff0c\u63d0\u524d\u505c\u6b62\u641c\u7d22 index += 1 return comparisons , - 1 # \u6ca1\u627e\u5230\u76ee\u6807\u8fd4\u56de\u6bd4\u8f83\u6b21\u6570\u548c-1 def main (): # \u6d4b\u8bd5 arr = [ 1 , 2 , 3 , 4 , 5 , 6 , 7 , 8 , 9 , 10 ] for target in [ 5 , 11 ]: comparisons , index = ordered_sequential_search ( arr , target ) if index != - 1 : print ( f \"\u76ee\u6807 { target } \u5728\u7d22\u5f15 { index } \u5904\u627e\u5230\uff0c\u6bd4\u8f83\u6b21\u6570\u4e3a { comparisons } \" ) else : print ( f \"\u76ee\u6807 { target } \u672a\u627e\u5230\uff0c\u6bd4\u8f83\u6b21\u6570\u4e3a { comparisons } \" ) if __name__ == \"__main__\" : main () # \u8fd0\u884c\u7ed3\u679c # \u76ee\u6807 5 \u5728\u7d22\u5f15 4 \u5904\u627e\u5230\uff0c\u6bd4\u8f83\u6b21\u6570\u4e3a 5 # \u76ee\u6807 11 \u672a\u627e\u5230\uff0c\u6bd4\u8f83\u6b21\u6570\u4e3a 10 2\uff0e\u5217\u8868\u7684 reverse \u65b9\u6cd5\u7528\u6765\u53cd\u8f6c\u5217\u8868\u91cc\u7684\u5143\u7d20\u3002\u5b9a\u4e49\u4e00\u4e2a\u53eb\u4f5c reverse \u7684\u51fd\u6570\uff0c\u8fd9\u4e2a\u51fd\u6570\u53ef\u4ee5\u5728\u4e0d\u4f7f\u7528 reverse \u65b9\u6cd5\u7684\u60c5\u51b5\u4e0b\uff0c\u53cd\u8f6c\u5217\u8868\u53c2\u6570\u91cc\u7684\u6240\u6709\u5143\u7d20\u3002\u5c1d\u8bd5\u8ba9\u8fd9\u4e2a\u51fd\u6570\u5c3d\u53ef\u80fd\u5730\u9ad8\u6548\uff0c\u5e76\u4f7f\u7528\u5927O\u8868\u793a\u6cd5\u63cf\u8ff0\u5b83\u7684\u8ba1\u7b97\u590d\u6742\u5ea6\u3002 \u89e3\u7b54\uff1a \u53ea\u9700\u8981\u904d\u5386\u5217\u8868\u7684\u4e00\u534a\uff0c\u6211\u4eec\u5c31\u80fd\u5230\u8fbe\u5217\u8868\u7684\u4e2d\u95f4\u4f4d\u7f6e\u628a\u5217\u8868\u4e24\u8fb9\u7684\u5143\u7d20\u4e92\u6362\uff0c\u8fd9\u6837\u5c31\u5b8c\u6210\u4e86\u5217\u8868\u7684\u53cd\u8f6c\u3002 \u8fd9\u4e2a\u7b97\u6cd5\u7684\u65f6\u95f4\u590d\u6742\u5ea6\u662f O(n/2) \uff0c\u5176\u4e2d n \u662f\u5217\u8868\u7684\u957f\u5ea6\u3002\u4f46\u5728\u5927O\u8868\u793a\u6cd5\u4e2d\uff0c\u5e38\u6570\u88ab\u5ffd\u7565\uff0c\u56e0\u6b64\u8be5\u7b97\u6cd5\u7684\u65f6\u95f4\u590d\u6742\u5ea6\u662f O(n) \u3002\u5728\u8fd9\u4e2a\u7b97\u6cd5\u4e2d\uff0c n \u5c31\u4ee3\u8868\u7740\u5217\u8868\u7684\u957f\u5ea6\u3002\u610f\u5473\u7740\u65f6\u95f4\u590d\u6742\u5ea6\u53d7\u5217\u8868\u957f\u5ea6\u7684\u5f71\u54cd\u3002\u5217\u8868\u957f\u5ea6\u6bcf\u589e\u52a0\u4e00\u6b21\uff0c\u6267\u884c\u53cd\u8f6c\u7684\u65f6\u95f4\u5c31\u589e\u52a0\u4e00\u6b21\u3002\u8fd9\u5c31\u662f O(n) \u7684\u6982\u5ff5\u3002 \u8fd9\u4e2a\u51fd\u6570\u7684\u7a7a\u95f4\u590d\u6742\u5ea6\u662f O(1) \uff0c\u56e0\u4e3a\u5b83\u53ea\u662f\u5728\u539f\u5730\u4fee\u6539\u5217\u8868\uff0c\u4e0d\u9700\u8981\u989d\u5916\u7684\u5b58\u50a8\u7a7a\u95f4\u3002 \u4ee3\u7801\u5982\u4e0b\uff1a def custom_reverse ( arr ): left , right = 0 , len ( arr ) - 1 while left < right : arr [ left ], arr [ right ] = arr [ right ], arr [ left ] left += 1 right -= 1 def main (): # \u6d4b\u8bd5\u5217\u8868reverse\u65b9\u6cd5 my_list = [ 1 , 2 , 3 , 4 , 5 ] my_list . reverse () print ( my_list ) # \u6d4b\u8bd5\u81ea\u5b9a\u4e49\u7684reverse\u65b9\u6cd5 my_list = [ 1 , 2 , 3 , 4 , 5 ] custom_reverse ( my_list ) print ( my_list ) if __name__ == \"__main__\" : main () # \u8fd0\u884c\u7ed3\u679c # [5, 4, 3, 2, 1] # [5, 4, 3, 2, 1] 3\uff0ePython\u7684pow\u51fd\u6570\u4f1a\u8fd4\u56de\u6570\u5b57\u7279\u5b9a\u5e42\u6b21\u7684\u7ed3\u679c\u3002\u5b9a\u4e49\u6267\u884c\u8fd9\u4e2a\u4efb\u52a1\u7684expo\u51fd\u6570\uff0c\u5e76\u4f7f\u7528\u5927O\u8868\u793a\u6cd5\u63cf\u8ff0\u5b83\u7684\u8ba1\u7b97\u590d\u6742\u5ea6\u3002\u8fd9\u4e2a\u51fd\u6570\u7684\u7b2c\u4e00\u4e2a\u53c2\u6570\u662f\u6570\u5b57\uff0c\u7b2c\u4e8c\u4e2a\u53c2\u6570\u662f\u6307\u6570\uff08\u975e\u8d1f\u6570\uff09\u3002\u4f60\u53ef\u4ee5\u901a\u8fc7\u5faa\u73af\u6216\u9012\u5f52\u51fd\u6570\u6765\u5b9e\u73b0\uff0c\u4f46\u4e0d\u8981\u4f7f\u7528Python\u5185\u7f6e\u7684**\u8fd0\u7b97\u7b26\u6216\u662fpow\u51fd\u6570\u3002 \u89e3\u7b54\uff1a \u4e0b\u9762\u5b9e\u73b0\u7684 expo \u51fd\u6570\u4f7f\u7528\u5faa\u73af\u6765\u8fde\u7eed\u4e58\u4ee5 base \uff0c\u5faa\u73af\u7684\u6b21\u6570\u7b49\u4e8e exponent \u7684\u503c\u3002 \u65f6\u95f4\u590d\u6742\u5ea6\u662f O(exponent) \uff0c\u5176\u4e2d exponent \u662f\u6307\u6570\u7684\u503c\u3002 \u6700\u597d\u60c5\u51b5\uff1aO(exponent) \u6700\u574f\u60c5\u51b5\uff1aO(exponent) \u5e73\u5747\u60c5\u51b5\uff1aO(exponent) def expo ( base , exponent ): result = 1 for _ in range ( exponent ): result *= base return result def main (): # \u6d4b\u8bd5 base = 2 for exponent in [ 3 , - 3 ]: result = expo ( base , exponent ) print ( f \" { base } \u7684 { exponent } \u6b21\u65b9\u7b49\u4e8e { result } \" ) if __name__ == \"__main__\" : main () # \u8fd0\u884c\u7ed3\u679c # 2 \u7684 3 \u6b21\u65b9\u7b49\u4e8e 8 # 2 \u7684 -3 \u6b21\u65b9\u7b49\u4e8e 1 4\uff0e\u53e6\u4e00\u4e2a\u5b9e\u73b0 expo \u51fd\u6570\u7684\u7b56\u7565\u4f7f\u7528\u4e0b\u9762\u8fd9\u4e2a\u9012\u5f52\u3002\u8bf7\u5b9a\u4e49\u4f7f\u7528\u8fd9\u4e2a\u7b56\u7565\u7684\u9012\u5f52\u51fd\u6570 expo \uff0c\u5e76\u4f7f\u7528\u5927O\u8868\u793a\u6cd5\u63cf\u8ff0\u5b83\u7684\u8ba1\u7b97\u590d\u6742\u5ea6\u3002 expo ( number \uff0c exponent ) = 1 \uff0c \u5f53 exponent = 0 \u7684\u65f6\u5019 = number * expo ( number , exponent \u2212 1 ) \uff0c \u5f53exponent\u4e3a\u5947\u6570\u7684\u65f6\u5019 = ( expo ( number , exponent / 2 )) 2 \uff0c \u5f53exponent\u4e3a\u5076\u6570\u7684\u65f6\u5019 \u89e3\u7b54\uff1a \u4e0b\u9762\u5b9e\u73b0expo\u51fd\u6570\u662f\u901a\u8fc7\u9012\u5f52\u5b9e\u73b0\uff0c\u5e76\u91c7\u7528\u4e86\u5206\u800c\u6cbb\u4e4b\u7684\u7b56\u7565\u3002 \u5982\u679c\u6307\u6570\u662f\u5947\u6570\uff0c\u5c31\u628a\u95ee\u9898\u5206\u89e3\u4e3a\u4e00\u4e2a\u66f4\u5c0f\u7684\u7248\u672c\uff08\u5373 num * num^(exp - 1) \uff09\uff1b \u5982\u679c\u6307\u6570\u662f\u5076\u6570\uff0c\u5219\u53ef\u4ee5\u5c06\u6307\u6570\u5206\u6210\u4e24\u534a\uff0c\u5e76\u53ea\u8ba1\u7b97\u5176\u4e2d\u7684\u4e00\u534a\uff08\u5373 num^(exp / 2) * num^(exp / 2) \uff09\u3002 \u8fd9\u5c31\u5229\u7528\u4e86\u5e42\u7684\u6027\u8d28 a^(m * n) = (a^m)^n \u3002 \u8be5\u9012\u5f52\u5b9e\u73b0\u7684\u65f6\u95f4\u590d\u6742\u5ea6\u4e3a O(log n) \uff0c\u5176\u4e2dn\u4e3a\u6307\u6570\u3002\u8fd9\u662f\u56e0\u4e3a\u5728\u6307\u6570\u4e3a\u5076\u6570\u7684\u60c5\u51b5\u4e0b\uff0c\u6bcf\u6b21\u9012\u5f52\u8c03\u7528\u90fd\u4f1a\u628a\u95ee\u9898\u89c4\u6a21\u7f29\u5c0f\u4e00\u534a\uff0c\u7c7b\u4f3c\u4e8e\u4e8c\u5206\u67e5\u627e\u7b49\u8bfe\u5206\u5272\u95ee\u9898\u3002 \u7a7a\u95f4\u590d\u6742\u5ea6\u4e5f\u662f O(log n) \uff0c\u8fd9\u4e3b\u8981\u662f\u7531\u4e8e\u51fd\u6570\u8c03\u7528\u6808\u7684\u6df1\u5ea6\u5728\u6307\u6570\u4e3a\u5076\u6570\u7684\u60c5\u51b5\u4e0b\uff0c\u4f1a\u53d8\u4e3a\u539f\u6765\u7684\u4e00\u534a\u3002 def expo ( number , exponent ): if exponent <= 0 : return 1 elif exponent % 2 == 1 : # \u5f53 exponent \u4e3a\u5947\u6570 return number * expo ( number , exponent - 1 ) else : # \u5f53 exponent \u4e3a\u5076\u6570 half_expo = expo ( number , exponent // 2 ) return half_expo * half_expo def main (): # \u6d4b\u8bd5 base = 2 for exponent in [ 3 , - 3 ]: result = expo ( base , exponent ) print ( f \" { base } \u7684 { exponent } \u6b21\u65b9\u7b49\u4e8e { result } \" ) if __name__ == \"__main__\" : main () # \u8fd0\u884c\u7ed3\u679c # 2 \u7684 3 \u6b21\u65b9\u7b49\u4e8e 8 # 2 \u7684 -3 \u6b21\u65b9\u7b49\u4e8e 1 5\uff0ePython\u4e2dlist\u91cc\u7684sort\u65b9\u6cd5\u5305\u542b\u4e00\u4e2a\u7528\u5173\u952e\u5b57\u547d\u540d\u7684\u53c2\u6570reverse\uff0c\u5b83\u7684\u9ed8\u8ba4\u503c\u4e3aFalse\u3002\u7a0b\u5e8f\u5458\u53ef\u4ee5\u901a\u8fc7\u8986\u76d6\u8fd9\u4e2a\u503c\u4ee5\u5bf9\u5217\u8868\u8fdb\u884c\u964d\u5e8f\u6392\u5e8f\u3002\u4fee\u6539\u672c\u7ae0\u8ba8\u8bba\u7684selectionSort\u51fd\u6570\uff0c\u4f7f\u5b83\u53ef\u4ee5\u63d0\u4f9b\u8fd9\u4e2a\u9644\u52a0\u53c2\u6570\u6765\u8ba9\u7a0b\u5e8f\u5458\u51b3\u5b9a\u6392\u5e8f\u7684\u65b9\u5411\u3002 \u89e3\u7b54\uff1a \u901a\u8fc7\u6dfb\u52a0\u4e00\u4e2a\u540d\u4e3a reverse \u7684\u53c2\u6570\u6765\u4fee\u6539 selectionSort \u51fd\u6570\uff0c\u4ee5\u4fbf\u8ba9\u7a0b\u5e8f\u5458\u51b3\u5b9a\u6392\u5e8f\u7684\u65b9\u5411\u3002\u5982\u679c reverse \u4e3a True \uff0c\u6392\u5e8f\u5c06\u662f\u964d\u5e8f\u7684\uff0c\u5982\u679c\u4e3a False \uff08\u9ed8\u8ba4\u503c\uff09\uff0c\u6392\u5e8f\u5c06\u662f\u5347\u5e8f\u7684\u3002 \u4e0b\u9762\u662f\u4fee\u6539\u540e\u7684 selectionSort \u51fd\u6570\uff1a def swap ( lyst , i , j ): \"\"\"\u4ea4\u6362\u5143\u7d20\u4f4d\u7f6e\u4e3ai\u548cj\u7684\u5143\u7d20\"\"\" temp = lyst [ i ] lyst [ i ] = lyst [ j ] lyst [ j ] = temp def selectionSort ( lyst , reverse = False ): \"\"\"\u5b9e\u73b0\u4ea4\u6362\u6392\u5e8f\u7b97\u6cd5\uff0c\u53ef\u4ee5\u9009\u62e9\u5347\u5e8f\u6216\u964d\u5e8f\u6392\u5e8f\"\"\" i = 0 while i < len ( lyst ) - 1 : # \u5b9e\u73b0n-1\u6b21\u641c\u7d22 index = i # \u6700\u5c0f\u6216\u6700\u5927\u5143\u7d20\u4f4d\u7f6e j = i + 1 while j < len ( lyst ): # \u5411\u540e\u904d\u5386\u641c\u7d22\uff0c\u66f4\u65b0\u6700\u5c0f\u6216\u6700\u5927\u5143\u7d20\u4f4d\u7f6e if not reverse : if ( lyst [ j ] < lyst [ index ]): index = j else : if ( lyst [ j ] > lyst [ index ]): index = j j += 1 if index != i : # \u5982\u679c\u9700\u8981\uff0c\u5219\u4ea4\u6362\u5143\u7d20\u4f4d\u7f6e swap ( lyst , index , i ) i += 1 def main (): myList = [ 9 , 4 , 2 , 7 , 6 , 8 , 1 ] print ( \"Before selection sort \" , myList ) selectionSort ( myList ) print ( \"After selection sort \" , myList ) if __name__ == \"__main__\" : main () # \u8fd0\u884c\u7ed3\u679c\uff1a # Before selection sort [9, 4, 2, 7, 6, 8, 1] # After selection sort [1, 2, 4, 6, 7, 8, 9] 6\uff0e\u4fee\u6539\u9012\u5f52\u6590\u6ce2\u90a3\u5951\u51fd\u6570\uff0c\u8ba9\u5b83\u652f\u6301\u672c\u7ae0\u91cc\u8ba8\u8bba\u8fc7\u7684\u8bb0\u5fc6\u5316\u6280\u672f\u3002\u8fd9\u4e2a\u51fd\u6570\u5e94\u6dfb\u52a0\u4e00\u4e2a\u5b57\u5178\u7c7b\u578b\u7684\u53c2\u6570\u3002\u5b83\u7684\u9876\u5c42\u8c03\u7528\u4f1a\u63a5\u6536\u4e00\u4e2a\u7a7a\u5b57\u5178\u4f5c\u4e3a\u53c2\u6570\uff0c\u8fd9\u4e2a\u5b57\u5178\u7684\u952e\u548c\u503c\u5e94\u8be5\u662f\u9012\u5f52\u8c03\u7528\u6240\u4f20\u9012\u7684\u53c2\u6570\u548c\u8ba1\u7b97\u51fa\u7684\u503c\u3002\u4e4b\u540e\uff0c\u7528\u672c\u7ae0\u8ba8\u8bba\u8fc7\u7684\u8ba1\u6570\u5668\u5bf9\u8c61\u5bf9\u9012\u5f52\u8c03\u7528\u7684\u6570\u91cf\u8fdb\u884c\u7edf\u8ba1\u3002 \u89e3\u7b54\uff1a \u4e0b\u9762\u662f\u4e00\u4e2a\u4fee\u6539\u540e\u7684\u7248\u672c\uff0c\u5b83\u4f7f\u7528\u4e00\u4e2a\u5b57\u5178\uff08\u7f13\u5b58\uff09\u6765\u5b58\u50a8\u5df2\u8ba1\u7b97\u7684\u7ed3\u679c\uff0c\u5e76\u4e14\u6dfb\u52a0\u4e86\u4e00\u4e2a\u8ba1\u6570\u5668\u5bf9\u8c61\u6765\u7edf\u8ba1\u9012\u5f52\u8c03\u7528\u6b21\u6570\u3002\u8fd9\u4e2a\u4ee3\u7801\u4f1a\u8f93\u51fa\u6307\u5b9a\u9879\u6570\u7684\u6590\u6ce2\u90a3\u5951\u6570\u4ee5\u53ca\u9012\u5f52\u8c03\u7528\u7684\u603b\u6b21\u6570\u3002\u8bb0\u5fc6\u5316\u6280\u672f\u53ef\u4ee5\u663e\u8457\u63d0\u9ad8\u6590\u6ce2\u90a3\u5951\u51fd\u6570\u7684\u6027\u80fd\uff0c\u907f\u514d\u4e86\u91cd\u590d\u8ba1\u7b97\u3002 class Counter : def __init__ ( self ): self . count = 0 def increment ( self ): self . count += 1 def fib ( n , cache , counter ): \"\"\"\u6590\u6ce2\u90a3\u5951\u9012\u5f52\u6570\u5217\uff0c\u5e26\u6709\u8bb0\u5fc6\u5316\u548c\u8c03\u7528\u8ba1\u6570\u5668\"\"\" if n in cache : return cache [ n ] counter . increment () if n <= 1 : result = 1 else : result = fib ( n - 1 , cache , counter ) + fib ( n - 2 , cache , counter ) cache [ n ] = result return result def main (): n = 10 # \u4f60\u53ef\u4ee5\u8bbe\u7f6e\u4e0d\u540c\u7684\u6590\u6ce2\u90a3\u5951\u6570\u5217\u9879\u6570 cache = {} # \u7528\u4e8e\u7f13\u5b58\u5df2\u8ba1\u7b97\u7ed3\u679c\u7684\u5b57\u5178 counter = Counter () # \u7528\u4e8e\u8ba1\u6570\u9012\u5f52\u8c03\u7528\u6b21\u6570\u7684\u8ba1\u6570\u5668\u5bf9\u8c61 result = fib ( n , cache , counter ) print ( f \"Fibonacci( { n } ) = { result } \" ) print ( f \"Total recursive calls: { counter . count } \" ) if __name__ == \"__main__\" : main () # \u8fd0\u884c\u7ed3\u679c\uff1a # Fibonacci(10) = 89 # Total recursive calls: 11 7\uff0e\u5206\u6790\u4e0a\u9762\u6590\u6ce2\u90a3\u5951\u6570\u5217\u91cc\u5b9a\u4e49\u7684\u8bb0\u5fc6\u5316\u6590\u6ce2\u90a3\u5951\u51fd\u6570\u7684\u6027\u80fd\uff0c\u7edf\u8ba1\u8fd9\u4e2a\u51fd\u6570\u9012\u5f52\u8c03\u7528\u7684\u6b21\u6570\u3002\u4f7f\u7528\u5927O\u8868\u793a\u6cd5\u63cf\u8ff0\u5b83\u7684\u8ba1\u7b97\u590d\u6742\u5ea6\uff0c\u5e76\u8bc1\u660e\u4f60\u7684\u7b54\u6848\u662f\u5408\u7406\u7684\u3002 \u89e3\u7b54\uff1a \u5728\u4e0a\u9762\u7684\u8bb0\u5fc6\u5316\u6590\u6ce2\u90a3\u5951\u51fd\u6570\u4e2d\uff0c\u6211\u4eec\u4f7f\u7528\u4e86\u8bb0\u5fc6\u5316\u6280\u672f\u6765\u907f\u514d\u91cd\u590d\u8ba1\u7b97\u3002\u8fd9\u79cd\u4f18\u5316\u4f1a\u663e\u8457\u51cf\u5c11\u8ba1\u7b97\u65f6\u95f4\uff0c\u56e0\u4e3a\u6bcf\u4e2a\u6590\u6ce2\u90a3\u5951\u6570\u53ea\u4f1a\u88ab\u8ba1\u7b97\u4e00\u6b21\u3002 \u8ba1\u7b97\u590d\u6742\u5ea6\u5206\u6790\uff1a \u8bb0\u5fc6\u5316\u6590\u6ce2\u90a3\u5951\u51fd\u6570\u7684\u8ba1\u7b97\u590d\u6742\u5ea6\u662f O(n) \u3002\u8fd9\u662f\u56e0\u4e3a\u5b83\u9700\u8981\u8ba1\u7b97\u6590\u6ce2\u90a3\u5951\u6570\u5217\u7684\u524d n \u9879\uff0c\u6bcf\u4e00\u9879\u53ea\u9700\u8ba1\u7b97\u4e00\u6b21\uff0c\u7136\u540e\u5b58\u50a8\u5728\u7f13\u5b58\u4e2d\u3002\u56e0\u6b64\uff0c\u603b\u5171\u6267\u884c\u7684\u8ba1\u7b97\u91cf\u4e0e n \u6210\u6b63\u6bd4\uff0c\u5373 O(n) \u3002 \u9012\u5f52\u8c03\u7528\u6b21\u6570\uff1a \u9012\u5f52\u8c03\u7528\u7684\u6b21\u6570\u53d6\u51b3\u4e8e\u8f93\u5165\u53c2\u6570 n \u3002\u5bf9\u4e8e\u6590\u6ce2\u90a3\u5951\u6570\u5217\uff0c\u9012\u5f52\u8c03\u7528\u7684\u6b21\u6570\u5927\u81f4\u7b49\u4e8e n \u3002\u56e0\u4e3a\u6bcf\u4e2a\u9879\u9700\u8981\u8ba1\u7b97\u4e00\u6b21\uff0c\u6240\u4ee5\u9012\u5f52\u8c03\u7528\u7684\u6b21\u6570\u4e0e\u8ba1\u7b97\u7684\u9879\u6570\u662f\u4e00\u81f4\u7684\u3002 \u6240\u4ee5\uff0c\u8fd9\u4e2a\u8bb0\u5fc6\u5316\u6590\u6ce2\u90a3\u5951\u51fd\u6570\u7684\u8ba1\u7b97\u590d\u6742\u5ea6\u662f O(n) \uff0c\u800c\u9012\u5f52\u8c03\u7528\u7684\u6b21\u6570\u4e5f\u5927\u81f4\u7b49\u4e8e n \u3002\u8fd9\u4e2a\u6027\u80fd\u662f\u76f8\u5bf9\u8f83\u597d\u7684\uff0c\u56e0\u4e3a\u5b83\u907f\u514d\u4e86\u6307\u6570\u7ea7\u522b\u7684\u91cd\u590d\u8ba1\u7b97\uff0c\u800c\u662f\u7ebf\u6027\u5730\u8ba1\u7b97\u6590\u6ce2\u90a3\u5951\u6570\u5217\u7684\u5404\u9879\u3002 8\uff0e\u51fd\u6570makeRandomList\u4f1a\u521b\u5efa\u5e76\u8fd4\u56de\u4e00\u4e2a\u7ed9\u5b9a\u5927\u5c0f\uff08\u5b83\u7684\u53c2\u6570\uff09\u7684\u6570\u5b57\u5217\u8868\u3002\u5217\u8868\u91cc\u7684\u6570\u5b57\u6ca1\u6709\u91cd\u590d\uff0c\u5b83\u4eec\u7684\u8303\u56f4\u4e3a1\uff5esize\uff0c\u4f4d\u7f6e\u662f\u968f\u673a\u7684\u3002\u4e0b\u9762\u662f\u8fd9\u4e2a\u51fd\u6570\u7684\u4ee3\u7801\u3002\u53ef\u4ee5\u5047\u5b9arange\u3001randint\u548cappend\u51fd\u6570\u90fd\u662f\u5e38\u6570\u65f6\u95f4\u7684\u590d\u6742\u5ea6\u3002\u8fd8\u53ef\u4ee5\u5047\u8bberandom.randint\u968f\u7740\u53c2\u6570\u4e4b\u95f4\u5dee\u503c\u7684\u589e\u52a0\u800c\u66f4\u5c11\u5730\u8fd4\u56de\u91cd\u590d\u7684\u6570\u5b57\u3002\u4f7f\u7528\u5927O\u8868\u793a\u6cd5\u63cf\u8ff0\u8fd9\u4e2a\u51fd\u6570\u7684\u8ba1\u7b97\u590d\u6742\u5ea6\uff0c\u5e76\u8bc1\u660e\u4f60\u7684\u7b54\u6848\u662f\u5408\u7406\u7684\u3002 def makeRandomList ( size ): lyst = [] for count in range ( size ): while True : number = random . randint ( 1 , size ) if not number in lyst : lyst . append ( number ) break return lyst \u89e3\u7b54\uff1a \u8fd9\u4e2a\u51fd\u6570\u7684\u8ba1\u7b97\u590d\u6742\u5ea6\u53d6\u51b3\u4e8e\u5b83\u7684\u5185\u90e8\u5faa\u73af\uff0c\u8be5\u5faa\u73af\u4f1a\u4e0d\u65ad\u751f\u6210\u968f\u673a\u6570\uff0c\u5e76\u68c0\u67e5\u5b83\u662f\u5426\u5df2\u7ecf\u5728\u5217\u8868 lyst \u4e2d\u3002\u5177\u4f53\u5206\u6790\u5982\u4e0b\uff1a \u521b\u5efa\u4e00\u4e2a\u7a7a\u5217\u8868 lyst \uff0c\u65f6\u95f4\u590d\u6742\u5ea6\u4e3a O(1)\u3002 \u8fdb\u5165 for \u5faa\u73af\uff0c\u5faa\u73af\u6b21\u6570\u4e3a size \uff0c\u65f6\u95f4\u590d\u6742\u5ea6\u4e3a O(size)\u3002 \u5728\u5185\u90e8 while \u5faa\u73af\u4e2d\uff0c\u751f\u6210\u4e00\u4e2a\u968f\u673a\u6570 number \uff0c\u6700\u574f\u60c5\u51b5\u4e0b\u9700\u8981\u751f\u6210 size \u6b21\u968f\u673a\u6570\u624d\u80fd\u627e\u5230\u4e00\u4e2a\u4e0d\u5728 lyst \u4e2d\u7684\u6570\u5b57\u3002\u8fd9\u90e8\u5206\u7684\u65f6\u95f4\u590d\u6742\u5ea6\u4e3a O(size)\u3002 \u7efc\u4e0a\u6240\u8ff0\uff0c\u8fd9\u4e2a\u51fd\u6570\u7684\u603b\u4f53\u65f6\u95f4\u590d\u6742\u5ea6\u4e3a O(size^2)\u3002\u8fd9\u662f\u56e0\u4e3a\u5728\u6700\u574f\u60c5\u51b5\u4e0b\uff0c\u6bcf\u6b21\u751f\u6210\u7684\u968f\u673a\u6570\u90fd\u9700\u8981\u68c0\u67e5\u662f\u5426\u5728 lyst \u4e2d\uff0c\u800c\u968f\u673a\u6570\u7684\u751f\u6210\u53ef\u80fd\u9700\u8981\u591a\u6b21\u624d\u80fd\u751f\u6210\u4e00\u4e2a\u4e0d\u5728\u5217\u8868\u4e2d\u7684\u6570\u5b57\u3002 \u9700\u8981\u6ce8\u610f\u7684\u662f\uff0c\u968f\u7740 size \u7684\u589e\u52a0\uff0c\u5185\u90e8\u5faa\u73af\u7684\u8fed\u4ee3\u6b21\u6570\u4e5f\u4f1a\u589e\u52a0\uff0c\u5bfc\u81f4\u65f6\u95f4\u590d\u6742\u5ea6\u5448\u4e8c\u6b21\u589e\u957f\u3002\u56e0\u6b64\uff0c\u8fd9\u4e2a\u51fd\u6570\u7684\u6027\u80fd\u5728\u5927\u89c4\u6a21\u6570\u636e\u4e0a\u53ef\u80fd\u4f1a\u53d7\u5230\u9650\u5236\u3002\u5982\u679c\u9700\u8981\u66f4\u597d\u7684\u6027\u80fd\uff0c\u53ef\u4ee5\u8003\u8651\u5176\u4ed6\u7b97\u6cd5\uff0c\u4ee5\u907f\u514d\u91cd\u590d\u68c0\u67e5\u548c\u751f\u6210\u968f\u673a\u6570\u3002 import random def makeRandomList ( size ): lyst = [] for count in range ( size ): while True : number = random . randint ( 1 , size ) if not number in lyst : lyst . append ( number ) break print ( \"count=\" , count , \"list=\" , lyst ) return lyst def main (): print ( \"final list=\" , makeRandomList ( 10 )) if __name__ == \"__main__\" : main () # \u8fd0\u884c\u7ed3\u679c\uff1a # count= 0 list= [2] # count= 1 list= [2, 10] # count= 2 list= [2, 10, 9] # count= 3 list= [2, 10, 9, 5] # count= 4 list= [2, 10, 9, 5, 3] # count= 5 list= [2, 10, 9, 5, 3, 4] # count= 6 list= [2, 10, 9, 5, 3, 4, 8] # count= 7 list= [2, 10, 9, 5, 3, 4, 8, 7] # count= 8 list= [2, 10, 9, 5, 3, 4, 8, 7, 6] # count= 9 list= [2, 10, 9, 5, 3, 4, 8, 7, 6, 1] # final list= [2, 10, 9, 5, 3, 4, 8, 7, 6, 1] 9\uff0e\u4fee\u6539quicksort\u51fd\u6570\uff0c\u8ba9\u5b83\u53ef\u4ee5\u5bf9\u4efb\u4f55\u5c3a\u5bf8\u5c0f\u4e8e50\u7684\u5b50\u5217\u8868\u8c03\u7528\u63d2\u5165\u6392\u5e8f\u3002\u4f7f\u7528\u670950\u3001500\u548c5000\u4e2a\u5143\u7d20\u7684\u6570\u636e\u96c6\u6bd4\u8f83\u8fd9\u4e2a\u7248\u672c\u4e0e\u539f\u59cb\u7248\u672c\u7684\u6027\u80fd\u3002\u7136\u540e\u8c03\u6574\u8fd9\u4e2a\u9608\u503c\uff0c\u4ece\u800c\u786e\u5b9a\u4f7f\u7528\u63d2\u5165\u6392\u5e8f\u7684\u6700\u4f73\u8bbe\u7f6e\u3002 \u89e3\u7b54\uff1a \u53ef\u4ee5\u5728 quicksortHelper \u51fd\u6570\u4e2d\u6dfb\u52a0\u4e00\u4e2a\u6761\u4ef6\uff0c\u68c0\u67e5\u5b50\u5217\u8868\u7684\u5927\u5c0f\u3002\u7136\u540e\u518d\u4fee\u6539 quicksort \u51fd\u6570\uff0c\u5b9e\u73b0\u5728\u5c0f\u4e8e50\u7684\u5b50\u5217\u8868\u4e0a\u4f7f\u7528\u63d2\u5165\u6392\u5e8f\u3002 \u5982\u679c\u5b50\u5217\u8868\u7684\u5927\u5c0f\u5c0f\u4e8e50\uff0c\u5c31\u4f7f\u7528\u63d2\u5165\u6392\u5e8f\u7b97\u6cd5\uff0c\u5426\u5219\u4f7f\u7528\u5feb\u901f\u6392\u5e8f\u7b97\u6cd5\u3002\u4e0b\u9762\u662f\u4fee\u6539\u540e\u7684\u4ee3\u7801\uff1a import random def swap ( lyst , i , j ): \"\"\"\u4ea4\u6362\u5143\u7d20\u4f4d\u7f6e\u4e3ai\u548cj\u7684\u5143\u7d20\"\"\" temp = lyst [ i ] lyst [ i ] = lyst [ j ] lyst [ j ] = temp def quicksort ( lyst ): quicksortHelper ( lyst , 0 , len ( lyst ) - 1 ) def quicksortHelper ( lyst , left , right ): if left < right : # \u68c0\u67e5\u5b50\u5217\u8868\u7684\u5927\u5c0f\u662f\u5426\u5c0f\u4e8e50 if right - left < 50 : # \u5982\u679c\u5c0f\u4e8e50\uff0c\u4f7f\u7528\u63d2\u5165\u6392\u5e8f insertionSort ( lyst , left , right ) else : pivotLocation = partition ( lyst , left , right ) quicksortHelper ( lyst , left , pivotLocation - 1 ) quicksortHelper ( lyst , pivotLocation + 1 , right ) def partition ( lyst , left , right ): \"\"\"\u5bf9\u5217\u8868\u8fdb\u884c\u5206\u533a\"\"\" # \u627e\u5230\u57fa\u51c6\u5143\u7d20\uff08pivot\uff09\uff0c\u5e76\u548c\u6700\u540e\u4e00\u4e2a\u5143\u7d20\u4e92\u6362 middle = ( left + right ) // 2 pivot = lyst [ middle ] lyst [ middle ] = lyst [ right ] lyst [ right ] = pivot # \u8bbe\u5b9a\u8fb9\u754c\u5143\u7d20\uff08boundary point\uff09\uff0c\u521d\u59cb\u662f\u7b2c\u4e00\u4e2a\u5143\u7d20 boundary = left print ( \"pivot: \" , pivot , \"boundary: \" , lyst [ boundary ]) # \u628a\u6240\u6709\u5c0f\u4e8e\u57fa\u51c6\u7684\u5143\u7d20\u90fd\u79fb\u52a8\u5230\u8fb9\u754c\u7684\u5de6\u8fb9 for index in range ( left , right ): if lyst [ index ] < pivot : swap ( lyst , index , boundary ) boundary += 1 # \u4ea4\u6362\u57fa\u51c6\u5143\u7d20\u548c\u8fb9\u754c\u5143\u7d20 swap ( lyst , right , boundary ) print ( lyst ) return boundary def insertionSort ( lyst , left , right ): \"\"\"\u63d2\u5165\u6392\u5e8f\u7b97\u6cd5\"\"\" for i in range ( left + 1 , right + 1 ): currentElement = lyst [ i ] j = i while j > left and currentElement < lyst [ j - 1 ]: lyst [ j ] = lyst [ j - 1 ] j -= 1 lyst [ j ] = currentElement def main ( size = 20 , sort = quicksort ): lyst = [ random . randint ( 1 , size ) for _ in range ( size )] print ( \"Before sorted\" , lyst ) sort ( lyst ) print ( \"After sorted\" , lyst ) if __name__ == \"__main__\" : main () # \u8fd0\u884c\u7ed3\u679c\uff1a # Before sorted [1, 3, 6, 14, 9, 6, 14, 15, 17, 13, 4, 3, 1, 13, 11, 16, 2, 4, 6, 2] # After sorted [1, 1, 2, 2, 3, 3, 4, 4, 6, 6, 6, 9, 11, 13, 13, 14, 14, 15, 16, 17] 10\uff0e\u8ba1\u7b97\u673a\u4f7f\u7528\u540d\u4e3a\u8c03\u7528\u6808\u7684\u7ed3\u6784\u6765\u4e3a\u9012\u5f52\u51fd\u6570\u7684\u8c03\u7528\u63d0\u4f9b\u652f\u6301\u3002\u4e00\u822c\u800c\u8a00\uff0c\u8ba1\u7b97\u673a\u4f1a\u4e3a\u51fd\u6570\u7684\u6bcf\u6b21\u8c03\u7528\u90fd\u4fdd\u7559\u4e00\u5b9a\u6570\u91cf\u7684\u5185\u5b58\u3002\u56e0\u6b64\uff0c\u53ef\u4ee5\u5bf9\u9012\u5f52\u51fd\u6570\u4f7f\u7528\u7684\u5185\u5b58\u6570\u91cf\u8fdb\u884c\u590d\u6742\u5ea6\u5206\u6790\u3002\u8bf7\u8bf4\u660e\u9012\u5f52\u9636\u4e58\u51fd\u6570\u548c\u9012\u5f52\u6590\u6ce2\u90a3\u5951\u51fd\u6570\u4f7f\u7528\u7684\u5185\u5b58\u7684\u8ba1\u7b97\u590d\u6742\u5ea6\u3002 \u89e3\u7b54\uff1a \u9012\u5f52\u9636\u4e58\u51fd\u6570\u548c\u9012\u5f52\u6590\u6ce2\u90a3\u5951\u51fd\u6570\u4f7f\u7528\u7684\u5185\u5b58\u7684\u8ba1\u7b97\u590d\u6742\u5ea6\u90fd\u4e0e\u9012\u5f52\u7684\u6df1\u5ea6\uff08\u9012\u5f52\u8c03\u7528\u7684\u5c42\u6570\uff09\u76f8\u5173\u3002\u9012\u5f52\u51fd\u6570\u6bcf\u6b21\u8c03\u7528\u90fd\u4f1a\u5728\u8c03\u7528\u6808\u4e2d\u5206\u914d\u4e00\u5b9a\u6570\u91cf\u7684\u5185\u5b58\uff0c\u5305\u62ec\u51fd\u6570\u7684\u53c2\u6570\u3001\u5c40\u90e8\u53d8\u91cf\u4ee5\u53ca\u8fd4\u56de\u5730\u5740\u7b49\u4fe1\u606f\u3002 \u9012\u5f52\u9636\u4e58\u51fd\u6570\u7684\u5185\u5b58\u590d\u6742\u5ea6\uff1a \u9012\u5f52\u9636\u4e58\u51fd\u6570\u662f\u4e00\u4e2a\u975e\u5e38\u7b80\u5355\u7684\u9012\u5f52\u51fd\u6570\uff0c\u5b83\u53ea\u9700\u8981\u4fdd\u5b58\u4e00\u4e2a\u6574\u6570\u53c2\u6570 n \u548c\u8fd4\u56de\u5730\u5740\u3002\u56e0\u6b64\uff0c\u5b83\u7684\u5185\u5b58\u590d\u6742\u5ea6\u662f O(1)\uff0c\u4e0e\u8f93\u5165\u53c2\u6570 n \u7684\u5927\u5c0f\u65e0\u5173\u3002\u6bcf\u4e2a\u9012\u5f52\u8c03\u7528\u90fd\u53ea\u9700\u8981\u5e38\u6570\u7ea7\u522b\u7684\u5185\u5b58\u7a7a\u95f4\u3002 \u9012\u5f52\u6590\u6ce2\u90a3\u5951\u51fd\u6570\u7684\u5185\u5b58\u590d\u6742\u5ea6\uff1a \u9012\u5f52\u6590\u6ce2\u90a3\u5951\u51fd\u6570\u7684\u5185\u5b58\u590d\u6742\u5ea6\u53d6\u51b3\u4e8e\u9012\u5f52\u7684\u6df1\u5ea6\u3002\u6bcf\u4e2a\u9012\u5f52\u8c03\u7528\u90fd\u9700\u8981\u4fdd\u5b58\u4e24\u4e2a\u6574\u6570\u53c2\u6570 n \u548c depth \uff0c\u4ee5\u53ca\u8fd4\u56de\u5730\u5740\u3002\u56e0\u6b64\uff0c\u6bcf\u6b21\u9012\u5f52\u8c03\u7528\u9700\u8981\u7684\u5185\u5b58\u7a7a\u95f4\u662f\u5e38\u6570\u7ea7\u522b\u7684\u3002 \u9012\u5f52\u6590\u6ce2\u90a3\u5951\u51fd\u6570\u7684\u9012\u5f52\u6df1\u5ea6\u53d6\u51b3\u4e8e\u8f93\u5165\u53c2\u6570 n \u3002\u5177\u4f53\u6765\u8bf4\uff0c\u9012\u5f52\u6df1\u5ea6\u7b49\u4e8e n \u3002\u56e0\u6b64\uff0c\u9012\u5f52\u6590\u6ce2\u90a3\u5951\u51fd\u6570\u7684\u5185\u5b58\u590d\u6742\u5ea6\u662f O(n)\uff0c\u4e0e\u8f93\u5165\u53c2\u6570 n \u6210\u6b63\u6bd4\u3002 \u603b\u7ed3\u6765\u8bf4\uff0c\u9012\u5f52\u9636\u4e58\u51fd\u6570\u7684\u5185\u5b58\u590d\u6742\u5ea6\u662f O(1)\uff0c\u800c\u9012\u5f52\u6590\u6ce2\u90a3\u5951\u51fd\u6570\u7684\u5185\u5b58\u590d\u6742\u5ea6\u662f O(n)\u3002\u5728\u9012\u5f52\u7b97\u6cd5\u4e2d\uff0c\u5185\u5b58\u590d\u6742\u5ea6\u901a\u5e38\u4e0e\u9012\u5f52\u6df1\u5ea6\u6210\u6b63\u6bd4\uff0c\u56e0\u6b64\u9700\u8981\u8c28\u614e\u5904\u7406\u9012\u5f52\u8c03\u7528\uff0c\u4ee5\u907f\u514d\u51fa\u73b0\u6808\u6ea2\u51fa\u7b49\u95ee\u9898\u3002\u53ef\u4ee5\u4f7f\u7528\u8fed\u4ee3\u6216\u52a8\u6001\u89c4\u5212\u7b49\u65b9\u6cd5\u6765\u964d\u4f4e\u5185\u5b58\u6d88\u8017\u3002","title":"\u641c\u7d22\u3001\u6392\u5e8f\u4ee5\u53ca\u590d\u6742\u5ea6\u5206\u6790"},{"location":"python/DataStructure/03_TimeComplexity/#3","text":"\u7b97\u6cd5\u63cf\u8ff0\u4e86\u4e00\u4e2a\u968f\u7740\u95ee\u9898\u88ab\u89e3\u51b3\u800c\u505c\u6b62\u7684\u8ba1\u7b97\u8fc7\u7a0b\u3002 \u7b97\u6cd5\u662f\u8ba1\u7b97\u673a\u7a0b\u5e8f\u7684\u57fa\u672c\u7ec4\u6210\u90e8\u5206\u4e4b\u4e00\uff0c\u53e6\u4e00\u4e2a\u57fa\u672c\u7ec4\u6210\u90e8\u5206\u662f\u6570\u636e\u7ed3\u6784\u3002 \u5728\u7b97\u6cd5\u6267\u884c\u8fc7\u7a0b\u4e2d\u4f1a\u6d88\u8017\u4e24\u4e2a\u8d44\u6e90\uff1a\u5904\u7406\u5bf9\u8c61\u6240\u9700\u7684\u65f6\u95f4\u548c\u7a7a\u95f4\uff08\u4e5f\u5c31\u662f\u5185\u5b58\uff09\u3002\u5bf9\u4e8e\u7b97\u6cd5\u6765\u8bf4\uff0c\u603b\u4f1a\u8ffd\u6c42\u6d88\u8017\u66f4\u77ed\u7684\u65f6\u95f4\u548c\u5360\u7528\u66f4\u5c11\u7684\u7a7a\u95f4\u3002\u5728\u9009\u62e9\u7b97\u6cd5\u65f6\uff0c\u901a\u5e38\u5728\u7a7a\u95f4/\u65f6\u95f4\u4e4b\u95f4\u8fdb\u884c\u6743\u8861\u3002 \u7b97\u6cd5\u8d28\u91cf\u7684\u4e3b\u8981\u8bc4\u4f30\u6807\u51c6\uff1a \u6b63\u786e\u6027\uff0c\u5373\u7b97\u6cd5\u80fd\u591f\u771f\u6b63\u89e3\u51b3\u6240\u9488\u5bf9\u7684\u95ee\u9898\uff1b \u53ef\u8bfb\u6027\u548c\u6613\u4e8e\u7ef4\u62a4\u6027\uff1b \u8fd0\u884c\u65f6\u6027\u80fd\uff1b \u76ee\u6807\uff1a \u6839\u636e\u95ee\u9898\u7684\u89c4\u6a21\u786e\u5b9a\u7b97\u6cd5\u5de5\u4f5c\u91cf\u7684\u589e\u957f\u7387\uff1b \u4f7f\u7528\u5927O\u8868\u793a\u6cd5\u6765\u63cf\u8ff0\u7b97\u6cd5\u7684\u8fd0\u884c\u65f6\u548c\u5185\u5b58\u4f7f\u7528\u60c5\u51b5\uff1b \u8ba4\u8bc6\u5e38\u89c1\u7684\u5de5\u4f5c\u91cf\u589e\u957f\u7387\u6216\u590d\u6742\u5ea6\u7684\u7c7b\u522b\uff08\u5e38\u6570\u3001\u5bf9\u6570\u3001\u7ebf\u6027\u3001\u5e73\u65b9\u548c\u6307\u6570\uff09\uff1b \u5c06\u7b97\u6cd5\u8f6c\u6362\u4e3a\u590d\u6742\u5ea6\u4f4e\u4e00\u4e2a\u6570\u91cf\u7ea7\u7684\u66f4\u5feb\u7684\u7248\u672c\uff1b \u63cf\u8ff0\u987a\u5e8f\u641c\u7d22\u7b97\u6cd5\u548c\u4e8c\u5206\u641c\u7d22\u7b97\u6cd5\u7684\u5de5\u4f5c\u65b9\u5f0f\uff1b \u63cf\u8ff0\u9009\u62e9\u6392\u5e8f\u7b97\u6cd5\u548c\u5feb\u901f\u6392\u5e8f\u7b97\u6cd5\u7684\u5de5\u4f5c\u65b9\u5f0f\u3002","title":"3.\u641c\u7d22\u3001\u6392\u5e8f\u4ee5\u53ca\u590d\u6742\u5ea6\u5206\u6790"},{"location":"python/DataStructure/03_TimeComplexity/#31","text":"\u8861\u91cf\u7b97\u6cd5\u65f6\u95f4\u6210\u672c\u7684\u4e24\u79cd\u65b9\u6cd5\uff1a \u7528\u8ba1\u7b97\u673a\u65f6\u949f\u5f97\u5230\u7b97\u6cd5\u5b9e\u9645\u7684\u8fd0\u884c\u65f6\u3002\u8fd9\u4e2a\u8fc7\u7a0b\u88ab\u79f0\u4e3a\u57fa\u51c6\u6d4b\u8bd5\uff08benchmarking\uff09\u6216\u6027\u80fd\u5206\u6790\uff08profiling\uff09\u3002\u9884\u6d4b\u7b97\u6cd5\u6267\u884c\u7684\u62bd\u8c61\u5de5\u4f5c\u91cf\u4f9d\u8d56\u4e8e\u7279\u5b9a\u7684\u786c\u4ef6\u6216\u8f6f\u4ef6\u5e73\u53f0\u3002 \u5728\u4e0d\u540c\u95ee\u9898\u89c4\u6a21\u4e0b\uff0c\u7edf\u8ba1\u9700\u8981\u6267\u884c\u7684\u6307\u4ee4\u6570\u3002\u9884\u6d4b\u7b97\u6cd5\u6267\u884c\u7684\u62bd\u8c61\u5de5\u4f5c\u91cf\u9002\u7528\u4e8e\u4e0d\u540c\u7684\u786c\u4ef6\u6216\u8f6f\u4ef6\u5e73\u53f0\u3002","title":"3.1.\u8861\u91cf\u7b97\u6cd5\u7684\u6548\u7387"},{"location":"python/DataStructure/03_TimeComplexity/#311","text":"import time problemSize = 10000000 print ( \" %12s%16s \" % ( \"Problem Size\" , \"Seconds\" )) for count in range ( 5 ): \"\"\" \u5728\u4e00\u4e2a\u5faa\u73af\u4e2d\uff0c\u5c06\u95ee\u9898\u89c4\u6a21\u7ffb\u500d5\u6b21\uff0c\u8bb0\u5f55\u7b97\u6cd5\u6bcf\u6b21\u8fd0\u884c\u65f6\u95f4\u3002 \"\"\" start = time . time () # \u7b97\u6cd5\u5f00\u59cb work = 1 for x in range ( problemSize ): work += 1 work -= 1 # \u7b97\u6cd5\u7ed3\u675f elapsed = time . time () - start print ( \" %12d%16.3f \" % ( problemSize , elapsed )) problemSize *= 2 # \u8fd0\u884c\u7ed3\u679c\uff1a # Problem Size Seconds # 10000000 0.689 # 20000000 1.367 # 40000000 2.644 # 80000000 5.296 # 160000000 10.622 \u4e0a\u8ff0\u6d4b\u8bd5\u7a0b\u5e8f\u4f7f\u7528\u4e86 time \u6a21\u5757\u91cc\u7684 time() \u51fd\u6570\u6765\u8bb0\u5f55\u8fd0\u884c\u65f6\uff0c\u5373 time.time() \u3002\u8fd9\u4e2a\u51fd\u6570\u4f1a\u8fd4\u56de\u8ba1\u7b97\u673a\u7684\u5f53\u524d\u65f6\u95f4\u548c1970\u5e741\u67081\u65e5\uff3b\u4e5f\u79f0\u4e3a\u7eaa\u5143\uff08epoch\uff09\uff3d\u76f8\u5dee\u7684\u79d2\u6570\u3002\u4e24\u6b21\u8c03\u7528 time.time() \u7684\u7ed3\u679c\u4e4b\u95f4\u7684\u5dee\u503c\u5c31\u4ee3\u8868\u4e86\u4e2d\u95f4\u7ecf\u5386\u4e86\u591a\u5c11\u79d2\u3002 \u4e0a\u8ff0\u6d4b\u8bd5\u7a0b\u5e8f\u5728\u6bcf\u6b21\u5faa\u73af\u7684\u65f6\u5019\u90fd\u4f1a\u6267\u884c\u4e24\u4e2a\u6269\u5c55\u7684\u8d4b\u503c\u8bed\u53e5\uff0c\u4e5f\u5c31\u662f\u6bcf\u6b21\u90fd\u6267\u884c\u7684\u5de5\u4f5c\u91cf\u662f\u56fa\u5b9a\u7684\uff0c\u4f1a\u6d88\u8017\u4e86\u4e00\u5b9a\u7684\u65f6\u95f4\u3002 \u4fee\u6539\u4e0a\u8ff0\u7b97\u6cd5\uff0c\u6211\u4eec\u53ef\u4ee5\u4ece\u4e0b\u9762\u7684\u8fd0\u884c\u7ed3\u679c\u770b\u51fa\uff0c\u5f53 problemSize \u4e3a 1,000 \u65f6\uff0c\u7b97\u6cd5\u7684\u6d88\u8017\u65f6\u95f4\u5c31\u5df2\u7ecf\u8d85\u8fc7\u4e86\u539f\u5148\u7b97\u6cd5\uff0c\u6211\u4eec\u53ef\u4ee5\u63a8\u65ad\u51fa\u7ee7\u7eed\u6d4b\u8bd5 problemSize \u4e3a 10,000,000 \u7684\u8017\u65f6\u5df2\u7ecf\u53d8\u5f97\u4e0d\u5b9e\u9645\u4e86\u3002 import time problemSize = 1000 print ( \" %12s%16s \" % ( \"Problem Size\" , \"Seconds\" )) for count in range ( 5 ): start = time . time () # \u7b97\u6cd5\u5f00\u59cb work = 1 for x in range ( problemSize ): for y in range ( problemSize ): work += 1 work -= 1 # \u7b97\u6cd5\u7ed3\u675f elapsed = time . time () - start print ( \" %12d%16.3f \" % ( problemSize , elapsed )) problemSize *= 2 # \u8fd0\u884c\u7ed3\u679c\uff1a # Problem Size Seconds # 1000 0.093 # 2000 0.350 # 4000 1.280 # 8000 5.004 # 16000 20.020 \u4e0d\u540c\u7684\u786c\u4ef6\u5e73\u53f0\u4f1a\u6709\u4e0d\u540c\u7684\u5904\u7406\u901f\u5ea6\uff0c\u7b97\u6cd5\u7684\u8fd0\u884c\u65f6\u4f1a\u56e0\u673a\u5668\u7684\u4e0d\u540c\u800c\u5b58\u5728\u5dee\u5f02\u3002 \u7a0b\u5e8f\u7684\u8fd0\u884c\u65f6\u4e5f\u4f1a\u968f\u7740\u5b83\u548c\u786c\u4ef6\u4e4b\u95f4\u7684\u64cd\u4f5c\u7cfb\u7edf\u7c7b\u578b\u7684\u4e0d\u540c\u800c\u53d8\u5316\u3002 \u4e0d\u540c\u7684\u7f16\u7a0b\u8bed\u8a00\u548c\u7f16\u8bd1\u5668\u751f\u6210\u7684\u4ee3\u7801\u7684\u6027\u80fd\u4e5f\u4f1a\u6709\u6240\u4e0d\u540c\uff0c\u56e0\u6b64\uff0c\u5728\u67d0\u4e00\u4e2a\u786c\u4ef6\u6216\u8f6f\u4ef6\u5e73\u53f0\u4e0a\u6d4b\u5f97\u7684\u8fd0\u884c\u65f6\u7ed3\u679c\u901a\u5e38\u4e0d\u80fd\u7528\u6765\u9884\u6d4b\u5728\u5176\u4ed6\u5e73\u53f0\u4e0a\u7684\u6027\u80fd\u3002 \u7528\u975e\u5e38\u5927\u7684\u6570\u636e\u96c6\u786e\u5b9a\u7b97\u6cd5\u7684\u8fd0\u884c\u65f6\u662f\u975e\u5e38\u4e0d\u5207\u5b9e\u9645\u7684\u3002\u5bf9\u4e8e\u67d0\u4e9b\u7b97\u6cd5\u6765\u8bf4\uff0c\u4e0d\u8bba\u662f\u7f16\u8bd1\u7684\u4ee3\u7801\u8fd8\u662f\u786c\u4ef6\u5904\u7406\u5668\u7684\u901f\u5ea6\u6709\u591a\u5feb\uff0c\u90fd\u6ca1\u6709\u4efb\u4f55\u7684\u533a\u522b\uff0c\u56e0\u4e3a\u5b83\u4eec\u5728\u4efb\u4f55\u8ba1\u7b97\u673a\u4e0a\u90fd\u6ca1\u529e\u6cd5\u5904\u7406\u975e\u5e38\u5927\u7684\u6570\u636e\u96c6\u3002","title":"3.1.1.\u8861\u91cf\u7b97\u6cd5\u7684\u8fd0\u884c\u65f6"},{"location":"python/DataStructure/03_TimeComplexity/#312","text":"\u7edf\u8ba1\u6307\u4ee4\u6570\u65f6\uff0c\u7edf\u8ba1\u7684\u662f\u7f16\u5199\u7b97\u6cd5\u7684\u9ad8\u7ea7\u8bed\u8a00\u91cc\u7684\u6307\u4ee4\u6570\uff0c\u800c\u4e0d\u662f\u53ef\u6267\u884c\u673a\u5668\u8bed\u8a00\u7a0b\u5e8f\u91cc\u7684\u6307\u4ee4\u6570\u3002 \u901a\u8fc7\u8fd9\u79cd\u65b9\u5f0f\u5bf9\u7b97\u6cd5\u8fdb\u884c\u5206\u6790\u65f6\uff0c\u628a\u5b83\u5206\u6210\u4e24\u4e2a\u90e8\u5206\uff1a \u65e0\u8bba\u95ee\u9898\u7684\u89c4\u6a21\u5982\u4f55\u53d8\u5316\uff0c\u6307\u4ee4\u6267\u884c\u7684\u6b21\u6570\u603b\u662f\u76f8\u540c\u7684\uff1b\u6211\u4eec\u5ffd\u7565\u8fd9\u79cd\u7c7b\u578b\uff0c\u56e0\u4e3a\u5206\u6790\u6548\u7387\u65f6\u5b83\u4eec\u7684\u4f5c\u7528\u5e76\u4e0d\u660e\u663e\u3002 \u6267\u884c\u7684\u6307\u4ee4\u6570\u968f\u7740\u95ee\u9898\u89c4\u6a21\u7684\u53d8\u5316\u800c\u53d8\u5316\uff1b\u6211\u4eec\u91cd\u70b9\u5173\u6ce8\u8fd9\u79cd\u7c7b\u578b\uff0c\u8fd9\u79cd\u7c7b\u578b\u7684\u6307\u4ee4\u901a\u5e38\u53ef\u4ee5\u5728\u5faa\u73af\u6216\u8005\u9012\u5f52\u51fd\u6570\u91cc\u627e\u5230\u3002 \u6211\u4eec\u6765\u6539\u5199\u4e0a\u9762\u7684\u4f8b\u5b50\uff0c\u4ece\u7edf\u8ba1\u8fd0\u884c\u65f6\u95f4\u53d8\u4e3a\u7edf\u8ba1\u8fed\u4ee3\u6b21\u6570\u3002 \u4e0b\u9762\u7684\u7b97\u6cd5\u4e2d\uff0c\u8fed\u4ee3\u6b21\u6570\u548c\u95ee\u9898\u89c4\u6a21\u662f\u76f8\u7b49\u7684\u3002 import time problemSize = 10000000 print ( \" %12s%16s \" % ( \"Problem Size\" , \"Seconds\" )) for count in range ( 5 ): number = 0 # \u7b97\u6cd5\u5f00\u59cb work = 1 for x in range ( problemSize ): number += 1 work += 1 work -= 1 # \u7b97\u6cd5\u7ed3\u675f print ( \" %12d%16.3f \" % ( problemSize , Iterations )) problemSize *= 2 # \u8fd0\u884c\u7ed3\u679c\uff1a # Problem Size Iterations # 10000000 10000000.000 # 20000000 20000000.000 # 40000000 40000000.000 # 80000000 80000000.000 # 160000000 160000000.000 \u4e0b\u9762\u7684\u7b97\u6cd5\u4e2d\uff0c\u8fed\u4ee3\u6b21\u6570\u548c\u95ee\u9898\u89c4\u6a21\u7684\u5e73\u65b9\u3002\u8fd9\u5c31\u89e3\u91ca\u4e86\u4e3a\u4ec0\u4e48\u8fd9\u4e2a\u7b97\u6cd5\u7684\u8017\u65f6\u975e\u5e38\u5927\u3002 import time problemSize = 1000 print ( \" %12s%16s \" % ( \"Problem Size\" , \"Seconds\" )) for count in range ( 5 ): number = 0 # \u7b97\u6cd5\u5f00\u59cb work = 1 for x in range ( problemSize ): for y in range ( problemSize ): number += 1 work += 1 work -= 1 # \u7b97\u6cd5\u7ed3\u675f print ( \" %12d%16.3f \" % ( problemSize , number )) problemSize *= 2 # \u8fd0\u884c\u7ed3\u679c\uff1a # Problem Size Iterations # 1000 1000000.000 # 2000 4000000.000 # 4000 16000000.000 # 8000 64000000.000 # 16000 256000000.000 \u5728\u4e0b\u9762\u7684\u6590\u6ce2\u90a3\u5951\u9012\u5f52\u7684\u4f8b\u5b50\u4e2d\uff0c\u51fd\u6570 fib(problemSize, counter) \u4e2d counter \u53c2\u6570\u662f\u4e00\u4e2a\u5bf9\u8c61\uff0c\u6bcf\u6b21\u9012\u5f52\u8c03\u7528\u7684\u65f6\u5019\uff0c\u90fd\u4f1a\u521b\u5efa\u4e00\u4e2a\u65b0\u7684\u8ba1\u6570\u5668\u5bf9\u8c61\u3002 \u4ece\u4e0b\u9762\u7684\u8fd0\u884c\u7ed3\u679c\u53ef\u4ee5\u770b\u51fa\uff0c\u968f\u7740\u95ee\u9898\u89c4\u6a21\uff08Problem Size\uff09\u7684\u7ffb\u500d\uff0c\u6307\u4ee4\u6570\uff08\u9012\u5f52\u8c03\u7528\u7684\u6b21\u6570\uff09\u5728\u4e00\u5f00\u59cb\u7684\u65f6\u5019\u7f13\u6162\u589e\u957f\uff0c\u968f\u540e\u8fc5\u901f\u52a0\u5feb\u3002 \u7edf\u8ba1\u6307\u4ee4\u6570\u662f\u6b63\u786e\u7684\u601d\u8def\uff0c\u4f46\u4ee5\u8fd9\u79cd\u65b9\u5f0f\u8fdb\u884c\u8ddf\u8e2a\u8ba1\u6570\u7684\u95ee\u9898\u5728\u4e8e\uff0c\u5bf9\u4e8e\u67d0\u4e9b\u7b97\u6cd5\u6765\u8bf4\uff0c\u5982\u679c\u95ee\u9898\u89c4\u6a21\u975e\u5e38\u5927\uff0c\u8ba1\u7b97\u673a\u65e0\u6cd5\u4ee5\u8db3\u591f\u5feb\u7684\u901f\u5ea6\u8fd0\u884c\uff0c\u5e76\u5728\u4e00\u5b9a\u65f6\u95f4\u5185\u5f97\u5230\u7ed3\u679c\u3002 class Counter ( object ): \"\"\"Models a counter.\"\"\" # Class variable instances = 0 #Constructor def __init__ ( self ): \"\"\"Sets up the counter.\"\"\" Counter . instances += 1 self . reset () # Mutator methods def reset ( self ): \"\"\"Sets the counter to 0.\"\"\" self . _value = 0 def increment ( self , amount = 1 ): \"\"\"Adds amount to the counter.\"\"\" self . _value += amount def decrement ( self , amount = 1 ): \"\"\"Subtracts amount from the counter.\"\"\" self . _value -= amount # Accessor methods def getValue ( self ): \"\"\"Returns the counter's value.\"\"\" return self . _value def __str__ ( self ): \"\"\"Returns the string representation of the counter.\"\"\" return str ( self . _value ) def __eq__ ( self , other ): \"\"\"Returns True if self equals other or False otherwise.\"\"\" if self is other : return True if type ( self ) != type ( other ): return False return self . _value == other . _value def fib ( n , counter ): \"\"\"\u7edf\u8ba1\u6590\u6ce2\u90a3\u5951\u51fd\u6570\u88ab\u5916\u90e8\u8c03\u7528\u7684\u6b21\u6570\"\"\" counter . increment () if n < 3 : return 1 else : return fib ( n - 1 , counter ) + fib ( n - 2 , counter ) problemSize = 2 print ( \" %12s%15s \" % ( \"Problem Size\" , \"Calls\" )) for count in range ( 5 ): \"\"\"\u968f\u7740\u95ee\u9898\u89c4\u6a21\u589e\u52a0\uff0c\u8f93\u51fa\u6590\u6ce2\u90a3\u5951\u9012\u5f52\u51fd\u6570\u88ab\u5916\u90e8\u8c03\u7528\u7684\u6b21\u6570\"\"\" counter = Counter () # \u7b97\u6cd5\u5f00\u59cb fib ( problemSize , counter ) # \u7b97\u6cd5\u7ed3\u675f print ( \" %12d%15s \" % ( problemSize , counter )) problemSize *= 2 # \u8fd0\u884c\u7ed3\u679c\uff1a # Problem Size Calls # 2 1 # 4 5 # 8 41 # 16 1973 # 32 4356617","title":"3.1.2.\u7edf\u8ba1\u6307\u4ee4\u6570"},{"location":"python/DataStructure/03_TimeComplexity/#313","text":"\u5bf9\u4e8e\u7b97\u6cd5\u6240\u7528\u8d44\u6e90\u7684\u5206\u6790\u4e5f\u9700\u8981\u5305\u542b\u5b83\u6240\u9700\u7684\u5185\u5b58\u91cf\u7684\u5206\u6790\u3002\u548c\u524d\u9762\u7c7b\u4f3c\u7684\u95ee\u9898\u4e5f\u4f1a\u5b58\u5728\uff0c\u4e00\u4e9b\u7b97\u6cd5\u4f1a\u968f\u7740\u95ee\u9898\u89c4\u6a21\u53d8\u5927\u800c\u9700\u8981\u989d\u5916\u66f4\u591a\u7684\u5185\u5b58\u3002","title":"3.1.3.\u8861\u91cf\u7b97\u6cd5\u4f7f\u7528\u7684\u5185\u5b58"},{"location":"python/DataStructure/03_TimeComplexity/#314","text":"\u7f16\u5199\u4e00\u4e2a\u6d4b\u8bd5\u7a0b\u5e8f\uff0c\u8fd9\u4e2a\u7a0b\u5e8f\u7edf\u8ba1\u5e76\u663e\u793a\u51fa\u4e0b\u9762\u8fd9\u4e2a\u5faa\u73af\u7684\u8fed\u4ee3\u6b21\u6570\u3002 while problemSize > 0 : problemSize = problemSize // 2 \u89e3\u7b54\uff1a def count_iterations ( problemSize ): iterations = 0 # \u521d\u59cb\u5316\u8ba1\u6570\u5668 while problemSize > 0 : problemSize = problemSize // 2 iterations += 1 # \u6bcf\u6b21\u5faa\u73af\u8fed\u4ee3\uff0c\u8ba1\u6570\u5668\u52a0\u4e00 return iterations problemSize = 1000 # \u8bbe\u7f6e\u95ee\u9898\u89c4\u6a21 iterations = count_iterations ( problemSize ) print ( f \"Problem Size: { problemSize } \" ) print ( f \"Iterations: { iterations } \" ) # \u8fd0\u884c\u7ed3\u679c\uff1a # Problem Size: 1000 # Iterations: 10 \u5728\u95ee\u9898\u89c4\u6a21\u5206\u522b\u4e3a1000\u30012000\u30014000\u300110000\u548c100000\u65f6\uff0c\u8fd0\u884c\u5728\u7ec3\u4e601\u91cc\u6240\u521b\u5efa\u7684\u7a0b\u5e8f\u3002\u5f53\u95ee\u9898\u89c4\u6a21\u7ffb\u500d\u6216\u662f\u4e58\u4ee510\u65f6\uff0c\u8fed\u4ee3\u6b21\u6570\u4f1a\u5982\u4f55\u53d8\u5316\uff1f \u89e3\u7b54\uff1a\u5206\u522b\u4ee5\u4e0d\u540c\u7684\u95ee\u9898\u89c4\u6a21\u8fd0\u884c\u4e0a\u9762\u7684\u4ee3\u7801\uff0c\u7ed3\u679c\u5982\u4e0b\uff1a Problem Size : 1000 Iterations : 10 Problem Size : 4000 Iterations : 12 Problem Size : 8000 Iterations : 13 Problem Size : 10000 Iterations : 14 Problem Size : 100000 Iterations : 17 \u4e24\u6b21\u8c03\u7528\u51fd\u6570 time.time() \u7684\u7ed3\u679c\u4e4b\u5dee\u5c31\u662f\u8fd0\u884c\u65f6\u3002\u7531\u4e8e\u64cd\u4f5c\u7cfb\u7edf\u4e5f\u53ef\u80fd\u4f1a\u5728\u8fd9\u6bb5\u65f6\u95f4\u5185\u4f7f\u7528CPU\uff0c\u56e0\u6b64\u8fd9\u4e2a\u8fd0\u884c\u65f6\u53ef\u80fd\u5e76\u4e0d\u80fd\u53cd\u6620\u51faPython\u4ee3\u7801\u4f7f\u7528CPU\u7684\u5b9e\u9645\u65f6\u95f4\u3002\u6d4f\u89c8Python\u6587\u6863\uff0c\u627e\u51fa\u53e6\u4e00\u79cd\u53ef\u4ee5\u5b8c\u6574\u8bb0\u5f55\u5904\u7406\u65f6\u95f4\u7684\u65b9\u6cd5\uff0c\u5e76\u63cf\u8ff0\u5982\u4f55\u5b9e\u73b0\u5b83\u3002 \u89e3\u7b54\uff1a \u5728Python\u4e2d\uff0c time \u6a21\u5757\u63d0\u4f9b\u4e86\u66f4\u7cbe\u786e\u7684\u8ba1\u65f6\u529f\u80fd\uff0c\u5176\u4e2d\u7684 time.perf_counter() \u51fd\u6570\u53ef\u4ee5\u7528\u6765\u6d4b\u91cf\u65f6\u95f4\u7684\u7cbe\u786e\u95f4\u9694\u3002\u4e0e time.time() \u4e0d\u540c\uff0c time. perf_counter() \u4f1a\u5728\u5927\u591a\u6570\u5e73\u53f0\u4e0a\u63d0\u4f9b\u4e00\u4e2a\u66f4\u9ad8\u5206\u8fa8\u7387\u7684\u8ba1\u65f6\u5668\uff0c\u53ef\u4ee5\u7528\u6765\u6d4b\u91cf\u4ee3\u7801\u5757\u7684\u6267\u884c\u65f6\u95f4\u3002 time.perf_counter() \u8fd4\u56de\u4e00\u4e2a\u6d6e\u70b9\u6570\uff0c\u8868\u793a\u4ece\u67d0\u4e2a\u7279\u5b9a\u65f6\u95f4\u70b9\u5230\u73b0\u5728\u7ecf\u8fc7\u7684\u79d2\u6570\u3002\u4ee5\u4e0b\u662f\u5982\u4f55\u4f7f\u7528 time.perf_counter() \u6765\u8ba1\u7b97\u4ee3\u7801\u5757\u7684\u6267\u884c\u65f6\u95f4\uff1a import time # \u83b7\u53d6\u8d77\u59cb\u65f6\u95f4\uff08\u5305\u62ecCPU\u65f6\u95f4\u548c\u7cfb\u7edf\u65f6\u95f4\uff09 start_cpu_time = time . process_time () start_real_time = time . perf_counter () start_system_time = time . time () # \u6267\u884c\u4ee3\u7801 for i in range ( 100000000 ): _ = i * i # \u83b7\u53d6\u7ed3\u675f\u65f6\u95f4\uff08\u5305\u62ecCPU\u65f6\u95f4\u548c\u7cfb\u7edf\u65f6\u95f4\uff09 end_cpu_time = time . process_time () end_real_time = time . perf_counter () end_system_time = time . time () # \u8ba1\u7b97CPU\u65f6\u95f4\u5dee cpu_execution_time = end_cpu_time - start_cpu_time real_execution_time = end_real_time - start_real_time system_execution_time = end_system_time - start_system_time print ( f \"CPU Execution Time: { cpu_execution_time : .6f } seconds\" ) print ( f \"Real Execution Time: { real_execution_time : .6f } seconds\" ) print ( f \"System Execution Time: { system_execution_time : .6f } seconds\" ) # \u8fd0\u884c\u7ed3\u679c\uff1a # CPU Execution Time: 7.157305 seconds # Real Execution Time: 7.156638 seconds # System Execution Time: 7.156638 seconds \u5728\u4e0a\u9762\u4ee3\u7801\u4e2d\uff0c start_system_time \u548c end_system_time \u5206\u522b\u8bb0\u5f55\u4e86\u4ee3\u7801\u5757\u5f00\u59cb\u548c\u7ed3\u675f\u65f6\u7684\u7cfb\u7edf\u65f6\u95f4\u3002\u7136\u540e\uff0c\u53ef\u4ee5\u901a\u8fc7\u8ba1\u7b97 end_system_time - start_system_time \u6765\u83b7\u53d6\u7cfb\u7edf\u65f6\u95f4\u7684\u6d88\u8017\u3002 \u7cfb\u7edf\u65f6\u95f4\u7684\u8ba1\u7b97\u53ef\u80fd\u53d7\u5230\u7cfb\u7edf\u7684\u5f71\u54cd\uff0c\u53ef\u80fd\u4f1a\u56e0\u4e3a\u7cfb\u7edf\u65f6\u95f4\u7684\u53d8\u5316\u800c\u4ea7\u751f\u4e0d\u51c6\u786e\u7684\u7ed3\u679c\u3002\u5728\u8fdb\u884c\u6027\u80fd\u6d4b\u8bd5\u65f6\uff0c\u5c3d\u91cf\u4ee5CPU\u65f6\u95f4\u548c\u5b9e\u9645\u7ecf\u8fc7\u65f6\u95f4\u4e3a\u4e3b\u8981\u53c2\u8003\u6307\u6807\u3002 \u8865\u5145\uff1a CPU \u65f6\u95f4\u3001\u5b9e\u9645\u7ecf\u8fc7\u65f6\u95f4\u548c\u7cfb\u7edf\u65f6\u95f4\u4ee3\u8868\u4e86\u4e0d\u540c\u7684\u65f6\u95f4\u6307\u6807\uff0c\u5b83\u4eec\u4e4b\u95f4\u6709\u4ee5\u4e0b\u533a\u522b\uff1a CPU \u65f6\u95f4\uff1a - CPU \u65f6\u95f4\u662f\u7a0b\u5e8f\u5728 CPU \u4e0a\u6267\u884c\u7684\u65f6\u95f4\uff0c\u5305\u62ec\u4e86\u5728\u7528\u6237\u6001\uff08\u6267\u884c\u5e94\u7528\u7a0b\u5e8f\u4ee3\u7801\uff09\u548c\u5185\u6838\u6001\uff08\u6267\u884c\u64cd\u4f5c\u7cfb\u7edf\u4ee3\u7801\uff09\u7684\u65f6\u95f4\u3002\u56e0\u6b64\uff0c\u5b83\u8003\u8651\u4e86\u5e94\u7528\u7a0b\u5e8f\u548c\u64cd\u4f5c\u7cfb\u7edf\u7684\u6267\u884c\u65f6\u95f4\u3002 - CPU \u65f6\u95f4\u901a\u5e38\u7528\u4e8e\u6d4b\u91cf\u7a0b\u5e8f\u7684\u8ba1\u7b97\u5bc6\u96c6\u578b\u5de5\u4f5c\u91cf\uff0c\u5373\u5927\u91cf\u8ba1\u7b97\u64cd\u4f5c\uff0c\u6bd4\u5982\u5faa\u73af\u548c\u6570\u5b66\u8ba1\u7b97\u3002 - \u901a\u8fc7 time.process_time() \u51fd\u6570\u53ef\u4ee5\u83b7\u53d6\u5f53\u524d\u8fdb\u7a0b\u7684 CPU \u65f6\u95f4\u3002 \u5b9e\u9645\u7ecf\u8fc7\u65f6\u95f4\uff1a - \u5b9e\u9645\u7ecf\u8fc7\u65f6\u95f4\u662f\u4ece\u67d0\u4e2a\u65f6\u95f4\u70b9\u5230\u73b0\u5728\u7684\u5b9e\u9645\u7ecf\u8fc7\u7684\u65f6\u95f4\uff0c\u8003\u8651\u4e86\u6240\u6709\u56e0\u7d20\uff0c\u5305\u62ec\u4e86 CPU \u65f6\u95f4\u3001\u7b49\u5f85\u65f6\u95f4\u3001\u7cfb\u7edf\u8c03\u5ea6\u7b49\u3002 - \u5b9e\u9645\u7ecf\u8fc7\u65f6\u95f4\u7528\u4e8e\u6d4b\u91cf\u4ee3\u7801\u7684\u603b\u6267\u884c\u65f6\u95f4\uff0c\u5305\u62ec\u4e86\u8ba1\u7b97\u548c\u7b49\u5f85\u7684\u65f6\u95f4\u3002 - \u901a\u8fc7 time.perf_counter() \u51fd\u6570\u53ef\u4ee5\u83b7\u53d6\u5f53\u524d\u65f6\u95f4\u3002 \u7cfb\u7edf\u65f6\u95f4\uff1a - \u7cfb\u7edf\u65f6\u95f4\u662f\u64cd\u4f5c\u7cfb\u7edf\u5185\u90e8\u7ef4\u62a4\u7684\u4e00\u4e2a\u65f6\u95f4\u503c\uff0c\u5b83\u4ee3\u8868\u4e86\u4ece\u67d0\u4e2a\u56fa\u5b9a\u65f6\u95f4\u70b9\u5f00\u59cb\u7684\u79d2\u6570\u3002 - \u7cfb\u7edf\u65f6\u95f4\u901a\u5e38\u7528\u4e8e\u8bb0\u5f55\u4e8b\u4ef6\u548c\u8ba1\u7b97\u65f6\u95f4\u95f4\u9694\uff0c\u4e0d\u53d7\u7a0b\u5e8f\u7684\u6267\u884c\u5f71\u54cd\u3002 - \u901a\u8fc7 time.time() \u51fd\u6570\u53ef\u4ee5\u83b7\u53d6\u5f53\u524d\u7684\u7cfb\u7edf\u65f6\u95f4\u3002 \u603b\u7ed3\uff1aCPU \u65f6\u95f4\u5173\u6ce8\u7684\u662f\u7a0b\u5e8f\u5728 CPU \u4e0a\u7684\u6267\u884c\u65f6\u95f4\uff0c\u5b9e\u9645\u7ecf\u8fc7\u65f6\u95f4\u5173\u6ce8\u7684\u662f\u4ece\u4ee3\u7801\u5f00\u59cb\u5230\u7ed3\u675f\u6240\u7ecf\u8fc7\u7684\u771f\u5b9e\u65f6\u95f4\uff0c\u7cfb\u7edf\u65f6\u95f4\u662f\u7cfb\u7edf\u7ef4\u62a4\u7684\u5168\u5c40\u65f6\u95f4\u3002\u5728\u4e0d\u540c\u7684\u573a\u666f\u4e2d\uff0c\u4f60\u53ef\u4ee5\u6839\u636e\u9700\u8981\u9009\u62e9\u5408\u9002\u7684\u65f6\u95f4\u6307\u6807\u6765\u8fdb\u884c\u6027\u80fd\u6d4b\u91cf\u548c\u5206\u6790\u3002","title":"3.1.4.\u7ec3\u4e60\u9898"},{"location":"python/DataStructure/03_TimeComplexity/#32","text":"\u590d\u6742\u5ea6\u5206\u6790\uff08complexity analysis\uff09\u65b9\u6cd5\uff0c\u4e00\u79cd\u8bc4\u4f30\u7b97\u6cd5\u6548\u7387\u7684\u65b9\u6cd5\uff0c\u8fd9\u4e2a\u65b9\u6cd5\u53ef\u4ee5\u4e0d\u7528\u5173\u5fc3\u4e0e\u5e73\u53f0\u76f8\u5173\u7684\u65f6\u95f4\uff0c\u4e5f\u4e0d\u9700\u8981\u4f7f\u7528\u7edf\u8ba1\u6307\u4ee4\u6570\u91cf\u8fd9\u79cd\u65b9\u6cd5\u6765\u5bf9\u7b97\u6cd5\u8fdb\u884c\u8bc4\u4f30\u3002","title":"3.2.\u590d\u6742\u5ea6\u5206\u6790"},{"location":"python/DataStructure/03_TimeComplexity/#321","text":"\u5728 3.1.2.\u7edf\u8ba1\u6307\u4ee4\u6570 \u4e2d\u5173\u4e8e\u8fed\u4ee3\u6b21\u6570\u548c\u95ee\u9898\u89c4\u6a21\u7684\u4e24\u4e2a\u7b97\u6cd5\uff0c\u5b83\u4eec\u590d\u6742\u5ea6\u7684\u9636\uff08order of complexity\uff09\u4e0a\u662f\u4e0d\u4e00\u6837\u7684\u3002 \u7b2c\u4e00\u4e2a\u7b97\u6cd5\u4e2d\uff0c\u8fed\u4ee3\u6b21\u6570\u548c\u95ee\u9898\u89c4\u6a21\u4e4b\u95f4\u662f\u7ebf\u6027\u5173\u7cfb\uff0c\u79f0\u5176\u590d\u6742\u5ea6\u4e3a\u7ebf\u6027\uff08linear\uff09\u9636\uff1b \u7b2c\u4e8c\u4e2a\u7b97\u6cd5\u4e2d\uff0c\u8fed\u4ee3\u6b21\u6570\u548c\u95ee\u9898\u89c4\u6a21\u4e4b\u95f4\u662f\u5e73\u65b9\u5173\u7cfb\uff0c\u79f0\u5176\u590d\u6742\u5ea6\u4e3a\u5e73\u65b9\uff08quadratic\uff09\u9636\uff1b \u5982\u679c\u7b97\u6cd5\u9700\u8981\u76f8\u540c\u6570\u91cf\u7684\u8fd0\u7b97\uff0c\u90a3\u4e48\u5b83\u7684\u6027\u80fd\u5c31\u662f\u5e38\u6570\uff08constant\uff09\u9636\u3002\u5217\u8868\u7d22\u5f15\u5c31\u662f\u4e00\u4e2a\u5e38\u6570\u65f6\u95f4\u7b97\u6cd5\u7684\u4f8b\u5b50\u3002 \u6bd4\u7ebf\u6027\u6027\u80fd\u597d\uff0c\u4f46\u6bd4\u5e38\u6570\u6027\u80fd\u5dee\u7684\u53e6\u4e00\u4e2a\u590d\u6742\u5ea6\u7684\u9636\u88ab\u79f0\u4e3a\u5bf9\u6570\uff08logarithmic\uff09\u9636\u3002\u5bf9\u6570\u7b97\u6cd5\u7684\u5de5\u4f5c\u91cf\u4e0e\u95ee\u9898\u89c4\u6a21\u7684\u4ee52\u4e3a\u5e95\u7684\u5bf9\u6570\u6210\u6b63\u6bd4\u3002\u5f53\u95ee\u9898\u89c4\u6a21\u6269\u5927\u4e00\u500d\u65f6\uff0c\u5de5\u4f5c\u91cf\u53ea\u4f1a\u52a01\u3002 \u591a\u9879\u5f0f\u65f6\u95f4\u7b97\u6cd5\uff08polynomial time algorithm\uff09\u7684\u5de5\u4f5c\u91cf\u4f1a\u4ee5 n^k \u7684\u901f\u7387\u589e\u957f\uff0c\u5176\u4e2d k \u662f\u5927\u4e8e 1 \u7684\u5e38\u6570\uff0c\u6bd4\u5982 n^2 \u3001 n^3 \u4ee5\u53ca n^10 \u3002\u4ece\u67d0\u79cd\u610f\u4e49\u4e0a\u8bb2\uff0c n^3 \u7684\u6027\u80fd\u8981\u6bd4 n^2 \u5dee\uff0c\u4f46\u90fd\u5c5e\u4e8e\u591a\u9879\u5f0f\uff08polynomial\uff09\u9636\u3002 \u6bd4\u591a\u9879\u5f0f\u8fd8\u8981\u5dee\u7684\u590d\u6742\u5ea6\u7684\u9636\u88ab\u79f0\u4e3a\u6307\u6570\uff08exponential\uff09\u9636\uff0c\u6bd4\u5982 2^n \u3002\u5bf9\u4e8e\u5927\u7684\u95ee\u9898\u89c4\u6a21\u6765\u8bf4\uff0c\u6307\u6570\u7b97\u6cd5\u662f\u4e0d\u53ef\u884c\u7684\u3002 \u4e0d\u540c\u590d\u6742\u5ea6\u9636\u7684\u7b97\u6cd5\u7684\u5de5\u4f5c\u91cf\u6bd4\u8f83\uff08\u4ece\u5c0f\u5230\u5927\uff09\uff1a\u5bf9\u6570\u9636 < \u7ebf\u6027\u9636 < \u5e73\u65b9\u9636 < \u6307\u6570\u9636\u3002\u968f\u7740\u95ee\u9898\u89c4\u6a21\u7684\u589e\u5927\uff0c\u5177\u6709\u8f83\u9ad8\u590d\u6742\u5ea6\u7684\u9636\u7684\u7b97\u6cd5\u7684\u6027\u80fd\u4f1a\u66f4\u5feb\u5730\u53d8\u5dee\u3002","title":"3.2.1.\u590d\u6742\u5ea6\u7684\u9636"},{"location":"python/DataStructure/03_TimeComplexity/#322o","text":"\u5f88\u591a\u60c5\u51b5\u4e0b\uff0c\u7b97\u6cd5\u4e2d\u7684\u5de5\u4f5c\u91cf\u901a\u5e38\u662f\u591a\u9879\u5f0f\u91cc\u591a\u9879\u7684\u603b\u548c\uff0c\u800c\u5f53\u5de5\u4f5c\u91cf\u8868\u793a\u4e3a\u591a\u9879\u5f0f\u65f6\uff0c\u5176\u4e2d\u4e00\u9879\u662f\u4e3b\u5bfc\u9879\uff08dominant\uff09\u3002\u968f\u7740 n \u8d8a\u6765\u8d8a\u5927\uff0c\u4e3b\u5bfc\u9879\u5c06\u53d8\u5f97\u975e\u5e38\u5927\uff0c\u4ee5\u81f3\u4e8e\u53ef\u4ee5\u5ffd\u7565\u5176\u4ed6\u9879\u6240\u4ee3\u8868\u7684\u5de5\u4f5c\u91cf\u3002\u56e0\u6b64\uff0c\u5bf9\u4e8e\u591a\u9879\u5f0f n^2+n \uff0c\u53ea\u9700\u8981\u7740\u91cd\u8003\u8651\u5e73\u65b9\u9879 n^2 \uff0c\u4e5f\u5c31\u662f\u5728\u8003\u8651\u7684\u65f6\u5019\u53ef\u4ee5\u5ffd\u7565\u7ebf\u6027\u9879 n \u3002\u968f\u7740 n^2 \u53d8\u5f97\u975e\u5e38\u5927\uff0c\u591a\u9879\u5f0f\u7684\u503c\u6e10\u8fd1\u5730\u63a5\u8fd1\u6216\u8fd1\u4f3c\u4e8e\u5b83\u7684\u6700\u5927\u9879\u503c\uff0c\u8fd9\u79cd\u5f62\u5f0f\u7684\u5206\u6790\u6709\u65f6\u88ab\u79f0\u4e3a\u6e10\u8fd1\u5206\u6790\uff08asymptotic analysis\uff09\u3002 \u8ba1\u7b97\u4e2d\u7528\u6765\u8868\u793a\u7b97\u6cd5\u7684\u6548\u7387\u6216\u8ba1\u7b97\u590d\u6742\u5ea6\u7684\u4e00\u79cd\u65b9\u6cd5\u88ab\u79f0\u4e3a\u5927O\u8868\u793a\u6cd5\uff08big-O notation\uff09\u3002\u201cO\u201d\u4ee3\u8868\u201c\u5728\u2026\u2026\u9636\u201d\uff0c\u6307\u7684\u662f\u7b97\u6cd5\u5de5\u4f5c\u7684\u590d\u6742\u5ea6\u7684\u9636\u3002\u4f8b\u5982\uff1a \u5e38\u6570\u65f6\u95f4\uff1aO(1) \u7ebf\u6027\u65f6\u95f4\uff1aO(n) \u5e73\u65b9\u65f6\u95f4\uff1aO(n^2) \u7acb\u65b9\u65f6\u95f4\uff1aO(n^3) \u591a\u9879\u5f0f\u65f6\u95f4\uff1aO(n^k)","title":"3.2.2.\u5927O\u8868\u793a\u6cd5"},{"location":"python/DataStructure/03_TimeComplexity/#323","text":"\u6bd4\u4f8b\u5e38\u6570\uff08constant of proportionality\uff09\u5305\u542b\u5728\u5927O\u5206\u6790\u4e2d\u88ab\u5ffd\u7565\u7684\u9879\u548c\u7cfb\u6570\u3002\u6bd4\u5982\uff0c\u7ebf\u6027\u65f6\u95f4\u7b97\u6cd5\u6240\u6267\u884c\u7684\u5de5\u4f5c\u91cf\u53ef\u4ee5\u8868\u793a\u4e3a\uff1a work = 2 * size \uff0c\u5176\u4e2d\u6bd4\u4f8b\u5e38\u6570\u5c31\u662f work/size \uff0c\u4e5f\u5c31\u662f 2 \u3002\u5728\u5904\u7406\u4e2d\u5c0f\u578b\u6570\u636e\u96c6\u7684\u65f6\u5019\uff0c\u5982\u679c\u8fd9\u4e9b\u5e38\u6570\u5f88\u5927\uff0c\u90a3\u4e48\u5b83\u4eec\u4e5f\u4f1a\u5f71\u54cd\u5230\u7b97\u6cd5\u6548\u7387\u3002 \u56de\u987e\u4e0b\u9762\u7684\u4f8b\u5b50\u3002 import time problemSize = 10000000 print ( \" %12s%16s \" % ( \"Problem Size\" , \"Seconds\" )) for count in range ( 5 ): number = 0 # \u7b97\u6cd5\u5f00\u59cb work = 1 for x in range ( problemSize ): number += 1 work += 1 work -= 1 # \u7b97\u6cd5\u7ed3\u675f print ( \" %12d%16.3f \" % ( problemSize , Iterations )) problemSize *= 2 # \u8fd0\u884c\u7ed3\u679c\uff1a # Problem Size Iterations # 10000000 10000000.000 # 20000000 20000000.000 # 40000000 40000000.000 # 80000000 80000000.000 # 160000000 160000000.000 \u5176\u4e2d\u7684\u7b97\u6cd5\u90e8\u5206\uff0c\u9664\u4e86\u5faa\u73af\u8bed\u53e5\u672c\u8eab\uff0c\u8fd8\u6709\u5176\u4ed63\u884c\u4ee3\u7801\uff0c\u5b83\u4eec\u90fd\u662f\u590d\u5236\u8bed\u53e5\uff0c\u90fd\u4f1a\u4ee5\u5e38\u6570\u65f6\u95f4\u8fd0\u884c\u3002\u5047\u8bbe\u5faa\u73af\u8bed\u53e5\u672c\u8eab\u4f1a\u6d88\u8017\u4e00\u4e2a\u65f6\u95f4\u5e38\u6570\uff0c\u90a3\u4e48\u8fd9\u4e2a\u7b97\u6cd5\u7684\u62bd\u8c61\u5de5\u4f5c\u65f6\u95f4\u5c31\u662f 3n+1 \u3002\u867d\u7136 3n+1 \u7684\u5de5\u4f5c\u91cf\u5927\u4e8e n \uff0c\u4f46\u4e8c\u8005\u5728\u8fd0\u884c\u65f6\u90fd\u662f\u7ebf\u6027\u589e\u52a0\uff0c\u6240\u4ee5\u4ed6\u4eec\u8fd0\u884c\u65f6\u90fd\u662f O(n) \u3002 # \u7b97\u6cd5\u5f00\u59cb work = 1 for x in range ( problemSize ): number += 1 work += 1 work -= 1 # \u7b97\u6cd5\u7ed3\u675f","title":"3.2.3.\u6bd4\u4f8b\u5e38\u6570\u7684\u4f5c\u7528"},{"location":"python/DataStructure/03_TimeComplexity/#324","text":"\u5047\u8bbe\u4e0b\u9762\u7684\u8868\u8fbe\u5f0f\u90fd\u5206\u522b\u8868\u793a\u5bf9\u95ee\u9898\u89c4\u6a21\u4e3a n \u7684\u7b97\u6cd5\u6240\u9700\u8981\u6267\u884c\u7684\u64cd\u4f5c\u6570\uff0c\u8bf7\u6307\u51fa\u6bcf\u79cd\u7b97\u6cd5\u4e2d\u7684\u4e3b\u5bfc\u9879\uff0c\u5e76\u4f7f\u7528\u5927O\u8868\u793a\u6cd5\u5bf9\u5b83\u8fdb\u884c\u5206\u7c7b\u3002 a. 2^n - 4n + 5n b. 2n^2 + 8 c. n^3 n^2 + n \u89e3\u7b54\uff1a a. 2^n\uff0cO(n) b. n 2\uff0cO(n 2) c. n 3\uff0cO(n 3) \u5bf9\u4e8e\u89c4\u6a21\u4e3a n \u7684\u95ee\u9898\uff0c\u7b97\u6cd5A\u548cB\u5206\u522b\u4f1a\u6267\u884c n^2 \u548c (1/2)*n^2+(1/2)*n \u6761\u6307\u4ee4\u3002\u54ea\u79cd\u7b97\u6cd5\u66f4\u9ad8\u6548\uff1f\u6709\u6ca1\u6709\u4e00\u79cd\u7b97\u6cd5\u6bd4\u53e6\u4e00\u79cd\u7b97\u6cd5\u6027\u80fd\u660e\u663e\u66f4\u597d\u7684\u7279\u5b9a\u7684\u95ee\u9898\u89c4\u6a21\uff1f\u662f\u5426\u6709\u8ba9\u4e24\u79cd\u7b97\u6cd5\u90fd\u6267\u884c\u5927\u81f4\u76f8\u540c\u5de5\u4f5c\u91cf\u7684\u7279\u5b9a\u7684\u95ee\u9898\u89c4\u6a21\uff1f \u89e3\u7b54\uff1a \u5728\u6bd4\u8f83\u4e24\u79cd\u7b97\u6cd5\u7684\u6548\u7387\u65f6\uff0c\u901a\u5e38\u5173\u6ce8\u7b97\u6cd5\u6267\u884c\u65f6\u95f4\u968f\u95ee\u9898\u89c4\u6a21\u589e\u957f\u7684\u8d8b\u52bf\u3002\u9898\u76ee\u4e2d\u7684\u4e24\u79cd\u7b97\u6cd5\u7684\u6267\u884c\u6307\u4ee4\u6570\u5206\u522b\u5982\u4e0b\uff1a \u7b97\u6cd5A\uff1a\u6267\u884c n^2 \u6761\u6307\u4ee4\u3002 \u7b97\u6cd5B\uff1a\u6267\u884c (1/2)*n^2+(1/2)*n \u6761\u6307\u4ee4\u3002 \u7528\u5982\u4e0b\u4ee3\u7801\u6a21\u62df\u7b97\u6cd5A\u548c\u7b97\u6cd5B\uff0c\u53ef\u4ee5\u770b\u51fa\uff0c\u968f\u7740 n \u7684\u589e\u52a0\uff0c\u7b97\u6cd5A\u7684\u589e\u957f\u901f\u7387\u8fdc\u5927\u4e8e\u7b97\u6cd5B\u3002\u6240\u4ee5\u53ef\u4ee5\u8ba4\u4e3a\u5728 n >= 2 \u7684\u60c5\u51b5\u4e0b\uff0c\u7b97\u6cd5A\u4f18\u4e8e\u7b97\u6cd5B\u3002 n = 1 print ( \" %-15s%25s \" % ( \"ProblemSize: n\" , \"A/B\" )) while n < 1000000 : n *= 10 print ( \" %-15d%25d \" % ( n , int (( n ** 2 ) / ( 1 / 2 ) * n ** 2 + ( 1 / 2 ) * n ))) # ProblemSize: n A/B # 10 20005 # 100 200000050 # 1000 2000000000500 # 10000 20000000000005000 # 100000 200000000000000065536 # 1000000 1999999999999999966445568 \u7531\u6b64\u53ef\u5f97\uff0c\u5728\u5927\u95ee\u9898\u89c4\u6a21\u4e0b\uff0c\u7b97\u6cd5B\u7684\u589e\u957f\u901f\u7387\u4f1a\u66f4\u6162\uff0c\u56e0\u4e3a (1/2)*n^2+(1/2)*n \u4e2d\u7684 (1/2)*n \u90e8\u5206\u5bf9\u4e8e\u6574\u4f53\u589e\u957f\u6765\u8bf4\u76f8\u5bf9\u8f83\u5c0f\u3002 \u4e3a\u4e86\u8ba9\u4e24\u79cd\u7b97\u6cd5\u6267\u884c\u76f8\u8fd1\u7684\u5de5\u4f5c\u91cf\uff0c\u6211\u4eec\u53ef\u4ee5\u89e3\u4e0b\u9762\u7684\u65b9\u7a0b\uff1a ( 1 / 2 ) * n ^ 2 + ( 1 / 2 ) * n = k * n ^ 2 \u5176\u4e2d k \u662f\u4e00\u4e2a\u5e38\u6570\uff0c\u8868\u793a\u4e24\u79cd\u7b97\u6cd5\u6267\u884c\u7684\u5de5\u4f5c\u91cf\u76f8\u7b49\u65f6\u7684\u95ee\u9898\u89c4\u6a21\u3002\u901a\u8fc7\u89e3\u8fd9\u4e2a\u65b9\u7a0b\uff0c\u6211\u4eec\u53ef\u4ee5\u627e\u5230\u4e00\u4e2a\u95ee\u9898\u89c4\u6a21 k \uff0c\u5728\u8fd9\u4e2a\u95ee\u9898\u89c4\u6a21\u4e0b\uff0c\u4e24\u79cd\u7b97\u6cd5\u7684\u6267\u884c\u6307\u4ee4\u6570\u76f8\u8fd1\u3002 \u7b97\u6cd5\u7684\u6548\u7387\u5206\u6790\u5e76\u4e0d\u4ec5\u4ec5\u53d6\u51b3\u4e8e\u6307\u4ee4\u6570\uff0c\u8fd8\u53ef\u80fd\u53d7\u5230\u7b97\u6cd5\u4e2d\u5e38\u6570\u56e0\u5b50\u3001\u6570\u636e\u8bbf\u95ee\u6a21\u5f0f\u3001\u5185\u5b58\u5360\u7528\u7b49\u56e0\u7d20\u7684\u5f71\u54cd\u3002\u56e0\u6b64\uff0c\u5728\u5b9e\u9645\u5e94\u7528\u4e2d\uff0c\u901a\u5e38\u9700\u8981\u7efc\u5408\u8003\u8651\u591a\u4e2a\u56e0\u7d20\u6765\u786e\u5b9a\u6700\u4f18\u7684\u7b97\u6cd5\u9009\u62e9\u3002 \u5728\u4ec0\u4e48\u65f6\u5019\u5f00\u59cb n^4 \u7b97\u6cd5\u6bd4 2^n \u7b97\u6cd5\u8868\u73b0\u66f4\u597d\uff1f \u89e3\u7b54\uff1a\u7528\u4e0b\u9762\u7684\u7b97\u6cd5\u6a21\u62df n^4 \u7b97\u6cd5\u6bd4 2^n \u7b97\u6cd5\u6267\u884c\u5de5\u4f5c\u91cf\u3002\u4ece\u8fd0\u884c\u7ed3\u679c\u53ef\u4ee5\u770b\u51fa\uff1a n=16 \u662f\u5206\u754c\u70b9\uff0c n^4 \u7b97\u6cd5\u4e0e 2^n \u7b97\u6cd5\u5de5\u4f5c\u91cf\u76f8\u7b49\uff1b \u5f53 n<16 \u65f6\uff0c n^4 \u7b97\u6cd5\u6bd4 2^n \u7b97\u6cd5\u5de5\u4f5c\u91cf\u8981\u9ad8\uff1b \u5f53 n>16 \u65f6\uff0c n^4 \u7b97\u6cd5\u6bd4 2^n \u7b97\u6cd5\u5de5\u4f5c\u91cf\u8981\u4f4e\uff1b\u800c\u4e14 2^n \u7b97\u6cd5\u5de5\u4f5c\u91cf\u589e\u957f\u901f\u5ea6\u8fdc\u5927\u4e8e n^4 \u7b97\u6cd5\uff1b n = 1 print ( \" %-8s%10s%15s%10s \" % ( \"Size:n\" , \"A:n^4\" , \"B:2^n\" , \"B/A\" )) while n < 30 : n += 1 print ( \" %-8d%10d%15d%10.3f \" % ( n , int ( n ** 4 ), int ( 2 ** n ), ( 2 ** n ) / ( n ** 4 ))) # \u8fd0\u884c\u7ed3\u679c\uff1a # Size:n A:n^4 B:2^n B/A # 2 16 4 0.250 # 3 81 8 0.099 # 4 256 16 0.062 # 5 625 32 0.051 # 6 1296 64 0.049 # 7 2401 128 0.053 # 8 4096 256 0.062 # 9 6561 512 0.078 # 10 10000 1024 0.102 # 11 14641 2048 0.140 # 12 20736 4096 0.198 # 13 28561 8192 0.287 # 14 38416 16384 0.426 # 15 50625 32768 0.647 # 16 65536 65536 1.000 # 17 83521 131072 1.569 # 18 104976 262144 2.497 # 19 130321 524288 4.023 # 20 160000 1048576 6.554 # 21 194481 2097152 10.783 # 22 234256 4194304 17.905 # 23 279841 8388608 29.976 # 24 331776 16777216 50.568 # 25 390625 33554432 85.899 # 26 456976 67108864 146.854 # 27 531441 134217728 252.554 # 28 614656 268435456 436.725 # 29 707281 536870912 759.063 # 30 810000 1073741824 1325.607","title":"3.2.4.\u7ec3\u4e60\u9898"},{"location":"python/DataStructure/03_TimeComplexity/#33","text":"\u7ea6\u5b9a\uff1a \u4ee5\u5217\u8868\u4e3a\u4f8b\uff0c\u4ecb\u7ecd\u641c\u7d22\u548c\u6392\u5e8f\u7684\u7b97\u6cd5\uff1b \u9610\u91ca\u8fd9\u4e9b\u7b97\u6cd5\u7684\u8bbe\u8ba1\uff0c\u5e76\u628a\u5b83\u5b9e\u73b0\u4e3aPython\u51fd\u6570\uff1b \u51fd\u6570\u53ea\u5904\u7406\u5168\u90e8\u662f\u6574\u6570\u7684\u5217\u8868\uff0c\u4e0d\u540c\u5927\u5c0f\u7684\u5217\u8868\u5c06\u4f5c\u4e3a\u53c2\u6570\u4f20\u9012\u7ed9\u51fd\u6570\uff1b \u5bf9\u8fd9\u4e9b\u7b97\u6cd5\u7684\u8ba1\u7b97\u590d\u6742\u5ea6\u8fdb\u884c\u5206\u6790\uff1b","title":"3.3.\u641c\u7d22\u7b97\u6cd5"},{"location":"python/DataStructure/03_TimeComplexity/#331","text":"Python\u4e2d\u6709 min \u51fd\u6570\uff0c\u4f1a\u8fd4\u56de\u5217\u8868\u91cc\u7684\u6700\u5c0f\u503c\u6216\u6700\u5c0f\u5143\u7d20\uff0c\u4e0b\u9762\u5199\u4e00\u4e2a\u65b0\u7b97\u6cd5\uff0c\u6765\u5206\u6790 min \u51fd\u6570\u7684\u7b97\u6cd5\u590d\u6742\u5ea6\u3002 \u7b97\u6cd5\u76ee\u6807\uff1a\u5047\u5b9a\u5217\u8868\u4e0d\u4e3a\u7a7a\uff0c\u5e76\u4e14\u5143\u7d20\u662f\u6309\u7167\u4efb\u610f\u987a\u5e8f\u5b58\u653e\u5728\u5217\u8868\u91cc\u7684\uff0c\u7b97\u6cd5\u8fd4\u56de\u6700\u5c0f\u5143\u7d20\u7684\u7d22\u5f15\uff08index\uff09\u3002 \u7b97\u6cd5\u89e3\u6790\uff1a \u9996\u5148\u628a\u7b2c\u4e00\u4e2a\u4f4d\u7f6e\u4f5c\u4e3a\u5b58\u653e\u6700\u5c0f\u5143\u7d20\u7684\u4f4d\u7f6e\uff1b \u7136\u540e\u5411\u53f3\u4fa7\u641c\u7d22\u66f4\u5c0f\u7684\u5143\u7d20\uff1b \u5982\u679c\u627e\u5230\uff0c\u90a3\u4e48\u628a\u6700\u5c0f\u5143\u7d20\u7684\u4f4d\u7f6e\u91cd\u7f6e\u4e3a\u5f53\u524d\u4f4d\u7f6e\uff1b \u5f53\u7b97\u6cd5\u5230\u8fbe\u5217\u8868\u672b\u5c3e\u65f6\uff0c\u5b83\u5c06\u8fd4\u56de\u6700\u5c0f\u5143\u7d20\u7684\u4f4d\u7f6e\u3002 \u7b97\u6cd5\u5b9e\u73b0\uff1a def indexOfMin ( lyst ): \"\"\"\u8fd4\u56de\u6700\u5c0f\u5143\u7d20\u7684\u7d22\u5f15\uff0c\u76f8\u540c\u6700\u5c0f\u5143\u7d20\u8fd4\u56de\u7b2c\u4e00\u4e2a\u7d22\u5f15\"\"\" # \u7b97\u6cd5\u5f00\u59cb minIndex = 0 currentIndex = 1 while currentIndex < len ( lyst ): if lyst [ currentIndex ] < lyst [ minIndex ]: # \u6539\u6210<=\uff0c\u76f8\u540c\u6700\u5c0f\u5143\u7d20\u5219\u8fd4\u56de\u6700\u540e\u4e00\u4e2a\u7d22\u5f15 minIndex = currentIndex currentIndex += 1 return minIndex # \u7b97\u6cd5\u7ed3\u675f def main (): myList = [ 2 , 20 , 5 , 0 , 1 , 0 , 9 ] minIndex = indexOfMin ( myList ) print ( minIndex , myList [ minIndex ]) if __name__ == \"__main__\" : main () # \u8fd0\u7b97\u7ed3\u679c\uff1a # 3 0 # \u5982\u679c\u6539\u6210\u6539\u6210yst[currentIndex] <= lyst[minIndex]\uff0c\u5219\u76f8\u540c\u6700\u5c0f\u5143\u7d20\u5219\u8fd4\u56de\u6700\u540e\u4e00\u4e2a\u7d22\u5f15 # 5 0 \u65e0\u8bba\u5217\u8868\u7684\u5927\u5c0f\u5982\u4f55\uff0c\u5faa\u73af\u5916\u76843\u6761\u6307\u4ee4\uff082\u6761\u8d4b\u503c\u8bed\u53e5\uff0c\u4e00\u6761while\u8bed\u53e5\u672c\u8eab\uff09\u90fd\u4f1a\u6267\u884c\u76f8\u540c\u7684\u6b21\u6570\uff0c\u53ef\u4ee5\u5ffd\u7565\u5b83\u4eec\u90fd\u5f71\u54cd\u3002 \u5faa\u73af\u91cc\u8fd8\u67093\u6761\u6307\u4ee4\uff0c\u5176\u4e2d if \u8bed\u53e5\u5185\u7684\u6bd4\u8f83 lyst[currentIndex] < lyst[minIndex] \u548c currentIndex += 1 \u7684\u81ea\u589e\uff0c\u4f1a\u5728\u6bcf\u6b21\u5faa\u73af\u65f6\u90fd\u6267\u884c\uff0c\u4e14\u6ca1\u6709\u5176\u5b83\u5d4c\u5957\u6216\u9690\u85cf\u7684\u5faa\u73af\u3002 if \u8bed\u53e5\u4e2d\u7684\u6bd4\u8f83\u64cd\u4f5c\u5b9e\u73b0\u4e86\u8bbf\u95ee\u5217\u8868\u91cc\u7684\u6bcf\u4e2a\u5143\u7d20\uff0c\u4ece\u800c\u80fd\u591f\u627e\u5230\u6700\u5c0f\u5143\u7d20\u7684\u4f4d\u7f6e\u3002 \u56e0\u6b64\uff0c\u8fd9\u4e2a\u7b97\u6cd5\u5fc5\u987b\u5bf9\u5927\u5c0f\u4e3a n \u7684\u5217\u8868\u8fdb\u884c n-1 \u6b21\u6bd4\u8f83\uff0c\u5373\uff0c\u5b83\u7684\u590d\u6742\u5ea6\u4e3aO(n)\u3002","title":"3.3.1.\u6700\u5c0f\u503c\u641c\u7d22"},{"location":"python/DataStructure/03_TimeComplexity/#332","text":"Python\u7684 in \u8fd0\u7b97\u7b26\u5728list\u7c7b\u91cc\u88ab\u5b9e\u73b0\u4e3a\u53eb\u4f5c __contains__ \u7684\u65b9\u6cd5\uff0c\u8fd9\u4e2a\u65b9\u6cd5\u4f1a\u5728\u4efb\u610f\u7684\u5143\u7d20\u5217\u8868\u91cc\u641c\u7d22\u7279\u5b9a\u7684\u5143\u7d20\uff0c\u5373\u76ee\u6807\u5143\u7d20\uff08target item\uff09\u3002 \u5728\u5217\u8868\u91cc\uff0c\u627e\u5230\u76ee\u6807\u5143\u7d20\u7684\u552f\u4e00\u65b9\u6cd5\u662f\u4ece\u4f4d\u4e8e\u7b2c\u4e00\u4e2a\u4f4d\u7f6e\u7684\u5143\u7d20\u5f00\u59cb\uff0c\u5e76\u628a\u5b83\u548c\u76ee\u6807\u5143\u7d20\u8fdb\u884c\u6bd4\u8f83\u3002\u5982\u679c\u4e24\u4e2a\u5143\u7d20\u76f8\u7b49\uff0c\u90a3\u4e48\u8fd9\u4e2a\u65b9\u6cd5\u8fd4\u56de True \uff1b\u5426\u5219\uff0c\u8fd9\u4e2a\u65b9\u6cd5\u5c06\u79fb\u52a8\u5230\u4e0b\u4e00\u4e2a\u4f4d\u7f6e\uff0c\u5e76\u628a\u5b83\u548c\u76ee\u6807\u5143\u7d20\u8fdb\u884c\u6bd4\u8f83\u3002\u5982\u679c\u8fd9\u4e2a\u65b9\u6cd5\u5230\u4e86\u6700\u540e\u4e00\u4e2a\u4f4d\u7f6e\u4ecd\u7136\u627e\u4e0d\u5230\u76ee\u6807\uff0c\u90a3\u4e48\u8fd4\u56de False \u3002\u8fd9\u79cd\u641c\u7d22\u79f0\u4e3a\u987a\u5e8f\u641c\u7d22\uff08sequential search\uff09\u6216\u7ebf\u6027\u641c\u7d22\uff08linear search\uff09\u3002 \u4e0b\u9762\u662f\u987a\u5e8f\u641c\u7d22\u51fd\u6570\u7684\u5b9e\u73b0\u3002\u82e5\u987a\u5e8f\u641c\u7d22\u7b97\u6cd5\u5728\u5217\u8868\u5f00\u5934\u5c31\u627e\u5230\u76ee\u6807\u5143\u7d20\uff0c\u90a3\u4e48\u8fd9\u65f6\u7684\u5de5\u4f5c\u91cf\u660e\u663e\u4f1a\u6bd4\u5728\u5217\u8868\u672b\u5c3e\u627e\u5230\u7684\u5de5\u4f5c\u91cf\u8981\u5c11\u3002 def sequentialSearch ( target , lyst ): \"\"\"\u627e\u5230\u76ee\u6807\u5143\u7d20\u65f6\u8fd4\u56de\u5143\u7d20\u7684\u7d22\u5f15, \u5426\u5219\u8fd4\u56de-1\"\"\" position = 0 while position < len ( lyst ): if target == lyst [ position ]: return position position += 1 return - 1 def main (): myList = [ 2 , 20 , 5 , 0 , 1 , 0 , 9 ] locatedIndex = sequentialSearch ( 9 , myList ) print ( locatedIndex , myList [ locatedIndex ]) if __name__ == \"__main__\" : main () # \u8fd0\u7b97\u7ed3\u679c\uff1a # 6 9","title":"3.3.2.\u987a\u5e8f\u641c\u7d22\u5217\u8868"},{"location":"python/DataStructure/03_TimeComplexity/#333","text":"\u4e00\u822c\u6765\u8bf4\uff0c\u91cd\u70b9\u5173\u6ce8\u5728\u5e73\u5747\u60c5\u51b5\u548c\u6700\u574f\u60c5\u51b5\u4e0b\u7684\u6027\u80fd\uff0c\u4e0d\u4f1a\u7279\u522b\u5173\u6ce8\u6700\u597d\u60c5\u51b5\u3002 \u5bf9\u987a\u5e8f\u641c\u7d22\u7684\u5206\u6790\u9700\u8981\u8003\u8651\u4e0b\u97623\u79cd\u60c5\u51b5\u3002 \u5728\u6700\u574f\u60c5\u51b5\u4e0b\uff0c\u76ee\u6807\u5143\u7d20\u4f4d\u4e8e\u5217\u8868\u7684\u672b\u5c3e\u6216\u8005\u6839\u672c\u5c31\u4e0d\u5728\u5217\u8868\u91cc\u3002\u8fd9\u65f6\uff0c\u8fd9\u4e2a\u7b97\u6cd5\u5c31\u5fc5\u987b\u8bbf\u95ee\u6bcf\u4e00\u4e2a\u5143\u7d20\uff0c\u5bf9\u5927\u5c0f\u4e3a n \u7684\u5217\u8868\u9700\u8981\u6267\u884c n \u6b21\u8fed\u4ee3\u3002\u56e0\u6b64\uff0c\u987a\u5e8f\u641c\u7d22\u7684\u6700\u574f\u60c5\u51b5\u7684\u590d\u6742\u5ea6\u4e3aO(n)\u3002 \u5728\u6700\u597d\u60c5\u51b5\u4e0b\uff0c\u53ea\u9700\u8981O(1)\u7684\u590d\u6742\u5ea6\uff0c\u56e0\u4e3a\u8fd9\u4e2a\u7b97\u6cd5\u5728\u4e00\u6b21\u8fed\u4ee3\u4e4b\u540e\u5c31\u4f1a\u5728\u7b2c\u4e00\u4e2a\u4f4d\u7f6e\u627e\u5230\u76ee\u6807\u5143\u7d20\u3002 \u8981\u786e\u5b9a\u5e73\u5747\u60c5\u51b5\uff0c\u5c31\u9700\u8981\u628a\u6bcf\u4e2a\u53ef\u80fd\u4f4d\u7f6e\u627e\u5230\u76ee\u6807\u6240\u9700\u8981\u7684\u8fed\u4ee3\u6b21\u6570\u76f8\u52a0\uff0c\u7136\u540e\u518d\u5c06\u5b83\u4eec\u7684\u603b\u548c\u9664\u4ee5 n \u3002\u56e0\u6b64\uff0c\u8fd9\u79cd\u60c5\u51b5\u4e0b\uff0c\u7b97\u6cd5\u4f1a\u6267\u884c (n + n\u22121 + n\u22122+ ... +1)/n \u6216 (n+1)/2 \u6b21\u8fed\u4ee3\u3002\u5bf9\u4e8e\u975e\u5e38\u5927\u7684 n \u6765\u8bf4\uff0c\u5e38\u6570\u7cfb\u65702\u662f\u53ef\u4ee5\u5ffd\u7565\u7684\uff0c\u56e0\u6b64\uff0c\u5e73\u5747\u60c5\u51b5\u7684\u590d\u6742\u5ea6\u4ecd\u7136\u662fO(2)\u3002 \u7ed3\u8bba\uff1a\u6700\u597d\u60c5\u51b5\u4e0b\u987a\u5e8f\u641c\u7d22\u7684\u6027\u80fd\u548c\u5176\u4ed6\u4e24\u79cd\u60c5\u51b5\u6bd4\u8d77\u6765\u5c0f\u5f88\u591a\uff0c\u800c\u5176\u4ed6\u4e24\u79cd\u60c5\u51b5\u4e0b\u7684\u6027\u80fd\u662f\u5dee\u4e0d\u591a\u7684\u3002","title":"3.3.3.\u6700\u597d\u60c5\u51b5\u3001\u6700\u574f\u60c5\u51b5\u4ee5\u53ca\u5e73\u5747\u60c5\u51b5\u4e0b\u7684\u6027\u80fd"},{"location":"python/DataStructure/03_TimeComplexity/#334","text":"\u5728\u6570\u636e\u65e0\u5e8f\u7684\u60c5\u51b5\u4e0b\uff0c\u4f7f\u7528\u987a\u5e8f\u641c\u7d22\u6765\u627e\u5230\u76ee\u6807\u5143\u7d20\u3002 \u5728\u6570\u636e\u6709\u5e8f\u7684\u60c5\u51b5\u4e0b\uff0c\u4f7f\u7528\u4e8c\u5206\u641c\u7d22\u6765\u627e\u5230\u76ee\u6807\u5143\u7d20\u3002 Python\u4e2d\u5b9e\u73b0\u4e8c\u5206\u641c\u7d22\u7684\u601d\u8def\uff1a \u5047\u8bbe\u5217\u8868\u91cc\u7684\u5143\u7d20\u90fd\u4ee5\u5347\u5e8f\u6392\u5e8f\u3002 \u641c\u7d22\u7b97\u6cd5\u9996\u5148\u5230\u5217\u8868\u7684\u4e2d\u95f4\u4f4d\u7f6e\uff0c\u5e76\u628a\u8fd9\u4e2a\u4f4d\u7f6e\u7684\u5143\u7d20\u4e0e\u76ee\u6807\u5143\u7d20\u8fdb\u884c\u6bd4\u8f83\uff1b \u5982\u679c\u5339\u914d\uff0c\u90a3\u4e48\u7b97\u6cd5\u5c31\u8fd4\u56de\u5f53\u524d\u4f4d\u7f6e\u3002\u5982\u679c\u76ee\u6807\u5143\u7d20\u5c0f\u4e8e\u5f53\u524d\u5143\u7d20\uff0c\u90a3\u4e48\u7b97\u6cd5\u5c06\u4f1a\u641c\u7d22\u4e2d\u95f4\u4f4d\u7f6e\u4e4b\u524d\u7684\u90e8\u5206\uff1b \u5982\u679c\u76ee\u6807\u5143\u7d20\u5927\u4e8e\u5f53\u524d\u5143\u7d20\uff0c\u5219\u641c\u7d22\u4e2d\u95f4\u4f4d\u7f6e\u4e4b\u540e\u7684\u90e8\u5206\u3002 \u5728\u627e\u5230\u4e86\u76ee\u6807\u5143\u7d20\u6216\u8005\u5f53\u524d\u5f00\u59cb\u4f4d\u7f6e\u5927\u4e8e\u5f53\u524d\u7ed3\u675f\u4f4d\u7f6e\u65f6\uff0c\u505c\u6b62\u641c\u7d22\u8fc7\u7a0b\u3002 \u4e0b\u9762\u662f\u4e8c\u5206\u641c\u7d22\u51fd\u6570\u7684\u4ee3\u7801\u3002\u4ee5\u5217\u8868 [2, 20, 5, 0, 1, 0, 9] \u4e3a\u4f8b\uff1a \u6392\u5e8f\u540e\u7684\u5217\u8868\u4e3a [0, 0, 1, 2, 5, 9, 20] \uff1b \u6392\u5e8f\u540e\u5217\u8868\u957f\u5ea6\u662f7\uff0c\u6240\u4ee5\u521d\u59cbmidpoint=3\uff0c\u5bf9\u5e94\u5217\u8868\u503c\u662f2\uff1b def binarySearch ( target , sortedLyst ): left = 0 right = len ( sortedLyst ) - 1 while left <= right : midpoint = ( left + right ) // 2 if target == sortedLyst [ midpoint ]: return midpoint elif target < sortedLyst [ midpoint ]: right = midpoint - 1 else : left = midpoint + 1 return - 1 def main (): myList = [ 2 , 20 , 5 , 0 , 1 , 0 , 9 ] sortedList = sorted ( myList ) # \u5982\u679c\u4f7f\u7528myList.sort()\uff0c\u5219\u4f1a\u4fee\u6539myList\u672c\u8eab locatedIndex = binarySearch ( 5 , sortedList ) print ( sortedList ) print ( locatedIndex , sortedList [ locatedIndex ]) if __name__ == \"__main__\" : main () # \u8fd0\u7b97\u7ed3\u679c\uff1a # [0, 0, 1, 2, 5, 9, 20] # 4 5 # \u5982\u679c\u6267\u884cbinarySearch(0, sortedList)\uff0c\u5219\u4f1a\u8fd4\u56de\u7b2c\u4e8c\u4e2a0\u7684\u7d22\u5f15 # [0, 0, 1, 2, 5, 9, 20] # 1 0 \u4e0a\u9762\u4e8c\u5206\u6cd5\u7b97\u6cd5\u590d\u6742\u5ea6\u5206\u6790\uff1a \u7b97\u6cd5\u91cc\u53ea\u6709\u4e00\u4e2a\u5faa\u73af\uff0c\u5e76\u4e14\u6ca1\u6709\u5d4c\u5957\u6216\u9690\u85cf\u7684\u5faa\u73af\u3002\u5982\u679c\u76ee\u6807\u4e0d\u5728\u5217\u8868\u91cc\uff0c\u5c31\u4f1a\u5f97\u5230\u6700\u574f\u60c5\u51b5\uff0c\u5373\u904d\u5386\u5217\u8868\u7684\u4e00\u534a\uff0c\u5373\u5faa\u73af\u5217\u8868\u5927\u5c0f\u4e0d\u65ad\u9664\u4ee52\u76f4\u81f3\u5546\u4e3a1\u7684\u6b21\u6570\u3002 \u5bf9\u4e8e\u5927\u5c0f\u4e3a n \u7684\u5217\u8868\u6765\u8bf4\uff0c\u4e5f\u5c31\u662f\u4f60\u9700\u8981\u6267\u884c n/2/2/.../2 \u6b21\uff0c\u76f4\u5230\u7ed3\u679c\u4e3a1\u3002\u5047\u8bbe k \u662f n \u53ef\u4ee5\u9664\u4ee52\u7684\u6b21\u6570\uff0c\u90a3\u4e48\u6c42\u89e3 k \u4f1a\u6709 n/(2^k)=1 \uff0c\u5373 n=2^k \uff0c\u5373 k=log(n,2) \u3002\u56e0\u6b64\uff0c\u4e8c\u5206\u641c\u7d22\u5728\u6700\u574f\u60c5\u51b5\u4e0b\u7684\u590d\u6742\u5ea6\u4e3aO(log(n,2))\u3002","title":"3.3.4.\u57fa\u4e8e\u6709\u5e8f\u5217\u8868\u7684\u4e8c\u5206\u641c\u7d22"},{"location":"python/DataStructure/03_TimeComplexity/#335","text":"\u4e8c\u5206\u641c\u7d22\u548c\u6700\u5c0f\u503c\u641c\u7d22\u90fd\u6709\u4e00\u4e2a\u5047\u8bbe\uff0c\u90a3\u5c31\u662f\u201c\u5217\u8868\u91cc\u7684\u5143\u7d20\u5f7c\u6b64\u4e4b\u95f4\u662f\u53ef\u4ee5\u6bd4\u8f83\u7684\u201d\u3002\u5373\uff0c\u8fd9\u4e9b\u5143\u7d20\u5c5e\u4e8e\u540c\u4e00\u4e2a\u7c7b\u578b\uff0c\u5373\uff0c\u53ef\u4ee5\u4f7f\u7528\u6bd4\u8f83\u8fd0\u7b97\u7b26 == \u3001 < \u548c > \u3002 Python\u5185\u7f6e\u7684\u7c7b\u578b\u5bf9\u8c61\uff0c\u5982\u6570\u5b57\u3001\u5b57\u7b26\u4e32\u548c\u5217\u8868\uff0c\u90fd\u652f\u6301\u6bd4\u8f83\u8fd0\u7b97\u7b26\u3002 \u4e3a\u4e86\u80fd\u591f\u8ba9\u7b97\u6cd5\u5bf9\u65b0\u7684\u7c7b\u5bf9\u8c61\u4f7f\u7528\u6bd4\u8f83\u8fd0\u7b97\u7b26 == \u3001 < \u548c > \uff0c\u5e94\u8be5\u5728\u8fd9\u4e2a\u7c7b\u91cc\u5b9a\u4e49 __eq__ \u3001 __lt__ \u548c __gt__ \u65b9\u6cd5\u3002\u5728\u5b9a\u4e49\u4e86\u8fd9\u4e9b\u65b9\u6cd5\u4e4b\u540e\uff0c\u5176\u4ed6\u6bd4\u8f83\u8fd0\u7b97\u7b26\u7684\u65b9\u6cd5\u5c06\u81ea\u52a8\u751f\u6210\u3002 \u4f8b\u5982\uff0c __lt__ \u7684\u5b9a\u4e49\u5982\u4e0b\uff0c\u5982\u679c self \u5c0f\u4e8e other \uff0c\u90a3\u4e48\u8fd9\u4e2a\u65b9\u6cd5\u5c06\u8fd4\u56de True \uff1b\u5426\u5219\uff0c\u8fd4\u56de False \u3002 __lt__ \u65b9\u6cd5\u4f1a\u4e3a\u4e24\u4e2a\u8d26\u6237\u5bf9\u8c61\u7684 name \u5b57\u6bb5\u8c03\u7528\u8fd0\u7b97\u7b26 < \u3002 \u540d\u79f0\u5b57\u6bb5\u662f\u5b57\u7b26\u4e32\uff0c\u5b57\u7b26\u4e32\u7c7b\u578b\u5df2\u7ecf\u5305\u542b\u5728 __lt__ \u65b9\u6cd5\u91cc\u3002 \u5728\u4f7f\u7528\u8fd0\u7b97\u7b26 < \u65f6\uff0cPython\u4f1a\u81ea\u52a8\u8fd0\u884c\u5b57\u7b26\u4e32\u7684 __lt__ \u65b9\u6cd5\uff0c\u8fd9\u4e0e\u8c03\u7528 str \u51fd\u6570\u65f6\u81ea\u52a8\u8fd0\u884c __str__ \u65b9\u6cd5\u662f\u7c7b\u4f3c\u7684\u3002 def __lt__ ( self , other ): \u793a\u4f8b\uff1a\u8fd4\u56de\u50a8\u84c4\u8d26\u6237\u7684\u6240\u6709\u4eba\u540d\u5b57\u3001PIN\u7801\u3001\u4f59\u989d\u3002 class SavingsAccount ( object ): \"\"\"\u8fd4\u56de\u50a8\u84c4\u8d26\u6237\u7684\u6240\u6709\u4eba\u540d\u5b57\u3001PIN\u7801\u3001\u4f59\u989d\"\"\" def __init__ ( self , name , pin , balance = 0.0 ): self . name = name self . pin = pin self . balance = balance def __lt__ ( self , other ): return self . name < other . name # Other methods, including __eq__ def main (): s1 = SavingsAccount ( \"Ken\" , \"1001\" , 0 ) s2 = SavingsAccount ( \"Bill\" , \"1001\" , 30 ) s3 = SavingsAccount ( \"Ken\" , \"1000\" , 0 ) s4 = s1 print ( \"s1 < s2: \" , s1 < s2 ) print ( \"s2 < s1: \" , s2 < s1 ) print ( \"s2 > s1: \" , s2 > s1 ) print ( \"s2 == s1: \" , s2 == s1 ) print ( \"s1 == s3: \" , s1 == s3 ) print ( \"s1 == s4: \" , s1 == s4 ) if __name__ == \"__main__\" : main () # \u8fd0\u7b97\u7ed3\u679c\uff1a # s1 < s2: False # s2 < s1: True # s2 > s1: False # s2 == s1: False # s1 == s3: False # s1 == s4: True \u63d0\u793a\uff1a\u5728Python\u4e2d\uff0c\u9ed8\u8ba4\u662f\u6309\u7167ASCII\u7684\u5927\u5c0f\u6bd4\u8f83\u5b57\u7b26\u4e32\u7684\uff0c\u5373\u4ece\u5b57\u7b26\u4e32\u7684\u7b2c\u4e00\u4e2a\u5b57\u7b26\u8fdb\u884c\u6bd4\u8f83\uff0c\u5982\u679c\u76f8\u7b49\uff0c\u5219\u7ee7\u7eed\u6bd4\u8f83\u4e0b\u4e00\u4e2a\u5b57\u7b26\uff0c\u76f4\u5230\u5206\u51fa\u5927\u5c0f\uff0c\u6216\u8005\u8fd8\u6ca1\u5206\u51fa\u5927\u5c0f\uff0c\u6709\u4e00\u4e2a\u5b57\u7b26\u4e32\u5df2\u7ecf\u5230\u5934\u4e86\uff0c\u90a3\u4e48\u8f83\u957f\u7684\u90a3\u4e00\u4e2a\u5b57\u7b26\u4e32\u5927\u3002","title":"3.3.5.\u6bd4\u8f83\u6570\u636e\u5143\u7d20"},{"location":"python/DataStructure/03_TimeComplexity/#336","text":"\u5047\u8bbe\u4e00\u4e2a\u5217\u8868\u5728\u7d22\u5f150\uff5e9\u7684\u4f4d\u7f6e\u5904\u5305\u542b\u503c20\u300144\u300148\u300155\u300162\u300166\u300174\u300188\u300193\u300199\uff0c\u8bf7\u5728\u7528\u4e8c\u5206\u641c\u7d22\u67e5\u627e\u76ee\u6807\u5143\u7d2090\u7684\u65f6\u5019\uff0c\u5bf9\u53d8\u91cfleft\u3001right\u548cmidpoint\u7684\u503c\u8fdb\u884c\u8ddf\u8e2a\u3002\u6539\u53d8\u76ee\u6807\u5143\u7d20\u4e3a44\uff0c\u5e76\u91cd\u590d\u8fd9\u4e2a\u6b65\u9aa4\u3002 \u89e3\u7b54\uff1a \u4e0b\u9762\u662f\u4ee3\u7801\u548c\u8ddf\u8e2a\u7ed3\u679c\u3002 def binarySearch ( target , sortedLyst ): left = 0 right = len ( sortedLyst ) - 1 print ( \" %5s%10s%10s \" % ( \"left\" , \"midpoint\" , \"right\" )) while left <= right : midpoint = ( left + right ) // 2 print ( \" %5s%10s%10s \" % ( left , midpoint , right )) if target == sortedLyst [ midpoint ]: return midpoint elif target < sortedLyst [ midpoint ]: right = midpoint - 1 else : left = midpoint + 1 return - 1 def main (): myList = [ 20 , 44 , 48 , 55 , 62 , 66 , 74 , 88 , 93 , 99 ] sortedList = sorted ( myList ) locatedIndex = binarySearch ( 44 , sortedList ) if __name__ == \"__main__\" : main () # \u8fd0\u7b97\u7ed3\u679c\uff1a # Target = 90 # left midpoint right # 0 4 9 # 5 7 9 # 8 8 9 # # Target = 44 # left midpoint right # 0 4 9 # 0 1 3 \u901a\u5e38\u6765\u8bf4\uff0c\u67e5\u627e\u7535\u8bdd\u7c3f\u4e2d\u6761\u76ee\u7684\u65b9\u6cd5\u4e0e\u4e8c\u5206\u641c\u7d22\u5e76\u4e0d\u5b8c\u5168\u76f8\u540c\uff0c\u56e0\u4e3a\u4f7f\u7528\u7535\u8bdd\u7c3f\u7684\u65f6\u5019\uff0c\u5e76\u4e0d\u4f1a\u6bcf\u6b21\u90fd\u7ffb\u5230\u88ab\u641c\u7d22\u7684\u5b50\u5217\u8868\u7684\u4e2d\u70b9\u3002\u4e00\u822c\u6765\u8bf4\uff0c\u53ef\u4ee5\u6839\u636e\u8fd9\u4e2a\u4eba\u7684\u59d3\u6c0f\u7684\u7b2c\u4e00\u4e2a\u5b57\u6bcd\u987a\u5e8f\u6765\u4f30\u7b97\u76ee\u6807\u53ef\u80fd\u4f1a\u5728\u7684\u4f4d\u7f6e\u3002\u4f8b\u5982\uff0c\u5f53\u67e5\u627e\u201cSmith\u201d\u7684\u7535\u8bdd\u65f6\uff0c\u4f60\u4f1a\u9996\u5148\u67e5\u770b\u7535\u8bdd\u7c3f\u4e0b\u534a\u90e8\u5206\u7684\u4e2d\u95f4\uff0c\u800c\u4e0d\u662f\u6574\u4e2a\u7535\u8bdd\u7c3f\u7684\u4e2d\u95f4\u3002\u8bf7\u5bf9\u4e8c\u5206\u641c\u7d22\u7b97\u6cd5\u5c1d\u8bd5\u8fdb\u884c\u4fee\u6539\uff0c\u4ece\u800c\u53ef\u4ee5\u5728\u5904\u7406\u540d\u79f0\u5217\u8868\u7684\u65f6\u5019\u6a21\u62df\u8fd9\u4e2a\u7b56\u7565\u3002\u5b83\u7684\u8ba1\u7b97\u590d\u6742\u5ea6\u4e0e\u6807\u51c6\u7684\u4e8c\u5206\u641c\u7d22\u76f8\u6bd4\u8f83\u4f1a\u66f4\u597d\u5417\uff1f \u89e3\u7b54\uff1a\u4e0b\u9762\u662f\u4ee3\u7801\u548c\u8ffd\u8e2a\u7ed3\u679c\u3002\u901a\u8fc7\u5bf9\u6bd4\u4e0d\u540c\u6743\u91cd\u5355\u8bcd\u5230\u7684\u641c\u7d22\uff0c\u53ef\u4ee5\u53d1\u73b0\u6743\u91cd\u4e8c\u5206\u6cd5\u7684\u6548\u7387\u82e5\u8981\u4f18\u4e8e\u4f20\u7edf\u4e8c\u5206\u6cd5\uff0c\u662f\u9700\u8981\u6ee1\u8db3\u4e00\u5b9a\u7684\u6761\u4ef6\u7684\u3002 \u5728\u641c\u7d22\u7684\u7b2c\u4e00\u8f6e\u4e2d\uff0c\u4e2d\u95f4\u4f4d\u7f6e\u5c06\u53d6\u51b3\u4e8e\u5217\u8868\u7684\u5927\u5c0f\u548c\u76ee\u6807\u540d\u5b57\u7684\u7b2c\u4e00\u4e2a\u5b57\u6bcd\u7684\u987a\u5e8f\u503c\u3002\u56e0\u6b64\uff0c\u7b2c\u4e00\u8f6e\u641c\u7d22\u5c06\u6d88\u9664\u6bd4\u4ee5\u524d\u66f4\u591a\u7684\u5143\u7d20\uff0c\u5e76\u4e14\u5982\u679c\u9700\u8981\u5176\u4ed6\u8f6e\u641c\u7d22\uff0c\u5b83\u4eec\u7684\u641c\u7d22\u7a7a\u95f4\u4e5f\u4f1a\u66f4\u5c0f\u3002\u7136\u800c\uff0c\u5728\u6700\u574f\u60c5\u51b5\u4e0b\uff0c\u4fee\u6539\u540e\u7684\u7b97\u6cd5\u4ecd\u7136\u6bd4O(1)\u66f4\u63a5\u8fd1O(log n)\u3002 def binarySearch ( target , sortedLyst ): left = 0 right = len ( sortedLyst ) - 1 print ( \" %5s%10s%10s \" % ( \"left\" , \"midpoint\" , \"right\" )) while left <= right : midpoint = ( left + right ) // 2 print ( \" %5s%10s%10s \" % ( left , midpoint , right )) if target == sortedLyst [ midpoint ]: return midpoint elif target < sortedLyst [ midpoint ]: right = midpoint - 1 else : left = midpoint + 1 return - 1 def letter_position ( myLetter ): letter = myLetter . lower () # \u8f6c\u6210\u5c0f\u5199\u5b57\u6bcd alphabet = \"abcdefghijklmnopqrstuvwxyz\" if letter in alphabet : return alphabet . index ( letter ) + 1 # \u4f4d\u7f6e\u63091\uff5e26\u8ba1\u7b97 else : return None # \u975e\u5b57\u6bcd def dictSearch ( target , sortedLyst ): left = 0 right = len ( sortedLyst ) - 1 # \u9996\u5b57\u6bcd\u5728\u5b57\u6bcd\u8868\u4e2d\u7684\u767e\u5206\u4f4d letter_position_range = letter_position ( target [ 0 ]) * 100 // 26 # \u6309\u7167\u6240\u5f97\u7684\u9996\u5b57\u6bcd\u5728\u5b57\u6bcd\u8868\u4e2d\u7684\u767e\u5206\u4f4d\uff0c\u4f5c\u4e3a\u7ed9\u5b9a\u5b57\u4e32\u4e2d\u8bbe\u5b9a\u641c\u7d22\u8d77\u59cb\u767e\u5206\u4f4d midpoint = letter_position_range * ( len ( sortedLyst ) - 1 ) // 100 print ( \" %5s%10s%10s \" % ( \"left\" , \"midpoint\" , \"right\" )) while left <= right : print ( \" %5s%10s%10s \" % ( left , midpoint , right )) if target == sortedLyst [ midpoint ]: return midpoint elif target < sortedLyst [ midpoint ]: right = midpoint - 1 else : left = midpoint + 1 midpoint = ( left + right ) // 2 return - 1 def main (): myList = [ \"Bob\" , \"Charlie\" , \"Eva\" , \"Alice\" , \"Grace\" , \"David\" , \"Smith\" , \"Frank\" , \"Zoe\" , \"Jack\" ] sortedList = sorted ( myList ) print ( sortedList ) print ( \"=====call binarySearch=====\" ) locatedIndex = binarySearch ( \"Alice\" , sortedList ) print ( \"Found\" , sortedList [ locatedIndex ], \"in position\" , locatedIndex ) print ( \"=====call dictSearch=====\" ) locatedIndex = dictSearch ( \"Alice\" , sortedList ) print ( \"Found\" , sortedList [ locatedIndex ], \"in position\" , locatedIndex ) if __name__ == \"__main__\" : main () # \u8fd0\u7b97\u7ed3\u679c\uff1a # \u641c\u7d22Alice # ['Alice', 'Bob', 'Charlie', 'David', 'Eva', 'Frank', 'Grace', 'Jack', 'Smith', 'Zoe'] # =====call binarySearch===== # left midpoint right # 0 4 9 # 0 1 3 # 0 0 0 # Found Alice in position 0 # =====call dictSearch===== # left midpoint right # 0 0 9 # Found Alice in position 0 # \u641c\u7d22Bob # ['Alice', 'Bob', 'Charlie', 'David', 'Eva', 'Frank', 'Grace', 'Jack', 'Smith', 'Zoe'] # =====call binarySearch===== # left midpoint right # 0 4 9 # 0 1 3 # Found Bob in position 1 # =====call dictSearch===== # left midpoint right # 0 0 9 # 1 5 9 # 1 2 4 # 1 1 1 # Found Bob in position 1 # \u641c\u7d22Smith # ['Alice', 'Bob', 'Charlie', 'David', 'Eva', 'Frank', 'Grace', 'Jack', 'Smith', 'Zoe'] # =====call binarySearch===== # left midpoint right # 0 4 9 # 5 7 9 # 8 8 9 # Found Smith in position 8 # =====call dictSearch===== # left midpoint right # 0 6 9 # 7 8 9 # Found Smith in position 8 # \u641c\u7d22Zoe # ['Alice', 'Bob', 'Charlie', 'David', 'Eva', 'Frank', 'Grace', 'Jack', 'Smith', 'Zoe'] # =====call binarySearch===== # left midpoint right # 0 4 9 # 5 7 9 # 8 8 9 # 9 9 9 # Found Zoe in position 9 # =====call dictSearch===== # left midpoint right # 0 9 9 # Found Zoe in position 9","title":"3.3.6.\u7ec3\u4e60\u9898"},{"location":"python/DataStructure/03_TimeComplexity/#34","text":"\u4e0b\u9762\u662fswap\u51fd\u6570\u7684\u4f8b\u5b50\uff0c\u5b9e\u73b0\u4e86\uff1a \u5047\u8bbe\u90fd\u5728\u6574\u6570\u5217\u8868\u4e0a\u8fd0\u884c\uff1b \u4ea4\u6362\u5217\u8868\u4e2d\u4e24\u4e2a\u5143\u7d20\u7684\u4f4d\u7f6e\uff1b def swap ( lyst , i , j ): \"\"\"\u4ea4\u6362\u5143\u7d20\u4f4d\u7f6e\u4e3ai\u548cj\u7684\u5143\u7d20\"\"\" temp = lyst [ i ] lyst [ i ] = lyst [ j ] lyst [ j ] = temp def main (): myList = [ 9 , 4 , 2 , 7 , 6 , 8 , 1 ] print ( myList ) swap ( myList , 3 , 5 ) print ( myList ) if __name__ == \"__main__\" : main () # \u8fd0\u884c\u7ed3\u679c\uff1a # [9, 4, 2, 7, 6, 8, 1] # [9, 4, 2, 8, 6, 7, 1]","title":"3.4.\u57fa\u672c\u7684\u6392\u5e8f\u7b97\u6cd5"},{"location":"python/DataStructure/03_TimeComplexity/#341","text":"\u9009\u62e9\u6392\u5e8f\uff08selection sort\uff09\uff1a\uff08\u4ee5\u5217\u8868\u4e3a\u4f8b\uff09 \u5728\u4e00\u4e2a\u957f\u5ea6\u4e3a N \u7684\u65e0\u5e8f\u5217\u8868\u4e2d\uff0c\u7b2c\u4e00\u6b21\u904d\u5386 n-1 \u4e2a\u6570\u627e\u5230\u6700\u5c0f\u7684\u548c\u7b2c\u4e00\u4e2a\u6570\u4ea4\u6362\u3002 \u7b2c\u4e8c\u6b21\u4ece\u4e0b\u4e00\u4e2a\u6570\u5f00\u59cb\u904d\u5386 n-2 \u4e2a\u6570\uff0c\u627e\u5230\u6700\u5c0f\u7684\u6570\u548c\u7b2c\u4e8c\u4e2a\u6570\u4ea4\u6362\u3002 \u91cd\u590d\u4ee5\u4e0a\u64cd\u4f5c\u76f4\u5230\u7b2c n-1 \u6b21\u904d\u5386\u6700\u5c0f\u7684\u6570\u548c\u7b2c n-1 \u4e2a\u6570\u4ea4\u6362\uff0c\u6392\u5e8f\u5b8c\u6210\u3002 \u8fd9\u4e2a\u7b97\u6cd5\u5728\u6bcf\u6b21\u901a\u8fc7\u4e3b\u5faa\u73af\u65f6\uff0c\u90fd\u4f1a\u9009\u62e9\u8981\u79fb\u52a8\u7684\u90a3\u4e00\u4e2a\u5143\u7d20\u3002 \u7b97\u6cd5\u590d\u6742\u5ea6\uff1a \u7b2c1\u6b21\u6267\u884c\u5916\u90e8\u5faa\u73af\u65f6\uff0c\u5185\u90e8\u5faa\u73af\u4f1a\u6267\u884cn-1\u6b21\uff1b \u7b2c2\u6b21\u6267\u884c\u5916\u90e8\u5faa\u73af\u65f6\uff0c\u5185\u90e8\u5faa\u73af\u4f1a\u6267\u884cn-2\u6b21\uff1b \u6700\u540e\u4e00\u6b21\u6267\u884c\u5916\u90e8\u5faa\u73af\u65f6\uff0c\u5185\u90e8\u5faa\u73af\u4f1a\u6267\u884c1\u6b21\uff1b \u6240\u4ee5\uff0c\u5927\u5c0f\u4e3a n \u7684\u5217\u8868\uff0c\u4e00\u5171\u9700\u8981\u7684\u6bd4\u8f83\u6b21\u6570\u662f (n-1)+(n-2)+...+1 \uff0c\u5316\u7b80\u4e3a n*(n-1)/2 \uff0c\u5373 (1/2)*n^2+(1/2)*n \u3002\u5f53 n \u6bd4\u8f83\u5927\u65f6\uff0c\u53ef\u4ee5\u9009\u62e9\u6700\u9ad8\u6b21\u7684\u9879\u5e76\u5ffd\u7565\u7cfb\u6570\uff0c\u56e0\u6b64\u5728\u6240\u6709\u60c5\u51b5\u4e0b\uff0c\u9009\u62e9\u6392\u5e8f\u7684\u590d\u6742\u5ea6\u90fd\u662fO(n^2)\u3002 \u5bf9\u4e8e\u5927\u578b\u6570\u636e\u96c6\u6765\u8bf4\uff0c\u4ea4\u6362\u5143\u7d20\u7684\u6210\u672c\u53ef\u80fd\u4f1a\u5f88\u9ad8\u3002\u56e0\u4e3a\u8fd9\u4e2a\u7b97\u6cd5\u53ea\u4f1a\u5728\u5916\u90e8\u5faa\u73af\u91cc\u5bf9\u6570\u636e\u5143\u7d20\u8fdb\u884c\u4ea4\u6362\uff0c\u6240\u4ee5\u5728\u6700\u574f\u60c5\u51b5\u548c\u5e73\u5747\u60c5\u51b5\u4e0b\uff0c\u9009\u62e9\u6392\u5e8f\u7684\u989d\u5916\u6210\u672c\u662f\u7ebf\u6027\u7684\u3002 \u7b97\u6cd5\u4ee3\u7801\uff1a def swap ( lyst , i , j ): \"\"\"\u4ea4\u6362\u5143\u7d20\u4f4d\u7f6e\u4e3ai\u548cj\u7684\u5143\u7d20\"\"\" temp = lyst [ i ] lyst [ i ] = lyst [ j ] lyst [ j ] = temp def selectionSort ( lyst ): \"\"\"\u5b9e\u73b0\u4ea4\u6362\u6392\u5e8f\u7b97\u6cd5\"\"\" i = 0 while i < len ( lyst ) - 1 : # \u5b9e\u73b0n-1\u6b21\u641c\u7d22 minIndex = i # \u6700\u5c0f\u5143\u7d20\u4f4d\u7f6e j = i + 1 while j < len ( lyst ): # \u5411\u540e\u904d\u5386\u641c\u7d22\uff0c\u66f4\u65b0\u6700\u5c0f\u5143\u7d20\u4f4d\u7f6e if lyst [ j ] < lyst [ minIndex ]: minIndex = j j += 1 if minIndex != i : # \u5982\u679c\u9700\u8981\uff0c\u5219\u4ea4\u6362\u5143\u7d20\u4f4d\u7f6e swap ( lyst , minIndex , i ) i += 1 def main (): myList = [ 9 , 4 , 2 , 7 , 6 , 8 , 1 ] print ( \"Before selection sort \" , myList ) selectionSort ( myList ) print ( \"After selection sort \" , myList ) if __name__ == \"__main__\" : main () # \u8fd0\u884c\u7ed3\u679c\uff1a # Before selection sort [9, 4, 2, 7, 6, 8, 1] # After selection sort [1, 2, 4, 6, 7, 8, 9]","title":"3.4.1.\u9009\u62e9\u6392\u5e8f"},{"location":"python/DataStructure/03_TimeComplexity/#342","text":"\u5192\u6ce1\u6392\u5e8f\uff08Bubble Sort\uff09\uff1a \u6bd4\u8f83\u76f8\u90bb\u4e24\u4e2a\u6570\u636e\u5982\u679c\u3002\u7b2c\u4e00\u4e2a\u6bd4\u7b2c\u4e8c\u4e2a\u5927\uff0c\u5c31\u4ea4\u6362\u4e24\u4e2a\u6570\uff1b \u5bf9\u6bcf\u4e00\u4e2a\u76f8\u90bb\u7684\u6570\u505a\u540c\u68371\u7684\u5de5\u4f5c\uff0c\u8fd9\u6837\u4ece\u5f00\u59cb\u4e00\u961f\u5230\u7ed3\u5c3e\u4e00\u961f\u5728\u6700\u540e\u7684\u6570\u5c31\u662f\u6700\u5927\u7684\u6570\u3002 \u9488\u5bf9\u6240\u6709\u5143\u7d20\u4e0a\u9762\u7684\u64cd\u4f5c\uff0c\u9664\u4e86\u6700\u540e\u4e00\u4e2a\u3002 \u91cd\u590d1~3\u6b65\u9aa4\uff0c\u76f4\u81f3\u5b8c\u6210\u3002 \u7b97\u6cd5\u590d\u6742\u5ea6\uff1a \u5192\u6ce1\u6392\u5e8f\u53ea\u4f1a\u6539\u5584\u6700\u597d\u60c5\u51b5\u4e0b\u7684\u590d\u6742\u5ea6\u3002\u5bf9\u4e8e\u5e73\u5747\u60c5\u51b5\u800c\u8a00\uff0c\u7531\u4e8e\u4f9d\u7136\u662f\u53cc\u91cd\u5faa\u73af\u65f6\u95f4\uff0c\u6240\u4ee5\u590d\u6742\u5ea6\u662fO(n^2)\uff1b \u5bf9\u4e8e\u6709\u5e8f\u7684\u5217\u8868\u6765\u8bf4\uff0c\u4fee\u6539\u540e\u7684\u5192\u6ce1\u6392\u5e8f\u4f1a\u6bd4\u9009\u62e9\u6392\u5e8f\u7684\u6267\u884c\u6548\u7387\u66f4\u9ad8\u3002 \u7b97\u6cd5\u4ee3\u7801\uff1a def swap ( lyst , i , j ): \"\"\"\u4ea4\u6362\u5143\u7d20\u4f4d\u7f6e\u4e3ai\u548cj\u7684\u5143\u7d20\"\"\" temp = lyst [ i ] lyst [ i ] = lyst [ j ] lyst [ j ] = temp def selectionSort ( lyst ): \"\"\"\u5b9e\u73b0\u4ea4\u6362\u6392\u5e8f\u7b97\u6cd5\"\"\" i = 0 while i < len ( lyst ) - 1 : # \u5b9e\u73b0n-1\u6b21\u641c\u7d22 minIndex = i # \u6700\u5c0f\u5143\u7d20\u4f4d\u7f6e j = i + 1 while j < len ( lyst ): # \u5411\u540e\u904d\u5386\u641c\u7d22\uff0c\u66f4\u65b0\u6700\u5c0f\u5143\u7d20\u4f4d\u7f6e if lyst [ j ] < lyst [ minIndex ]: minIndex = j j += 1 if minIndex != i : # \u5982\u679c\u9700\u8981\uff0c\u5219\u4ea4\u6362\u5143\u7d20\u4f4d\u7f6e swap ( lyst , minIndex , i ) i += 1 def bubbleSortWithTweak ( lyst ): \"\"\"\u5b9e\u73b0\u5192\u6ce1\u6392\u5e8f\u7b97\u6cd5\"\"\" n = len ( lyst ) while n > 1 : swapped = False # \u7528\u5e03\u5c14\u6807\u5fd7\u6765\u8ffd\u8e2a\u6709\u6ca1\u6709\u53d1\u751f\u4ea4\u6362 i = 1 while i < n : if lyst [ i ] < lyst [ i - 1 ]: # \u5982\u679c\u540e\u9762\u5143\u7d20\u7684\u503c\u6bd4\u524d\u9762\u5143\u7d20\u7684\u5927\uff0c\u5219\u4ea4\u6362\u5143\u7d20\u4f4d\u7f6e\uff0c\u76f4\u81f3\u628a\u5faa\u73af\u4e2d\u7684\u6700\u5927\u5143\u7d20\u79fb\u5230\u6700\u540e swap ( lyst , i , i - 1 ) swapped = True i += 1 if not swapped : # \u5982\u679c\u4e0d\u9700\u8981\u4ea4\u6362\uff0c\u76f4\u63a5return return n -= 1 def main (): myList = [ 9 , 4 , 2 , 7 , 6 , 8 , 1 ] # \u6bd4\u8f83\u6392\u5e8f print ( \"Before selection sort \" , myList ) selectionSort ( myList ) print ( \"After selection sort \" , myList ) # \u5192\u6ce1\u6392\u5e8f myList = [ 9 , 4 , 2 , 7 , 6 , 8 , 1 ] print ( \"Before bubble sort \" , myList ) bubbleSortWithTweak ( myList ) print ( \"After bubble sort \" , myList ) if __name__ == \"__main__\" : main () # \u8fd0\u884c\u7ed3\u679c\uff1a # Before selection sort [9, 4, 2, 7, 6, 8, 1] # After selection sort [1, 2, 4, 6, 7, 8, 9] # Before bubble sort [9, 4, 2, 7, 6, 8, 1] # After bubble sort [1, 2, 4, 6, 7, 8, 9]","title":"3.4.2.\u5192\u6ce1\u6392\u5e8f"},{"location":"python/DataStructure/03_TimeComplexity/#343","text":"\u63d2\u5165\u6392\u5e8f\uff08Insertion-Sort\uff09\u662f\u901a\u8fc7\u6784\u5efa\u6709\u5e8f\u5e8f\u5217\uff0c\u5bf9\u4e8e\u672a\u6392\u5e8f\u6570\u636e\uff0c\u5728\u5df2\u6392\u5e8f\u5e8f\u5217\u4e2d\u4ece\u540e\u5411\u524d\u626b\u63cf\uff0c\u627e\u5230\u76f8\u5e94\u4f4d\u7f6e\u5e76\u63d2\u5165\u3002\u63d2\u5165\u6392\u5e8f\u90fd\u91c7\u7528 in-place \u5728\u6570\u7ec4\u4e0a\u5b9e\u73b0\uff1a \u4ece\u7b2c\u4e00\u4e2a\u5143\u7d20\u5f00\u59cb\uff0c\u8be5\u5143\u7d20\u53ef\u4ee5\u8ba4\u4e3a\u5df2\u7ecf\u88ab\u6392\u5e8f\uff1b \u53d6\u51fa\u4e0b\u4e00\u4e2a\u5143\u7d20\uff0c\u5728\u5df2\u7ecf\u6392\u5e8f\u7684\u5143\u7d20\u5e8f\u5217\u4ece\u540e\u5411\u524d\u626b\u63cf\uff1b \u5982\u679c\u65b0\u5143\u7d20\u5c0f\u4e8e\u5df2\u6392\u5e8f\u7684\u5143\u7d20\uff0c\u5c06\u65b0\u5143\u7d20\u79fb\u5230\u4e0b\u4e00\u4f4d\u7f6e\uff1b \u91cd\u590d\u6b65\u9aa43\uff0c\u76f4\u5230\u627e\u5230\u5df2\u6392\u5e8f\u7684\u5143\u7d20\u5c0f\u4e8e\u6216\u8005\u7b49\u4e8e\u65b0\u5143\u7d20\u7684\u4f4d\u7f6e\uff1b \u5c06\u65b0\u5143\u7d20\u63d2\u5165\u5230\u8be5\u4f4d\u7f6e\u540e\uff1b \u91cd\u590d\u6b65\u9aa42~5\u3002 \u590d\u6742\u5ea6\uff1a \u548c\u9009\u62e9\u6392\u5e8f\u7c7b\u4f3c\uff0c\u904d\u5386\u6b21\u6570\u4e5f\u662f (1/2)*n^2+(1/2)*n \uff0c\u6240\u4ee5\u590d\u6742\u5ea6\u4e5f\u662fO(n^2)\u3002 \u5217\u8868\u91cc\u6709\u5e8f\u5143\u7d20\u8d8a\u591a\uff0c\u63d2\u5165\u6392\u5e8f\u7684\u6027\u80fd\u5c31\u4f1a\u8d8a\u597d\uff1b \u5728\u6709\u5e8f\u5217\u8868\u7684\u6700\u597d\u60c5\u51b5\u4e0b\uff0c\u6392\u5e8f\u590d\u6742\u5ea6\u662f\u7ebf\u6027\u7684\uff1b def swap ( lyst , i , j ): \"\"\"\u4ea4\u6362\u5143\u7d20\u4f4d\u7f6e\u4e3ai\u548cj\u7684\u5143\u7d20\"\"\" temp = lyst [ i ] lyst [ i ] = lyst [ j ] lyst [ j ] = temp def selectionSort ( lyst ): \"\"\"\u5b9e\u73b0\u4ea4\u6362\u6392\u5e8f\u7b97\u6cd5\"\"\" i = 0 while i < len ( lyst ) - 1 : # \u5b9e\u73b0n-1\u6b21\u641c\u7d22 minIndex = i # \u6700\u5c0f\u5143\u7d20\u4f4d\u7f6e j = i + 1 while j < len ( lyst ): # \u5411\u540e\u904d\u5386\u641c\u7d22\uff0c\u66f4\u65b0\u6700\u5c0f\u5143\u7d20\u4f4d\u7f6e if lyst [ j ] < lyst [ minIndex ]: minIndex = j j += 1 if minIndex != i : # \u5982\u679c\u9700\u8981\uff0c\u5219\u4ea4\u6362\u5143\u7d20\u4f4d\u7f6e swap ( lyst , minIndex , i ) i += 1 def bubbleSortWithTweak ( lyst ): \"\"\"\u5b9e\u73b0\u5192\u6ce1\u6392\u5e8f\u7b97\u6cd5\"\"\" n = len ( lyst ) while n > 1 : swapped = False # \u7528\u5e03\u5c14\u6807\u5fd7\u6765\u8ffd\u8e2a\u6709\u6ca1\u6709\u53d1\u751f\u4ea4\u6362 i = 1 while i < n : if lyst [ i ] < lyst [ i - 1 ]: # \u5982\u679c\u540e\u9762\u5143\u7d20\u7684\u503c\u6bd4\u524d\u9762\u5143\u7d20\u7684\u5927\uff0c\u5219\u4ea4\u6362\u5143\u7d20\u4f4d\u7f6e\uff0c\u76f4\u81f3\u628a\u5faa\u73af\u4e2d\u7684\u6700\u5927\u5143\u7d20\u79fb\u5230\u6700\u540e swap ( lyst , i , i - 1 ) swapped = True i += 1 if not swapped : # \u5982\u679c\u4e0d\u9700\u8981\u4ea4\u6362\uff0c\u76f4\u63a5return return n -= 1 def insertionSort ( lyst ): i = 1 # \u65b0\u5143\u7d20\u7684\u4f4d\u7f6e while i < len ( lyst ): itemToInsert = lyst [ i ] # \u65b0\u5143\u7d20 j = i - 1 # \u5df2\u6392\u5e8f\u7684\u5143\u7d20\u5e8f\u5217\u7684\u6700\u53f3\u4f4d\u7f6e while j >= 0 : if itemToInsert < lyst [ j ]: lyst [ j + 1 ] = lyst [ j ] # \u5982\u679c\u65b0\u5143\u7d20\u5c0f\u4e8e\u5df2\u6392\u5e8f\u5143\u7d20\uff0c\u5219\u5df2\u6392\u5e8f\u5143\u7d20\u5411\u540e\u79fb\u52a8\u4e00\u4e2a\u4f4d\u7f6e j -= 1 else : break # \u65b0\u5143\u7d20\u7b49\u4e8e\u6216\u8005\u5927\u4e8e\u5df2\u6392\u5e8f\u5143\u7d20\uff0c\u8df3\u51fa\u5faa\u73af\uff0c\u6b64\u65f6lyst[j + 1]\u662f\u548clyst[j]\u662f\u540c\u4e00\u4e2a\u5143\u7d20\u503c\uff0clyst[j + 1]\u4f4d\u7f6e\u662f\u7559\u7ed9\u65b0\u5143\u7d20\u7684 lyst [ j + 1 ] = itemToInsert # i += 1 def main (): myList = [ 9 , 4 , 2 , 7 , 6 , 8 , 1 ] # \u6bd4\u8f83\u6392\u5e8f print ( \"Before selection sort \" , myList ) selectionSort ( myList ) print ( \"After selection sort \" , myList ) # \u5192\u6ce1\u6392\u5e8f myList = [ 9 , 4 , 2 , 7 , 6 , 8 , 1 ] print ( \"Before bubble sort \" , myList ) bubbleSortWithTweak ( myList ) print ( \"After bubble sort \" , myList ) # \u63d2\u5165\u6392\u5e8f myList = [ 9 , 4 , 2 , 7 , 6 , 8 , 1 ] print ( \"Before insertion sort \" , myList ) insertionSort ( myList ) print ( \"After insertion sort \" , myList ) if __name__ == \"__main__\" : main () # \u8fd0\u884c\u7ed3\u679c\uff1a # Before selection sort [9, 4, 2, 7, 6, 8, 1] # After selection sort [1, 2, 4, 6, 7, 8, 9] # Before bubble sort [9, 4, 2, 7, 6, 8, 1] # After bubble sort [1, 2, 4, 6, 7, 8, 9] # Before insertion sort [9, 4, 2, 7, 6, 8, 1] # After insertion sort [1, 2, 4, 6, 7, 8, 9]","title":"3.4.3.\u63d2\u5165\u6392\u5e8f"},{"location":"python/DataStructure/03_TimeComplexity/#344","text":"\u5bf9\u4e8e\u8bb8\u591a\u7b97\u6cd5\u6765\u8bf4\uff0c\u4e0d\u80fd\u5bf9\u6240\u6709\u60c5\u51b5\u91c7\u7528\u5355\u4e00\u7684\u590d\u6742\u5ea6\u6765\u8861\u91cf\u3002\u5f53\u9047\u5230\u7279\u5b9a\u987a\u5e8f\u7684\u6570\u636e\u65f6\uff0c\u7b97\u6cd5\u7684\u884c\u4e3a\u53ef\u80fd\u4f1a\u53d8\u5f97\u66f4\u597d\u6216\u66f4\u7cdf\u3002 \u5bf9\u7b97\u6cd5\u590d\u6742\u5ea6\u884c\u4e3a\u5206\u4e3a3\u79cd\u60c5\u51b5\uff1a \u6700\u597d\u60c5\u51b5\uff08best case\uff09\u2014\u2014\u7b97\u6cd5\u5728\u4ec0\u4e48\u60c5\u51b5\u4e0b\u53ef\u4ee5\u4ee5\u6700\u5c11\u7684\u5de5\u4f5c\u91cf\u5b8c\u6210\u5de5\u4f5c\uff1f\u5728\u6700\u597d\u60c5\u51b5\u4e0b\uff0c\u7b97\u6cd5\u7684\u590d\u6742\u5ea6\u662f\u591a\u5c11\uff1f \u6700\u574f\u60c5\u51b5\uff08worst case\uff09\u2014\u2014\u7b97\u6cd5\u5728\u4ec0\u4e48\u60c5\u51b5\u4e0b\u9700\u8981\u5b8c\u6210\u6700\u591a\u7684\u5de5\u4f5c\u91cf\uff1f\u5728\u6700\u574f\u60c5\u51b5\u4e0b\uff0c\u7b97\u6cd5\u7684\u590d\u6742\u5ea6\u662f\u591a\u5c11\uff1f \u5e73\u5747\u60c5\u51b5\uff08average case\uff09\u2014\u2014\u7b97\u6cd5\u5728\u4ec0\u4e48\u60c5\u51b5\u4e0b\u7528\u9002\u91cf\u7684\u5de5\u4f5c\u91cf\u5c31\u80fd\u5b8c\u6210\u5de5\u4f5c\uff1f\u5728\u5e73\u5747\u60c5\u51b5\u4e0b\uff0c\u7b97\u6cd5\u7684\u590d\u6742\u5ea6\u662f\u591a\u5c11\uff1f \u4e0b\u9762\u5206\u522b\u5bf9\u6700\u5c0f\u503c\u641c\u7d22\u3001\u987a\u5e8f\u641c\u7d22\u548c\u5192\u6ce1\u6392\u5e8f\u8fdb\u884c\u6700\u597d\u60c5\u51b5\u3001\u6700\u574f\u60c5\u51b5\u548c\u5e73\u5747\u60c5\u51b5\u4e0b\u7684\u6027\u80fd\u5206\u6790\uff0c\u4e0d\u8003\u8651\u5b9e\u9645\u786c\u4ef6\u548c\u7f16\u7a0b\u8bed\u8a00\u7b49\u7684\u5f71\u54cd\u3002 \u6700\u5c0f\u503c\u641c\u7d22\uff08Minimum Value Search\uff09 \u6700\u597d\u60c5\u51b5\uff1a\u6700\u5c0f\u503c\u521a\u597d\u5728\u7b2c\u4e00\u4e2a\u4f4d\u7f6e\u3002\u8fd9\u65f6\uff0c\u53ea\u9700\u8981\u4e00\u6b21\u6bd4\u8f83\u5c31\u53ef\u4ee5\u627e\u5230\u6700\u5c0f\u503c\uff0c\u65f6\u95f4\u590d\u6742\u5ea6\u4e3aO(1)\u3002 \u6700\u574f\u60c5\u51b5\uff1a\u6700\u5c0f\u503c\u5728\u6700\u540e\u4e00\u4e2a\u4f4d\u7f6e\u6216\u4e0d\u5b58\u5728\u3002\u8fd9\u65f6\uff0c\u9700\u8981\u8fdb\u884cn-1\u6b21\u6bd4\u8f83\u624d\u80fd\u786e\u5b9a\u6700\u5c0f\u503c\uff0c\u65f6\u95f4\u590d\u6742\u5ea6\u4e3aO(n)\u3002 \u5e73\u5747\u60c5\u51b5\uff1a\u5e73\u5747\u60c5\u51b5\u4e0b\uff0c\u6bcf\u4e2a\u5143\u7d20\u6709\u76f8\u7b49\u7684\u6982\u7387\u6210\u4e3a\u6700\u5c0f\u503c\u3002\u56e0\u6b64\uff0c\u5e73\u5747\u6bd4\u8f83\u6b21\u6570\u4e3a(n-1)/2\uff0c\u65f6\u95f4\u590d\u6742\u5ea6\u4e3aO(n)\u3002 \u987a\u5e8f\u641c\u7d22\uff08Sequential Search\uff09 \u6700\u597d\u60c5\u51b5\uff1a\u641c\u7d22\u7684\u5143\u7d20\u521a\u597d\u662f\u5217\u8868\u7684\u7b2c\u4e00\u4e2a\u5143\u7d20\u3002\u8fd9\u65f6\uff0c\u53ea\u9700\u8981\u4e00\u6b21\u6bd4\u8f83\u5c31\u53ef\u4ee5\u627e\u5230\u76ee\u6807\u5143\u7d20\uff0c\u65f6\u95f4\u590d\u6742\u5ea6\u4e3aO(1)\u3002 \u6700\u574f\u60c5\u51b5\uff1a\u641c\u7d22\u7684\u5143\u7d20\u5728\u5217\u8868\u7684\u6700\u540e\u4e00\u4e2a\u4f4d\u7f6e\u6216\u4e0d\u5b58\u5728\u3002\u8fd9\u65f6\uff0c\u9700\u8981\u8fdb\u884cn\u6b21\u6bd4\u8f83\u624d\u80fd\u786e\u5b9a\u76ee\u6807\u5143\u7d20\u4e0d\u5b58\u5728\uff0c\u65f6\u95f4\u590d\u6742\u5ea6\u4e3aO(n)\u3002 \u5e73\u5747\u60c5\u51b5\uff1a\u5e73\u5747\u60c5\u51b5\u4e0b\uff0c\u6bcf\u4e2a\u5143\u7d20\u6709\u76f8\u7b49\u7684\u6982\u7387\u6210\u4e3a\u76ee\u6807\u5143\u7d20\u3002\u56e0\u6b64\uff0c\u5e73\u5747\u6bd4\u8f83\u6b21\u6570\u4e3a (n+1)/2 \uff0c\u65f6\u95f4\u590d\u6742\u5ea6\u4e3aO(n)\u3002 \u5192\u6ce1\u6392\u5e8f\uff08Bubble Sort\uff09 \u6700\u597d\u60c5\u51b5\uff1a\u5982\u679c\u8f93\u5165\u5217\u8868\u5df2\u7ecf\u662f\u6709\u5e8f\u7684\uff0c\u5192\u6ce1\u6392\u5e8f\u53ea\u9700\u8981\u8fdb\u884c\u4e00\u6b21\u904d\u5386\u6765\u68c0\u6d4b\u5217\u8868\u5df2\u7ecf\u6709\u5e8f\uff0c\u65f6\u95f4\u590d\u6742\u5ea6\u4e3aO(n)\u3002\u4f46\u5b9e\u9645\u4e0a\uff0c\u901a\u5e38\u9700\u8981\u8fdb\u884c\u591a\u6b21\u904d\u5386\u6765\u5b8c\u6210\u6392\u5e8f\uff0c\u56e0\u6b64\u6700\u597d\u60c5\u51b5\u4e0b\u7684\u65f6\u95f4\u590d\u6742\u5ea6\u4ecd\u7136\u662fO(n^2)\u3002 \u6700\u574f\u60c5\u51b5\uff1a\u5982\u679c\u8f93\u5165\u5217\u8868\u662f\u9006\u5e8f\u7684\uff0c\u6bcf\u6b21\u904d\u5386\u90fd\u9700\u8981\u8fdb\u884cn-1\u6b21\u4ea4\u6362\uff0c\u603b\u5171\u9700\u8981\u8fdb\u884cn-1\u8f6e\u904d\u5386\uff0c\u65f6\u95f4\u590d\u6742\u5ea6\u4e3aO(n^2)\u3002 \u5e73\u5747\u60c5\u51b5\uff1a\u5e73\u5747\u60c5\u51b5\u4e0b\uff0c\u5192\u6ce1\u6392\u5e8f\u9700\u8981\u8fdb\u884c n(n-1)/2 \u6b21\u6bd4\u8f83\u548c\u4ea4\u6362\u64cd\u4f5c\uff0c\u65f6\u95f4\u590d\u6742\u5ea6\u4e3aO(n^2)\u3002","title":"3.4.4.\u518d\u8bba\u6700\u597d\u60c5\u51b5\u3001\u6700\u574f\u60c5\u51b5\u4ee5\u53ca\u5e73\u5747\u60c5\u51b5\u4e0b\u7684\u6027\u80fd"},{"location":"python/DataStructure/03_TimeComplexity/#345","text":"\u5217\u8868\u91cc\u5982\u4f55\u6392\u5217\u6570\u636e\u624d\u80fd\u8ba9\u9009\u62e9\u6392\u5e8f\u4e2d\u5143\u7d20\u4ea4\u6362\u7684\u6b21\u6570\u6700\u5c11\uff1f\u5982\u4f55\u6392\u5217\u6570\u636e\u624d\u80fd\u8ba9\u5b83\u6267\u884c\u6700\u591a\u7684\u4ea4\u6362\u6b21\u6570\uff1f \u89e3\u7b54\uff1a \u5728\u9009\u62e9\u6392\u5e8f\u4e2d\uff0c\u5143\u7d20\u7684\u4ea4\u6362\u6b21\u6570\u4e3b\u8981\u53d6\u51b3\u4e8e\u5f85\u6392\u5e8f\u5217\u8868\u7684\u521d\u59cb\u6392\u5217\uff1a \u6700\u5c0f\u5316\u4ea4\u6362\u6b21\u6570\uff1a \u8981\u6700\u5c0f\u5316\u9009\u62e9\u6392\u5e8f\u7684\u5143\u7d20\u4ea4\u6362\u6b21\u6570\uff0c\u53ef\u4ee5\u8ba9\u8f93\u5165\u5217\u8868\u5df2\u7ecf\u6309\u5347\u5e8f\u6392\u5217\u3002\u8fd9\u662f\u56e0\u4e3a\u5728\u5347\u5e8f\u6392\u5217\u7684\u60c5\u51b5\u4e0b\uff0c\u9009\u62e9\u6392\u5e8f\u6bcf\u6b21\u9009\u62e9\u6700\u5c0f\u7684\u5143\u7d20\u5e76\u5c06\u5176\u653e\u7f6e\u5728\u6b63\u786e\u7684\u4f4d\u7f6e\uff0c\u65e0\u9700\u4ea4\u6362\u3002\u56e0\u6b64\uff0c\u5143\u7d20\u4ea4\u6362\u7684\u6b21\u6570\u4e3a 0 \u3002 \u6700\u5927\u5316\u4ea4\u6362\u6b21\u6570\uff1a \u8981\u6700\u5927\u5316\u9009\u62e9\u6392\u5e8f\u7684\u5143\u7d20\u4ea4\u6362\u6b21\u6570\uff0c\u53ef\u4ee5\u8ba9\u8f93\u5165\u5217\u8868\u6309\u964d\u5e8f\u6392\u5217\u3002\u5728\u964d\u5e8f\u6392\u5217\u7684\u60c5\u51b5\u4e0b\uff0c\u9009\u62e9\u6392\u5e8f\u6bcf\u6b21\u9009\u62e9\u6700\u5927\u7684\u5143\u7d20\u5e76\u5c06\u5176\u653e\u7f6e\u5728\u6b63\u786e\u7684\u4f4d\u7f6e\uff0c\u8fd9\u5c06\u5bfc\u81f4\u5927\u91cf\u7684\u4ea4\u6362\u64cd\u4f5c\u3002\u5177\u4f53\u6765\u8bf4\uff0c\u5bf9\u4e8e\u957f\u5ea6\u4e3an\u7684\u5217\u8868\uff0c\u6700\u5927\u5316\u4ea4\u6362\u6b21\u6570\u7684\u60c5\u51b5\u4e0b\uff0c\u5c06\u6267\u884c n-1 \u6b21\u4ea4\u6362\u64cd\u4f5c\u3002 \u603b\u4e4b\uff0c\u8981\u6700\u5c0f\u5316\u9009\u62e9\u6392\u5e8f\u7684\u5143\u7d20\u4ea4\u6362\u6b21\u6570\uff0c\u8f93\u5165\u5217\u8868\u5e94\u8be5\u5df2\u7ecf\u6309\u5347\u5e8f\u6392\u5217\u3002\u8981\u6700\u5927\u5316\u4ea4\u6362\u6b21\u6570\uff0c\u8f93\u5165\u5217\u8868\u5e94\u8be5\u6309\u964d\u5e8f\u6392\u5217\u3002\u5728\u5b9e\u9645\u5e94\u7528\u4e2d\uff0c\u9009\u62e9\u6392\u5e8f\u901a\u5e38\u4e0d\u662f\u9996\u9009\u7684\u6392\u5e8f\u7b97\u6cd5\uff0c\u56e0\u4e3a\u5176\u4ea4\u6362\u6b21\u6570\u8f83\u591a\uff0c\u800c\u5176\u4ed6\u7b97\u6cd5\u5982\u5feb\u901f\u6392\u5e8f\u3001\u5f52\u5e76\u6392\u5e8f\u7b49\u5177\u6709\u66f4\u597d\u7684\u6027\u80fd\u3002 \u8bf7\u8bf4\u660e\u6570\u636e\u4ea4\u6362\u7684\u6b21\u6570\u5728\u5206\u6790\u9009\u62e9\u6392\u5e8f\u548c\u5192\u6ce1\u6392\u5e8f\u65f6\u6240\u8d77\u5230\u7684\u4f5c\u7528\u3002\u6570\u636e\u5bf9\u8c61\u7684\u89c4\u6a21\u5728\u5b83\u4eec\u4e4b\u95f4\u53d1\u6325\u7740\u4ec0\u4e48\u4f5c\u7528\uff08\u5982\u679c\u6709\u4f5c\u7528\uff09\uff1f \u89e3\u7b54\uff1a \u6570\u636e\u4ea4\u6362\u7684\u6b21\u6570\u5728\u5206\u6790\u9009\u62e9\u6392\u5e8f\u548c\u5192\u6ce1\u6392\u5e8f\u65f6\u8d77\u5230\u91cd\u8981\u4f5c\u7528\uff0c\u56e0\u4e3a\u5b83\u4eec\u76f4\u63a5\u5f71\u54cd\u5230\u6392\u5e8f\u7b97\u6cd5\u7684\u6027\u80fd\u548c\u6548\u7387\u3002 \u9009\u62e9\u6392\u5e8f\uff08Selection Sort\uff09\uff1a \u9009\u62e9\u6392\u5e8f\u7684\u6570\u636e\u4ea4\u6362\u6b21\u6570\u4e0e\u6570\u636e\u5bf9\u8c61\u7684\u89c4\u6a21\u76f4\u63a5\u76f8\u5173\u3002\u5728\u9009\u62e9\u6392\u5e8f\u4e2d\uff0c\u6bcf\u4e00\u8f6e\u90fd\u4f1a\u9009\u62e9\u672a\u6392\u5e8f\u90e8\u5206\u7684\u6700\u5c0f\u5143\u7d20\uff0c\u5e76\u5c06\u5176\u653e\u7f6e\u5728\u6b63\u786e\u7684\u4f4d\u7f6e\uff0c\u8fd9\u610f\u5473\u7740\u6bcf\u8f6e\u90fd\u9700\u8981\u4e00\u6b21\u4ea4\u6362\u64cd\u4f5c\u3002 \u9009\u62e9\u6392\u5e8f\u7684\u6570\u636e\u4ea4\u6362\u6b21\u6570\u662f\u4e0e\u8f93\u5165\u6570\u636e\u7684\u521d\u59cb\u6392\u5217\u65e0\u5173\u7684\uff0c\u56e0\u4e3a\u5b83\u603b\u662f\u4f1a\u6267\u884c\u76f8\u540c\u6570\u91cf\u7684\u4ea4\u6362\u64cd\u4f5c\uff0c\u65e0\u8bba\u6570\u636e\u662f\u5426\u6709\u5e8f\u3002 \u5bf9\u4e8e\u9009\u62e9\u6392\u5e8f\uff0c\u6570\u636e\u4ea4\u6362\u6b21\u6570\u4e3b\u8981\u53d7\u5230\u6570\u636e\u5bf9\u8c61\u7684\u89c4\u6a21\u5f71\u54cd\uff0c\u800c\u4e0d\u53d7\u6570\u636e\u7684\u5177\u4f53\u6392\u5217\u65b9\u5f0f\u7684\u5f71\u54cd\u3002\u65e0\u8bba\u6570\u636e\u7684\u6392\u5217\u5982\u4f55\uff0c\u9009\u62e9\u6392\u5e8f\u7684\u5e73\u5747\u548c\u6700\u574f\u60c5\u51b5\u4e0b\u7684\u6570\u636e\u4ea4\u6362\u6b21\u6570\u90fd\u662f\u76f8\u540c\u7684\uff0c\u5373 n-1 \u6b21\u3002 \u5192\u6ce1\u6392\u5e8f\uff08Bubble Sort\uff09\uff1a \u5192\u6ce1\u6392\u5e8f\u7684\u6570\u636e\u4ea4\u6362\u6b21\u6570\u4e5f\u4e0e\u6570\u636e\u5bf9\u8c61\u7684\u89c4\u6a21\u76f8\u5173\u3002\u5728\u5192\u6ce1\u6392\u5e8f\u4e2d\uff0c\u76f8\u90bb\u5143\u7d20\u9010\u4e00\u6bd4\u8f83\uff0c\u5982\u679c\u9006\u5e8f\u5c31\u4ea4\u6362\u4f4d\u7f6e\uff0c\u56e0\u6b64\u5192\u6ce1\u6392\u5e8f\u7684\u6570\u636e\u4ea4\u6362\u6b21\u6570\u4e0e\u9006\u5e8f\u5bf9\u7684\u6570\u91cf\u76f8\u5173\u3002 \u5192\u6ce1\u6392\u5e8f\u7684\u6570\u636e\u4ea4\u6362\u6b21\u6570\u5728\u4e0d\u540c\u7684\u6570\u636e\u6392\u5217\u60c5\u51b5\u4e0b\u53ef\u4ee5\u6709\u5f88\u5927\u5dee\u5f02\u3002\u5728\u6700\u597d\u60c5\u51b5\u4e0b\uff08\u8f93\u5165\u6570\u636e\u5df2\u7ecf\u6709\u5e8f\uff09\uff0c\u5192\u6ce1\u6392\u5e8f\u7684\u6570\u636e\u4ea4\u6362\u6b21\u6570\u4e3a 0 \u3002\u5728\u6700\u574f\u60c5\u51b5\u4e0b\uff08\u8f93\u5165\u6570\u636e\u5b8c\u5168\u9006\u5e8f\uff09\uff0c\u5192\u6ce1\u6392\u5e8f\u7684\u6570\u636e\u4ea4\u6362\u6b21\u6570\u662f\u6700\u5927\u7684\u3002 \u5192\u6ce1\u6392\u5e8f\u7684\u6570\u636e\u4ea4\u6362\u6b21\u6570\u65e2\u53d7\u5230\u6570\u636e\u5bf9\u8c61\u7684\u89c4\u6a21\u5f71\u54cd\uff0c\u53c8\u53d7\u5230\u6570\u636e\u7684\u6392\u5217\u65b9\u5f0f\u7684\u5f71\u54cd\u3002\u6700\u597d\u60c5\u51b5\u4e0b\u7684\u4ea4\u6362\u6b21\u6570\u4e3a 0 \uff0c\u6700\u574f\u60c5\u51b5\u4e0b\u7684\u4ea4\u6362\u6b21\u6570\u4e3a n*(n-1)/2 \uff0c\u5e73\u5747\u60c5\u51b5\u4e0b\u7684\u4ea4\u6362\u6b21\u6570\u53d6\u51b3\u4e8e\u6570\u636e\u6392\u5217\u7684\u968f\u673a\u6027\u3002 \u7efc\u4e0a\u6240\u8ff0\uff0c\u6570\u636e\u4ea4\u6362\u7684\u6b21\u6570\u5728\u9009\u62e9\u6392\u5e8f\u548c\u5192\u6ce1\u6392\u5e8f\u7684\u5206\u6790\u4e2d\u662f\u91cd\u8981\u7684\u6027\u80fd\u6307\u6807\u3002\u9009\u62e9\u6392\u5e8f\u7684\u4ea4\u6362\u6b21\u6570\u4e0e\u6570\u636e\u89c4\u6a21\u76f8\u5173\uff0c\u800c\u5192\u6ce1\u6392\u5e8f\u7684\u4ea4\u6362\u6b21\u6570\u65e2\u4e0e\u6570\u636e\u89c4\u6a21\u76f8\u5173\uff0c\u53c8\u53d7\u5230\u6570\u636e\u6392\u5217\u65b9\u5f0f\u7684\u5f71\u54cd\u3002\u5728\u5927\u89c4\u6a21\u6570\u636e\u96c6\u4e0a\uff0c\u5192\u6ce1\u6392\u5e8f\u901a\u5e38\u6bd4\u9009\u62e9\u6392\u5e8f\u66f4\u6162\uff0c\u56e0\u4e3a\u5b83\u7684\u4ea4\u6362\u64cd\u4f5c\u66f4\u591a\u3002\u56e0\u6b64\uff0c\u5728\u5b9e\u9645\u5e94\u7528\u4e2d\uff0c\u901a\u5e38\u9009\u62e9\u6392\u5e8f\u6bd4\u5192\u6ce1\u6392\u5e8f\u66f4\u6709\u6548\u3002\u4f46\u4e24\u8005\u90fd\u4e0d\u662f\u9996\u9009\u7684\u6392\u5e8f\u7b97\u6cd5\uff0c\u66f4\u9ad8\u6548\u7684\u6392\u5e8f\u7b97\u6cd5\u5982\u5feb\u901f\u6392\u5e8f\u3001\u5f52\u5e76\u6392\u5e8f\u7b49\u901a\u5e38\u88ab\u4f18\u5148\u8003\u8651\u3002 \u8bf7\u8bf4\u660e\u4e3a\u4ec0\u4e48\u4fee\u6539\u540e\u7684\u5192\u6ce1\u6392\u5e8f\u5728\u5e73\u5747\u60c5\u51b5\u4e0b\u6027\u80fd\u4ecd\u7136\u4e3aO(n^2)\u3002 \u89e3\u7b54\uff1a \u4fee\u6539\u540e\u7684\u5192\u6ce1\u6392\u5e8f\u5728\u5e73\u5747\u60c5\u51b5\u4e0b\u6027\u80fd\u4ecd\u7136\u4e3aO(n^2)\uff0c\u539f\u56e0\u5982\u4e0b\uff1a \u5192\u6ce1\u6392\u5e8f\u7684\u57fa\u672c\u64cd\u4f5c\u662f\u6bd4\u8f83\u76f8\u90bb\u5143\u7d20\u5e76\u4ea4\u6362\u5b83\u4eec\uff0c\u76f4\u5230\u6574\u4e2a\u5217\u8868\u6309\u7167\u5347\u5e8f\u6392\u5217\u3002\u5728\u4fee\u6539\u540e\u7684\u5192\u6ce1\u6392\u5e8f\u4e2d\uff0c\u5f53\u4e24\u4e2a\u76f8\u90bb\u5143\u7d20\u9006\u5e8f\u65f6\uff0c\u4f1a\u53d1\u751f\u4ea4\u6362\u3002\u8fd9\u4e2a\u57fa\u672c\u64cd\u4f5c\u7684\u590d\u6742\u5ea6\u662fO(1)\uff0c\u56e0\u4e3a\u5b83\u53ea\u6d89\u53ca\u4e24\u4e2a\u5143\u7d20\u7684\u6bd4\u8f83\u548c\u53ef\u80fd\u7684\u4ea4\u6362\u3002 \u4fee\u6539\u540e\u7684\u5192\u6ce1\u6392\u5e8f\u5728\u6bcf\u4e00\u8f6e\u904d\u5386\u4e2d\uff0c\u4ecd\u7136\u9700\u8981\u68c0\u67e5\u76f8\u90bb\u5143\u7d20\u7684\u6bd4\u8f83\uff0c\u5373\u4f7f\u5728\u6709\u5e8f\u90e8\u5206\uff0c\u5b83\u4ecd\u7136\u9700\u8981\u8fdb\u884c\u6bd4\u8f83\u3002\u5728\u6700\u574f\u60c5\u51b5\u4e0b\uff0c\u5b83\u4f1a\u6267\u884cn-1\u6b21\u904d\u5386\uff0c\u6bcf\u6b21\u90fd\u8981\u6bd4\u8f83\u76f8\u90bb\u5143\u7d20\u3002 \u5192\u6ce1\u6392\u5e8f\u7684\u5e73\u5747\u65f6\u95f4\u590d\u6742\u5ea6\u662fO(n^2)\uff0c\u8fd9\u662f\u56e0\u4e3a\u5b83\u4e0d\u4f1a\u5229\u7528\u8f93\u5165\u6570\u636e\u7684\u4efb\u4f55\u6709\u5e8f\u6027\u3002\u65e0\u8bba\u8f93\u5165\u6570\u636e\u662f\u6709\u5e8f\u7684\u3001\u9006\u5e8f\u7684\uff0c\u8fd8\u662f\u968f\u673a\u6392\u5217\u7684\uff0c\u90fd\u9700\u8981\u6267\u884c\u76f8\u540c\u6570\u91cf\u7684\u6bd4\u8f83\u548c\u4ea4\u6362\u64cd\u4f5c\u3002 \u603b\u4e4b\uff0c\u4fee\u6539\u540e\u7684\u5192\u6ce1\u6392\u5e8f\u867d\u7136\u51cf\u5c11\u4e86\u6570\u636e\u4ea4\u6362\u7684\u6b21\u6570\uff0c\u4f46\u5728\u5e73\u5747\u60c5\u51b5\u4e0b\u4ecd\u7136\u9700\u8981\u6267\u884c\u5927\u7ea6 n(n-1)/2 \u6b21\u6bd4\u8f83\u64cd\u4f5c\uff0c\u56e0\u6b64\u5b83\u7684\u5e73\u5747\u65f6\u95f4\u590d\u6742\u5ea6\u4ecd\u7136\u662fO(n^2)\u3002\u5192\u6ce1\u6392\u5e8f\u7684\u6027\u80fd\u4e3b\u8981\u53d7\u5230\u6570\u636e\u89c4\u6a21\u7684\u5f71\u54cd\uff0c\u800c\u4e0d\u592a\u53d7\u5230\u5177\u4f53\u6570\u636e\u6392\u5217\u65b9\u5f0f\u7684\u5f71\u54cd\u3002\u56e0\u6b64\uff0c\u5b83\u5728\u5e73\u5747\u60c5\u51b5\u4e0b\u4ecd\u7136\u5177\u6709\u4e8c\u6b21\u65f6\u95f4\u590d\u6742\u5ea6\u3002 \u8bf7\u8bf4\u660e\u4e3a\u4ec0\u4e48\u63d2\u5165\u6392\u5e8f\u5728\u90e8\u5206\u6709\u5e8f\u7684\u5217\u8868\u4e0a\u80fd\u591f\u5f88\u597d\u5730\u5de5\u4f5c\u3002 \u89e3\u7b54\uff1a \u63d2\u5165\u6392\u5e8f\u4e4b\u6240\u4ee5\u80fd\u591f\u5728\u90e8\u5206\u6709\u5e8f\u7684\u5217\u8868\u4e0a\u5f88\u597d\u5730\u5de5\u4f5c\uff0c\u662f\u56e0\u4e3a\u5b83\u7684\u6838\u5fc3\u601d\u60f3\u662f\u9010\u6b65\u6784\u5efa\u6709\u5e8f\u7684\u5b50\u5217\u8868\uff0c\u800c\u4e0d\u662f\u50cf\u9009\u62e9\u6392\u5e8f\u6216\u5192\u6ce1\u6392\u5e8f\u4e00\u6837\u603b\u662f\u8003\u8651\u6574\u4e2a\u5217\u8868\u3002\u8fd9\u4f7f\u5f97\u63d2\u5165\u6392\u5e8f\u5728\u5904\u7406\u90e8\u5206\u6709\u5e8f\u7684\u5217\u8868\u65f6\u5177\u6709\u4e00\u4e9b\u4f18\u52bf\uff1a \u5c40\u90e8\u6027\u539f\u7406\uff1a\u63d2\u5165\u6392\u5e8f\u5229\u7528\u4e86\u5c40\u90e8\u6027\u539f\u7406\uff0c\u5373\u5728\u5927\u591a\u6570\u60c5\u51b5\u4e0b\uff0c\u6570\u636e\u9879\u7684\u6b63\u786e\u4f4d\u7f6e\u79bb\u5b83\u4eec\u5f53\u524d\u7684\u4f4d\u7f6e\u5f88\u8fd1\u3002\u5728\u90e8\u5206\u6709\u5e8f\u7684\u5217\u8868\u4e2d\uff0c\u5927\u591a\u6570\u6570\u636e\u9879\u5df2\u7ecf\u63a5\u8fd1\u4e8e\u5b83\u4eec\u7684\u6700\u7ec8\u4f4d\u7f6e\uff0c\u56e0\u6b64\u53ea\u9700\u8981\u8fdb\u884c\u5c11\u91cf\u7684\u79fb\u52a8\u64cd\u4f5c\u3002 \u9002\u5e94\u6027\uff1a\u63d2\u5165\u6392\u5e8f\u662f\u4e00\u79cd\u81ea\u9002\u5e94\u6392\u5e8f\u7b97\u6cd5\uff0c\u5b83\u53ef\u4ee5\u6839\u636e\u8f93\u5165\u6570\u636e\u7684\u6709\u5e8f\u6027\u8fdb\u884c\u81ea\u52a8\u8c03\u6574\u3002\u5728\u5904\u7406\u90e8\u5206\u6709\u5e8f\u7684\u5217\u8868\u65f6\uff0c\u63d2\u5165\u6392\u5e8f\u7684\u6027\u80fd\u4f1a\u66f4\u597d\uff0c\u56e0\u4e3a\u4e0d\u9700\u8981\u6267\u884c\u592a\u591a\u7684\u6bd4\u8f83\u548c\u4ea4\u6362\u64cd\u4f5c\u3002 \u7b80\u5355\u6027\uff1a\u63d2\u5165\u6392\u5e8f\u7684\u5b9e\u73b0\u975e\u5e38\u7b80\u5355\u76f4\u89c2\uff0c\u5b83\u53ea\u6d89\u53ca\u5230\u9010\u4e2a\u63d2\u5165\u5143\u7d20\u5230\u6b63\u786e\u7684\u4f4d\u7f6e\u3002\u8fd9\u79cd\u7b80\u5355\u6027\u4f7f\u5f97\u63d2\u5165\u6392\u5e8f\u5728\u67d0\u4e9b\u60c5\u51b5\u4e0b\u6bd4\u66f4\u590d\u6742\u7684\u6392\u5e8f\u7b97\u6cd5\u66f4\u5177\u7ade\u4e89\u529b\u3002 \u867d\u7136\u63d2\u5165\u6392\u5e8f\u5728\u90e8\u5206\u6709\u5e8f\u7684\u5217\u8868\u4e0a\u8868\u73b0\u826f\u597d\uff0c\u4f46\u5728\u5904\u7406\u5927\u89c4\u6a21\u4e71\u5e8f\u6570\u636e\u96c6\u65f6\uff0c\u5b83\u7684\u6027\u80fd\u4e0d\u5982\u5feb\u901f\u6392\u5e8f\u3001\u5f52\u5e76\u6392\u5e8f\u7b49\u66f4\u9ad8\u7ea7\u7684\u6392\u5e8f\u7b97\u6cd5\u3002\u56e0\u6b64\uff0c\u5728\u5b9e\u9645\u5e94\u7528\u4e2d\uff0c\u6839\u636e\u6570\u636e\u7684\u6027\u8d28\u9009\u62e9\u9002\u5f53\u7684\u6392\u5e8f\u7b97\u6cd5\u662f\u91cd\u8981\u7684\u3002\u63d2\u5165\u6392\u5e8f\u901a\u5e38\u9002\u7528\u4e8e\u5c0f\u89c4\u6a21\u6570\u636e\u6216\u8005\u5df2\u7ecf\u90e8\u5206\u6709\u5e8f\u7684\u6570\u636e\uff0c\u800c\u4e0d\u662f\u5927\u89c4\u6a21\u4e71\u5e8f\u6570\u636e\u7684\u6392\u5e8f\u3002","title":"3.4.5.\u7ec3\u4e60\u9898"},{"location":"python/DataStructure/03_TimeComplexity/#35","text":"\u5206\u6cbb\u6cd5\uff08divide-and-conquer\uff09\u7b56\u7565\uff1a\u628a\u5217\u8868\u5206\u6210\u66f4\u5c0f\u7684\u5b50\u5217\u8868\uff0c\u7136\u540e\u518d\u901a\u8fc7\u9012\u5f52\u628a\u8fd9\u4e9b\u5b50\u5217\u8868\u6392\u5e8f\u3002 \u7406\u60f3\u60c5\u51b5\u4e0b\uff0c\u5982\u679c\u8fd9\u4e9b\u88ab\u62c6\u5206\u7684\u5b50\u5217\u8868\u7684\u6570\u91cf\u662f logn \uff0c\u800c\u628a\u6bcf\u4e2a\u5b50\u5217\u8868\u8fdb\u884c\u5408\u5e76\u6240\u9700\u7684\u5de5\u4f5c\u91cf\u4e3a n \uff0c\u90a3\u4e48\u8fd9\u79cd\u6392\u5e8f\u7b97\u6cd5\u7684\u603b\u590d\u6742\u5ea6\u5c31\u662f O(nlogn) \uff0c\u76f8\u6bd4 O(n^2) \u7684\u5de5\u4f5c\u91cf\u589e\u957f\u8981\u4f4e\u5f88\u591a\u3002","title":"3.5.\u66f4\u5feb\u7684\u6392\u5e8f"},{"location":"python/DataStructure/03_TimeComplexity/#351","text":"\u5feb\u901f\u6392\u5e8f\uff08QuickSort\uff09\u662f\u6392\u9664\u7a33\u5b9a\u6027\u56e0\u7d20\u540e\u6700\u5e38\u7528\u7684\u6392\u5e8f\u3002 \u9996\u5148\u4ece\u5217\u8868\u7684\u4e2d\u95f4\u4f4d\u7f6e\u9009\u62e9\u4e00\u4e2a\u5143\u7d20\uff0c\u8fd9\u4e2a\u5143\u7d20\u88ab\u79f0\u4e3a\u57fa\u51c6\uff08pivot\uff09\uff1b \u5bf9\u5217\u8868\u91cc\u7684\u5143\u7d20\u8fdb\u884c\u5206\u5272\uff0c\u628a\u5c0f\u4e8e\u57fa\u51c6\u7684\u6240\u6709\u5143\u7d20\u79fb\u52a8\u5230\u57fa\u51c6\u7684\u5de6\u4fa7\uff0c\u800c\u628a\u5176\u4f59\u5143\u7d20\u90fd\u79fb\u5230\u57fa\u51c6\u7684\u53f3\u4fa7\u3002 \u5982\u679c\u57fa\u51c6\u6b63\u597d\u662f\u6700\u5927\u7684\u5143\u7d20\uff0c\u90a3\u4e48\u5b83\u6700\u7ec8\u4f1a\u5904\u4e8e\u5217\u8868\u7684\u6700\u53f3\u4fa7\uff1b \u5982\u679c\u57fa\u51c6\u6b63\u597d\u662f\u6700\u5c0f\u7684\u5143\u7d20\uff0c\u90a3\u4e48\u5b83\u5c31\u4f1a\u5728\u6700\u5de6\u4fa7\uff1b \u5206\u6cbb\u6cd5\u3002\u5c06\u8fd9\u4e2a\u8fc7\u7a0b\u9012\u5f52\u5730\u5e94\u7528\u5230\u901a\u8fc7\u57fa\u51c6\u800c\u628a\u539f\u5217\u8868\u5206\u5272\u7684\u5b50\u5217\u8868\u4e0a\uff0c\u5176\u4e2d\uff1a \u4e00\u4e2a\u65b0\u7684\u5b50\u5217\u8868\u7531\u57fa\u51c6\u5de6\u4fa7\u7684\u6240\u6709\u5143\u7d20\uff08\u8f83\u5c0f\u7684\u5143\u7d20\uff09\u7ec4\u6210\uff0c \u53e6\u4e00\u4e2a\u65b0\u7684\u5b50\u5217\u8868\u7531\u57fa\u51c6\u53f3\u4fa7\u7684\u6240\u6709\u5143\u7d20\uff08\u8f83\u5927\u7684\u5143\u7d20\uff09\u7ec4\u6210\uff1b \u5f53\u5206\u51fa\u7684\u5b50\u5217\u8868\u5185\u5c11\u4e8e\u4e24\u4e2a\u5143\u7d20\u65f6\uff0c\u8fd9\u4e2a\u8fc7\u7a0b\u7ec8\u6b62\uff1b","title":"3.5.1.\u5feb\u901f\u6392\u5e8f"},{"location":"python/DataStructure/03_TimeComplexity/#3511","text":"\u8fd9\u4e2a\u7b97\u6cd5\u91cc\u6700\u590d\u6742\u7684\u90e8\u5206\u662f\u5bf9\u5143\u7d20\u8fdb\u884c\u5206\u5272\u4ece\u800c\u5f97\u5230\u5b50\u5217\u8868\u7684\u64cd\u4f5c\u3002 \u5c06\u57fa\u51c6\u4e0e\u5b50\u5217\u8868\u91cc\u7684\u6700\u540e\u4e00\u4e2a\u5143\u7d20\u8fdb\u884c\u4ea4\u6362\u3002 \u5728\u5df2\u77e5\u5c0f\u4e8e\u57fa\u51c6\u7684\u5143\u7d20\u548c\u5176\u4ed6\u5143\u7d20\u4e4b\u95f4\u6784\u5efa\u4e00\u4e2a\u8fb9\u754c\u3002\u4e00\u5f00\u59cb\uff0c\u8fd9\u4e2a\u8fb9\u754c\u4f1a\u5904\u4e8e\u7b2c\u4e00\u4e2a\u5143\u7d20\u4e4b\u524d\u3002 \u4ece\u5b50\u5217\u8868\u8fb9\u754c\u4e4b\u540e\u7684\u7b2c\u4e00\u4e2a\u5143\u7d20\u5f00\u59cb\u5411\u53f3\u626b\u63cf\u3002\u5f53\u6bcf\u6b21\u9047\u5230\u5c0f\u4e8e\u57fa\u51c6\u7684\u5143\u7d20\u65f6\uff0c\u5c06\u5b83\u548c\u8fb9\u754c\u4e4b\u540e\u7684\u7b2c\u4e00\u4e2a\u5143\u7d20\u8fdb\u884c\u4ea4\u6362\uff0c\u5e76\u4e14\u5c06\u8fb9\u754c\u5411\u53f3\u79fb\u52a8\u3002 \u5728\u7ed3\u675f\u7684\u65f6\u5019\uff0c\u5c06\u57fa\u51c6\u548c\u8fb9\u754c\u4e4b\u540e\u7684\u7b2c\u4e00\u4e2a\u5143\u7d20\u8fdb\u884c\u4ea4\u6362\u3002 \u793a\u4f8b\u5217\u8868\uff1a[12,19,17,18,14,11,15,13,16]\uff0c\u4e0b\u56fe\u5c55\u793a\u4e86\u5206\u5272\u7684\u6bcf\u4e00\u6b65\u8fc7\u7a0b\u3002","title":"3.5.1.1.\u5206\u5272"},{"location":"python/DataStructure/03_TimeComplexity/#3512","text":"\u5feb\u901f\u6392\u5e8f\uff08Quick Sort\uff09\u662f\u4e00\u79cd\u9ad8\u6548\u7684\u6392\u5e8f\u7b97\u6cd5\uff0c\u5176\u5e73\u5747\u548c\u6700\u574f\u65f6\u95f4\u590d\u6742\u5ea6\u90fd\u662f O(n log n) \u3002\u4e0b\u9762\u662f\u5feb\u901f\u6392\u5e8f\u7684\u590d\u6742\u5ea6\u5206\u6790\uff1a \u5728\u7b2c\u4e00\u6b21\u8fdb\u884c\u5206\u5272\u64cd\u4f5c\u65f6\uff0c\u6211\u4eec\u5c06\u626b\u63cf\u5217\u8868\u91cc\u4ece\u5f00\u5934\u5230\u7ed3\u5c3e\u7684\u6240\u6709\u5143\u7d20\u3002\u56e0\u6b64\uff0c\u5728\u8fd9\u4e2a\u64cd\u4f5c\u671f\u95f4\u5de5\u4f5c\u91cf\u662f\u548c\u5217\u8868\u7684\u957f\u5ea6 n \u6210\u6b63\u6bd4\u7684\u3002\u8fd9\u6b21\u5206\u5272\u4e4b\u540e\u7684\u5de5\u4f5c\u91cf\u4f1a\u548c\u5de6\u5b50\u5217\u8868\u52a0\u4e0a\u53f3\u5b50\u5217\u8868\u7684\u603b\u957f\u5ea6\u6210\u6b63\u6bd4\uff0c\u4e5f\u5c31\u662f n-1 \u3002 \u518d\u6b21\u5bf9\u8fd9\u4e24\u4e2a\u5b50\u5217\u8868\u8fdb\u884c\u5206\u5272\u4e4b\u540e\uff0c\u5c31\u4f1a\u4ea7\u751f4\u4e2a\u52a0\u8d77\u6765\u603b\u957f\u5ea6\u5927\u7ea6\u4e3a n \u7684\u5217\u8868\u6bb5\u3002\u56e0\u6b64\uff0c\u5bf9\u5b83\u4eec\u8fdb\u884c\u5206\u5272\u7684\u603b\u5de5\u4f5c\u91cf\u8fd8\u662f\u548c n \u6210\u6b63\u6bd4\u7684\u3002\u968f\u7740\u5217\u8868\u88ab\u5206\u5272\u6210\u66f4\u591a\u6bb5\uff0c\u603b\u5de5\u4f5c\u91cf\u4f1a\u4e00\u76f4\u548c n \u6210\u6b63\u6bd4\u3002 \u8981\u5b8c\u6210\u6574\u4e2a\u5206\u6790\uff0c\u8fd8\u9700\u8981\u786e\u5b9a\u5217\u8868\u88ab\u5206\u5272\u4e86\u591a\u5c11\u6b21\u3002\u6309\u7167\u6700\u4e50\u89c2\u7684\u60c5\u51b5\u6765\u8bf4\uff08\u867d\u7136\u5728\u5b9e\u9645\u64cd\u4f5c\u7684\u65f6\u5019\uff0c\u901a\u5e38\u5e76\u4e0d\u4f1a\u51fa\u73b0\u8fd9\u4e48\u597d\u7684\u60c5\u51b5\uff09\uff0c\u5047\u8bbe\u6bcf\u6b21\u65b0\u5b50\u5217\u8868\u4e4b\u95f4\u7684\u5206\u754c\u7ebf\u90fd\u5c3d\u53ef\u80fd\u5730\u9760\u8fd1\u5f53\u524d\u5217\u8868\u7684\u4e2d\u5fc3\uff0c\u901a\u5e38\u8fd9\u79cd\u60c5\u51b5\u5e76\u4e0d\u5e38\u89c1\u3002\u4ece\u4e8c\u5206\u641c\u7d22\u7b97\u6cd5\u7684\u8ba8\u8bba\u91cc\u53ef\u77e5\uff0c\u8981\u628a\u5217\u8868\u4e0d\u65ad\u5730\u5206\u6210\u4e24\u534a\uff0c\u5927\u7ea6\u5728 log n \u6b65\u7684\u65f6\u5019\u5c31\u53ea\u5269\u4e0b\u4e00\u4e2a\u5143\u7d20\u4e86\u3002 \u56e0\u6b64\uff0c\u8fd9\u4e2a\u7b97\u6cd5\u5728\u6700\u597d\u60c5\u51b5\u4e0b\u7684\u6027\u80fd\u4e3a O(n log n) \u3002\u5728\u6700\u574f\u60c5\u51b5\u4e0b\uff0c\u6211\u4eec\u6765\u8003\u8651\u6709\u5e8f\u5217\u8868\u7684\u60c5\u51b5\u3002\u5982\u679c\u9009\u62e9\u7684\u57fa\u51c6\u5143\u7d20\u662f\u7b2c\u4e00\u4e2a\u5143\u7d20\uff0c\u90a3\u4e48\u5728\u7b2c\u4e00\u6b21\u5206\u5272\u4e4b\u540e\u5b83\u7684\u53f3\u8fb9\u4f1a\u6709 n-1 \u4e2a\u5143\u7d20\uff0c\u5728\u7b2c\u4e8c\u6b21\u5206\u5272\u4e4b\u540e\u5b83\u7684\u53f3\u8fb9\u6709 n-2 \u4e2a\u5143\u7d20\uff0c\u4ee5\u6b64\u7c7b\u63a8\uff0c \u5c3d\u7ba1\u6574\u4e2a\u64cd\u4f5c\u91cc\u6ca1\u6709\u4ea4\u6362\u4efb\u4f55\u5143\u7d20\uff0c\u4f46\u5206\u5272\u603b\u5171\u4e5f\u6267\u884c\u4e86 n-1 \u6b21\uff0c\u4e8e\u662f\u6267\u884c\u7684\u6bd4\u8f83\u603b\u6570\u5c31\u662f n^2/2-n/2 \u3002\u8fd9\u4e0e\u9009\u62e9\u6392\u5e8f\u4ee5\u53ca\u5192\u6ce1\u6392\u5e8f\u7684\u60c5\u51b5\u662f\u4e00\u6837\u7684\u3002\u56e0\u6b64\uff0c\u5728\u6700\u574f\u60c5\u51b5\u4e0b\uff0c\u5feb\u901f\u6392\u5e8f\u7b97\u6cd5\u7684\u6027\u80fd\u4e3a O(n^2) \u3002\u5982\u679c\u628a\u5feb\u901f\u6392\u5e8f\u5b9e\u73b0\u6210\u9012\u5f52\u7b97\u6cd5\uff0c\u90a3\u4e48\u5728\u5bf9\u5b83\u8fdb\u884c\u5206\u6790\u65f6\u8fd8\u5fc5\u987b\u8981\u8003\u8651\u8c03\u7528\u6808\u7684\u5185\u5b58\u4f7f\u7528\u60c5\u51b5\u3002\u7531\u4e8e\u5bf9\u4e8e\u6808\u7684\u4e00\u5e27\uff0c\u6bcf\u6b21\u9012\u5f52\u8c03\u7528\u90fd\u9700\u8981\u56fa\u5b9a\u7684\u5185\u5b58\uff0c\u5e76\u4e14\u6bcf\u6b21\u5206\u5272\u4e4b\u540e\u90fd\u4f1a\u6709\u4e24\u6b21\u9012\u5f52\u8c03\u7528\u3002\u56e0\u6b64\uff0c\u5728\u6700\u597d\u60c5\u51b5\u4e0b\u5185\u5b58\u7684\u4f7f\u7528\u91cf\u4f1a\u662f O(log n) \uff0c\u800c\u6700\u574f\u60c5\u51b5\u4e0b\u7684\u5185\u5b58\u4f7f\u7528\u91cf\u662f O(n) \u3002 \u5c3d\u7ba1\u5feb\u901f\u6392\u5e8f\u5904\u4e8e\u6700\u574f\u60c5\u51b5\u4e0b\u7684\u53ef\u80fd\u6027\u5f88\u5c0f\uff0c\u6211\u4eec\u8fd8\u662f\u4f1a\u52aa\u529b\u5730\u53bb\u907f\u514d\u8fd9\u79cd\u60c5\u51b5\uff0c\u56e0\u6b64\uff0c\u5b83\u4eec\u5e76\u4e0d\u4f1a\u5728\u7b2c\u4e00\u4e2a\u6216\u6700\u540e\u4e00\u4e2a\u4f4d\u7f6e\u9009\u62e9\u57fa\u51c6\u5143\u7d20\u3002\u6709\u5176\u4ed6\u4e00\u4e9b\u9009\u62e9\u57fa\u51c6\u7684\u65b9\u6cd5\u53ef\u4ee5\u8ba9\u8fd9\u4e2a\u7b97\u6cd5\u5728\u5e73\u5747\u60c5\u51b5\u4e0b\u6709\u5927\u7ea6 O(n log n) \u7684\u6027\u80fd\uff0c\u6bd4\u5982\uff0c\u53ef\u4ee5\u9009\u62e9\u968f\u673a\u4f4d\u7f6e\u4e0a\u7684\u5143\u7d20\u4f5c\u4e3a\u57fa\u51c6\uff0c\u6216\u8005\u9009\u62e9\u6574\u4e2a\u5217\u8868\u91cc\u7b2c\u4e00\u4e2a\u4f4d\u7f6e\u3001\u4e2d\u95f4\u4f4d\u7f6e\u4ee5\u53ca\u6700\u540e\u4e00\u4e2a\u4f4d\u7f6e\u8fd93\u4e2a\u5143\u7d20\u7684\u4e2d\u4f4d\u6570\u3002 \u603b\u7ed3\uff1a \u6700\u597d\u60c5\u51b5\u65f6\u95f4\u590d\u6742\u5ea6\uff1a\u5728\u6700\u597d\u60c5\u51b5\u4e0b\uff0c\u4e5f\u5c31\u662f\u6bcf\u6b21\u9009\u62e9\u7684\u57fa\u51c6\u5143\u7d20\u90fd\u521a\u597d\u5c06\u8f93\u5165\u6570\u636e\u5206\u6210\u4e24\u4e2a\u7b49\u957f\u7684\u5b50\u6570\u7ec4\uff0c\u5feb\u901f\u6392\u5e8f\u7684\u65f6\u95f4\u590d\u6742\u5ea6\u662f O(n log n) \u3002\u8fd9\u79cd\u60c5\u51b5\u901a\u5e38\u53d1\u751f\u5728\u57fa\u51c6\u5143\u7d20\u7684\u9009\u62e9\u975e\u5e38\u5408\u7406\u7684\u60c5\u51b5\u4e0b\uff0c\u4f8b\u5982\u5728\u6bcf\u6b21\u9009\u62e9\u4e2d\u90fd\u9009\u62e9\u4e2d\u95f4\u5143\u7d20\u3002 \u5e73\u5747\u60c5\u51b5\u65f6\u95f4\u590d\u6742\u5ea6\uff1a\u5728\u5e73\u5747\u60c5\u51b5\u4e0b\uff0c\u5feb\u901f\u6392\u5e8f\u7684\u65f6\u95f4\u590d\u6742\u5ea6\u4e5f\u662f O(n log n) \u3002\u8fd9\u662f\u56e0\u4e3a\u5feb\u901f\u6392\u5e8f\u662f\u4e00\u79cd\u5206\u6cbb\u7b97\u6cd5\uff0c\u6bcf\u6b21\u5c06\u95ee\u9898\u5206\u6210\u4e24\u4e2a\u5b50\u95ee\u9898\uff0c\u7136\u540e\u9012\u5f52\u5730\u89e3\u51b3\u8fd9\u4e9b\u5b50\u95ee\u9898\u3002\u5e73\u5747\u60c5\u51b5\u4e0b\uff0c\u6bcf\u6b21\u5206\u5272\u64cd\u4f5c\u90fd\u80fd\u5c06\u95ee\u9898\u89c4\u6a21\u51cf\u534a\uff0c\u56e0\u6b64\u9700\u8981\u6267\u884c O(n log n) \u6b21\u5206\u5272\u64cd\u4f5c\uff0c\u6bcf\u6b21\u5206\u5272\u64cd\u4f5c\u7684\u65f6\u95f4\u590d\u6742\u5ea6\u662f O(n) \u3002\u56e0\u6b64\uff0c\u5e73\u5747\u65f6\u95f4\u590d\u6742\u5ea6\u662f O(n log n) \u3002 \u6700\u574f\u60c5\u51b5\u65f6\u95f4\u590d\u6742\u5ea6\uff1a\u5728\u6700\u574f\u60c5\u51b5\u4e0b\uff0c\u5feb\u901f\u6392\u5e8f\u7684\u65f6\u95f4\u590d\u6742\u5ea6\u662f O(n^2) \u3002\u6700\u574f\u60c5\u51b5\u53d1\u751f\u5728\u6bcf\u6b21\u9009\u62e9\u7684\u57fa\u51c6\u5143\u7d20\u90fd\u662f\u8f93\u5165\u6570\u636e\u4e2d\u7684\u6700\u5c0f\u6216\u6700\u5927\u5143\u7d20\uff0c\u5bfc\u81f4\u5206\u5272\u64cd\u4f5c\u4e0d\u5747\u8861\uff0c\u6bcf\u6b21\u5206\u5272\u53ea\u80fd\u5c06\u95ee\u9898\u89c4\u6a21\u51cf\u5c111\u3002\u5728\u8fd9\u79cd\u60c5\u51b5\u4e0b\uff0c\u5feb\u901f\u6392\u5e8f\u9000\u5316\u4e3a\u5192\u6ce1\u6392\u5e8f\uff0c\u65f6\u95f4\u590d\u6742\u5ea6\u4e3a O(n^2) \u3002 \u5feb\u901f\u6392\u5e8f\u7684\u5e73\u5747\u548c\u6700\u597d\u60c5\u51b5\u65f6\u95f4\u590d\u6742\u5ea6\u4e3a O(n log n) \uff0c\u5728\u5b9e\u9645\u5e94\u7528\u4e2d\u901a\u5e38\u6027\u80fd\u4f18\u8d8a\u3002\u7136\u800c\uff0c\u9700\u8981\u6ce8\u610f\u7684\u662f\uff0c\u6700\u574f\u60c5\u51b5\u4e0b\u7684\u65f6\u95f4\u590d\u6742\u5ea6\u4e3a O(n^2) \uff0c\u56e0\u6b64\u5728\u5b9e\u73b0\u5feb\u901f\u6392\u5e8f\u65f6\u9700\u8981\u7279\u522b\u6ce8\u610f\u57fa\u51c6\u5143\u7d20\u7684\u9009\u62e9\u4ee5\u907f\u514d\u6700\u574f\u60c5\u51b5\u7684\u53d1\u751f\u3002","title":"3.5.1.2.\u5feb\u901f\u6392\u5e8f\u590d\u6742\u5ea6\u5206\u6790"},{"location":"python/DataStructure/03_TimeComplexity/#3513","text":"\u4ee5\u4e0a\u9762\u56fe\u793a\u7684\u5217\u8868 [12,19,17,18,14,11,15,13,16] \u4e3a\u4f8b\uff0c\u4e0b\u9762\u662f\u5b9e\u73b0\u4ee3\u7801\uff1a import random def swap ( lyst , i , j ): \"\"\"\u4ea4\u6362\u5143\u7d20\u4f4d\u7f6e\u4e3ai\u548cj\u7684\u5143\u7d20\"\"\" temp = lyst [ i ] lyst [ i ] = lyst [ j ] lyst [ j ] = temp def quicksort ( lyst ): # left\u7684\u521d\u59cb\u503c\u662f0 # right\u7684\u521d\u59cb\u503c\u662f\u5217\u8868\u957f\u5ea6\u51cf1 quicksortHelper ( lyst , 0 , len ( lyst ) - 1 ) def quicksortHelper ( lyst , left , right ): print ( lyst ) if left < right : pivotLocation = partition ( lyst , left , right ) quicksortHelper ( lyst , left , pivotLocation - 1 ) quicksortHelper ( lyst , pivotLocation + 1 , right ) def partition ( lyst , left , right ): \"\"\"\u5bf9\u5217\u8868\u8fdb\u884c\u5206\u533a\"\"\" # \u627e\u5230\u57fa\u51c6\u5143\u7d20\uff08pivot\uff09\uff0c\u5e76\u548c\u6700\u540e\u4e00\u4e2a\u5143\u7d20\u4e92\u6362 middle = ( left + right ) // 2 pivot = lyst [ middle ] lyst [ middle ] = lyst [ right ] lyst [ right ] = pivot # \u8bbe\u5b9a\u8fb9\u754c\u5143\u7d20\uff08boundary point\uff09\uff0c\u521d\u59cb\u662f\u7b2c\u4e00\u4e2a\u5143\u7d20 boundary = left print ( \"pivot: \" , pivot , \"boundary: \" , lyst [ boundary ]) # \u628a\u6240\u6709\u5c0f\u4e8e\u57fa\u51c6\u7684\u5143\u7d20\u90fd\u79fb\u52a8\u5230\u8fb9\u754c\u7684\u5de6\u8fb9 for index in range ( left , right ): if lyst [ index ] < pivot : swap ( lyst , index , boundary ) boundary += 1 # \u4ea4\u6362\u57fa\u51c6\u5143\u7d20\u548c\u8fb9\u754c\u5143\u7d20 swap ( lyst , right , boundary ) print ( lyst ) return boundary def main ( size = 20 , sort = quicksort ): lyst = [ 12 , 19 , 17 , 18 , 14 , 11 , 15 , 13 , 16 ] sort ( lyst ) if __name__ == \"__main__\" : main () # \u8fd0\u884c\u7ed3\u679c\uff1a # [12, 19, 17, 18, 14, 11, 15, 13, 16] # pivot: 14 boundary: 12 # [12, 11, 13, 14, 16, 19, 15, 17, 18] # [12, 11, 13, 14, 16, 19, 15, 17, 18] # pivot: 11 boundary: 12 # [11, 13, 12, 14, 16, 19, 15, 17, 18] # [11, 13, 12, 14, 16, 19, 15, 17, 18] # [11, 13, 12, 14, 16, 19, 15, 17, 18] # pivot: 13 boundary: 12 # [11, 12, 13, 14, 16, 19, 15, 17, 18] # [11, 12, 13, 14, 16, 19, 15, 17, 18] # [11, 12, 13, 14, 16, 19, 15, 17, 18] # [11, 12, 13, 14, 16, 19, 15, 17, 18] # pivot: 15 boundary: 16 # [11, 12, 13, 14, 15, 19, 18, 17, 16] # [11, 12, 13, 14, 15, 19, 18, 17, 16] # [11, 12, 13, 14, 15, 19, 18, 17, 16] # pivot: 18 boundary: 19 # [11, 12, 13, 14, 15, 16, 17, 18, 19] # [11, 12, 13, 14, 15, 16, 17, 18, 19] # pivot: 16 boundary: 17 # [11, 12, 13, 14, 15, 16, 17, 18, 19] # [11, 12, 13, 14, 15, 16, 17, 18, 19] # [11, 12, 13, 14, 15, 16, 17, 18, 19] # [11, 12, 13, 14, 15, 16, 17, 18, 19] \u628amain()\u6539\u6210\u5982\u4e0b\uff0c\u5219\u53ef\u4ee5\u751f\u6210\u753120\u4e2a\u968f\u673a\u6574\u6570\u7ec4\u6210\u7684\u5217\u8868\uff1a def main ( size = 20 , sort = quicksort ): lyst = [] for count in range ( size ): lyst . append ( random . randint ( 1 , size + 1 )) print ( lyst ) sort ( lyst ) print ( lyst ) # \u8fd0\u884c\u7ed3\u679c\uff1a # \u7b2c\u4e00\u6b21\u8fd0\u884c # [3, 19, 18, 11, 2, 16, 2, 13, 14, 1, 20, 1, 1, 19, 19, 9, 16, 1, 7, 4] # [1, 1, 1, 1, 2, 2, 3, 4, 7, 9, 11, 13, 14, 16, 16, 18, 19, 19, 19, 20] # \u7b2c\u4e8c\u6b21\u8fd0\u884c # [20, 4, 1, 15, 6, 4, 3, 16, 21, 4, 12, 9, 16, 10, 3, 6, 2, 15, 21, 4] # [1, 2, 3, 3, 4, 4, 4, 4, 6, 6, 9, 10, 12, 15, 15, 16, 16, 20, 21, 21]","title":"3.5.1.3.\u5b9e\u73b0\u5feb\u901f\u6392\u5e8f"},{"location":"python/DataStructure/03_TimeComplexity/#352","text":"\u5f52\u5e76\u6392\u5e8f\u7684\u7b97\u6cd5\u4e5f\u662f\u91c7\u7528\u5206\u6cbb\u6cd5\uff08Divide and Conquer\uff09\u7684\u4e00\u4e2a\u975e\u5e38\u5178\u578b\u7684\u5e94\u7528\uff0c\u901a\u8fc7\u9012\u5f52\u548c\u5206\u6cbb\u7b56\u7565\u6765\u7a81\u7834 O(n^2) \u6027\u80fd\u74f6\u9888\u7684\u3002 \u4e0b\u9762\u662f\u5bf9\u8fd9\u4e2a\u7b97\u6cd5\u7684\u7b80\u5355\u63cf\u8ff0\u3002 \u5206\u89e3\uff08Divide\uff09\uff1a\u5c06n\u4e2a\u5143\u7d20\u5206\u6210\u4e2a\u542bn/2\u4e2a\u5143\u7d20\u7684\u5b50\u5e8f\u5217\u3002 \u89e3\u51b3\uff08Conquer\uff09\uff1a\u7528\u5408\u5e76\u6392\u5e8f\u6cd5\u5bf9\u4e24\u4e2a\u5b50\u5e8f\u5217\u9012\u5f52\u7684\u6392\u5e8f\u3002 \u5408\u5e76\uff08Combine\uff09\uff1a\u5408\u5e76\u4e24\u4e2a\u5df2\u6392\u5e8f\u7684\u5b50\u5e8f\u5217\u5df2\u5f97\u5230\u6392\u5e8f\u7ed3\u679c\u3002 \u7b97\u6cd5\u601d\u8def\uff1a \u8fed\u4ee3\u6cd5 \u7533\u8bf7\u7a7a\u95f4\uff0c\u4f7f\u5176\u5927\u5c0f\u4e3a\u4e24\u4e2a\u5df2\u7ecf\u6392\u5e8f\u5e8f\u5217\u4e4b\u548c\uff0c\u8be5\u7a7a\u95f4\u7528\u6765\u5b58\u653e\u5408\u5e76\u540e\u7684\u5e8f\u5217\uff1b \u8bbe\u5b9a\u4e24\u4e2a\u6307\u9488\uff0c\u6700\u521d\u4f4d\u7f6e\u5206\u522b\u4e3a\u4e24\u4e2a\u5df2\u7ecf\u6392\u5e8f\u5e8f\u5217\u7684\u8d77\u59cb\u4f4d\u7f6e\uff1b \u6bd4\u8f83\u4e24\u4e2a\u6307\u9488\u6240\u6307\u5411\u7684\u5143\u7d20\uff0c\u9009\u62e9\u76f8\u5bf9\u5c0f\u7684\u5143\u7d20\u653e\u5165\u5230\u5408\u5e76\u7a7a\u95f4\uff0c\u5e76\u79fb\u52a8\u6307\u9488\u5230\u4e0b\u4e00\u4f4d\u7f6e\uff1b \u91cd\u590d\u6b65\u9aa43\u76f4\u5230\u67d0\u4e00\u6307\u9488\u5230\u8fbe\u5e8f\u5217\u5c3e\uff1b \u5c06\u53e6\u4e00\u5e8f\u5217\u5269\u4e0b\u7684\u6240\u6709\u5143\u7d20\u76f4\u63a5\u590d\u5236\u5230\u5408\u5e76\u5e8f\u5217\u5c3e\uff1b \u9012\u5f52\u6cd5 \u5c06\u5e8f\u5217\u6bcf\u76f8\u90bb\u4e24\u4e2a\u6570\u5b57\u8fdb\u884c\u5f52\u5e76\u64cd\u4f5c\uff0c\u5f62\u6210 floor(n/2) \u4e2a\u5e8f\u5217\uff0c\u6392\u5e8f\u540e\u6bcf\u4e2a\u5e8f\u5217\u5305\u542b\u4e24\u4e2a\u5143\u7d20\uff1b \u5c06\u4e0a\u8ff0\u5e8f\u5217\u518d\u6b21\u5f52\u5e76\uff0c\u5f62\u6210 floor(n/4) \u4e2a\u5e8f\u5217\uff0c\u6bcf\u4e2a\u5e8f\u5217\u5305\u542b\u56db\u4e2a\u5143\u7d20\uff1b \u91cd\u590d\u6b65\u9aa42\uff0c\u76f4\u5230\u6240\u6709\u5143\u7d20\u6392\u5e8f\u5b8c\u6bd5\uff1b \u5728\u9876\u5c42\u5b9a\u4e49\u4e863\u4e2aPython\u51fd\u6570\u8fdb\u884c\u534f\u4f5c\u3002 mergeSort \uff1a\u7528\u6237\u8c03\u7528\u7684\u51fd\u6570\uff1b mergeSortHelper \uff1a\u8f85\u52a9\u51fd\u6570\uff0c\u7528\u6765\u9690\u85cf\u9012\u5f52\u8c03\u7528\u6240\u9700\u8981\u7684\u989d\u5916\u53c2\u6570\uff1b merge \uff1a\u5b9e\u73b0\u5408\u5e76\u8fc7\u7a0b\u7684\u51fd\u6570\uff1b","title":"3.5.2.\u5f52\u5e76\u6392\u5e8f"},{"location":"python/DataStructure/03_TimeComplexity/#3521","text":"\u5408\u5e76\u8fc7\u7a0b\u7528\u5230\u4e00\u4e2a\u4e0e\u5217\u8868\u5927\u5c0f\u76f8\u540c\u7684\u6570\u7ec4\uff0c\u8fd9\u4e2a\u6570\u7ec4\u53ef\u4ee5\u628a\u5b83\u79f0\u4e3a copyBuffer \u3002\u4e3a\u4e86\u907f\u514d\u6bcf\u6b21\u8c03\u7528 merge \u65f6\u90fd\u8981\u4e3a copyBuffer \u7684\u5206\u914d\u548c\u91ca\u653e\u4ea7\u751f\u5f00\u9500\uff0c\u8fd9\u4e2a\u7f13\u51b2\u533a\u4f1a\u5728 mergeSort \u51fd\u6570\u91cc\u5c31\u5206\u914d\u597d\uff0c\u7136\u540e\u4f5c\u4e3a\u53c2\u6570\u4f20\u9012\u7ed9 mergeSortHelper \u548c merge \u51fd\u6570\u3002\u6bcf\u6b21\u8c03\u7528 mergeSortHelper \u51fd\u6570\u65f6\uff0c\u5b83\u8fd8\u9700\u8981\u77e5\u9053\u5e94\u8be5\u4f7f\u7528\u7684\u5b50\u5217\u8868\u7684\u8303\u56f4\u3002\u8fd9\u4e2a\u8303\u56f4\u53ef\u4ee5\u7531\u53e6\u5916\u4e24\u4e2a\u53c2\u6570 low \u548c high \u6765\u63d0\u4f9b\u3002\u5177\u4f53\u5b9e\u73b0\u53c2\u8003 mergeSort \u51fd\u6570\u7684\u4ee3\u7801\u3002 \u5728\u68c0\u67e5\u4f20\u9012\u7684\u5b50\u5217\u8868\u662f\u4e0d\u662f\u81f3\u5c11\u6709\u4e24\u4e2a\u5143\u7d20\u4e4b\u540e\uff0c mergeSortHelper \u51fd\u6570\u5c06\u4f1a\u8ba1\u7b97\u8fd9\u4e2a\u5b50\u5217\u8868\u7684\u4e2d\u70b9\uff0c\u5e76\u4e14\u5bf9\u4e2d\u70b9\u5de6\u53f3\u4e24\u90e8\u5206\u8fdb\u884c\u9012\u5f52\u6392\u5e8f\uff0c\u6700\u540e\u518d\u8c03\u7528 merge \u51fd\u6570\u6765\u5408\u5e76\u7ed3\u679c\u3002\u5177\u4f53\u5b9e\u73b0\u53c2\u8003 mergeSortHelper \u51fd\u6570\u7684\u4ee3\u7801\u3002 merge \u51fd\u6570\u4f1a\u628a\u4e24\u4e2a\u5df2\u7ecf\u6392\u597d\u5e8f\u7684\u5b50\u5217\u8868\u5408\u5e76\u6210\u4e00\u4e2a\u66f4\u5927\u7684\u6709\u5e8f\u5217\u8868\u3002\u5728\u539f\u5217\u8868\u91cc\uff0c\u7b2c\u4e00\u4e2a\u5b50\u5217\u8868\u4f1a\u5728 low \u5230 middle \u4e4b\u95f4\uff1b\u7b2c\u4e8c\u4e2a\u5b50\u5217\u8868\u5219\u4f4d\u4e8e middle + 1 \u548c high \u4e4b\u95f4\u3002\u8fd9\u4e2a\u8fc7\u7a0b\u5305\u542b\u5982\u4e0b3\u4e2a\u6b65\u9aa4\u3002 \u8bbe\u7f6e\u6307\u5411\u4e24\u4e2a\u5b50\u5217\u8868\u4e2d\u7b2c\u4e00\u4e2a\u5143\u7d20\u7684\u7d22\u5f15\u6307\u9488\u3002\u5b83\u4eec\u5206\u522b\u4f4d\u4e8e low \u548c middle +1 \uff1b \u4ece\u5b50\u5217\u8868\u7684\u7b2c\u4e00\u4e2a\u5143\u7d20\u5f00\u59cb\u91cd\u590d\u6bd4\u8f83\u8fd9\u4e9b\u5143\u7d20\u3002\u628a\u66f4\u5c0f\u7684\u90a3\u4e2a\u5143\u7d20\u4ece\u5b83\u6240\u5728\u7684\u5b50\u5217\u8868\u91cc\u590d\u5236\u5230\u62f7\u8d1d\u7f13\u51b2\u533a\u53bb\uff0c\u7136\u540e\u628a\u8fd9\u4e2a\u5b50\u5217\u8868\u7684\u7d22\u5f15\u79fb\u52a8\u5230\u4e0b\u4e00\u4e2a\u5143\u7d20\uff1b \u4e0d\u65ad\u5730\u6267\u884c\u8fd9\u4e2a\u64cd\u4f5c\uff0c\u76f4\u5230\u5df2\u7ecf\u5b8c\u5168\u590d\u5236\u4e86\u4e24\u4e2a\u5b50\u5217\u8868\u91cc\u7684\u6240\u6709\u5143\u7d20\u3002\u5982\u679c\u5176\u4e2d\u4e00\u4e2a\u5b50\u5217\u8868\u5df2\u7ecf\u5230\u8fbe\u4e86\u672b\u5c3e\uff0c\u90a3\u4e48\u53ef\u4ee5\u628a\u53e6\u4e00\u4e2a\u5b50\u5217\u8868\u91cc\u7684\u5176\u4f59\u5143\u7d20\u76f4\u63a5\u590d\u5236\u8fc7\u53bb\uff1b \u628a copyBuffer \u4e2d low \u5230 high \u4e4b\u95f4\u7684\u90e8\u5206\u590d\u5236\u56de lyst \u4e2d\u7684\u76f8\u5e94\u4f4d\u7f6e\uff1b \u5b9e\u73b0\u4ee3\u7801\uff1a class Array ( object ): \"\"\" \u63cf\u8ff0\u4e00\u4e2a\u6570\u7ec4\u3002 \u6570\u7ec4\u7c7b\u4f3c\u5217\u8868\uff0c\u4f46\u6570\u7ec4\u53ea\u80fd\u4f7f\u7528[], len, iter, \u548c str\u8fd9\u4e9b\u5c5e\u6027\u3002 \u5b9e\u4f8b\u5316\u4e00\u4e2a\u6570\u7ec4\uff0c\u4f7f\u7528 = Array(, ) \u5176\u4e2dfill value\u9ed8\u8ba4\u503c\u662fNone\u3002 \"\"\" def __init__ ( self , capacity , fillValue = None ): \"\"\"Capacity\u662f\u6570\u7ec4\u7684\u5927\u5c0f. fillValue\u4f1a\u586b\u5145\u5728\u6bcf\u4e2a\u5143\u7d20\u4f4d\u7f6e, \u9ed8\u8ba4\u503c\u662fNone\"\"\" self . items = list () for count in range ( capacity ): self . items . append ( fillValue ) def __len__ ( self ): \"\"\"-> \u6570\u7ec4\u7684\u5927\u5c0f\"\"\" return len ( self . items ) def __str__ ( self ): \"\"\"-> \u5c06\u6570\u7ec4\u5b57\u7b26\u4e32\u5316\"\"\" return str ( self . items ) def __iter__ ( self ): \"\"\"\u652f\u6301for\u5faa\u73af\u5bf9\u6570\u7ec4\u8fdb\u884c\u904d\u5386.\"\"\" return iter ( self . items ) def __getitem__ ( self , index ): \"\"\"\u7528\u4e8e\u8bbf\u95ee\u7d22\u5f15\u5904\u7684\u4e0b\u6807\u8fd0\u7b97\u7b26.\"\"\" return self . items [ index ] def __setitem__ ( self , index , newItem ): \"\"\"\u4e0b\u6807\u8fd0\u7b97\u7b26\u7528\u4e8e\u5728\u7d22\u5f15\u5904\u8fdb\u884c\u66ff\u6362.\"\"\" self . items [ index ] = newItem def mergeSort ( lyst ): # lyst : \u7528\u4e8e\u6392\u5e8f\u7684\u5217\u8868 # copyBuffer : \u7528\u4e8e\u5408\u5e76\u7684\u4e34\u65f6\u7a7a\u95f4 copyBuffer = Array ( len ( lyst )) mergeSortHelper ( lyst , copyBuffer , 0 , len ( lyst ) - 1 ) def mergeSortHelper ( lyst , copyBuffer , low , high ): # lyst : \u7528\u4e8e\u6392\u5e8f\u7684\u5217\u8868 # copyBuffer : \u7528\u4e8e\u5408\u5e76\u7684\u4e34\u65f6\u7a7a\u95f4 # low, high : \u5b50\u5217\u8868\u7684\u8fb9\u754c # middle : \u5b50\u5217\u8868\u7684\u4e2d\u70b9 if low < high : middle = ( low + high ) // 2 print ( f 'low: { lyst [ low ] } , middle: { lyst [ middle ] } , high: { lyst [ high ] } , copyBuffer: { copyBuffer } ' ) # \u9012\u5f52\u5904\u7406\u7b2c\u4e00\u4e2a\u6392\u5e8f\u5b50\u5217\u8868\uff0c\u5373\u4e2d\u503c\u7684\u5de6\u6bb5\uff0c\u76f4\u81f3\u4e0d\u6ee1\u8db3low < high\u65f6\u9000\u51fa mergeSortHelper ( lyst , copyBuffer , low , middle ) # \u9012\u5f52\u5904\u7406\u7b2c\u4e8c\u4e2a\u6392\u5e8f\u5b50\u5217\u8868\uff0c\u5373\u4e2d\u503c\u7684\u53f3\u6bb5\uff0c\u76f4\u81f3\u4e0d\u6ee1\u8db3low < high\u65f6\u9000\u51fa mergeSortHelper ( lyst , copyBuffer , middle + 1 , high ) # \u5f53\u524d\u5904\u7406\u7684\u5b50\u8868\u6570\u636e\u9001\u5165copyBuffer\uff0c\u5408\u5e76\u4e14\u6392\u5e8f merge ( lyst , copyBuffer , low , middle , high ) def merge ( lyst , copyBuffer , low , middle , high ): # lyst : \u7528\u4e8e\u6392\u5e8f\u7684\u5217\u8868 # copyBuffer : \u7528\u4e8e\u5408\u5e76\u7684\u4e34\u65f6\u7a7a\u95f4 # low : \u7b2c\u4e00\u4e2a\u6392\u5e8f\u5b50\u5217\u8868\u7684\u5f00\u5934 # middle : \u7b2c\u4e00\u4e2a\u6392\u5e8f\u5b50\u5217\u8868\u7684\u7ed3\u5c3e # middle + 1 : \u7b2c\u4e8c\u4e2a\u6392\u5e8f\u5b50\u5217\u8868\u7684\u5f00\u5934 # high : \u7b2c\u4e8c\u4e2a\u6392\u5e8f\u5b50\u5217\u8868\u7684\u7ed3\u5c3e # \u5c06 i1 \u548c i2 \u521d\u59cb\u5316\u4e3a\u6bcf\u4e2a\u5b50\u5217\u8868\u4e2d\u7684\u7b2c\u4e00\u9879 i1 = low i2 = middle + 1 # \u5c06\u5b50\u5217\u8868\u4e2d\u7684\u5143\u7d20\u4ea4\u9519\u653e\u5165copyBuffer\u4e2d\uff0c\u5e76\u4fdd\u6301\u987a\u5e8f\u3002 for i in range ( low , high + 1 ): if i1 > middle : copyBuffer [ i ] = lyst [ i2 ] # \u7b2c\u4e00\u4e2a\u5b50\u5217\u8868\u5df2\u7528\u5b8c i2 += 1 elif i2 > high : copyBuffer [ i ] = lyst [ i1 ] # \u7b2c\u4e8c\u4e2a\u5b50\u5217\u8868\u5df2\u7528\u5b8c i1 += 1 elif lyst [ i1 ] < lyst [ i2 ]: copyBuffer [ i ] = lyst [ i1 ] # \u7b2c\u4e00\u4e2a\u5b50\u8868\u4e2d\u7684\u5143\u7d20 < i1 += 1 else : copyBuffer [ i ] = lyst [ i2 ] # \u7b2c\u4e8c\u4e2a\u5b50\u8868\u4e2d\u7684\u5143\u7d20 < i2 += 1 print ( \"i=\" , i , \"\" , \"i1=\" , i1 , \"i2=\" , i2 , \"copyBuffer:\" , copyBuffer ) for i in range ( low , high + 1 ): # \u5c06\u5df2\u6392\u5e8f\u7684\u5143\u7d20\u590d\u5236\u56delyst\u4e2d\u7684\u6b63\u786e\u4f4d\u7f6e lyst [ i ] = copyBuffer [ i ] def main (): lyst = [ 12 , 19 , 17 , 18 , 14 , 11 , 15 , 13 , 16 ] print ( \"Original List\" , lyst ) mergeSort ( lyst ) print ( \"Sorted List\" , lyst ) if __name__ == \"__main__\" : main () # \u8fd0\u884c\u7ed3\u679c\uff1a # Original List [12, 19, 17, 18, 14, 11, 15, 13, 16] # low: 12, middle: 14, high: 16, copyBuffer: [None, None, None, None, None, None, None, None, None] # low: 12, middle: 17, high: 14, copyBuffer: [None, None, None, None, None, None, None, None, None] # low: 12, middle: 19, high: 17, copyBuffer: [None, None, None, None, None, None, None, None, None] # low: 12, middle: 12, high: 19, copyBuffer: [None, None, None, None, None, None, None, None, None] # i= 1 i1= 1 i2= 2 copyBuffer: [12, 19, None, None, None, None, None, None, None] # i= 2 i1= 2 i2= 3 copyBuffer: [12, 17, 19, None, None, None, None, None, None] # low: 18, middle: 18, high: 14, copyBuffer: [12, 17, 19, None, None, None, None, None, None] # i= 4 i1= 4 i2= 5 copyBuffer: [12, 17, 19, 14, 18, None, None, None, None] # i= 4 i1= 3 i2= 5 copyBuffer: [12, 14, 17, 18, 19, None, None, None, None] # low: 11, middle: 15, high: 16, copyBuffer: [12, 14, 17, 18, 19, None, None, None, None] # low: 11, middle: 11, high: 15, copyBuffer: [12, 14, 17, 18, 19, None, None, None, None] # i= 6 i1= 6 i2= 7 copyBuffer: [12, 14, 17, 18, 19, 11, 15, None, None] # low: 13, middle: 13, high: 16, copyBuffer: [12, 14, 17, 18, 19, 11, 15, None, None] # i= 8 i1= 8 i2= 9 copyBuffer: [12, 14, 17, 18, 19, 11, 15, 13, 16] # i= 8 i1= 7 i2= 9 copyBuffer: [12, 14, 17, 18, 19, 11, 13, 15, 16] # i= 8 i1= 5 i2= 9 copyBuffer: [11, 12, 13, 14, 15, 16, 17, 18, 19] # Sorted List [11, 12, 13, 14, 15, 16, 17, 18, 19] \u8fd0\u884c\u7ed3\u679c\u56fe\u793a\u5206\u6790\uff1a","title":"3.5.2.1.\u5408\u5e76\u8fc7\u7a0b\u7684\u5b9e\u73b0"},{"location":"python/DataStructure/03_TimeComplexity/#3522","text":"merge \u51fd\u6570\u7684\u8fd0\u884c\u65f6\u7531\u4e24\u4e2a for \u8bed\u53e5\u6765\u51b3\u5b9a\uff0c\u800c\u8fd9\u4e24\u4e2a\u5faa\u73af\u90fd\u4f1a\u88ab\u8fed\u4ee3 (high \u2013 low + 1) \u6b21\uff0c\u56e0\u6b64\uff0c\u8fd9\u4e2a\u51fd\u6570\u7684\u8fd0\u884c\u65f6\u662f O(high\u2212low) \uff0c\u4e8e\u662f\u6bcf\u4e00\u5c42\u4e0a\u7684\u6240\u6709\u5408\u5e76\u603b\u5171\u9700\u8981 O(n) \u7684\u65f6\u95f4\u3002\u56e0\u4e3a mergeSortHelper \u5728\u6bcf\u4e00\u5c42\u90fd\u5c3d\u53ef\u80fd\u5747\u5300\u5730\u62c6\u5206\u5b50\u5217\u8868\uff0c\u6240\u4ee5\u5c42\u6570\u5e94\u8be5\u662f O(log n) \uff0c\u5728\u6240\u6709\u7684\u60c5\u51b5\u4e0b\u8fd9\u4e2a\u51fd\u6570\u7684\u6700\u5927\u8fd0\u884c\u65f6\u90fd\u662f O(n log n) \u3002 \u5f52\u5e76\u6392\u5e8f\u4f1a\u6709\u4e24\u4e2a\u57fa\u4e8e\u5217\u8868\u5927\u5c0f\u7684\u7a7a\u95f4\u9700\u6c42\u3002\u9996\u5148\uff0c\u5728\u8c03\u7528\u6808\u4e0a\u9700\u8981 O(log n) \u7684\u7a7a\u95f4\u6765\u652f\u6301\u9012\u5f52\u8c03\u7528\uff1b\u5176\u6b21\uff0c\u62f7\u8d1d\u7f13\u51b2\u533a\u4f1a\u7528\u5230 O(n) \u7684\u7a7a\u95f4\u3002","title":"3.5.2.2.\u5f52\u5e76\u6392\u5e8f\u7684\u590d\u6742\u5ea6\u5206\u6790"},{"location":"python/DataStructure/03_TimeComplexity/#353","text":"\u63cf\u8ff0\u5feb\u901f\u6392\u5e8f\u7684\u7b56\u7565\uff0c\u5e76\u8bf4\u660e\u4e3a\u4ec0\u4e48\u5b83\u53ef\u4ee5\u628a\u6392\u5e8f\u7684\u65f6\u95f4\u590d\u6742\u5ea6\u4ece O(n^2) \u964d\u4f4e\u5230 O(n log n) \u3002 \u89e3\u7b54\uff1a\u5feb\u901f\u6392\u5e8f\uff08Quick Sort\uff09\u662f\u4e00\u79cd\u9ad8\u6548\u7684\u6392\u5e8f\u7b97\u6cd5\uff0c\u5b83\u91c7\u7528\u5206\u6cbb\u7b56\u7565\u6765\u5c06\u4e00\u4e2a\u5927\u95ee\u9898\u5206\u89e3\u6210\u82e5\u5e72\u4e2a\u5b50\u95ee\u9898\uff0c\u7136\u540e\u9012\u5f52\u5730\u89e3\u51b3\u8fd9\u4e9b\u5b50\u95ee\u9898\u3002\u4ee5\u4e0b\u662f\u5feb\u901f\u6392\u5e8f\u7684\u7b56\u7565\u548c\u539f\u7406\uff0c\u4ee5\u53ca\u4e3a\u4ec0\u4e48\u5b83\u80fd\u591f\u5c06\u6392\u5e8f\u7684\u65f6\u95f4\u590d\u6742\u5ea6\u4ece O(n^2) \u964d\u4f4e\u5230 O(n log n) \uff1a \u5feb\u901f\u6392\u5e8f\u7684\u7b56\u7565\uff1a \u9009\u62e9\u4e3b\u5143\uff08Pivot\uff09\uff1a\u5728\u5feb\u901f\u6392\u5e8f\u4e2d\uff0c\u9996\u5148\u4ece\u5f85\u6392\u5e8f\u7684\u5143\u7d20\u4e2d\u9009\u62e9\u4e00\u4e2a\u4e3b\u5143\uff08\u901a\u5e38\u662f\u7b2c\u4e00\u4e2a\u6216\u6700\u540e\u4e00\u4e2a\u5143\u7d20\uff09\uff0c\u4e5f\u53eb\u57fa\u51c6\u5143\u7d20\u3002 \u5206\u5272\u64cd\u4f5c\uff1a\u5c06\u5143\u7d20\u5206\u4e3a\u4e24\u4e2a\u5b50\u6570\u7ec4\uff0c\u4e00\u4e2a\u5c0f\u4e8e\u4e3b\u5143\u7684\u5b50\u6570\u7ec4\uff0c\u4e00\u4e2a\u5927\u4e8e\u4e3b\u5143\u7684\u5b50\u6570\u7ec4\u3002\u8fd9\u4e2a\u8fc7\u7a0b\u79f0\u4e3a\u5206\u5272\u3002 \u9012\u5f52\u6392\u5e8f\uff1a\u9012\u5f52\u5730\u5bf9\u4e24\u4e2a\u5b50\u6570\u7ec4\u8fdb\u884c\u6392\u5e8f\u3002\u5373\uff0c\u5bf9\u5c0f\u4e8e\u4e3b\u5143\u7684\u5b50\u6570\u7ec4\u548c\u5927\u4e8e\u4e3b\u5143\u7684\u5b50\u6570\u7ec4\u5206\u522b\u8fdb\u884c\u5feb\u901f\u6392\u5e8f\u3002 \u5408\u5e76\uff1a\u5c06\u5df2\u6392\u5e8f\u7684\u5b50\u6570\u7ec4\u5408\u5e76\u6210\u6700\u7ec8\u7684\u6709\u5e8f\u6570\u7ec4\u3002 \u4e3a\u4ec0\u4e48\u5feb\u901f\u6392\u5e8f\u80fd\u591f\u964d\u4f4e\u65f6\u95f4\u590d\u6742\u5ea6\uff1a \u5feb\u901f\u6392\u5e8f\u4e4b\u6240\u4ee5\u80fd\u591f\u5c06\u6392\u5e8f\u7684\u65f6\u95f4\u590d\u6742\u5ea6\u4ece O(n^2) \u964d\u4f4e\u5230 O(n log n) \uff0c\u4e3b\u8981\u6709\u4ee5\u4e0b\u539f\u56e0\uff1a \u5206\u6cbb\u7b56\u7565\uff1a\u5feb\u901f\u6392\u5e8f\u91c7\u7528\u4e86\u5206\u6cbb\u7b56\u7565\uff0c\u5c06\u4e00\u4e2a\u5927\u95ee\u9898\u5206\u89e3\u6210\u4e24\u4e2a\u6216\u591a\u4e2a\u89c4\u6a21\u8f83\u5c0f\u7684\u5b50\u95ee\u9898\u3002\u8fd9\u79cd\u5206\u6cbb\u7b56\u7565\u80fd\u591f\u51cf\u5c0f\u95ee\u9898\u7684\u89c4\u6a21\uff0c\u4ece\u800c\u964d\u4f4e\u4e86\u89e3\u51b3\u95ee\u9898\u7684\u590d\u6742\u5ea6\u3002 \u597d\u7684\u5e73\u5747\u60c5\u51b5\uff1a\u5728\u5e73\u5747\u60c5\u51b5\u4e0b\uff0c\u5feb\u901f\u6392\u5e8f\u5bf9\u5f85\u6392\u5e8f\u7684\u6570\u636e\u8fdb\u884c\u4e86\u826f\u597d\u7684\u5e73\u5747\u5206\u5272\uff0c\u6bcf\u6b21\u5206\u5272\u90fd\u5c06\u95ee\u9898\u89c4\u6a21\u51cf\u534a\u3002\u8fd9\u4f7f\u5f97\u5e73\u5747\u65f6\u95f4\u590d\u6742\u5ea6\u4e3a O(n log n) \u3002 **\u4e0d\u7a33\u5b9a\u6027\uff1a\u5feb\u901f\u6392\u5e8f\u662f\u4e0d\u7a33\u5b9a\u7684\u6392\u5e8f\u7b97\u6cd5\uff0c\u8fd9\u610f\u5473\u7740\u76f8\u540c\u5143\u7d20\u7684\u76f8\u5bf9\u987a\u5e8f\u5728\u6392\u5e8f\u540e\u53ef\u80fd\u4f1a\u6539\u53d8\u3002\u8fd9\u79cd\u4e0d\u7a33\u5b9a\u6027\u4f7f\u5f97\u5feb\u901f\u6392\u5e8f\u53ef\u4ee5\u66f4\u5feb\u5730\u6392\u5e8f\u76f8\u540c\u5143\u7d20\u7684\u5927\u6570\u636e\u96c6\u3002 \u539f\u5730\u6392\u5e8f\uff1a\u5feb\u901f\u6392\u5e8f\u901a\u5e38\u662f\u539f\u5730\u6392\u5e8f\u7684\uff0c\u5b83\u4e0d\u9700\u8981\u989d\u5916\u7684\u5185\u5b58\u6765\u5b58\u50a8\u4e34\u65f6\u6570\u636e\u3002\u8fd9\u5bf9\u4e8e\u5185\u5b58\u5360\u7528\u6709\u9650\u7684\u60c5\u51b5\u5f88\u6709\u5229\u3002 \u6700\u574f\u60c5\u51b5\u4e0b\uff0c\u5feb\u901f\u6392\u5e8f\u7684\u65f6\u95f4\u590d\u6742\u5ea6\u4ecd\u7136\u662f O(n^2) \uff0c\u8fd9\u79cd\u60c5\u51b5\u901a\u5e38\u53d1\u751f\u5728\u4e3b\u5143\u9009\u62e9\u4e0d\u5f53\u6216\u8f93\u5165\u6570\u636e\u5df2\u7ecf\u6709\u5e8f\u7684\u60c5\u51b5\u4e0b\u3002\u5728\u5b9e\u9645\u5e94\u7528\u4e2d\uff0c\u901a\u5e38\u9700\u8981\u9009\u62e9\u4e00\u4e2a\u5408\u9002\u7684\u4e3b\u5143\u9009\u62e9\u7b56\u7565\uff0c\u4ee5\u5c3d\u91cf\u907f\u514d\u6700\u574f\u60c5\u51b5\u7684\u53d1\u751f\u3002 \u4e3a\u4ec0\u4e48\u5feb\u901f\u6392\u5e8f\u5e76\u4e0d\u5728\u6240\u6709\u60c5\u51b5\u4e0b\u90fd\u6709 O(n log n) \u7684\u590d\u6742\u5ea6\uff1f\u5bf9\u5feb\u901f\u6392\u5e8f\u7684\u6700\u574f\u60c5\u51b5\u8fdb\u884c\u63cf\u8ff0\uff0c\u5e76\u7ed9\u51fa\u4e00\u4e2a\u4f1a\u4ea7\u751f\u8fd9\u4e2a\u60c5\u51b5\u7684\u5305\u542b10\u4e2a\u6574\u6570\uff081\uff5e10\uff09\u7684\u5217\u8868\u3002 \u89e3\u7b54\uff1a\u5feb\u901f\u6392\u5e8f\u5e76\u4e0d\u5728\u6240\u6709\u60c5\u51b5\u4e0b\u90fd\u5177\u6709 O(n log n) \u7684\u65f6\u95f4\u590d\u6742\u5ea6\uff0c\u5b83\u7684\u6027\u80fd\u53d6\u51b3\u4e8e\u4e3b\u5143\uff08pivot\uff09\u7684\u9009\u62e9\u548c\u8f93\u5165\u6570\u636e\u7684\u5206\u5e03\u60c5\u51b5\u3002\u6700\u574f\u60c5\u51b5\u53d1\u751f\u5728\u4ee5\u4e0b\u60c5\u51b5\u4e0b\uff1a \u4e3b\u5143\u9009\u62e9\u4e0d\u5f53\uff1a\u5982\u679c\u6bcf\u6b21\u9009\u62e9\u7684\u4e3b\u5143\u90fd\u662f\u8f93\u5165\u6570\u636e\u4e2d\u7684\u6700\u5c0f\u6216\u6700\u5927\u5143\u7d20\uff0c\u5feb\u901f\u6392\u5e8f\u5c06\u4f1a\u4ea7\u751f\u6700\u574f\u60c5\u51b5\u3002\u5728\u8fd9\u79cd\u60c5\u51b5\u4e0b\uff0c\u5206\u5272\u64cd\u4f5c\u5c06\u5bfc\u81f4\u4e00\u4e2a\u5b50\u6570\u7ec4\u4e3a\u7a7a\uff0c\u53e6\u4e00\u4e2a\u5b50\u6570\u7ec4\u7684\u5927\u5c0f\u4e3a\u539f\u59cb\u6570\u7ec4\u5927\u5c0f\u51cf\u4e00\u3002\u8fd9\u4f7f\u5f97\u6bcf\u6b21\u5206\u5272\u64cd\u4f5c\u53ea\u51cf\u5c11\u4e00\u4e2a\u5143\u7d20\uff0c\u5bfc\u81f4\u9012\u5f52\u6df1\u5ea6\u8fbe\u5230\u6700\u5927\uff0c\u65f6\u95f4\u590d\u6742\u5ea6\u4e3a O(n^2) \u3002 \u8f93\u5165\u6570\u636e\u5df2\u7ecf\u6709\u5e8f\uff1a\u5982\u679c\u8f93\u5165\u6570\u636e\u5df2\u7ecf\u662f\u6709\u5e8f\u7684\uff0c\u4e0d\u7ba1\u662f\u5347\u5e8f\u8fd8\u662f\u964d\u5e8f\uff0c\u5feb\u901f\u6392\u5e8f\u4e5f\u4f1a\u4ea7\u751f\u6700\u574f\u60c5\u51b5\u3002\u56e0\u4e3a\u65e0\u8bba\u5982\u4f55\u9009\u62e9\u4e3b\u5143\uff0c\u5206\u5272\u64cd\u4f5c\u90fd\u5c06\u5bfc\u81f4\u4e00\u4e2a\u5b50\u6570\u7ec4\u4e3a\u7a7a\uff0c\u53e6\u4e00\u4e2a\u5b50\u6570\u7ec4\u7684\u5927\u5c0f\u4e3a\u539f\u59cb\u6570\u7ec4\u5927\u5c0f\u51cf\u4e00\u3002 \u4e0b\u9762\u662f\u4e00\u4e2a\u5305\u542b10\u4e2a\u6574\u6570\uff081\uff5e10\uff09\u7684\u5217\u8868\uff0c\u6f14\u793a\u4e86\u5bfc\u81f4\u5feb\u901f\u6392\u5e8f\u6700\u574f\u60c5\u51b5\u7684\u8f93\u5165\u6570\u636e\uff1a [ 10 , 9 , 8 , 7 , 6 , 5 , 4 , 3 , 2 , 1 ] \u5728\u8fd9\u4e2a\u793a\u4f8b\u4e2d\uff0c\u6bcf\u6b21\u9009\u62e9\u7684\u4e3b\u5143\u90fd\u662f\u6700\u5927\u7684\u5143\u7d20\uff0810\uff09\uff0c\u5bfc\u81f4\u5206\u5272\u64cd\u4f5c\u4e0d\u65ad\u51cf\u5c11\u6570\u7ec4\u7684\u5927\u5c0f\uff0c\u9012\u5f52\u6df1\u5ea6\u8fbe\u5230\u6700\u5927\uff0c\u65f6\u95f4\u590d\u6742\u5ea6\u4e3a O(n^2) \u3002 \u8981\u907f\u514d\u6700\u574f\u60c5\u51b5\uff0c\u901a\u5e38\u91c7\u7528\u4ee5\u4e0b\u7b56\u7565\uff1a \u9009\u62e9\u5408\u9002\u7684\u4e3b\u5143\uff0c\u4f8b\u5982\u9009\u62e9\u4e2d\u95f4\u5143\u7d20\uff0c\u4ee5\u786e\u4fdd\u5e73\u5747\u5206\u5272\u3002 \u968f\u673a\u9009\u62e9\u4e3b\u5143\uff0c\u4ee5\u51cf\u5c11\u51fa\u73b0\u6700\u574f\u60c5\u51b5\u7684\u6982\u7387\u3002 \u8fd9\u4e9b\u7b56\u7565\u6709\u52a9\u4e8e\u7ef4\u6301\u5feb\u901f\u6392\u5e8f\u7684\u5e73\u5747\u65f6\u95f4\u590d\u6742\u5ea6\u4e3a O(n log n) \u3002 \u5feb\u901f\u6392\u5e8f\u91cc\u7684\u5206\u5272\u64cd\u4f5c\u4f1a\u9009\u62e9\u4e2d\u70b9\u5143\u7d20\u4f5c\u4e3a\u57fa\u51c6\u3002\u8bf7\u63cf\u8ff0\u53e6\u5916\u4e24\u79cd\u9009\u62e9\u57fa\u51c6\u7684\u7b56\u7565\u3002 \u89e3\u7b54\uff1a\u5feb\u901f\u6392\u5e8f\u4e2d\u7684\u5206\u5272\u64cd\u4f5c\u53ef\u4ee5\u9009\u62e9\u4e2d\u70b9\u5143\u7d20\u4f5c\u4e3a\u57fa\u51c6\uff0c\u4f46\u8fd8\u6709\u5176\u4ed6\u4e24\u79cd\u5e38\u89c1\u7684\u9009\u62e9\u57fa\u51c6\u7684\u7b56\u7565\uff0c\u5b83\u4eec\u5206\u522b\u662f\uff1a \u968f\u673a\u9009\u62e9\u57fa\u51c6\uff08Random Pivot\uff09\uff1a\u8fd9\u79cd\u7b56\u7565\u662f\u5728\u5f85\u6392\u5e8f\u6570\u7ec4\u4e2d\u968f\u673a\u9009\u62e9\u4e00\u4e2a\u5143\u7d20\u4f5c\u4e3a\u57fa\u51c6\u3002\u968f\u673a\u9009\u62e9\u57fa\u51c6\u7684\u597d\u5904\u662f\u53ef\u4ee5\u964d\u4f4e\u51fa\u73b0\u6700\u574f\u60c5\u51b5\u7684\u6982\u7387\uff0c\u56e0\u4e3a\u5728\u5927\u591a\u6570\u60c5\u51b5\u4e0b\uff0c\u968f\u673a\u9009\u62e9\u7684\u57fa\u51c6\u4f1a\u6bd4\u56fa\u5b9a\u4f4d\u7f6e\u7684\u57fa\u51c6\u66f4\u5e73\u5747\u5730\u5212\u5206\u6570\u636e\u3002\u8fd9\u53ef\u4ee5\u63d0\u9ad8\u7b97\u6cd5\u7684\u6027\u80fd\u3002 \u4e09\u6570\u53d6\u4e2d\u6cd5\uff08Median-of-Three Pivot\uff09\uff1a\u8fd9\u79cd\u7b56\u7565\u662f\u5728\u5f85\u6392\u5e8f\u6570\u7ec4\u4e2d\u9009\u62e9\u4e09\u4e2a\u5143\u7d20\uff08\u901a\u5e38\u662f\u7b2c\u4e00\u4e2a\u3001\u4e2d\u95f4\u4e00\u4e2a\u548c\u6700\u540e\u4e00\u4e2a\u5143\u7d20\uff09\uff0c\u7136\u540e\u4ece\u8fd9\u4e09\u4e2a\u5143\u7d20\u4e2d\u9009\u62e9\u4e2d\u95f4\u503c\u4f5c\u4e3a\u57fa\u51c6\u3002\u8fd9\u4e2a\u7b56\u7565\u7684\u76ee\u7684\u662f\u5728\u5c3d\u91cf\u907f\u514d\u6700\u574f\u60c5\u51b5\u7684\u540c\u65f6\uff0c\u4fdd\u6301\u57fa\u51c6\u7684\u76f8\u5bf9\u4e2d\u95f4\u4f4d\u7f6e\u3002\u8fd9\u53ef\u4ee5\u63d0\u9ad8\u7b97\u6cd5\u7684\u5e73\u5747\u6027\u80fd\u3002 \u8fd9\u4e09\u79cd\u9009\u62e9\u57fa\u51c6\u7684\u7b56\u7565\u5404\u6709\u4f18\u52a3\uff0c\u4f46\u5b83\u4eec\u7684\u5171\u540c\u76ee\u6807\u662f\u964d\u4f4e\u6700\u574f\u60c5\u51b5\u7684\u6982\u7387\uff0c\u4ece\u800c\u63d0\u9ad8\u5feb\u901f\u6392\u5e8f\u7684\u6027\u80fd\u3002\u5728\u5b9e\u9645\u5e94\u7528\u4e2d\uff0c\u9009\u62e9\u54ea\u79cd\u7b56\u7565\u53d6\u51b3\u4e8e\u5177\u4f53\u7684\u60c5\u51b5\u548c\u5b9e\u73b0\u3002 \u5f53\u5feb\u901f\u6392\u5e8f\u91cc\u7684\u5b50\u5217\u8868\u7684\u957f\u5ea6\u5c0f\u4e8e\u67d0\u4e2a\u6570\u5b57\uff08\u598230\uff09\u65f6\uff0c\u6267\u884c\u63d2\u5165\u6392\u5e8f\u6765\u5904\u7406\u8fd9\u4e2a\u5b50\u5217\u8868\u3002\u8bf7\u8bf4\u660e\u4e3a\u4ec0\u4e48\u8fd9\u662f\u4e00\u4e2a\u597d\u65b9\u6cd5\u3002 \u89e3\u7b54\uff1a\u5728\u5feb\u901f\u6392\u5e8f\u4e2d\uff0c\u5f53\u5b50\u5217\u8868\u7684\u957f\u5ea6\u53d8\u5f97\u5f88\u5c0f\u65f6\uff08\u901a\u5e38\u5c0f\u4e8e\u67d0\u4e2a\u9884\u5b9a\u7684\u9608\u503c\uff0c\u598230\u6216\u5176\u4ed6\u7ecf\u9a8c\u503c\uff09\uff0c\u6267\u884c\u63d2\u5165\u6392\u5e8f\u6765\u5904\u7406\u8fd9\u4e2a\u5b50\u5217\u8868\u662f\u4e00\u4e2a\u597d\u65b9\u6cd5\uff0c\u4e3b\u8981\u57fa\u4e8e\u4ee5\u4e0b\u8003\u8651\uff1a \u63d2\u5165\u6392\u5e8f\u5bf9\u5c0f\u89c4\u6a21\u6570\u636e\u8868\u73b0\u826f\u597d\uff1a\u63d2\u5165\u6392\u5e8f\u662f\u4e00\u79cd\u7b80\u5355\u4f46\u9ad8\u6548\u7684\u6392\u5e8f\u7b97\u6cd5\uff0c\u7279\u522b\u9002\u7528\u4e8e\u5c0f\u89c4\u6a21\u6570\u636e\u96c6\u3002\u5b83\u7684\u65f6\u95f4\u590d\u6742\u5ea6\u4e3a O(n^2) \uff0c\u4f46\u5728\u5b9e\u9645\u5e94\u7528\u4e2d\uff0c\u5bf9\u4e8e\u5c0f\u89c4\u6a21\u7684\u6570\u636e\uff0c\u5b83\u7684\u6027\u80fd\u901a\u5e38\u5f88\u597d\u3002 \u51cf\u5c11\u9012\u5f52\u6df1\u5ea6\uff1a\u5728\u5feb\u901f\u6392\u5e8f\u4e2d\uff0c\u6bcf\u6b21\u9012\u5f52\u8c03\u7528\u90fd\u4f1a\u589e\u52a0\u9012\u5f52\u6df1\u5ea6\uff0c\u800c\u9012\u5f52\u6df1\u5ea6\u8fc7\u5927\u53ef\u80fd\u4f1a\u5bfc\u81f4\u6808\u6ea2\u51fa\u6216\u6027\u80fd\u4e0b\u964d\u3002\u5f53\u5b50\u5217\u8868\u957f\u5ea6\u5c0f\u4e8e\u67d0\u4e2a\u9608\u503c\u65f6\uff0c\u4f7f\u7528\u63d2\u5165\u6392\u5e8f\u53ef\u4ee5\u907f\u514d\u4e0d\u5fc5\u8981\u7684\u9012\u5f52\u6df1\u5ea6\uff0c\u4ece\u800c\u51cf\u5c11\u9012\u5f52\u8c03\u7528\u7684\u6b21\u6570\u3002 \u9002\u7528\u4e8e\u90e8\u5206\u6709\u5e8f\u7684\u5b50\u5217\u8868\uff1a\u5f53\u5b50\u5217\u8868\u5df2\u7ecf\u90e8\u5206\u6709\u5e8f\u65f6\uff0c\u63d2\u5165\u6392\u5e8f\u7684\u6027\u80fd\u901a\u5e38\u6bd4\u5feb\u901f\u6392\u5e8f\u66f4\u597d\u3002\u56e0\u6b64\uff0c\u5bf9\u4e8e\u53ef\u80fd\u5305\u542b\u5df2\u6392\u5e8f\u90e8\u5206\u7684\u5c0f\u5b50\u5217\u8868\uff0c\u4f7f\u7528\u63d2\u5165\u6392\u5e8f\u53ef\u4ee5\u63d0\u9ad8\u7b97\u6cd5\u7684\u6548\u7387\u3002 \u51cf\u5c11\u9012\u5f52\u5f00\u9500\uff1a\u9012\u5f52\u5f00\u9500\u662f\u5feb\u901f\u6392\u5e8f\u7684\u4e00\u4e2a\u4e0d\u53ef\u5ffd\u89c6\u7684\u56e0\u7d20\uff0c\u7279\u522b\u662f\u5728\u5904\u7406\u5c0f\u89c4\u6a21\u5b50\u5217\u8868\u65f6\u3002\u901a\u8fc7\u4f7f\u7528\u63d2\u5165\u6392\u5e8f\u6765\u5904\u7406\u8fd9\u4e9b\u5c0f\u89c4\u6a21\u5b50\u5217\u8868\uff0c\u53ef\u4ee5\u51cf\u5c11\u9012\u5f52\u5f00\u9500\uff0c\u63d0\u9ad8\u7b97\u6cd5\u7684\u6574\u4f53\u6027\u80fd\u3002 \u5c06\u63d2\u5165\u6392\u5e8f\u4e0e\u5feb\u901f\u6392\u5e8f\u7ed3\u5408\u4f7f\u7528\u662f\u4e00\u79cd\u5e38\u89c1\u7684\u4f18\u5316\u7b56\u7565\uff0c\u5b83\u53ef\u4ee5\u5728\u5904\u7406\u5c0f\u89c4\u6a21\u5b50\u5217\u8868\u65f6\u63d0\u9ad8\u7b97\u6cd5\u7684\u6548\u7387\uff0c\u540c\u65f6\u4fdd\u6301\u5feb\u901f\u6392\u5e8f\u7684\u6574\u4f53\u6027\u80fd\u3002\u8fd9\u79cd\u65b9\u6cd5\u88ab\u79f0\u4e3a\u201c\u5feb\u901f\u6392\u5e8f\u7684\u6539\u8fdb\u201d\u6216\u201c\u5feb\u901f\u6392\u5e8f\u7684\u6df7\u5408\u6392\u5e8f\u201d\u7b56\u7565\uff0c\u7528\u4e8e\u5728\u5b9e\u9645\u5e94\u7528\u4e2d\u63d0\u9ad8\u7b97\u6cd5\u7684\u6548\u7387\u3002 \u4e3a\u4ec0\u4e48\u5f52\u5e76\u6392\u5e8f\u5728\u6700\u574f\u60c5\u51b5\u4e0b\u4e5f\u662f\u4e00\u4e2a O(n log n) \u7b97\u6cd5\uff1f \u89e3\u7b54\uff1a\u5f52\u5e76\u6392\u5e8f\u5728\u6700\u574f\u60c5\u51b5\u4e0b\u4ecd\u7136\u5177\u6709 O(n log n) \u7684\u65f6\u95f4\u590d\u6742\u5ea6\uff0c\u8fd9\u662f\u56e0\u4e3a\u5f52\u5e76\u6392\u5e8f\u7684\u7b97\u6cd5\u8bbe\u8ba1\u4f7f\u5176\u80fd\u591f\u7a33\u5b9a\u5730\u4fdd\u6301\u8fd9\u79cd\u6027\u80fd\uff0c\u4e0d\u53d7\u8f93\u5165\u6570\u636e\u5206\u5e03\u7684\u5f71\u54cd\u3002 \u4ee5\u4e0b\u662f\u5f52\u5e76\u6392\u5e8f\u5728\u6700\u574f\u60c5\u51b5\u4e0b\u4ecd\u7136\u5177\u6709 O(n log n) \u65f6\u95f4\u590d\u6742\u5ea6\u7684\u539f\u56e0\uff1a \u5206\u800c\u6cbb\u4e4b\u7b56\u7565\uff1a\u5f52\u5e76\u6392\u5e8f\u91c7\u7528\u4e86\u5206\u800c\u6cbb\u4e4b\u7684\u7b56\u7565\uff0c\u5c06\u95ee\u9898\u5206\u89e3\u4e3a\u8f83\u5c0f\u7684\u5b50\u95ee\u9898\uff0c\u7136\u540e\u5408\u5e76\u8fd9\u4e9b\u5b50\u95ee\u9898\u7684\u89e3\u3002\u8fd9\u4e2a\u7b56\u7565\u786e\u4fdd\u4e86\u7b97\u6cd5\u7684\u9012\u5f52\u6df1\u5ea6\u5728 log n \u7ea7\u522b\uff0c\u56e0\u4e3a\u6bcf\u6b21\u9012\u5f52\u90fd\u5c06\u6570\u636e\u5212\u5206\u6210\u4e24\u534a\uff0c\u76f4\u5230\u6700\u5c0f\u5b50\u95ee\u9898\u7684\u5927\u5c0f\u4e3a1\u3002 \u5408\u5e76\u64cd\u4f5c\u7684\u7ebf\u6027\u65f6\u95f4\uff1a\u5f52\u5e76\u6392\u5e8f\u7684\u5173\u952e\u64cd\u4f5c\u662f\u5408\u5e76\u5df2\u6392\u5e8f\u7684\u5b50\u6570\u7ec4\u3002\u5408\u5e76\u64cd\u4f5c\u7684\u65f6\u95f4\u590d\u6742\u5ea6\u662f\u7ebf\u6027\u7684\uff0c\u4e0e\u8f93\u5165\u6570\u636e\u7684\u89c4\u6a21 n \u6210\u6b63\u6bd4\u3002\u56e0\u6b64\uff0c\u5373\u4f7f\u5728\u5408\u5e76\u9636\u6bb5\uff0c\u7b97\u6cd5\u7684\u603b\u65f6\u95f4\u590d\u6742\u5ea6\u4ecd\u7136\u53d7\u9650\u4e8e O(n log n) \u3002 \u7a33\u5b9a\u6027\uff1a\u5f52\u5e76\u6392\u5e8f\u662f\u4e00\u79cd\u7a33\u5b9a\u6392\u5e8f\u7b97\u6cd5\uff0c\u610f\u5473\u7740\u5b83\u5728\u6392\u5e8f\u76f8\u7b49\u5143\u7d20\u65f6\u4f1a\u4fdd\u6301\u5b83\u4eec\u7684\u76f8\u5bf9\u987a\u5e8f\u3002\u8fd9\u4e00\u6027\u8d28\u4f7f\u5f97\u7b97\u6cd5\u5728\u5904\u7406\u76f8\u7b49\u5143\u7d20\u6216\u8005\u5177\u6709\u7279\u5b9a\u6570\u636e\u5206\u5e03\u7684\u60c5\u51b5\u4e0b\u4ecd\u7136\u4fdd\u6301 O(n log n) \u7684\u6027\u80fd\uff0c\u800c\u4e0d\u4f1a\u51fa\u73b0\u6700\u574f\u60c5\u51b5\u3002 \u65e0\u8bba\u8f93\u5165\u6570\u636e\u5982\u4f55\u5206\u5e03\uff0c\u5f52\u5e76\u6392\u5e8f\u7684\u5206\u5272\u548c\u5408\u5e76\u64cd\u4f5c\u90fd\u662f\u786e\u5b9a\u6027\u7684\uff1a\u5f52\u5e76\u6392\u5e8f\u7684\u6bcf\u4e00\u6b65\u90fd\u662f\u786e\u5b9a\u6027\u7684\uff0c\u4e0d\u53d7\u8f93\u5165\u6570\u636e\u5206\u5e03\u7684\u5f71\u54cd\u3002\u4e0d\u50cf\u5feb\u901f\u6392\u5e8f\u5728\u6700\u574f\u60c5\u51b5\u4e0b\u53ef\u80fd\u51fa\u73b0\u5206\u5272\u6781\u4e0d\u5e73\u8861\u7684\u60c5\u51b5\uff0c\u5bfc\u81f4\u6027\u80fd\u4e0b\u964d\u3002 \u56e0\u6b64\uff0c\u5f52\u5e76\u6392\u5e8f\u5728\u6700\u574f\u60c5\u51b5\u4e0b\u4ecd\u7136\u80fd\u591f\u4fdd\u6301 O(n log n) \u7684\u65f6\u95f4\u590d\u6742\u5ea6\uff0c\u4f7f\u5176\u6210\u4e3a\u4e00\u79cd\u53ef\u9760\u7684\u6392\u5e8f\u7b97\u6cd5\uff0c\u7279\u522b\u9002\u7528\u4e8e\u5bf9\u7a33\u5b9a\u6027\u548c\u6027\u80fd\u6709\u8981\u6c42\u7684\u60c5\u51b5\u3002","title":"3.5.3.\u7ec3\u4e60\u9898"},{"location":"python/DataStructure/03_TimeComplexity/#36","text":"","title":"3.6.\u6307\u6570\u590d\u6742\u5ea6\u7684\u7b97\u6cd5"},{"location":"python/DataStructure/03_TimeComplexity/#_1","text":"\u4e0b\u9762\u662f\u6590\u6ce2\u90a3\u5951\u9012\u5f52\u7b97\u6cd5\u7684\u4f8b\u5b50\u3002 def fib ( n , depth = 0 ): \"\"\"\u6590\u6ce2\u90a3\u5951\u9012\u5f52\u6570\u5217\"\"\" if n <= 1 : return 1 else : print ( f 'Depth: { depth } ,fib( { n } ) calls fib( { n - 1 } ) and fib( { n - 2 } )' ) return fib ( n - 1 , depth + 1 ) + fib ( n - 2 , depth + 1 ) def main (): fib ( 6 ) if __name__ == \"__main__\" : main () # \u8fd0\u884c\u7ed3\u679c\uff1a # Depth:0,fib(6) calls fib(5) and fib(4) # Depth:1,fib(5) calls fib(4) and fib(3) # Depth:2,fib(4) calls fib(3) and fib(2) # Depth:3,fib(3) calls fib(2) and fib(1) # Depth:4,fib(2) calls fib(1) and fib(0) # Depth:3,fib(2) calls fib(1) and fib(0) # Depth:2,fib(3) calls fib(2) and fib(1) # Depth:3,fib(2) calls fib(1) and fib(0) # Depth:1,fib(4) calls fib(3) and fib(2) # Depth:2,fib(3) calls fib(2) and fib(1) # Depth:3,fib(2) calls fib(1) and fib(0) # Depth:2,fib(2) calls fib(1) and fib(0) \u4e0a\u4f8b\u53ef\u4ee5\u770b\u51fa\uff0c\u6590\u6ce2\u90a3\u5951\u9012\u5f52\u7b97\u6cd5\u7684\u8c03\u7528\u6b21\u6570\u6bd4\u95ee\u9898\u89c4\u6a21\u7684\u5e73\u65b9\u6570\u589e\u957f\u7684\u8fd8\u8981\u5feb\u5f88\u591a\u3002\u4f8b\u5982\uff0c fib(4) \u53ea\u9700\u89814\u6b21\u9012\u5f52\u8c03\u7528\uff0c\u770b\u8d77\u6765\u5b83\u597d\u50cf\u662f\u7ebf\u6027\u589e\u957f\u7684\uff0c\u4f46\u5728\u603b\u5171\u768414\u6b21\u9012\u5f52\u8c03\u7528\u91cc\uff0c fib(6) \u9700\u8981\u8c03\u75282\u6b21 fib(4) \u3002\u968f\u7740\u95ee\u9898\u89c4\u6a21\u7684\u6269\u5927\uff0c\u5de5\u4f5c\u91cf\u4f1a\u663e\u8457\u589e\u52a0\uff0c\u8fd9\u662f\u56e0\u4e3a\u5728\u8c03\u7528\u6811\uff08call tree\uff09\u91cc\u53ef\u80fd\u6709\u5f88\u591a\u91cd\u590d\u7684\u76f8\u540c\u5b50\u6811\u3002 \u5982\u679c\u8fd9\u68f5\u8c03\u7528\u6811\u662f\u5b8c\u5168\u5e73\u8861\u7684\uff0c\u5e76\u4e14\u5b8c\u5168\u586b\u5145\u4e86\u6700\u4e0b\u9762\u7684\u4e24\u5c42\u8c03\u7528\uff0c\u90a3\u4e48\u5f53\u53c2\u6570\u4e3a6\u65f6\uff0c\u4f1a\u67092 + 4 + 8 + 16 = 30\u6b21\u9012\u5f52\u8c03\u7528\u3002\u6bcf\u4e00\u5c42\u91cc\u7684\u6ee1\u8c03\u7528\u6570\u91cf\u90fd\u662f\u5b83\u4e0a\u4e00\u5c42\u76842\u500d\u3002\u56e0\u6b64\uff0c\u5728\u5b8c\u5168\u5e73\u8861\u7684\u8c03\u7528\u6811\u91cc\uff0c\u9012\u5f52\u8c03\u7528\u7684\u603b\u6570\u91cf\u901a\u5e38\u662f 2^(n+1)-2 \uff0c\u5176\u4e2d n \u662f\u8c03\u7528\u6811\u9876\u90e8\uff08\u6839\uff09\u7684\u53c2\u6570\u3002\u8fd9\u662f\u4e00\u4e2a\u6307\u6570\u7ea7\u7684\u589e\u957f\uff0c\u4e5f\u5c31\u662f O(k^n) \u7b97\u6cd5\u3002 \u5c3d\u7ba1\u5728\u9012\u5f52\u6590\u6ce2\u90a3\u5951\u8c03\u7528\u6811\u7684\u5e95\u90e8\u4e24\u5c42\u5e76\u6ca1\u6709\u88ab\u5b8c\u5168\u586b\u5145\u6ee1\uff0c\u4f46\u5b83\u7684\u8c03\u7528\u6811\u5f62\u72b6\u548c\u5b8c\u5168\u5e73\u8861\u7684\u6811\u5df2\u7ecf\u8db3\u591f\u76f8\u8fd1\u4e86\uff0c\u56e0\u6b64\uff0c\u53ef\u4ee5\u628a\u9012\u5f52\u6590\u6ce2\u90a3\u5951\u5f52\u4e3a\u6307\u6570\u7b97\u6cd5\u3002\u7ecf\u8fc7\u8ba1\u7b97\uff0c\u9012\u5f52\u6590\u6ce2\u90a3\u5951\u7684\u5e38\u6570 k \u5927\u7ea6\u662f1.63\u3002 \u6307\u6570\u7b97\u6cd5\u901a\u5e38\u53ea\u9002\u5408\u7528\u4e8e\u975e\u5e38\u5c0f\u7684\u95ee\u9898\u89c4\u6a21\u3002","title":"\u6590\u6ce2\u90a3\u5951\u9012\u5f52\u7b97\u6cd5"},{"location":"python/DataStructure/03_TimeComplexity/#_2","text":"\u4e0b\u9762\u7684\u4ee3\u7801\u7528\u7ebf\u6027\u7b97\u6cd5\u6539\u5199\u4e86\u4e0a\u9762\u7684\u9012\u5f52\u7b97\u6cd5\u3002\u5b83\u7684\u65f6\u95f4\u590d\u6742\u5ea6\u662fO(n)\u3002 def fibonacci_linear ( n ): if n <= 1 : return 1 prev , current = 0 , 1 for _ in range ( 2 , n + 1 ): next_value = prev + current prev , current = current , next_value return current def main (): n = 6 result = fibonacci_linear ( n ) print ( f \"Fibonacci( { n } ) = { result } \" ) if __name__ == \"__main__\" : main () # \u8fd0\u884c\u7ed3\u679c\uff1a # Fibonacci(6) = 8","title":"\u5c06\u6590\u6ce2\u90a3\u5951\u8f6c\u6362\u4e3a\u7ebf\u6027\u7b97\u6cd5"},{"location":"python/DataStructure/03_TimeComplexity/#37","text":"\u76ee\u6807\uff1a\u7f16\u5199\u4e00\u4e2a\u53ef\u4ee5\u7528\u6765\u5206\u6790\u4e0d\u540c\u6392\u5e8f\u7b97\u6cd5\u7684\u7a0b\u5e8f\u3002 \u9700\u6c42\uff1a \u5206\u6790\u5668\u53ef\u4ee5\u8fd0\u884c\u6392\u5e8f\u7b97\u6cd5\u4ee5\u5bf9\u6570\u5b57\u5217\u8868\u8fdb\u884c\u6392\u5e8f\uff1b \u5206\u6790\u5668\u53ef\u4ee5\u8ffd\u8e2a\u7b97\u6cd5\u7684\u8fd0\u884c\u65f6\u3001\u6bd4\u8f83\u6b21\u6570\u4ee5\u53ca\u6267\u884c\u4ea4\u6362\u7684\u6b21\u6570\uff1b \u5f53\u7b97\u6cd5\u4ea4\u6362\u4e24\u4e2a\u503c\u7684\u65f6\u5019\uff0c\u5206\u6790\u5668\u53ef\u4ee5\u6253\u5370\u51fa\u5217\u8868\u7684\u53d8\u5316\u8f68\u8ff9\uff1b \u5141\u8bb8\u7ed9\u5206\u6790\u5668\u63d0\u4f9b\u81ea\u5b9a\u4e49\u7684\u6570\u5b57\u5217\u8868\uff0c\u6216\u8005\u751f\u6210\u4e00\u4e2a\u5927\u5c0f\u7ed9\u5b9a\u7684\u968f\u673a\u6570\u5b57\u5217\u8868\uff1b\u5141\u8bb8\u5217\u8868\u53ea\u5305\u542b\u4e00\u4e2a\u6570\u5b57\uff0c\u6216\u8005\u5305\u542b\u91cd\u590d\u6570\u503c\uff1b \u5728\u8fd0\u884c\u7b97\u6cd5\u4e4b\u524d\uff0c\u5141\u8bb8\u7528\u6237\u9009\u62e9\u4e0a\u8ff0\u8fd9\u4e9b\u529f\u80fd\uff1b \u5206\u6790\u5668\u7684\u9ed8\u8ba4\u884c\u4e3a\u662f\u5728\u4e00\u4e2a\u5305\u542b10\u4e2a\u4e0d\u91cd\u590d\u6570\u5b57\u7684\u968f\u673a\u5217\u8868\u4e0a\u8fd0\u884c\u7b97\u6cd5\uff0c\u5e76\u8bb0\u5f55\u7b97\u6cd5\u7684\u8fd0\u884c\u65f6\u3001\u6bd4\u8f83\u6b21\u6570\u4ee5\u53ca\u4ea4\u6362\u6b21\u6570\uff1b \u5b9e\u73b0\uff1a \u5206\u6790\u5668\u662f Profiler \u7c7b\u7684\u4e00\u4e2a\u5b9e\u4f8b\u3002\u6211\u4eec\u53ef\u4ee5\u901a\u8fc7\u8fd0\u884c\u5206\u6790\u5668\u91cc\u7684 test \u65b9\u6cd5\u6765\u5206\u6790\u6392\u5e8f\u51fd\u6570\uff0c\u8fd9\u4e2a\u6392\u5e8f\u51fd\u6570\u4f1a\u4f5c\u4e3a\u65b9\u6cd5\u7684\u7b2c\u4e00\u4e2a\u53c2\u6570\uff0c\u4e0a\u9762\u9700\u6c42\u4e2d\u63d0\u5230\u7684\u90a3\u4e9b\u9009\u9879\u4e5f\u4f1a\u4f5c\u4e3a\u53c2\u6570\u540c\u65f6\u4f20\u9012\u7ed9\u8fd9\u4e2a\u65b9\u6cd5\u3002 \u4e24\u4e2a\u6a21\u5757\uff1a profiler \uff1a\u8fd9\u4e2a\u6a21\u5757\u4f1a\u5b9a\u4e49 Profiler \u7c7b\u3002 algorithms \uff1a\u8fd9\u4e2a\u6a21\u5757\u5b9a\u4e49\u9488\u5bf9\u5206\u6790\u5668\u4fee\u6539\u8fc7\u7684\u6392\u5e8f\u51fd\u6570\u3002 import time import random class Profiler ( object ): \"\"\" \u5b9a\u4e49\u4e00\u4e2aProfiler\u7c7b, \u7528\u6765\u5206\u6790\u6392\u5e8f\u7b97\u6cd5\u3002 Profiler\u5bf9\u8c61\u8ddf\u8e2a\u4e00\u4e2a\u5217\u8868\u7684\u6bd4\u8f83\u6b21\u6570\u3001\u4ea4\u6362\u6b21\u6570\u3001\u548c\u8fd0\u884c\u65f6\u95f4\u3002 Profiler\u5bf9\u8c61\u4e5f\u80fd\u8f93\u51fa\u4e0a\u8ff0\u8ffd\u8e2a\u4fe1\u606f, \u5e76\u521b\u5efa\u4e00\u4e2a\u542b\u6709\u91cd\u590d\u6216\u4e0d\u91cd\u590d\u6570\u5b57\u7684\u5217\u8868\u3002 \u793a\u4f8b\uff1a from profiler import Profiler from algorithms import selectionSort p = Profiler() p.test(selectionSort, size = 15, comp = True, exch = True, trace = True) \"\"\" def test ( self , function , lyst = None , size = 10 , unique = True , comp = True , exch = True , trace = False ): \"\"\" function: \u914d\u7f6e\u7684\u7b97\u6cd5 target: \u914d\u7f6e\u7684\u641c\u7d22\u76ee\u6807 lyst: \u5141\u8bb8\u8c03\u7528\u8005\u4f7f\u7528\u7684\u5217\u8868 size: \u5217\u8868\u7684\u5927\u5c0f, \u9ed8\u8ba4\u503c\u662f10 unique: \u5982\u679c\u662fTrue, \u5219\u5217\u8868\u5305\u542b\u4e0d\u91cd\u590d\u7684\u6574\u6570 comp: \u5982\u679c\u662fTrue, \u5219\u7edf\u8ba1\u6bd4\u8f83\u6b21\u6570 exch: \u5982\u679c\u662fTrue, \u5219\u7edf\u8ba1\u4ea4\u6362\u6b21\u6570 trace: \u5982\u679c\u662fTrue, \u5219\u5728\u6bcf\u6b21\u4ea4\u6362\u540e\u90fd\u8f93\u51fa\u5217\u8868\u5185\u5bb9 \u6b64\u51fd\u6570\u4f9d\u636e\u7ed9\u5b9a\u7684\u4e0a\u8ff0\u5c5e\u6027, \u6253\u5370\u8f93\u51fa\u76f8\u5e94\u7684\u7ed3\u679c \"\"\" self . comp = comp self . exch = exch self . trace = trace if lyst != None : self . lyst = lyst elif unique : self . lyst = list ( range ( 1 , size + 1 )) random . shuffle ( self . lyst ) else : self . lyst = [] for count in range ( size ): self . lyst . append ( random . randint ( 1 , size )) self . exchCount = 0 self . cmpCount = 0 self . startClock () function ( self . lyst , self ) self . stopClock () print ( self ) def exchange ( self ): \"\"\"\u7edf\u8ba1\u4ea4\u6362\u6b21\u6570\"\"\" if self . exch : self . exchCount += 1 if self . trace : print ( self . lyst ) def comparison ( self ): \"\"\"\u7edf\u8ba1\u4ea4\u6362\u6b21\u6570\"\"\" if self . comp : self . cmpCount += 1 def startClock ( self ): \"\"\"\u8bb0\u5f55\u5f00\u59cb\u65f6\u95f4\"\"\" self . start = time . time () def stopClock ( self ): \"\"\"\u505c\u6b62\u8ba1\u65f6\u5e76\u4ee5\u79d2\u4e3a\u5355\u4f4d\u8ba1\u7b97\u6d88\u8017\u65f6\u95f4\"\"\" self . elapsedTime = round ( time . time () - self . start , 3 ) def __str__ ( self ): \"\"\"\u4ee5\u5b57\u7b26\u4e32\u65b9\u5f0f\u8fd4\u56de\u7ed3\u679c\"\"\" result = \"Problem size: \" result += str ( len ( self . lyst )) + \" \\n \" result += \"Elapsed time: \" result += str ( self . elapsedTime ) + \" \\n \" if self . comp : result += \"Comparisons: \" result += str ( self . cmpCount ) + \" \\n \" if self . exch : result += \"Exchanges: \" result += str ( self . exchCount ) + \" \\n \" return result def selectionSort ( lyst , profiler ): i = 0 while i < len ( lyst ) - 1 : minIndex = i j = i + 1 while j < len ( lyst ): profiler . comparison () # Count if lyst [ j ] < lyst [ minIndex ]: minIndex = j j += 1 if minIndex != i : swap ( lyst , minIndex , i , profiler ) i += 1 def swap ( lyst , i , j , profiler ): \"\"\"\u4ea4\u6362\u5904\u4e8e\u4f4d\u7f6ei\u548cj\u7684\u5143\u7d20\"\"\" profiler . exchange () # Count temp = lyst [ i ] lyst [ i ] = lyst [ j ] lyst [ j ] = temp def main (): p = Profiler () # \u9ed8\u8ba4\u884c\u4e3a print ( \"The result of p.test(selectionSort)\" ) p . test ( selectionSort ) print ( \"The result of p.test(selectionSort, size=5, trace=True)\" ) p . test ( selectionSort , size = 5 , trace = True ) print ( \"The result of p.test(selectionSort, size=100)\" ) p . test ( selectionSort , size = 100 ) print ( \"The result of p.test(selectionSort, size=1000)\" ) p . test ( selectionSort , size = 1000 ) print ( \"The result of p.test(selectionSort, size=10000, exch=False, comp=False)\" ) p . test ( selectionSort , size = 10000 , exch = False , comp = False ) if __name__ == \"__main__\" : main () # \u8fd0\u884c\u7ed3\u679c\uff1a # The result of p.test(selectionSort) # Problem size: 20 # Elapsed time: 0.0 # Comparisons: 190 # Exchanges: 12 # The result of p.test(selectionSort, size=5, trace=True) # [5, 1, 4, 3, 2, 1, 1, 2, 4, 4] # [1, 5, 4, 3, 2, 1, 1, 2, 4, 4] # [1, 1, 4, 3, 2, 5, 1, 2, 4, 4] # [1, 1, 1, 3, 2, 5, 4, 2, 4, 4] # [1, 1, 1, 2, 3, 5, 4, 2, 4, 4] # [1, 1, 1, 2, 2, 5, 4, 3, 4, 4] # [1, 1, 1, 2, 2, 3, 4, 5, 4, 4] # [1, 1, 1, 2, 2, 3, 4, 4, 5, 4] # Problem size: 10 # Elapsed time: 0.0 # Comparisons: 45 # Exchanges: 8 # The result of p.test(selectionSort, size=100) # Problem size: 200 # Elapsed time: 0.003 # Comparisons: 19900 # Exchanges: 195 # The result of p.test(selectionSort, size=1000) # Problem size: 2000 # Elapsed time: 0.36 # Comparisons: 1999000 # Exchanges: 1992 # The result of p.test(selectionSort, size=10000, exch=False, comp=False) # Problem size: 20000 # Elapsed time: 26.535","title":"3.7.\u6848\u4f8b\u7814\u7a76:\u7b97\u6cd5\u5206\u6790\u5668"},{"location":"python/DataStructure/03_TimeComplexity/#38","text":"\u6839\u636e\u6240\u9700\u8981\u7684\u65f6\u95f4\u548c\u5185\u5b58\u8d44\u6e90\uff0c\u6211\u4eec\u53ef\u4ee5\u5bf9\u89e3\u51b3\u540c\u4e00\u4e2a\u95ee\u9898\u7684\u4e0d\u540c\u7b97\u6cd5\u8fdb\u884c\u6392\u540d\u3002\u4e0e\u9700\u8981\u66f4\u591a\u8d44\u6e90\u7684\u7b97\u6cd5\u76f8\u6bd4\uff0c\u6211\u4eec\u901a\u5e38\u8ba4\u4e3a\u8017\u8d39\u66f4\u5c11\u8fd0\u884c\u65f6\u548c\u5360\u7528\u66f4\u5c11\u5185\u5b58\u7684\u7b97\u6cd5\u66f4\u597d\u3002\u4f46\u662f\uff0c\u8fd9\u4e24\u79cd\u8d44\u6e90\u4e5f\u901a\u5e38\u9700\u8981\u8fdb\u884c\u6743\u8861\u53d6\u820d\uff1a\u6709\u65f6\u4ee5\u66f4\u591a\u5185\u5b58\u4e3a\u4ee3\u4ef7\u6765\u6539\u5584\u8fd0\u884c\u65f6\uff1b\u6709\u65f6\u4ee5\u8f83\u6162\u7684\u8fd0\u884c\u65f6\u4f5c\u4e3a\u4ee3\u4ef7\u6765\u63d0\u9ad8\u5185\u5b58\u7684\u4f7f\u7528\u7387\u3002 \u53ef\u4ee5\u6839\u636e\u8ba1\u7b97\u673a\u7684\u65f6\u949f\u6309\u7167\u8fc7\u5f80\u7ecf\u9a8c\u6d4b\u7b97\u7b97\u6cd5\u7684\u8fd0\u884c\u65f6\u3002\u4f46\u662f\uff0c\u8fd9\u4e2a\u65f6\u95f4\u4f1a\u968f\u7740\u786c\u4ef6\u548c\u6240\u7528\u7f16\u7a0b\u8bed\u8a00\u7684\u4e0d\u540c\u800c\u53d8\u5316\u3002 \u7edf\u8ba1\u6307\u4ee4\u7684\u6570\u91cf\u63d0\u4f9b\u4e86\u53e6\u4e00\u79cd\u5bf9\u7b97\u6cd5\u6240\u9700\u5de5\u4f5c\u91cf\u8fdb\u884c\u7ecf\u9a8c\u6027\u5ea6\u91cf\u7684\u65b9\u5f0f\u3002\u6307\u4ee4\u7684\u8ba1\u6570\u53ef\u4ee5\u663e\u793a\u51fa\u7b97\u6cd5\u5de5\u4f5c\u91cf\u7684\u589e\u957f\u7387\u7684\u53d8\u5316\uff0c\u800c\u4e14\u8fd9\u4e2a\u6570\u636e\u548c\u786c\u4ef6\u4ee5\u53ca\u8f6f\u4ef6\u5e73\u53f0\u90fd\u6ca1\u6709\u5173\u7cfb\u3002 \u7b97\u6cd5\u5de5\u4f5c\u91cf\u7684\u589e\u957f\u7387\u53ef\u4ee5\u7528\u57fa\u4e8e\u95ee\u9898\u89c4\u6a21\u7684\u51fd\u6570\u6765\u8868\u793a\u3002\u590d\u6742\u5ea6\u5206\u6790\u67e5\u770b\u7b97\u6cd5\u91cc\u7684\u4ee3\u7801\u4ee5\u5f97\u5230\u8fd9\u4e9b\u6570\u5b66\u8868\u8fbe\u5f0f\uff0c\u4ece\u800c\u8ba9\u7a0b\u5e8f\u5458\u9884\u6d4b\u5728\u4efb\u4f55\u8ba1\u7b97\u673a\u4e0a\u6267\u884c\u8fd9\u4e2a\u7b97\u6cd5\u7684\u6548\u679c\u3002 \u5927O\u8868\u793a\u6cd5\u662f\u7528\u6765\u8868\u793a\u7b97\u6cd5\u8fd0\u884c\u65f6\u884c\u4e3a\u7684\u5e38\u7528\u65b9\u6cd5\u3002\u5b83\u7528 O(f(n)) \u7684\u5f62\u5f0f\u6765\u8868\u793a\u89e3\u51b3\u8fd9\u4e2a\u95ee\u9898\u6240\u9700\u8981\u7684\u5de5\u4f5c\u91cf\uff0c\u5176\u4e2d n \u662f\u7b97\u6cd5\u95ee\u9898\u7684\u89c4\u6a21\u3001 f(n) \u662f\u6570\u5b66\u51fd\u6570\u3002 \u8fd0\u884c\u65f6\u884c\u4e3a\u7684\u5e38\u89c1\u8868\u8fbe\u5f0f\u6709 O(log(n, 2)) \uff08\u5bf9\u6570\uff09\u3001 O(n) \uff08\u7ebf\u6027\uff09\u3001 O(n^2) \uff08\u5e73\u65b9\uff09\u4ee5\u53ca O(k^n) \uff08\u6307\u6570\uff09\u3002 \u7b97\u6cd5\u5728\u6700\u597d\u60c5\u51b5\u3001\u6700\u574f\u60c5\u51b5\u4ee5\u53ca\u5e73\u5747\u60c5\u51b5\u4e0b\u7684\u6027\u80fd\u53ef\u4ee5\u662f\u4e0d\u540c\u7684\u3002\u6bd4\u5982\uff0c\u5192\u6ce1\u6392\u5e8f\u548c\u63d2\u5165\u6392\u5e8f\u5728\u6700\u597d\u60c5\u51b5\u4e0b\u90fd\u662f\u7ebf\u6027\u590d\u6742\u5ea6\uff0c\u4f46\u662f\u5b83\u4eec\u5728\u5e73\u5747\u60c5\u51b5\u548c\u6700\u574f\u60c5\u51b5\u4e0b\u662f\u5e73\u65b9\u9636\u590d\u6742\u5ea6\u3002 \u901a\u5e38\u6765\u8bf4\uff0c\u8981\u63d0\u9ad8\u7b97\u6cd5\u7684\u6027\u80fd\u6700\u597d\u662f\u5c1d\u8bd5\u964d\u4f4e\u5b83\u7684\u8fd0\u884c\u65f6\u590d\u6742\u5ea6\u7684\u9636\u6570\uff0c\u800c\u4e0d\u662f\u5bf9\u4ee3\u7801\u8fdb\u884c\u5fae\u8c03\u3002 \u4e8c\u5206\u641c\u7d22\u4f1a\u6bd4\u987a\u5e8f\u641c\u7d22\u8981\u5feb\u5f97\u591a\u3002\u4f46\u662f\uff0c\u5728\u7528\u4e8c\u5206\u641c\u7d22\u8fdb\u884c\u641c\u7d22\u65f6\uff0c\u6570\u636e\u5fc5\u987b\u662f\u6709\u5e8f\u7684\u3002 nlogn \u6392\u5e8f\u7b97\u6cd5\u901a\u8fc7\u9012\u5f52\u3001\u5206\u6cbb\u6cd5\u7b56\u7565\u6765\u7a81\u7834 n^2 \u7684\u6027\u80fd\u969c\u788d\u3002\u5feb\u901f\u6392\u5e8f\u4f1a\u5728\u57fa\u51c6\u5143\u7d20\u5de6\u53f3\u5bf9\u5176\u4ed6\u5143\u7d20\u91cd\u65b0\u6392\u5217\uff0c\u7136\u540e\u5bf9\u57fa\u51c6\u4e24\u4fa7\u7684\u5b50\u5217\u8868\u9012\u5f52\u5730\u6392\u5e8f\u3002\u5f52\u5e76\u6392\u5e8f\u5219\u4f1a\u628a\u4e00\u4e2a\u5217\u8868\u8fdb\u884c\u62c6\u5206\uff0c\u9012\u5f52\u5730\u5bf9\u6bcf\u4e2a\u90e8\u5206\u8fdb\u884c\u6392\u5e8f\uff0c\u7136\u540e\u5408\u5e76\u51fa\u6700\u7ec8\u7ed3\u679c\u3002 \u6307\u6570\u590d\u6742\u5ea6\u7684\u7b97\u6cd5\u901a\u5e38\u53ea\u5728\u7406\u8bba\u4e0a\u88ab\u5173\u6ce8\uff0c\u5728\u5904\u7406\u5927\u578b\u95ee\u9898\u7684\u65f6\u5019\uff0c\u5b83\u4eec\u662f\u6ca1\u6709\u4f7f\u7528\u4ef7\u503c\u7684\u3002","title":"3.8.\u5c0f\u7ed3"},{"location":"python/DataStructure/03_TimeComplexity/#39","text":"\u5728\u4e0d\u540c\u95ee\u9898\u89c4\u6a21\u7684\u60c5\u51b5\u4e0b\u8bb0\u5f55\u7b97\u6cd5\u8fd0\u884c\u65f6\uff1a \u53ef\u4ee5\u8ba9\u4f60\u5927\u81f4\u4e86\u89e3\u7b97\u6cd5\u7684\u8fd0\u884c\u65f6\u884c\u4e3a \u53ef\u4ee5\u8ba9\u4f60\u4e86\u89e3\u7b97\u6cd5\u5728\u7279\u5b9a\u786c\u4ef6\u5e73\u53f0\u548c\u7279\u5b9a\u8f6f\u4ef6\u5e73\u53f0\u4e0a\u7684\u8fd0\u884c\u65f6\u884c\u4e3a \u7edf\u8ba1\u6307\u4ee4\u7684\u6570\u91cf\u4f1a\uff1a \u5728\u4e0d\u540c\u7684\u786c\u4ef6\u548c\u8f6f\u4ef6\u5e73\u53f0\u4e0a\u5f97\u5230\u76f8\u540c\u7684\u6570\u636e \u53ef\u4ee5\u8bc1\u660e\u5728\u95ee\u9898\u89c4\u6a21\u5f88\u5927\u7684\u60c5\u51b5\u4e0b\uff0c\u6307\u6570\u7b97\u6cd5\u662f\u6ca1\u6cd5\u4f7f\u7528\u7684 \u8868\u8fbe\u5f0f O(n) \u3001 O(n^2) \u548c O(k^n) \u5206\u522b\u4ee3\u8868\u7684\u590d\u6742\u5ea6\u662f\uff1a \u6307\u6570\u3001\u7ebf\u6027\u548c\u5e73\u65b9 \u7ebf\u6027\u3001\u5e73\u65b9\u548c\u6307\u6570 \u5bf9\u6570\u3001\u7ebf\u6027\u548c\u5e73\u65b9 \u4e8c\u5206\u641c\u7d22\u9700\u8981\u5047\u5b9a\u6570\u636e\uff1a \u6ca1\u6709\u4efb\u4f55\u7279\u522b\u7684\u987a\u5e8f\u5173\u7cfb \u6709\u5e8f\u7684 \u9009\u62e9\u6392\u5e8f\u6700\u591a\u53ef\u4ee5\u6709\uff1a n^2 \u6b21\u6570\u636e\u5143\u7d20\u7684\u4ea4\u6362 n \u6b21\u6570\u636e\u5143\u7d20\u7684\u4ea4\u6362 \u63d2\u5165\u6392\u5e8f\u548c\u4fee\u6539\u540e\u7684\u5192\u6ce1\u6392\u5e8f\u5728\u6700\u597d\u60c5\u51b5\u4e0b\u662f\uff1a \u7ebf\u6027\u7684 \u5e73\u65b9\u7684 \u6307\u6570\u7684 \u6700\u597d\u60c5\u51b5\u3001\u5e73\u5747\u60c5\u51b5\u4ee5\u53ca\u6700\u574f\u60c5\u51b5\u4e0b\u590d\u6742\u5ea6\u90fd\u76f8\u540c\u7684\u7b97\u6cd5\u662f\uff1a \u987a\u5e8f\u641c\u7d22 \u9009\u62e9\u6392\u5e8f \u5feb\u901f\u6392\u5e8f \u4e00\u822c\u6765\u8bf4\uff0c\u4e0b\u9762\u54ea\u4e2a\u9009\u62e9\u66f4\u597d\uff1a \u8c03\u6574\u7b97\u6cd5\u4ece\u800c\u8282\u7701\u82e5\u5e72\u79d2\u7684\u8fd0\u884c\u65f6 \u9009\u62e9\u8ba1\u7b97\u590d\u6742\u5ea6\u66f4\u4f4e\u7684\u7b97\u6cd5 \u5bf9\u4e8e\u9012\u5f52\u6590\u6ce2\u90a3\u5951\u51fd\u6570\uff1a \u95ee\u9898\u89c4\u6a21\u4e3a n \u7684\u65f6\u5019\uff0c\u6709 n^2 \u6b21\u9012\u5f52\u8c03\u7528 \u95ee\u9898\u89c4\u6a21\u4e3a n \u7684\u65f6\u5019\uff0c\u6709 2n \u6b21\u9012\u5f52\u8c03\u7528 \u5b8c\u5168\u586b\u5145\u7684\u4e8c\u53c9\u8c03\u7528\u6811\u91cc\u6bcf\u4e00\u5c42\uff1a \u8c03\u7528\u6b21\u6570\u662f\u4e0a\u4e00\u5c42\u8c03\u7528\u6b21\u6570\u76842\u500d \u4e0e\u4e0a\u4e00\u5c42\u76f8\u540c\u7684\u8c03\u7528\u6b21\u6570","title":"3.9.\u590d\u4e60\u9898"},{"location":"python/DataStructure/03_TimeComplexity/#310","text":"1\uff0e\u5bf9\u4e00\u4e2a\u6709\u5e8f\u5217\u8868\u8fdb\u884c\u987a\u5e8f\u641c\u7d22\uff0c\u5f53\u76ee\u6807\u5c0f\u4e8e\u6709\u5e8f\u5217\u8868\u91cc\u7684\u67d0\u4e2a\u5143\u7d20\u65f6\uff0c\u987a\u5e8f\u641c\u7d22\u53ef\u4ee5\u63d0\u524d\u505c\u6b62\u3002\u5b9a\u4e49\u8fd9\u4e2a\u7b97\u6cd5\u7684\u4fee\u6539\u7248\u672c\uff0c\u5e76\u4f7f\u7528\u5927O\u8868\u793a\u6cd5\u6765\u63cf\u8ff0\u5b83\u5728\u6700\u597d\u60c5\u51b5\u3001\u6700\u574f\u60c5\u51b5\u4ee5\u53ca\u5e73\u5747\u60c5\u51b5\u4e0b\u7684\u8ba1\u7b97\u590d\u6742\u5ea6\u3002 \u89e3\u7b54\uff1a \u5728\u6700\u597d\u7684\u60c5\u51b5\u4e0b\uff0c\u76ee\u6807\u5143\u7d20\u5728\u6709\u5e8f\u5217\u8868\u7684\u7b2c\u4e00\u4e2a\u4f4d\u7f6e\u3002\u5728\u8fd9\u79cd\u60c5\u51b5\u4e0b\uff0c\u51fd\u6570\u53ea\u9700\u8981\u8fdb\u884c\u4e00\u6b21\u6bd4\u8f83\u3002\u6240\u4ee5\uff0c\u6700\u4f73\u60c5\u51b5\u590d\u6742\u5ea6\u4e3a O(1) \u3002 \u5728\u6700\u574f\u7684\u60c5\u51b5\u4e0b\uff0c\u76ee\u6807\u5143\u7d20\u4e0d\u5728\u5217\u8868\u4e2d\uff0c\u5e76\u4e14\u6240\u6709\u5217\u8868\u5143\u7d20\u90fd\u5c0f\u4e8e\u76ee\u6807\u5143\u7d20\u3002\u8fd9\u5c06\u5bfc\u81f4\u51fd\u6570\u904d\u5386\u6574\u4e2a\u5217\u8868\uff0c\u6240\u4ee5\u6700\u574f\u60c5\u51b5\u590d\u6742\u5ea6\u4e3a O(n) \u3002 \u5bf9\u4e8e\u5e73\u5747\u60c5\u51b5\uff0c\u5047\u8bbe\u6709 n \u4e2a\u9879\u5728\u5217\u8868\u4e2d\uff0c\u641c\u7d22\u76ee\u6807\u4f1a\u5728\u5217\u8868\u524d n/2 \u4e2a\u9879\u6216\u8005\u4e0d\u5728\u6240\u6709\u3002\u5728\u8fd9\u4e2a\u7ea6\u5b9a\u4e0b\uff0c\u5e73\u5747\u6211\u4eec\u9700\u8981\u5bfb\u627e n/2 \u4e2a\u9879\uff0c\u56e0\u6b64\u590d\u6742\u5ea6\u4e3a O(n) \u3002\u4e4b\u6240\u4ee5\u662f n/2 \uff0c\u662f\u56e0\u4e3a\u8fd9\u4e2a\u4efb\u52a1\u53ef\u80fd\u4f1a\u5728\u4efb\u4f55\u5730\u65b9\u88ab\u505c\u6b62\uff0c\u6211\u4eec\u5bf9\u6b64\u505a\u5e73\u5747\u5904\u7406\u3002\u7136\u800c\u5728\u5927O\u6807\u8bb0\u6cd5\u4e2d\uff0c\u5e38\u6570\u5c06\u88ab\u9057\u5fd8\uff0c\u6240\u4ee5\u5b83\u4ecd\u7136\u662f O(n) \u3002 \u4ee3\u7801\u5982\u4e0b\uff1a def ordered_sequential_search ( arr , target ): comparisons = 0 # \u7528\u4e8e\u7edf\u8ba1\u6bd4\u8f83\u6b21\u6570 index = 0 while index < len ( arr ): comparisons += 1 if arr [ index ] == target : return comparisons , index # \u627e\u5230\u76ee\u6807\u5e76\u8fd4\u56de\u6bd4\u8f83\u6b21\u6570\u548c\u7d22\u5f15 elif arr [ index ] > target : break # \u5982\u679c\u76ee\u6807\u5c0f\u4e8e\u5f53\u524d\u5143\u7d20\uff0c\u63d0\u524d\u505c\u6b62\u641c\u7d22 index += 1 return comparisons , - 1 # \u6ca1\u627e\u5230\u76ee\u6807\u8fd4\u56de\u6bd4\u8f83\u6b21\u6570\u548c-1 def main (): # \u6d4b\u8bd5 arr = [ 1 , 2 , 3 , 4 , 5 , 6 , 7 , 8 , 9 , 10 ] for target in [ 5 , 11 ]: comparisons , index = ordered_sequential_search ( arr , target ) if index != - 1 : print ( f \"\u76ee\u6807 { target } \u5728\u7d22\u5f15 { index } \u5904\u627e\u5230\uff0c\u6bd4\u8f83\u6b21\u6570\u4e3a { comparisons } \" ) else : print ( f \"\u76ee\u6807 { target } \u672a\u627e\u5230\uff0c\u6bd4\u8f83\u6b21\u6570\u4e3a { comparisons } \" ) if __name__ == \"__main__\" : main () # \u8fd0\u884c\u7ed3\u679c # \u76ee\u6807 5 \u5728\u7d22\u5f15 4 \u5904\u627e\u5230\uff0c\u6bd4\u8f83\u6b21\u6570\u4e3a 5 # \u76ee\u6807 11 \u672a\u627e\u5230\uff0c\u6bd4\u8f83\u6b21\u6570\u4e3a 10 2\uff0e\u5217\u8868\u7684 reverse \u65b9\u6cd5\u7528\u6765\u53cd\u8f6c\u5217\u8868\u91cc\u7684\u5143\u7d20\u3002\u5b9a\u4e49\u4e00\u4e2a\u53eb\u4f5c reverse \u7684\u51fd\u6570\uff0c\u8fd9\u4e2a\u51fd\u6570\u53ef\u4ee5\u5728\u4e0d\u4f7f\u7528 reverse \u65b9\u6cd5\u7684\u60c5\u51b5\u4e0b\uff0c\u53cd\u8f6c\u5217\u8868\u53c2\u6570\u91cc\u7684\u6240\u6709\u5143\u7d20\u3002\u5c1d\u8bd5\u8ba9\u8fd9\u4e2a\u51fd\u6570\u5c3d\u53ef\u80fd\u5730\u9ad8\u6548\uff0c\u5e76\u4f7f\u7528\u5927O\u8868\u793a\u6cd5\u63cf\u8ff0\u5b83\u7684\u8ba1\u7b97\u590d\u6742\u5ea6\u3002 \u89e3\u7b54\uff1a \u53ea\u9700\u8981\u904d\u5386\u5217\u8868\u7684\u4e00\u534a\uff0c\u6211\u4eec\u5c31\u80fd\u5230\u8fbe\u5217\u8868\u7684\u4e2d\u95f4\u4f4d\u7f6e\u628a\u5217\u8868\u4e24\u8fb9\u7684\u5143\u7d20\u4e92\u6362\uff0c\u8fd9\u6837\u5c31\u5b8c\u6210\u4e86\u5217\u8868\u7684\u53cd\u8f6c\u3002 \u8fd9\u4e2a\u7b97\u6cd5\u7684\u65f6\u95f4\u590d\u6742\u5ea6\u662f O(n/2) \uff0c\u5176\u4e2d n \u662f\u5217\u8868\u7684\u957f\u5ea6\u3002\u4f46\u5728\u5927O\u8868\u793a\u6cd5\u4e2d\uff0c\u5e38\u6570\u88ab\u5ffd\u7565\uff0c\u56e0\u6b64\u8be5\u7b97\u6cd5\u7684\u65f6\u95f4\u590d\u6742\u5ea6\u662f O(n) \u3002\u5728\u8fd9\u4e2a\u7b97\u6cd5\u4e2d\uff0c n \u5c31\u4ee3\u8868\u7740\u5217\u8868\u7684\u957f\u5ea6\u3002\u610f\u5473\u7740\u65f6\u95f4\u590d\u6742\u5ea6\u53d7\u5217\u8868\u957f\u5ea6\u7684\u5f71\u54cd\u3002\u5217\u8868\u957f\u5ea6\u6bcf\u589e\u52a0\u4e00\u6b21\uff0c\u6267\u884c\u53cd\u8f6c\u7684\u65f6\u95f4\u5c31\u589e\u52a0\u4e00\u6b21\u3002\u8fd9\u5c31\u662f O(n) \u7684\u6982\u5ff5\u3002 \u8fd9\u4e2a\u51fd\u6570\u7684\u7a7a\u95f4\u590d\u6742\u5ea6\u662f O(1) \uff0c\u56e0\u4e3a\u5b83\u53ea\u662f\u5728\u539f\u5730\u4fee\u6539\u5217\u8868\uff0c\u4e0d\u9700\u8981\u989d\u5916\u7684\u5b58\u50a8\u7a7a\u95f4\u3002 \u4ee3\u7801\u5982\u4e0b\uff1a def custom_reverse ( arr ): left , right = 0 , len ( arr ) - 1 while left < right : arr [ left ], arr [ right ] = arr [ right ], arr [ left ] left += 1 right -= 1 def main (): # \u6d4b\u8bd5\u5217\u8868reverse\u65b9\u6cd5 my_list = [ 1 , 2 , 3 , 4 , 5 ] my_list . reverse () print ( my_list ) # \u6d4b\u8bd5\u81ea\u5b9a\u4e49\u7684reverse\u65b9\u6cd5 my_list = [ 1 , 2 , 3 , 4 , 5 ] custom_reverse ( my_list ) print ( my_list ) if __name__ == \"__main__\" : main () # \u8fd0\u884c\u7ed3\u679c # [5, 4, 3, 2, 1] # [5, 4, 3, 2, 1] 3\uff0ePython\u7684pow\u51fd\u6570\u4f1a\u8fd4\u56de\u6570\u5b57\u7279\u5b9a\u5e42\u6b21\u7684\u7ed3\u679c\u3002\u5b9a\u4e49\u6267\u884c\u8fd9\u4e2a\u4efb\u52a1\u7684expo\u51fd\u6570\uff0c\u5e76\u4f7f\u7528\u5927O\u8868\u793a\u6cd5\u63cf\u8ff0\u5b83\u7684\u8ba1\u7b97\u590d\u6742\u5ea6\u3002\u8fd9\u4e2a\u51fd\u6570\u7684\u7b2c\u4e00\u4e2a\u53c2\u6570\u662f\u6570\u5b57\uff0c\u7b2c\u4e8c\u4e2a\u53c2\u6570\u662f\u6307\u6570\uff08\u975e\u8d1f\u6570\uff09\u3002\u4f60\u53ef\u4ee5\u901a\u8fc7\u5faa\u73af\u6216\u9012\u5f52\u51fd\u6570\u6765\u5b9e\u73b0\uff0c\u4f46\u4e0d\u8981\u4f7f\u7528Python\u5185\u7f6e\u7684**\u8fd0\u7b97\u7b26\u6216\u662fpow\u51fd\u6570\u3002 \u89e3\u7b54\uff1a \u4e0b\u9762\u5b9e\u73b0\u7684 expo \u51fd\u6570\u4f7f\u7528\u5faa\u73af\u6765\u8fde\u7eed\u4e58\u4ee5 base \uff0c\u5faa\u73af\u7684\u6b21\u6570\u7b49\u4e8e exponent \u7684\u503c\u3002 \u65f6\u95f4\u590d\u6742\u5ea6\u662f O(exponent) \uff0c\u5176\u4e2d exponent \u662f\u6307\u6570\u7684\u503c\u3002 \u6700\u597d\u60c5\u51b5\uff1aO(exponent) \u6700\u574f\u60c5\u51b5\uff1aO(exponent) \u5e73\u5747\u60c5\u51b5\uff1aO(exponent) def expo ( base , exponent ): result = 1 for _ in range ( exponent ): result *= base return result def main (): # \u6d4b\u8bd5 base = 2 for exponent in [ 3 , - 3 ]: result = expo ( base , exponent ) print ( f \" { base } \u7684 { exponent } \u6b21\u65b9\u7b49\u4e8e { result } \" ) if __name__ == \"__main__\" : main () # \u8fd0\u884c\u7ed3\u679c # 2 \u7684 3 \u6b21\u65b9\u7b49\u4e8e 8 # 2 \u7684 -3 \u6b21\u65b9\u7b49\u4e8e 1 4\uff0e\u53e6\u4e00\u4e2a\u5b9e\u73b0 expo \u51fd\u6570\u7684\u7b56\u7565\u4f7f\u7528\u4e0b\u9762\u8fd9\u4e2a\u9012\u5f52\u3002\u8bf7\u5b9a\u4e49\u4f7f\u7528\u8fd9\u4e2a\u7b56\u7565\u7684\u9012\u5f52\u51fd\u6570 expo \uff0c\u5e76\u4f7f\u7528\u5927O\u8868\u793a\u6cd5\u63cf\u8ff0\u5b83\u7684\u8ba1\u7b97\u590d\u6742\u5ea6\u3002 expo ( number \uff0c exponent ) = 1 \uff0c \u5f53 exponent = 0 \u7684\u65f6\u5019 = number * expo ( number , exponent \u2212 1 ) \uff0c \u5f53exponent\u4e3a\u5947\u6570\u7684\u65f6\u5019 = ( expo ( number , exponent / 2 )) 2 \uff0c \u5f53exponent\u4e3a\u5076\u6570\u7684\u65f6\u5019 \u89e3\u7b54\uff1a \u4e0b\u9762\u5b9e\u73b0expo\u51fd\u6570\u662f\u901a\u8fc7\u9012\u5f52\u5b9e\u73b0\uff0c\u5e76\u91c7\u7528\u4e86\u5206\u800c\u6cbb\u4e4b\u7684\u7b56\u7565\u3002 \u5982\u679c\u6307\u6570\u662f\u5947\u6570\uff0c\u5c31\u628a\u95ee\u9898\u5206\u89e3\u4e3a\u4e00\u4e2a\u66f4\u5c0f\u7684\u7248\u672c\uff08\u5373 num * num^(exp - 1) \uff09\uff1b \u5982\u679c\u6307\u6570\u662f\u5076\u6570\uff0c\u5219\u53ef\u4ee5\u5c06\u6307\u6570\u5206\u6210\u4e24\u534a\uff0c\u5e76\u53ea\u8ba1\u7b97\u5176\u4e2d\u7684\u4e00\u534a\uff08\u5373 num^(exp / 2) * num^(exp / 2) \uff09\u3002 \u8fd9\u5c31\u5229\u7528\u4e86\u5e42\u7684\u6027\u8d28 a^(m * n) = (a^m)^n \u3002 \u8be5\u9012\u5f52\u5b9e\u73b0\u7684\u65f6\u95f4\u590d\u6742\u5ea6\u4e3a O(log n) \uff0c\u5176\u4e2dn\u4e3a\u6307\u6570\u3002\u8fd9\u662f\u56e0\u4e3a\u5728\u6307\u6570\u4e3a\u5076\u6570\u7684\u60c5\u51b5\u4e0b\uff0c\u6bcf\u6b21\u9012\u5f52\u8c03\u7528\u90fd\u4f1a\u628a\u95ee\u9898\u89c4\u6a21\u7f29\u5c0f\u4e00\u534a\uff0c\u7c7b\u4f3c\u4e8e\u4e8c\u5206\u67e5\u627e\u7b49\u8bfe\u5206\u5272\u95ee\u9898\u3002 \u7a7a\u95f4\u590d\u6742\u5ea6\u4e5f\u662f O(log n) \uff0c\u8fd9\u4e3b\u8981\u662f\u7531\u4e8e\u51fd\u6570\u8c03\u7528\u6808\u7684\u6df1\u5ea6\u5728\u6307\u6570\u4e3a\u5076\u6570\u7684\u60c5\u51b5\u4e0b\uff0c\u4f1a\u53d8\u4e3a\u539f\u6765\u7684\u4e00\u534a\u3002 def expo ( number , exponent ): if exponent <= 0 : return 1 elif exponent % 2 == 1 : # \u5f53 exponent \u4e3a\u5947\u6570 return number * expo ( number , exponent - 1 ) else : # \u5f53 exponent \u4e3a\u5076\u6570 half_expo = expo ( number , exponent // 2 ) return half_expo * half_expo def main (): # \u6d4b\u8bd5 base = 2 for exponent in [ 3 , - 3 ]: result = expo ( base , exponent ) print ( f \" { base } \u7684 { exponent } \u6b21\u65b9\u7b49\u4e8e { result } \" ) if __name__ == \"__main__\" : main () # \u8fd0\u884c\u7ed3\u679c # 2 \u7684 3 \u6b21\u65b9\u7b49\u4e8e 8 # 2 \u7684 -3 \u6b21\u65b9\u7b49\u4e8e 1 5\uff0ePython\u4e2dlist\u91cc\u7684sort\u65b9\u6cd5\u5305\u542b\u4e00\u4e2a\u7528\u5173\u952e\u5b57\u547d\u540d\u7684\u53c2\u6570reverse\uff0c\u5b83\u7684\u9ed8\u8ba4\u503c\u4e3aFalse\u3002\u7a0b\u5e8f\u5458\u53ef\u4ee5\u901a\u8fc7\u8986\u76d6\u8fd9\u4e2a\u503c\u4ee5\u5bf9\u5217\u8868\u8fdb\u884c\u964d\u5e8f\u6392\u5e8f\u3002\u4fee\u6539\u672c\u7ae0\u8ba8\u8bba\u7684selectionSort\u51fd\u6570\uff0c\u4f7f\u5b83\u53ef\u4ee5\u63d0\u4f9b\u8fd9\u4e2a\u9644\u52a0\u53c2\u6570\u6765\u8ba9\u7a0b\u5e8f\u5458\u51b3\u5b9a\u6392\u5e8f\u7684\u65b9\u5411\u3002 \u89e3\u7b54\uff1a \u901a\u8fc7\u6dfb\u52a0\u4e00\u4e2a\u540d\u4e3a reverse \u7684\u53c2\u6570\u6765\u4fee\u6539 selectionSort \u51fd\u6570\uff0c\u4ee5\u4fbf\u8ba9\u7a0b\u5e8f\u5458\u51b3\u5b9a\u6392\u5e8f\u7684\u65b9\u5411\u3002\u5982\u679c reverse \u4e3a True \uff0c\u6392\u5e8f\u5c06\u662f\u964d\u5e8f\u7684\uff0c\u5982\u679c\u4e3a False \uff08\u9ed8\u8ba4\u503c\uff09\uff0c\u6392\u5e8f\u5c06\u662f\u5347\u5e8f\u7684\u3002 \u4e0b\u9762\u662f\u4fee\u6539\u540e\u7684 selectionSort \u51fd\u6570\uff1a def swap ( lyst , i , j ): \"\"\"\u4ea4\u6362\u5143\u7d20\u4f4d\u7f6e\u4e3ai\u548cj\u7684\u5143\u7d20\"\"\" temp = lyst [ i ] lyst [ i ] = lyst [ j ] lyst [ j ] = temp def selectionSort ( lyst , reverse = False ): \"\"\"\u5b9e\u73b0\u4ea4\u6362\u6392\u5e8f\u7b97\u6cd5\uff0c\u53ef\u4ee5\u9009\u62e9\u5347\u5e8f\u6216\u964d\u5e8f\u6392\u5e8f\"\"\" i = 0 while i < len ( lyst ) - 1 : # \u5b9e\u73b0n-1\u6b21\u641c\u7d22 index = i # \u6700\u5c0f\u6216\u6700\u5927\u5143\u7d20\u4f4d\u7f6e j = i + 1 while j < len ( lyst ): # \u5411\u540e\u904d\u5386\u641c\u7d22\uff0c\u66f4\u65b0\u6700\u5c0f\u6216\u6700\u5927\u5143\u7d20\u4f4d\u7f6e if not reverse : if ( lyst [ j ] < lyst [ index ]): index = j else : if ( lyst [ j ] > lyst [ index ]): index = j j += 1 if index != i : # \u5982\u679c\u9700\u8981\uff0c\u5219\u4ea4\u6362\u5143\u7d20\u4f4d\u7f6e swap ( lyst , index , i ) i += 1 def main (): myList = [ 9 , 4 , 2 , 7 , 6 , 8 , 1 ] print ( \"Before selection sort \" , myList ) selectionSort ( myList ) print ( \"After selection sort \" , myList ) if __name__ == \"__main__\" : main () # \u8fd0\u884c\u7ed3\u679c\uff1a # Before selection sort [9, 4, 2, 7, 6, 8, 1] # After selection sort [1, 2, 4, 6, 7, 8, 9] 6\uff0e\u4fee\u6539\u9012\u5f52\u6590\u6ce2\u90a3\u5951\u51fd\u6570\uff0c\u8ba9\u5b83\u652f\u6301\u672c\u7ae0\u91cc\u8ba8\u8bba\u8fc7\u7684\u8bb0\u5fc6\u5316\u6280\u672f\u3002\u8fd9\u4e2a\u51fd\u6570\u5e94\u6dfb\u52a0\u4e00\u4e2a\u5b57\u5178\u7c7b\u578b\u7684\u53c2\u6570\u3002\u5b83\u7684\u9876\u5c42\u8c03\u7528\u4f1a\u63a5\u6536\u4e00\u4e2a\u7a7a\u5b57\u5178\u4f5c\u4e3a\u53c2\u6570\uff0c\u8fd9\u4e2a\u5b57\u5178\u7684\u952e\u548c\u503c\u5e94\u8be5\u662f\u9012\u5f52\u8c03\u7528\u6240\u4f20\u9012\u7684\u53c2\u6570\u548c\u8ba1\u7b97\u51fa\u7684\u503c\u3002\u4e4b\u540e\uff0c\u7528\u672c\u7ae0\u8ba8\u8bba\u8fc7\u7684\u8ba1\u6570\u5668\u5bf9\u8c61\u5bf9\u9012\u5f52\u8c03\u7528\u7684\u6570\u91cf\u8fdb\u884c\u7edf\u8ba1\u3002 \u89e3\u7b54\uff1a \u4e0b\u9762\u662f\u4e00\u4e2a\u4fee\u6539\u540e\u7684\u7248\u672c\uff0c\u5b83\u4f7f\u7528\u4e00\u4e2a\u5b57\u5178\uff08\u7f13\u5b58\uff09\u6765\u5b58\u50a8\u5df2\u8ba1\u7b97\u7684\u7ed3\u679c\uff0c\u5e76\u4e14\u6dfb\u52a0\u4e86\u4e00\u4e2a\u8ba1\u6570\u5668\u5bf9\u8c61\u6765\u7edf\u8ba1\u9012\u5f52\u8c03\u7528\u6b21\u6570\u3002\u8fd9\u4e2a\u4ee3\u7801\u4f1a\u8f93\u51fa\u6307\u5b9a\u9879\u6570\u7684\u6590\u6ce2\u90a3\u5951\u6570\u4ee5\u53ca\u9012\u5f52\u8c03\u7528\u7684\u603b\u6b21\u6570\u3002\u8bb0\u5fc6\u5316\u6280\u672f\u53ef\u4ee5\u663e\u8457\u63d0\u9ad8\u6590\u6ce2\u90a3\u5951\u51fd\u6570\u7684\u6027\u80fd\uff0c\u907f\u514d\u4e86\u91cd\u590d\u8ba1\u7b97\u3002 class Counter : def __init__ ( self ): self . count = 0 def increment ( self ): self . count += 1 def fib ( n , cache , counter ): \"\"\"\u6590\u6ce2\u90a3\u5951\u9012\u5f52\u6570\u5217\uff0c\u5e26\u6709\u8bb0\u5fc6\u5316\u548c\u8c03\u7528\u8ba1\u6570\u5668\"\"\" if n in cache : return cache [ n ] counter . increment () if n <= 1 : result = 1 else : result = fib ( n - 1 , cache , counter ) + fib ( n - 2 , cache , counter ) cache [ n ] = result return result def main (): n = 10 # \u4f60\u53ef\u4ee5\u8bbe\u7f6e\u4e0d\u540c\u7684\u6590\u6ce2\u90a3\u5951\u6570\u5217\u9879\u6570 cache = {} # \u7528\u4e8e\u7f13\u5b58\u5df2\u8ba1\u7b97\u7ed3\u679c\u7684\u5b57\u5178 counter = Counter () # \u7528\u4e8e\u8ba1\u6570\u9012\u5f52\u8c03\u7528\u6b21\u6570\u7684\u8ba1\u6570\u5668\u5bf9\u8c61 result = fib ( n , cache , counter ) print ( f \"Fibonacci( { n } ) = { result } \" ) print ( f \"Total recursive calls: { counter . count } \" ) if __name__ == \"__main__\" : main () # \u8fd0\u884c\u7ed3\u679c\uff1a # Fibonacci(10) = 89 # Total recursive calls: 11 7\uff0e\u5206\u6790\u4e0a\u9762\u6590\u6ce2\u90a3\u5951\u6570\u5217\u91cc\u5b9a\u4e49\u7684\u8bb0\u5fc6\u5316\u6590\u6ce2\u90a3\u5951\u51fd\u6570\u7684\u6027\u80fd\uff0c\u7edf\u8ba1\u8fd9\u4e2a\u51fd\u6570\u9012\u5f52\u8c03\u7528\u7684\u6b21\u6570\u3002\u4f7f\u7528\u5927O\u8868\u793a\u6cd5\u63cf\u8ff0\u5b83\u7684\u8ba1\u7b97\u590d\u6742\u5ea6\uff0c\u5e76\u8bc1\u660e\u4f60\u7684\u7b54\u6848\u662f\u5408\u7406\u7684\u3002 \u89e3\u7b54\uff1a \u5728\u4e0a\u9762\u7684\u8bb0\u5fc6\u5316\u6590\u6ce2\u90a3\u5951\u51fd\u6570\u4e2d\uff0c\u6211\u4eec\u4f7f\u7528\u4e86\u8bb0\u5fc6\u5316\u6280\u672f\u6765\u907f\u514d\u91cd\u590d\u8ba1\u7b97\u3002\u8fd9\u79cd\u4f18\u5316\u4f1a\u663e\u8457\u51cf\u5c11\u8ba1\u7b97\u65f6\u95f4\uff0c\u56e0\u4e3a\u6bcf\u4e2a\u6590\u6ce2\u90a3\u5951\u6570\u53ea\u4f1a\u88ab\u8ba1\u7b97\u4e00\u6b21\u3002 \u8ba1\u7b97\u590d\u6742\u5ea6\u5206\u6790\uff1a \u8bb0\u5fc6\u5316\u6590\u6ce2\u90a3\u5951\u51fd\u6570\u7684\u8ba1\u7b97\u590d\u6742\u5ea6\u662f O(n) \u3002\u8fd9\u662f\u56e0\u4e3a\u5b83\u9700\u8981\u8ba1\u7b97\u6590\u6ce2\u90a3\u5951\u6570\u5217\u7684\u524d n \u9879\uff0c\u6bcf\u4e00\u9879\u53ea\u9700\u8ba1\u7b97\u4e00\u6b21\uff0c\u7136\u540e\u5b58\u50a8\u5728\u7f13\u5b58\u4e2d\u3002\u56e0\u6b64\uff0c\u603b\u5171\u6267\u884c\u7684\u8ba1\u7b97\u91cf\u4e0e n \u6210\u6b63\u6bd4\uff0c\u5373 O(n) \u3002 \u9012\u5f52\u8c03\u7528\u6b21\u6570\uff1a \u9012\u5f52\u8c03\u7528\u7684\u6b21\u6570\u53d6\u51b3\u4e8e\u8f93\u5165\u53c2\u6570 n \u3002\u5bf9\u4e8e\u6590\u6ce2\u90a3\u5951\u6570\u5217\uff0c\u9012\u5f52\u8c03\u7528\u7684\u6b21\u6570\u5927\u81f4\u7b49\u4e8e n \u3002\u56e0\u4e3a\u6bcf\u4e2a\u9879\u9700\u8981\u8ba1\u7b97\u4e00\u6b21\uff0c\u6240\u4ee5\u9012\u5f52\u8c03\u7528\u7684\u6b21\u6570\u4e0e\u8ba1\u7b97\u7684\u9879\u6570\u662f\u4e00\u81f4\u7684\u3002 \u6240\u4ee5\uff0c\u8fd9\u4e2a\u8bb0\u5fc6\u5316\u6590\u6ce2\u90a3\u5951\u51fd\u6570\u7684\u8ba1\u7b97\u590d\u6742\u5ea6\u662f O(n) \uff0c\u800c\u9012\u5f52\u8c03\u7528\u7684\u6b21\u6570\u4e5f\u5927\u81f4\u7b49\u4e8e n \u3002\u8fd9\u4e2a\u6027\u80fd\u662f\u76f8\u5bf9\u8f83\u597d\u7684\uff0c\u56e0\u4e3a\u5b83\u907f\u514d\u4e86\u6307\u6570\u7ea7\u522b\u7684\u91cd\u590d\u8ba1\u7b97\uff0c\u800c\u662f\u7ebf\u6027\u5730\u8ba1\u7b97\u6590\u6ce2\u90a3\u5951\u6570\u5217\u7684\u5404\u9879\u3002 8\uff0e\u51fd\u6570makeRandomList\u4f1a\u521b\u5efa\u5e76\u8fd4\u56de\u4e00\u4e2a\u7ed9\u5b9a\u5927\u5c0f\uff08\u5b83\u7684\u53c2\u6570\uff09\u7684\u6570\u5b57\u5217\u8868\u3002\u5217\u8868\u91cc\u7684\u6570\u5b57\u6ca1\u6709\u91cd\u590d\uff0c\u5b83\u4eec\u7684\u8303\u56f4\u4e3a1\uff5esize\uff0c\u4f4d\u7f6e\u662f\u968f\u673a\u7684\u3002\u4e0b\u9762\u662f\u8fd9\u4e2a\u51fd\u6570\u7684\u4ee3\u7801\u3002\u53ef\u4ee5\u5047\u5b9arange\u3001randint\u548cappend\u51fd\u6570\u90fd\u662f\u5e38\u6570\u65f6\u95f4\u7684\u590d\u6742\u5ea6\u3002\u8fd8\u53ef\u4ee5\u5047\u8bberandom.randint\u968f\u7740\u53c2\u6570\u4e4b\u95f4\u5dee\u503c\u7684\u589e\u52a0\u800c\u66f4\u5c11\u5730\u8fd4\u56de\u91cd\u590d\u7684\u6570\u5b57\u3002\u4f7f\u7528\u5927O\u8868\u793a\u6cd5\u63cf\u8ff0\u8fd9\u4e2a\u51fd\u6570\u7684\u8ba1\u7b97\u590d\u6742\u5ea6\uff0c\u5e76\u8bc1\u660e\u4f60\u7684\u7b54\u6848\u662f\u5408\u7406\u7684\u3002 def makeRandomList ( size ): lyst = [] for count in range ( size ): while True : number = random . randint ( 1 , size ) if not number in lyst : lyst . append ( number ) break return lyst \u89e3\u7b54\uff1a \u8fd9\u4e2a\u51fd\u6570\u7684\u8ba1\u7b97\u590d\u6742\u5ea6\u53d6\u51b3\u4e8e\u5b83\u7684\u5185\u90e8\u5faa\u73af\uff0c\u8be5\u5faa\u73af\u4f1a\u4e0d\u65ad\u751f\u6210\u968f\u673a\u6570\uff0c\u5e76\u68c0\u67e5\u5b83\u662f\u5426\u5df2\u7ecf\u5728\u5217\u8868 lyst \u4e2d\u3002\u5177\u4f53\u5206\u6790\u5982\u4e0b\uff1a \u521b\u5efa\u4e00\u4e2a\u7a7a\u5217\u8868 lyst \uff0c\u65f6\u95f4\u590d\u6742\u5ea6\u4e3a O(1)\u3002 \u8fdb\u5165 for \u5faa\u73af\uff0c\u5faa\u73af\u6b21\u6570\u4e3a size \uff0c\u65f6\u95f4\u590d\u6742\u5ea6\u4e3a O(size)\u3002 \u5728\u5185\u90e8 while \u5faa\u73af\u4e2d\uff0c\u751f\u6210\u4e00\u4e2a\u968f\u673a\u6570 number \uff0c\u6700\u574f\u60c5\u51b5\u4e0b\u9700\u8981\u751f\u6210 size \u6b21\u968f\u673a\u6570\u624d\u80fd\u627e\u5230\u4e00\u4e2a\u4e0d\u5728 lyst \u4e2d\u7684\u6570\u5b57\u3002\u8fd9\u90e8\u5206\u7684\u65f6\u95f4\u590d\u6742\u5ea6\u4e3a O(size)\u3002 \u7efc\u4e0a\u6240\u8ff0\uff0c\u8fd9\u4e2a\u51fd\u6570\u7684\u603b\u4f53\u65f6\u95f4\u590d\u6742\u5ea6\u4e3a O(size^2)\u3002\u8fd9\u662f\u56e0\u4e3a\u5728\u6700\u574f\u60c5\u51b5\u4e0b\uff0c\u6bcf\u6b21\u751f\u6210\u7684\u968f\u673a\u6570\u90fd\u9700\u8981\u68c0\u67e5\u662f\u5426\u5728 lyst \u4e2d\uff0c\u800c\u968f\u673a\u6570\u7684\u751f\u6210\u53ef\u80fd\u9700\u8981\u591a\u6b21\u624d\u80fd\u751f\u6210\u4e00\u4e2a\u4e0d\u5728\u5217\u8868\u4e2d\u7684\u6570\u5b57\u3002 \u9700\u8981\u6ce8\u610f\u7684\u662f\uff0c\u968f\u7740 size \u7684\u589e\u52a0\uff0c\u5185\u90e8\u5faa\u73af\u7684\u8fed\u4ee3\u6b21\u6570\u4e5f\u4f1a\u589e\u52a0\uff0c\u5bfc\u81f4\u65f6\u95f4\u590d\u6742\u5ea6\u5448\u4e8c\u6b21\u589e\u957f\u3002\u56e0\u6b64\uff0c\u8fd9\u4e2a\u51fd\u6570\u7684\u6027\u80fd\u5728\u5927\u89c4\u6a21\u6570\u636e\u4e0a\u53ef\u80fd\u4f1a\u53d7\u5230\u9650\u5236\u3002\u5982\u679c\u9700\u8981\u66f4\u597d\u7684\u6027\u80fd\uff0c\u53ef\u4ee5\u8003\u8651\u5176\u4ed6\u7b97\u6cd5\uff0c\u4ee5\u907f\u514d\u91cd\u590d\u68c0\u67e5\u548c\u751f\u6210\u968f\u673a\u6570\u3002 import random def makeRandomList ( size ): lyst = [] for count in range ( size ): while True : number = random . randint ( 1 , size ) if not number in lyst : lyst . append ( number ) break print ( \"count=\" , count , \"list=\" , lyst ) return lyst def main (): print ( \"final list=\" , makeRandomList ( 10 )) if __name__ == \"__main__\" : main () # \u8fd0\u884c\u7ed3\u679c\uff1a # count= 0 list= [2] # count= 1 list= [2, 10] # count= 2 list= [2, 10, 9] # count= 3 list= [2, 10, 9, 5] # count= 4 list= [2, 10, 9, 5, 3] # count= 5 list= [2, 10, 9, 5, 3, 4] # count= 6 list= [2, 10, 9, 5, 3, 4, 8] # count= 7 list= [2, 10, 9, 5, 3, 4, 8, 7] # count= 8 list= [2, 10, 9, 5, 3, 4, 8, 7, 6] # count= 9 list= [2, 10, 9, 5, 3, 4, 8, 7, 6, 1] # final list= [2, 10, 9, 5, 3, 4, 8, 7, 6, 1] 9\uff0e\u4fee\u6539quicksort\u51fd\u6570\uff0c\u8ba9\u5b83\u53ef\u4ee5\u5bf9\u4efb\u4f55\u5c3a\u5bf8\u5c0f\u4e8e50\u7684\u5b50\u5217\u8868\u8c03\u7528\u63d2\u5165\u6392\u5e8f\u3002\u4f7f\u7528\u670950\u3001500\u548c5000\u4e2a\u5143\u7d20\u7684\u6570\u636e\u96c6\u6bd4\u8f83\u8fd9\u4e2a\u7248\u672c\u4e0e\u539f\u59cb\u7248\u672c\u7684\u6027\u80fd\u3002\u7136\u540e\u8c03\u6574\u8fd9\u4e2a\u9608\u503c\uff0c\u4ece\u800c\u786e\u5b9a\u4f7f\u7528\u63d2\u5165\u6392\u5e8f\u7684\u6700\u4f73\u8bbe\u7f6e\u3002 \u89e3\u7b54\uff1a \u53ef\u4ee5\u5728 quicksortHelper \u51fd\u6570\u4e2d\u6dfb\u52a0\u4e00\u4e2a\u6761\u4ef6\uff0c\u68c0\u67e5\u5b50\u5217\u8868\u7684\u5927\u5c0f\u3002\u7136\u540e\u518d\u4fee\u6539 quicksort \u51fd\u6570\uff0c\u5b9e\u73b0\u5728\u5c0f\u4e8e50\u7684\u5b50\u5217\u8868\u4e0a\u4f7f\u7528\u63d2\u5165\u6392\u5e8f\u3002 \u5982\u679c\u5b50\u5217\u8868\u7684\u5927\u5c0f\u5c0f\u4e8e50\uff0c\u5c31\u4f7f\u7528\u63d2\u5165\u6392\u5e8f\u7b97\u6cd5\uff0c\u5426\u5219\u4f7f\u7528\u5feb\u901f\u6392\u5e8f\u7b97\u6cd5\u3002\u4e0b\u9762\u662f\u4fee\u6539\u540e\u7684\u4ee3\u7801\uff1a import random def swap ( lyst , i , j ): \"\"\"\u4ea4\u6362\u5143\u7d20\u4f4d\u7f6e\u4e3ai\u548cj\u7684\u5143\u7d20\"\"\" temp = lyst [ i ] lyst [ i ] = lyst [ j ] lyst [ j ] = temp def quicksort ( lyst ): quicksortHelper ( lyst , 0 , len ( lyst ) - 1 ) def quicksortHelper ( lyst , left , right ): if left < right : # \u68c0\u67e5\u5b50\u5217\u8868\u7684\u5927\u5c0f\u662f\u5426\u5c0f\u4e8e50 if right - left < 50 : # \u5982\u679c\u5c0f\u4e8e50\uff0c\u4f7f\u7528\u63d2\u5165\u6392\u5e8f insertionSort ( lyst , left , right ) else : pivotLocation = partition ( lyst , left , right ) quicksortHelper ( lyst , left , pivotLocation - 1 ) quicksortHelper ( lyst , pivotLocation + 1 , right ) def partition ( lyst , left , right ): \"\"\"\u5bf9\u5217\u8868\u8fdb\u884c\u5206\u533a\"\"\" # \u627e\u5230\u57fa\u51c6\u5143\u7d20\uff08pivot\uff09\uff0c\u5e76\u548c\u6700\u540e\u4e00\u4e2a\u5143\u7d20\u4e92\u6362 middle = ( left + right ) // 2 pivot = lyst [ middle ] lyst [ middle ] = lyst [ right ] lyst [ right ] = pivot # \u8bbe\u5b9a\u8fb9\u754c\u5143\u7d20\uff08boundary point\uff09\uff0c\u521d\u59cb\u662f\u7b2c\u4e00\u4e2a\u5143\u7d20 boundary = left print ( \"pivot: \" , pivot , \"boundary: \" , lyst [ boundary ]) # \u628a\u6240\u6709\u5c0f\u4e8e\u57fa\u51c6\u7684\u5143\u7d20\u90fd\u79fb\u52a8\u5230\u8fb9\u754c\u7684\u5de6\u8fb9 for index in range ( left , right ): if lyst [ index ] < pivot : swap ( lyst , index , boundary ) boundary += 1 # \u4ea4\u6362\u57fa\u51c6\u5143\u7d20\u548c\u8fb9\u754c\u5143\u7d20 swap ( lyst , right , boundary ) print ( lyst ) return boundary def insertionSort ( lyst , left , right ): \"\"\"\u63d2\u5165\u6392\u5e8f\u7b97\u6cd5\"\"\" for i in range ( left + 1 , right + 1 ): currentElement = lyst [ i ] j = i while j > left and currentElement < lyst [ j - 1 ]: lyst [ j ] = lyst [ j - 1 ] j -= 1 lyst [ j ] = currentElement def main ( size = 20 , sort = quicksort ): lyst = [ random . randint ( 1 , size ) for _ in range ( size )] print ( \"Before sorted\" , lyst ) sort ( lyst ) print ( \"After sorted\" , lyst ) if __name__ == \"__main__\" : main () # \u8fd0\u884c\u7ed3\u679c\uff1a # Before sorted [1, 3, 6, 14, 9, 6, 14, 15, 17, 13, 4, 3, 1, 13, 11, 16, 2, 4, 6, 2] # After sorted [1, 1, 2, 2, 3, 3, 4, 4, 6, 6, 6, 9, 11, 13, 13, 14, 14, 15, 16, 17] 10\uff0e\u8ba1\u7b97\u673a\u4f7f\u7528\u540d\u4e3a\u8c03\u7528\u6808\u7684\u7ed3\u6784\u6765\u4e3a\u9012\u5f52\u51fd\u6570\u7684\u8c03\u7528\u63d0\u4f9b\u652f\u6301\u3002\u4e00\u822c\u800c\u8a00\uff0c\u8ba1\u7b97\u673a\u4f1a\u4e3a\u51fd\u6570\u7684\u6bcf\u6b21\u8c03\u7528\u90fd\u4fdd\u7559\u4e00\u5b9a\u6570\u91cf\u7684\u5185\u5b58\u3002\u56e0\u6b64\uff0c\u53ef\u4ee5\u5bf9\u9012\u5f52\u51fd\u6570\u4f7f\u7528\u7684\u5185\u5b58\u6570\u91cf\u8fdb\u884c\u590d\u6742\u5ea6\u5206\u6790\u3002\u8bf7\u8bf4\u660e\u9012\u5f52\u9636\u4e58\u51fd\u6570\u548c\u9012\u5f52\u6590\u6ce2\u90a3\u5951\u51fd\u6570\u4f7f\u7528\u7684\u5185\u5b58\u7684\u8ba1\u7b97\u590d\u6742\u5ea6\u3002 \u89e3\u7b54\uff1a \u9012\u5f52\u9636\u4e58\u51fd\u6570\u548c\u9012\u5f52\u6590\u6ce2\u90a3\u5951\u51fd\u6570\u4f7f\u7528\u7684\u5185\u5b58\u7684\u8ba1\u7b97\u590d\u6742\u5ea6\u90fd\u4e0e\u9012\u5f52\u7684\u6df1\u5ea6\uff08\u9012\u5f52\u8c03\u7528\u7684\u5c42\u6570\uff09\u76f8\u5173\u3002\u9012\u5f52\u51fd\u6570\u6bcf\u6b21\u8c03\u7528\u90fd\u4f1a\u5728\u8c03\u7528\u6808\u4e2d\u5206\u914d\u4e00\u5b9a\u6570\u91cf\u7684\u5185\u5b58\uff0c\u5305\u62ec\u51fd\u6570\u7684\u53c2\u6570\u3001\u5c40\u90e8\u53d8\u91cf\u4ee5\u53ca\u8fd4\u56de\u5730\u5740\u7b49\u4fe1\u606f\u3002 \u9012\u5f52\u9636\u4e58\u51fd\u6570\u7684\u5185\u5b58\u590d\u6742\u5ea6\uff1a \u9012\u5f52\u9636\u4e58\u51fd\u6570\u662f\u4e00\u4e2a\u975e\u5e38\u7b80\u5355\u7684\u9012\u5f52\u51fd\u6570\uff0c\u5b83\u53ea\u9700\u8981\u4fdd\u5b58\u4e00\u4e2a\u6574\u6570\u53c2\u6570 n \u548c\u8fd4\u56de\u5730\u5740\u3002\u56e0\u6b64\uff0c\u5b83\u7684\u5185\u5b58\u590d\u6742\u5ea6\u662f O(1)\uff0c\u4e0e\u8f93\u5165\u53c2\u6570 n \u7684\u5927\u5c0f\u65e0\u5173\u3002\u6bcf\u4e2a\u9012\u5f52\u8c03\u7528\u90fd\u53ea\u9700\u8981\u5e38\u6570\u7ea7\u522b\u7684\u5185\u5b58\u7a7a\u95f4\u3002 \u9012\u5f52\u6590\u6ce2\u90a3\u5951\u51fd\u6570\u7684\u5185\u5b58\u590d\u6742\u5ea6\uff1a \u9012\u5f52\u6590\u6ce2\u90a3\u5951\u51fd\u6570\u7684\u5185\u5b58\u590d\u6742\u5ea6\u53d6\u51b3\u4e8e\u9012\u5f52\u7684\u6df1\u5ea6\u3002\u6bcf\u4e2a\u9012\u5f52\u8c03\u7528\u90fd\u9700\u8981\u4fdd\u5b58\u4e24\u4e2a\u6574\u6570\u53c2\u6570 n \u548c depth \uff0c\u4ee5\u53ca\u8fd4\u56de\u5730\u5740\u3002\u56e0\u6b64\uff0c\u6bcf\u6b21\u9012\u5f52\u8c03\u7528\u9700\u8981\u7684\u5185\u5b58\u7a7a\u95f4\u662f\u5e38\u6570\u7ea7\u522b\u7684\u3002 \u9012\u5f52\u6590\u6ce2\u90a3\u5951\u51fd\u6570\u7684\u9012\u5f52\u6df1\u5ea6\u53d6\u51b3\u4e8e\u8f93\u5165\u53c2\u6570 n \u3002\u5177\u4f53\u6765\u8bf4\uff0c\u9012\u5f52\u6df1\u5ea6\u7b49\u4e8e n \u3002\u56e0\u6b64\uff0c\u9012\u5f52\u6590\u6ce2\u90a3\u5951\u51fd\u6570\u7684\u5185\u5b58\u590d\u6742\u5ea6\u662f O(n)\uff0c\u4e0e\u8f93\u5165\u53c2\u6570 n \u6210\u6b63\u6bd4\u3002 \u603b\u7ed3\u6765\u8bf4\uff0c\u9012\u5f52\u9636\u4e58\u51fd\u6570\u7684\u5185\u5b58\u590d\u6742\u5ea6\u662f O(1)\uff0c\u800c\u9012\u5f52\u6590\u6ce2\u90a3\u5951\u51fd\u6570\u7684\u5185\u5b58\u590d\u6742\u5ea6\u662f O(n)\u3002\u5728\u9012\u5f52\u7b97\u6cd5\u4e2d\uff0c\u5185\u5b58\u590d\u6742\u5ea6\u901a\u5e38\u4e0e\u9012\u5f52\u6df1\u5ea6\u6210\u6b63\u6bd4\uff0c\u56e0\u6b64\u9700\u8981\u8c28\u614e\u5904\u7406\u9012\u5f52\u8c03\u7528\uff0c\u4ee5\u907f\u514d\u51fa\u73b0\u6808\u6ea2\u51fa\u7b49\u95ee\u9898\u3002\u53ef\u4ee5\u4f7f\u7528\u8fed\u4ee3\u6216\u52a8\u6001\u89c4\u5212\u7b49\u65b9\u6cd5\u6765\u964d\u4f4e\u5185\u5b58\u6d88\u8017\u3002","title":"3.10.\u7f16\u7a0b\u7ec3\u4e60"},{"location":"python/DataStructure/04_ArrayChain/","text":"4.\u6570\u7ec4\u548c\u94fe\u63a5\u7ed3\u6784 \u00b6 \u6570\u636e\u7ed3\u6784\uff08data structure\uff09\u6216\u5177\u4f53\u6570\u636e\u7c7b\u578b\uff08concrete data type\uff09\u662f\u6307\u4e00\u7ec4\u6570\u636e\u7684\u5185\u90e8\u5b58\u50a8\u65b9\u5f0f\u3002 \u6570\u7ec4\uff08array\uff09\u548c\u94fe\u63a5\u7ed3\u6784\uff08linked structure\uff09\u8fd9\u4e24\u79cd\u6570\u636e\u7ed3\u6784\u662f\u7f16\u7a0b\u8bed\u8a00\u91cc\u591a\u9879\u96c6\u6700\u5e38\u7528\u7684\u5b9e\u73b0\u3002 \u76ee\u6807\uff1a \u521b\u5efa\u6570\u7ec4\uff1b \u5bf9\u6570\u7ec4\u6267\u884c\u5404\u79cd\u64cd\u4f5c\uff1b \u786e\u5b9a\u6570\u7ec4\u76f8\u5173\u64cd\u4f5c\u7684\u8fd0\u884c\u65f6\u548c\u5185\u5b58\u7684\u4f7f\u7528\u60c5\u51b5\uff1b \u57fa\u4e8e\u6570\u7ec4\u5728\u8ba1\u7b97\u673a\u5185\u5b58\u91cc\u7684\u4e0d\u540c\u5b58\u50a8\u65b9\u5f0f\uff0c\u63cf\u8ff0\u6570\u7ec4\u76f8\u5173\u64cd\u4f5c\u7684\u6210\u672c\u548c\u6536\u76ca\uff1b \u4f7f\u7528\u5355\u5411\u94fe\u63a5\u8282\u70b9\u521b\u5efa\u94fe\u63a5\u7ed3\u6784\uff1b \u5bf9\u7531\u5355\u5411\u94fe\u63a5\u8282\u70b9\u6784\u6210\u7684\u94fe\u63a5\u7ed3\u6784\u6267\u884c\u5404\u79cd\u64cd\u4f5c\uff1b \u57fa\u4e8e\u94fe\u63a5\u7ed3\u6784\u5728\u8ba1\u7b97\u673a\u5185\u5b58\u91cc\u7684\u4e0d\u540c\u5b58\u50a8\u65b9\u5f0f\uff0c\u63cf\u8ff0\u5728\u94fe\u63a5\u7ed3\u6784\u4e0a\u6267\u884c\u76f8\u5173\u64cd\u4f5c\u7684\u6210\u672c\u548c\u6536\u76ca\uff1b \u6bd4\u8f83\u6570\u7ec4\u548c\u94fe\u63a5\u7ed3\u6784\u5728\u8fd0\u884c\u65f6\u548c\u5185\u5b58\u4f7f\u7528\u4e0a\u7684\u6743\u8861\uff1b 4.1.\u6570\u7ec4\u6570\u636e\u7ed3\u6784 \u00b6 \u5173\u4e8e\u6570\u7ec4\uff08array\uff09\uff1a \u6570\u7ec4\u662f\u6307\u5728\u7ed9\u5b9a\u7d22\u5f15\u4f4d\u7f6e\u53ef\u4ee5\u8bbf\u95ee\u548c\u66ff\u6362\u7684\u5143\u7d20\u5e8f\u5217\u3002 Python\u5217\u8868\u7684\u5e95\u5c42\u6570\u636e\u7ed3\u6784\u6b63\u662f\u4e00\u4e2a\u6570\u7ec4\u3002 Python\u4e2d\u6570\u7ec4\u7684\u9650\u5236\u8981\u6bd4\u5217\u8868\u66f4\u591a\u3002\u53ea\u80fd\u5728\u6307\u5b9a\u4f4d\u7f6e\u8bbf\u95ee\u548c\u66ff\u6362\u6570\u7ec4\u4e2d\u7684\u5143\u7d20\u3001\u68c0\u67e5\u6570\u7ec4\u7684\u957f\u5ea6\u3001\u83b7\u53d6\u5b83\u7684\u5b57\u7b26\u4e32\u8868\u8fbe\u5f0f\uff1b\u4e0d\u80fd\u57fa\u4e8e\u4f4d\u7f6e\u6dfb\u52a0\u6216\u5220\u9664\u5143\u7d20\uff1b\u6570\u7ec4\u7684\u957f\u5ea6\u4e5f\u5c31\u662f\u5b83\u7684\u5bb9\u91cf\uff0c\u5728\u521b\u5efa\u4e4b\u540e\u5c31\u662f\u56fa\u5b9a\u7684\u3002 4.1.1.\u968f\u673a\u8bbf\u95ee\u548c\u8fde\u7eed\u5185\u5b58 \u00b6 \u901a\u8fc7\u4e0b\u6807\u64cd\u4f5c\u6216\u7d22\u5f15\u64cd\u4f5c\u5b9e\u73b0\u5bf9\u6570\u7ec4\u5728\u6307\u5b9a\u4f4d\u7f6e\u5bf9\u5143\u7d20\u8fdb\u884c\u5b58\u50a8\u6216\u68c0\u7d22\u3002 \u6570\u7ec4\u7d22\u5f15\u662f\u968f\u673a\u8bbf\u95ee\uff08random access\uff09\u64cd\u4f5c\uff0c\u800c\u5728\u968f\u673a\u8bbf\u95ee\u65f6\uff0c\u8ba1\u7b97\u673a\u603b\u4f1a\u6267\u884c\u56fa\u5b9a\u7684\u6b65\u9aa4\u6765\u83b7\u53d6\u7b2c i \u4e2a\u5143\u7d20\u7684\u4f4d\u7f6e\u3002\u56e0\u6b64\uff0c\u4e0d\u8bba\u6570\u7ec4\u6709\u591a\u5927\uff0c\u8bbf\u95ee\u7b2c\u4e00\u4e2a\u5143\u7d20\u6240\u9700\u7684\u65f6\u95f4\u548c\u8bbf\u95ee\u6700\u540e\u4e00\u4e2a\u5143\u7d20\u6240\u9700\u8981\u7684\u65f6\u95f4\u90fd\u662f\u76f8\u540c\u7684\u3002 \u8ba1\u7b97\u673a\u901a\u8fc7\u5206\u914d\u4e00\u5757\u8fde\u7eed\u5185\u5b58\uff08contiguous memory\uff09\u5355\u5143\u6765\u5b58\u50a8\u6570\u7ec4\u91cc\u7684\u5143\u7d20\uff0c\u4ece\u800c\u652f\u6301\u5bf9\u6570\u7ec4\u7684\u968f\u673a\u8bbf\u95ee\u3002 \u7531\u4e8e\u6570\u7ec4\u91cc\u7684\u5143\u7d20\u5730\u5740\u90fd\u662f\u6309\u7167\u6570\u5b57\u987a\u5e8f\u8fdb\u884c\u6392\u5217\u7684\uff0c\u56e0\u6b64\u53ef\u4ee5\u901a\u8fc7\u6dfb\u52a0\u4e24\u4e2a\u503c\u6765\u8ba1\u7b97\u51fa\u6570\u7ec4\u5143\u7d20\u7684\u673a\u5668\u5730\u5740\uff0c\u5b83\u4eec\u662f\u6570\u7ec4\u7684\u57fa\u5730\u5740\uff08base address\uff09\u4ee5\u53ca\u5143\u7d20\u7684\u504f\u79fb\u91cf\uff08offset\uff09\u3002\u5176\u4e2d\uff0c\u6570\u7ec4\u7684\u57fa\u5730\u5740\u5c31\u662f\u7b2c\u4e00\u4e2a\u5143\u7d20\u7684\u673a\u5668\u5730\u5740\uff0c\u800c\u5143\u7d20\u7684\u504f\u79fb\u91cf\u5c31\u662f\u5b83\u7684\u7d22\u5f15\u503c\u518d\u4e58\u4ee5\u4e00\u4e2a\u4ee3\u8868\u6570\u7ec4\u5143\u7d20\u6240\u9700\u5185\u5b58\u5355\u5143\u6570\u7684\u5e38\u91cf\uff08\u5728Python\u91cc\uff0c\u8fd9\u4e2a\u503c\u59cb\u7ec8\u662f1\uff09\u3002 \u7b80\u800c\u8a00\u4e4b\uff0cPython\u6570\u7ec4\u91cc\u7684\u7d22\u5f15\u64cd\u4f5c\u5305\u62ec\u4e0b\u9762\u4e24\u4e2a\u6b65\u9aa4\uff1a \u5f97\u5230\u6570\u7ec4\u5185\u5b58\u5757\u7684\u57fa\u5730\u5740\u3002 \u5c06\u7d22\u5f15\u503c\u6dfb\u52a0\u5230\u8fd9\u4e2a\u5730\u5740\u5e76\u8fd4\u56de\u3002 4.1.2.\u9759\u6001\u5185\u5b58\u548c\u52a8\u6001\u5185\u5b58 \u00b6 \u5728\u6bd4\u8f83\u8001\u7684\u7f16\u7a0b\u8bed\u8a00\uff08\u5982FORTRAN\u6216Pascal\uff09\u91cc\uff0c\u6570\u7ec4\u662f\u9759\u6001\u6570\u636e\u7ed3\u6784\u3002\u5728\u8fd9\u79cd\u60c5\u51b5\u4e0b\uff0c\u6570\u7ec4\u7684\u957f\u5ea6\u6216\u5bb9\u91cf\u5728\u7f16\u8bd1\u65f6\u5c31\u786e\u5b9a\u4e86\uff0c\u7a0b\u5e8f\u5458\u9700\u8981\u7533\u8bf7\u8db3\u591f\u591a\u7684\u5185\u5b58\u6765\u6ee1\u8db3\u5728\u6570\u7ec4\u91cc\u5b58\u50a8\u53ef\u80fd\u6709\u6700\u5927\u6570\u91cf\u5143\u7d20\u7684\u60c5\u51b5\uff0c\u8fd9\u6837\u505a\u4f1a\u6d6a\u8d39\u5927\u91cf\u7684\u5185\u5b58\u3002 \u50cfJava\u548cC++\u8fd9\u7c7b\u7684\u73b0\u4ee3\u7f16\u7a0b\u8bed\u8a00\u4f1a\u5141\u8bb8\u7a0b\u5e8f\u5458\u521b\u5efa\u52a8\u6001\u6570\u7ec4\uff08dynamic array\uff09\uff0c\u4ece\u800c\u4e3a\u8fd9\u4e2a\u95ee\u9898\u63d0\u4f9b\u4e86\u4e00\u79cd\u8865\u6551\u65b9\u6cd5\u3002\u548c\u9759\u6001\u6570\u7ec4\u76f8\u4f3c\u7684\u662f\uff0c\u52a8\u6001\u6570\u7ec4\u4e5f\u4f1a\u5360\u7528\u4e00\u5757\u8fde\u7eed\u5185\u5b58\uff0c\u5e76\u652f\u6301\u968f\u673a\u8bbf\u95ee\u3002\u52a8\u6001\u6570\u7ec4\u7684\u957f\u5ea6\u53ea\u5728\u8fd0\u884c\u65f6\u624d\u77e5\u9053\uff0c\u5728\u52a8\u6001\u6570\u7ec4\u5b9e\u4f8b\u5316\u7684\u65f6\u5019\u6307\u5b9a\u5b83\u7684\u957f\u5ea6\u3002\u5728Python\u91cc\u5b9e\u73b0\u7684Array\u7c7b\u7684\u884c\u4e3a\u4e5f\u662f\u8fd9\u6837\u7684\u3002 \u6211\u4eec\u53ef\u4ee5\u901a\u8fc7\u53e6\u4e00\u79cd\u65b9\u6cd5\u5728\u8fd0\u884c\u65f6\u6839\u636e\u5e94\u7528\u7a0b\u5e8f\u7684\u6570\u636e\u8981\u6c42\u6765\u8c03\u6574\u6570\u7ec4\u7684\u957f\u5ea6\uff0c\u8fd9\u4e9b\u8c03\u6574\u4f1a\u7531Python\u5217\u8868\u81ea\u52a8\u8fdb\u884c\u3002\u8fd9\u65f6\uff0c\u6570\u7ec4\u6709\u4ee5\u4e0b3\u79cd\u4e0d\u540c\u5f62\u5f0f\u3002 \u5728\u7a0b\u5e8f\u542f\u52a8\u65f6\u521b\u5efa\u4e00\u4e2a\u5177\u6709\u5408\u7406\u9ed8\u8ba4\u5927\u5c0f\u7684\u6570\u7ec4\u3002 \u5f53\u6570\u7ec4\u65e0\u6cd5\u5bb9\u7eb3\u66f4\u591a\u6570\u636e\u65f6\uff0c\u521b\u5efa\u4e00\u4e2a\u66f4\u5927\u7684\u65b0\u6570\u7ec4\uff0c\u5e76\u628a\u65e7\u6570\u7ec4\u91cc\u7684\u6570\u636e\u5143\u7d20\u4f20\u8f93\u7ed9\u5b83\u3002 \u5982\u679c\u6570\u7ec4\u5728\u6d6a\u8d39\u5185\u5b58\uff08\u5e94\u7528\u7a0b\u5e8f\u5220\u9664\u4e86\u4e00\u4e9b\u6570\u636e\uff09\uff0c\u90a3\u4e48\u7528\u7c7b\u4f3c\u7684\u65b9\u5f0f\u51cf\u5c0f\u6570\u7ec4\u7684\u957f\u5ea6\u3002 4.1.3.\u7269\u7406\u5c3a\u5bf8\u548c\u903b\u8f91\u5c3a\u5bf8 \u00b6 \u6570\u7ec4\u7684\u7269\u7406\u5c3a\u5bf8\uff08physical size\uff09\u662f\u6307\u6570\u7ec4\u5355\u5143\u7684\u603b\u6570\uff0c\u6216\u8005\u521b\u5efa\u6570\u7ec4\u65f6\u6307\u5b9a\u5176\u5bb9\u91cf\u7684\u90a3\u4e2a\u6570\u5b57\uff1b \u6570\u7ec4\u7684\u903b\u8f91\u5c3a\u5bf8\uff08logical size\uff09\u662f\u6307\u5f53\u524d\u5e94\u7528\u7a0b\u5e8f\u4f7f\u7528\u7684\u5143\u7d20\u6570\u91cf\u3002 \u5f53\u6570\u7ec4\u88ab\u586b\u6ee1\u7684\u65f6\u5019\uff0c\u6211\u4eec\u4e0d\u9700\u8981\u62c5\u5fc3\u5b83\u4eec\u7684\u4e0d\u540c\u3002\u5f53\u6570\u7ec4\u88ab\u90e8\u5206\u586b\u6ee1\u7684\u65f6\u5019\uff0c\u672a\u88ab\u586b\u5145\u7684\u5185\u5b58\u5355\u5143\u91cc\u7684\u6570\u636e\u5bf9\u5f53\u524d\u5e94\u7528\u7a0b\u5e8f\u662f\u6ca1\u6709\u7528\u7684\uff0c\u6211\u4eec\u79f0\u4e4b\u5783\u573e\u5185\u5bb9\uff08garbage\uff09\u3002\u5728\u5927\u591a\u6570\u5e94\u7528\u7a0b\u5e8f\u91cc\uff0c\u6211\u4eec\u662f\u8981\u6ce8\u610f\u5bf9\u6570\u7ec4\u7684\u7269\u7406\u5c3a\u5bf8\u548c\u903b\u8f91\u5c3a\u5bf8\u8fdb\u884c\u8ffd\u8e2a\u3002\u901a\u5e38\u6765\u8bf4\uff0c\u903b\u8f91\u5c3a\u5bf8\u548c\u7269\u7406\u5c3a\u5bf8\u4f1a\u53cd\u6620\u51fa\u6709\u5173\u6570\u7ec4\u72b6\u6001\u7684\u51e0\u4e2a\u91cd\u70b9\u3002 \u5982\u679c\u903b\u8f91\u5c3a\u5bf8\u4e3a0\uff0c\u90a3\u4e48\u6570\u7ec4\u5c31\u4e3a\u7a7a\u3002\u4e5f\u5c31\u662f\u8bf4\uff0c\u8fd9\u4e2a\u6570\u7ec4\u4e0d\u5305\u542b\u4efb\u4f55\u6570\u636e\u5143\u7d20\u3002 \u5982\u679c\u5e76\u975e\u4e0a\u8ff0\u60c5\u51b5\uff0c\u5728\u4efb\u4f55\u60c5\u51b5\u4e0b\uff0c\u6570\u7ec4\u4e2d\u6700\u540e\u4e00\u4e2a\u5143\u7d20\u7684\u7d22\u5f15\u90fd\u662f\u5b83\u7684\u903b\u8f91\u5c3a\u5bf8\u51cf1\u3002 \u5982\u679c\u903b\u8f91\u5c3a\u5bf8\u7b49\u4e8e\u7269\u7406\u5c3a\u5bf8\uff0c\u90a3\u4e48\u8868\u793a\u6570\u7ec4\u5df2\u88ab\u586b\u6ee1\u4e86\u3002 4.1.4.\u7ec3\u4e60\u9898 \u00b6 1\uff0e\u8bf7\u8bf4\u660e\u968f\u673a\u8bbf\u95ee\u7684\u5de5\u4f5c\u539f\u7406\uff0c\u4ee5\u53ca\u8fd9\u4e2a\u64cd\u4f5c\u8fd9\u4e48\u5feb\u7684\u539f\u56e0\u3002 \u89e3\u7b54\uff1a\u968f\u673a\u8bbf\u95ee\u662f\u4e00\u79cd\u8ba1\u7b97\u673a\u5b58\u50a8\u7cfb\u7edf\u4e2d\u7684\u8bfb\u53d6\u6216\u5199\u5165\u6570\u636e\u7684\u64cd\u4f5c\uff0c\u5176\u4e2d\u6570\u636e\u53ef\u4ee5\u901a\u8fc7\u76f4\u63a5\u8df3\u8f6c\u5230\u5176\u5b58\u50a8\u4f4d\u7f6e\u800c\u4e0d\u9700\u8981\u987a\u5e8f\u626b\u63cf\u6765\u8bbf\u95ee\u3002\u8fd9\u4e0e\u987a\u5e8f\u8bbf\u95ee\u4e0d\u540c\uff0c\u540e\u8005\u9700\u8981\u6309\u987a\u5e8f\u904d\u5386\u6570\u636e\u4ee5\u627e\u5230\u6240\u9700\u7684\u4fe1\u606f\u3002\u968f\u673a\u8bbf\u95ee\u7684\u5de5\u4f5c\u539f\u7406\u5982\u4e0b\uff1a \u5b58\u50a8\u4ecb\u8d28\uff1a\u8ba1\u7b97\u673a\u5185\u5b58\u548c\u786c\u76d8\u7b49\u5b58\u50a8\u8bbe\u5907\u90fd\u652f\u6301\u968f\u673a\u8bbf\u95ee\u3002\u8fd9\u4e9b\u5b58\u50a8\u4ecb\u8d28\u4e2d\u7684\u6570\u636e\u901a\u5e38\u88ab\u5212\u5206\u4e3a\u5757\u6216\u6247\u533a\uff0c\u5e76\u4e14\u6bcf\u4e2a\u5757\u6216\u6247\u533a\u90fd\u6709\u4e00\u4e2a\u552f\u4e00\u7684\u5730\u5740\u6216\u7d22\u5f15\u3002 \u8bbf\u95ee\u5730\u5740\uff1a\u4e3a\u4e86\u8fdb\u884c\u968f\u673a\u8bbf\u95ee\uff0c\u8ba1\u7b97\u673a\u9700\u8981\u77e5\u9053\u8981\u8bbf\u95ee\u7684\u6570\u636e\u7684\u5730\u5740\u3002\u8fd9\u4e2a\u5730\u5740\u53ef\u4ee5\u662f\u5185\u5b58\u4e2d\u7684\u7279\u5b9a\u4f4d\u7f6e\uff0c\u4e5f\u53ef\u4ee5\u662f\u786c\u76d8\u4e0a\u7684\u67d0\u4e2a\u6247\u533a\u7684\u5730\u5740\u3002 \u5bfb\u5740\u548c\u4f20\u8f93\uff1a\u8ba1\u7b97\u673a\u4f7f\u7528\u5b58\u50a8\u8bbe\u5907\u7684\u63a7\u5236\u5668\u6216\u5b58\u50a8\u5668\u7ba1\u7406\u5355\u5143\u6765\u67e5\u627e\u6570\u636e\u7684\u5730\u5740\u3002\u4e00\u65e6\u627e\u5230\u4e86\u6b63\u786e\u7684\u5730\u5740\uff0c\u5b58\u50a8\u8bbe\u5907\u4f1a\u5c06\u6570\u636e\u4f20\u8f93\u5230\u8ba1\u7b97\u673a\u7684\u5185\u5b58\u4e2d\u4f9b\u5904\u7406\u5668\u4f7f\u7528\u3002 \u8bbf\u95ee\u901f\u5ea6\uff1a\u968f\u673a\u8bbf\u95ee\u4e4b\u6240\u4ee5\u5982\u6b64\u5feb\u901f\uff0c\u662f\u56e0\u4e3a\u8ba1\u7b97\u673a\u5185\u5b58\u548c\u73b0\u4ee3\u786c\u76d8\u9a71\u52a8\u5668\u7b49\u5b58\u50a8\u8bbe\u5907\u90fd\u7ecf\u8fc7\u4e86\u4f18\u5316\uff0c\u53ef\u4ee5\u5feb\u901f\u54cd\u5e94\u8bbf\u95ee\u8bf7\u6c42\u3002\u8fd9\u4e9b\u8bbe\u5907\u4f7f\u7528\u4e86\u9ad8\u901f\u7f13\u5b58\u3001\u8bfb\u5199\u5934\u3001\u5bfb\u9053\u673a\u6784\u7b49\u6280\u672f\u6765\u6700\u5c0f\u5316\u6570\u636e\u8bbf\u95ee\u7684\u5ef6\u8fdf\u3002 \u539f\u56e0\uff1a \u5b58\u50a8\u8bbe\u5907\u7684\u7269\u7406\u7ed3\u6784\uff1a\u8ba1\u7b97\u673a\u5185\u5b58\u548c\u786c\u76d8\u7b49\u5b58\u50a8\u8bbe\u5907\u7684\u7269\u7406\u7ed3\u6784\u88ab\u8bbe\u8ba1\u6210\u53ef\u4ee5\u968f\u673a\u8bbf\u95ee\u7684\u3002\u5185\u5b58\u4e2d\u7684\u6bcf\u4e2a\u5730\u5740\u90fd\u53ef\u4ee5\u77ac\u95f4\u8bbf\u95ee\uff0c\u800c\u786c\u76d8\u4e0a\u7684\u6247\u533a\u4e5f\u53ef\u4ee5\u901a\u8fc7\u78c1\u5934\u5bfb\u9053\u548c\u65cb\u8f6c\u78c1\u76d8\u7b49\u673a\u5236\u8fc5\u901f\u8bbf\u95ee\u3002 \u9ad8\u901f\u7f13\u5b58\uff1a\u73b0\u4ee3\u8ba1\u7b97\u673a\u5185\u5b58\u548c\u5904\u7406\u5668\u90fd\u914d\u5907\u4e86\u9ad8\u901f\u7f13\u5b58\uff08\u4f8b\u5982\uff0cCPU\u7f13\u5b58\uff09\u3002\u8fd9\u4e9b\u9ad8\u901f\u7f13\u5b58\u5b58\u50a8\u4e86\u6700\u8fd1\u8bbf\u95ee\u7684\u6570\u636e\uff0c\u53ef\u4ee5\u5feb\u901f\u63d0\u4f9b\u7ed9\u5904\u7406\u5668\uff0c\u4ece\u800c\u964d\u4f4e\u4e86\u8bbf\u95ee\u5ef6\u8fdf\u3002 \u5b58\u50a8\u5668\u7ba1\u7406\uff1a\u64cd\u4f5c\u7cfb\u7edf\u548c\u5b58\u50a8\u8bbe\u5907\u7684\u63a7\u5236\u5668\u4f1a\u7ba1\u7406\u5b58\u50a8\u5668\u7684\u8bbf\u95ee\uff0c\u4ee5\u786e\u4fdd\u6570\u636e\u53ef\u4ee5\u9ad8\u6548\u5730\u88ab\u8bbf\u95ee\u548c\u4f20\u8f93\u3002\u8fd9\u5305\u62ec\u4e86\u78c1\u76d8\u8c03\u5ea6\u7b97\u6cd5\u3001\u5185\u5b58\u5206\u9875\u7b49\u7b56\u7565\u3002 \u6280\u672f\u8fdb\u6b65\uff1a\u786c\u4ef6\u5236\u9020\u6280\u672f\u7684\u8fdb\u6b65\u548c\u5b58\u50a8\u8bbe\u5907\u7684\u4f18\u5316\u4f7f\u5f97\u968f\u673a\u8bbf\u95ee\u901f\u5ea6\u66f4\u5feb\u3002\u4f8b\u5982\uff0c\u56fa\u6001\u786c\u76d8\uff08SSD\uff09\u7684\u51fa\u73b0\u663e\u8457\u63d0\u9ad8\u4e86\u6570\u636e\u7684\u968f\u673a\u8bbf\u95ee\u901f\u5ea6\u3002 \u603b\u4e4b\uff0c\u968f\u673a\u8bbf\u95ee\u4e4b\u6240\u4ee5\u5982\u6b64\u5feb\u901f\uff0c\u662f\u56e0\u4e3a\u8ba1\u7b97\u673a\u5185\u5b58\u548c\u5b58\u50a8\u8bbe\u5907\u7684\u7269\u7406\u548c\u6280\u672f\u7279\u6027\u4f7f\u5176\u80fd\u591f\u4ee5\u9ad8\u6548\u3001\u8fc5\u901f\u7684\u65b9\u5f0f\u8bbf\u95ee\u6570\u636e\u3002\u8fd9\u79cd\u8bbf\u95ee\u901f\u5ea6\u5bf9\u4e8e\u8ba1\u7b97\u673a\u7684\u6027\u80fd\u548c\u54cd\u5e94\u65f6\u95f4\u81f3\u5173\u91cd\u8981\u3002 2\uff0e\u6570\u7ec4\u548cPython\u5217\u8868\u4e4b\u95f4\u6709\u4ec0\u4e48\u533a\u522b\uff1f \u89e3\u7b54\uff1a\u6570\u7ec4\u548cPython\u5217\u8868\u4e4b\u95f4\u6709\u51e0\u4e2a\u5173\u952e\u533a\u522b\uff0c\u8fd9\u4e9b\u533a\u522b\u5728\u6570\u636e\u7ed3\u6784\u3001\u529f\u80fd\u548c\u7528\u9014\u4e0a\u5b58\u5728\u5dee\u5f02\uff1a \u6570\u636e\u7c7b\u578b\uff1a \u6570\u7ec4\uff1a\u901a\u5e38\u8981\u6c42\u6240\u6709\u5143\u7d20\u5177\u6709\u76f8\u540c\u7684\u6570\u636e\u7c7b\u578b\u3002\u8fd9\u662f\u56e0\u4e3a\u6570\u7ec4\u5728\u5185\u5b58\u4e2d\u4ee5\u7d27\u51d1\u7684\u65b9\u5f0f\u5b58\u50a8\u6570\u636e\uff0c\u9700\u8981\u77e5\u9053\u6bcf\u4e2a\u5143\u7d20\u7684\u5927\u5c0f\u4ee5\u4fbf\u8fdb\u884c\u968f\u673a\u8bbf\u95ee\u3002 Python\u5217\u8868\uff1aPython\u7684\u5217\u8868\u53ef\u4ee5\u5bb9\u7eb3\u4e0d\u540c\u6570\u636e\u7c7b\u578b\u7684\u5143\u7d20\uff0c\u56e0\u4e3a\u5b83\u4eec\u662f\u52a8\u6001\u7c7b\u578b\u7684\u3002 \u5185\u5b58\u7ba1\u7406\uff1a \u6570\u7ec4\uff1a\u901a\u5e38\u5728\u521b\u5efa\u65f6\u9700\u8981\u6307\u5b9a\u56fa\u5b9a\u5927\u5c0f\uff0c\u56e0\u6b64\u5728\u5185\u5b58\u4e2d\u4f1a\u5206\u914d\u4e00\u5757\u8fde\u7eed\u7684\u7a7a\u95f4\uff0c\u8fd9\u4f7f\u5f97\u6570\u7ec4\u5bf9\u4e8e\u9ad8\u6548\u7684\u968f\u673a\u8bbf\u95ee\u975e\u5e38\u9002\u7528\u3002 Python\u5217\u8868\uff1aPython\u7684\u5217\u8868\u662f\u52a8\u6001\u7684\uff0c\u5b83\u4eec\u53ef\u4ee5\u6839\u636e\u9700\u8981\u81ea\u52a8\u6269\u5c55\u6216\u7f29\u5c0f\u3002\u8fd9\u5bfc\u81f4\u4e86\u4e00\u4e9b\u989d\u5916\u7684\u5185\u5b58\u5f00\u9500\uff0c\u56e0\u4e3a\u5217\u8868\u9700\u8981\u66f4\u591a\u7684\u7a7a\u95f4\u6765\u7ba1\u7406\u5143\u7d20\u7684\u6dfb\u52a0\u548c\u5220\u9664\u3002 \u6027\u80fd\uff1a \u6570\u7ec4\uff1a\u7531\u4e8e\u5185\u5b58\u5e03\u5c40\u8fde\u7eed\uff0c\u56e0\u6b64\u6570\u7ec4\u901a\u5e38\u5728\u8bbf\u95ee\u5143\u7d20\u65f6\u66f4\u5feb\u3002\u6570\u7ec4\u8fd8\u652f\u6301\u66f4\u591a\u7684\u5e95\u5c42\u64cd\u4f5c\uff0c\u5982\u4f4d\u64cd\u4f5c\u3002 Python\u5217\u8868\uff1aPython\u5217\u8868\u66f4\u52a0\u7075\u6d3b\uff0c\u4f46\u5728\u67d0\u4e9b\u60c5\u51b5\u4e0b\u53ef\u80fd\u4f1a\u5bfc\u81f4\u6027\u80fd\u4e0b\u964d\uff0c\u7279\u522b\u662f\u5f53\u6d89\u53ca\u5927\u91cf\u5143\u7d20\u7684\u63d2\u5165\u548c\u5220\u9664\u64cd\u4f5c\u65f6\u3002 \u64cd\u4f5c\u548c\u65b9\u6cd5\uff1a \u6570\u7ec4\uff1a\u901a\u5e38\u63d0\u4f9b\u4e00\u7ec4\u57fa\u672c\u64cd\u4f5c\uff0c\u5982\u8bfb\u53d6\u548c\u5199\u5165\u5143\u7d20\uff0c\u4ee5\u53ca\u4e00\u4e9b\u6570\u5b66\u8fd0\u7b97\uff0c\u5982\u5411\u91cf\u5316\u64cd\u4f5c\u3002 Python\u5217\u8868\uff1aPython\u5217\u8868\u63d0\u4f9b\u4e86\u66f4\u4e30\u5bcc\u7684\u65b9\u6cd5\u548c\u64cd\u4f5c\uff0c\u5305\u62ec\u5143\u7d20\u7684\u63d2\u5165\u3001\u5220\u9664\u3001\u8ffd\u52a0\u3001\u5207\u7247\u3001\u8fde\u63a5\u7b49\u3002 \u8bed\u8a00\u4f9d\u8d56\u6027\uff1a \u6570\u7ec4\uff1a\u6570\u7ec4\u901a\u5e38\u662f\u7f16\u7a0b\u8bed\u8a00\u7684\u4e00\u90e8\u5206\uff0c\u5177\u6709\u56fa\u5b9a\u7684\u8bed\u6cd5\u548c\u8bed\u4e49\u3002 Python\u5217\u8868\uff1aPython\u7684\u5217\u8868\u662fPython\u6807\u51c6\u5e93\u7684\u4e00\u90e8\u5206\uff0c\u4e0ePython\u7684\u52a8\u6001\u7279\u6027\u76f8\u9002\u5e94\u3002 \u9002\u7528\u573a\u666f\uff1a \u6570\u7ec4\uff1a\u9002\u7528\u4e8e\u9700\u8981\u9ad8\u6548\u968f\u673a\u8bbf\u95ee\u7684\u60c5\u51b5\uff0c\u5982\u6570\u503c\u8ba1\u7b97\u3001\u56fe\u50cf\u5904\u7406\u7b49\u3002 Python\u5217\u8868\uff1a\u9002\u7528\u4e8e\u66f4\u5e7f\u6cdb\u7684\u5e94\u7528\uff0c\u7279\u522b\u662f\u5728\u7f16\u5199Python\u4ee3\u7801\u65f6\uff0c\u56e0\u4e3a\u5b83\u4eec\u66f4\u7075\u6d3b\u4e14\u6613\u4e8e\u4f7f\u7528\u3002 \u603b\u4e4b\uff0c\u6570\u7ec4\u548cPython\u5217\u8868\u90fd\u6709\u81ea\u5df1\u7684\u4f18\u52bf\u548c\u9002\u7528\u573a\u666f\u3002\u9009\u62e9\u4f7f\u7528\u54ea\u79cd\u6570\u636e\u7ed3\u6784\u53d6\u51b3\u4e8e\u5177\u4f53\u7684\u9700\u6c42\u548c\u7f16\u7a0b\u8bed\u8a00\u3002\u5728Python\u4e2d\uff0c\u901a\u5e38\u4f1a\u4f18\u5148\u9009\u62e9\u4f7f\u7528\u5217\u8868\uff0c\u56e0\u4e3a\u5b83\u4eec\u66f4\u65b9\u4fbf\uff0c\u800c\u5728\u5176\u4ed6\u7f16\u7a0b\u8bed\u8a00\u4e2d\uff0c\u5982C\u6216Java\uff0c\u6570\u7ec4\u53ef\u80fd\u66f4\u4e3a\u5e38\u89c1\u3002 \u5728\u8fd9\u91cc\u9700\u8981\u8bf4\u660e\u4e00\u4e2a\u6982\u5ff5\u3002\u5728Python\u4e2d\uff0c\u672f\u8bed\"\u6570\u7ec4\"\u901a\u5e38\u6307\u7684\u662fNumPy\u5e93\u4e2d\u7684\u6570\u7ec4\u5bf9\u8c61\uff0c\u800c\"\u5217\u8868\"\u6307\u7684\u662fPython\u7684\u5185\u7f6e\u5217\u8868\uff08list\uff09\u6570\u636e\u7ed3\u6784\u3002\u8fd9\u4e24\u8005\u4e4b\u95f4\u6709\u4ee5\u4e0b\u533a\u522b\uff1a \u6570\u636e\u7c7b\u578b\uff1a \u6570\u7ec4\uff08NumPy\u6570\u7ec4\uff09\uff1aNumPy\u5e93\u63d0\u4f9b\u4e86\u4e00\u4e2a\u591a\u7ef4\u6570\u7ec4\u5bf9\u8c61\uff0c\u5b83\u53ef\u4ee5\u5305\u542b\u76f8\u540c\u6570\u636e\u7c7b\u578b\u7684\u5143\u7d20\uff0c\u5e76\u652f\u6301\u9ad8\u7ea7\u6570\u5b66\u3001\u79d1\u5b66\u548c\u5de5\u7a0b\u8ba1\u7b97\u3002NumPy\u6570\u7ec4\u7684\u5143\u7d20\u7c7b\u578b\u901a\u5e38\u662f\u56fa\u5b9a\u7684\uff0c\u4f8b\u5982\uff0c\u53ef\u4ee5\u662f\u6574\u6570\u3001\u6d6e\u70b9\u6570\u3001\u590d\u6570\u7b49\u3002\u8fd9\u4e9b\u6570\u7ec4\u662f\u9ad8\u6027\u80fd\u7684\uff0c\u652f\u6301\u5411\u91cf\u5316\u64cd\u4f5c\u3002 \u5217\u8868\uff08Python\u5217\u8868\uff09\uff1aPython\u7684\u5185\u7f6e\u5217\u8868\u662f\u4e00\u79cd\u901a\u7528\u7684\u3001\u52a8\u6001\u7c7b\u578b\u7684\u6570\u636e\u7ed3\u6784\uff0c\u53ef\u4ee5\u5305\u542b\u4e0d\u540c\u6570\u636e\u7c7b\u578b\u7684\u5143\u7d20\uff0c\u4f8b\u5982\u6574\u6570\u3001\u6d6e\u70b9\u6570\u3001\u5b57\u7b26\u4e32\u3001\u5bf9\u8c61\u7b49\u3002\u5217\u8868\u53ef\u4ee5\u52a8\u6001\u6269\u5c55\u548c\u7f29\u5c0f\uff0c\u5e76\u63d0\u4f9b\u4e86\u4e30\u5bcc\u7684\u5185\u7f6e\u65b9\u6cd5\u548c\u64cd\u4f5c\u3002 \u6027\u80fd\uff1a \u6570\u7ec4\uff08NumPy\u6570\u7ec4\uff09\uff1aNumPy\u6570\u7ec4\u901a\u5e38\u6bd4Python\u5217\u8868\u66f4\u9ad8\u6548\uff0c\u7279\u522b\u662f\u5728\u8fdb\u884c\u6570\u503c\u8ba1\u7b97\u548c\u79d1\u5b66\u8ba1\u7b97\u65f6\u3002\u5b83\u4eec\u5185\u90e8\u4f7f\u7528\u4e86C\u8bed\u8a00\u5b9e\u73b0\uff0c\u652f\u6301\u5411\u91cf\u5316\u64cd\u4f5c\uff0c\u56e0\u6b64\u5728\u5927\u89c4\u6a21\u6570\u636e\u5904\u7406\u4e2d\u901a\u5e38\u66f4\u5feb\u3002 \u5217\u8868\uff08Python\u5217\u8868\uff09\uff1aPython\u5217\u8868\u867d\u7136\u7075\u6d3b\uff0c\u4f46\u6027\u80fd\u76f8\u5bf9\u8f83\u4f4e\uff0c\u4e0d\u9002\u5408\u5927\u89c4\u6a21\u7684\u6570\u503c\u8ba1\u7b97\u3002\u5b83\u4eec\u7684\u5143\u7d20\u7c7b\u578b\u53ef\u4ee5\u4e0d\u540c\uff0c\u8fd9\u610f\u5473\u7740\u9700\u8981\u66f4\u591a\u7684\u5185\u5b58\u548c\u5904\u7406\u65f6\u95f4\u6765\u7ba1\u7406\u5143\u7d20\u3002 \u5e93\u4f9d\u8d56\uff1a \u6570\u7ec4\uff08NumPy\u6570\u7ec4\uff09\uff1a\u4f7f\u7528NumPy\u5e93\u9700\u8981\u5b89\u88c5NumPy\u6a21\u5757\u3002NumPy\u662fPython\u4e2d\u7528\u4e8e\u6570\u503c\u8ba1\u7b97\u7684\u6838\u5fc3\u5e93\uff0c\u5e7f\u6cdb\u5e94\u7528\u4e8e\u79d1\u5b66\u8ba1\u7b97\u3001\u673a\u5668\u5b66\u4e60\u7b49\u9886\u57df\u3002 \u5217\u8868\uff08Python\u5217\u8868\uff09\uff1aPython\u7684\u5185\u7f6e\u5217\u8868\u662fPython\u6807\u51c6\u5e93\u7684\u4e00\u90e8\u5206\uff0c\u65e0\u9700\u989d\u5916\u5b89\u88c5\u3002 \u529f\u80fd\uff1a \u6570\u7ec4\uff08NumPy\u6570\u7ec4\uff09\uff1aNumPy\u6570\u7ec4\u63d0\u4f9b\u4e86\u8bb8\u591a\u6570\u5b66\u548c\u79d1\u5b66\u8ba1\u7b97\u51fd\u6570\uff0c\u5982\u7ebf\u6027\u4ee3\u6570\u3001\u5085\u7acb\u53f6\u53d8\u6362\u3001\u7edf\u8ba1\u5206\u6790\u7b49\u3002\u5b83\u4eec\u9002\u7528\u4e8e\u5904\u7406\u5927\u91cf\u6570\u503c\u6570\u636e\u3002 \u5217\u8868\uff08Python\u5217\u8868\uff09\uff1aPython\u5217\u8868\u63d0\u4f9b\u4e86\u901a\u7528\u7684\u6570\u636e\u5bb9\u5668\uff0c\u7528\u4e8e\u5b58\u50a8\u548c\u7ba1\u7406\u5404\u79cd\u7c7b\u578b\u7684\u6570\u636e\uff0c\u4f46\u4e0d\u63d0\u4f9b\u4e13\u95e8\u7684\u6570\u5b66\u548c\u79d1\u5b66\u8ba1\u7b97\u529f\u80fd\u3002 \u5982\u679c\u9700\u8981\u8fdb\u884c\u6570\u503c\u8ba1\u7b97\u3001\u79d1\u5b66\u8ba1\u7b97\u6216\u6570\u636e\u5206\u6790\uff0c\u901a\u5e38\u4f1a\u4f7f\u7528NumPy\u6570\u7ec4\u3002\u5982\u679c\u53ea\u662f\u9700\u8981\u4e00\u4e2a\u901a\u7528\u7684\u6570\u636e\u5bb9\u5668\uff0c\u7528\u4e8e\u5b58\u50a8\u548c\u7ba1\u7406\u6570\u636e\uff0c\u90a3\u4e48Python\u5217\u8868\u901a\u5e38\u8db3\u591f\u4e86\u3002 3\uff0e\u8bf7\u8bf4\u660e\u6570\u7ec4\u7684\u7269\u7406\u5c3a\u5bf8\u548c\u903b\u8f91\u5c3a\u5bf8\u4e4b\u95f4\u7684\u533a\u522b\u3002 \u89e3\u7b54\uff1a\"\u7269\u7406\u5c3a\u5bf8\"\u548c\"\u903b\u8f91\u5c3a\u5bf8\"\u901a\u5e38\u7528\u4e8e\u63cf\u8ff0\u6570\u636e\u7ed3\u6784\u4e2d\u7684\u4e24\u4e2a\u4e0d\u540c\u65b9\u9762\uff1a \u7269\u7406\u5c3a\u5bf8\uff08Physical Size\uff09\uff1a \u7269\u7406\u5c3a\u5bf8\u662f\u6307\u6570\u636e\u7ed3\u6784\u5b9e\u9645\u5360\u7528\u7684\u5185\u5b58\u7a7a\u95f4\u6216\u5b58\u50a8\u4ecb\u8d28\u4e2d\u7684\u7a7a\u95f4\u5927\u5c0f\u3002 \u5b83\u8868\u793a\u6570\u636e\u7ed3\u6784\u5728\u8ba1\u7b97\u673a\u5185\u5b58\u6216\u78c1\u76d8\u4e2d\u6240\u5360\u636e\u7684\u5b9e\u9645\u5b57\u8282\u6570\u3002 \u7269\u7406\u5c3a\u5bf8\u4e0e\u6570\u636e\u7ed3\u6784\u7684\u5b58\u50a8\u65b9\u5f0f\u3001\u6570\u636e\u7c7b\u578b\u4ee5\u53ca\u8ba1\u7b97\u673a\u67b6\u6784\u6709\u5173\u3002 \u903b\u8f91\u5c3a\u5bf8\uff08Logical Size\uff09\uff1a \u903b\u8f91\u5c3a\u5bf8\u662f\u6307\u6570\u636e\u7ed3\u6784\u4e2d\u5305\u542b\u7684\u5143\u7d20\u6570\u91cf\u6216\u6570\u636e\u9879\u7684\u6570\u91cf\u3002 \u5b83\u8868\u793a\u6570\u636e\u7ed3\u6784\u5185\u90e8\u7684\u5143\u7d20\u6570\u91cf\u6216\u6570\u636e\u9879\u7684\u4e2a\u6570\uff0c\u4e0d\u6d89\u53ca\u5b9e\u9645\u7684\u5b58\u50a8\u5927\u5c0f\u3002 \u903b\u8f91\u5c3a\u5bf8\u901a\u5e38\u7528\u4e8e\u63cf\u8ff0\u6570\u636e\u7ed3\u6784\u7684\u5bb9\u91cf\u3001\u89c4\u6a21\u6216\u7ef4\u5ea6\u3002 \u8fd9\u4e24\u4e2a\u6982\u5ff5\u4e4b\u95f4\u7684\u5173\u7cfb\u5982\u4e0b\uff1a \u4e00\u4e2a\u6570\u636e\u7ed3\u6784\u53ef\u4ee5\u5177\u6709\u56fa\u5b9a\u7684\u7269\u7406\u5c3a\u5bf8\uff08\u5360\u636e\u56fa\u5b9a\u6570\u91cf\u7684\u5b57\u8282\uff09\uff0c\u4f46\u5176\u903b\u8f91\u5c3a\u5bf8\u53ef\u4ee5\u6839\u636e\u5b9e\u9645\u5b58\u50a8\u7684\u5143\u7d20\u6570\u91cf\u800c\u53d8\u5316\u3002 \u7269\u7406\u5c3a\u5bf8\u901a\u5e38\u662f\u7531\u8ba1\u7b97\u673a\u786c\u4ef6\u548c\u64cd\u4f5c\u7cfb\u7edf\u7ba1\u7406\u7684\uff0c\u800c\u903b\u8f91\u5c3a\u5bf8\u5219\u662f\u7a0b\u5e8f\u5458\u6839\u636e\u6570\u636e\u7ed3\u6784\u7684\u8bbe\u8ba1\u6765\u7ba1\u7406\u7684\u3002 \u4e3e\u4f8b\u6765\u8bf4\uff0c\u4e00\u4e2a\u6574\u6570\u6570\u7ec4\u53ef\u4ee5\u5177\u6709\u56fa\u5b9a\u7684\u7269\u7406\u5c3a\u5bf8\uff0c\u4f8b\u59824\u5b57\u8282/\u6574\u6570\uff0c\u4f46\u5b83\u7684\u903b\u8f91\u5c3a\u5bf8\u53ef\u4ee5\u662f\u6570\u7ec4\u4e2d\u6574\u6570\u7684\u6570\u91cf\uff0c\u53ef\u4ee5\u662f0\u4e2a\u300110\u4e2a\u3001100\u4e2a\u7b49\u7b49\u3002\u56e0\u6b64\uff0c\u903b\u8f91\u5c3a\u5bf8\u63cf\u8ff0\u4e86\u6570\u7ec4\u53ef\u4ee5\u5bb9\u7eb3\u7684\u5143\u7d20\u6570\u91cf\uff0c\u800c\u7269\u7406\u5c3a\u5bf8\u63cf\u8ff0\u4e86\u5b9e\u9645\u5360\u7528\u7684\u5185\u5b58\u7a7a\u95f4\u3002 \u5728\u6570\u636e\u7ed3\u6784\u7684\u8bbe\u8ba1\u548c\u4f7f\u7528\u4e2d\uff0c\u4e86\u89e3\u548c\u7ba1\u7406\u7269\u7406\u5c3a\u5bf8\u548c\u903b\u8f91\u5c3a\u5bf8\u5bf9\u4e8e\u6709\u6548\u5730\u5229\u7528\u8ba1\u7b97\u673a\u8d44\u6e90\u975e\u5e38\u91cd\u8981\u3002 4.2.\u6570\u7ec4\u7684\u64cd\u4f5c \u00b6 Python\u7684 array \u6a21\u5757\u5305\u542b\u4e00\u4e2a\u53eb\u4f5c array \u7684\u7c7b\uff0c\u5b83\u975e\u5e38\u7c7b\u4f3c\u4e8e\u5217\u8868\uff0c\u4f46\u662f\u53ea\u80fd\u5b58\u50a8\u6570\u5b57\u3002\u6211\u4eec\u4f1a\u5b9a\u4e49\u4e00\u4e2a\u53eb\u4f5c Array \u7684\u65b0\u7c7b\uff0c\u4f7f\u7528\u5217\u8868\u4fdd\u5b58\u5143\u7d20\uff0c\u5b58\u50a8\u4efb\u4f55\u7c7b\u578b\u7684\u5143\u7d20\u3002 \u4e0b\u9762\u7684\u793a\u4f8b\u5b9a\u4e49\u4e86\u4e00\u4e2a\u6570\u7ec4\u7c7b Array \uff0c\u4e0b\u9762\u5bf9\u6570\u7ec4\u7684\u4e00\u4e9b\u64cd\u4f5c\u7684\u4ee3\u7801\u5b9e\u73b0\u4e5f\u5df2\u7ecf\u5305\u542b\u5728\u4e0b\u9762\u7684\u4ee3\u7801\u4e2d\u3002\u5176\u4e2d\uff1a \u6570\u7ec4\u9ed8\u8ba4\u7684\u7269\u7406\u5c3a\u5bf8\uff08\u4e5f\u5c31\u662f\u5bb9\u91cf\uff09\u662f5 \u6570\u7ec4\u7684\u521d\u59cb\u903b\u8f91\u5c3a\u5bf8\u662f0 class Array ( object ): \"\"\"\u63cf\u8ff0\u4e00\u4e2a\u6570\u7ec4\u3002\"\"\" def __init__ ( self , capacity , fillValue = None ): \"\"\"Capacity\u662f\u6570\u7ec4\u7684\u5927\u5c0f. fillValue\u4f1a\u586b\u5145\u5728\u6bcf\u4e2a\u5143\u7d20\u4f4d\u7f6e, \u9ed8\u8ba4\u503c\u662fNone\"\"\" # \u521d\u59cb\u5316\u6570\u7ec4\u7684\u903b\u8f91\u5c3a\u5bf8\u548c\u7269\u7406\u5c3a\u5bf8 self . logicalSize = 0 self . capacity = capacity self . fillValue = fillValue #\u521d\u59cb\u5316\u5185\u90e8\u6570\u7ec4\uff0c\u5e76\u586b\u5145\u5143\u7d20\u503c self . items = list () for count in range ( capacity ): self . items . append ( fillValue ) self . logicalSize += 1 # \u521d\u59cb\u5316\u6570\u7ec4\u7269\u7406\u5927\u5c0f\u65f6\uff0c\u4e5f\u540c\u65f6\u521d\u59cb\u5316\u5176\u903b\u8f91\u5927\u5c0f def __len__ ( self ): \"\"\"\u8fd4\u56de\u6570\u7ec4\u7684\u5927\u5c0f\"\"\" return len ( self . items ) def __str__ ( self ): \"\"\"\u5c06\u6570\u7ec4\u5b57\u7b26\u4e32\u5316\u5e76\u8fd4\u56de\"\"\" result = \"\" for index in range ( self . size ()): result += str ( self . items [ index ]) + \" \" return result def size ( self ): \"\"\"\u8fd4\u56de\u6570\u7ec4\u7684\u903b\u8f91\u5c3a\u5bf8\"\"\" return self . logicalSize def __iter__ ( self ): \"\"\"\u652f\u6301for\u5faa\u73af\u5bf9\u6570\u7ec4\u8fdb\u884c\u904d\u5386.\"\"\" print ( \"__iter__ called\" ) # \u4ec5\u7528\u6765\u6d4b\u8bd5\u4f55\u65f6__iter__\u4f1a\u88ab\u8c03\u7528 return iter ( self . items ) def __getitem__ ( self , index ): \"\"\" \u7528\u4e8e\u8bbf\u95ee\u7d22\u5f15\u5904\u7684\u4e0b\u6807\u8fd0\u7b97\u7b26. \u5148\u51b3\u6761\u4ef6: 0 <= index < size() \"\"\" if index < 0 or index >= self . size (): raise IndexError ( \"\u8bfb\u53d6\u64cd\u4f5c\u51fa\u9519, \u6570\u7ec4\u7d22\u5f15\u8d8a\u754c(\u4e0d\u5728\u6570\u7ec4\u903b\u8f91\u8fb9\u754c\u8303\u56f4\u5185)\" ) return self . items [ index ] def __setitem__ ( self , index , newItem ): \"\"\" \u4e0b\u6807\u8fd0\u7b97\u7b26\u7528\u4e8e\u5728\u7d22\u5f15\u5904\u8fdb\u884c\u66ff\u6362. \u5148\u51b3\u6761\u4ef6: 0 <= index < size() \"\"\" if index < 0 or index >= self . size (): raise IndexError ( \"\u66f4\u65b0\u64cd\u4f5c\u51fa\u9519, \u6570\u7ec4\u7d22\u5f15\u8d8a\u754c(\u4e0d\u5728\u6570\u7ec4\u903b\u8f91\u8fb9\u754c\u8303\u56f4\u5185)\" ) self . items [ index ] = newItem def __eq__ ( self , other ): \"\"\" \u4e24\u4e2a\u6570\u7ec4\u76f8\u7b49\u5219\u8fd4\u56deTrue\uff0c\u5426\u5219\u8fd4\u56deFalse \"\"\" # \u5224\u65ad\u4e24\u4e2a\u6570\u7ec4\u662f\u5426\u662f\u540c\u4e00\u4e2a\u5bf9\u8c61\uff0c\u6ce8\u610f\uff0c\u4e0d\u662f\u5b83\u4eec\u7684\u503c\u662f\u5426\u76f8\u7b49 if self is other : return True # \u5224\u65ad\u4e24\u4e2a\u5bf9\u8c61\u7c7b\u578b\u662f\u5426\u4e00\u6837 if type ( self ) != type ( other ): return False # \u5224\u65ad\u4e24\u4e2a\u6570\u7ec4\u5927\u5c0f\u662f\u5426\u4e00\u6837 if self . size () != other . size (): return False # \u6bd4\u8f83\u4e24\u4e2a\u6570\u7ec4\u7684\u503c\u662f\u5426\u4e00\u6837 for index in range ( self . size ()): if self [ index ] != other [ index ]: return False return True def grow ( self ): \"\"\"\u589e\u5927\u6570\u7ec4\u7269\u7406\u5c3a\u5bf8\"\"\" # \u57fa\u4e8e\u5f53\u524d\u7269\u7406\u5c3a\u5bf8\u52a0\u500d\uff0c\u5e76\u5c06fillValue\u8d4b\u503c\u5e95\u5c42\u5217\u8868\u7684\u65b0\u5143\u7d20 for count in range ( len ( self )): self . items . append ( self . fillValue ) def insert ( self , index , newItem ): \"\"\"\u5728\u6570\u7ec4\u6307\u5b9a\u7d22\u5f15\u5904\u63d2\u5165\u65b0\u5143\u7d20\"\"\" # \u5f53\u6570\u7ec4\u7684\u7269\u7406\u5c3a\u5bf8\u548c\u903b\u8f91\u5c3a\u5bf8\u4e00\u6837\u65f6\uff0c\u5219\u589e\u52a0\u7269\u7406\u5c3a\u5bf8 if self . size () == len ( self ): self . grow () # \u63d2\u5165\u65b0\u5143\u7d20 # \u5f53\u63d2\u5165\u4f4d\u7f6e\u5927\u4e8e\u6216\u7b49\u4e8e\u6700\u5927\u903b\u8f91\u4f4d\u7f6e\uff0c\u5219\u5728\u6570\u7ec4\u672b\u7aef\u63d2\u5165\u65b0\u5143\u7d20 # \u5f53\u63d2\u5165\u4f4d\u7f6e\u4ecb\u4e8e\u6570\u7ec4\u903b\u8f91\u4f4d\u7f6e\u7684\u4e2d\u95f4\uff0c\u5219\u4ece\u63d2\u5165\u4f4d\u7f6e\u8d77\u5c06\u5269\u4f59\u6570\u7ec4\u5143\u7d20\u5411\u5c3e\u90e8\u5e73\u79fb\u4e00\u4e2a\u4f4d\u7f6e if index >= self . size (): self . items [ self . size ()] = newItem else : index = max ( index , 0 ) # \u5c06\u6570\u7ec4\u5143\u7d20\u5411\u5c3e\u90e8\u5e73\u79fb\u4e00\u4e2a\u4f4d\u7f6e for i in range ( self . size (), index , - 1 ): self . items [ i ] = self . items [ i - 1 ] # \u63d2\u5165\u65b0\u5143\u7d20 self . items [ index ] = newItem # \u589e\u52a0\u6570\u7ec4\u7684\u903b\u8f91\u5c3a\u5bf8 self . logicalSize += 1 def shrink ( self ): \"\"\" \u51cf\u5c11\u6570\u7ec4\u7684\u7269\u7406\u5c3a\u5bf8 \u5f53: - \u6570\u7ec4\u7684\u903b\u8f91\u5c3a\u5bf8\u5c0f\u4e8e\u6216\u7b49\u4e8e\u5176\u7269\u7406\u5c3a\u5bf8\u76841/4 - \u5e76\u4e14\u5b83\u7684\u7269\u7406\u5c3a\u5bf8\u81f3\u5c11\u662f\u8fd9\u4e2a\u6570\u7ec4\u5efa\u7acb\u65f6\u9ed8\u8ba4\u5bb9\u91cf\u76842\u500d\u65f6 \u5219\u628a\u6570\u7ec4\u7684\u7269\u7406\u5c3a\u5bf8\u51cf\u5c0f\u5230\u539f\u6765\u7684\u4e00\u534a\uff0c\u5e76\u4e14\u4e5f\u4e0d\u4f1a\u5c0f\u4e8e\u5176\u9ed8\u8ba4\u5bb9\u91cf \"\"\" # \u5728\u903b\u8f91\u5c3a\u5bf8\u548c\u7269\u7406\u5c3a\u5bf8\u7684\u4e00\u534a\u4e4b\u95f4\u9009\u62e9\u6700\u5927\u503c\u4f5c\u4e3a\u6570\u7ec4\u6536\u7f29\u540e\u7684\u7269\u7406\u5c3a\u5bf8 newSize = max ( self . capacity , len ( self ) // 2 ) # \u91ca\u653e\u591a\u4f59\u7684\u6570\u7ec4\u7a7a\u95f4 for count in range ( len ( self ) - newSize ): self . items . pop () def pop ( self , index ): \"\"\" \u5220\u9664\u6307\u5b9a\u7d22\u5f15\u503c\u7684\u6570\u7ec4\u5143\u7d20,\u5e76\u8fd4\u56de\u5220\u9664\u7684\u6570\u7ec4\u5143\u7d20\u503c \u5148\u51b3\u6761\u4ef6: 0 <= index < size() \"\"\" if index < 0 or index >= self . size (): raise IndexError ( \"\u5220\u9664\u64cd\u4f5c\u51fa\u9519, \u6570\u7ec4\u7d22\u5f15\u8d8a\u754c(\u4e0d\u5728\u6570\u7ec4\u903b\u8f91\u8fb9\u754c\u8303\u56f4\u5185)\" ) # \u4fdd\u5b58\u5373\u5c06\u88ab\u5220\u9664\u7684\u6570\u7ec4\u5143\u7d20\u503c itemToReturn = self . items [ index ] # \u5c06\u6570\u7ec4\u5143\u7d20\u5411\u5934\u90e8\u5e73\u79fb\u4e00\u4e2a\u4f4d\u7f6e for i in range ( index , self . size () - 1 ): self . items [ i ] = self . items [ i + 1 ] # \u5c06\u6570\u7ec4\u5c3e\u90e8\u7684\u7a7a\u4f59\u4f4d\u8d4b\u503cfillValue\uff0c\u9ed8\u8ba4\u662fNone self . items [ self . size () - 1 ] = self . fillValue # \u51cf\u5c11\u6570\u7ec4\u903b\u8f91\u5c3a\u5bf8 self . logicalSize -= 1 # \u51cf\u5c11\u6570\u7ec4\u7269\u7406\u5c3a\u5bf8 # \u5f53: # - \u6570\u7ec4\u7684\u903b\u8f91\u5c3a\u5bf8\u5c0f\u4e8e\u6216\u7b49\u4e8e\u5176\u7269\u7406\u5c3a\u5bf8\u76841/4 # - \u5e76\u4e14\u5b83\u7684\u7269\u7406\u5c3a\u5bf8\u81f3\u5c11\u662f\u8fd9\u4e2a\u6570\u7ec4\u5efa\u7acb\u65f6\u9ed8\u8ba4\u5bb9\u91cf\u76842\u500d\u65f6 # \u5219\u628a\u6570\u7ec4\u7684\u7269\u7406\u5c3a\u5bf8\u51cf\u5c0f\u5230\u539f\u6765\u7684\u4e00\u534a\uff0c\u5e76\u4e14\u4e5f\u4e0d\u4f1a\u5c0f\u4e8e\u5176\u9ed8\u8ba4\u5bb9\u91cf if self . size () <= len ( self ) // 4 and len ( self ) > self . capacity : self . shrink () # \u8fd4\u56de\u88ab\u5220\u9664\u5143\u7d20\u7684\u503c print ( f 'Item { itemToReturn } was deleted' ) return itemToReturn def main (): # \u521d\u59cb\u5316\u7a7a\u6570\u7ec4 DEFAULT_CAPACITY = 5 my_arr = Array ( DEFAULT_CAPACITY ) # \u6253\u5370\u8f93\u51fa\u6570\u7ec4\u521d\u59cb\u4fe1\u606f print ( \"Physical size:\" , len ( my_arr )) print ( \"Logical size:\" , my_arr . size ()) print ( \"Initial items:\" , my_arr . items ) # \u521d\u59cb\u5316\u6570\u7ec4\u5143\u7d20 print ( '------' ) for item in range ( 4 ): my_arr . insert ( 0 , item ) # \u5728\u6570\u7ec4\u5934\u90e8\u63d2\u5165\uff0c\u6bcf\u63d2\u5165\u4e00\u6b21\u90fd\u9700\u8981\u5411\u540e\u79fb\u52a8\u5df2\u6709\u6570\u7ec4\u5143\u7d20 print ( \"Items(logical):\" , my_arr ) print ( \"Items(physical):\" , my_arr . items ) # \u5728\u6570\u7ec4\u4e2d\u95f4\u63d2\u5165\u65b0\u5143\u7d20 print ( '------' ) my_arr . insert ( 3 , 99 ) print ( \"Items(logical):\" , my_arr ) print ( \"Items(physical):\" , my_arr . items ) # \u5728\u6570\u7ec4\u903b\u8f91\u5c3a\u5bf8\u5916\u63d2\u5165\u65b0\u5143\u7d20 print ( '------' ) my_arr . insert ( 20 , 88 ) print ( \"Items(logical):\" , my_arr ) print ( \"Items(physical):\" , my_arr . items ) # \u5220\u9664\u6570\u7ec4\u5143\u7d20 print ( '------' ) my_arr . pop ( 3 ) my_arr . pop ( 3 ) print ( \"Items(logical):\" , my_arr ) print ( \"Items(physical):\" , my_arr . items ) # \u6e05\u7a7a\u6570\u7ec4\u5143\u7d20 print ( '------' ) for count in range ( my_arr . size ()): my_arr . pop ( 0 ) print ( \"Items(logical):\" , my_arr ) print ( \"Items(physical):\" , my_arr . items ) # \u6570\u7ec4\u5143\u7d20\u5df2\u7ecf\u5168\u90e8\u5220\u9664\uff0c\u903b\u8f91\u5c3a\u5bf8\u4e3a\u96f6\uff0c\u4e0b\u9762\u547d\u4ee4\u8fd4\u56de\u9519\u8bef # print('------') # print(my_arr.pop(0)) # \u6570\u7ec4\u6bd4\u8f83 # \u521d\u59cb\u5316\u6570\u7ec4 print ( '------' ) arr_a = Array ( 5 ) for item in range ( 4 ): arr_a . insert ( 0 , item ) arr_b = arr_a arr_c = Array ( 5 ) for item in range ( 4 ): arr_c . insert ( 0 , item ) arr_d = [] print ( \"arr_a(physical):\" , arr_a . items ) print ( \"arr_b(physical):\" , arr_b . items ) print ( \"arr_c(physical):\" , arr_c . items ) print ( \"arr_d(physical):\" , arr_d ) print ( \"arr_a == arr_b:\" , arr_a == arr_b ) print ( \"arr_a is arr_b:\" , arr_a is arr_b ) print ( \"arr_a == arr_c:\" , arr_a == arr_c ) print ( \"arr_a is arr_c:\" , arr_a is arr_c ) arr_c . insert ( 10 , 10 ) print ( \"arr_a == arr_c:\" , arr_a == arr_c ) arr_c . pop ( arr_c . size () - 1 ) arr_c [ 2 ] = 6 print ( \"arr_a == arr_c:\" , arr_a == arr_c ) print ( \"arr_a == arr_d:\" , arr_a == arr_d ) if __name__ == \"__main__\" : main () # \u8fd0\u884c\u7ed3\u679c # Physical size: 5 # Logical size: 0 # Initial items: [None, None, None, None, None] # ------ # Items(logical): 3 2 1 0 # Items(physical): [3, 2, 1, 0, None] # ------ # Items(logical): 3 2 1 99 0 # Items(physical): [3, 2, 1, 99, 0] # ------ # Items(logical): 3 2 1 99 0 88 # Items(physical): [3, 2, 1, 99, 0, 88, None, None, None, None] # ------ # Item 99 was deleted # Item 0 was deleted # Items(logical): 3 2 1 88 # Items(physical): [3, 2, 1, 88, None, None, None, None, None, None] # ------ # Item 3 was deleted # Item 2 was deleted # Item 1 was deleted # Item 88 was deleted # Items(logical): # Items(physical): [None, None, None, None, None] # ------ # IndexError: \u5220\u9664\u64cd\u4f5c\u51fa\u9519, \u6570\u7ec4\u7d22\u5f15\u8d8a\u754c(\u4e0d\u5728\u6570\u7ec4\u903b\u8f91\u8fb9\u754c\u8303\u56f4\u5185) # ------ # arr_a(physical): [3, 2, 1, 0, None] # arr_b(physical): [3, 2, 1, 0, None] # arr_c(physical): [3, 2, 1, 0, None] # arr_d(physical): [] # arr_a == arr_b: True # arr_a is arr_b: True # arr_a == arr_c: True # arr_a is arr_c: False # arr_a == arr_c: False # Item 10 was deleted # arr_a == arr_c: False # arr_a == arr_d: False 4.2.1.\u589e\u5927\u6570\u7ec4\u7684\u5c3a\u5bf8 \u00b6 \u5f53\u6570\u7ec4\u7684\u903b\u8f91\u5c3a\u5bf8\u7b49\u4e8e\u5b83\u7684\u7269\u7406\u5c3a\u5bf8\u65f6\uff0c\u5982\u679c\u8981\u63d2\u5165\u65b0\u7684\u5143\u7d20\uff0c\u5c31\u9700\u8981\u589e\u5927\u6570\u7ec4\u7684\u7269\u7406\u5c3a\u5bf8\u3002 \u5982\u679c\u9700\u8981\u4e3a\u6570\u7ec4\u63d0\u4f9b\u66f4\u591a\u5185\u5b58\uff0cPython\u7684list\u7c7b\u578b\u4f1a\u5728\u8c03\u7528insert\u6216append\u65b9\u6cd5\u65f6\u6267\u884c\u8fd9\u4e2a\u64cd\u4f5c\u3002 \u8c03\u6574\u6570\u7ec4\u7269\u7406\u5c3a\u5bf8\u7684\u8fc7\u7a0b\u5305\u542b\u5982\u4e0b3\u4e2a\u6b65\u9aa4\u3002 \u521b\u5efa\u4e00\u4e2a\u66f4\u5927\u7684\u65b0\u6570\u7ec4\u3002 \u5c06\u6570\u636e\u4ece\u65e7\u6570\u7ec4\u4e2d\u590d\u5236\u5230\u65b0\u6570\u7ec4\u3002 \u5c06\u6307\u5411\u65e7\u6570\u7ec4\u7684\u53d8\u91cf\u6307\u5411\u65b0\u6570\u7ec4\u5bf9\u8c61\u3002 \u4e0b\u9762\u4ee3\u7801\u5b9e\u73b0\u3002 # \u589e\u5927\u6570\u7ec4\u7269\u7406\u5c3a\u5bf8 if logicalSize == len ( my_array ): temp = Array ( len ( my_array ) + 1 ) # \u521b\u5efa\u4e00\u4e2a\u65b0\u6570\u7ec4 for i in range ( logicalSize ): temp [ i ] = my_array [ i ] # \u4ece\u539f\u6570\u7ec4\u590d\u5236\u5185\u5bb9\u5230\u65b0\u6570\u7ec4 my_array = temp # \u628a\u65b0\u6570\u7ec4\u8d4b\u503c\u7ed9\u539f\u6570\u7ec4 \u5728\u4e0a\u9762\u4ee3\u7801\u4e2d\uff0c\u901a\u8fc7 temp[i] = my_array[i] \u6765\u8c03\u6574\u6570\u7ec4\u5c3a\u5bf8\uff0c\u8fd9\u4e2a\u590d\u5236\u64cd\u4f5c\u7684\u6570\u91cf\u662f\u7ebf\u6027\u589e\u957f\u7684\u3002\u56e0\u6b64\uff0c\u5c06 n \u4e2a\u5143\u7d20\u6dfb\u52a0\u5230\u6570\u7ec4\u91cc\u7684\u603b\u65f6\u95f4\u590d\u6742\u5ea6\u662f 1+2+3...+n \uff0c\u4e5f\u5c31\u662f n(n+1)/2 \uff0c\u56e0\u6b64\u662f O(n^2) \u3002 \u5728\u4e0a\u9762\u7684\u4ee3\u7801\u4e2d\uff0c\u901a\u8fc7 temp = Array(len(my_array) + 1) \u5bf9\u6570\u7ec4\u8fdb\u884c\u52a8\u6001\u6269\u5c55\uff0c\u5bf9\u6027\u80fd\u4f1a\u4ea7\u751f\u4e00\u4e9b\u53ef\u80fd\u7684\u5f71\u54cd\uff1a \u65f6\u95f4\u590d\u6742\u5ea6\uff1a\u52a8\u6001\u6269\u5c55\u6570\u7ec4\u901a\u5e38\u9700\u8981\u590d\u5236\u73b0\u6709\u6570\u636e\u5230\u65b0\u7684\u5185\u5b58\u4f4d\u7f6e\uff0c\u8fd9\u5c06\u6d89\u53ca\u5230\u5143\u7d20\u7684\u590d\u5236\u64cd\u4f5c\u3002\u8fd9\u4e9b\u64cd\u4f5c\u7684\u65f6\u95f4\u590d\u6742\u5ea6\u53d6\u51b3\u4e8e\u6570\u7ec4\u7684\u957f\u5ea6\uff0c\u901a\u5e38\u662f O(n) \uff0c\u5176\u4e2d n \u662f\u6570\u7ec4\u7684\u957f\u5ea6\u3002\u56e0\u6b64\uff0c\u5f53\u6570\u7ec4\u9700\u8981\u6269\u5c55\u65f6\uff0c\u53ef\u80fd\u4f1a\u4ea7\u751f\u4e00\u4e9b\u989d\u5916\u7684\u65f6\u95f4\u5f00\u9500\u3002 \u7a7a\u95f4\u590d\u6742\u5ea6\uff1a\u52a8\u6001\u6269\u5c55\u6570\u7ec4\u4f1a\u5360\u7528\u989d\u5916\u7684\u5185\u5b58\u7a7a\u95f4\uff0c\u56e0\u4e3a\u9700\u8981\u5206\u914d\u65b0\u7684\u5185\u5b58\u5757\u6765\u5bb9\u7eb3\u6269\u5c55\u540e\u7684\u6570\u7ec4\u3002\u8fd9\u53ef\u80fd\u4f1a\u5bfc\u81f4\u5185\u5b58\u788e\u7247\u5316\uff0c\u7279\u522b\u662f\u5728\u9891\u7e41\u6269\u5c55\u548c\u7f29\u5c0f\u6570\u7ec4\u65f6\u3002 \u6269\u5c55\u9891\u7387\uff1a\u6269\u5c55\u6570\u7ec4\u7684\u9891\u7387\u4f1a\u5f71\u54cd\u6027\u80fd\u3002\u5982\u679c\u6570\u7ec4\u9700\u8981\u9891\u7e41\u6269\u5c55\uff0c\u90a3\u4e48\u590d\u5236\u548c\u5185\u5b58\u5206\u914d\u7684\u5f00\u9500\u4f1a\u66f4\u52a0\u663e\u8457\uff0c\u4ece\u800c\u964d\u4f4e\u6027\u80fd\u3002\u56e0\u6b64\uff0c\u5728\u8bbe\u8ba1\u6570\u636e\u7ed3\u6784\u65f6\uff0c\u901a\u5e38\u4f1a\u8003\u8651\u521d\u59cb\u5bb9\u91cf\u548c\u6269\u5c55\u7b56\u7565\uff0c\u4ee5\u51cf\u5c11\u4e0d\u5fc5\u8981\u7684\u6269\u5c55\u6b21\u6570\u3002 Amortized Analysis\uff1a\u4e00\u4e9b\u6570\u636e\u7ed3\u6784\uff0c\u4f8b\u5982Python\u7684\u5217\u8868\uff08list\uff09\uff0c\u91c7\u7528\u644a\u8fd8\u5206\u6790\u6765\u5e73\u644a\u52a8\u6001\u6269\u5c55\u7684\u5f00\u9500\u3002\u8fd9\u610f\u5473\u7740\u867d\u7136\u67d0\u4e9b\u64cd\u4f5c\u53ef\u80fd\u4f1a\u82b1\u8d39 O(n) \u7684\u65f6\u95f4\uff0c\u4f46\u8fd9\u4e9b\u5f00\u9500\u5728\u4e00\u7cfb\u5217\u64cd\u4f5c\u4e2d\u88ab\u5206\u644a\uff0c\u5e73\u5747\u4e0b\u6765\u4ecd\u7136\u4fdd\u6301\u8f83\u4f4e\u7684\u590d\u6742\u5ea6\u3002\u8fd9\u53ef\u4ee5\u5728\u4e00\u5b9a\u7a0b\u5ea6\u4e0a\u7f13\u89e3\u6027\u80fd\u95ee\u9898\u3002 \u52a8\u6001\u6269\u5c55\u6570\u7ec4\u4f1a\u5f15\u5165\u4e00\u4e9b\u6027\u80fd\u5f00\u9500\uff0c\u4f46\u5728\u5b9e\u9645\u5e94\u7528\u4e2d\uff0c\u8fd9\u79cd\u5f00\u9500\u901a\u5e38\u662f\u53ef\u4ee5\u63a5\u53d7\u7684\u3002\u4e3a\u4e86\u4f18\u5316\u6027\u80fd\uff0c\u53ef\u4ee5\u8003\u8651\u4ee5\u4e0b\u51e0\u70b9\u7b56\u7565\uff0c\u9700\u8981\u6839\u636e\u5177\u4f53\u5e94\u7528\u7684\u9700\u6c42\u548c\u6027\u80fd\u8981\u6c42\u6765\u6743\u8861\u8fd9\u4e9b\u56e0\u7d20\uff1a \u9884\u5148\u5206\u914d\u8db3\u591f\u7684\u521d\u59cb\u5bb9\u91cf\uff0c\u4ee5\u51cf\u5c11\u6269\u5c55\u7684\u9891\u7387\u3002 \u4f7f\u7528\u644a\u8fd8\u5206\u6790\u6765\u5e73\u644a\u5f00\u9500\u3002 \u8003\u8651\u4f7f\u7528\u5176\u4ed6\u6570\u636e\u7ed3\u6784\uff0c\u5982\u94fe\u8868\uff0c\u5bf9\u63d2\u5165\u548c\u5220\u9664\u64cd\u4f5c\u7684\u6027\u80fd\u66f4\u52a0\u53cb\u597d\u3002 \u4e0b\u9762\uff0c\u5c1d\u8bd5\u5728\u6bcf\u6b21\u589e\u5927\u6570\u7ec4\u5c3a\u5bf8\u65f6\u628a\u6570\u7ec4\u5c3a\u5bf8\u7ffb\u500d\uff0c\u4ee3\u7801\u5b9e\u73b0\u5982\u4e0b\uff1a # \u589e\u5927\u6570\u7ec4\u7269\u7406\u5c3a\u5bf8 while logicalSize < DEFAULT_CAPACITY * 2 : logicalSize += 1 if logicalSize == len ( my_array ): # \u89e6\u53d1\u6761\u4ef6 temp = Array ( len ( my_array ) + 1 ) # \u521b\u5efa\u4e00\u4e2a\u65b0\u6570\u7ec4 for i in range ( logicalSize ): temp [ i ] = my_array [ i ] # \u4ece\u539f\u6570\u7ec4\u590d\u5236\u5185\u5bb9\u5230\u65b0\u6570\u7ec4 my_array = temp # \u628a\u65b0\u6570\u7ec4\u8d4b\u503c\u7ed9\u539f\u6570\u7ec4 \u5c06\u6570\u7ec4\u5c3a\u5bf8\u7ffb\u500d\u6765\u6269\u5c55\u6570\u7ec4\u7684\u65b9\u5f0f\u662f\u4e00\u79cd\u5e38\u89c1\u7684\u7b56\u7565\uff0c\u901a\u5e38\u7528\u4e8e\u51cf\u5c11\u52a8\u6001\u6570\u7ec4\u7684\u9891\u7e41\u6269\u5c55\u6b21\u6570\uff0c\u4ee5\u63d0\u9ad8\u6027\u80fd\u3002\u8fd9\u79cd\u65b9\u5f0f\u7684\u64cd\u4f5c\u65f6\u95f4\u590d\u6742\u5ea6\u4e3b\u8981\u53d6\u51b3\u4e8e\u6269\u5c55\u64cd\u4f5c\u7684\u9891\u7387\u548c\u5143\u7d20\u7684\u590d\u5236\u6210\u672c\u3002 \u644a\u8fd8\u5206\u6790\uff1a\u5bf9\u4e8e\u5c06\u6570\u7ec4\u5c3a\u5bf8\u7ffb\u500d\u7684\u7b56\u7565\uff0c\u644a\u8fd8\u5206\u6790\u8868\u660e\uff0c\u6bcf\u6b21\u6269\u5c55\u64cd\u4f5c\u7684\u644a\u8fd8\u65f6\u95f4\u590d\u6742\u5ea6\u4ecd\u7136\u662f\u5e38\u6570\u65f6\u95f4\u7684\uff08\u901a\u5e38\u662fO(1)\uff09\uff0c\u8fd9\u610f\u5473\u7740\u5e73\u5747\u4e0b\u6765\uff0c\u6bcf\u6b21\u6269\u5c55\u7684\u5f00\u9500\u662f\u56fa\u5b9a\u7684\uff0c\u800c\u4e0d\u4f1a\u968f\u6570\u7ec4\u7684\u5927\u5c0f\u7ebf\u6027\u589e\u52a0\u3002 \u64cd\u4f5c\u65f6\u95f4\uff1a\u5047\u8bbe\u6570\u7ec4\u9700\u8981\u6269\u5c55\uff0c\u90a3\u4e48\u5c06\u6570\u7ec4\u5c3a\u5bf8\u7ffb\u500d\u9700\u8981\u5206\u914d\u65b0\u7684\u5185\u5b58\u5757\u5e76\u590d\u5236\u73b0\u6709\u5143\u7d20\uff0c\u8fd9\u4e2a\u64cd\u4f5c\u7684\u65f6\u95f4\u590d\u6742\u5ea6\u662fO(n)\uff0c\u5176\u4e2dn\u662f\u6570\u7ec4\u7684\u5f53\u524d\u5927\u5c0f\u3002\u7136\u800c\uff0c\u7531\u4e8e\u6269\u5c55\u64cd\u4f5c\u4e0d\u662f\u6bcf\u6b21\u90fd\u6267\u884c\u7684\uff0c\u800c\u662f\u5f53\u6570\u7ec4\u5df2\u6ee1\u65f6\u624d\u6267\u884c\uff0c\u56e0\u6b64\u53ef\u4ee5\u8ba4\u4e3a\u8fd9\u4e2a\u64cd\u4f5c\u7684\u644a\u8fd8\u65f6\u95f4\u662f\u5e38\u6570\u65f6\u95f4\uff0c\u5373O(1)\u3002 \u7a7a\u95f4\u590d\u6742\u5ea6\uff1a\u5c06\u6570\u7ec4\u5c3a\u5bf8\u7ffb\u500d\u4f1a\u5360\u7528\u989d\u5916\u7684\u5185\u5b58\u7a7a\u95f4\uff0c\u4f46\u968f\u7740\u6570\u7ec4\u7684\u589e\u957f\uff0c\u989d\u5916\u5185\u5b58\u7684\u5360\u7528\u76f8\u5bf9\u4e8e\u6570\u7ec4\u672c\u8eab\u7684\u5927\u5c0f\u6765\u8bf4\u662f\u6709\u9650\u7684\u3002\u901a\u5e38\u60c5\u51b5\u4e0b\uff0c\u8fd9\u79cd\u5360\u7528\u53ef\u4ee5\u63a5\u53d7\u3002 \u603b\u7ed3\uff0c\u5c06\u6570\u7ec4\u5c3a\u5bf8\u7ffb\u500d\u7684\u7b56\u7565\u53ef\u4ee5\u663e\u8457\u51cf\u5c11\u52a8\u6001\u6570\u7ec4\u7684\u6269\u5c55\u6b21\u6570\uff0c\u4ece\u800c\u63d0\u9ad8\u6027\u80fd\u3002\u867d\u7136\u6bcf\u6b21\u6269\u5c55\u64cd\u4f5c\u53ef\u80fd\u4f1a\u82b1\u8d39\u4e00\u4e9b\u65f6\u95f4\u548c\u989d\u5916\u5185\u5b58\uff0c\u4f46\u8fd9\u4e9b\u5f00\u9500\u5728\u4e00\u7cfb\u5217\u64cd\u4f5c\u4e2d\u88ab\u5e73\u644a\uff0c\u5e73\u5747\u4e0b\u6765\u662f\u5e38\u6570\u65f6\u95f4\u3002\u8fd9\u662f\u4e00\u79cd\u9ad8\u6548\u7684\u52a8\u6001\u6570\u7ec4\u5b9e\u73b0\u65b9\u5f0f\uff0c\u5e38\u89c1\u4e8e\u8bb8\u591a\u7f16\u7a0b\u8bed\u8a00\u7684\u6807\u51c6\u5e93\u4e2d\uff0c\u5305\u62ecPython\u7684\u5217\u8868\uff08list\uff09\u3002 \u5728\u589e\u52a0\u6570\u7ec4\u7684\u957f\u5ea6\u65f6\uff0c\u6bcf\u6b21\u589e\u52a0\u4e00\u4e2a\u5185\u5b58\u5355\u5143\uff0c\u4e0e\u6bcf\u6b21\u589e\u5927\u6570\u7ec4\u5c3a\u5bf8\u65f6\u628a\u6570\u7ec4\u5c3a\u5bf8\u7ffb\u500d\u76f8\u6bd4\uff0c\u540e\u8005\u7684\u65b9\u6cd5\u901a\u5e38\u66f4\u9ad8\u6548\u3002 \u6bcf\u6b21\u589e\u52a0\u4e00\u4e2a\u5185\u5b58\u5355\u5143\uff1a\u8fd9\u79cd\u65b9\u5f0f\u5728\u6bcf\u6b21\u6dfb\u52a0\u65b0\u5143\u7d20\u65f6\u90fd\u9700\u8981\u5206\u914d\u989d\u5916\u7684\u5185\u5b58\uff0c\u5bfc\u81f4\u6570\u7ec4\u5c3a\u5bf8\u7684\u589e\u957f\u662f\u7ebf\u6027\u7684\u3002\u5982\u679c\u9891\u7e41\u6dfb\u52a0\u5143\u7d20\uff0c\u8fd9\u5c06\u5bfc\u81f4\u5927\u91cf\u7684\u5185\u5b58\u5206\u914d\u548c\u6570\u636e\u590d\u5236\u64cd\u4f5c\uff0c\u56e0\u6b64\u65f6\u95f4\u590d\u6742\u5ea6\u4f1a\u53d8\u5f97\u76f8\u5bf9\u8f83\u9ad8\u3002 \u6bcf\u6b21\u589e\u5927\u6570\u7ec4\u5c3a\u5bf8\u65f6\u628a\u6570\u7ec4\u5c3a\u5bf8\u7ffb\u500d\uff1a\u8fd9\u662f\u4e00\u79cd\u66f4\u9ad8\u6548\u7684\u7b56\u7565\u3002\u5728\u8fd9\u79cd\u65b9\u5f0f\u4e0b\uff0c\u6bcf\u6b21\u6269\u5c55\u64cd\u4f5c\u90fd\u4f1a\u589e\u52a0\u6570\u7ec4\u7684\u5c3a\u5bf8\uff0c\u4f46\u589e\u5e45\u662f\u6307\u6570\u7ea7\u7684\uff0c\u800c\u4e0d\u662f\u7ebf\u6027\u7684\u3002\u8fd9\u610f\u5473\u7740\u968f\u7740\u6570\u7ec4\u7684\u589e\u957f\uff0c\u6269\u5c55\u64cd\u4f5c\u7684\u9891\u7387\u4f1a\u51cf\u5c11\uff0c\u56e0\u4e3a\u6570\u7ec4\u80fd\u591f\u5bb9\u7eb3\u66f4\u591a\u5143\u7d20\u3002\u8fd9\u6837\uff0c\u867d\u7136\u6bcf\u6b21\u6269\u5c55\u64cd\u4f5c\u9700\u8981\u590d\u5236\u66f4\u591a\u7684\u5143\u7d20\uff0c\u4f46\u5b83\u4eec\u7684\u644a\u8fd8\u65f6\u95f4\u590d\u6742\u5ea6\u4ecd\u7136\u662f\u5e38\u6570\u65f6\u95f4\uff0c\u56e0\u4e3a\u5b83\u4eec\u4e0d\u662f\u6bcf\u6b21\u90fd\u6267\u884c\u7684\u3002 \u603b\u7ed3\uff0c\u5c06\u6570\u7ec4\u5c3a\u5bf8\u7ffb\u500d\u7684\u7b56\u7565\u901a\u5e38\u66f4\u9ad8\u6548\uff0c\u56e0\u4e3a\u5b83\u53ef\u4ee5\u51cf\u5c11\u9891\u7e41\u7684\u5185\u5b58\u5206\u914d\u548c\u590d\u5236\u64cd\u4f5c\uff0c\u964d\u4f4e\u4e86\u65f6\u95f4\u590d\u6742\u5ea6\u3002\u8fd9\u662f\u8bb8\u591a\u52a8\u6001\u6570\u7ec4\u5b9e\u73b0\u7684\u5e38\u89c1\u505a\u6cd5\uff0c\u5305\u62ecPython\u7684\u5217\u8868\uff08list\uff09\u3002 \u5728 Array \u7c7b\u5b9e\u73b0\u4e2d\uff0c\u662f\u901a\u8fc7\u4e0b\u9762\u4ee3\u7801\u6bb5\u5b9e\u73b0\u7684\u6570\u7ec4\u7269\u7406\u5c3a\u5bf8\u589e\u52a0\u7684\uff0c\u5373\u5c06\u6570\u7ec4\u5c3a\u5bf8\u7ffb\u500d\u3002 def grow ( self ): \"\"\"\u589e\u5927\u6570\u7ec4\u7269\u7406\u5c3a\u5bf8\"\"\" # \u57fa\u4e8e\u5f53\u524d\u7269\u7406\u5c3a\u5bf8\u52a0\u500d\uff0c\u5e76\u5c06fillValue\u8d4b\u503c\u5e95\u5c42\u5217\u8868\u7684\u65b0\u5143\u7d20 for count in range ( len ( self )): self . items . append ( self . fillValue ) 4.2.2.\u51cf\u5c0f\u6570\u7ec4\u7684\u5c3a\u5bf8 \u00b6 \u5982\u679c\u51cf\u5c0f\u6570\u7ec4\u7684\u903b\u8f91\u5c3a\u5bf8\uff0c\u5c31\u4f1a\u6d6a\u8d39\u76f8\u5e94\u7684\u5185\u5b58\u5355\u5143\u3002\u56e0\u6b64\uff0c\u5f53\u5220\u9664\u67d0\u4e00\u4e2a\u5143\u7d20\uff0c\u5982\u679c\u672a\u4f7f\u7528\u7684\u5185\u5b58\u5355\u5143\u6570\u8fbe\u5230\u6216\u8d85\u8fc7\u4e86\u67d0\u4e2a\u9608\u503c\uff08\u5982\u6570\u7ec4\u7269\u7406\u5c3a\u5bf8\u7684\u00be\uff09\u65f6\uff0c\u5219\u5e94\u8be5\u51cf\u5c0f\u7269\u7406\u5c3a\u5bf8\u4e86\u3002\u5982\u679c\u6d6a\u8d39\u7684\u5185\u5b58\u8d85\u8fc7\u7279\u5b9a\u9608\u503c\uff0c\u90a3\u4e48Python\u7684list\u7c7b\u578b\u4f1a\u5728\u8c03\u7528 pop \u65b9\u6cd5\u65f6\u6267\u884c\u51cf\u5c0f\u6570\u7ec4\u7269\u7406\u5c3a\u5bf8\u7684\u64cd\u4f5c\u3002 \u51cf\u5c0f\u6570\u7ec4\u5c3a\u5bf8\u7684\u8fc7\u7a0b\u4e0e\u589e\u5927\u6570\u7ec4\u5c3a\u5bf8\u7684\u8fc7\u7a0b\u76f8\u53cd\uff0c\u6b65\u9aa4\u5982\u4e0b\uff1a \u521b\u5efa\u4e00\u4e2a\u66f4\u5c0f\u7684\u65b0\u6570\u7ec4\u3002 \u5c06\u6570\u636e\u4ece\u65e7\u6570\u7ec4\u4e2d\u590d\u5236\u5230\u65b0\u6570\u7ec4\u3002 \u5c06\u6307\u5411\u65e7\u6570\u7ec4\u7684\u53d8\u91cf\u6307\u5411\u65b0\u6570\u7ec4\u5bf9\u8c61\u3002 \u4e0b\u9762\u7684\u4ee3\u7801\u5b9e\u73b0\u4e86\u51cf\u5c0f\u6570\u7ec4\u5c3a\u5bf8\u3002 \u5f53\u6570\u7ec4\u7684\u903b\u8f91\u5c3a\u5bf8\u5c0f\u4e8e\u6216\u7b49\u4e8e\u5176\u7269\u7406\u5c3a\u5bf8\u7684\u00bc\uff0c\u5e76\u4e14\u5b83\u7684\u7269\u7406\u5c3a\u5bf8\u81f3\u5c11\u662f\u8fd9\u4e2a\u6570\u7ec4\u5efa\u7acb\u65f6\u9ed8\u8ba4\u5bb9\u91cf\u76842\u500d\u65f6\uff0c\u5219\u4e0b\u9762\u7684\u7b97\u6cd5\u628a\u6570\u7ec4\u7684\u7269\u7406\u5c3a\u5bf8\u51cf\u5c0f\u5230\u539f\u6765\u7684\u4e00\u534a\uff0c\u5e76\u4e14\u4e5f\u4e0d\u4f1a\u5c0f\u4e8e\u5176\u9ed8\u8ba4\u5bb9\u91cf\u3002 # \u51cf\u5c0f\u6570\u7ec4\u7269\u7406\u5c3a\u5bf8 while logicalSize > len ( my_array ) // 4 : logicalSize -= 1 if logicalSize <= len ( my_array ) // 4 and len ( my_array ) >= DEFAULT_CAPACITY * 2 : # \u89e6\u53d1\u6761\u4ef6 temp = Array ( len ( my_array ) // 2 ) # \u521b\u5efa\u4e00\u4e2a\u65b0\u6570\u7ec4 for i in range ( logicalSize ): temp [ i ] = my_array [ i ] # \u4ece\u539f\u6570\u7ec4\u590d\u5236\u5185\u5bb9\u5230\u65b0\u6570\u7ec4 my_array = temp # \u628a\u65b0\u6570\u7ec4\u8d4b\u503c\u7ed9\u539f\u6570\u7ec4 \u6309\u7167\u4e0a\u9762\u7b97\u6cd5\u51cf\u5c11\u6570\u7ec4\u7684\u5c3a\u5bf8\uff0c\u6211\u4eec\u53ef\u4ee5\u5206\u6790\u5176\u65f6\u95f4\u548c\u7a7a\u95f4\u590d\u6742\u5ea6\u5982\u4e0b\uff1a \u65f6\u95f4\u590d\u6742\u5ea6\uff1a\u4e3b\u8981\u6d89\u53ca\u4e24\u4e2a\u64cd\u4f5c\uff1a \u521b\u5efa\u65b0\u6570\u7ec4\u5e76\u5c06\u5143\u7d20\u4ece\u65e7\u6570\u7ec4\u590d\u5236\u5230\u65b0\u6570\u7ec4\uff1b \u5c06\u65e7\u6570\u7ec4\u5f15\u7528\u66f4\u6539\u4e3a\u65b0\u6570\u7ec4\u3002 \u590d\u5236\u64cd\u4f5c\u7684\u65f6\u95f4\u590d\u6742\u5ea6\u53d6\u51b3\u4e8e\u6570\u7ec4\u7684\u7269\u7406\u5c3a\u5bf8\uff0c\u53ef\u4ee5\u8868\u793a\u4e3a O(n) \uff0c\u5176\u4e2d n \u662f\u6570\u7ec4\u7684\u5f53\u524d\u7269\u7406\u5c3a\u5bf8\u3002\u5f15\u7528\u66f4\u6539\u662f\u4e00\u4e2a\u5e38\u6570\u65f6\u95f4\u64cd\u4f5c\uff0c\u4e0d\u5f71\u54cd\u65f6\u95f4\u590d\u6742\u5ea6\u3002\u6240\u4ee5\uff0c\u6574\u4f53\u7684\u65f6\u95f4\u590d\u6742\u5ea6\u662f O(n) \u3002 \u7a7a\u95f4\u590d\u6742\u5ea6\uff1a\u7a7a\u95f4\u590d\u6742\u5ea6\u4e5f\u6d89\u53ca\u4e24\u4e2a\u65b9\u9762\uff1a \u521b\u5efa\u65b0\u6570\u7ec4\u7684\u5185\u5b58\u6d88\u8017\uff0c\u5176\u7a7a\u95f4\u590d\u6742\u5ea6\u662fO(N)\uff1b \u5f15\u7528\u66f4\u6539\u6240\u9700\u7684\u5e38\u6570\u989d\u5916\u7a7a\u95f4\uff0c\u901a\u5e38\u5ffd\u7565\u4e0d\u8ba1\u3002 \u6240\u4ee5\uff0c\u603b\u7684\u7a7a\u95f4\u590d\u6742\u5ea6\u662f O(n) \u3002 \u8fd9\u4e2a\u7b97\u6cd5\u7b56\u7565\u4f1a\u5728\u9002\u5f53\u7684\u65f6\u5019\u51cf\u5c0f\u6570\u7ec4\u7684\u7269\u7406\u5c3a\u5bf8\uff0c\u4ee5\u51cf\u5c11\u5185\u5b58\u5360\u7528\uff0c\u4f46\u4ecd\u7136\u4fdd\u6301\u7740\u6570\u7ec4\u7684\u52a8\u6001\u6027\u3002\u65f6\u95f4\u590d\u6742\u5ea6\u548c\u7a7a\u95f4\u590d\u6742\u5ea6\u90fd\u4e0e\u5f53\u524d\u6570\u7ec4\u7684\u7269\u7406\u5c3a\u5bf8\u6210\u7ebf\u6027\u5173\u7cfb\uff0c\u56e0\u6b64\u662f\u7ebf\u6027\u7684\uff0c\u8fd9\u662f\u4e00\u79cd\u6709\u6548\u7684\u7b56\u7565\u6765\u4f18\u5316\u5185\u5b58\u4f7f\u7528\u3002\u540c\u65f6\uff0c\u4fdd\u7559\u4e86\u4e00\u5b9a\u7684\u5197\u4f59\u7a7a\u95f4\uff0c\u4ee5\u907f\u514d\u9891\u7e41\u5730\u6269\u5c55\u548c\u7f29\u5c0f\u6570\u7ec4\uff0c\u4ece\u800c\u63d0\u9ad8\u4e86\u6027\u80fd\u3002 \u4e0b\u9762\u662f\u5728 Array \u7c7b\u4e2d\u5b9e\u73b0\u51cf\u5c0f\u6570\u7ec4\u7684\u7269\u7406\u5c3a\u5bf8\u7684\u4ee3\u7801\u3002 def shrink ( self ): \"\"\" \u51cf\u5c11\u6570\u7ec4\u7684\u7269\u7406\u5c3a\u5bf8 \u5f53: - \u6570\u7ec4\u7684\u903b\u8f91\u5c3a\u5bf8\u5c0f\u4e8e\u6216\u7b49\u4e8e\u5176\u7269\u7406\u5c3a\u5bf8\u76841/4 - \u5e76\u4e14\u5b83\u7684\u7269\u7406\u5c3a\u5bf8\u81f3\u5c11\u662f\u8fd9\u4e2a\u6570\u7ec4\u5efa\u7acb\u65f6\u9ed8\u8ba4\u5bb9\u91cf\u76842\u500d\u65f6 \u5219\u628a\u6570\u7ec4\u7684\u7269\u7406\u5c3a\u5bf8\u51cf\u5c0f\u5230\u539f\u6765\u7684\u4e00\u534a\uff0c\u5e76\u4e14\u4e5f\u4e0d\u4f1a\u5c0f\u4e8e\u5176\u9ed8\u8ba4\u5bb9\u91cf \"\"\" # \u5728\u903b\u8f91\u5c3a\u5bf8\u548c\u7269\u7406\u5c3a\u5bf8\u7684\u4e00\u534a\u4e4b\u95f4\u9009\u62e9\u6700\u5927\u503c\u4f5c\u4e3a\u6570\u7ec4\u6536\u7f29\u540e\u7684\u7269\u7406\u5c3a\u5bf8 newSize = max ( self . capacity , len ( self ) // 2 ) # \u91ca\u653e\u591a\u4f59\u7684\u6570\u7ec4\u7a7a\u95f4 for count in range ( len ( self ) - newSize ): self . items . pop () 4.2.3.\u5c06\u5143\u7d20\u63d2\u5165\u589e\u5927\u7684\u6570\u7ec4 \u00b6 \u628a\u5143\u7d20\u63d2\u5165\u6570\u7ec4\u4e2d\u548c\u66ff\u6362\u6570\u7ec4\u91cc\u7684\u5143\u7d20\u662f\u4e0d\u4e00\u6837\u7684\u3002 \u66ff\u6362\u6570\u7ec4\u5143\u7d20\u65f6\uff0c\u5143\u7d20\u5df2\u5728\u4e00\u4e2a\u7ed9\u5b9a\u7684\u7d22\u5f15\u4f4d\u7f6e\uff0c\u5bf9\u8fd9\u4e2a\u4f4d\u7f6e\u8fdb\u884c\u7b80\u5355\u590d\u5236\u5373\u53ef\uff0c\u6570\u7ec4\u7684\u903b\u8f91\u5c3a\u5bf8\u5e76\u4e0d\u4f1a\u6539\u53d8\u3002 \u63d2\u5165\u6570\u7ec4\u5143\u7d20\u65f6\uff0c\u9700\u8981\u5b8c\u6210\u4e0b\u97624\u4e2a\u6b65\u9aa4\uff1a \u5728\u63d2\u5165\u5143\u7d20\u4e4b\u524d\u5148\u68c0\u67e5\u53ef\u4ee5\u4f7f\u7528\u7684\u7a7a\u95f4\uff0c\u6839\u636e\u9700\u8981\u6765\u589e\u5927\u6570\u7ec4\u7684\u7269\u7406\u5c3a\u5bf8\u3002 \u5c06\u6570\u7ec4\u91cc\u4ece\u903b\u8f91\u7ed3\u5c3e\u5230\u76ee\u6807\u7d22\u5f15\u7684\u6240\u6709\u5143\u7d20\u5411\u540e\u79fb\u52a8\u3002\u8fd9\u4e2a\u8fc7\u7a0b\u4f1a\u5728\u76ee\u6807\u7d22\u5f15\u4f4d\u7f6e\u5904\u4e3a\u65b0\u5143\u7d20\u7559\u4e0b\u4e00\u4e2a\u7a7a\u683c\u3002 \u5c06\u65b0\u5143\u7d20\u5206\u914d\u5230\u76ee\u6807\u7d22\u5f15\u4f4d\u7f6e\u3002 \u5c06\u903b\u8f91\u5c3a\u5bf8\u52a01\u3002 \u5b9e\u73b0\u7b97\u6cd5\uff1a # \u5f53\u6570\u7ec4\u7684\u7269\u7406\u5c3a\u5bf8\u548c\u903b\u8f91\u5c3a\u5bf8\u4e00\u6837\u65f6\uff0c\u5219\u589e\u52a0\u7269\u7406\u5c3a\u5bf8 # \u5c06\u6570\u7ec4\u5143\u7d20\u5411\u5c3e\u90e8\u5e73\u79fb\u4e00\u4e2a\u4f4d\u7f6e for i in range ( logicalSize , targetIndex , - 1 ): my_array [ i ] = my_array [ i - 1 ] # \u63d2\u5165\u65b0\u5143\u7d20\uff0c\u589e\u52a0\u6570\u7ec4\u7684\u903b\u8f91\u5c3a\u5bf8 my_array [ targetIndex ] = newItem logicalSize += 1 \u4e0b\u9762\u662f Array \u7c7b\u4e2d\u5b9e\u73b0\u63d2\u5165\u5143\u7d20\u7684\u65b9\u6cd5\u3002 def insert ( self , index , newItem ): \"\"\"\u5728\u6570\u7ec4\u6307\u5b9a\u7d22\u5f15\u5904\u63d2\u5165\u65b0\u5143\u7d20\"\"\" # \u5f53\u6570\u7ec4\u7684\u7269\u7406\u5c3a\u5bf8\u548c\u903b\u8f91\u5c3a\u5bf8\u4e00\u6837\u65f6\uff0c\u5219\u589e\u52a0\u7269\u7406\u5c3a\u5bf8 if self . size () == len ( self ): self . grow () # \u63d2\u5165\u65b0\u5143\u7d20 # \u5f53\u63d2\u5165\u4f4d\u7f6e\u5927\u4e8e\u6216\u7b49\u4e8e\u6700\u5927\u903b\u8f91\u4f4d\u7f6e\uff0c\u5219\u5728\u6570\u7ec4\u672b\u7aef\u63d2\u5165\u65b0\u5143\u7d20 # \u5f53\u63d2\u5165\u4f4d\u7f6e\u4ecb\u4e8e\u6570\u7ec4\u903b\u8f91\u4f4d\u7f6e\u7684\u4e2d\u95f4\uff0c\u5219\u4ece\u63d2\u5165\u4f4d\u7f6e\u8d77\u5c06\u5269\u4f59\u6570\u7ec4\u5143\u7d20\u5411\u5c3e\u90e8\u5e73\u79fb\u4e00\u4e2a\u4f4d\u7f6e if index >= self . size (): self . items [ self . size ()] = newItem else : index = max ( index , 0 ) # \u5c06\u6570\u7ec4\u5143\u7d20\u5411\u5c3e\u90e8\u5e73\u79fb\u4e00\u4e2a\u4f4d\u7f6e for i in range ( self . size (), index , - 1 ): self . items [ i ] = self . items [ i - 1 ] # \u63d2\u5165\u65b0\u5143\u7d20 self . items [ index ] = newItem # \u589e\u52a0\u6570\u7ec4\u7684\u903b\u8f91\u5c3a\u5bf8 self . logicalSize += 1 4.2.4.\u4ece\u6570\u7ec4\u91cc\u5220\u9664\u5143\u7d20 \u00b6 \u4ece\u6570\u7ec4\u91cc\u5220\u9664\u5143\u7d20\u7684\u6b65\u9aa4\u5982\u4e0b\uff0c\u548c\u63d2\u5165\u64cd\u4f5c\u4e00\u6837\uff0c\u5143\u7d20\u7684\u79fb\u52a8\u987a\u5e8f\u975e\u5e38\u91cd\u8981\u3002 \u5c06\u6570\u7ec4\u91cc\u4ece\u76ee\u6807\u7d22\u5f15\u5230\u903b\u8f91\u7ed3\u5c3e\u7684\u6240\u6709\u5143\u7d20\u5411\u524d\u79fb\u52a8\uff0c\u628a\u6bcf\u4e2a\u5143\u7d20\u90fd\u590d\u5236\u5230\u5b83\u524d\u9762\u7684\u90a3\u4e2a\u5185\u5b58\u5355\u5143\u91cc\u3002\u8fd9\u4e2a\u8fc7\u7a0b\u4f1a\u5173\u95ed\u5220\u9664\u76ee\u6807\u7d22\u5f15\u4f4d\u7f6e\u4e2d\u7684\u5143\u7d20\u6240\u7559\u4e0b\u7684\u7a7a\u683c\u3002 \u5c06\u903b\u8f91\u5c3a\u5bf8\u51cf1\u3002 \u68c0\u67e5\u662f\u5426\u5b58\u5728\u5185\u5b58\u7a7a\u95f4\u7684\u6d6a\u8d39\uff0c\u5e76\u6839\u636e\u9700\u8981\u51cf\u5c0f\u6570\u7ec4\u7684\u7269\u7406\u5c3a\u5bf8\u3002 \u5728\u5e73\u5747\u60c5\u51b5\u4e0b\uff0c\u79fb\u52a8\u5143\u7d20\u7684\u65f6\u95f4\u590d\u6742\u5ea6\u662f\u7ebf\u6027\u7684\uff0c\u56e0\u6b64\u5220\u9664\u64cd\u4f5c\u7684\u65f6\u95f4\u590d\u6742\u5ea6\u4e5f\u662f\u7ebf\u6027\u7684\u3002 \u4e0b\u9762\u662f\u5b9e\u73b0\u5220\u9664\u64cd\u4f5c\u7684\u4ee3\u7801\u3002 # \u5c06\u6570\u7ec4\u5143\u7d20\u5411\u5934\u90e8\u5e73\u79fb\u4e00\u4e2a\u4f4d\u7f6e for i in range ( targetIndex , logicalSize - 1 ): my_array [ i ] = my_arraya [ i + 1 ] # \u51cf\u5c11\u6570\u7ec4\u903b\u8f91\u5c3a\u5bf8 logicalSize -= 1 # \u5982\u679c\u9700\u8981\uff0c\u5219\u51cf\u5c11\u6570\u7ec4\u7269\u7406\u5c3a\u5bf8 \u4e0b\u9762\u662f Array \u7c7b\u4e2d\u5b9e\u73b0\u5220\u9664\u5143\u7d20\u7684\u65b9\u6cd5\u3002 def pop ( self , index ): \"\"\" \u5220\u9664\u6307\u5b9a\u7d22\u5f15\u503c\u7684\u6570\u7ec4\u5143\u7d20,\u5e76\u8fd4\u56de\u5220\u9664\u7684\u6570\u7ec4\u5143\u7d20\u503c \u5148\u51b3\u6761\u4ef6: 0 <= index < size() \"\"\" if index < 0 or index >= self . size (): raise IndexError ( \"\u5220\u9664\u64cd\u4f5c\u51fa\u9519, \u6570\u7ec4\u7d22\u5f15\u8d8a\u754c(\u4e0d\u5728\u6570\u7ec4\u903b\u8f91\u8fb9\u754c\u8303\u56f4\u5185)\" ) # \u4fdd\u5b58\u5373\u5c06\u88ab\u5220\u9664\u7684\u6570\u7ec4\u5143\u7d20\u503c itemToReturn = self . items [ index ] # \u5c06\u6570\u7ec4\u5143\u7d20\u5411\u5934\u90e8\u5e73\u79fb\u4e00\u4e2a\u4f4d\u7f6e for i in range ( index , self . size () - 1 ): self . items [ i ] = self . items [ i + 1 ] # \u5c06\u6570\u7ec4\u5c3e\u90e8\u7684\u7a7a\u4f59\u4f4d\u8d4b\u503cfillValue\uff0c\u9ed8\u8ba4\u662fNone self . items [ self . size () - 1 ] = self . fillValue # \u51cf\u5c11\u6570\u7ec4\u903b\u8f91\u5c3a\u5bf8 self . logicalSize -= 1 # \u51cf\u5c11\u6570\u7ec4\u7269\u7406\u5c3a\u5bf8 # \u5f53: # - \u6570\u7ec4\u7684\u903b\u8f91\u5c3a\u5bf8\u5c0f\u4e8e\u6216\u7b49\u4e8e\u5176\u7269\u7406\u5c3a\u5bf8\u76841/4 # - \u5e76\u4e14\u5b83\u7684\u7269\u7406\u5c3a\u5bf8\u81f3\u5c11\u662f\u8fd9\u4e2a\u6570\u7ec4\u5efa\u7acb\u65f6\u9ed8\u8ba4\u5bb9\u91cf\u76842\u500d\u65f6 # \u5219\u628a\u6570\u7ec4\u7684\u7269\u7406\u5c3a\u5bf8\u51cf\u5c0f\u5230\u539f\u6765\u7684\u4e00\u534a\uff0c\u5e76\u4e14\u4e5f\u4e0d\u4f1a\u5c0f\u4e8e\u5176\u9ed8\u8ba4\u5bb9\u91cf if self . size () <= len ( self ) // 4 and len ( self ) > self . capacity : self . shrink () # \u8fd4\u56de\u88ab\u5220\u9664\u5143\u7d20\u7684\u503c print ( f 'Item { itemToReturn } was deleted' ) return itemToReturn 4.2.5.\u590d\u6742\u5ea6\u7684\u6743\u8861\uff1a\u65f6\u95f4\u3001\u7a7a\u95f4\u548c\u6570\u7ec4 \u00b6 \u4e0b\u8868\u5217\u51fa\u4e86\u6240\u6709\u6570\u7ec4\u64cd\u4f5c\u7684\u8fd0\u884c\u65f6\u590d\u6742\u5ea6\uff0c\u5305\u62ec\u5728\u6570\u7ec4\u7684\u903b\u8f91\u7ed3\u5c3e\u5904\u63d2\u5165\u548c\u5220\u9664\u5143\u7d20\u3002 \u6570\u7ec4\u63d0\u4f9b\u4e86\u5bf9\u5df2\u7ecf\u5b58\u5728\u7684\u5143\u7d20\u8fdb\u884c\u5feb\u901f\u8bbf\u95ee\u7684\u529f\u80fd\uff0c\u4ee5\u53ca\u5728\u903b\u8f91\u7ed3\u5c3e\u5904\u5feb\u901f\u63d2\u5165\u548c\u5220\u9664\u7684\u529f\u80fd\u3002 \u5728\u4efb\u610f\u4f4d\u7f6e\u5904\u8fdb\u884c\u63d2\u5165\u548c\u5220\u9664\u64cd\u4f5c\u7684\u901f\u5ea6\u5219\u4f1a\u6162\u4e0a\u4e00\u4e2a\u6570\u91cf\u7ea7\u3002 \u8c03\u6574\u6570\u7ec4\u7684\u5c3a\u5bf8\u4e5f\u9700\u8981\u7ebf\u6027\u65f6\u95f4\uff0c\u4f46\u662f\u56e0\u4e3a\u8fd9\u4e2a\u64cd\u4f5c\u4f1a\u628a\u6570\u7ec4\u5c3a\u5bf8\u52a0\u500d\u6216\u51cf\u534a\uff0c\u6240\u4ee5\u53ef\u4ee5\u6700\u5927\u9650\u5ea6\u5730\u51cf\u5c11\u9700\u8981\u6267\u884c\u7684\u6b21\u6570\u3002 \u7531\u4e8e\u53ef\u80fd\u4f1a\u8c03\u6574\u6570\u7ec4\u7684\u5c3a\u5bf8\uff0c\u56e0\u6b64\u63d2\u5165\u548c\u5220\u9664\u64cd\u4f5c\u5728\u4f7f\u7528\u5185\u5b58\u7684\u65f6\u5019\u4f1a\u6709 O(n) \u7684\u590d\u6742\u5ea6\uff0c\u90a3\u4e48\u8fd9\u5c31\u662f\u6700\u574f\u60c5\u51b5\u4e0b\u7684\u6027\u80fd\uff1b\u800c\u5728\u5e73\u5747\u60c5\u51b5\u4e0b\uff0c\u8fd9\u4e9b\u64cd\u4f5c\u7684\u5185\u5b58\u4f7f\u7528\u60c5\u51b5\u4ecd\u7136\u4e3a O(1) \u3002 \u64cd\u4f5c \u8fd0\u884c\u65f6\u590d\u6742\u5ea6 \u5728\u4f4d\u7f6ei\u5904\u8bbf\u95ee O(1)\uff0c\u6700\u597d\u548c\u6700\u574f\u60c5\u51b5\u4e0b \u5728\u4f4d\u7f6ei\u5904\u66ff\u6362 O(1)\uff0c\u6700\u597d\u548c\u6700\u574f\u60c5\u51b5\u4e0b \u5728\u903b\u8f91\u7ed3\u5c3e\u5904\u63d2\u5165 O(1)\uff0c\u5e73\u5747\u60c5\u51b5\u4e0b \u5728\u4f4d\u7f6ei\u5904\u63d2\u5165 O(n)\uff0c\u5e73\u5747\u60c5\u51b5\u4e0b \u5728\u4f4d\u7f6ei\u5904\u5220\u9664 O(n)\uff0c\u5e73\u5747\u60c5\u51b5\u4e0b \u589e\u5927\u5bb9\u91cf O(n)\uff0c\u6700\u597d\u548c\u6700\u574f\u60c5\u51b5\u4e0b \u51cf\u5c0f\u5bb9\u91cf O(n)\uff0c\u6700\u597d\u548c\u6700\u574f\u60c5\u51b5\u4e0b \u5728\u903b\u8f91\u7ed3\u5c3e\u5904\u5220\u9664 O(1)\uff0c\u5e73\u5747\u60c5\u51b5\u4e0b \u4f7f\u7528\u6570\u7ec4\u7684\u65f6\u5019\uff0c\u5185\u5b58\u91cc\u552f\u4e00\u771f\u6b63\u88ab\u6d6a\u8d39\u7684\u662f\u90a3\u4e9b\u5c1a\u672a\u586b\u5145\u6ee1\u7684\u6570\u7ec4\u5355\u5143\u3002 \u8bc4\u4f30\u6570\u7ec4\u5185\u5b58\u4f7f\u7528\u7387\u7684\u4e00\u4e2a\u975e\u5e38\u6709\u7528\u7684\u6982\u5ff5\u662f\u8d1f\u8f7d\u56e0\u5b50\uff08load factor\uff09\u3002\u6570\u7ec4\u7684\u8d1f\u8f7d\u56e0\u5b50\u7b49\u540c\u4e8e\u5b83\u6240\u5b58\u50a8\u7684\u5143\u7d20\u6570\u9664\u4ee5\u6570\u7ec4\u7684\u5bb9\u91cf\u3002 \u5f53\u6570\u7ec4\u5df2\u6ee1\u7684\u65f6\u5019\uff0c\u8d1f\u8f7d\u56e0\u5b50\u5c31\u662f1\uff1b \u5f53\u6570\u7ec4\u4e3a\u7a7a\u65f6\uff0c\u8d1f\u8f7d\u56e0\u5b50\u5c31\u662f0\uff1b \u5f53\u5185\u5b58\u5355\u5143\u7684\u5bb9\u91cf\u4e3a10\u4e14\u5360\u7528\u4e863\u4e2a\u5355\u5143\u65f6\uff0c\u8d1f\u8f7d\u56e0\u5b50\u5c31\u662f0.3\uff1b \u5f53\u6570\u7ec4\u7684\u8d1f\u8f7d\u56e0\u5b50\u964d\u5230\u67d0\u4e2a\u9608\u503c\uff08\u59820.25\uff09\u4ee5\u4e0b\u65f6\uff0c\u53ef\u4ee5\u901a\u8fc7\u8c03\u6574\u6570\u7ec4\u5c3a\u5bf8\u5c06\u6d6a\u8d39\u7684\u5185\u5b58\u5355\u5143\u6570\u4fdd\u6301\u5728\u5c3d\u53ef\u80fd\u4f4e\u7684\u6c34\u5e73\uff1b 4.2.6.\u7ec3\u4e60\u9898 \u00b6 1\uff0e\u8bf7\u8bf4\u660e\u4e3a\u4ec0\u4e48\u63d2\u5165\u6216\u5220\u9664\u7ed9\u5b9a\u5143\u7d20\u65f6\u5fc5\u987b\u8981\u79fb\u52a8\u6570\u7ec4\u91cc\u7684\u67d0\u4e9b\u5143\u7d20\u3002 \u89e3\u7b54\uff1a\u5728 Python \u4e2d\uff0c\u5217\u8868\uff08list\uff09\u662f\u57fa\u4e8e\u6570\u7ec4\u5b9e\u73b0\u7684\u6570\u636e\u7ed3\u6784\u3002\u6240\u8c13\u7684\u201c\u6570\u7ec4\u201d\uff0c\u5176\u672c\u8d28\u4e0a\u662f\u4e00\u5757\u8fde\u7eed\u7684\u5185\u5b58\u7a7a\u95f4\uff0c\u7531\u4e8e\u5176\u5185\u5b58\u8fde\u7eed\u7684\u7279\u6027\uff0c\u6570\u7ec4\u5728\u8fdb\u884c\u63d2\u5165\u6216\u8005\u5220\u9664\u4e00\u4e2a\u5143\u7d20\u65f6\uff0c\u4e3a\u4e86\u4fdd\u6301\u5185\u5b58\u7684\u8fde\u7eed\u6027\uff0c\u5f80\u5f80\u9700\u8981\u79fb\u52a8\u6570\u7ec4\u91cc\u7684\u5176\u5b83\u5143\u7d20\u3002 \u5f53\u5728\u6570\u7ec4\u7684\u4e2d\u95f4\u4f4d\u7f6e\u63d2\u5165\u4e00\u4e2a\u65b0\u7684\u5143\u7d20\u65f6\uff0c\u4e3a\u4e86\u7ed9\u65b0\u5143\u7d20\u817e\u51fa\u7a7a\u95f4\uff0c\u5b83\u540e\u9762\u7684\u6240\u6709\u5143\u7d20\u90fd\u9700\u8981\u5411\u540e\u79fb\u52a8\u4e00\u4f4d\u3002\u540c\u6837\u7684\uff0c\u5982\u679c\u6211\u4eec\u5220\u9664\u4e86\u6570\u7ec4\u7684\u4e00\u4e2a\u5143\u7d20\uff0c\u4e3a\u4e86\u907f\u514d\u5728\u6570\u7ec4\u4e2d\u51fa\u73b0\u4e00\u4e2a\u7a7a\u6d1e\uff0c\u88ab\u5220\u9664\u5143\u7d20\u540e\u9762\u7684\u6240\u6709\u5143\u7d20\u90fd\u9700\u8981\u5411\u524d\u79fb\u52a8\u4e00\u4f4d\u3002 \u7136\u800c\uff0cPython\u7684 list \u6570\u636e\u7ed3\u6784\u662f\u52a8\u6001\u7684\uff0c\u4e5f\u5c31\u662f\u8bf4\uff0c\u5f53\u63d2\u5165\u6216\u5220\u9664\u5143\u7d20\u65f6\uff0cPython\u4f1a\u81ea\u52a8\u5206\u914d\u6216\u56de\u6536\u5185\u5b58\u3002\u5f53\u5728 list \u7684\u672b\u5c3e\u6dfb\u52a0\u6216\u79fb\u9664\u5143\u7d20\u65f6\uff0c\u4e0d\u9700\u8981\u79fb\u52a8\u5176\u4ed6\u5143\u7d20\uff0c\u56e0\u6b64\u64cd\u4f5c\u6548\u7387\u8f83\u9ad8\uff1b\u4f46\u662f\u5728 list \u7684\u4e2d\u95f4\u6216\u8d77\u59cb\u90e8\u5206\u63d2\u5165\u6216\u5220\u9664\u5143\u7d20\u65f6\uff0c\u5c31\u9700\u8981\u79fb\u52a8\u5176\u5b83\u5143\u7d20\uff0c\u76f8\u5bf9\u800c\u8a00\uff0c\u5176\u64cd\u4f5c\u6548\u7387\u5c31\u8f83\u4f4e\u4e86\u3002 2\uff0e\u5728\u63d2\u5165\u8fc7\u7a0b\u4e2d\uff0c\u79fb\u52a8\u6570\u7ec4\u5143\u7d20\u65f6\uff0c\u8981\u5148\u79fb\u52a8\u54ea\u4e2a\u5143\u7d20\uff1f\u5148\u79fb\u52a8\u63d2\u5165\u4f4d\u7f6e\u7684\u5143\u7d20\uff0c\u8fd8\u662f\u6700\u540e\u4e00\u4e2a\u5143\u7d20\uff1f\u4e3a\u4ec0\u4e48\uff1f \u89e3\u7b54\uff1a\u5728 Python \u4e2d\u5b9e\u73b0\u6570\u7ec4\u7684\u63d2\u5165\u8fc7\u7a0b\u65f6\uff0c\u5e94\u5f53\u5148\u79fb\u52a8\u63d2\u5165\u4f4d\u7f6e\u4e4b\u540e\u7684\u6700\u540e\u4e00\u4e2a\u5143\u7d20\u3002 \u8003\u8651\u4ee5\u4e0b\u7684\u60c5\u51b5\uff1a\u503c\u63d2\u5165\u4e8e\u6570\u7ec4\u7684\u4e2d\u95f4\u4f4d\u7f6e\uff0c\u4f60\u8bd5\u56fe\u4ece\u63d2\u5165\u4f4d\u7f6e\u5f00\u59cb\uff0c\u5c06\u6bcf\u4e2a\u5143\u7d20\u540e\u79fb\u4e00\u4f4d\u3002\u4f46\u662f\uff0c\u5f53\u4f60\u628a\u7b2c\u4e00\u4e2a\u5143\u7d20\u79fb\u5230\u7b2c\u4e8c\u4e2a\u4f4d\u7f6e\u65f6\uff0c\u4f60\u4f1a\u8986\u76d6\u6389\u539f\u6709\u7684\u7b2c\u4e8c\u4e2a\u5143\u7d20\uff0c\u7531\u4e8e\u4f60\u8fd8\u6ca1\u6709\u4fdd\u5b58\u6216\u590d\u5236\u8fd9\u4e2a\u88ab\u8986\u76d6\u7684\u5143\u7d20\uff0c\u5b83\u5c31\u4f1a\u4e22\u5931\u3002 \u5982\u679c\u4ece\u6700\u540e\u4e00\u4e2a\u5143\u7d20\u5f00\u59cb\uff0c\u5c06\u6bcf\u4e2a\u5143\u7d20\u5411\u540e\u79fb\u4e00\u4f4d\uff0c\u90a3\u4e48\u6bcf\u4e2a\u5143\u7d20\u90fd\u4f1a\u88ab\u590d\u5236\u5230\u5b83\u7684\u4e0b\u4e00\u4f4d\uff0c\u7136\u540e\u624d\u4f1a\u88ab\u5b83\u524d\u9762\u7684\u5143\u7d20\u8986\u76d6\u3002\u8fd9\u6837\u5c31\u786e\u4fdd\u4e86\u6bcf\u4e2a\u5143\u7d20\u90fd\u80fd\u6b63\u786e\u5730\u79fb\u52a8\u5230\u5b83\u5e94\u8be5\u5230\u8fbe\u7684\u4f4d\u7f6e\uff0c\u4e0d\u4f1a\u6709\u4efb\u4f55\u5143\u7d20\u4e22\u5931\u3002 \u6240\u4ee5\uff0c\u5728\u63d2\u5165\u8fc7\u7a0b\u4e2d\uff0c\u6211\u4eec\u5e94\u8be5\u4ece\u6700\u540e\u4e00\u4e2a\u5143\u7d20\u5f00\u59cb\uff0c\u9010\u4e2a\u5c06\u5143\u7d20\u540e\u79fb\u4e00\u4f4d\uff0c\u76f4\u5230\u5c06\u63d2\u5165\u4f4d\u7f6e\u7684\u5143\u7d20\u4e5f\u540e\u79fb\u4e00\u4f4d\uff0c\u7136\u540e\u5728\u63d2\u5165\u4f4d\u7f6e\u653e\u5165\u65b0\u7684\u5143\u7d20\u3002 3\uff0e\u5982\u679c\u63d2\u5165\u4f4d\u7f6e\u662f\u6570\u7ec4\u7684\u903b\u8f91\u672b\u5c3e\uff0c\u8bf7\u8bf4\u660e\u8fd9\u4e2a\u63d2\u5165\u64cd\u4f5c\u7684\u8fd0\u884c\u65f6\u590d\u6742\u5ea6\u3002 \u89e3\u7b54\uff1a\u5982\u679c\u5728\u6570\u7ec4\uff08\u5728 Python \u4e2d\u5c31\u662f list\uff09\u7684\u903b\u8f91\u672b\u5c3e\u63d2\u5165\u5143\u7d20\uff0c\u8fd9\u79cd\u64cd\u4f5c\u901a\u5e38\u53ef\u4ee5\u5728\u5e38\u6570\u65f6\u95f4\u5185\u5b8c\u6210\uff0c\u4e5f\u5c31\u662f\u8bf4\uff0c\u8fd9\u79cd\u64cd\u4f5c\u7684\u65f6\u95f4\u590d\u6742\u5ea6\u662f O(1)\u3002 \u56e0\u4e3a\u6570\u7ec4\u662f\u8fde\u7eed\u7684\u5185\u5b58\u7a7a\u95f4\uff0c\u4f4d\u4e8e\u672b\u5c3e\u7684\u63d2\u5165\u64cd\u4f5c\u4e0d\u9700\u8981\u79fb\u52a8\u4efb\u4f55\u5143\u7d20\uff0c\u4ec5\u4ec5\u6d89\u53ca\u5728\u672b\u5c3e\u6dfb\u52a0\u65b0\u5143\u7d20\uff0c\u5e76\u53ef\u80fd\u6d89\u53ca\u4e00\u4e9b\u989d\u5916\u7684\u5185\u5b58\u5206\u914d\uff08\u5982\u679c\u6570\u7ec4\u5df2\u6ee1\uff0c\u9700\u8981\u5206\u914d\u66f4\u5927\u7684\u6570\u7ec4\u6765\u5bb9\u7eb3\u65b0\u7684\u5143\u7d20\uff09\u3002 \u9700\u8981\u6ce8\u610f\u7684\u662f\uff0c\u5185\u5b58\u5206\u914d\u548c\u590d\u5236\u5143\u7d20\u5728\u5b9e\u9645\u64cd\u4f5c\u4e2d\u53ef\u80fd\u8fd8\u662f\u9700\u8981\u4e00\u4e9b\u65f6\u95f4\u7684\uff0c\u5c24\u5176\u662f\u5728\u6570\u7ec4\u5df2\u6ee1\u65f6\uff0c\u9700\u8981\u91cd\u65b0\u5206\u914d\u5e76\u590d\u5236\u6574\u4e2a\u6570\u7ec4\u5230\u65b0\u7684\u5185\u5b58\u5730\u5740\u3002\u4f46\u662f\u5728\u7406\u8bba\u5206\u6790\u65f6\uff0c\u6211\u4eec\u901a\u5e38\u5ffd\u7565\u8fd9\u79cd\u60c5\u51b5\uff0c\u56e0\u4e3a\u5b83\u662f\u4e00\u79cd\u88ab\u79f0\u4e3a\u644a\u8fd8\uff08amortized\uff09\u64cd\u4f5c\u7684\u7279\u4f8b\uff0c\u4ece\u957f\u671f\u7684\u5e73\u5747\u8fd0\u884c\u65f6\u95f4\u6765\u770b\uff0c\u8fd9\u79cd\u63d2\u5165\u64cd\u4f5c\u7684\u65f6\u95f4\u590d\u6742\u5ea6\u4ecd\u7136\u662f O(1) \u7684\u3002 4\uff0e\u5047\u8bbe\u6570\u7ec4\u5f53\u524d\u5305\u542b14\u4e2a\u5143\u7d20\uff0c\u5b83\u7684\u8d1f\u8f7d\u56e0\u5b50\u4e3a0.70\uff0c\u90a3\u4e48\u5b83\u7684\u7269\u7406\u5bb9\u91cf\u662f\u591a\u5c11\uff1f \u89e3\u7b54\uff1a\u8d1f\u8f7d\u56e0\u5b50\u901a\u5e38\u662f\u6307\u4e00\u4e2a\u54c8\u5e0c\u8868\u4e2d\u5df2\u5b58\u5143\u7d20\u6570\u91cf\u5bf9\u5e94\u4e8e\u5176\u5e95\u5c42\u6570\u7ec4\u5bb9\u91cf\u7684\u6bd4\u4f8b\u3002\u5bf9\u4e8e\u4e00\u822c\u7684\u6570\u7ec4\u548c Python \u7684 list\uff0c\u6211\u4eec\u901a\u5e38\u4e0d\u4f1a\u8c08\u8bba\u8d1f\u8f7d\u56e0\u5b50\uff0c\u56e0\u4e3a\u8fd9\u4e9b\u6570\u636e\u7ed3\u6784\u7684\u5927\u5c0f\u76f4\u63a5\u5bf9\u5e94\u4e8e\u5176\u4e2d\u5305\u542b\u7684\u5143\u7d20\u6570\u91cf\u3002 \u7136\u800c\uff0c\u5982\u679c\u4f60\u8981\u8ba1\u7b97\u4e00\u4e2a\u8d1f\u8f7d\u56e0\u5b50\u4e3a 0.70 \u7684\u5bb9\u5668\uff0c\u5e76\u4e14\u5b83\u5305\u542b\u4e8614\u4e2a\u5143\u7d20\uff0c\u90a3\u4e48\u5b83\u7684\u7269\u7406\u5bb9\u91cf\u53ef\u4ee5\u8ba1\u7b97\u4e3a\uff1a \u5143\u7d20\u6570\u91cf / \u8d1f\u8f7d\u56e0\u5b50 = \u5bb9\u91cf \u5728\u8fd9\u79cd\u60c5\u51b5\u4e0b\uff0c\u7269\u7406\u5bb9\u91cf\u5e94\u8be5\u662f 14 / 0.70 = 20\u3002\u6240\u4ee5\u7269\u7406\u5bb9\u91cf\u5e94\u8be5\u662f 20\u3002 4.3.\u4e8c\u7ef4\u6570\u7ec4\uff08\u7f51\u683c\uff09 \u00b6 \u4e00\u7ef4\u6570\u7ec4\uff08one-dimensional array\uff09 \u4e8c\u7ef4\u6570\u7ec4\uff08two-dimensional array\uff09\uff0c\u6216\u7f51\u683c\uff08grid\uff09 \u8981\u8bbf\u95eegrid\u91cc\u7684\u5143\u7d20\uff0c\u53ef\u4ee5\u901a\u8fc7\u4e24\u4e2a\u4e0b\u6807\u6765\u6307\u5b9a\u5176\u884c\u548c\u5217\u7684\u76f8\u5e94\u4f4d\u7f6e\uff0c\u5e76\u4e14\u8fd9\u4e24\u4e2a\u7d22\u5f15\u90fd\u662f\u4ece0\u5f00\u59cb\u7684\u3002 x = grid [ 2 ][ 3 ] # \u5c06\u4e8c\u7ef4\u6570\u7ec4\u7b2c\u4e8c\u884c\u7b2c\u4e09\u5217\u7684\u503c\u8d4b\u7ed9\u53d8\u91cfx 4.3.1.\u4f7f\u7528\u7f51\u683c \u00b6 \u9664\u4e86\u7528\u53cc\u4e0b\u6807\uff0c\u7f51\u683c\u8fd8\u5fc5\u987b\u8981\u6709\u4e24\u4e2a\u65b9\u6cd5\uff0c\u7528\u6765\u8fd4\u56de\u884c\u6570\u548c\u5217\u6570\u3002\u6211\u4eec\u628a\u8fd9\u4e24\u4e2a\u65b9\u6cd5\u5206\u522b\u547d\u540d\u4e3a getHeight \u548c getWidth \u3002 \u57fa\u4e8e4.3.3\u4e2d\u5b9a\u4e49\u7684Grid\u7c7b\uff0c\u4e0b\u9762\u8fd9\u6bb5\u4ee3\u7801\u4f1a\u5b9e\u4f8b\u5316\u4e00\u4e2a\u4e8c\u7ef4\u6570\u7ec4\uff0c\u5e76\u8ba1\u7b97\u53d8\u91cf my_grid \u91cc\u6240\u6709\u6570\u5b57\u7684\u603b\u548c\u3002\u5916\u90e8\u5faa\u73af\u4f1a\u8fed\u4ee35\u6b21\u5e76\u5411\u4e0b\u9010\u884c\u79fb\u52a8\uff0c\u5728\u6bcf\u6b21\u8fdb\u5165\u5916\u90e8\u5faa\u73af\u7684\u65f6\u5019\uff0c\u5185\u90e8\u5faa\u73af\u90fd\u4f1a\u8fed\u4ee35\u6b21\uff0c\u4ece\u800c\u5728\u4e0d\u540c\u884c\u7684\u5217\u4e4b\u95f4\u79fb\u52a8\u3002 my_grid = Grid ( 5 , 5 , 1 ) sum = 0 for row in range ( my_grid . getHeight ()): # Go through rows for column in range ( my_grid . getWidth ()): # Go through columns sum += my_grid [ row ][ column ] 4.3.2.\u521b\u5efa\u5e76\u521d\u59cb\u5316\u7f51\u683c \u00b6 \u57fa\u4e8e4.3.3\u4e2d\u5b9a\u4e49\u7684Grid\u7c7b\uff0c\u4e0b\u9762\u4ee3\u7801\u5b9e\u4f8b\u5316\u4e86\u4e00\u4e2a\u4e8c\u7ef4\u6570\u7ec4\uff0c\u904d\u5386\u8be5\u6570\u7ec4\u7684\u6bcf\u4e2a\u5143\u7d20\u5e76\u8d4b\u503c\u3002 my_grid = Grid ( 5 , 5 , 1 ) print ( my_grid ) # \u884c\u904d\u5386 for row in range ( my_grid . getHeight ()): # \u5217\u904d\u5386 for column in range ( my_grid . getWidth ()): my_grid [ row ][ column ] = int ( str ( row ) + str ( column )) 4.3.3.\u5b9a\u4e49Grid\u7c7b \u00b6 \u4e0b\u9762\u5b9e\u73b0\u4e86\u4e00\u4e2a Grid \u5bf9\u8c61\uff0c\u5305\u542b3\u4e2a\u53c2\u6570\uff08\u9ad8\u5ea6\u3001\u5bbd\u5ea6\u4ee5\u53ca\u521d\u59cb\u7684\u586b\u5145\u503c\uff09\u7684 Grid \u6784\u9020\u51fd\u6570\u3002 \u9ad8\u5ea6\uff0c\u5373\u884c\u6570\uff1b\u5bbd\u5ea6\uff0c\u5373\u5217\u6570\uff1b \u5b9e\u4f8b\u5316\u4e86\u4e00\u4e2a5\u884c5\u5217\u7684\u4e8c\u7ef4\u6570\u7ec4\uff1b class Array ( object ): \"\"\"\u63cf\u8ff0\u4e00\u4e2a\u6570\u7ec4\u3002\"\"\" def __init__ ( self , capacity , fillValue = None ): \"\"\"Capacity\u662f\u6570\u7ec4\u7684\u5927\u5c0f. fillValue\u4f1a\u586b\u5145\u5728\u6bcf\u4e2a\u5143\u7d20\u4f4d\u7f6e, \u9ed8\u8ba4\u503c\u662fNone\"\"\" # \u521d\u59cb\u5316\u6570\u7ec4\u7684\u903b\u8f91\u5c3a\u5bf8\u548c\u7269\u7406\u5c3a\u5bf8 self . logicalSize = 0 self . capacity = capacity self . fillValue = fillValue #\u521d\u59cb\u5316\u5185\u90e8\u6570\u7ec4\uff0c\u5e76\u586b\u5145\u5143\u7d20\u503c self . items = list () for count in range ( capacity ): self . items . append ( fillValue ) self . logicalSize += 1 # \u521d\u59cb\u5316\u6570\u7ec4\u7269\u7406\u5927\u5c0f\u65f6\uff0c\u4e5f\u540c\u65f6\u521d\u59cb\u5316\u5176\u903b\u8f91\u5927\u5c0f def __len__ ( self ): \"\"\"\u8fd4\u56de\u6570\u7ec4\u7684\u5927\u5c0f\"\"\" return len ( self . items ) def __str__ ( self ): \"\"\"\u5c06\u6570\u7ec4\u5b57\u7b26\u4e32\u5316\u5e76\u8fd4\u56de\"\"\" result = \"\" for index in range ( self . size ()): result += str ( self . items [ index ]) + \" \" return result def size ( self ): \"\"\"\u8fd4\u56de\u6570\u7ec4\u7684\u903b\u8f91\u5c3a\u5bf8\"\"\" return self . logicalSize def __iter__ ( self ): \"\"\"\u652f\u6301for\u5faa\u73af\u5bf9\u6570\u7ec4\u8fdb\u884c\u904d\u5386.\"\"\" print ( \"__iter__ called\" ) # \u4ec5\u7528\u6765\u6d4b\u8bd5\u4f55\u65f6__iter__\u4f1a\u88ab\u8c03\u7528 return iter ( self . items ) def __getitem__ ( self , index ): \"\"\" \u7528\u4e8e\u8bbf\u95ee\u7d22\u5f15\u5904\u7684\u4e0b\u6807\u8fd0\u7b97\u7b26. \u5148\u51b3\u6761\u4ef6: 0 <= index < size() \"\"\" if index < 0 or index >= self . size (): raise IndexError ( \"\u8bfb\u53d6\u64cd\u4f5c\u51fa\u9519, \u6570\u7ec4\u7d22\u5f15\u8d8a\u754c(\u4e0d\u5728\u6570\u7ec4\u903b\u8f91\u8fb9\u754c\u8303\u56f4\u5185)\" ) return self . items [ index ] def __setitem__ ( self , index , newItem ): \"\"\" \u4e0b\u6807\u8fd0\u7b97\u7b26\u7528\u4e8e\u5728\u7d22\u5f15\u5904\u8fdb\u884c\u66ff\u6362. \u5148\u51b3\u6761\u4ef6: 0 <= index < size() \"\"\" if index < 0 or index >= self . size (): raise IndexError ( \"\u66f4\u65b0\u64cd\u4f5c\u51fa\u9519, \u6570\u7ec4\u7d22\u5f15\u8d8a\u754c(\u4e0d\u5728\u6570\u7ec4\u903b\u8f91\u8fb9\u754c\u8303\u56f4\u5185)\" ) self . items [ index ] = newItem def __eq__ ( self , other ): \"\"\" \u4e24\u4e2a\u6570\u7ec4\u76f8\u7b49\u5219\u8fd4\u56deTrue, \u5426\u5219\u8fd4\u56deFalse \"\"\" # \u5224\u65ad\u4e24\u4e2a\u6570\u7ec4\u662f\u5426\u662f\u540c\u4e00\u4e2a\u5bf9\u8c61\uff0c\u6ce8\u610f\uff0c\u4e0d\u662f\u5b83\u4eec\u7684\u503c\u662f\u5426\u76f8\u7b49 if self is other : return True # \u5224\u65ad\u4e24\u4e2a\u5bf9\u8c61\u7c7b\u578b\u662f\u5426\u4e00\u6837 if type ( self ) != type ( other ): return False # \u5224\u65ad\u4e24\u4e2a\u6570\u7ec4\u5927\u5c0f\u662f\u5426\u4e00\u6837 if self . size () != other . size (): return False # \u6bd4\u8f83\u4e24\u4e2a\u6570\u7ec4\u7684\u503c\u662f\u5426\u4e00\u6837 for index in range ( self . size ()): if self [ index ] != other [ index ]: return False return True def grow ( self ): \"\"\"\u589e\u5927\u6570\u7ec4\u7269\u7406\u5c3a\u5bf8\"\"\" # \u57fa\u4e8e\u5f53\u524d\u7269\u7406\u5c3a\u5bf8\u52a0\u500d\uff0c\u5e76\u5c06fillValue\u8d4b\u503c\u5e95\u5c42\u5217\u8868\u7684\u65b0\u5143\u7d20 for count in range ( len ( self )): self . items . append ( self . fillValue ) def insert ( self , index , newItem ): \"\"\"\u5728\u6570\u7ec4\u6307\u5b9a\u7d22\u5f15\u5904\u63d2\u5165\u65b0\u5143\u7d20\"\"\" # \u5f53\u6570\u7ec4\u7684\u7269\u7406\u5c3a\u5bf8\u548c\u903b\u8f91\u5c3a\u5bf8\u4e00\u6837\u65f6\uff0c\u5219\u589e\u52a0\u7269\u7406\u5c3a\u5bf8 if self . size () == len ( self ): self . grow () # \u63d2\u5165\u65b0\u5143\u7d20 # \u5f53\u63d2\u5165\u4f4d\u7f6e\u5927\u4e8e\u6216\u7b49\u4e8e\u6700\u5927\u903b\u8f91\u4f4d\u7f6e\uff0c\u5219\u5728\u6570\u7ec4\u672b\u7aef\u63d2\u5165\u65b0\u5143\u7d20 # \u5f53\u63d2\u5165\u4f4d\u7f6e\u4ecb\u4e8e\u6570\u7ec4\u903b\u8f91\u4f4d\u7f6e\u7684\u4e2d\u95f4\uff0c\u5219\u4ece\u63d2\u5165\u4f4d\u7f6e\u8d77\u5c06\u5269\u4f59\u6570\u7ec4\u5143\u7d20\u5411\u5c3e\u90e8\u5e73\u79fb\u4e00\u4e2a\u4f4d\u7f6e if index >= self . size (): self . items [ self . size ()] = newItem else : index = max ( index , 0 ) # \u5c06\u6570\u7ec4\u5143\u7d20\u5411\u5c3e\u90e8\u5e73\u79fb\u4e00\u4e2a\u4f4d\u7f6e for i in range ( self . size (), index , - 1 ): self . items [ i ] = self . items [ i - 1 ] # \u63d2\u5165\u65b0\u5143\u7d20 self . items [ index ] = newItem # \u589e\u52a0\u6570\u7ec4\u7684\u903b\u8f91\u5c3a\u5bf8 self . logicalSize += 1 def shrink ( self ): \"\"\" \u51cf\u5c11\u6570\u7ec4\u7684\u7269\u7406\u5c3a\u5bf8 \u5f53: - \u6570\u7ec4\u7684\u903b\u8f91\u5c3a\u5bf8\u5c0f\u4e8e\u6216\u7b49\u4e8e\u5176\u7269\u7406\u5c3a\u5bf8\u76841/4 - \u5e76\u4e14\u5b83\u7684\u7269\u7406\u5c3a\u5bf8\u81f3\u5c11\u662f\u8fd9\u4e2a\u6570\u7ec4\u5efa\u7acb\u65f6\u9ed8\u8ba4\u5bb9\u91cf\u76842\u500d\u65f6 \u5219\u628a\u6570\u7ec4\u7684\u7269\u7406\u5c3a\u5bf8\u51cf\u5c0f\u5230\u539f\u6765\u7684\u4e00\u534a\uff0c\u5e76\u4e14\u4e5f\u4e0d\u4f1a\u5c0f\u4e8e\u5176\u9ed8\u8ba4\u5bb9\u91cf \"\"\" # \u5728\u903b\u8f91\u5c3a\u5bf8\u548c\u7269\u7406\u5c3a\u5bf8\u7684\u4e00\u534a\u4e4b\u95f4\u9009\u62e9\u6700\u5927\u503c\u4f5c\u4e3a\u6570\u7ec4\u6536\u7f29\u540e\u7684\u7269\u7406\u5c3a\u5bf8 newSize = max ( self . capacity , len ( self ) // 2 ) # \u91ca\u653e\u591a\u4f59\u7684\u6570\u7ec4\u7a7a\u95f4 for count in range ( len ( self ) - newSize ): self . items . pop () def pop ( self , index ): \"\"\" \u5220\u9664\u6307\u5b9a\u7d22\u5f15\u503c\u7684\u6570\u7ec4\u5143\u7d20,\u5e76\u8fd4\u56de\u5220\u9664\u7684\u6570\u7ec4\u5143\u7d20\u503c \u5148\u51b3\u6761\u4ef6: 0 <= index < size() \"\"\" if index < 0 or index >= self . size (): raise IndexError ( \"\u5220\u9664\u64cd\u4f5c\u51fa\u9519, \u6570\u7ec4\u7d22\u5f15\u8d8a\u754c(\u4e0d\u5728\u6570\u7ec4\u903b\u8f91\u8fb9\u754c\u8303\u56f4\u5185)\" ) # \u4fdd\u5b58\u5373\u5c06\u88ab\u5220\u9664\u7684\u6570\u7ec4\u5143\u7d20\u503c itemToReturn = self . items [ index ] # \u5c06\u6570\u7ec4\u5143\u7d20\u5411\u5934\u90e8\u5e73\u79fb\u4e00\u4e2a\u4f4d\u7f6e for i in range ( index , self . size () - 1 ): self . items [ i ] = self . items [ i + 1 ] # \u5c06\u6570\u7ec4\u5c3e\u90e8\u7684\u7a7a\u4f59\u4f4d\u8d4b\u503cfillValue\uff0c\u9ed8\u8ba4\u662fNone self . items [ self . size () - 1 ] = self . fillValue # \u51cf\u5c11\u6570\u7ec4\u903b\u8f91\u5c3a\u5bf8 self . logicalSize -= 1 # \u51cf\u5c11\u6570\u7ec4\u7269\u7406\u5c3a\u5bf8 # \u5f53: # - \u6570\u7ec4\u7684\u903b\u8f91\u5c3a\u5bf8\u5c0f\u4e8e\u6216\u7b49\u4e8e\u5176\u7269\u7406\u5c3a\u5bf8\u76841/4 # - \u5e76\u4e14\u5b83\u7684\u7269\u7406\u5c3a\u5bf8\u81f3\u5c11\u662f\u8fd9\u4e2a\u6570\u7ec4\u5efa\u7acb\u65f6\u9ed8\u8ba4\u5bb9\u91cf\u76842\u500d\u65f6 # \u5219\u628a\u6570\u7ec4\u7684\u7269\u7406\u5c3a\u5bf8\u51cf\u5c0f\u5230\u539f\u6765\u7684\u4e00\u534a\uff0c\u5e76\u4e14\u4e5f\u4e0d\u4f1a\u5c0f\u4e8e\u5176\u9ed8\u8ba4\u5bb9\u91cf if self . size () <= len ( self ) // 4 and len ( self ) > self . capacity : self . shrink () # \u8fd4\u56de\u88ab\u5220\u9664\u5143\u7d20\u7684\u503c print ( f 'Item { itemToReturn } was deleted' ) return itemToReturn class Grid ( object ): \"\"\"\u63cf\u8ff0\u4e00\u4e2a\u4e8c\u7ef4\u6570\u7ec4\u3002\"\"\" def __init__ ( self , rows , columns , fillValue = None ): self . rows = rows self . columns = columns self . fillValue = fillValue # \u6309\u884c\u6570\u521d\u59cb\u5316\u6570\u7ec4y\u8f74\u7269\u7406\u5c3a\u5bf8 self . data = Array ( rows , fillValue ) # \u6309\u5217\u6570\u521d\u59cb\u5316\u6570\u7ec4x\u8f74\u7269\u7406\u5c3a\u5bf8\uff0c\u5e76\u8d4b\u503c\u5230y\u8f74\u6570\u7ec4\uff0c\u586b\u5145None\u503c for row in range ( rows ): self . data [ row ] = Array ( columns , fillValue ) def getHeight ( self ): \"\"\"\u8fd4\u56de\u4e8c\u7ef4\u6570\u7ec4\u7684y\u8f74\u7684\u5927\u5c0f(\u7269\u7406\u5c3a\u5bf8), \u5373\u6570\u7ec4\u7684\u884c\u6570\"\"\" return len ( self . data ) def getWidth ( self ): \"\"\"\u8fd4\u56de\u4e8c\u7ef4\u6570\u7ec4\u7684x\u8f74\u7684\u5927\u5c0f(\u7269\u7406\u5c3a\u5bf8), \u5373\u6570\u7ec4\u7684\u5217\u6570\"\"\" return len ( self . data [ 0 ]) def __getitem__ ( self , index ): \"\"\"\u8fd4\u56de\u4e8c\u7ef4\u6570\u7ec4\u6307\u5b9a\u884c\u548c\u5217\u7d22\u5f15\u5bf9\u5e94\u7684\u5143\u7d20\u503c\"\"\" return self . data [ index ] def __str__ ( self ): \"\"\"\u8fd4\u56de\u4e8c\u7ef4\u6570\u7ec4\u7684\u5b57\u7b26\u4e32\u5f62\u5f0f\"\"\" result = \"\" for row in range ( self . getHeight ()): for col in range ( self . getWidth ()): result += str ( self . data [ row ][ col ]) + \" \" result += \" \\n \" return result def main (): my_grid = Grid ( 5 , 5 , 1 ) print ( my_grid ) if __name__ == \"__main__\" : main () # \u8fd0\u884c\u7ed3\u679c # 1 1 1 1 1 # 1 1 1 1 1 # 1 1 1 1 1 # 1 1 1 1 1 # 1 1 1 1 1 4.3.4.\u53c2\u5dee\u4e0d\u9f50\u7684\u7f51\u683c\u548c\u591a\u7ef4\u6570\u7ec4 \u00b6 \u5230\u76ee\u524d\u4e3a\u6b62\uff0c\u6211\u4eec\u6240\u8ba8\u8bba\u7684\u7f51\u683c\u90fd\u662f\u4e8c\u7ef4\u5e76\u4e14\u662f\u77e9\u5f62\u7684\u3002\u6211\u4eec\u4e5f\u53ef\u4ee5\u628a\u7f51\u683c\u521b\u5efa\u6210\u53c2\u5dee\u4e0d\u9f50\u7684\u6837\u5b50\uff0c\u4e5f\u53ef\u4ee5\u521b\u5efa\u9ad8\u4e8e\u4e24\u4e2a\u7ef4\u5ea6\u7684\u7f51\u683c\u3002 \u53c2\u5dee\u4e0d\u9f50\u7684\u7f51\u683c\u6709\u56fa\u5b9a\u7684\u884c\u6570\uff0c\u4f46\u662f\u6bcf\u4e00\u884c\u91cc\u7684\u6570\u636e\u5217\u6570\u5404\u6709\u4e0d\u540c\u3002\u5217\u8868\u6570\u7ec4\u6216\u6570\u7ec4\u662f\u53ef\u4ee5\u5b9e\u73b0\u8fd9\u79cd\u7f51\u683c\u7684\u5408\u9002\u7ed3\u6784\u3002 \u6bd4\u5982\uff0c\u53ef\u4ee5\u521b\u5efa\u4e00\u4e2a\u4e09\u7ef4\u6570\u7ec4\u7684\u65f6\u5019\u9700\u8981\u6307\u5b9a\u5b83\u7684\u6df1\u5ea6\u3001\u9ad8\u5ea6\u4ee5\u53ca\u5bbd\u5ea6\u3002\u56e0\u6b64\u53ef\u4ee5\u7ed9\u6570\u7ec4\u7c7b\u578b\u6dfb\u52a0\u4e00\u4e2a\u53eb\u4f5c getDepth \u7684\u65b9\u6cd5\uff0c\u4ece\u800c\u50cf getWidth \u548c getHeight \u65b9\u6cd5\u4e00\u6837\u518d\u5f97\u5230\u8fd9\u4e2a\u7ef4\u5ea6\u7684\u76f8\u5173\u6570\u636e\u3002\u5728\u8fd9\u4e2a\u5b9e\u73b0\u91cc\uff0c\u6bcf\u4e2a\u5143\u7d20\u90fd\u53ef\u4ee5\u901a\u8fc73\u4e2a\u4f5c\u4e3a\u7d22\u5f15\u7684\u6574\u6570\u8fdb\u884c\u8bbf\u95ee\uff0c\u4e5f\u53ef\u4ee5\u901a\u8fc7\u67093\u5c42\u5faa\u73af\u7684\u63a7\u5236\u8bed\u53e5\u7ed3\u6784\u6765\u4f7f\u7528\u5b83\u3002 4.3.5.\u7ec3\u4e60\u9898 \u00b6 1\uff0e\u4ec0\u4e48\u662f\u4e8c\u7ef4\u6570\u7ec4\uff08\u7f51\u683c\uff09\uff1f \u89e3\u7b54\uff1a\u4e8c\u7ef4\u6570\u7ec4\uff0c\u6709\u65f6\u88ab\u79f0\u4e3a\u7f51\u683c\uff0c\u662f\u4e00\u4e2a\u6570\u636e\u7ed3\u6784\uff0c\u5b83\u5141\u8bb8\u6211\u4eec\u5c06\u6570\u636e\u4ee5\u8868\u683c\u5f62\u5f0f\u7ec4\u7ec7\u8d77\u6765\uff0c\u5373\u6570\u636e\u5728\u4e24\u4e2a\u7ef4\u5ea6\u4e0a\u8fdb\u884c\u7ec4\u7ec7\u3002\u53ef\u4ee5\u628a\u4e8c\u7ef4\u6570\u7ec4\u770b\u4f5c\u662f\u4e00\u4e2a\u6570\u7ec4\u7684\u6570\u7ec4\u3002\u4f8b\u5982\uff0c\u5728 Python \u4e2d\uff0c\u4e00\u4e2a\u4e8c\u7ef4\u6570\u7ec4\u53ef\u4ee5\u662f\u4e00\u4e2a\u5217\u8868\u7684\u5217\u8868\u3002 \u5728\u4e8c\u7ef4\u6570\u7ec4\u4e2d\uff0c\u6bcf\u4e2a\u5143\u7d20\u90fd\u7531\u4e24\u4e2a\u7d22\u5f15\u786e\u5b9a\uff0c\u901a\u5e38\u79f0\u4e3a\u884c\u7d22\u5f15\u548c\u5217\u7d22\u5f15\u3002\u53ef\u4ee5\u8fd9\u6837\u7406\u89e3\uff1a\u9996\u5148\u9009\u5b9a\u4e00\u4e2a\u884c\uff0c\u7136\u540e\u518d\u5728\u8be5\u884c\u4e2d\u9009\u62e9\u4e00\u4e2a\u5143\u7d20\u3002\u7528\u4efb\u4f55\u4e00\u79cd\u7f16\u7a0b\u8bed\u8a00\u521b\u5efa\u548c\u64cd\u4f5c\u4e8c\u7ef4\u6570\u7ec4\u7684\u5177\u4f53\u8bed\u6cd5\u90fd\u4e0d\u5c3d\u76f8\u540c\uff0c\u4f46\u662f\u539f\u7406\u662f\u4e00\u6837\u7684\u3002 \u5728 Python \u4e2d\uff0c\u521b\u5efa\u4e8c\u7ef4\u6570\u7ec4\u7684\u4f8b\u5b50\u5982\u4e0b\uff1a # \u521b\u5efa\u4e00\u4e2a 3x3 \u7684\u4e8c\u7ef4\u6570\u7ec4 grid = [[ 1 , 2 , 3 ], [ 4 , 5 , 6 ], [ 7 , 8 , 9 ]] # \u8bbf\u95ee\u4e8c\u7ef4\u6570\u7ec4\u4e2d\u7279\u5b9a\u7684\u5143\u7d20 print ( grid [ 1 ][ 2 ]) # \u8f93\u51fa\uff1a6 2\uff0e\u8bf7\u63cf\u8ff0\u4e00\u4e2a\u53ef\u80fd\u4f1a\u7528\u5230\u4e8c\u7ef4\u6570\u7ec4\u7684\u5e94\u7528\u7a0b\u5e8f\u3002 \u89e3\u7b54\uff1a\u4e8c\u7ef4\u6570\u7ec4\u5728\u5404\u79cd\u7c7b\u578b\u7684\u5e94\u7528\u7a0b\u5e8f\u4e2d\u90fd\u88ab\u5e7f\u6cdb\u4f7f\u7528\u3002\u4e00\u4e2a\u5e38\u89c1\u7684\u4f8b\u5b50\u662f\u5728\u5904\u7406\u56fe\u50cf\u6216\u50cf\u7d20\u7684\u5e94\u7528\u4e2d\u3002 \u56fe\u50cf\u53ef\u4ee5\u88ab\u770b\u4f5c\u4e00\u4e2a\u4e8c\u7ef4\u6570\u7ec4\uff08\u6216\u8005\u5728\u5f69\u8272\u56fe\u50cf\u4e2d\uff0c\u662f\u4e00\u4e2a\u4e09\u7ef4\u6570\u7ec4\uff0c\u4e09\u4e2a\u901a\u9053\u5206\u522b\u662f\u7ea2\u3001\u7eff\u3001\u84dd\uff09\uff0c\u5176\u4e2d\u6bcf\u4e2a\u5143\u7d20\u8868\u793a\u4e00\u4e2a\u50cf\u7d20\u3002\u4e8c\u7ef4\u6570\u7ec4\u4e2d\u7684\u884c\u548c\u5217\u5bf9\u5e94\u4e8e\u56fe\u50cf\u7684\u5bbd\u5ea6\u548c\u9ad8\u5ea6\uff0c\u5143\u7d20\u503c\u901a\u5e38\u4ee3\u8868\u50cf\u7d20\u7684\u989c\u8272\u6df1\u5ea6\u3002 \u4f8b\u5982\uff0c\u4ee5\u4e0b Python \u4ee3\u7801\u521b\u5efa\u4e86\u4e00\u4e2a\u7b80\u5355\u7684\u7070\u5ea6\u56fe\u50cf\uff0c\u5e76\u4f7f\u7528 matplotlib \u5e93\u663e\u793a\u5b83\uff1a import numpy as np import matplotlib.pyplot as plt # \u521b\u5efa\u4e00\u4e2a 10x10 \u7684\u4e8c\u7ef4\u6570\u7ec4\uff0c\u6bcf\u4e2a\u5143\u7d20\u503c\u4e3a 0-255 \u4e4b\u95f4\u7684\u968f\u673a\u6574\u6570 image = np . random . randint ( 0 , 256 , ( 10 , 10 )) # \u663e\u793a\u8fd9\u4e2a\u56fe\u50cf plt . imshow ( image , cmap = 'gray' ) plt . show () \u5728\u8fd9\u4e2a\u4f8b\u5b50\u4e2d\uff0c\u6211\u4eec\u4f7f\u7528\u4e86 NumPy \u5e93\u6765\u521b\u5efa\u548c\u64cd\u4f5c\u4e8c\u7ef4\u6570\u7ec4\uff08\u5728 NumPy \u4e2d\uff0c\u8fd9\u79cd\u7ed3\u6784\u88ab\u79f0\u4e3a ndarray\uff09\u3002\u8fd9\u662f\u5904\u7406\u5927\u89c4\u6a21\u6570\u503c\u6570\u636e\u7684\u4e00\u4e2a\u975e\u5e38\u597d\u7684\u5de5\u5177\uff0c\u5c24\u5176\u662f\u5bf9\u4e8e\u6d89\u53ca\u5230\u79d1\u5b66\u8ba1\u7b97\u548c\u6570\u636e\u5206\u6790\u7684\u5e94\u7528\u7a0b\u5e8f\u3002 \u6b64\u5916\uff0c\u4e8c\u7ef4\u6570\u7ec4\u4e5f\u5e7f\u6cdb\u5e94\u7528\u4e8e\u6e38\u620f\u5f00\u53d1\uff08\u5982\u68cb\u76d8\u6e38\u620f\uff0c\u5982\u56fd\u9645\u8c61\u68cb\u6216\u4e95\u5b57\u6e38\u620f\u7684\u68cb\u76d8\u53ef\u4ee5\u7528\u4e8c\u7ef4\u6570\u7ec4\u6765\u8868\u793a\uff09\u3001\u7269\u7406\u6a21\u62df\u3001\u7cfb\u7edf\u52a8\u529b\u5b66\u6a21\u4eff\u3001\u5730\u7406\u4fe1\u606f\u7cfb\u7edf\uff08\u5730\u56fe\u53ef\u4ee5\u8868\u793a\u4e3a\u4e8c\u7ef4\u6570\u7ec4\u7684\u9ad8\u7a0b\u6570\u636e\uff09\u7b49\u8bb8\u591a\u9886\u57df\u3002 3\uff0e\u7f16\u5199\u4e00\u4e2a\u7a0b\u5e8f\uff0c\u4f7f\u4e4b\u53ef\u4ee5\u5728Grid\u5bf9\u8c61\u91cc\u641c\u7d22\u4e00\u4e2a\u8d1f\u6574\u6570\u3002\u5faa\u73af\u5e94\u8be5\u5728\u9047\u5230\u7f51\u683c\u91cc\u7684\u7b2c\u4e00\u4e2a\u8d1f\u6574\u6570\u7684\u5730\u65b9\u7ec8\u6b62\uff0c\u8fd9\u65f6\u53d8\u91cfrow\u548ccolumn\u5e94\u8be5\u88ab\u8bbe\u7f6e\u4e3a\u8fd9\u4e2a\u8d1f\u6570\u7684\u4f4d\u7f6e\u3002\u5982\u679c\u5728\u7f51\u683c\u91cc\u627e\u4e0d\u5230\u8d1f\u6570\uff0c\u90a3\u4e48\u53d8\u91cfrow\u548ccolumn\u5e94\u8be5\u7b49\u4e8e\u7f51\u683c\u7684\u884c\u6570\u548c\u5217\u6570\u3002 \u89e3\u7b54\uff1a\u5728Grid\u7c7b\u4e2d\u6dfb\u52a0\u4e0b\u9762\u7684\u65b9\u6cd5\uff0c\u53ef\u4ee5\u5b9e\u73b0\u63d0\u540d\u4e2d\u7684\u8981\u6c42 def find_negative ( self ): \"\"\"\u8fd4\u56de\u7b2c\u4e00\u4e2a\u8d1f\u6574\u6570\u7684\u7d22\u5f15\u503c\"\"\" target_row = 0 target_col = 0 for row in range ( self . getHeight ()): for col in range ( self . getWidth ()): # \u5982\u679c\u5f53\u524d\u5143\u7d20\u662f\u8d1f\u6570 if self . data [ row ][ col ] < 0 : # \u66f4\u65b0 row \u548c column \u4e3a\u8be5\u5143\u7d20\u7684\u4f4d\u7f6e target_row = row target_col = col # \u7ec8\u6b62\u5faa\u73af break # \u5982\u679c\u5df2\u627e\u5230\u8d1f\u6570\uff0c\u7ec8\u6b62\u5916\u5c42\u5faa\u73af if self . data [ row ][ col ] < 0 : break # \u8fd4\u56de\u8d1f\u6570\u7684\u4f4d\u7f6e\uff0c\u6216\u8005\u5982\u679c\u6ca1\u6709\u627e\u5230\u8d1f\u6570\uff0c\u8fd4\u56de\u884c\u6570\u548c\u5217\u6570 return row , col import random def main (): my_grid = Grid ( 5 , 5 , random . randint ( - 10 , 10 )) print ( my_grid ) print ( my_grid . find_negative ()) 4\uff0e\u8bf4\u8bf4\u8fd0\u884c\u4e0b\u9762\u8fd9\u6bb5\u4ee3\u7801\u540e\u7f51\u683c\u91cc\u7684\u5185\u5bb9\u662f\u4ec0\u4e48\u3002 matrix = Grid ( 3 , 3 ) for row in range ( matrix . getHeight ()): for column in range ( matrix . getWidth ()): matrix [ row ][ column ] = row * column \u89e3\u7b54\uff1a\u8fd9\u6bb5\u4ee3\u7801\u9996\u5148\u521b\u5efa\u4e86\u4e00\u4e2a3x3\u7684\u7f51\u683c\uff08\u6216\u4e8c\u7ef4\u6570\u7ec4\uff09\uff0c\u7136\u540e\u4f7f\u7528\u4e24\u4e2a\u5d4c\u5957\u7684for\u5faa\u73af\u6765\u904d\u5386\u8fd9\u4e2a\u7f51\u683c\u7684\u6bcf\u4e00\u4e2a\u5143\u7d20\u3002\u5bf9\u4e8e\u7f51\u683c\u4e2d\u7684\u6bcf\u4e00\u4e2a\u5143\u7d20\uff0c\u5b83\u7684\u503c\u88ab\u8bbe\u7f6e\u4e3a\u5176\u884c\u7d22\u5f15\u4e58\u4ee5\u5217\u7d22\u5f15\u3002\u7531\u4e8e\u7b2c\u4e00\u884c\u548c\u7b2c\u4e00\u5217\u7684\u7d22\u5f15\u90fd\u662f0\uff0c\u6240\u4ee5\u7b2c\u4e00\u884c\u548c\u7b2c\u4e00\u5217\u7684\u5143\u7d20\u503c\u90fd\u662f0\uff08\u56e0\u4e3a\u4efb\u4f55\u6570\u4e58\u4ee50\u90fd\u7b49\u4e8e0\uff09\u3002\u5176\u5b83\u5143\u7d20\u7684\u503c\u7b49\u4e8e\u5b83\u4eec\u7684\u884c\u7d22\u5f15\u4e58\u4ee5\u5217\u7d22\u5f15\u3002 0 0 0 0 1 2 0 2 4 5\uff0e\u7f16\u5199\u4e00\u6bb5\u4ee3\u7801\u4ee5\u521b\u5efa\u4e00\u4e2a\u53c2\u5dee\u4e0d\u9f50\u7684\u7f51\u683c\uff0c\u5b83\u7684\u884c\u5206\u522b\u7528\u6765\u5b58\u50a83\u4e2a\u30016\u4e2a\u548c9\u4e2a\u5143\u7d20\u3002 \u89e3\u7b54\uff1a\u4f7f\u7528\u5217\u8868\u7684\u5217\u8868\uff08\u5373\u5217\u8868\u7684\u5d4c\u5957\uff09\u6765\u521b\u5efa\u53c2\u5dee\u4e0d\u9f50\u7684\u7f51\u683c\u3002\u4e0b\u9762\u662fPython\u5b9e\u73b0\u4ee3\u7801\uff1a # \u521b\u5efa\u7a7a\u7f51\u683c grid = [] # \u4e3a\u7f51\u683c\u6dfb\u52a0\u884c grid . append ([ \"\" ] * 3 ) # \u7b2c\u4e00\u884c3\u4e2a\u5143\u7d20 grid . append ([ \"\" ] * 6 ) # \u7b2c\u4e8c\u884c6\u4e2a\u5143\u7d20 grid . append ([ \"\" ] * 9 ) # \u7b2c\u4e09\u884c9\u4e2a\u5143\u7d20 # \u6253\u5370\u7f51\u683c for row in grid : print ( row ) \u4e0a\u9762\u4ee3\u7801\u521b\u5efa\u4e00\u4e2a\u5177\u6709\u4e09\u884c\u7684\u7f51\u683c\uff0c\u5176\u4e2d\u7b2c\u4e00\u884c\u6709\u4e09\u4e2a\u5143\u7d20\uff0c\u7b2c\u4e8c\u884c\u6709\u516d\u4e2a\u5143\u7d20\uff0c\u7b2c\u4e09\u884c\u6709\u4e5d\u4e2a\u5143\u7d20\u3002\u6bcf\u4e2a\u5143\u7d20\u6700\u521d\u90fd\u88ab\u8bbe\u7f6e\u4e3a\u4e00\u4e2a\u7a7a\u5b57\u7b26\u4e32\uff0c\u8fd9\u4e2a\u7f51\u683c\u7684\u5f62\u72b6\u5c06\u7c7b\u4f3c\u4e8e\uff1a [ '' , '' , '' ] [ '' , '' , '' , '' , '' , '' ] [ '' , '' , '' , '' , '' , '' , '' , '' , '' ] 6\uff0e\u63d0\u4f9b\u4e00\u4e2a\u628aGrid\u7c7b\u7528\u4f5c\u6570\u636e\u7ed3\u6784\u6765\u5b9e\u73b0\u4e09\u7ef4array\u7c7b\u7684\u7b56\u7565\u3002 \u89e3\u7b54\uff1a\u4ee3\u7801\u5b9e\u73b0\u5982\u4e0b\uff1a class ThreeDArray ( object ): \"\"\"\u63cf\u8ff0\u4e00\u4e2a\u4e09\u7ef4\u6570\u7ec4\u3002\"\"\" def __init__ ( self , depth , rows , columns , fillValue = None ): self . depth = depth self . rows = rows self . columns = columns self . fillValue = fillValue # \u521d\u59cb\u5316\u4e09\u7ef4\u6570\u7ec4\uff0c\u6309\u7167\u6df1\u5ea6\u521d\u59cb\u5316\u6bcf\u4e00\u5c42\u4e3a\u4e00\u4e2a\u4e8c\u7ef4\u6570\u7ec4 self . data = Array ( depth , fillValue ) for d in range ( depth ): self . data [ d ] = Grid ( rows , columns , fillValue ) def getDepth ( self ): \"\"\"\u8fd4\u56de\u4e09\u7ef4\u6570\u7ec4\u7684z\u8f74\u5927\u5c0f, \u5373\u6570\u7ec4\u7684\u6df1\u5ea6\"\"\" return len ( self . data ) def get_element ( self , depth , row , column ): \"\"\"\u83b7\u53d6\u6307\u5b9a\u6df1\u5ea6\u3001\u884c\u548c\u5217\u7684\u5143\u7d20\"\"\" return self . data [ depth ][ row ][ column ] def set_element ( self , depth , row , column , new_value ): \"\"\"\u8bbe\u7f6e\u6307\u5b9a\u6df1\u5ea6\u3001\u884c\u548c\u5217\u7684\u5143\u7d20\"\"\" self . data [ depth ][ row ][ column ] = new_value def add_element ( self , depth , row , column , value ): \"\"\"\u5728\u6307\u5b9a\u6df1\u5ea6\u3001\u884c\u548c\u5217\u6dfb\u52a0\u5143\u7d20 \"\"\" if self . data [ depth ][ row ][ column ] == self . fillValue : self . data [ depth ][ row ][ column ] = value else : raise Exception ( \"\u5143\u7d20\u6dfb\u52a0\u5931\u8d25\" ) def remove_element ( self , depth , row , column ): \"\"\"\u5728\u6307\u5b9a\u6df1\u5ea6\u3001\u884c\u548c\u5217\u5220\u9664\u5143\u7d20 \"\"\" if self . data [ depth ][ row ][ column ] != self . fillValue : self . data [ depth ][ row ][ column ] = self . fillValue else : raise Exception ( \"\u5143\u7d20\u5220\u9664\u5931\u8d25\" ) def __str__ ( self ): result = \"\" for depth in range ( self . getDepth ()): result += f \"Depth { depth } : \\n \" for row in range ( self . rows ): for column in range ( self . columns ): result += str ( self . data [ depth ][ row ][ column ]) + \" \\t \" result += \" \\n \" return result def main (): print ( \"---Initial 3D Array---\" ) my_3d = ThreeDArray ( 3 , 2 , 2 , 9 ) print ( my_3d ) print ( \"---Add element into 3D Array---\" ) my_3d . add_element ( 0 , 1 , 1 , 0 ) my_3d . add_element ( 1 , 1 , 1 , 1 ) my_3d . add_element ( 2 , 1 , 1 , 2 ) print ( my_3d ) print ( \"---Remove element from 3D Array---\" ) my_3d . remove_element ( 1 , 1 , 1 ) print ( my_3d ) if __name__ == \"__main__\" : main () # \u8fd0\u884c\u7ed3\u679c # ---Initial 3D Array--- # Depth 0: # 9 9 # 9 9 # Depth 1: # 9 9 # 9 9 # Depth 2: # 9 9 # 9 9 # ---Add element into 3D Array--- # Depth 0: # 9 9 # 9 0 # Depth 1: # 9 9 # 9 1 # Depth 2: # 9 9 # 9 2 # ---Remove element from 3D Array--- # Depth 0: # 9 9 # 9 0 # Depth 1: # 9 9 # 9 9 # Depth 2: # 9 9 # 9 2 7\uff0e\u7f16\u5199\u4e00\u6bb5\u4ee3\u7801\uff1a\u8fd9\u6bb5\u4ee3\u7801\u4f1a\u628a\u4e09\u7ef4\u6570\u7ec4\u91cc\u6bcf\u4e2a\u5355\u5143\u7684\u503c\u90fd\u521d\u59cb\u5316\u4e3a\u5b83\u76843\u4e2a\u7d22\u5f15\u4f4d\u7f6e\u3002\u4f8b\u5982\uff0c\u5982\u679c\u4f4d\u7f6e\u662f\uff08\u6df1\u5ea6\u3001\u884c\u3001\u5217\uff09\uff0c\u5219\u5bf9\u4e8e\u4f4d\u7f6e\uff082\u30013\u30013\uff09\u6765\u8bf4\uff0c\u5b83\u7684\u503c\u5c31\u662f233\u3002 \u89e3\u7b54\uff1a\u4fee\u6539\u4e0a\u9762\u7684\u4ee3\u7801\u4e2d\u7684 __init__ \u548c __str__ \u65b9\u6cd5\uff0c\u4ee3\u7801\u5b9e\u73b0\u5982\u4e0b\u3002 class ThreeDArray ( object ): \"\"\"\u63cf\u8ff0\u4e00\u4e2a\u4e09\u7ef4\u6570\u7ec4\u3002\"\"\" # def __init__(self, depth, rows, columns, fillValue=None): # self.depth = depth # self.rows = rows # self.columns = columns # self.fillValue = fillValue # # \u521d\u59cb\u5316\u4e09\u7ef4\u6570\u7ec4\uff0c\u6309\u7167\u6df1\u5ea6\u521d\u59cb\u5316\u6bcf\u4e00\u5c42\u4e3a\u4e00\u4e2a\u4e8c\u7ef4\u6570\u7ec4 # self.data = Array(depth, fillValue) # for d in range(depth): # self.data[d] = Grid(rows, columns, fillValue) def __init__ ( self , depth , rows , columns ): self . depth = depth self . rows = rows self . columns = columns # \u521d\u59cb\u5316\u4e09\u7ef4\u6570\u7ec4\uff0c\u6309\u7167\u6df1\u5ea6\u521d\u59cb\u5316\u6bcf\u4e00\u5c42\u4e3a\u4e00\u4e2a\u4e8c\u7ef4\u6570\u7ec4 self . data = Array ( depth ) for d in range ( depth ): self . data [ d ] = Grid ( rows , columns ) for r in range ( rows ): for c in range ( columns ): # \u5c06\u6bcf\u4e2a\u4f4d\u7f6e\u7684\u7d22\u5f15\u62fc\u63a5\u6210\u5b57\u7b26\u4e32\u4f5c\u4e3a\u5143\u7d20\u503c self . data [ d ][ r ][ c ] = str ( d ) + str ( r ) + str ( c ) def getDepth ( self ): \"\"\"\u8fd4\u56de\u4e09\u7ef4\u6570\u7ec4\u7684z\u8f74\u5927\u5c0f, \u5373\u6570\u7ec4\u7684\u6df1\u5ea6\"\"\" return len ( self . data ) def get_element ( self , depth , row , column ): \"\"\"\u83b7\u53d6\u6307\u5b9a\u6df1\u5ea6\u3001\u884c\u548c\u5217\u7684\u5143\u7d20\"\"\" return self . data [ depth ][ row ][ column ] def set_element ( self , depth , row , column , new_value ): \"\"\"\u8bbe\u7f6e\u6307\u5b9a\u6df1\u5ea6\u3001\u884c\u548c\u5217\u7684\u5143\u7d20\"\"\" self . data [ depth ][ row ][ column ] = new_value def add_element ( self , depth , row , column , value ): \"\"\"\u5728\u6307\u5b9a\u6df1\u5ea6\u3001\u884c\u548c\u5217\u6dfb\u52a0\u5143\u7d20 \"\"\" if self . data [ depth ][ row ][ column ] == self . fillValue : self . data [ depth ][ row ][ column ] = value else : raise Exception ( \"\u5143\u7d20\u6dfb\u52a0\u5931\u8d25\" ) def remove_element ( self , depth , row , column ): \"\"\"\u5728\u6307\u5b9a\u6df1\u5ea6\u3001\u884c\u548c\u5217\u5220\u9664\u5143\u7d20 \"\"\" if self . data [ depth ][ row ][ column ] != self . fillValue : self . data [ depth ][ row ][ column ] = self . fillValue else : raise Exception ( \"\u5143\u7d20\u5220\u9664\u5931\u8d25\" ) # def __str__(self): # result = \"\" # for depth in range(self.getDepth()): # result += f\"Depth {depth}:\\n\" # for row in range(self.rows): # for column in range(self.columns): # result += str(self.data[depth][row][column]) + \"\\t\" # result += \"\\n\" # return result def __str__ ( self ): result = \"\" for depth in range ( self . getDepth ()): result += f \"Depth { depth } : \\n \" for row in range ( self . rows ): for column in range ( self . columns ): result += str ( self . data [ depth ][ row ][ column ]) + \" \\t \" result += \" \\n \" return result def main (): my_3d = ThreeDArray ( 3 , 4 , 4 ) print ( my_3d ) # \u6253\u5370\u521d\u59cb\u72b6\u6001 if __name__ == \"__main__\" : main () # \u8fd0\u884c\u7ed3\u679c # Depth 0: # 000 001 002 003 # 010 011 012 013 # 020 021 022 023 # 030 031 032 033 # Depth 1: # 100 101 102 103 # 110 111 112 113 # 120 121 122 123 # 130 131 132 133 # Depth 2: # 200 201 202 203 # 210 211 212 213 # 220 221 222 223 # 230 231 232 233 8\uff0e\u7f16\u5199\u4e00\u6bb5\u4ee3\u7801\uff1a\u8fd9\u6bb5\u4ee3\u7801\u53ef\u4ee5\u663e\u793a\u51fa\u4e09\u7ef4\u6570\u7ec4\u91cc\u7684\u6240\u6709\u5143\u7d20\u3002\u6253\u5370\u51fa\u7684\u6bcf\u4e00\u884c\u6570\u636e\u90fd\u5e94\u8be5\u4ee3\u8868\u7ed9\u5b9a\u884c\u548c\u5217\u91cc\u7684\u6240\u6709\u5143\u7d20\uff0c\u800c\u6df1\u5ea6\u5c06\u4ece\u7b2c\u4e00\u4e2a\u4f4d\u7f6e\u5411\u540e\u9012\u5f52\u5230\u6700\u540e\u4e00\u4e2a\u4f4d\u7f6e\u3002\u904d\u5386\u5e94\u8be5\u4ece\u7b2c1\u884c\u3001\u7b2c1\u5217\u4ee5\u53ca\u7b2c\u4e00\u4e2a\u6df1\u5ea6\u4f4d\u7f6e\u5f00\u59cb\uff0c\u4f9d\u6b21\u904d\u5386\u6240\u6709\u7684\u6df1\u5ea6\u3001\u5217\u548c\u884c\u3002 \u89e3\u7b54\uff1a\u6dfb\u52a0\u4e86\u4e00\u4e2a\u65b9\u6cd5 printAllElements \uff0c\u4ee3\u7801\u5b9e\u73b0\u5982\u4e0b\uff1a class ThreeDArray ( object ): \"\"\"\u63cf\u8ff0\u4e00\u4e2a\u4e09\u7ef4\u6570\u7ec4\u3002\"\"\" # def __init__(self, depth, rows, columns, fillValue=None): # self.depth = depth # self.rows = rows # self.columns = columns # self.fillValue = fillValue # # \u521d\u59cb\u5316\u4e09\u7ef4\u6570\u7ec4\uff0c\u6309\u7167\u6df1\u5ea6\u521d\u59cb\u5316\u6bcf\u4e00\u5c42\u4e3a\u4e00\u4e2a\u4e8c\u7ef4\u6570\u7ec4 # self.data = Array(depth, fillValue) # for d in range(depth): # self.data[d] = Grid(rows, columns, fillValue) def __init__ ( self , depth , rows , columns ): self . depth = depth self . rows = rows self . columns = columns # \u521d\u59cb\u5316\u4e09\u7ef4\u6570\u7ec4\uff0c\u6309\u7167\u6df1\u5ea6\u521d\u59cb\u5316\u6bcf\u4e00\u5c42\u4e3a\u4e00\u4e2a\u4e8c\u7ef4\u6570\u7ec4 self . data = Array ( depth ) for d in range ( depth ): self . data [ d ] = Grid ( rows , columns ) for r in range ( rows ): for c in range ( columns ): # \u5c06\u6bcf\u4e2a\u4f4d\u7f6e\u7684\u7d22\u5f15\u62fc\u63a5\u6210\u5b57\u7b26\u4e32\u4f5c\u4e3a\u5143\u7d20\u503c self . data [ d ][ r ][ c ] = str ( d ) + str ( r ) + str ( c ) def getDepth ( self ): \"\"\"\u8fd4\u56de\u4e09\u7ef4\u6570\u7ec4\u7684z\u8f74\u5927\u5c0f, \u5373\u6570\u7ec4\u7684\u6df1\u5ea6\"\"\" return len ( self . data ) def get_element ( self , depth , row , column ): \"\"\"\u83b7\u53d6\u6307\u5b9a\u6df1\u5ea6\u3001\u884c\u548c\u5217\u7684\u5143\u7d20\"\"\" return self . data [ depth ][ row ][ column ] def set_element ( self , depth , row , column , new_value ): \"\"\"\u8bbe\u7f6e\u6307\u5b9a\u6df1\u5ea6\u3001\u884c\u548c\u5217\u7684\u5143\u7d20\"\"\" self . data [ depth ][ row ][ column ] = new_value def add_element ( self , depth , row , column , value ): \"\"\"\u5728\u6307\u5b9a\u6df1\u5ea6\u3001\u884c\u548c\u5217\u6dfb\u52a0\u5143\u7d20 \"\"\" if self . data [ depth ][ row ][ column ] == self . fillValue : self . data [ depth ][ row ][ column ] = value else : raise Exception ( \"\u5143\u7d20\u6dfb\u52a0\u5931\u8d25\" ) def remove_element ( self , depth , row , column ): \"\"\"\u5728\u6307\u5b9a\u6df1\u5ea6\u3001\u884c\u548c\u5217\u5220\u9664\u5143\u7d20 \"\"\" if self . data [ depth ][ row ][ column ] != self . fillValue : self . data [ depth ][ row ][ column ] = self . fillValue else : raise Exception ( \"\u5143\u7d20\u5220\u9664\u5931\u8d25\" ) def printAllElements ( self ): \"\"\"\u6253\u5370\u4e09\u7ef4\u6570\u7ec4\u4e2d\u7684\u6240\u6709\u5143\u7d20\u3002\"\"\" for row in range ( self . rows ): for col in range ( self . columns ): for depth in range ( self . depth ): print ( f \"Element at position ( { row } , { col } , { depth } ): { self . data [ depth ][ row ][ col ] } \" ) # def __str__(self): # result = \"\" # for depth in range(self.getDepth()): # result += f\"Depth {depth}:\\n\" # for row in range(self.rows): # for column in range(self.columns): # result += str(self.data[depth][row][column]) + \"\\t\" # result += \"\\n\" # return result def __str__ ( self ): result = \"\" for depth in range ( self . getDepth ()): result += f \"Depth { depth } : \\n \" for row in range ( self . rows ): for column in range ( self . columns ): result += str ( self . data [ depth ][ row ][ column ]) + \" \\t \" result += \" \\n \" return result def main (): my_3d = ThreeDArray ( 3 , 4 , 4 ) print ( my_3d ) # \u6253\u5370\u521d\u59cb\u72b6\u6001 my_3d . printAllElements () if __name__ == \"__main__\" : main () # \u8fd0\u884c\u7ed3\u679c # Depth 0: # 000 001 002 003 # 010 011 012 013 # 020 021 022 023 # 030 031 032 033 # Depth 1: # 100 101 102 103 # 110 111 112 113 # 120 121 122 123 # 130 131 132 133 # Depth 2: # 200 201 202 203 # 210 211 212 213 # 220 221 222 223 # 230 231 232 233 # Element at position (0, 0, 0): 000 # Element at position (0, 0, 1): 100 # Element at position (0, 0, 2): 200 # Element at position (0, 1, 0): 001 # Element at position (0, 1, 1): 101 # Element at position (0, 1, 2): 201 # Element at position (0, 2, 0): 002 # Element at position (0, 2, 1): 102 # Element at position (0, 2, 2): 202 # Element at position (0, 3, 0): 003 # Element at position (0, 3, 1): 103 # Element at position (0, 3, 2): 203 # Element at position (1, 0, 0): 010 # Element at position (1, 0, 1): 110 # Element at position (1, 0, 2): 210 # Element at position (1, 1, 0): 011 # Element at position (1, 1, 1): 111 # Element at position (1, 1, 2): 211 # Element at position (1, 2, 0): 012 # Element at position (1, 2, 1): 112 # Element at position (1, 2, 2): 212 # Element at position (1, 3, 0): 013 # Element at position (1, 3, 1): 113 # Element at position (1, 3, 2): 213 # Element at position (2, 0, 0): 020 # Element at position (2, 0, 1): 120 # Element at position (2, 0, 2): 220 # Element at position (2, 1, 0): 021 # Element at position (2, 1, 1): 121 # Element at position (2, 1, 2): 221 # Element at position (2, 2, 0): 022 # Element at position (2, 2, 1): 122 # Element at position (2, 2, 2): 222 # Element at position (2, 3, 0): 023 # Element at position (2, 3, 1): 123 # Element at position (2, 3, 2): 223 # Element at position (3, 0, 0): 030 # Element at position (3, 0, 1): 130 # Element at position (3, 0, 2): 230 # Element at position (3, 1, 0): 031 # Element at position (3, 1, 1): 131 # Element at position (3, 1, 2): 231 # Element at position (3, 2, 0): 032 # Element at position (3, 2, 1): 132 # Element at position (3, 2, 2): 232 # Element at position (3, 3, 0): 033 # Element at position (3, 3, 1): 133 # Element at position (3, 3, 2): 233 4.4.\u94fe\u63a5\u7ed3\u6784 \u00b6 \u94fe\u63a5\u7ed3\u6784\u4f5c\u4e3a\u4e00\u79cd\u6570\u636e\u7c7b\u578b\uff0c\u53ef\u4ee5\u7528\u6765\u5b9e\u73b0\u82e5\u5e72\u7c7b\u578b\u7684\u591a\u9879\u96c6\uff08\u5305\u62ec\u5217\u8868\uff09\u3002 \u76ee\u6807\uff1a\u5728\u4f7f\u7528\u94fe\u63a5\u7ed3\u6784\u5b9e\u73b0\u4efb\u4f55\u7c7b\u578b\u7684\u591a\u9879\u96c6\u65f6\u6240\u5fc5\u987b\u8981\u77e5\u9053\u7684\u51e0\u4e2a\u7279\u5f81\uff0c\u4ee5\u53ca\u5982\u4f55\u5728\u591a\u9879\u96c6\uff08\u5982\u5217\u8868\u548c\u4e8c\u53c9\u6811\uff09\u91cc\u4f7f\u7528\u94fe\u63a5\u7ed3\u6784\u3002 4.4.1.\u5355\u5411\u94fe\u63a5\u7ed3\u6784\u548c\u53cc\u5411\u94fe\u63a5\u7ed3\u6784 \u00b6 \u94fe\u63a5\u7ed3\u6784\u7531\u53ef\u4ee5\u94fe\u63a5\u5230\u5176\u4ed6\u8282\u70b9\u7684\u8282\u70b9\u7ec4\u6210\u3002 \u8282\u70b9\u4e4b\u95f4\u6700\u7b80\u5355\u7684\u94fe\u63a5\u7ed3\u6784\u662f\uff1a \u5355\u5411\u94fe\u63a5\u7ed3\u6784\uff08singly linked structure\uff09 \u53cc\u5411\u94fe\u63a5\u7ed3\u6784\uff08doubly linked structure\uff09 \u4e0b\u9762\u56fe\u4f8b\u662f\u7528\u6846\u548c\u6307\u9488\u7b26\u53f7\u7ed8\u51fa\u5355\u5411\u548c\u53cc\u5411\u94fe\u63a5\u7ed3\u6784\u3002 \u901a\u8fc7\u4e00\u4e2a\u989d\u5916\u7684\u5934\u90e8\u94fe\u63a5\uff08head link\uff09\uff0c\u53ef\u4ee5\u4f7f\u7528\u5355\u5411\u94fe\u63a5\u7ed3\u6784\u8bbf\u95ee\u7b2c\u4e00\u4e2a\u8282\u70b9\u3002\u63a5\u4e0b\u6765\uff0c\u6211\u4eec\u5c31\u53ef\u4ee5\u901a\u8fc7\u8fd9\u4e2a\u8282\u70b9\u91cc\u53d1\u51fa\u7684\u94fe\u63a5\uff08\u4e0a\u56fe\u4e2d\u7684\u7bad\u5934\uff09\u6765\u8bbf\u95ee\u5176\u4ed6\u8282\u70b9\u4e86\u3002\u56e0\u6b64\uff0c\u5728\u5355\u5411\u94fe\u63a5\u7ed3\u6784\u91cc\uff0c\u6211\u4eec\u53ef\u4ee5\u5f88\u5bb9\u6613\u5730\u83b7\u5f97\u8282\u70b9\u7684\u540e\u7ee7\u8282\u70b9\uff0c\u4f46\u4e0d\u90a3\u4e48\u5bb9\u6613\u83b7\u5f97\u8282\u70b9\u7684\u524d\u5e8f\u8282\u70b9\u3002 \u53cc\u5411\u94fe\u63a5\u7ed3\u6784\u4f1a\u5305\u542b\u53cc\u5411\u7684\u94fe\u63a5\uff0c\u6211\u4eec\u53ef\u4ee5\u5f88\u5bb9\u6613\u5730\u79fb\u52a8\u5230\u8282\u70b9\u7684\u524d\u5e8f\u6216\u8005\u540e\u7ee7\u8282\u70b9\uff0c\u8fd9\u4e2a\u65f6\u5019\u4f1a\u7528\u5230\u7b2c\u4e8c\u4e2a\u989d\u5916\u7684\u94fe\u63a5\uff08\u5c3e\u90e8\u94fe\u63a5tail link\uff09\u3002\u5c3e\u90e8\u94fe\u63a5\u80fd\u591f\u8ba9\u53cc\u5411\u94fe\u63a5\u7ed3\u6784\u7684\u7528\u6237\u76f4\u63a5\u8bbf\u95ee\u6700\u540e\u4e00\u4e2a\u8282\u70b9\u3002 \u5728\u4e24\u79cd\u94fe\u63a5\u7ed3\u6784\u91cc\uff0c\u6700\u540e\u4e00\u4e2a\u8282\u70b9\u90fd\u6ca1\u6709\u6307\u5411\u540e\u7eed\u8282\u70b9\u7684\u94fe\u63a5\u3002\u5728\u4e0a\u56fe\u4e2d\uff0c\u7528\u659c\u6760\u4ee3\u66ff\u7bad\u5934\u4ee5\u8868\u793a\u6ca1\u6709\u94fe\u63a5\uff0c\u8fd9\u79f0\u4e3a\u7a7a\u94fe\u63a5\uff08empty link\uff09\u3002 \u5728\u53cc\u5411\u94fe\u63a5\u7ed3\u6784\u91cc\uff0c\u7b2c\u4e00\u4e2a\u8282\u70b9\u4e5f\u6ca1\u6709\u6307\u5411\u524d\u5e8f\u8282\u70b9\u7684\u94fe\u63a5\u3002 \u548c\u6570\u7ec4\u4e00\u6837\uff0c\u94fe\u63a5\u7ed3\u6784\u4e5f\u53ef\u4ee5\u7528\u6765\u5b58\u50a8\u5143\u7d20\u7684\u7ebf\u6027\u5e8f\u5217\uff0c\u4f46\u65e0\u6cd5\u901a\u8fc7\u6307\u5b9a\u7684\u7d22\u5f15\u4f4d\u7f6e\u76f4\u63a5\u8bbf\u95ee\u8fd9\u4e2a\u5143\u7d20\uff0c\u5fc5\u987b\u4ece\u6570\u636e\u7ed3\u6784\u7684\u4e00\u4e2a\u9876\u7aef\u5f00\u59cb\uff0c\u7136\u540e\u6309\u7167\u94fe\u63a5\u8fdb\u884c\u8bbf\u95ee\uff0c\u76f4\u81f3\u5230\u8fbe\u6240\u9700\u7684\u4f4d\u7f6e\uff08\u6216\u627e\u5230\u671f\u671b\u7684\u5143\u7d20\uff09\u4e3a\u6b62\u3002\u94fe\u63a5\u7ed3\u6784\u7684\u8fd9\u79cd\u6027\u8d28\u5bf9\u4e8e\u5f88\u591a\u64cd\u4f5c\u90fd\u6709\u663e\u8457\u7684\u5f71\u54cd\u3002 \u4e3a\u94fe\u63a5\u7ed3\u6784\u5206\u914d\u5185\u5b58\u7684\u65b9\u5f0f\u548c\u4e3a\u6570\u7ec4\u5206\u914d\u5185\u5b58\u7684\u65b9\u5f0f\u662f\u5b8c\u5168\u4e0d\u540c\u7684\uff0c\u800c\u4e14\u5bf9\u4e8e\u63d2\u5165\u548c\u5220\u9664\u64cd\u4f5c\u6765\u8bf4\uff0c\u6709\u4e24\u4e2a\u663e\u8457\u5f71\u54cd\u3002 \u5728\u627e\u5230\u63d2\u5165\u6216\u5220\u9664\u70b9\u4e4b\u540e\uff0c\u53ef\u4ee5\u5728\u4e0d\u79fb\u52a8\u5185\u5b58\u91cc\u7684\u6570\u636e\u5143\u7d20\u7684\u60c5\u51b5\u4e0b\u6267\u884c\u63d2\u5165\u6216\u5220\u9664\u64cd\u4f5c\u3002 \u53ef\u4ee5\u5728\u6bcf\u6b21\u63d2\u5165\u6216\u5220\u9664\u671f\u95f4\u81ea\u52a8\u8c03\u6574\u94fe\u63a5\u7ed3\u6784\u7684\u5927\u5c0f\uff0c\u4e0d\u9700\u8981\u82b1\u8d39\u989d\u5916\u7684\u5185\u5b58\u7a7a\u95f4\uff0c\u4e5f\u4e0d\u9700\u8981\u590d\u5236\u6570\u636e\u5143\u7d20\u3002 4.4.2.\u975e\u8fde\u7eed\u5185\u5b58\u548c\u8282\u70b9 \u00b6 \u6570\u7ec4\u91cc\u7684\u5143\u7d20\u5fc5\u987b\u5b58\u50a8\u5728\u4e00\u6bb5\u8fde\u7eed\u7684\u5185\u5b58\u4e2d\uff0c\u8fd9\u5c31\u610f\u5473\u7740\u6570\u7ec4\u91cc\u5404\u4e2a\u5143\u7d20\u7684\u903b\u8f91\u987a\u5e8f\u548c\u5b83\u4eec\u5728\u5185\u5b58\u5355\u5143\u91cc\u7684\u7269\u7406\u987a\u5e8f\u662f\u7d27\u5bc6\u8026\u5408\u7684\u3002 \u76f8\u6bd4\u800c\u8a00\uff0c\u94fe\u63a5\u7ed3\u6784\u4f1a\u628a\u7ed3\u6784\u91cc\u5404\u4e2a\u5143\u7d20\u7684\u903b\u8f91\u987a\u5e8f\u548c\u5b83\u4eec\u5728\u5185\u5b58\u91cc\u7684\u987a\u5e8f\u89e3\u8026\u3002\u8981\u5728\u5185\u5b58\u7684\u67d0\u4e2a\u4f4d\u7f6e\u4e0a\u627e\u5230\u94fe\u63a5\u7ed3\u6784\u91cc\u7279\u5b9a\u5143\u7d20\u7684\u5185\u5b58\u5355\u5143\uff0c\u53ea\u9700\u8981\u8ba9\u8ba1\u7b97\u673a\u8ddf\u968f\u6307\u5411\u8fd9\u4e2a\u5143\u7d20\u7684\u5730\u5740\u6216\u4f4d\u7f6e\u94fe\u63a5\u5c31\u884c\u4e86\u3002\u8fd9\u79f0\u4e3a\u975e\u8fde\u7eed\u5185\u5b58\uff08noncontiguous memory\uff09\u3002 \u94fe\u63a5\u7ed3\u6784\u91cc\u7528\u6765\u5b58\u50a8\u7684\u57fa\u672c\u5355\u4f4d\u662f\u8282\u70b9\uff08node\uff09\u3002 \u5355\u5411\u94fe\u63a5\u8282\u70b9\uff08singly linked node\uff09\u5305\u542b\u4e0b\u9762\u8fd9\u4e9b\u7ec4\u4ef6\u6216\u5b57\u6bb5\uff1a \u6570\u636e\u5143\u7d20\uff1b \u6307\u5411\u7ed3\u6784\u91cc\u540e\u7ee7\u8282\u70b9\u7684\u94fe\u63a5\uff1b \u5bf9\u4e8e\u53cc\u5411\u94fe\u63a5\u8282\u70b9\uff08doubly linked node\uff09\u5305\u542b\u4e0b\u9762\u8fd9\u4e9b\u7ec4\u4ef6\u6216\u5b57\u6bb5\uff1a \u6570\u636e\u5143\u7d20\uff1b \u6307\u5411\u7ed3\u6784\u91cc\u540e\u7ee7\u8282\u70b9\u7684\u94fe\u63a5\uff1b \u6307\u5411\u7ed3\u6784\u91cc\u524d\u5e8f\u8282\u70b9\u7684\u94fe\u63a5\uff1b \u4e0d\u540c\u7684\u7f16\u7a0b\u8bed\u8a00\uff0c\u901a\u8fc7\u4e0d\u540c\u7684\u65b9\u6cd5\u6765\u8ba9\u8282\u70b9\u5229\u7528\u975e\u8fde\u7eed\u5185\u5b58\u3002 FORTRAN\u8bed\u8a00\u4e2d\uff0c\u901a\u8fc7\u4e24\u4e2a\u5e76\u6392\u7684\u6570\u7ec4\u4e3a\u5355\u5411\u94fe\u63a5\u7ed3\u6784\u5b9e\u73b0\u975e\u8fde\u7eed\u5185\u5b58\u548c\u8282\u70b9\u3002\u8fd9\u6837\u505a\u53ef\u4ee5\u6709\u6548\u5730\u5c06\u94fe\u63a5\u7ed3\u6784\u91cc\u6570\u636e\u5143\u7d20\u7684\u903b\u8f91\u4f4d\u7f6e\u548c\u5b83\u5728\u6570\u7ec4\u91cc\u7684\u7269\u7406\u4f4d\u7f6e\u5206\u79bb\u3002 \u7b2c\u4e00\u4e2a\u6570\u7ec4\u5305\u542b\u6570\u636e\u5143\u7d20\uff1b\u7b2c\u4e8c\u4e2a\u6570\u7ec4\u5219\u5305\u542b\u6570\u636e\u6570\u7ec4\u91cc\u5f53\u524d\u8282\u70b9\u6240\u5bf9\u5e94\u7684\u540e\u7eed\u8282\u70b9\u7684\u7d22\u5f15\u4f4d\u7f6e\u3002 \u7528\u7b2c\u4e00\u4e2a\u6570\u7ec4\u91cc\u7684\u6570\u636e\u5143\u7d20\u7d22\u5f15\u6765\u8bbf\u95ee\u7b2c\u4e8c\u4e2a\u6570\u7ec4\u91cc\u7684\u503c\uff0c\u7136\u540e\u518d\u628a\u8fd9\u4e2a\u503c\u4f5c\u4e3a\u7b2c\u4e00\u4e2a\u6570\u7ec4\u91cc\u4e0b\u4e00\u4e2a\u6570\u636e\u5143\u7d20\u7684\u7d22\u5f15\u3002\u7a7a\u94fe\u63a5\u4f1a\u7528\u503c\u22121\u6765\u8868\u793a\u3002 Pascal\u548cC++\u8bed\u8a00\u4e2d\uff0c\u901a\u8fc7\u8bbf\u95ee\u6307\u9488\uff08pointer\uff09\u76f4\u63a5\u5f97\u5230\u6240\u9700\u7684\u6570\u636e\u5730\u5740\u3002 \u5355\u5411\u94fe\u63a5\u7ed3\u6784\u91cc\u7684\u8282\u70b9\u5305\u542b\u4e00\u4e2a\u6570\u636e\u5143\u7d20\u548c\u4e00\u4e2a\u6307\u9488\u503c\u3002\u5bf9\u4e8e\u7a7a\u94fe\u63a5\u6765\u8bf4\uff0c\u5b83\u7684\u6307\u9488\u503c\u7528\u7279\u6b8a\u503cnull\uff08\u6216nil\uff09\u6765\u8868\u793a\u3002 \u8bf7\u6c42\u4e00\u4e2a\u5bf9\u8c61\u5806\uff08object heap\uff09\u7684\u65b0\u8282\u70b9\u7684\u6307\u9488\uff0c\u8fd9\u4e2a\u8282\u70b9\u6765\u81ea\u975e\u8fde\u7eed\u5185\u5b58\u7684\u5185\u7f6e\u533a\u57df\uff0c\u5e76\u628a\u8fd9\u4e2a\u8282\u70b9\u91cc\u7684\u6307\u9488\u8bbe\u7f6e\u4e3a\u6307\u5411\u53e6\u4e00\u4e2a\u8282\u70b9\uff0c\u4ece\u800c\u5efa\u7acb\u5230\u8fd9\u4e2a\u94fe\u63a5\u7ed3\u6784\u91cc\u5176\u4ed6\u6570\u636e\u7684\u94fe\u63a5\u3002 \u901a\u8fc7\u663e\u5f0f\u5730\u4f7f\u7528\u6307\u9488\u548c\u5185\u7f6e\u5806\uff0c\u53ef\u4ee5\u4e0d\u518d\u9700\u8981\u7ba1\u7406\u975e\u8fde\u7eed\u5185\u5b58\u7684\u5e95\u5c42\u6570\u7ec4\u5b58\u50a8\u65b9\u5f0f\u4e86\uff0c\u4f46\u8fd8\u662f\u9700\u8981\u4eba\u4e3a\u7ba1\u7406\u5806\uff0c\u901a\u8fc7\u7279\u6b8a\u7684dispose\u6216delete\u64cd\u4f5c\u628a\u4e0d\u4f7f\u7528\u7684\u8282\u70b9\u8fd4\u56de\u7ed9\u5806\u3002 Python\u8bed\u8a00\u4e2d\uff0c\u901a\u8fc7\u4f7f\u7528\u5bf9\u5bf9\u8c61\u7684\u5f15\u7528\uff08reference\uff09\u8bbe\u7f6e\u8282\u70b9\u548c\u94fe\u63a5\u7ed3\u6784\u3002 Python\u4e2d\uff0c\u4efb\u4f55\u53d8\u91cf\u90fd\u53ef\u4ee5\u7528\u6765\u5f15\u7528\u4efb\u4f55\u6570\u636e\uff0c\u8fd9\u4e5f\u5305\u62ec\u503c None \uff0c\u5b83\u53ef\u4ee5\u7528\u6765\u4ee3\u8868\u7a7a\u94fe\u63a5\u3002 Python\u4e2d\uff0c\u5b9a\u4e49\u5305\u542b\u4e24\u4e2a\u5b57\u6bb5\u7684\u5bf9\u8c61\u6765\u5b9a\u4e49\u5355\u5411\u94fe\u63a5\u8282\u70b9\uff0c\u8fd9\u4e24\u4e2a\u5b57\u6bb5\u662f\u5bf9\u6570\u636e\u5143\u7d20\u7684\u5f15\u7528\u548c\u5bf9\u53e6\u4e00\u4e2a\u8282\u70b9\u7684\u5f15\u7528\u3002 Python\u4e2d\uff0c\u4e3a\u6bcf\u4e2a\u65b0\u7684\u8282\u70b9\u5bf9\u8c61\u63d0\u4f9b\u975e\u8fde\u7eed\u5185\u5b58\u7684\u52a8\u6001\u5206\u914d\uff0c\u5e76\u4e14\u5f53\u5e94\u7528\u7a0b\u5e8f\u4e0d\u518d\u5f15\u7528\u8fd9\u4e2a\u5bf9\u8c61\u7684\u65f6\u5019\uff0c\u5b83\u4f1a\u81ea\u52a8\u628a\u8fd9\u90e8\u5206\u5185\u5b58\u8fd4\u56de\u7ed9\u7cfb\u7edf\uff08\u5783\u573e\u56de\u6536\uff09\u3002 4.4.3.\u5b9a\u4e49\u5355\u5411\u94fe\u63a5\u8282\u70b9\u7c7b \u00b6 \u5355\u5411\u94fe\u63a5\u8282\u70b9\u53ea\u5305\u542b\u6570\u636e\u5143\u7d20\u548c\u5bf9\u4e0b\u4e00\u4e2a\u8282\u70b9\u7684\u5f15\u7528\u3002\u56e0\u4e3a\u8282\u70b9\u5bf9\u8c61\u7684\u7075\u6d3b\u6027\u548c\u6613\u7528\u6027\u975e\u5e38\u91cd\u8981\uff0c\u6240\u4ee5\u901a\u5e38\u4f1a\u5f15\u7528\u8282\u70b9\u5bf9\u8c61\u7684\u5b9e\u4f8b\u53d8\u91cf\u800c\u4e0d\u662f\u65b9\u6cd5\u8c03\u7528\uff0c\u5e76\u4e14\u6784\u9020\u51fd\u6570\u4e5f\u9700\u8981\u7528\u6237\u5728\u521b\u5efa\u8282\u70b9\u65f6\u53ef\u4ee5\u8bbe\u7f6e\u8282\u70b9\u7684\u94fe\u63a5\u3002 \u4e0b\u9762\u662f\u7528\u6765\u5b9e\u73b0\u5355\u5411\u94fe\u63a5\u8282\u70b9\u7c7b\u7684\u4ee3\u7801\u3002 class Node ( object ): \"\"\"\u5355\u5411\u94fe\u63a5\u8282\u70b9\u7c7b\"\"\" def __init__ ( self , data , next = None ): \"\"\"\u5b9e\u4f8b\u5316\u4e00\u4e2a\u8282\u70b9, \u9ed8\u8ba4\u540e\u7ee7\u8282\u70b9\u4e3aNone\"\"\" self . data = data self . next = next def main (): # \u521b\u5efa\u4e00\u4e2a\u7a7a\u94fe node1 = None # \u521b\u5efa\u4e00\u4e2a\u5355\u5411\u94fe\u63a5\u8282\u70b9\uff0c\u542b\u6570\u636e\u5143\u7d20\u548c\u7a7a\u94fe node2 = Node ( \"A\" , None ) # \u521b\u5efa\u4e00\u4e2a\u5355\u5411\u94fe\u63a5\u8282\u70b9\uff0c\u542b\u6570\u636e\u5143\u7d20\u548c\u6307\u5411\u4e0b\u4e00\u4e2a\u8282\u70b9\u7684\u94fe\u63a5 node3 = Node ( \"B\" , node2 ) if __name__ == \"__main__\" : main () 4.4.4.\u4f7f\u7528\u5355\u5411\u94fe\u63a5\u8282\u70b9\u7c7b \u00b6 \u4e0b\u9762\u8fd9\u6bb5\u4ee3\u7801\u6f14\u793a\u4e86\u8282\u70b9\u53d8\u91cf\u88ab\u521d\u59cb\u5316\u4e3a None \u6216\u4e00\u4e2a\u65b0\u7684 Node \u5bf9\u8c61\u3002 node1 \u6ca1\u6709\u6307\u5411\u4efb\u4f55\u8282\u70b9\u5bf9\u8c61\uff08\u662f None \uff09\u3002 node2 \u548c node3 \u90fd\u6307\u5411\u4e86\u94fe\u63a5\u7684\u5bf9\u8c61\u3002 node2 \u6307\u5411\u4e86\u4e0b\u4e00\u4e2a\u6307\u9488\u662f None \u7684\u5bf9\u8c61\u3002 def main (): # \u521b\u5efa\u4e00\u4e2a\u7a7a\u94fe node1 = None # \u521b\u5efa\u4e00\u4e2a\u5355\u5411\u94fe\u63a5\u8282\u70b9\uff0c\u542b\u6570\u636e\u5143\u7d20\u548c\u7a7a\u94fe node2 = Node ( \"A\" , None ) # \u521b\u5efa\u4e00\u4e2a\u5355\u5411\u94fe\u63a5\u8282\u70b9\uff0c\u542b\u6570\u636e\u5143\u7d20\u548c\u6307\u5411\u4e0b\u4e00\u4e2a\u8282\u70b9\u7684\u94fe\u63a5 node3 = Node ( \"B\" , node2 ) \u6267\u884c node1.next = node3 \u4f1a\u6536\u5230\u9519\u8bef AttributeError: 'NoneType' object has no attribute 'next' \uff0c\u56e0\u4e3a\u53d8\u91cf node1 \u7684\u503c\u662f None \uff0c\u6240\u4ee5\u5b83\u5e76\u4e0d\u5305\u542b\u7528\u6765\u5f15\u7528\u8282\u70b9\u5bf9\u8c61\u7684 next \u5b57\u6bb5\u3002 \u5e94\u8be5\u5148\u6b63\u786e\u5b9e\u4f8b\u5316 node1 \uff0c\u518d\u5c06 node3 \u4f5c\u4e3a\u5176\u540e\u7ee7\u3002\u4e0b\u9762\u662f\u793a\u4f8b\u4ee3\u7801\u3002 def main (): # \u521b\u5efa\u4e00\u4e2a\u7a7a\u94fe node1 = None # \u521b\u5efa\u4e00\u4e2a\u5355\u5411\u94fe\u63a5\u8282\u70b9\uff0c\u542b\u6570\u636e\u5143\u7d20\u548c\u7a7a\u94fe node2 = Node ( \"A\" , None ) # \u521b\u5efa\u4e00\u4e2a\u5355\u5411\u94fe\u63a5\u8282\u70b9\uff0c\u542b\u6570\u636e\u5143\u7d20\u548c\u6307\u5411\u4e0b\u4e00\u4e2a\u8282\u70b9\u7684\u94fe\u63a5 node3 = Node ( \"B\" , node2 ) if node1 != None : node1 . next = node3 else : node1 = Node ( \"C\" , None ) node1 . next = node3 \u4e0b\u9762\u7684\u4ee3\u7801\u7684\u529f\u80fd\u662f\uff1a\u521b\u5efa\u4e00\u4e2a\u5355\u5411\u94fe\u63a5\u7ed3\u6784\uff0c\u5e76\u6253\u5370\u51fa\u5b83\u7684\u5185\u5bb9\u3002 \u4ee3\u7801\u4e2d head \u662f\u4e00\u4e2a\u6307\u9488\uff0c\u7528\u4e8e\u751f\u6210\u6574\u4e2a\u94fe\u63a5\u7ed3\u6784\u3002\u8fd9\u4e2a\u6307\u9488\u7684\u7528\u6cd5\u662f\u8ba9\u6240\u6709\u65b0\u63d2\u5165\u7684\u5143\u7d20\u59cb\u7ec8\u4f4d\u4e8e\u94fe\u63a5\u7ed3\u6784\u7684\u5f00\u5934\u3002 \u5728\u663e\u793a\u6570\u636e\u65f6\uff0c\u5b83\u4eec\u4f1a\u4ee5\u548c\u63d2\u5165\u65f6\u76f8\u53cd\u7684\u987a\u5e8f\u51fa\u73b0\u3002\u6b64\u5916\uff0c\u5f53\u663e\u793a\u6570\u636e\u65f6\uff0c\u5934\u90e8\u6307\u9488 head \u4f1a\u88ab\u91cd\u7f6e\u5230\u4e0b\u4e00\u4e2a\u8282\u70b9\uff0c\u76f4\u5230\u5934\u90e8\u6307\u9488\u53d8\u4e3a None \u4e3a\u6b62\u3002 \u4ee3\u7801\u6267\u884c\u7ed3\u675f\u4e4b\u540e\uff0c\u8fd9\u4e9b\u8282\u70b9\u5728\u7a0b\u5e8f\u91cc\u4e0d\u518d\u53ef\u7528\uff0c\u5e76\u4e14\u4f1a\u5728\u4e0b\u4e00\u6b21\u5783\u573e\u56de\u6536\u671f\u95f4\u88ab\u56de\u6536\u3002 def main (): # \u521b\u5efa\u4e00\u4e2a\u5355\u5411\u94fe\u63a5\u7ed3\u6784\uff0c\u5e76\u6253\u5370\u51fa\u5b83\u7684\u5185\u5bb9 head = None # \u5728\u94fe\u63a5\u7ed3\u6784\u7684\u5f00\u5934\u4f9d\u6b21\u63d2\u5165\u4e94\u4e2a\u8282\u70b9 for count in range ( 1 , 6 ): head = Node ( count , head ) # \u6253\u5370\u8f93\u51fa\u8fd9\u4e2a\u5355\u5411\u94fe\u63a5\u7684\u4e94\u4e2a\u8282\u70b9\u7684\u5185\u5bb9 while head != None : print ( head . data ) head = head . next if __name__ == \"__main__\" : main () # \u8fd0\u884c\u7ed3\u679c # 5 # 4 # 3 # 2 # 1 4.4.5.\u7ec3\u4e60\u9898 \u00b6 1\uff0e\u7528\u6846\u548c\u6307\u9488\u7ed8\u5236\u6d4b\u8bd5\u7a0b\u5e8f\u91cc\u7b2c\u4e00\u4e2a\u5faa\u73af\u6240\u521b\u5efa\u7684\u8282\u70b9\u7684\u793a\u610f\u56fe\u3002 \u89e3\u7b54\uff1a\u5728\u4e0b\u9762\u7684\u4ee3\u7801\u4e2d\uff0c\u6211\u4eec\u9996\u5148\u521b\u5efa\u4e86\u4e00\u4e2a\u7a7a\u7684\u5355\u94fe\u8868 head \u3002\u7136\u540e\u6211\u4eec\u5728\u94fe\u8868\u7684\u5f00\u5934\u4f9d\u6b21\u63d2\u5165\u4e94\u4e2a\u8282\u70b9\uff0c\u8282\u70b9\u7684\u6570\u636e\u4f9d\u6b21\u4e3a 1 , 2 , 3 , 4 , 5 \u3002\u5728\u63d2\u5165\u8fc7\u7a0b\u4e2d\uff0c\u6bcf\u6b21\u90fd\u628a\u65b0\u7684\u8282\u70b9\u63d2\u5165\u5230\u94fe\u8868\u7684\u5934\u90e8\uff0c\u6240\u4ee5\u6700\u540e\u7684\u94fe\u8868\u987a\u5e8f\u4f1a\u662f 5 , 4 , 3 , 2 , 1 \u3002 def main (): # \u521b\u5efa\u4e00\u4e2a\u5355\u5411\u94fe\u63a5\u7ed3\u6784\uff0c\u5e76\u6253\u5370\u51fa\u5b83\u7684\u5185\u5bb9 head = None # \u5728\u94fe\u63a5\u7ed3\u6784\u7684\u5f00\u5934\u4f9d\u6b21\u63d2\u5165\u4e94\u4e2a\u8282\u70b9 for count in range ( 1 , 6 ): head = Node ( count , head ) # \u6253\u5370\u8f93\u51fa\u8fd9\u4e2a\u5355\u5411\u94fe\u63a5\u7684\u4e94\u4e2a\u8282\u70b9\u7684\u5185\u5bb9 while head != None : print ( head . data ) head = head . next \u4ee5\u4e0b\u662f\u56fe\u793a\uff0c\u6bcf\u4e2a [] \u4ee3\u8868\u4e00\u4e2a\u8282\u70b9\uff0c\u8282\u70b9\u4e2d\u7684\u6570\u5b57\u4ee3\u8868\u8282\u70b9\u7684\u6570\u636e\uff0c\u7bad\u5934\u4ee3\u8868\u6307\u9488\uff0c\u6307\u5411\u4e86\u4e0b\u4e00\u4e2a\u8282\u70b9\u3002 NULL \u8868\u793a\u94fe\u8868\u7684\u7ed3\u675f\u3002 [5]---> [4] ---> [3] ---> [2] ---> [1] ---> NULL 2\uff0e\u5f53\u8282\u70b9\u53d8\u91cf\u5f15\u7528\u7684\u662f None \u65f6\uff0c\u5982\u679c\u7a0b\u5e8f\u5458\u5c1d\u8bd5\u8bbf\u95ee\u8282\u70b9\u7684\u6570\u636e\u5b57\u6bb5\uff0c\u5219\u4f1a\u53d1\u751f\u4ec0\u4e48\uff1f\u5982\u4f55\u9632\u6b62\u8fd9\u79cd\u60c5\u51b5\u7684\u53d1\u751f\uff1f \u89e3\u7b54\uff1a\u5f53\u8282\u70b9\u53d8\u91cf\u5f15\u7528\u7684\u662f None \u65f6\uff0c\u4f8b\u5982\uff0c\u6267\u884c node1.next = node3 \u4f1a\u6536\u5230\u9519\u8bef AttributeError: 'NoneType' object has no attribute 'next' \uff0c\u56e0\u4e3a\u53d8\u91cf node1 \u7684\u503c\u662f None \uff0c\u6240\u4ee5\u5b83\u5e76\u4e0d\u5305\u542b\u7528\u6765\u5f15\u7528\u8282\u70b9\u5bf9\u8c61\u7684 next \u5b57\u6bb5\u3002 \u5e94\u8be5\u5148\u6b63\u786e\u5b9e\u4f8b\u5316 node1 \uff0c\u518d\u5c06 node3 \u4f5c\u4e3a\u5176\u540e\u7ee7\u3002\u4e0b\u9762\u662f\u793a\u4f8b\u4ee3\u7801\u3002 if node1 != None : node1 . next = node3 else : node1 = Node ( \"C\" , None ) node1 . next = node3 3\uff0e\u7f16\u5199\u4e00\u6bb5\u4ee3\u7801\uff1a\u8fd9\u6bb5\u4ee3\u7801\u4f1a\u628a\u4e00\u4e2a\u88ab\u586b\u6ee1\u7684\u6570\u7ec4\u91cc\u7684\u5143\u7d20\u90fd\u8f6c\u79fb\u4e3a\u5355\u5411\u94fe\u63a5\u7ed3\u6784\u91cc\u7684\u6570\u636e\u3002\u8fd9\u4e2a\u64cd\u4f5c\u5e94\u4fdd\u7559\u5143\u7d20\u7684\u987a\u5e8f\u4e0d\u53d8\u3002 \u89e3\u7b54\uff1a\u4e0b\u9762\u662f\u4ee3\u7801\u5b9e\u73b0\u3002 LinkedList \u7c7b\u6709\u4e24\u4e2a\u65b9\u6cd5\uff0c insert_from_list \u7528\u4e8e\u4ece\u5217\u8868\u4e2d\u63d2\u5165\u6570\u636e\uff0c print_list \u7528\u4e8e\u6253\u5370\u94fe\u8868\u7684\u6240\u6709\u5143\u7d20\u3002 \u5728 insert_from_list \u65b9\u6cd5\u4e2d\uff0c\u6211\u4eec\u9996\u5148\u521b\u5efa\u7b2c\u4e00\u4e2a\u8282\u70b9\uff0c\u7136\u540e\u5bf9\u5217\u8868\u7684\u5269\u4f59\u5143\u7d20\uff0c\u4f9d\u6b21\u521b\u5efa\u65b0\u7684\u8282\u70b9\u5e76\u6dfb\u52a0\u5230\u94fe\u8868\u5c3e\u90e8\u3002 \u7531\u4e8e\u6211\u4eec\u662f\u9010\u4e2a\u5c06\u5143\u7d20\u6dfb\u52a0\u5230\u94fe\u8868\u7684\u672b\u5c3e\uff0c\u6240\u4ee5\u5728\u521b\u5efaNode\u65f6\u5e76\u4e0d\u9700\u8981\u6307\u5b9anext\u8282\u70b9\u3002 class Node ( object ): \"\"\"\u5355\u5411\u94fe\u63a5\u8282\u70b9\u7c7b\"\"\" def __init__ ( self , data , next = None ): \"\"\"\u5b9e\u4f8b\u5316\u4e00\u4e2a\u8282\u70b9, \u9ed8\u8ba4\u540e\u7ee7\u8282\u70b9\u4e3aNone\"\"\" self . data = data self . next = next class LinkedList : \"\"\"\u5c06\u5217\u8868\u5143\u7d20\u8f6c\u79fb\u4e3a\u5355\u5411\u94fe\u63a5\u7ed3\u6784\u91cc\u7684\u6570\u636e\uff0c\u5e76\u4fdd\u7559\u5143\u7d20\u7684\u987a\u5e8f\u4e0d\u53d8\"\"\" def __init__ ( self ): self . head = None # \u521d\u59cb\u5316head def insert_from_list ( self , data_list ): # \u521b\u5efa\u4e86\u94fe\u8868\u7684\u5934\u8282\u70b9 self . head = Node ( data_list [ 0 ]) # \u8bfb\u53d6\u5217\u8868\u7d22\u5f150\u7684\u5143\u7d20\u503c\uff0c\u5e76\u5c06\u5730\u5740\u8d4b\u503c\u7ed9head current = self . head # \u5c06head\u5f15\u7528\u8d4b\u503c\u7ed9current # \u5728\u94fe\u8868\u7684\u5c3e\u90e8\u4f9d\u6b21\u6dfb\u52a0\u65b0\u7684\u8282\u70b9 # \u5728\u6bcf\u6b21\u5faa\u73af\u540e\uff0c\u94fe\u8868\u7684\u5c3e\u90e8\u90fd\u4f1a\u6dfb\u52a0\u65b0\u7684\u8282\u70b9\uff0c\u5e76\u4e14current\u8282\u70b9\u4e5f\u4f1a\u968f\u4e4b\u66f4\u65b0\u3002 for data in data_list [ 1 :]: current . next = Node ( data ) # \u521b\u5efa\u4e00\u4e2a\u65b0\u7684\u8282\u70b9\uff0c\u5e76\u4e14\u5c06current\u8282\u70b9\u7684next\u5c5e\u6027\u8bbe\u7f6e\u4e3a\u8fd9\u4e2a\u65b0\u7684\u8282\u70b9\u3002\u8fd9\u6837\uff0ccurrent\u8282\u70b9\uff08\u4e5f\u5c31\u662f\u4e4b\u524d\u7684\u5c3e\u8282\u70b9\uff09\u5c31\u548c\u65b0\u7684\u8282\u70b9\u5efa\u7acb\u4e86\u94fe\u63a5\u5173\u7cfb\u3002 current = current . next # \u5c06current\u66f4\u65b0\u4e3a\u65b0\u521b\u5efa\u7684\u8282\u70b9\u3002\u4e5f\u5c31\u662f\u8bf4\uff0ccurrent\u59cb\u7ec8\u4ee3\u8868\u5f53\u524d\u94fe\u8868\u7684\u5c3e\u8282\u70b9\u3002 def print_list ( self ): current = self . head while current : print ( current . data , end = ' ' ) current = current . next print () def main (): # \u5c06\u5217\u8868data_list\u4e2d\u7684\u5143\u7d20\u63d2\u5165\u5230LinkedList\u5b9e\u4f8b\u4e2d\uff0c\u518d\u4f7f\u7528print_list\u65b9\u6cd5\u6253\u5370\u51fa\u94fe\u8868\u4e2d\u6240\u6709\u5143\u7d20\u3002 data_list = [ 1 , 2 , 3 , 4 , 5 ] linked_list = LinkedList () linked_list . insert_from_list ( data_list ) linked_list . print_list () # \u8f93\u51fa: 1 2 3 4 5 if __name__ == \"__main__\" : main () # \u8fd0\u884c\u7ed3\u679c # 1 2 3 4 5 \u5982\u679c\u5728\u521b\u5efaNode\u7684\u65f6\u5019\u6307\u5b9a next \u8282\u70b9\uff0c\u5219\u53ef\u4ee5\u4fee\u6539\u4e3a\u4e0b\u9762\u7684\u4ee3\u7801\u3002 insert_from_list \u51fd\u6570\u9996\u5148\u53cd\u8f6c\u4e86\u8f93\u5165\u7684\u5217\u8868\uff0c\u7136\u540e\u904d\u5386\u53cd\u8f6c\u540e\u7684\u5217\u8868\uff0c\u6bcf\u6b21\u90fd\u5728\u94fe\u8868\u5934\u90e8\u63d2\u5165\u4e00\u4e2a\u65b0\u7684\u8282\u70b9\u3002\u8fd9\u6837\u53ef\u4ee5\u786e\u4fdd\u63d2\u5165\u94fe\u8868\u7684\u5143\u7d20\u987a\u5e8f\u548c\u5b83\u4eec\u5728\u8f93\u5165\u5217\u8868\u4e2d\u7684\u987a\u5e8f\u662f\u4e00\u6837\u7684\u3002 class Node ( object ): \"\"\"\u5355\u5411\u94fe\u63a5\u8282\u70b9\u7c7b\"\"\" def __init__ ( self , data , next = None ): \"\"\"\u5b9e\u4f8b\u5316\u4e00\u4e2a\u8282\u70b9, \u9ed8\u8ba4\u540e\u7ee7\u8282\u70b9\u4e3aNone\"\"\" self . data = data self . next = next class LinkedList : \"\"\"\u5c06\u6570\u7ec4\u5143\u7d20\u8f6c\u79fb\u4e3a\u5355\u5411\u94fe\u63a5\u7ed3\u6784\u91cc\u7684\u6570\u636e\uff0c\u5e76\u4fdd\u7559\u5143\u7d20\u7684\u987a\u5e8f\u4e0d\u53d8\"\"\" def __init__ ( self ): self . head = None # \u521d\u59cb\u5316head def insert_from_list ( self , data_list ): for data in reversed ( data_list ): self . head = Node ( data , self . head ) def print_list ( self ): current = self . head while current : print ( current . data , end = ' ' ) current = current . next print () def main (): data_list = [ 1 , 2 , 3 , 4 , 5 ] linked_list = LinkedList () linked_list . insert_from_list ( data_list ) linked_list . print_list () # \u8f93\u51fa: 1 2 3 4 5 if __name__ == \"__main__\" : main () # \u8fd0\u884c\u7ed3\u679c # 1 2 3 4 5 4.5.\u5355\u5411\u94fe\u63a5\u7ed3\u6784\u4e0a\u7684\u64cd\u4f5c \u00b6 \u6570\u7ec4\u4e0a\u7684\u64cd\u4f5c\u51e0\u4e4e\u90fd\u662f\u57fa\u4e8e\u7d22\u5f15\u7684\u3002\u94fe\u63a5\u7ed3\u6784\u4e0a\u7684\u64cd\u4f5c\u662f\u901a\u8fc7\u64cd\u63a7\u7ed3\u6784\u91cc\u7684\u94fe\u63a5\u6765\u6a21\u62df\u8fd9\u4e9b\u57fa\u4e8e\u7d22\u5f15\u7684\u64cd\u4f5c\u3002 \u4e0b\u9762\u662f\u5b8c\u6574\u4ee3\u7801\uff0c\u5305\u542b\u4e86\u540e\u9762\u5173\u4e8e\u8fde\u63a5\u7ed3\u6784\u7684\u64cd\u4f5c\u793a\u4f8b\u3002 # class Node(object): # \"\"\"\u5355\u5411\u94fe\u63a5\u8282\u70b9\u7c7b\"\"\" # def __init__(self, data, next=None): # \"\"\"\u5b9e\u4f8b\u5316\u4e00\u4e2a\u8282\u70b9, \u9ed8\u8ba4\u540e\u7ee7\u8282\u70b9\u4e3aNone\"\"\" # self.data = data # self.next = next # class TwoWayNode(Node): # \"\"\"\u53cc\u5411\u94fe\u63a5\u8282\u70b9\u7c7b\"\"\" # def __init__(self, data, previous=None, next=None): # \"\"\"\u5b9e\u4f8b\u5316\u4e00\u4e2a\u8282\u70b9, \u9ed8\u8ba4\u524d\u5e8f\u8282\u70b9\u5c3eNone, \u9ed8\u8ba4\u540e\u7ee7\u8282\u70b9\u4e3aNone\"\"\" # Node.__init__(self, data, next) # self.previous = previous # class LinkedList: # \"\"\"\u5355\u5411\u548c\u53cc\u5411\u94fe\u63a5\u7ed3\u6784\"\"\" # def __init__(self, node): # # \u521d\u59cb\u5316\u5934\u8282\u70b9 # self.head = node # # \u5c5e\u6027size\u4fdd\u5b58\u94fe\u63a5\u7ed3\u6784\u7684\u903b\u8f91\u5927\u5c0f\uff0c\u901a\u5e38\u6307\u7684\u662f\u94fe\u8868\u6240\u5305\u542b\u7684\u5143\u7d20\u7684\u6570\u91cf\uff0c\u521d\u59cb\u5316\u94fe\u63a5\u7ed3\u6784\u5927\u5c0f\u4e3a0 # self.size = 0 # def insert_from_list(self, data_list, twoway=False): # \"\"\" # \u628a\u4e00\u4e2a\u5217\u8868\uff08\u5df2\u6709\u7684\u6570\u636e\u7ed3\u6784\uff09\u8f6c\u6362\u4e3a\u94fe\u63a5\u7ed3\u6784\u662f\u4e00\u79cd\u6bd4\u8f83\u5e38\u89c1\u5b9e\u7528\u7684\u65b9\u5f0f\u3002\u8fd9\u79cd\u505a\u6cd5\u53ef\u4ee5\u901a\u8fc7\u63a7\u5236\u4ee3\u7801\uff0c\u65b9\u4fbf\u5730\u4ece\u5df2\u6709\u7684\u96c6\u5408\u7c7b\uff08\u5982\u5217\u8868\uff0c\u6570\u7ec4\u7b49\uff09\u4e2d\u5bfc\u5165\u5143\u7d20\uff0c\u5e76\u6784\u5efa\u9700\u8981\u7684\u7684\u94fe\u63a5\u7ed3\u6784\u3002 # \u5728\u4e00\u4e9b\u7b80\u5355\u573a\u666f\u4e0b\uff0c\u6bd4\u5982\u5df2\u77e5\u5f85\u6dfb\u52a0\u7684\u5143\u7d20\u6570\u91cf\u5f88\u5c11\uff0c\u6216\u8005\u6709\u5176\u4ed6\u7ea6\u675f\u4f7f\u5f97\u7528\u5217\u8868\u4e0d\u65b9\u4fbf\u65f6\uff0c\u53ef\u4ee5\u901a\u8fc7\u624b\u52a8\u65b9\u5f0f\u5411\u94fe\u63a5\u7ed3\u6784\u6dfb\u52a0\u5143\u7d20\u3002\u4f46\u5982\u679c\u5143\u7d20\u5f88\u591a\uff0c\u6216\u8005\u6709\u672a\u77e5\u6570\u91cf\u7684\u5143\u7d20\u9700\u8981\u6dfb\u52a0\uff0c\u7528\u5217\u8868\u53ef\u4ee5\u65b9\u4fbf\u5730\u4e00\u6b21\u6027\u5bfc\u5165\u6240\u6709\u5143\u7d20\u3002 # \"\"\" # if twoway: # \u68c0\u67e5\u662f\u5426\u8981\u521b\u5efa\u53cc\u5411\u94fe\u8868 # for data in data_list: # \u5bf9\u4e8e\u6570\u636e\u5217\u8868\u4e2d\u7684\u6bcf\u4e2a\u6570\u636e\u521b\u5efa\u4e00\u4e2a\u65b0\u7684\u53cc\u5411\u94fe\u63a5\u8282\u70b9 # node = TwoWayNode(data) # if self.head is None: # \u5982\u679c\u94fe\u8868\u4e3a\u7a7a\u628a\u65b0\u8282\u70b9\u8bbe\u7f6e\u4e3a\u5934\u8282\u70b9 # self.head = node # else: # \u5982\u679c\u94fe\u8868\u4e0d\u4e3a\u7a7a # tail = self.head # \u4ece\u5934\u8282\u70b9\u5f00\u59cb # while tail.next is not None: # \u901a\u8fc7\u904d\u5386\u94fe\u8868\u67e5\u627e\u5c3e\u8282\u70b9 # tail = tail.next # tail.next = node # \u628a\u65b0\u8282\u70b9\u63d2\u5165\u5230\u5c3e\u8282\u70b9 # node.previous = tail # \u8bbe\u7f6e\u65b0\u8282\u70b9\u7684\u524d\u4e00\u4e2a\u8282\u70b9\u6307\u5411\u5c3e\u8282\u70b9 # else: # \u521b\u5efa\u5355\u5411\u94fe\u8868 # for data in reversed(data_list): # \u5bf9\u4e8e\u5217\u8868\u4e2d\u7684\u6bcf\u4e2a\u5143\u7d20\uff0c\u53cd\u5411\u8fed\u4ee3\u4f7f\u5f97\u63d2\u5165\u7684\u8282\u70b9\u4e0e\u539f\u6570\u636e\u987a\u5e8f\u76f8\u540c # self.head = Node(data, self.head) # \u521b\u5efa\u4e00\u4e2a\u65b0\u7684\u5355\u5411\u94fe\u63a5\u8282\u70b9\u5e76\u63d2\u5165\u5230\u5934\u8282\u70b9 # self.size += len(data_list) # \u66f4\u65b0\u94fe\u8868\u5927\u5c0f # def get_size(self): # \"\"\"\u83b7\u53d6\u94fe\u8868\u5927\u5c0f\uff08\u8282\u70b9\u6570\u91cf\uff09\"\"\" # return self.size # def search(self, target): # \"\"\"\u5728\u94fe\u63a5\u7ed3\u6784\u4e2d\u641c\u7d22\u6307\u5b9a\u5143\u7d20\"\"\" # current = self.head # \u4ece\u5934\u8282\u70b9\u5f00\u59cb # while current: # \u5f53\u5f53\u524d\u8282\u70b9\u975eNone\u65f6\u7ee7\u7eed\u904d\u5386 # if current.data == target: # \u5982\u679c\u5f53\u524d\u8282\u70b9\u7684\u6570\u636e\u7b49\u4e8e\u76ee\u6807\u6570\u636e # return True # \u8fd4\u56de\u771f\u503c # current = current.next # \u79fb\u52a8\u5230\u4e0b\u4e00\u8282\u70b9 # return False # \u5982\u679c\u6574\u4e2a\u94fe\u8868\u904d\u5386\u5b8c\u6bd5\u8fd8\u627e\u4e0d\u5230\u76ee\u6807\u6570\u636e\uff0c\u8fd4\u56de\u5047\u503c # def locate(self, index): # \"\"\"\u8fd4\u56de\u94fe\u63a5\u7ed3\u6784\u4e2d\u7b2cindex\u4e2a\u5143\u7d20, 0 <= index < n\"\"\" # if index >= self.get_size() or index < 0: # \u5982\u679c\u7d22\u5f15\u8d85\u51fa\u8303\u56f4\uff0c\u7acb\u5373\u629b\u51fa\u9519\u8bef # raise IndexError(\"\u94fe\u8868\u7d22\u5f15\u8d85\u51fa\u8303\u56f4\") # probe = self.head # \u786e\u5b9a\u8d77\u59cb\u70b9\u4e3a\u5934\u8282\u70b9 # while index > 0: # \u5f53\u7d22\u5f15\u5927\u4e8e0\u65f6\uff0c\u8fdb\u5165\u5faa\u73af # probe = probe.next # \u5c06\u63a2\u9488\uff08probe\uff09\u79fb\u52a8\u5230\u4e0b\u4e00\u4e2a\u8282\u70b9 # index -= 1 # \u5c06\u7d22\u5f15\u503c\u51cf1 # return probe.data # \u8fd4\u56de\u5f53\u524d\u4f4d\u7f6e\uff08index\u5bf9\u5e94\u4f4d\u7f6e\uff09\u7684\u8282\u70b9\u6570\u636e # def replace(self, old, new): # \"\"\"\u66ff\u6362\u94fe\u8868\u4e2d\u6240\u6709\u7b49\u4e8eold\u7684\u5143\u7d20\u4e3anew\"\"\" # current = self.head # \u4ece\u94fe\u8868\u7684\u5934\u8282\u70b9\u5f00\u59cb\u904d\u5386 # while current: # \u53ea\u8981\u8fd8\u6709\u8282\u70b9\uff0c\u5c31\u7ee7\u7eed\u904d\u5386 # if current.data == old: # \u68c0\u67e5\u5f53\u524d\u8282\u70b9\u7684\u6570\u636e\u662f\u5426\u7b49\u4e8eold # current.data = new # \u5982\u679c\u7b49\u4e8eold\uff0c\u5c06\u5f53\u524d\u8282\u70b9\u7684\u6570\u636e\u66ff\u6362\u4e3anew # current = current.next # \u7ee7\u7eed\u68c0\u67e5\u4e0b\u4e00\u4e2a\u8282\u70b9 # def print_list(self): # \"\"\"\u6253\u5370\u8f93\u51fa\u94fe\u63a5\u7ed3\u6784\u5185\u5bb9\"\"\" # current = self.head # while current: # print(current.data, end=' ') # current = current.next # print() # def main(): # # \u521b\u5efa\u6d4b\u8bd5\u6570\u636e # test_data = [1, 2, 3, 4, 5] # # \u5355\u5411\u94fe\u8868\u6d4b\u8bd5 # print(\"\u5355\u5411\u94fe\u8868\u6d4b\u8bd5:\") # single_linked_list = LinkedList(None) # print(\"\u63d2\u5165\u6570\u636e\") # single_linked_list.insert_from_list(test_data) # \u63d2\u5165\u6d4b\u8bd5\u6570\u636e # single_linked_list.print_list() # \u6253\u5370\u94fe\u63a5\u7ed3\u6784\u5185\u5bb9 # print(\"\u94fe\u8868\u5927\u5c0f\uff1a\", single_linked_list.get_size()) # \u663e\u793a\u94fe\u63a5\u7ed3\u6784\u5927\u5c0f # print(\"\u641c\u7d22\u5143\u7d203: \", single_linked_list.search(3)) # \u641c\u7d22\u94fe\u63a5\u7ed3\u6784\u4e2d\u662f\u5426\u5b58\u5728\u5143\u7d203 # print(\"\u67e5\u627e\u7b2c2\u4e2a\u5143\u7d20: \", single_linked_list.locate(2)) # \u67e5\u627e\u94fe\u63a5\u7ed3\u6784\u4e2d\u7b2c2\u4e2a\u5143\u7d20 # print(\"\u628a\u5143\u7d201\u66ff\u6362\u4e3a10\") # single_linked_list.replace(1, 10) # \u66ff\u6362\u5143\u7d201\u4e3a10 # single_linked_list.print_list() # print() # # \u53cc\u5411\u94fe\u8868\u6d4b\u8bd5 # print(\"\u53cc\u5411\u94fe\u8868\u6d4b\u8bd5:\") # double_linked_list = LinkedList(None) # print(\"\u63d2\u5165\u6570\u636e\") # double_linked_list.insert_from_list(test_data, twoway=True) # double_linked_list.print_list() # print(\"\u94fe\u8868\u5927\u5c0f\uff1a\", double_linked_list.get_size()) # print(\"\u641c\u7d22\u5143\u7d203\uff1a\", double_linked_list.search(3)) # print(\"\u67e5\u627e\u7b2c2\u4e2a\u5143\u7d20\uff1a\", double_linked_list.locate(2)) # print(\"\u66ff\u6362\u5143\u7d201\u4e3a10\") # double_linked_list.replace(1, 10) # double_linked_list.print_list() # if __name__ == \"__main__\": # main() # # \u8fd0\u884c\u7ed3\u679c # # \u5355\u5411\u94fe\u8868\u6d4b\u8bd5: # # \u63d2\u5165\u6570\u636e # # 1 2 3 4 5 # # \u94fe\u8868\u5927\u5c0f\uff1a 5 # # \u641c\u7d22\u5143\u7d203\uff1a True # # \u67e5\u627e\u7b2c2\u4e2a\u5143\u7d20\uff1a 3 # # \u66ff\u6362\u5143\u7d201\u4e3a10 # # 10 2 3 4 5 # # \u53cc\u5411\u94fe\u8868\u6d4b\u8bd5: # # \u63d2\u5165\u6570\u636e # # 1 2 3 4 5 # # \u94fe\u8868\u5927\u5c0f\uff1a 5 # # \u641c\u7d22\u5143\u7d203\uff1a True # # \u67e5\u627e\u7b2c2\u4e2a\u5143\u7d20\uff1a 3 # # \u66ff\u6362\u5143\u7d201\u4e3a10 # # 10 2 3 4 5 4.5.1.\u904d\u5386 \u00b6 \u57284.4\u4e2d\u7684\u793a\u4f8b\u4ee3\u7801\u4e2d\uff08\u5982\u4e0b\uff09\uff0c\u8282\u70b9\u4f1a\u5728\u88ab\u6253\u5370\u4e4b\u540e\u4ece\u94fe\u63a5\u7ed3\u6784\u91cc\u5220\u9664\u3002 def main (): # \u521b\u5efa\u4e00\u4e2a\u5355\u5411\u94fe\u63a5\u7ed3\u6784\uff0c\u5e76\u6253\u5370\u51fa\u5b83\u7684\u5185\u5bb9 head = None # \u5728\u94fe\u63a5\u7ed3\u6784\u7684\u5f00\u5934\u4f9d\u6b21\u63d2\u5165\u4e94\u4e2a\u8282\u70b9 for count in range ( 1 , 6 ): head = Node ( count , head ) # \u6253\u5370\u8f93\u51fa\u8fd9\u4e2a\u5355\u5411\u94fe\u63a5\u7684\u4e94\u4e2a\u8282\u70b9\u7684\u5185\u5bb9 while head != None : print ( head . data ) head = head . next if __name__ == \"__main__\" : main () # \u8fd0\u884c\u7ed3\u679c # 5 # 4 # 3 # 2 # 1 \u5bf9\u4e8e\u8bb8\u591a\u5e94\u7528\u7a0b\u5e8f\u6765\u8bf4\uff0c\u53ea\u9700\u8981\u8bbf\u95ee\u6bcf\u4e2a\u8282\u70b9\u800c\u4e0d\u7528\u5220\u9664\u5b83\u4eec\u3002\u8fd9\u4e2a\u64cd\u4f5c\u79f0\u4e3a\u904d\u5386\uff08traversal\uff09\u3002 \u5728\u904d\u5386\u4e2d\uff0c\u4f1a\u7528\u5230\u4e00\u4e2a\u53eb\u4f5c probe \u7684\u4e34\u65f6\u6307\u9488\u53d8\u91cf\u3002\u4e00\u5f00\u59cb\uff0c\u8fd9\u4e2a\u53d8\u91cf\u88ab\u521d\u59cb\u5316\u4e3a\u94fe\u63a5\u7ed3\u6784\u7684head\u6307\u9488\uff0c\u7136\u540e\u901a\u8fc7\u5faa\u73af\u6765\u5b8c\u6210\uff0c\u5728\u6574\u4e2a\u8fc7\u7a0b\u7ed3\u675f\u4e4b\u540e\uff0cprobe\u6307\u9488\u662fNone\uff0c\u4f46head\u6307\u9488\u4ecd\u7136\u5f15\u7528\u7b2c\u4e00\u4e2a\u8282\u70b9\u3002 \u4e0b\u9762\u662f\u4fee\u6539\u540e\u7684\u4ee3\u7801\uff1a def main (): print ( \"------\" ) # \u521b\u5efa\u4e00\u4e2a\u5355\u5411\u94fe\u63a5\u7ed3\u6784\uff0c\u5e76\u6253\u5370\u51fa\u5b83\u7684\u5185\u5bb9 head = None # \u5728\u94fe\u63a5\u7ed3\u6784\u7684\u5f00\u5934\u4f9d\u6b21\u63d2\u5165\u4e94\u4e2a\u8282\u70b9 for count in range ( 1 , 6 ): head = Node ( count , head ) # \u6253\u5370\u8f93\u51fa\u8fd9\u4e2a\u5355\u5411\u94fe\u63a5\u7684\u4e94\u4e2a\u8282\u70b9\u7684\u5185\u5bb9 probe = head while probe != None : print ( probe . data ) probe = probe . next \u901a\u5e38\u6765\u8bf4\uff0c\u5355\u5411\u94fe\u63a5\u7ed3\u6784\u7684\u904d\u5386\u4f1a\u8bbf\u95ee\u6240\u6709\u8282\u70b9\uff0c\u5e76\u4e14\u5728\u5230\u8fbe\u7a7a\u94fe\u63a5\u65f6\u7ec8\u6b62\u904d\u5386\u3002\u56e0\u6b64\uff0c\u503c None \u76f8\u5f53\u4e8e\u505c\u6b62\u8fdb\u7a0b\u7684\u54e8\u5175\uff08sentinel\uff09\u3002 \u904d\u5386\u7684\u65f6\u95f4\u590d\u6742\u5ea6\u662f\u7ebf\u6027\u7684\uff0c\u4e5f\u4e0d\u9700\u8981\u989d\u5916\u7684\u5185\u5b58\u3002 4.5.2.\u641c\u7d22 \u00b6 \u5bf9\u94fe\u63a5\u7ed3\u6784\u8fdb\u884c\u987a\u5e8f\u641c\u7d22\u6709\u70b9\u7c7b\u4f3c\u4e8e\u904d\u5386\u64cd\u4f5c\uff0c\u56e0\u4e3a\u5fc5\u987b\u8981\u4ece\u7b2c\u4e00\u4e2a\u8282\u70b9\u5f00\u59cb\u5e76\u4f9d\u7167\u94fe\u63a5\u987a\u5e8f\u79fb\u52a8\uff0c\u76f4\u81f3\u627e\u5230\u5bf9\u5e94\u7684\u6807\u8bb0\u3002\u5728\u8fd9\u79cd\u60c5\u51b5\u4e0b\uff0c\u8fd9\u4e2a\u6807\u8bb0\u6709\u4e24\u79cd\u53ef\u80fd\u6027\u3002 \u7a7a\u94fe\u63a5\uff0c\u8bf4\u660e\u6ca1\u6709\u66f4\u591a\u9700\u8981\u88ab\u68c0\u67e5\u7684\u6570\u636e\u5143\u7d20\u3002 \u7b49\u540c\u4e8e\u76ee\u6807\u5143\u7d20\u7684\u6570\u636e\u5143\u7d20\uff0c\u4ee3\u8868\u641c\u7d22\u6210\u529f\u3002 \u4e0b\u9762\u662f\u641c\u7d22\u7ed9\u5b9a\u5143\u7d20\u7684\u4ee3\u7801\u3002 search(self, target) \u65b9\u6cd5\u5b9e\u73b0\u4e86\u5728\u5355\u5411\u6216\u53cc\u5411\u94fe\u8868\u4e2d\u641c\u7d22\u6307\u5b9a\u5143\u7d20\u3002 def search ( self , target ): \"\"\"\u5728\u94fe\u63a5\u7ed3\u6784\u4e2d\u641c\u7d22\u6307\u5b9a\u5143\u7d20\"\"\" current = self . head # \u4ece\u5934\u8282\u70b9\u5f00\u59cb while current : # \u5f53\u5f53\u524d\u8282\u70b9\u975eNone\u65f6\u7ee7\u7eed\u904d\u5386 if current . data == target : # \u5982\u679c\u5f53\u524d\u8282\u70b9\u7684\u6570\u636e\u7b49\u4e8e\u76ee\u6807\u6570\u636e return True # \u8fd4\u56de\u771f\u503c current = current . next # \u79fb\u52a8\u5230\u4e0b\u4e00\u8282\u70b9 return False # \u5982\u679c\u6574\u4e2a\u94fe\u8868\u904d\u5386\u5b8c\u6bd5\u8fd8\u627e\u4e0d\u5230\u76ee\u6807\u6570\u636e\uff0c\u8fd4\u56de\u5047\u503c \u5e73\u5747\u60c5\u51b5\u4e0b\uff0c\u987a\u5e8f\u641c\u7d22\u5728\u5355\u5411\u94fe\u63a5\u7ed3\u6784\u4e0a\u662f\u7ebf\u6027\u7684\u3002 \u8bbf\u95ee\u94fe\u63a5\u7ed3\u6784\u7684\u7b2c i \u4e2a\u5143\u7d20\u65f6\u6267\u884c\u7684\u4e5f\u662f\u987a\u5e8f\u641c\u7d22\u3002\u8fd9\u662f\u56e0\u4e3a\u5fc5\u987b\u4ece\u7b2c\u4e00\u4e2a\u8282\u70b9\u5f00\u59cb\u7edf\u8ba1\u94fe\u63a5\u7684\u6570\u91cf\uff0c\u76f4\u81f3\u5230\u8fbe\u7b2c i \u4e2a\u8282\u70b9\u4e3a\u6b62\u3002\u5047\u8bbe\u6709 0<=i= self . get_size () or index < 0 : # \u5982\u679c\u7d22\u5f15\u8d85\u51fa\u8303\u56f4\uff0c\u7acb\u5373\u629b\u51fa\u9519\u8bef raise IndexError ( \"\u94fe\u8868\u7d22\u5f15\u8d85\u51fa\u8303\u56f4\" ) probe = self . head # \u786e\u5b9a\u8d77\u59cb\u70b9\u4e3a\u5934\u8282\u70b9 while index > 0 : # \u5f53\u7d22\u5f15\u5927\u4e8e0\u65f6\uff0c\u8fdb\u5165\u5faa\u73af probe = probe . next # \u5c06\u63a2\u9488\uff08probe\uff09\u79fb\u52a8\u5230\u4e0b\u4e00\u4e2a\u8282\u70b9 index -= 1 # \u5c06\u7d22\u5f15\u503c\u51cf1 return probe . data # \u8fd4\u56de\u5f53\u524d\u4f4d\u7f6e\uff08index\u5bf9\u5e94\u4f4d\u7f6e\uff09\u7684\u8282\u70b9\u6570\u636e \u548c\u6570\u7ec4\u4e0d\u540c\u7684\u662f\uff0c\u94fe\u63a5\u7ed3\u6784\u5e76\u4e0d\u652f\u6301\u968f\u673a\u8bbf\u95ee\u3002\u56e0\u6b64\uff0c\u4e0d\u80fd\u50cf\u5728\u6709\u5e8f\u6570\u7ec4\u91cc\u90a3\u6837\u5bf9\u6709\u5e8f\u7684\u5355\u5411\u94fe\u63a5\u7ed3\u6784\u8fdb\u884c\u9ad8\u6548\u641c\u7d22\u3002 4.5.3.\u66ff\u6362 \u00b6 \u5355\u5411\u94fe\u63a5\u7ed3\u6784\u91cc\u7684\u66ff\u6362\u64cd\u4f5c\u4e5f\u4f1a\u91c7\u7528\u904d\u5386\u7684\u6a21\u5f0f\u3002\u5728\u8fd9\u79cd\u60c5\u51b5\u4e0b\uff0c\u6211\u4eec\u4f1a\u5728\u94fe\u63a5\u7ed3\u6784\u91cc\u641c\u7d22\u7ed9\u5b9a\u7684\u5143\u7d20\u6216\u7ed9\u5b9a\u7684\u4f4d\u7f6e\uff0c\u7136\u540e\u7528\u4e00\u4e2a\u65b0\u7684\u5143\u7d20\u66ff\u6362\u8fd9\u4e2a\u5143\u7d20\u3002 \u5728\u66ff\u6362\u7ed9\u5b9a\u5143\u7d20\u65f6\uff0c\u5e76\u4e0d\u9700\u8981\u5047\u5b9a\u76ee\u6807\u5143\u7d20\u5df2\u7ecf\u5b58\u5728\u4e8e\u94fe\u63a5\u7ed3\u6784\u91cc\u3002 \u5982\u679c\u76ee\u6807\u5143\u7d20\u4e0d\u5b58\u5728\uff0c\u5c31\u4e0d\u4f1a\u53d1\u751f\u4efb\u4f55\u66ff\u6362\u64cd\u4f5c\uff0c\u5e76\u4e14\u4f1a\u8fd4\u56de False \uff1b \u5982\u679c\u76ee\u6807\u5143\u7d20\u5b58\u5728\uff0c\u65b0\u7684\u5143\u7d20\u5c31\u4f1a\u66ff\u6362\u5b83\uff0c\u5e76\u4e14\u8fd4\u56de True \uff1b \u4e0b\u9762\u662f\u8fd9\u4e2a\u64cd\u4f5c\u7684\u4ee3\u7801\u3002 def replace ( self , old , new ): \"\"\"\u66ff\u6362\u94fe\u8868\u4e2d\u6240\u6709\u7b49\u4e8eold\u7684\u5143\u7d20\u4e3anew\"\"\" current = self . head # \u4ece\u94fe\u8868\u7684\u5934\u8282\u70b9\u5f00\u59cb\u904d\u5386 while current : # \u53ea\u8981\u8fd8\u6709\u8282\u70b9\uff0c\u5c31\u7ee7\u7eed\u904d\u5386 if current . data == old : # \u68c0\u67e5\u5f53\u524d\u8282\u70b9\u7684\u6570\u636e\u662f\u5426\u7b49\u4e8eold current . data = new # \u5982\u679c\u7b49\u4e8eold\uff0c\u5c06\u5f53\u524d\u8282\u70b9\u7684\u6570\u636e\u66ff\u6362\u4e3anew current = current . next # \u7ee7\u7eed\u68c0\u67e5\u4e0b\u4e00\u4e2a\u8282\u70b9 4.5.4.\u5728\u5f00\u59cb\u5904\u63d2\u5165 \u00b6 \u5728\u94fe\u63a5\u7ed3\u6784\u5934\u90e8\u63d2\u5165\u52062\u79cd\u60c5\u51b5\uff1a \u7b2c\u4e00\u79cd\u60c5\u51b5\uff1a head \u6307\u9488\u662f None \uff0c\u63d2\u5165\u64cd\u4f5c\u4f1a\u628a\u7b2c\u4e00\u4e2a\u5143\u7d20\u63d2\u5165\u7ed3\u6784\u91cc\uff1b \u7b2c\u4e8c\u79cd\u60c5\u51b5\uff1a head \u6307\u9488\u4e0d\u662f None \uff0c\uff0c\u7b2c\u4e8c\u4e2a\u5143\u7d20\u4f1a\u88ab\u63d2\u5165\u8fd9\u4e2a\u7ed3\u6784\u7684\u5f00\u5934\uff1b \u4ece\u4e0a\u97622\u79cd\u60c5\u51b5\u5f97\u51fa\uff0c\u5728\u5df2\u7ecf\u6709\u6570\u636e\u7684\u60c5\u51b5\u4e0b\uff0c\u5e76\u4e0d\u9700\u8981\u901a\u8fc7\u590d\u5236\u6570\u636e\u6765\u8ba9\u5b83\u4eec\u5411\u540e\u79fb\u52a8\uff0c\u4e5f\u4e0d\u9700\u8981\u989d\u5916\u7684\u5185\u5b58\u3002\u8fd9\u4e5f\u5c31\u610f\u5473\u7740\u5728\u94fe\u63a5\u7ed3\u6784\u7684\u5f00\u5934\u5904\u63d2\u5165\u6570\u636e\u53ea\u4f1a\u7528\u5230\u5e38\u6570\u7684\u65f6\u95f4\u548c\u5185\u5b58\uff0c\u8fd9\u548c\u5bf9\u6570\u7ec4\u7684\u76f8\u540c\u64cd\u4f5c\u662f\u4e0d\u4e00\u6837\u7684\u3002 \u4e0b\u9762\u662f\u5b8c\u6574\u7684\u4ee3\u7801\u3002 \"\"\" \u5b9e\u73b0\u4e86\u5bf9\u5355\u5411\u94fe\u63a5\u8fdb\u884c\u5982\u4e0b\u64cd\u4f5c\uff1a 1. \u5728\u5f00\u59cb\u5904\u63d2\u5165 2. \u5728\u7ed3\u5c3e\u5904\u63d2\u5165 3. \u5728\u5f00\u59cb\u5904\u5220\u9664 4. \u5728\u7ed3\u5c3e\u5904\u5220\u9664 5. \u5728\u4efb\u610f\u5904\u63d2\u5165 6. \u5728\u4efb\u610f\u5904\u5220\u9664 \"\"\" class Node ( object ): \"\"\"\u5355\u5411\u94fe\u63a5\u8282\u70b9\u7c7b\"\"\" def __init__ ( self , data , next = None ): \"\"\" \u5b9e\u4f8b\u5316\u4e00\u4e2a\u8282\u70b9, \u9ed8\u8ba4\u540e\u7ee7\u8282\u70b9\u4e3aNone Args: data: \u8282\u70b9\u5b58\u50a8\u7684\u6570\u636e next: \u6307\u5411\u4e0b\u4e00\u4e2a\u8282\u70b9\u7684\u6307\u9488\uff0c\u9ed8\u8ba4\u4e3aNone \"\"\" self . data = data # \u5b9a\u4e49\u8282\u70b9\u7684\u6570\u636e\u90e8\u5206 self . next = next # \u5b9a\u4e49\u8282\u70b9\u7684\u6307\u9488\u90e8\u5206\uff0c\u521d\u59cb\u503c\u4e3aNone\u8868\u793a\u6ca1\u6709\u4e0b\u4e00\u4e2a\u8282\u70b9 def insert_at_beginning ( head , data ): \"\"\" \u5728\u94fe\u8868\u5f00\u59cb\u5904\u63d2\u5165\u65b0\u8282\u70b9 Args: head: \u5f53\u524d\u94fe\u8868\u7684\u5934\u8282\u70b9 data: \u65b0\u8282\u70b9\u7684\u6570\u636e Returns: Node: \u65b0\u7684\u5934\u8282\u70b9 \"\"\" new_node = Node ( data ) # \u521b\u5efa\u65b0\u7684\u8282\u70b9\u5bf9\u8c61 new_node . next = head # \u5c06\u65b0\u8282\u70b9\u7684next\u6307\u9488\u6307\u5411\u5f53\u524d\u5934\u8282\u70b9 return new_node # \u8fd4\u56de\u65b0\u7684\u5934\u8282\u70b9 def insert_at_end ( head , data ): \"\"\" \u5728\u94fe\u8868\u672b\u5c3e\u63d2\u5165\u65b0\u8282\u70b9 Args: head: \u5f53\u524d\u94fe\u8868\u7684\u5934\u8282\u70b9 data: \u65b0\u8282\u70b9\u7684\u6570\u636e Returns: Node: \u5934\u8282\u70b9 \"\"\" new_node = Node ( data ) # \u521b\u5efa\u65b0\u7684\u8282\u70b9\u5bf9\u8c61 if head is None : # \u5982\u679c\u94fe\u8868\u4e3a\u7a7a\uff0c\u5c06\u65b0\u8282\u70b9\u8bbe\u7f6e\u4e3a\u5934\u8282\u70b9 head = new_node else : probe = head # \u521b\u5efa\u4e00\u4e2a\u6307\u9488\uff0c\u4ece\u5934\u8282\u70b9\u5f00\u59cb\u904d\u5386\u94fe\u8868 while probe . next is not None : # \u5f53\u6307\u9488\u6240\u6307\u8282\u70b9\u6709\u4e0b\u4e00\u4e2a\u8282\u70b9\u65f6 probe = probe . next # \u79fb\u52a8\u6307\u9488\u5230\u4e0b\u4e00\u4e2a\u8282\u70b9 probe . next = new_node # \u5c06\u65b0\u8282\u70b9\u8fde\u63a5\u5230\u5f53\u524d\u6307\u9488\u6240\u6307\u8282\u70b9\u7684\u4e0b\u4e00\u4e2a\u4f4d\u7f6e\uff0c\u5b8c\u6210\u8282\u70b9\u7684\u63d2\u5165 return head # \u8fd4\u56de\u5934\u8282\u70b9 def delete_at_beginning ( head ): \"\"\" \u4ece\u94fe\u8868\u5f00\u59cb\u5904\u5220\u9664\u8282\u70b9 Args: head: \u5f53\u524d\u94fe\u8868\u7684\u5934\u8282\u70b9 Returns: Node: \u65b0\u7684\u5934\u8282\u70b9 \"\"\" if head is None : # \u5982\u679c\u94fe\u8868\u4e3a\u7a7a\uff0c\u6253\u5370\u6d88\u606f\u5e76\u8fd4\u56de\u7a7a\u94fe\u8868 print ( \"Linked list is empty.\" ) else : head = head . next # \u5c06\u5934\u8282\u70b9\u6307\u5411\u4e0b\u4e00\u4e2a\u8282\u70b9\uff0c\u5373\u5220\u9664\u7b2c\u4e00\u4e2a\u8282\u70b9 return head # \u8fd4\u56de\u65b0\u7684\u5934\u8282\u70b9 def delete_at_end ( head ): \"\"\" \u4ece\u94fe\u8868\u672b\u5c3e\u5220\u9664\u8282\u70b9 Args: head: \u5f53\u524d\u94fe\u8868\u7684\u5934\u8282\u70b9 Returns: Node: \u5934\u8282\u70b9 \"\"\" if head is None : # \u5982\u679c\u94fe\u8868\u4e3a\u7a7a\uff0c\u8fd4\u56deNone return None if head . next is None : # \u5982\u679c\u94fe\u8868\u53ea\u6709\u4e00\u4e2a\u8282\u70b9\uff0c\u5c06\u5934\u8282\u70b9\u7f6e\u4e3aNone return None current = head while current . next . next : # \u79fb\u52a8\u5230\u5012\u6570\u7b2c\u4e8c\u4e2a\u8282\u70b9 current = current . next current . next = None # \u5c06\u5012\u6570\u7b2c\u4e8c\u4e2a\u8282\u70b9\u7684next\u7f6e\u4e3aNone\uff0c\u5373\u5220\u9664\u4e86\u6700\u540e\u4e00\u4e2a\u8282\u70b9 return head # \u8fd4\u56de\u5934\u8282\u70b9 def insert_at_position ( head , data , position ): \"\"\" \u5728\u94fe\u8868\u7684\u4efb\u610f\u4f4d\u7f6e\u63d2\u5165\u65b0\u8282\u70b9 Args: head: \u5f53\u524d\u94fe\u8868\u7684\u5934\u8282\u70b9 data: \u65b0\u8282\u70b9\u7684\u6570\u636e position: \u63d2\u5165\u7684\u4f4d\u7f6e Returns: Node: \u5934\u8282\u70b9 \"\"\" new_node = Node ( data ) # \u521b\u5efa\u65b0\u7684\u8282\u70b9\u5bf9\u8c61 if position == 0 : # \u5982\u679c\u63d2\u5165\u4f4d\u7f6e\u4e3a0\uff0c\u5373\u5728\u5934\u90e8\u63d2\u5165 new_node . next = head # \u65b0\u8282\u70b9\u7684next\u6307\u5411\u5f53\u524d\u5934\u8282\u70b9 return new_node # \u8fd4\u56de\u65b0\u7684\u5934\u8282\u70b9 probe = head # \u521b\u5efa\u4e00\u4e2a\u6307\u9488\uff0c\u4ece\u5934\u8282\u70b9\u5f00\u59cb\u904d\u5386\u94fe\u8868 count = 0 while probe . next is not None and count < position - 1 : # \u627e\u5230\u63d2\u5165\u4f4d\u7f6e\u7684\u524d\u4e00\u4e2a\u8282\u70b9 probe = probe . next count += 1 new_node . next = probe . next # \u65b0\u8282\u70b9\u7684next\u6307\u5411\u63d2\u5165\u4f4d\u7f6e\u7684\u8282\u70b9 probe . next = new_node # \u63d2\u5165\u4f4d\u7f6e\u7684\u524d\u4e00\u4e2a\u8282\u70b9\u7684next\u6307\u5411\u65b0\u8282\u70b9 return head # \u8fd4\u56de\u5934\u8282\u70b9 def delete_at_position ( head , position ): \"\"\" \u4ece\u94fe\u8868\u7684\u4efb\u610f\u4f4d\u7f6e\u5220\u9664\u8282\u70b9 Args: head: \u5f53\u524d\u94fe\u8868\u7684\u5934\u8282\u70b9 position: \u5220\u9664\u7684\u4f4d\u7f6e Returns: Node: \u5934\u8282\u70b9 \"\"\" if head is None : # \u5982\u679c\u94fe\u8868\u4e3a\u7a7a\uff0c\u8fd4\u56deNone return None if position == 0 : # \u5982\u679c\u5220\u9664\u4f4d\u7f6e\u4e3a0\uff0c\u5373\u5220\u9664\u5934\u90e8\u8282\u70b9 return head . next # \u8fd4\u56de\u5934\u8282\u70b9\u7684\u4e0b\u4e00\u4e2a\u8282\u70b9 probe = head # \u521b\u5efa\u4e00\u4e2a\u6307\u9488\uff0c\u4ece\u5934\u8282\u70b9\u5f00\u59cb\u904d\u5386\u94fe\u8868 count = 0 while probe . next is not None and count < position - 1 : # \u627e\u5230\u5220\u9664\u4f4d\u7f6e\u7684\u524d\u4e00\u4e2a\u8282\u70b9 probe = probe . next count += 1 if probe . next is None : # \u5982\u679c\u5220\u9664\u4f4d\u7f6e\u8d85\u8fc7\u94fe\u8868\u957f\u5ea6\uff0c\u4e0d\u505a\u64cd\u4f5c return head probe . next = probe . next . next # \u5220\u9664\u4f4d\u7f6e\u7684\u524d\u4e00\u4e2a\u8282\u70b9\u7684next\u6307\u5411\u5220\u9664\u4f4d\u7f6e\u7684\u540e\u4e00\u4e2a\u8282\u70b9 return head # \u8fd4\u56de\u5934\u8282\u70b9 def print_linked_list ( head ): \"\"\" \u6253\u5370\u94fe\u8868\u4e2d\u7684\u6240\u6709\u8282\u70b9 Args: head: \u5f53\u524d\u94fe\u8868\u7684\u5934\u8282\u70b9 \"\"\" probe = head while probe is not None : print ( probe . data , end = \" -> \" ) # \u6253\u5370\u5f53\u524d\u8282\u70b9\u7684\u6570\u636e probe = probe . next # \u79fb\u52a8\u5230\u4e0b\u4e00\u4e2a\u8282\u70b9 print ( \"None\" ) # \u6253\u5370\u94fe\u8868\u7ed3\u675f\u7684\u6807\u5fd7 def main (): head = None # \u521b\u5efa\u4e00\u4e2a\u7a7a\u94fe\u8868\uff0c\u521d\u59cb\u65f6\u5934\u8282\u70b9\u4e3aNone # \u4ece\u5c3e\u90e8\u63d2\u5165\u8282\u70b9 for count in range ( 1 , 6 ): # \u4ece1\u52305\u904d\u5386 head = insert_at_end ( head , count ) # \u5728\u5c3e\u90e8\u63d2\u5165\u8282\u70b9 print ( \"\u521d\u59cb\u94fe\u8868:\" ) print_linked_list ( head ) # \u6253\u5370\u539f\u59cb\u94fe\u8868 # \u9a8c\u8bc1\u4ece\u5934\u90e8\u5904\u63d2\u5165\u8282\u70b9 new_data_at_beginning = 0 head = insert_at_beginning ( head , new_data_at_beginning ) # \u5728\u94fe\u8868\u5934\u90e8\u63d2\u5165\u65b0\u8282\u70b9 print ( f \" \\n \u5728\u5934\u90e8\u63d2\u5165 { new_data_at_beginning } \u540e\u7684\u94fe\u8868:\" ) print_linked_list ( head ) # \u6253\u5370\u63d2\u5165\u65b0\u8282\u70b9\u540e\u7684\u94fe\u8868\u72b6\u6001 # \u9a8c\u8bc1\u4ece\u672b\u5c3e\u5904\u63d2\u5165\u8282\u70b9 new_data = 10 head = insert_at_end ( head , new_data ) # \u5728\u94fe\u8868\u672b\u5c3e\u63d2\u5165\u65b0\u8282\u70b9 print ( f \" \\n \u5728\u5c3e\u90e8\u63d2\u5165 { new_data } \u540e\u7684\u94fe\u8868:\" ) print_linked_list ( head ) # \u6253\u5370\u63d2\u5165\u65b0\u8282\u70b9\u540e\u7684\u94fe\u8868\u72b6\u6001 # \u9a8c\u8bc1\u4ece\u5934\u90e8\u5220\u9664\u8282\u70b9 head = delete_at_beginning ( head ) # \u5220\u9664\u7b2c\u4e00\u4e2a\u8282\u70b9 print ( \" \\n \u4ece\u5934\u90e8\u5220\u9664\u8282\u70b9\u540e\u7684\u94fe\u8868:\" ) print_linked_list ( head ) # \u6253\u5370\u5220\u9664\u8282\u70b9\u540e\u7684\u94fe\u8868\u72b6\u6001 # \u9a8c\u8bc1\u4ece\u5c3e\u90e8\u5220\u9664\u8282\u70b9 head = delete_at_end ( head ) # \u4ece\u94fe\u8868\u672b\u5c3e\u5220\u9664\u8282\u70b9 print ( \" \\n \u4ece\u5c3e\u90e8\u5220\u9664\u8282\u70b9\u540e\u7684\u94fe\u8868:\" ) print_linked_list ( head ) # \u6253\u5370\u5220\u9664\u8282\u70b9\u540e\u7684\u94fe\u8868\u72b6\u6001 # \u9a8c\u8bc1\u4ece\u4efb\u610f\u4f4d\u7f6e\u63d2\u5165\u8282\u70b9 position = 3 new_data = 99 head = insert_at_position ( head , new_data , position ) # \u5728\u7b2c3\u4e2a\u4f4d\u7f6e\u63d2\u5165\u8282\u70b9 print ( f \" \\n \u5728\u4f4d\u7f6e { position } \u63d2\u5165 { new_data } \u540e\u7684\u94fe\u8868:\" ) print_linked_list ( head ) # \u9a8c\u8bc1\u4ece\u4efb\u610f\u4f4d\u7f6e\u5220\u9664\u8282\u70b9 position = 2 head = delete_at_position ( head , position ) # \u5220\u9664\u7b2c2\u4e2a\u4f4d\u7f6e\u7684\u8282\u70b9 print ( f \" \\n \u5728\u4f4d\u7f6e { position } \u63d2\u5165 { new_data } \u540e\u7684\u94fe\u8868:\" ) print_linked_list ( head ) if __name__ == \"__main__\" : main () # \u8fd0\u884c\u7ed3\u679c # \u521d\u59cb\u94fe\u8868: # 1 -> 2 -> 3 -> 4 -> 5 -> None # \u5728\u5934\u90e8\u63d2\u5165 0 \u540e\u7684\u94fe\u8868: # 0 -> 1 -> 2 -> 3 -> 4 -> 5 -> None # \u5728\u5c3e\u90e8\u63d2\u5165 10 \u540e\u7684\u94fe\u8868: # 0 -> 1 -> 2 -> 3 -> 4 -> 5 -> 10 -> None # \u4ece\u5934\u90e8\u5220\u9664\u8282\u70b9\u540e\u7684\u94fe\u8868: # 1 -> 2 -> 3 -> 4 -> 5 -> 10 -> None # \u4ece\u5c3e\u90e8\u5220\u9664\u8282\u70b9\u540e\u7684\u94fe\u8868: # 1 -> 2 -> 3 -> 4 -> 5 -> None # \u5728\u4f4d\u7f6e 3 \u63d2\u5165 99 \u540e\u7684\u94fe\u8868: # 1 -> 2 -> 3 -> 99 -> 4 -> 5 -> None # \u5728\u4f4d\u7f6e 2 \u63d2\u5165 99 \u540e\u7684\u94fe\u8868: # 1 -> 2 -> 99 -> 4 -> 5 -> None 4.5.5.\u5728\u7ed3\u5c3e\u5904\u63d2\u5165 \u00b6 \u5bf9\u4e8e\u5355\u5411\u94fe\u63a5\u7ed3\u6784\uff0c\u5728\u7ed3\u5c3e\u5904\u63d2\u5165\u65f6\u9700\u8981\u8003\u8651\u4e24\u79cd\u60c5\u51b5\uff1a \u5f53 head \u6307\u9488\u662f None \u65f6\uff0c\u5b83\u4f1a\u88ab\u8bbe\u7f6e\u4e3a\u65b0\u8282\u70b9\u3002 \u5f53 head \u6307\u9488\u4e0d\u662f None \u65f6\uff0c\u4ee3\u7801\u4f1a\u627e\u5230\u6700\u540e\u4e00\u4e2a\u8282\u70b9\uff0c\u5e76\u628a\u5b83\u7684\u4e0b\u4e00\u4e2a\u6307\u9488\u6307\u5411\u65b0\u8282\u70b9\u3002 \u56e0\u6b64\u5728\u6709\u6570\u636e\u7684\u60c5\u51b5\u4e0b\uff0c\u4f1a\u7528\u5230\u904d\u5386\u6a21\u5f0f\u3002 4.5.6.\u5728\u5f00\u59cb\u5904\u5220\u9664 \u00b6 \u5728\u6267\u884c\u4ece\u94fe\u63a5\u7ed3\u6784\u7684\u5f00\u5934\u5220\u9664\u5143\u7d20\u7684\u64cd\u4f5c\u65f6\uff0c\u901a\u5e38\u90fd\u4f1a\u5047\u5b9a\u7ed3\u6784\u91cc\u81f3\u5c11\u5b58\u5728\u4e00\u4e2a\u8282\u70b9\uff0c\u8fd9\u4e2a\u64cd\u4f5c\u5c06\u8fd4\u56de\u88ab\u5220\u9664\u7684\u5143\u7d20\u3002 \u8fd9\u4e2a\u64cd\u4f5c\u4f1a\u7528\u5230\u5e38\u6570\u7684\u65f6\u95f4\u548c\u5185\u5b58\uff0c\u8fd9\u4e0e\u5728\u6570\u7ec4\u4e0a\u6267\u884c\u76f8\u540c\u7684\u64cd\u4f5c\u662f\u6709\u6240\u4e0d\u540c\u7684\u3002 4.5.7.\u5728\u7ed3\u5c3e\u5904\u5220\u9664 \u00b6 \u5355\u5411\u94fe\u63a5\u7ed3\u6784\u4e2d\u7684\u8fd9\u4e2a\u64cd\u4f5c\u5047\u5b9a\u5728\u7ed3\u6784\u91cc\u81f3\u5c11\u6709\u4e00\u4e2a\u8282\u70b9\uff0c\u8fd9\u6837\u5c31\u6709\u4e24\u79cd\u60c5\u51b5\u9700\u8981\u8003\u8651\u3002 \u53ea\u6709\u4e00\u4e2a\u8282\u70b9\uff0c\u8fd9\u65f6\u53ea\u9700\u8981\u628ahead\u6307\u9488\u8bbe\u7f6e\u4e3a None \u3002 \u6700\u540e\u4e00\u4e2a\u8282\u70b9\u4e4b\u524d\u8fd8\u6709\u4e00\u4e2a\u8282\u70b9\u3002\u8fd9\u65f6\u76f8\u5e94\u7684\u4ee3\u7801\u4f1a\u627e\u5230\u5012\u6570\u7b2c\u4e8c\u4e2a\u8282\u70b9\uff0c\u5e76\u628a\u4e0b\u4e00\u4e2a\u6307\u9488\u8bbe\u7f6e\u4e3a None \u3002 \u65e0\u8bba\u662f\u54ea\u79cd\u60c5\u51b5\uff0c\u4ee3\u7801\u90fd\u4f1a\u8fd4\u56de\u8fd9\u4e2a\u88ab\u5220\u9664\u8282\u70b9\u91cc\u5305\u542b\u7684\u6570\u636e\u5143\u7d20\u3002 \u8fd9\u4e2a\u64cd\u4f5c\u4f1a\u7528\u5230\u5e38\u6570\u7684\u65f6\u95f4\u548c\u5185\u5b58\u3002 4.5.8.\u5728\u4efb\u610f\u4f4d\u7f6e\u5904\u63d2\u5165 \u00b6 \u5728\u94fe\u63a5\u7ed3\u6784\u7684\u4efb\u610f\u4f4d\u7f6e\u63d2\u5165\u5143\u7d20\u65f6\u9700\u8981\u8003\u86512\u79cd\u60c5\u51b5\uff1a \u5728\u5f00\u5934\u63d2\u5165\uff0c\u53ef\u4ee5\u7528\u524d\u9762\u63d0\u5230\u7684\u4ee3\u7801\u3002 \u5728\u5176\u4ed6\u4f4d\u7f6e i \u5904\u8981\u8fdb\u884c\u63d2\u5165\uff0c\u63d2\u5165\u64cd\u4f5c\u5fc5\u987b\u8981\u5148\u627e\u5230\u4f4d\u7f6e i-1 \uff08\u5982\u679c i=n \uff09\u5904\u7684\u8282\u70b9\u3002\u8fd9\u6837\uff0c\u5c31\u6709\u4e24\u79cd\u60c5\u51b5\u9700\u8981\u8003\u8651\u3002 \u8fd9\u4e2a\u8282\u70b9\u540e\u9762\u7684\u6307\u9488\u662f None \u3002\u8fd9\u610f\u5473\u7740 i>=n \uff0c\u56e0\u6b64\u5e94\u8be5\u628a\u65b0\u7684\u5143\u7d20\u653e\u5728\u94fe\u63a5\u7ed3\u6784\u7684\u672b\u5c3e\u3002 \u8fd9\u4e2a\u8282\u70b9\u540e\u9762\u7684\u6307\u9488\u4e0d\u662fNone\u3002\u8fd9\u610f\u5473\u7740 0=n \u2014\u2014\u5220\u9664\u6700\u540e\u4e00\u4e2a\u8282\u70b9\u3002 \u5047\u8bbe\u5728\u94fe\u63a5\u7ed3\u6784\u91cc\u81f3\u5c11\u6709\u4e00\u4e2a\u8282\u70b9\u3002\u8fd9\u4e2a\u64cd\u4f5c\u7684\u6a21\u5f0f\u548c\u63d2\u5165\u64cd\u4f5c\u7684\u6a21\u5f0f\u662f\u7c7b\u4f3c\u7684\uff0c\u56e0\u6b64\u4e5f\u8981\u907f\u514d\u5728\u641c\u7d22\u8fc7\u7a0b\u4e2d\u8d85\u51fa\u94fe\u63a5\u7ed3\u6784\u7684\u672b\u5c3e\u3002\u4f46\u662f\u5728\u8fd9\u4e2a\u8fc7\u7a0b\u4e2d\uff0c\u4f60\u5fc5\u987b\u5141\u8bb8probe\u6307\u9488\u53ef\u4ee5\u8bbf\u95ee\u5230\u94fe\u63a5\u7ed3\u6784\u7684\u5012\u6570\u7b2c\u4e8c\u4e2a\u8282\u70b9\u3002 4.5.10.\u590d\u6742\u5ea6\u7684\u6743\u8861\uff1a\u65f6\u95f4\u3001\u7a7a\u95f4\u548c\u5355\u5411\u94fe\u63a5\u7ed3\u6784 \u00b6 \u5355\u5411\u94fe\u63a5\u7ed3\u6784\u5404\u9879\u64cd\u4f5c\u7684\u8fd0\u884c\u65f6\u590d\u6742\u5ea6 \u64cd\u4f5c \u8fd0\u884c\u65f6\u590d\u6742\u5ea6 \u5728\u4f4d\u7f6ei\u5904\u8bbf\u95ee O(n)\uff0c\uff0c\u5e73\u5747\u60c5\u51b5\u4e0b \u5728\u4f4d\u7f6ei\u5904\u66ff\u6362 O(n)\uff0c\u6700\u597d\u548c\u6700\u574f\u60c5\u51b5\u4e0b \u5728\u5f00\u59cb\u5904\u63d2\u5165 O(1)\uff0c\u6700\u597d\u548c\u6700\u574f\u60c5\u51b5\u4e0b \u5728\u5f00\u59cb\u5904\u5220\u9664 O(1)\uff0c\u6700\u597d\u548c\u6700\u574f\u60c5\u51b5\u4e0b \u5728\u4f4d\u7f6ei\u5904\u63d2\u5165 O(n)\uff0c\u5e73\u5747\u60c5\u51b5\u4e0b \u5728\u4f4d\u7f6ei\u5904\u5220\u9664 O(n)\uff0c\u5e73\u5747\u60c5\u51b5\u4e0b \u4e0e\u6570\u7ec4\u76f8\u6bd4\uff0c\u5355\u5411\u94fe\u63a5\u7ed3\u6784\u7684\u4e3b\u8981\u4f18\u52bf\u5e76\u4e0d\u5728\u4e8e\u65f6\u95f4\u590d\u6742\u5ea6\u800c\u5728\u4e8e\u5185\u5b58\u6027\u80fd\u3002 \u8c03\u6574\u6570\u7ec4\u5c3a\u5bf8\uff08\u5728\u9700\u8981\u7684\u65f6\u5019\u6267\u884c\uff09\uff0c\u4f7f\u5176\u5728\u65f6\u95f4\u548c\u5185\u5b58\u4e0a\u90fd\u662f\u7ebf\u6027\u7684\uff1b\u8c03\u6574\u94fe\u63a5\u7ed3\u6784\u7684\u5927\u5c0f\uff08\u4f1a\u5728\u63d2\u5165\u6216\u5220\u9664\u65f6\u53d1\u751f\uff09\u5728\u65f6\u95f4\u548c\u5185\u5b58\u4e0a\u90fd\u662f\u5e38\u6570\u590d\u6742\u5ea6\u3002 \u5728\u94fe\u63a5\u7ed3\u6784\u91cc\uff0c\u4e0d\u4f1a\u6709\u5185\u5b58\u7684\u6d6a\u8d39\uff0c\u56e0\u4e3a\u8fd9\u4e2a\u7ed3\u6784\u7684\u7269\u7406\u5c3a\u5bf8\u6c38\u8fdc\u90fd\u4e0d\u4f1a\u8d85\u8fc7\u903b\u8f91\u5c3a\u5bf8\u3002 \u94fe\u63a5\u7ed3\u6784\u7684\u786e\u4f1a\u4ea7\u751f\u4e00\u4e9b\u989d\u5916\u7684\u5185\u5b58\u5f00\u9500\uff0c\u8fd9\u662f\u56e0\u4e3a\u5355\u5411\u94fe\u63a5\u7ed3\u6784\u5fc5\u987b\u8981\u6709\u989d\u5916\u7684 n \u4e2a\u5185\u5b58\u5355\u5143\u6765\u5b58\u50a8\u6307\u9488\u3002 \u5bf9\u4e8e\u53cc\u5411\u94fe\u63a5\u7ed3\u6784\u6765\u8bf4\uff0c\u5b83\u7684\u8282\u70b9\u91cc\u5305\u542b\u4e24\u4e2a\u94fe\u63a5\uff0c\u56e0\u6b64\u5185\u5b58\u7684\u6210\u672c\u4f1a\u66f4\u9ad8\u4e00\u4e9b\u3002 4.5.11.\u7ec3\u4e60\u9898 \u00b6 1\uff0e\u5047\u8bbe\u5df2\u7ecf\u627e\u5230\u4e86\u4ece\u5355\u5411\u94fe\u63a5\u7ed3\u6784\u91cc\u5220\u9664\u5143\u7d20\u7684\u4f4d\u7f6e\uff0c\u8bf7\u8bf4\u660e\u4ece\u8fd9\u4e2a\u65f6\u5019\u5f00\u59cb\u5b8c\u6210\u5220\u9664\u64cd\u4f5c\u7684\u8fd0\u884c\u65f6\u590d\u6742\u5ea6\u3002 \u89e3\u7b54\uff1a\u5982\u679c\u5df2\u7ecf\u627e\u5230\u4e86\u5355\u5411\u94fe\u8868\u4e2d\u8981\u5220\u9664\u5143\u7d20\u7684\u4f4d\u7f6e\uff0c\u5220\u9664\u64cd\u4f5c\u7684\u8fd0\u884c\u65f6\u590d\u6742\u5ea6\u53d6\u51b3\u4e8e\u5220\u9664\u64cd\u4f5c\u7684\u5177\u4f53\u5b9e\u73b0\u3002\u5728\u5355\u5411\u94fe\u8868\u4e2d\uff0c\u5220\u9664\u4e00\u4e2a\u8282\u70b9\u901a\u5e38\u9700\u8981\u627e\u5230\u5f85\u5220\u9664\u8282\u70b9\u7684\u524d\u9a71\u8282\u70b9\uff0c\u7136\u540e\u5c06\u524d\u9a71\u8282\u70b9\u7684 next \u6307\u9488\u6307\u5411\u5f85\u5220\u9664\u8282\u70b9\u7684\u4e0b\u4e00\u4e2a\u8282\u70b9\uff0c\u4ece\u800c\u5c06\u5f85\u5220\u9664\u8282\u70b9\u4ece\u94fe\u8868\u4e2d\u79fb\u9664\u3002 \u67e5\u627e\u5f85\u5220\u9664\u8282\u70b9\u7684\u65f6\u95f4\u590d\u6742\u5ea6\uff1a\u5728\u6700\u574f\u60c5\u51b5\u4e0b\uff0c\u5982\u679c\u8981\u5220\u9664\u7684\u8282\u70b9\u4f4d\u4e8e\u94fe\u8868\u7684\u672b\u5c3e\uff0c\u6216\u8005\u9700\u8981\u904d\u5386\u6574\u4e2a\u94fe\u8868\u624d\u80fd\u627e\u5230\u5f85\u5220\u9664\u8282\u70b9\uff0c\u67e5\u627e\u64cd\u4f5c\u7684\u65f6\u95f4\u590d\u6742\u5ea6\u4e3aO(n)\uff0c\u5176\u4e2dn\u662f\u94fe\u8868\u7684\u957f\u5ea6\u3002 \u5220\u9664\u8282\u70b9\u7684\u65f6\u95f4\u590d\u6742\u5ea6\uff1a\u5220\u9664\u8282\u70b9\u7684\u64cd\u4f5c\u662f\u5e38\u6570\u65f6\u95f4O(1)\uff0c\u56e0\u4e3a\u5b83\u6d89\u53ca\u7684\u64cd\u4f5c\u90fd\u662f\u57fa\u672c\u7684\u8d4b\u503c\u548c\u6307\u9488\u8c03\u6574\u3002 \u6240\u4ee5\uff0c\u5982\u679c\u5df2\u7ecf\u627e\u5230\u4e86\u5f85\u5220\u9664\u8282\u70b9\u7684\u4f4d\u7f6e\uff0c\u5220\u9664\u64cd\u4f5c\u7684\u8fd0\u884c\u65f6\u590d\u6742\u5ea6\u662fO(n)\u3002 2\uff0e\u53ef\u4ee5\u5bf9\u5355\u5411\u94fe\u63a5\u7ed3\u6784\u91cc\u6309\u987a\u5e8f\u6392\u5217\u7684\u5143\u7d20\u6267\u884c\u4e8c\u5206\u641c\u7d22\u5417\uff1f\u5982\u679c\u4e0d\u53ef\u4ee5\uff0c\u4e3a\u4ec0\u4e48\uff1f \u89e3\u7b54\uff1a\u5728\u666e\u901a\u7684\u5355\u5411\u94fe\u8868\u4e2d\uff0c\u65e0\u6cd5\u76f4\u63a5\u6267\u884c\u4e8c\u5206\u641c\u7d22\u3002\u4e8c\u5206\u641c\u7d22\u901a\u5e38\u57fa\u4e8e\u6570\u7ec4\u8fd9\u79cd\u8fde\u7eed\u5b58\u50a8\u7ed3\u6784\uff0c\u53ef\u4ee5\u76f4\u63a5\u901a\u8fc7\u7d22\u5f15\u8fdb\u884c\u5feb\u901f\u8bbf\u95ee\u3002\u4f46\u5728\u5355\u5411\u94fe\u8868\u4e2d\uff0c\u8981\u67e5\u627e\u4e2d\u95f4\u5143\u7d20\uff0c\u9700\u8981\u904d\u5386\u94fe\u8868\u4ee5\u627e\u5230\u4e2d\u95f4\u4f4d\u7f6e\u3002\u56e0\u4e3a\u94fe\u8868\u7684\u5143\u7d20\u4e0d\u662f\u6309\u7167\u7d22\u5f15\u6392\u5217\u7684\uff0c\u6240\u4ee5\u4e0d\u80fd\u76f4\u63a5\u8fdb\u884c\u4e8c\u5206\u641c\u7d22\u3002 \u5982\u679c\u5e0c\u671b\u5728\u6709\u5e8f\u94fe\u8868\u4e2d\u6267\u884c\u4e8c\u5206\u641c\u7d22\uff0c\u53ef\u4ee5\u8003\u8651\u4f7f\u7528\u53e6\u4e00\u79cd\u6570\u636e\u7ed3\u6784\u2014\u2014\u4e8c\u53c9\u641c\u7d22\u6811\uff08Binary Search Tree\uff09\u3002\u5728\u4e8c\u53c9\u641c\u7d22\u6811\u4e2d\uff0c\u6bcf\u4e2a\u8282\u70b9\u7684\u5de6\u5b50\u6811\u7684\u503c\u5c0f\u4e8e\u8be5\u8282\u70b9\u7684\u503c\uff0c\u53f3\u5b50\u6811\u7684\u503c\u5927\u4e8e\u8be5\u8282\u70b9\u7684\u503c\uff0c\u56e0\u6b64\u53ef\u4ee5\u5229\u7528\u8fd9\u79cd\u6709\u5e8f\u6027\u8fdb\u884c\u5feb\u901f\u641c\u7d22\u3002 3\uff0e\u8bf7\u8bf4\u660e\u4e3a\u4ec0\u4e48Python\u5217\u8868\u4f1a\u4f7f\u7528\u6570\u7ec4\u800c\u4e0d\u662f\u94fe\u63a5\u7ed3\u6784\u6765\u4fdd\u5b58\u5b83\u7684\u5143\u7d20\u3002 \u89e3\u7b54\uff1aPython\u7684\u5217\u8868\u4f7f\u7528\u6570\u7ec4\u800c\u4e0d\u662f\u94fe\u63a5\u7ed3\u6784\u6765\u4fdd\u5b58\u5143\u7d20\uff0c\u4e3b\u8981\u662f\u56e0\u4e3a\u6570\u7ec4\u5728\u968f\u673a\u8bbf\u95ee\uff08\u6839\u636e\u7d22\u5f15\u76f4\u63a5\u8bbf\u95ee\u5143\u7d20\uff09\u548c\u5207\u7247\uff08\u901a\u8fc7[start:stop:step]\u65b9\u5f0f\u622a\u53d6\u5b50\u5217\u8868\uff09\u64cd\u4f5c\u4e0a\u5177\u6709\u66f4\u597d\u7684\u6027\u80fd\u3002\u6570\u7ec4\u7684\u5185\u5b58\u7a7a\u95f4\u662f\u8fde\u7eed\u7684\uff0c\u56e0\u6b64\u53ef\u4ee5\u901a\u8fc7\u7d22\u5f15\u8fc5\u901f\u8ba1\u7b97\u51fa\u5143\u7d20\u7684\u5185\u5b58\u5730\u5740\u3002\u8fd9\u4f7f\u5f97\u968f\u673a\u8bbf\u95ee\u548c\u5207\u7247\u7684\u65f6\u95f4\u590d\u6742\u5ea6\u662fO(1)\uff0c\u5373\u5e38\u6570\u65f6\u95f4\u3002\u800c\u94fe\u63a5\u7ed3\u6784\u5728\u968f\u673a\u8bbf\u95ee\u4e0a\u7684\u65f6\u95f4\u590d\u6742\u5ea6\u901a\u5e38\u662fO(n)\uff0c\u5176\u4e2dn\u662f\u94fe\u8868\u7684\u957f\u5ea6\uff0c\u56e0\u4e3a\u9700\u8981\u4ece\u5934\u8282\u70b9\u5f00\u59cb\u9010\u4e2a\u904d\u5386\u627e\u5230\u76ee\u6807\u8282\u70b9\u3002 \u5728Python\u7684\u5217\u8868\u4e2d\uff0c\u652f\u6301\u901a\u8fc7\u7d22\u5f15\u968f\u673a\u8bbf\u95ee\u5143\u7d20\uff0c\u8fd9\u662f\u56e0\u4e3a\u5217\u8868\u7684\u5143\u7d20\u662f\u4fdd\u5b58\u5728\u4e00\u4e2a\u8fde\u7eed\u7684\u5185\u5b58\u5757\u4e2d\u7684\u3002\u8fd9\u79cd\u8bbe\u8ba1\u4f7f\u5f97Python\u7684\u5217\u8868\u5728\u5927\u591a\u6570\u5e38\u89c1\u64cd\u4f5c\uff08\u4f8b\u5982\u67e5\u627e\u3001\u63d2\u5165\u3001\u5220\u9664\uff09\u4e0a\u90fd\u80fd\u63d0\u4f9b\u8f83\u597d\u7684\u6027\u80fd\uff0c\u7279\u522b\u662f\u5f53\u9700\u8981\u901a\u8fc7\u7d22\u5f15\u6216\u5207\u7247\u5feb\u901f\u8bbf\u95ee\u6216\u4fee\u6539\u5143\u7d20\u65f6\u3002\u7136\u800c\uff0c\u5bf9\u4e8e\u5728\u4e2d\u95f4\u63d2\u5165\u6216\u5220\u9664\u5143\u7d20\u8fd9\u6837\u7684\u64cd\u4f5c\uff0c\u5217\u8868\u7684\u6027\u80fd\u53ef\u80fd\u76f8\u5bf9\u8f83\u4f4e\uff0c\u56e0\u4e3a\u5728\u6570\u7ec4\u4e2d\u95f4\u63d2\u5165\u6216\u5220\u9664\u5143\u7d20\u901a\u5e38\u9700\u8981\u79fb\u52a8\u5176\u4ed6\u5143\u7d20\uff0c\u5bfc\u81f4\u65f6\u95f4\u590d\u6742\u5ea6\u4e3aO(n)\u3002 \u603b\u7684\u6765\u8bf4\uff0cPython\u7684\u5217\u8868\u91c7\u7528\u6570\u7ec4\u5b58\u50a8\u5143\u7d20\uff0c\u662f\u4e3a\u4e86\u5728\u5927\u591a\u6570\u5e38\u89c1\u64cd\u4f5c\u4e2d\u63d0\u4f9b\u8f83\u597d\u7684\u6027\u80fd\u3002\u5982\u679c\u9700\u8981\u5728\u4e2d\u95f4\u63d2\u5165\u6216\u5220\u9664\u5143\u7d20\u7684\u64cd\u4f5c\u6bd4\u8f83\u9891\u7e41\uff0c\u53ef\u80fd\u9700\u8981\u8003\u8651\u4f7f\u7528\u94fe\u8868\u7b49\u6570\u636e\u7ed3\u6784\u3002Python\u4e2d\u7684 collections \u6a21\u5757\u63d0\u4f9b\u4e86 deque \uff08\u53cc\u7aef\u961f\u5217\uff09\u7b49\u6570\u636e\u7ed3\u6784\uff0c\u53ef\u4ee5\u7528\u4e8e\u5728\u4e24\u7aef\u9ad8\u6548\u5730\u8fdb\u884c\u63d2\u5165\u548c\u5220\u9664\u64cd\u4f5c\u3002 \u8865\u5145\uff1a \u67e5\u770b\u6e90\u4ee3\u7801\u7684\u65b9\u6cd5\u3002 import array import inspect # \u83b7\u53d6array\u6a21\u5757\u7684\u6e90\u4ee3\u7801 source_code = inspect . getsource ( array ) # \u6253\u5370\u6e90\u4ee3\u7801 print ( source_code ) \u5bf9\u4e8e\u5185\u7f6e\u7684\u6a21\u5757\uff0c\u4e0d\u80fd\u76f4\u63a5\u901a\u8fc7inspect\u6a21\u5757\u67e5\u770b\u6e90\u4ee3\u7801\u3002\u53ef\u4ee5\u901a\u8fc7\u5728\u7ebf\u67e5\u770bPython\u7684\u6e90\u4ee3\u7801\u3002Python\u7684\u6e90\u4ee3\u7801\u6258\u7ba1\u5728GitHub\u4e0a\uff0c\u4f60\u53ef\u4ee5\u5728\u4ee5\u4e0b\u94fe\u63a5\u4e2d\u627e\u5230Python\u7684\u6e90\u4ee3\u7801\uff1a Python GitHub Repository \uff0c\u5305\u62ec array\u7684\u6e90\u4ee3\u7801 \u3002 4.6.\u94fe\u63a5\u4e0a\u7684\u53d8\u5316 \u00b6 4.6.1.\u5305\u542b\u865a\u62df\u5934\u8282\u70b9\u7684\u73af\u72b6\u94fe\u63a5\u7ed3\u6784 \u00b6 \u5728\u7b2c\u4e00\u4e2a\u8282\u70b9\u4f4d\u7f6e\u5904\u6267\u884c\u63d2\u5165\u548c\u5220\u9664\u64cd\u4f5c\u662f\u5355\u5411\u94fe\u63a5\u7ed3\u6784\u91cc\u5728\u4efb\u610f\u4f4d\u7f6e\u8fdb\u884c\u63d2\u5165\u548c\u5220\u9664\u64cd\u4f5c\u7684\u7279\u6b8a\u60c5\u51b5\uff0c\u662f\u56e0\u4e3a\u8fd9\u4e2a\u65f6\u5019\u5fc5\u987b\u91cd\u7f6ehead\u6307\u9488\u3002 \u53ef\u4ee5\u901a\u8fc7\u5305\u542b\u865a\u62df\u5934\u8282\u70b9\uff08dummy header node\uff09\u7684\u73af\u72b6\u94fe\u63a5\u7ed3\u6784\uff08circular linked structure\uff09\u7b80\u5316\u8fd9\u4e24\u4e2a\u64cd\u4f5c\u3002 \u73af\u72b6\u94fe\u63a5\u7ed3\u6784\u5305\u542b\u4e86\u4ece\u6700\u540e\u4e00\u4e2a\u8282\u70b9\u5230\u7b2c\u4e00\u4e2a\u8282\u70b9\u7684\u94fe\u63a5\uff0c\u5e76\u4e14\u5b83\u7684\u5b9e\u73b0\u91cc\u81f3\u5c11\u4f1a\u5305\u542b\u4e00\u4e2a\u8282\u70b9\u3002\u8fd9\u4e2a\u8282\u70b9\uff08\u865a\u62df\u5934\u8282\u70b9\uff09\u4e0d\u5305\u542b\u4efb\u4f55\u6570\u636e\uff0c\u4f46\u4f1a\u88ab\u7528\u6765\u4f5c\u4e3a\u94fe\u63a5\u7ed3\u6784\u7684\u5f00\u59cb\u548c\u7ed3\u675f\u7684\u6807\u8bb0\u3002\u5728\u6700\u521d\u7684\u7a7a\u94fe\u63a5\u7ed3\u6784\u91cc\uff0chead\u53d8\u91cf\u4f1a\u6307\u5411\u865a\u62df\u5934\u8282\u70b9\uff0c\u800c\u865a\u62df\u5934\u8282\u70b9\u7684\u4e0b\u4e00\u4e2a\u6307\u9488\u4f1a\u6307\u5411\u865a\u62df\u5934\u8282\u70b9\u672c\u8eab\u3002\u5982\u4e0b\u56fe\u6240\u793a\u3002 4.6.2.\u53cc\u5411\u94fe\u63a5\u7ed3\u6784 \u00b6 4.6.3.\u7ec3\u4e60\u9898 \u00b6 1\uff0e\u5305\u542b\u865a\u62df\u5934\u8282\u70b9\u7684\u73af\u72b6\u94fe\u63a5\u7ed3\u6784\u7ed9\u7a0b\u5e8f\u5458\u5e26\u6765\u4e86\u4ec0\u4e48\u597d\u5904\uff1f 2\uff0e\u548c\u5355\u5411\u94fe\u63a5\u7ed3\u6784\u76f8\u6bd4\uff0c\u8bf7\u63cf\u8ff0\u53cc\u5411\u94fe\u63a5\u7ed3\u6784\u7684\u4e00\u4e2a\u597d\u5904\u548c\u4e00\u4e2a\u989d\u5916\u5f00\u9500\u3002 4.7.\u5c0f\u7ed3 \u00b6 \u6570\u636e\u7ed3\u6784\u662f\u4e00\u4e2a\u8868\u793a\u591a\u9879\u96c6\u91cc\u6240\u5305\u542b\u6570\u636e\u7684\u5bf9\u8c61\u3002 \u6570\u7ec4\u662f\u4e00\u79cd\u5728\u5e38\u6570\u65f6\u95f4\u5185\u652f\u6301\u5bf9\u4f4d\u7f6e\u9010\u9879\u968f\u673a\u8bbf\u95ee\u7684\u6570\u636e\u7ed3\u6784\u3002\u5728\u521b\u5efa\u6570\u7ec4\u65f6\uff0c\u4f1a\u4e3a\u5b83\u5206\u914d\u82e5\u5e72\u4e2a\u7528\u6765\u5b58\u653e\u6570\u636e\u7684\u5185\u5b58\u7a7a\u95f4\uff0c\u5e76\u4e14\u6570\u7ec4\u7684\u957f\u5ea6\u4f1a\u4fdd\u6301\u4e0d\u53d8\u3002\u63d2\u5165\u548c\u5220\u9664\u64cd\u4f5c\u9700\u8981\u79fb\u52a8\u6570\u636e\u5143\u7d20\uff0c\u5e76\u4e14\u53ef\u80fd\u9700\u8981\u521b\u5efa\u4e00\u4e2a\u65b0\u7684\u3001\u66f4\u5927\u6216\u66f4\u5c0f\u7684\u6570\u7ec4\u3002 \u4e8c\u7ef4\u6570\u7ec4\u91cc\u7684\u6bcf\u4e2a\u6570\u636e\u503c\u90fd\u4f4d\u4e8e\u77e9\u5f62\u7f51\u683c\u7684\u884c\u548c\u5217\u4e0a\u3002 \u94fe\u63a5\u7ed3\u6784\u662f\u75310\u4e2a\u6216\u591a\u4e2a\u8282\u70b9\u7ec4\u6210\u7684\u6570\u636e\u7ed3\u6784\u3002\u6bcf\u4e2a\u8282\u70b9\u90fd\u5305\u542b\u4e00\u4e2a\u6570\u636e\u5143\u7d20\u548c\u4e00\u4e2a\u6216\u591a\u4e2a\u6307\u5411\u5176\u4ed6\u8282\u70b9\u7684\u94fe\u63a5\u3002 \u5355\u5411\u94fe\u63a5\u7ed3\u6784\u7684\u8282\u70b9\u5305\u542b\u6570\u636e\u5143\u7d20\u548c\u5230\u4e0b\u4e00\u4e2a\u8282\u70b9\u7684\u94fe\u63a5\u3002\u53cc\u5411\u94fe\u63a5\u7ed3\u6784\u91cc\u7684\u8282\u70b9\u8fd8\u5305\u542b\u5230\u524d\u4e00\u4e2a\u8282\u70b9\u7684\u94fe\u63a5\u3002 \u5728\u94fe\u63a5\u7ed3\u6784\u91cc\u8fdb\u884c\u63d2\u5165\u6216\u5220\u9664\u64cd\u4f5c\u4e0d\u9700\u8981\u79fb\u52a8\u6570\u636e\u5143\u7d20\uff0c\u6bcf\u6b21\u6700\u591a\u53ea\u4f1a\u521b\u5efa\u4e00\u4e2a\u8282\u70b9\u3002\u4f46\u662f\uff0c\u5728\u94fe\u63a5\u7ed3\u6784\u91cc\u6267\u884c\u63d2\u5165\u3001\u5220\u9664\u548c\u8bbf\u95ee\u64cd\u4f5c\u9700\u8981\u7684\u65f6\u95f4\u590d\u6742\u5ea6\u90fd\u662f\u7ebf\u6027\u7684\u3002 \u5728\u94fe\u63a5\u7ed3\u6784\u91cc\u4f7f\u7528\u5934\u8282\u70b9\u53ef\u4ee5\u7b80\u5316\u67d0\u4e9b\u64cd\u4f5c\uff0c\u5982\u6dfb\u52a0\u6216\u5220\u9664\u5143\u7d20\u3002 4.8.\u590d\u4e60\u9898 \u00b6 1\uff0e\u6570\u7ec4\u548c\u94fe\u63a5\u7ed3\u6784\u90fd\u662f\uff1a \u62bd\u8c61\u6570\u636e\u7c7b\u578b\uff08ADT\uff09 \u6570\u636e\u7ed3\u6784 2\uff0e\u6570\u7ec4\u7684\u957f\u5ea6\uff1a \u5728\u521b\u5efa\u4e4b\u540e\u5927\u5c0f\u662f\u56fa\u5b9a\u7684 \u5728\u521b\u5efa\u4e4b\u540e\u5927\u5c0f\u53ef\u4ee5\u589e\u52a0\u6216\u51cf\u5c11 3\uff0e\u5728\u6570\u7ec4\u91cc\u8fdb\u884c\u968f\u673a\u8bbf\u95ee\u652f\u6301\u5728\uff1a \u5e38\u6570\u65f6\u95f4\u91cc\u8bbf\u95ee\u6570\u636e \u7ebf\u6027\u65f6\u95f4\u91cc\u8bbf\u95ee\u6570\u636e 4\uff0e\u5355\u5411\u94fe\u63a5\u7ed3\u6784\u91cc\u7684\u6570\u636e\u5305\u542b\u5728\uff1a \u5355\u5143\u91cc \u8282\u70b9\u91cc 5\uff0e\u5bf9\u5355\u5411\u94fe\u63a5\u7ed3\u6784\u6267\u884c\u7684\u5927\u591a\u6570\u64cd\u4f5c\u90fd\u9700\u8981\uff1a \u5e38\u6570\u65f6\u95f4 \u7ebf\u6027\u65f6\u95f4 6\uff0e\u4ece\u4ee5\u4e0b\u54ea\u79cd\u7c7b\u578b\u91cc\u5220\u9664\u7b2c\u4e00\u4e2a\u5143\u7d20\u9700\u8981\u5e38\u6570\u65f6\u95f4\uff1a \u6570\u7ec4 \u5355\u5411\u94fe\u63a5\u7ed3\u6784 7\uff0e\u5728\u4e0b\u9762\u54ea\u79cd\u60c5\u51b5\u4e0b\uff0c\u6570\u7ec4\u91cc\u4f7f\u7528\u7684\u5185\u5b58\u4f1a\u5c11\u4e8e\u5355\u5411\u94fe\u63a5\u7ed3\u6784\u7684\uff1a \u4e0d\u5230\u4e00\u534a\u7684\u4f4d\u7f6e\u653e\u7f6e\u4e86\u6570\u636e \u4e00\u534a\u4ee5\u4e0a\u7684\u4f4d\u7f6e\u653e\u7f6e\u4e86\u6570\u636e 8\uff0e\u5f53\u6570\u7ec4\u7684\u5185\u5b58\u4e0d\u8db3\u4ee5\u4fdd\u5b58\u6570\u636e\u65f6\uff0c\u6700\u597d\u521b\u5efa\u4e00\u4e2a\u65b0\u7684\u6570\u7ec4\uff0c\u8fd9\u4e2a\u65b0\u6570\u7ec4\u5e94\u8be5\uff1a \u5927\u5c0f\u6bd4\u65e7\u6570\u7ec4\u591a1\u4e2a\u4f4d\u7f6e \u5927\u5c0f\u662f\u65e7\u6570\u7ec4\u76842\u500d 9\uff0e\u5bf9\u4e8e\u5355\u5411\u94fe\u63a5\u7ed3\u6784\uff0c\u5f53\u4f60\u5728\u4ec0\u4e48\u5730\u65b9\u6267\u884c\u63d2\u5165\u64cd\u4f5c\u4f1a\u5f97\u5230\u6700\u574f\u60c5\u51b5\u4e0b\u7684\u8fd0\u884c\u65f6\uff1a \u5728\u7ed3\u6784\u7684\u5f00\u5934 \u5728\u7ed3\u6784\u7684\u672b\u5c3e 10\uff0e\u53cc\u5411\u94fe\u63a5\u7ed3\u6784\u8ba9\u7a0b\u5e8f\u5458\u53ef\u4ee5\u79fb\u52a8\u5230\uff1a \u7ed9\u5b9a\u8282\u70b9\u7684\u540e\u4e00\u4e2a\u8282\u70b9\u6216\u524d\u4e00\u4e2a\u8282\u70b9 \u7ed9\u5b9a\u8282\u70b9\u7684\u540e\u4e00\u4e2a\u8282\u70b9 4.9.\u7f16\u7a0b\u7ec3\u4e60 \u00b6 \u5728\u524d6\u4e2a\u9879\u76ee\u91cc\uff0c\u4f60\u5c06\u4fee\u6539\u5728\u672c\u7ae0\u5b9a\u4e49\u7684Array\u7c7b\uff0c\u4ece\u800c\u8ba9\u5b83\u66f4\u50cfPython\u7684list\u7c7b\u3002\u5bf9\u4e8e\u8fd9\u4e9b\u9879\u76ee\u7684\u7b54\u6848\uff0c\u8bf7\u5305\u542b\u4f60\u5bf9Array\u7c7b\u6240\u505a\u4fee\u6539\u7684\u4ee3\u7801\u6d4b\u8bd5\u3002 1\uff0e\u4e3aArray\u7c7b\u6dfb\u52a0\u4e00\u4e2a\u5b9e\u4f8b\u53d8\u91cf logicalSize \u3002\u8fd9\u4e2a\u53d8\u91cf\u7684\u521d\u59cb\u503c\u4e3a 0 \uff0c\u7528\u6765\u8bb0\u5f55\u6570\u7ec4\u91cc\u5f53\u524d\u5df2\u7ecf\u5305\u542b\u7684\u5143\u7d20\u6570\u91cf\u3002\u7136\u540e\u4e3aArray\u7c7b\u6dfb\u52a0 size() \u65b9\u6cd5\uff0c\u8fd9\u4e2a\u65b9\u6cd5\u7528\u6765\u8fd4\u56de\u6570\u7ec4\u7684\u903b\u8f91\u5c3a\u5bf8\u3002 __len__ \u65b9\u6cd5\u4f9d\u7136\u4f1a\u8fd4\u56de\u6570\u7ec4\u7684\u5bb9\u91cf\uff0c\u4e5f\u5c31\u662f\u5b83\u7684\u7269\u7406\u5c3a\u5bf8\u3002 2\uff0e\u4e3aArray\u7c7b\u7684 __getitem__ \u548c_ _setitem__ \u65b9\u6cd5\u6dfb\u52a0\u5148\u9a8c\u6761\u4ef6\u3002\u5b83\u4eec\u7684\u5148\u9a8c\u6761\u4ef6\u662f 0<=index < size() \u3002\u5982\u679c\u4e0d\u6ee1\u8db3\u5148\u9a8c\u6761\u4ef6\uff0c\u5c31\u5f15\u53d1\u5f02\u5e38\u3002 3\uff0e\u5c06 grow \u548c shrink \u65b9\u6cd5\u6dfb\u52a0\u5230Array\u7c7b\u3002\u5b83\u4eec\u80fd\u591f\u57fa\u4e8e\u672c\u7ae0\u6240\u8ba8\u8bba\u7684\u7b56\u7565\u6765\u589e\u52a0\u6216\u51cf\u5c11\u6570\u7ec4\u91cc\u6240\u5305\u542b\u7684\u5217\u8868\u957f\u5ea6\u3002\u5728\u5b9e\u73b0\u65f6\uff0c\u8981\u4fdd\u8bc1\u6570\u7ec4\u7684\u7269\u7406\u5c3a\u5bf8\u4e0d\u4f1a\u7f29\u5c0f\u5230\u7528\u6237\u6307\u5b9a\u7684\u5bb9\u91cf\u4e4b\u4e0b\uff0c\u5e76\u4e14\u5728\u589e\u52a0\u6570\u7ec4\u5c3a\u5bf8\u65f6\uff0c\u6570\u7ec4\u7684\u5185\u5b58\u5355\u5143\u5c06\u4f1a\u7528\u9ed8\u8ba4\u503c\u6765\u586b\u5145\u3002 4\uff0e\u5c06\u65b9\u6cd5 insert \u548c pop \u6dfb\u52a0\u5230Array\u7c7b\u4e2d\u3002\u5b83\u4eec\u57fa\u4e8e\u672c\u7ae0\u5df2\u7ecf\u8ba8\u8bba\u8fc7\u7684\u7b56\u7565\uff0c\u5728\u9700\u8981\u7684\u65f6\u5019\u5bf9\u6570\u7ec4\u7684\u957f\u5ea6\u8fdb\u884c\u8c03\u6574\u3002 insert \u65b9\u6cd5\u4f1a\u63a5\u6536\u4e00\u4e2a\u4f4d\u7f6e\u548c\u4e00\u4e2a\u5143\u7d20\u503c\u4f5c\u4e3a\u53c2\u6570\uff0c\u7136\u540e\u628a\u8fd9\u4e2a\u5143\u7d20\u63d2\u5165\u6307\u5b9a\u7684\u4f4d\u7f6e\u3002\u5982\u679c\u4f4d\u7f6e\u5927\u4e8e\u6216\u7b49\u4e8e\u6570\u7ec4\u7684\u903b\u8f91\u5c3a\u5bf8\uff0c\u90a3\u4e48\u8fd9\u4e2a\u65b9\u6cd5\u4f1a\u628a\u5143\u7d20\u63d2\u5165\u6570\u7ec4\u91cc\u5f53\u524d\u53ef\u83b7\u5f97\u7684\u6700\u540e\u4e00\u4e2a\u5143\u7d20\u4e4b\u540e\u3002 pop \u65b9\u6cd5\u4f1a\u63a5\u6536\u4e00\u4e2a\u4f4d\u7f6e\u4f5c\u4e3a\u53c2\u6570\uff0c\u7136\u540e\u5220\u9664\u5e76\u8fd4\u56de\u8fd9\u4e2a\u4f4d\u7f6e\u7684\u5143\u7d20\u3002 pop \u65b9\u6cd5\u7684\u5148\u9a8c\u6761\u4ef6\u662f 0<=index < size() \u3002 pop \u65b9\u6cd5\u8fd8\u5e94\u8be5\u628a\u817e\u51fa\u6765\u7684\u6570\u7ec4\u5185\u5b58\u5355\u5143\u91cd\u7f6e\u4e3a\u586b\u5145\u503c\u3002 5\uff0e\u5c06\u65b9\u6cd5 __eq__ \u6dfb\u52a0\u5230Array\u7c7b\u4e2d\u3002\u5f53Array\u5bf9\u8c61\u4f5c\u4e3a == \u8fd0\u7b97\u7b26\u7684\u5de6\u64cd\u4f5c\u6570\u65f6\uff0cPython\u4f1a\u8fd0\u884c\u8fd9\u4e2a\u65b9\u6cd5\u3002\u5982\u679c\u8fd9\u4e2a\u65b9\u6cd5\u7684\u53c2\u6570\u4e5f\u662f\u4e00\u4e2aArray\u5bf9\u8c61\uff0c\u5e76\u4e14\u5b83\u7684\u903b\u8f91\u5c3a\u5bf8\u548c\u5de6\u64cd\u4f5c\u6570\u76f8\u540c\uff0c\u4e14\u5728\u4e24\u4e2a\u6570\u7ec4\u91cc\u6bcf\u4e2a\u903b\u8f91\u4f4d\u7f6e\u4e0a\u7684\u5143\u7d20\u90fd\u76f8\u7b49\uff0c\u90a3\u4e48\u8fd9\u4e2a\u65b9\u6cd5\u4f1a\u8fd4\u56de True \uff1b\u5426\u5219\uff0c\u8fd9\u4e2a\u65b9\u6cd5\u8fd4\u56de False \u3002 6\uff0e\u4e3a\u4e86\u8ba9Array\u7c7b\u548c\u5217\u8868\u4e00\u6837\uff0c\u5e94\u8be5\u5220\u9664 __iter__ \u65b9\u6cd5\u7684\u5f53\u524d\u5b9e\u73b0\u3002\u8bf7\u89e3\u91ca\u8fd9\u4e3a\u4ec0\u4e48\u662f\u4e00\u4e2a\u597d\u5efa\u8bae\uff0c\u5e76\u8bf4\u660e\u5728\u8fd9\u4e2a\u60c5\u51b5\u4e0b\u5e94\u8be5\u5982\u4f55\u5bf9 __str__ \u65b9\u6cd5\u8fdb\u884c\u4fee\u6539\u3002 7\uff0e Matrix \u7c7b\u53ef\u4ee5\u6267\u884c\u7ebf\u6027\u4ee3\u6570\u91cc\u7684\u67d0\u4e9b\u8fd0\u7b97\uff0c\u6bd4\u5982\u77e9\u9635\u8fd0\u7b97\u3002\u5f00\u53d1\u4e00\u4e2a\u4f7f\u7528\u5185\u7f6e\u8fd0\u7b97\u7b26\u8fdb\u884c\u7b97\u672f\u8fd0\u7b97\u7684 Matrix \u7c7b\uff0c\u8fd9\u4e2a Matrix \u7c7b\u5e94\u6269\u5c55\u81ea Grid \u7c7b\u3002\u5728\u63a5\u4e0b\u6765\u76844\u4e2a\u9879\u76ee\u91cc\uff0c\u4f60\u5e94\u5b9a\u4e49\u4e00\u4e9b\u7528\u6765\u64cd\u4f5c\u94fe\u63a5\u7ed3\u6784\u7684\u51fd\u6570\u3002\u5728\u89e3\u7b54\u7684\u8fc7\u7a0b\u4e2d\uff0c\u4f60\u5e94\u8be5\u7ee7\u7eed\u4f7f\u7528\u672c\u7ae0\u5b9a\u4e49\u7684 Node \u548c TwoWayNode \u7c7b\u3002\u521b\u5efa\u4e00\u4e2a\u6d4b\u8bd5\u6a21\u5757\u4ee5\u5305\u542b\u4f60\u7684\u51fd\u6570\u5b9a\u4e49\u548c\u7528\u6765\u6d4b\u8bd5\u5b83\u4eec\u7684\u4ee3\u7801\u3002 8\uff0e\u5b9a\u4e49\u4e00\u4e2a\u53eb\u4f5c length \u7684\u51fd\u6570\uff08\u4e0d\u662f len \uff09\uff0c\u8fd9\u4e2a\u51fd\u6570\u4f1a\u63a5\u53d7\u4e00\u4e2a\u5355\u5411\u94fe\u63a5\u7ed3\u6784\u4f5c\u4e3a\u53c2\u6570\uff0c\u5e76\u80fd\u591f\u8fd4\u56de\u7ed3\u6784\u91cc\u7684\u5143\u7d20\u6570\u91cf\u3002 9\uff0e\u5b9a\u4e49\u4e00\u4e2a\u53eb\u4f5c insert \u7684\u51fd\u6570\uff0c\u8fd9\u4e2a\u51fd\u6570\u5177\u6709\u628a\u5143\u7d20\u63d2\u5165\u5355\u5411\u94fe\u63a5\u7ed3\u6784\u4e2d\u6307\u5b9a\u4f4d\u7f6e\u7684\u529f\u80fd\u3002\u8fd9\u4e2a\u51fd\u6570\u67093\u4e2a\u53c2\u6570\uff1a\u5143\u7d20\u3001\u4f4d\u7f6e\u4ee5\u53ca\u4e00\u4e2a\u94fe\u63a5\u7ed3\u6784\uff08\u8fd9\u4e2a\u94fe\u63a5\u7ed3\u6784\u53ef\u80fd\u4e3a\u7a7a\uff09\u3002\u8fd9\u4e2a\u51fd\u6570\u80fd\u591f\u8fd4\u56de\u4fee\u6539\u4e4b\u540e\u7684\u94fe\u63a5\u7ed3\u6784\u3002\u5982\u679c\u4f20\u9012\u7684\u4f4d\u7f6e\u5927\u4e8e\u6216\u7b49\u4e8e\u94fe\u63a5\u7ed3\u6784\u7684\u957f\u5ea6\uff0c\u90a3\u4e48\u8fd9\u4e2a\u51fd\u6570\u4f1a\u628a\u5143\u7d20\u63d2\u5165\u5b83\u7684\u672b\u5c3e\u3002\u8fd9\u4e2a\u51fd\u6570\u7684\u8c03\u7528\u793a\u4f8b\u662f head =insert(1,data,head) \uff0c\u5176\u4e2d head \u662f\u4e00\u4e2a\u53d8\u91cf\uff0c\u8fd9\u4e2a\u53d8\u91cf\u8981\u4e48\u4e3a\u7a7a\u94fe\u63a5\uff0c\u8981\u4e48\u6307\u5411\u94fe\u63a5\u7ed3\u6784\u7684\u7b2c\u4e00\u4e2a\u8282\u70b9\u3002 10\uff0e\u5b9a\u4e49\u4e00\u4e2a\u53eb\u4f5c pop \u7684\u51fd\u6570\uff0c\u8fd9\u4e2a\u51fd\u6570\u80fd\u591f\u5728\u5355\u5411\u94fe\u63a5\u7ed3\u6784\u7684\u6307\u5b9a\u4f4d\u7f6e\u4e0a\u5220\u9664\u5143\u7d20\u3002\u8fd9\u4e2a\u51fd\u6570\u7684\u7b2c\u4e00\u4e2a\u53c2\u6570\u662f\u4f4d\u7f6e\uff0c\u5b83\u7684\u5148\u9a8c\u6761\u4ef6\u662f 0<=position<\u7ed3\u6784\u7684\u957f\u5ea6 \u3002\u5b83\u7684\u7b2c\u4e8c\u4e2a\u53c2\u6570\u662f\u4e00\u4e2a\u94fe\u63a5\u7ed3\u6784\uff0c\u5f88\u660e\u663e\u5b83\u4e0d\u5e94\u8be5\u4e3a\u7a7a\u3002\u8fd9\u4e2a\u51fd\u6570\u5c06\u4f1a\u8fd4\u56de\u4e00\u4e2a\u5143\u7ec4\uff0c\u5305\u542b\u4fee\u6539\u540e\u7684\u94fe\u63a5\u7ed3\u6784\u548c\u5220\u9664\u7684\u5143\u7d20\u3002\u5b83\u7684\u8c03\u7528\u793a\u4f8b\u662f (head, item) = pop(1,head) \u3002 11\uff0e\u5b9a\u4e49\u4e00\u4e2a\u51fd\u6570 makeTwoWay \uff0c\u8fd9\u4e2a\u51fd\u6570\u4f1a\u63a5\u53d7\u4e00\u4e2a\u5355\u5411\u94fe\u63a5\u7ed3\u6784\u4f5c\u4e3a\u53c2\u6570\uff0c\u7136\u540e\u751f\u6210\u5e76\u8fd4\u56de\u4e00\u4e2a\u5305\u542b\u5355\u5411\u94fe\u63a5\u7ed3\u6784\u91cc\u7684\u5143\u7d20\u7684\u53cc\u5411\u94fe\u63a5\u7ed3\u6784\u3002\uff08\u6ce8\u610f\uff1a\u8fd9\u4e2a\u51fd\u6570\u4e0d\u5e94\u8be5\u5bf9\u4f5c\u4e3a\u53c2\u6570\u7684\u94fe\u63a5\u7ed3\u6784\u8fdb\u884c\u4efb\u4f55\u4fee\u6539\u3002\uff09","title":"\u6570\u7ec4\u548c\u94fe\u63a5\u7ed3\u6784"},{"location":"python/DataStructure/04_ArrayChain/#4","text":"\u6570\u636e\u7ed3\u6784\uff08data structure\uff09\u6216\u5177\u4f53\u6570\u636e\u7c7b\u578b\uff08concrete data type\uff09\u662f\u6307\u4e00\u7ec4\u6570\u636e\u7684\u5185\u90e8\u5b58\u50a8\u65b9\u5f0f\u3002 \u6570\u7ec4\uff08array\uff09\u548c\u94fe\u63a5\u7ed3\u6784\uff08linked structure\uff09\u8fd9\u4e24\u79cd\u6570\u636e\u7ed3\u6784\u662f\u7f16\u7a0b\u8bed\u8a00\u91cc\u591a\u9879\u96c6\u6700\u5e38\u7528\u7684\u5b9e\u73b0\u3002 \u76ee\u6807\uff1a \u521b\u5efa\u6570\u7ec4\uff1b \u5bf9\u6570\u7ec4\u6267\u884c\u5404\u79cd\u64cd\u4f5c\uff1b \u786e\u5b9a\u6570\u7ec4\u76f8\u5173\u64cd\u4f5c\u7684\u8fd0\u884c\u65f6\u548c\u5185\u5b58\u7684\u4f7f\u7528\u60c5\u51b5\uff1b \u57fa\u4e8e\u6570\u7ec4\u5728\u8ba1\u7b97\u673a\u5185\u5b58\u91cc\u7684\u4e0d\u540c\u5b58\u50a8\u65b9\u5f0f\uff0c\u63cf\u8ff0\u6570\u7ec4\u76f8\u5173\u64cd\u4f5c\u7684\u6210\u672c\u548c\u6536\u76ca\uff1b \u4f7f\u7528\u5355\u5411\u94fe\u63a5\u8282\u70b9\u521b\u5efa\u94fe\u63a5\u7ed3\u6784\uff1b \u5bf9\u7531\u5355\u5411\u94fe\u63a5\u8282\u70b9\u6784\u6210\u7684\u94fe\u63a5\u7ed3\u6784\u6267\u884c\u5404\u79cd\u64cd\u4f5c\uff1b \u57fa\u4e8e\u94fe\u63a5\u7ed3\u6784\u5728\u8ba1\u7b97\u673a\u5185\u5b58\u91cc\u7684\u4e0d\u540c\u5b58\u50a8\u65b9\u5f0f\uff0c\u63cf\u8ff0\u5728\u94fe\u63a5\u7ed3\u6784\u4e0a\u6267\u884c\u76f8\u5173\u64cd\u4f5c\u7684\u6210\u672c\u548c\u6536\u76ca\uff1b \u6bd4\u8f83\u6570\u7ec4\u548c\u94fe\u63a5\u7ed3\u6784\u5728\u8fd0\u884c\u65f6\u548c\u5185\u5b58\u4f7f\u7528\u4e0a\u7684\u6743\u8861\uff1b","title":"4.\u6570\u7ec4\u548c\u94fe\u63a5\u7ed3\u6784"},{"location":"python/DataStructure/04_ArrayChain/#41","text":"\u5173\u4e8e\u6570\u7ec4\uff08array\uff09\uff1a \u6570\u7ec4\u662f\u6307\u5728\u7ed9\u5b9a\u7d22\u5f15\u4f4d\u7f6e\u53ef\u4ee5\u8bbf\u95ee\u548c\u66ff\u6362\u7684\u5143\u7d20\u5e8f\u5217\u3002 Python\u5217\u8868\u7684\u5e95\u5c42\u6570\u636e\u7ed3\u6784\u6b63\u662f\u4e00\u4e2a\u6570\u7ec4\u3002 Python\u4e2d\u6570\u7ec4\u7684\u9650\u5236\u8981\u6bd4\u5217\u8868\u66f4\u591a\u3002\u53ea\u80fd\u5728\u6307\u5b9a\u4f4d\u7f6e\u8bbf\u95ee\u548c\u66ff\u6362\u6570\u7ec4\u4e2d\u7684\u5143\u7d20\u3001\u68c0\u67e5\u6570\u7ec4\u7684\u957f\u5ea6\u3001\u83b7\u53d6\u5b83\u7684\u5b57\u7b26\u4e32\u8868\u8fbe\u5f0f\uff1b\u4e0d\u80fd\u57fa\u4e8e\u4f4d\u7f6e\u6dfb\u52a0\u6216\u5220\u9664\u5143\u7d20\uff1b\u6570\u7ec4\u7684\u957f\u5ea6\u4e5f\u5c31\u662f\u5b83\u7684\u5bb9\u91cf\uff0c\u5728\u521b\u5efa\u4e4b\u540e\u5c31\u662f\u56fa\u5b9a\u7684\u3002","title":"4.1.\u6570\u7ec4\u6570\u636e\u7ed3\u6784"},{"location":"python/DataStructure/04_ArrayChain/#411","text":"\u901a\u8fc7\u4e0b\u6807\u64cd\u4f5c\u6216\u7d22\u5f15\u64cd\u4f5c\u5b9e\u73b0\u5bf9\u6570\u7ec4\u5728\u6307\u5b9a\u4f4d\u7f6e\u5bf9\u5143\u7d20\u8fdb\u884c\u5b58\u50a8\u6216\u68c0\u7d22\u3002 \u6570\u7ec4\u7d22\u5f15\u662f\u968f\u673a\u8bbf\u95ee\uff08random access\uff09\u64cd\u4f5c\uff0c\u800c\u5728\u968f\u673a\u8bbf\u95ee\u65f6\uff0c\u8ba1\u7b97\u673a\u603b\u4f1a\u6267\u884c\u56fa\u5b9a\u7684\u6b65\u9aa4\u6765\u83b7\u53d6\u7b2c i \u4e2a\u5143\u7d20\u7684\u4f4d\u7f6e\u3002\u56e0\u6b64\uff0c\u4e0d\u8bba\u6570\u7ec4\u6709\u591a\u5927\uff0c\u8bbf\u95ee\u7b2c\u4e00\u4e2a\u5143\u7d20\u6240\u9700\u7684\u65f6\u95f4\u548c\u8bbf\u95ee\u6700\u540e\u4e00\u4e2a\u5143\u7d20\u6240\u9700\u8981\u7684\u65f6\u95f4\u90fd\u662f\u76f8\u540c\u7684\u3002 \u8ba1\u7b97\u673a\u901a\u8fc7\u5206\u914d\u4e00\u5757\u8fde\u7eed\u5185\u5b58\uff08contiguous memory\uff09\u5355\u5143\u6765\u5b58\u50a8\u6570\u7ec4\u91cc\u7684\u5143\u7d20\uff0c\u4ece\u800c\u652f\u6301\u5bf9\u6570\u7ec4\u7684\u968f\u673a\u8bbf\u95ee\u3002 \u7531\u4e8e\u6570\u7ec4\u91cc\u7684\u5143\u7d20\u5730\u5740\u90fd\u662f\u6309\u7167\u6570\u5b57\u987a\u5e8f\u8fdb\u884c\u6392\u5217\u7684\uff0c\u56e0\u6b64\u53ef\u4ee5\u901a\u8fc7\u6dfb\u52a0\u4e24\u4e2a\u503c\u6765\u8ba1\u7b97\u51fa\u6570\u7ec4\u5143\u7d20\u7684\u673a\u5668\u5730\u5740\uff0c\u5b83\u4eec\u662f\u6570\u7ec4\u7684\u57fa\u5730\u5740\uff08base address\uff09\u4ee5\u53ca\u5143\u7d20\u7684\u504f\u79fb\u91cf\uff08offset\uff09\u3002\u5176\u4e2d\uff0c\u6570\u7ec4\u7684\u57fa\u5730\u5740\u5c31\u662f\u7b2c\u4e00\u4e2a\u5143\u7d20\u7684\u673a\u5668\u5730\u5740\uff0c\u800c\u5143\u7d20\u7684\u504f\u79fb\u91cf\u5c31\u662f\u5b83\u7684\u7d22\u5f15\u503c\u518d\u4e58\u4ee5\u4e00\u4e2a\u4ee3\u8868\u6570\u7ec4\u5143\u7d20\u6240\u9700\u5185\u5b58\u5355\u5143\u6570\u7684\u5e38\u91cf\uff08\u5728Python\u91cc\uff0c\u8fd9\u4e2a\u503c\u59cb\u7ec8\u662f1\uff09\u3002 \u7b80\u800c\u8a00\u4e4b\uff0cPython\u6570\u7ec4\u91cc\u7684\u7d22\u5f15\u64cd\u4f5c\u5305\u62ec\u4e0b\u9762\u4e24\u4e2a\u6b65\u9aa4\uff1a \u5f97\u5230\u6570\u7ec4\u5185\u5b58\u5757\u7684\u57fa\u5730\u5740\u3002 \u5c06\u7d22\u5f15\u503c\u6dfb\u52a0\u5230\u8fd9\u4e2a\u5730\u5740\u5e76\u8fd4\u56de\u3002","title":"4.1.1.\u968f\u673a\u8bbf\u95ee\u548c\u8fde\u7eed\u5185\u5b58"},{"location":"python/DataStructure/04_ArrayChain/#412","text":"\u5728\u6bd4\u8f83\u8001\u7684\u7f16\u7a0b\u8bed\u8a00\uff08\u5982FORTRAN\u6216Pascal\uff09\u91cc\uff0c\u6570\u7ec4\u662f\u9759\u6001\u6570\u636e\u7ed3\u6784\u3002\u5728\u8fd9\u79cd\u60c5\u51b5\u4e0b\uff0c\u6570\u7ec4\u7684\u957f\u5ea6\u6216\u5bb9\u91cf\u5728\u7f16\u8bd1\u65f6\u5c31\u786e\u5b9a\u4e86\uff0c\u7a0b\u5e8f\u5458\u9700\u8981\u7533\u8bf7\u8db3\u591f\u591a\u7684\u5185\u5b58\u6765\u6ee1\u8db3\u5728\u6570\u7ec4\u91cc\u5b58\u50a8\u53ef\u80fd\u6709\u6700\u5927\u6570\u91cf\u5143\u7d20\u7684\u60c5\u51b5\uff0c\u8fd9\u6837\u505a\u4f1a\u6d6a\u8d39\u5927\u91cf\u7684\u5185\u5b58\u3002 \u50cfJava\u548cC++\u8fd9\u7c7b\u7684\u73b0\u4ee3\u7f16\u7a0b\u8bed\u8a00\u4f1a\u5141\u8bb8\u7a0b\u5e8f\u5458\u521b\u5efa\u52a8\u6001\u6570\u7ec4\uff08dynamic array\uff09\uff0c\u4ece\u800c\u4e3a\u8fd9\u4e2a\u95ee\u9898\u63d0\u4f9b\u4e86\u4e00\u79cd\u8865\u6551\u65b9\u6cd5\u3002\u548c\u9759\u6001\u6570\u7ec4\u76f8\u4f3c\u7684\u662f\uff0c\u52a8\u6001\u6570\u7ec4\u4e5f\u4f1a\u5360\u7528\u4e00\u5757\u8fde\u7eed\u5185\u5b58\uff0c\u5e76\u652f\u6301\u968f\u673a\u8bbf\u95ee\u3002\u52a8\u6001\u6570\u7ec4\u7684\u957f\u5ea6\u53ea\u5728\u8fd0\u884c\u65f6\u624d\u77e5\u9053\uff0c\u5728\u52a8\u6001\u6570\u7ec4\u5b9e\u4f8b\u5316\u7684\u65f6\u5019\u6307\u5b9a\u5b83\u7684\u957f\u5ea6\u3002\u5728Python\u91cc\u5b9e\u73b0\u7684Array\u7c7b\u7684\u884c\u4e3a\u4e5f\u662f\u8fd9\u6837\u7684\u3002 \u6211\u4eec\u53ef\u4ee5\u901a\u8fc7\u53e6\u4e00\u79cd\u65b9\u6cd5\u5728\u8fd0\u884c\u65f6\u6839\u636e\u5e94\u7528\u7a0b\u5e8f\u7684\u6570\u636e\u8981\u6c42\u6765\u8c03\u6574\u6570\u7ec4\u7684\u957f\u5ea6\uff0c\u8fd9\u4e9b\u8c03\u6574\u4f1a\u7531Python\u5217\u8868\u81ea\u52a8\u8fdb\u884c\u3002\u8fd9\u65f6\uff0c\u6570\u7ec4\u6709\u4ee5\u4e0b3\u79cd\u4e0d\u540c\u5f62\u5f0f\u3002 \u5728\u7a0b\u5e8f\u542f\u52a8\u65f6\u521b\u5efa\u4e00\u4e2a\u5177\u6709\u5408\u7406\u9ed8\u8ba4\u5927\u5c0f\u7684\u6570\u7ec4\u3002 \u5f53\u6570\u7ec4\u65e0\u6cd5\u5bb9\u7eb3\u66f4\u591a\u6570\u636e\u65f6\uff0c\u521b\u5efa\u4e00\u4e2a\u66f4\u5927\u7684\u65b0\u6570\u7ec4\uff0c\u5e76\u628a\u65e7\u6570\u7ec4\u91cc\u7684\u6570\u636e\u5143\u7d20\u4f20\u8f93\u7ed9\u5b83\u3002 \u5982\u679c\u6570\u7ec4\u5728\u6d6a\u8d39\u5185\u5b58\uff08\u5e94\u7528\u7a0b\u5e8f\u5220\u9664\u4e86\u4e00\u4e9b\u6570\u636e\uff09\uff0c\u90a3\u4e48\u7528\u7c7b\u4f3c\u7684\u65b9\u5f0f\u51cf\u5c0f\u6570\u7ec4\u7684\u957f\u5ea6\u3002","title":"4.1.2.\u9759\u6001\u5185\u5b58\u548c\u52a8\u6001\u5185\u5b58"},{"location":"python/DataStructure/04_ArrayChain/#413","text":"\u6570\u7ec4\u7684\u7269\u7406\u5c3a\u5bf8\uff08physical size\uff09\u662f\u6307\u6570\u7ec4\u5355\u5143\u7684\u603b\u6570\uff0c\u6216\u8005\u521b\u5efa\u6570\u7ec4\u65f6\u6307\u5b9a\u5176\u5bb9\u91cf\u7684\u90a3\u4e2a\u6570\u5b57\uff1b \u6570\u7ec4\u7684\u903b\u8f91\u5c3a\u5bf8\uff08logical size\uff09\u662f\u6307\u5f53\u524d\u5e94\u7528\u7a0b\u5e8f\u4f7f\u7528\u7684\u5143\u7d20\u6570\u91cf\u3002 \u5f53\u6570\u7ec4\u88ab\u586b\u6ee1\u7684\u65f6\u5019\uff0c\u6211\u4eec\u4e0d\u9700\u8981\u62c5\u5fc3\u5b83\u4eec\u7684\u4e0d\u540c\u3002\u5f53\u6570\u7ec4\u88ab\u90e8\u5206\u586b\u6ee1\u7684\u65f6\u5019\uff0c\u672a\u88ab\u586b\u5145\u7684\u5185\u5b58\u5355\u5143\u91cc\u7684\u6570\u636e\u5bf9\u5f53\u524d\u5e94\u7528\u7a0b\u5e8f\u662f\u6ca1\u6709\u7528\u7684\uff0c\u6211\u4eec\u79f0\u4e4b\u5783\u573e\u5185\u5bb9\uff08garbage\uff09\u3002\u5728\u5927\u591a\u6570\u5e94\u7528\u7a0b\u5e8f\u91cc\uff0c\u6211\u4eec\u662f\u8981\u6ce8\u610f\u5bf9\u6570\u7ec4\u7684\u7269\u7406\u5c3a\u5bf8\u548c\u903b\u8f91\u5c3a\u5bf8\u8fdb\u884c\u8ffd\u8e2a\u3002\u901a\u5e38\u6765\u8bf4\uff0c\u903b\u8f91\u5c3a\u5bf8\u548c\u7269\u7406\u5c3a\u5bf8\u4f1a\u53cd\u6620\u51fa\u6709\u5173\u6570\u7ec4\u72b6\u6001\u7684\u51e0\u4e2a\u91cd\u70b9\u3002 \u5982\u679c\u903b\u8f91\u5c3a\u5bf8\u4e3a0\uff0c\u90a3\u4e48\u6570\u7ec4\u5c31\u4e3a\u7a7a\u3002\u4e5f\u5c31\u662f\u8bf4\uff0c\u8fd9\u4e2a\u6570\u7ec4\u4e0d\u5305\u542b\u4efb\u4f55\u6570\u636e\u5143\u7d20\u3002 \u5982\u679c\u5e76\u975e\u4e0a\u8ff0\u60c5\u51b5\uff0c\u5728\u4efb\u4f55\u60c5\u51b5\u4e0b\uff0c\u6570\u7ec4\u4e2d\u6700\u540e\u4e00\u4e2a\u5143\u7d20\u7684\u7d22\u5f15\u90fd\u662f\u5b83\u7684\u903b\u8f91\u5c3a\u5bf8\u51cf1\u3002 \u5982\u679c\u903b\u8f91\u5c3a\u5bf8\u7b49\u4e8e\u7269\u7406\u5c3a\u5bf8\uff0c\u90a3\u4e48\u8868\u793a\u6570\u7ec4\u5df2\u88ab\u586b\u6ee1\u4e86\u3002","title":"4.1.3.\u7269\u7406\u5c3a\u5bf8\u548c\u903b\u8f91\u5c3a\u5bf8"},{"location":"python/DataStructure/04_ArrayChain/#414","text":"1\uff0e\u8bf7\u8bf4\u660e\u968f\u673a\u8bbf\u95ee\u7684\u5de5\u4f5c\u539f\u7406\uff0c\u4ee5\u53ca\u8fd9\u4e2a\u64cd\u4f5c\u8fd9\u4e48\u5feb\u7684\u539f\u56e0\u3002 \u89e3\u7b54\uff1a\u968f\u673a\u8bbf\u95ee\u662f\u4e00\u79cd\u8ba1\u7b97\u673a\u5b58\u50a8\u7cfb\u7edf\u4e2d\u7684\u8bfb\u53d6\u6216\u5199\u5165\u6570\u636e\u7684\u64cd\u4f5c\uff0c\u5176\u4e2d\u6570\u636e\u53ef\u4ee5\u901a\u8fc7\u76f4\u63a5\u8df3\u8f6c\u5230\u5176\u5b58\u50a8\u4f4d\u7f6e\u800c\u4e0d\u9700\u8981\u987a\u5e8f\u626b\u63cf\u6765\u8bbf\u95ee\u3002\u8fd9\u4e0e\u987a\u5e8f\u8bbf\u95ee\u4e0d\u540c\uff0c\u540e\u8005\u9700\u8981\u6309\u987a\u5e8f\u904d\u5386\u6570\u636e\u4ee5\u627e\u5230\u6240\u9700\u7684\u4fe1\u606f\u3002\u968f\u673a\u8bbf\u95ee\u7684\u5de5\u4f5c\u539f\u7406\u5982\u4e0b\uff1a \u5b58\u50a8\u4ecb\u8d28\uff1a\u8ba1\u7b97\u673a\u5185\u5b58\u548c\u786c\u76d8\u7b49\u5b58\u50a8\u8bbe\u5907\u90fd\u652f\u6301\u968f\u673a\u8bbf\u95ee\u3002\u8fd9\u4e9b\u5b58\u50a8\u4ecb\u8d28\u4e2d\u7684\u6570\u636e\u901a\u5e38\u88ab\u5212\u5206\u4e3a\u5757\u6216\u6247\u533a\uff0c\u5e76\u4e14\u6bcf\u4e2a\u5757\u6216\u6247\u533a\u90fd\u6709\u4e00\u4e2a\u552f\u4e00\u7684\u5730\u5740\u6216\u7d22\u5f15\u3002 \u8bbf\u95ee\u5730\u5740\uff1a\u4e3a\u4e86\u8fdb\u884c\u968f\u673a\u8bbf\u95ee\uff0c\u8ba1\u7b97\u673a\u9700\u8981\u77e5\u9053\u8981\u8bbf\u95ee\u7684\u6570\u636e\u7684\u5730\u5740\u3002\u8fd9\u4e2a\u5730\u5740\u53ef\u4ee5\u662f\u5185\u5b58\u4e2d\u7684\u7279\u5b9a\u4f4d\u7f6e\uff0c\u4e5f\u53ef\u4ee5\u662f\u786c\u76d8\u4e0a\u7684\u67d0\u4e2a\u6247\u533a\u7684\u5730\u5740\u3002 \u5bfb\u5740\u548c\u4f20\u8f93\uff1a\u8ba1\u7b97\u673a\u4f7f\u7528\u5b58\u50a8\u8bbe\u5907\u7684\u63a7\u5236\u5668\u6216\u5b58\u50a8\u5668\u7ba1\u7406\u5355\u5143\u6765\u67e5\u627e\u6570\u636e\u7684\u5730\u5740\u3002\u4e00\u65e6\u627e\u5230\u4e86\u6b63\u786e\u7684\u5730\u5740\uff0c\u5b58\u50a8\u8bbe\u5907\u4f1a\u5c06\u6570\u636e\u4f20\u8f93\u5230\u8ba1\u7b97\u673a\u7684\u5185\u5b58\u4e2d\u4f9b\u5904\u7406\u5668\u4f7f\u7528\u3002 \u8bbf\u95ee\u901f\u5ea6\uff1a\u968f\u673a\u8bbf\u95ee\u4e4b\u6240\u4ee5\u5982\u6b64\u5feb\u901f\uff0c\u662f\u56e0\u4e3a\u8ba1\u7b97\u673a\u5185\u5b58\u548c\u73b0\u4ee3\u786c\u76d8\u9a71\u52a8\u5668\u7b49\u5b58\u50a8\u8bbe\u5907\u90fd\u7ecf\u8fc7\u4e86\u4f18\u5316\uff0c\u53ef\u4ee5\u5feb\u901f\u54cd\u5e94\u8bbf\u95ee\u8bf7\u6c42\u3002\u8fd9\u4e9b\u8bbe\u5907\u4f7f\u7528\u4e86\u9ad8\u901f\u7f13\u5b58\u3001\u8bfb\u5199\u5934\u3001\u5bfb\u9053\u673a\u6784\u7b49\u6280\u672f\u6765\u6700\u5c0f\u5316\u6570\u636e\u8bbf\u95ee\u7684\u5ef6\u8fdf\u3002 \u539f\u56e0\uff1a \u5b58\u50a8\u8bbe\u5907\u7684\u7269\u7406\u7ed3\u6784\uff1a\u8ba1\u7b97\u673a\u5185\u5b58\u548c\u786c\u76d8\u7b49\u5b58\u50a8\u8bbe\u5907\u7684\u7269\u7406\u7ed3\u6784\u88ab\u8bbe\u8ba1\u6210\u53ef\u4ee5\u968f\u673a\u8bbf\u95ee\u7684\u3002\u5185\u5b58\u4e2d\u7684\u6bcf\u4e2a\u5730\u5740\u90fd\u53ef\u4ee5\u77ac\u95f4\u8bbf\u95ee\uff0c\u800c\u786c\u76d8\u4e0a\u7684\u6247\u533a\u4e5f\u53ef\u4ee5\u901a\u8fc7\u78c1\u5934\u5bfb\u9053\u548c\u65cb\u8f6c\u78c1\u76d8\u7b49\u673a\u5236\u8fc5\u901f\u8bbf\u95ee\u3002 \u9ad8\u901f\u7f13\u5b58\uff1a\u73b0\u4ee3\u8ba1\u7b97\u673a\u5185\u5b58\u548c\u5904\u7406\u5668\u90fd\u914d\u5907\u4e86\u9ad8\u901f\u7f13\u5b58\uff08\u4f8b\u5982\uff0cCPU\u7f13\u5b58\uff09\u3002\u8fd9\u4e9b\u9ad8\u901f\u7f13\u5b58\u5b58\u50a8\u4e86\u6700\u8fd1\u8bbf\u95ee\u7684\u6570\u636e\uff0c\u53ef\u4ee5\u5feb\u901f\u63d0\u4f9b\u7ed9\u5904\u7406\u5668\uff0c\u4ece\u800c\u964d\u4f4e\u4e86\u8bbf\u95ee\u5ef6\u8fdf\u3002 \u5b58\u50a8\u5668\u7ba1\u7406\uff1a\u64cd\u4f5c\u7cfb\u7edf\u548c\u5b58\u50a8\u8bbe\u5907\u7684\u63a7\u5236\u5668\u4f1a\u7ba1\u7406\u5b58\u50a8\u5668\u7684\u8bbf\u95ee\uff0c\u4ee5\u786e\u4fdd\u6570\u636e\u53ef\u4ee5\u9ad8\u6548\u5730\u88ab\u8bbf\u95ee\u548c\u4f20\u8f93\u3002\u8fd9\u5305\u62ec\u4e86\u78c1\u76d8\u8c03\u5ea6\u7b97\u6cd5\u3001\u5185\u5b58\u5206\u9875\u7b49\u7b56\u7565\u3002 \u6280\u672f\u8fdb\u6b65\uff1a\u786c\u4ef6\u5236\u9020\u6280\u672f\u7684\u8fdb\u6b65\u548c\u5b58\u50a8\u8bbe\u5907\u7684\u4f18\u5316\u4f7f\u5f97\u968f\u673a\u8bbf\u95ee\u901f\u5ea6\u66f4\u5feb\u3002\u4f8b\u5982\uff0c\u56fa\u6001\u786c\u76d8\uff08SSD\uff09\u7684\u51fa\u73b0\u663e\u8457\u63d0\u9ad8\u4e86\u6570\u636e\u7684\u968f\u673a\u8bbf\u95ee\u901f\u5ea6\u3002 \u603b\u4e4b\uff0c\u968f\u673a\u8bbf\u95ee\u4e4b\u6240\u4ee5\u5982\u6b64\u5feb\u901f\uff0c\u662f\u56e0\u4e3a\u8ba1\u7b97\u673a\u5185\u5b58\u548c\u5b58\u50a8\u8bbe\u5907\u7684\u7269\u7406\u548c\u6280\u672f\u7279\u6027\u4f7f\u5176\u80fd\u591f\u4ee5\u9ad8\u6548\u3001\u8fc5\u901f\u7684\u65b9\u5f0f\u8bbf\u95ee\u6570\u636e\u3002\u8fd9\u79cd\u8bbf\u95ee\u901f\u5ea6\u5bf9\u4e8e\u8ba1\u7b97\u673a\u7684\u6027\u80fd\u548c\u54cd\u5e94\u65f6\u95f4\u81f3\u5173\u91cd\u8981\u3002 2\uff0e\u6570\u7ec4\u548cPython\u5217\u8868\u4e4b\u95f4\u6709\u4ec0\u4e48\u533a\u522b\uff1f \u89e3\u7b54\uff1a\u6570\u7ec4\u548cPython\u5217\u8868\u4e4b\u95f4\u6709\u51e0\u4e2a\u5173\u952e\u533a\u522b\uff0c\u8fd9\u4e9b\u533a\u522b\u5728\u6570\u636e\u7ed3\u6784\u3001\u529f\u80fd\u548c\u7528\u9014\u4e0a\u5b58\u5728\u5dee\u5f02\uff1a \u6570\u636e\u7c7b\u578b\uff1a \u6570\u7ec4\uff1a\u901a\u5e38\u8981\u6c42\u6240\u6709\u5143\u7d20\u5177\u6709\u76f8\u540c\u7684\u6570\u636e\u7c7b\u578b\u3002\u8fd9\u662f\u56e0\u4e3a\u6570\u7ec4\u5728\u5185\u5b58\u4e2d\u4ee5\u7d27\u51d1\u7684\u65b9\u5f0f\u5b58\u50a8\u6570\u636e\uff0c\u9700\u8981\u77e5\u9053\u6bcf\u4e2a\u5143\u7d20\u7684\u5927\u5c0f\u4ee5\u4fbf\u8fdb\u884c\u968f\u673a\u8bbf\u95ee\u3002 Python\u5217\u8868\uff1aPython\u7684\u5217\u8868\u53ef\u4ee5\u5bb9\u7eb3\u4e0d\u540c\u6570\u636e\u7c7b\u578b\u7684\u5143\u7d20\uff0c\u56e0\u4e3a\u5b83\u4eec\u662f\u52a8\u6001\u7c7b\u578b\u7684\u3002 \u5185\u5b58\u7ba1\u7406\uff1a \u6570\u7ec4\uff1a\u901a\u5e38\u5728\u521b\u5efa\u65f6\u9700\u8981\u6307\u5b9a\u56fa\u5b9a\u5927\u5c0f\uff0c\u56e0\u6b64\u5728\u5185\u5b58\u4e2d\u4f1a\u5206\u914d\u4e00\u5757\u8fde\u7eed\u7684\u7a7a\u95f4\uff0c\u8fd9\u4f7f\u5f97\u6570\u7ec4\u5bf9\u4e8e\u9ad8\u6548\u7684\u968f\u673a\u8bbf\u95ee\u975e\u5e38\u9002\u7528\u3002 Python\u5217\u8868\uff1aPython\u7684\u5217\u8868\u662f\u52a8\u6001\u7684\uff0c\u5b83\u4eec\u53ef\u4ee5\u6839\u636e\u9700\u8981\u81ea\u52a8\u6269\u5c55\u6216\u7f29\u5c0f\u3002\u8fd9\u5bfc\u81f4\u4e86\u4e00\u4e9b\u989d\u5916\u7684\u5185\u5b58\u5f00\u9500\uff0c\u56e0\u4e3a\u5217\u8868\u9700\u8981\u66f4\u591a\u7684\u7a7a\u95f4\u6765\u7ba1\u7406\u5143\u7d20\u7684\u6dfb\u52a0\u548c\u5220\u9664\u3002 \u6027\u80fd\uff1a \u6570\u7ec4\uff1a\u7531\u4e8e\u5185\u5b58\u5e03\u5c40\u8fde\u7eed\uff0c\u56e0\u6b64\u6570\u7ec4\u901a\u5e38\u5728\u8bbf\u95ee\u5143\u7d20\u65f6\u66f4\u5feb\u3002\u6570\u7ec4\u8fd8\u652f\u6301\u66f4\u591a\u7684\u5e95\u5c42\u64cd\u4f5c\uff0c\u5982\u4f4d\u64cd\u4f5c\u3002 Python\u5217\u8868\uff1aPython\u5217\u8868\u66f4\u52a0\u7075\u6d3b\uff0c\u4f46\u5728\u67d0\u4e9b\u60c5\u51b5\u4e0b\u53ef\u80fd\u4f1a\u5bfc\u81f4\u6027\u80fd\u4e0b\u964d\uff0c\u7279\u522b\u662f\u5f53\u6d89\u53ca\u5927\u91cf\u5143\u7d20\u7684\u63d2\u5165\u548c\u5220\u9664\u64cd\u4f5c\u65f6\u3002 \u64cd\u4f5c\u548c\u65b9\u6cd5\uff1a \u6570\u7ec4\uff1a\u901a\u5e38\u63d0\u4f9b\u4e00\u7ec4\u57fa\u672c\u64cd\u4f5c\uff0c\u5982\u8bfb\u53d6\u548c\u5199\u5165\u5143\u7d20\uff0c\u4ee5\u53ca\u4e00\u4e9b\u6570\u5b66\u8fd0\u7b97\uff0c\u5982\u5411\u91cf\u5316\u64cd\u4f5c\u3002 Python\u5217\u8868\uff1aPython\u5217\u8868\u63d0\u4f9b\u4e86\u66f4\u4e30\u5bcc\u7684\u65b9\u6cd5\u548c\u64cd\u4f5c\uff0c\u5305\u62ec\u5143\u7d20\u7684\u63d2\u5165\u3001\u5220\u9664\u3001\u8ffd\u52a0\u3001\u5207\u7247\u3001\u8fde\u63a5\u7b49\u3002 \u8bed\u8a00\u4f9d\u8d56\u6027\uff1a \u6570\u7ec4\uff1a\u6570\u7ec4\u901a\u5e38\u662f\u7f16\u7a0b\u8bed\u8a00\u7684\u4e00\u90e8\u5206\uff0c\u5177\u6709\u56fa\u5b9a\u7684\u8bed\u6cd5\u548c\u8bed\u4e49\u3002 Python\u5217\u8868\uff1aPython\u7684\u5217\u8868\u662fPython\u6807\u51c6\u5e93\u7684\u4e00\u90e8\u5206\uff0c\u4e0ePython\u7684\u52a8\u6001\u7279\u6027\u76f8\u9002\u5e94\u3002 \u9002\u7528\u573a\u666f\uff1a \u6570\u7ec4\uff1a\u9002\u7528\u4e8e\u9700\u8981\u9ad8\u6548\u968f\u673a\u8bbf\u95ee\u7684\u60c5\u51b5\uff0c\u5982\u6570\u503c\u8ba1\u7b97\u3001\u56fe\u50cf\u5904\u7406\u7b49\u3002 Python\u5217\u8868\uff1a\u9002\u7528\u4e8e\u66f4\u5e7f\u6cdb\u7684\u5e94\u7528\uff0c\u7279\u522b\u662f\u5728\u7f16\u5199Python\u4ee3\u7801\u65f6\uff0c\u56e0\u4e3a\u5b83\u4eec\u66f4\u7075\u6d3b\u4e14\u6613\u4e8e\u4f7f\u7528\u3002 \u603b\u4e4b\uff0c\u6570\u7ec4\u548cPython\u5217\u8868\u90fd\u6709\u81ea\u5df1\u7684\u4f18\u52bf\u548c\u9002\u7528\u573a\u666f\u3002\u9009\u62e9\u4f7f\u7528\u54ea\u79cd\u6570\u636e\u7ed3\u6784\u53d6\u51b3\u4e8e\u5177\u4f53\u7684\u9700\u6c42\u548c\u7f16\u7a0b\u8bed\u8a00\u3002\u5728Python\u4e2d\uff0c\u901a\u5e38\u4f1a\u4f18\u5148\u9009\u62e9\u4f7f\u7528\u5217\u8868\uff0c\u56e0\u4e3a\u5b83\u4eec\u66f4\u65b9\u4fbf\uff0c\u800c\u5728\u5176\u4ed6\u7f16\u7a0b\u8bed\u8a00\u4e2d\uff0c\u5982C\u6216Java\uff0c\u6570\u7ec4\u53ef\u80fd\u66f4\u4e3a\u5e38\u89c1\u3002 \u5728\u8fd9\u91cc\u9700\u8981\u8bf4\u660e\u4e00\u4e2a\u6982\u5ff5\u3002\u5728Python\u4e2d\uff0c\u672f\u8bed\"\u6570\u7ec4\"\u901a\u5e38\u6307\u7684\u662fNumPy\u5e93\u4e2d\u7684\u6570\u7ec4\u5bf9\u8c61\uff0c\u800c\"\u5217\u8868\"\u6307\u7684\u662fPython\u7684\u5185\u7f6e\u5217\u8868\uff08list\uff09\u6570\u636e\u7ed3\u6784\u3002\u8fd9\u4e24\u8005\u4e4b\u95f4\u6709\u4ee5\u4e0b\u533a\u522b\uff1a \u6570\u636e\u7c7b\u578b\uff1a \u6570\u7ec4\uff08NumPy\u6570\u7ec4\uff09\uff1aNumPy\u5e93\u63d0\u4f9b\u4e86\u4e00\u4e2a\u591a\u7ef4\u6570\u7ec4\u5bf9\u8c61\uff0c\u5b83\u53ef\u4ee5\u5305\u542b\u76f8\u540c\u6570\u636e\u7c7b\u578b\u7684\u5143\u7d20\uff0c\u5e76\u652f\u6301\u9ad8\u7ea7\u6570\u5b66\u3001\u79d1\u5b66\u548c\u5de5\u7a0b\u8ba1\u7b97\u3002NumPy\u6570\u7ec4\u7684\u5143\u7d20\u7c7b\u578b\u901a\u5e38\u662f\u56fa\u5b9a\u7684\uff0c\u4f8b\u5982\uff0c\u53ef\u4ee5\u662f\u6574\u6570\u3001\u6d6e\u70b9\u6570\u3001\u590d\u6570\u7b49\u3002\u8fd9\u4e9b\u6570\u7ec4\u662f\u9ad8\u6027\u80fd\u7684\uff0c\u652f\u6301\u5411\u91cf\u5316\u64cd\u4f5c\u3002 \u5217\u8868\uff08Python\u5217\u8868\uff09\uff1aPython\u7684\u5185\u7f6e\u5217\u8868\u662f\u4e00\u79cd\u901a\u7528\u7684\u3001\u52a8\u6001\u7c7b\u578b\u7684\u6570\u636e\u7ed3\u6784\uff0c\u53ef\u4ee5\u5305\u542b\u4e0d\u540c\u6570\u636e\u7c7b\u578b\u7684\u5143\u7d20\uff0c\u4f8b\u5982\u6574\u6570\u3001\u6d6e\u70b9\u6570\u3001\u5b57\u7b26\u4e32\u3001\u5bf9\u8c61\u7b49\u3002\u5217\u8868\u53ef\u4ee5\u52a8\u6001\u6269\u5c55\u548c\u7f29\u5c0f\uff0c\u5e76\u63d0\u4f9b\u4e86\u4e30\u5bcc\u7684\u5185\u7f6e\u65b9\u6cd5\u548c\u64cd\u4f5c\u3002 \u6027\u80fd\uff1a \u6570\u7ec4\uff08NumPy\u6570\u7ec4\uff09\uff1aNumPy\u6570\u7ec4\u901a\u5e38\u6bd4Python\u5217\u8868\u66f4\u9ad8\u6548\uff0c\u7279\u522b\u662f\u5728\u8fdb\u884c\u6570\u503c\u8ba1\u7b97\u548c\u79d1\u5b66\u8ba1\u7b97\u65f6\u3002\u5b83\u4eec\u5185\u90e8\u4f7f\u7528\u4e86C\u8bed\u8a00\u5b9e\u73b0\uff0c\u652f\u6301\u5411\u91cf\u5316\u64cd\u4f5c\uff0c\u56e0\u6b64\u5728\u5927\u89c4\u6a21\u6570\u636e\u5904\u7406\u4e2d\u901a\u5e38\u66f4\u5feb\u3002 \u5217\u8868\uff08Python\u5217\u8868\uff09\uff1aPython\u5217\u8868\u867d\u7136\u7075\u6d3b\uff0c\u4f46\u6027\u80fd\u76f8\u5bf9\u8f83\u4f4e\uff0c\u4e0d\u9002\u5408\u5927\u89c4\u6a21\u7684\u6570\u503c\u8ba1\u7b97\u3002\u5b83\u4eec\u7684\u5143\u7d20\u7c7b\u578b\u53ef\u4ee5\u4e0d\u540c\uff0c\u8fd9\u610f\u5473\u7740\u9700\u8981\u66f4\u591a\u7684\u5185\u5b58\u548c\u5904\u7406\u65f6\u95f4\u6765\u7ba1\u7406\u5143\u7d20\u3002 \u5e93\u4f9d\u8d56\uff1a \u6570\u7ec4\uff08NumPy\u6570\u7ec4\uff09\uff1a\u4f7f\u7528NumPy\u5e93\u9700\u8981\u5b89\u88c5NumPy\u6a21\u5757\u3002NumPy\u662fPython\u4e2d\u7528\u4e8e\u6570\u503c\u8ba1\u7b97\u7684\u6838\u5fc3\u5e93\uff0c\u5e7f\u6cdb\u5e94\u7528\u4e8e\u79d1\u5b66\u8ba1\u7b97\u3001\u673a\u5668\u5b66\u4e60\u7b49\u9886\u57df\u3002 \u5217\u8868\uff08Python\u5217\u8868\uff09\uff1aPython\u7684\u5185\u7f6e\u5217\u8868\u662fPython\u6807\u51c6\u5e93\u7684\u4e00\u90e8\u5206\uff0c\u65e0\u9700\u989d\u5916\u5b89\u88c5\u3002 \u529f\u80fd\uff1a \u6570\u7ec4\uff08NumPy\u6570\u7ec4\uff09\uff1aNumPy\u6570\u7ec4\u63d0\u4f9b\u4e86\u8bb8\u591a\u6570\u5b66\u548c\u79d1\u5b66\u8ba1\u7b97\u51fd\u6570\uff0c\u5982\u7ebf\u6027\u4ee3\u6570\u3001\u5085\u7acb\u53f6\u53d8\u6362\u3001\u7edf\u8ba1\u5206\u6790\u7b49\u3002\u5b83\u4eec\u9002\u7528\u4e8e\u5904\u7406\u5927\u91cf\u6570\u503c\u6570\u636e\u3002 \u5217\u8868\uff08Python\u5217\u8868\uff09\uff1aPython\u5217\u8868\u63d0\u4f9b\u4e86\u901a\u7528\u7684\u6570\u636e\u5bb9\u5668\uff0c\u7528\u4e8e\u5b58\u50a8\u548c\u7ba1\u7406\u5404\u79cd\u7c7b\u578b\u7684\u6570\u636e\uff0c\u4f46\u4e0d\u63d0\u4f9b\u4e13\u95e8\u7684\u6570\u5b66\u548c\u79d1\u5b66\u8ba1\u7b97\u529f\u80fd\u3002 \u5982\u679c\u9700\u8981\u8fdb\u884c\u6570\u503c\u8ba1\u7b97\u3001\u79d1\u5b66\u8ba1\u7b97\u6216\u6570\u636e\u5206\u6790\uff0c\u901a\u5e38\u4f1a\u4f7f\u7528NumPy\u6570\u7ec4\u3002\u5982\u679c\u53ea\u662f\u9700\u8981\u4e00\u4e2a\u901a\u7528\u7684\u6570\u636e\u5bb9\u5668\uff0c\u7528\u4e8e\u5b58\u50a8\u548c\u7ba1\u7406\u6570\u636e\uff0c\u90a3\u4e48Python\u5217\u8868\u901a\u5e38\u8db3\u591f\u4e86\u3002 3\uff0e\u8bf7\u8bf4\u660e\u6570\u7ec4\u7684\u7269\u7406\u5c3a\u5bf8\u548c\u903b\u8f91\u5c3a\u5bf8\u4e4b\u95f4\u7684\u533a\u522b\u3002 \u89e3\u7b54\uff1a\"\u7269\u7406\u5c3a\u5bf8\"\u548c\"\u903b\u8f91\u5c3a\u5bf8\"\u901a\u5e38\u7528\u4e8e\u63cf\u8ff0\u6570\u636e\u7ed3\u6784\u4e2d\u7684\u4e24\u4e2a\u4e0d\u540c\u65b9\u9762\uff1a \u7269\u7406\u5c3a\u5bf8\uff08Physical Size\uff09\uff1a \u7269\u7406\u5c3a\u5bf8\u662f\u6307\u6570\u636e\u7ed3\u6784\u5b9e\u9645\u5360\u7528\u7684\u5185\u5b58\u7a7a\u95f4\u6216\u5b58\u50a8\u4ecb\u8d28\u4e2d\u7684\u7a7a\u95f4\u5927\u5c0f\u3002 \u5b83\u8868\u793a\u6570\u636e\u7ed3\u6784\u5728\u8ba1\u7b97\u673a\u5185\u5b58\u6216\u78c1\u76d8\u4e2d\u6240\u5360\u636e\u7684\u5b9e\u9645\u5b57\u8282\u6570\u3002 \u7269\u7406\u5c3a\u5bf8\u4e0e\u6570\u636e\u7ed3\u6784\u7684\u5b58\u50a8\u65b9\u5f0f\u3001\u6570\u636e\u7c7b\u578b\u4ee5\u53ca\u8ba1\u7b97\u673a\u67b6\u6784\u6709\u5173\u3002 \u903b\u8f91\u5c3a\u5bf8\uff08Logical Size\uff09\uff1a \u903b\u8f91\u5c3a\u5bf8\u662f\u6307\u6570\u636e\u7ed3\u6784\u4e2d\u5305\u542b\u7684\u5143\u7d20\u6570\u91cf\u6216\u6570\u636e\u9879\u7684\u6570\u91cf\u3002 \u5b83\u8868\u793a\u6570\u636e\u7ed3\u6784\u5185\u90e8\u7684\u5143\u7d20\u6570\u91cf\u6216\u6570\u636e\u9879\u7684\u4e2a\u6570\uff0c\u4e0d\u6d89\u53ca\u5b9e\u9645\u7684\u5b58\u50a8\u5927\u5c0f\u3002 \u903b\u8f91\u5c3a\u5bf8\u901a\u5e38\u7528\u4e8e\u63cf\u8ff0\u6570\u636e\u7ed3\u6784\u7684\u5bb9\u91cf\u3001\u89c4\u6a21\u6216\u7ef4\u5ea6\u3002 \u8fd9\u4e24\u4e2a\u6982\u5ff5\u4e4b\u95f4\u7684\u5173\u7cfb\u5982\u4e0b\uff1a \u4e00\u4e2a\u6570\u636e\u7ed3\u6784\u53ef\u4ee5\u5177\u6709\u56fa\u5b9a\u7684\u7269\u7406\u5c3a\u5bf8\uff08\u5360\u636e\u56fa\u5b9a\u6570\u91cf\u7684\u5b57\u8282\uff09\uff0c\u4f46\u5176\u903b\u8f91\u5c3a\u5bf8\u53ef\u4ee5\u6839\u636e\u5b9e\u9645\u5b58\u50a8\u7684\u5143\u7d20\u6570\u91cf\u800c\u53d8\u5316\u3002 \u7269\u7406\u5c3a\u5bf8\u901a\u5e38\u662f\u7531\u8ba1\u7b97\u673a\u786c\u4ef6\u548c\u64cd\u4f5c\u7cfb\u7edf\u7ba1\u7406\u7684\uff0c\u800c\u903b\u8f91\u5c3a\u5bf8\u5219\u662f\u7a0b\u5e8f\u5458\u6839\u636e\u6570\u636e\u7ed3\u6784\u7684\u8bbe\u8ba1\u6765\u7ba1\u7406\u7684\u3002 \u4e3e\u4f8b\u6765\u8bf4\uff0c\u4e00\u4e2a\u6574\u6570\u6570\u7ec4\u53ef\u4ee5\u5177\u6709\u56fa\u5b9a\u7684\u7269\u7406\u5c3a\u5bf8\uff0c\u4f8b\u59824\u5b57\u8282/\u6574\u6570\uff0c\u4f46\u5b83\u7684\u903b\u8f91\u5c3a\u5bf8\u53ef\u4ee5\u662f\u6570\u7ec4\u4e2d\u6574\u6570\u7684\u6570\u91cf\uff0c\u53ef\u4ee5\u662f0\u4e2a\u300110\u4e2a\u3001100\u4e2a\u7b49\u7b49\u3002\u56e0\u6b64\uff0c\u903b\u8f91\u5c3a\u5bf8\u63cf\u8ff0\u4e86\u6570\u7ec4\u53ef\u4ee5\u5bb9\u7eb3\u7684\u5143\u7d20\u6570\u91cf\uff0c\u800c\u7269\u7406\u5c3a\u5bf8\u63cf\u8ff0\u4e86\u5b9e\u9645\u5360\u7528\u7684\u5185\u5b58\u7a7a\u95f4\u3002 \u5728\u6570\u636e\u7ed3\u6784\u7684\u8bbe\u8ba1\u548c\u4f7f\u7528\u4e2d\uff0c\u4e86\u89e3\u548c\u7ba1\u7406\u7269\u7406\u5c3a\u5bf8\u548c\u903b\u8f91\u5c3a\u5bf8\u5bf9\u4e8e\u6709\u6548\u5730\u5229\u7528\u8ba1\u7b97\u673a\u8d44\u6e90\u975e\u5e38\u91cd\u8981\u3002","title":"4.1.4.\u7ec3\u4e60\u9898"},{"location":"python/DataStructure/04_ArrayChain/#42","text":"Python\u7684 array \u6a21\u5757\u5305\u542b\u4e00\u4e2a\u53eb\u4f5c array \u7684\u7c7b\uff0c\u5b83\u975e\u5e38\u7c7b\u4f3c\u4e8e\u5217\u8868\uff0c\u4f46\u662f\u53ea\u80fd\u5b58\u50a8\u6570\u5b57\u3002\u6211\u4eec\u4f1a\u5b9a\u4e49\u4e00\u4e2a\u53eb\u4f5c Array \u7684\u65b0\u7c7b\uff0c\u4f7f\u7528\u5217\u8868\u4fdd\u5b58\u5143\u7d20\uff0c\u5b58\u50a8\u4efb\u4f55\u7c7b\u578b\u7684\u5143\u7d20\u3002 \u4e0b\u9762\u7684\u793a\u4f8b\u5b9a\u4e49\u4e86\u4e00\u4e2a\u6570\u7ec4\u7c7b Array \uff0c\u4e0b\u9762\u5bf9\u6570\u7ec4\u7684\u4e00\u4e9b\u64cd\u4f5c\u7684\u4ee3\u7801\u5b9e\u73b0\u4e5f\u5df2\u7ecf\u5305\u542b\u5728\u4e0b\u9762\u7684\u4ee3\u7801\u4e2d\u3002\u5176\u4e2d\uff1a \u6570\u7ec4\u9ed8\u8ba4\u7684\u7269\u7406\u5c3a\u5bf8\uff08\u4e5f\u5c31\u662f\u5bb9\u91cf\uff09\u662f5 \u6570\u7ec4\u7684\u521d\u59cb\u903b\u8f91\u5c3a\u5bf8\u662f0 class Array ( object ): \"\"\"\u63cf\u8ff0\u4e00\u4e2a\u6570\u7ec4\u3002\"\"\" def __init__ ( self , capacity , fillValue = None ): \"\"\"Capacity\u662f\u6570\u7ec4\u7684\u5927\u5c0f. fillValue\u4f1a\u586b\u5145\u5728\u6bcf\u4e2a\u5143\u7d20\u4f4d\u7f6e, \u9ed8\u8ba4\u503c\u662fNone\"\"\" # \u521d\u59cb\u5316\u6570\u7ec4\u7684\u903b\u8f91\u5c3a\u5bf8\u548c\u7269\u7406\u5c3a\u5bf8 self . logicalSize = 0 self . capacity = capacity self . fillValue = fillValue #\u521d\u59cb\u5316\u5185\u90e8\u6570\u7ec4\uff0c\u5e76\u586b\u5145\u5143\u7d20\u503c self . items = list () for count in range ( capacity ): self . items . append ( fillValue ) self . logicalSize += 1 # \u521d\u59cb\u5316\u6570\u7ec4\u7269\u7406\u5927\u5c0f\u65f6\uff0c\u4e5f\u540c\u65f6\u521d\u59cb\u5316\u5176\u903b\u8f91\u5927\u5c0f def __len__ ( self ): \"\"\"\u8fd4\u56de\u6570\u7ec4\u7684\u5927\u5c0f\"\"\" return len ( self . items ) def __str__ ( self ): \"\"\"\u5c06\u6570\u7ec4\u5b57\u7b26\u4e32\u5316\u5e76\u8fd4\u56de\"\"\" result = \"\" for index in range ( self . size ()): result += str ( self . items [ index ]) + \" \" return result def size ( self ): \"\"\"\u8fd4\u56de\u6570\u7ec4\u7684\u903b\u8f91\u5c3a\u5bf8\"\"\" return self . logicalSize def __iter__ ( self ): \"\"\"\u652f\u6301for\u5faa\u73af\u5bf9\u6570\u7ec4\u8fdb\u884c\u904d\u5386.\"\"\" print ( \"__iter__ called\" ) # \u4ec5\u7528\u6765\u6d4b\u8bd5\u4f55\u65f6__iter__\u4f1a\u88ab\u8c03\u7528 return iter ( self . items ) def __getitem__ ( self , index ): \"\"\" \u7528\u4e8e\u8bbf\u95ee\u7d22\u5f15\u5904\u7684\u4e0b\u6807\u8fd0\u7b97\u7b26. \u5148\u51b3\u6761\u4ef6: 0 <= index < size() \"\"\" if index < 0 or index >= self . size (): raise IndexError ( \"\u8bfb\u53d6\u64cd\u4f5c\u51fa\u9519, \u6570\u7ec4\u7d22\u5f15\u8d8a\u754c(\u4e0d\u5728\u6570\u7ec4\u903b\u8f91\u8fb9\u754c\u8303\u56f4\u5185)\" ) return self . items [ index ] def __setitem__ ( self , index , newItem ): \"\"\" \u4e0b\u6807\u8fd0\u7b97\u7b26\u7528\u4e8e\u5728\u7d22\u5f15\u5904\u8fdb\u884c\u66ff\u6362. \u5148\u51b3\u6761\u4ef6: 0 <= index < size() \"\"\" if index < 0 or index >= self . size (): raise IndexError ( \"\u66f4\u65b0\u64cd\u4f5c\u51fa\u9519, \u6570\u7ec4\u7d22\u5f15\u8d8a\u754c(\u4e0d\u5728\u6570\u7ec4\u903b\u8f91\u8fb9\u754c\u8303\u56f4\u5185)\" ) self . items [ index ] = newItem def __eq__ ( self , other ): \"\"\" \u4e24\u4e2a\u6570\u7ec4\u76f8\u7b49\u5219\u8fd4\u56deTrue\uff0c\u5426\u5219\u8fd4\u56deFalse \"\"\" # \u5224\u65ad\u4e24\u4e2a\u6570\u7ec4\u662f\u5426\u662f\u540c\u4e00\u4e2a\u5bf9\u8c61\uff0c\u6ce8\u610f\uff0c\u4e0d\u662f\u5b83\u4eec\u7684\u503c\u662f\u5426\u76f8\u7b49 if self is other : return True # \u5224\u65ad\u4e24\u4e2a\u5bf9\u8c61\u7c7b\u578b\u662f\u5426\u4e00\u6837 if type ( self ) != type ( other ): return False # \u5224\u65ad\u4e24\u4e2a\u6570\u7ec4\u5927\u5c0f\u662f\u5426\u4e00\u6837 if self . size () != other . size (): return False # \u6bd4\u8f83\u4e24\u4e2a\u6570\u7ec4\u7684\u503c\u662f\u5426\u4e00\u6837 for index in range ( self . size ()): if self [ index ] != other [ index ]: return False return True def grow ( self ): \"\"\"\u589e\u5927\u6570\u7ec4\u7269\u7406\u5c3a\u5bf8\"\"\" # \u57fa\u4e8e\u5f53\u524d\u7269\u7406\u5c3a\u5bf8\u52a0\u500d\uff0c\u5e76\u5c06fillValue\u8d4b\u503c\u5e95\u5c42\u5217\u8868\u7684\u65b0\u5143\u7d20 for count in range ( len ( self )): self . items . append ( self . fillValue ) def insert ( self , index , newItem ): \"\"\"\u5728\u6570\u7ec4\u6307\u5b9a\u7d22\u5f15\u5904\u63d2\u5165\u65b0\u5143\u7d20\"\"\" # \u5f53\u6570\u7ec4\u7684\u7269\u7406\u5c3a\u5bf8\u548c\u903b\u8f91\u5c3a\u5bf8\u4e00\u6837\u65f6\uff0c\u5219\u589e\u52a0\u7269\u7406\u5c3a\u5bf8 if self . size () == len ( self ): self . grow () # \u63d2\u5165\u65b0\u5143\u7d20 # \u5f53\u63d2\u5165\u4f4d\u7f6e\u5927\u4e8e\u6216\u7b49\u4e8e\u6700\u5927\u903b\u8f91\u4f4d\u7f6e\uff0c\u5219\u5728\u6570\u7ec4\u672b\u7aef\u63d2\u5165\u65b0\u5143\u7d20 # \u5f53\u63d2\u5165\u4f4d\u7f6e\u4ecb\u4e8e\u6570\u7ec4\u903b\u8f91\u4f4d\u7f6e\u7684\u4e2d\u95f4\uff0c\u5219\u4ece\u63d2\u5165\u4f4d\u7f6e\u8d77\u5c06\u5269\u4f59\u6570\u7ec4\u5143\u7d20\u5411\u5c3e\u90e8\u5e73\u79fb\u4e00\u4e2a\u4f4d\u7f6e if index >= self . size (): self . items [ self . size ()] = newItem else : index = max ( index , 0 ) # \u5c06\u6570\u7ec4\u5143\u7d20\u5411\u5c3e\u90e8\u5e73\u79fb\u4e00\u4e2a\u4f4d\u7f6e for i in range ( self . size (), index , - 1 ): self . items [ i ] = self . items [ i - 1 ] # \u63d2\u5165\u65b0\u5143\u7d20 self . items [ index ] = newItem # \u589e\u52a0\u6570\u7ec4\u7684\u903b\u8f91\u5c3a\u5bf8 self . logicalSize += 1 def shrink ( self ): \"\"\" \u51cf\u5c11\u6570\u7ec4\u7684\u7269\u7406\u5c3a\u5bf8 \u5f53: - \u6570\u7ec4\u7684\u903b\u8f91\u5c3a\u5bf8\u5c0f\u4e8e\u6216\u7b49\u4e8e\u5176\u7269\u7406\u5c3a\u5bf8\u76841/4 - \u5e76\u4e14\u5b83\u7684\u7269\u7406\u5c3a\u5bf8\u81f3\u5c11\u662f\u8fd9\u4e2a\u6570\u7ec4\u5efa\u7acb\u65f6\u9ed8\u8ba4\u5bb9\u91cf\u76842\u500d\u65f6 \u5219\u628a\u6570\u7ec4\u7684\u7269\u7406\u5c3a\u5bf8\u51cf\u5c0f\u5230\u539f\u6765\u7684\u4e00\u534a\uff0c\u5e76\u4e14\u4e5f\u4e0d\u4f1a\u5c0f\u4e8e\u5176\u9ed8\u8ba4\u5bb9\u91cf \"\"\" # \u5728\u903b\u8f91\u5c3a\u5bf8\u548c\u7269\u7406\u5c3a\u5bf8\u7684\u4e00\u534a\u4e4b\u95f4\u9009\u62e9\u6700\u5927\u503c\u4f5c\u4e3a\u6570\u7ec4\u6536\u7f29\u540e\u7684\u7269\u7406\u5c3a\u5bf8 newSize = max ( self . capacity , len ( self ) // 2 ) # \u91ca\u653e\u591a\u4f59\u7684\u6570\u7ec4\u7a7a\u95f4 for count in range ( len ( self ) - newSize ): self . items . pop () def pop ( self , index ): \"\"\" \u5220\u9664\u6307\u5b9a\u7d22\u5f15\u503c\u7684\u6570\u7ec4\u5143\u7d20,\u5e76\u8fd4\u56de\u5220\u9664\u7684\u6570\u7ec4\u5143\u7d20\u503c \u5148\u51b3\u6761\u4ef6: 0 <= index < size() \"\"\" if index < 0 or index >= self . size (): raise IndexError ( \"\u5220\u9664\u64cd\u4f5c\u51fa\u9519, \u6570\u7ec4\u7d22\u5f15\u8d8a\u754c(\u4e0d\u5728\u6570\u7ec4\u903b\u8f91\u8fb9\u754c\u8303\u56f4\u5185)\" ) # \u4fdd\u5b58\u5373\u5c06\u88ab\u5220\u9664\u7684\u6570\u7ec4\u5143\u7d20\u503c itemToReturn = self . items [ index ] # \u5c06\u6570\u7ec4\u5143\u7d20\u5411\u5934\u90e8\u5e73\u79fb\u4e00\u4e2a\u4f4d\u7f6e for i in range ( index , self . size () - 1 ): self . items [ i ] = self . items [ i + 1 ] # \u5c06\u6570\u7ec4\u5c3e\u90e8\u7684\u7a7a\u4f59\u4f4d\u8d4b\u503cfillValue\uff0c\u9ed8\u8ba4\u662fNone self . items [ self . size () - 1 ] = self . fillValue # \u51cf\u5c11\u6570\u7ec4\u903b\u8f91\u5c3a\u5bf8 self . logicalSize -= 1 # \u51cf\u5c11\u6570\u7ec4\u7269\u7406\u5c3a\u5bf8 # \u5f53: # - \u6570\u7ec4\u7684\u903b\u8f91\u5c3a\u5bf8\u5c0f\u4e8e\u6216\u7b49\u4e8e\u5176\u7269\u7406\u5c3a\u5bf8\u76841/4 # - \u5e76\u4e14\u5b83\u7684\u7269\u7406\u5c3a\u5bf8\u81f3\u5c11\u662f\u8fd9\u4e2a\u6570\u7ec4\u5efa\u7acb\u65f6\u9ed8\u8ba4\u5bb9\u91cf\u76842\u500d\u65f6 # \u5219\u628a\u6570\u7ec4\u7684\u7269\u7406\u5c3a\u5bf8\u51cf\u5c0f\u5230\u539f\u6765\u7684\u4e00\u534a\uff0c\u5e76\u4e14\u4e5f\u4e0d\u4f1a\u5c0f\u4e8e\u5176\u9ed8\u8ba4\u5bb9\u91cf if self . size () <= len ( self ) // 4 and len ( self ) > self . capacity : self . shrink () # \u8fd4\u56de\u88ab\u5220\u9664\u5143\u7d20\u7684\u503c print ( f 'Item { itemToReturn } was deleted' ) return itemToReturn def main (): # \u521d\u59cb\u5316\u7a7a\u6570\u7ec4 DEFAULT_CAPACITY = 5 my_arr = Array ( DEFAULT_CAPACITY ) # \u6253\u5370\u8f93\u51fa\u6570\u7ec4\u521d\u59cb\u4fe1\u606f print ( \"Physical size:\" , len ( my_arr )) print ( \"Logical size:\" , my_arr . size ()) print ( \"Initial items:\" , my_arr . items ) # \u521d\u59cb\u5316\u6570\u7ec4\u5143\u7d20 print ( '------' ) for item in range ( 4 ): my_arr . insert ( 0 , item ) # \u5728\u6570\u7ec4\u5934\u90e8\u63d2\u5165\uff0c\u6bcf\u63d2\u5165\u4e00\u6b21\u90fd\u9700\u8981\u5411\u540e\u79fb\u52a8\u5df2\u6709\u6570\u7ec4\u5143\u7d20 print ( \"Items(logical):\" , my_arr ) print ( \"Items(physical):\" , my_arr . items ) # \u5728\u6570\u7ec4\u4e2d\u95f4\u63d2\u5165\u65b0\u5143\u7d20 print ( '------' ) my_arr . insert ( 3 , 99 ) print ( \"Items(logical):\" , my_arr ) print ( \"Items(physical):\" , my_arr . items ) # \u5728\u6570\u7ec4\u903b\u8f91\u5c3a\u5bf8\u5916\u63d2\u5165\u65b0\u5143\u7d20 print ( '------' ) my_arr . insert ( 20 , 88 ) print ( \"Items(logical):\" , my_arr ) print ( \"Items(physical):\" , my_arr . items ) # \u5220\u9664\u6570\u7ec4\u5143\u7d20 print ( '------' ) my_arr . pop ( 3 ) my_arr . pop ( 3 ) print ( \"Items(logical):\" , my_arr ) print ( \"Items(physical):\" , my_arr . items ) # \u6e05\u7a7a\u6570\u7ec4\u5143\u7d20 print ( '------' ) for count in range ( my_arr . size ()): my_arr . pop ( 0 ) print ( \"Items(logical):\" , my_arr ) print ( \"Items(physical):\" , my_arr . items ) # \u6570\u7ec4\u5143\u7d20\u5df2\u7ecf\u5168\u90e8\u5220\u9664\uff0c\u903b\u8f91\u5c3a\u5bf8\u4e3a\u96f6\uff0c\u4e0b\u9762\u547d\u4ee4\u8fd4\u56de\u9519\u8bef # print('------') # print(my_arr.pop(0)) # \u6570\u7ec4\u6bd4\u8f83 # \u521d\u59cb\u5316\u6570\u7ec4 print ( '------' ) arr_a = Array ( 5 ) for item in range ( 4 ): arr_a . insert ( 0 , item ) arr_b = arr_a arr_c = Array ( 5 ) for item in range ( 4 ): arr_c . insert ( 0 , item ) arr_d = [] print ( \"arr_a(physical):\" , arr_a . items ) print ( \"arr_b(physical):\" , arr_b . items ) print ( \"arr_c(physical):\" , arr_c . items ) print ( \"arr_d(physical):\" , arr_d ) print ( \"arr_a == arr_b:\" , arr_a == arr_b ) print ( \"arr_a is arr_b:\" , arr_a is arr_b ) print ( \"arr_a == arr_c:\" , arr_a == arr_c ) print ( \"arr_a is arr_c:\" , arr_a is arr_c ) arr_c . insert ( 10 , 10 ) print ( \"arr_a == arr_c:\" , arr_a == arr_c ) arr_c . pop ( arr_c . size () - 1 ) arr_c [ 2 ] = 6 print ( \"arr_a == arr_c:\" , arr_a == arr_c ) print ( \"arr_a == arr_d:\" , arr_a == arr_d ) if __name__ == \"__main__\" : main () # \u8fd0\u884c\u7ed3\u679c # Physical size: 5 # Logical size: 0 # Initial items: [None, None, None, None, None] # ------ # Items(logical): 3 2 1 0 # Items(physical): [3, 2, 1, 0, None] # ------ # Items(logical): 3 2 1 99 0 # Items(physical): [3, 2, 1, 99, 0] # ------ # Items(logical): 3 2 1 99 0 88 # Items(physical): [3, 2, 1, 99, 0, 88, None, None, None, None] # ------ # Item 99 was deleted # Item 0 was deleted # Items(logical): 3 2 1 88 # Items(physical): [3, 2, 1, 88, None, None, None, None, None, None] # ------ # Item 3 was deleted # Item 2 was deleted # Item 1 was deleted # Item 88 was deleted # Items(logical): # Items(physical): [None, None, None, None, None] # ------ # IndexError: \u5220\u9664\u64cd\u4f5c\u51fa\u9519, \u6570\u7ec4\u7d22\u5f15\u8d8a\u754c(\u4e0d\u5728\u6570\u7ec4\u903b\u8f91\u8fb9\u754c\u8303\u56f4\u5185) # ------ # arr_a(physical): [3, 2, 1, 0, None] # arr_b(physical): [3, 2, 1, 0, None] # arr_c(physical): [3, 2, 1, 0, None] # arr_d(physical): [] # arr_a == arr_b: True # arr_a is arr_b: True # arr_a == arr_c: True # arr_a is arr_c: False # arr_a == arr_c: False # Item 10 was deleted # arr_a == arr_c: False # arr_a == arr_d: False","title":"4.2.\u6570\u7ec4\u7684\u64cd\u4f5c"},{"location":"python/DataStructure/04_ArrayChain/#421","text":"\u5f53\u6570\u7ec4\u7684\u903b\u8f91\u5c3a\u5bf8\u7b49\u4e8e\u5b83\u7684\u7269\u7406\u5c3a\u5bf8\u65f6\uff0c\u5982\u679c\u8981\u63d2\u5165\u65b0\u7684\u5143\u7d20\uff0c\u5c31\u9700\u8981\u589e\u5927\u6570\u7ec4\u7684\u7269\u7406\u5c3a\u5bf8\u3002 \u5982\u679c\u9700\u8981\u4e3a\u6570\u7ec4\u63d0\u4f9b\u66f4\u591a\u5185\u5b58\uff0cPython\u7684list\u7c7b\u578b\u4f1a\u5728\u8c03\u7528insert\u6216append\u65b9\u6cd5\u65f6\u6267\u884c\u8fd9\u4e2a\u64cd\u4f5c\u3002 \u8c03\u6574\u6570\u7ec4\u7269\u7406\u5c3a\u5bf8\u7684\u8fc7\u7a0b\u5305\u542b\u5982\u4e0b3\u4e2a\u6b65\u9aa4\u3002 \u521b\u5efa\u4e00\u4e2a\u66f4\u5927\u7684\u65b0\u6570\u7ec4\u3002 \u5c06\u6570\u636e\u4ece\u65e7\u6570\u7ec4\u4e2d\u590d\u5236\u5230\u65b0\u6570\u7ec4\u3002 \u5c06\u6307\u5411\u65e7\u6570\u7ec4\u7684\u53d8\u91cf\u6307\u5411\u65b0\u6570\u7ec4\u5bf9\u8c61\u3002 \u4e0b\u9762\u4ee3\u7801\u5b9e\u73b0\u3002 # \u589e\u5927\u6570\u7ec4\u7269\u7406\u5c3a\u5bf8 if logicalSize == len ( my_array ): temp = Array ( len ( my_array ) + 1 ) # \u521b\u5efa\u4e00\u4e2a\u65b0\u6570\u7ec4 for i in range ( logicalSize ): temp [ i ] = my_array [ i ] # \u4ece\u539f\u6570\u7ec4\u590d\u5236\u5185\u5bb9\u5230\u65b0\u6570\u7ec4 my_array = temp # \u628a\u65b0\u6570\u7ec4\u8d4b\u503c\u7ed9\u539f\u6570\u7ec4 \u5728\u4e0a\u9762\u4ee3\u7801\u4e2d\uff0c\u901a\u8fc7 temp[i] = my_array[i] \u6765\u8c03\u6574\u6570\u7ec4\u5c3a\u5bf8\uff0c\u8fd9\u4e2a\u590d\u5236\u64cd\u4f5c\u7684\u6570\u91cf\u662f\u7ebf\u6027\u589e\u957f\u7684\u3002\u56e0\u6b64\uff0c\u5c06 n \u4e2a\u5143\u7d20\u6dfb\u52a0\u5230\u6570\u7ec4\u91cc\u7684\u603b\u65f6\u95f4\u590d\u6742\u5ea6\u662f 1+2+3...+n \uff0c\u4e5f\u5c31\u662f n(n+1)/2 \uff0c\u56e0\u6b64\u662f O(n^2) \u3002 \u5728\u4e0a\u9762\u7684\u4ee3\u7801\u4e2d\uff0c\u901a\u8fc7 temp = Array(len(my_array) + 1) \u5bf9\u6570\u7ec4\u8fdb\u884c\u52a8\u6001\u6269\u5c55\uff0c\u5bf9\u6027\u80fd\u4f1a\u4ea7\u751f\u4e00\u4e9b\u53ef\u80fd\u7684\u5f71\u54cd\uff1a \u65f6\u95f4\u590d\u6742\u5ea6\uff1a\u52a8\u6001\u6269\u5c55\u6570\u7ec4\u901a\u5e38\u9700\u8981\u590d\u5236\u73b0\u6709\u6570\u636e\u5230\u65b0\u7684\u5185\u5b58\u4f4d\u7f6e\uff0c\u8fd9\u5c06\u6d89\u53ca\u5230\u5143\u7d20\u7684\u590d\u5236\u64cd\u4f5c\u3002\u8fd9\u4e9b\u64cd\u4f5c\u7684\u65f6\u95f4\u590d\u6742\u5ea6\u53d6\u51b3\u4e8e\u6570\u7ec4\u7684\u957f\u5ea6\uff0c\u901a\u5e38\u662f O(n) \uff0c\u5176\u4e2d n \u662f\u6570\u7ec4\u7684\u957f\u5ea6\u3002\u56e0\u6b64\uff0c\u5f53\u6570\u7ec4\u9700\u8981\u6269\u5c55\u65f6\uff0c\u53ef\u80fd\u4f1a\u4ea7\u751f\u4e00\u4e9b\u989d\u5916\u7684\u65f6\u95f4\u5f00\u9500\u3002 \u7a7a\u95f4\u590d\u6742\u5ea6\uff1a\u52a8\u6001\u6269\u5c55\u6570\u7ec4\u4f1a\u5360\u7528\u989d\u5916\u7684\u5185\u5b58\u7a7a\u95f4\uff0c\u56e0\u4e3a\u9700\u8981\u5206\u914d\u65b0\u7684\u5185\u5b58\u5757\u6765\u5bb9\u7eb3\u6269\u5c55\u540e\u7684\u6570\u7ec4\u3002\u8fd9\u53ef\u80fd\u4f1a\u5bfc\u81f4\u5185\u5b58\u788e\u7247\u5316\uff0c\u7279\u522b\u662f\u5728\u9891\u7e41\u6269\u5c55\u548c\u7f29\u5c0f\u6570\u7ec4\u65f6\u3002 \u6269\u5c55\u9891\u7387\uff1a\u6269\u5c55\u6570\u7ec4\u7684\u9891\u7387\u4f1a\u5f71\u54cd\u6027\u80fd\u3002\u5982\u679c\u6570\u7ec4\u9700\u8981\u9891\u7e41\u6269\u5c55\uff0c\u90a3\u4e48\u590d\u5236\u548c\u5185\u5b58\u5206\u914d\u7684\u5f00\u9500\u4f1a\u66f4\u52a0\u663e\u8457\uff0c\u4ece\u800c\u964d\u4f4e\u6027\u80fd\u3002\u56e0\u6b64\uff0c\u5728\u8bbe\u8ba1\u6570\u636e\u7ed3\u6784\u65f6\uff0c\u901a\u5e38\u4f1a\u8003\u8651\u521d\u59cb\u5bb9\u91cf\u548c\u6269\u5c55\u7b56\u7565\uff0c\u4ee5\u51cf\u5c11\u4e0d\u5fc5\u8981\u7684\u6269\u5c55\u6b21\u6570\u3002 Amortized Analysis\uff1a\u4e00\u4e9b\u6570\u636e\u7ed3\u6784\uff0c\u4f8b\u5982Python\u7684\u5217\u8868\uff08list\uff09\uff0c\u91c7\u7528\u644a\u8fd8\u5206\u6790\u6765\u5e73\u644a\u52a8\u6001\u6269\u5c55\u7684\u5f00\u9500\u3002\u8fd9\u610f\u5473\u7740\u867d\u7136\u67d0\u4e9b\u64cd\u4f5c\u53ef\u80fd\u4f1a\u82b1\u8d39 O(n) \u7684\u65f6\u95f4\uff0c\u4f46\u8fd9\u4e9b\u5f00\u9500\u5728\u4e00\u7cfb\u5217\u64cd\u4f5c\u4e2d\u88ab\u5206\u644a\uff0c\u5e73\u5747\u4e0b\u6765\u4ecd\u7136\u4fdd\u6301\u8f83\u4f4e\u7684\u590d\u6742\u5ea6\u3002\u8fd9\u53ef\u4ee5\u5728\u4e00\u5b9a\u7a0b\u5ea6\u4e0a\u7f13\u89e3\u6027\u80fd\u95ee\u9898\u3002 \u52a8\u6001\u6269\u5c55\u6570\u7ec4\u4f1a\u5f15\u5165\u4e00\u4e9b\u6027\u80fd\u5f00\u9500\uff0c\u4f46\u5728\u5b9e\u9645\u5e94\u7528\u4e2d\uff0c\u8fd9\u79cd\u5f00\u9500\u901a\u5e38\u662f\u53ef\u4ee5\u63a5\u53d7\u7684\u3002\u4e3a\u4e86\u4f18\u5316\u6027\u80fd\uff0c\u53ef\u4ee5\u8003\u8651\u4ee5\u4e0b\u51e0\u70b9\u7b56\u7565\uff0c\u9700\u8981\u6839\u636e\u5177\u4f53\u5e94\u7528\u7684\u9700\u6c42\u548c\u6027\u80fd\u8981\u6c42\u6765\u6743\u8861\u8fd9\u4e9b\u56e0\u7d20\uff1a \u9884\u5148\u5206\u914d\u8db3\u591f\u7684\u521d\u59cb\u5bb9\u91cf\uff0c\u4ee5\u51cf\u5c11\u6269\u5c55\u7684\u9891\u7387\u3002 \u4f7f\u7528\u644a\u8fd8\u5206\u6790\u6765\u5e73\u644a\u5f00\u9500\u3002 \u8003\u8651\u4f7f\u7528\u5176\u4ed6\u6570\u636e\u7ed3\u6784\uff0c\u5982\u94fe\u8868\uff0c\u5bf9\u63d2\u5165\u548c\u5220\u9664\u64cd\u4f5c\u7684\u6027\u80fd\u66f4\u52a0\u53cb\u597d\u3002 \u4e0b\u9762\uff0c\u5c1d\u8bd5\u5728\u6bcf\u6b21\u589e\u5927\u6570\u7ec4\u5c3a\u5bf8\u65f6\u628a\u6570\u7ec4\u5c3a\u5bf8\u7ffb\u500d\uff0c\u4ee3\u7801\u5b9e\u73b0\u5982\u4e0b\uff1a # \u589e\u5927\u6570\u7ec4\u7269\u7406\u5c3a\u5bf8 while logicalSize < DEFAULT_CAPACITY * 2 : logicalSize += 1 if logicalSize == len ( my_array ): # \u89e6\u53d1\u6761\u4ef6 temp = Array ( len ( my_array ) + 1 ) # \u521b\u5efa\u4e00\u4e2a\u65b0\u6570\u7ec4 for i in range ( logicalSize ): temp [ i ] = my_array [ i ] # \u4ece\u539f\u6570\u7ec4\u590d\u5236\u5185\u5bb9\u5230\u65b0\u6570\u7ec4 my_array = temp # \u628a\u65b0\u6570\u7ec4\u8d4b\u503c\u7ed9\u539f\u6570\u7ec4 \u5c06\u6570\u7ec4\u5c3a\u5bf8\u7ffb\u500d\u6765\u6269\u5c55\u6570\u7ec4\u7684\u65b9\u5f0f\u662f\u4e00\u79cd\u5e38\u89c1\u7684\u7b56\u7565\uff0c\u901a\u5e38\u7528\u4e8e\u51cf\u5c11\u52a8\u6001\u6570\u7ec4\u7684\u9891\u7e41\u6269\u5c55\u6b21\u6570\uff0c\u4ee5\u63d0\u9ad8\u6027\u80fd\u3002\u8fd9\u79cd\u65b9\u5f0f\u7684\u64cd\u4f5c\u65f6\u95f4\u590d\u6742\u5ea6\u4e3b\u8981\u53d6\u51b3\u4e8e\u6269\u5c55\u64cd\u4f5c\u7684\u9891\u7387\u548c\u5143\u7d20\u7684\u590d\u5236\u6210\u672c\u3002 \u644a\u8fd8\u5206\u6790\uff1a\u5bf9\u4e8e\u5c06\u6570\u7ec4\u5c3a\u5bf8\u7ffb\u500d\u7684\u7b56\u7565\uff0c\u644a\u8fd8\u5206\u6790\u8868\u660e\uff0c\u6bcf\u6b21\u6269\u5c55\u64cd\u4f5c\u7684\u644a\u8fd8\u65f6\u95f4\u590d\u6742\u5ea6\u4ecd\u7136\u662f\u5e38\u6570\u65f6\u95f4\u7684\uff08\u901a\u5e38\u662fO(1)\uff09\uff0c\u8fd9\u610f\u5473\u7740\u5e73\u5747\u4e0b\u6765\uff0c\u6bcf\u6b21\u6269\u5c55\u7684\u5f00\u9500\u662f\u56fa\u5b9a\u7684\uff0c\u800c\u4e0d\u4f1a\u968f\u6570\u7ec4\u7684\u5927\u5c0f\u7ebf\u6027\u589e\u52a0\u3002 \u64cd\u4f5c\u65f6\u95f4\uff1a\u5047\u8bbe\u6570\u7ec4\u9700\u8981\u6269\u5c55\uff0c\u90a3\u4e48\u5c06\u6570\u7ec4\u5c3a\u5bf8\u7ffb\u500d\u9700\u8981\u5206\u914d\u65b0\u7684\u5185\u5b58\u5757\u5e76\u590d\u5236\u73b0\u6709\u5143\u7d20\uff0c\u8fd9\u4e2a\u64cd\u4f5c\u7684\u65f6\u95f4\u590d\u6742\u5ea6\u662fO(n)\uff0c\u5176\u4e2dn\u662f\u6570\u7ec4\u7684\u5f53\u524d\u5927\u5c0f\u3002\u7136\u800c\uff0c\u7531\u4e8e\u6269\u5c55\u64cd\u4f5c\u4e0d\u662f\u6bcf\u6b21\u90fd\u6267\u884c\u7684\uff0c\u800c\u662f\u5f53\u6570\u7ec4\u5df2\u6ee1\u65f6\u624d\u6267\u884c\uff0c\u56e0\u6b64\u53ef\u4ee5\u8ba4\u4e3a\u8fd9\u4e2a\u64cd\u4f5c\u7684\u644a\u8fd8\u65f6\u95f4\u662f\u5e38\u6570\u65f6\u95f4\uff0c\u5373O(1)\u3002 \u7a7a\u95f4\u590d\u6742\u5ea6\uff1a\u5c06\u6570\u7ec4\u5c3a\u5bf8\u7ffb\u500d\u4f1a\u5360\u7528\u989d\u5916\u7684\u5185\u5b58\u7a7a\u95f4\uff0c\u4f46\u968f\u7740\u6570\u7ec4\u7684\u589e\u957f\uff0c\u989d\u5916\u5185\u5b58\u7684\u5360\u7528\u76f8\u5bf9\u4e8e\u6570\u7ec4\u672c\u8eab\u7684\u5927\u5c0f\u6765\u8bf4\u662f\u6709\u9650\u7684\u3002\u901a\u5e38\u60c5\u51b5\u4e0b\uff0c\u8fd9\u79cd\u5360\u7528\u53ef\u4ee5\u63a5\u53d7\u3002 \u603b\u7ed3\uff0c\u5c06\u6570\u7ec4\u5c3a\u5bf8\u7ffb\u500d\u7684\u7b56\u7565\u53ef\u4ee5\u663e\u8457\u51cf\u5c11\u52a8\u6001\u6570\u7ec4\u7684\u6269\u5c55\u6b21\u6570\uff0c\u4ece\u800c\u63d0\u9ad8\u6027\u80fd\u3002\u867d\u7136\u6bcf\u6b21\u6269\u5c55\u64cd\u4f5c\u53ef\u80fd\u4f1a\u82b1\u8d39\u4e00\u4e9b\u65f6\u95f4\u548c\u989d\u5916\u5185\u5b58\uff0c\u4f46\u8fd9\u4e9b\u5f00\u9500\u5728\u4e00\u7cfb\u5217\u64cd\u4f5c\u4e2d\u88ab\u5e73\u644a\uff0c\u5e73\u5747\u4e0b\u6765\u662f\u5e38\u6570\u65f6\u95f4\u3002\u8fd9\u662f\u4e00\u79cd\u9ad8\u6548\u7684\u52a8\u6001\u6570\u7ec4\u5b9e\u73b0\u65b9\u5f0f\uff0c\u5e38\u89c1\u4e8e\u8bb8\u591a\u7f16\u7a0b\u8bed\u8a00\u7684\u6807\u51c6\u5e93\u4e2d\uff0c\u5305\u62ecPython\u7684\u5217\u8868\uff08list\uff09\u3002 \u5728\u589e\u52a0\u6570\u7ec4\u7684\u957f\u5ea6\u65f6\uff0c\u6bcf\u6b21\u589e\u52a0\u4e00\u4e2a\u5185\u5b58\u5355\u5143\uff0c\u4e0e\u6bcf\u6b21\u589e\u5927\u6570\u7ec4\u5c3a\u5bf8\u65f6\u628a\u6570\u7ec4\u5c3a\u5bf8\u7ffb\u500d\u76f8\u6bd4\uff0c\u540e\u8005\u7684\u65b9\u6cd5\u901a\u5e38\u66f4\u9ad8\u6548\u3002 \u6bcf\u6b21\u589e\u52a0\u4e00\u4e2a\u5185\u5b58\u5355\u5143\uff1a\u8fd9\u79cd\u65b9\u5f0f\u5728\u6bcf\u6b21\u6dfb\u52a0\u65b0\u5143\u7d20\u65f6\u90fd\u9700\u8981\u5206\u914d\u989d\u5916\u7684\u5185\u5b58\uff0c\u5bfc\u81f4\u6570\u7ec4\u5c3a\u5bf8\u7684\u589e\u957f\u662f\u7ebf\u6027\u7684\u3002\u5982\u679c\u9891\u7e41\u6dfb\u52a0\u5143\u7d20\uff0c\u8fd9\u5c06\u5bfc\u81f4\u5927\u91cf\u7684\u5185\u5b58\u5206\u914d\u548c\u6570\u636e\u590d\u5236\u64cd\u4f5c\uff0c\u56e0\u6b64\u65f6\u95f4\u590d\u6742\u5ea6\u4f1a\u53d8\u5f97\u76f8\u5bf9\u8f83\u9ad8\u3002 \u6bcf\u6b21\u589e\u5927\u6570\u7ec4\u5c3a\u5bf8\u65f6\u628a\u6570\u7ec4\u5c3a\u5bf8\u7ffb\u500d\uff1a\u8fd9\u662f\u4e00\u79cd\u66f4\u9ad8\u6548\u7684\u7b56\u7565\u3002\u5728\u8fd9\u79cd\u65b9\u5f0f\u4e0b\uff0c\u6bcf\u6b21\u6269\u5c55\u64cd\u4f5c\u90fd\u4f1a\u589e\u52a0\u6570\u7ec4\u7684\u5c3a\u5bf8\uff0c\u4f46\u589e\u5e45\u662f\u6307\u6570\u7ea7\u7684\uff0c\u800c\u4e0d\u662f\u7ebf\u6027\u7684\u3002\u8fd9\u610f\u5473\u7740\u968f\u7740\u6570\u7ec4\u7684\u589e\u957f\uff0c\u6269\u5c55\u64cd\u4f5c\u7684\u9891\u7387\u4f1a\u51cf\u5c11\uff0c\u56e0\u4e3a\u6570\u7ec4\u80fd\u591f\u5bb9\u7eb3\u66f4\u591a\u5143\u7d20\u3002\u8fd9\u6837\uff0c\u867d\u7136\u6bcf\u6b21\u6269\u5c55\u64cd\u4f5c\u9700\u8981\u590d\u5236\u66f4\u591a\u7684\u5143\u7d20\uff0c\u4f46\u5b83\u4eec\u7684\u644a\u8fd8\u65f6\u95f4\u590d\u6742\u5ea6\u4ecd\u7136\u662f\u5e38\u6570\u65f6\u95f4\uff0c\u56e0\u4e3a\u5b83\u4eec\u4e0d\u662f\u6bcf\u6b21\u90fd\u6267\u884c\u7684\u3002 \u603b\u7ed3\uff0c\u5c06\u6570\u7ec4\u5c3a\u5bf8\u7ffb\u500d\u7684\u7b56\u7565\u901a\u5e38\u66f4\u9ad8\u6548\uff0c\u56e0\u4e3a\u5b83\u53ef\u4ee5\u51cf\u5c11\u9891\u7e41\u7684\u5185\u5b58\u5206\u914d\u548c\u590d\u5236\u64cd\u4f5c\uff0c\u964d\u4f4e\u4e86\u65f6\u95f4\u590d\u6742\u5ea6\u3002\u8fd9\u662f\u8bb8\u591a\u52a8\u6001\u6570\u7ec4\u5b9e\u73b0\u7684\u5e38\u89c1\u505a\u6cd5\uff0c\u5305\u62ecPython\u7684\u5217\u8868\uff08list\uff09\u3002 \u5728 Array \u7c7b\u5b9e\u73b0\u4e2d\uff0c\u662f\u901a\u8fc7\u4e0b\u9762\u4ee3\u7801\u6bb5\u5b9e\u73b0\u7684\u6570\u7ec4\u7269\u7406\u5c3a\u5bf8\u589e\u52a0\u7684\uff0c\u5373\u5c06\u6570\u7ec4\u5c3a\u5bf8\u7ffb\u500d\u3002 def grow ( self ): \"\"\"\u589e\u5927\u6570\u7ec4\u7269\u7406\u5c3a\u5bf8\"\"\" # \u57fa\u4e8e\u5f53\u524d\u7269\u7406\u5c3a\u5bf8\u52a0\u500d\uff0c\u5e76\u5c06fillValue\u8d4b\u503c\u5e95\u5c42\u5217\u8868\u7684\u65b0\u5143\u7d20 for count in range ( len ( self )): self . items . append ( self . fillValue )","title":"4.2.1.\u589e\u5927\u6570\u7ec4\u7684\u5c3a\u5bf8"},{"location":"python/DataStructure/04_ArrayChain/#422","text":"\u5982\u679c\u51cf\u5c0f\u6570\u7ec4\u7684\u903b\u8f91\u5c3a\u5bf8\uff0c\u5c31\u4f1a\u6d6a\u8d39\u76f8\u5e94\u7684\u5185\u5b58\u5355\u5143\u3002\u56e0\u6b64\uff0c\u5f53\u5220\u9664\u67d0\u4e00\u4e2a\u5143\u7d20\uff0c\u5982\u679c\u672a\u4f7f\u7528\u7684\u5185\u5b58\u5355\u5143\u6570\u8fbe\u5230\u6216\u8d85\u8fc7\u4e86\u67d0\u4e2a\u9608\u503c\uff08\u5982\u6570\u7ec4\u7269\u7406\u5c3a\u5bf8\u7684\u00be\uff09\u65f6\uff0c\u5219\u5e94\u8be5\u51cf\u5c0f\u7269\u7406\u5c3a\u5bf8\u4e86\u3002\u5982\u679c\u6d6a\u8d39\u7684\u5185\u5b58\u8d85\u8fc7\u7279\u5b9a\u9608\u503c\uff0c\u90a3\u4e48Python\u7684list\u7c7b\u578b\u4f1a\u5728\u8c03\u7528 pop \u65b9\u6cd5\u65f6\u6267\u884c\u51cf\u5c0f\u6570\u7ec4\u7269\u7406\u5c3a\u5bf8\u7684\u64cd\u4f5c\u3002 \u51cf\u5c0f\u6570\u7ec4\u5c3a\u5bf8\u7684\u8fc7\u7a0b\u4e0e\u589e\u5927\u6570\u7ec4\u5c3a\u5bf8\u7684\u8fc7\u7a0b\u76f8\u53cd\uff0c\u6b65\u9aa4\u5982\u4e0b\uff1a \u521b\u5efa\u4e00\u4e2a\u66f4\u5c0f\u7684\u65b0\u6570\u7ec4\u3002 \u5c06\u6570\u636e\u4ece\u65e7\u6570\u7ec4\u4e2d\u590d\u5236\u5230\u65b0\u6570\u7ec4\u3002 \u5c06\u6307\u5411\u65e7\u6570\u7ec4\u7684\u53d8\u91cf\u6307\u5411\u65b0\u6570\u7ec4\u5bf9\u8c61\u3002 \u4e0b\u9762\u7684\u4ee3\u7801\u5b9e\u73b0\u4e86\u51cf\u5c0f\u6570\u7ec4\u5c3a\u5bf8\u3002 \u5f53\u6570\u7ec4\u7684\u903b\u8f91\u5c3a\u5bf8\u5c0f\u4e8e\u6216\u7b49\u4e8e\u5176\u7269\u7406\u5c3a\u5bf8\u7684\u00bc\uff0c\u5e76\u4e14\u5b83\u7684\u7269\u7406\u5c3a\u5bf8\u81f3\u5c11\u662f\u8fd9\u4e2a\u6570\u7ec4\u5efa\u7acb\u65f6\u9ed8\u8ba4\u5bb9\u91cf\u76842\u500d\u65f6\uff0c\u5219\u4e0b\u9762\u7684\u7b97\u6cd5\u628a\u6570\u7ec4\u7684\u7269\u7406\u5c3a\u5bf8\u51cf\u5c0f\u5230\u539f\u6765\u7684\u4e00\u534a\uff0c\u5e76\u4e14\u4e5f\u4e0d\u4f1a\u5c0f\u4e8e\u5176\u9ed8\u8ba4\u5bb9\u91cf\u3002 # \u51cf\u5c0f\u6570\u7ec4\u7269\u7406\u5c3a\u5bf8 while logicalSize > len ( my_array ) // 4 : logicalSize -= 1 if logicalSize <= len ( my_array ) // 4 and len ( my_array ) >= DEFAULT_CAPACITY * 2 : # \u89e6\u53d1\u6761\u4ef6 temp = Array ( len ( my_array ) // 2 ) # \u521b\u5efa\u4e00\u4e2a\u65b0\u6570\u7ec4 for i in range ( logicalSize ): temp [ i ] = my_array [ i ] # \u4ece\u539f\u6570\u7ec4\u590d\u5236\u5185\u5bb9\u5230\u65b0\u6570\u7ec4 my_array = temp # \u628a\u65b0\u6570\u7ec4\u8d4b\u503c\u7ed9\u539f\u6570\u7ec4 \u6309\u7167\u4e0a\u9762\u7b97\u6cd5\u51cf\u5c11\u6570\u7ec4\u7684\u5c3a\u5bf8\uff0c\u6211\u4eec\u53ef\u4ee5\u5206\u6790\u5176\u65f6\u95f4\u548c\u7a7a\u95f4\u590d\u6742\u5ea6\u5982\u4e0b\uff1a \u65f6\u95f4\u590d\u6742\u5ea6\uff1a\u4e3b\u8981\u6d89\u53ca\u4e24\u4e2a\u64cd\u4f5c\uff1a \u521b\u5efa\u65b0\u6570\u7ec4\u5e76\u5c06\u5143\u7d20\u4ece\u65e7\u6570\u7ec4\u590d\u5236\u5230\u65b0\u6570\u7ec4\uff1b \u5c06\u65e7\u6570\u7ec4\u5f15\u7528\u66f4\u6539\u4e3a\u65b0\u6570\u7ec4\u3002 \u590d\u5236\u64cd\u4f5c\u7684\u65f6\u95f4\u590d\u6742\u5ea6\u53d6\u51b3\u4e8e\u6570\u7ec4\u7684\u7269\u7406\u5c3a\u5bf8\uff0c\u53ef\u4ee5\u8868\u793a\u4e3a O(n) \uff0c\u5176\u4e2d n \u662f\u6570\u7ec4\u7684\u5f53\u524d\u7269\u7406\u5c3a\u5bf8\u3002\u5f15\u7528\u66f4\u6539\u662f\u4e00\u4e2a\u5e38\u6570\u65f6\u95f4\u64cd\u4f5c\uff0c\u4e0d\u5f71\u54cd\u65f6\u95f4\u590d\u6742\u5ea6\u3002\u6240\u4ee5\uff0c\u6574\u4f53\u7684\u65f6\u95f4\u590d\u6742\u5ea6\u662f O(n) \u3002 \u7a7a\u95f4\u590d\u6742\u5ea6\uff1a\u7a7a\u95f4\u590d\u6742\u5ea6\u4e5f\u6d89\u53ca\u4e24\u4e2a\u65b9\u9762\uff1a \u521b\u5efa\u65b0\u6570\u7ec4\u7684\u5185\u5b58\u6d88\u8017\uff0c\u5176\u7a7a\u95f4\u590d\u6742\u5ea6\u662fO(N)\uff1b \u5f15\u7528\u66f4\u6539\u6240\u9700\u7684\u5e38\u6570\u989d\u5916\u7a7a\u95f4\uff0c\u901a\u5e38\u5ffd\u7565\u4e0d\u8ba1\u3002 \u6240\u4ee5\uff0c\u603b\u7684\u7a7a\u95f4\u590d\u6742\u5ea6\u662f O(n) \u3002 \u8fd9\u4e2a\u7b97\u6cd5\u7b56\u7565\u4f1a\u5728\u9002\u5f53\u7684\u65f6\u5019\u51cf\u5c0f\u6570\u7ec4\u7684\u7269\u7406\u5c3a\u5bf8\uff0c\u4ee5\u51cf\u5c11\u5185\u5b58\u5360\u7528\uff0c\u4f46\u4ecd\u7136\u4fdd\u6301\u7740\u6570\u7ec4\u7684\u52a8\u6001\u6027\u3002\u65f6\u95f4\u590d\u6742\u5ea6\u548c\u7a7a\u95f4\u590d\u6742\u5ea6\u90fd\u4e0e\u5f53\u524d\u6570\u7ec4\u7684\u7269\u7406\u5c3a\u5bf8\u6210\u7ebf\u6027\u5173\u7cfb\uff0c\u56e0\u6b64\u662f\u7ebf\u6027\u7684\uff0c\u8fd9\u662f\u4e00\u79cd\u6709\u6548\u7684\u7b56\u7565\u6765\u4f18\u5316\u5185\u5b58\u4f7f\u7528\u3002\u540c\u65f6\uff0c\u4fdd\u7559\u4e86\u4e00\u5b9a\u7684\u5197\u4f59\u7a7a\u95f4\uff0c\u4ee5\u907f\u514d\u9891\u7e41\u5730\u6269\u5c55\u548c\u7f29\u5c0f\u6570\u7ec4\uff0c\u4ece\u800c\u63d0\u9ad8\u4e86\u6027\u80fd\u3002 \u4e0b\u9762\u662f\u5728 Array \u7c7b\u4e2d\u5b9e\u73b0\u51cf\u5c0f\u6570\u7ec4\u7684\u7269\u7406\u5c3a\u5bf8\u7684\u4ee3\u7801\u3002 def shrink ( self ): \"\"\" \u51cf\u5c11\u6570\u7ec4\u7684\u7269\u7406\u5c3a\u5bf8 \u5f53: - \u6570\u7ec4\u7684\u903b\u8f91\u5c3a\u5bf8\u5c0f\u4e8e\u6216\u7b49\u4e8e\u5176\u7269\u7406\u5c3a\u5bf8\u76841/4 - \u5e76\u4e14\u5b83\u7684\u7269\u7406\u5c3a\u5bf8\u81f3\u5c11\u662f\u8fd9\u4e2a\u6570\u7ec4\u5efa\u7acb\u65f6\u9ed8\u8ba4\u5bb9\u91cf\u76842\u500d\u65f6 \u5219\u628a\u6570\u7ec4\u7684\u7269\u7406\u5c3a\u5bf8\u51cf\u5c0f\u5230\u539f\u6765\u7684\u4e00\u534a\uff0c\u5e76\u4e14\u4e5f\u4e0d\u4f1a\u5c0f\u4e8e\u5176\u9ed8\u8ba4\u5bb9\u91cf \"\"\" # \u5728\u903b\u8f91\u5c3a\u5bf8\u548c\u7269\u7406\u5c3a\u5bf8\u7684\u4e00\u534a\u4e4b\u95f4\u9009\u62e9\u6700\u5927\u503c\u4f5c\u4e3a\u6570\u7ec4\u6536\u7f29\u540e\u7684\u7269\u7406\u5c3a\u5bf8 newSize = max ( self . capacity , len ( self ) // 2 ) # \u91ca\u653e\u591a\u4f59\u7684\u6570\u7ec4\u7a7a\u95f4 for count in range ( len ( self ) - newSize ): self . items . pop ()","title":"4.2.2.\u51cf\u5c0f\u6570\u7ec4\u7684\u5c3a\u5bf8"},{"location":"python/DataStructure/04_ArrayChain/#423","text":"\u628a\u5143\u7d20\u63d2\u5165\u6570\u7ec4\u4e2d\u548c\u66ff\u6362\u6570\u7ec4\u91cc\u7684\u5143\u7d20\u662f\u4e0d\u4e00\u6837\u7684\u3002 \u66ff\u6362\u6570\u7ec4\u5143\u7d20\u65f6\uff0c\u5143\u7d20\u5df2\u5728\u4e00\u4e2a\u7ed9\u5b9a\u7684\u7d22\u5f15\u4f4d\u7f6e\uff0c\u5bf9\u8fd9\u4e2a\u4f4d\u7f6e\u8fdb\u884c\u7b80\u5355\u590d\u5236\u5373\u53ef\uff0c\u6570\u7ec4\u7684\u903b\u8f91\u5c3a\u5bf8\u5e76\u4e0d\u4f1a\u6539\u53d8\u3002 \u63d2\u5165\u6570\u7ec4\u5143\u7d20\u65f6\uff0c\u9700\u8981\u5b8c\u6210\u4e0b\u97624\u4e2a\u6b65\u9aa4\uff1a \u5728\u63d2\u5165\u5143\u7d20\u4e4b\u524d\u5148\u68c0\u67e5\u53ef\u4ee5\u4f7f\u7528\u7684\u7a7a\u95f4\uff0c\u6839\u636e\u9700\u8981\u6765\u589e\u5927\u6570\u7ec4\u7684\u7269\u7406\u5c3a\u5bf8\u3002 \u5c06\u6570\u7ec4\u91cc\u4ece\u903b\u8f91\u7ed3\u5c3e\u5230\u76ee\u6807\u7d22\u5f15\u7684\u6240\u6709\u5143\u7d20\u5411\u540e\u79fb\u52a8\u3002\u8fd9\u4e2a\u8fc7\u7a0b\u4f1a\u5728\u76ee\u6807\u7d22\u5f15\u4f4d\u7f6e\u5904\u4e3a\u65b0\u5143\u7d20\u7559\u4e0b\u4e00\u4e2a\u7a7a\u683c\u3002 \u5c06\u65b0\u5143\u7d20\u5206\u914d\u5230\u76ee\u6807\u7d22\u5f15\u4f4d\u7f6e\u3002 \u5c06\u903b\u8f91\u5c3a\u5bf8\u52a01\u3002 \u5b9e\u73b0\u7b97\u6cd5\uff1a # \u5f53\u6570\u7ec4\u7684\u7269\u7406\u5c3a\u5bf8\u548c\u903b\u8f91\u5c3a\u5bf8\u4e00\u6837\u65f6\uff0c\u5219\u589e\u52a0\u7269\u7406\u5c3a\u5bf8 # \u5c06\u6570\u7ec4\u5143\u7d20\u5411\u5c3e\u90e8\u5e73\u79fb\u4e00\u4e2a\u4f4d\u7f6e for i in range ( logicalSize , targetIndex , - 1 ): my_array [ i ] = my_array [ i - 1 ] # \u63d2\u5165\u65b0\u5143\u7d20\uff0c\u589e\u52a0\u6570\u7ec4\u7684\u903b\u8f91\u5c3a\u5bf8 my_array [ targetIndex ] = newItem logicalSize += 1 \u4e0b\u9762\u662f Array \u7c7b\u4e2d\u5b9e\u73b0\u63d2\u5165\u5143\u7d20\u7684\u65b9\u6cd5\u3002 def insert ( self , index , newItem ): \"\"\"\u5728\u6570\u7ec4\u6307\u5b9a\u7d22\u5f15\u5904\u63d2\u5165\u65b0\u5143\u7d20\"\"\" # \u5f53\u6570\u7ec4\u7684\u7269\u7406\u5c3a\u5bf8\u548c\u903b\u8f91\u5c3a\u5bf8\u4e00\u6837\u65f6\uff0c\u5219\u589e\u52a0\u7269\u7406\u5c3a\u5bf8 if self . size () == len ( self ): self . grow () # \u63d2\u5165\u65b0\u5143\u7d20 # \u5f53\u63d2\u5165\u4f4d\u7f6e\u5927\u4e8e\u6216\u7b49\u4e8e\u6700\u5927\u903b\u8f91\u4f4d\u7f6e\uff0c\u5219\u5728\u6570\u7ec4\u672b\u7aef\u63d2\u5165\u65b0\u5143\u7d20 # \u5f53\u63d2\u5165\u4f4d\u7f6e\u4ecb\u4e8e\u6570\u7ec4\u903b\u8f91\u4f4d\u7f6e\u7684\u4e2d\u95f4\uff0c\u5219\u4ece\u63d2\u5165\u4f4d\u7f6e\u8d77\u5c06\u5269\u4f59\u6570\u7ec4\u5143\u7d20\u5411\u5c3e\u90e8\u5e73\u79fb\u4e00\u4e2a\u4f4d\u7f6e if index >= self . size (): self . items [ self . size ()] = newItem else : index = max ( index , 0 ) # \u5c06\u6570\u7ec4\u5143\u7d20\u5411\u5c3e\u90e8\u5e73\u79fb\u4e00\u4e2a\u4f4d\u7f6e for i in range ( self . size (), index , - 1 ): self . items [ i ] = self . items [ i - 1 ] # \u63d2\u5165\u65b0\u5143\u7d20 self . items [ index ] = newItem # \u589e\u52a0\u6570\u7ec4\u7684\u903b\u8f91\u5c3a\u5bf8 self . logicalSize += 1","title":"4.2.3.\u5c06\u5143\u7d20\u63d2\u5165\u589e\u5927\u7684\u6570\u7ec4"},{"location":"python/DataStructure/04_ArrayChain/#424","text":"\u4ece\u6570\u7ec4\u91cc\u5220\u9664\u5143\u7d20\u7684\u6b65\u9aa4\u5982\u4e0b\uff0c\u548c\u63d2\u5165\u64cd\u4f5c\u4e00\u6837\uff0c\u5143\u7d20\u7684\u79fb\u52a8\u987a\u5e8f\u975e\u5e38\u91cd\u8981\u3002 \u5c06\u6570\u7ec4\u91cc\u4ece\u76ee\u6807\u7d22\u5f15\u5230\u903b\u8f91\u7ed3\u5c3e\u7684\u6240\u6709\u5143\u7d20\u5411\u524d\u79fb\u52a8\uff0c\u628a\u6bcf\u4e2a\u5143\u7d20\u90fd\u590d\u5236\u5230\u5b83\u524d\u9762\u7684\u90a3\u4e2a\u5185\u5b58\u5355\u5143\u91cc\u3002\u8fd9\u4e2a\u8fc7\u7a0b\u4f1a\u5173\u95ed\u5220\u9664\u76ee\u6807\u7d22\u5f15\u4f4d\u7f6e\u4e2d\u7684\u5143\u7d20\u6240\u7559\u4e0b\u7684\u7a7a\u683c\u3002 \u5c06\u903b\u8f91\u5c3a\u5bf8\u51cf1\u3002 \u68c0\u67e5\u662f\u5426\u5b58\u5728\u5185\u5b58\u7a7a\u95f4\u7684\u6d6a\u8d39\uff0c\u5e76\u6839\u636e\u9700\u8981\u51cf\u5c0f\u6570\u7ec4\u7684\u7269\u7406\u5c3a\u5bf8\u3002 \u5728\u5e73\u5747\u60c5\u51b5\u4e0b\uff0c\u79fb\u52a8\u5143\u7d20\u7684\u65f6\u95f4\u590d\u6742\u5ea6\u662f\u7ebf\u6027\u7684\uff0c\u56e0\u6b64\u5220\u9664\u64cd\u4f5c\u7684\u65f6\u95f4\u590d\u6742\u5ea6\u4e5f\u662f\u7ebf\u6027\u7684\u3002 \u4e0b\u9762\u662f\u5b9e\u73b0\u5220\u9664\u64cd\u4f5c\u7684\u4ee3\u7801\u3002 # \u5c06\u6570\u7ec4\u5143\u7d20\u5411\u5934\u90e8\u5e73\u79fb\u4e00\u4e2a\u4f4d\u7f6e for i in range ( targetIndex , logicalSize - 1 ): my_array [ i ] = my_arraya [ i + 1 ] # \u51cf\u5c11\u6570\u7ec4\u903b\u8f91\u5c3a\u5bf8 logicalSize -= 1 # \u5982\u679c\u9700\u8981\uff0c\u5219\u51cf\u5c11\u6570\u7ec4\u7269\u7406\u5c3a\u5bf8 \u4e0b\u9762\u662f Array \u7c7b\u4e2d\u5b9e\u73b0\u5220\u9664\u5143\u7d20\u7684\u65b9\u6cd5\u3002 def pop ( self , index ): \"\"\" \u5220\u9664\u6307\u5b9a\u7d22\u5f15\u503c\u7684\u6570\u7ec4\u5143\u7d20,\u5e76\u8fd4\u56de\u5220\u9664\u7684\u6570\u7ec4\u5143\u7d20\u503c \u5148\u51b3\u6761\u4ef6: 0 <= index < size() \"\"\" if index < 0 or index >= self . size (): raise IndexError ( \"\u5220\u9664\u64cd\u4f5c\u51fa\u9519, \u6570\u7ec4\u7d22\u5f15\u8d8a\u754c(\u4e0d\u5728\u6570\u7ec4\u903b\u8f91\u8fb9\u754c\u8303\u56f4\u5185)\" ) # \u4fdd\u5b58\u5373\u5c06\u88ab\u5220\u9664\u7684\u6570\u7ec4\u5143\u7d20\u503c itemToReturn = self . items [ index ] # \u5c06\u6570\u7ec4\u5143\u7d20\u5411\u5934\u90e8\u5e73\u79fb\u4e00\u4e2a\u4f4d\u7f6e for i in range ( index , self . size () - 1 ): self . items [ i ] = self . items [ i + 1 ] # \u5c06\u6570\u7ec4\u5c3e\u90e8\u7684\u7a7a\u4f59\u4f4d\u8d4b\u503cfillValue\uff0c\u9ed8\u8ba4\u662fNone self . items [ self . size () - 1 ] = self . fillValue # \u51cf\u5c11\u6570\u7ec4\u903b\u8f91\u5c3a\u5bf8 self . logicalSize -= 1 # \u51cf\u5c11\u6570\u7ec4\u7269\u7406\u5c3a\u5bf8 # \u5f53: # - \u6570\u7ec4\u7684\u903b\u8f91\u5c3a\u5bf8\u5c0f\u4e8e\u6216\u7b49\u4e8e\u5176\u7269\u7406\u5c3a\u5bf8\u76841/4 # - \u5e76\u4e14\u5b83\u7684\u7269\u7406\u5c3a\u5bf8\u81f3\u5c11\u662f\u8fd9\u4e2a\u6570\u7ec4\u5efa\u7acb\u65f6\u9ed8\u8ba4\u5bb9\u91cf\u76842\u500d\u65f6 # \u5219\u628a\u6570\u7ec4\u7684\u7269\u7406\u5c3a\u5bf8\u51cf\u5c0f\u5230\u539f\u6765\u7684\u4e00\u534a\uff0c\u5e76\u4e14\u4e5f\u4e0d\u4f1a\u5c0f\u4e8e\u5176\u9ed8\u8ba4\u5bb9\u91cf if self . size () <= len ( self ) // 4 and len ( self ) > self . capacity : self . shrink () # \u8fd4\u56de\u88ab\u5220\u9664\u5143\u7d20\u7684\u503c print ( f 'Item { itemToReturn } was deleted' ) return itemToReturn","title":"4.2.4.\u4ece\u6570\u7ec4\u91cc\u5220\u9664\u5143\u7d20"},{"location":"python/DataStructure/04_ArrayChain/#425","text":"\u4e0b\u8868\u5217\u51fa\u4e86\u6240\u6709\u6570\u7ec4\u64cd\u4f5c\u7684\u8fd0\u884c\u65f6\u590d\u6742\u5ea6\uff0c\u5305\u62ec\u5728\u6570\u7ec4\u7684\u903b\u8f91\u7ed3\u5c3e\u5904\u63d2\u5165\u548c\u5220\u9664\u5143\u7d20\u3002 \u6570\u7ec4\u63d0\u4f9b\u4e86\u5bf9\u5df2\u7ecf\u5b58\u5728\u7684\u5143\u7d20\u8fdb\u884c\u5feb\u901f\u8bbf\u95ee\u7684\u529f\u80fd\uff0c\u4ee5\u53ca\u5728\u903b\u8f91\u7ed3\u5c3e\u5904\u5feb\u901f\u63d2\u5165\u548c\u5220\u9664\u7684\u529f\u80fd\u3002 \u5728\u4efb\u610f\u4f4d\u7f6e\u5904\u8fdb\u884c\u63d2\u5165\u548c\u5220\u9664\u64cd\u4f5c\u7684\u901f\u5ea6\u5219\u4f1a\u6162\u4e0a\u4e00\u4e2a\u6570\u91cf\u7ea7\u3002 \u8c03\u6574\u6570\u7ec4\u7684\u5c3a\u5bf8\u4e5f\u9700\u8981\u7ebf\u6027\u65f6\u95f4\uff0c\u4f46\u662f\u56e0\u4e3a\u8fd9\u4e2a\u64cd\u4f5c\u4f1a\u628a\u6570\u7ec4\u5c3a\u5bf8\u52a0\u500d\u6216\u51cf\u534a\uff0c\u6240\u4ee5\u53ef\u4ee5\u6700\u5927\u9650\u5ea6\u5730\u51cf\u5c11\u9700\u8981\u6267\u884c\u7684\u6b21\u6570\u3002 \u7531\u4e8e\u53ef\u80fd\u4f1a\u8c03\u6574\u6570\u7ec4\u7684\u5c3a\u5bf8\uff0c\u56e0\u6b64\u63d2\u5165\u548c\u5220\u9664\u64cd\u4f5c\u5728\u4f7f\u7528\u5185\u5b58\u7684\u65f6\u5019\u4f1a\u6709 O(n) \u7684\u590d\u6742\u5ea6\uff0c\u90a3\u4e48\u8fd9\u5c31\u662f\u6700\u574f\u60c5\u51b5\u4e0b\u7684\u6027\u80fd\uff1b\u800c\u5728\u5e73\u5747\u60c5\u51b5\u4e0b\uff0c\u8fd9\u4e9b\u64cd\u4f5c\u7684\u5185\u5b58\u4f7f\u7528\u60c5\u51b5\u4ecd\u7136\u4e3a O(1) \u3002 \u64cd\u4f5c \u8fd0\u884c\u65f6\u590d\u6742\u5ea6 \u5728\u4f4d\u7f6ei\u5904\u8bbf\u95ee O(1)\uff0c\u6700\u597d\u548c\u6700\u574f\u60c5\u51b5\u4e0b \u5728\u4f4d\u7f6ei\u5904\u66ff\u6362 O(1)\uff0c\u6700\u597d\u548c\u6700\u574f\u60c5\u51b5\u4e0b \u5728\u903b\u8f91\u7ed3\u5c3e\u5904\u63d2\u5165 O(1)\uff0c\u5e73\u5747\u60c5\u51b5\u4e0b \u5728\u4f4d\u7f6ei\u5904\u63d2\u5165 O(n)\uff0c\u5e73\u5747\u60c5\u51b5\u4e0b \u5728\u4f4d\u7f6ei\u5904\u5220\u9664 O(n)\uff0c\u5e73\u5747\u60c5\u51b5\u4e0b \u589e\u5927\u5bb9\u91cf O(n)\uff0c\u6700\u597d\u548c\u6700\u574f\u60c5\u51b5\u4e0b \u51cf\u5c0f\u5bb9\u91cf O(n)\uff0c\u6700\u597d\u548c\u6700\u574f\u60c5\u51b5\u4e0b \u5728\u903b\u8f91\u7ed3\u5c3e\u5904\u5220\u9664 O(1)\uff0c\u5e73\u5747\u60c5\u51b5\u4e0b \u4f7f\u7528\u6570\u7ec4\u7684\u65f6\u5019\uff0c\u5185\u5b58\u91cc\u552f\u4e00\u771f\u6b63\u88ab\u6d6a\u8d39\u7684\u662f\u90a3\u4e9b\u5c1a\u672a\u586b\u5145\u6ee1\u7684\u6570\u7ec4\u5355\u5143\u3002 \u8bc4\u4f30\u6570\u7ec4\u5185\u5b58\u4f7f\u7528\u7387\u7684\u4e00\u4e2a\u975e\u5e38\u6709\u7528\u7684\u6982\u5ff5\u662f\u8d1f\u8f7d\u56e0\u5b50\uff08load factor\uff09\u3002\u6570\u7ec4\u7684\u8d1f\u8f7d\u56e0\u5b50\u7b49\u540c\u4e8e\u5b83\u6240\u5b58\u50a8\u7684\u5143\u7d20\u6570\u9664\u4ee5\u6570\u7ec4\u7684\u5bb9\u91cf\u3002 \u5f53\u6570\u7ec4\u5df2\u6ee1\u7684\u65f6\u5019\uff0c\u8d1f\u8f7d\u56e0\u5b50\u5c31\u662f1\uff1b \u5f53\u6570\u7ec4\u4e3a\u7a7a\u65f6\uff0c\u8d1f\u8f7d\u56e0\u5b50\u5c31\u662f0\uff1b \u5f53\u5185\u5b58\u5355\u5143\u7684\u5bb9\u91cf\u4e3a10\u4e14\u5360\u7528\u4e863\u4e2a\u5355\u5143\u65f6\uff0c\u8d1f\u8f7d\u56e0\u5b50\u5c31\u662f0.3\uff1b \u5f53\u6570\u7ec4\u7684\u8d1f\u8f7d\u56e0\u5b50\u964d\u5230\u67d0\u4e2a\u9608\u503c\uff08\u59820.25\uff09\u4ee5\u4e0b\u65f6\uff0c\u53ef\u4ee5\u901a\u8fc7\u8c03\u6574\u6570\u7ec4\u5c3a\u5bf8\u5c06\u6d6a\u8d39\u7684\u5185\u5b58\u5355\u5143\u6570\u4fdd\u6301\u5728\u5c3d\u53ef\u80fd\u4f4e\u7684\u6c34\u5e73\uff1b","title":"4.2.5.\u590d\u6742\u5ea6\u7684\u6743\u8861\uff1a\u65f6\u95f4\u3001\u7a7a\u95f4\u548c\u6570\u7ec4"},{"location":"python/DataStructure/04_ArrayChain/#426","text":"1\uff0e\u8bf7\u8bf4\u660e\u4e3a\u4ec0\u4e48\u63d2\u5165\u6216\u5220\u9664\u7ed9\u5b9a\u5143\u7d20\u65f6\u5fc5\u987b\u8981\u79fb\u52a8\u6570\u7ec4\u91cc\u7684\u67d0\u4e9b\u5143\u7d20\u3002 \u89e3\u7b54\uff1a\u5728 Python \u4e2d\uff0c\u5217\u8868\uff08list\uff09\u662f\u57fa\u4e8e\u6570\u7ec4\u5b9e\u73b0\u7684\u6570\u636e\u7ed3\u6784\u3002\u6240\u8c13\u7684\u201c\u6570\u7ec4\u201d\uff0c\u5176\u672c\u8d28\u4e0a\u662f\u4e00\u5757\u8fde\u7eed\u7684\u5185\u5b58\u7a7a\u95f4\uff0c\u7531\u4e8e\u5176\u5185\u5b58\u8fde\u7eed\u7684\u7279\u6027\uff0c\u6570\u7ec4\u5728\u8fdb\u884c\u63d2\u5165\u6216\u8005\u5220\u9664\u4e00\u4e2a\u5143\u7d20\u65f6\uff0c\u4e3a\u4e86\u4fdd\u6301\u5185\u5b58\u7684\u8fde\u7eed\u6027\uff0c\u5f80\u5f80\u9700\u8981\u79fb\u52a8\u6570\u7ec4\u91cc\u7684\u5176\u5b83\u5143\u7d20\u3002 \u5f53\u5728\u6570\u7ec4\u7684\u4e2d\u95f4\u4f4d\u7f6e\u63d2\u5165\u4e00\u4e2a\u65b0\u7684\u5143\u7d20\u65f6\uff0c\u4e3a\u4e86\u7ed9\u65b0\u5143\u7d20\u817e\u51fa\u7a7a\u95f4\uff0c\u5b83\u540e\u9762\u7684\u6240\u6709\u5143\u7d20\u90fd\u9700\u8981\u5411\u540e\u79fb\u52a8\u4e00\u4f4d\u3002\u540c\u6837\u7684\uff0c\u5982\u679c\u6211\u4eec\u5220\u9664\u4e86\u6570\u7ec4\u7684\u4e00\u4e2a\u5143\u7d20\uff0c\u4e3a\u4e86\u907f\u514d\u5728\u6570\u7ec4\u4e2d\u51fa\u73b0\u4e00\u4e2a\u7a7a\u6d1e\uff0c\u88ab\u5220\u9664\u5143\u7d20\u540e\u9762\u7684\u6240\u6709\u5143\u7d20\u90fd\u9700\u8981\u5411\u524d\u79fb\u52a8\u4e00\u4f4d\u3002 \u7136\u800c\uff0cPython\u7684 list \u6570\u636e\u7ed3\u6784\u662f\u52a8\u6001\u7684\uff0c\u4e5f\u5c31\u662f\u8bf4\uff0c\u5f53\u63d2\u5165\u6216\u5220\u9664\u5143\u7d20\u65f6\uff0cPython\u4f1a\u81ea\u52a8\u5206\u914d\u6216\u56de\u6536\u5185\u5b58\u3002\u5f53\u5728 list \u7684\u672b\u5c3e\u6dfb\u52a0\u6216\u79fb\u9664\u5143\u7d20\u65f6\uff0c\u4e0d\u9700\u8981\u79fb\u52a8\u5176\u4ed6\u5143\u7d20\uff0c\u56e0\u6b64\u64cd\u4f5c\u6548\u7387\u8f83\u9ad8\uff1b\u4f46\u662f\u5728 list \u7684\u4e2d\u95f4\u6216\u8d77\u59cb\u90e8\u5206\u63d2\u5165\u6216\u5220\u9664\u5143\u7d20\u65f6\uff0c\u5c31\u9700\u8981\u79fb\u52a8\u5176\u5b83\u5143\u7d20\uff0c\u76f8\u5bf9\u800c\u8a00\uff0c\u5176\u64cd\u4f5c\u6548\u7387\u5c31\u8f83\u4f4e\u4e86\u3002 2\uff0e\u5728\u63d2\u5165\u8fc7\u7a0b\u4e2d\uff0c\u79fb\u52a8\u6570\u7ec4\u5143\u7d20\u65f6\uff0c\u8981\u5148\u79fb\u52a8\u54ea\u4e2a\u5143\u7d20\uff1f\u5148\u79fb\u52a8\u63d2\u5165\u4f4d\u7f6e\u7684\u5143\u7d20\uff0c\u8fd8\u662f\u6700\u540e\u4e00\u4e2a\u5143\u7d20\uff1f\u4e3a\u4ec0\u4e48\uff1f \u89e3\u7b54\uff1a\u5728 Python \u4e2d\u5b9e\u73b0\u6570\u7ec4\u7684\u63d2\u5165\u8fc7\u7a0b\u65f6\uff0c\u5e94\u5f53\u5148\u79fb\u52a8\u63d2\u5165\u4f4d\u7f6e\u4e4b\u540e\u7684\u6700\u540e\u4e00\u4e2a\u5143\u7d20\u3002 \u8003\u8651\u4ee5\u4e0b\u7684\u60c5\u51b5\uff1a\u503c\u63d2\u5165\u4e8e\u6570\u7ec4\u7684\u4e2d\u95f4\u4f4d\u7f6e\uff0c\u4f60\u8bd5\u56fe\u4ece\u63d2\u5165\u4f4d\u7f6e\u5f00\u59cb\uff0c\u5c06\u6bcf\u4e2a\u5143\u7d20\u540e\u79fb\u4e00\u4f4d\u3002\u4f46\u662f\uff0c\u5f53\u4f60\u628a\u7b2c\u4e00\u4e2a\u5143\u7d20\u79fb\u5230\u7b2c\u4e8c\u4e2a\u4f4d\u7f6e\u65f6\uff0c\u4f60\u4f1a\u8986\u76d6\u6389\u539f\u6709\u7684\u7b2c\u4e8c\u4e2a\u5143\u7d20\uff0c\u7531\u4e8e\u4f60\u8fd8\u6ca1\u6709\u4fdd\u5b58\u6216\u590d\u5236\u8fd9\u4e2a\u88ab\u8986\u76d6\u7684\u5143\u7d20\uff0c\u5b83\u5c31\u4f1a\u4e22\u5931\u3002 \u5982\u679c\u4ece\u6700\u540e\u4e00\u4e2a\u5143\u7d20\u5f00\u59cb\uff0c\u5c06\u6bcf\u4e2a\u5143\u7d20\u5411\u540e\u79fb\u4e00\u4f4d\uff0c\u90a3\u4e48\u6bcf\u4e2a\u5143\u7d20\u90fd\u4f1a\u88ab\u590d\u5236\u5230\u5b83\u7684\u4e0b\u4e00\u4f4d\uff0c\u7136\u540e\u624d\u4f1a\u88ab\u5b83\u524d\u9762\u7684\u5143\u7d20\u8986\u76d6\u3002\u8fd9\u6837\u5c31\u786e\u4fdd\u4e86\u6bcf\u4e2a\u5143\u7d20\u90fd\u80fd\u6b63\u786e\u5730\u79fb\u52a8\u5230\u5b83\u5e94\u8be5\u5230\u8fbe\u7684\u4f4d\u7f6e\uff0c\u4e0d\u4f1a\u6709\u4efb\u4f55\u5143\u7d20\u4e22\u5931\u3002 \u6240\u4ee5\uff0c\u5728\u63d2\u5165\u8fc7\u7a0b\u4e2d\uff0c\u6211\u4eec\u5e94\u8be5\u4ece\u6700\u540e\u4e00\u4e2a\u5143\u7d20\u5f00\u59cb\uff0c\u9010\u4e2a\u5c06\u5143\u7d20\u540e\u79fb\u4e00\u4f4d\uff0c\u76f4\u5230\u5c06\u63d2\u5165\u4f4d\u7f6e\u7684\u5143\u7d20\u4e5f\u540e\u79fb\u4e00\u4f4d\uff0c\u7136\u540e\u5728\u63d2\u5165\u4f4d\u7f6e\u653e\u5165\u65b0\u7684\u5143\u7d20\u3002 3\uff0e\u5982\u679c\u63d2\u5165\u4f4d\u7f6e\u662f\u6570\u7ec4\u7684\u903b\u8f91\u672b\u5c3e\uff0c\u8bf7\u8bf4\u660e\u8fd9\u4e2a\u63d2\u5165\u64cd\u4f5c\u7684\u8fd0\u884c\u65f6\u590d\u6742\u5ea6\u3002 \u89e3\u7b54\uff1a\u5982\u679c\u5728\u6570\u7ec4\uff08\u5728 Python \u4e2d\u5c31\u662f list\uff09\u7684\u903b\u8f91\u672b\u5c3e\u63d2\u5165\u5143\u7d20\uff0c\u8fd9\u79cd\u64cd\u4f5c\u901a\u5e38\u53ef\u4ee5\u5728\u5e38\u6570\u65f6\u95f4\u5185\u5b8c\u6210\uff0c\u4e5f\u5c31\u662f\u8bf4\uff0c\u8fd9\u79cd\u64cd\u4f5c\u7684\u65f6\u95f4\u590d\u6742\u5ea6\u662f O(1)\u3002 \u56e0\u4e3a\u6570\u7ec4\u662f\u8fde\u7eed\u7684\u5185\u5b58\u7a7a\u95f4\uff0c\u4f4d\u4e8e\u672b\u5c3e\u7684\u63d2\u5165\u64cd\u4f5c\u4e0d\u9700\u8981\u79fb\u52a8\u4efb\u4f55\u5143\u7d20\uff0c\u4ec5\u4ec5\u6d89\u53ca\u5728\u672b\u5c3e\u6dfb\u52a0\u65b0\u5143\u7d20\uff0c\u5e76\u53ef\u80fd\u6d89\u53ca\u4e00\u4e9b\u989d\u5916\u7684\u5185\u5b58\u5206\u914d\uff08\u5982\u679c\u6570\u7ec4\u5df2\u6ee1\uff0c\u9700\u8981\u5206\u914d\u66f4\u5927\u7684\u6570\u7ec4\u6765\u5bb9\u7eb3\u65b0\u7684\u5143\u7d20\uff09\u3002 \u9700\u8981\u6ce8\u610f\u7684\u662f\uff0c\u5185\u5b58\u5206\u914d\u548c\u590d\u5236\u5143\u7d20\u5728\u5b9e\u9645\u64cd\u4f5c\u4e2d\u53ef\u80fd\u8fd8\u662f\u9700\u8981\u4e00\u4e9b\u65f6\u95f4\u7684\uff0c\u5c24\u5176\u662f\u5728\u6570\u7ec4\u5df2\u6ee1\u65f6\uff0c\u9700\u8981\u91cd\u65b0\u5206\u914d\u5e76\u590d\u5236\u6574\u4e2a\u6570\u7ec4\u5230\u65b0\u7684\u5185\u5b58\u5730\u5740\u3002\u4f46\u662f\u5728\u7406\u8bba\u5206\u6790\u65f6\uff0c\u6211\u4eec\u901a\u5e38\u5ffd\u7565\u8fd9\u79cd\u60c5\u51b5\uff0c\u56e0\u4e3a\u5b83\u662f\u4e00\u79cd\u88ab\u79f0\u4e3a\u644a\u8fd8\uff08amortized\uff09\u64cd\u4f5c\u7684\u7279\u4f8b\uff0c\u4ece\u957f\u671f\u7684\u5e73\u5747\u8fd0\u884c\u65f6\u95f4\u6765\u770b\uff0c\u8fd9\u79cd\u63d2\u5165\u64cd\u4f5c\u7684\u65f6\u95f4\u590d\u6742\u5ea6\u4ecd\u7136\u662f O(1) \u7684\u3002 4\uff0e\u5047\u8bbe\u6570\u7ec4\u5f53\u524d\u5305\u542b14\u4e2a\u5143\u7d20\uff0c\u5b83\u7684\u8d1f\u8f7d\u56e0\u5b50\u4e3a0.70\uff0c\u90a3\u4e48\u5b83\u7684\u7269\u7406\u5bb9\u91cf\u662f\u591a\u5c11\uff1f \u89e3\u7b54\uff1a\u8d1f\u8f7d\u56e0\u5b50\u901a\u5e38\u662f\u6307\u4e00\u4e2a\u54c8\u5e0c\u8868\u4e2d\u5df2\u5b58\u5143\u7d20\u6570\u91cf\u5bf9\u5e94\u4e8e\u5176\u5e95\u5c42\u6570\u7ec4\u5bb9\u91cf\u7684\u6bd4\u4f8b\u3002\u5bf9\u4e8e\u4e00\u822c\u7684\u6570\u7ec4\u548c Python \u7684 list\uff0c\u6211\u4eec\u901a\u5e38\u4e0d\u4f1a\u8c08\u8bba\u8d1f\u8f7d\u56e0\u5b50\uff0c\u56e0\u4e3a\u8fd9\u4e9b\u6570\u636e\u7ed3\u6784\u7684\u5927\u5c0f\u76f4\u63a5\u5bf9\u5e94\u4e8e\u5176\u4e2d\u5305\u542b\u7684\u5143\u7d20\u6570\u91cf\u3002 \u7136\u800c\uff0c\u5982\u679c\u4f60\u8981\u8ba1\u7b97\u4e00\u4e2a\u8d1f\u8f7d\u56e0\u5b50\u4e3a 0.70 \u7684\u5bb9\u5668\uff0c\u5e76\u4e14\u5b83\u5305\u542b\u4e8614\u4e2a\u5143\u7d20\uff0c\u90a3\u4e48\u5b83\u7684\u7269\u7406\u5bb9\u91cf\u53ef\u4ee5\u8ba1\u7b97\u4e3a\uff1a \u5143\u7d20\u6570\u91cf / \u8d1f\u8f7d\u56e0\u5b50 = \u5bb9\u91cf \u5728\u8fd9\u79cd\u60c5\u51b5\u4e0b\uff0c\u7269\u7406\u5bb9\u91cf\u5e94\u8be5\u662f 14 / 0.70 = 20\u3002\u6240\u4ee5\u7269\u7406\u5bb9\u91cf\u5e94\u8be5\u662f 20\u3002","title":"4.2.6.\u7ec3\u4e60\u9898"},{"location":"python/DataStructure/04_ArrayChain/#43","text":"\u4e00\u7ef4\u6570\u7ec4\uff08one-dimensional array\uff09 \u4e8c\u7ef4\u6570\u7ec4\uff08two-dimensional array\uff09\uff0c\u6216\u7f51\u683c\uff08grid\uff09 \u8981\u8bbf\u95eegrid\u91cc\u7684\u5143\u7d20\uff0c\u53ef\u4ee5\u901a\u8fc7\u4e24\u4e2a\u4e0b\u6807\u6765\u6307\u5b9a\u5176\u884c\u548c\u5217\u7684\u76f8\u5e94\u4f4d\u7f6e\uff0c\u5e76\u4e14\u8fd9\u4e24\u4e2a\u7d22\u5f15\u90fd\u662f\u4ece0\u5f00\u59cb\u7684\u3002 x = grid [ 2 ][ 3 ] # \u5c06\u4e8c\u7ef4\u6570\u7ec4\u7b2c\u4e8c\u884c\u7b2c\u4e09\u5217\u7684\u503c\u8d4b\u7ed9\u53d8\u91cfx","title":"4.3.\u4e8c\u7ef4\u6570\u7ec4\uff08\u7f51\u683c\uff09"},{"location":"python/DataStructure/04_ArrayChain/#431","text":"\u9664\u4e86\u7528\u53cc\u4e0b\u6807\uff0c\u7f51\u683c\u8fd8\u5fc5\u987b\u8981\u6709\u4e24\u4e2a\u65b9\u6cd5\uff0c\u7528\u6765\u8fd4\u56de\u884c\u6570\u548c\u5217\u6570\u3002\u6211\u4eec\u628a\u8fd9\u4e24\u4e2a\u65b9\u6cd5\u5206\u522b\u547d\u540d\u4e3a getHeight \u548c getWidth \u3002 \u57fa\u4e8e4.3.3\u4e2d\u5b9a\u4e49\u7684Grid\u7c7b\uff0c\u4e0b\u9762\u8fd9\u6bb5\u4ee3\u7801\u4f1a\u5b9e\u4f8b\u5316\u4e00\u4e2a\u4e8c\u7ef4\u6570\u7ec4\uff0c\u5e76\u8ba1\u7b97\u53d8\u91cf my_grid \u91cc\u6240\u6709\u6570\u5b57\u7684\u603b\u548c\u3002\u5916\u90e8\u5faa\u73af\u4f1a\u8fed\u4ee35\u6b21\u5e76\u5411\u4e0b\u9010\u884c\u79fb\u52a8\uff0c\u5728\u6bcf\u6b21\u8fdb\u5165\u5916\u90e8\u5faa\u73af\u7684\u65f6\u5019\uff0c\u5185\u90e8\u5faa\u73af\u90fd\u4f1a\u8fed\u4ee35\u6b21\uff0c\u4ece\u800c\u5728\u4e0d\u540c\u884c\u7684\u5217\u4e4b\u95f4\u79fb\u52a8\u3002 my_grid = Grid ( 5 , 5 , 1 ) sum = 0 for row in range ( my_grid . getHeight ()): # Go through rows for column in range ( my_grid . getWidth ()): # Go through columns sum += my_grid [ row ][ column ]","title":"4.3.1.\u4f7f\u7528\u7f51\u683c"},{"location":"python/DataStructure/04_ArrayChain/#432","text":"\u57fa\u4e8e4.3.3\u4e2d\u5b9a\u4e49\u7684Grid\u7c7b\uff0c\u4e0b\u9762\u4ee3\u7801\u5b9e\u4f8b\u5316\u4e86\u4e00\u4e2a\u4e8c\u7ef4\u6570\u7ec4\uff0c\u904d\u5386\u8be5\u6570\u7ec4\u7684\u6bcf\u4e2a\u5143\u7d20\u5e76\u8d4b\u503c\u3002 my_grid = Grid ( 5 , 5 , 1 ) print ( my_grid ) # \u884c\u904d\u5386 for row in range ( my_grid . getHeight ()): # \u5217\u904d\u5386 for column in range ( my_grid . getWidth ()): my_grid [ row ][ column ] = int ( str ( row ) + str ( column ))","title":"4.3.2.\u521b\u5efa\u5e76\u521d\u59cb\u5316\u7f51\u683c"},{"location":"python/DataStructure/04_ArrayChain/#433grid","text":"\u4e0b\u9762\u5b9e\u73b0\u4e86\u4e00\u4e2a Grid \u5bf9\u8c61\uff0c\u5305\u542b3\u4e2a\u53c2\u6570\uff08\u9ad8\u5ea6\u3001\u5bbd\u5ea6\u4ee5\u53ca\u521d\u59cb\u7684\u586b\u5145\u503c\uff09\u7684 Grid \u6784\u9020\u51fd\u6570\u3002 \u9ad8\u5ea6\uff0c\u5373\u884c\u6570\uff1b\u5bbd\u5ea6\uff0c\u5373\u5217\u6570\uff1b \u5b9e\u4f8b\u5316\u4e86\u4e00\u4e2a5\u884c5\u5217\u7684\u4e8c\u7ef4\u6570\u7ec4\uff1b class Array ( object ): \"\"\"\u63cf\u8ff0\u4e00\u4e2a\u6570\u7ec4\u3002\"\"\" def __init__ ( self , capacity , fillValue = None ): \"\"\"Capacity\u662f\u6570\u7ec4\u7684\u5927\u5c0f. fillValue\u4f1a\u586b\u5145\u5728\u6bcf\u4e2a\u5143\u7d20\u4f4d\u7f6e, \u9ed8\u8ba4\u503c\u662fNone\"\"\" # \u521d\u59cb\u5316\u6570\u7ec4\u7684\u903b\u8f91\u5c3a\u5bf8\u548c\u7269\u7406\u5c3a\u5bf8 self . logicalSize = 0 self . capacity = capacity self . fillValue = fillValue #\u521d\u59cb\u5316\u5185\u90e8\u6570\u7ec4\uff0c\u5e76\u586b\u5145\u5143\u7d20\u503c self . items = list () for count in range ( capacity ): self . items . append ( fillValue ) self . logicalSize += 1 # \u521d\u59cb\u5316\u6570\u7ec4\u7269\u7406\u5927\u5c0f\u65f6\uff0c\u4e5f\u540c\u65f6\u521d\u59cb\u5316\u5176\u903b\u8f91\u5927\u5c0f def __len__ ( self ): \"\"\"\u8fd4\u56de\u6570\u7ec4\u7684\u5927\u5c0f\"\"\" return len ( self . items ) def __str__ ( self ): \"\"\"\u5c06\u6570\u7ec4\u5b57\u7b26\u4e32\u5316\u5e76\u8fd4\u56de\"\"\" result = \"\" for index in range ( self . size ()): result += str ( self . items [ index ]) + \" \" return result def size ( self ): \"\"\"\u8fd4\u56de\u6570\u7ec4\u7684\u903b\u8f91\u5c3a\u5bf8\"\"\" return self . logicalSize def __iter__ ( self ): \"\"\"\u652f\u6301for\u5faa\u73af\u5bf9\u6570\u7ec4\u8fdb\u884c\u904d\u5386.\"\"\" print ( \"__iter__ called\" ) # \u4ec5\u7528\u6765\u6d4b\u8bd5\u4f55\u65f6__iter__\u4f1a\u88ab\u8c03\u7528 return iter ( self . items ) def __getitem__ ( self , index ): \"\"\" \u7528\u4e8e\u8bbf\u95ee\u7d22\u5f15\u5904\u7684\u4e0b\u6807\u8fd0\u7b97\u7b26. \u5148\u51b3\u6761\u4ef6: 0 <= index < size() \"\"\" if index < 0 or index >= self . size (): raise IndexError ( \"\u8bfb\u53d6\u64cd\u4f5c\u51fa\u9519, \u6570\u7ec4\u7d22\u5f15\u8d8a\u754c(\u4e0d\u5728\u6570\u7ec4\u903b\u8f91\u8fb9\u754c\u8303\u56f4\u5185)\" ) return self . items [ index ] def __setitem__ ( self , index , newItem ): \"\"\" \u4e0b\u6807\u8fd0\u7b97\u7b26\u7528\u4e8e\u5728\u7d22\u5f15\u5904\u8fdb\u884c\u66ff\u6362. \u5148\u51b3\u6761\u4ef6: 0 <= index < size() \"\"\" if index < 0 or index >= self . size (): raise IndexError ( \"\u66f4\u65b0\u64cd\u4f5c\u51fa\u9519, \u6570\u7ec4\u7d22\u5f15\u8d8a\u754c(\u4e0d\u5728\u6570\u7ec4\u903b\u8f91\u8fb9\u754c\u8303\u56f4\u5185)\" ) self . items [ index ] = newItem def __eq__ ( self , other ): \"\"\" \u4e24\u4e2a\u6570\u7ec4\u76f8\u7b49\u5219\u8fd4\u56deTrue, \u5426\u5219\u8fd4\u56deFalse \"\"\" # \u5224\u65ad\u4e24\u4e2a\u6570\u7ec4\u662f\u5426\u662f\u540c\u4e00\u4e2a\u5bf9\u8c61\uff0c\u6ce8\u610f\uff0c\u4e0d\u662f\u5b83\u4eec\u7684\u503c\u662f\u5426\u76f8\u7b49 if self is other : return True # \u5224\u65ad\u4e24\u4e2a\u5bf9\u8c61\u7c7b\u578b\u662f\u5426\u4e00\u6837 if type ( self ) != type ( other ): return False # \u5224\u65ad\u4e24\u4e2a\u6570\u7ec4\u5927\u5c0f\u662f\u5426\u4e00\u6837 if self . size () != other . size (): return False # \u6bd4\u8f83\u4e24\u4e2a\u6570\u7ec4\u7684\u503c\u662f\u5426\u4e00\u6837 for index in range ( self . size ()): if self [ index ] != other [ index ]: return False return True def grow ( self ): \"\"\"\u589e\u5927\u6570\u7ec4\u7269\u7406\u5c3a\u5bf8\"\"\" # \u57fa\u4e8e\u5f53\u524d\u7269\u7406\u5c3a\u5bf8\u52a0\u500d\uff0c\u5e76\u5c06fillValue\u8d4b\u503c\u5e95\u5c42\u5217\u8868\u7684\u65b0\u5143\u7d20 for count in range ( len ( self )): self . items . append ( self . fillValue ) def insert ( self , index , newItem ): \"\"\"\u5728\u6570\u7ec4\u6307\u5b9a\u7d22\u5f15\u5904\u63d2\u5165\u65b0\u5143\u7d20\"\"\" # \u5f53\u6570\u7ec4\u7684\u7269\u7406\u5c3a\u5bf8\u548c\u903b\u8f91\u5c3a\u5bf8\u4e00\u6837\u65f6\uff0c\u5219\u589e\u52a0\u7269\u7406\u5c3a\u5bf8 if self . size () == len ( self ): self . grow () # \u63d2\u5165\u65b0\u5143\u7d20 # \u5f53\u63d2\u5165\u4f4d\u7f6e\u5927\u4e8e\u6216\u7b49\u4e8e\u6700\u5927\u903b\u8f91\u4f4d\u7f6e\uff0c\u5219\u5728\u6570\u7ec4\u672b\u7aef\u63d2\u5165\u65b0\u5143\u7d20 # \u5f53\u63d2\u5165\u4f4d\u7f6e\u4ecb\u4e8e\u6570\u7ec4\u903b\u8f91\u4f4d\u7f6e\u7684\u4e2d\u95f4\uff0c\u5219\u4ece\u63d2\u5165\u4f4d\u7f6e\u8d77\u5c06\u5269\u4f59\u6570\u7ec4\u5143\u7d20\u5411\u5c3e\u90e8\u5e73\u79fb\u4e00\u4e2a\u4f4d\u7f6e if index >= self . size (): self . items [ self . size ()] = newItem else : index = max ( index , 0 ) # \u5c06\u6570\u7ec4\u5143\u7d20\u5411\u5c3e\u90e8\u5e73\u79fb\u4e00\u4e2a\u4f4d\u7f6e for i in range ( self . size (), index , - 1 ): self . items [ i ] = self . items [ i - 1 ] # \u63d2\u5165\u65b0\u5143\u7d20 self . items [ index ] = newItem # \u589e\u52a0\u6570\u7ec4\u7684\u903b\u8f91\u5c3a\u5bf8 self . logicalSize += 1 def shrink ( self ): \"\"\" \u51cf\u5c11\u6570\u7ec4\u7684\u7269\u7406\u5c3a\u5bf8 \u5f53: - \u6570\u7ec4\u7684\u903b\u8f91\u5c3a\u5bf8\u5c0f\u4e8e\u6216\u7b49\u4e8e\u5176\u7269\u7406\u5c3a\u5bf8\u76841/4 - \u5e76\u4e14\u5b83\u7684\u7269\u7406\u5c3a\u5bf8\u81f3\u5c11\u662f\u8fd9\u4e2a\u6570\u7ec4\u5efa\u7acb\u65f6\u9ed8\u8ba4\u5bb9\u91cf\u76842\u500d\u65f6 \u5219\u628a\u6570\u7ec4\u7684\u7269\u7406\u5c3a\u5bf8\u51cf\u5c0f\u5230\u539f\u6765\u7684\u4e00\u534a\uff0c\u5e76\u4e14\u4e5f\u4e0d\u4f1a\u5c0f\u4e8e\u5176\u9ed8\u8ba4\u5bb9\u91cf \"\"\" # \u5728\u903b\u8f91\u5c3a\u5bf8\u548c\u7269\u7406\u5c3a\u5bf8\u7684\u4e00\u534a\u4e4b\u95f4\u9009\u62e9\u6700\u5927\u503c\u4f5c\u4e3a\u6570\u7ec4\u6536\u7f29\u540e\u7684\u7269\u7406\u5c3a\u5bf8 newSize = max ( self . capacity , len ( self ) // 2 ) # \u91ca\u653e\u591a\u4f59\u7684\u6570\u7ec4\u7a7a\u95f4 for count in range ( len ( self ) - newSize ): self . items . pop () def pop ( self , index ): \"\"\" \u5220\u9664\u6307\u5b9a\u7d22\u5f15\u503c\u7684\u6570\u7ec4\u5143\u7d20,\u5e76\u8fd4\u56de\u5220\u9664\u7684\u6570\u7ec4\u5143\u7d20\u503c \u5148\u51b3\u6761\u4ef6: 0 <= index < size() \"\"\" if index < 0 or index >= self . size (): raise IndexError ( \"\u5220\u9664\u64cd\u4f5c\u51fa\u9519, \u6570\u7ec4\u7d22\u5f15\u8d8a\u754c(\u4e0d\u5728\u6570\u7ec4\u903b\u8f91\u8fb9\u754c\u8303\u56f4\u5185)\" ) # \u4fdd\u5b58\u5373\u5c06\u88ab\u5220\u9664\u7684\u6570\u7ec4\u5143\u7d20\u503c itemToReturn = self . items [ index ] # \u5c06\u6570\u7ec4\u5143\u7d20\u5411\u5934\u90e8\u5e73\u79fb\u4e00\u4e2a\u4f4d\u7f6e for i in range ( index , self . size () - 1 ): self . items [ i ] = self . items [ i + 1 ] # \u5c06\u6570\u7ec4\u5c3e\u90e8\u7684\u7a7a\u4f59\u4f4d\u8d4b\u503cfillValue\uff0c\u9ed8\u8ba4\u662fNone self . items [ self . size () - 1 ] = self . fillValue # \u51cf\u5c11\u6570\u7ec4\u903b\u8f91\u5c3a\u5bf8 self . logicalSize -= 1 # \u51cf\u5c11\u6570\u7ec4\u7269\u7406\u5c3a\u5bf8 # \u5f53: # - \u6570\u7ec4\u7684\u903b\u8f91\u5c3a\u5bf8\u5c0f\u4e8e\u6216\u7b49\u4e8e\u5176\u7269\u7406\u5c3a\u5bf8\u76841/4 # - \u5e76\u4e14\u5b83\u7684\u7269\u7406\u5c3a\u5bf8\u81f3\u5c11\u662f\u8fd9\u4e2a\u6570\u7ec4\u5efa\u7acb\u65f6\u9ed8\u8ba4\u5bb9\u91cf\u76842\u500d\u65f6 # \u5219\u628a\u6570\u7ec4\u7684\u7269\u7406\u5c3a\u5bf8\u51cf\u5c0f\u5230\u539f\u6765\u7684\u4e00\u534a\uff0c\u5e76\u4e14\u4e5f\u4e0d\u4f1a\u5c0f\u4e8e\u5176\u9ed8\u8ba4\u5bb9\u91cf if self . size () <= len ( self ) // 4 and len ( self ) > self . capacity : self . shrink () # \u8fd4\u56de\u88ab\u5220\u9664\u5143\u7d20\u7684\u503c print ( f 'Item { itemToReturn } was deleted' ) return itemToReturn class Grid ( object ): \"\"\"\u63cf\u8ff0\u4e00\u4e2a\u4e8c\u7ef4\u6570\u7ec4\u3002\"\"\" def __init__ ( self , rows , columns , fillValue = None ): self . rows = rows self . columns = columns self . fillValue = fillValue # \u6309\u884c\u6570\u521d\u59cb\u5316\u6570\u7ec4y\u8f74\u7269\u7406\u5c3a\u5bf8 self . data = Array ( rows , fillValue ) # \u6309\u5217\u6570\u521d\u59cb\u5316\u6570\u7ec4x\u8f74\u7269\u7406\u5c3a\u5bf8\uff0c\u5e76\u8d4b\u503c\u5230y\u8f74\u6570\u7ec4\uff0c\u586b\u5145None\u503c for row in range ( rows ): self . data [ row ] = Array ( columns , fillValue ) def getHeight ( self ): \"\"\"\u8fd4\u56de\u4e8c\u7ef4\u6570\u7ec4\u7684y\u8f74\u7684\u5927\u5c0f(\u7269\u7406\u5c3a\u5bf8), \u5373\u6570\u7ec4\u7684\u884c\u6570\"\"\" return len ( self . data ) def getWidth ( self ): \"\"\"\u8fd4\u56de\u4e8c\u7ef4\u6570\u7ec4\u7684x\u8f74\u7684\u5927\u5c0f(\u7269\u7406\u5c3a\u5bf8), \u5373\u6570\u7ec4\u7684\u5217\u6570\"\"\" return len ( self . data [ 0 ]) def __getitem__ ( self , index ): \"\"\"\u8fd4\u56de\u4e8c\u7ef4\u6570\u7ec4\u6307\u5b9a\u884c\u548c\u5217\u7d22\u5f15\u5bf9\u5e94\u7684\u5143\u7d20\u503c\"\"\" return self . data [ index ] def __str__ ( self ): \"\"\"\u8fd4\u56de\u4e8c\u7ef4\u6570\u7ec4\u7684\u5b57\u7b26\u4e32\u5f62\u5f0f\"\"\" result = \"\" for row in range ( self . getHeight ()): for col in range ( self . getWidth ()): result += str ( self . data [ row ][ col ]) + \" \" result += \" \\n \" return result def main (): my_grid = Grid ( 5 , 5 , 1 ) print ( my_grid ) if __name__ == \"__main__\" : main () # \u8fd0\u884c\u7ed3\u679c # 1 1 1 1 1 # 1 1 1 1 1 # 1 1 1 1 1 # 1 1 1 1 1 # 1 1 1 1 1","title":"4.3.3.\u5b9a\u4e49Grid\u7c7b"},{"location":"python/DataStructure/04_ArrayChain/#434","text":"\u5230\u76ee\u524d\u4e3a\u6b62\uff0c\u6211\u4eec\u6240\u8ba8\u8bba\u7684\u7f51\u683c\u90fd\u662f\u4e8c\u7ef4\u5e76\u4e14\u662f\u77e9\u5f62\u7684\u3002\u6211\u4eec\u4e5f\u53ef\u4ee5\u628a\u7f51\u683c\u521b\u5efa\u6210\u53c2\u5dee\u4e0d\u9f50\u7684\u6837\u5b50\uff0c\u4e5f\u53ef\u4ee5\u521b\u5efa\u9ad8\u4e8e\u4e24\u4e2a\u7ef4\u5ea6\u7684\u7f51\u683c\u3002 \u53c2\u5dee\u4e0d\u9f50\u7684\u7f51\u683c\u6709\u56fa\u5b9a\u7684\u884c\u6570\uff0c\u4f46\u662f\u6bcf\u4e00\u884c\u91cc\u7684\u6570\u636e\u5217\u6570\u5404\u6709\u4e0d\u540c\u3002\u5217\u8868\u6570\u7ec4\u6216\u6570\u7ec4\u662f\u53ef\u4ee5\u5b9e\u73b0\u8fd9\u79cd\u7f51\u683c\u7684\u5408\u9002\u7ed3\u6784\u3002 \u6bd4\u5982\uff0c\u53ef\u4ee5\u521b\u5efa\u4e00\u4e2a\u4e09\u7ef4\u6570\u7ec4\u7684\u65f6\u5019\u9700\u8981\u6307\u5b9a\u5b83\u7684\u6df1\u5ea6\u3001\u9ad8\u5ea6\u4ee5\u53ca\u5bbd\u5ea6\u3002\u56e0\u6b64\u53ef\u4ee5\u7ed9\u6570\u7ec4\u7c7b\u578b\u6dfb\u52a0\u4e00\u4e2a\u53eb\u4f5c getDepth \u7684\u65b9\u6cd5\uff0c\u4ece\u800c\u50cf getWidth \u548c getHeight \u65b9\u6cd5\u4e00\u6837\u518d\u5f97\u5230\u8fd9\u4e2a\u7ef4\u5ea6\u7684\u76f8\u5173\u6570\u636e\u3002\u5728\u8fd9\u4e2a\u5b9e\u73b0\u91cc\uff0c\u6bcf\u4e2a\u5143\u7d20\u90fd\u53ef\u4ee5\u901a\u8fc73\u4e2a\u4f5c\u4e3a\u7d22\u5f15\u7684\u6574\u6570\u8fdb\u884c\u8bbf\u95ee\uff0c\u4e5f\u53ef\u4ee5\u901a\u8fc7\u67093\u5c42\u5faa\u73af\u7684\u63a7\u5236\u8bed\u53e5\u7ed3\u6784\u6765\u4f7f\u7528\u5b83\u3002","title":"4.3.4.\u53c2\u5dee\u4e0d\u9f50\u7684\u7f51\u683c\u548c\u591a\u7ef4\u6570\u7ec4"},{"location":"python/DataStructure/04_ArrayChain/#435","text":"1\uff0e\u4ec0\u4e48\u662f\u4e8c\u7ef4\u6570\u7ec4\uff08\u7f51\u683c\uff09\uff1f \u89e3\u7b54\uff1a\u4e8c\u7ef4\u6570\u7ec4\uff0c\u6709\u65f6\u88ab\u79f0\u4e3a\u7f51\u683c\uff0c\u662f\u4e00\u4e2a\u6570\u636e\u7ed3\u6784\uff0c\u5b83\u5141\u8bb8\u6211\u4eec\u5c06\u6570\u636e\u4ee5\u8868\u683c\u5f62\u5f0f\u7ec4\u7ec7\u8d77\u6765\uff0c\u5373\u6570\u636e\u5728\u4e24\u4e2a\u7ef4\u5ea6\u4e0a\u8fdb\u884c\u7ec4\u7ec7\u3002\u53ef\u4ee5\u628a\u4e8c\u7ef4\u6570\u7ec4\u770b\u4f5c\u662f\u4e00\u4e2a\u6570\u7ec4\u7684\u6570\u7ec4\u3002\u4f8b\u5982\uff0c\u5728 Python \u4e2d\uff0c\u4e00\u4e2a\u4e8c\u7ef4\u6570\u7ec4\u53ef\u4ee5\u662f\u4e00\u4e2a\u5217\u8868\u7684\u5217\u8868\u3002 \u5728\u4e8c\u7ef4\u6570\u7ec4\u4e2d\uff0c\u6bcf\u4e2a\u5143\u7d20\u90fd\u7531\u4e24\u4e2a\u7d22\u5f15\u786e\u5b9a\uff0c\u901a\u5e38\u79f0\u4e3a\u884c\u7d22\u5f15\u548c\u5217\u7d22\u5f15\u3002\u53ef\u4ee5\u8fd9\u6837\u7406\u89e3\uff1a\u9996\u5148\u9009\u5b9a\u4e00\u4e2a\u884c\uff0c\u7136\u540e\u518d\u5728\u8be5\u884c\u4e2d\u9009\u62e9\u4e00\u4e2a\u5143\u7d20\u3002\u7528\u4efb\u4f55\u4e00\u79cd\u7f16\u7a0b\u8bed\u8a00\u521b\u5efa\u548c\u64cd\u4f5c\u4e8c\u7ef4\u6570\u7ec4\u7684\u5177\u4f53\u8bed\u6cd5\u90fd\u4e0d\u5c3d\u76f8\u540c\uff0c\u4f46\u662f\u539f\u7406\u662f\u4e00\u6837\u7684\u3002 \u5728 Python \u4e2d\uff0c\u521b\u5efa\u4e8c\u7ef4\u6570\u7ec4\u7684\u4f8b\u5b50\u5982\u4e0b\uff1a # \u521b\u5efa\u4e00\u4e2a 3x3 \u7684\u4e8c\u7ef4\u6570\u7ec4 grid = [[ 1 , 2 , 3 ], [ 4 , 5 , 6 ], [ 7 , 8 , 9 ]] # \u8bbf\u95ee\u4e8c\u7ef4\u6570\u7ec4\u4e2d\u7279\u5b9a\u7684\u5143\u7d20 print ( grid [ 1 ][ 2 ]) # \u8f93\u51fa\uff1a6 2\uff0e\u8bf7\u63cf\u8ff0\u4e00\u4e2a\u53ef\u80fd\u4f1a\u7528\u5230\u4e8c\u7ef4\u6570\u7ec4\u7684\u5e94\u7528\u7a0b\u5e8f\u3002 \u89e3\u7b54\uff1a\u4e8c\u7ef4\u6570\u7ec4\u5728\u5404\u79cd\u7c7b\u578b\u7684\u5e94\u7528\u7a0b\u5e8f\u4e2d\u90fd\u88ab\u5e7f\u6cdb\u4f7f\u7528\u3002\u4e00\u4e2a\u5e38\u89c1\u7684\u4f8b\u5b50\u662f\u5728\u5904\u7406\u56fe\u50cf\u6216\u50cf\u7d20\u7684\u5e94\u7528\u4e2d\u3002 \u56fe\u50cf\u53ef\u4ee5\u88ab\u770b\u4f5c\u4e00\u4e2a\u4e8c\u7ef4\u6570\u7ec4\uff08\u6216\u8005\u5728\u5f69\u8272\u56fe\u50cf\u4e2d\uff0c\u662f\u4e00\u4e2a\u4e09\u7ef4\u6570\u7ec4\uff0c\u4e09\u4e2a\u901a\u9053\u5206\u522b\u662f\u7ea2\u3001\u7eff\u3001\u84dd\uff09\uff0c\u5176\u4e2d\u6bcf\u4e2a\u5143\u7d20\u8868\u793a\u4e00\u4e2a\u50cf\u7d20\u3002\u4e8c\u7ef4\u6570\u7ec4\u4e2d\u7684\u884c\u548c\u5217\u5bf9\u5e94\u4e8e\u56fe\u50cf\u7684\u5bbd\u5ea6\u548c\u9ad8\u5ea6\uff0c\u5143\u7d20\u503c\u901a\u5e38\u4ee3\u8868\u50cf\u7d20\u7684\u989c\u8272\u6df1\u5ea6\u3002 \u4f8b\u5982\uff0c\u4ee5\u4e0b Python \u4ee3\u7801\u521b\u5efa\u4e86\u4e00\u4e2a\u7b80\u5355\u7684\u7070\u5ea6\u56fe\u50cf\uff0c\u5e76\u4f7f\u7528 matplotlib \u5e93\u663e\u793a\u5b83\uff1a import numpy as np import matplotlib.pyplot as plt # \u521b\u5efa\u4e00\u4e2a 10x10 \u7684\u4e8c\u7ef4\u6570\u7ec4\uff0c\u6bcf\u4e2a\u5143\u7d20\u503c\u4e3a 0-255 \u4e4b\u95f4\u7684\u968f\u673a\u6574\u6570 image = np . random . randint ( 0 , 256 , ( 10 , 10 )) # \u663e\u793a\u8fd9\u4e2a\u56fe\u50cf plt . imshow ( image , cmap = 'gray' ) plt . show () \u5728\u8fd9\u4e2a\u4f8b\u5b50\u4e2d\uff0c\u6211\u4eec\u4f7f\u7528\u4e86 NumPy \u5e93\u6765\u521b\u5efa\u548c\u64cd\u4f5c\u4e8c\u7ef4\u6570\u7ec4\uff08\u5728 NumPy \u4e2d\uff0c\u8fd9\u79cd\u7ed3\u6784\u88ab\u79f0\u4e3a ndarray\uff09\u3002\u8fd9\u662f\u5904\u7406\u5927\u89c4\u6a21\u6570\u503c\u6570\u636e\u7684\u4e00\u4e2a\u975e\u5e38\u597d\u7684\u5de5\u5177\uff0c\u5c24\u5176\u662f\u5bf9\u4e8e\u6d89\u53ca\u5230\u79d1\u5b66\u8ba1\u7b97\u548c\u6570\u636e\u5206\u6790\u7684\u5e94\u7528\u7a0b\u5e8f\u3002 \u6b64\u5916\uff0c\u4e8c\u7ef4\u6570\u7ec4\u4e5f\u5e7f\u6cdb\u5e94\u7528\u4e8e\u6e38\u620f\u5f00\u53d1\uff08\u5982\u68cb\u76d8\u6e38\u620f\uff0c\u5982\u56fd\u9645\u8c61\u68cb\u6216\u4e95\u5b57\u6e38\u620f\u7684\u68cb\u76d8\u53ef\u4ee5\u7528\u4e8c\u7ef4\u6570\u7ec4\u6765\u8868\u793a\uff09\u3001\u7269\u7406\u6a21\u62df\u3001\u7cfb\u7edf\u52a8\u529b\u5b66\u6a21\u4eff\u3001\u5730\u7406\u4fe1\u606f\u7cfb\u7edf\uff08\u5730\u56fe\u53ef\u4ee5\u8868\u793a\u4e3a\u4e8c\u7ef4\u6570\u7ec4\u7684\u9ad8\u7a0b\u6570\u636e\uff09\u7b49\u8bb8\u591a\u9886\u57df\u3002 3\uff0e\u7f16\u5199\u4e00\u4e2a\u7a0b\u5e8f\uff0c\u4f7f\u4e4b\u53ef\u4ee5\u5728Grid\u5bf9\u8c61\u91cc\u641c\u7d22\u4e00\u4e2a\u8d1f\u6574\u6570\u3002\u5faa\u73af\u5e94\u8be5\u5728\u9047\u5230\u7f51\u683c\u91cc\u7684\u7b2c\u4e00\u4e2a\u8d1f\u6574\u6570\u7684\u5730\u65b9\u7ec8\u6b62\uff0c\u8fd9\u65f6\u53d8\u91cfrow\u548ccolumn\u5e94\u8be5\u88ab\u8bbe\u7f6e\u4e3a\u8fd9\u4e2a\u8d1f\u6570\u7684\u4f4d\u7f6e\u3002\u5982\u679c\u5728\u7f51\u683c\u91cc\u627e\u4e0d\u5230\u8d1f\u6570\uff0c\u90a3\u4e48\u53d8\u91cfrow\u548ccolumn\u5e94\u8be5\u7b49\u4e8e\u7f51\u683c\u7684\u884c\u6570\u548c\u5217\u6570\u3002 \u89e3\u7b54\uff1a\u5728Grid\u7c7b\u4e2d\u6dfb\u52a0\u4e0b\u9762\u7684\u65b9\u6cd5\uff0c\u53ef\u4ee5\u5b9e\u73b0\u63d0\u540d\u4e2d\u7684\u8981\u6c42 def find_negative ( self ): \"\"\"\u8fd4\u56de\u7b2c\u4e00\u4e2a\u8d1f\u6574\u6570\u7684\u7d22\u5f15\u503c\"\"\" target_row = 0 target_col = 0 for row in range ( self . getHeight ()): for col in range ( self . getWidth ()): # \u5982\u679c\u5f53\u524d\u5143\u7d20\u662f\u8d1f\u6570 if self . data [ row ][ col ] < 0 : # \u66f4\u65b0 row \u548c column \u4e3a\u8be5\u5143\u7d20\u7684\u4f4d\u7f6e target_row = row target_col = col # \u7ec8\u6b62\u5faa\u73af break # \u5982\u679c\u5df2\u627e\u5230\u8d1f\u6570\uff0c\u7ec8\u6b62\u5916\u5c42\u5faa\u73af if self . data [ row ][ col ] < 0 : break # \u8fd4\u56de\u8d1f\u6570\u7684\u4f4d\u7f6e\uff0c\u6216\u8005\u5982\u679c\u6ca1\u6709\u627e\u5230\u8d1f\u6570\uff0c\u8fd4\u56de\u884c\u6570\u548c\u5217\u6570 return row , col import random def main (): my_grid = Grid ( 5 , 5 , random . randint ( - 10 , 10 )) print ( my_grid ) print ( my_grid . find_negative ()) 4\uff0e\u8bf4\u8bf4\u8fd0\u884c\u4e0b\u9762\u8fd9\u6bb5\u4ee3\u7801\u540e\u7f51\u683c\u91cc\u7684\u5185\u5bb9\u662f\u4ec0\u4e48\u3002 matrix = Grid ( 3 , 3 ) for row in range ( matrix . getHeight ()): for column in range ( matrix . getWidth ()): matrix [ row ][ column ] = row * column \u89e3\u7b54\uff1a\u8fd9\u6bb5\u4ee3\u7801\u9996\u5148\u521b\u5efa\u4e86\u4e00\u4e2a3x3\u7684\u7f51\u683c\uff08\u6216\u4e8c\u7ef4\u6570\u7ec4\uff09\uff0c\u7136\u540e\u4f7f\u7528\u4e24\u4e2a\u5d4c\u5957\u7684for\u5faa\u73af\u6765\u904d\u5386\u8fd9\u4e2a\u7f51\u683c\u7684\u6bcf\u4e00\u4e2a\u5143\u7d20\u3002\u5bf9\u4e8e\u7f51\u683c\u4e2d\u7684\u6bcf\u4e00\u4e2a\u5143\u7d20\uff0c\u5b83\u7684\u503c\u88ab\u8bbe\u7f6e\u4e3a\u5176\u884c\u7d22\u5f15\u4e58\u4ee5\u5217\u7d22\u5f15\u3002\u7531\u4e8e\u7b2c\u4e00\u884c\u548c\u7b2c\u4e00\u5217\u7684\u7d22\u5f15\u90fd\u662f0\uff0c\u6240\u4ee5\u7b2c\u4e00\u884c\u548c\u7b2c\u4e00\u5217\u7684\u5143\u7d20\u503c\u90fd\u662f0\uff08\u56e0\u4e3a\u4efb\u4f55\u6570\u4e58\u4ee50\u90fd\u7b49\u4e8e0\uff09\u3002\u5176\u5b83\u5143\u7d20\u7684\u503c\u7b49\u4e8e\u5b83\u4eec\u7684\u884c\u7d22\u5f15\u4e58\u4ee5\u5217\u7d22\u5f15\u3002 0 0 0 0 1 2 0 2 4 5\uff0e\u7f16\u5199\u4e00\u6bb5\u4ee3\u7801\u4ee5\u521b\u5efa\u4e00\u4e2a\u53c2\u5dee\u4e0d\u9f50\u7684\u7f51\u683c\uff0c\u5b83\u7684\u884c\u5206\u522b\u7528\u6765\u5b58\u50a83\u4e2a\u30016\u4e2a\u548c9\u4e2a\u5143\u7d20\u3002 \u89e3\u7b54\uff1a\u4f7f\u7528\u5217\u8868\u7684\u5217\u8868\uff08\u5373\u5217\u8868\u7684\u5d4c\u5957\uff09\u6765\u521b\u5efa\u53c2\u5dee\u4e0d\u9f50\u7684\u7f51\u683c\u3002\u4e0b\u9762\u662fPython\u5b9e\u73b0\u4ee3\u7801\uff1a # \u521b\u5efa\u7a7a\u7f51\u683c grid = [] # \u4e3a\u7f51\u683c\u6dfb\u52a0\u884c grid . append ([ \"\" ] * 3 ) # \u7b2c\u4e00\u884c3\u4e2a\u5143\u7d20 grid . append ([ \"\" ] * 6 ) # \u7b2c\u4e8c\u884c6\u4e2a\u5143\u7d20 grid . append ([ \"\" ] * 9 ) # \u7b2c\u4e09\u884c9\u4e2a\u5143\u7d20 # \u6253\u5370\u7f51\u683c for row in grid : print ( row ) \u4e0a\u9762\u4ee3\u7801\u521b\u5efa\u4e00\u4e2a\u5177\u6709\u4e09\u884c\u7684\u7f51\u683c\uff0c\u5176\u4e2d\u7b2c\u4e00\u884c\u6709\u4e09\u4e2a\u5143\u7d20\uff0c\u7b2c\u4e8c\u884c\u6709\u516d\u4e2a\u5143\u7d20\uff0c\u7b2c\u4e09\u884c\u6709\u4e5d\u4e2a\u5143\u7d20\u3002\u6bcf\u4e2a\u5143\u7d20\u6700\u521d\u90fd\u88ab\u8bbe\u7f6e\u4e3a\u4e00\u4e2a\u7a7a\u5b57\u7b26\u4e32\uff0c\u8fd9\u4e2a\u7f51\u683c\u7684\u5f62\u72b6\u5c06\u7c7b\u4f3c\u4e8e\uff1a [ '' , '' , '' ] [ '' , '' , '' , '' , '' , '' ] [ '' , '' , '' , '' , '' , '' , '' , '' , '' ] 6\uff0e\u63d0\u4f9b\u4e00\u4e2a\u628aGrid\u7c7b\u7528\u4f5c\u6570\u636e\u7ed3\u6784\u6765\u5b9e\u73b0\u4e09\u7ef4array\u7c7b\u7684\u7b56\u7565\u3002 \u89e3\u7b54\uff1a\u4ee3\u7801\u5b9e\u73b0\u5982\u4e0b\uff1a class ThreeDArray ( object ): \"\"\"\u63cf\u8ff0\u4e00\u4e2a\u4e09\u7ef4\u6570\u7ec4\u3002\"\"\" def __init__ ( self , depth , rows , columns , fillValue = None ): self . depth = depth self . rows = rows self . columns = columns self . fillValue = fillValue # \u521d\u59cb\u5316\u4e09\u7ef4\u6570\u7ec4\uff0c\u6309\u7167\u6df1\u5ea6\u521d\u59cb\u5316\u6bcf\u4e00\u5c42\u4e3a\u4e00\u4e2a\u4e8c\u7ef4\u6570\u7ec4 self . data = Array ( depth , fillValue ) for d in range ( depth ): self . data [ d ] = Grid ( rows , columns , fillValue ) def getDepth ( self ): \"\"\"\u8fd4\u56de\u4e09\u7ef4\u6570\u7ec4\u7684z\u8f74\u5927\u5c0f, \u5373\u6570\u7ec4\u7684\u6df1\u5ea6\"\"\" return len ( self . data ) def get_element ( self , depth , row , column ): \"\"\"\u83b7\u53d6\u6307\u5b9a\u6df1\u5ea6\u3001\u884c\u548c\u5217\u7684\u5143\u7d20\"\"\" return self . data [ depth ][ row ][ column ] def set_element ( self , depth , row , column , new_value ): \"\"\"\u8bbe\u7f6e\u6307\u5b9a\u6df1\u5ea6\u3001\u884c\u548c\u5217\u7684\u5143\u7d20\"\"\" self . data [ depth ][ row ][ column ] = new_value def add_element ( self , depth , row , column , value ): \"\"\"\u5728\u6307\u5b9a\u6df1\u5ea6\u3001\u884c\u548c\u5217\u6dfb\u52a0\u5143\u7d20 \"\"\" if self . data [ depth ][ row ][ column ] == self . fillValue : self . data [ depth ][ row ][ column ] = value else : raise Exception ( \"\u5143\u7d20\u6dfb\u52a0\u5931\u8d25\" ) def remove_element ( self , depth , row , column ): \"\"\"\u5728\u6307\u5b9a\u6df1\u5ea6\u3001\u884c\u548c\u5217\u5220\u9664\u5143\u7d20 \"\"\" if self . data [ depth ][ row ][ column ] != self . fillValue : self . data [ depth ][ row ][ column ] = self . fillValue else : raise Exception ( \"\u5143\u7d20\u5220\u9664\u5931\u8d25\" ) def __str__ ( self ): result = \"\" for depth in range ( self . getDepth ()): result += f \"Depth { depth } : \\n \" for row in range ( self . rows ): for column in range ( self . columns ): result += str ( self . data [ depth ][ row ][ column ]) + \" \\t \" result += \" \\n \" return result def main (): print ( \"---Initial 3D Array---\" ) my_3d = ThreeDArray ( 3 , 2 , 2 , 9 ) print ( my_3d ) print ( \"---Add element into 3D Array---\" ) my_3d . add_element ( 0 , 1 , 1 , 0 ) my_3d . add_element ( 1 , 1 , 1 , 1 ) my_3d . add_element ( 2 , 1 , 1 , 2 ) print ( my_3d ) print ( \"---Remove element from 3D Array---\" ) my_3d . remove_element ( 1 , 1 , 1 ) print ( my_3d ) if __name__ == \"__main__\" : main () # \u8fd0\u884c\u7ed3\u679c # ---Initial 3D Array--- # Depth 0: # 9 9 # 9 9 # Depth 1: # 9 9 # 9 9 # Depth 2: # 9 9 # 9 9 # ---Add element into 3D Array--- # Depth 0: # 9 9 # 9 0 # Depth 1: # 9 9 # 9 1 # Depth 2: # 9 9 # 9 2 # ---Remove element from 3D Array--- # Depth 0: # 9 9 # 9 0 # Depth 1: # 9 9 # 9 9 # Depth 2: # 9 9 # 9 2 7\uff0e\u7f16\u5199\u4e00\u6bb5\u4ee3\u7801\uff1a\u8fd9\u6bb5\u4ee3\u7801\u4f1a\u628a\u4e09\u7ef4\u6570\u7ec4\u91cc\u6bcf\u4e2a\u5355\u5143\u7684\u503c\u90fd\u521d\u59cb\u5316\u4e3a\u5b83\u76843\u4e2a\u7d22\u5f15\u4f4d\u7f6e\u3002\u4f8b\u5982\uff0c\u5982\u679c\u4f4d\u7f6e\u662f\uff08\u6df1\u5ea6\u3001\u884c\u3001\u5217\uff09\uff0c\u5219\u5bf9\u4e8e\u4f4d\u7f6e\uff082\u30013\u30013\uff09\u6765\u8bf4\uff0c\u5b83\u7684\u503c\u5c31\u662f233\u3002 \u89e3\u7b54\uff1a\u4fee\u6539\u4e0a\u9762\u7684\u4ee3\u7801\u4e2d\u7684 __init__ \u548c __str__ \u65b9\u6cd5\uff0c\u4ee3\u7801\u5b9e\u73b0\u5982\u4e0b\u3002 class ThreeDArray ( object ): \"\"\"\u63cf\u8ff0\u4e00\u4e2a\u4e09\u7ef4\u6570\u7ec4\u3002\"\"\" # def __init__(self, depth, rows, columns, fillValue=None): # self.depth = depth # self.rows = rows # self.columns = columns # self.fillValue = fillValue # # \u521d\u59cb\u5316\u4e09\u7ef4\u6570\u7ec4\uff0c\u6309\u7167\u6df1\u5ea6\u521d\u59cb\u5316\u6bcf\u4e00\u5c42\u4e3a\u4e00\u4e2a\u4e8c\u7ef4\u6570\u7ec4 # self.data = Array(depth, fillValue) # for d in range(depth): # self.data[d] = Grid(rows, columns, fillValue) def __init__ ( self , depth , rows , columns ): self . depth = depth self . rows = rows self . columns = columns # \u521d\u59cb\u5316\u4e09\u7ef4\u6570\u7ec4\uff0c\u6309\u7167\u6df1\u5ea6\u521d\u59cb\u5316\u6bcf\u4e00\u5c42\u4e3a\u4e00\u4e2a\u4e8c\u7ef4\u6570\u7ec4 self . data = Array ( depth ) for d in range ( depth ): self . data [ d ] = Grid ( rows , columns ) for r in range ( rows ): for c in range ( columns ): # \u5c06\u6bcf\u4e2a\u4f4d\u7f6e\u7684\u7d22\u5f15\u62fc\u63a5\u6210\u5b57\u7b26\u4e32\u4f5c\u4e3a\u5143\u7d20\u503c self . data [ d ][ r ][ c ] = str ( d ) + str ( r ) + str ( c ) def getDepth ( self ): \"\"\"\u8fd4\u56de\u4e09\u7ef4\u6570\u7ec4\u7684z\u8f74\u5927\u5c0f, \u5373\u6570\u7ec4\u7684\u6df1\u5ea6\"\"\" return len ( self . data ) def get_element ( self , depth , row , column ): \"\"\"\u83b7\u53d6\u6307\u5b9a\u6df1\u5ea6\u3001\u884c\u548c\u5217\u7684\u5143\u7d20\"\"\" return self . data [ depth ][ row ][ column ] def set_element ( self , depth , row , column , new_value ): \"\"\"\u8bbe\u7f6e\u6307\u5b9a\u6df1\u5ea6\u3001\u884c\u548c\u5217\u7684\u5143\u7d20\"\"\" self . data [ depth ][ row ][ column ] = new_value def add_element ( self , depth , row , column , value ): \"\"\"\u5728\u6307\u5b9a\u6df1\u5ea6\u3001\u884c\u548c\u5217\u6dfb\u52a0\u5143\u7d20 \"\"\" if self . data [ depth ][ row ][ column ] == self . fillValue : self . data [ depth ][ row ][ column ] = value else : raise Exception ( \"\u5143\u7d20\u6dfb\u52a0\u5931\u8d25\" ) def remove_element ( self , depth , row , column ): \"\"\"\u5728\u6307\u5b9a\u6df1\u5ea6\u3001\u884c\u548c\u5217\u5220\u9664\u5143\u7d20 \"\"\" if self . data [ depth ][ row ][ column ] != self . fillValue : self . data [ depth ][ row ][ column ] = self . fillValue else : raise Exception ( \"\u5143\u7d20\u5220\u9664\u5931\u8d25\" ) # def __str__(self): # result = \"\" # for depth in range(self.getDepth()): # result += f\"Depth {depth}:\\n\" # for row in range(self.rows): # for column in range(self.columns): # result += str(self.data[depth][row][column]) + \"\\t\" # result += \"\\n\" # return result def __str__ ( self ): result = \"\" for depth in range ( self . getDepth ()): result += f \"Depth { depth } : \\n \" for row in range ( self . rows ): for column in range ( self . columns ): result += str ( self . data [ depth ][ row ][ column ]) + \" \\t \" result += \" \\n \" return result def main (): my_3d = ThreeDArray ( 3 , 4 , 4 ) print ( my_3d ) # \u6253\u5370\u521d\u59cb\u72b6\u6001 if __name__ == \"__main__\" : main () # \u8fd0\u884c\u7ed3\u679c # Depth 0: # 000 001 002 003 # 010 011 012 013 # 020 021 022 023 # 030 031 032 033 # Depth 1: # 100 101 102 103 # 110 111 112 113 # 120 121 122 123 # 130 131 132 133 # Depth 2: # 200 201 202 203 # 210 211 212 213 # 220 221 222 223 # 230 231 232 233 8\uff0e\u7f16\u5199\u4e00\u6bb5\u4ee3\u7801\uff1a\u8fd9\u6bb5\u4ee3\u7801\u53ef\u4ee5\u663e\u793a\u51fa\u4e09\u7ef4\u6570\u7ec4\u91cc\u7684\u6240\u6709\u5143\u7d20\u3002\u6253\u5370\u51fa\u7684\u6bcf\u4e00\u884c\u6570\u636e\u90fd\u5e94\u8be5\u4ee3\u8868\u7ed9\u5b9a\u884c\u548c\u5217\u91cc\u7684\u6240\u6709\u5143\u7d20\uff0c\u800c\u6df1\u5ea6\u5c06\u4ece\u7b2c\u4e00\u4e2a\u4f4d\u7f6e\u5411\u540e\u9012\u5f52\u5230\u6700\u540e\u4e00\u4e2a\u4f4d\u7f6e\u3002\u904d\u5386\u5e94\u8be5\u4ece\u7b2c1\u884c\u3001\u7b2c1\u5217\u4ee5\u53ca\u7b2c\u4e00\u4e2a\u6df1\u5ea6\u4f4d\u7f6e\u5f00\u59cb\uff0c\u4f9d\u6b21\u904d\u5386\u6240\u6709\u7684\u6df1\u5ea6\u3001\u5217\u548c\u884c\u3002 \u89e3\u7b54\uff1a\u6dfb\u52a0\u4e86\u4e00\u4e2a\u65b9\u6cd5 printAllElements \uff0c\u4ee3\u7801\u5b9e\u73b0\u5982\u4e0b\uff1a class ThreeDArray ( object ): \"\"\"\u63cf\u8ff0\u4e00\u4e2a\u4e09\u7ef4\u6570\u7ec4\u3002\"\"\" # def __init__(self, depth, rows, columns, fillValue=None): # self.depth = depth # self.rows = rows # self.columns = columns # self.fillValue = fillValue # # \u521d\u59cb\u5316\u4e09\u7ef4\u6570\u7ec4\uff0c\u6309\u7167\u6df1\u5ea6\u521d\u59cb\u5316\u6bcf\u4e00\u5c42\u4e3a\u4e00\u4e2a\u4e8c\u7ef4\u6570\u7ec4 # self.data = Array(depth, fillValue) # for d in range(depth): # self.data[d] = Grid(rows, columns, fillValue) def __init__ ( self , depth , rows , columns ): self . depth = depth self . rows = rows self . columns = columns # \u521d\u59cb\u5316\u4e09\u7ef4\u6570\u7ec4\uff0c\u6309\u7167\u6df1\u5ea6\u521d\u59cb\u5316\u6bcf\u4e00\u5c42\u4e3a\u4e00\u4e2a\u4e8c\u7ef4\u6570\u7ec4 self . data = Array ( depth ) for d in range ( depth ): self . data [ d ] = Grid ( rows , columns ) for r in range ( rows ): for c in range ( columns ): # \u5c06\u6bcf\u4e2a\u4f4d\u7f6e\u7684\u7d22\u5f15\u62fc\u63a5\u6210\u5b57\u7b26\u4e32\u4f5c\u4e3a\u5143\u7d20\u503c self . data [ d ][ r ][ c ] = str ( d ) + str ( r ) + str ( c ) def getDepth ( self ): \"\"\"\u8fd4\u56de\u4e09\u7ef4\u6570\u7ec4\u7684z\u8f74\u5927\u5c0f, \u5373\u6570\u7ec4\u7684\u6df1\u5ea6\"\"\" return len ( self . data ) def get_element ( self , depth , row , column ): \"\"\"\u83b7\u53d6\u6307\u5b9a\u6df1\u5ea6\u3001\u884c\u548c\u5217\u7684\u5143\u7d20\"\"\" return self . data [ depth ][ row ][ column ] def set_element ( self , depth , row , column , new_value ): \"\"\"\u8bbe\u7f6e\u6307\u5b9a\u6df1\u5ea6\u3001\u884c\u548c\u5217\u7684\u5143\u7d20\"\"\" self . data [ depth ][ row ][ column ] = new_value def add_element ( self , depth , row , column , value ): \"\"\"\u5728\u6307\u5b9a\u6df1\u5ea6\u3001\u884c\u548c\u5217\u6dfb\u52a0\u5143\u7d20 \"\"\" if self . data [ depth ][ row ][ column ] == self . fillValue : self . data [ depth ][ row ][ column ] = value else : raise Exception ( \"\u5143\u7d20\u6dfb\u52a0\u5931\u8d25\" ) def remove_element ( self , depth , row , column ): \"\"\"\u5728\u6307\u5b9a\u6df1\u5ea6\u3001\u884c\u548c\u5217\u5220\u9664\u5143\u7d20 \"\"\" if self . data [ depth ][ row ][ column ] != self . fillValue : self . data [ depth ][ row ][ column ] = self . fillValue else : raise Exception ( \"\u5143\u7d20\u5220\u9664\u5931\u8d25\" ) def printAllElements ( self ): \"\"\"\u6253\u5370\u4e09\u7ef4\u6570\u7ec4\u4e2d\u7684\u6240\u6709\u5143\u7d20\u3002\"\"\" for row in range ( self . rows ): for col in range ( self . columns ): for depth in range ( self . depth ): print ( f \"Element at position ( { row } , { col } , { depth } ): { self . data [ depth ][ row ][ col ] } \" ) # def __str__(self): # result = \"\" # for depth in range(self.getDepth()): # result += f\"Depth {depth}:\\n\" # for row in range(self.rows): # for column in range(self.columns): # result += str(self.data[depth][row][column]) + \"\\t\" # result += \"\\n\" # return result def __str__ ( self ): result = \"\" for depth in range ( self . getDepth ()): result += f \"Depth { depth } : \\n \" for row in range ( self . rows ): for column in range ( self . columns ): result += str ( self . data [ depth ][ row ][ column ]) + \" \\t \" result += \" \\n \" return result def main (): my_3d = ThreeDArray ( 3 , 4 , 4 ) print ( my_3d ) # \u6253\u5370\u521d\u59cb\u72b6\u6001 my_3d . printAllElements () if __name__ == \"__main__\" : main () # \u8fd0\u884c\u7ed3\u679c # Depth 0: # 000 001 002 003 # 010 011 012 013 # 020 021 022 023 # 030 031 032 033 # Depth 1: # 100 101 102 103 # 110 111 112 113 # 120 121 122 123 # 130 131 132 133 # Depth 2: # 200 201 202 203 # 210 211 212 213 # 220 221 222 223 # 230 231 232 233 # Element at position (0, 0, 0): 000 # Element at position (0, 0, 1): 100 # Element at position (0, 0, 2): 200 # Element at position (0, 1, 0): 001 # Element at position (0, 1, 1): 101 # Element at position (0, 1, 2): 201 # Element at position (0, 2, 0): 002 # Element at position (0, 2, 1): 102 # Element at position (0, 2, 2): 202 # Element at position (0, 3, 0): 003 # Element at position (0, 3, 1): 103 # Element at position (0, 3, 2): 203 # Element at position (1, 0, 0): 010 # Element at position (1, 0, 1): 110 # Element at position (1, 0, 2): 210 # Element at position (1, 1, 0): 011 # Element at position (1, 1, 1): 111 # Element at position (1, 1, 2): 211 # Element at position (1, 2, 0): 012 # Element at position (1, 2, 1): 112 # Element at position (1, 2, 2): 212 # Element at position (1, 3, 0): 013 # Element at position (1, 3, 1): 113 # Element at position (1, 3, 2): 213 # Element at position (2, 0, 0): 020 # Element at position (2, 0, 1): 120 # Element at position (2, 0, 2): 220 # Element at position (2, 1, 0): 021 # Element at position (2, 1, 1): 121 # Element at position (2, 1, 2): 221 # Element at position (2, 2, 0): 022 # Element at position (2, 2, 1): 122 # Element at position (2, 2, 2): 222 # Element at position (2, 3, 0): 023 # Element at position (2, 3, 1): 123 # Element at position (2, 3, 2): 223 # Element at position (3, 0, 0): 030 # Element at position (3, 0, 1): 130 # Element at position (3, 0, 2): 230 # Element at position (3, 1, 0): 031 # Element at position (3, 1, 1): 131 # Element at position (3, 1, 2): 231 # Element at position (3, 2, 0): 032 # Element at position (3, 2, 1): 132 # Element at position (3, 2, 2): 232 # Element at position (3, 3, 0): 033 # Element at position (3, 3, 1): 133 # Element at position (3, 3, 2): 233","title":"4.3.5.\u7ec3\u4e60\u9898"},{"location":"python/DataStructure/04_ArrayChain/#44","text":"\u94fe\u63a5\u7ed3\u6784\u4f5c\u4e3a\u4e00\u79cd\u6570\u636e\u7c7b\u578b\uff0c\u53ef\u4ee5\u7528\u6765\u5b9e\u73b0\u82e5\u5e72\u7c7b\u578b\u7684\u591a\u9879\u96c6\uff08\u5305\u62ec\u5217\u8868\uff09\u3002 \u76ee\u6807\uff1a\u5728\u4f7f\u7528\u94fe\u63a5\u7ed3\u6784\u5b9e\u73b0\u4efb\u4f55\u7c7b\u578b\u7684\u591a\u9879\u96c6\u65f6\u6240\u5fc5\u987b\u8981\u77e5\u9053\u7684\u51e0\u4e2a\u7279\u5f81\uff0c\u4ee5\u53ca\u5982\u4f55\u5728\u591a\u9879\u96c6\uff08\u5982\u5217\u8868\u548c\u4e8c\u53c9\u6811\uff09\u91cc\u4f7f\u7528\u94fe\u63a5\u7ed3\u6784\u3002","title":"4.4.\u94fe\u63a5\u7ed3\u6784"},{"location":"python/DataStructure/04_ArrayChain/#441","text":"\u94fe\u63a5\u7ed3\u6784\u7531\u53ef\u4ee5\u94fe\u63a5\u5230\u5176\u4ed6\u8282\u70b9\u7684\u8282\u70b9\u7ec4\u6210\u3002 \u8282\u70b9\u4e4b\u95f4\u6700\u7b80\u5355\u7684\u94fe\u63a5\u7ed3\u6784\u662f\uff1a \u5355\u5411\u94fe\u63a5\u7ed3\u6784\uff08singly linked structure\uff09 \u53cc\u5411\u94fe\u63a5\u7ed3\u6784\uff08doubly linked structure\uff09 \u4e0b\u9762\u56fe\u4f8b\u662f\u7528\u6846\u548c\u6307\u9488\u7b26\u53f7\u7ed8\u51fa\u5355\u5411\u548c\u53cc\u5411\u94fe\u63a5\u7ed3\u6784\u3002 \u901a\u8fc7\u4e00\u4e2a\u989d\u5916\u7684\u5934\u90e8\u94fe\u63a5\uff08head link\uff09\uff0c\u53ef\u4ee5\u4f7f\u7528\u5355\u5411\u94fe\u63a5\u7ed3\u6784\u8bbf\u95ee\u7b2c\u4e00\u4e2a\u8282\u70b9\u3002\u63a5\u4e0b\u6765\uff0c\u6211\u4eec\u5c31\u53ef\u4ee5\u901a\u8fc7\u8fd9\u4e2a\u8282\u70b9\u91cc\u53d1\u51fa\u7684\u94fe\u63a5\uff08\u4e0a\u56fe\u4e2d\u7684\u7bad\u5934\uff09\u6765\u8bbf\u95ee\u5176\u4ed6\u8282\u70b9\u4e86\u3002\u56e0\u6b64\uff0c\u5728\u5355\u5411\u94fe\u63a5\u7ed3\u6784\u91cc\uff0c\u6211\u4eec\u53ef\u4ee5\u5f88\u5bb9\u6613\u5730\u83b7\u5f97\u8282\u70b9\u7684\u540e\u7ee7\u8282\u70b9\uff0c\u4f46\u4e0d\u90a3\u4e48\u5bb9\u6613\u83b7\u5f97\u8282\u70b9\u7684\u524d\u5e8f\u8282\u70b9\u3002 \u53cc\u5411\u94fe\u63a5\u7ed3\u6784\u4f1a\u5305\u542b\u53cc\u5411\u7684\u94fe\u63a5\uff0c\u6211\u4eec\u53ef\u4ee5\u5f88\u5bb9\u6613\u5730\u79fb\u52a8\u5230\u8282\u70b9\u7684\u524d\u5e8f\u6216\u8005\u540e\u7ee7\u8282\u70b9\uff0c\u8fd9\u4e2a\u65f6\u5019\u4f1a\u7528\u5230\u7b2c\u4e8c\u4e2a\u989d\u5916\u7684\u94fe\u63a5\uff08\u5c3e\u90e8\u94fe\u63a5tail link\uff09\u3002\u5c3e\u90e8\u94fe\u63a5\u80fd\u591f\u8ba9\u53cc\u5411\u94fe\u63a5\u7ed3\u6784\u7684\u7528\u6237\u76f4\u63a5\u8bbf\u95ee\u6700\u540e\u4e00\u4e2a\u8282\u70b9\u3002 \u5728\u4e24\u79cd\u94fe\u63a5\u7ed3\u6784\u91cc\uff0c\u6700\u540e\u4e00\u4e2a\u8282\u70b9\u90fd\u6ca1\u6709\u6307\u5411\u540e\u7eed\u8282\u70b9\u7684\u94fe\u63a5\u3002\u5728\u4e0a\u56fe\u4e2d\uff0c\u7528\u659c\u6760\u4ee3\u66ff\u7bad\u5934\u4ee5\u8868\u793a\u6ca1\u6709\u94fe\u63a5\uff0c\u8fd9\u79f0\u4e3a\u7a7a\u94fe\u63a5\uff08empty link\uff09\u3002 \u5728\u53cc\u5411\u94fe\u63a5\u7ed3\u6784\u91cc\uff0c\u7b2c\u4e00\u4e2a\u8282\u70b9\u4e5f\u6ca1\u6709\u6307\u5411\u524d\u5e8f\u8282\u70b9\u7684\u94fe\u63a5\u3002 \u548c\u6570\u7ec4\u4e00\u6837\uff0c\u94fe\u63a5\u7ed3\u6784\u4e5f\u53ef\u4ee5\u7528\u6765\u5b58\u50a8\u5143\u7d20\u7684\u7ebf\u6027\u5e8f\u5217\uff0c\u4f46\u65e0\u6cd5\u901a\u8fc7\u6307\u5b9a\u7684\u7d22\u5f15\u4f4d\u7f6e\u76f4\u63a5\u8bbf\u95ee\u8fd9\u4e2a\u5143\u7d20\uff0c\u5fc5\u987b\u4ece\u6570\u636e\u7ed3\u6784\u7684\u4e00\u4e2a\u9876\u7aef\u5f00\u59cb\uff0c\u7136\u540e\u6309\u7167\u94fe\u63a5\u8fdb\u884c\u8bbf\u95ee\uff0c\u76f4\u81f3\u5230\u8fbe\u6240\u9700\u7684\u4f4d\u7f6e\uff08\u6216\u627e\u5230\u671f\u671b\u7684\u5143\u7d20\uff09\u4e3a\u6b62\u3002\u94fe\u63a5\u7ed3\u6784\u7684\u8fd9\u79cd\u6027\u8d28\u5bf9\u4e8e\u5f88\u591a\u64cd\u4f5c\u90fd\u6709\u663e\u8457\u7684\u5f71\u54cd\u3002 \u4e3a\u94fe\u63a5\u7ed3\u6784\u5206\u914d\u5185\u5b58\u7684\u65b9\u5f0f\u548c\u4e3a\u6570\u7ec4\u5206\u914d\u5185\u5b58\u7684\u65b9\u5f0f\u662f\u5b8c\u5168\u4e0d\u540c\u7684\uff0c\u800c\u4e14\u5bf9\u4e8e\u63d2\u5165\u548c\u5220\u9664\u64cd\u4f5c\u6765\u8bf4\uff0c\u6709\u4e24\u4e2a\u663e\u8457\u5f71\u54cd\u3002 \u5728\u627e\u5230\u63d2\u5165\u6216\u5220\u9664\u70b9\u4e4b\u540e\uff0c\u53ef\u4ee5\u5728\u4e0d\u79fb\u52a8\u5185\u5b58\u91cc\u7684\u6570\u636e\u5143\u7d20\u7684\u60c5\u51b5\u4e0b\u6267\u884c\u63d2\u5165\u6216\u5220\u9664\u64cd\u4f5c\u3002 \u53ef\u4ee5\u5728\u6bcf\u6b21\u63d2\u5165\u6216\u5220\u9664\u671f\u95f4\u81ea\u52a8\u8c03\u6574\u94fe\u63a5\u7ed3\u6784\u7684\u5927\u5c0f\uff0c\u4e0d\u9700\u8981\u82b1\u8d39\u989d\u5916\u7684\u5185\u5b58\u7a7a\u95f4\uff0c\u4e5f\u4e0d\u9700\u8981\u590d\u5236\u6570\u636e\u5143\u7d20\u3002","title":"4.4.1.\u5355\u5411\u94fe\u63a5\u7ed3\u6784\u548c\u53cc\u5411\u94fe\u63a5\u7ed3\u6784"},{"location":"python/DataStructure/04_ArrayChain/#442","text":"\u6570\u7ec4\u91cc\u7684\u5143\u7d20\u5fc5\u987b\u5b58\u50a8\u5728\u4e00\u6bb5\u8fde\u7eed\u7684\u5185\u5b58\u4e2d\uff0c\u8fd9\u5c31\u610f\u5473\u7740\u6570\u7ec4\u91cc\u5404\u4e2a\u5143\u7d20\u7684\u903b\u8f91\u987a\u5e8f\u548c\u5b83\u4eec\u5728\u5185\u5b58\u5355\u5143\u91cc\u7684\u7269\u7406\u987a\u5e8f\u662f\u7d27\u5bc6\u8026\u5408\u7684\u3002 \u76f8\u6bd4\u800c\u8a00\uff0c\u94fe\u63a5\u7ed3\u6784\u4f1a\u628a\u7ed3\u6784\u91cc\u5404\u4e2a\u5143\u7d20\u7684\u903b\u8f91\u987a\u5e8f\u548c\u5b83\u4eec\u5728\u5185\u5b58\u91cc\u7684\u987a\u5e8f\u89e3\u8026\u3002\u8981\u5728\u5185\u5b58\u7684\u67d0\u4e2a\u4f4d\u7f6e\u4e0a\u627e\u5230\u94fe\u63a5\u7ed3\u6784\u91cc\u7279\u5b9a\u5143\u7d20\u7684\u5185\u5b58\u5355\u5143\uff0c\u53ea\u9700\u8981\u8ba9\u8ba1\u7b97\u673a\u8ddf\u968f\u6307\u5411\u8fd9\u4e2a\u5143\u7d20\u7684\u5730\u5740\u6216\u4f4d\u7f6e\u94fe\u63a5\u5c31\u884c\u4e86\u3002\u8fd9\u79f0\u4e3a\u975e\u8fde\u7eed\u5185\u5b58\uff08noncontiguous memory\uff09\u3002 \u94fe\u63a5\u7ed3\u6784\u91cc\u7528\u6765\u5b58\u50a8\u7684\u57fa\u672c\u5355\u4f4d\u662f\u8282\u70b9\uff08node\uff09\u3002 \u5355\u5411\u94fe\u63a5\u8282\u70b9\uff08singly linked node\uff09\u5305\u542b\u4e0b\u9762\u8fd9\u4e9b\u7ec4\u4ef6\u6216\u5b57\u6bb5\uff1a \u6570\u636e\u5143\u7d20\uff1b \u6307\u5411\u7ed3\u6784\u91cc\u540e\u7ee7\u8282\u70b9\u7684\u94fe\u63a5\uff1b \u5bf9\u4e8e\u53cc\u5411\u94fe\u63a5\u8282\u70b9\uff08doubly linked node\uff09\u5305\u542b\u4e0b\u9762\u8fd9\u4e9b\u7ec4\u4ef6\u6216\u5b57\u6bb5\uff1a \u6570\u636e\u5143\u7d20\uff1b \u6307\u5411\u7ed3\u6784\u91cc\u540e\u7ee7\u8282\u70b9\u7684\u94fe\u63a5\uff1b \u6307\u5411\u7ed3\u6784\u91cc\u524d\u5e8f\u8282\u70b9\u7684\u94fe\u63a5\uff1b \u4e0d\u540c\u7684\u7f16\u7a0b\u8bed\u8a00\uff0c\u901a\u8fc7\u4e0d\u540c\u7684\u65b9\u6cd5\u6765\u8ba9\u8282\u70b9\u5229\u7528\u975e\u8fde\u7eed\u5185\u5b58\u3002 FORTRAN\u8bed\u8a00\u4e2d\uff0c\u901a\u8fc7\u4e24\u4e2a\u5e76\u6392\u7684\u6570\u7ec4\u4e3a\u5355\u5411\u94fe\u63a5\u7ed3\u6784\u5b9e\u73b0\u975e\u8fde\u7eed\u5185\u5b58\u548c\u8282\u70b9\u3002\u8fd9\u6837\u505a\u53ef\u4ee5\u6709\u6548\u5730\u5c06\u94fe\u63a5\u7ed3\u6784\u91cc\u6570\u636e\u5143\u7d20\u7684\u903b\u8f91\u4f4d\u7f6e\u548c\u5b83\u5728\u6570\u7ec4\u91cc\u7684\u7269\u7406\u4f4d\u7f6e\u5206\u79bb\u3002 \u7b2c\u4e00\u4e2a\u6570\u7ec4\u5305\u542b\u6570\u636e\u5143\u7d20\uff1b\u7b2c\u4e8c\u4e2a\u6570\u7ec4\u5219\u5305\u542b\u6570\u636e\u6570\u7ec4\u91cc\u5f53\u524d\u8282\u70b9\u6240\u5bf9\u5e94\u7684\u540e\u7eed\u8282\u70b9\u7684\u7d22\u5f15\u4f4d\u7f6e\u3002 \u7528\u7b2c\u4e00\u4e2a\u6570\u7ec4\u91cc\u7684\u6570\u636e\u5143\u7d20\u7d22\u5f15\u6765\u8bbf\u95ee\u7b2c\u4e8c\u4e2a\u6570\u7ec4\u91cc\u7684\u503c\uff0c\u7136\u540e\u518d\u628a\u8fd9\u4e2a\u503c\u4f5c\u4e3a\u7b2c\u4e00\u4e2a\u6570\u7ec4\u91cc\u4e0b\u4e00\u4e2a\u6570\u636e\u5143\u7d20\u7684\u7d22\u5f15\u3002\u7a7a\u94fe\u63a5\u4f1a\u7528\u503c\u22121\u6765\u8868\u793a\u3002 Pascal\u548cC++\u8bed\u8a00\u4e2d\uff0c\u901a\u8fc7\u8bbf\u95ee\u6307\u9488\uff08pointer\uff09\u76f4\u63a5\u5f97\u5230\u6240\u9700\u7684\u6570\u636e\u5730\u5740\u3002 \u5355\u5411\u94fe\u63a5\u7ed3\u6784\u91cc\u7684\u8282\u70b9\u5305\u542b\u4e00\u4e2a\u6570\u636e\u5143\u7d20\u548c\u4e00\u4e2a\u6307\u9488\u503c\u3002\u5bf9\u4e8e\u7a7a\u94fe\u63a5\u6765\u8bf4\uff0c\u5b83\u7684\u6307\u9488\u503c\u7528\u7279\u6b8a\u503cnull\uff08\u6216nil\uff09\u6765\u8868\u793a\u3002 \u8bf7\u6c42\u4e00\u4e2a\u5bf9\u8c61\u5806\uff08object heap\uff09\u7684\u65b0\u8282\u70b9\u7684\u6307\u9488\uff0c\u8fd9\u4e2a\u8282\u70b9\u6765\u81ea\u975e\u8fde\u7eed\u5185\u5b58\u7684\u5185\u7f6e\u533a\u57df\uff0c\u5e76\u628a\u8fd9\u4e2a\u8282\u70b9\u91cc\u7684\u6307\u9488\u8bbe\u7f6e\u4e3a\u6307\u5411\u53e6\u4e00\u4e2a\u8282\u70b9\uff0c\u4ece\u800c\u5efa\u7acb\u5230\u8fd9\u4e2a\u94fe\u63a5\u7ed3\u6784\u91cc\u5176\u4ed6\u6570\u636e\u7684\u94fe\u63a5\u3002 \u901a\u8fc7\u663e\u5f0f\u5730\u4f7f\u7528\u6307\u9488\u548c\u5185\u7f6e\u5806\uff0c\u53ef\u4ee5\u4e0d\u518d\u9700\u8981\u7ba1\u7406\u975e\u8fde\u7eed\u5185\u5b58\u7684\u5e95\u5c42\u6570\u7ec4\u5b58\u50a8\u65b9\u5f0f\u4e86\uff0c\u4f46\u8fd8\u662f\u9700\u8981\u4eba\u4e3a\u7ba1\u7406\u5806\uff0c\u901a\u8fc7\u7279\u6b8a\u7684dispose\u6216delete\u64cd\u4f5c\u628a\u4e0d\u4f7f\u7528\u7684\u8282\u70b9\u8fd4\u56de\u7ed9\u5806\u3002 Python\u8bed\u8a00\u4e2d\uff0c\u901a\u8fc7\u4f7f\u7528\u5bf9\u5bf9\u8c61\u7684\u5f15\u7528\uff08reference\uff09\u8bbe\u7f6e\u8282\u70b9\u548c\u94fe\u63a5\u7ed3\u6784\u3002 Python\u4e2d\uff0c\u4efb\u4f55\u53d8\u91cf\u90fd\u53ef\u4ee5\u7528\u6765\u5f15\u7528\u4efb\u4f55\u6570\u636e\uff0c\u8fd9\u4e5f\u5305\u62ec\u503c None \uff0c\u5b83\u53ef\u4ee5\u7528\u6765\u4ee3\u8868\u7a7a\u94fe\u63a5\u3002 Python\u4e2d\uff0c\u5b9a\u4e49\u5305\u542b\u4e24\u4e2a\u5b57\u6bb5\u7684\u5bf9\u8c61\u6765\u5b9a\u4e49\u5355\u5411\u94fe\u63a5\u8282\u70b9\uff0c\u8fd9\u4e24\u4e2a\u5b57\u6bb5\u662f\u5bf9\u6570\u636e\u5143\u7d20\u7684\u5f15\u7528\u548c\u5bf9\u53e6\u4e00\u4e2a\u8282\u70b9\u7684\u5f15\u7528\u3002 Python\u4e2d\uff0c\u4e3a\u6bcf\u4e2a\u65b0\u7684\u8282\u70b9\u5bf9\u8c61\u63d0\u4f9b\u975e\u8fde\u7eed\u5185\u5b58\u7684\u52a8\u6001\u5206\u914d\uff0c\u5e76\u4e14\u5f53\u5e94\u7528\u7a0b\u5e8f\u4e0d\u518d\u5f15\u7528\u8fd9\u4e2a\u5bf9\u8c61\u7684\u65f6\u5019\uff0c\u5b83\u4f1a\u81ea\u52a8\u628a\u8fd9\u90e8\u5206\u5185\u5b58\u8fd4\u56de\u7ed9\u7cfb\u7edf\uff08\u5783\u573e\u56de\u6536\uff09\u3002","title":"4.4.2.\u975e\u8fde\u7eed\u5185\u5b58\u548c\u8282\u70b9"},{"location":"python/DataStructure/04_ArrayChain/#443","text":"\u5355\u5411\u94fe\u63a5\u8282\u70b9\u53ea\u5305\u542b\u6570\u636e\u5143\u7d20\u548c\u5bf9\u4e0b\u4e00\u4e2a\u8282\u70b9\u7684\u5f15\u7528\u3002\u56e0\u4e3a\u8282\u70b9\u5bf9\u8c61\u7684\u7075\u6d3b\u6027\u548c\u6613\u7528\u6027\u975e\u5e38\u91cd\u8981\uff0c\u6240\u4ee5\u901a\u5e38\u4f1a\u5f15\u7528\u8282\u70b9\u5bf9\u8c61\u7684\u5b9e\u4f8b\u53d8\u91cf\u800c\u4e0d\u662f\u65b9\u6cd5\u8c03\u7528\uff0c\u5e76\u4e14\u6784\u9020\u51fd\u6570\u4e5f\u9700\u8981\u7528\u6237\u5728\u521b\u5efa\u8282\u70b9\u65f6\u53ef\u4ee5\u8bbe\u7f6e\u8282\u70b9\u7684\u94fe\u63a5\u3002 \u4e0b\u9762\u662f\u7528\u6765\u5b9e\u73b0\u5355\u5411\u94fe\u63a5\u8282\u70b9\u7c7b\u7684\u4ee3\u7801\u3002 class Node ( object ): \"\"\"\u5355\u5411\u94fe\u63a5\u8282\u70b9\u7c7b\"\"\" def __init__ ( self , data , next = None ): \"\"\"\u5b9e\u4f8b\u5316\u4e00\u4e2a\u8282\u70b9, \u9ed8\u8ba4\u540e\u7ee7\u8282\u70b9\u4e3aNone\"\"\" self . data = data self . next = next def main (): # \u521b\u5efa\u4e00\u4e2a\u7a7a\u94fe node1 = None # \u521b\u5efa\u4e00\u4e2a\u5355\u5411\u94fe\u63a5\u8282\u70b9\uff0c\u542b\u6570\u636e\u5143\u7d20\u548c\u7a7a\u94fe node2 = Node ( \"A\" , None ) # \u521b\u5efa\u4e00\u4e2a\u5355\u5411\u94fe\u63a5\u8282\u70b9\uff0c\u542b\u6570\u636e\u5143\u7d20\u548c\u6307\u5411\u4e0b\u4e00\u4e2a\u8282\u70b9\u7684\u94fe\u63a5 node3 = Node ( \"B\" , node2 ) if __name__ == \"__main__\" : main ()","title":"4.4.3.\u5b9a\u4e49\u5355\u5411\u94fe\u63a5\u8282\u70b9\u7c7b"},{"location":"python/DataStructure/04_ArrayChain/#444","text":"\u4e0b\u9762\u8fd9\u6bb5\u4ee3\u7801\u6f14\u793a\u4e86\u8282\u70b9\u53d8\u91cf\u88ab\u521d\u59cb\u5316\u4e3a None \u6216\u4e00\u4e2a\u65b0\u7684 Node \u5bf9\u8c61\u3002 node1 \u6ca1\u6709\u6307\u5411\u4efb\u4f55\u8282\u70b9\u5bf9\u8c61\uff08\u662f None \uff09\u3002 node2 \u548c node3 \u90fd\u6307\u5411\u4e86\u94fe\u63a5\u7684\u5bf9\u8c61\u3002 node2 \u6307\u5411\u4e86\u4e0b\u4e00\u4e2a\u6307\u9488\u662f None \u7684\u5bf9\u8c61\u3002 def main (): # \u521b\u5efa\u4e00\u4e2a\u7a7a\u94fe node1 = None # \u521b\u5efa\u4e00\u4e2a\u5355\u5411\u94fe\u63a5\u8282\u70b9\uff0c\u542b\u6570\u636e\u5143\u7d20\u548c\u7a7a\u94fe node2 = Node ( \"A\" , None ) # \u521b\u5efa\u4e00\u4e2a\u5355\u5411\u94fe\u63a5\u8282\u70b9\uff0c\u542b\u6570\u636e\u5143\u7d20\u548c\u6307\u5411\u4e0b\u4e00\u4e2a\u8282\u70b9\u7684\u94fe\u63a5 node3 = Node ( \"B\" , node2 ) \u6267\u884c node1.next = node3 \u4f1a\u6536\u5230\u9519\u8bef AttributeError: 'NoneType' object has no attribute 'next' \uff0c\u56e0\u4e3a\u53d8\u91cf node1 \u7684\u503c\u662f None \uff0c\u6240\u4ee5\u5b83\u5e76\u4e0d\u5305\u542b\u7528\u6765\u5f15\u7528\u8282\u70b9\u5bf9\u8c61\u7684 next \u5b57\u6bb5\u3002 \u5e94\u8be5\u5148\u6b63\u786e\u5b9e\u4f8b\u5316 node1 \uff0c\u518d\u5c06 node3 \u4f5c\u4e3a\u5176\u540e\u7ee7\u3002\u4e0b\u9762\u662f\u793a\u4f8b\u4ee3\u7801\u3002 def main (): # \u521b\u5efa\u4e00\u4e2a\u7a7a\u94fe node1 = None # \u521b\u5efa\u4e00\u4e2a\u5355\u5411\u94fe\u63a5\u8282\u70b9\uff0c\u542b\u6570\u636e\u5143\u7d20\u548c\u7a7a\u94fe node2 = Node ( \"A\" , None ) # \u521b\u5efa\u4e00\u4e2a\u5355\u5411\u94fe\u63a5\u8282\u70b9\uff0c\u542b\u6570\u636e\u5143\u7d20\u548c\u6307\u5411\u4e0b\u4e00\u4e2a\u8282\u70b9\u7684\u94fe\u63a5 node3 = Node ( \"B\" , node2 ) if node1 != None : node1 . next = node3 else : node1 = Node ( \"C\" , None ) node1 . next = node3 \u4e0b\u9762\u7684\u4ee3\u7801\u7684\u529f\u80fd\u662f\uff1a\u521b\u5efa\u4e00\u4e2a\u5355\u5411\u94fe\u63a5\u7ed3\u6784\uff0c\u5e76\u6253\u5370\u51fa\u5b83\u7684\u5185\u5bb9\u3002 \u4ee3\u7801\u4e2d head \u662f\u4e00\u4e2a\u6307\u9488\uff0c\u7528\u4e8e\u751f\u6210\u6574\u4e2a\u94fe\u63a5\u7ed3\u6784\u3002\u8fd9\u4e2a\u6307\u9488\u7684\u7528\u6cd5\u662f\u8ba9\u6240\u6709\u65b0\u63d2\u5165\u7684\u5143\u7d20\u59cb\u7ec8\u4f4d\u4e8e\u94fe\u63a5\u7ed3\u6784\u7684\u5f00\u5934\u3002 \u5728\u663e\u793a\u6570\u636e\u65f6\uff0c\u5b83\u4eec\u4f1a\u4ee5\u548c\u63d2\u5165\u65f6\u76f8\u53cd\u7684\u987a\u5e8f\u51fa\u73b0\u3002\u6b64\u5916\uff0c\u5f53\u663e\u793a\u6570\u636e\u65f6\uff0c\u5934\u90e8\u6307\u9488 head \u4f1a\u88ab\u91cd\u7f6e\u5230\u4e0b\u4e00\u4e2a\u8282\u70b9\uff0c\u76f4\u5230\u5934\u90e8\u6307\u9488\u53d8\u4e3a None \u4e3a\u6b62\u3002 \u4ee3\u7801\u6267\u884c\u7ed3\u675f\u4e4b\u540e\uff0c\u8fd9\u4e9b\u8282\u70b9\u5728\u7a0b\u5e8f\u91cc\u4e0d\u518d\u53ef\u7528\uff0c\u5e76\u4e14\u4f1a\u5728\u4e0b\u4e00\u6b21\u5783\u573e\u56de\u6536\u671f\u95f4\u88ab\u56de\u6536\u3002 def main (): # \u521b\u5efa\u4e00\u4e2a\u5355\u5411\u94fe\u63a5\u7ed3\u6784\uff0c\u5e76\u6253\u5370\u51fa\u5b83\u7684\u5185\u5bb9 head = None # \u5728\u94fe\u63a5\u7ed3\u6784\u7684\u5f00\u5934\u4f9d\u6b21\u63d2\u5165\u4e94\u4e2a\u8282\u70b9 for count in range ( 1 , 6 ): head = Node ( count , head ) # \u6253\u5370\u8f93\u51fa\u8fd9\u4e2a\u5355\u5411\u94fe\u63a5\u7684\u4e94\u4e2a\u8282\u70b9\u7684\u5185\u5bb9 while head != None : print ( head . data ) head = head . next if __name__ == \"__main__\" : main () # \u8fd0\u884c\u7ed3\u679c # 5 # 4 # 3 # 2 # 1","title":"4.4.4.\u4f7f\u7528\u5355\u5411\u94fe\u63a5\u8282\u70b9\u7c7b"},{"location":"python/DataStructure/04_ArrayChain/#445","text":"1\uff0e\u7528\u6846\u548c\u6307\u9488\u7ed8\u5236\u6d4b\u8bd5\u7a0b\u5e8f\u91cc\u7b2c\u4e00\u4e2a\u5faa\u73af\u6240\u521b\u5efa\u7684\u8282\u70b9\u7684\u793a\u610f\u56fe\u3002 \u89e3\u7b54\uff1a\u5728\u4e0b\u9762\u7684\u4ee3\u7801\u4e2d\uff0c\u6211\u4eec\u9996\u5148\u521b\u5efa\u4e86\u4e00\u4e2a\u7a7a\u7684\u5355\u94fe\u8868 head \u3002\u7136\u540e\u6211\u4eec\u5728\u94fe\u8868\u7684\u5f00\u5934\u4f9d\u6b21\u63d2\u5165\u4e94\u4e2a\u8282\u70b9\uff0c\u8282\u70b9\u7684\u6570\u636e\u4f9d\u6b21\u4e3a 1 , 2 , 3 , 4 , 5 \u3002\u5728\u63d2\u5165\u8fc7\u7a0b\u4e2d\uff0c\u6bcf\u6b21\u90fd\u628a\u65b0\u7684\u8282\u70b9\u63d2\u5165\u5230\u94fe\u8868\u7684\u5934\u90e8\uff0c\u6240\u4ee5\u6700\u540e\u7684\u94fe\u8868\u987a\u5e8f\u4f1a\u662f 5 , 4 , 3 , 2 , 1 \u3002 def main (): # \u521b\u5efa\u4e00\u4e2a\u5355\u5411\u94fe\u63a5\u7ed3\u6784\uff0c\u5e76\u6253\u5370\u51fa\u5b83\u7684\u5185\u5bb9 head = None # \u5728\u94fe\u63a5\u7ed3\u6784\u7684\u5f00\u5934\u4f9d\u6b21\u63d2\u5165\u4e94\u4e2a\u8282\u70b9 for count in range ( 1 , 6 ): head = Node ( count , head ) # \u6253\u5370\u8f93\u51fa\u8fd9\u4e2a\u5355\u5411\u94fe\u63a5\u7684\u4e94\u4e2a\u8282\u70b9\u7684\u5185\u5bb9 while head != None : print ( head . data ) head = head . next \u4ee5\u4e0b\u662f\u56fe\u793a\uff0c\u6bcf\u4e2a [] \u4ee3\u8868\u4e00\u4e2a\u8282\u70b9\uff0c\u8282\u70b9\u4e2d\u7684\u6570\u5b57\u4ee3\u8868\u8282\u70b9\u7684\u6570\u636e\uff0c\u7bad\u5934\u4ee3\u8868\u6307\u9488\uff0c\u6307\u5411\u4e86\u4e0b\u4e00\u4e2a\u8282\u70b9\u3002 NULL \u8868\u793a\u94fe\u8868\u7684\u7ed3\u675f\u3002 [5]---> [4] ---> [3] ---> [2] ---> [1] ---> NULL 2\uff0e\u5f53\u8282\u70b9\u53d8\u91cf\u5f15\u7528\u7684\u662f None \u65f6\uff0c\u5982\u679c\u7a0b\u5e8f\u5458\u5c1d\u8bd5\u8bbf\u95ee\u8282\u70b9\u7684\u6570\u636e\u5b57\u6bb5\uff0c\u5219\u4f1a\u53d1\u751f\u4ec0\u4e48\uff1f\u5982\u4f55\u9632\u6b62\u8fd9\u79cd\u60c5\u51b5\u7684\u53d1\u751f\uff1f \u89e3\u7b54\uff1a\u5f53\u8282\u70b9\u53d8\u91cf\u5f15\u7528\u7684\u662f None \u65f6\uff0c\u4f8b\u5982\uff0c\u6267\u884c node1.next = node3 \u4f1a\u6536\u5230\u9519\u8bef AttributeError: 'NoneType' object has no attribute 'next' \uff0c\u56e0\u4e3a\u53d8\u91cf node1 \u7684\u503c\u662f None \uff0c\u6240\u4ee5\u5b83\u5e76\u4e0d\u5305\u542b\u7528\u6765\u5f15\u7528\u8282\u70b9\u5bf9\u8c61\u7684 next \u5b57\u6bb5\u3002 \u5e94\u8be5\u5148\u6b63\u786e\u5b9e\u4f8b\u5316 node1 \uff0c\u518d\u5c06 node3 \u4f5c\u4e3a\u5176\u540e\u7ee7\u3002\u4e0b\u9762\u662f\u793a\u4f8b\u4ee3\u7801\u3002 if node1 != None : node1 . next = node3 else : node1 = Node ( \"C\" , None ) node1 . next = node3 3\uff0e\u7f16\u5199\u4e00\u6bb5\u4ee3\u7801\uff1a\u8fd9\u6bb5\u4ee3\u7801\u4f1a\u628a\u4e00\u4e2a\u88ab\u586b\u6ee1\u7684\u6570\u7ec4\u91cc\u7684\u5143\u7d20\u90fd\u8f6c\u79fb\u4e3a\u5355\u5411\u94fe\u63a5\u7ed3\u6784\u91cc\u7684\u6570\u636e\u3002\u8fd9\u4e2a\u64cd\u4f5c\u5e94\u4fdd\u7559\u5143\u7d20\u7684\u987a\u5e8f\u4e0d\u53d8\u3002 \u89e3\u7b54\uff1a\u4e0b\u9762\u662f\u4ee3\u7801\u5b9e\u73b0\u3002 LinkedList \u7c7b\u6709\u4e24\u4e2a\u65b9\u6cd5\uff0c insert_from_list \u7528\u4e8e\u4ece\u5217\u8868\u4e2d\u63d2\u5165\u6570\u636e\uff0c print_list \u7528\u4e8e\u6253\u5370\u94fe\u8868\u7684\u6240\u6709\u5143\u7d20\u3002 \u5728 insert_from_list \u65b9\u6cd5\u4e2d\uff0c\u6211\u4eec\u9996\u5148\u521b\u5efa\u7b2c\u4e00\u4e2a\u8282\u70b9\uff0c\u7136\u540e\u5bf9\u5217\u8868\u7684\u5269\u4f59\u5143\u7d20\uff0c\u4f9d\u6b21\u521b\u5efa\u65b0\u7684\u8282\u70b9\u5e76\u6dfb\u52a0\u5230\u94fe\u8868\u5c3e\u90e8\u3002 \u7531\u4e8e\u6211\u4eec\u662f\u9010\u4e2a\u5c06\u5143\u7d20\u6dfb\u52a0\u5230\u94fe\u8868\u7684\u672b\u5c3e\uff0c\u6240\u4ee5\u5728\u521b\u5efaNode\u65f6\u5e76\u4e0d\u9700\u8981\u6307\u5b9anext\u8282\u70b9\u3002 class Node ( object ): \"\"\"\u5355\u5411\u94fe\u63a5\u8282\u70b9\u7c7b\"\"\" def __init__ ( self , data , next = None ): \"\"\"\u5b9e\u4f8b\u5316\u4e00\u4e2a\u8282\u70b9, \u9ed8\u8ba4\u540e\u7ee7\u8282\u70b9\u4e3aNone\"\"\" self . data = data self . next = next class LinkedList : \"\"\"\u5c06\u5217\u8868\u5143\u7d20\u8f6c\u79fb\u4e3a\u5355\u5411\u94fe\u63a5\u7ed3\u6784\u91cc\u7684\u6570\u636e\uff0c\u5e76\u4fdd\u7559\u5143\u7d20\u7684\u987a\u5e8f\u4e0d\u53d8\"\"\" def __init__ ( self ): self . head = None # \u521d\u59cb\u5316head def insert_from_list ( self , data_list ): # \u521b\u5efa\u4e86\u94fe\u8868\u7684\u5934\u8282\u70b9 self . head = Node ( data_list [ 0 ]) # \u8bfb\u53d6\u5217\u8868\u7d22\u5f150\u7684\u5143\u7d20\u503c\uff0c\u5e76\u5c06\u5730\u5740\u8d4b\u503c\u7ed9head current = self . head # \u5c06head\u5f15\u7528\u8d4b\u503c\u7ed9current # \u5728\u94fe\u8868\u7684\u5c3e\u90e8\u4f9d\u6b21\u6dfb\u52a0\u65b0\u7684\u8282\u70b9 # \u5728\u6bcf\u6b21\u5faa\u73af\u540e\uff0c\u94fe\u8868\u7684\u5c3e\u90e8\u90fd\u4f1a\u6dfb\u52a0\u65b0\u7684\u8282\u70b9\uff0c\u5e76\u4e14current\u8282\u70b9\u4e5f\u4f1a\u968f\u4e4b\u66f4\u65b0\u3002 for data in data_list [ 1 :]: current . next = Node ( data ) # \u521b\u5efa\u4e00\u4e2a\u65b0\u7684\u8282\u70b9\uff0c\u5e76\u4e14\u5c06current\u8282\u70b9\u7684next\u5c5e\u6027\u8bbe\u7f6e\u4e3a\u8fd9\u4e2a\u65b0\u7684\u8282\u70b9\u3002\u8fd9\u6837\uff0ccurrent\u8282\u70b9\uff08\u4e5f\u5c31\u662f\u4e4b\u524d\u7684\u5c3e\u8282\u70b9\uff09\u5c31\u548c\u65b0\u7684\u8282\u70b9\u5efa\u7acb\u4e86\u94fe\u63a5\u5173\u7cfb\u3002 current = current . next # \u5c06current\u66f4\u65b0\u4e3a\u65b0\u521b\u5efa\u7684\u8282\u70b9\u3002\u4e5f\u5c31\u662f\u8bf4\uff0ccurrent\u59cb\u7ec8\u4ee3\u8868\u5f53\u524d\u94fe\u8868\u7684\u5c3e\u8282\u70b9\u3002 def print_list ( self ): current = self . head while current : print ( current . data , end = ' ' ) current = current . next print () def main (): # \u5c06\u5217\u8868data_list\u4e2d\u7684\u5143\u7d20\u63d2\u5165\u5230LinkedList\u5b9e\u4f8b\u4e2d\uff0c\u518d\u4f7f\u7528print_list\u65b9\u6cd5\u6253\u5370\u51fa\u94fe\u8868\u4e2d\u6240\u6709\u5143\u7d20\u3002 data_list = [ 1 , 2 , 3 , 4 , 5 ] linked_list = LinkedList () linked_list . insert_from_list ( data_list ) linked_list . print_list () # \u8f93\u51fa: 1 2 3 4 5 if __name__ == \"__main__\" : main () # \u8fd0\u884c\u7ed3\u679c # 1 2 3 4 5 \u5982\u679c\u5728\u521b\u5efaNode\u7684\u65f6\u5019\u6307\u5b9a next \u8282\u70b9\uff0c\u5219\u53ef\u4ee5\u4fee\u6539\u4e3a\u4e0b\u9762\u7684\u4ee3\u7801\u3002 insert_from_list \u51fd\u6570\u9996\u5148\u53cd\u8f6c\u4e86\u8f93\u5165\u7684\u5217\u8868\uff0c\u7136\u540e\u904d\u5386\u53cd\u8f6c\u540e\u7684\u5217\u8868\uff0c\u6bcf\u6b21\u90fd\u5728\u94fe\u8868\u5934\u90e8\u63d2\u5165\u4e00\u4e2a\u65b0\u7684\u8282\u70b9\u3002\u8fd9\u6837\u53ef\u4ee5\u786e\u4fdd\u63d2\u5165\u94fe\u8868\u7684\u5143\u7d20\u987a\u5e8f\u548c\u5b83\u4eec\u5728\u8f93\u5165\u5217\u8868\u4e2d\u7684\u987a\u5e8f\u662f\u4e00\u6837\u7684\u3002 class Node ( object ): \"\"\"\u5355\u5411\u94fe\u63a5\u8282\u70b9\u7c7b\"\"\" def __init__ ( self , data , next = None ): \"\"\"\u5b9e\u4f8b\u5316\u4e00\u4e2a\u8282\u70b9, \u9ed8\u8ba4\u540e\u7ee7\u8282\u70b9\u4e3aNone\"\"\" self . data = data self . next = next class LinkedList : \"\"\"\u5c06\u6570\u7ec4\u5143\u7d20\u8f6c\u79fb\u4e3a\u5355\u5411\u94fe\u63a5\u7ed3\u6784\u91cc\u7684\u6570\u636e\uff0c\u5e76\u4fdd\u7559\u5143\u7d20\u7684\u987a\u5e8f\u4e0d\u53d8\"\"\" def __init__ ( self ): self . head = None # \u521d\u59cb\u5316head def insert_from_list ( self , data_list ): for data in reversed ( data_list ): self . head = Node ( data , self . head ) def print_list ( self ): current = self . head while current : print ( current . data , end = ' ' ) current = current . next print () def main (): data_list = [ 1 , 2 , 3 , 4 , 5 ] linked_list = LinkedList () linked_list . insert_from_list ( data_list ) linked_list . print_list () # \u8f93\u51fa: 1 2 3 4 5 if __name__ == \"__main__\" : main () # \u8fd0\u884c\u7ed3\u679c # 1 2 3 4 5","title":"4.4.5.\u7ec3\u4e60\u9898"},{"location":"python/DataStructure/04_ArrayChain/#45","text":"\u6570\u7ec4\u4e0a\u7684\u64cd\u4f5c\u51e0\u4e4e\u90fd\u662f\u57fa\u4e8e\u7d22\u5f15\u7684\u3002\u94fe\u63a5\u7ed3\u6784\u4e0a\u7684\u64cd\u4f5c\u662f\u901a\u8fc7\u64cd\u63a7\u7ed3\u6784\u91cc\u7684\u94fe\u63a5\u6765\u6a21\u62df\u8fd9\u4e9b\u57fa\u4e8e\u7d22\u5f15\u7684\u64cd\u4f5c\u3002 \u4e0b\u9762\u662f\u5b8c\u6574\u4ee3\u7801\uff0c\u5305\u542b\u4e86\u540e\u9762\u5173\u4e8e\u8fde\u63a5\u7ed3\u6784\u7684\u64cd\u4f5c\u793a\u4f8b\u3002 # class Node(object): # \"\"\"\u5355\u5411\u94fe\u63a5\u8282\u70b9\u7c7b\"\"\" # def __init__(self, data, next=None): # \"\"\"\u5b9e\u4f8b\u5316\u4e00\u4e2a\u8282\u70b9, \u9ed8\u8ba4\u540e\u7ee7\u8282\u70b9\u4e3aNone\"\"\" # self.data = data # self.next = next # class TwoWayNode(Node): # \"\"\"\u53cc\u5411\u94fe\u63a5\u8282\u70b9\u7c7b\"\"\" # def __init__(self, data, previous=None, next=None): # \"\"\"\u5b9e\u4f8b\u5316\u4e00\u4e2a\u8282\u70b9, \u9ed8\u8ba4\u524d\u5e8f\u8282\u70b9\u5c3eNone, \u9ed8\u8ba4\u540e\u7ee7\u8282\u70b9\u4e3aNone\"\"\" # Node.__init__(self, data, next) # self.previous = previous # class LinkedList: # \"\"\"\u5355\u5411\u548c\u53cc\u5411\u94fe\u63a5\u7ed3\u6784\"\"\" # def __init__(self, node): # # \u521d\u59cb\u5316\u5934\u8282\u70b9 # self.head = node # # \u5c5e\u6027size\u4fdd\u5b58\u94fe\u63a5\u7ed3\u6784\u7684\u903b\u8f91\u5927\u5c0f\uff0c\u901a\u5e38\u6307\u7684\u662f\u94fe\u8868\u6240\u5305\u542b\u7684\u5143\u7d20\u7684\u6570\u91cf\uff0c\u521d\u59cb\u5316\u94fe\u63a5\u7ed3\u6784\u5927\u5c0f\u4e3a0 # self.size = 0 # def insert_from_list(self, data_list, twoway=False): # \"\"\" # \u628a\u4e00\u4e2a\u5217\u8868\uff08\u5df2\u6709\u7684\u6570\u636e\u7ed3\u6784\uff09\u8f6c\u6362\u4e3a\u94fe\u63a5\u7ed3\u6784\u662f\u4e00\u79cd\u6bd4\u8f83\u5e38\u89c1\u5b9e\u7528\u7684\u65b9\u5f0f\u3002\u8fd9\u79cd\u505a\u6cd5\u53ef\u4ee5\u901a\u8fc7\u63a7\u5236\u4ee3\u7801\uff0c\u65b9\u4fbf\u5730\u4ece\u5df2\u6709\u7684\u96c6\u5408\u7c7b\uff08\u5982\u5217\u8868\uff0c\u6570\u7ec4\u7b49\uff09\u4e2d\u5bfc\u5165\u5143\u7d20\uff0c\u5e76\u6784\u5efa\u9700\u8981\u7684\u7684\u94fe\u63a5\u7ed3\u6784\u3002 # \u5728\u4e00\u4e9b\u7b80\u5355\u573a\u666f\u4e0b\uff0c\u6bd4\u5982\u5df2\u77e5\u5f85\u6dfb\u52a0\u7684\u5143\u7d20\u6570\u91cf\u5f88\u5c11\uff0c\u6216\u8005\u6709\u5176\u4ed6\u7ea6\u675f\u4f7f\u5f97\u7528\u5217\u8868\u4e0d\u65b9\u4fbf\u65f6\uff0c\u53ef\u4ee5\u901a\u8fc7\u624b\u52a8\u65b9\u5f0f\u5411\u94fe\u63a5\u7ed3\u6784\u6dfb\u52a0\u5143\u7d20\u3002\u4f46\u5982\u679c\u5143\u7d20\u5f88\u591a\uff0c\u6216\u8005\u6709\u672a\u77e5\u6570\u91cf\u7684\u5143\u7d20\u9700\u8981\u6dfb\u52a0\uff0c\u7528\u5217\u8868\u53ef\u4ee5\u65b9\u4fbf\u5730\u4e00\u6b21\u6027\u5bfc\u5165\u6240\u6709\u5143\u7d20\u3002 # \"\"\" # if twoway: # \u68c0\u67e5\u662f\u5426\u8981\u521b\u5efa\u53cc\u5411\u94fe\u8868 # for data in data_list: # \u5bf9\u4e8e\u6570\u636e\u5217\u8868\u4e2d\u7684\u6bcf\u4e2a\u6570\u636e\u521b\u5efa\u4e00\u4e2a\u65b0\u7684\u53cc\u5411\u94fe\u63a5\u8282\u70b9 # node = TwoWayNode(data) # if self.head is None: # \u5982\u679c\u94fe\u8868\u4e3a\u7a7a\u628a\u65b0\u8282\u70b9\u8bbe\u7f6e\u4e3a\u5934\u8282\u70b9 # self.head = node # else: # \u5982\u679c\u94fe\u8868\u4e0d\u4e3a\u7a7a # tail = self.head # \u4ece\u5934\u8282\u70b9\u5f00\u59cb # while tail.next is not None: # \u901a\u8fc7\u904d\u5386\u94fe\u8868\u67e5\u627e\u5c3e\u8282\u70b9 # tail = tail.next # tail.next = node # \u628a\u65b0\u8282\u70b9\u63d2\u5165\u5230\u5c3e\u8282\u70b9 # node.previous = tail # \u8bbe\u7f6e\u65b0\u8282\u70b9\u7684\u524d\u4e00\u4e2a\u8282\u70b9\u6307\u5411\u5c3e\u8282\u70b9 # else: # \u521b\u5efa\u5355\u5411\u94fe\u8868 # for data in reversed(data_list): # \u5bf9\u4e8e\u5217\u8868\u4e2d\u7684\u6bcf\u4e2a\u5143\u7d20\uff0c\u53cd\u5411\u8fed\u4ee3\u4f7f\u5f97\u63d2\u5165\u7684\u8282\u70b9\u4e0e\u539f\u6570\u636e\u987a\u5e8f\u76f8\u540c # self.head = Node(data, self.head) # \u521b\u5efa\u4e00\u4e2a\u65b0\u7684\u5355\u5411\u94fe\u63a5\u8282\u70b9\u5e76\u63d2\u5165\u5230\u5934\u8282\u70b9 # self.size += len(data_list) # \u66f4\u65b0\u94fe\u8868\u5927\u5c0f # def get_size(self): # \"\"\"\u83b7\u53d6\u94fe\u8868\u5927\u5c0f\uff08\u8282\u70b9\u6570\u91cf\uff09\"\"\" # return self.size # def search(self, target): # \"\"\"\u5728\u94fe\u63a5\u7ed3\u6784\u4e2d\u641c\u7d22\u6307\u5b9a\u5143\u7d20\"\"\" # current = self.head # \u4ece\u5934\u8282\u70b9\u5f00\u59cb # while current: # \u5f53\u5f53\u524d\u8282\u70b9\u975eNone\u65f6\u7ee7\u7eed\u904d\u5386 # if current.data == target: # \u5982\u679c\u5f53\u524d\u8282\u70b9\u7684\u6570\u636e\u7b49\u4e8e\u76ee\u6807\u6570\u636e # return True # \u8fd4\u56de\u771f\u503c # current = current.next # \u79fb\u52a8\u5230\u4e0b\u4e00\u8282\u70b9 # return False # \u5982\u679c\u6574\u4e2a\u94fe\u8868\u904d\u5386\u5b8c\u6bd5\u8fd8\u627e\u4e0d\u5230\u76ee\u6807\u6570\u636e\uff0c\u8fd4\u56de\u5047\u503c # def locate(self, index): # \"\"\"\u8fd4\u56de\u94fe\u63a5\u7ed3\u6784\u4e2d\u7b2cindex\u4e2a\u5143\u7d20, 0 <= index < n\"\"\" # if index >= self.get_size() or index < 0: # \u5982\u679c\u7d22\u5f15\u8d85\u51fa\u8303\u56f4\uff0c\u7acb\u5373\u629b\u51fa\u9519\u8bef # raise IndexError(\"\u94fe\u8868\u7d22\u5f15\u8d85\u51fa\u8303\u56f4\") # probe = self.head # \u786e\u5b9a\u8d77\u59cb\u70b9\u4e3a\u5934\u8282\u70b9 # while index > 0: # \u5f53\u7d22\u5f15\u5927\u4e8e0\u65f6\uff0c\u8fdb\u5165\u5faa\u73af # probe = probe.next # \u5c06\u63a2\u9488\uff08probe\uff09\u79fb\u52a8\u5230\u4e0b\u4e00\u4e2a\u8282\u70b9 # index -= 1 # \u5c06\u7d22\u5f15\u503c\u51cf1 # return probe.data # \u8fd4\u56de\u5f53\u524d\u4f4d\u7f6e\uff08index\u5bf9\u5e94\u4f4d\u7f6e\uff09\u7684\u8282\u70b9\u6570\u636e # def replace(self, old, new): # \"\"\"\u66ff\u6362\u94fe\u8868\u4e2d\u6240\u6709\u7b49\u4e8eold\u7684\u5143\u7d20\u4e3anew\"\"\" # current = self.head # \u4ece\u94fe\u8868\u7684\u5934\u8282\u70b9\u5f00\u59cb\u904d\u5386 # while current: # \u53ea\u8981\u8fd8\u6709\u8282\u70b9\uff0c\u5c31\u7ee7\u7eed\u904d\u5386 # if current.data == old: # \u68c0\u67e5\u5f53\u524d\u8282\u70b9\u7684\u6570\u636e\u662f\u5426\u7b49\u4e8eold # current.data = new # \u5982\u679c\u7b49\u4e8eold\uff0c\u5c06\u5f53\u524d\u8282\u70b9\u7684\u6570\u636e\u66ff\u6362\u4e3anew # current = current.next # \u7ee7\u7eed\u68c0\u67e5\u4e0b\u4e00\u4e2a\u8282\u70b9 # def print_list(self): # \"\"\"\u6253\u5370\u8f93\u51fa\u94fe\u63a5\u7ed3\u6784\u5185\u5bb9\"\"\" # current = self.head # while current: # print(current.data, end=' ') # current = current.next # print() # def main(): # # \u521b\u5efa\u6d4b\u8bd5\u6570\u636e # test_data = [1, 2, 3, 4, 5] # # \u5355\u5411\u94fe\u8868\u6d4b\u8bd5 # print(\"\u5355\u5411\u94fe\u8868\u6d4b\u8bd5:\") # single_linked_list = LinkedList(None) # print(\"\u63d2\u5165\u6570\u636e\") # single_linked_list.insert_from_list(test_data) # \u63d2\u5165\u6d4b\u8bd5\u6570\u636e # single_linked_list.print_list() # \u6253\u5370\u94fe\u63a5\u7ed3\u6784\u5185\u5bb9 # print(\"\u94fe\u8868\u5927\u5c0f\uff1a\", single_linked_list.get_size()) # \u663e\u793a\u94fe\u63a5\u7ed3\u6784\u5927\u5c0f # print(\"\u641c\u7d22\u5143\u7d203: \", single_linked_list.search(3)) # \u641c\u7d22\u94fe\u63a5\u7ed3\u6784\u4e2d\u662f\u5426\u5b58\u5728\u5143\u7d203 # print(\"\u67e5\u627e\u7b2c2\u4e2a\u5143\u7d20: \", single_linked_list.locate(2)) # \u67e5\u627e\u94fe\u63a5\u7ed3\u6784\u4e2d\u7b2c2\u4e2a\u5143\u7d20 # print(\"\u628a\u5143\u7d201\u66ff\u6362\u4e3a10\") # single_linked_list.replace(1, 10) # \u66ff\u6362\u5143\u7d201\u4e3a10 # single_linked_list.print_list() # print() # # \u53cc\u5411\u94fe\u8868\u6d4b\u8bd5 # print(\"\u53cc\u5411\u94fe\u8868\u6d4b\u8bd5:\") # double_linked_list = LinkedList(None) # print(\"\u63d2\u5165\u6570\u636e\") # double_linked_list.insert_from_list(test_data, twoway=True) # double_linked_list.print_list() # print(\"\u94fe\u8868\u5927\u5c0f\uff1a\", double_linked_list.get_size()) # print(\"\u641c\u7d22\u5143\u7d203\uff1a\", double_linked_list.search(3)) # print(\"\u67e5\u627e\u7b2c2\u4e2a\u5143\u7d20\uff1a\", double_linked_list.locate(2)) # print(\"\u66ff\u6362\u5143\u7d201\u4e3a10\") # double_linked_list.replace(1, 10) # double_linked_list.print_list() # if __name__ == \"__main__\": # main() # # \u8fd0\u884c\u7ed3\u679c # # \u5355\u5411\u94fe\u8868\u6d4b\u8bd5: # # \u63d2\u5165\u6570\u636e # # 1 2 3 4 5 # # \u94fe\u8868\u5927\u5c0f\uff1a 5 # # \u641c\u7d22\u5143\u7d203\uff1a True # # \u67e5\u627e\u7b2c2\u4e2a\u5143\u7d20\uff1a 3 # # \u66ff\u6362\u5143\u7d201\u4e3a10 # # 10 2 3 4 5 # # \u53cc\u5411\u94fe\u8868\u6d4b\u8bd5: # # \u63d2\u5165\u6570\u636e # # 1 2 3 4 5 # # \u94fe\u8868\u5927\u5c0f\uff1a 5 # # \u641c\u7d22\u5143\u7d203\uff1a True # # \u67e5\u627e\u7b2c2\u4e2a\u5143\u7d20\uff1a 3 # # \u66ff\u6362\u5143\u7d201\u4e3a10 # # 10 2 3 4 5","title":"4.5.\u5355\u5411\u94fe\u63a5\u7ed3\u6784\u4e0a\u7684\u64cd\u4f5c"},{"location":"python/DataStructure/04_ArrayChain/#451","text":"\u57284.4\u4e2d\u7684\u793a\u4f8b\u4ee3\u7801\u4e2d\uff08\u5982\u4e0b\uff09\uff0c\u8282\u70b9\u4f1a\u5728\u88ab\u6253\u5370\u4e4b\u540e\u4ece\u94fe\u63a5\u7ed3\u6784\u91cc\u5220\u9664\u3002 def main (): # \u521b\u5efa\u4e00\u4e2a\u5355\u5411\u94fe\u63a5\u7ed3\u6784\uff0c\u5e76\u6253\u5370\u51fa\u5b83\u7684\u5185\u5bb9 head = None # \u5728\u94fe\u63a5\u7ed3\u6784\u7684\u5f00\u5934\u4f9d\u6b21\u63d2\u5165\u4e94\u4e2a\u8282\u70b9 for count in range ( 1 , 6 ): head = Node ( count , head ) # \u6253\u5370\u8f93\u51fa\u8fd9\u4e2a\u5355\u5411\u94fe\u63a5\u7684\u4e94\u4e2a\u8282\u70b9\u7684\u5185\u5bb9 while head != None : print ( head . data ) head = head . next if __name__ == \"__main__\" : main () # \u8fd0\u884c\u7ed3\u679c # 5 # 4 # 3 # 2 # 1 \u5bf9\u4e8e\u8bb8\u591a\u5e94\u7528\u7a0b\u5e8f\u6765\u8bf4\uff0c\u53ea\u9700\u8981\u8bbf\u95ee\u6bcf\u4e2a\u8282\u70b9\u800c\u4e0d\u7528\u5220\u9664\u5b83\u4eec\u3002\u8fd9\u4e2a\u64cd\u4f5c\u79f0\u4e3a\u904d\u5386\uff08traversal\uff09\u3002 \u5728\u904d\u5386\u4e2d\uff0c\u4f1a\u7528\u5230\u4e00\u4e2a\u53eb\u4f5c probe \u7684\u4e34\u65f6\u6307\u9488\u53d8\u91cf\u3002\u4e00\u5f00\u59cb\uff0c\u8fd9\u4e2a\u53d8\u91cf\u88ab\u521d\u59cb\u5316\u4e3a\u94fe\u63a5\u7ed3\u6784\u7684head\u6307\u9488\uff0c\u7136\u540e\u901a\u8fc7\u5faa\u73af\u6765\u5b8c\u6210\uff0c\u5728\u6574\u4e2a\u8fc7\u7a0b\u7ed3\u675f\u4e4b\u540e\uff0cprobe\u6307\u9488\u662fNone\uff0c\u4f46head\u6307\u9488\u4ecd\u7136\u5f15\u7528\u7b2c\u4e00\u4e2a\u8282\u70b9\u3002 \u4e0b\u9762\u662f\u4fee\u6539\u540e\u7684\u4ee3\u7801\uff1a def main (): print ( \"------\" ) # \u521b\u5efa\u4e00\u4e2a\u5355\u5411\u94fe\u63a5\u7ed3\u6784\uff0c\u5e76\u6253\u5370\u51fa\u5b83\u7684\u5185\u5bb9 head = None # \u5728\u94fe\u63a5\u7ed3\u6784\u7684\u5f00\u5934\u4f9d\u6b21\u63d2\u5165\u4e94\u4e2a\u8282\u70b9 for count in range ( 1 , 6 ): head = Node ( count , head ) # \u6253\u5370\u8f93\u51fa\u8fd9\u4e2a\u5355\u5411\u94fe\u63a5\u7684\u4e94\u4e2a\u8282\u70b9\u7684\u5185\u5bb9 probe = head while probe != None : print ( probe . data ) probe = probe . next \u901a\u5e38\u6765\u8bf4\uff0c\u5355\u5411\u94fe\u63a5\u7ed3\u6784\u7684\u904d\u5386\u4f1a\u8bbf\u95ee\u6240\u6709\u8282\u70b9\uff0c\u5e76\u4e14\u5728\u5230\u8fbe\u7a7a\u94fe\u63a5\u65f6\u7ec8\u6b62\u904d\u5386\u3002\u56e0\u6b64\uff0c\u503c None \u76f8\u5f53\u4e8e\u505c\u6b62\u8fdb\u7a0b\u7684\u54e8\u5175\uff08sentinel\uff09\u3002 \u904d\u5386\u7684\u65f6\u95f4\u590d\u6742\u5ea6\u662f\u7ebf\u6027\u7684\uff0c\u4e5f\u4e0d\u9700\u8981\u989d\u5916\u7684\u5185\u5b58\u3002","title":"4.5.1.\u904d\u5386"},{"location":"python/DataStructure/04_ArrayChain/#452","text":"\u5bf9\u94fe\u63a5\u7ed3\u6784\u8fdb\u884c\u987a\u5e8f\u641c\u7d22\u6709\u70b9\u7c7b\u4f3c\u4e8e\u904d\u5386\u64cd\u4f5c\uff0c\u56e0\u4e3a\u5fc5\u987b\u8981\u4ece\u7b2c\u4e00\u4e2a\u8282\u70b9\u5f00\u59cb\u5e76\u4f9d\u7167\u94fe\u63a5\u987a\u5e8f\u79fb\u52a8\uff0c\u76f4\u81f3\u627e\u5230\u5bf9\u5e94\u7684\u6807\u8bb0\u3002\u5728\u8fd9\u79cd\u60c5\u51b5\u4e0b\uff0c\u8fd9\u4e2a\u6807\u8bb0\u6709\u4e24\u79cd\u53ef\u80fd\u6027\u3002 \u7a7a\u94fe\u63a5\uff0c\u8bf4\u660e\u6ca1\u6709\u66f4\u591a\u9700\u8981\u88ab\u68c0\u67e5\u7684\u6570\u636e\u5143\u7d20\u3002 \u7b49\u540c\u4e8e\u76ee\u6807\u5143\u7d20\u7684\u6570\u636e\u5143\u7d20\uff0c\u4ee3\u8868\u641c\u7d22\u6210\u529f\u3002 \u4e0b\u9762\u662f\u641c\u7d22\u7ed9\u5b9a\u5143\u7d20\u7684\u4ee3\u7801\u3002 search(self, target) \u65b9\u6cd5\u5b9e\u73b0\u4e86\u5728\u5355\u5411\u6216\u53cc\u5411\u94fe\u8868\u4e2d\u641c\u7d22\u6307\u5b9a\u5143\u7d20\u3002 def search ( self , target ): \"\"\"\u5728\u94fe\u63a5\u7ed3\u6784\u4e2d\u641c\u7d22\u6307\u5b9a\u5143\u7d20\"\"\" current = self . head # \u4ece\u5934\u8282\u70b9\u5f00\u59cb while current : # \u5f53\u5f53\u524d\u8282\u70b9\u975eNone\u65f6\u7ee7\u7eed\u904d\u5386 if current . data == target : # \u5982\u679c\u5f53\u524d\u8282\u70b9\u7684\u6570\u636e\u7b49\u4e8e\u76ee\u6807\u6570\u636e return True # \u8fd4\u56de\u771f\u503c current = current . next # \u79fb\u52a8\u5230\u4e0b\u4e00\u8282\u70b9 return False # \u5982\u679c\u6574\u4e2a\u94fe\u8868\u904d\u5386\u5b8c\u6bd5\u8fd8\u627e\u4e0d\u5230\u76ee\u6807\u6570\u636e\uff0c\u8fd4\u56de\u5047\u503c \u5e73\u5747\u60c5\u51b5\u4e0b\uff0c\u987a\u5e8f\u641c\u7d22\u5728\u5355\u5411\u94fe\u63a5\u7ed3\u6784\u4e0a\u662f\u7ebf\u6027\u7684\u3002 \u8bbf\u95ee\u94fe\u63a5\u7ed3\u6784\u7684\u7b2c i \u4e2a\u5143\u7d20\u65f6\u6267\u884c\u7684\u4e5f\u662f\u987a\u5e8f\u641c\u7d22\u3002\u8fd9\u662f\u56e0\u4e3a\u5fc5\u987b\u4ece\u7b2c\u4e00\u4e2a\u8282\u70b9\u5f00\u59cb\u7edf\u8ba1\u94fe\u63a5\u7684\u6570\u91cf\uff0c\u76f4\u81f3\u5230\u8fbe\u7b2c i \u4e2a\u8282\u70b9\u4e3a\u6b62\u3002\u5047\u8bbe\u6709 0<=i= self . get_size () or index < 0 : # \u5982\u679c\u7d22\u5f15\u8d85\u51fa\u8303\u56f4\uff0c\u7acb\u5373\u629b\u51fa\u9519\u8bef raise IndexError ( \"\u94fe\u8868\u7d22\u5f15\u8d85\u51fa\u8303\u56f4\" ) probe = self . head # \u786e\u5b9a\u8d77\u59cb\u70b9\u4e3a\u5934\u8282\u70b9 while index > 0 : # \u5f53\u7d22\u5f15\u5927\u4e8e0\u65f6\uff0c\u8fdb\u5165\u5faa\u73af probe = probe . next # \u5c06\u63a2\u9488\uff08probe\uff09\u79fb\u52a8\u5230\u4e0b\u4e00\u4e2a\u8282\u70b9 index -= 1 # \u5c06\u7d22\u5f15\u503c\u51cf1 return probe . data # \u8fd4\u56de\u5f53\u524d\u4f4d\u7f6e\uff08index\u5bf9\u5e94\u4f4d\u7f6e\uff09\u7684\u8282\u70b9\u6570\u636e \u548c\u6570\u7ec4\u4e0d\u540c\u7684\u662f\uff0c\u94fe\u63a5\u7ed3\u6784\u5e76\u4e0d\u652f\u6301\u968f\u673a\u8bbf\u95ee\u3002\u56e0\u6b64\uff0c\u4e0d\u80fd\u50cf\u5728\u6709\u5e8f\u6570\u7ec4\u91cc\u90a3\u6837\u5bf9\u6709\u5e8f\u7684\u5355\u5411\u94fe\u63a5\u7ed3\u6784\u8fdb\u884c\u9ad8\u6548\u641c\u7d22\u3002","title":"4.5.2.\u641c\u7d22"},{"location":"python/DataStructure/04_ArrayChain/#453","text":"\u5355\u5411\u94fe\u63a5\u7ed3\u6784\u91cc\u7684\u66ff\u6362\u64cd\u4f5c\u4e5f\u4f1a\u91c7\u7528\u904d\u5386\u7684\u6a21\u5f0f\u3002\u5728\u8fd9\u79cd\u60c5\u51b5\u4e0b\uff0c\u6211\u4eec\u4f1a\u5728\u94fe\u63a5\u7ed3\u6784\u91cc\u641c\u7d22\u7ed9\u5b9a\u7684\u5143\u7d20\u6216\u7ed9\u5b9a\u7684\u4f4d\u7f6e\uff0c\u7136\u540e\u7528\u4e00\u4e2a\u65b0\u7684\u5143\u7d20\u66ff\u6362\u8fd9\u4e2a\u5143\u7d20\u3002 \u5728\u66ff\u6362\u7ed9\u5b9a\u5143\u7d20\u65f6\uff0c\u5e76\u4e0d\u9700\u8981\u5047\u5b9a\u76ee\u6807\u5143\u7d20\u5df2\u7ecf\u5b58\u5728\u4e8e\u94fe\u63a5\u7ed3\u6784\u91cc\u3002 \u5982\u679c\u76ee\u6807\u5143\u7d20\u4e0d\u5b58\u5728\uff0c\u5c31\u4e0d\u4f1a\u53d1\u751f\u4efb\u4f55\u66ff\u6362\u64cd\u4f5c\uff0c\u5e76\u4e14\u4f1a\u8fd4\u56de False \uff1b \u5982\u679c\u76ee\u6807\u5143\u7d20\u5b58\u5728\uff0c\u65b0\u7684\u5143\u7d20\u5c31\u4f1a\u66ff\u6362\u5b83\uff0c\u5e76\u4e14\u8fd4\u56de True \uff1b \u4e0b\u9762\u662f\u8fd9\u4e2a\u64cd\u4f5c\u7684\u4ee3\u7801\u3002 def replace ( self , old , new ): \"\"\"\u66ff\u6362\u94fe\u8868\u4e2d\u6240\u6709\u7b49\u4e8eold\u7684\u5143\u7d20\u4e3anew\"\"\" current = self . head # \u4ece\u94fe\u8868\u7684\u5934\u8282\u70b9\u5f00\u59cb\u904d\u5386 while current : # \u53ea\u8981\u8fd8\u6709\u8282\u70b9\uff0c\u5c31\u7ee7\u7eed\u904d\u5386 if current . data == old : # \u68c0\u67e5\u5f53\u524d\u8282\u70b9\u7684\u6570\u636e\u662f\u5426\u7b49\u4e8eold current . data = new # \u5982\u679c\u7b49\u4e8eold\uff0c\u5c06\u5f53\u524d\u8282\u70b9\u7684\u6570\u636e\u66ff\u6362\u4e3anew current = current . next # \u7ee7\u7eed\u68c0\u67e5\u4e0b\u4e00\u4e2a\u8282\u70b9","title":"4.5.3.\u66ff\u6362"},{"location":"python/DataStructure/04_ArrayChain/#454","text":"\u5728\u94fe\u63a5\u7ed3\u6784\u5934\u90e8\u63d2\u5165\u52062\u79cd\u60c5\u51b5\uff1a \u7b2c\u4e00\u79cd\u60c5\u51b5\uff1a head \u6307\u9488\u662f None \uff0c\u63d2\u5165\u64cd\u4f5c\u4f1a\u628a\u7b2c\u4e00\u4e2a\u5143\u7d20\u63d2\u5165\u7ed3\u6784\u91cc\uff1b \u7b2c\u4e8c\u79cd\u60c5\u51b5\uff1a head \u6307\u9488\u4e0d\u662f None \uff0c\uff0c\u7b2c\u4e8c\u4e2a\u5143\u7d20\u4f1a\u88ab\u63d2\u5165\u8fd9\u4e2a\u7ed3\u6784\u7684\u5f00\u5934\uff1b \u4ece\u4e0a\u97622\u79cd\u60c5\u51b5\u5f97\u51fa\uff0c\u5728\u5df2\u7ecf\u6709\u6570\u636e\u7684\u60c5\u51b5\u4e0b\uff0c\u5e76\u4e0d\u9700\u8981\u901a\u8fc7\u590d\u5236\u6570\u636e\u6765\u8ba9\u5b83\u4eec\u5411\u540e\u79fb\u52a8\uff0c\u4e5f\u4e0d\u9700\u8981\u989d\u5916\u7684\u5185\u5b58\u3002\u8fd9\u4e5f\u5c31\u610f\u5473\u7740\u5728\u94fe\u63a5\u7ed3\u6784\u7684\u5f00\u5934\u5904\u63d2\u5165\u6570\u636e\u53ea\u4f1a\u7528\u5230\u5e38\u6570\u7684\u65f6\u95f4\u548c\u5185\u5b58\uff0c\u8fd9\u548c\u5bf9\u6570\u7ec4\u7684\u76f8\u540c\u64cd\u4f5c\u662f\u4e0d\u4e00\u6837\u7684\u3002 \u4e0b\u9762\u662f\u5b8c\u6574\u7684\u4ee3\u7801\u3002 \"\"\" \u5b9e\u73b0\u4e86\u5bf9\u5355\u5411\u94fe\u63a5\u8fdb\u884c\u5982\u4e0b\u64cd\u4f5c\uff1a 1. \u5728\u5f00\u59cb\u5904\u63d2\u5165 2. \u5728\u7ed3\u5c3e\u5904\u63d2\u5165 3. \u5728\u5f00\u59cb\u5904\u5220\u9664 4. \u5728\u7ed3\u5c3e\u5904\u5220\u9664 5. \u5728\u4efb\u610f\u5904\u63d2\u5165 6. \u5728\u4efb\u610f\u5904\u5220\u9664 \"\"\" class Node ( object ): \"\"\"\u5355\u5411\u94fe\u63a5\u8282\u70b9\u7c7b\"\"\" def __init__ ( self , data , next = None ): \"\"\" \u5b9e\u4f8b\u5316\u4e00\u4e2a\u8282\u70b9, \u9ed8\u8ba4\u540e\u7ee7\u8282\u70b9\u4e3aNone Args: data: \u8282\u70b9\u5b58\u50a8\u7684\u6570\u636e next: \u6307\u5411\u4e0b\u4e00\u4e2a\u8282\u70b9\u7684\u6307\u9488\uff0c\u9ed8\u8ba4\u4e3aNone \"\"\" self . data = data # \u5b9a\u4e49\u8282\u70b9\u7684\u6570\u636e\u90e8\u5206 self . next = next # \u5b9a\u4e49\u8282\u70b9\u7684\u6307\u9488\u90e8\u5206\uff0c\u521d\u59cb\u503c\u4e3aNone\u8868\u793a\u6ca1\u6709\u4e0b\u4e00\u4e2a\u8282\u70b9 def insert_at_beginning ( head , data ): \"\"\" \u5728\u94fe\u8868\u5f00\u59cb\u5904\u63d2\u5165\u65b0\u8282\u70b9 Args: head: \u5f53\u524d\u94fe\u8868\u7684\u5934\u8282\u70b9 data: \u65b0\u8282\u70b9\u7684\u6570\u636e Returns: Node: \u65b0\u7684\u5934\u8282\u70b9 \"\"\" new_node = Node ( data ) # \u521b\u5efa\u65b0\u7684\u8282\u70b9\u5bf9\u8c61 new_node . next = head # \u5c06\u65b0\u8282\u70b9\u7684next\u6307\u9488\u6307\u5411\u5f53\u524d\u5934\u8282\u70b9 return new_node # \u8fd4\u56de\u65b0\u7684\u5934\u8282\u70b9 def insert_at_end ( head , data ): \"\"\" \u5728\u94fe\u8868\u672b\u5c3e\u63d2\u5165\u65b0\u8282\u70b9 Args: head: \u5f53\u524d\u94fe\u8868\u7684\u5934\u8282\u70b9 data: \u65b0\u8282\u70b9\u7684\u6570\u636e Returns: Node: \u5934\u8282\u70b9 \"\"\" new_node = Node ( data ) # \u521b\u5efa\u65b0\u7684\u8282\u70b9\u5bf9\u8c61 if head is None : # \u5982\u679c\u94fe\u8868\u4e3a\u7a7a\uff0c\u5c06\u65b0\u8282\u70b9\u8bbe\u7f6e\u4e3a\u5934\u8282\u70b9 head = new_node else : probe = head # \u521b\u5efa\u4e00\u4e2a\u6307\u9488\uff0c\u4ece\u5934\u8282\u70b9\u5f00\u59cb\u904d\u5386\u94fe\u8868 while probe . next is not None : # \u5f53\u6307\u9488\u6240\u6307\u8282\u70b9\u6709\u4e0b\u4e00\u4e2a\u8282\u70b9\u65f6 probe = probe . next # \u79fb\u52a8\u6307\u9488\u5230\u4e0b\u4e00\u4e2a\u8282\u70b9 probe . next = new_node # \u5c06\u65b0\u8282\u70b9\u8fde\u63a5\u5230\u5f53\u524d\u6307\u9488\u6240\u6307\u8282\u70b9\u7684\u4e0b\u4e00\u4e2a\u4f4d\u7f6e\uff0c\u5b8c\u6210\u8282\u70b9\u7684\u63d2\u5165 return head # \u8fd4\u56de\u5934\u8282\u70b9 def delete_at_beginning ( head ): \"\"\" \u4ece\u94fe\u8868\u5f00\u59cb\u5904\u5220\u9664\u8282\u70b9 Args: head: \u5f53\u524d\u94fe\u8868\u7684\u5934\u8282\u70b9 Returns: Node: \u65b0\u7684\u5934\u8282\u70b9 \"\"\" if head is None : # \u5982\u679c\u94fe\u8868\u4e3a\u7a7a\uff0c\u6253\u5370\u6d88\u606f\u5e76\u8fd4\u56de\u7a7a\u94fe\u8868 print ( \"Linked list is empty.\" ) else : head = head . next # \u5c06\u5934\u8282\u70b9\u6307\u5411\u4e0b\u4e00\u4e2a\u8282\u70b9\uff0c\u5373\u5220\u9664\u7b2c\u4e00\u4e2a\u8282\u70b9 return head # \u8fd4\u56de\u65b0\u7684\u5934\u8282\u70b9 def delete_at_end ( head ): \"\"\" \u4ece\u94fe\u8868\u672b\u5c3e\u5220\u9664\u8282\u70b9 Args: head: \u5f53\u524d\u94fe\u8868\u7684\u5934\u8282\u70b9 Returns: Node: \u5934\u8282\u70b9 \"\"\" if head is None : # \u5982\u679c\u94fe\u8868\u4e3a\u7a7a\uff0c\u8fd4\u56deNone return None if head . next is None : # \u5982\u679c\u94fe\u8868\u53ea\u6709\u4e00\u4e2a\u8282\u70b9\uff0c\u5c06\u5934\u8282\u70b9\u7f6e\u4e3aNone return None current = head while current . next . next : # \u79fb\u52a8\u5230\u5012\u6570\u7b2c\u4e8c\u4e2a\u8282\u70b9 current = current . next current . next = None # \u5c06\u5012\u6570\u7b2c\u4e8c\u4e2a\u8282\u70b9\u7684next\u7f6e\u4e3aNone\uff0c\u5373\u5220\u9664\u4e86\u6700\u540e\u4e00\u4e2a\u8282\u70b9 return head # \u8fd4\u56de\u5934\u8282\u70b9 def insert_at_position ( head , data , position ): \"\"\" \u5728\u94fe\u8868\u7684\u4efb\u610f\u4f4d\u7f6e\u63d2\u5165\u65b0\u8282\u70b9 Args: head: \u5f53\u524d\u94fe\u8868\u7684\u5934\u8282\u70b9 data: \u65b0\u8282\u70b9\u7684\u6570\u636e position: \u63d2\u5165\u7684\u4f4d\u7f6e Returns: Node: \u5934\u8282\u70b9 \"\"\" new_node = Node ( data ) # \u521b\u5efa\u65b0\u7684\u8282\u70b9\u5bf9\u8c61 if position == 0 : # \u5982\u679c\u63d2\u5165\u4f4d\u7f6e\u4e3a0\uff0c\u5373\u5728\u5934\u90e8\u63d2\u5165 new_node . next = head # \u65b0\u8282\u70b9\u7684next\u6307\u5411\u5f53\u524d\u5934\u8282\u70b9 return new_node # \u8fd4\u56de\u65b0\u7684\u5934\u8282\u70b9 probe = head # \u521b\u5efa\u4e00\u4e2a\u6307\u9488\uff0c\u4ece\u5934\u8282\u70b9\u5f00\u59cb\u904d\u5386\u94fe\u8868 count = 0 while probe . next is not None and count < position - 1 : # \u627e\u5230\u63d2\u5165\u4f4d\u7f6e\u7684\u524d\u4e00\u4e2a\u8282\u70b9 probe = probe . next count += 1 new_node . next = probe . next # \u65b0\u8282\u70b9\u7684next\u6307\u5411\u63d2\u5165\u4f4d\u7f6e\u7684\u8282\u70b9 probe . next = new_node # \u63d2\u5165\u4f4d\u7f6e\u7684\u524d\u4e00\u4e2a\u8282\u70b9\u7684next\u6307\u5411\u65b0\u8282\u70b9 return head # \u8fd4\u56de\u5934\u8282\u70b9 def delete_at_position ( head , position ): \"\"\" \u4ece\u94fe\u8868\u7684\u4efb\u610f\u4f4d\u7f6e\u5220\u9664\u8282\u70b9 Args: head: \u5f53\u524d\u94fe\u8868\u7684\u5934\u8282\u70b9 position: \u5220\u9664\u7684\u4f4d\u7f6e Returns: Node: \u5934\u8282\u70b9 \"\"\" if head is None : # \u5982\u679c\u94fe\u8868\u4e3a\u7a7a\uff0c\u8fd4\u56deNone return None if position == 0 : # \u5982\u679c\u5220\u9664\u4f4d\u7f6e\u4e3a0\uff0c\u5373\u5220\u9664\u5934\u90e8\u8282\u70b9 return head . next # \u8fd4\u56de\u5934\u8282\u70b9\u7684\u4e0b\u4e00\u4e2a\u8282\u70b9 probe = head # \u521b\u5efa\u4e00\u4e2a\u6307\u9488\uff0c\u4ece\u5934\u8282\u70b9\u5f00\u59cb\u904d\u5386\u94fe\u8868 count = 0 while probe . next is not None and count < position - 1 : # \u627e\u5230\u5220\u9664\u4f4d\u7f6e\u7684\u524d\u4e00\u4e2a\u8282\u70b9 probe = probe . next count += 1 if probe . next is None : # \u5982\u679c\u5220\u9664\u4f4d\u7f6e\u8d85\u8fc7\u94fe\u8868\u957f\u5ea6\uff0c\u4e0d\u505a\u64cd\u4f5c return head probe . next = probe . next . next # \u5220\u9664\u4f4d\u7f6e\u7684\u524d\u4e00\u4e2a\u8282\u70b9\u7684next\u6307\u5411\u5220\u9664\u4f4d\u7f6e\u7684\u540e\u4e00\u4e2a\u8282\u70b9 return head # \u8fd4\u56de\u5934\u8282\u70b9 def print_linked_list ( head ): \"\"\" \u6253\u5370\u94fe\u8868\u4e2d\u7684\u6240\u6709\u8282\u70b9 Args: head: \u5f53\u524d\u94fe\u8868\u7684\u5934\u8282\u70b9 \"\"\" probe = head while probe is not None : print ( probe . data , end = \" -> \" ) # \u6253\u5370\u5f53\u524d\u8282\u70b9\u7684\u6570\u636e probe = probe . next # \u79fb\u52a8\u5230\u4e0b\u4e00\u4e2a\u8282\u70b9 print ( \"None\" ) # \u6253\u5370\u94fe\u8868\u7ed3\u675f\u7684\u6807\u5fd7 def main (): head = None # \u521b\u5efa\u4e00\u4e2a\u7a7a\u94fe\u8868\uff0c\u521d\u59cb\u65f6\u5934\u8282\u70b9\u4e3aNone # \u4ece\u5c3e\u90e8\u63d2\u5165\u8282\u70b9 for count in range ( 1 , 6 ): # \u4ece1\u52305\u904d\u5386 head = insert_at_end ( head , count ) # \u5728\u5c3e\u90e8\u63d2\u5165\u8282\u70b9 print ( \"\u521d\u59cb\u94fe\u8868:\" ) print_linked_list ( head ) # \u6253\u5370\u539f\u59cb\u94fe\u8868 # \u9a8c\u8bc1\u4ece\u5934\u90e8\u5904\u63d2\u5165\u8282\u70b9 new_data_at_beginning = 0 head = insert_at_beginning ( head , new_data_at_beginning ) # \u5728\u94fe\u8868\u5934\u90e8\u63d2\u5165\u65b0\u8282\u70b9 print ( f \" \\n \u5728\u5934\u90e8\u63d2\u5165 { new_data_at_beginning } \u540e\u7684\u94fe\u8868:\" ) print_linked_list ( head ) # \u6253\u5370\u63d2\u5165\u65b0\u8282\u70b9\u540e\u7684\u94fe\u8868\u72b6\u6001 # \u9a8c\u8bc1\u4ece\u672b\u5c3e\u5904\u63d2\u5165\u8282\u70b9 new_data = 10 head = insert_at_end ( head , new_data ) # \u5728\u94fe\u8868\u672b\u5c3e\u63d2\u5165\u65b0\u8282\u70b9 print ( f \" \\n \u5728\u5c3e\u90e8\u63d2\u5165 { new_data } \u540e\u7684\u94fe\u8868:\" ) print_linked_list ( head ) # \u6253\u5370\u63d2\u5165\u65b0\u8282\u70b9\u540e\u7684\u94fe\u8868\u72b6\u6001 # \u9a8c\u8bc1\u4ece\u5934\u90e8\u5220\u9664\u8282\u70b9 head = delete_at_beginning ( head ) # \u5220\u9664\u7b2c\u4e00\u4e2a\u8282\u70b9 print ( \" \\n \u4ece\u5934\u90e8\u5220\u9664\u8282\u70b9\u540e\u7684\u94fe\u8868:\" ) print_linked_list ( head ) # \u6253\u5370\u5220\u9664\u8282\u70b9\u540e\u7684\u94fe\u8868\u72b6\u6001 # \u9a8c\u8bc1\u4ece\u5c3e\u90e8\u5220\u9664\u8282\u70b9 head = delete_at_end ( head ) # \u4ece\u94fe\u8868\u672b\u5c3e\u5220\u9664\u8282\u70b9 print ( \" \\n \u4ece\u5c3e\u90e8\u5220\u9664\u8282\u70b9\u540e\u7684\u94fe\u8868:\" ) print_linked_list ( head ) # \u6253\u5370\u5220\u9664\u8282\u70b9\u540e\u7684\u94fe\u8868\u72b6\u6001 # \u9a8c\u8bc1\u4ece\u4efb\u610f\u4f4d\u7f6e\u63d2\u5165\u8282\u70b9 position = 3 new_data = 99 head = insert_at_position ( head , new_data , position ) # \u5728\u7b2c3\u4e2a\u4f4d\u7f6e\u63d2\u5165\u8282\u70b9 print ( f \" \\n \u5728\u4f4d\u7f6e { position } \u63d2\u5165 { new_data } \u540e\u7684\u94fe\u8868:\" ) print_linked_list ( head ) # \u9a8c\u8bc1\u4ece\u4efb\u610f\u4f4d\u7f6e\u5220\u9664\u8282\u70b9 position = 2 head = delete_at_position ( head , position ) # \u5220\u9664\u7b2c2\u4e2a\u4f4d\u7f6e\u7684\u8282\u70b9 print ( f \" \\n \u5728\u4f4d\u7f6e { position } \u63d2\u5165 { new_data } \u540e\u7684\u94fe\u8868:\" ) print_linked_list ( head ) if __name__ == \"__main__\" : main () # \u8fd0\u884c\u7ed3\u679c # \u521d\u59cb\u94fe\u8868: # 1 -> 2 -> 3 -> 4 -> 5 -> None # \u5728\u5934\u90e8\u63d2\u5165 0 \u540e\u7684\u94fe\u8868: # 0 -> 1 -> 2 -> 3 -> 4 -> 5 -> None # \u5728\u5c3e\u90e8\u63d2\u5165 10 \u540e\u7684\u94fe\u8868: # 0 -> 1 -> 2 -> 3 -> 4 -> 5 -> 10 -> None # \u4ece\u5934\u90e8\u5220\u9664\u8282\u70b9\u540e\u7684\u94fe\u8868: # 1 -> 2 -> 3 -> 4 -> 5 -> 10 -> None # \u4ece\u5c3e\u90e8\u5220\u9664\u8282\u70b9\u540e\u7684\u94fe\u8868: # 1 -> 2 -> 3 -> 4 -> 5 -> None # \u5728\u4f4d\u7f6e 3 \u63d2\u5165 99 \u540e\u7684\u94fe\u8868: # 1 -> 2 -> 3 -> 99 -> 4 -> 5 -> None # \u5728\u4f4d\u7f6e 2 \u63d2\u5165 99 \u540e\u7684\u94fe\u8868: # 1 -> 2 -> 99 -> 4 -> 5 -> None","title":"4.5.4.\u5728\u5f00\u59cb\u5904\u63d2\u5165"},{"location":"python/DataStructure/04_ArrayChain/#455","text":"\u5bf9\u4e8e\u5355\u5411\u94fe\u63a5\u7ed3\u6784\uff0c\u5728\u7ed3\u5c3e\u5904\u63d2\u5165\u65f6\u9700\u8981\u8003\u8651\u4e24\u79cd\u60c5\u51b5\uff1a \u5f53 head \u6307\u9488\u662f None \u65f6\uff0c\u5b83\u4f1a\u88ab\u8bbe\u7f6e\u4e3a\u65b0\u8282\u70b9\u3002 \u5f53 head \u6307\u9488\u4e0d\u662f None \u65f6\uff0c\u4ee3\u7801\u4f1a\u627e\u5230\u6700\u540e\u4e00\u4e2a\u8282\u70b9\uff0c\u5e76\u628a\u5b83\u7684\u4e0b\u4e00\u4e2a\u6307\u9488\u6307\u5411\u65b0\u8282\u70b9\u3002 \u56e0\u6b64\u5728\u6709\u6570\u636e\u7684\u60c5\u51b5\u4e0b\uff0c\u4f1a\u7528\u5230\u904d\u5386\u6a21\u5f0f\u3002","title":"4.5.5.\u5728\u7ed3\u5c3e\u5904\u63d2\u5165"},{"location":"python/DataStructure/04_ArrayChain/#456","text":"\u5728\u6267\u884c\u4ece\u94fe\u63a5\u7ed3\u6784\u7684\u5f00\u5934\u5220\u9664\u5143\u7d20\u7684\u64cd\u4f5c\u65f6\uff0c\u901a\u5e38\u90fd\u4f1a\u5047\u5b9a\u7ed3\u6784\u91cc\u81f3\u5c11\u5b58\u5728\u4e00\u4e2a\u8282\u70b9\uff0c\u8fd9\u4e2a\u64cd\u4f5c\u5c06\u8fd4\u56de\u88ab\u5220\u9664\u7684\u5143\u7d20\u3002 \u8fd9\u4e2a\u64cd\u4f5c\u4f1a\u7528\u5230\u5e38\u6570\u7684\u65f6\u95f4\u548c\u5185\u5b58\uff0c\u8fd9\u4e0e\u5728\u6570\u7ec4\u4e0a\u6267\u884c\u76f8\u540c\u7684\u64cd\u4f5c\u662f\u6709\u6240\u4e0d\u540c\u7684\u3002","title":"4.5.6.\u5728\u5f00\u59cb\u5904\u5220\u9664"},{"location":"python/DataStructure/04_ArrayChain/#457","text":"\u5355\u5411\u94fe\u63a5\u7ed3\u6784\u4e2d\u7684\u8fd9\u4e2a\u64cd\u4f5c\u5047\u5b9a\u5728\u7ed3\u6784\u91cc\u81f3\u5c11\u6709\u4e00\u4e2a\u8282\u70b9\uff0c\u8fd9\u6837\u5c31\u6709\u4e24\u79cd\u60c5\u51b5\u9700\u8981\u8003\u8651\u3002 \u53ea\u6709\u4e00\u4e2a\u8282\u70b9\uff0c\u8fd9\u65f6\u53ea\u9700\u8981\u628ahead\u6307\u9488\u8bbe\u7f6e\u4e3a None \u3002 \u6700\u540e\u4e00\u4e2a\u8282\u70b9\u4e4b\u524d\u8fd8\u6709\u4e00\u4e2a\u8282\u70b9\u3002\u8fd9\u65f6\u76f8\u5e94\u7684\u4ee3\u7801\u4f1a\u627e\u5230\u5012\u6570\u7b2c\u4e8c\u4e2a\u8282\u70b9\uff0c\u5e76\u628a\u4e0b\u4e00\u4e2a\u6307\u9488\u8bbe\u7f6e\u4e3a None \u3002 \u65e0\u8bba\u662f\u54ea\u79cd\u60c5\u51b5\uff0c\u4ee3\u7801\u90fd\u4f1a\u8fd4\u56de\u8fd9\u4e2a\u88ab\u5220\u9664\u8282\u70b9\u91cc\u5305\u542b\u7684\u6570\u636e\u5143\u7d20\u3002 \u8fd9\u4e2a\u64cd\u4f5c\u4f1a\u7528\u5230\u5e38\u6570\u7684\u65f6\u95f4\u548c\u5185\u5b58\u3002","title":"4.5.7.\u5728\u7ed3\u5c3e\u5904\u5220\u9664"},{"location":"python/DataStructure/04_ArrayChain/#458","text":"\u5728\u94fe\u63a5\u7ed3\u6784\u7684\u4efb\u610f\u4f4d\u7f6e\u63d2\u5165\u5143\u7d20\u65f6\u9700\u8981\u8003\u86512\u79cd\u60c5\u51b5\uff1a \u5728\u5f00\u5934\u63d2\u5165\uff0c\u53ef\u4ee5\u7528\u524d\u9762\u63d0\u5230\u7684\u4ee3\u7801\u3002 \u5728\u5176\u4ed6\u4f4d\u7f6e i \u5904\u8981\u8fdb\u884c\u63d2\u5165\uff0c\u63d2\u5165\u64cd\u4f5c\u5fc5\u987b\u8981\u5148\u627e\u5230\u4f4d\u7f6e i-1 \uff08\u5982\u679c i=n \uff09\u5904\u7684\u8282\u70b9\u3002\u8fd9\u6837\uff0c\u5c31\u6709\u4e24\u79cd\u60c5\u51b5\u9700\u8981\u8003\u8651\u3002 \u8fd9\u4e2a\u8282\u70b9\u540e\u9762\u7684\u6307\u9488\u662f None \u3002\u8fd9\u610f\u5473\u7740 i>=n \uff0c\u56e0\u6b64\u5e94\u8be5\u628a\u65b0\u7684\u5143\u7d20\u653e\u5728\u94fe\u63a5\u7ed3\u6784\u7684\u672b\u5c3e\u3002 \u8fd9\u4e2a\u8282\u70b9\u540e\u9762\u7684\u6307\u9488\u4e0d\u662fNone\u3002\u8fd9\u610f\u5473\u7740 0=n \u2014\u2014\u5220\u9664\u6700\u540e\u4e00\u4e2a\u8282\u70b9\u3002 \u5047\u8bbe\u5728\u94fe\u63a5\u7ed3\u6784\u91cc\u81f3\u5c11\u6709\u4e00\u4e2a\u8282\u70b9\u3002\u8fd9\u4e2a\u64cd\u4f5c\u7684\u6a21\u5f0f\u548c\u63d2\u5165\u64cd\u4f5c\u7684\u6a21\u5f0f\u662f\u7c7b\u4f3c\u7684\uff0c\u56e0\u6b64\u4e5f\u8981\u907f\u514d\u5728\u641c\u7d22\u8fc7\u7a0b\u4e2d\u8d85\u51fa\u94fe\u63a5\u7ed3\u6784\u7684\u672b\u5c3e\u3002\u4f46\u662f\u5728\u8fd9\u4e2a\u8fc7\u7a0b\u4e2d\uff0c\u4f60\u5fc5\u987b\u5141\u8bb8probe\u6307\u9488\u53ef\u4ee5\u8bbf\u95ee\u5230\u94fe\u63a5\u7ed3\u6784\u7684\u5012\u6570\u7b2c\u4e8c\u4e2a\u8282\u70b9\u3002","title":"4.5.9.\u5728\u4efb\u610f\u4f4d\u7f6e\u5904\u5220\u9664"},{"location":"python/DataStructure/04_ArrayChain/#4510","text":"\u5355\u5411\u94fe\u63a5\u7ed3\u6784\u5404\u9879\u64cd\u4f5c\u7684\u8fd0\u884c\u65f6\u590d\u6742\u5ea6 \u64cd\u4f5c \u8fd0\u884c\u65f6\u590d\u6742\u5ea6 \u5728\u4f4d\u7f6ei\u5904\u8bbf\u95ee O(n)\uff0c\uff0c\u5e73\u5747\u60c5\u51b5\u4e0b \u5728\u4f4d\u7f6ei\u5904\u66ff\u6362 O(n)\uff0c\u6700\u597d\u548c\u6700\u574f\u60c5\u51b5\u4e0b \u5728\u5f00\u59cb\u5904\u63d2\u5165 O(1)\uff0c\u6700\u597d\u548c\u6700\u574f\u60c5\u51b5\u4e0b \u5728\u5f00\u59cb\u5904\u5220\u9664 O(1)\uff0c\u6700\u597d\u548c\u6700\u574f\u60c5\u51b5\u4e0b \u5728\u4f4d\u7f6ei\u5904\u63d2\u5165 O(n)\uff0c\u5e73\u5747\u60c5\u51b5\u4e0b \u5728\u4f4d\u7f6ei\u5904\u5220\u9664 O(n)\uff0c\u5e73\u5747\u60c5\u51b5\u4e0b \u4e0e\u6570\u7ec4\u76f8\u6bd4\uff0c\u5355\u5411\u94fe\u63a5\u7ed3\u6784\u7684\u4e3b\u8981\u4f18\u52bf\u5e76\u4e0d\u5728\u4e8e\u65f6\u95f4\u590d\u6742\u5ea6\u800c\u5728\u4e8e\u5185\u5b58\u6027\u80fd\u3002 \u8c03\u6574\u6570\u7ec4\u5c3a\u5bf8\uff08\u5728\u9700\u8981\u7684\u65f6\u5019\u6267\u884c\uff09\uff0c\u4f7f\u5176\u5728\u65f6\u95f4\u548c\u5185\u5b58\u4e0a\u90fd\u662f\u7ebf\u6027\u7684\uff1b\u8c03\u6574\u94fe\u63a5\u7ed3\u6784\u7684\u5927\u5c0f\uff08\u4f1a\u5728\u63d2\u5165\u6216\u5220\u9664\u65f6\u53d1\u751f\uff09\u5728\u65f6\u95f4\u548c\u5185\u5b58\u4e0a\u90fd\u662f\u5e38\u6570\u590d\u6742\u5ea6\u3002 \u5728\u94fe\u63a5\u7ed3\u6784\u91cc\uff0c\u4e0d\u4f1a\u6709\u5185\u5b58\u7684\u6d6a\u8d39\uff0c\u56e0\u4e3a\u8fd9\u4e2a\u7ed3\u6784\u7684\u7269\u7406\u5c3a\u5bf8\u6c38\u8fdc\u90fd\u4e0d\u4f1a\u8d85\u8fc7\u903b\u8f91\u5c3a\u5bf8\u3002 \u94fe\u63a5\u7ed3\u6784\u7684\u786e\u4f1a\u4ea7\u751f\u4e00\u4e9b\u989d\u5916\u7684\u5185\u5b58\u5f00\u9500\uff0c\u8fd9\u662f\u56e0\u4e3a\u5355\u5411\u94fe\u63a5\u7ed3\u6784\u5fc5\u987b\u8981\u6709\u989d\u5916\u7684 n \u4e2a\u5185\u5b58\u5355\u5143\u6765\u5b58\u50a8\u6307\u9488\u3002 \u5bf9\u4e8e\u53cc\u5411\u94fe\u63a5\u7ed3\u6784\u6765\u8bf4\uff0c\u5b83\u7684\u8282\u70b9\u91cc\u5305\u542b\u4e24\u4e2a\u94fe\u63a5\uff0c\u56e0\u6b64\u5185\u5b58\u7684\u6210\u672c\u4f1a\u66f4\u9ad8\u4e00\u4e9b\u3002","title":"4.5.10.\u590d\u6742\u5ea6\u7684\u6743\u8861\uff1a\u65f6\u95f4\u3001\u7a7a\u95f4\u548c\u5355\u5411\u94fe\u63a5\u7ed3\u6784"},{"location":"python/DataStructure/04_ArrayChain/#4511","text":"1\uff0e\u5047\u8bbe\u5df2\u7ecf\u627e\u5230\u4e86\u4ece\u5355\u5411\u94fe\u63a5\u7ed3\u6784\u91cc\u5220\u9664\u5143\u7d20\u7684\u4f4d\u7f6e\uff0c\u8bf7\u8bf4\u660e\u4ece\u8fd9\u4e2a\u65f6\u5019\u5f00\u59cb\u5b8c\u6210\u5220\u9664\u64cd\u4f5c\u7684\u8fd0\u884c\u65f6\u590d\u6742\u5ea6\u3002 \u89e3\u7b54\uff1a\u5982\u679c\u5df2\u7ecf\u627e\u5230\u4e86\u5355\u5411\u94fe\u8868\u4e2d\u8981\u5220\u9664\u5143\u7d20\u7684\u4f4d\u7f6e\uff0c\u5220\u9664\u64cd\u4f5c\u7684\u8fd0\u884c\u65f6\u590d\u6742\u5ea6\u53d6\u51b3\u4e8e\u5220\u9664\u64cd\u4f5c\u7684\u5177\u4f53\u5b9e\u73b0\u3002\u5728\u5355\u5411\u94fe\u8868\u4e2d\uff0c\u5220\u9664\u4e00\u4e2a\u8282\u70b9\u901a\u5e38\u9700\u8981\u627e\u5230\u5f85\u5220\u9664\u8282\u70b9\u7684\u524d\u9a71\u8282\u70b9\uff0c\u7136\u540e\u5c06\u524d\u9a71\u8282\u70b9\u7684 next \u6307\u9488\u6307\u5411\u5f85\u5220\u9664\u8282\u70b9\u7684\u4e0b\u4e00\u4e2a\u8282\u70b9\uff0c\u4ece\u800c\u5c06\u5f85\u5220\u9664\u8282\u70b9\u4ece\u94fe\u8868\u4e2d\u79fb\u9664\u3002 \u67e5\u627e\u5f85\u5220\u9664\u8282\u70b9\u7684\u65f6\u95f4\u590d\u6742\u5ea6\uff1a\u5728\u6700\u574f\u60c5\u51b5\u4e0b\uff0c\u5982\u679c\u8981\u5220\u9664\u7684\u8282\u70b9\u4f4d\u4e8e\u94fe\u8868\u7684\u672b\u5c3e\uff0c\u6216\u8005\u9700\u8981\u904d\u5386\u6574\u4e2a\u94fe\u8868\u624d\u80fd\u627e\u5230\u5f85\u5220\u9664\u8282\u70b9\uff0c\u67e5\u627e\u64cd\u4f5c\u7684\u65f6\u95f4\u590d\u6742\u5ea6\u4e3aO(n)\uff0c\u5176\u4e2dn\u662f\u94fe\u8868\u7684\u957f\u5ea6\u3002 \u5220\u9664\u8282\u70b9\u7684\u65f6\u95f4\u590d\u6742\u5ea6\uff1a\u5220\u9664\u8282\u70b9\u7684\u64cd\u4f5c\u662f\u5e38\u6570\u65f6\u95f4O(1)\uff0c\u56e0\u4e3a\u5b83\u6d89\u53ca\u7684\u64cd\u4f5c\u90fd\u662f\u57fa\u672c\u7684\u8d4b\u503c\u548c\u6307\u9488\u8c03\u6574\u3002 \u6240\u4ee5\uff0c\u5982\u679c\u5df2\u7ecf\u627e\u5230\u4e86\u5f85\u5220\u9664\u8282\u70b9\u7684\u4f4d\u7f6e\uff0c\u5220\u9664\u64cd\u4f5c\u7684\u8fd0\u884c\u65f6\u590d\u6742\u5ea6\u662fO(n)\u3002 2\uff0e\u53ef\u4ee5\u5bf9\u5355\u5411\u94fe\u63a5\u7ed3\u6784\u91cc\u6309\u987a\u5e8f\u6392\u5217\u7684\u5143\u7d20\u6267\u884c\u4e8c\u5206\u641c\u7d22\u5417\uff1f\u5982\u679c\u4e0d\u53ef\u4ee5\uff0c\u4e3a\u4ec0\u4e48\uff1f \u89e3\u7b54\uff1a\u5728\u666e\u901a\u7684\u5355\u5411\u94fe\u8868\u4e2d\uff0c\u65e0\u6cd5\u76f4\u63a5\u6267\u884c\u4e8c\u5206\u641c\u7d22\u3002\u4e8c\u5206\u641c\u7d22\u901a\u5e38\u57fa\u4e8e\u6570\u7ec4\u8fd9\u79cd\u8fde\u7eed\u5b58\u50a8\u7ed3\u6784\uff0c\u53ef\u4ee5\u76f4\u63a5\u901a\u8fc7\u7d22\u5f15\u8fdb\u884c\u5feb\u901f\u8bbf\u95ee\u3002\u4f46\u5728\u5355\u5411\u94fe\u8868\u4e2d\uff0c\u8981\u67e5\u627e\u4e2d\u95f4\u5143\u7d20\uff0c\u9700\u8981\u904d\u5386\u94fe\u8868\u4ee5\u627e\u5230\u4e2d\u95f4\u4f4d\u7f6e\u3002\u56e0\u4e3a\u94fe\u8868\u7684\u5143\u7d20\u4e0d\u662f\u6309\u7167\u7d22\u5f15\u6392\u5217\u7684\uff0c\u6240\u4ee5\u4e0d\u80fd\u76f4\u63a5\u8fdb\u884c\u4e8c\u5206\u641c\u7d22\u3002 \u5982\u679c\u5e0c\u671b\u5728\u6709\u5e8f\u94fe\u8868\u4e2d\u6267\u884c\u4e8c\u5206\u641c\u7d22\uff0c\u53ef\u4ee5\u8003\u8651\u4f7f\u7528\u53e6\u4e00\u79cd\u6570\u636e\u7ed3\u6784\u2014\u2014\u4e8c\u53c9\u641c\u7d22\u6811\uff08Binary Search Tree\uff09\u3002\u5728\u4e8c\u53c9\u641c\u7d22\u6811\u4e2d\uff0c\u6bcf\u4e2a\u8282\u70b9\u7684\u5de6\u5b50\u6811\u7684\u503c\u5c0f\u4e8e\u8be5\u8282\u70b9\u7684\u503c\uff0c\u53f3\u5b50\u6811\u7684\u503c\u5927\u4e8e\u8be5\u8282\u70b9\u7684\u503c\uff0c\u56e0\u6b64\u53ef\u4ee5\u5229\u7528\u8fd9\u79cd\u6709\u5e8f\u6027\u8fdb\u884c\u5feb\u901f\u641c\u7d22\u3002 3\uff0e\u8bf7\u8bf4\u660e\u4e3a\u4ec0\u4e48Python\u5217\u8868\u4f1a\u4f7f\u7528\u6570\u7ec4\u800c\u4e0d\u662f\u94fe\u63a5\u7ed3\u6784\u6765\u4fdd\u5b58\u5b83\u7684\u5143\u7d20\u3002 \u89e3\u7b54\uff1aPython\u7684\u5217\u8868\u4f7f\u7528\u6570\u7ec4\u800c\u4e0d\u662f\u94fe\u63a5\u7ed3\u6784\u6765\u4fdd\u5b58\u5143\u7d20\uff0c\u4e3b\u8981\u662f\u56e0\u4e3a\u6570\u7ec4\u5728\u968f\u673a\u8bbf\u95ee\uff08\u6839\u636e\u7d22\u5f15\u76f4\u63a5\u8bbf\u95ee\u5143\u7d20\uff09\u548c\u5207\u7247\uff08\u901a\u8fc7[start:stop:step]\u65b9\u5f0f\u622a\u53d6\u5b50\u5217\u8868\uff09\u64cd\u4f5c\u4e0a\u5177\u6709\u66f4\u597d\u7684\u6027\u80fd\u3002\u6570\u7ec4\u7684\u5185\u5b58\u7a7a\u95f4\u662f\u8fde\u7eed\u7684\uff0c\u56e0\u6b64\u53ef\u4ee5\u901a\u8fc7\u7d22\u5f15\u8fc5\u901f\u8ba1\u7b97\u51fa\u5143\u7d20\u7684\u5185\u5b58\u5730\u5740\u3002\u8fd9\u4f7f\u5f97\u968f\u673a\u8bbf\u95ee\u548c\u5207\u7247\u7684\u65f6\u95f4\u590d\u6742\u5ea6\u662fO(1)\uff0c\u5373\u5e38\u6570\u65f6\u95f4\u3002\u800c\u94fe\u63a5\u7ed3\u6784\u5728\u968f\u673a\u8bbf\u95ee\u4e0a\u7684\u65f6\u95f4\u590d\u6742\u5ea6\u901a\u5e38\u662fO(n)\uff0c\u5176\u4e2dn\u662f\u94fe\u8868\u7684\u957f\u5ea6\uff0c\u56e0\u4e3a\u9700\u8981\u4ece\u5934\u8282\u70b9\u5f00\u59cb\u9010\u4e2a\u904d\u5386\u627e\u5230\u76ee\u6807\u8282\u70b9\u3002 \u5728Python\u7684\u5217\u8868\u4e2d\uff0c\u652f\u6301\u901a\u8fc7\u7d22\u5f15\u968f\u673a\u8bbf\u95ee\u5143\u7d20\uff0c\u8fd9\u662f\u56e0\u4e3a\u5217\u8868\u7684\u5143\u7d20\u662f\u4fdd\u5b58\u5728\u4e00\u4e2a\u8fde\u7eed\u7684\u5185\u5b58\u5757\u4e2d\u7684\u3002\u8fd9\u79cd\u8bbe\u8ba1\u4f7f\u5f97Python\u7684\u5217\u8868\u5728\u5927\u591a\u6570\u5e38\u89c1\u64cd\u4f5c\uff08\u4f8b\u5982\u67e5\u627e\u3001\u63d2\u5165\u3001\u5220\u9664\uff09\u4e0a\u90fd\u80fd\u63d0\u4f9b\u8f83\u597d\u7684\u6027\u80fd\uff0c\u7279\u522b\u662f\u5f53\u9700\u8981\u901a\u8fc7\u7d22\u5f15\u6216\u5207\u7247\u5feb\u901f\u8bbf\u95ee\u6216\u4fee\u6539\u5143\u7d20\u65f6\u3002\u7136\u800c\uff0c\u5bf9\u4e8e\u5728\u4e2d\u95f4\u63d2\u5165\u6216\u5220\u9664\u5143\u7d20\u8fd9\u6837\u7684\u64cd\u4f5c\uff0c\u5217\u8868\u7684\u6027\u80fd\u53ef\u80fd\u76f8\u5bf9\u8f83\u4f4e\uff0c\u56e0\u4e3a\u5728\u6570\u7ec4\u4e2d\u95f4\u63d2\u5165\u6216\u5220\u9664\u5143\u7d20\u901a\u5e38\u9700\u8981\u79fb\u52a8\u5176\u4ed6\u5143\u7d20\uff0c\u5bfc\u81f4\u65f6\u95f4\u590d\u6742\u5ea6\u4e3aO(n)\u3002 \u603b\u7684\u6765\u8bf4\uff0cPython\u7684\u5217\u8868\u91c7\u7528\u6570\u7ec4\u5b58\u50a8\u5143\u7d20\uff0c\u662f\u4e3a\u4e86\u5728\u5927\u591a\u6570\u5e38\u89c1\u64cd\u4f5c\u4e2d\u63d0\u4f9b\u8f83\u597d\u7684\u6027\u80fd\u3002\u5982\u679c\u9700\u8981\u5728\u4e2d\u95f4\u63d2\u5165\u6216\u5220\u9664\u5143\u7d20\u7684\u64cd\u4f5c\u6bd4\u8f83\u9891\u7e41\uff0c\u53ef\u80fd\u9700\u8981\u8003\u8651\u4f7f\u7528\u94fe\u8868\u7b49\u6570\u636e\u7ed3\u6784\u3002Python\u4e2d\u7684 collections \u6a21\u5757\u63d0\u4f9b\u4e86 deque \uff08\u53cc\u7aef\u961f\u5217\uff09\u7b49\u6570\u636e\u7ed3\u6784\uff0c\u53ef\u4ee5\u7528\u4e8e\u5728\u4e24\u7aef\u9ad8\u6548\u5730\u8fdb\u884c\u63d2\u5165\u548c\u5220\u9664\u64cd\u4f5c\u3002 \u8865\u5145\uff1a \u67e5\u770b\u6e90\u4ee3\u7801\u7684\u65b9\u6cd5\u3002 import array import inspect # \u83b7\u53d6array\u6a21\u5757\u7684\u6e90\u4ee3\u7801 source_code = inspect . getsource ( array ) # \u6253\u5370\u6e90\u4ee3\u7801 print ( source_code ) \u5bf9\u4e8e\u5185\u7f6e\u7684\u6a21\u5757\uff0c\u4e0d\u80fd\u76f4\u63a5\u901a\u8fc7inspect\u6a21\u5757\u67e5\u770b\u6e90\u4ee3\u7801\u3002\u53ef\u4ee5\u901a\u8fc7\u5728\u7ebf\u67e5\u770bPython\u7684\u6e90\u4ee3\u7801\u3002Python\u7684\u6e90\u4ee3\u7801\u6258\u7ba1\u5728GitHub\u4e0a\uff0c\u4f60\u53ef\u4ee5\u5728\u4ee5\u4e0b\u94fe\u63a5\u4e2d\u627e\u5230Python\u7684\u6e90\u4ee3\u7801\uff1a Python GitHub Repository \uff0c\u5305\u62ec array\u7684\u6e90\u4ee3\u7801 \u3002","title":"4.5.11.\u7ec3\u4e60\u9898"},{"location":"python/DataStructure/04_ArrayChain/#46","text":"","title":"4.6.\u94fe\u63a5\u4e0a\u7684\u53d8\u5316"},{"location":"python/DataStructure/04_ArrayChain/#461","text":"\u5728\u7b2c\u4e00\u4e2a\u8282\u70b9\u4f4d\u7f6e\u5904\u6267\u884c\u63d2\u5165\u548c\u5220\u9664\u64cd\u4f5c\u662f\u5355\u5411\u94fe\u63a5\u7ed3\u6784\u91cc\u5728\u4efb\u610f\u4f4d\u7f6e\u8fdb\u884c\u63d2\u5165\u548c\u5220\u9664\u64cd\u4f5c\u7684\u7279\u6b8a\u60c5\u51b5\uff0c\u662f\u56e0\u4e3a\u8fd9\u4e2a\u65f6\u5019\u5fc5\u987b\u91cd\u7f6ehead\u6307\u9488\u3002 \u53ef\u4ee5\u901a\u8fc7\u5305\u542b\u865a\u62df\u5934\u8282\u70b9\uff08dummy header node\uff09\u7684\u73af\u72b6\u94fe\u63a5\u7ed3\u6784\uff08circular linked structure\uff09\u7b80\u5316\u8fd9\u4e24\u4e2a\u64cd\u4f5c\u3002 \u73af\u72b6\u94fe\u63a5\u7ed3\u6784\u5305\u542b\u4e86\u4ece\u6700\u540e\u4e00\u4e2a\u8282\u70b9\u5230\u7b2c\u4e00\u4e2a\u8282\u70b9\u7684\u94fe\u63a5\uff0c\u5e76\u4e14\u5b83\u7684\u5b9e\u73b0\u91cc\u81f3\u5c11\u4f1a\u5305\u542b\u4e00\u4e2a\u8282\u70b9\u3002\u8fd9\u4e2a\u8282\u70b9\uff08\u865a\u62df\u5934\u8282\u70b9\uff09\u4e0d\u5305\u542b\u4efb\u4f55\u6570\u636e\uff0c\u4f46\u4f1a\u88ab\u7528\u6765\u4f5c\u4e3a\u94fe\u63a5\u7ed3\u6784\u7684\u5f00\u59cb\u548c\u7ed3\u675f\u7684\u6807\u8bb0\u3002\u5728\u6700\u521d\u7684\u7a7a\u94fe\u63a5\u7ed3\u6784\u91cc\uff0chead\u53d8\u91cf\u4f1a\u6307\u5411\u865a\u62df\u5934\u8282\u70b9\uff0c\u800c\u865a\u62df\u5934\u8282\u70b9\u7684\u4e0b\u4e00\u4e2a\u6307\u9488\u4f1a\u6307\u5411\u865a\u62df\u5934\u8282\u70b9\u672c\u8eab\u3002\u5982\u4e0b\u56fe\u6240\u793a\u3002","title":"4.6.1.\u5305\u542b\u865a\u62df\u5934\u8282\u70b9\u7684\u73af\u72b6\u94fe\u63a5\u7ed3\u6784"},{"location":"python/DataStructure/04_ArrayChain/#462","text":"","title":"4.6.2.\u53cc\u5411\u94fe\u63a5\u7ed3\u6784"},{"location":"python/DataStructure/04_ArrayChain/#463","text":"1\uff0e\u5305\u542b\u865a\u62df\u5934\u8282\u70b9\u7684\u73af\u72b6\u94fe\u63a5\u7ed3\u6784\u7ed9\u7a0b\u5e8f\u5458\u5e26\u6765\u4e86\u4ec0\u4e48\u597d\u5904\uff1f 2\uff0e\u548c\u5355\u5411\u94fe\u63a5\u7ed3\u6784\u76f8\u6bd4\uff0c\u8bf7\u63cf\u8ff0\u53cc\u5411\u94fe\u63a5\u7ed3\u6784\u7684\u4e00\u4e2a\u597d\u5904\u548c\u4e00\u4e2a\u989d\u5916\u5f00\u9500\u3002","title":"4.6.3.\u7ec3\u4e60\u9898"},{"location":"python/DataStructure/04_ArrayChain/#47","text":"\u6570\u636e\u7ed3\u6784\u662f\u4e00\u4e2a\u8868\u793a\u591a\u9879\u96c6\u91cc\u6240\u5305\u542b\u6570\u636e\u7684\u5bf9\u8c61\u3002 \u6570\u7ec4\u662f\u4e00\u79cd\u5728\u5e38\u6570\u65f6\u95f4\u5185\u652f\u6301\u5bf9\u4f4d\u7f6e\u9010\u9879\u968f\u673a\u8bbf\u95ee\u7684\u6570\u636e\u7ed3\u6784\u3002\u5728\u521b\u5efa\u6570\u7ec4\u65f6\uff0c\u4f1a\u4e3a\u5b83\u5206\u914d\u82e5\u5e72\u4e2a\u7528\u6765\u5b58\u653e\u6570\u636e\u7684\u5185\u5b58\u7a7a\u95f4\uff0c\u5e76\u4e14\u6570\u7ec4\u7684\u957f\u5ea6\u4f1a\u4fdd\u6301\u4e0d\u53d8\u3002\u63d2\u5165\u548c\u5220\u9664\u64cd\u4f5c\u9700\u8981\u79fb\u52a8\u6570\u636e\u5143\u7d20\uff0c\u5e76\u4e14\u53ef\u80fd\u9700\u8981\u521b\u5efa\u4e00\u4e2a\u65b0\u7684\u3001\u66f4\u5927\u6216\u66f4\u5c0f\u7684\u6570\u7ec4\u3002 \u4e8c\u7ef4\u6570\u7ec4\u91cc\u7684\u6bcf\u4e2a\u6570\u636e\u503c\u90fd\u4f4d\u4e8e\u77e9\u5f62\u7f51\u683c\u7684\u884c\u548c\u5217\u4e0a\u3002 \u94fe\u63a5\u7ed3\u6784\u662f\u75310\u4e2a\u6216\u591a\u4e2a\u8282\u70b9\u7ec4\u6210\u7684\u6570\u636e\u7ed3\u6784\u3002\u6bcf\u4e2a\u8282\u70b9\u90fd\u5305\u542b\u4e00\u4e2a\u6570\u636e\u5143\u7d20\u548c\u4e00\u4e2a\u6216\u591a\u4e2a\u6307\u5411\u5176\u4ed6\u8282\u70b9\u7684\u94fe\u63a5\u3002 \u5355\u5411\u94fe\u63a5\u7ed3\u6784\u7684\u8282\u70b9\u5305\u542b\u6570\u636e\u5143\u7d20\u548c\u5230\u4e0b\u4e00\u4e2a\u8282\u70b9\u7684\u94fe\u63a5\u3002\u53cc\u5411\u94fe\u63a5\u7ed3\u6784\u91cc\u7684\u8282\u70b9\u8fd8\u5305\u542b\u5230\u524d\u4e00\u4e2a\u8282\u70b9\u7684\u94fe\u63a5\u3002 \u5728\u94fe\u63a5\u7ed3\u6784\u91cc\u8fdb\u884c\u63d2\u5165\u6216\u5220\u9664\u64cd\u4f5c\u4e0d\u9700\u8981\u79fb\u52a8\u6570\u636e\u5143\u7d20\uff0c\u6bcf\u6b21\u6700\u591a\u53ea\u4f1a\u521b\u5efa\u4e00\u4e2a\u8282\u70b9\u3002\u4f46\u662f\uff0c\u5728\u94fe\u63a5\u7ed3\u6784\u91cc\u6267\u884c\u63d2\u5165\u3001\u5220\u9664\u548c\u8bbf\u95ee\u64cd\u4f5c\u9700\u8981\u7684\u65f6\u95f4\u590d\u6742\u5ea6\u90fd\u662f\u7ebf\u6027\u7684\u3002 \u5728\u94fe\u63a5\u7ed3\u6784\u91cc\u4f7f\u7528\u5934\u8282\u70b9\u53ef\u4ee5\u7b80\u5316\u67d0\u4e9b\u64cd\u4f5c\uff0c\u5982\u6dfb\u52a0\u6216\u5220\u9664\u5143\u7d20\u3002","title":"4.7.\u5c0f\u7ed3"},{"location":"python/DataStructure/04_ArrayChain/#48","text":"1\uff0e\u6570\u7ec4\u548c\u94fe\u63a5\u7ed3\u6784\u90fd\u662f\uff1a \u62bd\u8c61\u6570\u636e\u7c7b\u578b\uff08ADT\uff09 \u6570\u636e\u7ed3\u6784 2\uff0e\u6570\u7ec4\u7684\u957f\u5ea6\uff1a \u5728\u521b\u5efa\u4e4b\u540e\u5927\u5c0f\u662f\u56fa\u5b9a\u7684 \u5728\u521b\u5efa\u4e4b\u540e\u5927\u5c0f\u53ef\u4ee5\u589e\u52a0\u6216\u51cf\u5c11 3\uff0e\u5728\u6570\u7ec4\u91cc\u8fdb\u884c\u968f\u673a\u8bbf\u95ee\u652f\u6301\u5728\uff1a \u5e38\u6570\u65f6\u95f4\u91cc\u8bbf\u95ee\u6570\u636e \u7ebf\u6027\u65f6\u95f4\u91cc\u8bbf\u95ee\u6570\u636e 4\uff0e\u5355\u5411\u94fe\u63a5\u7ed3\u6784\u91cc\u7684\u6570\u636e\u5305\u542b\u5728\uff1a \u5355\u5143\u91cc \u8282\u70b9\u91cc 5\uff0e\u5bf9\u5355\u5411\u94fe\u63a5\u7ed3\u6784\u6267\u884c\u7684\u5927\u591a\u6570\u64cd\u4f5c\u90fd\u9700\u8981\uff1a \u5e38\u6570\u65f6\u95f4 \u7ebf\u6027\u65f6\u95f4 6\uff0e\u4ece\u4ee5\u4e0b\u54ea\u79cd\u7c7b\u578b\u91cc\u5220\u9664\u7b2c\u4e00\u4e2a\u5143\u7d20\u9700\u8981\u5e38\u6570\u65f6\u95f4\uff1a \u6570\u7ec4 \u5355\u5411\u94fe\u63a5\u7ed3\u6784 7\uff0e\u5728\u4e0b\u9762\u54ea\u79cd\u60c5\u51b5\u4e0b\uff0c\u6570\u7ec4\u91cc\u4f7f\u7528\u7684\u5185\u5b58\u4f1a\u5c11\u4e8e\u5355\u5411\u94fe\u63a5\u7ed3\u6784\u7684\uff1a \u4e0d\u5230\u4e00\u534a\u7684\u4f4d\u7f6e\u653e\u7f6e\u4e86\u6570\u636e \u4e00\u534a\u4ee5\u4e0a\u7684\u4f4d\u7f6e\u653e\u7f6e\u4e86\u6570\u636e 8\uff0e\u5f53\u6570\u7ec4\u7684\u5185\u5b58\u4e0d\u8db3\u4ee5\u4fdd\u5b58\u6570\u636e\u65f6\uff0c\u6700\u597d\u521b\u5efa\u4e00\u4e2a\u65b0\u7684\u6570\u7ec4\uff0c\u8fd9\u4e2a\u65b0\u6570\u7ec4\u5e94\u8be5\uff1a \u5927\u5c0f\u6bd4\u65e7\u6570\u7ec4\u591a1\u4e2a\u4f4d\u7f6e \u5927\u5c0f\u662f\u65e7\u6570\u7ec4\u76842\u500d 9\uff0e\u5bf9\u4e8e\u5355\u5411\u94fe\u63a5\u7ed3\u6784\uff0c\u5f53\u4f60\u5728\u4ec0\u4e48\u5730\u65b9\u6267\u884c\u63d2\u5165\u64cd\u4f5c\u4f1a\u5f97\u5230\u6700\u574f\u60c5\u51b5\u4e0b\u7684\u8fd0\u884c\u65f6\uff1a \u5728\u7ed3\u6784\u7684\u5f00\u5934 \u5728\u7ed3\u6784\u7684\u672b\u5c3e 10\uff0e\u53cc\u5411\u94fe\u63a5\u7ed3\u6784\u8ba9\u7a0b\u5e8f\u5458\u53ef\u4ee5\u79fb\u52a8\u5230\uff1a \u7ed9\u5b9a\u8282\u70b9\u7684\u540e\u4e00\u4e2a\u8282\u70b9\u6216\u524d\u4e00\u4e2a\u8282\u70b9 \u7ed9\u5b9a\u8282\u70b9\u7684\u540e\u4e00\u4e2a\u8282\u70b9","title":"4.8.\u590d\u4e60\u9898"},{"location":"python/DataStructure/04_ArrayChain/#49","text":"\u5728\u524d6\u4e2a\u9879\u76ee\u91cc\uff0c\u4f60\u5c06\u4fee\u6539\u5728\u672c\u7ae0\u5b9a\u4e49\u7684Array\u7c7b\uff0c\u4ece\u800c\u8ba9\u5b83\u66f4\u50cfPython\u7684list\u7c7b\u3002\u5bf9\u4e8e\u8fd9\u4e9b\u9879\u76ee\u7684\u7b54\u6848\uff0c\u8bf7\u5305\u542b\u4f60\u5bf9Array\u7c7b\u6240\u505a\u4fee\u6539\u7684\u4ee3\u7801\u6d4b\u8bd5\u3002 1\uff0e\u4e3aArray\u7c7b\u6dfb\u52a0\u4e00\u4e2a\u5b9e\u4f8b\u53d8\u91cf logicalSize \u3002\u8fd9\u4e2a\u53d8\u91cf\u7684\u521d\u59cb\u503c\u4e3a 0 \uff0c\u7528\u6765\u8bb0\u5f55\u6570\u7ec4\u91cc\u5f53\u524d\u5df2\u7ecf\u5305\u542b\u7684\u5143\u7d20\u6570\u91cf\u3002\u7136\u540e\u4e3aArray\u7c7b\u6dfb\u52a0 size() \u65b9\u6cd5\uff0c\u8fd9\u4e2a\u65b9\u6cd5\u7528\u6765\u8fd4\u56de\u6570\u7ec4\u7684\u903b\u8f91\u5c3a\u5bf8\u3002 __len__ \u65b9\u6cd5\u4f9d\u7136\u4f1a\u8fd4\u56de\u6570\u7ec4\u7684\u5bb9\u91cf\uff0c\u4e5f\u5c31\u662f\u5b83\u7684\u7269\u7406\u5c3a\u5bf8\u3002 2\uff0e\u4e3aArray\u7c7b\u7684 __getitem__ \u548c_ _setitem__ \u65b9\u6cd5\u6dfb\u52a0\u5148\u9a8c\u6761\u4ef6\u3002\u5b83\u4eec\u7684\u5148\u9a8c\u6761\u4ef6\u662f 0<=index < size() \u3002\u5982\u679c\u4e0d\u6ee1\u8db3\u5148\u9a8c\u6761\u4ef6\uff0c\u5c31\u5f15\u53d1\u5f02\u5e38\u3002 3\uff0e\u5c06 grow \u548c shrink \u65b9\u6cd5\u6dfb\u52a0\u5230Array\u7c7b\u3002\u5b83\u4eec\u80fd\u591f\u57fa\u4e8e\u672c\u7ae0\u6240\u8ba8\u8bba\u7684\u7b56\u7565\u6765\u589e\u52a0\u6216\u51cf\u5c11\u6570\u7ec4\u91cc\u6240\u5305\u542b\u7684\u5217\u8868\u957f\u5ea6\u3002\u5728\u5b9e\u73b0\u65f6\uff0c\u8981\u4fdd\u8bc1\u6570\u7ec4\u7684\u7269\u7406\u5c3a\u5bf8\u4e0d\u4f1a\u7f29\u5c0f\u5230\u7528\u6237\u6307\u5b9a\u7684\u5bb9\u91cf\u4e4b\u4e0b\uff0c\u5e76\u4e14\u5728\u589e\u52a0\u6570\u7ec4\u5c3a\u5bf8\u65f6\uff0c\u6570\u7ec4\u7684\u5185\u5b58\u5355\u5143\u5c06\u4f1a\u7528\u9ed8\u8ba4\u503c\u6765\u586b\u5145\u3002 4\uff0e\u5c06\u65b9\u6cd5 insert \u548c pop \u6dfb\u52a0\u5230Array\u7c7b\u4e2d\u3002\u5b83\u4eec\u57fa\u4e8e\u672c\u7ae0\u5df2\u7ecf\u8ba8\u8bba\u8fc7\u7684\u7b56\u7565\uff0c\u5728\u9700\u8981\u7684\u65f6\u5019\u5bf9\u6570\u7ec4\u7684\u957f\u5ea6\u8fdb\u884c\u8c03\u6574\u3002 insert \u65b9\u6cd5\u4f1a\u63a5\u6536\u4e00\u4e2a\u4f4d\u7f6e\u548c\u4e00\u4e2a\u5143\u7d20\u503c\u4f5c\u4e3a\u53c2\u6570\uff0c\u7136\u540e\u628a\u8fd9\u4e2a\u5143\u7d20\u63d2\u5165\u6307\u5b9a\u7684\u4f4d\u7f6e\u3002\u5982\u679c\u4f4d\u7f6e\u5927\u4e8e\u6216\u7b49\u4e8e\u6570\u7ec4\u7684\u903b\u8f91\u5c3a\u5bf8\uff0c\u90a3\u4e48\u8fd9\u4e2a\u65b9\u6cd5\u4f1a\u628a\u5143\u7d20\u63d2\u5165\u6570\u7ec4\u91cc\u5f53\u524d\u53ef\u83b7\u5f97\u7684\u6700\u540e\u4e00\u4e2a\u5143\u7d20\u4e4b\u540e\u3002 pop \u65b9\u6cd5\u4f1a\u63a5\u6536\u4e00\u4e2a\u4f4d\u7f6e\u4f5c\u4e3a\u53c2\u6570\uff0c\u7136\u540e\u5220\u9664\u5e76\u8fd4\u56de\u8fd9\u4e2a\u4f4d\u7f6e\u7684\u5143\u7d20\u3002 pop \u65b9\u6cd5\u7684\u5148\u9a8c\u6761\u4ef6\u662f 0<=index < size() \u3002 pop \u65b9\u6cd5\u8fd8\u5e94\u8be5\u628a\u817e\u51fa\u6765\u7684\u6570\u7ec4\u5185\u5b58\u5355\u5143\u91cd\u7f6e\u4e3a\u586b\u5145\u503c\u3002 5\uff0e\u5c06\u65b9\u6cd5 __eq__ \u6dfb\u52a0\u5230Array\u7c7b\u4e2d\u3002\u5f53Array\u5bf9\u8c61\u4f5c\u4e3a == \u8fd0\u7b97\u7b26\u7684\u5de6\u64cd\u4f5c\u6570\u65f6\uff0cPython\u4f1a\u8fd0\u884c\u8fd9\u4e2a\u65b9\u6cd5\u3002\u5982\u679c\u8fd9\u4e2a\u65b9\u6cd5\u7684\u53c2\u6570\u4e5f\u662f\u4e00\u4e2aArray\u5bf9\u8c61\uff0c\u5e76\u4e14\u5b83\u7684\u903b\u8f91\u5c3a\u5bf8\u548c\u5de6\u64cd\u4f5c\u6570\u76f8\u540c\uff0c\u4e14\u5728\u4e24\u4e2a\u6570\u7ec4\u91cc\u6bcf\u4e2a\u903b\u8f91\u4f4d\u7f6e\u4e0a\u7684\u5143\u7d20\u90fd\u76f8\u7b49\uff0c\u90a3\u4e48\u8fd9\u4e2a\u65b9\u6cd5\u4f1a\u8fd4\u56de True \uff1b\u5426\u5219\uff0c\u8fd9\u4e2a\u65b9\u6cd5\u8fd4\u56de False \u3002 6\uff0e\u4e3a\u4e86\u8ba9Array\u7c7b\u548c\u5217\u8868\u4e00\u6837\uff0c\u5e94\u8be5\u5220\u9664 __iter__ \u65b9\u6cd5\u7684\u5f53\u524d\u5b9e\u73b0\u3002\u8bf7\u89e3\u91ca\u8fd9\u4e3a\u4ec0\u4e48\u662f\u4e00\u4e2a\u597d\u5efa\u8bae\uff0c\u5e76\u8bf4\u660e\u5728\u8fd9\u4e2a\u60c5\u51b5\u4e0b\u5e94\u8be5\u5982\u4f55\u5bf9 __str__ \u65b9\u6cd5\u8fdb\u884c\u4fee\u6539\u3002 7\uff0e Matrix \u7c7b\u53ef\u4ee5\u6267\u884c\u7ebf\u6027\u4ee3\u6570\u91cc\u7684\u67d0\u4e9b\u8fd0\u7b97\uff0c\u6bd4\u5982\u77e9\u9635\u8fd0\u7b97\u3002\u5f00\u53d1\u4e00\u4e2a\u4f7f\u7528\u5185\u7f6e\u8fd0\u7b97\u7b26\u8fdb\u884c\u7b97\u672f\u8fd0\u7b97\u7684 Matrix \u7c7b\uff0c\u8fd9\u4e2a Matrix \u7c7b\u5e94\u6269\u5c55\u81ea Grid \u7c7b\u3002\u5728\u63a5\u4e0b\u6765\u76844\u4e2a\u9879\u76ee\u91cc\uff0c\u4f60\u5e94\u5b9a\u4e49\u4e00\u4e9b\u7528\u6765\u64cd\u4f5c\u94fe\u63a5\u7ed3\u6784\u7684\u51fd\u6570\u3002\u5728\u89e3\u7b54\u7684\u8fc7\u7a0b\u4e2d\uff0c\u4f60\u5e94\u8be5\u7ee7\u7eed\u4f7f\u7528\u672c\u7ae0\u5b9a\u4e49\u7684 Node \u548c TwoWayNode \u7c7b\u3002\u521b\u5efa\u4e00\u4e2a\u6d4b\u8bd5\u6a21\u5757\u4ee5\u5305\u542b\u4f60\u7684\u51fd\u6570\u5b9a\u4e49\u548c\u7528\u6765\u6d4b\u8bd5\u5b83\u4eec\u7684\u4ee3\u7801\u3002 8\uff0e\u5b9a\u4e49\u4e00\u4e2a\u53eb\u4f5c length \u7684\u51fd\u6570\uff08\u4e0d\u662f len \uff09\uff0c\u8fd9\u4e2a\u51fd\u6570\u4f1a\u63a5\u53d7\u4e00\u4e2a\u5355\u5411\u94fe\u63a5\u7ed3\u6784\u4f5c\u4e3a\u53c2\u6570\uff0c\u5e76\u80fd\u591f\u8fd4\u56de\u7ed3\u6784\u91cc\u7684\u5143\u7d20\u6570\u91cf\u3002 9\uff0e\u5b9a\u4e49\u4e00\u4e2a\u53eb\u4f5c insert \u7684\u51fd\u6570\uff0c\u8fd9\u4e2a\u51fd\u6570\u5177\u6709\u628a\u5143\u7d20\u63d2\u5165\u5355\u5411\u94fe\u63a5\u7ed3\u6784\u4e2d\u6307\u5b9a\u4f4d\u7f6e\u7684\u529f\u80fd\u3002\u8fd9\u4e2a\u51fd\u6570\u67093\u4e2a\u53c2\u6570\uff1a\u5143\u7d20\u3001\u4f4d\u7f6e\u4ee5\u53ca\u4e00\u4e2a\u94fe\u63a5\u7ed3\u6784\uff08\u8fd9\u4e2a\u94fe\u63a5\u7ed3\u6784\u53ef\u80fd\u4e3a\u7a7a\uff09\u3002\u8fd9\u4e2a\u51fd\u6570\u80fd\u591f\u8fd4\u56de\u4fee\u6539\u4e4b\u540e\u7684\u94fe\u63a5\u7ed3\u6784\u3002\u5982\u679c\u4f20\u9012\u7684\u4f4d\u7f6e\u5927\u4e8e\u6216\u7b49\u4e8e\u94fe\u63a5\u7ed3\u6784\u7684\u957f\u5ea6\uff0c\u90a3\u4e48\u8fd9\u4e2a\u51fd\u6570\u4f1a\u628a\u5143\u7d20\u63d2\u5165\u5b83\u7684\u672b\u5c3e\u3002\u8fd9\u4e2a\u51fd\u6570\u7684\u8c03\u7528\u793a\u4f8b\u662f head =insert(1,data,head) \uff0c\u5176\u4e2d head \u662f\u4e00\u4e2a\u53d8\u91cf\uff0c\u8fd9\u4e2a\u53d8\u91cf\u8981\u4e48\u4e3a\u7a7a\u94fe\u63a5\uff0c\u8981\u4e48\u6307\u5411\u94fe\u63a5\u7ed3\u6784\u7684\u7b2c\u4e00\u4e2a\u8282\u70b9\u3002 10\uff0e\u5b9a\u4e49\u4e00\u4e2a\u53eb\u4f5c pop \u7684\u51fd\u6570\uff0c\u8fd9\u4e2a\u51fd\u6570\u80fd\u591f\u5728\u5355\u5411\u94fe\u63a5\u7ed3\u6784\u7684\u6307\u5b9a\u4f4d\u7f6e\u4e0a\u5220\u9664\u5143\u7d20\u3002\u8fd9\u4e2a\u51fd\u6570\u7684\u7b2c\u4e00\u4e2a\u53c2\u6570\u662f\u4f4d\u7f6e\uff0c\u5b83\u7684\u5148\u9a8c\u6761\u4ef6\u662f 0<=position<\u7ed3\u6784\u7684\u957f\u5ea6 \u3002\u5b83\u7684\u7b2c\u4e8c\u4e2a\u53c2\u6570\u662f\u4e00\u4e2a\u94fe\u63a5\u7ed3\u6784\uff0c\u5f88\u660e\u663e\u5b83\u4e0d\u5e94\u8be5\u4e3a\u7a7a\u3002\u8fd9\u4e2a\u51fd\u6570\u5c06\u4f1a\u8fd4\u56de\u4e00\u4e2a\u5143\u7ec4\uff0c\u5305\u542b\u4fee\u6539\u540e\u7684\u94fe\u63a5\u7ed3\u6784\u548c\u5220\u9664\u7684\u5143\u7d20\u3002\u5b83\u7684\u8c03\u7528\u793a\u4f8b\u662f (head, item) = pop(1,head) \u3002 11\uff0e\u5b9a\u4e49\u4e00\u4e2a\u51fd\u6570 makeTwoWay \uff0c\u8fd9\u4e2a\u51fd\u6570\u4f1a\u63a5\u53d7\u4e00\u4e2a\u5355\u5411\u94fe\u63a5\u7ed3\u6784\u4f5c\u4e3a\u53c2\u6570\uff0c\u7136\u540e\u751f\u6210\u5e76\u8fd4\u56de\u4e00\u4e2a\u5305\u542b\u5355\u5411\u94fe\u63a5\u7ed3\u6784\u91cc\u7684\u5143\u7d20\u7684\u53cc\u5411\u94fe\u63a5\u7ed3\u6784\u3002\uff08\u6ce8\u610f\uff1a\u8fd9\u4e2a\u51fd\u6570\u4e0d\u5e94\u8be5\u5bf9\u4f5c\u4e3a\u53c2\u6570\u7684\u94fe\u63a5\u7ed3\u6784\u8fdb\u884c\u4efb\u4f55\u4fee\u6539\u3002\uff09","title":"4.9.\u7f16\u7a0b\u7ec3\u4e60"},{"location":"python/DataStructure/05_InterfacePolymorphism/","text":"5.\u63a5\u53e3\u3001\u5b9e\u73b0\u548c\u591a\u6001 \u00b6 \u76ee\u6807\uff1a \u4e3a\u7ed9\u5b9a\u7684\u591a\u9879\u96c6\u7c7b\u578b\u5f00\u53d1\u63a5\u53e3\uff1b \u6309\u7167\u591a\u9879\u96c6\u7c7b\u578b\u7684\u63a5\u53e3\u5b9e\u73b0\u591a\u4e2a\u7c7b\uff1b \u5bf9\u7ed9\u5b9a\u591a\u9879\u96c6\u7c7b\u578b\u7684\u4e0d\u540c\u5b9e\u73b0\u8bc4\u4f30\u8fd0\u884c\u65f6\u548c\u5185\u5b58\u4f7f\u7528\u60c5\u51b5\u7684\u6743\u8861\uff1b \u5b9e\u73b0\u4e00\u4e2a\u7b80\u5355\u7684\u8fed\u4ee3\u5668\uff1b \u4f7f\u7528\u65b9\u6cd5\u5bf9\u5305\u548c\u96c6\u5408\u8fdb\u884c\u64cd\u4f5c\uff1b \u5224\u65ad\u5305\u6216\u96c6\u5408\u662f\u5426\u9002\u5408\u5728\u7ed9\u5b9a\u7684\u5e94\u7528\u7a0b\u5e8f\u91cc\u4f7f\u7528\uff1b \u5c06\u5305\u7684\u5b9e\u73b0\u8f6c\u6362\u6210\u6709\u5e8f\u5305\u7684\u5b9e\u73b0\u3002 5.1.\u5f00\u53d1\u63a5\u53e3 \u00b6 5.1.1.\u8bbe\u8ba1\u5305\u63a5\u53e3 \u00b6 5.1.2.\u6307\u5b9a\u53c2\u6570\u548c\u8fd4\u56de\u503c \u00b6 5.2.\u6784\u9020\u51fd\u6570\u548c\u7c7b\u7684\u5b9e\u73b0 \u00b6 5.2.1.\u524d\u7f6e\u6761\u4ef6\u3001\u540e\u7f6e\u6761\u4ef6\u3001\u5f02\u5e38\u548c\u6587\u6863 \u00b6 5.2.2.\u5728Python\u91cc\u7f16\u5199\u63a5\u53e3 \u00b6 \u7ec3\u4e60\u9898 1\uff0e\u5305\u91cc\u7684\u5143\u7d20\u662f\u6709\u5e8f\u7684\uff0c\u8fd8\u662f\u65e0\u5e8f\u7684\uff1f 2\uff0e\u54ea\u4e9b\u64cd\u4f5c\u4f1a\u51fa\u73b0\u5728\u6240\u6709\u591a\u9879\u96c6\u7684\u63a5\u53e3\u91cc\uff1f 3\uff0e\u54ea\u4e2a\u65b9\u6cd5\u8d1f\u8d23\u521b\u5efa\u591a\u9879\u96c6\u5bf9\u8c61\uff1f 4\uff0e\u8bf7\u8bf4\u51fa\u63a5\u53e3\u4e0e\u5b9e\u73b0\u5206\u79bb\u76843\u4e2a\u539f\u56e0\u3002 5.3.\u5f00\u53d1\u57fa\u4e8e\u6570\u7ec4\u7684\u5b9e\u73b0 \u00b6 5.3.1.\u9009\u62e9\u5e76\u521d\u59cb\u5316\u6570\u636e\u7ed3\u6784 \u00b6 5.3.2.\u5148\u5b8c\u6210\u7b80\u5355\u7684\u65b9\u6cd5 \u00b6 5.3.3.\u5b8c\u6210\u8fed\u4ee3\u5668 \u00b6 5.3.4.\u5b8c\u6210\u4f7f\u7528\u8fed\u4ee3\u5668\u7684\u65b9\u6cd5 \u00b6 5.3.5.in\u8fd0\u7b97\u7b26\u548c__contains__\u65b9\u6cd5 \u00b6 5.3.6.\u5b8c\u6210remove\u65b9\u6cd5 \u00b6 5.3.7.\u7ec3\u4e60\u9898 \u00b6 1\uff0e\u89e3\u91ca\u591a\u9879\u96c6\u7c7b\u7684__init__\u65b9\u6cd5\u7684\u4f5c\u7528\u3002 2\uff0e\u4e3a\u4ec0\u4e48\u8c03\u7528\u65b9\u6cd5\u6bd4\u76f4\u63a5\u5728\u7c7b\u91cc\u5f15\u7528\u5b9e\u4f8b\u53d8\u91cf\u66f4\u597d\uff1f 3\uff0e\u5bf9\u4e8eArrayBag\u7684__init__\u65b9\u6cd5\uff0c\u5c55\u793a\u5982\u4f55\u901a\u8fc7\u8c03\u7528clear\u65b9\u6cd5\u6765\u7b80\u5316\u4ee3\u7801\u3002 4\uff0e\u89e3\u91ca\u4e3a\u4ec0\u4e48__iter__\u65b9\u6cd5\u53ef\u80fd\u4f1a\u662f\u591a\u9879\u96c6\u7c7b\u91cc\u6700\u6709\u7528\u7684\u65b9\u6cd5\u3002 5\uff0e\u89e3\u91ca\u4e3a\u4ec0\u4e48\u5728ArrayBag\u7c7b\u4e2d\u4e0d\u7528\u5305\u542b__contains__\u65b9\u6cd5\u3002 5.4.\u5f00\u53d1\u57fa\u4e8e\u94fe\u63a5\u7684\u5b9e\u73b0 \u00b6 5.4.1.\u521d\u59cb\u5316\u6570\u636e\u7ed3\u6784 \u00b6 5.4.2.\u5b8c\u6210\u8fed\u4ee3\u5668 \u00b6 5.4.3.\u5b8c\u6210clear\u548cadd\u65b9\u6cd5 \u00b6 5.4.4.\u5b8c\u6210remove\u65b9\u6cd5 \u00b6 5.4.5.\u7ec3\u4e60\u9898 \u00b6 1\uff0e\u5047\u8bbea\u662f\u4e00\u4e2a\u6570\u7ec4\u5305\uff0cb\u662f\u4e00\u4e2a\u94fe\u63a5\u5305\uff0c\u5b83\u4eec\u90fd\u4e0d\u5305\u542b\u4efb\u4f55\u5143\u7d20\u3002\u8bf7\u63cf\u8ff0\u5728\u8fd9\u79cd\u60c5\u51b5\u4e0b\u5b83\u4eec\u5728\u5185\u5b58\u4f7f\u7528\u4e0a\u7684\u5dee\u5f02\u3002 2\uff0e\u4e3a\u4ec0\u4e48\u94fe\u63a5\u5305\u4ecd\u7136\u9700\u8981\u4e00\u4e2a\u5355\u72ec\u7684\u5b9e\u4f8b\u53d8\u91cf\u6765\u8bb0\u5f55\u5b83\u7684\u903b\u8f91\u5c3a\u5bf8\uff1f 3\uff0e\u4e3a\u4ec0\u4e48\u4ece\u94fe\u63a5\u5305\u91cc\u5220\u9664\u5143\u7d20\u4e4b\u540e\uff0c\u7a0b\u5e8f\u5458\u4e0d\u7528\u62c5\u5fc3\u51fa\u73b0\u5185\u5b58\u6d6a\u8d39\u7684\u60c5\u51b5\uff1f 5.5.\u4e24\u79cd\u5305\u5b9e\u73b0\u7684\u8fd0\u884c\u65f6\u6027\u80fd \u00b6 5.6.\u6d4b\u8bd5\u5305\u7684\u4e24\u79cd\u5b9e\u73b0 \u00b6 5.7.\u4f7f\u7528UML\u7ed8\u5236\u5305\u8d44\u6e90 \u00b6 5.8.\u5c0f\u7ed3 \u00b6 \u63a5\u53e3\u662f\u7528\u6237\u7684\u8f6f\u4ef6\u8d44\u6e90\u53ef\u4ee5\u4f7f\u7528\u7684\u4e00\u7ec4\u64cd\u4f5c\u3002 \u63a5\u53e3\u91cc\u7684\u5143\u7d20\u662f\u51fd\u6570\u548c\u65b9\u6cd5\u7684\u5b9a\u4e49\u4ee5\u53ca\u5b83\u4eec\u7684\u6587\u6863\u3002 \u524d\u7f6e\u6761\u4ef6\u662f\u6307\u5728\u51fd\u6570\u6216\u65b9\u6cd5\u53ef\u4ee5\u6b63\u786e\u5b8c\u6210\u4efb\u52a1\u4e4b\u524d\u5fc5\u987b\u8981\u6ee1\u8db3\u7684\u6761\u4ef6\u3002 \u540e\u7f6e\u6761\u4ef6\u662f\u6307\u5728\u51fd\u6570\u6216\u65b9\u6cd5\u6b63\u786e\u5b8c\u6210\u4efb\u52a1\u4e4b\u540e\u5fc5\u987b\u4e3a\u771f\u7684\u6761\u4ef6\u3002 \u8bbe\u8ba1\u826f\u597d\u7684\u8f6f\u4ef6\u7cfb\u7edf\u4f1a\u628a\u63a5\u53e3\u548c\u5b83\u7684\u5b9e\u73b0\u5206\u5f00\u3002 \u5b9e\u73b0\u662f\u6307\u6ee1\u8db3\u63a5\u53e3\u7684\u51fd\u6570\u3001\u65b9\u6cd5\u6216\u7c7b\u3002 \u591a\u9879\u96c6\u7c7b\u578b\u53ef\u4ee5\u901a\u8fc7\u63a5\u53e3\u8fdb\u884c\u6307\u5b9a\u3002 \u591a\u9879\u96c6\u7c7b\u578b\u53ef\u4ee5\u6709\u51e0\u4e2a\u4e0d\u540c\u7684\u5b9e\u73b0\u7c7b\u3002 \u591a\u6001\u662f\u6307\u5728\u4e24\u4e2a\u6216\u591a\u4e2a\u5b9e\u73b0\u91cc\u4f7f\u7528\u76f8\u540c\u7684\u8fd0\u7b97\u7b26\u3001\u51fd\u6570\u540d\u79f0\u6216\u65b9\u6cd5\u540d\u79f0\u3002\u591a\u6001\u51fd\u6570\u7684\u793a\u4f8b\u662f str \u548c len \uff1b\u591a\u6001\u8fd0\u7b97\u7b26\u7684\u793a\u4f8b\u662f + \u548c == \uff1b\u591a\u6001\u65b9\u6cd5\u7684\u793a\u4f8b\u5305\u62ecadd\u548c isEmpty \u3002 \u5305\u591a\u9879\u96c6\u7c7b\u578b\u662f\u65e0\u5e8f\u7684\uff0c\u5e76\u4e14\u652f\u6301\u6dfb\u52a0\u3001\u5220\u9664\u548c\u8bbf\u95ee\u5176\u5143\u7d20\u7b49\u64cd\u4f5c\u3002 \u7c7b\u56fe\u662f\u4e00\u79cd\u63cf\u8ff0\u7c7b\u4e0e\u7c7b\u4e4b\u95f4\u5173\u7cfb\u7684\u53ef\u89c6\u5316\u8868\u793a\u65b9\u6cd5\u3002 \u7ec4\u5408\u8868\u793a\u4e24\u4e2a\u7c7b\u4e4b\u95f4\u6574\u4f53\u4e0e\u5c40\u90e8\u7684\u5173\u7cfb\u3002 \u805a\u5408\u8868\u793a\u4e24\u4e2a\u7c7b\u4e4b\u95f4\u4e00\u5bf9\u591a\u7684\u5173\u7cfb\u3002 UML\u662f\u4e00\u79cd\u63cf\u8ff0\u8f6f\u4ef6\u8d44\u6e90\u4e4b\u95f4\u5173\u7cfb\u7684\u53ef\u89c6\u5316\u8868\u793a\u65b9\u6cd5\u3002 5.9.\u590d\u4e60\u9898 \u00b6 1\uff0e\u5305\u662f\uff1a \u7ebf\u6027\u591a\u9879\u96c6 \u65e0\u5e8f\u591a\u9879\u96c6 2\uff0e\u7528\u6765\u8bbe\u7f6e\u5bf9\u8c61\u5b9e\u4f8b\u53d8\u91cf\u7684\u521d\u59cb\u72b6\u6001\u7684\u65b9\u6cd5\u662f\uff1a __init__ \u65b9\u6cd5 __str__ \u65b9\u6cd5 3\uff0e\u8ba9\u7a0b\u5e8f\u5458\u53ef\u4ee5\u8bbf\u95ee\u591a\u9879\u96c6\u91cc\u6240\u6709\u5143\u7d20\u7684\u65b9\u6cd5\u662f\uff1a __init__ \u65b9\u6cd5 __iter__ \u65b9\u6cd5 4\uff0e\u6539\u53d8\u5bf9\u8c61\u5185\u90e8\u72b6\u6001\u7684\u65b9\u6cd5\u662f\uff1a \u8bbf\u95ee\u5668\u65b9\u6cd5 \u53d8\u5f02\u5668\u65b9\u6cd5 5\uff0e\u4e00\u7ec4\u53ef\u4ee5\u88ab\u7c7b\u7684\u5ba2\u6237\u7aef\u4f7f\u7528\u7684\u65b9\u6cd5\u96c6\u79f0\u4e3a\uff1a \u5b9e\u73b0 \u63a5\u53e3 6\uff0e\u591a\u6001\u7528\u6765\u4ee3\u8868\u7684\u672f\u8bed\u662f\uff1a \u591a\u4e2a\u7c7b\u91cc\u76f8\u540c\u7684\u65b9\u6cd5\u540d\u79f0 \u7528\u6765\u5b58\u50a8\u53e6\u4e00\u4e2a\u7c7b\u91cc\u6240\u5305\u542b\u6570\u636e\u7684\u7c7b 7\uff0e\u7ec4\u5408\u662f\u6307\uff1a \u4e24\u4e2a\u7c7b\u4e4b\u95f4\u90e8\u5206\u4e0e\u6574\u4f53\u5173\u7cfb \u4e24\u4e2a\u7c7b\u4e4b\u95f4\u591a\u5bf9\u4e00\u5173\u7cfb 8\uff0e\u5305\u4e2dadd\u65b9\u6cd5\u7684\u5e73\u5747\u8fd0\u884c\u65f6\u4e3a\uff1a O(n) O(k) 9\uff0e\u5305\u4e2dremove\u65b9\u6cd5\u7684\u5e73\u5747\u8fd0\u884c\u65f6\u4e3a\uff1a O(n) O(k) 10\uff0e\u5728\u4ec0\u4e48\u60c5\u51b5\u4e0b\uff0c\u6570\u7ec4\u5305\u5b9e\u73b0\u4f1a\u6bd4\u94fe\u63a5\u5305\u5b9e\u73b0\u4f7f\u7528\u66f4\u5c11\u7684\u5185\u5b58\uff1a \u542b\u6709\u5c11\u4e8e\u4e00\u534a\u7684\u6570\u636e \u542b\u6709\u4e00\u534a\u4ee5\u4e0a\u7684\u6570\u636e 5.10.\u7f16\u7a0b\u7ec3\u4e60 \u00b6 1\uff0e\u5bf9\u4e8e\u4e24\u4e2a\u5305\u5b9e\u73b0\uff0c\u786e\u5b9a == \u64cd\u4f5c\u7684\u8fd0\u884c\u65f6\u3002\u53ef\u4ee5\u9884\u89c1\u5230\uff0c\u8fd9\u91cc\u6709\u51e0\u79cd\u60c5\u51b5\u9700\u8981\u5206\u6790\u3002 2\uff0e\u5bf9\u4e8e\u5305\u7684\u4e24\u4e2a\u5b9e\u73b0\uff0c\u786e\u5b9a + \u8fd0\u7b97\u7b26\u7684\u8fd0\u884c\u65f6\u3002 3\uff0e\u7f16\u7801 ArrayBag \u91cc add \u65b9\u6cd5\u7684\u4ee3\u7801\uff0c\u4ece\u800c\u53ef\u4ee5\u5728\u9700\u8981\u7684\u65f6\u5019\u5bf9\u6570\u7ec4\u5c3a\u5bf8\u8fdb\u884c\u8c03\u6574\u3002 4\uff0e\u7f16\u7801 ArrayBag \u91cc remove \u65b9\u6cd5\u7684\u4ee3\u7801\uff0c\u4ece\u800c\u53ef\u4ee5\u5728\u9700\u8981\u7684\u65f6\u5019\u5bf9\u6570\u7ec4\u5c3a\u5bf8\u8fdb\u884c\u8c03\u6574\u3002 5\uff0e\u5728 ArrayBag \u548c LinkedBag \u7c7b\u91cc\u6dfb\u52a0 clone \u65b9\u6cd5\u3002\u8fd9\u4e2a\u65b9\u6cd5\u5728\u8c03\u7528\u7684\u65f6\u5019\uff0c\u4e0d\u4f1a\u63a5\u6536\u4efb\u4f55\u53c2\u6570\uff0c\u5e76\u4e14\u4f1a\u8fd4\u56de\u5f53\u524d\u5305\u7c7b\u578b\u7684\u4e00\u4e2a\u5b8c\u6574\u526f\u672c\u3002\u5728\u4e0b\u9762\u8fd9\u6bb5\u4ee3\u7801\u7684\u6700\u540e\uff0c\u53d8\u91cf bag2 \u5c06\u5305\u542b\u6570\u5b57 2 \u3001 3 \u548c 4 \u3002 bag1 = ArrayBag ([ 2 , 3 , 4 ]) bag2 = bag1 . clone () bag1 == bag2 # Returns True bag1 is bag2 # Returns False 6\uff0e\u96c6\u5408\u662f\u4e00\u4e2a\u65e0\u5e8f\u591a\u9879\u96c6\uff0c\u5e76\u4e14\u548c\u5305\u5177\u6709\u76f8\u540c\u7684\u63a5\u53e3\u3002\u4f46\u662f\u5728\u96c6\u5408\u91cc\uff0c\u5143\u7d20\u662f\u552f\u4e00\u7684\uff0c\u800c\u5305\u91cc\u53ef\u4ee5\u5305\u542b\u91cd\u590d\u7684\u7269\u54c1\u3002\u5b9a\u4e49\u4e00\u4e2a\u57fa\u4e8e\u6570\u7ec4\u7684\u53eb\u4f5c ArraySet \u7684\u591a\u9879\u96c6\u65b0\u7c7b\u3002\u5982\u679c\u96c6\u5408\u91cc\u7684\u5143\u7d20\u5df2\u7ecf\u5b58\u5728\u4e86\uff0c\u90a3\u4e48 add \u65b9\u6cd5\u5c06\u4f1a\u5ffd\u7565\u8fd9\u4e2a\u5143\u7d20\u3002 7\uff0e\u4f7f\u7528\u94fe\u63a5\u8282\u70b9\u5b9a\u4e49\u4e00\u4e2a\u53eb\u4f5c LinkedSet \u7684\u591a\u9879\u96c6\u65b0\u7c7b\u6765\u5b9e\u73b0\u96c6\u5408\u7c7b\u578b\u3002\u5982\u679c\u96c6\u5408\u91cc\u7684\u5143\u7d20\u5df2\u7ecf\u5b58\u5728\u4e86\uff0c\u90a3\u4e48 add \u65b9\u6cd5\u5c06\u4f1a\u5ffd\u7565\u8fd9\u4e2a\u5143\u7d20\u3002 8\uff0e\u6709\u5e8f\u5305\u7684\u884c\u4e3a\u548c\u666e\u901a\u5305\u7684\u662f\u4e00\u6837\u7684\uff0c\u4f46\u662f\u5b83\u80fd\u591f\u8ba9\u7528\u6237\u5728\u4f7f\u7528 for \u5faa\u73af\u65f6\u6309\u7167\u5347\u5e8f\u8bbf\u95ee\u91cc\u9762\u7684\u5143\u7d20\u3002\u56e0\u6b64\uff0c\u6dfb\u52a0\u5230\u8fd9\u4e2a\u5305\u7c7b\u578b\u91cc\u7684\u5143\u7d20\uff0c\u90fd\u5fc5\u987b\u5177\u6709\u4e00\u5b9a\u7684\u987a\u5e8f\u5e76\u4e14\u652f\u6301\u6bd4\u8f83\u8fd0\u7b97\u7b26\u3002\u8fd9\u79cd\u7c7b\u578b\u5143\u7d20\u7684\u7b80\u5355\u4f8b\u5b50\u662f\uff1a\u5b57\u7b26\u4e32\u548c\u6574\u6570\u3002\u5b9a\u4e49\u4e00\u4e2a\u652f\u6301\u8fd9\u4e2a\u529f\u80fd\u7684\u53eb\u4f5c ArraySortedBag \u7684\u65b0\u7c7b\u3002\u548c ArrayBag \u4e00\u6837\uff0c\u8fd9\u4e2a\u65b0\u7c7b\u4f1a\u57fa\u4e8e\u6570\u7ec4\uff0c\u4f46\u662f\u5b83\u7684 in \u64cd\u4f5c\u73b0\u5728\u53ef\u4ee5\u5728\u5bf9\u6570\u65f6\u95f4\u91cc\u8fd0\u884c\u3002\u8981\u5b8c\u6210\u8fd9\u4e00\u70b9\uff0c ArraySortedBag \u5fc5\u987b\u5c06\u65b0\u6dfb\u52a0\u7684\u5143\u7d20\u6309\u7167\u987a\u5e8f\u653e\u5230\u6570\u7ec4\u91cc\u3002\u6700\u7b80\u5355\u7684\u529e\u6cd5\u662f\u4fee\u6539 add \u65b9\u6cd5\uff0c\u4ece\u800c\u8ba9\u65b0\u5143\u7d20\u63d2\u5165\u9002\u5f53\u7684\u4f4d\u7f6e\uff1b\u7136\u540e\uff0c\u6dfb\u52a0_ _contains__ \u65b9\u6cd5\u6765\u63d0\u4f9b\u65b0\u7684\u4e14\u66f4\u6709\u6548\u7684\u641c\u7d22\uff1b\u6700\u540e\uff0c\u8981\u628a\u5bf9 ArrayBag \u7684\u6240\u6709\u5f15\u7528\u90fd\u66ff\u6362\u4e3a ArraySortedBag \u3002\uff08\u63d0\u793a\uff1a\u628a\u4ee3\u7801\u4ece ArrayBag \u7c7b\u4e2d\u590d\u5236\u5230\u4e00\u4e2a\u65b0\u6587\u4ef6\u91cc\uff0c\u7136\u540e\u5728\u8fd9\u4e2a\u65b0\u6587\u4ef6\u91cc\u5f00\u59cb\u4fee\u6539\u3002\uff09 9\uff0e\u786e\u5b9a ArraySortedBag \u91cc add \u65b9\u6cd5\u7684\u8fd0\u884c\u65f6\u3002 10\uff0ePython\u7684 for \u5faa\u73af\u53ef\u4ee5\u8ba9\u7a0b\u5e8f\u5458\u5728\u5faa\u73af\u8fed\u4ee3\u591a\u9879\u96c6\u7684\u65f6\u5019\u5bf9\u5b83\u6267\u884c\u6dfb\u52a0\u6216\u5220\u9664\u5143\u7d20\u7684\u64cd\u4f5c\u3002\u4e00\u4e9b\u8bbe\u8ba1\u4eba\u5458\u62c5\u5fc3\u5728\u8fed\u4ee3\u8fc7\u7a0b\u4e2d\u5bf9\u591a\u9879\u96c6\u7684\u7ed3\u6784\u8fdb\u884c\u4fee\u6539\u53ef\u80fd\u4f1a\u5bfc\u81f4\u7a0b\u5e8f\u5d29\u6e83\u3002\u6709\u4e00\u79cd\u4fee\u6539\u7b56\u7565\u662f\u901a\u8fc7\u7981\u6b62\u5728\u8fed\u4ee3\u671f\u95f4\u5bf9\u591a\u9879\u96c6\u8fdb\u884c\u53d8\u5f02\u6765\u8ba9 for \u5faa\u73af\u6210\u4e3a\u53ea\u8bfb\u3002\u4f60\u53ef\u4ee5\u901a\u8fc7\u5bf9\u53d8\u5f02\u64cd\u4f5c\u8fdb\u884c\u8ba1\u6570\uff0c\u5e76\u4e14\u5224\u65ad\u8fd9\u4e2a\u8ba1\u6570\u6709\u6ca1\u6709\u5728\u591a\u9879\u96c6\u7684 __iter__ \u65b9\u6cd5\u7684\u4efb\u610f\u8282\u62cd\u4e2d\u88ab\u589e\u52a0\u6765\u68c0\u6d4b\u8fd9\u79cd\u7c7b\u578b\u7684\u53d8\u5f02\u3002\u5f53\u53d1\u751f\u8fd9\u79cd\u60c5\u51b5\u65f6\uff0c\u5c31\u53ef\u4ee5\u5f15\u53d1\u5f02\u5e38\u4ece\u800c\u907f\u514d\u8ba1\u7b97\u7684\u7ee7\u7eed\u8fdb\u884c\u3002\u628a\u8fd9\u4e2a\u673a\u5236\u6dfb\u52a0\u5230 ArrayBag \u7c7b\u91cc\u3002\u53ef\u4ee5\u6dfb\u52a0\u4e00\u4e2a\u53eb\u4f5c modCount \u7684\u65b0\u5b9e\u4f8b\u53d8\u91cf\uff0c\u8fd9\u4e2a\u5b9e\u4f8b\u53d8\u91cf\u4f1a\u5728 __init__ \u65b9\u6cd5\u91cc\u8bbe\u7f6e\u4e3a 0 \uff1b\u7136\u540e\uff0c\u6bcf\u4e2a\u53d8\u5f02\u5668\u65b9\u6cd5\u90fd\u4f1a\u9012\u589e\u8fd9\u4e2a\u53d8\u91cf\uff1b\u6700\u540e\uff0c __iter__ \u65b9\u6cd5\u6709\u4e00\u4e2a\u53eb\u4f5c modCount \u7684\u4e34\u65f6\u53d8\u91cf\uff0c\u8fd9\u4e2a\u4e34\u65f6\u53d8\u91cf\u7684\u521d\u59cb\u503c\u662f\u5b9e\u4f8b\u53d8\u91cf self.modCount \u7684\u503c\u3002\u5728 __iter__ \u65b9\u6cd5\u91cc\u8fd4\u56de\u4e00\u4e2a\u5143\u7d20\u540e\uff0c\u5982\u679c\u8fd9\u4e24\u4e2a\u4fee\u6539\u8fc7\u7684\u8ba1\u6570\u5668\u503c\u4e0d\u76f8\u7b49\uff0c\u5c31\u7acb\u5373\u5f15\u53d1\u5f02\u5e38\u3002\u7528\u4e00\u4e2a\u7a0b\u5e8f\u6765\u6d4b\u8bd5\u4f60\u7684\u4fee\u6539\uff0c\u4ece\u800c\u4fdd\u8bc1\u6ee1\u8db3\u76f8\u5e94\u7684\u9700\u6c42\u3002","title":"\u63a5\u53e3\u3001\u5b9e\u73b0\u548c\u591a\u6001"},{"location":"python/DataStructure/05_InterfacePolymorphism/#5","text":"\u76ee\u6807\uff1a \u4e3a\u7ed9\u5b9a\u7684\u591a\u9879\u96c6\u7c7b\u578b\u5f00\u53d1\u63a5\u53e3\uff1b \u6309\u7167\u591a\u9879\u96c6\u7c7b\u578b\u7684\u63a5\u53e3\u5b9e\u73b0\u591a\u4e2a\u7c7b\uff1b \u5bf9\u7ed9\u5b9a\u591a\u9879\u96c6\u7c7b\u578b\u7684\u4e0d\u540c\u5b9e\u73b0\u8bc4\u4f30\u8fd0\u884c\u65f6\u548c\u5185\u5b58\u4f7f\u7528\u60c5\u51b5\u7684\u6743\u8861\uff1b \u5b9e\u73b0\u4e00\u4e2a\u7b80\u5355\u7684\u8fed\u4ee3\u5668\uff1b \u4f7f\u7528\u65b9\u6cd5\u5bf9\u5305\u548c\u96c6\u5408\u8fdb\u884c\u64cd\u4f5c\uff1b \u5224\u65ad\u5305\u6216\u96c6\u5408\u662f\u5426\u9002\u5408\u5728\u7ed9\u5b9a\u7684\u5e94\u7528\u7a0b\u5e8f\u91cc\u4f7f\u7528\uff1b \u5c06\u5305\u7684\u5b9e\u73b0\u8f6c\u6362\u6210\u6709\u5e8f\u5305\u7684\u5b9e\u73b0\u3002","title":"5.\u63a5\u53e3\u3001\u5b9e\u73b0\u548c\u591a\u6001"},{"location":"python/DataStructure/05_InterfacePolymorphism/#51","text":"","title":"5.1.\u5f00\u53d1\u63a5\u53e3"},{"location":"python/DataStructure/05_InterfacePolymorphism/#511","text":"","title":"5.1.1.\u8bbe\u8ba1\u5305\u63a5\u53e3"},{"location":"python/DataStructure/05_InterfacePolymorphism/#512","text":"","title":"5.1.2.\u6307\u5b9a\u53c2\u6570\u548c\u8fd4\u56de\u503c"},{"location":"python/DataStructure/05_InterfacePolymorphism/#52","text":"","title":"5.2.\u6784\u9020\u51fd\u6570\u548c\u7c7b\u7684\u5b9e\u73b0"},{"location":"python/DataStructure/05_InterfacePolymorphism/#521","text":"","title":"5.2.1.\u524d\u7f6e\u6761\u4ef6\u3001\u540e\u7f6e\u6761\u4ef6\u3001\u5f02\u5e38\u548c\u6587\u6863"},{"location":"python/DataStructure/05_InterfacePolymorphism/#522python","text":"\u7ec3\u4e60\u9898 1\uff0e\u5305\u91cc\u7684\u5143\u7d20\u662f\u6709\u5e8f\u7684\uff0c\u8fd8\u662f\u65e0\u5e8f\u7684\uff1f 2\uff0e\u54ea\u4e9b\u64cd\u4f5c\u4f1a\u51fa\u73b0\u5728\u6240\u6709\u591a\u9879\u96c6\u7684\u63a5\u53e3\u91cc\uff1f 3\uff0e\u54ea\u4e2a\u65b9\u6cd5\u8d1f\u8d23\u521b\u5efa\u591a\u9879\u96c6\u5bf9\u8c61\uff1f 4\uff0e\u8bf7\u8bf4\u51fa\u63a5\u53e3\u4e0e\u5b9e\u73b0\u5206\u79bb\u76843\u4e2a\u539f\u56e0\u3002","title":"5.2.2.\u5728Python\u91cc\u7f16\u5199\u63a5\u53e3"},{"location":"python/DataStructure/05_InterfacePolymorphism/#53","text":"","title":"5.3.\u5f00\u53d1\u57fa\u4e8e\u6570\u7ec4\u7684\u5b9e\u73b0"},{"location":"python/DataStructure/05_InterfacePolymorphism/#531","text":"","title":"5.3.1.\u9009\u62e9\u5e76\u521d\u59cb\u5316\u6570\u636e\u7ed3\u6784"},{"location":"python/DataStructure/05_InterfacePolymorphism/#532","text":"","title":"5.3.2.\u5148\u5b8c\u6210\u7b80\u5355\u7684\u65b9\u6cd5"},{"location":"python/DataStructure/05_InterfacePolymorphism/#533","text":"","title":"5.3.3.\u5b8c\u6210\u8fed\u4ee3\u5668"},{"location":"python/DataStructure/05_InterfacePolymorphism/#534","text":"","title":"5.3.4.\u5b8c\u6210\u4f7f\u7528\u8fed\u4ee3\u5668\u7684\u65b9\u6cd5"},{"location":"python/DataStructure/05_InterfacePolymorphism/#535in__contains__","text":"","title":"5.3.5.in\u8fd0\u7b97\u7b26\u548c__contains__\u65b9\u6cd5"},{"location":"python/DataStructure/05_InterfacePolymorphism/#536remove","text":"","title":"5.3.6.\u5b8c\u6210remove\u65b9\u6cd5"},{"location":"python/DataStructure/05_InterfacePolymorphism/#537","text":"1\uff0e\u89e3\u91ca\u591a\u9879\u96c6\u7c7b\u7684__init__\u65b9\u6cd5\u7684\u4f5c\u7528\u3002 2\uff0e\u4e3a\u4ec0\u4e48\u8c03\u7528\u65b9\u6cd5\u6bd4\u76f4\u63a5\u5728\u7c7b\u91cc\u5f15\u7528\u5b9e\u4f8b\u53d8\u91cf\u66f4\u597d\uff1f 3\uff0e\u5bf9\u4e8eArrayBag\u7684__init__\u65b9\u6cd5\uff0c\u5c55\u793a\u5982\u4f55\u901a\u8fc7\u8c03\u7528clear\u65b9\u6cd5\u6765\u7b80\u5316\u4ee3\u7801\u3002 4\uff0e\u89e3\u91ca\u4e3a\u4ec0\u4e48__iter__\u65b9\u6cd5\u53ef\u80fd\u4f1a\u662f\u591a\u9879\u96c6\u7c7b\u91cc\u6700\u6709\u7528\u7684\u65b9\u6cd5\u3002 5\uff0e\u89e3\u91ca\u4e3a\u4ec0\u4e48\u5728ArrayBag\u7c7b\u4e2d\u4e0d\u7528\u5305\u542b__contains__\u65b9\u6cd5\u3002","title":"5.3.7.\u7ec3\u4e60\u9898"},{"location":"python/DataStructure/05_InterfacePolymorphism/#54","text":"","title":"5.4.\u5f00\u53d1\u57fa\u4e8e\u94fe\u63a5\u7684\u5b9e\u73b0"},{"location":"python/DataStructure/05_InterfacePolymorphism/#541","text":"","title":"5.4.1.\u521d\u59cb\u5316\u6570\u636e\u7ed3\u6784"},{"location":"python/DataStructure/05_InterfacePolymorphism/#542","text":"","title":"5.4.2.\u5b8c\u6210\u8fed\u4ee3\u5668"},{"location":"python/DataStructure/05_InterfacePolymorphism/#543clearadd","text":"","title":"5.4.3.\u5b8c\u6210clear\u548cadd\u65b9\u6cd5"},{"location":"python/DataStructure/05_InterfacePolymorphism/#544remove","text":"","title":"5.4.4.\u5b8c\u6210remove\u65b9\u6cd5"},{"location":"python/DataStructure/05_InterfacePolymorphism/#545","text":"1\uff0e\u5047\u8bbea\u662f\u4e00\u4e2a\u6570\u7ec4\u5305\uff0cb\u662f\u4e00\u4e2a\u94fe\u63a5\u5305\uff0c\u5b83\u4eec\u90fd\u4e0d\u5305\u542b\u4efb\u4f55\u5143\u7d20\u3002\u8bf7\u63cf\u8ff0\u5728\u8fd9\u79cd\u60c5\u51b5\u4e0b\u5b83\u4eec\u5728\u5185\u5b58\u4f7f\u7528\u4e0a\u7684\u5dee\u5f02\u3002 2\uff0e\u4e3a\u4ec0\u4e48\u94fe\u63a5\u5305\u4ecd\u7136\u9700\u8981\u4e00\u4e2a\u5355\u72ec\u7684\u5b9e\u4f8b\u53d8\u91cf\u6765\u8bb0\u5f55\u5b83\u7684\u903b\u8f91\u5c3a\u5bf8\uff1f 3\uff0e\u4e3a\u4ec0\u4e48\u4ece\u94fe\u63a5\u5305\u91cc\u5220\u9664\u5143\u7d20\u4e4b\u540e\uff0c\u7a0b\u5e8f\u5458\u4e0d\u7528\u62c5\u5fc3\u51fa\u73b0\u5185\u5b58\u6d6a\u8d39\u7684\u60c5\u51b5\uff1f","title":"5.4.5.\u7ec3\u4e60\u9898"},{"location":"python/DataStructure/05_InterfacePolymorphism/#55","text":"","title":"5.5.\u4e24\u79cd\u5305\u5b9e\u73b0\u7684\u8fd0\u884c\u65f6\u6027\u80fd"},{"location":"python/DataStructure/05_InterfacePolymorphism/#56","text":"","title":"5.6.\u6d4b\u8bd5\u5305\u7684\u4e24\u79cd\u5b9e\u73b0"},{"location":"python/DataStructure/05_InterfacePolymorphism/#57uml","text":"","title":"5.7.\u4f7f\u7528UML\u7ed8\u5236\u5305\u8d44\u6e90"},{"location":"python/DataStructure/05_InterfacePolymorphism/#58","text":"\u63a5\u53e3\u662f\u7528\u6237\u7684\u8f6f\u4ef6\u8d44\u6e90\u53ef\u4ee5\u4f7f\u7528\u7684\u4e00\u7ec4\u64cd\u4f5c\u3002 \u63a5\u53e3\u91cc\u7684\u5143\u7d20\u662f\u51fd\u6570\u548c\u65b9\u6cd5\u7684\u5b9a\u4e49\u4ee5\u53ca\u5b83\u4eec\u7684\u6587\u6863\u3002 \u524d\u7f6e\u6761\u4ef6\u662f\u6307\u5728\u51fd\u6570\u6216\u65b9\u6cd5\u53ef\u4ee5\u6b63\u786e\u5b8c\u6210\u4efb\u52a1\u4e4b\u524d\u5fc5\u987b\u8981\u6ee1\u8db3\u7684\u6761\u4ef6\u3002 \u540e\u7f6e\u6761\u4ef6\u662f\u6307\u5728\u51fd\u6570\u6216\u65b9\u6cd5\u6b63\u786e\u5b8c\u6210\u4efb\u52a1\u4e4b\u540e\u5fc5\u987b\u4e3a\u771f\u7684\u6761\u4ef6\u3002 \u8bbe\u8ba1\u826f\u597d\u7684\u8f6f\u4ef6\u7cfb\u7edf\u4f1a\u628a\u63a5\u53e3\u548c\u5b83\u7684\u5b9e\u73b0\u5206\u5f00\u3002 \u5b9e\u73b0\u662f\u6307\u6ee1\u8db3\u63a5\u53e3\u7684\u51fd\u6570\u3001\u65b9\u6cd5\u6216\u7c7b\u3002 \u591a\u9879\u96c6\u7c7b\u578b\u53ef\u4ee5\u901a\u8fc7\u63a5\u53e3\u8fdb\u884c\u6307\u5b9a\u3002 \u591a\u9879\u96c6\u7c7b\u578b\u53ef\u4ee5\u6709\u51e0\u4e2a\u4e0d\u540c\u7684\u5b9e\u73b0\u7c7b\u3002 \u591a\u6001\u662f\u6307\u5728\u4e24\u4e2a\u6216\u591a\u4e2a\u5b9e\u73b0\u91cc\u4f7f\u7528\u76f8\u540c\u7684\u8fd0\u7b97\u7b26\u3001\u51fd\u6570\u540d\u79f0\u6216\u65b9\u6cd5\u540d\u79f0\u3002\u591a\u6001\u51fd\u6570\u7684\u793a\u4f8b\u662f str \u548c len \uff1b\u591a\u6001\u8fd0\u7b97\u7b26\u7684\u793a\u4f8b\u662f + \u548c == \uff1b\u591a\u6001\u65b9\u6cd5\u7684\u793a\u4f8b\u5305\u62ecadd\u548c isEmpty \u3002 \u5305\u591a\u9879\u96c6\u7c7b\u578b\u662f\u65e0\u5e8f\u7684\uff0c\u5e76\u4e14\u652f\u6301\u6dfb\u52a0\u3001\u5220\u9664\u548c\u8bbf\u95ee\u5176\u5143\u7d20\u7b49\u64cd\u4f5c\u3002 \u7c7b\u56fe\u662f\u4e00\u79cd\u63cf\u8ff0\u7c7b\u4e0e\u7c7b\u4e4b\u95f4\u5173\u7cfb\u7684\u53ef\u89c6\u5316\u8868\u793a\u65b9\u6cd5\u3002 \u7ec4\u5408\u8868\u793a\u4e24\u4e2a\u7c7b\u4e4b\u95f4\u6574\u4f53\u4e0e\u5c40\u90e8\u7684\u5173\u7cfb\u3002 \u805a\u5408\u8868\u793a\u4e24\u4e2a\u7c7b\u4e4b\u95f4\u4e00\u5bf9\u591a\u7684\u5173\u7cfb\u3002 UML\u662f\u4e00\u79cd\u63cf\u8ff0\u8f6f\u4ef6\u8d44\u6e90\u4e4b\u95f4\u5173\u7cfb\u7684\u53ef\u89c6\u5316\u8868\u793a\u65b9\u6cd5\u3002","title":"5.8.\u5c0f\u7ed3"},{"location":"python/DataStructure/05_InterfacePolymorphism/#59","text":"1\uff0e\u5305\u662f\uff1a \u7ebf\u6027\u591a\u9879\u96c6 \u65e0\u5e8f\u591a\u9879\u96c6 2\uff0e\u7528\u6765\u8bbe\u7f6e\u5bf9\u8c61\u5b9e\u4f8b\u53d8\u91cf\u7684\u521d\u59cb\u72b6\u6001\u7684\u65b9\u6cd5\u662f\uff1a __init__ \u65b9\u6cd5 __str__ \u65b9\u6cd5 3\uff0e\u8ba9\u7a0b\u5e8f\u5458\u53ef\u4ee5\u8bbf\u95ee\u591a\u9879\u96c6\u91cc\u6240\u6709\u5143\u7d20\u7684\u65b9\u6cd5\u662f\uff1a __init__ \u65b9\u6cd5 __iter__ \u65b9\u6cd5 4\uff0e\u6539\u53d8\u5bf9\u8c61\u5185\u90e8\u72b6\u6001\u7684\u65b9\u6cd5\u662f\uff1a \u8bbf\u95ee\u5668\u65b9\u6cd5 \u53d8\u5f02\u5668\u65b9\u6cd5 5\uff0e\u4e00\u7ec4\u53ef\u4ee5\u88ab\u7c7b\u7684\u5ba2\u6237\u7aef\u4f7f\u7528\u7684\u65b9\u6cd5\u96c6\u79f0\u4e3a\uff1a \u5b9e\u73b0 \u63a5\u53e3 6\uff0e\u591a\u6001\u7528\u6765\u4ee3\u8868\u7684\u672f\u8bed\u662f\uff1a \u591a\u4e2a\u7c7b\u91cc\u76f8\u540c\u7684\u65b9\u6cd5\u540d\u79f0 \u7528\u6765\u5b58\u50a8\u53e6\u4e00\u4e2a\u7c7b\u91cc\u6240\u5305\u542b\u6570\u636e\u7684\u7c7b 7\uff0e\u7ec4\u5408\u662f\u6307\uff1a \u4e24\u4e2a\u7c7b\u4e4b\u95f4\u90e8\u5206\u4e0e\u6574\u4f53\u5173\u7cfb \u4e24\u4e2a\u7c7b\u4e4b\u95f4\u591a\u5bf9\u4e00\u5173\u7cfb 8\uff0e\u5305\u4e2dadd\u65b9\u6cd5\u7684\u5e73\u5747\u8fd0\u884c\u65f6\u4e3a\uff1a O(n) O(k) 9\uff0e\u5305\u4e2dremove\u65b9\u6cd5\u7684\u5e73\u5747\u8fd0\u884c\u65f6\u4e3a\uff1a O(n) O(k) 10\uff0e\u5728\u4ec0\u4e48\u60c5\u51b5\u4e0b\uff0c\u6570\u7ec4\u5305\u5b9e\u73b0\u4f1a\u6bd4\u94fe\u63a5\u5305\u5b9e\u73b0\u4f7f\u7528\u66f4\u5c11\u7684\u5185\u5b58\uff1a \u542b\u6709\u5c11\u4e8e\u4e00\u534a\u7684\u6570\u636e \u542b\u6709\u4e00\u534a\u4ee5\u4e0a\u7684\u6570\u636e","title":"5.9.\u590d\u4e60\u9898"},{"location":"python/DataStructure/05_InterfacePolymorphism/#510","text":"1\uff0e\u5bf9\u4e8e\u4e24\u4e2a\u5305\u5b9e\u73b0\uff0c\u786e\u5b9a == \u64cd\u4f5c\u7684\u8fd0\u884c\u65f6\u3002\u53ef\u4ee5\u9884\u89c1\u5230\uff0c\u8fd9\u91cc\u6709\u51e0\u79cd\u60c5\u51b5\u9700\u8981\u5206\u6790\u3002 2\uff0e\u5bf9\u4e8e\u5305\u7684\u4e24\u4e2a\u5b9e\u73b0\uff0c\u786e\u5b9a + \u8fd0\u7b97\u7b26\u7684\u8fd0\u884c\u65f6\u3002 3\uff0e\u7f16\u7801 ArrayBag \u91cc add \u65b9\u6cd5\u7684\u4ee3\u7801\uff0c\u4ece\u800c\u53ef\u4ee5\u5728\u9700\u8981\u7684\u65f6\u5019\u5bf9\u6570\u7ec4\u5c3a\u5bf8\u8fdb\u884c\u8c03\u6574\u3002 4\uff0e\u7f16\u7801 ArrayBag \u91cc remove \u65b9\u6cd5\u7684\u4ee3\u7801\uff0c\u4ece\u800c\u53ef\u4ee5\u5728\u9700\u8981\u7684\u65f6\u5019\u5bf9\u6570\u7ec4\u5c3a\u5bf8\u8fdb\u884c\u8c03\u6574\u3002 5\uff0e\u5728 ArrayBag \u548c LinkedBag \u7c7b\u91cc\u6dfb\u52a0 clone \u65b9\u6cd5\u3002\u8fd9\u4e2a\u65b9\u6cd5\u5728\u8c03\u7528\u7684\u65f6\u5019\uff0c\u4e0d\u4f1a\u63a5\u6536\u4efb\u4f55\u53c2\u6570\uff0c\u5e76\u4e14\u4f1a\u8fd4\u56de\u5f53\u524d\u5305\u7c7b\u578b\u7684\u4e00\u4e2a\u5b8c\u6574\u526f\u672c\u3002\u5728\u4e0b\u9762\u8fd9\u6bb5\u4ee3\u7801\u7684\u6700\u540e\uff0c\u53d8\u91cf bag2 \u5c06\u5305\u542b\u6570\u5b57 2 \u3001 3 \u548c 4 \u3002 bag1 = ArrayBag ([ 2 , 3 , 4 ]) bag2 = bag1 . clone () bag1 == bag2 # Returns True bag1 is bag2 # Returns False 6\uff0e\u96c6\u5408\u662f\u4e00\u4e2a\u65e0\u5e8f\u591a\u9879\u96c6\uff0c\u5e76\u4e14\u548c\u5305\u5177\u6709\u76f8\u540c\u7684\u63a5\u53e3\u3002\u4f46\u662f\u5728\u96c6\u5408\u91cc\uff0c\u5143\u7d20\u662f\u552f\u4e00\u7684\uff0c\u800c\u5305\u91cc\u53ef\u4ee5\u5305\u542b\u91cd\u590d\u7684\u7269\u54c1\u3002\u5b9a\u4e49\u4e00\u4e2a\u57fa\u4e8e\u6570\u7ec4\u7684\u53eb\u4f5c ArraySet \u7684\u591a\u9879\u96c6\u65b0\u7c7b\u3002\u5982\u679c\u96c6\u5408\u91cc\u7684\u5143\u7d20\u5df2\u7ecf\u5b58\u5728\u4e86\uff0c\u90a3\u4e48 add \u65b9\u6cd5\u5c06\u4f1a\u5ffd\u7565\u8fd9\u4e2a\u5143\u7d20\u3002 7\uff0e\u4f7f\u7528\u94fe\u63a5\u8282\u70b9\u5b9a\u4e49\u4e00\u4e2a\u53eb\u4f5c LinkedSet \u7684\u591a\u9879\u96c6\u65b0\u7c7b\u6765\u5b9e\u73b0\u96c6\u5408\u7c7b\u578b\u3002\u5982\u679c\u96c6\u5408\u91cc\u7684\u5143\u7d20\u5df2\u7ecf\u5b58\u5728\u4e86\uff0c\u90a3\u4e48 add \u65b9\u6cd5\u5c06\u4f1a\u5ffd\u7565\u8fd9\u4e2a\u5143\u7d20\u3002 8\uff0e\u6709\u5e8f\u5305\u7684\u884c\u4e3a\u548c\u666e\u901a\u5305\u7684\u662f\u4e00\u6837\u7684\uff0c\u4f46\u662f\u5b83\u80fd\u591f\u8ba9\u7528\u6237\u5728\u4f7f\u7528 for \u5faa\u73af\u65f6\u6309\u7167\u5347\u5e8f\u8bbf\u95ee\u91cc\u9762\u7684\u5143\u7d20\u3002\u56e0\u6b64\uff0c\u6dfb\u52a0\u5230\u8fd9\u4e2a\u5305\u7c7b\u578b\u91cc\u7684\u5143\u7d20\uff0c\u90fd\u5fc5\u987b\u5177\u6709\u4e00\u5b9a\u7684\u987a\u5e8f\u5e76\u4e14\u652f\u6301\u6bd4\u8f83\u8fd0\u7b97\u7b26\u3002\u8fd9\u79cd\u7c7b\u578b\u5143\u7d20\u7684\u7b80\u5355\u4f8b\u5b50\u662f\uff1a\u5b57\u7b26\u4e32\u548c\u6574\u6570\u3002\u5b9a\u4e49\u4e00\u4e2a\u652f\u6301\u8fd9\u4e2a\u529f\u80fd\u7684\u53eb\u4f5c ArraySortedBag \u7684\u65b0\u7c7b\u3002\u548c ArrayBag \u4e00\u6837\uff0c\u8fd9\u4e2a\u65b0\u7c7b\u4f1a\u57fa\u4e8e\u6570\u7ec4\uff0c\u4f46\u662f\u5b83\u7684 in \u64cd\u4f5c\u73b0\u5728\u53ef\u4ee5\u5728\u5bf9\u6570\u65f6\u95f4\u91cc\u8fd0\u884c\u3002\u8981\u5b8c\u6210\u8fd9\u4e00\u70b9\uff0c ArraySortedBag \u5fc5\u987b\u5c06\u65b0\u6dfb\u52a0\u7684\u5143\u7d20\u6309\u7167\u987a\u5e8f\u653e\u5230\u6570\u7ec4\u91cc\u3002\u6700\u7b80\u5355\u7684\u529e\u6cd5\u662f\u4fee\u6539 add \u65b9\u6cd5\uff0c\u4ece\u800c\u8ba9\u65b0\u5143\u7d20\u63d2\u5165\u9002\u5f53\u7684\u4f4d\u7f6e\uff1b\u7136\u540e\uff0c\u6dfb\u52a0_ _contains__ \u65b9\u6cd5\u6765\u63d0\u4f9b\u65b0\u7684\u4e14\u66f4\u6709\u6548\u7684\u641c\u7d22\uff1b\u6700\u540e\uff0c\u8981\u628a\u5bf9 ArrayBag \u7684\u6240\u6709\u5f15\u7528\u90fd\u66ff\u6362\u4e3a ArraySortedBag \u3002\uff08\u63d0\u793a\uff1a\u628a\u4ee3\u7801\u4ece ArrayBag \u7c7b\u4e2d\u590d\u5236\u5230\u4e00\u4e2a\u65b0\u6587\u4ef6\u91cc\uff0c\u7136\u540e\u5728\u8fd9\u4e2a\u65b0\u6587\u4ef6\u91cc\u5f00\u59cb\u4fee\u6539\u3002\uff09 9\uff0e\u786e\u5b9a ArraySortedBag \u91cc add \u65b9\u6cd5\u7684\u8fd0\u884c\u65f6\u3002 10\uff0ePython\u7684 for \u5faa\u73af\u53ef\u4ee5\u8ba9\u7a0b\u5e8f\u5458\u5728\u5faa\u73af\u8fed\u4ee3\u591a\u9879\u96c6\u7684\u65f6\u5019\u5bf9\u5b83\u6267\u884c\u6dfb\u52a0\u6216\u5220\u9664\u5143\u7d20\u7684\u64cd\u4f5c\u3002\u4e00\u4e9b\u8bbe\u8ba1\u4eba\u5458\u62c5\u5fc3\u5728\u8fed\u4ee3\u8fc7\u7a0b\u4e2d\u5bf9\u591a\u9879\u96c6\u7684\u7ed3\u6784\u8fdb\u884c\u4fee\u6539\u53ef\u80fd\u4f1a\u5bfc\u81f4\u7a0b\u5e8f\u5d29\u6e83\u3002\u6709\u4e00\u79cd\u4fee\u6539\u7b56\u7565\u662f\u901a\u8fc7\u7981\u6b62\u5728\u8fed\u4ee3\u671f\u95f4\u5bf9\u591a\u9879\u96c6\u8fdb\u884c\u53d8\u5f02\u6765\u8ba9 for \u5faa\u73af\u6210\u4e3a\u53ea\u8bfb\u3002\u4f60\u53ef\u4ee5\u901a\u8fc7\u5bf9\u53d8\u5f02\u64cd\u4f5c\u8fdb\u884c\u8ba1\u6570\uff0c\u5e76\u4e14\u5224\u65ad\u8fd9\u4e2a\u8ba1\u6570\u6709\u6ca1\u6709\u5728\u591a\u9879\u96c6\u7684 __iter__ \u65b9\u6cd5\u7684\u4efb\u610f\u8282\u62cd\u4e2d\u88ab\u589e\u52a0\u6765\u68c0\u6d4b\u8fd9\u79cd\u7c7b\u578b\u7684\u53d8\u5f02\u3002\u5f53\u53d1\u751f\u8fd9\u79cd\u60c5\u51b5\u65f6\uff0c\u5c31\u53ef\u4ee5\u5f15\u53d1\u5f02\u5e38\u4ece\u800c\u907f\u514d\u8ba1\u7b97\u7684\u7ee7\u7eed\u8fdb\u884c\u3002\u628a\u8fd9\u4e2a\u673a\u5236\u6dfb\u52a0\u5230 ArrayBag \u7c7b\u91cc\u3002\u53ef\u4ee5\u6dfb\u52a0\u4e00\u4e2a\u53eb\u4f5c modCount \u7684\u65b0\u5b9e\u4f8b\u53d8\u91cf\uff0c\u8fd9\u4e2a\u5b9e\u4f8b\u53d8\u91cf\u4f1a\u5728 __init__ \u65b9\u6cd5\u91cc\u8bbe\u7f6e\u4e3a 0 \uff1b\u7136\u540e\uff0c\u6bcf\u4e2a\u53d8\u5f02\u5668\u65b9\u6cd5\u90fd\u4f1a\u9012\u589e\u8fd9\u4e2a\u53d8\u91cf\uff1b\u6700\u540e\uff0c __iter__ \u65b9\u6cd5\u6709\u4e00\u4e2a\u53eb\u4f5c modCount \u7684\u4e34\u65f6\u53d8\u91cf\uff0c\u8fd9\u4e2a\u4e34\u65f6\u53d8\u91cf\u7684\u521d\u59cb\u503c\u662f\u5b9e\u4f8b\u53d8\u91cf self.modCount \u7684\u503c\u3002\u5728 __iter__ \u65b9\u6cd5\u91cc\u8fd4\u56de\u4e00\u4e2a\u5143\u7d20\u540e\uff0c\u5982\u679c\u8fd9\u4e24\u4e2a\u4fee\u6539\u8fc7\u7684\u8ba1\u6570\u5668\u503c\u4e0d\u76f8\u7b49\uff0c\u5c31\u7acb\u5373\u5f15\u53d1\u5f02\u5e38\u3002\u7528\u4e00\u4e2a\u7a0b\u5e8f\u6765\u6d4b\u8bd5\u4f60\u7684\u4fee\u6539\uff0c\u4ece\u800c\u4fdd\u8bc1\u6ee1\u8db3\u76f8\u5e94\u7684\u9700\u6c42\u3002","title":"5.10.\u7f16\u7a0b\u7ec3\u4e60"},{"location":"python/DataStructure/06_InheritanceAbstractClass/","text":"\u7ee7\u627f\u4e0e\u62bd\u8c61\u7c7b \u00b6","title":"\u7ee7\u627f\u4e0e\u62bd\u8c61\u7c7b"},{"location":"python/DataStructure/06_InheritanceAbstractClass/#_1","text":"","title":"\u7ee7\u627f\u4e0e\u62bd\u8c61\u7c7b"},{"location":"python/Demo/CourseSystem/","text":"\u9009\u8bfe\u7cfb\u7edf \u00b6 \u4efb\u52a1\u9700\u6c42 \u00b6 \u89d2\u8272\uff1a\u5b66\u6821\u3001\u5b66\u5458\u3001\u8bfe\u7a0b\u3001\u8bb2\u5e08 \u8981\u6c42\uff1a \u521b\u5efa\u5317\u4eac\u3001\u4e0a\u6d772\u6240\u5b66\u6821\u3002 \u521b\u5efaLinux\u3001Python\u3001go\u4e09\u4e2a\u8bfe\u7a0b\uff0cLinux\u548cPython\u5728\u5317\u4eac\u5f00\uff0cgo\u5728\u4e0a\u6d77\u5f00\u3002 \u8bfe\u7a0b\u5305\u542b\u5468\u671f\u3001\u4ef7\u683c\uff0c\u901a\u8fc7\u5b66\u6821\u521b\u5efa\u8bfe\u7a0b\u3002 \u901a\u8fc7\u5b66\u6821\u521b\u5efa\u73ed\u7ea7\uff0c\u73ed\u7ea7\u5173\u8054\u8bfe\u7a0b\u3001\u8bb2\u5e08\u3002 \u521b\u5efa\u8bb2\u5e08\u3002 \u521b\u5efa\u5b66\u5458\u65f6\uff0c\u9009\u62e9\u5b66\u6821\uff0c\u5173\u8054\u73ed\u7ea7\u3002 \u521b\u5efa\u8bb2\u5e08\u89d2\u8272\uff08\u4e0d\u9700\u8981\u5173\u8054\u5b66\u6821\uff09\u3002 \u63d0\u4f9b\u4e24\u4e2a\u89d2\u8272\u63a5\u53e3\u3002 \u5b66\u5458\u89c6\u56fe\uff1a\u53ef\u4ee5\u6ce8\u518c\uff0c\u4ea4\u5b66\u8d39\uff0c\u9009\u62e9\u73ed\u7ea7\u3002 \u8bb2\u5e08\u89c6\u56fe\uff1a\u8bb2\u5e08\u53ef\u4ee5\u7ba1\u7406\u81ea\u5df1\u7684\u73ed\u7ea7\uff0c\u4e0a\u8bfe\u65f6\u9009\u62e9\u73ed\u7ea7\uff0c\u67e5\u770b\u73ed\u7ea7\u5b66\u5458\u5217\u8868\uff0c\u4fee\u6539\u6240\u7ba1\u7406\u7684\u5b66\u5458\u7684\u6210\u7ee9\u3002 \u7ba1\u7406\u89c6\u56fe\uff1a\u521b\u5efa\u8bb2\u5e08\uff0c\u521b\u5efa\u73ed\u7ea7\uff0c\u521b\u5efa\u8bfe\u7a0b\u3002 \u4e0a\u8ff0\u64cd\u4f5c\u6240\u4ea7\u751f\u7684\u6570\u636e\u901a\u8fc7pickle\u4fdd\u5b58\u5230\u6587\u4ef6\u3002 \u9700\u6c42\u5206\u6790 \u00b6 \u7ba1\u7406\u89c6\u56fe \u6ce8\u518c \u767b\u5f55 \u521b\u5efa\u5b66\u6821 \u521b\u5efa\u8bfe\u7a0b\uff08\u5148\u9009\u62e9\u5b66\u6821\uff09 \u521b\u5efa\u8bb2\u5e08 \u5b66\u5458\u89c6\u56fe \u6ce8\u518c \u767b\u5f55\u529f\u80fd \u9009\u62e9\u6821\u533a \u9009\u62e9\u8bfe\u7a0b\uff08\u5148\u9009\u62e9\u6821\u533a\uff0c\u5728\u9009\u62e9\u6821\u533a\u4e2d\u7684\u67d0\u4e00\u95e8\u8bfe\u7a0b\uff0c\u9009\u62e9\u8bfe\u7a0b\u5373\u9009\u62e9\u73ed\u7ea7\uff09 \u5b66\u751f\u9009\u62e9\u8bfe\u7a0b\uff0c\u8bfe\u7a0b\u4e5f\u9009\u62e9\u5b66\u751f \u67e5\u770b\u5206\u6570 \u4ea4\u5b66\u8d39 \u8bb2\u5e08\u89c6\u56fe \u767b\u5f55 \u67e5\u770b\u6559\u6388\u8bfe\u7a0b \u9009\u62e9\u6559\u6388\u8bfe\u7a0b \u67e5\u770b\u8bfe\u7a0b\u4e0b\u7684\u5b66\u751f \u4fee\u6539\u5b66\u751f\u5206\u6570 \u67b6\u6784\u8bbe\u8ba1\uff08\u4e09\u5c42\u67b6\u6784\uff09 \u00b6 \u7528\u6237\u89c6\u56fe\u5c42 \u7528\u4e8e\u4e0e\u7528\u6237\u8fdb\u884c\u4ea4\u4e92\u3002 \u5b9e\u73b0\u7b80\u5355\u7684\u903b\u8f91\u5224\u65ad\uff0c\u6bd4\u5982\u6ce8\u518c\u529f\u80fd\u4e2d\u4e24\u6b21\u5bc6\u7801\u662f\u5426\u4e00\u81f4\u7684\u6821\u9a8c\u3002 core src.py \u4e3b\u89c6\u56fe admin.py: \u7ba1\u7406\u89c6\u56fe student.py: \u5b66\u5458\u89c6\u56fe teacher.py: \u8bb2\u5e08\u89c6\u56fe \u903b\u8f91\u63a5\u53e3\u5c42 \u6838\u5fc3\u4e1a\u52a1\u903b\u8f91\u7684\u5904\u7406 interface admin_interface.py studeng_interface.py teacher_interface.py \u6570\u636e\u5904\u7406\u5c42 \u6570\u636e\u5904\u7406\uff0c\u6bd4\u5982\u589e\u5220\u6539\u67e5\u3002 db models.py db_handler.py pickle\u4fdd\u5b58\u5bf9\u8c61 object \u2192 pickle \u6587\u4ef6\u7ed3\u6784 \u00b6 /--conf/ | |--settings.py | |--core/ | |--src.py | |--admin.py | |--student.py | |--teacher.py | |--db/ | |--models.py | |--db_handler.py | |--pickle | |--interface/ | |--admin_interface.py | |--student_interface.py | |--teacher_interface.py | |--common_interface.py | |--lib/ | |--common.py | |--start.py \u9009\u8bfe\u7cfb\u7edf\u603b\u7ed3 \u00b6 1.\u7ba1\u7406\u5458 \u00b6 1.1.\u6ce8\u518c \u00b6 \u7528\u6237\u518d\u89c6\u56fe\u5c42\u8f93\u5165\u7528\u6237\u540d\u548c\u5bc6\u7801\uff0c\u4ea4\u7ed9\u63a5\u53e3\u5c42\u3002 \u63a5\u53e3\u5c42\u8c03\u7528\u6570\u636e\u5c42\u4e2d\u7684models.get()\u8fdb\u884c\u6821\u9a8c\u3002 \u82e5\u4e0d\u5b58\u5728\u5219\u521b\u5efa\uff0c\u5e76\u8bb2\u6ce8\u518c\u6210\u529f\u8fd4\u56de\u7ed9\u89c6\u56fe\u5c42\u3002 1.2.\u767b\u5f55 \u00b6 \u7528\u6237\u5728\u89c6\u56fe\u5c42\u8f93\u5165\u7528\u6237\u540d\u548c\u5bc6\u7801\uff0c\u4ea4\u7ed9\u63a5\u53e3\u5c42\u3002 \u63a5\u53e3\u5c42\u8c03\u7528\u6570\u636e\u5c42\u4e2d\u7684models.get()\u8fdb\u884c\u6821\u9a8c\u3002 \u82e5\u4e0d\u5b58\u5728\u5219\u521b\u5efa\uff0c\u5e76\u8bb2\u6ce8\u518c\u6210\u529f\u8fd4\u56de\u7ed9\u89c6\u56fe\u5c42\u3002 1.3.\u521b\u5efa\u5b66\u6821 \u00b6 \u8ba9\u7528\u6237\u8f93\u5165\u5b66\u6821\u540d\u548c\u5b66\u6821\u5730\u5740\u3002 \u8c03\u7528\u7ba1\u7406\u5458\u63a5\u53e3\u521b\u5efa\u5b66\u6821\u3002 \u5224\u65ad\u5b66\u6821\u662f\u5426\u5b58\u5728\uff0c\u82e5\u5b58\u5728\uff0c\u4e0d\u521b\u5efa\u3002 \u82e5\u4e0d\u5b58\u5728\uff0c\u5219\u8c03\u7528\u63a5\u53e3\u5c42\u521b\u5efa\u5b66\u6821\uff0c\u83b7\u53d6\u7ba1\u7406\u5458\u5bf9\u8c61\u7684\u521b\u5efa\u5b66\u6821\u65b9\u6cd5\u4fdd\u6301\u5b66\u6821\u5bf9\u8c61\u3002 \u5c06\u7ed3\u679c\u8fd4\u56de\u7ed9\u89c6\u56fe\u5c42\u3002 1.4.\u521b\u5efa\u8bfe\u7a0b \u00b6 \u83b7\u53d6\u6240\u6709\u5b66\u6821\uff0c\u5e76\u6253\u5370\uff0c\u8ba9\u7528\u6237\u9009\u62e9\u3002 \u83b7\u53d6\u7528\u6237\u9009\u62e9\u7684\u5b66\u6821\u4e0e\u521b\u5efa\u7684\u8bfe\u7a0b\uff0c\u4ea4\u7ed9\u63a5\u53e3\u5c42\u3002 \u63a5\u53e3\u5c42\u8c03\u7528\u7ba1\u7406\u5458\u5bf9\u8c61\u4e2d\u7684\u521b\u5efa\u8bfe\u7a0b\u65b9\u6cd5\uff0c\u4fdd\u5b58\u8bfe\u7a0b\u5bf9\u8c61\u3002 \u8bfe\u7a0b\u9700\u8981\u7ed1\u5b9a\u7ed9\u5b66\u6821\u5bf9\u8c61\uff0c\u6700\u7ec8\u5c06\u521b\u5efa\u6210\u529f\u7684\u7ed3\u679c\u8fd4\u56de\u7ed9\u89c6\u56fe\u5c42\u3002 1.5.\u521b\u5efa\u8001\u5e08 \u00b6 \u7528\u6237\u8f93\u5165\u8001\u5e08\u540d\u79f0\u3002 \u8c03\u7528\u63a5\u53e3\u5c42\uff0c\u63a5\u53e3\u5c42\u4e2d\u8bbe\u7f6e\u9ed8\u8ba4\u5bc6\u7801123\uff0c\u8c03\u7528\u6570\u636e\u5c42\u3002 \u5224\u65ad\u8001\u5e08\u662f\u5426\u5b58\u5728\uff0c\u4e0d\u5b58\u5728\u5219\u8c03\u7528\u7ba1\u7406\u5458\u5bf9\u8c61\u4e2d\u7684\u521b\u5efa\u8001\u5e08\u65b9\u6cd5\u3002 \u4fdd\u5b58\u8001\u5e08\u5bf9\u8c61\uff0c\u5e76\u5c06\u7ed3\u679c\u8fd4\u56de\u7ed9\u89c6\u56fe\u5c42\u3002 2.\u5b66\u751f \u00b6 2.1.\u6ce8\u518c \u00b6 \u540c\u4e0a 2.2.\u767b\u5f55 \u00b6 \u540c\u4e0a 2.3.\u9009\u62e9\u5b66\u6821 \u00b6 \u83b7\u53d6\u6240\u6709\u5b66\u6821\uff0c\u8ba9\u5b66\u751f\u9009\u62e9\uff0c\u5e76\u5c06\u9009\u62e9\u7684\u5b66\u6821\u4f20\u7ed9\u63a5\u53e3\u5c42\u3002 \u63a5\u53e3\u5c42\u5224\u65ad\u5f53\u524d\u5b66\u751f\u662f\u5426\u9009\u62e9\u5b66\u6821\u3002 \u82e5\u6ca1\u6709\u9009\u62e9\uff0c\u5219\u8c03\u7528\u5b66\u751f\u5bf9\u8c61\u4e2d\u7684\u6dfb\u52a0\u5b66\u6821\u65b9\u6cd5\u3002 \u5c06\u6dfb\u52a0\u540e\u6d88\u606f\u8fd4\u56de\u7ed9\u89c6\u56fe\u5c42\u3002 2.4.\u9009\u62e9\u8bfe\u7a0b \u00b6 \u5148\u83b7\u53d6\u5f53\u524d\u5b66\u751f\u6240\u5728\u5b66\u6821\u7684\u6240\u6709\u8bfe\u7a0b\uff0c\u5e76\u9009\u62e9\u3002 \u63a5\u53e3\u5c42\u5c06\u9009\u62e9\u540e\u7684\u8bfe\u7a0b\uff0c\u8c03\u7528\u6570\u636e\u5c42\u7684\u6dfb\u52a0\u8bfe\u7a0b\u65b9\u6cd5\u4fdd\u5b58\u3002 \u5b66\u751f\u5bf9\u8c61\u4e2d\u8bfe\u7a0b\u5217\u8868\u6dfb\u52a0\u8bfe\u7a0b\uff0c\u8bbe\u7f6e\u8bfe\u7a0b\u5206\u6570\uff0c\u9ed8\u8ba4\u4e3a0. \u6700\u7ec8\u5c06\u7ed3\u679c\u8fd4\u56de\u7ed9\u89c6\u56fe\u5c42\u3002 2.5.\u67e5\u770b\u6210\u7ee9 \u00b6 \u76f4\u63a5\u8c03\u7528\u63a5\u53e3\u5c42\u3002 \u63a5\u53e3\u5c42\u8c03\u7528\u6570\u636e\u5c42\u4e2d\u7684\u67e5\u770b\u6210\u7ee9\u65b9\u6cd5\u3002 \u8fd4\u56de\u6210\u7ee9\u7ed9\u89c6\u56fe\u5c42\u5e76\u6253\u5370\u3002 3.\u8001\u5e08 \u00b6 3.1.\u767b\u5f55 \u00b6 \u540c\u4e0a 3.2.\u67e5\u770b\u6559\u6388\u8bfe\u7a0b \u00b6 \u76f4\u63a5\u8c03\u7528\u63a5\u53e3\u5c42\uff0c\u83b7\u53d6\u8001\u5e08\u5bf9\u8c61\u4e0b\u8bfe\u7a0b\u5217\u8868\u6570\u636e\u3002 \u82e5\u6709\u5219\u6253\u5370\uff0c\u6ca1\u6709\u5219\u9000\u51fa\u3002 3.3.\u9009\u62e9\u6559\u6388\u8bfe\u7a0b \u00b6 \u8c03\u7528\u63a5\u53e3\u5c42\u4e2d\u7684\u9009\u62e9\u6559\u6388\u8bfe\u7a0b\u63a5\u53e3\uff0c\u8c03\u7528\u6570\u636e\u5c42\u4e2d\u6539\u8bfe\u7a0b\u4e0b\u6240\u6709\u7684\u5b66\u751f\uff0c\u8fd4\u56de\u7ed9\u89c6\u56fe\u5c42\u3002 \u6253\u5370\u6240\u6709\u7684\u8bfe\u7a0b\uff0c\u8ba9\u8001\u5e08\u9009\u62e9\uff0c\u82e5\u8001\u5e08\u8bfe\u7a0b\u4e2d\u6709\u8be5\u8bfe\u7a0b\u5219\u4e0d\u6dfb\u52a0\u3002 \u6ca1\u6709\uff0c\u5219\u55f2\u7528\u8001\u5e08\u5bf9\u8c61\u4e2d\u7684\u6dfb\u52a0\u8bfe\u7a0b\u65b9\u6cd5\u8fdb\u884c\u6dfb\u52a0\u3002 3.4.\u67e5\u770b\u8bfe\u7a0b\u4e0b\u7684\u5b66\u751f \u00b6 \u76f4\u63a5\u83b7\u53d6\u8001\u5e08\u5bf9\u8c61\u4e0b\u6240\u6709\u7684\u8bfe\u7a0b\uff0c\u9009\u62e9\u8bfe\u7a0b\u3002 \u4ece\u8001\u5e08\u5bf9\u8c61\u4e2d\uff0c\u8c03\u7528\u67e5\u770b\u8bfe\u7a0b\u4e0b\u5b66\u751f\u7684\u65b9\u6cd5\uff0c\u83b7\u53d6\u8bfe\u7a0b\u5bf9\u8c61\u4e0b\u7684\u6240\u6709\u5b66\u751f\uff0c\u8fd4\u56de\u7ed9\u89c6\u56fe\u5c42\u3002 \u89c6\u56fe\u5c42\u6253\u5370\u8be5\u8bfe\u7a0b\u4e0b\u6240\u6709\u7684\u5b66\u751f\u3002 3.5.\u4fee\u6539\u5b66\u751f\u5206\u6570 \u00b6 \u76f4\u63a5\u83b7\u53d6\u8001\u5e08\u5bf9\u8c61\u4e0b\u6240\u6709\u7684\u8bfe\u7a0b\u3002 \u4ece\u8001\u5e08\u5bf9\u8c61\u4e2d\uff0c\u8c03\u7528\u67e5\u770b\u8bfe\u7a0b\u4e0b\u5b66\u751f\u65b9\u6cd5\uff0c\u83b7\u53d6\u8bfe\u7a0b\u5bf9\u8c61\u4e0b\u6240\u6709\u7684\u5b66\u751f\uff0c\u8fd4\u56de\u7ed9\u89c6\u56fe\u5c42\u3002 \u89c6\u56fe\u5c42\u6253\u5370\u6539\u8bfe\u7a0b\u4e0b\u6240\u6709\u7684\u5b66\u751f\uff0c\u5e76\u8ba9\u7528\u6237\u9009\u62e9\u9700\u8981\u5206\u6570\u7684\u5b66\u751f\u3002 \u55f2\u7528\u8001\u5e08\u4fee\u6539\u5206\u6570\u63a5\u53e3\uff0c\u83b7\u53d6\u8001\u5e08\u5bf9\u8c61\uff0c\u8c03\u7528\u5bf9\u8c61\u4e2d\u4fee\u6539\u5206\u6570\u65b9\u6cd5\u3002 \u83b7\u53d6\u5b66\u751f\u5bf9\u8c61\u4e2d\u7684\u5206\u6570\u5b57\u5178\uff0c\u8fdb\u884c\u4fee\u6539\u3002 3.4.\u67e5\u770b\u6210\u7ee9 \u00b6 \u793a\u610f\u56fe \u00b6 \u53c2\u8003\u4ee3\u7801 \u00b6 \u4ee3\u7801","title":"\u9009\u8bfe\u7cfb\u7edf"},{"location":"python/Demo/CourseSystem/#_1","text":"","title":"\u9009\u8bfe\u7cfb\u7edf"},{"location":"python/Demo/CourseSystem/#_2","text":"\u89d2\u8272\uff1a\u5b66\u6821\u3001\u5b66\u5458\u3001\u8bfe\u7a0b\u3001\u8bb2\u5e08 \u8981\u6c42\uff1a \u521b\u5efa\u5317\u4eac\u3001\u4e0a\u6d772\u6240\u5b66\u6821\u3002 \u521b\u5efaLinux\u3001Python\u3001go\u4e09\u4e2a\u8bfe\u7a0b\uff0cLinux\u548cPython\u5728\u5317\u4eac\u5f00\uff0cgo\u5728\u4e0a\u6d77\u5f00\u3002 \u8bfe\u7a0b\u5305\u542b\u5468\u671f\u3001\u4ef7\u683c\uff0c\u901a\u8fc7\u5b66\u6821\u521b\u5efa\u8bfe\u7a0b\u3002 \u901a\u8fc7\u5b66\u6821\u521b\u5efa\u73ed\u7ea7\uff0c\u73ed\u7ea7\u5173\u8054\u8bfe\u7a0b\u3001\u8bb2\u5e08\u3002 \u521b\u5efa\u8bb2\u5e08\u3002 \u521b\u5efa\u5b66\u5458\u65f6\uff0c\u9009\u62e9\u5b66\u6821\uff0c\u5173\u8054\u73ed\u7ea7\u3002 \u521b\u5efa\u8bb2\u5e08\u89d2\u8272\uff08\u4e0d\u9700\u8981\u5173\u8054\u5b66\u6821\uff09\u3002 \u63d0\u4f9b\u4e24\u4e2a\u89d2\u8272\u63a5\u53e3\u3002 \u5b66\u5458\u89c6\u56fe\uff1a\u53ef\u4ee5\u6ce8\u518c\uff0c\u4ea4\u5b66\u8d39\uff0c\u9009\u62e9\u73ed\u7ea7\u3002 \u8bb2\u5e08\u89c6\u56fe\uff1a\u8bb2\u5e08\u53ef\u4ee5\u7ba1\u7406\u81ea\u5df1\u7684\u73ed\u7ea7\uff0c\u4e0a\u8bfe\u65f6\u9009\u62e9\u73ed\u7ea7\uff0c\u67e5\u770b\u73ed\u7ea7\u5b66\u5458\u5217\u8868\uff0c\u4fee\u6539\u6240\u7ba1\u7406\u7684\u5b66\u5458\u7684\u6210\u7ee9\u3002 \u7ba1\u7406\u89c6\u56fe\uff1a\u521b\u5efa\u8bb2\u5e08\uff0c\u521b\u5efa\u73ed\u7ea7\uff0c\u521b\u5efa\u8bfe\u7a0b\u3002 \u4e0a\u8ff0\u64cd\u4f5c\u6240\u4ea7\u751f\u7684\u6570\u636e\u901a\u8fc7pickle\u4fdd\u5b58\u5230\u6587\u4ef6\u3002","title":"\u4efb\u52a1\u9700\u6c42"},{"location":"python/Demo/CourseSystem/#_3","text":"\u7ba1\u7406\u89c6\u56fe \u6ce8\u518c \u767b\u5f55 \u521b\u5efa\u5b66\u6821 \u521b\u5efa\u8bfe\u7a0b\uff08\u5148\u9009\u62e9\u5b66\u6821\uff09 \u521b\u5efa\u8bb2\u5e08 \u5b66\u5458\u89c6\u56fe \u6ce8\u518c \u767b\u5f55\u529f\u80fd \u9009\u62e9\u6821\u533a \u9009\u62e9\u8bfe\u7a0b\uff08\u5148\u9009\u62e9\u6821\u533a\uff0c\u5728\u9009\u62e9\u6821\u533a\u4e2d\u7684\u67d0\u4e00\u95e8\u8bfe\u7a0b\uff0c\u9009\u62e9\u8bfe\u7a0b\u5373\u9009\u62e9\u73ed\u7ea7\uff09 \u5b66\u751f\u9009\u62e9\u8bfe\u7a0b\uff0c\u8bfe\u7a0b\u4e5f\u9009\u62e9\u5b66\u751f \u67e5\u770b\u5206\u6570 \u4ea4\u5b66\u8d39 \u8bb2\u5e08\u89c6\u56fe \u767b\u5f55 \u67e5\u770b\u6559\u6388\u8bfe\u7a0b \u9009\u62e9\u6559\u6388\u8bfe\u7a0b \u67e5\u770b\u8bfe\u7a0b\u4e0b\u7684\u5b66\u751f \u4fee\u6539\u5b66\u751f\u5206\u6570","title":"\u9700\u6c42\u5206\u6790"},{"location":"python/Demo/CourseSystem/#_4","text":"\u7528\u6237\u89c6\u56fe\u5c42 \u7528\u4e8e\u4e0e\u7528\u6237\u8fdb\u884c\u4ea4\u4e92\u3002 \u5b9e\u73b0\u7b80\u5355\u7684\u903b\u8f91\u5224\u65ad\uff0c\u6bd4\u5982\u6ce8\u518c\u529f\u80fd\u4e2d\u4e24\u6b21\u5bc6\u7801\u662f\u5426\u4e00\u81f4\u7684\u6821\u9a8c\u3002 core src.py \u4e3b\u89c6\u56fe admin.py: \u7ba1\u7406\u89c6\u56fe student.py: \u5b66\u5458\u89c6\u56fe teacher.py: \u8bb2\u5e08\u89c6\u56fe \u903b\u8f91\u63a5\u53e3\u5c42 \u6838\u5fc3\u4e1a\u52a1\u903b\u8f91\u7684\u5904\u7406 interface admin_interface.py studeng_interface.py teacher_interface.py \u6570\u636e\u5904\u7406\u5c42 \u6570\u636e\u5904\u7406\uff0c\u6bd4\u5982\u589e\u5220\u6539\u67e5\u3002 db models.py db_handler.py pickle\u4fdd\u5b58\u5bf9\u8c61 object \u2192 pickle","title":"\u67b6\u6784\u8bbe\u8ba1\uff08\u4e09\u5c42\u67b6\u6784\uff09"},{"location":"python/Demo/CourseSystem/#_5","text":"/--conf/ | |--settings.py | |--core/ | |--src.py | |--admin.py | |--student.py | |--teacher.py | |--db/ | |--models.py | |--db_handler.py | |--pickle | |--interface/ | |--admin_interface.py | |--student_interface.py | |--teacher_interface.py | |--common_interface.py | |--lib/ | |--common.py | |--start.py","title":"\u6587\u4ef6\u7ed3\u6784"},{"location":"python/Demo/CourseSystem/#_6","text":"","title":"\u9009\u8bfe\u7cfb\u7edf\u603b\u7ed3"},{"location":"python/Demo/CourseSystem/#1","text":"","title":"1.\u7ba1\u7406\u5458"},{"location":"python/Demo/CourseSystem/#11","text":"\u7528\u6237\u518d\u89c6\u56fe\u5c42\u8f93\u5165\u7528\u6237\u540d\u548c\u5bc6\u7801\uff0c\u4ea4\u7ed9\u63a5\u53e3\u5c42\u3002 \u63a5\u53e3\u5c42\u8c03\u7528\u6570\u636e\u5c42\u4e2d\u7684models.get()\u8fdb\u884c\u6821\u9a8c\u3002 \u82e5\u4e0d\u5b58\u5728\u5219\u521b\u5efa\uff0c\u5e76\u8bb2\u6ce8\u518c\u6210\u529f\u8fd4\u56de\u7ed9\u89c6\u56fe\u5c42\u3002","title":"1.1.\u6ce8\u518c"},{"location":"python/Demo/CourseSystem/#12","text":"\u7528\u6237\u5728\u89c6\u56fe\u5c42\u8f93\u5165\u7528\u6237\u540d\u548c\u5bc6\u7801\uff0c\u4ea4\u7ed9\u63a5\u53e3\u5c42\u3002 \u63a5\u53e3\u5c42\u8c03\u7528\u6570\u636e\u5c42\u4e2d\u7684models.get()\u8fdb\u884c\u6821\u9a8c\u3002 \u82e5\u4e0d\u5b58\u5728\u5219\u521b\u5efa\uff0c\u5e76\u8bb2\u6ce8\u518c\u6210\u529f\u8fd4\u56de\u7ed9\u89c6\u56fe\u5c42\u3002","title":"1.2.\u767b\u5f55"},{"location":"python/Demo/CourseSystem/#13","text":"\u8ba9\u7528\u6237\u8f93\u5165\u5b66\u6821\u540d\u548c\u5b66\u6821\u5730\u5740\u3002 \u8c03\u7528\u7ba1\u7406\u5458\u63a5\u53e3\u521b\u5efa\u5b66\u6821\u3002 \u5224\u65ad\u5b66\u6821\u662f\u5426\u5b58\u5728\uff0c\u82e5\u5b58\u5728\uff0c\u4e0d\u521b\u5efa\u3002 \u82e5\u4e0d\u5b58\u5728\uff0c\u5219\u8c03\u7528\u63a5\u53e3\u5c42\u521b\u5efa\u5b66\u6821\uff0c\u83b7\u53d6\u7ba1\u7406\u5458\u5bf9\u8c61\u7684\u521b\u5efa\u5b66\u6821\u65b9\u6cd5\u4fdd\u6301\u5b66\u6821\u5bf9\u8c61\u3002 \u5c06\u7ed3\u679c\u8fd4\u56de\u7ed9\u89c6\u56fe\u5c42\u3002","title":"1.3.\u521b\u5efa\u5b66\u6821"},{"location":"python/Demo/CourseSystem/#14","text":"\u83b7\u53d6\u6240\u6709\u5b66\u6821\uff0c\u5e76\u6253\u5370\uff0c\u8ba9\u7528\u6237\u9009\u62e9\u3002 \u83b7\u53d6\u7528\u6237\u9009\u62e9\u7684\u5b66\u6821\u4e0e\u521b\u5efa\u7684\u8bfe\u7a0b\uff0c\u4ea4\u7ed9\u63a5\u53e3\u5c42\u3002 \u63a5\u53e3\u5c42\u8c03\u7528\u7ba1\u7406\u5458\u5bf9\u8c61\u4e2d\u7684\u521b\u5efa\u8bfe\u7a0b\u65b9\u6cd5\uff0c\u4fdd\u5b58\u8bfe\u7a0b\u5bf9\u8c61\u3002 \u8bfe\u7a0b\u9700\u8981\u7ed1\u5b9a\u7ed9\u5b66\u6821\u5bf9\u8c61\uff0c\u6700\u7ec8\u5c06\u521b\u5efa\u6210\u529f\u7684\u7ed3\u679c\u8fd4\u56de\u7ed9\u89c6\u56fe\u5c42\u3002","title":"1.4.\u521b\u5efa\u8bfe\u7a0b"},{"location":"python/Demo/CourseSystem/#15","text":"\u7528\u6237\u8f93\u5165\u8001\u5e08\u540d\u79f0\u3002 \u8c03\u7528\u63a5\u53e3\u5c42\uff0c\u63a5\u53e3\u5c42\u4e2d\u8bbe\u7f6e\u9ed8\u8ba4\u5bc6\u7801123\uff0c\u8c03\u7528\u6570\u636e\u5c42\u3002 \u5224\u65ad\u8001\u5e08\u662f\u5426\u5b58\u5728\uff0c\u4e0d\u5b58\u5728\u5219\u8c03\u7528\u7ba1\u7406\u5458\u5bf9\u8c61\u4e2d\u7684\u521b\u5efa\u8001\u5e08\u65b9\u6cd5\u3002 \u4fdd\u5b58\u8001\u5e08\u5bf9\u8c61\uff0c\u5e76\u5c06\u7ed3\u679c\u8fd4\u56de\u7ed9\u89c6\u56fe\u5c42\u3002","title":"1.5.\u521b\u5efa\u8001\u5e08"},{"location":"python/Demo/CourseSystem/#2","text":"","title":"2.\u5b66\u751f"},{"location":"python/Demo/CourseSystem/#21","text":"\u540c\u4e0a","title":"2.1.\u6ce8\u518c"},{"location":"python/Demo/CourseSystem/#22","text":"\u540c\u4e0a","title":"2.2.\u767b\u5f55"},{"location":"python/Demo/CourseSystem/#23","text":"\u83b7\u53d6\u6240\u6709\u5b66\u6821\uff0c\u8ba9\u5b66\u751f\u9009\u62e9\uff0c\u5e76\u5c06\u9009\u62e9\u7684\u5b66\u6821\u4f20\u7ed9\u63a5\u53e3\u5c42\u3002 \u63a5\u53e3\u5c42\u5224\u65ad\u5f53\u524d\u5b66\u751f\u662f\u5426\u9009\u62e9\u5b66\u6821\u3002 \u82e5\u6ca1\u6709\u9009\u62e9\uff0c\u5219\u8c03\u7528\u5b66\u751f\u5bf9\u8c61\u4e2d\u7684\u6dfb\u52a0\u5b66\u6821\u65b9\u6cd5\u3002 \u5c06\u6dfb\u52a0\u540e\u6d88\u606f\u8fd4\u56de\u7ed9\u89c6\u56fe\u5c42\u3002","title":"2.3.\u9009\u62e9\u5b66\u6821"},{"location":"python/Demo/CourseSystem/#24","text":"\u5148\u83b7\u53d6\u5f53\u524d\u5b66\u751f\u6240\u5728\u5b66\u6821\u7684\u6240\u6709\u8bfe\u7a0b\uff0c\u5e76\u9009\u62e9\u3002 \u63a5\u53e3\u5c42\u5c06\u9009\u62e9\u540e\u7684\u8bfe\u7a0b\uff0c\u8c03\u7528\u6570\u636e\u5c42\u7684\u6dfb\u52a0\u8bfe\u7a0b\u65b9\u6cd5\u4fdd\u5b58\u3002 \u5b66\u751f\u5bf9\u8c61\u4e2d\u8bfe\u7a0b\u5217\u8868\u6dfb\u52a0\u8bfe\u7a0b\uff0c\u8bbe\u7f6e\u8bfe\u7a0b\u5206\u6570\uff0c\u9ed8\u8ba4\u4e3a0. \u6700\u7ec8\u5c06\u7ed3\u679c\u8fd4\u56de\u7ed9\u89c6\u56fe\u5c42\u3002","title":"2.4.\u9009\u62e9\u8bfe\u7a0b"},{"location":"python/Demo/CourseSystem/#25","text":"\u76f4\u63a5\u8c03\u7528\u63a5\u53e3\u5c42\u3002 \u63a5\u53e3\u5c42\u8c03\u7528\u6570\u636e\u5c42\u4e2d\u7684\u67e5\u770b\u6210\u7ee9\u65b9\u6cd5\u3002 \u8fd4\u56de\u6210\u7ee9\u7ed9\u89c6\u56fe\u5c42\u5e76\u6253\u5370\u3002","title":"2.5.\u67e5\u770b\u6210\u7ee9"},{"location":"python/Demo/CourseSystem/#3","text":"","title":"3.\u8001\u5e08"},{"location":"python/Demo/CourseSystem/#31","text":"\u540c\u4e0a","title":"3.1.\u767b\u5f55"},{"location":"python/Demo/CourseSystem/#32","text":"\u76f4\u63a5\u8c03\u7528\u63a5\u53e3\u5c42\uff0c\u83b7\u53d6\u8001\u5e08\u5bf9\u8c61\u4e0b\u8bfe\u7a0b\u5217\u8868\u6570\u636e\u3002 \u82e5\u6709\u5219\u6253\u5370\uff0c\u6ca1\u6709\u5219\u9000\u51fa\u3002","title":"3.2.\u67e5\u770b\u6559\u6388\u8bfe\u7a0b"},{"location":"python/Demo/CourseSystem/#33","text":"\u8c03\u7528\u63a5\u53e3\u5c42\u4e2d\u7684\u9009\u62e9\u6559\u6388\u8bfe\u7a0b\u63a5\u53e3\uff0c\u8c03\u7528\u6570\u636e\u5c42\u4e2d\u6539\u8bfe\u7a0b\u4e0b\u6240\u6709\u7684\u5b66\u751f\uff0c\u8fd4\u56de\u7ed9\u89c6\u56fe\u5c42\u3002 \u6253\u5370\u6240\u6709\u7684\u8bfe\u7a0b\uff0c\u8ba9\u8001\u5e08\u9009\u62e9\uff0c\u82e5\u8001\u5e08\u8bfe\u7a0b\u4e2d\u6709\u8be5\u8bfe\u7a0b\u5219\u4e0d\u6dfb\u52a0\u3002 \u6ca1\u6709\uff0c\u5219\u55f2\u7528\u8001\u5e08\u5bf9\u8c61\u4e2d\u7684\u6dfb\u52a0\u8bfe\u7a0b\u65b9\u6cd5\u8fdb\u884c\u6dfb\u52a0\u3002","title":"3.3.\u9009\u62e9\u6559\u6388\u8bfe\u7a0b"},{"location":"python/Demo/CourseSystem/#34","text":"\u76f4\u63a5\u83b7\u53d6\u8001\u5e08\u5bf9\u8c61\u4e0b\u6240\u6709\u7684\u8bfe\u7a0b\uff0c\u9009\u62e9\u8bfe\u7a0b\u3002 \u4ece\u8001\u5e08\u5bf9\u8c61\u4e2d\uff0c\u8c03\u7528\u67e5\u770b\u8bfe\u7a0b\u4e0b\u5b66\u751f\u7684\u65b9\u6cd5\uff0c\u83b7\u53d6\u8bfe\u7a0b\u5bf9\u8c61\u4e0b\u7684\u6240\u6709\u5b66\u751f\uff0c\u8fd4\u56de\u7ed9\u89c6\u56fe\u5c42\u3002 \u89c6\u56fe\u5c42\u6253\u5370\u8be5\u8bfe\u7a0b\u4e0b\u6240\u6709\u7684\u5b66\u751f\u3002","title":"3.4.\u67e5\u770b\u8bfe\u7a0b\u4e0b\u7684\u5b66\u751f"},{"location":"python/Demo/CourseSystem/#35","text":"\u76f4\u63a5\u83b7\u53d6\u8001\u5e08\u5bf9\u8c61\u4e0b\u6240\u6709\u7684\u8bfe\u7a0b\u3002 \u4ece\u8001\u5e08\u5bf9\u8c61\u4e2d\uff0c\u8c03\u7528\u67e5\u770b\u8bfe\u7a0b\u4e0b\u5b66\u751f\u65b9\u6cd5\uff0c\u83b7\u53d6\u8bfe\u7a0b\u5bf9\u8c61\u4e0b\u6240\u6709\u7684\u5b66\u751f\uff0c\u8fd4\u56de\u7ed9\u89c6\u56fe\u5c42\u3002 \u89c6\u56fe\u5c42\u6253\u5370\u6539\u8bfe\u7a0b\u4e0b\u6240\u6709\u7684\u5b66\u751f\uff0c\u5e76\u8ba9\u7528\u6237\u9009\u62e9\u9700\u8981\u5206\u6570\u7684\u5b66\u751f\u3002 \u55f2\u7528\u8001\u5e08\u4fee\u6539\u5206\u6570\u63a5\u53e3\uff0c\u83b7\u53d6\u8001\u5e08\u5bf9\u8c61\uff0c\u8c03\u7528\u5bf9\u8c61\u4e2d\u4fee\u6539\u5206\u6570\u65b9\u6cd5\u3002 \u83b7\u53d6\u5b66\u751f\u5bf9\u8c61\u4e2d\u7684\u5206\u6570\u5b57\u5178\uff0c\u8fdb\u884c\u4fee\u6539\u3002","title":"3.5.\u4fee\u6539\u5b66\u751f\u5206\u6570"},{"location":"python/Demo/CourseSystem/#34_1","text":"","title":"3.4.\u67e5\u770b\u6210\u7ee9"},{"location":"python/Demo/CourseSystem/#_7","text":"","title":"\u793a\u610f\u56fe"},{"location":"python/Demo/CourseSystem/#_8","text":"\u4ee3\u7801","title":"\u53c2\u8003\u4ee3\u7801"},{"location":"python/Foundation/ch00/","text":"Python\u5b89\u88c5 \u00b6 Python\u73af\u5883 \u00b6 \u8fd9\u91cc\u4f7f\u7528\u7cfb\u7edf\u81ea\u5e26\u7684Python\u73af\u5883\uff1a \u4e3b\u673a\uff1aVMWare\u865a\u62df\u673a \u64cd\u4f5c\u7cfb\u7edf(Guest)\uff1aopenSUSE 15.3 Python\u7248\u672c\uff1a3.6.15(openSUSE\u81ea\u5e26) \u68c0\u67e5Python\u7248\u672c \u00b6 $ python --version Python 2 .7.18 $ python3 --version Python 3 .6.15 \u5347\u7ea7pip \u00b6 $ pip3 install --upgrade pip $ pip --version pip 21 .3.1 from /home/james/.local/lib/python3.6/site-packages/pip ( python 3 .6 ) $ pip3 --version pip 21 .3.1 from /home/james/.local/lib/python3.6/site-packages/pip ( python 3 .6 ) pip\u56fd\u5185\u6e90 \u00b6 https://mirrors.aliyun.com/pypi/simple/ https://pypi.tuna.tsinghua.edu.cn/simple/ http://pypi.doubanio.com/simple/ https://mirrors.cloud.tencent.com/pypi/simple/ \u5b89\u88c5Python\u5305(\u6307\u5b9a\u6e90) \u00b6 pip3 install jinja2 -i https://mirrors.aliyun.com/pypi/simple/ pip3 install Django -i https://mirrors.aliyun.com/pypi/simple/ pip3 install sqlite_utils -i https://mirrors.aliyun.com/pypi/simple/ pip3 install pymongo -i https://mirrors.aliyun.com/pypi/simple/ pip3 install numpy -i https://mirrors.aliyun.com/pypi/simple/ pip3 install matplotlib -i https://mirrors.aliyun.com/pypi/simple/ pip3 install scikit-learn -i https://mirrors.aliyun.com/pypi/simple/ pip3 install xlrd -i https://mirrors.aliyun.com/pypi/simple/ pip3 install pandas -i https://mirrors.aliyun.com/pypi/simple/ pip3 install pydotplus -i https://mirrors.aliyun.com/pypi/simple/ pip3 install seaborn -i https://mirrors.aliyun.com/pypi/simple/ pip3 install selenium -i https://mirrors.aliyun.com/pypi/simple/ pip3 install mlxtend -i https://mirrors.aliyun.com/pypi/simple/ pip3 install pandas-datareader -i https://mirrors.aliyun.com/pypi/simple/ pip3 install lxml -i https://mirrors.aliyun.com/pypi/simple/ pip3 install beautifulsoup4 -i https://mirrors.aliyun.com/pypi/simple/ pip3 install html5lib -i https://mirrors.aliyun.com/pypi/simple/ pip3 install tables -i https://mirrors.aliyun.com/pypi/simple/ pip3 install openpyxl -i https://mirrors.aliyun.com/pypi/simple/ pip3 install sqlalchemy -i https://mirrors.aliyun.com/pypi/simple/ pip3 install statsmodels -i https://mirrors.aliyun.com/pypi/simple/ pip3 install patsy -i https://mirrors.aliyun.com/pypi/simple/ pip3 install numba -i https://mirrors.aliyun.com/pypi/simple/ pip3 install jason -i https://mirrors.aliyun.com/pypi/simple/ pip3 install openpyxl -i https://mirrors.aliyun.com/pypi/simple/ \u6e90\u7801\u7f16\u8bd1\u65b9\u6cd5 \u00b6 \u4e0b\u9762\u662f\u6e90\u7801\u7f16\u8bd1\u65b9\u5f0f\u81ea\u884c\u5b89\u88c5Python\u7684\u65b9\u6cd5\uff0c\u4ee53.9.6\u7248\u672c\u4e3a\u4f8b\u3002 \u5b98\u7f51\u4e0b\u8f7dpython3.9.6 \uff08 \u8fde\u63a5 \uff09 \u89e3\u538b\u5b89\u88c5\u5305 tar xvf Python-3.9.6.tgz \u5b89\u88c5\u8def\u5f84\u4e3a /opt/Python-3.9.6/ \uff0c\u9700\u8981\u628a\u5b89\u88c5\u8def\u5f84\u7684owner\u6539\u4e3a\u5f53\u524d\u7528\u6237\uff0c\u5426\u5219\u540e\u671fpython\u7f16\u8bd1\u4ee5\u53ca\u4f7f\u7528pip\u5b89\u88c5python\u5305\u4f1a\u62a5\u9519\u3002 chown -R james.wheel /opt/Python-3.9.6 \u5728\u5b89\u88c5\u524d\u7684\u4e00\u4e9b\u5efa\u8bae \u5728openSUSE\u4e2d\u628a\u5f00\u53d1\u5305\u90fd\u5b89\u88c5\u4e00\u4e0b\uff0c\u7279\u522b\u662fc\u548cc++\u7684\u5f00\u53d1\u5305\u3002\u8fd9\u4e9b\u90fd\u662fPython\u7f16\u8bd1\u7684\u4f9d\u8d56\u5305\u3002 \u5728openSUSE\u4e2d\u5b89\u88c5sqlite3. \u4f7f\u7528openSUSE\u81ea\u5e26\u7684openSSL\uff0c\u5982\u679c\u81ea\u884c\u7f16\u8bd1openSSL\uff0c\u5728\u7f16\u8bd1Python\u65f6\u4f1a\u9047\u5230\u4e00\u4e9b\u672a\u77e5\u95ee\u9898\u3002 \u7f16\u8bd1\u548c\u5b89\u88c5\uff1a cd /opt/Python-3.9.6 sudo ./configure --enable-optimizations --with-ensurepip = install sudo make sudo make test sudo make install \u4fee\u6539\u7cfb\u7edf\u9ed8\u8ba4Python\u7684\u914d\u7f6e\uff0c\u5c06python3\u6307\u5411\u65b0\u5b89\u88c5\u7684Python\u3002\u9700\u8981\u4fee\u6539\u7684\u8def\u5f84\u67092\u4e2a\uff0c /usr/bin/python3 \u548c /usr/local/bin/ \u5c06 /usr/bin/python3 \u91cd\u65b0\u6307\u5411\u65b0\u5b89\u88c5\u7684Python\u3002 sudo rm /usr/bin/python3 sudo ln -s /opt/Python-3.9.6/python /usr/bin/python3 \u68c0\u67e5 /usr/local/bin/ \u76ee\u5f55\u4e0b\u7684python\u6587\u4ef6\u662f\u5426\u6307\u5411\u65b0\u5b89\u88c5\u7684Pyton\u3002\u9ed8\u8ba4\u662f\u7f16\u8bd1\u5b89\u88c5\u5b8c\u6210\u540e\u5df2\u7ecf\u88ab\u4fee\u6539\u4e86\u3002 $ ls -l /usr/local/bin/python* lrwxrwxrwx 1 root root 9 Jul 25 02 :15 python3 -> python3.9 -rwxr-xr-x 1 root root 17645928 Jul 25 02 :14 python3.9 -rwxr-xr-x 1 root root 3087 Jul 25 02 :15 python3.9-config lrwxrwxrwx 1 root root 16 Jul 25 02 :15 python3-config -> python3.9-config \u9a8c\u8bc1python\u7684\u7248\u672c\u3002 $ python Python 2 .7.18 ( default, Mar 04 2021 , 23 :25:57 ) [ GCC ] on linux2 $ python3 Python 3 .9.6 ( default, Jul 25 2021 , 02 :13:27 ) [ GCC 7 .5.0 ] on linux \u6dfb\u52a0\u4e0b\u9762\u7684\u73af\u5883\u53d8\u91cf\u5230\u914d\u7f6e\u6587\u4ef6 /etc/profile.local \u3002 export PATH = /usr/local/bin:/home/ $USER /.local/bin: $PATH \u5e76\u6267\u884c\u4e0b\u9762\u7684\u547d\u4ee4\u4f7f\u4e4b\u751f\u6548\u3002 source /etc/profile.local \u4e0b\u9762\u4fee\u6539pip\u7684\u914d\u7f6e\u3002 $ whereis pip pip: /usr/bin/pip /usr/bin/pip3.6 /usr/local/bin/pip3.9 \u901a\u8fc7\u4e0b\u9762\u53ef\u4ee5\u770b\u5230pip\u5b9e\u9645\u6307\u5411\u7684\u662f\u7cfb\u7edf\u9ed8\u8ba4\u76843.6\u7248\u672c\u3002 $ l /usr/bin/pip* lrwxrwxrwx 1 root root 21 Dec 4 2020 /usr/bin/pip -> /etc/alternatives/pip* -rwxr-xr-x 1 root root 367 Dec 4 2020 /usr/bin/pip3* -rwxr-xr-x 1 root root 371 Dec 4 2020 /usr/bin/pip3.6* -rwxr-xr-x 1 root root 10608 Jun 10 06 :15 /usr/bin/pipewire* -rwxr-xr-x 1 root root 720208 Jun 10 06 :15 /usr/bin/pipewire-media-session* james@lizard:/opt> l /etc/alternatives/pip* lrwxrwxrwx 1 root root 15 Jul 24 20 :24 /etc/alternatives/pip -> /usr/bin/pip3.6* \u68c0\u67e5\u4e00\u4e0b\u5f53\u524dpip\u5728alternative\u91cc\u9762\u7684\u8bbe\u7f6e\u3002 $ sudo update-alternatives --display pip pip - auto mode link best version is /usr/bin/pip3.6 link currently points to /usr/bin/pip3.6 link pip is /usr/bin/pip /usr/bin/pip3.6 - priority 36 \u5220\u9664\u8001\u7248\u672c\uff0c\u6dfb\u52a0\u65b0\u7248\u672c\u3002 $ sudo update-alternatives --remove pip /usr/bin/pip3.6 $ sudo update-alternatives --install /usr/bin/pip pip /usr/bin/pip3.9 100 update-alternatives: using /usr/bin/pip3.9 to provide /usr/bin/pip ( pip ) in auto mode","title":"Python\u5b89\u88c5"},{"location":"python/Foundation/ch00/#python","text":"","title":"Python\u5b89\u88c5"},{"location":"python/Foundation/ch00/#python_1","text":"\u8fd9\u91cc\u4f7f\u7528\u7cfb\u7edf\u81ea\u5e26\u7684Python\u73af\u5883\uff1a \u4e3b\u673a\uff1aVMWare\u865a\u62df\u673a \u64cd\u4f5c\u7cfb\u7edf(Guest)\uff1aopenSUSE 15.3 Python\u7248\u672c\uff1a3.6.15(openSUSE\u81ea\u5e26)","title":"Python\u73af\u5883"},{"location":"python/Foundation/ch00/#python_2","text":"$ python --version Python 2 .7.18 $ python3 --version Python 3 .6.15","title":"\u68c0\u67e5Python\u7248\u672c"},{"location":"python/Foundation/ch00/#pip","text":"$ pip3 install --upgrade pip $ pip --version pip 21 .3.1 from /home/james/.local/lib/python3.6/site-packages/pip ( python 3 .6 ) $ pip3 --version pip 21 .3.1 from /home/james/.local/lib/python3.6/site-packages/pip ( python 3 .6 )","title":"\u5347\u7ea7pip"},{"location":"python/Foundation/ch00/#pip_1","text":"https://mirrors.aliyun.com/pypi/simple/ https://pypi.tuna.tsinghua.edu.cn/simple/ http://pypi.doubanio.com/simple/ https://mirrors.cloud.tencent.com/pypi/simple/","title":"pip\u56fd\u5185\u6e90"},{"location":"python/Foundation/ch00/#python_3","text":"pip3 install jinja2 -i https://mirrors.aliyun.com/pypi/simple/ pip3 install Django -i https://mirrors.aliyun.com/pypi/simple/ pip3 install sqlite_utils -i https://mirrors.aliyun.com/pypi/simple/ pip3 install pymongo -i https://mirrors.aliyun.com/pypi/simple/ pip3 install numpy -i https://mirrors.aliyun.com/pypi/simple/ pip3 install matplotlib -i https://mirrors.aliyun.com/pypi/simple/ pip3 install scikit-learn -i https://mirrors.aliyun.com/pypi/simple/ pip3 install xlrd -i https://mirrors.aliyun.com/pypi/simple/ pip3 install pandas -i https://mirrors.aliyun.com/pypi/simple/ pip3 install pydotplus -i https://mirrors.aliyun.com/pypi/simple/ pip3 install seaborn -i https://mirrors.aliyun.com/pypi/simple/ pip3 install selenium -i https://mirrors.aliyun.com/pypi/simple/ pip3 install mlxtend -i https://mirrors.aliyun.com/pypi/simple/ pip3 install pandas-datareader -i https://mirrors.aliyun.com/pypi/simple/ pip3 install lxml -i https://mirrors.aliyun.com/pypi/simple/ pip3 install beautifulsoup4 -i https://mirrors.aliyun.com/pypi/simple/ pip3 install html5lib -i https://mirrors.aliyun.com/pypi/simple/ pip3 install tables -i https://mirrors.aliyun.com/pypi/simple/ pip3 install openpyxl -i https://mirrors.aliyun.com/pypi/simple/ pip3 install sqlalchemy -i https://mirrors.aliyun.com/pypi/simple/ pip3 install statsmodels -i https://mirrors.aliyun.com/pypi/simple/ pip3 install patsy -i https://mirrors.aliyun.com/pypi/simple/ pip3 install numba -i https://mirrors.aliyun.com/pypi/simple/ pip3 install jason -i https://mirrors.aliyun.com/pypi/simple/ pip3 install openpyxl -i https://mirrors.aliyun.com/pypi/simple/","title":"\u5b89\u88c5Python\u5305(\u6307\u5b9a\u6e90)"},{"location":"python/Foundation/ch00/#_1","text":"\u4e0b\u9762\u662f\u6e90\u7801\u7f16\u8bd1\u65b9\u5f0f\u81ea\u884c\u5b89\u88c5Python\u7684\u65b9\u6cd5\uff0c\u4ee53.9.6\u7248\u672c\u4e3a\u4f8b\u3002 \u5b98\u7f51\u4e0b\u8f7dpython3.9.6 \uff08 \u8fde\u63a5 \uff09 \u89e3\u538b\u5b89\u88c5\u5305 tar xvf Python-3.9.6.tgz \u5b89\u88c5\u8def\u5f84\u4e3a /opt/Python-3.9.6/ \uff0c\u9700\u8981\u628a\u5b89\u88c5\u8def\u5f84\u7684owner\u6539\u4e3a\u5f53\u524d\u7528\u6237\uff0c\u5426\u5219\u540e\u671fpython\u7f16\u8bd1\u4ee5\u53ca\u4f7f\u7528pip\u5b89\u88c5python\u5305\u4f1a\u62a5\u9519\u3002 chown -R james.wheel /opt/Python-3.9.6 \u5728\u5b89\u88c5\u524d\u7684\u4e00\u4e9b\u5efa\u8bae \u5728openSUSE\u4e2d\u628a\u5f00\u53d1\u5305\u90fd\u5b89\u88c5\u4e00\u4e0b\uff0c\u7279\u522b\u662fc\u548cc++\u7684\u5f00\u53d1\u5305\u3002\u8fd9\u4e9b\u90fd\u662fPython\u7f16\u8bd1\u7684\u4f9d\u8d56\u5305\u3002 \u5728openSUSE\u4e2d\u5b89\u88c5sqlite3. \u4f7f\u7528openSUSE\u81ea\u5e26\u7684openSSL\uff0c\u5982\u679c\u81ea\u884c\u7f16\u8bd1openSSL\uff0c\u5728\u7f16\u8bd1Python\u65f6\u4f1a\u9047\u5230\u4e00\u4e9b\u672a\u77e5\u95ee\u9898\u3002 \u7f16\u8bd1\u548c\u5b89\u88c5\uff1a cd /opt/Python-3.9.6 sudo ./configure --enable-optimizations --with-ensurepip = install sudo make sudo make test sudo make install \u4fee\u6539\u7cfb\u7edf\u9ed8\u8ba4Python\u7684\u914d\u7f6e\uff0c\u5c06python3\u6307\u5411\u65b0\u5b89\u88c5\u7684Python\u3002\u9700\u8981\u4fee\u6539\u7684\u8def\u5f84\u67092\u4e2a\uff0c /usr/bin/python3 \u548c /usr/local/bin/ \u5c06 /usr/bin/python3 \u91cd\u65b0\u6307\u5411\u65b0\u5b89\u88c5\u7684Python\u3002 sudo rm /usr/bin/python3 sudo ln -s /opt/Python-3.9.6/python /usr/bin/python3 \u68c0\u67e5 /usr/local/bin/ \u76ee\u5f55\u4e0b\u7684python\u6587\u4ef6\u662f\u5426\u6307\u5411\u65b0\u5b89\u88c5\u7684Pyton\u3002\u9ed8\u8ba4\u662f\u7f16\u8bd1\u5b89\u88c5\u5b8c\u6210\u540e\u5df2\u7ecf\u88ab\u4fee\u6539\u4e86\u3002 $ ls -l /usr/local/bin/python* lrwxrwxrwx 1 root root 9 Jul 25 02 :15 python3 -> python3.9 -rwxr-xr-x 1 root root 17645928 Jul 25 02 :14 python3.9 -rwxr-xr-x 1 root root 3087 Jul 25 02 :15 python3.9-config lrwxrwxrwx 1 root root 16 Jul 25 02 :15 python3-config -> python3.9-config \u9a8c\u8bc1python\u7684\u7248\u672c\u3002 $ python Python 2 .7.18 ( default, Mar 04 2021 , 23 :25:57 ) [ GCC ] on linux2 $ python3 Python 3 .9.6 ( default, Jul 25 2021 , 02 :13:27 ) [ GCC 7 .5.0 ] on linux \u6dfb\u52a0\u4e0b\u9762\u7684\u73af\u5883\u53d8\u91cf\u5230\u914d\u7f6e\u6587\u4ef6 /etc/profile.local \u3002 export PATH = /usr/local/bin:/home/ $USER /.local/bin: $PATH \u5e76\u6267\u884c\u4e0b\u9762\u7684\u547d\u4ee4\u4f7f\u4e4b\u751f\u6548\u3002 source /etc/profile.local \u4e0b\u9762\u4fee\u6539pip\u7684\u914d\u7f6e\u3002 $ whereis pip pip: /usr/bin/pip /usr/bin/pip3.6 /usr/local/bin/pip3.9 \u901a\u8fc7\u4e0b\u9762\u53ef\u4ee5\u770b\u5230pip\u5b9e\u9645\u6307\u5411\u7684\u662f\u7cfb\u7edf\u9ed8\u8ba4\u76843.6\u7248\u672c\u3002 $ l /usr/bin/pip* lrwxrwxrwx 1 root root 21 Dec 4 2020 /usr/bin/pip -> /etc/alternatives/pip* -rwxr-xr-x 1 root root 367 Dec 4 2020 /usr/bin/pip3* -rwxr-xr-x 1 root root 371 Dec 4 2020 /usr/bin/pip3.6* -rwxr-xr-x 1 root root 10608 Jun 10 06 :15 /usr/bin/pipewire* -rwxr-xr-x 1 root root 720208 Jun 10 06 :15 /usr/bin/pipewire-media-session* james@lizard:/opt> l /etc/alternatives/pip* lrwxrwxrwx 1 root root 15 Jul 24 20 :24 /etc/alternatives/pip -> /usr/bin/pip3.6* \u68c0\u67e5\u4e00\u4e0b\u5f53\u524dpip\u5728alternative\u91cc\u9762\u7684\u8bbe\u7f6e\u3002 $ sudo update-alternatives --display pip pip - auto mode link best version is /usr/bin/pip3.6 link currently points to /usr/bin/pip3.6 link pip is /usr/bin/pip /usr/bin/pip3.6 - priority 36 \u5220\u9664\u8001\u7248\u672c\uff0c\u6dfb\u52a0\u65b0\u7248\u672c\u3002 $ sudo update-alternatives --remove pip /usr/bin/pip3.6 $ sudo update-alternatives --install /usr/bin/pip pip /usr/bin/pip3.9 100 update-alternatives: using /usr/bin/pip3.9 to provide /usr/bin/pip ( pip ) in auto mode","title":"\u6e90\u7801\u7f16\u8bd1\u65b9\u6cd5"},{"location":"python/Foundation/ch01/","text":"Python\u8bed\u8a00\u57fa\u7840 \u00b6 1. Python\u6570\u636e\u7c7b\u578b\uff086\u4e2a\uff09 \u00b6 6\u4e2aPython\u6570\u636e\u7c7b\u578b\uff1a \u6570\u503c\u578b\uff08number\uff09\uff1a\u8868\u793a\u6570\u636e\u7ec4\u6210\u4e3a\u6570\u5b57 \u6574\u578b\uff08int\uff09 \u5341\u8fdb\u5236 \u516b\u8fdb\u5236 \u5341\u516d\u8fdb\u5236 \u6d6e\u70b9\u578b\uff08float\uff09 \u5e03\u5c14\u578b\uff08bool\uff09 \u590d\u6570\u6027\uff08complex\uff09 \u5b57\u7b26\u578b\uff08string\uff09\uff1a\u8868\u793a\u6570\u636e\u7ec4\u6210\u662f\u5b57\u7b26 \u5217\u8868\uff08list\uff09\uff1a\u7528\u6765\u8868\u793a\u4e00\u7ec4\u6709\u5e8f\u5143\u7d20\uff0c\u540e\u671f\u6570\u636e\u53ef\u4ee5\u4fee\u6539 ['A','B','C'] \u5143\u7ec4\uff08tuple\uff09\uff1a\u7528\u6765\u8868\u793a\u4e00\u7ec4\u6709\u5e8f\u5143\u7d20\uff0c\u540e\u671f\u6570\u636e\u4e0d\u53ef\u4fee\u6539 ('A','B','C','1') \u96c6\u5408\uff08set\uff09\uff1a\u4e00\u7ec4\u6570\u636e\u65e0\u5e8f\u4e0d\u91cd\u590d\u5143\u7d20 set([1,2,3,4]) \u5b57\u5178\uff08dictionary\uff09\uff1a\u7528\u952e\u503c\u5bf9\u7684\u5f62\u5f0f\u4fdd\u5b58\u4e00\u7ec4\u5143\u7d20 {'A':7,'B':1,'C':9} \u53ef\u8fed\u4ee3\u5bf9\u8c61\uff08Iterable\uff09\uff1a An object capable of returning its members one at a time. Examples of iterables include all sequence types (such as list, str, and tuple) and some non-sequence types like dict, file objects, and objects of any classes you define with an iter() method or with a getitem() method that implements Sequence semantics. \u5e8f\u5217\uff08Sequence\uff09\uff1a An iterable which supports efficient element access using integer indices via the getitem() special method and defines a len() method that returns the length of the sequence. Some built-in sequence types are list, str, tuple, and bytes. Note that dict also supports getitem() and len(), but is considered a mapping rather than a sequence because the lookups use arbitrary immutable keys rather than integers. \u8fed\u4ee3\u5668\uff08Iterator\uff09\uff1a An object representing a stream of data. Repeated calls to the iterator\u2019s next() method (or passing it to the built-in function next()) return successive items in the stream. When no more data are available a StopIteration exception is raised instead. At this point, the iterator object is exhausted and any further calls to its next() method just raise StopIteration again. Iterators are required to have an iter() method that returns the iterator object itself so every iterator is also iterable and may be used in most places where other iterables are accepted. One notable exception is code which attempts multiple iteration passes. A container object (such as a list) produces a fresh new iterator each time you pass it to the iter() function or use it in a for loop. Attempting this with an iterator will just return the same exhausted iterator object used in the previous iteration pass, making it appear like an empty container. \u53ef\u53d8\u6570\u636e\uff08immutable\uff09 \u5217\u8868\uff08list\uff09 \u5b57\u5178\uff08dictionary\uff09 \u96c6\u5408\uff08set\uff09\u3002 \u4e0d\u53ef\u53d8\u6570\u636e\uff08immutable\uff09 \u6570\u5b57\uff08number\uff09 \u5b57\u7b26\uff08string\uff09 \u5143\u7ec4\uff08tuple\uff09 \u53ef\u8fed\u4ee3\uff08iterable\uff09 \u5b57\u7b26\uff08string\uff09 \u5143\u7ec4\uff08tuple\uff09 \u5217\u8868\uff08list\uff09 \u5b57\u5178\uff08dictionary\uff09 \u96c6\u5408\uff08set\uff09 \u5e8f\u5217 \u6709\u5e8f\u5e8f\u5217\uff1a\u5b57\u7b26\uff08string\uff09\uff0c\u5143\u7ec4\uff08tuple\uff09\uff0c\u5217\u8868\uff08list\uff09 \u65e0\u5e8f\u5e8f\u5217\uff1a\u5b57\u5178\uff08dictionary\uff09\uff0c\u96c6\u5408\uff08set\uff09 Python\u5e8f\u5217\u7c7b\u578b\u6700\u5e38\u89c1\u7684\u5206\u7c7b\u5c31\u662f\u53ef\u53d8\u548c\u4e0d\u53ef\u53d8\u5e8f\u5217\u3002\u4f46\u53e6\u5916\u4e00\u79cd\u5206\u7c7b\u65b9\u5f0f\u4e5f\u5f88\u6709\u7528\uff0c\u90a3\u5c31\u662f\u628a\u5b83\u4eec\u5206\u4e3a**\u6241\u5e73\u5e8f\u5217**\u548c**\u5bb9\u5668\u5e8f\u5217**\u3002\u524d\u8005\u7684\u4f53\u79ef\u66f4\u5c0f\u3001\u901f\u5ea6\u66f4\u5feb\u800c\u4e14\u7528\u8d77\u6765\u66f4\u7b80\u5355\uff0c\u4f46\u662f\u5b83\u53ea\u80fd\u4fdd\u5b58\u4e00\u4e9b\u539f\u5b50\u6027\u7684\u6570\u636e\uff0c\u6bd4\u5982\u6570\u5b57\u3001\u5b57\u7b26\u548c\u5b57\u8282\u3002\u5bb9\u5668\u5e8f\u5217\u5219\u6bd4\u8f83\u7075\u6d3b\uff0c\u4f46\u662f\u5f53\u5bb9\u5668\u5e8f\u5217\u9047\u5230\u53ef\u53d8\u5bf9\u8c61\u65f6\uff0c\u5c31\u9700\u8981\u683c\u5916\u5c0f\u5fc3\uff0c\u56e0\u4e3a\u8fd9\u79cd\u7ec4\u5408\u65f6\u5e38\u4f1a\u51fa\u73b0\u4e00\u4e9b\u201c\u610f\u5916\u201d\uff0c\u7279\u522b\u662f\u5e26\u5d4c\u5957\u7684\u6570\u636e\u7ed3\u6784\u51fa\u73b0\u65f6\uff0c\u66f4\u9700\u8981\u9a8c\u8bc1\u4ee3\u7801\u7684\u6b63\u786e\u6027\u3002 Python\u4e2d\u7684\u53d8\u91cf\u3001\u5e38\u91cf\u548c\u5b57\u9762\u91cf \u53d8\u91cf \u53d8\u91cf\u662f\u7528\u4e8e\u5728\u5185\u5b58\u4e2d\u5b58\u50a8\u6570\u636e\u7684\u547d\u540d\u4f4d\u7f6e\u3002\u53ef\u4ee5\u5c06\u53d8\u91cf\u89c6\u4e3a\u4fdd\u5b58\u6570\u636e\u7684\u5bb9\u5668\uff0c\u8fd9\u4e9b\u6570\u636e\u53ef\u4ee5\u5728\u540e\u9762\u7a0b\u5e8f\u4e2d\u8fdb\u884c\u66f4\u6539\u3002\u4f8b\u5982\uff1a number = 10 \u3002\u4ece\u4f8b\u5b50\u4e2d\u53ef\u4ee5\u770b\u5230\uff0cPython\u4f7f\u7528\u8d4b\u503c\u8fd0\u7b97\u7b26 = \u4e3a\u53d8\u91cf\u8d4b\u503c\u3002 \u5e38\u91cf \u5e38\u91cf\u4e5f\u662f\u4e00\u79cd\u53d8\u91cf\uff0c\u53ea\u662f\u5176\u503c\u4e00\u65e6\u8d4b\u4e88\u540e\u65e0\u6cd5\u66f4\u6539\u3002\u53ef\u4ee5\u5c06\u5e38\u91cf\u89c6\u4e3a\u4fdd\u5b58\u4e86\u4ee5\u540e\u65e0\u6cd5\u66f4\u6539\u7684\u4fe1\u606f\u7684\u5bb9\u5668\u3002 \u5728Python\u4e2d\uff0c\u5e38\u91cf\u901a\u5e38\u662f\u5728\u6a21\u5757\u4e2d\u58f0\u660e\u548c\u5206\u914d\u7684\u3002\u5728\u8fd9\u91cc\uff0c\u6a21\u5757\u662f\u4e00\u4e2a\u5305\u542b\u53d8\u91cf\uff0c\u51fd\u6570\u7b49\u7684\u65b0\u6587\u4ef6\uff0c\u8be5\u6587\u4ef6\u88ab\u5bfc\u5165\u5230\u4e3b\u6587\u4ef6\u4e2d\u3002\u5728\u6a21\u5757\u5185\u90e8\uff0c\u7528\u6240\u6709\u5927\u5199\u5b57\u6bcd\u5199\u7684\u5e38\u91cf\u548c\u4e0b\u5212\u7ebf\u5c06\u5355\u8bcd\u5206\u5f00\u3002\u5b9e\u9645\u4e0a\uff0c\u6211\u4eec\u4e0d\u5728Python\u4e2d\u4f7f\u7528\u5e38\u91cf\u3002\u7528\u5927\u5199\u5b57\u6bcd\u547d\u540d\u5b83\u4eec\u662f\u4e00\u79cd\u5c06\u5176\u4e0e\u666e\u901a\u53d8\u91cf\u5206\u5f00\u7684\u4e00\u79cd\u7ea6\u5b9a\uff0c\u4f46\u662f\uff0c\u5b9e\u9645\u4e0a\u5e76\u4e0d\u80fd\u963b\u6b62\u91cd\u65b0\u5206\u914d\u3002 \u5b57\u9762\u91cf\uff08literal\uff09 \u5b57\u9762\u91cf\u662f\u4ee5\u53d8\u91cf\u6216\u5e38\u91cf\u7ed9\u51fa\u7684\u539f\u59cb\u6570\u636e\uff08\u5176\u5b9e\u5c31\u662f\u6307\u53d8\u91cf\u7684\u5e38\u6570\u503c\uff0c\u5b57\u9762\u4e0a\u6240\u770b\u5230\u7684\u503c\uff09\u3002\u5728Python\u4e2d\u5b57\u9762\u91cf\u7c7b\u578b\u5982\u4e0b\uff1a \u6570\u5b57\u5b57\u9762\u91cf\u3002\u6570\u5b57\u5b57\u9762\u91cf\u662f\u4e0d\u53ef\u53d8\u7684\uff08\u4e0d\u53ef\u66f4\u6539\uff09\u3002\u6570\u5b57\u5b57\u9762\u91cf\u53ef\u4ee5\u5c5e\u4e8e3\u79cd\u4e0d\u540c\u7684\u6570\u503c\u7c7b\u578b\uff1aInteger\uff0cFloat \u548c Complex\u3002\u4f8b\u5982\uff1a float_1 = 10.5 \u662f\u5c5e\u4e8eFloat\u5b57\u9762\u91cf\u3002 \u5b57\u7b26\u4e32\u5b57\u9762\u91cf\u662f\u7531\u5f15\u53f7\u62ec\u8d77\u6765\u7684\u4e00\u7cfb\u5217\u5b57\u7b26\u3002\u6211\u4eec\u53ef\u4ee5\u5bf9\u5b57\u7b26\u4e32\u4f7f\u7528\u5355\u5f15\u53f7\uff0c\u53cc\u5f15\u53f7 \u6216 \u4e09\u5f15\u53f7\u3002\u5e76\u4e14\uff0c\u5b57\u7b26\u5b57\u9762\u91cf\u662f\u7528\u5355\u5f15\u53f7\u6216\u53cc\u5f15\u53f7\u5f15\u8d77\u6765\u7684\u5355\u4e2a\u5b57\u7b26\u3002\u4f8b\u5982\uff1a strings = \"This is Python\" \u3002 \u5e03\u5c14\u5b57\u9762\u91cf\u3002\u5e03\u5c14\u5b57\u9762\u91cf\u53ef\u4ee5\u5177\u6709\u4e24\u4e2a\u503c\u4e2d\u7684\u4efb\u4f55\u4e00\u4e2a\uff1a True \u6216 False \u3002\u4f8b\u5982\uff1a a = True + 4 \u3002 \u7279\u6b8a\u5b57\u9762\u91cf\u3002Python\u5305\u542b\u4e00\u4e2a\u7279\u6b8a\u5b57\u9762\u91cf\uff0c\u5373 None \u3002 \u5b57\u9762\u91cf\u96c6\u3002\u6709\u56db\u79cd\u4e0d\u540c\u7684\u5b57\u9762\u91cf\u96c6\u5408\uff1a\u5217\u8868\u5b57\u9762\u91cf\uff0c\u5143\u7ec4\u5b57\u9762\u91cf\uff0c\u5b57\u5178\u5b57\u9762\u91cf \u548c \u96c6\u5408\u5b57\u9762\u91cf\u3002 1.1 \u6570\u503c\u578b\uff08number\uff09 \u00b6 \u4f8b\u5b50\uff1a a , b , c , d = 20 , 5.5 , True , 4 + 3 j print ( a , b , c , d ) # 20 5.5 True (4+3j) print ( type ( a ), type ( b ), type ( c ), type ( d )) # Python\u4e5f\u53ef\u4ee5\u8fd9\u6837\u8d4b\u503c\uff1a a = b = c = d = 1 print ( a , b , c , d ) # 1 1 1 1 \u8fdb\u5236\u8f6c\u6362\uff1a a = - 15 print ( f ' { a } \u5bf9\u5e94\u7684\u5341\u8fdb\u5236\u662f { a } , \u4e8c\u8fdb\u5236\u662f { a : b } , \u516b\u8fdb\u5236\u662f { a : o } , \u5341\u516d\u8fdb\u5236\u662f { a : x } ' ) 1.2 \u5b57\u7b26\u578b\uff08string\uff09 \u00b6 \u5355\u5f15\u53f7\uff1a\u5185\u5bb9\u4e2d\u5305\u542b\u5927\u91cf\u53cc\u5f15\u53f7 \u53cc\u5f15\u53f7\uff1a\u5185\u5bb9\u4e2d\u5305\u542b\u5927\u91cf\u5355\u5f15\u53f7 \u4e09\u5f15\u53f7\uff1a\u5185\u5bb9\u4e2d\u540c\u65f6\u5305\u542b\u5355\u53cc\u5f15\u53f7\uff0c\u4e09\u4e2a\u5355\u5f15\u53f7\u6bd4\u8f83\u597d\u3002 a = 'string is \"special\"' b = \"string's value\" c = '''string's value is \"special\"''' d = \"\"\"string's context \"\"\" \u5b57\u7b26\u4e32\u5e38\u7528\u65b9\u6cd5 \u00b6 \u5b57\u7b26\u4e32\u5207\u7247 s = 'Python is very good' print ( s [ 2 : 4 ]) # th print ( s [ 5 ]) # n print ( s [ - 1 ]) # d print ( s [ - 3 : - 1 ]) # oo # \u975e\u8fed\u4ee3\u578b\uff0c\u4e0d\u53ef\u4fee\u6539 s [ 3 ] = 'b' # Traceback (most recent call last): # File \"\", line 1, in # TypeError: 'str' object does not support item assignment \u5b57\u7b26\u4e32\u5408\u5e76 print ( s + '!!!' ) # Python is very good!!! replace( a,b \u5c06\u5b57\u7b26\u4e32\u4e2d\u7684 a \u66ff\u6362\u6210 b print ( s . replace ( 'is' , 'we' )) # Python we very good find(str) : \u8fd4\u56de str \u51fa\u73b0\u7684\u7d22\u5f15\u4f4d\u7f6e\uff0c\u5982\u679c\u627e\u4e0d\u5230\u8be5\u503c\uff0c\u5219 find() \u65b9\u6cd5\u5c06\u8fd4\u56de -1\u3002 print ( s . find ( 'a' )) # -1 print ( s . find ( 's' )) # 8 str.index(a): \u67e5\u627e\u6307\u5b9a\u503c\u7684\u9996\u6b21\u51fa\u73b0\u3002\u5982\u679c\u627e\u4e0d\u5230\u8be5\u503c\uff0cindex() \u65b9\u6cd5\u5c06\u5f15\u53d1\u5f02\u5e38\u3002 print ( s . index ( 's' )) # 8 print ( s . index ( 'a' )) # Traceback (most recent call last): # File \"\", line 1, in # ValueError: substring not found str.count(a): \u7edf\u8ba1\u5b57\u7b26\u4e32\u4e2d a \u51fa\u73b0\u7684\u6b21\u6570 print ( s . count ( 'a' )) # 0 print ( s . count ( 'o' )) # 3 split: \u5bf9\u5b57\u7b26\u4e32\u8fdb\u884c\u5206\u5272\u3002\u5982\u679c\u53c2\u6570 num \u6709\u6307\u5b9a\u503c\uff0c\u5219\u5206\u9694 num+1 \u4e2a\u5b50\u5b57\u7b26\u4e32\u3002 # \u6309\u7a7a\u683c\u5206\u5272 print ( s . split ( ' ' )) # ['Python', 'is', 'very', 'good'] # \u6309\u7a7a\u683c\u5206\u5272\u62102\u4e2a\u5b50\u5b57\u7b26\u4e32 print ( s . split ( ' ' , 1 )) # ['Python', 'is very good'] strip: \u79fb\u9664\u5b57\u7b26\u4e32\u9996\u5c3e\u6307\u5b9a\u7684\u5b57\u7b26 \u9ed8\u8ba4\u4e3a\u7a7a\u683c\u3002\u8be5\u65b9\u6cd5\u53ea\u80fd\u5220\u9664\u5f00\u5934\u6216\u662f\u7ed3\u5c3e\u7684\u5b57\u7b26\uff0c\u4e0d\u80fd\u5220\u9664\u4e2d\u95f4\u90e8\u5206\u7684\u5b57\u7b26\u3002 print ( s ) # Python is very good # \u79fb\u9664\u672b\u5c3e\u5b57\u7b26d print ( s . strip ( 'd' )) # Python is very goo endswith (str): \u5224\u65ad\u5b57\u7b26\u4e32\u662f\u5426\u4ee5 str \u7ed3\u5c3e print ( s . endswith ( 'd' )) # True print ( s . endswith ( 'a' )) # False startswith (str): \u5224\u65ad\u5b57\u7b26\u4e32\u662f\u5426\u4ee5 str \u5f00\u5934 print ( s . startswith ( 'p' )) # False print ( s . startswith ( 'P' )) # True isdigit \uff1a\u5224\u65ad\u5b57\u7b26\u4e32\u662f\u5426\u5168\u4e3a\u6570\u5b57 d = '+86-123' print ( d . isdigit ()) # False d = '86123' print ( d . isdigit ()) # True isalpha \uff1a\u5224\u65ad\u5b57\u7b26\u4e32\u662f\u5426\u5168\u4e3a\u5b57\u6bcd b = 'Ab?' print ( b . isalpha ()) # False c = 'Ab' print () c . isalpha () # True \u8f6c\u4e49\u5b57\u7b26 \u00b6 \u4f7f\u7528\u53cd\u659c\u6760\\\u8868\u793a\u8f6c\u4e49\u5b57\u7b26\u3002\u53cd\u659c\u6760\u524d\u9762\u52a0r\u4ee3\u8868\u539f\u59cb\u5b57\u7b26\u3002 a = 'str \\n ing' print ( a ) # str # ing a = r 'str\\ning' print ( a ) # str\\ning \u8f6c\u4e49\u7b26 \u63cf\u8ff0 \\\u5728\u884c\u5c3e \u7eed\u884c\u7b26 \\\\ \u53cd\u659c\u6760\u7b26\u53f7\\ \\' \u5355\u5f15\u53f7 \\b \u9000\u683c(Backspace) \\000 \u7a7a \\n \u6362\u884c \\v \u7eb5\u5411\u5236\u8868\u7b26 \\t \u6a2a\u5411\u5236\u8868\u7b26 \\r \u56de\u8f66\uff0c\u5c06 \\r \u540e\u9762\u7684\u5185\u5bb9\u79fb\u5230\u5b57\u7b26\u4e32\u5f00\u5934\uff0c\u5e76\u9010\u4e00\u66ff\u6362\u5f00\u5934\u90e8\u5206\u7684\u5b57\u7b26\uff0c\u76f4\u81f3\u5c06 \\r \u540e\u9762\u7684\u5185\u5bb9\u5b8c\u5168\u66ff\u6362\u5b8c\u6210\u3002 \\yyy \u516b\u8fdb\u5236\u6570\uff0cy \u4ee3\u8868 0~7 \u7684\u5b57\u7b26 \\xyy \u5341\u516d\u8fdb\u5236\u6570\uff0c\u4ee5 \\x \u5f00\u5934\uff0cy \u4ee3\u8868\u7684\u5b57\u7b26 \u53ef\u8fed\u4ee3\u6027 \u00b6 \u5b57\u7b26\u4e32\u662f\u53ef\u8fed\u4ee3\u7684\u3002\u7d22\u5f15\u503c\u4ece0\u5f00\u59cb\uff0c-1\u4ee3\u8868\u4ece\u672b\u5c3e\u5f00\u59cb\u3002\u7d22\u5f15\u533a\u95f4\u662f\u5de6\u95ed\u53f3\u5f00\u3002 a = 'string is \"special\"' print ( a [ 2 : 4 ]) 'ri' print ( a [ - 4 : - 1 ]) # ial f-string \u00b6 f-string\u662fPython3.6\u63a8\u51fa\u7684\u65b0\u529f\u80fd\u3002\u770b\u4e0b\u9762\u7684\u4f8b\u5b50\uff0c\u5bf9\u6bd4\u4f20\u7edf\u8868\u793a\u65b9\u6cd5\u548cf-string\u7684\u65b9\u6cd5\u3002 age = 32 name = 'Tom' fstring = f 'My name is { name } and I am { age } years old.' print ( fstring ) # My name is Tom and I am 32 years old. \u5728f-string\u4e2d\u4f7f\u7528\u8868\u8fbe\u5f0f\u3002 height = 2 base = 3 fstring = f 'The area of the triangle is { base * height / 2 } .' print ( fstring ) # The area of the triangle is 3.0. \u901a\u8fc7f-string\u5bf9\u5b57\u5178\u8fdb\u884c\u64cd\u4f5c\u3002 person1 = { 'name' : 'Tom' , 'age' : 20 , 'gender' : 'male' } person2 = { 'name' : 'Jerry' , 'age' : 20 , 'gender' : 'female' } # \u8bfb\u53d6\u5b57\u5178 fstring = f ' { person1 . get ( \"name\" ) } is { person1 . get ( \"age\" ) } and is { person1 . get ( \"ender\" ) } ' print ( fstring ) # Tom is 20 and is None # \u904d\u5386\u5b57\u5178 people = [ person1 , person2 ] for person in people : fstring = f ' { person . get ( \"name\" ) } is { person . get ( \"age\" ) } and is { person . get ( \"ender\" ) } ' print ( fstring ) # Tom is 20 and is None # Jerry is 20 and is None \u5728f-string\u4e2d\u4f7f\u7528\u6761\u4ef6\u3002 person1 = { 'name' : 'Tom' , 'age' : 20 , 'gender' : 'male' } person2 = { 'name' : 'Jerry' , 'age' : 20 , 'gender' : 'female' } people = [ person1 , person2 ] for person in people : fstring = f ' { \"She\" if person . get ( \"gender\" ) == \"female\" else \"He\" } is watching TV.' print ( fstring ) # He is watching TV. # She is watching TV. \u4f7f\u7528f-string\u683c\u5f0f\u5316\u8f93\u51fa\u3002 \u5de6\u5bf9\u9f50\uff1a< \u53f3\u5bf9\u9f50\uff1a> \u5c45\u4e2d\u5bf9\u9f50\uff1a^ print ( f ' { \"apple\" : >30 } ' ) print ( f ' { \"apple\" : ^30 } ' ) print ( f ' { \"apple\" : <30 } ' ) # apple # apple # apple \u4f7f\u7528f-string\u683c\u5f0f\u5316\u6570\u5b57\u3002 number = 0.9124325345 # \u767e\u5206\u6bd4 fstring = f 'Percentage format for number with two decimal places: { number : .2% } ' print ( fstring ) # Percentage format for number with two decimal places: 91.24% # \u4fdd\u7559\u5c0f\u6570\u70b9\u540e3\u4f4d fstring = f 'Fixed point format for number with three decimal places: { number : .3f } ' print ( fstring ) # Fixed point format for number with three decimal places: 0.912 # \u79d1\u5b66\u8ba1\u6570\u6cd5\u8868\u793a fstring = f 'Exponent format for number: { number : e } ' print ( fstring ) # Exponent format for number: 9.124325e-01 # \u5e26\u8d27\u5e01\u7b26\u53f7 number = 123456.78921 fstring = f 'Currency format for number with two decimal places: $ { number : .2f } ' print ( fstring ) # Currency format for number with two decimal places: $123456.79 # \u5e26\u8d27\u5e01\u7b26\u53f7\u548c\u5343\u5206\u4f4d number = 123456.78921 fstring = f 'Currency format for number with two decimal places and comma seperators: $ { number : ,.2f } ' print ( fstring ) # Currency format for number with two decimal places and comma seperators: $123,456.79 # \u8f93\u51fa\u6570\u503c\u5e26\u6b63\u8d1f\u7b26\u5408 numbers = [ 1 , - 3 , 5 ] for number in numbers : fstring = f 'The number is { number : + } ' print ( fstring ) # The number is +1 # The number is -3 # The number is +5 # Debug\u8c03\u8bd5 number = 2 print ( f ' { number = } ' ) # number = 2 1.3 \u5217\u8868\uff08list\uff09 \u00b6 \u5217\u8868\u662f Python \u5185\u7f6e\u7684\u4e00\u79cd\u6570\u636e\u7ed3\u6784\uff0c\u662f\u4e00\u79cd\u6709\u5e8f\u7684\u96c6\u5408\uff0c\u7528\u6765\u5b58\u50a8\u4e00\u8fde\u4e32\u5143\u7d20\u7684\u5bb9\u5668\u3002\u5217\u8868\u4e2d\u5143\u7d20\u7c7b\u578b\u53ef\u4ee5\u4e0d\u76f8\u540c\uff0c\u5b83\u652f\u6301\u6570\u5b57\u3001\u5b57\u7b26\u4e32\u7b49\u3002 \u5217\u8868\u7684\u6bcf\u4e2a\u503c\u90fd\u6709\u5bf9\u5e94\u7684\u7d22\u5f15\u503c\uff0c\u7d22\u5f15\u503c\u4ece0\u5f00\u59cb\u3002 \u5217\u8868\u5207\u7247\uff1a \u4f7f\u7528\u5207\u7247\u7b26\u53f7\u53ef\u4ee5\u5bf9\u5927\u591a\u6570\u5e8f\u5217\u7c7b\u578b\u9009\u53d6\u5176\u5b50\u96c6\u3002 \u8d77\u59cb\u4f4d\u7f6estart\u7684\u7d22\u5f15\u662f\u5305\u542b\u7684\uff0c\u800c\u7ed3\u675f\u4f4d\u7f6estop\u7684\u7d22\u5f15\u5e76\u4e0d\u5305\u542b\uff08\u5de6\u95ed\u53f3\u5f00\uff09\u3002 \u6b65\u8fdb\u503cstep\u53ef\u4ee5\u5728\u7b2c\u4e8c\u4e2a\u5192\u53f7\u540e\u9762\u4f7f\u7528\uff0c\u610f\u601d\u662f\u6bcf\u9694\u591a\u5c11\u4e2a\u6570\u53d6\u4e00\u4e2a\u503c \u3002 color = [ 'red' , 'green' , 'blue' , 'yellow' , 'white' , 'black' ] # \u4ece0\u5f00\u59cb\u7edf\u8ba1\uff0c\u8bfb\u53d6\u7b2c1\uff0c2\u4f4d print ( color [ 1 : 3 ]) # ['green', 'blue'] # \u4ece0\u5f00\u59cb\u7edf\u8ba1\uff0c\u8bfb\u53d6\u4ece\u7b2c1\u4f4d\u5230\u5012\u6570\u7b2c3\u4f4d print ( color [ 1 : - 2 ]) # ['green', 'blue', 'yellow'] # \u4ece0\u5f00\u59cb\u7edf\u8ba1\uff0c\u8bfb\u53d6\u4ece\u5012\u6570\u7b2c4\u4f4d\u5230\u5012\u6570\u7b2c3\u4f4d print ( color [ - 4 : - 2 ]) # ['blue', 'yellow'] # \u5982\u679c\u5199\u6210\u4e0b\u9762\u8fd9\u6837\uff0c\u5219\u65e0\u8f93\u51fa\u3002 print ( color [ - 2 : - 4 ]) # [] print ( color [:: 2 ]) # ['red', 'blue', 'white'] \u5bf9\u4e8e\u7c7b\u4f3c\u4e0b\u9762 invoice \u683c\u5f0f\u7684\u7eaf\u6587\u672c\u89e3\u6790\uff0c\u4f7f\u7528\u6709\u540d\u5b57\u7684\u5207\u7247\u6bd4\u7528\u4e0a\u9762\u6240\u5217\u4e3e\u7684\u786c\u7f16\u7801\u7684\u6570\u5b57\u533a\u95f4\u8981\u65b9\u4fbf\u5f97\u591a\u3002 invoice = \"\"\" 0 6 40 52 55 1909 Primoroni PiBrella $17.50 3 $52.50 1489 6mm Tactile Switch x20 $4.19 2 $9.90 1510 Panavise JR.-PV-201 $28.00 1 $28.00 1601 PiTFT Mini Kit 320x240 $34.95 1 $34.95 \"\"\" SKU = slice ( 0 , 6 ) DESCRIPTION = slice ( 6 , 40 ) UNIT_PRICE = slice ( 40 , 52 ) QUANTITY = slice ( 52 , 55 ) ITEM_TOTAL = slice ( 55 , None ) line_items = invoice . split ( ' \\n ' )[ 2 :] # \u6309\u4e0a\u9762invoice\u7684\u683c\u5f0f\uff0c\u7b2c0\u548c1\u884c\u820d\u5f03 for item in line_items : print ( item [ UNIT_PRICE ], item [ DESCRIPTION ]) # $17.50 Primoroni PiBrella # $4.19 6mm Tactile Switch x20 # $28.00 Panavise JR.-PV-201 # $34.95 PiTFT Mini Kit 320x240 Python\u5185\u7f6e\u7684\u5e8f\u5217\u7c7b\u578b\u90fd\u662f\u4e00\u7ef4\u7684\uff0c\u56e0\u6b64\u5b83\u4eec\u53ea\u652f\u6301\u5355\u4e00\u7684\u7d22\u5f15\uff0c\u6210\u5bf9\u51fa\u73b0\u7684\u7d22\u5f15\u662f\u6ca1\u6709\u7528\u7684\u3002 **\u7701\u7565\uff08ellipsis\uff09**\u7684\u6b63\u786e\u4e66\u5199\u65b9\u6cd5\u662f\u4e09\u4e2a\u82f1\u8bed\u53e5\u53f7\uff08...\uff09\uff0c\u800c\u4e0d\u662fUnicdoe\u7801\u4f4dU+2026\u8868\u793a\u7684\u534a\u4e2a\u7701\u7565\u53f7\uff08...\uff09\u3002 \u7701\u7565\u5728Python\u89e3\u6790\u5668\u773c\u91cc\u662f\u4e00\u4e2a\u7b26\u53f7\uff0c\u800c\u5b9e\u9645\u4e0a\u5b83\u662f Ellipsis \u5bf9\u8c61\u7684\u522b\u540d\uff0c\u800c Ellipsis \u5bf9\u8c61\u53c8\u662f ellipsis \u7c7b\u7684\u5355\u4e00\u5b9e\u4f8b\u3002 \u5b83\u53ef\u4ee5\u5f53\u4f5c\u5207\u7247\u89c4\u8303\u7684\u4e00\u90e8\u5206\uff0c\u4e5f\u53ef\u4ee5\u7528\u5728\u51fd\u6570\u7684\u53c2\u6570\u6e05\u5355\u4e2d\uff0c\u6bd4\u5982 f(a, ..., z) \uff0c\u6216 a[i:...] \u3002 \u5728NumPy\u4e2d\uff0c ... \u7528\u4f5c\u591a\u7ef4\u6570\u7ec4\u5207\u7247\u7684\u5feb\u6377\u65b9\u5f0f\u3002\u5982\u679c `x\u662f\u56db\u7ef4\u6570\u7ec4\uff0c\u90a3\u4e48 x[i, ...] \u5c31\u662f x[i, :, :, :]`\u7684\u7f29\u5199\u3002\u5982\u679c\u60f3\u4e86\u89e3\u66f4\u591a\uff0c\u8bf7\u53c2\u89c1\u201cTentative NumPy Tutorial\u201d\u3002 \u5217\u8868\u5e38\u7528\u65b9\u6cd5 \u65b9\u6cd5\u540d\u79f0 \u4f5c\u7528 a.index() \u8fd4\u56dea\u4e2d\u9996\u4e2a\u5339\u914d\u9879\u7684\u4f4d\u7f6e a.pop() \u5220\u9664\u6307\u5b9a\u4f4d\u7f6e\u7684\u5143\u7d20 a.insert() \u5411\u6307\u5b9a\u4f4d\u7f6e\u63d2\u5165\u5143\u7d20 a.reverse() \u53cd\u5411\u6392\u5e8f a.append() \u5411\u672b\u5c3e\u6dfb\u52a0\u5143\u7d20 a.sort() \u5bf9\u5217\u8868\u8fdb\u884c\u6392\u5e8f a.remove() \u5220\u9664\u9996\u4e2a\u5339\u914d\u9879\u7684\u5143\u7d20 a.extend() \u5c06\u4e00\u4e2a\u5217\u8868\u6269\u5c55\u81f3\u53e6\u4e00\u4e2a\u5217\u8868 a.count() \u7edf\u8ba1\u67d0\u4e2a\u5143\u7d20\u51fa\u73b0\u7684\u6b21\u6570 \u521b\u5efa\u5217\u8868list a = [ 1 , 2 , 3 , 4 , 5 ] print ( a ) # [1, 2, 3, 4, 5] b = list ( '12345' ) print ( b ) # ['1', '2', '3', '4', '5'] c = list ( 12345 ) # Traceback (most recent call last): # File \"\", line 1, in # TypeError: 'int' object is not iterable \u5217\u8868\u5207\u7247\uff08\u4ece0\u5f00\u59cb\uff0c\u5de6\u95ed\u53f3\u5f00\uff09\uff1a print ( a [ 2 : 3 ]) # [3] print ( a [: 3 ]) # [1, 2, 3] print ( a [:: - 1 ]) # \u5012\u5e8f # [5, 4, 3, 2, 1] print ( a [::]) # [1, 2, 3, 4, 5] print ( a [:: 1 ]) [ 1 , 2 , 3 , 4 , 5 ] \u5217\u8868\u662f\u53ef\u4fee\u6539\u7684\uff1a print ( a [ 1 ]) # 2 a [ 1 ] = 'one' print ( a ) @ [ 1 , 'one' , 3 , 4 , 5 ] \u5217\u8868\u8ffd\u52a0\u548c\u63d2\u5165\u3002insert\u4e0eappend\u76f8\u6bd4\uff0c\u8ba1\u7b97\u4ee3\u4ef7\u66f4\u9ad8\u3002\u56e0\u4e3a\u5b50\u5e8f\u5217\u5143\u7d20\u9700\u8981\u5728\u5185\u90e8\u79fb\u52a8\u4e3a\u65b0\u5143\u7d20\u63d0\u4f9b\u7a7a\u95f4\u3002 a . append ( 6 ) # \u6ce8\u610f\uff0c\u76f4\u63a5\u4fee\u6539\u539f\u5217\u8868\uff0c\u4e0d\u662f\u521b\u5efa\u526f\u672c\u3002 print ( a ) # [1, 'one', 3, 4, 5, 6] a . extend ([ 7 , 8 , 9 ]) print ( a ) # [1, 'one', 3, 4, 5, 6, 7, 8, 9] a . insert ( 0 , 'Italy' ) print ( a ) # ['Italy', 1, 3, 5, 6, 7, 8] \u5217\u8868\u5220\u9664\u5143\u7d20\uff0c\u9ed8\u8ba4\u5220\u9664\u6700\u540e\u4e00\u4e2a\u3002insert\u7684\u53cd\u64cd\u4f5c\u662fpop\u3002 a . pop () # 9 print ( a ) # [1, 'one', 3, 4, 5, 6, 7, 8] a . pop ( 3 ) # 4 print ( a ) # [1, 'one', 3, 5, 6, 7, 8] \u5220\u9664\u5217\u8868\u4e2d\u67d0\u4e2a\u5143\u7d20\u3002 print ( a [ 1 ]) # one del a [ 1 ] print ( a ) [ 1 , 3 , 5 , 6 , 7 , 8 ] \u5220\u9664\u5217\u8868\u4e2d\u67d0\u4e2a\u5143\u7d20\u3002remove\u65b9\u6cd5\u4f1a\u5b9a\u4f4d\u7b2c\u4e00\u4e2a\u7b26\u5408\u8981\u6c42\u7684\u503c\u5e76\u79fb\u9664 a . remove ( 'Italy' ) print ( a ) # [1, 3, 5, 6, 7, 8] \u7edf\u8ba1\u67d0\u4e2a\u5143\u7d20\u51fa\u73b0\u7684\u6b21\u6570\u3002 print ( a . count ( 1 )) # 1 \u8fd4\u56de\u5217\u8868\u4e2d\u5339\u914d\u9879\u7684\u7d22\u5f15\u4f4d\u7f6e\u3002\u5339\u914d\u4e0d\u5230\u629b\u51fa\u5f02\u5e38\u3002 print ( a . index ( 2 )) # Traceback (most recent call last): # File \"\", line 1, in # ValueError: 2 is not in list print ( a . index ( 3 )) # 1 \u5224\u65ad\u5143\u7d20\u662f\u5426\u5b58\u5728\u4e8e\u5217\u8868\u3002 print ( 3 in a ) # True print ( '3' in a ) # False \u53cd\u5411\u8f93\u51fa\u5217\u8868\u3002 a . reverse () print ( a ) # [8, 7, 6, 5, 3, 1] \u53d6\u5217\u8868\u4e2d\u6700\u5927\u503c\u3001\u6700\u5c0f\u503c\u3002 print ( min ( a )) # 1 print ( max ( a )) # 78 \u8ba1\u7b97\u5217\u8868\u957f\u5ea6\u3002 print ( len ( a )) # 6 \u5217\u8868\u6269\u5c55\uff1a a = [ 1 , 2 , 3 ] b = [ 4 , 5 , 6 ] print ( a + b ) # [1, 2, 3, 4, 5, 6] a . extend ( b ) # a\u5217\u8868\u88ab\u4fee\u6539 print ( a ) # [1, 2, 3, 4, 5, 6] print ( b ) # [4, 5, 6] \u4f7f\u7528extend\u6dfb\u52a0\u5143\u7d20\u6bd4\u4f7f\u7528\u52a0\u53f7\uff08+\uff09\u8fde\u63a5\u6548\u7387\u66f4\u9ad8\u3002\u56e0\u4e3a\u4f7f\u7528\u52a0\u53f7\uff08+\uff09\u8fde\u63a5\u8fc7\u7a0b\u4e2d\u521b\u5efa\u4e86\u65b0\u5217\u8868\uff0c\u5e76\u4e14\u8fd8\u8981\u590d\u5236\u5bf9\u8c61\u3002 a_list = [ 4 , None , 'foo' ] b_list = [ 7 , 8 , ( 2 , 3 )] print ( a_list + b_list ) # [4, None, 'foo', 7, 8, (2, 3)] \u4f7f\u7528+\u53f7\u8fde\u63a5 a_list . extend ( b_list ) print ( a_list ) # [4, None, 'foo', 7, 8, (2, 3)] Python\u7684\u4e00\u4e2a\u60ef\u4f8b\uff1a\u5982\u679c\u4e00\u4e2a\u51fd\u6570\u6216\u8005\u65b9\u6cd5\u5bf9\u5bf9\u8c61\u8fdb\u884c\u7684\u662f\u5c31\u5730\u6539\u52a8\uff0c\u90a3\u5b83\u5c31\u5e94\u8be5\u8fd4\u56deNone\uff0c\u597d\u8ba9\u8c03\u7528\u8005\u77e5\u9053\u4f20\u5165\u7684\u53c2\u6570\u53d1\u751f\u4e86\u53d8\u52a8\uff0c\u800c\u4e14\u5e76\u672a\u4ea7\u751f\u65b0\u7684\u5bf9\u8c61\u3002 \u4e0b\u9762\u662f\u6392\u5e8f\u7684\u4f8b\u5b50 list.sort() \u548c sorted(list) \u7684\u533a\u522b\u3002 list1 = [ '1' , 'one' , '3' , 'Four' , '5' , 'two' , 'apple' , '8' , '9' ] print ( list1 ) # ['1', 'one', '3', 'Four', '5', 'two', 'apple', '8', '9'] # \u4e0b\u9762\u7684\u64cd\u4f5c\u4e0d\u6539\u53d8\u539f\u5217\u8868 print ( sorted ( list1 )) # ['1', '3', '5', '8', '9', 'Four', 'apple', 'one', 'two'] print ( sorted ( list1 , reverse = True )) # ['two', 'one', 'apple', 'Four', '9', '8', '5', '3', '1'] print ( sorted ( list1 , key = len )) # ['1', '3', '5', '8', '9', 'one', 'two', 'Four', 'apple'] print ( list1 ) # ['1', 'one', '3', 'Four', '5', 'two', 'apple', '8', '9'] # \u4e0b\u9762\u7684\u64cd\u4f5c\u76f4\u63a5\u4fee\u6539\u539f\u5217\u8868\uff0c\u8fd4\u56de\u503c\u662fNone print ( list1 . sort ()) # None print ( list1 ) # ['1', '3', '5', '8', '9', 'Four', 'apple', 'one', 'two'] \u5217\u8868\u590d\u5236\uff0c + \u548c * \u7684\u64cd\u4f5c\u90fd\u662f\u4e0d\u4fee\u6539\u539f\u6709\u7684\u64cd\u4f5c\u5bf9\u8c61\uff0c\u800c\u662f\u6784\u5efa\u4e00\u4e2a\u5168\u65b0\u7684\u5217\u8868\u3002 c = list ( 'Python' ) print ( a + c ) # [1, 2, 3, 4, 5, 6, 'P', 'y', 't', 'h', 'o', 'n'] print ( a * 3 ) # [1, 2, 3, 4, 5, 6, 1, 2, 3, 4, 5, 6, 1, 2, 3, 4, 5, 6] \u5982\u679c\u5728 a * n \u8fd9\u4e2a\u8bed\u53e5\u4e2d\uff0c\u5e8f\u5217 a \u91cc\u7684\u5143\u7d20\u662f\u5bf9\u5176\u4ed6\u53ef\u53d8\u5bf9\u8c61\u7684\u5f15\u7528\u7684\u8bdd\uff0c\u5c31\u9700\u8981\u683c\u5916\u6ce8\u610f\u4e86\uff0c\u56e0\u4e3a\u8fd9\u4e2a\u5f0f\u5b50\u7684\u7ed3\u679c\u53ef\u80fd\u4f1a\u51fa\u4e4e\u610f\u6599\u3002 \u6bd4\u5982\uff0c\u6211\u4eec\u60f3\u7528 my_list=[[]] * 3 \u6765\u521d\u59cb\u5316\u4e00\u4e2a\u7531\u5217\u8868\u7ec4\u6210\u7684\u5217\u8868\uff0c\u4f46\u662f\u6211\u4eec\u5b9e\u9645\u5f97\u5230\u7684\u5217\u8868\u91cc\u5305\u542b\u76843\u4e2a\u5143\u7d20\u5176\u5b9e\u662f3\u4e2a\u5f15\u7528\uff0c\u800c\u4e14\u8fd93\u4e2a\u5f15\u7528\u6307\u5411\u7684\u90fd\u662f*\u540c\u4e00\u4e2a*\u5217\u8868\u3002\u770b\u4e0b\u9762\u4f8b\u5b50\u3002 # \u505a\u6cd51 board = [[ '_' ] * 3 for i in range ( 3 )] print ( board ) # [['_', '_', '_'], ['_', '_', '_'], ['_', '_', '_']] board [ 1 ][ 2 ] = 'X' print ( board ) # [['_', '_', '_'], ['_', '_', 'X'], ['_', '_', '_']] # \u505a\u6cd52 board = [[ '_' ] * 3 ] * 3 print ( board ) # [['_', '_', '_'], ['_', '_', '_'], ['_', '_', '_']] board [ 1 ][ 2 ] = 'X' print ( board ) # [['_', '_', 'X'], ['_', '_', 'X'], ['_', '_', 'X']] \u4e0b\u9762\u4e5f\u662f\u540c\u6837\u7684\u95ee\u9898\u3002 # \u65b9\u6cd51 row = [ '_' ] * 3 board = [] for i in range ( 3 ): board . append ( row ) print ( board ) # [['_', '_', '_'], ['_', '_', '_'], ['_', '_', '_']] board [ 2 ][ 0 ] = 'X' print ( board ) # [['X', '_', '_'], ['X', '_', '_'], ['X', '_', '_']] # \u65b9\u6cd52 row = [] board = [] for i in range ( 3 ): row = [ '_' ] * 3 board . append ( row ) print ( board ) # [['_', '_', '_'], ['_', '_', '_'], ['_', '_', '_']] board [ 2 ][ 0 ] = 'X' print ( board ) # [['_', '_', '_'], ['_', '_', '_'], ['X', '_', '_']] \u53cc\u7aef\u961f\u5217collections.deque \uff0c\u53ef\u4ee5\u6ee1\u8db3\u5217\u8868\u5934\u5c3e\u90e8\u90fd\u589e\u52a0\u7684\u8981\u6c42\u3002 deque() \u4e2d maxlen \u662f\u4e00\u4e2a\u53ef\u9009\u53c2\u6570\uff0c\u4ee3\u8868\u8fd9\u4e2a\u961f\u5217\u53ef\u4ee5\u5bb9\u7eb3\u7684\u5143\u7d20\u7684\u6570\u91cf\uff0c\u800c\u4e14\u4e00\u65e6\u8bbe\u5b9a\uff0c\u8fd9\u4e2a\u5c5e\u6027\u5c31\u4e0d\u80fd\u4fee\u6539\u4e86\u3002 \u5f53\u8bd5\u56fe\u5bf9\u4e00\u4e2a\u5df2\u6ee1 len(d)==d.maxlen \u7684\u961f\u5217\u505a\u5934\u90e8\u6dfb\u52a0\u64cd\u4f5c\u7684\u65f6\u5019\uff0c\u5b83\u5c3e\u90e8\u7684\u5143\u7d20\u4f1a\u88ab\u5220\u9664\u6389\u3002 extendleft(iter) \u65b9\u6cd5\u4f1a\u628a\u8fed\u4ee3\u5668\u91cc\u7684\u5143\u7d20\u9010\u4e2a\u6dfb\u52a0\u5230\u53cc\u5411\u961f\u5217\u7684\u5de6\u8fb9\uff0c\u56e0\u6b64\u8fed\u4ee3\u5668\u91cc\u7684\u5143\u7d20\u4f1a\u9006\u5e8f\u51fa\u73b0\u5728\u961f\u5217\u91cc\u3002 \u961f\u5217\u7684\u65cb\u8f6c\u64cd\u4f5c rotate \u63a5\u53d7\u4e00\u4e2a\u53c2\u6570n\uff0c\u5f53n > 0\u65f6\uff0c\u961f\u5217\u7684\u6700\u53f3\u8fb9\u7684n\u4e2a\u5143\u7d20\u4f1a\u88ab\u79fb\u52a8\u5230\u961f\u5217\u7684\u5de6\u8fb9\u3002\u5f53n < 0\u65f6\uff0c\u6700\u5de6\u8fb9\u7684n\u4e2a\u5143\u7d20\u4f1a\u88ab\u79fb\u52a8\u5230\u53f3\u8fb9\u3002 from collections import deque d = deque ([ 1 , 2 , 3 ]) print ( d ) # deque([1, 2, 3]) # \u6ce8\u610f\u63d2\u5165\u987a\u5e8f d . extendleft ([ 'a' , 'b' , 'c' ]) print ( d ) # deque(['c', 'b', 'a', 1, 2, 3]) print ( len ( d )) # 6 print ( d [ - 2 ]) # 2 # \u7edf\u8ba1\u5b57\u7b26a\u51fa\u73b0\u7684\u6b21\u6570 print ( d . count ( 'a' )) # 1 # \u8fd4\u56de\u5b57\u7b26a\u7684\u7d22\u5f15\u503c print ( d . index ( 'a' )) # 2 # \u7b2c0\u4f4d\u63d2\u5165\u6570\u5b571\uff0c\u5176\u4f59\u987a\u79fb d . insert ( 0 , 1 ) print ( d ) # deque([1, 'c', 'b', 'a', 1, 2, 3]) # \u628a\u53f3\u8fb92\u4e2a\u5143\u7d20\u653e\u5230\u5de6\u8fb9\uff0c\u6ce8\u610f\u987a\u5e8f\uff0c\u548cextendleft\u4e0d\u4e00\u6837 d . rotate ( 2 ) print ( d ) # deque([2, 3, 1, 'c', 'b', 'a', 1]) d . rotate ( - 2 ) print ( d ) # deque([1, 'c', 'b', 'a', 1, 2, 3]) \u4e0b\u8868\u603b\u7ed3\u4e86\u5217\u8868\u548c\u53cc\u5411\u961f\u5217\u7684\u65b9\u6cd5\uff08\u4e0d\u5305\u62ec\u7531\u5bf9\u8c61\u5b9e\u73b0\u7684\u65b9\u6cd5\uff09\u3002 \u5217\u8868\u6392\u5e8f\u3002\u6392\u5e8f\u5bf9\u5217\u8868\u5143\u7d20\u7684\u6570\u636e\u7c7b\u578b\u662f\u6709\u8981\u6c42\u7684\u3002 a_list = [ 4 , None , 'foo' , 7 , 8 , ( 2 , 3 )] a_list . sort () # Traceback (most recent call last): # File \"\", line 1, in # TypeError: '<' not supported between instances of 'NoneType' and 'int' b_list = [ 7 , 8 , ( 2 , 3 )] b_list . sort () # Traceback (most recent call last): # File \"\", line 1, in # TypeError: '<' not supported between instances of 'tuple' and 'int' a_list = [ 7 , 2 , 5 , 1 , 3 ] a_list . sort () # \u6309\u6570\u503c\u5927\u5c0f\u6392\u5e8f print ( a_list ) # [1, 2, 3, 5, 7] b_list = [ 'saw' , 'small' , 'He' , 'foxes' , 'six' ] b_list . sort ( key = len ) # \u901a\u8fc7\u5b57\u7b26\u4e32\u7684\u957f\u5ea6\u8fdb\u884c\u6392\u5e8f print ( b_list ) # ['He', 'saw', 'six', 'small', 'foxes'] \u5217\u8868\u4e8c\u5206\u641c\u7d22\u548c\u5df2\u6392\u5e8f\u5217\u8868\u7684\u7ef4\u62a4 bisect \u8fd4\u56de\u8981\u63d2\u5165\u5143\u7d20\u5728\u5217\u8868\u4e2d\u7684\u4e0b\u6807\u3002\u5047\u5b9a\u5217\u8868\u662f\u6709\u5e8f\u7684\u3002 bisect_left \u4e0e bisect \u7c7b\u4f3c\uff0c\u53ea\u4e0d\u8fc7\u5176\u9ed8\u8ba4\u5c06\u5143\u7d20\u63d2\u5230\u5de6\u8fb9\uff0c\u6240\u4ee5\u8fd4\u56de\u7684\u662f\u63d2\u5165\u5230\u5de6\u8fb9\u7684\u4e0b\u6807 bisect_right\u4e0e bisect_left \u76f8\u53cd\u3002 \u4ee5\u4e0a\u65b9\u6cd5\u82e5\u5217\u8868\u65e0\u5e8f\uff0c\u90a3\u4e48\u4f1a\u8fd4\u56de\u63d2\u5165\u5230\u5217\u8868\u6700\u540e\u4e00\u4e2a\u5408\u9002\u7684\u4f4d\u7f6e\u3002 insort \u4f1a\u5728\u5217\u8868\u4e2d\u63d2\u5165\u5143\u7d20\u5230\u6b63\u786e\u4f4d\u7f6e\uff0c\u5047\u5b9a\u5217\u8868\u6709\u5e8f\u3002\u5982\u679c\u5217\u8868\u65e0\u5e8f\uff0c\u90a3\u4e48\u4f1a\u8fd4\u56de\u7a7a\u3002\u9ed8\u8ba4\u63d2\u5165\u5230\u53f3\u8fb9\u3002 insort_left \u548cinsort_right \u7c7b\u4f3c\u3002 import bisect c = [ 1 , 2 , 3 , 4 , 7 ] print ( bisect . bisect ( c , 2 )) # 2 bisect\u4f1a\u627e\u5230\u7b2c\u4e00\u4e2a2,\u5e76\u628a\u65b0\u76842\u63d2\u5165\u5b83\u540e\u9762 bisect . insort ( c , 2 ) # [1, 2, 2, 3, 4, 7] print ( bisect . bisect ( c , 5 )) # 5 bisect\u4f1a\u627e\u5230\u7b2c\u4e00\u4e2a4,\u5e76\u628a\u65b0\u76845\u63d2\u5165\u5b83\u540e\u9762 bisect . insort ( c , 5 ) print ( bisect . bisect ( c , 6 )) # 6 bisect\u4f1a\u627e\u5230\u7b2c\u4e00\u4e2a5,\u5e76\u628a\u65b0\u76846\u63d2\u5165\u5b83\u540e\u9762 bisect . insort ( c , 6 ) print ( c ) # [1, 2, 2, 3, 4, 5, 6, 7] bisect\u53ef\u4ee5\u7528\u6765\u5efa\u7acb\u4e00\u4e2a\u7528\u6570\u5b57\u4f5c\u4e3a\u7d22\u5f15\u7684\u67e5\u8be2\u8868\u683c\uff0c\u5982\u4e0b\u4f8b\uff0c\u628a\u5206\u6570\u548c\u6210\u7ee9\u5bf9\u5e94\u8d77\u6765\uff0c\u6839\u636e\u4e00\u4e2a\u5206\u6570\uff0c\u627e\u5230\u5b83\u6240\u5bf9\u5e94\u7684\u6210\u7ee9\u3002 import bisect def grade ( score , breakpoints = [ 60 , 70 , 80 , 90 ], grades = 'FDCBA' ): i = bisect . bisect ( breakpoints , score ) return grades [ i ] [ grade ( score ) for score in [ 15 , 26 , 31 , 62 , 79 , 85 ]] # ['F', 'F', 'F', 'D', 'C', 'B'] \u7528bisect.insort\u63d2\u5165\u65b0\u5143\u7d20\uff0c\u5e76\u80fd\u4fdd\u6301seq\u7684\u5347\u5e8f\u987a\u5e8f\u3002 import bisect import random size = 7 random . seed ( 1729 ) my_list = [] for i in range ( size ): new_item = random . randrange ( size * 2 ) bisect . insort ( my_list , new_item ) print ( f ' { new_item : 2d } :--> { my_list } ' ) # 10 :--> [10] # 0 :--> [0, 10] # 6 :--> [0, 6, 10] # 8 :--> [0, 6, 8, 10] # 7 :--> [0, 6, 7, 8, 10] # 2 :--> [0, 2, 6, 7, 8, 10] # 10 :--> [0, 2, 6, 7, 8, 10, 10] 1.4 \u5b57\u5178\uff08dictionary\uff09 \u00b6 \u5b57\u5178(dict)\u662f\u4f7f\u7528\u952e-\u503c\uff08key-value\uff09\u5b58\u50a8\uff0c\u952e\u662f\u4e0d\u53ef\u53d8\u5bf9\u8c61\uff0c\u4e14\u4e0d\u5141\u8bb8\u91cd\u590d\u3002 dict\uff08\u5b57\u5178\uff09\u66f4\u4e3a\u5e38\u7528\u7684\u540d\u5b57\u662f\u54c8\u5e0c\u8868\u6216\u8005\u662f\u5173\u8054\u6570\u7ec4\u3002 \u5b57\u5178\u662f\u62e5\u6709\u7075\u6d3b\u5c3a\u5bf8\u7684\u952e\u503c\u5bf9\u96c6\u5408\uff0c\u4e0d\u662f\u901a\u8fc7\u4f4d\u7f6e\u8fdb\u884c\u7d22\u5f15\uff0c\u5176\u4e2d\u952e\u548c\u503c\u90fd\u662fPython\u5bf9\u8c61\u3002\u7528\u5927\u62ec\u53f7{}\u662f\u521b\u5efa\u5b57\u5178\u7684\u4e00\u79cd\u65b9\u5f0f\uff0c\u5728\u5b57\u5178\u4e2d\u7528\u9017\u53f7\u5c06\u952e\u503c\u5bf9\u5206\u9694\u3002 \u521b\u5efa\u5b57\u5178\u7684\u51e0\u79cd\u65b9\u6cd5\uff1a a = dict ( one = 1 , two = 2 , three = 3 ) b = { 'one' : 1 , 'two' : 2 , 'three' : 3 } c = dict ( zip ([ 'one' , 'two' , 'three' ], [ 1 , 2 , 3 ])) d = dict ([( 'two' , 2 ), ( 'three' , 3 ), ( 'one' , 1 )]) e = dict ({ 'three' : 3 , 'one' : 1 , 'two' : 2 }) print ( a == b == c == d == e ) # True \u5b57\u5178\u5e38\u7528\u65b9\u6cd5 \u65b9\u6cd5\u540d\u79f0 \u4f5c\u7528 a.items() \u8fd4\u56dea\u4e2d\u6240\u6709\u952e\u503c\u5bf9 a.values() \u8fd4\u56dea\u4e2d\u6240\u6709\u503c a.keys() \u8fd4\u56dea\u4e2d\u6240\u6709\u952e a.get() \u901a\u8fc7\u952e\u6765\u67e5\u503c\uff0c\u8fd4\u56de\u5bf9\u5e94\u7684\u503c a.clear() \u6e05\u7a7a\u5b57\u5178a\u7684\u503c a.setdefault \u901a\u8fc7\u952e\u503c\u6765\u67e5\u627e\u503c\uff0c\u627e\u4e0d\u5230\u5219\u63d2\u5165 a.update() \u952e\u548c\u503c\u66f4\u65b0\u5230\u65b0\u7684\u5b57\u5178 a.pop() \u5220\u9664\u6307\u5b9a\u4f4d\u7f6e\u7684\u5143\u7d20 \u751f\u6210\u4e00\u4e2a\u5b57\u5178\u3002 dict_a = { 'name' : 'Ming' , 'id' : 1001 , 'age' : 35 } print ( type ( dict_a )) # dict_b = dict ( city = 'Shanghai' , strict = 'Xuhui' , zip = '200000' ) print ( type ( dict_b )) # \u901a\u8fc7\u952e\u67e5\u8be2\u503c\uff0c\u67e5\u8be2\u4e0d\u5230\u629b\u51fa\u5f02\u5e38\u3002 print ( dict_a [ 'name' ]) # Ming print ( dict_a [ 'Name' ]) # Traceback (most recent call last): # File \"\", line 1, in # KeyError: 'Name' \u63d2\u5165\u65b0\u7684\u952e\u503c\u5bf9\u3002 dict_a [ 'city' ] = 'Chengdu' print ( dict_a ) # {'name': 'Ming', 'id': 1001, 'city': 'Chengdu'} \u5220\u9664\u67d0\u4e2a\u952e\u503c\u5bf9\u3002pop\u65b9\u6cd5\u4f1a\u5728\u5220\u9664\u7684\u540c\u65f6\u8fd4\u56de\u88ab\u5220\u7684\u503c\uff0c\u5e76\u5220\u9664\u952e\u3002 dict_a . pop ( 'city' ) # Chengdu print ( dict_a ) # {'name': 'Ming', 'id': 1001} \u53e6\u4e00\u79cd\u65b9\u5f0f\u5220\u9664\u67d0\u4e2a\u952e\u503c\u5bf9\u3002 del dict_a [ 'age' ] # Traceback (most recent call last): # File \"\", line 1, in # KeyError: 'age' del dict_a [ 'id' ] print ( dict_a ) # {'name': 'Ming'} \u5224\u65ad\u952e\u662f\u5426\u5b58\u5728\u3002 dict_a [ 23 ] = 'Hello World' print ( dict_a ) # {'name': 'Ming', 23: 'Hello World'} print ( 23 in dict_a ) # True print ( 35 in dict_a ) # False \u901a\u8fc7\u952e\u67e5\u8be2\u503c\u7684\u53e6\u4e00\u79cd\u65b9\u5f0f\uff0c\u67e5\u8be2\u4e0d\u5230\u4e0d\u629b\u5f02\u5e38\u3002 dict_a . get ( 'hai' ) dict_a . get ( 'hai' , 1 ) # 1 dict_a . get ( 'name' , 1 ) # Ming dict_a [ 'hai' ] # Traceback (most recent call last): # File \"\", line 1, in # KeyError: 'hai' \u901a\u8fc7\u952e\u67e5\u8be2\u503c\u7684\u53e6\u4e00\u79cd\u65b9\u5f0f\uff0c\u67e5\u8be2\u4e0d\u5230\u5219\u6dfb\u52a0\u3002 dict_a . setdefault ( 'name' ) # Ming dict_a . setdefault ( 'hai' , 1 ) # 1 print ( dict_a ) # {'name': 'Ming', 23: 'Hello World', 'hai': 1} dict_a . setdefault ( 'go' ) print ( dict_a ) # {'name': 'Ming', 23: 'Hello World', 'hai': 1, 'go': None} \u8bfb\u53d6\u5b57\u5178\u6240\u6709\u952e\u503c\u5bf9\uff0c\u8fd4\u56de\u7684\u662f\u5217\u8868\u5f62\u5f0f\u3002 print ( dict_a . items ()) # dict_items([('name', 'Ming'), (23, 'Hello World'), ('hai', 1), ('go', None)]) \u8bfb\u53d6\u5b57\u5178\u7684\u952e\u3002 print ( dict_a . keys ()) # dict_keys(['name', 23, 'hai', 'go']) \u8bfb\u53d6\u5b57\u5178\u7684\u503c\u3002 print ( dict_a . values ()) # dict_values(['Ming', 'Hello World', 1, None]) \u5c06\u5b57\u5178\u503c\u8f6c\u5316\u6210\u5217\u8868\u3002 print ( list ( dict_a . values ())) # ['Ming', 'Hello World', 1, None] for key in dict_a . keys (): print ( dict_a [ key ]) # Ming # Hello World # 1 # None \u6e05\u7a7a\u5b57\u5178\u3002 dict_a . clear () print ( dict_a ) # {} print ( len ( dict_a )) # 0 \u5bf9\u4e8e\u4efb\u4f55\u539f\u5b57\u5178\u4e2d\u5df2\u7ecf\u5b58\u5728\u7684\u952e\uff0c\u5982\u679c\u4f20\u7ed9update\u65b9\u6cd5\u7684\u6570\u636e\u4e5f\u542b\u6709\u76f8\u540c\u7684\u952e\uff0c\u5219\u5b83\u7684\u503c\u5c06\u4f1a\u88ab\u8986\u76d6\u3002 dict_a = { 'name' : 'Ming' , 'id' : 1001 , 'age' : 35 } dict_b = dict ( city = 'Shanghai' , id = 2001 , zip = '200000' ) dict_a . update ( dict_b ) print ( dict_a ) # {'name': 'Ming', 'id': 2001, 'age': 35, 'city': 'Shanghai', 'zip': '200000'} \u4ece\u5217\u8868\u751f\u6210\u5b57\u5178\u3002 \u5b57\u5178\u672c\u8d28\u4e0a\u662f2-\u5143\u7ec4\uff08\u542b\u67092\u4e2a\u5143\u7d20\u7684\u5143\u7ec4\uff09\u7684\u96c6\u5408\uff0c\u5b57\u5178\u662f\u53ef\u4ee5\u63a5\u53d7\u4e00\u4e2a2-\u5143\u7ec4\u7684\u5217\u8868\u4f5c\u4e3a\u53c2\u6570\u7684\u3002 # \u65b9\u6cd51 mapping = {} key_list = list ( range ( 5 )) value_list = list ( reversed ( range ( 5 ))) for key , value in zip ( key_list , value_list ): mapping [ key ] = value print ( mapping ) # {0: 4, 1: 3, 2: 2, 3: 1, 4: 0} # \u65b9\u6cd52\u3002 mapping = {} key_list = list ( range ( 5 )) value_list = list ( reversed ( range ( 5 ))) mapping = dict ( zip ( key_list , value_list )) print ( mapping ) # {0: 4, 1: 3, 2: 2, 3: 1, 4: 0} \u6709\u6548\u7684\u5b57\u5178\u952e\u7c7b\u578b\u3002 \u5c3d\u7ba1\u5b57\u5178\u7684\u503c\u53ef\u4ee5\u662f\u4efb\u4f55Python\u5bf9\u8c61\uff0c\u4f46\u952e\u5fc5\u987b\u662f\u4e0d\u53ef\u53d8\u7684\u5bf9\u8c61\uff0c\u6bd4\u5982\u6807\u91cf\u7c7b\u578b\uff08\u6574\u6570\u3001\u6d6e\u70b9\u6570\u3001\u5b57\u7b26\u4e32\uff09\u6216\u5143\u7ec4\uff08\u4e14\u5143\u7ec4\u5185\u5bf9\u8c61\u4e5f\u5fc5\u987b\u662f\u4e0d\u53ef\u53d8\u5bf9\u8c61\uff09\u3002 \u901a\u8fc7hash\u51fd\u6570\u53ef\u4ee5\u68c0\u67e5\u4e00\u4e2a\u5bf9\u8c61\u662f\u5426\u53ef\u4ee5\u54c8\u5e0c\u5316\uff08\u5373\u662f\u5426\u53ef\u4ee5\u7528\u4f5c\u5b57\u5178\u7684\u952e\uff09\uff0c\u672f\u8bed\u53eb\u4f5c\u54c8\u5e0c\u5316\u3002 print ( hash ( 'string' )) # -4368784820203065343 print ( hash (( 1 , 2 , ( 2 , 3 )))) # -9209053662355515447 print ( hash (( 1 , 2 , [ 2 , 3 ]))) # TypeError: unhashable type: 'list' print ( hash (( 1 , 2 , tuple ([ 2 , 3 ])))) # -9209053662355515447 \u4e3a\u4e86\u5c06\u5217\u8868\u4f5c\u4e3a\u952e\uff0c\u4e00\u79cd\u65b9\u5f0f\u5c31\u662f\u5c06\u5176\u8f6c\u6362\u4e3a\u5143\u7ec4 \u5b57\u5178\u9ed8\u8ba4\u503c\u3002 \u4e0b\u9762\u7684\u4f8b\u5b50\uff0c\u5b9e\u73b0\u4e86\u5c06\u4e00\u4e2a\u5355\u8bcd\u7ec4\u6210\u7684\u5217\u8868\uff0c\u8f6c\u6362\u6210\u5355\u8bcd\u9996\u5b57\u6bcd\u548c\u5355\u8bcd\u4e3a\u952e\u503c\u5bf9\u7684\u5b57\u5178\u3002\u5148\u7528\u4f20\u7edf\u65b9\u6cd5\u5b9e\u73b0\uff0c\u518d\u7528\u5b57\u5178\u7684setdefault\u65b9\u6cd5\u8fdb\u884c\u6539\u5199\u3002 \u5148\u770b\u4f20\u7edf\u65b9\u6cd5\u3002 words = [ 'apple' , 'bat' , 'bar' , 'atom' , 'book' ] by_letter = {} for word in words : letter = word [ 0 ] # word[0]\u628a\u5217\u8868words\u7684\u6bcf\u4e2a\u5143\u7d20\u5217\u8868\u5316\uff0c\u5e76\u53d6\u9996\u5b57\u6bcd\u3002\u8f93\u51fa\u7684\u662fa, b, b, a, b\u8fd95\u4e2a\u5217\u8868\u5143\u7d20\u7684\u9996\u5b57\u6bcd if letter not in by_letter : # \u751f\u6210\u7b2c\u4e00\u4e2a\u952e\u503c\u5bf9 print ( letter ) by_letter [ letter ] = [ word ] # \u5bf9\u6bd4[word]\u548cword[]\u7684\u7528\u6cd5 print ( by_letter ) # a # {'a': ['apple']} # b # {'a': ['apple'], 'b': ['bat']} else : # append\u5176\u4ed6\u952e\u503c\u5bf9 print ( letter ) by_letter [ letter ] . append ( word ) print ( by_letter ) # b # {'a': ['apple'], 'b': ['bat', 'bar']} # a # {'a': ['apple', 'atom'], 'b': ['bat', 'bar']} # b # {'a': ['apple', 'atom'], 'b': ['bat', 'bar', 'book']} print ( by_letter ) # {'a': ['apple', 'atom'], 'b': ['bat', 'bar', 'book']} \u7528\u5b57\u5178\u7684setdefault\u65b9\u6cd5\uff0c\u4e0a\u8ff0\u7684for\u5faa\u73af\u8bed\u53e5\u53ef\u4ee5\u88ab\u5199\u4e3a\u5982\u4e0b\u3002 words = [ 'apple' , 'bat' , 'bar' , 'atom' , 'book' ] by_letter = {} for word in words : letter = word [ 0 ] # word[0]\u7684\u8f93\u51fa\u4f9d\u7136\u662f5\u4e2a\u5217\u8868\u5143\u7d20\u7684\u9996\u5b57\u6bcda, b, b, a, b by_letter . setdefault ( letter , []) . append ( word ) # \u5982\u679cletter\u4e0d\u5728[]\u5219\u901a\u8fc7append\u6dfb\u52a0word print ( by_letter ) # {'a': ['apple', 'atom'], 'b': ['bat', 'bar', 'book']} \u5982\u679c\u6539\u5199\u4e3a by_letter.setdefault(letter, ['a']).append(word) \uff0c\u5219\u8f93\u51fa by_letter \u662f {'a': ['a', 'apple', 'atom'], 'b': ['a', 'bat', 'bar', 'book']} \u3002 words = [ 'apple' , 'bat' , 'bar' , 'atom' , 'book' ] by_letter = {} for word in words : letter = word [ 0 ] # word[0]\u7684\u8f93\u51fa\u4f9d\u7136\u662f5\u4e2a\u5217\u8868\u5143\u7d20\u7684\u9996\u5b57\u6bcda, b, b, a, b by_letter . setdefault ( letter , [ 'a' ]) . append ( word ) print ( by_letter ) # {'a': ['a', 'apple', 'atom'], 'b': ['a', 'bat', 'bar', 'book']} \u4f53\u4f1asetdefault()\u7684\u6ce8\u91ca\u201cInsert key with a value of default if key is not in the dictionary. Return the value for key if key is in the dictionary, else default.\u201d \u901a\u8fc7defaultdict\u7c7b\u4f7f\u5f97\u4e0a\u8ff0\u76ee\u7684\u5b9e\u73b0\u66f4\u4e3a\u7b80\u5355\u3002 from collections import defaultdict by_letter = defaultdict ( list ) # list\u662f\u5185\u7f6e\u7684\u53ef\u53d8\u5e8f\u5217(Built-in mutable sequence) print ( dict ( by_letter )) # {} for word in words : by_letter [ word [ 0 ]] . append ( word ) print ( by_letter ) # defaultdict(, {'a': ['apple', 'atom'], 'b': ['bat', 'bar', 'book']}) print ( dict ( by_letter )) # {'a': ['apple', 'atom'], 'b': ['bat', 'bar', 'book']} \u4e0b\u8868\u5c55\u793a\u4e86 dict \u3001 defaultdict \u548c OrderedDict \u7684\u5e38\u89c1\u65b9\u6cd5\uff0c\u540e\u9762\u4e24\u4e2a\u6570\u636e\u7c7b\u578b\u662f dict \u7684\u53d8\u79cd\uff0c\u4f4d\u4e8e collections \u6a21\u5757\u5185\u3002 default_factory \u5e76\u4e0d\u662f\u4e00\u4e2a\u65b9\u6cd5\uff0c\u800c\u662f\u4e00\u4e2a\u53ef\u8c03\u7528\u5bf9\u8c61\uff08callable\uff09\uff0c\u5b83\u7684\u503c\u5728 defaultdict \u521d\u59cb\u5316\u7684\u65f6\u5019\u7531\u7528\u6237\u8bbe\u5b9a\u3002 OrderedDict.popitem() \u4f1a\u79fb\u9664\u5b57\u5178\u91cc\u6700\u5148\u63d2\u5165\u7684\u5143\u7d20\uff08\u5148\u8fdb\u5148\u51fa\uff09\uff1b\u540c\u65f6\u8fd9\u4e2a\u65b9\u6cd5\u8fd8\u6709\u4e00\u4e2a\u53ef\u9009\u7684last\u53c2\u6570\uff0c\u82e5\u4e3a\u771f\uff0c\u5219\u4f1a\u79fb\u9664\u6700\u540e\u63d2\u5165\u7684\u5143\u7d20\uff08\u540e\u8fdb\u5148\u51fa\uff09\u3002 \u4e0a\u9762\u7684\u8868\u683c\u4e2d\uff0cupdate\u65b9\u6cd5\u5904\u7406\u53c2\u6570m\u7684\u65b9\u5f0f\uff0c\u662f\u5178\u578b\u7684\u201c\u9e2d\u5b50\u7c7b\u578b\u201d\u3002\u51fd\u6570\u9996\u5148\u68c0\u67e5m\u662f\u5426\u6709keys\u65b9\u6cd5\uff0c\u5982\u679c\u6709\uff0c\u90a3\u4e48update\u51fd\u6570\u5c31\u628a\u5b83\u5f53\u4f5c\u6620\u5c04\u5bf9\u8c61\u6765\u5904\u7406\u3002\u5426\u5219\uff0c\u51fd\u6570\u4f1a\u9000\u4e00\u6b65\uff0c\u8f6c\u800c\u628am\u5f53\u4f5c\u5305\u542b\u4e86\u952e\u503c\u5bf9(key, value)\u5143\u7d20\u7684\u8fed\u4ee3\u5668\u3002Python\u91cc\u5927\u591a\u6570\u6620\u5c04\u7c7b\u578b\u7684\u6784\u9020\u65b9\u6cd5\u90fd\u91c7\u7528\u4e86\u7c7b\u4f3c\u7684\u903b\u8f91\uff0c\u56e0\u6b64\u4f60\u65e2\u53ef\u4ee5\u7528\u4e00\u4e2a\u6620\u5c04\u5bf9\u8c61\u6765\u65b0\u5efa\u4e00\u4e2a\u6620\u5c04\u5bf9\u8c61\uff0c\u4e5f\u53ef\u4ee5\u7528\u5305\u542b(key, value)\u5143\u7d20\u7684\u53ef\u8fed\u4ee3\u5bf9\u8c61\u6765\u521d\u59cb\u5316\u4e00\u4e2a\u6620\u5c04\u5bf9\u8c61\u3002 \u5b57\u5178\u7684\u53d8\u79cd\uff1a collections.OrderedDict \u8fd9\u4e2a\u7c7b\u578b\u5728\u6dfb\u52a0\u952e\u7684\u65f6\u5019\u4f1a\u4fdd\u6301\u987a\u5e8f\uff0c\u56e0\u6b64\u952e\u7684\u8fed\u4ee3\u6b21\u5e8f\u603b\u662f\u4e00\u81f4\u7684\u3002OrderedDict\u7684popitem\u65b9\u6cd5\u9ed8\u8ba4\u5220\u9664\u5e76\u8fd4\u56de\u7684\u662f\u5b57\u5178\u91cc\u7684\u6700\u540e\u4e00\u4e2a\u5143\u7d20\uff0c\u4f46\u662f\u5982\u679c\u50cfmy_odict.popitem(last=False)\u8fd9\u6837\u8c03\u7528\u5b83\uff0c\u90a3\u4e48\u5b83\u5220\u9664\u5e76\u8fd4\u56de\u7b2c\u4e00\u4e2a\u88ab\u6dfb\u52a0\u8fdb\u53bb\u7684\u5143\u7d20\u3002 collections.ChainMap \u8be5\u7c7b\u578b\u53ef\u4ee5\u5bb9\u7eb3\u6570\u4e2a\u4e0d\u540c\u7684\u6620\u5c04\u5bf9\u8c61\uff0c\u7136\u540e\u5728\u8fdb\u884c\u952e\u67e5\u627e\u64cd\u4f5c\u7684\u65f6\u5019\uff0c\u8fd9\u4e9b\u5bf9\u8c61\u4f1a\u88ab\u5f53\u4f5c\u4e00\u4e2a\u6574\u4f53\u88ab\u9010\u4e2a\u67e5\u627e\uff0c\u76f4\u5230\u952e\u88ab\u627e\u5230\u4e3a\u6b62\u3002\u8fd9\u4e2a\u529f\u80fd\u5728\u7ed9\u6709\u5d4c\u5957\u4f5c\u7528\u57df\u7684\u8bed\u8a00\u505a\u89e3\u91ca\u5668\u7684\u65f6\u5019\u5f88\u6709\u7528\uff0c\u53ef\u4ee5\u7528\u4e00\u4e2a\u6620\u5c04\u5bf9\u8c61\u6765\u4ee3\u8868\u4e00\u4e2a\u4f5c\u7528\u57df\u7684\u4e0a\u4e0b\u6587\u3002 collections.Counter \u8fd9\u4e2a\u6620\u5c04\u7c7b\u578b\u4f1a\u7ed9\u952e\u51c6\u5907\u4e00\u4e2a\u6574\u6570\u8ba1\u6570\u5668\u3002\u6bcf\u6b21\u66f4\u65b0\u4e00\u4e2a\u952e\u7684\u65f6\u5019\u90fd\u4f1a\u589e\u52a0\u8fd9\u4e2a\u8ba1\u6570\u5668\u3002\u6240\u4ee5\u8fd9\u4e2a\u7c7b\u578b\u53ef\u4ee5\u7528\u6765\u7ed9\u53ef\u6563\u5217\u8868\u5bf9\u8c61\u8ba1\u6570\uff0c\u6216\u8005\u662f\u5f53\u6210\u591a\u91cd\u96c6\u6765\u7528\u2014\u2014\u591a\u91cd\u96c6\u5408\u5c31\u662f\u96c6\u5408\u91cc\u7684\u5143\u7d20\u53ef\u4ee5\u51fa\u73b0\u4e0d\u6b62\u4e00\u6b21\u3002Counter\u5b9e\u73b0\u4e86+\u548c-\u8fd0\u7b97\u7b26\u7528\u6765\u5408\u5e76\u8bb0\u5f55\uff0c\u8fd8\u6709\u50cfmost_common([n])\u8fd9\u7c7b\u5f88\u6709\u7528\u7684\u65b9\u6cd5\u3002most_common([n])\u4f1a\u6309\u7167\u6b21\u5e8f\u8fd4\u56de\u6620\u5c04\u91cc\u6700\u5e38\u89c1\u7684n\u4e2a\u952e\u548c\u5b83\u4eec\u7684\u8ba1\u6570 collections.UserDict \u8fd9\u4e2a\u7c7b\u5176\u5b9e\u5c31\u662f\u628a\u6807\u51c6dict\u7528\u7eafPython\u53c8\u5b9e\u73b0\u4e86\u4e00\u904d\u3002\u8ddfOrderedDict\u3001ChainMap\u548cCounter\u8fd9\u4e9b\u5f00\u7bb1\u5373\u7528\u7684\u7c7b\u578b\u4e0d\u540c\uff0cUserDict\u662f\u8ba9\u7528\u6237\u7ee7\u627f\u5199\u5b50\u7c7b\u7684\u3002 \u4e0b\u9762\u7684\u4f8b\u5b50\u5229\u7528Counter\u6765\u8ba1\u7b97\u5355\u8bcd\u4e2d\u5404\u4e2a\u5b57\u6bcd\u51fa\u73b0\u7684\u6b21\u6570\uff1a str = 'abracadabra' ct = collections . Counter ( str ) print ( ct ) # Counter({'a': 5, 'b': 2, 'r': 2, 'c': 1, 'd': 1}) \u4e0d\u53ef\u53d8\u6620\u5c04\u7c7b\u578b\u3002 \u6807\u51c6\u5e93\u91cc\u6240\u6709\u7684\u6620\u5c04\u7c7b\u578b\u90fd\u662f\u53ef\u53d8\u7684\uff0c\u4f46\u6709\u65f6\u5019\u4f60\u4f1a\u6709\u8fd9\u6837\u7684\u9700\u6c42\uff0c\u6bd4\u5982\u4e0d\u80fd\u8ba9\u7528\u6237\u9519\u8bef\u5730\u4fee\u6539\u67d0\u4e2a\u6620\u5c04\u3002 \u4ecePython 3.3\u5f00\u59cb\uff0c types \u6a21\u5757\u4e2d\u5f15\u5165\u4e86\u4e00\u4e2a\u5c01\u88c5\u7c7b\u540d\u53eb MappingProxyType \u3002\u5982\u679c\u7ed9\u8fd9\u4e2a\u7c7b\u4e00\u4e2a\u6620\u5c04\uff0c\u5b83\u4f1a\u8fd4\u56de\u4e00\u4e2a\u53ea\u8bfb\u7684\u6620\u5c04\u89c6\u56fe\u3002\u867d\u7136\u662f\u4e2a\u53ea\u8bfb\u89c6\u56fe\uff0c\u4f46\u662f\u5b83\u662f\u52a8\u6001\u7684\u3002\u8fd9\u610f\u5473\u7740\u5982\u679c\u5bf9\u539f\u6620\u5c04\u505a\u51fa\u4e86\u6539\u52a8\uff0c\u6211\u4eec\u901a\u8fc7\u8fd9\u4e2a\u89c6\u56fe\u53ef\u4ee5\u89c2\u5bdf\u5230\uff0c\u4f46\u662f\u65e0\u6cd5\u901a\u8fc7\u8fd9\u4e2a\u89c6\u56fe\u5bf9\u539f\u6620\u5c04\u505a\u51fa\u4fee\u6539\u3002 \u901a\u8fc7\u4e0b\u4f8b\u53ef\u4ee5\u770b\u51fa\uff0c d \u4e2d\u7684\u5185\u5bb9\u53ef\u4ee5\u901a\u8fc7 d_proxy \u770b\u5230\u3002\u4f46\u662f\u901a\u8fc7 d_proxy \u5e76\u4e0d\u80fd\u505a\u4efb\u4f55\u4fee\u6539\u3002 d_proxy \u662f\u52a8\u6001\u7684\uff0c\u4e5f\u5c31\u662f\u8bf4\u5bf9 d \u6240\u505a\u7684\u4efb\u4f55\u6539\u52a8\u90fd\u4f1a\u53cd\u9988\u5230\u5b83\u4e0a\u9762\u3002 from types import MappingProxyType d = { 1 : 'A' } d_proxy = MappingProxyType ( d ) print ( d ) # {1: 'A'} print ( d_proxy ) # {1: 'A'} print ( d [ 1 ]) # A print ( d_proxy [ 1 ]) # A d [ 2 ] = 'W' print ( d ) # {1: 'A', 2: 'W'} d_proxy [ 2 ] = 'W' # TypeError: 'mappingproxy' object does not support item assignment print ( d_proxy ) # {1: 'A', 2: 'W'} 1.5 \u96c6\u5408\uff08set\uff09 \u00b6 \u201c\u96c6\u201d\u8fd9\u4e2a\u6982\u5ff5\u5728Python\u4e2d\u7b97\u662f\u6bd4\u8f83\u5e74\u8f7b\u7684\uff0c\u540c\u65f6\u5b83\u7684\u4f7f\u7528\u7387\u4e5f\u6bd4\u8f83\u4f4e\u3002set\u548c\u5b83\u7684\u4e0d\u53ef\u53d8\u7684\u59ca\u59b9\u7c7b\u578bfrozenset\u76f4\u5230Python 2.3\u624d\u9996\u6b21\u4ee5\u6a21\u5757\u7684\u5f62\u5f0f\u51fa\u73b0\uff0c\u7136\u540e\u5728Python 2.6\u4e2d\u5b83\u4eec\u5347\u7ea7\u6210\u4e3a\u5185\u7f6e\u7c7b\u578b\u3002 \u96c6\u5408(set) \uff0c\u5305\u542b\u4e0d\u53ef\u53d8\u7684\u96c6\u5408\uff08frozenset\uff09\uff0c\u662f\u4e00\u79cd\u65e0\u5e8f\u4e14\u5143\u7d20\u552f\u4e00\u7684\u5e8f\u5217\uff0c\u6240\u4ee5\u96c6\u5408\u7684\u672c\u8d28\u662f\u8bb8\u591a\u552f\u4e00\u5bf9\u8c61\u7684\u805a\u96c6\u3002 \u548c\u5b57\u5178\u7c7b\u4f3c\uff0c\u96c6\u5408\u7684\u5143\u7d20\u662f\u4e0d\u53ef\u53d8\u7684\u3002\u53ef\u4ee5\u8ba4\u4e3a\u96c6\u5408\u4e5f\u50cf\u5b57\u5178\uff0c\u4f46\u662f\u53ea\u6709\u952e\u6ca1\u6709\u503c\u3002\u57fa\u672c\u529f\u80fd\u662f\u8fdb\u884c\u6210\u5458\u5173\u7cfb\u6d4b\u8bd5\u548c\u5220\u9664\u91cd\u590d\u5143\u7d20\u3002\u6240\u4ee5\u96c6\u5408\u53e6\u4e00\u4e2a\u7528\u9014\u662f\u53bb\u91cd\u590d\u3002 \u96c6\u5408\u4e2d\u7684\u5143\u7d20\u5fc5\u987b\u662f\u53ef\u6563\u5217\u7684\uff0cset\u7c7b\u578b\u672c\u8eab\u662f\u4e0d\u53ef\u6563\u5217\u7684\uff0c\u4f46\u662ffrozenset\u53ef\u4ee5\u3002\u56e0\u6b64\u53ef\u4ee5\u521b\u5efa\u4e00\u4e2a\u5305\u542b\u4e0d\u540cfrozenset\u7684set\u3002 \u96c6\u5408\u53ef\u4ee5\u6709\u4e24\u79cd\u521b\u5efa\u65b9\u5f0f\uff1a\u901a\u8fc7set()\u51fd\u6570\u6216\u8005{}\u6765\u521b\u5efa\uff08\u7528\u5927\u62ec\u53f7\u62ec\u4f4f\u7684\u5185\u5bb9\uff0cPython3\u81ea\u52a8\u5b9a\u4e49\u4e3a\u96c6\u5408\uff09\u3002 \u96c6\u5408\u4e0d\u5c5e\u4e8e\u5e8f\u5217\u7c7b\u6570\u636e\uff0c \u96c6\u5408\u4e0d\u652f\u6301\u901a\u8fc7\u7d22\u5f15\u8bbf\u95ee\u6307\u5b9a\u5143\u7d20\uff0c\u4f46\u53ef\u4ee5\u589e\u52a0\u548c\u5220\u9664\u5143\u7d20\u3002 \u9762\u7684\u4f8b\u5b50\u662f\u6c42 haystacke \u548c needles \u4e24\u4e2a\u96c6\u5408\u7684\u4ea4\u96c6\u5143\u7d20\u4e2a\u6570\u3002 haystacke = { 'a' , 'b' , 'c' , 'd' , 'e' , 'f' , 'g' , 'h' , 'f' , 'g' , 'h' , 'c' , 'd' , 'e' , 'c' , 'd' , 'e' , 'f' , 'g' , 'h' } needles = { 'c' , 'h' , 'w' } type ( haystacke ) # type ( needles ) # # \u4f20\u7edf\u65b9\u6cd5 found = 0 for i in needles : if i in haystacke : found += 1 print ( found ) # 2 # \u96c6\u5408\u65b9\u6cd5\u4e00 found = len ( needles & haystacke ) print ( found ) # 2 # \u96c6\u5408\u65b9\u6cd5\u4e8c found = len ( needles . intersection ( haystacke )) print ( found ) # 2 \u96c6\u5408\u5b9e\u73b0\u4e86\u5f88\u591a\u57fa\u7840\u7684\u4e2d\u7f00\u8fd0\u7b97\u7b26\uff0c\u6bd4\u5982\uff0c\u96c6\u5408\u652f\u6301\u6570\u5b66\u4e0a\u7684\u96c6\u5408\u64cd\u4f5c\uff1a\u5e76\u96c6\u3001\u4ea4\u96c6\u3001\u5dee\u96c6\u3001\u5bf9\u79f0\u5dee\u96c6\u3002 \u65b9\u6cd5\u540d\u79f0 \u8bf4\u660e add() \u4e3a\u96c6\u5408\u6dfb\u52a0\u5143\u7d20 update() \u7ed9\u96c6\u5408\u6dfb\u52a0\u5143\u7d20 clear() \u79fb\u9664\u96c6\u5408\u4e2d\u7684\u6240\u6709\u5143\u7d20 copy() \u62f7\u8d1d\u4e00\u4e2a\u96c6\u5408 remove() \u79fb\u9664\u6307\u5b9a\u5143\u7d20 pop() \u968f\u673a\u79fb\u9664\u5143\u7d20 discard() \u5220\u9664\u96c6\u5408\u4e2d\u6307\u5b9a\u7684\u5143\u7d20 < \u6216\u8005issubset() \u5224\u65ad\u6307\u5b9a\u96c6\u5408\u662f\u5426\u4e3a\u8be5\u65b9\u6cd5\u53c2\u6570\u96c6\u5408\u7684\u5b50\u96c6 | \u6216\u8005union() \u8fd4\u56de\u4e24\u4e2a\u96c6\u5408\u7684\u5e76\u96c6 & \u6216\u8005intersection() \u8fd4\u56de\u96c6\u5408\u7684\u4ea4\u96c6 intersection_update() \u8fd4\u56de\u96c6\u5408\u7684\u4ea4\u96c6 - \u6216\u8005difference() \u8fd4\u56de\u591a\u4e2a\u96c6\u5408\u7684\u5dee\u96c6 difference_update() \u79fb\u9664\u96c6\u5408\u4e2d\u7684\u5143\u7d20\uff0c\u8be5\u5143\u7d20\u5728\u6307\u5b9a\u7684\u96c6\u5408\u4e5f\u5b58\u5728 ^ \u6216\u8005symmetric_difference() \u8fd4\u56de\u4e24\u4e2a\u96c6\u5408\u4e2d\u4e0d\u91cd\u590d\u7684\u5143\u7d20\u96c6\u5408(\u4e24\u96c6\u5408\u9664\u53bb\u4ea4\u96c6\u90e8\u5206\u7684\u5143\u7d20) symmetric_difference_update() \u79fb\u9664\u5f53\u524d\u96c6\u5408\u4e2d\u5728\u53e6\u5916\u4e00\u4e2a\u6307\u5b9a\u96c6\u5408\u76f8\u540c\u7684\u5143\u7d20\uff0c\u5e76\u5c06\u53e6\u5916\u4e00\u4e2a\u6307\u5b9a\u96c6\u5408\u4e2d\u4e0d\u540c\u7684\u5143\u7d20\u63d2\u5165\u5230\u5f53\u524d\u96c6\u5408\u4e2d isdisjoint() \u5224\u65ad\u4e24\u4e2a\u96c6\u5408\u662f\u5426\u5305\u542b\u76f8\u540c\u7684\u5143\u7d20\uff0c\u5982\u679c\u6ca1\u6709\u8fd4\u56de True\uff0c\u5426\u5219\u8fd4\u56de False issuperset() \u5224\u65ad\u8be5\u65b9\u6cd5\u7684\u53c2\u6570\u96c6\u5408\u662f\u5426\u4e3a\u6307\u5b9a\u96c6\u5408\u7684\u5b50\u96c6 \u4e3e\u4f8b\uff1a a = { 'a' , 'b' , 'c' , 1 , 2 } b = { 1 , 'c' , 'd' } \u5e76\u96c6(a\u548cb\u4e2d\u7684\u6240\u6709\u4e0d\u540c\u5143\u7d20)\u3002 print ( a . union ( b )) # {'c', 1, 2, 'd', 'a', 'b'} print ( a | b ) # {'c', 1, 2, 'd', 'a', 'b'} \u4ea4\u96c6(a\u3001b\u4e2d\u540c\u65f6\u5305\u542b\u7684\u5143\u7d20)\u3002 print ( a . intersection ( b )) # {'c', 1} print ( a & b ) # {'c', 1} \u5c06a\u7684\u5185\u5bb9\u8bbe\u7f6e\u4e3aa\u548cb\u7684\u4ea4\u96c6\u3002 a = { 'a' , 'b' , 'c' , 1 , 2 } b = { 1 , 'c' , 'd' } a . intersection_update ( b ) print ( a ) # {1, 'c'} \u5728a\u4e0d\u5728b\u7684\u5143\u7d20\u3002 print ( a . difference ( b )) # {'a', 2, 'b'} print ( a - b ) # {2, 'a', 'b'} \u5c06a\u7684\u5185\u5bb9\u8bbe\u4e3a\u5728a\u4e0d\u5728b\u7684\u5143\u7d20\u3002 a = { 'a' , 'b' , 'c' , 1 , 2 } b = { 1 , 'c' , 'd' } a . difference_update ( b ) print ( a ) # {2, 'b', 'a'} a = { 'a' , 'b' , 'c' , 1 , 2 } b = { 1 , 'c' , 'd' } a -= b print ( a ) # {2, 'a', 'b'} \u5c06\u5143\u7d20\u52a0\u5165\u96c6\u5408a\u3002 a . add ( 7 ) print ( a ) # {1, 2, 'c', 7, 'a', 'b'} \u6bcf\u6b21\u8f93\u51fa\u7684\u987a\u5e8f\u662f\u4e0d\u4e00\u6837\u7684 \u4ece\u96c6\u5408a\u79fb\u9664\u67d0\u4e2a\u5143\u7d20\u3002 a . remove ( 7 ) print ( a ) # {1, 2, 'c', 'a', 'b'} \u5982\u679ca\u88ab\u6e05\u7a7a\uff0c\u5219\u62a5\u9519 KeyError: 7 \u6240\u6709\u5728a\u6216b\u4e2d\uff0c\u4f46\u4e0d\u662f\u540c\u65f6\u5728a\u3001b\u4e2d\u7684\u5143\u7d20\u3002 print ( a . symmetric_difference ( b )) # {2, 'd', 'b', 'a'} print ( a ^ b ) # {2, 'd', 'b', 'a'} \u5c06a\u7684\u5185\u5bb9\u8bbe\u4e3a\u6240\u6709\u5728a\u6216b\u4e2d\uff0c\u4f46\u4e0d\u662f\u540c\u65f6\u5728a\u3001b\u4e2d\u7684\u5143\u7d20\u3002 a = { 'a' , 'b' , 'c' , 1 , 2 } b = { 1 , 'c' , 'd' } a . symmetric_difference_update ( b ) print ( a ) # {'a', 2, 'd', 'b'} a = { 'a' , 'b' , 'c' , 1 , 2 } b = { 1 , 'c' , 'd' } a ^= b print ( a ) # {2, 'd', 'a', 'b'} \u5982\u679ca\u5305\u542b\u4e8eb\uff0c\u8fd4\u56deTure\u3002 print ( a . issubset ( b )) # False \u5c06a\u7684\u5185\u5bb9\u8bbe\u7f6e\u4e3aa\u548cb\u7684\u5e76\u96c6\u3002 print ( a ) # {'a', 2, 'd', 'b'} a = { 'a' , 'b' , 'c' , 1 , 2 } a . update ( b ) print ( a ) # {1, 2, 'a', 'b', 'd', 'c'} \u79fb\u9664\u4efb\u610f\u5143\u7d20\uff0c\u5982\u679c\u96c6\u5408\u662f\u7a7a\u7684\uff0c\u629b\u51fakeyError\u3002 a . pop () # \u968f\u673a\u79fb\u9664\u67d0\u4e2a\u5143\u7d20\uff0c\u6ca1\u6709\u8f93\u5165\u53d8\u91cf\uff0c\u5982\u679c\u96c6\u5408\u662f\u7a7a\u7684\uff0c\u629b\u51faKeyError: 'pop from an empty set' print ( a ) # {2, 1, 'd', 'b', 'a'} \u5c06\u96c6\u5408\u91cd\u7f6e\u4e3a\u7a7a\uff0c\u6e05\u7a7a\u6240\u6709\u5143\u7d20\u3002 a . clear () print ( a ) # set() \u96c6\u5408\u7684\u5143\u7d20\u5fc5\u987b\u662f\u4e0d\u53ef\u53d8\u7684\uff0c\u5982\u679c\u60f3\u8981\u5305\u542b\u5217\u8868\u578b\u7684\u5143\u7d20\uff0c\u5fc5\u987b\u5148\u8f6c\u6362\u4e3a\u5143\u7ec4\u3002 my_data1 = [ 1 , 2 , 3 , 4 ] my_data2 = [ 3 , 4 , 5 , 6 ] my_set = { tuple ( my_data1 ), tuple ( my_data2 )} print ( my_set ) # {(1, 2, 3, 4), (3, 4, 5, 6)} 1.6 \u5143\u7ec4\uff08tuple\uff09 \u00b6 Python \u7684\u5143\u7ec4\u4e0e\u5217\u8868\u7c7b\u4f3c\uff0c\u4e0d\u540c\u4e4b\u5904\u5728\u4e8e\u5143\u7ec4\u7684\u5143\u7d20\u4e0d\u80fd\u4fee\u6539\u3002 \u5143\u7ec4\u4f7f\u7528\u5c0f\u62ec\u53f7( )\uff0c\u5217\u8868\u4f7f\u7528\u65b9\u62ec\u53f7[ ]\u3002 \u5143\u7ec4\u4e2d\u53ea\u5305\u542b\u4e00\u4e2a\u5143\u7d20\u65f6\uff0c\u9700\u8981\u5728\u5143\u7d20\u540e\u9762\u6dfb\u52a0\u9017\u53f7 \uff0c\u5426\u5219\u62ec\u53f7\u4f1a\u88ab\u5f53\u4f5c\u8fd0\u7b97\u7b26\u4f7f\u7528\u3002 \u5143\u7ec4\u53ef\u4ee5\u4f7f\u7528\u4e0b\u6807\u7d22\u5f15\u6765\u8bbf\u95ee\u5143\u7ec4\u4e2d\u7684\u503c\u3002 \u5143\u7ec4\u4e2d\u7684\u5143\u7d20\u503c\u662f\u4e0d\u5141\u8bb8\u4fee\u6539\u7684\uff0c\u4f46\u6211\u4eec\u53ef\u4ee5\u5bf9\u5143\u7ec4\u8fdb\u884c\u8fde\u63a5\u7ec4\u5408\u3002 \u5143\u7ec4\u4e2d\u7684\u5143\u7d20\u503c\u662f\u4e0d\u5141\u8bb8\u5220\u9664\u7684\uff0c\u4f46\u6211\u4eec\u53ef\u4ee5\u4f7f\u7528del\u8bed\u53e5\u6765\u5220\u9664\u6574\u4e2a\u5143\u7ec4\u3002 # \u6b64\u5904\u62ec\u53f7\u88ab\u89e3\u6790\u4e3a\u8fd0\u7b97\u7b26\uff0c\u9700\u8981\u5728\u540e\u9762\u52a0\u4e0a\u9017\u53f7\u624d\u4f1a\u88ab\u89e3\u91ca\u4e3a\u5143\u7ec4 tup1 = ( 10 ) print ( type ( tup1 )) # tup1 = ( 10 ,) print ( type ( tup1 )) # \u521b\u5efa\u5143\u7ec4\u6700\u7b80\u5355\u7684\u529e\u6cd5\u5c31\u662f\u7528\u9017\u53f7\u5206\u9694\u5e8f\u5217\u503c\u3002\u5143\u7ec4\u5bf9\u6570\u636e\u7c7b\u578b\u6ca1\u6709\u4e00\u81f4\u6027\u8981\u6c42\u3002 tup = 4 , 5 , 6 print ( tup ) # (4, 5, 6) nested_tup = ( 4 , 5 , 6 ), ( 7 , 8 ) print ( nested_tup ) # # ((4, 5, 6), (7, 8)) tup = ( 'a' , 'b' , { 'one' : 1 }) print ( type ( tup )) # \u4f7f\u7528\u52a0\u53f7\uff08+\uff09\u8fdb\u884c\u5143\u7ec4\u8fde\u63a5\u5408\u5e76\u3002 tup = tuple (( 4 , None , 'fool' ) + ( 6 , 0 ) + ( 'bar' ,)) print ( tup ) # (4, None, 'fool', 6, 0, 'bar') \u5143\u7ec4\u7684\u4e0d\u53ef\u53d8\u6307\u7684\u662f**\u5143\u7ec4\u6240\u6307\u5411\u7684\u5185\u5b58\u4e2d\u7684\u5185\u5bb9\u4e0d\u53ef\u53d8**\u3002 tup = ( 'h' , 'e' , 'l' , 'l' , 'o' ) print ( id ( tup )) # 139820353350208 tup = ( 1 , 2 , 3 , 4 , 5 ) print ( id ( tup )) # 139820353298896 tup [ 0 ] = 'x' # Traceback (most recent call last): # File \"\", line 1, in # TypeError: 'tuple' object does not support item assignment \u5c06\u5143\u7ec4\u4e58\u4ee5\u6574\u6570\uff0c\u5219\u4f1a\u548c\u5217\u8868\u4e00\u6837\uff0c\u751f\u6210\u542b\u6709\u591a\u4efd\u62f7\u8d1d\u7684\u5143\u7ec4\u3002\u5bf9\u8c61\u81ea\u8eab\u5e76\u6ca1\u6709\u590d\u5236\uff0c\u53ea\u662f\u6307\u5411\u5b83\u4eec\u7684\u5f15\u7528\u8fdb\u884c\u4e86\u590d\u5236\u3002 tup = tuple (( 'fool' , 'bar' ) * 4 ) print ( tup ) # ('fool', 'bar', 'fool', 'bar', 'fool', 'bar', 'fool', 'bar') \u5982\u679c\u5143\u7ec4\u4e2d\u7684\u4e00\u4e2a\u5bf9\u8c61\u662f\u53ef\u53d8\u7684\uff0c\u4f8b\u5982\u5217\u8868\uff0c\u4f60\u53ef\u4ee5\u5728\u5b83\u5185\u90e8\u8fdb\u884c\u4fee\u6539\u3002 tup = tuple ([ 'foo' , [ 4 , 5 , 6 ], True ]) tup [ 1 ] . append ( 0 ) print ( tup ) # ('foo', [4, 5, 6, 0], True) tup [ 1 ] . append ([ 9 ]) print ( tup ) # ('foo', [4, 5, 6, 0, [9]], True) \u4f7f\u7528tuple\u51fd\u6570\u5c06\u4efb\u610f\u5e8f\u5217\u6216\u8fed\u4ee3\u5668\u8f6c\u6362\u4e3a\u5143\u7ec4\u3002 tup = tuple ([ 4 , 5 , 6 ]) print ( tup ) # (4, 5, 6) tup = tuple ( 'string' ) print ( tup ) # ('s', 't', 'r', 'i', 'n', 'g') print ( tup [ 2 ]) # r # \u5143\u7ec4\u7684\u5143\u7d20\u53ef\u4ee5\u901a\u8fc7\u4e2d\u62ec\u53f7[]\u6765\u83b7\u53d6 \u5982\u679c\u8981\u5c06\u5143\u7ec4\u578b\u7684\u8868\u8fbe\u5f0f\u8d4b\u503c\u7ed9\u53d8\u91cf\uff0cPython\u4f1a\u5bf9\u7b49\u53f7\u53f3\u8fb9\u7684\u503c\u8fdb\u884c \u62c6\u5305 \u3002 tup = ( 9 , 5 , ( 8 , 7 )) a , b , c = tup print ( a ) # 9 print ( b ) # 5 print ( c ) # (8, 7) a , b , ( c , d ) = tup print ( a ) # 9 print ( b ) # 5 print ( c ) # 8 print ( d ) # 7 tup = ( 9 , 5 , ( 8 , 7 )) a , b , c = tup c , a = a , c # \u5229\u7528\u62c6\u5305\u5b9e\u73b0\u4ea4\u6362 print ( a ) # (8, 7) print ( b ) # 5 print ( c ) # 9 \u5229\u7528\u62c6\u5305\u5b9e\u73b0\u904d\u5386\u5143\u7ec4\u6216\u5217\u8868\u7ec4\u6210\u7684\u5e8f\u5217\u3002 seq = [( 1 , 2 , 3 ), ( 4 , 5 , 6 ), ( 7 , 8 , 9 )] for a , b , c in seq : print ( 'a= {0} , b= {0} , c= {0} ' . format ( a , b , c )) # \u5217\u8868\u6bcf\u4e2a\u5143\u7d20\u7684\u53d6\u503c\u987a\u5e8f # a=1, b=1, c=1 # a=4, b=4, c=4 # a=7, b=7, c=7 print ( 'a= {0} , b= {1} , c= {2} ' . format ( a , b , c )) # a=1, b=2, c=3 # a=4, b=5, c=6 # a=7, b=8, c=9 print ( 'a= {2} , b= {0} , c= {1} ' . format ( a , b , c )) # a=3, b=1, c=2 # a=6, b=4, c=5 # a=9, b=7, c=8 \u5143\u7ec4\u62c6\u5305\u529f\u80fd\u8fd8\u5305\u62ec\u7279\u6b8a\u7684\u8bed\u6cd5*rest\u3002\u5f88\u591aPython\u7f16\u7a0b\u8005\u4f1a\u4f7f\u7528\u4e0b\u5212\u7ebf\uff08_\uff09\u6765\u8868\u793a\u4e0d\u60f3\u8981\u7684\u53d8\u91cf\u3002 values = 1 , 2 , 3 , 4 , 5 a , b , * rest = values print ( a ) # 1 print ( b ) # 2 print ( * rest ) # 3 4 5 a , b , * _ = values print ( * _ ) # 3 4 5 \u5177\u540d\u5143\u7ec4\u3002 collections.namedtuple \u662f\u4e00\u4e2a\u5de5\u5382\u51fd\u6570\uff0c\u5b83\u53ef\u4ee5\u7528\u6765\u6784\u5efa\u4e00\u4e2a\u5e26\u5b57\u6bb5\u540d\u7684\u5143\u7ec4\u548c\u4e00\u4e2a\u6709\u540d\u5b57\u7684\u7c7b\u3002 \u7528namedtuple\u6784\u5efa\u7684\u7c7b\u7684\u5b9e\u4f8b\u6240\u6d88\u8017\u7684\u5185\u5b58\u8ddf\u5143\u7ec4\u662f\u4e00\u6837\u7684\uff0c\u56e0\u4e3a\u5b57\u6bb5\u540d\u90fd\u88ab\u5b58\u5728\u5bf9\u5e94\u7684\u7c7b\u91cc\u9762\u3002 \u521b\u5efa\u4e00\u4e2a\u5177\u540d\u5143\u7ec4\u9700\u8981\u4e24\u4e2a\u53c2\u6570\uff0c\u4e00\u4e2a\u662f\u7c7b\u540d( City )\uff0c\u53e6\u4e00\u4e2a\u662f\u7c7b\u7684\u5404\u4e2a\u5b57\u6bb5\u7684\u540d\u5b57( 'name country population coordinates' )\u3002\u540e\u8005\u53ef\u4ee5\u662f\u7531\u6570\u4e2a\u5b57\u7b26\u4e32\u7ec4\u6210\u7684\u53ef\u8fed\u4ee3\u5bf9\u8c61\uff0c\u6216\u8005\u662f\u7531\u7a7a\u683c\u5206\u9694\u5f00\u7684\u5b57\u6bb5\u540d\u7ec4\u6210\u7684\u5b57\u7b26\u4e32\u3002 \u5b58\u653e\u5728\u5bf9\u5e94\u5b57\u6bb5\u91cc\u7684\u6570\u636e\u8981\u4ee5\u4e00\u4e32\u53c2\u6570\u7684\u5f62\u5f0f\u4f20\u5165\u5230\u6784\u9020\u51fd\u6570\u4e2d\uff08\u6ce8\u610f\uff0c\u5143\u7ec4\u7684\u6784\u9020\u51fd\u6570\u5374\u53ea\u63a5\u53d7\u5355\u4e00\u7684\u53ef\u8fed\u4ee3\u5bf9\u8c61\uff09\u3002 \u5177\u540d\u5143\u7ec4\u8fd8\u6709\u4e00\u4e9b\u81ea\u5df1\u4e13\u6709\u7684\u5c5e\u6027\u3002\u4e0b\u9762\u5c55\u793a\u4e86\u51e0\u4e2a\u6700\u6709\u7528\u7684\uff1a _fields \u7c7b\u5c5e\u6027\u3001\u7c7b\u65b9\u6cd5 _make(iterable) \u548c\u5b9e\u4f8b\u65b9\u6cd5 _asdict() \u3002 _fields \u5c5e\u6027\u662f\u4e00\u4e2a\u5305\u542b\u8fd9\u4e2a\u7c7b\u6240\u6709\u5b57\u6bb5\u540d\u79f0\u7684\u5143\u7ec4\u3002 \u7528 _make() \u901a\u8fc7\u63a5\u53d7\u4e00\u4e2a\u53ef\u8fed\u4ee3\u5bf9\u8c61\u6765\u751f\u6210\u8fd9\u4e2a\u7c7b\u7684\u4e00\u4e2a\u5b9e\u4f8b\uff0c\u5b83\u7684\u4f5c\u7528\u8ddf City(*delhi_data) \u662f\u4e00\u6837\u7684\u3002 _asdict() \u628a\u5177\u540d\u5143\u7ec4\u4ee5 collections.OrderedDict \u7684\u5f62\u5f0f\u8fd4\u56de\uff0c\u6211\u4eec\u53ef\u4ee5\u5229\u7528\u5b83\u6765\u628a\u5143\u7ec4\u91cc\u7684\u4fe1\u606f\u53cb\u597d\u5730\u5448\u73b0\u51fa\u6765\u3002 from collections import namedtuple City = namedtuple ( 'City' , 'name country population coordinates' ) tokyo = City ( 'Tokyo' , 'JP' , 36.933 , ( 35.689722 , 139691667 )) print ( tokyo ) # City(name='Tokyo', country='JP', population=36.933, coordinates=(35.689722, 139691667)) print ( tokyo . population ) # 36.933 print ( tokyo [ 3 ]) # (35.689722, 139691667) print ( City . _fields ) # ('name', 'country', 'population', 'coordinates') LatLong = namedtuple ( 'LatLong' , 'lat long' ) delhi_data = ( 'Delhi NCR' , 'IN' , 21.935 , LatLong ( 28.613899 , 77.208889 )) delhi = City . _make ( delhi_data ) print ( delhi ) # City(name='Delhi NCR', country='IN', population=21.935, coordinates=LatLong(lat=28.613899, long=77.208889)) print ( delhi . _asdict ()) # OrderedDict([('name', 'Delhi NCR'), ('country', 'IN'), ('population', 21.935), ('coordinates', LatLong(lat=28.613899, long=77.208889))]) for key , value in delhi . _asdict () . items (): print ( key + ':' , value ) # name: Delhi NCR # country: IN # population: 21.935 # coordinates: LatLong(lat=28.613899, long=77.208889) \u5143\u7ec4\u8fd8\u6709\u7b2c\u4e8c\u91cd\u529f\u80fd\uff1a\u4f5c\u4e3a\u4e0d\u53ef\u53d8\u5217\u8868\u7684\u5143\u7ec4\u3002 \u4e0b\u9762\u662f\u5217\u8868\u6216\u5143\u7ec4\u7684\u65b9\u6cd5\u548c\u5c5e\u6027\u5bf9\u6bd4\u3002\u9664\u4e86\u8ddf\u589e\u51cf\u5143\u7d20\u76f8\u5173\u7684\u65b9\u6cd5\u4e4b\u5916\uff0c\u5143\u7ec4\u652f\u6301\u5217\u8868\u7684\u5176\u4ed6\u6240\u6709\u65b9\u6cd5\u3002\u8fd8\u6709\u4e00\u4e2a\u4f8b\u5916\uff0c\u5143\u7ec4\u6ca1\u6709__reversed__\u65b9\u6cd5\u3002 \u4e00\u4e2a\u5173\u4e8e+=\u548c*=\u7684\u8c1c\u9898\u3002 \u4e0b\u9762\u7684\u4f8b\u5b50\u5c55\u793a\u4e86 *= \u5728\u53ef\u53d8\u548c\u4e0d\u53ef\u53d8\u5e8f\u5217\u4e0a\u7684\u4f5c\u7528\u3002\u5217\u8868\u7684ID\u6ca1\u53d8\uff0c\u65b0\u5143\u7d20\u8ffd\u52a0\u5230\u5217\u8868\u4e0a\uff0c\u4f46\u6267\u884c\u589e\u91cf\u4e58\u6cd5\u540e\uff0c\u65b0\u7684\u5143\u7ec4\u88ab\u521b\u5efa\u3002 list1 = [ 1 , 2 , 3 , 4 ] id ( list1 ) # 140409777308808 list1 *= 2 print ( list1 ) # [1, 2, 3, 4, 1, 2, 3, 4] id ( list1 ) # 140409777308808 tuple1 = ( 1 , 2 , 3 , 4 ) id ( tuple1 ) # 140409777230536 tuple1 *= 2 print ( tuple1 ) # (1, 2, 3, 4, 1, 2, 3, 4) id ( tuple1 ) # 140409780104888 \u4f46\u5bf9\u4e8e\u4e0b\u9762\u7684\u4f8b\u5b50\uff0c\u867d\u7136 tuple1[2] += [50, 60] \u6267\u884c\u65f6\u6709\u5f02\u5e38\u629b\u51fa\uff0c\u4f46 tuple1 \u5374\u88ab\u4fee\u6539\u4e86\u3002 t = ( 1 , 2 , [ 10 , 20 ]) t [ 2 ] += [ 50 , 60 ] # TypeError: 'tuple' object does not support item assignment print ( t ) # (1, 2, [10, 20, 50, 60]) \u4e0b\u56fe\u5927\u81f4\u63cf\u8ff0\u4e86\u4e0a\u8ff0\u6267\u884c\u8fc7\u7a0b\u3002 \u4e3a\u4e86\u907f\u514d\u4e0a\u9762\u60c5\u51b5\u7684\u53d1\u751f\uff0c\u6211\u4eec**\u4e0d\u8981\u628a\u53ef\u53d8\u5bf9\u8c61\u653e\u5728\u5143\u7ec4\u91cc\u9762**\u3002\u589e\u91cf\u8d4b\u503c\u4e0d\u662f\u4e00\u4e2a\u539f\u5b50\u64cd\u4f5c\uff0c\u5b83\u867d\u7136\u629b\u51fa\u4e86\u5f02\u5e38\uff0c\u4f46\u8fd8\u662f\u5b8c\u6210\u4e86\u64cd\u4f5c\u3002 1.7 \u5185\u5b58\u89c6\u56feMemoryview \u00b6 memoryview \u662f\u4e00\u4e2a\u5185\u7f6e\u7c7b\uff0c\u5b83\u80fd\u8ba9\u7528\u6237\u5728\u4e0d\u590d\u5236\u5185\u5bb9\u7684\u60c5\u51b5\u4e0b\u64cd\u4f5c\u540c\u4e00\u4e2a\u6570\u7ec4\u7684\u4e0d\u540c\u5207\u7247\u3002 \u5185\u5b58\u89c6\u56fe\u5176\u5b9e\u662f\u6cdb\u5316\u548c\u53bb\u6570\u5b66\u5316\u7684NumPy\u6570\u7ec4\u3002\u5b83\u8ba9\u4f60\u5728\u4e0d\u9700\u8981\u590d\u5236\u5185\u5bb9\u7684\u524d\u63d0\u4e0b\uff0c\u5728\u6570\u636e\u7ed3\u6784\u4e4b\u95f4\u5171\u4eab\u5185\u5b58\u3002 \u5176\u4e2d\u6570\u636e\u7ed3\u6784\u53ef\u4ee5\u662f\u4efb\u4f55\u5f62\u5f0f\uff0c\u6bd4\u5982PIL\u56fe\u7247\u3001SQLite\u6570\u636e\u5e93\u548cNumPy\u7684\u6570\u7ec4\uff0c\u7b49\u7b49\u3002\u8fd9\u4e2a\u529f\u80fd\u5728\u5904\u7406\u5927\u578b\u6570\u636e\u96c6\u5408\u7684\u65f6\u5019\u975e\u5e38\u91cd\u8981\u3002 memoryview.cast \u7684\u6982\u5ff5\u8ddf\u6570\u7ec4\u6a21\u5757\u7c7b\u4f3c\uff0c\u80fd\u7528\u4e0d\u540c\u7684\u65b9\u5f0f\u8bfb\u5199\u540c\u4e00\u5757\u5185\u5b58\u6570\u636e\uff0c\u800c\u4e14\u5185\u5bb9\u5b57\u8282\u4e0d\u4f1a\u968f\u610f\u79fb\u52a8\u3002\u8fd9\u8ddfC\u8bed\u8a00\u4e2d\u7c7b\u578b\u8f6c\u6362\u7684\u6982\u5ff5\u5dee\u4e0d\u591a\u3002 memoryview.cast \u4f1a\u628a\u540c\u4e00\u5757\u5185\u5b58\u91cc\u7684\u5185\u5bb9\u6253\u5305\u6210\u4e00\u4e2a\u5168\u65b0\u7684memoryview\u5bf9\u8c61\u7ed9\u4f60\u3002 array \u91cc\u9762\u7684Type code\uff1a 'b' signed integer 1 'B' unsigned integer 1 'u' Unicode character 2 (see note) 'h' signed integer 2 'H' unsigned integer 2 'i' signed integer 2 'I' unsigned integer 2 'l' signed integer 4 'L' unsigned integer 4 'q' signed integer 8 (see note) 'Q' unsigned integer 8 (see note) 'f' floating point 4 'd' floating point 8 numbers = array ( 'h' , [ - 2 , - 1 , 0 , 1 , 2 ]) # array('h', [-2, -1, 0, 1, 2]) # \u75285\u4e2a\u77ed\u6574\u578b\u6709\u7b26\u53f7\u6574\u6570\u7684\u6570\u7ec4\uff08\u7c7b\u578b\u7801\u662f'h'\uff09\u521b\u5efa\u4e00\u4e2amemoryview\u3002 memv = memoryview ( numbers ) # memv\u91cc\u76845\u4e2a\u5143\u7d20\u8ddf\u6570\u7ec4\u91cc\u7684\u6ca1\u6709\u533a\u522b\u3002 print ( len ( memv )) # 5 print ( memv [ 0 ]) # -2 print ( memv . tolist ()) # [-2, -1, 0, 1, 2] # \u521b\u5efa\u4e00\u4e2amemv_oct\uff0c\u8fd9\u4e00\u6b21\u662f\u628amemv\u91cc\u7684\u5185\u5bb9\u8f6c\u6362\u6210'B'\u7c7b\u578b\uff0c\u4e5f\u5c31\u662f\u65e0\u7b26\u53f7\u5b57\u7b26\u3002 memv_oct = memv . cast ( 'B' ) print ( memv_oct . tolist ()) # [254, 255, 255, 255, 0, 0, 1, 0, 2, 0] # \u628a\u4f4d\u4e8e\u4f4d\u7f6e5\u7684\u5b57\u8282\u8d4b\u503c\u62104\u3002\u56e0\u4e3a\u6211\u4eec\u628a\u53602\u4e2a\u5b57\u8282\u7684\u6574\u6570\u7684\u9ad8\u4f4d\u5b57\u8282\u6539\u6210\u4e864\uff0c\u6240\u4ee5\u8fd9\u4e2a\u6709\u7b26\u53f7\u6574\u6570\u7684\u503c\u5c31\u53d8\u6210\u4e861024\u3002 memv_oct [ 5 ] = 4 print ( numbers ) # array('h', [-2, -1, 1024, 1, 2]) 2. \u52a8\u6001\u5f15\u7528\u3001\u5f3a\u7c7b\u578b \u00b6 \u661f\u53f7 * \u7684\u53c2\u6570\u4f1a\u4ee5\u5143\u7ec4(tuple)\u7684\u5f62\u5f0f\u5bfc\u5165\uff0c\u5b58\u653e\u6240\u6709\u672a\u547d\u540d\u7684\u53d8\u91cf\u53c2\u6570 def printinfo ( arg1 , * vartuple ): print ( \"\u8f93\u51fa\u4efb\u4f55\u4f20\u5165\u7684\u53c2\u6570: \" ) print ( arg1 ) print ( vartuple ) for var in vartuple : print ( var ) return printinfo ( 10 ) # 10 # () printinfo ( 70 , 60 , 50 ) # 70 # (60, 50) # 60 # 50 \u4e24\u4e2a\u661f\u53f7 ** \u7684\u53c2\u6570\u4f1a\u4ee5\u5b57\u5178\u7684\u5f62\u5f0f\u5bfc\u5165\u3002 def printinfo ( arg1 , ** vardict ): print ( \"\u8f93\u51fa\u4efb\u4f55\u4f20\u5165\u7684\u53c2\u6570: \" ) print ( arg1 ) print ( vardict ) printinfo ( 1 , a = 2 , b = 3 ) # 1 # {'a': 2, 'b': 3} \u5b57\u5178\u683c\u5f0f\u8f93\u51fa Python\u4e2d\u7684\u5bf9\u8c61\u5f15\u7528\u5e76\u4e0d\u6d89\u53ca\u7c7b\u578b\u3002\u53d8\u91cf\u5bf9\u4e8e\u5bf9\u8c61\u6765\u8bf4\u53ea\u662f\u7279\u5b9a\u547d\u540d\u7a7a\u95f4\u4e2d\u7684\u540d\u79f0\uff1b\u7c7b\u578b\u4fe1\u606f\u662f\u5b58\u50a8\u5728\u5bf9\u8c61\u81ea\u8eab\u4e4b\u4e2d\u3002 a = 5 print ( type ( a )) # a = 'foo' print ( type ( a )) # Python\u662f\u5f3a\u7c7b\u578b\u8bed\u8a00\uff0c\u6240\u6709\u7684\u5bf9\u8c61\u90fd\u62e5\u6709\u4e00\u4e2a\u6307\u5b9a\u7684\u7c7b\u578b\uff08\u6216\u7c7b\uff09\uff0c\u9690\u5f0f\u7684\u8f6c\u6362\u53ea\u5728\u67d0\u4e9b\u7279\u5b9a\u3001\u660e\u663e\u7684\u60c5\u51b5\u4e0b\u53d1\u751f\u3002 a = 4.5 b = 2 print ( 'a is {0} , b is {1} ' . format ( type ( a ), type ( b ))) # a is , b is \u5b57\u4e32\u683c\u5f0f\u5316\uff0c\u7528\u4e8e\u540e\u7eed\u8bbf\u95ee print ( a / b ) # 2.25 \u4f7f\u7528isinstance\u51fd\u6570\u6765\u68c0\u67e5\u4e00\u4e2a\u5bf9\u8c61\u662f\u5426\u662f\u7279\u5b9a\u7c7b\u578b\u7684\u5b9e\u4f8b\u3002isinstance\u63a5\u53d7\u4e00\u4e2a\u5305\u542b\u7c7b\u578b\u7684\u5143\u7ec4\uff0c\u53ef\u4ee5\u68c0\u67e5\u5bf9\u8c61\u7684\u7c7b\u578b\u662f\u5426\u5728\u5143\u7ec4\u4e2d\u7684\u7c7b\u578b\u4e2d\u3002 a = 5 b = 4.5 c = 'foo' print ( isinstance ( a , int )) # True print ( isinstance ( b , str )) # False print ( isinstance ( c , ( str , int ))) # True print ( isinstance ( c , ( float , int ))) # False \u5c5e\u6027\u548c\u65b9\u6cd5\u4e5f\u53ef\u4ee5\u901a\u8fc7getattr\u51fd\u6570\u83b7\u5f97\u3002\u5728\u5176\u4ed6\u7684\u8bed\u8a00\u4e2d\uff0c\u901a\u8fc7\u53d8\u91cf\u540d\u8bbf\u95ee\u5bf9\u8c61\u901a\u5e38\u88ab\u79f0\u4e3a\u201c\u53cd\u5c04\u201d\u3002 b = 'foo' print ( getattr ( b , 'split' )) # 3. \u4e8c\u5143\u8fd0\u7b97\u7b26\u548c\u6bd4\u8f83\u8fd0\u7b97 \u00b6 \u68c0\u67e5\u4e24\u4e2a\u5f15\u7528\u662f\u5426\u6307\u5411\u540c\u4e00\u4e2a\u5bf9\u8c61\uff0c\u53ef\u4ee5\u4f7f\u7528is\u5173\u952e\u5b57\u3002 is\u548cis not\u7684\u5e38\u7528\u4e4b\u5904\u662f\u68c0\u67e5\u4e00\u4e2a\u53d8\u91cf\u662f\u5426\u4e3aNone\uff0c\u56e0\u4e3aNone\u53ea\u6709\u4e00\u4e2a\u5b9e\u4f8b\u3002 a = [ 1 , 2 , 3 ] b = a c = list ( a ) # list\u51fd\u6570\u603b\u662f\u521b\u5efa\u4e00\u4e2a\u65b0\u7684Python\u5217\u8868\uff08\u5373\u4e00\u4efd\u62f7\u8d1d\uff09 print ( a is b ) # True print ( a is not c ) # True print ( a == c ) # True d = None print ( d is None ) # True Python\u4e2d\u7684\u5927\u90e8\u5206\u5bf9\u8c61\uff0c\u4f8b\u5982\u5217\u8868\u3001\u5b57\u5178\u3001NumPy\u6570\u7ec4\u90fd\u662f\u53ef\u53d8\u5bf9\u8c61\uff0c\u5927\u591a\u6570\u7528\u6237\u5b9a\u4e49\u7684\u7c7b\u578b\uff08\u7c7b\uff09\u4e5f\u662f\u53ef\u53d8\u7684\u3002 \u53ef\u53d8\u5bf9\u8c61\u4e2d\u5305\u542b\u7684\u5bf9\u8c61\u548c\u503c\u662f\u53ef\u4ee5\u88ab\u4fee\u6539\u7684\u3002\u8fd8\u6709\u5176\u4ed6\u4e00\u4e9b\u5bf9\u8c61\u662f\u4e0d\u53ef\u53d8\u7684\uff0c\u6bd4\u5982\u5b57\u7b26\u4e32\u3001\u5143\u7ec4\u3002 a_list = [ 'foo' , 2 , [ 4 , 5 ]] # \u5217\u8868 a_list [ 2 ] = ( 3 , 4 ) print ( a_list ) # ['foo', 2, (3, 4)] a_tuple = ( 3 , 5 , ( 4 , 5 )) # \u5143\u7ec4 a_tuple [ 1 ] = 'four' # TypeError: 'tuple' object does not support item assignment \u4e0d\u53ef\u88ab\u4fee\u6539 print ( a_tuple ) # (3, 5, (4, 5)) 4. \u6807\u91cf\u7c7b\u578b \u00b6 Python\u6807\u91cf\u7c7b\u578b\uff1aNone, str, bytes, float, bool, int\u3002 \u6570\u503c\u7c7b\u578b\u3002 \u57fa\u7840\u7684Python\u6570\u5b57\u7c7b\u578b\u5c31\u662fint\u548cfloat\u3002int\u53ef\u4ee5\u5b58\u50a8\u4efb\u610f\u5927\u5c0f\u6570\u5b57\u3002\u6d6e\u70b9\u6570\u5728Python\u4e2d\u7528float\u8868\u793a\uff0c\u6bcf\u4e00\u4e2a\u6d6e\u70b9\u6570\u90fd\u662f\u53cc\u7cbe\u5ea664\u4f4d\u6570\u503c\u3002 ival = 17338971 print ( ival ** 6 ) # 27173145946003847721495630081806010734757321 fval = 17338971.0 print ( fval ** 6 ) # 2.7173145946003847e+43 print ( 3 / 2 ) # 1.5 print ( 3 // 2 ) # 1 \u5b57\u7b26\u4e32\u3002 Python\u7684\u5b57\u7b26\u4e32\u662f\u4e0d\u53ef\u53d8\u7684\u3002 a = 5.6 s = str ( a ) print ( s ) # 5.6 b = 'python' print ( list ( b )) # ['p', 'y', 't', 'h', 'o', 'n'] print ( b [ 2 ]) # t b [ 2 ] = 'f' # TypeError: 'str' object does not support item assignment \u5b57\u7b26\u4e32\u662f\u4e0d\u53ef\u53d8\u7684 \u53cd\u659c\u6760\u7b26\u53f7\\\u662f\u4e00\u79cd\u8f6c\u4e49\u7b26\u53f7\uff0c\u5b83\u7528\u6765\u6307\u660e\u7279\u6b8a\u7b26\u53f7\u3002 \u5982\u679c\u4f60\u6709\u4e00\u4e2a\u4e0d\u542b\u7279\u6b8a\u7b26\u53f7\u4f46\u542b\u6709\u5927\u91cf\u53cd\u659c\u6760\u7684\u5b57\u7b26\u4e32\u65f6\uff0c\u53ef\u4ee5\u5728\u5b57\u7b26\u4e32\u524d\u9762\u52a0\u4e00\u4e2a\u524d\u7f00\u7b26\u53f7r\uff0c\u8868\u660e\u8fd9\u4e9b\u5b57\u7b26\u662f\u539f\u751f\u5b57\u7b26\uff0cr\u662fraw\u7684\u7b80\u5199\uff0c\u8868\u793a\u539f\u751f\u7684\u3002 x = '12 \\\\ 34' y = r 'this\\has\\no\\special\\characters' print ( x ) # 12\\34 print ( y ) # this\\has\\no\\special\\characters \u5b57\u7b26\u4e32\u683c\u5f0f\u5316 {0:.2f}\u8868\u793a\u5c06\u7b2c\u4e00\u4e2a\u53c2\u6570\u683c\u5f0f\u5316\u4e3a2\u4f4d\u5c0f\u6570\u7684\u6d6e\u70b9\u6570 {1:s}\u8868\u793a\u5c06\u7b2c\u4e8c\u4e2a\u53c2\u6570\u683c\u5f0f\u5316\u4e3a\u5b57\u7b26\u4e32 {2:d}\u8868\u793a\u5c06\u7b2c\u4e09\u4e2a\u53c2\u6570\u683c\u5f0f\u5316\u6574\u6570 \u53c2\u8003Python\u5b98\u65b9\u6587\u6863 https://docs.python.org/3.6/library/string.html template = ' {0:.2f} {1:s} are worth US$ {2:d} ' print ( template . format ( 4.5560 , 'Argentine Pesos' , 1 )) # 4.56 Argentine Pesos are worth US$1 \u65e5\u671f\u548c\u65f6\u95f4 from datetime import datetime , date , time dt = datetime ( 2011 , 10 , 29 , 20 , 30 , 21 ) print ( dt . day ) # 29 print ( dt . minute ) # 30 print ( dt . date ()) # 2011-10-29 print ( dt . time ()) # 20:30:21 print ( dt . replace ( minute = 0 , second = 0 )) # 2011-10-29 20:00:00 \u5c06\u5206\u949f\u3001\u79d2\u66ff\u6362\u4e3a0 print ( datetime . strptime ( '20091021' , '%Y%m %d ' )) # 2009-10-21 00:00:00 \u5b57\u7b26\u4e32\u53ef\u4ee5\u901a\u8fc7 strptime \u51fd\u6570\u8f6c\u6362\u4e3adatetime\u5bf9\u8c61 dt2 = datetime ( 2011 , 11 , 15 , 22 , 30 ) delta = dt2 - dt print ( delta ) # 17 days, 1:59:39 print ( dt + delta ) # 2011-11-15 22:30:00 range\u51fd\u6570\u8fd4\u56de\u4e00\u4e2a\u8fed\u4ee3\u5668\uff0c\u8be5\u8fed\u4ee3\u5668\u751f\u6210\u4e00\u4e2a\u7b49\u5dee\u6574\u6570\u5e8f\u5217\u3002 print ( range ( 10 )) # range(0, 10) print ( list ( range ( 10 ))) # [0, 1, 2, 3, 4, 5, 6, 7, 8, 9] print ( list ( range ( 0 , 20 , 2 ))) # [0, 2, 4, 6, 8, 10, 12, 14, 16, 18] 5. \u4e09\u5143\u8868\u8fbe\u5f0f \u00b6 value = true-expr if condition else false-expr x = 5 print ( 'non-negative' if x >= 0 else 'negative' ) # non-negative","title":"Python\u8bed\u8a00\u57fa\u7840"},{"location":"python/Foundation/ch01/#python","text":"","title":"Python\u8bed\u8a00\u57fa\u7840"},{"location":"python/Foundation/ch01/#1-python6","text":"6\u4e2aPython\u6570\u636e\u7c7b\u578b\uff1a \u6570\u503c\u578b\uff08number\uff09\uff1a\u8868\u793a\u6570\u636e\u7ec4\u6210\u4e3a\u6570\u5b57 \u6574\u578b\uff08int\uff09 \u5341\u8fdb\u5236 \u516b\u8fdb\u5236 \u5341\u516d\u8fdb\u5236 \u6d6e\u70b9\u578b\uff08float\uff09 \u5e03\u5c14\u578b\uff08bool\uff09 \u590d\u6570\u6027\uff08complex\uff09 \u5b57\u7b26\u578b\uff08string\uff09\uff1a\u8868\u793a\u6570\u636e\u7ec4\u6210\u662f\u5b57\u7b26 \u5217\u8868\uff08list\uff09\uff1a\u7528\u6765\u8868\u793a\u4e00\u7ec4\u6709\u5e8f\u5143\u7d20\uff0c\u540e\u671f\u6570\u636e\u53ef\u4ee5\u4fee\u6539 ['A','B','C'] \u5143\u7ec4\uff08tuple\uff09\uff1a\u7528\u6765\u8868\u793a\u4e00\u7ec4\u6709\u5e8f\u5143\u7d20\uff0c\u540e\u671f\u6570\u636e\u4e0d\u53ef\u4fee\u6539 ('A','B','C','1') \u96c6\u5408\uff08set\uff09\uff1a\u4e00\u7ec4\u6570\u636e\u65e0\u5e8f\u4e0d\u91cd\u590d\u5143\u7d20 set([1,2,3,4]) \u5b57\u5178\uff08dictionary\uff09\uff1a\u7528\u952e\u503c\u5bf9\u7684\u5f62\u5f0f\u4fdd\u5b58\u4e00\u7ec4\u5143\u7d20 {'A':7,'B':1,'C':9} \u53ef\u8fed\u4ee3\u5bf9\u8c61\uff08Iterable\uff09\uff1a An object capable of returning its members one at a time. Examples of iterables include all sequence types (such as list, str, and tuple) and some non-sequence types like dict, file objects, and objects of any classes you define with an iter() method or with a getitem() method that implements Sequence semantics. \u5e8f\u5217\uff08Sequence\uff09\uff1a An iterable which supports efficient element access using integer indices via the getitem() special method and defines a len() method that returns the length of the sequence. Some built-in sequence types are list, str, tuple, and bytes. Note that dict also supports getitem() and len(), but is considered a mapping rather than a sequence because the lookups use arbitrary immutable keys rather than integers. \u8fed\u4ee3\u5668\uff08Iterator\uff09\uff1a An object representing a stream of data. Repeated calls to the iterator\u2019s next() method (or passing it to the built-in function next()) return successive items in the stream. When no more data are available a StopIteration exception is raised instead. At this point, the iterator object is exhausted and any further calls to its next() method just raise StopIteration again. Iterators are required to have an iter() method that returns the iterator object itself so every iterator is also iterable and may be used in most places where other iterables are accepted. One notable exception is code which attempts multiple iteration passes. A container object (such as a list) produces a fresh new iterator each time you pass it to the iter() function or use it in a for loop. Attempting this with an iterator will just return the same exhausted iterator object used in the previous iteration pass, making it appear like an empty container. \u53ef\u53d8\u6570\u636e\uff08immutable\uff09 \u5217\u8868\uff08list\uff09 \u5b57\u5178\uff08dictionary\uff09 \u96c6\u5408\uff08set\uff09\u3002 \u4e0d\u53ef\u53d8\u6570\u636e\uff08immutable\uff09 \u6570\u5b57\uff08number\uff09 \u5b57\u7b26\uff08string\uff09 \u5143\u7ec4\uff08tuple\uff09 \u53ef\u8fed\u4ee3\uff08iterable\uff09 \u5b57\u7b26\uff08string\uff09 \u5143\u7ec4\uff08tuple\uff09 \u5217\u8868\uff08list\uff09 \u5b57\u5178\uff08dictionary\uff09 \u96c6\u5408\uff08set\uff09 \u5e8f\u5217 \u6709\u5e8f\u5e8f\u5217\uff1a\u5b57\u7b26\uff08string\uff09\uff0c\u5143\u7ec4\uff08tuple\uff09\uff0c\u5217\u8868\uff08list\uff09 \u65e0\u5e8f\u5e8f\u5217\uff1a\u5b57\u5178\uff08dictionary\uff09\uff0c\u96c6\u5408\uff08set\uff09 Python\u5e8f\u5217\u7c7b\u578b\u6700\u5e38\u89c1\u7684\u5206\u7c7b\u5c31\u662f\u53ef\u53d8\u548c\u4e0d\u53ef\u53d8\u5e8f\u5217\u3002\u4f46\u53e6\u5916\u4e00\u79cd\u5206\u7c7b\u65b9\u5f0f\u4e5f\u5f88\u6709\u7528\uff0c\u90a3\u5c31\u662f\u628a\u5b83\u4eec\u5206\u4e3a**\u6241\u5e73\u5e8f\u5217**\u548c**\u5bb9\u5668\u5e8f\u5217**\u3002\u524d\u8005\u7684\u4f53\u79ef\u66f4\u5c0f\u3001\u901f\u5ea6\u66f4\u5feb\u800c\u4e14\u7528\u8d77\u6765\u66f4\u7b80\u5355\uff0c\u4f46\u662f\u5b83\u53ea\u80fd\u4fdd\u5b58\u4e00\u4e9b\u539f\u5b50\u6027\u7684\u6570\u636e\uff0c\u6bd4\u5982\u6570\u5b57\u3001\u5b57\u7b26\u548c\u5b57\u8282\u3002\u5bb9\u5668\u5e8f\u5217\u5219\u6bd4\u8f83\u7075\u6d3b\uff0c\u4f46\u662f\u5f53\u5bb9\u5668\u5e8f\u5217\u9047\u5230\u53ef\u53d8\u5bf9\u8c61\u65f6\uff0c\u5c31\u9700\u8981\u683c\u5916\u5c0f\u5fc3\uff0c\u56e0\u4e3a\u8fd9\u79cd\u7ec4\u5408\u65f6\u5e38\u4f1a\u51fa\u73b0\u4e00\u4e9b\u201c\u610f\u5916\u201d\uff0c\u7279\u522b\u662f\u5e26\u5d4c\u5957\u7684\u6570\u636e\u7ed3\u6784\u51fa\u73b0\u65f6\uff0c\u66f4\u9700\u8981\u9a8c\u8bc1\u4ee3\u7801\u7684\u6b63\u786e\u6027\u3002 Python\u4e2d\u7684\u53d8\u91cf\u3001\u5e38\u91cf\u548c\u5b57\u9762\u91cf \u53d8\u91cf \u53d8\u91cf\u662f\u7528\u4e8e\u5728\u5185\u5b58\u4e2d\u5b58\u50a8\u6570\u636e\u7684\u547d\u540d\u4f4d\u7f6e\u3002\u53ef\u4ee5\u5c06\u53d8\u91cf\u89c6\u4e3a\u4fdd\u5b58\u6570\u636e\u7684\u5bb9\u5668\uff0c\u8fd9\u4e9b\u6570\u636e\u53ef\u4ee5\u5728\u540e\u9762\u7a0b\u5e8f\u4e2d\u8fdb\u884c\u66f4\u6539\u3002\u4f8b\u5982\uff1a number = 10 \u3002\u4ece\u4f8b\u5b50\u4e2d\u53ef\u4ee5\u770b\u5230\uff0cPython\u4f7f\u7528\u8d4b\u503c\u8fd0\u7b97\u7b26 = \u4e3a\u53d8\u91cf\u8d4b\u503c\u3002 \u5e38\u91cf \u5e38\u91cf\u4e5f\u662f\u4e00\u79cd\u53d8\u91cf\uff0c\u53ea\u662f\u5176\u503c\u4e00\u65e6\u8d4b\u4e88\u540e\u65e0\u6cd5\u66f4\u6539\u3002\u53ef\u4ee5\u5c06\u5e38\u91cf\u89c6\u4e3a\u4fdd\u5b58\u4e86\u4ee5\u540e\u65e0\u6cd5\u66f4\u6539\u7684\u4fe1\u606f\u7684\u5bb9\u5668\u3002 \u5728Python\u4e2d\uff0c\u5e38\u91cf\u901a\u5e38\u662f\u5728\u6a21\u5757\u4e2d\u58f0\u660e\u548c\u5206\u914d\u7684\u3002\u5728\u8fd9\u91cc\uff0c\u6a21\u5757\u662f\u4e00\u4e2a\u5305\u542b\u53d8\u91cf\uff0c\u51fd\u6570\u7b49\u7684\u65b0\u6587\u4ef6\uff0c\u8be5\u6587\u4ef6\u88ab\u5bfc\u5165\u5230\u4e3b\u6587\u4ef6\u4e2d\u3002\u5728\u6a21\u5757\u5185\u90e8\uff0c\u7528\u6240\u6709\u5927\u5199\u5b57\u6bcd\u5199\u7684\u5e38\u91cf\u548c\u4e0b\u5212\u7ebf\u5c06\u5355\u8bcd\u5206\u5f00\u3002\u5b9e\u9645\u4e0a\uff0c\u6211\u4eec\u4e0d\u5728Python\u4e2d\u4f7f\u7528\u5e38\u91cf\u3002\u7528\u5927\u5199\u5b57\u6bcd\u547d\u540d\u5b83\u4eec\u662f\u4e00\u79cd\u5c06\u5176\u4e0e\u666e\u901a\u53d8\u91cf\u5206\u5f00\u7684\u4e00\u79cd\u7ea6\u5b9a\uff0c\u4f46\u662f\uff0c\u5b9e\u9645\u4e0a\u5e76\u4e0d\u80fd\u963b\u6b62\u91cd\u65b0\u5206\u914d\u3002 \u5b57\u9762\u91cf\uff08literal\uff09 \u5b57\u9762\u91cf\u662f\u4ee5\u53d8\u91cf\u6216\u5e38\u91cf\u7ed9\u51fa\u7684\u539f\u59cb\u6570\u636e\uff08\u5176\u5b9e\u5c31\u662f\u6307\u53d8\u91cf\u7684\u5e38\u6570\u503c\uff0c\u5b57\u9762\u4e0a\u6240\u770b\u5230\u7684\u503c\uff09\u3002\u5728Python\u4e2d\u5b57\u9762\u91cf\u7c7b\u578b\u5982\u4e0b\uff1a \u6570\u5b57\u5b57\u9762\u91cf\u3002\u6570\u5b57\u5b57\u9762\u91cf\u662f\u4e0d\u53ef\u53d8\u7684\uff08\u4e0d\u53ef\u66f4\u6539\uff09\u3002\u6570\u5b57\u5b57\u9762\u91cf\u53ef\u4ee5\u5c5e\u4e8e3\u79cd\u4e0d\u540c\u7684\u6570\u503c\u7c7b\u578b\uff1aInteger\uff0cFloat \u548c Complex\u3002\u4f8b\u5982\uff1a float_1 = 10.5 \u662f\u5c5e\u4e8eFloat\u5b57\u9762\u91cf\u3002 \u5b57\u7b26\u4e32\u5b57\u9762\u91cf\u662f\u7531\u5f15\u53f7\u62ec\u8d77\u6765\u7684\u4e00\u7cfb\u5217\u5b57\u7b26\u3002\u6211\u4eec\u53ef\u4ee5\u5bf9\u5b57\u7b26\u4e32\u4f7f\u7528\u5355\u5f15\u53f7\uff0c\u53cc\u5f15\u53f7 \u6216 \u4e09\u5f15\u53f7\u3002\u5e76\u4e14\uff0c\u5b57\u7b26\u5b57\u9762\u91cf\u662f\u7528\u5355\u5f15\u53f7\u6216\u53cc\u5f15\u53f7\u5f15\u8d77\u6765\u7684\u5355\u4e2a\u5b57\u7b26\u3002\u4f8b\u5982\uff1a strings = \"This is Python\" \u3002 \u5e03\u5c14\u5b57\u9762\u91cf\u3002\u5e03\u5c14\u5b57\u9762\u91cf\u53ef\u4ee5\u5177\u6709\u4e24\u4e2a\u503c\u4e2d\u7684\u4efb\u4f55\u4e00\u4e2a\uff1a True \u6216 False \u3002\u4f8b\u5982\uff1a a = True + 4 \u3002 \u7279\u6b8a\u5b57\u9762\u91cf\u3002Python\u5305\u542b\u4e00\u4e2a\u7279\u6b8a\u5b57\u9762\u91cf\uff0c\u5373 None \u3002 \u5b57\u9762\u91cf\u96c6\u3002\u6709\u56db\u79cd\u4e0d\u540c\u7684\u5b57\u9762\u91cf\u96c6\u5408\uff1a\u5217\u8868\u5b57\u9762\u91cf\uff0c\u5143\u7ec4\u5b57\u9762\u91cf\uff0c\u5b57\u5178\u5b57\u9762\u91cf \u548c \u96c6\u5408\u5b57\u9762\u91cf\u3002","title":"1. Python\u6570\u636e\u7c7b\u578b\uff086\u4e2a\uff09"},{"location":"python/Foundation/ch01/#11-number","text":"\u4f8b\u5b50\uff1a a , b , c , d = 20 , 5.5 , True , 4 + 3 j print ( a , b , c , d ) # 20 5.5 True (4+3j) print ( type ( a ), type ( b ), type ( c ), type ( d )) # Python\u4e5f\u53ef\u4ee5\u8fd9\u6837\u8d4b\u503c\uff1a a = b = c = d = 1 print ( a , b , c , d ) # 1 1 1 1 \u8fdb\u5236\u8f6c\u6362\uff1a a = - 15 print ( f ' { a } \u5bf9\u5e94\u7684\u5341\u8fdb\u5236\u662f { a } , \u4e8c\u8fdb\u5236\u662f { a : b } , \u516b\u8fdb\u5236\u662f { a : o } , \u5341\u516d\u8fdb\u5236\u662f { a : x } ' )","title":"1.1 \u6570\u503c\u578b\uff08number\uff09"},{"location":"python/Foundation/ch01/#12-string","text":"\u5355\u5f15\u53f7\uff1a\u5185\u5bb9\u4e2d\u5305\u542b\u5927\u91cf\u53cc\u5f15\u53f7 \u53cc\u5f15\u53f7\uff1a\u5185\u5bb9\u4e2d\u5305\u542b\u5927\u91cf\u5355\u5f15\u53f7 \u4e09\u5f15\u53f7\uff1a\u5185\u5bb9\u4e2d\u540c\u65f6\u5305\u542b\u5355\u53cc\u5f15\u53f7\uff0c\u4e09\u4e2a\u5355\u5f15\u53f7\u6bd4\u8f83\u597d\u3002 a = 'string is \"special\"' b = \"string's value\" c = '''string's value is \"special\"''' d = \"\"\"string's context \"\"\"","title":"1.2 \u5b57\u7b26\u578b\uff08string\uff09"},{"location":"python/Foundation/ch01/#_1","text":"\u5b57\u7b26\u4e32\u5207\u7247 s = 'Python is very good' print ( s [ 2 : 4 ]) # th print ( s [ 5 ]) # n print ( s [ - 1 ]) # d print ( s [ - 3 : - 1 ]) # oo # \u975e\u8fed\u4ee3\u578b\uff0c\u4e0d\u53ef\u4fee\u6539 s [ 3 ] = 'b' # Traceback (most recent call last): # File \"\", line 1, in # TypeError: 'str' object does not support item assignment \u5b57\u7b26\u4e32\u5408\u5e76 print ( s + '!!!' ) # Python is very good!!! replace( a,b \u5c06\u5b57\u7b26\u4e32\u4e2d\u7684 a \u66ff\u6362\u6210 b print ( s . replace ( 'is' , 'we' )) # Python we very good find(str) : \u8fd4\u56de str \u51fa\u73b0\u7684\u7d22\u5f15\u4f4d\u7f6e\uff0c\u5982\u679c\u627e\u4e0d\u5230\u8be5\u503c\uff0c\u5219 find() \u65b9\u6cd5\u5c06\u8fd4\u56de -1\u3002 print ( s . find ( 'a' )) # -1 print ( s . find ( 's' )) # 8 str.index(a): \u67e5\u627e\u6307\u5b9a\u503c\u7684\u9996\u6b21\u51fa\u73b0\u3002\u5982\u679c\u627e\u4e0d\u5230\u8be5\u503c\uff0cindex() \u65b9\u6cd5\u5c06\u5f15\u53d1\u5f02\u5e38\u3002 print ( s . index ( 's' )) # 8 print ( s . index ( 'a' )) # Traceback (most recent call last): # File \"\", line 1, in # ValueError: substring not found str.count(a): \u7edf\u8ba1\u5b57\u7b26\u4e32\u4e2d a \u51fa\u73b0\u7684\u6b21\u6570 print ( s . count ( 'a' )) # 0 print ( s . count ( 'o' )) # 3 split: \u5bf9\u5b57\u7b26\u4e32\u8fdb\u884c\u5206\u5272\u3002\u5982\u679c\u53c2\u6570 num \u6709\u6307\u5b9a\u503c\uff0c\u5219\u5206\u9694 num+1 \u4e2a\u5b50\u5b57\u7b26\u4e32\u3002 # \u6309\u7a7a\u683c\u5206\u5272 print ( s . split ( ' ' )) # ['Python', 'is', 'very', 'good'] # \u6309\u7a7a\u683c\u5206\u5272\u62102\u4e2a\u5b50\u5b57\u7b26\u4e32 print ( s . split ( ' ' , 1 )) # ['Python', 'is very good'] strip: \u79fb\u9664\u5b57\u7b26\u4e32\u9996\u5c3e\u6307\u5b9a\u7684\u5b57\u7b26 \u9ed8\u8ba4\u4e3a\u7a7a\u683c\u3002\u8be5\u65b9\u6cd5\u53ea\u80fd\u5220\u9664\u5f00\u5934\u6216\u662f\u7ed3\u5c3e\u7684\u5b57\u7b26\uff0c\u4e0d\u80fd\u5220\u9664\u4e2d\u95f4\u90e8\u5206\u7684\u5b57\u7b26\u3002 print ( s ) # Python is very good # \u79fb\u9664\u672b\u5c3e\u5b57\u7b26d print ( s . strip ( 'd' )) # Python is very goo endswith (str): \u5224\u65ad\u5b57\u7b26\u4e32\u662f\u5426\u4ee5 str \u7ed3\u5c3e print ( s . endswith ( 'd' )) # True print ( s . endswith ( 'a' )) # False startswith (str): \u5224\u65ad\u5b57\u7b26\u4e32\u662f\u5426\u4ee5 str \u5f00\u5934 print ( s . startswith ( 'p' )) # False print ( s . startswith ( 'P' )) # True isdigit \uff1a\u5224\u65ad\u5b57\u7b26\u4e32\u662f\u5426\u5168\u4e3a\u6570\u5b57 d = '+86-123' print ( d . isdigit ()) # False d = '86123' print ( d . isdigit ()) # True isalpha \uff1a\u5224\u65ad\u5b57\u7b26\u4e32\u662f\u5426\u5168\u4e3a\u5b57\u6bcd b = 'Ab?' print ( b . isalpha ()) # False c = 'Ab' print () c . isalpha () # True","title":"\u5b57\u7b26\u4e32\u5e38\u7528\u65b9\u6cd5"},{"location":"python/Foundation/ch01/#_2","text":"\u4f7f\u7528\u53cd\u659c\u6760\\\u8868\u793a\u8f6c\u4e49\u5b57\u7b26\u3002\u53cd\u659c\u6760\u524d\u9762\u52a0r\u4ee3\u8868\u539f\u59cb\u5b57\u7b26\u3002 a = 'str \\n ing' print ( a ) # str # ing a = r 'str\\ning' print ( a ) # str\\ning \u8f6c\u4e49\u7b26 \u63cf\u8ff0 \\\u5728\u884c\u5c3e \u7eed\u884c\u7b26 \\\\ \u53cd\u659c\u6760\u7b26\u53f7\\ \\' \u5355\u5f15\u53f7 \\b \u9000\u683c(Backspace) \\000 \u7a7a \\n \u6362\u884c \\v \u7eb5\u5411\u5236\u8868\u7b26 \\t \u6a2a\u5411\u5236\u8868\u7b26 \\r \u56de\u8f66\uff0c\u5c06 \\r \u540e\u9762\u7684\u5185\u5bb9\u79fb\u5230\u5b57\u7b26\u4e32\u5f00\u5934\uff0c\u5e76\u9010\u4e00\u66ff\u6362\u5f00\u5934\u90e8\u5206\u7684\u5b57\u7b26\uff0c\u76f4\u81f3\u5c06 \\r \u540e\u9762\u7684\u5185\u5bb9\u5b8c\u5168\u66ff\u6362\u5b8c\u6210\u3002 \\yyy \u516b\u8fdb\u5236\u6570\uff0cy \u4ee3\u8868 0~7 \u7684\u5b57\u7b26 \\xyy \u5341\u516d\u8fdb\u5236\u6570\uff0c\u4ee5 \\x \u5f00\u5934\uff0cy \u4ee3\u8868\u7684\u5b57\u7b26","title":"\u8f6c\u4e49\u5b57\u7b26"},{"location":"python/Foundation/ch01/#_3","text":"\u5b57\u7b26\u4e32\u662f\u53ef\u8fed\u4ee3\u7684\u3002\u7d22\u5f15\u503c\u4ece0\u5f00\u59cb\uff0c-1\u4ee3\u8868\u4ece\u672b\u5c3e\u5f00\u59cb\u3002\u7d22\u5f15\u533a\u95f4\u662f\u5de6\u95ed\u53f3\u5f00\u3002 a = 'string is \"special\"' print ( a [ 2 : 4 ]) 'ri' print ( a [ - 4 : - 1 ]) # ial","title":"\u53ef\u8fed\u4ee3\u6027"},{"location":"python/Foundation/ch01/#f-string","text":"f-string\u662fPython3.6\u63a8\u51fa\u7684\u65b0\u529f\u80fd\u3002\u770b\u4e0b\u9762\u7684\u4f8b\u5b50\uff0c\u5bf9\u6bd4\u4f20\u7edf\u8868\u793a\u65b9\u6cd5\u548cf-string\u7684\u65b9\u6cd5\u3002 age = 32 name = 'Tom' fstring = f 'My name is { name } and I am { age } years old.' print ( fstring ) # My name is Tom and I am 32 years old. \u5728f-string\u4e2d\u4f7f\u7528\u8868\u8fbe\u5f0f\u3002 height = 2 base = 3 fstring = f 'The area of the triangle is { base * height / 2 } .' print ( fstring ) # The area of the triangle is 3.0. \u901a\u8fc7f-string\u5bf9\u5b57\u5178\u8fdb\u884c\u64cd\u4f5c\u3002 person1 = { 'name' : 'Tom' , 'age' : 20 , 'gender' : 'male' } person2 = { 'name' : 'Jerry' , 'age' : 20 , 'gender' : 'female' } # \u8bfb\u53d6\u5b57\u5178 fstring = f ' { person1 . get ( \"name\" ) } is { person1 . get ( \"age\" ) } and is { person1 . get ( \"ender\" ) } ' print ( fstring ) # Tom is 20 and is None # \u904d\u5386\u5b57\u5178 people = [ person1 , person2 ] for person in people : fstring = f ' { person . get ( \"name\" ) } is { person . get ( \"age\" ) } and is { person . get ( \"ender\" ) } ' print ( fstring ) # Tom is 20 and is None # Jerry is 20 and is None \u5728f-string\u4e2d\u4f7f\u7528\u6761\u4ef6\u3002 person1 = { 'name' : 'Tom' , 'age' : 20 , 'gender' : 'male' } person2 = { 'name' : 'Jerry' , 'age' : 20 , 'gender' : 'female' } people = [ person1 , person2 ] for person in people : fstring = f ' { \"She\" if person . get ( \"gender\" ) == \"female\" else \"He\" } is watching TV.' print ( fstring ) # He is watching TV. # She is watching TV. \u4f7f\u7528f-string\u683c\u5f0f\u5316\u8f93\u51fa\u3002 \u5de6\u5bf9\u9f50\uff1a< \u53f3\u5bf9\u9f50\uff1a> \u5c45\u4e2d\u5bf9\u9f50\uff1a^ print ( f ' { \"apple\" : >30 } ' ) print ( f ' { \"apple\" : ^30 } ' ) print ( f ' { \"apple\" : <30 } ' ) # apple # apple # apple \u4f7f\u7528f-string\u683c\u5f0f\u5316\u6570\u5b57\u3002 number = 0.9124325345 # \u767e\u5206\u6bd4 fstring = f 'Percentage format for number with two decimal places: { number : .2% } ' print ( fstring ) # Percentage format for number with two decimal places: 91.24% # \u4fdd\u7559\u5c0f\u6570\u70b9\u540e3\u4f4d fstring = f 'Fixed point format for number with three decimal places: { number : .3f } ' print ( fstring ) # Fixed point format for number with three decimal places: 0.912 # \u79d1\u5b66\u8ba1\u6570\u6cd5\u8868\u793a fstring = f 'Exponent format for number: { number : e } ' print ( fstring ) # Exponent format for number: 9.124325e-01 # \u5e26\u8d27\u5e01\u7b26\u53f7 number = 123456.78921 fstring = f 'Currency format for number with two decimal places: $ { number : .2f } ' print ( fstring ) # Currency format for number with two decimal places: $123456.79 # \u5e26\u8d27\u5e01\u7b26\u53f7\u548c\u5343\u5206\u4f4d number = 123456.78921 fstring = f 'Currency format for number with two decimal places and comma seperators: $ { number : ,.2f } ' print ( fstring ) # Currency format for number with two decimal places and comma seperators: $123,456.79 # \u8f93\u51fa\u6570\u503c\u5e26\u6b63\u8d1f\u7b26\u5408 numbers = [ 1 , - 3 , 5 ] for number in numbers : fstring = f 'The number is { number : + } ' print ( fstring ) # The number is +1 # The number is -3 # The number is +5 # Debug\u8c03\u8bd5 number = 2 print ( f ' { number = } ' ) # number = 2","title":"f-string"},{"location":"python/Foundation/ch01/#13-list","text":"\u5217\u8868\u662f Python \u5185\u7f6e\u7684\u4e00\u79cd\u6570\u636e\u7ed3\u6784\uff0c\u662f\u4e00\u79cd\u6709\u5e8f\u7684\u96c6\u5408\uff0c\u7528\u6765\u5b58\u50a8\u4e00\u8fde\u4e32\u5143\u7d20\u7684\u5bb9\u5668\u3002\u5217\u8868\u4e2d\u5143\u7d20\u7c7b\u578b\u53ef\u4ee5\u4e0d\u76f8\u540c\uff0c\u5b83\u652f\u6301\u6570\u5b57\u3001\u5b57\u7b26\u4e32\u7b49\u3002 \u5217\u8868\u7684\u6bcf\u4e2a\u503c\u90fd\u6709\u5bf9\u5e94\u7684\u7d22\u5f15\u503c\uff0c\u7d22\u5f15\u503c\u4ece0\u5f00\u59cb\u3002 \u5217\u8868\u5207\u7247\uff1a \u4f7f\u7528\u5207\u7247\u7b26\u53f7\u53ef\u4ee5\u5bf9\u5927\u591a\u6570\u5e8f\u5217\u7c7b\u578b\u9009\u53d6\u5176\u5b50\u96c6\u3002 \u8d77\u59cb\u4f4d\u7f6estart\u7684\u7d22\u5f15\u662f\u5305\u542b\u7684\uff0c\u800c\u7ed3\u675f\u4f4d\u7f6estop\u7684\u7d22\u5f15\u5e76\u4e0d\u5305\u542b\uff08\u5de6\u95ed\u53f3\u5f00\uff09\u3002 \u6b65\u8fdb\u503cstep\u53ef\u4ee5\u5728\u7b2c\u4e8c\u4e2a\u5192\u53f7\u540e\u9762\u4f7f\u7528\uff0c\u610f\u601d\u662f\u6bcf\u9694\u591a\u5c11\u4e2a\u6570\u53d6\u4e00\u4e2a\u503c \u3002 color = [ 'red' , 'green' , 'blue' , 'yellow' , 'white' , 'black' ] # \u4ece0\u5f00\u59cb\u7edf\u8ba1\uff0c\u8bfb\u53d6\u7b2c1\uff0c2\u4f4d print ( color [ 1 : 3 ]) # ['green', 'blue'] # \u4ece0\u5f00\u59cb\u7edf\u8ba1\uff0c\u8bfb\u53d6\u4ece\u7b2c1\u4f4d\u5230\u5012\u6570\u7b2c3\u4f4d print ( color [ 1 : - 2 ]) # ['green', 'blue', 'yellow'] # \u4ece0\u5f00\u59cb\u7edf\u8ba1\uff0c\u8bfb\u53d6\u4ece\u5012\u6570\u7b2c4\u4f4d\u5230\u5012\u6570\u7b2c3\u4f4d print ( color [ - 4 : - 2 ]) # ['blue', 'yellow'] # \u5982\u679c\u5199\u6210\u4e0b\u9762\u8fd9\u6837\uff0c\u5219\u65e0\u8f93\u51fa\u3002 print ( color [ - 2 : - 4 ]) # [] print ( color [:: 2 ]) # ['red', 'blue', 'white'] \u5bf9\u4e8e\u7c7b\u4f3c\u4e0b\u9762 invoice \u683c\u5f0f\u7684\u7eaf\u6587\u672c\u89e3\u6790\uff0c\u4f7f\u7528\u6709\u540d\u5b57\u7684\u5207\u7247\u6bd4\u7528\u4e0a\u9762\u6240\u5217\u4e3e\u7684\u786c\u7f16\u7801\u7684\u6570\u5b57\u533a\u95f4\u8981\u65b9\u4fbf\u5f97\u591a\u3002 invoice = \"\"\" 0 6 40 52 55 1909 Primoroni PiBrella $17.50 3 $52.50 1489 6mm Tactile Switch x20 $4.19 2 $9.90 1510 Panavise JR.-PV-201 $28.00 1 $28.00 1601 PiTFT Mini Kit 320x240 $34.95 1 $34.95 \"\"\" SKU = slice ( 0 , 6 ) DESCRIPTION = slice ( 6 , 40 ) UNIT_PRICE = slice ( 40 , 52 ) QUANTITY = slice ( 52 , 55 ) ITEM_TOTAL = slice ( 55 , None ) line_items = invoice . split ( ' \\n ' )[ 2 :] # \u6309\u4e0a\u9762invoice\u7684\u683c\u5f0f\uff0c\u7b2c0\u548c1\u884c\u820d\u5f03 for item in line_items : print ( item [ UNIT_PRICE ], item [ DESCRIPTION ]) # $17.50 Primoroni PiBrella # $4.19 6mm Tactile Switch x20 # $28.00 Panavise JR.-PV-201 # $34.95 PiTFT Mini Kit 320x240 Python\u5185\u7f6e\u7684\u5e8f\u5217\u7c7b\u578b\u90fd\u662f\u4e00\u7ef4\u7684\uff0c\u56e0\u6b64\u5b83\u4eec\u53ea\u652f\u6301\u5355\u4e00\u7684\u7d22\u5f15\uff0c\u6210\u5bf9\u51fa\u73b0\u7684\u7d22\u5f15\u662f\u6ca1\u6709\u7528\u7684\u3002 **\u7701\u7565\uff08ellipsis\uff09**\u7684\u6b63\u786e\u4e66\u5199\u65b9\u6cd5\u662f\u4e09\u4e2a\u82f1\u8bed\u53e5\u53f7\uff08...\uff09\uff0c\u800c\u4e0d\u662fUnicdoe\u7801\u4f4dU+2026\u8868\u793a\u7684\u534a\u4e2a\u7701\u7565\u53f7\uff08...\uff09\u3002 \u7701\u7565\u5728Python\u89e3\u6790\u5668\u773c\u91cc\u662f\u4e00\u4e2a\u7b26\u53f7\uff0c\u800c\u5b9e\u9645\u4e0a\u5b83\u662f Ellipsis \u5bf9\u8c61\u7684\u522b\u540d\uff0c\u800c Ellipsis \u5bf9\u8c61\u53c8\u662f ellipsis \u7c7b\u7684\u5355\u4e00\u5b9e\u4f8b\u3002 \u5b83\u53ef\u4ee5\u5f53\u4f5c\u5207\u7247\u89c4\u8303\u7684\u4e00\u90e8\u5206\uff0c\u4e5f\u53ef\u4ee5\u7528\u5728\u51fd\u6570\u7684\u53c2\u6570\u6e05\u5355\u4e2d\uff0c\u6bd4\u5982 f(a, ..., z) \uff0c\u6216 a[i:...] \u3002 \u5728NumPy\u4e2d\uff0c ... \u7528\u4f5c\u591a\u7ef4\u6570\u7ec4\u5207\u7247\u7684\u5feb\u6377\u65b9\u5f0f\u3002\u5982\u679c `x\u662f\u56db\u7ef4\u6570\u7ec4\uff0c\u90a3\u4e48 x[i, ...] \u5c31\u662f x[i, :, :, :]`\u7684\u7f29\u5199\u3002\u5982\u679c\u60f3\u4e86\u89e3\u66f4\u591a\uff0c\u8bf7\u53c2\u89c1\u201cTentative NumPy Tutorial\u201d\u3002 \u5217\u8868\u5e38\u7528\u65b9\u6cd5 \u65b9\u6cd5\u540d\u79f0 \u4f5c\u7528 a.index() \u8fd4\u56dea\u4e2d\u9996\u4e2a\u5339\u914d\u9879\u7684\u4f4d\u7f6e a.pop() \u5220\u9664\u6307\u5b9a\u4f4d\u7f6e\u7684\u5143\u7d20 a.insert() \u5411\u6307\u5b9a\u4f4d\u7f6e\u63d2\u5165\u5143\u7d20 a.reverse() \u53cd\u5411\u6392\u5e8f a.append() \u5411\u672b\u5c3e\u6dfb\u52a0\u5143\u7d20 a.sort() \u5bf9\u5217\u8868\u8fdb\u884c\u6392\u5e8f a.remove() \u5220\u9664\u9996\u4e2a\u5339\u914d\u9879\u7684\u5143\u7d20 a.extend() \u5c06\u4e00\u4e2a\u5217\u8868\u6269\u5c55\u81f3\u53e6\u4e00\u4e2a\u5217\u8868 a.count() \u7edf\u8ba1\u67d0\u4e2a\u5143\u7d20\u51fa\u73b0\u7684\u6b21\u6570 \u521b\u5efa\u5217\u8868list a = [ 1 , 2 , 3 , 4 , 5 ] print ( a ) # [1, 2, 3, 4, 5] b = list ( '12345' ) print ( b ) # ['1', '2', '3', '4', '5'] c = list ( 12345 ) # Traceback (most recent call last): # File \"\", line 1, in # TypeError: 'int' object is not iterable \u5217\u8868\u5207\u7247\uff08\u4ece0\u5f00\u59cb\uff0c\u5de6\u95ed\u53f3\u5f00\uff09\uff1a print ( a [ 2 : 3 ]) # [3] print ( a [: 3 ]) # [1, 2, 3] print ( a [:: - 1 ]) # \u5012\u5e8f # [5, 4, 3, 2, 1] print ( a [::]) # [1, 2, 3, 4, 5] print ( a [:: 1 ]) [ 1 , 2 , 3 , 4 , 5 ] \u5217\u8868\u662f\u53ef\u4fee\u6539\u7684\uff1a print ( a [ 1 ]) # 2 a [ 1 ] = 'one' print ( a ) @ [ 1 , 'one' , 3 , 4 , 5 ] \u5217\u8868\u8ffd\u52a0\u548c\u63d2\u5165\u3002insert\u4e0eappend\u76f8\u6bd4\uff0c\u8ba1\u7b97\u4ee3\u4ef7\u66f4\u9ad8\u3002\u56e0\u4e3a\u5b50\u5e8f\u5217\u5143\u7d20\u9700\u8981\u5728\u5185\u90e8\u79fb\u52a8\u4e3a\u65b0\u5143\u7d20\u63d0\u4f9b\u7a7a\u95f4\u3002 a . append ( 6 ) # \u6ce8\u610f\uff0c\u76f4\u63a5\u4fee\u6539\u539f\u5217\u8868\uff0c\u4e0d\u662f\u521b\u5efa\u526f\u672c\u3002 print ( a ) # [1, 'one', 3, 4, 5, 6] a . extend ([ 7 , 8 , 9 ]) print ( a ) # [1, 'one', 3, 4, 5, 6, 7, 8, 9] a . insert ( 0 , 'Italy' ) print ( a ) # ['Italy', 1, 3, 5, 6, 7, 8] \u5217\u8868\u5220\u9664\u5143\u7d20\uff0c\u9ed8\u8ba4\u5220\u9664\u6700\u540e\u4e00\u4e2a\u3002insert\u7684\u53cd\u64cd\u4f5c\u662fpop\u3002 a . pop () # 9 print ( a ) # [1, 'one', 3, 4, 5, 6, 7, 8] a . pop ( 3 ) # 4 print ( a ) # [1, 'one', 3, 5, 6, 7, 8] \u5220\u9664\u5217\u8868\u4e2d\u67d0\u4e2a\u5143\u7d20\u3002 print ( a [ 1 ]) # one del a [ 1 ] print ( a ) [ 1 , 3 , 5 , 6 , 7 , 8 ] \u5220\u9664\u5217\u8868\u4e2d\u67d0\u4e2a\u5143\u7d20\u3002remove\u65b9\u6cd5\u4f1a\u5b9a\u4f4d\u7b2c\u4e00\u4e2a\u7b26\u5408\u8981\u6c42\u7684\u503c\u5e76\u79fb\u9664 a . remove ( 'Italy' ) print ( a ) # [1, 3, 5, 6, 7, 8] \u7edf\u8ba1\u67d0\u4e2a\u5143\u7d20\u51fa\u73b0\u7684\u6b21\u6570\u3002 print ( a . count ( 1 )) # 1 \u8fd4\u56de\u5217\u8868\u4e2d\u5339\u914d\u9879\u7684\u7d22\u5f15\u4f4d\u7f6e\u3002\u5339\u914d\u4e0d\u5230\u629b\u51fa\u5f02\u5e38\u3002 print ( a . index ( 2 )) # Traceback (most recent call last): # File \"\", line 1, in # ValueError: 2 is not in list print ( a . index ( 3 )) # 1 \u5224\u65ad\u5143\u7d20\u662f\u5426\u5b58\u5728\u4e8e\u5217\u8868\u3002 print ( 3 in a ) # True print ( '3' in a ) # False \u53cd\u5411\u8f93\u51fa\u5217\u8868\u3002 a . reverse () print ( a ) # [8, 7, 6, 5, 3, 1] \u53d6\u5217\u8868\u4e2d\u6700\u5927\u503c\u3001\u6700\u5c0f\u503c\u3002 print ( min ( a )) # 1 print ( max ( a )) # 78 \u8ba1\u7b97\u5217\u8868\u957f\u5ea6\u3002 print ( len ( a )) # 6 \u5217\u8868\u6269\u5c55\uff1a a = [ 1 , 2 , 3 ] b = [ 4 , 5 , 6 ] print ( a + b ) # [1, 2, 3, 4, 5, 6] a . extend ( b ) # a\u5217\u8868\u88ab\u4fee\u6539 print ( a ) # [1, 2, 3, 4, 5, 6] print ( b ) # [4, 5, 6] \u4f7f\u7528extend\u6dfb\u52a0\u5143\u7d20\u6bd4\u4f7f\u7528\u52a0\u53f7\uff08+\uff09\u8fde\u63a5\u6548\u7387\u66f4\u9ad8\u3002\u56e0\u4e3a\u4f7f\u7528\u52a0\u53f7\uff08+\uff09\u8fde\u63a5\u8fc7\u7a0b\u4e2d\u521b\u5efa\u4e86\u65b0\u5217\u8868\uff0c\u5e76\u4e14\u8fd8\u8981\u590d\u5236\u5bf9\u8c61\u3002 a_list = [ 4 , None , 'foo' ] b_list = [ 7 , 8 , ( 2 , 3 )] print ( a_list + b_list ) # [4, None, 'foo', 7, 8, (2, 3)] \u4f7f\u7528+\u53f7\u8fde\u63a5 a_list . extend ( b_list ) print ( a_list ) # [4, None, 'foo', 7, 8, (2, 3)] Python\u7684\u4e00\u4e2a\u60ef\u4f8b\uff1a\u5982\u679c\u4e00\u4e2a\u51fd\u6570\u6216\u8005\u65b9\u6cd5\u5bf9\u5bf9\u8c61\u8fdb\u884c\u7684\u662f\u5c31\u5730\u6539\u52a8\uff0c\u90a3\u5b83\u5c31\u5e94\u8be5\u8fd4\u56deNone\uff0c\u597d\u8ba9\u8c03\u7528\u8005\u77e5\u9053\u4f20\u5165\u7684\u53c2\u6570\u53d1\u751f\u4e86\u53d8\u52a8\uff0c\u800c\u4e14\u5e76\u672a\u4ea7\u751f\u65b0\u7684\u5bf9\u8c61\u3002 \u4e0b\u9762\u662f\u6392\u5e8f\u7684\u4f8b\u5b50 list.sort() \u548c sorted(list) \u7684\u533a\u522b\u3002 list1 = [ '1' , 'one' , '3' , 'Four' , '5' , 'two' , 'apple' , '8' , '9' ] print ( list1 ) # ['1', 'one', '3', 'Four', '5', 'two', 'apple', '8', '9'] # \u4e0b\u9762\u7684\u64cd\u4f5c\u4e0d\u6539\u53d8\u539f\u5217\u8868 print ( sorted ( list1 )) # ['1', '3', '5', '8', '9', 'Four', 'apple', 'one', 'two'] print ( sorted ( list1 , reverse = True )) # ['two', 'one', 'apple', 'Four', '9', '8', '5', '3', '1'] print ( sorted ( list1 , key = len )) # ['1', '3', '5', '8', '9', 'one', 'two', 'Four', 'apple'] print ( list1 ) # ['1', 'one', '3', 'Four', '5', 'two', 'apple', '8', '9'] # \u4e0b\u9762\u7684\u64cd\u4f5c\u76f4\u63a5\u4fee\u6539\u539f\u5217\u8868\uff0c\u8fd4\u56de\u503c\u662fNone print ( list1 . sort ()) # None print ( list1 ) # ['1', '3', '5', '8', '9', 'Four', 'apple', 'one', 'two'] \u5217\u8868\u590d\u5236\uff0c + \u548c * \u7684\u64cd\u4f5c\u90fd\u662f\u4e0d\u4fee\u6539\u539f\u6709\u7684\u64cd\u4f5c\u5bf9\u8c61\uff0c\u800c\u662f\u6784\u5efa\u4e00\u4e2a\u5168\u65b0\u7684\u5217\u8868\u3002 c = list ( 'Python' ) print ( a + c ) # [1, 2, 3, 4, 5, 6, 'P', 'y', 't', 'h', 'o', 'n'] print ( a * 3 ) # [1, 2, 3, 4, 5, 6, 1, 2, 3, 4, 5, 6, 1, 2, 3, 4, 5, 6] \u5982\u679c\u5728 a * n \u8fd9\u4e2a\u8bed\u53e5\u4e2d\uff0c\u5e8f\u5217 a \u91cc\u7684\u5143\u7d20\u662f\u5bf9\u5176\u4ed6\u53ef\u53d8\u5bf9\u8c61\u7684\u5f15\u7528\u7684\u8bdd\uff0c\u5c31\u9700\u8981\u683c\u5916\u6ce8\u610f\u4e86\uff0c\u56e0\u4e3a\u8fd9\u4e2a\u5f0f\u5b50\u7684\u7ed3\u679c\u53ef\u80fd\u4f1a\u51fa\u4e4e\u610f\u6599\u3002 \u6bd4\u5982\uff0c\u6211\u4eec\u60f3\u7528 my_list=[[]] * 3 \u6765\u521d\u59cb\u5316\u4e00\u4e2a\u7531\u5217\u8868\u7ec4\u6210\u7684\u5217\u8868\uff0c\u4f46\u662f\u6211\u4eec\u5b9e\u9645\u5f97\u5230\u7684\u5217\u8868\u91cc\u5305\u542b\u76843\u4e2a\u5143\u7d20\u5176\u5b9e\u662f3\u4e2a\u5f15\u7528\uff0c\u800c\u4e14\u8fd93\u4e2a\u5f15\u7528\u6307\u5411\u7684\u90fd\u662f*\u540c\u4e00\u4e2a*\u5217\u8868\u3002\u770b\u4e0b\u9762\u4f8b\u5b50\u3002 # \u505a\u6cd51 board = [[ '_' ] * 3 for i in range ( 3 )] print ( board ) # [['_', '_', '_'], ['_', '_', '_'], ['_', '_', '_']] board [ 1 ][ 2 ] = 'X' print ( board ) # [['_', '_', '_'], ['_', '_', 'X'], ['_', '_', '_']] # \u505a\u6cd52 board = [[ '_' ] * 3 ] * 3 print ( board ) # [['_', '_', '_'], ['_', '_', '_'], ['_', '_', '_']] board [ 1 ][ 2 ] = 'X' print ( board ) # [['_', '_', 'X'], ['_', '_', 'X'], ['_', '_', 'X']] \u4e0b\u9762\u4e5f\u662f\u540c\u6837\u7684\u95ee\u9898\u3002 # \u65b9\u6cd51 row = [ '_' ] * 3 board = [] for i in range ( 3 ): board . append ( row ) print ( board ) # [['_', '_', '_'], ['_', '_', '_'], ['_', '_', '_']] board [ 2 ][ 0 ] = 'X' print ( board ) # [['X', '_', '_'], ['X', '_', '_'], ['X', '_', '_']] # \u65b9\u6cd52 row = [] board = [] for i in range ( 3 ): row = [ '_' ] * 3 board . append ( row ) print ( board ) # [['_', '_', '_'], ['_', '_', '_'], ['_', '_', '_']] board [ 2 ][ 0 ] = 'X' print ( board ) # [['_', '_', '_'], ['_', '_', '_'], ['X', '_', '_']] \u53cc\u7aef\u961f\u5217collections.deque \uff0c\u53ef\u4ee5\u6ee1\u8db3\u5217\u8868\u5934\u5c3e\u90e8\u90fd\u589e\u52a0\u7684\u8981\u6c42\u3002 deque() \u4e2d maxlen \u662f\u4e00\u4e2a\u53ef\u9009\u53c2\u6570\uff0c\u4ee3\u8868\u8fd9\u4e2a\u961f\u5217\u53ef\u4ee5\u5bb9\u7eb3\u7684\u5143\u7d20\u7684\u6570\u91cf\uff0c\u800c\u4e14\u4e00\u65e6\u8bbe\u5b9a\uff0c\u8fd9\u4e2a\u5c5e\u6027\u5c31\u4e0d\u80fd\u4fee\u6539\u4e86\u3002 \u5f53\u8bd5\u56fe\u5bf9\u4e00\u4e2a\u5df2\u6ee1 len(d)==d.maxlen \u7684\u961f\u5217\u505a\u5934\u90e8\u6dfb\u52a0\u64cd\u4f5c\u7684\u65f6\u5019\uff0c\u5b83\u5c3e\u90e8\u7684\u5143\u7d20\u4f1a\u88ab\u5220\u9664\u6389\u3002 extendleft(iter) \u65b9\u6cd5\u4f1a\u628a\u8fed\u4ee3\u5668\u91cc\u7684\u5143\u7d20\u9010\u4e2a\u6dfb\u52a0\u5230\u53cc\u5411\u961f\u5217\u7684\u5de6\u8fb9\uff0c\u56e0\u6b64\u8fed\u4ee3\u5668\u91cc\u7684\u5143\u7d20\u4f1a\u9006\u5e8f\u51fa\u73b0\u5728\u961f\u5217\u91cc\u3002 \u961f\u5217\u7684\u65cb\u8f6c\u64cd\u4f5c rotate \u63a5\u53d7\u4e00\u4e2a\u53c2\u6570n\uff0c\u5f53n > 0\u65f6\uff0c\u961f\u5217\u7684\u6700\u53f3\u8fb9\u7684n\u4e2a\u5143\u7d20\u4f1a\u88ab\u79fb\u52a8\u5230\u961f\u5217\u7684\u5de6\u8fb9\u3002\u5f53n < 0\u65f6\uff0c\u6700\u5de6\u8fb9\u7684n\u4e2a\u5143\u7d20\u4f1a\u88ab\u79fb\u52a8\u5230\u53f3\u8fb9\u3002 from collections import deque d = deque ([ 1 , 2 , 3 ]) print ( d ) # deque([1, 2, 3]) # \u6ce8\u610f\u63d2\u5165\u987a\u5e8f d . extendleft ([ 'a' , 'b' , 'c' ]) print ( d ) # deque(['c', 'b', 'a', 1, 2, 3]) print ( len ( d )) # 6 print ( d [ - 2 ]) # 2 # \u7edf\u8ba1\u5b57\u7b26a\u51fa\u73b0\u7684\u6b21\u6570 print ( d . count ( 'a' )) # 1 # \u8fd4\u56de\u5b57\u7b26a\u7684\u7d22\u5f15\u503c print ( d . index ( 'a' )) # 2 # \u7b2c0\u4f4d\u63d2\u5165\u6570\u5b571\uff0c\u5176\u4f59\u987a\u79fb d . insert ( 0 , 1 ) print ( d ) # deque([1, 'c', 'b', 'a', 1, 2, 3]) # \u628a\u53f3\u8fb92\u4e2a\u5143\u7d20\u653e\u5230\u5de6\u8fb9\uff0c\u6ce8\u610f\u987a\u5e8f\uff0c\u548cextendleft\u4e0d\u4e00\u6837 d . rotate ( 2 ) print ( d ) # deque([2, 3, 1, 'c', 'b', 'a', 1]) d . rotate ( - 2 ) print ( d ) # deque([1, 'c', 'b', 'a', 1, 2, 3]) \u4e0b\u8868\u603b\u7ed3\u4e86\u5217\u8868\u548c\u53cc\u5411\u961f\u5217\u7684\u65b9\u6cd5\uff08\u4e0d\u5305\u62ec\u7531\u5bf9\u8c61\u5b9e\u73b0\u7684\u65b9\u6cd5\uff09\u3002 \u5217\u8868\u6392\u5e8f\u3002\u6392\u5e8f\u5bf9\u5217\u8868\u5143\u7d20\u7684\u6570\u636e\u7c7b\u578b\u662f\u6709\u8981\u6c42\u7684\u3002 a_list = [ 4 , None , 'foo' , 7 , 8 , ( 2 , 3 )] a_list . sort () # Traceback (most recent call last): # File \"\", line 1, in # TypeError: '<' not supported between instances of 'NoneType' and 'int' b_list = [ 7 , 8 , ( 2 , 3 )] b_list . sort () # Traceback (most recent call last): # File \"\", line 1, in # TypeError: '<' not supported between instances of 'tuple' and 'int' a_list = [ 7 , 2 , 5 , 1 , 3 ] a_list . sort () # \u6309\u6570\u503c\u5927\u5c0f\u6392\u5e8f print ( a_list ) # [1, 2, 3, 5, 7] b_list = [ 'saw' , 'small' , 'He' , 'foxes' , 'six' ] b_list . sort ( key = len ) # \u901a\u8fc7\u5b57\u7b26\u4e32\u7684\u957f\u5ea6\u8fdb\u884c\u6392\u5e8f print ( b_list ) # ['He', 'saw', 'six', 'small', 'foxes'] \u5217\u8868\u4e8c\u5206\u641c\u7d22\u548c\u5df2\u6392\u5e8f\u5217\u8868\u7684\u7ef4\u62a4 bisect \u8fd4\u56de\u8981\u63d2\u5165\u5143\u7d20\u5728\u5217\u8868\u4e2d\u7684\u4e0b\u6807\u3002\u5047\u5b9a\u5217\u8868\u662f\u6709\u5e8f\u7684\u3002 bisect_left \u4e0e bisect \u7c7b\u4f3c\uff0c\u53ea\u4e0d\u8fc7\u5176\u9ed8\u8ba4\u5c06\u5143\u7d20\u63d2\u5230\u5de6\u8fb9\uff0c\u6240\u4ee5\u8fd4\u56de\u7684\u662f\u63d2\u5165\u5230\u5de6\u8fb9\u7684\u4e0b\u6807 bisect_right\u4e0e bisect_left \u76f8\u53cd\u3002 \u4ee5\u4e0a\u65b9\u6cd5\u82e5\u5217\u8868\u65e0\u5e8f\uff0c\u90a3\u4e48\u4f1a\u8fd4\u56de\u63d2\u5165\u5230\u5217\u8868\u6700\u540e\u4e00\u4e2a\u5408\u9002\u7684\u4f4d\u7f6e\u3002 insort \u4f1a\u5728\u5217\u8868\u4e2d\u63d2\u5165\u5143\u7d20\u5230\u6b63\u786e\u4f4d\u7f6e\uff0c\u5047\u5b9a\u5217\u8868\u6709\u5e8f\u3002\u5982\u679c\u5217\u8868\u65e0\u5e8f\uff0c\u90a3\u4e48\u4f1a\u8fd4\u56de\u7a7a\u3002\u9ed8\u8ba4\u63d2\u5165\u5230\u53f3\u8fb9\u3002 insort_left \u548cinsort_right \u7c7b\u4f3c\u3002 import bisect c = [ 1 , 2 , 3 , 4 , 7 ] print ( bisect . bisect ( c , 2 )) # 2 bisect\u4f1a\u627e\u5230\u7b2c\u4e00\u4e2a2,\u5e76\u628a\u65b0\u76842\u63d2\u5165\u5b83\u540e\u9762 bisect . insort ( c , 2 ) # [1, 2, 2, 3, 4, 7] print ( bisect . bisect ( c , 5 )) # 5 bisect\u4f1a\u627e\u5230\u7b2c\u4e00\u4e2a4,\u5e76\u628a\u65b0\u76845\u63d2\u5165\u5b83\u540e\u9762 bisect . insort ( c , 5 ) print ( bisect . bisect ( c , 6 )) # 6 bisect\u4f1a\u627e\u5230\u7b2c\u4e00\u4e2a5,\u5e76\u628a\u65b0\u76846\u63d2\u5165\u5b83\u540e\u9762 bisect . insort ( c , 6 ) print ( c ) # [1, 2, 2, 3, 4, 5, 6, 7] bisect\u53ef\u4ee5\u7528\u6765\u5efa\u7acb\u4e00\u4e2a\u7528\u6570\u5b57\u4f5c\u4e3a\u7d22\u5f15\u7684\u67e5\u8be2\u8868\u683c\uff0c\u5982\u4e0b\u4f8b\uff0c\u628a\u5206\u6570\u548c\u6210\u7ee9\u5bf9\u5e94\u8d77\u6765\uff0c\u6839\u636e\u4e00\u4e2a\u5206\u6570\uff0c\u627e\u5230\u5b83\u6240\u5bf9\u5e94\u7684\u6210\u7ee9\u3002 import bisect def grade ( score , breakpoints = [ 60 , 70 , 80 , 90 ], grades = 'FDCBA' ): i = bisect . bisect ( breakpoints , score ) return grades [ i ] [ grade ( score ) for score in [ 15 , 26 , 31 , 62 , 79 , 85 ]] # ['F', 'F', 'F', 'D', 'C', 'B'] \u7528bisect.insort\u63d2\u5165\u65b0\u5143\u7d20\uff0c\u5e76\u80fd\u4fdd\u6301seq\u7684\u5347\u5e8f\u987a\u5e8f\u3002 import bisect import random size = 7 random . seed ( 1729 ) my_list = [] for i in range ( size ): new_item = random . randrange ( size * 2 ) bisect . insort ( my_list , new_item ) print ( f ' { new_item : 2d } :--> { my_list } ' ) # 10 :--> [10] # 0 :--> [0, 10] # 6 :--> [0, 6, 10] # 8 :--> [0, 6, 8, 10] # 7 :--> [0, 6, 7, 8, 10] # 2 :--> [0, 2, 6, 7, 8, 10] # 10 :--> [0, 2, 6, 7, 8, 10, 10]","title":"1.3 \u5217\u8868\uff08list\uff09"},{"location":"python/Foundation/ch01/#14-dictionary","text":"\u5b57\u5178(dict)\u662f\u4f7f\u7528\u952e-\u503c\uff08key-value\uff09\u5b58\u50a8\uff0c\u952e\u662f\u4e0d\u53ef\u53d8\u5bf9\u8c61\uff0c\u4e14\u4e0d\u5141\u8bb8\u91cd\u590d\u3002 dict\uff08\u5b57\u5178\uff09\u66f4\u4e3a\u5e38\u7528\u7684\u540d\u5b57\u662f\u54c8\u5e0c\u8868\u6216\u8005\u662f\u5173\u8054\u6570\u7ec4\u3002 \u5b57\u5178\u662f\u62e5\u6709\u7075\u6d3b\u5c3a\u5bf8\u7684\u952e\u503c\u5bf9\u96c6\u5408\uff0c\u4e0d\u662f\u901a\u8fc7\u4f4d\u7f6e\u8fdb\u884c\u7d22\u5f15\uff0c\u5176\u4e2d\u952e\u548c\u503c\u90fd\u662fPython\u5bf9\u8c61\u3002\u7528\u5927\u62ec\u53f7{}\u662f\u521b\u5efa\u5b57\u5178\u7684\u4e00\u79cd\u65b9\u5f0f\uff0c\u5728\u5b57\u5178\u4e2d\u7528\u9017\u53f7\u5c06\u952e\u503c\u5bf9\u5206\u9694\u3002 \u521b\u5efa\u5b57\u5178\u7684\u51e0\u79cd\u65b9\u6cd5\uff1a a = dict ( one = 1 , two = 2 , three = 3 ) b = { 'one' : 1 , 'two' : 2 , 'three' : 3 } c = dict ( zip ([ 'one' , 'two' , 'three' ], [ 1 , 2 , 3 ])) d = dict ([( 'two' , 2 ), ( 'three' , 3 ), ( 'one' , 1 )]) e = dict ({ 'three' : 3 , 'one' : 1 , 'two' : 2 }) print ( a == b == c == d == e ) # True \u5b57\u5178\u5e38\u7528\u65b9\u6cd5 \u65b9\u6cd5\u540d\u79f0 \u4f5c\u7528 a.items() \u8fd4\u56dea\u4e2d\u6240\u6709\u952e\u503c\u5bf9 a.values() \u8fd4\u56dea\u4e2d\u6240\u6709\u503c a.keys() \u8fd4\u56dea\u4e2d\u6240\u6709\u952e a.get() \u901a\u8fc7\u952e\u6765\u67e5\u503c\uff0c\u8fd4\u56de\u5bf9\u5e94\u7684\u503c a.clear() \u6e05\u7a7a\u5b57\u5178a\u7684\u503c a.setdefault \u901a\u8fc7\u952e\u503c\u6765\u67e5\u627e\u503c\uff0c\u627e\u4e0d\u5230\u5219\u63d2\u5165 a.update() \u952e\u548c\u503c\u66f4\u65b0\u5230\u65b0\u7684\u5b57\u5178 a.pop() \u5220\u9664\u6307\u5b9a\u4f4d\u7f6e\u7684\u5143\u7d20 \u751f\u6210\u4e00\u4e2a\u5b57\u5178\u3002 dict_a = { 'name' : 'Ming' , 'id' : 1001 , 'age' : 35 } print ( type ( dict_a )) # dict_b = dict ( city = 'Shanghai' , strict = 'Xuhui' , zip = '200000' ) print ( type ( dict_b )) # \u901a\u8fc7\u952e\u67e5\u8be2\u503c\uff0c\u67e5\u8be2\u4e0d\u5230\u629b\u51fa\u5f02\u5e38\u3002 print ( dict_a [ 'name' ]) # Ming print ( dict_a [ 'Name' ]) # Traceback (most recent call last): # File \"\", line 1, in # KeyError: 'Name' \u63d2\u5165\u65b0\u7684\u952e\u503c\u5bf9\u3002 dict_a [ 'city' ] = 'Chengdu' print ( dict_a ) # {'name': 'Ming', 'id': 1001, 'city': 'Chengdu'} \u5220\u9664\u67d0\u4e2a\u952e\u503c\u5bf9\u3002pop\u65b9\u6cd5\u4f1a\u5728\u5220\u9664\u7684\u540c\u65f6\u8fd4\u56de\u88ab\u5220\u7684\u503c\uff0c\u5e76\u5220\u9664\u952e\u3002 dict_a . pop ( 'city' ) # Chengdu print ( dict_a ) # {'name': 'Ming', 'id': 1001} \u53e6\u4e00\u79cd\u65b9\u5f0f\u5220\u9664\u67d0\u4e2a\u952e\u503c\u5bf9\u3002 del dict_a [ 'age' ] # Traceback (most recent call last): # File \"\", line 1, in # KeyError: 'age' del dict_a [ 'id' ] print ( dict_a ) # {'name': 'Ming'} \u5224\u65ad\u952e\u662f\u5426\u5b58\u5728\u3002 dict_a [ 23 ] = 'Hello World' print ( dict_a ) # {'name': 'Ming', 23: 'Hello World'} print ( 23 in dict_a ) # True print ( 35 in dict_a ) # False \u901a\u8fc7\u952e\u67e5\u8be2\u503c\u7684\u53e6\u4e00\u79cd\u65b9\u5f0f\uff0c\u67e5\u8be2\u4e0d\u5230\u4e0d\u629b\u5f02\u5e38\u3002 dict_a . get ( 'hai' ) dict_a . get ( 'hai' , 1 ) # 1 dict_a . get ( 'name' , 1 ) # Ming dict_a [ 'hai' ] # Traceback (most recent call last): # File \"\", line 1, in # KeyError: 'hai' \u901a\u8fc7\u952e\u67e5\u8be2\u503c\u7684\u53e6\u4e00\u79cd\u65b9\u5f0f\uff0c\u67e5\u8be2\u4e0d\u5230\u5219\u6dfb\u52a0\u3002 dict_a . setdefault ( 'name' ) # Ming dict_a . setdefault ( 'hai' , 1 ) # 1 print ( dict_a ) # {'name': 'Ming', 23: 'Hello World', 'hai': 1} dict_a . setdefault ( 'go' ) print ( dict_a ) # {'name': 'Ming', 23: 'Hello World', 'hai': 1, 'go': None} \u8bfb\u53d6\u5b57\u5178\u6240\u6709\u952e\u503c\u5bf9\uff0c\u8fd4\u56de\u7684\u662f\u5217\u8868\u5f62\u5f0f\u3002 print ( dict_a . items ()) # dict_items([('name', 'Ming'), (23, 'Hello World'), ('hai', 1), ('go', None)]) \u8bfb\u53d6\u5b57\u5178\u7684\u952e\u3002 print ( dict_a . keys ()) # dict_keys(['name', 23, 'hai', 'go']) \u8bfb\u53d6\u5b57\u5178\u7684\u503c\u3002 print ( dict_a . values ()) # dict_values(['Ming', 'Hello World', 1, None]) \u5c06\u5b57\u5178\u503c\u8f6c\u5316\u6210\u5217\u8868\u3002 print ( list ( dict_a . values ())) # ['Ming', 'Hello World', 1, None] for key in dict_a . keys (): print ( dict_a [ key ]) # Ming # Hello World # 1 # None \u6e05\u7a7a\u5b57\u5178\u3002 dict_a . clear () print ( dict_a ) # {} print ( len ( dict_a )) # 0 \u5bf9\u4e8e\u4efb\u4f55\u539f\u5b57\u5178\u4e2d\u5df2\u7ecf\u5b58\u5728\u7684\u952e\uff0c\u5982\u679c\u4f20\u7ed9update\u65b9\u6cd5\u7684\u6570\u636e\u4e5f\u542b\u6709\u76f8\u540c\u7684\u952e\uff0c\u5219\u5b83\u7684\u503c\u5c06\u4f1a\u88ab\u8986\u76d6\u3002 dict_a = { 'name' : 'Ming' , 'id' : 1001 , 'age' : 35 } dict_b = dict ( city = 'Shanghai' , id = 2001 , zip = '200000' ) dict_a . update ( dict_b ) print ( dict_a ) # {'name': 'Ming', 'id': 2001, 'age': 35, 'city': 'Shanghai', 'zip': '200000'} \u4ece\u5217\u8868\u751f\u6210\u5b57\u5178\u3002 \u5b57\u5178\u672c\u8d28\u4e0a\u662f2-\u5143\u7ec4\uff08\u542b\u67092\u4e2a\u5143\u7d20\u7684\u5143\u7ec4\uff09\u7684\u96c6\u5408\uff0c\u5b57\u5178\u662f\u53ef\u4ee5\u63a5\u53d7\u4e00\u4e2a2-\u5143\u7ec4\u7684\u5217\u8868\u4f5c\u4e3a\u53c2\u6570\u7684\u3002 # \u65b9\u6cd51 mapping = {} key_list = list ( range ( 5 )) value_list = list ( reversed ( range ( 5 ))) for key , value in zip ( key_list , value_list ): mapping [ key ] = value print ( mapping ) # {0: 4, 1: 3, 2: 2, 3: 1, 4: 0} # \u65b9\u6cd52\u3002 mapping = {} key_list = list ( range ( 5 )) value_list = list ( reversed ( range ( 5 ))) mapping = dict ( zip ( key_list , value_list )) print ( mapping ) # {0: 4, 1: 3, 2: 2, 3: 1, 4: 0} \u6709\u6548\u7684\u5b57\u5178\u952e\u7c7b\u578b\u3002 \u5c3d\u7ba1\u5b57\u5178\u7684\u503c\u53ef\u4ee5\u662f\u4efb\u4f55Python\u5bf9\u8c61\uff0c\u4f46\u952e\u5fc5\u987b\u662f\u4e0d\u53ef\u53d8\u7684\u5bf9\u8c61\uff0c\u6bd4\u5982\u6807\u91cf\u7c7b\u578b\uff08\u6574\u6570\u3001\u6d6e\u70b9\u6570\u3001\u5b57\u7b26\u4e32\uff09\u6216\u5143\u7ec4\uff08\u4e14\u5143\u7ec4\u5185\u5bf9\u8c61\u4e5f\u5fc5\u987b\u662f\u4e0d\u53ef\u53d8\u5bf9\u8c61\uff09\u3002 \u901a\u8fc7hash\u51fd\u6570\u53ef\u4ee5\u68c0\u67e5\u4e00\u4e2a\u5bf9\u8c61\u662f\u5426\u53ef\u4ee5\u54c8\u5e0c\u5316\uff08\u5373\u662f\u5426\u53ef\u4ee5\u7528\u4f5c\u5b57\u5178\u7684\u952e\uff09\uff0c\u672f\u8bed\u53eb\u4f5c\u54c8\u5e0c\u5316\u3002 print ( hash ( 'string' )) # -4368784820203065343 print ( hash (( 1 , 2 , ( 2 , 3 )))) # -9209053662355515447 print ( hash (( 1 , 2 , [ 2 , 3 ]))) # TypeError: unhashable type: 'list' print ( hash (( 1 , 2 , tuple ([ 2 , 3 ])))) # -9209053662355515447 \u4e3a\u4e86\u5c06\u5217\u8868\u4f5c\u4e3a\u952e\uff0c\u4e00\u79cd\u65b9\u5f0f\u5c31\u662f\u5c06\u5176\u8f6c\u6362\u4e3a\u5143\u7ec4 \u5b57\u5178\u9ed8\u8ba4\u503c\u3002 \u4e0b\u9762\u7684\u4f8b\u5b50\uff0c\u5b9e\u73b0\u4e86\u5c06\u4e00\u4e2a\u5355\u8bcd\u7ec4\u6210\u7684\u5217\u8868\uff0c\u8f6c\u6362\u6210\u5355\u8bcd\u9996\u5b57\u6bcd\u548c\u5355\u8bcd\u4e3a\u952e\u503c\u5bf9\u7684\u5b57\u5178\u3002\u5148\u7528\u4f20\u7edf\u65b9\u6cd5\u5b9e\u73b0\uff0c\u518d\u7528\u5b57\u5178\u7684setdefault\u65b9\u6cd5\u8fdb\u884c\u6539\u5199\u3002 \u5148\u770b\u4f20\u7edf\u65b9\u6cd5\u3002 words = [ 'apple' , 'bat' , 'bar' , 'atom' , 'book' ] by_letter = {} for word in words : letter = word [ 0 ] # word[0]\u628a\u5217\u8868words\u7684\u6bcf\u4e2a\u5143\u7d20\u5217\u8868\u5316\uff0c\u5e76\u53d6\u9996\u5b57\u6bcd\u3002\u8f93\u51fa\u7684\u662fa, b, b, a, b\u8fd95\u4e2a\u5217\u8868\u5143\u7d20\u7684\u9996\u5b57\u6bcd if letter not in by_letter : # \u751f\u6210\u7b2c\u4e00\u4e2a\u952e\u503c\u5bf9 print ( letter ) by_letter [ letter ] = [ word ] # \u5bf9\u6bd4[word]\u548cword[]\u7684\u7528\u6cd5 print ( by_letter ) # a # {'a': ['apple']} # b # {'a': ['apple'], 'b': ['bat']} else : # append\u5176\u4ed6\u952e\u503c\u5bf9 print ( letter ) by_letter [ letter ] . append ( word ) print ( by_letter ) # b # {'a': ['apple'], 'b': ['bat', 'bar']} # a # {'a': ['apple', 'atom'], 'b': ['bat', 'bar']} # b # {'a': ['apple', 'atom'], 'b': ['bat', 'bar', 'book']} print ( by_letter ) # {'a': ['apple', 'atom'], 'b': ['bat', 'bar', 'book']} \u7528\u5b57\u5178\u7684setdefault\u65b9\u6cd5\uff0c\u4e0a\u8ff0\u7684for\u5faa\u73af\u8bed\u53e5\u53ef\u4ee5\u88ab\u5199\u4e3a\u5982\u4e0b\u3002 words = [ 'apple' , 'bat' , 'bar' , 'atom' , 'book' ] by_letter = {} for word in words : letter = word [ 0 ] # word[0]\u7684\u8f93\u51fa\u4f9d\u7136\u662f5\u4e2a\u5217\u8868\u5143\u7d20\u7684\u9996\u5b57\u6bcda, b, b, a, b by_letter . setdefault ( letter , []) . append ( word ) # \u5982\u679cletter\u4e0d\u5728[]\u5219\u901a\u8fc7append\u6dfb\u52a0word print ( by_letter ) # {'a': ['apple', 'atom'], 'b': ['bat', 'bar', 'book']} \u5982\u679c\u6539\u5199\u4e3a by_letter.setdefault(letter, ['a']).append(word) \uff0c\u5219\u8f93\u51fa by_letter \u662f {'a': ['a', 'apple', 'atom'], 'b': ['a', 'bat', 'bar', 'book']} \u3002 words = [ 'apple' , 'bat' , 'bar' , 'atom' , 'book' ] by_letter = {} for word in words : letter = word [ 0 ] # word[0]\u7684\u8f93\u51fa\u4f9d\u7136\u662f5\u4e2a\u5217\u8868\u5143\u7d20\u7684\u9996\u5b57\u6bcda, b, b, a, b by_letter . setdefault ( letter , [ 'a' ]) . append ( word ) print ( by_letter ) # {'a': ['a', 'apple', 'atom'], 'b': ['a', 'bat', 'bar', 'book']} \u4f53\u4f1asetdefault()\u7684\u6ce8\u91ca\u201cInsert key with a value of default if key is not in the dictionary. Return the value for key if key is in the dictionary, else default.\u201d \u901a\u8fc7defaultdict\u7c7b\u4f7f\u5f97\u4e0a\u8ff0\u76ee\u7684\u5b9e\u73b0\u66f4\u4e3a\u7b80\u5355\u3002 from collections import defaultdict by_letter = defaultdict ( list ) # list\u662f\u5185\u7f6e\u7684\u53ef\u53d8\u5e8f\u5217(Built-in mutable sequence) print ( dict ( by_letter )) # {} for word in words : by_letter [ word [ 0 ]] . append ( word ) print ( by_letter ) # defaultdict(, {'a': ['apple', 'atom'], 'b': ['bat', 'bar', 'book']}) print ( dict ( by_letter )) # {'a': ['apple', 'atom'], 'b': ['bat', 'bar', 'book']} \u4e0b\u8868\u5c55\u793a\u4e86 dict \u3001 defaultdict \u548c OrderedDict \u7684\u5e38\u89c1\u65b9\u6cd5\uff0c\u540e\u9762\u4e24\u4e2a\u6570\u636e\u7c7b\u578b\u662f dict \u7684\u53d8\u79cd\uff0c\u4f4d\u4e8e collections \u6a21\u5757\u5185\u3002 default_factory \u5e76\u4e0d\u662f\u4e00\u4e2a\u65b9\u6cd5\uff0c\u800c\u662f\u4e00\u4e2a\u53ef\u8c03\u7528\u5bf9\u8c61\uff08callable\uff09\uff0c\u5b83\u7684\u503c\u5728 defaultdict \u521d\u59cb\u5316\u7684\u65f6\u5019\u7531\u7528\u6237\u8bbe\u5b9a\u3002 OrderedDict.popitem() \u4f1a\u79fb\u9664\u5b57\u5178\u91cc\u6700\u5148\u63d2\u5165\u7684\u5143\u7d20\uff08\u5148\u8fdb\u5148\u51fa\uff09\uff1b\u540c\u65f6\u8fd9\u4e2a\u65b9\u6cd5\u8fd8\u6709\u4e00\u4e2a\u53ef\u9009\u7684last\u53c2\u6570\uff0c\u82e5\u4e3a\u771f\uff0c\u5219\u4f1a\u79fb\u9664\u6700\u540e\u63d2\u5165\u7684\u5143\u7d20\uff08\u540e\u8fdb\u5148\u51fa\uff09\u3002 \u4e0a\u9762\u7684\u8868\u683c\u4e2d\uff0cupdate\u65b9\u6cd5\u5904\u7406\u53c2\u6570m\u7684\u65b9\u5f0f\uff0c\u662f\u5178\u578b\u7684\u201c\u9e2d\u5b50\u7c7b\u578b\u201d\u3002\u51fd\u6570\u9996\u5148\u68c0\u67e5m\u662f\u5426\u6709keys\u65b9\u6cd5\uff0c\u5982\u679c\u6709\uff0c\u90a3\u4e48update\u51fd\u6570\u5c31\u628a\u5b83\u5f53\u4f5c\u6620\u5c04\u5bf9\u8c61\u6765\u5904\u7406\u3002\u5426\u5219\uff0c\u51fd\u6570\u4f1a\u9000\u4e00\u6b65\uff0c\u8f6c\u800c\u628am\u5f53\u4f5c\u5305\u542b\u4e86\u952e\u503c\u5bf9(key, value)\u5143\u7d20\u7684\u8fed\u4ee3\u5668\u3002Python\u91cc\u5927\u591a\u6570\u6620\u5c04\u7c7b\u578b\u7684\u6784\u9020\u65b9\u6cd5\u90fd\u91c7\u7528\u4e86\u7c7b\u4f3c\u7684\u903b\u8f91\uff0c\u56e0\u6b64\u4f60\u65e2\u53ef\u4ee5\u7528\u4e00\u4e2a\u6620\u5c04\u5bf9\u8c61\u6765\u65b0\u5efa\u4e00\u4e2a\u6620\u5c04\u5bf9\u8c61\uff0c\u4e5f\u53ef\u4ee5\u7528\u5305\u542b(key, value)\u5143\u7d20\u7684\u53ef\u8fed\u4ee3\u5bf9\u8c61\u6765\u521d\u59cb\u5316\u4e00\u4e2a\u6620\u5c04\u5bf9\u8c61\u3002 \u5b57\u5178\u7684\u53d8\u79cd\uff1a collections.OrderedDict \u8fd9\u4e2a\u7c7b\u578b\u5728\u6dfb\u52a0\u952e\u7684\u65f6\u5019\u4f1a\u4fdd\u6301\u987a\u5e8f\uff0c\u56e0\u6b64\u952e\u7684\u8fed\u4ee3\u6b21\u5e8f\u603b\u662f\u4e00\u81f4\u7684\u3002OrderedDict\u7684popitem\u65b9\u6cd5\u9ed8\u8ba4\u5220\u9664\u5e76\u8fd4\u56de\u7684\u662f\u5b57\u5178\u91cc\u7684\u6700\u540e\u4e00\u4e2a\u5143\u7d20\uff0c\u4f46\u662f\u5982\u679c\u50cfmy_odict.popitem(last=False)\u8fd9\u6837\u8c03\u7528\u5b83\uff0c\u90a3\u4e48\u5b83\u5220\u9664\u5e76\u8fd4\u56de\u7b2c\u4e00\u4e2a\u88ab\u6dfb\u52a0\u8fdb\u53bb\u7684\u5143\u7d20\u3002 collections.ChainMap \u8be5\u7c7b\u578b\u53ef\u4ee5\u5bb9\u7eb3\u6570\u4e2a\u4e0d\u540c\u7684\u6620\u5c04\u5bf9\u8c61\uff0c\u7136\u540e\u5728\u8fdb\u884c\u952e\u67e5\u627e\u64cd\u4f5c\u7684\u65f6\u5019\uff0c\u8fd9\u4e9b\u5bf9\u8c61\u4f1a\u88ab\u5f53\u4f5c\u4e00\u4e2a\u6574\u4f53\u88ab\u9010\u4e2a\u67e5\u627e\uff0c\u76f4\u5230\u952e\u88ab\u627e\u5230\u4e3a\u6b62\u3002\u8fd9\u4e2a\u529f\u80fd\u5728\u7ed9\u6709\u5d4c\u5957\u4f5c\u7528\u57df\u7684\u8bed\u8a00\u505a\u89e3\u91ca\u5668\u7684\u65f6\u5019\u5f88\u6709\u7528\uff0c\u53ef\u4ee5\u7528\u4e00\u4e2a\u6620\u5c04\u5bf9\u8c61\u6765\u4ee3\u8868\u4e00\u4e2a\u4f5c\u7528\u57df\u7684\u4e0a\u4e0b\u6587\u3002 collections.Counter \u8fd9\u4e2a\u6620\u5c04\u7c7b\u578b\u4f1a\u7ed9\u952e\u51c6\u5907\u4e00\u4e2a\u6574\u6570\u8ba1\u6570\u5668\u3002\u6bcf\u6b21\u66f4\u65b0\u4e00\u4e2a\u952e\u7684\u65f6\u5019\u90fd\u4f1a\u589e\u52a0\u8fd9\u4e2a\u8ba1\u6570\u5668\u3002\u6240\u4ee5\u8fd9\u4e2a\u7c7b\u578b\u53ef\u4ee5\u7528\u6765\u7ed9\u53ef\u6563\u5217\u8868\u5bf9\u8c61\u8ba1\u6570\uff0c\u6216\u8005\u662f\u5f53\u6210\u591a\u91cd\u96c6\u6765\u7528\u2014\u2014\u591a\u91cd\u96c6\u5408\u5c31\u662f\u96c6\u5408\u91cc\u7684\u5143\u7d20\u53ef\u4ee5\u51fa\u73b0\u4e0d\u6b62\u4e00\u6b21\u3002Counter\u5b9e\u73b0\u4e86+\u548c-\u8fd0\u7b97\u7b26\u7528\u6765\u5408\u5e76\u8bb0\u5f55\uff0c\u8fd8\u6709\u50cfmost_common([n])\u8fd9\u7c7b\u5f88\u6709\u7528\u7684\u65b9\u6cd5\u3002most_common([n])\u4f1a\u6309\u7167\u6b21\u5e8f\u8fd4\u56de\u6620\u5c04\u91cc\u6700\u5e38\u89c1\u7684n\u4e2a\u952e\u548c\u5b83\u4eec\u7684\u8ba1\u6570 collections.UserDict \u8fd9\u4e2a\u7c7b\u5176\u5b9e\u5c31\u662f\u628a\u6807\u51c6dict\u7528\u7eafPython\u53c8\u5b9e\u73b0\u4e86\u4e00\u904d\u3002\u8ddfOrderedDict\u3001ChainMap\u548cCounter\u8fd9\u4e9b\u5f00\u7bb1\u5373\u7528\u7684\u7c7b\u578b\u4e0d\u540c\uff0cUserDict\u662f\u8ba9\u7528\u6237\u7ee7\u627f\u5199\u5b50\u7c7b\u7684\u3002 \u4e0b\u9762\u7684\u4f8b\u5b50\u5229\u7528Counter\u6765\u8ba1\u7b97\u5355\u8bcd\u4e2d\u5404\u4e2a\u5b57\u6bcd\u51fa\u73b0\u7684\u6b21\u6570\uff1a str = 'abracadabra' ct = collections . Counter ( str ) print ( ct ) # Counter({'a': 5, 'b': 2, 'r': 2, 'c': 1, 'd': 1}) \u4e0d\u53ef\u53d8\u6620\u5c04\u7c7b\u578b\u3002 \u6807\u51c6\u5e93\u91cc\u6240\u6709\u7684\u6620\u5c04\u7c7b\u578b\u90fd\u662f\u53ef\u53d8\u7684\uff0c\u4f46\u6709\u65f6\u5019\u4f60\u4f1a\u6709\u8fd9\u6837\u7684\u9700\u6c42\uff0c\u6bd4\u5982\u4e0d\u80fd\u8ba9\u7528\u6237\u9519\u8bef\u5730\u4fee\u6539\u67d0\u4e2a\u6620\u5c04\u3002 \u4ecePython 3.3\u5f00\u59cb\uff0c types \u6a21\u5757\u4e2d\u5f15\u5165\u4e86\u4e00\u4e2a\u5c01\u88c5\u7c7b\u540d\u53eb MappingProxyType \u3002\u5982\u679c\u7ed9\u8fd9\u4e2a\u7c7b\u4e00\u4e2a\u6620\u5c04\uff0c\u5b83\u4f1a\u8fd4\u56de\u4e00\u4e2a\u53ea\u8bfb\u7684\u6620\u5c04\u89c6\u56fe\u3002\u867d\u7136\u662f\u4e2a\u53ea\u8bfb\u89c6\u56fe\uff0c\u4f46\u662f\u5b83\u662f\u52a8\u6001\u7684\u3002\u8fd9\u610f\u5473\u7740\u5982\u679c\u5bf9\u539f\u6620\u5c04\u505a\u51fa\u4e86\u6539\u52a8\uff0c\u6211\u4eec\u901a\u8fc7\u8fd9\u4e2a\u89c6\u56fe\u53ef\u4ee5\u89c2\u5bdf\u5230\uff0c\u4f46\u662f\u65e0\u6cd5\u901a\u8fc7\u8fd9\u4e2a\u89c6\u56fe\u5bf9\u539f\u6620\u5c04\u505a\u51fa\u4fee\u6539\u3002 \u901a\u8fc7\u4e0b\u4f8b\u53ef\u4ee5\u770b\u51fa\uff0c d \u4e2d\u7684\u5185\u5bb9\u53ef\u4ee5\u901a\u8fc7 d_proxy \u770b\u5230\u3002\u4f46\u662f\u901a\u8fc7 d_proxy \u5e76\u4e0d\u80fd\u505a\u4efb\u4f55\u4fee\u6539\u3002 d_proxy \u662f\u52a8\u6001\u7684\uff0c\u4e5f\u5c31\u662f\u8bf4\u5bf9 d \u6240\u505a\u7684\u4efb\u4f55\u6539\u52a8\u90fd\u4f1a\u53cd\u9988\u5230\u5b83\u4e0a\u9762\u3002 from types import MappingProxyType d = { 1 : 'A' } d_proxy = MappingProxyType ( d ) print ( d ) # {1: 'A'} print ( d_proxy ) # {1: 'A'} print ( d [ 1 ]) # A print ( d_proxy [ 1 ]) # A d [ 2 ] = 'W' print ( d ) # {1: 'A', 2: 'W'} d_proxy [ 2 ] = 'W' # TypeError: 'mappingproxy' object does not support item assignment print ( d_proxy ) # {1: 'A', 2: 'W'}","title":"1.4 \u5b57\u5178\uff08dictionary\uff09"},{"location":"python/Foundation/ch01/#15-set","text":"\u201c\u96c6\u201d\u8fd9\u4e2a\u6982\u5ff5\u5728Python\u4e2d\u7b97\u662f\u6bd4\u8f83\u5e74\u8f7b\u7684\uff0c\u540c\u65f6\u5b83\u7684\u4f7f\u7528\u7387\u4e5f\u6bd4\u8f83\u4f4e\u3002set\u548c\u5b83\u7684\u4e0d\u53ef\u53d8\u7684\u59ca\u59b9\u7c7b\u578bfrozenset\u76f4\u5230Python 2.3\u624d\u9996\u6b21\u4ee5\u6a21\u5757\u7684\u5f62\u5f0f\u51fa\u73b0\uff0c\u7136\u540e\u5728Python 2.6\u4e2d\u5b83\u4eec\u5347\u7ea7\u6210\u4e3a\u5185\u7f6e\u7c7b\u578b\u3002 \u96c6\u5408(set) \uff0c\u5305\u542b\u4e0d\u53ef\u53d8\u7684\u96c6\u5408\uff08frozenset\uff09\uff0c\u662f\u4e00\u79cd\u65e0\u5e8f\u4e14\u5143\u7d20\u552f\u4e00\u7684\u5e8f\u5217\uff0c\u6240\u4ee5\u96c6\u5408\u7684\u672c\u8d28\u662f\u8bb8\u591a\u552f\u4e00\u5bf9\u8c61\u7684\u805a\u96c6\u3002 \u548c\u5b57\u5178\u7c7b\u4f3c\uff0c\u96c6\u5408\u7684\u5143\u7d20\u662f\u4e0d\u53ef\u53d8\u7684\u3002\u53ef\u4ee5\u8ba4\u4e3a\u96c6\u5408\u4e5f\u50cf\u5b57\u5178\uff0c\u4f46\u662f\u53ea\u6709\u952e\u6ca1\u6709\u503c\u3002\u57fa\u672c\u529f\u80fd\u662f\u8fdb\u884c\u6210\u5458\u5173\u7cfb\u6d4b\u8bd5\u548c\u5220\u9664\u91cd\u590d\u5143\u7d20\u3002\u6240\u4ee5\u96c6\u5408\u53e6\u4e00\u4e2a\u7528\u9014\u662f\u53bb\u91cd\u590d\u3002 \u96c6\u5408\u4e2d\u7684\u5143\u7d20\u5fc5\u987b\u662f\u53ef\u6563\u5217\u7684\uff0cset\u7c7b\u578b\u672c\u8eab\u662f\u4e0d\u53ef\u6563\u5217\u7684\uff0c\u4f46\u662ffrozenset\u53ef\u4ee5\u3002\u56e0\u6b64\u53ef\u4ee5\u521b\u5efa\u4e00\u4e2a\u5305\u542b\u4e0d\u540cfrozenset\u7684set\u3002 \u96c6\u5408\u53ef\u4ee5\u6709\u4e24\u79cd\u521b\u5efa\u65b9\u5f0f\uff1a\u901a\u8fc7set()\u51fd\u6570\u6216\u8005{}\u6765\u521b\u5efa\uff08\u7528\u5927\u62ec\u53f7\u62ec\u4f4f\u7684\u5185\u5bb9\uff0cPython3\u81ea\u52a8\u5b9a\u4e49\u4e3a\u96c6\u5408\uff09\u3002 \u96c6\u5408\u4e0d\u5c5e\u4e8e\u5e8f\u5217\u7c7b\u6570\u636e\uff0c \u96c6\u5408\u4e0d\u652f\u6301\u901a\u8fc7\u7d22\u5f15\u8bbf\u95ee\u6307\u5b9a\u5143\u7d20\uff0c\u4f46\u53ef\u4ee5\u589e\u52a0\u548c\u5220\u9664\u5143\u7d20\u3002 \u9762\u7684\u4f8b\u5b50\u662f\u6c42 haystacke \u548c needles \u4e24\u4e2a\u96c6\u5408\u7684\u4ea4\u96c6\u5143\u7d20\u4e2a\u6570\u3002 haystacke = { 'a' , 'b' , 'c' , 'd' , 'e' , 'f' , 'g' , 'h' , 'f' , 'g' , 'h' , 'c' , 'd' , 'e' , 'c' , 'd' , 'e' , 'f' , 'g' , 'h' } needles = { 'c' , 'h' , 'w' } type ( haystacke ) # type ( needles ) # # \u4f20\u7edf\u65b9\u6cd5 found = 0 for i in needles : if i in haystacke : found += 1 print ( found ) # 2 # \u96c6\u5408\u65b9\u6cd5\u4e00 found = len ( needles & haystacke ) print ( found ) # 2 # \u96c6\u5408\u65b9\u6cd5\u4e8c found = len ( needles . intersection ( haystacke )) print ( found ) # 2 \u96c6\u5408\u5b9e\u73b0\u4e86\u5f88\u591a\u57fa\u7840\u7684\u4e2d\u7f00\u8fd0\u7b97\u7b26\uff0c\u6bd4\u5982\uff0c\u96c6\u5408\u652f\u6301\u6570\u5b66\u4e0a\u7684\u96c6\u5408\u64cd\u4f5c\uff1a\u5e76\u96c6\u3001\u4ea4\u96c6\u3001\u5dee\u96c6\u3001\u5bf9\u79f0\u5dee\u96c6\u3002 \u65b9\u6cd5\u540d\u79f0 \u8bf4\u660e add() \u4e3a\u96c6\u5408\u6dfb\u52a0\u5143\u7d20 update() \u7ed9\u96c6\u5408\u6dfb\u52a0\u5143\u7d20 clear() \u79fb\u9664\u96c6\u5408\u4e2d\u7684\u6240\u6709\u5143\u7d20 copy() \u62f7\u8d1d\u4e00\u4e2a\u96c6\u5408 remove() \u79fb\u9664\u6307\u5b9a\u5143\u7d20 pop() \u968f\u673a\u79fb\u9664\u5143\u7d20 discard() \u5220\u9664\u96c6\u5408\u4e2d\u6307\u5b9a\u7684\u5143\u7d20 < \u6216\u8005issubset() \u5224\u65ad\u6307\u5b9a\u96c6\u5408\u662f\u5426\u4e3a\u8be5\u65b9\u6cd5\u53c2\u6570\u96c6\u5408\u7684\u5b50\u96c6 | \u6216\u8005union() \u8fd4\u56de\u4e24\u4e2a\u96c6\u5408\u7684\u5e76\u96c6 & \u6216\u8005intersection() \u8fd4\u56de\u96c6\u5408\u7684\u4ea4\u96c6 intersection_update() \u8fd4\u56de\u96c6\u5408\u7684\u4ea4\u96c6 - \u6216\u8005difference() \u8fd4\u56de\u591a\u4e2a\u96c6\u5408\u7684\u5dee\u96c6 difference_update() \u79fb\u9664\u96c6\u5408\u4e2d\u7684\u5143\u7d20\uff0c\u8be5\u5143\u7d20\u5728\u6307\u5b9a\u7684\u96c6\u5408\u4e5f\u5b58\u5728 ^ \u6216\u8005symmetric_difference() \u8fd4\u56de\u4e24\u4e2a\u96c6\u5408\u4e2d\u4e0d\u91cd\u590d\u7684\u5143\u7d20\u96c6\u5408(\u4e24\u96c6\u5408\u9664\u53bb\u4ea4\u96c6\u90e8\u5206\u7684\u5143\u7d20) symmetric_difference_update() \u79fb\u9664\u5f53\u524d\u96c6\u5408\u4e2d\u5728\u53e6\u5916\u4e00\u4e2a\u6307\u5b9a\u96c6\u5408\u76f8\u540c\u7684\u5143\u7d20\uff0c\u5e76\u5c06\u53e6\u5916\u4e00\u4e2a\u6307\u5b9a\u96c6\u5408\u4e2d\u4e0d\u540c\u7684\u5143\u7d20\u63d2\u5165\u5230\u5f53\u524d\u96c6\u5408\u4e2d isdisjoint() \u5224\u65ad\u4e24\u4e2a\u96c6\u5408\u662f\u5426\u5305\u542b\u76f8\u540c\u7684\u5143\u7d20\uff0c\u5982\u679c\u6ca1\u6709\u8fd4\u56de True\uff0c\u5426\u5219\u8fd4\u56de False issuperset() \u5224\u65ad\u8be5\u65b9\u6cd5\u7684\u53c2\u6570\u96c6\u5408\u662f\u5426\u4e3a\u6307\u5b9a\u96c6\u5408\u7684\u5b50\u96c6 \u4e3e\u4f8b\uff1a a = { 'a' , 'b' , 'c' , 1 , 2 } b = { 1 , 'c' , 'd' } \u5e76\u96c6(a\u548cb\u4e2d\u7684\u6240\u6709\u4e0d\u540c\u5143\u7d20)\u3002 print ( a . union ( b )) # {'c', 1, 2, 'd', 'a', 'b'} print ( a | b ) # {'c', 1, 2, 'd', 'a', 'b'} \u4ea4\u96c6(a\u3001b\u4e2d\u540c\u65f6\u5305\u542b\u7684\u5143\u7d20)\u3002 print ( a . intersection ( b )) # {'c', 1} print ( a & b ) # {'c', 1} \u5c06a\u7684\u5185\u5bb9\u8bbe\u7f6e\u4e3aa\u548cb\u7684\u4ea4\u96c6\u3002 a = { 'a' , 'b' , 'c' , 1 , 2 } b = { 1 , 'c' , 'd' } a . intersection_update ( b ) print ( a ) # {1, 'c'} \u5728a\u4e0d\u5728b\u7684\u5143\u7d20\u3002 print ( a . difference ( b )) # {'a', 2, 'b'} print ( a - b ) # {2, 'a', 'b'} \u5c06a\u7684\u5185\u5bb9\u8bbe\u4e3a\u5728a\u4e0d\u5728b\u7684\u5143\u7d20\u3002 a = { 'a' , 'b' , 'c' , 1 , 2 } b = { 1 , 'c' , 'd' } a . difference_update ( b ) print ( a ) # {2, 'b', 'a'} a = { 'a' , 'b' , 'c' , 1 , 2 } b = { 1 , 'c' , 'd' } a -= b print ( a ) # {2, 'a', 'b'} \u5c06\u5143\u7d20\u52a0\u5165\u96c6\u5408a\u3002 a . add ( 7 ) print ( a ) # {1, 2, 'c', 7, 'a', 'b'} \u6bcf\u6b21\u8f93\u51fa\u7684\u987a\u5e8f\u662f\u4e0d\u4e00\u6837\u7684 \u4ece\u96c6\u5408a\u79fb\u9664\u67d0\u4e2a\u5143\u7d20\u3002 a . remove ( 7 ) print ( a ) # {1, 2, 'c', 'a', 'b'} \u5982\u679ca\u88ab\u6e05\u7a7a\uff0c\u5219\u62a5\u9519 KeyError: 7 \u6240\u6709\u5728a\u6216b\u4e2d\uff0c\u4f46\u4e0d\u662f\u540c\u65f6\u5728a\u3001b\u4e2d\u7684\u5143\u7d20\u3002 print ( a . symmetric_difference ( b )) # {2, 'd', 'b', 'a'} print ( a ^ b ) # {2, 'd', 'b', 'a'} \u5c06a\u7684\u5185\u5bb9\u8bbe\u4e3a\u6240\u6709\u5728a\u6216b\u4e2d\uff0c\u4f46\u4e0d\u662f\u540c\u65f6\u5728a\u3001b\u4e2d\u7684\u5143\u7d20\u3002 a = { 'a' , 'b' , 'c' , 1 , 2 } b = { 1 , 'c' , 'd' } a . symmetric_difference_update ( b ) print ( a ) # {'a', 2, 'd', 'b'} a = { 'a' , 'b' , 'c' , 1 , 2 } b = { 1 , 'c' , 'd' } a ^= b print ( a ) # {2, 'd', 'a', 'b'} \u5982\u679ca\u5305\u542b\u4e8eb\uff0c\u8fd4\u56deTure\u3002 print ( a . issubset ( b )) # False \u5c06a\u7684\u5185\u5bb9\u8bbe\u7f6e\u4e3aa\u548cb\u7684\u5e76\u96c6\u3002 print ( a ) # {'a', 2, 'd', 'b'} a = { 'a' , 'b' , 'c' , 1 , 2 } a . update ( b ) print ( a ) # {1, 2, 'a', 'b', 'd', 'c'} \u79fb\u9664\u4efb\u610f\u5143\u7d20\uff0c\u5982\u679c\u96c6\u5408\u662f\u7a7a\u7684\uff0c\u629b\u51fakeyError\u3002 a . pop () # \u968f\u673a\u79fb\u9664\u67d0\u4e2a\u5143\u7d20\uff0c\u6ca1\u6709\u8f93\u5165\u53d8\u91cf\uff0c\u5982\u679c\u96c6\u5408\u662f\u7a7a\u7684\uff0c\u629b\u51faKeyError: 'pop from an empty set' print ( a ) # {2, 1, 'd', 'b', 'a'} \u5c06\u96c6\u5408\u91cd\u7f6e\u4e3a\u7a7a\uff0c\u6e05\u7a7a\u6240\u6709\u5143\u7d20\u3002 a . clear () print ( a ) # set() \u96c6\u5408\u7684\u5143\u7d20\u5fc5\u987b\u662f\u4e0d\u53ef\u53d8\u7684\uff0c\u5982\u679c\u60f3\u8981\u5305\u542b\u5217\u8868\u578b\u7684\u5143\u7d20\uff0c\u5fc5\u987b\u5148\u8f6c\u6362\u4e3a\u5143\u7ec4\u3002 my_data1 = [ 1 , 2 , 3 , 4 ] my_data2 = [ 3 , 4 , 5 , 6 ] my_set = { tuple ( my_data1 ), tuple ( my_data2 )} print ( my_set ) # {(1, 2, 3, 4), (3, 4, 5, 6)}","title":"1.5 \u96c6\u5408\uff08set\uff09"},{"location":"python/Foundation/ch01/#16-tuple","text":"Python \u7684\u5143\u7ec4\u4e0e\u5217\u8868\u7c7b\u4f3c\uff0c\u4e0d\u540c\u4e4b\u5904\u5728\u4e8e\u5143\u7ec4\u7684\u5143\u7d20\u4e0d\u80fd\u4fee\u6539\u3002 \u5143\u7ec4\u4f7f\u7528\u5c0f\u62ec\u53f7( )\uff0c\u5217\u8868\u4f7f\u7528\u65b9\u62ec\u53f7[ ]\u3002 \u5143\u7ec4\u4e2d\u53ea\u5305\u542b\u4e00\u4e2a\u5143\u7d20\u65f6\uff0c\u9700\u8981\u5728\u5143\u7d20\u540e\u9762\u6dfb\u52a0\u9017\u53f7 \uff0c\u5426\u5219\u62ec\u53f7\u4f1a\u88ab\u5f53\u4f5c\u8fd0\u7b97\u7b26\u4f7f\u7528\u3002 \u5143\u7ec4\u53ef\u4ee5\u4f7f\u7528\u4e0b\u6807\u7d22\u5f15\u6765\u8bbf\u95ee\u5143\u7ec4\u4e2d\u7684\u503c\u3002 \u5143\u7ec4\u4e2d\u7684\u5143\u7d20\u503c\u662f\u4e0d\u5141\u8bb8\u4fee\u6539\u7684\uff0c\u4f46\u6211\u4eec\u53ef\u4ee5\u5bf9\u5143\u7ec4\u8fdb\u884c\u8fde\u63a5\u7ec4\u5408\u3002 \u5143\u7ec4\u4e2d\u7684\u5143\u7d20\u503c\u662f\u4e0d\u5141\u8bb8\u5220\u9664\u7684\uff0c\u4f46\u6211\u4eec\u53ef\u4ee5\u4f7f\u7528del\u8bed\u53e5\u6765\u5220\u9664\u6574\u4e2a\u5143\u7ec4\u3002 # \u6b64\u5904\u62ec\u53f7\u88ab\u89e3\u6790\u4e3a\u8fd0\u7b97\u7b26\uff0c\u9700\u8981\u5728\u540e\u9762\u52a0\u4e0a\u9017\u53f7\u624d\u4f1a\u88ab\u89e3\u91ca\u4e3a\u5143\u7ec4 tup1 = ( 10 ) print ( type ( tup1 )) # tup1 = ( 10 ,) print ( type ( tup1 )) # \u521b\u5efa\u5143\u7ec4\u6700\u7b80\u5355\u7684\u529e\u6cd5\u5c31\u662f\u7528\u9017\u53f7\u5206\u9694\u5e8f\u5217\u503c\u3002\u5143\u7ec4\u5bf9\u6570\u636e\u7c7b\u578b\u6ca1\u6709\u4e00\u81f4\u6027\u8981\u6c42\u3002 tup = 4 , 5 , 6 print ( tup ) # (4, 5, 6) nested_tup = ( 4 , 5 , 6 ), ( 7 , 8 ) print ( nested_tup ) # # ((4, 5, 6), (7, 8)) tup = ( 'a' , 'b' , { 'one' : 1 }) print ( type ( tup )) # \u4f7f\u7528\u52a0\u53f7\uff08+\uff09\u8fdb\u884c\u5143\u7ec4\u8fde\u63a5\u5408\u5e76\u3002 tup = tuple (( 4 , None , 'fool' ) + ( 6 , 0 ) + ( 'bar' ,)) print ( tup ) # (4, None, 'fool', 6, 0, 'bar') \u5143\u7ec4\u7684\u4e0d\u53ef\u53d8\u6307\u7684\u662f**\u5143\u7ec4\u6240\u6307\u5411\u7684\u5185\u5b58\u4e2d\u7684\u5185\u5bb9\u4e0d\u53ef\u53d8**\u3002 tup = ( 'h' , 'e' , 'l' , 'l' , 'o' ) print ( id ( tup )) # 139820353350208 tup = ( 1 , 2 , 3 , 4 , 5 ) print ( id ( tup )) # 139820353298896 tup [ 0 ] = 'x' # Traceback (most recent call last): # File \"\", line 1, in # TypeError: 'tuple' object does not support item assignment \u5c06\u5143\u7ec4\u4e58\u4ee5\u6574\u6570\uff0c\u5219\u4f1a\u548c\u5217\u8868\u4e00\u6837\uff0c\u751f\u6210\u542b\u6709\u591a\u4efd\u62f7\u8d1d\u7684\u5143\u7ec4\u3002\u5bf9\u8c61\u81ea\u8eab\u5e76\u6ca1\u6709\u590d\u5236\uff0c\u53ea\u662f\u6307\u5411\u5b83\u4eec\u7684\u5f15\u7528\u8fdb\u884c\u4e86\u590d\u5236\u3002 tup = tuple (( 'fool' , 'bar' ) * 4 ) print ( tup ) # ('fool', 'bar', 'fool', 'bar', 'fool', 'bar', 'fool', 'bar') \u5982\u679c\u5143\u7ec4\u4e2d\u7684\u4e00\u4e2a\u5bf9\u8c61\u662f\u53ef\u53d8\u7684\uff0c\u4f8b\u5982\u5217\u8868\uff0c\u4f60\u53ef\u4ee5\u5728\u5b83\u5185\u90e8\u8fdb\u884c\u4fee\u6539\u3002 tup = tuple ([ 'foo' , [ 4 , 5 , 6 ], True ]) tup [ 1 ] . append ( 0 ) print ( tup ) # ('foo', [4, 5, 6, 0], True) tup [ 1 ] . append ([ 9 ]) print ( tup ) # ('foo', [4, 5, 6, 0, [9]], True) \u4f7f\u7528tuple\u51fd\u6570\u5c06\u4efb\u610f\u5e8f\u5217\u6216\u8fed\u4ee3\u5668\u8f6c\u6362\u4e3a\u5143\u7ec4\u3002 tup = tuple ([ 4 , 5 , 6 ]) print ( tup ) # (4, 5, 6) tup = tuple ( 'string' ) print ( tup ) # ('s', 't', 'r', 'i', 'n', 'g') print ( tup [ 2 ]) # r # \u5143\u7ec4\u7684\u5143\u7d20\u53ef\u4ee5\u901a\u8fc7\u4e2d\u62ec\u53f7[]\u6765\u83b7\u53d6 \u5982\u679c\u8981\u5c06\u5143\u7ec4\u578b\u7684\u8868\u8fbe\u5f0f\u8d4b\u503c\u7ed9\u53d8\u91cf\uff0cPython\u4f1a\u5bf9\u7b49\u53f7\u53f3\u8fb9\u7684\u503c\u8fdb\u884c \u62c6\u5305 \u3002 tup = ( 9 , 5 , ( 8 , 7 )) a , b , c = tup print ( a ) # 9 print ( b ) # 5 print ( c ) # (8, 7) a , b , ( c , d ) = tup print ( a ) # 9 print ( b ) # 5 print ( c ) # 8 print ( d ) # 7 tup = ( 9 , 5 , ( 8 , 7 )) a , b , c = tup c , a = a , c # \u5229\u7528\u62c6\u5305\u5b9e\u73b0\u4ea4\u6362 print ( a ) # (8, 7) print ( b ) # 5 print ( c ) # 9 \u5229\u7528\u62c6\u5305\u5b9e\u73b0\u904d\u5386\u5143\u7ec4\u6216\u5217\u8868\u7ec4\u6210\u7684\u5e8f\u5217\u3002 seq = [( 1 , 2 , 3 ), ( 4 , 5 , 6 ), ( 7 , 8 , 9 )] for a , b , c in seq : print ( 'a= {0} , b= {0} , c= {0} ' . format ( a , b , c )) # \u5217\u8868\u6bcf\u4e2a\u5143\u7d20\u7684\u53d6\u503c\u987a\u5e8f # a=1, b=1, c=1 # a=4, b=4, c=4 # a=7, b=7, c=7 print ( 'a= {0} , b= {1} , c= {2} ' . format ( a , b , c )) # a=1, b=2, c=3 # a=4, b=5, c=6 # a=7, b=8, c=9 print ( 'a= {2} , b= {0} , c= {1} ' . format ( a , b , c )) # a=3, b=1, c=2 # a=6, b=4, c=5 # a=9, b=7, c=8 \u5143\u7ec4\u62c6\u5305\u529f\u80fd\u8fd8\u5305\u62ec\u7279\u6b8a\u7684\u8bed\u6cd5*rest\u3002\u5f88\u591aPython\u7f16\u7a0b\u8005\u4f1a\u4f7f\u7528\u4e0b\u5212\u7ebf\uff08_\uff09\u6765\u8868\u793a\u4e0d\u60f3\u8981\u7684\u53d8\u91cf\u3002 values = 1 , 2 , 3 , 4 , 5 a , b , * rest = values print ( a ) # 1 print ( b ) # 2 print ( * rest ) # 3 4 5 a , b , * _ = values print ( * _ ) # 3 4 5 \u5177\u540d\u5143\u7ec4\u3002 collections.namedtuple \u662f\u4e00\u4e2a\u5de5\u5382\u51fd\u6570\uff0c\u5b83\u53ef\u4ee5\u7528\u6765\u6784\u5efa\u4e00\u4e2a\u5e26\u5b57\u6bb5\u540d\u7684\u5143\u7ec4\u548c\u4e00\u4e2a\u6709\u540d\u5b57\u7684\u7c7b\u3002 \u7528namedtuple\u6784\u5efa\u7684\u7c7b\u7684\u5b9e\u4f8b\u6240\u6d88\u8017\u7684\u5185\u5b58\u8ddf\u5143\u7ec4\u662f\u4e00\u6837\u7684\uff0c\u56e0\u4e3a\u5b57\u6bb5\u540d\u90fd\u88ab\u5b58\u5728\u5bf9\u5e94\u7684\u7c7b\u91cc\u9762\u3002 \u521b\u5efa\u4e00\u4e2a\u5177\u540d\u5143\u7ec4\u9700\u8981\u4e24\u4e2a\u53c2\u6570\uff0c\u4e00\u4e2a\u662f\u7c7b\u540d( City )\uff0c\u53e6\u4e00\u4e2a\u662f\u7c7b\u7684\u5404\u4e2a\u5b57\u6bb5\u7684\u540d\u5b57( 'name country population coordinates' )\u3002\u540e\u8005\u53ef\u4ee5\u662f\u7531\u6570\u4e2a\u5b57\u7b26\u4e32\u7ec4\u6210\u7684\u53ef\u8fed\u4ee3\u5bf9\u8c61\uff0c\u6216\u8005\u662f\u7531\u7a7a\u683c\u5206\u9694\u5f00\u7684\u5b57\u6bb5\u540d\u7ec4\u6210\u7684\u5b57\u7b26\u4e32\u3002 \u5b58\u653e\u5728\u5bf9\u5e94\u5b57\u6bb5\u91cc\u7684\u6570\u636e\u8981\u4ee5\u4e00\u4e32\u53c2\u6570\u7684\u5f62\u5f0f\u4f20\u5165\u5230\u6784\u9020\u51fd\u6570\u4e2d\uff08\u6ce8\u610f\uff0c\u5143\u7ec4\u7684\u6784\u9020\u51fd\u6570\u5374\u53ea\u63a5\u53d7\u5355\u4e00\u7684\u53ef\u8fed\u4ee3\u5bf9\u8c61\uff09\u3002 \u5177\u540d\u5143\u7ec4\u8fd8\u6709\u4e00\u4e9b\u81ea\u5df1\u4e13\u6709\u7684\u5c5e\u6027\u3002\u4e0b\u9762\u5c55\u793a\u4e86\u51e0\u4e2a\u6700\u6709\u7528\u7684\uff1a _fields \u7c7b\u5c5e\u6027\u3001\u7c7b\u65b9\u6cd5 _make(iterable) \u548c\u5b9e\u4f8b\u65b9\u6cd5 _asdict() \u3002 _fields \u5c5e\u6027\u662f\u4e00\u4e2a\u5305\u542b\u8fd9\u4e2a\u7c7b\u6240\u6709\u5b57\u6bb5\u540d\u79f0\u7684\u5143\u7ec4\u3002 \u7528 _make() \u901a\u8fc7\u63a5\u53d7\u4e00\u4e2a\u53ef\u8fed\u4ee3\u5bf9\u8c61\u6765\u751f\u6210\u8fd9\u4e2a\u7c7b\u7684\u4e00\u4e2a\u5b9e\u4f8b\uff0c\u5b83\u7684\u4f5c\u7528\u8ddf City(*delhi_data) \u662f\u4e00\u6837\u7684\u3002 _asdict() \u628a\u5177\u540d\u5143\u7ec4\u4ee5 collections.OrderedDict \u7684\u5f62\u5f0f\u8fd4\u56de\uff0c\u6211\u4eec\u53ef\u4ee5\u5229\u7528\u5b83\u6765\u628a\u5143\u7ec4\u91cc\u7684\u4fe1\u606f\u53cb\u597d\u5730\u5448\u73b0\u51fa\u6765\u3002 from collections import namedtuple City = namedtuple ( 'City' , 'name country population coordinates' ) tokyo = City ( 'Tokyo' , 'JP' , 36.933 , ( 35.689722 , 139691667 )) print ( tokyo ) # City(name='Tokyo', country='JP', population=36.933, coordinates=(35.689722, 139691667)) print ( tokyo . population ) # 36.933 print ( tokyo [ 3 ]) # (35.689722, 139691667) print ( City . _fields ) # ('name', 'country', 'population', 'coordinates') LatLong = namedtuple ( 'LatLong' , 'lat long' ) delhi_data = ( 'Delhi NCR' , 'IN' , 21.935 , LatLong ( 28.613899 , 77.208889 )) delhi = City . _make ( delhi_data ) print ( delhi ) # City(name='Delhi NCR', country='IN', population=21.935, coordinates=LatLong(lat=28.613899, long=77.208889)) print ( delhi . _asdict ()) # OrderedDict([('name', 'Delhi NCR'), ('country', 'IN'), ('population', 21.935), ('coordinates', LatLong(lat=28.613899, long=77.208889))]) for key , value in delhi . _asdict () . items (): print ( key + ':' , value ) # name: Delhi NCR # country: IN # population: 21.935 # coordinates: LatLong(lat=28.613899, long=77.208889) \u5143\u7ec4\u8fd8\u6709\u7b2c\u4e8c\u91cd\u529f\u80fd\uff1a\u4f5c\u4e3a\u4e0d\u53ef\u53d8\u5217\u8868\u7684\u5143\u7ec4\u3002 \u4e0b\u9762\u662f\u5217\u8868\u6216\u5143\u7ec4\u7684\u65b9\u6cd5\u548c\u5c5e\u6027\u5bf9\u6bd4\u3002\u9664\u4e86\u8ddf\u589e\u51cf\u5143\u7d20\u76f8\u5173\u7684\u65b9\u6cd5\u4e4b\u5916\uff0c\u5143\u7ec4\u652f\u6301\u5217\u8868\u7684\u5176\u4ed6\u6240\u6709\u65b9\u6cd5\u3002\u8fd8\u6709\u4e00\u4e2a\u4f8b\u5916\uff0c\u5143\u7ec4\u6ca1\u6709__reversed__\u65b9\u6cd5\u3002 \u4e00\u4e2a\u5173\u4e8e+=\u548c*=\u7684\u8c1c\u9898\u3002 \u4e0b\u9762\u7684\u4f8b\u5b50\u5c55\u793a\u4e86 *= \u5728\u53ef\u53d8\u548c\u4e0d\u53ef\u53d8\u5e8f\u5217\u4e0a\u7684\u4f5c\u7528\u3002\u5217\u8868\u7684ID\u6ca1\u53d8\uff0c\u65b0\u5143\u7d20\u8ffd\u52a0\u5230\u5217\u8868\u4e0a\uff0c\u4f46\u6267\u884c\u589e\u91cf\u4e58\u6cd5\u540e\uff0c\u65b0\u7684\u5143\u7ec4\u88ab\u521b\u5efa\u3002 list1 = [ 1 , 2 , 3 , 4 ] id ( list1 ) # 140409777308808 list1 *= 2 print ( list1 ) # [1, 2, 3, 4, 1, 2, 3, 4] id ( list1 ) # 140409777308808 tuple1 = ( 1 , 2 , 3 , 4 ) id ( tuple1 ) # 140409777230536 tuple1 *= 2 print ( tuple1 ) # (1, 2, 3, 4, 1, 2, 3, 4) id ( tuple1 ) # 140409780104888 \u4f46\u5bf9\u4e8e\u4e0b\u9762\u7684\u4f8b\u5b50\uff0c\u867d\u7136 tuple1[2] += [50, 60] \u6267\u884c\u65f6\u6709\u5f02\u5e38\u629b\u51fa\uff0c\u4f46 tuple1 \u5374\u88ab\u4fee\u6539\u4e86\u3002 t = ( 1 , 2 , [ 10 , 20 ]) t [ 2 ] += [ 50 , 60 ] # TypeError: 'tuple' object does not support item assignment print ( t ) # (1, 2, [10, 20, 50, 60]) \u4e0b\u56fe\u5927\u81f4\u63cf\u8ff0\u4e86\u4e0a\u8ff0\u6267\u884c\u8fc7\u7a0b\u3002 \u4e3a\u4e86\u907f\u514d\u4e0a\u9762\u60c5\u51b5\u7684\u53d1\u751f\uff0c\u6211\u4eec**\u4e0d\u8981\u628a\u53ef\u53d8\u5bf9\u8c61\u653e\u5728\u5143\u7ec4\u91cc\u9762**\u3002\u589e\u91cf\u8d4b\u503c\u4e0d\u662f\u4e00\u4e2a\u539f\u5b50\u64cd\u4f5c\uff0c\u5b83\u867d\u7136\u629b\u51fa\u4e86\u5f02\u5e38\uff0c\u4f46\u8fd8\u662f\u5b8c\u6210\u4e86\u64cd\u4f5c\u3002","title":"1.6 \u5143\u7ec4\uff08tuple\uff09"},{"location":"python/Foundation/ch01/#17-memoryview","text":"memoryview \u662f\u4e00\u4e2a\u5185\u7f6e\u7c7b\uff0c\u5b83\u80fd\u8ba9\u7528\u6237\u5728\u4e0d\u590d\u5236\u5185\u5bb9\u7684\u60c5\u51b5\u4e0b\u64cd\u4f5c\u540c\u4e00\u4e2a\u6570\u7ec4\u7684\u4e0d\u540c\u5207\u7247\u3002 \u5185\u5b58\u89c6\u56fe\u5176\u5b9e\u662f\u6cdb\u5316\u548c\u53bb\u6570\u5b66\u5316\u7684NumPy\u6570\u7ec4\u3002\u5b83\u8ba9\u4f60\u5728\u4e0d\u9700\u8981\u590d\u5236\u5185\u5bb9\u7684\u524d\u63d0\u4e0b\uff0c\u5728\u6570\u636e\u7ed3\u6784\u4e4b\u95f4\u5171\u4eab\u5185\u5b58\u3002 \u5176\u4e2d\u6570\u636e\u7ed3\u6784\u53ef\u4ee5\u662f\u4efb\u4f55\u5f62\u5f0f\uff0c\u6bd4\u5982PIL\u56fe\u7247\u3001SQLite\u6570\u636e\u5e93\u548cNumPy\u7684\u6570\u7ec4\uff0c\u7b49\u7b49\u3002\u8fd9\u4e2a\u529f\u80fd\u5728\u5904\u7406\u5927\u578b\u6570\u636e\u96c6\u5408\u7684\u65f6\u5019\u975e\u5e38\u91cd\u8981\u3002 memoryview.cast \u7684\u6982\u5ff5\u8ddf\u6570\u7ec4\u6a21\u5757\u7c7b\u4f3c\uff0c\u80fd\u7528\u4e0d\u540c\u7684\u65b9\u5f0f\u8bfb\u5199\u540c\u4e00\u5757\u5185\u5b58\u6570\u636e\uff0c\u800c\u4e14\u5185\u5bb9\u5b57\u8282\u4e0d\u4f1a\u968f\u610f\u79fb\u52a8\u3002\u8fd9\u8ddfC\u8bed\u8a00\u4e2d\u7c7b\u578b\u8f6c\u6362\u7684\u6982\u5ff5\u5dee\u4e0d\u591a\u3002 memoryview.cast \u4f1a\u628a\u540c\u4e00\u5757\u5185\u5b58\u91cc\u7684\u5185\u5bb9\u6253\u5305\u6210\u4e00\u4e2a\u5168\u65b0\u7684memoryview\u5bf9\u8c61\u7ed9\u4f60\u3002 array \u91cc\u9762\u7684Type code\uff1a 'b' signed integer 1 'B' unsigned integer 1 'u' Unicode character 2 (see note) 'h' signed integer 2 'H' unsigned integer 2 'i' signed integer 2 'I' unsigned integer 2 'l' signed integer 4 'L' unsigned integer 4 'q' signed integer 8 (see note) 'Q' unsigned integer 8 (see note) 'f' floating point 4 'd' floating point 8 numbers = array ( 'h' , [ - 2 , - 1 , 0 , 1 , 2 ]) # array('h', [-2, -1, 0, 1, 2]) # \u75285\u4e2a\u77ed\u6574\u578b\u6709\u7b26\u53f7\u6574\u6570\u7684\u6570\u7ec4\uff08\u7c7b\u578b\u7801\u662f'h'\uff09\u521b\u5efa\u4e00\u4e2amemoryview\u3002 memv = memoryview ( numbers ) # memv\u91cc\u76845\u4e2a\u5143\u7d20\u8ddf\u6570\u7ec4\u91cc\u7684\u6ca1\u6709\u533a\u522b\u3002 print ( len ( memv )) # 5 print ( memv [ 0 ]) # -2 print ( memv . tolist ()) # [-2, -1, 0, 1, 2] # \u521b\u5efa\u4e00\u4e2amemv_oct\uff0c\u8fd9\u4e00\u6b21\u662f\u628amemv\u91cc\u7684\u5185\u5bb9\u8f6c\u6362\u6210'B'\u7c7b\u578b\uff0c\u4e5f\u5c31\u662f\u65e0\u7b26\u53f7\u5b57\u7b26\u3002 memv_oct = memv . cast ( 'B' ) print ( memv_oct . tolist ()) # [254, 255, 255, 255, 0, 0, 1, 0, 2, 0] # \u628a\u4f4d\u4e8e\u4f4d\u7f6e5\u7684\u5b57\u8282\u8d4b\u503c\u62104\u3002\u56e0\u4e3a\u6211\u4eec\u628a\u53602\u4e2a\u5b57\u8282\u7684\u6574\u6570\u7684\u9ad8\u4f4d\u5b57\u8282\u6539\u6210\u4e864\uff0c\u6240\u4ee5\u8fd9\u4e2a\u6709\u7b26\u53f7\u6574\u6570\u7684\u503c\u5c31\u53d8\u6210\u4e861024\u3002 memv_oct [ 5 ] = 4 print ( numbers ) # array('h', [-2, -1, 1024, 1, 2])","title":"1.7 \u5185\u5b58\u89c6\u56feMemoryview"},{"location":"python/Foundation/ch01/#2","text":"\u661f\u53f7 * \u7684\u53c2\u6570\u4f1a\u4ee5\u5143\u7ec4(tuple)\u7684\u5f62\u5f0f\u5bfc\u5165\uff0c\u5b58\u653e\u6240\u6709\u672a\u547d\u540d\u7684\u53d8\u91cf\u53c2\u6570 def printinfo ( arg1 , * vartuple ): print ( \"\u8f93\u51fa\u4efb\u4f55\u4f20\u5165\u7684\u53c2\u6570: \" ) print ( arg1 ) print ( vartuple ) for var in vartuple : print ( var ) return printinfo ( 10 ) # 10 # () printinfo ( 70 , 60 , 50 ) # 70 # (60, 50) # 60 # 50 \u4e24\u4e2a\u661f\u53f7 ** \u7684\u53c2\u6570\u4f1a\u4ee5\u5b57\u5178\u7684\u5f62\u5f0f\u5bfc\u5165\u3002 def printinfo ( arg1 , ** vardict ): print ( \"\u8f93\u51fa\u4efb\u4f55\u4f20\u5165\u7684\u53c2\u6570: \" ) print ( arg1 ) print ( vardict ) printinfo ( 1 , a = 2 , b = 3 ) # 1 # {'a': 2, 'b': 3} \u5b57\u5178\u683c\u5f0f\u8f93\u51fa Python\u4e2d\u7684\u5bf9\u8c61\u5f15\u7528\u5e76\u4e0d\u6d89\u53ca\u7c7b\u578b\u3002\u53d8\u91cf\u5bf9\u4e8e\u5bf9\u8c61\u6765\u8bf4\u53ea\u662f\u7279\u5b9a\u547d\u540d\u7a7a\u95f4\u4e2d\u7684\u540d\u79f0\uff1b\u7c7b\u578b\u4fe1\u606f\u662f\u5b58\u50a8\u5728\u5bf9\u8c61\u81ea\u8eab\u4e4b\u4e2d\u3002 a = 5 print ( type ( a )) # a = 'foo' print ( type ( a )) # Python\u662f\u5f3a\u7c7b\u578b\u8bed\u8a00\uff0c\u6240\u6709\u7684\u5bf9\u8c61\u90fd\u62e5\u6709\u4e00\u4e2a\u6307\u5b9a\u7684\u7c7b\u578b\uff08\u6216\u7c7b\uff09\uff0c\u9690\u5f0f\u7684\u8f6c\u6362\u53ea\u5728\u67d0\u4e9b\u7279\u5b9a\u3001\u660e\u663e\u7684\u60c5\u51b5\u4e0b\u53d1\u751f\u3002 a = 4.5 b = 2 print ( 'a is {0} , b is {1} ' . format ( type ( a ), type ( b ))) # a is , b is \u5b57\u4e32\u683c\u5f0f\u5316\uff0c\u7528\u4e8e\u540e\u7eed\u8bbf\u95ee print ( a / b ) # 2.25 \u4f7f\u7528isinstance\u51fd\u6570\u6765\u68c0\u67e5\u4e00\u4e2a\u5bf9\u8c61\u662f\u5426\u662f\u7279\u5b9a\u7c7b\u578b\u7684\u5b9e\u4f8b\u3002isinstance\u63a5\u53d7\u4e00\u4e2a\u5305\u542b\u7c7b\u578b\u7684\u5143\u7ec4\uff0c\u53ef\u4ee5\u68c0\u67e5\u5bf9\u8c61\u7684\u7c7b\u578b\u662f\u5426\u5728\u5143\u7ec4\u4e2d\u7684\u7c7b\u578b\u4e2d\u3002 a = 5 b = 4.5 c = 'foo' print ( isinstance ( a , int )) # True print ( isinstance ( b , str )) # False print ( isinstance ( c , ( str , int ))) # True print ( isinstance ( c , ( float , int ))) # False \u5c5e\u6027\u548c\u65b9\u6cd5\u4e5f\u53ef\u4ee5\u901a\u8fc7getattr\u51fd\u6570\u83b7\u5f97\u3002\u5728\u5176\u4ed6\u7684\u8bed\u8a00\u4e2d\uff0c\u901a\u8fc7\u53d8\u91cf\u540d\u8bbf\u95ee\u5bf9\u8c61\u901a\u5e38\u88ab\u79f0\u4e3a\u201c\u53cd\u5c04\u201d\u3002 b = 'foo' print ( getattr ( b , 'split' )) # ","title":"2. \u52a8\u6001\u5f15\u7528\u3001\u5f3a\u7c7b\u578b"},{"location":"python/Foundation/ch01/#3","text":"\u68c0\u67e5\u4e24\u4e2a\u5f15\u7528\u662f\u5426\u6307\u5411\u540c\u4e00\u4e2a\u5bf9\u8c61\uff0c\u53ef\u4ee5\u4f7f\u7528is\u5173\u952e\u5b57\u3002 is\u548cis not\u7684\u5e38\u7528\u4e4b\u5904\u662f\u68c0\u67e5\u4e00\u4e2a\u53d8\u91cf\u662f\u5426\u4e3aNone\uff0c\u56e0\u4e3aNone\u53ea\u6709\u4e00\u4e2a\u5b9e\u4f8b\u3002 a = [ 1 , 2 , 3 ] b = a c = list ( a ) # list\u51fd\u6570\u603b\u662f\u521b\u5efa\u4e00\u4e2a\u65b0\u7684Python\u5217\u8868\uff08\u5373\u4e00\u4efd\u62f7\u8d1d\uff09 print ( a is b ) # True print ( a is not c ) # True print ( a == c ) # True d = None print ( d is None ) # True Python\u4e2d\u7684\u5927\u90e8\u5206\u5bf9\u8c61\uff0c\u4f8b\u5982\u5217\u8868\u3001\u5b57\u5178\u3001NumPy\u6570\u7ec4\u90fd\u662f\u53ef\u53d8\u5bf9\u8c61\uff0c\u5927\u591a\u6570\u7528\u6237\u5b9a\u4e49\u7684\u7c7b\u578b\uff08\u7c7b\uff09\u4e5f\u662f\u53ef\u53d8\u7684\u3002 \u53ef\u53d8\u5bf9\u8c61\u4e2d\u5305\u542b\u7684\u5bf9\u8c61\u548c\u503c\u662f\u53ef\u4ee5\u88ab\u4fee\u6539\u7684\u3002\u8fd8\u6709\u5176\u4ed6\u4e00\u4e9b\u5bf9\u8c61\u662f\u4e0d\u53ef\u53d8\u7684\uff0c\u6bd4\u5982\u5b57\u7b26\u4e32\u3001\u5143\u7ec4\u3002 a_list = [ 'foo' , 2 , [ 4 , 5 ]] # \u5217\u8868 a_list [ 2 ] = ( 3 , 4 ) print ( a_list ) # ['foo', 2, (3, 4)] a_tuple = ( 3 , 5 , ( 4 , 5 )) # \u5143\u7ec4 a_tuple [ 1 ] = 'four' # TypeError: 'tuple' object does not support item assignment \u4e0d\u53ef\u88ab\u4fee\u6539 print ( a_tuple ) # (3, 5, (4, 5))","title":"3. \u4e8c\u5143\u8fd0\u7b97\u7b26\u548c\u6bd4\u8f83\u8fd0\u7b97"},{"location":"python/Foundation/ch01/#4","text":"Python\u6807\u91cf\u7c7b\u578b\uff1aNone, str, bytes, float, bool, int\u3002 \u6570\u503c\u7c7b\u578b\u3002 \u57fa\u7840\u7684Python\u6570\u5b57\u7c7b\u578b\u5c31\u662fint\u548cfloat\u3002int\u53ef\u4ee5\u5b58\u50a8\u4efb\u610f\u5927\u5c0f\u6570\u5b57\u3002\u6d6e\u70b9\u6570\u5728Python\u4e2d\u7528float\u8868\u793a\uff0c\u6bcf\u4e00\u4e2a\u6d6e\u70b9\u6570\u90fd\u662f\u53cc\u7cbe\u5ea664\u4f4d\u6570\u503c\u3002 ival = 17338971 print ( ival ** 6 ) # 27173145946003847721495630081806010734757321 fval = 17338971.0 print ( fval ** 6 ) # 2.7173145946003847e+43 print ( 3 / 2 ) # 1.5 print ( 3 // 2 ) # 1 \u5b57\u7b26\u4e32\u3002 Python\u7684\u5b57\u7b26\u4e32\u662f\u4e0d\u53ef\u53d8\u7684\u3002 a = 5.6 s = str ( a ) print ( s ) # 5.6 b = 'python' print ( list ( b )) # ['p', 'y', 't', 'h', 'o', 'n'] print ( b [ 2 ]) # t b [ 2 ] = 'f' # TypeError: 'str' object does not support item assignment \u5b57\u7b26\u4e32\u662f\u4e0d\u53ef\u53d8\u7684 \u53cd\u659c\u6760\u7b26\u53f7\\\u662f\u4e00\u79cd\u8f6c\u4e49\u7b26\u53f7\uff0c\u5b83\u7528\u6765\u6307\u660e\u7279\u6b8a\u7b26\u53f7\u3002 \u5982\u679c\u4f60\u6709\u4e00\u4e2a\u4e0d\u542b\u7279\u6b8a\u7b26\u53f7\u4f46\u542b\u6709\u5927\u91cf\u53cd\u659c\u6760\u7684\u5b57\u7b26\u4e32\u65f6\uff0c\u53ef\u4ee5\u5728\u5b57\u7b26\u4e32\u524d\u9762\u52a0\u4e00\u4e2a\u524d\u7f00\u7b26\u53f7r\uff0c\u8868\u660e\u8fd9\u4e9b\u5b57\u7b26\u662f\u539f\u751f\u5b57\u7b26\uff0cr\u662fraw\u7684\u7b80\u5199\uff0c\u8868\u793a\u539f\u751f\u7684\u3002 x = '12 \\\\ 34' y = r 'this\\has\\no\\special\\characters' print ( x ) # 12\\34 print ( y ) # this\\has\\no\\special\\characters \u5b57\u7b26\u4e32\u683c\u5f0f\u5316 {0:.2f}\u8868\u793a\u5c06\u7b2c\u4e00\u4e2a\u53c2\u6570\u683c\u5f0f\u5316\u4e3a2\u4f4d\u5c0f\u6570\u7684\u6d6e\u70b9\u6570 {1:s}\u8868\u793a\u5c06\u7b2c\u4e8c\u4e2a\u53c2\u6570\u683c\u5f0f\u5316\u4e3a\u5b57\u7b26\u4e32 {2:d}\u8868\u793a\u5c06\u7b2c\u4e09\u4e2a\u53c2\u6570\u683c\u5f0f\u5316\u6574\u6570 \u53c2\u8003Python\u5b98\u65b9\u6587\u6863 https://docs.python.org/3.6/library/string.html template = ' {0:.2f} {1:s} are worth US$ {2:d} ' print ( template . format ( 4.5560 , 'Argentine Pesos' , 1 )) # 4.56 Argentine Pesos are worth US$1 \u65e5\u671f\u548c\u65f6\u95f4 from datetime import datetime , date , time dt = datetime ( 2011 , 10 , 29 , 20 , 30 , 21 ) print ( dt . day ) # 29 print ( dt . minute ) # 30 print ( dt . date ()) # 2011-10-29 print ( dt . time ()) # 20:30:21 print ( dt . replace ( minute = 0 , second = 0 )) # 2011-10-29 20:00:00 \u5c06\u5206\u949f\u3001\u79d2\u66ff\u6362\u4e3a0 print ( datetime . strptime ( '20091021' , '%Y%m %d ' )) # 2009-10-21 00:00:00 \u5b57\u7b26\u4e32\u53ef\u4ee5\u901a\u8fc7 strptime \u51fd\u6570\u8f6c\u6362\u4e3adatetime\u5bf9\u8c61 dt2 = datetime ( 2011 , 11 , 15 , 22 , 30 ) delta = dt2 - dt print ( delta ) # 17 days, 1:59:39 print ( dt + delta ) # 2011-11-15 22:30:00 range\u51fd\u6570\u8fd4\u56de\u4e00\u4e2a\u8fed\u4ee3\u5668\uff0c\u8be5\u8fed\u4ee3\u5668\u751f\u6210\u4e00\u4e2a\u7b49\u5dee\u6574\u6570\u5e8f\u5217\u3002 print ( range ( 10 )) # range(0, 10) print ( list ( range ( 10 ))) # [0, 1, 2, 3, 4, 5, 6, 7, 8, 9] print ( list ( range ( 0 , 20 , 2 ))) # [0, 2, 4, 6, 8, 10, 12, 14, 16, 18]","title":"4. \u6807\u91cf\u7c7b\u578b"},{"location":"python/Foundation/ch01/#5","text":"value = true-expr if condition else false-expr x = 5 print ( 'non-negative' if x >= 0 else 'negative' ) # non-negative","title":"5. \u4e09\u5143\u8868\u8fbe\u5f0f"},{"location":"python/Foundation/ch02/","text":"Python\u6253\u5305\u548c\u89e3\u5305 \u00b6 \u89e3\u5305Unpacking \u00b6 Python \u5141\u8bb8\u53d8\u91cf\u7684\u5143\u7ec4\uff08\u6216\u5217\u8868\uff09\u51fa\u73b0\u5728\u8d4b\u503c\u64cd\u4f5c\u7684\u5de6\u4fa7\u3002 \u5143\u7ec4\u4e2d\u7684\u6bcf\u4e2a\u53d8\u91cf\u90fd\u53ef\u4ee5\u4ece\u8d4b\u503c\u53f3\u4fa7\u7684\u53ef\u8fed\u4ee3\u5bf9\u8c61\uff08iterable\uff09\u4e2d\u63a5\u6536\u4e00\u4e2a\u503c\uff08\u6216\u8005\u66f4\u591a\uff0c\u5982\u679c\u6211\u4eec\u4f7f\u7528 * \u8fd0\u7b97\u7b26\uff09\u3002 Python \u4e2d\u7684\u89e3\u5305\u662f\u6307\u4e00\u79cd\u64cd\u4f5c\uff0c\u8be5\u64cd\u4f5c\u5305\u62ec\u5728\u5355\u4e2a\u8d4b\u503c\u8bed\u53e5\u4e2d\u5c06\u53ef\u8fed\u4ee3\u7684\u503c\u5206\u914d\u7ed9\u53d8\u91cf\u7684\u5143\u7ec4\uff08\u6216\u5217\u8868\uff09\u3002 \u5728 Python \u4e2d\uff0c\u53ef\u4ee5\u5728\u8d4b\u503c\u8fd0\u7b97\u7b26 = \u7684\u5de6\u4fa7\u653e\u7f6e\u4e00\u4e2a\u53d8\u91cf\u5143\u7ec4\uff0c\u5728\u53f3\u4fa7\u653e\u7f6e\u4e00\u4e2a\u503c\u5143\u7ec4\u3002 \u53f3\u8fb9\u7684\u503c\u5c06\u6839\u636e\u5b83\u4eec\u5728\u5143\u7ec4\u4e2d\u7684\u4f4d\u7f6e\u81ea\u52a8\u5206\u914d\u7ed9\u5de6\u8fb9\u7684\u53d8\u91cf\u3002 \u8fd9\u5728 Python \u4e2d\u901a\u5e38\u79f0\u4e3a\u5143\u7ec4\u89e3\u5305\u3002 \u5982\u4e0b\u793a\u4f8b\uff1a >>> ( a , b , c ) = ( 1 , 2 , 3 ) >>> a 1 >>> b 2 >>> c 3 >>> birthday = ( 'April' , 5 , 2001 ) >>> month , day , year = birthday >>> month 'April' >>> day 5 >>> year 2001 \u5143\u7ec4\u89e3\u5305\u529f\u80fd\u5728 Python \u4e2d\u53ef\u4ee5\u6269\u5c55\u4e3a\u9002\u7528\u4e8e\u4efb\u4f55\u53ef\u8fed\u4ee3\u5bf9\u8c61\u3002 \u552f\u4e00\u7684\u8981\u6c42\u662f\u53ef\u8fed\u4ee3\u7684\u63a5\u6536\u5143\u7ec4\uff08\u6216\u5217\u8868\uff09\u4e2d\u7684\u6bcf\u4e2a\u53d8\u91cf\u6070\u597d\u5bf9\u5e94\u53ef\u8fed\u4ee3\u5bf9\u8c61\u7684\u4e00\u4e2a\u5143\u7d20\uff08item\uff09\u3002 \u4e0b\u9762\u7684\u793a\u4f8b\u4ecb\u7ecd\u4e86 Python \u4e2d\u53ef\u8fed\u4ee3\u89e3\u5305\u7684\u5de5\u4f5c\u539f\u7406\uff1a >>> # Unpackage strings >>> a , b , c = '123' >>> a '1' >>> b '2' >>> c '3' >>> # Unpacking lists >>> a , b , c = [ 1 , 2 , 3 ] >>> a 1 >>> b 2 >>> c 3 >>> # Unpacking generators >>> gen = ( i ** 2 for i in range ( 3 )) >>> a , b , c = gen >>> a 0 >>> b 1 >>> c 4 >>> # Upacking dictionaries (keys, values, and items) >>> my_dict = { 'one' : 1 , 'two' : 2 , 'three' : 3 } >>> a , b , c = my_dict >>> a 'one' >>> b 'two' >>> c 'three' >>> a , b , c = my_dict . values () >>> a 1 >>> b 2 >>> c 3 >>> a , b , c = my_dict . items () >>> a ( 'one' , 1 ) >>> b ( 'two' , 2 ) >>> c ( 'three' , 3 ) >>> # Use a tuple on the right side of assignment statement >>> [ a , b , c ] = 1 , 2 , 3 >>> a 1 >>> b 2 >>> c 3 >>> # Use range() iterator >>> x , y , z = range ( 3 ) >>> x 0 >>> y 1 >>> z 2 \u6253\u5305Packing \u00b6 \u6253\u5305\u53ef\u4ee5\u7406\u89e3\u4e3a\u4f7f\u7528\u53ef\u8fed\u4ee3\u89e3\u5305\u8fd0\u7b97\u7b26\u5728\u5355\u4e2a\u53d8\u91cf\u4e2d\u6536\u96c6\u591a\u4e2a\u503c\u3002\u5728\u8fd9\u79cd\u60c5\u51b5\u4e0b\uff0c * \u8fd0\u7b97\u7b26\u88ab\u79f0\u4e3a\u5143\u7ec4\uff08\u6216\u53ef\u8fed\u4ee3\uff09\u89e3\u5305\u8fd0\u7b97\u7b26\u3002 \u5b83\u6269\u5c55\u4e86\u89e3\u5305\u529f\u80fd\uff0c\u5141\u8bb8\u5728\u5355\u4e2a\u53d8\u91cf\u4e2d\u6536\u96c6\u6216\u6253\u5305\u591a\u4e2a\u503c\u3002 \u5728\u4ee5\u4e0b\u793a\u4f8b\u4e2d\u53ef\u4ee5\u770b\u5230 * \u8fd0\u7b97\u7b26\u5c06\u5143\u7ec4\u503c\u6253\u5305\u5230\u5355\u4e2a\u53d8\u91cf\u4e2d\uff1a >>> # The right side is a tuple, the left side is a list >>> * a , = 1 , 2 >>> a [ 1 , 2 ] >>> type ( a ) < class ' list '> \u5728\u4e0a\u9762\u7684\u4ee3\u7801\u4e2d\uff0c\u8d4b\u503c\u7684\u5de6\u4fa7\u5fc5\u987b\u662f\u5143\u7ec4\uff08\u6216\u5217\u8868\uff09\uff0c\u8fd9\u5c31\u662f\u4f7f\u7528\u5c3e\u968f\u9017\u53f7\u7684\u539f\u56e0\u3002\u8fd9\u4e2a\u5143\u7ec4\u53ef\u4ee5\u5305\u542b\u6240\u9700\u8981\u7684\u5c3d\u53ef\u80fd\u591a\u7684\u53d8\u91cf\uff0c\u4f46\u662f\uff0c\u5b83\u53ea\u80fd\u5305\u542b\u4e00\u4e2a\u661f\u53f7\u8868\u8fbe\u5f0f(starred expression)\u3002 >>> # Packing trailing values >>> a , * b = 1 , 2 , 3 >>> a 1 >>> b [ 2 , 3 ] >>> type ( a ) < class ' int '> >>> type ( b ) < class ' list '> >>> >>> * a , b , c = 1 , 2 , 3 >>> a [ 1 ] >>> b 2 >>> c 3 >>> * a , b , c , d , e = 1 , 2 , 3 Traceback ( most recent call last ): File \"\" , line 1 , in < module > ValueError : not enough values to unpack ( expected at least 4 , got 3 ) >>> * a , b , c , d = 1 , 2 , 3 >>> a [] >>> b 1 >>> c 2 >>> d 3 >>> >>> seq = [ 1 , 2 , 3 , 4 ] >>> first , * body , last = seq >>> first , body , last ( 1 , [ 2 , 3 ], 4 ) >>> first , body , * last = seq >>> first , body , last ( 1 , 2 , [ 3 , 4 ]) >>> >>> ran = range ( 10 ) >>> * r , = ran >>> r [ 0 , 1 , 2 , 3 , 4 , 5 , 6 , 7 , 8 , 9 ] \u4e0b\u9762\u662f\u4e00\u4e9b\u6253\u5305\u548c\u89e3\u5305\u7684\u4f8b\u5b50\u3002 >>> employee = [ 'John Doe' , '40' , 'Software Engineer' ] >>> name = employee [ 0 ] >>> age = employee [ 1 ] >>> job = employee [ 2 ] >>> name 'John Doe' >>> age '40' >>> job 'Software Engineer' >>> >>> name , age , job = [ 'John Doe' , '40' , 'Software Engineer' ] >>> name 'John Doe' >>> age '40' >>> job 'Software Engineer' >>> >>> a = 100 >>> b = 200 >>> a , b = b , a >>> a 200 >>> b 100 \u4f7f\u7528 * \u5220\u9664\u4e0d\u9700\u8981\u7684\u503c\u3002 >>> a , b , * _ = 1 , 2 , 0 , 0 , 0 , 0 >>> a 1 >>> b 2 >>> _ [ 0 , 0 , 0 , 0 ] \u5728\u4e0a\u4f8b\u4e2d\uff0c\u4e0d\u9700\u8981\u7684\u4fe1\u606f\u5b58\u50a8\u5728\u865a\u62df\u53d8\u91cf _ \u4e2d\uff0c\u5728\u540e\u7eed\u7684\u4f7f\u7528\u4e2d\u53ef\u4ee5\u5ffd\u7565\u5b83\u3002 \u9ed8\u8ba4\u60c5\u51b5\u4e0b\uff0cPython \u89e3\u91ca\u5668\u4f7f\u7528\u4e0b\u5212\u7ebf\u5b57\u7b26 _ \u6765\u5b58\u50a8\u5728\u4ea4\u4e92\u5f0f\u4f1a\u8bdd\u4e2d\u8fd0\u884c\u7684\u8bed\u53e5\u7684\u7ed3\u679c\u503c\u3002 \u56e0\u6b64\uff0c\u5728\u8fd9\u79cd\u60c5\u51b5\u4e0b\uff0c\u4f7f\u7528\u8fd9\u4e2a\u5b57\u7b26\u6765\u8bc6\u522b\u865a\u62df\u53d8\u91cf\u53ef\u80fd\u662f\u6a21\u68f1\u4e24\u53ef\u7684\u3002 \u5728\u51fd\u6570\u4e2d\u8fd4\u56de\u5143\u7ec4\u3002 >>> def powers ( num ): ... return num , num ** 2 , num ** 3 ... >>> # Packaging returned values in a tuple >>> result = powers ( 3 ) >>> result ( 3 , 9 , 27 ) >>> # Unpacking returned values to multiple variables >>> number , square , cube = powers ( 3 ) >>> number 3 >>> square 9 >>> cube 27 >>> * _ , cube = powers ( 3 ) >>> cube 27 \u4f7f\u7528 * \u548c ** \u8fd0\u7b97\u7b26 \u00b6 \u4f7f\u7528 * \u8fd0\u7b97\u7b26\u5408\u5e76\u8fed\u4ee3\u53d8\u91cf\uff08iterables\uff09\u3002\u4e0a\u9762\u4e24\u4e2a\u4f8b\u5b50\u8bf4\u660e\uff0c\u8fd9\u4e2d\u65b9\u6cd5\u4e5f\u662f\u8fde\u63a5\u8fed\u4ee3\u53d8\u91cf\uff08iterables\uff09\u7684\u4e00\u79cd\u66f4\u6613\u8bfb\u548c\u66f4\u6709\u6548\u7684\u65b9\u6cd5\u3002 \u8fd9\u4e2a\u65b9\u6cd5 (my_set) + my_list + list(my_tuple) + list(range(1, 4)) + list(my_str) \u53ef\u4ee5\u751f\u6210\u4e00\u4e2a\u5217\u8868 \uff0c\u4e5f\u53ef\u4ee5\u4f7f\u7528\u66f4\u7b80\u6d01\u7684\u65b9\u6cd5 [*my_set, *my_list, *my_tuple, *range(1, 4), *my_str] \u3002 >>> my_tuple = ( 1 , 2 , 3 ) >>> ( 0 , * my_tuple , 4 ) ( 0 , 1 , 2 , 3 , 4 ) >>> my_list = [ 1 , 2 , 3 ] >>> [ 0 , * my_list , 4 ] [ 0 , 1 , 2 , 3 , 4 ] >>> my_set = { 1 , 2 , 3 } >>> { 0 , * my_set , 4 } { 0 , 1 , 2 , 3 , 4 } >>> [ * my_set , * my_list , * my_tuple , * range ( 1 , 4 )] [ 1 , 2 , 3 , 1 , 2 , 3 , 1 , 2 , 3 , 1 , 2 , 3 ] >>> my_str = \"123\" >>> [ * my_set , * my_list , * my_tuple , * range ( 1 , 4 ), * my_str ] [ 1 , 2 , 3 , 1 , 2 , 3 , 1 , 2 , 3 , 1 , 2 , 3 , '1' , '2' , '3' ] \u4f7f\u7528 ** \u8fd0\u7b97\u7b26\u89e3\u5305\u5b57\u5178\u3002 >>> numbers = { 'one' : 1 , 'two' : 2 , 'three' : 3 } >>> letters = { 'a' : 'A' , 'b' : 'B' , 'c' : 'C' } >>> combination = { ** numbers , ** letters } >>> combination { 'one' : 1 , 'two' : 2 , 'three' : 3 , 'a' : 'A' , 'b' : 'B' , 'c' : 'C' } \u9700\u8981\u6ce8\u610f\u7684\u91cd\u8981\u4e00\u70b9\u662f\uff0c\u5982\u679c\u6211\u4eec\u5408\u5e76\u7684\u5b57\u5178\u5177\u6709\u91cd\u590d\u952e\u6216\u516c\u5171\u952e\uff0c\u5219\u6700\u53f3\u4fa7\u5b57\u5178\u7684\u503c\u5c06\u8986\u76d6\u6700\u5de6\u4fa7\u5b57\u5178\u7684\u503c\u3002\u4f8b\u5982: >>> letters = { 'a' : 'A' , 'b' : 'B' , 'c' : 'C' } >>> vowels = { 'a' : 'a' , 'e' : 'e' , 'i' : 'i' , 'o' : 'o' , 'u' : 'u' } >>> { ** letters , ** vowels } { 'a' : 'a' , 'b' : 'B' , 'c' : 'C' , 'e' : 'e' , 'i' : 'i' , 'o' : 'o' , 'u' : 'u' } >>> { ** vowels , ** letters } { 'a' : 'A' , 'e' : 'e' , 'i' : 'i' , 'o' : 'o' , 'u' : 'u' , 'b' : 'B' , 'c' : 'C' } \u901a\u8fc7 For-Loops \u89e3\u5305 \u00b6 \u6211\u4eec\u8fd8\u53ef\u4ee5\u5728 for \u5faa\u73af\u7684\u4e0a\u4e0b\u6587\u4e2d\u4f7f\u7528\u53ef\u8fed\u4ee3\u89e3\u5305\u3002 \u5f53\u6211\u4eec\u8fd0\u884c for \u5faa\u73af\u65f6\uff0c\u5728\u6bcf\u6b21\u5faa\u73af\u8fed\u4ee3\u4e2d\u5c06\u5176\u53ef\u8fed\u4ee3\u5bf9\u8c61\u4e2d\u7684\u4e00\u9879(item)\u5206\u914d\u7ed9\u76ee\u6807\u53d8\u91cf\u3002 \u5982\u679c\u8981\u5206\u914d\u7684\u9879(item)\u662f\u53ef\u8fed\u4ee3\u7684\uff0c\u90a3\u4e48\u6211\u4eec\u53ef\u4ee5\u4f7f\u7528\u5143\u7ec4\u4f5c\u4e3a\u76ee\u6807\u53d8\u91cf\uff0c\u901a\u8fc7\u5faa\u73af\u5c06\u53ef\u8fed\u4ee3\u5bf9\u8c61\u89e3\u5305\u5230\u76ee\u6807\u53d8\u91cf\u7684\u5143\u7ec4\u4e2d\u3002 \u4f8b\u5982\uff0c\u6211\u4eec\u53ef\u4ee5\u6784\u5efa\u4e00\u4e2a\u5305\u542b\u4e24\u4e2a\u5143\u7d20\u7684\u5143\u7ec4\u7684\u5217\u8868\u3002 \u6bcf\u4e2a\u5143\u7ec4\u5c06\u5305\u542b\u4ea7\u54c1\u540d\u79f0\u3001\u4ef7\u683c\u548c\u9500\u552e\u5355\u4f4d\uff0c\u6211\u4eec\u901a\u8fc7 for \u5faa\u73af\u904d\u5386\u6bcf\u4e2a\u5143\u7ec4\u5143\u7d20\u6765\u8ba1\u7b97\u6bcf\u4e2a\u4ea7\u54c1\u7684\u6536\u5165\u3002 >>> sales = [( 'Pencle' , 0.22 , 1500 ), ( 'Notebook' , 1.30 , 550 ), ( 'Eraser' , 0.75 , 1000 )] >>> for items in sales : ... print ( f \"Income for { items [ 0 ] } is: { items [ 1 ] * items [ 2 ] } \" ) ... Income for Pencle is : 330.0 Income for Notebook is : 715.0 Income for Eraser is : 750.0 \u6211\u4eec\u53ef\u4ee5\u4f7f\u7528\u7d22\u5f15\u6765\u8bbf\u95ee\u6bcf\u4e2a\u5143\u7ec4\u7684\u5404\u4e2a\u5143\u7d20\u3002\u4e0b\u9762\u7684\u793a\u4f8b\u4ee3\u7801\u4e2d\uff0c\u5728 for \u5faa\u73af\u4f7f\u7528\u89e3\u5305\uff0c\u8fd9\u4e5f\u662f Python \u4e2d\u89e3\u5305\u7684\u4e00\u79cd\u5b9e\u73b0\u3002 >>> sales = [( 'Pencle' , 0.22 , 1500 ), ( 'Notebook' , 1.30 , 550 ), ( 'Eraser' , 0.75 , 1000 )] >>> for product , price , sold_units in sales : ... print ( f \"Income for { product } is: { price * sold_units } \" ) ... Income for Pencle is : 330.0 Income for Notebook is : 715.0 Income for Eraser is : 750.0 \u4e5f\u53ef\u4ee5\u5728 for \u5faa\u73af\u4e2d\u4f7f\u7528 * \u8fd0\u7b97\u7b26\u5c06\u591a\u4e2a\u9879\u6253\u5305\u5230\u5355\u4e2a\u76ee\u6807\u53d8\u91cf\u4e2d\u3002 \u5728\u4e0b\u9762\u8fd9\u4e2a\u4f8b\u5b50\u4e2d\uff0c\u6211\u4eec\u9996\u5148\u53d6\u5f97\u6bcf\u4e2a\u5e8f\u5217\u7684\u7b2c\u4e00\u4e2a\u5143\u7d20\u3002 \u5176\u4f59\u503c\u901a\u8fc7 * \u8fd0\u7b97\u7b26\u8d4b\u7ed9\u76ee\u6807\u53d8\u91cf rest \u3002 >>> for first , * rest in [( 1 , 2 , 3 ),( 4 , 5 , 6 )]: ... print ( 'First: ' , first ) ... print ( 'Rest: ' , rest ) ... First : 1 Rest : [ 2 , 3 ] First : 4 Rest : [ 5 , 6 ] >>> \u76ee\u6807\u53d8\u91cf\u7684\u7ed3\u6784\u5fc5\u987b\u4e0e\u53ef\u8fed\u4ee3\u5bf9\u8c61\u7684\u7ed3\u6784\u4e00\u81f4\uff0c\u5426\u5219\u4f1a\u62a5\u9519\u3002\u770b\u4e0b\u9762\u7684\u4f8b\u5b50\u3002 >>> data = [(( 1 , 2 ), 3 ), (( 2 , 3 ), 3 )] >>> for ( a , b ), c in data : ... print ( a , b , c ) ... 1 2 3 2 3 3 >>> for a , b , c in data : ... print ( a , b , c ) ... Traceback ( most recent call last ): File \"\" , line 1 , in < module > ValueError : not enough values to unpack ( expected 3 , got 2 ) \u7528 * \u548c ** \u5b9a\u4e49\u51fd\u6570 \u00b6 \u4e0b\u9762\u4f8b\u5b50\u4e2d\u7684\u51fd\u6570func\u81f3\u5c11\u9700\u8981\u4e00\u4e2a\u540d\u4e3a required \u7684\u53c2\u6570\u3002 \u5b83\u4e5f\u53ef\u4ee5\u63a5\u53d7\u4e00\u4e2a\u6216\u591a\u4e2a\u4f4d\u7f6e\u53c2\u6570\u6216\u5173\u952e\u5b57\u53c2\u6570\u3002 \u5728\u8fd9\u79cd\u60c5\u51b5\u4e0b\uff0c * \u8fd0\u7b97\u7b26\u5728\u4e00\u4e2a\u53eb args \u7684\u5143\u7ec4\u4e2d\u6536\u96c6\u6216\u6253\u5305\u989d\u5916\u7684\u4f4d\u7f6e\u53c2\u6570\uff0c\u800c ** \u8fd0\u7b97\u7b26\u5728\u4e00\u4e2a\u53eb kwargs \u7684\u5b57\u5178\u4e2d\u6536\u96c6\u6216\u6253\u5305\u989d\u5916\u7684\u5173\u952e\u5b57\u53c2\u6570\u3002 args \u548c kwargs \u90fd\u662f\u53ef\u9009\u7684\uff0c\u5e76\u4e14\u5206\u522b\u81ea\u52a8\u9ed8\u8ba4\u4e3a\u5143\u7ec4 () \u548c\u5b57\u5178 {} \u3002 \u8fd9\u91cc args \u548c kwargs \u7684\u547d\u540d\u5e76\u4e0d\u662f\u5fc5\u987b\u7684\uff0c\u8bed\u6cd5\u4e0a\u53ea\u9700\u8981 * \u6216 ** \u540e\u8ddf\u6709\u6548\u6807\u8bc6\u7b26\u5373\u53ef\uff0c\u5efa\u8bae\u7ed9\u53d8\u91cf\u8d77\u4e2a\u6709\u610f\u4e49\u7684\u540d\u5b57\uff0c\u63d0\u9ad8\u4ee3\u7801\u7684\u53ef\u8bfb\u6027\u3002 >>> def func ( required , * args , ** kwargs ): ... print ( required ) ... print ( args ) ... print ( kwargs ) ... >>> func ( 'Welcome to ...' , 1 , 2 , 3 , site = 'CloudAcademy.com' ) Welcome to ... ( 1 , 2 , 3 ) { 'site' : 'CloudAcademy.com' } >>> func ( 'Welcome to ...' , 1 , 2 , 3 , 4 ) Welcome to ... ( 1 , 2 , 3 , 4 ) {} >>> func ( 'Welcome to ...' , 1 , 2 , 3 , ( 1 , 2 )) Welcome to ... ( 1 , 2 , 3 , ( 1 , 2 )) {} >>> func ( 'Welcome to ...' , 1 , 2 , 3 , [ 1 , 2 ]) Welcome to ... ( 1 , 2 , 3 , [ 1 , 2 ]) {} >>> func ( 'Welcome to ...' , 1 , 2 , 3 , ([ 2 , 3 ], [ 1 , 2 ])) Welcome to ... ( 1 , 2 , 3 , ([ 2 , 3 ], [ 1 , 2 ])) {} \u4f7f\u7528 * \u548c ** \u8c03\u7528\u51fd\u6570 \u00b6 \u8c03\u7528\u51fd\u6570\u65f6\uff0c\u6211\u4eec\u8fd8\u53ef\u4ee5\u53d7\u76ca\u4e8e\u4f7f\u7528 * \u548c ** \u8fd0\u7b97\u7b26\u5c06\u53c2\u6570\u96c6\u5408\u5206\u522b\u89e3\u538b\u7f29\u4e3a\u5355\u72ec\u7684\u4f4d\u7f6e\u53c2\u6570\u6216\u5173\u952e\u5b57\u53c2\u6570\u3002 \u8fd9\u4e0e\u5728\u51fd\u6570\u7b7e\u540d(signature of a function)\u4e2d\u4f7f\u7528 * \u548c ** \u662f\u76f8\u53cd\u7684\u3002 \u5728\u51fd\u6570\u7b7e\u540d\u4e2d\uff0c\u8fd0\u7b97\u7b26\u7684\u610f\u601d\u662f\u5728\u4e00\u4e2a\u6807\u8bc6\u7b26\u4e2d\u6536\u96c6\u6216\u6253\u5305\u53ef\u53d8\u6570\u91cf\u7684\u53c2\u6570\u3002 \u5728\u8c03\u7528(calling)\u4e2d\uff0c\u5b83\u4eec\u7684\u610f\u601d\u662f\u89e3\u5305(unpack)\u4e00\u4e2a\u53ef\u8fed\u4ee3\u5bf9\u8c61\u5230\u591a\u4e2a\u53c2\u6570\u4e2d\u3002 \u7eed\u4e0a\u4f8b\uff0c * \u8fd0\u7b97\u7b26\u5c06\u50cf [\"Welcome\", \"to\"] \u8fd9\u6837\u7684\u5e8f\u5217\u89e3\u5305\u5230\u4f4d\u7f6e\u53c2\u6570\u4e2d\u3002 \u7c7b\u4f3c\u5730\uff0c ** \u8fd0\u7b97\u7b26\u5c06\u5b57\u5178\u89e3\u5305\u4e3a\u4e0e\u5b57\u5178\u7684\u952e\u503c\u5339\u914d\u7684\u53c2\u6570\u540d\u3002 >>> def func ( welcome , to , site ): ... print ( welcome , to , site ) ... >>> func ( * [ 'Welcome' , 'to' ], ** { 'site' : 'CloudAcademy.com' }) Welcome to CloudAcademy . com \u7efc\u5408\u8fd0\u7528\u524d\u9762\u7684\u65b9\u6cd5\u6765\u7f16\u5199\u975e\u5e38\u7075\u6d3b\u7684\u51fd\u6570\uff0c\u6bd4\u5982\uff0c\u5728\u5b9a\u4e49\u548c\u8c03\u7528 Python \u51fd\u6570\u65f6\uff0c\u66f4\u7075\u6d3b\u7684\u4f7f\u7528 * \u548c ** \u8fd0\u7b97\u7b26\u3002 \u4f8b\u5982\uff1a >>> def func ( required , * args , ** kwargs ): ... print ( required ) ... print ( args ) ... print ( kwargs ) ... >>> func ( 'Welcome to...' , * ( 1 , 2 , 3 ), ** { 'Site' : 'CloudAcademy.com' }) Welcome to ... ( 1 , 2 , 3 ) { 'Site' : 'CloudAcademy.com' } \u603b\u7ed3 \u00b6 \u53ef\u8fed\u4ee3\u89e3\u5305\uff08iterable unpacking\uff09\u8fd9\u4e2a\u7279\u6027\u5141\u8bb8\u6211\u4eec\u5c06\u4e00\u4e2a\u53ef\u8fed\u4ee3\u5bf9\u8c61\u89e3\u5305\u6210\u51e0\u4e2a\u53d8\u91cf\u3002 \u53e6\u4e00\u65b9\u9762\uff0c\u6253\u5305\u5305\u62ec\u4f7f\u7528\u89e3\u5305\u8fd0\u7b97\u7b26 * \u5c06\u591a\u4e2a\u503c\u8d4b\u5230\u4e00\u4e2a\u53d8\u91cf\u4e2d\u3002 \u53ef\u8fed\u4ee3\u89e3\u5305\uff08iterable unpacking\uff09\u4e5f\u53ef\u4ee5\u7528\u6765\u8fdb\u884c\u5e76\u884c\u8d4b\u503c\u548c\u53d8\u91cf\u4e4b\u95f4\u7684\u503c\u4ea4\u6362\uff0c\u4e5f\u53ef\u4ee5\u7528\u5728 for \u5faa\u73af\u3001\u51fd\u6570\u8c03\u7528\u548c\u51fd\u6570\u5b9a\u4e49\u4e2d\u3002","title":"Python\u6253\u5305\u548c\u89e3\u5305"},{"location":"python/Foundation/ch02/#python","text":"","title":"Python\u6253\u5305\u548c\u89e3\u5305"},{"location":"python/Foundation/ch02/#unpacking","text":"Python \u5141\u8bb8\u53d8\u91cf\u7684\u5143\u7ec4\uff08\u6216\u5217\u8868\uff09\u51fa\u73b0\u5728\u8d4b\u503c\u64cd\u4f5c\u7684\u5de6\u4fa7\u3002 \u5143\u7ec4\u4e2d\u7684\u6bcf\u4e2a\u53d8\u91cf\u90fd\u53ef\u4ee5\u4ece\u8d4b\u503c\u53f3\u4fa7\u7684\u53ef\u8fed\u4ee3\u5bf9\u8c61\uff08iterable\uff09\u4e2d\u63a5\u6536\u4e00\u4e2a\u503c\uff08\u6216\u8005\u66f4\u591a\uff0c\u5982\u679c\u6211\u4eec\u4f7f\u7528 * \u8fd0\u7b97\u7b26\uff09\u3002 Python \u4e2d\u7684\u89e3\u5305\u662f\u6307\u4e00\u79cd\u64cd\u4f5c\uff0c\u8be5\u64cd\u4f5c\u5305\u62ec\u5728\u5355\u4e2a\u8d4b\u503c\u8bed\u53e5\u4e2d\u5c06\u53ef\u8fed\u4ee3\u7684\u503c\u5206\u914d\u7ed9\u53d8\u91cf\u7684\u5143\u7ec4\uff08\u6216\u5217\u8868\uff09\u3002 \u5728 Python \u4e2d\uff0c\u53ef\u4ee5\u5728\u8d4b\u503c\u8fd0\u7b97\u7b26 = \u7684\u5de6\u4fa7\u653e\u7f6e\u4e00\u4e2a\u53d8\u91cf\u5143\u7ec4\uff0c\u5728\u53f3\u4fa7\u653e\u7f6e\u4e00\u4e2a\u503c\u5143\u7ec4\u3002 \u53f3\u8fb9\u7684\u503c\u5c06\u6839\u636e\u5b83\u4eec\u5728\u5143\u7ec4\u4e2d\u7684\u4f4d\u7f6e\u81ea\u52a8\u5206\u914d\u7ed9\u5de6\u8fb9\u7684\u53d8\u91cf\u3002 \u8fd9\u5728 Python \u4e2d\u901a\u5e38\u79f0\u4e3a\u5143\u7ec4\u89e3\u5305\u3002 \u5982\u4e0b\u793a\u4f8b\uff1a >>> ( a , b , c ) = ( 1 , 2 , 3 ) >>> a 1 >>> b 2 >>> c 3 >>> birthday = ( 'April' , 5 , 2001 ) >>> month , day , year = birthday >>> month 'April' >>> day 5 >>> year 2001 \u5143\u7ec4\u89e3\u5305\u529f\u80fd\u5728 Python \u4e2d\u53ef\u4ee5\u6269\u5c55\u4e3a\u9002\u7528\u4e8e\u4efb\u4f55\u53ef\u8fed\u4ee3\u5bf9\u8c61\u3002 \u552f\u4e00\u7684\u8981\u6c42\u662f\u53ef\u8fed\u4ee3\u7684\u63a5\u6536\u5143\u7ec4\uff08\u6216\u5217\u8868\uff09\u4e2d\u7684\u6bcf\u4e2a\u53d8\u91cf\u6070\u597d\u5bf9\u5e94\u53ef\u8fed\u4ee3\u5bf9\u8c61\u7684\u4e00\u4e2a\u5143\u7d20\uff08item\uff09\u3002 \u4e0b\u9762\u7684\u793a\u4f8b\u4ecb\u7ecd\u4e86 Python \u4e2d\u53ef\u8fed\u4ee3\u89e3\u5305\u7684\u5de5\u4f5c\u539f\u7406\uff1a >>> # Unpackage strings >>> a , b , c = '123' >>> a '1' >>> b '2' >>> c '3' >>> # Unpacking lists >>> a , b , c = [ 1 , 2 , 3 ] >>> a 1 >>> b 2 >>> c 3 >>> # Unpacking generators >>> gen = ( i ** 2 for i in range ( 3 )) >>> a , b , c = gen >>> a 0 >>> b 1 >>> c 4 >>> # Upacking dictionaries (keys, values, and items) >>> my_dict = { 'one' : 1 , 'two' : 2 , 'three' : 3 } >>> a , b , c = my_dict >>> a 'one' >>> b 'two' >>> c 'three' >>> a , b , c = my_dict . values () >>> a 1 >>> b 2 >>> c 3 >>> a , b , c = my_dict . items () >>> a ( 'one' , 1 ) >>> b ( 'two' , 2 ) >>> c ( 'three' , 3 ) >>> # Use a tuple on the right side of assignment statement >>> [ a , b , c ] = 1 , 2 , 3 >>> a 1 >>> b 2 >>> c 3 >>> # Use range() iterator >>> x , y , z = range ( 3 ) >>> x 0 >>> y 1 >>> z 2","title":"\u89e3\u5305Unpacking"},{"location":"python/Foundation/ch02/#packing","text":"\u6253\u5305\u53ef\u4ee5\u7406\u89e3\u4e3a\u4f7f\u7528\u53ef\u8fed\u4ee3\u89e3\u5305\u8fd0\u7b97\u7b26\u5728\u5355\u4e2a\u53d8\u91cf\u4e2d\u6536\u96c6\u591a\u4e2a\u503c\u3002\u5728\u8fd9\u79cd\u60c5\u51b5\u4e0b\uff0c * \u8fd0\u7b97\u7b26\u88ab\u79f0\u4e3a\u5143\u7ec4\uff08\u6216\u53ef\u8fed\u4ee3\uff09\u89e3\u5305\u8fd0\u7b97\u7b26\u3002 \u5b83\u6269\u5c55\u4e86\u89e3\u5305\u529f\u80fd\uff0c\u5141\u8bb8\u5728\u5355\u4e2a\u53d8\u91cf\u4e2d\u6536\u96c6\u6216\u6253\u5305\u591a\u4e2a\u503c\u3002 \u5728\u4ee5\u4e0b\u793a\u4f8b\u4e2d\u53ef\u4ee5\u770b\u5230 * \u8fd0\u7b97\u7b26\u5c06\u5143\u7ec4\u503c\u6253\u5305\u5230\u5355\u4e2a\u53d8\u91cf\u4e2d\uff1a >>> # The right side is a tuple, the left side is a list >>> * a , = 1 , 2 >>> a [ 1 , 2 ] >>> type ( a ) < class ' list '> \u5728\u4e0a\u9762\u7684\u4ee3\u7801\u4e2d\uff0c\u8d4b\u503c\u7684\u5de6\u4fa7\u5fc5\u987b\u662f\u5143\u7ec4\uff08\u6216\u5217\u8868\uff09\uff0c\u8fd9\u5c31\u662f\u4f7f\u7528\u5c3e\u968f\u9017\u53f7\u7684\u539f\u56e0\u3002\u8fd9\u4e2a\u5143\u7ec4\u53ef\u4ee5\u5305\u542b\u6240\u9700\u8981\u7684\u5c3d\u53ef\u80fd\u591a\u7684\u53d8\u91cf\uff0c\u4f46\u662f\uff0c\u5b83\u53ea\u80fd\u5305\u542b\u4e00\u4e2a\u661f\u53f7\u8868\u8fbe\u5f0f(starred expression)\u3002 >>> # Packing trailing values >>> a , * b = 1 , 2 , 3 >>> a 1 >>> b [ 2 , 3 ] >>> type ( a ) < class ' int '> >>> type ( b ) < class ' list '> >>> >>> * a , b , c = 1 , 2 , 3 >>> a [ 1 ] >>> b 2 >>> c 3 >>> * a , b , c , d , e = 1 , 2 , 3 Traceback ( most recent call last ): File \"\" , line 1 , in < module > ValueError : not enough values to unpack ( expected at least 4 , got 3 ) >>> * a , b , c , d = 1 , 2 , 3 >>> a [] >>> b 1 >>> c 2 >>> d 3 >>> >>> seq = [ 1 , 2 , 3 , 4 ] >>> first , * body , last = seq >>> first , body , last ( 1 , [ 2 , 3 ], 4 ) >>> first , body , * last = seq >>> first , body , last ( 1 , 2 , [ 3 , 4 ]) >>> >>> ran = range ( 10 ) >>> * r , = ran >>> r [ 0 , 1 , 2 , 3 , 4 , 5 , 6 , 7 , 8 , 9 ] \u4e0b\u9762\u662f\u4e00\u4e9b\u6253\u5305\u548c\u89e3\u5305\u7684\u4f8b\u5b50\u3002 >>> employee = [ 'John Doe' , '40' , 'Software Engineer' ] >>> name = employee [ 0 ] >>> age = employee [ 1 ] >>> job = employee [ 2 ] >>> name 'John Doe' >>> age '40' >>> job 'Software Engineer' >>> >>> name , age , job = [ 'John Doe' , '40' , 'Software Engineer' ] >>> name 'John Doe' >>> age '40' >>> job 'Software Engineer' >>> >>> a = 100 >>> b = 200 >>> a , b = b , a >>> a 200 >>> b 100 \u4f7f\u7528 * \u5220\u9664\u4e0d\u9700\u8981\u7684\u503c\u3002 >>> a , b , * _ = 1 , 2 , 0 , 0 , 0 , 0 >>> a 1 >>> b 2 >>> _ [ 0 , 0 , 0 , 0 ] \u5728\u4e0a\u4f8b\u4e2d\uff0c\u4e0d\u9700\u8981\u7684\u4fe1\u606f\u5b58\u50a8\u5728\u865a\u62df\u53d8\u91cf _ \u4e2d\uff0c\u5728\u540e\u7eed\u7684\u4f7f\u7528\u4e2d\u53ef\u4ee5\u5ffd\u7565\u5b83\u3002 \u9ed8\u8ba4\u60c5\u51b5\u4e0b\uff0cPython \u89e3\u91ca\u5668\u4f7f\u7528\u4e0b\u5212\u7ebf\u5b57\u7b26 _ \u6765\u5b58\u50a8\u5728\u4ea4\u4e92\u5f0f\u4f1a\u8bdd\u4e2d\u8fd0\u884c\u7684\u8bed\u53e5\u7684\u7ed3\u679c\u503c\u3002 \u56e0\u6b64\uff0c\u5728\u8fd9\u79cd\u60c5\u51b5\u4e0b\uff0c\u4f7f\u7528\u8fd9\u4e2a\u5b57\u7b26\u6765\u8bc6\u522b\u865a\u62df\u53d8\u91cf\u53ef\u80fd\u662f\u6a21\u68f1\u4e24\u53ef\u7684\u3002 \u5728\u51fd\u6570\u4e2d\u8fd4\u56de\u5143\u7ec4\u3002 >>> def powers ( num ): ... return num , num ** 2 , num ** 3 ... >>> # Packaging returned values in a tuple >>> result = powers ( 3 ) >>> result ( 3 , 9 , 27 ) >>> # Unpacking returned values to multiple variables >>> number , square , cube = powers ( 3 ) >>> number 3 >>> square 9 >>> cube 27 >>> * _ , cube = powers ( 3 ) >>> cube 27","title":"\u6253\u5305Packing"},{"location":"python/Foundation/ch02/#_1","text":"\u4f7f\u7528 * \u8fd0\u7b97\u7b26\u5408\u5e76\u8fed\u4ee3\u53d8\u91cf\uff08iterables\uff09\u3002\u4e0a\u9762\u4e24\u4e2a\u4f8b\u5b50\u8bf4\u660e\uff0c\u8fd9\u4e2d\u65b9\u6cd5\u4e5f\u662f\u8fde\u63a5\u8fed\u4ee3\u53d8\u91cf\uff08iterables\uff09\u7684\u4e00\u79cd\u66f4\u6613\u8bfb\u548c\u66f4\u6709\u6548\u7684\u65b9\u6cd5\u3002 \u8fd9\u4e2a\u65b9\u6cd5 (my_set) + my_list + list(my_tuple) + list(range(1, 4)) + list(my_str) \u53ef\u4ee5\u751f\u6210\u4e00\u4e2a\u5217\u8868 \uff0c\u4e5f\u53ef\u4ee5\u4f7f\u7528\u66f4\u7b80\u6d01\u7684\u65b9\u6cd5 [*my_set, *my_list, *my_tuple, *range(1, 4), *my_str] \u3002 >>> my_tuple = ( 1 , 2 , 3 ) >>> ( 0 , * my_tuple , 4 ) ( 0 , 1 , 2 , 3 , 4 ) >>> my_list = [ 1 , 2 , 3 ] >>> [ 0 , * my_list , 4 ] [ 0 , 1 , 2 , 3 , 4 ] >>> my_set = { 1 , 2 , 3 } >>> { 0 , * my_set , 4 } { 0 , 1 , 2 , 3 , 4 } >>> [ * my_set , * my_list , * my_tuple , * range ( 1 , 4 )] [ 1 , 2 , 3 , 1 , 2 , 3 , 1 , 2 , 3 , 1 , 2 , 3 ] >>> my_str = \"123\" >>> [ * my_set , * my_list , * my_tuple , * range ( 1 , 4 ), * my_str ] [ 1 , 2 , 3 , 1 , 2 , 3 , 1 , 2 , 3 , 1 , 2 , 3 , '1' , '2' , '3' ] \u4f7f\u7528 ** \u8fd0\u7b97\u7b26\u89e3\u5305\u5b57\u5178\u3002 >>> numbers = { 'one' : 1 , 'two' : 2 , 'three' : 3 } >>> letters = { 'a' : 'A' , 'b' : 'B' , 'c' : 'C' } >>> combination = { ** numbers , ** letters } >>> combination { 'one' : 1 , 'two' : 2 , 'three' : 3 , 'a' : 'A' , 'b' : 'B' , 'c' : 'C' } \u9700\u8981\u6ce8\u610f\u7684\u91cd\u8981\u4e00\u70b9\u662f\uff0c\u5982\u679c\u6211\u4eec\u5408\u5e76\u7684\u5b57\u5178\u5177\u6709\u91cd\u590d\u952e\u6216\u516c\u5171\u952e\uff0c\u5219\u6700\u53f3\u4fa7\u5b57\u5178\u7684\u503c\u5c06\u8986\u76d6\u6700\u5de6\u4fa7\u5b57\u5178\u7684\u503c\u3002\u4f8b\u5982: >>> letters = { 'a' : 'A' , 'b' : 'B' , 'c' : 'C' } >>> vowels = { 'a' : 'a' , 'e' : 'e' , 'i' : 'i' , 'o' : 'o' , 'u' : 'u' } >>> { ** letters , ** vowels } { 'a' : 'a' , 'b' : 'B' , 'c' : 'C' , 'e' : 'e' , 'i' : 'i' , 'o' : 'o' , 'u' : 'u' } >>> { ** vowels , ** letters } { 'a' : 'A' , 'e' : 'e' , 'i' : 'i' , 'o' : 'o' , 'u' : 'u' , 'b' : 'B' , 'c' : 'C' }","title":"\u4f7f\u7528*\u548c**\u8fd0\u7b97\u7b26"},{"location":"python/Foundation/ch02/#for-loops","text":"\u6211\u4eec\u8fd8\u53ef\u4ee5\u5728 for \u5faa\u73af\u7684\u4e0a\u4e0b\u6587\u4e2d\u4f7f\u7528\u53ef\u8fed\u4ee3\u89e3\u5305\u3002 \u5f53\u6211\u4eec\u8fd0\u884c for \u5faa\u73af\u65f6\uff0c\u5728\u6bcf\u6b21\u5faa\u73af\u8fed\u4ee3\u4e2d\u5c06\u5176\u53ef\u8fed\u4ee3\u5bf9\u8c61\u4e2d\u7684\u4e00\u9879(item)\u5206\u914d\u7ed9\u76ee\u6807\u53d8\u91cf\u3002 \u5982\u679c\u8981\u5206\u914d\u7684\u9879(item)\u662f\u53ef\u8fed\u4ee3\u7684\uff0c\u90a3\u4e48\u6211\u4eec\u53ef\u4ee5\u4f7f\u7528\u5143\u7ec4\u4f5c\u4e3a\u76ee\u6807\u53d8\u91cf\uff0c\u901a\u8fc7\u5faa\u73af\u5c06\u53ef\u8fed\u4ee3\u5bf9\u8c61\u89e3\u5305\u5230\u76ee\u6807\u53d8\u91cf\u7684\u5143\u7ec4\u4e2d\u3002 \u4f8b\u5982\uff0c\u6211\u4eec\u53ef\u4ee5\u6784\u5efa\u4e00\u4e2a\u5305\u542b\u4e24\u4e2a\u5143\u7d20\u7684\u5143\u7ec4\u7684\u5217\u8868\u3002 \u6bcf\u4e2a\u5143\u7ec4\u5c06\u5305\u542b\u4ea7\u54c1\u540d\u79f0\u3001\u4ef7\u683c\u548c\u9500\u552e\u5355\u4f4d\uff0c\u6211\u4eec\u901a\u8fc7 for \u5faa\u73af\u904d\u5386\u6bcf\u4e2a\u5143\u7ec4\u5143\u7d20\u6765\u8ba1\u7b97\u6bcf\u4e2a\u4ea7\u54c1\u7684\u6536\u5165\u3002 >>> sales = [( 'Pencle' , 0.22 , 1500 ), ( 'Notebook' , 1.30 , 550 ), ( 'Eraser' , 0.75 , 1000 )] >>> for items in sales : ... print ( f \"Income for { items [ 0 ] } is: { items [ 1 ] * items [ 2 ] } \" ) ... Income for Pencle is : 330.0 Income for Notebook is : 715.0 Income for Eraser is : 750.0 \u6211\u4eec\u53ef\u4ee5\u4f7f\u7528\u7d22\u5f15\u6765\u8bbf\u95ee\u6bcf\u4e2a\u5143\u7ec4\u7684\u5404\u4e2a\u5143\u7d20\u3002\u4e0b\u9762\u7684\u793a\u4f8b\u4ee3\u7801\u4e2d\uff0c\u5728 for \u5faa\u73af\u4f7f\u7528\u89e3\u5305\uff0c\u8fd9\u4e5f\u662f Python \u4e2d\u89e3\u5305\u7684\u4e00\u79cd\u5b9e\u73b0\u3002 >>> sales = [( 'Pencle' , 0.22 , 1500 ), ( 'Notebook' , 1.30 , 550 ), ( 'Eraser' , 0.75 , 1000 )] >>> for product , price , sold_units in sales : ... print ( f \"Income for { product } is: { price * sold_units } \" ) ... Income for Pencle is : 330.0 Income for Notebook is : 715.0 Income for Eraser is : 750.0 \u4e5f\u53ef\u4ee5\u5728 for \u5faa\u73af\u4e2d\u4f7f\u7528 * \u8fd0\u7b97\u7b26\u5c06\u591a\u4e2a\u9879\u6253\u5305\u5230\u5355\u4e2a\u76ee\u6807\u53d8\u91cf\u4e2d\u3002 \u5728\u4e0b\u9762\u8fd9\u4e2a\u4f8b\u5b50\u4e2d\uff0c\u6211\u4eec\u9996\u5148\u53d6\u5f97\u6bcf\u4e2a\u5e8f\u5217\u7684\u7b2c\u4e00\u4e2a\u5143\u7d20\u3002 \u5176\u4f59\u503c\u901a\u8fc7 * \u8fd0\u7b97\u7b26\u8d4b\u7ed9\u76ee\u6807\u53d8\u91cf rest \u3002 >>> for first , * rest in [( 1 , 2 , 3 ),( 4 , 5 , 6 )]: ... print ( 'First: ' , first ) ... print ( 'Rest: ' , rest ) ... First : 1 Rest : [ 2 , 3 ] First : 4 Rest : [ 5 , 6 ] >>> \u76ee\u6807\u53d8\u91cf\u7684\u7ed3\u6784\u5fc5\u987b\u4e0e\u53ef\u8fed\u4ee3\u5bf9\u8c61\u7684\u7ed3\u6784\u4e00\u81f4\uff0c\u5426\u5219\u4f1a\u62a5\u9519\u3002\u770b\u4e0b\u9762\u7684\u4f8b\u5b50\u3002 >>> data = [(( 1 , 2 ), 3 ), (( 2 , 3 ), 3 )] >>> for ( a , b ), c in data : ... print ( a , b , c ) ... 1 2 3 2 3 3 >>> for a , b , c in data : ... print ( a , b , c ) ... Traceback ( most recent call last ): File \"\" , line 1 , in < module > ValueError : not enough values to unpack ( expected 3 , got 2 )","title":"\u901a\u8fc7 For-Loops \u89e3\u5305"},{"location":"python/Foundation/ch02/#_2","text":"\u4e0b\u9762\u4f8b\u5b50\u4e2d\u7684\u51fd\u6570func\u81f3\u5c11\u9700\u8981\u4e00\u4e2a\u540d\u4e3a required \u7684\u53c2\u6570\u3002 \u5b83\u4e5f\u53ef\u4ee5\u63a5\u53d7\u4e00\u4e2a\u6216\u591a\u4e2a\u4f4d\u7f6e\u53c2\u6570\u6216\u5173\u952e\u5b57\u53c2\u6570\u3002 \u5728\u8fd9\u79cd\u60c5\u51b5\u4e0b\uff0c * \u8fd0\u7b97\u7b26\u5728\u4e00\u4e2a\u53eb args \u7684\u5143\u7ec4\u4e2d\u6536\u96c6\u6216\u6253\u5305\u989d\u5916\u7684\u4f4d\u7f6e\u53c2\u6570\uff0c\u800c ** \u8fd0\u7b97\u7b26\u5728\u4e00\u4e2a\u53eb kwargs \u7684\u5b57\u5178\u4e2d\u6536\u96c6\u6216\u6253\u5305\u989d\u5916\u7684\u5173\u952e\u5b57\u53c2\u6570\u3002 args \u548c kwargs \u90fd\u662f\u53ef\u9009\u7684\uff0c\u5e76\u4e14\u5206\u522b\u81ea\u52a8\u9ed8\u8ba4\u4e3a\u5143\u7ec4 () \u548c\u5b57\u5178 {} \u3002 \u8fd9\u91cc args \u548c kwargs \u7684\u547d\u540d\u5e76\u4e0d\u662f\u5fc5\u987b\u7684\uff0c\u8bed\u6cd5\u4e0a\u53ea\u9700\u8981 * \u6216 ** \u540e\u8ddf\u6709\u6548\u6807\u8bc6\u7b26\u5373\u53ef\uff0c\u5efa\u8bae\u7ed9\u53d8\u91cf\u8d77\u4e2a\u6709\u610f\u4e49\u7684\u540d\u5b57\uff0c\u63d0\u9ad8\u4ee3\u7801\u7684\u53ef\u8bfb\u6027\u3002 >>> def func ( required , * args , ** kwargs ): ... print ( required ) ... print ( args ) ... print ( kwargs ) ... >>> func ( 'Welcome to ...' , 1 , 2 , 3 , site = 'CloudAcademy.com' ) Welcome to ... ( 1 , 2 , 3 ) { 'site' : 'CloudAcademy.com' } >>> func ( 'Welcome to ...' , 1 , 2 , 3 , 4 ) Welcome to ... ( 1 , 2 , 3 , 4 ) {} >>> func ( 'Welcome to ...' , 1 , 2 , 3 , ( 1 , 2 )) Welcome to ... ( 1 , 2 , 3 , ( 1 , 2 )) {} >>> func ( 'Welcome to ...' , 1 , 2 , 3 , [ 1 , 2 ]) Welcome to ... ( 1 , 2 , 3 , [ 1 , 2 ]) {} >>> func ( 'Welcome to ...' , 1 , 2 , 3 , ([ 2 , 3 ], [ 1 , 2 ])) Welcome to ... ( 1 , 2 , 3 , ([ 2 , 3 ], [ 1 , 2 ])) {}","title":"\u7528*\u548c**\u5b9a\u4e49\u51fd\u6570"},{"location":"python/Foundation/ch02/#_3","text":"\u8c03\u7528\u51fd\u6570\u65f6\uff0c\u6211\u4eec\u8fd8\u53ef\u4ee5\u53d7\u76ca\u4e8e\u4f7f\u7528 * \u548c ** \u8fd0\u7b97\u7b26\u5c06\u53c2\u6570\u96c6\u5408\u5206\u522b\u89e3\u538b\u7f29\u4e3a\u5355\u72ec\u7684\u4f4d\u7f6e\u53c2\u6570\u6216\u5173\u952e\u5b57\u53c2\u6570\u3002 \u8fd9\u4e0e\u5728\u51fd\u6570\u7b7e\u540d(signature of a function)\u4e2d\u4f7f\u7528 * \u548c ** \u662f\u76f8\u53cd\u7684\u3002 \u5728\u51fd\u6570\u7b7e\u540d\u4e2d\uff0c\u8fd0\u7b97\u7b26\u7684\u610f\u601d\u662f\u5728\u4e00\u4e2a\u6807\u8bc6\u7b26\u4e2d\u6536\u96c6\u6216\u6253\u5305\u53ef\u53d8\u6570\u91cf\u7684\u53c2\u6570\u3002 \u5728\u8c03\u7528(calling)\u4e2d\uff0c\u5b83\u4eec\u7684\u610f\u601d\u662f\u89e3\u5305(unpack)\u4e00\u4e2a\u53ef\u8fed\u4ee3\u5bf9\u8c61\u5230\u591a\u4e2a\u53c2\u6570\u4e2d\u3002 \u7eed\u4e0a\u4f8b\uff0c * \u8fd0\u7b97\u7b26\u5c06\u50cf [\"Welcome\", \"to\"] \u8fd9\u6837\u7684\u5e8f\u5217\u89e3\u5305\u5230\u4f4d\u7f6e\u53c2\u6570\u4e2d\u3002 \u7c7b\u4f3c\u5730\uff0c ** \u8fd0\u7b97\u7b26\u5c06\u5b57\u5178\u89e3\u5305\u4e3a\u4e0e\u5b57\u5178\u7684\u952e\u503c\u5339\u914d\u7684\u53c2\u6570\u540d\u3002 >>> def func ( welcome , to , site ): ... print ( welcome , to , site ) ... >>> func ( * [ 'Welcome' , 'to' ], ** { 'site' : 'CloudAcademy.com' }) Welcome to CloudAcademy . com \u7efc\u5408\u8fd0\u7528\u524d\u9762\u7684\u65b9\u6cd5\u6765\u7f16\u5199\u975e\u5e38\u7075\u6d3b\u7684\u51fd\u6570\uff0c\u6bd4\u5982\uff0c\u5728\u5b9a\u4e49\u548c\u8c03\u7528 Python \u51fd\u6570\u65f6\uff0c\u66f4\u7075\u6d3b\u7684\u4f7f\u7528 * \u548c ** \u8fd0\u7b97\u7b26\u3002 \u4f8b\u5982\uff1a >>> def func ( required , * args , ** kwargs ): ... print ( required ) ... print ( args ) ... print ( kwargs ) ... >>> func ( 'Welcome to...' , * ( 1 , 2 , 3 ), ** { 'Site' : 'CloudAcademy.com' }) Welcome to ... ( 1 , 2 , 3 ) { 'Site' : 'CloudAcademy.com' }","title":"\u4f7f\u7528*\u548c**\u8c03\u7528\u51fd\u6570"},{"location":"python/Foundation/ch02/#_4","text":"\u53ef\u8fed\u4ee3\u89e3\u5305\uff08iterable unpacking\uff09\u8fd9\u4e2a\u7279\u6027\u5141\u8bb8\u6211\u4eec\u5c06\u4e00\u4e2a\u53ef\u8fed\u4ee3\u5bf9\u8c61\u89e3\u5305\u6210\u51e0\u4e2a\u53d8\u91cf\u3002 \u53e6\u4e00\u65b9\u9762\uff0c\u6253\u5305\u5305\u62ec\u4f7f\u7528\u89e3\u5305\u8fd0\u7b97\u7b26 * \u5c06\u591a\u4e2a\u503c\u8d4b\u5230\u4e00\u4e2a\u53d8\u91cf\u4e2d\u3002 \u53ef\u8fed\u4ee3\u89e3\u5305\uff08iterable unpacking\uff09\u4e5f\u53ef\u4ee5\u7528\u6765\u8fdb\u884c\u5e76\u884c\u8d4b\u503c\u548c\u53d8\u91cf\u4e4b\u95f4\u7684\u503c\u4ea4\u6362\uff0c\u4e5f\u53ef\u4ee5\u7528\u5728 for \u5faa\u73af\u3001\u51fd\u6570\u8c03\u7528\u548c\u51fd\u6570\u5b9a\u4e49\u4e2d\u3002","title":"\u603b\u7ed3"},{"location":"python/Foundation/ch03/","text":"Python\u5185\u7f6e\u51fd\u6570\u53ca\u6587\u4ef6 \u00b6 1. \u533f\u540d\uff08Lambda\uff09\u51fd\u6570 \u00b6 \u533f\u540d\u51fd\u6570\u662f\u4e00\u79cd\u901a\u8fc7\u5355\u4e2a\u8bed\u53e5\u751f\u6210\u51fd\u6570\u7684\u65b9\u5f0f\uff0c\u5176\u7ed3\u679c\u662f\u8fd4\u56de\u503c\u3002\u533f\u540d\u51fd\u6570\u4f7f\u7528lambda\u5173\u952e\u5b57\u5b9a\u4e49\uff0c\u8be5\u5173\u952e\u5b57\u4ec5\u8868\u8fbe\u201c\u6211\u4eec\u58f0\u660e\u4e00\u4e2a\u533f\u540d\u51fd\u6570\u201d\u7684\u610f\u601d\u3002 lambda \u51fd\u6570\u53ef\u4ee5\u63a5\u6536\u4efb\u610f\u591a\u4e2a\u53c2\u6570 (\u5305\u62ec\u53ef\u9009\u53c2\u6570) \u5e76\u4e14\u8fd4\u56de\u5355\u4e2a\u8868\u8fbe\u5f0f\u7684\u503c\u3002 \u8bed\u6cd5\u683c\u5f0f\uff1a lambda arg1,arg2,arg3\u2026 :<\u8868\u8fbe\u5f0f> f = lambda x , y : x * y print ( f ( 2 , 3 )) # 6 f = [ lambda a : a * 2 , lambda b : b * 3 ] print ( f [ 0 ]( 5 )) # \u6267\u884cf\u5217\u8868\u7b2c\u4e00\u4e2a\u5143\u7d20 # 10 print ( f [ 1 ]( 5 )) # \u6267\u884cf\u5143\u7d20\u7b2c\u4e8c\u4e2a\u5143\u7d20 # 15 print ( f [ 0 , 1 ]( 5 , 5 )) # TypeError: list indices must be integers or slices, not tuple \u793a\u4f8b1\uff1a def short_func1 ( x ): return x * 2 short_func2 = lambda x : x * 2 print ( short_func1 ( 5 )) # 10 print ( short_func2 ( 5 )) # 10 \u793a\u4f8b2\uff1a def apply_to_list ( some_list , f ): return [ f ( x ) for x in some_list ] ints = [ 4 , 0 , 1 , 5 , 6 ] result5 = apply_to_list ( ints , lambda x : x * 2 ) print ( result5 ) # [8, 0, 2, 10, 12] lambda: None \u51fd\u6570\u6ca1\u6709\u8f93\u5165\u53c2\u6570\uff0c\u8f93\u51fa\u662fNone\u3002 print ( lambda : None ) # at 0x7fa5c4097670> lambda **kwargs: 1 \u8f93\u5165\u662f\u4efb\u610f\u952e\u503c\u5bf9\u53c2\u6570\uff0c\u8f93\u51fa\u662f1\u3002 print ( lambda ** kwargs : 1 ) # at 0x7fa5c4097670> 2. \u5185\u7f6e\u5e8f\u5217\u51fd\u6570enumerate \u00b6 \u5f53\u9700\u8981\u5bf9\u6570\u636e\u5efa\u7acb\u7d22\u5f15\u65f6\uff0c\u4e00\u79cd\u6709\u6548\u7684\u6a21\u5f0f\u5c31\u662f\u4f7f\u7528enumerate\u6784\u9020\u4e00\u4e2a\u5b57\u5178\uff0c\u5c06\u5e8f\u5217\u503c\uff08\u5047\u8bbe\u662f\u552f\u4e00\u7684\uff09\u6620\u5c04\u5230\u7d22\u5f15\u4f4d\u7f6e\u4e0a\u3002 seasons = [ 'Spring' , 'Summer' , 'Fall' , 'Winter' ] print ( list ( enumerate ( seasons ))) # [(0, 'Spring'), (1, 'Summer'), (2, 'Fall'), (3, 'Winter')] \u5bf9\u6bd4\u4e0b\u97622\u4e2a\u5faa\u73af a_list = [ 'foo' , 'bar' , 'baz' ] mapping = {} for i , v in enumerate ( a_list ): # enumerate\u751f\u6210\u7d22\u5f15\u503ci\u548c\u5e8f\u5217\u503cv mapping [ v ] = i print ( mapping ) # {'foo': 0, 'bar': 1, 'baz': 2} i = 0 mapping = {} for v in a_list : print ( i , a_list [ i ]) mapping [ v ] = i # \u53ef\u4ee5\u628ai\u548cv\u4e92\u6362 i += 1 print ( mapping ) # {'foo': 0, 'bar': 1, 'baz': 2} \u5229\u7528 enumerate() \u6279\u91cf\u4fee\u6539\u5217\u8868\u5185\u7684\u5143\u7d20 a_list = [ '01' , '02' , '03' ] unit_element = '1' for i , element in enumerate ( a_list ): a_list [ i ] = unit_element + element print ( a_list ) # ['101', '102', '103'] sorted\u51fd\u6570\u8fd4\u56de\u4e00\u4e2a\u6839\u636e\u4efb\u610f\u5e8f\u5217\u4e2d\u7684\u5143\u7d20\u65b0\u5efa\u7684\u5df2\u6392\u5e8f\u5217\u8868\u3002sorted\u51fd\u6570\u63a5\u53d7\u7684\u53c2\u6570\u4e0e\u5217\u8868\u7684sort\u65b9\u6cd5\u4e00\u81f4\u3002 y = sorted ([ 7 , 1 , 2 , 6 , 0 , 3 , 2 ]) print ( y ) # [0, 1, 2, 2, 3, 6, 7] \u7ed3\u679c\u5df2\u6392\u5e8f z = sorted ( 'Hello World' ) print ( z ) # [' ', 'H', 'W', 'd', 'e', 'l', 'l', 'l', 'o', 'o', 'r'] zip\u5c06\u5217\u8868\u3001\u5143\u7ec4\u6216\u5176\u4ed6\u5e8f\u5217\u7684\u5143\u7d20\u914d\u5bf9\uff0c\u65b0\u5efa\u4e00\u4e2a\u5143\u7ec4\u6784\u6210\u7684\u5217\u8868\u3002 seq1 = [ 'foo' , 'bar' , 'baz' ] seq2 = [ 'one' , 'two' , 'three' ] seq3 = [ False , True ] zipped = zip ( seq1 , seq2 ) print ( list ( zipped )) # [('foo', 'one'), ('bar', 'two'), ('baz', 'three')] zipped = zip ( seq1 , seq2 , seq3 ) print ( list ( zipped )) # [('foo', 'one', False), ('bar', 'two', True)] for i , ( a , b ) in enumerate ( zip ( seq1 , seq2 )): print ( ' {0} : {1} , {2} ' . format ( i , a , b )) # \u65b9\u6cd51 {0}\u5217\u8868\u5143\u7d20\u7684\u7d22\u5f15, {1}\u5143\u7ec4\u4e2d\u7b2c\u4e00\u4e2a\u503c, {2}\u5143\u7ec4\u4e2d\u7b2c\u4e8c\u4e2a\u503c print ( f ' { i } : { a } , { b } ' ) # \u65b9\u6cd52 # 0: foo, one # 1: bar, two # 2: baz, three \u7ed9\u5b9a\u4e00\u4e2a\u5df2\u201c\u914d\u5bf9\u201d\u7684\u5e8f\u5217\u65f6\uff0czip\u51fd\u6570\u53ef\u4ee5\u53bb\u201c\u62c6\u5206\u201d\u5e8f\u5217\u3002\u8fd9\u79cd\u65b9\u5f0f\u7684\u53e6\u4e00\u79cd\u601d\u8def\u5c31\u662f\u5c06\u884c\u7684\u5217\u8868\u8f6c\u6362\u4e3a\u5217\u7684\u5217\u8868\u3002\u53c2\u8003Python\u7684 Unpacking pitchers = [( 'Jack' , 'Ma' ), ( 'Tom' , 'Li' ), ( 'Jimmy' , 'Zhang' )] first_names , last_names = zip ( * pitchers ) print ( first_names ) # ('Jack', 'Tom', 'Jimmy') print ( last_names ) # ('Ma', 'Li', 'Zhang') reversed\u51fd\u6570\u5c06\u5e8f\u5217\u7684\u5143\u7d20\u5012\u5e8f\u6392\u5217 print ( list ( reversed ( range ( 10 )))) # [9, 8, 7, 6, 5, 4, 3, 2, 1, 0] 3. \u5217\u8868\u3001\u96c6\u5408\u548c\u5b57\u5178\u7684\u63a8\u5bfc\u5f0f \u00b6 \u63a8\u5bfc\u5f0fcomprehensions\uff08\u53c8\u79f0\u89e3\u6790\u5f0f\uff09\uff0c\u662fPython\u7684\u4e00\u79cd\u7279\u6027\u3002\u4f7f\u7528\u63a8\u5bfc\u5f0f\u53ef\u4ee5\u5feb\u901f\u751f\u6210\u5217\u8868\u3001\u5143\u7ec4\u3001\u96c6\u5408\u3001\u5b57\u5178\u7c7b\u578b\u7684\u6570\u636e\u3002\u63a8\u5bfc\u5f0f\u53c8\u5206\u4e3a\u5217\u8868\u63a8\u5bfc\u5f0f\u3001\u5143\u7ec4\u63a8\u5bfc\u5f0f\u3001\u96c6\u5408\u63a8\u5bfc\u5f0f\u3001\u5b57\u5178\u63a8\u5bfc\u5f0f\u3002 \u5217\u8868\u63a8\u5bfc\u5f0f(list comprehension) \u00b6 \u5217\u8868\u63a8\u5bfc\u5f0f(list comprehension)\u5141\u8bb8\u4f60\u8fc7\u6ee4\u4e00\u4e2a\u5bb9\u5668\u7684\u5143\u7d20\uff0c\u7528\u4e00\u79cd\u7b80\u660e\u7684\u8868\u8fbe\u5f0f\u8f6c\u6362\u4f20\u9012\u7ed9\u8fc7\u6ee4\u5668\u7684\u5143\u7d20\uff0c\u4ece\u800c\u751f\u6210\u4e00\u4e2a\u65b0\u7684\u5217\u8868\u3002 \u5217\u8868\u63a8\u5bfc\u5f0f\u7684\u57fa\u672c\u5f62\u5f0f\u4e3a\uff1a[expr for val in collection if condition]\uff0c\u6761\u4ef6if-condition\u4e0d\u662f\u5fc5\u987b\u7684\uff0c\u53ef\u4ee5\u53ea\u4fdd\u7559\u8868\u8fbe\u5f0f\u3002\u5217\u8868\u63a8\u5bfc\u5f0f\u4e0e\u4e0b\u9762\u7684for\u5faa\u73af\u662f\u7b49\u4ef7\u7684\uff1a result = [] for val in collection : if condition : result . append ( expr ) \u770b\u4e0b\u9762\u7684\u4f8b\u5b50\uff1a data = [] for i in range ( - 5 , 5 ): if i >= - 1 : data . append ( i ** 2 ) print ( data ) # [1, 0, 1, 4, 9, 16] data = [ i ** 2 for i in range ( - 5 , 5 ) if i >= - 1 ] print ( data ) # [1, 0, 1, 4, 9, 16] \u4e0b\u9762\u7684\u4f8b\u5b50\u662f\u4f7f\u7528for\u53bb\u904d\u5386\u4e00\u4e2a\u53ef\u8fed\u4ee3\u7684\u5217\u8868\u3002 data = [] fruit = [ 'pomegranate' , 'cherry' , 'apricot' , 'date' , 'Apple' , 'lemon' , 'kiwi' , 'ORANGE' , 'lime' , 'Watermelon' , 'guava' , 'papaya' , 'FIG' , 'pear' , 'banana' , 'Tamarind' , 'persimmon' , 'elderberry' , 'peach' , 'BLUEberry' , 'lychee' , 'grape' ] data = [ x . upper () if x . startswith ( 'p' ) else x . title () for x in fruit ] print ( data ) # ['POMEGRANATE', 'Cherry', 'Apricot', 'Date', 'Apple', 'Lemon', 'Kiwi', 'Orange', 'Lime', 'Watermelon', 'Guava', 'PAPAYA', 'Fig', 'PEAR', 'Banana', 'Tamarind', 'PERSIMMON', 'Elderberry', 'PEACH', 'Blueberry', 'Lychee', 'Grape'] \u5957\u5217\u8868\u63a8\u5bfc\u5f0f \u00b6 \u4e0b\u9762\u7684\u4f8b\u5b50\u662f\u7528\u5d4c\u5957\u5217\u8868\u63a8\u5bfc\u5f0f\u4ee3\u66ff2\u5c42for\u5faa\u73af\u3002 data = [] for i in range ( 1 , 3 ): if i >= 0 : for j in range ( 1 , 3 ): data . append (( i , j )) print ( data ) # [(1, 1), (1, 2), (2, 1), (2, 2)] data = [( i , j ) for i in range ( 1 , 3 ) if i >= - 1 for j in range ( 1 , 3 )] print ( data ) # [(1, 1), (1, 2), (2, 1), (2, 2)] \u518d\u4e3e\u4e00\u4e2a\u5d4c\u5957\u5217\u8868\u63a8\u5bfc\u5f0f\u7684\u4f8b\u5b50\u3002 all_data = [ [ 'John' , 'Emily' , 'Michael' , 'Lee' , 'Steven' ], [ 'Maria' , 'Juan' , 'Javier' , 'Natalia' , 'Pilar' ], ] names_of_interest = [] for names in all_data : enough_es = [ name for name in names if name . count ( 'e' ) >= 2 ] names_of_interest . extend ( enough_es ) print ( names_of_interest ) # ['Lee', 'Steven'] result = [ name for names in all_data for name in names if name . count ( 'e' ) >= 2 ] print ( result ) # ['Lee', 'Steven'] \u7528\u5d4c\u5957\u5217\u8868\u63a8\u5bfc\u5f0f\u5c06\u77e9\u9635\u6241\u5e73\u5316\u3002 \u8003\u8651\u4e0b\u9762\u8fd9\u4e2a3x4\u7684\u77e9\u9635\uff0c\u5b83\u75313\u4e2a\u957f\u5ea6\u4e3a4\u7684\u5217\u8868\u7ec4\u6210\u3002\u4e0b\u9762\u4f8b\u5b50\u5bf9\u6bd4\u4e86\u7528\u4f20\u7edffor\u5faa\u73af\u5c06\u77e9\u9635\u6241\u5e73\u5316\uff0c\u548c\u7528\u5d4c\u5957\u5217\u8868\u63a8\u5bfc\u5f0f\u5c06\u77e9\u9635\u6241\u5e73\u5316\u3002\u5e76\u4e14\u901a\u8fc7\u5217\u8868\u63a8\u5bfc\u5f0f\u4e2d\u7684\u5217\u8868\u63a8\u5bfc\u5f0f\u5c06\u6241\u5e73\u77e9\u9635\u8fd8\u539f\u4e3a3x4\u77e9\u9635\u3002 matrix = [ [ 1 , 2 , 3 , 4 ], [ 5 , 6 , 7 , 8 ], [ 9 , 10 , 11 , 12 ], ] flattened = [] # \u4f20\u7edffor\u5faa\u73af\u5d4c\u5957 for m in matrix : for x in m : flattened . append ( x ) print ( flattened ) # [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12] # \u5d4c\u5957\u5217\u8868\u63a8\u5bfc\u5f0f flattened = [ x for m in matrix for x in m ] print ( flattened ) # [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12] # \u5217\u8868\u63a8\u5bfc\u5f0f\u4e2d\u7684\u5217\u8868\u63a8\u5bfc\u5f0f z = [[ x for x in m ] for m in matrix ] print ( z ) # [[1, 2, 3, 4], [5, 6, 7, 8], [9, 10, 11, 12]] \u5143\u7ec4\u63a8\u5bfc\u5f0f \u00b6 \u4e0b\u9762\u7684\u4f8b\u5b50\u751f\u6210\u4e00\u4e2a\u5305\u542b\u6570\u5b571~5\u7684\u5143\u7ec4\u3002\u4ece\u7ed3\u679c\u53ef\u4ee5\u770b\u5230\uff0c\u5143\u7ec4\u63a8\u5bfc\u5f0f\u751f\u6210\u7684\u7ed3\u679c\u5e76\u4e0d\u662f\u4e00\u4e2a\u5143\u7ec4\uff0c\u800c\u662f\u4e00\u4e2a\u751f\u6210\u5668\u5bf9\u8c61\uff0c\u9700\u8981\u901a\u8fc7tuple()\u51fd\u6570\uff0c\u5c06\u751f\u6210\u5668\u5bf9\u8c61\u8f6c\u6362\u6210\u5143\u7ec4\u3002 data = ( x for x in range ( 5 )) print ( data ) # at 0x7f87217a8e40> print ( type ( data )) # print ( tuple ( data )) # (0, 1, 2, 3, 4) \u96c6\u5408\u63a8\u5bfc\u5f0f \u00b6 \u4e0b\u9762\u662f\u4e00\u4e2a\u7b80\u5355\u7684\u96c6\u5408\u63a8\u5bfc\u5f0f\u4f8b\u5b50\u3002 data = { x ** 2 for x in range ( 5 )} print ( data ) # {0, 1, 4, 9, 16} print ( type ( data )) # \u96c6\u5408\u8981\u4fdd\u8bc1\u5143\u7d20\u5fc5\u987b\u662f\u552f\u4e00\u7684\u3002 data = ( 1 , 1 , 2 , 2 , 3 , 3 , 4 , 5 , 6 ) newset = { x ** 2 for x in data } print ( newset ) # {1, 4, 36, 9, 16, 25} print ( type ( newset ) # \u5b57\u5178\u63a8\u5bfc\u5f0f \u00b6 \u5b57\u5178\u63a8\u5bfc\u5f0f: dict_comp = {key-expr : value-expr for value in collection if condition} \u5b57\u5178\u63a8\u5bfc\u5f0f\u7684\u7b80\u5355\u793a\u4f8b\uff1a strings = [ 'a' , 'as' , 'bat' , 'car' , 'dove' , 'python' ] loc_mapping = { index : val for index , val in enumerate ( strings )} print ( loc_mapping ) # {0: 'a', 1: 'as', 2: 'bat', 3: 'car', 4: 'dove', 5: 'python'} # \u4ea4\u6362\u952e\u548c\u503c loc_mapping = { index : val for val , index in enumerate ( strings )} print ( loc_mapping ) # {'a': 0, 'as': 1, 'bat': 2, 'car': 3, 'dove': 4, 'python': 5} 4. \u51fd\u6570\u58f0\u660e \u00b6 \u5982\u679cPython\u8fbe\u5230\u51fd\u6570\u7684\u5c3e\u90e8\u65f6\u4ecd\u7136\u6ca1\u6709\u9047\u5230return\u8bed\u53e5\uff0c\u5c31\u4f1a\u81ea\u52a8\u8fd4\u56deNone\u3002 \u6bcf\u4e2a\u51fd\u6570\u90fd\u53ef\u4ee5\u6709\u4f4d\u7f6e\u53c2\u6570\u548c\u5173\u952e\u5b57\u53c2\u6570\u3002\u5173\u952e\u5b57\u53c2\u6570\u6700\u5e38\u7528\u4e8e\u6307\u5b9a\u9ed8\u8ba4\u503c\u6216\u53ef\u9009\u53c2\u6570\u3002\u5173\u952e\u5b57\u53c2\u6570\u5fc5\u987b\u8ddf\u5728\u4f4d\u7f6e\u53c2\u6570\u540e\uff0c\u53ef\u4ee5\u4f7f\u7528\u5173\u952e\u5b57\u53c2\u6570\u5411\u4f4d\u7f6e\u53c2\u6570\u4f20\u53c2\u3002 import sys def my_function1 ( x , y , z = 1.5 ): if z > 1 : return z * ( x + y ) else : return z / ( x + y ) result1 = my_function1 ( 5 , 6 , z = 0.7 ) print ( result1 ) # 0.06363636363636363 result1 = my_function1 ( x = 5 , y = 6 , z = 0.7 ) print ( result1 ) # 0.06363636363636363 result1 = my_function1 ( 3.14 , 7 , 3.5 ) print ( result1 ) # 35.49 result1 = my_function1 ( 10 , 20 ) print ( result1 ) # 45.0 5. \u547d\u540d\u7a7a\u95f4\u3001\u4f5c\u7528\u57df\u548c\u672c\u5730\u51fd\u6570 \u00b6 \u51fd\u6570\u6709\u4e24\u79cd\u8fde\u63a5\u53d8\u91cf\u7684\u65b9\u5f0f\uff1a\u5168\u5c40\u3001\u672c\u5730\u3002 def func1 (): list1 = [] # \u672c\u5730\u53d8\u91cf for i in range ( 5 ): list1 . append ( i ) print ( list1 ) func1 () # [0, 1, 2, 3, 4] list2 = [] # \u5168\u5c40\u53d8\u91cf def func2 (): global list2 # \u5168\u5c40\u53d8\u91cf for i in range ( 5 ): list2 . append ( i ) print ( list2 ) func2 () # [0, 1, 2, 3, 4] \u6570\u636e\u6e05\u6d17\u793a\u4f8b states = [ ' Alabama' , 'Georgia!' , 'georgia' , 'Georgia' , 'FlOrIda' , 'south carolina##' , 'West virginia? ' ] # \u65b9\u6cd51 import re def clean_string1 ( strings ): result2 = [] for value in strings : value = value . strip () value = re . sub ( '[! #? ]' , '' , value ) value = value . title () result2 . append ( value ) return result2 print ( clean_string1 (( states ))) # ['Alabama', 'Georgia', 'Georgia', 'Georgia', 'Florida', 'Southcarolina', 'Westvirginia'] # \u65b9\u6cd52 def remove_punctuaion ( value ): return re . sub ( '[! #? ]' , '' , value ) clean_ops = [ str . strip , remove_punctuaion , str . title ] def clean_string2 ( strings , ops ): result3 = [] for value in strings : for function in ops : value = function ( value ) result3 . append ( value ) return result3 result4 = clean_string2 ( states , clean_ops ) print ( result4 ) # ['Alabama', 'Georgia', 'Georgia', 'Georgia', 'Florida', 'Southcarolina', 'Westvirginia'] # \u53ef\u4ee5\u5c06\u51fd\u6570\u4f5c\u4e3a\u4e00\u4e2a\u53c2\u6570\u4f20\u7ed9\u5176\u4ed6\u7684\u51fd\u6570\u3002 for x in map ( remove_punctuaion , states ): print ( x ) # Alabama # Georgia # georgia # Georgia # FlOrIda # southcarolina # Westvirginia 6. \u67ef\u91cc\u5316\uff1a\u90e8\u5206\u53c2\u6570\u5e94\u7528 \u00b6 \u67ef\u91cc\u5316\u662f\u8ba1\u7b97\u673a\u79d1\u5b66\u672f\u8bed\uff08\u4ee5\u6570\u5b66\u5bb6Haskell Curry\u547d\u540d\uff09\uff0c\u5b83\u8868\u793a\u901a\u8fc7\u90e8\u5206\u53c2\u6570\u5e94\u7528\u7684\u65b9\u5f0f\u4ece\u5df2\u6709\u7684\u51fd\u6570\u4e2d\u884d\u751f\u51fa\u65b0\u7684\u51fd\u6570\u3002\u67ef\u91cc\u5316\u662f\u4e00\u79cd\u5c06\u591a\u53c2\u6570\u51fd\u6570\u8f6c\u5316\u4e3a\u5355\u53c2\u6570\u9ad8\u9636\u51fd\u6570\u7684\u6280\u672f\uff0c\u5982\u679c\u4f60\u56fa\u5b9a\u67d0\u4e9b\u53c2\u6570\uff0c\u4f60\u5c06\u5f97\u5230\u63a5\u53d7\u4f59\u4e0b\u53c2\u6570\u7684\u4e00\u4e2a\u51fd\u6570\u3002 \u5b9a\u4e49\u4e00\uff1a \u67ef\u91cc\u5316\uff1a\u4e00\u4e2a\u51fd\u6570\u4e2d\u6709\u4e2a\u591a\u4e2a\u53c2\u6570\uff0c\u60f3\u56fa\u5b9a\u5176\u4e2d\u67d0\u4e2a\u6216\u8005\u51e0\u4e2a\u53c2\u6570\u7684\u503c\uff0c\u800c\u53ea\u63a5\u53d7\u53e6\u5916\u51e0\u4e2a\u8fd8\u672a\u56fa\u5b9a\u7684\u53c2\u6570\uff0c\u8fd9\u6837\u51fd\u6570\u6f14\u53d8\u6210\u65b0\u7684\u51fd\u6570\u3002 \u5b9a\u4e49\u4e8c\uff1a \u51fd\u6570\u67ef\u91cc\u5316\uff08currying\uff09\u53c8\u79f0\u90e8\u5206\u6c42\u503c\u3002\u4e00\u4e2a currying \u7684\u51fd\u6570\u9996\u5148\u4f1a\u63a5\u53d7\u4e00\u4e9b\u53c2\u6570\uff0c\u63a5\u53d7\u4e86\u8fd9\u4e9b\u53c2\u6570\u4e4b\u540e\uff0c\u8be5\u51fd\u6570\u5e76\u4e0d\u4f1a\u7acb\u5373\u6c42\u503c\uff0c\u800c\u662f\u7ee7\u7eed\u8fd4\u56de\u53e6\u5916\u4e00\u4e2a\u51fd\u6570\uff0c\u521a\u624d\u4f20\u5165\u7684\u53c2\u6570\u5728\u51fd\u6570\u5f62\u6210\u7684\u95ed\u5305\u4e2d\u88ab\u4fdd\u5b58\u8d77\u6765\u3002\u5f85\u5230\u51fd\u6570\u88ab\u771f\u6b63\u9700\u8981\u6c42\u503c\u7684\u65f6\u5019\uff0c\u4e4b\u524d\u4f20\u5165\u7684\u6240\u6709\u53c2\u6570\u90fd\u4f1a\u88ab\u4e00\u6b21\u6027\u7528\u4e8e\u6c42\u503c\u3002 \u5b9a\u4e49\u4e09\uff1a \u4e00\u4e9b\u51fd\u6570\u5f0f\u8bed\u8a00\u7684\u5de5\u4f5c\u539f\u7406\u662f\u5c06\u591a\u53c2\u6570\u51fd\u6570\u8bed\u6cd5\u8f6c\u5316\u4e3a\u5355\u53c2\u6570\u51fd\u6570\u96c6\u5408\uff0c\u8fd9\u4e00\u8fc7\u7a0b\u79f0\u4e3a\u67ef\u91cc\u5316\uff0c\u5b83\u662f\u4ee5\u903b\u8f91\u5b66\u5bb6Haskell Curry\u7684\u540d\u5b57\u547d\u540d\u7684\u3002Haskell Curry\u4ece\u65e9\u671f\u6982\u5ff5\u4e2d\u53d1\u5c55\u51fa\u4e86\u8be5\u7406\u8bba\u3002\u5176\u5f62\u5f0f\u76f8\u5f53\u4e8e\u5c06z=f(x, y)\u8f6c\u6362\u6210z=f(x)(y)\u7684\u5f62\u5f0f\uff0c\u539f\u51fd\u6570\u7531\u4e24\u4e2a\u53c2\u6570\uff0c\u73b0\u5728\u53d8\u4e3a\u4e24\u4e2a\u63a5\u53d7\u5355\u53c2\u6570\u7684\u51fd\u6570\uff0c \u793a\u4f8b1\uff1a\u67ef\u91cc\u5316\u7684\u8fc7\u7a0b\u5c31\u662f\u628a\u539f\u6765\u5e26\u4e24\u4e2a\u53c2\u6570\u7684\u51fd\u6570add(x, y)\uff0c\u53d8\u6210\u4e86\u4e00\u4e2a\u5d4c\u5957\u51fd\u6570\uff0c\u5728add_currying\u51fd\u6570\u5185\uff0c\u53c8\u5b9a\u4e49\u4e86\u4e00\u4e2a_add\u51fd\u6570\uff0c\u5e76\u4e14_add\u51fd\u6570\u53c8\u5f15\u7528\u4e86\u5916\u90e8\u51fd\u6570add_currying\u7684\u53d8\u91cfx\uff0c\u8fd9\u5c31\u662f\u4e00\u4e2a\u95ed\u5305\u3002 \u95ed\u5305\uff0c\u4e00\u53e5\u8bdd\u8bf4\u5c31\u662f\u5728\u51fd\u6570\u4e2d\u518d\u5d4c\u5957\u4e00\u4e2a\u51fd\u6570\uff0c\u5e76\u4e14\u5f15\u7528\u5916\u90e8\u51fd\u6570\u7684\u53d8\u91cf\u3002 # \u666e\u901a\u5199\u6cd5 def add ( x , y ): return x + y print ( add ( 1 , 2 )) # 3 # \u67ef\u91cc\u5316\u5199\u6cd5 def add_currying ( x ): def _add ( y ): return x + y return _add print ( add_currying ( 1 )( 2 )) # 3 \u793a\u4f8b2\uff0c\u901a\u8fc7\u56fa\u5b9a\u5176\u4e2d\u7684\u7b2c\u4e8c\u4e2a\u53c2\u6570\u4e0d\u53d8\u6765\u5b9e\u73b0\u67ef\u91cc\u5316\u3002 def add2 ( a , b ): def add1 ( a , b , c ): return a + b + c return add1 ( a , 666 , b ) result6 = add2 ( 12 , 13 ) print ( result6 ) # 691 result6 = add2 ( 12 , 555 , 13 ) # TypeError: add2() takes 2 positional arguments but 3 were given \u793a\u4f8b3\uff0c\u901a\u8fc7functools\u63d0\u4f9b\u7684\u504f\u51fd\u6570\u6765\u5b9e\u73b0\u67ef\u91cc\u5316\u3002 from functools import partial def add1 ( a , b , c ): return a + b + c add3 = partial ( add1 , b = 666 ) result7 = add3 ( a = 12 , c = 13 ) print ( result7 ) # 691 \u793a\u4f8b4\uff0c\u901a\u8fc7lambda\u8868\u8fbe\u5f0f\u6765\u5b9e\u73b0\u67ef\u91cc\u5316\u3002 def add1 ( a , b , c ): return a + b + c add4 = lambda x , y : add1 ( x , 666 , y ) result8 = add4 ( 12 , 13 ) print ( result8 ) # 691 \u793a\u4f8b5\uff0c\u901a\u8fc7python\u7684\u88c5\u9970\u5668\u6765\u5b9e\u73b0\u67ef\u91cc\u5316 def add1 ( a , b , c ): return a + b + c def currying_add ( func ): def wrapper ( a , c , b = 666 ): return func ( a , b , c ) return wrapper result9 = currying_add ( add1 )( 12 , 13 ) print ( result9 ) # 691 \u793a\u4f8b6\uff0c\u901a\u8fc7python\u7684\u88c5\u9970\u5668\u7b26\u53f7@\u6765\u5b9e\u73b0\u67ef\u91cc\u5316 def currying_add ( func ): def wrapper ( a , c , b = 666 ): return func ( a , b , c ) return wrapper @currying_add def add5 ( a , b , c ): return a + b + c result10 = add5 ( 12 , 13 ) print ( result10 ) # 691 7. \u8fed\u4ee3\u5668\u4e0e\u751f\u6210\u5668 \u00b6 \u8fed\u4ee3\u5668 \u00b6 \u8fed\u4ee3\u662fPython\u6700\u5f3a\u5927\u7684\u529f\u80fd\u4e4b\u4e00\uff0c\u662f\u8bbf\u95ee\u96c6\u5408\u5143\u7d20\u7684\u4e00\u79cd\u65b9\u5f0f\u3002\u8fed\u4ee3\u5668\u662f\u4e00\u4e2a\u53ef\u4ee5\u8bb0\u4f4f\u904d\u5386\u7684\u4f4d\u7f6e\u7684\u5bf9\u8c61\u3002 \u8fed\u4ee3\u5668\u5bf9\u8c61\u4ece\u96c6\u5408\u7684\u7b2c\u4e00\u4e2a\u5143\u7d20\u5f00\u59cb\u8bbf\u95ee\uff0c\u76f4\u5230\u6240\u6709\u7684\u5143\u7d20\u88ab\u8bbf\u95ee\u5b8c\u7ed3\u675f\u3002\u8fed\u4ee3\u5668\u53ea\u80fd\u5f80\u524d\u4e0d\u4f1a\u540e\u9000\u3002 \u8fed\u4ee3\u5668\u6709\u4e24\u4e2a\u57fa\u672c\u7684\u65b9\u6cd5\uff1aiter() \u548c next()\u3002 \u8fed\u4ee3\u5668\u793a\u4f8b\uff1a list_a = [ 1 , 2 , 3 , 4 ] it = iter ( list_a ) # \u521b\u5efa\u8fed\u4ee3\u5668\u5bf9\u8c61 print ( next ( it )) # \u8f93\u51fa\u8fed\u4ee3\u5668\u7684\u4e0b\u4e00\u4e2a\u5143\u7d20 # 1 print ( next ( it )) # \u8f93\u51fa\u8fed\u4ee3\u5668\u7684\u4e0b\u4e00\u4e2a\u5143\u7d20 # 2 \u8fed\u4ee3\u5668\u5bf9\u8c61\u53ef\u4ee5\u4f7f\u7528\u5e38\u89c4for\u8bed\u53e5\u8fdb\u884c\u904d\u5386\u3002 list_a = [ 1 , 2 , 3 , 4 ] it = iter ( list_a ) # \u521b\u5efa\u8fed\u4ee3\u5668\u5bf9\u8c61 for x in it : print ( x , end = \" \" ) print ( end = \" \\n \" ) # 1 2 3 4 \u751f\u6210\u5668 \u00b6 \u5728 Python \u4e2d\uff0c\u4f7f\u7528\u4e86 yield \u7684\u51fd\u6570\u88ab\u79f0\u4e3a\u751f\u6210\u5668\uff08generator\uff09\u3002\u8ddf\u666e\u901a\u51fd\u6570\u4e0d\u540c\u7684\u662f\uff0c\u751f\u6210\u5668\u662f\u4e00\u4e2a\u8fd4\u56de\u8fed\u4ee3\u5668\u7684\u51fd\u6570\uff0c\u53ea\u80fd\u7528\u4e8e\u8fed\u4ee3\u64cd\u4f5c\uff0c\u751f\u6210\u5668\u5c31\u662f\u4e00\u4e2a\u8fed\u4ee3\u5668\u3002 \u5728\u8c03\u7528\u751f\u6210\u5668\u8fd0\u884c\u7684\u8fc7\u7a0b\u4e2d\uff0c\u6bcf\u6b21\u9047\u5230 yield \u65f6\u51fd\u6570\u4f1a\u6682\u505c\u5e76\u4fdd\u5b58\u5f53\u524d\u6240\u6709\u7684\u8fd0\u884c\u4fe1\u606f\uff0c\u8fd4\u56de yield \u7684\u503c, \u5e76\u5728\u4e0b\u4e00\u6b21\u6267\u884c next() \u65b9\u6cd5\u65f6\u4ece\u5f53\u524d\u4f4d\u7f6e\u7ee7\u7eed\u8fd0\u884c\u3002 \u8c03\u7528\u4e00\u4e2a\u751f\u6210\u5668\u51fd\u6570\uff0c\u8fd4\u56de\u7684\u662f\u4e00\u4e2a\u8fed\u4ee3\u5668\u5bf9\u8c61\u3002 \u793a\u4f8b, \u6590\u6ce2\u90a3\u5951\u6570\u5217\uff1a def fibonacci ( n ): a , b , counter = 0 , 1 , 0 while True : if ( counter > n ): return yield a a , b = b , a + b counter += 1 f = fibonacci ( 10 ) # f \u662f\u4e00\u4e2a\u8fed\u4ee3\u5668\uff0c\u7531\u751f\u6210\u5668\u8fd4\u56de\u751f\u6210 print ( f ) # \u5b9e\u9645\u8c03\u7528\u751f\u6210\u5668\u65f6\uff0c\u4ee3\u7801\u5e76\u4e0d\u4f1a\u7acb\u5373\u6267\u884c for x in f : # \u8bf7\u6c42\u751f\u6210\u5668\u4e2d\u7684\u5143\u7d20\u65f6\uff0c\u5b83\u624d\u4f1a\u6267\u884c\u5b83\u7684\u4ee3\u7801 print ( x , end = \" \" ) print ( end = \" \\n \" ) # 0 1 1 2 3 5 8 13 21 34 55 \u751f\u6210\u5668\u8868\u8fbe\u5f0f\uff1a \u7528\u751f\u6210\u5668\u8868\u8fbe\u5f0f\u6765\u521b\u5efa\u751f\u6210\u5668\u66f4\u4e3a\u7b80\u5355\u3002\u751f\u6210\u5668\u8868\u8fbe\u5f0f\u4e0e\u5217\u8868\u3001\u5b57\u5178\u3001\u96c6\u5408\u7684\u63a8\u5bfc\u5f0f\u5f88\u7c7b\u4f3c\uff0c\u521b\u5efa\u4e00\u4e2a\u751f\u6210\u5668\u8868\u8fbe\u5f0f\uff0c\u53ea\u9700\u8981\u5c06\u5217\u8868\u63a8\u5bfc\u5f0f\u7684\u4e2d\u62ec\u53f7\u66ff\u6362\u4e3a\u5c0f\u62ec\u53f7\u5373\u53ef\u3002 gen1 = ( x ** 2 for x in range ( 100 )) print ( gen1 ) # at 0x7fd3f30c9580> \u4e0a\u9762\u7684\u4ee3\u7801\u4e0e\u4e0b\u9762\u7684\u751f\u6210\u5668\u662f\u7b49\u4ef7\u7684 def _make_gen (): for x in range ( 100 ): yield x ** 2 gen2 = _make_gen () print ( gen2 ) # \u751f\u6210\u5668\u8868\u8fbe\u5f0f\u53ef\u4ee5\u4f5c\u4e3a\u51fd\u6570\u53c2\u6570\u7528\u4e8e\u66ff\u4ee3\u5217\u8868\u63a8\u5bfc\u5f0f\u3002\u5bf9\u6bd4\u4e0b\u97622\u4e2a\u4f8b\u5b50\u3002 # \u793a\u4f8b1 result11 = sum ( x ** 2 for x in range ( 100 )) print ( result11 ) # 328350 gen1 = ( x ** 2 for x in range ( 100 )) result11 = sum ( gen1 ) print ( result11 ) # 328350 # \u793a\u4f8b2 result12 = dict (( i , i ** 2 ) for i in range ( 5 )) print ( result12 ) # {0: 0, 1: 1, 2: 4, 3: 9, 4: 16} gen2 = (( i , i ** 2 ) for i in range ( 5 )) result12 = dict ( gen2 ) print ( result12 ) # {0: 0, 1: 1, 2: 4, 3: 9, 4: 16} \u751f\u6210\u5668\uff1aitertools\u6a21\u5757 \u00b6 \u6807\u51c6\u5e93\u4e2d\u7684itertools\u6a21\u5757\u662f\u9002\u7528\u4e8e\u5927\u591a\u6570\u6570\u636e\u7b97\u6cd5\u7684\u751f\u6210\u5668\u96c6\u5408\u3002 import itertools first_letter = lambda x : x [ 0 ] names = [ 'Alan' , 'Adam' , 'Wes' , 'Will' , 'Albert' , 'Steven' ] for letter , names in itertools . groupby ( names , first_letter ): print ( letter ) print ( first_letter ) print ( letter , list ( names )) # names is generator # A # at 0x7fa598a7a0d0> # A ['Alan', 'Adam'] # W # at 0x7fa598a7a0d0> # W ['Wes', 'Will'] # A # at 0x7fa598a7a0d0> # A ['Albert'] # S # at 0x7fa598a7a0d0> # S ['Steven'] 8. \u9519\u8bef\u548c\u5f02\u5e38\u5904\u7406 \u00b6 Python\u7528\u5f02\u5e38\u5bf9\u8c61(exception object)\u6765\u8868\u793a\u5f02\u5e38\u60c5\u51b5\u3002\u9047\u5230\u9519\u8bef\u540e\uff0c\u4f1a\u5f15\u53d1\u5f02\u5e38\u3002\u5982\u679c\u5f02\u5e38\u5bf9\u8c61\u5e76\u672a\u88ab\u5904\u7406\u6216\u6355\u6349\uff0c\u7a0b\u5e8f\u5c31\u4f1a\u7528\u6240\u8c13\u7684\u56de\u6eaf(traceback\uff0c \u4e00\u79cd\u9519\u8bef\u4fe1\u606f)\u7ec8\u6b62\u6267\u884c\u3002 \u5f02\u5e38\u548c\u8bed\u6cd5\u9519\u8bef\u662f\u6709\u533a\u522b\u7684\u3002 \u9519\u8bef\uff1a\u662f\u6307\u4ee3\u7801\u4e0d\u7b26\u5408\u89e3\u91ca\u5668\u6216\u8005\u7f16\u8bd1\u5668\u8bed\u6cd5\u3002 \u5f02\u5e38\uff1a\u662f\u6307\u4e0d\u5b8c\u6574\u3001\u4e0d\u5408\u6cd5\u8f93\u5165\uff0c\u6216\u8005\u8ba1\u7b97\u51fa\u73b0\u9519\u8bef\u3002 python\u91cc\u7528try...except...\u8bed\u53e5\u6765\u5904\u7406\u5f02\u5e38\u60c5\u51b5\u3002 def attempt_float ( x ): try : return float ( x ) except ( TypeError , ValueError ): return \"Type error, not numbers\" r1 = attempt_float ( '1.2256' ) print ( r1 ) # 1.2256 r1 = attempt_float ( 'friends' ) print ( r1 ) # Type error, not numbers 9. \u6587\u4ef6\u4e0e\u64cd\u4f5c\u7cfb\u7edf \u00b6 f=open(path, 'w')\uff0c\u4e00\u4e2a\u65b0\u7684\u6587\u4ef6\u4f1a\u5728path\u6307\u5b9a\u7684\u8def\u5f84\u88ab\u521b\u5efa\uff0c\u5e76\u5728\u540c\u4e00\u8def\u5f84\u4e0b\u8986\u76d6\u540c\u540d\u6587\u4ef6\u3002\uff08\u8bf7\u5c0f\u5fc3\uff01\uff09 f=open(path, 'x')\uff0c\u4e00\u4e2a\u65b0\u7684\u6587\u4ef6\u4f1a\u5728path\u6307\u5b9a\u7684\u8def\u5f84\u88ab\u521b\u5efa\uff0c\u5982\u679c\u7ed9\u5b9a\u8def\u5f84\u4e0b\u5df2\u7ecf\u5b58\u5728\u540c\u540d\u6587\u4ef6\u5c31\u4f1a\u521b\u5efa\u5931\u8d25\u3002 import os # \u67e5\u770b\u5f53\u524d\u8def\u5f84 os . getcwd () # '/opt/myMemo' # \u66f4\u6539\u6587\u4ef6\u8bfb\u53d6\u9ed8\u8ba4\u8def\u5f84 os . chdir ( '/opt/myMemo/python/datasets/examples' ) # \u6307\u5b9a\u6587\u4ef6\u540d path = 'file01.txt' # \u6253\u5f00\u6587\u4ef6 f = open ( path ) # \u8bfb\u53d6\u6587\u4ef6\u6bcf\u4e00\u884c\uff0c\u6587\u4ef6\u6bcf\u4e00\u884c\u4f5c\u4e3a\u5217\u8868\u4e00\u4e2a\u5143\u7d20 lines = [ x . rstrip () for x in open ( path )] # \u8f93\u51fa\u5217\u8868 print ( lines ) # \u5173\u95ed\u6587\u4ef6\u4f1a\u5c06\u8d44\u6e90\u91ca\u653e\u56de\u64cd\u4f5c\u7cfb\u7edf f . close () \u53e6\u4e00\u79cd\u66f4\u7b80\u5355\u7684\u5173\u95ed\u6587\u4ef6\u7684\u65b9\u5f0f import os # \u67e5\u770b\u5f53\u524d\u8def\u5f84 os . getcwd () # '/opt/myMemo' # \u66f4\u6539\u6587\u4ef6\u8bfb\u53d6\u9ed8\u8ba4\u8def\u5f84 os . chdir ( '/opt/myMemo/python/datasets/examples' ) # \u6307\u5b9a\u6587\u4ef6\u540d path = 'file01.txt' # \u6253\u5f00\u6587\u4ef6 f = open ( path ) # \u4f7f\u7528with\u8bed\u53e5\u8bfb\u53d6\u6587\u4ef6\uff0c\u6587\u4ef6\u4f1a\u5728with\u4ee3\u7801\u5757\u7ed3\u675f\u540e\u81ea\u52a8\u5173\u95ed\u3002 with open ( path ) as f : lines = [ x . rstrip () for x in open ( path )] # \u8f93\u51fa\uff1a\u6587\u4ef6\u6bcf\u4e00\u884c\u4f5c\u4e3a\u5217\u8868\u4e00\u4e2a\u5143\u7d20 print ( lines ) \u5728\u6253\u5f00\u6587\u4ef6\u65f6\u4f7f\u7528seek\u8bfb\u53d6\u6587\u4ef6\u5185\u5bb9\u8981\u5f53\u5fc3\u3002\u5982\u679c\u6587\u4ef6\u7684\u53e5\u67c4\u4f4d\u7f6e\u6070\u597d\u5728\u4e00\u4e2aUnicode\u7b26\u53f7\u7684\u5b57\u8282\u4e2d\u95f4\u65f6\uff0c\u540e\u7eed\u7684\u8bfb\u53d6\u4f1a\u5bfc\u81f4\u9519\u8bef\u3002 import os # \u67e5\u770b\u5f53\u524d\u8def\u5f84 os . getcwd () # '/opt/myMemo' # \u66f4\u6539\u6587\u4ef6\u8bfb\u53d6\u9ed8\u8ba4\u8def\u5f84 os . chdir ( '/opt/myMemo/python/datasets/examples' ) # \u6307\u5b9a\u6587\u4ef6\u540d path = 'file01.txt' # \u6253\u5f00\u6587\u4ef6 f = open ( path ) # \u8bfb\u53d6\u6587\u4ef6\u3002 print ( f . read ( 5 )) # \u8f93\u51fa\u524d5\u4e2a\u5b57\u7b26\u3002 read\u65b9\u6cd5\u901a\u8fc7\u8bfb\u53d6\u7684\u5b57\u8282\u6570\u6765\u63a8\u8fdb\u6587\u4ef6\u53e5\u67c4\u7684\u4f4d\u7f6e\u3002 # I Thi print ( f . tell ()) # tell\u65b9\u6cd5\u53ef\u4ee5\u7ed9\u51fa\u53e5\u67c4\u5f53\u524d\u7684\u4f4d\u7f6e # 5 print ( f . seek ( 6 )) # seek\u65b9\u6cd5\u53ef\u4ee5\u5c06\u53e5\u67c4\u4f4d\u7f6e\u6539\u53d8\u5230\u6587\u4ef6\u4e2d\u7279\u5b9a\u7684\u5b57\u8282 # 6 print ( f . read ( 1 )) # \u4ece\u7b2c7\u4e2a\u5b57\u8282\u5f00\u59cb\uff0c\u8f93\u51fa1\u4e2a\u5b57\u8282 # k # \u5173\u95ed\u6587\u4ef6\u4f1a\u5c06\u8d44\u6e90\u91ca\u653e\u56de\u64cd\u4f5c\u7cfb\u7edf f . close () \u5982\u679c\u4f7f\u7528\u4e8c\u8fdb\u5236\u65b9\u5f0f\u6253\u5f00\u6587\u4ef6\uff0c\u5219\uff1a import os # \u67e5\u770b\u5f53\u524d\u8def\u5f84 os . getcwd () # '/opt/myMemo' # \u66f4\u6539\u6587\u4ef6\u8bfb\u53d6\u9ed8\u8ba4\u8def\u5f84 os . chdir ( '/opt/myMemo/python/datasets/examples' ) # \u6307\u5b9a\u6587\u4ef6\u540d path = 'file01.txt' # \u6253\u5f00\u6587\u4ef6 f2 = open ( path , 'rb' ) # \u4e8c\u8fdb\u5236\u6a21\u5f0f # \u8bfb\u53d6\u6587\u4ef6 print ( f2 . read ( 5 )) # \u7b2c\u4e00\u4e2ab\u4ee3\u8868\u4e8c\u8fdb\u5236\u683c\u5f0f # b'I Thi' print ( f2 . tell ()) # 5 print ( f2 . seek ( 6 )) # 6 print ( f2 . read ( 2 )) # \u4ece\u7b2c7\u4e2a\u5b57\u8282\u5f00\u59cb\uff0c\u8f93\u51fa2\u4e2a\u5b57\u8282 # b'k ' # \u5173\u95ed\u6587\u4ef6\u4f1a\u5c06\u8d44\u6e90\u91ca\u653e\u56de\u64cd\u4f5c\u7cfb\u7edf f2 . close () \u5c06\u672c\u6587\u5199\u5165\u6587\u4ef6\uff0c\u53ef\u4ee5\u4f7f\u7528\u6587\u4ef6\u5bf9\u8c61\u7684write\u6216wirtelines\u65b9\u6cd5\u3002 import os # \u67e5\u770b\u5f53\u524d\u8def\u5f84 os . getcwd () # '/opt/myMemo' # \u66f4\u6539\u6587\u4ef6\u8bfb\u53d6\u9ed8\u8ba4\u8def\u5f84 os . chdir ( '/opt/myMemo/python/datasets/examples' ) # \u6307\u5b9a\u6587\u4ef6\u540d path1 = 'file01.txt' path2 = 'file02.txt' # file02.txt\u662f\u4e00\u4e2a\u7a7a\u6587\u4ef6 with open ( path2 , 'r+' , encoding = 'utf-8' ) as f : f . writelines ( x for x in open ( path1 , 'r' , encoding = 'utf-8' ) if len ( x ) > 1 ) # \u628afile01.txt\u7684\u5185\u5bb9\u5199\u5165file02.txt lines = f . readlines () print ( lines ) 10. \u88c5\u9970\u5668 \u00b6 \u95ed\u5305 \u00b6 \u7ef4\u57fa\u767e\u79d1\u4e2d\u7684\u89e3\u91ca\uff1a \u95ed\u5305\uff08Closure\uff09 \uff0c\u53c8\u79f0\u8bcd\u6cd5\u95ed\u5305\uff08Lexical Closure\uff09\u6216\u51fd\u6570\u95ed\u5305\uff08function closures\uff09\uff0c\u662f\u5f15\u7528\u4e86\u81ea\u7531\u53d8\u91cf\u7684\u51fd\u6570\u3002\u8fd9\u4e2a\u88ab\u5f15\u7528\u7684\u81ea\u7531\u53d8\u91cf\u5c06\u548c\u8fd9\u4e2a\u51fd\u6570\u4e00\u540c\u5b58\u5728\uff0c\u5373\u4f7f\u5df2\u7ecf\u79bb\u5f00\u4e86\u521b\u9020\u5b83\u7684\u73af\u5883\u4e5f\u4e0d\u4f8b\u5916\u3002 \u95ed\u5305\u5ef6\u4f38\u4e86\u4f5c\u7528\u57df\u7684\u51fd\u6570\uff0c\u5176\u4e2d\u5305\u542b\u51fd\u6570\u5b9a\u4e49\u4f53\u4e2d\u5f15\u7528\u3001\u4f46\u662f\u4e0d\u5728\u5b9a\u4e49\u4f53\u4e2d\u5b9a\u4e49\u7684\u975e\u5168\u5c40\u53d8\u91cf\u3002\u51fd\u6570\u662f\u4e0d\u662f\u533f\u540d\u7684\u6ca1\u6709\u5173\u7cfb\uff0c\u5173\u952e\u662f\u5b83\u80fd\u8bbf\u95ee\u5b9a\u4e49\u4f53\u4e4b\u5916\u5b9a\u4e49\u7684\u975e\u5168\u5c40\u53d8\u91cf\u3002 \u4f8b\u4e00\uff0c\u8ba1\u7b97\u79fb\u52a8\u5e73\u5747\u503c\u3002 \u4e0b\u9762\u662f\u662f\u4f20\u7edf\u7c7b\u5b9e\u73b0\u65b9\u5f0f\uff0cAvg\u7684\u5b9e\u4f8b\u662f\u53ef\u8c03\u7528\u7684\u5bf9\u8c61\u3002 class Avg (): def __init__ ( self ): self . mylist = [] def __call__ ( self , newValue ): self . mylist . append ( newValue ) total = sum ( self . mylist ) return total / len ( self . mylist ) avg = Avg () avg ( 10 ) # 10.0 avg ( 20 ) # 15.0 avg ( 30 ) # 20.0 \u4e0b\u9762\u662f\u9ad8\u9636\u51fd\u6570\u5b9e\u73b0\u65b9\u5f0f\u3002\u8c03\u7528 make_avg \u65f6\uff0c\u8fd4\u56de\u4e00\u4e2a my_avg \u51fd\u6570\u5bf9\u8c61\u3002\u6bcf\u6b21\u8c03\u7528 my_avg \u65f6\uff0c\u5b83\u4f1a\u628a\u53c2\u6570\u6dfb\u52a0\u5230\u7cfb\u5217\u503c\u4e2d\uff0c\u7136\u540e\u8ba1\u7b97\u5f53\u524d\u5e73\u5747\u503c\u3002 def make_avg (): my_list = [] def avg ( newValue ): my_list . append ( newValue ) total = sum ( my_list ) return total / len ( my_list ) return avg my_avg = make_avg () my_avg ( 10 ) # 10.0 my_avg ( 20 ) # 15.0 my_avg ( 30 ) # 20.0 my_avg . __code__ . co_varnames # ('newValue', 'total') my_avg . __code__ . co_freevars # ('my_list',) my_avg . __closure__ # (,) my_avg . __closure__ [ 0 ] . cell_contents # [10, 20, 30] \u8fd9\u4e24\u4e2a\u793a\u4f8b\u6709\u5171\u901a\u4e4b\u5904\uff1a\u8c03\u7528 Avg() \u6216 make_avg() \u5f97\u5230\u4e00\u4e2a\u53ef\u8c03\u7528\u5bf9\u8c61 avg \uff0c\u5b83\u4f1a\u66f4\u65b0\u5386\u53f2\u503c\uff0c\u7136\u540e\u8ba1\u7b97\u5f53\u524d\u5747\u503c\u3002 \u5728\u7c7b\u5b9e\u73b0\u4e2d\uff0c avg \u662f Avg \u7684\u5b9e\u4f8b\uff1b\u5728\u9ad8\u9636\u51fd\u6570\u5b9e\u73b0\u4e2d\u662f\u5185\u90e8\u51fd\u6570 avg \u3002 \u4e24\u79cd\u5b9e\u73b0\u65b9\u5f0f\u4e2d\uff0c\u6211\u4eec\u90fd\u53ea\u9700\u8c03\u7528 avg(n) \uff0c\u628a n \u653e\u5165\u7cfb\u5217\u503c\u4e2d\uff0c\u7136\u540e\u91cd\u65b0\u8ba1\u7b97\u5747\u503c\u3002 \u7b2c\u4e00\u4e2a\u4f8b\u5b50\u4e2d\uff0c Avg \u7c7b\u7684\u5b9e\u4f8b avg \u5728 self.series \u5b9e\u4f8b\u5c5e\u6027\u4e2d\u5b58\u50a8\u5386\u53f2\u503c\u3002 \u7b2c\u4e8c\u4e2a\u4f8b\u5b50\u4e2d\u7684 my_list \u662f\u51fd\u6570 make_avg() \u7684\u5c40\u90e8\u53d8\u91cf\uff0c\u4e5f\u79f0\u4e3a\u8be5\u51fd\u6570\u7684**\u81ea\u7531\u53d8\u91cf\uff08free variable\uff09**\uff0c\u6307\u672a\u5728\u672c\u5730\u4f5c\u7528\u57df\u4e2d\u7ed1\u5b9a\u7684\u53d8\u91cf\u3002 avg() \u51fd\u6570\u7684\u95ed\u5305\u5ef6\u4f38\u5230\u51fd\u6570\u7684\u4f5c\u7528\u57df\u4e4b\u5916\uff0c\u5305\u542b\u4e86 make_avg() \u7684\u81ea\u7531\u53d8\u91cf my_list \u7684\u7ed1\u5b9a\u3002 \u5bf9\u4e8e\u8fd4\u56de\u7684 my_avg \u5bf9\u8c61\uff0c\u5176 __code__ \u5c5e\u6027\uff08\u8868\u793a\u7f16\u8bd1\u540e\u7684\u51fd\u6570\u5b9a\u4e49\u4f53\uff09\u4e2d\u4fdd\u5b58\u4e86\u5c40\u90e8\u53d8\u91cf\u548c\u81ea\u7531\u53d8\u91cf\u7684\u540d\u79f0\uff0c\u5373 my_avg.__code__.co_varnames \u8fd4\u56de\u4e86\u5c40\u90e8\u53d8\u91cf ('newValue', 'total') \u548c my_avg.__code__.co_freevars \u8fd4\u56de\u4e86\u81ea\u7531\u53d8\u91cf ('my_list',) \u3002 \u81ea\u7531\u53d8\u91cf my_list \u7ed1\u5b9a\u5728\u8fd4\u56de\u7684 my_avg \u7684 __closure__ \u7684\u5c5e\u6027\u4e2d\uff0c my_avg.__closure__ \u4e2d\u7684\u5404\u4e2a\u5143\u7d20\u5bf9\u5e94\u4e86 my_avg.__code__.co_freevars \u4e2d\u7684\u4e00\u4e2a\u540d\u79f0\u3002\u8fd9\u4e9b\u5143\u7d20\u662f cell \u5bf9\u8c61\uff0c\u6709\u4e2a cell_contents \u5c5e\u6027\uff0c\u5982\uff1a my_avg.__closure__ \u8fd4\u56de (,) \uff0c\u91cc\u9762\u4fdd\u5b58\u7740\u771f\u6b63\u7684\u503c\uff0c\u5982 my_avg.__closure__[0].cell_contents \u91cc\u9762\u4fdd\u5b58\u6bcf\u6b21\u8c03\u7528\u7684\u771f\u5b9e\u503c [10, 20, 30] \u3002 \u4e0a\u9762 my_list \u662f\u4e00\u4e2a\u53ef\u53d8\u7c7b\u578b\uff0c\u5982\u679c\u7528\u4e0d\u53ef\u53d8\u7c7b\u578b\u6539\u5199\uff0c\u5e76\u5b9e\u73b0\u95ed\u5305\uff0c\u53ef\u4ee5\u4f7f\u7528 nolocal \u8fdb\u884c\u58f0\u660e\u3002\u5b83\u7684\u4f5c\u7528\u662f\u628a\u53d8\u91cf\u6807\u8bb0\u4e3a\u81ea\u7531\u53d8\u91cf\uff0c\u5373\u4f7f\u5728\u51fd\u6570\u4e2d\u4e3a\u53d8\u91cf\u8d4b\u4e88\u65b0\u503c\u4e86\uff0c\u4e5f\u4f1a\u53d8\u6210\u81ea\u7531\u53d8\u91cf\u3002\u5982\u679c\u4e3anonlocal\u58f0\u660e\u7684\u53d8\u91cf\u8d4b\u4e88\u65b0\u503c\uff0c\u95ed\u5305\u4e2d\u4fdd\u5b58\u7684\u7ed1\u5b9a\u4f1a\u66f4\u65b0\u3002 my_avg.__code__.co_freevars \u8fd4\u56de\u4e862\u4e2a\u81ea\u7531\u53d8\u91cf ('count', 'total') \uff0c\u5e76\u5728 my_avg.__closure__[0].cell_contents \u548c my_avg.__closure__[1].cell_contents \u91cc\u9762\u4fdd\u5b58\u4e86\u6700\u540e\u4e00\u6b21\u6267\u884c\u7684\u771f\u5b9e\u503c\u3002 def make_avg (): count = 0 total = 0 def avg ( newValue ): nonlocal count , total count += 1 total += newValue return total / count return avg my_avg = make_avg () my_avg ( 10 ) # 10.0 my_avg ( 20 ) # 15.0 my_avg ( 30 ) # 20.0 my_avg . __code__ . co_varnames # ('newValue',) my_avg . __code__ . co_freevars # ('count', 'total') my_avg . __closure__ # (, ) my_avg . __closure__ [ 0 ] . cell_contents # 3 my_avg . __closure__ [ 1 ] . cell_contents # 60 \u4f8b\u4e8c\uff1a money \u662f\u4e00\u4e2a\u5c40\u90e8\u53d8\u91cf\uff0c\u5728 get_money \u662f\u5916\u56f4\u51fd\u6570\uff0c\u51fd\u6570\u6267\u884c\u4e4b\u540e\u5e94\u8be5\u5c31\u4e0d\u4f1a\u5b58\u5728\u4e86\u3002 \u4f46\u662f\u5d4c\u5957\u51fd\u6570 work \u5f15\u7528\u4e86 money \u8fd9\u4e2a\u81ea\u7531\u53d8\u91cf\uff0c\u5c06\u8fd9\u4e2a\u5c40\u90e8\u53d8\u91cf\u5c01\u95ed\u5728\u4e86\u5d4c\u5957\u51fd\u6570 work \u4e2d\uff0c\u8fd9\u6837\u5c31\u5f62\u6210\u4e86\u4e00\u4e2a\u95ed\u5305\u3002 closure = get_money() \u83b7\u5f97\u7684\u5c31\u662f\u4e00\u4e2a\u95ed\u5305\u3002 closure() \u8f93\u51fa\u95ed\u5305\uff0c\u5373\uff0c\u6267\u884c\u4e86 work() \uff0c\u6253\u5370\u8f93\u51fa money \u7684\u503c\u3002 \u672c\u5730\u51fd\u6570\u901a\u8fc7global\u58f0\u660e\u5bf9\u5168\u5c40\u53d8\u91cf\u8fdb\u884c\u5f15\u7528\u4fee\u6539\uff0c\u90a3\u4e48\u5bf9\u4e8e\u5185\u5d4c\u51fd\u6570 work() \u4f5c\u7528\u57df\u4e2d\u7684\u53d8\u91cf\u8fdb\u884c\u4fee\u6539\uff0c\u5c31\u8981\u4f7f\u7528 nonlocal \u8fdb\u884c\u58f0\u660e\u3002 def get_money (): money = 0 def work (): nonlocal money money += 100 print ( money ) return work closure = get_money () closure () # 100 closure () # 200 closure () # 300 \u4f8b\u4e09\uff1a \u51fd\u6570 maker \u4e2d\u5b9a\u4e49\u4e86\u51fd\u6570 action \uff0c action \u5f15\u7528\u4e86 maker \u5d4c\u5957\u4f5c\u7528\u57df\u5185\u7684\u53d8\u91cf k \uff0c\u5e76\u4e14\uff0c maker \u5c06\u51fd\u6570 action \u4f5c\u4e3a\u8fd4\u56de\u5bf9\u8c61\u8fdb\u884c\u8fd4\u56de\u3002 \u8fd9\u6837\uff0c\u6211\u4eec\u901a\u8fc7\u6267\u884c f = maker(2) \uff0c f \u83b7\u53d6\u4e86\u8fd4\u56de\u5bf9\u8c61 action \uff0c\u867d\u7136\u6b64\u65f6 maker \u51fd\u6570\u4ee5\u53ca\u7ed3\u675f\u9000\u51fa\u4e86\uff0c\u4f46\u5bf9\u8c61 f \u4ecd\u7136\u8bb0\u4f4f\u4e86\u51fd\u6570 maker \u5d4c\u5957\u4f5c\u7528\u57df\u5185\u7684\u53d8\u91cf k \u548c n \uff0c\u5e76\u5728\u6267\u884c f(3) \u65f6\uff0c\u5c06 x=3 \u4ee5\u53ca\u4e4b\u524d\u8bb0\u4f4f\u7684 k \u548c n \uff0c\u4e00\u5e76\u4f20\u5165 action() \uff0c\u8ba1\u7b97\u5e76\u8fd4\u56de x + n + k \u503c\u3002 make \u4e5f\u79f0\u4e3a**\u5de5\u5382\u51fd\u6570**\u3002 def maker ( n ): k = 8 def action ( x ): return x + n + k return action f = maker ( 2 ) print ( f ( 3 )) # 13 print ( f ( 4 )) # 14 print ( f ( 5 )) # 15 \u7ed3\u5408\u524d\u97622\u4e2a\u4f8b\u5b50\u518d\u770b\u4e0a\u9762\u7684\u89e3\u91ca\uff0c\u95ed\u5305\u5c31\u662f\u5f15\u7528\u4e86\u81ea\u7531\u53d8\u91cf\u7684\u51fd\u6570\uff0c\u8fd9\u4e2a\u51fd\u6570\u4fdd\u5b58\u4e86\u6267\u884c\u7684\u4e0a\u4e0b\u6587\uff0c\u53ef\u4ee5\u8131\u79bb\u539f\u672c\u7684\u4f5c\u7528\u57df\u72ec\u7acb\u5b58\u5728\u3002 \u88c5\u9970\u5668 \u00b6 \u770b\u4e0b\u9762\u4f8b\u5b50\uff0c\u5c06\u51fd\u6570\u4f5c\u4e3a\u53c2\u6570\u4f20\u7ed9\u53e6\u4e00\u4e2a\u51fd\u6570\uff0c\u51fd\u6570 my_decorator \u7684\u4f20\u5165\u53c2\u6570\u6b63\u597d\u662f\u5176\u5d4c\u5957\u51fd\u6570 myFunc \u3002 def my_decorator ( nestedFunc ): def myFunc (): print ( \"Before executing nestedFunc()\" ) nestedFunc () print ( \"After executing nestedFunc()\" ) return myFunc def nestedFunc (): print ( \"Decoration - executing nestedFunc()\" ) nestedFunc () # Decoration - executing nestedFunc() nestedFunc = my_decorator ( nestedFunc ) nestedFunc () # Before executing nestedFunc() # Decoration - executing nestedFunc() # After executing nestedFunc() \u88c5\u9970\u5668\u53ea\u662f\u4e2a\u65b9\u6cd5\uff0c\u4f7f\u7528\u65f6\u7528\u4e86 @ \u8bed\u6cd5\u3002 @ \u8bed\u6cd5\u53ea\u662f\u5c06\u51fd\u6570 nestedFunc \u4f20\u5165\u88c5\u9970\u5668\u51fd\u6570 my_decorator \u3002 @my_decorator \u662f nestedFunc = my_decorator(nestedFunc) \u7684\u5feb\u6377\u8868\u8fbe\u65b9\u5f0f\uff0c @my_decorator def nestedFunc (): print ( \"New added to decoration - executing nestedFunc()\" ) nestedFunc () # Before executing nestedFunc() # New added to decoration - executing nestedFunc() # After executing nestedFunc() print ( nestedFunc . __name__ ) # myFunc \u4f46\u4e0a\u4f8b\u6700\u540e\u7684\u8f93\u51fa\u4e0d\u662f\u6211\u4eec\u60f3\u8981\u7684\uff0c\u6211\u4eec\u5e0c\u671b\u8f93\u51fa nestedFunc \uff0c\u4f46\u5374\u88ab myFunc \u66ff\u4ee3\u4e86\uff0c\u5b83\u91cd\u5199\u4e86\u6211\u4eec\u51fd\u6570\u7684\u540d\u5b57\u548c\u6ce8\u91ca\u6587\u6863(docstring)\u3002 \u4e0b\u9762\u4f7f\u7528 functools.wraps \u6765\u4fee\u6b63\u4e0a\u9762\u7684\u95ee\u9898\u3002 from functools import wraps def my_decorator ( nestedFunc ): @wraps ( nestedFunc ) def myFunc (): print ( \"Before executing nestedFunc()\" ) nestedFunc () print ( \"After executing nestedFunc()\" ) return myFunc def nestedFunc (): print ( \"Decoration - executing nestedFunc()\" ) @my_decorator def nestedFunc (): print ( \"New added to decoration - executing nestedFunc()\" ) nestedFunc () # Before executing nestedFunc() # New added to decoration - executing nestedFunc() # After executing nestedFunc() print ( nestedFunc . __name__ ) # nestedFunc \u4e0b\u9762\u662f\u88c5\u9970\u5668\u7684\u84dd\u672c\u89c4\u8303\u3002 from functools import wraps def decorator_name ( f ): @wraps ( f ) def decorated ( * args , ** kwargs ): if not can_run : return \"Function will not run\" return f ( * args , ** kwargs ) return decorated @decorator_name def func (): return ( \"Function is running\" ) can_run = True print ( func ()) # Output: Function is running can_run = False print ( func ()) # Output: Function will not run \u4e0b\u9762\u8fd8\u662f\u4e00\u4e2a\u88c5\u9970\u5668\u7684\u4f8b\u5b50\u3002\u628a\u4e0b\u9762\u7684\u4ee3\u7801\u6bb5\u4fdd\u5b58\u5230\u6587\u4ef6 test.py \u3002 registry = [] def register ( func ): print ( f 'running register { func } ' ) registry . append ( func ) return func @register def f1 (): print ( 'running f1()' ) @register def f2 (): print ( 'running f2()' ) def f3 (): print ( 'running f3()' ) def main (): print ( 'runnning main()' ) print ( f 'registry--> { registry } ' ) f1 () f2 () f3 () if __name__ == '__main__' : main () \u6267\u884c\u4e0a\u8ff0\u4ee3\u7801\u6bb5 python3 test.py \uff0c\u5f97\u5230\u4e0b\u9762\u7684\u7ed3\u679c\u3002 running register < function f1 at 0x7f70847bec80 > running register < function f2 at 0x7f70705aa9d8 > runnning main () registry --> [ < function f1 at 0x7f70847bec80 > , < function f2 at 0x7f70705aa9d8 > ] running f1 () running f2 () running f3 () register \u5728\u6a21\u5757\u4e2d\u5176\u4ed6\u51fd\u6570\u4e4b\u524d\u8fd0\u884c\uff08\u4e24\u6b21\uff09\u3002\u8c03\u7528 register \u65f6\uff0c\u4f20\u7ed9\u5b83\u7684\u53c2\u6570\u662f\u88ab\u88c5\u9970\u7684\u51fd\u6570\uff0c\u4f8b\u5982 function f1 at 0x7f70847bec80> \u3002\u52a0\u8f7d\u6a21\u5757\u540e\uff0c registry \u4e2d\u6709\u4e24\u4e2a\u88ab\u88c5\u9970\u51fd\u6570\u7684\u5f15\u7528\uff1a f1 \u548c f2 \u3002\u8fd9\u4e24\u4e2a\u51fd\u6570\uff0c\u4ee5\u53ca f3 \uff0c\u53ea\u5728 main \u660e\u786e\u8c03\u7528\u5b83\u4eec\u65f6\u624d\u6267\u884c\u3002 \u7531\u6b64\u5f97\uff0c\u51fd\u6570\u88c5\u9970\u5668\u5728\u5bfc\u5165\u6a21\u5757\u65f6\u7acb\u5373\u6267\u884c\uff0c\u800c\u88ab\u88c5\u9970\u7684\u51fd\u6570\u53ea\u5728\u660e\u786e\u8c03\u7528\u65f6\u8fd0\u884c\uff0c\u5373Python\u4e2d\u63d0\u5230\u7684**\u5bfc\u5165\u65f6**\u548c**\u8fd0\u884c\u65f6**\u4e4b\u95f4\u7684\u533a\u522b\u3002 \u4e0a\u9762\u4f8b\u5b50\u4e2d\u88c5\u9970\u5668\u51fd\u6570\u4e0e\u88ab\u88c5\u9970\u7684\u51fd\u6570\u5728\u540c\u4e00\u4e2a\u6a21\u5757\u4e2d\u5b9a\u4e49\u3002\u5b9e\u9645\u5e94\u7528\u4e2d\uff0c\u88c5\u9970\u5668\u901a\u5e38\u5728\u4e00\u4e2a\u6a21\u5757\u4e2d\u5b9a\u4e49\uff0c\u7136\u540e\u5e94\u7528\u5230\u5176\u4ed6\u6a21\u5757\u4e2d\u7684\u51fd\u6570\u4e0a\u3002 \u4e0a\u9762\u4f8b\u5b50\u4e2d register \u88c5\u9970\u5668\u8fd4\u56de\u7684\u51fd\u6570\u4e0e\u901a\u8fc7\u53c2\u6570\u4f20\u5165\u7684\u76f8\u540c\u3002\u5b9e\u9645\u5e94\u7528\u4e2d\uff0c\u5927\u591a\u6570\u88c5\u9970\u5668\u4f1a\u5728\u5185\u90e8\u5b9a\u4e49\u4e00\u4e2a\u51fd\u6570\uff0c\u7136\u540e\u5c06\u5176\u8fd4\u56de\u3002","title":"Python\u5185\u7f6e\u51fd\u6570\u53ca\u6587\u4ef6"},{"location":"python/Foundation/ch03/#python","text":"","title":"Python\u5185\u7f6e\u51fd\u6570\u53ca\u6587\u4ef6"},{"location":"python/Foundation/ch03/#1-lambda","text":"\u533f\u540d\u51fd\u6570\u662f\u4e00\u79cd\u901a\u8fc7\u5355\u4e2a\u8bed\u53e5\u751f\u6210\u51fd\u6570\u7684\u65b9\u5f0f\uff0c\u5176\u7ed3\u679c\u662f\u8fd4\u56de\u503c\u3002\u533f\u540d\u51fd\u6570\u4f7f\u7528lambda\u5173\u952e\u5b57\u5b9a\u4e49\uff0c\u8be5\u5173\u952e\u5b57\u4ec5\u8868\u8fbe\u201c\u6211\u4eec\u58f0\u660e\u4e00\u4e2a\u533f\u540d\u51fd\u6570\u201d\u7684\u610f\u601d\u3002 lambda \u51fd\u6570\u53ef\u4ee5\u63a5\u6536\u4efb\u610f\u591a\u4e2a\u53c2\u6570 (\u5305\u62ec\u53ef\u9009\u53c2\u6570) \u5e76\u4e14\u8fd4\u56de\u5355\u4e2a\u8868\u8fbe\u5f0f\u7684\u503c\u3002 \u8bed\u6cd5\u683c\u5f0f\uff1a lambda arg1,arg2,arg3\u2026 :<\u8868\u8fbe\u5f0f> f = lambda x , y : x * y print ( f ( 2 , 3 )) # 6 f = [ lambda a : a * 2 , lambda b : b * 3 ] print ( f [ 0 ]( 5 )) # \u6267\u884cf\u5217\u8868\u7b2c\u4e00\u4e2a\u5143\u7d20 # 10 print ( f [ 1 ]( 5 )) # \u6267\u884cf\u5143\u7d20\u7b2c\u4e8c\u4e2a\u5143\u7d20 # 15 print ( f [ 0 , 1 ]( 5 , 5 )) # TypeError: list indices must be integers or slices, not tuple \u793a\u4f8b1\uff1a def short_func1 ( x ): return x * 2 short_func2 = lambda x : x * 2 print ( short_func1 ( 5 )) # 10 print ( short_func2 ( 5 )) # 10 \u793a\u4f8b2\uff1a def apply_to_list ( some_list , f ): return [ f ( x ) for x in some_list ] ints = [ 4 , 0 , 1 , 5 , 6 ] result5 = apply_to_list ( ints , lambda x : x * 2 ) print ( result5 ) # [8, 0, 2, 10, 12] lambda: None \u51fd\u6570\u6ca1\u6709\u8f93\u5165\u53c2\u6570\uff0c\u8f93\u51fa\u662fNone\u3002 print ( lambda : None ) # at 0x7fa5c4097670> lambda **kwargs: 1 \u8f93\u5165\u662f\u4efb\u610f\u952e\u503c\u5bf9\u53c2\u6570\uff0c\u8f93\u51fa\u662f1\u3002 print ( lambda ** kwargs : 1 ) # at 0x7fa5c4097670>","title":"1. \u533f\u540d\uff08Lambda\uff09\u51fd\u6570"},{"location":"python/Foundation/ch03/#2-enumerate","text":"\u5f53\u9700\u8981\u5bf9\u6570\u636e\u5efa\u7acb\u7d22\u5f15\u65f6\uff0c\u4e00\u79cd\u6709\u6548\u7684\u6a21\u5f0f\u5c31\u662f\u4f7f\u7528enumerate\u6784\u9020\u4e00\u4e2a\u5b57\u5178\uff0c\u5c06\u5e8f\u5217\u503c\uff08\u5047\u8bbe\u662f\u552f\u4e00\u7684\uff09\u6620\u5c04\u5230\u7d22\u5f15\u4f4d\u7f6e\u4e0a\u3002 seasons = [ 'Spring' , 'Summer' , 'Fall' , 'Winter' ] print ( list ( enumerate ( seasons ))) # [(0, 'Spring'), (1, 'Summer'), (2, 'Fall'), (3, 'Winter')] \u5bf9\u6bd4\u4e0b\u97622\u4e2a\u5faa\u73af a_list = [ 'foo' , 'bar' , 'baz' ] mapping = {} for i , v in enumerate ( a_list ): # enumerate\u751f\u6210\u7d22\u5f15\u503ci\u548c\u5e8f\u5217\u503cv mapping [ v ] = i print ( mapping ) # {'foo': 0, 'bar': 1, 'baz': 2} i = 0 mapping = {} for v in a_list : print ( i , a_list [ i ]) mapping [ v ] = i # \u53ef\u4ee5\u628ai\u548cv\u4e92\u6362 i += 1 print ( mapping ) # {'foo': 0, 'bar': 1, 'baz': 2} \u5229\u7528 enumerate() \u6279\u91cf\u4fee\u6539\u5217\u8868\u5185\u7684\u5143\u7d20 a_list = [ '01' , '02' , '03' ] unit_element = '1' for i , element in enumerate ( a_list ): a_list [ i ] = unit_element + element print ( a_list ) # ['101', '102', '103'] sorted\u51fd\u6570\u8fd4\u56de\u4e00\u4e2a\u6839\u636e\u4efb\u610f\u5e8f\u5217\u4e2d\u7684\u5143\u7d20\u65b0\u5efa\u7684\u5df2\u6392\u5e8f\u5217\u8868\u3002sorted\u51fd\u6570\u63a5\u53d7\u7684\u53c2\u6570\u4e0e\u5217\u8868\u7684sort\u65b9\u6cd5\u4e00\u81f4\u3002 y = sorted ([ 7 , 1 , 2 , 6 , 0 , 3 , 2 ]) print ( y ) # [0, 1, 2, 2, 3, 6, 7] \u7ed3\u679c\u5df2\u6392\u5e8f z = sorted ( 'Hello World' ) print ( z ) # [' ', 'H', 'W', 'd', 'e', 'l', 'l', 'l', 'o', 'o', 'r'] zip\u5c06\u5217\u8868\u3001\u5143\u7ec4\u6216\u5176\u4ed6\u5e8f\u5217\u7684\u5143\u7d20\u914d\u5bf9\uff0c\u65b0\u5efa\u4e00\u4e2a\u5143\u7ec4\u6784\u6210\u7684\u5217\u8868\u3002 seq1 = [ 'foo' , 'bar' , 'baz' ] seq2 = [ 'one' , 'two' , 'three' ] seq3 = [ False , True ] zipped = zip ( seq1 , seq2 ) print ( list ( zipped )) # [('foo', 'one'), ('bar', 'two'), ('baz', 'three')] zipped = zip ( seq1 , seq2 , seq3 ) print ( list ( zipped )) # [('foo', 'one', False), ('bar', 'two', True)] for i , ( a , b ) in enumerate ( zip ( seq1 , seq2 )): print ( ' {0} : {1} , {2} ' . format ( i , a , b )) # \u65b9\u6cd51 {0}\u5217\u8868\u5143\u7d20\u7684\u7d22\u5f15, {1}\u5143\u7ec4\u4e2d\u7b2c\u4e00\u4e2a\u503c, {2}\u5143\u7ec4\u4e2d\u7b2c\u4e8c\u4e2a\u503c print ( f ' { i } : { a } , { b } ' ) # \u65b9\u6cd52 # 0: foo, one # 1: bar, two # 2: baz, three \u7ed9\u5b9a\u4e00\u4e2a\u5df2\u201c\u914d\u5bf9\u201d\u7684\u5e8f\u5217\u65f6\uff0czip\u51fd\u6570\u53ef\u4ee5\u53bb\u201c\u62c6\u5206\u201d\u5e8f\u5217\u3002\u8fd9\u79cd\u65b9\u5f0f\u7684\u53e6\u4e00\u79cd\u601d\u8def\u5c31\u662f\u5c06\u884c\u7684\u5217\u8868\u8f6c\u6362\u4e3a\u5217\u7684\u5217\u8868\u3002\u53c2\u8003Python\u7684 Unpacking pitchers = [( 'Jack' , 'Ma' ), ( 'Tom' , 'Li' ), ( 'Jimmy' , 'Zhang' )] first_names , last_names = zip ( * pitchers ) print ( first_names ) # ('Jack', 'Tom', 'Jimmy') print ( last_names ) # ('Ma', 'Li', 'Zhang') reversed\u51fd\u6570\u5c06\u5e8f\u5217\u7684\u5143\u7d20\u5012\u5e8f\u6392\u5217 print ( list ( reversed ( range ( 10 )))) # [9, 8, 7, 6, 5, 4, 3, 2, 1, 0]","title":"2. \u5185\u7f6e\u5e8f\u5217\u51fd\u6570enumerate"},{"location":"python/Foundation/ch03/#3","text":"\u63a8\u5bfc\u5f0fcomprehensions\uff08\u53c8\u79f0\u89e3\u6790\u5f0f\uff09\uff0c\u662fPython\u7684\u4e00\u79cd\u7279\u6027\u3002\u4f7f\u7528\u63a8\u5bfc\u5f0f\u53ef\u4ee5\u5feb\u901f\u751f\u6210\u5217\u8868\u3001\u5143\u7ec4\u3001\u96c6\u5408\u3001\u5b57\u5178\u7c7b\u578b\u7684\u6570\u636e\u3002\u63a8\u5bfc\u5f0f\u53c8\u5206\u4e3a\u5217\u8868\u63a8\u5bfc\u5f0f\u3001\u5143\u7ec4\u63a8\u5bfc\u5f0f\u3001\u96c6\u5408\u63a8\u5bfc\u5f0f\u3001\u5b57\u5178\u63a8\u5bfc\u5f0f\u3002","title":"3. \u5217\u8868\u3001\u96c6\u5408\u548c\u5b57\u5178\u7684\u63a8\u5bfc\u5f0f"},{"location":"python/Foundation/ch03/#list-comprehension","text":"\u5217\u8868\u63a8\u5bfc\u5f0f(list comprehension)\u5141\u8bb8\u4f60\u8fc7\u6ee4\u4e00\u4e2a\u5bb9\u5668\u7684\u5143\u7d20\uff0c\u7528\u4e00\u79cd\u7b80\u660e\u7684\u8868\u8fbe\u5f0f\u8f6c\u6362\u4f20\u9012\u7ed9\u8fc7\u6ee4\u5668\u7684\u5143\u7d20\uff0c\u4ece\u800c\u751f\u6210\u4e00\u4e2a\u65b0\u7684\u5217\u8868\u3002 \u5217\u8868\u63a8\u5bfc\u5f0f\u7684\u57fa\u672c\u5f62\u5f0f\u4e3a\uff1a[expr for val in collection if condition]\uff0c\u6761\u4ef6if-condition\u4e0d\u662f\u5fc5\u987b\u7684\uff0c\u53ef\u4ee5\u53ea\u4fdd\u7559\u8868\u8fbe\u5f0f\u3002\u5217\u8868\u63a8\u5bfc\u5f0f\u4e0e\u4e0b\u9762\u7684for\u5faa\u73af\u662f\u7b49\u4ef7\u7684\uff1a result = [] for val in collection : if condition : result . append ( expr ) \u770b\u4e0b\u9762\u7684\u4f8b\u5b50\uff1a data = [] for i in range ( - 5 , 5 ): if i >= - 1 : data . append ( i ** 2 ) print ( data ) # [1, 0, 1, 4, 9, 16] data = [ i ** 2 for i in range ( - 5 , 5 ) if i >= - 1 ] print ( data ) # [1, 0, 1, 4, 9, 16] \u4e0b\u9762\u7684\u4f8b\u5b50\u662f\u4f7f\u7528for\u53bb\u904d\u5386\u4e00\u4e2a\u53ef\u8fed\u4ee3\u7684\u5217\u8868\u3002 data = [] fruit = [ 'pomegranate' , 'cherry' , 'apricot' , 'date' , 'Apple' , 'lemon' , 'kiwi' , 'ORANGE' , 'lime' , 'Watermelon' , 'guava' , 'papaya' , 'FIG' , 'pear' , 'banana' , 'Tamarind' , 'persimmon' , 'elderberry' , 'peach' , 'BLUEberry' , 'lychee' , 'grape' ] data = [ x . upper () if x . startswith ( 'p' ) else x . title () for x in fruit ] print ( data ) # ['POMEGRANATE', 'Cherry', 'Apricot', 'Date', 'Apple', 'Lemon', 'Kiwi', 'Orange', 'Lime', 'Watermelon', 'Guava', 'PAPAYA', 'Fig', 'PEAR', 'Banana', 'Tamarind', 'PERSIMMON', 'Elderberry', 'PEACH', 'Blueberry', 'Lychee', 'Grape']","title":"\u5217\u8868\u63a8\u5bfc\u5f0f(list comprehension)"},{"location":"python/Foundation/ch03/#_1","text":"\u4e0b\u9762\u7684\u4f8b\u5b50\u662f\u7528\u5d4c\u5957\u5217\u8868\u63a8\u5bfc\u5f0f\u4ee3\u66ff2\u5c42for\u5faa\u73af\u3002 data = [] for i in range ( 1 , 3 ): if i >= 0 : for j in range ( 1 , 3 ): data . append (( i , j )) print ( data ) # [(1, 1), (1, 2), (2, 1), (2, 2)] data = [( i , j ) for i in range ( 1 , 3 ) if i >= - 1 for j in range ( 1 , 3 )] print ( data ) # [(1, 1), (1, 2), (2, 1), (2, 2)] \u518d\u4e3e\u4e00\u4e2a\u5d4c\u5957\u5217\u8868\u63a8\u5bfc\u5f0f\u7684\u4f8b\u5b50\u3002 all_data = [ [ 'John' , 'Emily' , 'Michael' , 'Lee' , 'Steven' ], [ 'Maria' , 'Juan' , 'Javier' , 'Natalia' , 'Pilar' ], ] names_of_interest = [] for names in all_data : enough_es = [ name for name in names if name . count ( 'e' ) >= 2 ] names_of_interest . extend ( enough_es ) print ( names_of_interest ) # ['Lee', 'Steven'] result = [ name for names in all_data for name in names if name . count ( 'e' ) >= 2 ] print ( result ) # ['Lee', 'Steven'] \u7528\u5d4c\u5957\u5217\u8868\u63a8\u5bfc\u5f0f\u5c06\u77e9\u9635\u6241\u5e73\u5316\u3002 \u8003\u8651\u4e0b\u9762\u8fd9\u4e2a3x4\u7684\u77e9\u9635\uff0c\u5b83\u75313\u4e2a\u957f\u5ea6\u4e3a4\u7684\u5217\u8868\u7ec4\u6210\u3002\u4e0b\u9762\u4f8b\u5b50\u5bf9\u6bd4\u4e86\u7528\u4f20\u7edffor\u5faa\u73af\u5c06\u77e9\u9635\u6241\u5e73\u5316\uff0c\u548c\u7528\u5d4c\u5957\u5217\u8868\u63a8\u5bfc\u5f0f\u5c06\u77e9\u9635\u6241\u5e73\u5316\u3002\u5e76\u4e14\u901a\u8fc7\u5217\u8868\u63a8\u5bfc\u5f0f\u4e2d\u7684\u5217\u8868\u63a8\u5bfc\u5f0f\u5c06\u6241\u5e73\u77e9\u9635\u8fd8\u539f\u4e3a3x4\u77e9\u9635\u3002 matrix = [ [ 1 , 2 , 3 , 4 ], [ 5 , 6 , 7 , 8 ], [ 9 , 10 , 11 , 12 ], ] flattened = [] # \u4f20\u7edffor\u5faa\u73af\u5d4c\u5957 for m in matrix : for x in m : flattened . append ( x ) print ( flattened ) # [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12] # \u5d4c\u5957\u5217\u8868\u63a8\u5bfc\u5f0f flattened = [ x for m in matrix for x in m ] print ( flattened ) # [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12] # \u5217\u8868\u63a8\u5bfc\u5f0f\u4e2d\u7684\u5217\u8868\u63a8\u5bfc\u5f0f z = [[ x for x in m ] for m in matrix ] print ( z ) # [[1, 2, 3, 4], [5, 6, 7, 8], [9, 10, 11, 12]]","title":"\u5957\u5217\u8868\u63a8\u5bfc\u5f0f"},{"location":"python/Foundation/ch03/#_2","text":"\u4e0b\u9762\u7684\u4f8b\u5b50\u751f\u6210\u4e00\u4e2a\u5305\u542b\u6570\u5b571~5\u7684\u5143\u7ec4\u3002\u4ece\u7ed3\u679c\u53ef\u4ee5\u770b\u5230\uff0c\u5143\u7ec4\u63a8\u5bfc\u5f0f\u751f\u6210\u7684\u7ed3\u679c\u5e76\u4e0d\u662f\u4e00\u4e2a\u5143\u7ec4\uff0c\u800c\u662f\u4e00\u4e2a\u751f\u6210\u5668\u5bf9\u8c61\uff0c\u9700\u8981\u901a\u8fc7tuple()\u51fd\u6570\uff0c\u5c06\u751f\u6210\u5668\u5bf9\u8c61\u8f6c\u6362\u6210\u5143\u7ec4\u3002 data = ( x for x in range ( 5 )) print ( data ) # at 0x7f87217a8e40> print ( type ( data )) # print ( tuple ( data )) # (0, 1, 2, 3, 4)","title":"\u5143\u7ec4\u63a8\u5bfc\u5f0f"},{"location":"python/Foundation/ch03/#_3","text":"\u4e0b\u9762\u662f\u4e00\u4e2a\u7b80\u5355\u7684\u96c6\u5408\u63a8\u5bfc\u5f0f\u4f8b\u5b50\u3002 data = { x ** 2 for x in range ( 5 )} print ( data ) # {0, 1, 4, 9, 16} print ( type ( data )) # \u96c6\u5408\u8981\u4fdd\u8bc1\u5143\u7d20\u5fc5\u987b\u662f\u552f\u4e00\u7684\u3002 data = ( 1 , 1 , 2 , 2 , 3 , 3 , 4 , 5 , 6 ) newset = { x ** 2 for x in data } print ( newset ) # {1, 4, 36, 9, 16, 25} print ( type ( newset ) # ","title":"\u96c6\u5408\u63a8\u5bfc\u5f0f"},{"location":"python/Foundation/ch03/#_4","text":"\u5b57\u5178\u63a8\u5bfc\u5f0f: dict_comp = {key-expr : value-expr for value in collection if condition} \u5b57\u5178\u63a8\u5bfc\u5f0f\u7684\u7b80\u5355\u793a\u4f8b\uff1a strings = [ 'a' , 'as' , 'bat' , 'car' , 'dove' , 'python' ] loc_mapping = { index : val for index , val in enumerate ( strings )} print ( loc_mapping ) # {0: 'a', 1: 'as', 2: 'bat', 3: 'car', 4: 'dove', 5: 'python'} # \u4ea4\u6362\u952e\u548c\u503c loc_mapping = { index : val for val , index in enumerate ( strings )} print ( loc_mapping ) # {'a': 0, 'as': 1, 'bat': 2, 'car': 3, 'dove': 4, 'python': 5}","title":"\u5b57\u5178\u63a8\u5bfc\u5f0f"},{"location":"python/Foundation/ch03/#4","text":"\u5982\u679cPython\u8fbe\u5230\u51fd\u6570\u7684\u5c3e\u90e8\u65f6\u4ecd\u7136\u6ca1\u6709\u9047\u5230return\u8bed\u53e5\uff0c\u5c31\u4f1a\u81ea\u52a8\u8fd4\u56deNone\u3002 \u6bcf\u4e2a\u51fd\u6570\u90fd\u53ef\u4ee5\u6709\u4f4d\u7f6e\u53c2\u6570\u548c\u5173\u952e\u5b57\u53c2\u6570\u3002\u5173\u952e\u5b57\u53c2\u6570\u6700\u5e38\u7528\u4e8e\u6307\u5b9a\u9ed8\u8ba4\u503c\u6216\u53ef\u9009\u53c2\u6570\u3002\u5173\u952e\u5b57\u53c2\u6570\u5fc5\u987b\u8ddf\u5728\u4f4d\u7f6e\u53c2\u6570\u540e\uff0c\u53ef\u4ee5\u4f7f\u7528\u5173\u952e\u5b57\u53c2\u6570\u5411\u4f4d\u7f6e\u53c2\u6570\u4f20\u53c2\u3002 import sys def my_function1 ( x , y , z = 1.5 ): if z > 1 : return z * ( x + y ) else : return z / ( x + y ) result1 = my_function1 ( 5 , 6 , z = 0.7 ) print ( result1 ) # 0.06363636363636363 result1 = my_function1 ( x = 5 , y = 6 , z = 0.7 ) print ( result1 ) # 0.06363636363636363 result1 = my_function1 ( 3.14 , 7 , 3.5 ) print ( result1 ) # 35.49 result1 = my_function1 ( 10 , 20 ) print ( result1 ) # 45.0","title":"4. \u51fd\u6570\u58f0\u660e"},{"location":"python/Foundation/ch03/#5","text":"\u51fd\u6570\u6709\u4e24\u79cd\u8fde\u63a5\u53d8\u91cf\u7684\u65b9\u5f0f\uff1a\u5168\u5c40\u3001\u672c\u5730\u3002 def func1 (): list1 = [] # \u672c\u5730\u53d8\u91cf for i in range ( 5 ): list1 . append ( i ) print ( list1 ) func1 () # [0, 1, 2, 3, 4] list2 = [] # \u5168\u5c40\u53d8\u91cf def func2 (): global list2 # \u5168\u5c40\u53d8\u91cf for i in range ( 5 ): list2 . append ( i ) print ( list2 ) func2 () # [0, 1, 2, 3, 4] \u6570\u636e\u6e05\u6d17\u793a\u4f8b states = [ ' Alabama' , 'Georgia!' , 'georgia' , 'Georgia' , 'FlOrIda' , 'south carolina##' , 'West virginia? ' ] # \u65b9\u6cd51 import re def clean_string1 ( strings ): result2 = [] for value in strings : value = value . strip () value = re . sub ( '[! #? ]' , '' , value ) value = value . title () result2 . append ( value ) return result2 print ( clean_string1 (( states ))) # ['Alabama', 'Georgia', 'Georgia', 'Georgia', 'Florida', 'Southcarolina', 'Westvirginia'] # \u65b9\u6cd52 def remove_punctuaion ( value ): return re . sub ( '[! #? ]' , '' , value ) clean_ops = [ str . strip , remove_punctuaion , str . title ] def clean_string2 ( strings , ops ): result3 = [] for value in strings : for function in ops : value = function ( value ) result3 . append ( value ) return result3 result4 = clean_string2 ( states , clean_ops ) print ( result4 ) # ['Alabama', 'Georgia', 'Georgia', 'Georgia', 'Florida', 'Southcarolina', 'Westvirginia'] # \u53ef\u4ee5\u5c06\u51fd\u6570\u4f5c\u4e3a\u4e00\u4e2a\u53c2\u6570\u4f20\u7ed9\u5176\u4ed6\u7684\u51fd\u6570\u3002 for x in map ( remove_punctuaion , states ): print ( x ) # Alabama # Georgia # georgia # Georgia # FlOrIda # southcarolina # Westvirginia","title":"5. \u547d\u540d\u7a7a\u95f4\u3001\u4f5c\u7528\u57df\u548c\u672c\u5730\u51fd\u6570"},{"location":"python/Foundation/ch03/#6","text":"\u67ef\u91cc\u5316\u662f\u8ba1\u7b97\u673a\u79d1\u5b66\u672f\u8bed\uff08\u4ee5\u6570\u5b66\u5bb6Haskell Curry\u547d\u540d\uff09\uff0c\u5b83\u8868\u793a\u901a\u8fc7\u90e8\u5206\u53c2\u6570\u5e94\u7528\u7684\u65b9\u5f0f\u4ece\u5df2\u6709\u7684\u51fd\u6570\u4e2d\u884d\u751f\u51fa\u65b0\u7684\u51fd\u6570\u3002\u67ef\u91cc\u5316\u662f\u4e00\u79cd\u5c06\u591a\u53c2\u6570\u51fd\u6570\u8f6c\u5316\u4e3a\u5355\u53c2\u6570\u9ad8\u9636\u51fd\u6570\u7684\u6280\u672f\uff0c\u5982\u679c\u4f60\u56fa\u5b9a\u67d0\u4e9b\u53c2\u6570\uff0c\u4f60\u5c06\u5f97\u5230\u63a5\u53d7\u4f59\u4e0b\u53c2\u6570\u7684\u4e00\u4e2a\u51fd\u6570\u3002 \u5b9a\u4e49\u4e00\uff1a \u67ef\u91cc\u5316\uff1a\u4e00\u4e2a\u51fd\u6570\u4e2d\u6709\u4e2a\u591a\u4e2a\u53c2\u6570\uff0c\u60f3\u56fa\u5b9a\u5176\u4e2d\u67d0\u4e2a\u6216\u8005\u51e0\u4e2a\u53c2\u6570\u7684\u503c\uff0c\u800c\u53ea\u63a5\u53d7\u53e6\u5916\u51e0\u4e2a\u8fd8\u672a\u56fa\u5b9a\u7684\u53c2\u6570\uff0c\u8fd9\u6837\u51fd\u6570\u6f14\u53d8\u6210\u65b0\u7684\u51fd\u6570\u3002 \u5b9a\u4e49\u4e8c\uff1a \u51fd\u6570\u67ef\u91cc\u5316\uff08currying\uff09\u53c8\u79f0\u90e8\u5206\u6c42\u503c\u3002\u4e00\u4e2a currying \u7684\u51fd\u6570\u9996\u5148\u4f1a\u63a5\u53d7\u4e00\u4e9b\u53c2\u6570\uff0c\u63a5\u53d7\u4e86\u8fd9\u4e9b\u53c2\u6570\u4e4b\u540e\uff0c\u8be5\u51fd\u6570\u5e76\u4e0d\u4f1a\u7acb\u5373\u6c42\u503c\uff0c\u800c\u662f\u7ee7\u7eed\u8fd4\u56de\u53e6\u5916\u4e00\u4e2a\u51fd\u6570\uff0c\u521a\u624d\u4f20\u5165\u7684\u53c2\u6570\u5728\u51fd\u6570\u5f62\u6210\u7684\u95ed\u5305\u4e2d\u88ab\u4fdd\u5b58\u8d77\u6765\u3002\u5f85\u5230\u51fd\u6570\u88ab\u771f\u6b63\u9700\u8981\u6c42\u503c\u7684\u65f6\u5019\uff0c\u4e4b\u524d\u4f20\u5165\u7684\u6240\u6709\u53c2\u6570\u90fd\u4f1a\u88ab\u4e00\u6b21\u6027\u7528\u4e8e\u6c42\u503c\u3002 \u5b9a\u4e49\u4e09\uff1a \u4e00\u4e9b\u51fd\u6570\u5f0f\u8bed\u8a00\u7684\u5de5\u4f5c\u539f\u7406\u662f\u5c06\u591a\u53c2\u6570\u51fd\u6570\u8bed\u6cd5\u8f6c\u5316\u4e3a\u5355\u53c2\u6570\u51fd\u6570\u96c6\u5408\uff0c\u8fd9\u4e00\u8fc7\u7a0b\u79f0\u4e3a\u67ef\u91cc\u5316\uff0c\u5b83\u662f\u4ee5\u903b\u8f91\u5b66\u5bb6Haskell Curry\u7684\u540d\u5b57\u547d\u540d\u7684\u3002Haskell Curry\u4ece\u65e9\u671f\u6982\u5ff5\u4e2d\u53d1\u5c55\u51fa\u4e86\u8be5\u7406\u8bba\u3002\u5176\u5f62\u5f0f\u76f8\u5f53\u4e8e\u5c06z=f(x, y)\u8f6c\u6362\u6210z=f(x)(y)\u7684\u5f62\u5f0f\uff0c\u539f\u51fd\u6570\u7531\u4e24\u4e2a\u53c2\u6570\uff0c\u73b0\u5728\u53d8\u4e3a\u4e24\u4e2a\u63a5\u53d7\u5355\u53c2\u6570\u7684\u51fd\u6570\uff0c \u793a\u4f8b1\uff1a\u67ef\u91cc\u5316\u7684\u8fc7\u7a0b\u5c31\u662f\u628a\u539f\u6765\u5e26\u4e24\u4e2a\u53c2\u6570\u7684\u51fd\u6570add(x, y)\uff0c\u53d8\u6210\u4e86\u4e00\u4e2a\u5d4c\u5957\u51fd\u6570\uff0c\u5728add_currying\u51fd\u6570\u5185\uff0c\u53c8\u5b9a\u4e49\u4e86\u4e00\u4e2a_add\u51fd\u6570\uff0c\u5e76\u4e14_add\u51fd\u6570\u53c8\u5f15\u7528\u4e86\u5916\u90e8\u51fd\u6570add_currying\u7684\u53d8\u91cfx\uff0c\u8fd9\u5c31\u662f\u4e00\u4e2a\u95ed\u5305\u3002 \u95ed\u5305\uff0c\u4e00\u53e5\u8bdd\u8bf4\u5c31\u662f\u5728\u51fd\u6570\u4e2d\u518d\u5d4c\u5957\u4e00\u4e2a\u51fd\u6570\uff0c\u5e76\u4e14\u5f15\u7528\u5916\u90e8\u51fd\u6570\u7684\u53d8\u91cf\u3002 # \u666e\u901a\u5199\u6cd5 def add ( x , y ): return x + y print ( add ( 1 , 2 )) # 3 # \u67ef\u91cc\u5316\u5199\u6cd5 def add_currying ( x ): def _add ( y ): return x + y return _add print ( add_currying ( 1 )( 2 )) # 3 \u793a\u4f8b2\uff0c\u901a\u8fc7\u56fa\u5b9a\u5176\u4e2d\u7684\u7b2c\u4e8c\u4e2a\u53c2\u6570\u4e0d\u53d8\u6765\u5b9e\u73b0\u67ef\u91cc\u5316\u3002 def add2 ( a , b ): def add1 ( a , b , c ): return a + b + c return add1 ( a , 666 , b ) result6 = add2 ( 12 , 13 ) print ( result6 ) # 691 result6 = add2 ( 12 , 555 , 13 ) # TypeError: add2() takes 2 positional arguments but 3 were given \u793a\u4f8b3\uff0c\u901a\u8fc7functools\u63d0\u4f9b\u7684\u504f\u51fd\u6570\u6765\u5b9e\u73b0\u67ef\u91cc\u5316\u3002 from functools import partial def add1 ( a , b , c ): return a + b + c add3 = partial ( add1 , b = 666 ) result7 = add3 ( a = 12 , c = 13 ) print ( result7 ) # 691 \u793a\u4f8b4\uff0c\u901a\u8fc7lambda\u8868\u8fbe\u5f0f\u6765\u5b9e\u73b0\u67ef\u91cc\u5316\u3002 def add1 ( a , b , c ): return a + b + c add4 = lambda x , y : add1 ( x , 666 , y ) result8 = add4 ( 12 , 13 ) print ( result8 ) # 691 \u793a\u4f8b5\uff0c\u901a\u8fc7python\u7684\u88c5\u9970\u5668\u6765\u5b9e\u73b0\u67ef\u91cc\u5316 def add1 ( a , b , c ): return a + b + c def currying_add ( func ): def wrapper ( a , c , b = 666 ): return func ( a , b , c ) return wrapper result9 = currying_add ( add1 )( 12 , 13 ) print ( result9 ) # 691 \u793a\u4f8b6\uff0c\u901a\u8fc7python\u7684\u88c5\u9970\u5668\u7b26\u53f7@\u6765\u5b9e\u73b0\u67ef\u91cc\u5316 def currying_add ( func ): def wrapper ( a , c , b = 666 ): return func ( a , b , c ) return wrapper @currying_add def add5 ( a , b , c ): return a + b + c result10 = add5 ( 12 , 13 ) print ( result10 ) # 691","title":"6. \u67ef\u91cc\u5316\uff1a\u90e8\u5206\u53c2\u6570\u5e94\u7528"},{"location":"python/Foundation/ch03/#7","text":"","title":"7. \u8fed\u4ee3\u5668\u4e0e\u751f\u6210\u5668"},{"location":"python/Foundation/ch03/#_5","text":"\u8fed\u4ee3\u662fPython\u6700\u5f3a\u5927\u7684\u529f\u80fd\u4e4b\u4e00\uff0c\u662f\u8bbf\u95ee\u96c6\u5408\u5143\u7d20\u7684\u4e00\u79cd\u65b9\u5f0f\u3002\u8fed\u4ee3\u5668\u662f\u4e00\u4e2a\u53ef\u4ee5\u8bb0\u4f4f\u904d\u5386\u7684\u4f4d\u7f6e\u7684\u5bf9\u8c61\u3002 \u8fed\u4ee3\u5668\u5bf9\u8c61\u4ece\u96c6\u5408\u7684\u7b2c\u4e00\u4e2a\u5143\u7d20\u5f00\u59cb\u8bbf\u95ee\uff0c\u76f4\u5230\u6240\u6709\u7684\u5143\u7d20\u88ab\u8bbf\u95ee\u5b8c\u7ed3\u675f\u3002\u8fed\u4ee3\u5668\u53ea\u80fd\u5f80\u524d\u4e0d\u4f1a\u540e\u9000\u3002 \u8fed\u4ee3\u5668\u6709\u4e24\u4e2a\u57fa\u672c\u7684\u65b9\u6cd5\uff1aiter() \u548c next()\u3002 \u8fed\u4ee3\u5668\u793a\u4f8b\uff1a list_a = [ 1 , 2 , 3 , 4 ] it = iter ( list_a ) # \u521b\u5efa\u8fed\u4ee3\u5668\u5bf9\u8c61 print ( next ( it )) # \u8f93\u51fa\u8fed\u4ee3\u5668\u7684\u4e0b\u4e00\u4e2a\u5143\u7d20 # 1 print ( next ( it )) # \u8f93\u51fa\u8fed\u4ee3\u5668\u7684\u4e0b\u4e00\u4e2a\u5143\u7d20 # 2 \u8fed\u4ee3\u5668\u5bf9\u8c61\u53ef\u4ee5\u4f7f\u7528\u5e38\u89c4for\u8bed\u53e5\u8fdb\u884c\u904d\u5386\u3002 list_a = [ 1 , 2 , 3 , 4 ] it = iter ( list_a ) # \u521b\u5efa\u8fed\u4ee3\u5668\u5bf9\u8c61 for x in it : print ( x , end = \" \" ) print ( end = \" \\n \" ) # 1 2 3 4","title":"\u8fed\u4ee3\u5668"},{"location":"python/Foundation/ch03/#_6","text":"\u5728 Python \u4e2d\uff0c\u4f7f\u7528\u4e86 yield \u7684\u51fd\u6570\u88ab\u79f0\u4e3a\u751f\u6210\u5668\uff08generator\uff09\u3002\u8ddf\u666e\u901a\u51fd\u6570\u4e0d\u540c\u7684\u662f\uff0c\u751f\u6210\u5668\u662f\u4e00\u4e2a\u8fd4\u56de\u8fed\u4ee3\u5668\u7684\u51fd\u6570\uff0c\u53ea\u80fd\u7528\u4e8e\u8fed\u4ee3\u64cd\u4f5c\uff0c\u751f\u6210\u5668\u5c31\u662f\u4e00\u4e2a\u8fed\u4ee3\u5668\u3002 \u5728\u8c03\u7528\u751f\u6210\u5668\u8fd0\u884c\u7684\u8fc7\u7a0b\u4e2d\uff0c\u6bcf\u6b21\u9047\u5230 yield \u65f6\u51fd\u6570\u4f1a\u6682\u505c\u5e76\u4fdd\u5b58\u5f53\u524d\u6240\u6709\u7684\u8fd0\u884c\u4fe1\u606f\uff0c\u8fd4\u56de yield \u7684\u503c, \u5e76\u5728\u4e0b\u4e00\u6b21\u6267\u884c next() \u65b9\u6cd5\u65f6\u4ece\u5f53\u524d\u4f4d\u7f6e\u7ee7\u7eed\u8fd0\u884c\u3002 \u8c03\u7528\u4e00\u4e2a\u751f\u6210\u5668\u51fd\u6570\uff0c\u8fd4\u56de\u7684\u662f\u4e00\u4e2a\u8fed\u4ee3\u5668\u5bf9\u8c61\u3002 \u793a\u4f8b, \u6590\u6ce2\u90a3\u5951\u6570\u5217\uff1a def fibonacci ( n ): a , b , counter = 0 , 1 , 0 while True : if ( counter > n ): return yield a a , b = b , a + b counter += 1 f = fibonacci ( 10 ) # f \u662f\u4e00\u4e2a\u8fed\u4ee3\u5668\uff0c\u7531\u751f\u6210\u5668\u8fd4\u56de\u751f\u6210 print ( f ) # \u5b9e\u9645\u8c03\u7528\u751f\u6210\u5668\u65f6\uff0c\u4ee3\u7801\u5e76\u4e0d\u4f1a\u7acb\u5373\u6267\u884c for x in f : # \u8bf7\u6c42\u751f\u6210\u5668\u4e2d\u7684\u5143\u7d20\u65f6\uff0c\u5b83\u624d\u4f1a\u6267\u884c\u5b83\u7684\u4ee3\u7801 print ( x , end = \" \" ) print ( end = \" \\n \" ) # 0 1 1 2 3 5 8 13 21 34 55 \u751f\u6210\u5668\u8868\u8fbe\u5f0f\uff1a \u7528\u751f\u6210\u5668\u8868\u8fbe\u5f0f\u6765\u521b\u5efa\u751f\u6210\u5668\u66f4\u4e3a\u7b80\u5355\u3002\u751f\u6210\u5668\u8868\u8fbe\u5f0f\u4e0e\u5217\u8868\u3001\u5b57\u5178\u3001\u96c6\u5408\u7684\u63a8\u5bfc\u5f0f\u5f88\u7c7b\u4f3c\uff0c\u521b\u5efa\u4e00\u4e2a\u751f\u6210\u5668\u8868\u8fbe\u5f0f\uff0c\u53ea\u9700\u8981\u5c06\u5217\u8868\u63a8\u5bfc\u5f0f\u7684\u4e2d\u62ec\u53f7\u66ff\u6362\u4e3a\u5c0f\u62ec\u53f7\u5373\u53ef\u3002 gen1 = ( x ** 2 for x in range ( 100 )) print ( gen1 ) # at 0x7fd3f30c9580> \u4e0a\u9762\u7684\u4ee3\u7801\u4e0e\u4e0b\u9762\u7684\u751f\u6210\u5668\u662f\u7b49\u4ef7\u7684 def _make_gen (): for x in range ( 100 ): yield x ** 2 gen2 = _make_gen () print ( gen2 ) # \u751f\u6210\u5668\u8868\u8fbe\u5f0f\u53ef\u4ee5\u4f5c\u4e3a\u51fd\u6570\u53c2\u6570\u7528\u4e8e\u66ff\u4ee3\u5217\u8868\u63a8\u5bfc\u5f0f\u3002\u5bf9\u6bd4\u4e0b\u97622\u4e2a\u4f8b\u5b50\u3002 # \u793a\u4f8b1 result11 = sum ( x ** 2 for x in range ( 100 )) print ( result11 ) # 328350 gen1 = ( x ** 2 for x in range ( 100 )) result11 = sum ( gen1 ) print ( result11 ) # 328350 # \u793a\u4f8b2 result12 = dict (( i , i ** 2 ) for i in range ( 5 )) print ( result12 ) # {0: 0, 1: 1, 2: 4, 3: 9, 4: 16} gen2 = (( i , i ** 2 ) for i in range ( 5 )) result12 = dict ( gen2 ) print ( result12 ) # {0: 0, 1: 1, 2: 4, 3: 9, 4: 16}","title":"\u751f\u6210\u5668"},{"location":"python/Foundation/ch03/#itertools","text":"\u6807\u51c6\u5e93\u4e2d\u7684itertools\u6a21\u5757\u662f\u9002\u7528\u4e8e\u5927\u591a\u6570\u6570\u636e\u7b97\u6cd5\u7684\u751f\u6210\u5668\u96c6\u5408\u3002 import itertools first_letter = lambda x : x [ 0 ] names = [ 'Alan' , 'Adam' , 'Wes' , 'Will' , 'Albert' , 'Steven' ] for letter , names in itertools . groupby ( names , first_letter ): print ( letter ) print ( first_letter ) print ( letter , list ( names )) # names is generator # A # at 0x7fa598a7a0d0> # A ['Alan', 'Adam'] # W # at 0x7fa598a7a0d0> # W ['Wes', 'Will'] # A # at 0x7fa598a7a0d0> # A ['Albert'] # S # at 0x7fa598a7a0d0> # S ['Steven']","title":"\u751f\u6210\u5668\uff1aitertools\u6a21\u5757"},{"location":"python/Foundation/ch03/#8","text":"Python\u7528\u5f02\u5e38\u5bf9\u8c61(exception object)\u6765\u8868\u793a\u5f02\u5e38\u60c5\u51b5\u3002\u9047\u5230\u9519\u8bef\u540e\uff0c\u4f1a\u5f15\u53d1\u5f02\u5e38\u3002\u5982\u679c\u5f02\u5e38\u5bf9\u8c61\u5e76\u672a\u88ab\u5904\u7406\u6216\u6355\u6349\uff0c\u7a0b\u5e8f\u5c31\u4f1a\u7528\u6240\u8c13\u7684\u56de\u6eaf(traceback\uff0c \u4e00\u79cd\u9519\u8bef\u4fe1\u606f)\u7ec8\u6b62\u6267\u884c\u3002 \u5f02\u5e38\u548c\u8bed\u6cd5\u9519\u8bef\u662f\u6709\u533a\u522b\u7684\u3002 \u9519\u8bef\uff1a\u662f\u6307\u4ee3\u7801\u4e0d\u7b26\u5408\u89e3\u91ca\u5668\u6216\u8005\u7f16\u8bd1\u5668\u8bed\u6cd5\u3002 \u5f02\u5e38\uff1a\u662f\u6307\u4e0d\u5b8c\u6574\u3001\u4e0d\u5408\u6cd5\u8f93\u5165\uff0c\u6216\u8005\u8ba1\u7b97\u51fa\u73b0\u9519\u8bef\u3002 python\u91cc\u7528try...except...\u8bed\u53e5\u6765\u5904\u7406\u5f02\u5e38\u60c5\u51b5\u3002 def attempt_float ( x ): try : return float ( x ) except ( TypeError , ValueError ): return \"Type error, not numbers\" r1 = attempt_float ( '1.2256' ) print ( r1 ) # 1.2256 r1 = attempt_float ( 'friends' ) print ( r1 ) # Type error, not numbers","title":"8. \u9519\u8bef\u548c\u5f02\u5e38\u5904\u7406"},{"location":"python/Foundation/ch03/#9","text":"f=open(path, 'w')\uff0c\u4e00\u4e2a\u65b0\u7684\u6587\u4ef6\u4f1a\u5728path\u6307\u5b9a\u7684\u8def\u5f84\u88ab\u521b\u5efa\uff0c\u5e76\u5728\u540c\u4e00\u8def\u5f84\u4e0b\u8986\u76d6\u540c\u540d\u6587\u4ef6\u3002\uff08\u8bf7\u5c0f\u5fc3\uff01\uff09 f=open(path, 'x')\uff0c\u4e00\u4e2a\u65b0\u7684\u6587\u4ef6\u4f1a\u5728path\u6307\u5b9a\u7684\u8def\u5f84\u88ab\u521b\u5efa\uff0c\u5982\u679c\u7ed9\u5b9a\u8def\u5f84\u4e0b\u5df2\u7ecf\u5b58\u5728\u540c\u540d\u6587\u4ef6\u5c31\u4f1a\u521b\u5efa\u5931\u8d25\u3002 import os # \u67e5\u770b\u5f53\u524d\u8def\u5f84 os . getcwd () # '/opt/myMemo' # \u66f4\u6539\u6587\u4ef6\u8bfb\u53d6\u9ed8\u8ba4\u8def\u5f84 os . chdir ( '/opt/myMemo/python/datasets/examples' ) # \u6307\u5b9a\u6587\u4ef6\u540d path = 'file01.txt' # \u6253\u5f00\u6587\u4ef6 f = open ( path ) # \u8bfb\u53d6\u6587\u4ef6\u6bcf\u4e00\u884c\uff0c\u6587\u4ef6\u6bcf\u4e00\u884c\u4f5c\u4e3a\u5217\u8868\u4e00\u4e2a\u5143\u7d20 lines = [ x . rstrip () for x in open ( path )] # \u8f93\u51fa\u5217\u8868 print ( lines ) # \u5173\u95ed\u6587\u4ef6\u4f1a\u5c06\u8d44\u6e90\u91ca\u653e\u56de\u64cd\u4f5c\u7cfb\u7edf f . close () \u53e6\u4e00\u79cd\u66f4\u7b80\u5355\u7684\u5173\u95ed\u6587\u4ef6\u7684\u65b9\u5f0f import os # \u67e5\u770b\u5f53\u524d\u8def\u5f84 os . getcwd () # '/opt/myMemo' # \u66f4\u6539\u6587\u4ef6\u8bfb\u53d6\u9ed8\u8ba4\u8def\u5f84 os . chdir ( '/opt/myMemo/python/datasets/examples' ) # \u6307\u5b9a\u6587\u4ef6\u540d path = 'file01.txt' # \u6253\u5f00\u6587\u4ef6 f = open ( path ) # \u4f7f\u7528with\u8bed\u53e5\u8bfb\u53d6\u6587\u4ef6\uff0c\u6587\u4ef6\u4f1a\u5728with\u4ee3\u7801\u5757\u7ed3\u675f\u540e\u81ea\u52a8\u5173\u95ed\u3002 with open ( path ) as f : lines = [ x . rstrip () for x in open ( path )] # \u8f93\u51fa\uff1a\u6587\u4ef6\u6bcf\u4e00\u884c\u4f5c\u4e3a\u5217\u8868\u4e00\u4e2a\u5143\u7d20 print ( lines ) \u5728\u6253\u5f00\u6587\u4ef6\u65f6\u4f7f\u7528seek\u8bfb\u53d6\u6587\u4ef6\u5185\u5bb9\u8981\u5f53\u5fc3\u3002\u5982\u679c\u6587\u4ef6\u7684\u53e5\u67c4\u4f4d\u7f6e\u6070\u597d\u5728\u4e00\u4e2aUnicode\u7b26\u53f7\u7684\u5b57\u8282\u4e2d\u95f4\u65f6\uff0c\u540e\u7eed\u7684\u8bfb\u53d6\u4f1a\u5bfc\u81f4\u9519\u8bef\u3002 import os # \u67e5\u770b\u5f53\u524d\u8def\u5f84 os . getcwd () # '/opt/myMemo' # \u66f4\u6539\u6587\u4ef6\u8bfb\u53d6\u9ed8\u8ba4\u8def\u5f84 os . chdir ( '/opt/myMemo/python/datasets/examples' ) # \u6307\u5b9a\u6587\u4ef6\u540d path = 'file01.txt' # \u6253\u5f00\u6587\u4ef6 f = open ( path ) # \u8bfb\u53d6\u6587\u4ef6\u3002 print ( f . read ( 5 )) # \u8f93\u51fa\u524d5\u4e2a\u5b57\u7b26\u3002 read\u65b9\u6cd5\u901a\u8fc7\u8bfb\u53d6\u7684\u5b57\u8282\u6570\u6765\u63a8\u8fdb\u6587\u4ef6\u53e5\u67c4\u7684\u4f4d\u7f6e\u3002 # I Thi print ( f . tell ()) # tell\u65b9\u6cd5\u53ef\u4ee5\u7ed9\u51fa\u53e5\u67c4\u5f53\u524d\u7684\u4f4d\u7f6e # 5 print ( f . seek ( 6 )) # seek\u65b9\u6cd5\u53ef\u4ee5\u5c06\u53e5\u67c4\u4f4d\u7f6e\u6539\u53d8\u5230\u6587\u4ef6\u4e2d\u7279\u5b9a\u7684\u5b57\u8282 # 6 print ( f . read ( 1 )) # \u4ece\u7b2c7\u4e2a\u5b57\u8282\u5f00\u59cb\uff0c\u8f93\u51fa1\u4e2a\u5b57\u8282 # k # \u5173\u95ed\u6587\u4ef6\u4f1a\u5c06\u8d44\u6e90\u91ca\u653e\u56de\u64cd\u4f5c\u7cfb\u7edf f . close () \u5982\u679c\u4f7f\u7528\u4e8c\u8fdb\u5236\u65b9\u5f0f\u6253\u5f00\u6587\u4ef6\uff0c\u5219\uff1a import os # \u67e5\u770b\u5f53\u524d\u8def\u5f84 os . getcwd () # '/opt/myMemo' # \u66f4\u6539\u6587\u4ef6\u8bfb\u53d6\u9ed8\u8ba4\u8def\u5f84 os . chdir ( '/opt/myMemo/python/datasets/examples' ) # \u6307\u5b9a\u6587\u4ef6\u540d path = 'file01.txt' # \u6253\u5f00\u6587\u4ef6 f2 = open ( path , 'rb' ) # \u4e8c\u8fdb\u5236\u6a21\u5f0f # \u8bfb\u53d6\u6587\u4ef6 print ( f2 . read ( 5 )) # \u7b2c\u4e00\u4e2ab\u4ee3\u8868\u4e8c\u8fdb\u5236\u683c\u5f0f # b'I Thi' print ( f2 . tell ()) # 5 print ( f2 . seek ( 6 )) # 6 print ( f2 . read ( 2 )) # \u4ece\u7b2c7\u4e2a\u5b57\u8282\u5f00\u59cb\uff0c\u8f93\u51fa2\u4e2a\u5b57\u8282 # b'k ' # \u5173\u95ed\u6587\u4ef6\u4f1a\u5c06\u8d44\u6e90\u91ca\u653e\u56de\u64cd\u4f5c\u7cfb\u7edf f2 . close () \u5c06\u672c\u6587\u5199\u5165\u6587\u4ef6\uff0c\u53ef\u4ee5\u4f7f\u7528\u6587\u4ef6\u5bf9\u8c61\u7684write\u6216wirtelines\u65b9\u6cd5\u3002 import os # \u67e5\u770b\u5f53\u524d\u8def\u5f84 os . getcwd () # '/opt/myMemo' # \u66f4\u6539\u6587\u4ef6\u8bfb\u53d6\u9ed8\u8ba4\u8def\u5f84 os . chdir ( '/opt/myMemo/python/datasets/examples' ) # \u6307\u5b9a\u6587\u4ef6\u540d path1 = 'file01.txt' path2 = 'file02.txt' # file02.txt\u662f\u4e00\u4e2a\u7a7a\u6587\u4ef6 with open ( path2 , 'r+' , encoding = 'utf-8' ) as f : f . writelines ( x for x in open ( path1 , 'r' , encoding = 'utf-8' ) if len ( x ) > 1 ) # \u628afile01.txt\u7684\u5185\u5bb9\u5199\u5165file02.txt lines = f . readlines () print ( lines )","title":"9. \u6587\u4ef6\u4e0e\u64cd\u4f5c\u7cfb\u7edf"},{"location":"python/Foundation/ch03/#10","text":"","title":"10. \u88c5\u9970\u5668"},{"location":"python/Foundation/ch03/#_7","text":"\u7ef4\u57fa\u767e\u79d1\u4e2d\u7684\u89e3\u91ca\uff1a \u95ed\u5305\uff08Closure\uff09 \uff0c\u53c8\u79f0\u8bcd\u6cd5\u95ed\u5305\uff08Lexical Closure\uff09\u6216\u51fd\u6570\u95ed\u5305\uff08function closures\uff09\uff0c\u662f\u5f15\u7528\u4e86\u81ea\u7531\u53d8\u91cf\u7684\u51fd\u6570\u3002\u8fd9\u4e2a\u88ab\u5f15\u7528\u7684\u81ea\u7531\u53d8\u91cf\u5c06\u548c\u8fd9\u4e2a\u51fd\u6570\u4e00\u540c\u5b58\u5728\uff0c\u5373\u4f7f\u5df2\u7ecf\u79bb\u5f00\u4e86\u521b\u9020\u5b83\u7684\u73af\u5883\u4e5f\u4e0d\u4f8b\u5916\u3002 \u95ed\u5305\u5ef6\u4f38\u4e86\u4f5c\u7528\u57df\u7684\u51fd\u6570\uff0c\u5176\u4e2d\u5305\u542b\u51fd\u6570\u5b9a\u4e49\u4f53\u4e2d\u5f15\u7528\u3001\u4f46\u662f\u4e0d\u5728\u5b9a\u4e49\u4f53\u4e2d\u5b9a\u4e49\u7684\u975e\u5168\u5c40\u53d8\u91cf\u3002\u51fd\u6570\u662f\u4e0d\u662f\u533f\u540d\u7684\u6ca1\u6709\u5173\u7cfb\uff0c\u5173\u952e\u662f\u5b83\u80fd\u8bbf\u95ee\u5b9a\u4e49\u4f53\u4e4b\u5916\u5b9a\u4e49\u7684\u975e\u5168\u5c40\u53d8\u91cf\u3002 \u4f8b\u4e00\uff0c\u8ba1\u7b97\u79fb\u52a8\u5e73\u5747\u503c\u3002 \u4e0b\u9762\u662f\u662f\u4f20\u7edf\u7c7b\u5b9e\u73b0\u65b9\u5f0f\uff0cAvg\u7684\u5b9e\u4f8b\u662f\u53ef\u8c03\u7528\u7684\u5bf9\u8c61\u3002 class Avg (): def __init__ ( self ): self . mylist = [] def __call__ ( self , newValue ): self . mylist . append ( newValue ) total = sum ( self . mylist ) return total / len ( self . mylist ) avg = Avg () avg ( 10 ) # 10.0 avg ( 20 ) # 15.0 avg ( 30 ) # 20.0 \u4e0b\u9762\u662f\u9ad8\u9636\u51fd\u6570\u5b9e\u73b0\u65b9\u5f0f\u3002\u8c03\u7528 make_avg \u65f6\uff0c\u8fd4\u56de\u4e00\u4e2a my_avg \u51fd\u6570\u5bf9\u8c61\u3002\u6bcf\u6b21\u8c03\u7528 my_avg \u65f6\uff0c\u5b83\u4f1a\u628a\u53c2\u6570\u6dfb\u52a0\u5230\u7cfb\u5217\u503c\u4e2d\uff0c\u7136\u540e\u8ba1\u7b97\u5f53\u524d\u5e73\u5747\u503c\u3002 def make_avg (): my_list = [] def avg ( newValue ): my_list . append ( newValue ) total = sum ( my_list ) return total / len ( my_list ) return avg my_avg = make_avg () my_avg ( 10 ) # 10.0 my_avg ( 20 ) # 15.0 my_avg ( 30 ) # 20.0 my_avg . __code__ . co_varnames # ('newValue', 'total') my_avg . __code__ . co_freevars # ('my_list',) my_avg . __closure__ # (,) my_avg . __closure__ [ 0 ] . cell_contents # [10, 20, 30] \u8fd9\u4e24\u4e2a\u793a\u4f8b\u6709\u5171\u901a\u4e4b\u5904\uff1a\u8c03\u7528 Avg() \u6216 make_avg() \u5f97\u5230\u4e00\u4e2a\u53ef\u8c03\u7528\u5bf9\u8c61 avg \uff0c\u5b83\u4f1a\u66f4\u65b0\u5386\u53f2\u503c\uff0c\u7136\u540e\u8ba1\u7b97\u5f53\u524d\u5747\u503c\u3002 \u5728\u7c7b\u5b9e\u73b0\u4e2d\uff0c avg \u662f Avg \u7684\u5b9e\u4f8b\uff1b\u5728\u9ad8\u9636\u51fd\u6570\u5b9e\u73b0\u4e2d\u662f\u5185\u90e8\u51fd\u6570 avg \u3002 \u4e24\u79cd\u5b9e\u73b0\u65b9\u5f0f\u4e2d\uff0c\u6211\u4eec\u90fd\u53ea\u9700\u8c03\u7528 avg(n) \uff0c\u628a n \u653e\u5165\u7cfb\u5217\u503c\u4e2d\uff0c\u7136\u540e\u91cd\u65b0\u8ba1\u7b97\u5747\u503c\u3002 \u7b2c\u4e00\u4e2a\u4f8b\u5b50\u4e2d\uff0c Avg \u7c7b\u7684\u5b9e\u4f8b avg \u5728 self.series \u5b9e\u4f8b\u5c5e\u6027\u4e2d\u5b58\u50a8\u5386\u53f2\u503c\u3002 \u7b2c\u4e8c\u4e2a\u4f8b\u5b50\u4e2d\u7684 my_list \u662f\u51fd\u6570 make_avg() \u7684\u5c40\u90e8\u53d8\u91cf\uff0c\u4e5f\u79f0\u4e3a\u8be5\u51fd\u6570\u7684**\u81ea\u7531\u53d8\u91cf\uff08free variable\uff09**\uff0c\u6307\u672a\u5728\u672c\u5730\u4f5c\u7528\u57df\u4e2d\u7ed1\u5b9a\u7684\u53d8\u91cf\u3002 avg() \u51fd\u6570\u7684\u95ed\u5305\u5ef6\u4f38\u5230\u51fd\u6570\u7684\u4f5c\u7528\u57df\u4e4b\u5916\uff0c\u5305\u542b\u4e86 make_avg() \u7684\u81ea\u7531\u53d8\u91cf my_list \u7684\u7ed1\u5b9a\u3002 \u5bf9\u4e8e\u8fd4\u56de\u7684 my_avg \u5bf9\u8c61\uff0c\u5176 __code__ \u5c5e\u6027\uff08\u8868\u793a\u7f16\u8bd1\u540e\u7684\u51fd\u6570\u5b9a\u4e49\u4f53\uff09\u4e2d\u4fdd\u5b58\u4e86\u5c40\u90e8\u53d8\u91cf\u548c\u81ea\u7531\u53d8\u91cf\u7684\u540d\u79f0\uff0c\u5373 my_avg.__code__.co_varnames \u8fd4\u56de\u4e86\u5c40\u90e8\u53d8\u91cf ('newValue', 'total') \u548c my_avg.__code__.co_freevars \u8fd4\u56de\u4e86\u81ea\u7531\u53d8\u91cf ('my_list',) \u3002 \u81ea\u7531\u53d8\u91cf my_list \u7ed1\u5b9a\u5728\u8fd4\u56de\u7684 my_avg \u7684 __closure__ \u7684\u5c5e\u6027\u4e2d\uff0c my_avg.__closure__ \u4e2d\u7684\u5404\u4e2a\u5143\u7d20\u5bf9\u5e94\u4e86 my_avg.__code__.co_freevars \u4e2d\u7684\u4e00\u4e2a\u540d\u79f0\u3002\u8fd9\u4e9b\u5143\u7d20\u662f cell \u5bf9\u8c61\uff0c\u6709\u4e2a cell_contents \u5c5e\u6027\uff0c\u5982\uff1a my_avg.__closure__ \u8fd4\u56de (,) \uff0c\u91cc\u9762\u4fdd\u5b58\u7740\u771f\u6b63\u7684\u503c\uff0c\u5982 my_avg.__closure__[0].cell_contents \u91cc\u9762\u4fdd\u5b58\u6bcf\u6b21\u8c03\u7528\u7684\u771f\u5b9e\u503c [10, 20, 30] \u3002 \u4e0a\u9762 my_list \u662f\u4e00\u4e2a\u53ef\u53d8\u7c7b\u578b\uff0c\u5982\u679c\u7528\u4e0d\u53ef\u53d8\u7c7b\u578b\u6539\u5199\uff0c\u5e76\u5b9e\u73b0\u95ed\u5305\uff0c\u53ef\u4ee5\u4f7f\u7528 nolocal \u8fdb\u884c\u58f0\u660e\u3002\u5b83\u7684\u4f5c\u7528\u662f\u628a\u53d8\u91cf\u6807\u8bb0\u4e3a\u81ea\u7531\u53d8\u91cf\uff0c\u5373\u4f7f\u5728\u51fd\u6570\u4e2d\u4e3a\u53d8\u91cf\u8d4b\u4e88\u65b0\u503c\u4e86\uff0c\u4e5f\u4f1a\u53d8\u6210\u81ea\u7531\u53d8\u91cf\u3002\u5982\u679c\u4e3anonlocal\u58f0\u660e\u7684\u53d8\u91cf\u8d4b\u4e88\u65b0\u503c\uff0c\u95ed\u5305\u4e2d\u4fdd\u5b58\u7684\u7ed1\u5b9a\u4f1a\u66f4\u65b0\u3002 my_avg.__code__.co_freevars \u8fd4\u56de\u4e862\u4e2a\u81ea\u7531\u53d8\u91cf ('count', 'total') \uff0c\u5e76\u5728 my_avg.__closure__[0].cell_contents \u548c my_avg.__closure__[1].cell_contents \u91cc\u9762\u4fdd\u5b58\u4e86\u6700\u540e\u4e00\u6b21\u6267\u884c\u7684\u771f\u5b9e\u503c\u3002 def make_avg (): count = 0 total = 0 def avg ( newValue ): nonlocal count , total count += 1 total += newValue return total / count return avg my_avg = make_avg () my_avg ( 10 ) # 10.0 my_avg ( 20 ) # 15.0 my_avg ( 30 ) # 20.0 my_avg . __code__ . co_varnames # ('newValue',) my_avg . __code__ . co_freevars # ('count', 'total') my_avg . __closure__ # (, ) my_avg . __closure__ [ 0 ] . cell_contents # 3 my_avg . __closure__ [ 1 ] . cell_contents # 60 \u4f8b\u4e8c\uff1a money \u662f\u4e00\u4e2a\u5c40\u90e8\u53d8\u91cf\uff0c\u5728 get_money \u662f\u5916\u56f4\u51fd\u6570\uff0c\u51fd\u6570\u6267\u884c\u4e4b\u540e\u5e94\u8be5\u5c31\u4e0d\u4f1a\u5b58\u5728\u4e86\u3002 \u4f46\u662f\u5d4c\u5957\u51fd\u6570 work \u5f15\u7528\u4e86 money \u8fd9\u4e2a\u81ea\u7531\u53d8\u91cf\uff0c\u5c06\u8fd9\u4e2a\u5c40\u90e8\u53d8\u91cf\u5c01\u95ed\u5728\u4e86\u5d4c\u5957\u51fd\u6570 work \u4e2d\uff0c\u8fd9\u6837\u5c31\u5f62\u6210\u4e86\u4e00\u4e2a\u95ed\u5305\u3002 closure = get_money() \u83b7\u5f97\u7684\u5c31\u662f\u4e00\u4e2a\u95ed\u5305\u3002 closure() \u8f93\u51fa\u95ed\u5305\uff0c\u5373\uff0c\u6267\u884c\u4e86 work() \uff0c\u6253\u5370\u8f93\u51fa money \u7684\u503c\u3002 \u672c\u5730\u51fd\u6570\u901a\u8fc7global\u58f0\u660e\u5bf9\u5168\u5c40\u53d8\u91cf\u8fdb\u884c\u5f15\u7528\u4fee\u6539\uff0c\u90a3\u4e48\u5bf9\u4e8e\u5185\u5d4c\u51fd\u6570 work() \u4f5c\u7528\u57df\u4e2d\u7684\u53d8\u91cf\u8fdb\u884c\u4fee\u6539\uff0c\u5c31\u8981\u4f7f\u7528 nonlocal \u8fdb\u884c\u58f0\u660e\u3002 def get_money (): money = 0 def work (): nonlocal money money += 100 print ( money ) return work closure = get_money () closure () # 100 closure () # 200 closure () # 300 \u4f8b\u4e09\uff1a \u51fd\u6570 maker \u4e2d\u5b9a\u4e49\u4e86\u51fd\u6570 action \uff0c action \u5f15\u7528\u4e86 maker \u5d4c\u5957\u4f5c\u7528\u57df\u5185\u7684\u53d8\u91cf k \uff0c\u5e76\u4e14\uff0c maker \u5c06\u51fd\u6570 action \u4f5c\u4e3a\u8fd4\u56de\u5bf9\u8c61\u8fdb\u884c\u8fd4\u56de\u3002 \u8fd9\u6837\uff0c\u6211\u4eec\u901a\u8fc7\u6267\u884c f = maker(2) \uff0c f \u83b7\u53d6\u4e86\u8fd4\u56de\u5bf9\u8c61 action \uff0c\u867d\u7136\u6b64\u65f6 maker \u51fd\u6570\u4ee5\u53ca\u7ed3\u675f\u9000\u51fa\u4e86\uff0c\u4f46\u5bf9\u8c61 f \u4ecd\u7136\u8bb0\u4f4f\u4e86\u51fd\u6570 maker \u5d4c\u5957\u4f5c\u7528\u57df\u5185\u7684\u53d8\u91cf k \u548c n \uff0c\u5e76\u5728\u6267\u884c f(3) \u65f6\uff0c\u5c06 x=3 \u4ee5\u53ca\u4e4b\u524d\u8bb0\u4f4f\u7684 k \u548c n \uff0c\u4e00\u5e76\u4f20\u5165 action() \uff0c\u8ba1\u7b97\u5e76\u8fd4\u56de x + n + k \u503c\u3002 make \u4e5f\u79f0\u4e3a**\u5de5\u5382\u51fd\u6570**\u3002 def maker ( n ): k = 8 def action ( x ): return x + n + k return action f = maker ( 2 ) print ( f ( 3 )) # 13 print ( f ( 4 )) # 14 print ( f ( 5 )) # 15 \u7ed3\u5408\u524d\u97622\u4e2a\u4f8b\u5b50\u518d\u770b\u4e0a\u9762\u7684\u89e3\u91ca\uff0c\u95ed\u5305\u5c31\u662f\u5f15\u7528\u4e86\u81ea\u7531\u53d8\u91cf\u7684\u51fd\u6570\uff0c\u8fd9\u4e2a\u51fd\u6570\u4fdd\u5b58\u4e86\u6267\u884c\u7684\u4e0a\u4e0b\u6587\uff0c\u53ef\u4ee5\u8131\u79bb\u539f\u672c\u7684\u4f5c\u7528\u57df\u72ec\u7acb\u5b58\u5728\u3002","title":"\u95ed\u5305"},{"location":"python/Foundation/ch03/#_8","text":"\u770b\u4e0b\u9762\u4f8b\u5b50\uff0c\u5c06\u51fd\u6570\u4f5c\u4e3a\u53c2\u6570\u4f20\u7ed9\u53e6\u4e00\u4e2a\u51fd\u6570\uff0c\u51fd\u6570 my_decorator \u7684\u4f20\u5165\u53c2\u6570\u6b63\u597d\u662f\u5176\u5d4c\u5957\u51fd\u6570 myFunc \u3002 def my_decorator ( nestedFunc ): def myFunc (): print ( \"Before executing nestedFunc()\" ) nestedFunc () print ( \"After executing nestedFunc()\" ) return myFunc def nestedFunc (): print ( \"Decoration - executing nestedFunc()\" ) nestedFunc () # Decoration - executing nestedFunc() nestedFunc = my_decorator ( nestedFunc ) nestedFunc () # Before executing nestedFunc() # Decoration - executing nestedFunc() # After executing nestedFunc() \u88c5\u9970\u5668\u53ea\u662f\u4e2a\u65b9\u6cd5\uff0c\u4f7f\u7528\u65f6\u7528\u4e86 @ \u8bed\u6cd5\u3002 @ \u8bed\u6cd5\u53ea\u662f\u5c06\u51fd\u6570 nestedFunc \u4f20\u5165\u88c5\u9970\u5668\u51fd\u6570 my_decorator \u3002 @my_decorator \u662f nestedFunc = my_decorator(nestedFunc) \u7684\u5feb\u6377\u8868\u8fbe\u65b9\u5f0f\uff0c @my_decorator def nestedFunc (): print ( \"New added to decoration - executing nestedFunc()\" ) nestedFunc () # Before executing nestedFunc() # New added to decoration - executing nestedFunc() # After executing nestedFunc() print ( nestedFunc . __name__ ) # myFunc \u4f46\u4e0a\u4f8b\u6700\u540e\u7684\u8f93\u51fa\u4e0d\u662f\u6211\u4eec\u60f3\u8981\u7684\uff0c\u6211\u4eec\u5e0c\u671b\u8f93\u51fa nestedFunc \uff0c\u4f46\u5374\u88ab myFunc \u66ff\u4ee3\u4e86\uff0c\u5b83\u91cd\u5199\u4e86\u6211\u4eec\u51fd\u6570\u7684\u540d\u5b57\u548c\u6ce8\u91ca\u6587\u6863(docstring)\u3002 \u4e0b\u9762\u4f7f\u7528 functools.wraps \u6765\u4fee\u6b63\u4e0a\u9762\u7684\u95ee\u9898\u3002 from functools import wraps def my_decorator ( nestedFunc ): @wraps ( nestedFunc ) def myFunc (): print ( \"Before executing nestedFunc()\" ) nestedFunc () print ( \"After executing nestedFunc()\" ) return myFunc def nestedFunc (): print ( \"Decoration - executing nestedFunc()\" ) @my_decorator def nestedFunc (): print ( \"New added to decoration - executing nestedFunc()\" ) nestedFunc () # Before executing nestedFunc() # New added to decoration - executing nestedFunc() # After executing nestedFunc() print ( nestedFunc . __name__ ) # nestedFunc \u4e0b\u9762\u662f\u88c5\u9970\u5668\u7684\u84dd\u672c\u89c4\u8303\u3002 from functools import wraps def decorator_name ( f ): @wraps ( f ) def decorated ( * args , ** kwargs ): if not can_run : return \"Function will not run\" return f ( * args , ** kwargs ) return decorated @decorator_name def func (): return ( \"Function is running\" ) can_run = True print ( func ()) # Output: Function is running can_run = False print ( func ()) # Output: Function will not run \u4e0b\u9762\u8fd8\u662f\u4e00\u4e2a\u88c5\u9970\u5668\u7684\u4f8b\u5b50\u3002\u628a\u4e0b\u9762\u7684\u4ee3\u7801\u6bb5\u4fdd\u5b58\u5230\u6587\u4ef6 test.py \u3002 registry = [] def register ( func ): print ( f 'running register { func } ' ) registry . append ( func ) return func @register def f1 (): print ( 'running f1()' ) @register def f2 (): print ( 'running f2()' ) def f3 (): print ( 'running f3()' ) def main (): print ( 'runnning main()' ) print ( f 'registry--> { registry } ' ) f1 () f2 () f3 () if __name__ == '__main__' : main () \u6267\u884c\u4e0a\u8ff0\u4ee3\u7801\u6bb5 python3 test.py \uff0c\u5f97\u5230\u4e0b\u9762\u7684\u7ed3\u679c\u3002 running register < function f1 at 0x7f70847bec80 > running register < function f2 at 0x7f70705aa9d8 > runnning main () registry --> [ < function f1 at 0x7f70847bec80 > , < function f2 at 0x7f70705aa9d8 > ] running f1 () running f2 () running f3 () register \u5728\u6a21\u5757\u4e2d\u5176\u4ed6\u51fd\u6570\u4e4b\u524d\u8fd0\u884c\uff08\u4e24\u6b21\uff09\u3002\u8c03\u7528 register \u65f6\uff0c\u4f20\u7ed9\u5b83\u7684\u53c2\u6570\u662f\u88ab\u88c5\u9970\u7684\u51fd\u6570\uff0c\u4f8b\u5982 function f1 at 0x7f70847bec80> \u3002\u52a0\u8f7d\u6a21\u5757\u540e\uff0c registry \u4e2d\u6709\u4e24\u4e2a\u88ab\u88c5\u9970\u51fd\u6570\u7684\u5f15\u7528\uff1a f1 \u548c f2 \u3002\u8fd9\u4e24\u4e2a\u51fd\u6570\uff0c\u4ee5\u53ca f3 \uff0c\u53ea\u5728 main \u660e\u786e\u8c03\u7528\u5b83\u4eec\u65f6\u624d\u6267\u884c\u3002 \u7531\u6b64\u5f97\uff0c\u51fd\u6570\u88c5\u9970\u5668\u5728\u5bfc\u5165\u6a21\u5757\u65f6\u7acb\u5373\u6267\u884c\uff0c\u800c\u88ab\u88c5\u9970\u7684\u51fd\u6570\u53ea\u5728\u660e\u786e\u8c03\u7528\u65f6\u8fd0\u884c\uff0c\u5373Python\u4e2d\u63d0\u5230\u7684**\u5bfc\u5165\u65f6**\u548c**\u8fd0\u884c\u65f6**\u4e4b\u95f4\u7684\u533a\u522b\u3002 \u4e0a\u9762\u4f8b\u5b50\u4e2d\u88c5\u9970\u5668\u51fd\u6570\u4e0e\u88ab\u88c5\u9970\u7684\u51fd\u6570\u5728\u540c\u4e00\u4e2a\u6a21\u5757\u4e2d\u5b9a\u4e49\u3002\u5b9e\u9645\u5e94\u7528\u4e2d\uff0c\u88c5\u9970\u5668\u901a\u5e38\u5728\u4e00\u4e2a\u6a21\u5757\u4e2d\u5b9a\u4e49\uff0c\u7136\u540e\u5e94\u7528\u5230\u5176\u4ed6\u6a21\u5757\u4e2d\u7684\u51fd\u6570\u4e0a\u3002 \u4e0a\u9762\u4f8b\u5b50\u4e2d register \u88c5\u9970\u5668\u8fd4\u56de\u7684\u51fd\u6570\u4e0e\u901a\u8fc7\u53c2\u6570\u4f20\u5165\u7684\u76f8\u540c\u3002\u5b9e\u9645\u5e94\u7528\u4e2d\uff0c\u5927\u591a\u6570\u88c5\u9970\u5668\u4f1a\u5728\u5185\u90e8\u5b9a\u4e49\u4e00\u4e2a\u51fd\u6570\uff0c\u7136\u540e\u5c06\u5176\u8fd4\u56de\u3002","title":"\u88c5\u9970\u5668"},{"location":"python/Foundation/ch04/","text":"Python\u9762\u5411\u5bf9\u8c61\u6982\u5ff5 \u00b6 \u7c7b(class)\u628a\u6570\u636e\u4e0e\u529f\u80fd\u7ed1\u5b9a\u5728\u4e00\u8d77\u3002\u521b\u5efa\u65b0\u7c7b\u5c31\u662f\u521b\u5efa\u65b0\u7684\u5bf9\u8c61\u7c7b\u578b\uff08type of object\uff09\uff0c\u4ece\u800c\u521b\u5efa\u8be5\u7c7b\u578b\u7684\u65b0\u5b9e\u4f8b\uff08instances\uff09\u3002 \u7c7b\u5b9e\u4f8b\u5177\u6709\u591a\u79cd\u4fdd\u6301\u81ea\u8eab\u72b6\u6001\u7684\u5c5e\u6027\uff08attributes\uff09\u3002 \u7c7b\u5b9e\u4f8b\u8fd8\u652f\u6301\uff08\u7531\u7c7b\u5b9a\u4e49\u7684\uff09\u4fee\u6539\u81ea\u8eab\u72b6\u6001\u7684\u65b9\u6cd5\uff08methods\uff09\u3002 Python\u7684\u7c7b\u652f\u6301\u6240\u6709\u9762\u5411\u5bf9\u8c61\u7f16\u7a0b\uff08OOP\uff09\u7684\u6807\u51c6\u7279\u6027\uff1a \u7c7b\u7ee7\u627f\uff08class inheritance\uff09\u673a\u5236\u652f\u6301\u591a\u4e2a\u57fa\u7c7b\uff08base classes\uff09\uff1b \u6d3e\u751f\u7c7b\uff08derived class\uff09\u53ef\u4ee5\u8986\u76d6\u57fa\u7c7b\u7684\u4efb\u4f55\u65b9\u6cd5\uff08methods\uff09\uff1b \u7c7b\u7684\u65b9\u6cd5\u53ef\u4ee5\u8c03\u7528\u57fa\u7c7b\u4e2d\u76f8\u540c\u540d\u79f0\u7684\u65b9\u6cd5 \u5bf9\u8c61\u53ef\u4ee5\u5305\u542b\u4efb\u610f\u6570\u91cf\u548c\u7c7b\u578b\u7684\u6570\u636e\u3002 \u7c7b\uff08class\uff09\u548c\u6a21\u5757\uff08module\uff09\u90fd\u62e5\u6709\u52a8\u6001\u7279\u6027\uff08dynamic nature\uff09\uff1a\u5728\u8fd0\u884c\u65f6\u521b\u5efa\uff0c\u521b\u5efa\u540e\u4e5f\u53ef\u4ee5\u4fee\u6539\u3002 \u540d\u79f0Names\u548c\u5bf9\u8c61Objects \u00b6 \u5bf9\u8c61\u4e4b\u95f4\u76f8\u4e92\u72ec\u7acb\uff0c\u591a\u4e2a\u540d\u79f0\uff08names\uff09\uff08\u5728\u591a\u4e2a\u4f5c\u7528\u57df\u5185\uff09\u53ef\u4ee5\u7ed1\u5b9a\u5230\u540c\u4e00\u4e2a\u5bf9\u8c61\u3002 \u5176\u4ed6\u8bed\u8a00\u79f0\u4e4b\u4e3a\u522b\u540d\uff08alias\uff09\u3002 \u522b\u540d\u5728\u67d0\u4e9b\u65b9\u9762\u5c31\u50cf\u6307\u9488\u3002\u4f8b\u5982\uff0c\u4f20\u9012\u5bf9\u8c61\u7684\u4ee3\u4ef7\u5f88\u5c0f\uff0c\u56e0\u4e3a\u5b9e\u73b0\u53ea\u4f20\u9012\u4e00\u4e2a\u6307\u9488\uff1b\u5982\u679c\u51fd\u6570\u4fee\u6539\u4e86\u4f5c\u4e3a\u53c2\u6570\u4f20\u9012\u7684\u5bf9\u8c61\uff0c\u8c03\u7528\u8005\u5c31\u53ef\u4ee5\u770b\u5230\u66f4\u6539\u3002 \u4f5c\u7528\u57dfScopes\u548c\u547d\u540d\u7a7a\u95f4Namespaces \u00b6 **\u547d\u540d\u7a7a\u95f4\uff08namespace\uff09**\u662f\u4e00\u4e2a\u4ece\u540d\u5b57\u5230\u5bf9\u8c61\u7684\u6620\u5c04\u3002 \u5f53\u524d\u5927\u90e8\u5206\u547d\u540d\u7a7a\u95f4\u90fd\u7531 Python \u5b57\u5178\u5b9e\u73b0\u3002 \u4e0b\u9762\u662f\u51e0\u4e2a\u547d\u540d\u7a7a\u95f4\u7684\u4f8b\u5b50\uff1a \u5b58\u653e\u5185\u7f6e\u51fd\u6570\u7684\u96c6\u5408\uff08\u5305\u542b abs() \u8fd9\u6837\u7684\u51fd\u6570\uff0c\u548c\u5185\u5efa\u7684\u5f02\u5e38\u7b49\uff09\uff1b \u6a21\u5757\u4e2d\u7684\u5168\u5c40\u540d\u79f0\uff1b \u51fd\u6570\u8c03\u7528\u4e2d\u7684\u5c40\u90e8\u540d\u79f0\uff1b \u4ece\u67d0\u79cd\u610f\u4e49\u4e0a\u8bf4\uff0c \u5bf9\u8c61\u7684\u5c5e\u6027\u96c6\u5408\uff08the set of attributes of an object\uff09\u4e5f\u662f\u4e00\u79cd\u547d\u540d\u7a7a\u95f4\u7684\u5f62\u5f0f \u3002 \u5173\u4e8e\u547d\u540d\u7a7a\u95f4\u7684\u91cd\u8981\u4e00\u70b9\u662f\uff0c\u4e0d\u540c\u547d\u540d\u7a7a\u95f4\u4e2d\u7684\u540d\u79f0\u4e4b\u95f4\u7edd\u5bf9\u6ca1\u6709\u5173\u7cfb\uff1b \u4f8b\u5982\uff0c\u5728\u4e24\u4e2a\u4e0d\u540c\u7684\u6a21\u5757\u4e2d\u90fd\u53ef\u4ee5\u5b9a\u4e49\u4e00\u4e2a maximize \u51fd\u6570\u800c\u4e0d\u4f1a\u4ea7\u751f\u6df7\u6dc6\uff0c\u4f46\u5728\u8c03\u7528 maximize \u51fd\u6570\u65f6\u5fc5\u987b\u5fc5\u987b\u5728\u5176\u524d\u9762\u52a0\u4e0a\u6a21\u5757\u540d\u79f0\u3002 \u4efb\u4f55\u8ddf\u5728\u4e00\u4e2a\u70b9\u53f7\u4e4b\u540e\u7684\u540d\u79f0\u90fd\u79f0\u4e3a**\u5c5e\u6027\uff08attribute\uff09**\u3002\u4f8b\u5982\uff0c\u5728\u8868\u8fbe\u5f0f z.real \u4e2d\uff0c real \u662f\u5bf9\u8c61 z \u7684\u4e00\u4e2a\u5c5e\u6027\u3002 \u6309\u4e25\u683c\u7684\u8bf4\u6cd5\uff0c \u5bf9\u6a21\u5757\uff08module\uff09\u4e2d\u7684\u540d\u79f0\u7684\u5f15\u7528\uff08reference\uff09\u90fd\u5c5e\u4e8e\u5c5e\u6027\u5f15\u7528\uff08attribute reference\uff09 \uff1a \u5728\u8868\u8fbe\u5f0f modname.funcname \u4e2d\uff0c modname \u662f\u4e00\u4e2a\u6a21\u5757\u5bf9\u8c61\uff08module object\uff09\u800c funcname \u662f\u5b83\u7684\u4e00\u4e2a\u5c5e\u6027\u3002 \u5728\u6b64\u60c5\u51b5\u4e0b\u5728\u6a21\u5757\u7684\u5c5e\u6027\uff08module\u2019s attribute\uff09\u548c\u6a21\u5757\u4e2d\u5b9a\u4e49\u7684\u5168\u5c40\u540d\u79f0\u4e4b\u95f4\u6b63\u597d\u5b58\u5728\u4e00\u4e2a\u76f4\u89c2\u7684\u6620\u5c04\uff1a\u5b83\u4eec\u5171\u4eab\u76f8\u540c\u7684\u547d\u540d\u7a7a\u95f4\u3002 \u4f46\u5b58\u5728\u4e00\u4e2a\u4f8b\u5916\u3002 \u6a21\u5757\u5bf9\u8c61\u6709\u4e00\u4e2a\u53ea\u8bfb\u5c5e\u6027 __dict__ \uff0c\u5b83\u8fd4\u56de\u7528\u4e8e\u5b9e\u73b0\u6a21\u5757\u547d\u540d\u7a7a\u95f4\u7684\u5b57\u5178\uff1b __dict__ \u662f\u5c5e\u6027\u4f46\u4e0d\u662f\u5168\u5c40\u540d\u79f0\u3002 \u4f7f\u7528\u8fd9\u4e2a\u5c06\u8fdd\u53cd\u547d\u540d\u7a7a\u95f4\u5b9e\u73b0\u7684\u62bd\u8c61\uff0c\u5e94\u5f53\u4ec5\u88ab\u7528\u4e8e\u4e8b\u540e\u8c03\u8bd5\u5668\u4e4b\u7c7b\u7684\u573a\u5408\u3002 **\u5c5e\u6027\uff08attribute\uff09**\u53ef\u4ee5\u662f\u53ea\u8bfb\u6216\u8005\u53ef\u5199\u7684\uff0c\u6240\u4ee5\u53ef\u4ee5\u5bf9\u5c5e\u6027\u8fdb\u884c\u8d4b\u503c\uff0c\u4f8b\u5982 modname.the_answer = 42 \u3002 \u5220\u9664\u5c5e\u6027\u53ef\u4ee5\u7528del\u8bed\u53e5\uff0c\u4f8b\u5982\uff0c del modname.the_answer \u5c06\u4f1a\u4ece\u540d\u4e3a modname \u7684\u5bf9\u8c61\u4e2d\u79fb\u9664 the_answer \u5c5e\u6027\u3002 \u547d\u540d\u7a7a\u95f4\u5728\u4e0d\u540c\u65f6\u523b\u88ab\u521b\u5efa\uff0c\u62e5\u6709\u4e0d\u540c\u7684\u751f\u5b58\u671f\uff08lifetimes\uff09\u3002\u5305\u542b\u5185\u7f6e\u540d\u79f0\uff08built-in names\uff09\u7684\u547d\u540d\u7a7a\u95f4\u662f\u5728Python\u89e3\u91ca\u5668\u542f\u52a8\u65f6\u521b\u5efa\u7684\uff0c\u6c38\u8fdc\u4e0d\u4f1a\u88ab\u5220\u9664\u3002 \u6a21\u5757\u7684\u5168\u5c40\u547d\u540d\u7a7a\u95f4\uff08global namespace\uff09\u5728\u6a21\u5757\u5b9a\u4e49\u88ab\u8bfb\u5165\u65f6\u521b\u5efa\uff1b\u901a\u5e38\uff0c\u6a21\u5757\u547d\u540d\u7a7a\u95f4\u4e5f\u4f1a\u6301\u7eed\u5230\u89e3\u91ca\u5668\u9000\u51fa\u3002 \u88ab\u89e3\u91ca\u5668\u7684\u9876\u5c42\u8c03\u7528\uff08top-level invocation\uff09\u6267\u884c\u7684\u8bed\u53e5\uff0c\u4ece\u4e00\u4e2a\u811a\u672c\u6587\u4ef6\u8bfb\u53d6\u6216\u4ea4\u4e92\u5f0f\u5730\u8bfb\u53d6\uff0c\u88ab\u8ba4\u4e3a\u662f __main__ \u6a21\u5757\u8c03\u7528\u7684\u4e00\u90e8\u5206\uff0c\u56e0\u6b64\u5b83\u4eec\u62e5\u6709\u81ea\u5df1\u7684\u5168\u5c40\u547d\u540d\u7a7a\u95f4\u3002 \u5185\u7f6e\u540d\u79f0\uff08built-in names\uff09\u5b9e\u9645\u4e0a\u4e5f\u5b58\u5728\u4e8e\u4e00\u4e2a\u6a21\u5757\u4e2d\uff0c\u8fd9\u4e2a\u6a21\u5757\u88ab\u79f0\u4f5c builtins \u3002 \u4e00\u4e2a\u51fd\u6570\u7684\u672c\u5730\u547d\u540d\u7a7a\u95f4\uff08local namespace\uff09\u5728\u8fd9\u4e2a\u51fd\u6570\u88ab\u8c03\u7528\u65f6\u521b\u5efa\uff0c\u5e76\u5728\u51fd\u6570\u8fd4\u56de\u6216\u629b\u51fa\u4e00\u4e2a\u65e0\u6cd5\u5728\u8be5\u51fd\u6570\u5185\u90e8\u5904\u7406\u7684\u9519\u8bef\u65f6\u88ab\u5220\u9664\u3002 \u6bcf\u6b21\u9012\u5f52\u8c03\u7528\uff08recursive invocations\uff09\u90fd\u4f1a\u6709\u5b83\u81ea\u5df1\u7684\u672c\u5730\u547d\u540d\u7a7a\u95f4\u3002 \u4e00\u4e2a**\u4f5c\u7528\u57df\uff08scope\uff09**\u662f\u4e00\u4e2a\u547d\u540d\u7a7a\u95f4\u53ef\u76f4\u63a5\u8bbf\u95ee\uff08directly accessible\uff09\u7684Python\u7a0b\u5e8f\u7684\u4ee3\u7801\u533a\u57df\u3002 \u8fd9\u91cc\u7684 \u201c\u53ef\u76f4\u63a5\u8bbf\u95ee\u201d \u610f\u5473\u7740\u4e0d\u52a0\u4efb\u4f55\u9650\u5b9a\u7684\u540d\u79f0\u5f15\u7528\u4f1a\u5728\u547d\u540d\u7a7a\u95f4\u4e2d\u8fdb\u884c\u67e5\u627e\u3002 \u867d\u7136\u4f5c\u7528\u57df\u662f\u9759\u6001\u5730\u786e\u5b9a\u7684\uff0c\u4f46\u5b83\u4eec\u4f1a\u88ab\u52a8\u6001\u5730\u4f7f\u7528\u3002 \u5728\u4ee3\u7801\u6267\u884c\u671f\u95f4\u7684\u4efb\u4f55\u65f6\u523b\uff0c\u4f1a\u67093\u62164\u4e2a\u7684\u5d4c\u5957\u4f5c\u7528\u57df\u4f9b\u547d\u540d\u7a7a\u95f4\u76f4\u63a5\u8bbf\u95ee: \u6700\u5148\u641c\u7d22\u7684\u6700\u5185\u90e8\u4f5c\u7528\u57df\u5305\u542b\u5c40\u90e8\u540d\u79f0 \u4ece\u6700\u8fd1\u7684\u5c01\u95ed\u4f5c\u7528\u57df\u5f00\u59cb\u641c\u7d22\u7684\u4efb\u4f55\u5c01\u95ed\u51fd\u6570\u7684\u4f5c\u7528\u57df\u5305\u542b\u975e\u5c40\u90e8\u540d\u79f0\uff0c\u4e5f\u5305\u62ec\u975e\u5168\u5c40\u540d\u79f0 \u5012\u6570\u7b2c\u4e8c\u4e2a\u4f5c\u7528\u57df\u5305\u542b\u5f53\u524d\u6a21\u5757\u7684\u5168\u5c40\u540d\u79f0 \u6700\u5916\u9762\u7684\u4f5c\u7528\u57df\uff08\u6700\u540e\u641c\u7d22\uff09\u662f\u5305\u542b\u5185\u7f6e\u540d\u79f0\u7684\u547d\u540d\u7a7a\u95f4 \u5982\u679c\u4e00\u4e2a\u540d\u79f0\u88ab\u58f0\u660e\u4e3a\u5168\u5c40\u53d8\u91cf\uff0c\u5219\u6240\u6709\u5f15\u7528\u548c\u8d4b\u503c\u5c06\u76f4\u63a5\u6307\u5411\u8be5\u6a21\u5757\u5168\u5c40\u540d\u79f0\u6240\u5728\u7684\u4e2d\u95f4\u4f5c\u7528\u57df\u3002 \u5982\u679c\u8981\u91cd\u65b0\u7ed1\u5b9a\u5728\u6700\u5185\u5c42\u4f5c\u7528\u57df\u4ee5\u5916\u7684\u53d8\u91cf\uff0c\u53ef\u4ee5\u4f7f\u7528 nonlocal \u8bed\u53e5\u58f0\u660e\u4e3a\u975e\u672c\u5730\u53d8\u91cf\u3002 \u5982\u679c\u6ca1\u6709\u88ab\u58f0\u660e\u4e3a\u975e\u672c\u5730\u53d8\u91cf\uff0c\u8fd9\u4e9b\u53d8\u91cf\u5c06\u662f\u53ea\u8bfb\u7684\u3002\u7ed9\u8fd9\u6837\u7684\u53d8\u91cf\u8d4b\u65b0\u503c\u53ea\u4f1a\u5728\u6700\u5185\u5c42\u4f5c\u7528\u57df\u4e2d\u521b\u5efa\u4e00\u4e2a*\u65b0\u7684*\u5c40\u90e8\u53d8\u91cf\uff0c\u800c\u540c\u540d\u7684\u5916\u90e8\u5168\u5c40\u53d8\u91cf\u5c06\u4fdd\u6301\u4e0d\u53d8\u3002 \u901a\u5e38\uff0c\u5f53\u524d\u5c40\u90e8\u4f5c\u7528\u57df\uff08local scope\uff09\u5c06\u5f15\u7528\u5f53\u524d\u51fd\u6570\u4f5c\u7528\u57df\u7684\u540d\u79f0\uff08local name\uff09\u3002 \u5728\u51fd\u6570\u4f5c\u7528\u57df\u4ee5\u5916\uff0c\u5f53\u524d\u5c40\u90e8\u4f5c\u7528\u57df\u5c06\u5f15\u7528\u4e0e\u5168\u5c40\u4f5c\u7528\u57df\u76f8\u4e00\u81f4\u7684\u547d\u540d\u7a7a\u95f4\uff1a\u6a21\u5757\u7684\u547d\u540d\u7a7a\u95f4\uff08the module\u2019s namespace\uff09\u3002 \u5b9a\u4e49\u4e00\u4e2a\u7c7b\uff0c\u662f\u5728\u672c\u5730\u5c40\u90e8\u547d\u540d\u7a7a\u95f4\u5185\u5efa\u4e00\u4e2a\u65b0\u7684\u547d\u540d\u7a7a\u95f4\u3002 \u5728\u4e00\u4e2a\u6a21\u5757\uff08module \uff09\u5185\u5b9a\u4e49\u7684\u51fd\u6570\u7684\u4f5c\u7528\u57df\u5c31\u662f\u8be5\u6a21\u5757\u7684\u547d\u540d\u7a7a\u95f4\uff0c\u65e0\u8bba\u8be5\u51fd\u6570\u4ece\u4ec0\u4e48\u5730\u65b9\u6216\u4ee5\u4ec0\u4e48\u522b\u540d\u88ab\u8c03\u7528\u3002 \u53e6\u4e00\u65b9\u9762\uff0c\u5b9e\u9645\u7684\u540d\u79f0\u641c\u7d22\u662f\u5728\u8fd0\u884c\u65f6\u52a8\u6001\u5b8c\u6210\u7684\u3002 \u4f46\u662f\uff0cPython\u6b63\u5728\u671d\u7740\u201c\u7f16\u8bd1\u65f6\u9759\u6001\u540d\u79f0\u89e3\u6790\u201d\u7684\u65b9\u5411\u53d1\u5c55\uff0c\u56e0\u6b64\u4e0d\u8981\u8fc7\u4e8e\u4f9d\u8d56\u52a8\u6001\u540d\u79f0\u89e3\u6790\uff01\u4e8b\u5b9e\u4e0a\uff0c\u5c40\u90e8\u53d8\u91cf\u5df2\u7ecf\u662f\u88ab\u9759\u6001\u786e\u5b9a\u4e86\u3002 \u5982\u679c\u4e0d\u5b58\u5728\u751f\u6548\u7684 global \u6216 nonlocal \u8bed\u53e5\uff0c\u5219\u5bf9\u540d\u79f0\u7684\u8d4b\u503c\u603b\u662f\u4f1a\u8fdb\u5165\u6700\u5185\u5c42\u4f5c\u7528\u57df\u3002\u8d4b\u503c\u4e0d\u4f1a\u590d\u5236\u6570\u636e\uff0c\u662f\u5c06\u540d\u79f0\u7ed1\u5b9a\u5230\u5bf9\u8c61\u3002 \u5220\u9664\u4e5f\u662f\u5982\u6b64\uff1a\u8bed\u53e5 del x \u4f1a\u4ece\u5c40\u90e8\u4f5c\u7528\u57df\u6240\u5f15\u7528\u7684\u547d\u540d\u7a7a\u95f4\u4e2d\u79fb\u9664\u5bf9 x \u7684\u7ed1\u5b9a\u3002\u4e8b\u5b9e\u4e0a\uff0c\u6240\u6709\u5f15\u5165\u65b0\u540d\u79f0\u7684\u64cd\u4f5c\u90fd\u662f\u4f7f\u7528\u5c40\u90e8\u4f5c\u7528\u57df\u3002\u7279\u522b\u5730\uff0c import \u8bed\u53e5\u548c\u51fd\u6570\u5b9a\u4e49\u4f1a\u5728\u5c40\u90e8\u4f5c\u7528\u57df\u4e2d\u7ed1\u5b9a\u6a21\u5757\u6216\u51fd\u6570\u540d\u79f0\u3002 global \u8bed\u53e5\u53ef\u88ab\u7528\u6765\u8868\u660e\u7279\u5b9a\u53d8\u91cf\u5b58\u5728\u4e8e\u5168\u5c40\u4f5c\u7528\u57df\uff0c\u5e76\u4e14\u5e94\u5f53\u5728\u5168\u5c40\u4f5c\u7528\u57df\u4e2d\u88ab**\u91cd\u65b0**\u7ed1\u5b9a\uff1b nonlocal \u8bed\u53e5\u8868\u660e\u7279\u5b9a\u53d8\u91cf\u751f\u5b58\u4e8e\u5916\u5c42\u4f5c\u7528\u57df\u4e2d\uff0c\u5e76\u4e14\u5e94\u5f53\u5728\u5176\u6240\u5904\u7684\u5916\u5c42\u4f5c\u7528\u57df\u4e2d\u88ab**\u91cd\u65b0**\u7ed1\u5b9a\u3002 \u770b\u4e0b\u9762\u7684\u4f8b\u5b50\uff1a \u5c40\u90e8\u8d4b\u503c\uff08local assignment\uff0c\u8fd9\u662f\u9ed8\u8ba4\u72b6\u6001\uff09\u4e0d\u4f1a\u6539\u53d8 scope_test \u5bf9 spam \u7684\u7ed1\u5b9a\u3002 nonlocal \u8d4b\u503c\u4f1a\u6539\u53d8 scope_test \u5bf9 spam \u7684\u7ed1\u5b9a\u3002 global \u8d4b\u503c\u4f1a\u6539\u53d8\u6a21\u5757\u5c42\u7ea7\u7684\u7ed1\u5b9a\uff0c\u5373\uff0c global spam \u91cd\u65b0\u7ed1\u5b9a\u4e86spam\u7684\u5168\u5c40\u5b9a\u4e49\uff0c\u4ece spam = \"spam out of func\" \u53d8\u6210\u4e86 spam = \"global spam\" \u3002\u5982\u679c\u6ce8\u91ca\u6389def do_global()\u8fd9\u4e00\u6bb5\u4ee3\u7801\uff0c\u5219 spam = \"spam out of func\" \u8d77\u4f5c\u7528\u3002 spam = \"spam out of func\" def scope_test (): def do_local (): spam = \"local spam\" def do_nonlocal (): nonlocal spam spam = \"nonlocal spam\" def do_global (): global spam spam = \"global spam\" spam = \"test spam\" do_local () print ( \"After local assignment:\" , spam ) do_nonlocal () print ( \"After nonlocal assignment:\" , spam ) do_global () print ( \"After global assignment:\" , spam ) scope_test () print ( \"In global scope:\" , spam ) # \u8fd0\u884c\u7ed3\u679c # scope_test() After local assignment : test spam After nonlocal assignment : nonlocal spam After global assignment : nonlocal spam # print(\"In global scope:\", spam) In global scope : global spam \u7c7bClass \u00b6 \u7c7b\u5b9a\u4e49 Class Definition \u00b6 \u7c7b\u5b9a\u4e49\u4e0e\u51fd\u6570\u5b9a\u4e49 (def \u8bed\u53e5) \u4e00\u6837\u5fc5\u987b\u88ab\u6267\u884c\u624d\u4f1a\u8d77\u4f5c\u7528\u3002 class ClassName : < statement - 1 > ... < statement - N > \u5728\u5b9e\u8df5\u4e2d\uff0c\u7c7b\u5b9a\u4e49\u5185\u7684\u8bed\u53e5\u901a\u5e38\u90fd\u662f\u51fd\u6570\u5b9a\u4e49\uff0c\u4f46\u4e5f\u5141\u8bb8\u6709\u5176\u4ed6\u8bed\u53e5\u3002\u5728\u7c7b\u5185\u90e8\u7684\u51fd\u6570\u5b9a\u4e49\u901a\u5e38\u5177\u6709\u4e00\u79cd\u7279\u6709\u5f62\u5f0f\u7684\u53c2\u6570\u5217\u8868\uff0c\u8fd9\u662f\u7ea6\u5b9a\u7684\u65b9\u6cd5\u89c4\u8303\uff08conventions for methods\uff09\u3002 \u7f16\u8bd1\u8fc7\u7a0b\u4e2d\uff0c\u8fdb\u5165\u4e00\u4e2a\u7c7b\u7684\u5185\u90e8\uff0c\u5c06\u521b\u5efa\u4e00\u4e2a\u65b0\u7684\u547d\u540d\u7a7a\u95f4\uff0c\u4e00\u4e2a\u5c40\u90e8\u4f5c\u7528\u57df\u3002\u56e0\u6b64\uff0c\u6240\u6709\u5bf9\u7c7b\u5185\u90e8\u5c40\u90e8\u53d8\u91cf\u7684\u8d4b\u503c\u90fd\u662f\u5728\u8fd9\u4e2a\u65b0\u7684\u547d\u540d\u7a7a\u95f4\u4e4b\u5185\uff0c\u5305\u62ec\u65b0\u5b9a\u4e49\u7684\u51fd\u6570\u540d\u79f0\u3002 \u5f53\u6b63\u5e38\u79bb\u5f00\u4e00\u4e2a\u7c7b\u65f6\uff0c\u7f16\u8bd1\u8fc7\u7a0b\u5c06\u521b\u5efa\u4e00\u4e2a\u7c7b\u5bf9\u8c61\uff08class object\uff09\uff0c\u5c01\u88c5\u4e86\u7c7b\u5b9a\u4e49\u6240\u521b\u5efa\u7684\u547d\u540d\u7a7a\u95f4\u91cc\u7684\u5185\u5bb9\u3002 \u6700\u521d\u7684\uff08\u5728\u8fdb\u5165\u7c7b\u5b9a\u4e49\u4e4b\u524d\u8d77\u4f5c\u7528\u7684\uff09\u5c40\u90e8\u4f5c\u7528\u57df\u5c06\u91cd\u65b0\u751f\u6548\uff0c\u7c7b\u5bf9\u8c61\uff08class object\uff09\u5c06\u5728\u8fd9\u91cc\u88ab\u7ed1\u5b9a\u5230\u7c7b\u5b9a\u4e49\u5934\u90e8\u6240\u58f0\u660e\u7684\u7c7b\u540d\u79f0 (\u5728\u4e0a\u9762\u7684\u793a\u4f8b\u4e2d\u662f ClassName )\u3002 \u7c7b\u5bf9\u8c61 Class Objects \u00b6 \u7c7b\u5bf9\u8c61\u652f\u6301\u4e24\u79cd\u64cd\u4f5c\uff1a\u5c5e\u6027\u5f15\u7528\uff08attribute references\uff09\u548c\u5b9e\u4f8b\u5316\uff08instantiation\uff09\u3002 \u5c5e\u6027\u5f15\u7528\uff08attribute references\uff09 \u4f7f\u7528Python\u4e2d\u5c5e\u6027\u5f15\u7528\u7684\u6807\u51c6\u8bed\u6cd5: obj.name \u3002 \u5b58\u5728\u4e8e\u7c7b\u547d\u540d\u7a7a\u95f4\u4e2d\u7684\u6240\u6709\u540d\u79f0\uff0c\u7c7b\u5bf9\u8c61\u88ab\u521b\u5efa\u65f6\u540c\u65f6\u88ab\u521b\u5efa\u4e86\uff0c\u8fd9\u4e9b\u5c31\u662f\u6709\u6548\u7684\u5c5e\u6027\u540d\u79f0\u3002\u56e0\u6b64\uff0c\u5982\u679c\u7c7b\u5b9a\u4e49\u662f\u5982\u4e0b\u6240\u793a\uff0c\u90a3\u4e48 MyClass.i \u548c MyClass.f \u5c31\u662f\u6709\u6548\u7684\u5c5e\u6027\u5f15\u7528\uff0c\u5c06\u5206\u522b\u8fd4\u56de\u4e00\u4e2a\u6574\u6570\u548c\u4e00\u4e2a\u51fd\u6570\u5bf9\u8c61\u3002 \u7c7b\u5c5e\u6027\u4e5f\u53ef\u4ee5\u88ab\u8d4b\u503c\uff0c\u56e0\u6b64\u53ef\u4ee5\u901a\u8fc7\u8d4b\u503c\u6765\u66f4\u6539 MyClass.i \u7684\u503c\u3002 __doc__ \u4e5f\u662f\u4e00\u4e2a\u6709\u6548\u7684\u5c5e\u6027\uff0c\u5c06\u8fd4\u56de\u6240\u5c5e\u7c7b\u7684\u6587\u6863\u5b57\u7b26\u4e32: \"A simple example class\"\u3002 class MyClass : \"\"\"A simple example class\"\"\" i = 12345 def f ( self ): return 'hello world' print ( MyClass . i ) # 12345 print ( MyClass . __doc__ ) # A simple example class MyClass . i = 10 print ( MyClass . i ) # 10 \u7c7b\u7684**\u5b9e\u4f8b\u5316\uff08instantiation\uff09**\u4f7f\u7528\u51fd\u6570\u8868\u793a\u6cd5\u3002 \u53ef\u4ee5\u628a\u7c7b\u5bf9\u8c61\uff08class object\uff09\u770b\u4f5c\u662f\u4e00\u4e2a\u4e0d\u5e26\u53c2\u6570\u7684\u51fd\u6570\uff0c\u8fd9\u4e2a\u51fd\u6570\u8fd4\u56de\u4e86\u8be5\u7c7b\u7684\u4e00\u4e2a\u65b0\u5b9e\u4f8b\u3002 \u5728\u4e0b\u9762\u7684\u4f8b\u5b50\u4e2d\uff0c x = MyClass() \u521b\u5efa\u4e86 MyClass() \u8fd9\u4e2a\u7c7b\u7684\u4e00\u4e2a\u5b9e\u4f8b\uff0c\u5e76\u8d4b\u503c\u7ed9\u5c40\u90e8\u53d8\u91cf x \u3002 \u5b9e\u4f8b\u5316\u64cd\u4f5c\uff08\u8c03\u7528\u7c7b\u5bf9\u8c61\uff09\u4f1a\u521b\u5efa\u4e00\u4e2a\u7a7a\u5bf9\u8c61\u3002\u8bb8\u591a\u7c7b\u4f1a\u521b\u5efa\u5e26\u6709\u7279\u5b9a\u521d\u59cb\u72b6\u6001\u7684\u81ea\u5b9a\u4e49\u5b9e\u4f8b\u3002\u4e3a\u6b64\u7c7b\u5b9a\u4e49\u4e2d\u9700\u8981\u5305\u542b\u4e00\u4e2a\u540d\u4e3a __init__() \u7684\u7279\u6b8a\u65b9\u6cd5\u3002 \u5f53\u4e00\u4e2a\u7c7b\u5b9a\u4e49\u4e86 __init__() \u65b9\u6cd5\u65f6\uff0c\u7c7b\u7684\u5b9e\u4f8b\u5316\u64cd\u4f5c\u4f1a\u81ea\u52a8\u4e3a\u65b0\u521b\u5efa\u7684\u7c7b\u5b9e\u4f8b\u8c03\u7528 __init__() \u3002 \u66f4\u65b0\u4e0a\u9762\u7684\u4f8b\u5b50\uff0c\u6ce8\u610f __dict__ \u4e24\u6b21\u8fd4\u56de\u7684\u4e0d\u540c\u7684\u5b57\u5178\u3002\u590d\u4e60\u4e00\u4e0b\uff0c\u5728\u547d\u540d\u7a7a\u95f4\u4e2d\u63d0\u5230\uff0c __dict__ \u662f\u5c5e\u6027\u4f46\u4e0d\u662f\u5168\u5c40\u540d\u79f0\uff0c\u8fd4\u56de\u7528\u4e8e\u5b9e\u73b0\u6a21\u5757\u547d\u540d\u7a7a\u95f4\u7684\u5b57\u5178\u3002 class MyClass : \"\"\"A simple example class\"\"\" i = 12345 def f ( self ): return 'hello world' def __init__ ( self ): self . data = [] x = MyClass () print ( x . __dict__ ) # {'data': []} x . i = 10 print ( x . __dict__ ) # {'data': [], 'i': 10} __init__() \u65b9\u6cd5\u53ef\u4ee5\u6709\u989d\u5916\u7684\u53c2\u6570\u8f93\u5165\uff0c\u5728\u8fd9\u79cd\u60c5\u51b5\u4e0b\uff0c\u7c7b\u5b9e\u4f8b\u5316\u7684\u53c2\u6570\u5c06\u88ab\u4f20\u9012\u7ed9 __init__() \u3002 \u5982\u4e0b\u4f8b: class Complex : def __init__ ( self , realpart , imagpart ): self . r = realpart self . i = imagpart x = Complex ( 3.0 , - 4.5 ) print ( x . r , x . i ) # 3.0 -4.5 \u5b9e\u4f8b\u5bf9\u8c61 Instance Objects \u00b6 \u5bf9\u5b9e\u4f8b\u5bf9\u8c61\u552f\u4e00\u7684\u64cd\u4f5c\u662f\u5c5e\u6027\u5f15\u7528\u3002\u6709\u4e24\u79cd\u6709\u6548\u7684\u5c5e\u6027\u540d\u79f0\uff1a\u6570\u636e\u5c5e\u6027\uff08data attributes\uff09\u548c\u65b9\u6cd5\uff08methods\uff09\u3002 **\u6570\u636e\u5c5e\u6027\uff08data attributes\uff09**\u7c7b\u4f3c\u4e8e\u5b9e\u4f8b\u53d8\u91cf\uff0c\u6570\u636e\u5c5e\u6027\u4e0d\u9700\u8981\u58f0\u660e\u3002\u50cf\u5c40\u90e8\u53d8\u91cf\u4e00\u6837\uff0c\u6570\u636e\u5c5e\u6027\u5c06\u5728\u7b2c\u4e00\u6b21\u88ab\u8d4b\u503c\u65f6\u4ea7\u751f\u3002 \u4f8b\u5982\uff0c\u5982\u679c x \u662f\u4e0a\u9762\u521b\u5efa\u7684 MyClass \u7684\u5b9e\u4f8b\uff0c\u5219\u4ee5\u4e0b\u4ee3\u7801\u6bb5\u5c06\u6253\u5370\u6570\u503c 16 \uff0c\u4e14\u6ca1\u6709\u7559\u4e0b\u5173\u4e8e x.counter \u7684\u75d5\u8ff9\u3002 class MyClass : \"\"\"A simple example class\"\"\" i = 12345 def f ( self ): return 'hello world' def __init__ ( self ): self . data = [] x = MyClass () x . counter = 1 while x . counter < 10 : x . counter = x . counter * 2 print ( x . counter ) # 16 print ( x . __dict__ ) # {'data': [], 'counter': 16} del x . counter print ( x . __dict__ ) # {'data': []} \u53e6\u4e00\u7c7b\u5b9e\u4f8b\u5c5e\u6027\u5f15\u7528\u79f0\u4e3a**\u65b9\u6cd5\uff08methods\uff09 \u3002 \u65b9\u6cd5\u662f\u96b6\u5c5e\u4e8e\u5bf9\u8c61\u7684**\u51fd\u6570 \u3002 \u5728Python\u4e2d\uff0c\u65b9\u6cd5\u8fd9\u4e2a\u672f\u8bed\u5e76\u4e0d\u662f\u7c7b\u5b9e\u4f8b\u6240\u7279\u6709\u7684\uff0c\u5176\u4ed6\u5bf9\u8c61\u4e5f\u53ef\u4ee5\u6709\u65b9\u6cd5\u3002 \u4f8b\u5982\uff0c\u5217\u8868\u5bf9\u8c61\uff08list objects\uff09\u5177\u6709append, insert, remove, sort\u7b49\u65b9\u6cd5\u3002 \u5728\u4ee5\u4e0b\u8ba8\u8bba\u4e2d\uff0c\u6211\u4eec\u4f7f\u7528\u65b9\u6cd5\u4e00\u8bcd\u5c06\u4e13\u6307\u7c7b\u5b9e\u4f8b\u5bf9\u8c61\u7684\u65b9\u6cd5\uff0c\u9664\u975e\u53e6\u5916\u660e\u786e\u8bf4\u660e\u3002 \u5b9e\u4f8b\u5bf9\u8c61\u7684\u6709\u6548\u65b9\u6cd5\u540d\u79f0\u4f9d\u8d56\u4e8e\u5176\u6240\u5c5e\u7684\u7c7b\u3002 \u6839\u636e\u5b9a\u4e49\uff0c\u4e00\u4e2a\u7c7b\u5b9a\u4e49\u4e2d\u6240\u5305\u542b\u7684\u6240\u6709\u51fd\u6570\u5bf9\u8c61\uff08function objects\uff09\u90fd\u79f0\u4e3a\u5c5e\u6027\u3002 \u56e0\u6b64\u5728\u4e0a\u9762\u7684\u793a\u4f8b\u4e2d\uff0c x.f \u662f\u6709\u6548\u7684\u65b9\u6cd5\u5f15\u7528\uff0c\u56e0\u4e3a MyClass.f \u662f\u4e00\u4e2a\u51fd\u6570\uff0c\u800c x.i \u4e0d\u662f\u65b9\u6cd5\uff0c\u56e0\u4e3a MyClass.i \u4e0d\u662f\u51fd\u6570\u3002\u4f46\u662f x.f \u4e0e MyClass.f \u5e76\u4e0d\u662f\u4e00\u56de\u4e8b\uff0c x.f \u662f\u4e00\u4e2a**\u65b9\u6cd5\u5bf9\u8c61**\uff0c\u800c MyClass.f \u662f\u4e00\u4e2a**\u51fd\u6570\u5bf9\u8c61**\u3002\u5dee\u522b\u5728\u4e8e f() \u662f\u5426\u4e0e\u5b9e\u4f8b\u7ed1\u5b9a\uff0c\u672a\u7ed1\u5b9a\uff0c\u5c31\u662f\u51fd\u6570\uff0c\u7ed1\u5b9a\uff0c\u5c31\u662f\u65b9\u6cd5\u3002 class MyClass : \"\"\"A simple example class\"\"\" i = 12345 def f ( self ): return 'hello world' def __init__ ( self ): self . data = [] x = MyClass () print ( MyClass . f ( 0 )) # hello world print ( x . f ()) # hello world print ( MyClass . f ) # print ( x . f ) # > print ( type ( MyClass . f )) # print ( type ( x . f )) # \u8fd9\u91cc\u505a\u4e2a\u5c0f\u7ed3\uff1a \u51fd\u6570(function)\u662fPython\u4e2d\u4e00\u4e2a\u53ef\u8c03\u7528\u5bf9\u8c61(callable), \u65b9\u6cd5(method)\u662f\u4e00\u79cd\u7279\u6b8a\u7684\u51fd\u6570\u3002 \u4e00\u4e2a\u53ef\u8c03\u7528\u5bf9\u8c61\u662f\u65b9\u6cd5\u548c\u51fd\u6570\uff0c\u548c\u8fd9\u4e2a\u5bf9\u8c61\u65e0\u5173\uff0c\u4ec5\u548c\u8fd9\u4e2a\u5bf9\u8c61\u662f\u5426\u4e0e\u7c7b\u6216\u5b9e\u4f8b\u7ed1\u5b9a\u6709\u5173\uff08bound method\uff09\u3002 \u9759\u6001\u65b9\u6cd5\u6ca1\u6709\u548c\u4efb\u4f55\u7c7b\u6216\u5b9e\u4f8b\u7ed1\u5b9a\uff0c\u6240\u4ee5**\u9759\u6001\u65b9\u6cd5\u662f\u4e2a\u51fd\u6570**\u3002 \u65b9\u6cd5\u5bf9\u8c61 Method Objects \u00b6 \u5728 MyClass \u793a\u4f8b\u4e2d\uff0c x.f() \u662f\u4e00\u4e2a\u65b9\u6cd5\u5bf9\u8c61\uff0c\u88ab\u8c03\u7528\u540e\uff0c\u5c06\u8fd4\u56de\u5b57\u7b26\u4e32 'hello world' \u3002\u53ef\u4ee5\u7acb\u5373\u8c03\u7528\uff0c\u4e5f\u53ef\u4ee5\u4fdd\u5b58\u8d77\u6765\u4ee5\u540e\u518d\u8c03\u7528 xf = x.f \u3002 \u867d\u7136 f() \u7684\u51fd\u6570\u5b9a\u4e49\u6307\u5b9a\u4e86\u4e00\u4e2a\u53c2\u6570\uff0c\u4f46\u4e0a\u9762\u4f8b\u5b50\u4e2d\u8c03\u7528 x.f() \u65f6\u5e76\u6ca1\u6709\u5e26\u53c2\u6570\uff0c\u4e5f\u6ca1\u6709\u5f15\u53d1\u5f02\u5e38\u62a5\u9519\u3002\u539f\u56e0\u5728\u4e8e\uff0c \u65b9\u6cd5(method)\u7684\u7279\u6b8a\u4e4b\u5904\u5c31\u5728\u4e8e\u5b9e\u4f8b\u5bf9\u8c61\u4f1a\u4f5c\u4e3a\u51fd\u6570\u7684\u7b2c\u4e00\u4e2a\u53c2\u6570\u88ab\u4f20\u5165\u3002 \u8c03\u7528 x.f() \u5176\u5b9e\u5c31\u76f8\u5f53\u4e8e MyClass.f(x) \u3002 \u603b\u4e4b\uff0c\u8c03\u7528\u4e00\u4e2a\u5177\u6709 n \u4e2a\u53c2\u6570\u7684\u65b9\u6cd5(method)\u5c31\u76f8\u5f53\u4e8e\u8c03\u7528\u518d\u591a\u4e00\u4e2a\u53c2\u6570\u7684\u5bf9\u5e94\u51fd\u6570\uff0c\u8fd9\u4e2a\u53c2\u6570\u503c\u4e3a\u65b9\u6cd5\u6240\u5c5e\u5b9e\u4f8b\u5bf9\u8c61\uff0c \u4f4d\u7f6e\u5728\u5176\u4ed6\u53c2\u6570\u4e4b\u524d \u3002 \u5f53\u4e00\u4e2a\u5b9e\u4f8b\u7684\u975e\u6570\u636e\u5c5e\u6027\u88ab\u5f15\u7528\u65f6\uff0c\u5c06\u641c\u7d22\u5b9e\u4f8b\u6240\u5c5e\u7684\u7c7b\u3002 \u5982\u679c\u88ab\u5f15\u7528\u7684\u5c5e\u6027\u540d\u79f0\u662f\u7c7b\u4e2d\u4e00\u4e2a\u6709\u6548\u7684\u51fd\u6570\u5bf9\u8c61\uff0c\u5219\u4f1a\u521b\u5efa\u4e00\u4e2a\u62bd\u8c61\u7684\u5bf9\u8c61\uff0c\u901a\u8fc7\u6253\u5305\uff08parking\uff0c\u5373\u6307\u5411\uff09\u5339\u914d\u5230\u7684\u5b9e\u4f8b\u5bf9\u8c61\u548c\u51fd\u6570\u5bf9\u8c61\uff0c\u8fd9\u4e2a\u62bd\u8c61\u5bf9\u8c61\u5c31\u662f\u65b9\u6cd5\u5bf9\u8c61\u3002 \u5f53\u5e26\u53c2\u6570\u8c03\u7528\u65b9\u6cd5\u5bf9\u8c61\u65f6\uff0c\u5c06\u57fa\u4e8e\u5b9e\u4f8b\u5bf9\u8c61\u548c\u53c2\u6570\u5217\u8868\u6784\u5efa\u4e00\u4e2a\u65b0\u7684\u53c2\u6570\u5217\u8868\uff0c\u5e76\u4f7f\u7528\u8fd9\u4e2a\u65b0\u53c2\u6570\u5217\u8868\u8c03\u7528\u76f8\u5e94\u7684\u51fd\u6570\u5bf9\u8c61\u3002 \u7c7b\u548c\u5b9e\u4f8b\u53d8\u91cf Class and Instance Variables \u00b6 \u4e00\u822c\u6765\u8bf4\uff0c**\u5b9e\u4f8b\u53d8\u91cf**\u7528\u4e8e\u6bcf\u4e2a\u5b9e\u4f8b\u7684\u552f\u4e00\u6570\u636e\uff0c\u800c**\u7c7b\u53d8\u91cf**\u7528\u4e8e\u7c7b\u7684\u6240\u6709\u5b9e\u4f8b\u5171\u4eab\u7684\u5c5e\u6027\u548c\u65b9\u6cd5: class Dog : kind = 'canine' # class variable shared by all instances def __init__ ( self , name ): self . name = name # instance variable unique to each instance d = Dog ( 'Fido' ) e = Dog ( 'Buddy' ) print ( d . kind ) # shared by all dogs # 'canine' print ( e . kind ) # shared by all dogs # 'canine' print ( d . name ) # unique to d instance # 'Fido' print ( e . name ) # unique to e instance # 'Buddy' \u4e0b\u4ee3\u7801\u4e2d\u7684 tricks \u5217\u8868\u4e0d\u5e94\u8be5\u88ab\u7528\u4f5c\u7c7b\u53d8\u91cf\uff0c\u56e0\u4e3a\u6240\u6709\u7684 Dog \u5b9e\u4f8b\u5c06\u53ea\u5171\u4eab\u4e00\u4e2a\u5355\u72ec\u7684\u5217\u8868: class Dog : kind = 'canine' # class variable shared by all instances tricks = [] # mistaken use of a class variable def __init__ ( self , name ): self . name = name # instance variable unique to each instance def add_trick ( self , trick ): self . tricks . append ( trick ) d = Dog ( 'Fido' ) e = Dog ( 'Buddy' ) d . add_trick ( 'roll over' ) e . add_trick ( 'play dead' ) print ( d . tricks ) # ['roll over', 'play dead'] \u6b63\u786e\u7684\u7c7b\u8bbe\u8ba1\u5e94\u8be5\u4f7f\u7528\u5b9e\u4f8b\u53d8\u91cf: class Dog : kind = 'canine' # class variable shared by all instances def __init__ ( self , name ): self . name = name # instance variable unique to each instance self . tricks = [] # creates a new empty list for each dog def add_trick ( self , trick ): self . tricks . append ( trick ) d = Dog ( 'Fido' ) e = Dog ( 'Buddy' ) d . add_trick ( 'roll over' ) e . add_trick ( 'play dead' ) print ( d . tricks ) # ['roll over'] print ( e . tricks ) # ['play dead'] \u5982\u679c\u540c\u6837\u7684\u5c5e\u6027\u540d\u79f0\u540c\u65f6\u51fa\u73b0\u5728\u5b9e\u4f8b\u548c\u7c7b\u4e2d\uff0c\u5219\u5c5e\u6027\u67e5\u627e\u4f1a**\u4f18\u5148\u9009\u62e9\u5b9e\u4f8b**: class Warehouse : purpose = 'storage' region = 'west' w1 = Warehouse () print ( w1 . purpose , w1 . region ) # storage west w2 = Warehouse () w2 . region = 'east' # Instance W2 has higher priority than class print ( w2 . purpose , w2 . region ) # storage east \u6570\u636e\u5c5e\u6027\uff08Data attributes\uff09\u53ef\u4ee5\u88ab\u65b9\u6cd5\uff08method\uff09\u4ee5\u53ca\u4e00\u4e2a\u5bf9\u8c61\u7684\u666e\u901a\u7528\u6237\uff08ordinary users\uff09\uff08\u201c\u5ba2\u6237\u7aefClient\u201d\uff09\u6240\u5f15\u7528\u3002 \u6362\u53e5\u8bdd\u8bf4\uff0c\u7c7b\u4e0d\u80fd\u7528\u4e8e\u5b9e\u73b0\u7eaf\u62bd\u8c61\u6570\u636e\u7c7b\u578b\u3002 \u65b9\u6cd5\u7684\u7b2c\u4e00\u4e2a\u53c2\u6570\u5e38\u5e38\u88ab\u547d\u540d\u4e3a self \uff0c\u8fd9\u53ea\u662f\u4e00\u4e2a\u7ea6\u5b9a: self \u8fd9\u4e00\u540d\u79f0\u5728Python\u4e2d\u6ca1\u6709\u7279\u6b8a\u542b\u4e49\u3002 \u4f46\u662f\u9075\u5faa\u6b64\u7ea6\u5b9a\u4f1a\u4f7f\u5f97\u4ee3\u7801\u5177\u6709\u5f88\u597d\u7684\u53ef\u8bfb\u6027\u3002 \u4efb\u4f55\u4e00\u4e2a\u4f5c\u4e3a\u7c7b\u5c5e\u6027\uff08class attribute\uff09\u7684\u51fd\u6570\u5bf9\u8c61\uff08function object\uff09\u90fd\u4e3a\u8be5\u7c7b\u7684\u5b9e\u4f8b\u5b9a\u4e49\u4e86\u4e00\u4e2a\u76f8\u5e94\u65b9\u6cd5\u3002 \u51fd\u6570\u5b9a\u4e49\u7684\u6587\u672c\u5e76\u975e\u5fc5\u987b\u5305\u542b\u4e8e\u7c7b\u5b9a\u4e49\u4e4b\u5185\uff1a\u5c06\u4e00\u4e2a\u51fd\u6570\u5bf9\u8c61\u8d4b\u503c\u7ed9\u4e00\u4e2a\u5c40\u90e8\u53d8\u91cf\u4e5f\u662f\u53ef\u4ee5\u7684\u3002\u5982\u4e0b\u4f8b\u3002\u73b0\u5728 f , g \u548c h \u90fd\u662f\u7c7b C \u7684\u5f15\u7528\u51fd\u6570\u5bf9\u8c61\u7684\u5c5e\u6027\uff0c\u56e0\u800c\u5b83\u4eec\u5c31\u90fd\u662f\u7c7b C \u7684\u5b9e\u4f8b\u7684\u65b9\u6cd5\uff0c\u5176\u4e2d h \u5b8c\u5168\u7b49\u540c\u4e8e g \u3002\u4f46\u8bf7\u6ce8\u610f\uff0c\u4e0b\u9762\u8fd9\u4e2a\u4f8b\u5b50\u7684\u53ef\u8bfb\u6027\u975e\u5e38\u4e0d\u597d\u3002 # Function defined outside the class def f1 ( self , x , y ): return min ( x , x + y ) class C : f = f1 # Assign a function object to a local variable in the class def g ( self ): return 'hello world' h = g \u65b9\u6cd5\uff08methods\uff09\u53ef\u4ee5\u901a\u8fc7\u4f7f\u7528 self \u53c2\u6570\u7684\u65b9\u6cd5\u5c5e\u6027\uff08method attributes\uff09\u8c03\u7528\u5176\u4ed6\u65b9\u6cd5\uff08method\uff09: class Bag : def __init__ ( self ): self . data = [] def add ( self , x ): self . data . append ( x ) def addtwice ( self , x ): self . add ( x ) self . add ( x ) \u65b9\u6cd5\u53ef\u4ee5\u901a\u8fc7\u4e0e\u666e\u901a\u51fd\u6570\u76f8\u540c\u7684\u65b9\u5f0f\u5f15\u7528\u5168\u5c40\u540d\u79f0\u3002 \u4e0e\u65b9\u6cd5\u76f8\u5173\u8054\u7684\u5168\u5c40\u4f5c\u7528\u57df\u5c31\u662f\u5305\u542b\u5176\u5b9a\u4e49\u7684\u6a21\u5757\u3002 \uff08\u7c7b\u6c38\u8fdc\u4e0d\u4f1a\u88ab\u4f5c\u4e3a\u5168\u5c40\u4f5c\u7528\u57df\u3002\uff09 \u867d\u7136\u6211\u4eec\u5f88\u5c11\u4f1a\u6709\u5145\u5206\u7684\u7406\u7531\u5728\u65b9\u6cd5\u4e2d\u4f7f\u7528\u5168\u5c40\u4f5c\u7528\u57df\uff0c\u4f46\u5168\u5c40\u4f5c\u7528\u57df\u5b58\u5728\u8bb8\u591a\u5408\u7406\u7684\u4f7f\u7528\u573a\u666f\uff1a\u4e3e\u4e2a\u4f8b\u5b50\uff0c\u5bfc\u5165\u5230\u5168\u5c40\u4f5c\u7528\u57df\u7684\u51fd\u6570\u548c\u6a21\u5757\u53ef\u4ee5\u88ab\u65b9\u6cd5\u6240\u4f7f\u7528\uff0c\u5728\u5176\u4e2d\u5b9a\u4e49\u7684\u51fd\u6570\u548c\u7c7b\u4e5f\u4e00\u6837\u3002 \u901a\u5e38\uff0c\u5305\u542b\u8be5\u65b9\u6cd5\u7684\u7c7b\u672c\u8eab\u662f\u5728\u5168\u5c40\u4f5c\u7528\u57df\u4e2d\u5b9a\u4e49\u7684\u3002 \u603b\u7ed3 \u00b6 \u7c7b\u5b9a\u4e49\u5c0f\u7ed3 \u00b6 \u4e00\u4e2a\u7c7b\u5b9a\u4e49\u7c7b\u6210\u5458\u5c5e\u6027\u548c\u6210\u5458\u65b9\u6cd5\u3002 \u4e00\u4e2a\u7c7b\u53ef\u4ee5\u5b9e\u4f8b\u5316\u591a\u4e2a\u5bf9\u8c61\uff0c\u6bcf\u4e2a\u5b9e\u4f8b\u5316\u5bf9\u8c61\u90fd\u662f\u72ec\u7acb\u7684\u3002 \u521b\u5efa\u7684\u7c7b\u5b9e\u4f8b\u5316\u5bf9\u8c61\uff0c\u4f1a\u5f15\u7528\u7236\u7c7b\u4e2d\u7684\u5c5e\u6027\u548c\u65b9\u6cd5\uff0c\u5e76\u4e0d\u4f1a\u628a\u7c7b\u7684\u5c5e\u6027\u548c\u65b9\u6cd5\u590d\u5236\u7ed9\u5bf9\u8c61\uff0c\u56e0\u6b64\uff1a \u5728\u8bbf\u95ee\u5b9e\u4f8b\u5316\u5bf9\u8c61\u7684\u5c5e\u6027\u548c\u65b9\u6cd5\u65f6\uff0c\u4f1a\u5148\u53bb\u627e\u5bf9\u8c61\u81ea\u5df1\u7684\u5c5e\u6027\u548c\u65b9\u6cd5\uff0c\u7136\u540e\u518d\u53bb\u5b9e\u4f8b\u5316\u8fd9\u4e2a\u5bf9\u8c61\u7684\u7c7b\u4e2d\u67e5\u627e\uff08\u5f15\u7528\uff09\u3002 \u5bf9\u8c61\u6210\u5458\u7684\u6dfb\u52a0\u548c\u4fee\u6539\uff0c\u90fd\u53ea\u4f1a\u5f71\u54cd\u5f53\u524d\u5bf9\u8c61\u81ea\u5df1\uff0c\u4e0d\u4f1a\u5f71\u54cd\u7c7b\u548c\u5176\u5b83\u5bf9\u8c61\u3002 \u5220\u9664\u5bf9\u8c61\u6210\u5458\u7684\u65f6\u5019\uff0c\u5fc5\u987b\u662f\u8be5\u5bf9\u8c61\u81ea\u5df1\u5177\u5907\u7684\u6210\u5458\u624d\u53ef\u4ee5\uff0c\u4e0d\u80fd\u5220\u9664\u7c7b\u4e2d\u5f15\u7528\u7684\u6210\u5458\u3002 \u5bf9\u7c7b\u6210\u5458\u7684\u64cd\u4f5c\uff0c\u4f1a\u5f71\u54cd\u8fd9\u4e2a\u7c7b\u521b\u5efa\u7684\u5bf9\u8c61\uff0c\u5305\u62ec\u4e4b\u524d\u521b\u5efa\u7684\u5bf9\u8c61\uff08\u5f15\u7528\uff09\u3002 \u7c7b\u6210\u5458\u64cd\u4f5c\uff08\u4e0d\u63a8\u8350\uff09 \u00b6 \u6210\u5458\u5c5e\u6027\uff1a \u8bbf\u95ee\uff1a ClassName.AttributeName \u4fee\u6539\uff1a ClassName.AttributeName = NewValue \uff0c\u7b49\u4e8e\u7ed9\u8fd9\u4e2a\u7c7b\u5bf9\u8c61\u521b\u5efa\u4e86\u4e00\u4e2a\u81ea\u5df1\u7684\u5c5e\u6027\uff0c\u901a\u8fc7\u8fd9\u4e2a\u7c7b\u521b\u5efa\u7684\u5bf9\u8c61\u90fd\u5177\u6709\u8fd9\u4e2a\u5c5e\u6027\u3002 \u6dfb\u52a0\uff1a ClassName.NewAttributeName = Value \uff0c\u7b49\u4e8e\u7ed9\u8fd9\u4e2a\u7c7b\u5bf9\u8c61\u521b\u5efa\u4e86\u4e00\u4e2a\u81ea\u5df1\u7684\u5c5e\u6027\uff0c\u901a\u8fc7\u8fd9\u4e2a\u7c7b\u521b\u5efa\u7684\u5bf9\u8c61\u90fd\u5177\u6709\u8fd9\u4e2a\u5c5e\u6027\u3002 \u5220\u9664\uff1a del ClassName.AttributeName \uff0c\u6ce8\u610f\uff0c\u53ea\u80fd\u5220\u9664\u7c7b\u5bf9\u8c61\u81ea\u5df1\u7684\u5c5e\u6027\uff0c\u901a\u8fc7\u8fd9\u4e2a\u7c7b\u521b\u5efa\u7684\u5bf9\u8c61\u90fd\u4e0d\u518d\u5177\u6709\u8fd9\u4e2a\u5c5e\u6027\u3002 \u6210\u5458\u65b9\u6cd5\uff1a \u8bbf\u95ee\uff1a ClassName.MethodName() \u4fee\u6539\uff1a ClassName.MethodName = NewFunction \uff0c\u7b49\u4e8e\u7ed9\u8fd9\u4e2a\u7c7b\u5bf9\u8c61\u521b\u5efa\u4e86\u4e00\u4e2a\u81ea\u5df1\u7684\u65b9\u6cd5\uff0c\u901a\u8fc7\u8fd9\u4e2a\u7c7b\u521b\u5efa\u7684\u5bf9\u8c61\u90fd\u5177\u6709\u8fd9\u4e2a\u65b9\u6cd5\u3002 \u6dfb\u52a0\uff1a ClassName.MethodName = Function \uff0c\u7b49\u4e8e\u7ed9\u8fd9\u4e2a\u7c7b\u5bf9\u8c61\u521b\u5efa\u4e86\u4e00\u4e2a\u81ea\u5df1\u7684\u65b9\u6cd5\uff0c\u901a\u8fc7\u8fd9\u4e2a\u7c7b\u521b\u5efa\u7684\u5bf9\u8c61\u90fd\u5177\u6709\u8fd9\u4e2a\u65b9\u6cd5\u3002 \u5220\u9664\uff1a del ClassName.MethodName \uff0c\u6ce8\u610f\uff0c\u53ea\u80fd\u5220\u9664\u7c7b\u5bf9\u8c61\u81ea\u5df1\u7684\u65b9\u6cd5\uff0c\u901a\u8fc7\u8fd9\u4e2a\u7c7b\u521b\u5efa\u7684\u5bf9\u8c61\u90fd\u4e0d\u518d\u5177\u6709\u8fd9\u4e2a\u65b9\u6cd5\u3002 \u6210\u5458\u65b9\u6cd5\u4e2d\u7684self \u00b6 self \u53ea\u662f\u4e00\u4e2a\u5f62\u53c2\uff0c\u4e0d\u662f\u5173\u952e\u5b57\u3002 self \u5728\u65b9\u6cd5\uff08method\uff09\u4ee3\u8868\u5f53\u524d\u5bf9\u8c61\u81ea\u5df1\u3002\u524d\u9762\u63d0\u5230\u8fc7\uff0c\u65b9\u6cd5\u7684\u7b2c\u4e00\u4e2a\u53c2\u6570\u5e38\u5e38\u88ab\u547d\u540d\u4e3a self \uff0c\u8fd9\u53ea\u662f\u4e00\u4e2a\u7ea6\u5b9a\u3002 \u53ef\u4ee5\u4f7f\u7528 self \u5728\u7c7b\u5185\u90e8\u64cd\u4f5c\u6210\u5458\uff08\u6dfb\u52a0\u3001\u4fee\u6539\u3001\u5220\u9664\u7b49\uff09\u3002 \u65b9\u6cd5\u7684\u5206\u7c7b\uff1a \u542b\u6709self\u6216\u8005\u53ef\u4ee5\u63a5\u53d7\u5bf9\u8c61\u4f5c\u4e3a\u53c2\u6570\u7684\u65b9\u6cd5\uff0c\u79f0\u4e3a**\u975e\u7ed1\u5b9a\u7c7b\u65b9\u6cd5**\uff0c\u975e\u7ed1\u5b9a\u7c7b\u7684\u65b9\u6cd5\u53ef\u4ee5\u4f7f\u7528\u5bf9\u8c61\u53bb\u8bbf\u95ee\u3002 \u4e0d\u542b\u6709self\u6216\u8005\u4e0d\u80fd\u63a5\u53d7\u5bf9\u8c61\u4f5c\u4e3a\u53c2\u6570\u7684\u65b9\u6cd5\uff0c\u79f0\u4e3a**\u7ed1\u5b9a\u7c7b\u65b9\u6cd5**\uff0c\u7ed1\u5b9a\u65b9\u6cd5\u53ea\u80fd\u4f7f\u7528\u7c7b\u53bb\u8bbf\u95ee\u3002 \u9b54\u672f\u65b9\u6cd5 \u00b6 \u9b54\u672f\u65b9\u6cd5\uff08Magic Method\uff09\u548c\u666e\u901a\u65b9\u6cd5\u4e00\u6837\uff0c\u90fd\u662f\u7c7b\u4e2d\u5b9a\u4e49\u7684\u6210\u5458\u65b9\u6cd5\u3002 \u9b54\u672f\u65b9\u6cd5\u540d\u79f0\u524d\u540e\u5404\u67092\u4e2a\u4e0b\u5212\u7ebf\uff0c\u6bd4\u5982 __init__ \u9b54\u672f\u65b9\u6cd5\u662f\u4e0d\u9700\u8981\u624b\u52a8\u8c03\u7528\u7684\uff0c\u4f1a\u5728\u67d0\u79cd\u60c5\u51b5\u4e0b\u81ea\u52a8\u89e6\u53d1\uff08\u81ea\u52a8\u6267\u884c\uff09\u3002 \u9b54\u672f\u65b9\u6cd5\u662f\u7cfb\u7edf\u5b9a\u4e49\u597d\u7684\uff0c\u4e0d\u662f\u7528\u6237\u5b9a\u4e49\u7684\u3002 __init__ \u521d\u59cb\u5316\u65b9\u6cd5\uff0c\u4e5f\u79f0\u4f5c**\u6784\u9020\u65b9\u6cd5** \u00b6 \u7c7b\u5b9e\u4f8b\u5316\u5bf9\u8c61\u521b\u5efa\u540e\u81ea\u52a8\u89e6\u53d1\u3002 __init__ \u521d\u59cb\u5316\u65b9\u6cd5\u53ef\u4ee5\u7528\u6765\u5728\u5bf9\u8c61\u5b9e\u4f8b\u5316\u540e\u5b8c\u6210\u5bf9\u8c61\u7684\u521d\u59cb\u5316\uff0c\u6bd4\u5982\u5c5e\u6027\u8d4b\u503c\uff0c\u65b9\u6cd5\u8c03\u7528\u7b49\u3002 __del__ \u6790\u6784\u65b9\u6cd5 \u00b6 \u7c7b\u5b9e\u4f8b\u5316\u5bf9\u8c61\u88ab\u9500\u6bc1\u65f6\u81ea\u52a8\u89e6\u53d1\u3002 __del__ \u6790\u6784\u65b9\u6cd5\u53ef\u4ee5\u5728\u9500\u6bc1\u5bf9\u8c61\u65f6\u5b8c\u6210\u4e00\u4e9b\u7279\u6b8a\u4efb\u52a1\uff0c\u5173\u95ed\u5bf9\u8c61\u6253\u5f00\u7684\u4e00\u4e9b\u8d44\u6e90\uff0c\u5982\u6587\u4ef6\u7b49\u3002 \u6ce8\u610f\uff0c\u662f\u5bf9\u8c61\u88ab\u9500\u6bc1\u65f6\u89e6\u53d1\u4e86\u6790\u6784\u65b9\u6cd5\uff0c\u800c\u4e0d\u662f\u8fd9\u4e2a\u6790\u6784\u65b9\u6cd5\u9500\u6bc1\u4e86\u5bf9\u8c61\u3002 \u5bf9\u8c61\u9500\u6bc1\u7684\u60c5\u51b5\uff1a \u5f53\u7a0b\u5e8f\u6267\u884c\u5b8c\u6bd5\uff0c\u9500\u6bc1\u548c\u91ca\u653e\u5185\u5b58\u4e2d\u7684\u8d44\u6e90\u3002 \u4f7f\u7528 del \u5220\u9664\u65f6\u3002 \u5bf9\u8c61\u4e0d\u518d\u88ab\u4efb\u4f55\u5bf9\u8c61\u5f15\u7528\u65f6\uff0c\u4f1a\u81ea\u52a8\u9500\u6bc1\u3002 \u770b\u4e0b\u9762\u7684\u4f8b\u5b50\uff0c\u5bf9\u6bd4 bmw = Car('BMW') \u548c Car('BMW') \u6765\u7406\u89e3 init \u548c del \u7684\u89e6\u53d1\u673a\u5236\u3002 \u7f16\u8f91\u6587\u4ef6 file1.py class Car (): brand = \"\" def __init__ ( self , car_brand ): self . brand = car_brand print ( f \"initial method called, create { self . brand } car\" ) def __del__ ( self ): print ( f \"delete method called, destroy { self . brand } car\" ) bmw = Car ( 'BMW' ) vw = Car ( 'VW' ) \u6267\u884c\u4e0a\u9762\u7684\u4ee3\u7801 python3 file1.py \u5f97\u5230\u5982\u4e0b\u8f93\u51fa\uff0c\u5728\u7a0b\u5e8f\u6267\u884c\u5b8c\u6bd5\u65f6\uff0c\u4f9d\u6b21\u6267\u884c __del__ \u3002 initial method called , create BMW car initial method called , create VW car delete method called , destroy BMW car delete method called , destroy VW car \u7f16\u8f91\u6587\u4ef6 file2.py class Car (): brand = \"\" def __init__ ( self , car_brand ): self . brand = car_brand print ( f \"initial method called, create { self . brand } car\" ) def __del__ ( self ): print ( f \"delete method called, destroy { self . brand } car\" ) Car ( 'BMW' ) Car ( 'VW' ) \u6267\u884c\u4e0a\u9762\u7684\u4ee3\u7801 python3 file2.py \u5f97\u5230\u5982\u4e0b\u8f93\u51fa\uff1a initial method called , create BMW car delete method called , destroy BMW car initial method called , create VW car delete method called , destroy VW car Python\u51fd\u6570\u5185\u7701\u5185\u7701 \u00b6 \u4ece\u9b54\u672f\u65b9\u6cd5\u53ef\u4ee5\u5ef6\u7533\u5230Python\u7684**\u51fd\u6570\u5185\u7701**\uff0c\u51fd\u6570\u5185\u7701\u7684\u610f\u601d\u662f\u8bf4\uff0c\u5f53\u4f60\u62ff\u5230\u4e00\u4e2a\u201c\u51fd\u6570\u5bf9\u8c61\u201d\u7684\u65f6\u5019\uff0c\u4f60\u53ef\u4ee5\u7ee7\u7eed\u77e5\u9053\uff0c\u5b83\u7684\u540d\u5b57\uff0c\u53c2\u6570\u5b9a\u4e49\u7b49\u4fe1\u606f\u3002\u8fd9\u4e9b\u4fe1\u606f\u53ef\u4ee5\u901a\u8fc7\u51fd\u6570\u5bf9\u8c61\u7684\u5c5e\u6027\uff08\u4e00\u4e9b\u53cc\u4e0b\u5212\u7ebf\u7684\u9b54\u6cd5\u65b9\u6cd5\uff09\u5f97\u5230\u3002\u7b80\u8a00\u4e4b\uff0c\u5185\u7701\u662f\u5728\u8fd0\u884c\u65f6\u786e\u5b9a\u5bf9\u8c61\u7c7b\u578b\u7684\u80fd\u529b\u3002 \u4e0b\u9762\u7684\u4f8b\u5b50\u5217\u51fa\u4e86\u5e38\u89c4\u5bf9\u8c61\u6ca1\u6709\u800c\u51fd\u6570\u6709\u7684\u5c5e\u6027\u3002 class C : pass obj = C () def func (): pass sorted ( set ( dir ( obj )) - set ( dir ( func ))) # ['__weakref__'] sorted ( set ( dir ( func )) - set ( dir ( obj ))) # ['__annotations__', '__call__', '__closure__', '__code__', '__defaults__', '__get__', '__globals__', '__kwdefaults__', '__name__', '__qualname__'] \u4e0b\u8868\u603b\u7ed3\u4e86\u7528\u6237\u5b9a\u4e49\u7684\u51fd\u6570\u7684\u5c5e\u6027\u3002 \u4e0b\u9762\u7684\u4f8b\u5b50\u662f\u6f14\u793a\u4e86\u5728\u6307\u5b9a\u957f\u5ea6\u9644\u8fd1\u622a\u65ad\u5b57\u7b26\u4e32\u7684\u51fd\u6570\uff0c\u4ee5\u53ca\u63d0\u53d6\u5173\u4e8e\u51fd\u6570\u53c2\u6570\u7684\u4fe1\u606f\u7684\u65b9\u6cd5\u3002 \u53c2\u6570\u540d\u79f0\u5728 __code__.co_varnames \u4e2d\uff0c\u4f46\u8fd9\u91cc\u9762\u4e5f\u5305\u542b\u51fd\u6570\u5b9a\u4e49\u4f53\u4e2d\u521b\u5efa\u7684\u5c40\u90e8\u53d8\u91cf\u3002\u56e0\u6b64\uff0c\u53c2\u6570\u540d\u79f0\u662f\u524d N \u4e2a\u5b57\u7b26\u4e32\uff0c N \u7684\u503c\u7531 __code__.co_argcount \u786e\u5b9a\uff0c\u4f8b\u5b50\u91cc\u9762N\u662f2\uff0c\u5373\u53c2\u6570\u540d\u79f0\u662f text \u548c max_len \uff0c\u5c40\u90e8\u53d8\u91cf\u662f end \u3001 space_before \u3001 space_after \u3002 def clip ( text , max_len = 80 ): \"\"\" Get sub-string by the first blank before or after specified position. rfind() \u8fd4\u56de\u5b57\u7b26\u4e32\u6700\u540e\u4e00\u6b21\u51fa\u73b0\u7684\u4f4d\u7f6e\uff0c\u5982\u679c\u6ca1\u6709\u5339\u914d\u9879\u5219\u8fd4\u56de -1. \"\"\" end = None if len ( text ) > max_len : space_before = text . rfind ( ' ' , 0 , max_len ) if space_before >= 0 : end = space_before else : space_after = text . rfind ( ' ' , max_len ) if space_after >= 0 : end = space_after if end is None : end = len ( text ) return text [: end ] . rstrip () clip ( 'This is the string' , max_len = 10 ) # 'This is' clip . __defaults__ # (80,) clip . __code__ # \", line 1> clip . __code__ . co_varnames # ('text', 'max_len', 'end', 'space_before', 'space_after') clip . __code__ . co_argcount # 2 clip . __doc__ # '\\n Get sub-string by the first blank before or after specified position.\\n rfind() \u8fd4\u56de\u5b57\u7b26\u4e32\u6700\u540e\u4e00\u6b21\u51fa\u73b0\u7684\u4f4d\u7f6e\uff0c\u5982\u679c\u6ca1\u6709\u5339\u914d\u9879\u5219\u8fd4\u56de -1.\\n ' \u4e0a\u4f8b\u4e2d\uff0c\u53c2\u6570\u7684\u9ed8\u8ba4\u503c\u53ea\u80fd\u901a\u8fc7\u5b83\u4eec\u5728 __defaults__ \u5143\u7ec4\u4e2d\u7684\u4f4d\u7f6e\u786e\u5b9a\uff0c\u56e0\u6b64\u8981\u4ece\u540e\u5411\u524d\u626b\u63cf\u624d\u80fd\u628a\u53c2\u6570\u548c\u9ed8\u8ba4\u503c\u5bf9\u5e94\u8d77\u6765\uff0c\u6709\u4e9b\u4e0d\u5408\u7406\u3002\u5f15\u5165 inspect \u6a21\u5757\u540e\uff0c\u4e0a\u9762\u7684\u64cd\u4f5c\u5c31\u66f4\u5bb9\u6613\u4e86\u3002 inspect.signature \u51fd\u6570\u8fd4\u56de\u4e00\u4e2a inspect.Signature \u5bf9\u8c61\uff0c\u5b83\u6709\u4e00\u4e2a parameters \u5c5e\u6027\uff0c\u8fd9\u662f\u4e00\u4e2a\u6709\u5e8f\u6620\u5c04\uff0c\u628a\u53c2\u6570\u540d\u548c inspect.Parameter \u5bf9\u8c61\u5bf9\u5e94\u8d77\u6765\u3002\u5404\u4e2a Parameter \u5c5e\u6027\u4e5f\u6709\u81ea\u5df1\u7684\u5c5e\u6027\uff0c\u4f8b\u5982 name \u3001 default \u548c kind \u3002 from inspect import signature sig = signature ( clip ) type ( sig ) # print ( sig ) # (text, max_len=80) print ( str ( sig )) # (text, max_len=80) for name , param in sig . parameters . items (): print ( f ' { param . kind } : { name } = { param . default } ' ) # 1 : text = # 1 : max_len = 80 \u51fd\u6570\u6ce8\u89e3\u3002 Python 3 \u63d0\u4f9b\u4e86\u4e00\u79cd\u53e5\u6cd5\uff0c\u7528\u4e8e\u4e3a\u51fd\u6570\u58f0\u660e\u4e2d\u7684\u53c2\u6570\u548c\u8fd4\u56de\u503c\u9644\u52a0\u5143\u6570\u636e\u3002\u5bf9\u4e0a\u4f8b\u6dfb\u52a0\u6ce8\u89e3\u540e\u5982\u4e0b\u6240\u793a\uff0c\u4e8c\u8005\u552f\u4e00\u7684\u533a\u522b\u5728\u7b2c\u4e00\u884c\u3002 \u51fd\u6570\u58f0\u660e\u4e2d\u7684\u5404\u4e2a\u53c2\u6570\u53ef\u4ee5\u5728:\u4e4b\u540e\u589e\u52a0\u6ce8\u89e3\u8868\u8fbe\u5f0f\u3002 \u5982\u679c\u53c2\u6570\u6709\u9ed8\u8ba4\u503c\uff0c\u6ce8\u89e3\u653e\u5728\u53c2\u6570\u540d\u548c = \u53f7\u4e4b\u95f4\u3002 \u5982\u679c\u60f3\u6ce8\u89e3\u8fd4\u56de\u503c\uff0c\u5728)\u548c\u51fd\u6570\u58f0\u660e\u672b\u5c3e\u7684 : \u4e4b\u95f4\u6dfb\u52a0 -> \u548c\u4e00\u4e2a\u8868\u8fbe\u5f0f\u3002\u90a3\u4e2a\u8868\u8fbe\u5f0f\u53ef\u4ee5\u662f\u4efb\u4f55\u7c7b\u578b\u3002 \u6ce8\u89e3\u4e2d\u6700\u5e38\u7528\u7684\u7c7b\u578b\u662f\u7c7b\uff08\u5982 str \u6216 int \uff09\u548c\u5b57\u7b26\u4e32\uff08\u5982'int > 0'\uff09\u3002\u5728\u4e0b\u4f8b\u4e2d\uff0cmax_len\u53c2\u6570\u7684\u6ce8\u89e3\u7528\u7684\u662f\u5b57\u7b26\u4e32\u3002 \u6ce8\u89e3\u4e0d\u4f1a\u505a\u4efb\u4f55\u5904\u7406\uff0c\u53ea\u662f\u5b58\u50a8\u5728\u51fd\u6570\u7684 __annotations__ \u5c5e\u6027\uff08\u4e00\u4e2a\u5b57\u5178\uff09\u4e2d\u3002\u6362\u53e5\u8bdd\u8bf4\uff0c\u6ce8\u89e3\u5bf9Python\u89e3\u91ca\u5668\u6ca1\u6709\u4efb\u4f55\u610f\u4e49\u3002 \u6ce8\u89e3\u53ea\u662f\u5143\u6570\u636e \uff0c\u53ef\u4ee5\u4f9bIDE\u3001\u6846\u67b6\u548c\u88c5\u9970\u5668\u7b49\u5de5\u5177\u4f7f\u7528\u3002 return \u952e\u4fdd\u5b58\u7684\u662f\u8fd4\u56de\u503c\u6ce8\u89e3\uff0c\u5373\u4e0b\u4f8b\u4e2d\u51fd\u6570\u58f0\u660e\u91cc\u4ee5 -> \u6807\u8bb0\u7684\u90e8\u5206\u3002 def clip ( text : str , max_len : 'int > 0' = 80 ) -> str : \"\"\" Get sub-string by the first blank before or after specified position. rfind() \u8fd4\u56de\u5b57\u7b26\u4e32\u6700\u540e\u4e00\u6b21\u51fa\u73b0\u7684\u4f4d\u7f6e\uff0c\u5982\u679c\u6ca1\u6709\u5339\u914d\u9879\u5219\u8fd4\u56de -1. \"\"\" end = None if len ( text ) > max_len : space_before = text . rfind ( ' ' , 0 , max_len ) if space_before >= 0 : end = space_before else : space_after = text . rfind ( ' ' , max_len ) if space_after >= 0 : end = space_after if end is None : end = len ( text ) return text [: end ] . rstrip () clip ( 'This is the string' , max_len = 10 ) # 'This is' clip . __annotations__ # {'text': , 'max_len': 'int > 0', 'return': } signature \u51fd\u6570\u8fd4\u56de\u4e00\u4e2a Signature \u5bf9\u8c61\uff0c\u5b83\u6709\u4e00\u4e2a return_annotation \u5c5e\u6027\u548c\u4e00\u4e2a parameters \u5c5e\u6027\uff0c\u540e\u8005\u662f\u4e00\u4e2a\u5b57\u5178\uff0c\u628a\u53c2\u6570\u540d\u6620\u5c04\u5230 Parameter \u5bf9\u8c61\u4e0a\u3002\u6bcf\u4e2a Parameter \u5bf9\u8c61\u81ea\u5df1\u4e5f\u6709 annotation \u5c5e\u6027\u3002 from inspect import signature sig = signature ( clip ) print ( sig . return_annotation ) # for param in sig . parameters . values (): note = repr ( param . annotation ) . ljust ( 13 ) print ( f ' { note } : { param . name } = { param . default } ' ) # : text = # 'int > 0' : max_len = 80","title":"Python\u9762\u5411\u5bf9\u8c61\u6982\u5ff5"},{"location":"python/Foundation/ch04/#python","text":"\u7c7b(class)\u628a\u6570\u636e\u4e0e\u529f\u80fd\u7ed1\u5b9a\u5728\u4e00\u8d77\u3002\u521b\u5efa\u65b0\u7c7b\u5c31\u662f\u521b\u5efa\u65b0\u7684\u5bf9\u8c61\u7c7b\u578b\uff08type of object\uff09\uff0c\u4ece\u800c\u521b\u5efa\u8be5\u7c7b\u578b\u7684\u65b0\u5b9e\u4f8b\uff08instances\uff09\u3002 \u7c7b\u5b9e\u4f8b\u5177\u6709\u591a\u79cd\u4fdd\u6301\u81ea\u8eab\u72b6\u6001\u7684\u5c5e\u6027\uff08attributes\uff09\u3002 \u7c7b\u5b9e\u4f8b\u8fd8\u652f\u6301\uff08\u7531\u7c7b\u5b9a\u4e49\u7684\uff09\u4fee\u6539\u81ea\u8eab\u72b6\u6001\u7684\u65b9\u6cd5\uff08methods\uff09\u3002 Python\u7684\u7c7b\u652f\u6301\u6240\u6709\u9762\u5411\u5bf9\u8c61\u7f16\u7a0b\uff08OOP\uff09\u7684\u6807\u51c6\u7279\u6027\uff1a \u7c7b\u7ee7\u627f\uff08class inheritance\uff09\u673a\u5236\u652f\u6301\u591a\u4e2a\u57fa\u7c7b\uff08base classes\uff09\uff1b \u6d3e\u751f\u7c7b\uff08derived class\uff09\u53ef\u4ee5\u8986\u76d6\u57fa\u7c7b\u7684\u4efb\u4f55\u65b9\u6cd5\uff08methods\uff09\uff1b \u7c7b\u7684\u65b9\u6cd5\u53ef\u4ee5\u8c03\u7528\u57fa\u7c7b\u4e2d\u76f8\u540c\u540d\u79f0\u7684\u65b9\u6cd5 \u5bf9\u8c61\u53ef\u4ee5\u5305\u542b\u4efb\u610f\u6570\u91cf\u548c\u7c7b\u578b\u7684\u6570\u636e\u3002 \u7c7b\uff08class\uff09\u548c\u6a21\u5757\uff08module\uff09\u90fd\u62e5\u6709\u52a8\u6001\u7279\u6027\uff08dynamic nature\uff09\uff1a\u5728\u8fd0\u884c\u65f6\u521b\u5efa\uff0c\u521b\u5efa\u540e\u4e5f\u53ef\u4ee5\u4fee\u6539\u3002","title":"Python\u9762\u5411\u5bf9\u8c61\u6982\u5ff5"},{"location":"python/Foundation/ch04/#namesobjects","text":"\u5bf9\u8c61\u4e4b\u95f4\u76f8\u4e92\u72ec\u7acb\uff0c\u591a\u4e2a\u540d\u79f0\uff08names\uff09\uff08\u5728\u591a\u4e2a\u4f5c\u7528\u57df\u5185\uff09\u53ef\u4ee5\u7ed1\u5b9a\u5230\u540c\u4e00\u4e2a\u5bf9\u8c61\u3002 \u5176\u4ed6\u8bed\u8a00\u79f0\u4e4b\u4e3a\u522b\u540d\uff08alias\uff09\u3002 \u522b\u540d\u5728\u67d0\u4e9b\u65b9\u9762\u5c31\u50cf\u6307\u9488\u3002\u4f8b\u5982\uff0c\u4f20\u9012\u5bf9\u8c61\u7684\u4ee3\u4ef7\u5f88\u5c0f\uff0c\u56e0\u4e3a\u5b9e\u73b0\u53ea\u4f20\u9012\u4e00\u4e2a\u6307\u9488\uff1b\u5982\u679c\u51fd\u6570\u4fee\u6539\u4e86\u4f5c\u4e3a\u53c2\u6570\u4f20\u9012\u7684\u5bf9\u8c61\uff0c\u8c03\u7528\u8005\u5c31\u53ef\u4ee5\u770b\u5230\u66f4\u6539\u3002","title":"\u540d\u79f0Names\u548c\u5bf9\u8c61Objects"},{"location":"python/Foundation/ch04/#scopesnamespaces","text":"**\u547d\u540d\u7a7a\u95f4\uff08namespace\uff09**\u662f\u4e00\u4e2a\u4ece\u540d\u5b57\u5230\u5bf9\u8c61\u7684\u6620\u5c04\u3002 \u5f53\u524d\u5927\u90e8\u5206\u547d\u540d\u7a7a\u95f4\u90fd\u7531 Python \u5b57\u5178\u5b9e\u73b0\u3002 \u4e0b\u9762\u662f\u51e0\u4e2a\u547d\u540d\u7a7a\u95f4\u7684\u4f8b\u5b50\uff1a \u5b58\u653e\u5185\u7f6e\u51fd\u6570\u7684\u96c6\u5408\uff08\u5305\u542b abs() \u8fd9\u6837\u7684\u51fd\u6570\uff0c\u548c\u5185\u5efa\u7684\u5f02\u5e38\u7b49\uff09\uff1b \u6a21\u5757\u4e2d\u7684\u5168\u5c40\u540d\u79f0\uff1b \u51fd\u6570\u8c03\u7528\u4e2d\u7684\u5c40\u90e8\u540d\u79f0\uff1b \u4ece\u67d0\u79cd\u610f\u4e49\u4e0a\u8bf4\uff0c \u5bf9\u8c61\u7684\u5c5e\u6027\u96c6\u5408\uff08the set of attributes of an object\uff09\u4e5f\u662f\u4e00\u79cd\u547d\u540d\u7a7a\u95f4\u7684\u5f62\u5f0f \u3002 \u5173\u4e8e\u547d\u540d\u7a7a\u95f4\u7684\u91cd\u8981\u4e00\u70b9\u662f\uff0c\u4e0d\u540c\u547d\u540d\u7a7a\u95f4\u4e2d\u7684\u540d\u79f0\u4e4b\u95f4\u7edd\u5bf9\u6ca1\u6709\u5173\u7cfb\uff1b \u4f8b\u5982\uff0c\u5728\u4e24\u4e2a\u4e0d\u540c\u7684\u6a21\u5757\u4e2d\u90fd\u53ef\u4ee5\u5b9a\u4e49\u4e00\u4e2a maximize \u51fd\u6570\u800c\u4e0d\u4f1a\u4ea7\u751f\u6df7\u6dc6\uff0c\u4f46\u5728\u8c03\u7528 maximize \u51fd\u6570\u65f6\u5fc5\u987b\u5fc5\u987b\u5728\u5176\u524d\u9762\u52a0\u4e0a\u6a21\u5757\u540d\u79f0\u3002 \u4efb\u4f55\u8ddf\u5728\u4e00\u4e2a\u70b9\u53f7\u4e4b\u540e\u7684\u540d\u79f0\u90fd\u79f0\u4e3a**\u5c5e\u6027\uff08attribute\uff09**\u3002\u4f8b\u5982\uff0c\u5728\u8868\u8fbe\u5f0f z.real \u4e2d\uff0c real \u662f\u5bf9\u8c61 z \u7684\u4e00\u4e2a\u5c5e\u6027\u3002 \u6309\u4e25\u683c\u7684\u8bf4\u6cd5\uff0c \u5bf9\u6a21\u5757\uff08module\uff09\u4e2d\u7684\u540d\u79f0\u7684\u5f15\u7528\uff08reference\uff09\u90fd\u5c5e\u4e8e\u5c5e\u6027\u5f15\u7528\uff08attribute reference\uff09 \uff1a \u5728\u8868\u8fbe\u5f0f modname.funcname \u4e2d\uff0c modname \u662f\u4e00\u4e2a\u6a21\u5757\u5bf9\u8c61\uff08module object\uff09\u800c funcname \u662f\u5b83\u7684\u4e00\u4e2a\u5c5e\u6027\u3002 \u5728\u6b64\u60c5\u51b5\u4e0b\u5728\u6a21\u5757\u7684\u5c5e\u6027\uff08module\u2019s attribute\uff09\u548c\u6a21\u5757\u4e2d\u5b9a\u4e49\u7684\u5168\u5c40\u540d\u79f0\u4e4b\u95f4\u6b63\u597d\u5b58\u5728\u4e00\u4e2a\u76f4\u89c2\u7684\u6620\u5c04\uff1a\u5b83\u4eec\u5171\u4eab\u76f8\u540c\u7684\u547d\u540d\u7a7a\u95f4\u3002 \u4f46\u5b58\u5728\u4e00\u4e2a\u4f8b\u5916\u3002 \u6a21\u5757\u5bf9\u8c61\u6709\u4e00\u4e2a\u53ea\u8bfb\u5c5e\u6027 __dict__ \uff0c\u5b83\u8fd4\u56de\u7528\u4e8e\u5b9e\u73b0\u6a21\u5757\u547d\u540d\u7a7a\u95f4\u7684\u5b57\u5178\uff1b __dict__ \u662f\u5c5e\u6027\u4f46\u4e0d\u662f\u5168\u5c40\u540d\u79f0\u3002 \u4f7f\u7528\u8fd9\u4e2a\u5c06\u8fdd\u53cd\u547d\u540d\u7a7a\u95f4\u5b9e\u73b0\u7684\u62bd\u8c61\uff0c\u5e94\u5f53\u4ec5\u88ab\u7528\u4e8e\u4e8b\u540e\u8c03\u8bd5\u5668\u4e4b\u7c7b\u7684\u573a\u5408\u3002 **\u5c5e\u6027\uff08attribute\uff09**\u53ef\u4ee5\u662f\u53ea\u8bfb\u6216\u8005\u53ef\u5199\u7684\uff0c\u6240\u4ee5\u53ef\u4ee5\u5bf9\u5c5e\u6027\u8fdb\u884c\u8d4b\u503c\uff0c\u4f8b\u5982 modname.the_answer = 42 \u3002 \u5220\u9664\u5c5e\u6027\u53ef\u4ee5\u7528del\u8bed\u53e5\uff0c\u4f8b\u5982\uff0c del modname.the_answer \u5c06\u4f1a\u4ece\u540d\u4e3a modname \u7684\u5bf9\u8c61\u4e2d\u79fb\u9664 the_answer \u5c5e\u6027\u3002 \u547d\u540d\u7a7a\u95f4\u5728\u4e0d\u540c\u65f6\u523b\u88ab\u521b\u5efa\uff0c\u62e5\u6709\u4e0d\u540c\u7684\u751f\u5b58\u671f\uff08lifetimes\uff09\u3002\u5305\u542b\u5185\u7f6e\u540d\u79f0\uff08built-in names\uff09\u7684\u547d\u540d\u7a7a\u95f4\u662f\u5728Python\u89e3\u91ca\u5668\u542f\u52a8\u65f6\u521b\u5efa\u7684\uff0c\u6c38\u8fdc\u4e0d\u4f1a\u88ab\u5220\u9664\u3002 \u6a21\u5757\u7684\u5168\u5c40\u547d\u540d\u7a7a\u95f4\uff08global namespace\uff09\u5728\u6a21\u5757\u5b9a\u4e49\u88ab\u8bfb\u5165\u65f6\u521b\u5efa\uff1b\u901a\u5e38\uff0c\u6a21\u5757\u547d\u540d\u7a7a\u95f4\u4e5f\u4f1a\u6301\u7eed\u5230\u89e3\u91ca\u5668\u9000\u51fa\u3002 \u88ab\u89e3\u91ca\u5668\u7684\u9876\u5c42\u8c03\u7528\uff08top-level invocation\uff09\u6267\u884c\u7684\u8bed\u53e5\uff0c\u4ece\u4e00\u4e2a\u811a\u672c\u6587\u4ef6\u8bfb\u53d6\u6216\u4ea4\u4e92\u5f0f\u5730\u8bfb\u53d6\uff0c\u88ab\u8ba4\u4e3a\u662f __main__ \u6a21\u5757\u8c03\u7528\u7684\u4e00\u90e8\u5206\uff0c\u56e0\u6b64\u5b83\u4eec\u62e5\u6709\u81ea\u5df1\u7684\u5168\u5c40\u547d\u540d\u7a7a\u95f4\u3002 \u5185\u7f6e\u540d\u79f0\uff08built-in names\uff09\u5b9e\u9645\u4e0a\u4e5f\u5b58\u5728\u4e8e\u4e00\u4e2a\u6a21\u5757\u4e2d\uff0c\u8fd9\u4e2a\u6a21\u5757\u88ab\u79f0\u4f5c builtins \u3002 \u4e00\u4e2a\u51fd\u6570\u7684\u672c\u5730\u547d\u540d\u7a7a\u95f4\uff08local namespace\uff09\u5728\u8fd9\u4e2a\u51fd\u6570\u88ab\u8c03\u7528\u65f6\u521b\u5efa\uff0c\u5e76\u5728\u51fd\u6570\u8fd4\u56de\u6216\u629b\u51fa\u4e00\u4e2a\u65e0\u6cd5\u5728\u8be5\u51fd\u6570\u5185\u90e8\u5904\u7406\u7684\u9519\u8bef\u65f6\u88ab\u5220\u9664\u3002 \u6bcf\u6b21\u9012\u5f52\u8c03\u7528\uff08recursive invocations\uff09\u90fd\u4f1a\u6709\u5b83\u81ea\u5df1\u7684\u672c\u5730\u547d\u540d\u7a7a\u95f4\u3002 \u4e00\u4e2a**\u4f5c\u7528\u57df\uff08scope\uff09**\u662f\u4e00\u4e2a\u547d\u540d\u7a7a\u95f4\u53ef\u76f4\u63a5\u8bbf\u95ee\uff08directly accessible\uff09\u7684Python\u7a0b\u5e8f\u7684\u4ee3\u7801\u533a\u57df\u3002 \u8fd9\u91cc\u7684 \u201c\u53ef\u76f4\u63a5\u8bbf\u95ee\u201d \u610f\u5473\u7740\u4e0d\u52a0\u4efb\u4f55\u9650\u5b9a\u7684\u540d\u79f0\u5f15\u7528\u4f1a\u5728\u547d\u540d\u7a7a\u95f4\u4e2d\u8fdb\u884c\u67e5\u627e\u3002 \u867d\u7136\u4f5c\u7528\u57df\u662f\u9759\u6001\u5730\u786e\u5b9a\u7684\uff0c\u4f46\u5b83\u4eec\u4f1a\u88ab\u52a8\u6001\u5730\u4f7f\u7528\u3002 \u5728\u4ee3\u7801\u6267\u884c\u671f\u95f4\u7684\u4efb\u4f55\u65f6\u523b\uff0c\u4f1a\u67093\u62164\u4e2a\u7684\u5d4c\u5957\u4f5c\u7528\u57df\u4f9b\u547d\u540d\u7a7a\u95f4\u76f4\u63a5\u8bbf\u95ee: \u6700\u5148\u641c\u7d22\u7684\u6700\u5185\u90e8\u4f5c\u7528\u57df\u5305\u542b\u5c40\u90e8\u540d\u79f0 \u4ece\u6700\u8fd1\u7684\u5c01\u95ed\u4f5c\u7528\u57df\u5f00\u59cb\u641c\u7d22\u7684\u4efb\u4f55\u5c01\u95ed\u51fd\u6570\u7684\u4f5c\u7528\u57df\u5305\u542b\u975e\u5c40\u90e8\u540d\u79f0\uff0c\u4e5f\u5305\u62ec\u975e\u5168\u5c40\u540d\u79f0 \u5012\u6570\u7b2c\u4e8c\u4e2a\u4f5c\u7528\u57df\u5305\u542b\u5f53\u524d\u6a21\u5757\u7684\u5168\u5c40\u540d\u79f0 \u6700\u5916\u9762\u7684\u4f5c\u7528\u57df\uff08\u6700\u540e\u641c\u7d22\uff09\u662f\u5305\u542b\u5185\u7f6e\u540d\u79f0\u7684\u547d\u540d\u7a7a\u95f4 \u5982\u679c\u4e00\u4e2a\u540d\u79f0\u88ab\u58f0\u660e\u4e3a\u5168\u5c40\u53d8\u91cf\uff0c\u5219\u6240\u6709\u5f15\u7528\u548c\u8d4b\u503c\u5c06\u76f4\u63a5\u6307\u5411\u8be5\u6a21\u5757\u5168\u5c40\u540d\u79f0\u6240\u5728\u7684\u4e2d\u95f4\u4f5c\u7528\u57df\u3002 \u5982\u679c\u8981\u91cd\u65b0\u7ed1\u5b9a\u5728\u6700\u5185\u5c42\u4f5c\u7528\u57df\u4ee5\u5916\u7684\u53d8\u91cf\uff0c\u53ef\u4ee5\u4f7f\u7528 nonlocal \u8bed\u53e5\u58f0\u660e\u4e3a\u975e\u672c\u5730\u53d8\u91cf\u3002 \u5982\u679c\u6ca1\u6709\u88ab\u58f0\u660e\u4e3a\u975e\u672c\u5730\u53d8\u91cf\uff0c\u8fd9\u4e9b\u53d8\u91cf\u5c06\u662f\u53ea\u8bfb\u7684\u3002\u7ed9\u8fd9\u6837\u7684\u53d8\u91cf\u8d4b\u65b0\u503c\u53ea\u4f1a\u5728\u6700\u5185\u5c42\u4f5c\u7528\u57df\u4e2d\u521b\u5efa\u4e00\u4e2a*\u65b0\u7684*\u5c40\u90e8\u53d8\u91cf\uff0c\u800c\u540c\u540d\u7684\u5916\u90e8\u5168\u5c40\u53d8\u91cf\u5c06\u4fdd\u6301\u4e0d\u53d8\u3002 \u901a\u5e38\uff0c\u5f53\u524d\u5c40\u90e8\u4f5c\u7528\u57df\uff08local scope\uff09\u5c06\u5f15\u7528\u5f53\u524d\u51fd\u6570\u4f5c\u7528\u57df\u7684\u540d\u79f0\uff08local name\uff09\u3002 \u5728\u51fd\u6570\u4f5c\u7528\u57df\u4ee5\u5916\uff0c\u5f53\u524d\u5c40\u90e8\u4f5c\u7528\u57df\u5c06\u5f15\u7528\u4e0e\u5168\u5c40\u4f5c\u7528\u57df\u76f8\u4e00\u81f4\u7684\u547d\u540d\u7a7a\u95f4\uff1a\u6a21\u5757\u7684\u547d\u540d\u7a7a\u95f4\uff08the module\u2019s namespace\uff09\u3002 \u5b9a\u4e49\u4e00\u4e2a\u7c7b\uff0c\u662f\u5728\u672c\u5730\u5c40\u90e8\u547d\u540d\u7a7a\u95f4\u5185\u5efa\u4e00\u4e2a\u65b0\u7684\u547d\u540d\u7a7a\u95f4\u3002 \u5728\u4e00\u4e2a\u6a21\u5757\uff08module \uff09\u5185\u5b9a\u4e49\u7684\u51fd\u6570\u7684\u4f5c\u7528\u57df\u5c31\u662f\u8be5\u6a21\u5757\u7684\u547d\u540d\u7a7a\u95f4\uff0c\u65e0\u8bba\u8be5\u51fd\u6570\u4ece\u4ec0\u4e48\u5730\u65b9\u6216\u4ee5\u4ec0\u4e48\u522b\u540d\u88ab\u8c03\u7528\u3002 \u53e6\u4e00\u65b9\u9762\uff0c\u5b9e\u9645\u7684\u540d\u79f0\u641c\u7d22\u662f\u5728\u8fd0\u884c\u65f6\u52a8\u6001\u5b8c\u6210\u7684\u3002 \u4f46\u662f\uff0cPython\u6b63\u5728\u671d\u7740\u201c\u7f16\u8bd1\u65f6\u9759\u6001\u540d\u79f0\u89e3\u6790\u201d\u7684\u65b9\u5411\u53d1\u5c55\uff0c\u56e0\u6b64\u4e0d\u8981\u8fc7\u4e8e\u4f9d\u8d56\u52a8\u6001\u540d\u79f0\u89e3\u6790\uff01\u4e8b\u5b9e\u4e0a\uff0c\u5c40\u90e8\u53d8\u91cf\u5df2\u7ecf\u662f\u88ab\u9759\u6001\u786e\u5b9a\u4e86\u3002 \u5982\u679c\u4e0d\u5b58\u5728\u751f\u6548\u7684 global \u6216 nonlocal \u8bed\u53e5\uff0c\u5219\u5bf9\u540d\u79f0\u7684\u8d4b\u503c\u603b\u662f\u4f1a\u8fdb\u5165\u6700\u5185\u5c42\u4f5c\u7528\u57df\u3002\u8d4b\u503c\u4e0d\u4f1a\u590d\u5236\u6570\u636e\uff0c\u662f\u5c06\u540d\u79f0\u7ed1\u5b9a\u5230\u5bf9\u8c61\u3002 \u5220\u9664\u4e5f\u662f\u5982\u6b64\uff1a\u8bed\u53e5 del x \u4f1a\u4ece\u5c40\u90e8\u4f5c\u7528\u57df\u6240\u5f15\u7528\u7684\u547d\u540d\u7a7a\u95f4\u4e2d\u79fb\u9664\u5bf9 x \u7684\u7ed1\u5b9a\u3002\u4e8b\u5b9e\u4e0a\uff0c\u6240\u6709\u5f15\u5165\u65b0\u540d\u79f0\u7684\u64cd\u4f5c\u90fd\u662f\u4f7f\u7528\u5c40\u90e8\u4f5c\u7528\u57df\u3002\u7279\u522b\u5730\uff0c import \u8bed\u53e5\u548c\u51fd\u6570\u5b9a\u4e49\u4f1a\u5728\u5c40\u90e8\u4f5c\u7528\u57df\u4e2d\u7ed1\u5b9a\u6a21\u5757\u6216\u51fd\u6570\u540d\u79f0\u3002 global \u8bed\u53e5\u53ef\u88ab\u7528\u6765\u8868\u660e\u7279\u5b9a\u53d8\u91cf\u5b58\u5728\u4e8e\u5168\u5c40\u4f5c\u7528\u57df\uff0c\u5e76\u4e14\u5e94\u5f53\u5728\u5168\u5c40\u4f5c\u7528\u57df\u4e2d\u88ab**\u91cd\u65b0**\u7ed1\u5b9a\uff1b nonlocal \u8bed\u53e5\u8868\u660e\u7279\u5b9a\u53d8\u91cf\u751f\u5b58\u4e8e\u5916\u5c42\u4f5c\u7528\u57df\u4e2d\uff0c\u5e76\u4e14\u5e94\u5f53\u5728\u5176\u6240\u5904\u7684\u5916\u5c42\u4f5c\u7528\u57df\u4e2d\u88ab**\u91cd\u65b0**\u7ed1\u5b9a\u3002 \u770b\u4e0b\u9762\u7684\u4f8b\u5b50\uff1a \u5c40\u90e8\u8d4b\u503c\uff08local assignment\uff0c\u8fd9\u662f\u9ed8\u8ba4\u72b6\u6001\uff09\u4e0d\u4f1a\u6539\u53d8 scope_test \u5bf9 spam \u7684\u7ed1\u5b9a\u3002 nonlocal \u8d4b\u503c\u4f1a\u6539\u53d8 scope_test \u5bf9 spam \u7684\u7ed1\u5b9a\u3002 global \u8d4b\u503c\u4f1a\u6539\u53d8\u6a21\u5757\u5c42\u7ea7\u7684\u7ed1\u5b9a\uff0c\u5373\uff0c global spam \u91cd\u65b0\u7ed1\u5b9a\u4e86spam\u7684\u5168\u5c40\u5b9a\u4e49\uff0c\u4ece spam = \"spam out of func\" \u53d8\u6210\u4e86 spam = \"global spam\" \u3002\u5982\u679c\u6ce8\u91ca\u6389def do_global()\u8fd9\u4e00\u6bb5\u4ee3\u7801\uff0c\u5219 spam = \"spam out of func\" \u8d77\u4f5c\u7528\u3002 spam = \"spam out of func\" def scope_test (): def do_local (): spam = \"local spam\" def do_nonlocal (): nonlocal spam spam = \"nonlocal spam\" def do_global (): global spam spam = \"global spam\" spam = \"test spam\" do_local () print ( \"After local assignment:\" , spam ) do_nonlocal () print ( \"After nonlocal assignment:\" , spam ) do_global () print ( \"After global assignment:\" , spam ) scope_test () print ( \"In global scope:\" , spam ) # \u8fd0\u884c\u7ed3\u679c # scope_test() After local assignment : test spam After nonlocal assignment : nonlocal spam After global assignment : nonlocal spam # print(\"In global scope:\", spam) In global scope : global spam","title":"\u4f5c\u7528\u57dfScopes\u548c\u547d\u540d\u7a7a\u95f4Namespaces"},{"location":"python/Foundation/ch04/#class","text":"","title":"\u7c7bClass"},{"location":"python/Foundation/ch04/#class-definition","text":"\u7c7b\u5b9a\u4e49\u4e0e\u51fd\u6570\u5b9a\u4e49 (def \u8bed\u53e5) \u4e00\u6837\u5fc5\u987b\u88ab\u6267\u884c\u624d\u4f1a\u8d77\u4f5c\u7528\u3002 class ClassName : < statement - 1 > ... < statement - N > \u5728\u5b9e\u8df5\u4e2d\uff0c\u7c7b\u5b9a\u4e49\u5185\u7684\u8bed\u53e5\u901a\u5e38\u90fd\u662f\u51fd\u6570\u5b9a\u4e49\uff0c\u4f46\u4e5f\u5141\u8bb8\u6709\u5176\u4ed6\u8bed\u53e5\u3002\u5728\u7c7b\u5185\u90e8\u7684\u51fd\u6570\u5b9a\u4e49\u901a\u5e38\u5177\u6709\u4e00\u79cd\u7279\u6709\u5f62\u5f0f\u7684\u53c2\u6570\u5217\u8868\uff0c\u8fd9\u662f\u7ea6\u5b9a\u7684\u65b9\u6cd5\u89c4\u8303\uff08conventions for methods\uff09\u3002 \u7f16\u8bd1\u8fc7\u7a0b\u4e2d\uff0c\u8fdb\u5165\u4e00\u4e2a\u7c7b\u7684\u5185\u90e8\uff0c\u5c06\u521b\u5efa\u4e00\u4e2a\u65b0\u7684\u547d\u540d\u7a7a\u95f4\uff0c\u4e00\u4e2a\u5c40\u90e8\u4f5c\u7528\u57df\u3002\u56e0\u6b64\uff0c\u6240\u6709\u5bf9\u7c7b\u5185\u90e8\u5c40\u90e8\u53d8\u91cf\u7684\u8d4b\u503c\u90fd\u662f\u5728\u8fd9\u4e2a\u65b0\u7684\u547d\u540d\u7a7a\u95f4\u4e4b\u5185\uff0c\u5305\u62ec\u65b0\u5b9a\u4e49\u7684\u51fd\u6570\u540d\u79f0\u3002 \u5f53\u6b63\u5e38\u79bb\u5f00\u4e00\u4e2a\u7c7b\u65f6\uff0c\u7f16\u8bd1\u8fc7\u7a0b\u5c06\u521b\u5efa\u4e00\u4e2a\u7c7b\u5bf9\u8c61\uff08class object\uff09\uff0c\u5c01\u88c5\u4e86\u7c7b\u5b9a\u4e49\u6240\u521b\u5efa\u7684\u547d\u540d\u7a7a\u95f4\u91cc\u7684\u5185\u5bb9\u3002 \u6700\u521d\u7684\uff08\u5728\u8fdb\u5165\u7c7b\u5b9a\u4e49\u4e4b\u524d\u8d77\u4f5c\u7528\u7684\uff09\u5c40\u90e8\u4f5c\u7528\u57df\u5c06\u91cd\u65b0\u751f\u6548\uff0c\u7c7b\u5bf9\u8c61\uff08class object\uff09\u5c06\u5728\u8fd9\u91cc\u88ab\u7ed1\u5b9a\u5230\u7c7b\u5b9a\u4e49\u5934\u90e8\u6240\u58f0\u660e\u7684\u7c7b\u540d\u79f0 (\u5728\u4e0a\u9762\u7684\u793a\u4f8b\u4e2d\u662f ClassName )\u3002","title":"\u7c7b\u5b9a\u4e49 Class Definition"},{"location":"python/Foundation/ch04/#class-objects","text":"\u7c7b\u5bf9\u8c61\u652f\u6301\u4e24\u79cd\u64cd\u4f5c\uff1a\u5c5e\u6027\u5f15\u7528\uff08attribute references\uff09\u548c\u5b9e\u4f8b\u5316\uff08instantiation\uff09\u3002 \u5c5e\u6027\u5f15\u7528\uff08attribute references\uff09 \u4f7f\u7528Python\u4e2d\u5c5e\u6027\u5f15\u7528\u7684\u6807\u51c6\u8bed\u6cd5: obj.name \u3002 \u5b58\u5728\u4e8e\u7c7b\u547d\u540d\u7a7a\u95f4\u4e2d\u7684\u6240\u6709\u540d\u79f0\uff0c\u7c7b\u5bf9\u8c61\u88ab\u521b\u5efa\u65f6\u540c\u65f6\u88ab\u521b\u5efa\u4e86\uff0c\u8fd9\u4e9b\u5c31\u662f\u6709\u6548\u7684\u5c5e\u6027\u540d\u79f0\u3002\u56e0\u6b64\uff0c\u5982\u679c\u7c7b\u5b9a\u4e49\u662f\u5982\u4e0b\u6240\u793a\uff0c\u90a3\u4e48 MyClass.i \u548c MyClass.f \u5c31\u662f\u6709\u6548\u7684\u5c5e\u6027\u5f15\u7528\uff0c\u5c06\u5206\u522b\u8fd4\u56de\u4e00\u4e2a\u6574\u6570\u548c\u4e00\u4e2a\u51fd\u6570\u5bf9\u8c61\u3002 \u7c7b\u5c5e\u6027\u4e5f\u53ef\u4ee5\u88ab\u8d4b\u503c\uff0c\u56e0\u6b64\u53ef\u4ee5\u901a\u8fc7\u8d4b\u503c\u6765\u66f4\u6539 MyClass.i \u7684\u503c\u3002 __doc__ \u4e5f\u662f\u4e00\u4e2a\u6709\u6548\u7684\u5c5e\u6027\uff0c\u5c06\u8fd4\u56de\u6240\u5c5e\u7c7b\u7684\u6587\u6863\u5b57\u7b26\u4e32: \"A simple example class\"\u3002 class MyClass : \"\"\"A simple example class\"\"\" i = 12345 def f ( self ): return 'hello world' print ( MyClass . i ) # 12345 print ( MyClass . __doc__ ) # A simple example class MyClass . i = 10 print ( MyClass . i ) # 10 \u7c7b\u7684**\u5b9e\u4f8b\u5316\uff08instantiation\uff09**\u4f7f\u7528\u51fd\u6570\u8868\u793a\u6cd5\u3002 \u53ef\u4ee5\u628a\u7c7b\u5bf9\u8c61\uff08class object\uff09\u770b\u4f5c\u662f\u4e00\u4e2a\u4e0d\u5e26\u53c2\u6570\u7684\u51fd\u6570\uff0c\u8fd9\u4e2a\u51fd\u6570\u8fd4\u56de\u4e86\u8be5\u7c7b\u7684\u4e00\u4e2a\u65b0\u5b9e\u4f8b\u3002 \u5728\u4e0b\u9762\u7684\u4f8b\u5b50\u4e2d\uff0c x = MyClass() \u521b\u5efa\u4e86 MyClass() \u8fd9\u4e2a\u7c7b\u7684\u4e00\u4e2a\u5b9e\u4f8b\uff0c\u5e76\u8d4b\u503c\u7ed9\u5c40\u90e8\u53d8\u91cf x \u3002 \u5b9e\u4f8b\u5316\u64cd\u4f5c\uff08\u8c03\u7528\u7c7b\u5bf9\u8c61\uff09\u4f1a\u521b\u5efa\u4e00\u4e2a\u7a7a\u5bf9\u8c61\u3002\u8bb8\u591a\u7c7b\u4f1a\u521b\u5efa\u5e26\u6709\u7279\u5b9a\u521d\u59cb\u72b6\u6001\u7684\u81ea\u5b9a\u4e49\u5b9e\u4f8b\u3002\u4e3a\u6b64\u7c7b\u5b9a\u4e49\u4e2d\u9700\u8981\u5305\u542b\u4e00\u4e2a\u540d\u4e3a __init__() \u7684\u7279\u6b8a\u65b9\u6cd5\u3002 \u5f53\u4e00\u4e2a\u7c7b\u5b9a\u4e49\u4e86 __init__() \u65b9\u6cd5\u65f6\uff0c\u7c7b\u7684\u5b9e\u4f8b\u5316\u64cd\u4f5c\u4f1a\u81ea\u52a8\u4e3a\u65b0\u521b\u5efa\u7684\u7c7b\u5b9e\u4f8b\u8c03\u7528 __init__() \u3002 \u66f4\u65b0\u4e0a\u9762\u7684\u4f8b\u5b50\uff0c\u6ce8\u610f __dict__ \u4e24\u6b21\u8fd4\u56de\u7684\u4e0d\u540c\u7684\u5b57\u5178\u3002\u590d\u4e60\u4e00\u4e0b\uff0c\u5728\u547d\u540d\u7a7a\u95f4\u4e2d\u63d0\u5230\uff0c __dict__ \u662f\u5c5e\u6027\u4f46\u4e0d\u662f\u5168\u5c40\u540d\u79f0\uff0c\u8fd4\u56de\u7528\u4e8e\u5b9e\u73b0\u6a21\u5757\u547d\u540d\u7a7a\u95f4\u7684\u5b57\u5178\u3002 class MyClass : \"\"\"A simple example class\"\"\" i = 12345 def f ( self ): return 'hello world' def __init__ ( self ): self . data = [] x = MyClass () print ( x . __dict__ ) # {'data': []} x . i = 10 print ( x . __dict__ ) # {'data': [], 'i': 10} __init__() \u65b9\u6cd5\u53ef\u4ee5\u6709\u989d\u5916\u7684\u53c2\u6570\u8f93\u5165\uff0c\u5728\u8fd9\u79cd\u60c5\u51b5\u4e0b\uff0c\u7c7b\u5b9e\u4f8b\u5316\u7684\u53c2\u6570\u5c06\u88ab\u4f20\u9012\u7ed9 __init__() \u3002 \u5982\u4e0b\u4f8b: class Complex : def __init__ ( self , realpart , imagpart ): self . r = realpart self . i = imagpart x = Complex ( 3.0 , - 4.5 ) print ( x . r , x . i ) # 3.0 -4.5","title":"\u7c7b\u5bf9\u8c61 Class Objects"},{"location":"python/Foundation/ch04/#instance-objects","text":"\u5bf9\u5b9e\u4f8b\u5bf9\u8c61\u552f\u4e00\u7684\u64cd\u4f5c\u662f\u5c5e\u6027\u5f15\u7528\u3002\u6709\u4e24\u79cd\u6709\u6548\u7684\u5c5e\u6027\u540d\u79f0\uff1a\u6570\u636e\u5c5e\u6027\uff08data attributes\uff09\u548c\u65b9\u6cd5\uff08methods\uff09\u3002 **\u6570\u636e\u5c5e\u6027\uff08data attributes\uff09**\u7c7b\u4f3c\u4e8e\u5b9e\u4f8b\u53d8\u91cf\uff0c\u6570\u636e\u5c5e\u6027\u4e0d\u9700\u8981\u58f0\u660e\u3002\u50cf\u5c40\u90e8\u53d8\u91cf\u4e00\u6837\uff0c\u6570\u636e\u5c5e\u6027\u5c06\u5728\u7b2c\u4e00\u6b21\u88ab\u8d4b\u503c\u65f6\u4ea7\u751f\u3002 \u4f8b\u5982\uff0c\u5982\u679c x \u662f\u4e0a\u9762\u521b\u5efa\u7684 MyClass \u7684\u5b9e\u4f8b\uff0c\u5219\u4ee5\u4e0b\u4ee3\u7801\u6bb5\u5c06\u6253\u5370\u6570\u503c 16 \uff0c\u4e14\u6ca1\u6709\u7559\u4e0b\u5173\u4e8e x.counter \u7684\u75d5\u8ff9\u3002 class MyClass : \"\"\"A simple example class\"\"\" i = 12345 def f ( self ): return 'hello world' def __init__ ( self ): self . data = [] x = MyClass () x . counter = 1 while x . counter < 10 : x . counter = x . counter * 2 print ( x . counter ) # 16 print ( x . __dict__ ) # {'data': [], 'counter': 16} del x . counter print ( x . __dict__ ) # {'data': []} \u53e6\u4e00\u7c7b\u5b9e\u4f8b\u5c5e\u6027\u5f15\u7528\u79f0\u4e3a**\u65b9\u6cd5\uff08methods\uff09 \u3002 \u65b9\u6cd5\u662f\u96b6\u5c5e\u4e8e\u5bf9\u8c61\u7684**\u51fd\u6570 \u3002 \u5728Python\u4e2d\uff0c\u65b9\u6cd5\u8fd9\u4e2a\u672f\u8bed\u5e76\u4e0d\u662f\u7c7b\u5b9e\u4f8b\u6240\u7279\u6709\u7684\uff0c\u5176\u4ed6\u5bf9\u8c61\u4e5f\u53ef\u4ee5\u6709\u65b9\u6cd5\u3002 \u4f8b\u5982\uff0c\u5217\u8868\u5bf9\u8c61\uff08list objects\uff09\u5177\u6709append, insert, remove, sort\u7b49\u65b9\u6cd5\u3002 \u5728\u4ee5\u4e0b\u8ba8\u8bba\u4e2d\uff0c\u6211\u4eec\u4f7f\u7528\u65b9\u6cd5\u4e00\u8bcd\u5c06\u4e13\u6307\u7c7b\u5b9e\u4f8b\u5bf9\u8c61\u7684\u65b9\u6cd5\uff0c\u9664\u975e\u53e6\u5916\u660e\u786e\u8bf4\u660e\u3002 \u5b9e\u4f8b\u5bf9\u8c61\u7684\u6709\u6548\u65b9\u6cd5\u540d\u79f0\u4f9d\u8d56\u4e8e\u5176\u6240\u5c5e\u7684\u7c7b\u3002 \u6839\u636e\u5b9a\u4e49\uff0c\u4e00\u4e2a\u7c7b\u5b9a\u4e49\u4e2d\u6240\u5305\u542b\u7684\u6240\u6709\u51fd\u6570\u5bf9\u8c61\uff08function objects\uff09\u90fd\u79f0\u4e3a\u5c5e\u6027\u3002 \u56e0\u6b64\u5728\u4e0a\u9762\u7684\u793a\u4f8b\u4e2d\uff0c x.f \u662f\u6709\u6548\u7684\u65b9\u6cd5\u5f15\u7528\uff0c\u56e0\u4e3a MyClass.f \u662f\u4e00\u4e2a\u51fd\u6570\uff0c\u800c x.i \u4e0d\u662f\u65b9\u6cd5\uff0c\u56e0\u4e3a MyClass.i \u4e0d\u662f\u51fd\u6570\u3002\u4f46\u662f x.f \u4e0e MyClass.f \u5e76\u4e0d\u662f\u4e00\u56de\u4e8b\uff0c x.f \u662f\u4e00\u4e2a**\u65b9\u6cd5\u5bf9\u8c61**\uff0c\u800c MyClass.f \u662f\u4e00\u4e2a**\u51fd\u6570\u5bf9\u8c61**\u3002\u5dee\u522b\u5728\u4e8e f() \u662f\u5426\u4e0e\u5b9e\u4f8b\u7ed1\u5b9a\uff0c\u672a\u7ed1\u5b9a\uff0c\u5c31\u662f\u51fd\u6570\uff0c\u7ed1\u5b9a\uff0c\u5c31\u662f\u65b9\u6cd5\u3002 class MyClass : \"\"\"A simple example class\"\"\" i = 12345 def f ( self ): return 'hello world' def __init__ ( self ): self . data = [] x = MyClass () print ( MyClass . f ( 0 )) # hello world print ( x . f ()) # hello world print ( MyClass . f ) # print ( x . f ) # > print ( type ( MyClass . f )) # print ( type ( x . f )) # \u8fd9\u91cc\u505a\u4e2a\u5c0f\u7ed3\uff1a \u51fd\u6570(function)\u662fPython\u4e2d\u4e00\u4e2a\u53ef\u8c03\u7528\u5bf9\u8c61(callable), \u65b9\u6cd5(method)\u662f\u4e00\u79cd\u7279\u6b8a\u7684\u51fd\u6570\u3002 \u4e00\u4e2a\u53ef\u8c03\u7528\u5bf9\u8c61\u662f\u65b9\u6cd5\u548c\u51fd\u6570\uff0c\u548c\u8fd9\u4e2a\u5bf9\u8c61\u65e0\u5173\uff0c\u4ec5\u548c\u8fd9\u4e2a\u5bf9\u8c61\u662f\u5426\u4e0e\u7c7b\u6216\u5b9e\u4f8b\u7ed1\u5b9a\u6709\u5173\uff08bound method\uff09\u3002 \u9759\u6001\u65b9\u6cd5\u6ca1\u6709\u548c\u4efb\u4f55\u7c7b\u6216\u5b9e\u4f8b\u7ed1\u5b9a\uff0c\u6240\u4ee5**\u9759\u6001\u65b9\u6cd5\u662f\u4e2a\u51fd\u6570**\u3002","title":"\u5b9e\u4f8b\u5bf9\u8c61 Instance Objects"},{"location":"python/Foundation/ch04/#method-objects","text":"\u5728 MyClass \u793a\u4f8b\u4e2d\uff0c x.f() \u662f\u4e00\u4e2a\u65b9\u6cd5\u5bf9\u8c61\uff0c\u88ab\u8c03\u7528\u540e\uff0c\u5c06\u8fd4\u56de\u5b57\u7b26\u4e32 'hello world' \u3002\u53ef\u4ee5\u7acb\u5373\u8c03\u7528\uff0c\u4e5f\u53ef\u4ee5\u4fdd\u5b58\u8d77\u6765\u4ee5\u540e\u518d\u8c03\u7528 xf = x.f \u3002 \u867d\u7136 f() \u7684\u51fd\u6570\u5b9a\u4e49\u6307\u5b9a\u4e86\u4e00\u4e2a\u53c2\u6570\uff0c\u4f46\u4e0a\u9762\u4f8b\u5b50\u4e2d\u8c03\u7528 x.f() \u65f6\u5e76\u6ca1\u6709\u5e26\u53c2\u6570\uff0c\u4e5f\u6ca1\u6709\u5f15\u53d1\u5f02\u5e38\u62a5\u9519\u3002\u539f\u56e0\u5728\u4e8e\uff0c \u65b9\u6cd5(method)\u7684\u7279\u6b8a\u4e4b\u5904\u5c31\u5728\u4e8e\u5b9e\u4f8b\u5bf9\u8c61\u4f1a\u4f5c\u4e3a\u51fd\u6570\u7684\u7b2c\u4e00\u4e2a\u53c2\u6570\u88ab\u4f20\u5165\u3002 \u8c03\u7528 x.f() \u5176\u5b9e\u5c31\u76f8\u5f53\u4e8e MyClass.f(x) \u3002 \u603b\u4e4b\uff0c\u8c03\u7528\u4e00\u4e2a\u5177\u6709 n \u4e2a\u53c2\u6570\u7684\u65b9\u6cd5(method)\u5c31\u76f8\u5f53\u4e8e\u8c03\u7528\u518d\u591a\u4e00\u4e2a\u53c2\u6570\u7684\u5bf9\u5e94\u51fd\u6570\uff0c\u8fd9\u4e2a\u53c2\u6570\u503c\u4e3a\u65b9\u6cd5\u6240\u5c5e\u5b9e\u4f8b\u5bf9\u8c61\uff0c \u4f4d\u7f6e\u5728\u5176\u4ed6\u53c2\u6570\u4e4b\u524d \u3002 \u5f53\u4e00\u4e2a\u5b9e\u4f8b\u7684\u975e\u6570\u636e\u5c5e\u6027\u88ab\u5f15\u7528\u65f6\uff0c\u5c06\u641c\u7d22\u5b9e\u4f8b\u6240\u5c5e\u7684\u7c7b\u3002 \u5982\u679c\u88ab\u5f15\u7528\u7684\u5c5e\u6027\u540d\u79f0\u662f\u7c7b\u4e2d\u4e00\u4e2a\u6709\u6548\u7684\u51fd\u6570\u5bf9\u8c61\uff0c\u5219\u4f1a\u521b\u5efa\u4e00\u4e2a\u62bd\u8c61\u7684\u5bf9\u8c61\uff0c\u901a\u8fc7\u6253\u5305\uff08parking\uff0c\u5373\u6307\u5411\uff09\u5339\u914d\u5230\u7684\u5b9e\u4f8b\u5bf9\u8c61\u548c\u51fd\u6570\u5bf9\u8c61\uff0c\u8fd9\u4e2a\u62bd\u8c61\u5bf9\u8c61\u5c31\u662f\u65b9\u6cd5\u5bf9\u8c61\u3002 \u5f53\u5e26\u53c2\u6570\u8c03\u7528\u65b9\u6cd5\u5bf9\u8c61\u65f6\uff0c\u5c06\u57fa\u4e8e\u5b9e\u4f8b\u5bf9\u8c61\u548c\u53c2\u6570\u5217\u8868\u6784\u5efa\u4e00\u4e2a\u65b0\u7684\u53c2\u6570\u5217\u8868\uff0c\u5e76\u4f7f\u7528\u8fd9\u4e2a\u65b0\u53c2\u6570\u5217\u8868\u8c03\u7528\u76f8\u5e94\u7684\u51fd\u6570\u5bf9\u8c61\u3002","title":"\u65b9\u6cd5\u5bf9\u8c61 Method Objects"},{"location":"python/Foundation/ch04/#class-and-instance-variables","text":"\u4e00\u822c\u6765\u8bf4\uff0c**\u5b9e\u4f8b\u53d8\u91cf**\u7528\u4e8e\u6bcf\u4e2a\u5b9e\u4f8b\u7684\u552f\u4e00\u6570\u636e\uff0c\u800c**\u7c7b\u53d8\u91cf**\u7528\u4e8e\u7c7b\u7684\u6240\u6709\u5b9e\u4f8b\u5171\u4eab\u7684\u5c5e\u6027\u548c\u65b9\u6cd5: class Dog : kind = 'canine' # class variable shared by all instances def __init__ ( self , name ): self . name = name # instance variable unique to each instance d = Dog ( 'Fido' ) e = Dog ( 'Buddy' ) print ( d . kind ) # shared by all dogs # 'canine' print ( e . kind ) # shared by all dogs # 'canine' print ( d . name ) # unique to d instance # 'Fido' print ( e . name ) # unique to e instance # 'Buddy' \u4e0b\u4ee3\u7801\u4e2d\u7684 tricks \u5217\u8868\u4e0d\u5e94\u8be5\u88ab\u7528\u4f5c\u7c7b\u53d8\u91cf\uff0c\u56e0\u4e3a\u6240\u6709\u7684 Dog \u5b9e\u4f8b\u5c06\u53ea\u5171\u4eab\u4e00\u4e2a\u5355\u72ec\u7684\u5217\u8868: class Dog : kind = 'canine' # class variable shared by all instances tricks = [] # mistaken use of a class variable def __init__ ( self , name ): self . name = name # instance variable unique to each instance def add_trick ( self , trick ): self . tricks . append ( trick ) d = Dog ( 'Fido' ) e = Dog ( 'Buddy' ) d . add_trick ( 'roll over' ) e . add_trick ( 'play dead' ) print ( d . tricks ) # ['roll over', 'play dead'] \u6b63\u786e\u7684\u7c7b\u8bbe\u8ba1\u5e94\u8be5\u4f7f\u7528\u5b9e\u4f8b\u53d8\u91cf: class Dog : kind = 'canine' # class variable shared by all instances def __init__ ( self , name ): self . name = name # instance variable unique to each instance self . tricks = [] # creates a new empty list for each dog def add_trick ( self , trick ): self . tricks . append ( trick ) d = Dog ( 'Fido' ) e = Dog ( 'Buddy' ) d . add_trick ( 'roll over' ) e . add_trick ( 'play dead' ) print ( d . tricks ) # ['roll over'] print ( e . tricks ) # ['play dead'] \u5982\u679c\u540c\u6837\u7684\u5c5e\u6027\u540d\u79f0\u540c\u65f6\u51fa\u73b0\u5728\u5b9e\u4f8b\u548c\u7c7b\u4e2d\uff0c\u5219\u5c5e\u6027\u67e5\u627e\u4f1a**\u4f18\u5148\u9009\u62e9\u5b9e\u4f8b**: class Warehouse : purpose = 'storage' region = 'west' w1 = Warehouse () print ( w1 . purpose , w1 . region ) # storage west w2 = Warehouse () w2 . region = 'east' # Instance W2 has higher priority than class print ( w2 . purpose , w2 . region ) # storage east \u6570\u636e\u5c5e\u6027\uff08Data attributes\uff09\u53ef\u4ee5\u88ab\u65b9\u6cd5\uff08method\uff09\u4ee5\u53ca\u4e00\u4e2a\u5bf9\u8c61\u7684\u666e\u901a\u7528\u6237\uff08ordinary users\uff09\uff08\u201c\u5ba2\u6237\u7aefClient\u201d\uff09\u6240\u5f15\u7528\u3002 \u6362\u53e5\u8bdd\u8bf4\uff0c\u7c7b\u4e0d\u80fd\u7528\u4e8e\u5b9e\u73b0\u7eaf\u62bd\u8c61\u6570\u636e\u7c7b\u578b\u3002 \u65b9\u6cd5\u7684\u7b2c\u4e00\u4e2a\u53c2\u6570\u5e38\u5e38\u88ab\u547d\u540d\u4e3a self \uff0c\u8fd9\u53ea\u662f\u4e00\u4e2a\u7ea6\u5b9a: self \u8fd9\u4e00\u540d\u79f0\u5728Python\u4e2d\u6ca1\u6709\u7279\u6b8a\u542b\u4e49\u3002 \u4f46\u662f\u9075\u5faa\u6b64\u7ea6\u5b9a\u4f1a\u4f7f\u5f97\u4ee3\u7801\u5177\u6709\u5f88\u597d\u7684\u53ef\u8bfb\u6027\u3002 \u4efb\u4f55\u4e00\u4e2a\u4f5c\u4e3a\u7c7b\u5c5e\u6027\uff08class attribute\uff09\u7684\u51fd\u6570\u5bf9\u8c61\uff08function object\uff09\u90fd\u4e3a\u8be5\u7c7b\u7684\u5b9e\u4f8b\u5b9a\u4e49\u4e86\u4e00\u4e2a\u76f8\u5e94\u65b9\u6cd5\u3002 \u51fd\u6570\u5b9a\u4e49\u7684\u6587\u672c\u5e76\u975e\u5fc5\u987b\u5305\u542b\u4e8e\u7c7b\u5b9a\u4e49\u4e4b\u5185\uff1a\u5c06\u4e00\u4e2a\u51fd\u6570\u5bf9\u8c61\u8d4b\u503c\u7ed9\u4e00\u4e2a\u5c40\u90e8\u53d8\u91cf\u4e5f\u662f\u53ef\u4ee5\u7684\u3002\u5982\u4e0b\u4f8b\u3002\u73b0\u5728 f , g \u548c h \u90fd\u662f\u7c7b C \u7684\u5f15\u7528\u51fd\u6570\u5bf9\u8c61\u7684\u5c5e\u6027\uff0c\u56e0\u800c\u5b83\u4eec\u5c31\u90fd\u662f\u7c7b C \u7684\u5b9e\u4f8b\u7684\u65b9\u6cd5\uff0c\u5176\u4e2d h \u5b8c\u5168\u7b49\u540c\u4e8e g \u3002\u4f46\u8bf7\u6ce8\u610f\uff0c\u4e0b\u9762\u8fd9\u4e2a\u4f8b\u5b50\u7684\u53ef\u8bfb\u6027\u975e\u5e38\u4e0d\u597d\u3002 # Function defined outside the class def f1 ( self , x , y ): return min ( x , x + y ) class C : f = f1 # Assign a function object to a local variable in the class def g ( self ): return 'hello world' h = g \u65b9\u6cd5\uff08methods\uff09\u53ef\u4ee5\u901a\u8fc7\u4f7f\u7528 self \u53c2\u6570\u7684\u65b9\u6cd5\u5c5e\u6027\uff08method attributes\uff09\u8c03\u7528\u5176\u4ed6\u65b9\u6cd5\uff08method\uff09: class Bag : def __init__ ( self ): self . data = [] def add ( self , x ): self . data . append ( x ) def addtwice ( self , x ): self . add ( x ) self . add ( x ) \u65b9\u6cd5\u53ef\u4ee5\u901a\u8fc7\u4e0e\u666e\u901a\u51fd\u6570\u76f8\u540c\u7684\u65b9\u5f0f\u5f15\u7528\u5168\u5c40\u540d\u79f0\u3002 \u4e0e\u65b9\u6cd5\u76f8\u5173\u8054\u7684\u5168\u5c40\u4f5c\u7528\u57df\u5c31\u662f\u5305\u542b\u5176\u5b9a\u4e49\u7684\u6a21\u5757\u3002 \uff08\u7c7b\u6c38\u8fdc\u4e0d\u4f1a\u88ab\u4f5c\u4e3a\u5168\u5c40\u4f5c\u7528\u57df\u3002\uff09 \u867d\u7136\u6211\u4eec\u5f88\u5c11\u4f1a\u6709\u5145\u5206\u7684\u7406\u7531\u5728\u65b9\u6cd5\u4e2d\u4f7f\u7528\u5168\u5c40\u4f5c\u7528\u57df\uff0c\u4f46\u5168\u5c40\u4f5c\u7528\u57df\u5b58\u5728\u8bb8\u591a\u5408\u7406\u7684\u4f7f\u7528\u573a\u666f\uff1a\u4e3e\u4e2a\u4f8b\u5b50\uff0c\u5bfc\u5165\u5230\u5168\u5c40\u4f5c\u7528\u57df\u7684\u51fd\u6570\u548c\u6a21\u5757\u53ef\u4ee5\u88ab\u65b9\u6cd5\u6240\u4f7f\u7528\uff0c\u5728\u5176\u4e2d\u5b9a\u4e49\u7684\u51fd\u6570\u548c\u7c7b\u4e5f\u4e00\u6837\u3002 \u901a\u5e38\uff0c\u5305\u542b\u8be5\u65b9\u6cd5\u7684\u7c7b\u672c\u8eab\u662f\u5728\u5168\u5c40\u4f5c\u7528\u57df\u4e2d\u5b9a\u4e49\u7684\u3002","title":"\u7c7b\u548c\u5b9e\u4f8b\u53d8\u91cf Class and Instance Variables"},{"location":"python/Foundation/ch04/#_1","text":"","title":"\u603b\u7ed3"},{"location":"python/Foundation/ch04/#_2","text":"\u4e00\u4e2a\u7c7b\u5b9a\u4e49\u7c7b\u6210\u5458\u5c5e\u6027\u548c\u6210\u5458\u65b9\u6cd5\u3002 \u4e00\u4e2a\u7c7b\u53ef\u4ee5\u5b9e\u4f8b\u5316\u591a\u4e2a\u5bf9\u8c61\uff0c\u6bcf\u4e2a\u5b9e\u4f8b\u5316\u5bf9\u8c61\u90fd\u662f\u72ec\u7acb\u7684\u3002 \u521b\u5efa\u7684\u7c7b\u5b9e\u4f8b\u5316\u5bf9\u8c61\uff0c\u4f1a\u5f15\u7528\u7236\u7c7b\u4e2d\u7684\u5c5e\u6027\u548c\u65b9\u6cd5\uff0c\u5e76\u4e0d\u4f1a\u628a\u7c7b\u7684\u5c5e\u6027\u548c\u65b9\u6cd5\u590d\u5236\u7ed9\u5bf9\u8c61\uff0c\u56e0\u6b64\uff1a \u5728\u8bbf\u95ee\u5b9e\u4f8b\u5316\u5bf9\u8c61\u7684\u5c5e\u6027\u548c\u65b9\u6cd5\u65f6\uff0c\u4f1a\u5148\u53bb\u627e\u5bf9\u8c61\u81ea\u5df1\u7684\u5c5e\u6027\u548c\u65b9\u6cd5\uff0c\u7136\u540e\u518d\u53bb\u5b9e\u4f8b\u5316\u8fd9\u4e2a\u5bf9\u8c61\u7684\u7c7b\u4e2d\u67e5\u627e\uff08\u5f15\u7528\uff09\u3002 \u5bf9\u8c61\u6210\u5458\u7684\u6dfb\u52a0\u548c\u4fee\u6539\uff0c\u90fd\u53ea\u4f1a\u5f71\u54cd\u5f53\u524d\u5bf9\u8c61\u81ea\u5df1\uff0c\u4e0d\u4f1a\u5f71\u54cd\u7c7b\u548c\u5176\u5b83\u5bf9\u8c61\u3002 \u5220\u9664\u5bf9\u8c61\u6210\u5458\u7684\u65f6\u5019\uff0c\u5fc5\u987b\u662f\u8be5\u5bf9\u8c61\u81ea\u5df1\u5177\u5907\u7684\u6210\u5458\u624d\u53ef\u4ee5\uff0c\u4e0d\u80fd\u5220\u9664\u7c7b\u4e2d\u5f15\u7528\u7684\u6210\u5458\u3002 \u5bf9\u7c7b\u6210\u5458\u7684\u64cd\u4f5c\uff0c\u4f1a\u5f71\u54cd\u8fd9\u4e2a\u7c7b\u521b\u5efa\u7684\u5bf9\u8c61\uff0c\u5305\u62ec\u4e4b\u524d\u521b\u5efa\u7684\u5bf9\u8c61\uff08\u5f15\u7528\uff09\u3002","title":"\u7c7b\u5b9a\u4e49\u5c0f\u7ed3"},{"location":"python/Foundation/ch04/#_3","text":"\u6210\u5458\u5c5e\u6027\uff1a \u8bbf\u95ee\uff1a ClassName.AttributeName \u4fee\u6539\uff1a ClassName.AttributeName = NewValue \uff0c\u7b49\u4e8e\u7ed9\u8fd9\u4e2a\u7c7b\u5bf9\u8c61\u521b\u5efa\u4e86\u4e00\u4e2a\u81ea\u5df1\u7684\u5c5e\u6027\uff0c\u901a\u8fc7\u8fd9\u4e2a\u7c7b\u521b\u5efa\u7684\u5bf9\u8c61\u90fd\u5177\u6709\u8fd9\u4e2a\u5c5e\u6027\u3002 \u6dfb\u52a0\uff1a ClassName.NewAttributeName = Value \uff0c\u7b49\u4e8e\u7ed9\u8fd9\u4e2a\u7c7b\u5bf9\u8c61\u521b\u5efa\u4e86\u4e00\u4e2a\u81ea\u5df1\u7684\u5c5e\u6027\uff0c\u901a\u8fc7\u8fd9\u4e2a\u7c7b\u521b\u5efa\u7684\u5bf9\u8c61\u90fd\u5177\u6709\u8fd9\u4e2a\u5c5e\u6027\u3002 \u5220\u9664\uff1a del ClassName.AttributeName \uff0c\u6ce8\u610f\uff0c\u53ea\u80fd\u5220\u9664\u7c7b\u5bf9\u8c61\u81ea\u5df1\u7684\u5c5e\u6027\uff0c\u901a\u8fc7\u8fd9\u4e2a\u7c7b\u521b\u5efa\u7684\u5bf9\u8c61\u90fd\u4e0d\u518d\u5177\u6709\u8fd9\u4e2a\u5c5e\u6027\u3002 \u6210\u5458\u65b9\u6cd5\uff1a \u8bbf\u95ee\uff1a ClassName.MethodName() \u4fee\u6539\uff1a ClassName.MethodName = NewFunction \uff0c\u7b49\u4e8e\u7ed9\u8fd9\u4e2a\u7c7b\u5bf9\u8c61\u521b\u5efa\u4e86\u4e00\u4e2a\u81ea\u5df1\u7684\u65b9\u6cd5\uff0c\u901a\u8fc7\u8fd9\u4e2a\u7c7b\u521b\u5efa\u7684\u5bf9\u8c61\u90fd\u5177\u6709\u8fd9\u4e2a\u65b9\u6cd5\u3002 \u6dfb\u52a0\uff1a ClassName.MethodName = Function \uff0c\u7b49\u4e8e\u7ed9\u8fd9\u4e2a\u7c7b\u5bf9\u8c61\u521b\u5efa\u4e86\u4e00\u4e2a\u81ea\u5df1\u7684\u65b9\u6cd5\uff0c\u901a\u8fc7\u8fd9\u4e2a\u7c7b\u521b\u5efa\u7684\u5bf9\u8c61\u90fd\u5177\u6709\u8fd9\u4e2a\u65b9\u6cd5\u3002 \u5220\u9664\uff1a del ClassName.MethodName \uff0c\u6ce8\u610f\uff0c\u53ea\u80fd\u5220\u9664\u7c7b\u5bf9\u8c61\u81ea\u5df1\u7684\u65b9\u6cd5\uff0c\u901a\u8fc7\u8fd9\u4e2a\u7c7b\u521b\u5efa\u7684\u5bf9\u8c61\u90fd\u4e0d\u518d\u5177\u6709\u8fd9\u4e2a\u65b9\u6cd5\u3002","title":"\u7c7b\u6210\u5458\u64cd\u4f5c\uff08\u4e0d\u63a8\u8350\uff09"},{"location":"python/Foundation/ch04/#self","text":"self \u53ea\u662f\u4e00\u4e2a\u5f62\u53c2\uff0c\u4e0d\u662f\u5173\u952e\u5b57\u3002 self \u5728\u65b9\u6cd5\uff08method\uff09\u4ee3\u8868\u5f53\u524d\u5bf9\u8c61\u81ea\u5df1\u3002\u524d\u9762\u63d0\u5230\u8fc7\uff0c\u65b9\u6cd5\u7684\u7b2c\u4e00\u4e2a\u53c2\u6570\u5e38\u5e38\u88ab\u547d\u540d\u4e3a self \uff0c\u8fd9\u53ea\u662f\u4e00\u4e2a\u7ea6\u5b9a\u3002 \u53ef\u4ee5\u4f7f\u7528 self \u5728\u7c7b\u5185\u90e8\u64cd\u4f5c\u6210\u5458\uff08\u6dfb\u52a0\u3001\u4fee\u6539\u3001\u5220\u9664\u7b49\uff09\u3002 \u65b9\u6cd5\u7684\u5206\u7c7b\uff1a \u542b\u6709self\u6216\u8005\u53ef\u4ee5\u63a5\u53d7\u5bf9\u8c61\u4f5c\u4e3a\u53c2\u6570\u7684\u65b9\u6cd5\uff0c\u79f0\u4e3a**\u975e\u7ed1\u5b9a\u7c7b\u65b9\u6cd5**\uff0c\u975e\u7ed1\u5b9a\u7c7b\u7684\u65b9\u6cd5\u53ef\u4ee5\u4f7f\u7528\u5bf9\u8c61\u53bb\u8bbf\u95ee\u3002 \u4e0d\u542b\u6709self\u6216\u8005\u4e0d\u80fd\u63a5\u53d7\u5bf9\u8c61\u4f5c\u4e3a\u53c2\u6570\u7684\u65b9\u6cd5\uff0c\u79f0\u4e3a**\u7ed1\u5b9a\u7c7b\u65b9\u6cd5**\uff0c\u7ed1\u5b9a\u65b9\u6cd5\u53ea\u80fd\u4f7f\u7528\u7c7b\u53bb\u8bbf\u95ee\u3002","title":"\u6210\u5458\u65b9\u6cd5\u4e2d\u7684self"},{"location":"python/Foundation/ch04/#_4","text":"\u9b54\u672f\u65b9\u6cd5\uff08Magic Method\uff09\u548c\u666e\u901a\u65b9\u6cd5\u4e00\u6837\uff0c\u90fd\u662f\u7c7b\u4e2d\u5b9a\u4e49\u7684\u6210\u5458\u65b9\u6cd5\u3002 \u9b54\u672f\u65b9\u6cd5\u540d\u79f0\u524d\u540e\u5404\u67092\u4e2a\u4e0b\u5212\u7ebf\uff0c\u6bd4\u5982 __init__ \u9b54\u672f\u65b9\u6cd5\u662f\u4e0d\u9700\u8981\u624b\u52a8\u8c03\u7528\u7684\uff0c\u4f1a\u5728\u67d0\u79cd\u60c5\u51b5\u4e0b\u81ea\u52a8\u89e6\u53d1\uff08\u81ea\u52a8\u6267\u884c\uff09\u3002 \u9b54\u672f\u65b9\u6cd5\u662f\u7cfb\u7edf\u5b9a\u4e49\u597d\u7684\uff0c\u4e0d\u662f\u7528\u6237\u5b9a\u4e49\u7684\u3002","title":"\u9b54\u672f\u65b9\u6cd5"},{"location":"python/Foundation/ch04/#__init__","text":"\u7c7b\u5b9e\u4f8b\u5316\u5bf9\u8c61\u521b\u5efa\u540e\u81ea\u52a8\u89e6\u53d1\u3002 __init__ \u521d\u59cb\u5316\u65b9\u6cd5\u53ef\u4ee5\u7528\u6765\u5728\u5bf9\u8c61\u5b9e\u4f8b\u5316\u540e\u5b8c\u6210\u5bf9\u8c61\u7684\u521d\u59cb\u5316\uff0c\u6bd4\u5982\u5c5e\u6027\u8d4b\u503c\uff0c\u65b9\u6cd5\u8c03\u7528\u7b49\u3002","title":"__init__\u521d\u59cb\u5316\u65b9\u6cd5\uff0c\u4e5f\u79f0\u4f5c**\u6784\u9020\u65b9\u6cd5**"},{"location":"python/Foundation/ch04/#__del__","text":"\u7c7b\u5b9e\u4f8b\u5316\u5bf9\u8c61\u88ab\u9500\u6bc1\u65f6\u81ea\u52a8\u89e6\u53d1\u3002 __del__ \u6790\u6784\u65b9\u6cd5\u53ef\u4ee5\u5728\u9500\u6bc1\u5bf9\u8c61\u65f6\u5b8c\u6210\u4e00\u4e9b\u7279\u6b8a\u4efb\u52a1\uff0c\u5173\u95ed\u5bf9\u8c61\u6253\u5f00\u7684\u4e00\u4e9b\u8d44\u6e90\uff0c\u5982\u6587\u4ef6\u7b49\u3002 \u6ce8\u610f\uff0c\u662f\u5bf9\u8c61\u88ab\u9500\u6bc1\u65f6\u89e6\u53d1\u4e86\u6790\u6784\u65b9\u6cd5\uff0c\u800c\u4e0d\u662f\u8fd9\u4e2a\u6790\u6784\u65b9\u6cd5\u9500\u6bc1\u4e86\u5bf9\u8c61\u3002 \u5bf9\u8c61\u9500\u6bc1\u7684\u60c5\u51b5\uff1a \u5f53\u7a0b\u5e8f\u6267\u884c\u5b8c\u6bd5\uff0c\u9500\u6bc1\u548c\u91ca\u653e\u5185\u5b58\u4e2d\u7684\u8d44\u6e90\u3002 \u4f7f\u7528 del \u5220\u9664\u65f6\u3002 \u5bf9\u8c61\u4e0d\u518d\u88ab\u4efb\u4f55\u5bf9\u8c61\u5f15\u7528\u65f6\uff0c\u4f1a\u81ea\u52a8\u9500\u6bc1\u3002 \u770b\u4e0b\u9762\u7684\u4f8b\u5b50\uff0c\u5bf9\u6bd4 bmw = Car('BMW') \u548c Car('BMW') \u6765\u7406\u89e3 init \u548c del \u7684\u89e6\u53d1\u673a\u5236\u3002 \u7f16\u8f91\u6587\u4ef6 file1.py class Car (): brand = \"\" def __init__ ( self , car_brand ): self . brand = car_brand print ( f \"initial method called, create { self . brand } car\" ) def __del__ ( self ): print ( f \"delete method called, destroy { self . brand } car\" ) bmw = Car ( 'BMW' ) vw = Car ( 'VW' ) \u6267\u884c\u4e0a\u9762\u7684\u4ee3\u7801 python3 file1.py \u5f97\u5230\u5982\u4e0b\u8f93\u51fa\uff0c\u5728\u7a0b\u5e8f\u6267\u884c\u5b8c\u6bd5\u65f6\uff0c\u4f9d\u6b21\u6267\u884c __del__ \u3002 initial method called , create BMW car initial method called , create VW car delete method called , destroy BMW car delete method called , destroy VW car \u7f16\u8f91\u6587\u4ef6 file2.py class Car (): brand = \"\" def __init__ ( self , car_brand ): self . brand = car_brand print ( f \"initial method called, create { self . brand } car\" ) def __del__ ( self ): print ( f \"delete method called, destroy { self . brand } car\" ) Car ( 'BMW' ) Car ( 'VW' ) \u6267\u884c\u4e0a\u9762\u7684\u4ee3\u7801 python3 file2.py \u5f97\u5230\u5982\u4e0b\u8f93\u51fa\uff1a initial method called , create BMW car delete method called , destroy BMW car initial method called , create VW car delete method called , destroy VW car","title":"__del__\u6790\u6784\u65b9\u6cd5"},{"location":"python/Foundation/ch04/#python_1","text":"\u4ece\u9b54\u672f\u65b9\u6cd5\u53ef\u4ee5\u5ef6\u7533\u5230Python\u7684**\u51fd\u6570\u5185\u7701**\uff0c\u51fd\u6570\u5185\u7701\u7684\u610f\u601d\u662f\u8bf4\uff0c\u5f53\u4f60\u62ff\u5230\u4e00\u4e2a\u201c\u51fd\u6570\u5bf9\u8c61\u201d\u7684\u65f6\u5019\uff0c\u4f60\u53ef\u4ee5\u7ee7\u7eed\u77e5\u9053\uff0c\u5b83\u7684\u540d\u5b57\uff0c\u53c2\u6570\u5b9a\u4e49\u7b49\u4fe1\u606f\u3002\u8fd9\u4e9b\u4fe1\u606f\u53ef\u4ee5\u901a\u8fc7\u51fd\u6570\u5bf9\u8c61\u7684\u5c5e\u6027\uff08\u4e00\u4e9b\u53cc\u4e0b\u5212\u7ebf\u7684\u9b54\u6cd5\u65b9\u6cd5\uff09\u5f97\u5230\u3002\u7b80\u8a00\u4e4b\uff0c\u5185\u7701\u662f\u5728\u8fd0\u884c\u65f6\u786e\u5b9a\u5bf9\u8c61\u7c7b\u578b\u7684\u80fd\u529b\u3002 \u4e0b\u9762\u7684\u4f8b\u5b50\u5217\u51fa\u4e86\u5e38\u89c4\u5bf9\u8c61\u6ca1\u6709\u800c\u51fd\u6570\u6709\u7684\u5c5e\u6027\u3002 class C : pass obj = C () def func (): pass sorted ( set ( dir ( obj )) - set ( dir ( func ))) # ['__weakref__'] sorted ( set ( dir ( func )) - set ( dir ( obj ))) # ['__annotations__', '__call__', '__closure__', '__code__', '__defaults__', '__get__', '__globals__', '__kwdefaults__', '__name__', '__qualname__'] \u4e0b\u8868\u603b\u7ed3\u4e86\u7528\u6237\u5b9a\u4e49\u7684\u51fd\u6570\u7684\u5c5e\u6027\u3002 \u4e0b\u9762\u7684\u4f8b\u5b50\u662f\u6f14\u793a\u4e86\u5728\u6307\u5b9a\u957f\u5ea6\u9644\u8fd1\u622a\u65ad\u5b57\u7b26\u4e32\u7684\u51fd\u6570\uff0c\u4ee5\u53ca\u63d0\u53d6\u5173\u4e8e\u51fd\u6570\u53c2\u6570\u7684\u4fe1\u606f\u7684\u65b9\u6cd5\u3002 \u53c2\u6570\u540d\u79f0\u5728 __code__.co_varnames \u4e2d\uff0c\u4f46\u8fd9\u91cc\u9762\u4e5f\u5305\u542b\u51fd\u6570\u5b9a\u4e49\u4f53\u4e2d\u521b\u5efa\u7684\u5c40\u90e8\u53d8\u91cf\u3002\u56e0\u6b64\uff0c\u53c2\u6570\u540d\u79f0\u662f\u524d N \u4e2a\u5b57\u7b26\u4e32\uff0c N \u7684\u503c\u7531 __code__.co_argcount \u786e\u5b9a\uff0c\u4f8b\u5b50\u91cc\u9762N\u662f2\uff0c\u5373\u53c2\u6570\u540d\u79f0\u662f text \u548c max_len \uff0c\u5c40\u90e8\u53d8\u91cf\u662f end \u3001 space_before \u3001 space_after \u3002 def clip ( text , max_len = 80 ): \"\"\" Get sub-string by the first blank before or after specified position. rfind() \u8fd4\u56de\u5b57\u7b26\u4e32\u6700\u540e\u4e00\u6b21\u51fa\u73b0\u7684\u4f4d\u7f6e\uff0c\u5982\u679c\u6ca1\u6709\u5339\u914d\u9879\u5219\u8fd4\u56de -1. \"\"\" end = None if len ( text ) > max_len : space_before = text . rfind ( ' ' , 0 , max_len ) if space_before >= 0 : end = space_before else : space_after = text . rfind ( ' ' , max_len ) if space_after >= 0 : end = space_after if end is None : end = len ( text ) return text [: end ] . rstrip () clip ( 'This is the string' , max_len = 10 ) # 'This is' clip . __defaults__ # (80,) clip . __code__ # \", line 1> clip . __code__ . co_varnames # ('text', 'max_len', 'end', 'space_before', 'space_after') clip . __code__ . co_argcount # 2 clip . __doc__ # '\\n Get sub-string by the first blank before or after specified position.\\n rfind() \u8fd4\u56de\u5b57\u7b26\u4e32\u6700\u540e\u4e00\u6b21\u51fa\u73b0\u7684\u4f4d\u7f6e\uff0c\u5982\u679c\u6ca1\u6709\u5339\u914d\u9879\u5219\u8fd4\u56de -1.\\n ' \u4e0a\u4f8b\u4e2d\uff0c\u53c2\u6570\u7684\u9ed8\u8ba4\u503c\u53ea\u80fd\u901a\u8fc7\u5b83\u4eec\u5728 __defaults__ \u5143\u7ec4\u4e2d\u7684\u4f4d\u7f6e\u786e\u5b9a\uff0c\u56e0\u6b64\u8981\u4ece\u540e\u5411\u524d\u626b\u63cf\u624d\u80fd\u628a\u53c2\u6570\u548c\u9ed8\u8ba4\u503c\u5bf9\u5e94\u8d77\u6765\uff0c\u6709\u4e9b\u4e0d\u5408\u7406\u3002\u5f15\u5165 inspect \u6a21\u5757\u540e\uff0c\u4e0a\u9762\u7684\u64cd\u4f5c\u5c31\u66f4\u5bb9\u6613\u4e86\u3002 inspect.signature \u51fd\u6570\u8fd4\u56de\u4e00\u4e2a inspect.Signature \u5bf9\u8c61\uff0c\u5b83\u6709\u4e00\u4e2a parameters \u5c5e\u6027\uff0c\u8fd9\u662f\u4e00\u4e2a\u6709\u5e8f\u6620\u5c04\uff0c\u628a\u53c2\u6570\u540d\u548c inspect.Parameter \u5bf9\u8c61\u5bf9\u5e94\u8d77\u6765\u3002\u5404\u4e2a Parameter \u5c5e\u6027\u4e5f\u6709\u81ea\u5df1\u7684\u5c5e\u6027\uff0c\u4f8b\u5982 name \u3001 default \u548c kind \u3002 from inspect import signature sig = signature ( clip ) type ( sig ) # print ( sig ) # (text, max_len=80) print ( str ( sig )) # (text, max_len=80) for name , param in sig . parameters . items (): print ( f ' { param . kind } : { name } = { param . default } ' ) # 1 : text = # 1 : max_len = 80 \u51fd\u6570\u6ce8\u89e3\u3002 Python 3 \u63d0\u4f9b\u4e86\u4e00\u79cd\u53e5\u6cd5\uff0c\u7528\u4e8e\u4e3a\u51fd\u6570\u58f0\u660e\u4e2d\u7684\u53c2\u6570\u548c\u8fd4\u56de\u503c\u9644\u52a0\u5143\u6570\u636e\u3002\u5bf9\u4e0a\u4f8b\u6dfb\u52a0\u6ce8\u89e3\u540e\u5982\u4e0b\u6240\u793a\uff0c\u4e8c\u8005\u552f\u4e00\u7684\u533a\u522b\u5728\u7b2c\u4e00\u884c\u3002 \u51fd\u6570\u58f0\u660e\u4e2d\u7684\u5404\u4e2a\u53c2\u6570\u53ef\u4ee5\u5728:\u4e4b\u540e\u589e\u52a0\u6ce8\u89e3\u8868\u8fbe\u5f0f\u3002 \u5982\u679c\u53c2\u6570\u6709\u9ed8\u8ba4\u503c\uff0c\u6ce8\u89e3\u653e\u5728\u53c2\u6570\u540d\u548c = \u53f7\u4e4b\u95f4\u3002 \u5982\u679c\u60f3\u6ce8\u89e3\u8fd4\u56de\u503c\uff0c\u5728)\u548c\u51fd\u6570\u58f0\u660e\u672b\u5c3e\u7684 : \u4e4b\u95f4\u6dfb\u52a0 -> \u548c\u4e00\u4e2a\u8868\u8fbe\u5f0f\u3002\u90a3\u4e2a\u8868\u8fbe\u5f0f\u53ef\u4ee5\u662f\u4efb\u4f55\u7c7b\u578b\u3002 \u6ce8\u89e3\u4e2d\u6700\u5e38\u7528\u7684\u7c7b\u578b\u662f\u7c7b\uff08\u5982 str \u6216 int \uff09\u548c\u5b57\u7b26\u4e32\uff08\u5982'int > 0'\uff09\u3002\u5728\u4e0b\u4f8b\u4e2d\uff0cmax_len\u53c2\u6570\u7684\u6ce8\u89e3\u7528\u7684\u662f\u5b57\u7b26\u4e32\u3002 \u6ce8\u89e3\u4e0d\u4f1a\u505a\u4efb\u4f55\u5904\u7406\uff0c\u53ea\u662f\u5b58\u50a8\u5728\u51fd\u6570\u7684 __annotations__ \u5c5e\u6027\uff08\u4e00\u4e2a\u5b57\u5178\uff09\u4e2d\u3002\u6362\u53e5\u8bdd\u8bf4\uff0c\u6ce8\u89e3\u5bf9Python\u89e3\u91ca\u5668\u6ca1\u6709\u4efb\u4f55\u610f\u4e49\u3002 \u6ce8\u89e3\u53ea\u662f\u5143\u6570\u636e \uff0c\u53ef\u4ee5\u4f9bIDE\u3001\u6846\u67b6\u548c\u88c5\u9970\u5668\u7b49\u5de5\u5177\u4f7f\u7528\u3002 return \u952e\u4fdd\u5b58\u7684\u662f\u8fd4\u56de\u503c\u6ce8\u89e3\uff0c\u5373\u4e0b\u4f8b\u4e2d\u51fd\u6570\u58f0\u660e\u91cc\u4ee5 -> \u6807\u8bb0\u7684\u90e8\u5206\u3002 def clip ( text : str , max_len : 'int > 0' = 80 ) -> str : \"\"\" Get sub-string by the first blank before or after specified position. rfind() \u8fd4\u56de\u5b57\u7b26\u4e32\u6700\u540e\u4e00\u6b21\u51fa\u73b0\u7684\u4f4d\u7f6e\uff0c\u5982\u679c\u6ca1\u6709\u5339\u914d\u9879\u5219\u8fd4\u56de -1. \"\"\" end = None if len ( text ) > max_len : space_before = text . rfind ( ' ' , 0 , max_len ) if space_before >= 0 : end = space_before else : space_after = text . rfind ( ' ' , max_len ) if space_after >= 0 : end = space_after if end is None : end = len ( text ) return text [: end ] . rstrip () clip ( 'This is the string' , max_len = 10 ) # 'This is' clip . __annotations__ # {'text': , 'max_len': 'int > 0', 'return': } signature \u51fd\u6570\u8fd4\u56de\u4e00\u4e2a Signature \u5bf9\u8c61\uff0c\u5b83\u6709\u4e00\u4e2a return_annotation \u5c5e\u6027\u548c\u4e00\u4e2a parameters \u5c5e\u6027\uff0c\u540e\u8005\u662f\u4e00\u4e2a\u5b57\u5178\uff0c\u628a\u53c2\u6570\u540d\u6620\u5c04\u5230 Parameter \u5bf9\u8c61\u4e0a\u3002\u6bcf\u4e2a Parameter \u5bf9\u8c61\u81ea\u5df1\u4e5f\u6709 annotation \u5c5e\u6027\u3002 from inspect import signature sig = signature ( clip ) print ( sig . return_annotation ) # for param in sig . parameters . values (): note = repr ( param . annotation ) . ljust ( 13 ) print ( f ' { note } : { param . name } = { param . default } ' ) # : text = # 'int > 0' : max_len = 80","title":"Python\u51fd\u6570\u5185\u7701\u5185\u7701"},{"location":"python/Foundation/ch05/","text":"Python\u9762\u5411\u5bf9\u8c61\u4e09\u5927\u7279\u6027 \u00b6 Python\u9762\u5411\u5bf9\u8c61\u4e09\u5927\u7279\u6027\uff1a \u5c01\u88c5 \u7ee7\u627f \u591a\u6001 \u5c01\u88c5 Encapsulation \u00b6 \u5c01\u88c5\u662f\u4f7f\u7528\u7279\u6b8a\u7684\u8bed\u6cd5\uff0c\u5bf9\u6210\u5458\u5c5e\u6027\u548c\u6210\u5458\u65b9\u6cd5\u8fdb\u884c\u5305\u88c5\uff0c\u9650\u5236\u4e00\u4e9b\u8bbf\u95ee\u548c\u64cd\u4f5c\uff0c\u8fbe\u5230\u4fdd\u62a4\u548c\u9690\u85cf\u7684\u76ee\u7684\u3002 \u5c01\u88c5\u673a\u5236\u4fdd\u8bc1\u4e86\u7c7b\u5185\u90e8\u6570\u636e\u7ed3\u6784\u7684\u5b8c\u6574\u6027\uff0c\u56e0\u4e3a\u4f7f\u7528\u7c7b\u7684\u7528\u6237\u65e0\u6cd5\u76f4\u63a5\u770b\u5230\u7c7b\u4e2d\u7684\u6570\u636e\u7ed3\u6784\uff0c\u53ea\u80fd\u4f7f\u7528\u7c7b\u5141\u8bb8\u516c\u5f00\u7684\u6570\u636e\uff0c\u5f88\u597d\u5730\u907f\u514d\u4e86\u5916\u90e8\u5bf9\u5185\u90e8\u6570\u636e\u7684\u5f71\u54cd\uff0c\u63d0\u9ad8\u4e86\u7a0b\u5e8f\u7684\u53ef\u7ef4\u62a4\u6027\u3002 \u5bf9\u4e00\u4e2a\u7c7b\u5b9e\u73b0\u826f\u597d\u7684\u5c01\u88c5\uff0c\u7528\u6237\u53ea\u80fd\u501f\u52a9\u66b4\u9732\u51fa\u6765\u7684\u7c7b\u65b9\u6cd5\u6765\u8bbf\u95ee\u6570\u636e\uff0c\u53ef\u4ee5\u5728\u8fd9\u4e9b\u66b4\u9732\u7684\u65b9\u6cd5\u4e2d\u52a0\u5165\u9002\u5f53\u7684\u63a7\u5236\u903b\u8f91\uff0c\u5373\u53ef\u63a7\u5236\u7528\u6237\u5bf9\u7c7b\u4e2d\u5c5e\u6027\u6216\u65b9\u6cd5\u7684\u64cd\u4f5c\u3002 \u5bf9\u7c7b\u8fdb\u884c\u826f\u597d\u7684\u5c01\u88c5\uff0c\u4e3b\u8981\u662f\u5185\u90e8\u4f7f\u7528\u5c01\u88c5\u7684\u6210\u5458\uff0c\u4e5f\u63d0\u9ad8\u4e86\u4ee3\u7801\u7684\u590d\u7528\u6027\u3002 \u7c7b\u6210\u5458\u5c01\u88c5\u7684\u7ea7\u522b\uff1a \u516c\u6709\u7684\uff08public\uff09 \u4fdd\u62a4\u7684\uff08protected\uff09\uff0c\u5728Python\u4e2d\u5e76\u6ca1\u6709\u5b9e\u73b0protected\u5c01\u88c5\uff0c\u5c5e\u4e8e\u5f00\u53d1\u8005\u7684\u7ea6\u5b9a\u4fd7\u6210\u3002 \u79c1\u6709\u7684\uff08private\uff09\uff0c\u5728Python\u4e2dprivate\u5c01\u88c5\u662f\u901a\u8fc7\u6539\u540d\u7b56\u7565\u6765\u5b9e\u73b0\u7684\uff0c\u5e76\u4e0d\u662f\u771f\u6b63\u7684\u79c1\u6709\u5316\u3002 \u8bbf\u95ee\u9650\u5236 \u5171\u6709\u7684public \u53d7\u4fdd\u62a4\u7684protected \u79c1\u6709\u7684private \u5728\u7c7b\u7684\u5185\u90e8 OK OK OK \u5728\u7c7b\u7684\u5916\u90e8 OK No (Python\u4e2d\u53ef\u4ee5) No \u770b\u4e0b\u9762\u7684\u4f8b\u5b50\u3002(\u53c2\u8003 \u79c1\u6709\u53d8\u91cfPrivate Variables ) name \u662f\u5171\u6709\u5c5e\u6027\uff0c\u53ef\u4ee5\u5728\u5916\u90e8\u8c03\u7528tom.name\u3002 _age \u662f\u53d7\u4fdd\u62a4\u7684\u5c5e\u6027\uff0c\u7406\u8bba\u4e0a\u5728\u5916\u90e8\u662f\u4e0d\u53ef\u8c03\u7528\u7684\uff0c\u4f46\u5728Python\u4e2d\u662f\u53ef\u4ee5\u8c03\u7528\u7684 tom._age \u3002 __phone \u662f\u79c1\u6709\u5c5e\u6027\uff0c\u5728\u5916\u90e8\u662f\u4e0d\u53ef\u8c03\u7528\u7684\uff0c tom.__get_phone() \u62a5\u9519\u201c\u5c5e\u6027\u4e0d\u5b58\u5728\u201d\u3002 \u5bf9\u5e94\u65b9\u6cd5\u4e5f\u662f\u7c7b\u4f3c\u3002 \u5728\u7c7b\u7684\u5185\u90e8\u5bf9\u53d7\u4fdd\u62a4\u5bf9\u8c61\u548c\u79c1\u6709\u5bf9\u8c61\u6ca1\u6709\u8bbf\u95ee\u9650\u5236\u3002 _get_age \u53ef\u4ee5\u8c03\u7528\u79c1\u6709\u5c5e\u6027 __phone \u3002 class Person (): name = 'name' # public _age = 0 # protected __phone = 'phone' # private def __init__ ( self , n , a , p ): self . name = n self . _age = a self . __phone = p def get_name ( self ): print ( f 'My name is { self . name } ' ) def _get_age ( self ): print ( f 'My age is { self . _age } ' ) print ( f 'My age is { self . __phone } ' ) def __get_phone ( self ): print ( f 'My phone is { self . __phone } ' ) tom = Person ( 'Tom' , 18 , 12345678 ) tom . name # 'Tom' tom . _age # 18 tom . __phone # AttributeError: 'Person' object has no attribute '__phone' tom . get_name () # My name is Tom tom . _get_age () # My age is 18 # My age is 12345678 tom . __get_phone () # AttributeError: 'Person' object has no attribute '__get_phone' \u7ee7\u627f Inheritance \u00b6 \u5728\u4e0d\u6307\u5b9a\u7ee7\u627f\u7684\u7236\u7c7b\u65f6\uff0c\u6240\u6709\u7c7b\u90fd\u7ee7\u627fobject\u7c7b\uff08\u7cfb\u7edf\u63d0\u4f9b\uff09\u3002 \u88ab\u5176\u5b83\u7c7b\u7ee7\u627f\u7684\u7c7b\uff0c\u79f0\u4e3a\u7236\u7c7b\uff0c\u6216\u8005\u57fa\u7c7b\uff0c\u6216\u8005\u8d85\u7c7b\u3002 \u7ee7\u627f\u5176\u5b83\u7c7b\u7684\u7c7b\uff0c\u79f0\u4e3a\u5b50\u7c7b\uff0c\u6216\u8005\u6d3e\u751f\u7c7b\uff08derived class\uff09\u3002 \u5b50\u7c7b\u7ee7\u627f\u7236\u7c7b\u540e\uff0c\u5c31\u62e5\u6709\u4e86\u7236\u7c7b\u4e2d\u7684\u6240\u6709\u6210\u5458\uff08\u9664\u4e86\u79c1\u6709\u6210\u5458\uff09\u3002 \u5b50\u7c7b\u7ee7\u627f\u7236\u7c7b\u540e\uff0c\u5e76\u4e0d\u4f1a\u628a\u7236\u7c7b\u7684\u6210\u5458\u590d\u5236\u7ed9\u5b50\u7c7b\uff0c\u800c\u662f\u5f15\u7528\u3002 \u5b50\u7c7b\u53ef\u4ee5\u76f4\u63a5\u8c03\u7528\u7236\u7c7b\u7684\u65b9\u6cd5 super().BaseClassName \u3002\u5982\u679c\u7236\u7c7b\u65b9\u6cd5\u6709\u53c2\u6570\u8981\u6c42\uff0c\u5b50\u7c7b\u8c03\u7528\u65f6\u4e5f\u6709\u53c2\u6570\u8981\u6c42\u3002 \u5b50\u7c7b\u7ee7\u627f\u7236\u7c7b\u540e\uff0c\u53ef\u4ee5\u91cd\u65b0\u5b9a\u4e49\u7236\u7c7b\u4e2d\u7684\u65b9\u6cd5\uff0c\u79f0\u4e3a**\u91cd\u5199\uff08Override\uff09**\u3002 \u5b50\u7c7b\u7ee7\u627f\u7236\u7c7b\u540e\uff0c\u5b9a\u4e49\u7236\u7c7b\u4e2d\u6ca1\u6709\u7684\u65b9\u6cd5\uff0c\u88ab\u79f0\u4e3a\u5bf9\u7236\u7c7b\u7684\u6269\u5c55\u3002 \u4e00\u4e2a\u7236\u7c7b\u53ef\u4ee5\u88ab\u591a\u4e2a\u5b50\u7c7b\u7ee7\u627f\u3002 **\u6d3e\u751f\u7c7b\uff08derived class\uff09**\u5b9a\u4e49\u7684\u8bed\u6cd5\u5982\u4e0b\u6240\u793a: class BaseClassName (): < statement - 1 > . . . < statement - N > class DerivedClassName ( BaseClassName ): < statement - 1 > . . . < statement - N > \u540d\u79f0 BaseClassName \u5fc5\u987b\u5b9a\u4e49\u4e8e\u5305\u542b\u6d3e\u751f\u7c7b\u5b9a\u4e49\u7684\u4f5c\u7528\u57df\u4e2d\u3002 \u4e5f\u5141\u8bb8\u7528\u5176\u4ed6\u4efb\u610f\u8868\u8fbe\u5f0f\u4ee3\u66ff\u57fa\u7c7b\u540d\u79f0\u6240\u5728\u7684\u4f4d\u7f6e\uff0c\u4f8b\u5982\uff0c\u5f53\u57fa\u7c7b\u5b9a\u4e49\u5728\u53e6\u4e00\u4e2a\u6a21\u5757\u4e2d\u7684\u65f6\u5019: class DerivedClassName ( modname . BaseClassName ): \u6d3e\u751f\u7c7b\u5b9a\u4e49\u7684\u6267\u884c\u8fc7\u7a0b\u4e0e\u57fa\u7c7b\u76f8\u540c\u3002 \u5f53\u6784\u9020\u7c7b\u5bf9\u8c61\u65f6\uff0c\u57fa\u7c7b\u4f1a\u88ab\u8bb0\u4f4f\u3002 \u6b64\u4fe1\u606f\u5c06\u88ab\u7528\u6765\u89e3\u6790\u5c5e\u6027\u5f15\u7528\uff1a\u5982\u679c\u8bf7\u6c42\u7684\u5c5e\u6027\u5728\u7c7b\u4e2d\u627e\u4e0d\u5230\uff0c\u641c\u7d22\u5c06\u8f6c\u5f80\u57fa\u7c7b\u4e2d\u8fdb\u884c\u67e5\u627e\u3002 \u5982\u679c\u57fa\u7c7b\u672c\u8eab\u4e5f\u6d3e\u751f\u81ea\u5176\u4ed6\u67d0\u4e2a\u7c7b\uff0c\u5219\u6b64\u89c4\u5219\u5c06\u88ab\u9012\u5f52\u5730\uff08recursively\uff09\u5e94\u7528\u3002 \u6d3e\u751f\u7c7b\u7684\u5b9e\u4f8b\u5316\u6ca1\u6709\u4efb\u4f55\u7279\u6b8a\u4e4b\u5904: DerivedClassName() \u4f1a\u521b\u5efa\u8be5\u7c7b\u7684\u4e00\u4e2a*\u65b0\u5b9e\u4f8b*\u3002 \u65b9\u6cd5\u5f15\u7528\u5c06\u6309\u4ee5\u4e0b\u65b9\u5f0f\u89e3\u6790\uff1a\u641c\u7d22\u76f8\u5e94\u7684\u7c7b\u5c5e\u6027\uff0c\u5982\u6709\u5fc5\u8981\u5c06\u6309\u57fa\u7c7b\u7ee7\u627f\u94fe\u9010\u6b65\u5411\u4e0b\u67e5\u627e\uff0c\u5982\u679c\u4ea7\u751f\u4e86\u4e00\u4e2a\u51fd\u6570\u5bf9\u8c61\u5219\u65b9\u6cd5\u5f15\u7528\u5c31\u751f\u6548\u3002 \u6d3e\u751f\u7c7b\u53ef\u80fd\u4f1a\u91cd\u5199\uff08override\uff09\u5176\u57fa\u7c7b\u7684\u65b9\u6cd5\u3002 \u56e0\u4e3a\u65b9\u6cd5\u5728\u8c03\u7528\u540c\u4e00\u5bf9\u8c61\u7684\u5176\u4ed6\u65b9\u6cd5\u65f6\u6ca1\u6709\u7279\u6b8a\u6743\u9650\uff0c\u6240\u4ee5\u8c03\u7528\u540c\u4e00\u57fa\u7c7b\u4e2d\u5b9a\u4e49\u7684\u53e6\u4e00\u65b9\u6cd5\u7684\u57fa\u7c7b\u65b9\u6cd5\u6700\u7ec8\u53ef\u80fd\u4f1a\u8c03\u7528\u8986\u76d6\u5b83\u7684\u6d3e\u751f\u7c7b\u7684\u65b9\u6cd5\u3002 \u5728\u6d3e\u751f\u7c7b\u4e2d\u7684\u91cd\u8f7d\u65b9\u6cd5\uff08overriding method\uff09\u5b9e\u9645\u4e0a\u53ef\u80fd\u60f3\u8981\u6269\u5c55\u800c\u975e\u7b80\u5355\u5730\u66ff\u6362\u540c\u540d\u7684\u57fa\u7c7b\u65b9\u6cd5\u3002 \u6709\u4e00\u79cd\u65b9\u5f0f\u53ef\u4ee5\u7b80\u5355\u5730\u76f4\u63a5\u8c03\u7528\u57fa\u7c7b\u65b9\u6cd5\uff1a\u5373\u8c03\u7528 BaseClassName.methodname(self, arguments) \u3002 \u8bf7\u6ce8\u610f\uff0c\u4ec5\u5f53\u6b64\u57fa\u7c7b\u53ef\u5728\u5168\u5c40\u4f5c\u7528\u57df\u4e2d\u4ee5 BaseClassName \u7684\u540d\u79f0\u88ab\u8bbf\u95ee\u65f6\u65b9\u53ef\u4f7f\u7528\u6b64\u65b9\u5f0f\u3002 Python\u6709\u4e24\u4e2a\u5185\u7f6e\u51fd\u6570\u53ef\u88ab\u7528\u4e8e\u7ee7\u627f\u673a\u5236\uff1a \u4f7f\u7528 isinstance() \u6765\u68c0\u67e5\u4e00\u4e2a\u5b9e\u4f8b\u7684\u7c7b\u578b: isinstance(obj, int) \u4ec5\u4f1a\u5728 obj.__class__ \u4e3a int \u6216\u67d0\u4e2a\u6d3e\u751f\u81ea int \u7684\u7c7b\u65f6\u4e3a True \u3002 \u4f7f\u7528 issubclass() \u6765\u68c0\u67e5\u7c7b\u7684\u7ee7\u627f\u5173\u7cfb: issubclass(bool, int) \u4e3a True \uff0c\u56e0\u4e3a bool \u662f int \u7684\u5b50\u7c7b\u3002 \u4f46\u662f\uff0c issubclass(float, int) \u4e3a False \uff0c\u56e0\u4e3a float \u4e0d\u662f int \u7684\u5b50\u7c7b\u3002 \u591a\u91cd\u7ee7\u627f Multiple Inheritance \u00b6 \u5355\u7ee7\u627f\uff08single-inheritance\uff09\uff1a\u4e00\u4e2a\u7c7b\u53ea\u80fd\u7ee7\u627f\u4e00\u4e2a\u7236\u7c7b\u65b9\u5f0f\u3002 class DerivedClassName ( BaseClassName ): < statement - 1 > . . . < statement - N > \u591a\u7ee7\u627f\uff08Multiple Inheritance\uff09\uff1a\u4e00\u4e2a\u7c7b\u53bb\u7ee7\u627f\u591a\u4e2a\u7c7b\u7684\u65b9\u5f0f\u3002\u5b9a\u4e49\u8bed\u53e5\u5982\u4e0b\u6240\u793a class DerivedClassName ( Base1 , Base2 , Base3 ): < statement - 1 > . . . < statement - N > \u5728\u6700\u7b80\u5355\u7684\u60c5\u51b5\u4e0b\uff0c\u641c\u7d22\u4ece\u7236\u7c7b\u6240\u7ee7\u627f\u5c5e\u6027\u7684\u64cd\u4f5c\u662f\u6df1\u5ea6\u4f18\u5148\uff08depth-first\uff09\u3001\u4ece\u5de6\u81f3\u53f3\uff08left-to-right\uff09\u7684\uff0c\u5f53\u5c42\u6b21\u7ed3\u6784\u4e2d\u5b58\u5728\u91cd\u53e0\u65f6\u4e0d\u4f1a\u5728\u540c\u4e00\u4e2a\u7c7b\u4e2d\u641c\u7d22\u4e24\u6b21\u3002 \u56e0\u6b64\uff0c\u5982\u679c\u67d0\u4e00\u5c5e\u6027\u5728 DerivedClassName \u4e2d\u672a\u627e\u5230\uff0c\u5219\u4f1a\u5230 Base1 \u4e2d\u641c\u7d22\u5b83\uff0c\u7136\u540e\uff08\u9012\u5f52\u5730\uff09\u5230 Base1 \u7684\u57fa\u7c7b\u4e2d\u641c\u7d22\uff0c\u5982\u679c\u5728\u90a3\u91cc\u672a\u627e\u5230\uff0c\u518d\u5230 Base2 \u4e2d\u641c\u7d22\uff0c\u4f9d\u6b64\u7c7b\u63a8\u3002 \u771f\u5b9e\u60c5\u51b5\u66f4\u590d\u6742\uff1b\u65b9\u6cd5\u89e3\u6790\u987a\u5e8f\u4f1a\u52a8\u6001\u6539\u53d8\u4ee5\u652f\u6301\u5bf9 super() \u7684\u534f\u540c\u8c03\u7528\u3002 \u8fd9\u79cd\u65b9\u5f0f\u5728\u67d0\u4e9b\u5176\u4ed6\u591a\u91cd\u7ee7\u627f\u578b\u8bed\u8a00\u4e2d\u88ab\u79f0\u4e3a**\u540e\u7eed\u65b9\u6cd5\u8c03\u7528\uff08call-next-method\uff09**\uff0c\u5b83\u6bd4**\u5355\u7ee7\u627f\uff08single-inheritance\uff09**\u8bed\u8a00\u4e2d\u7684 uper \u8c03\u7528\u66f4\u5f3a\u5927\u3002 \u52a8\u6001\u6539\u53d8\u987a\u5e8f\u662f\u6709\u5fc5\u8981\u7684\uff0c\u56e0\u4e3a\u6240\u6709\u591a\u91cd\u7ee7\u627f\u7684\u60c5\u51b5\u90fd\u4f1a\u663e\u793a\u51fa\u4e00\u4e2a\u6216\u66f4\u591a\u7684\u83f1\u5f62\u5173\u8054\uff08diamond relationships\uff09\uff08\u5373\u81f3\u5c11\u6709\u4e00\u4e2a\u7236\u7c7b\u53ef\u901a\u8fc7\u591a\u6761\u8def\u5f84\u88ab\u6700\u5e95\u5c42\u7c7b\u6240\u8bbf\u95ee\uff09\u3002 \u4f8b\u5982\uff0c\u6240\u6709\u7c7b\u90fd\u662f\u7ee7\u627f\u81ea object \uff0c\u56e0\u6b64\u4efb\u4f55\u591a\u91cd\u7ee7\u627f\u7684\u60c5\u51b5\u90fd\u63d0\u4f9b\u4e86\u4e00\u6761\u4ee5\u4e0a\u7684\u8def\u5f84\u53ef\u4ee5\u901a\u5411 object \u3002 \u4e3a\u4e86\u786e\u4fdd\u57fa\u7c7b\u4e0d\u4f1a\u88ab\u8bbf\u95ee\u4e00\u6b21\u4ee5\u4e0a\uff0c\u52a8\u6001\u7b97\u6cd5\u4f1a\u7528\u4e00\u79cd\u7279\u6b8a\u65b9\u5f0f\u5c06\u641c\u7d22\u987a\u5e8f\u7ebf\u6027\u5316\uff0c \u4fdd\u7559\u6bcf\u4e2a\u7c7b\u6240\u6307\u5b9a\u7684\u4ece\u5de6\u81f3\u53f3\u7684\u987a\u5e8f\uff0c\u53ea\u8c03\u7528\u6bcf\u4e2a\u7236\u7c7b\u4e00\u6b21\uff0c\u5e76\u4e14\u4fdd\u6301\u5355\u8c03\uff08monotonic\uff09\uff08\u5373\u4e00\u4e2a\u7c7b\u53ef\u4ee5\u88ab\u5b50\u7c7b\u5316\u800c\u4e0d\u5f71\u54cd\u5176\u7236\u7c7b\u7684\u4f18\u5148\u987a\u5e8f\uff09\u3002 \u603b\u800c\u8a00\u4e4b\uff0c\u8fd9\u4e9b\u7279\u6027\u4f7f\u5f97\u8bbe\u8ba1\u5177\u6709\u591a\u91cd\u7ee7\u627f\u7684\u53ef\u9760\u4e14\u53ef\u6269\u5c55\u7684\u7c7b\u6210\u4e3a\u53ef\u80fd\u3002 \u770b\u4e0b\u9762\u4f8b\u5b50\uff0c\u5b9a\u4e49\u4e863\u4e2a\u7c7b\u548c\u7ee7\u627f\u5173\u7cfb\u3002 class F (): def drink ( self ): print ( \"Drink Beer\" ) class M (): def drink ( self ): print ( \"Drink Red Wine\" ) class C ( F , M ): def drink ( self ): print ( \"Drink Water\" ) \u6267\u884c\u7ed3\u679c\u662f c = C () c . drink () # Drink Water \u65b9\u6cd51\uff1a\u6309\u7167mro\u8fdb\u884c\u7ee7\u627f\u67e5\u627e\u3002 \u5982\u679c\u628a C \u7c7b\u6539\u5199\u4e3a\u5982\u4e0b\uff0c\u53ef\u4ee5\u8c03\u7528\u7236\u7c7b\uff0c\u53c2\u7167 C \u7c7b\u7684mro\u8fdb\u884c\uff0c mro \u91cc\u9762\u7c7b F \u7684\u4e0a\u4e00\u7ea7\u662f\u7c7b M \uff0c\u6240\u4ee5\u7c7b F \u4e2d\u7684 super() \u5c31\u662f\u6307\u7c7b M \u3002 class C ( F , M ): def drink ( self ): super () . drink () print ( \"Drink Water\" ) c = C () c . drink () # Drink Beer # Drink Water C . mro () # [, , , ] \u65b9\u6cd52\uff1a\u201c\u6307\u540d\u9053\u59d3\u201d\u8c03\u7528\u3002\u5982\u679c\u628a C \u7c7b\u6539\u5199\u4e3a\u5982\u4e0b\uff0c\u53ef\u4ee5\u8c03\u7528 M \u7c7b\u3002 class C ( F , M ): def drink ( self ): M . drink ( self ) print ( \"Drink Water\" ) c = C () c . drink () # Drink Red Wine # Drink Water \u83f1\u5f62\u7ee7\u627f\u548c\u7ee7\u627f\u5173\u7cfb\u68c0\u6d4b \u00b6 \u83f1\u5f62\u7ee7\u627f\u7684\u63cf\u8ff0\u662f\uff0c\u7c7b A \u4f5c\u4e3a\u57fa\u7c7b\uff08\u8fd9\u91cc\u57fa\u7c7b\u662f\u6307\u975e object \u7c7b\uff09\uff0c\u7c7b B \u548c\u7c7b C \u540c\u65f6\u7ee7\u627f\u7c7b A \uff0c\u7136\u540e\u7c7b D \u53c8\u7ee7\u627f\u7c7b B \u548c\u7c7b C \uff0c\u5982\u4e0b\u56fe\uff0c\u770b\u8d77\u6765\u50cf\u4e2a\u94bb\u77f3\u7684\u5f62\u72b6\u3002 A / \\ B C \\ / D \u5728\u8fd9\u79cd\u7ed3\u6784\u4e2d\uff0c\u5728\u8c03\u7528\u987a\u5e8f\u4e0a\u5c31\u4f1a\u51fa\u73b0\u7591\u60d1\uff0c\u8c03\u7528\u987a\u5e8f\u7a76\u7adf\u662f\u4ee5\u4e0b\u54ea\u4e00\u79cd\u987a\u5e8f\u5462\uff1f D->B->A->C\uff08\u6df1\u5ea6\u4f18\u5148\uff09 D->B->C->A\uff08\u5e7f\u5ea6\u4f18\u5148\uff09 \u770b\u4e0b\u9762\u4ee3\u7801\uff0c\u5728Python3\u4e2d\uff0c**\u83f1\u5f62**\u7684\u591a\u7ee7\u627f\u5173\u7cfb\u662f\u6309\u7167D->B->C->A**\u5e7f\u5ea6\u4f18\u5148**\u7684\u641c\u7d22\u65b9\u5f0f\u3002 class A (): pass class B ( A ): def test ( self ): print ( \"init B.test()\" ) class C ( A ): def test ( self ): print ( \"init C.test()\" ) class D ( B , C ): pass d = D () d . test () # init B.test() D . mro () # [, , , , ] \u5bf9\u4e8e\u4e0b\u9762\u8fd9\u79cd**\u975e\u83f1\u5f62**\u7684\u591a\u7ee7\u627f\u5173\u7cfb\uff0c\u67e5\u627e\u987a\u5e8f\u662fA->B->E->C->F->D**\u6df1\u5ea6\u4f18\u5148**\u7684\u641c\u7d22\u65b9\u5f0f\u3002 E F | | B ( E ) C ( F ) D | | | \\ | / \\ | / A ( B , C , D ) \u4ee3\u7801\u5b9e\u73b0\uff1a class D (): def test ( self ): print ( \"init D.test()\" ) class F (): def test ( self ): print ( \"init F.test()\" ) class C ( F ): pass class E (): pass class B ( E ): pass class A ( B , C , D ): pass a = A () a . test () # init F.test() A . mro () # [, , , , , , ] \u603b\u7ed3\uff1a \u7ee7\u627f\u7ed3\u6784\u8981\u5c3d\u91cf\u7b80\u5355\uff0c\u4e0d\u8981\u8fc7\u4e8e\u590d\u6742\u3002 \u63a8\u8350\u4f7f\u7528minxins\u673a\u5236\uff0c\u5728\u591a\u7ee7\u627f\u80cc\u666f\u4e0b\uff0c\u6ee1\u8db3\u7ee7\u627f\u7684\u4ec0\u4e48\u662f\u4ec0\u4e48\u7684\u5173\u7cfb\uff08is-a\uff09 \u591a\u7ee7\u627f\u5173\u7cfb\u7684minxins\u673a\u5236 \u00b6 \u770b\u4e0b\u9762\u4f8b\u5b50\uff0c\u5982\u679c\u5728 Vehicle \u7c7b\u4e2d\u5b9a\u4e49\u4e86 fly \u7684\u65b9\u6cd5\uff0c\u4f1a\u5bfc\u81f4 Car(Vehicle) \u7684\u7ee7\u627f\u5173\u7cfb\u51fa\u73b0\u77db\u76fe\uff0c\u6c7d\u8f66\u5e76\u4e0d\u4f1a\u98de\uff0c\u4f46\u6309\u7167\u4e0a\u8ff0\u7ee7\u627f\u5173\u7cfb\uff0c\u6c7d\u8f66\u4e5f\u80fd\u98de\u4e86\u3002 \u4f46\u662f\u5982\u679c\u6c11\u822a\u98de\u673a\u548c\u76f4\u5347\u673a\u90fd\u5404\u81ea\u5199\u81ea\u5df1\u7684\u98de\u884cfly\u65b9\u6cd5\uff0c\u53c8\u8fdd\u80cc\u4e86\u4ee3\u7801\u5c3d\u53ef\u80fd\u91cd\u7528\u7684\u539f\u5219\u3002 class Vehicle : # \u4ea4\u901a\u5de5\u5177 def fly ( self ): ''' \u98de\u884c\u529f\u80fd\u76f8\u5e94\u7684\u4ee3\u7801 ''' print ( \"I am flying\" ) # \u6c11\u822a\u98de\u673a class CivilAircraft ( Vehicle ): pass # \u76f4\u5347\u98de\u673a class Helicopter ( Vehicle ): pass # \u6c7d\u8f66 class Car ( Vehicle ): pass Python\u4e2d\u6ca1\u6709\u7c7b\u4f3cJava\u63a5\u53e3interface\u7684\u529f\u80fd\uff0c\u4f46\u63d0\u4f9b\u4e86Mixins\u673a\u5236\u3002 Python\u5bf9\u4e8e Mixin \u7c7b\u7684\u547d\u540d\u65b9\u5f0f\u4e00\u822c\u4ee5 Mixin , able , ible \u4e3a\u540e\u7f00\u3002 Mixin \u7c7b\u5fc5\u987b\u529f\u80fd\u5355\u4e00\uff0c\u5982\u679c\u6709\u591a\u4e2a\u529f\u80fd\uff0c\u90a3\u5c31\u5199\u591a\u4e2aMixin\u7c7b\u3002 \u4e00\u4e2a\u7c7b\u53ef\u4ee5\u7ee7\u627f\u591a\u4e2a Mixin \u7c7b\uff0c\u4e3a\u4e86\u4fdd\u8bc1\u9075\u5faa\u7ee7\u627f\u7684\u201cis-a\u201d\u539f\u5219\uff0c\u53ea\u80fd\u7ee7\u627f\u4e00\u4e2a\u6807\u8bc6\u5176\u5f52\u5c5e\u542b\u4e49\u7684\u7236\u7c7b Mixin \u7c7b\u4e0d\u4f9d\u8d56\u4e8e\u5b50\u7c7b\u7684\u5b9e\u73b0\u3002 \u5b50\u7c7b\u5373\u4fbf\u6ca1\u6709\u7ee7\u627f\u8fd9\u4e2a Mixin \u7c7b\u7c7b\uff0c\u4e5f\u7167\u6837\u53ef\u4ee5\u5de5\u4f5c\uff0c\u5c31\u662f\u7f3a\u5c11\u4e86\u67d0\u4e2a\u529f\u80fd\u3002 \u6211\u4eec\u5b9a\u4e49\u7684 Mixin \u7c7b\u8d8a\u591a\uff0c\u5b50\u7c7b\u7684\u4ee3\u7801\u53ef\u8bfb\u6027\u5c31\u4f1a\u8d8a\u5dee\u3002 # \u4ea4\u901a\u5de5\u5177 class Vehicle : pass # \u4e3a\u5f53\u524d\u7c7b\u6df7\u5165\u4e00\u4e9b\u529f\u80fd\uff0c\u4e0d\u662f\u4e00\u4e2a\u5355\u7eaf\u7684\u7c7b class FlyableMixin : def fly ( self ): ''' \u98de\u884c\u529f\u80fd\u76f8\u5e94\u7684\u4ee3\u7801 ''' print ( \"I am flying\" ) # \u6c11\u822a\u98de\u673a class CivilAircraft ( FlyableMixin , Vehicle ): pass # \u76f4\u5347\u98de\u673a class Helicopter ( FlyableMixin , Vehicle ): pass # \u6c7d\u8f66 class Car ( Vehicle ): pass \u7ec4\u5408\uff08Class Combination\uff09 \u00b6 \u5728\u4e00\u4e2a\u7c7b\u4e2d\u4ee5\u53e6\u4e00\u4e2a\u7c7b\u7684\u5bf9\u8c61\u4f5c\u4e3a\u6570\u636e\u5c5e\u6027\uff0c\u79f0\u4e3a\u7c7b\u7684**\u7ec4\u5408**\u3002\u7ec4\u5408\u4e0e\u7ee7\u627f\u90fd\u662f\u7528\u6765\u89e3\u51b3\u4ee3\u7801\u7684\u91cd\u7528\u6027\u95ee\u9898\u3002 \u7ee7\u627f\u4f53\u73b0\u201c\u662f\u201d\u7684\u5173\u7cfb\uff0c\u5f53\u7c7b\u4e4b\u95f4\u6709\u5f88\u591a\u76f8\u540c\u4e4b\u5904\uff0c\u7528\u7ee7\u627f\u3002 \u7ec4\u5408\u4f53\u73b0\u201c\u6709\u201d\u7684\u5173\u7cfb\uff0c\u5f53\u7c7b\u4e4b\u95f4\u6709\u663e\u8457\u4e0d\u540c\uff0c\u4e00\u4e2a\u7c7b\u662f\u53e6\u4e00\u4e2a\u7c7b\u7684\u5c5e\u6027\u662f\uff0c\u7528\u7ec4\u5408\u3002 \u4e0b\u4f8b\u662f\u8ba1\u7b97\u5706\u73af\u7684\u9762\u79ef\u548c\u5468\u957f\uff0c\u5706\u73af\u662f\u7531\u4e24\u4e2a\u5706\u7ec4\u6210\u7684\uff0c\u5706\u73af\u7684\u9762\u79ef\u662f\u5916\u9762\u5706\u7684\u9762\u79ef\u51cf\u53bb\u5185\u90e8\u5706\u7684\u9762\u79ef\u3002\u5706\u73af\u7684\u5468\u957f\u662f\u5185\u90e8\u5706\u7684\u5468\u957f\u52a0\u4e0a\u5916\u90e8\u5706\u7684\u5468\u957f\u3002 \u8fd9\u4e2a\u4f8b\u5b50\u6f14\u793a\u4e86\u7c7b ring \u91cc\u9762\u7684\u5c5e\u6027 circle1 \u548c circle2 \u6b63\u662f\u53e6\u4e00\u4e2a\u7c7b Circle \u3002 from math import pi class Circle (): def __init__ ( self , r ): self . r = r def area ( self ): return pi * self . r * self . r def perimeter ( self ): return 2 * pi * self . r class Ring (): def __init__ ( self , r1 , r2 ): self . circle1 = Circle ( r1 ) self . circle2 = Circle ( r2 ) def area ( self ): return abs ( self . circle1 . area () - self . circle2 . area ()) def permiter ( self ): return self . circle1 . perimeter () + self . circle2 . perimeter () ring = Ring ( 5 , 8 ) print ( ring . area ()) # 122.52211349000193 print ( ring . permiter ()) # 81.68140899333463 \u4e0b\u9762\u7684\u4f8b\u5b50\u6f14\u793a\u4e86\u5982\u4f55\u901a\u8fc7\u4f20\u53c2\u7684\u65b9\u5f0f\u8fdb\u884c\u7c7b\u7684\u7ec4\u5408\u3002 class Birthday (): def __init__ ( self , year , month , day ): self . year = year self . month = month self . day = day class Course (): def __init__ ( self , course_name , course_period ): self . course_name = course_name self . course_period = course_period class Professor (): def __init__ ( self , name , gender , birth , course ): self . name = name self . gender = gender self . birth = birth self . course = course def teach ( self ): print ( f \"Professor name: { self . name } ; Gender: { self . gender } ; Birthday: { self . birth . year } - { self . birth . month }{ self . birth . day } , Course name: { self . course . course_name } and period: { self . course . course_period } \" ) prof = Professor ( 'Tom' , 'Male' , Birthday ( 1985 , 5 , 5 ), Course ( 'Chinese' , '2022/3/1 ~ 2022/6/30' )) prof . teach () # Professor name: Tom; Gender: Male; Birthday: 1985-55, Course name: Chinese and period: 2022/3/1 ~ 2022/6/30 \u591a\u6001 Polymorphism \u00b6 \u591a\u6001\u610f\u5473\u7740\u76f8\u540c\u7684\u51fd\u6570\u540d\u7528\u4e8e\u4e0d\u540c\u7684\u60c5\u5f62\u3002 \u5982\u4e0b\u4f8b\uff0c len() \u88ab\u7528\u4e8e\u4e0d\u540c\u7684\u60c5\u5f62\u3002 # len() being used for a string print ( len ( \"geeks\" )) # 5 # len() being used for a list print ( len ([ 10 , 20 , 30 ])) # 3 \u7c7b\u65b9\u6cd5\u7684\u591a\u6001\u6027 \u00b6 \u4e0b\u9762\u7684\u4ee3\u7801\u5c55\u793a\u4e86 Python \u5982\u4f55\u4ee5\u76f8\u540c\u7684\u65b9\u5f0f\u4f7f\u7528\u4e24\u79cd\u4e0d\u540c\u7684\u7c7b\u7c7b\u578b\u3002 \u6211\u4eec\u521b\u5efa\u4e86\u4e00\u4e2a\u904d\u5386\u5bf9\u8c61\u5143\u7ec4\u7684 for \u5faa\u73af\u3002 \u7136\u540e\u8c03\u7528\u65b9\u6cd5\u800c\u4e0d\u7528\u5173\u5fc3\u6bcf\u4e2a\u5bf9\u8c61\u662f\u54ea\u4e2a\u7c7b\u7c7b\u578b\u3002 \u6211\u4eec\u5047\u8bbe\u8fd9\u4e9b\u65b9\u6cd5\u5b9e\u9645\u4e0a\u5b58\u5728\u4e8e\u6bcf\u4e2a\u7c7b\u4e2d\u3002 class India (): def capital ( self ): print ( \"New Delhi is the capital of India.\" ) def language ( self ): print ( \"Hindi is the most widely spoken language of India.\" ) def type ( self ): print ( \"India is a developing country.\" ) class USA (): def capital ( self ): print ( \"Washington, D.C. is the capital of USA.\" ) def language ( self ): print ( \"English is the primary language of USA.\" ) def type ( self ): print ( \"USA is a developed country.\" ) obj_ind = India () obj_usa = USA () for country in ( obj_ind , obj_usa ): country . capital () country . language () country . type () # New Delhi is the capital of India. # Hindi is the most widely spoken language of India. # India is a developing country. # Washington, D.C. is the capital of USA. # English is the primary language of USA. # USA is a developed country. \u7ee7\u627f\u7684\u591a\u6001\u6027 \u00b6 \u5728 Python \u4e2d\uff0c\u591a\u6001\u5141\u8bb8\u6211\u4eec\u5728\u5b50\u7c7b\u4e2d\u5b9a\u4e49\u4e0e\u7236\u7c7b\u4e2d\u7684\u65b9\u6cd5\u540c\u540d\u7684\u65b9\u6cd5\u3002 \u5728\u7ee7\u627f\u4e2d\uff0c\u5b50\u7c7b\u7ee7\u627f\u7236\u7c7b\u7684\u65b9\u6cd5\u3002 \u4f46\u662f\uff0c\u53ef\u4ee5\u4fee\u6539\u4ece\u7236\u7c7b\u7ee7\u627f\u7684\u5b50\u7c7b\u4e2d\u7684\u65b9\u6cd5\u3002 \u8fd9\u5728\u4ece\u7236\u7c7b\u7ee7\u627f\u7684\u65b9\u6cd5\u4e0d\u592a\u9002\u5408\u5b50\u7c7b\u7684\u60c5\u51b5\u4e0b\u7279\u522b\u6709\u7528\u3002 \u5728\u8fd9\u79cd\u60c5\u51b5\u4e0b\uff0c\u6211\u4eec\u5728\u5b50\u7c7b\u4e2d\u91cd\u65b0\u5b9e\u73b0\u8be5\u65b9\u6cd5\u3002 \u8fd9\u79cd\u5728\u5b50\u7c7b\u4e2d\u91cd\u65b0\u5b9e\u73b0\u65b9\u6cd5\u7684\u8fc7\u7a0b\u79f0\u4e3a**\u65b9\u6cd5\u8986\u76d6\uff08Method Overriding\uff09**\u3002 class Bird : def intro ( self ): print ( \"There are many types of birds.\" ) def flight ( self ): print ( \"Most of the birds can fly but some cannot.\" ) class sparrow ( Bird ): def flight ( self ): print ( \"Sparrows can fly.\" ) class ostrich ( Bird ): def flight ( self ): print ( \"Ostriches cannot fly.\" ) obj_bird = Bird () obj_spr = sparrow () obj_ost = ostrich () obj_bird . intro () # There are many types of birds. obj_bird . flight () # Most of the birds can fly but some cannot. obj_spr . intro () # There are many types of birds. obj_spr . flight () # Sparrows can fly. obj_ost . intro () # There are many types of birds. obj_ost . flight () # Ostriches cannot fly. \u51fd\u6570\u548c\u5bf9\u8c61\u7684\u591a\u6001\u6027 \u00b6 \u6211\u4eec\u4e5f\u53ef\u4ee5\u521b\u5efa\u4e00\u4e2a\u53ef\u4ee5\u63a5\u53d7\u4efb\u4f55\u5bf9\u8c61\u7684\u51fd\u6570\uff0c\u5141\u8bb8\u591a\u6001\u6027\u3002 \u5728\u4e0b\u9762\u4f8b\u5b50\u4e2d\uff0c\u6211\u4eec\u521b\u5efa\u4e00\u4e2a\u540d\u4e3a func() \u7684\u51fd\u6570\uff0c\u4f20\u5165\u53c2\u6570\u662f obj \u7684\u5bf9\u8c61\u3002 \u5728\u8fd9\u79cd\u60c5\u51b5\u4e0b\uff0c\u6211\u4eec\u8c03\u7528\u4e09\u4e2a\u65b9\u6cd5\uff0c\u5373 capital() \u3001 language() \u548c type() \uff0c\u6bcf\u4e2a\u65b9\u6cd5\u90fd\u5b9a\u4e49\u5728 India \u548c USA \u4e24\u4e2a\u7c7b\u4e2d\u3002 \u6211\u4eec\u53ef\u4ee5\u4f7f\u7528\u76f8\u540c\u7684 func() \u51fd\u6570\u8c03\u7528\u5b83\u4eec\u7684\u52a8\u4f5c\uff1a class India (): def capital ( self ): print ( \"New Delhi is the capital of India.\" ) def language ( self ): print ( \"Hindi is the most widely spoken language of India.\" ) def type ( self ): print ( \"India is a developing country.\" ) class USA (): def capital ( self ): print ( \"Washington, D.C. is the capital of USA.\" ) def language ( self ): print ( \"English is the primary language of USA.\" ) def type ( self ): print ( \"USA is a developed country.\" ) def func ( obj ): obj . capital () obj . language () obj . type () obj_ind = India () obj_usa = USA () func ( obj_ind ) # New Delhi is the capital of India. # Hindi is the most widely spoken language of India. # India is a developing country. func ( obj_usa ) # Washington, D.C. is the capital of USA. # English is the primary language of USA. # USA is a developed country. \u9e2d\u5b50\u7c7b\u578b\uff08Ducking Typing\uff09\u548c\u767d\u9e45\u7c7b\u578b\uff08Goose Typing\uff09 \u00b6 \u5728Python\u4e2d\u5b9e\u73b0\u591a\u6001\u4e3b\u8981\u6709\u4e24\u79cd\u673a\u5236\uff1a\u767d\u9e45\u7c7b\u578b\u548c\u9e2d\u5b50\u7c7b\u578b\u3002\u767d\u9e45\u7c7b\u578b\u548c\u9e2d\u5b50\u7c7b\u578b\u4e0d\u4ec5\u662f\u4e24\u79cd\u673a\u5236\uff0c\u4e5f\u662f\u4e24\u79cd\u4e0d\u540c\u7684\u7f16\u7a0b\u98ce\u683c\u3002 \u4e0b\u9762\u662f\u4e00\u4e2a\u6253\u5370\u5546\u54c1\u4ef7\u683c\u7684\u4f8b\u5b50\uff0c\u5206\u522b\u7528\u9e2d\u5b50\u7c7b\u578b\u548c\u767d\u9e45\u7c7b\u578b\u5b9e\u73b0\u3002 \u9e2d\u5b50\u7c7b\u578b\u3002 \u5728\u9e2d\u5b50\u7c7b\u578b\u7684\u5b9e\u73b0\u4e2d\uff0c\u6211\u4eec\u53ea\u9700\u8981\u4fdd\u8bc1\u8c03\u7528 price \u65b9\u6cd5\u7684\u6bcf\u4e2a\u5bf9\u8c61\u90fd\u6709 price \u65b9\u6cd5\u5373\u53ef\u3002 class Food : def price ( self ): print ( \" {} price:$4\" . format ( __class__ . __name__ )) class Clothes : def price ( self ): print ( \" {} price:$5\" . format ( __class__ . __name__ )) class Coffee : def price ( self ): print ( \" {} price:$6\" . format ( __class__ . __name__ )) if __name__ == '__main__' : goods = [ Food (), Clothes (), Coffee ()] for good in goods : good . price () # Food price:$4 # Clothes price:$5 # Coffee price:$6 \u767d\u9e45\u7c7b\u578b\u3002 \u5728\u767d\u9e45\u7c7b\u578b\u4e2d\uff0c\u76f4\u63a5\u8ba9\u6240\u6709\u5bf9\u8c61\u7684\u7c7b\u7ee7\u627f\u7236\u7c7b Good \u4e2d\u7684\u62bd\u8c61\u65b9\u6cd5 price \u3002Python\u4e2d\u7684\u767d\u9e45\u7c7b\u578b\u673a\u5236\u5c31\u662f\u5f3a\u7c7b\u578b\u8bed\u8a00\u4e2d\u5b9e\u73b0\u591a\u6001\u7684\u6807\u51c6\u6a21\u5f0f\uff0c\u5373\u901a\u8fc7\u8c03\u53d6\u7236\u7c7b\u7684\u865a\u51fd\u6570\u6216\u8005\u7ee7\u627f\u7684\u51fd\u6570\u6765\u5b8c\u6210\u4e0d\u540c\u7684\u884c\u4e3a\u3002 import abc class Good ( abc . ABC ): @abc . abstractmethod def price ( self ): pass class Food ( Good ): def price ( self ): print ( \" {} price:$4\" . format ( __class__ . __name__ )) class Clothes ( Good ): def price ( self ): print ( \" {} price:$5\" . format ( __class__ . __name__ )) if __name__ == '__main__' : goods = [ Food (), Clothes (), Coffee ()] for good in goods : good . price () # Food price:$4 # Clothes price:$5 # Coffee price:$6 \u7c7b\u65b9\u6cd5\uff08Class method\uff09\u548c\u9759\u6001\u65b9\u6cd5\uff08Static Method\uff09 \u00b6 \u7c7b\u65b9\u6cd5\uff08Class method\uff09\u4e5f\u53eb\u7ed1\u5b9a\u65b9\u6cd5\uff0c\u5fc5\u987b\u628a\u7c7b\u4f5c\u4e3a\u4f20\u5165\u53c2\u6570\uff0c\u4f7f\u7528 cls \u4f5c\u4e3a\u7b2c\u4e00\u4e2a\u4f20\u5165\u53c2\u6570\uff0c\u800c\u9759\u6001\u65b9\u6cd5\uff08Static Method\uff09\uff0c\u4e5f\u53eb\u975e\u7ed1\u5b9a\u65b9\u6cd5\uff0c\u4e0d\u9700\u8981\u7279\u5b9a\u7684\u53c2\u6570\u3002 \u7c7b\u65b9\u6cd5\u662f\u7ed1\u5b9a\u5230\u7c7b\u7684\uff0c\u4e0d\u662f\u7ed1\u5b9a\u5230\u7c7b\u5bf9\u8c61\uff0c\u6240\u4ee5\u7c7b\u65b9\u6cd5\u53ef\u4ee5\u8bbf\u95ee\u6216\u4fee\u6539\u7c7b\uff0c\u5e76\u5bf9\u6240\u6709\u7c7b\u5b9e\u4f8b\u751f\u6548\u3002 \u9759\u6001\u65b9\u6cd5\u65e0\u6cd5\u76f4\u63a5\u8bbf\u95ee\u6216\u4fee\u6539\u7c7b\uff0c\u56e0\u4e3a\u9759\u6001\u65b9\u6cd5\u662f\u4e0d\u77e5\u9053\u7c7b\u672c\u8eab\u7684\uff0c\u9759\u6001\u65b9\u6cd5\u662f\u5c5e\u4e8e\u5de5\u5177\u7c7b\u65b9\u6cd5\uff0c\u57fa\u4e8e\u4f20\u5165\u7684\u53c2\u6570\u5b8c\u6210\u7279\u5b9a\u7684\u529f\u80fd\uff0c\u5176\u5b9e\u5c31\u662f\u4e00\u4e2a\u666e\u901a\u51fd\u6570\u800c\u5df2\u3002 Python\u4e2d\u4f7f\u7528 @classmethod \u88c5\u9970\u5668\uff08decorator\uff09\u6765\u521b\u5efa\u4e00\u4e2a\u7c7b\u65b9\u6cd5\uff0c\u7528@staticmethod\u88c5\u9970\u5668\u6765\u521b\u5efa\u4e00\u4e2a\u9759\u6001\u65b9\u6cd5\u3002 \u8bed\u6cd5\u683c\u5f0f\uff1a @classmethod def fun ( cls , arg1 , arg2 , ... ): \u5176\u4e2d\uff1a fun : \u9700\u8981\u8f6c\u6362\u6210\u7c7b\u65b9\u6cd5\u7684\u51fd\u6570 returns : \u51fd\u6570\u7684\u7c7b\u65b9\u6cd5 classmethod() \u65b9\u6cd5\u7ed1\u5b9a\u5230\u7c7b\u800c\u4e0d\u662f\u5bf9\u8c61\u3002\u7c7b\u65b9\u6cd5\u53ef\u4ee5\u88ab\u7c7b\u548c\u5bf9\u8c61\u8c03\u7528\u3002\u8fd9\u4e9b\u65b9\u6cd5\u53ef\u4ee5\u901a\u8fc7\u7c7b\u6216\u5bf9\u8c61\u8fdb\u884c\u8c03\u7528\u3002 \u4f8b1\uff1a\u521b\u5efa\u4e00\u4e2a\u7b80\u5355\u7684 classmethod \u3002 \u521b\u5efa\u4e00\u4e2a\u7c7b Training \uff0c\u6709\u7c7b\u53d8\u91cf course \u548c\u65b9\u6cd5 purchase \u3002 \u6211\u4eec\u901a\u8fc7\u628a\u51fd\u6570 Training.purchase \u4f20\u7ed9 classmethod() \uff0c\u628a\u8be5\u65b9\u6cd5\u8f6c\u6210\u7c7b\u65b9\u6cd5\uff0c\u7136\u540e\u76f4\u63a5\u8c03\u7528\u5b83\uff0c\u800c\u65e0\u9700\u5148\u521b\u5efa\u5bf9\u8c61\u3002 \u53ef\u4ee5\u770b\u51fa\u8f6c\u6362\u524d\u540e Training.purchase \u7684\u7c7b\u578b\u53d8\u5316\u3002 class Training : course = 'Python for Data Analysis' def purchase ( obj ): print ( \"Puchase course : \" , obj . course ) type ( Training . purchase ) # Training . purchase = classmethod ( Training . purchase ) Training . purchase () # Puchase course : Python for Data Analysis type ( Training . purchase ) # \u4f8b2\uff1a\u4f7f\u7528\u88c5\u9970\u5668 @classmethod \u521b\u5efa\u5de5\u5382\u7c7b\u3002 class Training : def __init__ ( self , course ): self . course = course @classmethod def purchase ( cls , course ): return cls ( course ) def display ( self ): print ( 'Purchase course: ' , self . course ) training = Training ( \"Python for Data Analysis\" ) training . display () # Purchase course: Python for Data Analysis \u4f8b3\uff1a\u901a\u8fc7 staticmethod() \u548c classmethod() \u6765\u68c0\u67e5\u4e00\u4e2aperson\u662f\u5426\u662fadult\u3002 person1\u662f\u901a\u8fc7\u59d3\u540d\u548c\u5e74\u9f84\u521b\u5efa\u7684\u5b9e\u4f8b\u3002person2\u662f\u901a\u8fc7\u59d3\u540d\u548c\u5e74\u4efd\u521b\u5efa\u7684\u5b9e\u4f8b\u3002 from datetime import date class Person : def __init__ ( self , name , age ): self . name = name self . age = age @classmethod def fromBirthYear ( cls , name , year ): return cls ( name , date . today () . year - year ) @staticmethod def isAdult ( age ): return age > 18 person1 = Person ( 'mayank' , 21 ) person2 = Person . fromBirthYear ( 'mayank' , 1996 ) print ( person1 . age ) # 21 print ( person2 . age ) # 26 print ( Person . isAdult ( 22 )) # True \u5c0f\u7ed3\uff1a \u82e5\u7c7b\u4e2d\u9700\u8981\u4e00\u4e2a\u529f\u80fd\uff0c\u8be5\u529f\u80fd\u7684\u5b9e\u73b0\u4ee3\u7801\u4e2d\u9700\u8981\u5f15\u7528\u5bf9\u8c61\uff0c\u5219\u5c06\u5176\u5b9a\u4e49\u6210\u5bf9\u8c61\u65b9\u6cd5\uff1b\u9700\u8981\u5f15\u7528\u7c7b\uff0c\u5219\u5c06\u5176\u5b9a\u4e49\u6210\u7c7b\u65b9\u6cd5\uff1b\u65e0\u9700\u5f15\u7528\u7c7b\u6216\u5bf9\u8c61\uff0c\u5219\u5c06\u5176\u5b9a\u4e49\u6210\u9759\u6001\u65b9\u6cd5\u3002 \u7334\u5b50\u8865\u4e01\uff08monkey patch\uff09 \u00b6 \u7334\u5b50\u8865\u4e01\u662f\u52a8\u6001\u4e3a\u5df2\u7ecf\u521b\u5efa\u51fa\u7684\u5bf9\u8c61\u589e\u52a0\u65b0\u7684\u65b9\u6cd5\u548c\u5c5e\u6027\u6210\u5458\u7684\u4e00\u79cd\u673a\u5236\uff0c\u4e5f\u5c31\u662f\u52a8\u6001\u6253\u8865\u4e01\u3002 \u5b9e\u4f8b\u5316\u5bf9\u8c61\u7684\u7334\u5b50\u8865\u4e01\u3002 class Test : def __init__ ( self ): self . a = 1 def func1 ( self , x , y ): print ( x + y ) # \u6b63\u5e38\u5b9e\u4f8b\u5316 test = Test () test . func1 ( 1 , 1 ) # 2 # \u4fee\u6539\u5b9e\u4f8b test . func1 = lambda x , y : print ( x + 2 * y ) test . func1 ( 1 , 1 ) # 3 # \u901a\u8fc7\u4fee\u6539\u5b9e\u4f8b\uff0c\u8bbf\u95ee\u5185\u90e8\u6210\u5458\u53d8\u91cf\u3002 test . func1 = lambda x , y : print ( x + 2 * y + self . a ) test . func1 ( 1 , 1 ) # NameError: name 'self' is not defined test . func1 = lambda self , x , y : print ( x + 2 * y + self . a ) test . func1 ( test , 1 , 1 ) # 4 \u7c7b\u5bf9\u8c61\u7684\u7334\u5b50\u8865\u4e01\u3002 class Test : def __init__ ( self ): self . a = 1 def func1 ( self , x , y ): print ( x + y ) # \u4fee\u6539\u7c7b\u6210\u5458\uff0c\u5b9e\u4f8b\u5316\u540e\u7684\u7ed3\u679c\u5df2\u4fee\u6539\u3002 Test . func1 = lambda self , x , y : print ( x + 2 * y ) test = Test () test . func1 ( 1 , 1 ) # 3 # \u4fee\u6539\u7c7b\u6210\u5458\uff0c\u5e76\u8bbf\u95ee\u6210\u5458\u53d8\u91cf\uff0c\u5b9e\u4f8b\u5316\u540e\u7684\u7ed3\u679c\u5df2\u4fee\u6539\u3002 Test . func1 = lambda self , x , y : print ( x + 2 * y + self . a ) test = Test () test . func1 ( 1 , 1 ) # 4 # \u589e\u52a0\u7c7b\u6210\u5458\u3002 Test . func2 = lambda self , p , q : print ( p + 3 * q + self . a ) test = Test () test . func1 ( 1 , 1 ) # 4 test . func2 ( 1 , 3 ) # 11 \u79c1\u6709\u53d8\u91cf Private Variables \u00b6 \u90a3\u79cd\u4ec5\u9650\u4ece\u4e00\u4e2a\u5bf9\u8c61\u5185\u90e8\u8bbf\u95ee\u7684\u201c\u79c1\u6709\u201d\u5b9e\u4f8b\u53d8\u91cf\uff08\u201cPrivate\u201d instance variables\uff09\u5728 Python \u4e2d\u5e76\u4e0d\u5b58\u5728\u3002 \u4f46\u662f\uff0c\u5927\u591a\u6570 Python \u4ee3\u7801\u90fd\u9075\u5faa\u8fd9\u6837\u4e00\u4e2a\u7ea6\u5b9a\uff1a\u5e26\u6709*\u4e00\u4e2a\u524d\u7f00\u4e0b\u5212\u7ebf*\u7684\u540d\u79f0 (\u4f8b\u5982 _spam ) \u5e94\u8be5\u88ab\u5f53\u4f5c\u662f API \u7684\u975e\u516c\u6709\uff08non-public\uff09\u90e8\u5206 (\u65e0\u8bba\u5b83\u662f\u51fd\u6570\u3001\u65b9\u6cd5\u6216\u662f\u6570\u636e\u6210\u5458)\u3002 \u8fd9\u5e94\u5f53\u88ab\u89c6\u4e3a\u4e00\u4e2a\u5b9e\u73b0\u7ec6\u8282\uff0c\u53ef\u80fd\u4e0d\u7ecf\u901a\u77e5\u5373\u52a0\u4ee5\u6539\u53d8\u3002 \u7531\u4e8e\u5b58\u5728\u5bf9\u4e8e\u7c7b\u79c1\u6709\u6210\u5458\uff08class-private members\uff09\u7684\u6709\u6548\u4f7f\u7528\u573a\u666f\uff08\u4f8b\u5982\u907f\u514d\u540d\u79f0\u4e0e\u5b50\u7c7b\u6240\u5b9a\u4e49\u7684\u540d\u79f0\u76f8\u51b2\u7a81\uff09\uff0c\u56e0\u6b64\u5b58\u5728\u5bf9\u6b64\u79cd\u673a\u5236\u7684\u6709\u9650\u652f\u6301\uff0c\u79f0\u4e3a**\u540d\u79f0\u6539\u5199\uff08name mangling\uff09**\u3002 \u4efb\u4f55\u5f62\u5f0f\u4e3a __spam \u7684\u6807\u8bc6\u7b26\uff08\u81f3\u5c11\u5e26\u6709*\u4e24\u4e2a\u524d\u7f00\u4e0b\u5212\u7ebf*\uff0c\u81f3\u591a\u4e00\u4e2a\u540e\u7f00\u4e0b\u5212\u7ebf\uff09\u7684\u6587\u672c\u5c06\u88ab\u66ff\u6362\u4e3a _classname__spam \uff0c\u5176\u4e2d classname \u4e3a\u53bb\u9664\u4e86\u524d\u7f00\u4e0b\u5212\u7ebf\u7684\u5f53\u524d\u7c7b\u540d\u79f0\u3002 \u8fd9\u79cd\u6539\u5199\u4e0d\u8003\u8651\u6807\u8bc6\u7b26\u7684\u53e5\u6cd5\u4f4d\u7f6e\uff0c\u53ea\u8981\u5b83\u51fa\u73b0\u5728\u7c7b\u5b9a\u4e49\u5185\u90e8\u5c31\u4f1a\u8fdb\u884c\u3002 \u540d\u79f0\u6539\u5199\uff08Name mangling\uff09\u6709\u52a9\u4e8e\u8ba9\u5b50\u7c7b\u91cd\u8f7d\u65b9\u6cd5\uff08\uff09override methods\u800c\u4e0d\u7834\u574f\u7c7b\u5185\u65b9\u6cd5\uff08intraclass method\uff09\u8c03\u7528\u3002\u4f8b\u5982: class Mapping : def __init__ ( self , iterable ): self . items_list = [] self . __update ( iterable ) def update ( self , iterable ): for item in iterable : self . items_list . append ( item ) __update = update # private copy of original update() method class MappingSubclass ( Mapping ): def update ( self , keys , values ): # provides new signature for update() # but does not break __init__() for item in zip ( keys , values ): self . items_list . append ( item ) \u4e0a\u9762\u7684\u793a\u4f8b\u5373\u4f7f\u5728 MappingSubclass \u5f15\u5165\u4e86\u4e00\u4e2a __update \u6807\u8bc6\u7b26\u7684\u60c5\u51b5\u4e0b\u4e5f\u4e0d\u4f1a\u51fa\u9519\uff0c\u56e0\u4e3a\u5b83\u4f1a\u5728 Mapping \u7c7b\u4e2d\u88ab\u66ff\u6362\u4e3a _Mapping__update \u800c\u5728 MappingSubclass \u7c7b\u4e2d\u88ab\u66ff\u6362\u4e3a _MappingSubclass__update \u3002 \u8bf7\u6ce8\u610f\uff0c\u6539\u5199\u89c4\u5219\uff08mangling rules\uff09\u7684\u8bbe\u8ba1\u4e3b\u8981\u662f\u4e3a\u4e86\u907f\u514d\u610f\u5916\u51b2\u7a81\uff1b\u8bbf\u95ee\u6216\u4fee\u6539\u79c1\u6709\u53d8\u91cf\u4ecd\u7136\u662f\u53ef\u80fd\u7684\u3002\u8fd9\u5728\u7279\u6b8a\u60c5\u51b5\u4e0b\u751a\u81f3\u4f1a\u5f88\u6709\u7528\uff0c\u4f8b\u5982\u5728\u8c03\u8bd5\u5668\uff08debugger\uff09\u4e2d\u3002 \u8bf7\u6ce8\u610f\u4f20\u9012\u7ed9 exec() \u6216 eval() \u7684\u4ee3\u7801\u4e0d\u4f1a\u628a\u53d1\u8d77\u8c03\u7528\u7c7b\u7684\u7c7b\u540d\u89c6\u4f5c\u5f53\u524d\u7c7b\uff1b\u8fd9\u7c7b\u4f3c\u4e8e global \u8bed\u53e5\u7684\u6548\u679c\uff0c\u56e0\u6b64\u8fd9\u79cd\u6548\u679c\u4ec5\u9650\u4e8e\u540c\u65f6\u7ecf\u8fc7\u5b57\u8282\u7801\u7f16\u8bd1\u7684\u4ee3\u7801\u3002 \u540c\u6837\u7684\u9650\u5236\u4e5f\u9002\u7528\u4e8e getattr() , setattr() \u548c delattr() \uff0c\u4ee5\u53ca\u5bf9\u4e8e __dict__ \u7684\u76f4\u63a5\u5f15\u7528\u3002 \u53cd\u5c04(reflection) \u00b6 \u53cd\u5c04(reflection)\u662f\u52a8\u6001\u8bed\u8a00\u7684\u4e00\u4e2a\u7279\u6027\u3002**\u53cd\u5c04\u673a\u5236**\u6307\u7684\u662f\u5728\u7a0b\u5e8f\u7684\u8fd0\u884c\u72b6\u6001\u4e2d\uff0c\u5bf9\u4e8e\u4efb\u610f\u4e00\u4e2a\u7c7b\uff0c\u90fd\u53ef\u4ee5\u77e5\u9053\u8fd9\u4e2a\u7c7b\u7684\u6240\u6709\u5c5e\u6027\u548c\u65b9\u6cd5\uff1b\u5bf9\u4e8e\u4efb\u610f\u4e00\u4e2a\u5bf9\u8c61\uff0c\u90fd\u80fd\u591f\u8c03\u7528\u4ed6\u7684\u4efb\u610f\u65b9\u6cd5\u548c\u5c5e\u6027\u3002\u8fd9\u79cd\u52a8\u6001\u83b7\u53d6\u7a0b\u5e8f\u4fe1\u606f\u4ee5\u53ca\u52a8\u6001\u8c03\u7528\u5bf9\u8c61\u7684\u529f\u80fd\u79f0\u4e3a\u53cd\u5c04\u673a\u5236\u3002 \u901a\u8fc7\u4e0b\u9762\u4f8b\u5b50\u53ef\u77e5\uff0c\u901a\u8fc7 dir(person) \u83b7\u53d6\u4efb\u610f\u4e00\u4e2a\u7c7b\u6216\u8005\u5bf9\u8c61\u7684\u5c5e\u6027\u5217\u8868\u3002\u901a\u8fc7\u5185\u7f6e\u51fd\u6570 hasattr \u3001 getattr \u3001 setattr \u3001 delattr \u64cd\u4f5c\u7c7b\u548c\u5bf9\u8c61\u3002 class Person : def __init__ ( self , name , age , gender ): self . name = name self . age = age self . gender = gender person = Person ( 'Tom' , 21 , 'Male' ) print ( dir ( person )) # ['__class__', '__delattr__', '__dict__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__gt__', '__hash__', '__init__', '__init_subclass__', '__le__', '__lt__', '__module__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', '__weakref__', 'age', 'gender', 'name'] # hasattr(object,'name') # \u6309\u5b57\u7b26\u4e32'name'\u5224\u65ad\u6709\u65e0\u5c5e\u6027person.name hasattr ( person , 'name' ) # True # getattr(object, 'name', default=None) # \u7b49\u540c\u4e8eperson.name,\u4e0d\u5b58\u5728\u8be5\u5c5e\u6027\u5219\u8fd4\u56de\u9ed8\u8ba4\u503cNone getattr ( person , 'name' , None ) # 'Tom' # setattr(x, 'y', v) # \u7b49\u540c\u4e8eperson.age = 18 setattr ( person , 'age' , 18 ) print ( person . age ) # 18 # delattr(x, 'y') # \u7b49\u540c\u4e8edel person.age delattr ( person , 'age' ) print ( person . age ) # AttributeError: 'Person' object has no attribute 'age' \u4e0b\u9762\u662f\u4e00\u4e2a\u5b9e\u9645\u5e94\u7528\u7684\u4f8b\u5b50\u3002 class FtpServer (): def server_run ( self ): while True : inp = input ( 'Input your command >>:' ) . strip () cmd , file = inp . split () if hasattr ( self , cmd ): func = getattr ( self , cmd ) func ( file ) def get ( self , file ): print ( f 'Downloading { file } ...' ) def put ( self , file ): print ( f 'Uploading { file } ...' ) ftp_server = FtpServer () ftp_server . server_run () # Input your command >>:get a.ext # Downloading a.ext... # Input your command >>:put a.txt # Uploading a.txt... \u8fed\u4ee3\u5668 Iterators \u00b6 \u5728Python\u4e2d\uff0c\u5927\u591a\u6570\u5bb9\u5668\u5bf9\u8c61\uff08container object\uff09\u90fd\u53ef\u4ee5\u4f7f\u7528 for \u8bed\u53e5: for element in [ 1 , 2 , 3 ]: print ( element ) for element in ( 1 , 2 , 3 ): print ( element ) for key in { 'one' : 1 , 'two' : 2 }: print ( key ) for char in \"123\" : print ( char ) for line in open ( \"myfile.txt\" ): print ( line , end = '' ) for \u8bed\u53e5\u4f1a\u5728\u5bb9\u5668\u5bf9\u8c61\u4e0a\u8c03\u7528 iter()\u3002 \u8be5\u51fd\u6570\u8fd4\u56de\u4e00\u4e2a\u5b9a\u4e49\u4e86 __next__() \u65b9\u6cd5\u7684\u8fed\u4ee3\u5668\u5bf9\u8c61\uff0c\u6b64\u65b9\u6cd5\u5c06\u9010\u4e00\u8bbf\u95ee\u5bb9\u5668\u4e2d\u7684\u5143\u7d20\u3002 \u5f53\u5143\u7d20\u7528\u5c3d\u65f6\uff0c __next__() \u5c06\u5f15\u53d1 StopIteration \u5f02\u5e38\u6765\u901a\u77e5\u7ec8\u6b62 for \u5faa\u73af\u3002 \u53ef\u4ee5\u4f7f\u7528 next() \u5185\u7f6e\u51fd\u6570\u6765\u8c03\u7528 __next__() \u65b9\u6cd5\uff1b\u4e0b\u9762\u8fd9\u4e2a\u4f8b\u5b50\u5c55\u793a\u4e86\u521a\u521a\u63cf\u8ff0\u7684\u5177\u4f53\u8fd0\u884c\u65b9\u5f0f: >>> s = 'abc' >>> it = iter ( s ) >>> it < str_iterator object at 0x10c90e650 > >>> next ( it ) 'a' >>> next ( it ) 'b' >>> next ( it ) 'c' >>> next ( it ) Traceback ( most recent call last ): File \"\" , line 1 , in < module > next ( it ) StopIteration \u5728\u4e86\u89e3\u4e86\u8fed\u4ee3\u5668\u534f\u8bae\uff08iterator protocol\uff09\u7684\u673a\u5236\u540e\uff0c\u7ed9\u7c7b\u6dfb\u52a0\u8fed\u4ee3\u5668\u5c31\u5f88\u5bb9\u6613\u4e86\u3002 \u5b9a\u4e49\u4e00\u4e2a __iter__() \u65b9\u6cd5\u6765\u8fd4\u56de\u4e00\u4e2a\u5e26\u6709 __next__() \u65b9\u6cd5\u7684\u5bf9\u8c61\u3002 \u5982\u679c\u7c7b\u5df2\u5b9a\u4e49\u4e86 __next__() \uff0c\u5219 __iter__() \u53ef\u4ee5\u7b80\u5355\u5730\u8fd4\u56de self : class Reverse : \"\"\"Iterator for looping over a sequence backwards.\"\"\" def __init__ ( self , data ): self . data = data self . index = len ( data ) def __iter__ ( self ): return self def __next__ ( self ): if self . index == 0 : raise StopIteration self . index = self . index - 1 return self . data [ self . index ] rev = Reverse ( 'spam' ) print ( iter ( rev )) for char in rev : print ( char ) # m # a # p # s \u751f\u6210\u5668 Generators \u00b6 **\u751f\u6210\u5668\uff08Generators\uff09**\u662f\u4e00\u4e2a\u7528\u4e8e\u521b\u5efa\u8fed\u4ee3\u5668\u7684\u7b80\u5355\u800c\u5f3a\u5927\u7684\u5de5\u5177\u3002 \u5b83\u4eec\u7684\u5199\u6cd5\u7c7b\u4f3c\u4e8e\u6807\u51c6\u7684\u51fd\u6570\uff0c\u4f46\u5f53\u5b83\u4eec\u8981\u8fd4\u56de\u6570\u636e\u65f6\u4f1a\u4f7f\u7528 yield \u8bed\u53e5\u3002 \u6bcf\u6b21\u5728\u751f\u6210\u5668\u4e0a\u8c03\u7528 next() \u65f6\uff0c\u5b83\u4f1a\u4ece\u4e0a\u6b21\u79bb\u5f00\u7684\u4f4d\u7f6e\u6062\u590d\u6267\u884c\uff08\u5b83\u4f1a\u8bb0\u4f4f\u4e0a\u6b21\u6267\u884c\u8bed\u53e5\u65f6\u7684\u6240\u6709\u6570\u636e\u503c\uff09\u3002 \u4e00\u4e2a\u521b\u5efa\u751f\u6210\u5668\u7684\u793a\u4f8b\u5982\u4e0b\uff08\u6539\u5199\u4e0a\u9762\u8fed\u4ee3\u5668\u4e2d\u6240\u4e3e\u7684\u4f8b\u5b50\uff09: def reverse ( data ): for index in range ( len ( data ) - 1 , - 1 , - 1 ): yield data [ index ] for char in reverse ( 'golf' ): print ( char ) # f # l # o # g \u53ef\u4ee5\u7528\u751f\u6210\u5668\u6765\u5b8c\u6210\u7684\u64cd\u4f5c\u540c\u6837\u53ef\u4ee5\u7528\u524d\u9762\u6240\u63cf\u8ff0\u7684\u57fa\u4e8e\u7c7b\u7684\u8fed\u4ee3\u5668\u6765\u5b8c\u6210\u3002\u4f46\u751f\u6210\u5668\u7684\u5199\u6cd5\u66f4\u4e3a\u7d27\u51d1\uff0c\u56e0\u4e3a\u5b83\u4f1a\u81ea\u52a8\u521b\u5efa __iter__() \u548c __next__() \u65b9\u6cd5\u3002 \u53e6\u4e00\u4e2a\u5173\u952e\u7279\u6027\u5728\u4e8e\u5c40\u90e8\u53d8\u91cf\u548c\u6267\u884c\u72b6\u6001\u4f1a\u5728\u6bcf\u6b21\u8c03\u7528\u4e4b\u95f4\u81ea\u52a8\u4fdd\u5b58\u3002 \u8fd9\u4f7f\u5f97\u8be5\u51fd\u6570\u76f8\u6bd4\u4f7f\u7528 self.index \u548c self.data \u8fd9\u79cd\u5b9e\u4f8b\u53d8\u91cf\u7684\u65b9\u5f0f\u66f4\u6613\u7f16\u5199\u4e14\u66f4\u4e3a\u6e05\u6670\u3002 \u9664\u4e86\u4f1a\u81ea\u52a8\u521b\u5efa\u65b9\u6cd5\u548c\u4fdd\u5b58\u7a0b\u5e8f\u72b6\u6001\uff0c\u5f53\u751f\u6210\u5668\u7ec8\u7ed3\u65f6\uff0c\u5b83\u4eec\u8fd8\u4f1a\u81ea\u52a8\u5f15\u53d1 StopIteration \u3002 \u751f\u6210\u5668\u8868\u8fbe\u5f0f Generator Expressions \u00b6 \u67d0\u4e9b\u7b80\u5355\u7684\u751f\u6210\u5668\u53ef\u4ee5\u5199\u6210\u7b80\u6d01\u7684\u8868\u8fbe\u5f0f\u4ee3\u7801\uff0c\u6240\u7528\u8bed\u6cd5\u7c7b\u4f3c\u5217\u8868\u63a8\u5bfc\u5f0f\uff0c\u4f46\u5916\u5c42\u4e3a\u5706\u62ec\u53f7\u800c\u975e\u65b9\u62ec\u53f7\u3002 \u8fd9\u79cd\u8868\u8fbe\u5f0f\u88ab\u8bbe\u8ba1\u7528\u4e8e\u751f\u6210\u5668\u5c06\u7acb\u5373\u88ab\u5916\u5c42\u51fd\u6570\u6240\u4f7f\u7528\u7684\u60c5\u51b5\u3002 \u751f\u6210\u5668\u8868\u8fbe\u5f0f\u76f8\u6bd4\u5b8c\u6574\u7684\u751f\u6210\u5668\u66f4\u7d27\u51d1\u4f46\u8f83\u4e0d\u7075\u6d3b\uff0c\u76f8\u6bd4\u7b49\u6548\u7684\u5217\u8868\u63a8\u5bfc\u5f0f\u5219\u66f4\u4e3a\u8282\u7701\u5185\u5b58\u3002 \u793a\u4f8b: >>> sum ( i * i for i in range ( 10 )) # sum of squares 285 >>> xvec = [ 10 , 20 , 30 ] >>> yvec = [ 7 , 5 , 3 ] >>> sum ( x * y for x , y in zip ( xvec , yvec )) # dot product 260 >>> unique_words = set ( word for line in page for word in line . split ()) >>> valedictorian = max (( student . gpa , student . name ) for student in graduates ) >>> data = 'golf' >>> list ( data [ i ] for i in range ( len ( data ) - 1 , - 1 , - 1 )) [ 'f' , 'l' , 'o' , 'g' ] \u5143\u7c7b\uff08metaclass\uff09 \u00b6 \u6240\u6709\u7684\u5bf9\u8c61\u90fd\u662f\u5b9e\u4f8b\u5316\u6216\u8005\u8bf4\u8c03\u7528\u7c7b\u800c\u5f97\u5230\u7684\uff08\u8c03\u7528\u7c7b\u7684\u8fc7\u7a0b\u79f0\u4e3a\u7c7b\u7684\u5b9e\u4f8b\u5316\u3002 class StandfordProfessor ( object ): university = 'Standford' def __init__ ( self , name , gender ): self . name = name self . gender = gender def display ( self ): print ( f 'Professor { self . name } says welcome to { self . university } !' ) professor = StandfordProfessor ( 'Tom' , 'Male' ) \u4e0a\u4f8b\u4e2d\uff0c\u5bf9\u8c61 professor \u662f\u8c03\u7528\u7c7b StandfordProfessor \u5f97\u5230\u7684\u3002\u7c7b StandfordProfessor \u672c\u8d28\u4e5f\u662f\u4e00\u4e2a\u5bf9\u8c61\uff0c \u4e0b\u9762\u53ef\u4ee5\u9a8c\u8bc1\uff0c StandfordProfessor \u662f\u8c03\u7528\u4e86\u5185\u7f6e\u7684\u7c7b type \u5f97\u5230\u7684\u3002\u8fd9\u4e2a type \u79f0\u4e3a\u5143\u7c7b\u3002 print ( type ( StandfordProfessor )) # \u5982\u679c\u4e00\u4e2a\u7c7b\u6ca1\u6709\u58f0\u660e\u81ea\u5df1\u7684\u5143\u7c7b\uff0c\u9ed8\u8ba4\u5b83\u7684\u5143\u7c7b\u5c31\u662f type \uff0c\u9664\u4e86\u4f7f\u7528\u5185\u7f6e\u5143\u7c7b type \uff0c\u6211\u4eec\u4e5f\u53ef\u4ee5\u901a\u8fc7\u7ee7\u627f type \u6765\u81ea\u5b9a\u4e49\u5143\u7c7b\uff0c\u7136\u540e\u4f7f\u7528 metaclass \u5173\u952e\u5b57\u53c2\u6570\u4e3a\u4e00\u4e2a\u7c7b\u7684\u6307\u5b9a\u5143\u7c7b\u3002 \u53ea\u6709\u7ee7\u627f\u4e86type\u7c7b\u624d\u80fd\u79f0\u4e4b\u4e3a\u4e00\u4e2a\u5143\u7c7b\uff0c\u5426\u5219\u5c31\u662f\u4e00\u4e2a\u666e\u901a\u7684\u81ea\u5b9a\u4e49\u7c7b\u3002 class Mymeta ( type ): pass class StandfordProfessor ( object , metaclass = Mymeta ): university = 'Standford' def __init__ ( self , name , gender ): self . name = name self . gender = gender def display ( self ): print ( f 'Professor { self . name } says welcome to { self . university } !' ) professor = StandfordProfessor ( 'Tom' , 'Male' ) \u4e0b\u9762\u8fdb\u884c\u81ea\u5b9a\u4e49\u5143\u7c7b\uff0c\u63a7\u5236\u7c7b StandfordProfessor \u7684\u8c03\u7528\u3002 \u8981\u60f3\u8ba9 professor \u8fd9\u4e2a\u5bf9\u8c61\u53d8\u6210\u4e00\u4e2a\u53ef\u8c03\u7528\u7684\u5bf9\u8c61\uff0c\u9700\u8981\u5728\u8be5\u5bf9\u8c61\u7684\u7c7b\u4e2d\u5b9a\u4e49\u4e00\u4e2a\u65b9\u6cd5 __call__ \uff0c\u8be5\u65b9\u6cd5\u4f1a\u5728\u8c03\u7528\u5bf9\u8c61\u65f6\u81ea\u52a8\u89e6\u53d1\u3002\u8c03\u7528 professor \u7684\u8fd4\u56de\u503c\u5c31\u662f __call__ \u65b9\u6cd5\u7684\u8fd4\u56de\u503c\u3002 class Mymeta ( type ): def __call__ ( self , * args , ** kwargs ): print ( self ) # \u7c7b\u540d print ( args ) # \u8f93\u5165\u53c2\u6570 print ( kwargs ) # \u8f93\u5165\u53c2\u6570 return 10086 class StandfordProfessor ( object , metaclass = Mymeta ): university = 'Standford' def __init__ ( self , name , gender ): self . name = name self . gender = gender def display ( self ): print ( f 'Professor { self . name } says welcome to { self . university } !' ) professor = StandfordProfessor ( 'Tom' , 'Male' ) # # ('Tom', 'Male') # {} \u7c7b\u7684\u4ea7\u751f\u8fc7\u7a0b\u5176\u5b9e\u5c31\u662f\u5143\u7c7b\u7684\u8c03\u7528\u8fc7\u7a0b,\u5373 StandfordProfessor = Mymeta('StandfordProfessor', (object), {...}) \uff0c\u8c03\u7528 Mymeta \u4f1a\u5148\u4ea7\u751f\u4e00\u4e2a\u7a7a\u5bf9\u8c61 StandfordProfessor \uff0c\u7136\u540e\u8fde\u540c\u8c03\u7528 Mymeta \u62ec\u53f7\u5185\u7684\u53c2\u6570\u4e00\u540c\u4f20\u7ed9 Mymeta \u4e0b\u7684 __init__ \u65b9\u6cd5\uff0c\u5b8c\u6210\u521d\u59cb\u5316\u3002\u6211\u4eec\u53ef\u4ee5\u57fa\u4e8e\u4e0a\u4f8b\u505a\u5982\u4e0b\u6539\u5199\u3002 class Mymeta ( type ): def __init__ ( self , class_name , class_bases , class_dic ): super ( Mymeta , self ) . __init__ ( class_name , class_bases , class_dic ) if class_name . islower (): raise TypeError ( f 'Please follow Camel-Case to change class name { class_name } ' ) if '__doc__' not in class_dic or len ( class_dic [ '__doc__' ] . strip ( ' \\n ' )) == 0 : raise TypeError ( 'Please add documentation in class {class_name} , which is mandatory.' ) class StandfordProfessor ( object , metaclass = Mymeta ): \"\"\" Documentation of class StanfordTeacher \"\"\" university = 'Standford' def __init__ ( self , name , gender ): self . name = name self . gender = gender def display ( self ): print ( f 'Professor { self . name } says welcome to { self . university } !' ) professor = StandfordProfessor ( 'Tom' , 'Male' ) professor . display () # Professor Tom says welcome to Standford! print ( professor . __dict__ ) # {'name': 'Tom', 'gender': 'Male'} StandfordProfessor . mro () # [, ]","title":"Python\u9762\u5411\u5bf9\u8c61\u4e09\u5927\u7279\u6027"},{"location":"python/Foundation/ch05/#python","text":"Python\u9762\u5411\u5bf9\u8c61\u4e09\u5927\u7279\u6027\uff1a \u5c01\u88c5 \u7ee7\u627f \u591a\u6001","title":"Python\u9762\u5411\u5bf9\u8c61\u4e09\u5927\u7279\u6027"},{"location":"python/Foundation/ch05/#encapsulation","text":"\u5c01\u88c5\u662f\u4f7f\u7528\u7279\u6b8a\u7684\u8bed\u6cd5\uff0c\u5bf9\u6210\u5458\u5c5e\u6027\u548c\u6210\u5458\u65b9\u6cd5\u8fdb\u884c\u5305\u88c5\uff0c\u9650\u5236\u4e00\u4e9b\u8bbf\u95ee\u548c\u64cd\u4f5c\uff0c\u8fbe\u5230\u4fdd\u62a4\u548c\u9690\u85cf\u7684\u76ee\u7684\u3002 \u5c01\u88c5\u673a\u5236\u4fdd\u8bc1\u4e86\u7c7b\u5185\u90e8\u6570\u636e\u7ed3\u6784\u7684\u5b8c\u6574\u6027\uff0c\u56e0\u4e3a\u4f7f\u7528\u7c7b\u7684\u7528\u6237\u65e0\u6cd5\u76f4\u63a5\u770b\u5230\u7c7b\u4e2d\u7684\u6570\u636e\u7ed3\u6784\uff0c\u53ea\u80fd\u4f7f\u7528\u7c7b\u5141\u8bb8\u516c\u5f00\u7684\u6570\u636e\uff0c\u5f88\u597d\u5730\u907f\u514d\u4e86\u5916\u90e8\u5bf9\u5185\u90e8\u6570\u636e\u7684\u5f71\u54cd\uff0c\u63d0\u9ad8\u4e86\u7a0b\u5e8f\u7684\u53ef\u7ef4\u62a4\u6027\u3002 \u5bf9\u4e00\u4e2a\u7c7b\u5b9e\u73b0\u826f\u597d\u7684\u5c01\u88c5\uff0c\u7528\u6237\u53ea\u80fd\u501f\u52a9\u66b4\u9732\u51fa\u6765\u7684\u7c7b\u65b9\u6cd5\u6765\u8bbf\u95ee\u6570\u636e\uff0c\u53ef\u4ee5\u5728\u8fd9\u4e9b\u66b4\u9732\u7684\u65b9\u6cd5\u4e2d\u52a0\u5165\u9002\u5f53\u7684\u63a7\u5236\u903b\u8f91\uff0c\u5373\u53ef\u63a7\u5236\u7528\u6237\u5bf9\u7c7b\u4e2d\u5c5e\u6027\u6216\u65b9\u6cd5\u7684\u64cd\u4f5c\u3002 \u5bf9\u7c7b\u8fdb\u884c\u826f\u597d\u7684\u5c01\u88c5\uff0c\u4e3b\u8981\u662f\u5185\u90e8\u4f7f\u7528\u5c01\u88c5\u7684\u6210\u5458\uff0c\u4e5f\u63d0\u9ad8\u4e86\u4ee3\u7801\u7684\u590d\u7528\u6027\u3002 \u7c7b\u6210\u5458\u5c01\u88c5\u7684\u7ea7\u522b\uff1a \u516c\u6709\u7684\uff08public\uff09 \u4fdd\u62a4\u7684\uff08protected\uff09\uff0c\u5728Python\u4e2d\u5e76\u6ca1\u6709\u5b9e\u73b0protected\u5c01\u88c5\uff0c\u5c5e\u4e8e\u5f00\u53d1\u8005\u7684\u7ea6\u5b9a\u4fd7\u6210\u3002 \u79c1\u6709\u7684\uff08private\uff09\uff0c\u5728Python\u4e2dprivate\u5c01\u88c5\u662f\u901a\u8fc7\u6539\u540d\u7b56\u7565\u6765\u5b9e\u73b0\u7684\uff0c\u5e76\u4e0d\u662f\u771f\u6b63\u7684\u79c1\u6709\u5316\u3002 \u8bbf\u95ee\u9650\u5236 \u5171\u6709\u7684public \u53d7\u4fdd\u62a4\u7684protected \u79c1\u6709\u7684private \u5728\u7c7b\u7684\u5185\u90e8 OK OK OK \u5728\u7c7b\u7684\u5916\u90e8 OK No (Python\u4e2d\u53ef\u4ee5) No \u770b\u4e0b\u9762\u7684\u4f8b\u5b50\u3002(\u53c2\u8003 \u79c1\u6709\u53d8\u91cfPrivate Variables ) name \u662f\u5171\u6709\u5c5e\u6027\uff0c\u53ef\u4ee5\u5728\u5916\u90e8\u8c03\u7528tom.name\u3002 _age \u662f\u53d7\u4fdd\u62a4\u7684\u5c5e\u6027\uff0c\u7406\u8bba\u4e0a\u5728\u5916\u90e8\u662f\u4e0d\u53ef\u8c03\u7528\u7684\uff0c\u4f46\u5728Python\u4e2d\u662f\u53ef\u4ee5\u8c03\u7528\u7684 tom._age \u3002 __phone \u662f\u79c1\u6709\u5c5e\u6027\uff0c\u5728\u5916\u90e8\u662f\u4e0d\u53ef\u8c03\u7528\u7684\uff0c tom.__get_phone() \u62a5\u9519\u201c\u5c5e\u6027\u4e0d\u5b58\u5728\u201d\u3002 \u5bf9\u5e94\u65b9\u6cd5\u4e5f\u662f\u7c7b\u4f3c\u3002 \u5728\u7c7b\u7684\u5185\u90e8\u5bf9\u53d7\u4fdd\u62a4\u5bf9\u8c61\u548c\u79c1\u6709\u5bf9\u8c61\u6ca1\u6709\u8bbf\u95ee\u9650\u5236\u3002 _get_age \u53ef\u4ee5\u8c03\u7528\u79c1\u6709\u5c5e\u6027 __phone \u3002 class Person (): name = 'name' # public _age = 0 # protected __phone = 'phone' # private def __init__ ( self , n , a , p ): self . name = n self . _age = a self . __phone = p def get_name ( self ): print ( f 'My name is { self . name } ' ) def _get_age ( self ): print ( f 'My age is { self . _age } ' ) print ( f 'My age is { self . __phone } ' ) def __get_phone ( self ): print ( f 'My phone is { self . __phone } ' ) tom = Person ( 'Tom' , 18 , 12345678 ) tom . name # 'Tom' tom . _age # 18 tom . __phone # AttributeError: 'Person' object has no attribute '__phone' tom . get_name () # My name is Tom tom . _get_age () # My age is 18 # My age is 12345678 tom . __get_phone () # AttributeError: 'Person' object has no attribute '__get_phone'","title":"\u5c01\u88c5 Encapsulation"},{"location":"python/Foundation/ch05/#inheritance","text":"\u5728\u4e0d\u6307\u5b9a\u7ee7\u627f\u7684\u7236\u7c7b\u65f6\uff0c\u6240\u6709\u7c7b\u90fd\u7ee7\u627fobject\u7c7b\uff08\u7cfb\u7edf\u63d0\u4f9b\uff09\u3002 \u88ab\u5176\u5b83\u7c7b\u7ee7\u627f\u7684\u7c7b\uff0c\u79f0\u4e3a\u7236\u7c7b\uff0c\u6216\u8005\u57fa\u7c7b\uff0c\u6216\u8005\u8d85\u7c7b\u3002 \u7ee7\u627f\u5176\u5b83\u7c7b\u7684\u7c7b\uff0c\u79f0\u4e3a\u5b50\u7c7b\uff0c\u6216\u8005\u6d3e\u751f\u7c7b\uff08derived class\uff09\u3002 \u5b50\u7c7b\u7ee7\u627f\u7236\u7c7b\u540e\uff0c\u5c31\u62e5\u6709\u4e86\u7236\u7c7b\u4e2d\u7684\u6240\u6709\u6210\u5458\uff08\u9664\u4e86\u79c1\u6709\u6210\u5458\uff09\u3002 \u5b50\u7c7b\u7ee7\u627f\u7236\u7c7b\u540e\uff0c\u5e76\u4e0d\u4f1a\u628a\u7236\u7c7b\u7684\u6210\u5458\u590d\u5236\u7ed9\u5b50\u7c7b\uff0c\u800c\u662f\u5f15\u7528\u3002 \u5b50\u7c7b\u53ef\u4ee5\u76f4\u63a5\u8c03\u7528\u7236\u7c7b\u7684\u65b9\u6cd5 super().BaseClassName \u3002\u5982\u679c\u7236\u7c7b\u65b9\u6cd5\u6709\u53c2\u6570\u8981\u6c42\uff0c\u5b50\u7c7b\u8c03\u7528\u65f6\u4e5f\u6709\u53c2\u6570\u8981\u6c42\u3002 \u5b50\u7c7b\u7ee7\u627f\u7236\u7c7b\u540e\uff0c\u53ef\u4ee5\u91cd\u65b0\u5b9a\u4e49\u7236\u7c7b\u4e2d\u7684\u65b9\u6cd5\uff0c\u79f0\u4e3a**\u91cd\u5199\uff08Override\uff09**\u3002 \u5b50\u7c7b\u7ee7\u627f\u7236\u7c7b\u540e\uff0c\u5b9a\u4e49\u7236\u7c7b\u4e2d\u6ca1\u6709\u7684\u65b9\u6cd5\uff0c\u88ab\u79f0\u4e3a\u5bf9\u7236\u7c7b\u7684\u6269\u5c55\u3002 \u4e00\u4e2a\u7236\u7c7b\u53ef\u4ee5\u88ab\u591a\u4e2a\u5b50\u7c7b\u7ee7\u627f\u3002 **\u6d3e\u751f\u7c7b\uff08derived class\uff09**\u5b9a\u4e49\u7684\u8bed\u6cd5\u5982\u4e0b\u6240\u793a: class BaseClassName (): < statement - 1 > . . . < statement - N > class DerivedClassName ( BaseClassName ): < statement - 1 > . . . < statement - N > \u540d\u79f0 BaseClassName \u5fc5\u987b\u5b9a\u4e49\u4e8e\u5305\u542b\u6d3e\u751f\u7c7b\u5b9a\u4e49\u7684\u4f5c\u7528\u57df\u4e2d\u3002 \u4e5f\u5141\u8bb8\u7528\u5176\u4ed6\u4efb\u610f\u8868\u8fbe\u5f0f\u4ee3\u66ff\u57fa\u7c7b\u540d\u79f0\u6240\u5728\u7684\u4f4d\u7f6e\uff0c\u4f8b\u5982\uff0c\u5f53\u57fa\u7c7b\u5b9a\u4e49\u5728\u53e6\u4e00\u4e2a\u6a21\u5757\u4e2d\u7684\u65f6\u5019: class DerivedClassName ( modname . BaseClassName ): \u6d3e\u751f\u7c7b\u5b9a\u4e49\u7684\u6267\u884c\u8fc7\u7a0b\u4e0e\u57fa\u7c7b\u76f8\u540c\u3002 \u5f53\u6784\u9020\u7c7b\u5bf9\u8c61\u65f6\uff0c\u57fa\u7c7b\u4f1a\u88ab\u8bb0\u4f4f\u3002 \u6b64\u4fe1\u606f\u5c06\u88ab\u7528\u6765\u89e3\u6790\u5c5e\u6027\u5f15\u7528\uff1a\u5982\u679c\u8bf7\u6c42\u7684\u5c5e\u6027\u5728\u7c7b\u4e2d\u627e\u4e0d\u5230\uff0c\u641c\u7d22\u5c06\u8f6c\u5f80\u57fa\u7c7b\u4e2d\u8fdb\u884c\u67e5\u627e\u3002 \u5982\u679c\u57fa\u7c7b\u672c\u8eab\u4e5f\u6d3e\u751f\u81ea\u5176\u4ed6\u67d0\u4e2a\u7c7b\uff0c\u5219\u6b64\u89c4\u5219\u5c06\u88ab\u9012\u5f52\u5730\uff08recursively\uff09\u5e94\u7528\u3002 \u6d3e\u751f\u7c7b\u7684\u5b9e\u4f8b\u5316\u6ca1\u6709\u4efb\u4f55\u7279\u6b8a\u4e4b\u5904: DerivedClassName() \u4f1a\u521b\u5efa\u8be5\u7c7b\u7684\u4e00\u4e2a*\u65b0\u5b9e\u4f8b*\u3002 \u65b9\u6cd5\u5f15\u7528\u5c06\u6309\u4ee5\u4e0b\u65b9\u5f0f\u89e3\u6790\uff1a\u641c\u7d22\u76f8\u5e94\u7684\u7c7b\u5c5e\u6027\uff0c\u5982\u6709\u5fc5\u8981\u5c06\u6309\u57fa\u7c7b\u7ee7\u627f\u94fe\u9010\u6b65\u5411\u4e0b\u67e5\u627e\uff0c\u5982\u679c\u4ea7\u751f\u4e86\u4e00\u4e2a\u51fd\u6570\u5bf9\u8c61\u5219\u65b9\u6cd5\u5f15\u7528\u5c31\u751f\u6548\u3002 \u6d3e\u751f\u7c7b\u53ef\u80fd\u4f1a\u91cd\u5199\uff08override\uff09\u5176\u57fa\u7c7b\u7684\u65b9\u6cd5\u3002 \u56e0\u4e3a\u65b9\u6cd5\u5728\u8c03\u7528\u540c\u4e00\u5bf9\u8c61\u7684\u5176\u4ed6\u65b9\u6cd5\u65f6\u6ca1\u6709\u7279\u6b8a\u6743\u9650\uff0c\u6240\u4ee5\u8c03\u7528\u540c\u4e00\u57fa\u7c7b\u4e2d\u5b9a\u4e49\u7684\u53e6\u4e00\u65b9\u6cd5\u7684\u57fa\u7c7b\u65b9\u6cd5\u6700\u7ec8\u53ef\u80fd\u4f1a\u8c03\u7528\u8986\u76d6\u5b83\u7684\u6d3e\u751f\u7c7b\u7684\u65b9\u6cd5\u3002 \u5728\u6d3e\u751f\u7c7b\u4e2d\u7684\u91cd\u8f7d\u65b9\u6cd5\uff08overriding method\uff09\u5b9e\u9645\u4e0a\u53ef\u80fd\u60f3\u8981\u6269\u5c55\u800c\u975e\u7b80\u5355\u5730\u66ff\u6362\u540c\u540d\u7684\u57fa\u7c7b\u65b9\u6cd5\u3002 \u6709\u4e00\u79cd\u65b9\u5f0f\u53ef\u4ee5\u7b80\u5355\u5730\u76f4\u63a5\u8c03\u7528\u57fa\u7c7b\u65b9\u6cd5\uff1a\u5373\u8c03\u7528 BaseClassName.methodname(self, arguments) \u3002 \u8bf7\u6ce8\u610f\uff0c\u4ec5\u5f53\u6b64\u57fa\u7c7b\u53ef\u5728\u5168\u5c40\u4f5c\u7528\u57df\u4e2d\u4ee5 BaseClassName \u7684\u540d\u79f0\u88ab\u8bbf\u95ee\u65f6\u65b9\u53ef\u4f7f\u7528\u6b64\u65b9\u5f0f\u3002 Python\u6709\u4e24\u4e2a\u5185\u7f6e\u51fd\u6570\u53ef\u88ab\u7528\u4e8e\u7ee7\u627f\u673a\u5236\uff1a \u4f7f\u7528 isinstance() \u6765\u68c0\u67e5\u4e00\u4e2a\u5b9e\u4f8b\u7684\u7c7b\u578b: isinstance(obj, int) \u4ec5\u4f1a\u5728 obj.__class__ \u4e3a int \u6216\u67d0\u4e2a\u6d3e\u751f\u81ea int \u7684\u7c7b\u65f6\u4e3a True \u3002 \u4f7f\u7528 issubclass() \u6765\u68c0\u67e5\u7c7b\u7684\u7ee7\u627f\u5173\u7cfb: issubclass(bool, int) \u4e3a True \uff0c\u56e0\u4e3a bool \u662f int \u7684\u5b50\u7c7b\u3002 \u4f46\u662f\uff0c issubclass(float, int) \u4e3a False \uff0c\u56e0\u4e3a float \u4e0d\u662f int \u7684\u5b50\u7c7b\u3002","title":"\u7ee7\u627f Inheritance"},{"location":"python/Foundation/ch05/#multiple-inheritance","text":"\u5355\u7ee7\u627f\uff08single-inheritance\uff09\uff1a\u4e00\u4e2a\u7c7b\u53ea\u80fd\u7ee7\u627f\u4e00\u4e2a\u7236\u7c7b\u65b9\u5f0f\u3002 class DerivedClassName ( BaseClassName ): < statement - 1 > . . . < statement - N > \u591a\u7ee7\u627f\uff08Multiple Inheritance\uff09\uff1a\u4e00\u4e2a\u7c7b\u53bb\u7ee7\u627f\u591a\u4e2a\u7c7b\u7684\u65b9\u5f0f\u3002\u5b9a\u4e49\u8bed\u53e5\u5982\u4e0b\u6240\u793a class DerivedClassName ( Base1 , Base2 , Base3 ): < statement - 1 > . . . < statement - N > \u5728\u6700\u7b80\u5355\u7684\u60c5\u51b5\u4e0b\uff0c\u641c\u7d22\u4ece\u7236\u7c7b\u6240\u7ee7\u627f\u5c5e\u6027\u7684\u64cd\u4f5c\u662f\u6df1\u5ea6\u4f18\u5148\uff08depth-first\uff09\u3001\u4ece\u5de6\u81f3\u53f3\uff08left-to-right\uff09\u7684\uff0c\u5f53\u5c42\u6b21\u7ed3\u6784\u4e2d\u5b58\u5728\u91cd\u53e0\u65f6\u4e0d\u4f1a\u5728\u540c\u4e00\u4e2a\u7c7b\u4e2d\u641c\u7d22\u4e24\u6b21\u3002 \u56e0\u6b64\uff0c\u5982\u679c\u67d0\u4e00\u5c5e\u6027\u5728 DerivedClassName \u4e2d\u672a\u627e\u5230\uff0c\u5219\u4f1a\u5230 Base1 \u4e2d\u641c\u7d22\u5b83\uff0c\u7136\u540e\uff08\u9012\u5f52\u5730\uff09\u5230 Base1 \u7684\u57fa\u7c7b\u4e2d\u641c\u7d22\uff0c\u5982\u679c\u5728\u90a3\u91cc\u672a\u627e\u5230\uff0c\u518d\u5230 Base2 \u4e2d\u641c\u7d22\uff0c\u4f9d\u6b64\u7c7b\u63a8\u3002 \u771f\u5b9e\u60c5\u51b5\u66f4\u590d\u6742\uff1b\u65b9\u6cd5\u89e3\u6790\u987a\u5e8f\u4f1a\u52a8\u6001\u6539\u53d8\u4ee5\u652f\u6301\u5bf9 super() \u7684\u534f\u540c\u8c03\u7528\u3002 \u8fd9\u79cd\u65b9\u5f0f\u5728\u67d0\u4e9b\u5176\u4ed6\u591a\u91cd\u7ee7\u627f\u578b\u8bed\u8a00\u4e2d\u88ab\u79f0\u4e3a**\u540e\u7eed\u65b9\u6cd5\u8c03\u7528\uff08call-next-method\uff09**\uff0c\u5b83\u6bd4**\u5355\u7ee7\u627f\uff08single-inheritance\uff09**\u8bed\u8a00\u4e2d\u7684 uper \u8c03\u7528\u66f4\u5f3a\u5927\u3002 \u52a8\u6001\u6539\u53d8\u987a\u5e8f\u662f\u6709\u5fc5\u8981\u7684\uff0c\u56e0\u4e3a\u6240\u6709\u591a\u91cd\u7ee7\u627f\u7684\u60c5\u51b5\u90fd\u4f1a\u663e\u793a\u51fa\u4e00\u4e2a\u6216\u66f4\u591a\u7684\u83f1\u5f62\u5173\u8054\uff08diamond relationships\uff09\uff08\u5373\u81f3\u5c11\u6709\u4e00\u4e2a\u7236\u7c7b\u53ef\u901a\u8fc7\u591a\u6761\u8def\u5f84\u88ab\u6700\u5e95\u5c42\u7c7b\u6240\u8bbf\u95ee\uff09\u3002 \u4f8b\u5982\uff0c\u6240\u6709\u7c7b\u90fd\u662f\u7ee7\u627f\u81ea object \uff0c\u56e0\u6b64\u4efb\u4f55\u591a\u91cd\u7ee7\u627f\u7684\u60c5\u51b5\u90fd\u63d0\u4f9b\u4e86\u4e00\u6761\u4ee5\u4e0a\u7684\u8def\u5f84\u53ef\u4ee5\u901a\u5411 object \u3002 \u4e3a\u4e86\u786e\u4fdd\u57fa\u7c7b\u4e0d\u4f1a\u88ab\u8bbf\u95ee\u4e00\u6b21\u4ee5\u4e0a\uff0c\u52a8\u6001\u7b97\u6cd5\u4f1a\u7528\u4e00\u79cd\u7279\u6b8a\u65b9\u5f0f\u5c06\u641c\u7d22\u987a\u5e8f\u7ebf\u6027\u5316\uff0c \u4fdd\u7559\u6bcf\u4e2a\u7c7b\u6240\u6307\u5b9a\u7684\u4ece\u5de6\u81f3\u53f3\u7684\u987a\u5e8f\uff0c\u53ea\u8c03\u7528\u6bcf\u4e2a\u7236\u7c7b\u4e00\u6b21\uff0c\u5e76\u4e14\u4fdd\u6301\u5355\u8c03\uff08monotonic\uff09\uff08\u5373\u4e00\u4e2a\u7c7b\u53ef\u4ee5\u88ab\u5b50\u7c7b\u5316\u800c\u4e0d\u5f71\u54cd\u5176\u7236\u7c7b\u7684\u4f18\u5148\u987a\u5e8f\uff09\u3002 \u603b\u800c\u8a00\u4e4b\uff0c\u8fd9\u4e9b\u7279\u6027\u4f7f\u5f97\u8bbe\u8ba1\u5177\u6709\u591a\u91cd\u7ee7\u627f\u7684\u53ef\u9760\u4e14\u53ef\u6269\u5c55\u7684\u7c7b\u6210\u4e3a\u53ef\u80fd\u3002 \u770b\u4e0b\u9762\u4f8b\u5b50\uff0c\u5b9a\u4e49\u4e863\u4e2a\u7c7b\u548c\u7ee7\u627f\u5173\u7cfb\u3002 class F (): def drink ( self ): print ( \"Drink Beer\" ) class M (): def drink ( self ): print ( \"Drink Red Wine\" ) class C ( F , M ): def drink ( self ): print ( \"Drink Water\" ) \u6267\u884c\u7ed3\u679c\u662f c = C () c . drink () # Drink Water \u65b9\u6cd51\uff1a\u6309\u7167mro\u8fdb\u884c\u7ee7\u627f\u67e5\u627e\u3002 \u5982\u679c\u628a C \u7c7b\u6539\u5199\u4e3a\u5982\u4e0b\uff0c\u53ef\u4ee5\u8c03\u7528\u7236\u7c7b\uff0c\u53c2\u7167 C \u7c7b\u7684mro\u8fdb\u884c\uff0c mro \u91cc\u9762\u7c7b F \u7684\u4e0a\u4e00\u7ea7\u662f\u7c7b M \uff0c\u6240\u4ee5\u7c7b F \u4e2d\u7684 super() \u5c31\u662f\u6307\u7c7b M \u3002 class C ( F , M ): def drink ( self ): super () . drink () print ( \"Drink Water\" ) c = C () c . drink () # Drink Beer # Drink Water C . mro () # [, , , ] \u65b9\u6cd52\uff1a\u201c\u6307\u540d\u9053\u59d3\u201d\u8c03\u7528\u3002\u5982\u679c\u628a C \u7c7b\u6539\u5199\u4e3a\u5982\u4e0b\uff0c\u53ef\u4ee5\u8c03\u7528 M \u7c7b\u3002 class C ( F , M ): def drink ( self ): M . drink ( self ) print ( \"Drink Water\" ) c = C () c . drink () # Drink Red Wine # Drink Water","title":"\u591a\u91cd\u7ee7\u627f Multiple Inheritance"},{"location":"python/Foundation/ch05/#_1","text":"\u83f1\u5f62\u7ee7\u627f\u7684\u63cf\u8ff0\u662f\uff0c\u7c7b A \u4f5c\u4e3a\u57fa\u7c7b\uff08\u8fd9\u91cc\u57fa\u7c7b\u662f\u6307\u975e object \u7c7b\uff09\uff0c\u7c7b B \u548c\u7c7b C \u540c\u65f6\u7ee7\u627f\u7c7b A \uff0c\u7136\u540e\u7c7b D \u53c8\u7ee7\u627f\u7c7b B \u548c\u7c7b C \uff0c\u5982\u4e0b\u56fe\uff0c\u770b\u8d77\u6765\u50cf\u4e2a\u94bb\u77f3\u7684\u5f62\u72b6\u3002 A / \\ B C \\ / D \u5728\u8fd9\u79cd\u7ed3\u6784\u4e2d\uff0c\u5728\u8c03\u7528\u987a\u5e8f\u4e0a\u5c31\u4f1a\u51fa\u73b0\u7591\u60d1\uff0c\u8c03\u7528\u987a\u5e8f\u7a76\u7adf\u662f\u4ee5\u4e0b\u54ea\u4e00\u79cd\u987a\u5e8f\u5462\uff1f D->B->A->C\uff08\u6df1\u5ea6\u4f18\u5148\uff09 D->B->C->A\uff08\u5e7f\u5ea6\u4f18\u5148\uff09 \u770b\u4e0b\u9762\u4ee3\u7801\uff0c\u5728Python3\u4e2d\uff0c**\u83f1\u5f62**\u7684\u591a\u7ee7\u627f\u5173\u7cfb\u662f\u6309\u7167D->B->C->A**\u5e7f\u5ea6\u4f18\u5148**\u7684\u641c\u7d22\u65b9\u5f0f\u3002 class A (): pass class B ( A ): def test ( self ): print ( \"init B.test()\" ) class C ( A ): def test ( self ): print ( \"init C.test()\" ) class D ( B , C ): pass d = D () d . test () # init B.test() D . mro () # [, , , , ] \u5bf9\u4e8e\u4e0b\u9762\u8fd9\u79cd**\u975e\u83f1\u5f62**\u7684\u591a\u7ee7\u627f\u5173\u7cfb\uff0c\u67e5\u627e\u987a\u5e8f\u662fA->B->E->C->F->D**\u6df1\u5ea6\u4f18\u5148**\u7684\u641c\u7d22\u65b9\u5f0f\u3002 E F | | B ( E ) C ( F ) D | | | \\ | / \\ | / A ( B , C , D ) \u4ee3\u7801\u5b9e\u73b0\uff1a class D (): def test ( self ): print ( \"init D.test()\" ) class F (): def test ( self ): print ( \"init F.test()\" ) class C ( F ): pass class E (): pass class B ( E ): pass class A ( B , C , D ): pass a = A () a . test () # init F.test() A . mro () # [, , , , , , ] \u603b\u7ed3\uff1a \u7ee7\u627f\u7ed3\u6784\u8981\u5c3d\u91cf\u7b80\u5355\uff0c\u4e0d\u8981\u8fc7\u4e8e\u590d\u6742\u3002 \u63a8\u8350\u4f7f\u7528minxins\u673a\u5236\uff0c\u5728\u591a\u7ee7\u627f\u80cc\u666f\u4e0b\uff0c\u6ee1\u8db3\u7ee7\u627f\u7684\u4ec0\u4e48\u662f\u4ec0\u4e48\u7684\u5173\u7cfb\uff08is-a\uff09","title":"\u83f1\u5f62\u7ee7\u627f\u548c\u7ee7\u627f\u5173\u7cfb\u68c0\u6d4b"},{"location":"python/Foundation/ch05/#minxins","text":"\u770b\u4e0b\u9762\u4f8b\u5b50\uff0c\u5982\u679c\u5728 Vehicle \u7c7b\u4e2d\u5b9a\u4e49\u4e86 fly \u7684\u65b9\u6cd5\uff0c\u4f1a\u5bfc\u81f4 Car(Vehicle) \u7684\u7ee7\u627f\u5173\u7cfb\u51fa\u73b0\u77db\u76fe\uff0c\u6c7d\u8f66\u5e76\u4e0d\u4f1a\u98de\uff0c\u4f46\u6309\u7167\u4e0a\u8ff0\u7ee7\u627f\u5173\u7cfb\uff0c\u6c7d\u8f66\u4e5f\u80fd\u98de\u4e86\u3002 \u4f46\u662f\u5982\u679c\u6c11\u822a\u98de\u673a\u548c\u76f4\u5347\u673a\u90fd\u5404\u81ea\u5199\u81ea\u5df1\u7684\u98de\u884cfly\u65b9\u6cd5\uff0c\u53c8\u8fdd\u80cc\u4e86\u4ee3\u7801\u5c3d\u53ef\u80fd\u91cd\u7528\u7684\u539f\u5219\u3002 class Vehicle : # \u4ea4\u901a\u5de5\u5177 def fly ( self ): ''' \u98de\u884c\u529f\u80fd\u76f8\u5e94\u7684\u4ee3\u7801 ''' print ( \"I am flying\" ) # \u6c11\u822a\u98de\u673a class CivilAircraft ( Vehicle ): pass # \u76f4\u5347\u98de\u673a class Helicopter ( Vehicle ): pass # \u6c7d\u8f66 class Car ( Vehicle ): pass Python\u4e2d\u6ca1\u6709\u7c7b\u4f3cJava\u63a5\u53e3interface\u7684\u529f\u80fd\uff0c\u4f46\u63d0\u4f9b\u4e86Mixins\u673a\u5236\u3002 Python\u5bf9\u4e8e Mixin \u7c7b\u7684\u547d\u540d\u65b9\u5f0f\u4e00\u822c\u4ee5 Mixin , able , ible \u4e3a\u540e\u7f00\u3002 Mixin \u7c7b\u5fc5\u987b\u529f\u80fd\u5355\u4e00\uff0c\u5982\u679c\u6709\u591a\u4e2a\u529f\u80fd\uff0c\u90a3\u5c31\u5199\u591a\u4e2aMixin\u7c7b\u3002 \u4e00\u4e2a\u7c7b\u53ef\u4ee5\u7ee7\u627f\u591a\u4e2a Mixin \u7c7b\uff0c\u4e3a\u4e86\u4fdd\u8bc1\u9075\u5faa\u7ee7\u627f\u7684\u201cis-a\u201d\u539f\u5219\uff0c\u53ea\u80fd\u7ee7\u627f\u4e00\u4e2a\u6807\u8bc6\u5176\u5f52\u5c5e\u542b\u4e49\u7684\u7236\u7c7b Mixin \u7c7b\u4e0d\u4f9d\u8d56\u4e8e\u5b50\u7c7b\u7684\u5b9e\u73b0\u3002 \u5b50\u7c7b\u5373\u4fbf\u6ca1\u6709\u7ee7\u627f\u8fd9\u4e2a Mixin \u7c7b\u7c7b\uff0c\u4e5f\u7167\u6837\u53ef\u4ee5\u5de5\u4f5c\uff0c\u5c31\u662f\u7f3a\u5c11\u4e86\u67d0\u4e2a\u529f\u80fd\u3002 \u6211\u4eec\u5b9a\u4e49\u7684 Mixin \u7c7b\u8d8a\u591a\uff0c\u5b50\u7c7b\u7684\u4ee3\u7801\u53ef\u8bfb\u6027\u5c31\u4f1a\u8d8a\u5dee\u3002 # \u4ea4\u901a\u5de5\u5177 class Vehicle : pass # \u4e3a\u5f53\u524d\u7c7b\u6df7\u5165\u4e00\u4e9b\u529f\u80fd\uff0c\u4e0d\u662f\u4e00\u4e2a\u5355\u7eaf\u7684\u7c7b class FlyableMixin : def fly ( self ): ''' \u98de\u884c\u529f\u80fd\u76f8\u5e94\u7684\u4ee3\u7801 ''' print ( \"I am flying\" ) # \u6c11\u822a\u98de\u673a class CivilAircraft ( FlyableMixin , Vehicle ): pass # \u76f4\u5347\u98de\u673a class Helicopter ( FlyableMixin , Vehicle ): pass # \u6c7d\u8f66 class Car ( Vehicle ): pass","title":"\u591a\u7ee7\u627f\u5173\u7cfb\u7684minxins\u673a\u5236"},{"location":"python/Foundation/ch05/#class-combination","text":"\u5728\u4e00\u4e2a\u7c7b\u4e2d\u4ee5\u53e6\u4e00\u4e2a\u7c7b\u7684\u5bf9\u8c61\u4f5c\u4e3a\u6570\u636e\u5c5e\u6027\uff0c\u79f0\u4e3a\u7c7b\u7684**\u7ec4\u5408**\u3002\u7ec4\u5408\u4e0e\u7ee7\u627f\u90fd\u662f\u7528\u6765\u89e3\u51b3\u4ee3\u7801\u7684\u91cd\u7528\u6027\u95ee\u9898\u3002 \u7ee7\u627f\u4f53\u73b0\u201c\u662f\u201d\u7684\u5173\u7cfb\uff0c\u5f53\u7c7b\u4e4b\u95f4\u6709\u5f88\u591a\u76f8\u540c\u4e4b\u5904\uff0c\u7528\u7ee7\u627f\u3002 \u7ec4\u5408\u4f53\u73b0\u201c\u6709\u201d\u7684\u5173\u7cfb\uff0c\u5f53\u7c7b\u4e4b\u95f4\u6709\u663e\u8457\u4e0d\u540c\uff0c\u4e00\u4e2a\u7c7b\u662f\u53e6\u4e00\u4e2a\u7c7b\u7684\u5c5e\u6027\u662f\uff0c\u7528\u7ec4\u5408\u3002 \u4e0b\u4f8b\u662f\u8ba1\u7b97\u5706\u73af\u7684\u9762\u79ef\u548c\u5468\u957f\uff0c\u5706\u73af\u662f\u7531\u4e24\u4e2a\u5706\u7ec4\u6210\u7684\uff0c\u5706\u73af\u7684\u9762\u79ef\u662f\u5916\u9762\u5706\u7684\u9762\u79ef\u51cf\u53bb\u5185\u90e8\u5706\u7684\u9762\u79ef\u3002\u5706\u73af\u7684\u5468\u957f\u662f\u5185\u90e8\u5706\u7684\u5468\u957f\u52a0\u4e0a\u5916\u90e8\u5706\u7684\u5468\u957f\u3002 \u8fd9\u4e2a\u4f8b\u5b50\u6f14\u793a\u4e86\u7c7b ring \u91cc\u9762\u7684\u5c5e\u6027 circle1 \u548c circle2 \u6b63\u662f\u53e6\u4e00\u4e2a\u7c7b Circle \u3002 from math import pi class Circle (): def __init__ ( self , r ): self . r = r def area ( self ): return pi * self . r * self . r def perimeter ( self ): return 2 * pi * self . r class Ring (): def __init__ ( self , r1 , r2 ): self . circle1 = Circle ( r1 ) self . circle2 = Circle ( r2 ) def area ( self ): return abs ( self . circle1 . area () - self . circle2 . area ()) def permiter ( self ): return self . circle1 . perimeter () + self . circle2 . perimeter () ring = Ring ( 5 , 8 ) print ( ring . area ()) # 122.52211349000193 print ( ring . permiter ()) # 81.68140899333463 \u4e0b\u9762\u7684\u4f8b\u5b50\u6f14\u793a\u4e86\u5982\u4f55\u901a\u8fc7\u4f20\u53c2\u7684\u65b9\u5f0f\u8fdb\u884c\u7c7b\u7684\u7ec4\u5408\u3002 class Birthday (): def __init__ ( self , year , month , day ): self . year = year self . month = month self . day = day class Course (): def __init__ ( self , course_name , course_period ): self . course_name = course_name self . course_period = course_period class Professor (): def __init__ ( self , name , gender , birth , course ): self . name = name self . gender = gender self . birth = birth self . course = course def teach ( self ): print ( f \"Professor name: { self . name } ; Gender: { self . gender } ; Birthday: { self . birth . year } - { self . birth . month }{ self . birth . day } , Course name: { self . course . course_name } and period: { self . course . course_period } \" ) prof = Professor ( 'Tom' , 'Male' , Birthday ( 1985 , 5 , 5 ), Course ( 'Chinese' , '2022/3/1 ~ 2022/6/30' )) prof . teach () # Professor name: Tom; Gender: Male; Birthday: 1985-55, Course name: Chinese and period: 2022/3/1 ~ 2022/6/30","title":"\u7ec4\u5408\uff08Class Combination\uff09"},{"location":"python/Foundation/ch05/#polymorphism","text":"\u591a\u6001\u610f\u5473\u7740\u76f8\u540c\u7684\u51fd\u6570\u540d\u7528\u4e8e\u4e0d\u540c\u7684\u60c5\u5f62\u3002 \u5982\u4e0b\u4f8b\uff0c len() \u88ab\u7528\u4e8e\u4e0d\u540c\u7684\u60c5\u5f62\u3002 # len() being used for a string print ( len ( \"geeks\" )) # 5 # len() being used for a list print ( len ([ 10 , 20 , 30 ])) # 3","title":"\u591a\u6001 Polymorphism"},{"location":"python/Foundation/ch05/#_2","text":"\u4e0b\u9762\u7684\u4ee3\u7801\u5c55\u793a\u4e86 Python \u5982\u4f55\u4ee5\u76f8\u540c\u7684\u65b9\u5f0f\u4f7f\u7528\u4e24\u79cd\u4e0d\u540c\u7684\u7c7b\u7c7b\u578b\u3002 \u6211\u4eec\u521b\u5efa\u4e86\u4e00\u4e2a\u904d\u5386\u5bf9\u8c61\u5143\u7ec4\u7684 for \u5faa\u73af\u3002 \u7136\u540e\u8c03\u7528\u65b9\u6cd5\u800c\u4e0d\u7528\u5173\u5fc3\u6bcf\u4e2a\u5bf9\u8c61\u662f\u54ea\u4e2a\u7c7b\u7c7b\u578b\u3002 \u6211\u4eec\u5047\u8bbe\u8fd9\u4e9b\u65b9\u6cd5\u5b9e\u9645\u4e0a\u5b58\u5728\u4e8e\u6bcf\u4e2a\u7c7b\u4e2d\u3002 class India (): def capital ( self ): print ( \"New Delhi is the capital of India.\" ) def language ( self ): print ( \"Hindi is the most widely spoken language of India.\" ) def type ( self ): print ( \"India is a developing country.\" ) class USA (): def capital ( self ): print ( \"Washington, D.C. is the capital of USA.\" ) def language ( self ): print ( \"English is the primary language of USA.\" ) def type ( self ): print ( \"USA is a developed country.\" ) obj_ind = India () obj_usa = USA () for country in ( obj_ind , obj_usa ): country . capital () country . language () country . type () # New Delhi is the capital of India. # Hindi is the most widely spoken language of India. # India is a developing country. # Washington, D.C. is the capital of USA. # English is the primary language of USA. # USA is a developed country.","title":"\u7c7b\u65b9\u6cd5\u7684\u591a\u6001\u6027"},{"location":"python/Foundation/ch05/#_3","text":"\u5728 Python \u4e2d\uff0c\u591a\u6001\u5141\u8bb8\u6211\u4eec\u5728\u5b50\u7c7b\u4e2d\u5b9a\u4e49\u4e0e\u7236\u7c7b\u4e2d\u7684\u65b9\u6cd5\u540c\u540d\u7684\u65b9\u6cd5\u3002 \u5728\u7ee7\u627f\u4e2d\uff0c\u5b50\u7c7b\u7ee7\u627f\u7236\u7c7b\u7684\u65b9\u6cd5\u3002 \u4f46\u662f\uff0c\u53ef\u4ee5\u4fee\u6539\u4ece\u7236\u7c7b\u7ee7\u627f\u7684\u5b50\u7c7b\u4e2d\u7684\u65b9\u6cd5\u3002 \u8fd9\u5728\u4ece\u7236\u7c7b\u7ee7\u627f\u7684\u65b9\u6cd5\u4e0d\u592a\u9002\u5408\u5b50\u7c7b\u7684\u60c5\u51b5\u4e0b\u7279\u522b\u6709\u7528\u3002 \u5728\u8fd9\u79cd\u60c5\u51b5\u4e0b\uff0c\u6211\u4eec\u5728\u5b50\u7c7b\u4e2d\u91cd\u65b0\u5b9e\u73b0\u8be5\u65b9\u6cd5\u3002 \u8fd9\u79cd\u5728\u5b50\u7c7b\u4e2d\u91cd\u65b0\u5b9e\u73b0\u65b9\u6cd5\u7684\u8fc7\u7a0b\u79f0\u4e3a**\u65b9\u6cd5\u8986\u76d6\uff08Method Overriding\uff09**\u3002 class Bird : def intro ( self ): print ( \"There are many types of birds.\" ) def flight ( self ): print ( \"Most of the birds can fly but some cannot.\" ) class sparrow ( Bird ): def flight ( self ): print ( \"Sparrows can fly.\" ) class ostrich ( Bird ): def flight ( self ): print ( \"Ostriches cannot fly.\" ) obj_bird = Bird () obj_spr = sparrow () obj_ost = ostrich () obj_bird . intro () # There are many types of birds. obj_bird . flight () # Most of the birds can fly but some cannot. obj_spr . intro () # There are many types of birds. obj_spr . flight () # Sparrows can fly. obj_ost . intro () # There are many types of birds. obj_ost . flight () # Ostriches cannot fly.","title":"\u7ee7\u627f\u7684\u591a\u6001\u6027"},{"location":"python/Foundation/ch05/#_4","text":"\u6211\u4eec\u4e5f\u53ef\u4ee5\u521b\u5efa\u4e00\u4e2a\u53ef\u4ee5\u63a5\u53d7\u4efb\u4f55\u5bf9\u8c61\u7684\u51fd\u6570\uff0c\u5141\u8bb8\u591a\u6001\u6027\u3002 \u5728\u4e0b\u9762\u4f8b\u5b50\u4e2d\uff0c\u6211\u4eec\u521b\u5efa\u4e00\u4e2a\u540d\u4e3a func() \u7684\u51fd\u6570\uff0c\u4f20\u5165\u53c2\u6570\u662f obj \u7684\u5bf9\u8c61\u3002 \u5728\u8fd9\u79cd\u60c5\u51b5\u4e0b\uff0c\u6211\u4eec\u8c03\u7528\u4e09\u4e2a\u65b9\u6cd5\uff0c\u5373 capital() \u3001 language() \u548c type() \uff0c\u6bcf\u4e2a\u65b9\u6cd5\u90fd\u5b9a\u4e49\u5728 India \u548c USA \u4e24\u4e2a\u7c7b\u4e2d\u3002 \u6211\u4eec\u53ef\u4ee5\u4f7f\u7528\u76f8\u540c\u7684 func() \u51fd\u6570\u8c03\u7528\u5b83\u4eec\u7684\u52a8\u4f5c\uff1a class India (): def capital ( self ): print ( \"New Delhi is the capital of India.\" ) def language ( self ): print ( \"Hindi is the most widely spoken language of India.\" ) def type ( self ): print ( \"India is a developing country.\" ) class USA (): def capital ( self ): print ( \"Washington, D.C. is the capital of USA.\" ) def language ( self ): print ( \"English is the primary language of USA.\" ) def type ( self ): print ( \"USA is a developed country.\" ) def func ( obj ): obj . capital () obj . language () obj . type () obj_ind = India () obj_usa = USA () func ( obj_ind ) # New Delhi is the capital of India. # Hindi is the most widely spoken language of India. # India is a developing country. func ( obj_usa ) # Washington, D.C. is the capital of USA. # English is the primary language of USA. # USA is a developed country.","title":"\u51fd\u6570\u548c\u5bf9\u8c61\u7684\u591a\u6001\u6027"},{"location":"python/Foundation/ch05/#ducking-typinggoose-typing","text":"\u5728Python\u4e2d\u5b9e\u73b0\u591a\u6001\u4e3b\u8981\u6709\u4e24\u79cd\u673a\u5236\uff1a\u767d\u9e45\u7c7b\u578b\u548c\u9e2d\u5b50\u7c7b\u578b\u3002\u767d\u9e45\u7c7b\u578b\u548c\u9e2d\u5b50\u7c7b\u578b\u4e0d\u4ec5\u662f\u4e24\u79cd\u673a\u5236\uff0c\u4e5f\u662f\u4e24\u79cd\u4e0d\u540c\u7684\u7f16\u7a0b\u98ce\u683c\u3002 \u4e0b\u9762\u662f\u4e00\u4e2a\u6253\u5370\u5546\u54c1\u4ef7\u683c\u7684\u4f8b\u5b50\uff0c\u5206\u522b\u7528\u9e2d\u5b50\u7c7b\u578b\u548c\u767d\u9e45\u7c7b\u578b\u5b9e\u73b0\u3002 \u9e2d\u5b50\u7c7b\u578b\u3002 \u5728\u9e2d\u5b50\u7c7b\u578b\u7684\u5b9e\u73b0\u4e2d\uff0c\u6211\u4eec\u53ea\u9700\u8981\u4fdd\u8bc1\u8c03\u7528 price \u65b9\u6cd5\u7684\u6bcf\u4e2a\u5bf9\u8c61\u90fd\u6709 price \u65b9\u6cd5\u5373\u53ef\u3002 class Food : def price ( self ): print ( \" {} price:$4\" . format ( __class__ . __name__ )) class Clothes : def price ( self ): print ( \" {} price:$5\" . format ( __class__ . __name__ )) class Coffee : def price ( self ): print ( \" {} price:$6\" . format ( __class__ . __name__ )) if __name__ == '__main__' : goods = [ Food (), Clothes (), Coffee ()] for good in goods : good . price () # Food price:$4 # Clothes price:$5 # Coffee price:$6 \u767d\u9e45\u7c7b\u578b\u3002 \u5728\u767d\u9e45\u7c7b\u578b\u4e2d\uff0c\u76f4\u63a5\u8ba9\u6240\u6709\u5bf9\u8c61\u7684\u7c7b\u7ee7\u627f\u7236\u7c7b Good \u4e2d\u7684\u62bd\u8c61\u65b9\u6cd5 price \u3002Python\u4e2d\u7684\u767d\u9e45\u7c7b\u578b\u673a\u5236\u5c31\u662f\u5f3a\u7c7b\u578b\u8bed\u8a00\u4e2d\u5b9e\u73b0\u591a\u6001\u7684\u6807\u51c6\u6a21\u5f0f\uff0c\u5373\u901a\u8fc7\u8c03\u53d6\u7236\u7c7b\u7684\u865a\u51fd\u6570\u6216\u8005\u7ee7\u627f\u7684\u51fd\u6570\u6765\u5b8c\u6210\u4e0d\u540c\u7684\u884c\u4e3a\u3002 import abc class Good ( abc . ABC ): @abc . abstractmethod def price ( self ): pass class Food ( Good ): def price ( self ): print ( \" {} price:$4\" . format ( __class__ . __name__ )) class Clothes ( Good ): def price ( self ): print ( \" {} price:$5\" . format ( __class__ . __name__ )) if __name__ == '__main__' : goods = [ Food (), Clothes (), Coffee ()] for good in goods : good . price () # Food price:$4 # Clothes price:$5 # Coffee price:$6","title":"\u9e2d\u5b50\u7c7b\u578b\uff08Ducking Typing\uff09\u548c\u767d\u9e45\u7c7b\u578b\uff08Goose Typing\uff09"},{"location":"python/Foundation/ch05/#class-methodstatic-method","text":"\u7c7b\u65b9\u6cd5\uff08Class method\uff09\u4e5f\u53eb\u7ed1\u5b9a\u65b9\u6cd5\uff0c\u5fc5\u987b\u628a\u7c7b\u4f5c\u4e3a\u4f20\u5165\u53c2\u6570\uff0c\u4f7f\u7528 cls \u4f5c\u4e3a\u7b2c\u4e00\u4e2a\u4f20\u5165\u53c2\u6570\uff0c\u800c\u9759\u6001\u65b9\u6cd5\uff08Static Method\uff09\uff0c\u4e5f\u53eb\u975e\u7ed1\u5b9a\u65b9\u6cd5\uff0c\u4e0d\u9700\u8981\u7279\u5b9a\u7684\u53c2\u6570\u3002 \u7c7b\u65b9\u6cd5\u662f\u7ed1\u5b9a\u5230\u7c7b\u7684\uff0c\u4e0d\u662f\u7ed1\u5b9a\u5230\u7c7b\u5bf9\u8c61\uff0c\u6240\u4ee5\u7c7b\u65b9\u6cd5\u53ef\u4ee5\u8bbf\u95ee\u6216\u4fee\u6539\u7c7b\uff0c\u5e76\u5bf9\u6240\u6709\u7c7b\u5b9e\u4f8b\u751f\u6548\u3002 \u9759\u6001\u65b9\u6cd5\u65e0\u6cd5\u76f4\u63a5\u8bbf\u95ee\u6216\u4fee\u6539\u7c7b\uff0c\u56e0\u4e3a\u9759\u6001\u65b9\u6cd5\u662f\u4e0d\u77e5\u9053\u7c7b\u672c\u8eab\u7684\uff0c\u9759\u6001\u65b9\u6cd5\u662f\u5c5e\u4e8e\u5de5\u5177\u7c7b\u65b9\u6cd5\uff0c\u57fa\u4e8e\u4f20\u5165\u7684\u53c2\u6570\u5b8c\u6210\u7279\u5b9a\u7684\u529f\u80fd\uff0c\u5176\u5b9e\u5c31\u662f\u4e00\u4e2a\u666e\u901a\u51fd\u6570\u800c\u5df2\u3002 Python\u4e2d\u4f7f\u7528 @classmethod \u88c5\u9970\u5668\uff08decorator\uff09\u6765\u521b\u5efa\u4e00\u4e2a\u7c7b\u65b9\u6cd5\uff0c\u7528@staticmethod\u88c5\u9970\u5668\u6765\u521b\u5efa\u4e00\u4e2a\u9759\u6001\u65b9\u6cd5\u3002 \u8bed\u6cd5\u683c\u5f0f\uff1a @classmethod def fun ( cls , arg1 , arg2 , ... ): \u5176\u4e2d\uff1a fun : \u9700\u8981\u8f6c\u6362\u6210\u7c7b\u65b9\u6cd5\u7684\u51fd\u6570 returns : \u51fd\u6570\u7684\u7c7b\u65b9\u6cd5 classmethod() \u65b9\u6cd5\u7ed1\u5b9a\u5230\u7c7b\u800c\u4e0d\u662f\u5bf9\u8c61\u3002\u7c7b\u65b9\u6cd5\u53ef\u4ee5\u88ab\u7c7b\u548c\u5bf9\u8c61\u8c03\u7528\u3002\u8fd9\u4e9b\u65b9\u6cd5\u53ef\u4ee5\u901a\u8fc7\u7c7b\u6216\u5bf9\u8c61\u8fdb\u884c\u8c03\u7528\u3002 \u4f8b1\uff1a\u521b\u5efa\u4e00\u4e2a\u7b80\u5355\u7684 classmethod \u3002 \u521b\u5efa\u4e00\u4e2a\u7c7b Training \uff0c\u6709\u7c7b\u53d8\u91cf course \u548c\u65b9\u6cd5 purchase \u3002 \u6211\u4eec\u901a\u8fc7\u628a\u51fd\u6570 Training.purchase \u4f20\u7ed9 classmethod() \uff0c\u628a\u8be5\u65b9\u6cd5\u8f6c\u6210\u7c7b\u65b9\u6cd5\uff0c\u7136\u540e\u76f4\u63a5\u8c03\u7528\u5b83\uff0c\u800c\u65e0\u9700\u5148\u521b\u5efa\u5bf9\u8c61\u3002 \u53ef\u4ee5\u770b\u51fa\u8f6c\u6362\u524d\u540e Training.purchase \u7684\u7c7b\u578b\u53d8\u5316\u3002 class Training : course = 'Python for Data Analysis' def purchase ( obj ): print ( \"Puchase course : \" , obj . course ) type ( Training . purchase ) # Training . purchase = classmethod ( Training . purchase ) Training . purchase () # Puchase course : Python for Data Analysis type ( Training . purchase ) # \u4f8b2\uff1a\u4f7f\u7528\u88c5\u9970\u5668 @classmethod \u521b\u5efa\u5de5\u5382\u7c7b\u3002 class Training : def __init__ ( self , course ): self . course = course @classmethod def purchase ( cls , course ): return cls ( course ) def display ( self ): print ( 'Purchase course: ' , self . course ) training = Training ( \"Python for Data Analysis\" ) training . display () # Purchase course: Python for Data Analysis \u4f8b3\uff1a\u901a\u8fc7 staticmethod() \u548c classmethod() \u6765\u68c0\u67e5\u4e00\u4e2aperson\u662f\u5426\u662fadult\u3002 person1\u662f\u901a\u8fc7\u59d3\u540d\u548c\u5e74\u9f84\u521b\u5efa\u7684\u5b9e\u4f8b\u3002person2\u662f\u901a\u8fc7\u59d3\u540d\u548c\u5e74\u4efd\u521b\u5efa\u7684\u5b9e\u4f8b\u3002 from datetime import date class Person : def __init__ ( self , name , age ): self . name = name self . age = age @classmethod def fromBirthYear ( cls , name , year ): return cls ( name , date . today () . year - year ) @staticmethod def isAdult ( age ): return age > 18 person1 = Person ( 'mayank' , 21 ) person2 = Person . fromBirthYear ( 'mayank' , 1996 ) print ( person1 . age ) # 21 print ( person2 . age ) # 26 print ( Person . isAdult ( 22 )) # True \u5c0f\u7ed3\uff1a \u82e5\u7c7b\u4e2d\u9700\u8981\u4e00\u4e2a\u529f\u80fd\uff0c\u8be5\u529f\u80fd\u7684\u5b9e\u73b0\u4ee3\u7801\u4e2d\u9700\u8981\u5f15\u7528\u5bf9\u8c61\uff0c\u5219\u5c06\u5176\u5b9a\u4e49\u6210\u5bf9\u8c61\u65b9\u6cd5\uff1b\u9700\u8981\u5f15\u7528\u7c7b\uff0c\u5219\u5c06\u5176\u5b9a\u4e49\u6210\u7c7b\u65b9\u6cd5\uff1b\u65e0\u9700\u5f15\u7528\u7c7b\u6216\u5bf9\u8c61\uff0c\u5219\u5c06\u5176\u5b9a\u4e49\u6210\u9759\u6001\u65b9\u6cd5\u3002","title":"\u7c7b\u65b9\u6cd5\uff08Class method\uff09\u548c\u9759\u6001\u65b9\u6cd5\uff08Static Method\uff09"},{"location":"python/Foundation/ch05/#monkey-patch","text":"\u7334\u5b50\u8865\u4e01\u662f\u52a8\u6001\u4e3a\u5df2\u7ecf\u521b\u5efa\u51fa\u7684\u5bf9\u8c61\u589e\u52a0\u65b0\u7684\u65b9\u6cd5\u548c\u5c5e\u6027\u6210\u5458\u7684\u4e00\u79cd\u673a\u5236\uff0c\u4e5f\u5c31\u662f\u52a8\u6001\u6253\u8865\u4e01\u3002 \u5b9e\u4f8b\u5316\u5bf9\u8c61\u7684\u7334\u5b50\u8865\u4e01\u3002 class Test : def __init__ ( self ): self . a = 1 def func1 ( self , x , y ): print ( x + y ) # \u6b63\u5e38\u5b9e\u4f8b\u5316 test = Test () test . func1 ( 1 , 1 ) # 2 # \u4fee\u6539\u5b9e\u4f8b test . func1 = lambda x , y : print ( x + 2 * y ) test . func1 ( 1 , 1 ) # 3 # \u901a\u8fc7\u4fee\u6539\u5b9e\u4f8b\uff0c\u8bbf\u95ee\u5185\u90e8\u6210\u5458\u53d8\u91cf\u3002 test . func1 = lambda x , y : print ( x + 2 * y + self . a ) test . func1 ( 1 , 1 ) # NameError: name 'self' is not defined test . func1 = lambda self , x , y : print ( x + 2 * y + self . a ) test . func1 ( test , 1 , 1 ) # 4 \u7c7b\u5bf9\u8c61\u7684\u7334\u5b50\u8865\u4e01\u3002 class Test : def __init__ ( self ): self . a = 1 def func1 ( self , x , y ): print ( x + y ) # \u4fee\u6539\u7c7b\u6210\u5458\uff0c\u5b9e\u4f8b\u5316\u540e\u7684\u7ed3\u679c\u5df2\u4fee\u6539\u3002 Test . func1 = lambda self , x , y : print ( x + 2 * y ) test = Test () test . func1 ( 1 , 1 ) # 3 # \u4fee\u6539\u7c7b\u6210\u5458\uff0c\u5e76\u8bbf\u95ee\u6210\u5458\u53d8\u91cf\uff0c\u5b9e\u4f8b\u5316\u540e\u7684\u7ed3\u679c\u5df2\u4fee\u6539\u3002 Test . func1 = lambda self , x , y : print ( x + 2 * y + self . a ) test = Test () test . func1 ( 1 , 1 ) # 4 # \u589e\u52a0\u7c7b\u6210\u5458\u3002 Test . func2 = lambda self , p , q : print ( p + 3 * q + self . a ) test = Test () test . func1 ( 1 , 1 ) # 4 test . func2 ( 1 , 3 ) # 11","title":"\u7334\u5b50\u8865\u4e01\uff08monkey patch\uff09"},{"location":"python/Foundation/ch05/#private-variables","text":"\u90a3\u79cd\u4ec5\u9650\u4ece\u4e00\u4e2a\u5bf9\u8c61\u5185\u90e8\u8bbf\u95ee\u7684\u201c\u79c1\u6709\u201d\u5b9e\u4f8b\u53d8\u91cf\uff08\u201cPrivate\u201d instance variables\uff09\u5728 Python \u4e2d\u5e76\u4e0d\u5b58\u5728\u3002 \u4f46\u662f\uff0c\u5927\u591a\u6570 Python \u4ee3\u7801\u90fd\u9075\u5faa\u8fd9\u6837\u4e00\u4e2a\u7ea6\u5b9a\uff1a\u5e26\u6709*\u4e00\u4e2a\u524d\u7f00\u4e0b\u5212\u7ebf*\u7684\u540d\u79f0 (\u4f8b\u5982 _spam ) \u5e94\u8be5\u88ab\u5f53\u4f5c\u662f API \u7684\u975e\u516c\u6709\uff08non-public\uff09\u90e8\u5206 (\u65e0\u8bba\u5b83\u662f\u51fd\u6570\u3001\u65b9\u6cd5\u6216\u662f\u6570\u636e\u6210\u5458)\u3002 \u8fd9\u5e94\u5f53\u88ab\u89c6\u4e3a\u4e00\u4e2a\u5b9e\u73b0\u7ec6\u8282\uff0c\u53ef\u80fd\u4e0d\u7ecf\u901a\u77e5\u5373\u52a0\u4ee5\u6539\u53d8\u3002 \u7531\u4e8e\u5b58\u5728\u5bf9\u4e8e\u7c7b\u79c1\u6709\u6210\u5458\uff08class-private members\uff09\u7684\u6709\u6548\u4f7f\u7528\u573a\u666f\uff08\u4f8b\u5982\u907f\u514d\u540d\u79f0\u4e0e\u5b50\u7c7b\u6240\u5b9a\u4e49\u7684\u540d\u79f0\u76f8\u51b2\u7a81\uff09\uff0c\u56e0\u6b64\u5b58\u5728\u5bf9\u6b64\u79cd\u673a\u5236\u7684\u6709\u9650\u652f\u6301\uff0c\u79f0\u4e3a**\u540d\u79f0\u6539\u5199\uff08name mangling\uff09**\u3002 \u4efb\u4f55\u5f62\u5f0f\u4e3a __spam \u7684\u6807\u8bc6\u7b26\uff08\u81f3\u5c11\u5e26\u6709*\u4e24\u4e2a\u524d\u7f00\u4e0b\u5212\u7ebf*\uff0c\u81f3\u591a\u4e00\u4e2a\u540e\u7f00\u4e0b\u5212\u7ebf\uff09\u7684\u6587\u672c\u5c06\u88ab\u66ff\u6362\u4e3a _classname__spam \uff0c\u5176\u4e2d classname \u4e3a\u53bb\u9664\u4e86\u524d\u7f00\u4e0b\u5212\u7ebf\u7684\u5f53\u524d\u7c7b\u540d\u79f0\u3002 \u8fd9\u79cd\u6539\u5199\u4e0d\u8003\u8651\u6807\u8bc6\u7b26\u7684\u53e5\u6cd5\u4f4d\u7f6e\uff0c\u53ea\u8981\u5b83\u51fa\u73b0\u5728\u7c7b\u5b9a\u4e49\u5185\u90e8\u5c31\u4f1a\u8fdb\u884c\u3002 \u540d\u79f0\u6539\u5199\uff08Name mangling\uff09\u6709\u52a9\u4e8e\u8ba9\u5b50\u7c7b\u91cd\u8f7d\u65b9\u6cd5\uff08\uff09override methods\u800c\u4e0d\u7834\u574f\u7c7b\u5185\u65b9\u6cd5\uff08intraclass method\uff09\u8c03\u7528\u3002\u4f8b\u5982: class Mapping : def __init__ ( self , iterable ): self . items_list = [] self . __update ( iterable ) def update ( self , iterable ): for item in iterable : self . items_list . append ( item ) __update = update # private copy of original update() method class MappingSubclass ( Mapping ): def update ( self , keys , values ): # provides new signature for update() # but does not break __init__() for item in zip ( keys , values ): self . items_list . append ( item ) \u4e0a\u9762\u7684\u793a\u4f8b\u5373\u4f7f\u5728 MappingSubclass \u5f15\u5165\u4e86\u4e00\u4e2a __update \u6807\u8bc6\u7b26\u7684\u60c5\u51b5\u4e0b\u4e5f\u4e0d\u4f1a\u51fa\u9519\uff0c\u56e0\u4e3a\u5b83\u4f1a\u5728 Mapping \u7c7b\u4e2d\u88ab\u66ff\u6362\u4e3a _Mapping__update \u800c\u5728 MappingSubclass \u7c7b\u4e2d\u88ab\u66ff\u6362\u4e3a _MappingSubclass__update \u3002 \u8bf7\u6ce8\u610f\uff0c\u6539\u5199\u89c4\u5219\uff08mangling rules\uff09\u7684\u8bbe\u8ba1\u4e3b\u8981\u662f\u4e3a\u4e86\u907f\u514d\u610f\u5916\u51b2\u7a81\uff1b\u8bbf\u95ee\u6216\u4fee\u6539\u79c1\u6709\u53d8\u91cf\u4ecd\u7136\u662f\u53ef\u80fd\u7684\u3002\u8fd9\u5728\u7279\u6b8a\u60c5\u51b5\u4e0b\u751a\u81f3\u4f1a\u5f88\u6709\u7528\uff0c\u4f8b\u5982\u5728\u8c03\u8bd5\u5668\uff08debugger\uff09\u4e2d\u3002 \u8bf7\u6ce8\u610f\u4f20\u9012\u7ed9 exec() \u6216 eval() \u7684\u4ee3\u7801\u4e0d\u4f1a\u628a\u53d1\u8d77\u8c03\u7528\u7c7b\u7684\u7c7b\u540d\u89c6\u4f5c\u5f53\u524d\u7c7b\uff1b\u8fd9\u7c7b\u4f3c\u4e8e global \u8bed\u53e5\u7684\u6548\u679c\uff0c\u56e0\u6b64\u8fd9\u79cd\u6548\u679c\u4ec5\u9650\u4e8e\u540c\u65f6\u7ecf\u8fc7\u5b57\u8282\u7801\u7f16\u8bd1\u7684\u4ee3\u7801\u3002 \u540c\u6837\u7684\u9650\u5236\u4e5f\u9002\u7528\u4e8e getattr() , setattr() \u548c delattr() \uff0c\u4ee5\u53ca\u5bf9\u4e8e __dict__ \u7684\u76f4\u63a5\u5f15\u7528\u3002","title":"\u79c1\u6709\u53d8\u91cf Private Variables"},{"location":"python/Foundation/ch05/#reflection","text":"\u53cd\u5c04(reflection)\u662f\u52a8\u6001\u8bed\u8a00\u7684\u4e00\u4e2a\u7279\u6027\u3002**\u53cd\u5c04\u673a\u5236**\u6307\u7684\u662f\u5728\u7a0b\u5e8f\u7684\u8fd0\u884c\u72b6\u6001\u4e2d\uff0c\u5bf9\u4e8e\u4efb\u610f\u4e00\u4e2a\u7c7b\uff0c\u90fd\u53ef\u4ee5\u77e5\u9053\u8fd9\u4e2a\u7c7b\u7684\u6240\u6709\u5c5e\u6027\u548c\u65b9\u6cd5\uff1b\u5bf9\u4e8e\u4efb\u610f\u4e00\u4e2a\u5bf9\u8c61\uff0c\u90fd\u80fd\u591f\u8c03\u7528\u4ed6\u7684\u4efb\u610f\u65b9\u6cd5\u548c\u5c5e\u6027\u3002\u8fd9\u79cd\u52a8\u6001\u83b7\u53d6\u7a0b\u5e8f\u4fe1\u606f\u4ee5\u53ca\u52a8\u6001\u8c03\u7528\u5bf9\u8c61\u7684\u529f\u80fd\u79f0\u4e3a\u53cd\u5c04\u673a\u5236\u3002 \u901a\u8fc7\u4e0b\u9762\u4f8b\u5b50\u53ef\u77e5\uff0c\u901a\u8fc7 dir(person) \u83b7\u53d6\u4efb\u610f\u4e00\u4e2a\u7c7b\u6216\u8005\u5bf9\u8c61\u7684\u5c5e\u6027\u5217\u8868\u3002\u901a\u8fc7\u5185\u7f6e\u51fd\u6570 hasattr \u3001 getattr \u3001 setattr \u3001 delattr \u64cd\u4f5c\u7c7b\u548c\u5bf9\u8c61\u3002 class Person : def __init__ ( self , name , age , gender ): self . name = name self . age = age self . gender = gender person = Person ( 'Tom' , 21 , 'Male' ) print ( dir ( person )) # ['__class__', '__delattr__', '__dict__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__gt__', '__hash__', '__init__', '__init_subclass__', '__le__', '__lt__', '__module__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', '__weakref__', 'age', 'gender', 'name'] # hasattr(object,'name') # \u6309\u5b57\u7b26\u4e32'name'\u5224\u65ad\u6709\u65e0\u5c5e\u6027person.name hasattr ( person , 'name' ) # True # getattr(object, 'name', default=None) # \u7b49\u540c\u4e8eperson.name,\u4e0d\u5b58\u5728\u8be5\u5c5e\u6027\u5219\u8fd4\u56de\u9ed8\u8ba4\u503cNone getattr ( person , 'name' , None ) # 'Tom' # setattr(x, 'y', v) # \u7b49\u540c\u4e8eperson.age = 18 setattr ( person , 'age' , 18 ) print ( person . age ) # 18 # delattr(x, 'y') # \u7b49\u540c\u4e8edel person.age delattr ( person , 'age' ) print ( person . age ) # AttributeError: 'Person' object has no attribute 'age' \u4e0b\u9762\u662f\u4e00\u4e2a\u5b9e\u9645\u5e94\u7528\u7684\u4f8b\u5b50\u3002 class FtpServer (): def server_run ( self ): while True : inp = input ( 'Input your command >>:' ) . strip () cmd , file = inp . split () if hasattr ( self , cmd ): func = getattr ( self , cmd ) func ( file ) def get ( self , file ): print ( f 'Downloading { file } ...' ) def put ( self , file ): print ( f 'Uploading { file } ...' ) ftp_server = FtpServer () ftp_server . server_run () # Input your command >>:get a.ext # Downloading a.ext... # Input your command >>:put a.txt # Uploading a.txt...","title":"\u53cd\u5c04(reflection)"},{"location":"python/Foundation/ch05/#iterators","text":"\u5728Python\u4e2d\uff0c\u5927\u591a\u6570\u5bb9\u5668\u5bf9\u8c61\uff08container object\uff09\u90fd\u53ef\u4ee5\u4f7f\u7528 for \u8bed\u53e5: for element in [ 1 , 2 , 3 ]: print ( element ) for element in ( 1 , 2 , 3 ): print ( element ) for key in { 'one' : 1 , 'two' : 2 }: print ( key ) for char in \"123\" : print ( char ) for line in open ( \"myfile.txt\" ): print ( line , end = '' ) for \u8bed\u53e5\u4f1a\u5728\u5bb9\u5668\u5bf9\u8c61\u4e0a\u8c03\u7528 iter()\u3002 \u8be5\u51fd\u6570\u8fd4\u56de\u4e00\u4e2a\u5b9a\u4e49\u4e86 __next__() \u65b9\u6cd5\u7684\u8fed\u4ee3\u5668\u5bf9\u8c61\uff0c\u6b64\u65b9\u6cd5\u5c06\u9010\u4e00\u8bbf\u95ee\u5bb9\u5668\u4e2d\u7684\u5143\u7d20\u3002 \u5f53\u5143\u7d20\u7528\u5c3d\u65f6\uff0c __next__() \u5c06\u5f15\u53d1 StopIteration \u5f02\u5e38\u6765\u901a\u77e5\u7ec8\u6b62 for \u5faa\u73af\u3002 \u53ef\u4ee5\u4f7f\u7528 next() \u5185\u7f6e\u51fd\u6570\u6765\u8c03\u7528 __next__() \u65b9\u6cd5\uff1b\u4e0b\u9762\u8fd9\u4e2a\u4f8b\u5b50\u5c55\u793a\u4e86\u521a\u521a\u63cf\u8ff0\u7684\u5177\u4f53\u8fd0\u884c\u65b9\u5f0f: >>> s = 'abc' >>> it = iter ( s ) >>> it < str_iterator object at 0x10c90e650 > >>> next ( it ) 'a' >>> next ( it ) 'b' >>> next ( it ) 'c' >>> next ( it ) Traceback ( most recent call last ): File \"\" , line 1 , in < module > next ( it ) StopIteration \u5728\u4e86\u89e3\u4e86\u8fed\u4ee3\u5668\u534f\u8bae\uff08iterator protocol\uff09\u7684\u673a\u5236\u540e\uff0c\u7ed9\u7c7b\u6dfb\u52a0\u8fed\u4ee3\u5668\u5c31\u5f88\u5bb9\u6613\u4e86\u3002 \u5b9a\u4e49\u4e00\u4e2a __iter__() \u65b9\u6cd5\u6765\u8fd4\u56de\u4e00\u4e2a\u5e26\u6709 __next__() \u65b9\u6cd5\u7684\u5bf9\u8c61\u3002 \u5982\u679c\u7c7b\u5df2\u5b9a\u4e49\u4e86 __next__() \uff0c\u5219 __iter__() \u53ef\u4ee5\u7b80\u5355\u5730\u8fd4\u56de self : class Reverse : \"\"\"Iterator for looping over a sequence backwards.\"\"\" def __init__ ( self , data ): self . data = data self . index = len ( data ) def __iter__ ( self ): return self def __next__ ( self ): if self . index == 0 : raise StopIteration self . index = self . index - 1 return self . data [ self . index ] rev = Reverse ( 'spam' ) print ( iter ( rev )) for char in rev : print ( char ) # m # a # p # s","title":"\u8fed\u4ee3\u5668 Iterators"},{"location":"python/Foundation/ch05/#generators","text":"**\u751f\u6210\u5668\uff08Generators\uff09**\u662f\u4e00\u4e2a\u7528\u4e8e\u521b\u5efa\u8fed\u4ee3\u5668\u7684\u7b80\u5355\u800c\u5f3a\u5927\u7684\u5de5\u5177\u3002 \u5b83\u4eec\u7684\u5199\u6cd5\u7c7b\u4f3c\u4e8e\u6807\u51c6\u7684\u51fd\u6570\uff0c\u4f46\u5f53\u5b83\u4eec\u8981\u8fd4\u56de\u6570\u636e\u65f6\u4f1a\u4f7f\u7528 yield \u8bed\u53e5\u3002 \u6bcf\u6b21\u5728\u751f\u6210\u5668\u4e0a\u8c03\u7528 next() \u65f6\uff0c\u5b83\u4f1a\u4ece\u4e0a\u6b21\u79bb\u5f00\u7684\u4f4d\u7f6e\u6062\u590d\u6267\u884c\uff08\u5b83\u4f1a\u8bb0\u4f4f\u4e0a\u6b21\u6267\u884c\u8bed\u53e5\u65f6\u7684\u6240\u6709\u6570\u636e\u503c\uff09\u3002 \u4e00\u4e2a\u521b\u5efa\u751f\u6210\u5668\u7684\u793a\u4f8b\u5982\u4e0b\uff08\u6539\u5199\u4e0a\u9762\u8fed\u4ee3\u5668\u4e2d\u6240\u4e3e\u7684\u4f8b\u5b50\uff09: def reverse ( data ): for index in range ( len ( data ) - 1 , - 1 , - 1 ): yield data [ index ] for char in reverse ( 'golf' ): print ( char ) # f # l # o # g \u53ef\u4ee5\u7528\u751f\u6210\u5668\u6765\u5b8c\u6210\u7684\u64cd\u4f5c\u540c\u6837\u53ef\u4ee5\u7528\u524d\u9762\u6240\u63cf\u8ff0\u7684\u57fa\u4e8e\u7c7b\u7684\u8fed\u4ee3\u5668\u6765\u5b8c\u6210\u3002\u4f46\u751f\u6210\u5668\u7684\u5199\u6cd5\u66f4\u4e3a\u7d27\u51d1\uff0c\u56e0\u4e3a\u5b83\u4f1a\u81ea\u52a8\u521b\u5efa __iter__() \u548c __next__() \u65b9\u6cd5\u3002 \u53e6\u4e00\u4e2a\u5173\u952e\u7279\u6027\u5728\u4e8e\u5c40\u90e8\u53d8\u91cf\u548c\u6267\u884c\u72b6\u6001\u4f1a\u5728\u6bcf\u6b21\u8c03\u7528\u4e4b\u95f4\u81ea\u52a8\u4fdd\u5b58\u3002 \u8fd9\u4f7f\u5f97\u8be5\u51fd\u6570\u76f8\u6bd4\u4f7f\u7528 self.index \u548c self.data \u8fd9\u79cd\u5b9e\u4f8b\u53d8\u91cf\u7684\u65b9\u5f0f\u66f4\u6613\u7f16\u5199\u4e14\u66f4\u4e3a\u6e05\u6670\u3002 \u9664\u4e86\u4f1a\u81ea\u52a8\u521b\u5efa\u65b9\u6cd5\u548c\u4fdd\u5b58\u7a0b\u5e8f\u72b6\u6001\uff0c\u5f53\u751f\u6210\u5668\u7ec8\u7ed3\u65f6\uff0c\u5b83\u4eec\u8fd8\u4f1a\u81ea\u52a8\u5f15\u53d1 StopIteration \u3002","title":"\u751f\u6210\u5668 Generators"},{"location":"python/Foundation/ch05/#generator-expressions","text":"\u67d0\u4e9b\u7b80\u5355\u7684\u751f\u6210\u5668\u53ef\u4ee5\u5199\u6210\u7b80\u6d01\u7684\u8868\u8fbe\u5f0f\u4ee3\u7801\uff0c\u6240\u7528\u8bed\u6cd5\u7c7b\u4f3c\u5217\u8868\u63a8\u5bfc\u5f0f\uff0c\u4f46\u5916\u5c42\u4e3a\u5706\u62ec\u53f7\u800c\u975e\u65b9\u62ec\u53f7\u3002 \u8fd9\u79cd\u8868\u8fbe\u5f0f\u88ab\u8bbe\u8ba1\u7528\u4e8e\u751f\u6210\u5668\u5c06\u7acb\u5373\u88ab\u5916\u5c42\u51fd\u6570\u6240\u4f7f\u7528\u7684\u60c5\u51b5\u3002 \u751f\u6210\u5668\u8868\u8fbe\u5f0f\u76f8\u6bd4\u5b8c\u6574\u7684\u751f\u6210\u5668\u66f4\u7d27\u51d1\u4f46\u8f83\u4e0d\u7075\u6d3b\uff0c\u76f8\u6bd4\u7b49\u6548\u7684\u5217\u8868\u63a8\u5bfc\u5f0f\u5219\u66f4\u4e3a\u8282\u7701\u5185\u5b58\u3002 \u793a\u4f8b: >>> sum ( i * i for i in range ( 10 )) # sum of squares 285 >>> xvec = [ 10 , 20 , 30 ] >>> yvec = [ 7 , 5 , 3 ] >>> sum ( x * y for x , y in zip ( xvec , yvec )) # dot product 260 >>> unique_words = set ( word for line in page for word in line . split ()) >>> valedictorian = max (( student . gpa , student . name ) for student in graduates ) >>> data = 'golf' >>> list ( data [ i ] for i in range ( len ( data ) - 1 , - 1 , - 1 )) [ 'f' , 'l' , 'o' , 'g' ]","title":"\u751f\u6210\u5668\u8868\u8fbe\u5f0f Generator Expressions"},{"location":"python/Foundation/ch05/#metaclass","text":"\u6240\u6709\u7684\u5bf9\u8c61\u90fd\u662f\u5b9e\u4f8b\u5316\u6216\u8005\u8bf4\u8c03\u7528\u7c7b\u800c\u5f97\u5230\u7684\uff08\u8c03\u7528\u7c7b\u7684\u8fc7\u7a0b\u79f0\u4e3a\u7c7b\u7684\u5b9e\u4f8b\u5316\u3002 class StandfordProfessor ( object ): university = 'Standford' def __init__ ( self , name , gender ): self . name = name self . gender = gender def display ( self ): print ( f 'Professor { self . name } says welcome to { self . university } !' ) professor = StandfordProfessor ( 'Tom' , 'Male' ) \u4e0a\u4f8b\u4e2d\uff0c\u5bf9\u8c61 professor \u662f\u8c03\u7528\u7c7b StandfordProfessor \u5f97\u5230\u7684\u3002\u7c7b StandfordProfessor \u672c\u8d28\u4e5f\u662f\u4e00\u4e2a\u5bf9\u8c61\uff0c \u4e0b\u9762\u53ef\u4ee5\u9a8c\u8bc1\uff0c StandfordProfessor \u662f\u8c03\u7528\u4e86\u5185\u7f6e\u7684\u7c7b type \u5f97\u5230\u7684\u3002\u8fd9\u4e2a type \u79f0\u4e3a\u5143\u7c7b\u3002 print ( type ( StandfordProfessor )) # \u5982\u679c\u4e00\u4e2a\u7c7b\u6ca1\u6709\u58f0\u660e\u81ea\u5df1\u7684\u5143\u7c7b\uff0c\u9ed8\u8ba4\u5b83\u7684\u5143\u7c7b\u5c31\u662f type \uff0c\u9664\u4e86\u4f7f\u7528\u5185\u7f6e\u5143\u7c7b type \uff0c\u6211\u4eec\u4e5f\u53ef\u4ee5\u901a\u8fc7\u7ee7\u627f type \u6765\u81ea\u5b9a\u4e49\u5143\u7c7b\uff0c\u7136\u540e\u4f7f\u7528 metaclass \u5173\u952e\u5b57\u53c2\u6570\u4e3a\u4e00\u4e2a\u7c7b\u7684\u6307\u5b9a\u5143\u7c7b\u3002 \u53ea\u6709\u7ee7\u627f\u4e86type\u7c7b\u624d\u80fd\u79f0\u4e4b\u4e3a\u4e00\u4e2a\u5143\u7c7b\uff0c\u5426\u5219\u5c31\u662f\u4e00\u4e2a\u666e\u901a\u7684\u81ea\u5b9a\u4e49\u7c7b\u3002 class Mymeta ( type ): pass class StandfordProfessor ( object , metaclass = Mymeta ): university = 'Standford' def __init__ ( self , name , gender ): self . name = name self . gender = gender def display ( self ): print ( f 'Professor { self . name } says welcome to { self . university } !' ) professor = StandfordProfessor ( 'Tom' , 'Male' ) \u4e0b\u9762\u8fdb\u884c\u81ea\u5b9a\u4e49\u5143\u7c7b\uff0c\u63a7\u5236\u7c7b StandfordProfessor \u7684\u8c03\u7528\u3002 \u8981\u60f3\u8ba9 professor \u8fd9\u4e2a\u5bf9\u8c61\u53d8\u6210\u4e00\u4e2a\u53ef\u8c03\u7528\u7684\u5bf9\u8c61\uff0c\u9700\u8981\u5728\u8be5\u5bf9\u8c61\u7684\u7c7b\u4e2d\u5b9a\u4e49\u4e00\u4e2a\u65b9\u6cd5 __call__ \uff0c\u8be5\u65b9\u6cd5\u4f1a\u5728\u8c03\u7528\u5bf9\u8c61\u65f6\u81ea\u52a8\u89e6\u53d1\u3002\u8c03\u7528 professor \u7684\u8fd4\u56de\u503c\u5c31\u662f __call__ \u65b9\u6cd5\u7684\u8fd4\u56de\u503c\u3002 class Mymeta ( type ): def __call__ ( self , * args , ** kwargs ): print ( self ) # \u7c7b\u540d print ( args ) # \u8f93\u5165\u53c2\u6570 print ( kwargs ) # \u8f93\u5165\u53c2\u6570 return 10086 class StandfordProfessor ( object , metaclass = Mymeta ): university = 'Standford' def __init__ ( self , name , gender ): self . name = name self . gender = gender def display ( self ): print ( f 'Professor { self . name } says welcome to { self . university } !' ) professor = StandfordProfessor ( 'Tom' , 'Male' ) # # ('Tom', 'Male') # {} \u7c7b\u7684\u4ea7\u751f\u8fc7\u7a0b\u5176\u5b9e\u5c31\u662f\u5143\u7c7b\u7684\u8c03\u7528\u8fc7\u7a0b,\u5373 StandfordProfessor = Mymeta('StandfordProfessor', (object), {...}) \uff0c\u8c03\u7528 Mymeta \u4f1a\u5148\u4ea7\u751f\u4e00\u4e2a\u7a7a\u5bf9\u8c61 StandfordProfessor \uff0c\u7136\u540e\u8fde\u540c\u8c03\u7528 Mymeta \u62ec\u53f7\u5185\u7684\u53c2\u6570\u4e00\u540c\u4f20\u7ed9 Mymeta \u4e0b\u7684 __init__ \u65b9\u6cd5\uff0c\u5b8c\u6210\u521d\u59cb\u5316\u3002\u6211\u4eec\u53ef\u4ee5\u57fa\u4e8e\u4e0a\u4f8b\u505a\u5982\u4e0b\u6539\u5199\u3002 class Mymeta ( type ): def __init__ ( self , class_name , class_bases , class_dic ): super ( Mymeta , self ) . __init__ ( class_name , class_bases , class_dic ) if class_name . islower (): raise TypeError ( f 'Please follow Camel-Case to change class name { class_name } ' ) if '__doc__' not in class_dic or len ( class_dic [ '__doc__' ] . strip ( ' \\n ' )) == 0 : raise TypeError ( 'Please add documentation in class {class_name} , which is mandatory.' ) class StandfordProfessor ( object , metaclass = Mymeta ): \"\"\" Documentation of class StanfordTeacher \"\"\" university = 'Standford' def __init__ ( self , name , gender ): self . name = name self . gender = gender def display ( self ): print ( f 'Professor { self . name } says welcome to { self . university } !' ) professor = StandfordProfessor ( 'Tom' , 'Male' ) professor . display () # Professor Tom says welcome to Standford! print ( professor . __dict__ ) # {'name': 'Tom', 'gender': 'Male'} StandfordProfessor . mro () # [, ]","title":"\u5143\u7c7b\uff08metaclass\uff09"},{"location":"python/Pythonic90Rules/Rule01/","text":"\u7b2c1\u6761\u3000\u67e5\u8be2\u81ea\u5df1\u4f7f\u7528\u7684Python\u7248\u672c \u00b6 >>> import sys >>> print(sys.version) 3.9.6 (default, Aug 5 2021, 17:13:26) [GCC 7.5.0] >>> print(sys.path) ['', '/usr/local/lib/python39.zip', '/usr/local/lib/python3.9', '/usr/local/lib/python3.9/lib-dynload', '/home/james/.local/lib/python3.9/site-packages', '/usr/local/lib/python3.9/site-packages'] >>> print(sys.version_info) sys.version_info(major=3, minor=9, micro=6, releaselevel='final', serial=0)","title":"\u7b2c01\u6761 \u67e5\u8be2\u81ea\u5df1\u4f7f\u7528\u7684Python\u7248\u672c"},{"location":"python/Pythonic90Rules/Rule01/#1-python","text":">>> import sys >>> print(sys.version) 3.9.6 (default, Aug 5 2021, 17:13:26) [GCC 7.5.0] >>> print(sys.path) ['', '/usr/local/lib/python39.zip', '/usr/local/lib/python3.9', '/usr/local/lib/python3.9/lib-dynload', '/home/james/.local/lib/python3.9/site-packages', '/usr/local/lib/python3.9/site-packages'] >>> print(sys.version_info) sys.version_info(major=3, minor=9, micro=6, releaselevel='final', serial=0)","title":"\u7b2c1\u6761\u3000\u67e5\u8be2\u81ea\u5df1\u4f7f\u7528\u7684Python\u7248\u672c"},{"location":"python/Pythonic90Rules/Rule02/","text":"\u7b2c2\u6761\u3000\u9075\u5faaPEP 8\u98ce\u683c\u6307\u5357 \u00b6 Python Enhancement Proposal #8\u53eb\u4f5cPEP 8\uff0c\u5b83\u662f\u4e00\u4efd\u9488\u5bf9Python\u4ee3\u7801\u683c\u5f0f\u800c\u7f16\u8ba2\u7684\u98ce\u683c\u6307\u5357\u3002 \u5b8c\u6574\u6307\u5357\uff1ahttps://www.python.org/dev/peps/pep-0008 \u4e0e\u7a7a\u767d\u6709\u5173\u7684\u5efa\u8bae \u00b6 \u5728Python\u4e2d\uff0c\u7a7a\u767d\uff08whitespace\uff09\u7684\u4f7f\u7528\u9075\u5faa\u4ee5\u4e0b\u51e0\u6761\u5efa\u8bae\u3002 \u7528\u7a7a\u683c\uff08space\uff09\u8868\u793a\u7f29\u8fdb\uff0c\u800c\u4e0d\u8981\u7528\u5236\u8868\u7b26\uff08tab\uff09\u3002 \u548c\u8bed\u6cd5\u76f8\u5173\u7684\u6bcf\u4e00\u5c42\u7f29\u8fdb\u90fd\u75284\u4e2a\u7a7a\u683c\u8868\u793a\u3002 \u6bcf\u884c\u4e0d\u8d85\u8fc779\u4e2a\u5b57\u7b26\u3002 \u5bf9\u4e8e\u5360\u636e\u591a\u884c\u7684\u957f\u8868\u8fbe\u5f0f\u6765\u8bf4\uff0c\u9664\u4e86\u9996\u884c\u4e4b\u5916\u7684\u5176\u4f59\u5404\u884c\u90fd\u5e94\u8be5\u5728\u901a\u5e38\u7684\u7f29\u8fdb\u7ea7\u522b\u4e4b\u4e0a\u518d\u52a04\u4e2a\u7a7a\u683c\u3002 \u5728\u540c\u4e00\u4efd\u6587\u4ef6\u4e2d\uff0c\u51fd\u6570\u4e0e\u7c7b\u4e4b\u95f4\u7528\u4e24\u4e2a\u7a7a\u884c\u9694\u5f00\u3002 \u5728\u540c\u4e00\u4e2a\u7c7b\u4e2d\uff0c\u65b9\u6cd5\u4e0e\u65b9\u6cd5\u4e4b\u95f4\u7528\u4e00\u4e2a\u7a7a\u884c\u9694\u5f00\u3002 \u4f7f\u7528\u5b57\u5178\u65f6\uff0c\u952e\u4e0e\u5192\u53f7\u4e4b\u95f4\u4e0d\u52a0\u7a7a\u683c\uff0c\u5199\u5728\u540c\u4e00\u884c\u7684\u5192\u53f7\u548c\u503c\u4e4b\u95f4\u5e94\u8be5\u52a0\u4e00\u4e2a\u7a7a\u683c\u3002 \u7ed9\u53d8\u91cf\u8d4b\u503c\u65f6\uff0c\u8d4b\u503c\u7b26\u53f7\u7684\u5de6\u8fb9\u548c\u53f3\u8fb9\u5404\u52a0\u4e00\u4e2a\u7a7a\u683c\uff0c\u5e76\u4e14\u53ea\u52a0\u4e00\u4e2a\u7a7a\u683c\u5c31\u597d\u3002 \u7ed9\u53d8\u91cf\u7684\u7c7b\u578b\u505a\u6ce8\u89e3\uff08annotation\uff09\u65f6\uff0c\u4e0d\u8981\u628a\u53d8\u91cf\u540d\u548c\u5192\u53f7\u9694\u5f00\uff0c\u4f46\u5728\u7c7b\u578b\u4fe1\u606f\u524d\u5e94\u8be5\u6709\u4e00\u4e2a\u7a7a\u683c\u3002 \u4e0e\u547d\u540d\u6709\u5173\u7684\u5efa\u8bae \u00b6 PEP 8\u5efa\u8bae\u91c7\u7528\u4e0d\u540c\u7684\u65b9\u5f0f\u6765\u7ed9Python\u4ee3\u7801\u4e2d\u7684\u5404\u4e2a\u90e8\u5206\u547d\u540d\uff0c\u9075\u5faa\u4ee5\u4e0b\u4e0e\u547d\u540d\u76f8\u5173\u7684\u5efa\u8bae\u3002 \u51fd\u6570\u3001\u53d8\u91cf\u53ca\u5c5e\u6027\u7528\u5c0f\u5199\u5b57\u6bcd\u6765\u62fc\u5199\uff0c\u5404\u5355\u8bcd\u4e4b\u95f4\u7528\u4e0b\u5212\u7ebf\u76f8\u8fde\uff0c\u4f8b\u5982\uff1alowercase_underscore\u3002 \u53d7\u4fdd\u62a4\u7684\u5b9e\u4f8b\u5c5e\u6027\uff0c\u7528\u4e00\u4e2a\u4e0b\u5212\u7ebf\u5f00\u5934\uff0c\u4f8b\u5982\uff1a_leading_underscore\u3002 \u79c1\u6709\u7684\u5b9e\u4f8b\u5c5e\u6027\uff0c\u7528\u4e24\u4e2a\u4e0b\u5212\u7ebf\u5f00\u5934\uff0c\u4f8b\u5982\uff1a__double_leading_underscore\u3002 \u7c7b\uff08\u5305\u62ec\u5f02\u5e38\uff09\u547d\u540d\u65f6\uff0c\u6bcf\u4e2a\u5355\u8bcd\u7684\u9996\u5b57\u6bcd\u5747\u5927\u5199\uff0c\u4f8b\u5982\uff1aCapitalizedWord\u3002 \u6a21\u5757\u7ea7\u522b\u7684\u5e38\u91cf\uff0c\u6240\u6709\u5b57\u6bcd\u90fd\u5927\u5199\uff0c\u5404\u5355\u8bcd\u4e4b\u95f4\u7528\u4e0b\u5212\u7ebf\u76f8\u8fde\uff0c\u4f8b\u5982\uff1aALL_CAPS\u3002 \u7c7b\u4e2d\u7684\u5b9e\u4f8b\u65b9\u6cd5\uff0c\u5e94\u8be5\u628a\u7b2c\u4e00\u4e2a\u53c2\u6570\u547d\u540d\u4e3aself\uff0c\u7528\u6765\u8868\u793a\u8be5\u5bf9\u8c61\u672c\u8eab\u3002 \u7c7b\u65b9\u6cd5\u7684\u7b2c\u4e00\u4e2a\u53c2\u6570\uff0c\u5e94\u8be5\u547d\u540d\u4e3acls\uff0c\u7528\u6765\u8868\u793a\u8fd9\u4e2a\u7c7b\u672c\u8eab\u3002 \u4e0e\u8868\u8fbe\u5f0f\u548c\u8bed\u53e5\u6709\u5173\u7684\u5efa\u8bae \u00b6 The Zen of Python\u4e2d\u63d0\u5230\uff1a\u201c\u6bcf\u4ef6\u4e8b\u90fd\u5e94\u8be5\u6709\u7b80\u5355\u7684\u505a\u6cd5\uff0c\u800c\u4e14\u6700\u597d\u53ea\u6709\u4e00\u79cd\u3002\u201dPEP 8\u5c31\u8bd5\u7740\u8fd0\u7528\u8fd9\u4e2a\u7406\u5ff5\uff0c\u6765\u89c4\u8303\u8868\u8fbe\u5f0f\u548c\u8bed\u53e5\u7684\u5199\u6cd5\u3002 \u91c7\u7528\u884c\u5185\u5426\u5b9a\uff0c\u5373\u628a\u5426\u5b9a\u8bcd\u76f4\u63a5\u5199\u5728\u8981\u5426\u5b9a\u7684\u5185\u5bb9\u524d\u9762\uff0c\u800c\u4e0d\u8981\u653e\u5728\u6574\u4e2a\u8868\u8fbe\u5f0f\u7684\u524d\u9762\uff0c\u4f8b\u5982\u5e94\u8be5\u5199if a is not b\uff0c\u800c\u4e0d\u662fif not a is b\u3002 \u4e0d\u8981\u901a\u8fc7\u957f\u5ea6\u5224\u65ad\u5bb9\u5668\u6216\u5e8f\u5217\u662f\u4e0d\u662f\u7a7a\u7684\uff0c\u4f8b\u5982\u4e0d\u8981\u901a\u8fc7if len(somelist) == 0\u5224\u65adsomelist\u662f\u5426\u4e3a[]\u6216''\u7b49\u7a7a\u503c\uff0c\u800c\u662f\u5e94\u8be5\u91c7\u7528if not somelist\u8fd9\u6837\u7684\u5199\u6cd5\u6765\u5224\u65ad\uff0c\u56e0\u4e3aPython\u4f1a\u628a\u7a7a\u503c\u81ea\u52a8\u8bc4\u4f30\u4e3aFalse\u3002 \u5982\u679c\u8981\u5224\u65ad\u5bb9\u5668\u6216\u5e8f\u5217\u91cc\u9762\u6709\u6ca1\u6709\u5185\u5bb9\uff08\u6bd4\u5982\u8981\u5224\u65ad somelist \u662f\u5426\u4e3a[1]\u6216'hi'\u8fd9\u6837\u975e\u7a7a\u7684\u503c\uff09\uff0c\u4e5f\u4e0d\u5e94\u8be5\u901a\u8fc7\u957f\u5ea6\u6765\u5224\u65ad\uff0c\u800c\u662f\u5e94\u8be5\u91c7\u7528if somelist \u8bed\u53e5\uff0c\u56e0\u4e3aPython\u4f1a\u628a\u975e\u7a7a\u7684\u503c\u81ea\u52a8\u5224\u5b9a\u4e3aTrue\u3002 \u4e0d\u8981\u628aif\u8bed\u53e5\u3001for\u5faa\u73af\u3001while\u5faa\u73af\u53caexcept\u590d\u5408\u8bed\u53e5\u6324\u5728\u4e00\u884c\u3002\u5e94\u8be5\u628a\u8fd9\u4e9b\u8bed\u53e5\u5206\u6210\u591a\u884c\u6765\u5199\uff0c\u8fd9\u6837\u66f4\u52a0\u6e05\u6670\u3002 \u5982\u679c\u8868\u8fbe\u5f0f\u4e00\u884c\u5199\u4e0d\u4e0b\uff0c\u53ef\u4ee5\u7528\u62ec\u53f7\u5c06\u5176\u62ec\u8d77\u6765\uff0c\u800c\u4e14\u8981\u9002\u5f53\u5730\u6dfb\u52a0\u6362\u884c\u4e0e\u7f29\u8fdb\u4ee5\u4fbf\u4e8e\u9605\u8bfb\u3002\u591a\u884c\u7684\u8868\u8fbe\u5f0f\uff0c\u5e94\u8be5\u7528\u62ec\u53f7\u62ec\u8d77\u6765\uff0c\u800c\u4e0d\u8981\u7528 \u4e0e\u5f15\u5165\u6709\u5173\u7684\u5efa\u8bae \u00b6 PEP 8\u5bf9\u4e8e\u600e\u6837\u5728\u4ee3\u7801\u4e2d\u5f15\u5165\u5e76\u4f7f\u7528\u6a21\u5757\uff0c\u7ed9\u51fa\u4e86\u4e0b\u9762\u51e0\u6761\u5efa\u8bae\u3002 import\u8bed\u53e5\uff08\u542bfrom x import y\uff09\u603b\u662f\u5e94\u8be5\u653e\u5728\u6587\u4ef6\u5f00\u5934\u3002 \u5f15\u5165\u6a21\u5757\u65f6\uff0c\u603b\u662f\u5e94\u8be5\u4f7f\u7528\u7edd\u5bf9\u540d\u79f0\uff0c\u800c\u4e0d\u5e94\u8be5\u6839\u636e\u5f53\u524d\u6a21\u5757\u8def\u5f84\u6765\u4f7f\u7528\u76f8\u5bf9\u540d\u79f0\u3002\u4f8b\u5982\uff0c\u8981\u5f15\u5165bar\u5305\u4e2d\u7684foo\u6a21\u5757\uff0c\u5e94\u8be5\u5b8c\u6574\u5730\u5199\u51fafrom bar import foo\uff0c\u5373\u4fbf\u5f53\u524d\u8def\u5f84\u4e3abar\u5305\u91cc\uff0c\u4e5f\u4e0d\u5e94\u8be5\u7b80\u5199\u4e3aimport foo\u3002 \u5982\u679c\u4e00\u5b9a\u8981\u7528\u76f8\u5bf9\u540d\u79f0\u6765\u7f16\u5199import\u8bed\u53e5\uff0c\u90a3\u5c31\u5e94\u8be5\u660e\u786e\u5730\u5199\u6210\uff1afrom . import foo\u3002 \u6587\u4ef6\u4e2d\u7684import\u8bed\u53e5\u5e94\u8be5\u6309\u987a\u5e8f\u5212\u5206\u6210\u4e09\u4e2a\u90e8\u5206\uff1a\u9996\u5148\u5f15\u5165\u6807\u51c6\u5e93\u91cc\u7684\u6a21\u5757\uff0c\u7136\u540e\u5f15\u5165\u7b2c\u4e09\u65b9\u6a21\u5757\uff0c\u6700\u540e\u5f15\u5165\u81ea\u5df1\u7684\u6a21\u5757\u3002\u5c5e\u4e8e\u540c\u4e00\u4e2a\u90e8\u5206\u7684import\u8bed\u53e5\u6309\u5b57\u6bcd\u987a\u5e8f\u6392\u5217\u3002 \u63d0\u793a \u00b6 Pylint\uff08https://www.pylint.org/\uff09\u662f\u4e00\u6b3e\u6d41\u884c\u7684Python\u6e90\u7801\u9759\u6001\u5206\u6790\u5de5\u5177\u3002","title":"\u7b2c02\u6761 \u9075\u5faaPEP 8\u98ce\u683c\u6307\u5357"},{"location":"python/Pythonic90Rules/Rule02/#2-pep-8","text":"Python Enhancement Proposal #8\u53eb\u4f5cPEP 8\uff0c\u5b83\u662f\u4e00\u4efd\u9488\u5bf9Python\u4ee3\u7801\u683c\u5f0f\u800c\u7f16\u8ba2\u7684\u98ce\u683c\u6307\u5357\u3002 \u5b8c\u6574\u6307\u5357\uff1ahttps://www.python.org/dev/peps/pep-0008","title":"\u7b2c2\u6761\u3000\u9075\u5faaPEP 8\u98ce\u683c\u6307\u5357"},{"location":"python/Pythonic90Rules/Rule02/#_1","text":"\u5728Python\u4e2d\uff0c\u7a7a\u767d\uff08whitespace\uff09\u7684\u4f7f\u7528\u9075\u5faa\u4ee5\u4e0b\u51e0\u6761\u5efa\u8bae\u3002 \u7528\u7a7a\u683c\uff08space\uff09\u8868\u793a\u7f29\u8fdb\uff0c\u800c\u4e0d\u8981\u7528\u5236\u8868\u7b26\uff08tab\uff09\u3002 \u548c\u8bed\u6cd5\u76f8\u5173\u7684\u6bcf\u4e00\u5c42\u7f29\u8fdb\u90fd\u75284\u4e2a\u7a7a\u683c\u8868\u793a\u3002 \u6bcf\u884c\u4e0d\u8d85\u8fc779\u4e2a\u5b57\u7b26\u3002 \u5bf9\u4e8e\u5360\u636e\u591a\u884c\u7684\u957f\u8868\u8fbe\u5f0f\u6765\u8bf4\uff0c\u9664\u4e86\u9996\u884c\u4e4b\u5916\u7684\u5176\u4f59\u5404\u884c\u90fd\u5e94\u8be5\u5728\u901a\u5e38\u7684\u7f29\u8fdb\u7ea7\u522b\u4e4b\u4e0a\u518d\u52a04\u4e2a\u7a7a\u683c\u3002 \u5728\u540c\u4e00\u4efd\u6587\u4ef6\u4e2d\uff0c\u51fd\u6570\u4e0e\u7c7b\u4e4b\u95f4\u7528\u4e24\u4e2a\u7a7a\u884c\u9694\u5f00\u3002 \u5728\u540c\u4e00\u4e2a\u7c7b\u4e2d\uff0c\u65b9\u6cd5\u4e0e\u65b9\u6cd5\u4e4b\u95f4\u7528\u4e00\u4e2a\u7a7a\u884c\u9694\u5f00\u3002 \u4f7f\u7528\u5b57\u5178\u65f6\uff0c\u952e\u4e0e\u5192\u53f7\u4e4b\u95f4\u4e0d\u52a0\u7a7a\u683c\uff0c\u5199\u5728\u540c\u4e00\u884c\u7684\u5192\u53f7\u548c\u503c\u4e4b\u95f4\u5e94\u8be5\u52a0\u4e00\u4e2a\u7a7a\u683c\u3002 \u7ed9\u53d8\u91cf\u8d4b\u503c\u65f6\uff0c\u8d4b\u503c\u7b26\u53f7\u7684\u5de6\u8fb9\u548c\u53f3\u8fb9\u5404\u52a0\u4e00\u4e2a\u7a7a\u683c\uff0c\u5e76\u4e14\u53ea\u52a0\u4e00\u4e2a\u7a7a\u683c\u5c31\u597d\u3002 \u7ed9\u53d8\u91cf\u7684\u7c7b\u578b\u505a\u6ce8\u89e3\uff08annotation\uff09\u65f6\uff0c\u4e0d\u8981\u628a\u53d8\u91cf\u540d\u548c\u5192\u53f7\u9694\u5f00\uff0c\u4f46\u5728\u7c7b\u578b\u4fe1\u606f\u524d\u5e94\u8be5\u6709\u4e00\u4e2a\u7a7a\u683c\u3002","title":"\u4e0e\u7a7a\u767d\u6709\u5173\u7684\u5efa\u8bae"},{"location":"python/Pythonic90Rules/Rule02/#_2","text":"PEP 8\u5efa\u8bae\u91c7\u7528\u4e0d\u540c\u7684\u65b9\u5f0f\u6765\u7ed9Python\u4ee3\u7801\u4e2d\u7684\u5404\u4e2a\u90e8\u5206\u547d\u540d\uff0c\u9075\u5faa\u4ee5\u4e0b\u4e0e\u547d\u540d\u76f8\u5173\u7684\u5efa\u8bae\u3002 \u51fd\u6570\u3001\u53d8\u91cf\u53ca\u5c5e\u6027\u7528\u5c0f\u5199\u5b57\u6bcd\u6765\u62fc\u5199\uff0c\u5404\u5355\u8bcd\u4e4b\u95f4\u7528\u4e0b\u5212\u7ebf\u76f8\u8fde\uff0c\u4f8b\u5982\uff1alowercase_underscore\u3002 \u53d7\u4fdd\u62a4\u7684\u5b9e\u4f8b\u5c5e\u6027\uff0c\u7528\u4e00\u4e2a\u4e0b\u5212\u7ebf\u5f00\u5934\uff0c\u4f8b\u5982\uff1a_leading_underscore\u3002 \u79c1\u6709\u7684\u5b9e\u4f8b\u5c5e\u6027\uff0c\u7528\u4e24\u4e2a\u4e0b\u5212\u7ebf\u5f00\u5934\uff0c\u4f8b\u5982\uff1a__double_leading_underscore\u3002 \u7c7b\uff08\u5305\u62ec\u5f02\u5e38\uff09\u547d\u540d\u65f6\uff0c\u6bcf\u4e2a\u5355\u8bcd\u7684\u9996\u5b57\u6bcd\u5747\u5927\u5199\uff0c\u4f8b\u5982\uff1aCapitalizedWord\u3002 \u6a21\u5757\u7ea7\u522b\u7684\u5e38\u91cf\uff0c\u6240\u6709\u5b57\u6bcd\u90fd\u5927\u5199\uff0c\u5404\u5355\u8bcd\u4e4b\u95f4\u7528\u4e0b\u5212\u7ebf\u76f8\u8fde\uff0c\u4f8b\u5982\uff1aALL_CAPS\u3002 \u7c7b\u4e2d\u7684\u5b9e\u4f8b\u65b9\u6cd5\uff0c\u5e94\u8be5\u628a\u7b2c\u4e00\u4e2a\u53c2\u6570\u547d\u540d\u4e3aself\uff0c\u7528\u6765\u8868\u793a\u8be5\u5bf9\u8c61\u672c\u8eab\u3002 \u7c7b\u65b9\u6cd5\u7684\u7b2c\u4e00\u4e2a\u53c2\u6570\uff0c\u5e94\u8be5\u547d\u540d\u4e3acls\uff0c\u7528\u6765\u8868\u793a\u8fd9\u4e2a\u7c7b\u672c\u8eab\u3002","title":"\u4e0e\u547d\u540d\u6709\u5173\u7684\u5efa\u8bae"},{"location":"python/Pythonic90Rules/Rule02/#_3","text":"The Zen of Python\u4e2d\u63d0\u5230\uff1a\u201c\u6bcf\u4ef6\u4e8b\u90fd\u5e94\u8be5\u6709\u7b80\u5355\u7684\u505a\u6cd5\uff0c\u800c\u4e14\u6700\u597d\u53ea\u6709\u4e00\u79cd\u3002\u201dPEP 8\u5c31\u8bd5\u7740\u8fd0\u7528\u8fd9\u4e2a\u7406\u5ff5\uff0c\u6765\u89c4\u8303\u8868\u8fbe\u5f0f\u548c\u8bed\u53e5\u7684\u5199\u6cd5\u3002 \u91c7\u7528\u884c\u5185\u5426\u5b9a\uff0c\u5373\u628a\u5426\u5b9a\u8bcd\u76f4\u63a5\u5199\u5728\u8981\u5426\u5b9a\u7684\u5185\u5bb9\u524d\u9762\uff0c\u800c\u4e0d\u8981\u653e\u5728\u6574\u4e2a\u8868\u8fbe\u5f0f\u7684\u524d\u9762\uff0c\u4f8b\u5982\u5e94\u8be5\u5199if a is not b\uff0c\u800c\u4e0d\u662fif not a is b\u3002 \u4e0d\u8981\u901a\u8fc7\u957f\u5ea6\u5224\u65ad\u5bb9\u5668\u6216\u5e8f\u5217\u662f\u4e0d\u662f\u7a7a\u7684\uff0c\u4f8b\u5982\u4e0d\u8981\u901a\u8fc7if len(somelist) == 0\u5224\u65adsomelist\u662f\u5426\u4e3a[]\u6216''\u7b49\u7a7a\u503c\uff0c\u800c\u662f\u5e94\u8be5\u91c7\u7528if not somelist\u8fd9\u6837\u7684\u5199\u6cd5\u6765\u5224\u65ad\uff0c\u56e0\u4e3aPython\u4f1a\u628a\u7a7a\u503c\u81ea\u52a8\u8bc4\u4f30\u4e3aFalse\u3002 \u5982\u679c\u8981\u5224\u65ad\u5bb9\u5668\u6216\u5e8f\u5217\u91cc\u9762\u6709\u6ca1\u6709\u5185\u5bb9\uff08\u6bd4\u5982\u8981\u5224\u65ad somelist \u662f\u5426\u4e3a[1]\u6216'hi'\u8fd9\u6837\u975e\u7a7a\u7684\u503c\uff09\uff0c\u4e5f\u4e0d\u5e94\u8be5\u901a\u8fc7\u957f\u5ea6\u6765\u5224\u65ad\uff0c\u800c\u662f\u5e94\u8be5\u91c7\u7528if somelist \u8bed\u53e5\uff0c\u56e0\u4e3aPython\u4f1a\u628a\u975e\u7a7a\u7684\u503c\u81ea\u52a8\u5224\u5b9a\u4e3aTrue\u3002 \u4e0d\u8981\u628aif\u8bed\u53e5\u3001for\u5faa\u73af\u3001while\u5faa\u73af\u53caexcept\u590d\u5408\u8bed\u53e5\u6324\u5728\u4e00\u884c\u3002\u5e94\u8be5\u628a\u8fd9\u4e9b\u8bed\u53e5\u5206\u6210\u591a\u884c\u6765\u5199\uff0c\u8fd9\u6837\u66f4\u52a0\u6e05\u6670\u3002 \u5982\u679c\u8868\u8fbe\u5f0f\u4e00\u884c\u5199\u4e0d\u4e0b\uff0c\u53ef\u4ee5\u7528\u62ec\u53f7\u5c06\u5176\u62ec\u8d77\u6765\uff0c\u800c\u4e14\u8981\u9002\u5f53\u5730\u6dfb\u52a0\u6362\u884c\u4e0e\u7f29\u8fdb\u4ee5\u4fbf\u4e8e\u9605\u8bfb\u3002\u591a\u884c\u7684\u8868\u8fbe\u5f0f\uff0c\u5e94\u8be5\u7528\u62ec\u53f7\u62ec\u8d77\u6765\uff0c\u800c\u4e0d\u8981\u7528","title":"\u4e0e\u8868\u8fbe\u5f0f\u548c\u8bed\u53e5\u6709\u5173\u7684\u5efa\u8bae"},{"location":"python/Pythonic90Rules/Rule02/#_4","text":"PEP 8\u5bf9\u4e8e\u600e\u6837\u5728\u4ee3\u7801\u4e2d\u5f15\u5165\u5e76\u4f7f\u7528\u6a21\u5757\uff0c\u7ed9\u51fa\u4e86\u4e0b\u9762\u51e0\u6761\u5efa\u8bae\u3002 import\u8bed\u53e5\uff08\u542bfrom x import y\uff09\u603b\u662f\u5e94\u8be5\u653e\u5728\u6587\u4ef6\u5f00\u5934\u3002 \u5f15\u5165\u6a21\u5757\u65f6\uff0c\u603b\u662f\u5e94\u8be5\u4f7f\u7528\u7edd\u5bf9\u540d\u79f0\uff0c\u800c\u4e0d\u5e94\u8be5\u6839\u636e\u5f53\u524d\u6a21\u5757\u8def\u5f84\u6765\u4f7f\u7528\u76f8\u5bf9\u540d\u79f0\u3002\u4f8b\u5982\uff0c\u8981\u5f15\u5165bar\u5305\u4e2d\u7684foo\u6a21\u5757\uff0c\u5e94\u8be5\u5b8c\u6574\u5730\u5199\u51fafrom bar import foo\uff0c\u5373\u4fbf\u5f53\u524d\u8def\u5f84\u4e3abar\u5305\u91cc\uff0c\u4e5f\u4e0d\u5e94\u8be5\u7b80\u5199\u4e3aimport foo\u3002 \u5982\u679c\u4e00\u5b9a\u8981\u7528\u76f8\u5bf9\u540d\u79f0\u6765\u7f16\u5199import\u8bed\u53e5\uff0c\u90a3\u5c31\u5e94\u8be5\u660e\u786e\u5730\u5199\u6210\uff1afrom . import foo\u3002 \u6587\u4ef6\u4e2d\u7684import\u8bed\u53e5\u5e94\u8be5\u6309\u987a\u5e8f\u5212\u5206\u6210\u4e09\u4e2a\u90e8\u5206\uff1a\u9996\u5148\u5f15\u5165\u6807\u51c6\u5e93\u91cc\u7684\u6a21\u5757\uff0c\u7136\u540e\u5f15\u5165\u7b2c\u4e09\u65b9\u6a21\u5757\uff0c\u6700\u540e\u5f15\u5165\u81ea\u5df1\u7684\u6a21\u5757\u3002\u5c5e\u4e8e\u540c\u4e00\u4e2a\u90e8\u5206\u7684import\u8bed\u53e5\u6309\u5b57\u6bcd\u987a\u5e8f\u6392\u5217\u3002","title":"\u4e0e\u5f15\u5165\u6709\u5173\u7684\u5efa\u8bae"},{"location":"python/Pythonic90Rules/Rule02/#_5","text":"Pylint\uff08https://www.pylint.org/\uff09\u662f\u4e00\u6b3e\u6d41\u884c\u7684Python\u6e90\u7801\u9759\u6001\u5206\u6790\u5de5\u5177\u3002","title":"\u63d0\u793a"},{"location":"python/Pythonic90Rules/Rule03/","text":"\u7b2c3\u6761\u3000\u4e86\u89e3bytes\u4e0estr\u7684\u533a\u522b \u00b6 UNICODE\u7f16\u7801\u7b80\u4ecb \u00b6 ASCII\u7f16\u7801\u89c4\u5b9a1\u4e2a\u5b57\u8282\u7b49\u4e8e8\u4e2a\u6bd4\u7279\u4f4d\uff0c\u4ee3\u88681\u4e2a\u5b57\u7b26\u7684\u7f16\u7801\uff0c\u9664\u4e86\u7b2c\u4e00\u4f4d\u662f0\uff0c \u5176\u4ed67\u4f4d\u90fd\u53ef\u4ee5\u67090 \u6216\u8005 1 \u4e24\u4e2a\u9009\u62e9\uff0c\u6240\u4ee5ASCII \u4e00\u5171\u53ef\u4ee5\u8868\u793a 2^7 \uff0c\u4e5f\u5c31\u662f128\u4e2a\u5b57\u7b26\u3002\u5305\u62eca-z \u5927\u5c0f\u5199\uff0c0-9 \u6570\u5b57 \u548c\u4e00\u4e9b\u6807\u70b9\u7b26\u53f7\u7b49\u3002\u5176\u4e2d\u771f\u6b63\u53ef\u8bfb\u7684\u53ea\u670995 \u4e2a\u5b57\u7b26\uff0c\u5176\u4ed6\u7684\u90fd\u662f\u4e00\u4e9b\u63a7\u5236\u7b26\uff0c\u6bd4\u5982NUL\uff0c\u4ee3\u8868NULL\u3002 \u591a\u5b57\u8282\u7f16\u7801\uff0c\u6bd4\u5982\u53cc\u5b57\u8282\u7f16\u7801\u65b9\u5f0f\uff0cBIG-5\u548cGB18030\u5305\u542b\u4e86\u5927\u591a\u6570\u4e2d\u6587\u7b80\u4f53\u548c\u7e41\u4f53\u3002\u8fd9\u4e2a\u7f16\u7801\u4e0d\u517c\u5bb9ASCII\uff0c\u540c\u65f6\u8fd8\u5360\u7528\u8f83\u591a\u7684\u7a7a\u95f4\u548c\u5185\u5b58\u3002 UNICODE\u4e0d\u662f\u4e00\u79cd\u7f16\u7801\uff0c \u800c\u662f\u5b9a\u4e49\u4e86\u4e00\u4e2a\u8868\uff0c \u8868\u4e2d\u4e3a\u4e16\u754c\u4e0a\u6bcf\u79cd\u8bed\u8a00\u4e2d\u7684\u6bcf\u4e2a\u5b57\u7b26\u8bbe\u5b9a\u4e86\u7edf\u4e00\u5e76\u4e14\u552f\u4e00\u7684\u7801\u4f4d \uff08code point\uff09\uff0c\u4ee5\u6ee1\u8db3\u8de8\u8bed\u8a00\u3001\u8de8\u5e73\u53f0\u8fdb\u884c\u6587\u672c\u8f6c\u6362\u7684\u8981\u6c42\u3002 UTF-8\u7f16\u7801\u89c4\u5b9a\u82f1\u6587\u5b57\u6bcd\u7cfb\u5217\u75281\u4e2a\u5b57\u8282\u8868\u793a\uff0c\u6c49\u5b57\u75283\u4e2a\u5b57\u8282\u8868\u793a\u7b49\u7b49\u3002UTF-8\u7684\u7279\u70b9\u662f\u5bf9\u4e0d\u540c\u8303\u56f4\u7684\u5b57\u7b26\u4f7f\u7528\u4e0d\u540c\u957f\u5ea6\u7684\u7f16\u7801\u3002 \u4e0b\u8868\u8868\u793a\u5982\u4f55\u4ece\u4e00\u4e2a\u4eceUnicode \u8f6c\u5316\u5230UTF-8 , \u5bf9\u4e8e\u524d0x7F\u7684\u5b57\u7b26\uff0cUTF-8\u7f16\u7801\u548cASCII\u7801\u662f\u4e00\u4e00\u5bf9\u5e94\u7684\u3002 \u5982\u679c\u4e00\u4e2a\u5b57\u7b26\u5728000800-00FFFF \u4e4b\u95f4\uff0c\u90a3\u8f6c\u5316\u5230UTF-8 \u9700\u8981\u7528\u4e09\u5b57\u8282\u6a21\u677f\uff0c\u4f7f\u752816\u4e2a\u7801\u4f4d\uff0c\u6bcf\u4e2ax\u5c31\u662f\u4e00\u4e2a\u7801\u4f4d\u3002 Unicode\u7f16\u7801\uff08\u5341\u516d\u8fdb\u5236\uff09 UTF-8\u5b57\u8282\u6d41\uff08\u4e8c\u8fdb\u5236\uff09 000000 - 00007F 0xxxxxxx 000080 - 0007FF 110xxxx 10xxxxxx 000800 - 00FFFF 1110xxxx 10xxxxxx 10xxxxxx 010000 - 10FFFF 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx Python\u6709\u4e24\u79cd\u7c7b\u578b\u53ef\u4ee5\u8868\u793a\u5b57\u7b26\u5e8f\u5217(sequence)\uff1a\u4e00\u79cd\u662fbytes\uff0c\u53e6\u4e00\u79cd\u662fstr\u3002 bytes\u5b9e\u4f8b\u5305\u542b\u7684\u662f\u539f\u59cb\u6570\u636e\uff0c\u53738\u4f4d\u7684\u65e0\u7b26\u53f7\u503c\uff08\u901a\u5e38\u6309\u7167ASCII\u7f16\u7801\u6807\u51c6\u6765\u663e\u793a\uff09\u3002 str\u5b9e\u4f8b\u5305\u542b\u7684\u662fUnicode\u7801\u70b9\uff08code point\uff0c\u4e5f\u53eb\u4f5c\u4ee3\u7801\u70b9\uff09\uff0c\u8fd9\u4e9b\u7801\u70b9\u4e0e\u4eba\u7c7b\u8bed\u8a00\u4e4b\u4e2d\u7684\u6587\u672c\u5b57\u7b26\u76f8\u5bf9\u5e94\u3002 >>> a = b'h\\x65llo' >>> a b'hello' >>> list(a) [104, 101, 108, 108, 111] >>> b = 'a\\u0300 hello' >>> b 'a\u0300 hello' >>> list(b) ['a', '\u0300', ' ', 'h', 'e', 'l', 'l', 'o'] \u5185\u5b58\u662funicode\u7f16\u7801\u683c\u5f0f\uff0c\u786c\u76d8\u662futf-8\u3002 \u5728\u505a\u7f16\u7801\u8f6c\u6362\u65f6\u5019\uff0c\u901a\u5e38\u7528unicode\u4f5c\u4e3a\u4e2d\u95f4\u7f16\u7801\u3002 \u5148\u5c06\u5176\u4ed6\u7f16\u7801\u7684\u5b57\u7b26\u4e32\u89e3\u7801(decode)\u6210unicode,\u518d\u4eceunicode\u7f16\u7801(encode)\u6210\u53e6\u4e00\u79cd\u7f16\u7801\u683c\u5f0f\u3002 decode\u7684\u4f5c\u7528\u662f\u5c06\u4e8c\u8fdb\u5236\u6570\u636e\u89e3\u7801\u6210unicode\u7f16\u7801\u3002 encode\u7684\u4f5c\u7528\u662f\u5c06unicode\u7f16\u7801\u7684\u5b57\u7b26\u4e32\u7f16\u7801\u6210\u4e8c\u8fdb\u5236\u6570\u636e\u3002 \u8981\u628aUnicode\u6570\u636e\u8f6c\u6362\u6210\u4e8c\u8fdb\u5236\u6570\u636e\uff0c\u5fc5\u987b\u8c03\u7528str\u7684encode\u65b9\u6cd5\u3002 \u8981\u628a\u4e8c\u8fdb\u5236\u6570\u636e\u8f6c\u6362\u6210Unicode\u6570\u636e\uff0c\u5fc5\u987b\u8c03\u7528bytes\u7684decode\u65b9\u6cd5\u3002 \u8c03\u7528\u8fd9\u4e9b\u65b9\u6cd5\u7684\u65f6\u5019\uff0c\u53ef\u4ee5\u660e\u786e\u6307\u51fa\u81ea\u5df1\u8981\u4f7f\u7528\u7684\u7f16\u7801\u65b9\u6848\uff0c\u4e5f\u53ef\u4ee5\u91c7\u7528\u7cfb\u7edf\u9ed8\u8ba4\u7684\u65b9\u6848\uff0c\u901a\u5e38\u662f\u6307UTF-8\u3002 \u5728bytes\u548cstr\u7684\u4e92\u76f8\u8f6c\u6362\u8fc7\u7a0b\u4e2d\uff0c\u5b9e\u9645\u5c31\u662f\u7f16\u7801\u89e3\u7801\u7684\u8fc7\u7a0b\uff0c\u5fc5\u987b\u663e\u5f0f\u5730\u6307\u5b9a\u7f16\u7801\u683c\u5f0f\u3002 >>> s = '\u4e2d\u6587' >>> s '\u4e2d\u6587' >>> type(s) >>> b = bytes(s, encoding='utf-8') >>> b b'\\xe4\\xb8\\xad\\xe6\\x96\\x87' >>> type(b) >>> s.encode('utf-8') b'\\xe4\\xb8\\xad\\xe6\\x96\\x87' >>> b.decode('utf-8') '\u4e2d\u6587' >>> >>> str(b, encoding='utf-8') '\u4e2d\u6587' \u7f16\u5199Python\u7a0b\u5e8f\u7684\u65f6\u5019\uff0c\u4e00\u5b9a\u8981\u628a\u89e3\u7801\u548c\u7f16\u7801\u64cd\u4f5c\u653e\u5728\u754c\u9762\u6700\u5916\u5c42\u6765\u505a\uff0c\u8ba9\u7a0b\u5e8f\u7684\u6838\u5fc3\u90e8\u5206\u53ef\u4ee5\u4f7f\u7528Unicode\u6570\u636e\u6765\u8fd0\u4f5c\uff0c\u8fd9\u79cd\u529e\u6cd5\u901a\u5e38\u53eb\u4f5cUnicode\u4e09\u660e\u6cbb\uff08Unicode sandwich\uff09\u3002 \u6211\u4eec\u53ef\u4ee5\u7f16\u5199\u8f85\u52a9\u51fd\u6570\u6765\u786e\u4fdd\u7a0b\u5e8f\u6536\u5230\u7684\u5b57\u7b26\u5e8f\u5217\u786e\u5b9e\u662f\u671f\u671b\u8981\u64cd\u4f5c\u7684\u7c7b\u578b\uff08\u8981\u77e5\u9053\u81ea\u5df1\u60f3\u64cd\u4f5c\u7684\u5230\u5e95\u662fUnicode\u7801\u70b9\uff0c\u8fd8\u662f\u539f\u59cb\u76848\u4f4d\u503c\u3002\u7528UTF-8\u6807\u51c6\u7ed9\u5b57\u7b26\u4e32\u7f16\u7801\uff0c\u5f97\u5230\u7684\u5c31\u662f\u8fd9\u6837\u7684\u4e00\u7cfb\u52178\u4f4d\u503c\uff09\u3002 \u8f85\u52a9\u51fd\u6570to_str\u63a5\u53d7bytes\u6216str\u5b9e\u4f8b\uff0c\u5e76\u8fd4\u56destr\uff1a >>> def to_str(bytes_or_str): ... if isinstance(bytes_or_str, bytes): ... value = bytes_or_str.decode('utf-8') ... else: ... value = bytes_or_str ... return value ... >>> repr(to_str(b'foo')) \"'foo'\" >>> repr(to_str('foo')) \"'foo'\" >>> to_str('foo') 'foo' >>> to_str(b'foo') 'foo' \u8f85\u52a9\u51fd\u6570to_bytes\u63a5\u53d7bytes\u6216str\u5b9e\u4f8b\uff0c\u5e76\u8fd4\u56debytes\uff1a >>> def to_bytes(bytes_or_str): ... if isinstance(bytes_or_str, str): ... value = bytes_or_str.encode('utf-8') ... else: ... value = bytes_or_str ... return value ... >>> repr(to_bytes(b'foo')) \"b'foo'\" >>> repr(to_bytes('foo')) \"b'foo'\" >>> to_bytes(b'foo') b'foo' >>> to_bytes('foo') bytes\u4e0estr\u8fd9\u4e24\u79cd\u5b9e\u4f8b\u4e0d\u80fd\u5728\u67d0\u4e9b\u64cd\u4f5c\u7b26\uff08\u4f8b\u5982>\u3001==\u3001+\u3001%\u64cd\u4f5c\u7b26\uff09\u4e0a\u9762\u6df7\u7528\u3002 >>> b'one' + b'two' b'onetwo' >>> 'one'+'two' 'onetwo' \u4e0d\u80fd\u5c06str\u5b9e\u4f8b\u6dfb\u52a0\u5230bytes\u5b9e\u4f8b\uff1a >>> b'one' + 'two' Traceback (most recent call last): File \"\", line 1, in TypeError: can't concat str to bytes \u4e0d\u80fd\u5c06byte\u5b9e\u4f8b\u6dfb\u52a0\u5230str\u5b9e\u4f8b\uff1a > > > 'one' + b'two' Traceback (most recent call last): File \"\", line 1, in TypeError: can only concatenate str (not \"bytes\") to str str\u5b9e\u4f8b\u4e0d\u80fd\u4e0ebytes\u5b9e\u4f8b\u6bd4\u8f83\uff0c\u5373\u4fbf\u8fd9\u4e24\u4e2a\u5b9e\u4f8b\u8868\u793a\u7684\u5b57\u7b26\u5b8c\u5168\u76f8\u540c\uff0c\u5b83\u4eec\u4e5f\u4e0d\u76f8\u7b49\uff1a >>> assert 'red' >= b'red' Traceback (most recent call last): File \"\", line 1, in TypeError: '>=' not supported between instances of 'str' and 'bytes' >>> assert b'red' >= 'red' Traceback (most recent call last): File \"\", line 1, in TypeError: '>=' not supported between instances of 'bytes' and 'str' \u4e24\u79cd\u7c7b\u578b\u7684\u5b9e\u4f8b\u90fd\u53ef\u4ee5\u51fa\u73b0\u5728%\u64cd\u4f5c\u7b26\u7684\u53f3\u4fa7\uff0c\u7528\u6765\u66ff\u6362\u5de6\u4fa7\u90a3\u4e2a\u683c\u5f0f\u5b57\u7b26\u4e32\uff08format string\uff09\u91cc\u9762\u7684%s\u3002 >>> print(b'red %s' % b'blue') b'red blue' >>> print('red %s' % 'blue') red blue \u5982\u679c\u683c\u5f0f\u5b57\u7b26\u4e32\u662fbytes\u7c7b\u578b\uff0c\u90a3\u4e48\u4e0d\u80fd\u7528str\u5b9e\u4f8b\u6765\u66ff\u6362\u5176\u4e2d\u7684%s\u3002 \u5982\u679c\u683c\u5f0f\u5b57\u7b26\u4e32\u662fstr\u7c7b\u578b\uff0c\u5219\u53ef\u4ee5\u7528bytes\u5b9e\u4f8b\u6765\u66ff\u6362\u5176\u4e2d\u7684%s\u3002(\u7cfb\u7edf\u5728bytes\u5b9e\u4f8b\u4e0a\u9762\u8c03\u7528__repr__ \u65b9\u6cd5\uff08Rule75\uff09\uff0c\u7136\u540e\u7528\u8fd9\u6b21\u8c03\u7528\u6240\u5f97\u5230\u7684\u7ed3\u679c\u66ff\u6362\u683c\u5f0f\u5b57\u7b26\u4e32\u91cc\u7684%s\uff0c\u56e0\u6b64\u7a0b\u5e8f\u4f1a\u76f4\u63a5\u8f93\u51fab'blue'\uff0c\u800c\u4e0d\u662f\u8f93\u51fablue\u672c\u8eab\u3002) >>> print(b'red %s' % 'blue') Traceback (most recent call last): File \"\", line 1, in TypeError: %b requires a bytes-like object, or an object that implements __bytes__, not 'str' >>> print('red %s' % b'blue') red b'blue' \u5728\u64cd\u4f5c\u6587\u4ef6\u53e5\u67c4\u7684\u65f6\u5019\uff0c\u8fd9\u91cc\u7684\u53e5\u67c4\u6307\u7531\u5185\u7f6e\u7684open\u51fd\u6570\u8fd4\u56de\u7684\u53e5\u67c4\u3002\u8fd9\u6837\u7684\u53e5\u67c4\u9ed8\u8ba4\u9700\u8981\u4f7f\u7528Unicode\u5b57\u7b26\u4e32\u64cd\u4f5c\uff0c\u800c\u4e0d\u80fd\u91c7\u7528\u539f\u59cb\u7684bytes\u3002 \u4ece\u6587\u4ef6\u4e2d\u8bfb\u53d6\u4e8c\u8fdb\u5236\u6570\u636e\uff08\u6216\u8005\u628a\u4e8c\u8fdb\u5236\u6570\u636e\u5199\u5165\u6587\u4ef6\uff09\u65f6\uff0c\u5e94\u8be5\u7528'rb'\uff08'wb'\uff09\u8fd9\u6837\u7684\u4e8c\u8fdb\u5236\u6a21\u5f0f\u6253\u5f00\u6587\u4ef6\u3002 >>> with open('./temp/data.bin', 'w') as f: ... f.write(b'\\xf1\\xf2\\xf3\\xf4\\xf5') ... Traceback (most recent call last): File \"\", line 2, in TypeError: write() argument must be str, not bytes >>> >>> with open('./temp/data.bin', 'wb') as f: ... f.write(b'\\xf1\\xf2\\xf3\\xf4\\xf5') ... 5 >>> >>> with open('./temp/data.bin', 'r') as f: ... data = f.read() ... Traceback (most recent call last): File \"\", line 2, in File \"/usr/local/lib/python3.9/codecs.py\", line 322, in decode (result, consumed) = self._buffer_decode(data, self.errors, final) UnicodeDecodeError: 'utf-8' codec can't decode byte 0xf1 in position 0: invalid continuation byte >>> >>> >>> with open('./temp/data.bin', 'rb') as f: ... data = f.read() ... >>> assert data == b'\\xf1\\xf2\\xf3\\xf4\\xf5' >>> \u5982\u679c\u8981\u4ece\u6587\u4ef6\u4e2d\u8bfb\u53d6\uff08\u6216\u8005\u8981\u5199\u5165\u6587\u4ef6\u4e4b\u4e2d\uff09\u7684\u662fUnicode\u6570\u636e\uff0c\u90a3\u4e48\u5fc5\u987b\u6ce8\u610f\u7cfb\u7edf\u9ed8\u8ba4\u7684\u6587\u672c\u7f16\u7801\u65b9\u6848\u3002\u82e5\u65e0\u6cd5\u80af\u5b9a\uff0c\u53ef\u901a\u8fc7encoding\u53c2\u6570\u660e\u786e\u6307\u5b9a\u3002 >>> with open('./temp/data.bin', 'r', encoding='cp1252') as f: ... data = f.read() ... >>> assert data == b'\\xf1\\xf2\\xf3\\xf4\\xf5' Traceback (most recent call last): File \"\", line 1, in AssertionError \u67e5\u770b\u5f53\u524d\u64cd\u4f5c\u7cfb\u7edf\u9ed8\u8ba4\u7684\u7f16\u7801\u6807\u51c6 >>> import locale >>> locale.getpreferredencoding() 'UTF-8' >>>","title":"\u7b2c03\u6761 \u4e86\u89e3bytes\u4e0estr\u7684\u533a\u522b"},{"location":"python/Pythonic90Rules/Rule03/#3-bytesstr","text":"","title":"\u7b2c3\u6761\u3000\u4e86\u89e3bytes\u4e0estr\u7684\u533a\u522b"},{"location":"python/Pythonic90Rules/Rule03/#unicode","text":"ASCII\u7f16\u7801\u89c4\u5b9a1\u4e2a\u5b57\u8282\u7b49\u4e8e8\u4e2a\u6bd4\u7279\u4f4d\uff0c\u4ee3\u88681\u4e2a\u5b57\u7b26\u7684\u7f16\u7801\uff0c\u9664\u4e86\u7b2c\u4e00\u4f4d\u662f0\uff0c \u5176\u4ed67\u4f4d\u90fd\u53ef\u4ee5\u67090 \u6216\u8005 1 \u4e24\u4e2a\u9009\u62e9\uff0c\u6240\u4ee5ASCII \u4e00\u5171\u53ef\u4ee5\u8868\u793a 2^7 \uff0c\u4e5f\u5c31\u662f128\u4e2a\u5b57\u7b26\u3002\u5305\u62eca-z \u5927\u5c0f\u5199\uff0c0-9 \u6570\u5b57 \u548c\u4e00\u4e9b\u6807\u70b9\u7b26\u53f7\u7b49\u3002\u5176\u4e2d\u771f\u6b63\u53ef\u8bfb\u7684\u53ea\u670995 \u4e2a\u5b57\u7b26\uff0c\u5176\u4ed6\u7684\u90fd\u662f\u4e00\u4e9b\u63a7\u5236\u7b26\uff0c\u6bd4\u5982NUL\uff0c\u4ee3\u8868NULL\u3002 \u591a\u5b57\u8282\u7f16\u7801\uff0c\u6bd4\u5982\u53cc\u5b57\u8282\u7f16\u7801\u65b9\u5f0f\uff0cBIG-5\u548cGB18030\u5305\u542b\u4e86\u5927\u591a\u6570\u4e2d\u6587\u7b80\u4f53\u548c\u7e41\u4f53\u3002\u8fd9\u4e2a\u7f16\u7801\u4e0d\u517c\u5bb9ASCII\uff0c\u540c\u65f6\u8fd8\u5360\u7528\u8f83\u591a\u7684\u7a7a\u95f4\u548c\u5185\u5b58\u3002 UNICODE\u4e0d\u662f\u4e00\u79cd\u7f16\u7801\uff0c \u800c\u662f\u5b9a\u4e49\u4e86\u4e00\u4e2a\u8868\uff0c \u8868\u4e2d\u4e3a\u4e16\u754c\u4e0a\u6bcf\u79cd\u8bed\u8a00\u4e2d\u7684\u6bcf\u4e2a\u5b57\u7b26\u8bbe\u5b9a\u4e86\u7edf\u4e00\u5e76\u4e14\u552f\u4e00\u7684\u7801\u4f4d \uff08code point\uff09\uff0c\u4ee5\u6ee1\u8db3\u8de8\u8bed\u8a00\u3001\u8de8\u5e73\u53f0\u8fdb\u884c\u6587\u672c\u8f6c\u6362\u7684\u8981\u6c42\u3002 UTF-8\u7f16\u7801\u89c4\u5b9a\u82f1\u6587\u5b57\u6bcd\u7cfb\u5217\u75281\u4e2a\u5b57\u8282\u8868\u793a\uff0c\u6c49\u5b57\u75283\u4e2a\u5b57\u8282\u8868\u793a\u7b49\u7b49\u3002UTF-8\u7684\u7279\u70b9\u662f\u5bf9\u4e0d\u540c\u8303\u56f4\u7684\u5b57\u7b26\u4f7f\u7528\u4e0d\u540c\u957f\u5ea6\u7684\u7f16\u7801\u3002 \u4e0b\u8868\u8868\u793a\u5982\u4f55\u4ece\u4e00\u4e2a\u4eceUnicode \u8f6c\u5316\u5230UTF-8 , \u5bf9\u4e8e\u524d0x7F\u7684\u5b57\u7b26\uff0cUTF-8\u7f16\u7801\u548cASCII\u7801\u662f\u4e00\u4e00\u5bf9\u5e94\u7684\u3002 \u5982\u679c\u4e00\u4e2a\u5b57\u7b26\u5728000800-00FFFF \u4e4b\u95f4\uff0c\u90a3\u8f6c\u5316\u5230UTF-8 \u9700\u8981\u7528\u4e09\u5b57\u8282\u6a21\u677f\uff0c\u4f7f\u752816\u4e2a\u7801\u4f4d\uff0c\u6bcf\u4e2ax\u5c31\u662f\u4e00\u4e2a\u7801\u4f4d\u3002 Unicode\u7f16\u7801\uff08\u5341\u516d\u8fdb\u5236\uff09 UTF-8\u5b57\u8282\u6d41\uff08\u4e8c\u8fdb\u5236\uff09 000000 - 00007F 0xxxxxxx 000080 - 0007FF 110xxxx 10xxxxxx 000800 - 00FFFF 1110xxxx 10xxxxxx 10xxxxxx 010000 - 10FFFF 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx Python\u6709\u4e24\u79cd\u7c7b\u578b\u53ef\u4ee5\u8868\u793a\u5b57\u7b26\u5e8f\u5217(sequence)\uff1a\u4e00\u79cd\u662fbytes\uff0c\u53e6\u4e00\u79cd\u662fstr\u3002 bytes\u5b9e\u4f8b\u5305\u542b\u7684\u662f\u539f\u59cb\u6570\u636e\uff0c\u53738\u4f4d\u7684\u65e0\u7b26\u53f7\u503c\uff08\u901a\u5e38\u6309\u7167ASCII\u7f16\u7801\u6807\u51c6\u6765\u663e\u793a\uff09\u3002 str\u5b9e\u4f8b\u5305\u542b\u7684\u662fUnicode\u7801\u70b9\uff08code point\uff0c\u4e5f\u53eb\u4f5c\u4ee3\u7801\u70b9\uff09\uff0c\u8fd9\u4e9b\u7801\u70b9\u4e0e\u4eba\u7c7b\u8bed\u8a00\u4e4b\u4e2d\u7684\u6587\u672c\u5b57\u7b26\u76f8\u5bf9\u5e94\u3002 >>> a = b'h\\x65llo' >>> a b'hello' >>> list(a) [104, 101, 108, 108, 111] >>> b = 'a\\u0300 hello' >>> b 'a\u0300 hello' >>> list(b) ['a', '\u0300', ' ', 'h', 'e', 'l', 'l', 'o'] \u5185\u5b58\u662funicode\u7f16\u7801\u683c\u5f0f\uff0c\u786c\u76d8\u662futf-8\u3002 \u5728\u505a\u7f16\u7801\u8f6c\u6362\u65f6\u5019\uff0c\u901a\u5e38\u7528unicode\u4f5c\u4e3a\u4e2d\u95f4\u7f16\u7801\u3002 \u5148\u5c06\u5176\u4ed6\u7f16\u7801\u7684\u5b57\u7b26\u4e32\u89e3\u7801(decode)\u6210unicode,\u518d\u4eceunicode\u7f16\u7801(encode)\u6210\u53e6\u4e00\u79cd\u7f16\u7801\u683c\u5f0f\u3002 decode\u7684\u4f5c\u7528\u662f\u5c06\u4e8c\u8fdb\u5236\u6570\u636e\u89e3\u7801\u6210unicode\u7f16\u7801\u3002 encode\u7684\u4f5c\u7528\u662f\u5c06unicode\u7f16\u7801\u7684\u5b57\u7b26\u4e32\u7f16\u7801\u6210\u4e8c\u8fdb\u5236\u6570\u636e\u3002 \u8981\u628aUnicode\u6570\u636e\u8f6c\u6362\u6210\u4e8c\u8fdb\u5236\u6570\u636e\uff0c\u5fc5\u987b\u8c03\u7528str\u7684encode\u65b9\u6cd5\u3002 \u8981\u628a\u4e8c\u8fdb\u5236\u6570\u636e\u8f6c\u6362\u6210Unicode\u6570\u636e\uff0c\u5fc5\u987b\u8c03\u7528bytes\u7684decode\u65b9\u6cd5\u3002 \u8c03\u7528\u8fd9\u4e9b\u65b9\u6cd5\u7684\u65f6\u5019\uff0c\u53ef\u4ee5\u660e\u786e\u6307\u51fa\u81ea\u5df1\u8981\u4f7f\u7528\u7684\u7f16\u7801\u65b9\u6848\uff0c\u4e5f\u53ef\u4ee5\u91c7\u7528\u7cfb\u7edf\u9ed8\u8ba4\u7684\u65b9\u6848\uff0c\u901a\u5e38\u662f\u6307UTF-8\u3002 \u5728bytes\u548cstr\u7684\u4e92\u76f8\u8f6c\u6362\u8fc7\u7a0b\u4e2d\uff0c\u5b9e\u9645\u5c31\u662f\u7f16\u7801\u89e3\u7801\u7684\u8fc7\u7a0b\uff0c\u5fc5\u987b\u663e\u5f0f\u5730\u6307\u5b9a\u7f16\u7801\u683c\u5f0f\u3002 >>> s = '\u4e2d\u6587' >>> s '\u4e2d\u6587' >>> type(s) >>> b = bytes(s, encoding='utf-8') >>> b b'\\xe4\\xb8\\xad\\xe6\\x96\\x87' >>> type(b) >>> s.encode('utf-8') b'\\xe4\\xb8\\xad\\xe6\\x96\\x87' >>> b.decode('utf-8') '\u4e2d\u6587' >>> >>> str(b, encoding='utf-8') '\u4e2d\u6587' \u7f16\u5199Python\u7a0b\u5e8f\u7684\u65f6\u5019\uff0c\u4e00\u5b9a\u8981\u628a\u89e3\u7801\u548c\u7f16\u7801\u64cd\u4f5c\u653e\u5728\u754c\u9762\u6700\u5916\u5c42\u6765\u505a\uff0c\u8ba9\u7a0b\u5e8f\u7684\u6838\u5fc3\u90e8\u5206\u53ef\u4ee5\u4f7f\u7528Unicode\u6570\u636e\u6765\u8fd0\u4f5c\uff0c\u8fd9\u79cd\u529e\u6cd5\u901a\u5e38\u53eb\u4f5cUnicode\u4e09\u660e\u6cbb\uff08Unicode sandwich\uff09\u3002 \u6211\u4eec\u53ef\u4ee5\u7f16\u5199\u8f85\u52a9\u51fd\u6570\u6765\u786e\u4fdd\u7a0b\u5e8f\u6536\u5230\u7684\u5b57\u7b26\u5e8f\u5217\u786e\u5b9e\u662f\u671f\u671b\u8981\u64cd\u4f5c\u7684\u7c7b\u578b\uff08\u8981\u77e5\u9053\u81ea\u5df1\u60f3\u64cd\u4f5c\u7684\u5230\u5e95\u662fUnicode\u7801\u70b9\uff0c\u8fd8\u662f\u539f\u59cb\u76848\u4f4d\u503c\u3002\u7528UTF-8\u6807\u51c6\u7ed9\u5b57\u7b26\u4e32\u7f16\u7801\uff0c\u5f97\u5230\u7684\u5c31\u662f\u8fd9\u6837\u7684\u4e00\u7cfb\u52178\u4f4d\u503c\uff09\u3002 \u8f85\u52a9\u51fd\u6570to_str\u63a5\u53d7bytes\u6216str\u5b9e\u4f8b\uff0c\u5e76\u8fd4\u56destr\uff1a >>> def to_str(bytes_or_str): ... if isinstance(bytes_or_str, bytes): ... value = bytes_or_str.decode('utf-8') ... else: ... value = bytes_or_str ... return value ... >>> repr(to_str(b'foo')) \"'foo'\" >>> repr(to_str('foo')) \"'foo'\" >>> to_str('foo') 'foo' >>> to_str(b'foo') 'foo' \u8f85\u52a9\u51fd\u6570to_bytes\u63a5\u53d7bytes\u6216str\u5b9e\u4f8b\uff0c\u5e76\u8fd4\u56debytes\uff1a >>> def to_bytes(bytes_or_str): ... if isinstance(bytes_or_str, str): ... value = bytes_or_str.encode('utf-8') ... else: ... value = bytes_or_str ... return value ... >>> repr(to_bytes(b'foo')) \"b'foo'\" >>> repr(to_bytes('foo')) \"b'foo'\" >>> to_bytes(b'foo') b'foo' >>> to_bytes('foo') bytes\u4e0estr\u8fd9\u4e24\u79cd\u5b9e\u4f8b\u4e0d\u80fd\u5728\u67d0\u4e9b\u64cd\u4f5c\u7b26\uff08\u4f8b\u5982>\u3001==\u3001+\u3001%\u64cd\u4f5c\u7b26\uff09\u4e0a\u9762\u6df7\u7528\u3002 >>> b'one' + b'two' b'onetwo' >>> 'one'+'two' 'onetwo' \u4e0d\u80fd\u5c06str\u5b9e\u4f8b\u6dfb\u52a0\u5230bytes\u5b9e\u4f8b\uff1a >>> b'one' + 'two' Traceback (most recent call last): File \"\", line 1, in TypeError: can't concat str to bytes \u4e0d\u80fd\u5c06byte\u5b9e\u4f8b\u6dfb\u52a0\u5230str\u5b9e\u4f8b\uff1a > > > 'one' + b'two' Traceback (most recent call last): File \"\", line 1, in TypeError: can only concatenate str (not \"bytes\") to str str\u5b9e\u4f8b\u4e0d\u80fd\u4e0ebytes\u5b9e\u4f8b\u6bd4\u8f83\uff0c\u5373\u4fbf\u8fd9\u4e24\u4e2a\u5b9e\u4f8b\u8868\u793a\u7684\u5b57\u7b26\u5b8c\u5168\u76f8\u540c\uff0c\u5b83\u4eec\u4e5f\u4e0d\u76f8\u7b49\uff1a >>> assert 'red' >= b'red' Traceback (most recent call last): File \"\", line 1, in TypeError: '>=' not supported between instances of 'str' and 'bytes' >>> assert b'red' >= 'red' Traceback (most recent call last): File \"\", line 1, in TypeError: '>=' not supported between instances of 'bytes' and 'str' \u4e24\u79cd\u7c7b\u578b\u7684\u5b9e\u4f8b\u90fd\u53ef\u4ee5\u51fa\u73b0\u5728%\u64cd\u4f5c\u7b26\u7684\u53f3\u4fa7\uff0c\u7528\u6765\u66ff\u6362\u5de6\u4fa7\u90a3\u4e2a\u683c\u5f0f\u5b57\u7b26\u4e32\uff08format string\uff09\u91cc\u9762\u7684%s\u3002 >>> print(b'red %s' % b'blue') b'red blue' >>> print('red %s' % 'blue') red blue \u5982\u679c\u683c\u5f0f\u5b57\u7b26\u4e32\u662fbytes\u7c7b\u578b\uff0c\u90a3\u4e48\u4e0d\u80fd\u7528str\u5b9e\u4f8b\u6765\u66ff\u6362\u5176\u4e2d\u7684%s\u3002 \u5982\u679c\u683c\u5f0f\u5b57\u7b26\u4e32\u662fstr\u7c7b\u578b\uff0c\u5219\u53ef\u4ee5\u7528bytes\u5b9e\u4f8b\u6765\u66ff\u6362\u5176\u4e2d\u7684%s\u3002(\u7cfb\u7edf\u5728bytes\u5b9e\u4f8b\u4e0a\u9762\u8c03\u7528__repr__ \u65b9\u6cd5\uff08Rule75\uff09\uff0c\u7136\u540e\u7528\u8fd9\u6b21\u8c03\u7528\u6240\u5f97\u5230\u7684\u7ed3\u679c\u66ff\u6362\u683c\u5f0f\u5b57\u7b26\u4e32\u91cc\u7684%s\uff0c\u56e0\u6b64\u7a0b\u5e8f\u4f1a\u76f4\u63a5\u8f93\u51fab'blue'\uff0c\u800c\u4e0d\u662f\u8f93\u51fablue\u672c\u8eab\u3002) >>> print(b'red %s' % 'blue') Traceback (most recent call last): File \"\", line 1, in TypeError: %b requires a bytes-like object, or an object that implements __bytes__, not 'str' >>> print('red %s' % b'blue') red b'blue' \u5728\u64cd\u4f5c\u6587\u4ef6\u53e5\u67c4\u7684\u65f6\u5019\uff0c\u8fd9\u91cc\u7684\u53e5\u67c4\u6307\u7531\u5185\u7f6e\u7684open\u51fd\u6570\u8fd4\u56de\u7684\u53e5\u67c4\u3002\u8fd9\u6837\u7684\u53e5\u67c4\u9ed8\u8ba4\u9700\u8981\u4f7f\u7528Unicode\u5b57\u7b26\u4e32\u64cd\u4f5c\uff0c\u800c\u4e0d\u80fd\u91c7\u7528\u539f\u59cb\u7684bytes\u3002 \u4ece\u6587\u4ef6\u4e2d\u8bfb\u53d6\u4e8c\u8fdb\u5236\u6570\u636e\uff08\u6216\u8005\u628a\u4e8c\u8fdb\u5236\u6570\u636e\u5199\u5165\u6587\u4ef6\uff09\u65f6\uff0c\u5e94\u8be5\u7528'rb'\uff08'wb'\uff09\u8fd9\u6837\u7684\u4e8c\u8fdb\u5236\u6a21\u5f0f\u6253\u5f00\u6587\u4ef6\u3002 >>> with open('./temp/data.bin', 'w') as f: ... f.write(b'\\xf1\\xf2\\xf3\\xf4\\xf5') ... Traceback (most recent call last): File \"\", line 2, in TypeError: write() argument must be str, not bytes >>> >>> with open('./temp/data.bin', 'wb') as f: ... f.write(b'\\xf1\\xf2\\xf3\\xf4\\xf5') ... 5 >>> >>> with open('./temp/data.bin', 'r') as f: ... data = f.read() ... Traceback (most recent call last): File \"\", line 2, in File \"/usr/local/lib/python3.9/codecs.py\", line 322, in decode (result, consumed) = self._buffer_decode(data, self.errors, final) UnicodeDecodeError: 'utf-8' codec can't decode byte 0xf1 in position 0: invalid continuation byte >>> >>> >>> with open('./temp/data.bin', 'rb') as f: ... data = f.read() ... >>> assert data == b'\\xf1\\xf2\\xf3\\xf4\\xf5' >>> \u5982\u679c\u8981\u4ece\u6587\u4ef6\u4e2d\u8bfb\u53d6\uff08\u6216\u8005\u8981\u5199\u5165\u6587\u4ef6\u4e4b\u4e2d\uff09\u7684\u662fUnicode\u6570\u636e\uff0c\u90a3\u4e48\u5fc5\u987b\u6ce8\u610f\u7cfb\u7edf\u9ed8\u8ba4\u7684\u6587\u672c\u7f16\u7801\u65b9\u6848\u3002\u82e5\u65e0\u6cd5\u80af\u5b9a\uff0c\u53ef\u901a\u8fc7encoding\u53c2\u6570\u660e\u786e\u6307\u5b9a\u3002 >>> with open('./temp/data.bin', 'r', encoding='cp1252') as f: ... data = f.read() ... >>> assert data == b'\\xf1\\xf2\\xf3\\xf4\\xf5' Traceback (most recent call last): File \"\", line 1, in AssertionError \u67e5\u770b\u5f53\u524d\u64cd\u4f5c\u7cfb\u7edf\u9ed8\u8ba4\u7684\u7f16\u7801\u6807\u51c6 >>> import locale >>> locale.getpreferredencoding() 'UTF-8' >>>","title":"UNICODE\u7f16\u7801\u7b80\u4ecb"},{"location":"python/Pythonic90Rules/Rule04/","text":"\u7b2c4\u6761\u3000\u7528\u652f\u6301\u63d2\u503c\u7684f-string\u53d6\u4ee3C\u98ce\u683c\u7684\u683c\u5f0f\u5b57\u7b26\u4e32\u4e0estr.format\u65b9\u6cd5 \u00b6 \u683c\u5f0f\u5316\uff08formatting\uff09\u662f\u6307\u628a\u6570\u636e\u586b\u5199\u5230\u9884\u5148\u5b9a\u4e49\u7684\u6587\u672c\u6a21\u677f\u91cc\u9762\uff0c\u5f62\u6210\u4e00\u6761\u7528\u6237\u53ef\u8bfb\u7684\u6d88\u606f\uff0c\u5e76\u628a\u8fd9\u6761\u6d88\u606f\u4fdd\u5b58\u6210\u5b57\u7b26\u4e32\u7684\u8fc7\u7a0b\u3002 \u7528Python\u5bf9\u5b57\u7b26\u4e32\u505a\u683c\u5f0f\u5316\u5904\u7406\u6709\u56db\u79cd\u529e\u6cd5\u53ef\u4ee5\u8003\u8651\uff0c\u8fd9\u4e9b\u529e\u6cd5\u90fd\u5185\u7f6e\u5728\u8bed\u8a00\u548c\u6807\u51c6\u5e93\u91cc\u9762\u3002 \u4f46\u5176\u4e2d\u4e09\u79cd\u529e\u6cd5\u6709\u4e25\u91cd\u7684\u7f3a\u9677\uff0c\u73b0\u5728\u5148\u89e3\u91ca\u4e3a\u4ec0\u4e48\u4e0d\u8981\u4f7f\u7528\u8fd9\u4e09\u79cd\u529e\u6cd5\uff0c\u6700\u540e\u518d\u7ed9\u51fa\u5269\u4e0b\u7684\u90a3\u4e00\u79cd\u3002 Python\u91cc\u9762\u6700\u5e38\u7528\u7684\u5b57\u7b26\u4e32\u683c\u5f0f\u5316\u65b9\u5f0f\u662f\u91c7\u7528%\u683c\u5f0f\u5316\u64cd\u4f5c\u7b26(C\u98ce\u683c\u7684\u683c\u5f0f\u5b57\u7b26\u4e32)\u3002 \u8fd9\u4e2a\u64cd\u4f5c\u7b26\u5de6\u8fb9\u7684\u6587\u672c\u6a21\u677f\u53eb\u4f5c\u683c\u5f0f\u5b57\u7b26\u4e32\uff08format string\uff09\uff0c\u6211\u4eec\u53ef\u4ee5\u5728\u64cd\u4f5c\u7b26\u53f3\u8fb9\u5199\u4e0a\u67d0\u4e2a\u503c\u6216\u8005\u7531\u591a\u4e2a\u503c\u6240\u6784\u6210\u7684\u5143\u7ec4\uff08tuple\uff09\uff0c\u7528\u6765\u66ff\u6362\u683c\u5f0f\u5b57\u7b26\u4e32\u91cc\u7684\u76f8\u5173\u7b26\u53f7\u3002 python\u5b57\u7b26\u4e32\u683c\u5f0f\u5316\u7b26\u53f7\uff1a %c\uff1a\u5b57\u7b26\u53ca\u5176ASCII\u7801 %s\uff1a\u5b57\u7b26\u4e32 %d\uff1a\u6574\u6570 %u\uff1a\u65e0\u7b26\u53f7\u6574\u578b %o\uff1a\u65e0\u7b26\u53f7\u516b\u8fdb\u5236\u6570 %x\uff1a\u65e0\u7b26\u53f7\u5341\u516d\u8fdb\u5236\u6570 %X\uff1a\u65e0\u7b26\u53f7\u5341\u516d\u8fdb\u5236\u6570\uff08\u5927\u5199\uff09 %f\uff1a\u6d6e\u70b9\u6570\u5b57\uff0c\u53ef\u6307\u5b9a\u5c0f\u6570\u70b9\u540e\u7684\u7cbe\u5ea6 %e\uff1a\u7528\u79d1\u5b66\u8ba1\u6570\u6cd5\u683c\u5f0f\u5316\u6d6e\u70b9\u6570 %E\uff1a\u4f5c\u7528\u540c%e\uff0c\u7528\u79d1\u5b66\u8ba1\u6570\u6cd5\u683c\u5f0f\u5316\u6d6e\u70b9\u6570 %g\uff1a%f\u548c%e\u7684\u7b80\u5199 %G\uff1a%f \u548c %E \u7684\u7b80\u5199 %p\uff1a\u7528\u5341\u516d\u8fdb\u5236\u6570\u683c\u5f0f\u5316\u53d8\u91cf\u7684\u5730\u5740 a = 128 b = 3.1415926 print('Binary is %d, Hex is %X, Oct is %o, Float is %e' % (a, a, a, b)) >>> Binary is 128, Hex is 80, Oct is 200, Float is 3.141593e+00 C\u98ce\u683c\u7684\u683c\u5f0f\u5b57\u7b26\u4e32\uff0c\u5728Python\u91cc\u6709\u56db\u4e2a\u7f3a\u70b9\u3002 \u7b2c\u4e00\u4e2a\u7f3a\u70b9\u662f\uff0c\u5982\u679c%\u53f3\u4fa7\u90a3\u4e2a\u5143\u7ec4\u91cc\u9762\u7684\u503c\u5728\u7c7b\u578b\u6216\u987a\u5e8f\u4e0a\u6709\u53d8\u5316\uff0c\u90a3\u4e48\u7a0b\u5e8f\u53ef\u80fd\u4f1a\u56e0\u4e3a\u8f6c\u6362\u7c7b\u578b\u65f6\u53d1\u751f\u4e0d\u517c\u5bb9\u95ee\u9898\u800c\u51fa\u73b0\u9519\u8bef\u3002 >>> key = 'my_var' >>> value = 1.234 >>> formatted = '%-10s = %.2f' % (key, value) # %-10s\u4ee3\u8868=\u5de6\u8fb9\u5b57\u4e32\u603b\u957f\u5ea610,\u4e0d\u8db3\u90e8\u5206\u5728\u5c3e\u90e8\u6dfb\u52a0\u7a7a\u683c >>> formatted 'my_var = 1.23' >>> \u5982\u679c\u628akey\u8ddfvalue\u4e92\u6362\u4f4d\u7f6e\uff0c\u6216\u8005\u5de6\u4fa7\u90a3\u4e2a\u683c\u5f0f\u5b57\u7b26\u4e32\u91cc\u9762\u7684\u4e24\u4e2a\u8bf4\u660e\u7b26\u5bf9\u8c03\u4e86\u987a\u5e8f\uff0c\u90a3\u4e48\u7a0b\u5e8f\u5c31\u4f1a\u5728\u8fd0\u884c\u65f6\u51fa\u73b0\u5f02\u5e38\u3002 >>> key = 'my_var' >>> value = 1.234 >>> formatted = '%-10s = %.2f' % (value, key) Traceback (most recent call last): File \"\", line 1, in TypeError: must be real number, not str >>> key = 'my_var' >>> value = 1.234 >>> formatted = '%.2f = %-10s' % (key, value) Traceback (most recent call last): File \"\", line 1, in TypeError: must be real number, not str \u7b2c\u4e8c\u4e2a\u7f3a\u70b9\u662f\uff0c\u5728\u586b\u5145\u6a21\u677f\u4e4b\u524d\uff0c\u7ecf\u5e38\u8981\u5148\u5bf9\u51c6\u5907\u586b\u5199\u8fdb\u53bb\u7684\u8fd9\u4e2a\u503c\u7a0d\u5fae\u505a\u4e00\u4e9b\u5904\u7406\uff0c\u4f46\u8fd9\u6837\u4e00\u6765\uff0c\u6574\u4e2a\u8868\u8fbe\u5f0f\u53ef\u80fd\u5c31\u4f1a\u5199\u5f97\u5f88\u957f\uff0c\u5f71\u54cd\u7a0b\u5e8f\u7684\u53ef\u8bfb\u6027\u3002 >>> pantry = [ ... ('avocados', 1.25), ... ('bananas', 2.5), ... ('cherries', 15) ... ] >>> for i, (item, count) in enumerate(pantry): ... print( ... '#%d: %-10s = %.2f' % ( ... i + 1, ... item.title(), ... round(count) ... ) ... ) ... #1: Avocados = 1.00 #2: Bananas = 2.00 #3: Cherries = 15.00 \u7b2c\u4e09\u4e2a\u7f3a\u70b9\u662f\uff0c\u5982\u679c\u60f3\u7528\u540c\u4e00\u4e2a\u503c\u6765\u586b\u5145\u683c\u5f0f\u5b57\u7b26\u4e32\u91cc\u7684\u591a\u4e2a\u4f4d\u7f6e\uff0c\u90a3\u4e48\u5fc5\u987b\u5728%\u64cd\u4f5c\u7b26\u53f3\u4fa7\u7684\u5143\u7ec4\u4e2d\u76f8\u5e94\u5730\u591a\u6b21\u91cd\u590d\u8be5\u503c\u3002 >>> template = '%s loves food. See %s cook.' >>> name = 'Max' >>> formatted = template % (name, name) >>> formatted 'Max loves food. See Max cook.' \u4e3a\u4e86\u89e3\u51b3\u4e0a\u9762\u63d0\u5230\u7684\u4e00\u4e9b\u95ee\u9898\uff0cPython\u7684%\u64cd\u4f5c\u7b26\u5141\u8bb8\u6211\u4eec\u7528dict\u53d6\u4ee3tuple\uff0c\u89e3\u51b3\u4e86%\u64cd\u4f5c\u7b26\u4e24\u4fa7\u7684\u987a\u5e8f\u4e0d\u5339\u914d\u95ee\u9898\u3002 >>> key = 'my_var' >>> value = 1.234 >>> old_way = '%-10s = %.2f' % (key, value) >>> new_way = '%(key)-10s = %(value).2f' % {'key': key, 'value': value} # \u5bf9\u5e94 >>> reordered = '%(key)-10s = %(value).2f' % {'value': value, 'key': key} # \u4e92\u6362 >>> assert old_way == new_way == reordered >>> old_way 'my_var = 1.23' >>> new_way 'my_var = 1.23' >>> reordered 'my_var = 1.23' \u7528dict\u53d6\u4ee3tuple\uff0c\u4e5f\u89e3\u51b3\u7528\u540c\u4e00\u4e2a\u503c\u66ff\u6362\u591a\u4e2a\u683c\u5f0f\u8bf4\u660e\u7b26\u7684\u95ee\u9898\uff0c\u6211\u4eec\u5c31\u4e0d\u7528\u5728%\u64cd\u4f5c\u7b26\u53f3\u4fa7\u91cd\u590d\u8fd9\u4e2a\u503c\u4e86\u3002 >>> name = 'Max' >>> template = '%s loves food. See %s cook.' >>> before = template % (name, name) >>> template = '%(name)s loves food. See %(name)s cook.' >>> after = template % {'name': name} >>> assert before == after >>> before 'Max loves food. See Max cook.' >>> after 'Max loves food. See Max cook.' \u4f46\u662f\uff0c\u8fd9\u79cd\u5199\u6cd5\u4f1a\u8ba9\u7b2c\u4e8c\u4e2a\u7f3a\u70b9\u53d8\u5f97\u66f4\u52a0\u4e25\u91cd\uff0c\u683c\u5f0f\u5316\u8868\u8fbe\u5f0f\u53d8\u5f97\u66f4\u52a0\u5197\u957f\uff0c\u770b\u8d77\u6765\u4e5f\u66f4\u52a0\u6df7\u4e71\u3002\u5982\u4e0b\u4f8b\uff1a >>> pantry = [ ... ('avocados', 1.25), ... ('bananas', 2.5), ... ('cherries', 15) ... ] >>> for i, (item, count) in enumerate(pantry): ... before = '#%d: %-10s = %.2f' % ( ... i + 1, ... item.title(), ... round(count) ... ) ... after = '#%(loop)d: %(item)-10s = %(count).2f' % { ... 'loop': i + 1, ... 'item': item.title(), ... 'count': round(count) ... } ... assert before == after ... print(before) ... print(after) ... #1: Avocados = 1.00 #1: Avocados = 1.00 #2: Bananas = 2.00 #2: Bananas = 2.00 #3: Cherries = 15.00 #3: Cherries = 15.00 \u6240\u4ee5\uff0c\u7b2c\u56db\u4e2a\u7f3a\u70b9\u662f\uff0c\u628adict\u5199\u5230\u683c\u5f0f\u5316\u8868\u8fbe\u5f0f\u91cc\u9762\u4f1a\u8ba9\u4ee3\u7801\u53d8\u591a\uff0c\u6bcf\u4e2a\u952e\u90fd\u81f3\u5c11\u8981\u5199\u4e24\u6b21\u3002\u4e3a\u4e86\u67e5\u770b\u683c\u5f0f\u5b57\u7b26\u4e32\u4e2d\u7684\u8bf4\u660e\u7b26\u7a76\u7adf\u5bf9\u5e94\u4e8e\u5b57\u5178\u91cc\u7684\u54ea\u4e2a\u952e\uff0c\u5fc5\u987b\u5728\u8fd9\u4e24\u6bb5\u4ee3\u7801\u4e4b\u95f4\u6765\u56de\u8df3\u8dc3\u3002\u5982\u679c\u8981\u5bf9\u952e\u540d\u7a0d\u505a\u4fee\u6539\uff0c\u90a3\u4e48\u5fc5\u987b\u540c\u6b65\u4fee\u6539\u683c\u5f0f\u5b57\u7b26\u4e32\u91cc\u7684\u8bf4\u660e\u7b26\uff0c\u8fd9\u66f4\u8ba9\u4ee3\u7801\u53d8\u5f97\u76f8\u5f53\u70e6\u7410\uff0c\u53ef\u8bfb\u6027\u66f4\u5dee\u3002 \u5185\u7f6e\u7684format\u51fd\u6570\u4e0estr\u7c7b\u7684format\u65b9\u6cd5 \u00b6 Python 3\u6dfb\u52a0\u4e86\u9ad8\u7ea7\u5b57\u7b26\u4e32\u683c\u5f0f\u5316\uff08advanced stringformatting\uff09\u673a\u5236\uff0c\u5b83\u7684\u8868\u8fbe\u80fd\u529b\u6bd4\u8001\u5f0fC\u98ce\u683c\u7684\u683c\u5f0f\u5b57\u7b26\u4e32\u8981\u5f3a\uff0c\u4e14\u4e0d\u518d\u4f7f\u7528%\u64cd\u4f5c\u7b26\u3002 \u4e0b\u9762\u8fd9\u6bb5\u4ee3\u7801\uff0c\u6f14\u793a\u4e86\u8fd9\u79cd\u65b0\u7684\u683c\u5f0f\u5316\u65b9\u5f0f\u3002\u5728\u4f20\u7ed9format\u51fd\u6570\u7684\u683c\u5f0f\u91cc\u9762\uff0c\u9017\u53f7\u8868\u793a\u663e\u793a\u5343\u4f4d\u5206\u9694\u7b26\uff0c^\u8868\u793a\u5c45\u4e2d\u5bf9\u9f50\u3002 >>> a = 1234.5678 >>> formatted = format(a, ',.2f') >>> formatted '1,234.57' >>> b = 'my string' >>> formatted = format(b, '^20s') >>> formatted ' my string ' \u5982\u679cstr\u7c7b\u578b\u7684\u5b57\u7b26\u4e32\u91cc\u9762\u6709\u8bb8\u591a\u503c\u90fd\u9700\u8981\u8c03\u6574\u683c\u5f0f\uff0c\u5219\u53ef\u4ee5\u628a\u683c\u5f0f\u6709\u5f85\u8c03\u6574\u7684\u90a3\u4e9b\u4f4d\u7f6e\u5728\u5b57\u7b26\u4e32\u91cc\u9762\u5148\u7528{}\u4ee3\u66ff\uff0c\u7136\u540e\u6309\u4ece\u5de6\u5230\u53f3\u7684\u987a\u5e8f\uff0c\u628a\u9700\u8981\u586b\u5199\u5230\u90a3\u4e9b\u4f4d\u7f6e\u7684\u503c\u4f20\u7ed9format\u65b9\u6cd5\uff0c\u4f7f\u8fd9\u4e9b\u503c\u4f9d\u6b21\u51fa\u73b0\u5728\u5b57\u7b26\u4e32\u4e2d\u7684\u76f8\u5e94\u4f4d\u7f6e\u3002 >>> key = 'my_var' >>> value = 1.234 >>> formatted = '{} = {}'.format(key, value) >>> formatted 'my_var = 1.234' >>> formatted = '{} = {}'.format(value, key) >>> formatted '1.234 = my_var' \u901a\u8fc7\u5728{}\u91cc\u5199\u4e2a\u5192\u53f7\uff0c\u7136\u540e\u628a\u683c\u5f0f\u8bf4\u660e\u7b26\u5199\u5728\u5192\u53f7\u7684\u53f3\u8fb9\uff0c\u6765\u6dfb\u52a0\u683c\u5f0f\u3002\uff08\u6dfb\u52a0\u683c\u5f0f\u540e\uff0c\u4e92\u6362\u4f1a\u62a5\u9519\uff09 >>> formatted = '{:<10} = {:.2f}'.format(key, value) >>> formatted 'my_var = 1.23' >>> formatted = '{:<10} = {:.2f}'.format(value, key) Traceback (most recent call last): File \"\", line 1, in ValueError: Unknown format code 'f' for object of type 'str' \u4e5f\u53ef\u4ee5\u7ed9str\u7684{}\u91cc\u9762\u5199\u4e0a\u6570\u5b57\uff0c\u7528\u6765\u6307\u4ee3format\u65b9\u6cd5\u5728\u8fd9\u4e2a\u4f4d\u7f6e\u6240\u63a5\u6536\u5230\u7684\u53c2\u6570\u503c\u4f4d\u7f6e\u7d22\u5f15\u3002 \u4ee5\u540e\u5373\u4f7f\u8fd9\u4e9b{}\u5728\u683c\u5f0f\u5b57\u7b26\u4e32\u4e2d\u7684\u6b21\u5e8f\u6709\u6240\u53d8\u52a8\uff0c\u4e5f\u4e0d\u7528\u8c03\u6362\u4f20\u7ed9format\u65b9\u6cd5\u7684\u90a3\u4e9b\u53c2\u6570\u3002\u4e8e\u662f\uff0c\u8fd9\u5c31\u907f\u514d\u4e86\u524d\u9762\u8bb2\u7684\u7b2c\u4e00\u4e2a\u7f3a\u70b9\u6240\u63d0\u5230\u7684\u90a3\u4e2a\u987a\u5e8f\u95ee\u9898\u3002 >>> key = 'my_var' >>> value = 1.234 >>> formatted = '{} = {}'.format(key, value) >>> formatted 'my_var = 1.234' >>> formatted = '{1} = {0}'.format(key, value) >>> formatted '1.234 = my_var' >>> formatted = '{2} = {1}'.format(key, value) Traceback (most recent call last): File \"\", line 1, in IndexError: Replacement index 2 out of range for positional args tuple \u540c\u4e00\u4e2a\u4f4d\u7f6e\u7d22\u5f15\u53ef\u4ee5\u51fa\u73b0\u5728str\u7684\u591a\u4e2a{}\u91cc\u9762\uff0c\u8fd9\u5c31\u4e0d\u9700\u8981\u628a\u8fd9\u4e2a\u503c\u91cd\u590d\u5730\u4f20\u7ed9format\u65b9\u6cd5\uff0c\u4e8e\u662f\u5c31\u89e3\u51b3\u4e86\u524d\u9762\u63d0\u5230\u7684\u7b2c\u4e09\u4e2a\u7f3a\u70b9\u3002 >>> name = 'Max' >>> formatted = '%s loves food. See %s cook.' % (name, name) >>> formatted 'Max loves food. See Max cook.' >>> formatted = '%(name)s loves food. See %(name)s cook.' % {'name': name} >>> formatted 'Max loves food. See Max cook.' >>> formatted = '{0} loves food. See {0} cook.'.format(name) >>> formatted 'Max loves food. See Max cook.' \u4e0a\u8ff0\u529f\u80fd\u5206\u6790\uff1a \u7cfb\u7edf\u5148\u628astr.format\u65b9\u6cd5\u63a5\u6536\u5230\u7684\u6bcf\u4e2a\u503c\u4f20\u7ed9\u5185\u7f6e\u7684format\u51fd\u6570\uff0c\u5e76\u627e\u5230\u8fd9\u4e2a\u503c\u5728\u5b57\u7b26\u4e32\u91cc\u5bf9\u5e94\u7684{}\uff0c\u540c\u65f6\u5c06{}\u91cc\u9762\u5199\u7684\u683c\u5f0f\u4e5f\u4f20\u7ed9format\u51fd\u6570\uff0c\u4f8b\u5982\u7cfb\u7edf\u5728\u5904\u7406value\u7684\u65f6\u5019\uff0c\u4f20\u7684\u5c31\u662fformat(value,'.2f')\u3002 \u7136\u540e\uff0c\u7cfb\u7edf\u4f1a\u628aformat\u51fd\u6570\u6240\u8fd4\u56de\u7684\u7ed3\u679c\u5199\u5728\u6574\u4e2a\u683c\u5f0f\u5316\u5b57\u7b26\u4e32{}\u6240\u5728\u7684\u4f4d\u7f6e\u3002 \u53e6\u5916\uff0c\u6bcf\u4e2a\u7c7b\u90fd\u53ef\u4ee5\u901a\u8fc7__format__\u8fd9\u4e2a\u7279\u6b8a\u7684\u65b9\u6cd5\u5b9a\u5236\u76f8\u5e94\u7684\u903b\u8f91\uff0c\u8fd9\u6837\u7684\u8bdd\uff0cformat\u51fd\u6570\u5728\u628a\u8be5\u7c7b\u5b9e\u4f8b\u8f6c\u6362\u6210\u5b57\u7b26\u4e32\u65f6\uff0c\u5c31\u4f1a\u6309\u7167\u8fd9\u79cd\u903b\u8f91\u6765\u8f6c\u6362\u3002 \u8f6c\u4e49\u5904\u7406\uff1a >>> formatted = '%.2f%%' % 12.5 >>> formatted '12.50%' >>> formatted = '{} replace {{}}'.format(1.23) >>> formatted '1.23 replace {}' \u7136\u800c\uff0cstr.format\u65b9\u6cd5\u5e76\u6ca1\u6709\u89e3\u51b3\u4e0a\u9762\u8bb2\u7684\u7b2c\u4e8c\u4e2a\u7f3a\u70b9\u3002\u5982\u679c\u5728\u5bf9\u503c\u505a\u586b\u5145\u4e4b\u524d\u8981\u5148\u5bf9\u8fd9\u4e2a\u503c\u505a\u51fa\u8c03\u6574\uff0c\u90a3\u4e48\u7528\u8fd9\u79cd\u65b9\u6cd5\u5199\u51fa\u6765\u7684\u4ee3\u7801\u8fd8\u662f\u8ddf\u539f\u6765\u4e00\u6837\u4e71\uff0c\u9605\u8bfb\u6027\u5dee\u3002\u5bf9\u6bd4\u4e00\u4e0b\uff1a >>> pantry = [ ... ('avocados', 1.25), ... ('bananas', 2.5), ... ('cherries', 15) ... ] >>> for i, (item, count) in enumerate(pantry): ... before = '#%d: %-10s = %.2f' % ( ... i + 1, ... item.title(), ... round(count) ... ) ... after = '#%(loop)d: %(item)-10s = %(count).2f' % { ... 'loop': i + 1, ... 'item': item.title(), ... 'count': round(count) ... } ... new_style = '#{}: {:<10s} = {:.2f}'.format( ... i + 1, ... item.title(), ... round(count) ... ) ... assert before == after == new_style ... print(before) ... print(after) ... print(new_style) ... #1: Avocados = 1.00 #1: Avocados = 1.00 #1: Avocados = 1.00 #2: Bananas = 2.00 #2: Bananas = 2.00 #2: Bananas = 2.00 #3: Cherries = 15.00 #3: Cherries = 15.00 #3: Cherries = 15.00 \u63d2\u503c\u683c\u5f0f\u5b57\u7b26\u4e32f-string \u00b6 Python 3.6\u6dfb\u52a0\u4e86\u4e00\u79cd\u65b0\u7684\u7279\u6027\uff0c\u53eb\u4f5c\u63d2\u503c\u683c\u5f0f\u5b57\u7b26\u4e32\uff08interpolated format string\uff0c\u7b80\u79f0f-string\uff09\uff0c\u53ef\u4ee5\u89e3\u51b3\u4e0a\u9762\u63d0\u5230\u7684\u6240\u6709\u95ee\u9898\u3002 \u4e0b\u9762\u6309\u7167\u4ece\u77ed\u5230\u957f\u7684\u987a\u5e8f\u628a\u8fd9\u51e0\u79cd\u5199\u6cd5\u6240\u5360\u7684\u7bc7\u5e45\u5bf9\u6bd4\u4e00\u4e0b\uff0c\u8fd9\u6837\u5f88\u5bb9\u6613\u770b\u51fa\u7b26\u53f7\u53f3\u8fb9\u7684\u4ee3\u7801\u5230\u5e95\u6709\u591a\u5c11\u3002C\u98ce\u683c\u7684\u5199\u6cd5\u4e0e\u91c7\u7528str.format\u65b9\u6cd5\u7684\u5199\u6cd5\u53ef\u80fd\u4f1a\u8ba9\u8868\u8fbe\u5f0f\u53d8\u5f97\u5f88\u957f\uff0c\u4f46\u5982\u679c\u6539\u7528f-string\uff0c\u6216\u8bb8\u4e00\u884c\u5c31\u80fd\u5199\u5b8c\u3002 >>> key = 'my_var' >>> value = 1.234 >>> f_string = f'{key:<10} = {value:.2f}' >>> c_tuple = '%-10s = %.2f' % (key, value) >>> str_args = '{:<10} = {:.2f}'.format(key, value) >>> str_kw = '{key:<10} = {value:.2f}'.format(key=key, value=value) >>> c_dict = '%(key)-10s = %(value).2f' % {'key': key, 'value': value} >>> assert c_tuple == c_dict == f_string >>> assert str_args == str_kw == f_string >>> f_string 'my_var = 1.23' >>> c_tuple 'my_var = 1.23' >>> str_args 'my_var = 1.23' >>> str_kw 'my_var = 1.23' >>> c_dict 'my_var = 1.23' \u5bf9\u6bd4\u4e0b\u9762\uff0c\u628astr.format\u65b9\u6cd5\u7684\u5199\u6cd5\u6539\u7528f-string\uff0c\u4e00\u884c\u5c31\u80fd\u5199\u5b8c\u3002 >>> pantry = [ ... ('avocados', 1.25), ... ('bananas', 2.5), ... ('cherries', 15) ... ] >>> for i, (item, count) in enumerate(pantry): ... before = '#%d: %-10s = %.2f' % ( ... i + 1, ... item.title(), ... round(count) ... ) ... after = '#%(loop)d: %(item)-10s = %(count).2f' % { ... 'loop': i + 1, ... 'item': item.title(), ... 'count': round(count) ... } ... new_style = '#{}: {:<10s} = {:.2f}'.format( ... i + 1, ... item.title(), ... round(count) ... ) ... f_string = f'#{i+1}: {item.title():<10s} = {round(count):.2f}' ... assert before == after == new_style == f_string ... print(before) ... print(after) ... print(new_style) ... print(f_string) ... #1: Avocados = 1.00 #1: Avocados = 1.00 #1: Avocados = 1.00 #1: Avocados = 1.00 #2: Bananas = 2.00 #2: Bananas = 2.00 #2: Bananas = 2.00 #2: Bananas = 2.00 #3: Cherries = 15.00 #3: Cherries = 15.00 #3: Cherries = 15.00 #3: Cherries = 15.00 \u8981\u70b9\u603b\u7ed3\uff1a \u91c7\u7528%\u64cd\u4f5c\u7b26\u628a\u503c\u586b\u5145\u5230C\u98ce\u683c\u7684\u683c\u5f0f\u5b57\u7b26\u4e32\u65f6\u4f1a\u9047\u5230\u8bb8\u591a\u95ee\u9898\uff0c\u800c\u4e14\u8fd9\u79cd\u5199\u6cd5\u6bd4\u8f83\u70e6\u7410\u3002 str.format\u65b9\u6cd5\u4e13\u95e8\u7528\u4e00\u5957\u8ff7\u4f60\u8bed\u8a00\u6765\u5b9a\u4e49\u5b83\u7684\u683c\u5f0f\u8bf4\u660e\u7b26\uff0c\u8fd9\u5957\u8bed\u8a00\u7ed9\u6211\u4eec\u63d0\u4f9b\u4e86\u4e00\u4e9b\u6709\u7528\u7684\u6982\u5ff5\uff0c\u4f46\u662f\u5728\u5176\u4ed6\u65b9\u9762\uff0c\u8fd9\u4e2a\u65b9\u6cd5\u8fd8\u662f\u5b58\u5728\u4e0eC\u98ce\u683c\u7684\u683c\u5f0f\u5b57\u7b26\u4e32\u4e00\u6837\u7684\u591a\u79cd\u7f3a\u70b9\uff0c\u6240\u4ee5\u6211\u4eec\u4e5f\u5e94\u8be5\u907f\u514d\u4f7f\u7528\u5b83\u3002 f-string\u91c7\u7528\u65b0\u7684\u5199\u6cd5\uff0c\u5c06\u503c\u586b\u5145\u5230\u5b57\u7b26\u4e32\u4e4b\u4e2d\uff0c\u89e3\u51b3\u4e86C\u98ce\u683c\u7684\u683c\u5f0f\u5b57\u7b26\u4e32\u6240\u5e26\u6765\u7684\u6700\u5927\u95ee\u9898\u3002 f-string\u662f\u4e2a\u7b80\u6d01\u800c\u5f3a\u5927\u7684\u673a\u5236\uff0c\u53ef\u4ee5\u76f4\u63a5\u5728\u683c\u5f0f\u8bf4\u660e\u7b26\u91cc\u5d4c\u5165\u4efb\u610fPython\u8868\u8fbe\u5f0f\u3002","title":"\u7b2c04\u6761 \u7528\u652f\u6301\u63d2\u503c\u7684f-string\u53d6\u4ee3C\u98ce\u683c\u7684\u683c\u5f0f\u5b57\u7b26\u4e32\u4e0estr.format\u65b9\u6cd5"},{"location":"python/Pythonic90Rules/Rule04/#4-f-stringcstrformat","text":"\u683c\u5f0f\u5316\uff08formatting\uff09\u662f\u6307\u628a\u6570\u636e\u586b\u5199\u5230\u9884\u5148\u5b9a\u4e49\u7684\u6587\u672c\u6a21\u677f\u91cc\u9762\uff0c\u5f62\u6210\u4e00\u6761\u7528\u6237\u53ef\u8bfb\u7684\u6d88\u606f\uff0c\u5e76\u628a\u8fd9\u6761\u6d88\u606f\u4fdd\u5b58\u6210\u5b57\u7b26\u4e32\u7684\u8fc7\u7a0b\u3002 \u7528Python\u5bf9\u5b57\u7b26\u4e32\u505a\u683c\u5f0f\u5316\u5904\u7406\u6709\u56db\u79cd\u529e\u6cd5\u53ef\u4ee5\u8003\u8651\uff0c\u8fd9\u4e9b\u529e\u6cd5\u90fd\u5185\u7f6e\u5728\u8bed\u8a00\u548c\u6807\u51c6\u5e93\u91cc\u9762\u3002 \u4f46\u5176\u4e2d\u4e09\u79cd\u529e\u6cd5\u6709\u4e25\u91cd\u7684\u7f3a\u9677\uff0c\u73b0\u5728\u5148\u89e3\u91ca\u4e3a\u4ec0\u4e48\u4e0d\u8981\u4f7f\u7528\u8fd9\u4e09\u79cd\u529e\u6cd5\uff0c\u6700\u540e\u518d\u7ed9\u51fa\u5269\u4e0b\u7684\u90a3\u4e00\u79cd\u3002 Python\u91cc\u9762\u6700\u5e38\u7528\u7684\u5b57\u7b26\u4e32\u683c\u5f0f\u5316\u65b9\u5f0f\u662f\u91c7\u7528%\u683c\u5f0f\u5316\u64cd\u4f5c\u7b26(C\u98ce\u683c\u7684\u683c\u5f0f\u5b57\u7b26\u4e32)\u3002 \u8fd9\u4e2a\u64cd\u4f5c\u7b26\u5de6\u8fb9\u7684\u6587\u672c\u6a21\u677f\u53eb\u4f5c\u683c\u5f0f\u5b57\u7b26\u4e32\uff08format string\uff09\uff0c\u6211\u4eec\u53ef\u4ee5\u5728\u64cd\u4f5c\u7b26\u53f3\u8fb9\u5199\u4e0a\u67d0\u4e2a\u503c\u6216\u8005\u7531\u591a\u4e2a\u503c\u6240\u6784\u6210\u7684\u5143\u7ec4\uff08tuple\uff09\uff0c\u7528\u6765\u66ff\u6362\u683c\u5f0f\u5b57\u7b26\u4e32\u91cc\u7684\u76f8\u5173\u7b26\u53f7\u3002 python\u5b57\u7b26\u4e32\u683c\u5f0f\u5316\u7b26\u53f7\uff1a %c\uff1a\u5b57\u7b26\u53ca\u5176ASCII\u7801 %s\uff1a\u5b57\u7b26\u4e32 %d\uff1a\u6574\u6570 %u\uff1a\u65e0\u7b26\u53f7\u6574\u578b %o\uff1a\u65e0\u7b26\u53f7\u516b\u8fdb\u5236\u6570 %x\uff1a\u65e0\u7b26\u53f7\u5341\u516d\u8fdb\u5236\u6570 %X\uff1a\u65e0\u7b26\u53f7\u5341\u516d\u8fdb\u5236\u6570\uff08\u5927\u5199\uff09 %f\uff1a\u6d6e\u70b9\u6570\u5b57\uff0c\u53ef\u6307\u5b9a\u5c0f\u6570\u70b9\u540e\u7684\u7cbe\u5ea6 %e\uff1a\u7528\u79d1\u5b66\u8ba1\u6570\u6cd5\u683c\u5f0f\u5316\u6d6e\u70b9\u6570 %E\uff1a\u4f5c\u7528\u540c%e\uff0c\u7528\u79d1\u5b66\u8ba1\u6570\u6cd5\u683c\u5f0f\u5316\u6d6e\u70b9\u6570 %g\uff1a%f\u548c%e\u7684\u7b80\u5199 %G\uff1a%f \u548c %E \u7684\u7b80\u5199 %p\uff1a\u7528\u5341\u516d\u8fdb\u5236\u6570\u683c\u5f0f\u5316\u53d8\u91cf\u7684\u5730\u5740 a = 128 b = 3.1415926 print('Binary is %d, Hex is %X, Oct is %o, Float is %e' % (a, a, a, b)) >>> Binary is 128, Hex is 80, Oct is 200, Float is 3.141593e+00 C\u98ce\u683c\u7684\u683c\u5f0f\u5b57\u7b26\u4e32\uff0c\u5728Python\u91cc\u6709\u56db\u4e2a\u7f3a\u70b9\u3002 \u7b2c\u4e00\u4e2a\u7f3a\u70b9\u662f\uff0c\u5982\u679c%\u53f3\u4fa7\u90a3\u4e2a\u5143\u7ec4\u91cc\u9762\u7684\u503c\u5728\u7c7b\u578b\u6216\u987a\u5e8f\u4e0a\u6709\u53d8\u5316\uff0c\u90a3\u4e48\u7a0b\u5e8f\u53ef\u80fd\u4f1a\u56e0\u4e3a\u8f6c\u6362\u7c7b\u578b\u65f6\u53d1\u751f\u4e0d\u517c\u5bb9\u95ee\u9898\u800c\u51fa\u73b0\u9519\u8bef\u3002 >>> key = 'my_var' >>> value = 1.234 >>> formatted = '%-10s = %.2f' % (key, value) # %-10s\u4ee3\u8868=\u5de6\u8fb9\u5b57\u4e32\u603b\u957f\u5ea610,\u4e0d\u8db3\u90e8\u5206\u5728\u5c3e\u90e8\u6dfb\u52a0\u7a7a\u683c >>> formatted 'my_var = 1.23' >>> \u5982\u679c\u628akey\u8ddfvalue\u4e92\u6362\u4f4d\u7f6e\uff0c\u6216\u8005\u5de6\u4fa7\u90a3\u4e2a\u683c\u5f0f\u5b57\u7b26\u4e32\u91cc\u9762\u7684\u4e24\u4e2a\u8bf4\u660e\u7b26\u5bf9\u8c03\u4e86\u987a\u5e8f\uff0c\u90a3\u4e48\u7a0b\u5e8f\u5c31\u4f1a\u5728\u8fd0\u884c\u65f6\u51fa\u73b0\u5f02\u5e38\u3002 >>> key = 'my_var' >>> value = 1.234 >>> formatted = '%-10s = %.2f' % (value, key) Traceback (most recent call last): File \"\", line 1, in TypeError: must be real number, not str >>> key = 'my_var' >>> value = 1.234 >>> formatted = '%.2f = %-10s' % (key, value) Traceback (most recent call last): File \"\", line 1, in TypeError: must be real number, not str \u7b2c\u4e8c\u4e2a\u7f3a\u70b9\u662f\uff0c\u5728\u586b\u5145\u6a21\u677f\u4e4b\u524d\uff0c\u7ecf\u5e38\u8981\u5148\u5bf9\u51c6\u5907\u586b\u5199\u8fdb\u53bb\u7684\u8fd9\u4e2a\u503c\u7a0d\u5fae\u505a\u4e00\u4e9b\u5904\u7406\uff0c\u4f46\u8fd9\u6837\u4e00\u6765\uff0c\u6574\u4e2a\u8868\u8fbe\u5f0f\u53ef\u80fd\u5c31\u4f1a\u5199\u5f97\u5f88\u957f\uff0c\u5f71\u54cd\u7a0b\u5e8f\u7684\u53ef\u8bfb\u6027\u3002 >>> pantry = [ ... ('avocados', 1.25), ... ('bananas', 2.5), ... ('cherries', 15) ... ] >>> for i, (item, count) in enumerate(pantry): ... print( ... '#%d: %-10s = %.2f' % ( ... i + 1, ... item.title(), ... round(count) ... ) ... ) ... #1: Avocados = 1.00 #2: Bananas = 2.00 #3: Cherries = 15.00 \u7b2c\u4e09\u4e2a\u7f3a\u70b9\u662f\uff0c\u5982\u679c\u60f3\u7528\u540c\u4e00\u4e2a\u503c\u6765\u586b\u5145\u683c\u5f0f\u5b57\u7b26\u4e32\u91cc\u7684\u591a\u4e2a\u4f4d\u7f6e\uff0c\u90a3\u4e48\u5fc5\u987b\u5728%\u64cd\u4f5c\u7b26\u53f3\u4fa7\u7684\u5143\u7ec4\u4e2d\u76f8\u5e94\u5730\u591a\u6b21\u91cd\u590d\u8be5\u503c\u3002 >>> template = '%s loves food. See %s cook.' >>> name = 'Max' >>> formatted = template % (name, name) >>> formatted 'Max loves food. See Max cook.' \u4e3a\u4e86\u89e3\u51b3\u4e0a\u9762\u63d0\u5230\u7684\u4e00\u4e9b\u95ee\u9898\uff0cPython\u7684%\u64cd\u4f5c\u7b26\u5141\u8bb8\u6211\u4eec\u7528dict\u53d6\u4ee3tuple\uff0c\u89e3\u51b3\u4e86%\u64cd\u4f5c\u7b26\u4e24\u4fa7\u7684\u987a\u5e8f\u4e0d\u5339\u914d\u95ee\u9898\u3002 >>> key = 'my_var' >>> value = 1.234 >>> old_way = '%-10s = %.2f' % (key, value) >>> new_way = '%(key)-10s = %(value).2f' % {'key': key, 'value': value} # \u5bf9\u5e94 >>> reordered = '%(key)-10s = %(value).2f' % {'value': value, 'key': key} # \u4e92\u6362 >>> assert old_way == new_way == reordered >>> old_way 'my_var = 1.23' >>> new_way 'my_var = 1.23' >>> reordered 'my_var = 1.23' \u7528dict\u53d6\u4ee3tuple\uff0c\u4e5f\u89e3\u51b3\u7528\u540c\u4e00\u4e2a\u503c\u66ff\u6362\u591a\u4e2a\u683c\u5f0f\u8bf4\u660e\u7b26\u7684\u95ee\u9898\uff0c\u6211\u4eec\u5c31\u4e0d\u7528\u5728%\u64cd\u4f5c\u7b26\u53f3\u4fa7\u91cd\u590d\u8fd9\u4e2a\u503c\u4e86\u3002 >>> name = 'Max' >>> template = '%s loves food. See %s cook.' >>> before = template % (name, name) >>> template = '%(name)s loves food. See %(name)s cook.' >>> after = template % {'name': name} >>> assert before == after >>> before 'Max loves food. See Max cook.' >>> after 'Max loves food. See Max cook.' \u4f46\u662f\uff0c\u8fd9\u79cd\u5199\u6cd5\u4f1a\u8ba9\u7b2c\u4e8c\u4e2a\u7f3a\u70b9\u53d8\u5f97\u66f4\u52a0\u4e25\u91cd\uff0c\u683c\u5f0f\u5316\u8868\u8fbe\u5f0f\u53d8\u5f97\u66f4\u52a0\u5197\u957f\uff0c\u770b\u8d77\u6765\u4e5f\u66f4\u52a0\u6df7\u4e71\u3002\u5982\u4e0b\u4f8b\uff1a >>> pantry = [ ... ('avocados', 1.25), ... ('bananas', 2.5), ... ('cherries', 15) ... ] >>> for i, (item, count) in enumerate(pantry): ... before = '#%d: %-10s = %.2f' % ( ... i + 1, ... item.title(), ... round(count) ... ) ... after = '#%(loop)d: %(item)-10s = %(count).2f' % { ... 'loop': i + 1, ... 'item': item.title(), ... 'count': round(count) ... } ... assert before == after ... print(before) ... print(after) ... #1: Avocados = 1.00 #1: Avocados = 1.00 #2: Bananas = 2.00 #2: Bananas = 2.00 #3: Cherries = 15.00 #3: Cherries = 15.00 \u6240\u4ee5\uff0c\u7b2c\u56db\u4e2a\u7f3a\u70b9\u662f\uff0c\u628adict\u5199\u5230\u683c\u5f0f\u5316\u8868\u8fbe\u5f0f\u91cc\u9762\u4f1a\u8ba9\u4ee3\u7801\u53d8\u591a\uff0c\u6bcf\u4e2a\u952e\u90fd\u81f3\u5c11\u8981\u5199\u4e24\u6b21\u3002\u4e3a\u4e86\u67e5\u770b\u683c\u5f0f\u5b57\u7b26\u4e32\u4e2d\u7684\u8bf4\u660e\u7b26\u7a76\u7adf\u5bf9\u5e94\u4e8e\u5b57\u5178\u91cc\u7684\u54ea\u4e2a\u952e\uff0c\u5fc5\u987b\u5728\u8fd9\u4e24\u6bb5\u4ee3\u7801\u4e4b\u95f4\u6765\u56de\u8df3\u8dc3\u3002\u5982\u679c\u8981\u5bf9\u952e\u540d\u7a0d\u505a\u4fee\u6539\uff0c\u90a3\u4e48\u5fc5\u987b\u540c\u6b65\u4fee\u6539\u683c\u5f0f\u5b57\u7b26\u4e32\u91cc\u7684\u8bf4\u660e\u7b26\uff0c\u8fd9\u66f4\u8ba9\u4ee3\u7801\u53d8\u5f97\u76f8\u5f53\u70e6\u7410\uff0c\u53ef\u8bfb\u6027\u66f4\u5dee\u3002","title":"\u7b2c4\u6761\u3000\u7528\u652f\u6301\u63d2\u503c\u7684f-string\u53d6\u4ee3C\u98ce\u683c\u7684\u683c\u5f0f\u5b57\u7b26\u4e32\u4e0estr.format\u65b9\u6cd5"},{"location":"python/Pythonic90Rules/Rule04/#formatstrformat","text":"Python 3\u6dfb\u52a0\u4e86\u9ad8\u7ea7\u5b57\u7b26\u4e32\u683c\u5f0f\u5316\uff08advanced stringformatting\uff09\u673a\u5236\uff0c\u5b83\u7684\u8868\u8fbe\u80fd\u529b\u6bd4\u8001\u5f0fC\u98ce\u683c\u7684\u683c\u5f0f\u5b57\u7b26\u4e32\u8981\u5f3a\uff0c\u4e14\u4e0d\u518d\u4f7f\u7528%\u64cd\u4f5c\u7b26\u3002 \u4e0b\u9762\u8fd9\u6bb5\u4ee3\u7801\uff0c\u6f14\u793a\u4e86\u8fd9\u79cd\u65b0\u7684\u683c\u5f0f\u5316\u65b9\u5f0f\u3002\u5728\u4f20\u7ed9format\u51fd\u6570\u7684\u683c\u5f0f\u91cc\u9762\uff0c\u9017\u53f7\u8868\u793a\u663e\u793a\u5343\u4f4d\u5206\u9694\u7b26\uff0c^\u8868\u793a\u5c45\u4e2d\u5bf9\u9f50\u3002 >>> a = 1234.5678 >>> formatted = format(a, ',.2f') >>> formatted '1,234.57' >>> b = 'my string' >>> formatted = format(b, '^20s') >>> formatted ' my string ' \u5982\u679cstr\u7c7b\u578b\u7684\u5b57\u7b26\u4e32\u91cc\u9762\u6709\u8bb8\u591a\u503c\u90fd\u9700\u8981\u8c03\u6574\u683c\u5f0f\uff0c\u5219\u53ef\u4ee5\u628a\u683c\u5f0f\u6709\u5f85\u8c03\u6574\u7684\u90a3\u4e9b\u4f4d\u7f6e\u5728\u5b57\u7b26\u4e32\u91cc\u9762\u5148\u7528{}\u4ee3\u66ff\uff0c\u7136\u540e\u6309\u4ece\u5de6\u5230\u53f3\u7684\u987a\u5e8f\uff0c\u628a\u9700\u8981\u586b\u5199\u5230\u90a3\u4e9b\u4f4d\u7f6e\u7684\u503c\u4f20\u7ed9format\u65b9\u6cd5\uff0c\u4f7f\u8fd9\u4e9b\u503c\u4f9d\u6b21\u51fa\u73b0\u5728\u5b57\u7b26\u4e32\u4e2d\u7684\u76f8\u5e94\u4f4d\u7f6e\u3002 >>> key = 'my_var' >>> value = 1.234 >>> formatted = '{} = {}'.format(key, value) >>> formatted 'my_var = 1.234' >>> formatted = '{} = {}'.format(value, key) >>> formatted '1.234 = my_var' \u901a\u8fc7\u5728{}\u91cc\u5199\u4e2a\u5192\u53f7\uff0c\u7136\u540e\u628a\u683c\u5f0f\u8bf4\u660e\u7b26\u5199\u5728\u5192\u53f7\u7684\u53f3\u8fb9\uff0c\u6765\u6dfb\u52a0\u683c\u5f0f\u3002\uff08\u6dfb\u52a0\u683c\u5f0f\u540e\uff0c\u4e92\u6362\u4f1a\u62a5\u9519\uff09 >>> formatted = '{:<10} = {:.2f}'.format(key, value) >>> formatted 'my_var = 1.23' >>> formatted = '{:<10} = {:.2f}'.format(value, key) Traceback (most recent call last): File \"\", line 1, in ValueError: Unknown format code 'f' for object of type 'str' \u4e5f\u53ef\u4ee5\u7ed9str\u7684{}\u91cc\u9762\u5199\u4e0a\u6570\u5b57\uff0c\u7528\u6765\u6307\u4ee3format\u65b9\u6cd5\u5728\u8fd9\u4e2a\u4f4d\u7f6e\u6240\u63a5\u6536\u5230\u7684\u53c2\u6570\u503c\u4f4d\u7f6e\u7d22\u5f15\u3002 \u4ee5\u540e\u5373\u4f7f\u8fd9\u4e9b{}\u5728\u683c\u5f0f\u5b57\u7b26\u4e32\u4e2d\u7684\u6b21\u5e8f\u6709\u6240\u53d8\u52a8\uff0c\u4e5f\u4e0d\u7528\u8c03\u6362\u4f20\u7ed9format\u65b9\u6cd5\u7684\u90a3\u4e9b\u53c2\u6570\u3002\u4e8e\u662f\uff0c\u8fd9\u5c31\u907f\u514d\u4e86\u524d\u9762\u8bb2\u7684\u7b2c\u4e00\u4e2a\u7f3a\u70b9\u6240\u63d0\u5230\u7684\u90a3\u4e2a\u987a\u5e8f\u95ee\u9898\u3002 >>> key = 'my_var' >>> value = 1.234 >>> formatted = '{} = {}'.format(key, value) >>> formatted 'my_var = 1.234' >>> formatted = '{1} = {0}'.format(key, value) >>> formatted '1.234 = my_var' >>> formatted = '{2} = {1}'.format(key, value) Traceback (most recent call last): File \"\", line 1, in IndexError: Replacement index 2 out of range for positional args tuple \u540c\u4e00\u4e2a\u4f4d\u7f6e\u7d22\u5f15\u53ef\u4ee5\u51fa\u73b0\u5728str\u7684\u591a\u4e2a{}\u91cc\u9762\uff0c\u8fd9\u5c31\u4e0d\u9700\u8981\u628a\u8fd9\u4e2a\u503c\u91cd\u590d\u5730\u4f20\u7ed9format\u65b9\u6cd5\uff0c\u4e8e\u662f\u5c31\u89e3\u51b3\u4e86\u524d\u9762\u63d0\u5230\u7684\u7b2c\u4e09\u4e2a\u7f3a\u70b9\u3002 >>> name = 'Max' >>> formatted = '%s loves food. See %s cook.' % (name, name) >>> formatted 'Max loves food. See Max cook.' >>> formatted = '%(name)s loves food. See %(name)s cook.' % {'name': name} >>> formatted 'Max loves food. See Max cook.' >>> formatted = '{0} loves food. See {0} cook.'.format(name) >>> formatted 'Max loves food. See Max cook.' \u4e0a\u8ff0\u529f\u80fd\u5206\u6790\uff1a \u7cfb\u7edf\u5148\u628astr.format\u65b9\u6cd5\u63a5\u6536\u5230\u7684\u6bcf\u4e2a\u503c\u4f20\u7ed9\u5185\u7f6e\u7684format\u51fd\u6570\uff0c\u5e76\u627e\u5230\u8fd9\u4e2a\u503c\u5728\u5b57\u7b26\u4e32\u91cc\u5bf9\u5e94\u7684{}\uff0c\u540c\u65f6\u5c06{}\u91cc\u9762\u5199\u7684\u683c\u5f0f\u4e5f\u4f20\u7ed9format\u51fd\u6570\uff0c\u4f8b\u5982\u7cfb\u7edf\u5728\u5904\u7406value\u7684\u65f6\u5019\uff0c\u4f20\u7684\u5c31\u662fformat(value,'.2f')\u3002 \u7136\u540e\uff0c\u7cfb\u7edf\u4f1a\u628aformat\u51fd\u6570\u6240\u8fd4\u56de\u7684\u7ed3\u679c\u5199\u5728\u6574\u4e2a\u683c\u5f0f\u5316\u5b57\u7b26\u4e32{}\u6240\u5728\u7684\u4f4d\u7f6e\u3002 \u53e6\u5916\uff0c\u6bcf\u4e2a\u7c7b\u90fd\u53ef\u4ee5\u901a\u8fc7__format__\u8fd9\u4e2a\u7279\u6b8a\u7684\u65b9\u6cd5\u5b9a\u5236\u76f8\u5e94\u7684\u903b\u8f91\uff0c\u8fd9\u6837\u7684\u8bdd\uff0cformat\u51fd\u6570\u5728\u628a\u8be5\u7c7b\u5b9e\u4f8b\u8f6c\u6362\u6210\u5b57\u7b26\u4e32\u65f6\uff0c\u5c31\u4f1a\u6309\u7167\u8fd9\u79cd\u903b\u8f91\u6765\u8f6c\u6362\u3002 \u8f6c\u4e49\u5904\u7406\uff1a >>> formatted = '%.2f%%' % 12.5 >>> formatted '12.50%' >>> formatted = '{} replace {{}}'.format(1.23) >>> formatted '1.23 replace {}' \u7136\u800c\uff0cstr.format\u65b9\u6cd5\u5e76\u6ca1\u6709\u89e3\u51b3\u4e0a\u9762\u8bb2\u7684\u7b2c\u4e8c\u4e2a\u7f3a\u70b9\u3002\u5982\u679c\u5728\u5bf9\u503c\u505a\u586b\u5145\u4e4b\u524d\u8981\u5148\u5bf9\u8fd9\u4e2a\u503c\u505a\u51fa\u8c03\u6574\uff0c\u90a3\u4e48\u7528\u8fd9\u79cd\u65b9\u6cd5\u5199\u51fa\u6765\u7684\u4ee3\u7801\u8fd8\u662f\u8ddf\u539f\u6765\u4e00\u6837\u4e71\uff0c\u9605\u8bfb\u6027\u5dee\u3002\u5bf9\u6bd4\u4e00\u4e0b\uff1a >>> pantry = [ ... ('avocados', 1.25), ... ('bananas', 2.5), ... ('cherries', 15) ... ] >>> for i, (item, count) in enumerate(pantry): ... before = '#%d: %-10s = %.2f' % ( ... i + 1, ... item.title(), ... round(count) ... ) ... after = '#%(loop)d: %(item)-10s = %(count).2f' % { ... 'loop': i + 1, ... 'item': item.title(), ... 'count': round(count) ... } ... new_style = '#{}: {:<10s} = {:.2f}'.format( ... i + 1, ... item.title(), ... round(count) ... ) ... assert before == after == new_style ... print(before) ... print(after) ... print(new_style) ... #1: Avocados = 1.00 #1: Avocados = 1.00 #1: Avocados = 1.00 #2: Bananas = 2.00 #2: Bananas = 2.00 #2: Bananas = 2.00 #3: Cherries = 15.00 #3: Cherries = 15.00 #3: Cherries = 15.00","title":"\u5185\u7f6e\u7684format\u51fd\u6570\u4e0estr\u7c7b\u7684format\u65b9\u6cd5"},{"location":"python/Pythonic90Rules/Rule04/#f-string","text":"Python 3.6\u6dfb\u52a0\u4e86\u4e00\u79cd\u65b0\u7684\u7279\u6027\uff0c\u53eb\u4f5c\u63d2\u503c\u683c\u5f0f\u5b57\u7b26\u4e32\uff08interpolated format string\uff0c\u7b80\u79f0f-string\uff09\uff0c\u53ef\u4ee5\u89e3\u51b3\u4e0a\u9762\u63d0\u5230\u7684\u6240\u6709\u95ee\u9898\u3002 \u4e0b\u9762\u6309\u7167\u4ece\u77ed\u5230\u957f\u7684\u987a\u5e8f\u628a\u8fd9\u51e0\u79cd\u5199\u6cd5\u6240\u5360\u7684\u7bc7\u5e45\u5bf9\u6bd4\u4e00\u4e0b\uff0c\u8fd9\u6837\u5f88\u5bb9\u6613\u770b\u51fa\u7b26\u53f7\u53f3\u8fb9\u7684\u4ee3\u7801\u5230\u5e95\u6709\u591a\u5c11\u3002C\u98ce\u683c\u7684\u5199\u6cd5\u4e0e\u91c7\u7528str.format\u65b9\u6cd5\u7684\u5199\u6cd5\u53ef\u80fd\u4f1a\u8ba9\u8868\u8fbe\u5f0f\u53d8\u5f97\u5f88\u957f\uff0c\u4f46\u5982\u679c\u6539\u7528f-string\uff0c\u6216\u8bb8\u4e00\u884c\u5c31\u80fd\u5199\u5b8c\u3002 >>> key = 'my_var' >>> value = 1.234 >>> f_string = f'{key:<10} = {value:.2f}' >>> c_tuple = '%-10s = %.2f' % (key, value) >>> str_args = '{:<10} = {:.2f}'.format(key, value) >>> str_kw = '{key:<10} = {value:.2f}'.format(key=key, value=value) >>> c_dict = '%(key)-10s = %(value).2f' % {'key': key, 'value': value} >>> assert c_tuple == c_dict == f_string >>> assert str_args == str_kw == f_string >>> f_string 'my_var = 1.23' >>> c_tuple 'my_var = 1.23' >>> str_args 'my_var = 1.23' >>> str_kw 'my_var = 1.23' >>> c_dict 'my_var = 1.23' \u5bf9\u6bd4\u4e0b\u9762\uff0c\u628astr.format\u65b9\u6cd5\u7684\u5199\u6cd5\u6539\u7528f-string\uff0c\u4e00\u884c\u5c31\u80fd\u5199\u5b8c\u3002 >>> pantry = [ ... ('avocados', 1.25), ... ('bananas', 2.5), ... ('cherries', 15) ... ] >>> for i, (item, count) in enumerate(pantry): ... before = '#%d: %-10s = %.2f' % ( ... i + 1, ... item.title(), ... round(count) ... ) ... after = '#%(loop)d: %(item)-10s = %(count).2f' % { ... 'loop': i + 1, ... 'item': item.title(), ... 'count': round(count) ... } ... new_style = '#{}: {:<10s} = {:.2f}'.format( ... i + 1, ... item.title(), ... round(count) ... ) ... f_string = f'#{i+1}: {item.title():<10s} = {round(count):.2f}' ... assert before == after == new_style == f_string ... print(before) ... print(after) ... print(new_style) ... print(f_string) ... #1: Avocados = 1.00 #1: Avocados = 1.00 #1: Avocados = 1.00 #1: Avocados = 1.00 #2: Bananas = 2.00 #2: Bananas = 2.00 #2: Bananas = 2.00 #2: Bananas = 2.00 #3: Cherries = 15.00 #3: Cherries = 15.00 #3: Cherries = 15.00 #3: Cherries = 15.00 \u8981\u70b9\u603b\u7ed3\uff1a \u91c7\u7528%\u64cd\u4f5c\u7b26\u628a\u503c\u586b\u5145\u5230C\u98ce\u683c\u7684\u683c\u5f0f\u5b57\u7b26\u4e32\u65f6\u4f1a\u9047\u5230\u8bb8\u591a\u95ee\u9898\uff0c\u800c\u4e14\u8fd9\u79cd\u5199\u6cd5\u6bd4\u8f83\u70e6\u7410\u3002 str.format\u65b9\u6cd5\u4e13\u95e8\u7528\u4e00\u5957\u8ff7\u4f60\u8bed\u8a00\u6765\u5b9a\u4e49\u5b83\u7684\u683c\u5f0f\u8bf4\u660e\u7b26\uff0c\u8fd9\u5957\u8bed\u8a00\u7ed9\u6211\u4eec\u63d0\u4f9b\u4e86\u4e00\u4e9b\u6709\u7528\u7684\u6982\u5ff5\uff0c\u4f46\u662f\u5728\u5176\u4ed6\u65b9\u9762\uff0c\u8fd9\u4e2a\u65b9\u6cd5\u8fd8\u662f\u5b58\u5728\u4e0eC\u98ce\u683c\u7684\u683c\u5f0f\u5b57\u7b26\u4e32\u4e00\u6837\u7684\u591a\u79cd\u7f3a\u70b9\uff0c\u6240\u4ee5\u6211\u4eec\u4e5f\u5e94\u8be5\u907f\u514d\u4f7f\u7528\u5b83\u3002 f-string\u91c7\u7528\u65b0\u7684\u5199\u6cd5\uff0c\u5c06\u503c\u586b\u5145\u5230\u5b57\u7b26\u4e32\u4e4b\u4e2d\uff0c\u89e3\u51b3\u4e86C\u98ce\u683c\u7684\u683c\u5f0f\u5b57\u7b26\u4e32\u6240\u5e26\u6765\u7684\u6700\u5927\u95ee\u9898\u3002 f-string\u662f\u4e2a\u7b80\u6d01\u800c\u5f3a\u5927\u7684\u673a\u5236\uff0c\u53ef\u4ee5\u76f4\u63a5\u5728\u683c\u5f0f\u8bf4\u660e\u7b26\u91cc\u5d4c\u5165\u4efb\u610fPython\u8868\u8fbe\u5f0f\u3002","title":"\u63d2\u503c\u683c\u5f0f\u5b57\u7b26\u4e32f-string"},{"location":"python/Pythonic90Rules/Rule05/","text":"\u7b2c5\u6761\u3000\u7528\u8f85\u52a9\u51fd\u6570\u53d6\u4ee3\u590d\u6742\u7684\u8868\u8fbe\u5f0f \u00b6 Python\u7684\u8bed\u6cd5\u76f8\u5f53\u7b80\u660e\uff0c\u6240\u4ee5\u6709\u65f6\u53ea\u7528\u4e00\u6761\u8868\u8fbe\u5f0f\u5c31\u80fd\u5b9e\u73b0\u8bb8\u591a\u903b\u8f91\u3002 \u4f8b\u5982\uff0c\u8981\u628aURL\u4e4b\u4e2d\u7684\u67e5\u8be2\u5b57\u7b26\u4e32\u62c6\u5206\u6210\u952e\u503c\u5bf9\uff0c\u90a3\u4e48\u53ea\u9700\u8981\u4f7f\u7528parse_qs\u51fd\u6570\u5c31\u53ef\u4ee5\u4e86\u3002 >>> from urllib.parse import parse_qs >>> my_value = parse_qs('red=5&blue=0&green=', keep_blank_values=True) >>> my_value {'red': ['5'], 'blue': ['0'], 'green': ['']} \u5728\u89e3\u6790\u67e5\u8be2\u5b57\u7b26\u4e32\u65f6\uff0c\u53ef\u4ee5\u53d1\u73b0\uff0c\u6709\u7684\u53c2\u6570\u53ef\u80fd\u5e26\u6709\u591a\u4e2a\u503c\uff0c\u6709\u7684\u53c2\u6570\u53ef\u80fd\u53ea\u6709\u4e00\u4e2a\u503c\uff0c\u8fd8\u6709\u7684\u53c2\u6570\u53ef\u80fd\u662f\u7a7a\u767d\u503c\uff0c\u53e6\u5916\u4e5f\u4f1a\u9047\u5230\u6839\u672c\u6ca1\u63d0\u4f9b\u8fd9\u4e2a\u53c2\u6570\u7684\u60c5\u51b5\u3002 \u4e0b\u9762\u8fd9\u4e09\u884c\u4ee3\u7801\u5206\u522b\u901a\u8fc7get\u65b9\u6cd5\u67e5\u8be2\u7ed3\u679c\u5b57\u5178\u91cc\u9762\u7684\u4e09\u4e2a\u53c2\u6570\uff0c\u8fd9\u521a\u597d\u5bf9\u5e94\u4e09\u79cd\u4e0d\u540c\u7684\u60c5\u51b5\uff1a >>> red = my_value.get('red') >>> green = my_value.get('green') >>> opacity = my_value.get('Opacity') >>> print('Red ', red) Red ['5'] >>> print('Green ', green) Green [''] >>> print('Opacity ', opacity) Opacity None \u901a\u8fc7Boolean\u8868\u8fbe\u5f0f\u6765\u5b9e\u73b0\u628a\u4e0a\u8ff0\u53c2\u6570\u7f3a\u5931\u4e0e\u53c2\u6570\u4e3a\u7a7a\u8fd9\u4e24\u79cd\u60c5\u51b5\u9ed8\u8ba4\u503c\u90fd\u8bbe\u62100\u3002Boolean\u8868\u8fbe\u5f0f\u4f1a\u628a\u7a7a\u767d\u5b57\u7b26\u4e32\u3001\u7a7a\u767dlist\u4ee5\u53ca0\u503c\uff0c\u5168\u90fd\u5f53\u6210False\u770b\u5f85\u3002 >>> red = my_value.get('red', [''])[0] or 0 >>> green = my_value.get('green', [''])[0] or 0 >>> opacity = my_value.get('Opacity', [''])[0] or 0 >>> print(f'Red : {red!r}') Red : '5' >>> print(f'Green : {green!r}') Green : 0 >>> print(f'Opacity : {opacity!r}') Opacity : 0 \u4e0a\u8ff0\u4ee3\u7801\u89e3\u6790\uff1a \u56e0\u4e3ared\u952e\u5b58\u5728\u4e8emy_value\u5b57\u5178\uff08dict\uff09\u91cc\u9762\uff0c\u5b83\u5bf9\u5e94\u7684\u503c\u662f\u4e2a\u53ea\u6709\u4e00\u4e2a\u5143\u7d20\u7684\u5217\u8868 ['5'] \uff0c\u8fd9\u4e2a\u5143\u7d20\u662f\u5b57\u7b26\u4e32'5'\u3002Python\u4f1a\u628a\u5b57\u7b26\u4e32'5' \u89e3\u6790\u4e3aTrue\uff0c\u6240\u4ee5\u6574\u4e2a\u8868\u8fbe\u5f0f\u7684\u503c\u5c31\u7b49\u4e8eor\u5de6\u4fa7\u90a3\u4e2a\u5b50\u8868\u8fbe\u5f0f\u7684\u503c\uff0c\u5373 my_values.get('red', [''])[0] \u3002 \u5bf9\u4e8egreen\uff0c\u8fd9\u4e2a\u952e\u503c\u4e5f\u5b58\u5728\u4e8emy_value\u5b57\u5178\uff08dict\uff09\u91cc\u9762\uff0c\u5b83\u5bf9\u5e94\u7684\u503c\u662f\u4e2a\u53ea\u6709\u4e00\u4e2a\u5143\u7d20\u7684\u5217\u8868 [''] \uff0c\u8fd9\u4e2a\u5143\u7d20\u662f\u7a7a\u767d\u5b57\u7b26\u4e32\u3002Python\u4f1a\u628a\u7a7a\u767d\u5b57\u7b26\u4e32\u89e3\u6790\u4e3aFalse\uff0c\u6240\u4ee5green\u53d8\u91cf\u7684\u503c\u5c31\u7b49\u4e8eor\u53f3\u4fa7\u90a3\u4e2a\u5b50\u8868\u8fbe\u5f0f\u7684\u503c\uff0c\u4e5f\u5c31\u662f0\u3002 \u5bf9\u4e8eopacity\uff0c\u8fd9\u4e2a\u952e\u503c\u4e0d\u5b58\u5728\u4e8emy_value\u5b57\u5178\uff08dict\uff09\u91cc\u9762\uff0cget\u65b9\u6cd5\u4f1a\u8fd4\u56de\u4f20\u9012\u7ed9\u5b83\u7684\u7b2c\u4e8c\u4e2a\u503c [''] \uff0c\u548cgreen\u7684\u60c5\u51b5\u7c7b\u4f3c\uff0c\u5143\u7d20\u662f\u7a7a\u767d\u5b57\u7b26\u4e32\u3002Python\u4f1a\u628a\u7a7a\u767d\u5b57\u7b26\u4e32\u89e3\u6790\u4e3aFalse\uff0c\u6240\u4ee5opacity\u53d8\u91cf\u7684\u503c\u5c31\u7b49\u4e8eor\u53f3\u4fa7\u90a3\u4e2a\u5b50\u8868\u8fbe\u5f0f\u7684\u503c\uff0c\u4e5f\u5c31\u662f0\u3002 \u4f46\u662f\uff0c\u4e0a\u9762\u7684\u8868\u8fbe\u5f0f\u53ef\u8bfb\u6027\u6bd4\u8f83\u5dee\uff0c\u76f8\u6bd4\u4e4b\u4e0b\uff0c\u6539\u7528if/else\u6761\u4ef6\u8868\u8fbe\u5f0f\uff0c\u4ee3\u7801\u53ef\u8bfb\u6027\u4f1a\u597d\u4e00\u4e9b\u3002 >>> green_str = my_value.get('green', ['']) >>> if green_str[0]: ... green = green_str[0] ... else: ... green =0 ... >>> green 0 \u5982\u679c\u8981\u53cd\u590d\u4f7f\u7528\u8fd9\u5957\u903b\u8f91\uff0c\u5efa\u8bae\u5199\u6210\u8f85\u52a9\u51fd\u6570\u6bd4\u8f83\u597d\uff0c\u5373\u4f7f\u50cf\u4e0a\u9762\u8fd9\u4e2a\u4f8b\u5b50\u4e00\u6837\u53ea\u7528\u4e09\u6b21\u3002 >>> def get_first_value(value, key, default=0): ... found = value.get(key, ['']) ... if found[0]: ... return found[0] ... return default ... >>> green = get_first_value(my_value, 'green') >>> green 0 \u8981\u70b9\uff1a * Python\u7684\u8bed\u6cd5\u5f88\u5bb9\u6613\u628a\u590d\u6742\u7684\u610f\u601d\u6324\u5230\u540c\u4e00\u884c\u8868\u8fbe\u5f0f\u91cc\uff0c\u8fd9\u6837\u5199\u5f88\u96be\u61c2\u3002 * \u590d\u6742\u7684\u8868\u8fbe\u5f0f\uff0c\u5c24\u5176\u662f\u90a3\u79cd\u9700\u8981\u91cd\u590d\u4f7f\u7528\u7684\u590d\u6742\u8868\u8fbe\u5f0f\uff0c\u5e94\u8be5\u5199\u5230\u8f85\u52a9\u51fd\u6570\u91cc\u9762\u3002 * \u7528if/else\u7ed3\u6784\u5199\u6210\u7684\u6761\u4ef6\u8868\u8fbe\u5f0f\uff0c\u8981\u6bd4\u7528or\u4e0eand\u5199\u6210\u7684Boolean\u8868\u8fbe\u5f0f\u66f4\u597d\u61c2\u3002 * \u9075\u5faa\u5faaDRY\u539f\u5219\uff0c\u4e0d\u8981\u91cd\u590d\u81ea\u5df1\u5199\u8fc7\u7684\u4ee3\u7801\uff08Don't Repeat Yourself\uff09\u3002","title":"\u7b2c05\u6761 \u7528\u8f85\u52a9\u51fd\u6570\u53d6\u4ee3\u590d\u6742\u7684\u8868\u8fbe\u5f0f"},{"location":"python/Pythonic90Rules/Rule05/#5","text":"Python\u7684\u8bed\u6cd5\u76f8\u5f53\u7b80\u660e\uff0c\u6240\u4ee5\u6709\u65f6\u53ea\u7528\u4e00\u6761\u8868\u8fbe\u5f0f\u5c31\u80fd\u5b9e\u73b0\u8bb8\u591a\u903b\u8f91\u3002 \u4f8b\u5982\uff0c\u8981\u628aURL\u4e4b\u4e2d\u7684\u67e5\u8be2\u5b57\u7b26\u4e32\u62c6\u5206\u6210\u952e\u503c\u5bf9\uff0c\u90a3\u4e48\u53ea\u9700\u8981\u4f7f\u7528parse_qs\u51fd\u6570\u5c31\u53ef\u4ee5\u4e86\u3002 >>> from urllib.parse import parse_qs >>> my_value = parse_qs('red=5&blue=0&green=', keep_blank_values=True) >>> my_value {'red': ['5'], 'blue': ['0'], 'green': ['']} \u5728\u89e3\u6790\u67e5\u8be2\u5b57\u7b26\u4e32\u65f6\uff0c\u53ef\u4ee5\u53d1\u73b0\uff0c\u6709\u7684\u53c2\u6570\u53ef\u80fd\u5e26\u6709\u591a\u4e2a\u503c\uff0c\u6709\u7684\u53c2\u6570\u53ef\u80fd\u53ea\u6709\u4e00\u4e2a\u503c\uff0c\u8fd8\u6709\u7684\u53c2\u6570\u53ef\u80fd\u662f\u7a7a\u767d\u503c\uff0c\u53e6\u5916\u4e5f\u4f1a\u9047\u5230\u6839\u672c\u6ca1\u63d0\u4f9b\u8fd9\u4e2a\u53c2\u6570\u7684\u60c5\u51b5\u3002 \u4e0b\u9762\u8fd9\u4e09\u884c\u4ee3\u7801\u5206\u522b\u901a\u8fc7get\u65b9\u6cd5\u67e5\u8be2\u7ed3\u679c\u5b57\u5178\u91cc\u9762\u7684\u4e09\u4e2a\u53c2\u6570\uff0c\u8fd9\u521a\u597d\u5bf9\u5e94\u4e09\u79cd\u4e0d\u540c\u7684\u60c5\u51b5\uff1a >>> red = my_value.get('red') >>> green = my_value.get('green') >>> opacity = my_value.get('Opacity') >>> print('Red ', red) Red ['5'] >>> print('Green ', green) Green [''] >>> print('Opacity ', opacity) Opacity None \u901a\u8fc7Boolean\u8868\u8fbe\u5f0f\u6765\u5b9e\u73b0\u628a\u4e0a\u8ff0\u53c2\u6570\u7f3a\u5931\u4e0e\u53c2\u6570\u4e3a\u7a7a\u8fd9\u4e24\u79cd\u60c5\u51b5\u9ed8\u8ba4\u503c\u90fd\u8bbe\u62100\u3002Boolean\u8868\u8fbe\u5f0f\u4f1a\u628a\u7a7a\u767d\u5b57\u7b26\u4e32\u3001\u7a7a\u767dlist\u4ee5\u53ca0\u503c\uff0c\u5168\u90fd\u5f53\u6210False\u770b\u5f85\u3002 >>> red = my_value.get('red', [''])[0] or 0 >>> green = my_value.get('green', [''])[0] or 0 >>> opacity = my_value.get('Opacity', [''])[0] or 0 >>> print(f'Red : {red!r}') Red : '5' >>> print(f'Green : {green!r}') Green : 0 >>> print(f'Opacity : {opacity!r}') Opacity : 0 \u4e0a\u8ff0\u4ee3\u7801\u89e3\u6790\uff1a \u56e0\u4e3ared\u952e\u5b58\u5728\u4e8emy_value\u5b57\u5178\uff08dict\uff09\u91cc\u9762\uff0c\u5b83\u5bf9\u5e94\u7684\u503c\u662f\u4e2a\u53ea\u6709\u4e00\u4e2a\u5143\u7d20\u7684\u5217\u8868 ['5'] \uff0c\u8fd9\u4e2a\u5143\u7d20\u662f\u5b57\u7b26\u4e32'5'\u3002Python\u4f1a\u628a\u5b57\u7b26\u4e32'5' \u89e3\u6790\u4e3aTrue\uff0c\u6240\u4ee5\u6574\u4e2a\u8868\u8fbe\u5f0f\u7684\u503c\u5c31\u7b49\u4e8eor\u5de6\u4fa7\u90a3\u4e2a\u5b50\u8868\u8fbe\u5f0f\u7684\u503c\uff0c\u5373 my_values.get('red', [''])[0] \u3002 \u5bf9\u4e8egreen\uff0c\u8fd9\u4e2a\u952e\u503c\u4e5f\u5b58\u5728\u4e8emy_value\u5b57\u5178\uff08dict\uff09\u91cc\u9762\uff0c\u5b83\u5bf9\u5e94\u7684\u503c\u662f\u4e2a\u53ea\u6709\u4e00\u4e2a\u5143\u7d20\u7684\u5217\u8868 [''] \uff0c\u8fd9\u4e2a\u5143\u7d20\u662f\u7a7a\u767d\u5b57\u7b26\u4e32\u3002Python\u4f1a\u628a\u7a7a\u767d\u5b57\u7b26\u4e32\u89e3\u6790\u4e3aFalse\uff0c\u6240\u4ee5green\u53d8\u91cf\u7684\u503c\u5c31\u7b49\u4e8eor\u53f3\u4fa7\u90a3\u4e2a\u5b50\u8868\u8fbe\u5f0f\u7684\u503c\uff0c\u4e5f\u5c31\u662f0\u3002 \u5bf9\u4e8eopacity\uff0c\u8fd9\u4e2a\u952e\u503c\u4e0d\u5b58\u5728\u4e8emy_value\u5b57\u5178\uff08dict\uff09\u91cc\u9762\uff0cget\u65b9\u6cd5\u4f1a\u8fd4\u56de\u4f20\u9012\u7ed9\u5b83\u7684\u7b2c\u4e8c\u4e2a\u503c [''] \uff0c\u548cgreen\u7684\u60c5\u51b5\u7c7b\u4f3c\uff0c\u5143\u7d20\u662f\u7a7a\u767d\u5b57\u7b26\u4e32\u3002Python\u4f1a\u628a\u7a7a\u767d\u5b57\u7b26\u4e32\u89e3\u6790\u4e3aFalse\uff0c\u6240\u4ee5opacity\u53d8\u91cf\u7684\u503c\u5c31\u7b49\u4e8eor\u53f3\u4fa7\u90a3\u4e2a\u5b50\u8868\u8fbe\u5f0f\u7684\u503c\uff0c\u4e5f\u5c31\u662f0\u3002 \u4f46\u662f\uff0c\u4e0a\u9762\u7684\u8868\u8fbe\u5f0f\u53ef\u8bfb\u6027\u6bd4\u8f83\u5dee\uff0c\u76f8\u6bd4\u4e4b\u4e0b\uff0c\u6539\u7528if/else\u6761\u4ef6\u8868\u8fbe\u5f0f\uff0c\u4ee3\u7801\u53ef\u8bfb\u6027\u4f1a\u597d\u4e00\u4e9b\u3002 >>> green_str = my_value.get('green', ['']) >>> if green_str[0]: ... green = green_str[0] ... else: ... green =0 ... >>> green 0 \u5982\u679c\u8981\u53cd\u590d\u4f7f\u7528\u8fd9\u5957\u903b\u8f91\uff0c\u5efa\u8bae\u5199\u6210\u8f85\u52a9\u51fd\u6570\u6bd4\u8f83\u597d\uff0c\u5373\u4f7f\u50cf\u4e0a\u9762\u8fd9\u4e2a\u4f8b\u5b50\u4e00\u6837\u53ea\u7528\u4e09\u6b21\u3002 >>> def get_first_value(value, key, default=0): ... found = value.get(key, ['']) ... if found[0]: ... return found[0] ... return default ... >>> green = get_first_value(my_value, 'green') >>> green 0 \u8981\u70b9\uff1a * Python\u7684\u8bed\u6cd5\u5f88\u5bb9\u6613\u628a\u590d\u6742\u7684\u610f\u601d\u6324\u5230\u540c\u4e00\u884c\u8868\u8fbe\u5f0f\u91cc\uff0c\u8fd9\u6837\u5199\u5f88\u96be\u61c2\u3002 * \u590d\u6742\u7684\u8868\u8fbe\u5f0f\uff0c\u5c24\u5176\u662f\u90a3\u79cd\u9700\u8981\u91cd\u590d\u4f7f\u7528\u7684\u590d\u6742\u8868\u8fbe\u5f0f\uff0c\u5e94\u8be5\u5199\u5230\u8f85\u52a9\u51fd\u6570\u91cc\u9762\u3002 * \u7528if/else\u7ed3\u6784\u5199\u6210\u7684\u6761\u4ef6\u8868\u8fbe\u5f0f\uff0c\u8981\u6bd4\u7528or\u4e0eand\u5199\u6210\u7684Boolean\u8868\u8fbe\u5f0f\u66f4\u597d\u61c2\u3002 * \u9075\u5faa\u5faaDRY\u539f\u5219\uff0c\u4e0d\u8981\u91cd\u590d\u81ea\u5df1\u5199\u8fc7\u7684\u4ee3\u7801\uff08Don't Repeat Yourself\uff09\u3002","title":"\u7b2c5\u6761\u3000\u7528\u8f85\u52a9\u51fd\u6570\u53d6\u4ee3\u590d\u6742\u7684\u8868\u8fbe\u5f0f"},{"location":"python/Pythonic90Rules/Rule06/","text":"\u7b2c6\u6761\u3000\u628a\u6570\u636e\u7ed3\u6784\u76f4\u63a5\u62c6\u5206\u5230\u591a\u4e2a\u53d8\u91cf\u91cc\uff0c\u4e0d\u8981\u4e13\u95e8\u901a\u8fc7\u4e0b\u6807\u8bbf\u95ee \u00b6 Python\u5185\u7f6e\u7684\u5143\u7ec4\uff08tuple\uff09\u7c7b\u578b\u53ef\u4ee5\u521b\u5efa\u4e0d\u53ef\u53d8\u7684\u5e8f\u5217\uff0c\u628a\u8bb8\u591a\u5143\u7d20\u4f9d\u6b21\u4fdd\u5b58\u8d77\u6765\u3002 \u53ef\u4ee5\u7528\u6574\u6570\u4f5c\u4e0b\u6807\uff0c\u901a\u8fc7\u4e0b\u6807\u6765\u8bbf\u95ee\u5143\u7ec4\u91cc\u9762\u5bf9\u5e94\u7684\u5143\u7d20\u3002\u4f46\u4e0d\u80fd\u901a\u8fc7\u4e0b\u6807\u7ed9\u5143\u7d20\u8d4b\u65b0\u503c\u3002 >>> snack_calories = { ... 'chips': 140, ... 'popcorn': 80, ... 'nuts': 190 ... } >>> items = tuple(snack_calories.items()) >>> type(snack_calories) >>> type(items) >>> snack_calories {'chips': 140, 'popcorn': 80, 'nuts': 190} >>> items (('chips', 140), ('popcorn', 80), ('nuts', 190)) >>> items[2] ('nuts', 190) >>> items[1] = ('apple', 200) Traceback (most recent call last): File \"\", line 1, in TypeError: 'tuple' object does not support item assignment Python\u8fd8\u6709\u4e00\u79cd\u5199\u6cd5\uff0c\u53eb\u4f5c\u62c6\u5206\uff08unpacking\uff09\u3002\u8fd9\u79cd\u5199\u6cd5\u8ba9\u6211\u4eec\u53ea\u7528\u4e00\u6761\u8bed\u53e5\uff0c\u5c31\u53ef\u4ee5\u628a\u5143\u7ec4\u91cc\u9762\u7684\u5143\u7d20\u5206\u522b\u8d4b\u7ed9\u591a\u4e2a\u53d8\u91cf\uff0c\u4e0d\u7528\u518d\u901a\u8fc7\u4e0b\u6807\u53bb\u8bbf\u95ee\u3002 \u5143\u7ec4\u7684\u5143\u7d20\u672c\u8eab\u4e0d\u80fd\u4fee\u6539\uff0c\u4f46\u662f\u90a3\u4e9b\u88ab\u8d4b\u503c\u7684\u53d8\u91cf\u662f\u53ef\u4ee5\u4fee\u6539\u7684\u3002 \u901a\u8fc7unpacking\u6765\u8d4b\u503c\u8981\u6bd4\u901a\u8fc7\u4e0b\u6807\u53bb\u8bbf\u95ee\u5143\u7ec4\u5185\u7684\u5143\u7d20\u66f4\u6e05\u6670\uff0c\u800c\u4e14\u8fd9\u79cd\u5199\u6cd5\u6240\u9700\u7684\u4ee3\u7801\u91cf\u901a\u5e38\u6bd4\u8f83\u5c11\u3002\u5f53\u7136\uff0c\u8d4b\u503c\u64cd\u4f5c\u7684\u5de6\u8fb9\u9664\u4e86\u53ef\u4ee5\u7f57\u5217\u5355\u4e2a\u53d8\u91cf\uff0c\u4e5f\u53ef\u4ee5\u5199\u6210\u5217\u8868\u3001\u5e8f\u5217\u6216\u4efb\u610f\u6df1\u5ea6\u7684\u53ef\u8fed\u4ee3\u5bf9\u8c61\uff08iterable\uff09\u3002 >>> favorite_snacks = { ... 'salty': ('pretzels', 100), ... 'sweet': ('cookies', 280), ... 'veggie': ('carrots', 20) ... } >>> ( ... (type1, (name1, cals1)), ... (type2, (name2, cals2)), ... (type3, (name3, cals3)), ... ) = favorite_snacks.items() >>> print(f'Favorite {type1} is {name1} with {cals1} calories') Favorite salty is pretzels with 100 calories >>> print(f'Favorite {type2} is {name2} with {cals2} calories') Favorite sweet is cookies with 280 calories >>> print(f'Favorite {type3} is {name3} with {cals3} calories') Favorite veggie is carrots with 20 calories \u53ef\u4ee5\u901a\u8fc7unpacking\u539f\u5730\u4ea4\u6362\u4e24\u4e2a\u53d8\u91cf\uff0c\u800c\u4e0d\u7528\u4e13\u95e8\u521b\u5efa\u4e34\u65f6\u53d8\u91cf\u3002 >>> def bubble_sort(a): ... for _ in range(len(a)): ... for i in range(1, len(a)): ... if a[i] < a[i - 1]: ... temp = a[i] ... a[i] = a[i - 1] ... a[i - 1] = temp ... >>> names = ['pretzels', 'carrots', 'arugula', 'bacon'] >>> bubble_sort(names) >>> names ['arugula', 'bacon', 'carrots', 'pretzels'] >>> def bubble_sort(a): ... for _ in range(len(a)): ... for i in range(1, len(a)): ... if a[i] < a[i - 1]: ... a[i], a[i - 1] = a[i - 1], a[i] ... >>> names = ['pretzels', 'carrots', 'arugula', 'bacon'] >>> bubble_sort(names) >>> names ['arugula', 'bacon', 'carrots', 'pretzels'] \u539f\u7406\u5206\u6790\uff1a Python\u5904\u7406\u8d4b\u503c\u64cd\u4f5c\u7684\u65f6\u5019\uff0c\u8981\u5148\u5bf9=\u53f7\u53f3\u4fa7\u6c42\u503c\uff0c\u4e8e\u662f\uff0c\u5b83\u4f1a\u65b0\u5efa\u4e00\u4e2a\u4e34\u65f6\u7684\u5143\u7ec4\uff0c\u628a a[i] \u4e0e a[i-1] \u8fd9\u4e24\u4e2a\u5143\u7d20\u653e\u5230\u8fd9\u4e2a\u5143\u7ec4\u91cc\u9762\u3002\u4f8b\u5982\uff0c\u7b2c\u4e00\u6b21\u8fdb\u5165\u5185\u90e8\u7684for\u5faa\u73af\u65f6\uff0c\u8fd9\u4e24\u4e2a\u5143\u7d20\u5206\u522b\u662f 'carrots' \u4e0e 'pretzels '\uff0c\u4e8e\u662f\uff0c\u7cfb\u7edf\u5c31\u4f1a\u521b\u5efa\u51fa ('carrots','pretzels') \u8fd9\u6837\u4e00\u4e2a\u4e34\u65f6\u7684\u5143\u7ec4\u3002 \u7136\u540e\uff0cPython\u4f1a\u5bf9\u8fd9\u4e2a\u4e34\u65f6\u7684\u5143\u7ec4\u505aunpacking\uff0c\u628a\u5b83\u91cc\u9762\u7684\u4e24\u4e2a\u5143\u7d20\u5206\u522b\u653e\u5230=\u53f7\u5de6\u4fa7\u7684\u90a3\u4e24\u4e2a\u5730\u65b9\uff0c\u4e8e\u662f\uff0c 'carrots' \u5c31\u4f1a\u628a a[i-1] \u91cc\u9762\u539f\u6709\u7684 'pretzels' \u6362\u6389\uff0c 'pretzels' \u4e5f\u4f1a\u628a a[i] \u91cc\u9762\u539f\u6709\u7684 'carrots' \u6362\u6389\u3002 \u73b0\u5728\uff0c\u51fa\u73b0\u5728 a[0] \u8fd9\u4e2a\u4f4d\u7f6e\u4e0a\u9762\u7684\u5b57\u7b26\u4e32\u5c31\u662f 'carrots' \u4e86\uff0c\u51fa\u73b0\u5728 a[1] \u8fd9\u4e2a\u4f4d\u7f6e\u4e0a\u9762\u7684\u5b57\u7b26\u4e32\u5219\u662f 'pretzels' \u3002 \u505a\u5b8cunpacking\u540e\uff0c\u7cfb\u7edf\u4f1a\u6254\u6389\u8fd9\u4e2a\u4e34\u65f6\u7684\u5143\u7ec4\u3002 unpacking\u673a\u5236\u8fd8\u6709\u4e00\u4e2a\u7279\u522b\u91cd\u8981\u7684\u7528\u6cd5\uff0c\u5c31\u662f\u53ef\u4ee5\u5728for\u5faa\u73af\u6216\u8005\u7c7b\u4f3c\u7684\u7ed3\u6784\u91cc\u9762\uff0c\u628a\u590d\u6742\u7684\u6570\u636e\u62c6\u5206\u5230\u76f8\u5173\u7684\u53d8\u91cf\u4e4b\u4e2d\u3002 >>> snacks = [('bacon', 350), ('donut', 240), ('muffin', 190)] >>> for i in range(len(snacks)): ... item = snacks[i] ... name = item[0] ... calories = item[1] ... print(f'#{i+1}: {name} has {calories} calories') ... #1: bacon has 350 calories #2: donut has 240 calories #3: muffin has 190 calories \u4e0a\u9762\u8fd9\u6bb5\u4ee3\u7801\u867d\u7136\u6ca1\u9519\uff0c\u4f46\u770b\u8d77\u6765\u5f88\u4e71\uff0c\u56e0\u4e3asnacks\u7ed3\u6784\u672c\u8eab\u5e76\u4e0d\u662f\u4e00\u4efd\u7b80\u5355\u7684\u5217\u8868\uff0c\u5b83\u7684\u6bcf\u4e2a\u5143\u7d20\u90fd\u662f\u4e00\u4e2a\u5143\u7ec4\uff0c \u6240\u4ee5\u5fc5\u987b\u9010\u5c42\u8bbf\u95ee\u624d\u80fd\u67e5\u5230\u6700\u4e3a\u5177\u4f53\u7684\u6570\u636e\uff0c\u4e5f\u5c31\u662f\u6bcf\u79cd\u96f6\u98df\u7684\u540d\u79f0\uff08name\uff09\u53ca\u5361\u8def\u91cc\uff08calories\uff09\u3002 \u4e0b\u9762\u6362\u4e00\u79cd\u5199\u6cd5\uff0c\u9996\u5148\u8c03\u7528\u5185\u7f6e\u7684enumerate\u51fd\u6570\uff08\u53c2\u89c1\u7b2c7\u6761\uff09\u83b7\u5f97\u5f53\u524d\u8981\u8fed\u4ee3\u7684\u5143\u7ec4\uff0c \u7136\u540e\u9488\u5bf9\u8fd9\u4e2a\u5143\u7ec4\u505aunpacking\uff0c\u8fd9\u6837\u5c31\u53ef\u4ee5\u76f4\u63a5\u5f97\u5230\u5177\u4f53\u7684name\u4e0ecalories\u503c\u4e86\u3002 \u8fd9\u624d\u662f\u7b26\u5408Python\u98ce\u683c\u7684\u5199\u6cd5\uff08Pythonic\u5f0f\u7684\u5199\u6cd5\uff09\u3002 >>> for rank, (name, calories) in enumerate(snacks, 1): ... print(f'#{rank}: {name} has {calories} calories') ... #1: bacon has 350 calories #2: donut has 240 calories #3: muffin has 190 calories Python\u7684unpacking\u673a\u5236\u53ef\u4ee5\u7528\u5728\u8bb8\u591a\u65b9\u9762\uff0c\u4f8b\u5982\u6784\u5efa\u5217\u8868\uff08Rule13\uff09\u3001\u7ed9\u51fd\u6570\u8bbe\u8ba1\u53c2\u6570\u5217\u8868\uff08Rule22\uff09\u3001\u4f20\u9012\u5173\u952e\u5b57\u53c2\u6570\uff08Rule23\uff09\u3001\u63a5\u6536\u591a\u4e2a\u8fd4\u56de\u503c\uff08Rule19\u6761\uff09\u7b49\u3002 \u8981\u70b9\uff1a unpacking\u662f\u4e00\u79cd\u7279\u6b8a\u7684Python\u8bed\u6cd5\uff0c\u53ea\u9700\u8981\u4e00\u884c\u4ee3\u7801\uff0c\u5c31\u80fd\u628a\u6570\u636e\u7ed3\u6784\u91cc\u9762\u7684\u591a\u4e2a\u503c\u5206\u522b\u8d4b\u7ed9\u76f8\u5e94\u7684\u53d8\u91cf\u3002 unpacking\u5728Python\u4e2d\u5e94\u7528\u5e7f\u6cdb\uff0c\u51e1\u662f\u53ef\u8fed\u4ee3\u7684\u5bf9\u8c61\u90fd\u80fd\u62c6\u5206\uff0c\u65e0\u8bba\u5b83\u91cc\u9762\u8fd8\u6709\u591a\u5c11\u5c42\u8fed\u4ee3\u7ed3\u6784\u3002 \u5c3d\u91cf\u901a\u8fc7unpacking\u6765\u62c6\u89e3\u5e8f\u5217\u4e4b\u4e2d\u7684\u6570\u636e\uff0c\u800c\u4e0d\u8981\u901a\u8fc7\u4e0b\u6807\u8bbf\u95ee\uff0c\u8fd9\u6837\u53ef\u4ee5\u8ba9\u4ee3\u7801\u66f4\u7b80\u6d01\u3001\u66f4\u6e05\u6670\u3002 \u62d3\u5c55\uff1aPacking and Unpacking in Python \u00b6 Python allows a tuple (or list) of variables to appear on the left side of an assignment operation. Each variable in the tuple can receive one value (or more, if we use the * operator) from an iterable on the right side of the assignment. Unpacking in Python refers to an operation that consists of assigning an iterable of values to a tuple (or list) of variables in a single assignment statement. In Python, we can put a tuple of variables on the left side of an assignment operator (=) and a tuple of values on the right side. The values on the right will be automatically assigned to the variables on the left according to their position in the tuple. This is commonly known as tuple unpacking in Python. Check out the following example: >>> (a, b, c) = (1, 2, 3) >>> a 1 >>> b 2 >>> c 3 >>> birthday = ('April', 5, 2001) >>> month, day, year = birthday >>> month 'April' >>> day 5 >>> year 2001 The tuple unpacking feature got so popular among Python developers that the syntax was extended to work with any iterable object. The only requirement is that the iterable yields exactly one item per variable in the receiving tuple ( or list). Check out the following examples of how iterable unpacking works in Python: >>> # Unpackage strings >>> a, b, c = '123' >>> a '1' >>> b '2' >>> c '3' >>> # Unpackaging strings >>> a, b, c = '123' >>> a '1' >>> b '2' >>> c '3' >>> # Unpacking lists >>> a, b, c = [1, 2, 3] >>> a 1 >>> b 2 >>> c 3 >>> # Unpacking generators >>> gen = (i ** 2 for i in range(3)) >>> a, b, c = gen >>> a 0 >>> b 1 >>> c 4 >>> # Upacking dictionaries (keys, values, and items) >>> my_dict = {'one': 1, 'two': 2, 'three': 3} >>> a, b, c = my_dict >>> a 'one' >>> b 'two' >>> c 'three' >>> a, b, c = my_dict.values() >>> a 1 >>> b 2 >>> c 3 >>> a, b, c = my_dict.items() >>> a ('one', 1) >>> b ('two', 2) >>> c ('three', 3) >>> # Use a tuple on the right side of assignment statement >>> [a, b, c] = 1, 2, 3 >>> a 1 >>> b 2 >>> c 3 >>> # Use range() iterator >>> x, y, z = range(3) >>> x 0 >>> y 1 >>> z 2 As a complement, the term packing can be used when we collect several values in a single variable using the iterable unpacking operator. The * operator is known, in this context, as the tuple (or iterable) unpacking operator. It extends the unpacking functionality to allow us to collect or pack multiple values in a single variable. In the following example, we pack a tuple of values into a single variable by using the * operator: >>> *a, = 1, 2 >>> a [1, 2] For this code to work, the left side of the assignment must be a tuple (or a list). That's why we use a trailing comma. This tuple can contain as many variables as we need. However, it can only contain one starred expression. >>> # Packing trailing values >>> a, *b = 1, 2, 3 >>> a 1 >>> b [2, 3] >>> *a, b, c = 1, 2, 3 >>> a [1] >>> b 2 >>> c 3 >>> *a, b, c, d, e = 1, 2, 3 Traceback (most recent call last): File \"\", line 1, in ValueError: not enough values to unpack (expected at least 4, got 3) >>> *a, b, c, d = 1, 2, 3 >>> a [] >>> b 1 >>> c 2 >>> d 3 >>> >>> seq = [1, 2, 3, 4] >>> first, *body, last = seq >>> first, body, last (1, [2, 3], 4) >>> first, body, *last = seq >>> first, body, last (1, 2, [3, 4]) >>> ran = range(10) >>> *r, = ran >>> r [0, 1, 2, 3, 4, 5, 6, 7, 8, 9] Using Packing and Unpacking in Practice >>> employee = ['John Doe', '40', 'Software Engineer'] >>> name = employee[0] >>> age = employee[1] >>> job = employee[2] >>> name 'John Doe' >>> age '40' >>> job 'Software Engineer' >>> >>> name, age, job = ['John Doe', '40', 'Software Engineer'] >>> name 'John Doe' >>> age '40' >>> job 'Software Engineer' >>> >>> a = 100 >>> b = 200 >>> a, b = b, a >>> a 200 >>> b 100 Dropping Unneeded Values With * >>> a, b, *_ = 1, 2, 0, 0, 0, 0 >>> a 1 >>> b 2 >>> _ [0, 0, 0, 0] The rest of the information is stored in the dummy variable _, which can be ignored by our program. By default, the underscore character _ is used by the Python interpreter to store the resulting value of the statements we run in an interactive session. So, in this context, the use of this character to identify dummy variables can be ambiguous. Returning Tuples in Functions >>> def powers(num): ... return num, num ** 2, num ** 3 ... >>> # Packaging returned values in a tuple >>> result = powers(3) >>> result (3, 9, 27) >>> # Unpacking returned values to multiple variables >>> number, square, cube = powers(3) >>> number 3 >>> square 9 >>> cube 27 >>> *_, cube = powers(3) >>> cube 27 Merging Iterables With the * Operator The last two examples show that this is also a more readable and efficient way to concatenate iterables. Instead of writing list(my_set) + my_list + list(my_tuple) + list(range(1, 4)) + list(my_str) we just write [*my_set, *my_list, *my_tuple, *range(1, 4), *my_str] . >>> my_tuple = (1, 2, 3) >>> (0, *my_tuple, 4) (0, 1, 2, 3, 4) >>> my_list = [1, 2, 3] >>> [0, *my_list, 4] [0, 1, 2, 3, 4] >>> my_set = {1, 2, 3} >>> {0, *my_set, 4} {0, 1, 2, 3, 4} >>> [*my_set, *my_list, *my_tuple, *range(1, 4)] [1, 2, 3, 1, 2, 3, 1, 2, 3, 1, 2, 3] >>> my_str = \"123\" >>> [*my_set, *my_list, *my_tuple, *range(1, 4), *my_str] [1, 2, 3, 1, 2, 3, 1, 2, 3, 1, 2, 3, '1', '2', '3'] Unpacking Dictionaries With the ** Operator >>> numbers = {'one': 1, 'two': 2, 'three': 3} >>> letters = {'a': 'A', 'b': 'B', 'c': 'C'} >>> combination = {**numbers, **letters} >>> combination {'one': 1, 'two': 2, 'three': 3, 'a': 'A', 'b': 'B', 'c': 'C'} An important point to note is that, if the dictionaries we're trying to merge have repeated or common keys, then the values of the right-most dictionary will override the values of the left-most dictionary. Here's an example: >>> letters = {'a': 'A', 'b': 'B', 'c': 'C'} >>> vowels = {'a': 'a', 'e': 'e', 'i': 'i', 'o': 'o', 'u': 'u'} >>> {**letters, **vowels} {'a': 'a', 'b': 'B', 'c': 'C', 'e': 'e', 'i': 'i', 'o': 'o', 'u': 'u'} >>> {**vowels, **letters} {'a': 'A', 'e': 'e', 'i': 'i', 'o': 'o', 'u': 'u', 'b': 'B', 'c': 'C'} Unpacking in For-Loops We can also use iterable unpacking in the context of for loops. When we run a for loop, the loop assigns one item of its iterable to the target variable in every iteration. If the item to be assigned is an iterable, then we can use a tuple of target variables. The loop will unpack the iterable at hand into the tuple of target variables. We can build a list of two-elements tuples. Each tuple will contain the name of the product, the price, and the sold units. With this information, we want to calculate the income of each product. To do this, we can use a for loop like this: >>> sales = [('Pencle', 0.22, 1500), ('Notebook', 1.30, 550), ('Eraser', 0.75, 1000)] >>> for items in sales: ... print(f\"Income for {item[0]} is: {item[1] * item[2]}\") ... Traceback (most recent call last): File \"\", line 2, in NameError: name 'item' is not defined >>> for items in sales: ... print(f\"Income for {items[0]} is: {items[1] * items[2]}\") ... Income for Pencle is: 330.0 Income for Notebook is: 715.0 Income for Eraser is: 750.0 we're using indices to get access to individual elements of each tuple. This can be difficult to read and to understand by newcomer developers. We're now using iterable unpacking in our for loop in below sample codes, which is an alternative implementation using unpacking in Python: >>> sales = [('Pencle', 0.22, 1500), ('Notebook', 1.30, 550), ('Eraser', 0.75, 1000)] >>> for product, price, sold_units in sales: ... print(f\"Income for {product} is: {price * sold_units}\") ... Income for Pencle is: 330.0 Income for Notebook is: 715.0 Income for Eraser is: 750.0 It's also possible to use the * operator in a for loop to pack several items in a single target variable. In this for loop, we're catching the first element of each sequence in first. Then the * operator catches a list of values in its target variable rest. >>> for first, *rest in [(1, 2, 3),(4, 5, 6)]: ... print('First: ', first) ... print('Rest: ', rest) ... First: 1 Rest: [2, 3] First: 4 Rest: [5, 6] >>> Finally, the structure of the target variables must agree with the structure of the iterable. Otherwise, we'll get an error. Take a look at the following example: >>> data = [((1, 2), 3), ((2, 3), 3)] >>> for (a, b), c in data: ... print(a, b, c) ... 1 2 3 2 3 3 >>> for a, b, c in data: ... print(a, b, c) ... Traceback (most recent call last): File \"\", line 1, in ValueError: not enough values to unpack (expected 3, got 2) Defining Functions With * and ** The below function requires at least one argument called required . It can accept a variable number of positional and keyword arguments as well. In this case, the * operator collects or packs extra positional arguments in a tuple called args and the ** operator collects or packs extra keyword arguments in a dictionary called kwargs . Both, args and kwargs , are optional and automatically default to () and {} respectively. Even though the names args and kwargs are widely used by the Python community, they're not a requirement for these techniques to work. The syntax just requires * or ** followed by a valid identifier. So, if you can give meaningful names to these arguments, then do it. That will certainly improve your code's readability. >>> def func(required, *args, **kwargs): ... print(required) ... print(args) ... print(kwargs) ... >>> func('Welcome to ...', 1, 2, 3, site='CloudAcademy.com') Welcome to ... (1, 2, 3) {'site': 'CloudAcademy.com'} >>> func('Welcome to ...', 1, 2, 3, 4) Welcome to ... (1, 2, 3, 4) {} >>> func('Welcome to ...', 1, 2, 3, (1, 2)) Welcome to ... (1, 2, 3, (1, 2)) {} >>> func('Welcome to ...', 1, 2, 3, [1, 2]) Welcome to ... (1, 2, 3, [1, 2]) {} >>> func('Welcome to ...', 1, 2, 3, ([2, 3], [1, 2])) Welcome to ... (1, 2, 3, ([2, 3], [1, 2])) {} Calling Functions With * and ** When calling functions, we can also benefit from the use of the * and ** operator to unpack collections of arguments into separate positional or keyword arguments respectively. This is the inverse of using * and ** in the signature of a function. In the signature, the operators mean collect or pack a variable number of arguments in one identifier. In the call, they mean unpack an iterable into several arguments. Here's a basic example of how this works. The * operator unpacks sequences like [\"Welcome\", \"to\"] into positional arguments. Similarly, the ** operator unpacks dictionaries into arguments whose names match the keys of the unpacked dictionary. >>> def func(welcome, to, site): ... print(welcome, to, site ... ... ) ... >>> def func(welcome, to, site): ... print(welcome, to, site) ... >>> func(*['Welcome', 'to'], **{'site': 'CloudAcademy.com'}) Welcome to CloudAcademy.com We can also combine this technique and the one covered in the previous section to write quite flexible functions. The use of the * and ** operators, when defining and calling Python functions, will give them extra capabilities and make them more flexible and powerful. Here's an example: >>> def func(required, *args, **kwargs): ... print(required) ... print(args) ... print(kwargs) ... >>> func('Welcome to...', *(1, 2, 3), **{'Site': 'CloudAcademy.com'}) Welcome to... (1, 2, 3) {'Site': 'CloudAcademy.com'} Conclusion Iterable unpacking turns out to be a pretty useful and popular feature in Python. This feature allows us to unpack an iterable into several variables. On the other hand, packing consists of catching several values into one variable using the unpacking operator, *. In this tutorial, we've learned how to use iterable unpacking in Python to write more readable, maintainable, and pythonic code. With this knowledge, we are now able to use iterable unpacking in Python to solve common problems like parallel assignment and swapping values between variables. We're also able to use this Python feature in other structures like for loops, function calls, and function definitions. \u62d3\u5c55\uff1aenumerate \u00b6 enumerate() \u51fd\u6570\u7528\u4e8e\u5c06\u4e00\u4e2a\u53ef\u904d\u5386\u7684\u6570\u636e\u5bf9\u8c61(\u5982\u5217\u8868\u3001\u5143\u7ec4\u6216\u5b57\u7b26\u4e32)\u7ec4\u5408\u4e3a\u4e00\u4e2a\u7d22\u5f15\u5e8f\u5217\uff0c\u540c\u65f6\u5217\u51fa\u6570\u636e\u548c\u6570\u636e\u4e0b\u6807\uff0c\u4e00\u822c\u7528\u5728 for \u5faa\u73af\u5f53\u4e2d\u3002 enumerate() \u65b9\u6cd5: \u8bed\u6cd5 enumerate(sequence, [start=0]) \u53c2\u6570 sequence\uff1a\u4e00\u4e2a\u5e8f\u5217\u3001\u8fed\u4ee3\u5668\u6216\u5176\u4ed6\u652f\u6301\u8fed\u4ee3\u5bf9\u8c61\u3002 start\uff1a\u4e0b\u6807\u8d77\u59cb\u4f4d\u7f6e\u3002 \u8fd4\u56de\u503c \u8fd4\u56de enumerate(\u679a\u4e3e) \u5bf9\u8c61\u3002 \u57fa\u672c\u7528\u6cd5\uff1a \u5b57\u7b26\u4e32 >>> sample = 'abcd' >>> for i, j in enumerate(sample): # \u8f93\u51fa\u7684\u662f\u5143\u7ec4\u5185\u7684\u5143\u7d20 ... print(i, j) ... 0 a 1 b 2 c 3 d >>> for i in enumerate(sample): # \u8f93\u51fa\u7684\u662f\u5143\u7ec4 ... print(i) ... (0, 'a') (1, 'b') (2, 'c') (3, 'd') >>> sample = ('abcd') >>> for i, j in enumerate(sample): ... print(i, j) ... 0 a 1 b 2 c 3 d \u5143\u7ec4 >>> sample = ('abcd', 'hijk') >>> for i, j in enumerate(sample): ... print(i, j) ... 0 abcd 1 hijk >>> sample = ('abcd', 'hijk') >>> for i, j in enumerate(sample, 2): ... print(i, j) ... 2 abcd 3 hijk \u6570\u7ec4 >>> sample = ['abcd', 'hijk'] >>> for i, j in enumerate(sample): ... print(i, j) ... 0 abcd 1 hijk \u5b57\u5178 >>> sample = {'abcd': 1, 'hijk': 2} >>> for i, j in enumerate(sample): ... print(i, j) ... 0 abcd 1 hijk","title":"\u7b2c06\u6761 \u628a\u6570\u636e\u7ed3\u6784\u76f4\u63a5\u62c6\u5206\u5230\u591a\u4e2a\u53d8\u91cf\u91cc\uff0c\u4e0d\u8981\u4e13\u95e8\u901a\u8fc7\u4e0b\u6807\u8bbf\u95ee"},{"location":"python/Pythonic90Rules/Rule06/#6","text":"Python\u5185\u7f6e\u7684\u5143\u7ec4\uff08tuple\uff09\u7c7b\u578b\u53ef\u4ee5\u521b\u5efa\u4e0d\u53ef\u53d8\u7684\u5e8f\u5217\uff0c\u628a\u8bb8\u591a\u5143\u7d20\u4f9d\u6b21\u4fdd\u5b58\u8d77\u6765\u3002 \u53ef\u4ee5\u7528\u6574\u6570\u4f5c\u4e0b\u6807\uff0c\u901a\u8fc7\u4e0b\u6807\u6765\u8bbf\u95ee\u5143\u7ec4\u91cc\u9762\u5bf9\u5e94\u7684\u5143\u7d20\u3002\u4f46\u4e0d\u80fd\u901a\u8fc7\u4e0b\u6807\u7ed9\u5143\u7d20\u8d4b\u65b0\u503c\u3002 >>> snack_calories = { ... 'chips': 140, ... 'popcorn': 80, ... 'nuts': 190 ... } >>> items = tuple(snack_calories.items()) >>> type(snack_calories) >>> type(items) >>> snack_calories {'chips': 140, 'popcorn': 80, 'nuts': 190} >>> items (('chips', 140), ('popcorn', 80), ('nuts', 190)) >>> items[2] ('nuts', 190) >>> items[1] = ('apple', 200) Traceback (most recent call last): File \"\", line 1, in TypeError: 'tuple' object does not support item assignment Python\u8fd8\u6709\u4e00\u79cd\u5199\u6cd5\uff0c\u53eb\u4f5c\u62c6\u5206\uff08unpacking\uff09\u3002\u8fd9\u79cd\u5199\u6cd5\u8ba9\u6211\u4eec\u53ea\u7528\u4e00\u6761\u8bed\u53e5\uff0c\u5c31\u53ef\u4ee5\u628a\u5143\u7ec4\u91cc\u9762\u7684\u5143\u7d20\u5206\u522b\u8d4b\u7ed9\u591a\u4e2a\u53d8\u91cf\uff0c\u4e0d\u7528\u518d\u901a\u8fc7\u4e0b\u6807\u53bb\u8bbf\u95ee\u3002 \u5143\u7ec4\u7684\u5143\u7d20\u672c\u8eab\u4e0d\u80fd\u4fee\u6539\uff0c\u4f46\u662f\u90a3\u4e9b\u88ab\u8d4b\u503c\u7684\u53d8\u91cf\u662f\u53ef\u4ee5\u4fee\u6539\u7684\u3002 \u901a\u8fc7unpacking\u6765\u8d4b\u503c\u8981\u6bd4\u901a\u8fc7\u4e0b\u6807\u53bb\u8bbf\u95ee\u5143\u7ec4\u5185\u7684\u5143\u7d20\u66f4\u6e05\u6670\uff0c\u800c\u4e14\u8fd9\u79cd\u5199\u6cd5\u6240\u9700\u7684\u4ee3\u7801\u91cf\u901a\u5e38\u6bd4\u8f83\u5c11\u3002\u5f53\u7136\uff0c\u8d4b\u503c\u64cd\u4f5c\u7684\u5de6\u8fb9\u9664\u4e86\u53ef\u4ee5\u7f57\u5217\u5355\u4e2a\u53d8\u91cf\uff0c\u4e5f\u53ef\u4ee5\u5199\u6210\u5217\u8868\u3001\u5e8f\u5217\u6216\u4efb\u610f\u6df1\u5ea6\u7684\u53ef\u8fed\u4ee3\u5bf9\u8c61\uff08iterable\uff09\u3002 >>> favorite_snacks = { ... 'salty': ('pretzels', 100), ... 'sweet': ('cookies', 280), ... 'veggie': ('carrots', 20) ... } >>> ( ... (type1, (name1, cals1)), ... (type2, (name2, cals2)), ... (type3, (name3, cals3)), ... ) = favorite_snacks.items() >>> print(f'Favorite {type1} is {name1} with {cals1} calories') Favorite salty is pretzels with 100 calories >>> print(f'Favorite {type2} is {name2} with {cals2} calories') Favorite sweet is cookies with 280 calories >>> print(f'Favorite {type3} is {name3} with {cals3} calories') Favorite veggie is carrots with 20 calories \u53ef\u4ee5\u901a\u8fc7unpacking\u539f\u5730\u4ea4\u6362\u4e24\u4e2a\u53d8\u91cf\uff0c\u800c\u4e0d\u7528\u4e13\u95e8\u521b\u5efa\u4e34\u65f6\u53d8\u91cf\u3002 >>> def bubble_sort(a): ... for _ in range(len(a)): ... for i in range(1, len(a)): ... if a[i] < a[i - 1]: ... temp = a[i] ... a[i] = a[i - 1] ... a[i - 1] = temp ... >>> names = ['pretzels', 'carrots', 'arugula', 'bacon'] >>> bubble_sort(names) >>> names ['arugula', 'bacon', 'carrots', 'pretzels'] >>> def bubble_sort(a): ... for _ in range(len(a)): ... for i in range(1, len(a)): ... if a[i] < a[i - 1]: ... a[i], a[i - 1] = a[i - 1], a[i] ... >>> names = ['pretzels', 'carrots', 'arugula', 'bacon'] >>> bubble_sort(names) >>> names ['arugula', 'bacon', 'carrots', 'pretzels'] \u539f\u7406\u5206\u6790\uff1a Python\u5904\u7406\u8d4b\u503c\u64cd\u4f5c\u7684\u65f6\u5019\uff0c\u8981\u5148\u5bf9=\u53f7\u53f3\u4fa7\u6c42\u503c\uff0c\u4e8e\u662f\uff0c\u5b83\u4f1a\u65b0\u5efa\u4e00\u4e2a\u4e34\u65f6\u7684\u5143\u7ec4\uff0c\u628a a[i] \u4e0e a[i-1] \u8fd9\u4e24\u4e2a\u5143\u7d20\u653e\u5230\u8fd9\u4e2a\u5143\u7ec4\u91cc\u9762\u3002\u4f8b\u5982\uff0c\u7b2c\u4e00\u6b21\u8fdb\u5165\u5185\u90e8\u7684for\u5faa\u73af\u65f6\uff0c\u8fd9\u4e24\u4e2a\u5143\u7d20\u5206\u522b\u662f 'carrots' \u4e0e 'pretzels '\uff0c\u4e8e\u662f\uff0c\u7cfb\u7edf\u5c31\u4f1a\u521b\u5efa\u51fa ('carrots','pretzels') \u8fd9\u6837\u4e00\u4e2a\u4e34\u65f6\u7684\u5143\u7ec4\u3002 \u7136\u540e\uff0cPython\u4f1a\u5bf9\u8fd9\u4e2a\u4e34\u65f6\u7684\u5143\u7ec4\u505aunpacking\uff0c\u628a\u5b83\u91cc\u9762\u7684\u4e24\u4e2a\u5143\u7d20\u5206\u522b\u653e\u5230=\u53f7\u5de6\u4fa7\u7684\u90a3\u4e24\u4e2a\u5730\u65b9\uff0c\u4e8e\u662f\uff0c 'carrots' \u5c31\u4f1a\u628a a[i-1] \u91cc\u9762\u539f\u6709\u7684 'pretzels' \u6362\u6389\uff0c 'pretzels' \u4e5f\u4f1a\u628a a[i] \u91cc\u9762\u539f\u6709\u7684 'carrots' \u6362\u6389\u3002 \u73b0\u5728\uff0c\u51fa\u73b0\u5728 a[0] \u8fd9\u4e2a\u4f4d\u7f6e\u4e0a\u9762\u7684\u5b57\u7b26\u4e32\u5c31\u662f 'carrots' \u4e86\uff0c\u51fa\u73b0\u5728 a[1] \u8fd9\u4e2a\u4f4d\u7f6e\u4e0a\u9762\u7684\u5b57\u7b26\u4e32\u5219\u662f 'pretzels' \u3002 \u505a\u5b8cunpacking\u540e\uff0c\u7cfb\u7edf\u4f1a\u6254\u6389\u8fd9\u4e2a\u4e34\u65f6\u7684\u5143\u7ec4\u3002 unpacking\u673a\u5236\u8fd8\u6709\u4e00\u4e2a\u7279\u522b\u91cd\u8981\u7684\u7528\u6cd5\uff0c\u5c31\u662f\u53ef\u4ee5\u5728for\u5faa\u73af\u6216\u8005\u7c7b\u4f3c\u7684\u7ed3\u6784\u91cc\u9762\uff0c\u628a\u590d\u6742\u7684\u6570\u636e\u62c6\u5206\u5230\u76f8\u5173\u7684\u53d8\u91cf\u4e4b\u4e2d\u3002 >>> snacks = [('bacon', 350), ('donut', 240), ('muffin', 190)] >>> for i in range(len(snacks)): ... item = snacks[i] ... name = item[0] ... calories = item[1] ... print(f'#{i+1}: {name} has {calories} calories') ... #1: bacon has 350 calories #2: donut has 240 calories #3: muffin has 190 calories \u4e0a\u9762\u8fd9\u6bb5\u4ee3\u7801\u867d\u7136\u6ca1\u9519\uff0c\u4f46\u770b\u8d77\u6765\u5f88\u4e71\uff0c\u56e0\u4e3asnacks\u7ed3\u6784\u672c\u8eab\u5e76\u4e0d\u662f\u4e00\u4efd\u7b80\u5355\u7684\u5217\u8868\uff0c\u5b83\u7684\u6bcf\u4e2a\u5143\u7d20\u90fd\u662f\u4e00\u4e2a\u5143\u7ec4\uff0c \u6240\u4ee5\u5fc5\u987b\u9010\u5c42\u8bbf\u95ee\u624d\u80fd\u67e5\u5230\u6700\u4e3a\u5177\u4f53\u7684\u6570\u636e\uff0c\u4e5f\u5c31\u662f\u6bcf\u79cd\u96f6\u98df\u7684\u540d\u79f0\uff08name\uff09\u53ca\u5361\u8def\u91cc\uff08calories\uff09\u3002 \u4e0b\u9762\u6362\u4e00\u79cd\u5199\u6cd5\uff0c\u9996\u5148\u8c03\u7528\u5185\u7f6e\u7684enumerate\u51fd\u6570\uff08\u53c2\u89c1\u7b2c7\u6761\uff09\u83b7\u5f97\u5f53\u524d\u8981\u8fed\u4ee3\u7684\u5143\u7ec4\uff0c \u7136\u540e\u9488\u5bf9\u8fd9\u4e2a\u5143\u7ec4\u505aunpacking\uff0c\u8fd9\u6837\u5c31\u53ef\u4ee5\u76f4\u63a5\u5f97\u5230\u5177\u4f53\u7684name\u4e0ecalories\u503c\u4e86\u3002 \u8fd9\u624d\u662f\u7b26\u5408Python\u98ce\u683c\u7684\u5199\u6cd5\uff08Pythonic\u5f0f\u7684\u5199\u6cd5\uff09\u3002 >>> for rank, (name, calories) in enumerate(snacks, 1): ... print(f'#{rank}: {name} has {calories} calories') ... #1: bacon has 350 calories #2: donut has 240 calories #3: muffin has 190 calories Python\u7684unpacking\u673a\u5236\u53ef\u4ee5\u7528\u5728\u8bb8\u591a\u65b9\u9762\uff0c\u4f8b\u5982\u6784\u5efa\u5217\u8868\uff08Rule13\uff09\u3001\u7ed9\u51fd\u6570\u8bbe\u8ba1\u53c2\u6570\u5217\u8868\uff08Rule22\uff09\u3001\u4f20\u9012\u5173\u952e\u5b57\u53c2\u6570\uff08Rule23\uff09\u3001\u63a5\u6536\u591a\u4e2a\u8fd4\u56de\u503c\uff08Rule19\u6761\uff09\u7b49\u3002 \u8981\u70b9\uff1a unpacking\u662f\u4e00\u79cd\u7279\u6b8a\u7684Python\u8bed\u6cd5\uff0c\u53ea\u9700\u8981\u4e00\u884c\u4ee3\u7801\uff0c\u5c31\u80fd\u628a\u6570\u636e\u7ed3\u6784\u91cc\u9762\u7684\u591a\u4e2a\u503c\u5206\u522b\u8d4b\u7ed9\u76f8\u5e94\u7684\u53d8\u91cf\u3002 unpacking\u5728Python\u4e2d\u5e94\u7528\u5e7f\u6cdb\uff0c\u51e1\u662f\u53ef\u8fed\u4ee3\u7684\u5bf9\u8c61\u90fd\u80fd\u62c6\u5206\uff0c\u65e0\u8bba\u5b83\u91cc\u9762\u8fd8\u6709\u591a\u5c11\u5c42\u8fed\u4ee3\u7ed3\u6784\u3002 \u5c3d\u91cf\u901a\u8fc7unpacking\u6765\u62c6\u89e3\u5e8f\u5217\u4e4b\u4e2d\u7684\u6570\u636e\uff0c\u800c\u4e0d\u8981\u901a\u8fc7\u4e0b\u6807\u8bbf\u95ee\uff0c\u8fd9\u6837\u53ef\u4ee5\u8ba9\u4ee3\u7801\u66f4\u7b80\u6d01\u3001\u66f4\u6e05\u6670\u3002","title":"\u7b2c6\u6761\u3000\u628a\u6570\u636e\u7ed3\u6784\u76f4\u63a5\u62c6\u5206\u5230\u591a\u4e2a\u53d8\u91cf\u91cc\uff0c\u4e0d\u8981\u4e13\u95e8\u901a\u8fc7\u4e0b\u6807\u8bbf\u95ee"},{"location":"python/Pythonic90Rules/Rule06/#packing-and-unpacking-in-python","text":"Python allows a tuple (or list) of variables to appear on the left side of an assignment operation. Each variable in the tuple can receive one value (or more, if we use the * operator) from an iterable on the right side of the assignment. Unpacking in Python refers to an operation that consists of assigning an iterable of values to a tuple (or list) of variables in a single assignment statement. In Python, we can put a tuple of variables on the left side of an assignment operator (=) and a tuple of values on the right side. The values on the right will be automatically assigned to the variables on the left according to their position in the tuple. This is commonly known as tuple unpacking in Python. Check out the following example: >>> (a, b, c) = (1, 2, 3) >>> a 1 >>> b 2 >>> c 3 >>> birthday = ('April', 5, 2001) >>> month, day, year = birthday >>> month 'April' >>> day 5 >>> year 2001 The tuple unpacking feature got so popular among Python developers that the syntax was extended to work with any iterable object. The only requirement is that the iterable yields exactly one item per variable in the receiving tuple ( or list). Check out the following examples of how iterable unpacking works in Python: >>> # Unpackage strings >>> a, b, c = '123' >>> a '1' >>> b '2' >>> c '3' >>> # Unpackaging strings >>> a, b, c = '123' >>> a '1' >>> b '2' >>> c '3' >>> # Unpacking lists >>> a, b, c = [1, 2, 3] >>> a 1 >>> b 2 >>> c 3 >>> # Unpacking generators >>> gen = (i ** 2 for i in range(3)) >>> a, b, c = gen >>> a 0 >>> b 1 >>> c 4 >>> # Upacking dictionaries (keys, values, and items) >>> my_dict = {'one': 1, 'two': 2, 'three': 3} >>> a, b, c = my_dict >>> a 'one' >>> b 'two' >>> c 'three' >>> a, b, c = my_dict.values() >>> a 1 >>> b 2 >>> c 3 >>> a, b, c = my_dict.items() >>> a ('one', 1) >>> b ('two', 2) >>> c ('three', 3) >>> # Use a tuple on the right side of assignment statement >>> [a, b, c] = 1, 2, 3 >>> a 1 >>> b 2 >>> c 3 >>> # Use range() iterator >>> x, y, z = range(3) >>> x 0 >>> y 1 >>> z 2 As a complement, the term packing can be used when we collect several values in a single variable using the iterable unpacking operator. The * operator is known, in this context, as the tuple (or iterable) unpacking operator. It extends the unpacking functionality to allow us to collect or pack multiple values in a single variable. In the following example, we pack a tuple of values into a single variable by using the * operator: >>> *a, = 1, 2 >>> a [1, 2] For this code to work, the left side of the assignment must be a tuple (or a list). That's why we use a trailing comma. This tuple can contain as many variables as we need. However, it can only contain one starred expression. >>> # Packing trailing values >>> a, *b = 1, 2, 3 >>> a 1 >>> b [2, 3] >>> *a, b, c = 1, 2, 3 >>> a [1] >>> b 2 >>> c 3 >>> *a, b, c, d, e = 1, 2, 3 Traceback (most recent call last): File \"\", line 1, in ValueError: not enough values to unpack (expected at least 4, got 3) >>> *a, b, c, d = 1, 2, 3 >>> a [] >>> b 1 >>> c 2 >>> d 3 >>> >>> seq = [1, 2, 3, 4] >>> first, *body, last = seq >>> first, body, last (1, [2, 3], 4) >>> first, body, *last = seq >>> first, body, last (1, 2, [3, 4]) >>> ran = range(10) >>> *r, = ran >>> r [0, 1, 2, 3, 4, 5, 6, 7, 8, 9] Using Packing and Unpacking in Practice >>> employee = ['John Doe', '40', 'Software Engineer'] >>> name = employee[0] >>> age = employee[1] >>> job = employee[2] >>> name 'John Doe' >>> age '40' >>> job 'Software Engineer' >>> >>> name, age, job = ['John Doe', '40', 'Software Engineer'] >>> name 'John Doe' >>> age '40' >>> job 'Software Engineer' >>> >>> a = 100 >>> b = 200 >>> a, b = b, a >>> a 200 >>> b 100 Dropping Unneeded Values With * >>> a, b, *_ = 1, 2, 0, 0, 0, 0 >>> a 1 >>> b 2 >>> _ [0, 0, 0, 0] The rest of the information is stored in the dummy variable _, which can be ignored by our program. By default, the underscore character _ is used by the Python interpreter to store the resulting value of the statements we run in an interactive session. So, in this context, the use of this character to identify dummy variables can be ambiguous. Returning Tuples in Functions >>> def powers(num): ... return num, num ** 2, num ** 3 ... >>> # Packaging returned values in a tuple >>> result = powers(3) >>> result (3, 9, 27) >>> # Unpacking returned values to multiple variables >>> number, square, cube = powers(3) >>> number 3 >>> square 9 >>> cube 27 >>> *_, cube = powers(3) >>> cube 27 Merging Iterables With the * Operator The last two examples show that this is also a more readable and efficient way to concatenate iterables. Instead of writing list(my_set) + my_list + list(my_tuple) + list(range(1, 4)) + list(my_str) we just write [*my_set, *my_list, *my_tuple, *range(1, 4), *my_str] . >>> my_tuple = (1, 2, 3) >>> (0, *my_tuple, 4) (0, 1, 2, 3, 4) >>> my_list = [1, 2, 3] >>> [0, *my_list, 4] [0, 1, 2, 3, 4] >>> my_set = {1, 2, 3} >>> {0, *my_set, 4} {0, 1, 2, 3, 4} >>> [*my_set, *my_list, *my_tuple, *range(1, 4)] [1, 2, 3, 1, 2, 3, 1, 2, 3, 1, 2, 3] >>> my_str = \"123\" >>> [*my_set, *my_list, *my_tuple, *range(1, 4), *my_str] [1, 2, 3, 1, 2, 3, 1, 2, 3, 1, 2, 3, '1', '2', '3'] Unpacking Dictionaries With the ** Operator >>> numbers = {'one': 1, 'two': 2, 'three': 3} >>> letters = {'a': 'A', 'b': 'B', 'c': 'C'} >>> combination = {**numbers, **letters} >>> combination {'one': 1, 'two': 2, 'three': 3, 'a': 'A', 'b': 'B', 'c': 'C'} An important point to note is that, if the dictionaries we're trying to merge have repeated or common keys, then the values of the right-most dictionary will override the values of the left-most dictionary. Here's an example: >>> letters = {'a': 'A', 'b': 'B', 'c': 'C'} >>> vowels = {'a': 'a', 'e': 'e', 'i': 'i', 'o': 'o', 'u': 'u'} >>> {**letters, **vowels} {'a': 'a', 'b': 'B', 'c': 'C', 'e': 'e', 'i': 'i', 'o': 'o', 'u': 'u'} >>> {**vowels, **letters} {'a': 'A', 'e': 'e', 'i': 'i', 'o': 'o', 'u': 'u', 'b': 'B', 'c': 'C'} Unpacking in For-Loops We can also use iterable unpacking in the context of for loops. When we run a for loop, the loop assigns one item of its iterable to the target variable in every iteration. If the item to be assigned is an iterable, then we can use a tuple of target variables. The loop will unpack the iterable at hand into the tuple of target variables. We can build a list of two-elements tuples. Each tuple will contain the name of the product, the price, and the sold units. With this information, we want to calculate the income of each product. To do this, we can use a for loop like this: >>> sales = [('Pencle', 0.22, 1500), ('Notebook', 1.30, 550), ('Eraser', 0.75, 1000)] >>> for items in sales: ... print(f\"Income for {item[0]} is: {item[1] * item[2]}\") ... Traceback (most recent call last): File \"\", line 2, in NameError: name 'item' is not defined >>> for items in sales: ... print(f\"Income for {items[0]} is: {items[1] * items[2]}\") ... Income for Pencle is: 330.0 Income for Notebook is: 715.0 Income for Eraser is: 750.0 we're using indices to get access to individual elements of each tuple. This can be difficult to read and to understand by newcomer developers. We're now using iterable unpacking in our for loop in below sample codes, which is an alternative implementation using unpacking in Python: >>> sales = [('Pencle', 0.22, 1500), ('Notebook', 1.30, 550), ('Eraser', 0.75, 1000)] >>> for product, price, sold_units in sales: ... print(f\"Income for {product} is: {price * sold_units}\") ... Income for Pencle is: 330.0 Income for Notebook is: 715.0 Income for Eraser is: 750.0 It's also possible to use the * operator in a for loop to pack several items in a single target variable. In this for loop, we're catching the first element of each sequence in first. Then the * operator catches a list of values in its target variable rest. >>> for first, *rest in [(1, 2, 3),(4, 5, 6)]: ... print('First: ', first) ... print('Rest: ', rest) ... First: 1 Rest: [2, 3] First: 4 Rest: [5, 6] >>> Finally, the structure of the target variables must agree with the structure of the iterable. Otherwise, we'll get an error. Take a look at the following example: >>> data = [((1, 2), 3), ((2, 3), 3)] >>> for (a, b), c in data: ... print(a, b, c) ... 1 2 3 2 3 3 >>> for a, b, c in data: ... print(a, b, c) ... Traceback (most recent call last): File \"\", line 1, in ValueError: not enough values to unpack (expected 3, got 2) Defining Functions With * and ** The below function requires at least one argument called required . It can accept a variable number of positional and keyword arguments as well. In this case, the * operator collects or packs extra positional arguments in a tuple called args and the ** operator collects or packs extra keyword arguments in a dictionary called kwargs . Both, args and kwargs , are optional and automatically default to () and {} respectively. Even though the names args and kwargs are widely used by the Python community, they're not a requirement for these techniques to work. The syntax just requires * or ** followed by a valid identifier. So, if you can give meaningful names to these arguments, then do it. That will certainly improve your code's readability. >>> def func(required, *args, **kwargs): ... print(required) ... print(args) ... print(kwargs) ... >>> func('Welcome to ...', 1, 2, 3, site='CloudAcademy.com') Welcome to ... (1, 2, 3) {'site': 'CloudAcademy.com'} >>> func('Welcome to ...', 1, 2, 3, 4) Welcome to ... (1, 2, 3, 4) {} >>> func('Welcome to ...', 1, 2, 3, (1, 2)) Welcome to ... (1, 2, 3, (1, 2)) {} >>> func('Welcome to ...', 1, 2, 3, [1, 2]) Welcome to ... (1, 2, 3, [1, 2]) {} >>> func('Welcome to ...', 1, 2, 3, ([2, 3], [1, 2])) Welcome to ... (1, 2, 3, ([2, 3], [1, 2])) {} Calling Functions With * and ** When calling functions, we can also benefit from the use of the * and ** operator to unpack collections of arguments into separate positional or keyword arguments respectively. This is the inverse of using * and ** in the signature of a function. In the signature, the operators mean collect or pack a variable number of arguments in one identifier. In the call, they mean unpack an iterable into several arguments. Here's a basic example of how this works. The * operator unpacks sequences like [\"Welcome\", \"to\"] into positional arguments. Similarly, the ** operator unpacks dictionaries into arguments whose names match the keys of the unpacked dictionary. >>> def func(welcome, to, site): ... print(welcome, to, site ... ... ) ... >>> def func(welcome, to, site): ... print(welcome, to, site) ... >>> func(*['Welcome', 'to'], **{'site': 'CloudAcademy.com'}) Welcome to CloudAcademy.com We can also combine this technique and the one covered in the previous section to write quite flexible functions. The use of the * and ** operators, when defining and calling Python functions, will give them extra capabilities and make them more flexible and powerful. Here's an example: >>> def func(required, *args, **kwargs): ... print(required) ... print(args) ... print(kwargs) ... >>> func('Welcome to...', *(1, 2, 3), **{'Site': 'CloudAcademy.com'}) Welcome to... (1, 2, 3) {'Site': 'CloudAcademy.com'} Conclusion Iterable unpacking turns out to be a pretty useful and popular feature in Python. This feature allows us to unpack an iterable into several variables. On the other hand, packing consists of catching several values into one variable using the unpacking operator, *. In this tutorial, we've learned how to use iterable unpacking in Python to write more readable, maintainable, and pythonic code. With this knowledge, we are now able to use iterable unpacking in Python to solve common problems like parallel assignment and swapping values between variables. We're also able to use this Python feature in other structures like for loops, function calls, and function definitions.","title":"\u62d3\u5c55\uff1aPacking and Unpacking in Python"},{"location":"python/Pythonic90Rules/Rule06/#enumerate","text":"enumerate() \u51fd\u6570\u7528\u4e8e\u5c06\u4e00\u4e2a\u53ef\u904d\u5386\u7684\u6570\u636e\u5bf9\u8c61(\u5982\u5217\u8868\u3001\u5143\u7ec4\u6216\u5b57\u7b26\u4e32)\u7ec4\u5408\u4e3a\u4e00\u4e2a\u7d22\u5f15\u5e8f\u5217\uff0c\u540c\u65f6\u5217\u51fa\u6570\u636e\u548c\u6570\u636e\u4e0b\u6807\uff0c\u4e00\u822c\u7528\u5728 for \u5faa\u73af\u5f53\u4e2d\u3002 enumerate() \u65b9\u6cd5: \u8bed\u6cd5 enumerate(sequence, [start=0]) \u53c2\u6570 sequence\uff1a\u4e00\u4e2a\u5e8f\u5217\u3001\u8fed\u4ee3\u5668\u6216\u5176\u4ed6\u652f\u6301\u8fed\u4ee3\u5bf9\u8c61\u3002 start\uff1a\u4e0b\u6807\u8d77\u59cb\u4f4d\u7f6e\u3002 \u8fd4\u56de\u503c \u8fd4\u56de enumerate(\u679a\u4e3e) \u5bf9\u8c61\u3002 \u57fa\u672c\u7528\u6cd5\uff1a \u5b57\u7b26\u4e32 >>> sample = 'abcd' >>> for i, j in enumerate(sample): # \u8f93\u51fa\u7684\u662f\u5143\u7ec4\u5185\u7684\u5143\u7d20 ... print(i, j) ... 0 a 1 b 2 c 3 d >>> for i in enumerate(sample): # \u8f93\u51fa\u7684\u662f\u5143\u7ec4 ... print(i) ... (0, 'a') (1, 'b') (2, 'c') (3, 'd') >>> sample = ('abcd') >>> for i, j in enumerate(sample): ... print(i, j) ... 0 a 1 b 2 c 3 d \u5143\u7ec4 >>> sample = ('abcd', 'hijk') >>> for i, j in enumerate(sample): ... print(i, j) ... 0 abcd 1 hijk >>> sample = ('abcd', 'hijk') >>> for i, j in enumerate(sample, 2): ... print(i, j) ... 2 abcd 3 hijk \u6570\u7ec4 >>> sample = ['abcd', 'hijk'] >>> for i, j in enumerate(sample): ... print(i, j) ... 0 abcd 1 hijk \u5b57\u5178 >>> sample = {'abcd': 1, 'hijk': 2} >>> for i, j in enumerate(sample): ... print(i, j) ... 0 abcd 1 hijk","title":"\u62d3\u5c55\uff1aenumerate"},{"location":"python/Pythonic90Rules/Rule07/","text":"\u7b2c7\u6761\u3000\u5c3d\u91cf\u7528enumerate\u53d6\u4ee3range \u00b6 Python\u5185\u7f6e\u7684range\u51fd\u6570\u9002\u5408\u7528\u6765\u8fed\u4ee3\u4e00\u7cfb\u5217\u6574\u6570\u3002 >>> from random import randint >>> random_bits = 0 >>> for i in range(32): ... if randint(0, 1): ... random_bits |= 1 << i # \u8fd0\u7b97\u7b26|\u662f\u4e8c\u8fdb\u5236OR\u64cd\u4f5c ... >>> print(bin(random_bits)) 0b110110000110100101001011010 \u5982\u679c\u8981\u8fed\u4ee3\u7684\u662f\u67d0\u79cd\u6570\u636e\u7ed3\u6784\uff0c\u4f8b\u5982\u5b57\u7b26\u4e32\u5217\u8868\uff0c\u90a3\u4e48\u53ef\u4ee5\u76f4\u63a5\u5728\u8fd9\u4e2a\u5e8f\u5217\u4e0a\u9762\u8fed\u4ee3\uff0c\u4e0d\u9700\u8981\u901a\u8fc7range\u3002 >>> flavor_list\u7b2c8\u6761\u3000\u7528zip\u51fd\u6570\u540c\u65f6\u904d\u5386\u4e24\u4e2a\u8fed\u4ee3\u5668 = ['vanilla', 'chocolate', 'pecan', 'strawberry'] >>> for flavor in flavor_list: ... print(f'{flavor} is delicious') ... vanilla is delicious chocolate is delicious pecan is delicious strawberry is delicious \u901a\u8fc7\u4f20\u7edf\u7684range\u65b9\u6cd5\uff0c\u7ed9\u6bcf\u79cd\u53e3\u5473\u6dfb\u52a0\u5e8f\u5217\u53f7\u3002\u4f46\u6b65\u9aa4\u6709\u4e9b\u592a\u591a\uff0c\u5148\u5f97\u77e5\u9053\u5217\u8868\u7684\u957f\u5ea6\uff0c\u7136\u540e\u8981\u6839\u636e\u5217\u8868\u957f\u5ea6\u6784\u9020\u53d6\u503c\u8303\u56f4\uff0c\u7528\u5176\u4e2d\u7684\u6bcf\u4e2a\u6574\u6570\u505a\u4e0b\u6807\uff0c\u5206\u522b\u8bbf\u95ee\u5217\u8868\u91cc\u7684\u5bf9\u5e94\u5143\u7d20\u3002 >>> for i in range(len(flavor_list)): ... flavor = flavor_list[i] ... print(f'{i + 1}: {flavor}') ... 1: vanilla 2: chocolate 3: pecan 4: strawberry Python\u7684\u5185\u7f6e\u7684\u51fd\u6570enumerate\uff0c\u80fd\u591f\u628a\u4efb\u4f55\u4e00\u79cd\u8fed\u4ee3\u5668\uff08iterator\uff09\u5c01\u88c5\u6210\u60f0\u6027\u751f\u6210\u5668\uff08lazy generator\uff0c\u53c2\u89c1Rule30\uff09\u3002 \u8fd9\u6837\u6bcf\u6b21\u5faa\u73af\u7684\u65f6\u5019\uff0c\u5b83\u53ea\u9700\u8981\u4eceiterator\u91cc\u9762\u83b7\u53d6\u4e0b\u4e00\u4e2a\u503c\u5c31\u884c\u4e86\uff0c\u540c\u65f6\u8fd8\u4f1a\u7ed9\u51fa\u672c\u8f6e\u5faa\u73af\u7684\u5e8f\u53f7\uff0c\u5373\u751f\u6210\u5668\u6bcf\u6b21\u4ea7\u751f\u7684\u4e00\u5bf9\u8f93\u51fa\u503c\u3002 \u4e0b\u9762\u901a\u8fc7\u5185\u7f6e\u7684next\u51fd\u6570\u624b\u52a8\u63a8\u8fdbenumerate\u6240\u8fd4\u56de\u7684\u8fd9\u4e2aiterator\uff0c\u6765\u6f14\u793aenumerate\u3002 >>> it = enumerate(flavor_list) >>> print(next(it)) (0, 'vanilla') >>> print(next(it)) (1, 'chocolate') >>> print(next(it)) (2, 'pecan') >>> print(next(it)) (3, 'strawberry') >>> print(next(it)) Traceback (most recent call last): File \"\", line 1, in StopIteration enumerate\u8f93\u51fa\u7684\u6bcf\u4e00\u5bf9\u6570\u636e\uff0c\u90fd\u53ef\u4ee5\u62c6\u5206\uff08unpacking\uff09\u5230for\u8bed\u53e5\u7684\u90a3\u4e24\u4e2a\u53d8\u91cf\u91cc\u9762\uff08unpacking\u673a\u5236\u53c2\u89c1Rule06\uff09\uff0c\u8fd9\u6837\u4f1a\u8ba9\u4ee3\u7801\u66f4\u52a0\u6e05\u6670\u3002 >>> for i, flavor in enumerate(flavor_list): ... print(f'{i + 1}: {flavor}') ... 1: vanilla 2: chocolate 3: pecan 4: strawberry >>> for i, flavor in enumerate(flavor_list, 1): ... print(f'{i}: {flavor}') ... 1: vanilla 2: chocolate 3: pecan 4: strawberry \u8981\u70b9\uff1a enumerate\u51fd\u6570\u53ef\u4ee5\u7528\u7b80\u6d01\u7684\u4ee3\u7801\u8fed\u4ee3iterator\uff0c\u800c\u4e14\u53ef\u4ee5\u6307\u51fa\u5f53\u524d\u8fd9\u8f6e\u5faa\u73af\u7684\u5e8f\u53f7\u3002 \u4e0d\u8981\u5148\u901a\u8fc7range\u6307\u5b9a\u4e0b\u6807\u7684\u53d6\u503c\u8303\u56f4\uff0c\u7136\u540e\u7528\u4e0b\u6807\u53bb\u8bbf\u95ee\u5e8f\u5217\uff0c\u800c\u662f\u5e94\u8be5\u76f4\u63a5\u7528enumerate\u51fd\u6570\u8fed\u4ee3\u3002 \u53ef\u4ee5\u901a\u8fc7enumerate\u7684\u7b2c\u4e8c\u4e2a\u53c2\u6570\u6307\u5b9a\u8d77\u59cb\u5e8f\u53f7\uff08\u9ed8\u8ba4\u4e3a0\uff09\u3002","title":"\u7b2c07\u6761 \u5c3d\u91cf\u7528enumerate\u53d6\u4ee3range"},{"location":"python/Pythonic90Rules/Rule07/#7-enumeraterange","text":"Python\u5185\u7f6e\u7684range\u51fd\u6570\u9002\u5408\u7528\u6765\u8fed\u4ee3\u4e00\u7cfb\u5217\u6574\u6570\u3002 >>> from random import randint >>> random_bits = 0 >>> for i in range(32): ... if randint(0, 1): ... random_bits |= 1 << i # \u8fd0\u7b97\u7b26|\u662f\u4e8c\u8fdb\u5236OR\u64cd\u4f5c ... >>> print(bin(random_bits)) 0b110110000110100101001011010 \u5982\u679c\u8981\u8fed\u4ee3\u7684\u662f\u67d0\u79cd\u6570\u636e\u7ed3\u6784\uff0c\u4f8b\u5982\u5b57\u7b26\u4e32\u5217\u8868\uff0c\u90a3\u4e48\u53ef\u4ee5\u76f4\u63a5\u5728\u8fd9\u4e2a\u5e8f\u5217\u4e0a\u9762\u8fed\u4ee3\uff0c\u4e0d\u9700\u8981\u901a\u8fc7range\u3002 >>> flavor_list\u7b2c8\u6761\u3000\u7528zip\u51fd\u6570\u540c\u65f6\u904d\u5386\u4e24\u4e2a\u8fed\u4ee3\u5668 = ['vanilla', 'chocolate', 'pecan', 'strawberry'] >>> for flavor in flavor_list: ... print(f'{flavor} is delicious') ... vanilla is delicious chocolate is delicious pecan is delicious strawberry is delicious \u901a\u8fc7\u4f20\u7edf\u7684range\u65b9\u6cd5\uff0c\u7ed9\u6bcf\u79cd\u53e3\u5473\u6dfb\u52a0\u5e8f\u5217\u53f7\u3002\u4f46\u6b65\u9aa4\u6709\u4e9b\u592a\u591a\uff0c\u5148\u5f97\u77e5\u9053\u5217\u8868\u7684\u957f\u5ea6\uff0c\u7136\u540e\u8981\u6839\u636e\u5217\u8868\u957f\u5ea6\u6784\u9020\u53d6\u503c\u8303\u56f4\uff0c\u7528\u5176\u4e2d\u7684\u6bcf\u4e2a\u6574\u6570\u505a\u4e0b\u6807\uff0c\u5206\u522b\u8bbf\u95ee\u5217\u8868\u91cc\u7684\u5bf9\u5e94\u5143\u7d20\u3002 >>> for i in range(len(flavor_list)): ... flavor = flavor_list[i] ... print(f'{i + 1}: {flavor}') ... 1: vanilla 2: chocolate 3: pecan 4: strawberry Python\u7684\u5185\u7f6e\u7684\u51fd\u6570enumerate\uff0c\u80fd\u591f\u628a\u4efb\u4f55\u4e00\u79cd\u8fed\u4ee3\u5668\uff08iterator\uff09\u5c01\u88c5\u6210\u60f0\u6027\u751f\u6210\u5668\uff08lazy generator\uff0c\u53c2\u89c1Rule30\uff09\u3002 \u8fd9\u6837\u6bcf\u6b21\u5faa\u73af\u7684\u65f6\u5019\uff0c\u5b83\u53ea\u9700\u8981\u4eceiterator\u91cc\u9762\u83b7\u53d6\u4e0b\u4e00\u4e2a\u503c\u5c31\u884c\u4e86\uff0c\u540c\u65f6\u8fd8\u4f1a\u7ed9\u51fa\u672c\u8f6e\u5faa\u73af\u7684\u5e8f\u53f7\uff0c\u5373\u751f\u6210\u5668\u6bcf\u6b21\u4ea7\u751f\u7684\u4e00\u5bf9\u8f93\u51fa\u503c\u3002 \u4e0b\u9762\u901a\u8fc7\u5185\u7f6e\u7684next\u51fd\u6570\u624b\u52a8\u63a8\u8fdbenumerate\u6240\u8fd4\u56de\u7684\u8fd9\u4e2aiterator\uff0c\u6765\u6f14\u793aenumerate\u3002 >>> it = enumerate(flavor_list) >>> print(next(it)) (0, 'vanilla') >>> print(next(it)) (1, 'chocolate') >>> print(next(it)) (2, 'pecan') >>> print(next(it)) (3, 'strawberry') >>> print(next(it)) Traceback (most recent call last): File \"\", line 1, in StopIteration enumerate\u8f93\u51fa\u7684\u6bcf\u4e00\u5bf9\u6570\u636e\uff0c\u90fd\u53ef\u4ee5\u62c6\u5206\uff08unpacking\uff09\u5230for\u8bed\u53e5\u7684\u90a3\u4e24\u4e2a\u53d8\u91cf\u91cc\u9762\uff08unpacking\u673a\u5236\u53c2\u89c1Rule06\uff09\uff0c\u8fd9\u6837\u4f1a\u8ba9\u4ee3\u7801\u66f4\u52a0\u6e05\u6670\u3002 >>> for i, flavor in enumerate(flavor_list): ... print(f'{i + 1}: {flavor}') ... 1: vanilla 2: chocolate 3: pecan 4: strawberry >>> for i, flavor in enumerate(flavor_list, 1): ... print(f'{i}: {flavor}') ... 1: vanilla 2: chocolate 3: pecan 4: strawberry \u8981\u70b9\uff1a enumerate\u51fd\u6570\u53ef\u4ee5\u7528\u7b80\u6d01\u7684\u4ee3\u7801\u8fed\u4ee3iterator\uff0c\u800c\u4e14\u53ef\u4ee5\u6307\u51fa\u5f53\u524d\u8fd9\u8f6e\u5faa\u73af\u7684\u5e8f\u53f7\u3002 \u4e0d\u8981\u5148\u901a\u8fc7range\u6307\u5b9a\u4e0b\u6807\u7684\u53d6\u503c\u8303\u56f4\uff0c\u7136\u540e\u7528\u4e0b\u6807\u53bb\u8bbf\u95ee\u5e8f\u5217\uff0c\u800c\u662f\u5e94\u8be5\u76f4\u63a5\u7528enumerate\u51fd\u6570\u8fed\u4ee3\u3002 \u53ef\u4ee5\u901a\u8fc7enumerate\u7684\u7b2c\u4e8c\u4e2a\u53c2\u6570\u6307\u5b9a\u8d77\u59cb\u5e8f\u53f7\uff08\u9ed8\u8ba4\u4e3a0\uff09\u3002","title":"\u7b2c7\u6761\u3000\u5c3d\u91cf\u7528enumerate\u53d6\u4ee3range"},{"location":"python/Pythonic90Rules/Rule08/","text":"\u7b2c8\u6761\u3000\u7528zip\u51fd\u6570\u540c\u65f6\u904d\u5386\u4e24\u4e2a\u8fed\u4ee3\u5668 \u00b6 \u5199Python\u4ee3\u7801\u65f6\uff0c\u7ecf\u5e38\u4f1a\u6839\u636e\u67d0\u4efd\u5217\u8868\u4e2d\u7684\u5bf9\u8c61\u521b\u5efa\u8bb8\u591a\u4e0e\u8fd9\u4efd\u5217\u8868\u6709\u5173\u7684\u65b0\u5217\u8868\u3002 \u4e0b\u9762\u8fd9\u6837\u7684\u5217\u8868\u63a8\u5bfc\u673a\u5236\uff0c\u53ef\u4ee5\u628a\u8868\u8fbe\u5f0f\u8fd0\u7528\u5230\u6e90\u5217\u8868\u7684\u6bcf\u4e2a\u5143\u7d20\u4e0a\u9762\uff0c\u4ece\u800c\u751f\u6210\u4e00\u4efd\u6d3e\u751f\u5217\u8868\uff08\u53c2\u89c1Rule27\uff09\u3002 >>> names = ['Cecilia', 'Lise', 'Marie'] >>> counts = [len(n) for n in names] >>> counts [7, 4, 5] \u6d3e\u751f\u5217\u8868\u4e2d\u7684\u5143\u7d20\u4e0e\u6e90\u5217\u8868\u4e2d\u5bf9\u5e94\u4f4d\u7f6e\u4e0a\u9762\u7684\u5143\u7d20\u6709\u7740\u4e00\u5b9a\u7684\u5173\u7cfb\u3002\u5982\u679c\u60f3\u540c\u65f6\u904d\u5386\u8fd9\u4e24\u4efd\u5217\u8868\uff0c\u90a3\u53ef\u4ee5\u6839\u636e\u6e90\u5217\u8868\u7684\u957f\u5ea6\u505a\u8fed\u4ee3\u3002 >>> names = ['Cecilia', 'Lise', 'Marie'] >>> longest_name = None >>> max_count = 0 >>> counts = [len(n) for n in names] >>> for i in range(len(names)): ... count = counts[i] ... if count > max_count: ... longest_name = names[i] ... max_count = count ... >>> longest_name 'Cecilia' \u7528enumerate\u6765\u6539\u5199\u4e0a\u9762\u7684\u4ee3\u7801\uff0c\u6539\u5584\u4e0a\u9762\u4ee3\u7801\u4e2d\u590d\u6742\u7684\u5faa\u73af\u5173\u7cfb\u3002 >>> names = ['Cecilia', 'Lise', 'Marie'] >>> longest_name = None >>> max_count = 0 >>> counts = [len(n) for n in names] >>> for i, name in enumerate(names): ... count = counts[i] ... if count > max_count: ... longest_name = name ... max_count = count ... >>> longest_name 'Cecilia' \u7528zip\u6765\u6539\u5199\u4ee3\u7801\uff0c\u4f7f\u4e4b\u66f4\u7b80\u6d01\u3002 zip\u51fd\u6570\u80fd\u628a\u4e24\u4e2a\u6216\u66f4\u591a\u7684iterator\u5c01\u88c5\u6210\u60f0\u6027\u751f\u6210\u5668\uff08lazy generator\uff09\u3002 \u6bcf\u6b21\u5faa\u73af\u65f6\uff0c\u5b83\u4f1a\u5206\u522b\u4ece\u8fd9\u4e9b\u8fed\u4ee3\u5668\u91cc\u83b7\u53d6\u5404\u81ea\u7684\u4e0b\u4e00\u4e2a\u5143\u7d20\uff0c\u5e76\u628a\u8fd9\u4e9b\u503c\u653e\u5728\u4e00\u4e2a\u5143\u7ec4\u91cc\u9762\u3002 zip\u6bcf\u6b21\u53ea\u4ece\u5b83\u5c01\u88c5\u7684\u90a3\u4e9b\u8fed\u4ee3\u5668\u91cc\u9762\u5404\u81ea\u53d6\u51fa\u4e00\u4e2a\u5143\u7d20\uff0c\u6240\u4ee5\u5373\u4fbf\u6e90\u5217\u8868\u5f88\u957f\uff0c\u7a0b\u5e8f\u4e5f\u4e0d\u4f1a\u56e0\u4e3a\u5360\u7528\u5185\u5b58\u8fc7\u591a\u800c\u5d29\u6e83\u3002 \u800c\u8fd9\u4e2a\u5143\u7ec4\u53ef\u4ee5\u62c6\u5206\u5230for\u8bed\u53e5\u91cc\u7684\u90a3\u4e9b\u53d8\u91cf\u4e4b\u4e2d\uff08\u53c2\u89c1Rule06\uff09\u3002 \u8fd9\u6837\u5199\u51fa\u6765\u7684\u4ee3\u7801\uff0c\u6bd4\u901a\u8fc7\u4e0b\u6807\u8bbf\u95ee\u591a\u4e2a\u5217\u8868\u7684\u90a3\u79cd\u4ee3\u7801\u8981\u6e05\u6670\u5f97\u591a\u3002 >>> names = ['Cecilia', 'Lise', 'Marie'] >>> longest_name = None >>> max_count = 0 >>> counts = [len(n) for n in names] >>> for name, count in zip(names, counts): ... if count > max_count: ... longest_name = name ... max_count = count ... >>> longest_name 'Cecilia' \u4f46\u662f\uff0c\u5982\u679c\u8f93\u5165zip\u7684\u90a3\u4e9b\u5217\u8868\u7684\u957f\u5ea6\u4e0d\u4e00\u81f4\uff0c\u7528zip\u540c\u65f6\u904d\u5386\u90a3\u4e9b\u5217\u8868\uff0c\u4f1a\u4ea7\u751f\u5947\u602a\u7684\u7ed3\u679c\u3002 \u4f8b\u5982\uff0c\u6211\u7ed9names\u5217\u8868\u91cc\u53c8\u6dfb\u52a0\u4e86\u4e00\u4e2a\u540d\u5b57\uff0c\u4f46\u662f\u5fd8\u4e86\u628a\u5b83\u7684\u957f\u5ea6\u66f4\u65b0\u5230counts\u5217\u8868\u4e4b\u4e2d\u3002 \u65b0\u6dfb\u52a0\u7684\u90a3\u4e2a'Rosalind' \u5143\u7d20\u4e0d\u4f1a\u88ab\u6253\u5370\u51fa\u6765\uff0c\u56e0\u4e3azip\u51fd\u6570\u5728\u6267\u884c\u4e2d\uff0c\u53ea\u8981\u5176\u4e2d\u4efb\u4f55\u4e00\u4e2a\u8fed\u4ee3\u5668\u5904\u7406\u5b8c\u6bd5\uff0c\u5b83\u5c31\u4e0d\u518d\u5f80\u4e0b\u8d70\u4e86\u3002 \u4e8e\u662f\uff0c\u5faa\u73af\u7684\u6b21\u6570\u5b9e\u9645\u4e0a\u7b49\u4e8e\u6700\u77ed\u7684\u90a3\u4efd\u5217\u8868\u6240\u5177\u5907\u7684\u957f\u5ea6\u3002 \u4e00\u822c\u60c5\u51b5\u4e0b\uff0c\u6211\u4eec\u90fd\u662f\u6839\u636e\u67d0\u4efd\u5217\u8868\u63a8\u5bfc\u51fa\u5176\u4ed6\u51e0\u4efd\u5217\u8868\uff0c\u7136\u540e\u628a\u8fd9\u4e9b\u5217\u8868\u4e00\u8d77\u5c01\u88c5\u5230zip\u91cc\u9762\uff0c\u5e76\u4fdd\u8bc1\u8fd9\u4e9b\u5217\u8868\u957f\u5ea6\u76f8\u540c\u3002 >>> names.append('Rosalind') >>> names ['Cecilia', 'Lise', 'Marie', 'Rosalind'] >>> for name, count in zip(names, counts): ... print(name) ... Cecilia Lise Marie \u5728\u5217\u8868\u957f\u5ea6\u4e0d\u540c\u7684\u60c5\u51b5\u4e0b\uff0c\u5982\u679c\u65e0\u6cd5\u786e\u5b9a\u8fd9\u4e9b\u5217\u8868\u7684\u957f\u5ea6\u76f8\u540c\uff0c\u90a3\u5c31\u4e0d\u8981\u628a\u5b83\u4eec\u4f20\u7ed9zip\uff0c\u800c\u662f\u5e94\u8be5\u4f20\u7ed9\u53e6\u4e00\u4e2a\u53eb\u4f5czip_longest\u7684\u51fd\u6570\uff0c\u8fd9\u4e2a\u51fd\u6570\u4f4d\u4e8e\u5185\u7f6e\u7684itertools\u6a21\u5757\u91cc\u3002 \u5982\u679c\u5176\u4e2d\u6709\u4e9b\u5217\u8868\u5df2\u7ecf\u904d\u5386\u5b8c\u4e86\uff0c\u90a3\u4e48zip_longest\u4f1a\u7528\u5f53\u521d\u4f20\u7ed9fillvalue\u53c2\u6570\u7684\u90a3\u4e2a\u503c\u6765\u586b\u8865\u7a7a\u7f3a\uff08\u672c\u4f8b\u4e2d\u7a7a\u7f3a\u7684\u4e3a\u5b57\u7b26\u4e32'Rosalind'\u7684\u957f\u5ea6\u503c\uff09\uff0c\u9ed8\u8ba4\u7684\u53c2\u6570\u503c\u662fNone\u3002 >>> import itertools >>> names = ['Cecilia', 'Lise', 'Marie'] >>> longest_name = None >>> max_count = 0 >>> counts = [len(n) for n in names] >>> names.append('Rosalind') >>> names ['Cecilia', 'Lise', 'Marie', 'Rosalind'] >>> counts [7, 4, 5] >>> for name, count in itertools.zip_longest(names, counts): ... print(f'{name}: {count}') ... Cecilia: 7 Lise: 4 Marie: 5 Rosalind: None \u8981\u70b9\uff1a \u5185\u7f6e\u7684zip\u51fd\u6570\u53ef\u4ee5\u540c\u65f6\u904d\u5386\u591a\u4e2a\u8fed\u4ee3\u5668\u3002 zip\u4f1a\u521b\u5efa\u60f0\u6027\u751f\u6210\u5668\uff0c\u8ba9\u5b83\u6bcf\u6b21\u53ea\u751f\u6210\u4e00\u4e2a\u5143\u7ec4\uff0c\u6240\u4ee5\u65e0\u8bba\u8f93\u5165\u7684\u6570\u636e\u6709\u591a\u957f\uff0c\u5b83\u90fd\u662f\u4e00\u4e2a\u4e00\u4e2a\u5904\u7406\u7684\u3002 \u5982\u679c\u63d0\u4f9b\u7684\u8fed\u4ee3\u5668\u7684\u957f\u5ea6\u4e0d\u4e00\u81f4\uff0c\u90a3\u4e48\u53ea\u8981\u5176\u4e2d\u4efb\u4f55\u4e00\u4e2a\u8fed\u4ee3\u5b8c\u6bd5\uff0czip\u5c31\u4f1a\u505c\u6b62\u3002 \u5982\u679c\u60f3\u6309\u6700\u957f\u7684\u90a3\u4e2a\u8fed\u4ee3\u5668\u6765\u904d\u5386\uff0c\u90a3\u5c31\u6539\u7528\u5185\u7f6e\u7684itertools\u6a21\u5757\u4e2d\u7684zip_longest\u51fd\u6570\u3002","title":"\u7b2c08\u6761 \u7528zip\u51fd\u6570\u540c\u65f6\u904d\u5386\u4e24\u4e2a\u8fed\u4ee3\u5668"},{"location":"python/Pythonic90Rules/Rule08/#8-zip","text":"\u5199Python\u4ee3\u7801\u65f6\uff0c\u7ecf\u5e38\u4f1a\u6839\u636e\u67d0\u4efd\u5217\u8868\u4e2d\u7684\u5bf9\u8c61\u521b\u5efa\u8bb8\u591a\u4e0e\u8fd9\u4efd\u5217\u8868\u6709\u5173\u7684\u65b0\u5217\u8868\u3002 \u4e0b\u9762\u8fd9\u6837\u7684\u5217\u8868\u63a8\u5bfc\u673a\u5236\uff0c\u53ef\u4ee5\u628a\u8868\u8fbe\u5f0f\u8fd0\u7528\u5230\u6e90\u5217\u8868\u7684\u6bcf\u4e2a\u5143\u7d20\u4e0a\u9762\uff0c\u4ece\u800c\u751f\u6210\u4e00\u4efd\u6d3e\u751f\u5217\u8868\uff08\u53c2\u89c1Rule27\uff09\u3002 >>> names = ['Cecilia', 'Lise', 'Marie'] >>> counts = [len(n) for n in names] >>> counts [7, 4, 5] \u6d3e\u751f\u5217\u8868\u4e2d\u7684\u5143\u7d20\u4e0e\u6e90\u5217\u8868\u4e2d\u5bf9\u5e94\u4f4d\u7f6e\u4e0a\u9762\u7684\u5143\u7d20\u6709\u7740\u4e00\u5b9a\u7684\u5173\u7cfb\u3002\u5982\u679c\u60f3\u540c\u65f6\u904d\u5386\u8fd9\u4e24\u4efd\u5217\u8868\uff0c\u90a3\u53ef\u4ee5\u6839\u636e\u6e90\u5217\u8868\u7684\u957f\u5ea6\u505a\u8fed\u4ee3\u3002 >>> names = ['Cecilia', 'Lise', 'Marie'] >>> longest_name = None >>> max_count = 0 >>> counts = [len(n) for n in names] >>> for i in range(len(names)): ... count = counts[i] ... if count > max_count: ... longest_name = names[i] ... max_count = count ... >>> longest_name 'Cecilia' \u7528enumerate\u6765\u6539\u5199\u4e0a\u9762\u7684\u4ee3\u7801\uff0c\u6539\u5584\u4e0a\u9762\u4ee3\u7801\u4e2d\u590d\u6742\u7684\u5faa\u73af\u5173\u7cfb\u3002 >>> names = ['Cecilia', 'Lise', 'Marie'] >>> longest_name = None >>> max_count = 0 >>> counts = [len(n) for n in names] >>> for i, name in enumerate(names): ... count = counts[i] ... if count > max_count: ... longest_name = name ... max_count = count ... >>> longest_name 'Cecilia' \u7528zip\u6765\u6539\u5199\u4ee3\u7801\uff0c\u4f7f\u4e4b\u66f4\u7b80\u6d01\u3002 zip\u51fd\u6570\u80fd\u628a\u4e24\u4e2a\u6216\u66f4\u591a\u7684iterator\u5c01\u88c5\u6210\u60f0\u6027\u751f\u6210\u5668\uff08lazy generator\uff09\u3002 \u6bcf\u6b21\u5faa\u73af\u65f6\uff0c\u5b83\u4f1a\u5206\u522b\u4ece\u8fd9\u4e9b\u8fed\u4ee3\u5668\u91cc\u83b7\u53d6\u5404\u81ea\u7684\u4e0b\u4e00\u4e2a\u5143\u7d20\uff0c\u5e76\u628a\u8fd9\u4e9b\u503c\u653e\u5728\u4e00\u4e2a\u5143\u7ec4\u91cc\u9762\u3002 zip\u6bcf\u6b21\u53ea\u4ece\u5b83\u5c01\u88c5\u7684\u90a3\u4e9b\u8fed\u4ee3\u5668\u91cc\u9762\u5404\u81ea\u53d6\u51fa\u4e00\u4e2a\u5143\u7d20\uff0c\u6240\u4ee5\u5373\u4fbf\u6e90\u5217\u8868\u5f88\u957f\uff0c\u7a0b\u5e8f\u4e5f\u4e0d\u4f1a\u56e0\u4e3a\u5360\u7528\u5185\u5b58\u8fc7\u591a\u800c\u5d29\u6e83\u3002 \u800c\u8fd9\u4e2a\u5143\u7ec4\u53ef\u4ee5\u62c6\u5206\u5230for\u8bed\u53e5\u91cc\u7684\u90a3\u4e9b\u53d8\u91cf\u4e4b\u4e2d\uff08\u53c2\u89c1Rule06\uff09\u3002 \u8fd9\u6837\u5199\u51fa\u6765\u7684\u4ee3\u7801\uff0c\u6bd4\u901a\u8fc7\u4e0b\u6807\u8bbf\u95ee\u591a\u4e2a\u5217\u8868\u7684\u90a3\u79cd\u4ee3\u7801\u8981\u6e05\u6670\u5f97\u591a\u3002 >>> names = ['Cecilia', 'Lise', 'Marie'] >>> longest_name = None >>> max_count = 0 >>> counts = [len(n) for n in names] >>> for name, count in zip(names, counts): ... if count > max_count: ... longest_name = name ... max_count = count ... >>> longest_name 'Cecilia' \u4f46\u662f\uff0c\u5982\u679c\u8f93\u5165zip\u7684\u90a3\u4e9b\u5217\u8868\u7684\u957f\u5ea6\u4e0d\u4e00\u81f4\uff0c\u7528zip\u540c\u65f6\u904d\u5386\u90a3\u4e9b\u5217\u8868\uff0c\u4f1a\u4ea7\u751f\u5947\u602a\u7684\u7ed3\u679c\u3002 \u4f8b\u5982\uff0c\u6211\u7ed9names\u5217\u8868\u91cc\u53c8\u6dfb\u52a0\u4e86\u4e00\u4e2a\u540d\u5b57\uff0c\u4f46\u662f\u5fd8\u4e86\u628a\u5b83\u7684\u957f\u5ea6\u66f4\u65b0\u5230counts\u5217\u8868\u4e4b\u4e2d\u3002 \u65b0\u6dfb\u52a0\u7684\u90a3\u4e2a'Rosalind' \u5143\u7d20\u4e0d\u4f1a\u88ab\u6253\u5370\u51fa\u6765\uff0c\u56e0\u4e3azip\u51fd\u6570\u5728\u6267\u884c\u4e2d\uff0c\u53ea\u8981\u5176\u4e2d\u4efb\u4f55\u4e00\u4e2a\u8fed\u4ee3\u5668\u5904\u7406\u5b8c\u6bd5\uff0c\u5b83\u5c31\u4e0d\u518d\u5f80\u4e0b\u8d70\u4e86\u3002 \u4e8e\u662f\uff0c\u5faa\u73af\u7684\u6b21\u6570\u5b9e\u9645\u4e0a\u7b49\u4e8e\u6700\u77ed\u7684\u90a3\u4efd\u5217\u8868\u6240\u5177\u5907\u7684\u957f\u5ea6\u3002 \u4e00\u822c\u60c5\u51b5\u4e0b\uff0c\u6211\u4eec\u90fd\u662f\u6839\u636e\u67d0\u4efd\u5217\u8868\u63a8\u5bfc\u51fa\u5176\u4ed6\u51e0\u4efd\u5217\u8868\uff0c\u7136\u540e\u628a\u8fd9\u4e9b\u5217\u8868\u4e00\u8d77\u5c01\u88c5\u5230zip\u91cc\u9762\uff0c\u5e76\u4fdd\u8bc1\u8fd9\u4e9b\u5217\u8868\u957f\u5ea6\u76f8\u540c\u3002 >>> names.append('Rosalind') >>> names ['Cecilia', 'Lise', 'Marie', 'Rosalind'] >>> for name, count in zip(names, counts): ... print(name) ... Cecilia Lise Marie \u5728\u5217\u8868\u957f\u5ea6\u4e0d\u540c\u7684\u60c5\u51b5\u4e0b\uff0c\u5982\u679c\u65e0\u6cd5\u786e\u5b9a\u8fd9\u4e9b\u5217\u8868\u7684\u957f\u5ea6\u76f8\u540c\uff0c\u90a3\u5c31\u4e0d\u8981\u628a\u5b83\u4eec\u4f20\u7ed9zip\uff0c\u800c\u662f\u5e94\u8be5\u4f20\u7ed9\u53e6\u4e00\u4e2a\u53eb\u4f5czip_longest\u7684\u51fd\u6570\uff0c\u8fd9\u4e2a\u51fd\u6570\u4f4d\u4e8e\u5185\u7f6e\u7684itertools\u6a21\u5757\u91cc\u3002 \u5982\u679c\u5176\u4e2d\u6709\u4e9b\u5217\u8868\u5df2\u7ecf\u904d\u5386\u5b8c\u4e86\uff0c\u90a3\u4e48zip_longest\u4f1a\u7528\u5f53\u521d\u4f20\u7ed9fillvalue\u53c2\u6570\u7684\u90a3\u4e2a\u503c\u6765\u586b\u8865\u7a7a\u7f3a\uff08\u672c\u4f8b\u4e2d\u7a7a\u7f3a\u7684\u4e3a\u5b57\u7b26\u4e32'Rosalind'\u7684\u957f\u5ea6\u503c\uff09\uff0c\u9ed8\u8ba4\u7684\u53c2\u6570\u503c\u662fNone\u3002 >>> import itertools >>> names = ['Cecilia', 'Lise', 'Marie'] >>> longest_name = None >>> max_count = 0 >>> counts = [len(n) for n in names] >>> names.append('Rosalind') >>> names ['Cecilia', 'Lise', 'Marie', 'Rosalind'] >>> counts [7, 4, 5] >>> for name, count in itertools.zip_longest(names, counts): ... print(f'{name}: {count}') ... Cecilia: 7 Lise: 4 Marie: 5 Rosalind: None \u8981\u70b9\uff1a \u5185\u7f6e\u7684zip\u51fd\u6570\u53ef\u4ee5\u540c\u65f6\u904d\u5386\u591a\u4e2a\u8fed\u4ee3\u5668\u3002 zip\u4f1a\u521b\u5efa\u60f0\u6027\u751f\u6210\u5668\uff0c\u8ba9\u5b83\u6bcf\u6b21\u53ea\u751f\u6210\u4e00\u4e2a\u5143\u7ec4\uff0c\u6240\u4ee5\u65e0\u8bba\u8f93\u5165\u7684\u6570\u636e\u6709\u591a\u957f\uff0c\u5b83\u90fd\u662f\u4e00\u4e2a\u4e00\u4e2a\u5904\u7406\u7684\u3002 \u5982\u679c\u63d0\u4f9b\u7684\u8fed\u4ee3\u5668\u7684\u957f\u5ea6\u4e0d\u4e00\u81f4\uff0c\u90a3\u4e48\u53ea\u8981\u5176\u4e2d\u4efb\u4f55\u4e00\u4e2a\u8fed\u4ee3\u5b8c\u6bd5\uff0czip\u5c31\u4f1a\u505c\u6b62\u3002 \u5982\u679c\u60f3\u6309\u6700\u957f\u7684\u90a3\u4e2a\u8fed\u4ee3\u5668\u6765\u904d\u5386\uff0c\u90a3\u5c31\u6539\u7528\u5185\u7f6e\u7684itertools\u6a21\u5757\u4e2d\u7684zip_longest\u51fd\u6570\u3002","title":"\u7b2c8\u6761\u3000\u7528zip\u51fd\u6570\u540c\u65f6\u904d\u5386\u4e24\u4e2a\u8fed\u4ee3\u5668"},{"location":"python/Pythonic90Rules/Rule09/","text":"\u7b2c9\u6761\u3000\u4e0d\u8981\u5728for\u4e0ewhile\u5faa\u73af\u540e\u9762\u5199else\u5757 \u00b6 Python\u7684\u5faa\u73af\u6709\u4e00\u9879\u5927\u591a\u6570\u7f16\u7a0b\u8bed\u8a00\u90fd\u4e0d\u652f\u6301\u7684\u7279\u6027\uff0c\u5373\u53ef\u4ee5\u628aelse\u5757\u7d27\u8ddf\u5728\u6574\u4e2a\u5faa\u73af\u7ed3\u6784\u7684\u540e\u9762\u3002 \u7a0b\u5e8f\u505a\u5b8c\u6574\u4e2afor\u5faa\u73af\u4e4b\u540e\uff0c\u7adf\u7136\u4f1a\u6267\u884celse\u5757\u91cc\u7684\u5185\u5bb9\u3002 >>> for i in range(3): ... print('loop', i) ... else: ... print('Else block!') ... loop 0 loop 1 loop 2 Else block! try/except/else\u7ed3\u6784\u91cc\u7684else\uff08\u53c2\u89c1Rule65\u6761\uff09\uff0c\u5b83\u7684\u610f\u601d\u662f\uff1a\u5982\u679c\u6ca1\u6709\u5f02\u5e38\u9700\u8981\u5904\u7406\uff0c\u90a3\u5c31\u6267\u884c\u8fd9\u5757\u8bed\u53e5\u3002 try/finally\u7ed3\u6784\u91cc\u7684finally\uff0c\u5b83\u7684\u610f\u601d\u662f\uff1a\u4e0d\u7ba1\u524d\u9762\u90a3\u5757\u4ee3\u7801\u6267\u884c\u5f97\u5982\u4f55\uff0c\u6700\u540e\u90fd\u8981\u6267\u884cfinally\u5757\u4ee3\u7801\u3002 for/else\u7ed3\u6784\u91cc\u9762\u7684else\uff0c\u5b83\u7684\u610f\u601d\u662f\uff1a\u5982\u679c\u5faa\u73af\u6ca1\u6709\u4ece\u5934\u5230\u5c3e\u6267\u884c\u5b8c\uff08\u4e5f\u5c31\u662f\u5faa\u73af\u63d0\u524d\u7ec8\u6b62\u4e86\uff09\uff0c\u90a3\u4e48else\u5757\u91cc\u7684\u4ee3\u7801\u662f\u4e0d\u4f1a\u6267\u884c\u7684\u3002\u5728\u5faa\u73af\u4e2d\u4f7f\u7528break\u8bed\u53e5\u5b9e\u9645\u4e0a\u4f1a\u8df3\u8fc7else\u5757\u3002 >>> for i in range(3): ... print('loop', i) ... if i == 1: ... break ... else: ... print('Else block!') ... loop 0 loop 1 \u8fd8\u6709\u4e00\u4e2a\u5947\u602a\u7684\u5730\u65b9\u662f\uff0c\u5982\u679c\u5bf9\u7a7a\u767d\u5e8f\u5217\u505afor\u5faa\u73af\uff0c\u90a3\u4e48\u7a0b\u5e8f\u7acb\u523b\u5c31\u4f1a\u6267\u884celse\u5757\u3002 >>> for x in []: ... print('Never Runs') ... else: ... print('For Else block!') ... For Else block! while\u5faa\u73af\u4e5f\u662f\u8fd9\u6837\uff0c\u5982\u679c\u9996\u6b21\u5faa\u73af\u5c31\u9047\u5230False\uff0c\u90a3\u4e48\u7a0b\u5e8f\u4e5f\u4f1a\u7acb\u523b\u8fd0\u884celse\u5757\u3002 >>> while True: ... print('Never runs') ... break ... else: ... print('While Else block!') ... Never runs >>> while False: ... print('Never runs') ... else: ... print('While Else block!') ... While Else block! Python\u628aelse\u8bbe\u8ba1\u6210\u8fd9\u6837\uff0c\u4e3b\u8981\u76ee\u7684\u662f\u5229\u7528\u5b83\u5b9e\u73b0\u641c\u7d22\u903b\u8f91\u3002 \u4f8b\u5982\u4e0b\u9762\u4ee3\u7801\uff0c\u5982\u679c\u8981\u5224\u65ad\u4e24\u4e2a\u6570\u662f\u5426\u4e92\u8d28\uff08\u4e5f\u5c31\u662f\u9664\u4e861\u4e4b\u5916\uff0c\u662f\u4e0d\u662f\u6ca1\u6709\u522b\u7684\u6570\u80fd\u591f\u540c\u65f6\u6574\u9664\u5b83\u4eec\uff09\uff0c\u5c31\u53ef\u4ee5\u7528\u8fd9\u79cd\u7ed3\u6784\u5b9e\u73b0\u3002 \u5148\u628a\u6709\u53ef\u80fd\u540c\u65f6\u6574\u9664\u5b83\u4eec\u7684\u6570\u9010\u4e2a\u8bd5\u4e00\u904d\uff0c\u5982\u679c\u5168\u90fd\u8bd5\u8fc7\u4e4b\u540e\u8fd8\u662f\u6ca1\u627e\u5230\u8fd9\u6837\u7684\u6570\uff0c \u90a3\u4e48\u5faa\u73af\u5c31\u4f1a\u4ece\u5934\u5230\u5c3e\u6267\u884c\u5b8c\uff08\u8fd9\u610f\u5473\u7740\u5faa\u73af\u6ca1\u6709\u56e0\u4e3abreak\u800c\u63d0\u524d\u8df3\u51fa\uff09\uff0c \u7136\u540e\u7a0b\u5e8f\u5c31\u4f1a\u6267\u884celse\u5757\u91cc\u7684\u4ee3\u7801\u3002 >>> for i in range(2, min(a, b) + 1): ... print('Testing', i) ... if a % i == 0 and b% i == 0: ... print('Not coprime') ... else: ... print('Coprime') ... Testing 2 Testing 3 Testing 4 Coprime \u5b9e\u9645\u5de5\u4f5c\u4e2d\uff0c\u4e0a\u8ff0\u4ee3\u7801\u4f1a\u6539\u7528\u8f85\u52a9\u51fd\u6570\u5b8c\u6210\u3002\u8fd9\u6837\u7684\u8f85\u52a9\u51fd\u6570\u6709\u4e24\u79cd\u5e38\u89c1\u7684\u5199\u6cd5\u3002 \u7b2c\u4e00\u79cd\u5199\u6cd5\u662f\uff0c\u53ea\u8981\u53d1\u73b0\u67d0\u4e2a\u6761\u4ef6\u6210\u7acb\uff0c\u5c31\u7acb\u523b\u8fd4\u56de\uff0c\u5982\u679c\u59cb\u7ec8\u90fd\u6ca1\u78b0\u5230\u8fd9\u79cd\u60c5\u51b5\uff0c\u90a3\u4e48\u5faa\u73af\u5c31\u4f1a\u5b8c\u6574\u5730\u6267\u884c\uff0c\u8ba9\u7a0b\u5e8f\u8fd4\u56de\u51fd\u6570\u672b\u5c3e\u7684\u90a3\u4e2a\u503c\u4f5c\u4e3a\u9ed8\u8ba4\u8fd4\u56de\u503c\u3002 >>> def coprime(a, b): ... for i in range(2, min(a, b) + 1): ... if a % i == 0 and b% i == 0: ... return False ... return True ... >>> assert coprime(4, 9) >>> assert not coprime(4, 9) Traceback (most recent call last): File \"\", line 1, in AssertionError >>> assert coprime(3, 6) Traceback (most recent call last): File \"\", line 1, in AssertionError >>> assert not coprime(3, 6) >>> \u7b2c\u4e8c\u79cd\u5199\u6cd5\u662f\uff0c\u7528\u53d8\u91cf\u6765\u8bb0\u5f55\u5faa\u73af\u8fc7\u7a0b\u4e2d\u6709\u6ca1\u6709\u78b0\u5230\u8fd9\u6837\u7684\u60c5\u51b5\uff0c\u5982\u679c\u6709\uff0c\u90a3\u5c31\u7528break\u63d0\u524d\u8df3\u51fa\u5faa\u73af\uff0c\u5982\u679c\u6ca1\u6709\uff0c\u5faa\u73af\u5c31\u4f1a\u5b8c\u6574\u5730\u6267\u884c\uff0c\u65e0\u8bba\u5982\u4f55\uff0c\u6700\u540e\u90fd\u8fd4\u56de\u8fd9\u4e2a\u53d8\u91cf\u7684\u503c\u3002 >>> def coprime_alternate(a, b): ... is_coprime = True ... for i in range(2, min(a, b) + 1): ... if a % i == 0 and b% i == 0: ... is_coprime = False ... break ... return is_coprime ... >>> assert coprime_alternate(4, 9) >>> assert not coprime_alternate(4, 9) Traceback (most recent call last): File \"\", line 1, in AssertionError >>> assert coprime_alternate(3, 6) Traceback (most recent call last): File \"\", line 1, in AssertionError >>> assert not coprime_alternate(3, 6) >>> \u5bf9\u4e8e\u4e0d\u719f\u6089for/else\u7ed3\u6784\u7684\u4eba\u6765\u8bf4\uff0c\u521a\u624d\u90a3\u4e24\u79cd\u5199\u6cd5\u90fd\u662f\u6bd4\u8f83\u6e05\u6670\u7684\u65b9\u6848\u3002 for/else\u6216while/else\u7ed3\u6784\u672c\u8eab\u867d\u7136\u53ef\u4ee5\u5b9e\u73b0\u67d0\u4e9b\u903b\u8f91\u8868\u8fbe\uff0c\u4f46\u5b83\u5e26\u6765\u7684\u56f0\u60d1\u5df2\u7ecf\u76d6\u8fc7\u4e86\u5b83\u7684\u597d\u5904\uff0c\u4f1a\u8ba9\u4ee3\u7801\u4ea7\u751f\u6b67\u4e49\u3002\u6240\u4ee5\uff0c\u8bf7\u4e0d\u8981\u8fd9\u4e48\u5199\u3002 \u8981\u70b9\uff1a * Python\u6709\u79cd\u7279\u6b8a\u7684\u8bed\u6cd5\uff0c\u53ef\u4ee5\u628aelse\u5757\u7d27\u8ddf\u5728\u6574\u4e2afor\u5faa\u73af\u6216while\u5faa\u73af\u7684\u540e\u9762\u3002 * \u53ea\u6709\u5728\u6574\u4e2a\u5faa\u73af\u6ca1\u6709\u56e0\u4e3abreak\u63d0\u524d\u8df3\u51fa\u7684\u60c5\u51b5\u4e0b\uff0celse\u5757\u624d\u4f1a\u6267\u884c\u3002 * \u628aelse\u5757\u7d27\u8ddf\u5728\u6574\u4e2a\u5faa\u73af\u540e\u9762\uff0c\u4f1a\u8ba9\u4eba\u4e0d\u592a\u5bb9\u6613\u770b\u51fa\u8fd9\u6bb5\u4ee3\u7801\u7684\u610f\u601d\uff0c\u6240\u4ee5\u8981\u907f\u514d\u8fd9\u6837\u5199\u3002","title":"\u7b2c09\u6761 \u4e0d\u8981\u5728for\u4e0ewhile\u5faa\u73af\u540e\u9762\u5199else\u5757"},{"location":"python/Pythonic90Rules/Rule09/#9-forwhileelse","text":"Python\u7684\u5faa\u73af\u6709\u4e00\u9879\u5927\u591a\u6570\u7f16\u7a0b\u8bed\u8a00\u90fd\u4e0d\u652f\u6301\u7684\u7279\u6027\uff0c\u5373\u53ef\u4ee5\u628aelse\u5757\u7d27\u8ddf\u5728\u6574\u4e2a\u5faa\u73af\u7ed3\u6784\u7684\u540e\u9762\u3002 \u7a0b\u5e8f\u505a\u5b8c\u6574\u4e2afor\u5faa\u73af\u4e4b\u540e\uff0c\u7adf\u7136\u4f1a\u6267\u884celse\u5757\u91cc\u7684\u5185\u5bb9\u3002 >>> for i in range(3): ... print('loop', i) ... else: ... print('Else block!') ... loop 0 loop 1 loop 2 Else block! try/except/else\u7ed3\u6784\u91cc\u7684else\uff08\u53c2\u89c1Rule65\u6761\uff09\uff0c\u5b83\u7684\u610f\u601d\u662f\uff1a\u5982\u679c\u6ca1\u6709\u5f02\u5e38\u9700\u8981\u5904\u7406\uff0c\u90a3\u5c31\u6267\u884c\u8fd9\u5757\u8bed\u53e5\u3002 try/finally\u7ed3\u6784\u91cc\u7684finally\uff0c\u5b83\u7684\u610f\u601d\u662f\uff1a\u4e0d\u7ba1\u524d\u9762\u90a3\u5757\u4ee3\u7801\u6267\u884c\u5f97\u5982\u4f55\uff0c\u6700\u540e\u90fd\u8981\u6267\u884cfinally\u5757\u4ee3\u7801\u3002 for/else\u7ed3\u6784\u91cc\u9762\u7684else\uff0c\u5b83\u7684\u610f\u601d\u662f\uff1a\u5982\u679c\u5faa\u73af\u6ca1\u6709\u4ece\u5934\u5230\u5c3e\u6267\u884c\u5b8c\uff08\u4e5f\u5c31\u662f\u5faa\u73af\u63d0\u524d\u7ec8\u6b62\u4e86\uff09\uff0c\u90a3\u4e48else\u5757\u91cc\u7684\u4ee3\u7801\u662f\u4e0d\u4f1a\u6267\u884c\u7684\u3002\u5728\u5faa\u73af\u4e2d\u4f7f\u7528break\u8bed\u53e5\u5b9e\u9645\u4e0a\u4f1a\u8df3\u8fc7else\u5757\u3002 >>> for i in range(3): ... print('loop', i) ... if i == 1: ... break ... else: ... print('Else block!') ... loop 0 loop 1 \u8fd8\u6709\u4e00\u4e2a\u5947\u602a\u7684\u5730\u65b9\u662f\uff0c\u5982\u679c\u5bf9\u7a7a\u767d\u5e8f\u5217\u505afor\u5faa\u73af\uff0c\u90a3\u4e48\u7a0b\u5e8f\u7acb\u523b\u5c31\u4f1a\u6267\u884celse\u5757\u3002 >>> for x in []: ... print('Never Runs') ... else: ... print('For Else block!') ... For Else block! while\u5faa\u73af\u4e5f\u662f\u8fd9\u6837\uff0c\u5982\u679c\u9996\u6b21\u5faa\u73af\u5c31\u9047\u5230False\uff0c\u90a3\u4e48\u7a0b\u5e8f\u4e5f\u4f1a\u7acb\u523b\u8fd0\u884celse\u5757\u3002 >>> while True: ... print('Never runs') ... break ... else: ... print('While Else block!') ... Never runs >>> while False: ... print('Never runs') ... else: ... print('While Else block!') ... While Else block! Python\u628aelse\u8bbe\u8ba1\u6210\u8fd9\u6837\uff0c\u4e3b\u8981\u76ee\u7684\u662f\u5229\u7528\u5b83\u5b9e\u73b0\u641c\u7d22\u903b\u8f91\u3002 \u4f8b\u5982\u4e0b\u9762\u4ee3\u7801\uff0c\u5982\u679c\u8981\u5224\u65ad\u4e24\u4e2a\u6570\u662f\u5426\u4e92\u8d28\uff08\u4e5f\u5c31\u662f\u9664\u4e861\u4e4b\u5916\uff0c\u662f\u4e0d\u662f\u6ca1\u6709\u522b\u7684\u6570\u80fd\u591f\u540c\u65f6\u6574\u9664\u5b83\u4eec\uff09\uff0c\u5c31\u53ef\u4ee5\u7528\u8fd9\u79cd\u7ed3\u6784\u5b9e\u73b0\u3002 \u5148\u628a\u6709\u53ef\u80fd\u540c\u65f6\u6574\u9664\u5b83\u4eec\u7684\u6570\u9010\u4e2a\u8bd5\u4e00\u904d\uff0c\u5982\u679c\u5168\u90fd\u8bd5\u8fc7\u4e4b\u540e\u8fd8\u662f\u6ca1\u627e\u5230\u8fd9\u6837\u7684\u6570\uff0c \u90a3\u4e48\u5faa\u73af\u5c31\u4f1a\u4ece\u5934\u5230\u5c3e\u6267\u884c\u5b8c\uff08\u8fd9\u610f\u5473\u7740\u5faa\u73af\u6ca1\u6709\u56e0\u4e3abreak\u800c\u63d0\u524d\u8df3\u51fa\uff09\uff0c \u7136\u540e\u7a0b\u5e8f\u5c31\u4f1a\u6267\u884celse\u5757\u91cc\u7684\u4ee3\u7801\u3002 >>> for i in range(2, min(a, b) + 1): ... print('Testing', i) ... if a % i == 0 and b% i == 0: ... print('Not coprime') ... else: ... print('Coprime') ... Testing 2 Testing 3 Testing 4 Coprime \u5b9e\u9645\u5de5\u4f5c\u4e2d\uff0c\u4e0a\u8ff0\u4ee3\u7801\u4f1a\u6539\u7528\u8f85\u52a9\u51fd\u6570\u5b8c\u6210\u3002\u8fd9\u6837\u7684\u8f85\u52a9\u51fd\u6570\u6709\u4e24\u79cd\u5e38\u89c1\u7684\u5199\u6cd5\u3002 \u7b2c\u4e00\u79cd\u5199\u6cd5\u662f\uff0c\u53ea\u8981\u53d1\u73b0\u67d0\u4e2a\u6761\u4ef6\u6210\u7acb\uff0c\u5c31\u7acb\u523b\u8fd4\u56de\uff0c\u5982\u679c\u59cb\u7ec8\u90fd\u6ca1\u78b0\u5230\u8fd9\u79cd\u60c5\u51b5\uff0c\u90a3\u4e48\u5faa\u73af\u5c31\u4f1a\u5b8c\u6574\u5730\u6267\u884c\uff0c\u8ba9\u7a0b\u5e8f\u8fd4\u56de\u51fd\u6570\u672b\u5c3e\u7684\u90a3\u4e2a\u503c\u4f5c\u4e3a\u9ed8\u8ba4\u8fd4\u56de\u503c\u3002 >>> def coprime(a, b): ... for i in range(2, min(a, b) + 1): ... if a % i == 0 and b% i == 0: ... return False ... return True ... >>> assert coprime(4, 9) >>> assert not coprime(4, 9) Traceback (most recent call last): File \"\", line 1, in AssertionError >>> assert coprime(3, 6) Traceback (most recent call last): File \"\", line 1, in AssertionError >>> assert not coprime(3, 6) >>> \u7b2c\u4e8c\u79cd\u5199\u6cd5\u662f\uff0c\u7528\u53d8\u91cf\u6765\u8bb0\u5f55\u5faa\u73af\u8fc7\u7a0b\u4e2d\u6709\u6ca1\u6709\u78b0\u5230\u8fd9\u6837\u7684\u60c5\u51b5\uff0c\u5982\u679c\u6709\uff0c\u90a3\u5c31\u7528break\u63d0\u524d\u8df3\u51fa\u5faa\u73af\uff0c\u5982\u679c\u6ca1\u6709\uff0c\u5faa\u73af\u5c31\u4f1a\u5b8c\u6574\u5730\u6267\u884c\uff0c\u65e0\u8bba\u5982\u4f55\uff0c\u6700\u540e\u90fd\u8fd4\u56de\u8fd9\u4e2a\u53d8\u91cf\u7684\u503c\u3002 >>> def coprime_alternate(a, b): ... is_coprime = True ... for i in range(2, min(a, b) + 1): ... if a % i == 0 and b% i == 0: ... is_coprime = False ... break ... return is_coprime ... >>> assert coprime_alternate(4, 9) >>> assert not coprime_alternate(4, 9) Traceback (most recent call last): File \"\", line 1, in AssertionError >>> assert coprime_alternate(3, 6) Traceback (most recent call last): File \"\", line 1, in AssertionError >>> assert not coprime_alternate(3, 6) >>> \u5bf9\u4e8e\u4e0d\u719f\u6089for/else\u7ed3\u6784\u7684\u4eba\u6765\u8bf4\uff0c\u521a\u624d\u90a3\u4e24\u79cd\u5199\u6cd5\u90fd\u662f\u6bd4\u8f83\u6e05\u6670\u7684\u65b9\u6848\u3002 for/else\u6216while/else\u7ed3\u6784\u672c\u8eab\u867d\u7136\u53ef\u4ee5\u5b9e\u73b0\u67d0\u4e9b\u903b\u8f91\u8868\u8fbe\uff0c\u4f46\u5b83\u5e26\u6765\u7684\u56f0\u60d1\u5df2\u7ecf\u76d6\u8fc7\u4e86\u5b83\u7684\u597d\u5904\uff0c\u4f1a\u8ba9\u4ee3\u7801\u4ea7\u751f\u6b67\u4e49\u3002\u6240\u4ee5\uff0c\u8bf7\u4e0d\u8981\u8fd9\u4e48\u5199\u3002 \u8981\u70b9\uff1a * Python\u6709\u79cd\u7279\u6b8a\u7684\u8bed\u6cd5\uff0c\u53ef\u4ee5\u628aelse\u5757\u7d27\u8ddf\u5728\u6574\u4e2afor\u5faa\u73af\u6216while\u5faa\u73af\u7684\u540e\u9762\u3002 * \u53ea\u6709\u5728\u6574\u4e2a\u5faa\u73af\u6ca1\u6709\u56e0\u4e3abreak\u63d0\u524d\u8df3\u51fa\u7684\u60c5\u51b5\u4e0b\uff0celse\u5757\u624d\u4f1a\u6267\u884c\u3002 * \u628aelse\u5757\u7d27\u8ddf\u5728\u6574\u4e2a\u5faa\u73af\u540e\u9762\uff0c\u4f1a\u8ba9\u4eba\u4e0d\u592a\u5bb9\u6613\u770b\u51fa\u8fd9\u6bb5\u4ee3\u7801\u7684\u610f\u601d\uff0c\u6240\u4ee5\u8981\u907f\u514d\u8fd9\u6837\u5199\u3002","title":"\u7b2c9\u6761\u3000\u4e0d\u8981\u5728for\u4e0ewhile\u5faa\u73af\u540e\u9762\u5199else\u5757"},{"location":"python/Pythonic90Rules/Rule10/","text":"\u7b2c10\u6761\u3000\u7528\u8d4b\u503c\u8868\u8fbe\u5f0f\u51cf\u5c11\u91cd\u590d\u4ee3\u7801 \u00b6 \u8d4b\u503c\u8868\u8fbe\u5f0f\uff08assignment expression\uff09\u662fPython 3.8\u65b0\u5f15\u5165\u7684\u8bed\u6cd5\uff0c\u5b83\u4f1a\u7528\u5230\u6d77\u8c61\u64cd\u4f5c\u7b26\uff08walrusoperator\uff09\u3002 a = b\u662f\u666e\u901a\u7684\u8d4b\u503c\u8bed\u53e5\uff0c\u8bfb\u4f5ca equals b\uff0c\u800ca := b\u5219\u662f\u8d4b\u503c\u8868\u8fbe\u5f0f\uff0c\u8bfb\u4f5ca walrus b\u3002 \u8fd9\u4e2a\u7b26\u53f7\u4e3a\u4ec0\u4e48\u53ebwalrus\u5462\uff1f\u56e0\u4e3a\u628a:=\u987a\u65f6\u9488\u65cb\u8f6c90\u00ba\u4e4b\u540e\uff0c\u5192\u53f7\u5c31\u662f\u6d77\u8c61\u7684\u4e00\u53cc\u773c\u775b\uff0c\u7b49\u53f7\u5c31\u662f\u5b83\u7684\u4e00\u5bf9\u7360\u7259\u3002 \u5728Python\u91cc\u9762\u7ecf\u5e38\u8981\u5148\u83b7\u53d6\u67d0\u4e2a\u503c\uff0c\u7136\u540e\u5224\u65ad\u5b83\u662f\u5426\u975e\u96f6\uff0c\u5982\u679c\u662f\u5c31\u6267\u884c\u67d0\u6bb5\u4ee3\u7801\u3002 fresh_fruit = { 'apple': 10, 'banana': 8, 'lemon': 5 } count = fresh_fruit.get('lemon', 0) if count: print('Stock:', count) else: print('Out of Stock') Result: Stock: 5 \u4e0a\u9762\u7684\u4ee3\u7801\u6539\u7528\u6d77\u8c61\u64cd\u4f5c\u7b26\u6765\u5199\uff1a fresh_fruit = { 'apple': 10, 'banana': 8, 'lemon': 5 } if count := fresh_fruit.get('lemon', 0): print('Stock:', count) else: print('Out of Stock') Result: Stock: 5 \u65b0\u4ee3\u7801\u867d\u7136\u53ea\u7701\u4e86\u4e00\u884c\uff0c\u4f46\u8bfb\u8d77\u6765\u5374\u6e05\u6670\u5f88\u591a\uff0c\u56e0\u4e3a\u8fd9\u79cd\u5199\u6cd5\u660e\u786e\u4f53\u73b0\u51facount\u53d8\u91cf\u53ea\u4e0eif\u5757\u6709\u5173\u3002 \u8fd9\u4e2a\u8d4b\u503c\u8868\u8fbe\u5f0f\u5148\u628a:=\u53f3\u8fb9\u7684\u503c\u8d4b\u7ed9\u5de6\u8fb9\u7684count\u53d8\u91cf\uff0c\u7136\u540e\u5bf9\u81ea\u8eab\u6c42\u503c\uff0c\u4e5f\u5c31\u662f\u628a\u53d8\u91cf\u7684\u503c\u5f53\u6210\u6574\u4e2a\u8868\u8fbe\u5f0f\u7684\u503c\u3002 \u7531\u4e8e\u8868\u8fbe\u5f0f\u7d27\u8ddf\u7740if\uff0c\u7a0b\u5e8f\u4f1a\u6839\u636e\u5b83\u7684\u503c\u662f\u5426\u975e\u96f6\u6765\u51b3\u5b9a\u8be5\u4e0d\u8be5\u6267\u884cif\u5757\u3002 \u8fd9\u79cd\u5148\u8d4b\u503c\u518d\u5224\u65ad\u7684\u505a\u6cd5\uff0c\u6b63\u662f\u6d77\u8c61\u64cd\u4f5c\u7b26\u60f3\u8981\u8868\u8fbe\u7684\u610f\u601d\u3002 \u4e0b\u9762\u7684\u4f8b\u5b50\u628a\u8d4b\u503c\u8868\u8fbe\u5f0f\u653e\u5728\u4e00\u5bf9\u62ec\u53f7\u91cc\u9762\u7684\uff0c\u56e0\u4e3a\u6211\u4eec\u8981\u5728if\u8bed\u53e5\u91cc\u9762\u628a\u8fd9\u4e2a\u8868\u8fbe\u5f0f\u7684\u7ed3\u679c\u8ddf4\u8fd9\u4e2a\u503c\u76f8\u6bd4\u8f83\u3002\u800c\u4e14\uff0c\u901a\u8fc7\u4f7f\u7528\u6d77\u8c61\u64cd\u4f5c\u7b26\u628a\u5b9a\u4e49pieces\u653e\u5728if/else\u5206\u652f\u5185\uff0c\u4e5f\u80fd\u8ba9\u4ee3\u7801\u53d8\u5f97\u6e05\u6670 fresh_fruit = { 'apple': 10, 'banana': 8, 'lemon': 5 } pieces = 0 if (count := fresh_fruit.get('apple', 2)) > 4: pieces = count print('Stock:', count) else: pieces = 0 print('Out of Stock') \u4f7f\u7528\u6d77\u8c61\u64cd\u4f5c\u7b26\u7ed3\u6784\u5b9e\u73b0switch/case\u7ed3\u6784\u3002 fresh_fruit = { 'apple': 10, 'banana': 8, 'lemon': 5 } pieces = 0 if (count := fresh_fruit.get('apple', 2)) > 10: pieces = count elif (count := fresh_fruit.get('banana', 2)) > 8: pieces = count elif (count := fresh_fruit.get('lemon', 2)) > 3: pieces = count else: pieces = 0 print(pieces) Result: 5 \u8981\u70b9\uff1a * \u8d4b\u503c\u8868\u8fbe\u5f0f\u901a\u8fc7\u6d77\u8c61\u64cd\u4f5c\u7b26\uff08:=\uff09\u7ed9\u53d8\u91cf\u8d4b\u503c\uff0c\u5e76\u4e14\u8ba9\u8fd9\u4e2a\u503c\u6210\u4e3a\u8fd9\u6761\u8868\u8fbe\u5f0f\u7684\u7ed3\u679c\uff0c\u4e8e\u662f\uff0c\u6211\u4eec\u53ef\u4ee5\u5229\u7528\u8fd9\u9879\u7279\u6027\u6765\u7f29\u51cf\u4ee3\u7801\u3002 * \u5982\u679c\u8d4b\u503c\u8868\u8fbe\u5f0f\u662f\u5927\u8868\u8fbe\u5f0f\u91cc\u7684\u4e00\u90e8\u5206\uff0c\u5c31\u5f97\u7528\u4e00\u5bf9\u62ec\u53f7\u628a\u5b83\u62ec\u8d77\u6765\u3002 * \u867d\u8bf4Python\u4e0d\u652f\u6301switch/case\u4e0edo/while\u7ed3\u6784\uff0c\u4f46\u53ef\u4ee5\u5229\u7528\u8d4b\u503c\u8868\u8fbe\u5f0f\u6e05\u6670\u5730\u6a21\u62df\u51fa\u8fd9\u79cd\u903b\u8f91\u3002 \u8865\u5145\uff1aPEP572: \u6d77\u8c61\u8fd0\u7b97\u7b26 \u00b6 \u7528\u4e8e if-else \u6761\u4ef6\u8868\u8fbe\u5f0f \u00b6 \u4e00\u822c\u5199\u6cd5\uff1a a = 15 if a > 10: print('hello, it''s walrus') \u6d77\u8c61\u8fd0\u7b97\u7b26\uff1a if a := 15 > 10: print('hello, it''s walrus') \u7528\u4e8e while \u5faa\u73af \u00b6 \u5e38\u89c4\u5199\u6cd5\uff1a n = 5 while n: print('hello walrus: ', n) n = n - 1 Result: hello walrus: 4 hello walrus: 3 hello walrus: 2 hello walrus: 1 hello walrus: 0 \u6d77\u8c61\u5199\u6cd5\uff1a n = 5 while (n := n - 1) + 1: print('hello walrus: ', n) Result: hello walrus: 4 hello walrus: 3 hello walrus: 2 hello walrus: 1 hello walrus: 0 \u5bc6\u7801\u6821\u9a8c\u5e38\u89c4\u5199\u6cd5\uff1a while True: psw = input('input password: ') if psw == '123': break \u5bc6\u7801\u6821\u9a8c\u6d77\u8c61\u5199\u6cd5\uff1a while (psw := input('input password: ')) != '123': continue \u7528\u4e8e\u5217\u8868\u63a8\u5bfc\u5f0f \u00b6 \u8ba1\u7b97\u5143\u7d20\u5e73\u65b9\u6839\uff0c\u5e76\u4fdd\u7559\u5e73\u65b9\u6839\u5927\u4e8e 5 \u7684\u503c\uff1a \u5e38\u89c4\u5199\u6cd5\uff1a(\u6ce8\u610f\uff0c\u6267\u884c\u4e867\u6b21\uff0c\u6ee1\u8db3\u6761\u4ef6\u76843\u4e2a\u6570\u5b57\u6267\u884c\u4e86\u4e24\u904d\uff0c\u7b2c\u4e00\u6b21\u6267\u884cfor\u540e\u9762\u7684if f(i) > 5\uff0c\u7b2c\u4e8c\u6b21\u6267\u884cfor\u524d\u9762\u7684f(i))\u3002 nums = [16, 36, 49, 64] def f(x): print('run f(x) 1 time: ', x) return x ** 0.5 print([f(i) for i in nums if f(i) > 5]) Result: run f(x) 1 time: 16 run f(x) 1 time: 36 run f(x) 1 time: 36 run f(x) 1 time: 49 run f(x) 1 time: 49 run f(x) 1 time: 64 run f(x) 1 time: 64 [6.0, 7.0, 8.0] \u6d77\u8c61\u5199\u6cd5\uff1a\uff08\u51fd\u6570\u53ea\u6267\u884c\u4e864\u6b21\uff0c\u6027\u80fd\u4f18\u4e8e\u4f20\u7edf\u5199\u6cd5\uff09 nums = [16, 36, 49, 64] def f(x): print('run f(x) 1 time: ', x) return x ** 0.5 print([n for i in nums if(n := f(i)) > 5]) Result: run f(x) 1 time: 16 run f(x) 1 time: 36 run f(x) 1 time: 49 run f(x) 1 time: 64 [6.0, 7.0, 8.0]","title":"\u7b2c10\u6761 \u7528\u8d4b\u503c\u8868\u8fbe\u5f0f\u51cf\u5c11\u91cd\u590d\u4ee3\u7801"},{"location":"python/Pythonic90Rules/Rule10/#10","text":"\u8d4b\u503c\u8868\u8fbe\u5f0f\uff08assignment expression\uff09\u662fPython 3.8\u65b0\u5f15\u5165\u7684\u8bed\u6cd5\uff0c\u5b83\u4f1a\u7528\u5230\u6d77\u8c61\u64cd\u4f5c\u7b26\uff08walrusoperator\uff09\u3002 a = b\u662f\u666e\u901a\u7684\u8d4b\u503c\u8bed\u53e5\uff0c\u8bfb\u4f5ca equals b\uff0c\u800ca := b\u5219\u662f\u8d4b\u503c\u8868\u8fbe\u5f0f\uff0c\u8bfb\u4f5ca walrus b\u3002 \u8fd9\u4e2a\u7b26\u53f7\u4e3a\u4ec0\u4e48\u53ebwalrus\u5462\uff1f\u56e0\u4e3a\u628a:=\u987a\u65f6\u9488\u65cb\u8f6c90\u00ba\u4e4b\u540e\uff0c\u5192\u53f7\u5c31\u662f\u6d77\u8c61\u7684\u4e00\u53cc\u773c\u775b\uff0c\u7b49\u53f7\u5c31\u662f\u5b83\u7684\u4e00\u5bf9\u7360\u7259\u3002 \u5728Python\u91cc\u9762\u7ecf\u5e38\u8981\u5148\u83b7\u53d6\u67d0\u4e2a\u503c\uff0c\u7136\u540e\u5224\u65ad\u5b83\u662f\u5426\u975e\u96f6\uff0c\u5982\u679c\u662f\u5c31\u6267\u884c\u67d0\u6bb5\u4ee3\u7801\u3002 fresh_fruit = { 'apple': 10, 'banana': 8, 'lemon': 5 } count = fresh_fruit.get('lemon', 0) if count: print('Stock:', count) else: print('Out of Stock') Result: Stock: 5 \u4e0a\u9762\u7684\u4ee3\u7801\u6539\u7528\u6d77\u8c61\u64cd\u4f5c\u7b26\u6765\u5199\uff1a fresh_fruit = { 'apple': 10, 'banana': 8, 'lemon': 5 } if count := fresh_fruit.get('lemon', 0): print('Stock:', count) else: print('Out of Stock') Result: Stock: 5 \u65b0\u4ee3\u7801\u867d\u7136\u53ea\u7701\u4e86\u4e00\u884c\uff0c\u4f46\u8bfb\u8d77\u6765\u5374\u6e05\u6670\u5f88\u591a\uff0c\u56e0\u4e3a\u8fd9\u79cd\u5199\u6cd5\u660e\u786e\u4f53\u73b0\u51facount\u53d8\u91cf\u53ea\u4e0eif\u5757\u6709\u5173\u3002 \u8fd9\u4e2a\u8d4b\u503c\u8868\u8fbe\u5f0f\u5148\u628a:=\u53f3\u8fb9\u7684\u503c\u8d4b\u7ed9\u5de6\u8fb9\u7684count\u53d8\u91cf\uff0c\u7136\u540e\u5bf9\u81ea\u8eab\u6c42\u503c\uff0c\u4e5f\u5c31\u662f\u628a\u53d8\u91cf\u7684\u503c\u5f53\u6210\u6574\u4e2a\u8868\u8fbe\u5f0f\u7684\u503c\u3002 \u7531\u4e8e\u8868\u8fbe\u5f0f\u7d27\u8ddf\u7740if\uff0c\u7a0b\u5e8f\u4f1a\u6839\u636e\u5b83\u7684\u503c\u662f\u5426\u975e\u96f6\u6765\u51b3\u5b9a\u8be5\u4e0d\u8be5\u6267\u884cif\u5757\u3002 \u8fd9\u79cd\u5148\u8d4b\u503c\u518d\u5224\u65ad\u7684\u505a\u6cd5\uff0c\u6b63\u662f\u6d77\u8c61\u64cd\u4f5c\u7b26\u60f3\u8981\u8868\u8fbe\u7684\u610f\u601d\u3002 \u4e0b\u9762\u7684\u4f8b\u5b50\u628a\u8d4b\u503c\u8868\u8fbe\u5f0f\u653e\u5728\u4e00\u5bf9\u62ec\u53f7\u91cc\u9762\u7684\uff0c\u56e0\u4e3a\u6211\u4eec\u8981\u5728if\u8bed\u53e5\u91cc\u9762\u628a\u8fd9\u4e2a\u8868\u8fbe\u5f0f\u7684\u7ed3\u679c\u8ddf4\u8fd9\u4e2a\u503c\u76f8\u6bd4\u8f83\u3002\u800c\u4e14\uff0c\u901a\u8fc7\u4f7f\u7528\u6d77\u8c61\u64cd\u4f5c\u7b26\u628a\u5b9a\u4e49pieces\u653e\u5728if/else\u5206\u652f\u5185\uff0c\u4e5f\u80fd\u8ba9\u4ee3\u7801\u53d8\u5f97\u6e05\u6670 fresh_fruit = { 'apple': 10, 'banana': 8, 'lemon': 5 } pieces = 0 if (count := fresh_fruit.get('apple', 2)) > 4: pieces = count print('Stock:', count) else: pieces = 0 print('Out of Stock') \u4f7f\u7528\u6d77\u8c61\u64cd\u4f5c\u7b26\u7ed3\u6784\u5b9e\u73b0switch/case\u7ed3\u6784\u3002 fresh_fruit = { 'apple': 10, 'banana': 8, 'lemon': 5 } pieces = 0 if (count := fresh_fruit.get('apple', 2)) > 10: pieces = count elif (count := fresh_fruit.get('banana', 2)) > 8: pieces = count elif (count := fresh_fruit.get('lemon', 2)) > 3: pieces = count else: pieces = 0 print(pieces) Result: 5 \u8981\u70b9\uff1a * \u8d4b\u503c\u8868\u8fbe\u5f0f\u901a\u8fc7\u6d77\u8c61\u64cd\u4f5c\u7b26\uff08:=\uff09\u7ed9\u53d8\u91cf\u8d4b\u503c\uff0c\u5e76\u4e14\u8ba9\u8fd9\u4e2a\u503c\u6210\u4e3a\u8fd9\u6761\u8868\u8fbe\u5f0f\u7684\u7ed3\u679c\uff0c\u4e8e\u662f\uff0c\u6211\u4eec\u53ef\u4ee5\u5229\u7528\u8fd9\u9879\u7279\u6027\u6765\u7f29\u51cf\u4ee3\u7801\u3002 * \u5982\u679c\u8d4b\u503c\u8868\u8fbe\u5f0f\u662f\u5927\u8868\u8fbe\u5f0f\u91cc\u7684\u4e00\u90e8\u5206\uff0c\u5c31\u5f97\u7528\u4e00\u5bf9\u62ec\u53f7\u628a\u5b83\u62ec\u8d77\u6765\u3002 * \u867d\u8bf4Python\u4e0d\u652f\u6301switch/case\u4e0edo/while\u7ed3\u6784\uff0c\u4f46\u53ef\u4ee5\u5229\u7528\u8d4b\u503c\u8868\u8fbe\u5f0f\u6e05\u6670\u5730\u6a21\u62df\u51fa\u8fd9\u79cd\u903b\u8f91\u3002","title":"\u7b2c10\u6761\u3000\u7528\u8d4b\u503c\u8868\u8fbe\u5f0f\u51cf\u5c11\u91cd\u590d\u4ee3\u7801"},{"location":"python/Pythonic90Rules/Rule10/#pep572","text":"","title":"\u8865\u5145\uff1aPEP572: \u6d77\u8c61\u8fd0\u7b97\u7b26"},{"location":"python/Pythonic90Rules/Rule10/#if-else","text":"\u4e00\u822c\u5199\u6cd5\uff1a a = 15 if a > 10: print('hello, it''s walrus') \u6d77\u8c61\u8fd0\u7b97\u7b26\uff1a if a := 15 > 10: print('hello, it''s walrus')","title":"\u7528\u4e8e if-else \u6761\u4ef6\u8868\u8fbe\u5f0f"},{"location":"python/Pythonic90Rules/Rule10/#while","text":"\u5e38\u89c4\u5199\u6cd5\uff1a n = 5 while n: print('hello walrus: ', n) n = n - 1 Result: hello walrus: 4 hello walrus: 3 hello walrus: 2 hello walrus: 1 hello walrus: 0 \u6d77\u8c61\u5199\u6cd5\uff1a n = 5 while (n := n - 1) + 1: print('hello walrus: ', n) Result: hello walrus: 4 hello walrus: 3 hello walrus: 2 hello walrus: 1 hello walrus: 0 \u5bc6\u7801\u6821\u9a8c\u5e38\u89c4\u5199\u6cd5\uff1a while True: psw = input('input password: ') if psw == '123': break \u5bc6\u7801\u6821\u9a8c\u6d77\u8c61\u5199\u6cd5\uff1a while (psw := input('input password: ')) != '123': continue","title":"\u7528\u4e8e while \u5faa\u73af"},{"location":"python/Pythonic90Rules/Rule10/#_1","text":"\u8ba1\u7b97\u5143\u7d20\u5e73\u65b9\u6839\uff0c\u5e76\u4fdd\u7559\u5e73\u65b9\u6839\u5927\u4e8e 5 \u7684\u503c\uff1a \u5e38\u89c4\u5199\u6cd5\uff1a(\u6ce8\u610f\uff0c\u6267\u884c\u4e867\u6b21\uff0c\u6ee1\u8db3\u6761\u4ef6\u76843\u4e2a\u6570\u5b57\u6267\u884c\u4e86\u4e24\u904d\uff0c\u7b2c\u4e00\u6b21\u6267\u884cfor\u540e\u9762\u7684if f(i) > 5\uff0c\u7b2c\u4e8c\u6b21\u6267\u884cfor\u524d\u9762\u7684f(i))\u3002 nums = [16, 36, 49, 64] def f(x): print('run f(x) 1 time: ', x) return x ** 0.5 print([f(i) for i in nums if f(i) > 5]) Result: run f(x) 1 time: 16 run f(x) 1 time: 36 run f(x) 1 time: 36 run f(x) 1 time: 49 run f(x) 1 time: 49 run f(x) 1 time: 64 run f(x) 1 time: 64 [6.0, 7.0, 8.0] \u6d77\u8c61\u5199\u6cd5\uff1a\uff08\u51fd\u6570\u53ea\u6267\u884c\u4e864\u6b21\uff0c\u6027\u80fd\u4f18\u4e8e\u4f20\u7edf\u5199\u6cd5\uff09 nums = [16, 36, 49, 64] def f(x): print('run f(x) 1 time: ', x) return x ** 0.5 print([n for i in nums if(n := f(i)) > 5]) Result: run f(x) 1 time: 16 run f(x) 1 time: 36 run f(x) 1 time: 49 run f(x) 1 time: 64 [6.0, 7.0, 8.0]","title":"\u7528\u4e8e\u5217\u8868\u63a8\u5bfc\u5f0f"},{"location":"python/Pythonic90Rules/Rule11/","text":"\u7b2c11\u6761\u3000\u5b66\u4f1a\u5bf9\u5e8f\u5217\u505a\u5207\u7247 \u00b6 Python\u5f00\u53d1\u8005\u6700\u559c\u6b22\u7528\u5217\u8868\uff08list\uff09\u7c7b\u578b\u6765\u5904\u7406\u4e00\u4e9b\u81ea\u52a8\u5904\u7406\u7684\u4efb\u52a1\uff0c\u628a\u6bcf\u9879\u4efb\u52a1\u90fd\u5f53\u6210\u5217\u8868\u4e2d\u7684\u4e00\u4e2a\u5143\u7d20\u3002 \u6709\u4e86\u5217\u8868\uff0c\u81ea\u7136\u5c31\u6709\u8ddf\u5b83\u4e92\u8865\u7684\u7ed3\u6784\uff0c\u4e5f\u5c31\u662f\u5b57\u5178\uff08dict\uff09\uff0c\u8fd9\u79cd\u7ed3\u6784\u53ef\u4ee5\u628a\u67e5\u8be2\u6240\u7528\u7684\u952e\u4e0e\u76f8\u5173\u7684\u503c\u5bf9\u5e94\u8d77\u6765\uff08\u6240\u4ee5\u4e5f\u53eb\u5173\u952e\u77e9\u9635\uff08associative array\uff09\u6216\u54c8\u5e0c\u8868\uff08hash table\uff09\uff09\u3002 \u5bf9\u4e8e\u5b57\u5178\u6765\u8bf4\uff0c\u8bbf\u95ee\u4e0e\u8d4b\u503c\u6240\u82b1\u7684\u65f6\u95f4\u5e73\u5747\u4e0b\u6765\u662f\u4e2a\u5e38\u91cf\uff0c\u6240\u4ee5\u8fd9\u79cd\u7ed3\u6784\u5f88\u9002\u5408\u4fdd\u5b58\u52a8\u6001\u7684\u4fe1\u606f\u3002","title":"\u7b2c11\u6761 \u5b66\u4f1a\u5bf9\u5e8f\u5217\u505a\u5207\u7247"},{"location":"python/Pythonic90Rules/Rule11/#11","text":"Python\u5f00\u53d1\u8005\u6700\u559c\u6b22\u7528\u5217\u8868\uff08list\uff09\u7c7b\u578b\u6765\u5904\u7406\u4e00\u4e9b\u81ea\u52a8\u5904\u7406\u7684\u4efb\u52a1\uff0c\u628a\u6bcf\u9879\u4efb\u52a1\u90fd\u5f53\u6210\u5217\u8868\u4e2d\u7684\u4e00\u4e2a\u5143\u7d20\u3002 \u6709\u4e86\u5217\u8868\uff0c\u81ea\u7136\u5c31\u6709\u8ddf\u5b83\u4e92\u8865\u7684\u7ed3\u6784\uff0c\u4e5f\u5c31\u662f\u5b57\u5178\uff08dict\uff09\uff0c\u8fd9\u79cd\u7ed3\u6784\u53ef\u4ee5\u628a\u67e5\u8be2\u6240\u7528\u7684\u952e\u4e0e\u76f8\u5173\u7684\u503c\u5bf9\u5e94\u8d77\u6765\uff08\u6240\u4ee5\u4e5f\u53eb\u5173\u952e\u77e9\u9635\uff08associative array\uff09\u6216\u54c8\u5e0c\u8868\uff08hash table\uff09\uff09\u3002 \u5bf9\u4e8e\u5b57\u5178\u6765\u8bf4\uff0c\u8bbf\u95ee\u4e0e\u8d4b\u503c\u6240\u82b1\u7684\u65f6\u95f4\u5e73\u5747\u4e0b\u6765\u662f\u4e2a\u5e38\u91cf\uff0c\u6240\u4ee5\u8fd9\u79cd\u7ed3\u6784\u5f88\u9002\u5408\u4fdd\u5b58\u52a8\u6001\u7684\u4fe1\u606f\u3002","title":"\u7b2c11\u6761\u3000\u5b66\u4f1a\u5bf9\u5e8f\u5217\u505a\u5207\u7247"},{"location":"python/Pythonic90Rules/Rule12/","text":"","title":"\u7b2c12\u6761 \u4e0d\u8981\u5728\u5207\u7247\u91cc\u540c\u65f6\u6307\u5b9a\u8d77\u6b62\u4e0b\u6807\u4e0e\u6b65\u8fdb"},{"location":"python/Pythonic90Rules/Rule13/","text":"","title":"\u7b2c13\u6761 \u901a\u8fc7\u5e26\u661f\u53f7\u7684unpacking\u64cd\u4f5c\u6765\u6355\u83b7\u591a\u4e2a\u5143\u7d20,\u4e0d\u8981\u7528\u5207\u7247"},{"location":"python/Pythonic90Rules/Rule14/","text":"","title":"\u7b2c14\u6761 \u7528sort\u65b9\u6cd5\u7684key\u53c2\u6570\u6765\u8868\u793a\u590d\u6742\u7684\u6392\u5e8f\u903b\u8f91"},{"location":"python/Pythonic90Rules/Rule15/","text":"","title":"\u7b2c15\u6761 \u4e0d\u8981\u8fc7\u5206\u4f9d\u8d56\u7ed9\u5b57\u5178\u6dfb\u52a0\u6761\u76ee\u65f6\u6240\u7528\u7684\u987a\u5e8f"},{"location":"python/Pythonic90Rules/Rule16/","text":"","title":"\u7b2c16\u6761 \u7528get\u5904\u7406\u952e\u4e0d\u5728\u5b57\u5178\u4e2d\u7684\u60c5\u51b5,\u4e0d\u8981\u4f7f\u7528in\u4e0eKeyError"},{"location":"python/Pythonic90Rules/Rule17/","text":"","title":"\u7b2c17\u6761 \u7528defaultdict\u5904\u7406\u5185\u90e8\u72b6\u6001\u4e2d\u7f3a\u5931\u7684\u5143\u7d20,\u800c\u4e0d\u8981\u7528setdefault"},{"location":"python/Pythonic90Rules/Rule18/","text":"","title":"\u7b2c18\u6761 \u5b66\u4f1a\u5229\u7528__missing__\u6784\u9020\u4f9d\u8d56\u952e\u7684\u9ed8\u8ba4\u503c"},{"location":"python/Pythonic90Rules/Rule19/","text":"","title":"\u7b2c19\u6761 \u4e0d\u8981\u628a\u51fd\u6570\u8fd4\u56de\u7684\u591a\u4e2a\u6570\u503c\u62c6\u5206\u5230\u4e09\u4e2a\u4ee5\u4e0a\u7684\u53d8\u91cf\u4e2d"},{"location":"python/Pythonic90Rules/Rule20/","text":"","title":"\u7b2c20\u6761 \u9047\u5230\u610f\u5916\u72b6\u51b5\u65f6\u5e94\u8be5\u629b\u51fa\u5f02\u5e38,\u4e0d\u8981\u8fd4\u56deNone"},{"location":"python/Pythonic90Rules/Rule21/","text":"","title":"\u7b2c21\u6761 \u4e86\u89e3\u5982\u4f55\u5728\u95ed\u5305\u91cc\u9762\u4f7f\u7528\u5916\u56f4\u4f5c\u7528\u57df\u4e2d\u7684\u53d8\u91cf"},{"location":"python/Pythonic90Rules/Rule22/","text":"","title":"\u7b2c22\u6761 \u7528\u6570\u91cf\u53ef\u53d8\u7684\u4f4d\u7f6e\u53c2\u6570\u7ed9\u51fd\u6570\u8bbe\u8ba1\u6e05\u6670\u7684\u53c2\u6570\u5217\u8868"},{"location":"python/Pythonic90Rules/Rule23/","text":"","title":"\u7b2c23\u6761 \u7528\u5173\u952e\u5b57\u53c2\u6570\u6765\u8868\u793a\u53ef\u9009\u7684\u884c\u4e3a"},{"location":"python/Pythonic90Rules/Rule24/","text":"","title":"\u7b2c24\u6761 \u7528None\u548cdocstring\u6765\u63cf\u8ff0\u9ed8\u8ba4\u503c\u4f1a\u53d8\u7684\u53c2\u6570"},{"location":"python/Pythonic90Rules/Rule25/","text":"","title":"\u7b2c25\u6761 \u7528\u53ea\u80fd\u4ee5\u5173\u952e\u5b57\u6307\u5b9a\u548c\u53ea\u80fd\u6309\u4f4d\u7f6e\u4f20\u5165\u7684\u53c2\u6570\u6765\u8bbe\u8ba1\u6e05\u6670\u7684\u53c2\u6570\u5217\u8868"},{"location":"python/Pythonic90Rules/Rule26/","text":"","title":"\u7b2c26\u6761 \u7528functools.wraps\u5b9a\u4e49\u51fd\u6570\u4fee\u9970\u5668"},{"location":"python/Pythonic90Rules/Rule27/","text":"","title":"\u7b2c27\u6761 \u7528\u5217\u8868\u63a8\u5bfc\u53d6\u4ee3map\u4e0efilter"},{"location":"python/Pythonic90Rules/Rule28/","text":"","title":"\u7b2c28\u6761 \u63a7\u5236\u63a8\u5bfc\u903b\u8f91\u7684\u5b50\u8868\u8fbe\u5f0f\u4e0d\u8981\u8d85\u8fc7\u4e24\u4e2a"},{"location":"python/Pythonic90Rules/Rule29/","text":"","title":"\u7b2c29\u6761 \u7528\u8d4b\u503c\u8868\u8fbe\u5f0f\u6d88\u9664\u63a8\u5bfc\u4e2d\u7684\u91cd\u590d\u4ee3\u7801"},{"location":"python/Pythonic90Rules/Rule30/","text":"","title":"\u7b2c30\u6761 \u4e0d\u8981\u8ba9\u51fd\u6570\u76f4\u63a5\u8fd4\u56de\u5217\u8868\uff0c\u5e94\u8be5\u8ba9\u5b83\u9010\u4e2a\u751f\u6210\u5217\u8868\u91cc\u7684\u503c"},{"location":"python/Pythonic90Rules/Rule31/","text":"","title":"\u7b2c31\u6761 \u8c28\u614e\u5730\u8fed\u4ee3\u51fd\u6570\u6240\u6536\u5230\u7684\u53c2\u6570"},{"location":"python/Pythonic90Rules/Rule32/","text":"","title":"\u7b2c32\u6761 \u8003\u8651\u7528\u751f\u6210\u5668\u8868\u8fbe\u5f0f\u6539\u5199\u6570\u636e\u91cf\u8f83\u5927\u7684\u5217\u8868\u63a8\u5bfc"},{"location":"python/Pythonic90Rules/Rule33/","text":"","title":"\u7b2c33\u6761 \u901a\u8fc7yield from\u628a\u591a\u4e2a\u751f\u6210\u5668\u8fde\u8d77\u6765\u7528"},{"location":"python/Pythonic90Rules/Rule34/","text":"","title":"\u7b2c34\u6761 \u4e0d\u8981\u7528send\u7ed9\u751f\u6210\u5668\u6ce8\u5165\u6570\u636e"},{"location":"python/Pythonic90Rules/Rule35/","text":"","title":"\u7b2c35\u6761 \u4e0d\u8981\u901a\u8fc7throw\u53d8\u6362\u751f\u6210\u5668\u7684\u72b6\u6001"},{"location":"python/Pythonic90Rules/Rule36/","text":"","title":"\u7b2c36\u6761 \u8003\u8651\u7528itertools\u62fc\u88c5\u8fed\u4ee3\u5668\u4e0e\u751f\u6210\u5668"},{"location":"python/Pythonic90Rules/Rule37/","text":"","title":"\u7b2c37\u6761 \u7528\u7ec4\u5408\u8d77\u6765\u7684\u7c7b\u6765\u5b9e\u73b0\u591a\u5c42\u7ed3\u6784\uff0c\u4e0d\u8981\u7528\u5d4c\u5957\u7684\u5185\u7f6e\u7c7b\u578b"},{"location":"python/Pythonic90Rules/Rule38/","text":"","title":"\u7b2c38\u6761 \u8ba9\u7b80\u5355\u7684\u63a5\u53e3\u63a5\u53d7\u51fd\u6570\uff0c\u800c\u4e0d\u662f\u7c7b\u7684\u5b9e\u4f8b"},{"location":"python/Pythonic90Rules/Rule39/","text":"","title":"\u7b2c39\u6761 \u901a\u8fc7@classmethod\u591a\u6001\u6765\u6784\u9020\u540c\u4e00\u4f53\u7cfb\u4e2d\u7684\u5404\u7c7b\u5bf9\u8c61"},{"location":"python/Pythonic90Rules/Rule40/","text":"","title":"\u7b2c40\u6761 \u901a\u8fc7super\u521d\u59cb\u5316\u8d85\u7c7b"},{"location":"python/Pythonic90Rules/Rule41/","text":"","title":"\u7b2c41\u6761 \u8003\u8651\u7528mix-in\u7c7b\u6765\u8868\u793a\u53ef\u7ec4\u5408\u7684\u529f\u80fd"},{"location":"python/Pythonic90Rules/Rule42/","text":"","title":"\u7b2c42\u6761 \u4f18\u5148\u8003\u8651\u7528public\u5c5e\u6027\u8868\u793a\u5e94\u53d7\u4fdd\u62a4\u7684\u6570\u636e,\u4e0d\u8981\u7528private\u5c5e\u6027\u8868\u793a"},{"location":"python/Pythonic90Rules/Rule43/","text":"","title":"\u7b2c43\u6761 \u81ea\u5b9a\u4e49\u7684\u5bb9\u5668\u7c7b\u578b\u5e94\u8be5\u4ececollections.abc\u7ee7\u627f"},{"location":"python/Pythonic90Rules/Rule44/","text":"","title":"\u7b2c44\u6761 \u7528\u7eaf\u5c5e\u6027\u4e0e\u4fee\u9970\u5668\u53d6\u4ee3\u65e7\u5f0f\u7684setter\u4e0egetter\u65b9\u6cd5"},{"location":"python/Pythonic90Rules/Rule45/","text":"","title":"\u7b2c45\u6761 \u8003\u8651\u7528@property\u5b9e\u73b0\u65b0\u7684\u5c5e\u6027\u8bbf\u95ee\u903b\u8f91,\u4e0d\u8981\u6025\u7740\u91cd\u6784\u539f\u6709\u7684\u4ee3\u7801"},{"location":"python/Pythonic90Rules/Rule46/","text":"","title":"\u7b2c46\u6761 \u7528\u63cf\u8ff0\u7b26\u6765\u6539\u5199\u9700\u8981\u590d\u7528\u7684@property\u65b9\u6cd5"},{"location":"python/Pythonic90Rules/Rule47/","text":"","title":"\u7b2c47\u6761 \u9488\u5bf9\u60f0\u6027\u5c5e\u6027\u4f7f\u7528__getattr__\u3001__getattribute__\u53ca__setattr__"},{"location":"python/Pythonic90Rules/Rule48/","text":"","title":"\u7b2c48\u6761 \u7528__init_subclass__\u9a8c\u8bc1\u5b50\u7c7b\u5199\u5f97\u662f\u5426\u6b63\u786e"},{"location":"python/Pythonic90Rules/Rule49/","text":"","title":"\u7b2c49\u6761 \u7528__init_subclass__\u8bb0\u5f55\u73b0\u6709\u7684\u5b50\u7c7b"},{"location":"python/Pythonic90Rules/Rule50/","text":"","title":"\u7b2c50\u6761 \u7528__set_name__\u7ed9\u7c7b\u5c5e\u6027\u52a0\u6ce8\u89e3"},{"location":"python/Pythonic90Rules/Rule51/","text":"","title":"\u7b2c51\u6761 \u4f18\u5148\u8003\u8651\u901a\u8fc7\u7c7b\u4fee\u9970\u5668\u6765\u63d0\u4f9b\u53ef\u7ec4\u5408\u7684\u6269\u5145\u529f\u80fd\uff0c\u4e0d\u8981\u4f7f\u7528\u5143\u7c7b"},{"location":"python/Pythonic90Rules/Rule52/","text":"","title":"\u7b2c52\u6761 \u7528subprocess\u7ba1\u7406\u5b50\u8fdb\u7a0b"},{"location":"python/Pythonic90Rules/Rule53/","text":"","title":"\u7b2c53\u6761 \u53ef\u4ee5\u7528\u7ebf\u7a0b\u6267\u884c\u963b\u585e\u5f0fI/O,\u4f46\u4e0d\u8981\u7528\u5b83\u505a\u5e76\u884c\u8ba1\u7b97"},{"location":"python/Pythonic90Rules/Rule54/","text":"","title":"\u7b2c54\u6761 \u5229\u7528Lock\u9632\u6b62\u591a\u4e2a\u7ebf\u7a0b\u4e89\u7528\u540c\u4e00\u4efd\u6570\u636e"},{"location":"python/Pythonic90Rules/Rule55/","text":"","title":"\u7b2c55\u6761 \u7528Queue\u6765\u534f\u8c03\u5404\u7ebf\u7a0b\u4e4b\u95f4\u7684\u5de5\u4f5c\u8fdb\u5ea6"},{"location":"python/Pythonic90Rules/Rule56/","text":"","title":"\u7b2c56\u6761 \u5b66\u4f1a\u5224\u65ad\u4ec0\u4e48\u573a\u5408\u5fc5\u987b\u505a\u5e76\u53d1"},{"location":"python/Pythonic90Rules/Rule57/","text":"","title":"\u7b2c57\u6761 \u4e0d\u8981\u5728\u6bcf\u6b21fan-out\u65f6\u90fd\u65b0\u5efa\u4e00\u6279Thread\u5b9e\u4f8b"},{"location":"python/Pythonic90Rules/Rule58/","text":"","title":"\u7b2c58\u6761 \u5b66\u4f1a\u6b63\u786e\u5730\u91cd\u6784\u4ee3\u7801,\u4ee5\u4fbf\u7528Queue\u505a\u5e76\u53d1"},{"location":"python/Pythonic90Rules/Rule59/","text":"","title":"\u7b2c59\u6761 \u5982\u679c\u5fc5\u987b\u7528\u7ebf\u7a0b\u505a\u5e76\u53d1,\u90a3\u5c31\u8003\u8651\u901a\u8fc7ThreadPoolExecutor\u5b9e\u73b0"},{"location":"python/Pythonic90Rules/Rule60/","text":"","title":"\u7b2c60\u6761 \u7528\u534f\u7a0b\u5b9e\u73b0\u9ad8\u5e76\u53d1\u7684I/O"},{"location":"python/Pythonic90Rules/Rule61/","text":"","title":"\u7b2c61\u6761 \u5b66\u4f1a\u7528asyncio\u6539\u5199\u90a3\u4e9b\u901a\u8fc7\u7ebf\u7a0b\u5b9e\u73b0\u7684I/O"},{"location":"python/Pythonic90Rules/Rule62/","text":"","title":"\u7b2c62\u6761 \u7ed3\u5408\u7ebf\u7a0b\u4e0e\u534f\u7a0b,\u5c06\u4ee3\u7801\u987a\u5229\u8fc1\u79fb\u5230asyncio"},{"location":"python/Pythonic90Rules/Rule63/","text":"","title":"\u7b2c63\u6761 \u8ba9asyncio\u7684\u4e8b\u4ef6\u5faa\u73af\u4fdd\u6301\u7545\u901a,\u4ee5\u4fbf\u8fdb\u4e00\u6b65\u63d0\u5347\u7a0b\u5e8f\u7684\u54cd\u5e94\u80fd\u529b"},{"location":"python/Pythonic90Rules/Rule64/","text":"","title":"\u7b2c64\u6761 \u8003\u8651\u7528concurrent.futures\u5b9e\u73b0\u771f\u6b63\u7684\u5e76\u884c\u8ba1\u7b97"},{"location":"python/Pythonic90Rules/Rule65/","text":"","title":"\u7b2c65\u6761 \u5408\u7406\u5229\u7528try/except/else/finally\u7ed3\u6784\u4e2d\u7684\u6bcf\u4e2a\u4ee3\u7801\u5757"},{"location":"python/Pythonic90Rules/Rule66/","text":"","title":"\u7b2c66\u6761 \u8003\u8651\u7528contextlib\u548cwith\u8bed\u53e5\u6765\u6539\u5199\u53ef\u590d\u7528\u7684try/finally\u4ee3\u7801"},{"location":"python/Pythonic90Rules/Rule67/","text":"","title":"\u7b2c67\u6761 \u7528datetime\u6a21\u5757\u5904\u7406\u672c\u5730\u65f6\u95f4,\u4e0d\u8981\u7528time\u6a21\u5757"},{"location":"python/Pythonic90Rules/Rule68/","text":"","title":"\u7b2c68\u6761 \u7528copyreg\u5b9e\u73b0\u53ef\u9760\u7684pickle\u64cd\u4f5c"},{"location":"python/Pythonic90Rules/Rule69/","text":"","title":"\u7b2c69\u6761 \u5728\u9700\u8981\u51c6\u786e\u8ba1\u7b97\u7684\u573a\u5408,\u7528decimal\u8868\u793a\u76f8\u5e94\u7684\u6570\u503c"},{"location":"python/Pythonic90Rules/Rule70/","text":"","title":"\u7b2c70\u6761 \u5148\u5206\u6790\u6027\u80fd\uff0c\u7136\u540e\u518d\u4f18\u5316"},{"location":"python/Pythonic90Rules/Rule71/","text":"","title":"\u7b2c71\u6761 \u4f18\u5148\u8003\u8651\u7528deque\u5b9e\u73b0\u751f\u4ea7\u8005-\u6d88\u8d39\u8005\u961f\u5217"},{"location":"python/Pythonic90Rules/Rule72/","text":"","title":"\u7b2c72\u6761 \u8003\u8651\u7528bisect\u641c\u7d22\u5df2\u6392\u5e8f\u7684\u5e8f\u5217"},{"location":"python/Pythonic90Rules/Rule73/","text":"","title":"\u7b2c73\u6761 \u5b66\u4f1a\u4f7f\u7528heapq\u5236\u4f5c\u4f18\u5148\u7ea7\u961f\u5217"},{"location":"python/Pythonic90Rules/Rule74/","text":"","title":"\u7b2c74\u6761 \u8003\u8651\u7528memoryview\u4e0ebytearray\u6765\u5b9e\u73b0\u65e0\u987b\u62f7\u8d1d\u7684bytes\u64cd\u4f5c"},{"location":"python/Pythonic90Rules/Rule75/","text":"","title":"\u7b2c75\u6761 \u901a\u8fc7repr\u5b57\u7b26\u4e32\u8f93\u51fa\u8c03\u8bd5\u4fe1\u606f"},{"location":"python/Pythonic90Rules/Rule76/","text":"","title":"\u7b2c76\u6761 \u5728TestCase\u5b50\u7c7b\u91cc\u9a8c\u8bc1\u76f8\u5173\u7684\u884c\u4e3a"},{"location":"python/Pythonic90Rules/Rule77/","text":"","title":"\u7b2c77\u6761 \u628a\u6d4b\u8bd5\u524d\u3001\u540e\u7684\u51c6\u5907\u4e0e\u6e05\u7406\u903b\u8f91\u5199\u5728setUp\u3001tearDown\u3001setUpModule\u4e0etearDownModule\u4e2d,\u4ee5\u9632\u7528\u4f8b\u4e4b\u95f4\u4e92\u76f8\u5e72\u6270"},{"location":"python/Pythonic90Rules/Rule78/","text":"","title":"\u7b2c78\u6761 \u7528Mock\u6765\u6a21\u62df\u53d7\u6d4b\u4ee3\u7801\u6240\u4f9d\u8d56\u7684\u590d\u6742\u51fd\u6570"},{"location":"python/Pythonic90Rules/Rule79/","text":"","title":"\u7b2c79\u6761 \u628a\u53d7\u6d4b\u4ee3\u7801\u6240\u4f9d\u8d56\u7684\u7cfb\u7edf\u5c01\u88c5\u8d77\u6765\uff0c\u4ee5\u4fbf\u4e8e\u6a21\u62df\u548c\u6d4b\u8bd5"},{"location":"python/Pythonic90Rules/Rule80/","text":"","title":"\u7b2c80\u6761 \u8003\u8651\u7528pdb\u505a\u4ea4\u4e92\u8c03\u8bd5"},{"location":"python/Pythonic90Rules/Rule81/","text":"","title":"\u7b2c81\u6761 \u7528tracemalloc\u6765\u638c\u63e1\u5185\u5b58\u7684\u4f7f\u7528\u4e0e\u6cc4\u6f0f\u60c5\u51b5"},{"location":"python/Pythonic90Rules/Rule82/","text":"","title":"\u7b2c82\u6761 \u5b66\u4f1a\u5bfb\u627e\u7531\u5176\u4ed6Python\u5f00\u53d1\u8005\u6240\u6784\u5efa\u7684\u6a21\u5757"},{"location":"python/Pythonic90Rules/Rule83/","text":"","title":"\u7b2c83\u6761 \u7528\u865a\u62df\u73af\u5883\u9694\u79bb\u9879\u76ee,\u5e76\u91cd\u5efa\u4f9d\u8d56\u5173\u7cfb"},{"location":"python/Pythonic90Rules/Rule84/","text":"","title":"\u7b2c84\u6761 \u6bcf\u4e00\u4e2a\u51fd\u6570\u3001\u7c7b\u4e0e\u6a21\u5757\u90fd\u8981\u5199docstring"},{"location":"python/Pythonic90Rules/Rule85/","text":"","title":"\u7b2c85\u6761 \u7528\u5305\u6765\u5b89\u6392\u6a21\u5757,\u4ee5\u63d0\u4f9b\u7a33\u56fa\u7684API"},{"location":"python/Pythonic90Rules/Rule86/","text":"","title":"\u7b2c86\u6761 \u8003\u8651\u7528\u6a21\u5757\u7ea7\u522b\u7684\u4ee3\u7801\u914d\u7f6e\u4e0d\u540c\u7684\u90e8\u7f72\u73af\u5883"},{"location":"python/Pythonic90Rules/Rule87/","text":"","title":"\u7b2c87\u6761 \u4e3a\u81ea\u7f16\u7684\u6a21\u5757\u5b9a\u4e49\u6839\u5f02\u5e38,\u8ba9\u8c03\u7528\u8005\u80fd\u591f\u4e13\u95e8\u5904\u7406\u4e0e\u6b64API\u6709\u5173\u7684\u5f02\u5e38"},{"location":"python/Pythonic90Rules/Rule88/","text":"","title":"\u7b2c88\u6761 \u7528\u9002\u5f53\u7684\u65b9\u5f0f\u6253\u7834\u5faa\u73af\u4f9d\u8d56\u5173\u7cfb"},{"location":"python/Pythonic90Rules/Rule89/","text":"","title":"\u7b2c89\u6761 \u91cd\u6784\u65f6\u8003\u8651\u901a\u8fc7warnings\u63d0\u9192\u5f00\u53d1\u8005API\u5df2\u7ecf\u53d1\u751f\u53d8\u5316"},{"location":"python/Pythonic90Rules/Rule90/","text":"","title":"\u7b2c90\u6761 \u8003\u8651\u901a\u8fc7typing\u505a\u9759\u6001\u5206\u6790,\u4ee5\u6d88\u9664bug"}]} \ No newline at end of file +{"config":{"indexing":"full","lang":["en"],"min_search_length":3,"prebuild_index":false,"separator":"[\\s\\-]+"},"docs":[{"location":"","text":"\u77e5\u884c\u658b \u00b6 1.Linux \u00b6 1.1.Linux SRE \u00b6 \u7b2c\u4e00\u7ae0 Linux\u57fa\u7840 \u7b2c\u4e8c\u7ae0 \u6587\u4ef6\u7cfb\u7edf \u7b2c\u4e09\u7ae0 \u8eab\u4efd\u4e0e\u5b89\u5168 \u7b2c\u56db\u7ae0 \u6587\u672c\u7f16\u8f91 \u7b2c\u4e94\u7ae0 \u6b63\u5219\u8868\u8fbe\u5f0f \u7b2c\u516d\u7ae0 \u6587\u4ef6\u67e5\u627e \u7b2c\u4e03\u7ae0 \u6587\u4ef6\u6253\u5305\u548c\u89e3\u5305 1.2.SUSE Linux Administration \u00b6 Linux File System Overview Useful Commands Shell 1.3.SUSE Enterprise Storage Foundation \u00b6 SUSE Enterprise Storage Foundation SUSE Enterprise Storage Basic Operation 2.Kubernetes \u00b6 2.1.CKA Learning Memo \u00b6 Installation Single Node Installation Multiple Nodes Installation Installation on Aliyun ECS Docker Fundamentals Foundamentals Memo Overview kubectl basics Core Kubernetes Pod Deployment Service Application Modeling Namespace StatefulSet DaemonSet Job and Cronjob Configuration Secrets Persistence Role Based Access Control (RBAC) Ingress Advanced Kubernetes Scheduling Horizontal Pod Autoscaling Policy Network Policy Cluster Management Operating Kubernetes Troubleshooting Health Check Helming Topics Operations on Resources Health Check Calico Installation Kyma 2.2.CKA\u5b66\u4e60\u7b14\u8bb0 \u00b6 \u5b89\u88c5 \u5355\u8282\u70b9\u865a\u62df\u673a\u5b89\u88c5Kubernetes \u591a\u8282\u70b9\u865a\u62df\u673a\u5b89\u88c5Kubernetes \u963f\u91cc\u4e91ECS\u5b89\u88c5Kubernetes Docker Docker\u57fa\u7840 \u57fa\u7840\u77e5\u8bc6 Kubernetes\u968f\u7b14 Kubernetes\u96c6\u7fa4\u6982\u89c8 kubectl\u57fa\u7840 \u6838\u5fc3\u6982\u5ff5 Pod Deployment Service \u5e94\u7528\u4f53\u7cfb Namespace StatefulSet DaemonSet Job and Cronjob Configuration secrets Persistence RBAC\u9274\u6743 Ingress-nginx \u8fdb\u9636\u6982\u5ff5 Scheduling Horizontal Pod Autoscaling (HPA) Policy Network Policy Cluster Management \u65e5\u5e38\u7ef4\u62a4 Troubleshooting \u5065\u5eb7\u68c0\u67e5 Helm Chart \u4e3b\u9898\u8ba8\u8bba Kubernetes\u8d44\u6e90\u5e38\u89c1\u64cd\u4f5c \u5065\u5eb7\u68c0\u67e5 \u5b89\u88c5Calico Demos Build CAP Application on Kyma 3.Python \u00b6 3.1.Python\u57fa\u7840 \u00b6 Python\u5b89\u88c5 Python\u8bed\u8a00\u57fa\u7840 Python\u6253\u5305\u548c\u89e3\u5305 Python\u5185\u7f6e\u51fd\u6570\u53ca\u6587\u4ef6 Python\u9762\u5411\u5bf9\u8c61\u6982\u5ff5 Python\u9762\u5411\u5bf9\u8c61\u4e09\u5927\u7279\u6027 3.2.Python\u6570\u636e\u5206\u6790\u57fa\u7840 \u00b6 NumPy\u57fa\u7840 NumPy\u8fdb\u9636 Pandas\u5165\u95e8 \u6570\u636e\u8f7d\u5165\u3001\u5b58\u50a8\u53ca\u6587\u4ef6\u683c\u5f0f \u6570\u636e\u6e05\u6d17\u4e0e\u51c6\u5907 \u6570\u636e\u89c4\u6574\uff1a\u8fde\u63a5\u3001\u8054\u5408\u4e0e\u91cd\u5851 \u7ed8\u56fe\u4e0e\u53ef\u89c6\u5316 \u6570\u636e\u805a\u5408\u4e0e\u5206\u7ec4\u64cd\u4f5c \u65f6\u95f4\u5e8f\u5217 \u9ad8\u9636pandas Python\u5efa\u6a21\u5e93\u4ecb\u7ecd 3.3.\u6570\u636e\u7ed3\u6784\u548c\u7b97\u6cd5 \u00b6 1.\u57fa\u7840\u77e5\u8bc6\u56de\u987e 2.\u591a\u9879\u96c6\u7684\u6982\u8ff0 3.\u641c\u7d22\u3001\u6392\u5e8f\u4ee5\u53ca\u590d\u6742\u5ea6\u5206\u6790 4.\u6570\u7ec4\u548c\u94fe\u63a5\u7ed3\u6784 5.\u63a5\u53e3\u3001\u5b9e\u73b0\u548c\u591a\u6001 6.\u7ee7\u627f\u4e0e\u62bd\u8c61\u7c7b 3.5.Effective Python \u00b6 \u7b2c1\u7ae0\u3000\u57f9\u517bPythonic\u601d\u7ef4 \u7b2c1\u6761\u3000\u67e5\u8be2\u81ea\u5df1\u4f7f\u7528\u7684Python\u7248\u672c \u7b2c2\u6761\u3000\u9075\u5faaPEP 8\u98ce\u683c\u6307\u5357 \u7b2c3\u6761\u3000\u4e86\u89e3bytes\u4e0estr\u7684\u533a\u522b \u7b2c4\u6761\u3000\u7528\u652f\u6301\u63d2\u503c\u7684f-string\u53d6\u4ee3C\u98ce\u683c\u7684\u683c\u5f0f\u5b57\u7b26\u4e32\u4e0estr.format\u65b9\u6cd5 \u7b2c5\u6761\u3000\u7528\u8f85\u52a9\u51fd\u6570\u53d6\u4ee3\u590d\u6742\u7684\u8868\u8fbe\u5f0f \u7b2c6\u6761\u3000\u628a\u6570\u636e\u7ed3\u6784\u76f4\u63a5\u62c6\u5206\u5230\u591a\u4e2a\u53d8\u91cf\u91cc\uff0c\u4e0d\u8981\u4e13\u95e8\u901a\u8fc7\u4e0b\u6807\u8bbf\u95ee \u7b2c7\u6761\u3000\u5c3d\u91cf\u7528enumerate\u53d6\u4ee3range \u7b2c8\u6761\u3000\u7528zip\u51fd\u6570\u540c\u65f6\u904d\u5386\u4e24\u4e2a\u8fed\u4ee3\u5668 \u7b2c9\u6761\u3000\u4e0d\u8981\u5728for\u4e0ewhile\u5faa\u73af\u540e\u9762\u5199else\u5757 \u7b2c10\u6761\u3000\u7528\u8d4b\u503c\u8868\u8fbe\u5f0f\u51cf\u5c11\u91cd\u590d\u4ee3\u7801 \u7b2c2\u7ae0\u3000\u5217\u8868\u4e0e\u5b57\u5178 \u7b2c11\u6761\u3000\u5b66\u4f1a\u5bf9\u5e8f\u5217\u505a\u5207\u7247 \u7b2c12\u6761\u3000\u4e0d\u8981\u5728\u5207\u7247\u91cc\u540c\u65f6\u6307\u5b9a\u8d77\u6b62\u4e0b\u6807\u4e0e\u6b65\u8fdb \u7b2c13\u6761\u3000\u901a\u8fc7\u5e26\u661f\u53f7\u7684unpacking\u64cd\u4f5c\u6765\u6355\u83b7\u591a\u4e2a\u5143\u7d20\uff0c\u4e0d\u8981\u7528\u5207\u7247 \u7b2c14\u6761\u3000\u7528sort\u65b9\u6cd5\u7684key\u53c2\u6570\u6765\u8868\u793a\u590d\u6742\u7684\u6392\u5e8f\u903b\u8f91 \u7b2c15\u6761\u3000\u4e0d\u8981\u8fc7\u5206\u4f9d\u8d56\u7ed9\u5b57\u5178\u6dfb\u52a0\u6761\u76ee\u65f6\u6240\u7528\u7684\u987a\u5e8f \u7b2c16\u6761\u3000\u7528get\u5904\u7406\u952e\u4e0d\u5728\u5b57\u5178\u4e2d\u7684\u60c5\u51b5\uff0c\u4e0d\u8981\u4f7f\u7528in\u4e0eKeyError \u7b2c17\u6761\u3000\u7528defaultdict\u5904\u7406\u5185\u90e8\u72b6\u6001\u4e2d\u7f3a\u5931\u7684\u5143\u7d20\uff0c\u800c\u4e0d\u8981\u7528setdefault \u7b2c18\u6761\u3000\u5b66\u4f1a\u5229\u7528__missing__\u6784\u9020\u4f9d\u8d56\u952e\u7684\u9ed8\u8ba4\u503c \u7b2c3\u7ae0\u3000\u51fd\u6570 \u7b2c19\u6761\u3000\u4e0d\u8981\u628a\u51fd\u6570\u8fd4\u56de\u7684\u591a\u4e2a\u6570\u503c\u62c6\u5206\u5230\u4e09\u4e2a\u4ee5\u4e0a\u7684\u53d8\u91cf\u4e2d \u7b2c20\u6761\u3000\u9047\u5230\u610f\u5916\u72b6\u51b5\u65f6\u5e94\u8be5\u629b\u51fa\u5f02\u5e38\uff0c\u4e0d\u8981\u8fd4\u56deNone \u7b2c21\u6761\u3000\u4e86\u89e3\u5982\u4f55\u5728\u95ed\u5305\u91cc\u9762\u4f7f\u7528\u5916\u56f4\u4f5c\u7528\u57df\u4e2d\u7684\u53d8\u91cf \u7b2c22\u6761\u3000\u7528\u6570\u91cf\u53ef\u53d8\u7684\u4f4d\u7f6e\u53c2\u6570\u7ed9\u51fd\u6570\u8bbe\u8ba1\u6e05\u6670\u7684\u53c2\u6570\u5217\u8868 \u7b2c23\u6761\u3000\u7528\u5173\u952e\u5b57\u53c2\u6570\u6765\u8868\u793a\u53ef\u9009\u7684\u884c\u4e3a \u7b2c24\u6761\u3000\u7528None\u548cdocstring\u6765\u63cf\u8ff0\u9ed8\u8ba4\u503c\u4f1a\u53d8\u7684\u53c2\u6570 \u7b2c25\u6761\u3000\u7528\u53ea\u80fd\u4ee5\u5173\u952e\u5b57\u6307\u5b9a\u548c\u53ea\u80fd\u6309\u4f4d\u7f6e\u4f20\u5165\u7684\u53c2\u6570\u6765\u8bbe\u8ba1\u6e05\u6670\u7684\u53c2\u6570\u5217\u8868 \u7b2c26\u6761\u3000\u7528functools.wraps\u5b9a\u4e49\u51fd\u6570\u4fee\u9970\u5668 \u7b2c4\u7ae0\u3000\u63a8\u5bfc\u4e0e\u751f\u6210 \u7b2c27\u6761\u3000\u7528\u5217\u8868\u63a8\u5bfc\u53d6\u4ee3map\u4e0efilter \u7b2c28\u6761\u3000\u63a7\u5236\u63a8\u5bfc\u903b\u8f91\u7684\u5b50\u8868\u8fbe\u5f0f\u4e0d\u8981\u8d85\u8fc7\u4e24\u4e2a \u7b2c29\u6761\u3000\u7528\u8d4b\u503c\u8868\u8fbe\u5f0f\u6d88\u9664\u63a8\u5bfc\u4e2d\u7684\u91cd\u590d\u4ee3\u7801 \u7b2c30\u6761\u3000\u4e0d\u8981\u8ba9\u51fd\u6570\u76f4\u63a5\u8fd4\u56de\u5217\u8868\uff0c\u5e94\u8be5\u8ba9\u5b83\u9010\u4e2a\u751f\u6210\u5217\u8868\u91cc\u7684\u503c \u7b2c31\u6761\u3000\u8c28\u614e\u5730\u8fed\u4ee3\u51fd\u6570\u6240\u6536\u5230\u7684\u53c2\u6570 \u7b2c32\u6761\u3000\u8003\u8651\u7528\u751f\u6210\u5668\u8868\u8fbe\u5f0f\u6539\u5199\u6570\u636e\u91cf\u8f83\u5927\u7684\u5217\u8868\u63a8\u5bfc \u7b2c33\u6761\u3000\u901a\u8fc7yield from\u628a\u591a\u4e2a\u751f\u6210\u5668\u8fde\u8d77\u6765\u7528 \u7b2c34\u6761\u3000\u4e0d\u8981\u7528send\u7ed9\u751f\u6210\u5668\u6ce8\u5165\u6570\u636e \u7b2c35\u6761\u3000\u4e0d\u8981\u901a\u8fc7throw\u53d8\u6362\u751f\u6210\u5668\u7684\u72b6\u6001 \u7b2c36\u6761\u3000\u8003\u8651\u7528itertools\u62fc\u88c5\u8fed\u4ee3\u5668\u4e0e\u751f\u6210\u5668 \u7b2c5\u7ae0\u3000\u7c7b\u4e0e\u63a5\u53e3 \u7b2c37\u6761\u3000\u7528\u7ec4\u5408\u8d77\u6765\u7684\u7c7b\u6765\u5b9e\u73b0\u591a\u5c42\u7ed3\u6784\uff0c\u4e0d\u8981\u7528\u5d4c\u5957\u7684\u5185\u7f6e\u7c7b\u578b \u7b2c38\u6761\u3000\u8ba9\u7b80\u5355\u7684\u63a5\u53e3\u63a5\u53d7\u51fd\u6570\uff0c\u800c\u4e0d\u662f\u7c7b\u7684\u5b9e\u4f8b \u7b2c39\u6761\u3000\u901a\u8fc7@classmethod\u591a\u6001\u6765\u6784\u9020\u540c\u4e00\u4f53\u7cfb\u4e2d\u7684\u5404\u7c7b\u5bf9\u8c61 \u7b2c40\u6761\u3000\u901a\u8fc7super\u521d\u59cb\u5316\u8d85\u7c7b \u7b2c41\u6761\u3000\u8003\u8651\u7528mix-in\u7c7b\u6765\u8868\u793a\u53ef\u7ec4\u5408\u7684\u529f\u80fd \u7b2c42\u6761\u3000\u4f18\u5148\u8003\u8651\u7528public\u5c5e\u6027\u8868\u793a\u5e94\u53d7\u4fdd\u62a4\u7684\u6570\u636e\uff0c\u4e0d\u8981\u7528private\u5c5e\u6027\u8868\u793a \u7b2c43\u6761\u3000\u81ea\u5b9a\u4e49\u7684\u5bb9\u5668\u7c7b\u578b\u5e94\u8be5\u4ececollections.abc\u7ee7\u627f \u7b2c6\u7ae0\u3000\u5143\u7c7b\u4e0e\u5c5e\u6027 \u7b2c44\u6761\u3000\u7528\u7eaf\u5c5e\u6027\u4e0e\u4fee\u9970\u5668\u53d6\u4ee3\u65e7\u5f0f\u7684setter\u4e0egetter\u65b9\u6cd5 \u7b2c45\u6761\u3000\u8003\u8651\u7528@property\u5b9e\u73b0\u65b0\u7684\u5c5e\u6027\u8bbf\u95ee\u903b\u8f91\uff0c\u4e0d\u8981\u6025\u7740\u91cd\u6784\u539f\u6709\u7684\u4ee3\u7801 \u7b2c46\u6761\u3000\u7528\u63cf\u8ff0\u7b26\u6765\u6539\u5199\u9700\u8981\u590d\u7528\u7684@property\u65b9\u6cd5 \u7b2c47\u6761\u3000\u9488\u5bf9\u60f0\u6027\u5c5e\u6027\u4f7f\u7528__getattr__\u3001 getattribute__\u53ca__setattr \u7b2c48\u6761\u3000\u7528__init_subclass__\u9a8c\u8bc1\u5b50\u7c7b\u5199\u5f97\u662f\u5426\u6b63\u786e \u7b2c49\u6761\u3000\u7528__init_subclass__\u8bb0\u5f55\u73b0\u6709\u7684\u5b50\u7c7b \u7b2c50\u6761\u3000\u7528__set_name__\u7ed9\u7c7b\u5c5e\u6027\u52a0\u6ce8\u89e3 \u7b2c51\u6761\u3000\u4f18\u5148\u8003\u8651\u901a\u8fc7\u7c7b\u4fee\u9970\u5668\u6765\u63d0\u4f9b\u53ef\u7ec4\u5408\u7684\u6269\u5145\u529f\u80fd\uff0c\u4e0d\u8981\u4f7f\u7528\u5143\u7c7b \u7b2c7\u7ae0\u3000\u5e76\u53d1\u4e0e\u5e76\u884c \u7b2c52\u6761\u3000\u7528subprocess\u7ba1\u7406\u5b50\u8fdb\u7a0b \u7b2c53\u6761\u3000\u53ef\u4ee5\u7528\u7ebf\u7a0b\u6267\u884c\u963b\u585e\u5f0fI/O\uff0c\u4f46\u4e0d\u8981\u7528\u5b83\u505a\u5e76\u884c\u8ba1\u7b97 \u7b2c54\u6761\u3000\u5229\u7528Lock\u9632\u6b62\u591a\u4e2a\u7ebf\u7a0b\u4e89\u7528\u540c\u4e00\u4efd\u6570\u636e \u7b2c55\u6761\u3000\u7528Queue\u6765\u534f\u8c03\u5404\u7ebf\u7a0b\u4e4b\u95f4\u7684\u5de5\u4f5c\u8fdb\u5ea6 \u7b2c56\u6761\u3000\u5b66\u4f1a\u5224\u65ad\u4ec0\u4e48\u573a\u5408\u5fc5\u987b\u505a\u5e76\u53d1 \u7b2c57\u6761\u3000\u4e0d\u8981\u5728\u6bcf\u6b21fan-out\u65f6\u90fd\u65b0\u5efa\u4e00\u6279Thread\u5b9e\u4f8b \u7b2c58\u6761\u3000\u5b66\u4f1a\u6b63\u786e\u5730\u91cd\u6784\u4ee3\u7801\uff0c\u4ee5\u4fbf\u7528Queue\u505a\u5e76\u53d1 \u7b2c59\u6761\u3000\u5982\u679c\u5fc5\u987b\u7528\u7ebf\u7a0b\u505a\u5e76\u53d1\uff0c\u90a3\u5c31\u8003\u8651\u901a\u8fc7ThreadPoolExecutor\u5b9e\u73b0 \u7b2c60\u6761\u3000\u7528\u534f\u7a0b\u5b9e\u73b0\u9ad8\u5e76\u53d1\u7684I/O \u7b2c61\u6761\u3000\u5b66\u4f1a\u7528asyncio\u6539\u5199\u90a3\u4e9b\u901a\u8fc7\u7ebf\u7a0b\u5b9e\u73b0\u7684I/O \u7b2c62\u6761\u3000\u7ed3\u5408\u7ebf\u7a0b\u4e0e\u534f\u7a0b\uff0c\u5c06\u4ee3\u7801\u987a\u5229\u8fc1\u79fb\u5230asyncio \u7b2c63\u6761\u3000\u8ba9asyncio\u7684\u4e8b\u4ef6\u5faa\u73af\u4fdd\u6301\u7545\u901a\uff0c\u4ee5\u4fbf\u8fdb\u4e00\u6b65\u63d0\u5347\u7a0b\u5e8f\u7684\u54cd\u5e94\u80fd\u529b \u7b2c64\u6761\u3000\u8003\u8651\u7528concurrent.futures\u5b9e\u73b0\u771f\u6b63\u7684\u5e76\u884c\u8ba1\u7b97 \u7b2c8\u7ae0\u3000\u7a33\u5b9a\u4e0e\u6027\u80fd \u7b2c65\u6761\u3000\u5408\u7406\u5229\u7528try/except/else/finally\u7ed3\u6784\u4e2d\u7684\u6bcf\u4e2a\u4ee3\u7801\u5757 \u7b2c66\u6761\u3000\u8003\u8651\u7528contextlib\u548cwith\u8bed\u53e5\u6765\u6539\u5199\u53ef\u590d\u7528\u7684try/finally\u4ee3\u7801 \u7b2c67\u6761\u3000\u7528datetime\u6a21\u5757\u5904\u7406\u672c\u5730\u65f6\u95f4\uff0c\u4e0d\u8981\u7528time\u6a21\u5757 \u7b2c68\u6761\u3000\u7528copyreg\u5b9e\u73b0\u53ef\u9760\u7684pickle\u64cd\u4f5c \u7b2c69\u6761\u3000\u5728\u9700\u8981\u51c6\u786e\u8ba1\u7b97\u7684\u573a\u5408\uff0c\u7528decimal\u8868\u793a\u76f8\u5e94\u7684\u6570\u503c \u7b2c70\u6761\u3000\u5148\u5206\u6790\u6027\u80fd\uff0c\u7136\u540e\u518d\u4f18\u5316 \u7b2c71\u6761\u3000\u4f18\u5148\u8003\u8651\u7528deque\u5b9e\u73b0\u751f\u4ea7\u8005-\u6d88\u8d39\u8005\u961f\u5217 \u7b2c72\u6761\u3000\u8003\u8651\u7528bisect\u641c\u7d22\u5df2\u6392\u5e8f\u7684\u5e8f\u5217 \u7b2c73\u6761\u3000\u5b66\u4f1a\u4f7f\u7528heapq\u5236\u4f5c\u4f18\u5148\u7ea7\u961f\u5217 \u7b2c74\u6761\u3000\u8003\u8651\u7528memoryview\u4e0ebytearray\u6765\u5b9e\u73b0\u65e0\u987b\u62f7\u8d1d\u7684bytes\u64cd\u4f5c \u7b2c9\u7ae0\u3000\u6d4b\u8bd5\u4e0e\u8c03\u8bd5 \u7b2c75\u6761\u3000\u901a\u8fc7repr\u5b57\u7b26\u4e32\u8f93\u51fa\u8c03\u8bd5\u4fe1\u606f \u7b2c76\u6761\u3000\u5728TestCase\u5b50\u7c7b\u91cc\u9a8c\u8bc1\u76f8\u5173\u7684\u884c\u4e3a \u7b2c77\u6761\u3000\u628a\u6d4b\u8bd5\u524d\u3001\u540e\u7684\u51c6\u5907\u4e0e\u6e05\u7406\u903b\u8f91\u5199\u5728setUp\u3001tearDown\u3001setUpModule\u4e0etearDownModule\u4e2d\uff0c\u4ee5\u9632\u7528\u4f8b\u4e4b\u95f4\u4e92\u76f8\u5e72\u6270 \u7b2c78\u6761\u3000\u7528Mock\u6765\u6a21\u62df\u53d7\u6d4b\u4ee3\u7801\u6240\u4f9d\u8d56\u7684\u590d\u6742\u51fd\u6570 \u7b2c79\u6761\u3000\u628a\u53d7\u6d4b\u4ee3\u7801\u6240\u4f9d\u8d56\u7684\u7cfb\u7edf\u5c01\u88c5\u8d77\u6765\uff0c\u4ee5\u4fbf\u4e8e\u6a21\u62df\u548c\u6d4b\u8bd5 \u7b2c80\u6761\u3000\u8003\u8651\u7528pdb\u505a\u4ea4\u4e92\u8c03\u8bd5 \u7b2c81\u6761\u3000\u7528tracemalloc\u6765\u638c\u63e1\u5185\u5b58\u7684\u4f7f\u7528\u4e0e\u6cc4\u6f0f\u60c5\u51b5 \u7b2c10\u7ae0\u3000\u534f\u4f5c\u5f00\u53d1 \u7b2c82\u6761\u3000\u5b66\u4f1a\u5bfb\u627e\u7531\u5176\u4ed6Python\u5f00\u53d1\u8005\u6240\u6784\u5efa\u7684\u6a21\u5757 \u7b2c83\u6761\u3000\u7528\u865a\u62df\u73af\u5883\u9694\u79bb\u9879\u76ee\uff0c\u5e76\u91cd\u5efa\u4f9d\u8d56\u5173\u7cfb \u7b2c84\u6761\u3000\u6bcf\u4e00\u4e2a\u51fd\u6570\u3001\u7c7b\u4e0e\u6a21\u5757\u90fd\u8981\u5199docstring \u7b2c85\u6761\u3000\u7528\u5305\u6765\u5b89\u6392\u6a21\u5757\uff0c\u4ee5\u63d0\u4f9b\u7a33\u56fa\u7684API \u7b2c86\u6761\u3000\u8003\u8651\u7528\u6a21\u5757\u7ea7\u522b\u7684\u4ee3\u7801\u914d\u7f6e\u4e0d\u540c\u7684\u90e8\u7f72\u73af\u5883 \u7b2c87\u6761\u3000\u4e3a\u81ea\u7f16\u7684\u6a21\u5757\u5b9a\u4e49\u6839\u5f02\u5e38\uff0c\u8ba9\u8c03\u7528\u8005\u80fd\u591f\u4e13\u95e8\u5904\u7406\u4e0e\u6b64API\u6709\u5173\u7684\u5f02\u5e38 \u7b2c88\u6761\u3000\u7528\u9002\u5f53\u7684\u65b9\u5f0f\u6253\u7834\u5faa\u73af\u4f9d\u8d56\u5173\u7cfb \u7b2c89\u6761\u3000\u91cd\u6784\u65f6\u8003\u8651\u901a\u8fc7warnings\u63d0\u9192\u5f00\u53d1\u8005API\u5df2\u7ecf\u53d1\u751f\u53d8\u5316 \u7b2c90\u6761\u3000\u8003\u8651\u901a\u8fc7typing\u505a\u9759\u6001\u5206\u6790\uff0c\u4ee5\u6d88\u9664bug 3.5.Demos \u00b6 \u9009\u8bfe\u7cfb\u7edf 4. \u8bfb\u4e66\u6709\u611f \u00b6 \u7ea6\u7ff0\u00b7\u68ee\u6885\u5179\u76842\u672c\u4e66","title":"Index"},{"location":"#_1","text":"","title":"\u77e5\u884c\u658b"},{"location":"#1linux","text":"","title":"1.Linux"},{"location":"#11linux-sre","text":"\u7b2c\u4e00\u7ae0 Linux\u57fa\u7840 \u7b2c\u4e8c\u7ae0 \u6587\u4ef6\u7cfb\u7edf \u7b2c\u4e09\u7ae0 \u8eab\u4efd\u4e0e\u5b89\u5168 \u7b2c\u56db\u7ae0 \u6587\u672c\u7f16\u8f91 \u7b2c\u4e94\u7ae0 \u6b63\u5219\u8868\u8fbe\u5f0f \u7b2c\u516d\u7ae0 \u6587\u4ef6\u67e5\u627e \u7b2c\u4e03\u7ae0 \u6587\u4ef6\u6253\u5305\u548c\u89e3\u5305","title":"1.1.Linux SRE"},{"location":"#12suse-linux-administration","text":"Linux File System Overview Useful Commands Shell","title":"1.2.SUSE Linux Administration"},{"location":"#13suse-enterprise-storage-foundation","text":"SUSE Enterprise Storage Foundation SUSE Enterprise Storage Basic Operation","title":"1.3.SUSE Enterprise Storage Foundation"},{"location":"#2kubernetes","text":"","title":"2.Kubernetes"},{"location":"#21cka-learning-memo","text":"Installation Single Node Installation Multiple Nodes Installation Installation on Aliyun ECS Docker Fundamentals Foundamentals Memo Overview kubectl basics Core Kubernetes Pod Deployment Service Application Modeling Namespace StatefulSet DaemonSet Job and Cronjob Configuration Secrets Persistence Role Based Access Control (RBAC) Ingress Advanced Kubernetes Scheduling Horizontal Pod Autoscaling Policy Network Policy Cluster Management Operating Kubernetes Troubleshooting Health Check Helming Topics Operations on Resources Health Check Calico Installation Kyma","title":"2.1.CKA Learning Memo"},{"location":"#22cka","text":"\u5b89\u88c5 \u5355\u8282\u70b9\u865a\u62df\u673a\u5b89\u88c5Kubernetes \u591a\u8282\u70b9\u865a\u62df\u673a\u5b89\u88c5Kubernetes \u963f\u91cc\u4e91ECS\u5b89\u88c5Kubernetes Docker Docker\u57fa\u7840 \u57fa\u7840\u77e5\u8bc6 Kubernetes\u968f\u7b14 Kubernetes\u96c6\u7fa4\u6982\u89c8 kubectl\u57fa\u7840 \u6838\u5fc3\u6982\u5ff5 Pod Deployment Service \u5e94\u7528\u4f53\u7cfb Namespace StatefulSet DaemonSet Job and Cronjob Configuration secrets Persistence RBAC\u9274\u6743 Ingress-nginx \u8fdb\u9636\u6982\u5ff5 Scheduling Horizontal Pod Autoscaling (HPA) Policy Network Policy Cluster Management \u65e5\u5e38\u7ef4\u62a4 Troubleshooting \u5065\u5eb7\u68c0\u67e5 Helm Chart \u4e3b\u9898\u8ba8\u8bba Kubernetes\u8d44\u6e90\u5e38\u89c1\u64cd\u4f5c \u5065\u5eb7\u68c0\u67e5 \u5b89\u88c5Calico Demos Build CAP Application on Kyma","title":"2.2.CKA\u5b66\u4e60\u7b14\u8bb0"},{"location":"#3python","text":"","title":"3.Python"},{"location":"#31python","text":"Python\u5b89\u88c5 Python\u8bed\u8a00\u57fa\u7840 Python\u6253\u5305\u548c\u89e3\u5305 Python\u5185\u7f6e\u51fd\u6570\u53ca\u6587\u4ef6 Python\u9762\u5411\u5bf9\u8c61\u6982\u5ff5 Python\u9762\u5411\u5bf9\u8c61\u4e09\u5927\u7279\u6027","title":"3.1.Python\u57fa\u7840"},{"location":"#32python","text":"NumPy\u57fa\u7840 NumPy\u8fdb\u9636 Pandas\u5165\u95e8 \u6570\u636e\u8f7d\u5165\u3001\u5b58\u50a8\u53ca\u6587\u4ef6\u683c\u5f0f \u6570\u636e\u6e05\u6d17\u4e0e\u51c6\u5907 \u6570\u636e\u89c4\u6574\uff1a\u8fde\u63a5\u3001\u8054\u5408\u4e0e\u91cd\u5851 \u7ed8\u56fe\u4e0e\u53ef\u89c6\u5316 \u6570\u636e\u805a\u5408\u4e0e\u5206\u7ec4\u64cd\u4f5c \u65f6\u95f4\u5e8f\u5217 \u9ad8\u9636pandas Python\u5efa\u6a21\u5e93\u4ecb\u7ecd","title":"3.2.Python\u6570\u636e\u5206\u6790\u57fa\u7840"},{"location":"#33","text":"1.\u57fa\u7840\u77e5\u8bc6\u56de\u987e 2.\u591a\u9879\u96c6\u7684\u6982\u8ff0 3.\u641c\u7d22\u3001\u6392\u5e8f\u4ee5\u53ca\u590d\u6742\u5ea6\u5206\u6790 4.\u6570\u7ec4\u548c\u94fe\u63a5\u7ed3\u6784 5.\u63a5\u53e3\u3001\u5b9e\u73b0\u548c\u591a\u6001 6.\u7ee7\u627f\u4e0e\u62bd\u8c61\u7c7b","title":"3.3.\u6570\u636e\u7ed3\u6784\u548c\u7b97\u6cd5"},{"location":"#35effective-python","text":"\u7b2c1\u7ae0\u3000\u57f9\u517bPythonic\u601d\u7ef4 \u7b2c1\u6761\u3000\u67e5\u8be2\u81ea\u5df1\u4f7f\u7528\u7684Python\u7248\u672c \u7b2c2\u6761\u3000\u9075\u5faaPEP 8\u98ce\u683c\u6307\u5357 \u7b2c3\u6761\u3000\u4e86\u89e3bytes\u4e0estr\u7684\u533a\u522b \u7b2c4\u6761\u3000\u7528\u652f\u6301\u63d2\u503c\u7684f-string\u53d6\u4ee3C\u98ce\u683c\u7684\u683c\u5f0f\u5b57\u7b26\u4e32\u4e0estr.format\u65b9\u6cd5 \u7b2c5\u6761\u3000\u7528\u8f85\u52a9\u51fd\u6570\u53d6\u4ee3\u590d\u6742\u7684\u8868\u8fbe\u5f0f \u7b2c6\u6761\u3000\u628a\u6570\u636e\u7ed3\u6784\u76f4\u63a5\u62c6\u5206\u5230\u591a\u4e2a\u53d8\u91cf\u91cc\uff0c\u4e0d\u8981\u4e13\u95e8\u901a\u8fc7\u4e0b\u6807\u8bbf\u95ee \u7b2c7\u6761\u3000\u5c3d\u91cf\u7528enumerate\u53d6\u4ee3range \u7b2c8\u6761\u3000\u7528zip\u51fd\u6570\u540c\u65f6\u904d\u5386\u4e24\u4e2a\u8fed\u4ee3\u5668 \u7b2c9\u6761\u3000\u4e0d\u8981\u5728for\u4e0ewhile\u5faa\u73af\u540e\u9762\u5199else\u5757 \u7b2c10\u6761\u3000\u7528\u8d4b\u503c\u8868\u8fbe\u5f0f\u51cf\u5c11\u91cd\u590d\u4ee3\u7801 \u7b2c2\u7ae0\u3000\u5217\u8868\u4e0e\u5b57\u5178 \u7b2c11\u6761\u3000\u5b66\u4f1a\u5bf9\u5e8f\u5217\u505a\u5207\u7247 \u7b2c12\u6761\u3000\u4e0d\u8981\u5728\u5207\u7247\u91cc\u540c\u65f6\u6307\u5b9a\u8d77\u6b62\u4e0b\u6807\u4e0e\u6b65\u8fdb \u7b2c13\u6761\u3000\u901a\u8fc7\u5e26\u661f\u53f7\u7684unpacking\u64cd\u4f5c\u6765\u6355\u83b7\u591a\u4e2a\u5143\u7d20\uff0c\u4e0d\u8981\u7528\u5207\u7247 \u7b2c14\u6761\u3000\u7528sort\u65b9\u6cd5\u7684key\u53c2\u6570\u6765\u8868\u793a\u590d\u6742\u7684\u6392\u5e8f\u903b\u8f91 \u7b2c15\u6761\u3000\u4e0d\u8981\u8fc7\u5206\u4f9d\u8d56\u7ed9\u5b57\u5178\u6dfb\u52a0\u6761\u76ee\u65f6\u6240\u7528\u7684\u987a\u5e8f \u7b2c16\u6761\u3000\u7528get\u5904\u7406\u952e\u4e0d\u5728\u5b57\u5178\u4e2d\u7684\u60c5\u51b5\uff0c\u4e0d\u8981\u4f7f\u7528in\u4e0eKeyError \u7b2c17\u6761\u3000\u7528defaultdict\u5904\u7406\u5185\u90e8\u72b6\u6001\u4e2d\u7f3a\u5931\u7684\u5143\u7d20\uff0c\u800c\u4e0d\u8981\u7528setdefault \u7b2c18\u6761\u3000\u5b66\u4f1a\u5229\u7528__missing__\u6784\u9020\u4f9d\u8d56\u952e\u7684\u9ed8\u8ba4\u503c \u7b2c3\u7ae0\u3000\u51fd\u6570 \u7b2c19\u6761\u3000\u4e0d\u8981\u628a\u51fd\u6570\u8fd4\u56de\u7684\u591a\u4e2a\u6570\u503c\u62c6\u5206\u5230\u4e09\u4e2a\u4ee5\u4e0a\u7684\u53d8\u91cf\u4e2d \u7b2c20\u6761\u3000\u9047\u5230\u610f\u5916\u72b6\u51b5\u65f6\u5e94\u8be5\u629b\u51fa\u5f02\u5e38\uff0c\u4e0d\u8981\u8fd4\u56deNone \u7b2c21\u6761\u3000\u4e86\u89e3\u5982\u4f55\u5728\u95ed\u5305\u91cc\u9762\u4f7f\u7528\u5916\u56f4\u4f5c\u7528\u57df\u4e2d\u7684\u53d8\u91cf \u7b2c22\u6761\u3000\u7528\u6570\u91cf\u53ef\u53d8\u7684\u4f4d\u7f6e\u53c2\u6570\u7ed9\u51fd\u6570\u8bbe\u8ba1\u6e05\u6670\u7684\u53c2\u6570\u5217\u8868 \u7b2c23\u6761\u3000\u7528\u5173\u952e\u5b57\u53c2\u6570\u6765\u8868\u793a\u53ef\u9009\u7684\u884c\u4e3a \u7b2c24\u6761\u3000\u7528None\u548cdocstring\u6765\u63cf\u8ff0\u9ed8\u8ba4\u503c\u4f1a\u53d8\u7684\u53c2\u6570 \u7b2c25\u6761\u3000\u7528\u53ea\u80fd\u4ee5\u5173\u952e\u5b57\u6307\u5b9a\u548c\u53ea\u80fd\u6309\u4f4d\u7f6e\u4f20\u5165\u7684\u53c2\u6570\u6765\u8bbe\u8ba1\u6e05\u6670\u7684\u53c2\u6570\u5217\u8868 \u7b2c26\u6761\u3000\u7528functools.wraps\u5b9a\u4e49\u51fd\u6570\u4fee\u9970\u5668 \u7b2c4\u7ae0\u3000\u63a8\u5bfc\u4e0e\u751f\u6210 \u7b2c27\u6761\u3000\u7528\u5217\u8868\u63a8\u5bfc\u53d6\u4ee3map\u4e0efilter \u7b2c28\u6761\u3000\u63a7\u5236\u63a8\u5bfc\u903b\u8f91\u7684\u5b50\u8868\u8fbe\u5f0f\u4e0d\u8981\u8d85\u8fc7\u4e24\u4e2a \u7b2c29\u6761\u3000\u7528\u8d4b\u503c\u8868\u8fbe\u5f0f\u6d88\u9664\u63a8\u5bfc\u4e2d\u7684\u91cd\u590d\u4ee3\u7801 \u7b2c30\u6761\u3000\u4e0d\u8981\u8ba9\u51fd\u6570\u76f4\u63a5\u8fd4\u56de\u5217\u8868\uff0c\u5e94\u8be5\u8ba9\u5b83\u9010\u4e2a\u751f\u6210\u5217\u8868\u91cc\u7684\u503c \u7b2c31\u6761\u3000\u8c28\u614e\u5730\u8fed\u4ee3\u51fd\u6570\u6240\u6536\u5230\u7684\u53c2\u6570 \u7b2c32\u6761\u3000\u8003\u8651\u7528\u751f\u6210\u5668\u8868\u8fbe\u5f0f\u6539\u5199\u6570\u636e\u91cf\u8f83\u5927\u7684\u5217\u8868\u63a8\u5bfc \u7b2c33\u6761\u3000\u901a\u8fc7yield from\u628a\u591a\u4e2a\u751f\u6210\u5668\u8fde\u8d77\u6765\u7528 \u7b2c34\u6761\u3000\u4e0d\u8981\u7528send\u7ed9\u751f\u6210\u5668\u6ce8\u5165\u6570\u636e \u7b2c35\u6761\u3000\u4e0d\u8981\u901a\u8fc7throw\u53d8\u6362\u751f\u6210\u5668\u7684\u72b6\u6001 \u7b2c36\u6761\u3000\u8003\u8651\u7528itertools\u62fc\u88c5\u8fed\u4ee3\u5668\u4e0e\u751f\u6210\u5668 \u7b2c5\u7ae0\u3000\u7c7b\u4e0e\u63a5\u53e3 \u7b2c37\u6761\u3000\u7528\u7ec4\u5408\u8d77\u6765\u7684\u7c7b\u6765\u5b9e\u73b0\u591a\u5c42\u7ed3\u6784\uff0c\u4e0d\u8981\u7528\u5d4c\u5957\u7684\u5185\u7f6e\u7c7b\u578b \u7b2c38\u6761\u3000\u8ba9\u7b80\u5355\u7684\u63a5\u53e3\u63a5\u53d7\u51fd\u6570\uff0c\u800c\u4e0d\u662f\u7c7b\u7684\u5b9e\u4f8b \u7b2c39\u6761\u3000\u901a\u8fc7@classmethod\u591a\u6001\u6765\u6784\u9020\u540c\u4e00\u4f53\u7cfb\u4e2d\u7684\u5404\u7c7b\u5bf9\u8c61 \u7b2c40\u6761\u3000\u901a\u8fc7super\u521d\u59cb\u5316\u8d85\u7c7b \u7b2c41\u6761\u3000\u8003\u8651\u7528mix-in\u7c7b\u6765\u8868\u793a\u53ef\u7ec4\u5408\u7684\u529f\u80fd \u7b2c42\u6761\u3000\u4f18\u5148\u8003\u8651\u7528public\u5c5e\u6027\u8868\u793a\u5e94\u53d7\u4fdd\u62a4\u7684\u6570\u636e\uff0c\u4e0d\u8981\u7528private\u5c5e\u6027\u8868\u793a \u7b2c43\u6761\u3000\u81ea\u5b9a\u4e49\u7684\u5bb9\u5668\u7c7b\u578b\u5e94\u8be5\u4ececollections.abc\u7ee7\u627f \u7b2c6\u7ae0\u3000\u5143\u7c7b\u4e0e\u5c5e\u6027 \u7b2c44\u6761\u3000\u7528\u7eaf\u5c5e\u6027\u4e0e\u4fee\u9970\u5668\u53d6\u4ee3\u65e7\u5f0f\u7684setter\u4e0egetter\u65b9\u6cd5 \u7b2c45\u6761\u3000\u8003\u8651\u7528@property\u5b9e\u73b0\u65b0\u7684\u5c5e\u6027\u8bbf\u95ee\u903b\u8f91\uff0c\u4e0d\u8981\u6025\u7740\u91cd\u6784\u539f\u6709\u7684\u4ee3\u7801 \u7b2c46\u6761\u3000\u7528\u63cf\u8ff0\u7b26\u6765\u6539\u5199\u9700\u8981\u590d\u7528\u7684@property\u65b9\u6cd5 \u7b2c47\u6761\u3000\u9488\u5bf9\u60f0\u6027\u5c5e\u6027\u4f7f\u7528__getattr__\u3001 getattribute__\u53ca__setattr \u7b2c48\u6761\u3000\u7528__init_subclass__\u9a8c\u8bc1\u5b50\u7c7b\u5199\u5f97\u662f\u5426\u6b63\u786e \u7b2c49\u6761\u3000\u7528__init_subclass__\u8bb0\u5f55\u73b0\u6709\u7684\u5b50\u7c7b \u7b2c50\u6761\u3000\u7528__set_name__\u7ed9\u7c7b\u5c5e\u6027\u52a0\u6ce8\u89e3 \u7b2c51\u6761\u3000\u4f18\u5148\u8003\u8651\u901a\u8fc7\u7c7b\u4fee\u9970\u5668\u6765\u63d0\u4f9b\u53ef\u7ec4\u5408\u7684\u6269\u5145\u529f\u80fd\uff0c\u4e0d\u8981\u4f7f\u7528\u5143\u7c7b \u7b2c7\u7ae0\u3000\u5e76\u53d1\u4e0e\u5e76\u884c \u7b2c52\u6761\u3000\u7528subprocess\u7ba1\u7406\u5b50\u8fdb\u7a0b \u7b2c53\u6761\u3000\u53ef\u4ee5\u7528\u7ebf\u7a0b\u6267\u884c\u963b\u585e\u5f0fI/O\uff0c\u4f46\u4e0d\u8981\u7528\u5b83\u505a\u5e76\u884c\u8ba1\u7b97 \u7b2c54\u6761\u3000\u5229\u7528Lock\u9632\u6b62\u591a\u4e2a\u7ebf\u7a0b\u4e89\u7528\u540c\u4e00\u4efd\u6570\u636e \u7b2c55\u6761\u3000\u7528Queue\u6765\u534f\u8c03\u5404\u7ebf\u7a0b\u4e4b\u95f4\u7684\u5de5\u4f5c\u8fdb\u5ea6 \u7b2c56\u6761\u3000\u5b66\u4f1a\u5224\u65ad\u4ec0\u4e48\u573a\u5408\u5fc5\u987b\u505a\u5e76\u53d1 \u7b2c57\u6761\u3000\u4e0d\u8981\u5728\u6bcf\u6b21fan-out\u65f6\u90fd\u65b0\u5efa\u4e00\u6279Thread\u5b9e\u4f8b \u7b2c58\u6761\u3000\u5b66\u4f1a\u6b63\u786e\u5730\u91cd\u6784\u4ee3\u7801\uff0c\u4ee5\u4fbf\u7528Queue\u505a\u5e76\u53d1 \u7b2c59\u6761\u3000\u5982\u679c\u5fc5\u987b\u7528\u7ebf\u7a0b\u505a\u5e76\u53d1\uff0c\u90a3\u5c31\u8003\u8651\u901a\u8fc7ThreadPoolExecutor\u5b9e\u73b0 \u7b2c60\u6761\u3000\u7528\u534f\u7a0b\u5b9e\u73b0\u9ad8\u5e76\u53d1\u7684I/O \u7b2c61\u6761\u3000\u5b66\u4f1a\u7528asyncio\u6539\u5199\u90a3\u4e9b\u901a\u8fc7\u7ebf\u7a0b\u5b9e\u73b0\u7684I/O \u7b2c62\u6761\u3000\u7ed3\u5408\u7ebf\u7a0b\u4e0e\u534f\u7a0b\uff0c\u5c06\u4ee3\u7801\u987a\u5229\u8fc1\u79fb\u5230asyncio \u7b2c63\u6761\u3000\u8ba9asyncio\u7684\u4e8b\u4ef6\u5faa\u73af\u4fdd\u6301\u7545\u901a\uff0c\u4ee5\u4fbf\u8fdb\u4e00\u6b65\u63d0\u5347\u7a0b\u5e8f\u7684\u54cd\u5e94\u80fd\u529b \u7b2c64\u6761\u3000\u8003\u8651\u7528concurrent.futures\u5b9e\u73b0\u771f\u6b63\u7684\u5e76\u884c\u8ba1\u7b97 \u7b2c8\u7ae0\u3000\u7a33\u5b9a\u4e0e\u6027\u80fd \u7b2c65\u6761\u3000\u5408\u7406\u5229\u7528try/except/else/finally\u7ed3\u6784\u4e2d\u7684\u6bcf\u4e2a\u4ee3\u7801\u5757 \u7b2c66\u6761\u3000\u8003\u8651\u7528contextlib\u548cwith\u8bed\u53e5\u6765\u6539\u5199\u53ef\u590d\u7528\u7684try/finally\u4ee3\u7801 \u7b2c67\u6761\u3000\u7528datetime\u6a21\u5757\u5904\u7406\u672c\u5730\u65f6\u95f4\uff0c\u4e0d\u8981\u7528time\u6a21\u5757 \u7b2c68\u6761\u3000\u7528copyreg\u5b9e\u73b0\u53ef\u9760\u7684pickle\u64cd\u4f5c \u7b2c69\u6761\u3000\u5728\u9700\u8981\u51c6\u786e\u8ba1\u7b97\u7684\u573a\u5408\uff0c\u7528decimal\u8868\u793a\u76f8\u5e94\u7684\u6570\u503c \u7b2c70\u6761\u3000\u5148\u5206\u6790\u6027\u80fd\uff0c\u7136\u540e\u518d\u4f18\u5316 \u7b2c71\u6761\u3000\u4f18\u5148\u8003\u8651\u7528deque\u5b9e\u73b0\u751f\u4ea7\u8005-\u6d88\u8d39\u8005\u961f\u5217 \u7b2c72\u6761\u3000\u8003\u8651\u7528bisect\u641c\u7d22\u5df2\u6392\u5e8f\u7684\u5e8f\u5217 \u7b2c73\u6761\u3000\u5b66\u4f1a\u4f7f\u7528heapq\u5236\u4f5c\u4f18\u5148\u7ea7\u961f\u5217 \u7b2c74\u6761\u3000\u8003\u8651\u7528memoryview\u4e0ebytearray\u6765\u5b9e\u73b0\u65e0\u987b\u62f7\u8d1d\u7684bytes\u64cd\u4f5c \u7b2c9\u7ae0\u3000\u6d4b\u8bd5\u4e0e\u8c03\u8bd5 \u7b2c75\u6761\u3000\u901a\u8fc7repr\u5b57\u7b26\u4e32\u8f93\u51fa\u8c03\u8bd5\u4fe1\u606f \u7b2c76\u6761\u3000\u5728TestCase\u5b50\u7c7b\u91cc\u9a8c\u8bc1\u76f8\u5173\u7684\u884c\u4e3a \u7b2c77\u6761\u3000\u628a\u6d4b\u8bd5\u524d\u3001\u540e\u7684\u51c6\u5907\u4e0e\u6e05\u7406\u903b\u8f91\u5199\u5728setUp\u3001tearDown\u3001setUpModule\u4e0etearDownModule\u4e2d\uff0c\u4ee5\u9632\u7528\u4f8b\u4e4b\u95f4\u4e92\u76f8\u5e72\u6270 \u7b2c78\u6761\u3000\u7528Mock\u6765\u6a21\u62df\u53d7\u6d4b\u4ee3\u7801\u6240\u4f9d\u8d56\u7684\u590d\u6742\u51fd\u6570 \u7b2c79\u6761\u3000\u628a\u53d7\u6d4b\u4ee3\u7801\u6240\u4f9d\u8d56\u7684\u7cfb\u7edf\u5c01\u88c5\u8d77\u6765\uff0c\u4ee5\u4fbf\u4e8e\u6a21\u62df\u548c\u6d4b\u8bd5 \u7b2c80\u6761\u3000\u8003\u8651\u7528pdb\u505a\u4ea4\u4e92\u8c03\u8bd5 \u7b2c81\u6761\u3000\u7528tracemalloc\u6765\u638c\u63e1\u5185\u5b58\u7684\u4f7f\u7528\u4e0e\u6cc4\u6f0f\u60c5\u51b5 \u7b2c10\u7ae0\u3000\u534f\u4f5c\u5f00\u53d1 \u7b2c82\u6761\u3000\u5b66\u4f1a\u5bfb\u627e\u7531\u5176\u4ed6Python\u5f00\u53d1\u8005\u6240\u6784\u5efa\u7684\u6a21\u5757 \u7b2c83\u6761\u3000\u7528\u865a\u62df\u73af\u5883\u9694\u79bb\u9879\u76ee\uff0c\u5e76\u91cd\u5efa\u4f9d\u8d56\u5173\u7cfb \u7b2c84\u6761\u3000\u6bcf\u4e00\u4e2a\u51fd\u6570\u3001\u7c7b\u4e0e\u6a21\u5757\u90fd\u8981\u5199docstring \u7b2c85\u6761\u3000\u7528\u5305\u6765\u5b89\u6392\u6a21\u5757\uff0c\u4ee5\u63d0\u4f9b\u7a33\u56fa\u7684API \u7b2c86\u6761\u3000\u8003\u8651\u7528\u6a21\u5757\u7ea7\u522b\u7684\u4ee3\u7801\u914d\u7f6e\u4e0d\u540c\u7684\u90e8\u7f72\u73af\u5883 \u7b2c87\u6761\u3000\u4e3a\u81ea\u7f16\u7684\u6a21\u5757\u5b9a\u4e49\u6839\u5f02\u5e38\uff0c\u8ba9\u8c03\u7528\u8005\u80fd\u591f\u4e13\u95e8\u5904\u7406\u4e0e\u6b64API\u6709\u5173\u7684\u5f02\u5e38 \u7b2c88\u6761\u3000\u7528\u9002\u5f53\u7684\u65b9\u5f0f\u6253\u7834\u5faa\u73af\u4f9d\u8d56\u5173\u7cfb \u7b2c89\u6761\u3000\u91cd\u6784\u65f6\u8003\u8651\u901a\u8fc7warnings\u63d0\u9192\u5f00\u53d1\u8005API\u5df2\u7ecf\u53d1\u751f\u53d8\u5316 \u7b2c90\u6761\u3000\u8003\u8651\u901a\u8fc7typing\u505a\u9759\u6001\u5206\u6790\uff0c\u4ee5\u6d88\u9664bug","title":"3.5.Effective Python"},{"location":"#35demos","text":"\u9009\u8bfe\u7cfb\u7edf","title":"3.5.Demos"},{"location":"#4","text":"\u7ea6\u7ff0\u00b7\u68ee\u6885\u5179\u76842\u672c\u4e66","title":"4. \u8bfb\u4e66\u6709\u611f"},{"location":"about/","text":"About \u00b6 What's past is prologue. It\u2019s never too late to do. You may also visit my posts on zhihu . --From Shanghai China","title":"About"},{"location":"about/#about","text":"What's past is prologue. It\u2019s never too late to do. You may also visit my posts on zhihu . --From Shanghai China","title":"About"},{"location":"Reading/Developers/","text":"\u7a0b\u5e8f\u5458\u7684\u804c\u4e1a\u548c\u751f\u5b58\u6307\u5357 - \u8bfb\u7ea6\u7ff0\u00b7\u68ee\u6885\u5179\u76842\u672c\u4e66\u6709\u611f \u00b6 2024\u5e74\u5143\u65e6\u540e\u8bfb\u4e86\u7ea6\u7ff0\u00b7\u68ee\u6885\u5179\uff08John Sonmez\uff09\u76842\u672c\u4e66\uff0c\u5f88\u6709\u5171\u9e23\uff0c\u4ea7\u751f\u4e86\u5199\u8bfb\u4e66\u611f\u60f3\u7684\u5ff5\u5934\uff0c\u501f\u673a\u4e5f\u68b3\u7406\u4e86\u6211\u4e2a\u4eba\u7684\u89c2\u70b9\u548c\u60f3\u6cd5\uff0c\u4e8e\u662f\u4fbf\u6709\u4e86\u4e0b\u9762\u8fd9\u4e9b\u6587\u7ae0\u3002 \u76ee\u5f55 \u00b6 \u300a\u8f6f\u6280\u80fd2\uff1a\u8f6f\u4ef6\u5f00\u53d1\u8005\u804c\u4e1a\u751f\u6daf\u6307\u5357\u300b \u00b6 \u7b2c\u4e00\u7bc7 \u5165\u884c\u6210\u4e3a\u8f6f\u4ef6\u5f00\u53d1\u8005 \u7b2c2\u7ae0 \u8dec\u6b65\u5343\u91cc\uff1a\u5982\u4f55\u5165\u884c \u7b2c3\u7ae0 \u508d\u8eab\u4e4b\u6280\uff1a\u4f60\u9700\u8981\u62e5\u6709\u7684\u6280\u672f\u6280\u80fd \u7b2c4\u7ae0 \u683c\u7269\u81f4\u77e5\uff1a\u5982\u4f55\u62d3\u5c55\u6280\u672f\u6280\u80fd \u7b2c5\u7ae0 \u65e0\u95ee\u897f\u4e1c\uff1a\u5230\u5e95\u5e94\u8be5\u5b66\u54ea\u95e8\u7f16\u7a0b\u8bed\u8a00 \u7b2c6\u7ae0 \u59d7\u59d7\u5b66\u6b65\uff1a\u5982\u4f55\u5b66\u597d\u4f60\u7684\u7b2c\u4e00\u95e8\u7f16\u7a0b\u8bed\u8a00 \u7b2c7\u7ae0 \u5dcd\u5dcd\u5b66\u5e9c\uff1a\u901a\u8fc7\u4e0a\u5927\u5b66\u6df1\u9020\u6210\u4e3a\u8f6f\u4ef6\u5f00\u53d1\u8005 \u7b2c8\u7ae0 \u8eac\u884c\u5b9e\u8df5\uff1a\u901a\u8fc7\u53c2\u52a0\u7f16\u7a0b\u8bad\u7ec3\u8425\u6210\u4e3a\u8f6f\u4ef6\u5f00\u53d1\u8005 \u7b2c9\u7ae0 \u81ea\u5b66\u6210\u624d\uff1a\u901a\u8fc7\u81ea\u5b66\u6210\u4e3a\u8f6f\u4ef6\u5f00\u53d1\u8005 \u7b2c\u4e8c\u7bc7 \u627e\u5230\u4e00\u4efd\u5de5\u4f5c \u7b2c10\u7ae0 \u521d\u51fa\u8305\u5e90\uff1a\u600e\u6837\u83b7\u5f97\u5b9e\u4e60\u673a\u4f1a \u7b2c11\u7ae0 \u67f3\u6697\u82b1\u660e\uff1a\u6ca1\u6709\u7ecf\u9a8c\u5982\u4f55\u627e\u5230\u5de5\u4f5c \u7b2c12\u7ae0 \u72ec\u8f9f\u8e4a\u5f84\uff1a\u627e\u5de5\u4f5c\u65f6\u7684\u521b\u65b0\u601d\u7ef4 \u7b2c13\u7ae0 \u79fb\u6a3d\u5c31\u6559\uff1a\u600e\u6837\u5199\u7b80\u5386 \u7b2c14\u7ae0 \u9526\u56ca\u5999\u8ba1\uff1a\u5982\u4f55\u5bf9\u4ed8\u9762\u8bd5 \u7b2c15\u7ae0 \u5507\u67aa\u820c\u5251\uff1a\u5173\u4e8e\u85aa\u916c\u8c08\u5224 \u7b2c16\u7ae0 \u5c71\u9ad8\u6c34\u957f\uff1a\u5982\u679c\u8981\u79bb\u804c\uff0c\u8be5\u600e\u4e48\u505a \u7b2c17\u7ae0 \u534a\u8def\u51fa\u5bb6\uff1a\u5982\u4f55\u4ece\u5176\u4ed6\u884c\u4e1a\u8f6c\u884c\u6210\u4e3a\u8f6f\u4ef6\u5f00\u53d1\u8005 \u7b2c18\u7ae0 \u9047\u6c34\u53e0\u6865\uff1a\u5982\u4f55\u4ece\u6d4b\u8bd5\u6216\u8005\u5176\u4ed6\u6280\u672f\u6027\u89d2\u8272\u8f6c\u578b\u6210\u4e3a\u8f6f\u4ef6\u5f00\u53d1\u8005 \u7b2c19\u7ae0 \u638e\u646d\u5229\u75c5\uff1a\u5408\u540c\u5236\u5458\u5de5\u4e0e\u9886\u85aa\u5236\u6b63\u5f0f\u96c7\u5458\u4e4b\u95f4\u7684\u6bd4\u8f83 \u7b2c20\u7ae0 \u53bb\u68af\u4e4b\u8a00\uff1a\u4ece\u672a\u516c\u5f00\u8fc7\u7684\u62db\u8058\u884c\u4e1a\u8fd0\u4f5c\u7684\u79d8\u5bc6 \u7b2c\u4e09\u7bc7 \u5173\u4e8e\u8f6f\u4ef6\u5f00\u53d1\u4f60\u9700\u8981\u77e5\u9053\u4e9b\u4ec0\u4e48 \u7b2c21\u7ae0 \u8d70\u9a6c\u89c2\u82b1\uff1a\u7f16\u7a0b\u8bed\u8a00\u6982\u8ff0 \u7b2c22\u7ae0 \u77e5\u96be\u800c\u8fdb\uff1a\u4ec0\u4e48\u662fWeb\u5f00\u53d1 \u7b2c23\u7ae0 \u524d\u9014\u5927\u597d\uff1a\u79fb\u52a8\u5f00\u53d1 \u7b2c24\u7ae0 \u5e55\u540e\u82f1\u96c4\uff1a\u540e\u7aef\u5f00\u53d1 \u7b2c25\u7ae0 \u6e38\u620f\u4eba\u751f\uff1a\u6e38\u620f\u5f00\u53d1\u8005\u7684\u804c\u4e1a\u751f\u6daf \u7b2c26\u7ae0 \u4e8b\u65e0\u5de8\u7ec6\uff1aDBA\u4e0eDevOps \u7b2c27\u7ae0 \u9ad8\u5c4b\u5efa\u74f4\uff1a\u8f6f\u4ef6\u5f00\u53d1\u65b9\u6cd5\u8bba \u7b2c28\u7ae0 \u5c42\u5c42\u8bbe\u9632\uff1a\u6d4b\u8bd5\u548cQA\u57fa\u7840 \u7b2c29\u7ae0 \u6e90\u5934\u628a\u5173\uff1a\u6d4b\u8bd5\u9a71\u52a8\u5f00\u53d1\u4e0e\u5355\u5143\u6d4b\u8bd5 \u7b2c30\u7ae0 \u6e05\u6e05\u723d\u723d\uff1a\u6e90\u4ee3\u7801\u63a7\u5236 \u7b2c31\u7ae0 \u6b65\u6b65\u4e3a\u8425\uff1a\u6301\u7eed\u96c6\u6210 \u7b2c32\u7ae0 \u706b\u773c\u91d1\u775b\uff1a\u8c03\u8bd5 \u7b2c33\u7ae0 \u65e5\u81fb\u5b8c\u5584\uff1a\u4ee3\u7801\u7ef4\u62a4 \u7b2c34\u7ae0 \u5b9e\u81f3\u540d\u5f52\uff1a\u5de5\u4f5c\u5c97\u4f4d\u4e0e\u5934\u8854 \u7b2c35\u7ae0 \u591a\u59ff\u591a\u5f69\uff1a\u8f6f\u4ef6\u5f00\u53d1\u8005\u7684\u5de5\u4f5c\u7c7b\u578b \u7b2c\u56db\u7bc7 \u8f6f\u4ef6\u5f00\u53d1\u8005\u7684\u65e5\u5e38\u5de5\u4f5c \u7b2c36\u7ae0 \u548c\u800c\u4e0d\u540c\uff1a\u4e0e\u540c\u4e8b\u76f8\u5904 \u7b2c37\u7ae0 \u987a\u52bf\u800c\u4e3a\uff1a\u4e0e\u8001\u677f\u76f8\u5904 \u7b2c38\u7ae0 \u534f\u529b\u5171\u8fdb\uff1a\u4e0e\u6d4b\u8bd5\u4eba\u5458\u76f8\u5904 \u7b2c39\u7ae0 \u7b49\u91cf\u9f50\u89c2\uff1a\u5de5\u4f5c\u4e0e\u751f\u6d3b\u7684\u5e73\u8861 \u7b2c40\u7ae0 \u5e76\u80a9\u4f5c\u6218\uff1a\u4e0e\u56e2\u961f\u534f\u4f5c \u7b2c41\u7ae0 \u8c20\u8a00\u5609\u8bba\uff1a\u63a8\u9500\u4f60\u7684\u60f3\u6cd5 \u7b2c42\u7ae0 \u8863\u51a0\u695a\u695a\uff1a\u5982\u4f55\u7740\u88c5 \u7b2c43\u7ae0 \u8c0b\u4e8b\u5728\u4eba\uff1a\u5b89\u7136\u6e21\u8fc7\u7ee9\u6548\u8bc4\u4f30 \u7b2c44\u7ae0 \u5149\u660e\u78ca\u843d\uff1a\u5904\u7406\u504f\u89c1 \u7b2c45\u7ae0 \u8eab\u5148\u58eb\u5352\uff1a\u5904\u4e8e\u9886\u5bfc\u7684\u4f4d\u7f6e \u7b2c46\u7ae0 \u524d\u7a0b\u4f3c\u9526\uff1a\u83b7\u5f97\u63d0\u62d4\u4e0e\u664b\u5347 \u7b2c47\u7ae0 \u5dfe\u5e3c\u82f1\u96c4\uff1a\u79d1\u6280\u5973\u6027 \u7b2c\u4e94\u7bc7 \u63a8\u8fdb\u4f60\u7684\u804c\u4e1a\u53d1\u5c55 \u7b2c48\u7ae0 \u540d\u6ee1\u5929\u4e0b\uff1a\u5efa\u7acb\u58f0\u8a89 \u7b2c49\u7ae0 \u5e7f\u7ed3\u5584\u7f18\uff1a\u793e\u4ea4\u4e0e\u4eba\u8109 \u7b2c50\u7ae0 \u4e0e\u65f6\u4ff1\u8fdb\uff1a\u8ba9\u4f60\u7684\u6280\u80fd\u7d27\u8ddf\u4e0a\u65f6\u4ee3 \u7b2c51\u7ae0 \u884c\u5bb6\u91cc\u624b\uff1a\u505a\u4e13\u624d\u8fd8\u662f\u505a\u901a\u624d \u7b2c52\u7ae0 \u4f20\u7ecf\u5e03\u9053\uff1a\u6f14\u8bb2\u548c\u53c2\u52a0\u4f1a\u8bae \u7b2c53\u7ae0 \u7b14\u8015\u4e0d\u8f8d\uff1a\u521b\u5efa\u535a\u5ba2 \u7b2c54\u7ae0 \u6d77\u9614\u5929\u7a7a\uff1a\u505a\u81ea\u7531\u804c\u4e1a\u8005\u4e43\u81f3\u521b\u4e1a \u7b2c55\u7ae0 \u7b56\u9a6c\u626c\u97ad\uff1a\u804c\u4e1a\u53d1\u5c55\u8def\u5f84 \u7b2c56\u7ae0 \u672a\u96e8\u7ef8\u7f2a\uff1a\u5de5\u4f5c\u7a33\u5b9a\u6027\u4e0e\u5de5\u4f5c\u4fdd\u969c \u7b2c57\u7ae0 \u5b66\u65e0\u6b62\u5883\uff1a\u57f9\u8bad\u4e0e\u8d44\u683c\u8ba4\u8bc1 \u7b2c58\u7ae0 \u4e50\u6b64\u4e0d\u75b2\uff1a\u517c\u804c\u9879\u76ee \u7b2c59\u7ae0 \u5f00\u5377\u6709\u76ca\uff1a\u8981\u8bfb\u7684\u597d\u4e66 \u7b2c60\u7ae0 \u4f59\u97f3\u8885\u8885\uff1a\u7ed3\u675f\u8bed \u300a\u8f6f\u6280\u80fd\uff1a\u4ee3\u7801\u4e4b\u5916\u7684\u751f\u5b58\u6307\u5357\uff08\u7b2c2\u7248\uff09\u300b \u00b6 \u7b2c\u4e00\u7bc7\u3000\u804c\u4e1a \u7b2c2\u7ae0\u3000\u7ecf\u8425\u81ea\u5df1\u7684\u804c\u4e1a\u751f\u6daf\u5c31\u50cf\u7ecf\u8425\u4e00\u5bb6\u4f01\u4e1a \u7b2c3\u7ae0\u3000\u5982\u4f55\u7ed9\u81ea\u5df1\u8bbe\u5b9a\u597d\u804c\u4e1a\u76ee\u6807 \u7b2c4\u7ae0\u3000\u62d3\u5c55\u81ea\u5df1\u7684\u4eba\u9645\u4ea4\u5f80\u80fd\u529b \u7b2c5\u7ae0\u3000\u521b\u5efa\u4e00\u4efd\u5c61\u8bd5\u5c61\u9a8c\u7684\u7b80\u5386 \u7b2c6\u7ae0\u3000\u7834\u89e3\u9762\u8bd5\u4e4b\u9053 \u7b2c7\u7ae0\u3000\u8f6f\u4ef6\u5f00\u53d1\u4eba\u5458\u7684\u4e09\u6761\u804c\u4e1a\u8def\u5f84 \u7b2c8\u7ae0\u3000\u4e3a\u4ec0\u4e48\u4f60\u9700\u8981\u8d70\u4e13\u4e1a\u5316\u9053\u8def \u7b2c9\u7ae0\u3000\u516c\u53f8\u4e0e\u516c\u53f8\u662f\u4e0d\u4e00\u6837\u7684 \u7b2c10\u7ae0\u3000\u6500\u767b\u664b\u5347\u9636\u68af \u7b2c11\u7ae0\u3000\u6210\u4e3a\u4e13\u4e1a\u4eba\u58eb \u7b2c12\u7ae0\u3000\u4e0e\u8001\u677f\u548c\u540c\u4e8b\u7684\u76f8\u5904\u4e4b\u9053 \u7b2c13\u7ae0\u3000\u4e0d\u8981\u9677\u5165\u5bf9\u6280\u672f\u7684\u72c2\u70ed\u4e4b\u4e2d \u7b2c14\u7ae0\u3000\u5982\u4f55\u8f9e\u804c\u5e76\u5f00\u59cb\u4e3a\u81ea\u5df1\u5de5\u4f5c \u7b2c15\u7ae0\u3000\u5982\u4f55\u6210\u4e3a\u81ea\u7531\u804c\u4e1a\u8005 \u7b2c16\u7ae0\u3000\u5982\u4f55\u6210\u4e3a\u4e00\u540d\u4f01\u4e1a\u5bb6 \u7b2c17\u7ae0\u3000\u5982\u4f55\u5f00\u59cb\u521b\u4e1a \u7b2c18\u7ae0\u3000\u8fdc\u7a0b\u5de5\u4f5c \u7b2c\u4e8c\u7bc7\u3000\u81ea\u6211\u8425\u9500 \u7b2c19\u7ae0\u3000\u81ea\u6211\u8425\u9500\u57fa\u7840\u8bfe \u7b2c20\u7ae0\u3000\u5982\u4f55\u6253\u9020\u4e2a\u4eba\u54c1\u724c \u7b2c21\u7ae0\u3000\u5982\u4f55\u521b\u5efa\u5927\u83b7\u6210\u529f\u7684\u535a\u5ba2 \u7b2c22\u7ae0\u3000\u5728YouTube\u4e0a\u521b\u7acb\u81ea\u5df1\u7684\u4e13\u680f \u7b2c23\u7ae0\u3000\u4e3a\u4f55\u4e3a\u4ed6\u4eba\u589e\u52a0\u4ef7\u503c\u975e\u5e38\u91cd\u8981 \u7b2c24\u7ae0\u3000\u5584\u4e8e\u8fd0\u7528\u793e\u4ea4\u5a92\u4f53\u63d0\u5347\u81ea\u5df1\u7684\u54c1\u724c \u7b2c25\u7ae0\u3000\u6f14\u8bb2\u3001\u57f9\u8bad\u548c\u62a5\u544a \u7b2c26\u7ae0\u3000\u8457\u4e66\u7acb\u8bf4 \u7b2c\u4e09\u7bc7\u3000\u5b66\u4e60 \u7b2c27\u7ae0\u3000\u5b66\u4e60\u600e\u6837\u5b66\u4e60 \u7b2c28\u7ae0\u3000\u6211\u7684\u201c\u5341\u6b65\u5b66\u4e60\u6cd5\u201d \u7b2c29\u7ae0\u3000\u7b2c 1 \u6b65\u5230\u7b2c 6 \u6b65\uff1a\u8fd9\u4e9b\u6b65\u9aa4\u53ea\u505a\u4e00\u6b21 \u7b2c30\u7ae0\u3000\u7b2c7\u6b65\u5230\u7b2c10\u6b65\uff1a\u5faa\u73af\u5f80\u590d \u7b2c31\u7ae0\u3000\u5982\u4f55\u5bfb\u627e\u5bfc\u5e08 \u7b2c32\u7ae0\u3000\u5982\u4f55\u6210\u4e3a\u5bfc\u5e08 \u7b2c33\u7ae0\u3000\u4e3a\u4f55\u8bf4\u6559\u5b66\u76f8\u957f \u7b2c34\u7ae0\u3000\u4f60\u9700\u8981\u4e00\u4e2a\u5927\u5b66\u5b66\u4f4d\u5417 \u7b2c35\u7ae0\u3000\u53d1\u73b0\u81ea\u5df1\u7684\u77e5\u8bc6\u77ed\u677f \u7b2c\u56db\u7bc7\u3000\u751f\u4ea7\u529b \u7b2c36\u7ae0\u3000\u4e00\u5207\u59cb\u4e8e\u4e13\u6ce8 \u7b2c37\u7ae0\u3000\u6211\u7684\u79c1\u623f\u201c\u751f\u4ea7\u529b\u63d0\u5347\u8ba1\u5212\u201d \u7b2c38\u7ae0\u3000\u756a\u8304\u5de5\u4f5c\u6cd5 \u7b2c39\u7ae0\u3000\u6211\u7684\u201c\u5b9a\u989d\u5de5\u4f5c\u6cd5\u201d \u7b2c40\u7ae0\u3000\u5bf9\u81ea\u5df1\u8d1f\u8d23 \u7b2c41\u7ae0\u3000\u4e3a\u4ec0\u4e48\u8bf4\u591a\u4efb\u52a1\u5e76\u884c\u5f0a\u5927\u4e8e\u5229 \u7b2c42\u7ae0\u3000\u5982\u4f55\u5e94\u5bf9\u804c\u4e1a\u5026\u6020 \u7b2c43\u7ae0\u3000\u4f60\u662f\u600e\u6837\u6d6a\u8d39\u6389\u65f6\u95f4\u7684 \u7b2c44\u7ae0\u3000\u5f62\u6210\u60ef\u4f8b\u7684\u91cd\u8981\u6027 \u7b2c45\u7ae0\u3000\u5982\u4f55\u57f9\u517b\u597d\u4e60\u60ef \u7b2c46\u7ae0\u3000\u5206\u89e3\u4efb\u52a1\u4f1a\u63d0\u9ad8\u751f\u4ea7\u529b \u7b2c47\u7ae0\u3000\u52aa\u529b\u5de5\u4f5c\u7684\u4ef7\u503c\uff0c\u4ee5\u53ca\u4e3a\u4ec0\u4e48\u4f60\u603b\u662f\u9003\u907f\u52aa\u529b\u5de5\u4f5c \u7b2c48\u7ae0\u3000\u4efb\u4f55\u884c\u52a8\u90fd\u6bd4\u4e0d\u91c7\u53d6\u884c\u52a8\u597d \u7b2c\u4e94\u7bc7\u3000\u7406\u8d22 \u7b2c49\u7ae0\u3000\u5408\u7406\u652f\u914d\u4f60\u7684\u85aa\u6c34 \u7b2c50\u7ae0\u3000\u600e\u6837\u8fdb\u884c\u85aa\u916c\u8c08\u5224 \u7b2c51\u7ae0\u3000\u4e3a\u4f55\u8bf4\u623f\u5730\u4ea7\u662f\u6700\u597d\u7684\u6295\u8d44 \u7b2c52\u7ae0\u3000\u4f60\u771f\u7684\u4e86\u89e3\u81ea\u5df1\u7684\u9000\u4f11\u8ba1\u5212\u5417 \u7b2c53\u7ae0\u3000\u503a\u52a1\u7684\u5371\u5bb3 \u7b2c54\u7ae0\u3000\u5982\u4f55\u521b\u9020\u771f\u6b63\u7684\u8d22\u5bcc \u7b2c55\u7ae0\u3000\u6211\u662f\u5982\u4f55\u505a\u523033\u5c81\u9000\u4f11\u7684 \u7b2c\u516d\u7bc7\u3000\u5065\u8eab \u7b2c56\u7ae0\u3000\u5065\u8eab\u7684\u597d\u5904 \u7b2c57\u7ae0\u3000\u8bbe\u5b9a\u4f60\u7684\u5065\u8eab\u76ee\u6807 \u7b2c58\u7ae0\u3000\u5982\u4f55\u51cf\u80a5\uff08\u6216\u8005\u589e\u91cd\uff09 \u7b2c59\u7ae0\u3000\u5065\u8eab\u7684\u52a8\u529b\u4ece\u4f55\u800c\u6765 \u7b2c60\u7ae0\u3000\u589e\u808c \u7b2c61\u7ae0\u3000\u5982\u4f55\u83b7\u5f97\u5b8c\u7f8e\u8179\u808c \u7b2c62\u7ae0\u3000\u5f00\u59cb\u8dd1\u6b65 \u7b2c63\u7ae0\u3000\u6211\u7684\u51cf\u8102\u589e\u808c\u79d8\u8bc0 \u7b2c64\u7ae0\u3000\u7ad9\u7acb\u5f0f\u529e\u516c\u53ca\u5176\u4ed6\u7a8d\u95e8 \u7b2c65\u7ae0\u3000\u5229\u7528\u9ad8\u79d1\u6280\u88c5\u5907\u5065\u8eab \u7b2c\u4e03\u7bc7\u3000\u5fc3\u6001 \u7b2c66\u7ae0\u3000\u5fc3\u667a\u662f\u5982\u4f55\u5f71\u54cd\u8eab\u4f53\u7684 \u7b2c67\u7ae0\u3000\u4e00\u5207\u90fd\u6e90\u81ea\u79ef\u6781\u5fc3\u6001 \u7b2c68\u7ae0\u3000\u5982\u4f55\u6539\u53d8\u4f60\u7684\u81ea\u6211\u5f62\u8c61 \u7b2c69\u7ae0\u3000\u7231\u60c5\u4e0e\u604b\u7231 \u7b2c70\u7ae0\u3000\u6211\u7684\u79c1\u623f\u6210\u529f\u4e66\u5355 \u7b2c71\u7ae0\u3000\u4e0d\u8981\u5bb3\u6015\u5931\u8d25 \u7b2c72\u7ae0\u3000\u8d70\u51fa\u8212\u9002\u533a \u7b2c73\u7ae0\u3000\u65af\u591a\u845b\u54f2\u5b66\uff0c\u4ee5\u53ca\u5b83\u5982\u4f55\u6539\u53d8\u4f60\u7684\u751f\u6d3b \u7b2c74\u7ae0\u3000\u7ed3\u675f\u8bed \u4e00\u3001\u5165\u884c \u00b6 \u6838\u5fc3\u601d\u60f3: \u6210\u4e3a\u4e00\u540d\u8f6f\u4ef6\u5f00\u53d1\u8005\u4e0d\u4ec5\u4ec5\u662f\u5b66\u4e60\u7f16\u7a0b\u8bed\u8a00\uff0c\u8fd8\u9700\u8981\u5177\u5907\u5404\u79cd\u8f6f\u6280\u80fd\uff0c\u4f8b\u5982\u6c9f\u901a\u80fd\u529b\u3001\u56e2\u961f\u5408\u4f5c\u80fd\u529b\u548c\u89e3\u51b3\u95ee\u9898\u7684\u80fd\u529b\u3002 \u672c\u7bc7\u4ecb\u7ecd\u4e86\u5982\u4f55\u6210\u4e3a\u4e00\u540d\u8f6f\u4ef6\u5f00\u53d1\u8005\u7684\u6b65\u9aa4\uff0c\u5305\u62ec\uff1a \u8bc4\u4f30\u4f60\u7684\u5174\u8da3\u548c\u80fd\u529b \u5b66\u4e60\u7f16\u7a0b\u8bed\u8a00 \u5efa\u7acb\u4f60\u7684\u4f5c\u54c1\u96c6 \u51c6\u5907\u7b80\u5386\u548c\u6c42\u804c\u4fe1 \u9762\u8bd5\u6280\u5de7 \u85aa\u916c\u8c08\u5224 \u4e3b\u8981\u5185\u5bb9: \u8bc4\u4f30\u4f60\u7684\u5174\u8da3\u548c\u80fd\u529b: \u8003\u8651\u4f60\u662f\u5426\u771f\u7684\u5bf9\u8f6f\u4ef6\u5f00\u53d1\u611f\u5174\u8da3\uff0c\u5e76\u8bc4\u4f30\u4f60\u7684\u5b66\u4e60\u80fd\u529b\u548c\u89e3\u51b3\u95ee\u9898\u7684\u80fd\u529b\u3002 \u5b66\u4e60\u7f16\u7a0b\u8bed\u8a00: \u9009\u62e9\u4e00\u79cd\u6216\u591a\u79cd\u7f16\u7a0b\u8bed\u8a00\u8fdb\u884c\u5b66\u4e60\uff0c\u5e76\u63a8\u8350\u4e00\u4e9b\u5b66\u4e60\u8d44\u6e90\u3002 \u5efa\u7acb\u4f60\u7684\u4f5c\u54c1\u96c6: \u5f00\u53d1\u4e00\u4e9b\u4e2a\u4eba\u9879\u76ee\u6216\u53c2\u4e0e\u5f00\u6e90\u9879\u76ee\uff0c\u4ee5\u5c55\u793a\u4f60\u7684\u6280\u80fd\u548c\u7ecf\u9a8c\u3002 \u51c6\u5907\u7b80\u5386\u548c\u6c42\u804c\u4fe1: \u7a81\u51fa\u4f60\u7684\u6280\u80fd\u548c\u7ecf\u9a8c\uff0c\u5e76\u9488\u5bf9\u4e0d\u540c\u7684\u804c\u4f4d\u8fdb\u884c\u8c03\u6574\u3002 \u9762\u8bd5\u6280\u5de7: \u4e86\u89e3\u9762\u8bd5\u7684\u5e38\u89c1\u95ee\u9898\uff0c\u5e76\u7ec3\u4e60\u4f60\u7684\u56de\u7b54\u3002 \u85aa\u916c\u8c08\u5224: \u4e86\u89e3\u4f60\u7684\u85aa\u916c\u8303\u56f4\uff0c\u5e76\u5b66\u4f1a\u5982\u4f55\u8c08\u5224\u3002 \u5173\u952e\u6b65\u9aa4: \u81ea\u6211\u8bc4\u4f30: \u8bc4\u4f30\u4f60\u7684\u5174\u8da3\u3001\u80fd\u529b\u548c\u76ee\u6807\u3002 \u5b66\u4e60\u8ba1\u5212: \u5236\u5b9a\u5b66\u4e60\u7f16\u7a0b\u8bed\u8a00\u7684\u8ba1\u5212\uff0c\u5e76\u9009\u62e9\u5408\u9002\u7684\u5b66\u4e60\u8d44\u6e90\u3002 \u5b9e\u8df5\u7ec3\u4e60: \u901a\u8fc7\u5f00\u53d1\u4e2a\u4eba\u9879\u76ee\u6216\u53c2\u4e0e\u5f00\u6e90\u9879\u76ee\u6765\u7ec3\u4e60\u4f60\u7684\u6280\u80fd\u3002 \u6c42\u804c\u51c6\u5907: \u51c6\u5907\u7b80\u5386\u3001\u6c42\u804c\u4fe1\u548c\u9762\u8bd5\u6280\u5de7\u3002 \u6301\u7eed\u5b66\u4e60: \u4e0d\u65ad\u5b66\u4e60\u65b0\u7684\u6280\u80fd\u548c\u77e5\u8bc6\uff0c\u4fdd\u6301\u7ade\u4e89\u529b\u3002 \u603b\u7ed3: \u6210\u4e3a\u4e00\u540d\u8f6f\u4ef6\u5f00\u53d1\u8005\u9700\u8981\u4ed8\u51fa\u52aa\u529b\u548c\u65f6\u95f4\u3002\u901a\u8fc7\u638c\u63e1\u5fc5\u8981\u7684\u6280\u80fd\u548c\u77e5\u8bc6\uff0c\u5e76\u505a\u597d\u6c42\u804c\u51c6\u5907\uff0c\u4f60\u5c31\u53ef\u4ee5\u5b9e\u73b0\u4f60\u7684\u76ee\u6807\u3002 \u4ee5\u4e0b\u662f\u4e00\u4e9b\u5177\u4f53\u7684\u5efa\u8bae: \u5c3d\u65e9\u5f00\u59cb\u5b66\u4e60\u7f16\u7a0b\u3002 \u8d8a\u65e9\u5f00\u59cb\u5b66\u4e60\uff0c\u4f60\u5c31\u6709\u8d8a\u591a\u7684\u65f6\u95f4\u6765\u7ec3\u4e60\u548c\u63d0\u9ad8\u4f60\u7684\u6280\u80fd\u3002 \u79ef\u6781\u53c2\u4e0e\u5f00\u6e90\u9879\u76ee\u3002 \u8fd9\u662f\u4e00\u4e2a\u5f88\u597d\u7684\u5b66\u4e60\u673a\u4f1a\uff0c\u53ef\u4ee5\u8ba9\u4f60\u4e0e\u5176\u4ed6\u5f00\u53d1\u4eba\u5458\u5408\u4f5c\uff0c\u5e76\u5c55\u793a\u4f60\u7684\u6280\u80fd\u3002 \u53c2\u52a0\u884c\u4e1a\u6d3b\u52a8\u3002 \u8fd9\u662f\u4e00\u4e2a\u5f88\u597d\u7684\u7ed3\u8bc6\u5176\u4ed6\u5f00\u53d1\u4eba\u5458\u548c\u4e86\u89e3\u884c\u4e1a\u8d8b\u52bf\u7684\u673a\u4f1a\u3002 \u5efa\u7acb\u81ea\u5df1\u7684\u4e2a\u4eba\u54c1\u724c\u3002 \u521b\u5efa\u4e00\u4e2a\u4e2a\u4eba\u7f51\u7ad9\u6216\u535a\u5ba2\uff0c\u5c55\u793a\u4f60\u7684\u4f5c\u54c1\u548c\u6280\u80fd\u3002 \u4fdd\u6301\u79ef\u6781\u4e3b\u52a8\u3002 \u4e0d\u8981\u7b49\u5f85\u673a\u4f1a\u6765\u627e\u4f60\uff0c\u8981\u4e3b\u52a8\u5bfb\u627e\u673a\u4f1a\u3002 \u4ee5\u4e0b\u662f\u4e00\u4e9b\u989d\u5916\u7684\u8865\u5145: \u4e66\u4e2d\u8fd8\u63d0\u5230\u4e86 \u804c\u4e1a\u89c4\u5212 \u7684\u91cd\u8981\u6027\u3002\u8bbe\u5b9a\u4f60\u7684\u804c\u4e1a\u76ee\u6807\uff0c\u5e76\u5236\u5b9a\u5b9e\u73b0\u76ee\u6807\u7684\u8ba1\u5212\u3002 \u4e66\u4e2d\u4e5f\u5f3a\u8c03\u4e86 \u4eba\u8109 \u7684\u91cd\u8981\u6027\u3002\u5efa\u7acb\u4e0e\u5176\u4ed6\u5f00\u53d1\u4eba\u5458\u548c\u884c\u4e1a\u4e13\u5bb6\u7684\u8054\u7cfb\uff0c\u53ef\u4ee5\u5e2e\u52a9\u4f60\u83b7\u5f97\u5b9d\u8d35\u7684\u7ecf\u9a8c\u548c\u5efa\u8bae\u3002 \u4e8c\u3001\u627e\u5de5\u4f5c \u00b6 \u6838\u5fc3\u601d\u60f3: \u627e\u5230\u4e00\u4efd\u8f6f\u4ef6\u5f00\u53d1\u5de5\u4f5c\u4e0d\u4ec5\u4ec5\u662f\u6295\u9012\u7b80\u5386\u548c\u53c2\u52a0\u9762\u8bd5\uff0c\u8fd8\u9700\u8981\u505a\u597d\u5145\u5206\u7684\u51c6\u5907\uff0c\u5e76\u4e86\u89e3\u6c42\u804c\u8fc7\u7a0b\u4e2d\u7684\u6ce8\u610f\u4e8b\u9879\u3002 \u672c\u7bc7\u4ecb\u7ecd\u4e86\u5982\u4f55\u627e\u5230\u4e00\u4efd\u8f6f\u4ef6\u5f00\u53d1\u5de5\u4f5c\u7684\u6b65\u9aa4\uff0c\u5305\u62ec\uff1a \u786e\u5b9a\u4f60\u7684\u6c42\u804c\u76ee\u6807 \u51c6\u5907\u7b80\u5386\u548c\u6c42\u804c\u4fe1 \u5b66\u4e60\u9762\u8bd5\u6280\u5de7 \u4e86\u89e3\u85aa\u916c\u8c08\u5224 \u62d3\u5c55\u4eba\u8109 \u5173\u6ce8\u884c\u4e1a\u8d8b\u52bf \u4e3b\u8981\u5185\u5bb9: \u786e\u5b9a\u4f60\u7684\u6c42\u804c\u76ee\u6807: \u660e\u786e\u4f60\u60f3\u8981\u4ec0\u4e48\u6837\u7684\u5de5\u4f5c\uff0c\u5e76\u4e86\u89e3\u4f60\u6240\u5728\u5730\u533a\u7684\u5c31\u4e1a\u5e02\u573a\u3002 \u51c6\u5907\u7b80\u5386\u548c\u6c42\u804c\u4fe1: \u7a81\u51fa\u4f60\u7684\u6280\u80fd\u548c\u7ecf\u9a8c\uff0c\u5e76\u9488\u5bf9\u4e0d\u540c\u7684\u804c\u4f4d\u8fdb\u884c\u8c03\u6574\u3002 \u5b66\u4e60\u9762\u8bd5\u6280\u5de7: \u4e86\u89e3\u9762\u8bd5\u7684\u5e38\u89c1\u95ee\u9898\uff0c\u5e76\u7ec3\u4e60\u4f60\u7684\u56de\u7b54\u3002 \u4e86\u89e3\u85aa\u916c\u8c08\u5224: \u4e86\u89e3\u4f60\u7684\u85aa\u916c\u8303\u56f4\uff0c\u5e76\u5b66\u4f1a\u5982\u4f55\u8c08\u5224\u3002 \u62d3\u5c55\u4eba\u8109: \u53c2\u52a0\u884c\u4e1a\u6d3b\u52a8\u548c\u5efa\u7acb\u4e0e\u5176\u4ed6\u5f00\u53d1\u4eba\u5458\u7684\u8054\u7cfb\uff0c\u53ef\u4ee5\u5e2e\u52a9\u4f60\u83b7\u5f97\u66f4\u591a\u673a\u4f1a\u3002 \u5173\u6ce8\u884c\u4e1a\u8d8b\u52bf: \u4e86\u89e3\u6700\u65b0\u7684\u6280\u672f\u548c\u8d8b\u52bf\uff0c\u53ef\u4ee5\u5e2e\u52a9\u4f60\u4fdd\u6301\u7ade\u4e89\u529b\u3002 \u5173\u952e\u6b65\u9aa4: \u81ea\u6211\u8bc4\u4f30: \u8bc4\u4f30\u4f60\u7684\u6280\u80fd\u3001\u7ecf\u9a8c\u548c\u76ee\u6807\u3002 \u6c42\u804c\u76ee\u6807: \u660e\u786e\u4f60\u60f3\u8981\u4ec0\u4e48\u6837\u7684\u5de5\u4f5c\uff0c\u5e76\u5236\u5b9a\u6c42\u804c\u8ba1\u5212\u3002 \u51c6\u5907\u6750\u6599: \u51c6\u5907\u7b80\u5386\u3001\u6c42\u804c\u4fe1\u548c\u4f5c\u54c1\u96c6\u3002 \u9762\u8bd5\u51c6\u5907: \u7ec3\u4e60\u9762\u8bd5\u6280\u5de7\uff0c\u5e76\u4e86\u89e3\u5e38\u89c1\u95ee\u9898\u3002 \u6301\u7eed\u5b66\u4e60: \u4e0d\u65ad\u5b66\u4e60\u65b0\u7684\u6280\u80fd\u548c\u77e5\u8bc6\uff0c\u4fdd\u6301\u7ade\u4e89\u529b\u3002 \u603b\u7ed3: \u627e\u5230\u4e00\u4efd\u8f6f\u4ef6\u5f00\u53d1\u5de5\u4f5c\u9700\u8981\u4ed8\u51fa\u52aa\u529b\u548c\u65f6\u95f4\u3002\u901a\u8fc7\u505a\u597d\u5145\u5206\u7684\u51c6\u5907\uff0c\u5e76\u4e86\u89e3\u6c42\u804c\u8fc7\u7a0b\u4e2d\u7684\u6ce8\u610f\u4e8b\u9879\uff0c\u4f60\u5c31\u53ef\u4ee5\u63d0\u9ad8\u627e\u5230\u7406\u60f3\u5de5\u4f5c\u7684\u6210\u529f\u7387\u3002 \u4ee5\u4e0b\u662f\u4e00\u4e9b\u5177\u4f53\u7684\u5efa\u8bae: \u5c3d\u65e9\u5f00\u59cb\u6c42\u804c\u3002 \u4e0d\u8981\u7b49\u5230\u4f60\u6bd5\u4e1a\u6216\u5b8c\u6210\u6240\u6709\u5b66\u4e60\u624d\u5f00\u59cb\u6c42\u804c\u3002 \u5145\u5206\u5229\u7528\u4f60\u7684\u8d44\u6e90\u3002 \u4f60\u7684\u5b66\u6821\u3001\u670b\u53cb\u3001\u5bb6\u4eba\u548c\u804c\u4e1a\u987e\u95ee\u90fd\u53ef\u4ee5\u63d0\u4f9b\u5e2e\u52a9\u3002 \u4fdd\u6301\u79ef\u6781\u4e3b\u52a8\u3002 \u4e0d\u8981\u7b49\u5f85\u673a\u4f1a\u6765\u627e\u4f60\uff0c\u8981\u4e3b\u52a8\u5bfb\u627e\u673a\u4f1a\u3002 \u5b66\u4f1a\u63a8\u9500\u81ea\u5df1\u3002 \u5728\u9762\u8bd5\u4e2d\u8981\u81ea\u4fe1\u5730\u5c55\u793a\u4f60\u7684\u6280\u80fd\u548c\u7ecf\u9a8c\u3002 \u4e0d\u8981\u653e\u5f03\u3002 \u6c42\u804c\u8fc7\u7a0b\u53ef\u80fd\u4f1a\u5f88\u6f2b\u957f\uff0c\u4f46\u4e0d\u8981\u653e\u5f03\uff0c\u6700\u7ec8\u4f60\u4f1a\u627e\u5230\u4e00\u4efd\u9002\u5408\u4f60\u7684\u5de5\u4f5c\u3002 \u4ee5\u4e0b\u662f\u4e00\u4e9b\u989d\u5916\u7684\u8865\u5145: \u4e66\u4e2d\u8fd8\u63d0\u5230\u4e86 \u5b9e\u4e60 \u7684\u91cd\u8981\u6027\u3002\u5b9e\u4e60\u662f\u4e00\u4e2a\u5f88\u597d\u7684\u83b7\u5f97\u5de5\u4f5c\u7ecf\u9a8c\u548c\u5efa\u7acb\u4eba\u8109\u7684\u673a\u4f1a\u3002 \u4e66\u4e2d\u4e5f\u5f3a\u8c03\u4e86 \u8f6f\u6280\u80fd \u7684\u91cd\u8981\u6027\u3002\u826f\u597d\u7684\u6c9f\u901a\u80fd\u529b\u3001\u56e2\u961f\u5408\u4f5c\u80fd\u529b\u548c\u89e3\u51b3\u95ee\u9898\u7684\u80fd\u529b\u53ef\u4ee5\u5e2e\u52a9\u4f60\u5728\u6c42\u804c\u4e2d\u8131\u9896\u800c\u51fa\u3002 \u4e09\u3001\u5173\u4e8e\u8f6f\u4ef6\u5f00\u53d1 \u00b6 \u6838\u5fc3\u601d\u60f3: \u8f6f\u4ef6\u5f00\u53d1\u4e0d\u4ec5\u4ec5\u662f\u5199\u4ee3\u7801\uff0c\u8fd8\u6d89\u53ca\u8bb8\u591a\u5176\u4ed6\u65b9\u9762\uff0c\u4f8b\u5982\u8f6f\u4ef6\u8bbe\u8ba1\u3001\u6d4b\u8bd5\u3001\u90e8\u7f72\u548c\u7ef4\u62a4\u3002 \u672c\u7bc7\u4ecb\u7ecd\u4e86\u8f6f\u4ef6\u5f00\u53d1\u8fc7\u7a0b\u4e2d\u7684\u4e00\u4e9b\u91cd\u8981\u6982\u5ff5\u548c\u5b9e\u8df5\uff0c\u5305\u62ec\uff1a \u8f6f\u4ef6\u8bbe\u8ba1\u539f\u5219 \u6d4b\u8bd5\u65b9\u6cd5 \u7248\u672c\u63a7\u5236 \u6301\u7eed\u96c6\u6210\u548c\u6301\u7eed\u90e8\u7f72 \u5b89\u5168\u7f16\u7801 \u8f6f\u4ef6\u6587\u6863 \u56e2\u961f\u5408\u4f5c \u4e3b\u8981\u5185\u5bb9: \u8f6f\u4ef6\u8bbe\u8ba1\u539f\u5219: \u4ecb\u7ecd\u4e86\u4e00\u4e9b\u91cd\u8981\u7684\u8f6f\u4ef6\u8bbe\u8ba1\u539f\u5219\uff0c\u4f8b\u5982 SOLID \u539f\u5219\u548c\u53ef\u91cd\u7528\u6027\u3002 \u6d4b\u8bd5\u65b9\u6cd5: \u4ecb\u7ecd\u4e86\u4e00\u4e9b\u5e38\u89c1\u7684\u6d4b\u8bd5\u65b9\u6cd5\uff0c\u4f8b\u5982\u5355\u5143\u6d4b\u8bd5\u3001\u96c6\u6210\u6d4b\u8bd5\u548c\u7cfb\u7edf\u6d4b\u8bd5\u3002 \u7248\u672c\u63a7\u5236: \u4ecb\u7ecd\u4e86\u7248\u672c\u63a7\u5236\u7684\u57fa\u672c\u6982\u5ff5\u548c\u5de5\u5177\uff0c\u4f8b\u5982 Git \u548c Mercurial\u3002 \u6301\u7eed\u96c6\u6210\u548c\u6301\u7eed\u90e8\u7f72: \u4ecb\u7ecd\u4e86\u6301\u7eed\u96c6\u6210\u548c\u6301\u7eed\u90e8\u7f72\u7684\u6982\u5ff5\u548c\u5b9e\u8df5\u3002 \u5b89\u5168\u7f16\u7801: \u4ecb\u7ecd\u4e86\u4e00\u4e9b\u5e38\u89c1\u7684\u5b89\u5168\u7f16\u7801\u5b9e\u8df5\uff0c\u4f8b\u5982\u8f93\u5165\u9a8c\u8bc1\u548c\u9519\u8bef\u5904\u7406\u3002 \u8f6f\u4ef6\u6587\u6863: \u4ecb\u7ecd\u4e86\u8f6f\u4ef6\u6587\u6863\u7684\u91cd\u8981\u6027\u4ee5\u53ca\u5982\u4f55\u7f16\u5199\u6587\u6863\u3002 \u56e2\u961f\u5408\u4f5c: \u4ecb\u7ecd\u4e86\u56e2\u961f\u5408\u4f5c\u5728\u8f6f\u4ef6\u5f00\u53d1\u4e2d\u7684\u91cd\u8981\u6027\u4ee5\u53ca\u5982\u4f55\u6709\u6548\u5730\u8fdb\u884c\u56e2\u961f\u5408\u4f5c\u3002 \u5173\u952e\u6b65\u9aa4: \u5b66\u4e60\u8f6f\u4ef6\u8bbe\u8ba1\u539f\u5219\u3002 \u597d\u7684\u8bbe\u8ba1\u53ef\u4ee5\u4f7f\u8f6f\u4ef6\u66f4\u52a0\u6613\u4e8e\u7406\u89e3\u3001\u7ef4\u62a4\u548c\u6269\u5c55\u3002 \u638c\u63e1\u6d4b\u8bd5\u65b9\u6cd5\u3002 \u6d4b\u8bd5\u53ef\u4ee5\u786e\u4fdd\u8f6f\u4ef6\u7684\u8d28\u91cf\u548c\u53ef\u9760\u6027\u3002 \u4f7f\u7528\u7248\u672c\u63a7\u5236\u5de5\u5177\u3002 \u7248\u672c\u63a7\u5236\u53ef\u4ee5\u5e2e\u52a9\u4f60\u8ddf\u8e2a\u4ee3\u7801\u7684\u66f4\u6539\u5e76\u56de\u6eda\u5230\u4e4b\u524d\u7684\u7248\u672c\u3002 \u4e86\u89e3\u6301\u7eed\u96c6\u6210\u548c\u6301\u7eed\u90e8\u7f72\u3002 \u6301\u7eed\u96c6\u6210\u548c\u6301\u7eed\u90e8\u7f72\u53ef\u4ee5\u5e2e\u52a9\u4f60\u66f4\u5feb\u5730\u53d1\u5e03\u8f6f\u4ef6\u5e76\u63d0\u9ad8\u8d28\u91cf\u3002 \u9075\u5faa\u5b89\u5168\u7f16\u7801\u5b9e\u8df5\u3002 \u5b89\u5168\u7f16\u7801\u53ef\u4ee5\u5e2e\u52a9\u4f60\u9632\u6b62\u8f6f\u4ef6\u6f0f\u6d1e\u3002 \u7f16\u5199\u6e05\u6670\u7684\u6587\u6863\u3002 \u6587\u6863\u53ef\u4ee5\u5e2e\u52a9\u5176\u4ed6\u4eba\u7406\u89e3\u548c\u4f7f\u7528\u4f60\u7684\u8f6f\u4ef6\u3002 \u5b66\u4f1a\u4e0e\u4ed6\u4eba\u5408\u4f5c\u3002 \u56e2\u961f\u5408\u4f5c\u53ef\u4ee5\u5e2e\u52a9\u4f60\u5b8c\u6210\u66f4\u5927\u7684\u9879\u76ee\u3002 \u603b\u7ed3: \u8f6f\u4ef6\u5f00\u53d1\u662f\u4e00\u9879\u590d\u6742\u7684\u5de5\u7a0b\uff0c\u9700\u8981\u638c\u63e1\u5404\u79cd\u77e5\u8bc6\u548c\u6280\u80fd\u3002\u901a\u8fc7\u5b66\u4e60\u548c\u5b9e\u8df5\uff0c\u4f60. \u4ee5\u4e0b\u662f\u4e00\u4e9b\u5177\u4f53\u7684\u5efa\u8bae: \u9605\u8bfb\u6709\u5173\u8f6f\u4ef6\u5f00\u53d1\u7684\u4e66\u7c4d\u548c\u6587\u7ae0\u3002 \u8bb8\u591a\u4f18\u79c0\u7684\u8d44\u6e90\u53ef\u4ee5\u5e2e\u52a9\u4f60\u5b66\u4e60\u8f6f\u4ef6\u5f00\u53d1\u7684\u5404\u4e2a\u65b9\u9762\u3002 \u53c2\u52a0\u8f6f\u4ef6\u5f00\u53d1\u57f9\u8bad\u8bfe\u7a0b\u3002 \u57f9\u8bad\u8bfe\u7a0b\u53ef\u4ee5\u5e2e\u52a9\u4f60\u5feb\u901f\u638c\u63e1\u8f6f\u4ef6\u5f00\u53d1\u7684\u6700\u65b0\u6280\u672f\u548c\u5b9e\u8df5\u3002 \u53c2\u4e0e\u5f00\u6e90\u9879\u76ee\u3002 \u8fd9\u662f\u4e00\u4e2a\u5f88\u597d\u7684\u5b66\u4e60\u673a\u4f1a\uff0c\u53ef\u4ee5\u8ba9\u4f60\u4e0e\u5176\u4ed6\u5f00\u53d1\u4eba\u5458\u5408\u4f5c\u5e76\u83b7\u5f97\u7ecf\u9a8c\u3002 \u5728\u4e2a\u4eba\u9879\u76ee\u4e2d\u7ec3\u4e60\u4f60\u7684\u6280\u80fd\u3002 \u5f00\u53d1\u4e2a\u4eba\u9879\u76ee\u53ef\u4ee5\u5e2e\u52a9\u4f60\u5de9\u56fa\u4f60\u6240\u5b66\u7684\u77e5\u8bc6\u5e76\u63d0\u9ad8\u4f60\u7684\u6280\u80fd\u3002 \u4e0e\u5176\u4ed6\u5f00\u53d1\u4eba\u5458\u4ea4\u6d41\u3002 \u4e0e\u5176\u4ed6\u5f00\u53d1\u4eba\u5458\u4ea4\u6d41\u53ef\u4ee5\u5e2e\u52a9\u4f60\u5b66\u4e60\u65b0\u77e5\u8bc6\u5e76\u83b7\u5f97\u65b0\u7684\u89c1\u89e3\u3002 \u4ee5\u4e0b\u662f\u4e00\u4e9b\u989d\u5916\u7684\u8865\u5145: \u4e66\u4e2d\u8fd8\u63d0\u5230\u4e86 \u4e13\u4e1a\u53d1\u5c55 \u7684\u91cd\u8981\u6027\u3002\u4e0d\u65ad\u5b66\u4e60\u65b0\u7684\u6280\u80fd\u548c\u77e5\u8bc6\uff0c\u5e76\u83b7\u5f97\u76f8\u5173\u7684\u8ba4\u8bc1\uff0c\u53ef\u4ee5\u5e2e\u52a9\u4f60\u63d0\u5347\u4f60\u7684\u804c\u4e1a\u7ade\u4e89\u529b\u3002 \u4e66\u4e2d\u4e5f\u5f3a\u8c03\u4e86 \u7ec8\u8eab\u5b66\u4e60 \u7684\u91cd\u8981\u6027\u3002\u8f6f\u4ef6\u5f00\u53d1\u662f\u4e00\u4e2a\u5feb\u901f\u53d1\u5c55\u7684\u884c\u4e1a\uff0c\u4f60\u9700\u8981\u4e0d\u65ad\u5b66\u4e60\u624d\u80fd\u8ddf\u4e0a\u6700\u65b0\u7684\u8d8b\u52bf\u3002 \u56db\u3001\u65e5\u5e38\u5de5\u4f5c \u00b6 \u6838\u5fc3\u601d\u60f3: \u8f6f\u4ef6\u5f00\u53d1\u8005\u7684\u65e5\u5e38\u5de5\u4f5c\u4e0d\u4ec5\u4ec5\u662f\u5199\u4ee3\u7801\uff0c\u8fd8\u5305\u62ec\u8bb8\u591a\u5176\u4ed6\u4efb\u52a1\uff0c\u4f8b\u5982\u6c9f\u901a\u3001\u534f\u4f5c\u3001\u89e3\u51b3\u95ee\u9898\u548c\u5b66\u4e60\u3002 \u672c\u7bc7\u4ecb\u7ecd\u4e86\u8f6f\u4ef6\u5f00\u53d1\u8005\u7684\u65e5\u5e38\u5de5\u4f5c\u5185\u5bb9\u548c\u804c\u8d23\uff0c\u4ee5\u53ca\u5982\u4f55\u6709\u6548\u5730\u5b8c\u6210\u8fd9\u4e9b\u5de5\u4f5c\u3002 \u4e3b\u8981\u5185\u5bb9: \u6c9f\u901a: \u8f6f\u4ef6\u5f00\u53d1\u8005\u9700\u8981\u4e0e\u56e2\u961f\u6210\u5458\u3001\u5ba2\u6237\u548c\u5176\u4ed6\u5229\u76ca\u76f8\u5173\u8005\u8fdb\u884c\u6709\u6548\u6c9f\u901a\u3002 \u534f\u4f5c: \u8f6f\u4ef6\u5f00\u53d1\u901a\u5e38\u662f\u56e2\u961f\u5408\u4f5c\u7684\u8fc7\u7a0b\uff0c\u9700\u8981\u4e0e\u4ed6\u4eba\u534f\u4f5c\u624d\u80fd\u5b8c\u6210\u4efb\u52a1\u3002 \u89e3\u51b3\u95ee\u9898: \u8f6f\u4ef6\u5f00\u53d1\u8fc7\u7a0b\u4e2d\u4f1a\u9047\u5230\u5404\u79cd\u95ee\u9898\uff0c\u9700\u8981\u80fd\u591f\u72ec\u7acb\u601d\u8003\u5e76\u89e3\u51b3\u95ee\u9898\u3002 \u5b66\u4e60: \u8f6f\u4ef6\u5f00\u53d1\u662f\u4e00\u4e2a\u5feb\u901f\u53d1\u5c55\u7684\u884c\u4e1a\uff0c\u9700\u8981\u4e0d\u65ad\u5b66\u4e60\u624d\u80fd\u8ddf\u4e0a\u6700\u65b0\u7684\u6280\u672f\u548c\u8d8b\u52bf\u3002 \u5173\u952e\u6b65\u9aa4: \u63d0\u9ad8\u6c9f\u901a\u80fd\u529b\u3002 \u6e05\u6670\u3001\u7b80\u6d01\u5730\u8868\u8fbe\u4f60\u7684\u60f3\u6cd5\uff0c\u5e76\u5b66\u4f1a\u503e\u542c\u4ed6\u4eba\u7684\u610f\u89c1\u3002 \u5b66\u4f1a\u56e2\u961f\u5408\u4f5c\u3002 \u4e0e\u4ed6\u4eba\u5408\u4f5c\u5b8c\u6210\u4efb\u52a1\uff0c\u5e76\u5206\u4eab\u4f60\u7684\u77e5\u8bc6\u548c\u7ecf\u9a8c\u3002 \u57f9\u517b\u89e3\u51b3\u95ee\u9898\u7684\u80fd\u529b\u3002 \u5206\u6790\u95ee\u9898\uff0c\u5e76\u63d0\u51fa\u6709\u6548\u7684\u89e3\u51b3\u65b9\u6848\u3002 \u4fdd\u6301\u7ec8\u8eab\u5b66\u4e60\u7684\u6001\u5ea6\u3002 \u4e0d\u65ad\u5b66\u4e60\u65b0\u7684\u6280\u80fd\u548c\u77e5\u8bc6\uff0c\u5e76\u4fdd\u6301\u5bf9\u65b0\u6280\u672f\u7684\u5173\u6ce8\u3002 \u603b\u7ed3: \u8f6f\u4ef6\u5f00\u53d1\u662f\u4e00\u9879\u5145\u6ee1\u6311\u6218\u4f46\u4e5f\u5f88\u6709\u610f\u4e49\u7684\u5de5\u4f5c\u3002\u901a\u8fc7\u638c\u63e1\u5fc5\u8981\u7684\u6280\u80fd\u548c\u77e5\u8bc6\uff0c\u5e76\u517b\u6210\u826f\u597d\u7684\u5de5\u4f5c\u4e60\u60ef\uff0c\u4f60\u5c31\u53ef\u4ee5\u6210\u4e3a\u4e00\u540d\u4f18\u79c0\u7684\u8f6f\u4ef6\u5f00\u53d1\u8005\u3002 \u4ee5\u4e0b\u662f\u4e00\u4e9b\u5177\u4f53\u7684\u5efa\u8bae: \u79ef\u6781\u53c2\u4e0e\u56e2\u961f\u8ba8\u8bba\u3002 \u63d0\u51fa\u4f60\u7684\u60f3\u6cd5\uff0c\u5e76\u4e0e\u4ed6\u4eba\u5206\u4eab\u4f60\u7684\u77e5\u8bc6\u548c\u7ecf\u9a8c\u3002 \u5584\u4e8e\u5229\u7528\u6c9f\u901a\u5de5\u5177\u3002 \u4f7f\u7528\u7535\u5b50\u90ae\u4ef6\u3001\u804a\u5929\u5de5\u5177\u548c\u5176\u4ed6\u5de5\u5177\u4e0e\u4ed6\u4eba\u4fdd\u6301\u6c9f\u901a\u3002 \u5b66\u4f1a\u7ba1\u7406\u65f6\u95f4\u3002 \u5236\u5b9a\u5de5\u4f5c\u8ba1\u5212\uff0c\u5e76\u6709\u6548\u5730\u5229\u7528\u4f60\u7684\u65f6\u95f4\u3002 \u4fdd\u6301\u826f\u597d\u7684\u5de5\u4f5c\u4e60\u60ef\u3002 \u5b9a\u671f\u6574\u7406\u4f60\u7684\u4ee3\u7801\uff0c\u5e76\u505a\u597d\u6ce8\u91ca\u3002 \u79ef\u6781\u53c2\u52a0\u884c\u4e1a\u6d3b\u52a8\u3002 \u8fd9\u662f\u4e00\u4e2a\u5f88\u597d\u7684\u5b66\u4e60\u673a\u4f1a\uff0c\u53ef\u4ee5\u8ba9\u4f60\u4e0e\u5176\u4ed6\u5f00\u53d1\u4eba\u5458\u4ea4\u6d41\u5e76\u4e86\u89e3\u6700\u65b0\u7684\u6280\u672f\u548c\u8d8b\u52bf\u3002 \u719f\u6089\u8f6f\u4ef6\u5f00\u53d1\u6d41\u7a0b\u3002 \u4e86\u89e3\u6bcf\u4e2a\u9636\u6bb5\u7684\u4efb\u52a1\u548c\u804c\u8d23\uff0c\u5e76\u80fd\u591f\u6709\u6548\u5730\u5b8c\u6210\u8fd9\u4e9b\u5de5\u4f5c\u3002 \u638c\u63e1\u5fc5\u8981\u7684\u5de5\u5177\u548c\u6280\u672f\u3002 \u4f7f\u7528\u5408\u9002\u7684\u5de5\u5177\u548c\u6280\u672f\u53ef\u4ee5\u63d0\u9ad8\u4f60\u7684\u5de5\u4f5c\u6548\u7387\u3002 \u6ce8\u91cd\u7ec6\u8282\u3002 \u8f6f\u4ef6\u5f00\u53d1\u662f\u4e00\u4e2a\u9700\u8981\u7ec6\u5fc3\u7684\u5de5\u4f5c\uff0c\u8981\u907f\u514d\u72af\u9519\u8bef\u3002 \u5584\u4e8e\u6c9f\u901a\u3002 \u4e0e\u56e2\u961f\u6210\u5458\u3001\u5ba2\u6237\u548c\u5176\u4ed6\u5229\u76ca\u76f8\u5173\u8005\u8fdb\u884c\u6709\u6548\u6c9f\u901a\uff0c\u4ee5\u786e\u4fdd\u9879\u76ee\u987a\u5229\u8fdb\u884c\u3002 \u4e94\u3001\u804c\u4e1a\u53d1\u5c55 \u00b6 \u6838\u5fc3\u601d\u60f3: \u8f6f\u4ef6\u5f00\u53d1\u8005\u7684\u804c\u4e1a\u53d1\u5c55\u4e0d\u4ec5\u4ec5\u662f\u83b7\u5f97\u66f4\u9ad8\u7684\u804c\u4f4d\u548c\u85aa\u916c\uff0c\u66f4\u91cd\u8981\u7684\u662f\u4e0d\u65ad\u5b66\u4e60\u548c\u6210\u957f\uff0c\u6210\u4e3a\u4e00\u540d\u4f18\u79c0\u7684\u8f6f\u4ef6\u5de5\u7a0b\u5e08\u3002 \u672c\u7bc7\u4ecb\u7ecd\u4e86\u5982\u4f55\u63a8\u8fdb\u4f60\u7684\u804c\u4e1a\u53d1\u5c55\u7684\u7b56\u7565\u548c\u65b9\u6cd5\uff0c\u5305\u62ec\uff1a \u5efa\u7acb\u4e2a\u4eba\u54c1\u724c \u62d3\u5c55\u4eba\u8109 \u4fdd\u6301\u5b66\u4e60 \u8d21\u732e\u793e\u533a \u5bfb\u627e\u5bfc\u5e08 \u89c4\u5212\u804c\u4e1a\u9053\u8def \u4e3b\u8981\u5185\u5bb9: \u5efa\u7acb\u4e2a\u4eba\u54c1\u724c: \u901a\u8fc7\u535a\u5ba2\u3001\u6280\u672f\u6587\u7ae0\u3001\u5f00\u6e90\u9879\u76ee\u7b49\u65b9\u5f0f\u5efa\u7acb\u4f60\u7684\u4e2a\u4eba\u54c1\u724c\uff0c\u8ba9\u66f4\u591a\u7684\u4eba\u4e86\u89e3\u4f60\u7684\u6280\u80fd\u548c\u7ecf\u9a8c\u3002 \u62d3\u5c55\u4eba\u8109: \u53c2\u52a0\u884c\u4e1a\u6d3b\u52a8\u3001\u6280\u672f\u4f1a\u8bae\u7b49\uff0c\u4e0e\u5176\u4ed6\u8f6f\u4ef6\u5f00\u53d1\u8005\u5efa\u7acb\u8054\u7cfb\uff0c\u62d3\u5c55\u4f60\u7684\u4eba\u8109\u3002 \u4fdd\u6301\u5b66\u4e60: \u4e0d\u65ad\u5b66\u4e60\u65b0\u7684\u6280\u80fd\u548c\u77e5\u8bc6\uff0c\u9605\u8bfb\u4e66\u7c4d\u3001\u53c2\u52a0\u57f9\u8bad\u8bfe\u7a0b\u7b49\uff0c\u4fdd\u6301\u4f60\u7684\u7ade\u4e89\u529b\u3002 \u8d21\u732e\u793e\u533a: \u53c2\u4e0e\u5f00\u6e90\u9879\u76ee\u3001\u6280\u672f\u793e\u533a\u7b49\uff0c\u4e3a\u793e\u533a\u505a\u51fa\u8d21\u732e\uff0c\u63d0\u5347\u4f60\u7684\u5f71\u54cd\u529b\u3002 \u5bfb\u627e\u5bfc\u5e08: \u5bfb\u627e\u4e00\u4f4d\u7ecf\u9a8c\u4e30\u5bcc\u7684\u8f6f\u4ef6\u5f00\u53d1\u8005\u4f5c\u4e3a\u4f60\u7684\u5bfc\u5e08\uff0c\u53ef\u4ee5\u5e2e\u52a9\u4f60\u5b66\u4e60\u548c\u6210\u957f\u3002 \u89c4\u5212\u804c\u4e1a\u9053\u8def: \u660e\u786e\u4f60\u7684\u804c\u4e1a\u76ee\u6807\uff0c\u5e76\u5236\u5b9a\u8ba1\u5212\u5b9e\u73b0\u4f60\u7684\u76ee\u6807\u3002 \u5173\u952e\u6b65\u9aa4: \u81ea\u6211\u8bc4\u4f30: \u8bc4\u4f30\u4f60\u7684\u6280\u80fd\u3001\u7ecf\u9a8c\u548c\u76ee\u6807\u3002 \u5236\u5b9a\u8ba1\u5212: \u5236\u5b9a\u4f60\u7684\u804c\u4e1a\u53d1\u5c55\u8ba1\u5212\uff0c\u5e76\u8bbe\u5b9a\u5177\u4f53\u7684\u76ee\u6a19\u3002 \u884c\u52a8\u8d77\u6765: \u91c7\u53d6\u884c\u52a8\uff0c\u6267\u884c\u4f60\u7684\u8ba1\u5212\u3002 \u5b9a\u671f\u56de\u987e: \u5b9a\u671f\u56de\u987e\u4f60\u7684\u8ba1\u5212\uff0c\u5e76\u8fdb\u884c\u5fc5\u8981\u7684\u8c03\u6574\u3002 \u603b\u7ed3: \u8f6f\u4ef6\u5f00\u53d1\u8005\u7684\u804c\u4e1a\u53d1\u5c55\u662f\u4e00\u4e2a\u6301\u7eed\u7684\u8fc7\u7a0b\u3002\u901a\u8fc7\u5236\u5b9a\u8ba1\u5212\u3001\u91c7\u53d6\u884c\u52a8 and \u4e0d\u65ad\u5b66\u4e60\uff0c\u4f60\u5c31\u53ef\u4ee5\u5b9e\u73b0\u4f60\u7684\u804c\u4e1a\u76ee\u6807\uff0c\u6210\u4e3a\u4e00\u540d\u4f18\u79c0\u7684\u8f6f\u4ef6\u5de5\u7a0b\u5e08\u3002 \u4ee5\u4e0b\u662f\u4e00\u4e9b\u5177\u4f53\u7684\u5efa\u8bae: \u79ef\u6781\u53c2\u4e0e\u6280\u672f\u793e\u533a\u3002 \u8fd9\u662f\u4e00\u4e2a\u5f88\u597d\u7684\u5b66\u4e60\u673a\u4f1a\uff0c\u53ef\u4ee5\u8ba9\u4f60\u4e0e\u5176\u4ed6\u5f00\u53d1\u4eba\u5458\u4ea4\u6d41\u5e76\u4e86\u89e3\u6700\u65b0\u7684\u6280\u672f\u548c\u8d8b\u52bf\u3002 \u5bfb\u627e\u4e00\u4f4d\u5bfc\u5e08\u3002 \u4e00\u4f4d\u7ecf\u9a8c\u4e30\u5bcc\u7684\u5bfc\u5e08\u53ef\u4ee5\u5e2e\u52a9\u4f60\u5b66\u4e60\u548c\u6210\u957f\uff0c\u5e76\u4e3a\u4f60\u63d0\u4f9b\u5b9d\u8d35\u7684\u5efa\u8bae\u3002 \u53c2\u52a0\u884c\u4e1a\u6d3b\u52a8\u3002 \u8fd9\u662f\u4e00\u4e2a\u5f88\u597d\u7684\u7ed3\u8bc6\u5176\u4ed6\u5f00\u53d1\u4eba\u5458\u548c\u4e86\u89e3\u884c\u4e1a\u8d8b\u52bf\u7684\u673a\u4f1a\u3002 \u5199\u535a\u5ba2\u6216\u6280\u672f\u6587\u7ae0\u3002 \u8fd9\u662f\u4e00\u4e2a\u5206\u4eab\u4f60\u7684\u77e5\u8bc6\u548c\u7ecf\u9a8c\u7684\u597d\u65b9\u6cd5\uff0c\u5e76\u5efa\u7acb\u4f60\u7684\u4e2a\u4eba\u54c1\u724c\u3002 \u5f00\u6e90\u9879\u76ee\u3002 \u8fd9\u662f\u4e00\u4e2a\u5f88\u597d\u7684\u8d21\u732e\u793e\u533a\u548c\u5b66\u4e60\u65b0\u6280\u80fd\u7684\u673a\u4f1a\u3002 \u4ee5\u4e0b\u662f\u4e00\u4e9b\u989d\u5916\u7684\u8865\u5145: \u4e66\u4e2d\u8fd8\u63d0\u5230\u4e86 \u5de5\u4f5c\u4e0e\u751f\u6d3b\u7684\u5e73\u8861 \u7684\u91cd\u8981\u6027\u3002\u5de5\u4f5c\u56fa\u7136\u91cd\u8981\uff0c\u4f46\u4e5f\u8981\u6ce8\u91cd\u4e2a\u4eba\u751f\u6d3b\u548c\u5065\u5eb7\u3002 \u4e66\u4e2d\u4e5f\u5f3a\u8c03\u4e86 \u7ec8\u8eab\u5b66\u4e60 \u7684\u91cd\u8981\u6027\u3002\u8f6f\u4ef6\u5f00\u53d1\u662f\u4e00\u4e2a\u5feb\u901f\u53d1\u5c55\u7684\u884c\u4e1a\uff0c\u4f60\u9700\u8981\u4e0d\u65ad\u5b66\u4e60\u624d\u80fd\u8ddf\u4e0a\u6700\u65b0\u7684\u6280\u672f\u548c\u8d8b\u52bf\u3002 \u4e00\u3001\u804c\u4e1a \u00b6 \u6838\u5fc3\u601d\u60f3: \u8f6f\u4ef6\u5f00\u53d1\u4eba\u5458\u7684\u804c\u4e1a\u53d1\u5c55\u4e0d\u4ec5\u4ec5\u662f\u5199\u4ee3\u7801\uff0c\u8fd8\u9700\u8981\u638c\u63e1\u5404\u79cd\u8f6f\u6280\u80fd\uff0c\u624d\u80fd\u53d6\u5f97\u6210\u529f\u3002 \u672c\u7bc7\u4ecb\u7ecd\u4e86\u8f6f\u4ef6\u5f00\u53d1\u4eba\u5458\u804c\u4e1a\u53d1\u5c55\u8fc7\u7a0b\u4e2d\u9700\u8981\u5173\u6ce8\u7684\u51e0\u4e2a\u5173\u952e\u65b9\u9762\uff0c\u5305\u62ec\uff1a \u804c\u4e1a\u89c4\u5212 \u9762\u8bd5\u6280\u5de7 \u6c9f\u901a\u80fd\u529b \u56e2\u961f\u5408\u4f5c \u65f6\u95f4\u7ba1\u7406 \u9886\u5bfc\u529b \u4e3b\u8981\u5185\u5bb9: \u804c\u4e1a\u89c4\u5212: \u8bbe\u5b9a\u804c\u4e1a\u76ee\u6807\uff0c\u5e76\u5236\u5b9a\u5b9e\u73b0\u76ee\u6807\u7684\u8ba1\u5212\u3002 \u9762\u8bd5\u6280\u5de7: \u51c6\u5907\u7b80\u5386\u548c\u9762\u8bd5\u6750\u6599\uff0c\u5e76\u7ec3\u4e60\u9762\u8bd5\u6280\u5de7\u3002 \u6c9f\u901a\u80fd\u529b: \u6e05\u6670\u6709\u6548\u5730\u8868\u8fbe\u81ea\u5df1\u7684\u60f3\u6cd5\u548c\u89c2\u70b9\u3002 \u56e2\u961f\u5408\u4f5c: \u4e0e\u4ed6\u4eba\u5408\u4f5c\u5b8c\u6210\u5171\u540c\u76ee\u6807\u3002 \u65f6\u95f4\u7ba1\u7406: \u9ad8\u6548\u5730\u5229\u7528\u65f6\u95f4\uff0c\u5b8c\u6210\u5de5\u4f5c\u4efb\u52a1\u3002 \u9886\u5bfc\u529b: \u9886\u5bfc\u56e2\u961f\u5b8c\u6210\u76ee\u6807\u3002 \u5173\u952e\u6b65\u9aa4: \u81ea\u6211\u8bc4\u4f30: \u4e86\u89e3\u81ea\u5df1\u7684\u4f18\u52bf\u3001\u52a3\u52bf\u3001\u5174\u8da3\u548c\u6280\u80fd\u3002 \u8bbe\u5b9a\u76ee\u6807: \u8bbe\u5b9a\u77ed\u671f\u548c\u957f\u671f\u7684\u804c\u4e1a\u76ee\u6807\u3002 \u5236\u5b9a\u8ba1\u5212: \u5236\u5b9a\u5b9e\u73b0\u76ee\u6807\u7684\u5177\u4f53\u8ba1\u5212\u3002 \u4e0d\u65ad\u5b66\u4e60: \u5b66\u4e60\u65b0\u6280\u80fd\u548c\u77e5\u8bc6\uff0c\u63d0\u5347\u81ea\u8eab\u80fd\u529b\u3002 \u5efa\u7acb\u4eba\u8109: \u5efa\u7acb\u4e0e\u5176\u4ed6\u5f00\u53d1\u4eba\u5458\u548c\u884c\u4e1a\u4e13\u5bb6\u7684\u8054\u7cfb\u3002 \u603b\u7ed3: \u8f6f\u4ef6\u5f00\u53d1\u4eba\u5458\u7684\u804c\u4e1a\u53d1\u5c55\u662f\u4e00\u4e2a\u6301\u7eed\u5b66\u4e60\u548c\u6210\u957f\u7684\u8fc7\u7a0b\u3002\u901a\u8fc7\u638c\u63e1\u5404\u79cd\u8f6f\u6280\u80fd\uff0c\u53ef\u4ee5\u63d0\u5347\u81ea\u8eab\u7684\u7ade\u4e89\u529b\uff0c\u5728\u804c\u4e1a\u53d1\u5c55\u4e2d\u53d6\u5f97\u6210\u529f\u3002 \u4ee5\u4e0b\u662f\u4e00\u4e9b\u5177\u4f53\u7684\u5efa\u8bae: \u5236\u5b9a\u804c\u4e1a\u89c4\u5212\u3002 \u82b1\u65f6\u95f4\u601d\u8003\u4f60\u60f3\u6210\u4e3a\u4e00\u540d\u4ec0\u4e48\u6837\u7684\u8f6f\u4ef6\u5f00\u53d1\u4eba\u5458\uff0c\u4ee5\u53ca\u4f60\u60f3\u8981\u8fbe\u6210\u7684\u804c\u4e1a\u76ee\u6807\u3002 \u4e0d\u65ad\u5b66\u4e60\u3002 \u8f6f\u4ef6\u884c\u4e1a\u53d1\u5c55\u8fc5\u901f\uff0c\u9700\u8981\u4e0d\u65ad\u5b66\u4e60\u65b0\u6280\u672f\u548c\u77e5\u8bc6\uff0c\u624d\u80fd\u4fdd\u6301\u7ade\u4e89\u529b\u3002 \u5efa\u7acb\u4eba\u8109\u3002 \u4e0e\u5176\u4ed6\u5f00\u53d1\u4eba\u5458\u548c\u884c\u4e1a\u4e13\u5bb6\u5efa\u7acb\u8054\u7cfb\uff0c\u53ef\u4ee5\u83b7\u5f97\u5b9d\u8d35\u7684\u7ecf\u9a8c\u548c\u5efa\u8bae\u3002 \u79ef\u6781\u53c2\u4e0e\u5f00\u6e90\u9879\u76ee\u3002 \u8fd9\u662f\u4e00\u4e2a\u5f88\u597d\u7684\u65b9\u5f0f\u6765\u5b66\u4e60\u65b0\u6280\u80fd\uff0c\u5e76\u83b7\u5f97\u5176\u4ed6\u5f00\u53d1\u4eba\u5458\u7684\u8ba4\u53ef\u3002 \u5bfb\u627e\u5bfc\u5e08\u3002 \u627e\u5230\u4e00\u4f4d\u7ecf\u9a8c\u4e30\u5bcc\u7684\u5bfc\u5e08\u53ef\u4ee5\u5e2e\u52a9\u4f60\u6307\u5f15\u65b9\u5411\uff0c\u5e76\u63d0\u4f9b\u5efa\u8bae\u3002 \u901a\u8fc7\u52aa\u529b\u5de5\u4f5c\u548c\u6301\u7eed\u5b66\u4e60\uff0c\u4f60\u4e00\u5b9a\u80fd\u591f\u5728\u4f60\u7684\u804c\u4e1a\u751f\u6daf\u4e2d\u53d6\u5f97\u6210\u529f\u3002 \u4e8c\u3001\u81ea\u6211\u8425\u9500 \u00b6 \u6838\u5fc3\u601d\u60f3\uff1a \u8f6f\u4ef6\u5f00\u53d1\u4eba\u5458\u9700\u8981\u5c06\u81ea\u5df1\u89c6\u4e3a\u4ea7\u54c1\uff0c\u5e76\u8fdb\u884c\u6709\u6548\u7684\u81ea\u6211\u8425\u9500\uff0c\u624d\u80fd\u5728\u804c\u4e1a\u53d1\u5c55\u4e2d\u53d6\u5f97\u6210\u529f\u3002 \u81ea\u6211\u8425\u9500\u5305\u62ec\u5efa\u7acb\u4e2a\u4eba\u54c1\u724c\u3001\u6253\u9020\u7ebf\u4e0a\u5f62\u8c61\u3001\u79ef\u6781\u53c2\u4e0e\u793e\u533a\u7b49\u591a\u4e2a\u65b9\u9762\u3002 \u4e3b\u8981\u5185\u5bb9\uff1a \u5efa\u7acb\u4e2a\u4eba\u54c1\u724c \uff1a\u660e\u786e\u81ea\u5df1\u7684\u4ef7\u503c\u4e3b\u5f20\uff0c\u5e76\u901a\u8fc7\u5404\u79cd\u6e20\u9053\u5c06\u5176\u4f20\u9012\u7ed9\u76ee\u6807\u53d7\u4f17\u3002 \u6253\u9020\u7ebf\u4e0a\u5f62\u8c61 \uff1a\u521b\u5efa\u5e76\u7ef4\u62a4\u4e2a\u4eba\u7f51\u7ad9\u3001\u535a\u5ba2\u3001\u793e\u4ea4\u5a92\u4f53\u8d26\u53f7\u7b49\uff0c\u5c55\u793a\u81ea\u5df1\u7684\u4e13\u4e1a\u6280\u80fd\u548c\u7ecf\u9a8c\u3002 \u79ef\u6781\u53c2\u4e0e\u793e\u533a \uff1a\u53c2\u52a0\u6280\u672f\u4f1a\u8bae\u3001\u5f00\u6e90\u9879\u76ee\u3001\u7ebf\u4e0a\u8bba\u575b\u7b49\uff0c\u4e0e\u5176\u4ed6\u5f00\u53d1\u4eba\u5458\u5efa\u7acb\u8054\u7cfb\uff0c\u6269\u5927\u5f71\u54cd\u529b\u3002 \u5176\u4ed6\u81ea\u6211\u8425\u9500\u7b56\u7565 \uff1a\u64b0\u5199\u6280\u672f\u6587\u7ae0\u3001\u6f14\u8bb2\u3001\u51fa\u7248\u4e66\u7c4d\u7b49\uff0c\u6811\u7acb\u884c\u4e1a\u4e13\u5bb6\u5f62\u8c61\u3002 \u5173\u952e\u6b65\u9aa4\uff1a \u81ea\u6211\u8bc4\u4f30 \uff1a\u5206\u6790\u81ea\u5df1\u7684\u4f18\u52bf\u3001\u52a3\u52bf\u3001\u6280\u80fd\u548c\u7ecf\u9a8c\uff0c\u660e\u786e\u81ea\u5df1\u7684\u804c\u4e1a\u76ee\u6807\u3002 \u5236\u5b9a\u76ee\u6807 \uff1a\u6839\u636e\u804c\u4e1a\u76ee\u6807\uff0c\u786e\u5b9a\u81ea\u6211\u8425\u9500\u7684\u5177\u4f53\u65b9\u5411\u548c\u7b56\u7565\u3002 \u6267\u884c\u7b56\u7565 \uff1a\u91c7\u53d6\u5404\u79cd\u63aa\u65bd\uff0c\u5efa\u7acb\u4e2a\u4eba\u54c1\u724c\u3001\u6253\u9020\u7ebf\u4e0a\u5f62\u8c61\u3001\u79ef\u6781\u53c2\u4e0e\u793e\u533a\u7b49\u3002 \u6301\u7eed\u6539\u8fdb \uff1a\u5b9a\u671f\u8bc4\u4f30\u81ea\u6211\u8425\u9500\u7684\u6548\u679c\uff0c\u5e76\u6839\u636e\u9700\u8981\u8fdb\u884c\u8c03\u6574\u548c\u6539\u8fdb\u3002 \u603b\u7ed3\uff1a \u81ea\u6211\u8425\u9500\u662f\u8f6f\u4ef6\u5f00\u53d1\u4eba\u5458\u5728\u804c\u4e1a\u53d1\u5c55\u4e2d\u4e0d\u53ef\u5ffd\u89c6\u7684\u91cd\u8981\u6280\u80fd\u3002\u901a\u8fc7\u6709\u6548\u7684\u81ea\u6211\u8425\u9500\uff0c\u53ef\u4ee5\u63d0\u5347\u4e2a\u4eba\u77e5\u540d\u5ea6\u3001\u5efa\u7acb\u4e13\u4e1a\u5f62\u8c61\u3001\u62d3\u5c55\u804c\u4e1a\u673a\u4f1a\uff0c\u6700\u7ec8\u5b9e\u73b0\u804c\u4e1a\u76ee\u6807\u3002 \u4ee5\u4e0b\u662f\u4e00\u4e9b\u5177\u4f53\u7684\u5efa\u8bae\uff1a \u82b1\u65f6\u95f4\u6253\u9020\u4f60\u7684\u4e2a\u4eba\u54c1\u724c\u3002 \u8fd9\u5305\u62ec\u521b\u5efa\u4e00\u4e2a\u4e2a\u4eba\u7f51\u7ad9\u6216\u535a\u5ba2\uff0c\u5e76\u5b9a\u671f\u53d1\u5e03\u9ad8\u8d28\u91cf\u7684\u5185\u5bb9\u3002 \u4f60\u4e5f\u53ef\u4ee5\u5728\u793e\u4ea4\u5a92\u4f53\u4e0a\u79ef\u6781\u53c2\u4e0e\uff0c\u5e76\u4e0e\u5176\u4ed6\u5f00\u53d1\u4eba\u5458\u5efa\u7acb\u8054\u7cfb\u3002 \u53c2\u4e0e\u5f00\u6e90\u9879\u76ee\u3002 \u8fd9\u662f\u4e00\u4e2a\u5f88\u597d\u7684\u65b9\u5f0f\u6765\u5c55\u793a\u4f60\u7684\u6280\u80fd\u548c\u7ecf\u9a8c\uff0c\u5e76\u83b7\u5f97\u5176\u4ed6\u5f00\u53d1\u4eba\u5458\u7684\u8ba4\u53ef\u3002 \u53c2\u52a0\u6280\u672f\u4f1a\u8bae\u548c\u6d3b\u52a8\u3002 \u8fd9\u662f\u4e00\u4e2a\u5f88\u597d\u7684\u65b9\u5f0f\u6765\u5b66\u4e60\u65b0\u6280\u672f\uff0c\u5e76\u7ed3\u8bc6\u5176\u4ed6\u5f00\u53d1\u4eba\u5458\u3002 \u64b0\u5199\u6280\u672f\u6587\u7ae0\u6216\u4e66\u7c4d\u3002 \u8fd9\u662f\u4e00\u4e2a\u5f88\u597d\u7684\u65b9\u5f0f\u6765\u5206\u4eab\u4f60\u7684\u77e5\u8bc6\u548c\u7ecf\u9a8c\uff0c\u5e76\u5efa\u7acb\u4f60\u7684\u4e13\u4e1a\u5f62\u8c61\u3002 \u901a\u8fc7\u52aa\u529b\u5de5\u4f5c\u548c\u6301\u7eed\u6539\u8fdb\uff0c\u4f60\u4e00\u5b9a\u80fd\u591f\u5728\u81ea\u6211\u8425\u9500\u65b9\u9762\u53d6\u5f97\u6210\u529f\u3002 \u4e09\u3001\u5b66\u4e60 \u00b6 \u6838\u5fc3\u601d\u60f3: \u5b66\u4e60\u662f\u8f6f\u4ef6\u5f00\u53d1\u4eba\u5458\u6301\u7eed\u6210\u957f\u548c\u6210\u529f\u7684\u5173\u952e\u3002 \u672c\u7bc7\u4ecb\u7ecd\u4e86\u5982\u4f55\u5feb\u901f\u6709\u6548\u5730\u5b66\u4e60\u65b0\u6280\u80fd\u548c\u77e5\u8bc6\uff0c\u5305\u62ec\uff1a \u5236\u5b9a\u5b66\u4e60\u8ba1\u5212 \u9009\u62e9\u5408\u9002\u7684\u5b66\u4e60\u8d44\u6e90 \u63d0\u9ad8\u5b66\u4e60\u6548\u7387 \u4fdd\u6301\u5b66\u4e60\u52a8\u529b \u4e3b\u8981\u5185\u5bb9: \u5236\u5b9a\u5b66\u4e60\u8ba1\u5212: \u660e\u786e\u5b66\u4e60\u76ee\u6807\uff0c\u5e76\u5236\u5b9a\u5177\u4f53\u7684\u5b66\u4e60\u8ba1\u5212\u3002 \u9009\u62e9\u5408\u9002\u7684\u5b66\u4e60\u8d44\u6e90: \u9009\u62e9\u9002\u5408\u81ea\u5df1\u7684\u5b66\u4e60\u65b9\u5f0f\u548c\u8d44\u6e90\uff0c\u4f8b\u5982\u4e66\u7c4d\u3001\u6587\u7ae0\u3001\u89c6\u9891\u3001\u8bfe\u7a0b\u7b49\u3002 \u63d0\u9ad8\u5b66\u4e60\u6548\u7387: \u638c\u63e1\u6709\u6548\u7684\u5b66\u4e60\u6280\u5de7\uff0c\u4f8b\u5982\u756a\u8304\u5de5\u4f5c\u6cd5\u3001\u8d39\u66fc\u6280\u5de7\u7b49\u3002 \u4fdd\u6301\u5b66\u4e60\u52a8\u529b: \u4fdd\u6301\u5bf9\u5b66\u4e60\u7684\u70ed\u60c5\u548c\u5174\u8da3\uff0c\u5e76\u5236\u5b9a\u6fc0\u52b1\u63aa\u65bd\u3002 \u5173\u952e\u6b65\u9aa4: \u8bbe\u5b9a\u76ee\u6807: \u660e\u786e\u4f60\u60f3\u8981\u5b66\u4e60\u4ec0\u4e48\uff0c\u4ee5\u53ca\u4f60\u60f3\u8981\u8fbe\u5230\u7684\u5b66\u4e60\u76ee\u6807\u3002 \u5236\u5b9a\u8ba1\u5212: \u5236\u5b9a\u5177\u4f53\u7684\u5b66\u4e60\u8ba1\u5212\uff0c\u5305\u62ec\u5b66\u4e60\u5185\u5bb9\u3001\u5b66\u4e60\u65f6\u95f4\u548c\u5b66\u4e60\u65b9\u6cd5\u7b49\u3002 \u9009\u62e9\u8d44\u6e90: \u9009\u62e9\u9002\u5408\u81ea\u5df1\u7684\u5b66\u4e60\u65b9\u5f0f\u548c\u8d44\u6e90\uff0c\u5e76\u786e\u4fdd\u8d44\u6e90\u7684\u8d28\u91cf\u548c\u53ef\u9760\u6027\u3002 \u4ed8\u8bf8\u884c\u52a8: \u6309\u7167\u8ba1\u5212\u5f00\u59cb\u5b66\u4e60\uff0c\u5e76\u5b9a\u671f\u8bc4\u4f30\u5b66\u4e60\u8fdb\u5ea6\u548c\u6548\u679c\u3002 \u4fdd\u6301\u52a8\u529b: \u4fdd\u6301\u5bf9\u5b66\u4e60\u7684\u70ed\u60c5\u548c\u5174\u8da3\uff0c\u5e76\u5236\u5b9a\u6fc0\u52b1\u63aa\u65bd\u3002 \u603b\u7ed3: \u5b66\u4e60\u662f\u4e00\u4e2a\u9700\u8981\u4e0d\u65ad\u5b9e\u8df5\u548c\u6539\u8fdb\u7684\u8fc7\u7a0b\u3002\u901a\u8fc7\u638c\u63e1\u6709\u6548\u7684\u5b66\u4e60\u65b9\u6cd5\uff0c\u53ef\u4ee5\u63d0\u9ad8\u5b66\u4e60\u6548\u7387\uff0c\u5e76\u53d6\u5f97\u66f4\u597d\u7684\u5b66\u4e60\u6210\u679c\u3002 \u4ee5\u4e0b\u662f\u4e00\u4e9b\u5177\u4f53\u7684\u5efa\u8bae: \u5236\u5b9a\u5177\u4f53\u7684\u5b66\u4e60\u76ee\u6807\u3002 \u76ee\u6807\u8d8a\u5177\u4f53\uff0c\u5c31\u8d8a\u5bb9\u6613\u5b9e\u73b0\u3002 \u5c06\u5b66\u4e60\u4efb\u52a1\u5206\u89e3\u6210\u5c0f\u5757\u3002 \u8fd9\u6837\u66f4\u5bb9\u6613\u5b8c\u6210\uff0c\u4e5f\u80fd\u8ba9\u4f60\u4fdd\u6301\u5b66\u4e60\u7684\u52a8\u529b\u3002 \u627e\u5230\u9002\u5408\u81ea\u5df1\u7684\u5b66\u4e60\u65b9\u5f0f\u3002 \u6709\u4e9b\u4eba\u559c\u6b22\u770b\u4e66\uff0c\u6709\u4e9b\u4eba\u559c\u6b22\u770b\u89c6\u9891\uff0c\u6709\u4e9b\u4eba\u559c\u6b22\u53c2\u52a0\u8bfe\u7a0b\u3002 \u5229\u7528\u788e\u7247\u65f6\u95f4\u5b66\u4e60\u3002 \u5229\u7528\u901a\u52e4\u65f6\u95f4\u3001\u5348\u4f11\u65f6\u95f4\u7b49\u788e\u7247\u65f6\u95f4\u5b66\u4e60\uff0c\u53ef\u4ee5\u63d0\u9ad8\u5b66\u4e60\u6548\u7387\u3002 \u4e0e\u4ed6\u4eba\u4e00\u8d77\u5b66\u4e60\u3002 \u4e0e\u4ed6\u4eba\u4e00\u8d77\u5b66\u4e60\u53ef\u4ee5\u4e92\u76f8\u9f13\u52b1\uff0c\u4e92\u76f8\u5e2e\u52a9\u3002 \u901a\u8fc7\u52aa\u529b\u5b66\u4e60\u548c\u4e0d\u65ad\u5b9e\u8df5\uff0c\u4f60\u4e00\u5b9a\u80fd\u591f\u5728\u4f60\u7684\u804c\u4e1a\u751f\u6daf\u4e2d\u53d6\u5f97\u6210\u529f\u3002 \u56db\u3001\u751f\u4ea7\u529b \u00b6 \u6838\u5fc3\u601d\u60f3: \u63d0\u9ad8\u751f\u4ea7\u529b\u662f\u8f6f\u4ef6\u5f00\u53d1\u4eba\u5458\u53d6\u5f97\u6210\u529f\u7684\u5173\u952e\u56e0\u7d20\u4e4b\u4e00\u3002 \u672c\u7bc7\u4ecb\u7ecd\u4e86\u5982\u4f55\u63d0\u9ad8\u5de5\u4f5c\u6548\u7387\u548c\u4ea7\u51fa\uff0c\u5305\u62ec\uff1a \u65f6\u95f4\u7ba1\u7406 \u4efb\u52a1\u7ba1\u7406 \u4e13\u6ce8\u529b \u6c9f\u901a\u6280\u5de7 \u907f\u514d\u5e72\u6270 \u4e3b\u8981\u5185\u5bb9: \u65f6\u95f4\u7ba1\u7406: \u6709\u6548\u5730\u5229\u7528\u65f6\u95f4\uff0c\u5b8c\u6210\u5de5\u4f5c\u4efb\u52a1\u3002 \u4efb\u52a1\u7ba1\u7406: \u5236\u5b9a\u4efb\u52a1\u8ba1\u5212\uff0c\u5e76\u6709\u6548\u5730\u8ddf\u8e2a\u4efb\u52a1\u8fdb\u5ea6\u3002 \u4e13\u6ce8\u529b: \u63d0\u9ad8\u5de5\u4f5c\u65f6\u7684\u4e13\u6ce8\u5ea6\uff0c\u907f\u514d\u5206\u5fc3\u3002 \u6c9f\u901a\u6280\u5de7: \u6e05\u6670\u6709\u6548\u5730\u4e0e\u4ed6\u4eba\u6c9f\u901a\uff0c\u907f\u514d\u8bef\u89e3\u548c\u6d6a\u8d39\u65f6\u95f4\u3002 \u907f\u514d\u5e72\u6270: \u51cf\u5c11\u5de5\u4f5c\u73af\u5883\u4e2d\u7684\u5e72\u6270\u56e0\u7d20\uff0c\u63d0\u9ad8\u5de5\u4f5c\u6548\u7387\u3002 \u5173\u952e\u6b65\u9aa4: \u8bc4\u4f30\u73b0\u72b6: \u8bc4\u4f30\u5f53\u524d\u7684\u5de5\u4f5c\u6548\u7387\u548c\u4ea7\u51fa\u6c34\u5e73\u3002 \u8bbe\u5b9a\u76ee\u6807: \u8bbe\u5b9a\u63d0\u9ad8\u751f\u4ea7\u529b\u7684\u76ee\u6807\u3002 \u5236\u5b9a\u8ba1\u5212: \u5236\u5b9a\u5177\u4f53\u7684\u63d0\u9ad8\u751f\u4ea7\u529b\u7684\u8ba1\u5212\u3002 \u4ed8\u8bf8\u884c\u52a8: \u6309\u7167\u8ba1\u5212\u5f00\u59cb\u5b9e\u65bd\uff0c\u5e76\u5b9a\u671f\u8bc4\u4f30\u6548\u679c\u3002 \u6301\u7eed\u6539\u8fdb: \u4e0d\u65ad\u5bfb\u627e\u65b0\u7684\u65b9\u6cd5\u548c\u5de5\u5177\u6765\u63d0\u9ad8\u751f\u4ea7\u529b\u3002 \u603b\u7ed3: \u63d0\u9ad8\u751f\u4ea7\u529b\u662f\u4e00\u4e2a\u9700\u8981\u4e0d\u65ad\u5b9e\u8df5\u548c\u6539\u8fdb\u7684\u8fc7\u7a0b\u3002\u901a\u8fc7\u638c\u63e1\u6709\u6548\u7684\u65f6\u95f4\u7ba1\u7406\u3001\u4efb\u52a1\u7ba1\u7406\u3001\u6c9f\u901a\u6280\u5de7\u7b49\u65b9\u6cd5\uff0c\u53ef\u4ee5\u63d0\u9ad8\u5de5\u4f5c\u6548\u7387\uff0c\u5e76\u53d6\u5f97\u66f4\u597d\u7684\u5de5\u4f5c\u6210\u679c\u3002 \u4ee5\u4e0b\u662f\u4e00\u4e9b\u5177\u4f53\u7684\u5efa\u8bae: \u4f7f\u7528\u65f6\u95f4\u7ba1\u7406\u5de5\u5177\u3002 \u8bb8\u591a\u65f6\u95f4\u7ba1\u7406\u5de5\u5177\u53ef\u4ee5\u5e2e\u52a9\u4f60\u8ddf\u8e2a\u65f6\u95f4\u3001\u5236\u5b9a\u8ba1\u5212\u548c\u63d0\u9ad8\u6548\u7387\u3002 \u5236\u5b9a\u4efb\u52a1\u6e05\u5355\u3002 \u5c06\u6240\u6709\u5f85\u529e\u4e8b\u9879\u5217\u5165\u6e05\u5355\uff0c\u5e76\u6309\u7167\u4f18\u5148\u7ea7\u6392\u5e8f\u3002 \u8bbe\u5b9a\u622a\u6b62\u65e5\u671f\u3002 \u4e3a\u6bcf\u4e2a\u4efb\u52a1\u8bbe\u5b9a\u622a\u6b62\u65e5\u671f\uff0c\u53ef\u4ee5\u5e2e\u52a9\u4f60\u63d0\u9ad8\u5de5\u4f5c\u6548\u7387\u3002 \u907f\u514d\u591a\u4efb\u52a1\u5904\u7406\u3002 \u540c\u65f6\u5904\u7406\u591a\u4e2a\u4efb\u52a1\u4f1a\u964d\u4f4e\u6548\u7387\uff0c\u5bfc\u81f4\u9519\u8bef\u3002 \u521b\u9020\u826f\u597d\u7684\u5de5\u4f5c\u73af\u5883\u3002 \u627e\u5230\u4e00\u4e2a\u5b89\u9759\u3001\u8212\u9002\u7684\u5de5\u4f5c\u73af\u5883\uff0c\u53ef\u4ee5\u5e2e\u52a9\u4f60\u63d0\u9ad8\u4e13\u6ce8\u529b\u3002 \u901a\u8fc7\u52aa\u529b\u63d0\u9ad8\u751f\u4ea7\u529b\uff0c\u4f60\u4e00\u5b9a\u80fd\u591f\u5728\u4f60\u7684\u804c\u4e1a\u751f\u6daf\u4e2d\u53d6\u5f97\u66f4\u5927\u7684\u6210\u529f\u3002 \u4ee5\u4e0b\u662f\u4e00\u4e9b\u989d\u5916\u7684\u8865\u5145: \u4e66\u4e2d\u8fd8\u63d0\u5230\u4e86 \u81ea\u52a8\u5316 \u7684\u91cd\u8981\u6027\u3002\u901a\u8fc7\u4f7f\u7528\u81ea\u52a8\u5316\u5de5\u5177\uff0c\u53ef\u4ee5\u5c06\u4e00\u4e9b\u91cd\u590d\u6027\u5de5\u4f5c\u81ea\u52a8\u5316\uff0c\u4ece\u800c\u8282\u7701\u65f6\u95f4\u548c\u7cbe\u529b\u3002 \u4e66\u4e2d\u4e5f\u5f3a\u8c03\u4e86 \u5065\u5eb7 \u7684\u91cd\u8981\u6027\u3002\u4fdd\u6301\u5065\u5eb7\u7684\u8eab\u4f53\u548c\u5fc3\u7406\u72b6\u6001\uff0c\u624d\u80fd\u66f4\u597d\u5730\u5de5\u4f5c\u548c\u5b66\u4e60\u3002 \u4e94\u3001\u7406\u8d22 \u00b6 \u6838\u5fc3\u601d\u60f3: \u7406\u8d22\u662f\u8f6f\u4ef6\u5f00\u53d1\u4eba\u5458\u9700\u8981\u638c\u63e1\u7684\u91cd\u8981\u6280\u80fd\u4e4b\u4e00\uff0c\u53ef\u4ee5\u5e2e\u52a9\u4ed6\u4eec\u5b9e\u73b0\u8d22\u52a1\u76ee\u6807\uff0c\u5e76\u83b7\u5f97\u8d22\u52a1\u5b89\u5168\u611f\u3002 \u672c\u7bc7\u4ecb\u7ecd\u4e86\u7406\u8d22\u7684\u57fa\u672c\u6982\u5ff5\u548c\u539f\u5219\uff0c\u5305\u62ec\uff1a \u8bbe\u5b9a\u8d22\u52a1\u76ee\u6807 \u5236\u5b9a\u9884\u7b97 \u6295\u8d44\u7406\u8d22 \u9000\u4f11\u89c4\u5212 \u907f\u514d\u5e38\u89c1\u7684\u7406\u8d22\u9519\u8bef \u4e3b\u8981\u5185\u5bb9: \u8bbe\u5b9a\u8d22\u52a1\u76ee\u6807: \u660e\u786e\u4f60\u7684\u77ed\u671f\u548c\u957f\u671f\u7684\u8d22\u52a1\u76ee\u6807\uff0c\u4f8b\u5982\u8d2d\u4e70\u623f\u5c4b\u3001\u9000\u4f11\u517b\u8001\u7b49\u3002 \u5236\u5b9a\u9884\u7b97: \u8bb0\u5f55\u4f60\u7684\u6536\u5165\u548c\u652f\u51fa\uff0c\u5e76\u5236\u5b9a\u5408\u7406\u7684\u9884\u7b97\u8ba1\u5212\u3002 \u6295\u8d44\u7406\u8d22: \u5b66\u4e60\u6295\u8d44\u7406\u8d22\u77e5\u8bc6\uff0c\u5e76\u9009\u62e9\u9002\u5408\u81ea\u5df1\u7684\u6295\u8d44\u65b9\u5f0f\u3002 \u9000\u4f11\u89c4\u5212: \u63d0\u524d\u505a\u597d\u9000\u4f11\u89c4\u5212\uff0c\u786e\u4fdd\u9000\u4f11\u540e\u7684\u751f\u6d3b\u8d28\u91cf\u3002 \u907f\u514d\u5e38\u89c1\u7684\u7406\u8d22\u9519\u8bef: \u4e86\u89e3\u5e38\u89c1\u7684\u7406\u8d22\u9519\u8bef\uff0c\u5e76\u907f\u514d\u5728\u7406\u8d22\u8fc7\u7a0b\u4e2d\u72af\u9519\u3002 \u5173\u952e\u6b65\u9aa4: \u8bc4\u4f30\u73b0\u72b6: \u8bc4\u4f30\u5f53\u524d\u7684\u8d22\u52a1\u72b6\u51b5\uff0c\u5305\u62ec\u6536\u5165\u3001\u652f\u51fa\u3001\u8d44\u4ea7\u548c\u8d1f\u503a\u7b49\u3002 \u8bbe\u5b9a\u76ee\u6807: \u660e\u786e\u4f60\u7684\u77ed\u671f\u548c\u957f\u671f\u7684\u8d22\u52a1\u76ee\u6807\u3002 \u5236\u5b9a\u8ba1\u5212: \u5236\u5b9a\u5177\u4f53\u7684\u7406\u8d22\u8ba1\u5212\uff0c\u5305\u62ec\u9884\u7b97\u3001\u6295\u8d44\u548c\u9000\u4f11\u89c4\u5212\u7b49\u3002 \u4ed8\u8bf8\u884c\u52a8: \u6309\u7167\u8ba1\u5212\u5f00\u59cb\u5b9e\u65bd\uff0c\u5e76\u5b9a\u671f\u8bc4\u4f30\u6548\u679c\u3002 \u6301\u7eed\u5b66\u4e60: \u4e0d\u65ad\u5b66\u4e60\u7406\u8d22\u77e5\u8bc6\uff0c\u5e76\u6839\u636e\u60c5\u51b5\u8c03\u6574\u4f60\u7684\u7406\u8d22\u7b56\u7565\u3002 \u603b\u7ed3: \u7406\u8d22\u662f\u4e00\u4e2a\u9700\u8981\u957f\u671f\u575a\u6301\u7684\u8fc7\u7a0b\u3002\u901a\u8fc7\u638c\u63e1\u7406\u8d22\u7684\u57fa\u672c\u77e5\u8bc6\u548c\u6280\u80fd\uff0c\u53ef\u4ee5\u5e2e\u52a9\u4f60\u5b9e\u73b0\u8d22\u52a1\u76ee\u6807\uff0c\u5e76\u83b7\u5f97\u66f4\u597d\u7684\u751f\u6d3b\u3002 \u4ee5\u4e0b\u662f\u4e00\u4e9b\u5177\u4f53\u7684\u5efa\u8bae: \u5c3d\u65e9\u5f00\u59cb\u7406\u8d22\u3002 \u8d8a\u65e9\u5f00\u59cb\u7406\u8d22\uff0c\u4f60\u7684\u65f6\u95f4\u548c\u91d1\u94b1\u5c31\u8d8a\u6709\u4ef7\u503c\u3002 \u517b\u6210\u826f\u597d\u7684\u6d88\u8d39\u4e60\u60ef\u3002 \u907f\u514d\u51b2\u52a8\u6d88\u8d39\uff0c\u5e76\u5b66\u4f1a\u5ef6\u8fdf\u6ee1\u8db3\u3002 \u5b9a\u671f\u8fdb\u884c\u8d22\u52a1\u68c0\u67e5\u3002 \u5b9a\u671f\u68c0\u67e5\u4f60\u7684\u8d22\u52a1\u72b6\u51b5\uff0c\u5e76\u6839\u636e\u9700\u8981\u8c03\u6574\u4f60\u7684\u7406\u8d22\u8ba1\u5212\u3002 \u5bfb\u6c42\u4e13\u4e1a\u5e2e\u52a9\u3002 \u5982\u679c\u9700\u8981\uff0c\u53ef\u4ee5\u5bfb\u6c42\u7406\u8d22\u987e\u95ee\u7684\u5e2e\u52a9\u3002 \u4ee5\u4e0b\u662f\u4e00\u4e9b\u989d\u5916\u7684\u8865\u5145: \u4e66\u4e2d\u8fd8\u63d0\u5230\u4e86 \u4fdd\u9669 \u7684\u91cd\u8981\u6027\u3002\u901a\u8fc7\u8d2d\u4e70\u4fdd\u9669\uff0c\u53ef\u4ee5\u8f6c\u79fb\u98ce\u9669\uff0c\u5e76\u63d0\u4f9b\u5fc5\u8981\u7684\u4fdd\u969c\u3002 \u4e66\u4e2d\u4e5f\u5f3a\u8c03\u4e86 \u7a0e\u6536\u89c4\u5212 \u7684\u91cd\u8981\u6027\u3002\u901a\u8fc7\u5408\u7406\u7684\u7a0e\u6536\u89c4\u5212\uff0c\u53ef\u4ee5\u51cf\u5c11\u7a0e\u6536\u8d1f\u62c5\u3002 \u516d\u3001\u5065\u8eab \u00b6 \u6838\u5fc3\u601d\u60f3: \u5065\u8eab\u662f\u8f6f\u4ef6\u5f00\u53d1\u4eba\u5458\u4fdd\u6301\u5065\u5eb7\u548c\u6d3b\u529b\uff0c\u63d0\u9ad8\u5de5\u4f5c\u6548\u7387\u7684\u91cd\u8981\u9014\u5f84\u3002 \u672c\u7bc7\u4ecb\u7ecd\u4e86\u5065\u8eab\u7684\u57fa\u672c\u77e5\u8bc6\u548c\u65b9\u6cd5\uff0c\u5305\u62ec\uff1a \u5236\u5b9a\u5065\u8eab\u76ee\u6807 \u9009\u62e9\u9002\u5408\u7684\u8fd0\u52a8\u65b9\u5f0f \u996e\u98df\u5065\u5eb7 \u7761\u7720\u5145\u8db3 \u907f\u514d\u4e45\u5750 \u4e3b\u8981\u5185\u5bb9: \u5236\u5b9a\u5065\u8eab\u76ee\u6807: \u660e\u786e\u4f60\u7684\u5065\u8eab\u76ee\u6807\uff0c\u4f8b\u5982\u51cf\u80a5\u3001\u589e\u808c\u3001\u63d0\u9ad8\u8010\u529b\u7b49\u3002 \u9009\u62e9\u9002\u5408\u7684\u8fd0\u52a8\u65b9\u5f0f: \u6839\u636e\u4f60\u7684\u5174\u8da3\u3001\u8eab\u4f53\u72b6\u51b5\u548c\u65f6\u95f4\u5b89\u6392\uff0c\u9009\u62e9\u9002\u5408\u7684\u8fd0\u52a8\u65b9\u5f0f\u3002 \u996e\u98df\u5065\u5eb7: \u4fdd\u6301\u5065\u5eb7\u7684\u996e\u98df\u4e60\u60ef\uff0c\u591a\u5403\u852c\u83dc\u6c34\u679c\u3001\u5168\u8c37\u7269\u548c\u7626\u8089\u7b49\u3002 \u7761\u7720\u5145\u8db3: \u4fdd\u8bc1\u5145\u8db3\u7684\u7761\u7720\uff0c\u8ba9\u8eab\u4f53\u5f97\u5230\u5145\u5206\u4f11\u606f\u3002 \u907f\u514d\u4e45\u5750: \u907f\u514d\u957f\u65f6\u95f4\u5750\u7740\u4e0d\u52a8\uff0c\u6bcf\u5c0f\u65f6\u8d77\u8eab\u6d3b\u52a8\u51e0\u5206\u949f\u3002 \u5173\u952e\u6b65\u9aa4: \u8bc4\u4f30\u73b0\u72b6: \u8bc4\u4f30\u5f53\u524d\u7684\u8eab\u4f53\u72b6\u51b5\uff0c\u5305\u62ec\u4f53\u91cd\u3001\u4f53\u8102\u7387\u3001\u808c\u8089\u91cf\u7b49\u3002 \u8bbe\u5b9a\u76ee\u6807: \u660e\u786e\u4f60\u7684\u5065\u8eab\u76ee\u6807\u3002 \u5236\u5b9a\u8ba1\u5212: \u5236\u5b9a\u5177\u4f53\u7684\u5065\u8eab\u8ba1\u5212\uff0c\u5305\u62ec\u8fd0\u52a8\u65b9\u5f0f\u3001\u996e\u98df\u548c\u7761\u7720\u7b49\u3002 \u4ed8\u8bf8\u884c\u52a8: \u6309\u7167\u8ba1\u5212\u5f00\u59cb\u5b9e\u65bd\uff0c\u5e76\u5b9a\u671f\u8bc4\u4f30\u6548\u679c\u3002 \u4fdd\u6301\u575a\u6301: \u5065\u8eab\u662f\u4e00\u4e2a\u9700\u8981\u957f\u671f\u575a\u6301\u7684\u8fc7\u7a0b\uff0c\u4e0d\u8981\u8f7b\u6613\u653e\u5f03\u3002 \u603b\u7ed3: \u5065\u8eab\u662f\u4e00\u4e2a\u9700\u8981\u957f\u671f\u575a\u6301\u7684\u8fc7\u7a0b\u3002\u901a\u8fc7\u638c\u63e1\u5065\u8eab\u7684\u57fa\u672c\u77e5\u8bc6\u548c\u65b9\u6cd5\uff0c\u53ef\u4ee5\u5e2e\u52a9\u4f60\u4fdd\u6301\u5065\u5eb7\u548c\u6d3b\u529b\uff0c\u63d0\u9ad8\u5de5\u4f5c\u6548\u7387\uff0c\u5e76\u83b7\u5f97\u66f4\u597d\u7684\u751f\u6d3b\u3002 \u4ee5\u4e0b\u662f\u4e00\u4e9b\u5177\u4f53\u7684\u5efa\u8bae: \u5faa\u5e8f\u6e10\u8fdb\uff0c\u4e0d\u8981\u6025\u4e8e\u6c42\u6210\u3002 \u521a\u5f00\u59cb\u5065\u8eab\u65f6\uff0c\u4e0d\u8981\u8fdb\u884c\u8fc7\u4e8e\u5267\u70c8\u7684\u8fd0\u52a8\uff0c\u4ee5\u514d\u9020\u6210\u8fd0\u52a8\u635f\u4f24\u3002 \u627e\u5230\u9002\u5408\u81ea\u5df1\u7684\u8fd0\u52a8\u65b9\u5f0f\u3002 \u9009\u62e9\u4f60\u559c\u6b22\u7684\u8fd0\u52a8\u65b9\u5f0f\uff0c\u8fd9\u6837\u4f60\u624d\u80fd\u575a\u6301\u4e0b\u53bb\u3002 \u5c06\u5065\u8eab\u878d\u5165\u5230\u4f60\u7684\u65e5\u5e38\u751f\u6d3b\u3002 \u4f8b\u5982\uff0c\u4f60\u53ef\u4ee5\u6bcf\u5929\u6b65\u884c\u4e0a\u4e0b\u73ed\uff0c\u6216\u8005\u5229\u7528\u5348\u4f11\u65f6\u95f4\u8fdb\u884c\u953b\u70bc\u3002 \u5bfb\u627e\u5065\u8eab\u4f19\u4f34\u3002 \u4e0e\u670b\u53cb\u6216\u5bb6\u4eba\u4e00\u8d77\u5065\u8eab\uff0c\u53ef\u4ee5\u4e92\u76f8\u9f13\u52b1\uff0c\u4e92\u76f8\u5e2e\u52a9\u3002 \u4ee5\u4e0b\u662f\u4e00\u4e9b\u989d\u5916\u7684\u8865\u5145: \u4e66\u4e2d\u8fd8\u63d0\u5230\u4e86 \u538b\u529b\u7ba1\u7406 \u7684\u91cd\u8981\u6027\u3002\u901a\u8fc7\u5408\u7406\u7684\u538b\u529b\u7ba1\u7406\uff0c\u53ef\u4ee5\u51cf\u5c11\u538b\u529b\u5bf9\u8eab\u4f53\u7684\u8d1f\u9762\u5f71\u54cd\u3002 \u4e66\u4e2d\u4e5f\u5f3a\u8c03\u4e86 \u5fc3\u7406\u5065\u5eb7 \u7684\u91cd\u8981\u6027\u3002\u4fdd\u6301\u826f\u597d\u7684\u5fc3\u7406\u5065\u5eb7\uff0c\u624d\u80fd\u66f4\u597d\u5730\u5de5\u4f5c\u548c\u751f\u6d3b\u3002 \u4e03\u3001\u5fc3\u6001 \u00b6 \u6838\u5fc3\u601d\u60f3: \u5fc3\u6001\u662f\u8f6f\u4ef6\u5f00\u53d1\u4eba\u5458\u53d6\u5f97\u6210\u529f\u7684\u91cd\u8981\u56e0\u7d20\u4e4b\u4e00\u3002\u62e5\u6709\u79ef\u6781\u4e50\u89c2\u7684\u5fc3\u6001\uff0c\u53ef\u4ee5\u5e2e\u52a9\u4ed6\u4eec\u514b\u670d\u56f0\u96be\uff0c\u53d6\u5f97\u66f4\u5927\u7684\u6210\u5c31\u3002 \u672c\u7bc7\u4ecb\u7ecd\u4e86\u5982\u4f55\u57f9\u517b\u79ef\u6781\u4e50\u89c2\u7684\u5fc3\u6001\uff0c\u5305\u62ec\uff1a \u8ba4\u8bc6\u81ea\u5df1\u7684\u601d\u7ef4\u6a21\u5f0f \u6311\u6218\u8d1f\u9762\u601d\u7ef4 \u7ec3\u4e60\u6b63\u5ff5 \u57f9\u517b\u611f\u6069\u4e4b\u5fc3 \u4fdd\u6301\u6210\u957f\u578b\u601d\u7ef4 \u4e3b\u8981\u5185\u5bb9: \u8ba4\u8bc6\u81ea\u5df1\u7684\u601d\u7ef4\u6a21\u5f0f: \u4e86\u89e3\u81ea\u5df1\u7684\u601d\u7ef4\u6a21\u5f0f\uff0c\u8bc6\u522b\u5e38\u89c1\u7684\u601d\u7ef4\u8bef\u533a\u3002 \u6311\u6218\u8d1f\u9762\u601d\u7ef4: \u6311\u6218\u8d1f\u9762\u60f3\u6cd5\uff0c\u7528\u79ef\u6781\u7684\u60f3\u6cd5\u66ff\u6362\u5b83\u4eec\u3002 \u7ec3\u4e60\u6b63\u5ff5: \u7ec3\u4e60\u6b63\u5ff5\uff0c\u6d3b\u5728\u5f53\u4e0b\uff0c\u4e13\u6ce8\u4e8e\u4f60\u73b0\u5728\u6240\u505a\u7684\u4e8b\u60c5\u3002 \u57f9\u517b\u611f\u6069\u4e4b\u5fc3: \u57f9\u517b\u611f\u6069\u4e4b\u5fc3\uff0c\u5b66\u4f1a\u6b23\u8d4f\u4f60\u6240\u62e5\u6709\u7684\u3002 \u4fdd\u6301\u6210\u957f\u578b\u601d\u7ef4: \u76f8\u4fe1\u81ea\u5df1\u53ef\u4ee5\u901a\u8fc7\u52aa\u529b\u5b66\u4e60\u548c\u6210\u957f\uff0c\u4e0d\u65ad\u8fdb\u6b65\u3002 \u5173\u952e\u6b65\u9aa4: \u81ea\u6211\u89c9\u5bdf: \u89c2\u5bdf\u4f60\u7684\u60f3\u6cd5\u548c\u611f\u53d7\uff0c\u5e76\u4e86\u89e3\u5b83\u4eec\u662f\u5982\u4f55\u5f71\u54cd\u4f60\u7684\u884c\u4e3a\u7684\u3002 \u6311\u6218\u8d1f\u9762\u601d\u7ef4: \u5f53\u4f60\u51fa\u73b0\u8d1f\u9762\u60f3\u6cd5\u65f6\uff0c\u95ee\u4e00\u95ee\u81ea\u5df1\u8fd9\u4e9b\u60f3\u6cd5\u662f\u5426\u5408\u7406\uff0c\u5e76\u7528\u66f4\u79ef\u6781\u7684\u60f3\u6cd5\u66ff\u6362\u5b83\u4eec\u3002 \u7ec3\u4e60\u6b63\u5ff5: \u6bcf\u5929\u82b1\u4e00\u4e9b\u65f6\u95f4\u7ec3\u4e60\u6b63\u5ff5\uff0c\u4f8b\u5982\u51a5\u60f3\u6216\u745c\u4f3d\u3002 \u611f\u6069\u7ec3\u4e60: \u5199\u611f\u6069\u65e5\u8bb0\uff0c\u6216\u8005\u5b9a\u671f\u5217\u51fa\u4f60\u6240\u611f\u6fc0\u7684\u4e8b\u60c5\u3002 \u4fdd\u6301\u6210\u957f\u578b\u601d\u7ef4: \u9047\u5230\u6311\u6218\u65f6\uff0c\u4e0d\u8981\u8f7b\u6613\u653e\u5f03\uff0c\u76f8\u4fe1\u81ea\u5df1\u53ef\u4ee5\u901a\u8fc7\u52aa\u529b\u514b\u670d\u56f0\u96be\u3002 \u603b\u7ed3: \u62e5\u6709\u79ef\u6781\u4e50\u89c2\u7684\u5fc3\u6001\uff0c\u53ef\u4ee5\u5e2e\u52a9\u8f6f\u4ef6\u5f00\u53d1\u4eba\u5458\u5728\u804c\u4e1a\u53d1\u5c55\u4e2d\u53d6\u5f97\u66f4\u5927\u7684\u6210\u5c31\u3002\u901a\u8fc7\u7ec3\u4e60\u548c\u81ea\u6211\u89c9\u5bdf\uff0c\u53ef\u4ee5\u57f9\u517b\u79ef\u6781\u4e50\u89c2\u7684\u5fc3\u6001\uff0c\u5e76\u514b\u670d\u56f0\u96be\uff0c\u53d6\u5f97\u6210\u529f\u3002 \u4ee5\u4e0b\u662f\u4e00\u4e9b\u5177\u4f53\u7684\u5efa\u8bae: \u9605\u8bfb\u52b1\u5fd7\u4e66\u7c4d\u548c\u6587\u7ae0\u3002 \u79ef\u6781\u7684\u4e66\u7c4d\u548c\u6587\u7ae0\u53ef\u4ee5\u5e2e\u52a9\u4f60\u5efa\u7acb\u79ef\u6781\u7684\u601d\u7ef4\u6a21\u5f0f\u3002 \u4e0e\u79ef\u6781\u4e50\u89c2\u7684\u4eba\u4ea4\u670b\u53cb\u3002 \u4e0e\u79ef\u6781\u4e50\u89c2\u7684\u4eba\u5728\u4e00\u8d77\uff0c\u53ef\u4ee5\u5e2e\u52a9\u4f60\u63d0\u5347\u81ea\u5df1\u7684\u5fc3\u6001\u3002 \u5e2e\u52a9\u4ed6\u4eba\u3002 \u5e2e\u52a9\u4ed6\u4eba\u53ef\u4ee5\u8ba9\u4f60\u611f\u5230\u5feb\u4e50\u548c\u6ee1\u8db3\uff0c\u5e76\u63d0\u5347\u4f60\u7684\u81ea\u4fe1\u5fc3\u3002 \u5b66\u4f1a\u653e\u677e\u3002 \u538b\u529b\u4f1a\u9020\u6210\u8d1f\u9762\u60c5\u7eea\uff0c\u56e0\u6b64\u8981\u5b66\u4f1a\u653e\u677e\uff0c\u4f8b\u5982\u8fd0\u52a8\u3001\u51a5\u60f3\u6216\u542c\u97f3\u4e50\u3002 \u4ee5\u4e0b\u662f\u4e00\u4e9b\u989d\u5916\u7684\u8865\u5145: \u4e66\u4e2d\u8fd8\u63d0\u5230\u4e86 \u65f6\u95f4\u7ba1\u7406 \u7684\u91cd\u8981\u6027\u3002\u901a\u8fc7\u5408\u7406\u7684\u5b89\u6392\u65f6\u95f4\uff0c\u53ef\u4ee5\u907f\u514d\u538b\u529b\u548c\u7126\u8651\u3002 \u4e66\u4e2d\u4e5f\u5f3a\u8c03\u4e86 \u7761\u7720 \u7684\u91cd\u8981\u6027\u3002\u5145\u8db3\u7684\u7761\u7720\u53ef\u4ee5\u5e2e\u52a9\u4f60\u4fdd\u6301\u826f\u597d\u7684\u7cbe\u795e\u72b6\u6001\u3002","title":"\u7a0b\u5e8f\u5458\u7684\u804c\u4e1a\u548c\u751f\u5b58\u6307\u5357"},{"location":"Reading/Developers/#-2","text":"2024\u5e74\u5143\u65e6\u540e\u8bfb\u4e86\u7ea6\u7ff0\u00b7\u68ee\u6885\u5179\uff08John Sonmez\uff09\u76842\u672c\u4e66\uff0c\u5f88\u6709\u5171\u9e23\uff0c\u4ea7\u751f\u4e86\u5199\u8bfb\u4e66\u611f\u60f3\u7684\u5ff5\u5934\uff0c\u501f\u673a\u4e5f\u68b3\u7406\u4e86\u6211\u4e2a\u4eba\u7684\u89c2\u70b9\u548c\u60f3\u6cd5\uff0c\u4e8e\u662f\u4fbf\u6709\u4e86\u4e0b\u9762\u8fd9\u4e9b\u6587\u7ae0\u3002","title":"\u7a0b\u5e8f\u5458\u7684\u804c\u4e1a\u548c\u751f\u5b58\u6307\u5357 - \u8bfb\u7ea6\u7ff0\u00b7\u68ee\u6885\u5179\u76842\u672c\u4e66\u6709\u611f"},{"location":"Reading/Developers/#_1","text":"","title":"\u76ee\u5f55"},{"location":"Reading/Developers/#2","text":"\u7b2c\u4e00\u7bc7 \u5165\u884c\u6210\u4e3a\u8f6f\u4ef6\u5f00\u53d1\u8005 \u7b2c2\u7ae0 \u8dec\u6b65\u5343\u91cc\uff1a\u5982\u4f55\u5165\u884c \u7b2c3\u7ae0 \u508d\u8eab\u4e4b\u6280\uff1a\u4f60\u9700\u8981\u62e5\u6709\u7684\u6280\u672f\u6280\u80fd \u7b2c4\u7ae0 \u683c\u7269\u81f4\u77e5\uff1a\u5982\u4f55\u62d3\u5c55\u6280\u672f\u6280\u80fd \u7b2c5\u7ae0 \u65e0\u95ee\u897f\u4e1c\uff1a\u5230\u5e95\u5e94\u8be5\u5b66\u54ea\u95e8\u7f16\u7a0b\u8bed\u8a00 \u7b2c6\u7ae0 \u59d7\u59d7\u5b66\u6b65\uff1a\u5982\u4f55\u5b66\u597d\u4f60\u7684\u7b2c\u4e00\u95e8\u7f16\u7a0b\u8bed\u8a00 \u7b2c7\u7ae0 \u5dcd\u5dcd\u5b66\u5e9c\uff1a\u901a\u8fc7\u4e0a\u5927\u5b66\u6df1\u9020\u6210\u4e3a\u8f6f\u4ef6\u5f00\u53d1\u8005 \u7b2c8\u7ae0 \u8eac\u884c\u5b9e\u8df5\uff1a\u901a\u8fc7\u53c2\u52a0\u7f16\u7a0b\u8bad\u7ec3\u8425\u6210\u4e3a\u8f6f\u4ef6\u5f00\u53d1\u8005 \u7b2c9\u7ae0 \u81ea\u5b66\u6210\u624d\uff1a\u901a\u8fc7\u81ea\u5b66\u6210\u4e3a\u8f6f\u4ef6\u5f00\u53d1\u8005 \u7b2c\u4e8c\u7bc7 \u627e\u5230\u4e00\u4efd\u5de5\u4f5c \u7b2c10\u7ae0 \u521d\u51fa\u8305\u5e90\uff1a\u600e\u6837\u83b7\u5f97\u5b9e\u4e60\u673a\u4f1a \u7b2c11\u7ae0 \u67f3\u6697\u82b1\u660e\uff1a\u6ca1\u6709\u7ecf\u9a8c\u5982\u4f55\u627e\u5230\u5de5\u4f5c \u7b2c12\u7ae0 \u72ec\u8f9f\u8e4a\u5f84\uff1a\u627e\u5de5\u4f5c\u65f6\u7684\u521b\u65b0\u601d\u7ef4 \u7b2c13\u7ae0 \u79fb\u6a3d\u5c31\u6559\uff1a\u600e\u6837\u5199\u7b80\u5386 \u7b2c14\u7ae0 \u9526\u56ca\u5999\u8ba1\uff1a\u5982\u4f55\u5bf9\u4ed8\u9762\u8bd5 \u7b2c15\u7ae0 \u5507\u67aa\u820c\u5251\uff1a\u5173\u4e8e\u85aa\u916c\u8c08\u5224 \u7b2c16\u7ae0 \u5c71\u9ad8\u6c34\u957f\uff1a\u5982\u679c\u8981\u79bb\u804c\uff0c\u8be5\u600e\u4e48\u505a \u7b2c17\u7ae0 \u534a\u8def\u51fa\u5bb6\uff1a\u5982\u4f55\u4ece\u5176\u4ed6\u884c\u4e1a\u8f6c\u884c\u6210\u4e3a\u8f6f\u4ef6\u5f00\u53d1\u8005 \u7b2c18\u7ae0 \u9047\u6c34\u53e0\u6865\uff1a\u5982\u4f55\u4ece\u6d4b\u8bd5\u6216\u8005\u5176\u4ed6\u6280\u672f\u6027\u89d2\u8272\u8f6c\u578b\u6210\u4e3a\u8f6f\u4ef6\u5f00\u53d1\u8005 \u7b2c19\u7ae0 \u638e\u646d\u5229\u75c5\uff1a\u5408\u540c\u5236\u5458\u5de5\u4e0e\u9886\u85aa\u5236\u6b63\u5f0f\u96c7\u5458\u4e4b\u95f4\u7684\u6bd4\u8f83 \u7b2c20\u7ae0 \u53bb\u68af\u4e4b\u8a00\uff1a\u4ece\u672a\u516c\u5f00\u8fc7\u7684\u62db\u8058\u884c\u4e1a\u8fd0\u4f5c\u7684\u79d8\u5bc6 \u7b2c\u4e09\u7bc7 \u5173\u4e8e\u8f6f\u4ef6\u5f00\u53d1\u4f60\u9700\u8981\u77e5\u9053\u4e9b\u4ec0\u4e48 \u7b2c21\u7ae0 \u8d70\u9a6c\u89c2\u82b1\uff1a\u7f16\u7a0b\u8bed\u8a00\u6982\u8ff0 \u7b2c22\u7ae0 \u77e5\u96be\u800c\u8fdb\uff1a\u4ec0\u4e48\u662fWeb\u5f00\u53d1 \u7b2c23\u7ae0 \u524d\u9014\u5927\u597d\uff1a\u79fb\u52a8\u5f00\u53d1 \u7b2c24\u7ae0 \u5e55\u540e\u82f1\u96c4\uff1a\u540e\u7aef\u5f00\u53d1 \u7b2c25\u7ae0 \u6e38\u620f\u4eba\u751f\uff1a\u6e38\u620f\u5f00\u53d1\u8005\u7684\u804c\u4e1a\u751f\u6daf \u7b2c26\u7ae0 \u4e8b\u65e0\u5de8\u7ec6\uff1aDBA\u4e0eDevOps \u7b2c27\u7ae0 \u9ad8\u5c4b\u5efa\u74f4\uff1a\u8f6f\u4ef6\u5f00\u53d1\u65b9\u6cd5\u8bba \u7b2c28\u7ae0 \u5c42\u5c42\u8bbe\u9632\uff1a\u6d4b\u8bd5\u548cQA\u57fa\u7840 \u7b2c29\u7ae0 \u6e90\u5934\u628a\u5173\uff1a\u6d4b\u8bd5\u9a71\u52a8\u5f00\u53d1\u4e0e\u5355\u5143\u6d4b\u8bd5 \u7b2c30\u7ae0 \u6e05\u6e05\u723d\u723d\uff1a\u6e90\u4ee3\u7801\u63a7\u5236 \u7b2c31\u7ae0 \u6b65\u6b65\u4e3a\u8425\uff1a\u6301\u7eed\u96c6\u6210 \u7b2c32\u7ae0 \u706b\u773c\u91d1\u775b\uff1a\u8c03\u8bd5 \u7b2c33\u7ae0 \u65e5\u81fb\u5b8c\u5584\uff1a\u4ee3\u7801\u7ef4\u62a4 \u7b2c34\u7ae0 \u5b9e\u81f3\u540d\u5f52\uff1a\u5de5\u4f5c\u5c97\u4f4d\u4e0e\u5934\u8854 \u7b2c35\u7ae0 \u591a\u59ff\u591a\u5f69\uff1a\u8f6f\u4ef6\u5f00\u53d1\u8005\u7684\u5de5\u4f5c\u7c7b\u578b \u7b2c\u56db\u7bc7 \u8f6f\u4ef6\u5f00\u53d1\u8005\u7684\u65e5\u5e38\u5de5\u4f5c \u7b2c36\u7ae0 \u548c\u800c\u4e0d\u540c\uff1a\u4e0e\u540c\u4e8b\u76f8\u5904 \u7b2c37\u7ae0 \u987a\u52bf\u800c\u4e3a\uff1a\u4e0e\u8001\u677f\u76f8\u5904 \u7b2c38\u7ae0 \u534f\u529b\u5171\u8fdb\uff1a\u4e0e\u6d4b\u8bd5\u4eba\u5458\u76f8\u5904 \u7b2c39\u7ae0 \u7b49\u91cf\u9f50\u89c2\uff1a\u5de5\u4f5c\u4e0e\u751f\u6d3b\u7684\u5e73\u8861 \u7b2c40\u7ae0 \u5e76\u80a9\u4f5c\u6218\uff1a\u4e0e\u56e2\u961f\u534f\u4f5c \u7b2c41\u7ae0 \u8c20\u8a00\u5609\u8bba\uff1a\u63a8\u9500\u4f60\u7684\u60f3\u6cd5 \u7b2c42\u7ae0 \u8863\u51a0\u695a\u695a\uff1a\u5982\u4f55\u7740\u88c5 \u7b2c43\u7ae0 \u8c0b\u4e8b\u5728\u4eba\uff1a\u5b89\u7136\u6e21\u8fc7\u7ee9\u6548\u8bc4\u4f30 \u7b2c44\u7ae0 \u5149\u660e\u78ca\u843d\uff1a\u5904\u7406\u504f\u89c1 \u7b2c45\u7ae0 \u8eab\u5148\u58eb\u5352\uff1a\u5904\u4e8e\u9886\u5bfc\u7684\u4f4d\u7f6e \u7b2c46\u7ae0 \u524d\u7a0b\u4f3c\u9526\uff1a\u83b7\u5f97\u63d0\u62d4\u4e0e\u664b\u5347 \u7b2c47\u7ae0 \u5dfe\u5e3c\u82f1\u96c4\uff1a\u79d1\u6280\u5973\u6027 \u7b2c\u4e94\u7bc7 \u63a8\u8fdb\u4f60\u7684\u804c\u4e1a\u53d1\u5c55 \u7b2c48\u7ae0 \u540d\u6ee1\u5929\u4e0b\uff1a\u5efa\u7acb\u58f0\u8a89 \u7b2c49\u7ae0 \u5e7f\u7ed3\u5584\u7f18\uff1a\u793e\u4ea4\u4e0e\u4eba\u8109 \u7b2c50\u7ae0 \u4e0e\u65f6\u4ff1\u8fdb\uff1a\u8ba9\u4f60\u7684\u6280\u80fd\u7d27\u8ddf\u4e0a\u65f6\u4ee3 \u7b2c51\u7ae0 \u884c\u5bb6\u91cc\u624b\uff1a\u505a\u4e13\u624d\u8fd8\u662f\u505a\u901a\u624d \u7b2c52\u7ae0 \u4f20\u7ecf\u5e03\u9053\uff1a\u6f14\u8bb2\u548c\u53c2\u52a0\u4f1a\u8bae \u7b2c53\u7ae0 \u7b14\u8015\u4e0d\u8f8d\uff1a\u521b\u5efa\u535a\u5ba2 \u7b2c54\u7ae0 \u6d77\u9614\u5929\u7a7a\uff1a\u505a\u81ea\u7531\u804c\u4e1a\u8005\u4e43\u81f3\u521b\u4e1a \u7b2c55\u7ae0 \u7b56\u9a6c\u626c\u97ad\uff1a\u804c\u4e1a\u53d1\u5c55\u8def\u5f84 \u7b2c56\u7ae0 \u672a\u96e8\u7ef8\u7f2a\uff1a\u5de5\u4f5c\u7a33\u5b9a\u6027\u4e0e\u5de5\u4f5c\u4fdd\u969c \u7b2c57\u7ae0 \u5b66\u65e0\u6b62\u5883\uff1a\u57f9\u8bad\u4e0e\u8d44\u683c\u8ba4\u8bc1 \u7b2c58\u7ae0 \u4e50\u6b64\u4e0d\u75b2\uff1a\u517c\u804c\u9879\u76ee \u7b2c59\u7ae0 \u5f00\u5377\u6709\u76ca\uff1a\u8981\u8bfb\u7684\u597d\u4e66 \u7b2c60\u7ae0 \u4f59\u97f3\u8885\u8885\uff1a\u7ed3\u675f\u8bed","title":"\u300a\u8f6f\u6280\u80fd2\uff1a\u8f6f\u4ef6\u5f00\u53d1\u8005\u804c\u4e1a\u751f\u6daf\u6307\u5357\u300b"},{"location":"Reading/Developers/#2_1","text":"\u7b2c\u4e00\u7bc7\u3000\u804c\u4e1a \u7b2c2\u7ae0\u3000\u7ecf\u8425\u81ea\u5df1\u7684\u804c\u4e1a\u751f\u6daf\u5c31\u50cf\u7ecf\u8425\u4e00\u5bb6\u4f01\u4e1a \u7b2c3\u7ae0\u3000\u5982\u4f55\u7ed9\u81ea\u5df1\u8bbe\u5b9a\u597d\u804c\u4e1a\u76ee\u6807 \u7b2c4\u7ae0\u3000\u62d3\u5c55\u81ea\u5df1\u7684\u4eba\u9645\u4ea4\u5f80\u80fd\u529b \u7b2c5\u7ae0\u3000\u521b\u5efa\u4e00\u4efd\u5c61\u8bd5\u5c61\u9a8c\u7684\u7b80\u5386 \u7b2c6\u7ae0\u3000\u7834\u89e3\u9762\u8bd5\u4e4b\u9053 \u7b2c7\u7ae0\u3000\u8f6f\u4ef6\u5f00\u53d1\u4eba\u5458\u7684\u4e09\u6761\u804c\u4e1a\u8def\u5f84 \u7b2c8\u7ae0\u3000\u4e3a\u4ec0\u4e48\u4f60\u9700\u8981\u8d70\u4e13\u4e1a\u5316\u9053\u8def \u7b2c9\u7ae0\u3000\u516c\u53f8\u4e0e\u516c\u53f8\u662f\u4e0d\u4e00\u6837\u7684 \u7b2c10\u7ae0\u3000\u6500\u767b\u664b\u5347\u9636\u68af \u7b2c11\u7ae0\u3000\u6210\u4e3a\u4e13\u4e1a\u4eba\u58eb \u7b2c12\u7ae0\u3000\u4e0e\u8001\u677f\u548c\u540c\u4e8b\u7684\u76f8\u5904\u4e4b\u9053 \u7b2c13\u7ae0\u3000\u4e0d\u8981\u9677\u5165\u5bf9\u6280\u672f\u7684\u72c2\u70ed\u4e4b\u4e2d \u7b2c14\u7ae0\u3000\u5982\u4f55\u8f9e\u804c\u5e76\u5f00\u59cb\u4e3a\u81ea\u5df1\u5de5\u4f5c \u7b2c15\u7ae0\u3000\u5982\u4f55\u6210\u4e3a\u81ea\u7531\u804c\u4e1a\u8005 \u7b2c16\u7ae0\u3000\u5982\u4f55\u6210\u4e3a\u4e00\u540d\u4f01\u4e1a\u5bb6 \u7b2c17\u7ae0\u3000\u5982\u4f55\u5f00\u59cb\u521b\u4e1a \u7b2c18\u7ae0\u3000\u8fdc\u7a0b\u5de5\u4f5c \u7b2c\u4e8c\u7bc7\u3000\u81ea\u6211\u8425\u9500 \u7b2c19\u7ae0\u3000\u81ea\u6211\u8425\u9500\u57fa\u7840\u8bfe \u7b2c20\u7ae0\u3000\u5982\u4f55\u6253\u9020\u4e2a\u4eba\u54c1\u724c \u7b2c21\u7ae0\u3000\u5982\u4f55\u521b\u5efa\u5927\u83b7\u6210\u529f\u7684\u535a\u5ba2 \u7b2c22\u7ae0\u3000\u5728YouTube\u4e0a\u521b\u7acb\u81ea\u5df1\u7684\u4e13\u680f \u7b2c23\u7ae0\u3000\u4e3a\u4f55\u4e3a\u4ed6\u4eba\u589e\u52a0\u4ef7\u503c\u975e\u5e38\u91cd\u8981 \u7b2c24\u7ae0\u3000\u5584\u4e8e\u8fd0\u7528\u793e\u4ea4\u5a92\u4f53\u63d0\u5347\u81ea\u5df1\u7684\u54c1\u724c \u7b2c25\u7ae0\u3000\u6f14\u8bb2\u3001\u57f9\u8bad\u548c\u62a5\u544a \u7b2c26\u7ae0\u3000\u8457\u4e66\u7acb\u8bf4 \u7b2c\u4e09\u7bc7\u3000\u5b66\u4e60 \u7b2c27\u7ae0\u3000\u5b66\u4e60\u600e\u6837\u5b66\u4e60 \u7b2c28\u7ae0\u3000\u6211\u7684\u201c\u5341\u6b65\u5b66\u4e60\u6cd5\u201d \u7b2c29\u7ae0\u3000\u7b2c 1 \u6b65\u5230\u7b2c 6 \u6b65\uff1a\u8fd9\u4e9b\u6b65\u9aa4\u53ea\u505a\u4e00\u6b21 \u7b2c30\u7ae0\u3000\u7b2c7\u6b65\u5230\u7b2c10\u6b65\uff1a\u5faa\u73af\u5f80\u590d \u7b2c31\u7ae0\u3000\u5982\u4f55\u5bfb\u627e\u5bfc\u5e08 \u7b2c32\u7ae0\u3000\u5982\u4f55\u6210\u4e3a\u5bfc\u5e08 \u7b2c33\u7ae0\u3000\u4e3a\u4f55\u8bf4\u6559\u5b66\u76f8\u957f \u7b2c34\u7ae0\u3000\u4f60\u9700\u8981\u4e00\u4e2a\u5927\u5b66\u5b66\u4f4d\u5417 \u7b2c35\u7ae0\u3000\u53d1\u73b0\u81ea\u5df1\u7684\u77e5\u8bc6\u77ed\u677f \u7b2c\u56db\u7bc7\u3000\u751f\u4ea7\u529b \u7b2c36\u7ae0\u3000\u4e00\u5207\u59cb\u4e8e\u4e13\u6ce8 \u7b2c37\u7ae0\u3000\u6211\u7684\u79c1\u623f\u201c\u751f\u4ea7\u529b\u63d0\u5347\u8ba1\u5212\u201d \u7b2c38\u7ae0\u3000\u756a\u8304\u5de5\u4f5c\u6cd5 \u7b2c39\u7ae0\u3000\u6211\u7684\u201c\u5b9a\u989d\u5de5\u4f5c\u6cd5\u201d \u7b2c40\u7ae0\u3000\u5bf9\u81ea\u5df1\u8d1f\u8d23 \u7b2c41\u7ae0\u3000\u4e3a\u4ec0\u4e48\u8bf4\u591a\u4efb\u52a1\u5e76\u884c\u5f0a\u5927\u4e8e\u5229 \u7b2c42\u7ae0\u3000\u5982\u4f55\u5e94\u5bf9\u804c\u4e1a\u5026\u6020 \u7b2c43\u7ae0\u3000\u4f60\u662f\u600e\u6837\u6d6a\u8d39\u6389\u65f6\u95f4\u7684 \u7b2c44\u7ae0\u3000\u5f62\u6210\u60ef\u4f8b\u7684\u91cd\u8981\u6027 \u7b2c45\u7ae0\u3000\u5982\u4f55\u57f9\u517b\u597d\u4e60\u60ef \u7b2c46\u7ae0\u3000\u5206\u89e3\u4efb\u52a1\u4f1a\u63d0\u9ad8\u751f\u4ea7\u529b \u7b2c47\u7ae0\u3000\u52aa\u529b\u5de5\u4f5c\u7684\u4ef7\u503c\uff0c\u4ee5\u53ca\u4e3a\u4ec0\u4e48\u4f60\u603b\u662f\u9003\u907f\u52aa\u529b\u5de5\u4f5c \u7b2c48\u7ae0\u3000\u4efb\u4f55\u884c\u52a8\u90fd\u6bd4\u4e0d\u91c7\u53d6\u884c\u52a8\u597d \u7b2c\u4e94\u7bc7\u3000\u7406\u8d22 \u7b2c49\u7ae0\u3000\u5408\u7406\u652f\u914d\u4f60\u7684\u85aa\u6c34 \u7b2c50\u7ae0\u3000\u600e\u6837\u8fdb\u884c\u85aa\u916c\u8c08\u5224 \u7b2c51\u7ae0\u3000\u4e3a\u4f55\u8bf4\u623f\u5730\u4ea7\u662f\u6700\u597d\u7684\u6295\u8d44 \u7b2c52\u7ae0\u3000\u4f60\u771f\u7684\u4e86\u89e3\u81ea\u5df1\u7684\u9000\u4f11\u8ba1\u5212\u5417 \u7b2c53\u7ae0\u3000\u503a\u52a1\u7684\u5371\u5bb3 \u7b2c54\u7ae0\u3000\u5982\u4f55\u521b\u9020\u771f\u6b63\u7684\u8d22\u5bcc \u7b2c55\u7ae0\u3000\u6211\u662f\u5982\u4f55\u505a\u523033\u5c81\u9000\u4f11\u7684 \u7b2c\u516d\u7bc7\u3000\u5065\u8eab \u7b2c56\u7ae0\u3000\u5065\u8eab\u7684\u597d\u5904 \u7b2c57\u7ae0\u3000\u8bbe\u5b9a\u4f60\u7684\u5065\u8eab\u76ee\u6807 \u7b2c58\u7ae0\u3000\u5982\u4f55\u51cf\u80a5\uff08\u6216\u8005\u589e\u91cd\uff09 \u7b2c59\u7ae0\u3000\u5065\u8eab\u7684\u52a8\u529b\u4ece\u4f55\u800c\u6765 \u7b2c60\u7ae0\u3000\u589e\u808c \u7b2c61\u7ae0\u3000\u5982\u4f55\u83b7\u5f97\u5b8c\u7f8e\u8179\u808c \u7b2c62\u7ae0\u3000\u5f00\u59cb\u8dd1\u6b65 \u7b2c63\u7ae0\u3000\u6211\u7684\u51cf\u8102\u589e\u808c\u79d8\u8bc0 \u7b2c64\u7ae0\u3000\u7ad9\u7acb\u5f0f\u529e\u516c\u53ca\u5176\u4ed6\u7a8d\u95e8 \u7b2c65\u7ae0\u3000\u5229\u7528\u9ad8\u79d1\u6280\u88c5\u5907\u5065\u8eab \u7b2c\u4e03\u7bc7\u3000\u5fc3\u6001 \u7b2c66\u7ae0\u3000\u5fc3\u667a\u662f\u5982\u4f55\u5f71\u54cd\u8eab\u4f53\u7684 \u7b2c67\u7ae0\u3000\u4e00\u5207\u90fd\u6e90\u81ea\u79ef\u6781\u5fc3\u6001 \u7b2c68\u7ae0\u3000\u5982\u4f55\u6539\u53d8\u4f60\u7684\u81ea\u6211\u5f62\u8c61 \u7b2c69\u7ae0\u3000\u7231\u60c5\u4e0e\u604b\u7231 \u7b2c70\u7ae0\u3000\u6211\u7684\u79c1\u623f\u6210\u529f\u4e66\u5355 \u7b2c71\u7ae0\u3000\u4e0d\u8981\u5bb3\u6015\u5931\u8d25 \u7b2c72\u7ae0\u3000\u8d70\u51fa\u8212\u9002\u533a \u7b2c73\u7ae0\u3000\u65af\u591a\u845b\u54f2\u5b66\uff0c\u4ee5\u53ca\u5b83\u5982\u4f55\u6539\u53d8\u4f60\u7684\u751f\u6d3b \u7b2c74\u7ae0\u3000\u7ed3\u675f\u8bed","title":"\u300a\u8f6f\u6280\u80fd\uff1a\u4ee3\u7801\u4e4b\u5916\u7684\u751f\u5b58\u6307\u5357\uff08\u7b2c2\u7248\uff09\u300b"},{"location":"Reading/Developers/#_2","text":"\u6838\u5fc3\u601d\u60f3: \u6210\u4e3a\u4e00\u540d\u8f6f\u4ef6\u5f00\u53d1\u8005\u4e0d\u4ec5\u4ec5\u662f\u5b66\u4e60\u7f16\u7a0b\u8bed\u8a00\uff0c\u8fd8\u9700\u8981\u5177\u5907\u5404\u79cd\u8f6f\u6280\u80fd\uff0c\u4f8b\u5982\u6c9f\u901a\u80fd\u529b\u3001\u56e2\u961f\u5408\u4f5c\u80fd\u529b\u548c\u89e3\u51b3\u95ee\u9898\u7684\u80fd\u529b\u3002 \u672c\u7bc7\u4ecb\u7ecd\u4e86\u5982\u4f55\u6210\u4e3a\u4e00\u540d\u8f6f\u4ef6\u5f00\u53d1\u8005\u7684\u6b65\u9aa4\uff0c\u5305\u62ec\uff1a \u8bc4\u4f30\u4f60\u7684\u5174\u8da3\u548c\u80fd\u529b \u5b66\u4e60\u7f16\u7a0b\u8bed\u8a00 \u5efa\u7acb\u4f60\u7684\u4f5c\u54c1\u96c6 \u51c6\u5907\u7b80\u5386\u548c\u6c42\u804c\u4fe1 \u9762\u8bd5\u6280\u5de7 \u85aa\u916c\u8c08\u5224 \u4e3b\u8981\u5185\u5bb9: \u8bc4\u4f30\u4f60\u7684\u5174\u8da3\u548c\u80fd\u529b: \u8003\u8651\u4f60\u662f\u5426\u771f\u7684\u5bf9\u8f6f\u4ef6\u5f00\u53d1\u611f\u5174\u8da3\uff0c\u5e76\u8bc4\u4f30\u4f60\u7684\u5b66\u4e60\u80fd\u529b\u548c\u89e3\u51b3\u95ee\u9898\u7684\u80fd\u529b\u3002 \u5b66\u4e60\u7f16\u7a0b\u8bed\u8a00: \u9009\u62e9\u4e00\u79cd\u6216\u591a\u79cd\u7f16\u7a0b\u8bed\u8a00\u8fdb\u884c\u5b66\u4e60\uff0c\u5e76\u63a8\u8350\u4e00\u4e9b\u5b66\u4e60\u8d44\u6e90\u3002 \u5efa\u7acb\u4f60\u7684\u4f5c\u54c1\u96c6: \u5f00\u53d1\u4e00\u4e9b\u4e2a\u4eba\u9879\u76ee\u6216\u53c2\u4e0e\u5f00\u6e90\u9879\u76ee\uff0c\u4ee5\u5c55\u793a\u4f60\u7684\u6280\u80fd\u548c\u7ecf\u9a8c\u3002 \u51c6\u5907\u7b80\u5386\u548c\u6c42\u804c\u4fe1: \u7a81\u51fa\u4f60\u7684\u6280\u80fd\u548c\u7ecf\u9a8c\uff0c\u5e76\u9488\u5bf9\u4e0d\u540c\u7684\u804c\u4f4d\u8fdb\u884c\u8c03\u6574\u3002 \u9762\u8bd5\u6280\u5de7: \u4e86\u89e3\u9762\u8bd5\u7684\u5e38\u89c1\u95ee\u9898\uff0c\u5e76\u7ec3\u4e60\u4f60\u7684\u56de\u7b54\u3002 \u85aa\u916c\u8c08\u5224: \u4e86\u89e3\u4f60\u7684\u85aa\u916c\u8303\u56f4\uff0c\u5e76\u5b66\u4f1a\u5982\u4f55\u8c08\u5224\u3002 \u5173\u952e\u6b65\u9aa4: \u81ea\u6211\u8bc4\u4f30: \u8bc4\u4f30\u4f60\u7684\u5174\u8da3\u3001\u80fd\u529b\u548c\u76ee\u6807\u3002 \u5b66\u4e60\u8ba1\u5212: \u5236\u5b9a\u5b66\u4e60\u7f16\u7a0b\u8bed\u8a00\u7684\u8ba1\u5212\uff0c\u5e76\u9009\u62e9\u5408\u9002\u7684\u5b66\u4e60\u8d44\u6e90\u3002 \u5b9e\u8df5\u7ec3\u4e60: \u901a\u8fc7\u5f00\u53d1\u4e2a\u4eba\u9879\u76ee\u6216\u53c2\u4e0e\u5f00\u6e90\u9879\u76ee\u6765\u7ec3\u4e60\u4f60\u7684\u6280\u80fd\u3002 \u6c42\u804c\u51c6\u5907: \u51c6\u5907\u7b80\u5386\u3001\u6c42\u804c\u4fe1\u548c\u9762\u8bd5\u6280\u5de7\u3002 \u6301\u7eed\u5b66\u4e60: \u4e0d\u65ad\u5b66\u4e60\u65b0\u7684\u6280\u80fd\u548c\u77e5\u8bc6\uff0c\u4fdd\u6301\u7ade\u4e89\u529b\u3002 \u603b\u7ed3: \u6210\u4e3a\u4e00\u540d\u8f6f\u4ef6\u5f00\u53d1\u8005\u9700\u8981\u4ed8\u51fa\u52aa\u529b\u548c\u65f6\u95f4\u3002\u901a\u8fc7\u638c\u63e1\u5fc5\u8981\u7684\u6280\u80fd\u548c\u77e5\u8bc6\uff0c\u5e76\u505a\u597d\u6c42\u804c\u51c6\u5907\uff0c\u4f60\u5c31\u53ef\u4ee5\u5b9e\u73b0\u4f60\u7684\u76ee\u6807\u3002 \u4ee5\u4e0b\u662f\u4e00\u4e9b\u5177\u4f53\u7684\u5efa\u8bae: \u5c3d\u65e9\u5f00\u59cb\u5b66\u4e60\u7f16\u7a0b\u3002 \u8d8a\u65e9\u5f00\u59cb\u5b66\u4e60\uff0c\u4f60\u5c31\u6709\u8d8a\u591a\u7684\u65f6\u95f4\u6765\u7ec3\u4e60\u548c\u63d0\u9ad8\u4f60\u7684\u6280\u80fd\u3002 \u79ef\u6781\u53c2\u4e0e\u5f00\u6e90\u9879\u76ee\u3002 \u8fd9\u662f\u4e00\u4e2a\u5f88\u597d\u7684\u5b66\u4e60\u673a\u4f1a\uff0c\u53ef\u4ee5\u8ba9\u4f60\u4e0e\u5176\u4ed6\u5f00\u53d1\u4eba\u5458\u5408\u4f5c\uff0c\u5e76\u5c55\u793a\u4f60\u7684\u6280\u80fd\u3002 \u53c2\u52a0\u884c\u4e1a\u6d3b\u52a8\u3002 \u8fd9\u662f\u4e00\u4e2a\u5f88\u597d\u7684\u7ed3\u8bc6\u5176\u4ed6\u5f00\u53d1\u4eba\u5458\u548c\u4e86\u89e3\u884c\u4e1a\u8d8b\u52bf\u7684\u673a\u4f1a\u3002 \u5efa\u7acb\u81ea\u5df1\u7684\u4e2a\u4eba\u54c1\u724c\u3002 \u521b\u5efa\u4e00\u4e2a\u4e2a\u4eba\u7f51\u7ad9\u6216\u535a\u5ba2\uff0c\u5c55\u793a\u4f60\u7684\u4f5c\u54c1\u548c\u6280\u80fd\u3002 \u4fdd\u6301\u79ef\u6781\u4e3b\u52a8\u3002 \u4e0d\u8981\u7b49\u5f85\u673a\u4f1a\u6765\u627e\u4f60\uff0c\u8981\u4e3b\u52a8\u5bfb\u627e\u673a\u4f1a\u3002 \u4ee5\u4e0b\u662f\u4e00\u4e9b\u989d\u5916\u7684\u8865\u5145: \u4e66\u4e2d\u8fd8\u63d0\u5230\u4e86 \u804c\u4e1a\u89c4\u5212 \u7684\u91cd\u8981\u6027\u3002\u8bbe\u5b9a\u4f60\u7684\u804c\u4e1a\u76ee\u6807\uff0c\u5e76\u5236\u5b9a\u5b9e\u73b0\u76ee\u6807\u7684\u8ba1\u5212\u3002 \u4e66\u4e2d\u4e5f\u5f3a\u8c03\u4e86 \u4eba\u8109 \u7684\u91cd\u8981\u6027\u3002\u5efa\u7acb\u4e0e\u5176\u4ed6\u5f00\u53d1\u4eba\u5458\u548c\u884c\u4e1a\u4e13\u5bb6\u7684\u8054\u7cfb\uff0c\u53ef\u4ee5\u5e2e\u52a9\u4f60\u83b7\u5f97\u5b9d\u8d35\u7684\u7ecf\u9a8c\u548c\u5efa\u8bae\u3002","title":"\u4e00\u3001\u5165\u884c"},{"location":"Reading/Developers/#_3","text":"\u6838\u5fc3\u601d\u60f3: \u627e\u5230\u4e00\u4efd\u8f6f\u4ef6\u5f00\u53d1\u5de5\u4f5c\u4e0d\u4ec5\u4ec5\u662f\u6295\u9012\u7b80\u5386\u548c\u53c2\u52a0\u9762\u8bd5\uff0c\u8fd8\u9700\u8981\u505a\u597d\u5145\u5206\u7684\u51c6\u5907\uff0c\u5e76\u4e86\u89e3\u6c42\u804c\u8fc7\u7a0b\u4e2d\u7684\u6ce8\u610f\u4e8b\u9879\u3002 \u672c\u7bc7\u4ecb\u7ecd\u4e86\u5982\u4f55\u627e\u5230\u4e00\u4efd\u8f6f\u4ef6\u5f00\u53d1\u5de5\u4f5c\u7684\u6b65\u9aa4\uff0c\u5305\u62ec\uff1a \u786e\u5b9a\u4f60\u7684\u6c42\u804c\u76ee\u6807 \u51c6\u5907\u7b80\u5386\u548c\u6c42\u804c\u4fe1 \u5b66\u4e60\u9762\u8bd5\u6280\u5de7 \u4e86\u89e3\u85aa\u916c\u8c08\u5224 \u62d3\u5c55\u4eba\u8109 \u5173\u6ce8\u884c\u4e1a\u8d8b\u52bf \u4e3b\u8981\u5185\u5bb9: \u786e\u5b9a\u4f60\u7684\u6c42\u804c\u76ee\u6807: \u660e\u786e\u4f60\u60f3\u8981\u4ec0\u4e48\u6837\u7684\u5de5\u4f5c\uff0c\u5e76\u4e86\u89e3\u4f60\u6240\u5728\u5730\u533a\u7684\u5c31\u4e1a\u5e02\u573a\u3002 \u51c6\u5907\u7b80\u5386\u548c\u6c42\u804c\u4fe1: \u7a81\u51fa\u4f60\u7684\u6280\u80fd\u548c\u7ecf\u9a8c\uff0c\u5e76\u9488\u5bf9\u4e0d\u540c\u7684\u804c\u4f4d\u8fdb\u884c\u8c03\u6574\u3002 \u5b66\u4e60\u9762\u8bd5\u6280\u5de7: \u4e86\u89e3\u9762\u8bd5\u7684\u5e38\u89c1\u95ee\u9898\uff0c\u5e76\u7ec3\u4e60\u4f60\u7684\u56de\u7b54\u3002 \u4e86\u89e3\u85aa\u916c\u8c08\u5224: \u4e86\u89e3\u4f60\u7684\u85aa\u916c\u8303\u56f4\uff0c\u5e76\u5b66\u4f1a\u5982\u4f55\u8c08\u5224\u3002 \u62d3\u5c55\u4eba\u8109: \u53c2\u52a0\u884c\u4e1a\u6d3b\u52a8\u548c\u5efa\u7acb\u4e0e\u5176\u4ed6\u5f00\u53d1\u4eba\u5458\u7684\u8054\u7cfb\uff0c\u53ef\u4ee5\u5e2e\u52a9\u4f60\u83b7\u5f97\u66f4\u591a\u673a\u4f1a\u3002 \u5173\u6ce8\u884c\u4e1a\u8d8b\u52bf: \u4e86\u89e3\u6700\u65b0\u7684\u6280\u672f\u548c\u8d8b\u52bf\uff0c\u53ef\u4ee5\u5e2e\u52a9\u4f60\u4fdd\u6301\u7ade\u4e89\u529b\u3002 \u5173\u952e\u6b65\u9aa4: \u81ea\u6211\u8bc4\u4f30: \u8bc4\u4f30\u4f60\u7684\u6280\u80fd\u3001\u7ecf\u9a8c\u548c\u76ee\u6807\u3002 \u6c42\u804c\u76ee\u6807: \u660e\u786e\u4f60\u60f3\u8981\u4ec0\u4e48\u6837\u7684\u5de5\u4f5c\uff0c\u5e76\u5236\u5b9a\u6c42\u804c\u8ba1\u5212\u3002 \u51c6\u5907\u6750\u6599: \u51c6\u5907\u7b80\u5386\u3001\u6c42\u804c\u4fe1\u548c\u4f5c\u54c1\u96c6\u3002 \u9762\u8bd5\u51c6\u5907: \u7ec3\u4e60\u9762\u8bd5\u6280\u5de7\uff0c\u5e76\u4e86\u89e3\u5e38\u89c1\u95ee\u9898\u3002 \u6301\u7eed\u5b66\u4e60: \u4e0d\u65ad\u5b66\u4e60\u65b0\u7684\u6280\u80fd\u548c\u77e5\u8bc6\uff0c\u4fdd\u6301\u7ade\u4e89\u529b\u3002 \u603b\u7ed3: \u627e\u5230\u4e00\u4efd\u8f6f\u4ef6\u5f00\u53d1\u5de5\u4f5c\u9700\u8981\u4ed8\u51fa\u52aa\u529b\u548c\u65f6\u95f4\u3002\u901a\u8fc7\u505a\u597d\u5145\u5206\u7684\u51c6\u5907\uff0c\u5e76\u4e86\u89e3\u6c42\u804c\u8fc7\u7a0b\u4e2d\u7684\u6ce8\u610f\u4e8b\u9879\uff0c\u4f60\u5c31\u53ef\u4ee5\u63d0\u9ad8\u627e\u5230\u7406\u60f3\u5de5\u4f5c\u7684\u6210\u529f\u7387\u3002 \u4ee5\u4e0b\u662f\u4e00\u4e9b\u5177\u4f53\u7684\u5efa\u8bae: \u5c3d\u65e9\u5f00\u59cb\u6c42\u804c\u3002 \u4e0d\u8981\u7b49\u5230\u4f60\u6bd5\u4e1a\u6216\u5b8c\u6210\u6240\u6709\u5b66\u4e60\u624d\u5f00\u59cb\u6c42\u804c\u3002 \u5145\u5206\u5229\u7528\u4f60\u7684\u8d44\u6e90\u3002 \u4f60\u7684\u5b66\u6821\u3001\u670b\u53cb\u3001\u5bb6\u4eba\u548c\u804c\u4e1a\u987e\u95ee\u90fd\u53ef\u4ee5\u63d0\u4f9b\u5e2e\u52a9\u3002 \u4fdd\u6301\u79ef\u6781\u4e3b\u52a8\u3002 \u4e0d\u8981\u7b49\u5f85\u673a\u4f1a\u6765\u627e\u4f60\uff0c\u8981\u4e3b\u52a8\u5bfb\u627e\u673a\u4f1a\u3002 \u5b66\u4f1a\u63a8\u9500\u81ea\u5df1\u3002 \u5728\u9762\u8bd5\u4e2d\u8981\u81ea\u4fe1\u5730\u5c55\u793a\u4f60\u7684\u6280\u80fd\u548c\u7ecf\u9a8c\u3002 \u4e0d\u8981\u653e\u5f03\u3002 \u6c42\u804c\u8fc7\u7a0b\u53ef\u80fd\u4f1a\u5f88\u6f2b\u957f\uff0c\u4f46\u4e0d\u8981\u653e\u5f03\uff0c\u6700\u7ec8\u4f60\u4f1a\u627e\u5230\u4e00\u4efd\u9002\u5408\u4f60\u7684\u5de5\u4f5c\u3002 \u4ee5\u4e0b\u662f\u4e00\u4e9b\u989d\u5916\u7684\u8865\u5145: \u4e66\u4e2d\u8fd8\u63d0\u5230\u4e86 \u5b9e\u4e60 \u7684\u91cd\u8981\u6027\u3002\u5b9e\u4e60\u662f\u4e00\u4e2a\u5f88\u597d\u7684\u83b7\u5f97\u5de5\u4f5c\u7ecf\u9a8c\u548c\u5efa\u7acb\u4eba\u8109\u7684\u673a\u4f1a\u3002 \u4e66\u4e2d\u4e5f\u5f3a\u8c03\u4e86 \u8f6f\u6280\u80fd \u7684\u91cd\u8981\u6027\u3002\u826f\u597d\u7684\u6c9f\u901a\u80fd\u529b\u3001\u56e2\u961f\u5408\u4f5c\u80fd\u529b\u548c\u89e3\u51b3\u95ee\u9898\u7684\u80fd\u529b\u53ef\u4ee5\u5e2e\u52a9\u4f60\u5728\u6c42\u804c\u4e2d\u8131\u9896\u800c\u51fa\u3002","title":"\u4e8c\u3001\u627e\u5de5\u4f5c"},{"location":"Reading/Developers/#_4","text":"\u6838\u5fc3\u601d\u60f3: \u8f6f\u4ef6\u5f00\u53d1\u4e0d\u4ec5\u4ec5\u662f\u5199\u4ee3\u7801\uff0c\u8fd8\u6d89\u53ca\u8bb8\u591a\u5176\u4ed6\u65b9\u9762\uff0c\u4f8b\u5982\u8f6f\u4ef6\u8bbe\u8ba1\u3001\u6d4b\u8bd5\u3001\u90e8\u7f72\u548c\u7ef4\u62a4\u3002 \u672c\u7bc7\u4ecb\u7ecd\u4e86\u8f6f\u4ef6\u5f00\u53d1\u8fc7\u7a0b\u4e2d\u7684\u4e00\u4e9b\u91cd\u8981\u6982\u5ff5\u548c\u5b9e\u8df5\uff0c\u5305\u62ec\uff1a \u8f6f\u4ef6\u8bbe\u8ba1\u539f\u5219 \u6d4b\u8bd5\u65b9\u6cd5 \u7248\u672c\u63a7\u5236 \u6301\u7eed\u96c6\u6210\u548c\u6301\u7eed\u90e8\u7f72 \u5b89\u5168\u7f16\u7801 \u8f6f\u4ef6\u6587\u6863 \u56e2\u961f\u5408\u4f5c \u4e3b\u8981\u5185\u5bb9: \u8f6f\u4ef6\u8bbe\u8ba1\u539f\u5219: \u4ecb\u7ecd\u4e86\u4e00\u4e9b\u91cd\u8981\u7684\u8f6f\u4ef6\u8bbe\u8ba1\u539f\u5219\uff0c\u4f8b\u5982 SOLID \u539f\u5219\u548c\u53ef\u91cd\u7528\u6027\u3002 \u6d4b\u8bd5\u65b9\u6cd5: \u4ecb\u7ecd\u4e86\u4e00\u4e9b\u5e38\u89c1\u7684\u6d4b\u8bd5\u65b9\u6cd5\uff0c\u4f8b\u5982\u5355\u5143\u6d4b\u8bd5\u3001\u96c6\u6210\u6d4b\u8bd5\u548c\u7cfb\u7edf\u6d4b\u8bd5\u3002 \u7248\u672c\u63a7\u5236: \u4ecb\u7ecd\u4e86\u7248\u672c\u63a7\u5236\u7684\u57fa\u672c\u6982\u5ff5\u548c\u5de5\u5177\uff0c\u4f8b\u5982 Git \u548c Mercurial\u3002 \u6301\u7eed\u96c6\u6210\u548c\u6301\u7eed\u90e8\u7f72: \u4ecb\u7ecd\u4e86\u6301\u7eed\u96c6\u6210\u548c\u6301\u7eed\u90e8\u7f72\u7684\u6982\u5ff5\u548c\u5b9e\u8df5\u3002 \u5b89\u5168\u7f16\u7801: \u4ecb\u7ecd\u4e86\u4e00\u4e9b\u5e38\u89c1\u7684\u5b89\u5168\u7f16\u7801\u5b9e\u8df5\uff0c\u4f8b\u5982\u8f93\u5165\u9a8c\u8bc1\u548c\u9519\u8bef\u5904\u7406\u3002 \u8f6f\u4ef6\u6587\u6863: \u4ecb\u7ecd\u4e86\u8f6f\u4ef6\u6587\u6863\u7684\u91cd\u8981\u6027\u4ee5\u53ca\u5982\u4f55\u7f16\u5199\u6587\u6863\u3002 \u56e2\u961f\u5408\u4f5c: \u4ecb\u7ecd\u4e86\u56e2\u961f\u5408\u4f5c\u5728\u8f6f\u4ef6\u5f00\u53d1\u4e2d\u7684\u91cd\u8981\u6027\u4ee5\u53ca\u5982\u4f55\u6709\u6548\u5730\u8fdb\u884c\u56e2\u961f\u5408\u4f5c\u3002 \u5173\u952e\u6b65\u9aa4: \u5b66\u4e60\u8f6f\u4ef6\u8bbe\u8ba1\u539f\u5219\u3002 \u597d\u7684\u8bbe\u8ba1\u53ef\u4ee5\u4f7f\u8f6f\u4ef6\u66f4\u52a0\u6613\u4e8e\u7406\u89e3\u3001\u7ef4\u62a4\u548c\u6269\u5c55\u3002 \u638c\u63e1\u6d4b\u8bd5\u65b9\u6cd5\u3002 \u6d4b\u8bd5\u53ef\u4ee5\u786e\u4fdd\u8f6f\u4ef6\u7684\u8d28\u91cf\u548c\u53ef\u9760\u6027\u3002 \u4f7f\u7528\u7248\u672c\u63a7\u5236\u5de5\u5177\u3002 \u7248\u672c\u63a7\u5236\u53ef\u4ee5\u5e2e\u52a9\u4f60\u8ddf\u8e2a\u4ee3\u7801\u7684\u66f4\u6539\u5e76\u56de\u6eda\u5230\u4e4b\u524d\u7684\u7248\u672c\u3002 \u4e86\u89e3\u6301\u7eed\u96c6\u6210\u548c\u6301\u7eed\u90e8\u7f72\u3002 \u6301\u7eed\u96c6\u6210\u548c\u6301\u7eed\u90e8\u7f72\u53ef\u4ee5\u5e2e\u52a9\u4f60\u66f4\u5feb\u5730\u53d1\u5e03\u8f6f\u4ef6\u5e76\u63d0\u9ad8\u8d28\u91cf\u3002 \u9075\u5faa\u5b89\u5168\u7f16\u7801\u5b9e\u8df5\u3002 \u5b89\u5168\u7f16\u7801\u53ef\u4ee5\u5e2e\u52a9\u4f60\u9632\u6b62\u8f6f\u4ef6\u6f0f\u6d1e\u3002 \u7f16\u5199\u6e05\u6670\u7684\u6587\u6863\u3002 \u6587\u6863\u53ef\u4ee5\u5e2e\u52a9\u5176\u4ed6\u4eba\u7406\u89e3\u548c\u4f7f\u7528\u4f60\u7684\u8f6f\u4ef6\u3002 \u5b66\u4f1a\u4e0e\u4ed6\u4eba\u5408\u4f5c\u3002 \u56e2\u961f\u5408\u4f5c\u53ef\u4ee5\u5e2e\u52a9\u4f60\u5b8c\u6210\u66f4\u5927\u7684\u9879\u76ee\u3002 \u603b\u7ed3: \u8f6f\u4ef6\u5f00\u53d1\u662f\u4e00\u9879\u590d\u6742\u7684\u5de5\u7a0b\uff0c\u9700\u8981\u638c\u63e1\u5404\u79cd\u77e5\u8bc6\u548c\u6280\u80fd\u3002\u901a\u8fc7\u5b66\u4e60\u548c\u5b9e\u8df5\uff0c\u4f60. \u4ee5\u4e0b\u662f\u4e00\u4e9b\u5177\u4f53\u7684\u5efa\u8bae: \u9605\u8bfb\u6709\u5173\u8f6f\u4ef6\u5f00\u53d1\u7684\u4e66\u7c4d\u548c\u6587\u7ae0\u3002 \u8bb8\u591a\u4f18\u79c0\u7684\u8d44\u6e90\u53ef\u4ee5\u5e2e\u52a9\u4f60\u5b66\u4e60\u8f6f\u4ef6\u5f00\u53d1\u7684\u5404\u4e2a\u65b9\u9762\u3002 \u53c2\u52a0\u8f6f\u4ef6\u5f00\u53d1\u57f9\u8bad\u8bfe\u7a0b\u3002 \u57f9\u8bad\u8bfe\u7a0b\u53ef\u4ee5\u5e2e\u52a9\u4f60\u5feb\u901f\u638c\u63e1\u8f6f\u4ef6\u5f00\u53d1\u7684\u6700\u65b0\u6280\u672f\u548c\u5b9e\u8df5\u3002 \u53c2\u4e0e\u5f00\u6e90\u9879\u76ee\u3002 \u8fd9\u662f\u4e00\u4e2a\u5f88\u597d\u7684\u5b66\u4e60\u673a\u4f1a\uff0c\u53ef\u4ee5\u8ba9\u4f60\u4e0e\u5176\u4ed6\u5f00\u53d1\u4eba\u5458\u5408\u4f5c\u5e76\u83b7\u5f97\u7ecf\u9a8c\u3002 \u5728\u4e2a\u4eba\u9879\u76ee\u4e2d\u7ec3\u4e60\u4f60\u7684\u6280\u80fd\u3002 \u5f00\u53d1\u4e2a\u4eba\u9879\u76ee\u53ef\u4ee5\u5e2e\u52a9\u4f60\u5de9\u56fa\u4f60\u6240\u5b66\u7684\u77e5\u8bc6\u5e76\u63d0\u9ad8\u4f60\u7684\u6280\u80fd\u3002 \u4e0e\u5176\u4ed6\u5f00\u53d1\u4eba\u5458\u4ea4\u6d41\u3002 \u4e0e\u5176\u4ed6\u5f00\u53d1\u4eba\u5458\u4ea4\u6d41\u53ef\u4ee5\u5e2e\u52a9\u4f60\u5b66\u4e60\u65b0\u77e5\u8bc6\u5e76\u83b7\u5f97\u65b0\u7684\u89c1\u89e3\u3002 \u4ee5\u4e0b\u662f\u4e00\u4e9b\u989d\u5916\u7684\u8865\u5145: \u4e66\u4e2d\u8fd8\u63d0\u5230\u4e86 \u4e13\u4e1a\u53d1\u5c55 \u7684\u91cd\u8981\u6027\u3002\u4e0d\u65ad\u5b66\u4e60\u65b0\u7684\u6280\u80fd\u548c\u77e5\u8bc6\uff0c\u5e76\u83b7\u5f97\u76f8\u5173\u7684\u8ba4\u8bc1\uff0c\u53ef\u4ee5\u5e2e\u52a9\u4f60\u63d0\u5347\u4f60\u7684\u804c\u4e1a\u7ade\u4e89\u529b\u3002 \u4e66\u4e2d\u4e5f\u5f3a\u8c03\u4e86 \u7ec8\u8eab\u5b66\u4e60 \u7684\u91cd\u8981\u6027\u3002\u8f6f\u4ef6\u5f00\u53d1\u662f\u4e00\u4e2a\u5feb\u901f\u53d1\u5c55\u7684\u884c\u4e1a\uff0c\u4f60\u9700\u8981\u4e0d\u65ad\u5b66\u4e60\u624d\u80fd\u8ddf\u4e0a\u6700\u65b0\u7684\u8d8b\u52bf\u3002","title":"\u4e09\u3001\u5173\u4e8e\u8f6f\u4ef6\u5f00\u53d1"},{"location":"Reading/Developers/#_5","text":"\u6838\u5fc3\u601d\u60f3: \u8f6f\u4ef6\u5f00\u53d1\u8005\u7684\u65e5\u5e38\u5de5\u4f5c\u4e0d\u4ec5\u4ec5\u662f\u5199\u4ee3\u7801\uff0c\u8fd8\u5305\u62ec\u8bb8\u591a\u5176\u4ed6\u4efb\u52a1\uff0c\u4f8b\u5982\u6c9f\u901a\u3001\u534f\u4f5c\u3001\u89e3\u51b3\u95ee\u9898\u548c\u5b66\u4e60\u3002 \u672c\u7bc7\u4ecb\u7ecd\u4e86\u8f6f\u4ef6\u5f00\u53d1\u8005\u7684\u65e5\u5e38\u5de5\u4f5c\u5185\u5bb9\u548c\u804c\u8d23\uff0c\u4ee5\u53ca\u5982\u4f55\u6709\u6548\u5730\u5b8c\u6210\u8fd9\u4e9b\u5de5\u4f5c\u3002 \u4e3b\u8981\u5185\u5bb9: \u6c9f\u901a: \u8f6f\u4ef6\u5f00\u53d1\u8005\u9700\u8981\u4e0e\u56e2\u961f\u6210\u5458\u3001\u5ba2\u6237\u548c\u5176\u4ed6\u5229\u76ca\u76f8\u5173\u8005\u8fdb\u884c\u6709\u6548\u6c9f\u901a\u3002 \u534f\u4f5c: \u8f6f\u4ef6\u5f00\u53d1\u901a\u5e38\u662f\u56e2\u961f\u5408\u4f5c\u7684\u8fc7\u7a0b\uff0c\u9700\u8981\u4e0e\u4ed6\u4eba\u534f\u4f5c\u624d\u80fd\u5b8c\u6210\u4efb\u52a1\u3002 \u89e3\u51b3\u95ee\u9898: \u8f6f\u4ef6\u5f00\u53d1\u8fc7\u7a0b\u4e2d\u4f1a\u9047\u5230\u5404\u79cd\u95ee\u9898\uff0c\u9700\u8981\u80fd\u591f\u72ec\u7acb\u601d\u8003\u5e76\u89e3\u51b3\u95ee\u9898\u3002 \u5b66\u4e60: \u8f6f\u4ef6\u5f00\u53d1\u662f\u4e00\u4e2a\u5feb\u901f\u53d1\u5c55\u7684\u884c\u4e1a\uff0c\u9700\u8981\u4e0d\u65ad\u5b66\u4e60\u624d\u80fd\u8ddf\u4e0a\u6700\u65b0\u7684\u6280\u672f\u548c\u8d8b\u52bf\u3002 \u5173\u952e\u6b65\u9aa4: \u63d0\u9ad8\u6c9f\u901a\u80fd\u529b\u3002 \u6e05\u6670\u3001\u7b80\u6d01\u5730\u8868\u8fbe\u4f60\u7684\u60f3\u6cd5\uff0c\u5e76\u5b66\u4f1a\u503e\u542c\u4ed6\u4eba\u7684\u610f\u89c1\u3002 \u5b66\u4f1a\u56e2\u961f\u5408\u4f5c\u3002 \u4e0e\u4ed6\u4eba\u5408\u4f5c\u5b8c\u6210\u4efb\u52a1\uff0c\u5e76\u5206\u4eab\u4f60\u7684\u77e5\u8bc6\u548c\u7ecf\u9a8c\u3002 \u57f9\u517b\u89e3\u51b3\u95ee\u9898\u7684\u80fd\u529b\u3002 \u5206\u6790\u95ee\u9898\uff0c\u5e76\u63d0\u51fa\u6709\u6548\u7684\u89e3\u51b3\u65b9\u6848\u3002 \u4fdd\u6301\u7ec8\u8eab\u5b66\u4e60\u7684\u6001\u5ea6\u3002 \u4e0d\u65ad\u5b66\u4e60\u65b0\u7684\u6280\u80fd\u548c\u77e5\u8bc6\uff0c\u5e76\u4fdd\u6301\u5bf9\u65b0\u6280\u672f\u7684\u5173\u6ce8\u3002 \u603b\u7ed3: \u8f6f\u4ef6\u5f00\u53d1\u662f\u4e00\u9879\u5145\u6ee1\u6311\u6218\u4f46\u4e5f\u5f88\u6709\u610f\u4e49\u7684\u5de5\u4f5c\u3002\u901a\u8fc7\u638c\u63e1\u5fc5\u8981\u7684\u6280\u80fd\u548c\u77e5\u8bc6\uff0c\u5e76\u517b\u6210\u826f\u597d\u7684\u5de5\u4f5c\u4e60\u60ef\uff0c\u4f60\u5c31\u53ef\u4ee5\u6210\u4e3a\u4e00\u540d\u4f18\u79c0\u7684\u8f6f\u4ef6\u5f00\u53d1\u8005\u3002 \u4ee5\u4e0b\u662f\u4e00\u4e9b\u5177\u4f53\u7684\u5efa\u8bae: \u79ef\u6781\u53c2\u4e0e\u56e2\u961f\u8ba8\u8bba\u3002 \u63d0\u51fa\u4f60\u7684\u60f3\u6cd5\uff0c\u5e76\u4e0e\u4ed6\u4eba\u5206\u4eab\u4f60\u7684\u77e5\u8bc6\u548c\u7ecf\u9a8c\u3002 \u5584\u4e8e\u5229\u7528\u6c9f\u901a\u5de5\u5177\u3002 \u4f7f\u7528\u7535\u5b50\u90ae\u4ef6\u3001\u804a\u5929\u5de5\u5177\u548c\u5176\u4ed6\u5de5\u5177\u4e0e\u4ed6\u4eba\u4fdd\u6301\u6c9f\u901a\u3002 \u5b66\u4f1a\u7ba1\u7406\u65f6\u95f4\u3002 \u5236\u5b9a\u5de5\u4f5c\u8ba1\u5212\uff0c\u5e76\u6709\u6548\u5730\u5229\u7528\u4f60\u7684\u65f6\u95f4\u3002 \u4fdd\u6301\u826f\u597d\u7684\u5de5\u4f5c\u4e60\u60ef\u3002 \u5b9a\u671f\u6574\u7406\u4f60\u7684\u4ee3\u7801\uff0c\u5e76\u505a\u597d\u6ce8\u91ca\u3002 \u79ef\u6781\u53c2\u52a0\u884c\u4e1a\u6d3b\u52a8\u3002 \u8fd9\u662f\u4e00\u4e2a\u5f88\u597d\u7684\u5b66\u4e60\u673a\u4f1a\uff0c\u53ef\u4ee5\u8ba9\u4f60\u4e0e\u5176\u4ed6\u5f00\u53d1\u4eba\u5458\u4ea4\u6d41\u5e76\u4e86\u89e3\u6700\u65b0\u7684\u6280\u672f\u548c\u8d8b\u52bf\u3002 \u719f\u6089\u8f6f\u4ef6\u5f00\u53d1\u6d41\u7a0b\u3002 \u4e86\u89e3\u6bcf\u4e2a\u9636\u6bb5\u7684\u4efb\u52a1\u548c\u804c\u8d23\uff0c\u5e76\u80fd\u591f\u6709\u6548\u5730\u5b8c\u6210\u8fd9\u4e9b\u5de5\u4f5c\u3002 \u638c\u63e1\u5fc5\u8981\u7684\u5de5\u5177\u548c\u6280\u672f\u3002 \u4f7f\u7528\u5408\u9002\u7684\u5de5\u5177\u548c\u6280\u672f\u53ef\u4ee5\u63d0\u9ad8\u4f60\u7684\u5de5\u4f5c\u6548\u7387\u3002 \u6ce8\u91cd\u7ec6\u8282\u3002 \u8f6f\u4ef6\u5f00\u53d1\u662f\u4e00\u4e2a\u9700\u8981\u7ec6\u5fc3\u7684\u5de5\u4f5c\uff0c\u8981\u907f\u514d\u72af\u9519\u8bef\u3002 \u5584\u4e8e\u6c9f\u901a\u3002 \u4e0e\u56e2\u961f\u6210\u5458\u3001\u5ba2\u6237\u548c\u5176\u4ed6\u5229\u76ca\u76f8\u5173\u8005\u8fdb\u884c\u6709\u6548\u6c9f\u901a\uff0c\u4ee5\u786e\u4fdd\u9879\u76ee\u987a\u5229\u8fdb\u884c\u3002","title":"\u56db\u3001\u65e5\u5e38\u5de5\u4f5c"},{"location":"Reading/Developers/#_6","text":"\u6838\u5fc3\u601d\u60f3: \u8f6f\u4ef6\u5f00\u53d1\u8005\u7684\u804c\u4e1a\u53d1\u5c55\u4e0d\u4ec5\u4ec5\u662f\u83b7\u5f97\u66f4\u9ad8\u7684\u804c\u4f4d\u548c\u85aa\u916c\uff0c\u66f4\u91cd\u8981\u7684\u662f\u4e0d\u65ad\u5b66\u4e60\u548c\u6210\u957f\uff0c\u6210\u4e3a\u4e00\u540d\u4f18\u79c0\u7684\u8f6f\u4ef6\u5de5\u7a0b\u5e08\u3002 \u672c\u7bc7\u4ecb\u7ecd\u4e86\u5982\u4f55\u63a8\u8fdb\u4f60\u7684\u804c\u4e1a\u53d1\u5c55\u7684\u7b56\u7565\u548c\u65b9\u6cd5\uff0c\u5305\u62ec\uff1a \u5efa\u7acb\u4e2a\u4eba\u54c1\u724c \u62d3\u5c55\u4eba\u8109 \u4fdd\u6301\u5b66\u4e60 \u8d21\u732e\u793e\u533a \u5bfb\u627e\u5bfc\u5e08 \u89c4\u5212\u804c\u4e1a\u9053\u8def \u4e3b\u8981\u5185\u5bb9: \u5efa\u7acb\u4e2a\u4eba\u54c1\u724c: \u901a\u8fc7\u535a\u5ba2\u3001\u6280\u672f\u6587\u7ae0\u3001\u5f00\u6e90\u9879\u76ee\u7b49\u65b9\u5f0f\u5efa\u7acb\u4f60\u7684\u4e2a\u4eba\u54c1\u724c\uff0c\u8ba9\u66f4\u591a\u7684\u4eba\u4e86\u89e3\u4f60\u7684\u6280\u80fd\u548c\u7ecf\u9a8c\u3002 \u62d3\u5c55\u4eba\u8109: \u53c2\u52a0\u884c\u4e1a\u6d3b\u52a8\u3001\u6280\u672f\u4f1a\u8bae\u7b49\uff0c\u4e0e\u5176\u4ed6\u8f6f\u4ef6\u5f00\u53d1\u8005\u5efa\u7acb\u8054\u7cfb\uff0c\u62d3\u5c55\u4f60\u7684\u4eba\u8109\u3002 \u4fdd\u6301\u5b66\u4e60: \u4e0d\u65ad\u5b66\u4e60\u65b0\u7684\u6280\u80fd\u548c\u77e5\u8bc6\uff0c\u9605\u8bfb\u4e66\u7c4d\u3001\u53c2\u52a0\u57f9\u8bad\u8bfe\u7a0b\u7b49\uff0c\u4fdd\u6301\u4f60\u7684\u7ade\u4e89\u529b\u3002 \u8d21\u732e\u793e\u533a: \u53c2\u4e0e\u5f00\u6e90\u9879\u76ee\u3001\u6280\u672f\u793e\u533a\u7b49\uff0c\u4e3a\u793e\u533a\u505a\u51fa\u8d21\u732e\uff0c\u63d0\u5347\u4f60\u7684\u5f71\u54cd\u529b\u3002 \u5bfb\u627e\u5bfc\u5e08: \u5bfb\u627e\u4e00\u4f4d\u7ecf\u9a8c\u4e30\u5bcc\u7684\u8f6f\u4ef6\u5f00\u53d1\u8005\u4f5c\u4e3a\u4f60\u7684\u5bfc\u5e08\uff0c\u53ef\u4ee5\u5e2e\u52a9\u4f60\u5b66\u4e60\u548c\u6210\u957f\u3002 \u89c4\u5212\u804c\u4e1a\u9053\u8def: \u660e\u786e\u4f60\u7684\u804c\u4e1a\u76ee\u6807\uff0c\u5e76\u5236\u5b9a\u8ba1\u5212\u5b9e\u73b0\u4f60\u7684\u76ee\u6807\u3002 \u5173\u952e\u6b65\u9aa4: \u81ea\u6211\u8bc4\u4f30: \u8bc4\u4f30\u4f60\u7684\u6280\u80fd\u3001\u7ecf\u9a8c\u548c\u76ee\u6807\u3002 \u5236\u5b9a\u8ba1\u5212: \u5236\u5b9a\u4f60\u7684\u804c\u4e1a\u53d1\u5c55\u8ba1\u5212\uff0c\u5e76\u8bbe\u5b9a\u5177\u4f53\u7684\u76ee\u6a19\u3002 \u884c\u52a8\u8d77\u6765: \u91c7\u53d6\u884c\u52a8\uff0c\u6267\u884c\u4f60\u7684\u8ba1\u5212\u3002 \u5b9a\u671f\u56de\u987e: \u5b9a\u671f\u56de\u987e\u4f60\u7684\u8ba1\u5212\uff0c\u5e76\u8fdb\u884c\u5fc5\u8981\u7684\u8c03\u6574\u3002 \u603b\u7ed3: \u8f6f\u4ef6\u5f00\u53d1\u8005\u7684\u804c\u4e1a\u53d1\u5c55\u662f\u4e00\u4e2a\u6301\u7eed\u7684\u8fc7\u7a0b\u3002\u901a\u8fc7\u5236\u5b9a\u8ba1\u5212\u3001\u91c7\u53d6\u884c\u52a8 and \u4e0d\u65ad\u5b66\u4e60\uff0c\u4f60\u5c31\u53ef\u4ee5\u5b9e\u73b0\u4f60\u7684\u804c\u4e1a\u76ee\u6807\uff0c\u6210\u4e3a\u4e00\u540d\u4f18\u79c0\u7684\u8f6f\u4ef6\u5de5\u7a0b\u5e08\u3002 \u4ee5\u4e0b\u662f\u4e00\u4e9b\u5177\u4f53\u7684\u5efa\u8bae: \u79ef\u6781\u53c2\u4e0e\u6280\u672f\u793e\u533a\u3002 \u8fd9\u662f\u4e00\u4e2a\u5f88\u597d\u7684\u5b66\u4e60\u673a\u4f1a\uff0c\u53ef\u4ee5\u8ba9\u4f60\u4e0e\u5176\u4ed6\u5f00\u53d1\u4eba\u5458\u4ea4\u6d41\u5e76\u4e86\u89e3\u6700\u65b0\u7684\u6280\u672f\u548c\u8d8b\u52bf\u3002 \u5bfb\u627e\u4e00\u4f4d\u5bfc\u5e08\u3002 \u4e00\u4f4d\u7ecf\u9a8c\u4e30\u5bcc\u7684\u5bfc\u5e08\u53ef\u4ee5\u5e2e\u52a9\u4f60\u5b66\u4e60\u548c\u6210\u957f\uff0c\u5e76\u4e3a\u4f60\u63d0\u4f9b\u5b9d\u8d35\u7684\u5efa\u8bae\u3002 \u53c2\u52a0\u884c\u4e1a\u6d3b\u52a8\u3002 \u8fd9\u662f\u4e00\u4e2a\u5f88\u597d\u7684\u7ed3\u8bc6\u5176\u4ed6\u5f00\u53d1\u4eba\u5458\u548c\u4e86\u89e3\u884c\u4e1a\u8d8b\u52bf\u7684\u673a\u4f1a\u3002 \u5199\u535a\u5ba2\u6216\u6280\u672f\u6587\u7ae0\u3002 \u8fd9\u662f\u4e00\u4e2a\u5206\u4eab\u4f60\u7684\u77e5\u8bc6\u548c\u7ecf\u9a8c\u7684\u597d\u65b9\u6cd5\uff0c\u5e76\u5efa\u7acb\u4f60\u7684\u4e2a\u4eba\u54c1\u724c\u3002 \u5f00\u6e90\u9879\u76ee\u3002 \u8fd9\u662f\u4e00\u4e2a\u5f88\u597d\u7684\u8d21\u732e\u793e\u533a\u548c\u5b66\u4e60\u65b0\u6280\u80fd\u7684\u673a\u4f1a\u3002 \u4ee5\u4e0b\u662f\u4e00\u4e9b\u989d\u5916\u7684\u8865\u5145: \u4e66\u4e2d\u8fd8\u63d0\u5230\u4e86 \u5de5\u4f5c\u4e0e\u751f\u6d3b\u7684\u5e73\u8861 \u7684\u91cd\u8981\u6027\u3002\u5de5\u4f5c\u56fa\u7136\u91cd\u8981\uff0c\u4f46\u4e5f\u8981\u6ce8\u91cd\u4e2a\u4eba\u751f\u6d3b\u548c\u5065\u5eb7\u3002 \u4e66\u4e2d\u4e5f\u5f3a\u8c03\u4e86 \u7ec8\u8eab\u5b66\u4e60 \u7684\u91cd\u8981\u6027\u3002\u8f6f\u4ef6\u5f00\u53d1\u662f\u4e00\u4e2a\u5feb\u901f\u53d1\u5c55\u7684\u884c\u4e1a\uff0c\u4f60\u9700\u8981\u4e0d\u65ad\u5b66\u4e60\u624d\u80fd\u8ddf\u4e0a\u6700\u65b0\u7684\u6280\u672f\u548c\u8d8b\u52bf\u3002","title":"\u4e94\u3001\u804c\u4e1a\u53d1\u5c55"},{"location":"Reading/Developers/#_7","text":"\u6838\u5fc3\u601d\u60f3: \u8f6f\u4ef6\u5f00\u53d1\u4eba\u5458\u7684\u804c\u4e1a\u53d1\u5c55\u4e0d\u4ec5\u4ec5\u662f\u5199\u4ee3\u7801\uff0c\u8fd8\u9700\u8981\u638c\u63e1\u5404\u79cd\u8f6f\u6280\u80fd\uff0c\u624d\u80fd\u53d6\u5f97\u6210\u529f\u3002 \u672c\u7bc7\u4ecb\u7ecd\u4e86\u8f6f\u4ef6\u5f00\u53d1\u4eba\u5458\u804c\u4e1a\u53d1\u5c55\u8fc7\u7a0b\u4e2d\u9700\u8981\u5173\u6ce8\u7684\u51e0\u4e2a\u5173\u952e\u65b9\u9762\uff0c\u5305\u62ec\uff1a \u804c\u4e1a\u89c4\u5212 \u9762\u8bd5\u6280\u5de7 \u6c9f\u901a\u80fd\u529b \u56e2\u961f\u5408\u4f5c \u65f6\u95f4\u7ba1\u7406 \u9886\u5bfc\u529b \u4e3b\u8981\u5185\u5bb9: \u804c\u4e1a\u89c4\u5212: \u8bbe\u5b9a\u804c\u4e1a\u76ee\u6807\uff0c\u5e76\u5236\u5b9a\u5b9e\u73b0\u76ee\u6807\u7684\u8ba1\u5212\u3002 \u9762\u8bd5\u6280\u5de7: \u51c6\u5907\u7b80\u5386\u548c\u9762\u8bd5\u6750\u6599\uff0c\u5e76\u7ec3\u4e60\u9762\u8bd5\u6280\u5de7\u3002 \u6c9f\u901a\u80fd\u529b: \u6e05\u6670\u6709\u6548\u5730\u8868\u8fbe\u81ea\u5df1\u7684\u60f3\u6cd5\u548c\u89c2\u70b9\u3002 \u56e2\u961f\u5408\u4f5c: \u4e0e\u4ed6\u4eba\u5408\u4f5c\u5b8c\u6210\u5171\u540c\u76ee\u6807\u3002 \u65f6\u95f4\u7ba1\u7406: \u9ad8\u6548\u5730\u5229\u7528\u65f6\u95f4\uff0c\u5b8c\u6210\u5de5\u4f5c\u4efb\u52a1\u3002 \u9886\u5bfc\u529b: \u9886\u5bfc\u56e2\u961f\u5b8c\u6210\u76ee\u6807\u3002 \u5173\u952e\u6b65\u9aa4: \u81ea\u6211\u8bc4\u4f30: \u4e86\u89e3\u81ea\u5df1\u7684\u4f18\u52bf\u3001\u52a3\u52bf\u3001\u5174\u8da3\u548c\u6280\u80fd\u3002 \u8bbe\u5b9a\u76ee\u6807: \u8bbe\u5b9a\u77ed\u671f\u548c\u957f\u671f\u7684\u804c\u4e1a\u76ee\u6807\u3002 \u5236\u5b9a\u8ba1\u5212: \u5236\u5b9a\u5b9e\u73b0\u76ee\u6807\u7684\u5177\u4f53\u8ba1\u5212\u3002 \u4e0d\u65ad\u5b66\u4e60: \u5b66\u4e60\u65b0\u6280\u80fd\u548c\u77e5\u8bc6\uff0c\u63d0\u5347\u81ea\u8eab\u80fd\u529b\u3002 \u5efa\u7acb\u4eba\u8109: \u5efa\u7acb\u4e0e\u5176\u4ed6\u5f00\u53d1\u4eba\u5458\u548c\u884c\u4e1a\u4e13\u5bb6\u7684\u8054\u7cfb\u3002 \u603b\u7ed3: \u8f6f\u4ef6\u5f00\u53d1\u4eba\u5458\u7684\u804c\u4e1a\u53d1\u5c55\u662f\u4e00\u4e2a\u6301\u7eed\u5b66\u4e60\u548c\u6210\u957f\u7684\u8fc7\u7a0b\u3002\u901a\u8fc7\u638c\u63e1\u5404\u79cd\u8f6f\u6280\u80fd\uff0c\u53ef\u4ee5\u63d0\u5347\u81ea\u8eab\u7684\u7ade\u4e89\u529b\uff0c\u5728\u804c\u4e1a\u53d1\u5c55\u4e2d\u53d6\u5f97\u6210\u529f\u3002 \u4ee5\u4e0b\u662f\u4e00\u4e9b\u5177\u4f53\u7684\u5efa\u8bae: \u5236\u5b9a\u804c\u4e1a\u89c4\u5212\u3002 \u82b1\u65f6\u95f4\u601d\u8003\u4f60\u60f3\u6210\u4e3a\u4e00\u540d\u4ec0\u4e48\u6837\u7684\u8f6f\u4ef6\u5f00\u53d1\u4eba\u5458\uff0c\u4ee5\u53ca\u4f60\u60f3\u8981\u8fbe\u6210\u7684\u804c\u4e1a\u76ee\u6807\u3002 \u4e0d\u65ad\u5b66\u4e60\u3002 \u8f6f\u4ef6\u884c\u4e1a\u53d1\u5c55\u8fc5\u901f\uff0c\u9700\u8981\u4e0d\u65ad\u5b66\u4e60\u65b0\u6280\u672f\u548c\u77e5\u8bc6\uff0c\u624d\u80fd\u4fdd\u6301\u7ade\u4e89\u529b\u3002 \u5efa\u7acb\u4eba\u8109\u3002 \u4e0e\u5176\u4ed6\u5f00\u53d1\u4eba\u5458\u548c\u884c\u4e1a\u4e13\u5bb6\u5efa\u7acb\u8054\u7cfb\uff0c\u53ef\u4ee5\u83b7\u5f97\u5b9d\u8d35\u7684\u7ecf\u9a8c\u548c\u5efa\u8bae\u3002 \u79ef\u6781\u53c2\u4e0e\u5f00\u6e90\u9879\u76ee\u3002 \u8fd9\u662f\u4e00\u4e2a\u5f88\u597d\u7684\u65b9\u5f0f\u6765\u5b66\u4e60\u65b0\u6280\u80fd\uff0c\u5e76\u83b7\u5f97\u5176\u4ed6\u5f00\u53d1\u4eba\u5458\u7684\u8ba4\u53ef\u3002 \u5bfb\u627e\u5bfc\u5e08\u3002 \u627e\u5230\u4e00\u4f4d\u7ecf\u9a8c\u4e30\u5bcc\u7684\u5bfc\u5e08\u53ef\u4ee5\u5e2e\u52a9\u4f60\u6307\u5f15\u65b9\u5411\uff0c\u5e76\u63d0\u4f9b\u5efa\u8bae\u3002 \u901a\u8fc7\u52aa\u529b\u5de5\u4f5c\u548c\u6301\u7eed\u5b66\u4e60\uff0c\u4f60\u4e00\u5b9a\u80fd\u591f\u5728\u4f60\u7684\u804c\u4e1a\u751f\u6daf\u4e2d\u53d6\u5f97\u6210\u529f\u3002","title":"\u4e00\u3001\u804c\u4e1a"},{"location":"Reading/Developers/#_8","text":"\u6838\u5fc3\u601d\u60f3\uff1a \u8f6f\u4ef6\u5f00\u53d1\u4eba\u5458\u9700\u8981\u5c06\u81ea\u5df1\u89c6\u4e3a\u4ea7\u54c1\uff0c\u5e76\u8fdb\u884c\u6709\u6548\u7684\u81ea\u6211\u8425\u9500\uff0c\u624d\u80fd\u5728\u804c\u4e1a\u53d1\u5c55\u4e2d\u53d6\u5f97\u6210\u529f\u3002 \u81ea\u6211\u8425\u9500\u5305\u62ec\u5efa\u7acb\u4e2a\u4eba\u54c1\u724c\u3001\u6253\u9020\u7ebf\u4e0a\u5f62\u8c61\u3001\u79ef\u6781\u53c2\u4e0e\u793e\u533a\u7b49\u591a\u4e2a\u65b9\u9762\u3002 \u4e3b\u8981\u5185\u5bb9\uff1a \u5efa\u7acb\u4e2a\u4eba\u54c1\u724c \uff1a\u660e\u786e\u81ea\u5df1\u7684\u4ef7\u503c\u4e3b\u5f20\uff0c\u5e76\u901a\u8fc7\u5404\u79cd\u6e20\u9053\u5c06\u5176\u4f20\u9012\u7ed9\u76ee\u6807\u53d7\u4f17\u3002 \u6253\u9020\u7ebf\u4e0a\u5f62\u8c61 \uff1a\u521b\u5efa\u5e76\u7ef4\u62a4\u4e2a\u4eba\u7f51\u7ad9\u3001\u535a\u5ba2\u3001\u793e\u4ea4\u5a92\u4f53\u8d26\u53f7\u7b49\uff0c\u5c55\u793a\u81ea\u5df1\u7684\u4e13\u4e1a\u6280\u80fd\u548c\u7ecf\u9a8c\u3002 \u79ef\u6781\u53c2\u4e0e\u793e\u533a \uff1a\u53c2\u52a0\u6280\u672f\u4f1a\u8bae\u3001\u5f00\u6e90\u9879\u76ee\u3001\u7ebf\u4e0a\u8bba\u575b\u7b49\uff0c\u4e0e\u5176\u4ed6\u5f00\u53d1\u4eba\u5458\u5efa\u7acb\u8054\u7cfb\uff0c\u6269\u5927\u5f71\u54cd\u529b\u3002 \u5176\u4ed6\u81ea\u6211\u8425\u9500\u7b56\u7565 \uff1a\u64b0\u5199\u6280\u672f\u6587\u7ae0\u3001\u6f14\u8bb2\u3001\u51fa\u7248\u4e66\u7c4d\u7b49\uff0c\u6811\u7acb\u884c\u4e1a\u4e13\u5bb6\u5f62\u8c61\u3002 \u5173\u952e\u6b65\u9aa4\uff1a \u81ea\u6211\u8bc4\u4f30 \uff1a\u5206\u6790\u81ea\u5df1\u7684\u4f18\u52bf\u3001\u52a3\u52bf\u3001\u6280\u80fd\u548c\u7ecf\u9a8c\uff0c\u660e\u786e\u81ea\u5df1\u7684\u804c\u4e1a\u76ee\u6807\u3002 \u5236\u5b9a\u76ee\u6807 \uff1a\u6839\u636e\u804c\u4e1a\u76ee\u6807\uff0c\u786e\u5b9a\u81ea\u6211\u8425\u9500\u7684\u5177\u4f53\u65b9\u5411\u548c\u7b56\u7565\u3002 \u6267\u884c\u7b56\u7565 \uff1a\u91c7\u53d6\u5404\u79cd\u63aa\u65bd\uff0c\u5efa\u7acb\u4e2a\u4eba\u54c1\u724c\u3001\u6253\u9020\u7ebf\u4e0a\u5f62\u8c61\u3001\u79ef\u6781\u53c2\u4e0e\u793e\u533a\u7b49\u3002 \u6301\u7eed\u6539\u8fdb \uff1a\u5b9a\u671f\u8bc4\u4f30\u81ea\u6211\u8425\u9500\u7684\u6548\u679c\uff0c\u5e76\u6839\u636e\u9700\u8981\u8fdb\u884c\u8c03\u6574\u548c\u6539\u8fdb\u3002 \u603b\u7ed3\uff1a \u81ea\u6211\u8425\u9500\u662f\u8f6f\u4ef6\u5f00\u53d1\u4eba\u5458\u5728\u804c\u4e1a\u53d1\u5c55\u4e2d\u4e0d\u53ef\u5ffd\u89c6\u7684\u91cd\u8981\u6280\u80fd\u3002\u901a\u8fc7\u6709\u6548\u7684\u81ea\u6211\u8425\u9500\uff0c\u53ef\u4ee5\u63d0\u5347\u4e2a\u4eba\u77e5\u540d\u5ea6\u3001\u5efa\u7acb\u4e13\u4e1a\u5f62\u8c61\u3001\u62d3\u5c55\u804c\u4e1a\u673a\u4f1a\uff0c\u6700\u7ec8\u5b9e\u73b0\u804c\u4e1a\u76ee\u6807\u3002 \u4ee5\u4e0b\u662f\u4e00\u4e9b\u5177\u4f53\u7684\u5efa\u8bae\uff1a \u82b1\u65f6\u95f4\u6253\u9020\u4f60\u7684\u4e2a\u4eba\u54c1\u724c\u3002 \u8fd9\u5305\u62ec\u521b\u5efa\u4e00\u4e2a\u4e2a\u4eba\u7f51\u7ad9\u6216\u535a\u5ba2\uff0c\u5e76\u5b9a\u671f\u53d1\u5e03\u9ad8\u8d28\u91cf\u7684\u5185\u5bb9\u3002 \u4f60\u4e5f\u53ef\u4ee5\u5728\u793e\u4ea4\u5a92\u4f53\u4e0a\u79ef\u6781\u53c2\u4e0e\uff0c\u5e76\u4e0e\u5176\u4ed6\u5f00\u53d1\u4eba\u5458\u5efa\u7acb\u8054\u7cfb\u3002 \u53c2\u4e0e\u5f00\u6e90\u9879\u76ee\u3002 \u8fd9\u662f\u4e00\u4e2a\u5f88\u597d\u7684\u65b9\u5f0f\u6765\u5c55\u793a\u4f60\u7684\u6280\u80fd\u548c\u7ecf\u9a8c\uff0c\u5e76\u83b7\u5f97\u5176\u4ed6\u5f00\u53d1\u4eba\u5458\u7684\u8ba4\u53ef\u3002 \u53c2\u52a0\u6280\u672f\u4f1a\u8bae\u548c\u6d3b\u52a8\u3002 \u8fd9\u662f\u4e00\u4e2a\u5f88\u597d\u7684\u65b9\u5f0f\u6765\u5b66\u4e60\u65b0\u6280\u672f\uff0c\u5e76\u7ed3\u8bc6\u5176\u4ed6\u5f00\u53d1\u4eba\u5458\u3002 \u64b0\u5199\u6280\u672f\u6587\u7ae0\u6216\u4e66\u7c4d\u3002 \u8fd9\u662f\u4e00\u4e2a\u5f88\u597d\u7684\u65b9\u5f0f\u6765\u5206\u4eab\u4f60\u7684\u77e5\u8bc6\u548c\u7ecf\u9a8c\uff0c\u5e76\u5efa\u7acb\u4f60\u7684\u4e13\u4e1a\u5f62\u8c61\u3002 \u901a\u8fc7\u52aa\u529b\u5de5\u4f5c\u548c\u6301\u7eed\u6539\u8fdb\uff0c\u4f60\u4e00\u5b9a\u80fd\u591f\u5728\u81ea\u6211\u8425\u9500\u65b9\u9762\u53d6\u5f97\u6210\u529f\u3002","title":"\u4e8c\u3001\u81ea\u6211\u8425\u9500"},{"location":"Reading/Developers/#_9","text":"\u6838\u5fc3\u601d\u60f3: \u5b66\u4e60\u662f\u8f6f\u4ef6\u5f00\u53d1\u4eba\u5458\u6301\u7eed\u6210\u957f\u548c\u6210\u529f\u7684\u5173\u952e\u3002 \u672c\u7bc7\u4ecb\u7ecd\u4e86\u5982\u4f55\u5feb\u901f\u6709\u6548\u5730\u5b66\u4e60\u65b0\u6280\u80fd\u548c\u77e5\u8bc6\uff0c\u5305\u62ec\uff1a \u5236\u5b9a\u5b66\u4e60\u8ba1\u5212 \u9009\u62e9\u5408\u9002\u7684\u5b66\u4e60\u8d44\u6e90 \u63d0\u9ad8\u5b66\u4e60\u6548\u7387 \u4fdd\u6301\u5b66\u4e60\u52a8\u529b \u4e3b\u8981\u5185\u5bb9: \u5236\u5b9a\u5b66\u4e60\u8ba1\u5212: \u660e\u786e\u5b66\u4e60\u76ee\u6807\uff0c\u5e76\u5236\u5b9a\u5177\u4f53\u7684\u5b66\u4e60\u8ba1\u5212\u3002 \u9009\u62e9\u5408\u9002\u7684\u5b66\u4e60\u8d44\u6e90: \u9009\u62e9\u9002\u5408\u81ea\u5df1\u7684\u5b66\u4e60\u65b9\u5f0f\u548c\u8d44\u6e90\uff0c\u4f8b\u5982\u4e66\u7c4d\u3001\u6587\u7ae0\u3001\u89c6\u9891\u3001\u8bfe\u7a0b\u7b49\u3002 \u63d0\u9ad8\u5b66\u4e60\u6548\u7387: \u638c\u63e1\u6709\u6548\u7684\u5b66\u4e60\u6280\u5de7\uff0c\u4f8b\u5982\u756a\u8304\u5de5\u4f5c\u6cd5\u3001\u8d39\u66fc\u6280\u5de7\u7b49\u3002 \u4fdd\u6301\u5b66\u4e60\u52a8\u529b: \u4fdd\u6301\u5bf9\u5b66\u4e60\u7684\u70ed\u60c5\u548c\u5174\u8da3\uff0c\u5e76\u5236\u5b9a\u6fc0\u52b1\u63aa\u65bd\u3002 \u5173\u952e\u6b65\u9aa4: \u8bbe\u5b9a\u76ee\u6807: \u660e\u786e\u4f60\u60f3\u8981\u5b66\u4e60\u4ec0\u4e48\uff0c\u4ee5\u53ca\u4f60\u60f3\u8981\u8fbe\u5230\u7684\u5b66\u4e60\u76ee\u6807\u3002 \u5236\u5b9a\u8ba1\u5212: \u5236\u5b9a\u5177\u4f53\u7684\u5b66\u4e60\u8ba1\u5212\uff0c\u5305\u62ec\u5b66\u4e60\u5185\u5bb9\u3001\u5b66\u4e60\u65f6\u95f4\u548c\u5b66\u4e60\u65b9\u6cd5\u7b49\u3002 \u9009\u62e9\u8d44\u6e90: \u9009\u62e9\u9002\u5408\u81ea\u5df1\u7684\u5b66\u4e60\u65b9\u5f0f\u548c\u8d44\u6e90\uff0c\u5e76\u786e\u4fdd\u8d44\u6e90\u7684\u8d28\u91cf\u548c\u53ef\u9760\u6027\u3002 \u4ed8\u8bf8\u884c\u52a8: \u6309\u7167\u8ba1\u5212\u5f00\u59cb\u5b66\u4e60\uff0c\u5e76\u5b9a\u671f\u8bc4\u4f30\u5b66\u4e60\u8fdb\u5ea6\u548c\u6548\u679c\u3002 \u4fdd\u6301\u52a8\u529b: \u4fdd\u6301\u5bf9\u5b66\u4e60\u7684\u70ed\u60c5\u548c\u5174\u8da3\uff0c\u5e76\u5236\u5b9a\u6fc0\u52b1\u63aa\u65bd\u3002 \u603b\u7ed3: \u5b66\u4e60\u662f\u4e00\u4e2a\u9700\u8981\u4e0d\u65ad\u5b9e\u8df5\u548c\u6539\u8fdb\u7684\u8fc7\u7a0b\u3002\u901a\u8fc7\u638c\u63e1\u6709\u6548\u7684\u5b66\u4e60\u65b9\u6cd5\uff0c\u53ef\u4ee5\u63d0\u9ad8\u5b66\u4e60\u6548\u7387\uff0c\u5e76\u53d6\u5f97\u66f4\u597d\u7684\u5b66\u4e60\u6210\u679c\u3002 \u4ee5\u4e0b\u662f\u4e00\u4e9b\u5177\u4f53\u7684\u5efa\u8bae: \u5236\u5b9a\u5177\u4f53\u7684\u5b66\u4e60\u76ee\u6807\u3002 \u76ee\u6807\u8d8a\u5177\u4f53\uff0c\u5c31\u8d8a\u5bb9\u6613\u5b9e\u73b0\u3002 \u5c06\u5b66\u4e60\u4efb\u52a1\u5206\u89e3\u6210\u5c0f\u5757\u3002 \u8fd9\u6837\u66f4\u5bb9\u6613\u5b8c\u6210\uff0c\u4e5f\u80fd\u8ba9\u4f60\u4fdd\u6301\u5b66\u4e60\u7684\u52a8\u529b\u3002 \u627e\u5230\u9002\u5408\u81ea\u5df1\u7684\u5b66\u4e60\u65b9\u5f0f\u3002 \u6709\u4e9b\u4eba\u559c\u6b22\u770b\u4e66\uff0c\u6709\u4e9b\u4eba\u559c\u6b22\u770b\u89c6\u9891\uff0c\u6709\u4e9b\u4eba\u559c\u6b22\u53c2\u52a0\u8bfe\u7a0b\u3002 \u5229\u7528\u788e\u7247\u65f6\u95f4\u5b66\u4e60\u3002 \u5229\u7528\u901a\u52e4\u65f6\u95f4\u3001\u5348\u4f11\u65f6\u95f4\u7b49\u788e\u7247\u65f6\u95f4\u5b66\u4e60\uff0c\u53ef\u4ee5\u63d0\u9ad8\u5b66\u4e60\u6548\u7387\u3002 \u4e0e\u4ed6\u4eba\u4e00\u8d77\u5b66\u4e60\u3002 \u4e0e\u4ed6\u4eba\u4e00\u8d77\u5b66\u4e60\u53ef\u4ee5\u4e92\u76f8\u9f13\u52b1\uff0c\u4e92\u76f8\u5e2e\u52a9\u3002 \u901a\u8fc7\u52aa\u529b\u5b66\u4e60\u548c\u4e0d\u65ad\u5b9e\u8df5\uff0c\u4f60\u4e00\u5b9a\u80fd\u591f\u5728\u4f60\u7684\u804c\u4e1a\u751f\u6daf\u4e2d\u53d6\u5f97\u6210\u529f\u3002","title":"\u4e09\u3001\u5b66\u4e60"},{"location":"Reading/Developers/#_10","text":"\u6838\u5fc3\u601d\u60f3: \u63d0\u9ad8\u751f\u4ea7\u529b\u662f\u8f6f\u4ef6\u5f00\u53d1\u4eba\u5458\u53d6\u5f97\u6210\u529f\u7684\u5173\u952e\u56e0\u7d20\u4e4b\u4e00\u3002 \u672c\u7bc7\u4ecb\u7ecd\u4e86\u5982\u4f55\u63d0\u9ad8\u5de5\u4f5c\u6548\u7387\u548c\u4ea7\u51fa\uff0c\u5305\u62ec\uff1a \u65f6\u95f4\u7ba1\u7406 \u4efb\u52a1\u7ba1\u7406 \u4e13\u6ce8\u529b \u6c9f\u901a\u6280\u5de7 \u907f\u514d\u5e72\u6270 \u4e3b\u8981\u5185\u5bb9: \u65f6\u95f4\u7ba1\u7406: \u6709\u6548\u5730\u5229\u7528\u65f6\u95f4\uff0c\u5b8c\u6210\u5de5\u4f5c\u4efb\u52a1\u3002 \u4efb\u52a1\u7ba1\u7406: \u5236\u5b9a\u4efb\u52a1\u8ba1\u5212\uff0c\u5e76\u6709\u6548\u5730\u8ddf\u8e2a\u4efb\u52a1\u8fdb\u5ea6\u3002 \u4e13\u6ce8\u529b: \u63d0\u9ad8\u5de5\u4f5c\u65f6\u7684\u4e13\u6ce8\u5ea6\uff0c\u907f\u514d\u5206\u5fc3\u3002 \u6c9f\u901a\u6280\u5de7: \u6e05\u6670\u6709\u6548\u5730\u4e0e\u4ed6\u4eba\u6c9f\u901a\uff0c\u907f\u514d\u8bef\u89e3\u548c\u6d6a\u8d39\u65f6\u95f4\u3002 \u907f\u514d\u5e72\u6270: \u51cf\u5c11\u5de5\u4f5c\u73af\u5883\u4e2d\u7684\u5e72\u6270\u56e0\u7d20\uff0c\u63d0\u9ad8\u5de5\u4f5c\u6548\u7387\u3002 \u5173\u952e\u6b65\u9aa4: \u8bc4\u4f30\u73b0\u72b6: \u8bc4\u4f30\u5f53\u524d\u7684\u5de5\u4f5c\u6548\u7387\u548c\u4ea7\u51fa\u6c34\u5e73\u3002 \u8bbe\u5b9a\u76ee\u6807: \u8bbe\u5b9a\u63d0\u9ad8\u751f\u4ea7\u529b\u7684\u76ee\u6807\u3002 \u5236\u5b9a\u8ba1\u5212: \u5236\u5b9a\u5177\u4f53\u7684\u63d0\u9ad8\u751f\u4ea7\u529b\u7684\u8ba1\u5212\u3002 \u4ed8\u8bf8\u884c\u52a8: \u6309\u7167\u8ba1\u5212\u5f00\u59cb\u5b9e\u65bd\uff0c\u5e76\u5b9a\u671f\u8bc4\u4f30\u6548\u679c\u3002 \u6301\u7eed\u6539\u8fdb: \u4e0d\u65ad\u5bfb\u627e\u65b0\u7684\u65b9\u6cd5\u548c\u5de5\u5177\u6765\u63d0\u9ad8\u751f\u4ea7\u529b\u3002 \u603b\u7ed3: \u63d0\u9ad8\u751f\u4ea7\u529b\u662f\u4e00\u4e2a\u9700\u8981\u4e0d\u65ad\u5b9e\u8df5\u548c\u6539\u8fdb\u7684\u8fc7\u7a0b\u3002\u901a\u8fc7\u638c\u63e1\u6709\u6548\u7684\u65f6\u95f4\u7ba1\u7406\u3001\u4efb\u52a1\u7ba1\u7406\u3001\u6c9f\u901a\u6280\u5de7\u7b49\u65b9\u6cd5\uff0c\u53ef\u4ee5\u63d0\u9ad8\u5de5\u4f5c\u6548\u7387\uff0c\u5e76\u53d6\u5f97\u66f4\u597d\u7684\u5de5\u4f5c\u6210\u679c\u3002 \u4ee5\u4e0b\u662f\u4e00\u4e9b\u5177\u4f53\u7684\u5efa\u8bae: \u4f7f\u7528\u65f6\u95f4\u7ba1\u7406\u5de5\u5177\u3002 \u8bb8\u591a\u65f6\u95f4\u7ba1\u7406\u5de5\u5177\u53ef\u4ee5\u5e2e\u52a9\u4f60\u8ddf\u8e2a\u65f6\u95f4\u3001\u5236\u5b9a\u8ba1\u5212\u548c\u63d0\u9ad8\u6548\u7387\u3002 \u5236\u5b9a\u4efb\u52a1\u6e05\u5355\u3002 \u5c06\u6240\u6709\u5f85\u529e\u4e8b\u9879\u5217\u5165\u6e05\u5355\uff0c\u5e76\u6309\u7167\u4f18\u5148\u7ea7\u6392\u5e8f\u3002 \u8bbe\u5b9a\u622a\u6b62\u65e5\u671f\u3002 \u4e3a\u6bcf\u4e2a\u4efb\u52a1\u8bbe\u5b9a\u622a\u6b62\u65e5\u671f\uff0c\u53ef\u4ee5\u5e2e\u52a9\u4f60\u63d0\u9ad8\u5de5\u4f5c\u6548\u7387\u3002 \u907f\u514d\u591a\u4efb\u52a1\u5904\u7406\u3002 \u540c\u65f6\u5904\u7406\u591a\u4e2a\u4efb\u52a1\u4f1a\u964d\u4f4e\u6548\u7387\uff0c\u5bfc\u81f4\u9519\u8bef\u3002 \u521b\u9020\u826f\u597d\u7684\u5de5\u4f5c\u73af\u5883\u3002 \u627e\u5230\u4e00\u4e2a\u5b89\u9759\u3001\u8212\u9002\u7684\u5de5\u4f5c\u73af\u5883\uff0c\u53ef\u4ee5\u5e2e\u52a9\u4f60\u63d0\u9ad8\u4e13\u6ce8\u529b\u3002 \u901a\u8fc7\u52aa\u529b\u63d0\u9ad8\u751f\u4ea7\u529b\uff0c\u4f60\u4e00\u5b9a\u80fd\u591f\u5728\u4f60\u7684\u804c\u4e1a\u751f\u6daf\u4e2d\u53d6\u5f97\u66f4\u5927\u7684\u6210\u529f\u3002 \u4ee5\u4e0b\u662f\u4e00\u4e9b\u989d\u5916\u7684\u8865\u5145: \u4e66\u4e2d\u8fd8\u63d0\u5230\u4e86 \u81ea\u52a8\u5316 \u7684\u91cd\u8981\u6027\u3002\u901a\u8fc7\u4f7f\u7528\u81ea\u52a8\u5316\u5de5\u5177\uff0c\u53ef\u4ee5\u5c06\u4e00\u4e9b\u91cd\u590d\u6027\u5de5\u4f5c\u81ea\u52a8\u5316\uff0c\u4ece\u800c\u8282\u7701\u65f6\u95f4\u548c\u7cbe\u529b\u3002 \u4e66\u4e2d\u4e5f\u5f3a\u8c03\u4e86 \u5065\u5eb7 \u7684\u91cd\u8981\u6027\u3002\u4fdd\u6301\u5065\u5eb7\u7684\u8eab\u4f53\u548c\u5fc3\u7406\u72b6\u6001\uff0c\u624d\u80fd\u66f4\u597d\u5730\u5de5\u4f5c\u548c\u5b66\u4e60\u3002","title":"\u56db\u3001\u751f\u4ea7\u529b"},{"location":"Reading/Developers/#_11","text":"\u6838\u5fc3\u601d\u60f3: \u7406\u8d22\u662f\u8f6f\u4ef6\u5f00\u53d1\u4eba\u5458\u9700\u8981\u638c\u63e1\u7684\u91cd\u8981\u6280\u80fd\u4e4b\u4e00\uff0c\u53ef\u4ee5\u5e2e\u52a9\u4ed6\u4eec\u5b9e\u73b0\u8d22\u52a1\u76ee\u6807\uff0c\u5e76\u83b7\u5f97\u8d22\u52a1\u5b89\u5168\u611f\u3002 \u672c\u7bc7\u4ecb\u7ecd\u4e86\u7406\u8d22\u7684\u57fa\u672c\u6982\u5ff5\u548c\u539f\u5219\uff0c\u5305\u62ec\uff1a \u8bbe\u5b9a\u8d22\u52a1\u76ee\u6807 \u5236\u5b9a\u9884\u7b97 \u6295\u8d44\u7406\u8d22 \u9000\u4f11\u89c4\u5212 \u907f\u514d\u5e38\u89c1\u7684\u7406\u8d22\u9519\u8bef \u4e3b\u8981\u5185\u5bb9: \u8bbe\u5b9a\u8d22\u52a1\u76ee\u6807: \u660e\u786e\u4f60\u7684\u77ed\u671f\u548c\u957f\u671f\u7684\u8d22\u52a1\u76ee\u6807\uff0c\u4f8b\u5982\u8d2d\u4e70\u623f\u5c4b\u3001\u9000\u4f11\u517b\u8001\u7b49\u3002 \u5236\u5b9a\u9884\u7b97: \u8bb0\u5f55\u4f60\u7684\u6536\u5165\u548c\u652f\u51fa\uff0c\u5e76\u5236\u5b9a\u5408\u7406\u7684\u9884\u7b97\u8ba1\u5212\u3002 \u6295\u8d44\u7406\u8d22: \u5b66\u4e60\u6295\u8d44\u7406\u8d22\u77e5\u8bc6\uff0c\u5e76\u9009\u62e9\u9002\u5408\u81ea\u5df1\u7684\u6295\u8d44\u65b9\u5f0f\u3002 \u9000\u4f11\u89c4\u5212: \u63d0\u524d\u505a\u597d\u9000\u4f11\u89c4\u5212\uff0c\u786e\u4fdd\u9000\u4f11\u540e\u7684\u751f\u6d3b\u8d28\u91cf\u3002 \u907f\u514d\u5e38\u89c1\u7684\u7406\u8d22\u9519\u8bef: \u4e86\u89e3\u5e38\u89c1\u7684\u7406\u8d22\u9519\u8bef\uff0c\u5e76\u907f\u514d\u5728\u7406\u8d22\u8fc7\u7a0b\u4e2d\u72af\u9519\u3002 \u5173\u952e\u6b65\u9aa4: \u8bc4\u4f30\u73b0\u72b6: \u8bc4\u4f30\u5f53\u524d\u7684\u8d22\u52a1\u72b6\u51b5\uff0c\u5305\u62ec\u6536\u5165\u3001\u652f\u51fa\u3001\u8d44\u4ea7\u548c\u8d1f\u503a\u7b49\u3002 \u8bbe\u5b9a\u76ee\u6807: \u660e\u786e\u4f60\u7684\u77ed\u671f\u548c\u957f\u671f\u7684\u8d22\u52a1\u76ee\u6807\u3002 \u5236\u5b9a\u8ba1\u5212: \u5236\u5b9a\u5177\u4f53\u7684\u7406\u8d22\u8ba1\u5212\uff0c\u5305\u62ec\u9884\u7b97\u3001\u6295\u8d44\u548c\u9000\u4f11\u89c4\u5212\u7b49\u3002 \u4ed8\u8bf8\u884c\u52a8: \u6309\u7167\u8ba1\u5212\u5f00\u59cb\u5b9e\u65bd\uff0c\u5e76\u5b9a\u671f\u8bc4\u4f30\u6548\u679c\u3002 \u6301\u7eed\u5b66\u4e60: \u4e0d\u65ad\u5b66\u4e60\u7406\u8d22\u77e5\u8bc6\uff0c\u5e76\u6839\u636e\u60c5\u51b5\u8c03\u6574\u4f60\u7684\u7406\u8d22\u7b56\u7565\u3002 \u603b\u7ed3: \u7406\u8d22\u662f\u4e00\u4e2a\u9700\u8981\u957f\u671f\u575a\u6301\u7684\u8fc7\u7a0b\u3002\u901a\u8fc7\u638c\u63e1\u7406\u8d22\u7684\u57fa\u672c\u77e5\u8bc6\u548c\u6280\u80fd\uff0c\u53ef\u4ee5\u5e2e\u52a9\u4f60\u5b9e\u73b0\u8d22\u52a1\u76ee\u6807\uff0c\u5e76\u83b7\u5f97\u66f4\u597d\u7684\u751f\u6d3b\u3002 \u4ee5\u4e0b\u662f\u4e00\u4e9b\u5177\u4f53\u7684\u5efa\u8bae: \u5c3d\u65e9\u5f00\u59cb\u7406\u8d22\u3002 \u8d8a\u65e9\u5f00\u59cb\u7406\u8d22\uff0c\u4f60\u7684\u65f6\u95f4\u548c\u91d1\u94b1\u5c31\u8d8a\u6709\u4ef7\u503c\u3002 \u517b\u6210\u826f\u597d\u7684\u6d88\u8d39\u4e60\u60ef\u3002 \u907f\u514d\u51b2\u52a8\u6d88\u8d39\uff0c\u5e76\u5b66\u4f1a\u5ef6\u8fdf\u6ee1\u8db3\u3002 \u5b9a\u671f\u8fdb\u884c\u8d22\u52a1\u68c0\u67e5\u3002 \u5b9a\u671f\u68c0\u67e5\u4f60\u7684\u8d22\u52a1\u72b6\u51b5\uff0c\u5e76\u6839\u636e\u9700\u8981\u8c03\u6574\u4f60\u7684\u7406\u8d22\u8ba1\u5212\u3002 \u5bfb\u6c42\u4e13\u4e1a\u5e2e\u52a9\u3002 \u5982\u679c\u9700\u8981\uff0c\u53ef\u4ee5\u5bfb\u6c42\u7406\u8d22\u987e\u95ee\u7684\u5e2e\u52a9\u3002 \u4ee5\u4e0b\u662f\u4e00\u4e9b\u989d\u5916\u7684\u8865\u5145: \u4e66\u4e2d\u8fd8\u63d0\u5230\u4e86 \u4fdd\u9669 \u7684\u91cd\u8981\u6027\u3002\u901a\u8fc7\u8d2d\u4e70\u4fdd\u9669\uff0c\u53ef\u4ee5\u8f6c\u79fb\u98ce\u9669\uff0c\u5e76\u63d0\u4f9b\u5fc5\u8981\u7684\u4fdd\u969c\u3002 \u4e66\u4e2d\u4e5f\u5f3a\u8c03\u4e86 \u7a0e\u6536\u89c4\u5212 \u7684\u91cd\u8981\u6027\u3002\u901a\u8fc7\u5408\u7406\u7684\u7a0e\u6536\u89c4\u5212\uff0c\u53ef\u4ee5\u51cf\u5c11\u7a0e\u6536\u8d1f\u62c5\u3002","title":"\u4e94\u3001\u7406\u8d22"},{"location":"Reading/Developers/#_12","text":"\u6838\u5fc3\u601d\u60f3: \u5065\u8eab\u662f\u8f6f\u4ef6\u5f00\u53d1\u4eba\u5458\u4fdd\u6301\u5065\u5eb7\u548c\u6d3b\u529b\uff0c\u63d0\u9ad8\u5de5\u4f5c\u6548\u7387\u7684\u91cd\u8981\u9014\u5f84\u3002 \u672c\u7bc7\u4ecb\u7ecd\u4e86\u5065\u8eab\u7684\u57fa\u672c\u77e5\u8bc6\u548c\u65b9\u6cd5\uff0c\u5305\u62ec\uff1a \u5236\u5b9a\u5065\u8eab\u76ee\u6807 \u9009\u62e9\u9002\u5408\u7684\u8fd0\u52a8\u65b9\u5f0f \u996e\u98df\u5065\u5eb7 \u7761\u7720\u5145\u8db3 \u907f\u514d\u4e45\u5750 \u4e3b\u8981\u5185\u5bb9: \u5236\u5b9a\u5065\u8eab\u76ee\u6807: \u660e\u786e\u4f60\u7684\u5065\u8eab\u76ee\u6807\uff0c\u4f8b\u5982\u51cf\u80a5\u3001\u589e\u808c\u3001\u63d0\u9ad8\u8010\u529b\u7b49\u3002 \u9009\u62e9\u9002\u5408\u7684\u8fd0\u52a8\u65b9\u5f0f: \u6839\u636e\u4f60\u7684\u5174\u8da3\u3001\u8eab\u4f53\u72b6\u51b5\u548c\u65f6\u95f4\u5b89\u6392\uff0c\u9009\u62e9\u9002\u5408\u7684\u8fd0\u52a8\u65b9\u5f0f\u3002 \u996e\u98df\u5065\u5eb7: \u4fdd\u6301\u5065\u5eb7\u7684\u996e\u98df\u4e60\u60ef\uff0c\u591a\u5403\u852c\u83dc\u6c34\u679c\u3001\u5168\u8c37\u7269\u548c\u7626\u8089\u7b49\u3002 \u7761\u7720\u5145\u8db3: \u4fdd\u8bc1\u5145\u8db3\u7684\u7761\u7720\uff0c\u8ba9\u8eab\u4f53\u5f97\u5230\u5145\u5206\u4f11\u606f\u3002 \u907f\u514d\u4e45\u5750: \u907f\u514d\u957f\u65f6\u95f4\u5750\u7740\u4e0d\u52a8\uff0c\u6bcf\u5c0f\u65f6\u8d77\u8eab\u6d3b\u52a8\u51e0\u5206\u949f\u3002 \u5173\u952e\u6b65\u9aa4: \u8bc4\u4f30\u73b0\u72b6: \u8bc4\u4f30\u5f53\u524d\u7684\u8eab\u4f53\u72b6\u51b5\uff0c\u5305\u62ec\u4f53\u91cd\u3001\u4f53\u8102\u7387\u3001\u808c\u8089\u91cf\u7b49\u3002 \u8bbe\u5b9a\u76ee\u6807: \u660e\u786e\u4f60\u7684\u5065\u8eab\u76ee\u6807\u3002 \u5236\u5b9a\u8ba1\u5212: \u5236\u5b9a\u5177\u4f53\u7684\u5065\u8eab\u8ba1\u5212\uff0c\u5305\u62ec\u8fd0\u52a8\u65b9\u5f0f\u3001\u996e\u98df\u548c\u7761\u7720\u7b49\u3002 \u4ed8\u8bf8\u884c\u52a8: \u6309\u7167\u8ba1\u5212\u5f00\u59cb\u5b9e\u65bd\uff0c\u5e76\u5b9a\u671f\u8bc4\u4f30\u6548\u679c\u3002 \u4fdd\u6301\u575a\u6301: \u5065\u8eab\u662f\u4e00\u4e2a\u9700\u8981\u957f\u671f\u575a\u6301\u7684\u8fc7\u7a0b\uff0c\u4e0d\u8981\u8f7b\u6613\u653e\u5f03\u3002 \u603b\u7ed3: \u5065\u8eab\u662f\u4e00\u4e2a\u9700\u8981\u957f\u671f\u575a\u6301\u7684\u8fc7\u7a0b\u3002\u901a\u8fc7\u638c\u63e1\u5065\u8eab\u7684\u57fa\u672c\u77e5\u8bc6\u548c\u65b9\u6cd5\uff0c\u53ef\u4ee5\u5e2e\u52a9\u4f60\u4fdd\u6301\u5065\u5eb7\u548c\u6d3b\u529b\uff0c\u63d0\u9ad8\u5de5\u4f5c\u6548\u7387\uff0c\u5e76\u83b7\u5f97\u66f4\u597d\u7684\u751f\u6d3b\u3002 \u4ee5\u4e0b\u662f\u4e00\u4e9b\u5177\u4f53\u7684\u5efa\u8bae: \u5faa\u5e8f\u6e10\u8fdb\uff0c\u4e0d\u8981\u6025\u4e8e\u6c42\u6210\u3002 \u521a\u5f00\u59cb\u5065\u8eab\u65f6\uff0c\u4e0d\u8981\u8fdb\u884c\u8fc7\u4e8e\u5267\u70c8\u7684\u8fd0\u52a8\uff0c\u4ee5\u514d\u9020\u6210\u8fd0\u52a8\u635f\u4f24\u3002 \u627e\u5230\u9002\u5408\u81ea\u5df1\u7684\u8fd0\u52a8\u65b9\u5f0f\u3002 \u9009\u62e9\u4f60\u559c\u6b22\u7684\u8fd0\u52a8\u65b9\u5f0f\uff0c\u8fd9\u6837\u4f60\u624d\u80fd\u575a\u6301\u4e0b\u53bb\u3002 \u5c06\u5065\u8eab\u878d\u5165\u5230\u4f60\u7684\u65e5\u5e38\u751f\u6d3b\u3002 \u4f8b\u5982\uff0c\u4f60\u53ef\u4ee5\u6bcf\u5929\u6b65\u884c\u4e0a\u4e0b\u73ed\uff0c\u6216\u8005\u5229\u7528\u5348\u4f11\u65f6\u95f4\u8fdb\u884c\u953b\u70bc\u3002 \u5bfb\u627e\u5065\u8eab\u4f19\u4f34\u3002 \u4e0e\u670b\u53cb\u6216\u5bb6\u4eba\u4e00\u8d77\u5065\u8eab\uff0c\u53ef\u4ee5\u4e92\u76f8\u9f13\u52b1\uff0c\u4e92\u76f8\u5e2e\u52a9\u3002 \u4ee5\u4e0b\u662f\u4e00\u4e9b\u989d\u5916\u7684\u8865\u5145: \u4e66\u4e2d\u8fd8\u63d0\u5230\u4e86 \u538b\u529b\u7ba1\u7406 \u7684\u91cd\u8981\u6027\u3002\u901a\u8fc7\u5408\u7406\u7684\u538b\u529b\u7ba1\u7406\uff0c\u53ef\u4ee5\u51cf\u5c11\u538b\u529b\u5bf9\u8eab\u4f53\u7684\u8d1f\u9762\u5f71\u54cd\u3002 \u4e66\u4e2d\u4e5f\u5f3a\u8c03\u4e86 \u5fc3\u7406\u5065\u5eb7 \u7684\u91cd\u8981\u6027\u3002\u4fdd\u6301\u826f\u597d\u7684\u5fc3\u7406\u5065\u5eb7\uff0c\u624d\u80fd\u66f4\u597d\u5730\u5de5\u4f5c\u548c\u751f\u6d3b\u3002","title":"\u516d\u3001\u5065\u8eab"},{"location":"Reading/Developers/#_13","text":"\u6838\u5fc3\u601d\u60f3: \u5fc3\u6001\u662f\u8f6f\u4ef6\u5f00\u53d1\u4eba\u5458\u53d6\u5f97\u6210\u529f\u7684\u91cd\u8981\u56e0\u7d20\u4e4b\u4e00\u3002\u62e5\u6709\u79ef\u6781\u4e50\u89c2\u7684\u5fc3\u6001\uff0c\u53ef\u4ee5\u5e2e\u52a9\u4ed6\u4eec\u514b\u670d\u56f0\u96be\uff0c\u53d6\u5f97\u66f4\u5927\u7684\u6210\u5c31\u3002 \u672c\u7bc7\u4ecb\u7ecd\u4e86\u5982\u4f55\u57f9\u517b\u79ef\u6781\u4e50\u89c2\u7684\u5fc3\u6001\uff0c\u5305\u62ec\uff1a \u8ba4\u8bc6\u81ea\u5df1\u7684\u601d\u7ef4\u6a21\u5f0f \u6311\u6218\u8d1f\u9762\u601d\u7ef4 \u7ec3\u4e60\u6b63\u5ff5 \u57f9\u517b\u611f\u6069\u4e4b\u5fc3 \u4fdd\u6301\u6210\u957f\u578b\u601d\u7ef4 \u4e3b\u8981\u5185\u5bb9: \u8ba4\u8bc6\u81ea\u5df1\u7684\u601d\u7ef4\u6a21\u5f0f: \u4e86\u89e3\u81ea\u5df1\u7684\u601d\u7ef4\u6a21\u5f0f\uff0c\u8bc6\u522b\u5e38\u89c1\u7684\u601d\u7ef4\u8bef\u533a\u3002 \u6311\u6218\u8d1f\u9762\u601d\u7ef4: \u6311\u6218\u8d1f\u9762\u60f3\u6cd5\uff0c\u7528\u79ef\u6781\u7684\u60f3\u6cd5\u66ff\u6362\u5b83\u4eec\u3002 \u7ec3\u4e60\u6b63\u5ff5: \u7ec3\u4e60\u6b63\u5ff5\uff0c\u6d3b\u5728\u5f53\u4e0b\uff0c\u4e13\u6ce8\u4e8e\u4f60\u73b0\u5728\u6240\u505a\u7684\u4e8b\u60c5\u3002 \u57f9\u517b\u611f\u6069\u4e4b\u5fc3: \u57f9\u517b\u611f\u6069\u4e4b\u5fc3\uff0c\u5b66\u4f1a\u6b23\u8d4f\u4f60\u6240\u62e5\u6709\u7684\u3002 \u4fdd\u6301\u6210\u957f\u578b\u601d\u7ef4: \u76f8\u4fe1\u81ea\u5df1\u53ef\u4ee5\u901a\u8fc7\u52aa\u529b\u5b66\u4e60\u548c\u6210\u957f\uff0c\u4e0d\u65ad\u8fdb\u6b65\u3002 \u5173\u952e\u6b65\u9aa4: \u81ea\u6211\u89c9\u5bdf: \u89c2\u5bdf\u4f60\u7684\u60f3\u6cd5\u548c\u611f\u53d7\uff0c\u5e76\u4e86\u89e3\u5b83\u4eec\u662f\u5982\u4f55\u5f71\u54cd\u4f60\u7684\u884c\u4e3a\u7684\u3002 \u6311\u6218\u8d1f\u9762\u601d\u7ef4: \u5f53\u4f60\u51fa\u73b0\u8d1f\u9762\u60f3\u6cd5\u65f6\uff0c\u95ee\u4e00\u95ee\u81ea\u5df1\u8fd9\u4e9b\u60f3\u6cd5\u662f\u5426\u5408\u7406\uff0c\u5e76\u7528\u66f4\u79ef\u6781\u7684\u60f3\u6cd5\u66ff\u6362\u5b83\u4eec\u3002 \u7ec3\u4e60\u6b63\u5ff5: \u6bcf\u5929\u82b1\u4e00\u4e9b\u65f6\u95f4\u7ec3\u4e60\u6b63\u5ff5\uff0c\u4f8b\u5982\u51a5\u60f3\u6216\u745c\u4f3d\u3002 \u611f\u6069\u7ec3\u4e60: \u5199\u611f\u6069\u65e5\u8bb0\uff0c\u6216\u8005\u5b9a\u671f\u5217\u51fa\u4f60\u6240\u611f\u6fc0\u7684\u4e8b\u60c5\u3002 \u4fdd\u6301\u6210\u957f\u578b\u601d\u7ef4: \u9047\u5230\u6311\u6218\u65f6\uff0c\u4e0d\u8981\u8f7b\u6613\u653e\u5f03\uff0c\u76f8\u4fe1\u81ea\u5df1\u53ef\u4ee5\u901a\u8fc7\u52aa\u529b\u514b\u670d\u56f0\u96be\u3002 \u603b\u7ed3: \u62e5\u6709\u79ef\u6781\u4e50\u89c2\u7684\u5fc3\u6001\uff0c\u53ef\u4ee5\u5e2e\u52a9\u8f6f\u4ef6\u5f00\u53d1\u4eba\u5458\u5728\u804c\u4e1a\u53d1\u5c55\u4e2d\u53d6\u5f97\u66f4\u5927\u7684\u6210\u5c31\u3002\u901a\u8fc7\u7ec3\u4e60\u548c\u81ea\u6211\u89c9\u5bdf\uff0c\u53ef\u4ee5\u57f9\u517b\u79ef\u6781\u4e50\u89c2\u7684\u5fc3\u6001\uff0c\u5e76\u514b\u670d\u56f0\u96be\uff0c\u53d6\u5f97\u6210\u529f\u3002 \u4ee5\u4e0b\u662f\u4e00\u4e9b\u5177\u4f53\u7684\u5efa\u8bae: \u9605\u8bfb\u52b1\u5fd7\u4e66\u7c4d\u548c\u6587\u7ae0\u3002 \u79ef\u6781\u7684\u4e66\u7c4d\u548c\u6587\u7ae0\u53ef\u4ee5\u5e2e\u52a9\u4f60\u5efa\u7acb\u79ef\u6781\u7684\u601d\u7ef4\u6a21\u5f0f\u3002 \u4e0e\u79ef\u6781\u4e50\u89c2\u7684\u4eba\u4ea4\u670b\u53cb\u3002 \u4e0e\u79ef\u6781\u4e50\u89c2\u7684\u4eba\u5728\u4e00\u8d77\uff0c\u53ef\u4ee5\u5e2e\u52a9\u4f60\u63d0\u5347\u81ea\u5df1\u7684\u5fc3\u6001\u3002 \u5e2e\u52a9\u4ed6\u4eba\u3002 \u5e2e\u52a9\u4ed6\u4eba\u53ef\u4ee5\u8ba9\u4f60\u611f\u5230\u5feb\u4e50\u548c\u6ee1\u8db3\uff0c\u5e76\u63d0\u5347\u4f60\u7684\u81ea\u4fe1\u5fc3\u3002 \u5b66\u4f1a\u653e\u677e\u3002 \u538b\u529b\u4f1a\u9020\u6210\u8d1f\u9762\u60c5\u7eea\uff0c\u56e0\u6b64\u8981\u5b66\u4f1a\u653e\u677e\uff0c\u4f8b\u5982\u8fd0\u52a8\u3001\u51a5\u60f3\u6216\u542c\u97f3\u4e50\u3002 \u4ee5\u4e0b\u662f\u4e00\u4e9b\u989d\u5916\u7684\u8865\u5145: \u4e66\u4e2d\u8fd8\u63d0\u5230\u4e86 \u65f6\u95f4\u7ba1\u7406 \u7684\u91cd\u8981\u6027\u3002\u901a\u8fc7\u5408\u7406\u7684\u5b89\u6392\u65f6\u95f4\uff0c\u53ef\u4ee5\u907f\u514d\u538b\u529b\u548c\u7126\u8651\u3002 \u4e66\u4e2d\u4e5f\u5f3a\u8c03\u4e86 \u7761\u7720 \u7684\u91cd\u8981\u6027\u3002\u5145\u8db3\u7684\u7761\u7720\u53ef\u4ee5\u5e2e\u52a9\u4f60\u4fdd\u6301\u826f\u597d\u7684\u7cbe\u795e\u72b6\u6001\u3002","title":"\u4e03\u3001\u5fc3\u6001"},{"location":"k8s/","text":"\u6211\u7684Kubernetes\u5b66\u4e60\u5fc3\u5f97 \u00b6 \u4f5c\u4e3a\u4e00\u79cd\u5f00\u6e90\u7684\u5bb9\u5668\u7f16\u6392\u7cfb\u7edf\uff0cKubernetes \u4e3a\u8fd0\u884c\u5728\u5bb9\u5668\u4e2d\u7684\u5e94\u7528\u7a0b\u5e8f\u63d0\u4f9b\u4e86\u4e00\u79cd\u7ba1\u7406\u65b9\u5f0f\u3002Kubernetes \u5177\u6709\u5f88\u591a\u5f3a\u5927\u7684\u529f\u80fd\uff0c\u4f8b\u5982\u81ea\u52a8\u5316\u90e8\u7f72\u3001\u8d1f\u8f7d\u5747\u8861\u3001\u81ea\u52a8\u6269\u5c55\u3001\u81ea\u52a8\u6062\u590d\u7b49\u3002 \u516c\u53f8\u5185\u90e8\u7684\u4e91\u5e73\u53f0\u4e5f\u5728\u4eceCloud Foundry\u73af\u5883\u5f00\u59cb\u5411\u57fa\u4e8eKubernetes\u7684Kyma\u73af\u5883\u5ef6\u5c55\uff0c\u518d\u52a0\u4e0a\u5404\u79cd\u5a92\u4f53\u5bf9Kubernetes\u7684\u4ecb\u7ecd\uff0c\u662f\u6211\u5f00\u59cb\u4e86\u89e3Kubernetes\u7684\u5916\u90e8\u52a8\u56e0\u3002 \u5185\u90e8\u52a8\u56e0\uff0c\u5219\u662f\u6e90\u4e8e2022\u5e74\u6625\u8282\u671f\u95f4\u53c2\u52a0\u4e86\u516c\u53f8\u5185\u90e8\u7684\u4e00\u5468Kubernetes\u57fa\u7840\u57f9\u8bad\uff0c\u56e0\u4e3a\u6388\u8bfe\u5185\u5bb9\u662f\u82f1\u8bed\uff0c\u6240\u4ee5\u6709\u5f88\u591a\u7ec6\u8282\u5728\u57f9\u8bad\u4e2d\u662fget\u4e0d\u5230\u7684\uff0c\u4e3b\u8981\u8fd8\u662f\u8bed\u8a00\u80fd\u529b\u4e0d\u591f\u5f3a\u3002\u5f53\u65f6\u7684\u76ee\u6807\u53ea\u662f\u8ddf\u7740\u5b8c\u6210\u8bb2\u5e08\u8bfe\u5802\u6f14\u793a\u3002 \u4ece3\u6708\u5f00\u59cb\uff0c\u6211\u5728\u7f51\u4e0a\u4e86\u53c2\u8003\u4e86\u522b\u4eba\u7684Kubernetes\u7684\u5b66\u4e60\u5fc3\u5f97\u548c\u8def\u7ebf\u56fe\uff0c\u51b3\u5b9a\u4ee5CKA\uff08certificate of Kubernetes administration\uff09\u8ba4\u8bc1\u4f5c\u4e3a\u5f53\u524d\u5b66\u4e60\u7684\u76ee\u6807\uff0c\u5229\u7528B\u7ad9\u7684\u89c6\u9891\uff0c\u53c2\u8003\u5b98\u65b9\u6587\u6863\uff0c\u5f00\u59cb\u4ece\u5934\u5f00\u59cb\u5b66\u4e60Kubernetes\u7684\u57fa\u7840\u77e5\u8bc6\u3002 \u4e0b\u9762\u51c6\u5907CKA\u8003\u8bd5\u7684\u4e00\u4e9b\u5fc3\u5f97\u4f53\u4f1a\uff1a \u5b66\u4e60 Kubernetes \u524d\uff0c\u9700\u8981\u4e86\u89e3\u5bb9\u5668\u6280\u672f\u548c Docker\uff0c\u6216\u8005\u8bf4\u8981\u6709\u5bb9\u5668\u5316\u7684\u57fa\u672c\u6982\u5ff5\u548c\u601d\u60f3\u65b9\u6cd5\uff0c\u56e0\u4e3a Kubernetes \u662f\u57fa\u4e8e\u5bb9\u5668\u6280\u672f\u6784\u5efa\u7684\u3002 \u5b66\u4e60 Kubernetes \u65f6\uff0c\u9700\u8981\u638c\u63e1\u5176\u6838\u5fc3\u6982\u5ff5\uff0c\u4f8b\u5982 Pod\u3001ReplicaSet\u3001Deployment\u3001Service \u7b49\u3002\u8fd9\u4e9b\u6982\u5ff5\u662f\u7406\u89e3 Kubernetes \u7684\u57fa\u7840\uff0c\u4e5f\u662f\u540e\u7eed\u5b9e\u9645\u5e94\u7528\u4e2d\u7684\u91cd\u8981\u90e8\u5206\u3002 \u5b66\u4e60 Kubernetes \u65f6\uff0c\u9700\u8981\u638c\u63e1 yaml \u6587\u4ef6\u7684\u7f16\u5199\u65b9\u6cd5\uff0c\u7279\u522b\u662f\u90a3\u4e9b\u57fa\u672c\u8d44\u6e90\u7684yaml\u6587\u4ef6\uff0c\u8981\u80fd\u505a\u5230\u4e0d\u501f\u52a9\u5e2e\u52a9\u6587\u6863\u5c31\u80fd\u5199\u51fa\u6846\u67b6\uff0c\u5426\u5219\u8003\u8bd5\u65f6\u505a\u4e0d\u5b8c\u9898\u76ee\u7684\u3002 \u5b66\u4e60 Kubernetes \u65f6\uff0c\u9700\u8981\u638c\u63e1 kubectl \u547d\u4ee4\u7684\u4f7f\u7528\uff0c\u5e38\u7528\u8d44\u6e90\u76f8\u5173\u7684\u547d\u4ee4\uff0c\u4e5f\u8981\u505a\u5230\u4e0d\u501f\u52a9\u5e2e\u52a9\u6587\u6863\u5c31\u80fd\u5199\u51fa\uff0c\u5426\u5219\u8003\u8bd5\u65f6\u4e5f\u662f\u505a\u4e0d\u5b8c\u9898\u76ee\u7684\u3002 \u5b66\u4e60 Kubernetes \u65f6\uff0c\u9700\u8981\u638c\u63e1\u5176\u7f51\u7edc\u548c\u5b58\u50a8\u914d\u7f6e\uff0c\u4f8b\u5982 Service\u3001Ingress\u3001PersistentVolume\u3001PersistentVolumeClaim \u7b49\uff0c\u8fd9\u4e9b\u90fd\u662f\u8003\u8bd5\u91cd\u70b9\u5185\u5bb9\uff0c\u8981\u719f\u6089yaml\u7279\u6027\uff0c\u80fd\u6309\u4e0d\u540c\u7684\u8981\u6c42\u8fdb\u884c\u62d3\u5c55\u548c\u53d8\u66f4\u3002 \u90e8\u7f72\u548c\u7ba1\u7406 Kubernetes \u96c6\u7fa4\u4e5f\u662f\u4e00\u4e2a\u91cd\u70b9\uff0c\u6211\u662f\u5728\u963f\u91cc\u4e91\u4e0a\u4e70\u4e863\u4e2aECS\u4f5c\u4e3a\u5b9e\u9a8c\u73af\u5883\u3002 \u6211\u7684CKA\u7684\u7b14\u8bb0\u5206\u4e2d\u6587\u548c\u82f1\u6587\u4e24\u79cd\u3002\u82f1\u6587\u7b14\u8bb0\u662f\u57fa\u4e8e\u7b2c\u4e00\u6b21\u53c2\u52a0\u516c\u53f8\u57f9\u8bad\u7684\u77e5\u8bc6\u7ed3\u6784\u505a\u7684\uff0c\u5728\u5907\u8003\u8fc7\u7a0b\u4e2d\u9010\u6b65\u5b8c\u5584\u7684\u3002\u4e2d\u6587\u7b14\u8bb0\u662f\u57282023\u5e744\u6708\u4efd\u57fa\u4e8e\u82f1\u6587\u7b14\u8bb0\u81ea\u5df1\u7ffb\u8bd1\u8fc7\u6765\u7684\uff0c\u5e76\u53d1\u5e03\u5728\u6211\u7684\u77e5\u4e4e\u4e13\u680f\u4e0a\uff0c\u7ffb\u8bd1\u8fc7\u7a0b\u8fd8\u662f\u6bd4\u8f83\u96be\u7684\uff0c\u5f88\u591a\u82f1\u8bed\u5185\u5bb9\u627e\u4e0d\u5230\u5408\u9002\u7684\u4e2d\u6587\u8868\u8fbe\u65b9\u5f0f\uff0c\u4e0d\u8fc7\u5bf9\u4e8e\u8ba1\u7b97\u673a\u884c\u4e1a\u6765\u8bb2\uff0c\u4f7f\u7528\u82f1\u8bed\u9605\u8bfb\u4e13\u4e1a\u8d44\u6599\u5e94\u8be5\u662f\u4e00\u4e2a\u5171\u8bc6\u3002 \u53c2\u8003\u7b14\u8bb0\uff0c\u5e76\u5b8c\u6210\u7b14\u8bb0\u4e2d\u7684\u7ec3\u4e60\uff0c\u518d\u719f\u7ec3\u4f7f\u7528yaml\u6587\u4ef6\u548ckubectl\u547d\u4ee4\uff0c\u901a\u8fc7\u8003\u8bd5\u6ca1\u4ec0\u4e48\u56f0\u96be\u3002","title":"Index"},{"location":"k8s/#kubernetes","text":"\u4f5c\u4e3a\u4e00\u79cd\u5f00\u6e90\u7684\u5bb9\u5668\u7f16\u6392\u7cfb\u7edf\uff0cKubernetes \u4e3a\u8fd0\u884c\u5728\u5bb9\u5668\u4e2d\u7684\u5e94\u7528\u7a0b\u5e8f\u63d0\u4f9b\u4e86\u4e00\u79cd\u7ba1\u7406\u65b9\u5f0f\u3002Kubernetes \u5177\u6709\u5f88\u591a\u5f3a\u5927\u7684\u529f\u80fd\uff0c\u4f8b\u5982\u81ea\u52a8\u5316\u90e8\u7f72\u3001\u8d1f\u8f7d\u5747\u8861\u3001\u81ea\u52a8\u6269\u5c55\u3001\u81ea\u52a8\u6062\u590d\u7b49\u3002 \u516c\u53f8\u5185\u90e8\u7684\u4e91\u5e73\u53f0\u4e5f\u5728\u4eceCloud Foundry\u73af\u5883\u5f00\u59cb\u5411\u57fa\u4e8eKubernetes\u7684Kyma\u73af\u5883\u5ef6\u5c55\uff0c\u518d\u52a0\u4e0a\u5404\u79cd\u5a92\u4f53\u5bf9Kubernetes\u7684\u4ecb\u7ecd\uff0c\u662f\u6211\u5f00\u59cb\u4e86\u89e3Kubernetes\u7684\u5916\u90e8\u52a8\u56e0\u3002 \u5185\u90e8\u52a8\u56e0\uff0c\u5219\u662f\u6e90\u4e8e2022\u5e74\u6625\u8282\u671f\u95f4\u53c2\u52a0\u4e86\u516c\u53f8\u5185\u90e8\u7684\u4e00\u5468Kubernetes\u57fa\u7840\u57f9\u8bad\uff0c\u56e0\u4e3a\u6388\u8bfe\u5185\u5bb9\u662f\u82f1\u8bed\uff0c\u6240\u4ee5\u6709\u5f88\u591a\u7ec6\u8282\u5728\u57f9\u8bad\u4e2d\u662fget\u4e0d\u5230\u7684\uff0c\u4e3b\u8981\u8fd8\u662f\u8bed\u8a00\u80fd\u529b\u4e0d\u591f\u5f3a\u3002\u5f53\u65f6\u7684\u76ee\u6807\u53ea\u662f\u8ddf\u7740\u5b8c\u6210\u8bb2\u5e08\u8bfe\u5802\u6f14\u793a\u3002 \u4ece3\u6708\u5f00\u59cb\uff0c\u6211\u5728\u7f51\u4e0a\u4e86\u53c2\u8003\u4e86\u522b\u4eba\u7684Kubernetes\u7684\u5b66\u4e60\u5fc3\u5f97\u548c\u8def\u7ebf\u56fe\uff0c\u51b3\u5b9a\u4ee5CKA\uff08certificate of Kubernetes administration\uff09\u8ba4\u8bc1\u4f5c\u4e3a\u5f53\u524d\u5b66\u4e60\u7684\u76ee\u6807\uff0c\u5229\u7528B\u7ad9\u7684\u89c6\u9891\uff0c\u53c2\u8003\u5b98\u65b9\u6587\u6863\uff0c\u5f00\u59cb\u4ece\u5934\u5f00\u59cb\u5b66\u4e60Kubernetes\u7684\u57fa\u7840\u77e5\u8bc6\u3002 \u4e0b\u9762\u51c6\u5907CKA\u8003\u8bd5\u7684\u4e00\u4e9b\u5fc3\u5f97\u4f53\u4f1a\uff1a \u5b66\u4e60 Kubernetes \u524d\uff0c\u9700\u8981\u4e86\u89e3\u5bb9\u5668\u6280\u672f\u548c Docker\uff0c\u6216\u8005\u8bf4\u8981\u6709\u5bb9\u5668\u5316\u7684\u57fa\u672c\u6982\u5ff5\u548c\u601d\u60f3\u65b9\u6cd5\uff0c\u56e0\u4e3a Kubernetes \u662f\u57fa\u4e8e\u5bb9\u5668\u6280\u672f\u6784\u5efa\u7684\u3002 \u5b66\u4e60 Kubernetes \u65f6\uff0c\u9700\u8981\u638c\u63e1\u5176\u6838\u5fc3\u6982\u5ff5\uff0c\u4f8b\u5982 Pod\u3001ReplicaSet\u3001Deployment\u3001Service \u7b49\u3002\u8fd9\u4e9b\u6982\u5ff5\u662f\u7406\u89e3 Kubernetes \u7684\u57fa\u7840\uff0c\u4e5f\u662f\u540e\u7eed\u5b9e\u9645\u5e94\u7528\u4e2d\u7684\u91cd\u8981\u90e8\u5206\u3002 \u5b66\u4e60 Kubernetes \u65f6\uff0c\u9700\u8981\u638c\u63e1 yaml \u6587\u4ef6\u7684\u7f16\u5199\u65b9\u6cd5\uff0c\u7279\u522b\u662f\u90a3\u4e9b\u57fa\u672c\u8d44\u6e90\u7684yaml\u6587\u4ef6\uff0c\u8981\u80fd\u505a\u5230\u4e0d\u501f\u52a9\u5e2e\u52a9\u6587\u6863\u5c31\u80fd\u5199\u51fa\u6846\u67b6\uff0c\u5426\u5219\u8003\u8bd5\u65f6\u505a\u4e0d\u5b8c\u9898\u76ee\u7684\u3002 \u5b66\u4e60 Kubernetes \u65f6\uff0c\u9700\u8981\u638c\u63e1 kubectl \u547d\u4ee4\u7684\u4f7f\u7528\uff0c\u5e38\u7528\u8d44\u6e90\u76f8\u5173\u7684\u547d\u4ee4\uff0c\u4e5f\u8981\u505a\u5230\u4e0d\u501f\u52a9\u5e2e\u52a9\u6587\u6863\u5c31\u80fd\u5199\u51fa\uff0c\u5426\u5219\u8003\u8bd5\u65f6\u4e5f\u662f\u505a\u4e0d\u5b8c\u9898\u76ee\u7684\u3002 \u5b66\u4e60 Kubernetes \u65f6\uff0c\u9700\u8981\u638c\u63e1\u5176\u7f51\u7edc\u548c\u5b58\u50a8\u914d\u7f6e\uff0c\u4f8b\u5982 Service\u3001Ingress\u3001PersistentVolume\u3001PersistentVolumeClaim \u7b49\uff0c\u8fd9\u4e9b\u90fd\u662f\u8003\u8bd5\u91cd\u70b9\u5185\u5bb9\uff0c\u8981\u719f\u6089yaml\u7279\u6027\uff0c\u80fd\u6309\u4e0d\u540c\u7684\u8981\u6c42\u8fdb\u884c\u62d3\u5c55\u548c\u53d8\u66f4\u3002 \u90e8\u7f72\u548c\u7ba1\u7406 Kubernetes \u96c6\u7fa4\u4e5f\u662f\u4e00\u4e2a\u91cd\u70b9\uff0c\u6211\u662f\u5728\u963f\u91cc\u4e91\u4e0a\u4e70\u4e863\u4e2aECS\u4f5c\u4e3a\u5b9e\u9a8c\u73af\u5883\u3002 \u6211\u7684CKA\u7684\u7b14\u8bb0\u5206\u4e2d\u6587\u548c\u82f1\u6587\u4e24\u79cd\u3002\u82f1\u6587\u7b14\u8bb0\u662f\u57fa\u4e8e\u7b2c\u4e00\u6b21\u53c2\u52a0\u516c\u53f8\u57f9\u8bad\u7684\u77e5\u8bc6\u7ed3\u6784\u505a\u7684\uff0c\u5728\u5907\u8003\u8fc7\u7a0b\u4e2d\u9010\u6b65\u5b8c\u5584\u7684\u3002\u4e2d\u6587\u7b14\u8bb0\u662f\u57282023\u5e744\u6708\u4efd\u57fa\u4e8e\u82f1\u6587\u7b14\u8bb0\u81ea\u5df1\u7ffb\u8bd1\u8fc7\u6765\u7684\uff0c\u5e76\u53d1\u5e03\u5728\u6211\u7684\u77e5\u4e4e\u4e13\u680f\u4e0a\uff0c\u7ffb\u8bd1\u8fc7\u7a0b\u8fd8\u662f\u6bd4\u8f83\u96be\u7684\uff0c\u5f88\u591a\u82f1\u8bed\u5185\u5bb9\u627e\u4e0d\u5230\u5408\u9002\u7684\u4e2d\u6587\u8868\u8fbe\u65b9\u5f0f\uff0c\u4e0d\u8fc7\u5bf9\u4e8e\u8ba1\u7b97\u673a\u884c\u4e1a\u6765\u8bb2\uff0c\u4f7f\u7528\u82f1\u8bed\u9605\u8bfb\u4e13\u4e1a\u8d44\u6599\u5e94\u8be5\u662f\u4e00\u4e2a\u5171\u8bc6\u3002 \u53c2\u8003\u7b14\u8bb0\uff0c\u5e76\u5b8c\u6210\u7b14\u8bb0\u4e2d\u7684\u7ec3\u4e60\uff0c\u518d\u719f\u7ec3\u4f7f\u7528yaml\u6587\u4ef6\u548ckubectl\u547d\u4ee4\uff0c\u901a\u8fc7\u8003\u8bd5\u6ca1\u4ec0\u4e48\u56f0\u96be\u3002","title":"\u6211\u7684Kubernetes\u5b66\u4e60\u5fc3\u5f97"},{"location":"k8s/cka_cn/foundamentals/basics/","text":"CKA\u81ea\u5b66\u7b14\u8bb07:kubectl\u57fa\u7840 \u00b6 \u6458\u8981 \u00b6 \u4e86\u89e3\u5982\u4f55\u4f7f\u7528 kubectl \u64cd\u4f5cKubernetes\u96c6\u7fa4\u3002 via API via kubectl via Dashboard \u68c0\u67e5\u5f53\u524dkubeconfig\u6587\u4ef6\u914d\u7f6e \u00b6 \u901a\u8fc7\u547d\u4ee4 kubectl config \u68c0\u67e5\u5f53\u524d\u914d\u7f6e\u6587\u4ef6\u4e2d\u7684\u4e0a\u4e0b\u6587\u3002 echo $KUBECONFIG kubectl config view kubectl config get-contexts \u83b7\u53d6\u8d44\u6e90\u6e05\u5355 \u00b6 \u8bfb\u53d6\u6240\u6709\u652f\u6301\u7684\u8d44\u6e90\u6e05\u5355\u3002 kubectl api-resources \u83b7\u53d6\u96c6\u7fa4\u72b6\u6001 \u00b6 Kubernetes \u63a7\u5236\u9762\u677f\u8fd0\u884c\u5728 https://:6443 \u3002 CoreDNS \u8fd0\u884c\u5728 https://:6443/api/v1/namespaces/kube-system/services/kube-dns:dns/proxy \u3002 kubectl cluster-info kubectl cluster-info dump \u8bfb\u53d6\u5f53\u524d\u8d44\u6e90 \u00b6 \u6267\u884c\u547d\u4ee4 kubectl get --help \u53ef\u4ee5\u5f97\u5230get\u547d\u4ee4\u7684\u793a\u4f8b\u548c\u4f7f\u7528\u65b9\u6cd5\u3002 \u8bfb\u53d6\u5f53\u524d\u63a7\u5236\u9762\u677f\u7684\u5065\u5eb7\u72b6\u6001\u3002 kubectl get componentstatuses kubectl get cs \u8fd0\u884c\u7ed3\u679c\uff1a NAME STATUS MESSAGE ERROR etcd-0 Healthy {\"health\":\"true\",\"reason\":\"\"} scheduler Healthy ok controller-manager Healthy ok \u8bfb\u53d6\u8282\u70b9\u72b6\u6001\u548c\u4fe1\u606f \u00b6 kubectl get nodes kubectl get nodes -o wide kubectl describe node cka001 \u53ef\u4ee5\u901a\u8fc7\u547d\u4ee4 kubectl create --help \u6765\u83b7\u53d6get\u547d\u4ee4\u7684\u5e2e\u52a9\u548c\u793a\u4f8b\u3002 \u521b\u5efaNamespace \u00b6 kubectl create namespace --help kubectl create namespace my-namespace \u63d0\u793a\uff1a \u547d\u540d\u7a7a\u95f4Namespace\u662f\u4e00\u4e2a\u96c6\u7fa4\uff0c\u5305\u542b\u4e86\u670d\u52a1\u3002\u670d\u52a1\u53ef\u80fd\u5728\u4e00\u4e2a\u8282\u70b9\u4e0a\uff0c\u4e5f\u53ef\u80fd\u4e0d\u5728\u3002 Namespace\u662f\u4e00\u79cd\u7528\u6765\u7ec4\u7ec7\u670d\u52a1\u7684\u65b9\u5f0f\uff0c\u5b83\u53ef\u4ee5\u5bf9\u670d\u52a1\u8fdb\u884c\u9694\u79bb\u548c\u5212\u5206\u3002 \u4e0d\u540c\u7684Namespace\u4e0b\uff0c\u53ef\u4ee5\u5b58\u5728\u76f8\u540c\u7684\u670d\u52a1\u540d\uff0c\u4f46\u662f\u4e0d\u540c\u7684Namespace\u4e4b\u95f4\u7684\u670d\u52a1\u4e0d\u80fd\u76f4\u63a5\u901a\u4fe1\uff0c\u9700\u8981\u901a\u8fc7Service\u6216Ingress\u6765\u66b4\u9732\u3002 \u670d\u52a1\u662f\u4e00\u79cd\u63d0\u4f9b\u529f\u80fd\u7684\u5b9e\u4f53 \u8282\u70b9\u662f\u4e00\u79cd\u8fd0\u884c\u670d\u52a1\u7684\u7269\u7406\u6216\u865a\u62df\u673a\u5668 \u521b\u5efadeployment \u00b6 \u5728\u67d0\u4e2aNamespace\u4e2d\u521b\u5efaDeployment\u3002 kubectl -n my-namespace create deployment my-busybox \\ --image = busybox \\ --replicas = 3 \\ --port = 5701 \u521b\u5efaClusterRole \u00b6 kubectl create clusterrole --help kubectl create clusterrole pod-creater \\ -n my-namespace \\ --verb = create \\ --resource = deployment \\ --resource-name = my-busybox \u521b\u5efaServiceAccount \u00b6 kubectl create serviceaccount --help kubectl -n my-namespace create serviceaccount my-service-account \u521b\u5efaRoleBinding \u00b6 RoleBinding \u53ef\u4ee5\u5f15\u7528\u540c\u4e00\u547d\u540d\u7a7a\u95f4\u4e2d\u7684\u4e00\u4e2aRole\uff0c\u6216\u8005\u5168\u5c40\u547d\u540d\u7a7a\u95f4\u4e2d\u7684\u4e00\u4e2aClusterRole\u3002 RoleBinding \u662f\u4e00\u79cd\u7528\u6765\u6388\u6743\u89d2\u8272\u7684\u8d44\u6e90\u3002 Role\u662f\u4e00\u79cd\u5b9a\u4e49\u6743\u9650\u7684\u8d44\u6e90\uff0c\u53ea\u80fd\u5728\u540c\u4e00\u547d\u540d\u7a7a\u95f4\u5185\u751f\u6548\u3002 ClusterRole\u662f\u4e00\u79cd\u5b9a\u4e49\u6743\u9650\u7684\u8d44\u6e90\uff0c\u53ef\u4ee5\u5728\u6574\u4e2a\u96c6\u7fa4\u5185\u751f\u6548\u3002 kubectl create rolebinding --help kubectl create rolebinding NAME \\ --clusterrole = NAME | --role = NAME \\ [ --user = username ] \\ [ --group = groupname ] \\ [ --serviceaccount = namespace:serviceaccountname ] \\ [ --dry-run = server | client | none ] kubectl create rolebinding my-admin \\ --clusterrole = pod-creater \\ --serviceaccount = my-namespace:my-service-account \u4f7f\u7528proxy \u00b6 \u6211\u4eec\u53ef\u4ee5\u4f7f\u7528 kubectl proxy \u547d\u4ee4\u6765\u6253\u5f00\u4e00\u4e2a\u5230API\u670d\u52a1\u5668\u7684\u96a7\u9053\uff08tunnel\uff09\uff0c\u5e76\u4f7f\u5b83\u5728\u672c\u5730\u53ef\u7528 - \u901a\u5e38\u662f\u5728 localhost:8001 / 127.0.0.1:8001 \u3002\u5f53\u6211\u60f3\u8981\u4f7f\u7528API\u65f6\uff0c\u6700\u7b80\u5355\u7684\u65b9\u6cd5\u5c31\u662f\u83b7\u53d6\u8bbf\u95ee\u6743\u9650\u3002 \u8fd0\u884c\u547d\u4ee4 kubectl proxy & \u5e76\u5728\u6d4f\u89c8\u5668\u4e2d\u6253\u5f00 http://localhost:8001/api/v1 \u3002 \u53ea\u6253\u5f00 http://localhost:8001 \u4f1a\u8fd4\u56de\u9519\u8bef\uff0c\u56e0\u4e3a\u6211\u4eec\u53ea\u80fd\u8bbf\u95eeAPI\u7684\u67d0\u4e9b\u5185\u5bb9\uff0c\u56e0\u6b64API\u8def\u5f84\u5f88\u91cd\u8981\u3002 \u8981\u70b9\u662f\uff1a kubectl proxy \u547d\u4ee4\u53ef\u4ee5\u521b\u5efa\u4e00\u4e2a\u672c\u5730\u4ee3\u7406\uff0c\u8ba9\u6211\u4eec\u53ef\u4ee5\u8bbf\u95eeAPI\u670d\u52a1\u5668\u3002 API\u670d\u52a1\u5668\u63d0\u4f9b\u4e86\u96c6\u7fa4\u7684\u5404\u79cd\u4fe1\u606f\u548c\u64cd\u4f5c\u3002 \u6211\u4eec\u9700\u8981\u6307\u5b9a\u6b63\u786e\u7684API\u8def\u5f84\uff0c\u624d\u80fd\u8bbf\u95ee\u6211\u4eec\u60f3\u8981\u7684\u8d44\u6e90\u3002 kubectl proxy & \u8f93\u51fa\u7ed3\u679c\uff1a [1] 102358 Starting to serve on 127.0.0.1:8001 \u6bd4\u5982\uff1a http://127.0.0.1:8001/ http://127.0.0.1:8001/api/v1 http://127.0.0.1:8001/api/v1/namespaces http://127.0.0.1:8001/api/v1/namespaces/default http://127.0.0.1:8001/api/v1/namespaces/sock-shop/pods \u4f5c\u4e3a\u5e94\u7528\u7a0b\u5e8f\u8bbf\u95ee \u00b6 \u5982\u679c\u6211\u4eec\u4f5c\u4e3a\u5e94\u7528\u7a0b\u5e8f\u800c\u4e0d\u662f\u7ba1\u7406\u5458\u6765\u8bbf\u95eekubernetes\uff0c\u5c31\u4e0d\u80fd\u4f7f\u7528 kubectl \uff0c\u53ef\u4ee5\u7528 curl \u7a0b\u5e8f\u6765\u4ee3\u66ff kubectl \u3002 \u6211\u4eec\u5fc5\u987b\u5411\u96c6\u7fa4\u53d1\u9001HTTP\u8bf7\u6c42\uff0c\u8be2\u95ee\u53ef\u7528\u7684\u8282\u70b9\u3002 \u786e\u4fdd kubectl proxy \u6b63\u5728\u8fd0\u884c\uff0c\u5e76\u5728 http://localhost:8001/ \u4e0a\u63d0\u4f9b\u670d\u52a1\u3002 \u6267\u884c\u4e0b\u9762\u7684\u547d\u4ee4\u65f6\u52a0\u4e0a\u4e00\u4e2a -v=9 \u7684\u6807\u5fd7\uff0c\u5b83\u4f1a\u663e\u793a\u6240\u6709\u9700\u8981\u7684\u4fe1\u606f\u3002 \u8981\u70b9\uff1a \u8bbf\u95ee\uff08access\uff09\u662f\u4e00\u79cd\u83b7\u53d6\u8d44\u6e90\u6216\u670d\u52a1\u7684\u884c\u4e3a\u3002 \u5e94\u7528\u7a0b\u5e8f\uff08application\uff09\u662f\u4e00\u79cd\u6267\u884c\u7279\u5b9a\u529f\u80fd\u7684\u8f6f\u4ef6\u3002 \u4f5c\u4e3a\u5e94\u7528\u7a0b\u5e8f\u8bbf\u95ee\u610f\u5473\u7740\u4f7f\u7528\u5e94\u7528\u7a0b\u5e8f\u7684\u8eab\u4efd\u6216\u51ed\u8bc1\u6765\u8bbf\u95ee\u3002 kubernetes\u662f\u4e00\u79cd\u7ba1\u7406\u5bb9\u5668\u5316\u5e94\u7528\u7a0b\u5e8f\u7684\u5e73\u53f0\u3002 kubectl \u662f\u4e00\u79cd\u7528\u6765\u548ckubernetes\u4ea4\u4e92\u7684\u547d\u4ee4\u884c\u5de5\u5177\u3002 curl \u662f\u4e00\u79cd\u7528\u6765\u53d1\u9001HTTP\u8bf7\u6c42\u7684\u547d\u4ee4\u884c\u5de5\u5177\u3002 kubectl proxy \u53ef\u4ee5\u521b\u5efa\u4e00\u4e2a\u672c\u5730\u4ee3\u7406\uff0c\u8ba9\u6211\u4eec\u53ef\u4ee5\u8bbf\u95eekubernetes\u7684API\u670d\u52a1\u5668\u3002 -v=9 \u662f\u4e00\u79cd\u7528\u6765\u663e\u793a\u8be6\u7ec6\u4fe1\u606f\u7684\u9009\u9879\u3002 kubectl get nodes \u5728\u4e0a\u9762\u547d\u4ee4\u7684\u8f93\u51fa\u7ed3\u679c\u4e2d\uff0c\u6211\u4eec\u53ef\u4ee5\u627e\u5230\u5bf9\u5e94\u7684curl\u8bf7\u6c42\u4fe1\u606f\u3002 curl -v -XGET \\ -H \"Accept: application/json;as=Table;v=v1;g=meta.k8s.io,application/json;as=Table;v=v1beta1;g=meta.k8s.io,application/json\" \\ -H \"User-Agent: kubectl/v1.24.1 (linux/amd64) kubernetes/3ddd0f4\" \\ 'https:///api/v1/nodes?limit=500' \u53c2\u8003\u4fe1\u606f\uff1a forum-like page \u662f\u6709K8s\u8fd0\u8425\u7684\u5e73\u53f0\uff0c\u63d0\u4f9b\u4e86\u5f88\u591a\u5173\u4e8e\u5982\u4f55\u4f7f\u7528 kubectl \u7684\u8be6\u7ec6\u4fe1\u606f\u548c\u4f8b\u5b50\u3002 Manage multiple clusters and multiple config files kubectl command documentation Shell autocompletion kubectl cheat sheet jsonpath in kubectl kubectl","title":"kubectl\u57fa\u7840"},{"location":"k8s/cka_cn/foundamentals/basics/#cka7kubectl","text":"","title":"CKA\u81ea\u5b66\u7b14\u8bb07:kubectl\u57fa\u7840"},{"location":"k8s/cka_cn/foundamentals/basics/#_1","text":"\u4e86\u89e3\u5982\u4f55\u4f7f\u7528 kubectl \u64cd\u4f5cKubernetes\u96c6\u7fa4\u3002 via API via kubectl via Dashboard","title":"\u6458\u8981"},{"location":"k8s/cka_cn/foundamentals/basics/#kubeconfig","text":"\u901a\u8fc7\u547d\u4ee4 kubectl config \u68c0\u67e5\u5f53\u524d\u914d\u7f6e\u6587\u4ef6\u4e2d\u7684\u4e0a\u4e0b\u6587\u3002 echo $KUBECONFIG kubectl config view kubectl config get-contexts","title":"\u68c0\u67e5\u5f53\u524dkubeconfig\u6587\u4ef6\u914d\u7f6e"},{"location":"k8s/cka_cn/foundamentals/basics/#_2","text":"\u8bfb\u53d6\u6240\u6709\u652f\u6301\u7684\u8d44\u6e90\u6e05\u5355\u3002 kubectl api-resources","title":"\u83b7\u53d6\u8d44\u6e90\u6e05\u5355"},{"location":"k8s/cka_cn/foundamentals/basics/#_3","text":"Kubernetes \u63a7\u5236\u9762\u677f\u8fd0\u884c\u5728 https://:6443 \u3002 CoreDNS \u8fd0\u884c\u5728 https://:6443/api/v1/namespaces/kube-system/services/kube-dns:dns/proxy \u3002 kubectl cluster-info kubectl cluster-info dump","title":"\u83b7\u53d6\u96c6\u7fa4\u72b6\u6001"},{"location":"k8s/cka_cn/foundamentals/basics/#_4","text":"\u6267\u884c\u547d\u4ee4 kubectl get --help \u53ef\u4ee5\u5f97\u5230get\u547d\u4ee4\u7684\u793a\u4f8b\u548c\u4f7f\u7528\u65b9\u6cd5\u3002 \u8bfb\u53d6\u5f53\u524d\u63a7\u5236\u9762\u677f\u7684\u5065\u5eb7\u72b6\u6001\u3002 kubectl get componentstatuses kubectl get cs \u8fd0\u884c\u7ed3\u679c\uff1a NAME STATUS MESSAGE ERROR etcd-0 Healthy {\"health\":\"true\",\"reason\":\"\"} scheduler Healthy ok controller-manager Healthy ok","title":"\u8bfb\u53d6\u5f53\u524d\u8d44\u6e90"},{"location":"k8s/cka_cn/foundamentals/basics/#_5","text":"kubectl get nodes kubectl get nodes -o wide kubectl describe node cka001 \u53ef\u4ee5\u901a\u8fc7\u547d\u4ee4 kubectl create --help \u6765\u83b7\u53d6get\u547d\u4ee4\u7684\u5e2e\u52a9\u548c\u793a\u4f8b\u3002","title":"\u8bfb\u53d6\u8282\u70b9\u72b6\u6001\u548c\u4fe1\u606f"},{"location":"k8s/cka_cn/foundamentals/basics/#namespace","text":"kubectl create namespace --help kubectl create namespace my-namespace \u63d0\u793a\uff1a \u547d\u540d\u7a7a\u95f4Namespace\u662f\u4e00\u4e2a\u96c6\u7fa4\uff0c\u5305\u542b\u4e86\u670d\u52a1\u3002\u670d\u52a1\u53ef\u80fd\u5728\u4e00\u4e2a\u8282\u70b9\u4e0a\uff0c\u4e5f\u53ef\u80fd\u4e0d\u5728\u3002 Namespace\u662f\u4e00\u79cd\u7528\u6765\u7ec4\u7ec7\u670d\u52a1\u7684\u65b9\u5f0f\uff0c\u5b83\u53ef\u4ee5\u5bf9\u670d\u52a1\u8fdb\u884c\u9694\u79bb\u548c\u5212\u5206\u3002 \u4e0d\u540c\u7684Namespace\u4e0b\uff0c\u53ef\u4ee5\u5b58\u5728\u76f8\u540c\u7684\u670d\u52a1\u540d\uff0c\u4f46\u662f\u4e0d\u540c\u7684Namespace\u4e4b\u95f4\u7684\u670d\u52a1\u4e0d\u80fd\u76f4\u63a5\u901a\u4fe1\uff0c\u9700\u8981\u901a\u8fc7Service\u6216Ingress\u6765\u66b4\u9732\u3002 \u670d\u52a1\u662f\u4e00\u79cd\u63d0\u4f9b\u529f\u80fd\u7684\u5b9e\u4f53 \u8282\u70b9\u662f\u4e00\u79cd\u8fd0\u884c\u670d\u52a1\u7684\u7269\u7406\u6216\u865a\u62df\u673a\u5668","title":"\u521b\u5efaNamespace"},{"location":"k8s/cka_cn/foundamentals/basics/#deployment","text":"\u5728\u67d0\u4e2aNamespace\u4e2d\u521b\u5efaDeployment\u3002 kubectl -n my-namespace create deployment my-busybox \\ --image = busybox \\ --replicas = 3 \\ --port = 5701","title":"\u521b\u5efadeployment"},{"location":"k8s/cka_cn/foundamentals/basics/#clusterrole","text":"kubectl create clusterrole --help kubectl create clusterrole pod-creater \\ -n my-namespace \\ --verb = create \\ --resource = deployment \\ --resource-name = my-busybox","title":"\u521b\u5efaClusterRole"},{"location":"k8s/cka_cn/foundamentals/basics/#serviceaccount","text":"kubectl create serviceaccount --help kubectl -n my-namespace create serviceaccount my-service-account","title":"\u521b\u5efaServiceAccount"},{"location":"k8s/cka_cn/foundamentals/basics/#rolebinding","text":"RoleBinding \u53ef\u4ee5\u5f15\u7528\u540c\u4e00\u547d\u540d\u7a7a\u95f4\u4e2d\u7684\u4e00\u4e2aRole\uff0c\u6216\u8005\u5168\u5c40\u547d\u540d\u7a7a\u95f4\u4e2d\u7684\u4e00\u4e2aClusterRole\u3002 RoleBinding \u662f\u4e00\u79cd\u7528\u6765\u6388\u6743\u89d2\u8272\u7684\u8d44\u6e90\u3002 Role\u662f\u4e00\u79cd\u5b9a\u4e49\u6743\u9650\u7684\u8d44\u6e90\uff0c\u53ea\u80fd\u5728\u540c\u4e00\u547d\u540d\u7a7a\u95f4\u5185\u751f\u6548\u3002 ClusterRole\u662f\u4e00\u79cd\u5b9a\u4e49\u6743\u9650\u7684\u8d44\u6e90\uff0c\u53ef\u4ee5\u5728\u6574\u4e2a\u96c6\u7fa4\u5185\u751f\u6548\u3002 kubectl create rolebinding --help kubectl create rolebinding NAME \\ --clusterrole = NAME | --role = NAME \\ [ --user = username ] \\ [ --group = groupname ] \\ [ --serviceaccount = namespace:serviceaccountname ] \\ [ --dry-run = server | client | none ] kubectl create rolebinding my-admin \\ --clusterrole = pod-creater \\ --serviceaccount = my-namespace:my-service-account","title":"\u521b\u5efaRoleBinding"},{"location":"k8s/cka_cn/foundamentals/basics/#proxy","text":"\u6211\u4eec\u53ef\u4ee5\u4f7f\u7528 kubectl proxy \u547d\u4ee4\u6765\u6253\u5f00\u4e00\u4e2a\u5230API\u670d\u52a1\u5668\u7684\u96a7\u9053\uff08tunnel\uff09\uff0c\u5e76\u4f7f\u5b83\u5728\u672c\u5730\u53ef\u7528 - \u901a\u5e38\u662f\u5728 localhost:8001 / 127.0.0.1:8001 \u3002\u5f53\u6211\u60f3\u8981\u4f7f\u7528API\u65f6\uff0c\u6700\u7b80\u5355\u7684\u65b9\u6cd5\u5c31\u662f\u83b7\u53d6\u8bbf\u95ee\u6743\u9650\u3002 \u8fd0\u884c\u547d\u4ee4 kubectl proxy & \u5e76\u5728\u6d4f\u89c8\u5668\u4e2d\u6253\u5f00 http://localhost:8001/api/v1 \u3002 \u53ea\u6253\u5f00 http://localhost:8001 \u4f1a\u8fd4\u56de\u9519\u8bef\uff0c\u56e0\u4e3a\u6211\u4eec\u53ea\u80fd\u8bbf\u95eeAPI\u7684\u67d0\u4e9b\u5185\u5bb9\uff0c\u56e0\u6b64API\u8def\u5f84\u5f88\u91cd\u8981\u3002 \u8981\u70b9\u662f\uff1a kubectl proxy \u547d\u4ee4\u53ef\u4ee5\u521b\u5efa\u4e00\u4e2a\u672c\u5730\u4ee3\u7406\uff0c\u8ba9\u6211\u4eec\u53ef\u4ee5\u8bbf\u95eeAPI\u670d\u52a1\u5668\u3002 API\u670d\u52a1\u5668\u63d0\u4f9b\u4e86\u96c6\u7fa4\u7684\u5404\u79cd\u4fe1\u606f\u548c\u64cd\u4f5c\u3002 \u6211\u4eec\u9700\u8981\u6307\u5b9a\u6b63\u786e\u7684API\u8def\u5f84\uff0c\u624d\u80fd\u8bbf\u95ee\u6211\u4eec\u60f3\u8981\u7684\u8d44\u6e90\u3002 kubectl proxy & \u8f93\u51fa\u7ed3\u679c\uff1a [1] 102358 Starting to serve on 127.0.0.1:8001 \u6bd4\u5982\uff1a http://127.0.0.1:8001/ http://127.0.0.1:8001/api/v1 http://127.0.0.1:8001/api/v1/namespaces http://127.0.0.1:8001/api/v1/namespaces/default http://127.0.0.1:8001/api/v1/namespaces/sock-shop/pods","title":"\u4f7f\u7528proxy"},{"location":"k8s/cka_cn/foundamentals/basics/#_6","text":"\u5982\u679c\u6211\u4eec\u4f5c\u4e3a\u5e94\u7528\u7a0b\u5e8f\u800c\u4e0d\u662f\u7ba1\u7406\u5458\u6765\u8bbf\u95eekubernetes\uff0c\u5c31\u4e0d\u80fd\u4f7f\u7528 kubectl \uff0c\u53ef\u4ee5\u7528 curl \u7a0b\u5e8f\u6765\u4ee3\u66ff kubectl \u3002 \u6211\u4eec\u5fc5\u987b\u5411\u96c6\u7fa4\u53d1\u9001HTTP\u8bf7\u6c42\uff0c\u8be2\u95ee\u53ef\u7528\u7684\u8282\u70b9\u3002 \u786e\u4fdd kubectl proxy \u6b63\u5728\u8fd0\u884c\uff0c\u5e76\u5728 http://localhost:8001/ \u4e0a\u63d0\u4f9b\u670d\u52a1\u3002 \u6267\u884c\u4e0b\u9762\u7684\u547d\u4ee4\u65f6\u52a0\u4e0a\u4e00\u4e2a -v=9 \u7684\u6807\u5fd7\uff0c\u5b83\u4f1a\u663e\u793a\u6240\u6709\u9700\u8981\u7684\u4fe1\u606f\u3002 \u8981\u70b9\uff1a \u8bbf\u95ee\uff08access\uff09\u662f\u4e00\u79cd\u83b7\u53d6\u8d44\u6e90\u6216\u670d\u52a1\u7684\u884c\u4e3a\u3002 \u5e94\u7528\u7a0b\u5e8f\uff08application\uff09\u662f\u4e00\u79cd\u6267\u884c\u7279\u5b9a\u529f\u80fd\u7684\u8f6f\u4ef6\u3002 \u4f5c\u4e3a\u5e94\u7528\u7a0b\u5e8f\u8bbf\u95ee\u610f\u5473\u7740\u4f7f\u7528\u5e94\u7528\u7a0b\u5e8f\u7684\u8eab\u4efd\u6216\u51ed\u8bc1\u6765\u8bbf\u95ee\u3002 kubernetes\u662f\u4e00\u79cd\u7ba1\u7406\u5bb9\u5668\u5316\u5e94\u7528\u7a0b\u5e8f\u7684\u5e73\u53f0\u3002 kubectl \u662f\u4e00\u79cd\u7528\u6765\u548ckubernetes\u4ea4\u4e92\u7684\u547d\u4ee4\u884c\u5de5\u5177\u3002 curl \u662f\u4e00\u79cd\u7528\u6765\u53d1\u9001HTTP\u8bf7\u6c42\u7684\u547d\u4ee4\u884c\u5de5\u5177\u3002 kubectl proxy \u53ef\u4ee5\u521b\u5efa\u4e00\u4e2a\u672c\u5730\u4ee3\u7406\uff0c\u8ba9\u6211\u4eec\u53ef\u4ee5\u8bbf\u95eekubernetes\u7684API\u670d\u52a1\u5668\u3002 -v=9 \u662f\u4e00\u79cd\u7528\u6765\u663e\u793a\u8be6\u7ec6\u4fe1\u606f\u7684\u9009\u9879\u3002 kubectl get nodes \u5728\u4e0a\u9762\u547d\u4ee4\u7684\u8f93\u51fa\u7ed3\u679c\u4e2d\uff0c\u6211\u4eec\u53ef\u4ee5\u627e\u5230\u5bf9\u5e94\u7684curl\u8bf7\u6c42\u4fe1\u606f\u3002 curl -v -XGET \\ -H \"Accept: application/json;as=Table;v=v1;g=meta.k8s.io,application/json;as=Table;v=v1beta1;g=meta.k8s.io,application/json\" \\ -H \"User-Agent: kubectl/v1.24.1 (linux/amd64) kubernetes/3ddd0f4\" \\ 'https:///api/v1/nodes?limit=500' \u53c2\u8003\u4fe1\u606f\uff1a forum-like page \u662f\u6709K8s\u8fd0\u8425\u7684\u5e73\u53f0\uff0c\u63d0\u4f9b\u4e86\u5f88\u591a\u5173\u4e8e\u5982\u4f55\u4f7f\u7528 kubectl \u7684\u8be6\u7ec6\u4fe1\u606f\u548c\u4f8b\u5b50\u3002 Manage multiple clusters and multiple config files kubectl command documentation Shell autocompletion kubectl cheat sheet jsonpath in kubectl kubectl","title":"\u4f5c\u4e3a\u5e94\u7528\u7a0b\u5e8f\u8bbf\u95ee"},{"location":"k8s/cka_cn/foundamentals/casestudy-calico/","text":"\u4e3b\u9898\u8ba8\u8bba:\u5b89\u88c5Calico \u00b6 \u6f14\u793a\u573a\u666f\uff1a\u5b89\u88c5Calico \u8fd9\u662f\u4e00\u4e2a\u5173\u4e8e\u5982\u4f55\u914d\u7f6e\u548c\u6d4b\u8bd5Calico\u7f51\u7edc\u7684\u7b80\u8981\u6b65\u9aa4\uff1a Calico\u6570\u636e\u5e93\uff08Datastore\uff09\uff1aCalico\u652f\u6301\u4f7f\u7528etcd\u6216Kubernetes API server\u4f5c\u4e3a\u6570\u636e\u5b58\u50a8\u540e\u7aef\u3002\u9009\u62e9\u5e76\u90e8\u7f72\u5176\u4e2d\u4e00\u4e2a\u6570\u636e\u5b58\u50a8\u540e\u7aef\u3002 \u914d\u7f6eIP\u6c60\uff1a\u4e3a\u4e86\u4e3aKubernetes\u96c6\u7fa4\u4e2d\u7684\u8282\u70b9\u5206\u914dIP\u5730\u5740\uff0c\u9700\u8981\u914d\u7f6eIP\u6c60\u3002\u53ef\u4ee5\u901a\u8fc7Calico\u81ea\u5b9a\u4e49\u8d44\u6e90\uff08CRD\uff09\u6765\u5b9a\u4e49IP\u6c60\u3002 \u5b89\u88c5CNI\u63d2\u4ef6\uff1aCNI\u63d2\u4ef6\u8d1f\u8d23\u5728\u8282\u70b9\u4e0a\u521b\u5efa\u548c\u5220\u9664\u7f51\u7edc\u63a5\u53e3\uff0c\u5b83\u4eec\u662f\u5e94\u7528\u7a0b\u5e8f\u5bb9\u5668\u548c\u7269\u7406\u7f51\u7edc\u4e4b\u95f4\u7684\u6865\u6881\u3002\u9700\u8981\u5728Kubernetes\u8282\u70b9\u4e0a\u5b89\u88c5Calico CNI\u63d2\u4ef6\u3002 \u5b89\u88c5Typha\uff1aTypha\u662fCalico\u4e2d\u592e\u63a7\u5236\u5e73\u9762\u7684\u4e00\u4e2a\u7ec4\u4ef6\u3002\u5b83\u4eceKubernetes API server\u4e2d\u83b7\u53d6\u7f51\u7edc\u7b56\u7565\u548c\u5176\u4ed6\u4fe1\u606f\uff0c\u5e76\u5c06\u5b83\u4eec\u5206\u53d1\u7ed9\u6240\u6709\u8282\u70b9\u4e0a\u7684calico/node\u3002 \u5b89\u88c5calico/node\uff1acalico/node\u662f\u4e00\u4e2a\u8fd0\u884c\u5728Kubernetes\u8282\u70b9\u4e0a\u7684\u5b88\u62a4\u8fdb\u7a0b\u3002\u5b83\u7ba1\u7406\u8282\u70b9\u4e0a\u7684\u7f51\u7edc\u63a5\u53e3\uff0c\u5e76\u4e3a\u5bb9\u5668\u5206\u914d\u548c\u91ca\u653eIP\u5730\u5740\u3002 \u6d4b\u8bd5\u7f51\u7edc\uff1a\u5728\u5b8c\u6210\u4e0a\u8ff0\u6b65\u9aa4\u540e\uff0c\u53ef\u4ee5\u901a\u8fc7\u5728Pod\u4e4b\u95f4\u8fdb\u884c\u7f51\u7edc\u901a\u4fe1\u6765\u6d4b\u8bd5Calico\u7f51\u7edc\u662f\u5426\u6b63\u5e38\u5de5\u4f5c\u3002\u53ef\u4ee5\u521b\u5efa\u4e24\u4e2a\u8fd0\u884c\u5728\u4e0d\u540c\u8282\u70b9\u4e0a\u7684Pod\uff0c\u5e76\u5c1d\u8bd5\u4ece\u4e00\u4e2aPod ping\u53e6\u4e00\u4e2aPod\u3002\u5982\u679cping\u6210\u529f\uff0c\u5219\u8868\u793aCalico\u7f51\u7edc\u5df2\u6210\u529f\u914d\u7f6e\u548c\u8fd0\u884c\u3002 Calico\u6570\u636e\u5e93 \u00b6 \u4e3a\u4e86\u5c06Kubernetes\u7528\u4f5cCalico\u6570\u636e\u5b58\u50a8\u5e93\uff0c\u6211\u4eec\u9700\u8981\u5b9a\u4e49Calico\u4f7f\u7528\u7684\u81ea\u5b9a\u4e49\u8d44\u6e90\u3002 \u4e0b\u8f7d\u5e76\u68c0\u67e5Calico\u81ea\u5b9a\u4e49\u8d44\u6e90\u5b9a\u4e49\u5217\u8868\uff0c\u5e76\u5728\u6587\u4ef6\u7f16\u8f91\u5668\u4e2d\u6253\u5f00\u5b83\u3002 wget https://projectcalico.docs.tigera.io/manifests/crds.yaml \u5728 Kubernetes \u4e2d\u521b\u5efa Calico \u7684\u81ea\u5b9a\u4e49\u8d44\u6e90\u3002 kubectl apply -f crds.yaml \u5b89\u88c5 calicoctl \u3002 \u4e0b\u8f7d calicoctl \u4e8c\u8fdb\u5236\u6587\u4ef6\u5230\u4e00\u4e2a\u53ef\u4ee5\u8bbf\u95ee Kubernetes \u7684 Linux \u4e3b\u673a\u4e0a\uff0c\u4ee5\u76f4\u63a5\u4e0e Calico \u6570\u636e\u5b58\u50a8\u4ea4\u4e92\u3002 \u6700\u65b0\u7248\u7684calicoctl\u53ef\u4ee5\u901a\u8fc7 git page \u8fdb\u884c\u4e0b\u8f7d\uff0c\u9700\u8981\u7528\u5b9e\u9645\u7248\u672c\u53f7\u66ff\u6362\u4e0b\u9762\u7684 v3.23.2 \u7684\u7248\u672c\u53f7\u3002 wget https://github.com/projectcalico/calico/releases/download/v3.23.3/calicoctl-linux-amd64 chmod +x calicoctl-linux-amd64 sudo cp calicoctl-linux-amd64 /usr/local/bin/calicoctl \u914d\u7f6e calicoctl \u4ee5\u8bbf\u95ee Kubernetes\u3002 echo \"export KUBECONFIG=/root/.kube/config\" >> ~/.bashrc echo \"export DATASTORE_TYPE=kubernetes\" >> ~/.bashrc echo $KUBECONFIG echo $DATASTORE_TYPE \u6267\u884c\u4e0b\u9762\u7684\u547d\u4ee4\uff0c\u9a8c\u8bc1 calicoctl \u80fd\u591f\u8bbf\u95ee\u6570\u636e\u5e93\u3002 calicoctl get nodes -o wide \u8fd0\u884c\u7ed3\u679c\u7c7b\u4f3c\u5982\u4e0b\uff1a NAME ASN IPV4 IPV6 cka001 cka002 cka003 \u8282\u70b9\u662f\u7531 Kubernetes \u8282\u70b9\u5bf9\u8c61\u652f\u6301\u7684\uff0c\u56e0\u6b64\u6211\u4eec\u5e94\u8be5\u770b\u5230\u4e0e kubectl get nodes \u5339\u914d\u7684\u540d\u79f0\u3002 kubectl get nodes -o wide \u8fd0\u884c\u7ed3\u679c\uff1a NAME STATUS ROLES AGE VERSION OS-IMAGE KERNEL-VERSION CONTAINER-RUNTIME cka001 NotReady control-plane,master 23m v1.24.0 Ubuntu 20.04.4 LTS 5.4.0-113-generic containerd://1.5.9 cka002 NotReady 22m v1.24.0 Ubuntu 20.04.4 LTS 5.4.0-113-generic containerd://1.5.9 cka003 NotReady 21m v1.24.0 Ubuntu 20.04.4 LTS 5.4.0-113-generic containerd://1.5.9 \u914d\u7f6eIP\u6c60 \u00b6 \u4e00\u4e2a\u5de5\u4f5c\u8d1f\u8f7d\uff08workload\uff09\u662f\u5bb9\u5668\u6216\u865a\u62df\u673a\uff0c\u57fa\u4e8eCalico\u7684\u865a\u62df\u7f51\u7edc\u3002 \u5728Kubernetes\u4e2d\uff0c\u5de5\u4f5c\u8d1f\u8f7d\u662fPod\u3002\u4e00\u4e2a\u5de5\u4f5c\u8d1f\u8f7d\u7aef\u70b9\uff08endpoint\uff09\u662f\u5de5\u4f5c\u8d1f\u8f7d\u7528\u6765\u8fde\u63a5Calico\u7f51\u7edc\u7684\u865a\u62df\u7f51\u7edc\u63a5\u53e3\u3002 IP\u6c60\u662fCalico\u4e3a\u5de5\u4f5c\u8d1f\u8f7d\u7aef\u70b9\u4f7f\u7528\u7684IP\u5730\u5740\u8303\u56f4\u3002 \u83b7\u53d6\u96c6\u7fa4\u4e2d\u5f53\u524d\u7684IP\u6c60\u3002\u76ee\u524d\uff0c\u5728\u521a\u521a\u5b89\u88c5\u5b8c\u4e4b\u540e\uff0c\u5b83\u662f\u7a7a\u7684\u3002 calicoctl get ippools \u8fd0\u884c\u7ed3\u679c\uff1a NAME CIDR SELECTOR \u6211\u4eec\u901a\u8fc7 kubeadm init \u547d\u4ee4\u6307\u5b9a\u4e86 Pod CIDR \u4e3a 10.244.0.0/16 \u3002 \u73b0\u5728\uff0c\u6211\u4eec\u4e3a\u96c6\u7fa4\u521b\u5efa\u4e24\u4e2a IP \u6c60\uff08IP pool\uff09\uff0c\u6bcf\u4e2a\u6c60\u4e4b\u95f4\u4e0d\u80fd\u91cd\u53e0\u3002 \u521b\u5efaIP\u6c60 ipv4-ippool-1 : 10.244.0.0/18 calicoctl apply -f - < /etc/cni/net.d/10-calico.conflist < /etc/cni/net.d/10-calico.conflist < /etc/cni/net.d/10-calico.conflist < 4h49m v1.24.0 cka003 Ready 4h49m v1.24.0 \u5b89\u88c5Typha \u00b6 Typha \u5904\u4e8e Kubernetes API \u670d\u52a1\u5668\u548c\u6bcf\u4e2a\u8282\u70b9\u5b88\u62a4\u8fdb\u7a0b\uff08\u5982\u8fd0\u884c\u5728 calico/node \u4e2d\u7684 Felix \u548c confd\uff09\u4e4b\u95f4\u3002 \u5b83\u76d1\u89c6\u8fd9\u4e9b\u5b88\u62a4\u8fdb\u7a0b\u4f7f\u7528\u7684 Kubernetes \u8d44\u6e90\u548c Calico \u81ea\u5b9a\u4e49\u8d44\u6e90\uff0c\u6bcf\u5f53\u8d44\u6e90\u66f4\u6539\u65f6\uff0c\u5b83\u4f1a\u5c06\u66f4\u65b0\u6269\u6563\u5230\u8fd9\u4e9b\u5b88\u62a4\u8fdb\u7a0b\u3002 \u8fd9\u51cf\u5c11\u4e86 Kubernetes API \u670d\u52a1\u5668\u9700\u8981\u670d\u52a1\u7684\u76d1\u89c6\u6570\uff0c\u63d0\u9ad8\u4e86\u96c6\u7fa4\u7684\u53ef\u6269\u5c55\u6027\u3002 \u51c6\u5907\u8bc1\u4e66 \u4e0b\u9762\uff0c\u6211\u4eec\u4f7f\u7528\u76f8\u4e92\u8ba4\u8bc1\u7684TLS\u6765\u786e\u4fddcalico/node\u548cTypha\u4e4b\u95f4\u7684\u901a\u4fe1\u5b89\u5168\u3002 \u751f\u6210\u4e00\u4e2a\u8bc1\u4e66\u6388\u6743\u673a\u6784\uff08CA\uff09\u5e76\u4f7f\u7528\u5b83\u6765\u4e3aTypha\u7b7e\u7f72\u8bc1\u4e66\u3002 \u5c06\u5f53\u524d\u5de5\u4f5c\u76ee\u5f55\u6539\u4e3a /etc/kubernetes/pki/ \u3002 cd /etc/kubernetes/pki/ \u521b\u5efaCA\u8bc1\u4e66\u548c\u5bc6\u94a5\u3002 openssl req -x509 -newkey rsa:4096 \\ -keyout typhaca.key \\ -nodes \\ -out typhaca.crt \\ -subj \"/CN=Calico Typha CA\" \\ -days 365 \u628aCA\u8bc1\u4e66\u5b58\u653e\u5728ConfigMap\u4e2d\uff0c\u4f7fTypha\u548ccalico/node\u80fd\u591f\u8bbf\u95ee\u3002 kubectl create configmap -n kube-system calico-typha-ca --from-file = typhaca.crt \u751f\u6210Typha\u5bc6\u94a5\u548c\u8bc1\u4e66\u7b7e\u540d\u8bf7\u6c42\uff08certificate signing request\uff0cCSR\uff09\u3002 openssl req -newkey rsa:4096 \\ -keyout typha.key \\ -nodes \\ -out typha.csr \\ -subj \"/CN=calico-typha\" \u8bc1\u4e66\u7684\u901a\u7528\u540d\u79f0\uff08CN\uff09\u8bbe\u7f6e\u4e3a calico-typha \u3002 calico/node \u5c06\u88ab\u7528\u6765\u9a8c\u8bc1\u6b64\u540d\u79f0\u3002 \u4f7f\u7528 CA \u5bf9 Typha \u8bc1\u4e66\u8fdb\u884c\u7b7e\u540d\u3002 openssl x509 -req -in typha.csr \\ -CA typhaca.crt \\ -CAkey typhaca.key \\ -CAcreateserial \\ -out typha.crt \\ -days 365 \u8fd0\u884c\u7ed3\u679c\uff1a Signature ok subject=CN = calico-typha Getting CA Private Key \u5c06 Typha \u5bc6\u94a5\u548c\u8bc1\u4e66\u5b58\u50a8\u5728\u4e00\u4e2a secret \u4e2d\uff0c\u4ee5\u4fbf Typha \u53ef\u4ee5\u8bbf\u95ee\u3002 kubectl create secret generic -n kube-system calico-typha-certs --from-file = typha.key --from-file = typha.crt \u914d\u7f6eRBAC \u5f53\u524d\u5de5\u4f5c\u76ee\u5f55\u4e3ahome\u8def\u5f84\u3002 cd ~ \u521b\u5efa\u4e00\u4e2aTypha\u4f7f\u7528\u7684ServiceAccount\u3002 kubectl create serviceaccount -n kube-system calico-typha \u4e3a Typha \u521b\u5efa\u4e00\u4e2a\u96c6\u7fa4\u89d2\u8272\uff0c\u6709\u89c2\u5bdf Calico \u6570\u636e\u5b58\u50a8\u5bf9\u8c61\u7684\u6743\u9650\u3002 kubectl apply -f - < pingtest-585b76c894-s2tbs 1/1 Running 0 7s 10.244.31.0 cka002 pingtest-585b76c894-vm9wn 1/1 Running 0 7s 10.244.28.64 cka003 \u7559\u610f\u7b2c\u4e8c\u4e2a\u548c\u7b2c\u4e09\u4e2a pod \u7684 IP \u5730\u5740\u3002 \u968f\u540e\u6211\u4eec\u4f1a\u5728\u7b2c\u4e00\u4e2a pod \u4e2d\u8fd0\u884c exec \u547d\u4ee4\u3002 \u5728\u7b2c\u4e00\u4e2a pod \u5185\u90e8\uff0c\u5bf9\u53e6\u5916\u4e24\u4e2a pod \u7684 IP \u5730\u5740\u8fdb\u884c ping \u6d4b\u8bd5\u3002 \u4f8b\u5982\uff1a kubectl exec -ti pingtest-585b76c894-chwjq -- sh / # ping 10.244.31.1 -c 4 4 packets transmitted, 4 packets received, 0 % packet loss / # ping 10.244.31.0 -c 4 4 packets transmitted, 4 packets received, 0 % packet loss / # ping 10.244.28.64 -c 4 4 packets transmitted, 0 packets received, 100 % packet loss \u8def\u7531\u68c0\u67e5 \u00b6 \u4ece\u5176\u4e2d\u4e00\u4e2a\u8282\u70b9\u9a8c\u8bc1\u662f\u5426\u80fdping\u901a\u5230\u6bcf\u4e2apod\u7684IP\u5730\u5740\u3002\u4f8b\u5982\uff1a ip route get 10 .244.31.1 ip route get 10 .244.31.0 ip route get 10 .244.28.64 \u5728\u4e0a\u9762\u7684\u7ed3\u679c\u4e2d\uff0c\u793a\u4f8b\u4e2d\u7684 via \uff08\u5b83\u662f\u63a7\u5236\u5e73\u9762\uff09\u8868\u793a\u6b64Pod IP\u7684\u4e0b\u4e00\u8df3\uff0c\u8fd9\u4e0ePod\u6240\u5728\u8282\u70b9\u7684IP\u5730\u5740\u5339\u914d\uff0c\u7b26\u5408\u9884\u671f\u3002 \u4e0d\u540cIP\u6c60\u7684IPAM\u5206\u914d\u3002\u5728\u524d\u9762\u7684\u6f14\u793a\u4e2d\uff0c\u6211\u4eec\u521b\u5efa\u4e86\u4e24\u4e2aIP\u6c60\uff0c\u4f46\u5c06\u4e00\u4e2a\u7981\u7528\u4e86\u3002 calicoctl get ippools -o wide \u8fd0\u884c\u7ed3\u679c\uff1a NAME CIDR NAT IPIPMODE VXLANMODE DISABLED DISABLEBGPEXPORT SELECTOR ipv4-ippool-1 10.244.0.0/18 true Never Never false false all() ipv4-ippool-2 10.244.192.0/19 true Never Never true false all() \u6fc0\u6d3b\u7b2c\u4e8c\u4e2aIP\u6c60\u3002 calicoctl --allow-version-mismatch apply -f - < \u8fde\u63a5\u5e76\u8fdb\u5165Pod pingtest-585b76c894-chwjq \u5185\u90e8\u3002 kubectl exec -ti pingtest-585b76c894-chwjq -- sh / # 10.244.203.192 -c 4 4 packets transmitted, 0 packets received, 100 % packet loss \u6807\u8bb0\uff1a \u6f14\u793a\u6b62\u4e8e\u6b64\uff0c\u8def\u7531\u6ca1\u6709\u5b89\u88c5\u9884\u671f\u5de5\u4f5c\uff0c\u539f\u56e0\u67e5\u627e\u4e2d\u3002 \u5220\u9664\u6f14\u793a\u4e2d\u521b\u5efa\u7684\u4e34\u65f6\u8d44\u6e90\u3002 kubectl delete deployments.apps pingtest kubectl delete pod pingtest-ippool-2 \u53c2\u8003\uff1a End-to-end Calico installation","title":"\u5b89\u88c5Calico"},{"location":"k8s/cka_cn/foundamentals/casestudy-calico/#calico","text":"\u6f14\u793a\u573a\u666f\uff1a\u5b89\u88c5Calico \u8fd9\u662f\u4e00\u4e2a\u5173\u4e8e\u5982\u4f55\u914d\u7f6e\u548c\u6d4b\u8bd5Calico\u7f51\u7edc\u7684\u7b80\u8981\u6b65\u9aa4\uff1a Calico\u6570\u636e\u5e93\uff08Datastore\uff09\uff1aCalico\u652f\u6301\u4f7f\u7528etcd\u6216Kubernetes API server\u4f5c\u4e3a\u6570\u636e\u5b58\u50a8\u540e\u7aef\u3002\u9009\u62e9\u5e76\u90e8\u7f72\u5176\u4e2d\u4e00\u4e2a\u6570\u636e\u5b58\u50a8\u540e\u7aef\u3002 \u914d\u7f6eIP\u6c60\uff1a\u4e3a\u4e86\u4e3aKubernetes\u96c6\u7fa4\u4e2d\u7684\u8282\u70b9\u5206\u914dIP\u5730\u5740\uff0c\u9700\u8981\u914d\u7f6eIP\u6c60\u3002\u53ef\u4ee5\u901a\u8fc7Calico\u81ea\u5b9a\u4e49\u8d44\u6e90\uff08CRD\uff09\u6765\u5b9a\u4e49IP\u6c60\u3002 \u5b89\u88c5CNI\u63d2\u4ef6\uff1aCNI\u63d2\u4ef6\u8d1f\u8d23\u5728\u8282\u70b9\u4e0a\u521b\u5efa\u548c\u5220\u9664\u7f51\u7edc\u63a5\u53e3\uff0c\u5b83\u4eec\u662f\u5e94\u7528\u7a0b\u5e8f\u5bb9\u5668\u548c\u7269\u7406\u7f51\u7edc\u4e4b\u95f4\u7684\u6865\u6881\u3002\u9700\u8981\u5728Kubernetes\u8282\u70b9\u4e0a\u5b89\u88c5Calico CNI\u63d2\u4ef6\u3002 \u5b89\u88c5Typha\uff1aTypha\u662fCalico\u4e2d\u592e\u63a7\u5236\u5e73\u9762\u7684\u4e00\u4e2a\u7ec4\u4ef6\u3002\u5b83\u4eceKubernetes API server\u4e2d\u83b7\u53d6\u7f51\u7edc\u7b56\u7565\u548c\u5176\u4ed6\u4fe1\u606f\uff0c\u5e76\u5c06\u5b83\u4eec\u5206\u53d1\u7ed9\u6240\u6709\u8282\u70b9\u4e0a\u7684calico/node\u3002 \u5b89\u88c5calico/node\uff1acalico/node\u662f\u4e00\u4e2a\u8fd0\u884c\u5728Kubernetes\u8282\u70b9\u4e0a\u7684\u5b88\u62a4\u8fdb\u7a0b\u3002\u5b83\u7ba1\u7406\u8282\u70b9\u4e0a\u7684\u7f51\u7edc\u63a5\u53e3\uff0c\u5e76\u4e3a\u5bb9\u5668\u5206\u914d\u548c\u91ca\u653eIP\u5730\u5740\u3002 \u6d4b\u8bd5\u7f51\u7edc\uff1a\u5728\u5b8c\u6210\u4e0a\u8ff0\u6b65\u9aa4\u540e\uff0c\u53ef\u4ee5\u901a\u8fc7\u5728Pod\u4e4b\u95f4\u8fdb\u884c\u7f51\u7edc\u901a\u4fe1\u6765\u6d4b\u8bd5Calico\u7f51\u7edc\u662f\u5426\u6b63\u5e38\u5de5\u4f5c\u3002\u53ef\u4ee5\u521b\u5efa\u4e24\u4e2a\u8fd0\u884c\u5728\u4e0d\u540c\u8282\u70b9\u4e0a\u7684Pod\uff0c\u5e76\u5c1d\u8bd5\u4ece\u4e00\u4e2aPod ping\u53e6\u4e00\u4e2aPod\u3002\u5982\u679cping\u6210\u529f\uff0c\u5219\u8868\u793aCalico\u7f51\u7edc\u5df2\u6210\u529f\u914d\u7f6e\u548c\u8fd0\u884c\u3002","title":"\u4e3b\u9898\u8ba8\u8bba:\u5b89\u88c5Calico"},{"location":"k8s/cka_cn/foundamentals/casestudy-calico/#calico_1","text":"\u4e3a\u4e86\u5c06Kubernetes\u7528\u4f5cCalico\u6570\u636e\u5b58\u50a8\u5e93\uff0c\u6211\u4eec\u9700\u8981\u5b9a\u4e49Calico\u4f7f\u7528\u7684\u81ea\u5b9a\u4e49\u8d44\u6e90\u3002 \u4e0b\u8f7d\u5e76\u68c0\u67e5Calico\u81ea\u5b9a\u4e49\u8d44\u6e90\u5b9a\u4e49\u5217\u8868\uff0c\u5e76\u5728\u6587\u4ef6\u7f16\u8f91\u5668\u4e2d\u6253\u5f00\u5b83\u3002 wget https://projectcalico.docs.tigera.io/manifests/crds.yaml \u5728 Kubernetes \u4e2d\u521b\u5efa Calico \u7684\u81ea\u5b9a\u4e49\u8d44\u6e90\u3002 kubectl apply -f crds.yaml \u5b89\u88c5 calicoctl \u3002 \u4e0b\u8f7d calicoctl \u4e8c\u8fdb\u5236\u6587\u4ef6\u5230\u4e00\u4e2a\u53ef\u4ee5\u8bbf\u95ee Kubernetes \u7684 Linux \u4e3b\u673a\u4e0a\uff0c\u4ee5\u76f4\u63a5\u4e0e Calico \u6570\u636e\u5b58\u50a8\u4ea4\u4e92\u3002 \u6700\u65b0\u7248\u7684calicoctl\u53ef\u4ee5\u901a\u8fc7 git page \u8fdb\u884c\u4e0b\u8f7d\uff0c\u9700\u8981\u7528\u5b9e\u9645\u7248\u672c\u53f7\u66ff\u6362\u4e0b\u9762\u7684 v3.23.2 \u7684\u7248\u672c\u53f7\u3002 wget https://github.com/projectcalico/calico/releases/download/v3.23.3/calicoctl-linux-amd64 chmod +x calicoctl-linux-amd64 sudo cp calicoctl-linux-amd64 /usr/local/bin/calicoctl \u914d\u7f6e calicoctl \u4ee5\u8bbf\u95ee Kubernetes\u3002 echo \"export KUBECONFIG=/root/.kube/config\" >> ~/.bashrc echo \"export DATASTORE_TYPE=kubernetes\" >> ~/.bashrc echo $KUBECONFIG echo $DATASTORE_TYPE \u6267\u884c\u4e0b\u9762\u7684\u547d\u4ee4\uff0c\u9a8c\u8bc1 calicoctl \u80fd\u591f\u8bbf\u95ee\u6570\u636e\u5e93\u3002 calicoctl get nodes -o wide \u8fd0\u884c\u7ed3\u679c\u7c7b\u4f3c\u5982\u4e0b\uff1a NAME ASN IPV4 IPV6 cka001 cka002 cka003 \u8282\u70b9\u662f\u7531 Kubernetes \u8282\u70b9\u5bf9\u8c61\u652f\u6301\u7684\uff0c\u56e0\u6b64\u6211\u4eec\u5e94\u8be5\u770b\u5230\u4e0e kubectl get nodes \u5339\u914d\u7684\u540d\u79f0\u3002 kubectl get nodes -o wide \u8fd0\u884c\u7ed3\u679c\uff1a NAME STATUS ROLES AGE VERSION OS-IMAGE KERNEL-VERSION CONTAINER-RUNTIME cka001 NotReady control-plane,master 23m v1.24.0 Ubuntu 20.04.4 LTS 5.4.0-113-generic containerd://1.5.9 cka002 NotReady 22m v1.24.0 Ubuntu 20.04.4 LTS 5.4.0-113-generic containerd://1.5.9 cka003 NotReady 21m v1.24.0 Ubuntu 20.04.4 LTS 5.4.0-113-generic containerd://1.5.9","title":"Calico\u6570\u636e\u5e93"},{"location":"k8s/cka_cn/foundamentals/casestudy-calico/#ip","text":"\u4e00\u4e2a\u5de5\u4f5c\u8d1f\u8f7d\uff08workload\uff09\u662f\u5bb9\u5668\u6216\u865a\u62df\u673a\uff0c\u57fa\u4e8eCalico\u7684\u865a\u62df\u7f51\u7edc\u3002 \u5728Kubernetes\u4e2d\uff0c\u5de5\u4f5c\u8d1f\u8f7d\u662fPod\u3002\u4e00\u4e2a\u5de5\u4f5c\u8d1f\u8f7d\u7aef\u70b9\uff08endpoint\uff09\u662f\u5de5\u4f5c\u8d1f\u8f7d\u7528\u6765\u8fde\u63a5Calico\u7f51\u7edc\u7684\u865a\u62df\u7f51\u7edc\u63a5\u53e3\u3002 IP\u6c60\u662fCalico\u4e3a\u5de5\u4f5c\u8d1f\u8f7d\u7aef\u70b9\u4f7f\u7528\u7684IP\u5730\u5740\u8303\u56f4\u3002 \u83b7\u53d6\u96c6\u7fa4\u4e2d\u5f53\u524d\u7684IP\u6c60\u3002\u76ee\u524d\uff0c\u5728\u521a\u521a\u5b89\u88c5\u5b8c\u4e4b\u540e\uff0c\u5b83\u662f\u7a7a\u7684\u3002 calicoctl get ippools \u8fd0\u884c\u7ed3\u679c\uff1a NAME CIDR SELECTOR \u6211\u4eec\u901a\u8fc7 kubeadm init \u547d\u4ee4\u6307\u5b9a\u4e86 Pod CIDR \u4e3a 10.244.0.0/16 \u3002 \u73b0\u5728\uff0c\u6211\u4eec\u4e3a\u96c6\u7fa4\u521b\u5efa\u4e24\u4e2a IP \u6c60\uff08IP pool\uff09\uff0c\u6bcf\u4e2a\u6c60\u4e4b\u95f4\u4e0d\u80fd\u91cd\u53e0\u3002 \u521b\u5efaIP\u6c60 ipv4-ippool-1 : 10.244.0.0/18 calicoctl apply -f - < /etc/cni/net.d/10-calico.conflist < /etc/cni/net.d/10-calico.conflist < /etc/cni/net.d/10-calico.conflist < 4h49m v1.24.0 cka003 Ready 4h49m v1.24.0","title":"\u5b89\u88c5CNI\u63d2\u4ef6"},{"location":"k8s/cka_cn/foundamentals/casestudy-calico/#typha","text":"Typha \u5904\u4e8e Kubernetes API \u670d\u52a1\u5668\u548c\u6bcf\u4e2a\u8282\u70b9\u5b88\u62a4\u8fdb\u7a0b\uff08\u5982\u8fd0\u884c\u5728 calico/node \u4e2d\u7684 Felix \u548c confd\uff09\u4e4b\u95f4\u3002 \u5b83\u76d1\u89c6\u8fd9\u4e9b\u5b88\u62a4\u8fdb\u7a0b\u4f7f\u7528\u7684 Kubernetes \u8d44\u6e90\u548c Calico \u81ea\u5b9a\u4e49\u8d44\u6e90\uff0c\u6bcf\u5f53\u8d44\u6e90\u66f4\u6539\u65f6\uff0c\u5b83\u4f1a\u5c06\u66f4\u65b0\u6269\u6563\u5230\u8fd9\u4e9b\u5b88\u62a4\u8fdb\u7a0b\u3002 \u8fd9\u51cf\u5c11\u4e86 Kubernetes API \u670d\u52a1\u5668\u9700\u8981\u670d\u52a1\u7684\u76d1\u89c6\u6570\uff0c\u63d0\u9ad8\u4e86\u96c6\u7fa4\u7684\u53ef\u6269\u5c55\u6027\u3002 \u51c6\u5907\u8bc1\u4e66 \u4e0b\u9762\uff0c\u6211\u4eec\u4f7f\u7528\u76f8\u4e92\u8ba4\u8bc1\u7684TLS\u6765\u786e\u4fddcalico/node\u548cTypha\u4e4b\u95f4\u7684\u901a\u4fe1\u5b89\u5168\u3002 \u751f\u6210\u4e00\u4e2a\u8bc1\u4e66\u6388\u6743\u673a\u6784\uff08CA\uff09\u5e76\u4f7f\u7528\u5b83\u6765\u4e3aTypha\u7b7e\u7f72\u8bc1\u4e66\u3002 \u5c06\u5f53\u524d\u5de5\u4f5c\u76ee\u5f55\u6539\u4e3a /etc/kubernetes/pki/ \u3002 cd /etc/kubernetes/pki/ \u521b\u5efaCA\u8bc1\u4e66\u548c\u5bc6\u94a5\u3002 openssl req -x509 -newkey rsa:4096 \\ -keyout typhaca.key \\ -nodes \\ -out typhaca.crt \\ -subj \"/CN=Calico Typha CA\" \\ -days 365 \u628aCA\u8bc1\u4e66\u5b58\u653e\u5728ConfigMap\u4e2d\uff0c\u4f7fTypha\u548ccalico/node\u80fd\u591f\u8bbf\u95ee\u3002 kubectl create configmap -n kube-system calico-typha-ca --from-file = typhaca.crt \u751f\u6210Typha\u5bc6\u94a5\u548c\u8bc1\u4e66\u7b7e\u540d\u8bf7\u6c42\uff08certificate signing request\uff0cCSR\uff09\u3002 openssl req -newkey rsa:4096 \\ -keyout typha.key \\ -nodes \\ -out typha.csr \\ -subj \"/CN=calico-typha\" \u8bc1\u4e66\u7684\u901a\u7528\u540d\u79f0\uff08CN\uff09\u8bbe\u7f6e\u4e3a calico-typha \u3002 calico/node \u5c06\u88ab\u7528\u6765\u9a8c\u8bc1\u6b64\u540d\u79f0\u3002 \u4f7f\u7528 CA \u5bf9 Typha \u8bc1\u4e66\u8fdb\u884c\u7b7e\u540d\u3002 openssl x509 -req -in typha.csr \\ -CA typhaca.crt \\ -CAkey typhaca.key \\ -CAcreateserial \\ -out typha.crt \\ -days 365 \u8fd0\u884c\u7ed3\u679c\uff1a Signature ok subject=CN = calico-typha Getting CA Private Key \u5c06 Typha \u5bc6\u94a5\u548c\u8bc1\u4e66\u5b58\u50a8\u5728\u4e00\u4e2a secret \u4e2d\uff0c\u4ee5\u4fbf Typha \u53ef\u4ee5\u8bbf\u95ee\u3002 kubectl create secret generic -n kube-system calico-typha-certs --from-file = typha.key --from-file = typha.crt \u914d\u7f6eRBAC \u5f53\u524d\u5de5\u4f5c\u76ee\u5f55\u4e3ahome\u8def\u5f84\u3002 cd ~ \u521b\u5efa\u4e00\u4e2aTypha\u4f7f\u7528\u7684ServiceAccount\u3002 kubectl create serviceaccount -n kube-system calico-typha \u4e3a Typha \u521b\u5efa\u4e00\u4e2a\u96c6\u7fa4\u89d2\u8272\uff0c\u6709\u89c2\u5bdf Calico \u6570\u636e\u5b58\u50a8\u5bf9\u8c61\u7684\u6743\u9650\u3002 kubectl apply -f - < pingtest-585b76c894-s2tbs 1/1 Running 0 7s 10.244.31.0 cka002 pingtest-585b76c894-vm9wn 1/1 Running 0 7s 10.244.28.64 cka003 \u7559\u610f\u7b2c\u4e8c\u4e2a\u548c\u7b2c\u4e09\u4e2a pod \u7684 IP \u5730\u5740\u3002 \u968f\u540e\u6211\u4eec\u4f1a\u5728\u7b2c\u4e00\u4e2a pod \u4e2d\u8fd0\u884c exec \u547d\u4ee4\u3002 \u5728\u7b2c\u4e00\u4e2a pod \u5185\u90e8\uff0c\u5bf9\u53e6\u5916\u4e24\u4e2a pod \u7684 IP \u5730\u5740\u8fdb\u884c ping \u6d4b\u8bd5\u3002 \u4f8b\u5982\uff1a kubectl exec -ti pingtest-585b76c894-chwjq -- sh / # ping 10.244.31.1 -c 4 4 packets transmitted, 4 packets received, 0 % packet loss / # ping 10.244.31.0 -c 4 4 packets transmitted, 4 packets received, 0 % packet loss / # ping 10.244.28.64 -c 4 4 packets transmitted, 0 packets received, 100 % packet loss","title":"pod\u4e4b\u95f4\u7684ping"},{"location":"k8s/cka_cn/foundamentals/casestudy-calico/#_2","text":"\u4ece\u5176\u4e2d\u4e00\u4e2a\u8282\u70b9\u9a8c\u8bc1\u662f\u5426\u80fdping\u901a\u5230\u6bcf\u4e2apod\u7684IP\u5730\u5740\u3002\u4f8b\u5982\uff1a ip route get 10 .244.31.1 ip route get 10 .244.31.0 ip route get 10 .244.28.64 \u5728\u4e0a\u9762\u7684\u7ed3\u679c\u4e2d\uff0c\u793a\u4f8b\u4e2d\u7684 via \uff08\u5b83\u662f\u63a7\u5236\u5e73\u9762\uff09\u8868\u793a\u6b64Pod IP\u7684\u4e0b\u4e00\u8df3\uff0c\u8fd9\u4e0ePod\u6240\u5728\u8282\u70b9\u7684IP\u5730\u5740\u5339\u914d\uff0c\u7b26\u5408\u9884\u671f\u3002 \u4e0d\u540cIP\u6c60\u7684IPAM\u5206\u914d\u3002\u5728\u524d\u9762\u7684\u6f14\u793a\u4e2d\uff0c\u6211\u4eec\u521b\u5efa\u4e86\u4e24\u4e2aIP\u6c60\uff0c\u4f46\u5c06\u4e00\u4e2a\u7981\u7528\u4e86\u3002 calicoctl get ippools -o wide \u8fd0\u884c\u7ed3\u679c\uff1a NAME CIDR NAT IPIPMODE VXLANMODE DISABLED DISABLEBGPEXPORT SELECTOR ipv4-ippool-1 10.244.0.0/18 true Never Never false false all() ipv4-ippool-2 10.244.192.0/19 true Never Never true false all() \u6fc0\u6d3b\u7b2c\u4e8c\u4e2aIP\u6c60\u3002 calicoctl --allow-version-mismatch apply -f - < \u8fde\u63a5\u5e76\u8fdb\u5165Pod pingtest-585b76c894-chwjq \u5185\u90e8\u3002 kubectl exec -ti pingtest-585b76c894-chwjq -- sh / # 10.244.203.192 -c 4 4 packets transmitted, 0 packets received, 100 % packet loss \u6807\u8bb0\uff1a \u6f14\u793a\u6b62\u4e8e\u6b64\uff0c\u8def\u7531\u6ca1\u6709\u5b89\u88c5\u9884\u671f\u5de5\u4f5c\uff0c\u539f\u56e0\u67e5\u627e\u4e2d\u3002 \u5220\u9664\u6f14\u793a\u4e2d\u521b\u5efa\u7684\u4e34\u65f6\u8d44\u6e90\u3002 kubectl delete deployments.apps pingtest kubectl delete pod pingtest-ippool-2 \u53c2\u8003\uff1a End-to-end Calico installation","title":"\u8def\u7531\u68c0\u67e5"},{"location":"k8s/cka_cn/foundamentals/casestudy-health-check/","text":"\u4e3b\u9898\u8ba8\u8bba:\u5065\u5eb7\u68c0\u67e5 \u00b6 \u6f14\u793a\u573a\u666f\uff1a \u521b\u5efa Deployment \u548c Service \u6a21\u62df\u4e00\u4e2a\u9519\u8bef\uff08\u5220\u9664 index.html\uff09 Pod \u5904\u4e8e\u4e0d\u5065\u5eb7\u72b6\u6001\u5e76\u4ece endpoint \u5217\u8868\u4e2d\u5220\u9664 \u4fee\u590d\u9519\u8bef\uff08\u6062\u590d index.html\uff09 Pod \u56de\u5230\u6b63\u5e38\u72b6\u6001\u5e76\u91cd\u65b0\u52a0\u5165 endpoint \u5217\u8868 \u521b\u5efa Deployment \u548c Service \u00b6 \u521b\u5efaDeployment nginx-healthcheck \u548cService nginx-healthcheck \u3002 kubectl apply -f - < nginx-healthcheck-79fc55d944-nwwjc 1/1 Running 0 9s 10.244.112.13 cka002 \u901a\u8fc7\u547d\u4ee4 curl \u6765\u8bbf\u95ee\u4e0a\u9762\u8fd0\u884c\u7ed3\u679c\u4e2dpod\u7684IP\u5730\u5740\u3002 curl 10 .244.102.14 curl 10 .244.112.13 \u5982\u679c\u4e0a\u9762\u547d\u4ee4\u6210\u529f\u6267\u884c\uff0c\u5219\u4f1a\u8fd4\u56deNginx\u4e2d index.html \u7684\u5185\u5bb9\u3002 \u83b7\u53d6\u524d\u9762\u521b\u5efa\u7684Service\u7684\u8be6\u7ec6\u4fe1\u606f\u3002 kubectl describe svc nginx-healthcheck \u8f93\u51fa\u7ed3\u679c\u5982\u4e0b\u3002\u5728 Endpoints \u90e8\u5206\u6211\u4eec\u53ef\u4ee5\u770b\u52302\u4e2apod\u3002 Name : nginx-healthcheck Namespace : dev Labels : Annotations : Selector : name=nginx-healthcheck Type : NodePort IP Family Policy : SingleStack IP Families : IPv4 IP : 11.244.238.20 IPs : 11.244.238.20 Port : 80/TCP TargetPort : 80/TCP NodePort : 31795/TCP Endpoints : 10.244.102.14:80,10.244.112.13:80 Session Affinity : None External Traffic Policy : Cluster Events : \u83b7\u53d6Endpoints\u7684\u4fe1\u606f\u3002 kubectl get endpoints nginx-healthcheck \u8fd0\u884c\u7ed3\u679c NAME ENDPOINTS AGE nginx-healthcheck 10.244.102.14:80,10.244.112.13:80 72s \u81f3\u6b64\uff0c2\u4e2apod nginx-healthcheck \u90fd\u80fd\u6309\u7167\u6211\u4eec\u7684\u671f\u671b\u6b63\u5e38\u5de5\u4f5c\u3002 \u6a21\u62dfreadinessProbe\u9519\u8bef \u00b6 \u8ba9\u6211\u4eec\u901a\u8fc7\u5220\u9664 nginx-healthcheck Pod \u4e2d\u7684 index.html \u6587\u4ef6\u6765\u6a21\u62df\u9519\u8bef\uff0c\u89c2\u5bdf readinessProbe \u7684\u8868\u73b0\u3002 \u9996\u5148\uff0c\u6267\u884c kubectl exec -it -- bash \u547d\u4ee4\u4ee5\u767b\u5f55\u5230 nginx-healthcheck Pod\uff0c\u5e76\u5220\u9664 index.html \u6587\u4ef6\u3002 kubectl exec -it nginx-healthcheck-79fc55d944-jw887 -- bash cd /usr/share/nginx/html/ rm -rf index.html exit \u5728\u6267\u884c\u4e86\u5220\u9664 nginx-healthcheck Pod \u4e2d\u7684 index.html \u6587\u4ef6\u4e4b\u540e\uff0c\u6211\u4eec\u68c0\u67e5\u8be5 Pod \u7684\u72b6\u6001\u3002 kubectl describe pod nginx-healthcheck-79fc55d944-jw887 \u4e0b\u9762\u7684\u8f93\u51fa\u7ed3\u679c\u4e2d\uff0c\u6211\u4eec\u53ef\u4ee5\u770b\u5230 Readiness probe failed \u8fd9\u4e2a\u9519\u8bef\u4e8b\u4ef6\u4fe1\u606f\u3002 ...... Events: Type Reason Age From Message ---- ------ ---- ---- ------- Normal Scheduled 2m8s default-scheduler Successfully assigned dev/nginx-healthcheck-79fc55d944-jw887 to cka003 Normal Pulled 2m7s kubelet Container image \"nginx:latest\" already present on machine Normal Created 2m7s kubelet Created container nginx-healthcheck Normal Started 2m7s kubelet Started container nginx-healthcheck Warning Unhealthy 2s (x2 over 7s) kubelet Readiness probe failed: HTTP probe failed with statuscode: 403 \u68c0\u67e5\u53e6\u4e00\u4e2apod\u3002 kubectl describe pod nginx-healthcheck-79fc55d944-nwwjc \u4e0b\u9762\u7684\u8f93\u51fa\u7ed3\u679c\u4e2d\uff0c\u6ca1\u6709\u53d1\u73b0\u9519\u8bef\u3002 ...... Events: Type Reason Age From Message ---- ------ ---- ---- ------- Normal Scheduled 3m46s default-scheduler Successfully assigned dev/nginx-healthcheck-79fc55d944-nwwjc to cka002 Normal Pulled 3m45s kubelet Container image \"nginx:latest\" already present on machine Normal Created 3m45s kubelet Created container nginx-healthcheck Normal Started 3m45s kubelet Started container nginx-healthcheck \u73b0\u5728\uff0c\u901a\u8fc7 curl \u547d\u4ee4\u6765\u8bbf\u95ee2\u4e2apod\u7684IP\u5730\u5740\uff0c\u6211\u4eec\u6765\u89c2\u5bdf\u4f1a\u5f97\u5230\u600e\u6837\u7684\u7ed3\u679c\u3002 curl 10 .244.102.14 curl 10 .244.112.13 \u8fd0\u884c\u7ed3\u679c\uff1a curl 10.244.102.14 \u5931\u8d25\uff0c\u9519\u8bef\u4fe1\u606f\u662f 403 Forbidden \u3002 curl 10.244.112.13 \u6210\u529f\u3002 \u6211\u4eec\u73b0\u5728\u6765\u67e5\u8be2Nginx service\u5728\u4e00\u4e2apod\u5931\u8d25\u65f6\u7684\u72b6\u6001\u3002 kubectl describe svc nginx-healthcheck \u5728\u4e0b\u9762\u7684\u8f93\u51fa\u7ed3\u679c\u4e2d\uff0c\u6211\u4eec\u770b\u5230Endpoint\u90e8\u5206\u4e2d\u53ea\u6709\u4e00\u4e2apod\u7684\u4fe1\u606f\u3002 Name : nginx-healthcheck Namespace : dev Labels : Annotations : Selector : name=nginx-healthcheck Type : NodePort IP Family Policy : SingleStack IP Families : IPv4 IP : 11.244.238.20 IPs : 11.244.238.20 Port : 80/TCP TargetPort : 80/TCP NodePort : 31795/TCP Endpoints : 10.244.112.13:80 Session Affinity : None External Traffic Policy : Cluster Events : \u540c\u6837\u7684\uff0c\u6211\u4eec\u53ef\u4ee5\u901a\u8fc7\u68c0\u67e5Endpoint\u7684\u4fe1\u606f\uff0c\u4e5f\u80fd\u53d1\u73b0\u53ea\u6709\u4e00\u4e2apod\u6b63\u5728\u8fd0\u884c\u3002 kubectl get endpoints nginx-healthcheck \u8fd0\u884c\u7ed3\u679c\uff1a NAME ENDPOINTS AGE nginx-healthcheck 10.244.112.13:80 6m5s \u4fee\u590dreadinessProbe\u9519\u8bef \u00b6 \u73b0\u5728\uff0c\u6211\u4eec\u5728pod\u4e2d\u91cd\u65b0\u521b\u5efa index.html \u6587\u4ef6\uff0c\u6765\u4fee\u590d\u9519\u8bef\u3002 kubectl exec -it nginx-healthcheck-79fc55d944-jw887 -- bash cd /usr/share/nginx/html/ cat > index.html << EOF Welcome to nginx!

Welcome to nginx!

If you see this page, the nginx web server is successfully installed and working. Further configuration is required.

For online documentation and support please refer to nginx.org.
Commercial support is available at nginx.com.

Thank you for using nginx.

EOF exit \u73b0\u5728\u6211\u4eec\u53ef\u4ee5\u770b\u5230\u4e24\u4e2aPod\u5df2\u7ecf\u91cd\u65b0\u52a0\u5165\u4e86Endpoint\u5217\u8868\uff0c\u53ef\u4ee5\u63d0\u4f9b\u670d\u52a1\u4e86\u3002 kubectl describe svc nginx-healthcheck kubectl get endpoints nginx-healthcheck \u91cd\u65b0\u901a\u8fc7 curl \u547d\u4ee4\u8bbf\u95ee2\u4e2apod\u7684IP\u5730\u5740\uff0c\u6211\u4eec\u53ef\u4ee5\u770b\u5230\u5b83\u4eec\u90fd\u5df2\u7ecf\u6062\u590d\u5230\u6b63\u5e38\u72b6\u6001\u4e86\u3002 curl 10 .244.102.14 curl 10 .244.112.13 \u518d\u6b21\u9a8c\u8bc1pod\u7684\u72b6\u6001\u3002 kubectl describe pod nginx-healthcheck-79fc55d944-jw887 \u7ed3\u8bba\uff1a \u901a\u8fc7\u5220\u9664 index.html \u6587\u4ef6\uff0cPod \u8fdb\u5165\u4e0d\u5065\u5eb7\u72b6\u6001\u5e76\u4ece\u7aef\u70b9\u5217\u8868\u4e2d\u5220\u9664\u3002 \u53ea\u6709\u4e00\u4e2a\u5065\u5eb7\u7684 Pod \u53ef\u4ee5\u63d0\u4f9b\u6b63\u5e38\u7684\u670d\u52a1\u3002 \u6e05\u9664\u6f14\u793a\u4e2d\u521b\u5efa\u7684\u4e34\u65f6\u8d44\u6e90\u3002 kubectl delete service nginx-healthcheck kubectl delete deployment nginx-healthcheck \u6a21\u62dflivenessProbe\u9519\u8bef \u00b6 \u91cd\u65b0\u521b\u5efadeployment nginx-healthcheck \u548cservice nginx-healthcheck \u3002 Deployment: NAME READY UP-TO-DATE AVAILABLE AGE nginx-healthcheck 0/2 2 0 7s Pods: NAME READY STATUS RESTARTS AGE nginx-healthcheck-79fc55d944-lknp9 1/1 Running 0 96s nginx-healthcheck-79fc55d944-wntmg 1/1 Running 0 96s \u5c06 Nginx \u9ed8\u8ba4\u76d1\u542c\u7aef\u53e3\u4ece 80 \u6539\u4e3a 90 \uff0c\u4ee5\u6a21\u62df livenessProbe \u5931\u8d25\u3002livenessProbe \u901a\u8fc7\u7aef\u53e3 80 \u68c0\u67e5\u751f\u5b58\u72b6\u6001\u3002 kubectl exec -it nginx-healthcheck-79fc55d944-lknp9 -- bash root@nginx-healthcheck-79fc55d944-lknp9:/# cd /etc/nginx/conf.d root@nginx-healthcheck-79fc55d944-lknp9:/etc/nginx/conf.d# sed -i 's/80/90/g' default.conf root@nginx-healthcheck-79fc55d944-lknp9:/etc/nginx/conf.d# nginx -s reload 2022 /07/24 12 :59:45 [ notice ] 79 #79: signal process started Pod\u73b0\u5728\u8868\u73b0\u4e3a\u5931\u8d25\u72b6\u6001\u3002 kubectl describe pod nginx-healthcheck-79fc55d944-lknp9 \u5728pod\u7684\u4e8b\u4ef6\u4fe1\u606f\u4e2d\uff0c\u6211\u4eec\u53ef\u4ee5\u53d1\u73b0 livenessProbe \u9519\u8bef\u4fe1\u606f\u3002 Events: Type Reason Age From Message ---- ------ ---- ---- ------- Normal Scheduled 17m default-scheduler Successfully assigned dev/nginx-healthcheck-79fc55d944-lknp9 to cka003 Normal Pulled 2m47s (x2 over 17m) kubelet Container image \"nginx:latest\" already present on machine Normal Created 2m47s (x2 over 17m) kubelet Created container nginx-healthcheck Normal Started 2m47s (x2 over 17m) kubelet Started container nginx-healthcheck Warning Unhealthy 2m47s (x4 over 2m57s) kubelet Readiness probe failed: Get \"http://10.244.102.46:80/\": dial tcp 10.244.102.46:80: connect: connection refused Warning Unhealthy 2m47s (x3 over 2m57s) kubelet Liveness probe failed: dial tcp 10.244.102.46:80: connect: connection refused Normal Killing 2m47s kubelet Container nginx-healthcheck failed liveness probe, will be restarted \u5f53 livenessProbe \u68c0\u6d4b\u5230\u5931\u8d25\u540e\uff0c\u5bb9\u5668\u5c06\u81ea\u52a8\u91cd\u65b0\u542f\u52a8\u3002\u6211\u4eec\u4fee\u6539\u7684 default.conf \u6587\u4ef6\u5c06\u88ab\u9ed8\u8ba4\u6587\u4ef6\u66ff\u6362\uff0c\u5bb9\u5668\u72b6\u6001\u5c06\u6062\u590d\u6b63\u5e38\u3002","title":"\u5065\u5eb7\u68c0\u67e5"},{"location":"k8s/cka_cn/foundamentals/casestudy-health-check/#_1","text":"\u6f14\u793a\u573a\u666f\uff1a \u521b\u5efa Deployment \u548c Service \u6a21\u62df\u4e00\u4e2a\u9519\u8bef\uff08\u5220\u9664 index.html\uff09 Pod \u5904\u4e8e\u4e0d\u5065\u5eb7\u72b6\u6001\u5e76\u4ece endpoint \u5217\u8868\u4e2d\u5220\u9664 \u4fee\u590d\u9519\u8bef\uff08\u6062\u590d index.html\uff09 Pod \u56de\u5230\u6b63\u5e38\u72b6\u6001\u5e76\u91cd\u65b0\u52a0\u5165 endpoint \u5217\u8868","title":"\u4e3b\u9898\u8ba8\u8bba:\u5065\u5eb7\u68c0\u67e5"},{"location":"k8s/cka_cn/foundamentals/casestudy-health-check/#deployment-service","text":"\u521b\u5efaDeployment nginx-healthcheck \u548cService nginx-healthcheck \u3002 kubectl apply -f - < nginx-healthcheck-79fc55d944-nwwjc 1/1 Running 0 9s 10.244.112.13 cka002 \u901a\u8fc7\u547d\u4ee4 curl \u6765\u8bbf\u95ee\u4e0a\u9762\u8fd0\u884c\u7ed3\u679c\u4e2dpod\u7684IP\u5730\u5740\u3002 curl 10 .244.102.14 curl 10 .244.112.13 \u5982\u679c\u4e0a\u9762\u547d\u4ee4\u6210\u529f\u6267\u884c\uff0c\u5219\u4f1a\u8fd4\u56deNginx\u4e2d index.html \u7684\u5185\u5bb9\u3002 \u83b7\u53d6\u524d\u9762\u521b\u5efa\u7684Service\u7684\u8be6\u7ec6\u4fe1\u606f\u3002 kubectl describe svc nginx-healthcheck \u8f93\u51fa\u7ed3\u679c\u5982\u4e0b\u3002\u5728 Endpoints \u90e8\u5206\u6211\u4eec\u53ef\u4ee5\u770b\u52302\u4e2apod\u3002 Name : nginx-healthcheck Namespace : dev Labels : Annotations : Selector : name=nginx-healthcheck Type : NodePort IP Family Policy : SingleStack IP Families : IPv4 IP : 11.244.238.20 IPs : 11.244.238.20 Port : 80/TCP TargetPort : 80/TCP NodePort : 31795/TCP Endpoints : 10.244.102.14:80,10.244.112.13:80 Session Affinity : None External Traffic Policy : Cluster Events : \u83b7\u53d6Endpoints\u7684\u4fe1\u606f\u3002 kubectl get endpoints nginx-healthcheck \u8fd0\u884c\u7ed3\u679c NAME ENDPOINTS AGE nginx-healthcheck 10.244.102.14:80,10.244.112.13:80 72s \u81f3\u6b64\uff0c2\u4e2apod nginx-healthcheck \u90fd\u80fd\u6309\u7167\u6211\u4eec\u7684\u671f\u671b\u6b63\u5e38\u5de5\u4f5c\u3002","title":"\u521b\u5efa Deployment \u548c Service"},{"location":"k8s/cka_cn/foundamentals/casestudy-health-check/#readinessprobe","text":"\u8ba9\u6211\u4eec\u901a\u8fc7\u5220\u9664 nginx-healthcheck Pod \u4e2d\u7684 index.html \u6587\u4ef6\u6765\u6a21\u62df\u9519\u8bef\uff0c\u89c2\u5bdf readinessProbe \u7684\u8868\u73b0\u3002 \u9996\u5148\uff0c\u6267\u884c kubectl exec -it -- bash \u547d\u4ee4\u4ee5\u767b\u5f55\u5230 nginx-healthcheck Pod\uff0c\u5e76\u5220\u9664 index.html \u6587\u4ef6\u3002 kubectl exec -it nginx-healthcheck-79fc55d944-jw887 -- bash cd /usr/share/nginx/html/ rm -rf index.html exit \u5728\u6267\u884c\u4e86\u5220\u9664 nginx-healthcheck Pod \u4e2d\u7684 index.html \u6587\u4ef6\u4e4b\u540e\uff0c\u6211\u4eec\u68c0\u67e5\u8be5 Pod \u7684\u72b6\u6001\u3002 kubectl describe pod nginx-healthcheck-79fc55d944-jw887 \u4e0b\u9762\u7684\u8f93\u51fa\u7ed3\u679c\u4e2d\uff0c\u6211\u4eec\u53ef\u4ee5\u770b\u5230 Readiness probe failed \u8fd9\u4e2a\u9519\u8bef\u4e8b\u4ef6\u4fe1\u606f\u3002 ...... Events: Type Reason Age From Message ---- ------ ---- ---- ------- Normal Scheduled 2m8s default-scheduler Successfully assigned dev/nginx-healthcheck-79fc55d944-jw887 to cka003 Normal Pulled 2m7s kubelet Container image \"nginx:latest\" already present on machine Normal Created 2m7s kubelet Created container nginx-healthcheck Normal Started 2m7s kubelet Started container nginx-healthcheck Warning Unhealthy 2s (x2 over 7s) kubelet Readiness probe failed: HTTP probe failed with statuscode: 403 \u68c0\u67e5\u53e6\u4e00\u4e2apod\u3002 kubectl describe pod nginx-healthcheck-79fc55d944-nwwjc \u4e0b\u9762\u7684\u8f93\u51fa\u7ed3\u679c\u4e2d\uff0c\u6ca1\u6709\u53d1\u73b0\u9519\u8bef\u3002 ...... Events: Type Reason Age From Message ---- ------ ---- ---- ------- Normal Scheduled 3m46s default-scheduler Successfully assigned dev/nginx-healthcheck-79fc55d944-nwwjc to cka002 Normal Pulled 3m45s kubelet Container image \"nginx:latest\" already present on machine Normal Created 3m45s kubelet Created container nginx-healthcheck Normal Started 3m45s kubelet Started container nginx-healthcheck \u73b0\u5728\uff0c\u901a\u8fc7 curl \u547d\u4ee4\u6765\u8bbf\u95ee2\u4e2apod\u7684IP\u5730\u5740\uff0c\u6211\u4eec\u6765\u89c2\u5bdf\u4f1a\u5f97\u5230\u600e\u6837\u7684\u7ed3\u679c\u3002 curl 10 .244.102.14 curl 10 .244.112.13 \u8fd0\u884c\u7ed3\u679c\uff1a curl 10.244.102.14 \u5931\u8d25\uff0c\u9519\u8bef\u4fe1\u606f\u662f 403 Forbidden \u3002 curl 10.244.112.13 \u6210\u529f\u3002 \u6211\u4eec\u73b0\u5728\u6765\u67e5\u8be2Nginx service\u5728\u4e00\u4e2apod\u5931\u8d25\u65f6\u7684\u72b6\u6001\u3002 kubectl describe svc nginx-healthcheck \u5728\u4e0b\u9762\u7684\u8f93\u51fa\u7ed3\u679c\u4e2d\uff0c\u6211\u4eec\u770b\u5230Endpoint\u90e8\u5206\u4e2d\u53ea\u6709\u4e00\u4e2apod\u7684\u4fe1\u606f\u3002 Name : nginx-healthcheck Namespace : dev Labels : Annotations : Selector : name=nginx-healthcheck Type : NodePort IP Family Policy : SingleStack IP Families : IPv4 IP : 11.244.238.20 IPs : 11.244.238.20 Port : 80/TCP TargetPort : 80/TCP NodePort : 31795/TCP Endpoints : 10.244.112.13:80 Session Affinity : None External Traffic Policy : Cluster Events : \u540c\u6837\u7684\uff0c\u6211\u4eec\u53ef\u4ee5\u901a\u8fc7\u68c0\u67e5Endpoint\u7684\u4fe1\u606f\uff0c\u4e5f\u80fd\u53d1\u73b0\u53ea\u6709\u4e00\u4e2apod\u6b63\u5728\u8fd0\u884c\u3002 kubectl get endpoints nginx-healthcheck \u8fd0\u884c\u7ed3\u679c\uff1a NAME ENDPOINTS AGE nginx-healthcheck 10.244.112.13:80 6m5s","title":"\u6a21\u62dfreadinessProbe\u9519\u8bef"},{"location":"k8s/cka_cn/foundamentals/casestudy-health-check/#readinessprobe_1","text":"\u73b0\u5728\uff0c\u6211\u4eec\u5728pod\u4e2d\u91cd\u65b0\u521b\u5efa index.html \u6587\u4ef6\uff0c\u6765\u4fee\u590d\u9519\u8bef\u3002 kubectl exec -it nginx-healthcheck-79fc55d944-jw887 -- bash cd /usr/share/nginx/html/ cat > index.html << EOF Welcome to nginx!

Welcome to nginx!

If you see this page, the nginx web server is successfully installed and working. Further configuration is required.

For online documentation and support please refer to nginx.org.
Commercial support is available at nginx.com.

Thank you for using nginx.

EOF exit \u73b0\u5728\u6211\u4eec\u53ef\u4ee5\u770b\u5230\u4e24\u4e2aPod\u5df2\u7ecf\u91cd\u65b0\u52a0\u5165\u4e86Endpoint\u5217\u8868\uff0c\u53ef\u4ee5\u63d0\u4f9b\u670d\u52a1\u4e86\u3002 kubectl describe svc nginx-healthcheck kubectl get endpoints nginx-healthcheck \u91cd\u65b0\u901a\u8fc7 curl \u547d\u4ee4\u8bbf\u95ee2\u4e2apod\u7684IP\u5730\u5740\uff0c\u6211\u4eec\u53ef\u4ee5\u770b\u5230\u5b83\u4eec\u90fd\u5df2\u7ecf\u6062\u590d\u5230\u6b63\u5e38\u72b6\u6001\u4e86\u3002 curl 10 .244.102.14 curl 10 .244.112.13 \u518d\u6b21\u9a8c\u8bc1pod\u7684\u72b6\u6001\u3002 kubectl describe pod nginx-healthcheck-79fc55d944-jw887 \u7ed3\u8bba\uff1a \u901a\u8fc7\u5220\u9664 index.html \u6587\u4ef6\uff0cPod \u8fdb\u5165\u4e0d\u5065\u5eb7\u72b6\u6001\u5e76\u4ece\u7aef\u70b9\u5217\u8868\u4e2d\u5220\u9664\u3002 \u53ea\u6709\u4e00\u4e2a\u5065\u5eb7\u7684 Pod \u53ef\u4ee5\u63d0\u4f9b\u6b63\u5e38\u7684\u670d\u52a1\u3002 \u6e05\u9664\u6f14\u793a\u4e2d\u521b\u5efa\u7684\u4e34\u65f6\u8d44\u6e90\u3002 kubectl delete service nginx-healthcheck kubectl delete deployment nginx-healthcheck","title":"\u4fee\u590dreadinessProbe\u9519\u8bef"},{"location":"k8s/cka_cn/foundamentals/casestudy-health-check/#livenessprobe","text":"\u91cd\u65b0\u521b\u5efadeployment nginx-healthcheck \u548cservice nginx-healthcheck \u3002 Deployment: NAME READY UP-TO-DATE AVAILABLE AGE nginx-healthcheck 0/2 2 0 7s Pods: NAME READY STATUS RESTARTS AGE nginx-healthcheck-79fc55d944-lknp9 1/1 Running 0 96s nginx-healthcheck-79fc55d944-wntmg 1/1 Running 0 96s \u5c06 Nginx \u9ed8\u8ba4\u76d1\u542c\u7aef\u53e3\u4ece 80 \u6539\u4e3a 90 \uff0c\u4ee5\u6a21\u62df livenessProbe \u5931\u8d25\u3002livenessProbe \u901a\u8fc7\u7aef\u53e3 80 \u68c0\u67e5\u751f\u5b58\u72b6\u6001\u3002 kubectl exec -it nginx-healthcheck-79fc55d944-lknp9 -- bash root@nginx-healthcheck-79fc55d944-lknp9:/# cd /etc/nginx/conf.d root@nginx-healthcheck-79fc55d944-lknp9:/etc/nginx/conf.d# sed -i 's/80/90/g' default.conf root@nginx-healthcheck-79fc55d944-lknp9:/etc/nginx/conf.d# nginx -s reload 2022 /07/24 12 :59:45 [ notice ] 79 #79: signal process started Pod\u73b0\u5728\u8868\u73b0\u4e3a\u5931\u8d25\u72b6\u6001\u3002 kubectl describe pod nginx-healthcheck-79fc55d944-lknp9 \u5728pod\u7684\u4e8b\u4ef6\u4fe1\u606f\u4e2d\uff0c\u6211\u4eec\u53ef\u4ee5\u53d1\u73b0 livenessProbe \u9519\u8bef\u4fe1\u606f\u3002 Events: Type Reason Age From Message ---- ------ ---- ---- ------- Normal Scheduled 17m default-scheduler Successfully assigned dev/nginx-healthcheck-79fc55d944-lknp9 to cka003 Normal Pulled 2m47s (x2 over 17m) kubelet Container image \"nginx:latest\" already present on machine Normal Created 2m47s (x2 over 17m) kubelet Created container nginx-healthcheck Normal Started 2m47s (x2 over 17m) kubelet Started container nginx-healthcheck Warning Unhealthy 2m47s (x4 over 2m57s) kubelet Readiness probe failed: Get \"http://10.244.102.46:80/\": dial tcp 10.244.102.46:80: connect: connection refused Warning Unhealthy 2m47s (x3 over 2m57s) kubelet Liveness probe failed: dial tcp 10.244.102.46:80: connect: connection refused Normal Killing 2m47s kubelet Container nginx-healthcheck failed liveness probe, will be restarted \u5f53 livenessProbe \u68c0\u6d4b\u5230\u5931\u8d25\u540e\uff0c\u5bb9\u5668\u5c06\u81ea\u52a8\u91cd\u65b0\u542f\u52a8\u3002\u6211\u4eec\u4fee\u6539\u7684 default.conf \u6587\u4ef6\u5c06\u88ab\u9ed8\u8ba4\u6587\u4ef6\u66ff\u6362\uff0c\u5bb9\u5668\u72b6\u6001\u5c06\u6062\u590d\u6b63\u5e38\u3002","title":"\u6a21\u62dflivenessProbe\u9519\u8bef"},{"location":"k8s/cka_cn/foundamentals/casestudy-operation-resources/","text":"\u4e3b\u9898\u8ba8\u8bba:Kubernetes\u8d44\u6e90\u5e38\u89c1\u64cd\u4f5c \u00b6 \u6f14\u793a\u573a\u666f\uff1a \u8282\u70b9\u6807\u7b7e\uff08Node Label\uff09 \u6ce8\u89e3\uff08Annotation\uff09 \u547d\u540d\u7a7a\u95f4\uff08Namespace\uff09 ServiceAccount \u6388\u6743\uff08ServiceAccount Authorization\uff09 \u6388\u6743\u9ed8\u8ba4 ServiceAccount \u8bbf\u95ee API \u90e8\u7f72\uff08Deployment\uff09 \u66b4\u9732\u670d\u52a1\uff08Expose Service\uff09 \u6269\u5c55\u90e8\u7f72\uff08Scale out the Deployment\uff09 \u6eda\u52a8\u5347\u7ea7\uff08Rolling update\uff09 \u56de\u6eda\u5347\u7ea7\uff08Rolling back update\uff09 \u4e8b\u4ef6\uff08Event\uff09 \u65e5\u5fd7\u8bb0\u5f55\uff08Logging\uff09 \u8282\u70b9\u6807\u7b7e\uff08Node Label\uff09 \u00b6 \u6dfb\u52a0/\u4fee\u6539/\u79fb\u51fa\u8282\u70b9\u6807\u7b7e\u3002 # Update node label kubectl label node cka002 node = demonode # Get node info with label info kubectl get node --show-labels # Search node by label kubectl get node -l node = demonode # Remove a lable of node kubectl label node cka002 node- \u6ce8\u89e3\uff08Annotation\uff09 \u00b6 \u521b\u5efadeployment Nginx \u3002 kubectl create deploy nginx --image = nginx:mainline \u83b7\u53d6\u6ce8\u89e3\u4fe1\u606f kubectl describe deployment/nginx \u8fd0\u884c\u7ed3\u679c\uff1a ...... Labels : app=nginx Annotations : deployment.kubernetes.io/revision : 1 Selector : app=nginx ...... \u6dfb\u52a0\u65b0\u7684\u6ce8\u89e3\u4fe1\u606f\u3002 kubectl annotate deployment nginx owner = James.H \u518d\u6b21\u67e5\u8be2\u6ce8\u89e3\u4fe1\u606f\u5f97\u5230\u5982\u4e0b\u7ed3\u679c\u3002 ...... Labels : app=nginx Annotations : deployment.kubernetes.io/revision : 1 owner : James.H Selector : app=nginx ...... \u66f4\u65b0/\u8986\u76d6\u6ce8\u89e3\u4fe1\u606f\u3002 kubectl annotate deployment/nginx owner = K8s --overwrite \u518d\u6b21\u67e5\u8be2\u6ce8\u89e3\u4fe1\u606f\u5f97\u5230\u5982\u4e0b\u7ed3\u679c\u3002 ...... Annotations : deployment.kubernetes.io/revision : 1 owner : K8s Selector : app=nginx ...... \u79fb\u9664\u6ce8\u89e3\u4fe1\u606f\u3002 kubectl annotate deployment/nginx owner- \u8fd0\u884c\u7ed3\u679c\uff1a ...... Labels : app=nginx Annotations : deployment.kubernetes.io/revision : 1 Selector : app=nginx ...... \u5220\u9664\u4e0a\u9762\u6f14\u793a\u4e2d\u521b\u5efa\u7684\u4e34\u65f6\u8d44\u6e90\u3002 kubectl delete deployment nginx \u547d\u540d\u7a7a\u95f4\uff08Namespace\uff09 \u00b6 \u67e5\u8be2\u5f53\u524d\u53ef\u7528namespace\u3002 kubectl get namespace \u8fd0\u884c\u7ed3\u679c\uff1a NAME STATUS AGE default Active 3h45m dev Active 3h11m kube-node-lease Active 3h45m kube-public Active 3h45m kube-system Active 3h45m \u67e5\u8be2\u67d0\u4e2anamespace\u4e0a\u8fd0\u884c\u7684pod\u4fe1\u606f\u3002 kubectl get pod -n kube-system \u8fd0\u884c\u7ed3\u679c\uff1a NAME READY STATUS RESTARTS AGE calico-kube-controllers-5c64b68895-jr4nl 1/1 Running 0 3h25m calico-node-dsx76 1/1 Running 0 3h25m calico-node-p5rf2 1/1 Running 0 3h25m calico-node-tr22l 1/1 Running 0 3h25m coredns-6d8c4cb4d-g4jxc 1/1 Running 0 3h45m coredns-6d8c4cb4d-sqcvj 1/1 Running 0 3h45m etcd-cka001 1/1 Running 0 3h45m kube-apiserver-cka001 1/1 Running 0 3h45m kube-controller-manager-cka001 1/1 Running 0 3h45m kube-proxy-5cdbj 1/1 Running 0 3h41m kube-proxy-cm4hc 1/1 Running 0 3h45m kube-proxy-g4w52 1/1 Running 0 3h41m kube-scheduler-cka001 1/1 Running 0 3h45m \u67e5\u8be2\u6240\u6709namespace\u4e0a\u7684pod\u4fe1\u606f\u3002 kubectl get pod --all-namespaces kubectl get pod -A ServiceAccount \u6388\u6743\uff08ServiceAccount Authorization\uff09 \u00b6 \u5728 Kubernetes 1.23 \u53ca\u66f4\u4f4e\u7248\u672c\u4e2d\uff0c\u5f53\u6211\u4eec\u521b\u5efa\u4e00\u4e2a\u65b0\u7684\u547d\u540d\u7a7a\u95f4\u65f6\uff0cKubernetes \u4f1a\u81ea\u52a8\u521b\u5efa\u4e00\u4e2a\u540d\u4e3a default \u7684 ServiceAccount \u548c\u4e00\u4e2a\u540d\u4e3a default-token-xxxxx \u7684\u4ee4\u724c\u3002 \u800c\u5728 Kubernetes 1.24 \u4e2d\uff0c\u521b\u5efa\u65b0\u7684\u547d\u540d\u7a7a\u95f4\u65f6\u4ec5\u4f1a\u81ea\u52a8\u521b\u5efa\u4e00\u4e2a\u540d\u4e3a default \u7684 ServiceAccount\uff0c\u9700\u8981\u624b\u52a8\u521b\u5efa\u4e0e default ServiceAccount \u76f8\u5173\u8054\u7684\u4ee4\u724c\u3002 \u4ee5\u4e0b\u662f\u521b\u5efa\u4e00\u4e2a\u540d\u4e3a dev \u7684\u65b0\u547d\u540d\u7a7a\u95f4\u7684\u793a\u4f8b\uff0c\u6211\u4eec\u53ef\u4ee5\u770b\u5230\u5728\u547d\u540d\u7a7a\u95f4 dev \u4e2d\u4ec5\u521b\u5efa\u4e86 ServiceAccount\uff1a default \uff0c\u6ca1\u6709\u4e0e ServiceAccount default \u76f8\u5173\u8054\u7684\u4ee4\u724c\uff08secret\uff09\u3002 kubectl create namespace dev kubectl get serviceaccount -n dev kubectl get secrets -n dev \u6709\u4e00\u4e2a\u9ed8\u8ba4\u7684\u96c6\u7fa4\u89d2\u8272 admin \uff0c\u4f46\u662f\u6ca1\u6709\u5c06\u5176\u7ed1\u5b9a\u5230\u4efb\u4f55\u96c6\u7fa4\u89d2\u8272\u7ed1\u5b9a\uff08clusterrole binding\uff09\u4e2d\u3002 kubectl get clusterrole admin kubectl get clusterrolebinding | grep ClusterRole/admin \u89d2\u8272Role\u548c\u89d2\u8272\u7ed1\u5b9aRoleBinding\u662f\u57fa\u4e8e\u547d\u540d\u7a7a\u95f4\u7684\u3002\u5728\u547d\u540d\u7a7a\u95f4 dev \u4e2d\uff0c\u6ca1\u6709\u89d2\u8272\u548c\u89d2\u8272\u7ed1\u5b9a\u3002 kubectl get role -n dev kubectl get rolebinding -n dev \u5728 Kubernetes \u96c6\u7fa4\u4e2d\uff0cSecret \u662f\u4e00\u4e2a\u5bf9\u8c61\uff0c\u7528\u4e8e\u5b58\u50a8\u654f\u611f\u4fe1\u606f\uff0c\u5982\u7528\u6237\u540d\u3001\u5bc6\u7801\u548c\u4ee4\u724c\u7b49\u3002Secret \u7684\u76ee\u6807\u662f\u5bf9\u51ed\u636e\u8fdb\u884c\u7f16\u7801\u6216\u54c8\u5e0c\u5316\u3002\u8fd9\u4e9b\u51ed\u636e\u53ef\u4ee5\u5728\u5404\u79cd Pod \u5b9a\u4e49\u6587\u4ef6\u4e2d\u91cd\u590d\u4f7f\u7528\u3002 kubernetes.io/service-account-token \u7c7b\u578b\u7684 Secret \u7528\u4e8e\u5b58\u50a8\u6807\u8bc6\u670d\u52a1\u8d26\u6237\u7684\u4ee4\u724c\u3002\u4f7f\u7528\u6b64\u7c7b\u578b\u7684 Secret \u65f6\uff0c\u9700\u8981\u786e\u4fdd kubernetes.io/service-account.name \u6ce8\u91ca\u8bbe\u7f6e\u4e3a\u73b0\u6709\u670d\u52a1\u8d26\u6237\u540d\u79f0\u3002 \u8ba9\u6211\u4eec\u5728 dev \u547d\u540d\u7a7a\u95f4\u4e2d\u4e3a ServiceAccount default \u521b\u5efa\u4e00\u4e2a\u4ee4\u724c\u3002 kubectl apply -f - << EOF apiVersion: v1 kind: Secret metadata: name: default-token-dev namespace: dev annotations: kubernetes.io/service-account.name: \"default\" type: kubernetes.io/service-account-token EOF \u73b0\u5728\u5728 dev \u547d\u540d\u7a7a\u95f4\u4e2d\u521b\u5efa\u4e86 ServiceAccount default \u548c Secret\uff08\u4ee4\u724c\uff09 default-token-dev \u3002 kubectl get serviceaccount -n dev kubectl get secrets -n dev \u83b7\u53d6\u9ed8\u8ba4 Service Account \u7684 token\uff0c\u5e76\u8d4b\u503c\u7ed9\u73af\u5883\u53d8\u91cf $TOKEN \u3002 TOKEN = $( kubectl -n dev describe secret $( kubectl -n dev get secrets | grep default | cut -f1 -d ' ' ) | grep -E '^token' | cut -f2 -d ':' | tr -d ' ' ) echo $TOKEN \u83b7\u53d6 API Service \u5730\u5740\uff0c\u5e76\u8d4b\u503c\u7ed9\u73af\u5883\u53d8\u91cf $APISERVER \u3002 APISERVER = $( kubectl config view | grep https | cut -f 2 - -d \":\" | tr -d \" \" ) echo $APISERVER \u901a\u8fc7 API Server \u4ee5 JSON \u683c\u5f0f\u83b7\u53d6\u547d\u540d\u7a7a\u95f4 dev \u4e2d\u7684 Pod \u8d44\u6e90\u3002 curl $APISERVER /api/v1/namespaces/dev/pods --header \"Authorization: Bearer $TOKEN \" --insecure \u6211\u4eec\u5c06\u6536\u5230\u201c403 forbidden\u201d\u7684\u9519\u8bef\u6d88\u606f\u3002ServiceAccount default \u6ca1\u6709\u8bbf\u95ee\u540d\u79f0\u7a7a\u95f4 dev \u4e2d\u7684Pod\u7684\u6388\u6743\u3002 \u8ba9\u6211\u4eec\u521b\u5efa\u4e00\u4e2a\u540d\u4e3a rolebinding-admin \u7684RoleBinding\uff0c\u5c06\u96c6\u7fa4\u89d2\u8272 admin \u7ed1\u5b9a\u5230\u540d\u79f0\u7a7a\u95f4 dev \u4e2d\u7684ServiceAccount default \u3002 \u56e0\u6b64\uff0cServiceAccount default \u88ab\u6388\u4e88\u5728\u540d\u79f0\u7a7a\u95f4 dev \u4e2d\u7684\u7ba1\u7406\u5458\u6388\u6743\u3002 # Usage: kubectl create rolebinding --clusterrole = --serviceaccount = : --namespace = # Crate rolebinding: kubectl create rolebinding rolebinding-admin --clusterrole = admin --serviceaccount = dev:default --namespace = dev \u6267\u884c\u547d\u4ee4 kubectl get rolebinding -n dev \uff0c\u5f97\u5230\u7c7b\u4f3c\u5982\u4e0b\u7684\u7ed3\u679c\u3002 NAME ROLE AGE rolebinding-admin ClusterRole/admin 10s \u518d\u6b21\u901a\u8fc7 API Server \u4ee5 JSON \u683c\u5f0f\u83b7\u53d6\u547d\u540d\u7a7a\u95f4 dev \u4e2d\u7684 Pod \u8d44\u6e90\uff0c\u6210\u529f\u3002 curl $APISERVER /api/v1/namespaces/dev/pods --header \"Authorization: Bearer $TOKEN \" --insecure \u5220\u9664\u4e0a\u9762\u6f14\u793a\u4e2d\u521b\u5efa\u7684\u4e34\u65f6\u8d44\u6e90\u3002 kubectl delete namespace dev \u90e8\u7f72\uff08Deployment\uff09 \u00b6 \u521b\u5efa\u4e00\u4e2a Ubuntu Pod \u4ee5\u8fdb\u884c\u64cd\u4f5c\uff0c\u5e76\u9644\u52a0\u5230\u8fd0\u884c\u4e2d\u7684 Pod\u3002 kubectl create -f - << EOF apiVersion: v1 kind: Pod metadata: name: ubuntu labels: app: ubuntu spec: containers: - name: ubuntu image: ubuntu:latest command: [\"/bin/sleep\", \"3650d\"] imagePullPolicy: IfNotPresent restartPolicy: Always EOF kubectl exec --stdin --tty ubuntu -- /bin/bash \u521b\u5efa\u4e00\u4e2a Deployment\uff0c\u9009\u9879 --image \u6307\u5b9a\u4e86\u4e00\u4e2a\u955c\u50cf\uff0c\u9009\u9879 --port \u6307\u5b9a\u4e86\u5916\u90e8\u8bbf\u95ee\u7684\u7aef\u53e3\u3002 \u5728\u521b\u5efa Deployment \u7684\u540c\u65f6\u4e5f\u4f1a\u521b\u5efa\u4e00\u4e2a Pod\u3002 kubectl create deployment myapp --image = docker.io/jocatalin/kubernetes-bootcamp:v1 --replicas = 1 --port = 8080 \u67e5\u8be2deployment\u7684\u72b6\u6001\u3002 kubectl get deployment myapp -o wide \u8f93\u51fa\u7ed3\u679c\uff1a NAME READY UP-TO-DATE AVAILABLE AGE CONTAINERS IMAGES SELECTOR myapp 1/1 1 1 79s kubernetes-bootcamp docker.io/jocatalin/kubernetes-bootcamp:v1 app=myapp \u67e5\u8be2deployment\u7684\u8be6\u7ec6\u4fe1\u606f\u3002 kubectl describe deployment myapp \u8fd0\u884c\u7ed3\u679c\uff1a Name: myapp Namespace: dev CreationTimestamp: Sat, 23 Jul 2022 14:36:43 +0800 Labels: app=myapp Annotations: deployment.kubernetes.io/revision: 1 Selector: app=myapp Replicas: 1 desired | 1 updated | 1 total | 1 available | 0 unavailable StrategyType: RollingUpdate MinReadySeconds: 0 RollingUpdateStrategy: 25% max unavailable, 25% max surge Pod Template: Labels: app=myapp Containers: kubernetes-bootcamp: Image: docker.io/jocatalin/kubernetes-bootcamp:v1 Port: 8080/TCP Host Port: 0/TCP Environment: Mounts: Volumes: Conditions: Type Status Reason ---- ------ ------ Available True MinimumReplicasAvailable Progressing True NewReplicaSetAvailable OldReplicaSets: NewReplicaSet: myapp-b5d775f5d (1/1 replicas created) Events: Type Reason Age From Message ---- ------ ---- ---- ------- Normal ScalingReplicaSet 95s deployment-controller Scaled up replica set myapp-b5d775f5d to 1 \u66b4\u9732\u670d\u52a1\uff08Expose Service\uff09 \u00b6 \u83b7\u53d6\u4e0a\u9762\u7ec3\u4e60\u4e2d\u521b\u5efa\u7684pod\u548cdeployment\u7684\u4fe1\u606f\u3002 kubectl get deployment myapp -o wide kubectl get pod -o wide \u8fd0\u884c\u7ed3\u679c\uff1a NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES myapp-b5d775f5d-cx8dx 1/1 Running 0 2m34s 10.244.102.7 cka003 \u6267\u884c\u547d\u4ee4 curl 10.244.102.7:8080 \uff0c\u4ee5\u53d1\u9001HTTP\u8bf7\u6c42\u5230pod\u7684\u7aef\u53e3\uff0c\u5f97\u5230\u5982\u4e0b\u7ed3\u679c\u3002 Hello Kubernetes bootcamp! | Running on: myapp-b5d775f5d-6jtgs | v=1 \u8981\u4f7f Pod \u53ef\u4ee5\u4ece\u5916\u90e8\u8bbf\u95ee\uff0c\u9700\u8981\u5c06\u7aef\u53e3 8080 \u66b4\u9732\u7ed9\u8282\u70b9\u7aef\u53e3\uff08NodePort\uff09\u3002\u8fd9\u9700\u8981\u521b\u5efa\u4e00\u4e2a\u76f8\u5173\u7684 Service\u3002 kubectl expose deployment myapp --type = NodePort --port = 8080 \u6267\u884c\u547d\u4ee4 kubectl get svc myapp -o wide \uff0c\u83b7\u53d6service myapp \u7684\u8be6\u7ec6\u4fe1\u606f\u3002 NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE SELECTOR myapp NodePort 11.244.74.3 8080:30514/TCP 7s app=myapp \u6267\u884c\u547d\u4ee4 curl 11.244.74.3:8080 \uff0c\u4ee5\u53d1\u9001HTTP\u8bf7\u6c42\u5230service\u7684\u7aef\u53e3\uff0c\u5f97\u5230\u5982\u4e0b\u7ed3\u679c\u3002 Hello Kubernetes bootcamp! | Running on: myapp-b5d775f5d-cx8dx | v=1 \u83b7\u53d6service\u7684\u8be6\u7ec6\u4fe1\u606f\u3002 kubectl get svc myapp -o yaml kubectl describe svc myapp \u6267\u884c kubectl get endpoints myapp -o wide \u547d\u4ee4\u4ee5\u83b7\u53d6\u76f8\u5173\u7684 myapp \u7aef\u70b9\uff08endpoint\uff09\u7684\u8be6\u7ec6\u4fe1\u606f\u3002 NAME ENDPOINTS AGE myapp 10.244.102.7:8080 43s \u63d0\u793a\uff1a Endpoint\uff08\u7aef\u70b9\uff09\u662f\u4e00\u4e2aKubernetes\u4e2d\u7684\u5bf9\u8c61\uff0c\u7528\u4e8e\u5b58\u50a8\u53ef\u4ee5\u88ab\u670d\u52a1\u8bbf\u95ee\u7684Pod\u7684\u7f51\u7edc\u5730\u5740\u548c\u7aef\u53e3\u4fe1\u606f\u3002 \u5f53Service\u521b\u5efa\u65f6\uff0cKubernetes\u4f1a\u81ea\u52a8\u521b\u5efa\u548c\u66f4\u65b0\u76f8\u5e94\u7684Endpoint\u3002 Endpoint\u662f\u7531kube-proxy\u81ea\u52a8\u521b\u5efa\u548c\u7ef4\u62a4\u7684\uff0c\u5e76\u6839\u636e\u9009\u62e9\u5668\u5339\u914d\u5bf9\u5e94\u7684Service\u548cPod\u3002 \u80fd\u6210\u529f\u7684\u53d1\u9001HTTP\u8bf7\u6c42\u5230service\u548c\u8282\u70b9\uff0c\u8bf4\u660epod\u7684\u7aef\u53e3 8080 \u88ab\u6b63\u786e\u7684\u6620\u5c04\u5230\u8282\u70b9\u7684\u7aef\u53e3 32566 \u3002 \u6267\u884c\u547d\u4ee4curl :30514\uff0c\u53d1\u9001HTTP\u8bf7\u6c42\u5230\u8282\u70b9 cka003 \u4e0a\u5bf9\u5e94\u7684\u7aef\u53e3\u3002 Hello Kubernetes bootcamp! | Running on: myapp-b5d775f5d-6jtgs | v=1 \u767b\u5f55\u8fdb\u5165Ubuntu pod\uff0c\u6211\u4eec\u53ef\u4ee5\u901a\u8fc7\u53d1\u9001HTTP\u8bf7\u6c42\u5230 myapp \u6240\u6620\u5c04\u7684service\u3001pod\u548c\u8282\u70b9\u7684\u7aef\u53e3\u3002 kubectl exec --stdin --tty ubuntu -- /bin/bash curl 10 .244.102.7:8080 curl 11 .244.74.3:8080 curl :30514 Hello Kubernetes bootcamp! | Running on: myapp-b5d775f5d-6jtgs | v = 1 \u6269\u5bb9\u90e8\u7f72\uff08Scale out the Deployment\uff09 \u00b6 Scale out by replicaset. We set three replicasets to scale out deployment myapp . The number of deployment myapp is now three. \u901a\u8fc7\u526f\u672c\u96c6replicaset\u8fdb\u884c\u6269\u5c55\u3002\u6211\u4eec\u901a\u8fc7\u6307\u5b9a\u526f\u672c\u96c6\u7684\u65b9\u5f0f\uff0c\u5bf9deployment myapp \u8fdb\u884c\u6269\u5c55\u90e8\u7f72\uff0c\u4e0b\u9762\u4f8b\u5b50\u4e2d\uff0cdeployment myapp \u7684\u526f\u672c\u6570\u662f\u4e09\u4e2a\u3002 kubectl scale deployment myapp --replicas = 3 \u67e5\u8be2deployment\u7684\u4fe1\u606f\u3002 kubectl get deployment myapp \u67e5\u8be2replicaset\u7684\u4fe1\u606f kubectl get replicaset \u6eda\u52a8\u5347\u7ea7\uff08Rolling update\uff09 \u00b6 \u547d\u4ee4\u7528\u6cd5\uff1a kubectl set image (-f \u6587\u4ef6\u540d | \u7c7b\u578b \u540d\u79f0) \u5bb9\u5668\u540d\u79f0_1=\u5bb9\u5668\u955c\u50cf_1 ... \u5bb9\u5668\u540d\u79f0_N=\u5bb9\u5668\u955c\u50cf_N \u3002 \u4f7f\u7528\u547d\u4ee4 kubectl get deployment \uff0c\u6211\u4eec\u53ef\u4ee5\u83b7\u53d6deployment myapp \u548c\u76f8\u5173\u5bb9\u5668 kubernetes-bootcamp \u3002 kubectl get deployment myapp -o wide \u4f7f\u7528\u547d\u4ee4 kubectl set image \u6765\u66f4\u65b0\u591a\u4e2a\u7248\u672c\u7684\u955c\u50cf\uff0c\u5e76\u4f7f\u7528\u9009\u9879 --record \u5c06\u66f4\u6539\u8bb0\u5f55\u5728\u90e8\u7f72\u7684\u6ce8\u91ca\u4e2d\u3002 kubectl set image deployment/myapp kubernetes-bootcamp = docker.io/jocatalin/kubernetes-bootcamp:v2 --record \u67e5\u8be2\u5f53\u524dreplicas\u7684\u72b6\u6001\u3002 kubectl get replicaset -o wide -l app = myapp \u8f93\u51fa\u7ed3\u679c\u5982\u4e0b\uff0cpod\u6b63\u4ee5\u65b0\u7684\u526f\u672c\u96c6replicas\u6570\u91cf\u8fd0\u884c\u3002 NAME DESIRED CURRENT READY AGE CONTAINERS IMAGES SELECTOR myapp-5dbd68cc99 1 1 0 8s kubernetes-bootcamp docker.io/jocatalin/kubernetes-bootcamp:v2 app=myapp,pod-template-hash=5dbd68cc99 myapp-b5d775f5d 3 3 3 14m kubernetes-bootcamp docker.io/jocatalin/kubernetes-bootcamp:v1 app=myapp,pod-template-hash=b5d775f5d \u6211\u4eec\u53ef\u4ee5\u5728\u5bf9\u5e94\u7684yaml\u6587\u4ef6\u4e2d metadata.annotations \u90e8\u5206\u83b7\u53d6\u53d8\u66f4\u5386\u53f2\u8bb0\u5f55\u3002 kubectl get deployment myapp -o yaml \u8fd0\u884c\u7ed3\u679c\uff1a apiVersion : apps/v1 kind : Deployment metadata : annotations : deployment.kubernetes.io/revision : \"2\" kubernetes.io/change-cause : kubectl set image deployment/myapp kubernetes-bootcamp=docker.io/jocatalin/kubernetes-bootcamp:v2 --record=true ...... \u6211\u4eec\u4e5f\u53ef\u4ee5\u4f7f\u7528\u547d\u4ee4 kubectl rollout history \u83b7\u53d6\u66f4\u65b0\u5386\u53f2\u8bb0\u5f55\uff0c\u5e76\u4f7f\u7528\u7279\u5b9a\u4fee\u8ba2\u7248\u672c\u53f7 --revision= \u663e\u793a\u8be6\u7ec6\u4fe1\u606f\u3002 kubectl rollout history deployment/myapp \u8fd0\u884c\u7ed3\u679c\uff1a deployment.apps/myapp REVISION CHANGE-CAUSE 1 2 kubectl set image deployment/myapp kubernetes-bootcamp=docker.io/jocatalin/kubernetes-bootcamp:v2 --record=true \u83b7\u53d6\u7279\u5b9a\u7248\u672c\u56de\u6eda\u5386\u53f2\u8bb0\u5f55\u3002 kubectl rollout history deployment/myapp --revision = 2 \u6267\u884c\u547d\u4ee4 kubectl rollout undo \u53ef\u4ee5\u56de\u6eda\u5230\u4e0a\u4e00\u4e2a\u7248\u672c\uff0c\u6216\u4f7f\u7528\u9009\u9879 --to-revision= \u56de\u6eda\u5230\u6307\u5b9a\u7684\u7248\u672c\u3002 kubectl rollout undo deployment/myapp --to-revision = 1 \u7248\u672c 1 \u73b0\u5728\u5df2\u7ecf\u88ab\u66ff\u6362\u6210\u7248\u672c 3 \u4e86\u3002 kubectl rollout history deployment/myapp \u8fd0\u884c\u7ed3\u679c\uff1a deployment.apps/myapp REVISION CHANGE-CAUSE 2 kubectl set image deployment/myapp kubernetes-bootcamp=docker.io/jocatalin/kubernetes-bootcamp:v2 --record=true 3 \u4e8b\u4ef6\uff08Event\uff09 \u00b6 \u83b7\u53d6\u6307\u5b9apod\u7684\u4e8b\u4ef6\u4fe1\u606f\u3002 kubectl describe pod myapp-b5d775f5d-jlx6g \u8f93\u51fa\u7ed3\u679c\uff1a ...... Events: Type Reason Age From Message ---- ------ ---- ---- ------- Normal Scheduled 54s default-scheduler Successfully assigned dev/myapp-b5d775f5d-jlx6g to cka003 Normal Pulled 53s kubelet Container image \"docker.io/jocatalin/kubernetes-bootcamp:v1\" already present on machine Normal Created 53s kubelet Created container kubernetes-bootcamp Normal Started 53s kubelet Started container kubernetes-bootcamp \u67e5\u8be2\u96c6\u7fa4\u7684\u4e8b\u4ef6\u4fe1\u606f\u3002 kubectl get event \u65e5\u5fd7\u8bb0\u5f55\uff08Logging\uff09 \u00b6 \u67e5\u8be2pod\u7684\u65e5\u5fd7\u4fe1\u606f\u3002 kubectl logs -f kubectl logs -f -c \u4f8b\u5982\uff1a kubectl logs -f myapp-b5d775f5d-jlx6g \u8fd0\u884c\u7ed3\u679c\uff1a Kubernetes Bootcamp App Started At: 2022-07-23T06:54:18.532Z | Running On: myapp-b5d775f5d-jlx6g \u67e5\u8be2K8s\u4e0d\u540c\u7ec4\u4ef6\u7684\u65e5\u5fd7\u4fe1\u606f\u3002 kubectl logs kube-apiserver-cka001 -n kube-system kubectl logs kube-controller-manager-cka001 -n kube-system kubectl logs kube-scheduler-cka001 -n kube-system kubectl logs etcd-cka001 -n kube-system systemctl status kubelet journalctl -fu kubelet kubectl logs kube-proxy-5cdbj -n kube-system \u5220\u9664\u6f14\u793a\u4e2d\u521b\u5efa\u7684\u4e34\u65f6\u8d44\u6e90\u3002 kubectl delete service myapp kubectl delete deployment myapp","title":"Kubernetes\u8d44\u6e90\u5e38\u89c1\u64cd\u4f5c"},{"location":"k8s/cka_cn/foundamentals/casestudy-operation-resources/#kubernetes","text":"\u6f14\u793a\u573a\u666f\uff1a \u8282\u70b9\u6807\u7b7e\uff08Node Label\uff09 \u6ce8\u89e3\uff08Annotation\uff09 \u547d\u540d\u7a7a\u95f4\uff08Namespace\uff09 ServiceAccount \u6388\u6743\uff08ServiceAccount Authorization\uff09 \u6388\u6743\u9ed8\u8ba4 ServiceAccount \u8bbf\u95ee API \u90e8\u7f72\uff08Deployment\uff09 \u66b4\u9732\u670d\u52a1\uff08Expose Service\uff09 \u6269\u5c55\u90e8\u7f72\uff08Scale out the Deployment\uff09 \u6eda\u52a8\u5347\u7ea7\uff08Rolling update\uff09 \u56de\u6eda\u5347\u7ea7\uff08Rolling back update\uff09 \u4e8b\u4ef6\uff08Event\uff09 \u65e5\u5fd7\u8bb0\u5f55\uff08Logging\uff09","title":"\u4e3b\u9898\u8ba8\u8bba:Kubernetes\u8d44\u6e90\u5e38\u89c1\u64cd\u4f5c"},{"location":"k8s/cka_cn/foundamentals/casestudy-operation-resources/#node-label","text":"\u6dfb\u52a0/\u4fee\u6539/\u79fb\u51fa\u8282\u70b9\u6807\u7b7e\u3002 # Update node label kubectl label node cka002 node = demonode # Get node info with label info kubectl get node --show-labels # Search node by label kubectl get node -l node = demonode # Remove a lable of node kubectl label node cka002 node-","title":"\u8282\u70b9\u6807\u7b7e\uff08Node Label\uff09"},{"location":"k8s/cka_cn/foundamentals/casestudy-operation-resources/#annotation","text":"\u521b\u5efadeployment Nginx \u3002 kubectl create deploy nginx --image = nginx:mainline \u83b7\u53d6\u6ce8\u89e3\u4fe1\u606f kubectl describe deployment/nginx \u8fd0\u884c\u7ed3\u679c\uff1a ...... Labels : app=nginx Annotations : deployment.kubernetes.io/revision : 1 Selector : app=nginx ...... \u6dfb\u52a0\u65b0\u7684\u6ce8\u89e3\u4fe1\u606f\u3002 kubectl annotate deployment nginx owner = James.H \u518d\u6b21\u67e5\u8be2\u6ce8\u89e3\u4fe1\u606f\u5f97\u5230\u5982\u4e0b\u7ed3\u679c\u3002 ...... Labels : app=nginx Annotations : deployment.kubernetes.io/revision : 1 owner : James.H Selector : app=nginx ...... \u66f4\u65b0/\u8986\u76d6\u6ce8\u89e3\u4fe1\u606f\u3002 kubectl annotate deployment/nginx owner = K8s --overwrite \u518d\u6b21\u67e5\u8be2\u6ce8\u89e3\u4fe1\u606f\u5f97\u5230\u5982\u4e0b\u7ed3\u679c\u3002 ...... Annotations : deployment.kubernetes.io/revision : 1 owner : K8s Selector : app=nginx ...... \u79fb\u9664\u6ce8\u89e3\u4fe1\u606f\u3002 kubectl annotate deployment/nginx owner- \u8fd0\u884c\u7ed3\u679c\uff1a ...... Labels : app=nginx Annotations : deployment.kubernetes.io/revision : 1 Selector : app=nginx ...... \u5220\u9664\u4e0a\u9762\u6f14\u793a\u4e2d\u521b\u5efa\u7684\u4e34\u65f6\u8d44\u6e90\u3002 kubectl delete deployment nginx","title":"\u6ce8\u89e3\uff08Annotation\uff09"},{"location":"k8s/cka_cn/foundamentals/casestudy-operation-resources/#namespace","text":"\u67e5\u8be2\u5f53\u524d\u53ef\u7528namespace\u3002 kubectl get namespace \u8fd0\u884c\u7ed3\u679c\uff1a NAME STATUS AGE default Active 3h45m dev Active 3h11m kube-node-lease Active 3h45m kube-public Active 3h45m kube-system Active 3h45m \u67e5\u8be2\u67d0\u4e2anamespace\u4e0a\u8fd0\u884c\u7684pod\u4fe1\u606f\u3002 kubectl get pod -n kube-system \u8fd0\u884c\u7ed3\u679c\uff1a NAME READY STATUS RESTARTS AGE calico-kube-controllers-5c64b68895-jr4nl 1/1 Running 0 3h25m calico-node-dsx76 1/1 Running 0 3h25m calico-node-p5rf2 1/1 Running 0 3h25m calico-node-tr22l 1/1 Running 0 3h25m coredns-6d8c4cb4d-g4jxc 1/1 Running 0 3h45m coredns-6d8c4cb4d-sqcvj 1/1 Running 0 3h45m etcd-cka001 1/1 Running 0 3h45m kube-apiserver-cka001 1/1 Running 0 3h45m kube-controller-manager-cka001 1/1 Running 0 3h45m kube-proxy-5cdbj 1/1 Running 0 3h41m kube-proxy-cm4hc 1/1 Running 0 3h45m kube-proxy-g4w52 1/1 Running 0 3h41m kube-scheduler-cka001 1/1 Running 0 3h45m \u67e5\u8be2\u6240\u6709namespace\u4e0a\u7684pod\u4fe1\u606f\u3002 kubectl get pod --all-namespaces kubectl get pod -A","title":"\u547d\u540d\u7a7a\u95f4\uff08Namespace\uff09"},{"location":"k8s/cka_cn/foundamentals/casestudy-operation-resources/#serviceaccount-serviceaccount-authorization","text":"\u5728 Kubernetes 1.23 \u53ca\u66f4\u4f4e\u7248\u672c\u4e2d\uff0c\u5f53\u6211\u4eec\u521b\u5efa\u4e00\u4e2a\u65b0\u7684\u547d\u540d\u7a7a\u95f4\u65f6\uff0cKubernetes \u4f1a\u81ea\u52a8\u521b\u5efa\u4e00\u4e2a\u540d\u4e3a default \u7684 ServiceAccount \u548c\u4e00\u4e2a\u540d\u4e3a default-token-xxxxx \u7684\u4ee4\u724c\u3002 \u800c\u5728 Kubernetes 1.24 \u4e2d\uff0c\u521b\u5efa\u65b0\u7684\u547d\u540d\u7a7a\u95f4\u65f6\u4ec5\u4f1a\u81ea\u52a8\u521b\u5efa\u4e00\u4e2a\u540d\u4e3a default \u7684 ServiceAccount\uff0c\u9700\u8981\u624b\u52a8\u521b\u5efa\u4e0e default ServiceAccount \u76f8\u5173\u8054\u7684\u4ee4\u724c\u3002 \u4ee5\u4e0b\u662f\u521b\u5efa\u4e00\u4e2a\u540d\u4e3a dev \u7684\u65b0\u547d\u540d\u7a7a\u95f4\u7684\u793a\u4f8b\uff0c\u6211\u4eec\u53ef\u4ee5\u770b\u5230\u5728\u547d\u540d\u7a7a\u95f4 dev \u4e2d\u4ec5\u521b\u5efa\u4e86 ServiceAccount\uff1a default \uff0c\u6ca1\u6709\u4e0e ServiceAccount default \u76f8\u5173\u8054\u7684\u4ee4\u724c\uff08secret\uff09\u3002 kubectl create namespace dev kubectl get serviceaccount -n dev kubectl get secrets -n dev \u6709\u4e00\u4e2a\u9ed8\u8ba4\u7684\u96c6\u7fa4\u89d2\u8272 admin \uff0c\u4f46\u662f\u6ca1\u6709\u5c06\u5176\u7ed1\u5b9a\u5230\u4efb\u4f55\u96c6\u7fa4\u89d2\u8272\u7ed1\u5b9a\uff08clusterrole binding\uff09\u4e2d\u3002 kubectl get clusterrole admin kubectl get clusterrolebinding | grep ClusterRole/admin \u89d2\u8272Role\u548c\u89d2\u8272\u7ed1\u5b9aRoleBinding\u662f\u57fa\u4e8e\u547d\u540d\u7a7a\u95f4\u7684\u3002\u5728\u547d\u540d\u7a7a\u95f4 dev \u4e2d\uff0c\u6ca1\u6709\u89d2\u8272\u548c\u89d2\u8272\u7ed1\u5b9a\u3002 kubectl get role -n dev kubectl get rolebinding -n dev \u5728 Kubernetes \u96c6\u7fa4\u4e2d\uff0cSecret \u662f\u4e00\u4e2a\u5bf9\u8c61\uff0c\u7528\u4e8e\u5b58\u50a8\u654f\u611f\u4fe1\u606f\uff0c\u5982\u7528\u6237\u540d\u3001\u5bc6\u7801\u548c\u4ee4\u724c\u7b49\u3002Secret \u7684\u76ee\u6807\u662f\u5bf9\u51ed\u636e\u8fdb\u884c\u7f16\u7801\u6216\u54c8\u5e0c\u5316\u3002\u8fd9\u4e9b\u51ed\u636e\u53ef\u4ee5\u5728\u5404\u79cd Pod \u5b9a\u4e49\u6587\u4ef6\u4e2d\u91cd\u590d\u4f7f\u7528\u3002 kubernetes.io/service-account-token \u7c7b\u578b\u7684 Secret \u7528\u4e8e\u5b58\u50a8\u6807\u8bc6\u670d\u52a1\u8d26\u6237\u7684\u4ee4\u724c\u3002\u4f7f\u7528\u6b64\u7c7b\u578b\u7684 Secret \u65f6\uff0c\u9700\u8981\u786e\u4fdd kubernetes.io/service-account.name \u6ce8\u91ca\u8bbe\u7f6e\u4e3a\u73b0\u6709\u670d\u52a1\u8d26\u6237\u540d\u79f0\u3002 \u8ba9\u6211\u4eec\u5728 dev \u547d\u540d\u7a7a\u95f4\u4e2d\u4e3a ServiceAccount default \u521b\u5efa\u4e00\u4e2a\u4ee4\u724c\u3002 kubectl apply -f - << EOF apiVersion: v1 kind: Secret metadata: name: default-token-dev namespace: dev annotations: kubernetes.io/service-account.name: \"default\" type: kubernetes.io/service-account-token EOF \u73b0\u5728\u5728 dev \u547d\u540d\u7a7a\u95f4\u4e2d\u521b\u5efa\u4e86 ServiceAccount default \u548c Secret\uff08\u4ee4\u724c\uff09 default-token-dev \u3002 kubectl get serviceaccount -n dev kubectl get secrets -n dev \u83b7\u53d6\u9ed8\u8ba4 Service Account \u7684 token\uff0c\u5e76\u8d4b\u503c\u7ed9\u73af\u5883\u53d8\u91cf $TOKEN \u3002 TOKEN = $( kubectl -n dev describe secret $( kubectl -n dev get secrets | grep default | cut -f1 -d ' ' ) | grep -E '^token' | cut -f2 -d ':' | tr -d ' ' ) echo $TOKEN \u83b7\u53d6 API Service \u5730\u5740\uff0c\u5e76\u8d4b\u503c\u7ed9\u73af\u5883\u53d8\u91cf $APISERVER \u3002 APISERVER = $( kubectl config view | grep https | cut -f 2 - -d \":\" | tr -d \" \" ) echo $APISERVER \u901a\u8fc7 API Server \u4ee5 JSON \u683c\u5f0f\u83b7\u53d6\u547d\u540d\u7a7a\u95f4 dev \u4e2d\u7684 Pod \u8d44\u6e90\u3002 curl $APISERVER /api/v1/namespaces/dev/pods --header \"Authorization: Bearer $TOKEN \" --insecure \u6211\u4eec\u5c06\u6536\u5230\u201c403 forbidden\u201d\u7684\u9519\u8bef\u6d88\u606f\u3002ServiceAccount default \u6ca1\u6709\u8bbf\u95ee\u540d\u79f0\u7a7a\u95f4 dev \u4e2d\u7684Pod\u7684\u6388\u6743\u3002 \u8ba9\u6211\u4eec\u521b\u5efa\u4e00\u4e2a\u540d\u4e3a rolebinding-admin \u7684RoleBinding\uff0c\u5c06\u96c6\u7fa4\u89d2\u8272 admin \u7ed1\u5b9a\u5230\u540d\u79f0\u7a7a\u95f4 dev \u4e2d\u7684ServiceAccount default \u3002 \u56e0\u6b64\uff0cServiceAccount default \u88ab\u6388\u4e88\u5728\u540d\u79f0\u7a7a\u95f4 dev \u4e2d\u7684\u7ba1\u7406\u5458\u6388\u6743\u3002 # Usage: kubectl create rolebinding --clusterrole = --serviceaccount = : --namespace = # Crate rolebinding: kubectl create rolebinding rolebinding-admin --clusterrole = admin --serviceaccount = dev:default --namespace = dev \u6267\u884c\u547d\u4ee4 kubectl get rolebinding -n dev \uff0c\u5f97\u5230\u7c7b\u4f3c\u5982\u4e0b\u7684\u7ed3\u679c\u3002 NAME ROLE AGE rolebinding-admin ClusterRole/admin 10s \u518d\u6b21\u901a\u8fc7 API Server \u4ee5 JSON \u683c\u5f0f\u83b7\u53d6\u547d\u540d\u7a7a\u95f4 dev \u4e2d\u7684 Pod \u8d44\u6e90\uff0c\u6210\u529f\u3002 curl $APISERVER /api/v1/namespaces/dev/pods --header \"Authorization: Bearer $TOKEN \" --insecure \u5220\u9664\u4e0a\u9762\u6f14\u793a\u4e2d\u521b\u5efa\u7684\u4e34\u65f6\u8d44\u6e90\u3002 kubectl delete namespace dev","title":"ServiceAccount \u6388\u6743\uff08ServiceAccount Authorization\uff09"},{"location":"k8s/cka_cn/foundamentals/casestudy-operation-resources/#deployment","text":"\u521b\u5efa\u4e00\u4e2a Ubuntu Pod \u4ee5\u8fdb\u884c\u64cd\u4f5c\uff0c\u5e76\u9644\u52a0\u5230\u8fd0\u884c\u4e2d\u7684 Pod\u3002 kubectl create -f - << EOF apiVersion: v1 kind: Pod metadata: name: ubuntu labels: app: ubuntu spec: containers: - name: ubuntu image: ubuntu:latest command: [\"/bin/sleep\", \"3650d\"] imagePullPolicy: IfNotPresent restartPolicy: Always EOF kubectl exec --stdin --tty ubuntu -- /bin/bash \u521b\u5efa\u4e00\u4e2a Deployment\uff0c\u9009\u9879 --image \u6307\u5b9a\u4e86\u4e00\u4e2a\u955c\u50cf\uff0c\u9009\u9879 --port \u6307\u5b9a\u4e86\u5916\u90e8\u8bbf\u95ee\u7684\u7aef\u53e3\u3002 \u5728\u521b\u5efa Deployment \u7684\u540c\u65f6\u4e5f\u4f1a\u521b\u5efa\u4e00\u4e2a Pod\u3002 kubectl create deployment myapp --image = docker.io/jocatalin/kubernetes-bootcamp:v1 --replicas = 1 --port = 8080 \u67e5\u8be2deployment\u7684\u72b6\u6001\u3002 kubectl get deployment myapp -o wide \u8f93\u51fa\u7ed3\u679c\uff1a NAME READY UP-TO-DATE AVAILABLE AGE CONTAINERS IMAGES SELECTOR myapp 1/1 1 1 79s kubernetes-bootcamp docker.io/jocatalin/kubernetes-bootcamp:v1 app=myapp \u67e5\u8be2deployment\u7684\u8be6\u7ec6\u4fe1\u606f\u3002 kubectl describe deployment myapp \u8fd0\u884c\u7ed3\u679c\uff1a Name: myapp Namespace: dev CreationTimestamp: Sat, 23 Jul 2022 14:36:43 +0800 Labels: app=myapp Annotations: deployment.kubernetes.io/revision: 1 Selector: app=myapp Replicas: 1 desired | 1 updated | 1 total | 1 available | 0 unavailable StrategyType: RollingUpdate MinReadySeconds: 0 RollingUpdateStrategy: 25% max unavailable, 25% max surge Pod Template: Labels: app=myapp Containers: kubernetes-bootcamp: Image: docker.io/jocatalin/kubernetes-bootcamp:v1 Port: 8080/TCP Host Port: 0/TCP Environment: Mounts: Volumes: Conditions: Type Status Reason ---- ------ ------ Available True MinimumReplicasAvailable Progressing True NewReplicaSetAvailable OldReplicaSets: NewReplicaSet: myapp-b5d775f5d (1/1 replicas created) Events: Type Reason Age From Message ---- ------ ---- ---- ------- Normal ScalingReplicaSet 95s deployment-controller Scaled up replica set myapp-b5d775f5d to 1","title":"\u90e8\u7f72\uff08Deployment\uff09"},{"location":"k8s/cka_cn/foundamentals/casestudy-operation-resources/#expose-service","text":"\u83b7\u53d6\u4e0a\u9762\u7ec3\u4e60\u4e2d\u521b\u5efa\u7684pod\u548cdeployment\u7684\u4fe1\u606f\u3002 kubectl get deployment myapp -o wide kubectl get pod -o wide \u8fd0\u884c\u7ed3\u679c\uff1a NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES myapp-b5d775f5d-cx8dx 1/1 Running 0 2m34s 10.244.102.7 cka003 \u6267\u884c\u547d\u4ee4 curl 10.244.102.7:8080 \uff0c\u4ee5\u53d1\u9001HTTP\u8bf7\u6c42\u5230pod\u7684\u7aef\u53e3\uff0c\u5f97\u5230\u5982\u4e0b\u7ed3\u679c\u3002 Hello Kubernetes bootcamp! | Running on: myapp-b5d775f5d-6jtgs | v=1 \u8981\u4f7f Pod \u53ef\u4ee5\u4ece\u5916\u90e8\u8bbf\u95ee\uff0c\u9700\u8981\u5c06\u7aef\u53e3 8080 \u66b4\u9732\u7ed9\u8282\u70b9\u7aef\u53e3\uff08NodePort\uff09\u3002\u8fd9\u9700\u8981\u521b\u5efa\u4e00\u4e2a\u76f8\u5173\u7684 Service\u3002 kubectl expose deployment myapp --type = NodePort --port = 8080 \u6267\u884c\u547d\u4ee4 kubectl get svc myapp -o wide \uff0c\u83b7\u53d6service myapp \u7684\u8be6\u7ec6\u4fe1\u606f\u3002 NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE SELECTOR myapp NodePort 11.244.74.3 8080:30514/TCP 7s app=myapp \u6267\u884c\u547d\u4ee4 curl 11.244.74.3:8080 \uff0c\u4ee5\u53d1\u9001HTTP\u8bf7\u6c42\u5230service\u7684\u7aef\u53e3\uff0c\u5f97\u5230\u5982\u4e0b\u7ed3\u679c\u3002 Hello Kubernetes bootcamp! | Running on: myapp-b5d775f5d-cx8dx | v=1 \u83b7\u53d6service\u7684\u8be6\u7ec6\u4fe1\u606f\u3002 kubectl get svc myapp -o yaml kubectl describe svc myapp \u6267\u884c kubectl get endpoints myapp -o wide \u547d\u4ee4\u4ee5\u83b7\u53d6\u76f8\u5173\u7684 myapp \u7aef\u70b9\uff08endpoint\uff09\u7684\u8be6\u7ec6\u4fe1\u606f\u3002 NAME ENDPOINTS AGE myapp 10.244.102.7:8080 43s \u63d0\u793a\uff1a Endpoint\uff08\u7aef\u70b9\uff09\u662f\u4e00\u4e2aKubernetes\u4e2d\u7684\u5bf9\u8c61\uff0c\u7528\u4e8e\u5b58\u50a8\u53ef\u4ee5\u88ab\u670d\u52a1\u8bbf\u95ee\u7684Pod\u7684\u7f51\u7edc\u5730\u5740\u548c\u7aef\u53e3\u4fe1\u606f\u3002 \u5f53Service\u521b\u5efa\u65f6\uff0cKubernetes\u4f1a\u81ea\u52a8\u521b\u5efa\u548c\u66f4\u65b0\u76f8\u5e94\u7684Endpoint\u3002 Endpoint\u662f\u7531kube-proxy\u81ea\u52a8\u521b\u5efa\u548c\u7ef4\u62a4\u7684\uff0c\u5e76\u6839\u636e\u9009\u62e9\u5668\u5339\u914d\u5bf9\u5e94\u7684Service\u548cPod\u3002 \u80fd\u6210\u529f\u7684\u53d1\u9001HTTP\u8bf7\u6c42\u5230service\u548c\u8282\u70b9\uff0c\u8bf4\u660epod\u7684\u7aef\u53e3 8080 \u88ab\u6b63\u786e\u7684\u6620\u5c04\u5230\u8282\u70b9\u7684\u7aef\u53e3 32566 \u3002 \u6267\u884c\u547d\u4ee4curl :30514\uff0c\u53d1\u9001HTTP\u8bf7\u6c42\u5230\u8282\u70b9 cka003 \u4e0a\u5bf9\u5e94\u7684\u7aef\u53e3\u3002 Hello Kubernetes bootcamp! | Running on: myapp-b5d775f5d-6jtgs | v=1 \u767b\u5f55\u8fdb\u5165Ubuntu pod\uff0c\u6211\u4eec\u53ef\u4ee5\u901a\u8fc7\u53d1\u9001HTTP\u8bf7\u6c42\u5230 myapp \u6240\u6620\u5c04\u7684service\u3001pod\u548c\u8282\u70b9\u7684\u7aef\u53e3\u3002 kubectl exec --stdin --tty ubuntu -- /bin/bash curl 10 .244.102.7:8080 curl 11 .244.74.3:8080 curl :30514 Hello Kubernetes bootcamp! | Running on: myapp-b5d775f5d-6jtgs | v = 1","title":"\u66b4\u9732\u670d\u52a1\uff08Expose Service\uff09"},{"location":"k8s/cka_cn/foundamentals/casestudy-operation-resources/#scale-out-the-deployment","text":"Scale out by replicaset. We set three replicasets to scale out deployment myapp . The number of deployment myapp is now three. \u901a\u8fc7\u526f\u672c\u96c6replicaset\u8fdb\u884c\u6269\u5c55\u3002\u6211\u4eec\u901a\u8fc7\u6307\u5b9a\u526f\u672c\u96c6\u7684\u65b9\u5f0f\uff0c\u5bf9deployment myapp \u8fdb\u884c\u6269\u5c55\u90e8\u7f72\uff0c\u4e0b\u9762\u4f8b\u5b50\u4e2d\uff0cdeployment myapp \u7684\u526f\u672c\u6570\u662f\u4e09\u4e2a\u3002 kubectl scale deployment myapp --replicas = 3 \u67e5\u8be2deployment\u7684\u4fe1\u606f\u3002 kubectl get deployment myapp \u67e5\u8be2replicaset\u7684\u4fe1\u606f kubectl get replicaset","title":"\u6269\u5bb9\u90e8\u7f72\uff08Scale out the Deployment\uff09"},{"location":"k8s/cka_cn/foundamentals/casestudy-operation-resources/#rolling-update","text":"\u547d\u4ee4\u7528\u6cd5\uff1a kubectl set image (-f \u6587\u4ef6\u540d | \u7c7b\u578b \u540d\u79f0) \u5bb9\u5668\u540d\u79f0_1=\u5bb9\u5668\u955c\u50cf_1 ... \u5bb9\u5668\u540d\u79f0_N=\u5bb9\u5668\u955c\u50cf_N \u3002 \u4f7f\u7528\u547d\u4ee4 kubectl get deployment \uff0c\u6211\u4eec\u53ef\u4ee5\u83b7\u53d6deployment myapp \u548c\u76f8\u5173\u5bb9\u5668 kubernetes-bootcamp \u3002 kubectl get deployment myapp -o wide \u4f7f\u7528\u547d\u4ee4 kubectl set image \u6765\u66f4\u65b0\u591a\u4e2a\u7248\u672c\u7684\u955c\u50cf\uff0c\u5e76\u4f7f\u7528\u9009\u9879 --record \u5c06\u66f4\u6539\u8bb0\u5f55\u5728\u90e8\u7f72\u7684\u6ce8\u91ca\u4e2d\u3002 kubectl set image deployment/myapp kubernetes-bootcamp = docker.io/jocatalin/kubernetes-bootcamp:v2 --record \u67e5\u8be2\u5f53\u524dreplicas\u7684\u72b6\u6001\u3002 kubectl get replicaset -o wide -l app = myapp \u8f93\u51fa\u7ed3\u679c\u5982\u4e0b\uff0cpod\u6b63\u4ee5\u65b0\u7684\u526f\u672c\u96c6replicas\u6570\u91cf\u8fd0\u884c\u3002 NAME DESIRED CURRENT READY AGE CONTAINERS IMAGES SELECTOR myapp-5dbd68cc99 1 1 0 8s kubernetes-bootcamp docker.io/jocatalin/kubernetes-bootcamp:v2 app=myapp,pod-template-hash=5dbd68cc99 myapp-b5d775f5d 3 3 3 14m kubernetes-bootcamp docker.io/jocatalin/kubernetes-bootcamp:v1 app=myapp,pod-template-hash=b5d775f5d \u6211\u4eec\u53ef\u4ee5\u5728\u5bf9\u5e94\u7684yaml\u6587\u4ef6\u4e2d metadata.annotations \u90e8\u5206\u83b7\u53d6\u53d8\u66f4\u5386\u53f2\u8bb0\u5f55\u3002 kubectl get deployment myapp -o yaml \u8fd0\u884c\u7ed3\u679c\uff1a apiVersion : apps/v1 kind : Deployment metadata : annotations : deployment.kubernetes.io/revision : \"2\" kubernetes.io/change-cause : kubectl set image deployment/myapp kubernetes-bootcamp=docker.io/jocatalin/kubernetes-bootcamp:v2 --record=true ...... \u6211\u4eec\u4e5f\u53ef\u4ee5\u4f7f\u7528\u547d\u4ee4 kubectl rollout history \u83b7\u53d6\u66f4\u65b0\u5386\u53f2\u8bb0\u5f55\uff0c\u5e76\u4f7f\u7528\u7279\u5b9a\u4fee\u8ba2\u7248\u672c\u53f7 --revision= \u663e\u793a\u8be6\u7ec6\u4fe1\u606f\u3002 kubectl rollout history deployment/myapp \u8fd0\u884c\u7ed3\u679c\uff1a deployment.apps/myapp REVISION CHANGE-CAUSE 1 2 kubectl set image deployment/myapp kubernetes-bootcamp=docker.io/jocatalin/kubernetes-bootcamp:v2 --record=true \u83b7\u53d6\u7279\u5b9a\u7248\u672c\u56de\u6eda\u5386\u53f2\u8bb0\u5f55\u3002 kubectl rollout history deployment/myapp --revision = 2 \u6267\u884c\u547d\u4ee4 kubectl rollout undo \u53ef\u4ee5\u56de\u6eda\u5230\u4e0a\u4e00\u4e2a\u7248\u672c\uff0c\u6216\u4f7f\u7528\u9009\u9879 --to-revision= \u56de\u6eda\u5230\u6307\u5b9a\u7684\u7248\u672c\u3002 kubectl rollout undo deployment/myapp --to-revision = 1 \u7248\u672c 1 \u73b0\u5728\u5df2\u7ecf\u88ab\u66ff\u6362\u6210\u7248\u672c 3 \u4e86\u3002 kubectl rollout history deployment/myapp \u8fd0\u884c\u7ed3\u679c\uff1a deployment.apps/myapp REVISION CHANGE-CAUSE 2 kubectl set image deployment/myapp kubernetes-bootcamp=docker.io/jocatalin/kubernetes-bootcamp:v2 --record=true 3 ","title":"\u6eda\u52a8\u5347\u7ea7\uff08Rolling update\uff09"},{"location":"k8s/cka_cn/foundamentals/casestudy-operation-resources/#event","text":"\u83b7\u53d6\u6307\u5b9apod\u7684\u4e8b\u4ef6\u4fe1\u606f\u3002 kubectl describe pod myapp-b5d775f5d-jlx6g \u8f93\u51fa\u7ed3\u679c\uff1a ...... Events: Type Reason Age From Message ---- ------ ---- ---- ------- Normal Scheduled 54s default-scheduler Successfully assigned dev/myapp-b5d775f5d-jlx6g to cka003 Normal Pulled 53s kubelet Container image \"docker.io/jocatalin/kubernetes-bootcamp:v1\" already present on machine Normal Created 53s kubelet Created container kubernetes-bootcamp Normal Started 53s kubelet Started container kubernetes-bootcamp \u67e5\u8be2\u96c6\u7fa4\u7684\u4e8b\u4ef6\u4fe1\u606f\u3002 kubectl get event","title":"\u4e8b\u4ef6\uff08Event\uff09"},{"location":"k8s/cka_cn/foundamentals/casestudy-operation-resources/#logging","text":"\u67e5\u8be2pod\u7684\u65e5\u5fd7\u4fe1\u606f\u3002 kubectl logs -f kubectl logs -f -c \u4f8b\u5982\uff1a kubectl logs -f myapp-b5d775f5d-jlx6g \u8fd0\u884c\u7ed3\u679c\uff1a Kubernetes Bootcamp App Started At: 2022-07-23T06:54:18.532Z | Running On: myapp-b5d775f5d-jlx6g \u67e5\u8be2K8s\u4e0d\u540c\u7ec4\u4ef6\u7684\u65e5\u5fd7\u4fe1\u606f\u3002 kubectl logs kube-apiserver-cka001 -n kube-system kubectl logs kube-controller-manager-cka001 -n kube-system kubectl logs kube-scheduler-cka001 -n kube-system kubectl logs etcd-cka001 -n kube-system systemctl status kubelet journalctl -fu kubelet kubectl logs kube-proxy-5cdbj -n kube-system \u5220\u9664\u6f14\u793a\u4e2d\u521b\u5efa\u7684\u4e34\u65f6\u8d44\u6e90\u3002 kubectl delete service myapp kubectl delete deployment myapp","title":"\u65e5\u5fd7\u8bb0\u5f55\uff08Logging\uff09"},{"location":"k8s/cka_cn/foundamentals/clustermgt/","text":"CKA\u81ea\u5b66\u7b14\u8bb024:Cluster Management \u00b6 \u6f14\u793a\u573a\u666f\uff1a etcd Backup and Restore \u5b89\u88c5 etcdctl \u5728\u5907\u4efd\u4e4b\u524d\u521b\u5efa Deployment \u5907\u4efd etcd \u5728\u5907\u4efd\u4e4b\u540e\u521b\u5efa Deployment \u505c\u6b62\u670d\u52a1 \u505c\u6b62 etcd \u6062\u590d etcd \u542f\u52a8\u670d\u52a1 \u9a8c\u8bc1 etcd \u5907\u4efd\u548c\u6062\u590d \u00b6 \u5b89\u88c5 etcdctl \u00b6 \u4e0b\u8f7d etcd \u5b89\u88c5\u5305\u3002 wget https://github.com/etcd-io/etcd/releases/download/v3.5.3/etcd-v3.5.3-linux-amd64.tar.gz \u89e3\u538b etcd \u5b89\u88c5\u5305\uff0c\u5e76\u8d4b\u4e88\u6267\u884c\u6743\u9650\u3002 tar -zxvf etcd-v3.5.3-linux-amd64.tar.gz cp etcd-v3.5.3-linux-amd64/etcdctl /usr/local/bin/ sudo chmod u+x /usr/local/bin/etcdctl \u9a8c\u8bc1\uff1a etcdctl --help \u521b\u5efa\u4e00\u4e2adeployment\uff08\u5907\u4efd\u524d\uff09 \u00b6 \u5907\u4efd\u524d\u521b\u5efa\u4e00\u4e2adeployment\u3002 kubectl create deployment app-before-backup --image = nginx \u5907\u4efd etcd \u00b6 \u8bf4\u660e\uff1a \u662f\u63a7\u5236\u5e73\u9762\u8282\u70b9\u7684\u5b9e\u9645IP\u5730\u5740\u3002 --endpoints \uff1a\u6307\u5b9a etcd \u5907\u4efd\u7684\u4fdd\u5b58\u4f4d\u7f6e\uff0c2379 \u662f etcd \u7684\u7aef\u53e3\u53f7\u3002 --cert \uff1a\u6307\u5b9a etcd \u8bc1\u4e66\u7684\u4f4d\u7f6e\uff0c\u8bc1\u4e66\u662f\u7531 kubeadm \u751f\u6210\u5e76\u4fdd\u5b58\u5728 /etc/kubernetes/pki/etcd/ \u76ee\u5f55\u4e0b\u7684\u3002 --key \uff1a\u6307\u5b9a etcd \u8bc1\u4e66\u7684\u79c1\u94a5\u7684\u4f4d\u7f6e\uff0c\u8bc1\u4e66\u662f\u7531 kubeadm \u751f\u6210\u5e76\u4fdd\u5b58\u5728 /etc/kubernetes/pki/etcd/ \u76ee\u5f55\u4e0b\u7684\u3002 --cacert \uff1a\u6307\u5b9a etcd \u8bc1\u4e66\u7684 CA \u7684\u4f4d\u7f6e\uff0c\u8bc1\u4e66\u662f\u7531 kubeadm \u751f\u6210\u5e76\u4fdd\u5b58\u5728 /etc/kubernetes/pki/etcd/ \u76ee\u5f55\u4e0b\u7684\u3002 etcdctl \\ --endpoints = https://:2379 \\ --cert = /etc/kubernetes/pki/etcd/server.crt \\ --key = /etc/kubernetes/pki/etcd/server.key \\ --cacert = /etc/kubernetes/pki/etcd/ca.crt \\ snapshot save snapshot- $( date + \"%Y%m%d%H%M%S\" ) .db \u6216\u8005 etcdctl \\ --endpoints = https://:2379 \\ --cert = /etc/kubernetes/pki/etcd/server.crt \\ --key = /etc/kubernetes/pki/etcd/server.key \\ --cacert = /etc/kubernetes/pki/etcd/ca.crt \\ snapshot save snapshot- $( date + \"%Y%m%d%H%M%S\" ) .db Output: {\"level\":\"info\",\"ts\":\"2022-07-24T18:51:21.328+0800\",\"caller\":\"snapshot/v3_snapshot.go:65\",\"msg\":\"created temporary db file\",\"path\":\"snapshot-20220724185121.db.part\"} {\"level\":\"info\",\"ts\":\"2022-07-24T18:51:21.337+0800\",\"logger\":\"client\",\"caller\":\"v3/maintenance.go:211\",\"msg\":\"opened snapshot stream; downloading\"} {\"level\":\"info\",\"ts\":\"2022-07-24T18:51:21.337+0800\",\"caller\":\"snapshot/v3_snapshot.go:73\",\"msg\":\"fetching snapshot\",\"endpoint\":\"https://:2379\"} {\"level\":\"info\",\"ts\":\"2022-07-24T18:51:21.415+0800\",\"logger\":\"client\",\"caller\":\"v3/maintenance.go:219\",\"msg\":\"completed snapshot read; closing\"} {\"level\":\"info\",\"ts\":\"2022-07-24T18:51:21.477+0800\",\"caller\":\"snapshot/v3_snapshot.go:88\",\"msg\":\"fetched snapshot\",\"endpoint\":\"https://:2379\",\"size\":\"3.6 MB\",\"took\":\"now\"} {\"level\":\"info\",\"ts\":\"2022-07-24T18:51:21.477+0800\",\"caller\":\"snapshot/v3_snapshot.go:97\",\"msg\":\"saved\",\"path\":\"snapshot-20220724185121.db\"} Snapshot saved at snapshot-20220724185121.db \u6267\u884c\u547d\u4ee4 ls -al \u5728\u5f53\u524d\u76ee\u5f55\u4e2d\u8bfb\u53d6\u6211\u4eec\u521a\u521a\u521b\u5efa\u7684\u5907\u4efd\u6587\u4ef6\u3002 -rw------- 1 root root 3616800 Jul 24 18 :51 snapshot-20220724185121.db \u521b\u5efa\u4e00\u4e2adeployment\uff08\u5907\u4efd\u540e\uff09 \u00b6 \u5907\u4efd\u540e\uff0c\u6211\u4eec\u521b\u5efa\u53e6\u5916\u4e00\u4e2adeployment\u3002 kubectl create deployment app-after-backup --image = nginx \u5220\u9664\u5907\u4efd\u524d\u6211\u4eec\u521b\u5efa\u7684\u90a3\u4e2adeployment\u3002 kubectl delete deployment app-before-backup \u68c0\u67e5deployment\u7684\u72b6\u6001\u3002 kubectl get deploy \u8fd0\u884c\u7ed3\u679c\uff1a NAME READY UP-TO-DATE AVAILABLE AGE app-after-backup 1/1 1 1 108s \u505c\u6b62Services \u00b6 \u5220\u9664 etcd \u7684\u76ee\u5f55\u3002 mv /var/lib/etcd/ /var/lib/etcd.bak \u505c\u6b62 kubelet \u3002 systemctl stop kubelet \u505c\u6b62 kube-apiserver \u3002 nerdctl -n k8s.io ps -a | grep apiserver \u8fd0\u884c\u7ed3\u679c\uff1a 0c5e69118f1b registry.aliyuncs.com/google_containers/kube-apiserver:v1.24.0 \"kube-apiserver --ad\u2026\" 32 hours ago Up k8s://kube-system/kube-apiserver-cka001/kube-apiserver 638bb602c310 registry.aliyuncs.com/google_containers/pause:3.6 \"/pause\" 32 hours ago Up k8s://kube-system/kube-apiserver-cka001 \u505c\u6b62\u90a3\u4e9b\u4ecd\u65e7\u5904\u4e8e up \u72b6\u6001\u7684\u5bb9\u5668\u3002 nerdctl -n k8s.io stop nerdctl -n k8s.io stop 0c5e69118f1b nerdctl -n k8s.io stop 638bb602c310 \u76f4\u81f3\u6ca1\u6709\u5904\u4e8e up \u72b6\u6001\u7684 kube-apiserver \u3002 nerdctl -n k8s.io ps -a | grep apiserver \u8fd0\u884c\u7ed3\u679c\uff1a 0c5e69118f1b registry.aliyuncs.com/google_containers/kube-apiserver:v1.24.0 \"kube-apiserver --ad\u2026\" 32 hours ago Created k8s://kube-system/kube-apiserver-cka001/kube-apiserver 638bb602c310 registry.aliyuncs.com/google_containers/pause:3.6 \"/pause\" 32 hours ago Created k8s://kube-system/kube-apiserver-cka001 \u505c\u6b62etcd \u00b6 nerdctl -n k8s.io ps -a | grep etcd \u8fd0\u884c\u7ed3\u679c\uff1a 0965b195f41a registry.aliyuncs.com/google_containers/etcd:3.5.1-0 \"etcd --advertise-cl\u2026\" 32 hours ago Up k8s://kube-system/etcd-cka001/etcd 9e1bea9f25d1 registry.aliyuncs.com/google_containers/pause:3.6 \"/pause\" 32 hours ago Up k8s://kube-system/etcd-cka001 \u505c\u6b62\u90a3\u4e9b\u4ecd\u65e7\u5904\u4e8e up \u72b6\u6001\u7684\u5bb9\u5668\u3002 nerdctl -n k8s.io stop nerdctl -n k8s.io stop 0965b195f41a nerdctl -n k8s.io stop 9e1bea9f25d1 \u76f4\u81f3\u6ca1\u6709\u5904\u4e8e up \u72b6\u6001\u7684 kube-apiserver \u3002 nerdctl -n k8s.io ps -a | grep etcd \u8fd0\u884c\u7ed3\u679c\uff1a 0965b195f41a registry.aliyuncs.com/google_containers/etcd:3.5.1-0 \"etcd --advertise-cl\u2026\" 32 hours ago Created k8s://kube-system/etcd-cka001/etcd 9e1bea9f25d1 registry.aliyuncs.com/google_containers/pause:3.6 \"/pause\" 32 hours ago Created k8s://kube-system/etcd-cka001 \u6062\u590d etcd \u00b6 \u5728\u63a7\u5236\u5e73\u9762\u8282\u70b9\u4e0a\u6267\u884c\u6062\u590d\u64cd\u4f5c\uff0c\u4f7f\u7528\u5b9e\u9645\u7684\u5907\u4efd\u6587\u4ef6\uff0c\u8fd9\u91cc\u662f\u6587\u4ef6 snapshot-20220724185121.db \u3002 etcdctl snapshot restore snapshot-20220724185121.db \\ --endpoints = :2379 \\ --cert = /etc/kubernetes/pki/etcd/server.crt \\ --key = /etc/kubernetes/pki/etcd/server.key \\ --cacert = /etc/kubernetes/pki/etcd/ca.crt \\ --data-dir = /var/lib/etcd \u8fd0\u884c\u7ed3\u679c\uff1a Deprecated: Use `etcdutl snapshot restore` instead. 2022-07-24T18:57:49+08:00 info snapshot/v3_snapshot.go:248 restoring snapshot {\"path\": \"snapshot-20220724185121.db\", \"wal-dir\": \"/var/lib/etcd/member/wal\", \"data-dir\": \"/var/lib/etcd\", \"snap-dir\": \"/var/lib/etcd/member/snap\", \"stack\": \"go.etcd.io/etcd/etcdutl/v3/snapshot.(*v3Manager).Restore\\n\\t/go/src/go.etcd.io/etcd/release/etcd/etcdutl/snapshot/v3_snapshot.go:254\\ngo.etcd.io/etcd/etcdutl/v3/etcdutl.SnapshotRestoreCommandFunc\\n\\t/go/src/go.etcd.io/etcd/release/etcd/etcdutl/etcdutl/snapshot_command.go:147\\ngo.etcd.io/etcd/etcdctl/v3/ctlv3/command.snapshotRestoreCommandFunc\\n\\t/go/src/go.etcd.io/etcd/release/etcd/etcdctl/ctlv3/command/snapshot_command.go:129\\ngithub.com/spf13/cobra.(*Command).execute\\n\\t/go/pkg/mod/github.com/spf13/cobra@v1.1.3/command.go:856\\ngithub.com/spf13/cobra.(*Command).ExecuteC\\n\\t/go/pkg/mod/github.com/spf13/cobra@v1.1.3/command.go:960\\ngithub.com/spf13/cobra.(*Command).Execute\\n\\t/go/pkg/mod/github.com/spf13/cobra@v1.1.3/command.go:897\\ngo.etcd.io/etcd/etcdctl/v3/ctlv3.Start\\n\\t/go/src/go.etcd.io/etcd/release/etcd/etcdctl/ctlv3/ctl.go:107\\ngo.etcd.io/etcd/etcdctl/v3/ctlv3.MustStart\\n\\t/go/src/go.etcd.io/etcd/release/etcd/etcdctl/ctlv3/ctl.go:111\\nmain.main\\n\\t/go/src/go.etcd.io/etcd/release/etcd/etcdctl/main.go:59\\nruntime.main\\n\\t/go/gos/go1.16.15/src/runtime/proc.go:225\"} 2022-07-24T18:57:49+08:00 info membership/store.go:141 Trimming membership information from the backend... 2022-07-24T18:57:49+08:00 info membership/cluster.go:421 added member {\"cluster-id\": \"cdf818194e3a8c32\", \"local-member-id\": \"0\", \"added-peer-id\": \"8e9e05c52164694d\", \"added-peer-peer-urls\": [\"http://localhost:2380\"]} 2022-07-24T18:57:49+08:00 info snapshot/v3_snapshot.go:269 restored snapshot {\"path\": \"snapshot-20220724185121.db\", \"wal-dir\": \"/var/lib/etcd/member/wal\", \"data-dir\": \"/var/lib/etcd\", \"snap-dir\": \"/var/lib/etcd/member/snap\"} \u68c0\u67e5\u88ab\u5220\u9664\u7684 etcd \u76ee\u5f55\u662f\u5426\u5df2\u7ecf\u4ece\u5907\u4efd\u4e2d\u6062\u590d\u4e86\u3002 tree /var/lib/etcd \u8fd0\u884c\u7ed3\u679c\uff1a /var/lib/etcd \u2514\u2500\u2500 member \u251c\u2500\u2500 snap \u2502 \u251c\u2500\u2500 0000000000000001-0000000000000001.snap \u2502 \u2514\u2500\u2500 db \u2514\u2500\u2500 wal \u2514\u2500\u2500 0000000000000000-0000000000000000.wal \u542f\u52a8\u670d\u52a1Services \u00b6 \u542f\u52a8 kubelet \u3002\u670d\u52a1 kube-apiserver \u548c etcd \u4e5f\u4f1a\u7ee7 kubelet \u542f\u52a8\u540e\u88ab\u81ea\u52a8\u542f\u52a8\u3002 systemctl start kubelet \u6267\u884c\u4e0b\u9762\u547d\u4ee4\u786e\u8ba4\u6240\u6709\u670d\u52a1\u90fd\u5df2\u7ecf\u542f\u52a8\u548c\u6b63\u5e38\u8fd0\u884c\u3002 systemctl status kubelet.service nerdctl -n k8s.io ps -a | grep etcd nerdctl -n k8s.io ps -a | grep apiserver \u67e5\u770b\u5f53\u524d etcd \u7684\u72b6\u6001\u3002 0965b195f41a registry.aliyuncs.com/google_containers/etcd:3.5.1-0 \"etcd --advertise-cl\u2026\" 32 hours ago Created k8s://kube-system/etcd-cka001/etcd 3b8f37c87782 registry.aliyuncs.com/google_containers/etcd:3.5.1-0 \"etcd --advertise-cl\u2026\" 6 seconds ago Up k8s://kube-system/etcd-cka001/etcd 9e1bea9f25d1 registry.aliyuncs.com/google_containers/pause:3.6 \"/pause\" 32 hours ago Created k8s://kube-system/etcd-cka001 fbbbb628a945 registry.aliyuncs.com/google_containers/pause:3.6 \"/pause\" 6 seconds ago Up k8s://kube-system/etcd-cka001 \u67e5\u770b\u5f53\u524d apiserver \u7684\u72b6\u6001\u3002 0c5e69118f1b registry.aliyuncs.com/google_containers/kube-apiserver:v1.24.0 \"kube-apiserver --ad\u2026\" 32 hours ago Created k8s://kube-system/kube-apiserver-cka001/kube-apiserver 281cf4c6670d registry.aliyuncs.com/google_containers/kube-apiserver:v1.24.0 \"kube-apiserver --ad\u2026\" 14 seconds ago Up k8s://kube-system/kube-apiserver-cka001/kube-apiserver 5ed8295d92da registry.aliyuncs.com/google_containers/pause:3.6 \"/pause\" 15 seconds ago Up k8s://kube-system/kube-apiserver-cka001 638bb602c310 registry.aliyuncs.com/google_containers/pause:3.6 \"/pause\" 32 hours ago Created k8s://kube-system/kube-apiserver-cka001 \u9a8c\u8bc1 \u00b6 \u68c0\u67e5\u96c6\u7fa4\u7684\u72b6\u6001\uff0c\u67e5\u770b\u662f\u5426pod app-before-backup \u5b58\u5728\u3002 kubectl get deploy \u8fd0\u884c\u7ed3\u679c\uff1a NAME READY UP-TO-DATE AVAILABLE AGE app-before-backup 1/1 1 1 11m \u96c6\u7fa4\u5347\u7ea7 \u00b6 \u6f14\u793a\u573a\u666f\uff1a\u96c6\u7fa4\u5347\u7ea7 \u9a71\u9010\u63a7\u5236\u5e73\u9762\u8282\u70b9 \u68c0\u67e5\u5f53\u524d\u53ef\u7528\u7684 kubeadm \u7248\u672c \u5c06 kubeadm \u5347\u7ea7\u5230\u65b0\u7248\u672c \u68c0\u67e5\u5347\u7ea7\u8ba1\u5212 \u5e94\u7528\u5347\u7ea7\u8ba1\u5212\u4ee5\u5347\u7ea7\u5230\u65b0\u7248\u672c \u5347\u7ea7 kubelet \u548c kubectl \u542f\u7528\u63a7\u5236\u5e73\u9762\u8282\u70b9\u8c03\u5ea6 \u9a71\u9010\u5de5\u4f5c\u8282\u70b9 \u5347\u7ea7 kubeadm \u548c kubelet \u542f\u7528\u5de5\u4f5c\u8282\u70b9\u8c03\u5ea6 \u53c2\u8003\uff1a kubeadm\u5347\u7ea7 \u5347\u7ea7\u63a7\u5236\u5e73\u9762 \u00b6 \u63a7\u5236\u5e73\u9762\u51c6\u5907 \u00b6 \u9a71\u9010\u63a7\u5236\u5e73\u9762\u8282\u70b9\u3002 kubectl drain --ignore-daemonsets \u8fd9\u91cc\u662f\uff1a kubectl drain cka001 --ignore-daemonsets \u8fd0\u884c\u7ed3\u679c\uff1a node/cka001 cordoned WARNING: ignoring DaemonSet-managed Pods: kube-system/calico-node-dsx76, kube-system/kube-proxy-cm4hc evicting pod kube-system/calico-kube-controllers-5c64b68895-jr4nl evicting pod kube-system/coredns-6d8c4cb4d-g4jxc evicting pod kube-system/coredns-6d8c4cb4d-sqcvj pod/calico-kube-controllers-5c64b68895-jr4nl evicted pod/coredns-6d8c4cb4d-g4jxc evicted pod/coredns-6d8c4cb4d-sqcvj evicted node/cka001 drained \u63a7\u5236\u5e73\u9762\u8282\u70b9\u73b0\u5728\u5904\u4e8e SchedulingDisabled \u72b6\u6001\u3002 kubectl get node -owide \u8fd0\u884c\u7ed3\u679c\uff1a NAME STATUS ROLES AGE VERSION OS-IMAGE KERNEL-VERSION CONTAINER-RUNTIME cka001 Ready,SchedulingDisabled control-plane,master 32h v1.24.0 Ubuntu 20.04.4 LTS 5.4.0-122-generic containerd://1.5.9 cka002 Ready 32h v1.24.0 Ubuntu 20.04.4 LTS 5.4.0-122-generic containerd://1.5.9 cka003 Ready 32h v1.24.0 Ubuntu 20.04.4 LTS 5.4.0-122-generic containerd://1.5.9 \u67e5\u8be2\u5f53\u524d kubeadm \u53ef\u7528\u7248\u672c\u3002 apt policy kubeadm \u8f93\u51fa\u7ed3\u679c\uff1a kubeadm: Installed: 1.24.0-00 Candidate: 1.24.3-00 Version table: 1.24.3-00 500 500 https://mirrors.aliyun.com/kubernetes/apt kubernetes-xenial/main amd64 Packages 1.24.2-00 500 500 https://mirrors.aliyun.com/kubernetes/apt kubernetes-xenial/main amd64 Packages 1.24.1-00 500 500 https://mirrors.aliyun.com/kubernetes/apt kubernetes-xenial/main amd64 Packages 1.24.0-00 500 500 https://mirrors.aliyun.com/kubernetes/apt kubernetes-xenial/main amd64 Packages 1.24.2-00 500 500 https://mirrors.aliyun.com/kubernetes/apt kubernetes-xenial/main amd64 Packages *** 1.24.0-00 500 500 https://mirrors.aliyun.com/kubernetes/apt kubernetes-xenial/main amd64 Packages 100 /var/lib/dpkg/status 1.23.7-00 500 500 https://mirrors.aliyun.com/kubernetes/apt kubernetes-xenial/main amd64 Packages ...... \u5347\u7ea7 kubeadm \u5230 Candidate: 1.24.2-00 \u7248\u672c\u3002 sudo apt-get -y install kubeadm = 1 .24.2-00 --allow-downgrades \u67e5\u8be2\u5347\u7ea7\u8ba1\u5212\u3002 kubeadm upgrade plan \u8f93\u51fa\u7c7b\u4f3c\u4e0b\u9762\u7684\u5347\u7ea7\u8ba1\u5212\u3002 [upgrade/config] Making sure the configuration is correct: [upgrade/config] Reading configuration from the cluster... [upgrade/config] FYI: You can look at this config file with 'kubectl -n kube-system get cm kubeadm-config -o yaml' [preflight] Running pre-flight checks. [upgrade] Running cluster health checks [upgrade] Fetching available versions to upgrade to [upgrade/versions] Cluster version: v1.24.0 [upgrade/versions] kubeadm version: v1.24.2 I0724 19:05:00.111855 1142460 version.go:255] remote version is much newer: v1.24.3; falling back to: stable-1.23 [upgrade/versions] Target version: v1.24.2 [upgrade/versions] Latest version in the v1.23 series: v1.24.2 Components that must be upgraded manually after you have upgraded the control plane with 'kubeadm upgrade apply': COMPONENT CURRENT TARGET kubelet 3 x v1.24.0 v1.24.2 Upgrade to the latest version in the v1.23 series: COMPONENT CURRENT TARGET kube-apiserver v1.24.0 v1.24.2 kube-controller-manager v1.24.0 v1.24.2 kube-scheduler v1.24.0 v1.24.2 kube-proxy v1.24.0 v1.24.2 CoreDNS v1.8.6 v1.8.6 etcd 3.5.1-0 3.5.1-0 You can now apply the upgrade by executing the following command: kubeadm upgrade apply v1.24.2 _____________________________________________________________________ The table below shows the current state of component configs as understood by this version of kubeadm. Configs that have a \"yes\" mark in the \"MANUAL UPGRADE REQUIRED\" column require manual config upgrade or resetting to kubeadm defaults before a successful upgrade can be performed. The version to manually upgrade to is denoted in the \"PREFERRED VERSION\" column. API GROUP CURRENT VERSION PREFERRED VERSION MANUAL UPGRADE REQUIRED kubeproxy.config.k8s.io v1alpha1 v1alpha1 no kubelet.config.k8s.io v1beta1 v1beta1 no _____________________________________________________________________ \u63a7\u5236\u5e73\u9762\u5347\u7ea7 \u00b6 \u53c2\u8003\u524d\u9762\u7684\u5347\u7ea7\u8ba1\u5212\uff0c\u6211\u4eec\u5347\u7ea7\u5230 v1.24.2 \u7248\u672c\u3002 kubeadm upgrade apply v1.24.2 \u901a\u8fc7\u9009\u9879 --etcd-upgrade=false \uff0c\u6211\u4eec\u628a etcd \u6392\u9664\u51fa\u5f53\u524d\u5347\u7ea7\u8303\u56f4\u3002 kubeadm upgrade apply v1.24.2 --etcd-upgrade = false \u6536\u5230\u4e0b\u9762\u7684\u4fe1\u606f\uff0c\u5219\u4ee3\u8868\u4e0a\u9762\u7684\u5347\u7ea7\u547d\u4ee4\u6210\u529f\u4e86\u3002 [upgrade/successful] SUCCESS! Your cluster was upgraded to \"v1.24.2\". Enjoy! [upgrade/kubelet] Now that your control plane is upgraded, please proceed with upgrading your kubelets if you haven't already done so. \u5347\u7ea7 kubelet \u548c kubectl \u3002 sudo apt-get -y install kubelet = 1 .24.2-00 kubectl = 1 .24.2-00 --allow-downgrades sudo systemctl daemon-reload sudo systemctl restart kubelet \u67e5\u8be2\u8282\u70b9\u5f53\u524d\u72b6\u6001\u3002 kubectl get node \u8fd0\u884c\u7ed3\u679c\uff1a NAME STATUS ROLES AGE VERSION cka001 Ready,SchedulingDisabled control-plane,master 32h v1.24.2 cka002 Ready 32h v1.24.0 cka003 Ready 32h v1.24.0 After verify that each node is in Ready status, enable node scheduling. \u5728\u786e\u8ba4\u6240\u6709\u8282\u70b9\u90fd\u5904\u4e8eReady\u72b6\u6001\uff0c\u5219\u6fc0\u6d3bscheduling\u3002 kubectl uncordon \u8fd9\u91cc\u662f\uff1a kubectl uncordon cka001 \u8f93\u51fa\u7ed3\u679c\uff1a node/cka001 uncordoned \u518d\u6b21\u68c0\u67e5\u8282\u70b9\u72b6\u6001\uff0c\u786e\u4fdd\u6240\u6709\u8282\u70b9\u90fd\u5904\u4e8eReady\u72b6\u6001\u3002 kubectl get node \u8fd0\u884c\u7ed3\u679c\uff1a NAME STATUS ROLES AGE VERSION cka001 Ready control-plane,master 32h v1.24.2 cka002 Ready 32h v1.24.0 cka003 Ready 32h v1.24.0 \u5347\u7ea7\u5de5\u4f5c\u8282\u70b9 \u00b6 \u5de5\u4f5c\u8282\u70b9\u51c6\u5907 \u00b6 \u767b\u5f55\u8282\u70b9 cka001 \u3002 \u9a71\u9010 Worker \u8282\u70b9\uff0c\u9700\u8981\u663e\u5f0f\u6307\u5b9a\u662f\u5426\u5220\u9664\u672c\u5730\u5b58\u50a8\u3002 kubectl drain --ignore-daemonsets --force kubectl drain --ignore-daemonsets --delete-emptydir-data --force \u5982\u679c\u9047\u5230\u5173\u4e8e emptydir \u4f9d\u8d56\u7684\u9519\u8bef\uff0c\u5219\u6267\u884c\u7b2c\u4e8c\u4e2a\u547d\u4ee4\u3002 kubectl drain cka002 --ignore-daemonsets --force kubectl drain cka002 --ignore-daemonsets --delete-emptydir-data --force \u8f93\u51fa\u7ed3\u679c\uff1a node/cka002 cordoned WARNING: deleting Pods not managed by ReplicationController, ReplicaSet, Job, DaemonSet or StatefulSet: dev/ubuntu; ignoring DaemonSet-managed Pods: kube-system/calico-node-p5rf2, kube-system/kube-proxy-zvs68 evicting pod ns-netpol/pod-netpol-5b67b6b496-2cgnw evicting pod dev/ubuntu evicting pod dev/app-before-backup-66dc9d5cb-6xc8c evicting pod dev/nfs-client-provisioner-86d7fb78b6-2f5dx evicting pod dev/pod-netpol-2-77478d77ff-l6rzm evicting pod ingress-nginx/ingress-nginx-admission-patch-nk9fv evicting pod ingress-nginx/ingress-nginx-admission-create-lgtdj evicting pod kube-system/coredns-6d8c4cb4d-l4kx4 pod/ingress-nginx-admission-create-lgtdj evicted pod/ingress-nginx-admission-patch-nk9fv evicted pod/nfs-client-provisioner-86d7fb78b6-2f5dx evicted pod/app-before-backup-66dc9d5cb-6xc8c evicted pod/coredns-6d8c4cb4d-l4kx4 evicted pod/pod-netpol-5b67b6b496-2cgnw evicted pod/pod-netpol-2-77478d77ff-l6rzm evicted pod/ubuntu evicted node/cka002 drained \u5de5\u4f5c\u8282\u70b9\u5347\u7ea7 \u00b6 \u767b\u5f55\u8282\u70b9 cka002 \u3002 \u4e0b\u8f7d kubeadm \u7684 v1.24.2 \u7248\u672c\u3002 sudo apt-get -y install kubeadm = 1 .24.2-00 --allow-downgrades \u5347\u7ea7 kubeadm \u3002 sudo kubeadm upgrade node \u5347\u7ea7 kubelet \u3002 sudo apt-get -y install kubelet = 1 .24.2-00 --allow-downgrades sudo systemctl daemon-reload sudo systemctl restart kubelet \u786e\u8ba4\u6240\u6709\u8282\u70b9\u90fd\u5904\u4e8eReady\u72b6\u6001\uff0c\u5219\u6fc0\u6d3bscheduling\u3002 kubectl uncordon \u8fd9\u91cc\u662f\uff1a kubectl uncordon cka002 \u5de5\u4f5c\u8282\u70b9\u9a8c\u8bc1 \u00b6 \u67e5\u8be2\u8282\u70b9\u72b6\u6001\u3002 kubectl get node \u8fd0\u884c\u7ed3\u679c\uff1a NAME STATUS ROLES AGE VERSION cka001 Ready control-plane,master 32h v1.24.2 cka002 Ready 32h v1.24.2 cka003 Ready 32h v1.24.0 \u5728\u8282\u70b9 cka003 \u4e0a\u91cd\u590d\u4e0a\u9762\u7684\u6b65\u9aa4\u3002 \u767b\u5f55\u8282\u70b9 cka003 \u3002\u5982\u679c\u9047\u5230\u5173\u4e8e emptydir \u4f9d\u8d56\u7684\u9519\u8bef\uff0c\u5219\u6267\u884c\u7b2c\u4e8c\u4e2a\u547d\u4ee4\u3002 kubectl drain cka003 --ignore-daemonsets --ignore-daemonsets --force kubectl drain cka003 --ignore-daemonsets --ignore-daemonsets --delete-emptydir-data --force \u767b\u5f55\u8282\u70b9 cka003 \uff0c\u6267\u884c\u4e0b\u9762\u7684\u547d\u4ee4\u3002 sudo apt-get -y install kubeadm = 1 .24.2-00 --allow-downgrades sudo kubeadm upgrade node sudo apt-get -y install kubelet = 1 .24.2-00 --allow-downgrades sudo systemctl daemon-reload sudo systemctl restart kubelet kubectl get node kubectl uncordon cka003 \u67e5\u8be2\u8282\u70b9\u72b6\u6001\u3002 kubectl get node \u8fd0\u884c\u7ed3\u679c\uff1a NAME STATUS ROLES AGE VERSION cka001 Ready control-plane,master 32h v1.24.2 cka002 Ready 32h v1.24.2 cka003 Ready 32h v1.24.2 \u603b\u7ed3 \u00b6 \u5728\u63a7\u5236\u9762\u677f\u4e0a\u7684\u6267\u884c\u6b65\u9aa4\uff1a kubectl get node -owide kubectl drain cka001 --ignore-daemonsets kubectl get node -owide apt policy kubeadm apt-get -y install kubeadm = 1 .24.0-00 --allow-downgrades kubeadm upgrade plan kubeadm upgrade apply v1.24.0 # kubeadm upgrade apply v1.24.0 --etcd-upgrade=false apt-get -y install kubelet = 1 .24.0-00 kubectl = 1 .24.0-00 --allow-downgrades systemctl daemon-reload systemctl restart kubelet kubectl get node kubectl uncordon cka001 \u5728\u5de5\u4f5c\u8282\u70b9\u4e0a\u7684\u6267\u884c\u6b65\u9aa4\uff1a \u5728\u63a7\u5236\u9762\u677f\u4e0a\uff1a kubectl drain cka002 --ignore-daemonsets \u5728\u5de5\u4f5c\u8282\u70b9\u4e0a\uff1a apt-get -y install kubeadm = 1 .24.1-00 --allow-downgrades kubeadm upgrade node apt-get -y install kubelet = 1 .24.1-00 --allow-downgrades systemctl daemon-reload systemctl restart kubelet kubectl uncordon cka002 \u5728\u5176\u4ed6\u5de5\u4f5c\u8282\u70b9\u4e0a\u91cd\u590d\u4e0a\u9762\u7684\u6b65\u9aa4\u3002","title":"Cluster Management"},{"location":"k8s/cka_cn/foundamentals/clustermgt/#cka24cluster-management","text":"\u6f14\u793a\u573a\u666f\uff1a etcd Backup and Restore \u5b89\u88c5 etcdctl \u5728\u5907\u4efd\u4e4b\u524d\u521b\u5efa Deployment \u5907\u4efd etcd \u5728\u5907\u4efd\u4e4b\u540e\u521b\u5efa Deployment \u505c\u6b62\u670d\u52a1 \u505c\u6b62 etcd \u6062\u590d etcd \u542f\u52a8\u670d\u52a1 \u9a8c\u8bc1","title":"CKA\u81ea\u5b66\u7b14\u8bb024:Cluster Management"},{"location":"k8s/cka_cn/foundamentals/clustermgt/#etcd","text":"","title":"etcd\u5907\u4efd\u548c\u6062\u590d"},{"location":"k8s/cka_cn/foundamentals/clustermgt/#etcdctl","text":"\u4e0b\u8f7d etcd \u5b89\u88c5\u5305\u3002 wget https://github.com/etcd-io/etcd/releases/download/v3.5.3/etcd-v3.5.3-linux-amd64.tar.gz \u89e3\u538b etcd \u5b89\u88c5\u5305\uff0c\u5e76\u8d4b\u4e88\u6267\u884c\u6743\u9650\u3002 tar -zxvf etcd-v3.5.3-linux-amd64.tar.gz cp etcd-v3.5.3-linux-amd64/etcdctl /usr/local/bin/ sudo chmod u+x /usr/local/bin/etcdctl \u9a8c\u8bc1\uff1a etcdctl --help","title":"\u5b89\u88c5etcdctl"},{"location":"k8s/cka_cn/foundamentals/clustermgt/#deployment","text":"\u5907\u4efd\u524d\u521b\u5efa\u4e00\u4e2adeployment\u3002 kubectl create deployment app-before-backup --image = nginx","title":"\u521b\u5efa\u4e00\u4e2adeployment\uff08\u5907\u4efd\u524d\uff09"},{"location":"k8s/cka_cn/foundamentals/clustermgt/#etcd_1","text":"\u8bf4\u660e\uff1a \u662f\u63a7\u5236\u5e73\u9762\u8282\u70b9\u7684\u5b9e\u9645IP\u5730\u5740\u3002 --endpoints \uff1a\u6307\u5b9a etcd \u5907\u4efd\u7684\u4fdd\u5b58\u4f4d\u7f6e\uff0c2379 \u662f etcd \u7684\u7aef\u53e3\u53f7\u3002 --cert \uff1a\u6307\u5b9a etcd \u8bc1\u4e66\u7684\u4f4d\u7f6e\uff0c\u8bc1\u4e66\u662f\u7531 kubeadm \u751f\u6210\u5e76\u4fdd\u5b58\u5728 /etc/kubernetes/pki/etcd/ \u76ee\u5f55\u4e0b\u7684\u3002 --key \uff1a\u6307\u5b9a etcd \u8bc1\u4e66\u7684\u79c1\u94a5\u7684\u4f4d\u7f6e\uff0c\u8bc1\u4e66\u662f\u7531 kubeadm \u751f\u6210\u5e76\u4fdd\u5b58\u5728 /etc/kubernetes/pki/etcd/ \u76ee\u5f55\u4e0b\u7684\u3002 --cacert \uff1a\u6307\u5b9a etcd \u8bc1\u4e66\u7684 CA \u7684\u4f4d\u7f6e\uff0c\u8bc1\u4e66\u662f\u7531 kubeadm \u751f\u6210\u5e76\u4fdd\u5b58\u5728 /etc/kubernetes/pki/etcd/ \u76ee\u5f55\u4e0b\u7684\u3002 etcdctl \\ --endpoints = https://:2379 \\ --cert = /etc/kubernetes/pki/etcd/server.crt \\ --key = /etc/kubernetes/pki/etcd/server.key \\ --cacert = /etc/kubernetes/pki/etcd/ca.crt \\ snapshot save snapshot- $( date + \"%Y%m%d%H%M%S\" ) .db \u6216\u8005 etcdctl \\ --endpoints = https://:2379 \\ --cert = /etc/kubernetes/pki/etcd/server.crt \\ --key = /etc/kubernetes/pki/etcd/server.key \\ --cacert = /etc/kubernetes/pki/etcd/ca.crt \\ snapshot save snapshot- $( date + \"%Y%m%d%H%M%S\" ) .db Output: {\"level\":\"info\",\"ts\":\"2022-07-24T18:51:21.328+0800\",\"caller\":\"snapshot/v3_snapshot.go:65\",\"msg\":\"created temporary db file\",\"path\":\"snapshot-20220724185121.db.part\"} {\"level\":\"info\",\"ts\":\"2022-07-24T18:51:21.337+0800\",\"logger\":\"client\",\"caller\":\"v3/maintenance.go:211\",\"msg\":\"opened snapshot stream; downloading\"} {\"level\":\"info\",\"ts\":\"2022-07-24T18:51:21.337+0800\",\"caller\":\"snapshot/v3_snapshot.go:73\",\"msg\":\"fetching snapshot\",\"endpoint\":\"https://:2379\"} {\"level\":\"info\",\"ts\":\"2022-07-24T18:51:21.415+0800\",\"logger\":\"client\",\"caller\":\"v3/maintenance.go:219\",\"msg\":\"completed snapshot read; closing\"} {\"level\":\"info\",\"ts\":\"2022-07-24T18:51:21.477+0800\",\"caller\":\"snapshot/v3_snapshot.go:88\",\"msg\":\"fetched snapshot\",\"endpoint\":\"https://:2379\",\"size\":\"3.6 MB\",\"took\":\"now\"} {\"level\":\"info\",\"ts\":\"2022-07-24T18:51:21.477+0800\",\"caller\":\"snapshot/v3_snapshot.go:97\",\"msg\":\"saved\",\"path\":\"snapshot-20220724185121.db\"} Snapshot saved at snapshot-20220724185121.db \u6267\u884c\u547d\u4ee4 ls -al \u5728\u5f53\u524d\u76ee\u5f55\u4e2d\u8bfb\u53d6\u6211\u4eec\u521a\u521a\u521b\u5efa\u7684\u5907\u4efd\u6587\u4ef6\u3002 -rw------- 1 root root 3616800 Jul 24 18 :51 snapshot-20220724185121.db","title":"\u5907\u4efdetcd"},{"location":"k8s/cka_cn/foundamentals/clustermgt/#deployment_1","text":"\u5907\u4efd\u540e\uff0c\u6211\u4eec\u521b\u5efa\u53e6\u5916\u4e00\u4e2adeployment\u3002 kubectl create deployment app-after-backup --image = nginx \u5220\u9664\u5907\u4efd\u524d\u6211\u4eec\u521b\u5efa\u7684\u90a3\u4e2adeployment\u3002 kubectl delete deployment app-before-backup \u68c0\u67e5deployment\u7684\u72b6\u6001\u3002 kubectl get deploy \u8fd0\u884c\u7ed3\u679c\uff1a NAME READY UP-TO-DATE AVAILABLE AGE app-after-backup 1/1 1 1 108s","title":"\u521b\u5efa\u4e00\u4e2adeployment\uff08\u5907\u4efd\u540e\uff09"},{"location":"k8s/cka_cn/foundamentals/clustermgt/#services","text":"\u5220\u9664 etcd \u7684\u76ee\u5f55\u3002 mv /var/lib/etcd/ /var/lib/etcd.bak \u505c\u6b62 kubelet \u3002 systemctl stop kubelet \u505c\u6b62 kube-apiserver \u3002 nerdctl -n k8s.io ps -a | grep apiserver \u8fd0\u884c\u7ed3\u679c\uff1a 0c5e69118f1b registry.aliyuncs.com/google_containers/kube-apiserver:v1.24.0 \"kube-apiserver --ad\u2026\" 32 hours ago Up k8s://kube-system/kube-apiserver-cka001/kube-apiserver 638bb602c310 registry.aliyuncs.com/google_containers/pause:3.6 \"/pause\" 32 hours ago Up k8s://kube-system/kube-apiserver-cka001 \u505c\u6b62\u90a3\u4e9b\u4ecd\u65e7\u5904\u4e8e up \u72b6\u6001\u7684\u5bb9\u5668\u3002 nerdctl -n k8s.io stop nerdctl -n k8s.io stop 0c5e69118f1b nerdctl -n k8s.io stop 638bb602c310 \u76f4\u81f3\u6ca1\u6709\u5904\u4e8e up \u72b6\u6001\u7684 kube-apiserver \u3002 nerdctl -n k8s.io ps -a | grep apiserver \u8fd0\u884c\u7ed3\u679c\uff1a 0c5e69118f1b registry.aliyuncs.com/google_containers/kube-apiserver:v1.24.0 \"kube-apiserver --ad\u2026\" 32 hours ago Created k8s://kube-system/kube-apiserver-cka001/kube-apiserver 638bb602c310 registry.aliyuncs.com/google_containers/pause:3.6 \"/pause\" 32 hours ago Created k8s://kube-system/kube-apiserver-cka001","title":"\u505c\u6b62Services"},{"location":"k8s/cka_cn/foundamentals/clustermgt/#etcd_2","text":"nerdctl -n k8s.io ps -a | grep etcd \u8fd0\u884c\u7ed3\u679c\uff1a 0965b195f41a registry.aliyuncs.com/google_containers/etcd:3.5.1-0 \"etcd --advertise-cl\u2026\" 32 hours ago Up k8s://kube-system/etcd-cka001/etcd 9e1bea9f25d1 registry.aliyuncs.com/google_containers/pause:3.6 \"/pause\" 32 hours ago Up k8s://kube-system/etcd-cka001 \u505c\u6b62\u90a3\u4e9b\u4ecd\u65e7\u5904\u4e8e up \u72b6\u6001\u7684\u5bb9\u5668\u3002 nerdctl -n k8s.io stop nerdctl -n k8s.io stop 0965b195f41a nerdctl -n k8s.io stop 9e1bea9f25d1 \u76f4\u81f3\u6ca1\u6709\u5904\u4e8e up \u72b6\u6001\u7684 kube-apiserver \u3002 nerdctl -n k8s.io ps -a | grep etcd \u8fd0\u884c\u7ed3\u679c\uff1a 0965b195f41a registry.aliyuncs.com/google_containers/etcd:3.5.1-0 \"etcd --advertise-cl\u2026\" 32 hours ago Created k8s://kube-system/etcd-cka001/etcd 9e1bea9f25d1 registry.aliyuncs.com/google_containers/pause:3.6 \"/pause\" 32 hours ago Created k8s://kube-system/etcd-cka001","title":"\u505c\u6b62etcd"},{"location":"k8s/cka_cn/foundamentals/clustermgt/#etcd_3","text":"\u5728\u63a7\u5236\u5e73\u9762\u8282\u70b9\u4e0a\u6267\u884c\u6062\u590d\u64cd\u4f5c\uff0c\u4f7f\u7528\u5b9e\u9645\u7684\u5907\u4efd\u6587\u4ef6\uff0c\u8fd9\u91cc\u662f\u6587\u4ef6 snapshot-20220724185121.db \u3002 etcdctl snapshot restore snapshot-20220724185121.db \\ --endpoints = :2379 \\ --cert = /etc/kubernetes/pki/etcd/server.crt \\ --key = /etc/kubernetes/pki/etcd/server.key \\ --cacert = /etc/kubernetes/pki/etcd/ca.crt \\ --data-dir = /var/lib/etcd \u8fd0\u884c\u7ed3\u679c\uff1a Deprecated: Use `etcdutl snapshot restore` instead. 2022-07-24T18:57:49+08:00 info snapshot/v3_snapshot.go:248 restoring snapshot {\"path\": \"snapshot-20220724185121.db\", \"wal-dir\": \"/var/lib/etcd/member/wal\", \"data-dir\": \"/var/lib/etcd\", \"snap-dir\": \"/var/lib/etcd/member/snap\", \"stack\": \"go.etcd.io/etcd/etcdutl/v3/snapshot.(*v3Manager).Restore\\n\\t/go/src/go.etcd.io/etcd/release/etcd/etcdutl/snapshot/v3_snapshot.go:254\\ngo.etcd.io/etcd/etcdutl/v3/etcdutl.SnapshotRestoreCommandFunc\\n\\t/go/src/go.etcd.io/etcd/release/etcd/etcdutl/etcdutl/snapshot_command.go:147\\ngo.etcd.io/etcd/etcdctl/v3/ctlv3/command.snapshotRestoreCommandFunc\\n\\t/go/src/go.etcd.io/etcd/release/etcd/etcdctl/ctlv3/command/snapshot_command.go:129\\ngithub.com/spf13/cobra.(*Command).execute\\n\\t/go/pkg/mod/github.com/spf13/cobra@v1.1.3/command.go:856\\ngithub.com/spf13/cobra.(*Command).ExecuteC\\n\\t/go/pkg/mod/github.com/spf13/cobra@v1.1.3/command.go:960\\ngithub.com/spf13/cobra.(*Command).Execute\\n\\t/go/pkg/mod/github.com/spf13/cobra@v1.1.3/command.go:897\\ngo.etcd.io/etcd/etcdctl/v3/ctlv3.Start\\n\\t/go/src/go.etcd.io/etcd/release/etcd/etcdctl/ctlv3/ctl.go:107\\ngo.etcd.io/etcd/etcdctl/v3/ctlv3.MustStart\\n\\t/go/src/go.etcd.io/etcd/release/etcd/etcdctl/ctlv3/ctl.go:111\\nmain.main\\n\\t/go/src/go.etcd.io/etcd/release/etcd/etcdctl/main.go:59\\nruntime.main\\n\\t/go/gos/go1.16.15/src/runtime/proc.go:225\"} 2022-07-24T18:57:49+08:00 info membership/store.go:141 Trimming membership information from the backend... 2022-07-24T18:57:49+08:00 info membership/cluster.go:421 added member {\"cluster-id\": \"cdf818194e3a8c32\", \"local-member-id\": \"0\", \"added-peer-id\": \"8e9e05c52164694d\", \"added-peer-peer-urls\": [\"http://localhost:2380\"]} 2022-07-24T18:57:49+08:00 info snapshot/v3_snapshot.go:269 restored snapshot {\"path\": \"snapshot-20220724185121.db\", \"wal-dir\": \"/var/lib/etcd/member/wal\", \"data-dir\": \"/var/lib/etcd\", \"snap-dir\": \"/var/lib/etcd/member/snap\"} \u68c0\u67e5\u88ab\u5220\u9664\u7684 etcd \u76ee\u5f55\u662f\u5426\u5df2\u7ecf\u4ece\u5907\u4efd\u4e2d\u6062\u590d\u4e86\u3002 tree /var/lib/etcd \u8fd0\u884c\u7ed3\u679c\uff1a /var/lib/etcd \u2514\u2500\u2500 member \u251c\u2500\u2500 snap \u2502 \u251c\u2500\u2500 0000000000000001-0000000000000001.snap \u2502 \u2514\u2500\u2500 db \u2514\u2500\u2500 wal \u2514\u2500\u2500 0000000000000000-0000000000000000.wal","title":"\u6062\u590detcd"},{"location":"k8s/cka_cn/foundamentals/clustermgt/#services_1","text":"\u542f\u52a8 kubelet \u3002\u670d\u52a1 kube-apiserver \u548c etcd \u4e5f\u4f1a\u7ee7 kubelet \u542f\u52a8\u540e\u88ab\u81ea\u52a8\u542f\u52a8\u3002 systemctl start kubelet \u6267\u884c\u4e0b\u9762\u547d\u4ee4\u786e\u8ba4\u6240\u6709\u670d\u52a1\u90fd\u5df2\u7ecf\u542f\u52a8\u548c\u6b63\u5e38\u8fd0\u884c\u3002 systemctl status kubelet.service nerdctl -n k8s.io ps -a | grep etcd nerdctl -n k8s.io ps -a | grep apiserver \u67e5\u770b\u5f53\u524d etcd \u7684\u72b6\u6001\u3002 0965b195f41a registry.aliyuncs.com/google_containers/etcd:3.5.1-0 \"etcd --advertise-cl\u2026\" 32 hours ago Created k8s://kube-system/etcd-cka001/etcd 3b8f37c87782 registry.aliyuncs.com/google_containers/etcd:3.5.1-0 \"etcd --advertise-cl\u2026\" 6 seconds ago Up k8s://kube-system/etcd-cka001/etcd 9e1bea9f25d1 registry.aliyuncs.com/google_containers/pause:3.6 \"/pause\" 32 hours ago Created k8s://kube-system/etcd-cka001 fbbbb628a945 registry.aliyuncs.com/google_containers/pause:3.6 \"/pause\" 6 seconds ago Up k8s://kube-system/etcd-cka001 \u67e5\u770b\u5f53\u524d apiserver \u7684\u72b6\u6001\u3002 0c5e69118f1b registry.aliyuncs.com/google_containers/kube-apiserver:v1.24.0 \"kube-apiserver --ad\u2026\" 32 hours ago Created k8s://kube-system/kube-apiserver-cka001/kube-apiserver 281cf4c6670d registry.aliyuncs.com/google_containers/kube-apiserver:v1.24.0 \"kube-apiserver --ad\u2026\" 14 seconds ago Up k8s://kube-system/kube-apiserver-cka001/kube-apiserver 5ed8295d92da registry.aliyuncs.com/google_containers/pause:3.6 \"/pause\" 15 seconds ago Up k8s://kube-system/kube-apiserver-cka001 638bb602c310 registry.aliyuncs.com/google_containers/pause:3.6 \"/pause\" 32 hours ago Created k8s://kube-system/kube-apiserver-cka001","title":"\u542f\u52a8\u670d\u52a1Services"},{"location":"k8s/cka_cn/foundamentals/clustermgt/#_1","text":"\u68c0\u67e5\u96c6\u7fa4\u7684\u72b6\u6001\uff0c\u67e5\u770b\u662f\u5426pod app-before-backup \u5b58\u5728\u3002 kubectl get deploy \u8fd0\u884c\u7ed3\u679c\uff1a NAME READY UP-TO-DATE AVAILABLE AGE app-before-backup 1/1 1 1 11m","title":"\u9a8c\u8bc1"},{"location":"k8s/cka_cn/foundamentals/clustermgt/#_2","text":"\u6f14\u793a\u573a\u666f\uff1a\u96c6\u7fa4\u5347\u7ea7 \u9a71\u9010\u63a7\u5236\u5e73\u9762\u8282\u70b9 \u68c0\u67e5\u5f53\u524d\u53ef\u7528\u7684 kubeadm \u7248\u672c \u5c06 kubeadm \u5347\u7ea7\u5230\u65b0\u7248\u672c \u68c0\u67e5\u5347\u7ea7\u8ba1\u5212 \u5e94\u7528\u5347\u7ea7\u8ba1\u5212\u4ee5\u5347\u7ea7\u5230\u65b0\u7248\u672c \u5347\u7ea7 kubelet \u548c kubectl \u542f\u7528\u63a7\u5236\u5e73\u9762\u8282\u70b9\u8c03\u5ea6 \u9a71\u9010\u5de5\u4f5c\u8282\u70b9 \u5347\u7ea7 kubeadm \u548c kubelet \u542f\u7528\u5de5\u4f5c\u8282\u70b9\u8c03\u5ea6 \u53c2\u8003\uff1a kubeadm\u5347\u7ea7","title":"\u96c6\u7fa4\u5347\u7ea7"},{"location":"k8s/cka_cn/foundamentals/clustermgt/#_3","text":"","title":"\u5347\u7ea7\u63a7\u5236\u5e73\u9762"},{"location":"k8s/cka_cn/foundamentals/clustermgt/#_4","text":"\u9a71\u9010\u63a7\u5236\u5e73\u9762\u8282\u70b9\u3002 kubectl drain --ignore-daemonsets \u8fd9\u91cc\u662f\uff1a kubectl drain cka001 --ignore-daemonsets \u8fd0\u884c\u7ed3\u679c\uff1a node/cka001 cordoned WARNING: ignoring DaemonSet-managed Pods: kube-system/calico-node-dsx76, kube-system/kube-proxy-cm4hc evicting pod kube-system/calico-kube-controllers-5c64b68895-jr4nl evicting pod kube-system/coredns-6d8c4cb4d-g4jxc evicting pod kube-system/coredns-6d8c4cb4d-sqcvj pod/calico-kube-controllers-5c64b68895-jr4nl evicted pod/coredns-6d8c4cb4d-g4jxc evicted pod/coredns-6d8c4cb4d-sqcvj evicted node/cka001 drained \u63a7\u5236\u5e73\u9762\u8282\u70b9\u73b0\u5728\u5904\u4e8e SchedulingDisabled \u72b6\u6001\u3002 kubectl get node -owide \u8fd0\u884c\u7ed3\u679c\uff1a NAME STATUS ROLES AGE VERSION OS-IMAGE KERNEL-VERSION CONTAINER-RUNTIME cka001 Ready,SchedulingDisabled control-plane,master 32h v1.24.0 Ubuntu 20.04.4 LTS 5.4.0-122-generic containerd://1.5.9 cka002 Ready 32h v1.24.0 Ubuntu 20.04.4 LTS 5.4.0-122-generic containerd://1.5.9 cka003 Ready 32h v1.24.0 Ubuntu 20.04.4 LTS 5.4.0-122-generic containerd://1.5.9 \u67e5\u8be2\u5f53\u524d kubeadm \u53ef\u7528\u7248\u672c\u3002 apt policy kubeadm \u8f93\u51fa\u7ed3\u679c\uff1a kubeadm: Installed: 1.24.0-00 Candidate: 1.24.3-00 Version table: 1.24.3-00 500 500 https://mirrors.aliyun.com/kubernetes/apt kubernetes-xenial/main amd64 Packages 1.24.2-00 500 500 https://mirrors.aliyun.com/kubernetes/apt kubernetes-xenial/main amd64 Packages 1.24.1-00 500 500 https://mirrors.aliyun.com/kubernetes/apt kubernetes-xenial/main amd64 Packages 1.24.0-00 500 500 https://mirrors.aliyun.com/kubernetes/apt kubernetes-xenial/main amd64 Packages 1.24.2-00 500 500 https://mirrors.aliyun.com/kubernetes/apt kubernetes-xenial/main amd64 Packages *** 1.24.0-00 500 500 https://mirrors.aliyun.com/kubernetes/apt kubernetes-xenial/main amd64 Packages 100 /var/lib/dpkg/status 1.23.7-00 500 500 https://mirrors.aliyun.com/kubernetes/apt kubernetes-xenial/main amd64 Packages ...... \u5347\u7ea7 kubeadm \u5230 Candidate: 1.24.2-00 \u7248\u672c\u3002 sudo apt-get -y install kubeadm = 1 .24.2-00 --allow-downgrades \u67e5\u8be2\u5347\u7ea7\u8ba1\u5212\u3002 kubeadm upgrade plan \u8f93\u51fa\u7c7b\u4f3c\u4e0b\u9762\u7684\u5347\u7ea7\u8ba1\u5212\u3002 [upgrade/config] Making sure the configuration is correct: [upgrade/config] Reading configuration from the cluster... [upgrade/config] FYI: You can look at this config file with 'kubectl -n kube-system get cm kubeadm-config -o yaml' [preflight] Running pre-flight checks. [upgrade] Running cluster health checks [upgrade] Fetching available versions to upgrade to [upgrade/versions] Cluster version: v1.24.0 [upgrade/versions] kubeadm version: v1.24.2 I0724 19:05:00.111855 1142460 version.go:255] remote version is much newer: v1.24.3; falling back to: stable-1.23 [upgrade/versions] Target version: v1.24.2 [upgrade/versions] Latest version in the v1.23 series: v1.24.2 Components that must be upgraded manually after you have upgraded the control plane with 'kubeadm upgrade apply': COMPONENT CURRENT TARGET kubelet 3 x v1.24.0 v1.24.2 Upgrade to the latest version in the v1.23 series: COMPONENT CURRENT TARGET kube-apiserver v1.24.0 v1.24.2 kube-controller-manager v1.24.0 v1.24.2 kube-scheduler v1.24.0 v1.24.2 kube-proxy v1.24.0 v1.24.2 CoreDNS v1.8.6 v1.8.6 etcd 3.5.1-0 3.5.1-0 You can now apply the upgrade by executing the following command: kubeadm upgrade apply v1.24.2 _____________________________________________________________________ The table below shows the current state of component configs as understood by this version of kubeadm. Configs that have a \"yes\" mark in the \"MANUAL UPGRADE REQUIRED\" column require manual config upgrade or resetting to kubeadm defaults before a successful upgrade can be performed. The version to manually upgrade to is denoted in the \"PREFERRED VERSION\" column. API GROUP CURRENT VERSION PREFERRED VERSION MANUAL UPGRADE REQUIRED kubeproxy.config.k8s.io v1alpha1 v1alpha1 no kubelet.config.k8s.io v1beta1 v1beta1 no _____________________________________________________________________","title":"\u63a7\u5236\u5e73\u9762\u51c6\u5907"},{"location":"k8s/cka_cn/foundamentals/clustermgt/#_5","text":"\u53c2\u8003\u524d\u9762\u7684\u5347\u7ea7\u8ba1\u5212\uff0c\u6211\u4eec\u5347\u7ea7\u5230 v1.24.2 \u7248\u672c\u3002 kubeadm upgrade apply v1.24.2 \u901a\u8fc7\u9009\u9879 --etcd-upgrade=false \uff0c\u6211\u4eec\u628a etcd \u6392\u9664\u51fa\u5f53\u524d\u5347\u7ea7\u8303\u56f4\u3002 kubeadm upgrade apply v1.24.2 --etcd-upgrade = false \u6536\u5230\u4e0b\u9762\u7684\u4fe1\u606f\uff0c\u5219\u4ee3\u8868\u4e0a\u9762\u7684\u5347\u7ea7\u547d\u4ee4\u6210\u529f\u4e86\u3002 [upgrade/successful] SUCCESS! Your cluster was upgraded to \"v1.24.2\". Enjoy! [upgrade/kubelet] Now that your control plane is upgraded, please proceed with upgrading your kubelets if you haven't already done so. \u5347\u7ea7 kubelet \u548c kubectl \u3002 sudo apt-get -y install kubelet = 1 .24.2-00 kubectl = 1 .24.2-00 --allow-downgrades sudo systemctl daemon-reload sudo systemctl restart kubelet \u67e5\u8be2\u8282\u70b9\u5f53\u524d\u72b6\u6001\u3002 kubectl get node \u8fd0\u884c\u7ed3\u679c\uff1a NAME STATUS ROLES AGE VERSION cka001 Ready,SchedulingDisabled control-plane,master 32h v1.24.2 cka002 Ready 32h v1.24.0 cka003 Ready 32h v1.24.0 After verify that each node is in Ready status, enable node scheduling. \u5728\u786e\u8ba4\u6240\u6709\u8282\u70b9\u90fd\u5904\u4e8eReady\u72b6\u6001\uff0c\u5219\u6fc0\u6d3bscheduling\u3002 kubectl uncordon \u8fd9\u91cc\u662f\uff1a kubectl uncordon cka001 \u8f93\u51fa\u7ed3\u679c\uff1a node/cka001 uncordoned \u518d\u6b21\u68c0\u67e5\u8282\u70b9\u72b6\u6001\uff0c\u786e\u4fdd\u6240\u6709\u8282\u70b9\u90fd\u5904\u4e8eReady\u72b6\u6001\u3002 kubectl get node \u8fd0\u884c\u7ed3\u679c\uff1a NAME STATUS ROLES AGE VERSION cka001 Ready control-plane,master 32h v1.24.2 cka002 Ready 32h v1.24.0 cka003 Ready 32h v1.24.0","title":"\u63a7\u5236\u5e73\u9762\u5347\u7ea7"},{"location":"k8s/cka_cn/foundamentals/clustermgt/#_6","text":"","title":"\u5347\u7ea7\u5de5\u4f5c\u8282\u70b9"},{"location":"k8s/cka_cn/foundamentals/clustermgt/#_7","text":"\u767b\u5f55\u8282\u70b9 cka001 \u3002 \u9a71\u9010 Worker \u8282\u70b9\uff0c\u9700\u8981\u663e\u5f0f\u6307\u5b9a\u662f\u5426\u5220\u9664\u672c\u5730\u5b58\u50a8\u3002 kubectl drain --ignore-daemonsets --force kubectl drain --ignore-daemonsets --delete-emptydir-data --force \u5982\u679c\u9047\u5230\u5173\u4e8e emptydir \u4f9d\u8d56\u7684\u9519\u8bef\uff0c\u5219\u6267\u884c\u7b2c\u4e8c\u4e2a\u547d\u4ee4\u3002 kubectl drain cka002 --ignore-daemonsets --force kubectl drain cka002 --ignore-daemonsets --delete-emptydir-data --force \u8f93\u51fa\u7ed3\u679c\uff1a node/cka002 cordoned WARNING: deleting Pods not managed by ReplicationController, ReplicaSet, Job, DaemonSet or StatefulSet: dev/ubuntu; ignoring DaemonSet-managed Pods: kube-system/calico-node-p5rf2, kube-system/kube-proxy-zvs68 evicting pod ns-netpol/pod-netpol-5b67b6b496-2cgnw evicting pod dev/ubuntu evicting pod dev/app-before-backup-66dc9d5cb-6xc8c evicting pod dev/nfs-client-provisioner-86d7fb78b6-2f5dx evicting pod dev/pod-netpol-2-77478d77ff-l6rzm evicting pod ingress-nginx/ingress-nginx-admission-patch-nk9fv evicting pod ingress-nginx/ingress-nginx-admission-create-lgtdj evicting pod kube-system/coredns-6d8c4cb4d-l4kx4 pod/ingress-nginx-admission-create-lgtdj evicted pod/ingress-nginx-admission-patch-nk9fv evicted pod/nfs-client-provisioner-86d7fb78b6-2f5dx evicted pod/app-before-backup-66dc9d5cb-6xc8c evicted pod/coredns-6d8c4cb4d-l4kx4 evicted pod/pod-netpol-5b67b6b496-2cgnw evicted pod/pod-netpol-2-77478d77ff-l6rzm evicted pod/ubuntu evicted node/cka002 drained","title":"\u5de5\u4f5c\u8282\u70b9\u51c6\u5907"},{"location":"k8s/cka_cn/foundamentals/clustermgt/#_8","text":"\u767b\u5f55\u8282\u70b9 cka002 \u3002 \u4e0b\u8f7d kubeadm \u7684 v1.24.2 \u7248\u672c\u3002 sudo apt-get -y install kubeadm = 1 .24.2-00 --allow-downgrades \u5347\u7ea7 kubeadm \u3002 sudo kubeadm upgrade node \u5347\u7ea7 kubelet \u3002 sudo apt-get -y install kubelet = 1 .24.2-00 --allow-downgrades sudo systemctl daemon-reload sudo systemctl restart kubelet \u786e\u8ba4\u6240\u6709\u8282\u70b9\u90fd\u5904\u4e8eReady\u72b6\u6001\uff0c\u5219\u6fc0\u6d3bscheduling\u3002 kubectl uncordon \u8fd9\u91cc\u662f\uff1a kubectl uncordon cka002","title":"\u5de5\u4f5c\u8282\u70b9\u5347\u7ea7"},{"location":"k8s/cka_cn/foundamentals/clustermgt/#_9","text":"\u67e5\u8be2\u8282\u70b9\u72b6\u6001\u3002 kubectl get node \u8fd0\u884c\u7ed3\u679c\uff1a NAME STATUS ROLES AGE VERSION cka001 Ready control-plane,master 32h v1.24.2 cka002 Ready 32h v1.24.2 cka003 Ready 32h v1.24.0 \u5728\u8282\u70b9 cka003 \u4e0a\u91cd\u590d\u4e0a\u9762\u7684\u6b65\u9aa4\u3002 \u767b\u5f55\u8282\u70b9 cka003 \u3002\u5982\u679c\u9047\u5230\u5173\u4e8e emptydir \u4f9d\u8d56\u7684\u9519\u8bef\uff0c\u5219\u6267\u884c\u7b2c\u4e8c\u4e2a\u547d\u4ee4\u3002 kubectl drain cka003 --ignore-daemonsets --ignore-daemonsets --force kubectl drain cka003 --ignore-daemonsets --ignore-daemonsets --delete-emptydir-data --force \u767b\u5f55\u8282\u70b9 cka003 \uff0c\u6267\u884c\u4e0b\u9762\u7684\u547d\u4ee4\u3002 sudo apt-get -y install kubeadm = 1 .24.2-00 --allow-downgrades sudo kubeadm upgrade node sudo apt-get -y install kubelet = 1 .24.2-00 --allow-downgrades sudo systemctl daemon-reload sudo systemctl restart kubelet kubectl get node kubectl uncordon cka003 \u67e5\u8be2\u8282\u70b9\u72b6\u6001\u3002 kubectl get node \u8fd0\u884c\u7ed3\u679c\uff1a NAME STATUS ROLES AGE VERSION cka001 Ready control-plane,master 32h v1.24.2 cka002 Ready 32h v1.24.2 cka003 Ready 32h v1.24.2","title":"\u5de5\u4f5c\u8282\u70b9\u9a8c\u8bc1"},{"location":"k8s/cka_cn/foundamentals/clustermgt/#_10","text":"\u5728\u63a7\u5236\u9762\u677f\u4e0a\u7684\u6267\u884c\u6b65\u9aa4\uff1a kubectl get node -owide kubectl drain cka001 --ignore-daemonsets kubectl get node -owide apt policy kubeadm apt-get -y install kubeadm = 1 .24.0-00 --allow-downgrades kubeadm upgrade plan kubeadm upgrade apply v1.24.0 # kubeadm upgrade apply v1.24.0 --etcd-upgrade=false apt-get -y install kubelet = 1 .24.0-00 kubectl = 1 .24.0-00 --allow-downgrades systemctl daemon-reload systemctl restart kubelet kubectl get node kubectl uncordon cka001 \u5728\u5de5\u4f5c\u8282\u70b9\u4e0a\u7684\u6267\u884c\u6b65\u9aa4\uff1a \u5728\u63a7\u5236\u9762\u677f\u4e0a\uff1a kubectl drain cka002 --ignore-daemonsets \u5728\u5de5\u4f5c\u8282\u70b9\u4e0a\uff1a apt-get -y install kubeadm = 1 .24.1-00 --allow-downgrades kubeadm upgrade node apt-get -y install kubelet = 1 .24.1-00 --allow-downgrades systemctl daemon-reload systemctl restart kubelet kubectl uncordon cka002 \u5728\u5176\u4ed6\u5de5\u4f5c\u8282\u70b9\u4e0a\u91cd\u590d\u4e0a\u9762\u7684\u6b65\u9aa4\u3002","title":"\u603b\u7ed3"},{"location":"k8s/cka_cn/foundamentals/configuration/","text":"CKA\u81ea\u5b66\u7b14\u8bb015:Configuration \u00b6","title":"Configuration"},{"location":"k8s/cka_cn/foundamentals/configuration/#cka15configuration","text":"","title":"CKA\u81ea\u5b66\u7b14\u8bb015:Configuration"},{"location":"k8s/cka_cn/foundamentals/daemonset/","text":"CKA\u81ea\u5b66\u7b14\u8bb013:DaemonSet \u00b6 \u6f14\u793a\u573a\u666f \u00b6 \u521b\u5efa\u4e00\u4e2aDaemonSet \u521b\u5efa\u7684DaemonSet\u4f1a\u5728\u6bcf\u4e2anode\u8282\u70b9\u4e0a\u8fd0\u884c\u81ea\u5df1\u7684pod\u3002 \u6f14\u793a \u00b6 \u521b\u5efa DaemonSet daemonset-busybox \u3002 kubectl apply -f - << EOF apiVersion: apps/v1 kind: DaemonSet metadata: name: daemonset-busybox labels: app: daemonset-busybox spec: selector: matchLabels: app: daemonset-busybox template: metadata: labels: app: daemonset-busybox spec: tolerations: - key: node-role.kubernetes.io/control-plane effect: NoSchedule - key: node-role.kubernetes.io/master effect: NoSchedule containers: - name: busybox image: busybox:1.28 args: - sleep - \"10000\" EOF \u83b7\u53d6DaemonSet\u7684\u8fd0\u884c\u72b6\u6001\u3002 kubectl get daemonsets daemonset-busybox \u8fd0\u884c\u7ed3\u679c NAME DESIRED CURRENT READY UP-TO-DATE AVAILABLE NODE SELECTOR AGE daemonset-busybox 3 3 3 3 3 5m33s \u83b7\u53d6 DaemonSet \u7684 Pod \u7684\u72b6\u6001\u3002\u8fd9\u4e9bpod\u4f1a\u90e8\u7f72\u5728\u6bcf\u4e2a\u8282\u70b9node\u4e0a\u3002 kubectl get pod -o wide \u8fd0\u884c\u7ed3\u679c NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES daemonset-busybox-54cj5 1 /1 Running 0 44s 10 .244.102.4 cka003 daemonset-busybox-5tl55 1 /1 Running 0 44s 10 .244.228.197 cka001 daemonset-busybox-wg225 1 /1 Running 0 44s 10 .244.112.5 cka002 \u5220\u9664\u6240\u521b\u5efa\u7684\u8d44\u6e90\u3002 kubectl delete daemonset daemonset-busybox","title":"DaemonSet"},{"location":"k8s/cka_cn/foundamentals/daemonset/#cka13daemonset","text":"","title":"CKA\u81ea\u5b66\u7b14\u8bb013:DaemonSet"},{"location":"k8s/cka_cn/foundamentals/daemonset/#_1","text":"\u521b\u5efa\u4e00\u4e2aDaemonSet \u521b\u5efa\u7684DaemonSet\u4f1a\u5728\u6bcf\u4e2anode\u8282\u70b9\u4e0a\u8fd0\u884c\u81ea\u5df1\u7684pod\u3002","title":"\u6f14\u793a\u573a\u666f"},{"location":"k8s/cka_cn/foundamentals/daemonset/#_2","text":"\u521b\u5efa DaemonSet daemonset-busybox \u3002 kubectl apply -f - << EOF apiVersion: apps/v1 kind: DaemonSet metadata: name: daemonset-busybox labels: app: daemonset-busybox spec: selector: matchLabels: app: daemonset-busybox template: metadata: labels: app: daemonset-busybox spec: tolerations: - key: node-role.kubernetes.io/control-plane effect: NoSchedule - key: node-role.kubernetes.io/master effect: NoSchedule containers: - name: busybox image: busybox:1.28 args: - sleep - \"10000\" EOF \u83b7\u53d6DaemonSet\u7684\u8fd0\u884c\u72b6\u6001\u3002 kubectl get daemonsets daemonset-busybox \u8fd0\u884c\u7ed3\u679c NAME DESIRED CURRENT READY UP-TO-DATE AVAILABLE NODE SELECTOR AGE daemonset-busybox 3 3 3 3 3 5m33s \u83b7\u53d6 DaemonSet \u7684 Pod \u7684\u72b6\u6001\u3002\u8fd9\u4e9bpod\u4f1a\u90e8\u7f72\u5728\u6bcf\u4e2a\u8282\u70b9node\u4e0a\u3002 kubectl get pod -o wide \u8fd0\u884c\u7ed3\u679c NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES daemonset-busybox-54cj5 1 /1 Running 0 44s 10 .244.102.4 cka003 daemonset-busybox-5tl55 1 /1 Running 0 44s 10 .244.228.197 cka001 daemonset-busybox-wg225 1 /1 Running 0 44s 10 .244.112.5 cka002 \u5220\u9664\u6240\u521b\u5efa\u7684\u8d44\u6e90\u3002 kubectl delete daemonset daemonset-busybox","title":"\u6f14\u793a"},{"location":"k8s/cka_cn/foundamentals/deployment/","text":"CKA\u81ea\u5b66\u7b14\u8bb09:Deployment \u00b6 \u6458\u8981 \u00b6 \u4fee\u6539\u5df2\u6709\u7684Deployment\uff0c\u6bd4\u5982\uff0c\u589e\u52a0\u7aef\u53e3\u53f7\u7b49\u3002 \u6f14\u793a \u00b6 \u521b\u5efaDeployment nginx \u3002 kubectl create deployment nginx --image = nginx \u6267\u884c\u4ee5\u4e0b\u547d\u4ee4\u4ee5\u83b7\u53d6\u5e26\u6709\u7aef\u53e3\u53f7\u7684yaml\u6a21\u677f\u3002 \u9009\u9879 --port=8080 \u6307\u5b9a\u4e86\u8be5\u5bb9\u5668\u66b4\u9732\u7684\u7aef\u53e3\u53f7\u3002 kubectl create deployment nginx --image = nginx --port = 8080 --dry-run = client -o yaml \u8fd9\u6837\u6211\u4eec\u5c31\u77e5\u9053\u4e86\u6dfb\u52a0\u7aef\u53e3\u53f7\u7684\u8def\u5f84\uff0c\u5c31\u50cf\u4e0b\u9762\u8fd9\u6837\uff1a kubectl explain deployment.spec.template.spec.containers.ports.containerPort \u6267\u884c\u4e0b\u9762\u7684\u547d\u4ee4\u6765\u4fee\u6539\u5f53\u524d\u6b63\u5728\u8fd0\u884c\u7684Deployment\u3002 kubectl edit deployment nginx \u6dfb\u52a0\u4e0b\u97622\u884c\u6765\u5236\u5b9a 8080 \u7aef\u53e3\u548c TCP \u534f\u8bae\u3002 spec : template : spec : containers : - image : nginx name : nginx ports : - containerPort : 8080 protocol : TCP \u901a\u8fc7\u547d\u4ee4 kubectl describe deployment \u6211\u4eec\u53ef\u4ee5\u770b\u5230\u5728Deployment\u4e2d\u7aef\u53e3\u53f7\u548c\u534f\u8bae\u5df2\u7ecf\u88ab\u6b63\u786e\u6dfb\u52a0\u4e86\u3002 Pod Template : Labels : app=nginx Containers : nginx : Image : nginx Port : 8080/TCP Host Port : 0/TCP Environment : Mounts : Volumes : \u901a\u8fc7\u547d\u4ee4 kubectl describe pod \u6211\u4eec\u53ef\u4ee5\u770b\u5230\u5728pod\u4e2d\u7aef\u53e3\u53f7\u548c\u534f\u8bae\u5df2\u7ecf\u88ab\u6b63\u786e\u6dfb\u52a0\u4e86\u3002 Containers : nginx : Container ID : containerd://af4a1243f981497074b5c006ac55fcf795688399871d1dfe91a095321f5c91aa Image : nginx Image ID : docker.io/library/nginx@sha256:1761fb5661e4d77e107427d8012ad3a5955007d997e0f4a3d41acc9ff20467c7 Port : 8080/TCP Host Port : 0/TCP State : Running Started : Sun, 24 Jul 2022 22:50:12 +0800 Ready : True Restart Count : 0 Environment : Mounts : /var/run/secrets/kubernetes.io/serviceaccount from kube-api-access-hftdt (ro) \u4ee5\u4e0b\u662fDeployment\u7684\u4e00\u4e9b\u5173\u952e\u5b57\u6bb5\uff08\u4f7f\u7528 kubectl explain \uff09\uff1a deployment.spec.revisionHistoryLimit \uff1a\u4fdd\u7559\u65e7\u7684 ReplicaSets \u7684\u6570\u91cf\uff0c\u4ee5\u4fbf\u8fdb\u884c\u56de\u6eda\u3002\u9ed8\u8ba4\u4e3a 10 \u3002 deployment.spec.strategy.type \uff1a\u90e8\u7f72\u7684\u7c7b\u578b\u3002\u53ef\u4ee5\u662f Recreate \u6216 RollingUpdate \u3002\u9ed8\u8ba4\u4e3a RollingUpdate \u3002 deployment.spec.strategy.rollingUpdate.maxUnavailable \uff1a\u5728\u66f4\u65b0\u671f\u95f4\u53ef\u4ee5\u4e0d\u53ef\u7528\u7684Pod\u7684\u6700\u5927\u6570\u91cf\u3002\u9ed8\u8ba4\u4e3a 25\uff05 \u3002 deployment.spec.strategy.rollingUpdate.maxSurge \uff1a\u53ef\u4ee5\u5b89\u6392\u7684Pod\u6570\u91cf\u8d85\u51fa\u6240\u9700Pod\u6570\u91cf\u7684\u6700\u5927\u503c\u3002\u9ed8\u8ba4\u4e3a 25\uff05 \u3002\u5982\u679c MaxUnavailable \u4e3a 0 \uff0c\u5219\u6b64\u503c\u4e0d\u80fd\u4e3a 0 \u3002 deployment.spec.minReadySeconds \uff1a\u65b0\u521b\u5efa\u7684Pod\u7684\u6700\u5c0f\u51c6\u5907\u65f6\u95f4\uff08\u6240\u6709\u5bb9\u5668\u90fd\u6ca1\u6709\u5d29\u6e83\uff09\uff0c\u4ee5\u4fbf\u88ab\u89c6\u4e3a\u53ef\u7528\u3002\u9ed8\u8ba4\u4e3a 0 \uff08\u4e00\u65e6\u51c6\u5907\u597d\u5c31\u4f1a\u88ab\u89c6\u4e3a\u53ef\u7528\uff09\u3002","title":"Deployment"},{"location":"k8s/cka_cn/foundamentals/deployment/#cka9deployment","text":"","title":"CKA\u81ea\u5b66\u7b14\u8bb09:Deployment"},{"location":"k8s/cka_cn/foundamentals/deployment/#_1","text":"\u4fee\u6539\u5df2\u6709\u7684Deployment\uff0c\u6bd4\u5982\uff0c\u589e\u52a0\u7aef\u53e3\u53f7\u7b49\u3002","title":"\u6458\u8981"},{"location":"k8s/cka_cn/foundamentals/deployment/#_2","text":"\u521b\u5efaDeployment nginx \u3002 kubectl create deployment nginx --image = nginx \u6267\u884c\u4ee5\u4e0b\u547d\u4ee4\u4ee5\u83b7\u53d6\u5e26\u6709\u7aef\u53e3\u53f7\u7684yaml\u6a21\u677f\u3002 \u9009\u9879 --port=8080 \u6307\u5b9a\u4e86\u8be5\u5bb9\u5668\u66b4\u9732\u7684\u7aef\u53e3\u53f7\u3002 kubectl create deployment nginx --image = nginx --port = 8080 --dry-run = client -o yaml \u8fd9\u6837\u6211\u4eec\u5c31\u77e5\u9053\u4e86\u6dfb\u52a0\u7aef\u53e3\u53f7\u7684\u8def\u5f84\uff0c\u5c31\u50cf\u4e0b\u9762\u8fd9\u6837\uff1a kubectl explain deployment.spec.template.spec.containers.ports.containerPort \u6267\u884c\u4e0b\u9762\u7684\u547d\u4ee4\u6765\u4fee\u6539\u5f53\u524d\u6b63\u5728\u8fd0\u884c\u7684Deployment\u3002 kubectl edit deployment nginx \u6dfb\u52a0\u4e0b\u97622\u884c\u6765\u5236\u5b9a 8080 \u7aef\u53e3\u548c TCP \u534f\u8bae\u3002 spec : template : spec : containers : - image : nginx name : nginx ports : - containerPort : 8080 protocol : TCP \u901a\u8fc7\u547d\u4ee4 kubectl describe deployment \u6211\u4eec\u53ef\u4ee5\u770b\u5230\u5728Deployment\u4e2d\u7aef\u53e3\u53f7\u548c\u534f\u8bae\u5df2\u7ecf\u88ab\u6b63\u786e\u6dfb\u52a0\u4e86\u3002 Pod Template : Labels : app=nginx Containers : nginx : Image : nginx Port : 8080/TCP Host Port : 0/TCP Environment : Mounts : Volumes : \u901a\u8fc7\u547d\u4ee4 kubectl describe pod \u6211\u4eec\u53ef\u4ee5\u770b\u5230\u5728pod\u4e2d\u7aef\u53e3\u53f7\u548c\u534f\u8bae\u5df2\u7ecf\u88ab\u6b63\u786e\u6dfb\u52a0\u4e86\u3002 Containers : nginx : Container ID : containerd://af4a1243f981497074b5c006ac55fcf795688399871d1dfe91a095321f5c91aa Image : nginx Image ID : docker.io/library/nginx@sha256:1761fb5661e4d77e107427d8012ad3a5955007d997e0f4a3d41acc9ff20467c7 Port : 8080/TCP Host Port : 0/TCP State : Running Started : Sun, 24 Jul 2022 22:50:12 +0800 Ready : True Restart Count : 0 Environment : Mounts : /var/run/secrets/kubernetes.io/serviceaccount from kube-api-access-hftdt (ro) \u4ee5\u4e0b\u662fDeployment\u7684\u4e00\u4e9b\u5173\u952e\u5b57\u6bb5\uff08\u4f7f\u7528 kubectl explain \uff09\uff1a deployment.spec.revisionHistoryLimit \uff1a\u4fdd\u7559\u65e7\u7684 ReplicaSets \u7684\u6570\u91cf\uff0c\u4ee5\u4fbf\u8fdb\u884c\u56de\u6eda\u3002\u9ed8\u8ba4\u4e3a 10 \u3002 deployment.spec.strategy.type \uff1a\u90e8\u7f72\u7684\u7c7b\u578b\u3002\u53ef\u4ee5\u662f Recreate \u6216 RollingUpdate \u3002\u9ed8\u8ba4\u4e3a RollingUpdate \u3002 deployment.spec.strategy.rollingUpdate.maxUnavailable \uff1a\u5728\u66f4\u65b0\u671f\u95f4\u53ef\u4ee5\u4e0d\u53ef\u7528\u7684Pod\u7684\u6700\u5927\u6570\u91cf\u3002\u9ed8\u8ba4\u4e3a 25\uff05 \u3002 deployment.spec.strategy.rollingUpdate.maxSurge \uff1a\u53ef\u4ee5\u5b89\u6392\u7684Pod\u6570\u91cf\u8d85\u51fa\u6240\u9700Pod\u6570\u91cf\u7684\u6700\u5927\u503c\u3002\u9ed8\u8ba4\u4e3a 25\uff05 \u3002\u5982\u679c MaxUnavailable \u4e3a 0 \uff0c\u5219\u6b64\u503c\u4e0d\u80fd\u4e3a 0 \u3002 deployment.spec.minReadySeconds \uff1a\u65b0\u521b\u5efa\u7684Pod\u7684\u6700\u5c0f\u51c6\u5907\u65f6\u95f4\uff08\u6240\u6709\u5bb9\u5668\u90fd\u6ca1\u6709\u5d29\u6e83\uff09\uff0c\u4ee5\u4fbf\u88ab\u89c6\u4e3a\u53ef\u7528\u3002\u9ed8\u8ba4\u4e3a 0 \uff08\u4e00\u65e6\u51c6\u5907\u597d\u5c31\u4f1a\u88ab\u89c6\u4e3a\u53ef\u7528\uff09\u3002","title":"\u6f14\u793a"},{"location":"k8s/cka_cn/foundamentals/docker/","text":"CKA\u81ea\u5b66\u7b14\u8bb04:Docker\u57fa\u7840 \u00b6 \u6458\u8981 \u00b6 \u4e86\u89e3Linux\u539f\u8bed\u7684\u6982\u5ff5\u548c\u5305\u542b\u7684\u7279\u6027\u3002 \u5b89\u88c5Docker\uff0c\u4e86\u89e3\u57fa\u672c\u7684Docker\u547d\u4ee4\u548cDockerfile\u7684\u4f7f\u7528\u3002 \u7ec3\u4e60\u73af\u5883 \u00b6 \u64cd\u4f5c\u7cfb\u7edf\uff1aopenSUSE 15.3 cat /etc/os-release \u8f93\u51fa\u7ed3\u679c\uff1a NAME=\"openSUSE Leap\" VERSION=\"15.3\" ID=\"opensuse-leap\" ID_LIKE=\"suse opensuse\" VERSION_ID=\"15.3\" PRETTY_NAME=\"openSUSE Leap 15.3\" ANSI_COLOR=\"0;32\" CPE_NAME=\"cpe:/o:opensuse:leap:15.3\" BUG_REPORT_URL=\"https://bugs.opensuse.org\" HOME_URL=\"https://www.opensuse.org/\" Linux\u539f\u8bed \u00b6 \u5728\u64cd\u4f5c\u7cfb\u7edf\u4e2d\uff0c\u539f\u8bed\uff08primitives\uff09\u662f\u7528\u4e8e\u521b\u5efa\u66f4\u590d\u6742\u529f\u80fd\u7684\u57fa\u672c\u6784\u5efa\u5757\u6216\u64cd\u4f5c\u3002\u5728Linux\u4e2d\uff0c\u6709\u51e0\u79cd\u5e38\u7528\u7684\u539f\u8bed\u3002\u5305\u62ec\uff1a \u8fdb\u7a0b\uff08Processes\uff09\uff1a\u8fdb\u7a0b\u662f\u7a0b\u5e8f\u6216\u5e94\u7528\u7a0b\u5e8f\u7684\u8fd0\u884c\u5b9e\u4f8b\u3002\u5b83\u4eec\u662fLinux\u4e2d\u7684\u57fa\u672c\u5de5\u4f5c\u5355\u5143\uff0c\u7531\u5185\u6838\u7ba1\u7406\u3002 \u6587\u4ef6\uff08Files\uff09\uff1a\u6587\u4ef6\u662f\u5728Linux\u4e2d\u5b58\u50a8\u6570\u636e\u7684\u4e3b\u8981\u65b9\u5f0f\u3002\u5b83\u4eec\u53ef\u4ee5\u662f\u6587\u672c\u6587\u4ef6\u3001\u4e8c\u8fdb\u5236\u6587\u4ef6\u3001\u76ee\u5f55\u6216\u7279\u6b8a\u6587\u4ef6\uff0c\u5982\u8bbe\u5907\u6587\u4ef6\u3002 \u4fe1\u53f7\uff08Signals\uff09\uff1a\u4fe1\u53f7\u662f\u8fdb\u7a0b\u4e4b\u95f4\u6216\u8fdb\u7a0b\u4e0e\u5185\u6838\u4e4b\u95f4\u901a\u4fe1\u7684\u4e00\u79cd\u65b9\u5f0f\u3002\u5b83\u4eec\u7528\u4e8e\u901a\u77e5\u8fdb\u7a0b\u4e8b\u4ef6\uff0c\u4f8b\u5982\u4efb\u52a1\u5b8c\u6210\u6216\u9519\u8bef\u53d1\u751f\u7684\u60c5\u51b5\u3002 \u5957\u63a5\u5b57\uff08Sockets\uff09\uff1a\u5957\u63a5\u5b57\u662fLinux\u4e2d\u8fdb\u7a0b\u95f4\u901a\u4fe1\u7684\u4e00\u79cd\u65b9\u5f0f\u3002\u5b83\u4eec\u5141\u8bb8\u8fdb\u7a0b\u5728\u7f51\u7edc\u6216\u672c\u5730\u673a\u5668\u4e0a\u53d1\u9001\u548c\u63a5\u6536\u6570\u636e\u3002 \u7ebf\u7a0b\uff08Threads\uff09\uff1a\u7ebf\u7a0b\u662f\u8f7b\u91cf\u7ea7\u7684\u8fdb\u7a0b\uff0c\u4e0e\u5176\u7236\u8fdb\u7a0b\u5171\u4eab\u76f8\u540c\u7684\u5185\u5b58\u7a7a\u95f4\u548c\u8d44\u6e90\u3002\u5b83\u4eec\u901a\u5e38\u7528\u4e8e\u901a\u8fc7\u5141\u8bb8\u540c\u65f6\u6267\u884c\u591a\u4e2a\u4efb\u52a1\u6765\u63d0\u9ad8\u5e94\u7528\u7a0b\u5e8f\u7684\u6027\u80fd\u3002 \u7ba1\u9053\uff08Pipes\uff09\uff1a\u7ba1\u9053\u662f\u4e00\u79cd\u5c06\u4e00\u4e2a\u8fdb\u7a0b\u7684\u8f93\u51fa\u8fde\u63a5\u5230\u53e6\u4e00\u4e2a\u8fdb\u7a0b\u7684\u8f93\u5165\u7684\u65b9\u5f0f\u3002\u5b83\u4eec\u5141\u8bb8\u8fdb\u7a0b\u4ee5\u53d7\u63a7\u7684\u65b9\u5f0f\u8fdb\u884c\u901a\u4fe1\u548c\u4ea4\u6362\u6570\u636e\u3002 \u4fe1\u53f7\u91cf\uff08Semaphores\uff09\uff1a\u4fe1\u53f7\u91cf\u662fLinux\u4e2d\u63a7\u5236\u5bf9\u5171\u4eab\u8d44\u6e90\u8bbf\u95ee\u7684\u4e00\u79cd\u65b9\u5f0f\u3002\u5b83\u4eec\u5141\u8bb8\u8fdb\u7a0b\u534f\u8c03\u5b83\u4eec\u5bf9\u5171\u4eab\u8d44\u6e90\u7684\u8bbf\u95ee\uff0c\u5982\u6587\u4ef6\u6216\u5185\u5b58\u3002 chroot \u00b6 chroot\u4f7f\u7528pivot_root\uff0c\u4ee5\u5b9e\u73b0\u5c06*\u8fdb\u7a0b*\u7684\u6839\u76ee\u5f55\u66f4\u6539\u4e3a\u4efb\u4f55\u7ed9\u5b9a\u7684\u76ee\u5f55\u3002 a. \u6a21\u62df\u5bb9\u5668 \u4f7f\u7528 chroot \u547d\u4ee4\u53ef\u4ee5\u5728Linux\u7cfb\u7edf\u4e2d\u521b\u5efa\u4e00\u4e2a\u5bb9\u5668\u3002\u8be5\u5bb9\u5668\u53ef\u4ee5\u770b\u4f5c\u662f\u4e00\u4e2a\u865a\u62df\u7684\u6839\u6587\u4ef6\u7cfb\u7edf\uff0c\u5176\u4e2d\u8fd0\u884c\u7684\u8fdb\u7a0b\u53ea\u80fd\u8bbf\u95ee\u8be5\u6839\u6587\u4ef6\u7cfb\u7edf\u4e2d\u7684\u8d44\u6e90\u3002 \u4f8b\u5982\uff0c\u4ee5\u4e0b\u547d\u4ee4\u4f1a\u5c06\u5f53\u524d\u6839\u6587\u4ef6\u7cfb\u7edf\u66f4\u6539\u4e3a /tmp/myroot \u76ee\u5f55\uff1a chroot /tmp/myroot /bin/bash \u8fd9\u6761\u547d\u4ee4\u4f1a\u542f\u52a8\u4e00\u4e2a\u65b0\u7684Bash shell\uff0c\u8be5shell\u7684\u6839\u76ee\u5f55\u4e3a /tmp/myroot \u3002 b. \u66f4\u6539\u6839\u6587\u4ef6\u7cfb\u7edf chroot \u547d\u4ee4\u8fd8\u53ef\u7528\u4e8e\u66f4\u6539\u8fdb\u7a0b\u7684\u6839\u6587\u4ef6\u7cfb\u7edf\u3002\u4f8b\u5982\uff0c\u6211\u4eec\u53ef\u4ee5\u4f7f\u7528 chroot \u547d\u4ee4\u542f\u52a8\u4e00\u4e2a\u5177\u6709\u53e6\u4e00\u4e2a\u6839\u6587\u4ef6\u7cfb\u7edf\u7684\u8fdb\u7a0b\uff0c\u800c\u4e0d\u662f\u7cfb\u7edf\u7684\u9ed8\u8ba4\u6839\u6587\u4ef6\u7cfb\u7edf\u3002 \u4f8b\u5982\uff0c\u4ee5\u4e0b\u547d\u4ee4\u4f1a\u5c06\u5f53\u524d\u76ee\u5f55\uff08\u5373 ./ \uff09\u4f5c\u4e3a\u6839\u76ee\u5f55\uff0c\u5e76\u5728\u5176\u4e2d\u542f\u52a8\u4e00\u4e2a\u65b0\u7684Bash shell\uff1a sudo chroot . /bin/bash \u547d\u540d\u7a7a\u95f4 \u00b6 \u5728Linux\u64cd\u4f5c\u7cfb\u7edf\u4e2d\uff0cNamespace\uff08\u547d\u540d\u7a7a\u95f4\uff09\u662f\u4e00\u79cd\u673a\u5236\uff0c\u7528\u4e8e\u9694\u79bb\u4e0d\u540c\u8fdb\u7a0b\u7684\u8d44\u6e90\u3002\u901a\u8fc7Namespace\u673a\u5236\uff0c\u53ef\u4ee5\u5c06\u4e00\u7ec4\u8fdb\u7a0b\u53ca\u5176\u5b50\u8fdb\u7a0b\u7684\u89c6\u56fe\u9694\u79bb\u5728\u4e00\u4e2a\u72ec\u7acb\u7684Namespace\u4e2d\uff0c\u4ece\u800c\u5b9e\u73b0\u8fdb\u7a0b\u4e4b\u95f4\u8d44\u6e90\u9694\u79bb\u7684\u76ee\u7684\u3002 \u4e0b\u9762\u662f\u4e00\u4e9b\u5e38\u89c1\u7684Namespace\u7c7b\u578b\u53ca\u5176\u4f5c\u7528\uff1a Mount Namespace\uff1a\u9694\u79bb\u6587\u4ef6\u7cfb\u7edf\u6302\u8f7d\u70b9\u3002\u53ef\u4ee5\u4f7f\u4e0d\u540c\u8fdb\u7a0b\u62e5\u6709\u81ea\u5df1\u7684\u72ec\u7acb\u7684\u6587\u4ef6\u7cfb\u7edf\u89c6\u56fe\u3002 PID Namespace\uff1a\u9694\u79bb\u8fdb\u7a0bID\u53f7\u3002\u53ef\u4ee5\u4f7f\u4e0d\u540c\u8fdb\u7a0b\u62e5\u6709\u81ea\u5df1\u7684\u8fdb\u7a0bID\u53f7\u7a7a\u95f4\uff0c\u907f\u514d\u8fdb\u7a0b\u4e4b\u95f4\u7684PID\u51b2\u7a81\u3002 Network Namespace\uff1a\u9694\u79bb\u7f51\u7edc\u6808\u3002\u53ef\u4ee5\u4f7f\u4e0d\u540c\u8fdb\u7a0b\u62e5\u6709\u81ea\u5df1\u7684\u72ec\u7acb\u7684\u7f51\u7edc\u6808\uff0c\u4ece\u800c\u907f\u514d\u8fdb\u7a0b\u4e4b\u95f4\u7684\u7f51\u7edc\u51b2\u7a81\u3002 IPC Namespace\uff1a\u9694\u79bb\u8fdb\u7a0b\u95f4\u901a\u4fe1\uff08IPC\uff09\u673a\u5236\u3002\u53ef\u4ee5\u4f7f\u4e0d\u540c\u8fdb\u7a0b\u62e5\u6709\u81ea\u5df1\u7684\u72ec\u7acb\u7684IPC\u7a7a\u95f4\uff0c\u4ece\u800c\u907f\u514dIPC\u673a\u5236\u5e26\u6765\u7684\u8d44\u6e90\u7ade\u4e89\u3002 UTS Namespace\uff1a\u9694\u79bb\u4e3b\u673a\u540d\u548c\u57df\u540d\u3002\u53ef\u4ee5\u4f7f\u4e0d\u540c\u8fdb\u7a0b\u62e5\u6709\u81ea\u5df1\u7684\u72ec\u7acb\u7684\u4e3b\u673a\u540d\u548c\u57df\u540d\u7a7a\u95f4\uff0c\u4ece\u800c\u907f\u514d\u8fdb\u7a0b\u4e4b\u95f4\u7684\u547d\u540d\u51b2\u7a81\u3002 Primitives namespace\u548cNamespace\u662f\u4e24\u4e2a\u4e0d\u540c\u7684\u6982\u5ff5\u3002 Namespace\u662fLinux\u64cd\u4f5c\u7cfb\u7edf\u63d0\u4f9b\u7684\u4e00\u79cd\u673a\u5236\uff0c\u7528\u4e8e\u9694\u79bb\u4e0d\u540c\u8fdb\u7a0b\u7684\u8d44\u6e90\uff0c\u4ee5\u5b9e\u73b0\u8fdb\u7a0b\u4e4b\u95f4\u7684\u8d44\u6e90\u9694\u79bb\u548c\u73af\u5883\u9694\u79bb\u3002\u4f8b\u5982\uff0cPID Namespace\u53ef\u4ee5\u4f7f\u4e0d\u540c\u8fdb\u7a0b\u62e5\u6709\u81ea\u5df1\u7684\u72ec\u7acb\u7684PID\u53f7\u7a7a\u95f4\uff0c\u907f\u514d\u8fdb\u7a0b\u4e4b\u95f4\u7684PID\u51b2\u7a81\uff1bNetwork Namespace\u53ef\u4ee5\u4f7f\u4e0d\u540c\u8fdb\u7a0b\u62e5\u6709\u81ea\u5df1\u7684\u72ec\u7acb\u7684\u7f51\u7edc\u6808\uff0c\u4ece\u800c\u907f\u514d\u8fdb\u7a0b\u4e4b\u95f4\u7684\u7f51\u7edc\u51b2\u7a81\u7b49\u3002 Primitives namespace\u662f\u4e00\u79cd\u65b0\u7684\u6280\u672f\u6982\u5ff5\uff0c\u5b83\u662f\u6307\u5c06\u4e0d\u540c\u7684\u57fa\u672c\u64cd\u4f5c\uff08\u4f8b\u5982\u8bfb\u5199\u6587\u4ef6\u3001\u521b\u5efa\u8fdb\u7a0b\u3001\u7f51\u7edc\u901a\u4fe1\u7b49\uff09\u4f5c\u4e3a\u539f\u8bed\u8fdb\u884c\u9694\u79bb\u548c\u5c01\u88c5\uff0c\u4f7f\u5f97\u5e94\u7528\u7a0b\u5e8f\u53ef\u4ee5\u5728\u8fd9\u4e9b\u9694\u79bb\u7684\u539f\u8bed\u4e0a\u6784\u5efa\u51fa\u81ea\u5df1\u7684\u9694\u79bb\u73af\u5883\u3002\u4f8b\u5982\uff0c\u53ef\u4ee5\u901a\u8fc7\u9694\u79bb\u6587\u4ef6\u7cfb\u7edf\u8bfb\u5199\u64cd\u4f5c\u6765\u5b9e\u73b0\u5bb9\u5668\u7ea7\u522b\u7684\u6587\u4ef6\u7cfb\u7edf\u9694\u79bb\uff1b\u901a\u8fc7\u9694\u79bb\u7f51\u7edc\u901a\u4fe1\u64cd\u4f5c\u6765\u5b9e\u73b0\u5bb9\u5668\u7ea7\u522b\u7684\u7f51\u7edc\u9694\u79bb\u7b49\u3002 \u56e0\u6b64\uff0cNamespace\u548cPrimitives namespace\u662f\u4e24\u4e2a\u4e0d\u540c\u7684\u6982\u5ff5\uff0c\u867d\u7136\u5b83\u4eec\u90fd\u53ef\u4ee5\u7528\u4e8e\u5b9e\u73b0\u9694\u79bb\u548c\u5c01\u88c5\u7684\u529f\u80fd\uff0c\u4f46\u662fNamespace\u662f\u4e00\u79cd\u66f4\u4e3a\u901a\u7528\u548c\u5e95\u5c42\u7684\u673a\u5236\uff0cPrimitives namespace\u662f\u4e00\u79cd\u66f4\u4e3a\u9ad8\u5c42\u7684\u62bd\u8c61\u6982\u5ff5\uff0c\u901a\u5e38\u7528\u4e8e\u6784\u5efa\u5bb9\u5668\u7b49\u5e94\u7528\u7ea7\u522b\u7684\u9694\u79bb\u73af\u5883\u3002 Namespace\u793a\u4f8b\uff1a \u5728Linux\u7cfb\u7edf\u4e2d\uff0c\u53ef\u4ee5\u4f7f\u7528PID Namespace\u6765\u9694\u79bb\u8fdb\u7a0bID\u53f7\u7a7a\u95f4\uff0c\u907f\u514d\u8fdb\u7a0b\u4e4b\u95f4\u7684PID\u51b2\u7a81\u3002\u4e0b\u9762\u662f\u4e00\u4e2a\u7b80\u5355\u7684\u793a\u4f8b\uff1a # \u521b\u5efa\u4e00\u4e2a\u65b0\u7684PID Namespace unshare -p /bin/bash # \u5728\u65b0\u7684PID Namespace\u4e2d\u8fd0\u884c\u4e00\u4e2a\u8fdb\u7a0b echo $$ # \u663e\u793a\u5f53\u524d\u8fdb\u7a0b\u7684PID ps aux # \u663e\u793a\u5f53\u524d\u8fdb\u7a0b\u53ca\u5176\u5b50\u8fdb\u7a0b \u5728\u4e0a\u9762\u7684\u793a\u4f8b\u4e2d\uff0c unshare -p \u547d\u4ee4\u521b\u5efa\u4e86\u4e00\u4e2a\u65b0\u7684PID Namespace\uff0c\u5e76\u5728\u5176\u4e2d\u542f\u52a8\u4e86\u4e00\u4e2a\u65b0\u7684bash\u8fdb\u7a0b\u3002\u7531\u4e8e\u8be5\u8fdb\u7a0b\u8fd0\u884c\u5728\u4e00\u4e2a\u72ec\u7acb\u7684PID Namespace\u4e2d\uff0c\u56e0\u6b64\u5b83\u7684PID\u53f7\u4e0e\u4e3b\u673a\u4e0a\u7684\u5176\u4ed6\u8fdb\u7a0b\u4e0d\u4f1a\u51b2\u7a81\u3002\u5728\u8fd9\u4e2a\u65b0\u7684bash\u8fdb\u7a0b\u4e2d\uff0c $$ \u547d\u4ee4\u663e\u793a\u7684\u662f\u8be5\u8fdb\u7a0b\u5728PID Namespace\u4e2d\u7684PID\u53f7\uff0c\u800c ps aux \u547d\u4ee4\u53ea\u4f1a\u663e\u793a\u5f53\u524dPID Namespace\u4e2d\u7684\u8fdb\u7a0b\uff0c\u4e0d\u4f1a\u663e\u793a\u4e3b\u673a\u4e0a\u7684\u5176\u4ed6\u8fdb\u7a0b\u3002 Primitives Namespace\u793a\u4f8b\uff1a \u5728Docker\u5bb9\u5668\u4e2d\uff0c\u53ef\u4ee5\u4f7f\u7528Filesystem Namespace\u6765\u9694\u79bb\u6587\u4ef6\u7cfb\u7edf\uff0c\u4f7f\u5f97\u4e0d\u540c\u7684\u5bb9\u5668\u4e4b\u95f4\u62e5\u6709\u72ec\u7acb\u7684\u6587\u4ef6\u7cfb\u7edf\u89c6\u56fe\u3002\u4e0b\u9762\u662f\u4e00\u4e2a\u7b80\u5355\u7684\u793a\u4f8b\uff1a # \u5728\u5bb9\u5668\u4e2d\u8fd0\u884c\u4e00\u4e2a\u547d\u4ee4 docker run --rm -it --name mycontainer ubuntu bash # \u5728\u5bb9\u5668\u4e2d\u521b\u5efa\u4e00\u4e2a\u6587\u4ef6\u5e76\u9000\u51fa touch myfile exit # \u5728\u4e3b\u673a\u4e0a\u67e5\u770b\u6587\u4ef6 ls myfile # myfile\u6587\u4ef6\u4e0d\u5b58\u5728 # \u518d\u6b21\u8fdb\u5165\u5bb9\u5668 docker start -i mycontainer # \u5728\u5bb9\u5668\u4e2d\u67e5\u770b\u6587\u4ef6 ls myfile # myfile\u6587\u4ef6\u5b58\u5728 \u5728\u4e0a\u9762\u7684\u793a\u4f8b\u4e2d\uff0c docker run \u547d\u4ee4\u542f\u52a8\u4e86\u4e00\u4e2a\u65b0\u7684Docker\u5bb9\u5668\uff0c\u5e76\u5728\u5176\u4e2d\u8fd0\u884c\u4e86\u4e00\u4e2abash\u8fdb\u7a0b\u3002\u7531\u4e8e\u8be5\u5bb9\u5668\u4f7f\u7528\u4e86Filesystem Namespace\uff0c\u56e0\u6b64\u5bb9\u5668\u5185\u7684\u6587\u4ef6\u7cfb\u7edf\u89c6\u56fe\u4e0e\u4e3b\u673a\u4e0a\u7684\u6587\u4ef6\u7cfb\u7edf\u89c6\u56fe\u662f\u9694\u79bb\u7684\u3002\u5728\u5bb9\u5668\u5185\u521b\u5efa\u7684\u6587\u4ef6 myfile \u53ea\u5b58\u5728\u4e8e\u5bb9\u5668\u5185\u90e8\uff0c\u5728\u4e3b\u673a\u4e0a\u662f\u770b\u4e0d\u5230\u7684\u3002\u5f53\u518d\u6b21\u8fdb\u5165\u5bb9\u5668\u65f6\uff0c myfile \u6587\u4ef6\u5c31\u53ef\u4ee5\u88ab\u770b\u5230\u4e86\u3002 \u603b\u7ed3\uff1a Namespace\u662fLinux\u5185\u6838\u63d0\u4f9b\u7684\u673a\u5236\uff0c\u800cPrimitives Namespace\u5219\u662f\u4e00\u79cd\u57fa\u4e8eNamespace\u7684\u9ad8\u5c42\u62bd\u8c61\uff0c\u7528\u4e8e\u5b9e\u73b0\u5e94\u7528\u7ea7\u522b\u7684\u9694\u79bb\u548c\u5c01\u88c5\u3002Namespace\u53ef\u4ee5\u7528\u4e8e\u9694\u79bb\u591a\u79cd\u8d44\u6e90\uff0c\u800cPrimitives Namespace\u901a\u5e38\u7528\u4e8e\u9694\u79bb\u6587\u4ef6\u7cfb\u7edf\u3001\u7f51\u7edc\u3001\u8fdb\u7a0b\u7b49\u64cd\u4f5c\u7684\u539f\u8bed\u3002 \u63a7\u5236\u7ec4 \u00b6 cgroup\uff0c\u5168\u79f0\u4e3aControl Group\uff0c\u5373\u63a7\u5236\u7ec4\uff0c\u662fLinux\u5185\u6838\u63d0\u4f9b\u7684\u4e00\u79cd\u673a\u5236\uff0c\u7528\u4e8e\u9650\u5236\u3001\u8bb0\u5f55\u3001\u9694\u79bb\u548c\u4f18\u5148\u7ea7\u63a7\u5236\u4e00\u7ec4\u8fdb\u7a0b\u7684\u8d44\u6e90\u4f7f\u7528\u3002\u5b83\u53ef\u4ee5\u9650\u5236\u8fdb\u7a0b\u7ec4\u7684CPU\u3001\u5185\u5b58\u3001\u78c1\u76d8\u3001\u7f51\u7edc\u7b49\u8d44\u6e90\u7684\u4f7f\u7528\uff0c\u540c\u65f6\u4e5f\u53ef\u4ee5\u8bb0\u5f55\u8fdb\u7a0b\u7ec4\u7684\u8d44\u6e90\u4f7f\u7528\u60c5\u51b5\u548c\u884c\u4e3a\u3002 cgroup\u901a\u8fc7\u5c06\u4e00\u7ec4\u8fdb\u7a0b\u7ec4\u7ec7\u6210\u4e00\u4e2a\u5c42\u6b21\u7ed3\u6784\uff0c\u5c06\u8d44\u6e90\u5206\u914d\u7ed9\u4e0d\u540c\u7684cgroup\u6765\u5b9e\u73b0\u8d44\u6e90\u9650\u5236\u548c\u4f18\u5148\u7ea7\u63a7\u5236\u3002\u6bcf\u4e2acgroup\u53ef\u4ee5\u8bbe\u7f6e\u8d44\u6e90\u9650\u5236\u548c\u63a7\u5236\u7b56\u7565\uff0c\u4f8b\u5982\u53ef\u4ee5\u9650\u5236\u4e00\u4e2a\u8fdb\u7a0b\u7ec4\u6700\u591a\u4f7f\u752850%\u7684CPU\u65f6\u95f4\uff0c\u6216\u8005\u9650\u5236\u4e00\u4e2a\u8fdb\u7a0b\u7ec4\u6700\u591a\u4f7f\u7528100MB\u7684\u5185\u5b58\u7b49\u3002 cgroup\u6700\u521d\u7531Google\u516c\u53f8\u5f00\u53d1\uff0c\u540e\u6765\u88abLinux\u5185\u6838\u793e\u533a\u91c7\u7eb3\u5e76\u52a0\u5165\u5230\u5185\u6838\u4e2d\uff0c\u6210\u4e3aLinux\u7cfb\u7edf\u7684\u4e00\u90e8\u5206\u3002\u5b83\u5728\u5bb9\u5668\u6280\u672f\u3001\u865a\u62df\u5316\u3001\u4e91\u8ba1\u7b97\u7b49\u9886\u57df\u90fd\u6709\u5e7f\u6cdb\u7684\u5e94\u7528\u3002 \u4e0b\u9762\u662fcgroup \u7684\u4e00\u4e9b\u5e38\u89c1\u7528\u9014\uff1a CPU \u9650\u5236\uff1a\u4f7f\u7528 cgroup \u53ef\u4ee5\u9650\u5236\u8fdb\u7a0b\u7684 CPU \u4f7f\u7528\u7387\uff0c\u907f\u514d\u67d0\u4e2a\u8fdb\u7a0b\u5360\u7528\u8fc7\u591a\u7684 CPU \u8d44\u6e90\u5bfc\u81f4\u7cfb\u7edf\u8d1f\u8f7d\u8fc7\u9ad8\uff0c\u4ece\u800c\u5f71\u54cd\u7cfb\u7edf\u7a33\u5b9a\u6027\u548c\u5176\u4ed6\u8fdb\u7a0b\u7684\u6b63\u5e38\u8fd0\u884c\u3002 \u5185\u5b58\u9650\u5236\uff1a\u4f7f\u7528 cgroup \u53ef\u4ee5\u9650\u5236\u8fdb\u7a0b\u7684\u5185\u5b58\u4f7f\u7528\u91cf\uff0c\u907f\u514d\u67d0\u4e2a\u8fdb\u7a0b\u5360\u7528\u8fc7\u591a\u7684\u5185\u5b58\u8d44\u6e90\u5bfc\u81f4\u7cfb\u7edf\u5185\u5b58\u4e0d\u8db3\uff0c\u4ece\u800c\u5f71\u54cd\u7cfb\u7edf\u6027\u80fd\u548c\u5176\u4ed6\u8fdb\u7a0b\u7684\u6b63\u5e38\u8fd0\u884c\u3002 IO \u9650\u5236\uff1a\u4f7f\u7528 cgroup \u53ef\u4ee5\u9650\u5236\u8fdb\u7a0b\u7684 IO \u5e26\u5bbd\uff0c\u907f\u514d\u67d0\u4e2a\u8fdb\u7a0b\u5360\u7528\u8fc7\u591a\u7684 IO \u8d44\u6e90\u5bfc\u81f4\u5176\u4ed6\u8fdb\u7a0b\u7684 IO \u64cd\u4f5c\u53d7\u5230\u5f71\u54cd\uff0c\u4ece\u800c\u5f71\u54cd\u7cfb\u7edf\u6027\u80fd\u548c\u54cd\u5e94\u901f\u5ea6\u3002 \u7f51\u7edc\u9650\u5236\uff1a\u4f7f\u7528 cgroup \u53ef\u4ee5\u9650\u5236\u8fdb\u7a0b\u7684\u7f51\u7edc\u5e26\u5bbd\uff0c\u907f\u514d\u67d0\u4e2a\u8fdb\u7a0b\u5360\u7528\u8fc7\u591a\u7684\u7f51\u7edc\u8d44\u6e90\u5bfc\u81f4\u7f51\u7edc\u62e5\u585e\uff0c\u4ece\u800c\u5f71\u54cd\u7cfb\u7edf\u6027\u80fd\u548c\u5176\u4ed6\u8fdb\u7a0b\u7684\u6b63\u5e38\u8fd0\u884c\u3002 \u8fdb\u7a0b\u63a7\u5236\uff1a\u4f7f\u7528 cgroup \u53ef\u4ee5\u9650\u5236\u8fdb\u7a0b\u7684\u542f\u52a8\u3001\u505c\u6b62\u548c\u8c03\u5ea6\u7b49\u884c\u4e3a\uff0c\u4ece\u800c\u5b9e\u73b0\u5bf9\u7cfb\u7edf\u8fdb\u7a0b\u7684\u63a7\u5236\u548c\u7ba1\u7406\u3002 \u8d44\u6e90\u7edf\u8ba1\uff1a\u4f7f\u7528 cgroup \u53ef\u4ee5\u5b9e\u65f6\u7edf\u8ba1\u7cfb\u7edf\u4e2d\u5404\u4e2a\u8fdb\u7a0b\u7684\u8d44\u6e90\u4f7f\u7528\u60c5\u51b5\uff0c\u4ece\u800c\u5e2e\u52a9\u7ba1\u7406\u5458\u4e86\u89e3\u7cfb\u7edf\u8d1f\u8f7d\u72b6\u51b5\u548c\u5404\u4e2a\u8fdb\u7a0b\u7684\u6027\u80fd\u74f6\u9888\uff0c\u4ece\u800c\u91c7\u53d6\u76f8\u5e94\u7684\u63aa\u65bd\u4f18\u5316\u7cfb\u7edf\u6027\u80fd\u3002 \u4e0b\u9762\u662fopenSUSE\u4e2d\u7684\u793a\u4f8b\uff1a \u5b89\u88c5\u9700\u8981\u7684\u8f6f\u4ef6\u5305\uff1a sudo zypper install libcgroup-tools \u9650\u5236CPU\u4f7f\u7528\u4e0a\u9650\uff1a # \u521b\u5efa\u65b0\u7684cgroup 'mygroup' sudo mkdir /sys/fs/cgroup/cpu/mygroup # \u7cfb\u7edf\u4f1a\u521b\u5efa\u9ed8\u8ba4\u7684\u4e00\u4e9b\u6587\u4ef6\uff0c\u542b\u521d\u59cb\u503c\uff0c\u6bd4\u5982CPU\u4f7f\u7528\u65f6\u95f4\u7684\u9650\u989d\u7684\u9ed8\u8ba4\u503c\u662f-1 cat /sys/fs/cgroup/cpu/mygroup/cpu.cfs_quota_us # \u8bbe\u5b9aCPU\u4f7f\u7528\u65f6\u95f4\u4e0a\u9650 sudo sh -c \"echo 50000 > /sys/fs/cgroup/cpu/mygroup/cpu.cfs_quota_us\" # \u542f\u52a8\u4e00\u4e2a\u65b0\u7684\u8fdb\u7a0b\uff0c\u5e76\u4e14\u5173\u8054\u5230 sudo cgcreate -g cpu:mygroup sudo cgexec -g cpu:mygroup /bin/bash \u5728\u4e0a\u9762\u7684\u4f8b\u5b50\u4e2d\uff0c cpu.cfs_quota_us \u6587\u4ef6\u8bbe\u7f6e\u4e86 cgroup \u4e2d\u7684\u8fdb\u7a0b\u53ef\u4ee5\u4f7f\u7528\u7684\u6700\u5927 CPU \u65f6\u95f4\u3002\u8be5\u503c\u4ee5\u5fae\u79d2\u4e3a\u5355\u4f4d\uff0c\u56e0\u6b64\u5c06\u5176\u8bbe\u7f6e\u4e3a 50000 \u8868\u793a\u8fdb\u7a0b\u6700\u591a\u53ef\u4ee5\u4f7f\u7528\u5355\u4e2a CPU \u6838\u5fc3\u7684 50%\u3002 cgcreate \u548c cgexec \u547d\u4ee4\u521b\u5efa\u5e76\u5c06\u8fdb\u7a0b /bin/bash \u79fb\u52a8\u5230 mygroup cgroup \u4e2d\u3002 \u9650\u5236\u5185\u5b58\u4f7f\u7528\u4e0a\u9650\uff1a # \u521b\u5efa\u65b0\u7684cgroup 'mygroup' sudo mkdir /sys/fs/cgroup/memory/mygroup # \u7cfb\u7edf\u4f1a\u521b\u5efa\u9ed8\u8ba4\u7684\u4e00\u4e9b\u6587\u4ef6\uff0c\u542b\u521d\u59cb\u503c\uff0c\u6bd4\u5982\u5185\u5b58\u4f7f\u7528\u4e0a\u9650\u7684\u9ed8\u8ba4\u503c\u662f9223372036854771712 cat /sys/fs/cgroup/memory/mygroup/memory.limit_in_bytes # \u8bbe\u7f6e\u5185\u5b58\u4f7f\u7528\u4e0a\u9650512MB sudo sh -c \"echo 536870912 > /sys/fs/cgroup/memory/mygroup/memory.limit_in_bytes\" # \u542f\u52a8\u4e00\u4e2a\u65b0\u7684\u8fdb\u7a0b\uff0c\u5e76\u4e14\u5173\u8054\u5230'mygroup' sudo cgcreate -g memory:mygroup sudo cgexec -g memory:mygroup /bin/bash \u5728\u4e0a\u9762\u4f8b\u5b50\u4e2d\uff0c memory.limit_in_bytes \u6587\u4ef6\u8bbe\u7f6e\u4e86 cgroup \u4e2d\u8fdb\u7a0b\u53ef\u4ee5\u4f7f\u7528\u7684\u6700\u5927\u5185\u5b58\u91cf\u3002\u8be5\u503c\u4ee5\u5b57\u8282\u4e3a\u5355\u4f4d\uff0c\u56e0\u6b64\u5c06\u5176\u8bbe\u7f6e\u4e3a 536870912 \u8868\u793a\u8fdb\u7a0b\u6700\u591a\u53ef\u4ee5\u4f7f\u7528 512MB \u7684\u5185\u5b58\u3002 \u8bbe\u7f6e\u4f18\u5148\u8fdb\u7a0b\u7684 I/O \u4f7f\u7528\u7387\uff1a # \u521b\u5efa\u65b0cgroup 'mygroup' sudo mkdir /sys/fs/cgroup/blkio/mygroup # \u8bbe\u7f6e\u8fdb\u7a0b\u6700\u5927\u8bfb\u548c\u5199\u7684\u901f\u738710MB/s sudo sh -c \"echo '8:0 10485760' > /sys/fs/cgroup/blkio/mygroup/blkio.throttle.read_bps_device\" sudo sh -c \"echo '8:0 10485760' > /sys/fs/cgroup/blkio/mygroup/blkio.throttle.write_bps_device\" # \u542f\u52a8\u4e00\u4e2a\u65b0\u7684\u8fdb\u7a0b\uff0c\u5e76\u4e14\u5173\u8054\u5230'mygroup' sudo cgcreate -g blkio:mygroup sudo cgexec -g blkio:mygroup /bin/bash \u5728\u4e0a\u9762\u4f8b\u5b50\u4e2d\uff0c blkio.throttle.read_bps_device \u548c blkio.throttle.write_bps_device \u6587\u4ef6\u8bbe\u7f6e\u4e86cgroup\u4e2d\u8fdb\u7a0b\u53ef\u4ee5\u4f7f\u7528\u7684\u6700\u5927\u8bfb\u53d6\u548c\u5199\u5165\u5e26\u5bbd\u3002\u8be5\u503c\u4ee5\u6bcf\u79d2\u5b57\u8282\u6570\u4e3a\u5355\u4f4d\uff0c\u56e0\u6b64\u5c06\u5176\u8bbe\u7f6e\u4e3a10485760\u610f\u5473\u7740\u8fdb\u7a0b\u5728\u4e3b\u8bbe\u5907\u53f7:\u6b21\u8bbe\u5907\u53f7\u4e3a8:0\u7684\u8bbe\u5907\uff08\u901a\u5e38\u662f\u7b2c\u4e00\u4e2a\u786c\u76d8\uff09\u4e0a\u8bfb\u53d6\u6216\u5199\u5165\u7684\u5e26\u5bbd\u6700\u591a\u4e3a10MB/s\u3002 \u5c06 8:0 10485760 \u8fd9\u4e2a\u5b57\u7b26\u4e32\u5199\u5165\u5230 /sys/fs/cgroup/blkio/mygroup/blkio.throttle.read_bps_device \u6587\u4ef6\u4e2d\u7684\u4f5c\u7528\u662f\u9650\u5236 mygroup \u63a7\u5236\u7ec4\u4e2d\u5173\u8054\u7684\u5757\u8bbe\u5907\uff08block device\uff09\u7684\u8bfb\u53d6\u901f\u7387\u3002 \u5728 Linux \u4e2d\uff0c blkio \u63a7\u5236\u7ec4\u5b50\u7cfb\u7edf\u53ef\u4ee5\u7528\u6765\u5bf9\u8fdb\u7a0b\u6216\u7ebf\u7a0b\u7684\u5757\u8bbe\u5907\u8bbf\u95ee\u8fdb\u884c\u9650\u5236\uff0c\u5982\u9650\u5236\u8bfb\u5199\u901f\u7387\u3001I/O \u4f18\u5148\u7ea7\u7b49\u3002\u800c blkio.throttle.read_bps_device \u8fd9\u4e2a\u6587\u4ef6\u5219\u7528\u4e8e\u8bbe\u7f6e\u67d0\u4e2a\u5757\u8bbe\u5907\u7684\u8bfb\u53d6\u901f\u7387\u9650\u5236\u3002 \u5177\u4f53\u6765\u8bf4\uff0c 8:0 \u8868\u793a\u8bbe\u5907\u7684\u4e3b\u6b21\u7f16\u53f7\uff08major:minor\uff09\uff0c\u8fd9\u91cc\u662f\u6307\u78c1\u76d8 /dev/sda \u3002 10485760 \u5219\u662f\u8bfb\u53d6\u901f\u7387\u7684\u9650\u5236\u503c\uff0c\u5355\u4f4d\u662f\u5b57\u8282/\u79d2\u3002\u8fd9\u4e2a\u503c\u8868\u793a /dev/sda \u6700\u5927\u8bfb\u53d6\u901f\u7387\u4e3a 10MB/s\uff0c\u8d85\u8fc7\u8fd9\u4e2a\u901f\u7387\u7684\u8bfb\u53d6\u8bf7\u6c42\u4f1a\u88ab\u5ef6\u8fdf\u6267\u884c\uff0c\u4ece\u800c\u9650\u5236\u4e86\u78c1\u76d8\u7684\u8bfb\u53d6\u5e26\u5bbd\u3002 \u56e0\u6b64\uff0c\u4ee5\u4e0a\u547d\u4ee4\u7684\u542b\u4e49\u662f\u5c06 mygroup \u63a7\u5236\u7ec4\u4e2d\u5173\u8054\u7684 /dev/sda \u78c1\u76d8\u7684\u8bfb\u53d6\u901f\u7387\u9650\u5236\u4e3a 10MB/s\uff0c\u4ece\u800c\u5b9e\u73b0\u5bf9\u8be5\u63a7\u5236\u7ec4\u4e2d\u8fdb\u7a0b\u6216\u7ebf\u7a0b\u5bf9\u78c1\u76d8\u8bfb\u53d6\u7684\u9650\u5236\u3002 \u540c\u7406\uff0c\u5c06 8:0 10485760 \u8fd9\u4e2a\u5b57\u7b26\u4e32\u5199\u5165\u5230 /sys/fs/cgroup/blkio/mygroup/blkio.throttle.write_bps_device \u6587\u4ef6\u4e2d\uff0c\u4ee5\u9650\u5236 mygroup \u63a7\u5236\u7ec4\u4e2d\u5173\u8054\u7684\u5757\u8bbe\u5907\uff08block device\uff09\u7684\u5199\u5165\u901f\u7387\u3002 \u9650\u5236\u4e00\u7ec4\u8fdb\u7a0b\u7684\u7f51\u7edc\u5e26\u5bbd\uff1a # \u521b\u5efa\u65b0\u7684cgroup 'mygroup' sudo mkdir /sys/fs/cgroup/net_cls/mygroup # \u5c06\u6b64\u7ec4\u4e2d\u7684\u8fdb\u7a0b\u7684\u7f51\u7edc\u7c7bID\u8bbe\u7f6e\u4e3a\u201cmyclass\u201d sudo sh -c \"echo 0x10001 > /sys/fs/cgroup/net_cls/mygroup/net_cls.classid\" \u4e0a\u9762\u7684\u4f8b\u5b50\u662f\u5c06 0x10001 \u8fd9\u4e2a\u5341\u516d\u8fdb\u5236\u6570\u503c\u5199\u5165\u5230 /sys/fs/cgroup/net_cls/mygroup/net_cls.classid \u6587\u4ef6\u4e2d\uff0c\u4ee5\u6307\u5b9a mygroup \u63a7\u5236\u7ec4\u7684\u7f51\u7edc\u7c7b\u522b\u6807\u8bc6\u7b26\uff08classid\uff09\u3002 \u7f51\u7edc\u7c7b\u522b\u6807\u8bc6\u7b26\u662f Linux \u5185\u6838\u4e2d\u7528\u6765\u5b9e\u73b0\u6d41\u91cf\u63a7\u5236\u548c\u6d41\u91cf\u5206\u7c7b\u7684\u4e00\u4e2a\u673a\u5236\uff0c\u5b83\u53ef\u4ee5\u5c06\u6570\u636e\u5305\u6309\u7167\u4e0d\u540c\u7684\u7c7b\u522b\uff08class\uff09\u8fdb\u884c\u6807\u8bb0\u548c\u533a\u5206\uff0c\u7136\u540e\u5728\u7f51\u7edc\u8bbe\u5907\u4e0a\u9488\u5bf9\u4e0d\u540c\u7684\u7c7b\u522b\u8fdb\u884c\u4e0d\u540c\u7684\u5904\u7406\uff0c\u5982\u9650\u901f\u3001\u4f18\u5148\u7ea7\u8c03\u6574\u7b49\u3002\u63a7\u5236\u7ec4\u4e2d\u7684 net_cls \u5b50\u7cfb\u7edf\u53ef\u4ee5\u7528\u6765\u5c06\u8fdb\u7a0b\u6216\u7ebf\u7a0b\u4e0e\u7f51\u7edc\u7c7b\u522b\u6807\u8bc6\u7b26\u5173\u8054\u8d77\u6765\uff0c\u4ece\u800c\u5b9e\u73b0\u5bf9\u5b83\u4eec\u7684\u7f51\u7edc\u6d41\u91cf\u8fdb\u884c\u63a7\u5236\u548c\u5206\u7c7b\u3002 \u56e0\u6b64\uff0c\u4ee5\u4e0a\u547d\u4ee4\u662f\u5c06 mygroup \u63a7\u5236\u7ec4\u7684\u7f51\u7edc\u7c7b\u522b\u6807\u8bc6\u7b26\u8bbe\u7f6e\u4e3a 0x10001 \uff0c\u8fd9\u6837\u4e0e\u8be5\u63a7\u5236\u7ec4\u76f8\u5173\u8054\u7684\u8fdb\u7a0b\u6216\u7ebf\u7a0b\u5c31\u4f1a\u88ab\u6807\u8bb0\u4e3a\u8be5\u7c7b\u522b\uff0c\u7136\u540e\u53ef\u4ee5\u901a\u8fc7\u5176\u4ed6\u5de5\u5177\uff08\u5982 tc \u547d\u4ee4\uff09\u5bf9\u5176\u8fdb\u884c\u7f51\u7edc\u6d41\u91cf\u63a7\u5236\u548c\u5206\u7c7b\u3002 \u5982\u679c\u9047\u5230\u5bf9\u5e94\u9650\u5236\u6587\u4ef6\u4e0d\u5b58\u5728\uff0c\u4e00\u79cd\u53ef\u80fd\u662f\u9700\u8981\u68c0\u67e5cgroup\u5b50\u7cfb\u6709\u6ca1\u6709\u6b63\u786e\u7edf\u8f7d\u6216\u8005\u6ca1\u6709\u542f\u7528\u5185\u5b58\u5b50\u7cfb\u7edf\u3002 mount | grep cgroup \u5982\u679c cgroups \u6587\u4ef6\u7cfb\u7edf\u5df2\u7ecf\u6302\u8f7d\uff0c\u5e94\u8be5\u4f1a\u770b\u5230\u8f93\u51fa\u7c7b\u4f3c\u4e8e\u4ee5\u4e0b\u5185\u5bb9\uff08\uff09\u4ee5memory\u4e3a\u4f8b\uff09\uff1a cgroup on /sys/fs/cgroup/memory type cgroup (rw,nosuid,nodev,noexec,relatime,memory) \u5982\u679c\u6ca1\u6709\u770b\u5230 memory \u5b57\u6bb5\uff0c\u5219\u8868\u793a\u5185\u5b58\u5b50\u7cfb\u7edf\u6ca1\u6709\u542f\u7528\u3002\u53ef\u4ee5\u7f16\u8f91 /etc/default/grub \u6587\u4ef6\uff0c\u6dfb\u52a0\u6216\u4fee\u6539\u4ee5\u4e0b\u884c\uff1a GRUB_CMDLINE_LINUX_DEFAULT=\"cgroup_enable=memory\" \u7136\u540e\u66f4\u65b0 GRUB \u914d\u7f6e\u5e76\u91cd\u542f\u7cfb\u7edf\uff1a sudo update-grub sudo reboot \u91cd\u542f\u540e\u518d\u6b21\u68c0\u67e5 /sys/fs/cgroup/memory/mygroup/memory.limit_in_bytes \u6587\u4ef6\u662f\u5426\u5b58\u5728\u3002\u5982\u679c\u8fd8\u662f\u4e0d\u5b58\u5728\uff0c\u53ef\u80fd\u9700\u8981\u624b\u52a8\u521b\u5efa\u5b83\u4ee5\u53ca\u5176\u4ed6\u76f8\u5173\u7684 cgroups \u6587\u4ef6\u3002\u4f8b\u5982\uff0c\u8fd0\u884c\u4ee5\u4e0b\u547d\u4ee4\uff1a sudo mkdir /sys/fs/cgroup/memory/mygroup sudo touch /sys/fs/cgroup/memory/mygroup/memory.limit_in_bytes \u7136\u540e\u5c31\u53ef\u4ee5\u50cf\u4e4b\u524d\u7684\u4f8b\u5b50\u4e00\u6837\u8bbe\u7f6e\u5185\u5b58\u9650\u5236\u4e86 Apparmor\u548cSELinux\u914d\u7f6e\u6587\u4ef6 \u00b6 \u5b89\u5168\u914d\u7f6e\u6587\u4ef6\uff0c\u7528\u4e8e\u63a7\u5236\u5bf9\u8d44\u6e90\u7684\u8bbf\u95ee AppArmor \u548c SELinux \u90fd\u662f\u5e38\u89c1\u7684\u5f3a\u5236\u8bbf\u95ee\u63a7\u5236\uff08MAC\uff09\u673a\u5236\uff0c\u53ef\u4ee5\u5bf9\u8fdb\u7a0b\u6216\u5e94\u7528\u7a0b\u5e8f\u7684\u8bbf\u95ee\u6743\u9650\u8fdb\u884c\u7cbe\u7ec6\u63a7\u5236\u3002\u4e0b\u9762\u5206\u522b\u4e3e\u4f8b\u8bf4\u660e\u8fd9\u4e24\u79cd\u673a\u5236\u7684\u914d\u7f6e\u6587\u4ef6\u4f7f\u7528\u3002 AppArmor AppArmor \u7684\u4e3b\u914d\u7f6e\u6587\u4ef6\u662f /etc/apparmor/profiles.d/ \u76ee\u5f55\u4e0b\u7684\u5404\u4e2a\u6587\u4ef6\uff0c\u6bcf\u4e2a\u6587\u4ef6\u5bf9\u5e94\u4e00\u4e2a\u5e94\u7528\u7a0b\u5e8f\u6216\u8fdb\u7a0b\u7684\u914d\u7f6e\u3002\u4ee5 sshd \u670d\u52a1\u4e3a\u4f8b\uff0c\u8be5\u670d\u52a1\u7684\u914d\u7f6e\u6587\u4ef6\u662f /etc/apparmor.d/usr.sbin.sshd \u3002 \u8be5\u914d\u7f6e\u6587\u4ef6\u7684\u5185\u5bb9\u7c7b\u4f3c\u4e8e\u4e0b\u9762\u8fd9\u6837\uff1a # Last Modified: Sun Mar 14 18 :53:00 2023 # include /usr/sbin/sshd { # include # include # allow read access to user home directories /home/** r, # allow sshd to execute /usr/bin/which to determine full path of shell /usr/bin/which ix, # allow sshd to read its own configuration file /etc/ssh/sshd_config r, # allow sshd to read the SSH host keys /etc/ssh/ssh_host_* r, # allow sshd to use pam for authentication /usr/share/pam/** r, # allow sshd to use nsswitch for name resolution /etc/nsswitch.conf r, /etc/hosts r, /etc/hostname r, /etc/resolv.conf r, # allow sshd to write to its own log file /var/log/auth.log w, # allow sshd to create and manage pid files /var/run/sshd.pid w, /var/run/sshd.dir/ w, /var/run/sshd.dir/* rw, # allow sshd to access systemd-logind /run/systemd/* r, /run/systemd/session/*.scope r, /run/systemd/sessions/*.scope r, # deny everything else deny /, } \u8be5\u914d\u7f6e\u6587\u4ef6\u5b9a\u4e49\u4e86 /usr/sbin/sshd \u8fdb\u7a0b\u7684\u6743\u9650\u9650\u5236\u89c4\u5219\uff0c\u5305\u62ec\u5141\u8bb8\u8bbf\u95ee\u7684\u6587\u4ef6\u3001\u7981\u6b62\u8bbf\u95ee\u7684\u6587\u4ef6\u7b49\u3002\u5176\u4e2d #include \u8868\u793a\u5305\u542b\u4e86\u4e00\u7ec4\u901a\u7528\u7684\u6743\u9650\u89c4\u5219\uff0c\u53ef\u4ee5\u5728\u4e0d\u540c\u7684\u5e94\u7528\u7a0b\u5e8f\u914d\u7f6e\u4e2d\u91cd\u590d\u4f7f\u7528\u3002 2.SELinux SELinux \u7684\u4e3b\u914d\u7f6e\u6587\u4ef6\u662f /etc/selinux/config \uff0c\u8be5\u6587\u4ef6\u5b9a\u4e49\u4e86\u7cfb\u7edf\u7684 SELinux \u7b56\u7565\u548c\u6a21\u5f0f\u3002\u9ed8\u8ba4\u60c5\u51b5\u4e0b\uff0copenSUSE \u4f7f\u7528\u7684\u662f targeted \u6a21\u5f0f\u3002 \u6bcf\u4e2a\u8fdb\u7a0b\u6216\u5e94\u7528\u7a0b\u5e8f\u8fd8\u9700\u8981\u5bf9\u5e94\u4e00\u4e2a SELinux \u914d\u7f6e\u6587\u4ef6\uff0c\u4ee5\u5b9a\u4e49\u5b83\u4eec\u7684\u8bbf\u95ee\u6743\u9650\u3002\u4ee5 httpd \u670d\u52a1\u4e3a\u4f8b\uff0c\u8be5\u670d\u52a1\u7684 SELinux \u914d\u7f6e\u6587\u4ef6\u662f /etc/selinux/targeted/contexts/httpd.te \u3002 \u8be5\u914d\u7f6e\u6587\u4ef6\u7684\u5185\u5bb9\u7c7b\u4f3c\u4e8e\u4e0b\u9762\u8fd9\u6837\uff1a # HTTPD server type httpd_t ; type httpd_sys_script_t ; init_daemon_domain ( httpd_t, httpd_sys_script_t ) \u8be5\u914d\u7f6e\u6587\u4ef6\u5b9a\u4e49\u4e86 httpd \u670d\u52a1\u7684 SELinux \u7c7b\u578b\u4e3a httpd_t \uff0c\u5e76\u4f7f\u7528\u4e86 httpd_sys_script_t \u4f5c\u4e3a\u5176\u521d\u59cb\u5316\u57df\u3002\u5176\u4e2d type \u8868\u793a SELinux \u7c7b\u578b\uff0c init_daemon_domain \u5219\u662f\u4e00\u4e2a SELinux \u5b8f\uff0c\u7528\u4e8e\u5b9a\u4e49\u670d\u52a1\u7684\u521d\u59cb\u57df\u3002 \u9700\u8981\u6ce8\u610f\u7684\u662f\uff0c\u5728 SELinux \u4e2d\uff0c\u8bbf\u95ee\u6743\u9650\u89c4\u5219\u4e0d\u662f\u76f4\u63a5\u5728\u914d\u7f6e\u6587\u4ef6\u4e2d\u5b9a\u4e49\u7684\uff0c\u800c\u662f\u901a\u8fc7\u8bbf\u95ee\u63a7\u5236\u7b56\u7565\u548c\u89c4\u5219\u8fdb\u884c\u63a7\u5236\u3002\u8fd9\u4e9b\u7b56\u7565\u548c\u89c4\u5219\u53ef\u4ee5\u4f7f\u7528 SELinux \u5de5\u5177\u96c6\uff08\u5982 semanage \u3001 setsebool \u3001 restorecon \u7b49\uff09\u8fdb\u884c\u7ba1\u7406\u548c\u8bbe\u7f6e\u3002 \u6bd4\u5982\uff0c\u5728openSUSE\u4e2d\u53ef\u4ee5\u770b\u5230 /etc/selinux/semanage.conf \u6587\u4ef6\u548c\u5176\u4e2d\u7684\u914d\u7f6e\u3002 \u5185\u6838\u80fd\u529b \u00b6 \u5185\u6838\u80fd\u529b\uff08Kernel capabilities\uff09 \u6ca1\u6709\u80fd\u529b\uff1aroot\u53ef\u4ee5\u6267\u884c\u6240\u6709\u64cd\u4f5c\uff0c\u5176\u4ed6\u7528\u6237\u53ef\u80fd\u4ec0\u4e48\u4e5f\u505a\u4e0d\u4e86 38\u4e2a\u7ec6\u7c92\u5ea6\u7684\u529f\u80fd\u6765\u63a7\u5236\u6743\u9650 Kernel capabilities \u662f Linux \u5185\u6838\u63d0\u4f9b\u7684\u4e00\u79cd\u673a\u5236\uff0c\u7528\u4e8e\u63a7\u5236\u8fdb\u7a0b\u5bf9\u7cfb\u7edf\u8d44\u6e90\u7684\u8bbf\u95ee\u6743\u9650\u3002\u4e0e\u4f20\u7edf\u7684 Unix \u6743\u9650\u673a\u5236\u4e0d\u540c\uff0cKernel capabilities \u53ef\u4ee5\u4f7f\u7ba1\u7406\u5458\u5728\u7cbe\u7ec6\u63a7\u5236\u7cfb\u7edf\u8d44\u6e90\u8bbf\u95ee\u7684\u540c\u65f6\uff0c\u907f\u514d\u5c06\u8fc7\u591a\u6743\u9650\u6388\u4e88\u8fdb\u7a0b\uff0c\u63d0\u9ad8\u4e86\u7cfb\u7edf\u7684\u5b89\u5168\u6027\u3002 \u5728\u4f20\u7edf Unix \u6743\u9650\u673a\u5236\u4e2d\uff0c\u6bcf\u4e2a\u8fdb\u7a0b\u90fd\u6709\u4e00\u4e2a\u6709\u6548\u7528\u6237 ID \u548c\u4e00\u4e2a\u6709\u6548\u7ec4 ID\uff0c\u8fd9\u4e9b ID \u51b3\u5b9a\u4e86\u8be5\u8fdb\u7a0b\u5bf9\u6587\u4ef6\u3001\u8bbe\u5907\u3001\u7f51\u7edc\u7b49\u8d44\u6e90\u7684\u8bbf\u95ee\u6743\u9650\u3002\u4f46\u662f\uff0c\u8fd9\u79cd\u6743\u9650\u673a\u5236\u4e0d\u591f\u7075\u6d3b\uff0c\u5982\u679c\u8981\u6388\u4e88\u8fdb\u7a0b\u67d0\u4e9b\u7279\u5b9a\u7684\u6743\u9650\uff0c\u53ef\u80fd\u9700\u8981\u5c06\u6240\u6709\u7684\u6743\u9650\u90fd\u6388\u4e88\u7ed9\u5b83\uff0c\u4ece\u800c\u964d\u4f4e\u4e86\u7cfb\u7edf\u7684\u5b89\u5168\u6027\u3002 Kernel capabilities \u63d0\u4f9b\u4e86\u4e00\u79cd\u66f4\u7ec6\u7c92\u5ea6\u7684\u6743\u9650\u63a7\u5236\u65b9\u5f0f\u3002\u6bcf\u4e2a\u8fdb\u7a0b\u90fd\u6709\u4e00\u7ec4 capabilities\uff0c\u6bcf\u4e2a capability \u8868\u793a\u4e00\u79cd\u7279\u5b9a\u7684\u6743\u9650\u3002\u8fdb\u7a0b\u53ef\u4ee5\u8bf7\u6c42\u548c\u91ca\u653e\u67d0\u4e9b capability\uff0c\u8fd9\u6837\u5c31\u53ef\u4ee5\u5c06\u6743\u9650\u6388\u4e88\u8fdb\u7a0b\uff0c\u800c\u4e0d\u5fc5\u6388\u4e88\u6240\u6709\u6743\u9650\u3002 \u4f8b\u5982\uff0c\u53ef\u4ee5\u5c06 CAP_NET_BIND_SERVICE capability \u6388\u4e88\u67d0\u4e2a\u8fdb\u7a0b\uff0c\u8fd9\u6837\u8be5\u8fdb\u7a0b\u5c31\u53ef\u4ee5\u7ed1\u5b9a 1-1023 \u7684\u7aef\u53e3\uff0c\u800c\u4e0d\u5fc5\u5177\u6709 root \u6743\u9650\u3002\u7c7b\u4f3c\u5730\uff0c\u53ef\u4ee5\u5c06 CAP_SYS_ADMIN capability \u6388\u4e88\u67d0\u4e2a\u8fdb\u7a0b\uff0c\u8fd9\u6837\u8be5\u8fdb\u7a0b\u5c31\u53ef\u4ee5\u6267\u884c\u7cfb\u7edf\u7ba1\u7406\u4efb\u52a1\uff0c\u5982\u6302\u8f7d\u6587\u4ef6\u7cfb\u7edf\u548c\u521b\u5efa\u8bbe\u5907\u8282\u70b9\u7b49\u3002 Linux \u5185\u6838\u63d0\u4f9b\u4e86\u4e00\u7ec4\u9ed8\u8ba4\u7684 capabilities\uff0c\u4e5f\u53ef\u4ee5\u901a\u8fc7\u81ea\u5b9a\u4e49\u7684\u65b9\u5f0f\u521b\u5efa\u65b0\u7684 capabilities\uff0c\u4ee5\u4fbf\u66f4\u597d\u5730\u63a7\u5236\u7cfb\u7edf\u8d44\u6e90\u7684\u8bbf\u95ee\u6743\u9650\u3002\u53ef\u4ee5\u4f7f\u7528 setcap \u547d\u4ee4\u4e3a\u4e8c\u8fdb\u5236\u6587\u4ef6\u8bbe\u7f6e capabilities\u3002\u4f8b\u5982\uff0c\u4e0b\u9762\u7684\u547d\u4ee4\u5c06 CAP_NET_RAW capability \u6388\u4e88 /usr/bin/ping \u547d\u4ee4\uff1a sudo setcap cap_net_raw+ep /usr/bin/ping \u8fd9\u6837\uff0c\u7528\u6237\u5c31\u53ef\u4ee5\u4f7f\u7528 ping \u547d\u4ee4\u800c\u4e0d\u5fc5\u4ee5 root \u7528\u6237\u7684\u8eab\u4efd\u767b\u5f55\u3002 \u9664\u4e86 CAP_NET_BIND_SERVICE \u548c CAP_SYS_ADMIN \uff0c\u8fd8\u6709\u4e00\u4e9b\u5176\u4ed6\u7684 capabilities\uff0c\u4ee5\u4e0b\u662f\u4e00\u4e9b\u4f8b\u5b50\uff1a CAP_DAC_OVERRIDE \uff1a\u5141\u8bb8\u8fdb\u7a0b\u5ffd\u7565\u6587\u4ef6\u6743\u9650\uff0c\u53ef\u4ee5\u8bbf\u95ee\u4efb\u4f55\u6587\u4ef6\u3002 CAP_CHOWN \uff1a\u5141\u8bb8\u8fdb\u7a0b\u4fee\u6539\u6587\u4ef6\u7684\u6240\u6709\u8005\u3002 CAP_SETUID \u548c CAP_SETGID \uff1a\u5141\u8bb8\u8fdb\u7a0b\u4fee\u6539\u81ea\u5df1\u7684\u7528\u6237 ID \u548c\u7ec4 ID\u3002 CAP_NET_ADMIN \uff1a\u5141\u8bb8\u8fdb\u7a0b\u6267\u884c\u7f51\u7edc\u7ba1\u7406\u4efb\u52a1\uff0c\u5982\u914d\u7f6e\u7f51\u7edc\u63a5\u53e3\u548c\u8def\u7531\u8868\u7b49\u3002 CAP_SYS_RESOURCE \uff1a\u5141\u8bb8\u8fdb\u7a0b\u4fee\u6539\u7cfb\u7edf\u8d44\u6e90\u9650\u5236\uff0c\u5982 CPU \u65f6\u95f4\u548c\u5185\u5b58\u9650\u5236\u7b49\u3002 \u53ef\u4ee5\u901a\u8fc7\u547d\u4ee4 man 7 capabilities \u6765\u67e5\u770b\u7cfb\u7edf\u63d0\u4f9b\u7684 capabilities \u5217\u8868\u548c\u8be6\u7ec6\u8bf4\u660e\u3002\u5728\u4f7f\u7528 Kernel capabilities \u65f6\uff0c\u9700\u8981\u6ce8\u610f\uff0c\u53ea\u6709\u62e5\u6709 CAP_SETFCAP \u6216 CAP_SYS_ADMIN capability \u7684\u8fdb\u7a0b\u624d\u80fd\u591f\u4fee\u6539\u81ea\u5df1\u6216\u5176\u4ed6\u8fdb\u7a0b\u7684 capabilities\uff0c\u8fd9\u4e5f\u662f\u4e3a\u4e86\u4fdd\u62a4\u7cfb\u7edf\u7684\u5b89\u5168\u6027\u3002 \u5982\u679c\u6267\u884c setcap \u547d\u4ee4\u65f6\u51fa\u73b0 \"command not found\" \u7684\u9519\u8bef\uff0c\u8fd9\u901a\u5e38\u610f\u5473\u7740 setcap \u547d\u4ee4\u6240\u5728\u7684\u5305\u5c1a\u672a\u5b89\u88c5\u3002\u5728 openSUSE \u4e2d\uff0csetcap \u547d\u4ee4\u5305\u542b\u5728 libcap-progs \u8f6f\u4ef6\u5305\u4e2d\u3002 \u5728 openSUSE \u7cfb\u7edf\u4e2d\u9700\u8981\u5b89\u88c5 libcap-progs \u8f6f\u4ef6\u5305\uff1a sudo zypper in libcap-progs \u5728 Ubuntu/Debian \u7cfb\u7edf\u4e0a\u9700\u8981\u5b89\u88c5 libcap \u5e93\uff1a sudo apt-get install libcap2-bin \u5728 CentOS/RHEL \u7cfb\u7edf\u4e0a\u9700\u8981\u5b89\u88c5 libcap \u5e93\uff1a sudo yum install libcap-devel \u5b89\u88c5\u5b8c\u6210\u540e\uff0c\u53ef\u4ee5\u4f7f\u7528 setcap \u547d\u4ee4\u4e3a\u4e8c\u8fdb\u5236\u6587\u4ef6\u8bbe\u7f6e capabilities\u3002\u5982\u679c\u8fd8\u662f\u65e0\u6cd5\u627e\u5230 setcap \u547d\u4ee4\uff0c\u53ef\u4ee5\u5c1d\u8bd5\u4f7f\u7528\u5b8c\u6574\u8def\u5f84 /sbin/setcap \u6216\u8005 /usr/sbin/setcap\u3002 seccomp\u7b56\u7565 \u00b6 seccomp\uff08secure computing mode\uff09\u662f Linux \u5185\u6838\u63d0\u4f9b\u7684\u4e00\u79cd\u5b89\u5168\u673a\u5236\uff0c\u5b83\u53ef\u4ee5\u9650\u5236\u8fdb\u7a0b\u80fd\u591f\u8fdb\u884c\u7684\u7cfb\u7edf\u8c03\u7528\u3002\u901a\u8fc7\u4f7f\u7528 seccomp\uff0c\u53ef\u4ee5\u9650\u5236\u8fdb\u7a0b\u53ea\u80fd\u591f\u4f7f\u7528\u5fc5\u8981\u7684\u7cfb\u7edf\u8c03\u7528\uff0c\u4ece\u800c\u51cf\u5c11\u7cfb\u7edf\u88ab\u653b\u51fb\u7684\u98ce\u9669\u3002 seccomp \u7b56\u7565\u53ef\u4ee5\u4f7f\u7528 BPF\uff08Berkeley Packet Filter\uff09\u8bed\u8a00\u7f16\u5199\uff0c\u5e76\u4f7f\u7528 seccomp() \u7cfb\u7edf\u8c03\u7528\u52a0\u8f7d\u3002\u4ee5\u4e0b\u662f\u4e00\u4e2a\u4f7f\u7528 seccomp \u7b56\u7565\u9650\u5236\u8fdb\u7a0b\u80fd\u591f\u8fdb\u884c\u7684\u7cfb\u7edf\u8c03\u7528\u7684\u793a\u4f8b\uff1a #include #include #include int main () { // \u521b\u5efa seccomp \u8fc7\u6ee4\u5668 struct sock_filter filter [] = { BPF_STMT ( BPF_LD | BPF_W | BPF_ABS , 0 ), BPF_JUMP ( BPF_JMP | BPF_JEQ | BPF_K , __NR_write , 0 , 1 ), BPF_STMT ( BPF_RET | BPF_K , SECCOMP_RET_ALLOW ), BPF_STMT ( BPF_RET | BPF_K , SECCOMP_RET_KILL ), }; struct sock_fprog prog = { . len = sizeof ( filter ) / sizeof ( filter [ 0 ]), . filter = filter , }; // \u52a0\u8f7d seccomp \u8fc7\u6ee4\u5668 if ( prctl ( PR_SET_SECCOMP , SECCOMP_MODE_FILTER , & prog ) < 0 ) { perror ( \"prctl\" ); return 1 ; } // \u8c03\u7528 write \u7cfb\u7edf\u8c03\u7528 char buf [] = \"Hello, world!\" ; write ( 1 , buf , sizeof ( buf )); return 0 ; } \u4e0a\u8ff0\u4ee3\u7801\u521b\u5efa\u4e86\u4e00\u4e2a seccomp \u8fc7\u6ee4\u5668\uff0c\u4ec5\u5141\u8bb8\u8fdb\u7a0b\u8c03\u7528 write() \u7cfb\u7edf\u8c03\u7528\uff0c\u5176\u4ed6\u7cfb\u7edf\u8c03\u7528\u5747\u4f1a\u88ab\u7981\u6b62\u3002\u53ef\u4ee5\u901a\u8fc7\u7f16\u8bd1\u5e76\u8fd0\u884c\u4e0a\u8ff0\u4ee3\u7801\u6765\u6f14\u793a seccomp \u7b56\u7565\u7684\u4f5c\u7528\u3002 \u9700\u8981\u6ce8\u610f\u7684\u662f\uff0cseccomp \u7b56\u7565\u53ea\u80fd\u591f\u9650\u5236\u8fdb\u7a0b\u8fdb\u884c\u7684\u7cfb\u7edf\u8c03\u7528\uff0c\u4f46\u4e0d\u80fd\u591f\u9650\u5236\u7cfb\u7edf\u8c03\u7528\u7684\u53c2\u6570\u6216\u8fd4\u56de\u503c\u3002\u56e0\u6b64\uff0c\u4f7f\u7528 seccomp \u7b56\u7565\u65f6\u9700\u8981\u7279\u522b\u5c0f\u5fc3\uff0c\u907f\u514d\u8bef\u7528\u6216\u4ea7\u751f\u6f0f\u6d1e\u3002 Netlink \u00b6 Netlink \u662f\u4e00\u79cd Linux \u5185\u6838\u63d0\u4f9b\u7684\u901a\u4fe1\u673a\u5236\uff0c\u7528\u4e8e\u5185\u6838\u548c\u7528\u6237\u7a7a\u95f4\u8fdb\u7a0b\u4e4b\u95f4\u7684\u53cc\u5411\u901a\u4fe1\uff08IPC\uff09\u3002Netlink \u53ef\u4ee5\u7528\u4e8e\u8bb8\u591a\u76ee\u7684\uff0c\u4f8b\u5982\uff1a \u914d\u7f6e\u7f51\u7edc\u8bbe\u5907\u548c\u8def\u7531\u8868\uff1a\u4f7f\u7528 Netlink \u53ef\u4ee5\u901a\u8fc7\u7528\u6237\u7a7a\u95f4\u8fdb\u7a0b\u4fee\u6539\u5185\u6838\u7684\u7f51\u7edc\u8bbe\u5907\u548c\u8def\u7531\u8868\u914d\u7f6e\uff0c\u4f8b\u5982\u6dfb\u52a0\u3001\u5220\u9664\u3001\u4fee\u6539\u7f51\u7edc\u63a5\u53e3\u3001IP \u5730\u5740\u3001\u8def\u7531\u7b49\u3002 \u76d1\u89c6\u7f51\u7edc\u4e8b\u4ef6\uff1a\u4f7f\u7528 Netlink \u53ef\u4ee5\u5b9e\u65f6\u5730\u4ece\u5185\u6838\u83b7\u53d6\u7f51\u7edc\u4e8b\u4ef6\u7684\u901a\u77e5\uff0c\u4f8b\u5982\u7f51\u7edc\u63a5\u53e3\u7684\u72b6\u6001\u53d8\u5316\u3001\u8def\u7531\u7684\u53d8\u5316\u7b49\u3002 \u7a0b\u5e8f\u95f4\u901a\u4fe1\uff1a\u4f7f\u7528 Netlink \u53ef\u4ee5\u5728\u7528\u6237\u7a7a\u95f4\u8fdb\u7a0b\u4e4b\u95f4\u8fdb\u884c\u901a\u4fe1\uff0c\u7c7b\u4f3c\u4e8e Unix \u57df\u5957\u63a5\u5b57\u3002 Netlink \u673a\u5236\u57fa\u4e8e\u4e00\u79cd\u7279\u6b8a\u7684\u5957\u63a5\u5b57\u7c7b\u578b\uff08PF_NETLINK\uff09\u548c\u4e00\u4e2a\u7279\u5b9a\u7684\u534f\u8bae\uff08NETLINK\uff09\u3002\u7528\u6237\u7a7a\u95f4\u8fdb\u7a0b\u53ef\u4ee5\u901a\u8fc7\u521b\u5efa Netlink \u5957\u63a5\u5b57\u548c\u5185\u6838\u901a\u4fe1\u3002\u5185\u6838\u548c\u7528\u6237\u7a7a\u95f4\u8fdb\u7a0b\u4e4b\u95f4\u7684\u901a\u4fe1\u662f\u57fa\u4e8e Netlink \u6d88\u606f\u7684\uff0c\u6bcf\u4e2a Netlink \u6d88\u606f\u5305\u542b\u4e00\u4e2a\u6d88\u606f\u5934\u548c\u4e00\u4e2a\u8d1f\u8f7d\uff08payload\uff09\uff0c\u8d1f\u8f7d\u53ef\u4ee5\u662f\u4efb\u4f55\u7ed3\u6784\u4f53\u6216\u4e8c\u8fdb\u5236\u6570\u636e\u3002 Netlink \u6d88\u606f\u7684\u7c7b\u578b\u548c\u683c\u5f0f\u7531\u5185\u6838\u5b9a\u4e49\u3002\u7528\u6237\u7a7a\u95f4\u8fdb\u7a0b\u9700\u8981\u4e86\u89e3\u5185\u6838\u7684 Netlink \u6d88\u606f\u683c\u5f0f\u548c\u7c7b\u578b\uff0c\u624d\u80fd\u6b63\u786e\u5730\u6784\u9020\u548c\u89e3\u6790 Netlink \u6d88\u606f\u3002\u5e38\u7528\u7684 Netlink \u6d88\u606f\u7c7b\u578b\u5305\u62ec\uff1a RTM_NEWLINK \u548c RTM_DELLINK\uff1a\u6dfb\u52a0\u548c\u5220\u9664\u7f51\u7edc\u63a5\u53e3\u3002 RTM_NEWADDR \u548c RTM_DELADDR\uff1a\u6dfb\u52a0\u548c\u5220\u9664 IP \u5730\u5740\u3002 RTM_NEWROUTE \u548c RTM_DELROUTE\uff1a\u6dfb\u52a0\u548c\u5220\u9664\u8def\u7531\u3002 RTM_NEWNEIGH \u548c RTM_DELNEIGH\uff1a\u6dfb\u52a0\u548c\u5220\u9664 ARP \u8868\u9879\u3002 Netlink \u53ef\u4ee5\u4f7f\u7528 C \u8bed\u8a00\u7684 socket API \u8fdb\u884c\u7f16\u7a0b\u3002 Netfilter \u00b6 Netfilter\u662fLinux\u5185\u6838\u4e2d\u7684\u4e00\u4e2a\u5b50\u7cfb\u7edf\uff0c\u7528\u4e8e\u5728\u6570\u636e\u5305\u4f20\u8f93\u8fc7\u7a0b\u4e2d\u8fdb\u884c\u8fc7\u6ee4\u548c\u64cd\u4f5c\u3002\u5b83\u652f\u6301\u5bf9\u7f51\u7edc\u6570\u636e\u5305\u8fdb\u884c\u5404\u79cd\u7c7b\u578b\u7684\u5904\u7406\uff0c\u5305\u62ec\u8fc7\u6ee4\u3001\u4fee\u6539\u3001\u91cd\u5b9a\u5411\u7b49\u3002Netfilter\u901a\u8fc7\u5728\u5185\u6838\u4e2d\u6ce8\u518c\u94a9\u5b50\u51fd\u6570\uff0c\u5728\u6570\u636e\u5305\u901a\u8fc7\u7f51\u7edc\u6808\u7684\u4e0d\u540c\u9636\u6bb5\u65f6\u8fdb\u884c\u62e6\u622a\u548c\u5904\u7406\u3002 Netfilter\u7684\u6838\u5fc3\u662fiptables\u547d\u4ee4\uff0c\u5b83\u53ef\u4ee5\u7528\u6765\u914d\u7f6eNetfilter\u89c4\u5219\u3002iptables\u547d\u4ee4\u53ef\u4ee5\u7528\u6765\u914d\u7f6e\u9632\u706b\u5899\u89c4\u5219\uff0cNAT\u89c4\u5219\uff0c\u9650\u5236\u8fde\u63a5\u901f\u5ea6\u7b49\u3002iptables\u547d\u4ee4\u901a\u8fc7\u5339\u914d\u4e0d\u540c\u7684\u6570\u636e\u5305\u5b57\u6bb5\uff08\u4f8b\u5982\u6e90IP\u5730\u5740\u3001\u76ee\u7684IP\u5730\u5740\u3001\u6e90\u7aef\u53e3\u3001\u76ee\u7684\u7aef\u53e3\u7b49\uff09\u6765\u8fdb\u884c\u8fc7\u6ee4\u3002 \u9664\u4e86iptables\u547d\u4ee4\uff0c\u8fd8\u6709\u5176\u4ed6\u4e00\u4e9b\u5de5\u5177\u53ef\u4ee5\u7528\u4e8e\u914d\u7f6eNetfilter\u89c4\u5219\uff0c\u4f8b\u5982nftables\u547d\u4ee4\u548cfirewalld\u670d\u52a1\u3002\u8fd9\u4e9b\u5de5\u5177\u63d0\u4f9b\u4e86\u66f4\u7075\u6d3b\u3001\u66f4\u5f3a\u5927\u7684\u914d\u7f6e\u9009\u9879\uff0c\u53ef\u4ee5\u5e2e\u52a9\u7ba1\u7406\u5458\u66f4\u597d\u5730\u7ba1\u7406\u548c\u4fdd\u62a4\u7f51\u7edc\u5b89\u5168\u3002 \u4e5f\u53ef\u4ee5\u7528\u4e8e\u5c06\u7f51\u7edc\u6570\u636e\u5305\u5b9a\u5411\u5230\u5355\u4e2a\u5bb9\u5668\u3002 \u66f4\u591a\u4fe1\u606f\u53ef\u4ee5\u53c2\u8003 LXC/LXD \u3002 \u5b89\u88c5Docker \u00b6 \u53c2\u8003 \u6307\u5bfc \u5b89\u88c5Docker\u5f15\u64ce\u3002 \u53c2\u8003 \u6307\u5bfc \u5b89\u88c5Docker\u684c\u9762\u7248\u3002 \u4e0b\u9762\u4ee5openSUSE\u4e3a\u4f8b\u5b89\u88c5Docker\u5f15\u64ce\u3002 sudo zypper in docker \u5728\u5b89\u88c5\u8fc7\u7a0b\u4e2d\uff0c\u5728\u64cd\u4f5c\u7cfb\u7edf\u4e2d\u4f1a\u81ea\u52a8\u521b\u5efa\u7ec4 docker \u3002 \u5c06vagrant\u7528\u6237\u52a0\u5165docker\u7ec4\uff0c\u5219vagrant\u7528\u6237\u53ef\u4ee5\u5728\u4e0b\u6b21\u767b\u5f55\u540e\u4e0e\u672c\u673a\u7684Docker\u5b88\u62a4\u8fdb\u7a0b\uff08daemon\uff09\u8fdb\u884c\u901a\u4fe1\u3002Docker\u5b88\u62a4\u8fdb\u7a0b\u76d1\u542c\u672c\u5730\u5957\u63a5\u5b57\uff0c\u53ea\u80fd\u7531root\u7528\u6237\u548cdocker\u7ec4\u7684\u6210\u5458\u8bbf\u95ee\u3002 sudo usermod -aG docker $USER \u542f\u7528\u5e76\u542f\u52a8 Docker \u5f15\u64ce\u3002 sudo systemctl enable docker.service sudo systemctl start docker.service sudo systemctl status docker.service \u4e0b\u9762\u901a\u8fc7\u4e00\u4e2a\u5bb9\u5668 alpine \u7684\u4f8b\u5b50\u6765\u6f14\u793a\u5728\u76ee\u5f55 /opt/test \u4e0b\u6a21\u62df\u5b9e\u73b0choot\u3002 mkdir test cd test wget https://dl-cdn.alpinelinux.org/alpine/v3.13/releases/x86_64/alpine-minirootfs-3.13.4-x86_64.tar.gz tar zxvf alpine-minirootfs-3.13.4-x86_64.tar.gz -C alpine-minirootfs/ \u67e5\u770b\u5f53\u524d\u76ee\u5f55\u7ed3\u6784\uff1a tree ./test -L 1 \u8f93\u51fa\u7ed3\u679c\uff1a ./test \u251c\u2500\u2500 alpine-minirootfs-3.13.4-x86_64.tar.gz \u251c\u2500\u2500 bin \u251c\u2500\u2500 dev \u251c\u2500\u2500 etc \u251c\u2500\u2500 home \u251c\u2500\u2500 lib \u251c\u2500\u2500 media \u251c\u2500\u2500 mnt \u251c\u2500\u2500 opt \u251c\u2500\u2500 proc \u251c\u2500\u2500 root \u251c\u2500\u2500 run \u251c\u2500\u2500 sbin \u251c\u2500\u2500 srv \u251c\u2500\u2500 sys \u251c\u2500\u2500 tmp \u251c\u2500\u2500 usr \u2514\u2500\u2500 var \u901a\u8fc7\u547d\u4ee4 unshare \u6302\u8f7d\u76ee\u5f55 /opt/test/proc \u5230\u67d0\u4e2a\u6587\u4ef6\u6765\u5b9e\u73b0\u5ba2\u6237\u5b50\u7cfb\u7edf\u3002 sudo mount -t tmpfs tmpfs /opt/test/proc sudo unshare --pid --mount-proc = $PWD /test/proc --fork chroot ./test/ /bin/sh / # ps -ef PID USER TIME COMMAND 1 root 0 :00 /bin/sh 2 root 0 :00 ps -ef / # touch 123 / # ls 123 123 \u6587\u4ef6 123 \u5728\u5ba2\u6237\u5b50\u7cfb\u7edf\u4e2d\u5df2\u521b\u5efa\uff0c\u5bf9\u5e94\u4e3b\u7cfb\u7edf\u4e2d\u4e5f\u53ef\u4ee5\u5bf9\u5176\u8fdb\u884c\u8bfb\u5199\u64cd\u4f5c\u3002\u6bd4\u5982\uff0c\u4fee\u6539\u6587\u4ef6 123 \u7684\u5185\u5bb9\u3002 su - ls 123 echo hello > 123 \u6587\u4ef6 123 \u4fee\u6539\u540e\u7684\u5185\u5bb9\u5728\u5ba2\u6237\u673a\u91cc\u9762\u4e5f\u53ef\u89c1\u3002 / # cat 123 hello \u5728\u4e3b\u7cfb\u7edf\u4e2d\u518d\u521b\u5efa\u4e24\u4e2a\u5b50\u76ee\u5f55 /opt/test-1 \u548c /opt/test-2 \u3002 mkdir test-1 mkdir test-2 \u521b\u5efa2\u4e2a\u5ba2\u6237\u5b50\u7cfb\u7edf\uff0c\u5e76\u5c06\u4e0a\u9762\u7684\u4e24\u4e2a\u5b50\u76ee\u5f55\u6302\u5728\u5230\u5404\u81ea\u7684 /opt/test/home/ \u76ee\u5f55\u3002 sudo mount --bind /opt/test-1 /opt/test/home/ sudo unshare --pid --mount-proc = $PWD /test/proc --fork chroot ./test/ /bin/sh / # cd /home /home # echo \"test-1\" > 123.1 /home # cat 123.1 test-1 sudo mount --bind /opt/test-2 /opt/test/home/ sudo unshare --pid --mount-proc = $PWD /test/proc --fork chroot ./test/ /bin/sh / # cd /home /home # echo \"test-2\" > 123.2 /home # cat 123.2 test-2 ll test/home ll test-1/ ll test-2/ \u901a\u8fc7\u4e0a\u9762\u7684\u6f14\u793a\uff0c\u53ef\u4ee5\u5f97\u51fa\u7ed3\u8bba\uff0c\u4e24\u4e2a\u5ba2\u6237\u5b50\u7cfb\u7edf\u6302\u5728\u5230\u540c\u4e00\u4e2a\u4e3b\u7cfb\u7edf\u76ee\u5f55\u65f6\uff0c\u5b50\u7cfb\u7edf\u65f6\u5171\u4eab\u4e3b\u7cfb\u7edf\u76ee\u5f55\uff0c\u5e76\u76f8\u4e92\u5f71\u54cd\u3002 \u5bb9\u5668\u751f\u547d\u5468\u671f \u00b6 \u6982\u8ff0 \u00b6 \u9884\u5148\u4e0b\u8f7d\u4e0b\u5217\u955c\u50cf\u3002 docker image pull busybox docker image pull nginx docker image pull alpine docker image pull jenkins/jenkins:lts docker image pull golang:1.12-alpine docker image pull golang \u521b\u5efa\u5e76\u4ea4\u4e92\u5f0f\u8fd0\u884c\u4e00\u4e2a\u65b0\u7684busybox\u5bb9\u5668\uff0c\u5e76\u8fde\u63a5\u4e00\u4e2a\u4f2a\u7ec8\u7aef\uff08pseudo terminal\uff09\u3002 \u5728\u5bb9\u5668\u5185\uff0c\u4f7f\u7528 top \u547d\u4ee4\u67e5\u627e /bin/sh \u6b63\u5728\u4f5c\u4e3aPID\u4e3a1\u7684\u8fdb\u7a0b\u8fd0\u884c\uff0c\u4ee5\u53ca top \u8fdb\u7a0b\u4e5f\u5728\u8fd0\u884c\u3002 \u7136\u540e\uff0c\u9000\u51fa\u5bb9\u5668\u3002 docker image ls docker run -d -it --name busybox_v1 -v /opt/test:/docker busybox:latest /bin/sh docker container ps -a docker exec -it 185efe490507 /bin/sh / # top Mem: 3627396K used, 12731512K free, 10080K shrd, 2920K buff, 2999340K cached CPU: 0 .0% usr 0 .1% sys 0 .0% nic 99 .8% idle 0 .0% io 0 .0% irq 0 .0% sirq Load average: 0 .38 1 .09 1 .29 2 /277 14 PID PPID USER STAT VSZ %VSZ CPU %CPU COMMAND 1 0 root S 1332 0 .0 1 0 .0 /bin/sh 8 0 root S 1332 0 .0 2 0 .0 /bin/sh 14 8 root R 1328 0 .0 1 0 .0 top / # exitbuild \u542f\u52a8\u4e00\u4e2a\u65b0\u7684 Nginx \u5bb9\u5668\uff0c\u5e76\u4ee5\u72ec\u7acb\u6a21\u5f0f\uff08detached mode\uff09\u8fd0\u884c\u3002 \u4f7f\u7528 docker exec \u547d\u4ee4\u5728 Nginx \u5bb9\u5668\u4e2d\u542f\u52a8\u53e6\u4e00\u4e2a shell\uff08 /bin/sh \uff09\u3002 \u4f7f\u7528 ps \u547d\u4ee4\u67e5\u770b\u5bb9\u5668\u4e2d\u6b63\u5728\u8fd0\u884c\u7684 sh \u548c ps \u547d\u4ee4\uff08\u5728\u4e0a\u4e00\u6b65\u6267\u884c\u7684\uff09\u3002 docker run -d -it --name nginx_v1 -v /opt/test:/docker nginx:latest /bin/sh docker container ps -a docker exec -it edb640127a0d /bin/sh # ps /bin/sh: 2 : ps: not found # apt-get update && apt-get install -y procps # ps PID TTY TIME CMD 8 pts/1 00 :00:00 sh 351 pts/1 00 :00:00 ps # exit \u901a\u8fc7\u4e0b\u9762\u547d\u4ee4\u53ef\u4ee5\u770b\u52302\u4e2a\u73b0\u5728\u8fd0\u884c\u4e2d\u7684\u5bb9\u5668\u3002 docker container ps -a \u4f7f\u7528 docker logs \u547d\u4ee4\u663e\u793a\u6211\u4eec\u521a\u521a\u9000\u51fa\u7684\u5bb9\u5668\u7684\u65e5\u5fd7\u3002\u9009\u9879 --since 35m \u8868\u793a\u663e\u793a\u6700\u8fd1 35 \u5206\u949f\u5185\u7684\u65e5\u5fd7\u3002 docker logs nginx_v1 --details --since 35m docker logs busybox_v1 --details --since 35m \u4f7f\u7528 docker stop \u547d\u4ee4\u6765\u505c\u6b62 nginx \u5bb9\u5668\u3002 docker stop busybox_v1 docker stop nginx_v1 docker container ps -a \u4f7f\u7528\u4e0a\u8ff0\u547d\u4ee4 docker container ps -a \uff0c\u6211\u4eec\u53ef\u4ee5\u83b7\u53d6\u6240\u6709\u6b63\u5728\u8fd0\u884c\u548c\u5df2\u9000\u51fa\u7684\u5bb9\u5668\u5217\u8868\u3002\u4f7f\u7528 docker rm \u5c06\u5176\u5220\u9664\u3002\u4f7f\u7528 docker rm $(docker ps -aq) \u6765\u6e05\u7406\u4e3b\u673a\u4e0a\u7684\u6240\u6709\u5bb9\u5668\u3002\u8bf7\u8c28\u614e\u4f7f\u7528\uff01 docker rm busybox_v1 docker container ps -a \u7aef\u53e3\u548c\u5377 \u00b6 \u73b0\u5728\u542f\u52a8\u4e00\u4e2a\u65b0\u7684 nginx \u5bb9\u5668\uff0c\u5e76\u5c06 nginx web \u670d\u52a1\u5668\u7684\u7aef\u53e3\u5bfc\u51fa\u5230 Docker \u968f\u673a\u9009\u62e9\u7684\u7aef\u53e3\u3002 \u6211\u4eec\u53ef\u4ee5\u4f7f\u7528\u547d\u4ee4 docker ps \u627e\u51fa web \u670d\u52a1\u5668\u8f6c\u53d1\u5230\u4e86\u54ea\u4e2a\u7aef\u53e3\u3002\u5728\u4e3b\u673a\u4e0a\u4f7f\u7528\u8f6c\u53d1\u7684\u7aef\u53e3\u53f7\u8bbf\u95ee docker http://localhost: \u3002 docker container ps -a docker run -d -P --name nginx_v2 nginx:latest docker container ps -a Start another nginx container and expose port to 1080 on host as an example via http://localhost:1080 . \u542f\u52a8\u53e6\u4e00\u4e2anginx\u5bb9\u5668\uff0c\u5c06\u5176\u7aef\u53e3\u6620\u5c04\u5230\u4e3b\u673a\u76841080\u7aef\u53e3\uff0c\u53ef\u4ee5\u901a\u8fc7 http://localhost:1080 \u8bbf\u95ee\u3002 docker run -d -p 1080 :80 --name nginx_v3 nginx:latest docker container ps -a \u4f7f\u7528 docker inspect \u547d\u4ee4\u67e5\u627e\u955c\u50cf\u66b4\u9732\u7684\u7aef\u53e3\u53f7\uff0c\u8f93\u51faJSON\u683c\u5f0f\u6587\u4ef6\uff0c\u7f51\u7edc\u4fe1\u606f\uff08IP\u3001\u7f51\u5173\u3001\u7aef\u53e3\u7b49\uff09\u662f\u8f93\u51faJSON\u683c\u5f0f\u7684\u4e00\u90e8\u5206\u3002 docker inspect nginx_v3 \u5728\u76ee\u5f55 /opt/test \u4e2d\u521b\u5efa\u4e00\u4e2a\u540d\u4e3a index.html \u7684\u6587\u4ef6\uff0c\u5176\u5185\u5bb9\u5982\u4e0b\uff1a < html > < head > < title > Sample Website from my container < body > < h1 > This is a custom website. < p > This website is served from my < a href = \"http://www.docker.com\" target = \"_blank\" > Docker container. \u542f\u52a8\u4e00\u4e2a\u65b0\u5bb9\u5668\uff0c\u5c06\u4e3b\u673a\u76ee\u5f55 /opt/test \u4e0e\u5bb9\u5668\u76ee\u5f55 /usr/share/nginx/html \u7ed1\u5b9a\u6302\u8f7d\u4e3a\u4e00\u4e2a\u5377\uff0c\u4ee5\u4fbfNginx\u53ef\u4ee5\u901a\u8fc7 http://localhost:49159/ \u53d1\u5e03\u6211\u4eec\u521a\u521b\u5efa\u7684html\u6587\u4ef6\uff0c\u800c\u4e0d\u662fNginx\u9ed8\u8ba4\u7684\u9875\u9762\u3002 docker run -d -P --mount type = bind,source = /opt/test/,target = /usr/share/nginx/html --name nginx_v3-1 nginx:latest docker container ps -a \u68c0\u67e5Nginx\u914d\u7f6e\u6587\u4ef6\uff0c\u67e5\u770b\u5bb9\u5668\u4e2dhtml\u4e3b\u9875\u5b58\u50a8\u7684\u4f4d\u7f6e\u3002 docker exec -it nginx_v3-1 /bin/sh # cd /etc/nginx/conf.d # ls default.conf # cat default.conf server { listen 80 ; listen [ :: ] :80 ; server_name localhost ; #access_log /var/log/nginx/host.access.log main; location / { root /usr/share/nginx/html ; <-- index index.html index.htm ; } #error_page 404 /404.html; # redirect server error pages to the static page /50x.html # error_page 500 502 503 504 /50x.html ; location = /50x.html { root /usr/share/nginx/html ; } # proxy the PHP scripts to Apache listening on 127.0.0.1:80 # #location ~ \\.php$ { # proxy_pass http://127.0.0.1; #} # pass the PHP scripts to FastCGI server listening on 127.0.0.1:9000 # #location ~ \\.php$ { # root html; # fastcgi_pass 127.0.0.1:9000; # fastcgi_index index.php; # fastcgi_param SCRIPT_FILENAME /scripts$fastcgi_script_name; # include fastcgi_params; #} # deny access to .htaccess files, if Apache's document root # concurs with nginx's one # #location ~ /\\.ht { # deny all; #} } # cd /usr/share/nginx/html # cat index.html Sample Website from my container

This is a custom website.

This website is served from my Docker container.

# \u63a8\u8350\u4f7f\u7528\u5377 API \u6765\u5b9e\u73b0\u6570\u636e\u6301\u4e45\u5316\uff0c\u800c\u4e0d\u662f\u5c06\u6570\u636e\u5b58\u50a8\u5728 Docker \u5bb9\u5668\u4e2d\u3002Docker \u652f\u6301\u4e24\u79cd\u6302\u8f7d\u65b9\u5f0f\uff1a \u7ed1\u5b9a\u6302\u8f7d\uff08Bind mounts\uff09\uff1a \u5c06\u672c\u5730\u4e3b\u673a\u76ee\u5f55\u6302\u8f7d\u5230\u5bb9\u5668\u4e2d\u7684\u67d0\u4e2a\u8def\u5f84\u3002 \u6302\u8f7d\u540e\uff0c\u76ee\u6807\u76ee\u5f55\u4e2d\u539f\u6709\u7684\u6240\u6709\u5185\u5bb9\u5c06\u88ab\u9690\u85cf\u3002 \u4f8b\u5982\uff0c\u5982\u679c\u6211\u4eec\u60f3\u8981\u6ce8\u5165\u67d0\u4e9b\u914d\u7f6e\u6587\u4ef6\uff0c\u6211\u4eec\u9700\u8981\u81ea\u5df1\u5199\u5bf9\u5e94\u7684\u914d\u7f6e\u6587\u4ef6\uff0c\u5c06\u5176\u5b58\u50a8\u5728 Docker \u4e3b\u673a\u4e0a\u7684 /home/container/config \u8def\u5f84\u4e0b\uff0c\u5e76\u5c06\u6b64\u76ee\u5f55\u7684\u5185\u5bb9\u6302\u8f7d\u5230 /usr/application/config \uff08\u5047\u8bbe\u5e94\u7528\u7a0b\u5e8f\u4ece\u6b64\u5904\u8bfb\u53d6\u914d\u7f6e\uff09\u3002 \u547d\u4ee4\uff1a docker run --mount type=bind,source=,target= \u2026 \u547d\u540d\u5377\uff08Named volumes\uff09\uff1a Docker \u53ef\u4ee5\u521b\u5efa\u4e00\u4e2a\u72ec\u7acb\u7684\u5b58\u50a8\u5377\uff0c\u5176\u751f\u547d\u5468\u671f\u72ec\u7acb\u4e8e\u5bb9\u5668\u4f46\u4ecd\u7531 Docker \u7ba1\u7406\u3002 \u5728\u521b\u5efa\u65f6\uff0c\u6302\u8f7d\u76ee\u6807\u7684\u5185\u5bb9\u5c06\u5408\u5e76\u5230\u5377\u4e2d\u3002 \u547d\u4ee4\uff1a docker run --mount source=,target= \u2026 \u5982\u4f55\u533a\u5206\u7ed1\u5b9a\u6302\u8f7d\u548c\u547d\u540d\u5377\uff1f \u5f53\u6307\u5b9a\u7edd\u5bf9\u8def\u5f84\u65f6\uff0cDocker \u4f1a\u8ba4\u4e3a\u8fd9\u662f\u4e00\u4e2a\u7ed1\u5b9a\u6302\u8f7d\u3002 \u5f53\u6211\u4eec\u4ec5\u63d0\u4f9b\u540d\u79f0\uff08\u5982\u76f8\u5bf9\u8def\u5f84 config \uff09\u65f6\uff0c\u5b83\u4f1a\u8ba4\u4e3a\u8fd9\u662f\u4e00\u4e2a\u547d\u540d\u5377\uff0c\u5e76\u521b\u5efa\u4e00\u4e2a\u540d\u4e3a config \u7684\u5377\u3002 \u6ce8\uff1a\u6301\u4e45\u5b58\u50a8\u7531\u4e3b\u673a\u63d0\u4f9b\uff0c\u53ef\u4ee5\u76f4\u63a5\u662f\u4e3b\u673a\u6587\u4ef6\u7cfb\u7edf\u7684\u4e00\u90e8\u5206\uff0c\u4e5f\u53ef\u4ee5\u662f NFS \u6302\u8f7d\u3002 Dockerfile \u00b6 \u8ba9\u6211\u4eec\u7528 Dockerfile \u6784\u5efa\u4e00\u4e2a\u955c\u50cf\uff0c\u5bf9\u5176\u8fdb\u884c\u6253\u6807\u7b7e\u5e76\u4e0a\u4f20\u5230\u955c\u50cf\u4ed3\u5e93\u3002 \u83b7\u53d6 Docker \u955c\u50cf\u7684\u6784\u5efa\u5386\u53f2\u8bb0\u5f55\u3002 docker image history nginx:latest \u521b\u5efa\u4e00\u4e2a\u7a7a\u7684\u76ee\u5f55 /opt/tmp-1 \uff0c\u8fdb\u5165\u8be5\u76ee\u5f55\u5e76\u5728\u5176\u4e2d\u521b\u5efa index.html \u6587\u4ef6\u3002 /opt/tmp-1> cat index.html Sample Website from my container

This is a custom website.

This website is served from my Docker container.

\u4f7f\u7528 FROM \u6765\u6269\u5c55\u4e00\u4e2a\u5df2\u6709\u7684\u955c\u50cf\uff0c\u5e76\u6307\u5b9a\u7248\u672c\u53f7\u3002 \u4f7f\u7528 COPY \u5c06\u4e00\u4e2a\u65b0\u7684\u9ed8\u8ba4\u7f51\u7ad9\u590d\u5236\u5230\u955c\u50cf\u4e2d\uff0c\u4f8b\u5982 /usr/share/nginx/html \u3002 \u4e3aNginx\u521b\u5efaSSL\u914d\u7f6e /opt/tmp-1/ssl.conf \u3002 server { listen 443 ssl; server_name localhost; ssl_certificate /etc/nginx/ssl/nginx.crt; ssl_certificate_key /etc/nginx/ssl/nginx.key; location / { root /usr/share/nginx/html; index index.html index.htm; } } \u4f7f\u7528OpenSSL\u521b\u5efa\u4e00\u4e2a\u81ea\u7b7e\u540d\u8bc1\u4e66\uff0c\u4ee5\u4fbfSSL/TLS\u5de5\u4f5c\u3002 \u4f7f\u7528\u4ee5\u4e0b\u547d\u4ee4\u521b\u5efa\u4e00\u4e2a\u52a0\u5bc6\u5bc6\u94a5\u548c\u8bc1\u4e66\u3002 openssl req -x509 -nodes -newkey rsa:4096 -keyout nginx.key -out nginx.crt -days 365 -subj \"/CN= $( hostname ) \" \u4e3a\u4e86\u542f\u7528\u52a0\u5bc6\u7684HTTPS\uff0c\u6211\u4eec\u9700\u8981\u4f7f\u7528 EXPOSE \u6307\u4ee4\u516c\u5f00 443 \u7aef\u53e3\u3002\u9ed8\u8ba4\u7684nginx\u955c\u50cf\u4ec5\u516c\u5f00\u7aef\u53e3 80 \uff0c\u7528\u4e8e\u975e\u52a0\u5bc6\u7684HTTP\u3002 \u5728 /opt/tmp-1 \u6587\u4ef6\u5939\u4e2d\u521b\u5efa\u4ee5\u4e0bDockerfile\u3002 cat Dockerfile \u8f93\u51fa\uff1a FROM nginx:latest # copy the custom website into the image COPY index.html /usr/share/nginx/html # copy the SSL configuration file into the image COPY ssl.conf /etc/nginx/conf.d/ssl.conf # download the SSL key and certificate into the image COPY nginx.key /etc/nginx/ssl/ COPY nginx.crt /etc/nginx/ssl/ # expose the HTTPS port EXPOSE 443 \u81f3\u6b64\uff0c\u6211\u4eec\u5728\u76ee\u5f55 /opt/tmp-1 \u4e0b\u67095\u4e2a\u6587\u4ef6\u3002 ls /opt/tmp-1 \u8f93\u51fa\uff1a Dockerfile index.html nginx.crt nginx.key ssl.conf \u4f7f\u7528 docker build \u547d\u4ee4\u6765\u6784\u5efa\u955c\u50cf\uff0c\u5e76\u5c06\u5bb9\u5668\u768480\u548c443\u7aef\u53e3\u8f6c\u53d1\u3002 docker build -t nginx:my1 /opt/tmp-1/ docker image ls docker run -d -p 1086 :80 -p 1088 :443 --name nginx_v5 nginx:my1 docker container ps -a \u901a\u8fc7\u4e0b\u9762\u4e24\u4e2a\u94fe\u63a5\u6765\u9a8c\u8bc1\u4e0a\u9762\u7684\u53d8\u5316\u662f\u5426\u751f\u6548\u3002 http://localhost:1086/ https://localhost:1088/ \u5728 DockerHub \u6ce8\u518c\u4e00\u4e2a\u4e2a\u4eba\u8d26\u53f7\uff0c\u542f\u7528 Docker Hub \u4e2d\u7684\u8bbf\u95ee\u4ee4\u724c\u4ee5\u8fdb\u884c CLI \u5ba2\u6237\u7aef\u8eab\u4efd\u9a8c\u8bc1\u3002 docker login \u8f93\u5165\u7528\u6237\u540d\u548c\u5bc6\u7801\u3002 Username: Password: \u7ed9\u8fd9\u4e2a\u955c\u50cf\u52a0\u4e0a\u4e00\u4e2a\u6807\u7b7e\uff0c\u4f8b\u5982\uff1asecure_nginx_0001\uff0c\u7248\u672c\u53f7\u4e3a v1\u3002 docker tag nginx:my1 secure_nginx_0001:v1 docker push secure_nginx_0001:v1 docker image ls \u591a\u9636\u6bb5Dockerfile \u00b6 \u4e0b\u9762\u7684\u4f8b\u5b50\u662f\u6f14\u793a\u4e00\u4e2a\u591a\u9636\u6bb5\uff08Multi-stage\uff09\u6784\u5efa\u7684\u4f8b\u5b50\u3002\u5728Docker\u7684\u4e0a\u4e0b\u6587\u4e2d\uff0c\u591a\u9636\u6bb5\uff08Multi-stage\uff09\u610f\u5473\u7740\u6211\u4eec\u53ef\u4ee5\u6709\u591a\u4e2a\u5e26\u6709 FROM \u5173\u952e\u5b57\u7684\u884c\u3002 \u521b\u5efa\u6587\u4ef6\u5939 /opt/tmp-2 \u548c /opt/tmp-2/tmpl \u3002\u521b\u5efa\u6587\u4ef6 edit.html \uff0c view.html \uff0c wiki.go \u3002 \u6587\u4ef6\u7ed3\u6784\u5982\u4e0b\uff1a tree -l /opt/tmp-2 \u8f93\u51fa\u7ed3\u679c\uff1a . \u251c\u2500\u2500 tmpl \u2502 \u251c\u2500\u2500 edit.html \u2502 \u2514\u2500\u2500 view.html \u2514\u2500\u2500 wiki.go \u521b\u5efa\u4e00\u4e2a\u65b0\u7684Dockerfile\u3002 cat Dockerfile \u6587\u4ef6\u5185\u5bb9\uff1a # app builder stage FROM golang:1.12-alpine as builder # # copy the go source code over and build the binary WORKDIR /go/src COPY wiki.go /go/src/wiki.go RUN go build wiki.go # app exec stage # separate & new image starts here!# FROM alpine:3.9 # prepare file system etc RUN mkdir -p /app/data /app/tmpl && adduser -S -D -H -h /app appuser COPY tmpl/* /app/tmpl/ # get the compiled binary from the previous stage COPY --from=builder /go/src/wiki /app/wiki # prepare runtime env RUN chown -R appuser /app USER appuser WORKDIR /app # expose app port & set default command EXPOSE 8080 CMD [\"/app/wiki\"] \u7528\u4e0a\u4e00\u6b65\u521b\u5efa\u7684Dockerfile\u6765\u521b\u5efa\u65b0\u666f\u8c61\u3002 docker build -t lizard/golang:my1 /opt/tmp-2/ \u4ee5\u72ec\u7acb\u6a21\u5f0f\uff08detached\uff09\u8fd0\u884c\u8fd9\u4e2a\u955c\u50cf\uff0c\u5e76\u5c06\u5bb9\u5668\u7aef\u53e3 8080 \u8f6c\u53d1\u5230\u4e3b\u673a\u7aef\u53e3 1090 \u3002 docker run -d -p 1090 :8080 --name golan_v1 lizard/golang:my1 \u901a\u8fc7\u94fe\u63a5 http://localhost:1090 \u8bbf\u95ee\u8fd9\u4e2a\u8fd0\u884c\u7684\u5bb9\u5668\u3002 \u5bf9\u6211\u4eec\u521a\u521a\u521b\u5efa\u7684\u65b0\u7684golang\u955c\u50cf\u8fdb\u884c\u6807\u7b7e\uff0c\u5e76\u4e14\u4e0a\u4f20\u5230Dockerhub\u3002 docker tag lizard/golang:my1 /golang_0001:v1 docker push /golang_0001:v1","title":"Docker\u57fa\u7840"},{"location":"k8s/cka_cn/foundamentals/docker/#cka4docker","text":"","title":"CKA\u81ea\u5b66\u7b14\u8bb04:Docker\u57fa\u7840"},{"location":"k8s/cka_cn/foundamentals/docker/#_1","text":"\u4e86\u89e3Linux\u539f\u8bed\u7684\u6982\u5ff5\u548c\u5305\u542b\u7684\u7279\u6027\u3002 \u5b89\u88c5Docker\uff0c\u4e86\u89e3\u57fa\u672c\u7684Docker\u547d\u4ee4\u548cDockerfile\u7684\u4f7f\u7528\u3002","title":"\u6458\u8981"},{"location":"k8s/cka_cn/foundamentals/docker/#_2","text":"\u64cd\u4f5c\u7cfb\u7edf\uff1aopenSUSE 15.3 cat /etc/os-release \u8f93\u51fa\u7ed3\u679c\uff1a NAME=\"openSUSE Leap\" VERSION=\"15.3\" ID=\"opensuse-leap\" ID_LIKE=\"suse opensuse\" VERSION_ID=\"15.3\" PRETTY_NAME=\"openSUSE Leap 15.3\" ANSI_COLOR=\"0;32\" CPE_NAME=\"cpe:/o:opensuse:leap:15.3\" BUG_REPORT_URL=\"https://bugs.opensuse.org\" HOME_URL=\"https://www.opensuse.org/\"","title":"\u7ec3\u4e60\u73af\u5883"},{"location":"k8s/cka_cn/foundamentals/docker/#linux","text":"\u5728\u64cd\u4f5c\u7cfb\u7edf\u4e2d\uff0c\u539f\u8bed\uff08primitives\uff09\u662f\u7528\u4e8e\u521b\u5efa\u66f4\u590d\u6742\u529f\u80fd\u7684\u57fa\u672c\u6784\u5efa\u5757\u6216\u64cd\u4f5c\u3002\u5728Linux\u4e2d\uff0c\u6709\u51e0\u79cd\u5e38\u7528\u7684\u539f\u8bed\u3002\u5305\u62ec\uff1a \u8fdb\u7a0b\uff08Processes\uff09\uff1a\u8fdb\u7a0b\u662f\u7a0b\u5e8f\u6216\u5e94\u7528\u7a0b\u5e8f\u7684\u8fd0\u884c\u5b9e\u4f8b\u3002\u5b83\u4eec\u662fLinux\u4e2d\u7684\u57fa\u672c\u5de5\u4f5c\u5355\u5143\uff0c\u7531\u5185\u6838\u7ba1\u7406\u3002 \u6587\u4ef6\uff08Files\uff09\uff1a\u6587\u4ef6\u662f\u5728Linux\u4e2d\u5b58\u50a8\u6570\u636e\u7684\u4e3b\u8981\u65b9\u5f0f\u3002\u5b83\u4eec\u53ef\u4ee5\u662f\u6587\u672c\u6587\u4ef6\u3001\u4e8c\u8fdb\u5236\u6587\u4ef6\u3001\u76ee\u5f55\u6216\u7279\u6b8a\u6587\u4ef6\uff0c\u5982\u8bbe\u5907\u6587\u4ef6\u3002 \u4fe1\u53f7\uff08Signals\uff09\uff1a\u4fe1\u53f7\u662f\u8fdb\u7a0b\u4e4b\u95f4\u6216\u8fdb\u7a0b\u4e0e\u5185\u6838\u4e4b\u95f4\u901a\u4fe1\u7684\u4e00\u79cd\u65b9\u5f0f\u3002\u5b83\u4eec\u7528\u4e8e\u901a\u77e5\u8fdb\u7a0b\u4e8b\u4ef6\uff0c\u4f8b\u5982\u4efb\u52a1\u5b8c\u6210\u6216\u9519\u8bef\u53d1\u751f\u7684\u60c5\u51b5\u3002 \u5957\u63a5\u5b57\uff08Sockets\uff09\uff1a\u5957\u63a5\u5b57\u662fLinux\u4e2d\u8fdb\u7a0b\u95f4\u901a\u4fe1\u7684\u4e00\u79cd\u65b9\u5f0f\u3002\u5b83\u4eec\u5141\u8bb8\u8fdb\u7a0b\u5728\u7f51\u7edc\u6216\u672c\u5730\u673a\u5668\u4e0a\u53d1\u9001\u548c\u63a5\u6536\u6570\u636e\u3002 \u7ebf\u7a0b\uff08Threads\uff09\uff1a\u7ebf\u7a0b\u662f\u8f7b\u91cf\u7ea7\u7684\u8fdb\u7a0b\uff0c\u4e0e\u5176\u7236\u8fdb\u7a0b\u5171\u4eab\u76f8\u540c\u7684\u5185\u5b58\u7a7a\u95f4\u548c\u8d44\u6e90\u3002\u5b83\u4eec\u901a\u5e38\u7528\u4e8e\u901a\u8fc7\u5141\u8bb8\u540c\u65f6\u6267\u884c\u591a\u4e2a\u4efb\u52a1\u6765\u63d0\u9ad8\u5e94\u7528\u7a0b\u5e8f\u7684\u6027\u80fd\u3002 \u7ba1\u9053\uff08Pipes\uff09\uff1a\u7ba1\u9053\u662f\u4e00\u79cd\u5c06\u4e00\u4e2a\u8fdb\u7a0b\u7684\u8f93\u51fa\u8fde\u63a5\u5230\u53e6\u4e00\u4e2a\u8fdb\u7a0b\u7684\u8f93\u5165\u7684\u65b9\u5f0f\u3002\u5b83\u4eec\u5141\u8bb8\u8fdb\u7a0b\u4ee5\u53d7\u63a7\u7684\u65b9\u5f0f\u8fdb\u884c\u901a\u4fe1\u548c\u4ea4\u6362\u6570\u636e\u3002 \u4fe1\u53f7\u91cf\uff08Semaphores\uff09\uff1a\u4fe1\u53f7\u91cf\u662fLinux\u4e2d\u63a7\u5236\u5bf9\u5171\u4eab\u8d44\u6e90\u8bbf\u95ee\u7684\u4e00\u79cd\u65b9\u5f0f\u3002\u5b83\u4eec\u5141\u8bb8\u8fdb\u7a0b\u534f\u8c03\u5b83\u4eec\u5bf9\u5171\u4eab\u8d44\u6e90\u7684\u8bbf\u95ee\uff0c\u5982\u6587\u4ef6\u6216\u5185\u5b58\u3002","title":"Linux\u539f\u8bed"},{"location":"k8s/cka_cn/foundamentals/docker/#chroot","text":"chroot\u4f7f\u7528pivot_root\uff0c\u4ee5\u5b9e\u73b0\u5c06*\u8fdb\u7a0b*\u7684\u6839\u76ee\u5f55\u66f4\u6539\u4e3a\u4efb\u4f55\u7ed9\u5b9a\u7684\u76ee\u5f55\u3002 a. \u6a21\u62df\u5bb9\u5668 \u4f7f\u7528 chroot \u547d\u4ee4\u53ef\u4ee5\u5728Linux\u7cfb\u7edf\u4e2d\u521b\u5efa\u4e00\u4e2a\u5bb9\u5668\u3002\u8be5\u5bb9\u5668\u53ef\u4ee5\u770b\u4f5c\u662f\u4e00\u4e2a\u865a\u62df\u7684\u6839\u6587\u4ef6\u7cfb\u7edf\uff0c\u5176\u4e2d\u8fd0\u884c\u7684\u8fdb\u7a0b\u53ea\u80fd\u8bbf\u95ee\u8be5\u6839\u6587\u4ef6\u7cfb\u7edf\u4e2d\u7684\u8d44\u6e90\u3002 \u4f8b\u5982\uff0c\u4ee5\u4e0b\u547d\u4ee4\u4f1a\u5c06\u5f53\u524d\u6839\u6587\u4ef6\u7cfb\u7edf\u66f4\u6539\u4e3a /tmp/myroot \u76ee\u5f55\uff1a chroot /tmp/myroot /bin/bash \u8fd9\u6761\u547d\u4ee4\u4f1a\u542f\u52a8\u4e00\u4e2a\u65b0\u7684Bash shell\uff0c\u8be5shell\u7684\u6839\u76ee\u5f55\u4e3a /tmp/myroot \u3002 b. \u66f4\u6539\u6839\u6587\u4ef6\u7cfb\u7edf chroot \u547d\u4ee4\u8fd8\u53ef\u7528\u4e8e\u66f4\u6539\u8fdb\u7a0b\u7684\u6839\u6587\u4ef6\u7cfb\u7edf\u3002\u4f8b\u5982\uff0c\u6211\u4eec\u53ef\u4ee5\u4f7f\u7528 chroot \u547d\u4ee4\u542f\u52a8\u4e00\u4e2a\u5177\u6709\u53e6\u4e00\u4e2a\u6839\u6587\u4ef6\u7cfb\u7edf\u7684\u8fdb\u7a0b\uff0c\u800c\u4e0d\u662f\u7cfb\u7edf\u7684\u9ed8\u8ba4\u6839\u6587\u4ef6\u7cfb\u7edf\u3002 \u4f8b\u5982\uff0c\u4ee5\u4e0b\u547d\u4ee4\u4f1a\u5c06\u5f53\u524d\u76ee\u5f55\uff08\u5373 ./ \uff09\u4f5c\u4e3a\u6839\u76ee\u5f55\uff0c\u5e76\u5728\u5176\u4e2d\u542f\u52a8\u4e00\u4e2a\u65b0\u7684Bash shell\uff1a sudo chroot . /bin/bash","title":"chroot"},{"location":"k8s/cka_cn/foundamentals/docker/#_3","text":"\u5728Linux\u64cd\u4f5c\u7cfb\u7edf\u4e2d\uff0cNamespace\uff08\u547d\u540d\u7a7a\u95f4\uff09\u662f\u4e00\u79cd\u673a\u5236\uff0c\u7528\u4e8e\u9694\u79bb\u4e0d\u540c\u8fdb\u7a0b\u7684\u8d44\u6e90\u3002\u901a\u8fc7Namespace\u673a\u5236\uff0c\u53ef\u4ee5\u5c06\u4e00\u7ec4\u8fdb\u7a0b\u53ca\u5176\u5b50\u8fdb\u7a0b\u7684\u89c6\u56fe\u9694\u79bb\u5728\u4e00\u4e2a\u72ec\u7acb\u7684Namespace\u4e2d\uff0c\u4ece\u800c\u5b9e\u73b0\u8fdb\u7a0b\u4e4b\u95f4\u8d44\u6e90\u9694\u79bb\u7684\u76ee\u7684\u3002 \u4e0b\u9762\u662f\u4e00\u4e9b\u5e38\u89c1\u7684Namespace\u7c7b\u578b\u53ca\u5176\u4f5c\u7528\uff1a Mount Namespace\uff1a\u9694\u79bb\u6587\u4ef6\u7cfb\u7edf\u6302\u8f7d\u70b9\u3002\u53ef\u4ee5\u4f7f\u4e0d\u540c\u8fdb\u7a0b\u62e5\u6709\u81ea\u5df1\u7684\u72ec\u7acb\u7684\u6587\u4ef6\u7cfb\u7edf\u89c6\u56fe\u3002 PID Namespace\uff1a\u9694\u79bb\u8fdb\u7a0bID\u53f7\u3002\u53ef\u4ee5\u4f7f\u4e0d\u540c\u8fdb\u7a0b\u62e5\u6709\u81ea\u5df1\u7684\u8fdb\u7a0bID\u53f7\u7a7a\u95f4\uff0c\u907f\u514d\u8fdb\u7a0b\u4e4b\u95f4\u7684PID\u51b2\u7a81\u3002 Network Namespace\uff1a\u9694\u79bb\u7f51\u7edc\u6808\u3002\u53ef\u4ee5\u4f7f\u4e0d\u540c\u8fdb\u7a0b\u62e5\u6709\u81ea\u5df1\u7684\u72ec\u7acb\u7684\u7f51\u7edc\u6808\uff0c\u4ece\u800c\u907f\u514d\u8fdb\u7a0b\u4e4b\u95f4\u7684\u7f51\u7edc\u51b2\u7a81\u3002 IPC Namespace\uff1a\u9694\u79bb\u8fdb\u7a0b\u95f4\u901a\u4fe1\uff08IPC\uff09\u673a\u5236\u3002\u53ef\u4ee5\u4f7f\u4e0d\u540c\u8fdb\u7a0b\u62e5\u6709\u81ea\u5df1\u7684\u72ec\u7acb\u7684IPC\u7a7a\u95f4\uff0c\u4ece\u800c\u907f\u514dIPC\u673a\u5236\u5e26\u6765\u7684\u8d44\u6e90\u7ade\u4e89\u3002 UTS Namespace\uff1a\u9694\u79bb\u4e3b\u673a\u540d\u548c\u57df\u540d\u3002\u53ef\u4ee5\u4f7f\u4e0d\u540c\u8fdb\u7a0b\u62e5\u6709\u81ea\u5df1\u7684\u72ec\u7acb\u7684\u4e3b\u673a\u540d\u548c\u57df\u540d\u7a7a\u95f4\uff0c\u4ece\u800c\u907f\u514d\u8fdb\u7a0b\u4e4b\u95f4\u7684\u547d\u540d\u51b2\u7a81\u3002 Primitives namespace\u548cNamespace\u662f\u4e24\u4e2a\u4e0d\u540c\u7684\u6982\u5ff5\u3002 Namespace\u662fLinux\u64cd\u4f5c\u7cfb\u7edf\u63d0\u4f9b\u7684\u4e00\u79cd\u673a\u5236\uff0c\u7528\u4e8e\u9694\u79bb\u4e0d\u540c\u8fdb\u7a0b\u7684\u8d44\u6e90\uff0c\u4ee5\u5b9e\u73b0\u8fdb\u7a0b\u4e4b\u95f4\u7684\u8d44\u6e90\u9694\u79bb\u548c\u73af\u5883\u9694\u79bb\u3002\u4f8b\u5982\uff0cPID Namespace\u53ef\u4ee5\u4f7f\u4e0d\u540c\u8fdb\u7a0b\u62e5\u6709\u81ea\u5df1\u7684\u72ec\u7acb\u7684PID\u53f7\u7a7a\u95f4\uff0c\u907f\u514d\u8fdb\u7a0b\u4e4b\u95f4\u7684PID\u51b2\u7a81\uff1bNetwork Namespace\u53ef\u4ee5\u4f7f\u4e0d\u540c\u8fdb\u7a0b\u62e5\u6709\u81ea\u5df1\u7684\u72ec\u7acb\u7684\u7f51\u7edc\u6808\uff0c\u4ece\u800c\u907f\u514d\u8fdb\u7a0b\u4e4b\u95f4\u7684\u7f51\u7edc\u51b2\u7a81\u7b49\u3002 Primitives namespace\u662f\u4e00\u79cd\u65b0\u7684\u6280\u672f\u6982\u5ff5\uff0c\u5b83\u662f\u6307\u5c06\u4e0d\u540c\u7684\u57fa\u672c\u64cd\u4f5c\uff08\u4f8b\u5982\u8bfb\u5199\u6587\u4ef6\u3001\u521b\u5efa\u8fdb\u7a0b\u3001\u7f51\u7edc\u901a\u4fe1\u7b49\uff09\u4f5c\u4e3a\u539f\u8bed\u8fdb\u884c\u9694\u79bb\u548c\u5c01\u88c5\uff0c\u4f7f\u5f97\u5e94\u7528\u7a0b\u5e8f\u53ef\u4ee5\u5728\u8fd9\u4e9b\u9694\u79bb\u7684\u539f\u8bed\u4e0a\u6784\u5efa\u51fa\u81ea\u5df1\u7684\u9694\u79bb\u73af\u5883\u3002\u4f8b\u5982\uff0c\u53ef\u4ee5\u901a\u8fc7\u9694\u79bb\u6587\u4ef6\u7cfb\u7edf\u8bfb\u5199\u64cd\u4f5c\u6765\u5b9e\u73b0\u5bb9\u5668\u7ea7\u522b\u7684\u6587\u4ef6\u7cfb\u7edf\u9694\u79bb\uff1b\u901a\u8fc7\u9694\u79bb\u7f51\u7edc\u901a\u4fe1\u64cd\u4f5c\u6765\u5b9e\u73b0\u5bb9\u5668\u7ea7\u522b\u7684\u7f51\u7edc\u9694\u79bb\u7b49\u3002 \u56e0\u6b64\uff0cNamespace\u548cPrimitives namespace\u662f\u4e24\u4e2a\u4e0d\u540c\u7684\u6982\u5ff5\uff0c\u867d\u7136\u5b83\u4eec\u90fd\u53ef\u4ee5\u7528\u4e8e\u5b9e\u73b0\u9694\u79bb\u548c\u5c01\u88c5\u7684\u529f\u80fd\uff0c\u4f46\u662fNamespace\u662f\u4e00\u79cd\u66f4\u4e3a\u901a\u7528\u548c\u5e95\u5c42\u7684\u673a\u5236\uff0cPrimitives namespace\u662f\u4e00\u79cd\u66f4\u4e3a\u9ad8\u5c42\u7684\u62bd\u8c61\u6982\u5ff5\uff0c\u901a\u5e38\u7528\u4e8e\u6784\u5efa\u5bb9\u5668\u7b49\u5e94\u7528\u7ea7\u522b\u7684\u9694\u79bb\u73af\u5883\u3002 Namespace\u793a\u4f8b\uff1a \u5728Linux\u7cfb\u7edf\u4e2d\uff0c\u53ef\u4ee5\u4f7f\u7528PID Namespace\u6765\u9694\u79bb\u8fdb\u7a0bID\u53f7\u7a7a\u95f4\uff0c\u907f\u514d\u8fdb\u7a0b\u4e4b\u95f4\u7684PID\u51b2\u7a81\u3002\u4e0b\u9762\u662f\u4e00\u4e2a\u7b80\u5355\u7684\u793a\u4f8b\uff1a # \u521b\u5efa\u4e00\u4e2a\u65b0\u7684PID Namespace unshare -p /bin/bash # \u5728\u65b0\u7684PID Namespace\u4e2d\u8fd0\u884c\u4e00\u4e2a\u8fdb\u7a0b echo $$ # \u663e\u793a\u5f53\u524d\u8fdb\u7a0b\u7684PID ps aux # \u663e\u793a\u5f53\u524d\u8fdb\u7a0b\u53ca\u5176\u5b50\u8fdb\u7a0b \u5728\u4e0a\u9762\u7684\u793a\u4f8b\u4e2d\uff0c unshare -p \u547d\u4ee4\u521b\u5efa\u4e86\u4e00\u4e2a\u65b0\u7684PID Namespace\uff0c\u5e76\u5728\u5176\u4e2d\u542f\u52a8\u4e86\u4e00\u4e2a\u65b0\u7684bash\u8fdb\u7a0b\u3002\u7531\u4e8e\u8be5\u8fdb\u7a0b\u8fd0\u884c\u5728\u4e00\u4e2a\u72ec\u7acb\u7684PID Namespace\u4e2d\uff0c\u56e0\u6b64\u5b83\u7684PID\u53f7\u4e0e\u4e3b\u673a\u4e0a\u7684\u5176\u4ed6\u8fdb\u7a0b\u4e0d\u4f1a\u51b2\u7a81\u3002\u5728\u8fd9\u4e2a\u65b0\u7684bash\u8fdb\u7a0b\u4e2d\uff0c $$ \u547d\u4ee4\u663e\u793a\u7684\u662f\u8be5\u8fdb\u7a0b\u5728PID Namespace\u4e2d\u7684PID\u53f7\uff0c\u800c ps aux \u547d\u4ee4\u53ea\u4f1a\u663e\u793a\u5f53\u524dPID Namespace\u4e2d\u7684\u8fdb\u7a0b\uff0c\u4e0d\u4f1a\u663e\u793a\u4e3b\u673a\u4e0a\u7684\u5176\u4ed6\u8fdb\u7a0b\u3002 Primitives Namespace\u793a\u4f8b\uff1a \u5728Docker\u5bb9\u5668\u4e2d\uff0c\u53ef\u4ee5\u4f7f\u7528Filesystem Namespace\u6765\u9694\u79bb\u6587\u4ef6\u7cfb\u7edf\uff0c\u4f7f\u5f97\u4e0d\u540c\u7684\u5bb9\u5668\u4e4b\u95f4\u62e5\u6709\u72ec\u7acb\u7684\u6587\u4ef6\u7cfb\u7edf\u89c6\u56fe\u3002\u4e0b\u9762\u662f\u4e00\u4e2a\u7b80\u5355\u7684\u793a\u4f8b\uff1a # \u5728\u5bb9\u5668\u4e2d\u8fd0\u884c\u4e00\u4e2a\u547d\u4ee4 docker run --rm -it --name mycontainer ubuntu bash # \u5728\u5bb9\u5668\u4e2d\u521b\u5efa\u4e00\u4e2a\u6587\u4ef6\u5e76\u9000\u51fa touch myfile exit # \u5728\u4e3b\u673a\u4e0a\u67e5\u770b\u6587\u4ef6 ls myfile # myfile\u6587\u4ef6\u4e0d\u5b58\u5728 # \u518d\u6b21\u8fdb\u5165\u5bb9\u5668 docker start -i mycontainer # \u5728\u5bb9\u5668\u4e2d\u67e5\u770b\u6587\u4ef6 ls myfile # myfile\u6587\u4ef6\u5b58\u5728 \u5728\u4e0a\u9762\u7684\u793a\u4f8b\u4e2d\uff0c docker run \u547d\u4ee4\u542f\u52a8\u4e86\u4e00\u4e2a\u65b0\u7684Docker\u5bb9\u5668\uff0c\u5e76\u5728\u5176\u4e2d\u8fd0\u884c\u4e86\u4e00\u4e2abash\u8fdb\u7a0b\u3002\u7531\u4e8e\u8be5\u5bb9\u5668\u4f7f\u7528\u4e86Filesystem Namespace\uff0c\u56e0\u6b64\u5bb9\u5668\u5185\u7684\u6587\u4ef6\u7cfb\u7edf\u89c6\u56fe\u4e0e\u4e3b\u673a\u4e0a\u7684\u6587\u4ef6\u7cfb\u7edf\u89c6\u56fe\u662f\u9694\u79bb\u7684\u3002\u5728\u5bb9\u5668\u5185\u521b\u5efa\u7684\u6587\u4ef6 myfile \u53ea\u5b58\u5728\u4e8e\u5bb9\u5668\u5185\u90e8\uff0c\u5728\u4e3b\u673a\u4e0a\u662f\u770b\u4e0d\u5230\u7684\u3002\u5f53\u518d\u6b21\u8fdb\u5165\u5bb9\u5668\u65f6\uff0c myfile \u6587\u4ef6\u5c31\u53ef\u4ee5\u88ab\u770b\u5230\u4e86\u3002 \u603b\u7ed3\uff1a Namespace\u662fLinux\u5185\u6838\u63d0\u4f9b\u7684\u673a\u5236\uff0c\u800cPrimitives Namespace\u5219\u662f\u4e00\u79cd\u57fa\u4e8eNamespace\u7684\u9ad8\u5c42\u62bd\u8c61\uff0c\u7528\u4e8e\u5b9e\u73b0\u5e94\u7528\u7ea7\u522b\u7684\u9694\u79bb\u548c\u5c01\u88c5\u3002Namespace\u53ef\u4ee5\u7528\u4e8e\u9694\u79bb\u591a\u79cd\u8d44\u6e90\uff0c\u800cPrimitives Namespace\u901a\u5e38\u7528\u4e8e\u9694\u79bb\u6587\u4ef6\u7cfb\u7edf\u3001\u7f51\u7edc\u3001\u8fdb\u7a0b\u7b49\u64cd\u4f5c\u7684\u539f\u8bed\u3002","title":"\u547d\u540d\u7a7a\u95f4"},{"location":"k8s/cka_cn/foundamentals/docker/#_4","text":"cgroup\uff0c\u5168\u79f0\u4e3aControl Group\uff0c\u5373\u63a7\u5236\u7ec4\uff0c\u662fLinux\u5185\u6838\u63d0\u4f9b\u7684\u4e00\u79cd\u673a\u5236\uff0c\u7528\u4e8e\u9650\u5236\u3001\u8bb0\u5f55\u3001\u9694\u79bb\u548c\u4f18\u5148\u7ea7\u63a7\u5236\u4e00\u7ec4\u8fdb\u7a0b\u7684\u8d44\u6e90\u4f7f\u7528\u3002\u5b83\u53ef\u4ee5\u9650\u5236\u8fdb\u7a0b\u7ec4\u7684CPU\u3001\u5185\u5b58\u3001\u78c1\u76d8\u3001\u7f51\u7edc\u7b49\u8d44\u6e90\u7684\u4f7f\u7528\uff0c\u540c\u65f6\u4e5f\u53ef\u4ee5\u8bb0\u5f55\u8fdb\u7a0b\u7ec4\u7684\u8d44\u6e90\u4f7f\u7528\u60c5\u51b5\u548c\u884c\u4e3a\u3002 cgroup\u901a\u8fc7\u5c06\u4e00\u7ec4\u8fdb\u7a0b\u7ec4\u7ec7\u6210\u4e00\u4e2a\u5c42\u6b21\u7ed3\u6784\uff0c\u5c06\u8d44\u6e90\u5206\u914d\u7ed9\u4e0d\u540c\u7684cgroup\u6765\u5b9e\u73b0\u8d44\u6e90\u9650\u5236\u548c\u4f18\u5148\u7ea7\u63a7\u5236\u3002\u6bcf\u4e2acgroup\u53ef\u4ee5\u8bbe\u7f6e\u8d44\u6e90\u9650\u5236\u548c\u63a7\u5236\u7b56\u7565\uff0c\u4f8b\u5982\u53ef\u4ee5\u9650\u5236\u4e00\u4e2a\u8fdb\u7a0b\u7ec4\u6700\u591a\u4f7f\u752850%\u7684CPU\u65f6\u95f4\uff0c\u6216\u8005\u9650\u5236\u4e00\u4e2a\u8fdb\u7a0b\u7ec4\u6700\u591a\u4f7f\u7528100MB\u7684\u5185\u5b58\u7b49\u3002 cgroup\u6700\u521d\u7531Google\u516c\u53f8\u5f00\u53d1\uff0c\u540e\u6765\u88abLinux\u5185\u6838\u793e\u533a\u91c7\u7eb3\u5e76\u52a0\u5165\u5230\u5185\u6838\u4e2d\uff0c\u6210\u4e3aLinux\u7cfb\u7edf\u7684\u4e00\u90e8\u5206\u3002\u5b83\u5728\u5bb9\u5668\u6280\u672f\u3001\u865a\u62df\u5316\u3001\u4e91\u8ba1\u7b97\u7b49\u9886\u57df\u90fd\u6709\u5e7f\u6cdb\u7684\u5e94\u7528\u3002 \u4e0b\u9762\u662fcgroup \u7684\u4e00\u4e9b\u5e38\u89c1\u7528\u9014\uff1a CPU \u9650\u5236\uff1a\u4f7f\u7528 cgroup \u53ef\u4ee5\u9650\u5236\u8fdb\u7a0b\u7684 CPU \u4f7f\u7528\u7387\uff0c\u907f\u514d\u67d0\u4e2a\u8fdb\u7a0b\u5360\u7528\u8fc7\u591a\u7684 CPU \u8d44\u6e90\u5bfc\u81f4\u7cfb\u7edf\u8d1f\u8f7d\u8fc7\u9ad8\uff0c\u4ece\u800c\u5f71\u54cd\u7cfb\u7edf\u7a33\u5b9a\u6027\u548c\u5176\u4ed6\u8fdb\u7a0b\u7684\u6b63\u5e38\u8fd0\u884c\u3002 \u5185\u5b58\u9650\u5236\uff1a\u4f7f\u7528 cgroup \u53ef\u4ee5\u9650\u5236\u8fdb\u7a0b\u7684\u5185\u5b58\u4f7f\u7528\u91cf\uff0c\u907f\u514d\u67d0\u4e2a\u8fdb\u7a0b\u5360\u7528\u8fc7\u591a\u7684\u5185\u5b58\u8d44\u6e90\u5bfc\u81f4\u7cfb\u7edf\u5185\u5b58\u4e0d\u8db3\uff0c\u4ece\u800c\u5f71\u54cd\u7cfb\u7edf\u6027\u80fd\u548c\u5176\u4ed6\u8fdb\u7a0b\u7684\u6b63\u5e38\u8fd0\u884c\u3002 IO \u9650\u5236\uff1a\u4f7f\u7528 cgroup \u53ef\u4ee5\u9650\u5236\u8fdb\u7a0b\u7684 IO \u5e26\u5bbd\uff0c\u907f\u514d\u67d0\u4e2a\u8fdb\u7a0b\u5360\u7528\u8fc7\u591a\u7684 IO \u8d44\u6e90\u5bfc\u81f4\u5176\u4ed6\u8fdb\u7a0b\u7684 IO \u64cd\u4f5c\u53d7\u5230\u5f71\u54cd\uff0c\u4ece\u800c\u5f71\u54cd\u7cfb\u7edf\u6027\u80fd\u548c\u54cd\u5e94\u901f\u5ea6\u3002 \u7f51\u7edc\u9650\u5236\uff1a\u4f7f\u7528 cgroup \u53ef\u4ee5\u9650\u5236\u8fdb\u7a0b\u7684\u7f51\u7edc\u5e26\u5bbd\uff0c\u907f\u514d\u67d0\u4e2a\u8fdb\u7a0b\u5360\u7528\u8fc7\u591a\u7684\u7f51\u7edc\u8d44\u6e90\u5bfc\u81f4\u7f51\u7edc\u62e5\u585e\uff0c\u4ece\u800c\u5f71\u54cd\u7cfb\u7edf\u6027\u80fd\u548c\u5176\u4ed6\u8fdb\u7a0b\u7684\u6b63\u5e38\u8fd0\u884c\u3002 \u8fdb\u7a0b\u63a7\u5236\uff1a\u4f7f\u7528 cgroup \u53ef\u4ee5\u9650\u5236\u8fdb\u7a0b\u7684\u542f\u52a8\u3001\u505c\u6b62\u548c\u8c03\u5ea6\u7b49\u884c\u4e3a\uff0c\u4ece\u800c\u5b9e\u73b0\u5bf9\u7cfb\u7edf\u8fdb\u7a0b\u7684\u63a7\u5236\u548c\u7ba1\u7406\u3002 \u8d44\u6e90\u7edf\u8ba1\uff1a\u4f7f\u7528 cgroup \u53ef\u4ee5\u5b9e\u65f6\u7edf\u8ba1\u7cfb\u7edf\u4e2d\u5404\u4e2a\u8fdb\u7a0b\u7684\u8d44\u6e90\u4f7f\u7528\u60c5\u51b5\uff0c\u4ece\u800c\u5e2e\u52a9\u7ba1\u7406\u5458\u4e86\u89e3\u7cfb\u7edf\u8d1f\u8f7d\u72b6\u51b5\u548c\u5404\u4e2a\u8fdb\u7a0b\u7684\u6027\u80fd\u74f6\u9888\uff0c\u4ece\u800c\u91c7\u53d6\u76f8\u5e94\u7684\u63aa\u65bd\u4f18\u5316\u7cfb\u7edf\u6027\u80fd\u3002 \u4e0b\u9762\u662fopenSUSE\u4e2d\u7684\u793a\u4f8b\uff1a \u5b89\u88c5\u9700\u8981\u7684\u8f6f\u4ef6\u5305\uff1a sudo zypper install libcgroup-tools \u9650\u5236CPU\u4f7f\u7528\u4e0a\u9650\uff1a # \u521b\u5efa\u65b0\u7684cgroup 'mygroup' sudo mkdir /sys/fs/cgroup/cpu/mygroup # \u7cfb\u7edf\u4f1a\u521b\u5efa\u9ed8\u8ba4\u7684\u4e00\u4e9b\u6587\u4ef6\uff0c\u542b\u521d\u59cb\u503c\uff0c\u6bd4\u5982CPU\u4f7f\u7528\u65f6\u95f4\u7684\u9650\u989d\u7684\u9ed8\u8ba4\u503c\u662f-1 cat /sys/fs/cgroup/cpu/mygroup/cpu.cfs_quota_us # \u8bbe\u5b9aCPU\u4f7f\u7528\u65f6\u95f4\u4e0a\u9650 sudo sh -c \"echo 50000 > /sys/fs/cgroup/cpu/mygroup/cpu.cfs_quota_us\" # \u542f\u52a8\u4e00\u4e2a\u65b0\u7684\u8fdb\u7a0b\uff0c\u5e76\u4e14\u5173\u8054\u5230 sudo cgcreate -g cpu:mygroup sudo cgexec -g cpu:mygroup /bin/bash \u5728\u4e0a\u9762\u7684\u4f8b\u5b50\u4e2d\uff0c cpu.cfs_quota_us \u6587\u4ef6\u8bbe\u7f6e\u4e86 cgroup \u4e2d\u7684\u8fdb\u7a0b\u53ef\u4ee5\u4f7f\u7528\u7684\u6700\u5927 CPU \u65f6\u95f4\u3002\u8be5\u503c\u4ee5\u5fae\u79d2\u4e3a\u5355\u4f4d\uff0c\u56e0\u6b64\u5c06\u5176\u8bbe\u7f6e\u4e3a 50000 \u8868\u793a\u8fdb\u7a0b\u6700\u591a\u53ef\u4ee5\u4f7f\u7528\u5355\u4e2a CPU \u6838\u5fc3\u7684 50%\u3002 cgcreate \u548c cgexec \u547d\u4ee4\u521b\u5efa\u5e76\u5c06\u8fdb\u7a0b /bin/bash \u79fb\u52a8\u5230 mygroup cgroup \u4e2d\u3002 \u9650\u5236\u5185\u5b58\u4f7f\u7528\u4e0a\u9650\uff1a # \u521b\u5efa\u65b0\u7684cgroup 'mygroup' sudo mkdir /sys/fs/cgroup/memory/mygroup # \u7cfb\u7edf\u4f1a\u521b\u5efa\u9ed8\u8ba4\u7684\u4e00\u4e9b\u6587\u4ef6\uff0c\u542b\u521d\u59cb\u503c\uff0c\u6bd4\u5982\u5185\u5b58\u4f7f\u7528\u4e0a\u9650\u7684\u9ed8\u8ba4\u503c\u662f9223372036854771712 cat /sys/fs/cgroup/memory/mygroup/memory.limit_in_bytes # \u8bbe\u7f6e\u5185\u5b58\u4f7f\u7528\u4e0a\u9650512MB sudo sh -c \"echo 536870912 > /sys/fs/cgroup/memory/mygroup/memory.limit_in_bytes\" # \u542f\u52a8\u4e00\u4e2a\u65b0\u7684\u8fdb\u7a0b\uff0c\u5e76\u4e14\u5173\u8054\u5230'mygroup' sudo cgcreate -g memory:mygroup sudo cgexec -g memory:mygroup /bin/bash \u5728\u4e0a\u9762\u4f8b\u5b50\u4e2d\uff0c memory.limit_in_bytes \u6587\u4ef6\u8bbe\u7f6e\u4e86 cgroup \u4e2d\u8fdb\u7a0b\u53ef\u4ee5\u4f7f\u7528\u7684\u6700\u5927\u5185\u5b58\u91cf\u3002\u8be5\u503c\u4ee5\u5b57\u8282\u4e3a\u5355\u4f4d\uff0c\u56e0\u6b64\u5c06\u5176\u8bbe\u7f6e\u4e3a 536870912 \u8868\u793a\u8fdb\u7a0b\u6700\u591a\u53ef\u4ee5\u4f7f\u7528 512MB \u7684\u5185\u5b58\u3002 \u8bbe\u7f6e\u4f18\u5148\u8fdb\u7a0b\u7684 I/O \u4f7f\u7528\u7387\uff1a # \u521b\u5efa\u65b0cgroup 'mygroup' sudo mkdir /sys/fs/cgroup/blkio/mygroup # \u8bbe\u7f6e\u8fdb\u7a0b\u6700\u5927\u8bfb\u548c\u5199\u7684\u901f\u738710MB/s sudo sh -c \"echo '8:0 10485760' > /sys/fs/cgroup/blkio/mygroup/blkio.throttle.read_bps_device\" sudo sh -c \"echo '8:0 10485760' > /sys/fs/cgroup/blkio/mygroup/blkio.throttle.write_bps_device\" # \u542f\u52a8\u4e00\u4e2a\u65b0\u7684\u8fdb\u7a0b\uff0c\u5e76\u4e14\u5173\u8054\u5230'mygroup' sudo cgcreate -g blkio:mygroup sudo cgexec -g blkio:mygroup /bin/bash \u5728\u4e0a\u9762\u4f8b\u5b50\u4e2d\uff0c blkio.throttle.read_bps_device \u548c blkio.throttle.write_bps_device \u6587\u4ef6\u8bbe\u7f6e\u4e86cgroup\u4e2d\u8fdb\u7a0b\u53ef\u4ee5\u4f7f\u7528\u7684\u6700\u5927\u8bfb\u53d6\u548c\u5199\u5165\u5e26\u5bbd\u3002\u8be5\u503c\u4ee5\u6bcf\u79d2\u5b57\u8282\u6570\u4e3a\u5355\u4f4d\uff0c\u56e0\u6b64\u5c06\u5176\u8bbe\u7f6e\u4e3a10485760\u610f\u5473\u7740\u8fdb\u7a0b\u5728\u4e3b\u8bbe\u5907\u53f7:\u6b21\u8bbe\u5907\u53f7\u4e3a8:0\u7684\u8bbe\u5907\uff08\u901a\u5e38\u662f\u7b2c\u4e00\u4e2a\u786c\u76d8\uff09\u4e0a\u8bfb\u53d6\u6216\u5199\u5165\u7684\u5e26\u5bbd\u6700\u591a\u4e3a10MB/s\u3002 \u5c06 8:0 10485760 \u8fd9\u4e2a\u5b57\u7b26\u4e32\u5199\u5165\u5230 /sys/fs/cgroup/blkio/mygroup/blkio.throttle.read_bps_device \u6587\u4ef6\u4e2d\u7684\u4f5c\u7528\u662f\u9650\u5236 mygroup \u63a7\u5236\u7ec4\u4e2d\u5173\u8054\u7684\u5757\u8bbe\u5907\uff08block device\uff09\u7684\u8bfb\u53d6\u901f\u7387\u3002 \u5728 Linux \u4e2d\uff0c blkio \u63a7\u5236\u7ec4\u5b50\u7cfb\u7edf\u53ef\u4ee5\u7528\u6765\u5bf9\u8fdb\u7a0b\u6216\u7ebf\u7a0b\u7684\u5757\u8bbe\u5907\u8bbf\u95ee\u8fdb\u884c\u9650\u5236\uff0c\u5982\u9650\u5236\u8bfb\u5199\u901f\u7387\u3001I/O \u4f18\u5148\u7ea7\u7b49\u3002\u800c blkio.throttle.read_bps_device \u8fd9\u4e2a\u6587\u4ef6\u5219\u7528\u4e8e\u8bbe\u7f6e\u67d0\u4e2a\u5757\u8bbe\u5907\u7684\u8bfb\u53d6\u901f\u7387\u9650\u5236\u3002 \u5177\u4f53\u6765\u8bf4\uff0c 8:0 \u8868\u793a\u8bbe\u5907\u7684\u4e3b\u6b21\u7f16\u53f7\uff08major:minor\uff09\uff0c\u8fd9\u91cc\u662f\u6307\u78c1\u76d8 /dev/sda \u3002 10485760 \u5219\u662f\u8bfb\u53d6\u901f\u7387\u7684\u9650\u5236\u503c\uff0c\u5355\u4f4d\u662f\u5b57\u8282/\u79d2\u3002\u8fd9\u4e2a\u503c\u8868\u793a /dev/sda \u6700\u5927\u8bfb\u53d6\u901f\u7387\u4e3a 10MB/s\uff0c\u8d85\u8fc7\u8fd9\u4e2a\u901f\u7387\u7684\u8bfb\u53d6\u8bf7\u6c42\u4f1a\u88ab\u5ef6\u8fdf\u6267\u884c\uff0c\u4ece\u800c\u9650\u5236\u4e86\u78c1\u76d8\u7684\u8bfb\u53d6\u5e26\u5bbd\u3002 \u56e0\u6b64\uff0c\u4ee5\u4e0a\u547d\u4ee4\u7684\u542b\u4e49\u662f\u5c06 mygroup \u63a7\u5236\u7ec4\u4e2d\u5173\u8054\u7684 /dev/sda \u78c1\u76d8\u7684\u8bfb\u53d6\u901f\u7387\u9650\u5236\u4e3a 10MB/s\uff0c\u4ece\u800c\u5b9e\u73b0\u5bf9\u8be5\u63a7\u5236\u7ec4\u4e2d\u8fdb\u7a0b\u6216\u7ebf\u7a0b\u5bf9\u78c1\u76d8\u8bfb\u53d6\u7684\u9650\u5236\u3002 \u540c\u7406\uff0c\u5c06 8:0 10485760 \u8fd9\u4e2a\u5b57\u7b26\u4e32\u5199\u5165\u5230 /sys/fs/cgroup/blkio/mygroup/blkio.throttle.write_bps_device \u6587\u4ef6\u4e2d\uff0c\u4ee5\u9650\u5236 mygroup \u63a7\u5236\u7ec4\u4e2d\u5173\u8054\u7684\u5757\u8bbe\u5907\uff08block device\uff09\u7684\u5199\u5165\u901f\u7387\u3002 \u9650\u5236\u4e00\u7ec4\u8fdb\u7a0b\u7684\u7f51\u7edc\u5e26\u5bbd\uff1a # \u521b\u5efa\u65b0\u7684cgroup 'mygroup' sudo mkdir /sys/fs/cgroup/net_cls/mygroup # \u5c06\u6b64\u7ec4\u4e2d\u7684\u8fdb\u7a0b\u7684\u7f51\u7edc\u7c7bID\u8bbe\u7f6e\u4e3a\u201cmyclass\u201d sudo sh -c \"echo 0x10001 > /sys/fs/cgroup/net_cls/mygroup/net_cls.classid\" \u4e0a\u9762\u7684\u4f8b\u5b50\u662f\u5c06 0x10001 \u8fd9\u4e2a\u5341\u516d\u8fdb\u5236\u6570\u503c\u5199\u5165\u5230 /sys/fs/cgroup/net_cls/mygroup/net_cls.classid \u6587\u4ef6\u4e2d\uff0c\u4ee5\u6307\u5b9a mygroup \u63a7\u5236\u7ec4\u7684\u7f51\u7edc\u7c7b\u522b\u6807\u8bc6\u7b26\uff08classid\uff09\u3002 \u7f51\u7edc\u7c7b\u522b\u6807\u8bc6\u7b26\u662f Linux \u5185\u6838\u4e2d\u7528\u6765\u5b9e\u73b0\u6d41\u91cf\u63a7\u5236\u548c\u6d41\u91cf\u5206\u7c7b\u7684\u4e00\u4e2a\u673a\u5236\uff0c\u5b83\u53ef\u4ee5\u5c06\u6570\u636e\u5305\u6309\u7167\u4e0d\u540c\u7684\u7c7b\u522b\uff08class\uff09\u8fdb\u884c\u6807\u8bb0\u548c\u533a\u5206\uff0c\u7136\u540e\u5728\u7f51\u7edc\u8bbe\u5907\u4e0a\u9488\u5bf9\u4e0d\u540c\u7684\u7c7b\u522b\u8fdb\u884c\u4e0d\u540c\u7684\u5904\u7406\uff0c\u5982\u9650\u901f\u3001\u4f18\u5148\u7ea7\u8c03\u6574\u7b49\u3002\u63a7\u5236\u7ec4\u4e2d\u7684 net_cls \u5b50\u7cfb\u7edf\u53ef\u4ee5\u7528\u6765\u5c06\u8fdb\u7a0b\u6216\u7ebf\u7a0b\u4e0e\u7f51\u7edc\u7c7b\u522b\u6807\u8bc6\u7b26\u5173\u8054\u8d77\u6765\uff0c\u4ece\u800c\u5b9e\u73b0\u5bf9\u5b83\u4eec\u7684\u7f51\u7edc\u6d41\u91cf\u8fdb\u884c\u63a7\u5236\u548c\u5206\u7c7b\u3002 \u56e0\u6b64\uff0c\u4ee5\u4e0a\u547d\u4ee4\u662f\u5c06 mygroup \u63a7\u5236\u7ec4\u7684\u7f51\u7edc\u7c7b\u522b\u6807\u8bc6\u7b26\u8bbe\u7f6e\u4e3a 0x10001 \uff0c\u8fd9\u6837\u4e0e\u8be5\u63a7\u5236\u7ec4\u76f8\u5173\u8054\u7684\u8fdb\u7a0b\u6216\u7ebf\u7a0b\u5c31\u4f1a\u88ab\u6807\u8bb0\u4e3a\u8be5\u7c7b\u522b\uff0c\u7136\u540e\u53ef\u4ee5\u901a\u8fc7\u5176\u4ed6\u5de5\u5177\uff08\u5982 tc \u547d\u4ee4\uff09\u5bf9\u5176\u8fdb\u884c\u7f51\u7edc\u6d41\u91cf\u63a7\u5236\u548c\u5206\u7c7b\u3002 \u5982\u679c\u9047\u5230\u5bf9\u5e94\u9650\u5236\u6587\u4ef6\u4e0d\u5b58\u5728\uff0c\u4e00\u79cd\u53ef\u80fd\u662f\u9700\u8981\u68c0\u67e5cgroup\u5b50\u7cfb\u6709\u6ca1\u6709\u6b63\u786e\u7edf\u8f7d\u6216\u8005\u6ca1\u6709\u542f\u7528\u5185\u5b58\u5b50\u7cfb\u7edf\u3002 mount | grep cgroup \u5982\u679c cgroups \u6587\u4ef6\u7cfb\u7edf\u5df2\u7ecf\u6302\u8f7d\uff0c\u5e94\u8be5\u4f1a\u770b\u5230\u8f93\u51fa\u7c7b\u4f3c\u4e8e\u4ee5\u4e0b\u5185\u5bb9\uff08\uff09\u4ee5memory\u4e3a\u4f8b\uff09\uff1a cgroup on /sys/fs/cgroup/memory type cgroup (rw,nosuid,nodev,noexec,relatime,memory) \u5982\u679c\u6ca1\u6709\u770b\u5230 memory \u5b57\u6bb5\uff0c\u5219\u8868\u793a\u5185\u5b58\u5b50\u7cfb\u7edf\u6ca1\u6709\u542f\u7528\u3002\u53ef\u4ee5\u7f16\u8f91 /etc/default/grub \u6587\u4ef6\uff0c\u6dfb\u52a0\u6216\u4fee\u6539\u4ee5\u4e0b\u884c\uff1a GRUB_CMDLINE_LINUX_DEFAULT=\"cgroup_enable=memory\" \u7136\u540e\u66f4\u65b0 GRUB \u914d\u7f6e\u5e76\u91cd\u542f\u7cfb\u7edf\uff1a sudo update-grub sudo reboot \u91cd\u542f\u540e\u518d\u6b21\u68c0\u67e5 /sys/fs/cgroup/memory/mygroup/memory.limit_in_bytes \u6587\u4ef6\u662f\u5426\u5b58\u5728\u3002\u5982\u679c\u8fd8\u662f\u4e0d\u5b58\u5728\uff0c\u53ef\u80fd\u9700\u8981\u624b\u52a8\u521b\u5efa\u5b83\u4ee5\u53ca\u5176\u4ed6\u76f8\u5173\u7684 cgroups \u6587\u4ef6\u3002\u4f8b\u5982\uff0c\u8fd0\u884c\u4ee5\u4e0b\u547d\u4ee4\uff1a sudo mkdir /sys/fs/cgroup/memory/mygroup sudo touch /sys/fs/cgroup/memory/mygroup/memory.limit_in_bytes \u7136\u540e\u5c31\u53ef\u4ee5\u50cf\u4e4b\u524d\u7684\u4f8b\u5b50\u4e00\u6837\u8bbe\u7f6e\u5185\u5b58\u9650\u5236\u4e86","title":"\u63a7\u5236\u7ec4"},{"location":"k8s/cka_cn/foundamentals/docker/#apparmorselinux","text":"\u5b89\u5168\u914d\u7f6e\u6587\u4ef6\uff0c\u7528\u4e8e\u63a7\u5236\u5bf9\u8d44\u6e90\u7684\u8bbf\u95ee AppArmor \u548c SELinux \u90fd\u662f\u5e38\u89c1\u7684\u5f3a\u5236\u8bbf\u95ee\u63a7\u5236\uff08MAC\uff09\u673a\u5236\uff0c\u53ef\u4ee5\u5bf9\u8fdb\u7a0b\u6216\u5e94\u7528\u7a0b\u5e8f\u7684\u8bbf\u95ee\u6743\u9650\u8fdb\u884c\u7cbe\u7ec6\u63a7\u5236\u3002\u4e0b\u9762\u5206\u522b\u4e3e\u4f8b\u8bf4\u660e\u8fd9\u4e24\u79cd\u673a\u5236\u7684\u914d\u7f6e\u6587\u4ef6\u4f7f\u7528\u3002 AppArmor AppArmor \u7684\u4e3b\u914d\u7f6e\u6587\u4ef6\u662f /etc/apparmor/profiles.d/ \u76ee\u5f55\u4e0b\u7684\u5404\u4e2a\u6587\u4ef6\uff0c\u6bcf\u4e2a\u6587\u4ef6\u5bf9\u5e94\u4e00\u4e2a\u5e94\u7528\u7a0b\u5e8f\u6216\u8fdb\u7a0b\u7684\u914d\u7f6e\u3002\u4ee5 sshd \u670d\u52a1\u4e3a\u4f8b\uff0c\u8be5\u670d\u52a1\u7684\u914d\u7f6e\u6587\u4ef6\u662f /etc/apparmor.d/usr.sbin.sshd \u3002 \u8be5\u914d\u7f6e\u6587\u4ef6\u7684\u5185\u5bb9\u7c7b\u4f3c\u4e8e\u4e0b\u9762\u8fd9\u6837\uff1a # Last Modified: Sun Mar 14 18 :53:00 2023 # include /usr/sbin/sshd { # include # include # allow read access to user home directories /home/** r, # allow sshd to execute /usr/bin/which to determine full path of shell /usr/bin/which ix, # allow sshd to read its own configuration file /etc/ssh/sshd_config r, # allow sshd to read the SSH host keys /etc/ssh/ssh_host_* r, # allow sshd to use pam for authentication /usr/share/pam/** r, # allow sshd to use nsswitch for name resolution /etc/nsswitch.conf r, /etc/hosts r, /etc/hostname r, /etc/resolv.conf r, # allow sshd to write to its own log file /var/log/auth.log w, # allow sshd to create and manage pid files /var/run/sshd.pid w, /var/run/sshd.dir/ w, /var/run/sshd.dir/* rw, # allow sshd to access systemd-logind /run/systemd/* r, /run/systemd/session/*.scope r, /run/systemd/sessions/*.scope r, # deny everything else deny /, } \u8be5\u914d\u7f6e\u6587\u4ef6\u5b9a\u4e49\u4e86 /usr/sbin/sshd \u8fdb\u7a0b\u7684\u6743\u9650\u9650\u5236\u89c4\u5219\uff0c\u5305\u62ec\u5141\u8bb8\u8bbf\u95ee\u7684\u6587\u4ef6\u3001\u7981\u6b62\u8bbf\u95ee\u7684\u6587\u4ef6\u7b49\u3002\u5176\u4e2d #include \u8868\u793a\u5305\u542b\u4e86\u4e00\u7ec4\u901a\u7528\u7684\u6743\u9650\u89c4\u5219\uff0c\u53ef\u4ee5\u5728\u4e0d\u540c\u7684\u5e94\u7528\u7a0b\u5e8f\u914d\u7f6e\u4e2d\u91cd\u590d\u4f7f\u7528\u3002 2.SELinux SELinux \u7684\u4e3b\u914d\u7f6e\u6587\u4ef6\u662f /etc/selinux/config \uff0c\u8be5\u6587\u4ef6\u5b9a\u4e49\u4e86\u7cfb\u7edf\u7684 SELinux \u7b56\u7565\u548c\u6a21\u5f0f\u3002\u9ed8\u8ba4\u60c5\u51b5\u4e0b\uff0copenSUSE \u4f7f\u7528\u7684\u662f targeted \u6a21\u5f0f\u3002 \u6bcf\u4e2a\u8fdb\u7a0b\u6216\u5e94\u7528\u7a0b\u5e8f\u8fd8\u9700\u8981\u5bf9\u5e94\u4e00\u4e2a SELinux \u914d\u7f6e\u6587\u4ef6\uff0c\u4ee5\u5b9a\u4e49\u5b83\u4eec\u7684\u8bbf\u95ee\u6743\u9650\u3002\u4ee5 httpd \u670d\u52a1\u4e3a\u4f8b\uff0c\u8be5\u670d\u52a1\u7684 SELinux \u914d\u7f6e\u6587\u4ef6\u662f /etc/selinux/targeted/contexts/httpd.te \u3002 \u8be5\u914d\u7f6e\u6587\u4ef6\u7684\u5185\u5bb9\u7c7b\u4f3c\u4e8e\u4e0b\u9762\u8fd9\u6837\uff1a # HTTPD server type httpd_t ; type httpd_sys_script_t ; init_daemon_domain ( httpd_t, httpd_sys_script_t ) \u8be5\u914d\u7f6e\u6587\u4ef6\u5b9a\u4e49\u4e86 httpd \u670d\u52a1\u7684 SELinux \u7c7b\u578b\u4e3a httpd_t \uff0c\u5e76\u4f7f\u7528\u4e86 httpd_sys_script_t \u4f5c\u4e3a\u5176\u521d\u59cb\u5316\u57df\u3002\u5176\u4e2d type \u8868\u793a SELinux \u7c7b\u578b\uff0c init_daemon_domain \u5219\u662f\u4e00\u4e2a SELinux \u5b8f\uff0c\u7528\u4e8e\u5b9a\u4e49\u670d\u52a1\u7684\u521d\u59cb\u57df\u3002 \u9700\u8981\u6ce8\u610f\u7684\u662f\uff0c\u5728 SELinux \u4e2d\uff0c\u8bbf\u95ee\u6743\u9650\u89c4\u5219\u4e0d\u662f\u76f4\u63a5\u5728\u914d\u7f6e\u6587\u4ef6\u4e2d\u5b9a\u4e49\u7684\uff0c\u800c\u662f\u901a\u8fc7\u8bbf\u95ee\u63a7\u5236\u7b56\u7565\u548c\u89c4\u5219\u8fdb\u884c\u63a7\u5236\u3002\u8fd9\u4e9b\u7b56\u7565\u548c\u89c4\u5219\u53ef\u4ee5\u4f7f\u7528 SELinux \u5de5\u5177\u96c6\uff08\u5982 semanage \u3001 setsebool \u3001 restorecon \u7b49\uff09\u8fdb\u884c\u7ba1\u7406\u548c\u8bbe\u7f6e\u3002 \u6bd4\u5982\uff0c\u5728openSUSE\u4e2d\u53ef\u4ee5\u770b\u5230 /etc/selinux/semanage.conf \u6587\u4ef6\u548c\u5176\u4e2d\u7684\u914d\u7f6e\u3002","title":"Apparmor\u548cSELinux\u914d\u7f6e\u6587\u4ef6"},{"location":"k8s/cka_cn/foundamentals/docker/#_5","text":"\u5185\u6838\u80fd\u529b\uff08Kernel capabilities\uff09 \u6ca1\u6709\u80fd\u529b\uff1aroot\u53ef\u4ee5\u6267\u884c\u6240\u6709\u64cd\u4f5c\uff0c\u5176\u4ed6\u7528\u6237\u53ef\u80fd\u4ec0\u4e48\u4e5f\u505a\u4e0d\u4e86 38\u4e2a\u7ec6\u7c92\u5ea6\u7684\u529f\u80fd\u6765\u63a7\u5236\u6743\u9650 Kernel capabilities \u662f Linux \u5185\u6838\u63d0\u4f9b\u7684\u4e00\u79cd\u673a\u5236\uff0c\u7528\u4e8e\u63a7\u5236\u8fdb\u7a0b\u5bf9\u7cfb\u7edf\u8d44\u6e90\u7684\u8bbf\u95ee\u6743\u9650\u3002\u4e0e\u4f20\u7edf\u7684 Unix \u6743\u9650\u673a\u5236\u4e0d\u540c\uff0cKernel capabilities \u53ef\u4ee5\u4f7f\u7ba1\u7406\u5458\u5728\u7cbe\u7ec6\u63a7\u5236\u7cfb\u7edf\u8d44\u6e90\u8bbf\u95ee\u7684\u540c\u65f6\uff0c\u907f\u514d\u5c06\u8fc7\u591a\u6743\u9650\u6388\u4e88\u8fdb\u7a0b\uff0c\u63d0\u9ad8\u4e86\u7cfb\u7edf\u7684\u5b89\u5168\u6027\u3002 \u5728\u4f20\u7edf Unix \u6743\u9650\u673a\u5236\u4e2d\uff0c\u6bcf\u4e2a\u8fdb\u7a0b\u90fd\u6709\u4e00\u4e2a\u6709\u6548\u7528\u6237 ID \u548c\u4e00\u4e2a\u6709\u6548\u7ec4 ID\uff0c\u8fd9\u4e9b ID \u51b3\u5b9a\u4e86\u8be5\u8fdb\u7a0b\u5bf9\u6587\u4ef6\u3001\u8bbe\u5907\u3001\u7f51\u7edc\u7b49\u8d44\u6e90\u7684\u8bbf\u95ee\u6743\u9650\u3002\u4f46\u662f\uff0c\u8fd9\u79cd\u6743\u9650\u673a\u5236\u4e0d\u591f\u7075\u6d3b\uff0c\u5982\u679c\u8981\u6388\u4e88\u8fdb\u7a0b\u67d0\u4e9b\u7279\u5b9a\u7684\u6743\u9650\uff0c\u53ef\u80fd\u9700\u8981\u5c06\u6240\u6709\u7684\u6743\u9650\u90fd\u6388\u4e88\u7ed9\u5b83\uff0c\u4ece\u800c\u964d\u4f4e\u4e86\u7cfb\u7edf\u7684\u5b89\u5168\u6027\u3002 Kernel capabilities \u63d0\u4f9b\u4e86\u4e00\u79cd\u66f4\u7ec6\u7c92\u5ea6\u7684\u6743\u9650\u63a7\u5236\u65b9\u5f0f\u3002\u6bcf\u4e2a\u8fdb\u7a0b\u90fd\u6709\u4e00\u7ec4 capabilities\uff0c\u6bcf\u4e2a capability \u8868\u793a\u4e00\u79cd\u7279\u5b9a\u7684\u6743\u9650\u3002\u8fdb\u7a0b\u53ef\u4ee5\u8bf7\u6c42\u548c\u91ca\u653e\u67d0\u4e9b capability\uff0c\u8fd9\u6837\u5c31\u53ef\u4ee5\u5c06\u6743\u9650\u6388\u4e88\u8fdb\u7a0b\uff0c\u800c\u4e0d\u5fc5\u6388\u4e88\u6240\u6709\u6743\u9650\u3002 \u4f8b\u5982\uff0c\u53ef\u4ee5\u5c06 CAP_NET_BIND_SERVICE capability \u6388\u4e88\u67d0\u4e2a\u8fdb\u7a0b\uff0c\u8fd9\u6837\u8be5\u8fdb\u7a0b\u5c31\u53ef\u4ee5\u7ed1\u5b9a 1-1023 \u7684\u7aef\u53e3\uff0c\u800c\u4e0d\u5fc5\u5177\u6709 root \u6743\u9650\u3002\u7c7b\u4f3c\u5730\uff0c\u53ef\u4ee5\u5c06 CAP_SYS_ADMIN capability \u6388\u4e88\u67d0\u4e2a\u8fdb\u7a0b\uff0c\u8fd9\u6837\u8be5\u8fdb\u7a0b\u5c31\u53ef\u4ee5\u6267\u884c\u7cfb\u7edf\u7ba1\u7406\u4efb\u52a1\uff0c\u5982\u6302\u8f7d\u6587\u4ef6\u7cfb\u7edf\u548c\u521b\u5efa\u8bbe\u5907\u8282\u70b9\u7b49\u3002 Linux \u5185\u6838\u63d0\u4f9b\u4e86\u4e00\u7ec4\u9ed8\u8ba4\u7684 capabilities\uff0c\u4e5f\u53ef\u4ee5\u901a\u8fc7\u81ea\u5b9a\u4e49\u7684\u65b9\u5f0f\u521b\u5efa\u65b0\u7684 capabilities\uff0c\u4ee5\u4fbf\u66f4\u597d\u5730\u63a7\u5236\u7cfb\u7edf\u8d44\u6e90\u7684\u8bbf\u95ee\u6743\u9650\u3002\u53ef\u4ee5\u4f7f\u7528 setcap \u547d\u4ee4\u4e3a\u4e8c\u8fdb\u5236\u6587\u4ef6\u8bbe\u7f6e capabilities\u3002\u4f8b\u5982\uff0c\u4e0b\u9762\u7684\u547d\u4ee4\u5c06 CAP_NET_RAW capability \u6388\u4e88 /usr/bin/ping \u547d\u4ee4\uff1a sudo setcap cap_net_raw+ep /usr/bin/ping \u8fd9\u6837\uff0c\u7528\u6237\u5c31\u53ef\u4ee5\u4f7f\u7528 ping \u547d\u4ee4\u800c\u4e0d\u5fc5\u4ee5 root \u7528\u6237\u7684\u8eab\u4efd\u767b\u5f55\u3002 \u9664\u4e86 CAP_NET_BIND_SERVICE \u548c CAP_SYS_ADMIN \uff0c\u8fd8\u6709\u4e00\u4e9b\u5176\u4ed6\u7684 capabilities\uff0c\u4ee5\u4e0b\u662f\u4e00\u4e9b\u4f8b\u5b50\uff1a CAP_DAC_OVERRIDE \uff1a\u5141\u8bb8\u8fdb\u7a0b\u5ffd\u7565\u6587\u4ef6\u6743\u9650\uff0c\u53ef\u4ee5\u8bbf\u95ee\u4efb\u4f55\u6587\u4ef6\u3002 CAP_CHOWN \uff1a\u5141\u8bb8\u8fdb\u7a0b\u4fee\u6539\u6587\u4ef6\u7684\u6240\u6709\u8005\u3002 CAP_SETUID \u548c CAP_SETGID \uff1a\u5141\u8bb8\u8fdb\u7a0b\u4fee\u6539\u81ea\u5df1\u7684\u7528\u6237 ID \u548c\u7ec4 ID\u3002 CAP_NET_ADMIN \uff1a\u5141\u8bb8\u8fdb\u7a0b\u6267\u884c\u7f51\u7edc\u7ba1\u7406\u4efb\u52a1\uff0c\u5982\u914d\u7f6e\u7f51\u7edc\u63a5\u53e3\u548c\u8def\u7531\u8868\u7b49\u3002 CAP_SYS_RESOURCE \uff1a\u5141\u8bb8\u8fdb\u7a0b\u4fee\u6539\u7cfb\u7edf\u8d44\u6e90\u9650\u5236\uff0c\u5982 CPU \u65f6\u95f4\u548c\u5185\u5b58\u9650\u5236\u7b49\u3002 \u53ef\u4ee5\u901a\u8fc7\u547d\u4ee4 man 7 capabilities \u6765\u67e5\u770b\u7cfb\u7edf\u63d0\u4f9b\u7684 capabilities \u5217\u8868\u548c\u8be6\u7ec6\u8bf4\u660e\u3002\u5728\u4f7f\u7528 Kernel capabilities \u65f6\uff0c\u9700\u8981\u6ce8\u610f\uff0c\u53ea\u6709\u62e5\u6709 CAP_SETFCAP \u6216 CAP_SYS_ADMIN capability \u7684\u8fdb\u7a0b\u624d\u80fd\u591f\u4fee\u6539\u81ea\u5df1\u6216\u5176\u4ed6\u8fdb\u7a0b\u7684 capabilities\uff0c\u8fd9\u4e5f\u662f\u4e3a\u4e86\u4fdd\u62a4\u7cfb\u7edf\u7684\u5b89\u5168\u6027\u3002 \u5982\u679c\u6267\u884c setcap \u547d\u4ee4\u65f6\u51fa\u73b0 \"command not found\" \u7684\u9519\u8bef\uff0c\u8fd9\u901a\u5e38\u610f\u5473\u7740 setcap \u547d\u4ee4\u6240\u5728\u7684\u5305\u5c1a\u672a\u5b89\u88c5\u3002\u5728 openSUSE \u4e2d\uff0csetcap \u547d\u4ee4\u5305\u542b\u5728 libcap-progs \u8f6f\u4ef6\u5305\u4e2d\u3002 \u5728 openSUSE \u7cfb\u7edf\u4e2d\u9700\u8981\u5b89\u88c5 libcap-progs \u8f6f\u4ef6\u5305\uff1a sudo zypper in libcap-progs \u5728 Ubuntu/Debian \u7cfb\u7edf\u4e0a\u9700\u8981\u5b89\u88c5 libcap \u5e93\uff1a sudo apt-get install libcap2-bin \u5728 CentOS/RHEL \u7cfb\u7edf\u4e0a\u9700\u8981\u5b89\u88c5 libcap \u5e93\uff1a sudo yum install libcap-devel \u5b89\u88c5\u5b8c\u6210\u540e\uff0c\u53ef\u4ee5\u4f7f\u7528 setcap \u547d\u4ee4\u4e3a\u4e8c\u8fdb\u5236\u6587\u4ef6\u8bbe\u7f6e capabilities\u3002\u5982\u679c\u8fd8\u662f\u65e0\u6cd5\u627e\u5230 setcap \u547d\u4ee4\uff0c\u53ef\u4ee5\u5c1d\u8bd5\u4f7f\u7528\u5b8c\u6574\u8def\u5f84 /sbin/setcap \u6216\u8005 /usr/sbin/setcap\u3002","title":"\u5185\u6838\u80fd\u529b"},{"location":"k8s/cka_cn/foundamentals/docker/#seccomp","text":"seccomp\uff08secure computing mode\uff09\u662f Linux \u5185\u6838\u63d0\u4f9b\u7684\u4e00\u79cd\u5b89\u5168\u673a\u5236\uff0c\u5b83\u53ef\u4ee5\u9650\u5236\u8fdb\u7a0b\u80fd\u591f\u8fdb\u884c\u7684\u7cfb\u7edf\u8c03\u7528\u3002\u901a\u8fc7\u4f7f\u7528 seccomp\uff0c\u53ef\u4ee5\u9650\u5236\u8fdb\u7a0b\u53ea\u80fd\u591f\u4f7f\u7528\u5fc5\u8981\u7684\u7cfb\u7edf\u8c03\u7528\uff0c\u4ece\u800c\u51cf\u5c11\u7cfb\u7edf\u88ab\u653b\u51fb\u7684\u98ce\u9669\u3002 seccomp \u7b56\u7565\u53ef\u4ee5\u4f7f\u7528 BPF\uff08Berkeley Packet Filter\uff09\u8bed\u8a00\u7f16\u5199\uff0c\u5e76\u4f7f\u7528 seccomp() \u7cfb\u7edf\u8c03\u7528\u52a0\u8f7d\u3002\u4ee5\u4e0b\u662f\u4e00\u4e2a\u4f7f\u7528 seccomp \u7b56\u7565\u9650\u5236\u8fdb\u7a0b\u80fd\u591f\u8fdb\u884c\u7684\u7cfb\u7edf\u8c03\u7528\u7684\u793a\u4f8b\uff1a #include #include #include int main () { // \u521b\u5efa seccomp \u8fc7\u6ee4\u5668 struct sock_filter filter [] = { BPF_STMT ( BPF_LD | BPF_W | BPF_ABS , 0 ), BPF_JUMP ( BPF_JMP | BPF_JEQ | BPF_K , __NR_write , 0 , 1 ), BPF_STMT ( BPF_RET | BPF_K , SECCOMP_RET_ALLOW ), BPF_STMT ( BPF_RET | BPF_K , SECCOMP_RET_KILL ), }; struct sock_fprog prog = { . len = sizeof ( filter ) / sizeof ( filter [ 0 ]), . filter = filter , }; // \u52a0\u8f7d seccomp \u8fc7\u6ee4\u5668 if ( prctl ( PR_SET_SECCOMP , SECCOMP_MODE_FILTER , & prog ) < 0 ) { perror ( \"prctl\" ); return 1 ; } // \u8c03\u7528 write \u7cfb\u7edf\u8c03\u7528 char buf [] = \"Hello, world!\" ; write ( 1 , buf , sizeof ( buf )); return 0 ; } \u4e0a\u8ff0\u4ee3\u7801\u521b\u5efa\u4e86\u4e00\u4e2a seccomp \u8fc7\u6ee4\u5668\uff0c\u4ec5\u5141\u8bb8\u8fdb\u7a0b\u8c03\u7528 write() \u7cfb\u7edf\u8c03\u7528\uff0c\u5176\u4ed6\u7cfb\u7edf\u8c03\u7528\u5747\u4f1a\u88ab\u7981\u6b62\u3002\u53ef\u4ee5\u901a\u8fc7\u7f16\u8bd1\u5e76\u8fd0\u884c\u4e0a\u8ff0\u4ee3\u7801\u6765\u6f14\u793a seccomp \u7b56\u7565\u7684\u4f5c\u7528\u3002 \u9700\u8981\u6ce8\u610f\u7684\u662f\uff0cseccomp \u7b56\u7565\u53ea\u80fd\u591f\u9650\u5236\u8fdb\u7a0b\u8fdb\u884c\u7684\u7cfb\u7edf\u8c03\u7528\uff0c\u4f46\u4e0d\u80fd\u591f\u9650\u5236\u7cfb\u7edf\u8c03\u7528\u7684\u53c2\u6570\u6216\u8fd4\u56de\u503c\u3002\u56e0\u6b64\uff0c\u4f7f\u7528 seccomp \u7b56\u7565\u65f6\u9700\u8981\u7279\u522b\u5c0f\u5fc3\uff0c\u907f\u514d\u8bef\u7528\u6216\u4ea7\u751f\u6f0f\u6d1e\u3002","title":"seccomp\u7b56\u7565"},{"location":"k8s/cka_cn/foundamentals/docker/#netlink","text":"Netlink \u662f\u4e00\u79cd Linux \u5185\u6838\u63d0\u4f9b\u7684\u901a\u4fe1\u673a\u5236\uff0c\u7528\u4e8e\u5185\u6838\u548c\u7528\u6237\u7a7a\u95f4\u8fdb\u7a0b\u4e4b\u95f4\u7684\u53cc\u5411\u901a\u4fe1\uff08IPC\uff09\u3002Netlink \u53ef\u4ee5\u7528\u4e8e\u8bb8\u591a\u76ee\u7684\uff0c\u4f8b\u5982\uff1a \u914d\u7f6e\u7f51\u7edc\u8bbe\u5907\u548c\u8def\u7531\u8868\uff1a\u4f7f\u7528 Netlink \u53ef\u4ee5\u901a\u8fc7\u7528\u6237\u7a7a\u95f4\u8fdb\u7a0b\u4fee\u6539\u5185\u6838\u7684\u7f51\u7edc\u8bbe\u5907\u548c\u8def\u7531\u8868\u914d\u7f6e\uff0c\u4f8b\u5982\u6dfb\u52a0\u3001\u5220\u9664\u3001\u4fee\u6539\u7f51\u7edc\u63a5\u53e3\u3001IP \u5730\u5740\u3001\u8def\u7531\u7b49\u3002 \u76d1\u89c6\u7f51\u7edc\u4e8b\u4ef6\uff1a\u4f7f\u7528 Netlink \u53ef\u4ee5\u5b9e\u65f6\u5730\u4ece\u5185\u6838\u83b7\u53d6\u7f51\u7edc\u4e8b\u4ef6\u7684\u901a\u77e5\uff0c\u4f8b\u5982\u7f51\u7edc\u63a5\u53e3\u7684\u72b6\u6001\u53d8\u5316\u3001\u8def\u7531\u7684\u53d8\u5316\u7b49\u3002 \u7a0b\u5e8f\u95f4\u901a\u4fe1\uff1a\u4f7f\u7528 Netlink \u53ef\u4ee5\u5728\u7528\u6237\u7a7a\u95f4\u8fdb\u7a0b\u4e4b\u95f4\u8fdb\u884c\u901a\u4fe1\uff0c\u7c7b\u4f3c\u4e8e Unix \u57df\u5957\u63a5\u5b57\u3002 Netlink \u673a\u5236\u57fa\u4e8e\u4e00\u79cd\u7279\u6b8a\u7684\u5957\u63a5\u5b57\u7c7b\u578b\uff08PF_NETLINK\uff09\u548c\u4e00\u4e2a\u7279\u5b9a\u7684\u534f\u8bae\uff08NETLINK\uff09\u3002\u7528\u6237\u7a7a\u95f4\u8fdb\u7a0b\u53ef\u4ee5\u901a\u8fc7\u521b\u5efa Netlink \u5957\u63a5\u5b57\u548c\u5185\u6838\u901a\u4fe1\u3002\u5185\u6838\u548c\u7528\u6237\u7a7a\u95f4\u8fdb\u7a0b\u4e4b\u95f4\u7684\u901a\u4fe1\u662f\u57fa\u4e8e Netlink \u6d88\u606f\u7684\uff0c\u6bcf\u4e2a Netlink \u6d88\u606f\u5305\u542b\u4e00\u4e2a\u6d88\u606f\u5934\u548c\u4e00\u4e2a\u8d1f\u8f7d\uff08payload\uff09\uff0c\u8d1f\u8f7d\u53ef\u4ee5\u662f\u4efb\u4f55\u7ed3\u6784\u4f53\u6216\u4e8c\u8fdb\u5236\u6570\u636e\u3002 Netlink \u6d88\u606f\u7684\u7c7b\u578b\u548c\u683c\u5f0f\u7531\u5185\u6838\u5b9a\u4e49\u3002\u7528\u6237\u7a7a\u95f4\u8fdb\u7a0b\u9700\u8981\u4e86\u89e3\u5185\u6838\u7684 Netlink \u6d88\u606f\u683c\u5f0f\u548c\u7c7b\u578b\uff0c\u624d\u80fd\u6b63\u786e\u5730\u6784\u9020\u548c\u89e3\u6790 Netlink \u6d88\u606f\u3002\u5e38\u7528\u7684 Netlink \u6d88\u606f\u7c7b\u578b\u5305\u62ec\uff1a RTM_NEWLINK \u548c RTM_DELLINK\uff1a\u6dfb\u52a0\u548c\u5220\u9664\u7f51\u7edc\u63a5\u53e3\u3002 RTM_NEWADDR \u548c RTM_DELADDR\uff1a\u6dfb\u52a0\u548c\u5220\u9664 IP \u5730\u5740\u3002 RTM_NEWROUTE \u548c RTM_DELROUTE\uff1a\u6dfb\u52a0\u548c\u5220\u9664\u8def\u7531\u3002 RTM_NEWNEIGH \u548c RTM_DELNEIGH\uff1a\u6dfb\u52a0\u548c\u5220\u9664 ARP \u8868\u9879\u3002 Netlink \u53ef\u4ee5\u4f7f\u7528 C \u8bed\u8a00\u7684 socket API \u8fdb\u884c\u7f16\u7a0b\u3002","title":"Netlink"},{"location":"k8s/cka_cn/foundamentals/docker/#netfilter","text":"Netfilter\u662fLinux\u5185\u6838\u4e2d\u7684\u4e00\u4e2a\u5b50\u7cfb\u7edf\uff0c\u7528\u4e8e\u5728\u6570\u636e\u5305\u4f20\u8f93\u8fc7\u7a0b\u4e2d\u8fdb\u884c\u8fc7\u6ee4\u548c\u64cd\u4f5c\u3002\u5b83\u652f\u6301\u5bf9\u7f51\u7edc\u6570\u636e\u5305\u8fdb\u884c\u5404\u79cd\u7c7b\u578b\u7684\u5904\u7406\uff0c\u5305\u62ec\u8fc7\u6ee4\u3001\u4fee\u6539\u3001\u91cd\u5b9a\u5411\u7b49\u3002Netfilter\u901a\u8fc7\u5728\u5185\u6838\u4e2d\u6ce8\u518c\u94a9\u5b50\u51fd\u6570\uff0c\u5728\u6570\u636e\u5305\u901a\u8fc7\u7f51\u7edc\u6808\u7684\u4e0d\u540c\u9636\u6bb5\u65f6\u8fdb\u884c\u62e6\u622a\u548c\u5904\u7406\u3002 Netfilter\u7684\u6838\u5fc3\u662fiptables\u547d\u4ee4\uff0c\u5b83\u53ef\u4ee5\u7528\u6765\u914d\u7f6eNetfilter\u89c4\u5219\u3002iptables\u547d\u4ee4\u53ef\u4ee5\u7528\u6765\u914d\u7f6e\u9632\u706b\u5899\u89c4\u5219\uff0cNAT\u89c4\u5219\uff0c\u9650\u5236\u8fde\u63a5\u901f\u5ea6\u7b49\u3002iptables\u547d\u4ee4\u901a\u8fc7\u5339\u914d\u4e0d\u540c\u7684\u6570\u636e\u5305\u5b57\u6bb5\uff08\u4f8b\u5982\u6e90IP\u5730\u5740\u3001\u76ee\u7684IP\u5730\u5740\u3001\u6e90\u7aef\u53e3\u3001\u76ee\u7684\u7aef\u53e3\u7b49\uff09\u6765\u8fdb\u884c\u8fc7\u6ee4\u3002 \u9664\u4e86iptables\u547d\u4ee4\uff0c\u8fd8\u6709\u5176\u4ed6\u4e00\u4e9b\u5de5\u5177\u53ef\u4ee5\u7528\u4e8e\u914d\u7f6eNetfilter\u89c4\u5219\uff0c\u4f8b\u5982nftables\u547d\u4ee4\u548cfirewalld\u670d\u52a1\u3002\u8fd9\u4e9b\u5de5\u5177\u63d0\u4f9b\u4e86\u66f4\u7075\u6d3b\u3001\u66f4\u5f3a\u5927\u7684\u914d\u7f6e\u9009\u9879\uff0c\u53ef\u4ee5\u5e2e\u52a9\u7ba1\u7406\u5458\u66f4\u597d\u5730\u7ba1\u7406\u548c\u4fdd\u62a4\u7f51\u7edc\u5b89\u5168\u3002 \u4e5f\u53ef\u4ee5\u7528\u4e8e\u5c06\u7f51\u7edc\u6570\u636e\u5305\u5b9a\u5411\u5230\u5355\u4e2a\u5bb9\u5668\u3002 \u66f4\u591a\u4fe1\u606f\u53ef\u4ee5\u53c2\u8003 LXC/LXD \u3002","title":"Netfilter"},{"location":"k8s/cka_cn/foundamentals/docker/#docker","text":"\u53c2\u8003 \u6307\u5bfc \u5b89\u88c5Docker\u5f15\u64ce\u3002 \u53c2\u8003 \u6307\u5bfc \u5b89\u88c5Docker\u684c\u9762\u7248\u3002 \u4e0b\u9762\u4ee5openSUSE\u4e3a\u4f8b\u5b89\u88c5Docker\u5f15\u64ce\u3002 sudo zypper in docker \u5728\u5b89\u88c5\u8fc7\u7a0b\u4e2d\uff0c\u5728\u64cd\u4f5c\u7cfb\u7edf\u4e2d\u4f1a\u81ea\u52a8\u521b\u5efa\u7ec4 docker \u3002 \u5c06vagrant\u7528\u6237\u52a0\u5165docker\u7ec4\uff0c\u5219vagrant\u7528\u6237\u53ef\u4ee5\u5728\u4e0b\u6b21\u767b\u5f55\u540e\u4e0e\u672c\u673a\u7684Docker\u5b88\u62a4\u8fdb\u7a0b\uff08daemon\uff09\u8fdb\u884c\u901a\u4fe1\u3002Docker\u5b88\u62a4\u8fdb\u7a0b\u76d1\u542c\u672c\u5730\u5957\u63a5\u5b57\uff0c\u53ea\u80fd\u7531root\u7528\u6237\u548cdocker\u7ec4\u7684\u6210\u5458\u8bbf\u95ee\u3002 sudo usermod -aG docker $USER \u542f\u7528\u5e76\u542f\u52a8 Docker \u5f15\u64ce\u3002 sudo systemctl enable docker.service sudo systemctl start docker.service sudo systemctl status docker.service \u4e0b\u9762\u901a\u8fc7\u4e00\u4e2a\u5bb9\u5668 alpine \u7684\u4f8b\u5b50\u6765\u6f14\u793a\u5728\u76ee\u5f55 /opt/test \u4e0b\u6a21\u62df\u5b9e\u73b0choot\u3002 mkdir test cd test wget https://dl-cdn.alpinelinux.org/alpine/v3.13/releases/x86_64/alpine-minirootfs-3.13.4-x86_64.tar.gz tar zxvf alpine-minirootfs-3.13.4-x86_64.tar.gz -C alpine-minirootfs/ \u67e5\u770b\u5f53\u524d\u76ee\u5f55\u7ed3\u6784\uff1a tree ./test -L 1 \u8f93\u51fa\u7ed3\u679c\uff1a ./test \u251c\u2500\u2500 alpine-minirootfs-3.13.4-x86_64.tar.gz \u251c\u2500\u2500 bin \u251c\u2500\u2500 dev \u251c\u2500\u2500 etc \u251c\u2500\u2500 home \u251c\u2500\u2500 lib \u251c\u2500\u2500 media \u251c\u2500\u2500 mnt \u251c\u2500\u2500 opt \u251c\u2500\u2500 proc \u251c\u2500\u2500 root \u251c\u2500\u2500 run \u251c\u2500\u2500 sbin \u251c\u2500\u2500 srv \u251c\u2500\u2500 sys \u251c\u2500\u2500 tmp \u251c\u2500\u2500 usr \u2514\u2500\u2500 var \u901a\u8fc7\u547d\u4ee4 unshare \u6302\u8f7d\u76ee\u5f55 /opt/test/proc \u5230\u67d0\u4e2a\u6587\u4ef6\u6765\u5b9e\u73b0\u5ba2\u6237\u5b50\u7cfb\u7edf\u3002 sudo mount -t tmpfs tmpfs /opt/test/proc sudo unshare --pid --mount-proc = $PWD /test/proc --fork chroot ./test/ /bin/sh / # ps -ef PID USER TIME COMMAND 1 root 0 :00 /bin/sh 2 root 0 :00 ps -ef / # touch 123 / # ls 123 123 \u6587\u4ef6 123 \u5728\u5ba2\u6237\u5b50\u7cfb\u7edf\u4e2d\u5df2\u521b\u5efa\uff0c\u5bf9\u5e94\u4e3b\u7cfb\u7edf\u4e2d\u4e5f\u53ef\u4ee5\u5bf9\u5176\u8fdb\u884c\u8bfb\u5199\u64cd\u4f5c\u3002\u6bd4\u5982\uff0c\u4fee\u6539\u6587\u4ef6 123 \u7684\u5185\u5bb9\u3002 su - ls 123 echo hello > 123 \u6587\u4ef6 123 \u4fee\u6539\u540e\u7684\u5185\u5bb9\u5728\u5ba2\u6237\u673a\u91cc\u9762\u4e5f\u53ef\u89c1\u3002 / # cat 123 hello \u5728\u4e3b\u7cfb\u7edf\u4e2d\u518d\u521b\u5efa\u4e24\u4e2a\u5b50\u76ee\u5f55 /opt/test-1 \u548c /opt/test-2 \u3002 mkdir test-1 mkdir test-2 \u521b\u5efa2\u4e2a\u5ba2\u6237\u5b50\u7cfb\u7edf\uff0c\u5e76\u5c06\u4e0a\u9762\u7684\u4e24\u4e2a\u5b50\u76ee\u5f55\u6302\u5728\u5230\u5404\u81ea\u7684 /opt/test/home/ \u76ee\u5f55\u3002 sudo mount --bind /opt/test-1 /opt/test/home/ sudo unshare --pid --mount-proc = $PWD /test/proc --fork chroot ./test/ /bin/sh / # cd /home /home # echo \"test-1\" > 123.1 /home # cat 123.1 test-1 sudo mount --bind /opt/test-2 /opt/test/home/ sudo unshare --pid --mount-proc = $PWD /test/proc --fork chroot ./test/ /bin/sh / # cd /home /home # echo \"test-2\" > 123.2 /home # cat 123.2 test-2 ll test/home ll test-1/ ll test-2/ \u901a\u8fc7\u4e0a\u9762\u7684\u6f14\u793a\uff0c\u53ef\u4ee5\u5f97\u51fa\u7ed3\u8bba\uff0c\u4e24\u4e2a\u5ba2\u6237\u5b50\u7cfb\u7edf\u6302\u5728\u5230\u540c\u4e00\u4e2a\u4e3b\u7cfb\u7edf\u76ee\u5f55\u65f6\uff0c\u5b50\u7cfb\u7edf\u65f6\u5171\u4eab\u4e3b\u7cfb\u7edf\u76ee\u5f55\uff0c\u5e76\u76f8\u4e92\u5f71\u54cd\u3002","title":"\u5b89\u88c5Docker"},{"location":"k8s/cka_cn/foundamentals/docker/#_6","text":"","title":"\u5bb9\u5668\u751f\u547d\u5468\u671f"},{"location":"k8s/cka_cn/foundamentals/docker/#_7","text":"\u9884\u5148\u4e0b\u8f7d\u4e0b\u5217\u955c\u50cf\u3002 docker image pull busybox docker image pull nginx docker image pull alpine docker image pull jenkins/jenkins:lts docker image pull golang:1.12-alpine docker image pull golang \u521b\u5efa\u5e76\u4ea4\u4e92\u5f0f\u8fd0\u884c\u4e00\u4e2a\u65b0\u7684busybox\u5bb9\u5668\uff0c\u5e76\u8fde\u63a5\u4e00\u4e2a\u4f2a\u7ec8\u7aef\uff08pseudo terminal\uff09\u3002 \u5728\u5bb9\u5668\u5185\uff0c\u4f7f\u7528 top \u547d\u4ee4\u67e5\u627e /bin/sh \u6b63\u5728\u4f5c\u4e3aPID\u4e3a1\u7684\u8fdb\u7a0b\u8fd0\u884c\uff0c\u4ee5\u53ca top \u8fdb\u7a0b\u4e5f\u5728\u8fd0\u884c\u3002 \u7136\u540e\uff0c\u9000\u51fa\u5bb9\u5668\u3002 docker image ls docker run -d -it --name busybox_v1 -v /opt/test:/docker busybox:latest /bin/sh docker container ps -a docker exec -it 185efe490507 /bin/sh / # top Mem: 3627396K used, 12731512K free, 10080K shrd, 2920K buff, 2999340K cached CPU: 0 .0% usr 0 .1% sys 0 .0% nic 99 .8% idle 0 .0% io 0 .0% irq 0 .0% sirq Load average: 0 .38 1 .09 1 .29 2 /277 14 PID PPID USER STAT VSZ %VSZ CPU %CPU COMMAND 1 0 root S 1332 0 .0 1 0 .0 /bin/sh 8 0 root S 1332 0 .0 2 0 .0 /bin/sh 14 8 root R 1328 0 .0 1 0 .0 top / # exitbuild \u542f\u52a8\u4e00\u4e2a\u65b0\u7684 Nginx \u5bb9\u5668\uff0c\u5e76\u4ee5\u72ec\u7acb\u6a21\u5f0f\uff08detached mode\uff09\u8fd0\u884c\u3002 \u4f7f\u7528 docker exec \u547d\u4ee4\u5728 Nginx \u5bb9\u5668\u4e2d\u542f\u52a8\u53e6\u4e00\u4e2a shell\uff08 /bin/sh \uff09\u3002 \u4f7f\u7528 ps \u547d\u4ee4\u67e5\u770b\u5bb9\u5668\u4e2d\u6b63\u5728\u8fd0\u884c\u7684 sh \u548c ps \u547d\u4ee4\uff08\u5728\u4e0a\u4e00\u6b65\u6267\u884c\u7684\uff09\u3002 docker run -d -it --name nginx_v1 -v /opt/test:/docker nginx:latest /bin/sh docker container ps -a docker exec -it edb640127a0d /bin/sh # ps /bin/sh: 2 : ps: not found # apt-get update && apt-get install -y procps # ps PID TTY TIME CMD 8 pts/1 00 :00:00 sh 351 pts/1 00 :00:00 ps # exit \u901a\u8fc7\u4e0b\u9762\u547d\u4ee4\u53ef\u4ee5\u770b\u52302\u4e2a\u73b0\u5728\u8fd0\u884c\u4e2d\u7684\u5bb9\u5668\u3002 docker container ps -a \u4f7f\u7528 docker logs \u547d\u4ee4\u663e\u793a\u6211\u4eec\u521a\u521a\u9000\u51fa\u7684\u5bb9\u5668\u7684\u65e5\u5fd7\u3002\u9009\u9879 --since 35m \u8868\u793a\u663e\u793a\u6700\u8fd1 35 \u5206\u949f\u5185\u7684\u65e5\u5fd7\u3002 docker logs nginx_v1 --details --since 35m docker logs busybox_v1 --details --since 35m \u4f7f\u7528 docker stop \u547d\u4ee4\u6765\u505c\u6b62 nginx \u5bb9\u5668\u3002 docker stop busybox_v1 docker stop nginx_v1 docker container ps -a \u4f7f\u7528\u4e0a\u8ff0\u547d\u4ee4 docker container ps -a \uff0c\u6211\u4eec\u53ef\u4ee5\u83b7\u53d6\u6240\u6709\u6b63\u5728\u8fd0\u884c\u548c\u5df2\u9000\u51fa\u7684\u5bb9\u5668\u5217\u8868\u3002\u4f7f\u7528 docker rm \u5c06\u5176\u5220\u9664\u3002\u4f7f\u7528 docker rm $(docker ps -aq) \u6765\u6e05\u7406\u4e3b\u673a\u4e0a\u7684\u6240\u6709\u5bb9\u5668\u3002\u8bf7\u8c28\u614e\u4f7f\u7528\uff01 docker rm busybox_v1 docker container ps -a","title":"\u6982\u8ff0"},{"location":"k8s/cka_cn/foundamentals/docker/#_8","text":"\u73b0\u5728\u542f\u52a8\u4e00\u4e2a\u65b0\u7684 nginx \u5bb9\u5668\uff0c\u5e76\u5c06 nginx web \u670d\u52a1\u5668\u7684\u7aef\u53e3\u5bfc\u51fa\u5230 Docker \u968f\u673a\u9009\u62e9\u7684\u7aef\u53e3\u3002 \u6211\u4eec\u53ef\u4ee5\u4f7f\u7528\u547d\u4ee4 docker ps \u627e\u51fa web \u670d\u52a1\u5668\u8f6c\u53d1\u5230\u4e86\u54ea\u4e2a\u7aef\u53e3\u3002\u5728\u4e3b\u673a\u4e0a\u4f7f\u7528\u8f6c\u53d1\u7684\u7aef\u53e3\u53f7\u8bbf\u95ee docker http://localhost: \u3002 docker container ps -a docker run -d -P --name nginx_v2 nginx:latest docker container ps -a Start another nginx container and expose port to 1080 on host as an example via http://localhost:1080 . \u542f\u52a8\u53e6\u4e00\u4e2anginx\u5bb9\u5668\uff0c\u5c06\u5176\u7aef\u53e3\u6620\u5c04\u5230\u4e3b\u673a\u76841080\u7aef\u53e3\uff0c\u53ef\u4ee5\u901a\u8fc7 http://localhost:1080 \u8bbf\u95ee\u3002 docker run -d -p 1080 :80 --name nginx_v3 nginx:latest docker container ps -a \u4f7f\u7528 docker inspect \u547d\u4ee4\u67e5\u627e\u955c\u50cf\u66b4\u9732\u7684\u7aef\u53e3\u53f7\uff0c\u8f93\u51faJSON\u683c\u5f0f\u6587\u4ef6\uff0c\u7f51\u7edc\u4fe1\u606f\uff08IP\u3001\u7f51\u5173\u3001\u7aef\u53e3\u7b49\uff09\u662f\u8f93\u51faJSON\u683c\u5f0f\u7684\u4e00\u90e8\u5206\u3002 docker inspect nginx_v3 \u5728\u76ee\u5f55 /opt/test \u4e2d\u521b\u5efa\u4e00\u4e2a\u540d\u4e3a index.html \u7684\u6587\u4ef6\uff0c\u5176\u5185\u5bb9\u5982\u4e0b\uff1a < html > < head > < title > Sample Website from my container < body > < h1 > This is a custom website. < p > This website is served from my < a href = \"http://www.docker.com\" target = \"_blank\" > Docker container. \u542f\u52a8\u4e00\u4e2a\u65b0\u5bb9\u5668\uff0c\u5c06\u4e3b\u673a\u76ee\u5f55 /opt/test \u4e0e\u5bb9\u5668\u76ee\u5f55 /usr/share/nginx/html \u7ed1\u5b9a\u6302\u8f7d\u4e3a\u4e00\u4e2a\u5377\uff0c\u4ee5\u4fbfNginx\u53ef\u4ee5\u901a\u8fc7 http://localhost:49159/ \u53d1\u5e03\u6211\u4eec\u521a\u521b\u5efa\u7684html\u6587\u4ef6\uff0c\u800c\u4e0d\u662fNginx\u9ed8\u8ba4\u7684\u9875\u9762\u3002 docker run -d -P --mount type = bind,source = /opt/test/,target = /usr/share/nginx/html --name nginx_v3-1 nginx:latest docker container ps -a \u68c0\u67e5Nginx\u914d\u7f6e\u6587\u4ef6\uff0c\u67e5\u770b\u5bb9\u5668\u4e2dhtml\u4e3b\u9875\u5b58\u50a8\u7684\u4f4d\u7f6e\u3002 docker exec -it nginx_v3-1 /bin/sh # cd /etc/nginx/conf.d # ls default.conf # cat default.conf server { listen 80 ; listen [ :: ] :80 ; server_name localhost ; #access_log /var/log/nginx/host.access.log main; location / { root /usr/share/nginx/html ; <-- index index.html index.htm ; } #error_page 404 /404.html; # redirect server error pages to the static page /50x.html # error_page 500 502 503 504 /50x.html ; location = /50x.html { root /usr/share/nginx/html ; } # proxy the PHP scripts to Apache listening on 127.0.0.1:80 # #location ~ \\.php$ { # proxy_pass http://127.0.0.1; #} # pass the PHP scripts to FastCGI server listening on 127.0.0.1:9000 # #location ~ \\.php$ { # root html; # fastcgi_pass 127.0.0.1:9000; # fastcgi_index index.php; # fastcgi_param SCRIPT_FILENAME /scripts$fastcgi_script_name; # include fastcgi_params; #} # deny access to .htaccess files, if Apache's document root # concurs with nginx's one # #location ~ /\\.ht { # deny all; #} } # cd /usr/share/nginx/html # cat index.html Sample Website from my container

This is a custom website.

This website is served from my Docker container.

# \u63a8\u8350\u4f7f\u7528\u5377 API \u6765\u5b9e\u73b0\u6570\u636e\u6301\u4e45\u5316\uff0c\u800c\u4e0d\u662f\u5c06\u6570\u636e\u5b58\u50a8\u5728 Docker \u5bb9\u5668\u4e2d\u3002Docker \u652f\u6301\u4e24\u79cd\u6302\u8f7d\u65b9\u5f0f\uff1a \u7ed1\u5b9a\u6302\u8f7d\uff08Bind mounts\uff09\uff1a \u5c06\u672c\u5730\u4e3b\u673a\u76ee\u5f55\u6302\u8f7d\u5230\u5bb9\u5668\u4e2d\u7684\u67d0\u4e2a\u8def\u5f84\u3002 \u6302\u8f7d\u540e\uff0c\u76ee\u6807\u76ee\u5f55\u4e2d\u539f\u6709\u7684\u6240\u6709\u5185\u5bb9\u5c06\u88ab\u9690\u85cf\u3002 \u4f8b\u5982\uff0c\u5982\u679c\u6211\u4eec\u60f3\u8981\u6ce8\u5165\u67d0\u4e9b\u914d\u7f6e\u6587\u4ef6\uff0c\u6211\u4eec\u9700\u8981\u81ea\u5df1\u5199\u5bf9\u5e94\u7684\u914d\u7f6e\u6587\u4ef6\uff0c\u5c06\u5176\u5b58\u50a8\u5728 Docker \u4e3b\u673a\u4e0a\u7684 /home/container/config \u8def\u5f84\u4e0b\uff0c\u5e76\u5c06\u6b64\u76ee\u5f55\u7684\u5185\u5bb9\u6302\u8f7d\u5230 /usr/application/config \uff08\u5047\u8bbe\u5e94\u7528\u7a0b\u5e8f\u4ece\u6b64\u5904\u8bfb\u53d6\u914d\u7f6e\uff09\u3002 \u547d\u4ee4\uff1a docker run --mount type=bind,source=,target= \u2026 \u547d\u540d\u5377\uff08Named volumes\uff09\uff1a Docker \u53ef\u4ee5\u521b\u5efa\u4e00\u4e2a\u72ec\u7acb\u7684\u5b58\u50a8\u5377\uff0c\u5176\u751f\u547d\u5468\u671f\u72ec\u7acb\u4e8e\u5bb9\u5668\u4f46\u4ecd\u7531 Docker \u7ba1\u7406\u3002 \u5728\u521b\u5efa\u65f6\uff0c\u6302\u8f7d\u76ee\u6807\u7684\u5185\u5bb9\u5c06\u5408\u5e76\u5230\u5377\u4e2d\u3002 \u547d\u4ee4\uff1a docker run --mount source=,target= \u2026 \u5982\u4f55\u533a\u5206\u7ed1\u5b9a\u6302\u8f7d\u548c\u547d\u540d\u5377\uff1f \u5f53\u6307\u5b9a\u7edd\u5bf9\u8def\u5f84\u65f6\uff0cDocker \u4f1a\u8ba4\u4e3a\u8fd9\u662f\u4e00\u4e2a\u7ed1\u5b9a\u6302\u8f7d\u3002 \u5f53\u6211\u4eec\u4ec5\u63d0\u4f9b\u540d\u79f0\uff08\u5982\u76f8\u5bf9\u8def\u5f84 config \uff09\u65f6\uff0c\u5b83\u4f1a\u8ba4\u4e3a\u8fd9\u662f\u4e00\u4e2a\u547d\u540d\u5377\uff0c\u5e76\u521b\u5efa\u4e00\u4e2a\u540d\u4e3a config \u7684\u5377\u3002 \u6ce8\uff1a\u6301\u4e45\u5b58\u50a8\u7531\u4e3b\u673a\u63d0\u4f9b\uff0c\u53ef\u4ee5\u76f4\u63a5\u662f\u4e3b\u673a\u6587\u4ef6\u7cfb\u7edf\u7684\u4e00\u90e8\u5206\uff0c\u4e5f\u53ef\u4ee5\u662f NFS \u6302\u8f7d\u3002","title":"\u7aef\u53e3\u548c\u5377"},{"location":"k8s/cka_cn/foundamentals/docker/#dockerfile","text":"\u8ba9\u6211\u4eec\u7528 Dockerfile \u6784\u5efa\u4e00\u4e2a\u955c\u50cf\uff0c\u5bf9\u5176\u8fdb\u884c\u6253\u6807\u7b7e\u5e76\u4e0a\u4f20\u5230\u955c\u50cf\u4ed3\u5e93\u3002 \u83b7\u53d6 Docker \u955c\u50cf\u7684\u6784\u5efa\u5386\u53f2\u8bb0\u5f55\u3002 docker image history nginx:latest \u521b\u5efa\u4e00\u4e2a\u7a7a\u7684\u76ee\u5f55 /opt/tmp-1 \uff0c\u8fdb\u5165\u8be5\u76ee\u5f55\u5e76\u5728\u5176\u4e2d\u521b\u5efa index.html \u6587\u4ef6\u3002 /opt/tmp-1> cat index.html Sample Website from my container

This is a custom website.

This website is served from my Docker container.

\u4f7f\u7528 FROM \u6765\u6269\u5c55\u4e00\u4e2a\u5df2\u6709\u7684\u955c\u50cf\uff0c\u5e76\u6307\u5b9a\u7248\u672c\u53f7\u3002 \u4f7f\u7528 COPY \u5c06\u4e00\u4e2a\u65b0\u7684\u9ed8\u8ba4\u7f51\u7ad9\u590d\u5236\u5230\u955c\u50cf\u4e2d\uff0c\u4f8b\u5982 /usr/share/nginx/html \u3002 \u4e3aNginx\u521b\u5efaSSL\u914d\u7f6e /opt/tmp-1/ssl.conf \u3002 server { listen 443 ssl; server_name localhost; ssl_certificate /etc/nginx/ssl/nginx.crt; ssl_certificate_key /etc/nginx/ssl/nginx.key; location / { root /usr/share/nginx/html; index index.html index.htm; } } \u4f7f\u7528OpenSSL\u521b\u5efa\u4e00\u4e2a\u81ea\u7b7e\u540d\u8bc1\u4e66\uff0c\u4ee5\u4fbfSSL/TLS\u5de5\u4f5c\u3002 \u4f7f\u7528\u4ee5\u4e0b\u547d\u4ee4\u521b\u5efa\u4e00\u4e2a\u52a0\u5bc6\u5bc6\u94a5\u548c\u8bc1\u4e66\u3002 openssl req -x509 -nodes -newkey rsa:4096 -keyout nginx.key -out nginx.crt -days 365 -subj \"/CN= $( hostname ) \" \u4e3a\u4e86\u542f\u7528\u52a0\u5bc6\u7684HTTPS\uff0c\u6211\u4eec\u9700\u8981\u4f7f\u7528 EXPOSE \u6307\u4ee4\u516c\u5f00 443 \u7aef\u53e3\u3002\u9ed8\u8ba4\u7684nginx\u955c\u50cf\u4ec5\u516c\u5f00\u7aef\u53e3 80 \uff0c\u7528\u4e8e\u975e\u52a0\u5bc6\u7684HTTP\u3002 \u5728 /opt/tmp-1 \u6587\u4ef6\u5939\u4e2d\u521b\u5efa\u4ee5\u4e0bDockerfile\u3002 cat Dockerfile \u8f93\u51fa\uff1a FROM nginx:latest # copy the custom website into the image COPY index.html /usr/share/nginx/html # copy the SSL configuration file into the image COPY ssl.conf /etc/nginx/conf.d/ssl.conf # download the SSL key and certificate into the image COPY nginx.key /etc/nginx/ssl/ COPY nginx.crt /etc/nginx/ssl/ # expose the HTTPS port EXPOSE 443 \u81f3\u6b64\uff0c\u6211\u4eec\u5728\u76ee\u5f55 /opt/tmp-1 \u4e0b\u67095\u4e2a\u6587\u4ef6\u3002 ls /opt/tmp-1 \u8f93\u51fa\uff1a Dockerfile index.html nginx.crt nginx.key ssl.conf \u4f7f\u7528 docker build \u547d\u4ee4\u6765\u6784\u5efa\u955c\u50cf\uff0c\u5e76\u5c06\u5bb9\u5668\u768480\u548c443\u7aef\u53e3\u8f6c\u53d1\u3002 docker build -t nginx:my1 /opt/tmp-1/ docker image ls docker run -d -p 1086 :80 -p 1088 :443 --name nginx_v5 nginx:my1 docker container ps -a \u901a\u8fc7\u4e0b\u9762\u4e24\u4e2a\u94fe\u63a5\u6765\u9a8c\u8bc1\u4e0a\u9762\u7684\u53d8\u5316\u662f\u5426\u751f\u6548\u3002 http://localhost:1086/ https://localhost:1088/ \u5728 DockerHub \u6ce8\u518c\u4e00\u4e2a\u4e2a\u4eba\u8d26\u53f7\uff0c\u542f\u7528 Docker Hub \u4e2d\u7684\u8bbf\u95ee\u4ee4\u724c\u4ee5\u8fdb\u884c CLI \u5ba2\u6237\u7aef\u8eab\u4efd\u9a8c\u8bc1\u3002 docker login \u8f93\u5165\u7528\u6237\u540d\u548c\u5bc6\u7801\u3002 Username: Password: \u7ed9\u8fd9\u4e2a\u955c\u50cf\u52a0\u4e0a\u4e00\u4e2a\u6807\u7b7e\uff0c\u4f8b\u5982\uff1asecure_nginx_0001\uff0c\u7248\u672c\u53f7\u4e3a v1\u3002 docker tag nginx:my1 secure_nginx_0001:v1 docker push secure_nginx_0001:v1 docker image ls","title":"Dockerfile"},{"location":"k8s/cka_cn/foundamentals/docker/#dockerfile_1","text":"\u4e0b\u9762\u7684\u4f8b\u5b50\u662f\u6f14\u793a\u4e00\u4e2a\u591a\u9636\u6bb5\uff08Multi-stage\uff09\u6784\u5efa\u7684\u4f8b\u5b50\u3002\u5728Docker\u7684\u4e0a\u4e0b\u6587\u4e2d\uff0c\u591a\u9636\u6bb5\uff08Multi-stage\uff09\u610f\u5473\u7740\u6211\u4eec\u53ef\u4ee5\u6709\u591a\u4e2a\u5e26\u6709 FROM \u5173\u952e\u5b57\u7684\u884c\u3002 \u521b\u5efa\u6587\u4ef6\u5939 /opt/tmp-2 \u548c /opt/tmp-2/tmpl \u3002\u521b\u5efa\u6587\u4ef6 edit.html \uff0c view.html \uff0c wiki.go \u3002 \u6587\u4ef6\u7ed3\u6784\u5982\u4e0b\uff1a tree -l /opt/tmp-2 \u8f93\u51fa\u7ed3\u679c\uff1a . \u251c\u2500\u2500 tmpl \u2502 \u251c\u2500\u2500 edit.html \u2502 \u2514\u2500\u2500 view.html \u2514\u2500\u2500 wiki.go \u521b\u5efa\u4e00\u4e2a\u65b0\u7684Dockerfile\u3002 cat Dockerfile \u6587\u4ef6\u5185\u5bb9\uff1a # app builder stage FROM golang:1.12-alpine as builder # # copy the go source code over and build the binary WORKDIR /go/src COPY wiki.go /go/src/wiki.go RUN go build wiki.go # app exec stage # separate & new image starts here!# FROM alpine:3.9 # prepare file system etc RUN mkdir -p /app/data /app/tmpl && adduser -S -D -H -h /app appuser COPY tmpl/* /app/tmpl/ # get the compiled binary from the previous stage COPY --from=builder /go/src/wiki /app/wiki # prepare runtime env RUN chown -R appuser /app USER appuser WORKDIR /app # expose app port & set default command EXPOSE 8080 CMD [\"/app/wiki\"] \u7528\u4e0a\u4e00\u6b65\u521b\u5efa\u7684Dockerfile\u6765\u521b\u5efa\u65b0\u666f\u8c61\u3002 docker build -t lizard/golang:my1 /opt/tmp-2/ \u4ee5\u72ec\u7acb\u6a21\u5f0f\uff08detached\uff09\u8fd0\u884c\u8fd9\u4e2a\u955c\u50cf\uff0c\u5e76\u5c06\u5bb9\u5668\u7aef\u53e3 8080 \u8f6c\u53d1\u5230\u4e3b\u673a\u7aef\u53e3 1090 \u3002 docker run -d -p 1090 :8080 --name golan_v1 lizard/golang:my1 \u901a\u8fc7\u94fe\u63a5 http://localhost:1090 \u8bbf\u95ee\u8fd9\u4e2a\u8fd0\u884c\u7684\u5bb9\u5668\u3002 \u5bf9\u6211\u4eec\u521a\u521a\u521b\u5efa\u7684\u65b0\u7684golang\u955c\u50cf\u8fdb\u884c\u6807\u7b7e\uff0c\u5e76\u4e14\u4e0a\u4f20\u5230Dockerhub\u3002 docker tag lizard/golang:my1 /golang_0001:v1 docker push /golang_0001:v1","title":"\u591a\u9636\u6bb5Dockerfile"},{"location":"k8s/cka_cn/foundamentals/healthcheck/","text":"CKA\u81ea\u5b66\u7b14\u8bb026:\u5065\u5eb7\u68c0\u67e5 \u00b6 Pod\u548cContainer\u7684\u72b6\u6001 \u00b6 \u6f14\u793a\u573a\u666f\uff1a \u521b\u5efa\u4e00\u4e2a\u67092\u4e2a\u5bb9\u5668\u7684pod\u3002 \u6f14\u793a\uff1a \u521b\u5efa\u4e00\u4e2a\u5305\u542b\u4e24\u4e2a\u5bb9\u5668 nginx \u548c busybox \u7684 Pod\uff0c\u547d\u540d\u4e3a multi-pods \u3002 kubectl apply -f - << EOF apiVersion: v1 kind: Pod metadata: labels: run: multi-pods name: multi-pods spec: containers: - image: nginx name: nginx - image: busybox name: busybox dnsPolicy: ClusterFirst restartPolicy: Always EOF \u6267\u884c\u4e0b\u9762\u547d\u4ee4\u6765\u76d1\u63a7\u72b6\u6001\uff0c\u4f7f\u7528\u9009\u9879 --watch \u3002 \u6ce8\u610f\uff0cpod\u7684\u72b6\u6001\u5df2\u7ecf\u4ece ContainerCreating \u53d8\u4e3a NotReady \uff0c\u518d\u53d8\u4e3a CrashLoopBackOff \u3002 kubectl get pod multi-pods --watch \u83b7\u53d6 Pod multi-pods \u7684\u8be6\u7ec6\u4fe1\u606f\uff0c\u5173\u6ce8 Containers \u90e8\u5206\u4e0b\u7684\u5bb9\u5668\u72b6\u6001\u548c Conditions \u90e8\u5206\u4e0b\u7684 Pod \u72b6\u6001\u3002 kubectl describe pod multi-pods \u8fd0\u884c\u7ed3\u679c\uff08\u90e8\u5206\uff09\uff1a ...... Containers : nginx : ...... State : Running Started : Sat, 23 Jul 2022 15:06:56 +0800 Ready : True Restart Count : 0 ...... busybox : ...... State : Terminated Reason : Completed Exit Code : 0 ...... Conditions : Type Status Initialized True Ready False ContainersReady False PodScheduled True ...... LivenessProbe \u00b6 \u6f14\u793a\u573a\u666f\uff1a \u521b\u5efa\u4e00\u4e2apod\uff0c\u5185\u542b livenessProbe \u68c0\u67e5\u3002 \u6f14\u793a\u7684\u8be6\u7ec6\u8bf4\u660e\u53ef\u4ee5\u67e5\u8be2 Kubernetes document \u3002 \u6f14\u793a\uff1a \u521b\u5efayaml\u6587\u4ef6 liveness.yaml \uff0c\u5e76\u5305\u542b livenessProbe \u914d\u7f6e\uff0c\u5e76\u5e94\u7528\u4e4b\u3002 kubectl apply -f - <> ~/.bashrc source < ( helm completion bash ) \u901a\u8fc7Helm\u5b89\u88c5MySQL \u00b6 \u6dfb\u52a0Bitnami Chartes\u4ed3\u5e93\u3002 helm repo add bitnami https://charts.bitnami.com/bitnami \u67e5\u8be2\u5f53\u524d\u53ef\u7528\u7684Chartes\u4ed3\u5e93\u3002 helm repo list \u8fd0\u884c\u7ed3\u679c\uff1a NAME URL bitnami https://charts.bitnami.com/bitnami \u540c\u6b65\u672c\u5730Charts\u4ed3\u5e93\u3002 helm repo update \u5728Charts\u4ed3\u5e93\u4e2d\u67e5\u627ebitnami Charts\u4ed3\u5e93\u3002 helm search repo bitnami \u5728\u4ed3\u5e93\u4e2d\u641c\u7d22bitnami/mysql Charts\u3002 helm search repo bitnami/mysql \u5728namespace dev \u4e0a\u5b89\u88c5MySQL Chart\u3002 helm install mysql bitnami/mysql -n dev \u8fd0\u884c\u7ed3\u679c\uff1a NAME: mysql LAST DEPLOYED: Sun Jul 24 19:37:20 2022 NAMESPACE: dev STATUS: deployed REVISION: 1 TEST SUITE: None NOTES: CHART NAME: mysql CHART VERSION: 9.2.1 APP VERSION: 8.0.29 ** Please be patient while the chart is being deployed ** Tip: Watch the deployment status using the command: kubectl get pods -w --namespace dev Services: echo Primary: mysql.dev.svc.cluster.local:3306 Execute the following to get the administrator credentials: echo Username: root MYSQL_ROOT_PASSWORD=$(kubectl get secret --namespace dev mysql -o jsonpath=\"{.data.mysql-root-password}\" | base64 -d) To connect to your database: 1. Run a pod that you can use as a client: kubectl run mysql-client --rm --tty -i --restart='Never' --image docker.io/bitnami/mysql:8.0.29-debian-11-r9 --namespace dev --env MYSQL_ROOT_PASSWORD=$MYSQL_ROOT_PASSWORD --command -- bash 2. To connect to primary service (read/write): mysql -h mysql.dev.svc.cluster.local -uroot -p\"$MYSQL_ROOT_PASSWORD\" \u67e5\u770b\u5f53\u524d\u5b89\u88c5\u5305\u7684\u4fe1\u606f\u3002 helm list \u8fd0\u884c\u7ed3\u679c\uff1a NAME NAMESPACE REVISION UPDATED STATUS CHART APP VERSION mysql dev 1 2022-07-24 19:37:20.710988009 +0800 CST deployed mysql-9.2.1 8.0.29 \u68c0\u67e5\u5f53\u524d\u5b89\u88c5\u7684mysql\u7248\u672c\u4fe1\u606f\u3002 helm status mysql \u68c0\u67e5pod mysql \u7684\u72b6\u6001\u3002 kubectl get pod \u8fd0\u884c\u7ed3\u679c\uff1a NAME READY STATUS RESTARTS AGE mysql-0 1/1 Running 0 72s \u90e8\u7f72\u4e00\u4e2aChart \u00b6 \u4e0b\u9762\u6f14\u793a\u4e86\u5982\u4f55\u90e8\u7f72\u4e00\u4e2aChart\u3002 \u6267\u884c\u547d\u4ee4 helm create \u6765\u521d\u59cb\u5316\u4e00\u4e2aChart\u3002 # Naming conventions of Chart: lowercase a~z and -(minus sign) helm create cka-demo \u76ee\u5f55 cka-demo \u4f1a\u88ab\u521b\u5efa\uff0c\u67e5\u770b\u8fd9\u4e2a\u76ee\u5f55\u7684\u7ed3\u6784\u3002 tree cka-demo/ \u8fd0\u884c\u7ed3\u679c\uff1a cka-demo/ \u251c\u2500\u2500 charts \u251c\u2500\u2500 Chart.yaml \u251c\u2500\u2500 templates \u2502 \u251c\u2500\u2500 deployment.yaml \u2502 \u251c\u2500\u2500 _helpers.tpl \u2502 \u251c\u2500\u2500 hpa.yaml \u2502 \u251c\u2500\u2500 ingress.yaml \u2502 \u251c\u2500\u2500 NOTES.txt \u2502 \u251c\u2500\u2500 serviceaccount.yaml \u2502 \u251c\u2500\u2500 service.yaml \u2502 \u2514\u2500\u2500 tests \u2502 \u2514\u2500\u2500 test-connection.yaml \u2514\u2500\u2500 values.yaml \u5220\u9664\u6216\u6e05\u7a7a\u67d0\u4e9b\u6587\u4ef6\uff0c\u6211\u4eec\u4f1a\u5728\u540e\u9762\u91cd\u65b0\u521b\u5efa\u8fd9\u4e9b\u6587\u4ef6\u3002 cd cka-demo rm -rf charts rm -rf templates/tests rm -rf templates/*.yaml echo \"\" > values.yaml echo \"\" > templates/NOTES.txt echo \"\" > templates/_helpers.tpl cd .. \u76ee\u5f55 cka-demo \u7684\u67b6\u6784\u73b0\u5728\u5e94\u8be5\u770b\u8d77\u6765\u7c7b\u4f3c\u4e0b\u9762\u7684\u7ed3\u679c\u3002 tree cka-demo/ \u8fd0\u884c\u7ed3\u679c\uff1a cka-demo/ \u251c\u2500\u2500 Chart.yaml \u251c\u2500\u2500 templates \u2502 \u251c\u2500\u2500 _helpers.tpl \u2502 \u2514\u2500\u2500 NOTES.txt \u2514\u2500\u2500 values.yaml NOTES.txt \u00b6 NOTES.txt \u7528\u4e8e\u5411 Chart \u7528\u6237\u63d0\u4f9b\u6982\u8981\u4fe1\u606f\u3002\u5728\u6f14\u793a\u4e2d\uff0c\u6211\u4eec\u5c06\u4f7f\u7528 NOTES.txt \u63d0\u4f9b\u5173\u4e8e\u7528\u6237\u662f\u5426\u901a\u8fc7 CKA \u8ba4\u8bc1\u7684\u6982\u8981\u4fe1\u606f\u3002 cd cka-demo/ vi templates/NOTES.txt \u6dfb\u52a0\u4e0b\u9762\u7684\u5185\u5bb9\u3002 {{- if .Values.passExam }} Congratulations! You have successfully completed Certified Kubernetes Administrator China Exam (CKA-CN). Your CKA score is: {{ .Values.ckaScore }} Click the link below to view and download your certificate. https://trainingportal.linuxfoundation.org/learn/dashboard {{- else }} Come on! you can do it next time! {{- end }} \u90e8\u7f72\u6a21\u7248 \u00b6 \u4e0b\u9762\u4f1a\u4f7f\u7528 Busybox \u670d\u52a1\u6765\u751f\u6210\u4fe1\u606f\u3002 \u901a\u8fc7\u547d\u4ee4 kubectl create deployment --dry-run=client -oyaml \u751f\u6210 Deployment \u7684 YAML \u6587\u4ef6\uff0c\u5e76\u5c06\u5176\u5185\u5bb9\u5199\u5165\u6587\u4ef6 templates/deployment.yaml \u3002 kubectl create deployment cka-demo-busybox --image = busybox:latest --dry-run = client -oyaml > templates/deployment.yaml \u68c0\u67e5deployment\u7684yaml\u6587\u4ef6 templates/deployment.yaml \u7684\u5185\u5bb9\u3002 cat templates/deployment.yaml \u8fd0\u884c\u7ed3\u679c\uff1a apiVersion : apps/v1 kind : Deployment metadata : creationTimestamp : null labels : app : cka-demo-busybox name : cka-demo-busybox spec : replicas : 1 selector : matchLabels : app : cka-demo-busybox strategy : {} template : metadata : creationTimestamp : null labels : app : cka-demo-busybox spec : containers : - image : busybox:latest name : busybox resources : {} status : {} \u7f16\u8f91\u4fee\u6539\u6587\u4ef6 templates/deployment.yaml \u3002 vi templates/deployment.yaml \u8ba9\u6211\u4eec\u5c06 .spec.replicas \u7684\u503c\u4ece 1 \u66ff\u6362\u4e3a\u53d8\u91cf {{ .Values.replicaCount }} \uff0c\u8fd9\u6837\u6211\u4eec\u53ef\u4ee5\u4e3a\u5176\u4ed6 Deployment \u52a8\u6001\u5206\u914d\u526f\u672c\u6570\u3002 apiVersion : apps/v1 kind : Deployment metadata : creationTimestamp : null labels : app : cka-demo-busybox name : cka-demo-busybox spec : replicas : {{ .Values.replicaCount }} selector : matchLabels : app : cka-demo-busybox strategy : {} template : metadata : creationTimestamp : null labels : app : cka-demo-busybox spec : containers : - image : busybox:latest name : busybox resources : {} status : {} .spec.replicas \u5c06\u5728\u90e8\u7f72\u671f\u95f4\u88ab\u5b9e\u9645\u7684 .Values.replicaCount \u503c\u66ff\u6362\u3002 \u73b0\u5728\u521b\u5efa\u53e6\u4e00\u4e2a\u6587\u4ef6 values.yaml \u5e76\u5728\u6587\u4ef6\u4e2d\u6dfb\u52a0\u4e00\u4e2a\u53d8\u91cf replicaCount \uff0c\u9ed8\u8ba4\u503c\u4e3a1\u3002 \u5f3a\u70c8\u5efa\u8bae\u5728\u6587\u4ef6 values.yaml \u4e2d\u5b9a\u4e49\u7684\u6bcf\u4e2a\u503c\u6dfb\u52a0\u6ce8\u91ca\u3002 vi values.yaml \u8f93\u51fa\u7ed3\u679c\uff1a # Number of deployment replicas replicaCount: 1 \u4e0b\u9762\u5bf9\u6587\u4ef6 templates/deployment.yaml \u6dfb\u52a0\u66f4\u591a\u7684\u53d8\u91cf\u3002 \u5c06 .metadata.name \u7684 Release \u540d\u79f0\u66ff\u6362\u4e3a {{ .Release.Name }} \uff0c\u5e76\u7528\u5728 values.yaml \u6587\u4ef6\u4e2d\u5b9a\u4e49\u7684\u53d8\u91cf\u586b\u5145\u3002 \u5c06\u6807\u7b7e\u540d\u79f0 .metadata.labels \u66ff\u6362\u4e3a {{- include \"cka-demo.labels\" . | nindent 4 }} \uff0c\u5e76\u7528\u5728 _helpers.tpl \u6587\u4ef6\u4e2d\u5b9a\u4e49\u7684\u6807\u7b7e\u540d\u79f0 cka-demo.labels \u586b\u5145\u3002 \u5c06 .spec.replicas \u66ff\u6362\u4e3a {{ .Values.replicaCount }} \uff0c\u5e76\u7528\u5728 values.yaml \u6587\u4ef6\u4e2d\u5b9a\u4e49\u7684\u53d8\u91cf\u586b\u5145\u3002 \u5c06 .spec.selector.matchLabels \u66ff\u6362\u4e3a {{- include \"cka-demo.selectorLabels\" . | nindent 6 }} \u5e76\u4f7f\u7528\u5728 _helpers.tpl \u6587\u4ef6\u4e2d\u5b9a\u4e49\u7684 cka-demo.selectorLabels \u8fdb\u884c\u586b\u5145\u3002 \u5c06 .spec.template.metadata.labels \u66ff\u6362\u4e3a {{- include \"cka-demo.selectorLabels\" . | nindent 8 }} \u5e76\u4f7f\u7528\u5728 _helpers.tpl \u6587\u4ef6\u4e2d\u5b9a\u4e49\u7684 cka-demo.selectorLabels \u8fdb\u884c\u586b\u5145\u3002 \u5c06 .spec.template.spec.containers[0].image \u66ff\u6362\u4e3a {{ .Values.image.repository }} \u548c {{ .Values.image.tag }} \u5e76\u4f7f\u7528\u5728 values.yaml \u6587\u4ef6\u4e2d\u5b9a\u4e49\u7684\u53d8\u91cf\u586b\u5145\u955c\u50cf\u540d\u79f0\u548c\u955c\u50cf\u6807\u7b7e\u3002 \u5c06 .spec.template.spec.containers[0].command \u66ff\u6362\u4e3a\u4e00\u4e2a if-else \u8bed\u53e5\uff0c\u5982\u679c .Values.passExam \u4e3a\u771f\uff0c\u5219\u6267\u884c\u5728 .Values.passCommand \u4e2d\u5b9a\u4e49\u7684\u547d\u4ee4\uff0c\u5426\u5219\u6267\u884c\u5728 .Values.lostCommand \u4e2d\u5b9a\u4e49\u7684\u547d\u4ee4\u3002 \u4f7f\u7528 .spec.template.spec.containers[0].env \u4e2d\u7684 key \u4f5c\u4e3a ConfigMap \u540d\u79f0\u7684\u524d\u7f00\uff0c\u5e76\u4f7f\u7528\u5728 values.yaml \u6587\u4ef6\u4e2d\u5b9a\u4e49\u7684 {{ .Values.studentName }} \u8fdb\u884c\u586b\u5145\u3002 \u5c06 .spec.template.spec.containers[0].resources \u66ff\u6362\u4e3a {{ .Values.resources }} \u5e76\u4f7f\u7528\u5728 values.yaml \u6587\u4ef6\u4e2d\u5b9a\u4e49\u7684\u53d8\u91cf\u8fdb\u884c\u586b\u5145\u3002 .Release.Name \u662f\u5185\u7f6e\u5bf9\u8c61\uff0c\u5728\u6587\u4ef6 values.yaml \u4e2d\u4e0d\u9700\u8981\u6307\u5b9a\u3002\u5b83\u662f\u7531 helm install \u751f\u6210\u7684Release\u3002 \u79fb\u9664\u4e0d\u5fc5\u8981\u7684\u884c\uff0c\u6700\u7ec8\u6587\u4ef6\u770b\u8d77\u6765\u7c7b\u4f3c\u4e0b\u9762\u7684\u7ed3\u679c\uff1a apiVersion : apps/v1 kind : Deployment metadata : name : {{ .Release.Name }} labels : {{ - include \"cka-demo.labels\" . | nindent 4 }} spec : replicas : {{ .Values.replicaCount }} selector : matchLabels : {{ - include \"cka-demo.selectorLabels\" . | nindent 6 }} template : metadata : labels : {{ - include \"cka-demo.selectorLabels\" . | nindent 8 }} spec : containers : - name : id-generator image : \"{{ .Values.image.repository }}:{{ .Values.image.tag }}\" {{ - if .Values.passExam }} {{ - with .Values.passCommand }} command : {{ range . }} - {{ . | quote }} {{ - end }} {{ - end }} {{ - else }} {{ - with .Values.lostCommand }} command : {{ range . }} - {{ . | quote }} {{ - end }} {{ - end }} {{ - end }} env : - name : CKA_SCORE valueFrom : configMapKeyRef : name : {{ .Values.studentName }} -cka-score key : cka_score {{ - with .Values.resources }} resources : {{ - toYaml . | nindent 12 }} {{ - end }} restartPolicy : Always \u66f4\u65b0\u6587\u4ef6 values.yaml \u4e2d\u53d8\u91cf\u7684\u9ed8\u8ba4\u503c\u3002\u5efa\u8bae\u9010\u4e2a\u6dfb\u52a0\u53d8\u91cf\u5e76\u6d4b\u8bd5\uff0c\u4e0d\u8981\u4e00\u6b21\u6dfb\u52a0\u6240\u6709\u53d8\u91cf\u3002 vi values.yaml \u8fd0\u884c\u7ed3\u679c\uff1a # Number of deployment replicas replicaCount: 1 # Image repository and tag image: repository: busybox tag: latest # Container start command passCommand: - '/bin/sh' - '-c' - \"echo Your CKA score is $(CKA_SCORE) and your CKA certificate ID number is $(tr -dc 'A-Za-z0-9' < /dev/urandom | head -c 13; echo) ; sleep 86400\" lostCommand: - '/bin/sh' - '-c' - \"echo Your CKA score is $(CKA_SCORE), Come on! you can do it next time! ; sleep 86400\" # Container resources resources: limits: cpu: 200m memory: 256Mi requests: cpu: 100m memory: 128Mi # Student Name studentName: whoareyou # Student pass CKA exam or not passExam: true ConfigMap\u6a21\u7248 \u00b6 ConfigMap\u88ab\u90e8\u7f72\u4e2d\u7684Deployment\u6240\u5f15\u7528\uff0c\u56e0\u6b64\u6211\u4eec\u9700\u8981\u5b9a\u4e49ConfigMap\u7684\u6a21\u677f\u3002 \u6211\u4eec\u5c06\u628aConfigMap\u7684\u540d\u79f0\u548c cka_score \u7ec4\u5408\u6210\u4e00\u4e2a\u53d8\u91cf\uff0c\u4f8b\u5982 name-cka-score \u3002 vi templates/configmap.yaml \u8fd0\u884c\u7ed3\u679c\uff1a apiVersion : v1 kind : ConfigMap metadata : name : {{ .Values.studentName }} -cka-score labels : {{ - include \"cka-demo.labels\" . | nindent 4 }} data : cka_score : {{ .Values.ckaScore | quote }} studentName \u5df2\u7ecf\u5728 values.yaml \u6587\u4ef6\u4e2d\u5b9a\u4e49\u8fc7\u4e86\uff0c\u6211\u4eec\u53ea\u9700\u8981\u6dfb\u52a0\u4e00\u4e2a\u540d\u4e3a ckaScore \u7684\u53d8\u91cf\u5e76\u7ed9\u5b83\u4e00\u4e2a\u9ed8\u8ba4\u503c\u5373\u53ef\u3002 vi values.yaml \u8fd0\u884c\u7ed3\u679c # Student CKA Score ckaScore: 100 _helpers.tpl \u00b6 \u5b9a\u4e49\u4e00\u4e2a\u901a\u7528\u7684\u6a21\u677f _helpers.tpl \uff0c\u4e3aDeployment\u548cConfigMap\u7684\u6807\u7b7e\u548c\u9009\u62e9\u5668\u6807\u7b7e\u6dfb\u52a0\u6807\u7b7e\u3002 vi templates/_helpers.tpl \u8fd0\u884c\u7ed3\u679c\uff1a {{/* Common labels */}} {{- define \"cka-demo.labels\" -}} {{ include \"cka-demo.selectorLabels\" . }} {{- if .Chart.AppVersion }} app.kubernetes.io/version: {{ .Chart.AppVersion | quote }} {{- end }} app.kubernetes.io/managed-by: {{ .Release.Service }} {{- end -}} {{/* Selector labels */}} {{- define \"cka-demo.selectorLabels\" -}} app: {{ .Chart.Name }} release: {{ .Release.Name }} {{- end -}} Chart.yaml \u00b6 \u8fd9\u91cc\u6211\u4eec\u4f7f\u7528CKA\u7684logo\u6765\u4f5c\u4e3aChart\u7684\u56fe\u6807\u3002 wget https://www.cncf.io/wp-content/uploads/2021/09/kubernetes-cka-color.svg \u7f16\u8f91\u4fee\u6539 Chart.yaml \u6587\u4ef6\u3002 vi Chart.yaml \u628a\u56fe\u6807\u4fe1\u606f\u6dfb\u52a0\u5230Chart.yaml\u6587\u4ef6\u672b\u5c3e\u3002 icon: file://./kubernetes-cka-color.svg \u628a\u4f5c\u8005\u4fe1\u606f\u6dfb\u52a0\u5230Chart.yaml\u6587\u4ef6\u672b\u5c3e\u3002 vi Chart.yaml \u8fd0\u884c\u7ed3\u679c\uff1a maintainers: - name: James.H \u6700\u7ec8\u7684 Chart.yaml \u7c7b\u4f3c\u5982\u4e0b\u5185\u5bb9\u3002\u522b\u5fd8\u8bb0\u66f4\u65b0 appVersion: \"v1.23\" \u4e3a\u5f53\u524dKubernetes\u7684\u7248\u672c\u3002 apiVersion: v2 name: cka-demo description: A Helm chart for CKA demo. type: application version: 0.1.0 appVersion: \"v1.23\" maintainers: - name: James.H icon: file://./kubernetes-cka-color.svg Chart Debug \u00b6 \u4f7f\u7528 helm lint \u6765\u9a8c\u8bc1\u4e0a\u8ff0\u53d8\u66f4\u3002 helm lint \u8fd0\u884c\u7ed3\u679c\uff1a 1 chart(s) linted, 0 chart(s) failed helm lint \u53ea\u68c0\u67e5Chart\u7684\u683c\u5f0f\uff0c\u4e0d\u68c0\u67e5Manifest\u6587\u4ef6\u3002 \u6211\u4eec\u53ef\u4ee5\u4f7f\u7528 helm install --debug --dry-run \u6216 helm template \u547d\u4ee4\u6765\u68c0\u67e5\u751f\u6210\u7684 Manifest \u662f\u5426\u6b63\u786e\u3002 helm template cka-demo ./ \u901a\u8fc7\u547d\u4ee4 helm install --debug --dry-run \u6765\u6a21\u62df\u5b89\u88c5\u3002\u6211\u4eec\u53ef\u4ee5\u4ece\u4e24\u4e2a\u4e0d\u540c\u7684\u9009\u9879\uff08\u901a\u8fc7\u6216\u672a\u901a\u8fc7CKA\u8ba4\u8bc1\uff09\u4e2d\u83b7\u5f97\u9884\u671f\u7684\u7ed3\u679c\u3002 helm install --debug --dry-run cka-demo ./ --create-namespace \\ -n cka \\ --set studentName = kubernetes \\ --set ckaScore = 99 \\ --set passExam = true helm install --debug --dry-run cka-demo ./ --create-namespace \\ -n cka \\ --set studentName = kubernetes \\ --set ckaScore = 0 \\ --set passExam = false \u628a Chart \u6253\u5305\u6210 .tgz \u6587\u4ef6\uff0c\u5e76\u4e0a\u4f20\u5230\u4ed3\u5e93\uff0c\u4f8b\u5982 Chart Museum \u6216\u8005 OCI Repo\u3002 cd ../ helm package cka-demo \u8fd0\u884c\u7ed3\u679c\uff1a Successfully packaged chart and saved it to: /root/cka-demo-0.1.0.tgz \u81f3\u6b64\uff0c\u6211\u4eec\u5df2\u7ecf\u5b8c\u6210\u4e86\u914d\u7f6e\u4e00\u4e2a\u65b0\u7684Chart\uff0c\u73b0\u5728\u5f00\u59cb\u5b89\u88c5\u8fd9\u4e2aChart\u3002 helm install cka-demo cka-demo-0.1.0.tgz --create-namespace \\ -n cka \\ --set studentName = kubernetes \\ --set ckaScore = 0 \\ --set passExam = false \u8fd0\u884c\u7ed3\u679c\uff1a NAME: cka-demo LAST DEPLOYED: Sun Jul 24 19:58:36 2022 NAMESPACE: cka STATUS: deployed REVISION: 1 TEST SUITE: None NOTES: Come on! you can do it next time! \u68c0\u67e5\u90e8\u7f72\u60c5\u51b5\uff1a helm list --all-namespaces \u8fd0\u884c\u7ed3\u679c\uff1a NAME NAMESPACE REVISION UPDATED STATUS CHART APP VERSION cka-demo cka 1 2022-07-24 19:58:36.272093383 +0800 CST deployed cka-demo-0.1.0 v1.23 mysql dev 1 2022-07-24 19:37:20.710988009 +0800 CST deployed mysql-9.2.1 8.0.29 \u5982\u679c\u9047\u5230\u9519\u8bef\uff0c\u5219\u9700\u8981\u5378\u8f7d cka-demo \u5e76\u91cd\u65b0\u5b89\u88c5\u5b83\u3002 helm uninstall cka-demo -n \u68c0\u67e5 cka-demo \u7684\u65e5\u5fd7\u3002 kubectl logs -n cka -l app = cka-demo \u8fd0\u884c\u7ed3\u679c Your CKA score is 0, Come on! you can do it next time! \u901a\u8fc7\u5176\u4ed6\u9009\u9879\u5b89\u88c5 cka-demo \u3002 helm uninstall cka-demo -n cka helm install cka-demo cka-demo-0.1.0.tgz --create-namespace \\ -n cka \\ --set studentName = kubernetes \\ --set ckaScore = 100 \\ --set passExam = true \u8fd0\u884c\u7ed3\u679c\uff1a NAME: cka-demo LAST DEPLOYED: Sun Jul 24 20:01:34 2022 NAMESPACE: cka STATUS: deployed REVISION: 1 TEST SUITE: None NOTES: Congratulations! You have successfully completed Certified Kubernetes Administrator China Exam (CKA-CN). Your CKA score is: 100 Click the link below to view and download your certificate. https://trainingportal.linuxfoundation.org/learn/dashboard \u68c0\u67e5 cka-demo \u7684\u65e5\u5fd7\u3002 kubectl logs -n cka -l app = cka-demo \u8fd0\u884c\u7ed3\u679c\uff1a Your CKA score is 100 and your CKA certificate ID number is BQKoVYVhjzl3G Built-in Objects\u5217\u8868 Release.Name # \u53d1\u5e03\u540d\u79f0 Release.Namespace # \u53d1\u5e03Namespace Release.Service # \u6e32\u67d3\u6a21\u677f\u7684\u670d\u52a1\uff0c\u5728Helm\u4e2d\u9ed8\u8ba4\u503c\u4e3a\"Helm\" Release.IsUpgrade # \u5982\u679c\u5f53\u524d\u662f\u5347\u7ea7\u6216\u56de\u6eda\uff0c\u8bbe\u7f6e\u4e3atrue Release.IsInstall # \u5982\u679c\u5f53\u524d\u662f\u5b89\u88c5\uff0c\u8bbe\u7f6e\u4e3atrue Release.Revision # \u53d1\u5e03\u7248\u672c\u53f7 Values # \u4ecevalues.yaml\u548c--set\u4f20\u5165\uff0c\u9ed8\u8ba4\u4e3a\u7a7a Chart # \u6240\u6709Chart.yaml\u4e2d\u7684\u5185\u5bb9 Chart.Version # Chart.Maintainers # Files # \u5728chart\u4e2d\u8bbf\u95ee\u975e\u7279\u6b8a\u6587\u4ef6 Capabilities # \u63d0\u4f9b\u5173\u4e8e\u652f\u6301\u80fd\u529b\u7684\u4fe1\u606f\uff08K8s API\u7248\u672c\u3001K8s\u7248\u672c\u3001Helm\u7248\u672c\uff09 Capabilities.KubeVersion # Kubernetes\u7684\u7248\u672c\u53f7 Capabilities.APIVersions.Has \"batch/v1\" # K8s API\u7248\u672c\u5305\u542b\"batch/v1\" Template # \u5f53\u524d\u6a21\u677f\u4fe1\u606f Template.Name # \u5f53\u524d\u6a21\u677f\u6587\u4ef6\u8def\u5f84 Template.BasePath # \u5f53\u524d\u6a21\u677f\u76ee\u5f55\u8def\u5f84 \u53c2\u8003\uff1a Helm \u5b98\u7f51 Helm \u7248\u672c\u652f\u6301\u7b56\u7565 Helm Chart \u8d44\u6e90\u5bf9\u8c61\u5b89\u88c5\u987a\u5e8f","title":"Helm Chart"},{"location":"k8s/cka_cn/foundamentals/helming/#cka27helm-chart","text":"","title":"CKA\u81ea\u5b66\u7b14\u8bb027:Helm Chart"},{"location":"k8s/cka_cn/foundamentals/helming/#helm","text":"\u5728\u8282\u70b9 cka001 \u4e0a\u5b89\u88c5Helm\u3002 # https://github.com/helm/helm/releases wget https://get.helm.sh/helm-v3.8.2-linux-amd64.tar.gz tar -zxvf helm-v3.8.2-linux-amd64.tar.gz cp linux-amd64/helm /usr/bin/ rm -rf linux-amd64 helm-v3.8.2-linux-amd64.tar.gz \u6216\u8005\u4ece\u94fe\u63a5 https://get.helm.sh/helm-v3.8.2-linux-amd64.tar.gz \u624b\u5de5\u4e0b\u8f7d\u5b89\u88c5\u5305\uff0c\u5e76\u62f7\u8d1d\u5230\u8282\u70b9 cka001 \u4e0a\u3002 scp -i cka-key-pair.pem ./Package/helm-v3.8.2-linux-amd64.tar.gz root@cka001:/root/ ssh -i cka-key-pair.pem root@cka001 tar -zxvf helm-v3.8.2-linux-amd64.tar.gz cp linux-amd64/helm /usr/bin/ rm -rf linux-amd64 helm-v3.8.2-linux-amd64.tar.gz","title":"\u5b89\u88c5Helm"},{"location":"k8s/cka_cn/foundamentals/helming/#helm_1","text":"\u68c0\u67e5 helm \u7684\u7248\u672c\u3002 helm version \u8fd0\u884c\u7ed3\u679c\uff1a version.BuildInfo{Version:\"v3.8.2\", GitCommit:\"6e3701edea09e5d55a8ca2aae03a68917630e91b\", GitTreeState:\"clean\", GoVersion:\"go1.17.5\"} \u83b7\u53d6 helm \u7684\u5e2e\u52a9\u4fe1\u606f\u3002 helm help \u914d\u7f6e helm \u7684\u547d\u4ee4\u81ea\u52a8\u8865\u5168\u529f\u80fd\u3002 echo \"source <(helm completion bash)\" >> ~/.bashrc source < ( helm completion bash )","title":"Helm\u7528\u6cd5"},{"location":"k8s/cka_cn/foundamentals/helming/#helmmysql","text":"\u6dfb\u52a0Bitnami Chartes\u4ed3\u5e93\u3002 helm repo add bitnami https://charts.bitnami.com/bitnami \u67e5\u8be2\u5f53\u524d\u53ef\u7528\u7684Chartes\u4ed3\u5e93\u3002 helm repo list \u8fd0\u884c\u7ed3\u679c\uff1a NAME URL bitnami https://charts.bitnami.com/bitnami \u540c\u6b65\u672c\u5730Charts\u4ed3\u5e93\u3002 helm repo update \u5728Charts\u4ed3\u5e93\u4e2d\u67e5\u627ebitnami Charts\u4ed3\u5e93\u3002 helm search repo bitnami \u5728\u4ed3\u5e93\u4e2d\u641c\u7d22bitnami/mysql Charts\u3002 helm search repo bitnami/mysql \u5728namespace dev \u4e0a\u5b89\u88c5MySQL Chart\u3002 helm install mysql bitnami/mysql -n dev \u8fd0\u884c\u7ed3\u679c\uff1a NAME: mysql LAST DEPLOYED: Sun Jul 24 19:37:20 2022 NAMESPACE: dev STATUS: deployed REVISION: 1 TEST SUITE: None NOTES: CHART NAME: mysql CHART VERSION: 9.2.1 APP VERSION: 8.0.29 ** Please be patient while the chart is being deployed ** Tip: Watch the deployment status using the command: kubectl get pods -w --namespace dev Services: echo Primary: mysql.dev.svc.cluster.local:3306 Execute the following to get the administrator credentials: echo Username: root MYSQL_ROOT_PASSWORD=$(kubectl get secret --namespace dev mysql -o jsonpath=\"{.data.mysql-root-password}\" | base64 -d) To connect to your database: 1. Run a pod that you can use as a client: kubectl run mysql-client --rm --tty -i --restart='Never' --image docker.io/bitnami/mysql:8.0.29-debian-11-r9 --namespace dev --env MYSQL_ROOT_PASSWORD=$MYSQL_ROOT_PASSWORD --command -- bash 2. To connect to primary service (read/write): mysql -h mysql.dev.svc.cluster.local -uroot -p\"$MYSQL_ROOT_PASSWORD\" \u67e5\u770b\u5f53\u524d\u5b89\u88c5\u5305\u7684\u4fe1\u606f\u3002 helm list \u8fd0\u884c\u7ed3\u679c\uff1a NAME NAMESPACE REVISION UPDATED STATUS CHART APP VERSION mysql dev 1 2022-07-24 19:37:20.710988009 +0800 CST deployed mysql-9.2.1 8.0.29 \u68c0\u67e5\u5f53\u524d\u5b89\u88c5\u7684mysql\u7248\u672c\u4fe1\u606f\u3002 helm status mysql \u68c0\u67e5pod mysql \u7684\u72b6\u6001\u3002 kubectl get pod \u8fd0\u884c\u7ed3\u679c\uff1a NAME READY STATUS RESTARTS AGE mysql-0 1/1 Running 0 72s","title":"\u901a\u8fc7Helm\u5b89\u88c5MySQL"},{"location":"k8s/cka_cn/foundamentals/helming/#chart","text":"\u4e0b\u9762\u6f14\u793a\u4e86\u5982\u4f55\u90e8\u7f72\u4e00\u4e2aChart\u3002 \u6267\u884c\u547d\u4ee4 helm create \u6765\u521d\u59cb\u5316\u4e00\u4e2aChart\u3002 # Naming conventions of Chart: lowercase a~z and -(minus sign) helm create cka-demo \u76ee\u5f55 cka-demo \u4f1a\u88ab\u521b\u5efa\uff0c\u67e5\u770b\u8fd9\u4e2a\u76ee\u5f55\u7684\u7ed3\u6784\u3002 tree cka-demo/ \u8fd0\u884c\u7ed3\u679c\uff1a cka-demo/ \u251c\u2500\u2500 charts \u251c\u2500\u2500 Chart.yaml \u251c\u2500\u2500 templates \u2502 \u251c\u2500\u2500 deployment.yaml \u2502 \u251c\u2500\u2500 _helpers.tpl \u2502 \u251c\u2500\u2500 hpa.yaml \u2502 \u251c\u2500\u2500 ingress.yaml \u2502 \u251c\u2500\u2500 NOTES.txt \u2502 \u251c\u2500\u2500 serviceaccount.yaml \u2502 \u251c\u2500\u2500 service.yaml \u2502 \u2514\u2500\u2500 tests \u2502 \u2514\u2500\u2500 test-connection.yaml \u2514\u2500\u2500 values.yaml \u5220\u9664\u6216\u6e05\u7a7a\u67d0\u4e9b\u6587\u4ef6\uff0c\u6211\u4eec\u4f1a\u5728\u540e\u9762\u91cd\u65b0\u521b\u5efa\u8fd9\u4e9b\u6587\u4ef6\u3002 cd cka-demo rm -rf charts rm -rf templates/tests rm -rf templates/*.yaml echo \"\" > values.yaml echo \"\" > templates/NOTES.txt echo \"\" > templates/_helpers.tpl cd .. \u76ee\u5f55 cka-demo \u7684\u67b6\u6784\u73b0\u5728\u5e94\u8be5\u770b\u8d77\u6765\u7c7b\u4f3c\u4e0b\u9762\u7684\u7ed3\u679c\u3002 tree cka-demo/ \u8fd0\u884c\u7ed3\u679c\uff1a cka-demo/ \u251c\u2500\u2500 Chart.yaml \u251c\u2500\u2500 templates \u2502 \u251c\u2500\u2500 _helpers.tpl \u2502 \u2514\u2500\u2500 NOTES.txt \u2514\u2500\u2500 values.yaml","title":"\u90e8\u7f72\u4e00\u4e2aChart"},{"location":"k8s/cka_cn/foundamentals/helming/#notestxt","text":"NOTES.txt \u7528\u4e8e\u5411 Chart \u7528\u6237\u63d0\u4f9b\u6982\u8981\u4fe1\u606f\u3002\u5728\u6f14\u793a\u4e2d\uff0c\u6211\u4eec\u5c06\u4f7f\u7528 NOTES.txt \u63d0\u4f9b\u5173\u4e8e\u7528\u6237\u662f\u5426\u901a\u8fc7 CKA \u8ba4\u8bc1\u7684\u6982\u8981\u4fe1\u606f\u3002 cd cka-demo/ vi templates/NOTES.txt \u6dfb\u52a0\u4e0b\u9762\u7684\u5185\u5bb9\u3002 {{- if .Values.passExam }} Congratulations! You have successfully completed Certified Kubernetes Administrator China Exam (CKA-CN). Your CKA score is: {{ .Values.ckaScore }} Click the link below to view and download your certificate. https://trainingportal.linuxfoundation.org/learn/dashboard {{- else }} Come on! you can do it next time! {{- end }}","title":"NOTES.txt"},{"location":"k8s/cka_cn/foundamentals/helming/#_1","text":"\u4e0b\u9762\u4f1a\u4f7f\u7528 Busybox \u670d\u52a1\u6765\u751f\u6210\u4fe1\u606f\u3002 \u901a\u8fc7\u547d\u4ee4 kubectl create deployment --dry-run=client -oyaml \u751f\u6210 Deployment \u7684 YAML \u6587\u4ef6\uff0c\u5e76\u5c06\u5176\u5185\u5bb9\u5199\u5165\u6587\u4ef6 templates/deployment.yaml \u3002 kubectl create deployment cka-demo-busybox --image = busybox:latest --dry-run = client -oyaml > templates/deployment.yaml \u68c0\u67e5deployment\u7684yaml\u6587\u4ef6 templates/deployment.yaml \u7684\u5185\u5bb9\u3002 cat templates/deployment.yaml \u8fd0\u884c\u7ed3\u679c\uff1a apiVersion : apps/v1 kind : Deployment metadata : creationTimestamp : null labels : app : cka-demo-busybox name : cka-demo-busybox spec : replicas : 1 selector : matchLabels : app : cka-demo-busybox strategy : {} template : metadata : creationTimestamp : null labels : app : cka-demo-busybox spec : containers : - image : busybox:latest name : busybox resources : {} status : {} \u7f16\u8f91\u4fee\u6539\u6587\u4ef6 templates/deployment.yaml \u3002 vi templates/deployment.yaml \u8ba9\u6211\u4eec\u5c06 .spec.replicas \u7684\u503c\u4ece 1 \u66ff\u6362\u4e3a\u53d8\u91cf {{ .Values.replicaCount }} \uff0c\u8fd9\u6837\u6211\u4eec\u53ef\u4ee5\u4e3a\u5176\u4ed6 Deployment \u52a8\u6001\u5206\u914d\u526f\u672c\u6570\u3002 apiVersion : apps/v1 kind : Deployment metadata : creationTimestamp : null labels : app : cka-demo-busybox name : cka-demo-busybox spec : replicas : {{ .Values.replicaCount }} selector : matchLabels : app : cka-demo-busybox strategy : {} template : metadata : creationTimestamp : null labels : app : cka-demo-busybox spec : containers : - image : busybox:latest name : busybox resources : {} status : {} .spec.replicas \u5c06\u5728\u90e8\u7f72\u671f\u95f4\u88ab\u5b9e\u9645\u7684 .Values.replicaCount \u503c\u66ff\u6362\u3002 \u73b0\u5728\u521b\u5efa\u53e6\u4e00\u4e2a\u6587\u4ef6 values.yaml \u5e76\u5728\u6587\u4ef6\u4e2d\u6dfb\u52a0\u4e00\u4e2a\u53d8\u91cf replicaCount \uff0c\u9ed8\u8ba4\u503c\u4e3a1\u3002 \u5f3a\u70c8\u5efa\u8bae\u5728\u6587\u4ef6 values.yaml \u4e2d\u5b9a\u4e49\u7684\u6bcf\u4e2a\u503c\u6dfb\u52a0\u6ce8\u91ca\u3002 vi values.yaml \u8f93\u51fa\u7ed3\u679c\uff1a # Number of deployment replicas replicaCount: 1 \u4e0b\u9762\u5bf9\u6587\u4ef6 templates/deployment.yaml \u6dfb\u52a0\u66f4\u591a\u7684\u53d8\u91cf\u3002 \u5c06 .metadata.name \u7684 Release \u540d\u79f0\u66ff\u6362\u4e3a {{ .Release.Name }} \uff0c\u5e76\u7528\u5728 values.yaml \u6587\u4ef6\u4e2d\u5b9a\u4e49\u7684\u53d8\u91cf\u586b\u5145\u3002 \u5c06\u6807\u7b7e\u540d\u79f0 .metadata.labels \u66ff\u6362\u4e3a {{- include \"cka-demo.labels\" . | nindent 4 }} \uff0c\u5e76\u7528\u5728 _helpers.tpl \u6587\u4ef6\u4e2d\u5b9a\u4e49\u7684\u6807\u7b7e\u540d\u79f0 cka-demo.labels \u586b\u5145\u3002 \u5c06 .spec.replicas \u66ff\u6362\u4e3a {{ .Values.replicaCount }} \uff0c\u5e76\u7528\u5728 values.yaml \u6587\u4ef6\u4e2d\u5b9a\u4e49\u7684\u53d8\u91cf\u586b\u5145\u3002 \u5c06 .spec.selector.matchLabels \u66ff\u6362\u4e3a {{- include \"cka-demo.selectorLabels\" . | nindent 6 }} \u5e76\u4f7f\u7528\u5728 _helpers.tpl \u6587\u4ef6\u4e2d\u5b9a\u4e49\u7684 cka-demo.selectorLabels \u8fdb\u884c\u586b\u5145\u3002 \u5c06 .spec.template.metadata.labels \u66ff\u6362\u4e3a {{- include \"cka-demo.selectorLabels\" . | nindent 8 }} \u5e76\u4f7f\u7528\u5728 _helpers.tpl \u6587\u4ef6\u4e2d\u5b9a\u4e49\u7684 cka-demo.selectorLabels \u8fdb\u884c\u586b\u5145\u3002 \u5c06 .spec.template.spec.containers[0].image \u66ff\u6362\u4e3a {{ .Values.image.repository }} \u548c {{ .Values.image.tag }} \u5e76\u4f7f\u7528\u5728 values.yaml \u6587\u4ef6\u4e2d\u5b9a\u4e49\u7684\u53d8\u91cf\u586b\u5145\u955c\u50cf\u540d\u79f0\u548c\u955c\u50cf\u6807\u7b7e\u3002 \u5c06 .spec.template.spec.containers[0].command \u66ff\u6362\u4e3a\u4e00\u4e2a if-else \u8bed\u53e5\uff0c\u5982\u679c .Values.passExam \u4e3a\u771f\uff0c\u5219\u6267\u884c\u5728 .Values.passCommand \u4e2d\u5b9a\u4e49\u7684\u547d\u4ee4\uff0c\u5426\u5219\u6267\u884c\u5728 .Values.lostCommand \u4e2d\u5b9a\u4e49\u7684\u547d\u4ee4\u3002 \u4f7f\u7528 .spec.template.spec.containers[0].env \u4e2d\u7684 key \u4f5c\u4e3a ConfigMap \u540d\u79f0\u7684\u524d\u7f00\uff0c\u5e76\u4f7f\u7528\u5728 values.yaml \u6587\u4ef6\u4e2d\u5b9a\u4e49\u7684 {{ .Values.studentName }} \u8fdb\u884c\u586b\u5145\u3002 \u5c06 .spec.template.spec.containers[0].resources \u66ff\u6362\u4e3a {{ .Values.resources }} \u5e76\u4f7f\u7528\u5728 values.yaml \u6587\u4ef6\u4e2d\u5b9a\u4e49\u7684\u53d8\u91cf\u8fdb\u884c\u586b\u5145\u3002 .Release.Name \u662f\u5185\u7f6e\u5bf9\u8c61\uff0c\u5728\u6587\u4ef6 values.yaml \u4e2d\u4e0d\u9700\u8981\u6307\u5b9a\u3002\u5b83\u662f\u7531 helm install \u751f\u6210\u7684Release\u3002 \u79fb\u9664\u4e0d\u5fc5\u8981\u7684\u884c\uff0c\u6700\u7ec8\u6587\u4ef6\u770b\u8d77\u6765\u7c7b\u4f3c\u4e0b\u9762\u7684\u7ed3\u679c\uff1a apiVersion : apps/v1 kind : Deployment metadata : name : {{ .Release.Name }} labels : {{ - include \"cka-demo.labels\" . | nindent 4 }} spec : replicas : {{ .Values.replicaCount }} selector : matchLabels : {{ - include \"cka-demo.selectorLabels\" . | nindent 6 }} template : metadata : labels : {{ - include \"cka-demo.selectorLabels\" . | nindent 8 }} spec : containers : - name : id-generator image : \"{{ .Values.image.repository }}:{{ .Values.image.tag }}\" {{ - if .Values.passExam }} {{ - with .Values.passCommand }} command : {{ range . }} - {{ . | quote }} {{ - end }} {{ - end }} {{ - else }} {{ - with .Values.lostCommand }} command : {{ range . }} - {{ . | quote }} {{ - end }} {{ - end }} {{ - end }} env : - name : CKA_SCORE valueFrom : configMapKeyRef : name : {{ .Values.studentName }} -cka-score key : cka_score {{ - with .Values.resources }} resources : {{ - toYaml . | nindent 12 }} {{ - end }} restartPolicy : Always \u66f4\u65b0\u6587\u4ef6 values.yaml \u4e2d\u53d8\u91cf\u7684\u9ed8\u8ba4\u503c\u3002\u5efa\u8bae\u9010\u4e2a\u6dfb\u52a0\u53d8\u91cf\u5e76\u6d4b\u8bd5\uff0c\u4e0d\u8981\u4e00\u6b21\u6dfb\u52a0\u6240\u6709\u53d8\u91cf\u3002 vi values.yaml \u8fd0\u884c\u7ed3\u679c\uff1a # Number of deployment replicas replicaCount: 1 # Image repository and tag image: repository: busybox tag: latest # Container start command passCommand: - '/bin/sh' - '-c' - \"echo Your CKA score is $(CKA_SCORE) and your CKA certificate ID number is $(tr -dc 'A-Za-z0-9' < /dev/urandom | head -c 13; echo) ; sleep 86400\" lostCommand: - '/bin/sh' - '-c' - \"echo Your CKA score is $(CKA_SCORE), Come on! you can do it next time! ; sleep 86400\" # Container resources resources: limits: cpu: 200m memory: 256Mi requests: cpu: 100m memory: 128Mi # Student Name studentName: whoareyou # Student pass CKA exam or not passExam: true","title":"\u90e8\u7f72\u6a21\u7248"},{"location":"k8s/cka_cn/foundamentals/helming/#configmap","text":"ConfigMap\u88ab\u90e8\u7f72\u4e2d\u7684Deployment\u6240\u5f15\u7528\uff0c\u56e0\u6b64\u6211\u4eec\u9700\u8981\u5b9a\u4e49ConfigMap\u7684\u6a21\u677f\u3002 \u6211\u4eec\u5c06\u628aConfigMap\u7684\u540d\u79f0\u548c cka_score \u7ec4\u5408\u6210\u4e00\u4e2a\u53d8\u91cf\uff0c\u4f8b\u5982 name-cka-score \u3002 vi templates/configmap.yaml \u8fd0\u884c\u7ed3\u679c\uff1a apiVersion : v1 kind : ConfigMap metadata : name : {{ .Values.studentName }} -cka-score labels : {{ - include \"cka-demo.labels\" . | nindent 4 }} data : cka_score : {{ .Values.ckaScore | quote }} studentName \u5df2\u7ecf\u5728 values.yaml \u6587\u4ef6\u4e2d\u5b9a\u4e49\u8fc7\u4e86\uff0c\u6211\u4eec\u53ea\u9700\u8981\u6dfb\u52a0\u4e00\u4e2a\u540d\u4e3a ckaScore \u7684\u53d8\u91cf\u5e76\u7ed9\u5b83\u4e00\u4e2a\u9ed8\u8ba4\u503c\u5373\u53ef\u3002 vi values.yaml \u8fd0\u884c\u7ed3\u679c # Student CKA Score ckaScore: 100","title":"ConfigMap\u6a21\u7248"},{"location":"k8s/cka_cn/foundamentals/helming/#_helperstpl","text":"\u5b9a\u4e49\u4e00\u4e2a\u901a\u7528\u7684\u6a21\u677f _helpers.tpl \uff0c\u4e3aDeployment\u548cConfigMap\u7684\u6807\u7b7e\u548c\u9009\u62e9\u5668\u6807\u7b7e\u6dfb\u52a0\u6807\u7b7e\u3002 vi templates/_helpers.tpl \u8fd0\u884c\u7ed3\u679c\uff1a {{/* Common labels */}} {{- define \"cka-demo.labels\" -}} {{ include \"cka-demo.selectorLabels\" . }} {{- if .Chart.AppVersion }} app.kubernetes.io/version: {{ .Chart.AppVersion | quote }} {{- end }} app.kubernetes.io/managed-by: {{ .Release.Service }} {{- end -}} {{/* Selector labels */}} {{- define \"cka-demo.selectorLabels\" -}} app: {{ .Chart.Name }} release: {{ .Release.Name }} {{- end -}}","title":"_helpers.tpl"},{"location":"k8s/cka_cn/foundamentals/helming/#chartyaml","text":"\u8fd9\u91cc\u6211\u4eec\u4f7f\u7528CKA\u7684logo\u6765\u4f5c\u4e3aChart\u7684\u56fe\u6807\u3002 wget https://www.cncf.io/wp-content/uploads/2021/09/kubernetes-cka-color.svg \u7f16\u8f91\u4fee\u6539 Chart.yaml \u6587\u4ef6\u3002 vi Chart.yaml \u628a\u56fe\u6807\u4fe1\u606f\u6dfb\u52a0\u5230Chart.yaml\u6587\u4ef6\u672b\u5c3e\u3002 icon: file://./kubernetes-cka-color.svg \u628a\u4f5c\u8005\u4fe1\u606f\u6dfb\u52a0\u5230Chart.yaml\u6587\u4ef6\u672b\u5c3e\u3002 vi Chart.yaml \u8fd0\u884c\u7ed3\u679c\uff1a maintainers: - name: James.H \u6700\u7ec8\u7684 Chart.yaml \u7c7b\u4f3c\u5982\u4e0b\u5185\u5bb9\u3002\u522b\u5fd8\u8bb0\u66f4\u65b0 appVersion: \"v1.23\" \u4e3a\u5f53\u524dKubernetes\u7684\u7248\u672c\u3002 apiVersion: v2 name: cka-demo description: A Helm chart for CKA demo. type: application version: 0.1.0 appVersion: \"v1.23\" maintainers: - name: James.H icon: file://./kubernetes-cka-color.svg","title":"Chart.yaml"},{"location":"k8s/cka_cn/foundamentals/helming/#chart-debug","text":"\u4f7f\u7528 helm lint \u6765\u9a8c\u8bc1\u4e0a\u8ff0\u53d8\u66f4\u3002 helm lint \u8fd0\u884c\u7ed3\u679c\uff1a 1 chart(s) linted, 0 chart(s) failed helm lint \u53ea\u68c0\u67e5Chart\u7684\u683c\u5f0f\uff0c\u4e0d\u68c0\u67e5Manifest\u6587\u4ef6\u3002 \u6211\u4eec\u53ef\u4ee5\u4f7f\u7528 helm install --debug --dry-run \u6216 helm template \u547d\u4ee4\u6765\u68c0\u67e5\u751f\u6210\u7684 Manifest \u662f\u5426\u6b63\u786e\u3002 helm template cka-demo ./ \u901a\u8fc7\u547d\u4ee4 helm install --debug --dry-run \u6765\u6a21\u62df\u5b89\u88c5\u3002\u6211\u4eec\u53ef\u4ee5\u4ece\u4e24\u4e2a\u4e0d\u540c\u7684\u9009\u9879\uff08\u901a\u8fc7\u6216\u672a\u901a\u8fc7CKA\u8ba4\u8bc1\uff09\u4e2d\u83b7\u5f97\u9884\u671f\u7684\u7ed3\u679c\u3002 helm install --debug --dry-run cka-demo ./ --create-namespace \\ -n cka \\ --set studentName = kubernetes \\ --set ckaScore = 99 \\ --set passExam = true helm install --debug --dry-run cka-demo ./ --create-namespace \\ -n cka \\ --set studentName = kubernetes \\ --set ckaScore = 0 \\ --set passExam = false \u628a Chart \u6253\u5305\u6210 .tgz \u6587\u4ef6\uff0c\u5e76\u4e0a\u4f20\u5230\u4ed3\u5e93\uff0c\u4f8b\u5982 Chart Museum \u6216\u8005 OCI Repo\u3002 cd ../ helm package cka-demo \u8fd0\u884c\u7ed3\u679c\uff1a Successfully packaged chart and saved it to: /root/cka-demo-0.1.0.tgz \u81f3\u6b64\uff0c\u6211\u4eec\u5df2\u7ecf\u5b8c\u6210\u4e86\u914d\u7f6e\u4e00\u4e2a\u65b0\u7684Chart\uff0c\u73b0\u5728\u5f00\u59cb\u5b89\u88c5\u8fd9\u4e2aChart\u3002 helm install cka-demo cka-demo-0.1.0.tgz --create-namespace \\ -n cka \\ --set studentName = kubernetes \\ --set ckaScore = 0 \\ --set passExam = false \u8fd0\u884c\u7ed3\u679c\uff1a NAME: cka-demo LAST DEPLOYED: Sun Jul 24 19:58:36 2022 NAMESPACE: cka STATUS: deployed REVISION: 1 TEST SUITE: None NOTES: Come on! you can do it next time! \u68c0\u67e5\u90e8\u7f72\u60c5\u51b5\uff1a helm list --all-namespaces \u8fd0\u884c\u7ed3\u679c\uff1a NAME NAMESPACE REVISION UPDATED STATUS CHART APP VERSION cka-demo cka 1 2022-07-24 19:58:36.272093383 +0800 CST deployed cka-demo-0.1.0 v1.23 mysql dev 1 2022-07-24 19:37:20.710988009 +0800 CST deployed mysql-9.2.1 8.0.29 \u5982\u679c\u9047\u5230\u9519\u8bef\uff0c\u5219\u9700\u8981\u5378\u8f7d cka-demo \u5e76\u91cd\u65b0\u5b89\u88c5\u5b83\u3002 helm uninstall cka-demo -n \u68c0\u67e5 cka-demo \u7684\u65e5\u5fd7\u3002 kubectl logs -n cka -l app = cka-demo \u8fd0\u884c\u7ed3\u679c Your CKA score is 0, Come on! you can do it next time! \u901a\u8fc7\u5176\u4ed6\u9009\u9879\u5b89\u88c5 cka-demo \u3002 helm uninstall cka-demo -n cka helm install cka-demo cka-demo-0.1.0.tgz --create-namespace \\ -n cka \\ --set studentName = kubernetes \\ --set ckaScore = 100 \\ --set passExam = true \u8fd0\u884c\u7ed3\u679c\uff1a NAME: cka-demo LAST DEPLOYED: Sun Jul 24 20:01:34 2022 NAMESPACE: cka STATUS: deployed REVISION: 1 TEST SUITE: None NOTES: Congratulations! You have successfully completed Certified Kubernetes Administrator China Exam (CKA-CN). Your CKA score is: 100 Click the link below to view and download your certificate. https://trainingportal.linuxfoundation.org/learn/dashboard \u68c0\u67e5 cka-demo \u7684\u65e5\u5fd7\u3002 kubectl logs -n cka -l app = cka-demo \u8fd0\u884c\u7ed3\u679c\uff1a Your CKA score is 100 and your CKA certificate ID number is BQKoVYVhjzl3G Built-in Objects\u5217\u8868 Release.Name # \u53d1\u5e03\u540d\u79f0 Release.Namespace # \u53d1\u5e03Namespace Release.Service # \u6e32\u67d3\u6a21\u677f\u7684\u670d\u52a1\uff0c\u5728Helm\u4e2d\u9ed8\u8ba4\u503c\u4e3a\"Helm\" Release.IsUpgrade # \u5982\u679c\u5f53\u524d\u662f\u5347\u7ea7\u6216\u56de\u6eda\uff0c\u8bbe\u7f6e\u4e3atrue Release.IsInstall # \u5982\u679c\u5f53\u524d\u662f\u5b89\u88c5\uff0c\u8bbe\u7f6e\u4e3atrue Release.Revision # \u53d1\u5e03\u7248\u672c\u53f7 Values # \u4ecevalues.yaml\u548c--set\u4f20\u5165\uff0c\u9ed8\u8ba4\u4e3a\u7a7a Chart # \u6240\u6709Chart.yaml\u4e2d\u7684\u5185\u5bb9 Chart.Version # Chart.Maintainers # Files # \u5728chart\u4e2d\u8bbf\u95ee\u975e\u7279\u6b8a\u6587\u4ef6 Capabilities # \u63d0\u4f9b\u5173\u4e8e\u652f\u6301\u80fd\u529b\u7684\u4fe1\u606f\uff08K8s API\u7248\u672c\u3001K8s\u7248\u672c\u3001Helm\u7248\u672c\uff09 Capabilities.KubeVersion # Kubernetes\u7684\u7248\u672c\u53f7 Capabilities.APIVersions.Has \"batch/v1\" # K8s API\u7248\u672c\u5305\u542b\"batch/v1\" Template # \u5f53\u524d\u6a21\u677f\u4fe1\u606f Template.Name # \u5f53\u524d\u6a21\u677f\u6587\u4ef6\u8def\u5f84 Template.BasePath # \u5f53\u524d\u6a21\u677f\u76ee\u5f55\u8def\u5f84 \u53c2\u8003\uff1a Helm \u5b98\u7f51 Helm \u7248\u672c\u652f\u6301\u7b56\u7565 Helm Chart \u8d44\u6e90\u5bf9\u8c61\u5b89\u88c5\u987a\u5e8f","title":"Chart Debug"},{"location":"k8s/cka_cn/foundamentals/hpa/","text":"CKA\u81ea\u5b66\u7b14\u8bb021:Horizontal Pod Autoscaling (HPA) \u00b6 \u6f14\u793a\u573a\u666f\uff1a \u5b89\u88c5 Metrics Server \u7ec4\u4ef6 \u521b\u5efa Deployment podinfo \u548c Service podinfo \u7528\u4e8e\u538b\u529b\u6d4b\u8bd5 \u521b\u5efa HPA my-hpa \u8fdb\u884c\u538b\u529b\u6d4b\u8bd5 \u5b89\u88c5Metrics Server \u00b6 \u4e0b\u8f7d components.yaml \u6587\u4ef6\uff0c\u6765\u90e8\u7f72Metrics Server\u3002 wget https://github.com/kubernetes-sigs/metrics-server/releases/latest/download/components.yaml \u628ayaml\u6587\u4ef6\u4e2dgoogle\u7684\u955c\u50cf\u6e90\u66ff\u6362\u4e3a\u963f\u91cc\u7684\u955c\u50cf\u6e90 image: registry.aliyuncs.com/google_containers/metrics-server:v0.6.1 \u3002 sed -i 's/k8s\\.gcr\\.io\\/metrics-server\\/metrics-server\\:v0\\.6\\.1/registry\\.aliyuncs\\.com\\/google_containers\\/metrics-server\\:v0\\.6\\.1/g' components.yaml \u4fee\u6539deployment metrics-server \u7684 args \uff0c\u6dfb\u52a0\u9009\u9879 --kubelet-insecure-tls \u4ee5\u7981\u7528\u8bc1\u4e66\u9a8c\u8bc1\u3002 vi components.yaml \u66f4\u65b0 args \u3002 ...... template : metadata : labels : k8s-app : metrics-server spec : containers : - args : - --cert-dir=/tmp - --secure-port=4443 - --kubelet-preferred-address-types=InternalIP,ExternalIP,Hostname - --kubelet-use-node-status-port - --metric-resolution=15s - --kubelet-insecure-tls image : registry.aliyuncs.com/google_containers/metrics-server:v0.6.1 ...... \u5e94\u7528\u6587\u4ef6 components.yaml \u6765\u90e8\u7f72 metrics-server \u3002 kubectl apply -f components.yaml \u4e0b\u9762\u662f\u8fd0\u884c\u7ed3\u679c\uff0c\u76f8\u5173\u8d44\u6e90\u88ab\u521b\u5efa\u3002 serviceaccount/metrics-server created clusterrole.rbac.authorization.k8s.io/system:aggregated-metrics-reader created clusterrole.rbac.authorization.k8s.io/system:metrics-server created rolebinding.rbac.authorization.k8s.io/metrics-server-auth-reader created clusterrolebinding.rbac.authorization.k8s.io/metrics-server:system:auth-delegator created clusterrolebinding.rbac.authorization.k8s.io/system:metrics-server created service/metrics-server created deployment.apps/metrics-server created apiservice.apiregistration.k8s.io/v1beta1.metrics.k8s.io created \u9a8c\u8bc1 pod metrics-server \u662f\u5426\u6309\u9884\u671f\u5728\u6b63\u5e38\u8fd0\u884c\u3002 kubectl get pod -n kube-system -owide | grep metrics-server \u8fd0\u884c\u7ed3\u679c\u3002\u5173\u6ce8READY\u4e0b\u7684\u72b6\u6001\uff1a 1/1 running\u4ee3\u8868\u6b63\u5e38\u8fd0\u884c\u3002 NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES metrics-server-7fd564dc66-sdhdc 1/1 Running 0 61s 10.244.102.15 cka003 \u67e5\u8be2\u6bcf\u4e2a\u8282\u70b9\u4e0a\u5f53\u524dCPU\u548c\u5185\u5b58\u7684\u7528\u91cf\u60c5\u51b5\u3002 kubectl top node \u8fd0\u884c\u7ed3\u679c\uff1a NAME CPU(cores) CPU% MEMORY(bytes) MEMORY% cka001 595m 29% 1937Mi 50% cka002 75m 3% 1081Mi 28% cka003 79m 3% 1026Mi 26% \u90e8\u7f72\u670d\u52a1 podinfo \u00b6 \u521b\u5efa Deployment podinfo \u548c Service podinfo \uff0c\u540e\u9762\u4f1a\u8fdb\u884c\u66f4\u8fdb\u4e00\u6b65\u7684\u538b\u529b\u6d4b\u8bd5\u3002 kubectl apply -f - << EOF apiVersion: v1 kind: Service metadata: name: podinfo labels: app: podinfo spec: type: NodePort ports: - port: 9898 targetPort: 9898 nodePort: 31198 protocol: TCP selector: app: podinfo --- apiVersion: apps/v1 kind: Deployment metadata: name: podinfo labels: app: podinfo spec: replicas: 2 selector: matchLabels: app: podinfo template: metadata: labels: app: podinfo spec: containers: - name: podinfod image: stefanprodan/podinfo:0.0.1 imagePullPolicy: Always command: - ./podinfo - -port=9898 - -logtostderr=true - -v=2 ports: - containerPort: 9898 protocol: TCP resources: requests: memory: \"32Mi\" cpu: \"10m\" limits: memory: \"256Mi\" cpu: \"100m\" EOF Config HPA \u00b6 \u521b\u5efa\u4e00\u4e2a\u540d\u4e3a my-hpa \u7684 HPA\uff0c\u5e76\u5c06\u5176\u7ed1\u5b9a\u5230\u540d\u4e3a podinfo \u7684\u90e8\u7f72\u4e2d\uff0c\u8bbe\u5b9a\u5176 CPU \u5229\u7528\u7387\u4e3a 50% \u4f5c\u4e3a\u89e6\u53d1\u81ea\u52a8\u7f29\u653e\u7684\u9608\u503c\uff0c\u6700\u5c0f\u526f\u672c\u6570\u4e3a 2 \uff0c\u6700\u5927\u526f\u672c\u6570\u4e3a 10 \u3002 \u4f7f\u7528\u4ee5\u4e0b\u547d\u4ee4\u521b\u5efa my-hpa HPA\uff1a kubectl autoscale deployment podinfo --cpu-percent = 50 --min = 2 --max = 10 --name = my-hpa kubectl autoscale deployment podinfo --cpu-percent = 50 --min = 1 --max = 10 \u4f7f\u7528 autoscaling/v1 \u7248\u672c\u7684\u6a21\u7248\u6765\u521b\u5efaHPA my-hpa \u3002 kubectl apply -f - < \u67e5\u8be2\u6bcf\u4e2a\u8282\u70b9\u4e0a\u5f53\u524dCPU\u548c\u5185\u5b58\u7684\u7528\u91cf\u60c5\u51b5\u3002 kubectl top node \u8fd0\u884c\u7ed3\u679c\uff1a NAME CPU(cores) CPU% MEMORY(bytes) MEMORY% cka001 595m 29% 1937Mi 50% cka002 75m 3% 1081Mi 28% cka003 79m 3% 1026Mi 26%","title":"\u5b89\u88c5Metrics Server"},{"location":"k8s/cka_cn/foundamentals/hpa/#podinfo","text":"\u521b\u5efa Deployment podinfo \u548c Service podinfo \uff0c\u540e\u9762\u4f1a\u8fdb\u884c\u66f4\u8fdb\u4e00\u6b65\u7684\u538b\u529b\u6d4b\u8bd5\u3002 kubectl apply -f - << EOF apiVersion: v1 kind: Service metadata: name: podinfo labels: app: podinfo spec: type: NodePort ports: - port: 9898 targetPort: 9898 nodePort: 31198 protocol: TCP selector: app: podinfo --- apiVersion: apps/v1 kind: Deployment metadata: name: podinfo labels: app: podinfo spec: replicas: 2 selector: matchLabels: app: podinfo template: metadata: labels: app: podinfo spec: containers: - name: podinfod image: stefanprodan/podinfo:0.0.1 imagePullPolicy: Always command: - ./podinfo - -port=9898 - -logtostderr=true - -v=2 ports: - containerPort: 9898 protocol: TCP resources: requests: memory: \"32Mi\" cpu: \"10m\" limits: memory: \"256Mi\" cpu: \"100m\" EOF","title":"\u90e8\u7f72\u670d\u52a1podinfo"},{"location":"k8s/cka_cn/foundamentals/hpa/#config-hpa","text":"\u521b\u5efa\u4e00\u4e2a\u540d\u4e3a my-hpa \u7684 HPA\uff0c\u5e76\u5c06\u5176\u7ed1\u5b9a\u5230\u540d\u4e3a podinfo \u7684\u90e8\u7f72\u4e2d\uff0c\u8bbe\u5b9a\u5176 CPU \u5229\u7528\u7387\u4e3a 50% \u4f5c\u4e3a\u89e6\u53d1\u81ea\u52a8\u7f29\u653e\u7684\u9608\u503c\uff0c\u6700\u5c0f\u526f\u672c\u6570\u4e3a 2 \uff0c\u6700\u5927\u526f\u672c\u6570\u4e3a 10 \u3002 \u4f7f\u7528\u4ee5\u4e0b\u547d\u4ee4\u521b\u5efa my-hpa HPA\uff1a kubectl autoscale deployment podinfo --cpu-percent = 50 --min = 2 --max = 10 --name = my-hpa kubectl autoscale deployment podinfo --cpu-percent = 50 --min = 1 --max = 10 \u4f7f\u7528 autoscaling/v1 \u7248\u672c\u7684\u6a21\u7248\u6765\u521b\u5efaHPA my-hpa \u3002 kubectl apply -f - << body >< h1 > It works! \u5220\u9664\u6f14\u793a\u4e2d\u521b\u5efa\u7684\u4e34\u65f6\u8d44\u6e90\u3002 kubectl delete ingress demo-localhost kubectl delete service demo kubectl delete deployment demo \u521b\u5efaDeployments \u00b6 \u521b\u5efa2\u4e2adeployment nginx-app-1 \u548c nginx-app-2 \u3002 kubectl apply -f - << EOF apiVersion: apps/v1 kind: Deployment metadata: name: nginx-app-1 spec: selector: matchLabels: app: nginx-app-1 replicas: 1 template: metadata: labels: app: nginx-app-1 spec: containers: - name: nginx image: nginx ports: - containerPort: 80 volumeMounts: - name: html mountPath: /usr/share/nginx/html volumes: - name: html hostPath: path: /opt/html-1 --- apiVersion: apps/v1 kind: Deployment metadata: name: nginx-app-2 spec: selector: matchLabels: app: nginx-app-2 replicas: 1 template: metadata: labels: app: nginx-app-2 spec: containers: - name: nginx image: nginx ports: - containerPort: 80 volumeMounts: - name: html mountPath: /usr/share/nginx/html volumes: - name: html hostPath: path: /opt/html-2 EOF \u6267\u884c\u547d\u4ee4 kubectl get pod -o wide \u6765\u83b7\u53d6pod\u7684\u72b6\u6001\u3002 \u53ef\u4ee5\u770b\u5230\u4e00\u4e2apod\u8fd0\u884c\u5728\u8282\u70b9 cka002 \uff0c\u53e6\u5916\u4e00\u4e2apod\u8fd0\u884c\u5728\u8282\u70b9 cka003 \u3002 Directory /opt/html-2/ is on cka002 Directory /opt/html-1/ is on cka002 \u901a\u8fc7 curl \u547d\u4ee4\u6765\u8bbf\u95ee\u8fd92\u4e2apod\uff0c\u6536\u5230 403 Forbidden \u9519\u8bef\u3002 curl 10 .244.102.13 curl 10 .244.112.19 \u767b\u5f55\u5230\u8282\u70b9 cka002 \uff0c\u6267\u884c\u4e0b\u9762\u547d\u4ee4\uff0c\u5728 /opt/html-2/ \u8def\u5f84\u4e0b\u521b\u5efa\u6587\u4ef6 index.html \u3002 cat < app1.com app2.com EOF \u6267\u884c\u4ee5\u4e0b\u547d\u4ee4\uff0c\u53ef\u4ee5\u5f97\u5230 IP \u5730\u5740\u6216 FQDN\u3002 kubectl get service ingress-nginx-controller --namespace = ingress-nginx \u5728\u8f93\u51fa\u7ed3\u679c\u4e2d\u53ef\u4ee5\u770b\u5230 EXTERNAL-IP \u5b57\u6bb5\u3002\u5982\u679c\u8be5\u5b57\u6bb5\u50cf\u4e0b\u9762\u4e00\u6837\u663e\u793a\u4e3a \uff0c\u8fd9\u610f\u5473\u7740 Kubernetes \u96c6\u7fa4\u65e0\u6cd5\u63d0\u4f9b\u8d1f\u8f7d\u5747\u8861\u5668\uff08\u901a\u5e38\u662f\u56e0\u4e3a\u5b83\u4e0d\u652f\u6301 LoadBalancer \u7c7b\u578b\u7684\u670d\u52a1\uff09\u3002 \u7531\u4e8e\u6ca1\u6709\u914d\u7f6e\u963f\u91cc\u4e91 ELB\uff0c\u56e0\u6b64\u6709\u4ee5\u4e0b\u4e24\u4e2a\u9009\u9879\u53ef\u4ee5\u89e3\u51b3\u8fd9\u4e2a\u95ee\u9898\u3002 \u9009\u9879 1\uff1a\u624b\u52a8\u5c06\u8282\u70b9 IP \u6dfb\u52a0\u5230\u8fd0\u884c ingress \u63a7\u5236\u5668\u7684\u8282\u70b9\u4e0a\u3002 \u6267\u884c\u547d\u4ee4 kubectl get pod -n ingress-nginx -o wide \u6765\u67e5\u770b ingress \u63a7\u5236\u5668 pod \u8fd0\u884c\u5728\u54ea\u4e2a\u8282\u70b9\u4e0a\u3002 \u624b\u52a8\u5c06 cka003 \u7684\u5916\u90e8 IP \u8865\u4e01\u5230 EXTERNAL-IP \u5b57\u6bb5\u3002 kubectl patch svc ingress-nginx-controller \\ --namespace = ingress-nginx \\ -p '{\"spec\": {\"type\": \"LoadBalancer\", \"externalIPs\":[\"\"]}}' \u9009\u9879 2\uff1a\u5c06 ingress \u63a7\u5236\u5668\u4ece LoadBalancer \u7c7b\u578b\u66f4\u6539\u4e3a NodePort \u7c7b\u578b\u3002 \u4e24\u4e2a Pod \u4e2d\u5404\u6709\u4e00\u4e2a index.html \u6587\u4ef6\uff0cWeb \u670d\u52a1\u901a\u8fc7\u8282\u70b9 IP \u5bf9\u5916\u66b4\u9732\u3002 ingress-nginx-controller \u4f5c\u4e3a\u4e2d\u5fc3\u5165\u53e3\u70b9\uff0c\u4e3a\u6765\u81ea Pod \u7684\u4e0d\u540c\u540e\u7aef\u670d\u52a1\u63d0\u4f9b\u4e86\u4e24\u4e2a\u7aef\u53e3\u3002 \u53d1\u9001HTTP\u8bf7\u6c42\u5230\u5728Ingress\u4e2d\u5b9a\u4e49\u76842\u4e2a\u4e3b\u673a\u8282\u70b9\u3002 curl http://app1.com:30011 curl http://app2.com:30011 curl app1.com:30011 curl app2.com:30011 \u53ef\u4ee5\u5f97\u5230\u4e0b\u9762\u7684\u4fe1\u606f\uff0c\u8bf4\u660e\u8bbf\u95ee\u6210\u529f\u3002 This is test 1 !! This is test 2 !! \u5220\u9664\u4e0a\u9762\u6f14\u793a\u4e2d\u521b\u5efa\u7684\u4e34\u65f6\u8d44\u6e90\u3002 kubectl delete ingress ingress-nginx-app kubectl delete service nginx-app-1 kubectl delete service nginx-app-2 kubectl delete deployment nginx-app-1 kubectl delete deployment nginx-app-2","title":"Ingress-nginx"},{"location":"k8s/cka_cn/foundamentals/ingress/#cka19ingress-nginx","text":"\u6f14\u793a\u573a\u666f\uff1a \u90e8\u7f72Ingress Controller\u3002 \u521b\u5efa\u4e24\u4e2aDeployment nginx-app-1 \u548c nginx-app-2 \u3002 \u5728\u8fd0\u884c\u4e3b\u673a\u4e0a\u521b\u5efa\u4e3b\u673a\u76ee\u5f55 /root/html-1 \u548c /root/html-2 \u5e76\u6302\u8f7d\u5230\u4e24\u4e2aDeployment\u4e0a\u3002 \u521b\u5efaService\u3002 \u521b\u5efaService nginx-app-1 \u548c nginx-app-2 \u5e76\u5c06\u5176\u6620\u5c04\u5230\u76f8\u5173\u7684Deployment nginx-app-1 \u548c nginx-app-2 \u3002 \u521b\u5efaIngress\u3002 \u521b\u5efaIngress\u8d44\u6e90 nginx-app \u5e76\u5c06\u5176\u6620\u5c04\u5230\u4e24\u4e2aServices nginx-app-1 \u548c nginx-app-1 \u3002 \u6d4b\u8bd5\u53ef\u8bbf\u95ee\u6027\u3002 \u5411Ingress\u4e2d\u5b9a\u4e49\u7684\u4e24\u4e2a\u4e3b\u673a\u53d1\u9001HTTP\u8bf7\u6c42\u3002 \u53c2\u8003\uff1a Github ingress-nginx Installation Guide","title":"CKA\u81ea\u5b66\u7b14\u8bb019:Ingress-nginx"},{"location":"k8s/cka_cn/foundamentals/ingress/#ingress","text":"\u83b7\u53d6Ingress\u63a7\u5236\u5668\u7684yaml\u6587\u4ef6\u3002\u6700\u65b0\u7248\u672c\u7684\u94fe\u63a5\u5728 \u5b89\u88c5\u6307\u5357 \u4e2d\u3002 wget https://raw.githubusercontent.com/kubernetes/ingress-nginx/controller-v1.3.0/deploy/static/provider/cloud/deploy.yaml \u4fee\u6539 deploy.yaml \u6587\u4ef6\u4e2d\u955c\u50cf\u6e90\u4e3a\u963f\u91cc\u4e91\u7684\u6e90\u3002 deploy.yaml \u6587\u4ef6\u4e2d\u9700\u8981\u4fee\u6539\u7684\u884c\uff1a image : k8s.gcr.io/ingress-nginx/controller:v1.2.1@sha256:5516d103a9c2ecc4f026efbd4b40662ce22dc1f824fb129ed121460aaa5c47f8 image : registry.k8s.io/ingress-nginx/controller:v1.3.0@sha256:d1707ca76d3b044ab8a28277a2466a02100ee9f58a86af1535a3edf9323ea1b5 image : k8s.gcr.io/ingress-nginx/kube-webhook-certgen:v1.1.1@sha256:64d8c73dca984af206adf9d6d7e46aa550362b1d7a01f3a0a91b20cc67868660 \u4fee\u6539\u5185\u5bb9\uff1a k8s.gcr.io/ingress-nginx/controller \u6539\u4e3a registry.aliyuncs.com/google_containers/nginx-ingress-controller \u3002 registry.k8s.io/ingress-nginx/controller \u6539\u4e3a registry.aliyuncs.com/google_containers/nginx-ingress-controller \u3002 k8s.gcr.io/ingress-nginx/kube-webhook-certgen \u6539\u4e3a registry.aliyuncs.com/google_containers/kube-webhook-certgen \u3002 \u4fee\u6539\u547d\u4ee4\uff1a sed -i 's/k8s.gcr.io\\/ingress-nginx\\/kube-webhook-certgen/registry.aliyuncs.com\\/google\\_containers\\/kube-webhook-certgen/g' deploy.yaml sed -i 's/k8s.gcr.io\\/ingress-nginx\\/controller/registry.aliyuncs.com\\/google\\_containers\\/nginx-ingress-controller/g' deploy.yaml \u5e94\u7528\u6587\u4ef6 deploy.yaml \u6765\u521b\u5efa Ingress Nginx\u3002 \u4e00\u4e2a\u65b0\u7684\u547d\u540d\u7a7a\u95f4namespace ingress-nginx \u4f1a\u88ab\u521b\u5efa\uff0cIngress Nginx\u76f8\u5173\u7684\u8d44\u6e90\u8fd0\u884c\u5728\u8fd9\u4e2anamespace\u4e0a\u3002 kubectl apply -f deploy.yaml \u67e5\u770bPod\u7684\u72b6\u6001\u3002 kubectl get pod -n ingress-nginx \u786e\u4fdd\u6240\u4ee5pod\u7684\u8fd0\u884c\u72b6\u6001\u90fd\u6b63\u5e38\uff0c\u7c7b\u4f3c\u5982\u4e0b\u7ed3\u679c\uff1a NAME READY STATUS RESTARTS AGE ingress-nginx-admission-create-lgtdj 0/1 Completed 0 49s ingress-nginx-admission-patch-nk9fv 0/1 Completed 0 49s ingress-nginx-controller-556fbd6d6f-6jl4x 1/1 Running 0 49s","title":"\u90e8\u7f72Ingress\u63a7\u5236\u5668"},{"location":"k8s/cka_cn/foundamentals/ingress/#_1","text":"\u8ba9\u6211\u4eec\u521b\u5efa\u4e00\u4e2a\u7b80\u5355\u7684 Web \u670d\u52a1\u5668\u548c\u76f8\u5173\u7684\u670d\u52a1\uff1a kubectl create deployment demo --image = httpd --port = 80 kubectl expose deployment demo \u63a5\u4e0b\u6765\u521b\u5efa\u4e00\u4e2a Ingress \u8d44\u6e90\u3002\u4ee5\u4e0b\u793a\u4f8b\u4f7f\u7528\u5c06\u4e3b\u673a\u6620\u5c04\u5230 localhost: kubectl create ingress demo-localhost --class = nginx --rule = \"demo.localdev.me/*=demo:80\" \u73b0\u5728\uff0c\u5c06\u672c\u5730\u7aef\u53e3\u8f6c\u53d1\u5230Ingress\u63a7\u5236\u5668\uff1a kubectl port-forward --namespace = ingress-nginx service/ingress-nginx-controller 8080 :80 \u73b0\u5728\uff0c\u5728\u53e6\u4e00\u4e2a\u7ec8\u7aef\u4e2d\u8bbf\u95ee http://demo.localdev.me:8080/ \uff0c\u6211\u4eec\u5e94\u8be5\u770b\u5230\u4e00\u4e2a HTML \u9875\u9762\uff0c\u4e0a\u9762\u5199\u7740 \"It works!\"\u3002 curl http://demo.localdev.me:8080/ \u8fd0\u884c\u7ed3\u679c\uff1b < html >< body >< h1 > It works! \u5220\u9664\u6f14\u793a\u4e2d\u521b\u5efa\u7684\u4e34\u65f6\u8d44\u6e90\u3002 kubectl delete ingress demo-localhost kubectl delete service demo kubectl delete deployment demo","title":"\u672c\u5730\u6d4b\u8bd5\u65b9\u5f0f"},{"location":"k8s/cka_cn/foundamentals/ingress/#deployments","text":"\u521b\u5efa2\u4e2adeployment nginx-app-1 \u548c nginx-app-2 \u3002 kubectl apply -f - << EOF apiVersion: apps/v1 kind: Deployment metadata: name: nginx-app-1 spec: selector: matchLabels: app: nginx-app-1 replicas: 1 template: metadata: labels: app: nginx-app-1 spec: containers: - name: nginx image: nginx ports: - containerPort: 80 volumeMounts: - name: html mountPath: /usr/share/nginx/html volumes: - name: html hostPath: path: /opt/html-1 --- apiVersion: apps/v1 kind: Deployment metadata: name: nginx-app-2 spec: selector: matchLabels: app: nginx-app-2 replicas: 1 template: metadata: labels: app: nginx-app-2 spec: containers: - name: nginx image: nginx ports: - containerPort: 80 volumeMounts: - name: html mountPath: /usr/share/nginx/html volumes: - name: html hostPath: path: /opt/html-2 EOF \u6267\u884c\u547d\u4ee4 kubectl get pod -o wide \u6765\u83b7\u53d6pod\u7684\u72b6\u6001\u3002 \u53ef\u4ee5\u770b\u5230\u4e00\u4e2apod\u8fd0\u884c\u5728\u8282\u70b9 cka002 \uff0c\u53e6\u5916\u4e00\u4e2apod\u8fd0\u884c\u5728\u8282\u70b9 cka003 \u3002 Directory /opt/html-2/ is on cka002 Directory /opt/html-1/ is on cka002 \u901a\u8fc7 curl \u547d\u4ee4\u6765\u8bbf\u95ee\u8fd92\u4e2apod\uff0c\u6536\u5230 403 Forbidden \u9519\u8bef\u3002 curl 10 .244.102.13 curl 10 .244.112.19 \u767b\u5f55\u5230\u8282\u70b9 cka002 \uff0c\u6267\u884c\u4e0b\u9762\u547d\u4ee4\uff0c\u5728 /opt/html-2/ \u8def\u5f84\u4e0b\u521b\u5efa\u6587\u4ef6 index.html \u3002 cat < app1.com app2.com EOF \u6267\u884c\u4ee5\u4e0b\u547d\u4ee4\uff0c\u53ef\u4ee5\u5f97\u5230 IP \u5730\u5740\u6216 FQDN\u3002 kubectl get service ingress-nginx-controller --namespace = ingress-nginx \u5728\u8f93\u51fa\u7ed3\u679c\u4e2d\u53ef\u4ee5\u770b\u5230 EXTERNAL-IP \u5b57\u6bb5\u3002\u5982\u679c\u8be5\u5b57\u6bb5\u50cf\u4e0b\u9762\u4e00\u6837\u663e\u793a\u4e3a \uff0c\u8fd9\u610f\u5473\u7740 Kubernetes \u96c6\u7fa4\u65e0\u6cd5\u63d0\u4f9b\u8d1f\u8f7d\u5747\u8861\u5668\uff08\u901a\u5e38\u662f\u56e0\u4e3a\u5b83\u4e0d\u652f\u6301 LoadBalancer \u7c7b\u578b\u7684\u670d\u52a1\uff09\u3002 \u7531\u4e8e\u6ca1\u6709\u914d\u7f6e\u963f\u91cc\u4e91 ELB\uff0c\u56e0\u6b64\u6709\u4ee5\u4e0b\u4e24\u4e2a\u9009\u9879\u53ef\u4ee5\u89e3\u51b3\u8fd9\u4e2a\u95ee\u9898\u3002 \u9009\u9879 1\uff1a\u624b\u52a8\u5c06\u8282\u70b9 IP \u6dfb\u52a0\u5230\u8fd0\u884c ingress \u63a7\u5236\u5668\u7684\u8282\u70b9\u4e0a\u3002 \u6267\u884c\u547d\u4ee4 kubectl get pod -n ingress-nginx -o wide \u6765\u67e5\u770b ingress \u63a7\u5236\u5668 pod \u8fd0\u884c\u5728\u54ea\u4e2a\u8282\u70b9\u4e0a\u3002 \u624b\u52a8\u5c06 cka003 \u7684\u5916\u90e8 IP \u8865\u4e01\u5230 EXTERNAL-IP \u5b57\u6bb5\u3002 kubectl patch svc ingress-nginx-controller \\ --namespace = ingress-nginx \\ -p '{\"spec\": {\"type\": \"LoadBalancer\", \"externalIPs\":[\"\"]}}' \u9009\u9879 2\uff1a\u5c06 ingress \u63a7\u5236\u5668\u4ece LoadBalancer \u7c7b\u578b\u66f4\u6539\u4e3a NodePort \u7c7b\u578b\u3002 \u4e24\u4e2a Pod \u4e2d\u5404\u6709\u4e00\u4e2a index.html \u6587\u4ef6\uff0cWeb \u670d\u52a1\u901a\u8fc7\u8282\u70b9 IP \u5bf9\u5916\u66b4\u9732\u3002 ingress-nginx-controller \u4f5c\u4e3a\u4e2d\u5fc3\u5165\u53e3\u70b9\uff0c\u4e3a\u6765\u81ea Pod \u7684\u4e0d\u540c\u540e\u7aef\u670d\u52a1\u63d0\u4f9b\u4e86\u4e24\u4e2a\u7aef\u53e3\u3002 \u53d1\u9001HTTP\u8bf7\u6c42\u5230\u5728Ingress\u4e2d\u5b9a\u4e49\u76842\u4e2a\u4e3b\u673a\u8282\u70b9\u3002 curl http://app1.com:30011 curl http://app2.com:30011 curl app1.com:30011 curl app2.com:30011 \u53ef\u4ee5\u5f97\u5230\u4e0b\u9762\u7684\u4fe1\u606f\uff0c\u8bf4\u660e\u8bbf\u95ee\u6210\u529f\u3002 This is test 1 !! This is test 2 !! \u5220\u9664\u4e0a\u9762\u6f14\u793a\u4e2d\u521b\u5efa\u7684\u4e34\u65f6\u8d44\u6e90\u3002 kubectl delete ingress ingress-nginx-app kubectl delete service nginx-app-1 kubectl delete service nginx-app-2 kubectl delete deployment nginx-app-1 kubectl delete deployment nginx-app-2","title":"\u53ef\u8bbf\u95ee\u6027\u6d4b\u8bd5"},{"location":"k8s/cka_cn/foundamentals/job/","text":"CKA\u81ea\u5b66\u7b14\u8bb014:Job and Cronjob \u00b6 Job \u00b6 \u6f14\u793a\u573a\u666f\uff1a \u521b\u5efaJob\u3002 \u6f14\u793a\uff1a \u521b\u5efaJob pi \u3002 kubectl apply -f - << EOF apiVersion: batch/v1 kind: Job metadata: name: pi spec: template: spec: containers: - name: pi image: perl:5.34 command: [\"perl\", \"-Mbignum=bpi\", \"-wle\", \"print bpi(2000)\"] restartPolicy: Never backoffLimit: 4 EOF \u83b7\u53d6Job\u7684\u8be6\u7ec6\u4fe1\u606f\u3002 kubectl get jobs \u83b7\u53d6Job\u7684Pod\u7684\u8be6\u7ec6\u4fe1\u606f\u3002 Completed \u7684\u72b6\u6001\u4ee3\u8868\u8fd9\u4e2ajob\u5df2\u7ecf\u6210\u529f\u5b8c\u6210\u4e86\u3002 kubectl get pod \u83b7\u53d6Job\u7684Pod\u7684\u65e5\u5fd7\u4fe1\u606f\u3002 kubectl pi-2s74d 3 .141592653589793.............. \u5220\u9664\u6240\u521b\u5efa\u7684\u8d44\u6e90\u3002 kubectl delete job pi Cronjob \u00b6 \u6f14\u793a\u573a\u666f\uff1a \u521b\u5efaCronjob\u3002 \u6f14\u793a\uff1a \u521b\u5efaCronjob hello \u3002 kubectl apply -f - << EOF apiVersion: batch/v1 kind: CronJob metadata: name: hello spec: schedule: \"*/1 * * * *\" jobTemplate: spec: template: spec: containers: - name: hello image: busybox args: - /bin/sh - -c - date ; echo Hello from the kubernetes cluster restartPolicy: OnFailure EOF \u83b7\u53d6Cronjob\u7684\u8be6\u7ec6\u4fe1\u606f\u3002 kubectl get cronjobs -o wide \u8fd0\u884c\u7ed3\u679c NAME SCHEDULE SUSPEND ACTIVE LAST SCHEDULE AGE CONTAINERS IMAGES SELECTOR hello */1 * * * * False 0 25s hello busybox \u76d1\u63a7Jobs\u3002\u6bcf\u96941\u5206\u949f\uff0c\u4e00\u4e2a\u65b0\u7684job\u4f1a\u88ab\u521b\u5efa\u3002 kubectl get jobs -w \u5220\u9664\u521b\u5efa\u7684\u8d44\u6e90\u3002 kubectl delete cronjob hello","title":"Job and Cronjob"},{"location":"k8s/cka_cn/foundamentals/job/#cka14job-and-cronjob","text":"","title":"CKA\u81ea\u5b66\u7b14\u8bb014:Job and Cronjob"},{"location":"k8s/cka_cn/foundamentals/job/#job","text":"\u6f14\u793a\u573a\u666f\uff1a \u521b\u5efaJob\u3002 \u6f14\u793a\uff1a \u521b\u5efaJob pi \u3002 kubectl apply -f - << EOF apiVersion: batch/v1 kind: Job metadata: name: pi spec: template: spec: containers: - name: pi image: perl:5.34 command: [\"perl\", \"-Mbignum=bpi\", \"-wle\", \"print bpi(2000)\"] restartPolicy: Never backoffLimit: 4 EOF \u83b7\u53d6Job\u7684\u8be6\u7ec6\u4fe1\u606f\u3002 kubectl get jobs \u83b7\u53d6Job\u7684Pod\u7684\u8be6\u7ec6\u4fe1\u606f\u3002 Completed \u7684\u72b6\u6001\u4ee3\u8868\u8fd9\u4e2ajob\u5df2\u7ecf\u6210\u529f\u5b8c\u6210\u4e86\u3002 kubectl get pod \u83b7\u53d6Job\u7684Pod\u7684\u65e5\u5fd7\u4fe1\u606f\u3002 kubectl pi-2s74d 3 .141592653589793.............. \u5220\u9664\u6240\u521b\u5efa\u7684\u8d44\u6e90\u3002 kubectl delete job pi","title":"Job"},{"location":"k8s/cka_cn/foundamentals/job/#cronjob","text":"\u6f14\u793a\u573a\u666f\uff1a \u521b\u5efaCronjob\u3002 \u6f14\u793a\uff1a \u521b\u5efaCronjob hello \u3002 kubectl apply -f - << EOF apiVersion: batch/v1 kind: CronJob metadata: name: hello spec: schedule: \"*/1 * * * *\" jobTemplate: spec: template: spec: containers: - name: hello image: busybox args: - /bin/sh - -c - date ; echo Hello from the kubernetes cluster restartPolicy: OnFailure EOF \u83b7\u53d6Cronjob\u7684\u8be6\u7ec6\u4fe1\u606f\u3002 kubectl get cronjobs -o wide \u8fd0\u884c\u7ed3\u679c NAME SCHEDULE SUSPEND ACTIVE LAST SCHEDULE AGE CONTAINERS IMAGES SELECTOR hello */1 * * * * False 0 25s hello busybox \u76d1\u63a7Jobs\u3002\u6bcf\u96941\u5206\u949f\uff0c\u4e00\u4e2a\u65b0\u7684job\u4f1a\u88ab\u521b\u5efa\u3002 kubectl get jobs -w \u5220\u9664\u521b\u5efa\u7684\u8d44\u6e90\u3002 kubectl delete cronjob hello","title":"Cronjob"},{"location":"k8s/cka_cn/foundamentals/memo/","text":"CKA\u81ea\u5b66\u7b14\u8bb05:Kubernetes\u968f\u7b14 \u00b6 \u6458\u8981 \u00b6 \u8fb9\u7ec3\u4e60\u8fb9\u8bb0\u5f55\u7684\u5185\u5bb9\uff0c\u4e0d\u662f\u5168\u9762\u7cfb\u7edf\u7684\uff0c\u5305\u62ec\u4e0b\u9762\u4e3b\u8981\u5185\u5bb9\uff1a Kubernetes\u57fa\u672c\u6982\u5ff5 \u7ec4\u4ef6 API \u5bf9\u8c61 \u8d44\u6e90 \u5de5\u4f5c\u8d1f\u8f7d\u8d44\u6e90 Pod Deployment ReplicaSet StatefulSet DaemonSet Job CronJob \u670d\u52a1\u8d44\u6e90 Service Endpoints \u914d\u7f6e\u548c\u5b58\u50a8\u8d44\u6e90 \u5377 Storage Class PV Access Modes Kubernetes\u57fa\u672c\u6982\u5ff5 \u00b6 Kubernetes\u7ec4\u4ef6 \u00b6 \u4e00\u4e2aKubernetes\u96c6\u7fa4\u7531\u4ee3\u8868\u63a7\u5236\u5e73\u9762\uff08control plane\uff09\u7684\u7ec4\u4ef6\u548c\u4e00\u7ec4\u79f0\u4e3a\u8282\u70b9\uff08nodes\uff09\u7684\u673a\u5668\u7ec4\u6210\u3002 Kubernetes\u7ec4\u4ef6: \u63a7\u5236\u5e73\u9762\u7ec4\u4ef6 Control Plane Components kube-apiserver: \u67e5\u8be2\u548c\u64cd\u4f5c Kubernetes \u4e2d\u5bf9\u8c61\u7684\u72b6\u6001\u3002 \u5145\u5f53\u6240\u6709\u8d44\u6e90\u4e4b\u95f4\u7684\u901a\u4fe1\u4e2d\u5fc3\uff08communication hub\uff09\u3002 \u63d0\u4f9b\u96c6\u7fa4\u5b89\u5168\u8eab\u4efd\u9a8c\u8bc1\u3001\u6388\u6743\u548c\u89d2\u8272\u5206\u914d\u3002 \u662f\u552f\u4e00\u80fd\u8fde\u63a5\u5230 etcd \u7684\u7ec4\u4ef6\u3002 etcd: \u6240\u6709 Kubernetes \u5bf9\u8c61\u90fd\u5b58\u50a8\u5728 etcd \u4e2d\u3002 Kubernetes \u5bf9\u8c61\u662f Kubernetes \u7cfb\u7edf\u4e2d\u7684\u6301\u4e45\u5b9e\u4f53(entities)\uff0c\u7528\u4e8e\u8868\u793a\u96c6\u7fa4\u7684\u72b6\u6001\u3002 kube-scheduler: \u76d1\u89c6\u6ca1\u6709\u5206\u914d\u8282\u70b9\u7684\u65b0\u521b\u5efa\u7684 Pod\uff0c\u5e76\u4e3a\u5b83\u4eec\u9009\u62e9\u4e00\u4e2a\u8282\u70b9\u6765\u8fd0\u884c\u3002 kube-controller-manager: \u8fd0\u884c\u63a7\u5236\u5668\u8fdb\u7a0b\u3002 Node controller : \u8d1f\u8d23\u8b66\u793a\u548c\u54cd\u5e94\u8282\u70b9\u7684\u6545\u969c\u3002 Job controller : \u76d1\u89c6\u8868\u793a\u4e00\u6b21\u6027\u4efb\u52a1\u7684 Job \u5bf9\u8c61\uff0c\u7136\u540e\u521b\u5efa Pod \u6765\u5b8c\u6210\u8fd9\u4e9b\u4efb\u52a1\u3002 Endpoints controller : \u586b\u5145 Endpoints \u5bf9\u8c61\uff08\u5373\u5c06 Service \u548c Pod \u8fde\u63a5\u8d77\u6765\uff09\u3002 Service Account & Token controllers : \u4e3a\u65b0\u547d\u540d\u7a7a\u95f4\u521b\u5efa\u9ed8\u8ba4\u5e10\u6237\u548c API \u8bbf\u95ee\u4ee4\u724c\u3002 cloud-controller-manager: \u5d4c\u5165\u4e91\u7279\u5b9a\u7684\u63a7\u5236\u903b\u8f91\uff0c\u4ec5\u8fd0\u884c\u7279\u5b9a\u4e8e\u6211\u4eec\u9009\u62e9\u7684\u4e91\u63d0\u4f9b\u5546\u7684\u63a7\u5236\u5668\uff0c\u65e0\u9700\u81ea\u5df1\u7684\u57fa\u7840\u8bbe\u65bd\u548c\u5b66\u4e60\u73af\u5883\u3002 Node controller : \u7528\u4e8e\u68c0\u67e5\u4e91\u63d0\u4f9b\u5546\uff0c\u4ee5\u786e\u5b9a\u8282\u70b9\u5728\u5728\u5b83\u505c\u6b62\u54cd\u5e94\u540e\u662f\u5426\u5df2\u5728\u4e91\u4e2d\u88ab\u5220\u9664\u3002 Route controller : \u7528\u4e8e\u5728\u5e95\u5c42\u4e91\u57fa\u7840\u67b6\u6784\u4e2d\u8bbe\u7f6e\u8def\u7531\u3002 Service controller : \u7528\u4e8e\u521b\u5efa\u3001\u66f4\u65b0\u548c\u5220\u9664\u4e91\u63d0\u4f9b\u5546\u8d1f\u8f7d\u5747\u8861\u5668\u3002 \u8282\u70b9\u7ec4\u4ef6 Node Components kubelet: \u5728\u96c6\u7fa4\u4e2d\u6bcf\u4e2a\u8282\u70b9\u4e0a\u8fd0\u884c\u7684\u4ee3\u7406\u3002 \u7ba1\u7406\u8282\u70b9\u3002\u5b83\u786e\u4fdd Pod \u4e2d\u8fd0\u884c\u5bb9\u5668\u3002 kubelet \u5411 APIServer \u6ce8\u518c\u548c\u66f4\u65b0\u8282\u70b9\u4fe1\u606f\uff0cAPIServer \u5c06\u5b83\u4eec\u5b58\u50a8\u5230 etcd \u4e2d\u3002 \u7ba1\u7406 Pod\u3002\u901a\u8fc7 APIServer \u76d1\u89c6 Pod\uff0c\u5e76\u5bf9 Pod \u6216 Pod \u4e2d\u7684\u5bb9\u5668\u91c7\u53d6\u884c\u52a8\u3002 \u5728\u5bb9\u5668\u7ea7\u522b\u8fdb\u884c\u5065\u5eb7\u68c0\u67e5\u3002 kube-proxy: \u662f\u5728\u96c6\u7fa4\u4e2d\u6bcf\u4e2a\u8282\u70b9\u4e0a\u8fd0\u884c\u7684\u7f51\u7edc\u4ee3\u7406\u3002 iptables ipvs \u7ef4\u62a4\u8282\u70b9\u4e0a\u7684\u7f51\u7edc\u89c4\u5219\u3002 \u5bb9\u5668\u8fd0\u884c\u65f6Container runtime\uff1a \u8d1f\u8d23\u8fd0\u884c\u5bb9\u5668\u7684\u8f6f\u4ef6\u3002 \u63d2\u4ef6Addons DNS: \u662f DNS \u670d\u52a1\u5668\uff0c\u662f\u6240\u6709 Kubernetes \u96c6\u7fa4\u6240\u5fc5\u9700\u7684\u3002 Web UI\uff08\u4eea\u8868\u76d8\uff09\uff1a\u7528\u4e8e Kubernetes \u96c6\u7fa4\u7684\u57fa\u4e8e Web \u7684\u7528\u6237\u754c\u9762\u3002 \u5bb9\u5668\u8d44\u6e90\u76d1\u63a7\uff1a\u8bb0\u5f55\u6709\u5173\u96c6\u4e2d\u5f0f\u6570\u636e\u5e93\u4e2d\u5bb9\u5668\u7684\u901a\u7528\u65f6\u95f4\u5e8f\u5217\u5ea6\u91cf\u3002 Cluster-level Logging\uff1a\u8d1f\u8d23\u5c06\u5bb9\u5668\u65e5\u5fd7\u4fdd\u5b58\u5230\u5177\u6709\u641c\u7d22/\u6d4f\u89c8\u63a5\u53e3\u7684\u4e2d\u592e\u65e5\u5fd7\u5b58\u50a8\u4e2d\u3002 \u53ef\u6269\u5c55\u6027\uff1a \u6c34\u5e73\u6269\u5c55\uff08Scaling out\uff09\u901a\u8fc7\u6dfb\u52a0\u66f4\u591a\u7684\u670d\u52a1\u5668\u5230\u67b6\u6784\u4e2d\uff0c\u5c06\u5de5\u4f5c\u8d1f\u8f7d\u5206\u6563\u5230\u66f4\u591a\u7684\u673a\u5668\u4e0a\u3002 \u5782\u76f4\u6269\u5c55\uff08Scaling up\uff09\u901a\u8fc7\u6dfb\u52a0\u66f4\u591a\u7684\u786c\u76d8\u548c\u5185\u5b58\u6765\u589e\u52a0\u7269\u7406\u670d\u52a1\u5668\u7684\u8ba1\u7b97\u80fd\u529b\u3002 Kubernetes API \u00b6 REST API\u662fKubernetes\u7684\u57fa\u672c\u6846\u67b6\u3002\u6240\u6709\u7ec4\u4ef6\u4e4b\u95f4\u7684\u64cd\u4f5c\u548c\u901a\u4fe1\uff0c\u4ee5\u53ca\u5916\u90e8\u7528\u6237\u547d\u4ee4\u90fd\u662f\u7531API\u670d\u52a1\u5668\u5904\u7406\u7684REST API\u8c03\u7528\u3002\u56e0\u6b64\uff0cKubernetes\u5e73\u53f0\u4e2d\u7684\u6240\u6709\u5185\u5bb9\u90fd\u88ab\u89c6\u4e3aAPI\u5bf9\u8c61\uff08API object\uff09\uff0c\u5e76\u5728API\u4e2d\u6709\u76f8\u5e94\u7684\u6761\u76ee\u3002 Kubernetes\u63a7\u5236\u5e73\u9762\u7684\u6838\u5fc3\u662fAPI\u670d\u52a1\u5668\u3002 CRI\uff1a\u5bb9\u5668\u8fd0\u884c\u65f6\u63a5\u53e3 CNI\uff1a\u5bb9\u5668\u7f51\u7edc\u63a5\u53e3 CSI\uff1a\u5bb9\u5668\u5b58\u50a8\u63a5\u53e3 API\u670d\u52a1\u5668\u516c\u5f00\u4e86\u4e00\u4e2aHTTP API\uff0c\u5141\u8bb8\u6700\u7ec8\u7528\u6237\u3001\u96c6\u7fa4\u7684\u4e0d\u540c\u90e8\u5206\u548c\u5916\u90e8\u7ec4\u4ef6\u5f7c\u6b64\u901a\u4fe1\u3002 Kubernetes API\u5141\u8bb8\u6211\u4eec\u67e5\u8be2\u548c\u64cd\u4f5cKubernetes\u4e2dAPI\u5bf9\u8c61\u7684\u72b6\u6001\uff08\u4f8b\u5982\uff1aPod\u3001Namespace\u3001ConfigMap\u548cEvent\uff09\u3002 Kubernetes API\uff1a OpenAPI\u89c4\u8303 OpenAPI V2 OpenAPI V3 \u6301\u4e45\u6027\u3002Kubernetes\u901a\u8fc7\u5c06\u5bf9\u8c61\u7684\u5e8f\u5217\u5316\u72b6\u6001\u5199\u5165etcd\u6765\u5b58\u50a8\u5b83\u4eec\u3002 API\u7ec4\u548c\u7248\u672c\u63a7\u5236\u3002\u7248\u672c\u63a7\u5236\u662f\u5728API\u7ea7\u522b\u8fdb\u884c\u7684\u3002API\u8d44\u6e90\u901a\u8fc7\u5b83\u4eec\u7684API\u7ec4\u3001\u8d44\u6e90\u7c7b\u578b\u3001\u547d\u540d\u7a7a\u95f4\uff08\u7528\u4e8e\u547d\u540d\u7a7a\u95f4\u8d44\u6e90\uff09\u548c\u540d\u79f0\u8fdb\u884c\u533a\u5206\u3002 API\u66f4\u6539 API\u6269\u5c55 API Version \u00b6 API\u7248\u672c\u548c\u8f6f\u4ef6\u7248\u672c\u95f4\u5b58\u5728\u95f4\u63a5\u5173\u7cfb\u3002API\u548c\u53d1\u5e03\u7248\u672c\u8ba1\u5212\u63cf\u8ff0\u4e86API\u7248\u672c\u548c\u8f6f\u4ef6\u7248\u672c\u4e4b\u95f4\u7684\u5173\u7cfb\u3002\u4e0d\u540c\u7684API\u7248\u672c\u8868\u793a\u4e0d\u540c\u7684\u7a33\u5b9a\u6027\u548c\u652f\u6301\u7ea7\u522b\u3002 \u4ee5\u4e0b\u662f\u6bcf\u4e2a\u7ea7\u522b\u7684\u6458\u8981\uff1a Alpha\uff1a \u7248\u672c\u540d\u79f0\u5305\u542balpha\uff08\u4f8b\u5982\uff0cv1alpha1\uff09\u3002 \u8f6f\u4ef6\u53ef\u80fd\u5305\u542b\u9519\u8bef\u3002\u542f\u7528\u529f\u80fd\u53ef\u80fd\u4f1a\u66b4\u9732\u9519\u8bef\u3002\u67d0\u4e9b\u529f\u80fd\u53ef\u80fd\u9ed8\u8ba4\u7981\u7528\u3002 \u5bf9\u4e8e\u67d0\u4e9b\u529f\u80fd\u7684\u652f\u6301\u53ef\u4ee5\u968f\u65f6\u53d6\u6d88\uff0c\u800c\u4e0d\u4f1a\u63d0\u524d\u901a\u77e5\u3002 API\u53ef\u80fd\u4f1a\u5728\u4ee5\u540e\u7684\u8f6f\u4ef6\u53d1\u5e03\u4e2d\u4ee5\u4e0d\u517c\u5bb9\u7684\u65b9\u5f0f\u66f4\u6539\uff0c\u800c\u4e0d\u4f1a\u63d0\u524d\u901a\u77e5\u3002 \u7531\u4e8e\u9519\u8bef\u98ce\u9669\u589e\u52a0\u548c\u957f\u671f\u652f\u6301\u4e0d\u8db3\uff0c\u5efa\u8bae\u4ec5\u5728\u77ed\u6682\u7684\u6d4b\u8bd5\u96c6\u7fa4\u4e2d\u4f7f\u7528\u8be5\u8f6f\u4ef6\u3002 Beta\uff1a \u7248\u672c\u540d\u79f0\u5305\u542bbeta\uff08\u4f8b\u5982\uff0cv2beta3\uff09\u3002 \u8f6f\u4ef6\u7ecf\u8fc7\u5145\u5206\u6d4b\u8bd5\u3002\u542f\u7528\u529f\u80fd\u88ab\u8ba4\u4e3a\u662f\u5b89\u5168\u7684\u3002\u67d0\u4e9b\u529f\u80fd\u9ed8\u8ba4\u542f\u7528\u3002 \u5bf9\u4e8e\u67d0\u4e9b\u529f\u80fd\u7684\u652f\u6301\u4e0d\u4f1a\u53d6\u6d88\uff0c\u4f46\u7ec6\u8282\u53ef\u80fd\u4f1a\u66f4\u6539\u3002 \u5bf9\u8c61\u7684\u6a21\u5f0f\u548c/\u6216\u8bed\u4e49\u53ef\u80fd\u4f1a\u5728\u540e\u7eed\u7684Beta\u6216\u7a33\u5b9a\u7248\u53d1\u5e03\u4e2d\u4ee5\u4e0d\u517c\u5bb9\u7684\u65b9\u5f0f\u66f4\u6539\u3002\u5f53\u53d1\u751f\u8fd9\u79cd\u60c5\u51b5\u65f6\uff0c\u5c06\u63d0\u4f9b\u8fc1\u79fb\u8bf4\u660e\u3002\u6a21\u5f0f\u66f4\u6539\u53ef\u80fd\u9700\u8981\u5220\u9664\u3001\u7f16\u8f91\u548c\u91cd\u65b0\u521b\u5efa API\u5bf9\u8c61\u3002\u7f16\u8f91\u8fc7\u7a0b\u53ef\u80fd\u4e0d\u7b80\u5355\u3002\u8fc1\u79fb\u53ef\u80fd\u9700\u8981\u505c\u673a\uff0c\u4ee5\u4fbf\u4f9d\u8d56\u4e8e\u8be5\u529f\u80fd\u7684\u5e94\u7528\u7a0b\u5e8f\u3002 \u4e0d\u5efa\u8bae\u5c06\u8be5\u8f6f\u4ef6\u7528\u4e8e\u751f\u4ea7\u7528\u9014\u3002\u540e\u7eed\u7684\u53d1\u5e03\u53ef\u80fd\u4f1a\u5f15\u5165\u4e0d\u517c\u5bb9\u7684\u66f4\u6539\u3002\u5982\u679c\u60a8\u6709\u591a\u4e2a\u53ef\u4ee5\u72ec\u7acb\u5347\u7ea7\u7684\u96c6\u7fa4\uff0c\u5219\u53ef\u4ee5\u653e\u5bbd\u6b64\u9650\u5236\u3002 \u6ce8\u610f\uff1a\u8bf7\u5c1d\u8bd5beta\u529f\u80fd\u5e76\u63d0\u4f9b\u53cd\u9988\u3002\u529f\u80fd\u9000\u51fabeta\u540e\uff0c\u53ef\u80fd\u4e0d\u5b9e\u9645\u518d\u8fdb\u884c\u66f4\u6539\u3002 \u7a33\u5b9a\u7248\uff1a \u7248\u672c\u540d\u79f0\u4e3avX\uff0c\u5176\u4e2dX\u662f\u6574\u6570\u3002 \u529f\u80fd\u7684\u7a33\u5b9a\u7248\u672c\u51fa\u73b0\u5728\u53d1\u5e03\u7684\u8f6f\u4ef6\u4e2d\u7684\u8bb8\u591a\u540e\u7eed\u7248\u672c\u4e2d\u3002 \u8bfb\u53d6\u5f53\u524dAPI\u7684\u7248\u672c\u547d\u4ee4\uff1a kubectl api-resources API Group \u00b6 API\u7ec4\uff08API groups\uff09 \u4f7f\u6269\u5c55Kubernetes API\u66f4\u52a0\u5bb9\u6613\u3002API\u7ec4\u5728REST\u8def\u5f84\u548c\u5e8f\u5217\u5316\u5bf9\u8c61\u7684apiVersion\u5b57\u6bb5\u4e2d\u6307\u5b9a\u3002 Kubernetes\u6709\u51e0\u4e2aAPI\u7ec4\uff1a \u6838\u5fc3\u7ec4\uff08\u4e5f\u79f0\u4e3a\u9057\u7559legacy\uff09\u4f4d\u4e8eREST\u8def\u5f84 /api/v1 \u3002 \u6838\u5fc3\u7ec4\u4e0d\u4f5c\u4e3aapiVersion\u5b57\u6bb5\u7684\u4e00\u90e8\u5206\u6307\u5b9a\uff0c\u4f8b\u5982 apiVersion: v1\u3002 \u547d\u540d\u7ec4\u4f4d\u4e8eREST\u8def\u5f84 /apis/$GROUP_NAME/$VERSION \uff0c\u5e76\u4f7f\u7528 apiVersion: $GROUP_NAME/$VERSION \uff08\u4f8b\u5982 apiVersion: batch/v1\uff09\u3002 Kubernetes\u5bf9\u8c61 \u00b6 \u5bf9\u8c61\u6982\u8ff0 \u00b6 \u5bf9\u8c61\u89c4\u8303\uff08Object Spec\uff09\uff1a \u63d0\u4f9b\u4e86\u4e00\u4e2a\u63cf\u8ff0\u6240\u521b\u5efa\u8d44\u6e90\u7684\u7279\u6027\u7684\u8bf4\u660e\uff1a \u5176\u671f\u671b\u7684\u72b6\u6001 \u3002 \u5bf9\u8c61\u72b6\u6001\uff08Object Status\uff09\uff1a \u63cf\u8ff0\u4e86\u5bf9\u8c61\u7684\u5f53\u524d\u72b6\u6001\u3002 \u6bd4\u5982\uff0cDeployment\u662f\u4e00\u4e2a\u53ef\u4ee5\u4ee3\u8868\u96c6\u7fa4\u4e0a\u8fd0\u884c\u7684\u5e94\u7528\u7a0b\u5e8f\u7684\u5bf9\u8c61\u3002 apiVersion : apps/v1 # \u5f53\u524d\u7528\u6765\u521b\u5efa\u5bf9\u8c61\u7684API\u7248\u672c kind : Deployment # \u521b\u5efa\u5bf9\u8c61\u7684\u7c7b\u578b metadata : # \u7528\u6765\u533a\u5206\u5bf9\u8c61\u7684\u5143\u6570\u636e\uff0c\u6bd4\u5982\uff1a\u540d\u79f0\uff0cUID\uff0c\u547d\u540d\u7a7a\u95f4\u7b49 name : nginx-deployment spec : # \u671f\u671b\u6240\u521b\u5efa\u5bf9\u8c61\u7684\u72b6\u6001 selector : matchLabels : app : nginx replicas : 2 # \u544a\u8bc9Deployment\u57fa\u4e8e\u4e0b\u9762\u7684\u6a21\u677ftemplate\u521b\u5efa2\u4e2aPods template : metadata : labels : app : nginx spec : containers : - name : nginx image : nginx:1.14.2 ports : - containerPort : 80 \u5bf9\u8c61\u7ba1\u7406 \u00b6 kubectl \u547d\u4ee4\u884c\u5de5\u5177\u652f\u6301\u591a\u79cd\u4e0d\u540c\u7684\u65b9\u5f0f\u6765\u521b\u5efa\u548c\u7ba1\u7406 Kubernetes \u5bf9\u8c61\u3002\u8be6\u7ec6\u4fe1\u606f\u8bf7\u9605\u8bfb Kubectl book \u3002 \u4e00\u4e2a Kubernetes \u5bf9\u8c61\u5e94\u8be5\u4ec5\u4f7f\u7528\u4e00\u79cd\u6280\u672f\u8fdb\u884c\u7ba1\u7406\u3002\u6df7\u5408\u4f7f\u7528\u4e0d\u540c\u7684\u6280\u672f\u6765\u7ba1\u7406\u540c\u4e00\u4e2a\u5bf9\u8c61\u4f1a\u5bfc\u81f4\u975e\u9884\u671f\u7684\u7ed3\u679c\u3002 \u4e09\u79cd\u7ba1\u7406\u6280\u672f: \u547d\u4ee4\u5f0f\u547d\u4ee4 \u76f4\u63a5\u5728\u96c6\u7fa4\u4e2d\u64cd\u4f5c\u5b9e\u65f6\u5bf9\u8c61\u3002 kubectl create deployment nginx --image nginx \u547d\u4ee4\u5f0f\u5bf9\u8c61\u914d\u7f6e kubectl create -f nginx.yaml kubectl delete -f nginx.yaml -f redis.yaml kubectl replace -f nginx.yaml \u58f0\u660e\u5f0f\u5bf9\u8c61\u914d\u7f6e kubectl diff -f configs/ kubectl apply -f configs/ \u5bf9\u8c61\u540d\u79f0\u548cID \u00b6 \u96c6\u7fa4\u4e2d\u7684\u6bcf\u4e2a\u5bf9\u8c61\u90fd\u6709\u4e00\u4e2a\u5728\u8be5\u8d44\u6e90\u7c7b\u578b\u4e2d\u552f\u4e00\u7684\u540d\u79f0\u3002 DNS \u5b50\u57df\u540d \u6807\u7b7e\u540d\u79f0 \u8def\u5f84\u6bb5\u540d\u79f0 \u6bcf\u4e2a Kubernetes \u5bf9\u8c61\u8fd8\u6709\u4e00\u4e2a UID\uff0c\u5728\u6574\u4e2a\u96c6\u7fa4\u4e2d\u662f\u552f\u4e00\u7684\u3002 \u547d\u540d\u7a7a\u95f4 \u00b6 \u5728Kubernetes\u4e2d\uff0c\u547d\u540d\u7a7a\u95f4\u63d0\u4f9b\u4e86\u4e00\u79cd\u5728\u5355\u4e2a\u96c6\u7fa4\u5185\u9694\u79bb\u8d44\u6e90\u7ec4\u7684\u673a\u5236\u3002 \u8d44\u6e90\u7684\u540d\u79f0\u9700\u8981\u5728\u547d\u540d\u7a7a\u95f4\u5185\u662f\u552f\u4e00\u7684\uff0c\u4f46\u4e0d\u9700\u8981\u8de8\u547d\u540d\u7a7a\u95f4\u552f\u4e00\u3002 \u57fa\u4e8e\u547d\u540d\u7a7a\u95f4\u7684\u8303\u56f4\u4ec5\u9002\u7528\u4e8e\u547d\u540d\u7a7a\u95f4\u5bf9\u8c61\uff08\u4f8b\u5982\u90e8\u7f72\uff0c\u670d\u52a1\u7b49\uff09\uff0c\u800c\u4e0d\u9002\u7528\u4e8e\u96c6\u7fa4\u8303\u56f4\u7684\u5bf9\u8c61\uff08\u4f8b\u5982StorageClass\uff0c\u8282\u70b9\uff0c\u6301\u4e45\u5377\u7b49\uff09\u3002 \u5e76\u975e\u6240\u6709\u5bf9\u8c61\u90fd\u4f4d\u4e8e\u547d\u540d\u7a7a\u95f4\u4e2d\u3002 Kubernetes\u4ece\u56db\u4e2a\u521d\u59cb\u547d\u540d\u7a7a\u95f4\u5f00\u59cb\uff1a default \u7528\u4e8e\u6ca1\u6709\u5176\u4ed6\u547d\u540d\u7a7a\u95f4\u7684\u5bf9\u8c61\u7684\u9ed8\u8ba4\u547d\u540d\u7a7a\u95f4 kube-system Kubernetes\u7cfb\u7edf\u521b\u5efa\u7684\u5bf9\u8c61\u7684\u547d\u540d\u7a7a\u95f4 kube-public \u8be5\u547d\u540d\u7a7a\u95f4\u662f\u81ea\u52a8\u521b\u5efa\u7684\uff0c\u5e76\u53ef\u7531\u6240\u6709\u7528\u6237\uff08\u5305\u62ec\u672a\u7ecf\u8eab\u4efd\u9a8c\u8bc1\u7684\u7528\u6237\uff09\u8bfb\u53d6\u3002\u6b64\u547d\u540d\u7a7a\u95f4\u5927\u591a\u4fdd\u7559\u4f9b\u96c6\u7fa4\u4f7f\u7528\uff0c\u4ee5\u9632\u4e00\u4e9b\u8d44\u6e90\u5e94\u5728\u6574\u4e2a\u96c6\u7fa4\u8303\u56f4\u5185\u516c\u5f00\u548c\u53ef\u8bfb\u3002\u6b64\u547d\u540d\u7a7a\u95f4\u7684\u516c\u5171\u65b9\u9762\u53ea\u662f\u4e00\u79cd\u7ea6\u5b9a\uff0c\u800c\u4e0d\u662f\u8981\u6c42\u3002 kube-node-lease \u6b64\u547d\u540d\u7a7a\u95f4\u4fdd\u5b58\u4e0e\u6bcf\u4e2a\u8282\u70b9\u5173\u8054\u7684\u79df\u8d41\u5bf9\u8c61\u3002\u8282\u70b9\u79df\u8d41\u5141\u8bb8kubelet\u53d1\u9001\u5fc3\u8df3\uff0c\u4ee5\u4fbf\u63a7\u5236\u5e73\u9762\u53ef\u4ee5\u68c0\u6d4b\u5230\u8282\u70b9\u6545\u969c\u3002 \u67e5\u770b\u547d\u540d\u7a7a\u95f4\uff1a kubectl get namespace \u4e3a\u8bf7\u6c42\u8bbe\u7f6e\u547d\u540d\u7a7a\u95f4 kubectl run nginx --image=nginx --namespace=<\u63d2\u5165\u547d\u540d\u7a7a\u95f4\u540d\u79f0> kubectl get pods --namespace=<\u63d2\u5165\u547d\u540d\u7a7a\u95f4\u540d\u79f0> \u6807\u7b7e\u548c\u9009\u62e9\u5668 \u00b6 \u6807\u7b7e\u662f\u9644\u52a0\u5230\u5bf9\u8c61\uff08\u4f8b\u5982 Pod\uff09\u7684\u952e/\u503c\u5bf9\u3002\u6709\u6548\u7684\u6807\u7b7e\u952e\u6709\u4e24\u4e2a\u90e8\u5206\uff1a\u53ef\u9009\u7684\u524d\u7f00\u548c\u540d\u79f0\uff0c\u7531\u659c\u6760\uff08 / \uff09\u5206\u9694\u3002 \u6807\u7b7e\u65e8\u5728\u7528\u4e8e\u6307\u5b9a\u5bf9\u7528\u6237\u6709\u610f\u4e49\u548c\u76f8\u5173\u7684\u5bf9\u8c61\u8bc6\u522b\u5c5e\u6027\u3002 \u6807\u7b7e\u53ef\u7528\u4e8e\u7ec4\u7ec7\u548c\u9009\u62e9\u5bf9\u8c61\u5b50\u96c6\u3002\u6807\u7b7e\u53ef\u4ee5\u5728\u521b\u5efa\u5bf9\u8c61\u65f6\u9644\u52a0\uff0c\u968f\u540e\u5728\u4efb\u4f55\u65f6\u5019\u6dfb\u52a0\u548c\u4fee\u6539\u3002\u6bcf\u4e2a\u5bf9\u8c61\u53ef\u4ee5\u5b9a\u4e49\u4e00\u7ec4\u952e/\u503c\u6807\u7b7e\uff0c\u6bcf\u4e2a\u952e\u5fc5\u987b\u5bf9\u4e8e\u7ed9\u5b9a\u5bf9\u8c61\u662f\u552f\u4e00\u7684\u3002 \u6807\u7b7e\u7684\u793a\u4f8b\uff1a \"metadata\" : { \"labels\" : { \"key1\" : \"value1\" , \"key2\" : \"value2\" } } \u4e0e\u540d\u79f0\u548c UID \u4e0d\u540c\uff0c\u6807\u7b7e\u4e0d\u63d0\u4f9b\u552f\u4e00\u6027\u3002\u901a\u5e38\u60c5\u51b5\u4e0b\uff0c\u6211\u4eec\u671f\u671b\u8bb8\u591a\u5bf9\u8c61\u5e26\u6709\u76f8\u540c\u7684\u6807\u7b7e\u3002 \u76ee\u524d API \u652f\u6301\u4e24\u79cd\u7c7b\u578b\u7684\u9009\u62e9\u5668\uff1a \u57fa\u4e8e\u7b49\u5f0f\u7684\u9009\u62e9\u5668\uff0c\u4f8b\u5982\uff1a environment = production \u3001 tier != frontend \u57fa\u4e8e\u96c6\u5408\u7684\u9009\u62e9\u5668\uff0c\u4f8b\u5982\uff1a environment in (production, qa) \u3001 tier notin (frontend, backend) \u4f8b\u5982\uff1a kubectl get pods -l environment = production,tier = frontend kubectl get pods -l 'environment in (production),tier in (frontend)' kubectl get pods -l 'environment in (production, qa)' kubectl get pods -l 'environment,environment notin (frontend)' \u6ce8\u91caAnnotations \u00b6 \u4f7f\u7528 Kubernetes \u6ce8\u91ca\uff08Annotations\uff09\u5c06\u4efb\u610f\u975e\u6807\u8bc6\u5143\u6570\u636e\u9644\u52a0\u5230\u5bf9\u8c61\u4e0a\u3002 \u5de5\u5177\u548c\u5e93\u7b49\u5ba2\u6237\u7aef\u53ef\u4ee5\u68c0\u7d22\u6b64\u5143\u6570\u636e\u3002 \u4f7f\u7528\u6807\u7b7e\u6216\u6ce8\u91ca\u5c06\u5143\u6570\u636e\u9644\u52a0\u5230 Kubernetes \u5bf9\u8c61\u4e0a\u3002 \u6807\u7b7e\u53ef\u7528\u4e8e\u9009\u62e9\u5bf9\u8c61\u5e76\u67e5\u627e\u6ee1\u8db3\u67d0\u4e9b\u6761\u4ef6\u7684\u5bf9\u8c61\u96c6\u5408\u3002 \u6ce8\u91ca\u4e0d\u7528\u4e8e\u6807\u8bc6\u548c\u9009\u62e9\u5bf9\u8c61\u3002 \u6ce8\u91ca\u4e0e\u6807\u7b7e\u7c7b\u4f3c\uff0c\u90fd\u662f\u952e/\u503c\u6620\u5c04\u3002 \u6620\u5c04\u4e2d\u7684\u952e\u548c\u503c\u5fc5\u987b\u662f\u5b57\u7b26\u4e32\u3002 \u4f8b\u5982\uff1a \"metadata\" : { \"annotations\" : { \"key1\" : \"value1\" , \"key2\" : \"value2\" } } \u5408\u6cd5\u7684\u6ce8\u91ca\u952e\u5177\u6709\u4e24\u4e2a\u90e8\u5206\uff1a\u53ef\u9009\u7684\u524d\u7f00\u548c\u540d\u79f0\uff0c\u7531\u659c\u6760 ( / ) \u5206\u9694\u3002 \u5b57\u6bb5\u9009\u62e9\u5668 \u00b6 \u5b57\u6bb5\u9009\u62e9\u5668\uff08field selectors\uff09\u53ef\u4ee5\u6839\u636e\u4e00\u4e2a\u6216\u591a\u4e2a\u8d44\u6e90\u5b57\u6bb5\u7684\u503c\u9009\u62e9Kubernetes\u8d44\u6e90\u3002 \u4e0b\u9762\u662f\u4e00\u4e9b\u4f7f\u7528\u5b57\u6bb5\u9009\u62e9\u5668\u8fdb\u884c\u67e5\u8be2\u7b5b\u9009\u7684\u4f8b\u5b50\uff1a metadata.name=my-service metadata.namespace!=default status.phase=Pending This kubectl command selects all Pods for which the value of the status.phase field is Running: kubectl get pods --field-selector status.phase=Running Supported field selectors vary by Kubernetes resource type. All resource types support the metadata.name and metadata.namespace fields. Use the = , == , and != operators with field selectors ( = and == mean the same thing). \u4e0b\u9762 kubectl \u547d\u4ee4\u9009\u62e9\u6240\u6709\u72b6\u6001(phase)\u5b57\u6bb5\u503c\u4e3a Running \u7684 Pod\uff1a kubectl get pods --field-selector status.phase = Running \u652f\u6301\u7684\u5b57\u6bb5\u9009\u62e9\u5668\u56e0 Kubernetes \u8d44\u6e90\u7c7b\u578b\u800c\u5f02\u3002\u6240\u6709\u8d44\u6e90\u7c7b\u578b\u90fd\u652f\u6301 metadata.name \u548c metadata.namespace \u5b57\u6bb5\u3002 \u5728\u5b57\u6bb5\u9009\u62e9\u5668\u4e2d\u4f7f\u7528 = , == , \u548c != \u8fd0\u7b97\u7b26( = \u548c == \u8868\u793a\u76f8\u540c\u7684\u610f\u601d)\u3002 \u4f8b\u5982\uff1a kubectl get ingress --field-selector foo.bar = baz kubectl get services --all-namespaces --field-selector metadata.namespace! = default kubectl get pods --field-selector = status.phase! = Running,spec.restartPolicy = Always kubectl get statefulsets,services --all-namespaces --field-selector metadata.namespace! = default Finalizers\u662f*\u547d\u540d\u7a7a\u95f4\u952e*\uff0c\u544a\u8bc9Kubernetes\u5728\u6ee1\u8db3\u7279\u5b9a\u6761\u4ef6\u4e4b\u524d\u7b49\u5f85\uff0c\u7136\u540e\u518d\u5b8c\u5168\u5220\u9664\u6807\u8bb0\u4e3a*\u5220\u9664*\u7684\u8d44\u6e90\u3002 Finalizer\u8b66\u544a\u63a7\u5236\u5668controller\u6e05\u7406\u5df2\u5220\u9664\u5bf9\u8c61\u6240\u62e5\u6709\u7684\u8d44\u6e90\u3002 \u901a\u5e38\u56e0\u4e3a\u67d0\u79cd\u76ee\u7684\u4e3a\u8d44\u6e90\u6dfb\u52a0Finalizers\uff0c\u5f3a\u5236\u5220\u9664\u5b83\u4eec\u53ef\u80fd\u4f1a\u5bfc\u81f4\u96c6\u7fa4\u4e2d\u51fa\u73b0\u95ee\u9898\u3002 \u4e0e\u6807\u7b7e\u7c7b\u4f3c\uff0c \u6240\u6709\u8005\u5f15\u7528 \uff08Owner references\uff09\u63cf\u8ff0\u4e86Kubernetes\u4e2d\u5bf9\u8c61\u4e4b\u95f4\u7684\u5173\u7cfb\uff0c\u4f46\u7528\u4e8e\u4e0d\u540c\u7684\u76ee\u7684\u3002 Kubernetes\u4f7f\u7528\u6240\u6709\u8005\u5f15\u7528\uff08\u800c\u4e0d\u662f\u6807\u7b7e\uff09\u6765\u786e\u5b9a\u96c6\u7fa4\u4e2d\u54ea\u4e9bPod\u9700\u8981\u6e05\u7406\u3002 \u5f53Kubernetes\u8bc6\u522b\u5230\u76ee\u6807\u5220\u9664\u7684\u8d44\u6e90\u4e0a\u6709\u6240\u6709\u8005\u5f15\u7528\u65f6\uff0c\u5b83\u4f1a\u5904\u7406Finalizer\u3002 \u6240\u6709\u8005\u548c\u4f9d\u8d56\u5173\u7cfb \u00b6 \u5728 Kubernetes \u4e2d\uff0c\u4e00\u4e9b\u5bf9\u8c61\u62e5\u6709\u5176\u4ed6\u5bf9\u8c61\u3002\u4f8b\u5982\uff0cReplicaSet \u662f\u4e00\u7ec4 Pod \u7684\u6240\u6709\u8005\u3002\u8fd9\u4e9b\u88ab\u62e5\u6709\u7684\u5bf9\u8c61\u662f\u5176\u6240\u6709\u8005\u7684\u4ece\u5c5e\u5bf9\u8c61\u3002 \u4ece\u5c5e\u5bf9\u8c61\u5177\u6709\u4e00\u4e2a metadata.ownerReferences \u5b57\u6bb5\uff0c\u8be5\u5b57\u6bb5\u5f15\u7528\u5176\u6240\u6709\u8005\u5bf9\u8c61\u3002 \u6709\u6548\u7684\u6240\u6709\u8005\u5f15\u7528\u5305\u62ec\u5bf9\u8c61\u540d\u79f0\u548c\u4e0e\u4ece\u5c5e\u5bf9\u8c61\u76f8\u540c\u7684\u547d\u540d\u7a7a\u95f4\u4e2d\u7684 UID\u3002 \u4ece\u5c5e\u5bf9\u8c61\u8fd8\u5177\u6709\u4e00\u4e2a ownerReferences.blockOwnerDeletion \u5b57\u6bb5\uff0c\u8be5\u5b57\u6bb5\u5177\u6709\u5e03\u5c14\u503c\uff0c\u63a7\u5236\u7279\u5b9a\u7684\u4ece\u5c5e\u5bf9\u8c61\u662f\u5426\u53ef\u4ee5\u963b\u6b62\u5783\u573e\u56de\u6536\u5220\u9664\u5176\u6240\u6709\u8005\u5bf9\u8c61\u3002 \u8d44\u6e90 \u00b6 Kubernetes\u8d44\u6e90\u548c\u201c\u610f\u5411\u8bb0\u5f55\u201d\u90fd\u4ee5API\u5bf9\u8c61\u7684\u5f62\u5f0f\u5b58\u50a8\uff0c\u5e76\u901a\u8fc7\u5bf9API\u7684RESTful\u8c03\u7528\u8fdb\u884c\u4fee\u6539\u3002 API\u5141\u8bb8\u4ee5\u58f0\u660e\u6027\u65b9\u5f0f\u7ba1\u7406\u914d\u7f6e\u3002 \u7528\u6237\u53ef\u4ee5\u76f4\u63a5\u4e0eKubernetes API\u4ea4\u4e92\uff0c\u4e5f\u53ef\u4ee5\u901a\u8fc7\u50cfkubectl\u8fd9\u6837\u7684\u5de5\u5177\u8fdb\u884c\u4ea4\u4e92\u3002 \u6838\u5fc3Kubernetes API\u5177\u6709\u7075\u6d3b\u6027\uff0c\u4e5f\u53ef\u4ee5\u6269\u5c55\u4ee5\u652f\u6301\u81ea\u5b9a\u4e49\u8d44\u6e90\u3002 \u5de5\u4f5c\u8d1f\u8f7d\u8d44\u6e90\uff08Workload Resources\uff09 Pod \u3002Pod \u662f\u53ef\u4ee5\u5728\u4e3b\u673a\u4e0a\u8fd0\u884c\u7684\u5bb9\u5668\u96c6\u5408\u3002 PodTemplate \u3002PodTemplate \u63cf\u8ff0\u4e86\u9884\u5b9a\u4e49 pod \u7684\u526f\u672c\u6a21\u677f\u3002 ReplicationController \u3002ReplicationController \u8868\u793a\u4e00\u4e2a\u590d\u5236\u63a7\u5236\u5668\u7684\u914d\u7f6e\u3002 ReplicaSet \u3002ReplicaSet \u786e\u4fdd\u5728\u4efb\u4f55\u7ed9\u5b9a\u65f6\u95f4\u6709\u6307\u5b9a\u6570\u91cf\u7684 pod \u526f\u672c\u6b63\u5728\u8fd0\u884c\u3002 Deployment \u3002Deployment \u4f7f Pod \u548c ReplicaSet \u7684\u58f0\u660e\u6027\u66f4\u65b0\u6210\u4e3a\u53ef\u80fd\u3002 StatefulSet \u3002StatefulSet \u8868\u793a\u5177\u6709\u4e00\u81f4\u6807\u8bc6\u7684 pod \u96c6\u5408\u3002 ControllerRevision \u3002ControllerRevision \u5b9e\u73b0\u4e86\u72b6\u6001\u6570\u636e\u7684\u4e0d\u53ef\u53d8\u5feb\u7167\u3002 DaemonSet \u3002DaemonSet \u8868\u793a\u4e00\u4e2a\u5b88\u62a4\u8fdb\u7a0b\u96c6\u7684\u914d\u7f6e\u3002 Job \u3002Job \u8868\u793a\u5355\u4e2a job \u7684\u914d\u7f6e\u3002 CronJob \u3002CronJob \u8868\u793a\u5355\u4e2a cron job \u7684\u914d\u7f6e\u3002 HorizontalPodAutoscaler \u3002HorizontalPodAutoscaler \u8868\u793a\u6c34\u5e73 pod \u81ea\u52a8\u7f29\u653e\u5668\u7684\u914d\u7f6e\u3002 HorizontalPodAutoscaler v2beta2 \u3002HorizontalPodAutoscaler \u662f\u6c34\u5e73 pod \u81ea\u52a8\u7f29\u653e\u5668\u7684\u914d\u7f6e\uff0c\u6839\u636e\u6307\u5b9a\u7684\u6307\u6807\u81ea\u52a8\u7ba1\u7406\u5b9e\u73b0\u6bd4\u4f8b\u5b50\u8d44\u6e90\u7684\u4efb\u4f55\u8d44\u6e90\u7684\u526f\u672c\u8ba1\u6570\u3002 PriorityClass \u3002PriorityClass \u5b9a\u4e49\u4e86\u4ece\u4f18\u5148\u7ea7\u7c7b\u540d\u79f0\u5230\u4f18\u5148\u7ea7\u6574\u6570\u503c\u7684\u6620\u5c04\u3002 \u670d\u52a1\u8d44\u6e90\uff08Service Resources\uff09 Service . Service \u662f\u5bf9\u8f6f\u4ef6\u670d\u52a1\uff08\u4f8b\u5982mysql\uff09\u7684\u547d\u540d\u62bd\u8c61\uff0c\u7531\u4ee3\u7406\u76d1\u542c\u7684\u672c\u5730\u7aef\u53e3\uff08\u4f8b\u59823306\uff09\u548c\u786e\u5b9a\u54ea\u4e9bPod\u5c06\u56de\u7b54\u901a\u8fc7\u4ee3\u7406\u53d1\u9001\u7684\u8bf7\u6c42\u7684\u9009\u62e9\u5668\u7ec4\u6210\u3002 Endpoints . Endpoints \u662f\u5b9e\u73b0\u5b9e\u9645\u670d\u52a1\u7684\u4e00\u7ec4\u7ec8\u7ed3\u70b9\u3002 EndpointSlice . EndpointSlice \u8868\u793a\u5b9e\u73b0\u670d\u52a1\u7684\u7ec8\u7ed3\u70b9\u7684\u5b50\u96c6\u3002 Ingress . Ingress \u662f\u4e00\u7ec4\u89c4\u5219\uff0c\u5141\u8bb8\u5165\u7ad9\u8fde\u63a5\u5230\u8fbe\u7531\u540e\u7aef\u5b9a\u4e49\u7684\u7ec8\u7ed3\u70b9\u3002 IngressClass . IngressClass \u8868\u793a Ingress \u7684\u7c7b\uff0c\u7531 Ingress Spec \u5f15\u7528\u3002 \u914d\u7f6e\u548c\u5b58\u50a8\u8d44\u6e90\uff08Config and Storage Resources\uff09 ConfigMap \u3002ConfigMap\u4fdd\u5b58\u5bb9\u5668\u9700\u8981\u4f7f\u7528\u7684\u914d\u7f6e\u6570\u636e\u3002 Secret \u3002Secret\u4fdd\u5b58\u7279\u5b9a\u7c7b\u578b\u7684\u673a\u5bc6\u6570\u636e\u3002 Volume \u3002Volume\u8868\u793aPod\u4e2d\u7684\u547d\u540d\u5377\uff0c\u53ef\u4ee5\u88abPod\u4e2d\u7684\u4efb\u4f55\u5bb9\u5668\u8bbf\u95ee\u3002 PersistentVolumeClaim \u3002PersistentVolumeClaim\u662f\u7528\u6237\u5bf9\u6301\u4e45\u5377\u7684\u8bf7\u6c42\u548c\u58f0\u660e\u3002 PersistentVolume \u3002PersistentVolume\uff08PV\uff09\u662f\u7531\u7ba1\u7406\u5458\u63d0\u4f9b\u7684\u5b58\u50a8\u8d44\u6e90\u3002 StorageClass \u3002StorageClass\u63cf\u8ff0\u53ef\u52a8\u6001\u5206\u914dPersistentVolumes\u7684\u5b58\u50a8\u7c7b\u522b\u7684\u53c2\u6570\u3002 VolumeAttachment \u3002VolumeAttachment\u8bb0\u5f55\u5c06\u6307\u5b9a\u7684\u5377\u9644\u52a0\u5230/\u4ece\u6307\u5b9a\u8282\u70b9\u4e2d\u5206\u79bb\u7684\u610f\u56fe\u3002 CSIDriver \u3002CSIDriver\u8bb0\u5f55\u96c6\u7fa4\u4e0a\u90e8\u7f72\u7684\u5bb9\u5668\u5b58\u50a8\u63a5\u53e3\uff08CSI\uff09\u5377\u9a71\u52a8\u7a0b\u5e8f\u7684\u4fe1\u606f\u3002 CSINode \u3002CSINode\u4fdd\u5b58\u6709\u5173\u8282\u70b9\u4e0a\u5b89\u88c5\u7684\u6240\u6709CSI\u9a71\u52a8\u7a0b\u5e8f\u7684\u4fe1\u606f\u3002 CSIStorageCapacity \u3002CSIStorageCapacity\u5b58\u50a8\u4e00\u4e2aCSI GetCapacity\u8c03\u7528\u7684\u7ed3\u679c\u3002 \u8ba4\u8bc1\u8d44\u6e90\uff08Authentication Resources\uff09 ServiceAccount*\u3002ServiceAccount\u548c\u4e0b\u9762\u7684\u4fe1\u606f\u7ed1\u5b9a\u5728\u4e00\u8d77\uff1a \u4e00\u4e2a\u53ef\u88ab\u7528\u6237\u548c\u5468\u8fb9\u7cfb\u7edf\u7406\u89e3\u7684\u540d\u79f0\uff0c\u7528\u4e8e\u8eab\u4efd\u8bc6\u522b \u53ef\u8fdb\u884c\u8eab\u4efd\u9a8c\u8bc1\u548c\u6388\u6743\u7684\u4e3b\u4f53 \u4e00\u7ec4\u5bc6\u94a5\u3002 TokenRequest*\u3002TokenRequest\u4e3a\u7ed9\u5b9a\u7684ServiceAccount\u8bf7\u6c42\u4e00\u4e2a\u4ee4\u724c\u3002 TokenReview*\u3002TokenReview\u5c1d\u8bd5\u5bf9\u5df2\u77e5\u7528\u6237\u7684\u4ee4\u724c\u8fdb\u884c\u8eab\u4efd\u9a8c\u8bc1\u3002 CertificateSigningRequest*\u3002CertificateSigningRequest\u5bf9\u8c61\u63d0\u4f9b\u4e86\u4e00\u79cd\u901a\u8fc7\u63d0\u4ea4\u8bc1\u4e66\u7b7e\u540d\u8bf7\u6c42\u5e76\u5f02\u6b65\u6279\u51c6\u548c\u53d1\u653e\u6765\u83b7\u53d6x509\u8bc1\u4e66\u7684\u673a\u5236\u3002 \u6388\u6743\u8d44\u6e90\uff08Authorization Resources\uff09 LocalSubjectAccessReview*\u3002LocalSubjectAccessReview\u68c0\u67e5\u4e00\u4e2a\u7528\u6237\u6216\u7ec4\u5728\u7ed9\u5b9a\u547d\u540d\u7a7a\u95f4\u4e2d\u662f\u5426\u80fd\u6267\u884c\u67d0\u4e2a\u64cd\u4f5c\u3002 SelfSubjectAccessReview*\u3002SelfSubjectAccessReview\u68c0\u67e5\u5f53\u524d\u7528\u6237\u662f\u5426\u80fd\u6267\u884c\u67d0\u4e2a\u64cd\u4f5c\u3002 SelfSubjectRulesReview*\u3002SelfSubjectRulesReview\u679a\u4e3e\u5f53\u524d\u7528\u6237\u5728\u4e00\u4e2a\u547d\u540d\u7a7a\u95f4\u5185\u53ef\u4ee5\u6267\u884c\u7684\u64cd\u4f5c\u96c6\u5408\u3002 SubjectAccessReview*\u3002SubjectAccessReview\u68c0\u67e5\u4e00\u4e2a\u7528\u6237\u6216\u7ec4\u662f\u5426\u80fd\u6267\u884c\u67d0\u4e2a\u64cd\u4f5c\u3002 ClusterRole*\u3002ClusterRole\u662f\u4e00\u4e2a\u96c6\u7fa4\u7ea7\u522b\u7684PolicyRules\u903b\u8f91\u5206\u7ec4\uff0c\u53ef\u4ee5\u88abRoleBinding\u6216ClusterRoleBinding\u5f15\u7528\u4e3a\u4e00\u4e2a\u5355\u5143\u3002 ClusterRoleBinding*\u3002ClusterRoleBinding\u5f15\u7528\u4e00\u4e2aClusterRole\uff0c\u4f46\u4e0d\u5305\u542b\u5b83\u3002 Role*\u3002Role\u662f\u4e00\u4e2a\u547d\u540d\u7a7a\u95f4\u7ea7\u522b\u7684PolicyRules\u903b\u8f91\u5206\u7ec4\uff0c\u53ef\u4ee5\u88abRoleBinding\u5f15\u7528\u4e3a\u4e00\u4e2a\u5355\u5143\u3002 RoleBinding*\u3002RoleBinding\u5f15\u7528\u4e00\u4e2aRole\uff0c\u4f46\u4e0d\u5305\u542b\u5b83\u3002 \u7b56\u7565\u8d44\u6e90\uff08Policy Resources\uff09 LimitRange*\u3002LimitRange\u4e3a\u547d\u540d\u7a7a\u95f4\u4e2d\u6bcf\u79cd\u8d44\u6e90\u8bbe\u7f6e\u8d44\u6e90\u4f7f\u7528\u9650\u5236\u3002 ResourceQuota*\u3002ResourceQuota\u8bbe\u7f6e\u6bcf\u4e2a\u547d\u540d\u7a7a\u95f4\u5f3a\u5236\u6267\u884c\u7684\u603b\u914d\u989d\u9650\u5236\u3002 NetworkPolicy*\u3002NetworkPolicy\u63cf\u8ff0\u4e86\u4e00\u7ec4Pod\u5141\u8bb8\u7684\u7f51\u7edc\u6d41\u91cf\u3002 PodDisruptionBudget*\u3002PodDisruptionBudget\u662f\u4e00\u4e2a\u5bf9\u8c61\uff0c\u7528\u4e8e\u5b9a\u4e49\u5bf9\u4e00\u7ec4Pod\u53ef\u80fd\u9020\u6210\u7684\u6700\u5927\u4e2d\u65ad\u3002 PodSecurityPolicy v1beta1*\u3002PodSecurityPolicy\u63a7\u5236\u5bf9\u53ef\u80fd\u5f71\u54cd\u5c06\u5e94\u7528\u4e8ePod\u548c\u5bb9\u5668\u7684\u5b89\u5168\u4e0a\u4e0b\u6587\u7684\u8bf7\u6c42\u7684\u80fd\u529b\u3002 \u6269\u5c55\u8d44\u6e90\uff08Extend Resources\uff09 CustomResourceDefinition*\u3002CustomResourceDefinition\u8868\u793a\u5e94\u5728API\u670d\u52a1\u5668\u4e0a\u516c\u5f00\u7684\u8d44\u6e90\u3002 MutatingWebhookConfiguration*\u3002MutatingWebhookConfiguration\u63cf\u8ff0\u63a5\u53d7\u6216\u62d2\u7edd\u5e76\u53ef\u80fd\u66f4\u6539\u5bf9\u8c61\u7684\u51c6\u5165Webhook\u7684\u914d\u7f6e\u3002 ValidatingWebhookConfiguration*\u3002ValidatingWebhookConfiguration\u63cf\u8ff0\u63a5\u53d7\u6216\u62d2\u7edd\u5bf9\u8c61\u4f46\u4e0d\u66f4\u6539\u5bf9\u8c61\u7684\u51c6\u5165Webhook\u7684\u914d\u7f6e\u3002 \u96c6\u7fa4\u8d44\u6e90\uff08Cluster Resources\uff09 Node*\u3002Node\u662fKubernetes\u4e2d\u7684\u5de5\u4f5c\u8282\u70b9\u3002 Namespace*\u3002Namespace\u4e3a\u540d\u79f0\u63d0\u4f9b\u4e86\u4f5c\u7528\u57df\u3002 Event*\u3002Event\u662f\u5bf9\u96c6\u7fa4\u4e2d\u67d0\u4e2a\u4f4d\u7f6e\u53d1\u751f\u4e8b\u4ef6\u7684\u62a5\u544a\u3002 APIService*\u3002APIService\u8868\u793a\u7279\u5b9aGroupVersion\u7684\u670d\u52a1\u5668\u3002 Lease*\u3002Lease\u5b9a\u4e49\u4e86\u79df\u8d41\u7684\u6982\u5ff5\u3002 RuntimeClass*\u3002RuntimeClass\u5b9a\u4e49\u4e86\u96c6\u7fa4\u4e2d\u652f\u6301\u7684\u5bb9\u5668\u8fd0\u884c\u65f6\u7c7b\u3002 FlowSchema v1beta2*\u3002FlowSchema\u5b9a\u4e49\u4e86\u4e00\u7ec4\u6d41\u7a0b\u7684\u67b6\u6784\u3002 PriorityLevelConfiguration v1beta2*\u3002PriorityLevelConfiguration\u8868\u793a\u4f18\u5148\u7ea7\u7ea7\u522b\u7684\u914d\u7f6e\u3002 Binding*\u3002Binding\u5c06\u4e00\u4e2a\u5bf9\u8c61\u7ed1\u5b9a\u5230\u53e6\u4e00\u4e2a\u5bf9\u8c61\uff1b\u4f8b\u5982\uff0c\u8c03\u5ea6\u7a0b\u5e8f\u5c06Pod\u7ed1\u5b9a\u5230\u8282\u70b9\u4e0a\u3002 ComponentStatus*\u3002ComponentStatus\uff08\u548cComponentStatusList\uff09\u4fdd\u5b58\u96c6\u7fa4\u9a8c\u8bc1\u4fe1\u606f\u3002 \u4f7f\u7528\u547d\u4ee4 kube api-resources \u83b7\u53d6\u652f\u6301\u7684API\u8d44\u6e90\u3002 \u4f7f\u7528\u547d\u4ee4 kubectl explain RESOURCE [options] \u63cf\u8ff0\u4e0e\u6bcf\u4e2a\u652f\u6301\u7684API\u8d44\u6e90\u76f8\u5173\u8054\u7684\u5b57\u6bb5\u3002\u8fd9\u4e9b\u5b57\u6bb5\u53ef\u4ee5\u901a\u8fc7\u7b80\u5355\u7684JSONPath\u6807\u8bc6\u7b26\u8fdb\u884c\u8bc6\u522b\uff1a kubectl explain binding kubectl explain binding.metadata kubectl explain binding.metadata.name \u5de5\u4f5c\u8d1f\u8f7d\u8d44\u6e90 \u00b6 Pods \u00b6 Pod\u662fKubernetes\u4e2d\u53ef\u521b\u5efa\u548c\u7ba1\u7406\u7684\u6700\u5c0f\u90e8\u7f72\u8ba1\u7b97\u5355\u4f4d\u3002 Pod\u662f\u4e00\u4e2a\u5305\u542b\u4e00\u4e2a\u6216\u591a\u4e2a\u5bb9\u5668\u3001\u5171\u4eab\u5b58\u50a8\u548c\u7f51\u7edc\u8d44\u6e90\u4ee5\u53ca\u5982\u4f55\u8fd0\u884c\u5bb9\u5668\u7684\u89c4\u8303\u7684\u7ec4\u3002 Pod\u7684\u5185\u5bb9\u59cb\u7ec8\u5171\u540c\u5b9a\u4f4d\u548c\u5171\u540c\u5b89\u6392\uff0c\u5e76\u5728\u5171\u4eab\u73af\u5883\u4e2d\u8fd0\u884c\u3002 Pod\u6a21\u62df\u4e86\u4e00\u4e2a\u7279\u5b9a\u4e8e\u5e94\u7528\u7a0b\u5e8f\u7684\u201c\u903b\u8f91\u4e3b\u673a\u201d\uff1a\u5b83\u5305\u542b\u4e00\u4e2a\u6216\u591a\u4e2a\u76f8\u5bf9\u7d27\u5bc6\u8026\u5408\u7684\u5e94\u7528\u7a0b\u5e8f\u5bb9\u5668\u3002 \u5728\u975e\u4e91\u73af\u5883\u4e2d\uff0c\u540c\u4e00\u7269\u7406\u6216\u865a\u62df\u673a\u4e0a\u6267\u884c\u7684\u5e94\u7528\u7a0b\u5e8f\u7c7b\u4f3c\u4e8e\u5728\u540c\u4e00\u903b\u8f91\u4e3b\u673a\u4e0a\u6267\u884c\u7684\u4e91\u5e94\u7528\u7a0b\u5e8f\u3002 Pod\u7684\u5171\u4eab\u73af\u5883\u662f\u4e00\u7ec4Linux\u547d\u540d\u7a7a\u95f4\u3001cgroups\u548c\u53ef\u80fd\u7684\u5176\u4ed6\u9694\u79bb\u8981\u7d20 - \u8fd9\u4e9b\u8981\u7d20\u4e0e\u9694\u79bbDocker\u5bb9\u5668\u7684\u65b9\u5f0f\u76f8\u540c\u3002 \u5728Docker\u6982\u5ff5\u65b9\u9762\uff0cPod\u7c7b\u4f3c\u4e8e\u5177\u6709\u5171\u4eab\u547d\u540d\u7a7a\u95f4\u548c\u5171\u4eab\u6587\u4ef6\u7cfb\u7edf\u5377\u7684\u4e00\u7ec4Docker\u5bb9\u5668\u3002 \u901a\u5e38\u60c5\u51b5\u4e0b\uff0c\u751a\u81f3\u662f\u5355\u4f8bPod\uff0c\u6211\u4eec\u90fd\u4e0d\u9700\u8981\u76f4\u63a5\u521b\u5efaPod\uff0c\u800c\u662f\u4f7f\u7528\u5de5\u4f5c\u8d1f\u8f7d\u8d44\u6e90\uff0c\u4f8b\u5982*Deployment*\u6216*Job*\u6765\u521b\u5efa\u5b83\u4eec\u3002\u5982\u679cPod\u9700\u8981\u8ddf\u8e2a\u72b6\u6001\uff0c\u5219\u53ef\u4ee5\u4f7f\u7528StatefulSet\u8d44\u6e90\u3002 Kubernetes\u96c6\u7fa4\u4e2d\u7684Pod\u6709\u4e24\u79cd\u4e3b\u8981\u7528\u6cd5\uff1a \u8fd0\u884c\u5355\u4e2a\u5bb9\u5668\u7684Pod\u3002 \u8fd0\u884c\u9700\u8981\u5171\u540c\u5de5\u4f5c\u7684\u591a\u4e2a\u5bb9\u5668\u7684Pod\u3002 \u201c\u6bcf\u4e2aPod\u4e00\u4e2a\u5bb9\u5668\u201d\u7684\u6a21\u578b\u662f\u6700\u5e38\u89c1\u7684Kubernetes\u7528\u4f8b\uff1b\u5728\u8fd9\u79cd\u60c5\u51b5\u4e0b\u53ef\u4ee5\u5c06Pod\u89c6\u4e3a\u5355\u4e2a\u5bb9\u5668\u7684\u5305\u88c5\u5668\uff1bKubernetes\u7ba1\u7406Pod\u800c\u4e0d\u662f\u76f4\u63a5\u7ba1\u7406\u5bb9\u5668\u3002 \u4e00\u4e2aPod\u53ef\u4ee5\u5c01\u88c5\u7531\u591a\u4e2a\u5171\u540c\u5b9a\u4f4d\u3001\u7d27\u5bc6\u8026\u5408\u4e14\u9700\u8981\u5171\u4eab\u8d44\u6e90\u7684\u5bb9\u5668\u7ec4\u6210\u7684\u5e94\u7528\u7a0b\u5e8f\u3002 \u8fd9\u4e9b\u5171\u540c\u5b9a\u4f4d\u7684\u5bb9\u5668\u5f62\u6210\u4e00\u4e2a\u5355\u4e00\u7684\u670d\u52a1\u6574\u4f53\u5355\u5143 - \u4f8b\u5982\uff0c\u4e00\u4e2a\u5bb9\u5668\u5411\u516c\u4f17\u63d0\u4f9b\u5b58\u50a8\u5728\u5171\u4eab\u5377\u4e2d\u7684\u6570\u636e\uff0c\u800c\u53e6\u4e00\u4e2a\u72ec\u7acb\u7684Sidecar\u5bb9\u5668\u5237\u65b0\u6216\u66f4\u65b0\u8fd9\u4e9b\u6587\u4ef6\u3002Pod\u5c06\u8fd9\u4e9b\u5bb9\u5668\u3001\u5b58\u50a8\u8d44\u6e90\u548c\u77ed\u6682\u7684\u7f51\u7edc\u6807\u8bc6\u5305\u88c5\u5728\u4e00\u8d77\uff0c\u4f5c\u4e3a\u4e00\u4e2a\u5355\u72ec\u7684\u5355\u4f4d\u3002 \u5728\u5355\u4e2aPod\u4e2d\u5206\u7ec4\u591a\u4e2a\u5171\u540c\u5b9a\u4f4d\u548c\u5171\u540c\u7ba1\u7406\u7684\u5bb9\u5668\u662f\u76f8\u5bf9\u9ad8\u7ea7\u7684\u7528\u4f8b\u3002\u5e94\u8be5*\u4ec5\u5728*\u5bb9\u5668\u7d27\u5bc6\u8026\u5408\u7684\u7279\u5b9a\u60c5\u51b5\u4e0b\u4f7f\u7528\u6b64\u6a21\u5f0f\u3002 \u6bcf\u4e2aPod\u90fd\u65e8\u5728\u8fd0\u884c\u7ed9\u5b9a\u5e94\u7528\u7a0b\u5e8f\u7684\u5355\u4e2a\u5b9e\u4f8b\u3002\u5982\u679c\u6211\u4eec\u60f3\u6c34\u5e73\u6269\u5c55\u60a8\u7684\u5e94\u7528\u7a0b\u5e8f\uff08\u901a\u8fc7\u8fd0\u884c\u66f4\u591a\u5b9e\u4f8b\u63d0\u4f9b\u66f4\u591a\u7684\u603b\u8d44\u6e90\uff09\uff0c\u5219\u5e94\u8be5\u4f7f\u7528\u591a\u4e2aPod\uff0c\u6bcf\u4e2a\u5b9e\u4f8b\u4e00\u4e2aPod\u3002\u5728Kubernetes\u4e2d\uff0c\u8fd9\u901a\u5e38\u79f0\u4e3a*\u590d\u5236*\u3002\u590d\u5236\u7684Pod\u901a\u5e38\u4f5c\u4e3a\u5de5\u4f5c\u8d1f\u8f7d\u8d44\u6e90\u53ca\u5176\u63a7\u5236\u5668\u7684\u4e00\u7ec4\u521b\u5efa\u548c\u7ba1\u7406\u3002 Pod\u672c\u5730\u63d0\u4f9b\u4e24\u79cd\u5171\u4eab\u8d44\u6e90\u4ee5\u4f9b\u5176\u7ec4\u6210\u5bb9\u5668\u4f7f\u7528\uff1a \u7f51\u7edc *\u548c \u5b58\u50a8 *\u3002 \u4e00\u4e2aPod\u53ef\u4ee5\u6307\u5b9a\u4e00\u7ec4\u5171\u4eab\u7684\u5b58\u50a8\u5377\u3002Pod\u4e2d\u7684\u6240\u6709\u5bb9\u5668\u90fd\u53ef\u4ee5\u8bbf\u95ee\u8fd9\u4e9b\u5171\u4eab\u5377\uff0c\u4f7f\u8fd9\u4e9b\u5bb9\u5668\u53ef\u4ee5\u5171\u4eab\u6570\u636e\u3002 \u6bcf\u4e2aPod\u4e3a\u6bcf\u4e2a\u5730\u5740\u65cf\u5206\u914d\u4e00\u4e2a\u552f\u4e00\u7684IP\u5730\u5740\u3002 \u5728\u4e00\u4e2aPod\u5185\uff0c\u5bb9\u5668\u5171\u4eab\u4e00\u4e2aIP\u5730\u5740\u548c\u7aef\u53e3\u7a7a\u95f4\uff0c\u5e76\u53ef\u4ee5\u901a\u8fc7\u201clocalhost\u201d\u627e\u5230\u5f7c\u6b64\u3002\u60f3\u8981\u4e0e\u8fd0\u884c\u5728\u4e0d\u540cPod\u4e2d\u7684\u5bb9\u5668\u4ea4\u4e92\u7684\u5bb9\u5668\u53ef\u4ee5\u4f7f\u7528IP\u7f51\u7edc\u8fdb\u884c\u901a\u4fe1\u3002 \u5f53\u521b\u5efa\u4e00\u4e2aPod\u65f6\uff0c\u65b0\u7684Pod\u88ab\u8c03\u5ea6\u5728\u96c6\u7fa4\u4e2d\u7684\u4e00\u4e2a\u8282\u70b9\u4e0a\u8fd0\u884c\u3002Pod\u4fdd\u7559\u5728\u8be5\u8282\u70b9\u4e0a\uff0c\u76f4\u5230Pod\u6267\u884c\u5b8c\u6bd5\u3001Pod\u5bf9\u8c61\u88ab\u5220\u9664\u3001Pod\u56e0\u7f3a\u4e4f\u8d44\u6e90\u800c\u88ab\u9a71\u9010\u6216\u8282\u70b9\u53d1\u751f\u6545\u969c\u3002 \u5728Pod\u4e2d\u91cd\u65b0\u542f\u52a8\u4e00\u4e2a\u5bb9\u5668\u4e0d\u5e94\u4e0e\u91cd\u65b0\u542f\u52a8\u4e00\u4e2aPod\u6df7\u6dc6\u3002Pod\u4e0d\u662f\u4e00\u4e2a\u8fdb\u7a0b\uff0c\u800c\u662f\u4e00\u4e2a\u8fd0\u884c\u5bb9\u5668\u7684\u73af\u5883\u3002Pod\u4f1a\u4e00\u76f4\u4fdd\u7559\uff0c\u76f4\u5230\u88ab\u5220\u9664\u4e3a\u6b62\u3002 \u60a8\u53ef\u4ee5\u4f7f\u7528\u5de5\u4f5c\u8d1f\u8f7d\u8d44\u6e90\uff08\u4f8b\u5982Deployment\u3001StatefulSet\u3001DaemonSet\uff09\u4e3a\u81ea\u5df1\u521b\u5efa\u548c\u7ba1\u7406\u591a\u4e2aPod\u3002\u8d44\u6e90\u7684\u63a7\u5236\u5668\u5904\u7406\u590d\u5236\u3001\u6eda\u52a8\u548c\u5728Pod\u5931\u8d25\u65f6\u7684\u81ea\u52a8\u6062\u590d\u3002 \u521d\u59cb\u5316\u5bb9\u5668 \u00b6 \u4e00\u4e9bPod\u8fd8\u6709\u521d\u59cb\u5316\u5bb9\u5668\uff08Init containers\uff09\u548c\u5e94\u7528\u5bb9\u5668\uff08app containers\uff09\u3002\u521d\u59cb\u5316\u5bb9\u5668\u5728\u5e94\u7528\u5bb9\u5668\u542f\u52a8\u4e4b\u524d\u8fd0\u884c\u5e76\u5b8c\u6210\u3002 \u6211\u4eec\u53ef\u4ee5\u5728Pod\u89c4\u8303\u4e2d\u6307\u5b9a\u521d\u59cb\u5316\u5bb9\u5668\uff0c\u540c\u65f6\u4e5f\u53ef\u4ee5\u5728\u5bb9\u5668\u6570\u7ec4\u4e2d\u63cf\u8ff0\u5e94\u7528\u5bb9\u5668\u3002 \u9759\u6001Pod \u00b6 \u9759\u6001Pod\u662f\u76f4\u63a5\u7531\u7279\u5b9a\u8282\u70b9\u4e0a\u7684kubelet\u5b88\u62a4\u7a0b\u5e8f\u7ba1\u7406\u7684\uff0cAPI\u670d\u52a1\u5668\u4e0d\u4f1a\u89c2\u5bdf\u5b83\u4eec\u3002 \u9759\u6001Pod\u59cb\u7ec8\u7ed1\u5b9a\u5230\u7279\u5b9a\u8282\u70b9\u4e0a\u7684\u4e00\u4e2aKubelet\u3002 \u9759\u6001Pod\u7684\u4e3b\u8981\u7528\u9014\u662f\u8fd0\u884c\u81ea\u6258\u7ba1\u63a7\u5236\u9762\u677f\uff1a\u6362\u53e5\u8bdd\u8bf4\uff0c\u4f7f\u7528kubelet\u76d1\u7763\u5404\u4e2a\u63a7\u5236\u9762\u677f\u7ec4\u4ef6\u3002 kubelet\u4f1a\u81ea\u52a8\u5c1d\u8bd5\u4e3a\u6bcf\u4e2a\u9759\u6001Pod\u5728Kubernetes API\u670d\u52a1\u5668\u4e0a\u521b\u5efa\u4e00\u4e2a\u955c\u50cfPod\u3002\u8fd9\u610f\u5473\u7740\u5728\u8282\u70b9\u4e0a\u8fd0\u884c\u7684Pod\u5728API\u670d\u52a1\u5668\u4e0a\u53ef\u89c1\uff0c\u4f46\u65e0\u6cd5\u4ece\u90a3\u91cc\u63a7\u5236\u3002 \u5bb9\u5668\u63a2\u9488 \u00b6 \u63a2\u9488\u662f kubelet \u5b9a\u671f\u5bf9\u5bb9\u5668\u6267\u884c\u7684\u4e00\u79cd\u8bca\u65ad\u3002 \u4e3a\u6267\u884c\u8bca\u65ad\uff0ckubelet \u8981\u4e48\u5728\u5bb9\u5668\u5185\u6267\u884c\u4ee3\u7801\uff0c\u8981\u4e48\u53d1\u8d77\u7f51\u7edc\u8bf7\u6c42\u3002 \u4f7f\u7528\u63a2\u9488\u6709\u56db\u79cd\u4e0d\u540c\u7684\u68c0\u67e5\u5bb9\u5668\u65b9\u5f0f\u3002\u6bcf\u4e2a\u63a2\u9488\u5fc5\u987b\u6070\u597d\u5b9a\u4e49\u8fd9\u56db\u79cd\u673a\u5236\u4e2d\u7684\u4e00\u79cd\uff1a exec \u3002\u5982\u679c\u547d\u4ee4\u4ee5\u72b6\u6001\u4ee3\u7801 0 \u9000\u51fa\uff0c\u5219\u5c06\u8bca\u65ad\u89c6\u4e3a\u6210\u529f\u3002 grpc \u3002\u5982\u679c\u54cd\u5e94\u7684\u72b6\u6001\u4e3a SERVING\uff0c\u5219\u5c06\u8bca\u65ad\u89c6\u4e3a\u6210\u529f\u3002 httpGet \u3002\u5982\u679c\u54cd\u5e94\u7684\u72b6\u6001\u4ee3\u7801\u5927\u4e8e\u6216\u7b49\u4e8e 200 \u4e14\u5c0f\u4e8e 400\uff0c\u5219\u5c06\u8bca\u65ad\u89c6\u4e3a\u6210\u529f\u3002 tcpSocket \u3002\u5982\u679c\u7aef\u53e3\u5f00\u653e\uff0c\u5219\u5c06\u8bca\u65ad\u89c6\u4e3a\u6210\u529f\u3002 \u6bcf\u4e2a\u63a2\u9488\u6709\u4e09\u79cd\u7ed3\u679c\uff1a \u6210\u529f \u5931\u8d25 \u672a\u77e5 \u63a2\u9488\u7c7b\u578b\uff1a livenessProbe \u3002\u6307\u793a\u5bb9\u5668\u662f\u5426\u6b63\u5728\u8fd0\u884c\u3002 readinessProbe \u3002\u6307\u793a\u5bb9\u5668\u662f\u5426\u51c6\u5907\u597d\u54cd\u5e94\u8bf7\u6c42\u3002 startupProbe \u3002\u6307\u793a\u5bb9\u5668\u5185\u7684\u5e94\u7528\u7a0b\u5e8f\u662f\u5426\u542f\u52a8\u3002 Deployment \u00b6 ReplicaSet \u00b6 ReplicaSet\u7684\u76ee\u7684\u662f\u5728\u4efb\u4f55\u65f6\u5019\u7ef4\u62a4\u4e00\u7ec4\u7a33\u5b9a\u7684\u526f\u672cPod\u3002\u56e0\u6b64\uff0c\u5b83\u901a\u5e38\u7528\u4e8e\u4fdd\u8bc1\u6307\u5b9a\u6570\u91cf\u7684\u76f8\u540cPod\u7684\u53ef\u7528\u6027\u3002 \u6211\u4eec\u4e00\u822c\u4e0d\u9700\u8981\u76f4\u63a5\u64cd\u7eb5ReplicaSet\u5bf9\u8c61\uff1a\u4f7f\u7528Deployment\uff0c\u7136\u540e\u5728spec\u90e8\u5206\u4e2d\u5b9a\u4e49\u60a8\u7684\u5e94\u7528\u7a0b\u5e8f\u3002 \u53ef\u4ee5\u901a\u8fc7\u8bbe\u7f6e replicaset.spec.replicas \u6765\u6307\u5b9a\u5e94\u540c\u65f6\u8fd0\u884c\u591a\u5c11\u4e2aPod\u3002 ReplicaSet\u5c06\u521b\u5efa/\u5220\u9664\u5176Pod\u4ee5\u5339\u914d\u6b64\u6570\u5b57\u3002 \u5982\u679c\u4e0d\u6307\u5b9a replicaset.spec.replicas \uff0c\u5219\u9ed8\u8ba4\u503c\u4e3a 1 \u3002 StatefulSet \u00b6 StatefulSet \u7279\u70b9\uff08\u53c8\u79f0\u56fa\u5b9a\u6807\u8bc6\uff09\uff1a Pod \u7684\u540d\u79f0\u5728\u521b\u5efa\u540e\u4e0d\u53ef\u53d8\u3002 DNS \u4e3b\u673a\u540d\u5728\u521b\u5efa\u540e\u4e0d\u53ef\u53d8\u3002 \u6302\u8f7d\u7684\u5377\u5728\u521b\u5efa\u540e\u4e0d\u53ef\u53d8\u3002 StatefulSet \u7684\u56fa\u5b9a\u6807\u8bc6\u5728\u5931\u8d25\u3001\u6269\u5c55\u548c\u5176\u4ed6\u64cd\u4f5c\u540e\u4e0d\u4f1a\u6539\u53d8\u3002 StatefulSet \u7684\u547d\u540d\u7ea6\u5b9a\u4e3a\uff1a - \u3002 StatefulSet \u53ef\u4ee5\u81ea\u884c\u8fdb\u884c\u6269\u5c55\uff0c\u4f46\u662f Deployment \u9700\u8981\u4f9d\u9760 ReplicaSet \u8fdb\u884c\u6269\u5c55\u3002 \u5efa\u8bae\uff1a\u5148\u5c06 StatefulSet \u51cf\u5c11\u5230 0\uff0c\u800c\u4e0d\u662f\u76f4\u63a5\u5220\u9664\u5b83\u3002 headless Service \u548c governing Service\uff1a Headless Service \u662f\u4e00\u4e2a\u666e\u901a\u7684 Kubernetes Service \u5bf9\u8c61\uff0c\u5176 spec.clusterIP \u88ab\u8bbe\u7f6e\u4e3a None \u3002 \u5f53 StatefulSet \u7684 spec.ServiceName \u8bbe\u7f6e\u4e3a headless Service \u540d\u79f0\u65f6\uff0cStatefulSet \u73b0\u5728\u662f\u4e00\u4e2a governing Service\u3002 \u521b\u5efa StatefulSet \u7684\u4e00\u822c\u8fc7\u7a0b\uff1a \u521b\u5efa StorageClass\u3002 \u521b\u5efa Headless Service\u3002 \u57fa\u4e8e\u4e0a\u8ff0\u4e24\u4e2a\u521b\u5efa StatefulSet\u3002 DaemonSet \u00b6 DaemonSet\u4fdd\u8bc1\u6240\u6709\uff08\u6216\u90e8\u5206\uff09\u8282\u70b9\u8fd0\u884cPod\u7684\u526f\u672c\u3002\u968f\u7740\u8282\u70b9\u4ece\u96c6\u7fa4\u4e2d\u5220\u9664\uff0c\u8fd9\u4e9bPod\u5c06\u88ab\u5783\u573e\u56de\u6536\u3002 \u5220\u9664DaemonSet\u5c06\u6e05\u7406\u5b83\u521b\u5efa\u7684Pod\u3002 \u4e00\u4e9b\u5178\u578bDaemonSet\u7684\u7528\u9014\u5305\u62ec\uff1a \u5728\u6bcf\u4e2a\u8282\u70b9\u4e0a\u8fd0\u884c\u96c6\u7fa4\u5b58\u50a8\u5b88\u62a4\u7a0b\u5e8f\u3002 \u5728\u6bcf\u4e2a\u8282\u70b9\u4e0a\u8fd0\u884c\u65e5\u5fd7\u6536\u96c6\u5b88\u62a4\u7a0b\u5e8f\u3002 \u5728\u6bcf\u4e2a\u8282\u70b9\u4e0a\u8fd0\u884c\u8282\u70b9\u76d1\u89c6\u5b88\u62a4\u7a0b\u5e8f\u3002 \u5728\u7b80\u5355\u7684\u60c5\u51b5\u4e0b\uff0c\u6bcf\u79cd\u7c7b\u578b\u7684\u5b88\u62a4\u7a0b\u5e8f\u5c06\u4f7f\u7528\u8986\u76d6\u6240\u6709\u8282\u70b9\u7684\u4e00\u4e2aDaemonSet\u3002 \u66f4\u590d\u6742\u7684\u8bbe\u7f6e\u53ef\u80fd\u4f1a\u4e3a\u5355\u4e2a\u5b88\u62a4\u7a0b\u5e8f\u4f7f\u7528\u591a\u4e2aDaemonSet\uff0c\u4f46\u4f7f\u7528\u4e0d\u540c\u7684\u6807\u5fd7\u548c/\u6216\u4e0d\u540c\u7684\u5185\u5b58\u548cCPU\u8bf7\u6c42\u6765\u652f\u6301\u4e0d\u540c\u7684\u786c\u4ef6\u7c7b\u578b\u3002 DaemonSet\u63a7\u5236\u5668\u8c03\u548c\u8fc7\u7a0b\u540c\u65f6\u68c0\u67e5\u73b0\u6709\u8282\u70b9\u548c\u65b0\u521b\u5efa\u7684\u8282\u70b9\u3002 \u9ed8\u8ba4\u60c5\u51b5\u4e0b\uff0cKubernetes\u8c03\u5ea6\u7a0b\u5e8f\u5ffd\u7565\u7531DamonSet\u521b\u5efa\u7684Pod\uff0c\u5e76\u5141\u8bb8\u5b83\u4eec\u5b58\u5728\u4e8e\u8282\u70b9\u4e0a\uff0c\u76f4\u5230\u5173\u95ed\u8282\u70b9\u672c\u8eab\u3002 \u5728\u9009\u62e9\u8282\u70b9\u4e0a\u8fd0\u884cPod\uff1a \u5982\u679c\u60a8\u6307\u5b9a daemonset.spec.template.spec.nodeSelector \uff0c\u90a3\u4e48DaemonSet\u63a7\u5236\u5668\u5c06\u5728\u4e0e\u8be5\u8282\u70b9\u9009\u62e9\u5668\u5339\u914d\u7684\u8282\u70b9\u4e0a\u521b\u5efaPod\u3002 \u5982\u679c\u60a8\u6307\u5b9a daemonset.spec.template.spec.affinity \uff0c\u90a3\u4e48DaemonSet\u63a7\u5236\u5668\u5c06\u5728\u4e0e\u8be5\u8282\u70b9\u4eb2\u548c\u529b\u5339\u914d\u7684\u8282\u70b9\u4e0a\u521b\u5efaPod\u3002 \u5982\u679c\u4e24\u8005\u90fd\u4e0d\u6307\u5b9a\uff0c\u5219DaemonSet\u63a7\u5236\u5668\u5c06\u5728\u6240\u6709\u8282\u70b9\u4e0a\u521b\u5efaPod\u3002 \u5728 kubectl explain daemonset.spec \u4e2d\u6ca1\u6709 replicas \u5b57\u6bb5\u4e0e kubectl explain deployment.spec.replicas \u76f8\u5bf9\u5e94\u3002\u5f53\u521b\u5efa\u4e00\u4e2aDaemonSet\u65f6\uff0c\u6bcf\u4e2a\u8282\u70b9\u5c06\u8fd0\u884c*\u4e00\u4e2a* DaemonSet Pod\u3002 \u5bf9\u4e8e\u670d\u52a1\uff0c\u901a\u5e38\u662f\u65e0\u72b6\u6001\u7684\uff0c\u4e00\u822c\u4e0d\u5173\u5fc3\u8282\u70b9\u5728\u54ea\u91cc\u8fd0\u884c\uff0c\u66f4\u5173\u5fc3Pod\u526f\u672c\u7684\u6570\u91cf\uff0c\u5e76\u4e14\u6211\u4eec\u53ef\u4ee5\u5c06\u8fd9\u4e9b\u526f\u672c/replicas\u7f29\u653e\u3002\u5728\u8fd9\u91cc\uff0c\u6eda\u52a8\u66f4\u65b0\u4e5f\u5c06\u662f\u4e00\u4e2a\u4f18\u70b9\u3002 \u5f53Pod\u7684\u4e00\u4e2a\u526f\u672c\u5fc5\u987b\u5728\u67d0\u4e2a\u6307\u5b9a\u8282\u70b9\u4e0a\u8fd0\u884c\u65f6\uff0c\u6211\u4eec\u5c06\u4f7f\u7528 DaemonSet \u3002\u6211\u4eec\u7684\u5b88\u62a4\u8fdb\u7a0bPod\u8fd8\u9700\u8981\u5728\u6211\u4eec\u7684\u5176\u4ed6Pod\u4e4b\u524d\u542f\u52a8\u3002 DaemonSet\u662f\u7528\u4e8e\u540e\u53f0\u670d\u52a1\u7684\u7b80\u5355\u53ef\u6269\u5c55\u6027\u7b56\u7565\u3002\u5f53\u66f4\u591a\u7684\u5408\u9002\u7684\u8282\u70b9\u6dfb\u52a0\u5230\u96c6\u7fa4\u65f6\uff0c\u540e\u53f0\u670d\u52a1\u5c06\u6269\u5c55\u3002\u5f53\u8282\u70b9\u88ab\u5220\u9664\u65f6\uff0c\u5b83\u5c06\u81ea\u52a8\u7f29\u5c0f\u3002 Job \u00b6 CronJob \u00b6 \u670d\u52a1\u8d44\u6e90 \u00b6 Service \u00b6 Service\u662f\u8f6f\u4ef6\u670d\u52a1\uff08\u4f8b\u5982mysql\uff09\u7684\u547d\u540d\u62bd\u8c61\uff0c\u7531\u4ee3\u7406\u76d1\u542c\u7684\u672c\u5730\u7aef\u53e3\uff08\u4f8b\u59823306\uff09\u548c\u786e\u5b9a\u54ea\u4e9bPod\u5c06\u56de\u7b54\u901a\u8fc7\u4ee3\u7406\u53d1\u9001\u7684\u8bf7\u6c42\u7684\u9009\u62e9\u5668\u7ec4\u6210\u3002 \u4e00\u4e2aService\u7684\u76ee\u6807Pod\u96c6\u5408\u901a\u5e38\u7531\u4e00\u4e2a\u9009\u62e9\u5668\uff08\u6807\u7b7e\u9009\u62e9\u5668\uff09\u6765\u786e\u5b9a\u3002 Service\u8d44\u6e90\u7684\u7c7b\u578b\u5305\u62ec\uff1a ClusterIP Service\uff08\u9ed8\u8ba4\uff09\uff1a\u53ef\u9760\u7684IP\u3001DNS\u548c\u7aef\u53e3\u3002\u4ec5\u9650\u5185\u90e8\u8bbf\u95ee\u3002 NodePort Service\uff1a\u5411\u5916\u90e8\u63d0\u4f9b\u8bbf\u95ee\u3002 LoadBalancer\uff1a\u57fa\u4e8eNodePort\uff0c\u5e76\u4e0e\u4e91\u4f9b\u5e94\u5546\u63d0\u4f9b\u7684\u8d1f\u8f7d\u5e73\u8861\u96c6\u6210\uff08\u4f8b\u5982AWS\u3001GCP\u7b49\uff09\u3002 ExternalName\uff1a\u8bbf\u95ee\u5c06\u88ab\u8f6c\u53d1\u5230\u5916\u90e8\u670d\u52a1\u3002 \u4e0b\u9762\u662f\u4e00\u4e2a\u521b\u5efa\u7b80\u5355Service\u7684yaml\u6587\u4ef6\uff1a apiVersion : v1 kind : Service metadata : name : nginx-service labels : tier : application spec : ports : - port : 80 protocol : TCP targetPort : 8080 selector : run : nginx type : NodePort \u4e0b\u9762\u662f\u4e00\u4e2aService\u7684\u4f8b\u5b50\uff1a IP 10.96.17.77 \u662f\u8be5\u670d\u52a1\u7684 ClusterIP(VIP)\u3002 \u7aef\u53e3 80/TCP \u662f Pod \u5728\u96c6\u7fa4\u5185\u76d1\u542c\u7684\u7aef\u53e3\u3002 TargetPort 8080/TCP \u662f\u5bb9\u5668\u5185\u670d\u52a1\u5e94\u8be5\u5b9a\u5411\u6d41\u91cf\u5230\u8fbe\u7684\u7aef\u53e3\u3002 NodePort 31893/TCP \u662f\u53ef\u4ee5\u4ece\u5916\u90e8\u8bbf\u95ee\u7684\u7aef\u53e3\u3002\u9ed8\u8ba4\u8303\u56f4\u662f 30000~32767 \u3002\u8be5\u7aef\u53e3\u4f1a\u5728\u6574\u4e2a\u96c6\u7fa4\u7684\u6240\u6709\u8282\u70b9\u4e0a\u66b4\u9732\u3002 Endpoints \u663e\u793a\u4e86\u5339\u914d\u670d\u52a1\u6807\u7b7e\u7684 Pod \u5217\u8868\u3002 Name : nginx-deployment Namespace : jh-namespace Labels : tier=application Annotations : Selector : run=nginx Type : NodePort IP Family Policy : SingleStack IP Families : IPv4 IP : 10.96.17.77 IPs : 10.96.17.77 Port : 80/TCP TargetPort : 8080/TCP NodePort : 31893/TCP Endpoints : 10.244.1.177:8080,10.244.1.178:8080,10.244.1.179:8080 + 7 more... Session Affinity : None External Traffic Policy : Cluster Events : \u5728 Kubernetes \u96c6\u7fa4\u4e2d\uff0c\u57fa\u4e8eDeployment coredns \u7684Service kube-dns \u63d0\u4f9b\u4e86\u96c6\u7fa4 DNS \u670d\u52a1\u3002 \u670d\u52a1\u6ce8\u518c\uff1a Kubernetes \u4f7f\u7528\u96c6\u7fa4 DNS \u4f5c\u4e3a\u670d\u52a1\u6ce8\u518c\u3002 \u6ce8\u518c\u662f\u57fa\u4e8e Service \u800c\u975e Pod \u7684\u3002 \u96c6\u7fa4 DNS\uff08CoreDNS\uff09\u4e3b\u52a8\u76d1\u89c6\u548c\u53d1\u73b0\u65b0\u670d\u52a1\u3002 Service \u540d\u79f0\u3001IP\u3001\u7aef\u53e3\u5c06\u88ab\u6ce8\u518c\u3002 Service \u6ce8\u518c\u7684\u8fc7\u7a0b\u5982\u4e0b\uff1a \u5c06\u65b0\u7684 Service POST \u5230 API Server\u3002 \u4e3a\u65b0\u7684 Service \u5206\u914d ClusterIP\u3002 \u5c06\u65b0\u7684 Service \u914d\u7f6e\u4fe1\u606f\u4fdd\u5b58\u5230 etcd \u4e2d\u3002 \u521b\u5efa\u4e0e\u65b0 Service \u5173\u8054\u7684\u5e26\u6709\u76f8\u5173 Pod IP \u7684 endpoints\u3002 \u901a\u8fc7 ClusterDNS \u63a2\u7d22\u65b0\u7684 Service\u3002 \u521b\u5efa DNS \u4fe1\u606f\u3002 kube-proxy \u83b7\u53d6 Service \u914d\u7f6e\u4fe1\u606f\u3002 \u521b\u5efa IPSV \u89c4\u5219\u3002 Service \u53d1\u73b0\u7684\u8fc7\u7a0b\u3002 \u8bf7\u6c42\u4e00\u4e2a Service \u540d\u79f0\u7684 DNS \u540d\u79f0\u89e3\u6790\u3002 \u6536\u5230 ClusterIP\u3002 \u8bbf\u95ee ClusterIP\u3002 \u6ca1\u6709\u8def\u7531\u5668\u3002\u5c06\u8bf7\u6c42\u8f6c\u53d1\u5230 Pod \u7684\u9ed8\u8ba4\u7f51\u5173\u3002 \u5c06\u8bf7\u6c42\u8f6c\u53d1\u5230\u8282\u70b9\u3002 \u6ca1\u6709\u8def\u7531\u5668\u3002\u5c06\u8bf7\u6c42\u8f6c\u53d1\u5230\u8282\u70b9\u7684\u9ed8\u8ba4\u7f51\u5173\u3002 \u8282\u70b9\u5185\u6838\u7ee7\u7eed\u5904\u7406\u8bf7\u6c42\u3002 \u4f7f\u7528 IPSV \u89c4\u5219\u6355\u83b7\u8bf7\u6c42\u3002 \u5c06\u76ee\u6807 Pod \u7684 IP \u653e\u5165\u8bf7\u6c42\u7684\u76ee\u6807 IP \u4e2d\u3002 \u8bf7\u6c42\u5230\u8fbe\u76ee\u6807 Pod\u3002 FQDN\u683c\u5f0f\u4e3a\uff1a ..svc.cluster.local \u3002\u6211\u4eec\u79f0 \u4e3a\u975e\u9650\u5b9a\u540d\u79f0\u6216\u7b80\u77ed\u540d\u79f0\u3002 \u547d\u540d\u7a7a\u95f4\u53ef\u4ee5\u9694\u79bb\u96c6\u7fa4\u7684\u5730\u5740\u7a7a\u95f4\u3002\u540c\u65f6\uff0c\u5b83\u8fd8\u53ef\u4ee5\u7528\u4e8e\u5b9e\u73b0\u8bbf\u95ee\u63a7\u5236\u548c\u8d44\u6e90\u914d\u989d\u3002 \u83b7\u53d6Pod\u4e2d\u7684DNS\u914d\u7f6e\u3002 nameserver\u7684IP\u4e0ekube-dns\u670d\u52a1\u7684ClusterIP\u76f8\u540c\uff0c\u8fd9\u662f\u7528\u4e8eDNS\u8bf7\u6c42\u6216\u670d\u52a1\u53d1\u73b0\u8bf7\u6c42\u7684\u4f17\u6240\u5468\u77e5\u7684IP\u3002 $ kubectl get service kube-dns -n kube-system NAME TYPE CLUSTER-IP EXTERNAL-IP PORT ( S ) AGE kube-dns ClusterIP 10 .96.0.10 53 /UDP,53/TCP,9153/TCP 7d7h $ kubectl exec -it nginx-5f5496dc9-bv5dx -- /bin/bash root@nginx-5f5496dc9-bv5dx:/# cat /etc/resolv.conf search jh-namespace.svc.cluster.local svc.cluster.local cluster.local nameserver 10 .96.0.10 options ndots:5 \u8bfb\u53d6 kube-dns \u4fe1\u606f\uff1a $ kubectl describe service kube-dns -n kube-system Name: kube-dns Namespace: kube-system Labels: k8s-app = kube-dns kubernetes.io/cluster-service = true kubernetes.io/name = CoreDNS Annotations: prometheus.io/port: 9153 prometheus.io/scrape: true Selector: k8s-app = kube-dns Type: ClusterIP IP Family Policy: SingleStack IP Families: IPv4 IP: 10 .96.0.10 IPs: 10 .96.0.10 Port: dns 53 /UDP TargetPort: 53 /UDP Endpoints: 10 .244.0.2:53,10.244.0.3:53 Port: dns-tcp 53 /TCP TargetPort: 53 /TCP Endpoints: 10 .244.0.2:53,10.244.0.3:53 Port: metrics 9153 /TCP TargetPort: 9153 /TCP Endpoints: 10 .244.0.2:9153,10.244.0.3:9153 Session Affinity: None Events: Endpoints \u00b6 Endpoints\u662f\u4e00\u7ec4\u5b9e\u73b0\u5b9e\u9645\u670d\u52a1\u7684\u7aef\u70b9\u96c6\u5408\u3002 \u5f53\u521b\u5efa\u670d\u52a1\u65f6\uff0c\u5b83\u4f1a\u4e0e\u4e00\u4e2aEndpoint\u5bf9\u8c61\u76f8\u5173\u8054\uff0c\u53ef\u4ee5\u4f7f\u7528\u547d\u4ee4 kubectl get endpoints \u83b7\u53d6\u3002 \u5339\u914d\u670d\u52a1\u6807\u7b7e\u7684Pod\u5217\u8868\u7ef4\u62a4\u4e3aEndpoint\u5bf9\u8c61\uff0c\u6dfb\u52a0\u65b0\u7684\u5339\u914dPod\u5e76\u5220\u9664\u4e0d\u5339\u914d\u7684Pod\u3002 \u914d\u7f6e\u548c\u5b58\u50a8\u8d44\u6e90 \u00b6 \u5377 \u00b6 emptyDir \u00b6 emptyDir \u5377\u662f\u5728Pod\u5206\u914d\u5230\u8282\u70b9\u65f6\u9996\u5148\u521b\u5efa\u7684\uff0c\u5e76\u4e14\u53ea\u8981\u8be5Pod\u5728\u8be5\u8282\u70b9\u4e0a\u8fd0\u884c\uff0c\u5b83\u5c31\u4f1a\u5b58\u5728\u3002 emptyDir \u5377\u6700\u521d\u4e3a\u7a7a\u3002 Pod\u4e2d\u7684\u6240\u6709\u5bb9\u5668\u90fd\u53ef\u4ee5\u8bfb\u53d6\u548c\u5199\u5165 emptyDir \u5377\u4e2d\u7684\u76f8\u540c\u6587\u4ef6\uff0c\u5c3d\u7ba1\u8be5\u5377\u53ef\u4ee5\u5728\u6bcf\u4e2a\u5bb9\u5668\u4e2d\u4ee5\u76f8\u540c\u6216\u4e0d\u540c\u7684\u8def\u5f84\u6302\u8f7d\u3002 \u5f53\u7531\u4e8e\u4efb\u4f55\u539f\u56e0\u4ece\u8282\u70b9\u4e2d\u5220\u9664Pod\u65f6\uff0c emptyDir \u4e2d\u7684\u6570\u636e\u5c06\u6c38\u4e45\u5220\u9664\u3002 \u5bb9\u5668\u5d29\u6e83\u4e0d\u4f1a\u5c06Pod\u4ece\u8282\u70b9\u4e2d\u5220\u9664\u3002 emptyDir \u5377\u4e2d\u7684\u6570\u636e\u53ef\u4ee5\u5728\u5bb9\u5668\u5d29\u6e83\u65f6\u5b89\u5168\u4fdd\u7559\u3002 \u7528\u9014\uff1a \u4e34\u65f6\u7a7a\u95f4\uff0c\u4f8b\u5982\u57fa\u4e8e\u78c1\u76d8\u7684\u5f52\u5e76\u6392\u5e8f \u4e3a\u4e86\u4ece\u5d29\u6e83\u4e2d\u6062\u590d\u800c\u8fdb\u884c\u7684\u957f\u65f6\u95f4\u8ba1\u7b97\u7684\u68c0\u67e5\u70b9 \u4fdd\u5b58\u5185\u5bb9\u7ba1\u7406\u5668\u5bb9\u5668\u63d0\u53d6\u7684\u6587\u4ef6\uff0c\u540c\u65f6Web\u670d\u52a1\u5668\u5bb9\u5668\u63d0\u4f9b\u6570\u636e hostPath \u00b6 hostPath \u5377\u5c06\u4e3b\u673a\u8282\u70b9\u6587\u4ef6\u7cfb\u7edf\u4e2d\u7684\u6587\u4ef6\u6216\u76ee\u5f55\u6302\u8f7d\u5230 Pod \u4e2d\u3002\u8fd9\u4e0d\u662f\u5927\u591a\u6570 Pod \u90fd\u9700\u8981\u7684\uff0c\u4f46\u5bf9\u4e8e\u67d0\u4e9b\u5e94\u7528\u7a0b\u5e8f\u6765\u8bf4\uff0c\u5b83\u63d0\u4f9b\u4e86\u4e00\u4e2a\u5f3a\u5927\u7684\u9003\u751f\u53e3\u3002 hostPath \u5377\u5b58\u5728\u8bb8\u591a\u5b89\u5168\u98ce\u9669\uff0c\u56e0\u6b64\u5728\u53ef\u80fd\u7684\u60c5\u51b5\u4e0b\u6700\u597d\u907f\u514d\u4f7f\u7528 HostPath\u3002\u5f53\u5fc5\u987b\u4f7f\u7528 HostPath \u5377\u65f6\uff0c\u5e94\u5c06\u5176\u8303\u56f4\u9650\u5b9a\u4e3a\u4ec5\u6240\u9700\u7684\u6587\u4ef6\u6216\u76ee\u5f55\uff0c\u5e76\u4ee5\u53ea\u8bfb\u65b9\u5f0f\u6302\u8f7d\u3002 \u5982\u679c\u901a\u8fc7 AdmissionPolicy \u9650\u5236 HostPath \u8bbf\u95ee\u7279\u5b9a\u76ee\u5f55\uff0c\u5219\u5fc5\u987b\u8981\u6c42 volumeMounts \u4f7f\u7528 readOnly \u6302\u8f7d\uff0c\u4ee5\u4f7f\u7b56\u7565\u751f\u6548\u3002 \u7528\u9014\uff1a \u4e0e DaemonSet \u4e00\u8d77\u8fd0\u884c\uff0c\u4f8b\u5982\uff0cEFK Fluentd \u6302\u8f7d\u672c\u5730\u4e3b\u673a\u7684\u65e5\u5fd7\u76ee\u5f55\u4ee5\u6536\u96c6\u4e3b\u673a\u65e5\u5fd7\u4fe1\u606f\u3002 \u901a\u8fc7\u4f7f\u7528 hostPath \u5377\u5728\u7279\u5b9a\u8282\u70b9\u4e0a\u8fd0\u884c\uff0c\u53ef\u4ee5\u83b7\u5f97\u9ad8\u6027\u80fd\u7684\u78c1\u76d8 I/O\u3002 \u8fd0\u884c\u9700\u8981\u8bbf\u95ee Docker \u5185\u90e8\u7684\u5bb9\u5668\uff1b\u4f7f\u7528 /var/lib/docker \u7684 hostPath\u3002 \u5728\u5bb9\u5668\u4e2d\u8fd0\u884c cAdvisor\uff1b\u4f7f\u7528 /sys \u7684 hostPath\u3002 \u5141\u8bb8 Pod \u6307\u5b9a\u7ed9\u5b9a\u7684 hostPath \u662f\u5426\u5e94\u8be5\u5728 Pod \u8fd0\u884c\u4e4b\u524d\u5b58\u5728\uff0c\u662f\u5426\u5e94\u8be5\u521b\u5efa\u5b83\u4ee5\u53ca\u5b83\u5e94\u8be5\u5b58\u5728\u7684\u5185\u5bb9\u3002 Storage Class \u00b6 StorageClass \u90e8\u7f72\u548c\u5b9e\u73b0\u7684\u6b65\u9aa4\u5982\u4e0b\uff1a \u521b\u5efa Kubernetes \u96c6\u7fa4\u548c\u540e\u7aef\u5b58\u50a8\u3002 \u786e\u4fdd Kubernetes \u4e2d\u7684 provisioner/plugin \u53ef\u7528\u3002 \u521b\u5efa\u4e00\u4e2a StorageClass \u5bf9\u8c61\u5e76\u5c06\u5176\u94fe\u63a5\u5230\u540e\u7aef\u5b58\u50a8\u3002StorageClass \u5c06\u81ea\u52a8\u521b\u5efa\u76f8\u5173\u7684 PV\u3002 \u521b\u5efa\u4e00\u4e2a PVC \u5bf9\u8c61\u5e76\u5c06\u5176\u94fe\u63a5\u5230\u6211\u4eec\u521b\u5efa\u7684 StorageClass\u3002 \u90e8\u7f72\u4e00\u4e2a Pod \u5e76\u4f7f\u7528 PVC \u5377\u3002 PV \u00b6 PV\u56de\u6536\u7b56\u7565\uff1a \u4fdd\u7559 (Retain) \u5220\u9664 (Delete) \u56de\u6536 (Recycle) PV in-tree\u7c7b\u578b\uff1a hostPath local NFS CSI Access Modes \u00b6 Access Modes\uff08\u8bbf\u95ee\u6a21\u5f0f\uff09\u4e2d\uff0c spec.accessModes \u5b9a\u4e49\u4e86 PV \u7684\u6302\u8f7d\u9009\u9879\uff1a ReadWriteOnce(RWO)\uff1a\u4e00\u4e2a PV \u53ea\u80fd\u88ab\u4e00\u4e2a\u8bfb\u5199\u6a21\u5f0f\u7684 PVC \u6302\u8f7d\uff0c\u7c7b\u4f3c\u4e8e\u5757\u8bbe\u5907\u3002 ReadWriteMany(RWM)\uff1a\u4e00\u4e2a PV \u53ef\u4ee5\u88ab\u591a\u4e2a\u8bfb\u5199\u6a21\u5f0f\u7684 PVC \u6302\u8f7d\uff0c\u4f8b\u5982 NFS\u3002 ReadOnlyMany(ROM)\uff1a\u4e00\u4e2a PV \u53ef\u4ee5\u88ab\u591a\u4e2a\u53ea\u8bfb\u6a21\u5f0f\u7684 PVC \u6302\u8f7d\u3002 ReadWriteOncePod(RWOP)\uff1a\u53ea\u652f\u6301 CSI \u7c7b\u578b\u7684 PV\uff0c\u53ea\u80fd\u88ab\u5355\u4e2a Pod \u6302\u8f7d\u3002 \u4e00\u4e2a PV \u53ea\u80fd\u8bbe\u7f6e\u4e00\u79cd\u9009\u9879\u3002Pod \u6302\u8f7d PVC\uff0c\u800c\u4e0d\u662f PV\u3002","title":"Kubernetes\u968f\u7b14"},{"location":"k8s/cka_cn/foundamentals/memo/#cka5kubernetes","text":"","title":"CKA\u81ea\u5b66\u7b14\u8bb05:Kubernetes\u968f\u7b14"},{"location":"k8s/cka_cn/foundamentals/memo/#_1","text":"\u8fb9\u7ec3\u4e60\u8fb9\u8bb0\u5f55\u7684\u5185\u5bb9\uff0c\u4e0d\u662f\u5168\u9762\u7cfb\u7edf\u7684\uff0c\u5305\u62ec\u4e0b\u9762\u4e3b\u8981\u5185\u5bb9\uff1a Kubernetes\u57fa\u672c\u6982\u5ff5 \u7ec4\u4ef6 API \u5bf9\u8c61 \u8d44\u6e90 \u5de5\u4f5c\u8d1f\u8f7d\u8d44\u6e90 Pod Deployment ReplicaSet StatefulSet DaemonSet Job CronJob \u670d\u52a1\u8d44\u6e90 Service Endpoints \u914d\u7f6e\u548c\u5b58\u50a8\u8d44\u6e90 \u5377 Storage Class PV Access Modes","title":"\u6458\u8981"},{"location":"k8s/cka_cn/foundamentals/memo/#kubernetes","text":"","title":"Kubernetes\u57fa\u672c\u6982\u5ff5"},{"location":"k8s/cka_cn/foundamentals/memo/#kubernetes_1","text":"\u4e00\u4e2aKubernetes\u96c6\u7fa4\u7531\u4ee3\u8868\u63a7\u5236\u5e73\u9762\uff08control plane\uff09\u7684\u7ec4\u4ef6\u548c\u4e00\u7ec4\u79f0\u4e3a\u8282\u70b9\uff08nodes\uff09\u7684\u673a\u5668\u7ec4\u6210\u3002 Kubernetes\u7ec4\u4ef6: \u63a7\u5236\u5e73\u9762\u7ec4\u4ef6 Control Plane Components kube-apiserver: \u67e5\u8be2\u548c\u64cd\u4f5c Kubernetes \u4e2d\u5bf9\u8c61\u7684\u72b6\u6001\u3002 \u5145\u5f53\u6240\u6709\u8d44\u6e90\u4e4b\u95f4\u7684\u901a\u4fe1\u4e2d\u5fc3\uff08communication hub\uff09\u3002 \u63d0\u4f9b\u96c6\u7fa4\u5b89\u5168\u8eab\u4efd\u9a8c\u8bc1\u3001\u6388\u6743\u548c\u89d2\u8272\u5206\u914d\u3002 \u662f\u552f\u4e00\u80fd\u8fde\u63a5\u5230 etcd \u7684\u7ec4\u4ef6\u3002 etcd: \u6240\u6709 Kubernetes \u5bf9\u8c61\u90fd\u5b58\u50a8\u5728 etcd \u4e2d\u3002 Kubernetes \u5bf9\u8c61\u662f Kubernetes \u7cfb\u7edf\u4e2d\u7684\u6301\u4e45\u5b9e\u4f53(entities)\uff0c\u7528\u4e8e\u8868\u793a\u96c6\u7fa4\u7684\u72b6\u6001\u3002 kube-scheduler: \u76d1\u89c6\u6ca1\u6709\u5206\u914d\u8282\u70b9\u7684\u65b0\u521b\u5efa\u7684 Pod\uff0c\u5e76\u4e3a\u5b83\u4eec\u9009\u62e9\u4e00\u4e2a\u8282\u70b9\u6765\u8fd0\u884c\u3002 kube-controller-manager: \u8fd0\u884c\u63a7\u5236\u5668\u8fdb\u7a0b\u3002 Node controller : \u8d1f\u8d23\u8b66\u793a\u548c\u54cd\u5e94\u8282\u70b9\u7684\u6545\u969c\u3002 Job controller : \u76d1\u89c6\u8868\u793a\u4e00\u6b21\u6027\u4efb\u52a1\u7684 Job \u5bf9\u8c61\uff0c\u7136\u540e\u521b\u5efa Pod \u6765\u5b8c\u6210\u8fd9\u4e9b\u4efb\u52a1\u3002 Endpoints controller : \u586b\u5145 Endpoints \u5bf9\u8c61\uff08\u5373\u5c06 Service \u548c Pod \u8fde\u63a5\u8d77\u6765\uff09\u3002 Service Account & Token controllers : \u4e3a\u65b0\u547d\u540d\u7a7a\u95f4\u521b\u5efa\u9ed8\u8ba4\u5e10\u6237\u548c API \u8bbf\u95ee\u4ee4\u724c\u3002 cloud-controller-manager: \u5d4c\u5165\u4e91\u7279\u5b9a\u7684\u63a7\u5236\u903b\u8f91\uff0c\u4ec5\u8fd0\u884c\u7279\u5b9a\u4e8e\u6211\u4eec\u9009\u62e9\u7684\u4e91\u63d0\u4f9b\u5546\u7684\u63a7\u5236\u5668\uff0c\u65e0\u9700\u81ea\u5df1\u7684\u57fa\u7840\u8bbe\u65bd\u548c\u5b66\u4e60\u73af\u5883\u3002 Node controller : \u7528\u4e8e\u68c0\u67e5\u4e91\u63d0\u4f9b\u5546\uff0c\u4ee5\u786e\u5b9a\u8282\u70b9\u5728\u5728\u5b83\u505c\u6b62\u54cd\u5e94\u540e\u662f\u5426\u5df2\u5728\u4e91\u4e2d\u88ab\u5220\u9664\u3002 Route controller : \u7528\u4e8e\u5728\u5e95\u5c42\u4e91\u57fa\u7840\u67b6\u6784\u4e2d\u8bbe\u7f6e\u8def\u7531\u3002 Service controller : \u7528\u4e8e\u521b\u5efa\u3001\u66f4\u65b0\u548c\u5220\u9664\u4e91\u63d0\u4f9b\u5546\u8d1f\u8f7d\u5747\u8861\u5668\u3002 \u8282\u70b9\u7ec4\u4ef6 Node Components kubelet: \u5728\u96c6\u7fa4\u4e2d\u6bcf\u4e2a\u8282\u70b9\u4e0a\u8fd0\u884c\u7684\u4ee3\u7406\u3002 \u7ba1\u7406\u8282\u70b9\u3002\u5b83\u786e\u4fdd Pod \u4e2d\u8fd0\u884c\u5bb9\u5668\u3002 kubelet \u5411 APIServer \u6ce8\u518c\u548c\u66f4\u65b0\u8282\u70b9\u4fe1\u606f\uff0cAPIServer \u5c06\u5b83\u4eec\u5b58\u50a8\u5230 etcd \u4e2d\u3002 \u7ba1\u7406 Pod\u3002\u901a\u8fc7 APIServer \u76d1\u89c6 Pod\uff0c\u5e76\u5bf9 Pod \u6216 Pod \u4e2d\u7684\u5bb9\u5668\u91c7\u53d6\u884c\u52a8\u3002 \u5728\u5bb9\u5668\u7ea7\u522b\u8fdb\u884c\u5065\u5eb7\u68c0\u67e5\u3002 kube-proxy: \u662f\u5728\u96c6\u7fa4\u4e2d\u6bcf\u4e2a\u8282\u70b9\u4e0a\u8fd0\u884c\u7684\u7f51\u7edc\u4ee3\u7406\u3002 iptables ipvs \u7ef4\u62a4\u8282\u70b9\u4e0a\u7684\u7f51\u7edc\u89c4\u5219\u3002 \u5bb9\u5668\u8fd0\u884c\u65f6Container runtime\uff1a \u8d1f\u8d23\u8fd0\u884c\u5bb9\u5668\u7684\u8f6f\u4ef6\u3002 \u63d2\u4ef6Addons DNS: \u662f DNS \u670d\u52a1\u5668\uff0c\u662f\u6240\u6709 Kubernetes \u96c6\u7fa4\u6240\u5fc5\u9700\u7684\u3002 Web UI\uff08\u4eea\u8868\u76d8\uff09\uff1a\u7528\u4e8e Kubernetes \u96c6\u7fa4\u7684\u57fa\u4e8e Web \u7684\u7528\u6237\u754c\u9762\u3002 \u5bb9\u5668\u8d44\u6e90\u76d1\u63a7\uff1a\u8bb0\u5f55\u6709\u5173\u96c6\u4e2d\u5f0f\u6570\u636e\u5e93\u4e2d\u5bb9\u5668\u7684\u901a\u7528\u65f6\u95f4\u5e8f\u5217\u5ea6\u91cf\u3002 Cluster-level Logging\uff1a\u8d1f\u8d23\u5c06\u5bb9\u5668\u65e5\u5fd7\u4fdd\u5b58\u5230\u5177\u6709\u641c\u7d22/\u6d4f\u89c8\u63a5\u53e3\u7684\u4e2d\u592e\u65e5\u5fd7\u5b58\u50a8\u4e2d\u3002 \u53ef\u6269\u5c55\u6027\uff1a \u6c34\u5e73\u6269\u5c55\uff08Scaling out\uff09\u901a\u8fc7\u6dfb\u52a0\u66f4\u591a\u7684\u670d\u52a1\u5668\u5230\u67b6\u6784\u4e2d\uff0c\u5c06\u5de5\u4f5c\u8d1f\u8f7d\u5206\u6563\u5230\u66f4\u591a\u7684\u673a\u5668\u4e0a\u3002 \u5782\u76f4\u6269\u5c55\uff08Scaling up\uff09\u901a\u8fc7\u6dfb\u52a0\u66f4\u591a\u7684\u786c\u76d8\u548c\u5185\u5b58\u6765\u589e\u52a0\u7269\u7406\u670d\u52a1\u5668\u7684\u8ba1\u7b97\u80fd\u529b\u3002","title":"Kubernetes\u7ec4\u4ef6"},{"location":"k8s/cka_cn/foundamentals/memo/#kubernetes-api","text":"REST API\u662fKubernetes\u7684\u57fa\u672c\u6846\u67b6\u3002\u6240\u6709\u7ec4\u4ef6\u4e4b\u95f4\u7684\u64cd\u4f5c\u548c\u901a\u4fe1\uff0c\u4ee5\u53ca\u5916\u90e8\u7528\u6237\u547d\u4ee4\u90fd\u662f\u7531API\u670d\u52a1\u5668\u5904\u7406\u7684REST API\u8c03\u7528\u3002\u56e0\u6b64\uff0cKubernetes\u5e73\u53f0\u4e2d\u7684\u6240\u6709\u5185\u5bb9\u90fd\u88ab\u89c6\u4e3aAPI\u5bf9\u8c61\uff08API object\uff09\uff0c\u5e76\u5728API\u4e2d\u6709\u76f8\u5e94\u7684\u6761\u76ee\u3002 Kubernetes\u63a7\u5236\u5e73\u9762\u7684\u6838\u5fc3\u662fAPI\u670d\u52a1\u5668\u3002 CRI\uff1a\u5bb9\u5668\u8fd0\u884c\u65f6\u63a5\u53e3 CNI\uff1a\u5bb9\u5668\u7f51\u7edc\u63a5\u53e3 CSI\uff1a\u5bb9\u5668\u5b58\u50a8\u63a5\u53e3 API\u670d\u52a1\u5668\u516c\u5f00\u4e86\u4e00\u4e2aHTTP API\uff0c\u5141\u8bb8\u6700\u7ec8\u7528\u6237\u3001\u96c6\u7fa4\u7684\u4e0d\u540c\u90e8\u5206\u548c\u5916\u90e8\u7ec4\u4ef6\u5f7c\u6b64\u901a\u4fe1\u3002 Kubernetes API\u5141\u8bb8\u6211\u4eec\u67e5\u8be2\u548c\u64cd\u4f5cKubernetes\u4e2dAPI\u5bf9\u8c61\u7684\u72b6\u6001\uff08\u4f8b\u5982\uff1aPod\u3001Namespace\u3001ConfigMap\u548cEvent\uff09\u3002 Kubernetes API\uff1a OpenAPI\u89c4\u8303 OpenAPI V2 OpenAPI V3 \u6301\u4e45\u6027\u3002Kubernetes\u901a\u8fc7\u5c06\u5bf9\u8c61\u7684\u5e8f\u5217\u5316\u72b6\u6001\u5199\u5165etcd\u6765\u5b58\u50a8\u5b83\u4eec\u3002 API\u7ec4\u548c\u7248\u672c\u63a7\u5236\u3002\u7248\u672c\u63a7\u5236\u662f\u5728API\u7ea7\u522b\u8fdb\u884c\u7684\u3002API\u8d44\u6e90\u901a\u8fc7\u5b83\u4eec\u7684API\u7ec4\u3001\u8d44\u6e90\u7c7b\u578b\u3001\u547d\u540d\u7a7a\u95f4\uff08\u7528\u4e8e\u547d\u540d\u7a7a\u95f4\u8d44\u6e90\uff09\u548c\u540d\u79f0\u8fdb\u884c\u533a\u5206\u3002 API\u66f4\u6539 API\u6269\u5c55","title":"Kubernetes API"},{"location":"k8s/cka_cn/foundamentals/memo/#api-version","text":"API\u7248\u672c\u548c\u8f6f\u4ef6\u7248\u672c\u95f4\u5b58\u5728\u95f4\u63a5\u5173\u7cfb\u3002API\u548c\u53d1\u5e03\u7248\u672c\u8ba1\u5212\u63cf\u8ff0\u4e86API\u7248\u672c\u548c\u8f6f\u4ef6\u7248\u672c\u4e4b\u95f4\u7684\u5173\u7cfb\u3002\u4e0d\u540c\u7684API\u7248\u672c\u8868\u793a\u4e0d\u540c\u7684\u7a33\u5b9a\u6027\u548c\u652f\u6301\u7ea7\u522b\u3002 \u4ee5\u4e0b\u662f\u6bcf\u4e2a\u7ea7\u522b\u7684\u6458\u8981\uff1a Alpha\uff1a \u7248\u672c\u540d\u79f0\u5305\u542balpha\uff08\u4f8b\u5982\uff0cv1alpha1\uff09\u3002 \u8f6f\u4ef6\u53ef\u80fd\u5305\u542b\u9519\u8bef\u3002\u542f\u7528\u529f\u80fd\u53ef\u80fd\u4f1a\u66b4\u9732\u9519\u8bef\u3002\u67d0\u4e9b\u529f\u80fd\u53ef\u80fd\u9ed8\u8ba4\u7981\u7528\u3002 \u5bf9\u4e8e\u67d0\u4e9b\u529f\u80fd\u7684\u652f\u6301\u53ef\u4ee5\u968f\u65f6\u53d6\u6d88\uff0c\u800c\u4e0d\u4f1a\u63d0\u524d\u901a\u77e5\u3002 API\u53ef\u80fd\u4f1a\u5728\u4ee5\u540e\u7684\u8f6f\u4ef6\u53d1\u5e03\u4e2d\u4ee5\u4e0d\u517c\u5bb9\u7684\u65b9\u5f0f\u66f4\u6539\uff0c\u800c\u4e0d\u4f1a\u63d0\u524d\u901a\u77e5\u3002 \u7531\u4e8e\u9519\u8bef\u98ce\u9669\u589e\u52a0\u548c\u957f\u671f\u652f\u6301\u4e0d\u8db3\uff0c\u5efa\u8bae\u4ec5\u5728\u77ed\u6682\u7684\u6d4b\u8bd5\u96c6\u7fa4\u4e2d\u4f7f\u7528\u8be5\u8f6f\u4ef6\u3002 Beta\uff1a \u7248\u672c\u540d\u79f0\u5305\u542bbeta\uff08\u4f8b\u5982\uff0cv2beta3\uff09\u3002 \u8f6f\u4ef6\u7ecf\u8fc7\u5145\u5206\u6d4b\u8bd5\u3002\u542f\u7528\u529f\u80fd\u88ab\u8ba4\u4e3a\u662f\u5b89\u5168\u7684\u3002\u67d0\u4e9b\u529f\u80fd\u9ed8\u8ba4\u542f\u7528\u3002 \u5bf9\u4e8e\u67d0\u4e9b\u529f\u80fd\u7684\u652f\u6301\u4e0d\u4f1a\u53d6\u6d88\uff0c\u4f46\u7ec6\u8282\u53ef\u80fd\u4f1a\u66f4\u6539\u3002 \u5bf9\u8c61\u7684\u6a21\u5f0f\u548c/\u6216\u8bed\u4e49\u53ef\u80fd\u4f1a\u5728\u540e\u7eed\u7684Beta\u6216\u7a33\u5b9a\u7248\u53d1\u5e03\u4e2d\u4ee5\u4e0d\u517c\u5bb9\u7684\u65b9\u5f0f\u66f4\u6539\u3002\u5f53\u53d1\u751f\u8fd9\u79cd\u60c5\u51b5\u65f6\uff0c\u5c06\u63d0\u4f9b\u8fc1\u79fb\u8bf4\u660e\u3002\u6a21\u5f0f\u66f4\u6539\u53ef\u80fd\u9700\u8981\u5220\u9664\u3001\u7f16\u8f91\u548c\u91cd\u65b0\u521b\u5efa API\u5bf9\u8c61\u3002\u7f16\u8f91\u8fc7\u7a0b\u53ef\u80fd\u4e0d\u7b80\u5355\u3002\u8fc1\u79fb\u53ef\u80fd\u9700\u8981\u505c\u673a\uff0c\u4ee5\u4fbf\u4f9d\u8d56\u4e8e\u8be5\u529f\u80fd\u7684\u5e94\u7528\u7a0b\u5e8f\u3002 \u4e0d\u5efa\u8bae\u5c06\u8be5\u8f6f\u4ef6\u7528\u4e8e\u751f\u4ea7\u7528\u9014\u3002\u540e\u7eed\u7684\u53d1\u5e03\u53ef\u80fd\u4f1a\u5f15\u5165\u4e0d\u517c\u5bb9\u7684\u66f4\u6539\u3002\u5982\u679c\u60a8\u6709\u591a\u4e2a\u53ef\u4ee5\u72ec\u7acb\u5347\u7ea7\u7684\u96c6\u7fa4\uff0c\u5219\u53ef\u4ee5\u653e\u5bbd\u6b64\u9650\u5236\u3002 \u6ce8\u610f\uff1a\u8bf7\u5c1d\u8bd5beta\u529f\u80fd\u5e76\u63d0\u4f9b\u53cd\u9988\u3002\u529f\u80fd\u9000\u51fabeta\u540e\uff0c\u53ef\u80fd\u4e0d\u5b9e\u9645\u518d\u8fdb\u884c\u66f4\u6539\u3002 \u7a33\u5b9a\u7248\uff1a \u7248\u672c\u540d\u79f0\u4e3avX\uff0c\u5176\u4e2dX\u662f\u6574\u6570\u3002 \u529f\u80fd\u7684\u7a33\u5b9a\u7248\u672c\u51fa\u73b0\u5728\u53d1\u5e03\u7684\u8f6f\u4ef6\u4e2d\u7684\u8bb8\u591a\u540e\u7eed\u7248\u672c\u4e2d\u3002 \u8bfb\u53d6\u5f53\u524dAPI\u7684\u7248\u672c\u547d\u4ee4\uff1a kubectl api-resources","title":"API Version"},{"location":"k8s/cka_cn/foundamentals/memo/#api-group","text":"API\u7ec4\uff08API groups\uff09 \u4f7f\u6269\u5c55Kubernetes API\u66f4\u52a0\u5bb9\u6613\u3002API\u7ec4\u5728REST\u8def\u5f84\u548c\u5e8f\u5217\u5316\u5bf9\u8c61\u7684apiVersion\u5b57\u6bb5\u4e2d\u6307\u5b9a\u3002 Kubernetes\u6709\u51e0\u4e2aAPI\u7ec4\uff1a \u6838\u5fc3\u7ec4\uff08\u4e5f\u79f0\u4e3a\u9057\u7559legacy\uff09\u4f4d\u4e8eREST\u8def\u5f84 /api/v1 \u3002 \u6838\u5fc3\u7ec4\u4e0d\u4f5c\u4e3aapiVersion\u5b57\u6bb5\u7684\u4e00\u90e8\u5206\u6307\u5b9a\uff0c\u4f8b\u5982 apiVersion: v1\u3002 \u547d\u540d\u7ec4\u4f4d\u4e8eREST\u8def\u5f84 /apis/$GROUP_NAME/$VERSION \uff0c\u5e76\u4f7f\u7528 apiVersion: $GROUP_NAME/$VERSION \uff08\u4f8b\u5982 apiVersion: batch/v1\uff09\u3002","title":"API Group"},{"location":"k8s/cka_cn/foundamentals/memo/#kubernetes_2","text":"","title":"Kubernetes\u5bf9\u8c61"},{"location":"k8s/cka_cn/foundamentals/memo/#_2","text":"\u5bf9\u8c61\u89c4\u8303\uff08Object Spec\uff09\uff1a \u63d0\u4f9b\u4e86\u4e00\u4e2a\u63cf\u8ff0\u6240\u521b\u5efa\u8d44\u6e90\u7684\u7279\u6027\u7684\u8bf4\u660e\uff1a \u5176\u671f\u671b\u7684\u72b6\u6001 \u3002 \u5bf9\u8c61\u72b6\u6001\uff08Object Status\uff09\uff1a \u63cf\u8ff0\u4e86\u5bf9\u8c61\u7684\u5f53\u524d\u72b6\u6001\u3002 \u6bd4\u5982\uff0cDeployment\u662f\u4e00\u4e2a\u53ef\u4ee5\u4ee3\u8868\u96c6\u7fa4\u4e0a\u8fd0\u884c\u7684\u5e94\u7528\u7a0b\u5e8f\u7684\u5bf9\u8c61\u3002 apiVersion : apps/v1 # \u5f53\u524d\u7528\u6765\u521b\u5efa\u5bf9\u8c61\u7684API\u7248\u672c kind : Deployment # \u521b\u5efa\u5bf9\u8c61\u7684\u7c7b\u578b metadata : # \u7528\u6765\u533a\u5206\u5bf9\u8c61\u7684\u5143\u6570\u636e\uff0c\u6bd4\u5982\uff1a\u540d\u79f0\uff0cUID\uff0c\u547d\u540d\u7a7a\u95f4\u7b49 name : nginx-deployment spec : # \u671f\u671b\u6240\u521b\u5efa\u5bf9\u8c61\u7684\u72b6\u6001 selector : matchLabels : app : nginx replicas : 2 # \u544a\u8bc9Deployment\u57fa\u4e8e\u4e0b\u9762\u7684\u6a21\u677ftemplate\u521b\u5efa2\u4e2aPods template : metadata : labels : app : nginx spec : containers : - name : nginx image : nginx:1.14.2 ports : - containerPort : 80","title":"\u5bf9\u8c61\u6982\u8ff0"},{"location":"k8s/cka_cn/foundamentals/memo/#_3","text":"kubectl \u547d\u4ee4\u884c\u5de5\u5177\u652f\u6301\u591a\u79cd\u4e0d\u540c\u7684\u65b9\u5f0f\u6765\u521b\u5efa\u548c\u7ba1\u7406 Kubernetes \u5bf9\u8c61\u3002\u8be6\u7ec6\u4fe1\u606f\u8bf7\u9605\u8bfb Kubectl book \u3002 \u4e00\u4e2a Kubernetes \u5bf9\u8c61\u5e94\u8be5\u4ec5\u4f7f\u7528\u4e00\u79cd\u6280\u672f\u8fdb\u884c\u7ba1\u7406\u3002\u6df7\u5408\u4f7f\u7528\u4e0d\u540c\u7684\u6280\u672f\u6765\u7ba1\u7406\u540c\u4e00\u4e2a\u5bf9\u8c61\u4f1a\u5bfc\u81f4\u975e\u9884\u671f\u7684\u7ed3\u679c\u3002 \u4e09\u79cd\u7ba1\u7406\u6280\u672f: \u547d\u4ee4\u5f0f\u547d\u4ee4 \u76f4\u63a5\u5728\u96c6\u7fa4\u4e2d\u64cd\u4f5c\u5b9e\u65f6\u5bf9\u8c61\u3002 kubectl create deployment nginx --image nginx \u547d\u4ee4\u5f0f\u5bf9\u8c61\u914d\u7f6e kubectl create -f nginx.yaml kubectl delete -f nginx.yaml -f redis.yaml kubectl replace -f nginx.yaml \u58f0\u660e\u5f0f\u5bf9\u8c61\u914d\u7f6e kubectl diff -f configs/ kubectl apply -f configs/","title":"\u5bf9\u8c61\u7ba1\u7406"},{"location":"k8s/cka_cn/foundamentals/memo/#id","text":"\u96c6\u7fa4\u4e2d\u7684\u6bcf\u4e2a\u5bf9\u8c61\u90fd\u6709\u4e00\u4e2a\u5728\u8be5\u8d44\u6e90\u7c7b\u578b\u4e2d\u552f\u4e00\u7684\u540d\u79f0\u3002 DNS \u5b50\u57df\u540d \u6807\u7b7e\u540d\u79f0 \u8def\u5f84\u6bb5\u540d\u79f0 \u6bcf\u4e2a Kubernetes \u5bf9\u8c61\u8fd8\u6709\u4e00\u4e2a UID\uff0c\u5728\u6574\u4e2a\u96c6\u7fa4\u4e2d\u662f\u552f\u4e00\u7684\u3002","title":"\u5bf9\u8c61\u540d\u79f0\u548cID"},{"location":"k8s/cka_cn/foundamentals/memo/#_4","text":"\u5728Kubernetes\u4e2d\uff0c\u547d\u540d\u7a7a\u95f4\u63d0\u4f9b\u4e86\u4e00\u79cd\u5728\u5355\u4e2a\u96c6\u7fa4\u5185\u9694\u79bb\u8d44\u6e90\u7ec4\u7684\u673a\u5236\u3002 \u8d44\u6e90\u7684\u540d\u79f0\u9700\u8981\u5728\u547d\u540d\u7a7a\u95f4\u5185\u662f\u552f\u4e00\u7684\uff0c\u4f46\u4e0d\u9700\u8981\u8de8\u547d\u540d\u7a7a\u95f4\u552f\u4e00\u3002 \u57fa\u4e8e\u547d\u540d\u7a7a\u95f4\u7684\u8303\u56f4\u4ec5\u9002\u7528\u4e8e\u547d\u540d\u7a7a\u95f4\u5bf9\u8c61\uff08\u4f8b\u5982\u90e8\u7f72\uff0c\u670d\u52a1\u7b49\uff09\uff0c\u800c\u4e0d\u9002\u7528\u4e8e\u96c6\u7fa4\u8303\u56f4\u7684\u5bf9\u8c61\uff08\u4f8b\u5982StorageClass\uff0c\u8282\u70b9\uff0c\u6301\u4e45\u5377\u7b49\uff09\u3002 \u5e76\u975e\u6240\u6709\u5bf9\u8c61\u90fd\u4f4d\u4e8e\u547d\u540d\u7a7a\u95f4\u4e2d\u3002 Kubernetes\u4ece\u56db\u4e2a\u521d\u59cb\u547d\u540d\u7a7a\u95f4\u5f00\u59cb\uff1a default \u7528\u4e8e\u6ca1\u6709\u5176\u4ed6\u547d\u540d\u7a7a\u95f4\u7684\u5bf9\u8c61\u7684\u9ed8\u8ba4\u547d\u540d\u7a7a\u95f4 kube-system Kubernetes\u7cfb\u7edf\u521b\u5efa\u7684\u5bf9\u8c61\u7684\u547d\u540d\u7a7a\u95f4 kube-public \u8be5\u547d\u540d\u7a7a\u95f4\u662f\u81ea\u52a8\u521b\u5efa\u7684\uff0c\u5e76\u53ef\u7531\u6240\u6709\u7528\u6237\uff08\u5305\u62ec\u672a\u7ecf\u8eab\u4efd\u9a8c\u8bc1\u7684\u7528\u6237\uff09\u8bfb\u53d6\u3002\u6b64\u547d\u540d\u7a7a\u95f4\u5927\u591a\u4fdd\u7559\u4f9b\u96c6\u7fa4\u4f7f\u7528\uff0c\u4ee5\u9632\u4e00\u4e9b\u8d44\u6e90\u5e94\u5728\u6574\u4e2a\u96c6\u7fa4\u8303\u56f4\u5185\u516c\u5f00\u548c\u53ef\u8bfb\u3002\u6b64\u547d\u540d\u7a7a\u95f4\u7684\u516c\u5171\u65b9\u9762\u53ea\u662f\u4e00\u79cd\u7ea6\u5b9a\uff0c\u800c\u4e0d\u662f\u8981\u6c42\u3002 kube-node-lease \u6b64\u547d\u540d\u7a7a\u95f4\u4fdd\u5b58\u4e0e\u6bcf\u4e2a\u8282\u70b9\u5173\u8054\u7684\u79df\u8d41\u5bf9\u8c61\u3002\u8282\u70b9\u79df\u8d41\u5141\u8bb8kubelet\u53d1\u9001\u5fc3\u8df3\uff0c\u4ee5\u4fbf\u63a7\u5236\u5e73\u9762\u53ef\u4ee5\u68c0\u6d4b\u5230\u8282\u70b9\u6545\u969c\u3002 \u67e5\u770b\u547d\u540d\u7a7a\u95f4\uff1a kubectl get namespace \u4e3a\u8bf7\u6c42\u8bbe\u7f6e\u547d\u540d\u7a7a\u95f4 kubectl run nginx --image=nginx --namespace=<\u63d2\u5165\u547d\u540d\u7a7a\u95f4\u540d\u79f0> kubectl get pods --namespace=<\u63d2\u5165\u547d\u540d\u7a7a\u95f4\u540d\u79f0>","title":"\u547d\u540d\u7a7a\u95f4"},{"location":"k8s/cka_cn/foundamentals/memo/#_5","text":"\u6807\u7b7e\u662f\u9644\u52a0\u5230\u5bf9\u8c61\uff08\u4f8b\u5982 Pod\uff09\u7684\u952e/\u503c\u5bf9\u3002\u6709\u6548\u7684\u6807\u7b7e\u952e\u6709\u4e24\u4e2a\u90e8\u5206\uff1a\u53ef\u9009\u7684\u524d\u7f00\u548c\u540d\u79f0\uff0c\u7531\u659c\u6760\uff08 / \uff09\u5206\u9694\u3002 \u6807\u7b7e\u65e8\u5728\u7528\u4e8e\u6307\u5b9a\u5bf9\u7528\u6237\u6709\u610f\u4e49\u548c\u76f8\u5173\u7684\u5bf9\u8c61\u8bc6\u522b\u5c5e\u6027\u3002 \u6807\u7b7e\u53ef\u7528\u4e8e\u7ec4\u7ec7\u548c\u9009\u62e9\u5bf9\u8c61\u5b50\u96c6\u3002\u6807\u7b7e\u53ef\u4ee5\u5728\u521b\u5efa\u5bf9\u8c61\u65f6\u9644\u52a0\uff0c\u968f\u540e\u5728\u4efb\u4f55\u65f6\u5019\u6dfb\u52a0\u548c\u4fee\u6539\u3002\u6bcf\u4e2a\u5bf9\u8c61\u53ef\u4ee5\u5b9a\u4e49\u4e00\u7ec4\u952e/\u503c\u6807\u7b7e\uff0c\u6bcf\u4e2a\u952e\u5fc5\u987b\u5bf9\u4e8e\u7ed9\u5b9a\u5bf9\u8c61\u662f\u552f\u4e00\u7684\u3002 \u6807\u7b7e\u7684\u793a\u4f8b\uff1a \"metadata\" : { \"labels\" : { \"key1\" : \"value1\" , \"key2\" : \"value2\" } } \u4e0e\u540d\u79f0\u548c UID \u4e0d\u540c\uff0c\u6807\u7b7e\u4e0d\u63d0\u4f9b\u552f\u4e00\u6027\u3002\u901a\u5e38\u60c5\u51b5\u4e0b\uff0c\u6211\u4eec\u671f\u671b\u8bb8\u591a\u5bf9\u8c61\u5e26\u6709\u76f8\u540c\u7684\u6807\u7b7e\u3002 \u76ee\u524d API \u652f\u6301\u4e24\u79cd\u7c7b\u578b\u7684\u9009\u62e9\u5668\uff1a \u57fa\u4e8e\u7b49\u5f0f\u7684\u9009\u62e9\u5668\uff0c\u4f8b\u5982\uff1a environment = production \u3001 tier != frontend \u57fa\u4e8e\u96c6\u5408\u7684\u9009\u62e9\u5668\uff0c\u4f8b\u5982\uff1a environment in (production, qa) \u3001 tier notin (frontend, backend) \u4f8b\u5982\uff1a kubectl get pods -l environment = production,tier = frontend kubectl get pods -l 'environment in (production),tier in (frontend)' kubectl get pods -l 'environment in (production, qa)' kubectl get pods -l 'environment,environment notin (frontend)'","title":"\u6807\u7b7e\u548c\u9009\u62e9\u5668"},{"location":"k8s/cka_cn/foundamentals/memo/#annotations","text":"\u4f7f\u7528 Kubernetes \u6ce8\u91ca\uff08Annotations\uff09\u5c06\u4efb\u610f\u975e\u6807\u8bc6\u5143\u6570\u636e\u9644\u52a0\u5230\u5bf9\u8c61\u4e0a\u3002 \u5de5\u5177\u548c\u5e93\u7b49\u5ba2\u6237\u7aef\u53ef\u4ee5\u68c0\u7d22\u6b64\u5143\u6570\u636e\u3002 \u4f7f\u7528\u6807\u7b7e\u6216\u6ce8\u91ca\u5c06\u5143\u6570\u636e\u9644\u52a0\u5230 Kubernetes \u5bf9\u8c61\u4e0a\u3002 \u6807\u7b7e\u53ef\u7528\u4e8e\u9009\u62e9\u5bf9\u8c61\u5e76\u67e5\u627e\u6ee1\u8db3\u67d0\u4e9b\u6761\u4ef6\u7684\u5bf9\u8c61\u96c6\u5408\u3002 \u6ce8\u91ca\u4e0d\u7528\u4e8e\u6807\u8bc6\u548c\u9009\u62e9\u5bf9\u8c61\u3002 \u6ce8\u91ca\u4e0e\u6807\u7b7e\u7c7b\u4f3c\uff0c\u90fd\u662f\u952e/\u503c\u6620\u5c04\u3002 \u6620\u5c04\u4e2d\u7684\u952e\u548c\u503c\u5fc5\u987b\u662f\u5b57\u7b26\u4e32\u3002 \u4f8b\u5982\uff1a \"metadata\" : { \"annotations\" : { \"key1\" : \"value1\" , \"key2\" : \"value2\" } } \u5408\u6cd5\u7684\u6ce8\u91ca\u952e\u5177\u6709\u4e24\u4e2a\u90e8\u5206\uff1a\u53ef\u9009\u7684\u524d\u7f00\u548c\u540d\u79f0\uff0c\u7531\u659c\u6760 ( / ) \u5206\u9694\u3002","title":"\u6ce8\u91caAnnotations"},{"location":"k8s/cka_cn/foundamentals/memo/#_6","text":"\u5b57\u6bb5\u9009\u62e9\u5668\uff08field selectors\uff09\u53ef\u4ee5\u6839\u636e\u4e00\u4e2a\u6216\u591a\u4e2a\u8d44\u6e90\u5b57\u6bb5\u7684\u503c\u9009\u62e9Kubernetes\u8d44\u6e90\u3002 \u4e0b\u9762\u662f\u4e00\u4e9b\u4f7f\u7528\u5b57\u6bb5\u9009\u62e9\u5668\u8fdb\u884c\u67e5\u8be2\u7b5b\u9009\u7684\u4f8b\u5b50\uff1a metadata.name=my-service metadata.namespace!=default status.phase=Pending This kubectl command selects all Pods for which the value of the status.phase field is Running: kubectl get pods --field-selector status.phase=Running Supported field selectors vary by Kubernetes resource type. All resource types support the metadata.name and metadata.namespace fields. Use the = , == , and != operators with field selectors ( = and == mean the same thing). \u4e0b\u9762 kubectl \u547d\u4ee4\u9009\u62e9\u6240\u6709\u72b6\u6001(phase)\u5b57\u6bb5\u503c\u4e3a Running \u7684 Pod\uff1a kubectl get pods --field-selector status.phase = Running \u652f\u6301\u7684\u5b57\u6bb5\u9009\u62e9\u5668\u56e0 Kubernetes \u8d44\u6e90\u7c7b\u578b\u800c\u5f02\u3002\u6240\u6709\u8d44\u6e90\u7c7b\u578b\u90fd\u652f\u6301 metadata.name \u548c metadata.namespace \u5b57\u6bb5\u3002 \u5728\u5b57\u6bb5\u9009\u62e9\u5668\u4e2d\u4f7f\u7528 = , == , \u548c != \u8fd0\u7b97\u7b26( = \u548c == \u8868\u793a\u76f8\u540c\u7684\u610f\u601d)\u3002 \u4f8b\u5982\uff1a kubectl get ingress --field-selector foo.bar = baz kubectl get services --all-namespaces --field-selector metadata.namespace! = default kubectl get pods --field-selector = status.phase! = Running,spec.restartPolicy = Always kubectl get statefulsets,services --all-namespaces --field-selector metadata.namespace! = default Finalizers\u662f*\u547d\u540d\u7a7a\u95f4\u952e*\uff0c\u544a\u8bc9Kubernetes\u5728\u6ee1\u8db3\u7279\u5b9a\u6761\u4ef6\u4e4b\u524d\u7b49\u5f85\uff0c\u7136\u540e\u518d\u5b8c\u5168\u5220\u9664\u6807\u8bb0\u4e3a*\u5220\u9664*\u7684\u8d44\u6e90\u3002 Finalizer\u8b66\u544a\u63a7\u5236\u5668controller\u6e05\u7406\u5df2\u5220\u9664\u5bf9\u8c61\u6240\u62e5\u6709\u7684\u8d44\u6e90\u3002 \u901a\u5e38\u56e0\u4e3a\u67d0\u79cd\u76ee\u7684\u4e3a\u8d44\u6e90\u6dfb\u52a0Finalizers\uff0c\u5f3a\u5236\u5220\u9664\u5b83\u4eec\u53ef\u80fd\u4f1a\u5bfc\u81f4\u96c6\u7fa4\u4e2d\u51fa\u73b0\u95ee\u9898\u3002 \u4e0e\u6807\u7b7e\u7c7b\u4f3c\uff0c \u6240\u6709\u8005\u5f15\u7528 \uff08Owner references\uff09\u63cf\u8ff0\u4e86Kubernetes\u4e2d\u5bf9\u8c61\u4e4b\u95f4\u7684\u5173\u7cfb\uff0c\u4f46\u7528\u4e8e\u4e0d\u540c\u7684\u76ee\u7684\u3002 Kubernetes\u4f7f\u7528\u6240\u6709\u8005\u5f15\u7528\uff08\u800c\u4e0d\u662f\u6807\u7b7e\uff09\u6765\u786e\u5b9a\u96c6\u7fa4\u4e2d\u54ea\u4e9bPod\u9700\u8981\u6e05\u7406\u3002 \u5f53Kubernetes\u8bc6\u522b\u5230\u76ee\u6807\u5220\u9664\u7684\u8d44\u6e90\u4e0a\u6709\u6240\u6709\u8005\u5f15\u7528\u65f6\uff0c\u5b83\u4f1a\u5904\u7406Finalizer\u3002","title":"\u5b57\u6bb5\u9009\u62e9\u5668"},{"location":"k8s/cka_cn/foundamentals/memo/#_7","text":"\u5728 Kubernetes \u4e2d\uff0c\u4e00\u4e9b\u5bf9\u8c61\u62e5\u6709\u5176\u4ed6\u5bf9\u8c61\u3002\u4f8b\u5982\uff0cReplicaSet \u662f\u4e00\u7ec4 Pod \u7684\u6240\u6709\u8005\u3002\u8fd9\u4e9b\u88ab\u62e5\u6709\u7684\u5bf9\u8c61\u662f\u5176\u6240\u6709\u8005\u7684\u4ece\u5c5e\u5bf9\u8c61\u3002 \u4ece\u5c5e\u5bf9\u8c61\u5177\u6709\u4e00\u4e2a metadata.ownerReferences \u5b57\u6bb5\uff0c\u8be5\u5b57\u6bb5\u5f15\u7528\u5176\u6240\u6709\u8005\u5bf9\u8c61\u3002 \u6709\u6548\u7684\u6240\u6709\u8005\u5f15\u7528\u5305\u62ec\u5bf9\u8c61\u540d\u79f0\u548c\u4e0e\u4ece\u5c5e\u5bf9\u8c61\u76f8\u540c\u7684\u547d\u540d\u7a7a\u95f4\u4e2d\u7684 UID\u3002 \u4ece\u5c5e\u5bf9\u8c61\u8fd8\u5177\u6709\u4e00\u4e2a ownerReferences.blockOwnerDeletion \u5b57\u6bb5\uff0c\u8be5\u5b57\u6bb5\u5177\u6709\u5e03\u5c14\u503c\uff0c\u63a7\u5236\u7279\u5b9a\u7684\u4ece\u5c5e\u5bf9\u8c61\u662f\u5426\u53ef\u4ee5\u963b\u6b62\u5783\u573e\u56de\u6536\u5220\u9664\u5176\u6240\u6709\u8005\u5bf9\u8c61\u3002","title":"\u6240\u6709\u8005\u548c\u4f9d\u8d56\u5173\u7cfb"},{"location":"k8s/cka_cn/foundamentals/memo/#_8","text":"Kubernetes\u8d44\u6e90\u548c\u201c\u610f\u5411\u8bb0\u5f55\u201d\u90fd\u4ee5API\u5bf9\u8c61\u7684\u5f62\u5f0f\u5b58\u50a8\uff0c\u5e76\u901a\u8fc7\u5bf9API\u7684RESTful\u8c03\u7528\u8fdb\u884c\u4fee\u6539\u3002 API\u5141\u8bb8\u4ee5\u58f0\u660e\u6027\u65b9\u5f0f\u7ba1\u7406\u914d\u7f6e\u3002 \u7528\u6237\u53ef\u4ee5\u76f4\u63a5\u4e0eKubernetes API\u4ea4\u4e92\uff0c\u4e5f\u53ef\u4ee5\u901a\u8fc7\u50cfkubectl\u8fd9\u6837\u7684\u5de5\u5177\u8fdb\u884c\u4ea4\u4e92\u3002 \u6838\u5fc3Kubernetes API\u5177\u6709\u7075\u6d3b\u6027\uff0c\u4e5f\u53ef\u4ee5\u6269\u5c55\u4ee5\u652f\u6301\u81ea\u5b9a\u4e49\u8d44\u6e90\u3002 \u5de5\u4f5c\u8d1f\u8f7d\u8d44\u6e90\uff08Workload Resources\uff09 Pod \u3002Pod \u662f\u53ef\u4ee5\u5728\u4e3b\u673a\u4e0a\u8fd0\u884c\u7684\u5bb9\u5668\u96c6\u5408\u3002 PodTemplate \u3002PodTemplate \u63cf\u8ff0\u4e86\u9884\u5b9a\u4e49 pod \u7684\u526f\u672c\u6a21\u677f\u3002 ReplicationController \u3002ReplicationController \u8868\u793a\u4e00\u4e2a\u590d\u5236\u63a7\u5236\u5668\u7684\u914d\u7f6e\u3002 ReplicaSet \u3002ReplicaSet \u786e\u4fdd\u5728\u4efb\u4f55\u7ed9\u5b9a\u65f6\u95f4\u6709\u6307\u5b9a\u6570\u91cf\u7684 pod \u526f\u672c\u6b63\u5728\u8fd0\u884c\u3002 Deployment \u3002Deployment \u4f7f Pod \u548c ReplicaSet \u7684\u58f0\u660e\u6027\u66f4\u65b0\u6210\u4e3a\u53ef\u80fd\u3002 StatefulSet \u3002StatefulSet \u8868\u793a\u5177\u6709\u4e00\u81f4\u6807\u8bc6\u7684 pod \u96c6\u5408\u3002 ControllerRevision \u3002ControllerRevision \u5b9e\u73b0\u4e86\u72b6\u6001\u6570\u636e\u7684\u4e0d\u53ef\u53d8\u5feb\u7167\u3002 DaemonSet \u3002DaemonSet \u8868\u793a\u4e00\u4e2a\u5b88\u62a4\u8fdb\u7a0b\u96c6\u7684\u914d\u7f6e\u3002 Job \u3002Job \u8868\u793a\u5355\u4e2a job \u7684\u914d\u7f6e\u3002 CronJob \u3002CronJob \u8868\u793a\u5355\u4e2a cron job \u7684\u914d\u7f6e\u3002 HorizontalPodAutoscaler \u3002HorizontalPodAutoscaler \u8868\u793a\u6c34\u5e73 pod \u81ea\u52a8\u7f29\u653e\u5668\u7684\u914d\u7f6e\u3002 HorizontalPodAutoscaler v2beta2 \u3002HorizontalPodAutoscaler \u662f\u6c34\u5e73 pod \u81ea\u52a8\u7f29\u653e\u5668\u7684\u914d\u7f6e\uff0c\u6839\u636e\u6307\u5b9a\u7684\u6307\u6807\u81ea\u52a8\u7ba1\u7406\u5b9e\u73b0\u6bd4\u4f8b\u5b50\u8d44\u6e90\u7684\u4efb\u4f55\u8d44\u6e90\u7684\u526f\u672c\u8ba1\u6570\u3002 PriorityClass \u3002PriorityClass \u5b9a\u4e49\u4e86\u4ece\u4f18\u5148\u7ea7\u7c7b\u540d\u79f0\u5230\u4f18\u5148\u7ea7\u6574\u6570\u503c\u7684\u6620\u5c04\u3002 \u670d\u52a1\u8d44\u6e90\uff08Service Resources\uff09 Service . Service \u662f\u5bf9\u8f6f\u4ef6\u670d\u52a1\uff08\u4f8b\u5982mysql\uff09\u7684\u547d\u540d\u62bd\u8c61\uff0c\u7531\u4ee3\u7406\u76d1\u542c\u7684\u672c\u5730\u7aef\u53e3\uff08\u4f8b\u59823306\uff09\u548c\u786e\u5b9a\u54ea\u4e9bPod\u5c06\u56de\u7b54\u901a\u8fc7\u4ee3\u7406\u53d1\u9001\u7684\u8bf7\u6c42\u7684\u9009\u62e9\u5668\u7ec4\u6210\u3002 Endpoints . Endpoints \u662f\u5b9e\u73b0\u5b9e\u9645\u670d\u52a1\u7684\u4e00\u7ec4\u7ec8\u7ed3\u70b9\u3002 EndpointSlice . EndpointSlice \u8868\u793a\u5b9e\u73b0\u670d\u52a1\u7684\u7ec8\u7ed3\u70b9\u7684\u5b50\u96c6\u3002 Ingress . Ingress \u662f\u4e00\u7ec4\u89c4\u5219\uff0c\u5141\u8bb8\u5165\u7ad9\u8fde\u63a5\u5230\u8fbe\u7531\u540e\u7aef\u5b9a\u4e49\u7684\u7ec8\u7ed3\u70b9\u3002 IngressClass . IngressClass \u8868\u793a Ingress \u7684\u7c7b\uff0c\u7531 Ingress Spec \u5f15\u7528\u3002 \u914d\u7f6e\u548c\u5b58\u50a8\u8d44\u6e90\uff08Config and Storage Resources\uff09 ConfigMap \u3002ConfigMap\u4fdd\u5b58\u5bb9\u5668\u9700\u8981\u4f7f\u7528\u7684\u914d\u7f6e\u6570\u636e\u3002 Secret \u3002Secret\u4fdd\u5b58\u7279\u5b9a\u7c7b\u578b\u7684\u673a\u5bc6\u6570\u636e\u3002 Volume \u3002Volume\u8868\u793aPod\u4e2d\u7684\u547d\u540d\u5377\uff0c\u53ef\u4ee5\u88abPod\u4e2d\u7684\u4efb\u4f55\u5bb9\u5668\u8bbf\u95ee\u3002 PersistentVolumeClaim \u3002PersistentVolumeClaim\u662f\u7528\u6237\u5bf9\u6301\u4e45\u5377\u7684\u8bf7\u6c42\u548c\u58f0\u660e\u3002 PersistentVolume \u3002PersistentVolume\uff08PV\uff09\u662f\u7531\u7ba1\u7406\u5458\u63d0\u4f9b\u7684\u5b58\u50a8\u8d44\u6e90\u3002 StorageClass \u3002StorageClass\u63cf\u8ff0\u53ef\u52a8\u6001\u5206\u914dPersistentVolumes\u7684\u5b58\u50a8\u7c7b\u522b\u7684\u53c2\u6570\u3002 VolumeAttachment \u3002VolumeAttachment\u8bb0\u5f55\u5c06\u6307\u5b9a\u7684\u5377\u9644\u52a0\u5230/\u4ece\u6307\u5b9a\u8282\u70b9\u4e2d\u5206\u79bb\u7684\u610f\u56fe\u3002 CSIDriver \u3002CSIDriver\u8bb0\u5f55\u96c6\u7fa4\u4e0a\u90e8\u7f72\u7684\u5bb9\u5668\u5b58\u50a8\u63a5\u53e3\uff08CSI\uff09\u5377\u9a71\u52a8\u7a0b\u5e8f\u7684\u4fe1\u606f\u3002 CSINode \u3002CSINode\u4fdd\u5b58\u6709\u5173\u8282\u70b9\u4e0a\u5b89\u88c5\u7684\u6240\u6709CSI\u9a71\u52a8\u7a0b\u5e8f\u7684\u4fe1\u606f\u3002 CSIStorageCapacity \u3002CSIStorageCapacity\u5b58\u50a8\u4e00\u4e2aCSI GetCapacity\u8c03\u7528\u7684\u7ed3\u679c\u3002 \u8ba4\u8bc1\u8d44\u6e90\uff08Authentication Resources\uff09 ServiceAccount*\u3002ServiceAccount\u548c\u4e0b\u9762\u7684\u4fe1\u606f\u7ed1\u5b9a\u5728\u4e00\u8d77\uff1a \u4e00\u4e2a\u53ef\u88ab\u7528\u6237\u548c\u5468\u8fb9\u7cfb\u7edf\u7406\u89e3\u7684\u540d\u79f0\uff0c\u7528\u4e8e\u8eab\u4efd\u8bc6\u522b \u53ef\u8fdb\u884c\u8eab\u4efd\u9a8c\u8bc1\u548c\u6388\u6743\u7684\u4e3b\u4f53 \u4e00\u7ec4\u5bc6\u94a5\u3002 TokenRequest*\u3002TokenRequest\u4e3a\u7ed9\u5b9a\u7684ServiceAccount\u8bf7\u6c42\u4e00\u4e2a\u4ee4\u724c\u3002 TokenReview*\u3002TokenReview\u5c1d\u8bd5\u5bf9\u5df2\u77e5\u7528\u6237\u7684\u4ee4\u724c\u8fdb\u884c\u8eab\u4efd\u9a8c\u8bc1\u3002 CertificateSigningRequest*\u3002CertificateSigningRequest\u5bf9\u8c61\u63d0\u4f9b\u4e86\u4e00\u79cd\u901a\u8fc7\u63d0\u4ea4\u8bc1\u4e66\u7b7e\u540d\u8bf7\u6c42\u5e76\u5f02\u6b65\u6279\u51c6\u548c\u53d1\u653e\u6765\u83b7\u53d6x509\u8bc1\u4e66\u7684\u673a\u5236\u3002 \u6388\u6743\u8d44\u6e90\uff08Authorization Resources\uff09 LocalSubjectAccessReview*\u3002LocalSubjectAccessReview\u68c0\u67e5\u4e00\u4e2a\u7528\u6237\u6216\u7ec4\u5728\u7ed9\u5b9a\u547d\u540d\u7a7a\u95f4\u4e2d\u662f\u5426\u80fd\u6267\u884c\u67d0\u4e2a\u64cd\u4f5c\u3002 SelfSubjectAccessReview*\u3002SelfSubjectAccessReview\u68c0\u67e5\u5f53\u524d\u7528\u6237\u662f\u5426\u80fd\u6267\u884c\u67d0\u4e2a\u64cd\u4f5c\u3002 SelfSubjectRulesReview*\u3002SelfSubjectRulesReview\u679a\u4e3e\u5f53\u524d\u7528\u6237\u5728\u4e00\u4e2a\u547d\u540d\u7a7a\u95f4\u5185\u53ef\u4ee5\u6267\u884c\u7684\u64cd\u4f5c\u96c6\u5408\u3002 SubjectAccessReview*\u3002SubjectAccessReview\u68c0\u67e5\u4e00\u4e2a\u7528\u6237\u6216\u7ec4\u662f\u5426\u80fd\u6267\u884c\u67d0\u4e2a\u64cd\u4f5c\u3002 ClusterRole*\u3002ClusterRole\u662f\u4e00\u4e2a\u96c6\u7fa4\u7ea7\u522b\u7684PolicyRules\u903b\u8f91\u5206\u7ec4\uff0c\u53ef\u4ee5\u88abRoleBinding\u6216ClusterRoleBinding\u5f15\u7528\u4e3a\u4e00\u4e2a\u5355\u5143\u3002 ClusterRoleBinding*\u3002ClusterRoleBinding\u5f15\u7528\u4e00\u4e2aClusterRole\uff0c\u4f46\u4e0d\u5305\u542b\u5b83\u3002 Role*\u3002Role\u662f\u4e00\u4e2a\u547d\u540d\u7a7a\u95f4\u7ea7\u522b\u7684PolicyRules\u903b\u8f91\u5206\u7ec4\uff0c\u53ef\u4ee5\u88abRoleBinding\u5f15\u7528\u4e3a\u4e00\u4e2a\u5355\u5143\u3002 RoleBinding*\u3002RoleBinding\u5f15\u7528\u4e00\u4e2aRole\uff0c\u4f46\u4e0d\u5305\u542b\u5b83\u3002 \u7b56\u7565\u8d44\u6e90\uff08Policy Resources\uff09 LimitRange*\u3002LimitRange\u4e3a\u547d\u540d\u7a7a\u95f4\u4e2d\u6bcf\u79cd\u8d44\u6e90\u8bbe\u7f6e\u8d44\u6e90\u4f7f\u7528\u9650\u5236\u3002 ResourceQuota*\u3002ResourceQuota\u8bbe\u7f6e\u6bcf\u4e2a\u547d\u540d\u7a7a\u95f4\u5f3a\u5236\u6267\u884c\u7684\u603b\u914d\u989d\u9650\u5236\u3002 NetworkPolicy*\u3002NetworkPolicy\u63cf\u8ff0\u4e86\u4e00\u7ec4Pod\u5141\u8bb8\u7684\u7f51\u7edc\u6d41\u91cf\u3002 PodDisruptionBudget*\u3002PodDisruptionBudget\u662f\u4e00\u4e2a\u5bf9\u8c61\uff0c\u7528\u4e8e\u5b9a\u4e49\u5bf9\u4e00\u7ec4Pod\u53ef\u80fd\u9020\u6210\u7684\u6700\u5927\u4e2d\u65ad\u3002 PodSecurityPolicy v1beta1*\u3002PodSecurityPolicy\u63a7\u5236\u5bf9\u53ef\u80fd\u5f71\u54cd\u5c06\u5e94\u7528\u4e8ePod\u548c\u5bb9\u5668\u7684\u5b89\u5168\u4e0a\u4e0b\u6587\u7684\u8bf7\u6c42\u7684\u80fd\u529b\u3002 \u6269\u5c55\u8d44\u6e90\uff08Extend Resources\uff09 CustomResourceDefinition*\u3002CustomResourceDefinition\u8868\u793a\u5e94\u5728API\u670d\u52a1\u5668\u4e0a\u516c\u5f00\u7684\u8d44\u6e90\u3002 MutatingWebhookConfiguration*\u3002MutatingWebhookConfiguration\u63cf\u8ff0\u63a5\u53d7\u6216\u62d2\u7edd\u5e76\u53ef\u80fd\u66f4\u6539\u5bf9\u8c61\u7684\u51c6\u5165Webhook\u7684\u914d\u7f6e\u3002 ValidatingWebhookConfiguration*\u3002ValidatingWebhookConfiguration\u63cf\u8ff0\u63a5\u53d7\u6216\u62d2\u7edd\u5bf9\u8c61\u4f46\u4e0d\u66f4\u6539\u5bf9\u8c61\u7684\u51c6\u5165Webhook\u7684\u914d\u7f6e\u3002 \u96c6\u7fa4\u8d44\u6e90\uff08Cluster Resources\uff09 Node*\u3002Node\u662fKubernetes\u4e2d\u7684\u5de5\u4f5c\u8282\u70b9\u3002 Namespace*\u3002Namespace\u4e3a\u540d\u79f0\u63d0\u4f9b\u4e86\u4f5c\u7528\u57df\u3002 Event*\u3002Event\u662f\u5bf9\u96c6\u7fa4\u4e2d\u67d0\u4e2a\u4f4d\u7f6e\u53d1\u751f\u4e8b\u4ef6\u7684\u62a5\u544a\u3002 APIService*\u3002APIService\u8868\u793a\u7279\u5b9aGroupVersion\u7684\u670d\u52a1\u5668\u3002 Lease*\u3002Lease\u5b9a\u4e49\u4e86\u79df\u8d41\u7684\u6982\u5ff5\u3002 RuntimeClass*\u3002RuntimeClass\u5b9a\u4e49\u4e86\u96c6\u7fa4\u4e2d\u652f\u6301\u7684\u5bb9\u5668\u8fd0\u884c\u65f6\u7c7b\u3002 FlowSchema v1beta2*\u3002FlowSchema\u5b9a\u4e49\u4e86\u4e00\u7ec4\u6d41\u7a0b\u7684\u67b6\u6784\u3002 PriorityLevelConfiguration v1beta2*\u3002PriorityLevelConfiguration\u8868\u793a\u4f18\u5148\u7ea7\u7ea7\u522b\u7684\u914d\u7f6e\u3002 Binding*\u3002Binding\u5c06\u4e00\u4e2a\u5bf9\u8c61\u7ed1\u5b9a\u5230\u53e6\u4e00\u4e2a\u5bf9\u8c61\uff1b\u4f8b\u5982\uff0c\u8c03\u5ea6\u7a0b\u5e8f\u5c06Pod\u7ed1\u5b9a\u5230\u8282\u70b9\u4e0a\u3002 ComponentStatus*\u3002ComponentStatus\uff08\u548cComponentStatusList\uff09\u4fdd\u5b58\u96c6\u7fa4\u9a8c\u8bc1\u4fe1\u606f\u3002 \u4f7f\u7528\u547d\u4ee4 kube api-resources \u83b7\u53d6\u652f\u6301\u7684API\u8d44\u6e90\u3002 \u4f7f\u7528\u547d\u4ee4 kubectl explain RESOURCE [options] \u63cf\u8ff0\u4e0e\u6bcf\u4e2a\u652f\u6301\u7684API\u8d44\u6e90\u76f8\u5173\u8054\u7684\u5b57\u6bb5\u3002\u8fd9\u4e9b\u5b57\u6bb5\u53ef\u4ee5\u901a\u8fc7\u7b80\u5355\u7684JSONPath\u6807\u8bc6\u7b26\u8fdb\u884c\u8bc6\u522b\uff1a kubectl explain binding kubectl explain binding.metadata kubectl explain binding.metadata.name","title":"\u8d44\u6e90"},{"location":"k8s/cka_cn/foundamentals/memo/#_9","text":"","title":"\u5de5\u4f5c\u8d1f\u8f7d\u8d44\u6e90"},{"location":"k8s/cka_cn/foundamentals/memo/#pods","text":"Pod\u662fKubernetes\u4e2d\u53ef\u521b\u5efa\u548c\u7ba1\u7406\u7684\u6700\u5c0f\u90e8\u7f72\u8ba1\u7b97\u5355\u4f4d\u3002 Pod\u662f\u4e00\u4e2a\u5305\u542b\u4e00\u4e2a\u6216\u591a\u4e2a\u5bb9\u5668\u3001\u5171\u4eab\u5b58\u50a8\u548c\u7f51\u7edc\u8d44\u6e90\u4ee5\u53ca\u5982\u4f55\u8fd0\u884c\u5bb9\u5668\u7684\u89c4\u8303\u7684\u7ec4\u3002 Pod\u7684\u5185\u5bb9\u59cb\u7ec8\u5171\u540c\u5b9a\u4f4d\u548c\u5171\u540c\u5b89\u6392\uff0c\u5e76\u5728\u5171\u4eab\u73af\u5883\u4e2d\u8fd0\u884c\u3002 Pod\u6a21\u62df\u4e86\u4e00\u4e2a\u7279\u5b9a\u4e8e\u5e94\u7528\u7a0b\u5e8f\u7684\u201c\u903b\u8f91\u4e3b\u673a\u201d\uff1a\u5b83\u5305\u542b\u4e00\u4e2a\u6216\u591a\u4e2a\u76f8\u5bf9\u7d27\u5bc6\u8026\u5408\u7684\u5e94\u7528\u7a0b\u5e8f\u5bb9\u5668\u3002 \u5728\u975e\u4e91\u73af\u5883\u4e2d\uff0c\u540c\u4e00\u7269\u7406\u6216\u865a\u62df\u673a\u4e0a\u6267\u884c\u7684\u5e94\u7528\u7a0b\u5e8f\u7c7b\u4f3c\u4e8e\u5728\u540c\u4e00\u903b\u8f91\u4e3b\u673a\u4e0a\u6267\u884c\u7684\u4e91\u5e94\u7528\u7a0b\u5e8f\u3002 Pod\u7684\u5171\u4eab\u73af\u5883\u662f\u4e00\u7ec4Linux\u547d\u540d\u7a7a\u95f4\u3001cgroups\u548c\u53ef\u80fd\u7684\u5176\u4ed6\u9694\u79bb\u8981\u7d20 - \u8fd9\u4e9b\u8981\u7d20\u4e0e\u9694\u79bbDocker\u5bb9\u5668\u7684\u65b9\u5f0f\u76f8\u540c\u3002 \u5728Docker\u6982\u5ff5\u65b9\u9762\uff0cPod\u7c7b\u4f3c\u4e8e\u5177\u6709\u5171\u4eab\u547d\u540d\u7a7a\u95f4\u548c\u5171\u4eab\u6587\u4ef6\u7cfb\u7edf\u5377\u7684\u4e00\u7ec4Docker\u5bb9\u5668\u3002 \u901a\u5e38\u60c5\u51b5\u4e0b\uff0c\u751a\u81f3\u662f\u5355\u4f8bPod\uff0c\u6211\u4eec\u90fd\u4e0d\u9700\u8981\u76f4\u63a5\u521b\u5efaPod\uff0c\u800c\u662f\u4f7f\u7528\u5de5\u4f5c\u8d1f\u8f7d\u8d44\u6e90\uff0c\u4f8b\u5982*Deployment*\u6216*Job*\u6765\u521b\u5efa\u5b83\u4eec\u3002\u5982\u679cPod\u9700\u8981\u8ddf\u8e2a\u72b6\u6001\uff0c\u5219\u53ef\u4ee5\u4f7f\u7528StatefulSet\u8d44\u6e90\u3002 Kubernetes\u96c6\u7fa4\u4e2d\u7684Pod\u6709\u4e24\u79cd\u4e3b\u8981\u7528\u6cd5\uff1a \u8fd0\u884c\u5355\u4e2a\u5bb9\u5668\u7684Pod\u3002 \u8fd0\u884c\u9700\u8981\u5171\u540c\u5de5\u4f5c\u7684\u591a\u4e2a\u5bb9\u5668\u7684Pod\u3002 \u201c\u6bcf\u4e2aPod\u4e00\u4e2a\u5bb9\u5668\u201d\u7684\u6a21\u578b\u662f\u6700\u5e38\u89c1\u7684Kubernetes\u7528\u4f8b\uff1b\u5728\u8fd9\u79cd\u60c5\u51b5\u4e0b\u53ef\u4ee5\u5c06Pod\u89c6\u4e3a\u5355\u4e2a\u5bb9\u5668\u7684\u5305\u88c5\u5668\uff1bKubernetes\u7ba1\u7406Pod\u800c\u4e0d\u662f\u76f4\u63a5\u7ba1\u7406\u5bb9\u5668\u3002 \u4e00\u4e2aPod\u53ef\u4ee5\u5c01\u88c5\u7531\u591a\u4e2a\u5171\u540c\u5b9a\u4f4d\u3001\u7d27\u5bc6\u8026\u5408\u4e14\u9700\u8981\u5171\u4eab\u8d44\u6e90\u7684\u5bb9\u5668\u7ec4\u6210\u7684\u5e94\u7528\u7a0b\u5e8f\u3002 \u8fd9\u4e9b\u5171\u540c\u5b9a\u4f4d\u7684\u5bb9\u5668\u5f62\u6210\u4e00\u4e2a\u5355\u4e00\u7684\u670d\u52a1\u6574\u4f53\u5355\u5143 - \u4f8b\u5982\uff0c\u4e00\u4e2a\u5bb9\u5668\u5411\u516c\u4f17\u63d0\u4f9b\u5b58\u50a8\u5728\u5171\u4eab\u5377\u4e2d\u7684\u6570\u636e\uff0c\u800c\u53e6\u4e00\u4e2a\u72ec\u7acb\u7684Sidecar\u5bb9\u5668\u5237\u65b0\u6216\u66f4\u65b0\u8fd9\u4e9b\u6587\u4ef6\u3002Pod\u5c06\u8fd9\u4e9b\u5bb9\u5668\u3001\u5b58\u50a8\u8d44\u6e90\u548c\u77ed\u6682\u7684\u7f51\u7edc\u6807\u8bc6\u5305\u88c5\u5728\u4e00\u8d77\uff0c\u4f5c\u4e3a\u4e00\u4e2a\u5355\u72ec\u7684\u5355\u4f4d\u3002 \u5728\u5355\u4e2aPod\u4e2d\u5206\u7ec4\u591a\u4e2a\u5171\u540c\u5b9a\u4f4d\u548c\u5171\u540c\u7ba1\u7406\u7684\u5bb9\u5668\u662f\u76f8\u5bf9\u9ad8\u7ea7\u7684\u7528\u4f8b\u3002\u5e94\u8be5*\u4ec5\u5728*\u5bb9\u5668\u7d27\u5bc6\u8026\u5408\u7684\u7279\u5b9a\u60c5\u51b5\u4e0b\u4f7f\u7528\u6b64\u6a21\u5f0f\u3002 \u6bcf\u4e2aPod\u90fd\u65e8\u5728\u8fd0\u884c\u7ed9\u5b9a\u5e94\u7528\u7a0b\u5e8f\u7684\u5355\u4e2a\u5b9e\u4f8b\u3002\u5982\u679c\u6211\u4eec\u60f3\u6c34\u5e73\u6269\u5c55\u60a8\u7684\u5e94\u7528\u7a0b\u5e8f\uff08\u901a\u8fc7\u8fd0\u884c\u66f4\u591a\u5b9e\u4f8b\u63d0\u4f9b\u66f4\u591a\u7684\u603b\u8d44\u6e90\uff09\uff0c\u5219\u5e94\u8be5\u4f7f\u7528\u591a\u4e2aPod\uff0c\u6bcf\u4e2a\u5b9e\u4f8b\u4e00\u4e2aPod\u3002\u5728Kubernetes\u4e2d\uff0c\u8fd9\u901a\u5e38\u79f0\u4e3a*\u590d\u5236*\u3002\u590d\u5236\u7684Pod\u901a\u5e38\u4f5c\u4e3a\u5de5\u4f5c\u8d1f\u8f7d\u8d44\u6e90\u53ca\u5176\u63a7\u5236\u5668\u7684\u4e00\u7ec4\u521b\u5efa\u548c\u7ba1\u7406\u3002 Pod\u672c\u5730\u63d0\u4f9b\u4e24\u79cd\u5171\u4eab\u8d44\u6e90\u4ee5\u4f9b\u5176\u7ec4\u6210\u5bb9\u5668\u4f7f\u7528\uff1a \u7f51\u7edc *\u548c \u5b58\u50a8 *\u3002 \u4e00\u4e2aPod\u53ef\u4ee5\u6307\u5b9a\u4e00\u7ec4\u5171\u4eab\u7684\u5b58\u50a8\u5377\u3002Pod\u4e2d\u7684\u6240\u6709\u5bb9\u5668\u90fd\u53ef\u4ee5\u8bbf\u95ee\u8fd9\u4e9b\u5171\u4eab\u5377\uff0c\u4f7f\u8fd9\u4e9b\u5bb9\u5668\u53ef\u4ee5\u5171\u4eab\u6570\u636e\u3002 \u6bcf\u4e2aPod\u4e3a\u6bcf\u4e2a\u5730\u5740\u65cf\u5206\u914d\u4e00\u4e2a\u552f\u4e00\u7684IP\u5730\u5740\u3002 \u5728\u4e00\u4e2aPod\u5185\uff0c\u5bb9\u5668\u5171\u4eab\u4e00\u4e2aIP\u5730\u5740\u548c\u7aef\u53e3\u7a7a\u95f4\uff0c\u5e76\u53ef\u4ee5\u901a\u8fc7\u201clocalhost\u201d\u627e\u5230\u5f7c\u6b64\u3002\u60f3\u8981\u4e0e\u8fd0\u884c\u5728\u4e0d\u540cPod\u4e2d\u7684\u5bb9\u5668\u4ea4\u4e92\u7684\u5bb9\u5668\u53ef\u4ee5\u4f7f\u7528IP\u7f51\u7edc\u8fdb\u884c\u901a\u4fe1\u3002 \u5f53\u521b\u5efa\u4e00\u4e2aPod\u65f6\uff0c\u65b0\u7684Pod\u88ab\u8c03\u5ea6\u5728\u96c6\u7fa4\u4e2d\u7684\u4e00\u4e2a\u8282\u70b9\u4e0a\u8fd0\u884c\u3002Pod\u4fdd\u7559\u5728\u8be5\u8282\u70b9\u4e0a\uff0c\u76f4\u5230Pod\u6267\u884c\u5b8c\u6bd5\u3001Pod\u5bf9\u8c61\u88ab\u5220\u9664\u3001Pod\u56e0\u7f3a\u4e4f\u8d44\u6e90\u800c\u88ab\u9a71\u9010\u6216\u8282\u70b9\u53d1\u751f\u6545\u969c\u3002 \u5728Pod\u4e2d\u91cd\u65b0\u542f\u52a8\u4e00\u4e2a\u5bb9\u5668\u4e0d\u5e94\u4e0e\u91cd\u65b0\u542f\u52a8\u4e00\u4e2aPod\u6df7\u6dc6\u3002Pod\u4e0d\u662f\u4e00\u4e2a\u8fdb\u7a0b\uff0c\u800c\u662f\u4e00\u4e2a\u8fd0\u884c\u5bb9\u5668\u7684\u73af\u5883\u3002Pod\u4f1a\u4e00\u76f4\u4fdd\u7559\uff0c\u76f4\u5230\u88ab\u5220\u9664\u4e3a\u6b62\u3002 \u60a8\u53ef\u4ee5\u4f7f\u7528\u5de5\u4f5c\u8d1f\u8f7d\u8d44\u6e90\uff08\u4f8b\u5982Deployment\u3001StatefulSet\u3001DaemonSet\uff09\u4e3a\u81ea\u5df1\u521b\u5efa\u548c\u7ba1\u7406\u591a\u4e2aPod\u3002\u8d44\u6e90\u7684\u63a7\u5236\u5668\u5904\u7406\u590d\u5236\u3001\u6eda\u52a8\u548c\u5728Pod\u5931\u8d25\u65f6\u7684\u81ea\u52a8\u6062\u590d\u3002","title":"Pods"},{"location":"k8s/cka_cn/foundamentals/memo/#_10","text":"\u4e00\u4e9bPod\u8fd8\u6709\u521d\u59cb\u5316\u5bb9\u5668\uff08Init containers\uff09\u548c\u5e94\u7528\u5bb9\u5668\uff08app containers\uff09\u3002\u521d\u59cb\u5316\u5bb9\u5668\u5728\u5e94\u7528\u5bb9\u5668\u542f\u52a8\u4e4b\u524d\u8fd0\u884c\u5e76\u5b8c\u6210\u3002 \u6211\u4eec\u53ef\u4ee5\u5728Pod\u89c4\u8303\u4e2d\u6307\u5b9a\u521d\u59cb\u5316\u5bb9\u5668\uff0c\u540c\u65f6\u4e5f\u53ef\u4ee5\u5728\u5bb9\u5668\u6570\u7ec4\u4e2d\u63cf\u8ff0\u5e94\u7528\u5bb9\u5668\u3002","title":"\u521d\u59cb\u5316\u5bb9\u5668"},{"location":"k8s/cka_cn/foundamentals/memo/#pod","text":"\u9759\u6001Pod\u662f\u76f4\u63a5\u7531\u7279\u5b9a\u8282\u70b9\u4e0a\u7684kubelet\u5b88\u62a4\u7a0b\u5e8f\u7ba1\u7406\u7684\uff0cAPI\u670d\u52a1\u5668\u4e0d\u4f1a\u89c2\u5bdf\u5b83\u4eec\u3002 \u9759\u6001Pod\u59cb\u7ec8\u7ed1\u5b9a\u5230\u7279\u5b9a\u8282\u70b9\u4e0a\u7684\u4e00\u4e2aKubelet\u3002 \u9759\u6001Pod\u7684\u4e3b\u8981\u7528\u9014\u662f\u8fd0\u884c\u81ea\u6258\u7ba1\u63a7\u5236\u9762\u677f\uff1a\u6362\u53e5\u8bdd\u8bf4\uff0c\u4f7f\u7528kubelet\u76d1\u7763\u5404\u4e2a\u63a7\u5236\u9762\u677f\u7ec4\u4ef6\u3002 kubelet\u4f1a\u81ea\u52a8\u5c1d\u8bd5\u4e3a\u6bcf\u4e2a\u9759\u6001Pod\u5728Kubernetes API\u670d\u52a1\u5668\u4e0a\u521b\u5efa\u4e00\u4e2a\u955c\u50cfPod\u3002\u8fd9\u610f\u5473\u7740\u5728\u8282\u70b9\u4e0a\u8fd0\u884c\u7684Pod\u5728API\u670d\u52a1\u5668\u4e0a\u53ef\u89c1\uff0c\u4f46\u65e0\u6cd5\u4ece\u90a3\u91cc\u63a7\u5236\u3002","title":"\u9759\u6001Pod"},{"location":"k8s/cka_cn/foundamentals/memo/#_11","text":"\u63a2\u9488\u662f kubelet \u5b9a\u671f\u5bf9\u5bb9\u5668\u6267\u884c\u7684\u4e00\u79cd\u8bca\u65ad\u3002 \u4e3a\u6267\u884c\u8bca\u65ad\uff0ckubelet \u8981\u4e48\u5728\u5bb9\u5668\u5185\u6267\u884c\u4ee3\u7801\uff0c\u8981\u4e48\u53d1\u8d77\u7f51\u7edc\u8bf7\u6c42\u3002 \u4f7f\u7528\u63a2\u9488\u6709\u56db\u79cd\u4e0d\u540c\u7684\u68c0\u67e5\u5bb9\u5668\u65b9\u5f0f\u3002\u6bcf\u4e2a\u63a2\u9488\u5fc5\u987b\u6070\u597d\u5b9a\u4e49\u8fd9\u56db\u79cd\u673a\u5236\u4e2d\u7684\u4e00\u79cd\uff1a exec \u3002\u5982\u679c\u547d\u4ee4\u4ee5\u72b6\u6001\u4ee3\u7801 0 \u9000\u51fa\uff0c\u5219\u5c06\u8bca\u65ad\u89c6\u4e3a\u6210\u529f\u3002 grpc \u3002\u5982\u679c\u54cd\u5e94\u7684\u72b6\u6001\u4e3a SERVING\uff0c\u5219\u5c06\u8bca\u65ad\u89c6\u4e3a\u6210\u529f\u3002 httpGet \u3002\u5982\u679c\u54cd\u5e94\u7684\u72b6\u6001\u4ee3\u7801\u5927\u4e8e\u6216\u7b49\u4e8e 200 \u4e14\u5c0f\u4e8e 400\uff0c\u5219\u5c06\u8bca\u65ad\u89c6\u4e3a\u6210\u529f\u3002 tcpSocket \u3002\u5982\u679c\u7aef\u53e3\u5f00\u653e\uff0c\u5219\u5c06\u8bca\u65ad\u89c6\u4e3a\u6210\u529f\u3002 \u6bcf\u4e2a\u63a2\u9488\u6709\u4e09\u79cd\u7ed3\u679c\uff1a \u6210\u529f \u5931\u8d25 \u672a\u77e5 \u63a2\u9488\u7c7b\u578b\uff1a livenessProbe \u3002\u6307\u793a\u5bb9\u5668\u662f\u5426\u6b63\u5728\u8fd0\u884c\u3002 readinessProbe \u3002\u6307\u793a\u5bb9\u5668\u662f\u5426\u51c6\u5907\u597d\u54cd\u5e94\u8bf7\u6c42\u3002 startupProbe \u3002\u6307\u793a\u5bb9\u5668\u5185\u7684\u5e94\u7528\u7a0b\u5e8f\u662f\u5426\u542f\u52a8\u3002","title":"\u5bb9\u5668\u63a2\u9488"},{"location":"k8s/cka_cn/foundamentals/memo/#deployment","text":"","title":"Deployment"},{"location":"k8s/cka_cn/foundamentals/memo/#replicaset","text":"ReplicaSet\u7684\u76ee\u7684\u662f\u5728\u4efb\u4f55\u65f6\u5019\u7ef4\u62a4\u4e00\u7ec4\u7a33\u5b9a\u7684\u526f\u672cPod\u3002\u56e0\u6b64\uff0c\u5b83\u901a\u5e38\u7528\u4e8e\u4fdd\u8bc1\u6307\u5b9a\u6570\u91cf\u7684\u76f8\u540cPod\u7684\u53ef\u7528\u6027\u3002 \u6211\u4eec\u4e00\u822c\u4e0d\u9700\u8981\u76f4\u63a5\u64cd\u7eb5ReplicaSet\u5bf9\u8c61\uff1a\u4f7f\u7528Deployment\uff0c\u7136\u540e\u5728spec\u90e8\u5206\u4e2d\u5b9a\u4e49\u60a8\u7684\u5e94\u7528\u7a0b\u5e8f\u3002 \u53ef\u4ee5\u901a\u8fc7\u8bbe\u7f6e replicaset.spec.replicas \u6765\u6307\u5b9a\u5e94\u540c\u65f6\u8fd0\u884c\u591a\u5c11\u4e2aPod\u3002 ReplicaSet\u5c06\u521b\u5efa/\u5220\u9664\u5176Pod\u4ee5\u5339\u914d\u6b64\u6570\u5b57\u3002 \u5982\u679c\u4e0d\u6307\u5b9a replicaset.spec.replicas \uff0c\u5219\u9ed8\u8ba4\u503c\u4e3a 1 \u3002","title":"ReplicaSet"},{"location":"k8s/cka_cn/foundamentals/memo/#statefulset","text":"StatefulSet \u7279\u70b9\uff08\u53c8\u79f0\u56fa\u5b9a\u6807\u8bc6\uff09\uff1a Pod \u7684\u540d\u79f0\u5728\u521b\u5efa\u540e\u4e0d\u53ef\u53d8\u3002 DNS \u4e3b\u673a\u540d\u5728\u521b\u5efa\u540e\u4e0d\u53ef\u53d8\u3002 \u6302\u8f7d\u7684\u5377\u5728\u521b\u5efa\u540e\u4e0d\u53ef\u53d8\u3002 StatefulSet \u7684\u56fa\u5b9a\u6807\u8bc6\u5728\u5931\u8d25\u3001\u6269\u5c55\u548c\u5176\u4ed6\u64cd\u4f5c\u540e\u4e0d\u4f1a\u6539\u53d8\u3002 StatefulSet \u7684\u547d\u540d\u7ea6\u5b9a\u4e3a\uff1a - \u3002 StatefulSet \u53ef\u4ee5\u81ea\u884c\u8fdb\u884c\u6269\u5c55\uff0c\u4f46\u662f Deployment \u9700\u8981\u4f9d\u9760 ReplicaSet \u8fdb\u884c\u6269\u5c55\u3002 \u5efa\u8bae\uff1a\u5148\u5c06 StatefulSet \u51cf\u5c11\u5230 0\uff0c\u800c\u4e0d\u662f\u76f4\u63a5\u5220\u9664\u5b83\u3002 headless Service \u548c governing Service\uff1a Headless Service \u662f\u4e00\u4e2a\u666e\u901a\u7684 Kubernetes Service \u5bf9\u8c61\uff0c\u5176 spec.clusterIP \u88ab\u8bbe\u7f6e\u4e3a None \u3002 \u5f53 StatefulSet \u7684 spec.ServiceName \u8bbe\u7f6e\u4e3a headless Service \u540d\u79f0\u65f6\uff0cStatefulSet \u73b0\u5728\u662f\u4e00\u4e2a governing Service\u3002 \u521b\u5efa StatefulSet \u7684\u4e00\u822c\u8fc7\u7a0b\uff1a \u521b\u5efa StorageClass\u3002 \u521b\u5efa Headless Service\u3002 \u57fa\u4e8e\u4e0a\u8ff0\u4e24\u4e2a\u521b\u5efa StatefulSet\u3002","title":"StatefulSet"},{"location":"k8s/cka_cn/foundamentals/memo/#daemonset","text":"DaemonSet\u4fdd\u8bc1\u6240\u6709\uff08\u6216\u90e8\u5206\uff09\u8282\u70b9\u8fd0\u884cPod\u7684\u526f\u672c\u3002\u968f\u7740\u8282\u70b9\u4ece\u96c6\u7fa4\u4e2d\u5220\u9664\uff0c\u8fd9\u4e9bPod\u5c06\u88ab\u5783\u573e\u56de\u6536\u3002 \u5220\u9664DaemonSet\u5c06\u6e05\u7406\u5b83\u521b\u5efa\u7684Pod\u3002 \u4e00\u4e9b\u5178\u578bDaemonSet\u7684\u7528\u9014\u5305\u62ec\uff1a \u5728\u6bcf\u4e2a\u8282\u70b9\u4e0a\u8fd0\u884c\u96c6\u7fa4\u5b58\u50a8\u5b88\u62a4\u7a0b\u5e8f\u3002 \u5728\u6bcf\u4e2a\u8282\u70b9\u4e0a\u8fd0\u884c\u65e5\u5fd7\u6536\u96c6\u5b88\u62a4\u7a0b\u5e8f\u3002 \u5728\u6bcf\u4e2a\u8282\u70b9\u4e0a\u8fd0\u884c\u8282\u70b9\u76d1\u89c6\u5b88\u62a4\u7a0b\u5e8f\u3002 \u5728\u7b80\u5355\u7684\u60c5\u51b5\u4e0b\uff0c\u6bcf\u79cd\u7c7b\u578b\u7684\u5b88\u62a4\u7a0b\u5e8f\u5c06\u4f7f\u7528\u8986\u76d6\u6240\u6709\u8282\u70b9\u7684\u4e00\u4e2aDaemonSet\u3002 \u66f4\u590d\u6742\u7684\u8bbe\u7f6e\u53ef\u80fd\u4f1a\u4e3a\u5355\u4e2a\u5b88\u62a4\u7a0b\u5e8f\u4f7f\u7528\u591a\u4e2aDaemonSet\uff0c\u4f46\u4f7f\u7528\u4e0d\u540c\u7684\u6807\u5fd7\u548c/\u6216\u4e0d\u540c\u7684\u5185\u5b58\u548cCPU\u8bf7\u6c42\u6765\u652f\u6301\u4e0d\u540c\u7684\u786c\u4ef6\u7c7b\u578b\u3002 DaemonSet\u63a7\u5236\u5668\u8c03\u548c\u8fc7\u7a0b\u540c\u65f6\u68c0\u67e5\u73b0\u6709\u8282\u70b9\u548c\u65b0\u521b\u5efa\u7684\u8282\u70b9\u3002 \u9ed8\u8ba4\u60c5\u51b5\u4e0b\uff0cKubernetes\u8c03\u5ea6\u7a0b\u5e8f\u5ffd\u7565\u7531DamonSet\u521b\u5efa\u7684Pod\uff0c\u5e76\u5141\u8bb8\u5b83\u4eec\u5b58\u5728\u4e8e\u8282\u70b9\u4e0a\uff0c\u76f4\u5230\u5173\u95ed\u8282\u70b9\u672c\u8eab\u3002 \u5728\u9009\u62e9\u8282\u70b9\u4e0a\u8fd0\u884cPod\uff1a \u5982\u679c\u60a8\u6307\u5b9a daemonset.spec.template.spec.nodeSelector \uff0c\u90a3\u4e48DaemonSet\u63a7\u5236\u5668\u5c06\u5728\u4e0e\u8be5\u8282\u70b9\u9009\u62e9\u5668\u5339\u914d\u7684\u8282\u70b9\u4e0a\u521b\u5efaPod\u3002 \u5982\u679c\u60a8\u6307\u5b9a daemonset.spec.template.spec.affinity \uff0c\u90a3\u4e48DaemonSet\u63a7\u5236\u5668\u5c06\u5728\u4e0e\u8be5\u8282\u70b9\u4eb2\u548c\u529b\u5339\u914d\u7684\u8282\u70b9\u4e0a\u521b\u5efaPod\u3002 \u5982\u679c\u4e24\u8005\u90fd\u4e0d\u6307\u5b9a\uff0c\u5219DaemonSet\u63a7\u5236\u5668\u5c06\u5728\u6240\u6709\u8282\u70b9\u4e0a\u521b\u5efaPod\u3002 \u5728 kubectl explain daemonset.spec \u4e2d\u6ca1\u6709 replicas \u5b57\u6bb5\u4e0e kubectl explain deployment.spec.replicas \u76f8\u5bf9\u5e94\u3002\u5f53\u521b\u5efa\u4e00\u4e2aDaemonSet\u65f6\uff0c\u6bcf\u4e2a\u8282\u70b9\u5c06\u8fd0\u884c*\u4e00\u4e2a* DaemonSet Pod\u3002 \u5bf9\u4e8e\u670d\u52a1\uff0c\u901a\u5e38\u662f\u65e0\u72b6\u6001\u7684\uff0c\u4e00\u822c\u4e0d\u5173\u5fc3\u8282\u70b9\u5728\u54ea\u91cc\u8fd0\u884c\uff0c\u66f4\u5173\u5fc3Pod\u526f\u672c\u7684\u6570\u91cf\uff0c\u5e76\u4e14\u6211\u4eec\u53ef\u4ee5\u5c06\u8fd9\u4e9b\u526f\u672c/replicas\u7f29\u653e\u3002\u5728\u8fd9\u91cc\uff0c\u6eda\u52a8\u66f4\u65b0\u4e5f\u5c06\u662f\u4e00\u4e2a\u4f18\u70b9\u3002 \u5f53Pod\u7684\u4e00\u4e2a\u526f\u672c\u5fc5\u987b\u5728\u67d0\u4e2a\u6307\u5b9a\u8282\u70b9\u4e0a\u8fd0\u884c\u65f6\uff0c\u6211\u4eec\u5c06\u4f7f\u7528 DaemonSet \u3002\u6211\u4eec\u7684\u5b88\u62a4\u8fdb\u7a0bPod\u8fd8\u9700\u8981\u5728\u6211\u4eec\u7684\u5176\u4ed6Pod\u4e4b\u524d\u542f\u52a8\u3002 DaemonSet\u662f\u7528\u4e8e\u540e\u53f0\u670d\u52a1\u7684\u7b80\u5355\u53ef\u6269\u5c55\u6027\u7b56\u7565\u3002\u5f53\u66f4\u591a\u7684\u5408\u9002\u7684\u8282\u70b9\u6dfb\u52a0\u5230\u96c6\u7fa4\u65f6\uff0c\u540e\u53f0\u670d\u52a1\u5c06\u6269\u5c55\u3002\u5f53\u8282\u70b9\u88ab\u5220\u9664\u65f6\uff0c\u5b83\u5c06\u81ea\u52a8\u7f29\u5c0f\u3002","title":"DaemonSet"},{"location":"k8s/cka_cn/foundamentals/memo/#job","text":"","title":"Job"},{"location":"k8s/cka_cn/foundamentals/memo/#cronjob","text":"","title":"CronJob"},{"location":"k8s/cka_cn/foundamentals/memo/#_12","text":"","title":"\u670d\u52a1\u8d44\u6e90"},{"location":"k8s/cka_cn/foundamentals/memo/#service","text":"Service\u662f\u8f6f\u4ef6\u670d\u52a1\uff08\u4f8b\u5982mysql\uff09\u7684\u547d\u540d\u62bd\u8c61\uff0c\u7531\u4ee3\u7406\u76d1\u542c\u7684\u672c\u5730\u7aef\u53e3\uff08\u4f8b\u59823306\uff09\u548c\u786e\u5b9a\u54ea\u4e9bPod\u5c06\u56de\u7b54\u901a\u8fc7\u4ee3\u7406\u53d1\u9001\u7684\u8bf7\u6c42\u7684\u9009\u62e9\u5668\u7ec4\u6210\u3002 \u4e00\u4e2aService\u7684\u76ee\u6807Pod\u96c6\u5408\u901a\u5e38\u7531\u4e00\u4e2a\u9009\u62e9\u5668\uff08\u6807\u7b7e\u9009\u62e9\u5668\uff09\u6765\u786e\u5b9a\u3002 Service\u8d44\u6e90\u7684\u7c7b\u578b\u5305\u62ec\uff1a ClusterIP Service\uff08\u9ed8\u8ba4\uff09\uff1a\u53ef\u9760\u7684IP\u3001DNS\u548c\u7aef\u53e3\u3002\u4ec5\u9650\u5185\u90e8\u8bbf\u95ee\u3002 NodePort Service\uff1a\u5411\u5916\u90e8\u63d0\u4f9b\u8bbf\u95ee\u3002 LoadBalancer\uff1a\u57fa\u4e8eNodePort\uff0c\u5e76\u4e0e\u4e91\u4f9b\u5e94\u5546\u63d0\u4f9b\u7684\u8d1f\u8f7d\u5e73\u8861\u96c6\u6210\uff08\u4f8b\u5982AWS\u3001GCP\u7b49\uff09\u3002 ExternalName\uff1a\u8bbf\u95ee\u5c06\u88ab\u8f6c\u53d1\u5230\u5916\u90e8\u670d\u52a1\u3002 \u4e0b\u9762\u662f\u4e00\u4e2a\u521b\u5efa\u7b80\u5355Service\u7684yaml\u6587\u4ef6\uff1a apiVersion : v1 kind : Service metadata : name : nginx-service labels : tier : application spec : ports : - port : 80 protocol : TCP targetPort : 8080 selector : run : nginx type : NodePort \u4e0b\u9762\u662f\u4e00\u4e2aService\u7684\u4f8b\u5b50\uff1a IP 10.96.17.77 \u662f\u8be5\u670d\u52a1\u7684 ClusterIP(VIP)\u3002 \u7aef\u53e3 80/TCP \u662f Pod \u5728\u96c6\u7fa4\u5185\u76d1\u542c\u7684\u7aef\u53e3\u3002 TargetPort 8080/TCP \u662f\u5bb9\u5668\u5185\u670d\u52a1\u5e94\u8be5\u5b9a\u5411\u6d41\u91cf\u5230\u8fbe\u7684\u7aef\u53e3\u3002 NodePort 31893/TCP \u662f\u53ef\u4ee5\u4ece\u5916\u90e8\u8bbf\u95ee\u7684\u7aef\u53e3\u3002\u9ed8\u8ba4\u8303\u56f4\u662f 30000~32767 \u3002\u8be5\u7aef\u53e3\u4f1a\u5728\u6574\u4e2a\u96c6\u7fa4\u7684\u6240\u6709\u8282\u70b9\u4e0a\u66b4\u9732\u3002 Endpoints \u663e\u793a\u4e86\u5339\u914d\u670d\u52a1\u6807\u7b7e\u7684 Pod \u5217\u8868\u3002 Name : nginx-deployment Namespace : jh-namespace Labels : tier=application Annotations : Selector : run=nginx Type : NodePort IP Family Policy : SingleStack IP Families : IPv4 IP : 10.96.17.77 IPs : 10.96.17.77 Port : 80/TCP TargetPort : 8080/TCP NodePort : 31893/TCP Endpoints : 10.244.1.177:8080,10.244.1.178:8080,10.244.1.179:8080 + 7 more... Session Affinity : None External Traffic Policy : Cluster Events : \u5728 Kubernetes \u96c6\u7fa4\u4e2d\uff0c\u57fa\u4e8eDeployment coredns \u7684Service kube-dns \u63d0\u4f9b\u4e86\u96c6\u7fa4 DNS \u670d\u52a1\u3002 \u670d\u52a1\u6ce8\u518c\uff1a Kubernetes \u4f7f\u7528\u96c6\u7fa4 DNS \u4f5c\u4e3a\u670d\u52a1\u6ce8\u518c\u3002 \u6ce8\u518c\u662f\u57fa\u4e8e Service \u800c\u975e Pod \u7684\u3002 \u96c6\u7fa4 DNS\uff08CoreDNS\uff09\u4e3b\u52a8\u76d1\u89c6\u548c\u53d1\u73b0\u65b0\u670d\u52a1\u3002 Service \u540d\u79f0\u3001IP\u3001\u7aef\u53e3\u5c06\u88ab\u6ce8\u518c\u3002 Service \u6ce8\u518c\u7684\u8fc7\u7a0b\u5982\u4e0b\uff1a \u5c06\u65b0\u7684 Service POST \u5230 API Server\u3002 \u4e3a\u65b0\u7684 Service \u5206\u914d ClusterIP\u3002 \u5c06\u65b0\u7684 Service \u914d\u7f6e\u4fe1\u606f\u4fdd\u5b58\u5230 etcd \u4e2d\u3002 \u521b\u5efa\u4e0e\u65b0 Service \u5173\u8054\u7684\u5e26\u6709\u76f8\u5173 Pod IP \u7684 endpoints\u3002 \u901a\u8fc7 ClusterDNS \u63a2\u7d22\u65b0\u7684 Service\u3002 \u521b\u5efa DNS \u4fe1\u606f\u3002 kube-proxy \u83b7\u53d6 Service \u914d\u7f6e\u4fe1\u606f\u3002 \u521b\u5efa IPSV \u89c4\u5219\u3002 Service \u53d1\u73b0\u7684\u8fc7\u7a0b\u3002 \u8bf7\u6c42\u4e00\u4e2a Service \u540d\u79f0\u7684 DNS \u540d\u79f0\u89e3\u6790\u3002 \u6536\u5230 ClusterIP\u3002 \u8bbf\u95ee ClusterIP\u3002 \u6ca1\u6709\u8def\u7531\u5668\u3002\u5c06\u8bf7\u6c42\u8f6c\u53d1\u5230 Pod \u7684\u9ed8\u8ba4\u7f51\u5173\u3002 \u5c06\u8bf7\u6c42\u8f6c\u53d1\u5230\u8282\u70b9\u3002 \u6ca1\u6709\u8def\u7531\u5668\u3002\u5c06\u8bf7\u6c42\u8f6c\u53d1\u5230\u8282\u70b9\u7684\u9ed8\u8ba4\u7f51\u5173\u3002 \u8282\u70b9\u5185\u6838\u7ee7\u7eed\u5904\u7406\u8bf7\u6c42\u3002 \u4f7f\u7528 IPSV \u89c4\u5219\u6355\u83b7\u8bf7\u6c42\u3002 \u5c06\u76ee\u6807 Pod \u7684 IP \u653e\u5165\u8bf7\u6c42\u7684\u76ee\u6807 IP \u4e2d\u3002 \u8bf7\u6c42\u5230\u8fbe\u76ee\u6807 Pod\u3002 FQDN\u683c\u5f0f\u4e3a\uff1a ..svc.cluster.local \u3002\u6211\u4eec\u79f0 \u4e3a\u975e\u9650\u5b9a\u540d\u79f0\u6216\u7b80\u77ed\u540d\u79f0\u3002 \u547d\u540d\u7a7a\u95f4\u53ef\u4ee5\u9694\u79bb\u96c6\u7fa4\u7684\u5730\u5740\u7a7a\u95f4\u3002\u540c\u65f6\uff0c\u5b83\u8fd8\u53ef\u4ee5\u7528\u4e8e\u5b9e\u73b0\u8bbf\u95ee\u63a7\u5236\u548c\u8d44\u6e90\u914d\u989d\u3002 \u83b7\u53d6Pod\u4e2d\u7684DNS\u914d\u7f6e\u3002 nameserver\u7684IP\u4e0ekube-dns\u670d\u52a1\u7684ClusterIP\u76f8\u540c\uff0c\u8fd9\u662f\u7528\u4e8eDNS\u8bf7\u6c42\u6216\u670d\u52a1\u53d1\u73b0\u8bf7\u6c42\u7684\u4f17\u6240\u5468\u77e5\u7684IP\u3002 $ kubectl get service kube-dns -n kube-system NAME TYPE CLUSTER-IP EXTERNAL-IP PORT ( S ) AGE kube-dns ClusterIP 10 .96.0.10 53 /UDP,53/TCP,9153/TCP 7d7h $ kubectl exec -it nginx-5f5496dc9-bv5dx -- /bin/bash root@nginx-5f5496dc9-bv5dx:/# cat /etc/resolv.conf search jh-namespace.svc.cluster.local svc.cluster.local cluster.local nameserver 10 .96.0.10 options ndots:5 \u8bfb\u53d6 kube-dns \u4fe1\u606f\uff1a $ kubectl describe service kube-dns -n kube-system Name: kube-dns Namespace: kube-system Labels: k8s-app = kube-dns kubernetes.io/cluster-service = true kubernetes.io/name = CoreDNS Annotations: prometheus.io/port: 9153 prometheus.io/scrape: true Selector: k8s-app = kube-dns Type: ClusterIP IP Family Policy: SingleStack IP Families: IPv4 IP: 10 .96.0.10 IPs: 10 .96.0.10 Port: dns 53 /UDP TargetPort: 53 /UDP Endpoints: 10 .244.0.2:53,10.244.0.3:53 Port: dns-tcp 53 /TCP TargetPort: 53 /TCP Endpoints: 10 .244.0.2:53,10.244.0.3:53 Port: metrics 9153 /TCP TargetPort: 9153 /TCP Endpoints: 10 .244.0.2:9153,10.244.0.3:9153 Session Affinity: None Events: ","title":"Service"},{"location":"k8s/cka_cn/foundamentals/memo/#endpoints","text":"Endpoints\u662f\u4e00\u7ec4\u5b9e\u73b0\u5b9e\u9645\u670d\u52a1\u7684\u7aef\u70b9\u96c6\u5408\u3002 \u5f53\u521b\u5efa\u670d\u52a1\u65f6\uff0c\u5b83\u4f1a\u4e0e\u4e00\u4e2aEndpoint\u5bf9\u8c61\u76f8\u5173\u8054\uff0c\u53ef\u4ee5\u4f7f\u7528\u547d\u4ee4 kubectl get endpoints \u83b7\u53d6\u3002 \u5339\u914d\u670d\u52a1\u6807\u7b7e\u7684Pod\u5217\u8868\u7ef4\u62a4\u4e3aEndpoint\u5bf9\u8c61\uff0c\u6dfb\u52a0\u65b0\u7684\u5339\u914dPod\u5e76\u5220\u9664\u4e0d\u5339\u914d\u7684Pod\u3002","title":"Endpoints"},{"location":"k8s/cka_cn/foundamentals/memo/#_13","text":"","title":"\u914d\u7f6e\u548c\u5b58\u50a8\u8d44\u6e90"},{"location":"k8s/cka_cn/foundamentals/memo/#_14","text":"","title":"\u5377"},{"location":"k8s/cka_cn/foundamentals/memo/#emptydir","text":"emptyDir \u5377\u662f\u5728Pod\u5206\u914d\u5230\u8282\u70b9\u65f6\u9996\u5148\u521b\u5efa\u7684\uff0c\u5e76\u4e14\u53ea\u8981\u8be5Pod\u5728\u8be5\u8282\u70b9\u4e0a\u8fd0\u884c\uff0c\u5b83\u5c31\u4f1a\u5b58\u5728\u3002 emptyDir \u5377\u6700\u521d\u4e3a\u7a7a\u3002 Pod\u4e2d\u7684\u6240\u6709\u5bb9\u5668\u90fd\u53ef\u4ee5\u8bfb\u53d6\u548c\u5199\u5165 emptyDir \u5377\u4e2d\u7684\u76f8\u540c\u6587\u4ef6\uff0c\u5c3d\u7ba1\u8be5\u5377\u53ef\u4ee5\u5728\u6bcf\u4e2a\u5bb9\u5668\u4e2d\u4ee5\u76f8\u540c\u6216\u4e0d\u540c\u7684\u8def\u5f84\u6302\u8f7d\u3002 \u5f53\u7531\u4e8e\u4efb\u4f55\u539f\u56e0\u4ece\u8282\u70b9\u4e2d\u5220\u9664Pod\u65f6\uff0c emptyDir \u4e2d\u7684\u6570\u636e\u5c06\u6c38\u4e45\u5220\u9664\u3002 \u5bb9\u5668\u5d29\u6e83\u4e0d\u4f1a\u5c06Pod\u4ece\u8282\u70b9\u4e2d\u5220\u9664\u3002 emptyDir \u5377\u4e2d\u7684\u6570\u636e\u53ef\u4ee5\u5728\u5bb9\u5668\u5d29\u6e83\u65f6\u5b89\u5168\u4fdd\u7559\u3002 \u7528\u9014\uff1a \u4e34\u65f6\u7a7a\u95f4\uff0c\u4f8b\u5982\u57fa\u4e8e\u78c1\u76d8\u7684\u5f52\u5e76\u6392\u5e8f \u4e3a\u4e86\u4ece\u5d29\u6e83\u4e2d\u6062\u590d\u800c\u8fdb\u884c\u7684\u957f\u65f6\u95f4\u8ba1\u7b97\u7684\u68c0\u67e5\u70b9 \u4fdd\u5b58\u5185\u5bb9\u7ba1\u7406\u5668\u5bb9\u5668\u63d0\u53d6\u7684\u6587\u4ef6\uff0c\u540c\u65f6Web\u670d\u52a1\u5668\u5bb9\u5668\u63d0\u4f9b\u6570\u636e","title":"emptyDir"},{"location":"k8s/cka_cn/foundamentals/memo/#hostpath","text":"hostPath \u5377\u5c06\u4e3b\u673a\u8282\u70b9\u6587\u4ef6\u7cfb\u7edf\u4e2d\u7684\u6587\u4ef6\u6216\u76ee\u5f55\u6302\u8f7d\u5230 Pod \u4e2d\u3002\u8fd9\u4e0d\u662f\u5927\u591a\u6570 Pod \u90fd\u9700\u8981\u7684\uff0c\u4f46\u5bf9\u4e8e\u67d0\u4e9b\u5e94\u7528\u7a0b\u5e8f\u6765\u8bf4\uff0c\u5b83\u63d0\u4f9b\u4e86\u4e00\u4e2a\u5f3a\u5927\u7684\u9003\u751f\u53e3\u3002 hostPath \u5377\u5b58\u5728\u8bb8\u591a\u5b89\u5168\u98ce\u9669\uff0c\u56e0\u6b64\u5728\u53ef\u80fd\u7684\u60c5\u51b5\u4e0b\u6700\u597d\u907f\u514d\u4f7f\u7528 HostPath\u3002\u5f53\u5fc5\u987b\u4f7f\u7528 HostPath \u5377\u65f6\uff0c\u5e94\u5c06\u5176\u8303\u56f4\u9650\u5b9a\u4e3a\u4ec5\u6240\u9700\u7684\u6587\u4ef6\u6216\u76ee\u5f55\uff0c\u5e76\u4ee5\u53ea\u8bfb\u65b9\u5f0f\u6302\u8f7d\u3002 \u5982\u679c\u901a\u8fc7 AdmissionPolicy \u9650\u5236 HostPath \u8bbf\u95ee\u7279\u5b9a\u76ee\u5f55\uff0c\u5219\u5fc5\u987b\u8981\u6c42 volumeMounts \u4f7f\u7528 readOnly \u6302\u8f7d\uff0c\u4ee5\u4f7f\u7b56\u7565\u751f\u6548\u3002 \u7528\u9014\uff1a \u4e0e DaemonSet \u4e00\u8d77\u8fd0\u884c\uff0c\u4f8b\u5982\uff0cEFK Fluentd \u6302\u8f7d\u672c\u5730\u4e3b\u673a\u7684\u65e5\u5fd7\u76ee\u5f55\u4ee5\u6536\u96c6\u4e3b\u673a\u65e5\u5fd7\u4fe1\u606f\u3002 \u901a\u8fc7\u4f7f\u7528 hostPath \u5377\u5728\u7279\u5b9a\u8282\u70b9\u4e0a\u8fd0\u884c\uff0c\u53ef\u4ee5\u83b7\u5f97\u9ad8\u6027\u80fd\u7684\u78c1\u76d8 I/O\u3002 \u8fd0\u884c\u9700\u8981\u8bbf\u95ee Docker \u5185\u90e8\u7684\u5bb9\u5668\uff1b\u4f7f\u7528 /var/lib/docker \u7684 hostPath\u3002 \u5728\u5bb9\u5668\u4e2d\u8fd0\u884c cAdvisor\uff1b\u4f7f\u7528 /sys \u7684 hostPath\u3002 \u5141\u8bb8 Pod \u6307\u5b9a\u7ed9\u5b9a\u7684 hostPath \u662f\u5426\u5e94\u8be5\u5728 Pod \u8fd0\u884c\u4e4b\u524d\u5b58\u5728\uff0c\u662f\u5426\u5e94\u8be5\u521b\u5efa\u5b83\u4ee5\u53ca\u5b83\u5e94\u8be5\u5b58\u5728\u7684\u5185\u5bb9\u3002","title":"hostPath"},{"location":"k8s/cka_cn/foundamentals/memo/#storage-class","text":"StorageClass \u90e8\u7f72\u548c\u5b9e\u73b0\u7684\u6b65\u9aa4\u5982\u4e0b\uff1a \u521b\u5efa Kubernetes \u96c6\u7fa4\u548c\u540e\u7aef\u5b58\u50a8\u3002 \u786e\u4fdd Kubernetes \u4e2d\u7684 provisioner/plugin \u53ef\u7528\u3002 \u521b\u5efa\u4e00\u4e2a StorageClass \u5bf9\u8c61\u5e76\u5c06\u5176\u94fe\u63a5\u5230\u540e\u7aef\u5b58\u50a8\u3002StorageClass \u5c06\u81ea\u52a8\u521b\u5efa\u76f8\u5173\u7684 PV\u3002 \u521b\u5efa\u4e00\u4e2a PVC \u5bf9\u8c61\u5e76\u5c06\u5176\u94fe\u63a5\u5230\u6211\u4eec\u521b\u5efa\u7684 StorageClass\u3002 \u90e8\u7f72\u4e00\u4e2a Pod \u5e76\u4f7f\u7528 PVC \u5377\u3002","title":"Storage Class"},{"location":"k8s/cka_cn/foundamentals/memo/#pv","text":"PV\u56de\u6536\u7b56\u7565\uff1a \u4fdd\u7559 (Retain) \u5220\u9664 (Delete) \u56de\u6536 (Recycle) PV in-tree\u7c7b\u578b\uff1a hostPath local NFS CSI","title":"PV"},{"location":"k8s/cka_cn/foundamentals/memo/#access-modes","text":"Access Modes\uff08\u8bbf\u95ee\u6a21\u5f0f\uff09\u4e2d\uff0c spec.accessModes \u5b9a\u4e49\u4e86 PV \u7684\u6302\u8f7d\u9009\u9879\uff1a ReadWriteOnce(RWO)\uff1a\u4e00\u4e2a PV \u53ea\u80fd\u88ab\u4e00\u4e2a\u8bfb\u5199\u6a21\u5f0f\u7684 PVC \u6302\u8f7d\uff0c\u7c7b\u4f3c\u4e8e\u5757\u8bbe\u5907\u3002 ReadWriteMany(RWM)\uff1a\u4e00\u4e2a PV \u53ef\u4ee5\u88ab\u591a\u4e2a\u8bfb\u5199\u6a21\u5f0f\u7684 PVC \u6302\u8f7d\uff0c\u4f8b\u5982 NFS\u3002 ReadOnlyMany(ROM)\uff1a\u4e00\u4e2a PV \u53ef\u4ee5\u88ab\u591a\u4e2a\u53ea\u8bfb\u6a21\u5f0f\u7684 PVC \u6302\u8f7d\u3002 ReadWriteOncePod(RWOP)\uff1a\u53ea\u652f\u6301 CSI \u7c7b\u578b\u7684 PV\uff0c\u53ea\u80fd\u88ab\u5355\u4e2a Pod \u6302\u8f7d\u3002 \u4e00\u4e2a PV \u53ea\u80fd\u8bbe\u7f6e\u4e00\u79cd\u9009\u9879\u3002Pod \u6302\u8f7d PVC\uff0c\u800c\u4e0d\u662f PV\u3002","title":"Access Modes"},{"location":"k8s/cka_cn/foundamentals/namespace/","text":"CKA\u81ea\u5b66\u7b14\u8bb011:Namespace \u00b6 \u6f14\u793a\u573a\u666f \u00b6 \u83b7\u53d6namespace\u5217\u8868 \u521b\u5efa\u65b0\u7684namespace \u7ed9namespace\u8bbe\u5b9a\u6807\u7b7e \u5220\u9664\u4e00\u4e2anamespace \u6f14\u793a \u00b6 \u83b7\u53d6\u5f53\u524dnamespace\u5217\u8868\u3002 kubectl get namespace \u83b7\u53d6\u5f53\u524dnamespace\u5217\u8868\u548c\u5bf9\u5e94\u6807\u7b7e\u4fe1\u606f\u3002 kubectl get ns --show-labels \u521b\u5efa\u4e00\u4e2anamespace cka \u3002 kubectl create namespace cka \u7ed9\u65b0\u521b\u5efa\u7684namespace cka \u8bbe\u5b9a\u6807\u7b7e\u3002 kubectl label ns cka cka = true \u5728namespace cka \u4e0a\u521b\u5efa Nginx Deployment\u3002 kubectl create deploy nginx --image = nginx --namespace cka \u5728namespace cka \u4e0a\u68c0\u67e5\u6b63\u5728\u8fd0\u884c\u7684deployment\u548cpod\u3002 kubectl get deploy,pod -n cka \u8fd0\u884c\u7ed3\u679c\uff1a NAME READY UP-TO-DATE AVAILABLE AGE deployment.apps/nginx 1/1 1 1 2m14s NAME READY STATUS RESTARTS AGE pod/nginx-85b98978db-bmkhf 1/1 Running 0 2m14s \u5220\u9664namespace cka \uff0c\u5219\u6240\u6709\u8fd0\u884c\u5728\u8fd9\u4e2anamespace\u4e0a\u7684\u8d44\u6e90\u90fd\u4f1a\u88ab\u5220\u9664\u3002 kubectl delete ns cka \u5982\u679c\u5728\u5220\u9664\u67d0\u4e2anamespace\u65f6\u9047\u5230\u72b6\u6001\u4e00\u76f4\u662f Terminating \uff0c\u5219\u53ef\u4ee5\u5c1d\u8bd5\u7528\u4e0b\u9762\u7684\u65b9\u6cd5\u89e3\u51b3\u3002 kubectl get namespace $NAMESPACE -o json | sed -e 's/\"kubernetes\"//' | kubectl replace --raw \"/api/v1/namespaces $NAMESPACE /finalize\" -f -","title":"Namespace"},{"location":"k8s/cka_cn/foundamentals/namespace/#cka11namespace","text":"","title":"CKA\u81ea\u5b66\u7b14\u8bb011:Namespace"},{"location":"k8s/cka_cn/foundamentals/namespace/#_1","text":"\u83b7\u53d6namespace\u5217\u8868 \u521b\u5efa\u65b0\u7684namespace \u7ed9namespace\u8bbe\u5b9a\u6807\u7b7e \u5220\u9664\u4e00\u4e2anamespace","title":"\u6f14\u793a\u573a\u666f"},{"location":"k8s/cka_cn/foundamentals/namespace/#_2","text":"\u83b7\u53d6\u5f53\u524dnamespace\u5217\u8868\u3002 kubectl get namespace \u83b7\u53d6\u5f53\u524dnamespace\u5217\u8868\u548c\u5bf9\u5e94\u6807\u7b7e\u4fe1\u606f\u3002 kubectl get ns --show-labels \u521b\u5efa\u4e00\u4e2anamespace cka \u3002 kubectl create namespace cka \u7ed9\u65b0\u521b\u5efa\u7684namespace cka \u8bbe\u5b9a\u6807\u7b7e\u3002 kubectl label ns cka cka = true \u5728namespace cka \u4e0a\u521b\u5efa Nginx Deployment\u3002 kubectl create deploy nginx --image = nginx --namespace cka \u5728namespace cka \u4e0a\u68c0\u67e5\u6b63\u5728\u8fd0\u884c\u7684deployment\u548cpod\u3002 kubectl get deploy,pod -n cka \u8fd0\u884c\u7ed3\u679c\uff1a NAME READY UP-TO-DATE AVAILABLE AGE deployment.apps/nginx 1/1 1 1 2m14s NAME READY STATUS RESTARTS AGE pod/nginx-85b98978db-bmkhf 1/1 Running 0 2m14s \u5220\u9664namespace cka \uff0c\u5219\u6240\u6709\u8fd0\u884c\u5728\u8fd9\u4e2anamespace\u4e0a\u7684\u8d44\u6e90\u90fd\u4f1a\u88ab\u5220\u9664\u3002 kubectl delete ns cka \u5982\u679c\u5728\u5220\u9664\u67d0\u4e2anamespace\u65f6\u9047\u5230\u72b6\u6001\u4e00\u76f4\u662f Terminating \uff0c\u5219\u53ef\u4ee5\u5c1d\u8bd5\u7528\u4e0b\u9762\u7684\u65b9\u6cd5\u89e3\u51b3\u3002 kubectl get namespace $NAMESPACE -o json | sed -e 's/\"kubernetes\"//' | kubectl replace --raw \"/api/v1/namespaces $NAMESPACE /finalize\" -f -","title":"\u6f14\u793a"},{"location":"k8s/cka_cn/foundamentals/networkpolicy/","text":"CKA\u81ea\u5b66\u7b14\u8bb023:Network Policy \u00b6 \u7528Calico\u66ff\u6362Flannel \u00b6 \u6f14\u793a\u573a\u666f\uff1a \u5378\u8f7dFlannel \u5b89\u88c5Calico \u6f14\u793a\uff1a \u5982\u679c\u5728\u5b89\u88c5\u8fc7\u7a0b\u4e2d\u5df2\u7ecf\u5b89\u88c5\u4e86 Calico\uff0c\u5219\u53ef\u4ee5\u5ffd\u7565\u8fd9\u90e8\u5206\u5185\u5bb9\u3002 \u5378\u8f7dFlannel kubectl delete -f https://raw.githubusercontent.com/coreos/flannel/v0.18.1/Documentation/kube-flannel.yml \u6216\u8005 kubectl delete -f kube-flannel.yml \u8f93\u51fa\uff1a Warning: policy/v1beta1 PodSecurityPolicy is deprecated in v1.21+, unavailable in v1.25+ podsecuritypolicy.policy \"psp.flannel.unprivileged\" deleted clusterrole.rbac.authorization.k8s.io \"flannel\" deleted clusterrolebinding.rbac.authorization.k8s.io \"flannel\" deleted serviceaccount \"flannel\" deleted configmap \"kube-flannel-cfg\" deleted daemonset.apps \"kube-flannel-ds\" deleted \u5728\u6240\u6709\u8282\u70b9\u4e0a\u6e05\u9664iptables\u8bbe\u7f6e\u3002 rm -rf /var/run/flannel /opt/cni /etc/cni /var/lib/cni iptables -F && iptables -t nat -F && iptables -t mangle -F && iptables -X \u91cd\u65b0\u767b\u5f55\u4e3b\u673a\u8282\u70b9\uff0c\u4f8b\u5982 cka001 \uff0c\u5b89\u88c5Calico\uff0c curl https://docs.projectcalico.org/manifests/calico.yaml -O kubectl apply -f calico.yaml Output: configmap/calico-config created customresourcedefinition.apiextensions.k8s.io/bgpconfigurations.crd.projectcalico.org created customresourcedefinition.apiextensions.k8s.io/bgppeers.crd.projectcalico.org created customresourcedefinition.apiextensions.k8s.io/blockaffinities.crd.projectcalico.org created customresourcedefinition.apiextensions.k8s.io/caliconodestatuses.crd.projectcalico.org created customresourcedefinition.apiextensions.k8s.io/clusterinformations.crd.projectcalico.org created customresourcedefinition.apiextensions.k8s.io/felixconfigurations.crd.projectcalico.org created customresourcedefinition.apiextensions.k8s.io/globalnetworkpolicies.crd.projectcalico.org created customresourcedefinition.apiextensions.k8s.io/globalnetworksets.crd.projectcalico.org created customresourcedefinition.apiextensions.k8s.io/hostendpoints.crd.projectcalico.org created customresourcedefinition.apiextensions.k8s.io/ipamblocks.crd.projectcalico.org created customresourcedefinition.apiextensions.k8s.io/ipamconfigs.crd.projectcalico.org created customresourcedefinition.apiextensions.k8s.io/ipamhandles.crd.projectcalico.org created customresourcedefinition.apiextensions.k8s.io/ippools.crd.projectcalico.org created customresourcedefinition.apiextensions.k8s.io/ipreservations.crd.projectcalico.org created customresourcedefinition.apiextensions.k8s.io/kubecontrollersconfigurations.crd.projectcalico.org created customresourcedefinition.apiextensions.k8s.io/networkpolicies.crd.projectcalico.org created customresourcedefinition.apiextensions.k8s.io/networksets.crd.projectcalico.org created clusterrole.rbac.authorization.k8s.io/calico-kube-controllers created clusterrolebinding.rbac.authorization.k8s.io/calico-kube-controllers created clusterrole.rbac.authorization.k8s.io/calico-node created clusterrolebinding.rbac.authorization.k8s.io/calico-node created daemonset.apps/calico-node created serviceaccount/calico-node created deployment.apps/calico-kube-controllers created serviceaccount/calico-kube-controllers created poddisruptionbudget.policy/calico-kube-controllers created \u9a8c\u8bc1Calico\u5b89\u88c5\u72b6\u6001\uff0c\u786e\u4fdd\u5728\u6bcf\u4e2a\u8282\u70b9\u4e0a\u90fd\u6b63\u5e38\u8fd0\u884c\u3002 kubectl get pod -n kube-system | grep calico \u8f93\u51fa\u7ed3\u679c\uff1a NAME READY STATUS RESTARTS AGE calico-kube-controllers-7bc6547ffb-tjfcg 1/1 Running 0 30m calico-node-7x8jm 1/1 Running 0 30m calico-node-cwxj5 1/1 Running 0 30m calico-node-rq978 1/1 Running 0 30m \u5982\u679c\u9047\u5230\u4efb\u4f55\u9519\u8bef\uff0c\u9996\u5148\u68c0\u67e5\u5bb9\u5668container\u65e5\u5fd7\u3002 # Get Container ID crictl ps # Get log info crictl logs \u7531\u4e8e\u6211\u4eec\u5c06 CNI \u4ece Flannel \u66f4\u6539\u4e3a Calico\uff0c\u6211\u4eec\u9700\u8981\u5220\u9664\u6240\u6709 Pod\uff0c\u6240\u6709 Pod \u90fd\u5c06\u81ea\u52a8\u91cd\u65b0\u521b\u5efa\u3002 kubectl delete pod -A --all \u67e5\u8be2\u6240\u6709pod\u90fd\u72b6\u6001\uff0c\u786e\u4fdd\u4ed6\u4eec\u90fd\u6b63\u5e38\u8fd0\u884c\u3002 kubectl get pod -A \u5165\u7ad9\u89c4\u5219\uff08Inbound Rules\uff09 \u00b6 \u6f14\u793a\u573a\u666f\uff1a \u521b\u5efa\u7528\u4e8e\u6d4b\u8bd5\u7684\u5de5\u4f5c\u8d1f\u8f7d\u3002 \u7981\u6b62\u6240\u6709\u5165\u7ad9\u6d41\u91cf\u3002 \u5141\u8bb8\u7279\u5b9a\u7684\u5165\u7ad9\u6d41\u91cf\u3002 \u9a8c\u8bc1NetworkPolicy\u3002 \u521b\u5efa\u6d4b\u8bd5\u5de5\u4f5c\u8d1f\u8f7d \u00b6 \u521b\u5efa\u4e09\u4e2a Deployment\uff0c\u540d\u79f0\u4e3a pod-netpol-1 \u3001 pod-netpol-2 \u548c pod-netpol-3 \uff0c\u5b83\u4eec\u90fd\u57fa\u4e8e\u955c\u50cf busybox \u3002 kubectl apply -f - << EOF apiVersion: apps/v1 kind: Deployment metadata: labels: app: pod-netpol-1 name: pod-netpol-1 spec: replicas: 1 selector: matchLabels: app: pod-netpol-1 template: metadata: labels: app: pod-netpol-1 spec: containers: - image: busybox name: busybox command: [\"sh\", \"-c\", \"sleep 1h\"] --- apiVersion: apps/v1 kind: Deployment metadata: labels: app: pod-netpol-2 name: pod-netpol-2 spec: replicas: 1 selector: matchLabels: app: pod-netpol-2 template: metadata: labels: app: pod-netpol-2 spec: containers: - image: busybox name: busybox command: [\"sh\", \"-c\", \"sleep 1h\"] --- apiVersion: apps/v1 kind: Deployment metadata: labels: app: pod-netpol-3 name: pod-netpol-3 spec: replicas: 1 selector: matchLabels: app: pod-netpol-3 template: metadata: labels: app: pod-netpol-3 spec: containers: - image: busybox name: busybox command: [\"sh\", \"-c\", \"sleep 1h\"] EOF \u68c0\u67e5pod\u7684IP\u5730\u5740\uff1a kubectl get pod -owide \u8f93\u51fa\u7ed3\u679c\uff1a NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES pod-netpol-1-6494f6bf8b-n58r9 1/1 Running 0 29s 10.244.102.30 cka003 pod-netpol-2-77478d77ff-l6rzm 1/1 Running 0 29s 10.244.112.30 cka002 pod-netpol-3-68977dcb48-ql5s6 1/1 Running 0 29s 10.244.102.31 cka003 \u767b\u5f55\u8fdb\u5165pod pod-netpol-1 \u3002 kubectl exec -it pod-netpol-1-6494f6bf8b-n58r9 -- sh \u6267\u884c\u547d\u4ee4 ping \uff0c\u786e\u4fdd pod-netpol-2 \u548c pod-netpol-3 \u53ef\u4e92\u76f8\u8bbf\u95ee\u3002 / # ping 10.244.112.30 3 packets transmitted, 3 packets received, 0 % packet loss / # ping 10.244.102.31 3 packets transmitted, 3 packets received, 0 % packet loss \u7981\u6b62\u6240\u6709\u5165\u7ad9\u6d41\u91cf \u00b6 \u521b\u5efa\u7b56\u7565\uff0c\u7981\u6b62\u6240\u6709\u5165\u7ad9\u6d41\u91cf\u3002 kubectl apply -f - << EOF apiVersion: networking.k8s.io/v1 kind: NetworkPolicy metadata: name: default-deny-ingress spec: podSelector: {} policyTypes: - Ingress EOF \u518d\u6b21\u767b\u5f55\u8fdb\u5165pod pod-netpol-1 \u3002 kubectl exec -it pod-netpol-1-6494f6bf8b-n58r9 -- sh Execute command ping that pod-netpol-2 and pod-netpol-3 are both unreachable as expected. \u6267\u884c\u547d\u4ee4 ping \uff0c\u548c\u6211\u4eec\u9884\u671f\u4e00\u6837\uff0c pod-netpol-2 \u548c pod-netpol-3 \u6b64\u65f6\u4e92\u76f8\u65e0\u6cd5\u8bbf\u95ee\u3002 / # ping 10.244.112.30 3 packets transmitted, 0 packets received, 100 % packet loss / # ping 10.244.102.31 3 packets transmitted, 0 packets received, 100 % packet loss \u5141\u8bb8\u7279\u5b9a\u7684\u5165\u7ad9\u6d41\u91cf \u00b6 \u521b\u5efa NetworkPolicy\uff0c\u5141\u8bb8\u6765\u81ea pod-netpol-1 \u5230 pod-netpol-2 \u7684\u5165\u7ad9\u6d41\u91cf\u3002 kubectl apply -f - <:80 \u5931\u8d25 \u8fd0\u884c curl :80 \u6210\u529f kubectl run centos --image = centos -n my-ns-1 -- \"/bin/sh\" \"-c\" \"sleep 3600\" kubectl exec -it mycentos -n my-ns-1 -- bash \u5728namespace my-ns-2 \u4e2d\u521b\u5efa\u4e00\u4e2a\u4e34\u65f6 Pod\uff0c\u7136\u540e\u8fde\u63a5\u5230\u8be5 Pod \u5e76\u9a8c\u8bc1\u8bbf\u95ee\u3002 \u547d\u4ee4 curl :80 \u5931\u8d25 \u547d\u4ee4 curl :80 \u5931\u8d25\u3002 kubectl run centos --image = centos -n my-ns-2 -- \"/bin/sh\" \"-c\" \"sleep 3600\" kubectl exec -it mycentos -n my-ns-2 -- bash \u4fee\u6539 my-networkpolicy-1 \uff0c \u628a ingress.from.namespaceSelector.matchLabels \u7684\u503c\u6539\u4e3a my-ns-2 \u3002 \u767b\u5f55\u8fdb\u5165namespace my-ns-2 \u4e0a\u7684\u4e34\u65f6pod\uff0c\u9a8c\u8bc1\u8bbf\u95ee\u3002 \u547d\u4ee4 curl :80 \u5931\u8d25 \u547d\u4ee4 curl :80 \u6210\u529f kubectl exec -it mycentos -n my-ns-2 -- bash \u5220\u9664\u6f14\u793a\u4e2d\u521b\u5efa\u7684\u4e34\u65f6\u8d44\u6e90\u3002 kubectl delete namespace my-ns-1 kubectl delete namespace my-ns-2","title":"Network Policy"},{"location":"k8s/cka_cn/foundamentals/networkpolicy/#cka23network-policy","text":"","title":"CKA\u81ea\u5b66\u7b14\u8bb023:Network Policy"},{"location":"k8s/cka_cn/foundamentals/networkpolicy/#calicoflannel","text":"\u6f14\u793a\u573a\u666f\uff1a \u5378\u8f7dFlannel \u5b89\u88c5Calico \u6f14\u793a\uff1a \u5982\u679c\u5728\u5b89\u88c5\u8fc7\u7a0b\u4e2d\u5df2\u7ecf\u5b89\u88c5\u4e86 Calico\uff0c\u5219\u53ef\u4ee5\u5ffd\u7565\u8fd9\u90e8\u5206\u5185\u5bb9\u3002 \u5378\u8f7dFlannel kubectl delete -f https://raw.githubusercontent.com/coreos/flannel/v0.18.1/Documentation/kube-flannel.yml \u6216\u8005 kubectl delete -f kube-flannel.yml \u8f93\u51fa\uff1a Warning: policy/v1beta1 PodSecurityPolicy is deprecated in v1.21+, unavailable in v1.25+ podsecuritypolicy.policy \"psp.flannel.unprivileged\" deleted clusterrole.rbac.authorization.k8s.io \"flannel\" deleted clusterrolebinding.rbac.authorization.k8s.io \"flannel\" deleted serviceaccount \"flannel\" deleted configmap \"kube-flannel-cfg\" deleted daemonset.apps \"kube-flannel-ds\" deleted \u5728\u6240\u6709\u8282\u70b9\u4e0a\u6e05\u9664iptables\u8bbe\u7f6e\u3002 rm -rf /var/run/flannel /opt/cni /etc/cni /var/lib/cni iptables -F && iptables -t nat -F && iptables -t mangle -F && iptables -X \u91cd\u65b0\u767b\u5f55\u4e3b\u673a\u8282\u70b9\uff0c\u4f8b\u5982 cka001 \uff0c\u5b89\u88c5Calico\uff0c curl https://docs.projectcalico.org/manifests/calico.yaml -O kubectl apply -f calico.yaml Output: configmap/calico-config created customresourcedefinition.apiextensions.k8s.io/bgpconfigurations.crd.projectcalico.org created customresourcedefinition.apiextensions.k8s.io/bgppeers.crd.projectcalico.org created customresourcedefinition.apiextensions.k8s.io/blockaffinities.crd.projectcalico.org created customresourcedefinition.apiextensions.k8s.io/caliconodestatuses.crd.projectcalico.org created customresourcedefinition.apiextensions.k8s.io/clusterinformations.crd.projectcalico.org created customresourcedefinition.apiextensions.k8s.io/felixconfigurations.crd.projectcalico.org created customresourcedefinition.apiextensions.k8s.io/globalnetworkpolicies.crd.projectcalico.org created customresourcedefinition.apiextensions.k8s.io/globalnetworksets.crd.projectcalico.org created customresourcedefinition.apiextensions.k8s.io/hostendpoints.crd.projectcalico.org created customresourcedefinition.apiextensions.k8s.io/ipamblocks.crd.projectcalico.org created customresourcedefinition.apiextensions.k8s.io/ipamconfigs.crd.projectcalico.org created customresourcedefinition.apiextensions.k8s.io/ipamhandles.crd.projectcalico.org created customresourcedefinition.apiextensions.k8s.io/ippools.crd.projectcalico.org created customresourcedefinition.apiextensions.k8s.io/ipreservations.crd.projectcalico.org created customresourcedefinition.apiextensions.k8s.io/kubecontrollersconfigurations.crd.projectcalico.org created customresourcedefinition.apiextensions.k8s.io/networkpolicies.crd.projectcalico.org created customresourcedefinition.apiextensions.k8s.io/networksets.crd.projectcalico.org created clusterrole.rbac.authorization.k8s.io/calico-kube-controllers created clusterrolebinding.rbac.authorization.k8s.io/calico-kube-controllers created clusterrole.rbac.authorization.k8s.io/calico-node created clusterrolebinding.rbac.authorization.k8s.io/calico-node created daemonset.apps/calico-node created serviceaccount/calico-node created deployment.apps/calico-kube-controllers created serviceaccount/calico-kube-controllers created poddisruptionbudget.policy/calico-kube-controllers created \u9a8c\u8bc1Calico\u5b89\u88c5\u72b6\u6001\uff0c\u786e\u4fdd\u5728\u6bcf\u4e2a\u8282\u70b9\u4e0a\u90fd\u6b63\u5e38\u8fd0\u884c\u3002 kubectl get pod -n kube-system | grep calico \u8f93\u51fa\u7ed3\u679c\uff1a NAME READY STATUS RESTARTS AGE calico-kube-controllers-7bc6547ffb-tjfcg 1/1 Running 0 30m calico-node-7x8jm 1/1 Running 0 30m calico-node-cwxj5 1/1 Running 0 30m calico-node-rq978 1/1 Running 0 30m \u5982\u679c\u9047\u5230\u4efb\u4f55\u9519\u8bef\uff0c\u9996\u5148\u68c0\u67e5\u5bb9\u5668container\u65e5\u5fd7\u3002 # Get Container ID crictl ps # Get log info crictl logs \u7531\u4e8e\u6211\u4eec\u5c06 CNI \u4ece Flannel \u66f4\u6539\u4e3a Calico\uff0c\u6211\u4eec\u9700\u8981\u5220\u9664\u6240\u6709 Pod\uff0c\u6240\u6709 Pod \u90fd\u5c06\u81ea\u52a8\u91cd\u65b0\u521b\u5efa\u3002 kubectl delete pod -A --all \u67e5\u8be2\u6240\u6709pod\u90fd\u72b6\u6001\uff0c\u786e\u4fdd\u4ed6\u4eec\u90fd\u6b63\u5e38\u8fd0\u884c\u3002 kubectl get pod -A","title":"\u7528Calico\u66ff\u6362Flannel"},{"location":"k8s/cka_cn/foundamentals/networkpolicy/#inbound-rules","text":"\u6f14\u793a\u573a\u666f\uff1a \u521b\u5efa\u7528\u4e8e\u6d4b\u8bd5\u7684\u5de5\u4f5c\u8d1f\u8f7d\u3002 \u7981\u6b62\u6240\u6709\u5165\u7ad9\u6d41\u91cf\u3002 \u5141\u8bb8\u7279\u5b9a\u7684\u5165\u7ad9\u6d41\u91cf\u3002 \u9a8c\u8bc1NetworkPolicy\u3002","title":"\u5165\u7ad9\u89c4\u5219\uff08Inbound Rules\uff09"},{"location":"k8s/cka_cn/foundamentals/networkpolicy/#_1","text":"\u521b\u5efa\u4e09\u4e2a Deployment\uff0c\u540d\u79f0\u4e3a pod-netpol-1 \u3001 pod-netpol-2 \u548c pod-netpol-3 \uff0c\u5b83\u4eec\u90fd\u57fa\u4e8e\u955c\u50cf busybox \u3002 kubectl apply -f - << EOF apiVersion: apps/v1 kind: Deployment metadata: labels: app: pod-netpol-1 name: pod-netpol-1 spec: replicas: 1 selector: matchLabels: app: pod-netpol-1 template: metadata: labels: app: pod-netpol-1 spec: containers: - image: busybox name: busybox command: [\"sh\", \"-c\", \"sleep 1h\"] --- apiVersion: apps/v1 kind: Deployment metadata: labels: app: pod-netpol-2 name: pod-netpol-2 spec: replicas: 1 selector: matchLabels: app: pod-netpol-2 template: metadata: labels: app: pod-netpol-2 spec: containers: - image: busybox name: busybox command: [\"sh\", \"-c\", \"sleep 1h\"] --- apiVersion: apps/v1 kind: Deployment metadata: labels: app: pod-netpol-3 name: pod-netpol-3 spec: replicas: 1 selector: matchLabels: app: pod-netpol-3 template: metadata: labels: app: pod-netpol-3 spec: containers: - image: busybox name: busybox command: [\"sh\", \"-c\", \"sleep 1h\"] EOF \u68c0\u67e5pod\u7684IP\u5730\u5740\uff1a kubectl get pod -owide \u8f93\u51fa\u7ed3\u679c\uff1a NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES pod-netpol-1-6494f6bf8b-n58r9 1/1 Running 0 29s 10.244.102.30 cka003 pod-netpol-2-77478d77ff-l6rzm 1/1 Running 0 29s 10.244.112.30 cka002 pod-netpol-3-68977dcb48-ql5s6 1/1 Running 0 29s 10.244.102.31 cka003 \u767b\u5f55\u8fdb\u5165pod pod-netpol-1 \u3002 kubectl exec -it pod-netpol-1-6494f6bf8b-n58r9 -- sh \u6267\u884c\u547d\u4ee4 ping \uff0c\u786e\u4fdd pod-netpol-2 \u548c pod-netpol-3 \u53ef\u4e92\u76f8\u8bbf\u95ee\u3002 / # ping 10.244.112.30 3 packets transmitted, 3 packets received, 0 % packet loss / # ping 10.244.102.31 3 packets transmitted, 3 packets received, 0 % packet loss","title":"\u521b\u5efa\u6d4b\u8bd5\u5de5\u4f5c\u8d1f\u8f7d"},{"location":"k8s/cka_cn/foundamentals/networkpolicy/#_2","text":"\u521b\u5efa\u7b56\u7565\uff0c\u7981\u6b62\u6240\u6709\u5165\u7ad9\u6d41\u91cf\u3002 kubectl apply -f - << EOF apiVersion: networking.k8s.io/v1 kind: NetworkPolicy metadata: name: default-deny-ingress spec: podSelector: {} policyTypes: - Ingress EOF \u518d\u6b21\u767b\u5f55\u8fdb\u5165pod pod-netpol-1 \u3002 kubectl exec -it pod-netpol-1-6494f6bf8b-n58r9 -- sh Execute command ping that pod-netpol-2 and pod-netpol-3 are both unreachable as expected. \u6267\u884c\u547d\u4ee4 ping \uff0c\u548c\u6211\u4eec\u9884\u671f\u4e00\u6837\uff0c pod-netpol-2 \u548c pod-netpol-3 \u6b64\u65f6\u4e92\u76f8\u65e0\u6cd5\u8bbf\u95ee\u3002 / # ping 10.244.112.30 3 packets transmitted, 0 packets received, 100 % packet loss / # ping 10.244.102.31 3 packets transmitted, 0 packets received, 100 % packet loss","title":"\u7981\u6b62\u6240\u6709\u5165\u7ad9\u6d41\u91cf"},{"location":"k8s/cka_cn/foundamentals/networkpolicy/#_3","text":"\u521b\u5efa NetworkPolicy\uff0c\u5141\u8bb8\u6765\u81ea pod-netpol-1 \u5230 pod-netpol-2 \u7684\u5165\u7ad9\u6d41\u91cf\u3002 kubectl apply -f - <:80 \u5931\u8d25 \u8fd0\u884c curl :80 \u6210\u529f kubectl run centos --image = centos -n my-ns-1 -- \"/bin/sh\" \"-c\" \"sleep 3600\" kubectl exec -it mycentos -n my-ns-1 -- bash \u5728namespace my-ns-2 \u4e2d\u521b\u5efa\u4e00\u4e2a\u4e34\u65f6 Pod\uff0c\u7136\u540e\u8fde\u63a5\u5230\u8be5 Pod \u5e76\u9a8c\u8bc1\u8bbf\u95ee\u3002 \u547d\u4ee4 curl :80 \u5931\u8d25 \u547d\u4ee4 curl :80 \u5931\u8d25\u3002 kubectl run centos --image = centos -n my-ns-2 -- \"/bin/sh\" \"-c\" \"sleep 3600\" kubectl exec -it mycentos -n my-ns-2 -- bash \u4fee\u6539 my-networkpolicy-1 \uff0c \u628a ingress.from.namespaceSelector.matchLabels \u7684\u503c\u6539\u4e3a my-ns-2 \u3002 \u767b\u5f55\u8fdb\u5165namespace my-ns-2 \u4e0a\u7684\u4e34\u65f6pod\uff0c\u9a8c\u8bc1\u8bbf\u95ee\u3002 \u547d\u4ee4 curl :80 \u5931\u8d25 \u547d\u4ee4 curl :80 \u6210\u529f kubectl exec -it mycentos -n my-ns-2 -- bash \u5220\u9664\u6f14\u793a\u4e2d\u521b\u5efa\u7684\u4e34\u65f6\u8d44\u6e90\u3002 kubectl delete namespace my-ns-1 kubectl delete namespace my-ns-2","title":"NetworkPolicy"},{"location":"k8s/cka_cn/foundamentals/overview/","text":"CKA\u81ea\u5b66\u7b14\u8bb06:Kubernetes\u96c6\u7fa4\u6982\u89c8 \u00b6 \u6458\u8981 \u00b6 \u5305\u542b\u4e0b\u9762\u5185\u5bb9\uff1a \u5bb9\u5668\u5c42 Kubernetes\u5c42 \u63d0\u793a\uff1a \u540e\u7eed\u5b9e\u9a8c\u73af\u5883\u90fd\u662f\u4f7f\u7528\u5728\u963f\u91cc\u4e91\u90e8\u7f72\u7684Ubuntu\u4e09\u8282\u70b9\u96c6\u7fa4\uff0c\u4e09\u4e2a\u8282\u70b9\u5206\u522b\u4e3a cka001 \u3001 cka002 \u548c cka003 \u3002 \u5bb9\u5668\u5c42 \u00b6 \u573a\u666f\uff1a \u4f7f\u7528Containerd\u670d\u52a1\uff0c\u901a\u8fc7\u547d\u4ee4 nerdctl \u6765\u7ba1\u7406\u6211\u4eec\u7684\u955c\u50cf\u548c\u5bb9\u5668\uff0c\u8fd9\u4e0eDocker\u7684\u6982\u5ff5\u76f8\u540c\u3002 Get namespace. Get containers. Get images. Get volumes. Get overall status. Get network status. \u6f14\u793a\uff1a \u8bfb\u53d6\u547d\u540d\u7a7a\u95f4namespaces\u3002 sudo nerdctl namespace ls \u8fd0\u884c\u7ed3\u679c\uff1a NAME CONTAINERS IMAGES VOLUMES LABELS k8s.io 21 30 0 \u8bfb\u53d6\u547d\u540d\u7a7a\u95f4 k8s.io \u4e0b\u7684\u5bb9\u5668\u3002 sudo nerdctl -n k8s.io ps \u8fd0\u884c\u7ed3\u679c\uff1a CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 0a3625f22f65 registry.aliyuncs.com/google_containers/pause:3.6 \"/pause\" 16 hours ago Up k8s://kube-system/coredns-74586cf9b6-4jwmk 121af2ecd1a1 registry.aliyuncs.com/google_containers/coredns:v1.8.6 \"/coredns -conf /etc\u2026\" 16 hours ago Up k8s://kube-system/coredns-74586cf9b6-c5mll/coredns 49f6c7e3efe5 registry.aliyuncs.com/google_containers/kube-proxy:v1.24.0 \"/usr/local/bin/kube\u2026\" 16 hours ago Up k8s://kube-system/kube-proxy-dmj2t/kube-proxy 4bba5fbd701d registry.aliyuncs.com/google_containers/pause:3.6 \"/pause\" 16 hours ago Up k8s://kube-system/kube-scheduler-cka001 57d47b57eb12 docker.io/calico/node:v3.23.3 \"start_runit\" 16 hours ago Up k8s://kube-system/calico-node-w8nvl/calico-node 5ce4c351a886 registry.aliyuncs.com/google_containers/pause:3.6 \"/pause\" 16 hours ago Up k8s://kube-system/calico-node-w8nvl 6456eef784bf registry.aliyuncs.com/google_containers/kube-scheduler:v1.24.0 \"kube-scheduler --au\u2026\" 16 hours ago Up k8s://kube-system/kube-scheduler-cka001/kube-scheduler 6a687305871c registry.aliyuncs.com/google_containers/kube-apiserver:v1.24.0 \"kube-apiserver --ad\u2026\" 16 hours ago Up k8s://kube-system/kube-apiserver-cka001/kube-apiserver 7dcb24568574 registry.aliyuncs.com/google_containers/pause:3.6 \"/pause\" 16 hours ago Up k8s://kube-system/coredns-74586cf9b6-c5mll a06b101118b8 registry.aliyuncs.com/google_containers/pause:3.6 \"/pause\" 16 hours ago Up k8s://kube-system/kube-controller-manager-cka001 a07ef8c3fc3a registry.aliyuncs.com/google_containers/pause:3.6 \"/pause\" 16 hours ago Up k8s://kube-system/etcd-cka001 b8566d3e4174 registry.aliyuncs.com/google_containers/kube-controller-manager:v1.24.0 \"kube-controller-man\u2026\" 16 hours ago Up k8s://kube-system/kube-controller-manager-cka001/kube-controller-manager ca6ac26314ff registry.aliyuncs.com/google_containers/coredns:v1.8.6 \"/coredns -conf /etc\u2026\" 16 hours ago Up k8s://kube-system/coredns-74586cf9b6-4jwmk/coredns cdc041b4791e registry.aliyuncs.com/google_containers/etcd:3.5.3-0 \"etcd --advertise-cl\u2026\" 16 hours ago Up k8s://kube-system/etcd-cka001/etcd e0c59abadf2e registry.aliyuncs.com/google_containers/pause:3.6 \"/pause\" 16 hours ago Up k8s://kube-system/kube-proxy-dmj2t e0d2e5f6ccff registry.aliyuncs.com/google_containers/pause:3.6 \"/pause\" 16 hours ago Up k8s://kube-system/kube-apiserver-cka001 \u8bfb\u53d6\u547d\u540d\u7a7a\u95f4 k8s.io \u4e0b\u7684\u955c\u50cf\u3002 sudo nerdctl -n k8s.io image ls -a \u8bfb\u53d6\u547d\u540d\u7a7a\u95f4 k8s.io \u4e0b\u7684\u5377Volume\u3002\u521d\u59cb\u5316\u5b89\u88c5\u540e\uff0c\u8be5\u547d\u540d\u7a7a\u95f4\u4e0b\u6ca1\u6709\u4efb\u4f55\u5377\u3002 sudo nerdctl -n k8s.io volume ls \u8bfb\u53d6\u96c6\u7fa4\u72b6\u6001\u3002 sudo nerdctl stats \u8bfb\u53d6\u7f51\u7edc\u72b6\u6001\u3002 sudo nerdctl network ls sudo nerdctl network inspect bridge sudo nerdctl network inspect k8s-pod-network \u8fd0\u884c\u7ed3\u679c\uff1a NETWORK ID NAME FILE k8s-pod-network /etc/cni/net.d/10-calico.conflist 0 bridge /etc/cni/net.d/nerdctl-bridge.conflist host none Get network interface in host cka001 with command ip addr list . IP pool of 10.4.0.1/24 is ipam and defined in /etc/cni/net.d/nerdctl-bridge.conflist . \u4f7f\u7528\u547d\u4ee4 ip addr list \u83b7\u53d6\u4e3b\u673a cka001 \u7684\u7f51\u7edc\u63a5\u53e3\u3002 10.4.0.1/24 \u7684IP\u6c60\u662f ipam \uff0c\u5728 /etc/cni/net.d/nerdctl-bridge.conflist \u4e2d\u5b9a\u4e49\u3002 lo : inet 127.0.0.1/8 qlen 1000 eth0 : inet /24 brd xxx.xxx.xxx.255 scope global dynamic eth0 tunl0@NONE : inet 10.244.228.192/32 scope global tunl0 cali96e32d88db2@if4 : cali93613212490@if4 : nerdctl-bridge.conflist \u6587\u4ef6\u7684\u4f5c\u7528\u662f\uff1a \u5b9a\u4e49\u4e86nerdctl\u4f7f\u7528\u7684\u9ed8\u8ba4\u6865\u63a5CNI\u7f51\u7edc\u7684\u914d\u7f6e\uff0c\u5305\u62ec\u7f51\u7edc\u540d\u79f0\u3001\u5b50\u7f51\u3001\u7f51\u5173\u3001IP\u5206\u914d\u7b56\u7565\u7b49 1 \uff0c 2 \u3002 \u4f7f\u5f97nerdctl\u53ef\u4ee5\u4f7f\u7528docker run -it --rm alpine\u8fd9\u6837\u7684\u547d\u4ee4\u6765\u8fd0\u884c\u4e00\u4e2a\u5bb9\u5668\uff0c\u5e76\u81ea\u52a8\u5206\u914d\u4e00\u4e2a10.4.0.0/24\u7f51\u6bb5\u7684IP\u5730\u5740 1 \uff0c 3 \u3002 \u4f7f\u5f97nerdctl\u53ef\u4ee5\u652f\u6301\u4e00\u4e9b\u57fa\u672c\u7684CNI\u63d2\u4ef6\uff0c\u5982bridge, portmap, firewall, tuning 1 \uff0c 2 \u3002 Kubernetes\u5c42 \u00b6 \u573a\u666f\uff1a \u8282\u70b9Nodes \u547d\u540d\u7a7a\u95f4Namespaces \u7cfb\u7edfPods \u6f14\u793a\uff1a \u8bfb\u53d6\u8282\u70b9\u72b6\u6001\uff1a kubectl get node -o wide \u5728\u4e09\u4e2a\u8282\u70b9\u4e0a\u6709\u56db\u4e2a\u521d\u59cb\u7684\u547d\u540d\u7a7a\u95f4\u3002 kubectl get namespace -A \u8fd0\u884c\u7ed3\u679c\uff1a NAME STATUS AGE default Active 56m kube-node-lease Active 56m kube-public Active 56m kube-system Active 56m \u5728\u4e09\u4e2a\u8282\u70b9\u4e0a\u7684\u521d\u59cb\u5316Pod\u3002 kubectl get pod -A -o wide \u8fd0\u884c\u7ed3\u679c\uff1a NAMESPACE NAME READY STATUS RESTARTS AGE NODE NOMINATED NODE READINESS GATES kube-system calico-kube-controllers-555bc4b957-l8bn2 1/1 Running 0 15h cka003 kube-system calico-node-255pc 1/1 Running 0 15h cka003 kube-system calico-node-7tmnb 1/1 Running 0 15h cka002 kube-system calico-node-w8nvl 1/1 Running 0 15h cka001 kube-system coredns-74586cf9b6-4jwmk 1/1 Running 0 15h cka001 kube-system coredns-74586cf9b6-c5mll 1/1 Running 0 15h cka001 kube-system etcd-cka001 1/1 Running 0 15h cka001 kube-system kube-apiserver-cka001 1/1 Running 0 15h cka001 kube-system kube-controller-manager-cka001 1/1 Running 0 15h cka001 kube-system kube-proxy-dmj2t 1/1 Running 0 15h cka001 kube-system kube-proxy-n77zw 1/1 Running 0 15h cka002 kube-system kube-proxy-qs6rf 1/1 Running 0 15h cka003 kube-system kube-scheduler-cka001 1/1 Running 0 15h cka001 \u603b\u7ed3\uff1a \u4e0b\u9762\u5217\u51fa\u4e86\u521d\u59cb\u96c6\u7fa4\u4e2d\u4e3b\u8282\u70b9\u548c\u6240\u6709\u8282\u70b9\u4e2d\u6240\u5305\u542b\u7684\u5bb9\u5668\u548cPod\u7684\u5173\u7cfb\u3002 Master node: CoreDNS: 2 Pod etcd: 1 Pod apiserver: 1 Pod controller-manager: 1 Pod scheduler: 1 Pod Calico Controller: 1 Pod All nodes: Calico Node: 1 Pod each Proxy: 1 Pod each \u53c2\u8003\uff1a pause\u5bb9\u5668\uff1a \u6587\u7ae01 and \u6587\u7ae02 . nerdctl","title":"Kubernetes\u96c6\u7fa4\u6982\u89c8"},{"location":"k8s/cka_cn/foundamentals/overview/#cka6kubernetes","text":"","title":"CKA\u81ea\u5b66\u7b14\u8bb06:Kubernetes\u96c6\u7fa4\u6982\u89c8"},{"location":"k8s/cka_cn/foundamentals/overview/#_1","text":"\u5305\u542b\u4e0b\u9762\u5185\u5bb9\uff1a \u5bb9\u5668\u5c42 Kubernetes\u5c42 \u63d0\u793a\uff1a \u540e\u7eed\u5b9e\u9a8c\u73af\u5883\u90fd\u662f\u4f7f\u7528\u5728\u963f\u91cc\u4e91\u90e8\u7f72\u7684Ubuntu\u4e09\u8282\u70b9\u96c6\u7fa4\uff0c\u4e09\u4e2a\u8282\u70b9\u5206\u522b\u4e3a cka001 \u3001 cka002 \u548c cka003 \u3002","title":"\u6458\u8981"},{"location":"k8s/cka_cn/foundamentals/overview/#_2","text":"\u573a\u666f\uff1a \u4f7f\u7528Containerd\u670d\u52a1\uff0c\u901a\u8fc7\u547d\u4ee4 nerdctl \u6765\u7ba1\u7406\u6211\u4eec\u7684\u955c\u50cf\u548c\u5bb9\u5668\uff0c\u8fd9\u4e0eDocker\u7684\u6982\u5ff5\u76f8\u540c\u3002 Get namespace. Get containers. Get images. Get volumes. Get overall status. Get network status. \u6f14\u793a\uff1a \u8bfb\u53d6\u547d\u540d\u7a7a\u95f4namespaces\u3002 sudo nerdctl namespace ls \u8fd0\u884c\u7ed3\u679c\uff1a NAME CONTAINERS IMAGES VOLUMES LABELS k8s.io 21 30 0 \u8bfb\u53d6\u547d\u540d\u7a7a\u95f4 k8s.io \u4e0b\u7684\u5bb9\u5668\u3002 sudo nerdctl -n k8s.io ps \u8fd0\u884c\u7ed3\u679c\uff1a CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 0a3625f22f65 registry.aliyuncs.com/google_containers/pause:3.6 \"/pause\" 16 hours ago Up k8s://kube-system/coredns-74586cf9b6-4jwmk 121af2ecd1a1 registry.aliyuncs.com/google_containers/coredns:v1.8.6 \"/coredns -conf /etc\u2026\" 16 hours ago Up k8s://kube-system/coredns-74586cf9b6-c5mll/coredns 49f6c7e3efe5 registry.aliyuncs.com/google_containers/kube-proxy:v1.24.0 \"/usr/local/bin/kube\u2026\" 16 hours ago Up k8s://kube-system/kube-proxy-dmj2t/kube-proxy 4bba5fbd701d registry.aliyuncs.com/google_containers/pause:3.6 \"/pause\" 16 hours ago Up k8s://kube-system/kube-scheduler-cka001 57d47b57eb12 docker.io/calico/node:v3.23.3 \"start_runit\" 16 hours ago Up k8s://kube-system/calico-node-w8nvl/calico-node 5ce4c351a886 registry.aliyuncs.com/google_containers/pause:3.6 \"/pause\" 16 hours ago Up k8s://kube-system/calico-node-w8nvl 6456eef784bf registry.aliyuncs.com/google_containers/kube-scheduler:v1.24.0 \"kube-scheduler --au\u2026\" 16 hours ago Up k8s://kube-system/kube-scheduler-cka001/kube-scheduler 6a687305871c registry.aliyuncs.com/google_containers/kube-apiserver:v1.24.0 \"kube-apiserver --ad\u2026\" 16 hours ago Up k8s://kube-system/kube-apiserver-cka001/kube-apiserver 7dcb24568574 registry.aliyuncs.com/google_containers/pause:3.6 \"/pause\" 16 hours ago Up k8s://kube-system/coredns-74586cf9b6-c5mll a06b101118b8 registry.aliyuncs.com/google_containers/pause:3.6 \"/pause\" 16 hours ago Up k8s://kube-system/kube-controller-manager-cka001 a07ef8c3fc3a registry.aliyuncs.com/google_containers/pause:3.6 \"/pause\" 16 hours ago Up k8s://kube-system/etcd-cka001 b8566d3e4174 registry.aliyuncs.com/google_containers/kube-controller-manager:v1.24.0 \"kube-controller-man\u2026\" 16 hours ago Up k8s://kube-system/kube-controller-manager-cka001/kube-controller-manager ca6ac26314ff registry.aliyuncs.com/google_containers/coredns:v1.8.6 \"/coredns -conf /etc\u2026\" 16 hours ago Up k8s://kube-system/coredns-74586cf9b6-4jwmk/coredns cdc041b4791e registry.aliyuncs.com/google_containers/etcd:3.5.3-0 \"etcd --advertise-cl\u2026\" 16 hours ago Up k8s://kube-system/etcd-cka001/etcd e0c59abadf2e registry.aliyuncs.com/google_containers/pause:3.6 \"/pause\" 16 hours ago Up k8s://kube-system/kube-proxy-dmj2t e0d2e5f6ccff registry.aliyuncs.com/google_containers/pause:3.6 \"/pause\" 16 hours ago Up k8s://kube-system/kube-apiserver-cka001 \u8bfb\u53d6\u547d\u540d\u7a7a\u95f4 k8s.io \u4e0b\u7684\u955c\u50cf\u3002 sudo nerdctl -n k8s.io image ls -a \u8bfb\u53d6\u547d\u540d\u7a7a\u95f4 k8s.io \u4e0b\u7684\u5377Volume\u3002\u521d\u59cb\u5316\u5b89\u88c5\u540e\uff0c\u8be5\u547d\u540d\u7a7a\u95f4\u4e0b\u6ca1\u6709\u4efb\u4f55\u5377\u3002 sudo nerdctl -n k8s.io volume ls \u8bfb\u53d6\u96c6\u7fa4\u72b6\u6001\u3002 sudo nerdctl stats \u8bfb\u53d6\u7f51\u7edc\u72b6\u6001\u3002 sudo nerdctl network ls sudo nerdctl network inspect bridge sudo nerdctl network inspect k8s-pod-network \u8fd0\u884c\u7ed3\u679c\uff1a NETWORK ID NAME FILE k8s-pod-network /etc/cni/net.d/10-calico.conflist 0 bridge /etc/cni/net.d/nerdctl-bridge.conflist host none Get network interface in host cka001 with command ip addr list . IP pool of 10.4.0.1/24 is ipam and defined in /etc/cni/net.d/nerdctl-bridge.conflist . \u4f7f\u7528\u547d\u4ee4 ip addr list \u83b7\u53d6\u4e3b\u673a cka001 \u7684\u7f51\u7edc\u63a5\u53e3\u3002 10.4.0.1/24 \u7684IP\u6c60\u662f ipam \uff0c\u5728 /etc/cni/net.d/nerdctl-bridge.conflist \u4e2d\u5b9a\u4e49\u3002 lo : inet 127.0.0.1/8 qlen 1000 eth0 : inet /24 brd xxx.xxx.xxx.255 scope global dynamic eth0 tunl0@NONE : inet 10.244.228.192/32 scope global tunl0 cali96e32d88db2@if4 : cali93613212490@if4 : nerdctl-bridge.conflist \u6587\u4ef6\u7684\u4f5c\u7528\u662f\uff1a \u5b9a\u4e49\u4e86nerdctl\u4f7f\u7528\u7684\u9ed8\u8ba4\u6865\u63a5CNI\u7f51\u7edc\u7684\u914d\u7f6e\uff0c\u5305\u62ec\u7f51\u7edc\u540d\u79f0\u3001\u5b50\u7f51\u3001\u7f51\u5173\u3001IP\u5206\u914d\u7b56\u7565\u7b49 1 \uff0c 2 \u3002 \u4f7f\u5f97nerdctl\u53ef\u4ee5\u4f7f\u7528docker run -it --rm alpine\u8fd9\u6837\u7684\u547d\u4ee4\u6765\u8fd0\u884c\u4e00\u4e2a\u5bb9\u5668\uff0c\u5e76\u81ea\u52a8\u5206\u914d\u4e00\u4e2a10.4.0.0/24\u7f51\u6bb5\u7684IP\u5730\u5740 1 \uff0c 3 \u3002 \u4f7f\u5f97nerdctl\u53ef\u4ee5\u652f\u6301\u4e00\u4e9b\u57fa\u672c\u7684CNI\u63d2\u4ef6\uff0c\u5982bridge, portmap, firewall, tuning 1 \uff0c 2 \u3002","title":"\u5bb9\u5668\u5c42"},{"location":"k8s/cka_cn/foundamentals/overview/#kubernetes","text":"\u573a\u666f\uff1a \u8282\u70b9Nodes \u547d\u540d\u7a7a\u95f4Namespaces \u7cfb\u7edfPods \u6f14\u793a\uff1a \u8bfb\u53d6\u8282\u70b9\u72b6\u6001\uff1a kubectl get node -o wide \u5728\u4e09\u4e2a\u8282\u70b9\u4e0a\u6709\u56db\u4e2a\u521d\u59cb\u7684\u547d\u540d\u7a7a\u95f4\u3002 kubectl get namespace -A \u8fd0\u884c\u7ed3\u679c\uff1a NAME STATUS AGE default Active 56m kube-node-lease Active 56m kube-public Active 56m kube-system Active 56m \u5728\u4e09\u4e2a\u8282\u70b9\u4e0a\u7684\u521d\u59cb\u5316Pod\u3002 kubectl get pod -A -o wide \u8fd0\u884c\u7ed3\u679c\uff1a NAMESPACE NAME READY STATUS RESTARTS AGE NODE NOMINATED NODE READINESS GATES kube-system calico-kube-controllers-555bc4b957-l8bn2 1/1 Running 0 15h cka003 kube-system calico-node-255pc 1/1 Running 0 15h cka003 kube-system calico-node-7tmnb 1/1 Running 0 15h cka002 kube-system calico-node-w8nvl 1/1 Running 0 15h cka001 kube-system coredns-74586cf9b6-4jwmk 1/1 Running 0 15h cka001 kube-system coredns-74586cf9b6-c5mll 1/1 Running 0 15h cka001 kube-system etcd-cka001 1/1 Running 0 15h cka001 kube-system kube-apiserver-cka001 1/1 Running 0 15h cka001 kube-system kube-controller-manager-cka001 1/1 Running 0 15h cka001 kube-system kube-proxy-dmj2t 1/1 Running 0 15h cka001 kube-system kube-proxy-n77zw 1/1 Running 0 15h cka002 kube-system kube-proxy-qs6rf 1/1 Running 0 15h cka003 kube-system kube-scheduler-cka001 1/1 Running 0 15h cka001 \u603b\u7ed3\uff1a \u4e0b\u9762\u5217\u51fa\u4e86\u521d\u59cb\u96c6\u7fa4\u4e2d\u4e3b\u8282\u70b9\u548c\u6240\u6709\u8282\u70b9\u4e2d\u6240\u5305\u542b\u7684\u5bb9\u5668\u548cPod\u7684\u5173\u7cfb\u3002 Master node: CoreDNS: 2 Pod etcd: 1 Pod apiserver: 1 Pod controller-manager: 1 Pod scheduler: 1 Pod Calico Controller: 1 Pod All nodes: Calico Node: 1 Pod each Proxy: 1 Pod each \u53c2\u8003\uff1a pause\u5bb9\u5668\uff1a \u6587\u7ae01 and \u6587\u7ae02 . nerdctl","title":"Kubernetes\u5c42"},{"location":"k8s/cka_cn/foundamentals/persistence/","text":"CKA\u81ea\u5b66\u7b14\u8bb017:Persistence \u00b6 \u6458\u8981 \u00b6 \u6f14\u793a\u573a\u666f\uff1a \u521b\u5efa\u4e00\u4e2a\u7c7b\u578b\u4e3a emptyDir \u7684\u5377\u6765\u521b\u5efa Pod\uff0cPod \u4e2d\u7684\u5bb9\u5668\u5c06\u4f1a\u6302\u8f7d\u5728\u8fd0\u884c\u8282\u70b9\u4e0a\u7684\u9ed8\u8ba4\u76ee\u5f55 /var/lib/kubelet/pods/ \u4e2d\u3002 \u521b\u5efa\u4e00\u4e2a\u7c7b\u578b\u4e3a hostPath \u7684\u5377\u6765\u521b\u5efa Deployment\uff0cDeployment \u4e2d\u7684\u5bb9\u5668\u5c06\u4f1a\u6302\u8f7d\u5728\u8fd0\u884c\u8282\u70b9\u4e0a\u5b9a\u4e49\u7684\u76ee\u5f55 hostPath: \u4e2d\u3002 \u521b\u5efa PV \u548c PVC\uff1a \u8bbe\u7f6e NFS \u670d\u52a1\u5668\u5e76\u5171\u4eab /nfsdata/ \u76ee\u5f55\u3002 \u521b\u5efa PV mysql-pv \u5e76\u6620\u5c04\u5230\u5171\u4eab\u76ee\u5f55 /nfsdata/ \uff0c\u540c\u65f6\u8bbe\u7f6e StorageClassName \u4e3a nfs \u3002 \u521b\u5efa PVC mysql-pvc \u5e76\u6620\u5c04\u5230 StorageClassName \u4e3a nfs \u7684 PV \u4e0a\u3002 \u521b\u5efa Deployment mysql \u6765\u4f7f\u7528 PVC mysql-pvc \u3002 \u521b\u5efa StorageClass\uff1a \u521b\u5efa ServiceAccount nfs-client-provisioner \u3002 \u521b\u5efa ClusterRole nfs-client-provisioner-runner \u548c Role leader-locking-nfs-client-provisioner \uff0c\u5e76\u5c06\u5176\u7ed1\u5b9a\u5230 ServiceAccount \u4e0a\uff0c\u4ee5\u4fbf\u8be5 ServiceAccount \u53ef\u4ee5\u64cd\u4f5c\u4e0b\u4e00\u6b65\u4e2d\u521b\u5efa\u7684 Deployment\u3002 \u521b\u5efa Deployment nfs-client-provisioner \u6765\u6dfb\u52a0\u8fde\u63a5\u5230 NFS \u670d\u52a1\u5668\u7684\u4fe1\u606f\uff0c\u4f8b\u5982 PROVISIONER_NAME \u662f k8s-sigs.io/nfs-subdir-external-provisioner \u3002 \u521b\u5efa StorageClass nfs-client \u5e76\u94fe\u63a5\u5230 provisioner: k8s-sigs.io/nfs-subdir-external-provisioner \uff0c\u76f8\u5173\u7684 PV \u4f1a\u81ea\u52a8\u521b\u5efa\u3002 \u521b\u5efa PVC nfs-pvc-from-sc \u5e76\u6620\u5c04\u5230 StorageClass nfs-client \u4e0a\u7684 PV\u3002 \u914d\u7f6eConfiguration\uff1a \u521b\u5efa\u4e00\u4e2a ConfigMap \u4ee5\u5305\u542b\u6587\u4ef6\u7684\u5185\u5bb9\uff0c\u5e76\u5c06\u6b64 ConfigMap \u6302\u8f7d\u5230 Pod \u4e2d\u7684\u7279\u5b9a\u6587\u4ef6\u4e2d\u3002 \u521b\u5efa\u4e00\u4e2a ConfigMap \u6765\u5305\u542b\u7528\u6237\u540d\u548c\u5bc6\u7801\uff0c\u5e76\u5728 Pod \u4e2d\u4f7f\u7528\u5b83\u4eec\u3002 \u5728 Pod \u4e2d\u5c06 ConfigMap \u7528\u4f5c\u73af\u5883\u53d8\u91cf\u3002 \u5efa\u8bae\uff1a \u9996\u5148\u5220\u9664 PVC\uff0c\u7136\u540e\u518d\u5220\u9664 PV\u3002 \u5982\u679c\u5220\u9664 PVC \u65f6\u9047\u5230 Terminating \u72b6\u6001\uff0c\u4f7f\u7528 kubectl edit pvc \u547d\u4ee4\uff0c\u7136\u540e\u5220\u9664 finalize: \u3002 emptyDir \u00b6 \u521b\u5efa\u4e00\u4e2a\u540d\u4e3a hello-producer \u7684 Pod\uff0c\u5e76\u4f7f\u7528 emptyDir \u7c7b\u578b\u7684 Volume\u3002 cat > pod-emptydir.yaml < /producer_dir/hello; sleep 30000 volumes: - name: shared-volume emptyDir: {} EOF kubectl apply -f pod-emptydir.yaml \u67e5\u770bPod hello-producer \u7684\u72b6\u6001\u3002 kubectl get pod hello-producer -owide Pod hello-producer \u8fd0\u884c\u5728\u8282\u70b9node cka003 \u4e0a\u3002 NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES hello-producer 1/1 Running 0 6s 10.244.102.24 cka003 \u767b\u5f55 cka003 \uff0c\u56e0\u4e3a Pod hello-producer \u6b63\u5728\u8be5\u8282\u70b9\u4e0a\u8fd0\u884c\u3002 \u4e3a crictl \u547d\u4ee4\u8bbe\u7f6e\u73af\u5883\u53d8\u91cf CONTAINER_RUNTIME_ENDPOINT \u3002\u5efa\u8bae\u5728\u6240\u6709\u8282\u70b9\u4e0a\u6267\u884c\u76f8\u540c\u7684\u64cd\u4f5c\u3002 export CONTAINER_RUNTIME_ENDPOINT = unix:///run/containerd/containerd.sock \u8fd0\u884c\u547d\u4ee4 crictl ps \u6765\u83b7\u53d6 Pod hello-producer \u7684\u5bb9\u5668 ID\u3002 crictl ps | grep hello-producer \u5bb9\u5668 producer \u7684ID\u662f 05f5e1bb6a1bb \u3002 CONTAINER IMAGE CREATED STATE NAME ATTEMPT POD ID POD 50058afb3cba5 62aedd01bd852 About an hour ago Running producer 0 e6953bd4833a7 hello-producer \u8fd0\u884c\u547d\u4ee4 crictl inspect \uff0c\u83b7\u53d6\u5df2\u6302\u8f7d\u7684 shared-volume \u7684\u8def\u5f84\uff0c\u5b83\u662f emptyDir \u7c7b\u578b\u7684\u3002 crictl inspect 50058afb3cba5 | grep source | grep empty \u8fd0\u884c\u7ed3\u679c \"source\": \"/var/lib/kubelet/pods/d7424f86-534a-48f9-9001-9d2a6e822b12/volumes/kubernetes.io~empty-dir/shared-volume\", \u4fee\u6539\u8def\u5f84\u4e3a\u4e0a\u9762\u83b7\u53d6\u5230\u7684 shared-volume \u7684\u6302\u8f7d\u8def\u5f84\u3002\u7136\u540e\u6211\u4eec\u4f1a\u770b\u5230\u6587\u4ef6 hello \u4e2d\u7684\u5185\u5bb9 hello world \u3002 cd /var/lib/kubelet/pods/d7424f86-534a-48f9-9001-9d2a6e822b12/volumes/kubernetes.io~empty-dir/shared-volume cat hello Pod\u5185\u7684\u8def\u5f84 /producer_dir \u88ab\u6302\u8f7d\u5230\u4e86\u672c\u5730\u5bbf\u4e3b\u673a\u8def\u5f84 /var/lib/kubelet/pods/d7424f86-534a-48f9-9001-9d2a6e822b12/volumes/kubernetes.io~empty-dir/shared-volume \u3002 \u6211\u4eec\u5728Pod\u5185\u521b\u5efa\u7684\u6587\u4ef6 /producer_dir/hello \u5b9e\u9645\u4e0a\u5728\u5bbf\u4e3b\u673a\u672c\u5730\u8def\u5f84\u4e2d\u3002 \u8ba9\u6211\u4eec\u5220\u9664\u5bb9\u5668 producer \uff0c\u5bb9\u5668 producer \u5c06\u4ee5\u65b0\u7684\u5bb9\u5668ID\u91cd\u65b0\u542f\u52a8\uff0c\u800c\u6587\u4ef6 hello \u4ecd\u5c06\u5b58\u5728\u3002 crictl ps crictl stop crictl rm \u73b0\u5728\u5220\u9664Pod hello-producer \uff0c\u5bb9\u5668 producer \u4f1a\u88ab\u5220\u9664\uff0c\u6587\u4ef6 hello \u4e5f\u4f1a\u88ab\u5220\u9664\u3002 kubectl delete pod hello-producer hostPath \u00b6 \u5e94\u7528\u4ee5\u4e0b yaml \u6587\u4ef6\u521b\u5efa\u4e00\u4e2a MySQL Pod \u5e76\u6302\u8f7d\u4e00\u4e2a hostPath \u3002 \u5c06\u4e3b\u673a\u76ee\u5f55 /tmp/mysql \u6302\u8f7d\u5230 Pod \u76ee\u5f55 /var/lib/mysql \u3002 \u5728\u672c\u5730\u68c0\u67e5\u662f\u5426\u5b58\u5728\u76ee\u5f55 /tmp/mysql \uff0c\u5982\u679c\u4e0d\u5b58\u5728\uff0c\u5219\u6267\u884c\u547d\u4ee4 mkdir /tmp/mysql \u521b\u5efa\u5b83\u3002 cat > mysql-hostpath.yaml < cka003 \u5728MySQL Pod\u8fd0\u884c\u7684\u8282\u70b9\u767b\u9646\u8fdb\u5165pod\u5185\u90e8\u3002 kubectl exec -it -- bash \u5728 Pod \u4e2d\uff0c\u8fdb\u5165 /var/lib/mysql \u76ee\u5f55\uff0c\u8be5\u76ee\u5f55\u4e2d\u7684\u6240\u6709\u6587\u4ef6\u90fd\u4e0e\u8282\u70b9 cka003 \u4e0a /tmp/mysql \u76ee\u5f55\u4e2d\u7684\u6240\u6709\u6587\u4ef6\u76f8\u540c\u3002 \u8fde\u63a5\u5230 Pod \u4e2d\u7684\u6570\u636e\u5e93\u3002 mysql -h 127 .0.0.1 -uroot -ppassword \u6267\u884c\u4e0b\u9762\u547d\u4ee4\u5bf9\u6570\u636e\u5e93\u8fdb\u884c\u7b80\u5355\u7684\u64cd\u4f5c\u3002 mysql> show databases ; mysql> connect mysql ; mysql> show tables ; mysql> exit PV\u548cPVC \u00b6 \u4e0b\u9762\u7684\u6f14\u793a\u4e2d\uff0c\u6211\u4eec\u5c06\u4f7f\u7528NFS\u4f5c\u4e3a\u540e\u7aef\u5b58\u50a8\u6765\u6f14\u793a\u5982\u4f55\u90e8\u7f72PV\u548cPVC\u3002 \u8bbe\u7f6eNFS\u5171\u4eab \u00b6 \u5b89\u88c5nfs-kernel-server \u767b\u5f55\u5230\u8282\u70b9 cka002 \u3002\u914d\u7f6eWorker cka002 \u6210\u4e3aNFS\u670d\u52a1\u5668\u3002 sudo apt-get install -y nfs-kernel-server 2.\u914d\u7f6e\u5171\u4eab\u76ee\u5f55 \u521b\u5efa\u5171\u4eab\u6587\u4ef6\u5939\u3002 mkdir /nfsdata \u7f16\u8f91\u6587\u4ef6 /etc/exports \uff0c\u6dfb\u52a0\u4e00\u884c /nfsdata *(rw,sync,no_root_squash) \u3002 cat >> /etc/exports << EOF /nfsdata *(rw,sync,no_root_squash) EOF \u6709\u8bb8\u591a\u4e0d\u540c\u7684NFS\u5171\u4eab\u9009\u9879\uff0c\u4f8b\u5982\uff1a * \uff1a\u5bf9\u6240\u6709IP\u6216\u7279\u5b9aIP\u53ef\u8bbf\u95ee\u3002 rw \uff1a\u4f5c\u4e3a\u8bfb\u5199\u5171\u4eab\u3002\u8bf7\u6ce8\u610f\uff0c\u6b63\u5e38\u7684Linux\u6743\u9650\u4ecd\u7136\u9002\u7528\u3002\uff08\u8bf7\u6ce8\u610f\uff0c\u8fd9\u662f\u9ed8\u8ba4\u9009\u9879\u3002\uff09 ro \uff1a\u4f5c\u4e3a\u53ea\u8bfb\u5171\u4eab\u3002 sync \uff1a\u6587\u4ef6\u6570\u636e\u66f4\u6539\u4f1a\u7acb\u5373\u5199\u5165\u78c1\u76d8\uff0c\u8fd9\u4f1a\u5f71\u54cd\u6027\u80fd\uff0c\u4f46\u4e0d\u592a\u53ef\u80fd\u5bfc\u81f4\u6570\u636e\u4e22\u5931\u3002\u5728\u67d0\u4e9b\u53d1\u884c\u7248\u4e0a\uff0c\u8fd9\u662f\u9ed8\u8ba4\u9009\u9879\u3002 async \uff1a\u4e0esync\u76f8\u53cd\uff0c\u6587\u4ef6\u6570\u636e\u66f4\u6539\u6700\u521d\u5199\u5165\u5185\u5b58\u3002\u8fd9\u63d0\u9ad8\u4e86\u6027\u80fd\uff0c\u4f46\u66f4\u5bb9\u6613\u5bfc\u81f4\u6570\u636e\u4e22\u5931\u3002\u5728\u67d0\u4e9b\u53d1\u884c\u7248\u4e0a\uff0c\u8fd9\u662f\u9ed8\u8ba4\u9009\u9879\u3002 root_squash \uff1a\u5c06NFS\u5ba2\u6237\u7aef\u7684root\u7528\u6237\u548c\u7ec4\u5e10\u6237\u6620\u5c04\u5230\u533f\u540d\u5e10\u6237\uff0c\u901a\u5e38\u662fnobody\u5e10\u6237\u6216nfsnobody\u5e10\u6237\u3002\u6709\u5173\u66f4\u591a\u8be6\u7ec6\u4fe1\u606f\uff0c\u8bf7\u53c2\u89c1\u672c\u6587\u540e\u7eed\u7684\u201c\u7528\u6237ID\u6620\u5c04\u201d\u3002\uff08\u8bf7\u6ce8\u610f\uff0c\u8fd9\u662f\u9ed8\u8ba4\u9009\u9879\u3002\uff09 no_root_squash \uff1a\u5c06NFS\u5ba2\u6237\u7aef\u7684root\u7528\u6237\u548c\u7ec4\u5e10\u6237\u6620\u5c04\u5230\u672c\u5730root\u548c\u7ec4\u5e10\u6237\u3002 \u6211\u4eec\u5c06\u4f7f\u7528\u57fa\u4e8eLinux\u670d\u52a1\u5668\u4e4b\u95f4\u7684 nfs \u548c rpcbind \u670d\u52a1\u7684\u65e0\u5bc6\u7801\u8fdc\u7a0b\u6302\u8f7d\uff0c\u800c\u4e0d\u662f\u57fa\u4e8e smb \u670d\u52a1\u3002\u9996\u5148\uff0c\u8fd9\u4e24\u53f0\u670d\u52a1\u5668\u5fc5\u987b\u6388\u6743\u3001\u5b89\u88c5\u5e76\u8bbe\u7f6enfs\u548crpcbind\u670d\u52a1\uff0c\u8bbe\u7f6e\u5171\u4eab\u76ee\u5f55\uff0c\u542f\u52a8\u670d\u52a1\uff0c\u5e76\u5728\u5ba2\u6237\u7aef\u4e0a\u8fdb\u884c\u6302\u8f7d\u3002 \u542f\u52a8 rpcbind \u670d\u52a1\u3002 sudo systemctl enable rpcbind sudo systemctl restart rpcbind \u542f\u52a8 nfs \u670d\u52a1\u3002 sudo systemctl enable nfs-server sudo systemctl start nfs-server \u5982\u679c /etc/exports \u6587\u4ef6\u88ab\u4fee\u6539\uff0c\u6211\u4eec\u9700\u8981\u8fd0\u884c\u4e0b\u9762\u7684\u547d\u4ee4\u4f7f\u4e4b\u751f\u6548\u3002 exportfs -ra \u8fd0\u884c\u7ed3\u679c exportfs: /etc/exports [ 1 ] : Neither 'subtree_check' or 'no_subtree_check' specified for export \"*:/nfsdata\" . Assuming default behaviour ( 'no_subtree_check' ) . NOTE: this default has changed since nfs-utils version 1 .0.x \u68c0\u67e5\u5171\u4eab\u76ee\u5f55\u662f\u5426\u5df2\u7ecf\u88ab\u6b63\u786e\u914d\u7f6e\u4e86\u3002 showmount -e \u5982\u679c\u770b\u5230\u4e0b\u9762\u7684\u7ed3\u679c\uff0c\u5219\u8bf4\u660e\u5171\u4eab\u76ee\u5f55\u5df2\u7ecf\u88ab\u6b63\u786e\u914d\u7f6e\u4e86\u3002 Export list for cka002: /nfsdata * 3.\u5b89\u88c5NFS\u5ba2\u6237\u7aef \u5728\u6240\u6709\u8282\u70b9\u4e0a\u5b89\u88c5NFS\u5ba2\u6237\u7aef\u3002 sudo apt-get install -y nfs-common 4.\u9a8c\u8bc1NFS\u670d\u52a1 \u767b\u5f55\u5230\u4efb\u4f55\u4e00\u4e2a\u8282\u70b9\u6765\u9a8c\u8bc1NFS\u670d\u52a1\u662f\u5426\u6b63\u786e\u5de5\u4f5c\uff0c\u4ee5\u53caNFS\u670d\u52a1\u6240\u5171\u4eab\u5230\u76ee\u5f55\u662f\u5426\u53ef\u89c1\u3002 \u767b\u9646\u5230 cka001 \uff0c\u5e76\u68c0\u67e5 cka002 \u7684\u5171\u4eab\u76ee\u5f55\u72b6\u6001\u3002 showmount -e cka002 \u5982\u679c\u5f97\u5230\u7c7b\u4f3c\u4e0b\u9762\u7684\u7ed3\u679c\uff0c\u5219\u8bf4\u660eNFS\u670d\u52a1\u6b63\u5e38\u5de5\u4f5c\uff0c\u5305\u62ec\u5171\u4eab\u76ee\u5f55\u3002 Export list for cka002: /nfsdata * 5.\u6302\u8f7dNFS\u5171\u4eab\u76ee\u5f55 \u6267\u884c\u4e0b\u9762\u547d\u4ee4\uff0c\u6302\u8f7dNFS\u5171\u4eab\u76ee\u5f55\u5230\u4efb\u4f55\u4e00\u4e2a\u975eNFS\u670d\u52a1\u5668\u8282\u70b9\uff0c\u6bd4\u5982 cka001 or cka003 \u3002 mkdir /remote-nfs-dir mount -t nfs cka002:/nfsdata /remote-nfs-dir/ \u6267\u884c\u547d\u4ee4 df -h \u6765\u68c0\u67e5NFS\u6302\u8f7d\u70b9\u662f\u5426\u6b63\u786e\uff0c\u7c7b\u4f3c\u4e0b\u9762\u7684\u7ed3\u679c\u3002 Filesystem Size Used Avail Use% Mounted on cka002:/nfsdata 40G 5 .8G 32G 16 % /remote-nfs-dir \u521b\u5efa PV \u00b6 \u521b\u5efa\u4e00\u4e2a PV mysql-pv \u3002 \u5c06 NFS \u670d\u52a1\u5668 IP \u66ff\u6362\u4e3a\u5b9e\u9645\u7684 IP\uff08\u8fd9\u91cc\u662f \uff09\uff0c\u5b83\u662f\u8fd0\u884c NFS \u670d\u52a1\u5668 cka002 \u7684 IP\u3002 kubectl apply -f - < EOF \u6267\u884c\u4e0b\u9762\u7684\u547d\u4ee4\uff0c\u68c0\u67e5\u521b\u5efa\u7684PV\u3002 kubectl get pv \u8fd0\u884c\u7ed3\u679c NAME CAPACITY ACCESS MODES RECLAIM POLICY STATUS CLAIM STORAGECLASS REASON AGE mysql-pv 1Gi RWO Retain Available nfs 19s \u521b\u5efa PVC \u00b6 \u521b\u5efa PVC mysql-pvc \u5e76\u6307\u5b9a\u5b58\u50a8\u5927\u5c0f\u3001\u8bbf\u95ee\u6a21\u5f0f\u548c\u5b58\u50a8\u7c7b\u3002 PVC mysql-pvc \u5c06\u901a\u8fc7\u5b58\u50a8\u7c7b\u540d\u79f0\u81ea\u52a8\u4e0e PV \u7ed1\u5b9a\u3002 kubectl apply -f - < nfs-provisioner-rbac.yaml < ( cka002 ) \u4e0a\u7684 /nfsdata \u76ee\u5f55\u7684\u5377 nfs-client-root \u3002 \u628a NFS \u670d\u52a1\u5668\u7684 IP \u66ff\u6362\u4e3a\u5b9e\u9645\u7684 IP \u5730\u5740\u5373\u53ef\uff08\u8fd9\u91cc\u7528 \u8868\u793a\uff09\u3002 cat > nfs-provisioner-deployment.yaml < - name: NFS_PATH value: /nfsdata volumes: - name: nfs-client-root nfs: server: path: /nfsdata EOF kubectl apply -f nfs-provisioner-deployment.yaml \u521b\u5efa NFS StorageClass \u00b6 \u521b\u5efa StorageClass nfs-client \uff0c\u5b9a\u4e49 NFS \u5b50\u76ee\u5f55\u5916\u90e8 provisioner \u7684 Kubernetes Storage Class\u3002 \u6267\u884c\u4e0b\u9762\u7684\u547d\u4ee4\u7f16\u8f91 nfs-storageclass.yaml \u6587\u4ef6\u3002 vi nfs-storageclass.yaml \u6dfb\u52a0\u4e0b\u9762\u7684\u4fe1\u606f\u6765\u914d\u7f6e NFS StorageClass\u3002 apiVersion: storage.k8s.io/v1 kind: StorageClass metadata: name: nfs-client annotations: storageclass.kubernetes.io/is-default-class: \"true\" provisioner: k8s-sigs.io/nfs-subdir-external-provisioner parameters: pathPattern: \" ${ .PVC.namespace } / ${ .PVC.annotations.nfs.io/storage-path } \" onDelete: delete \u5e94\u7528\u4e0a\u9762\u7684yaml\u6587\u4ef6\uff0c\u4f7f\u4e4b\u751f\u6548\u3002 kubectl apply -f nfs-storageclass.yaml \u521b\u5efaPVC \u00b6 \u521b\u5efa PVC nfs-pvc-from-sc \u3002 kubectl apply -f - < mysql-with-sc-pvc-7c97d875f8-wkvr9 1/1 Running 0 3m37s 10.244.102.27 cka003 \u6211\u4eec\u73b0\u5728\u6765\u67e5\u770b NFS \u670d\u52a1\u5668 cka002 \u4e0a\u7684\u5171\u4eab\u76ee\u5f55 /nfsdata/ \u3002 ll /nfsdata/ NFS \u670d\u52a1\u5668 cka002 \u4e0a\u7684\u5171\u4eab\u76ee\u5f55 /nfsdata/ \u4e0b\u6709\u4e862\u4e2a\u5b50\u76ee\u5f55\uff0c\u4e0e\u5176\u4ed62\u4e2a\u8282\u70b9\u4e0a\u7684\u76ee\u5f55 /remote-nfs-dir/ \u4e0b\u7684\u5185\u5bb9\u662f\u4e00\u81f4\u3002 drwxrwxrwx 6 systemd-coredump root 4096 Jul 23 23 :35 dev/ drwxr-xr-x 6 systemd-coredump root 4096 Jul 23 22 :29 mysqldata/ \u547d\u540d\u7a7a\u95f4Namespace\u7684\u540d\u79f0\u4f5c\u4e3a\u76ee\u5f55\u540d\u5728 /nfsdata/ \u76ee\u5f55\u4e0b\u7528\u4e8e\u6302\u8f7d\u5230 Pod \u4e2d\u3002 \u9ed8\u8ba4\u60c5\u51b5\u4e0b\uff0c\u547d\u540d\u7a7a\u95f4Namespace\u540d\u79f0\u5c06\u7528\u4e8e\u6302\u8f7d\u70b9\u3002 \u5982\u679c\u6211\u4eec\u60f3\u8981\u4f7f\u7528\u81ea\u5b9a\u4e49\u7684\u6587\u4ef6\u5939\u6765\u4ee3\u66ff\uff0c\u6211\u4eec\u9700\u8981\u58f0\u660e\u4e00\u4e2a nfs.io/storage-path \u6ce8\u91ca\uff0c\u4f8b\u5982\u4e0b\u9762\u7684\u4f8b\u5b50\u3002 \u5728\u547d\u540d\u7a7a\u95f4 kube-system \u4e0a\u521b\u5efa PVC test-claim \uff0c\u5e76\u6d88\u8d39 nfs-client \u5377\u3002 kubectl apply -f - < ..data/password lrwxrwxrwx 1 root root 15 Jul 23 16 :30 username -> ..data/username \u800c\u4e14\u6211\u4eec\u53ef\u4ee5\u770b\u5230\u8fd92\u4e2a\u6570\u636e\u5143\u7d20\uff08 username \u548c password \uff09\u7684\u5185\u5bb9\u5c31\u662f\u6211\u4eec\u9884\u5148\u5b9a\u4e49\u7684\u3002 / # cat /tmp/secret/username admin / # cat /tmp/secret/password 123456 \u62d3\u5c55\u6848\u4f8b \u00b6 \u591a\u79cd\u65b9\u6cd5\u521b\u5efaConfigMap \u00b6 \u6211\u4eec\u53ef\u4ee5\u901a\u8fc7\u6587\u4ef6\u3001\u76ee\u5f55\u3001\u6216\u8005\u503c\u6765\u521b\u5efaConfigMap\u3002 \u4e0b\u9762\u6211\u4eec\u521b\u5efaConfigMap colors \uff0c\u5305\u542b\uff1a \u56db\u4e2a\u6587\u4ef6\uff0c\u6587\u4ef6\u540d\u662f\u56db\u4e2a\u989c\u8272\u3002 \u4e00\u4e2a\u6587\u4ef6\uff0c\u6587\u4ef6\u540d\u662f\u6700\u559c\u6b22\u7684\u989c\u8272\u3002 mkdir configmap cd configmap mkdir primary echo c > primary/cyan echo m > primary/magenta echo y > primary/yellow echo k > primary/black echo \"known as key\" >> primary/black echo blue > favorite \u6267\u884c\u547d\u4ee4 tree configmap \uff0c\u53ef\u4ee5\u770b\u5230\u7c7b\u4f3c\u4e0b\u9762\u7684\u6587\u4ef6\u76ee\u5f55\u7ed3\u6784\u3002 configmap \u251c\u2500\u2500 favorite \u2514\u2500\u2500 primary \u251c\u2500\u2500 black \u251c\u2500\u2500 cyan \u251c\u2500\u2500 magenta \u2514\u2500\u2500 yellow \u521b\u5efa\u4e00\u4e2a ConfigMap\uff0c\u5f15\u7528\u4e0a\u9762\u6211\u4eec\u521b\u5efa\u7684\u6587\u4ef6\u3002\u786e\u4fdd\u6211\u4eec\u73b0\u5728\u5728\u8def\u5f84 ~/configmap \u4e0b\u3002 kubectl create configmap colors \\ --from-literal = text = black \\ --from-file = ./favorite \\ --from-file = ./primary/ \u67e5\u770bConfigMap colors \u7684\u5185\u5bb9\u3002 kubectl get configmap colors -o yaml \u8fd0\u884c\u7ed3\u679c\uff1a apiVersion: v1 data: black: | k known as key cyan: | c favorite: | blue magenta: | m text: black yellow: | y kind: ConfigMap metadata: creationTimestamp: \"2022-07-12T16:38:27Z\" name: colors namespace: dev resourceVersion: \"2377258\" uid: d5ab133f-5e4d-41d4-bc9e-2bbb22a872a1 \u901a\u8fc7ConfigMap\u8bbe\u5b9a\u73af\u5883\u53d8\u91cf \u00b6 \u7ee7\u7eed\u4e0a\u9762\u7684\u4f8b\u5b50\uff0c\u73b0\u5728\u6211\u4eec\u51c6\u5907\u521b\u5efa\u4e00\u4e2a\u540d\u4e3a pod-configmap-env \u7684Pod\uff0c\u8bbe\u7f6e\u73af\u5883\u53d8\u91cf ilike \u5e76\u4eceConfigMap colors \u4e2d\u5206\u914d\u503c favorite \u3002 kubectl apply -f - << EOF apiVersion: v1 kind: Pod metadata: name: pod-configmap-env spec: containers: - name: nginx image: nginx env: - name: ilike valueFrom: configMapKeyRef: name: colors key: favorite EOF \u8fde\u63a5\u5e76\u8fdb\u5165Pod pod-configmap-env \u5185\u90e8\u3002 kubectl exec -it pod-configmap-env -- bash \u9a8c\u8bc1\u73af\u5883\u53d8\u91cf ilike \u7684\u503c\u662f blue \uff0c\u8fd9\u662f ConfigMap colors \u7684 favorite \u503c\u3002 root@pod-configmap-env:/# echo $ilike blue \u6211\u4eec\u8fd8\u53ef\u4ee5\u4f7f\u7528 ConfigMap \u7684\u6240\u6709\u952e\u503c\u5bf9\u6765\u8bbe\u7f6e Pod \u7684\u73af\u5883\u53d8\u91cf\u3002 kubectl apply -f - << EOF apiVersion: v1 kind: Pod metadata: name: pod-configmap-env-2 spec: containers: - name: nginx image: nginx envFrom: - configMapRef: name: colors EOF \u8fde\u63a5\u5e76\u8fdb\u5165Pod pod-configmap-env-2 \u5185\u90e8\u3002 kubectl exec -it pod-configmap-env-2 -- bash \u9a8c\u8bc1\u73af\u5883\u53d8\u91cf\u7684\u503c\u662f\u6211\u4eec\u5728ConfigMap colors \u6240\u5b9a\u4e49\u7684\u952e\u503c\u5bf9\u3002 root@pod-configmap-env-2:/# echo $black k known as key root@pod-configmap-env-2:/# echo $cyan c root@pod-configmap-env-2:/# echo $favorite blue","title":"Persistence"},{"location":"k8s/cka_cn/foundamentals/persistence/#cka17persistence","text":"","title":"CKA\u81ea\u5b66\u7b14\u8bb017:Persistence"},{"location":"k8s/cka_cn/foundamentals/persistence/#_1","text":"\u6f14\u793a\u573a\u666f\uff1a \u521b\u5efa\u4e00\u4e2a\u7c7b\u578b\u4e3a emptyDir \u7684\u5377\u6765\u521b\u5efa Pod\uff0cPod \u4e2d\u7684\u5bb9\u5668\u5c06\u4f1a\u6302\u8f7d\u5728\u8fd0\u884c\u8282\u70b9\u4e0a\u7684\u9ed8\u8ba4\u76ee\u5f55 /var/lib/kubelet/pods/ \u4e2d\u3002 \u521b\u5efa\u4e00\u4e2a\u7c7b\u578b\u4e3a hostPath \u7684\u5377\u6765\u521b\u5efa Deployment\uff0cDeployment \u4e2d\u7684\u5bb9\u5668\u5c06\u4f1a\u6302\u8f7d\u5728\u8fd0\u884c\u8282\u70b9\u4e0a\u5b9a\u4e49\u7684\u76ee\u5f55 hostPath: \u4e2d\u3002 \u521b\u5efa PV \u548c PVC\uff1a \u8bbe\u7f6e NFS \u670d\u52a1\u5668\u5e76\u5171\u4eab /nfsdata/ \u76ee\u5f55\u3002 \u521b\u5efa PV mysql-pv \u5e76\u6620\u5c04\u5230\u5171\u4eab\u76ee\u5f55 /nfsdata/ \uff0c\u540c\u65f6\u8bbe\u7f6e StorageClassName \u4e3a nfs \u3002 \u521b\u5efa PVC mysql-pvc \u5e76\u6620\u5c04\u5230 StorageClassName \u4e3a nfs \u7684 PV \u4e0a\u3002 \u521b\u5efa Deployment mysql \u6765\u4f7f\u7528 PVC mysql-pvc \u3002 \u521b\u5efa StorageClass\uff1a \u521b\u5efa ServiceAccount nfs-client-provisioner \u3002 \u521b\u5efa ClusterRole nfs-client-provisioner-runner \u548c Role leader-locking-nfs-client-provisioner \uff0c\u5e76\u5c06\u5176\u7ed1\u5b9a\u5230 ServiceAccount \u4e0a\uff0c\u4ee5\u4fbf\u8be5 ServiceAccount \u53ef\u4ee5\u64cd\u4f5c\u4e0b\u4e00\u6b65\u4e2d\u521b\u5efa\u7684 Deployment\u3002 \u521b\u5efa Deployment nfs-client-provisioner \u6765\u6dfb\u52a0\u8fde\u63a5\u5230 NFS \u670d\u52a1\u5668\u7684\u4fe1\u606f\uff0c\u4f8b\u5982 PROVISIONER_NAME \u662f k8s-sigs.io/nfs-subdir-external-provisioner \u3002 \u521b\u5efa StorageClass nfs-client \u5e76\u94fe\u63a5\u5230 provisioner: k8s-sigs.io/nfs-subdir-external-provisioner \uff0c\u76f8\u5173\u7684 PV \u4f1a\u81ea\u52a8\u521b\u5efa\u3002 \u521b\u5efa PVC nfs-pvc-from-sc \u5e76\u6620\u5c04\u5230 StorageClass nfs-client \u4e0a\u7684 PV\u3002 \u914d\u7f6eConfiguration\uff1a \u521b\u5efa\u4e00\u4e2a ConfigMap \u4ee5\u5305\u542b\u6587\u4ef6\u7684\u5185\u5bb9\uff0c\u5e76\u5c06\u6b64 ConfigMap \u6302\u8f7d\u5230 Pod \u4e2d\u7684\u7279\u5b9a\u6587\u4ef6\u4e2d\u3002 \u521b\u5efa\u4e00\u4e2a ConfigMap \u6765\u5305\u542b\u7528\u6237\u540d\u548c\u5bc6\u7801\uff0c\u5e76\u5728 Pod \u4e2d\u4f7f\u7528\u5b83\u4eec\u3002 \u5728 Pod \u4e2d\u5c06 ConfigMap \u7528\u4f5c\u73af\u5883\u53d8\u91cf\u3002 \u5efa\u8bae\uff1a \u9996\u5148\u5220\u9664 PVC\uff0c\u7136\u540e\u518d\u5220\u9664 PV\u3002 \u5982\u679c\u5220\u9664 PVC \u65f6\u9047\u5230 Terminating \u72b6\u6001\uff0c\u4f7f\u7528 kubectl edit pvc \u547d\u4ee4\uff0c\u7136\u540e\u5220\u9664 finalize: \u3002","title":"\u6458\u8981"},{"location":"k8s/cka_cn/foundamentals/persistence/#emptydir","text":"\u521b\u5efa\u4e00\u4e2a\u540d\u4e3a hello-producer \u7684 Pod\uff0c\u5e76\u4f7f\u7528 emptyDir \u7c7b\u578b\u7684 Volume\u3002 cat > pod-emptydir.yaml < /producer_dir/hello; sleep 30000 volumes: - name: shared-volume emptyDir: {} EOF kubectl apply -f pod-emptydir.yaml \u67e5\u770bPod hello-producer \u7684\u72b6\u6001\u3002 kubectl get pod hello-producer -owide Pod hello-producer \u8fd0\u884c\u5728\u8282\u70b9node cka003 \u4e0a\u3002 NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES hello-producer 1/1 Running 0 6s 10.244.102.24 cka003 \u767b\u5f55 cka003 \uff0c\u56e0\u4e3a Pod hello-producer \u6b63\u5728\u8be5\u8282\u70b9\u4e0a\u8fd0\u884c\u3002 \u4e3a crictl \u547d\u4ee4\u8bbe\u7f6e\u73af\u5883\u53d8\u91cf CONTAINER_RUNTIME_ENDPOINT \u3002\u5efa\u8bae\u5728\u6240\u6709\u8282\u70b9\u4e0a\u6267\u884c\u76f8\u540c\u7684\u64cd\u4f5c\u3002 export CONTAINER_RUNTIME_ENDPOINT = unix:///run/containerd/containerd.sock \u8fd0\u884c\u547d\u4ee4 crictl ps \u6765\u83b7\u53d6 Pod hello-producer \u7684\u5bb9\u5668 ID\u3002 crictl ps | grep hello-producer \u5bb9\u5668 producer \u7684ID\u662f 05f5e1bb6a1bb \u3002 CONTAINER IMAGE CREATED STATE NAME ATTEMPT POD ID POD 50058afb3cba5 62aedd01bd852 About an hour ago Running producer 0 e6953bd4833a7 hello-producer \u8fd0\u884c\u547d\u4ee4 crictl inspect \uff0c\u83b7\u53d6\u5df2\u6302\u8f7d\u7684 shared-volume \u7684\u8def\u5f84\uff0c\u5b83\u662f emptyDir \u7c7b\u578b\u7684\u3002 crictl inspect 50058afb3cba5 | grep source | grep empty \u8fd0\u884c\u7ed3\u679c \"source\": \"/var/lib/kubelet/pods/d7424f86-534a-48f9-9001-9d2a6e822b12/volumes/kubernetes.io~empty-dir/shared-volume\", \u4fee\u6539\u8def\u5f84\u4e3a\u4e0a\u9762\u83b7\u53d6\u5230\u7684 shared-volume \u7684\u6302\u8f7d\u8def\u5f84\u3002\u7136\u540e\u6211\u4eec\u4f1a\u770b\u5230\u6587\u4ef6 hello \u4e2d\u7684\u5185\u5bb9 hello world \u3002 cd /var/lib/kubelet/pods/d7424f86-534a-48f9-9001-9d2a6e822b12/volumes/kubernetes.io~empty-dir/shared-volume cat hello Pod\u5185\u7684\u8def\u5f84 /producer_dir \u88ab\u6302\u8f7d\u5230\u4e86\u672c\u5730\u5bbf\u4e3b\u673a\u8def\u5f84 /var/lib/kubelet/pods/d7424f86-534a-48f9-9001-9d2a6e822b12/volumes/kubernetes.io~empty-dir/shared-volume \u3002 \u6211\u4eec\u5728Pod\u5185\u521b\u5efa\u7684\u6587\u4ef6 /producer_dir/hello \u5b9e\u9645\u4e0a\u5728\u5bbf\u4e3b\u673a\u672c\u5730\u8def\u5f84\u4e2d\u3002 \u8ba9\u6211\u4eec\u5220\u9664\u5bb9\u5668 producer \uff0c\u5bb9\u5668 producer \u5c06\u4ee5\u65b0\u7684\u5bb9\u5668ID\u91cd\u65b0\u542f\u52a8\uff0c\u800c\u6587\u4ef6 hello \u4ecd\u5c06\u5b58\u5728\u3002 crictl ps crictl stop crictl rm \u73b0\u5728\u5220\u9664Pod hello-producer \uff0c\u5bb9\u5668 producer \u4f1a\u88ab\u5220\u9664\uff0c\u6587\u4ef6 hello \u4e5f\u4f1a\u88ab\u5220\u9664\u3002 kubectl delete pod hello-producer","title":"emptyDir"},{"location":"k8s/cka_cn/foundamentals/persistence/#hostpath","text":"\u5e94\u7528\u4ee5\u4e0b yaml \u6587\u4ef6\u521b\u5efa\u4e00\u4e2a MySQL Pod \u5e76\u6302\u8f7d\u4e00\u4e2a hostPath \u3002 \u5c06\u4e3b\u673a\u76ee\u5f55 /tmp/mysql \u6302\u8f7d\u5230 Pod \u76ee\u5f55 /var/lib/mysql \u3002 \u5728\u672c\u5730\u68c0\u67e5\u662f\u5426\u5b58\u5728\u76ee\u5f55 /tmp/mysql \uff0c\u5982\u679c\u4e0d\u5b58\u5728\uff0c\u5219\u6267\u884c\u547d\u4ee4 mkdir /tmp/mysql \u521b\u5efa\u5b83\u3002 cat > mysql-hostpath.yaml < cka003 \u5728MySQL Pod\u8fd0\u884c\u7684\u8282\u70b9\u767b\u9646\u8fdb\u5165pod\u5185\u90e8\u3002 kubectl exec -it -- bash \u5728 Pod \u4e2d\uff0c\u8fdb\u5165 /var/lib/mysql \u76ee\u5f55\uff0c\u8be5\u76ee\u5f55\u4e2d\u7684\u6240\u6709\u6587\u4ef6\u90fd\u4e0e\u8282\u70b9 cka003 \u4e0a /tmp/mysql \u76ee\u5f55\u4e2d\u7684\u6240\u6709\u6587\u4ef6\u76f8\u540c\u3002 \u8fde\u63a5\u5230 Pod \u4e2d\u7684\u6570\u636e\u5e93\u3002 mysql -h 127 .0.0.1 -uroot -ppassword \u6267\u884c\u4e0b\u9762\u547d\u4ee4\u5bf9\u6570\u636e\u5e93\u8fdb\u884c\u7b80\u5355\u7684\u64cd\u4f5c\u3002 mysql> show databases ; mysql> connect mysql ; mysql> show tables ; mysql> exit","title":"hostPath"},{"location":"k8s/cka_cn/foundamentals/persistence/#pvpvc","text":"\u4e0b\u9762\u7684\u6f14\u793a\u4e2d\uff0c\u6211\u4eec\u5c06\u4f7f\u7528NFS\u4f5c\u4e3a\u540e\u7aef\u5b58\u50a8\u6765\u6f14\u793a\u5982\u4f55\u90e8\u7f72PV\u548cPVC\u3002","title":"PV\u548cPVC"},{"location":"k8s/cka_cn/foundamentals/persistence/#nfs","text":"\u5b89\u88c5nfs-kernel-server \u767b\u5f55\u5230\u8282\u70b9 cka002 \u3002\u914d\u7f6eWorker cka002 \u6210\u4e3aNFS\u670d\u52a1\u5668\u3002 sudo apt-get install -y nfs-kernel-server 2.\u914d\u7f6e\u5171\u4eab\u76ee\u5f55 \u521b\u5efa\u5171\u4eab\u6587\u4ef6\u5939\u3002 mkdir /nfsdata \u7f16\u8f91\u6587\u4ef6 /etc/exports \uff0c\u6dfb\u52a0\u4e00\u884c /nfsdata *(rw,sync,no_root_squash) \u3002 cat >> /etc/exports << EOF /nfsdata *(rw,sync,no_root_squash) EOF \u6709\u8bb8\u591a\u4e0d\u540c\u7684NFS\u5171\u4eab\u9009\u9879\uff0c\u4f8b\u5982\uff1a * \uff1a\u5bf9\u6240\u6709IP\u6216\u7279\u5b9aIP\u53ef\u8bbf\u95ee\u3002 rw \uff1a\u4f5c\u4e3a\u8bfb\u5199\u5171\u4eab\u3002\u8bf7\u6ce8\u610f\uff0c\u6b63\u5e38\u7684Linux\u6743\u9650\u4ecd\u7136\u9002\u7528\u3002\uff08\u8bf7\u6ce8\u610f\uff0c\u8fd9\u662f\u9ed8\u8ba4\u9009\u9879\u3002\uff09 ro \uff1a\u4f5c\u4e3a\u53ea\u8bfb\u5171\u4eab\u3002 sync \uff1a\u6587\u4ef6\u6570\u636e\u66f4\u6539\u4f1a\u7acb\u5373\u5199\u5165\u78c1\u76d8\uff0c\u8fd9\u4f1a\u5f71\u54cd\u6027\u80fd\uff0c\u4f46\u4e0d\u592a\u53ef\u80fd\u5bfc\u81f4\u6570\u636e\u4e22\u5931\u3002\u5728\u67d0\u4e9b\u53d1\u884c\u7248\u4e0a\uff0c\u8fd9\u662f\u9ed8\u8ba4\u9009\u9879\u3002 async \uff1a\u4e0esync\u76f8\u53cd\uff0c\u6587\u4ef6\u6570\u636e\u66f4\u6539\u6700\u521d\u5199\u5165\u5185\u5b58\u3002\u8fd9\u63d0\u9ad8\u4e86\u6027\u80fd\uff0c\u4f46\u66f4\u5bb9\u6613\u5bfc\u81f4\u6570\u636e\u4e22\u5931\u3002\u5728\u67d0\u4e9b\u53d1\u884c\u7248\u4e0a\uff0c\u8fd9\u662f\u9ed8\u8ba4\u9009\u9879\u3002 root_squash \uff1a\u5c06NFS\u5ba2\u6237\u7aef\u7684root\u7528\u6237\u548c\u7ec4\u5e10\u6237\u6620\u5c04\u5230\u533f\u540d\u5e10\u6237\uff0c\u901a\u5e38\u662fnobody\u5e10\u6237\u6216nfsnobody\u5e10\u6237\u3002\u6709\u5173\u66f4\u591a\u8be6\u7ec6\u4fe1\u606f\uff0c\u8bf7\u53c2\u89c1\u672c\u6587\u540e\u7eed\u7684\u201c\u7528\u6237ID\u6620\u5c04\u201d\u3002\uff08\u8bf7\u6ce8\u610f\uff0c\u8fd9\u662f\u9ed8\u8ba4\u9009\u9879\u3002\uff09 no_root_squash \uff1a\u5c06NFS\u5ba2\u6237\u7aef\u7684root\u7528\u6237\u548c\u7ec4\u5e10\u6237\u6620\u5c04\u5230\u672c\u5730root\u548c\u7ec4\u5e10\u6237\u3002 \u6211\u4eec\u5c06\u4f7f\u7528\u57fa\u4e8eLinux\u670d\u52a1\u5668\u4e4b\u95f4\u7684 nfs \u548c rpcbind \u670d\u52a1\u7684\u65e0\u5bc6\u7801\u8fdc\u7a0b\u6302\u8f7d\uff0c\u800c\u4e0d\u662f\u57fa\u4e8e smb \u670d\u52a1\u3002\u9996\u5148\uff0c\u8fd9\u4e24\u53f0\u670d\u52a1\u5668\u5fc5\u987b\u6388\u6743\u3001\u5b89\u88c5\u5e76\u8bbe\u7f6enfs\u548crpcbind\u670d\u52a1\uff0c\u8bbe\u7f6e\u5171\u4eab\u76ee\u5f55\uff0c\u542f\u52a8\u670d\u52a1\uff0c\u5e76\u5728\u5ba2\u6237\u7aef\u4e0a\u8fdb\u884c\u6302\u8f7d\u3002 \u542f\u52a8 rpcbind \u670d\u52a1\u3002 sudo systemctl enable rpcbind sudo systemctl restart rpcbind \u542f\u52a8 nfs \u670d\u52a1\u3002 sudo systemctl enable nfs-server sudo systemctl start nfs-server \u5982\u679c /etc/exports \u6587\u4ef6\u88ab\u4fee\u6539\uff0c\u6211\u4eec\u9700\u8981\u8fd0\u884c\u4e0b\u9762\u7684\u547d\u4ee4\u4f7f\u4e4b\u751f\u6548\u3002 exportfs -ra \u8fd0\u884c\u7ed3\u679c exportfs: /etc/exports [ 1 ] : Neither 'subtree_check' or 'no_subtree_check' specified for export \"*:/nfsdata\" . Assuming default behaviour ( 'no_subtree_check' ) . NOTE: this default has changed since nfs-utils version 1 .0.x \u68c0\u67e5\u5171\u4eab\u76ee\u5f55\u662f\u5426\u5df2\u7ecf\u88ab\u6b63\u786e\u914d\u7f6e\u4e86\u3002 showmount -e \u5982\u679c\u770b\u5230\u4e0b\u9762\u7684\u7ed3\u679c\uff0c\u5219\u8bf4\u660e\u5171\u4eab\u76ee\u5f55\u5df2\u7ecf\u88ab\u6b63\u786e\u914d\u7f6e\u4e86\u3002 Export list for cka002: /nfsdata * 3.\u5b89\u88c5NFS\u5ba2\u6237\u7aef \u5728\u6240\u6709\u8282\u70b9\u4e0a\u5b89\u88c5NFS\u5ba2\u6237\u7aef\u3002 sudo apt-get install -y nfs-common 4.\u9a8c\u8bc1NFS\u670d\u52a1 \u767b\u5f55\u5230\u4efb\u4f55\u4e00\u4e2a\u8282\u70b9\u6765\u9a8c\u8bc1NFS\u670d\u52a1\u662f\u5426\u6b63\u786e\u5de5\u4f5c\uff0c\u4ee5\u53caNFS\u670d\u52a1\u6240\u5171\u4eab\u5230\u76ee\u5f55\u662f\u5426\u53ef\u89c1\u3002 \u767b\u9646\u5230 cka001 \uff0c\u5e76\u68c0\u67e5 cka002 \u7684\u5171\u4eab\u76ee\u5f55\u72b6\u6001\u3002 showmount -e cka002 \u5982\u679c\u5f97\u5230\u7c7b\u4f3c\u4e0b\u9762\u7684\u7ed3\u679c\uff0c\u5219\u8bf4\u660eNFS\u670d\u52a1\u6b63\u5e38\u5de5\u4f5c\uff0c\u5305\u62ec\u5171\u4eab\u76ee\u5f55\u3002 Export list for cka002: /nfsdata * 5.\u6302\u8f7dNFS\u5171\u4eab\u76ee\u5f55 \u6267\u884c\u4e0b\u9762\u547d\u4ee4\uff0c\u6302\u8f7dNFS\u5171\u4eab\u76ee\u5f55\u5230\u4efb\u4f55\u4e00\u4e2a\u975eNFS\u670d\u52a1\u5668\u8282\u70b9\uff0c\u6bd4\u5982 cka001 or cka003 \u3002 mkdir /remote-nfs-dir mount -t nfs cka002:/nfsdata /remote-nfs-dir/ \u6267\u884c\u547d\u4ee4 df -h \u6765\u68c0\u67e5NFS\u6302\u8f7d\u70b9\u662f\u5426\u6b63\u786e\uff0c\u7c7b\u4f3c\u4e0b\u9762\u7684\u7ed3\u679c\u3002 Filesystem Size Used Avail Use% Mounted on cka002:/nfsdata 40G 5 .8G 32G 16 % /remote-nfs-dir","title":"\u8bbe\u7f6eNFS\u5171\u4eab"},{"location":"k8s/cka_cn/foundamentals/persistence/#pv","text":"\u521b\u5efa\u4e00\u4e2a PV mysql-pv \u3002 \u5c06 NFS \u670d\u52a1\u5668 IP \u66ff\u6362\u4e3a\u5b9e\u9645\u7684 IP\uff08\u8fd9\u91cc\u662f \uff09\uff0c\u5b83\u662f\u8fd0\u884c NFS \u670d\u52a1\u5668 cka002 \u7684 IP\u3002 kubectl apply -f - < EOF \u6267\u884c\u4e0b\u9762\u7684\u547d\u4ee4\uff0c\u68c0\u67e5\u521b\u5efa\u7684PV\u3002 kubectl get pv \u8fd0\u884c\u7ed3\u679c NAME CAPACITY ACCESS MODES RECLAIM POLICY STATUS CLAIM STORAGECLASS REASON AGE mysql-pv 1Gi RWO Retain Available nfs 19s","title":"\u521b\u5efa PV"},{"location":"k8s/cka_cn/foundamentals/persistence/#pvc","text":"\u521b\u5efa PVC mysql-pvc \u5e76\u6307\u5b9a\u5b58\u50a8\u5927\u5c0f\u3001\u8bbf\u95ee\u6a21\u5f0f\u548c\u5b58\u50a8\u7c7b\u3002 PVC mysql-pvc \u5c06\u901a\u8fc7\u5b58\u50a8\u7c7b\u540d\u79f0\u81ea\u52a8\u4e0e PV \u7ed1\u5b9a\u3002 kubectl apply -f - < nfs-provisioner-rbac.yaml < ( cka002 ) \u4e0a\u7684 /nfsdata \u76ee\u5f55\u7684\u5377 nfs-client-root \u3002 \u628a NFS \u670d\u52a1\u5668\u7684 IP \u66ff\u6362\u4e3a\u5b9e\u9645\u7684 IP \u5730\u5740\u5373\u53ef\uff08\u8fd9\u91cc\u7528 \u8868\u793a\uff09\u3002 cat > nfs-provisioner-deployment.yaml < - name: NFS_PATH value: /nfsdata volumes: - name: nfs-client-root nfs: server: path: /nfsdata EOF kubectl apply -f nfs-provisioner-deployment.yaml","title":"\u521b\u5efaProvisioner\u7684Deloyment"},{"location":"k8s/cka_cn/foundamentals/persistence/#nfs-storageclass","text":"\u521b\u5efa StorageClass nfs-client \uff0c\u5b9a\u4e49 NFS \u5b50\u76ee\u5f55\u5916\u90e8 provisioner \u7684 Kubernetes Storage Class\u3002 \u6267\u884c\u4e0b\u9762\u7684\u547d\u4ee4\u7f16\u8f91 nfs-storageclass.yaml \u6587\u4ef6\u3002 vi nfs-storageclass.yaml \u6dfb\u52a0\u4e0b\u9762\u7684\u4fe1\u606f\u6765\u914d\u7f6e NFS StorageClass\u3002 apiVersion: storage.k8s.io/v1 kind: StorageClass metadata: name: nfs-client annotations: storageclass.kubernetes.io/is-default-class: \"true\" provisioner: k8s-sigs.io/nfs-subdir-external-provisioner parameters: pathPattern: \" ${ .PVC.namespace } / ${ .PVC.annotations.nfs.io/storage-path } \" onDelete: delete \u5e94\u7528\u4e0a\u9762\u7684yaml\u6587\u4ef6\uff0c\u4f7f\u4e4b\u751f\u6548\u3002 kubectl apply -f nfs-storageclass.yaml","title":"\u521b\u5efa NFS StorageClass"},{"location":"k8s/cka_cn/foundamentals/persistence/#pvc_2","text":"\u521b\u5efa PVC nfs-pvc-from-sc \u3002 kubectl apply -f - < mysql-with-sc-pvc-7c97d875f8-wkvr9 1/1 Running 0 3m37s 10.244.102.27 cka003 \u6211\u4eec\u73b0\u5728\u6765\u67e5\u770b NFS \u670d\u52a1\u5668 cka002 \u4e0a\u7684\u5171\u4eab\u76ee\u5f55 /nfsdata/ \u3002 ll /nfsdata/ NFS \u670d\u52a1\u5668 cka002 \u4e0a\u7684\u5171\u4eab\u76ee\u5f55 /nfsdata/ \u4e0b\u6709\u4e862\u4e2a\u5b50\u76ee\u5f55\uff0c\u4e0e\u5176\u4ed62\u4e2a\u8282\u70b9\u4e0a\u7684\u76ee\u5f55 /remote-nfs-dir/ \u4e0b\u7684\u5185\u5bb9\u662f\u4e00\u81f4\u3002 drwxrwxrwx 6 systemd-coredump root 4096 Jul 23 23 :35 dev/ drwxr-xr-x 6 systemd-coredump root 4096 Jul 23 22 :29 mysqldata/ \u547d\u540d\u7a7a\u95f4Namespace\u7684\u540d\u79f0\u4f5c\u4e3a\u76ee\u5f55\u540d\u5728 /nfsdata/ \u76ee\u5f55\u4e0b\u7528\u4e8e\u6302\u8f7d\u5230 Pod \u4e2d\u3002 \u9ed8\u8ba4\u60c5\u51b5\u4e0b\uff0c\u547d\u540d\u7a7a\u95f4Namespace\u540d\u79f0\u5c06\u7528\u4e8e\u6302\u8f7d\u70b9\u3002 \u5982\u679c\u6211\u4eec\u60f3\u8981\u4f7f\u7528\u81ea\u5b9a\u4e49\u7684\u6587\u4ef6\u5939\u6765\u4ee3\u66ff\uff0c\u6211\u4eec\u9700\u8981\u58f0\u660e\u4e00\u4e2a nfs.io/storage-path \u6ce8\u91ca\uff0c\u4f8b\u5982\u4e0b\u9762\u7684\u4f8b\u5b50\u3002 \u5728\u547d\u540d\u7a7a\u95f4 kube-system \u4e0a\u521b\u5efa PVC test-claim \uff0c\u5e76\u6d88\u8d39 nfs-client \u5377\u3002 kubectl apply -f - < ..data/password lrwxrwxrwx 1 root root 15 Jul 23 16 :30 username -> ..data/username \u800c\u4e14\u6211\u4eec\u53ef\u4ee5\u770b\u5230\u8fd92\u4e2a\u6570\u636e\u5143\u7d20\uff08 username \u548c password \uff09\u7684\u5185\u5bb9\u5c31\u662f\u6211\u4eec\u9884\u5148\u5b9a\u4e49\u7684\u3002 / # cat /tmp/secret/username admin / # cat /tmp/secret/password 123456","title":"Secret"},{"location":"k8s/cka_cn/foundamentals/persistence/#_2","text":"","title":"\u62d3\u5c55\u6848\u4f8b"},{"location":"k8s/cka_cn/foundamentals/persistence/#configmap_1","text":"\u6211\u4eec\u53ef\u4ee5\u901a\u8fc7\u6587\u4ef6\u3001\u76ee\u5f55\u3001\u6216\u8005\u503c\u6765\u521b\u5efaConfigMap\u3002 \u4e0b\u9762\u6211\u4eec\u521b\u5efaConfigMap colors \uff0c\u5305\u542b\uff1a \u56db\u4e2a\u6587\u4ef6\uff0c\u6587\u4ef6\u540d\u662f\u56db\u4e2a\u989c\u8272\u3002 \u4e00\u4e2a\u6587\u4ef6\uff0c\u6587\u4ef6\u540d\u662f\u6700\u559c\u6b22\u7684\u989c\u8272\u3002 mkdir configmap cd configmap mkdir primary echo c > primary/cyan echo m > primary/magenta echo y > primary/yellow echo k > primary/black echo \"known as key\" >> primary/black echo blue > favorite \u6267\u884c\u547d\u4ee4 tree configmap \uff0c\u53ef\u4ee5\u770b\u5230\u7c7b\u4f3c\u4e0b\u9762\u7684\u6587\u4ef6\u76ee\u5f55\u7ed3\u6784\u3002 configmap \u251c\u2500\u2500 favorite \u2514\u2500\u2500 primary \u251c\u2500\u2500 black \u251c\u2500\u2500 cyan \u251c\u2500\u2500 magenta \u2514\u2500\u2500 yellow \u521b\u5efa\u4e00\u4e2a ConfigMap\uff0c\u5f15\u7528\u4e0a\u9762\u6211\u4eec\u521b\u5efa\u7684\u6587\u4ef6\u3002\u786e\u4fdd\u6211\u4eec\u73b0\u5728\u5728\u8def\u5f84 ~/configmap \u4e0b\u3002 kubectl create configmap colors \\ --from-literal = text = black \\ --from-file = ./favorite \\ --from-file = ./primary/ \u67e5\u770bConfigMap colors \u7684\u5185\u5bb9\u3002 kubectl get configmap colors -o yaml \u8fd0\u884c\u7ed3\u679c\uff1a apiVersion: v1 data: black: | k known as key cyan: | c favorite: | blue magenta: | m text: black yellow: | y kind: ConfigMap metadata: creationTimestamp: \"2022-07-12T16:38:27Z\" name: colors namespace: dev resourceVersion: \"2377258\" uid: d5ab133f-5e4d-41d4-bc9e-2bbb22a872a1","title":"\u591a\u79cd\u65b9\u6cd5\u521b\u5efaConfigMap"},{"location":"k8s/cka_cn/foundamentals/persistence/#configmap_2","text":"\u7ee7\u7eed\u4e0a\u9762\u7684\u4f8b\u5b50\uff0c\u73b0\u5728\u6211\u4eec\u51c6\u5907\u521b\u5efa\u4e00\u4e2a\u540d\u4e3a pod-configmap-env \u7684Pod\uff0c\u8bbe\u7f6e\u73af\u5883\u53d8\u91cf ilike \u5e76\u4eceConfigMap colors \u4e2d\u5206\u914d\u503c favorite \u3002 kubectl apply -f - << EOF apiVersion: v1 kind: Pod metadata: name: pod-configmap-env spec: containers: - name: nginx image: nginx env: - name: ilike valueFrom: configMapKeyRef: name: colors key: favorite EOF \u8fde\u63a5\u5e76\u8fdb\u5165Pod pod-configmap-env \u5185\u90e8\u3002 kubectl exec -it pod-configmap-env -- bash \u9a8c\u8bc1\u73af\u5883\u53d8\u91cf ilike \u7684\u503c\u662f blue \uff0c\u8fd9\u662f ConfigMap colors \u7684 favorite \u503c\u3002 root@pod-configmap-env:/# echo $ilike blue \u6211\u4eec\u8fd8\u53ef\u4ee5\u4f7f\u7528 ConfigMap \u7684\u6240\u6709\u952e\u503c\u5bf9\u6765\u8bbe\u7f6e Pod \u7684\u73af\u5883\u53d8\u91cf\u3002 kubectl apply -f - << EOF apiVersion: v1 kind: Pod metadata: name: pod-configmap-env-2 spec: containers: - name: nginx image: nginx envFrom: - configMapRef: name: colors EOF \u8fde\u63a5\u5e76\u8fdb\u5165Pod pod-configmap-env-2 \u5185\u90e8\u3002 kubectl exec -it pod-configmap-env-2 -- bash \u9a8c\u8bc1\u73af\u5883\u53d8\u91cf\u7684\u503c\u662f\u6211\u4eec\u5728ConfigMap colors \u6240\u5b9a\u4e49\u7684\u952e\u503c\u5bf9\u3002 root@pod-configmap-env-2:/# echo $black k known as key root@pod-configmap-env-2:/# echo $cyan c root@pod-configmap-env-2:/# echo $favorite blue","title":"\u901a\u8fc7ConfigMap\u8bbe\u5b9a\u73af\u5883\u53d8\u91cf"},{"location":"k8s/cka_cn/foundamentals/pod/","text":"CKA\u81ea\u5b66\u7b14\u8bb08:Pod \u00b6 \u6458\u8981 \u00b6 \u7ec3\u4e60\u76ee\u6807\uff1a \u521b\u5efapod \u8ffd\u8e2apod pod\u6807\u7b7e \u9759\u6001pod \u591a\u5bb9\u5668pod \u542b\u521d\u59cb\u5316\u5bb9\u5668\u7684pod \u521b\u5efaPod \u00b6 \u521b\u5efaPod my-first-podl \u3002 kubectl apply -f - << EOF apiVersion: v1 kind: Pod metadata: name: my-first-pod spec: containers: - name: nginx image: nginx:mainline ports: - containerPort: 80 EOF \u9a8c\u8bc1\u521a\u521a\u521b\u5efa\u7684pod\u7684\u72b6\u6001\u3002 kubectl get pods -o wide \u8ffd\u8e2apod \u00b6 \u68c0\u67e5\u521a\u521a\u521b\u5efa\u7684pod\u7684\u65e5\u5fd7\u3002 kubectl logs my-first-pod \u5982\u679c\u65e5\u5fd7\u6216\u8005\u5176\u4ed6\u547d\u4ee4\u8f93\u51fa\u7684\u4fe1\u606f\u4e0d\u8db3\u4ee5\u5e2e\u52a9\u6211\u4eec\u67e5\u627e\u6839\u672c\u539f\u56e0\uff0c\u6211\u4eec\u53ef\u4ee5\u901a\u8fc7 kubectl exec -it -- bash \u6765\u8fdb\u5165pod\u5185\u90e8\u8fdb\u884c\u5206\u6790\u3002 kubectl exec -it my-first-pod -- bash root@my-first-pod:/# ls root@my-first-pod:/# cd bin root@my-first-pod:/bin# ls root@my-first-pod:/bin# exit \u6267\u884c\u547d\u4ee4 kubectl explain pod.spec \u53ef\u4ee5\u5f97\u5230pod\u5bf9\u5e94\u7684yaml\u6587\u4ef6\u4e2dSpec\u533a\u6bb5\u7684\u5185\u5bb9\u3002 \u6211\u4eec\u53ef\u4ee5\u67e5\u770b Pod \u8d44\u6e90\u7684\u5b98\u65b9 API \u53c2\u8003\u6587\u6863\uff0c\u6216\u8005\u4f7f\u7528 kubectl explain pod \u547d\u4ee4\u884c\u83b7\u53d6\u8be5\u8d44\u6e90\u7684\u63cf\u8ff0\u4fe1\u606f\u3002\u901a\u8fc7\u5728\u8d44\u6e90\u7c7b\u578b\u540e\u6dfb\u52a0 . \uff0cexplain \u547d\u4ee4\u4f1a\u63d0\u4f9b\u8be5\u6307\u5b9a\u5b57\u6bb5\u7684\u66f4\u591a\u8be6\u7ec6\u4fe1\u606f\u3002 kubectl explain pod.kind kubectl explain pod.spec kubectl explain pod.spec.containers kubectl explain pod.spec.containers.name pod\u7684\u6807\u7b7e \u00b6 \u901a\u8fc7\u9009\u9879 --show-labels \u6765\u83b7\u5f97pod\u7684\u6807\u7b7e\u3002 kubectl get pods kubectl get pods --show-labels \u7ed9pod pod my-first-pod \u6dfb\u52a02\u4e2a\u6807\u7b7e\u3002 kubectl label pod my-first-pod nginx = mainline kubectl label pod my-first-pod env = demo kubectl get pods --show-labels \u901a\u8fc7\u6807\u7b7e\u6765\u67e5\u627epod\u3002 kubectl get pod -l env = demo kubectl get pod -l env = demo,nginx = mainline kubectl get pod -l env = training \u79fb\u9664pod\u7684\u6807\u7b7e\u3002 kubectl label pods my-first-pod env- kubectl get pods --show-labels \u63cf\u8ff0 Pod\u3002 kubectl describe pod my-first-pod \u5220\u9664pod. \u8fd0\u884c\u547d\u4ee4 watch kubectl get pods \u6765\u83b7\u53d6pod\u7684\u72b6\u6001\u3002 kubectl delete pod my-first-pod watch kubectl get pods \u9759\u6001pod \u00b6 \u6f14\u793a\u573a\u666f\uff1a \u521b\u5efa\u4e00\u4e2a\u9759\u6001pod\u3002 kubectl \u4f1a\u81ea\u52a8\u68c0\u67e5 /etc/kubernetes/manifests/ \u4e2d\u7684 YAML \u6587\u4ef6\uff0c\u5e76\u5728\u68c0\u6d4b\u5230\u540e\u521b\u5efa\u9759\u6001 Pod\u3002 \u6f14\u793a\uff1a \u67e5\u770b\u7cfb\u7edf\u521d\u59cb\u5316\u540e\u5df2\u7ecf\u5b58\u5728\u7684\u9759\u6001pod\u3002 ll /etc/kubernetes/manifests/ \u8fd0\u884c\u7ed3\u679c\uff1a -rw------- 1 root root 2292 Jul 23 10:45 etcd.yaml -rw------- 1 root root 3889 Jul 23 10:45 kube-apiserver.yaml -rw------- 1 root root 3395 Jul 23 10:45 kube-controller-manager.yaml -rw------- 1 root root 1464 Jul 23 10:45 kube-scheduler.yaml \u5728 /etc/kubernetes/manifests/ \u76ee\u5f55\u4e2d\u521b\u5efayaml\u6587\u4ef6 my-nginx.yaml \uff0c\u4e00\u65e6\u6587\u4ef6\u521b\u5efa\u5b8c\u6210\uff0c\u9759\u6001Pod my-nginx \u5c06\u4f1a\u88ab\u81ea\u52a8\u521b\u5efa\u3002 kubectl run my-nginx --image = nginx:mainline --dry-run = client -n default -oyaml | sudo tee /etc/kubernetes/manifests/my-nginx.yaml \u68c0\u67e5 Pod my-nginx \u7684\u72b6\u6001\u3002Pod \u540d\u79f0\u4e2d\u5305\u542b\u8282\u70b9\u540d\u79f0 cka001 \uff0c\u8fd9\u610f\u5473\u7740\u8be5 Pod \u6b63\u5728\u8282\u70b9 cka001 \u4e0a\u8fd0\u884c\u3002 kubectl get pod -o wide \u8fd0\u884c\u7ed3\u679c\uff1a NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES my-nginx-cka001 1/1 Running 0 20s 10.244.228.196 cka001 \u5220\u9664 /etc/kubernetes/manifests/my-nginx.yaml \u8fd9\u4e2a yaml \u6587\u4ef6\uff0c\u5bf9\u5e94\u7684\u9759\u6001 Pod my-nginx \u5c06\u4f1a\u88ab\u81ea\u52a8\u5220\u9664\u3002 sudo rm /etc/kubernetes/manifests/my-nginx.yaml \u591a\u5bb9\u5668Pod \u00b6 \u6f14\u793a\u573a\u666f\uff1a \u521b\u5efa\u591a\u5bb9\u5668Pod \u63cf\u8ff0\u8be5Pod \u68c0\u67e5Pod\u7684\u65e5\u5fd7 \u68c0\u67e5\u5bb9\u5668\u7684\u65e5\u5fd7 \u6f14\u793a\uff1a \u521b\u5efa\u4e00\u4e2a\u540d\u4e3a multi-container-pod \u7684Pod\uff0c\u5305\u542b\u591a\u4e2a\u5bb9\u5668\uff1a container-1-nginx \u548c container-2-alpine \u3002 kubectl apply -f - << EOF apiVersion : v1 kind : Pod metadata : name : multi-container-pod spec : containers : - name : container-1-nginx image : nginx ports : - containerPort : 80 - name : container-2-alpine image : alpine command : [ \"watch\" , \"wget\" , \"-qO-\" , \"localhost\" ] EOF \u83b7\u53d6pod\u72b6\u6001\u3002 kubectl get pod multi-container-pod \u8fd0\u884c\u7ed3\u679c \u83b7\u53d6pod\u7684\u8be6\u7ec6\u4fe1\u606f\u3002 kubectl describe pod multi-container-pod \u8fd0\u884c\u7ed3\u679c\uff1a ....... Events: Type Reason Age From Message ---- ------ ---- ---- ------- Normal Scheduled 41s default-scheduler Successfully assigned dev/multi-container-pod to cka002 Normal Pulling 40s kubelet Pulling image \"nginx\" Normal Pulled 23s kubelet Successfully pulled image \"nginx\" in 16.767129903s Normal Created 22s kubelet Created container container-1-nginx Normal Started 22s kubelet Started container container-1-nginx Normal Pulling 22s kubelet Pulling image \"alpine\" Normal Pulled 14s kubelet Successfully pulled image \"alpine\" in 7.776104353s Normal Created 14s kubelet Created container container-2-alpine Normal Started 14s kubelet Started container container-2-alpine \u5bf9\u4e8e\u591a\u5bb9\u5668 Pod\uff0c\u5982\u679c\u6211\u4eec\u60f3\u901a\u8fc7\u547d\u4ee4 kubectl logs \u83b7\u53d6 Pod \u7684\u65e5\u5fd7\uff0c\u9700\u8981\u6307\u5b9a\u5bb9\u5668\u540d\u79f0\u3002\u5982\u679c\u4e0d\u6307\u5b9a\u5bb9\u5668\u540d\u79f0\uff0c\u5c06\u4f1a\u6536\u5230\u9519\u8bef\u4fe1\u606f\u3002 kubectl logs multi-container-pod \u8fd0\u884c\u7ed3\u679c error: a container name must be specified for pod multi-container-pod, choose one of: [ container-1-nginx container-2-alpine ] \u6307\u5b9a\u5bb9\u5668\u540d\u79f0\uff0c\u6211\u4eec\u53ef\u4ee5\u5f97\u5230\u5bf9\u5e94\u7684\u65e5\u5fd7\u4fe1\u606f\u3002 kubectl logs multi-container-pod container-1-nginx \u8fd0\u884c\u7ed3\u679c ...... ::1 - - [ 23 /Jul/2022:04:06:37 +0000 ] \"GET / HTTP/1.1\" 200 615 \"-\" \"Wget\" \"-\" \u5982\u679c\u6211\u4eec\u9700\u8981\u4f7f\u7528\u547d\u4ee4 kubectl exec -it -c -- \u767b\u5f55\u5230 Pod \u4e2d\uff0c\u540c\u6837\u9700\u8981\u6307\u5b9a\u5bb9\u5668\u540d\u79f0\u3002\u5982\u679c\u6ca1\u6709\u6307\u5b9a\u5bb9\u5668\u540d\u79f0\uff0c\u4f1a\u51fa\u73b0\u9519\u8bef\u3002 kubectl exec -it multi-container-pod -c container-1-nginx -- /bin/bash root@multi-container-pod:/# ls \u5220\u9664\u4e0a\u9762\u7ec3\u4e60\u4e2d\u521b\u5efa\u7684pod\u3002 kubectl delete pod multi-container-pod \u4e0b\u9762\u662f\u4e00\u4e2a\u57fa\u672c\u7684yaml\u6587\u4ef6\u7528\u6765\u521b\u5efa\u591a\u5bb9\u5668pod\u3002 kubectl apply -f - << EOF apiVersion : v1 kind : Pod metadata : name : my-multi-pod spec : containers : - image : nginx name : nginx - image : memcached name : memcached - image : redis name : redis EOF \u6f14\u793a\u573a\u666f\uff1a \u521b\u5efa\u4e00\u4e2a\u540d\u4e3a my-busybox \u7684Pod\uff0c\u5e76\u5728\u5176\u4e2d\u6dfb\u52a0\u4e00\u4e2a\u540d\u4e3a container-1-busybox \u7684\u5bb9\u5668\u3002\u8be5\u5bb9\u5668\u5c06\u628a\u6d88\u606f\u5199\u5165\u5230\u6587\u4ef6 /var/log/my-pod-busybox.log \u4e2d\u3002 \u5411Pod my-busybox \u4e2d\u6dfb\u52a0\u53e6\u4e00\u4e2a\u5bb9\u5668 container-2-busybox \uff08Sidecar\uff09\u3002Sidecar\u5bb9\u5668\u4ece\u6587\u4ef6 /var/log/my-pod-busybox.log \u4e2d\u8bfb\u53d6\u6d88\u606f\u3002 \u63d0\u793a\uff1a\u521b\u5efa\u4e00\u4e2aVolume\u6765\u5b58\u50a8\u65e5\u5fd7\u6587\u4ef6\uff0c\u5e76\u4e0e\u4e24\u4e2a\u5bb9\u5668\u5171\u4eab\u3002 \u6f14\u793a\uff1a \u521b\u5efa\u4e00\u4e2a\u540d\u4e3a my-busybox \u7684 Pod\uff0c\u5176\u4e2d\u5305\u542b\u4e00\u4e2a\u5bb9\u5668 container-1-busybox \u3002 kubectl apply -f - << EOF apiVersion: v1 kind: Pod metadata: name: my-busybox spec: containers: - name: container-1-busybox image: busybox args: - /bin/sh - -c - > i=0; while true; do echo \"Hello message from container-1: $i\" >> /var/log/my-pod-busybox.log; i=$((i+1)); sleep 1; done EOF \u5728 Kubernetes \u6587\u6863\u4e2d\u641c\u7d22 emptyDir \u3002 \u53c2\u8003\u4ee5\u4e0b\u6a21\u677f\u7528\u4e8e emptyDir \uff1a https://kubernetes.io/zh-cn/docs/concepts/storage/volumes/ \u5c06\u4ee5\u4e0b\u65b0\u529f\u80fd\u6dfb\u52a0\u5230 Pod \u4e2d\uff1a Volume\uff1a \u5377\u540d\u79f0\uff1a logfile \u7c7b\u578b\uff1a emptyDir \u66f4\u65b0\u73b0\u6709\u5bb9\u5668\uff1a name: container-1-busybox volumeMounts name: logfile mounthPath: /var/log \u6dfb\u52a0\u65b0\u5bb9\u5668\uff1a name: container-2-busybox image: busybox args: ['/bin/sh', '-c', 'tail -n+1 -f /var/log/my-pod-busybox.log'] volumeMounts: name: logfile mountPath: /var/log kubectl get pod my-busybox -o yaml > my-busybox.yaml vi my-busybox.yaml kubectl delete pod my-busybox kubectl apply -f my-busybox.yaml kubectl logs my-busybox -c container-2-busybox \u66f4\u65b0\u540e\u7684\u6587\u4ef6 my-busybox.yaml \u5982\u4e0b\uff1a apiVersion : v1 kind : Pod metadata : annotations : cni.projectcalico.org/containerID : 89644b6b073cd152f94b4cae7bdea6bbc3292cf59afd4f28102bd74f0205c9e4 cni.projectcalico.org/podIP : 10.244.102.20/32 cni.projectcalico.org/podIPs : 10.244.102.20/32 kubectl.kubernetes.io/last-applied-configuration : | {\"apiVersion\":\"v1\",\"kind\":\"Pod\",\"metadata\":{\"annotations\":{},\"name\":\"my-busybox\",\"namespace\":\"dev\"},\"spec\":{\"containers\":[{\"args\":[\"/bin/sh\",\"-c\",\"i=0; while true; do\\n echo \\\"Hello message from container-1: \\\" \\u003e\\u003e /var/log/my-pod-busybox.log;\\n i=1;\\n sleep 1;\\ndone\\n\"],\"image\":\"busybox\",\"name\":\"container-1-busybox\"}]}} creationTimestamp : \"2022-07-29T22:58:27Z\" name : my-busybox namespace : dev resourceVersion : \"1185720\" uid : c5e62a16-4459-4828-a441-7d1471b89a56 spec : containers : - name : container-2-busybox image : busybox args : [ '/bin/sh' , '-c' , 'tail -n+1 -f /var/log/my-pod-busybox.log' ] volumeMounts : - name : logfile mountPath : /var/log - args : - /bin/sh - -c - | i=0; while true; do echo \"Hello message from container-1: $i\" >> /var/log/my-pod-busybox.log; i=1; sleep 1; done image : busybox imagePullPolicy : Always name : container-1-busybox resources : {} terminationMessagePath : /dev/termination-log terminationMessagePolicy : File volumeMounts : - name : logfile mountPath : /var/log - mountPath : /var/run/secrets/kubernetes.io/serviceaccount name : kube-api-access-mhxlf readOnly : true dnsPolicy : ClusterFirst enableServiceLinks : true nodeName : cka003 preemptionPolicy : PreemptLowerPriority priority : 0 restartPolicy : Always schedulerName : default-scheduler securityContext : {} serviceAccount : default serviceAccountName : default terminationGracePeriodSeconds : 30 tolerations : - effect : NoExecute key : node.kubernetes.io/not-ready operator : Exists tolerationSeconds : 300 - effect : NoExecute key : node.kubernetes.io/unreachable operator : Exists tolerationSeconds : 300 volumes : - name : logfile emptyDir : {} - name : kube-api-access-mhxlf projected : defaultMode : 420 sources : - serviceAccountToken : expirationSeconds : 3607 path : token - configMap : items : - key : ca.crt path : ca.crt name : kube-root-ca.crt - downwardAPI : items : - fieldRef : apiVersion : v1 fieldPath : metadata.namespace path : namespace status : conditions : - lastProbeTime : null lastTransitionTime : \"2022-07-29T22:58:27Z\" status : \"True\" type : Initialized - lastProbeTime : null lastTransitionTime : \"2022-07-29T22:58:30Z\" status : \"True\" type : Ready - lastProbeTime : null lastTransitionTime : \"2022-07-29T22:58:30Z\" status : \"True\" type : ContainersReady - lastProbeTime : null lastTransitionTime : \"2022-07-29T22:58:27Z\" status : \"True\" type : PodScheduled containerStatuses : - containerID : containerd://fd42d4ba4d94d8918d8846327b1db2328be13c5f93f381877ff0228ed7b5468d image : docker.io/library/busybox:latest imageID : docker.io/library/busybox@sha256:0e97a8ca6955f22dbc7db9e9dbe970971f423541e52c34b8cb96ccc88d6a3883 lastState : {} name : container-1-busybox ready : true restartCount : 0 started : true state : running : startedAt : \"2022-07-29T22:58:30Z\" hostIP : phase : Running podIP : 10.244.102.20 podIPs : - ip : 10.244.102.20 qosClass : BestEffort startTime : \"2022-07-29T22:58:27Z\" \u6e05\u7406\u4e0a\u9762\u7ec3\u4e60\u4e2d\u521b\u5efa\u7684pod\u3002 kubectl delete pod my-busybox \u542b\u521d\u59cb\u5316\u5bb9\u5668Pod \u00b6 \u6f14\u793a\u573a\u666f\uff1a \u521b\u5efa\u62e5\u6709\u4e24\u4e2a\u521d\u59cb\u5316\u5bb9\u5668\u7684 Pod myapp-pod \u3002 myapp-container init-mydb \u521b\u5efa\u4e24\u4e2a\u670d\u52a1\uff1a myservice mydb \u6f14\u793a\u9884\u671f\u7ed3\u8bba\uff1a myapp-container \u7b49\u5f85\u670d\u52a1 myservice \u542f\u52a8\uff0c\u4ee5\u89e3\u6790\u540d\u79f0 myservice.dev.svc.cluster.local init-mydb \u7b49\u5f85\u670d\u52a1 mydb \u542f\u52a8\uff0c\u4ee5\u89e3\u6790\u540d\u79f0 mydb.dev.svc.cluster.local \u3002 \u6f14\u793a\uff1a \u521b\u5efa\u540d\u4e3a myapp-pod.yaml \u7684yaml\u6587\u4ef6\uff0c\u5e76\u6dfb\u52a0\u4ee5\u4e0b\u5185\u5bb9\u3002 \u6ce8\u610f\uff1a\u7531\u4e8e\u547d\u4ee4 $(cat /var/..... \u5c06\u88ab\u89c6\u4e3a\u4e3b\u673a\u53d8\u91cf\uff0c\u56e0\u6b64\u6211\u4eec\u4e0d\u80fd\u4f7f\u7528echo\u751f\u6210\u8be5\u6587\u4ef6\u3002\u5b83\u662f\u5bb9\u5668\u672c\u8eab\u7684\u53d8\u91cf\u3002 vi myapp-pod.yaml \u6587\u4ef6\u5185\u5bb9 apiVersion : v1 kind : Pod metadata : name : myapp-pod labels : app : myapp spec : containers : - name : myapp-container image : busybox:1.28 command : [ 'sh' , '-c' , 'echo The app is running! && sleep 3600' ] initContainers : - name : init-myservice image : busybox:1.28 command : [ 'sh' , '-c' , \"until nslookup myservice.$(cat /var/run/secrets/kubernetes.io/serviceaccount/namespace).svc.cluster.local; do echo waiting for myservice; sleep 2; done\" ] - name : init-mydb image : busybox:1.28 command : [ 'sh' , '-c' , \"until nslookup mydb.$(cat /var/run/secrets/kubernetes.io/serviceaccount/namespace).svc.cluster.local; do echo waiting for mydb; sleep 2; done\" ] \u7528\u4e0a\u9762\u521b\u5efa\u7684yaml\u6587\u4ef6\u521b\u5efaPod myapp-pod \u3002 kubectl apply -f myapp-pod.yaml \u68c0\u67e5pod\u7684\u72b6\u6001\u3002 kubectl get pod myapp-pod \u8fd0\u884c\u7ed3\u679c\uff1a NAME READY STATUS RESTARTS AGE myapp-pod 0/1 Init:0/2 0 12m \u68c0\u67e5Pod\uff0c\u53ef\u4ee5\u770b\u5230\u4e24\u4e2a\u9519\u8bef\uff1a nslookup: \u65e0\u6cd5\u89e3\u6790'myservice.dev.svc.cluster.local' Pod \"myapp-pod\"\u4e2d\u7684\u5bb9\u5668\u201cinit-mydb\u201d\u6b63\u5728\u7b49\u5f85\u542f\u52a8\uff1aPodInitializing kubectl logs myapp-pod -c init-myservice # Inspect the first init container kubectl logs myapp-pod -c init-mydb # Inspect the second init container \u5728\u8fd9\u4e2a\u65f6\u5019\uff0c\u8fd9\u4e9b init \u5bb9\u5668\u5c06\u7b49\u5f85\u53d1\u73b0\u540d\u4e3a mydb \u548c myservice \u7684\u670d\u52a1\u3002 \u521b\u5efa mydb \u548c myservice \u670d\u52a1\uff1a kubectl apply -f - << EOF apiVersion: v1 kind: Service metadata: name: myservice spec: ports: - protocol: TCP port: 80 targetPort: 9376 --- apiVersion: v1 kind: Service metadata: name: mydb spec: ports: - protocol: TCP port: 80 targetPort: 9377 EOF \u67e5\u770b\u521b\u5efa\u7684\u670d\u52a1\u7684\u72b6\u6001\u3002 kubectl get service \u521b\u5efa\u76842\u4e2a\u670d\u52a1\u90fd\u662f\u8fd0\u884c\u72b6\u6001\u3002 NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE mydb ClusterIP 11.244.239.149 80/TCP 6s myservice ClusterIP 11.244.116.126 80/TCP 6s \u518d\u6b21\u67e5\u770bpod\u7684\u72b6\u6001\u3002 kubectl get pod myapp-pod -o wide pod\u5df2\u7ecf\u6b63\u5e38\u8fd0\u884c\u4e86\u3002 NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES myapp-pod 0/1 Init:0/2 0 2m40s 10.244.112.2 cka002 \u73b0\u5728\u6211\u4eec\u53ef\u4ee5\u770b\u5230\u90a3\u4e9b\u521d\u59cb\u5316\u5bb9\u5668\u90fd\u5df2\u7ecf\u5b8c\u6210\uff0c myapp-pod Pod \u8fdb\u5165\u4e86 Running \u72b6\u6001\u3002 \u5220\u9664\u4e0a\u9762\u7ec3\u4e60\u4e2d\u521b\u5efa\u7684pod\u3002 kubectl delete service mydb myservice kubectl delete pod myapp-pod \u53c2\u8003\uff1a Pod basics Lifecycle & phases Kubernetes pod design pattern","title":"Pod"},{"location":"k8s/cka_cn/foundamentals/pod/#cka8pod","text":"","title":"CKA\u81ea\u5b66\u7b14\u8bb08:Pod"},{"location":"k8s/cka_cn/foundamentals/pod/#_1","text":"\u7ec3\u4e60\u76ee\u6807\uff1a \u521b\u5efapod \u8ffd\u8e2apod pod\u6807\u7b7e \u9759\u6001pod \u591a\u5bb9\u5668pod \u542b\u521d\u59cb\u5316\u5bb9\u5668\u7684pod","title":"\u6458\u8981"},{"location":"k8s/cka_cn/foundamentals/pod/#pod","text":"\u521b\u5efaPod my-first-podl \u3002 kubectl apply -f - << EOF apiVersion: v1 kind: Pod metadata: name: my-first-pod spec: containers: - name: nginx image: nginx:mainline ports: - containerPort: 80 EOF \u9a8c\u8bc1\u521a\u521a\u521b\u5efa\u7684pod\u7684\u72b6\u6001\u3002 kubectl get pods -o wide","title":"\u521b\u5efaPod"},{"location":"k8s/cka_cn/foundamentals/pod/#pod_1","text":"\u68c0\u67e5\u521a\u521a\u521b\u5efa\u7684pod\u7684\u65e5\u5fd7\u3002 kubectl logs my-first-pod \u5982\u679c\u65e5\u5fd7\u6216\u8005\u5176\u4ed6\u547d\u4ee4\u8f93\u51fa\u7684\u4fe1\u606f\u4e0d\u8db3\u4ee5\u5e2e\u52a9\u6211\u4eec\u67e5\u627e\u6839\u672c\u539f\u56e0\uff0c\u6211\u4eec\u53ef\u4ee5\u901a\u8fc7 kubectl exec -it -- bash \u6765\u8fdb\u5165pod\u5185\u90e8\u8fdb\u884c\u5206\u6790\u3002 kubectl exec -it my-first-pod -- bash root@my-first-pod:/# ls root@my-first-pod:/# cd bin root@my-first-pod:/bin# ls root@my-first-pod:/bin# exit \u6267\u884c\u547d\u4ee4 kubectl explain pod.spec \u53ef\u4ee5\u5f97\u5230pod\u5bf9\u5e94\u7684yaml\u6587\u4ef6\u4e2dSpec\u533a\u6bb5\u7684\u5185\u5bb9\u3002 \u6211\u4eec\u53ef\u4ee5\u67e5\u770b Pod \u8d44\u6e90\u7684\u5b98\u65b9 API \u53c2\u8003\u6587\u6863\uff0c\u6216\u8005\u4f7f\u7528 kubectl explain pod \u547d\u4ee4\u884c\u83b7\u53d6\u8be5\u8d44\u6e90\u7684\u63cf\u8ff0\u4fe1\u606f\u3002\u901a\u8fc7\u5728\u8d44\u6e90\u7c7b\u578b\u540e\u6dfb\u52a0 . \uff0cexplain \u547d\u4ee4\u4f1a\u63d0\u4f9b\u8be5\u6307\u5b9a\u5b57\u6bb5\u7684\u66f4\u591a\u8be6\u7ec6\u4fe1\u606f\u3002 kubectl explain pod.kind kubectl explain pod.spec kubectl explain pod.spec.containers kubectl explain pod.spec.containers.name","title":"\u8ffd\u8e2apod"},{"location":"k8s/cka_cn/foundamentals/pod/#pod_2","text":"\u901a\u8fc7\u9009\u9879 --show-labels \u6765\u83b7\u5f97pod\u7684\u6807\u7b7e\u3002 kubectl get pods kubectl get pods --show-labels \u7ed9pod pod my-first-pod \u6dfb\u52a02\u4e2a\u6807\u7b7e\u3002 kubectl label pod my-first-pod nginx = mainline kubectl label pod my-first-pod env = demo kubectl get pods --show-labels \u901a\u8fc7\u6807\u7b7e\u6765\u67e5\u627epod\u3002 kubectl get pod -l env = demo kubectl get pod -l env = demo,nginx = mainline kubectl get pod -l env = training \u79fb\u9664pod\u7684\u6807\u7b7e\u3002 kubectl label pods my-first-pod env- kubectl get pods --show-labels \u63cf\u8ff0 Pod\u3002 kubectl describe pod my-first-pod \u5220\u9664pod. \u8fd0\u884c\u547d\u4ee4 watch kubectl get pods \u6765\u83b7\u53d6pod\u7684\u72b6\u6001\u3002 kubectl delete pod my-first-pod watch kubectl get pods","title":"pod\u7684\u6807\u7b7e"},{"location":"k8s/cka_cn/foundamentals/pod/#pod_3","text":"\u6f14\u793a\u573a\u666f\uff1a \u521b\u5efa\u4e00\u4e2a\u9759\u6001pod\u3002 kubectl \u4f1a\u81ea\u52a8\u68c0\u67e5 /etc/kubernetes/manifests/ \u4e2d\u7684 YAML \u6587\u4ef6\uff0c\u5e76\u5728\u68c0\u6d4b\u5230\u540e\u521b\u5efa\u9759\u6001 Pod\u3002 \u6f14\u793a\uff1a \u67e5\u770b\u7cfb\u7edf\u521d\u59cb\u5316\u540e\u5df2\u7ecf\u5b58\u5728\u7684\u9759\u6001pod\u3002 ll /etc/kubernetes/manifests/ \u8fd0\u884c\u7ed3\u679c\uff1a -rw------- 1 root root 2292 Jul 23 10:45 etcd.yaml -rw------- 1 root root 3889 Jul 23 10:45 kube-apiserver.yaml -rw------- 1 root root 3395 Jul 23 10:45 kube-controller-manager.yaml -rw------- 1 root root 1464 Jul 23 10:45 kube-scheduler.yaml \u5728 /etc/kubernetes/manifests/ \u76ee\u5f55\u4e2d\u521b\u5efayaml\u6587\u4ef6 my-nginx.yaml \uff0c\u4e00\u65e6\u6587\u4ef6\u521b\u5efa\u5b8c\u6210\uff0c\u9759\u6001Pod my-nginx \u5c06\u4f1a\u88ab\u81ea\u52a8\u521b\u5efa\u3002 kubectl run my-nginx --image = nginx:mainline --dry-run = client -n default -oyaml | sudo tee /etc/kubernetes/manifests/my-nginx.yaml \u68c0\u67e5 Pod my-nginx \u7684\u72b6\u6001\u3002Pod \u540d\u79f0\u4e2d\u5305\u542b\u8282\u70b9\u540d\u79f0 cka001 \uff0c\u8fd9\u610f\u5473\u7740\u8be5 Pod \u6b63\u5728\u8282\u70b9 cka001 \u4e0a\u8fd0\u884c\u3002 kubectl get pod -o wide \u8fd0\u884c\u7ed3\u679c\uff1a NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES my-nginx-cka001 1/1 Running 0 20s 10.244.228.196 cka001 \u5220\u9664 /etc/kubernetes/manifests/my-nginx.yaml \u8fd9\u4e2a yaml \u6587\u4ef6\uff0c\u5bf9\u5e94\u7684\u9759\u6001 Pod my-nginx \u5c06\u4f1a\u88ab\u81ea\u52a8\u5220\u9664\u3002 sudo rm /etc/kubernetes/manifests/my-nginx.yaml","title":"\u9759\u6001pod"},{"location":"k8s/cka_cn/foundamentals/pod/#pod_4","text":"\u6f14\u793a\u573a\u666f\uff1a \u521b\u5efa\u591a\u5bb9\u5668Pod \u63cf\u8ff0\u8be5Pod \u68c0\u67e5Pod\u7684\u65e5\u5fd7 \u68c0\u67e5\u5bb9\u5668\u7684\u65e5\u5fd7 \u6f14\u793a\uff1a \u521b\u5efa\u4e00\u4e2a\u540d\u4e3a multi-container-pod \u7684Pod\uff0c\u5305\u542b\u591a\u4e2a\u5bb9\u5668\uff1a container-1-nginx \u548c container-2-alpine \u3002 kubectl apply -f - << EOF apiVersion : v1 kind : Pod metadata : name : multi-container-pod spec : containers : - name : container-1-nginx image : nginx ports : - containerPort : 80 - name : container-2-alpine image : alpine command : [ \"watch\" , \"wget\" , \"-qO-\" , \"localhost\" ] EOF \u83b7\u53d6pod\u72b6\u6001\u3002 kubectl get pod multi-container-pod \u8fd0\u884c\u7ed3\u679c \u83b7\u53d6pod\u7684\u8be6\u7ec6\u4fe1\u606f\u3002 kubectl describe pod multi-container-pod \u8fd0\u884c\u7ed3\u679c\uff1a ....... Events: Type Reason Age From Message ---- ------ ---- ---- ------- Normal Scheduled 41s default-scheduler Successfully assigned dev/multi-container-pod to cka002 Normal Pulling 40s kubelet Pulling image \"nginx\" Normal Pulled 23s kubelet Successfully pulled image \"nginx\" in 16.767129903s Normal Created 22s kubelet Created container container-1-nginx Normal Started 22s kubelet Started container container-1-nginx Normal Pulling 22s kubelet Pulling image \"alpine\" Normal Pulled 14s kubelet Successfully pulled image \"alpine\" in 7.776104353s Normal Created 14s kubelet Created container container-2-alpine Normal Started 14s kubelet Started container container-2-alpine \u5bf9\u4e8e\u591a\u5bb9\u5668 Pod\uff0c\u5982\u679c\u6211\u4eec\u60f3\u901a\u8fc7\u547d\u4ee4 kubectl logs \u83b7\u53d6 Pod \u7684\u65e5\u5fd7\uff0c\u9700\u8981\u6307\u5b9a\u5bb9\u5668\u540d\u79f0\u3002\u5982\u679c\u4e0d\u6307\u5b9a\u5bb9\u5668\u540d\u79f0\uff0c\u5c06\u4f1a\u6536\u5230\u9519\u8bef\u4fe1\u606f\u3002 kubectl logs multi-container-pod \u8fd0\u884c\u7ed3\u679c error: a container name must be specified for pod multi-container-pod, choose one of: [ container-1-nginx container-2-alpine ] \u6307\u5b9a\u5bb9\u5668\u540d\u79f0\uff0c\u6211\u4eec\u53ef\u4ee5\u5f97\u5230\u5bf9\u5e94\u7684\u65e5\u5fd7\u4fe1\u606f\u3002 kubectl logs multi-container-pod container-1-nginx \u8fd0\u884c\u7ed3\u679c ...... ::1 - - [ 23 /Jul/2022:04:06:37 +0000 ] \"GET / HTTP/1.1\" 200 615 \"-\" \"Wget\" \"-\" \u5982\u679c\u6211\u4eec\u9700\u8981\u4f7f\u7528\u547d\u4ee4 kubectl exec -it -c -- \u767b\u5f55\u5230 Pod \u4e2d\uff0c\u540c\u6837\u9700\u8981\u6307\u5b9a\u5bb9\u5668\u540d\u79f0\u3002\u5982\u679c\u6ca1\u6709\u6307\u5b9a\u5bb9\u5668\u540d\u79f0\uff0c\u4f1a\u51fa\u73b0\u9519\u8bef\u3002 kubectl exec -it multi-container-pod -c container-1-nginx -- /bin/bash root@multi-container-pod:/# ls \u5220\u9664\u4e0a\u9762\u7ec3\u4e60\u4e2d\u521b\u5efa\u7684pod\u3002 kubectl delete pod multi-container-pod \u4e0b\u9762\u662f\u4e00\u4e2a\u57fa\u672c\u7684yaml\u6587\u4ef6\u7528\u6765\u521b\u5efa\u591a\u5bb9\u5668pod\u3002 kubectl apply -f - << EOF apiVersion : v1 kind : Pod metadata : name : my-multi-pod spec : containers : - image : nginx name : nginx - image : memcached name : memcached - image : redis name : redis EOF \u6f14\u793a\u573a\u666f\uff1a \u521b\u5efa\u4e00\u4e2a\u540d\u4e3a my-busybox \u7684Pod\uff0c\u5e76\u5728\u5176\u4e2d\u6dfb\u52a0\u4e00\u4e2a\u540d\u4e3a container-1-busybox \u7684\u5bb9\u5668\u3002\u8be5\u5bb9\u5668\u5c06\u628a\u6d88\u606f\u5199\u5165\u5230\u6587\u4ef6 /var/log/my-pod-busybox.log \u4e2d\u3002 \u5411Pod my-busybox \u4e2d\u6dfb\u52a0\u53e6\u4e00\u4e2a\u5bb9\u5668 container-2-busybox \uff08Sidecar\uff09\u3002Sidecar\u5bb9\u5668\u4ece\u6587\u4ef6 /var/log/my-pod-busybox.log \u4e2d\u8bfb\u53d6\u6d88\u606f\u3002 \u63d0\u793a\uff1a\u521b\u5efa\u4e00\u4e2aVolume\u6765\u5b58\u50a8\u65e5\u5fd7\u6587\u4ef6\uff0c\u5e76\u4e0e\u4e24\u4e2a\u5bb9\u5668\u5171\u4eab\u3002 \u6f14\u793a\uff1a \u521b\u5efa\u4e00\u4e2a\u540d\u4e3a my-busybox \u7684 Pod\uff0c\u5176\u4e2d\u5305\u542b\u4e00\u4e2a\u5bb9\u5668 container-1-busybox \u3002 kubectl apply -f - << EOF apiVersion: v1 kind: Pod metadata: name: my-busybox spec: containers: - name: container-1-busybox image: busybox args: - /bin/sh - -c - > i=0; while true; do echo \"Hello message from container-1: $i\" >> /var/log/my-pod-busybox.log; i=$((i+1)); sleep 1; done EOF \u5728 Kubernetes \u6587\u6863\u4e2d\u641c\u7d22 emptyDir \u3002 \u53c2\u8003\u4ee5\u4e0b\u6a21\u677f\u7528\u4e8e emptyDir \uff1a https://kubernetes.io/zh-cn/docs/concepts/storage/volumes/ \u5c06\u4ee5\u4e0b\u65b0\u529f\u80fd\u6dfb\u52a0\u5230 Pod \u4e2d\uff1a Volume\uff1a \u5377\u540d\u79f0\uff1a logfile \u7c7b\u578b\uff1a emptyDir \u66f4\u65b0\u73b0\u6709\u5bb9\u5668\uff1a name: container-1-busybox volumeMounts name: logfile mounthPath: /var/log \u6dfb\u52a0\u65b0\u5bb9\u5668\uff1a name: container-2-busybox image: busybox args: ['/bin/sh', '-c', 'tail -n+1 -f /var/log/my-pod-busybox.log'] volumeMounts: name: logfile mountPath: /var/log kubectl get pod my-busybox -o yaml > my-busybox.yaml vi my-busybox.yaml kubectl delete pod my-busybox kubectl apply -f my-busybox.yaml kubectl logs my-busybox -c container-2-busybox \u66f4\u65b0\u540e\u7684\u6587\u4ef6 my-busybox.yaml \u5982\u4e0b\uff1a apiVersion : v1 kind : Pod metadata : annotations : cni.projectcalico.org/containerID : 89644b6b073cd152f94b4cae7bdea6bbc3292cf59afd4f28102bd74f0205c9e4 cni.projectcalico.org/podIP : 10.244.102.20/32 cni.projectcalico.org/podIPs : 10.244.102.20/32 kubectl.kubernetes.io/last-applied-configuration : | {\"apiVersion\":\"v1\",\"kind\":\"Pod\",\"metadata\":{\"annotations\":{},\"name\":\"my-busybox\",\"namespace\":\"dev\"},\"spec\":{\"containers\":[{\"args\":[\"/bin/sh\",\"-c\",\"i=0; while true; do\\n echo \\\"Hello message from container-1: \\\" \\u003e\\u003e /var/log/my-pod-busybox.log;\\n i=1;\\n sleep 1;\\ndone\\n\"],\"image\":\"busybox\",\"name\":\"container-1-busybox\"}]}} creationTimestamp : \"2022-07-29T22:58:27Z\" name : my-busybox namespace : dev resourceVersion : \"1185720\" uid : c5e62a16-4459-4828-a441-7d1471b89a56 spec : containers : - name : container-2-busybox image : busybox args : [ '/bin/sh' , '-c' , 'tail -n+1 -f /var/log/my-pod-busybox.log' ] volumeMounts : - name : logfile mountPath : /var/log - args : - /bin/sh - -c - | i=0; while true; do echo \"Hello message from container-1: $i\" >> /var/log/my-pod-busybox.log; i=1; sleep 1; done image : busybox imagePullPolicy : Always name : container-1-busybox resources : {} terminationMessagePath : /dev/termination-log terminationMessagePolicy : File volumeMounts : - name : logfile mountPath : /var/log - mountPath : /var/run/secrets/kubernetes.io/serviceaccount name : kube-api-access-mhxlf readOnly : true dnsPolicy : ClusterFirst enableServiceLinks : true nodeName : cka003 preemptionPolicy : PreemptLowerPriority priority : 0 restartPolicy : Always schedulerName : default-scheduler securityContext : {} serviceAccount : default serviceAccountName : default terminationGracePeriodSeconds : 30 tolerations : - effect : NoExecute key : node.kubernetes.io/not-ready operator : Exists tolerationSeconds : 300 - effect : NoExecute key : node.kubernetes.io/unreachable operator : Exists tolerationSeconds : 300 volumes : - name : logfile emptyDir : {} - name : kube-api-access-mhxlf projected : defaultMode : 420 sources : - serviceAccountToken : expirationSeconds : 3607 path : token - configMap : items : - key : ca.crt path : ca.crt name : kube-root-ca.crt - downwardAPI : items : - fieldRef : apiVersion : v1 fieldPath : metadata.namespace path : namespace status : conditions : - lastProbeTime : null lastTransitionTime : \"2022-07-29T22:58:27Z\" status : \"True\" type : Initialized - lastProbeTime : null lastTransitionTime : \"2022-07-29T22:58:30Z\" status : \"True\" type : Ready - lastProbeTime : null lastTransitionTime : \"2022-07-29T22:58:30Z\" status : \"True\" type : ContainersReady - lastProbeTime : null lastTransitionTime : \"2022-07-29T22:58:27Z\" status : \"True\" type : PodScheduled containerStatuses : - containerID : containerd://fd42d4ba4d94d8918d8846327b1db2328be13c5f93f381877ff0228ed7b5468d image : docker.io/library/busybox:latest imageID : docker.io/library/busybox@sha256:0e97a8ca6955f22dbc7db9e9dbe970971f423541e52c34b8cb96ccc88d6a3883 lastState : {} name : container-1-busybox ready : true restartCount : 0 started : true state : running : startedAt : \"2022-07-29T22:58:30Z\" hostIP : phase : Running podIP : 10.244.102.20 podIPs : - ip : 10.244.102.20 qosClass : BestEffort startTime : \"2022-07-29T22:58:27Z\" \u6e05\u7406\u4e0a\u9762\u7ec3\u4e60\u4e2d\u521b\u5efa\u7684pod\u3002 kubectl delete pod my-busybox","title":"\u591a\u5bb9\u5668Pod"},{"location":"k8s/cka_cn/foundamentals/pod/#pod_5","text":"\u6f14\u793a\u573a\u666f\uff1a \u521b\u5efa\u62e5\u6709\u4e24\u4e2a\u521d\u59cb\u5316\u5bb9\u5668\u7684 Pod myapp-pod \u3002 myapp-container init-mydb \u521b\u5efa\u4e24\u4e2a\u670d\u52a1\uff1a myservice mydb \u6f14\u793a\u9884\u671f\u7ed3\u8bba\uff1a myapp-container \u7b49\u5f85\u670d\u52a1 myservice \u542f\u52a8\uff0c\u4ee5\u89e3\u6790\u540d\u79f0 myservice.dev.svc.cluster.local init-mydb \u7b49\u5f85\u670d\u52a1 mydb \u542f\u52a8\uff0c\u4ee5\u89e3\u6790\u540d\u79f0 mydb.dev.svc.cluster.local \u3002 \u6f14\u793a\uff1a \u521b\u5efa\u540d\u4e3a myapp-pod.yaml \u7684yaml\u6587\u4ef6\uff0c\u5e76\u6dfb\u52a0\u4ee5\u4e0b\u5185\u5bb9\u3002 \u6ce8\u610f\uff1a\u7531\u4e8e\u547d\u4ee4 $(cat /var/..... \u5c06\u88ab\u89c6\u4e3a\u4e3b\u673a\u53d8\u91cf\uff0c\u56e0\u6b64\u6211\u4eec\u4e0d\u80fd\u4f7f\u7528echo\u751f\u6210\u8be5\u6587\u4ef6\u3002\u5b83\u662f\u5bb9\u5668\u672c\u8eab\u7684\u53d8\u91cf\u3002 vi myapp-pod.yaml \u6587\u4ef6\u5185\u5bb9 apiVersion : v1 kind : Pod metadata : name : myapp-pod labels : app : myapp spec : containers : - name : myapp-container image : busybox:1.28 command : [ 'sh' , '-c' , 'echo The app is running! && sleep 3600' ] initContainers : - name : init-myservice image : busybox:1.28 command : [ 'sh' , '-c' , \"until nslookup myservice.$(cat /var/run/secrets/kubernetes.io/serviceaccount/namespace).svc.cluster.local; do echo waiting for myservice; sleep 2; done\" ] - name : init-mydb image : busybox:1.28 command : [ 'sh' , '-c' , \"until nslookup mydb.$(cat /var/run/secrets/kubernetes.io/serviceaccount/namespace).svc.cluster.local; do echo waiting for mydb; sleep 2; done\" ] \u7528\u4e0a\u9762\u521b\u5efa\u7684yaml\u6587\u4ef6\u521b\u5efaPod myapp-pod \u3002 kubectl apply -f myapp-pod.yaml \u68c0\u67e5pod\u7684\u72b6\u6001\u3002 kubectl get pod myapp-pod \u8fd0\u884c\u7ed3\u679c\uff1a NAME READY STATUS RESTARTS AGE myapp-pod 0/1 Init:0/2 0 12m \u68c0\u67e5Pod\uff0c\u53ef\u4ee5\u770b\u5230\u4e24\u4e2a\u9519\u8bef\uff1a nslookup: \u65e0\u6cd5\u89e3\u6790'myservice.dev.svc.cluster.local' Pod \"myapp-pod\"\u4e2d\u7684\u5bb9\u5668\u201cinit-mydb\u201d\u6b63\u5728\u7b49\u5f85\u542f\u52a8\uff1aPodInitializing kubectl logs myapp-pod -c init-myservice # Inspect the first init container kubectl logs myapp-pod -c init-mydb # Inspect the second init container \u5728\u8fd9\u4e2a\u65f6\u5019\uff0c\u8fd9\u4e9b init \u5bb9\u5668\u5c06\u7b49\u5f85\u53d1\u73b0\u540d\u4e3a mydb \u548c myservice \u7684\u670d\u52a1\u3002 \u521b\u5efa mydb \u548c myservice \u670d\u52a1\uff1a kubectl apply -f - << EOF apiVersion: v1 kind: Service metadata: name: myservice spec: ports: - protocol: TCP port: 80 targetPort: 9376 --- apiVersion: v1 kind: Service metadata: name: mydb spec: ports: - protocol: TCP port: 80 targetPort: 9377 EOF \u67e5\u770b\u521b\u5efa\u7684\u670d\u52a1\u7684\u72b6\u6001\u3002 kubectl get service \u521b\u5efa\u76842\u4e2a\u670d\u52a1\u90fd\u662f\u8fd0\u884c\u72b6\u6001\u3002 NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE mydb ClusterIP 11.244.239.149 80/TCP 6s myservice ClusterIP 11.244.116.126 80/TCP 6s \u518d\u6b21\u67e5\u770bpod\u7684\u72b6\u6001\u3002 kubectl get pod myapp-pod -o wide pod\u5df2\u7ecf\u6b63\u5e38\u8fd0\u884c\u4e86\u3002 NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES myapp-pod 0/1 Init:0/2 0 2m40s 10.244.112.2 cka002 \u73b0\u5728\u6211\u4eec\u53ef\u4ee5\u770b\u5230\u90a3\u4e9b\u521d\u59cb\u5316\u5bb9\u5668\u90fd\u5df2\u7ecf\u5b8c\u6210\uff0c myapp-pod Pod \u8fdb\u5165\u4e86 Running \u72b6\u6001\u3002 \u5220\u9664\u4e0a\u9762\u7ec3\u4e60\u4e2d\u521b\u5efa\u7684pod\u3002 kubectl delete service mydb myservice kubectl delete pod myapp-pod \u53c2\u8003\uff1a Pod basics Lifecycle & phases Kubernetes pod design pattern","title":"\u542b\u521d\u59cb\u5316\u5bb9\u5668Pod"},{"location":"k8s/cka_cn/foundamentals/policy/","text":"CKA\u81ea\u5b66\u7b14\u8bb022:Policy \u00b6 ResourceQuota \u00b6 \u6f14\u793a\u573a\u666f\uff1a \u4e3anamespace quota-object-example \u521b\u5efa\u8d44\u6e90\u914d\u989dResourceQuota object-quota-demo \u3002 \u4e3a NodePort \u6d4b\u8bd5 ResourceQuota object-quota-demo \u3002 \u4e3a PVC \u6d4b\u8bd5 ResourceQuota object-quota-demo \u3002 Create Namespace \u00b6 \u521b\u5efaNamespace\u3002 kubectl create ns quota-object-example \u521b\u5efaResourceQuota \u00b6 \u4e3anamespace quota-object-example \u521b\u5efa\u8d44\u6e90\u914d\u989dResourceQuota object-quota-demo \u3002 \u5728\u8be5namespace\u4e2d\uff0c\u6211\u4eec\u53ea\u80fd\u521b\u5efa 1 \u4e2a\u6c38\u4e45\u5377PVC\u30011 \u4e2a\u8d1f\u8f7d\u5747\u8861LoadBalancer\u670d\u52a1\uff0c\u4e0d\u80fd\u521b\u5efa NodePort \u670d\u52a1\u3002 kubectl apply -f - <@ \uff09 CURRENT NAME CLUSTER AUTHINFO NAMESPACE * kubernetes-admin@kubernetes kubernetes kubernetes-admin dev \u521b\u5efaCA\u914d\u7f6e\u6587\u4ef6 \u00b6 CA\uff08Certificate Authority\uff09\u914d\u7f6e\u6587\u4ef6\uff08config file\uff09\u662f\u4e00\u4e2a\u7528\u4e8e\u5b58\u50a8\u8bc1\u4e66\u9881\u53d1\u673a\u6784\uff08CA\uff09\u4fe1\u606f\u7684\u6587\u4ef6\u3002 \u5728\u4f7f\u7528TLS/SSL\u52a0\u5bc6\u901a\u4fe1\u65f6\uff0c\u9700\u8981\u4f7f\u7528\u8bc1\u4e66\u6765\u9a8c\u8bc1\u901a\u4fe1\u53cc\u65b9\u7684\u8eab\u4efd\u3002 \u800cCA\u5219\u662f\u8d1f\u8d23\u7b7e\u53d1\u548c\u9a8c\u8bc1\u8bc1\u4e66\u7684\u673a\u6784\uff0c\u56e0\u6b64\u5728\u5efa\u7acbTLS/SSL\u8fde\u63a5\u65f6\u9700\u8981\u5148\u9a8c\u8bc1CA\u7684\u4fe1\u4efb\u5173\u7cfb\uff0c\u4ee5\u4fdd\u8bc1\u8bc1\u4e66\u7684\u6709\u6548\u6027\u3002 CA\u6587\u4ef6\u4e2d\u5b58\u50a8\u4e86CA\u7684\u516c\u94a5\u4fe1\u606f\u548c\u5176\u4ed6\u76f8\u5173\u7684\u914d\u7f6e\u4fe1\u606f\u3002 \u5728Kubernetes\u4e2d\uff0c\u4f7f\u7528CA\u6587\u4ef6\u6765\u9a8c\u8bc1\u8bc1\u4e66\u7684\u6709\u6548\u6027\u548c\u6388\u6743\u8bbf\u95ee\u3002 \u67e5\u770b\u76ee\u5f55 /etc/kubernetes/pki \u53ca\u5176\u5b50\u76ee\u5f55\u7684\u7ed3\u6784\u60c5\u51b5\u3002 tree /etc/kubernetes/pki \u8fd0\u884c\u7ed3\u679c\uff0c\u4e0b\u9762\u662fKubernetes\u521d\u59cb\u5b89\u88c5\u540e\u7684\u6587\u4ef6\u7ed3\u6784\u7684\u793a\u4f8b\u5185\u5bb9\u3002 /etc/kubernetes/pki \u251c\u2500\u2500 apiserver.crt \u251c\u2500\u2500 apiserver-etcd-client.crt \u251c\u2500\u2500 apiserver-etcd-client.key \u251c\u2500\u2500 apiserver.key \u251c\u2500\u2500 apiserver-kubelet-client.crt \u251c\u2500\u2500 apiserver-kubelet-client.key \u251c\u2500\u2500 ca.crt \u251c\u2500\u2500 ca.key \u251c\u2500\u2500 etcd \u2502 \u251c\u2500\u2500 ca.crt \u2502 \u251c\u2500\u2500 ca.key \u2502 \u251c\u2500\u2500 healthcheck-client.crt \u2502 \u251c\u2500\u2500 healthcheck-client.key \u2502 \u251c\u2500\u2500 peer.crt \u2502 \u251c\u2500\u2500 peer.key \u2502 \u251c\u2500\u2500 server.crt \u2502 \u2514\u2500\u2500 server.key \u251c\u2500\u2500 front-proxy-ca.crt \u251c\u2500\u2500 front-proxy-ca.key \u251c\u2500\u2500 front-proxy-client.crt \u251c\u2500\u2500 front-proxy-client.key \u251c\u2500\u2500 sa.key \u2514\u2500\u2500 sa.pub \u8fdb\u5165\u76ee\u5f55 /etc/kubernetes/pki \uff0c\u5373\u5f53\u524d\u5de5\u4f5c\u76ee\u5f55\u3002 cd /etc/kubernetes/pki \u68c0\u67e5\u6587\u4ef6 ca-config.json \u662f\u5426\u5df2\u7ecf\u5b58\u5728\u4e0e\u5f53\u524d\u5de5\u4f5c\u76ee\u5f55\u3002 ll ca-config.json \u5982\u679c\u4e0d\u5b58\u5728\uff0c\u5219\u521b\u5efa\u8fd9\u4e2a\u6587\u4ef6\u3002 \u6211\u4eec\u53ef\u4ee5\u6dfb\u52a0\u591a\u4e2a\u914d\u7f6e\u6587\u4ef6\u6765\u6307\u5b9a\u4e0d\u540c\u7684\u8fc7\u671f\u65e5\u671f\u3001\u573a\u666f\u3001\u53c2\u6570\u7b49\u3002 \u914d\u7f6e\u6587\u4ef6\u5c06\u7528\u4e8e\u7b7e\u7f72\u8bc1\u4e66\u3002 87600 \u5c0f\u65f6\u5927\u7ea6\u662f10\u5e74\u3002 \u8fd9\u91cc\u6211\u4eec\u5c06\u5728 ca-config.json \u6587\u4ef6\u4e2d\u6dfb\u52a0\u4e00\u4e2a\u540d\u4e3a dev \u7684\u914d\u7f6e\u6587\u4ef6\u3002 cat > ca-config.json < cka-dev-csr.json < \uff09\u6765\u62fc\u63a5\u51fa\u73af\u5883\u53d8\u91cf APISERVER \u7684\u503c\uff0c\u5982\uff1a https://: \u3002 kubectl get node -owide \u8fd0\u884c\u7ed3\u679c\uff1a NAME STATUS ROLES AGE VERSION OS-IMAGE KERNEL-VERSION CONTAINER-RUNTIME cka001 Ready control-plane,master 14h v1.24.0 Ubuntu 20.04.4 LTS 5.4.0-122-generic containerd://1.5.9 cka002 Ready 14h v1.24.0 Ubuntu 20.04.4 LTS 5.4.0-122-generic containerd://1.5.9 cka003 Ready 14h v1.24.0 Ubuntu 20.04.4 LTS 5.4.0-122-generic containerd://1.5.9 \u8bbe\u5b9a\u5e76\u8f93\u51fa\u73af\u5883\u53d8\u91cf APISERVER \u3002 echo \"export APISERVER=\\\"https://:6443\\\"\" >> ~/.bashrc source ~/.bashrc \u9a8c\u8bc1\u73af\u5883\u53d8\u91cf APISERVER \u7684\u503c\u3002 echo $APISERVER \u8fd0\u884c\u7ed3\u679c\uff1a https://:6443 \u8bbe\u7f6e\u96c6\u7fa4 \u00b6 \u4fdd\u6301\u5f53\u524d\u5de5\u4f5c\u76ee\u5f55\u4e3a /etc/kubernetes/pki \u3002 \u751f\u6210 kubeconfig \u6587\u4ef6\u3002 kubectl config set-cluster kubernetes \\ --certificate-authority = /etc/kubernetes/pki/ca.crt \\ --embed-certs = true \\ --server = ${ APISERVER } \\ --kubeconfig = cka-dev.kubeconfig \u73b0\u5728\u6211\u4eec\u751f\u6210\u4e86\u65b0\u7684\u914d\u7f6e\u6587\u4ef6 cka-dev.kubeconfig \u3002 ll -tr | grep cka-dev \u8f93\u51fa\u7ed3\u679c\uff1a -rw-r--r-- 1 root root 222 Jul 24 08:49 cka-dev-csr.json -rw-r--r-- 1 root root 1281 Jul 24 09:14 cka-dev.pem -rw------- 1 root root 1675 Jul 24 09:14 cka-dev-key.pem -rw-r--r-- 1 root root 1001 Jul 24 09:14 cka-dev.csr -rw------- 1 root root 1671 Jul 24 09:16 cka-dev.kubeconfig \u8bfb\u53d6\u914d\u7f6e\u6587\u4ef6 cka-dev.kubeconfig \u7684\u5185\u5bb9\u3002 cat cka-dev.kubeconfig \u8f93\u51fa\u7684\u5185\u5bb9\uff1a apiVersion : v1 clusters : - cluster : certificate-authority-data : server : https://:6443 name : kubernetes contexts : null current-context : \"\" kind : Config preferences : {} users : null \u914d\u7f6e\u7528\u6237 \u00b6 \u5728\u6587\u4ef6 cka-dev.kubeconfig \u4e2d\uff0c\u7528\u6237\u4fe1\u606f\u8fd9\u90e8\u5206\u662f\u7a7a\u7684\u3002 \u4e0b\u9762\u6211\u4eec\u914d\u7f6e\u4e00\u4e2a\u7528\u6237 cka-dev \u3002 kubectl config set-credentials cka-dev \\ --client-certificate = /etc/kubernetes/pki/cka-dev.pem \\ --client-key = /etc/kubernetes/pki/cka-dev-key.pem \\ --embed-certs = true \\ --kubeconfig = cka-dev.kubeconfig \u73b0\u5728\uff0c\u7528\u6237\u4fe1\u606f\u5df2\u7ecf\u88ab\u6dfb\u52a0\u5230\u914d\u7f6e\u6587\u4ef6 cka-dev.kubeconfig \u4e2d\u4e86\u3002 cat cka-dev.kubeconfig \u8f93\u51fa\u7ed3\u679c\uff1a apiVersion : v1 clusters : - cluster : certificate-authority-data : server : https://:6443 name : kubernetes contexts : null current-context : \"\" kind : Config preferences : {} users : - name : cka-dev user : client-certificate-data : client-key-data : \u81f3\u6b64\u6211\u4eec\u5f97\u5230\u4e86\u4e00\u4e2a\u5b8c\u6574\u7684\u914d\u7f6e\u6587\u4ef6 cka-dev.kubeconfig \u3002 \u7531\u4e8e\u6211\u4eec\u6ca1\u6709\u5728 kubeconfig \u6587\u4ef6\u4e2d\u8bbe\u7f6e\u5f53\u524d\u4e0a\u4e0b\u6587\uff0c\u5f53\u6211\u4eec\u4f7f\u7528\u5b83\u6765\u83b7\u53d6\u8282\u70b9\u4fe1\u606f\u65f6\uff0c\u4f1a\u6536\u5230\u4ee5\u4e0b\u9519\u8bef\u3002 kubectl --kubeconfig = cka-dev.kubeconfig get nodes \u8fd0\u884c\u7ed3\u679c\uff1a The connection to the server localhost:8080 was refused - did you specify the right host or port? \u5f53\u524d\u4e0a\u4e0b\u6587\u5185\u5bb9\u662f\u7a7a\u767d\u3002 kubectl --kubeconfig = cka-dev.kubeconfig config get-contexts \u8f93\u51fa\u7ed3\u679c\uff1a CURRENT NAME CLUSTER AUTHINFO NAMESPACE \u914d\u7f6e\u4e0a\u4e0b\u6587 \u00b6 \u914d\u7f6e\u4e0a\u4e0b\u6587\u3002 kubectl config set-context dev --cluster = kubernetes --user = cka-dev --kubeconfig = cka-dev.kubeconfig \u73b0\u5728\u6211\u4eec\u914d\u7f6e\u4e86\u4e0a\u4e0b\u6587\uff0c\u4f46\u5176\u4e2d CURRENT \u4ecd\u7136\u662f\u7a7a\u767d\u3002 kubectl --kubeconfig = cka-dev.kubeconfig config get-contexts \u8fd0\u884c\u7ed3\u679c\uff1a CURRENT NAME CLUSTER AUTHINFO NAMESPACE dev kubernetes cka-dev \u8bbe\u7f6e\u9ed8\u8ba4\u4e0a\u4e0b\u6587\u3002\u4e0a\u4e0b\u6587\u5c06\u4e3a\u591a\u96c6\u7fa4\u73af\u5883\u4e2d\u7684\u96c6\u7fa4\u548c\u7528\u6237\u94fe\u63a5\uff0c\u5e76\u4e14\u6211\u4eec\u53ef\u4ee5\u5207\u6362\u5230\u4e0d\u540c\u7684\u96c6\u7fa4\u3002 kubectl --kubeconfig = cka-dev.kubeconfig config use-context dev \u9a8c\u8bc1 \u00b6 \u73b0\u5728 CURRENT \u5df2\u7ecf\u88ab\u6807\u8bb0\u4e3a * \u4e86\uff0c\u8fd9\u5c31\u8bf4\u660e\u5f53\u524d\u4e0a\u4e0b\u6587\u5df2\u7ecf\u914d\u7f6e\u597d\u4e86\u3002 kubectl --kubeconfig = cka-dev.kubeconfig config get-contexts \u8fd0\u884c\u7ed3\u679c\uff1a CURRENT NAME CLUSTER AUTHINFO NAMESPACE * dev kubernetes cka-dev \u56e0\u4e3a\u7528\u6237 cka-dev \u5728\u8be5\u96c6\u7fa4\u4e2d\u6ca1\u6709\u6388\u6743\uff0c\u6240\u4ee5\u5f53\u6211\u4eec\u5c1d\u8bd5\u83b7\u53d6 Pod \u6216 Node \u7684\u4fe1\u606f\u65f6\uff0c\u4f1a\u6536\u5230\u201c\u7981\u6b62\u8bbf\u95ee\uff08forbidden\uff09\u201d\u9519\u8bef\u3002 kubectl --kubeconfig = /etc/kubernetes/pki/cka-dev.kubeconfig get pod kubectl --kubeconfig = /etc/kubernetes/pki/cka-dev.kubeconfig get node \u5408\u5e76kubeconfig\u6587\u4ef6 \u00b6 \u62f7\u8d1d\u5f53\u524d\u914d\u7f6e\u6587\u4ef6\uff0c\u4f5c\u4e3a\u5907\u4efd\u3002 cp ~/.kube/config ~/.kube/config.old \u628a\u4e24\u4e2a\u914d\u7f6e\u6587\u4ef6\u5408\u5e76\u6210\u4e00\u4e2a\u65b0\u7684\u914d\u7f6e\u6587\u4ef6\uff0c\u5e76\u5b58\u653e\u5728 /tmp/config \u3002 KUBECONFIG = ~/.kube/config:/etc/kubernetes/pki/cka-dev.kubeconfig kubectl config view --flatten > /tmp/config \u7528\u5408\u5e76\u540e\u7684\u65b0\u914d\u7f6e\u6587\u4ef6\u66ff\u6362\u8001\u7684\u914d\u7f6e\u6587\u4ef6\u3002 mv /tmp/config ~/.kube/config \u65b0\u7684\u914d\u7f6e\u6587\u4ef6 ~/.kube/config \u7c7b\u4f3c\u5982\u4e0b\u3002 apiVersion : v1 clusters : - cluster : certificate-authority-data : server : https://:6443 name : kubernetes contexts : - context : cluster : kubernetes user : cka-dev name : dev - context : cluster : kubernetes user : kubernetes-admin name : kubernetes-admin@kubernetes current-context : kubernetes-admin@kubernetes kind : Config preferences : {} users : - name : cka-dev user : client-certificate-data : client-key-data : - name : kubernetes-admin user : client-certificate-data : client-key-data : \u68c0\u67e5\u57fa\u4e8e\u65b0\u7684\u914d\u7f6e\u6587\u4ef6\u4e0b\u7684\u5f53\u524d\u4e0a\u4e0b\u6587\u3002 kubectl config get-contexts \u5f53\u524d\u4e0a\u4e0b\u6587\u662f\u7cfb\u7edf\u9ed8\u8ba4\u914d\u7f6e kubernetes-admin@kubernetes \u3002 CURRENT NAME CLUSTER AUTHINFO NAMESPACE dev kubernetes cka-dev * kubernetes-admin@kubernetes kubernetes kubernetes-admin dev \u547d\u540d\u7a7a\u95f4\u548c\u4e0a\u4e0b\u6587 \u00b6 \u67e5\u8be2\u5f53\u524d\u547d\u540d\u7a7a\u95f4namespace\u5217\u8868\u548c\u5bf9\u5e94\u6807\u7b7elabel\u7684\u4fe1\u606f\u3002 kubectl get ns --show-labels \u521b\u5efanamespace cka \u3002 kubectl create namespace cka \u4f7f\u7528\u4ee5\u4e0b\u547d\u4ee4\u66f4\u65b0\u4e0a\u4e0b\u6587\u4fe1\u606f\uff0c\u4f8b\u5982\uff0c\u66f4\u65b0\u9ed8\u8ba4\u547d\u540d\u7a7a\u95f4\u7b49\u3002 kubectl config set-context --cluster = --namespace = --user = \u4e0b\u9762\u9488\u5bf9\u6bcf\u4e2a\u4e0a\u4e0b\u6587context\u8bbe\u5b9a\u9ed8\u8ba4\u7684namespace\u3002 kubectl config set-context kubernetes-admin@kubernetes --cluster = kubernetes --namespace = default --user = kubernetes-admin kubectl config set-context dev --cluster = kubernetes --namespace = cka --user = cka-dev \u68c0\u67e5\u5f53\u524d\u4e0a\u4e0b\u6587context\u7684\u4fe1\u606f\u3002 kubectl config get-contexts \u8f93\u51fa\u7ed3\u679c\uff1a CURRENT NAME CLUSTER AUTHINFO NAMESPACE dev kubernetes cka-dev cka * kubernetes-admin@kubernetes kubernetes kubernetes-admin dev \u901a\u8fc7\u4e0b\u9762\u7684\u547d\u4ee4\uff0c\u53ef\u4ee5\u5207\u6362\u5230\u65b0\u7684context\u3002 kubectl config use-contexts \u4f8b\u5982\uff1a kubectl config use-context dev \u68c0\u67e5\u4e0a\u9762\u7684\u53d8\u66f4\u662f\u5426\u751f\u6548\u3002 kubectl config get-contexts \u8fd0\u884c\u7ed3\u679c\uff1b CURRENT NAME CLUSTER AUTHINFO NAMESPACE * dev kubernetes cka-dev cka kubernetes-admin@kubernetes kubernetes kubernetes-admin dev Be noted, four users beginning with cka-dev created don't have any authorizations, e.g., access namespaces, get pods, etc.. Referring RBAC to grant their authorizations. \u6ce8\u610f\uff1a\u524d\u9762\u521b\u5efa\u7684\u4ee5 cka-dev \u5f00\u5934\u7684\u7528\u6237\u5b9e\u9645\u6ca1\u6709\u4efb\u4f55\u6743\u9650\uff0c\u4f8b\u5982\u8bbf\u95ee\u547d\u540d\u7a7a\u95f4\u3001\u83b7\u53d6 pod \u7b49\uff0c\u4e0b\u9762\u5c06\u901a\u8fc7 RBAC \u6388\u4e88\u4ed6\u4eec\u6388\u6743\u3002 \u89d2\u8272Role\u548c\u89d2\u8272\u7ed1\u5b9aRoleBinding \u00b6 \u5c06\u5f53\u524d\u5de5\u4f5c\u4e0a\u4e0b\u6587\u5207\u6362\u5230 kubernetes-admin@kubernetes \u3002 kubectl config use-context kubernetes-admin@kubernetes \u4f7f\u7528\u5e26\u6709\u9009\u9879 --dry-run=client \u548c -o yaml \u7684 kubectl create role \u547d\u4ee4\uff0c\u751f\u6210\u521b\u5efa\u89d2\u8272role\u7684 yaml \u6a21\u677f\u3002 kubectl create role admin-dev --resource = pods --verb = get --verb = list --verb = watch --dry-run = client -o yaml \u5728namespace cka \u4e0a\u521b\u5efa\u89d2\u8272role admin-dev \u3002 kubectl apply -f - << EOF apiVersion: rbac.authorization.k8s.io/v1 kind: Role metadata: namespace: cka name: admin-dev rules: - apiGroups: - \"\" resources: - pods verbs: - get - watch - list EOF \u4f7f\u7528\u5e26\u6709\u9009\u9879 --dry-run=client \u548c -o yaml \u7684 kubectl create rolebinding \u547d\u4ee4\uff0c\u751f\u6210\u521b\u5efa\u89d2\u8272\u7ed1\u5b9arolebinding\u7684 yaml \u6a21\u677f\u3002 kubectl create rolebinding admin --role = admin-dev --user = cka-dev --dry-run = client -o yaml \u5728namespace cka \u4e0a\u521b\u5efa\u4e00\u4e2a\u89d2\u8272\u7ed1\u5b9arolebinding admin \u3002 kubectl apply -f - << EOF apiVersion: rbac.authorization.k8s.io/v1 kind: RoleBinding metadata: name: admin namespace: cka roleRef: apiGroup: rbac.authorization.k8s.io kind: Role name: admin-dev subjects: - apiGroup: rbac.authorization.k8s.io kind: User name: cka-dev EOF \u9a8c\u8bc1namespace cka \u4e0a\u7684\u7528\u6237 cka-dev \u7684\u6743\u9650\u3002 \u5207\u6362\u5230\u4e0a\u4e0b\u6587 dev \u3002 kubectl config use-context dev \u67e5\u8be2namespace cka \u4e0apod\u7684\u72b6\u6001\uff0c\u6210\u529f\uff01 kubectl get pod -n cka \u67e5\u8be2namespace kube-system \u4e0apod\u7684\u72b6\u6001\uff0c\u5931\u8d25\uff01\u56e0\u4e3a\u524d\u9762\u6dfb\u52a0\u7684\u6743\u9650\u4ec5\u9650\u4e8enamespace cka \u3002 kubectl get pod -n kube-system \u67e5\u8be2\u8282\u70b9node\u7684\u72b6\u6001\uff0c\u5931\u8d25\uff01\u56e0\u4e3a\u5728\u89d2\u8272role\u91cc\u9762\u6211\u4eec\u53ea\u5b9a\u4e49\u4e86pod\u8fd9\u4e00\u79cd\u8d44\u6e90\u3002 kubectl get node \u5728namespace dev \u4e0a\u521b\u5efa\u4e00\u4e2apod\uff0c\u5931\u8d25\uff01\u56e0\u4e3a\u6211\u4eec\u5728\u53ea\u6709\u5bf9pod\u7684 get , watch , list \u4e09\u79cd\u64cd\u4f5c\u6743\u9650\uff0c\u6ca1\u6709 create \u6743\u9650\u3002 kubectl run nginx --image = nginx -n cka \u96c6\u7fa4\u89d2\u8272ClusterRole\u548c\u96c6\u7fa4\u89d2\u8272\u7ed1\u5b9aClusterRoleBinding \u00b6 \u5207\u6362\u5230\u4e0a\u4e0b\u6587 kubernetes-admin@kubernetes \u3002 kubectl config use-context kubernetes-admin@kubernetes \u521b\u5efa\u4e00\u4e2a\u540d\u4e3a nodes-admin \u7684 ClusterRole\uff0c\u5b83\u6388\u4e88 get \u3001 watch \u3001 list \u5bf9 nodes \u8d44\u6e90\u7684\u6388\u6743\u3002 kubectl apply -f - <@ \uff09 CURRENT NAME CLUSTER AUTHINFO NAMESPACE * kubernetes-admin@kubernetes kubernetes kubernetes-admin dev","title":"\u5f53\u524d\u4e0a\u4e0b\u6587"},{"location":"k8s/cka_cn/foundamentals/rbac/#ca","text":"CA\uff08Certificate Authority\uff09\u914d\u7f6e\u6587\u4ef6\uff08config file\uff09\u662f\u4e00\u4e2a\u7528\u4e8e\u5b58\u50a8\u8bc1\u4e66\u9881\u53d1\u673a\u6784\uff08CA\uff09\u4fe1\u606f\u7684\u6587\u4ef6\u3002 \u5728\u4f7f\u7528TLS/SSL\u52a0\u5bc6\u901a\u4fe1\u65f6\uff0c\u9700\u8981\u4f7f\u7528\u8bc1\u4e66\u6765\u9a8c\u8bc1\u901a\u4fe1\u53cc\u65b9\u7684\u8eab\u4efd\u3002 \u800cCA\u5219\u662f\u8d1f\u8d23\u7b7e\u53d1\u548c\u9a8c\u8bc1\u8bc1\u4e66\u7684\u673a\u6784\uff0c\u56e0\u6b64\u5728\u5efa\u7acbTLS/SSL\u8fde\u63a5\u65f6\u9700\u8981\u5148\u9a8c\u8bc1CA\u7684\u4fe1\u4efb\u5173\u7cfb\uff0c\u4ee5\u4fdd\u8bc1\u8bc1\u4e66\u7684\u6709\u6548\u6027\u3002 CA\u6587\u4ef6\u4e2d\u5b58\u50a8\u4e86CA\u7684\u516c\u94a5\u4fe1\u606f\u548c\u5176\u4ed6\u76f8\u5173\u7684\u914d\u7f6e\u4fe1\u606f\u3002 \u5728Kubernetes\u4e2d\uff0c\u4f7f\u7528CA\u6587\u4ef6\u6765\u9a8c\u8bc1\u8bc1\u4e66\u7684\u6709\u6548\u6027\u548c\u6388\u6743\u8bbf\u95ee\u3002 \u67e5\u770b\u76ee\u5f55 /etc/kubernetes/pki \u53ca\u5176\u5b50\u76ee\u5f55\u7684\u7ed3\u6784\u60c5\u51b5\u3002 tree /etc/kubernetes/pki \u8fd0\u884c\u7ed3\u679c\uff0c\u4e0b\u9762\u662fKubernetes\u521d\u59cb\u5b89\u88c5\u540e\u7684\u6587\u4ef6\u7ed3\u6784\u7684\u793a\u4f8b\u5185\u5bb9\u3002 /etc/kubernetes/pki \u251c\u2500\u2500 apiserver.crt \u251c\u2500\u2500 apiserver-etcd-client.crt \u251c\u2500\u2500 apiserver-etcd-client.key \u251c\u2500\u2500 apiserver.key \u251c\u2500\u2500 apiserver-kubelet-client.crt \u251c\u2500\u2500 apiserver-kubelet-client.key \u251c\u2500\u2500 ca.crt \u251c\u2500\u2500 ca.key \u251c\u2500\u2500 etcd \u2502 \u251c\u2500\u2500 ca.crt \u2502 \u251c\u2500\u2500 ca.key \u2502 \u251c\u2500\u2500 healthcheck-client.crt \u2502 \u251c\u2500\u2500 healthcheck-client.key \u2502 \u251c\u2500\u2500 peer.crt \u2502 \u251c\u2500\u2500 peer.key \u2502 \u251c\u2500\u2500 server.crt \u2502 \u2514\u2500\u2500 server.key \u251c\u2500\u2500 front-proxy-ca.crt \u251c\u2500\u2500 front-proxy-ca.key \u251c\u2500\u2500 front-proxy-client.crt \u251c\u2500\u2500 front-proxy-client.key \u251c\u2500\u2500 sa.key \u2514\u2500\u2500 sa.pub \u8fdb\u5165\u76ee\u5f55 /etc/kubernetes/pki \uff0c\u5373\u5f53\u524d\u5de5\u4f5c\u76ee\u5f55\u3002 cd /etc/kubernetes/pki \u68c0\u67e5\u6587\u4ef6 ca-config.json \u662f\u5426\u5df2\u7ecf\u5b58\u5728\u4e0e\u5f53\u524d\u5de5\u4f5c\u76ee\u5f55\u3002 ll ca-config.json \u5982\u679c\u4e0d\u5b58\u5728\uff0c\u5219\u521b\u5efa\u8fd9\u4e2a\u6587\u4ef6\u3002 \u6211\u4eec\u53ef\u4ee5\u6dfb\u52a0\u591a\u4e2a\u914d\u7f6e\u6587\u4ef6\u6765\u6307\u5b9a\u4e0d\u540c\u7684\u8fc7\u671f\u65e5\u671f\u3001\u573a\u666f\u3001\u53c2\u6570\u7b49\u3002 \u914d\u7f6e\u6587\u4ef6\u5c06\u7528\u4e8e\u7b7e\u7f72\u8bc1\u4e66\u3002 87600 \u5c0f\u65f6\u5927\u7ea6\u662f10\u5e74\u3002 \u8fd9\u91cc\u6211\u4eec\u5c06\u5728 ca-config.json \u6587\u4ef6\u4e2d\u6dfb\u52a0\u4e00\u4e2a\u540d\u4e3a dev \u7684\u914d\u7f6e\u6587\u4ef6\u3002 cat > ca-config.json < cka-dev-csr.json < \uff09\u6765\u62fc\u63a5\u51fa\u73af\u5883\u53d8\u91cf APISERVER \u7684\u503c\uff0c\u5982\uff1a https://: \u3002 kubectl get node -owide \u8fd0\u884c\u7ed3\u679c\uff1a NAME STATUS ROLES AGE VERSION OS-IMAGE KERNEL-VERSION CONTAINER-RUNTIME cka001 Ready control-plane,master 14h v1.24.0 Ubuntu 20.04.4 LTS 5.4.0-122-generic containerd://1.5.9 cka002 Ready 14h v1.24.0 Ubuntu 20.04.4 LTS 5.4.0-122-generic containerd://1.5.9 cka003 Ready 14h v1.24.0 Ubuntu 20.04.4 LTS 5.4.0-122-generic containerd://1.5.9 \u8bbe\u5b9a\u5e76\u8f93\u51fa\u73af\u5883\u53d8\u91cf APISERVER \u3002 echo \"export APISERVER=\\\"https://:6443\\\"\" >> ~/.bashrc source ~/.bashrc \u9a8c\u8bc1\u73af\u5883\u53d8\u91cf APISERVER \u7684\u503c\u3002 echo $APISERVER \u8fd0\u884c\u7ed3\u679c\uff1a https://:6443","title":"\u521b\u5efakubeconfig\u6587\u4ef6"},{"location":"k8s/cka_cn/foundamentals/rbac/#_4","text":"\u4fdd\u6301\u5f53\u524d\u5de5\u4f5c\u76ee\u5f55\u4e3a /etc/kubernetes/pki \u3002 \u751f\u6210 kubeconfig \u6587\u4ef6\u3002 kubectl config set-cluster kubernetes \\ --certificate-authority = /etc/kubernetes/pki/ca.crt \\ --embed-certs = true \\ --server = ${ APISERVER } \\ --kubeconfig = cka-dev.kubeconfig \u73b0\u5728\u6211\u4eec\u751f\u6210\u4e86\u65b0\u7684\u914d\u7f6e\u6587\u4ef6 cka-dev.kubeconfig \u3002 ll -tr | grep cka-dev \u8f93\u51fa\u7ed3\u679c\uff1a -rw-r--r-- 1 root root 222 Jul 24 08:49 cka-dev-csr.json -rw-r--r-- 1 root root 1281 Jul 24 09:14 cka-dev.pem -rw------- 1 root root 1675 Jul 24 09:14 cka-dev-key.pem -rw-r--r-- 1 root root 1001 Jul 24 09:14 cka-dev.csr -rw------- 1 root root 1671 Jul 24 09:16 cka-dev.kubeconfig \u8bfb\u53d6\u914d\u7f6e\u6587\u4ef6 cka-dev.kubeconfig \u7684\u5185\u5bb9\u3002 cat cka-dev.kubeconfig \u8f93\u51fa\u7684\u5185\u5bb9\uff1a apiVersion : v1 clusters : - cluster : certificate-authority-data : server : https://:6443 name : kubernetes contexts : null current-context : \"\" kind : Config preferences : {} users : null","title":"\u8bbe\u7f6e\u96c6\u7fa4"},{"location":"k8s/cka_cn/foundamentals/rbac/#_5","text":"\u5728\u6587\u4ef6 cka-dev.kubeconfig \u4e2d\uff0c\u7528\u6237\u4fe1\u606f\u8fd9\u90e8\u5206\u662f\u7a7a\u7684\u3002 \u4e0b\u9762\u6211\u4eec\u914d\u7f6e\u4e00\u4e2a\u7528\u6237 cka-dev \u3002 kubectl config set-credentials cka-dev \\ --client-certificate = /etc/kubernetes/pki/cka-dev.pem \\ --client-key = /etc/kubernetes/pki/cka-dev-key.pem \\ --embed-certs = true \\ --kubeconfig = cka-dev.kubeconfig \u73b0\u5728\uff0c\u7528\u6237\u4fe1\u606f\u5df2\u7ecf\u88ab\u6dfb\u52a0\u5230\u914d\u7f6e\u6587\u4ef6 cka-dev.kubeconfig \u4e2d\u4e86\u3002 cat cka-dev.kubeconfig \u8f93\u51fa\u7ed3\u679c\uff1a apiVersion : v1 clusters : - cluster : certificate-authority-data : server : https://:6443 name : kubernetes contexts : null current-context : \"\" kind : Config preferences : {} users : - name : cka-dev user : client-certificate-data : client-key-data : \u81f3\u6b64\u6211\u4eec\u5f97\u5230\u4e86\u4e00\u4e2a\u5b8c\u6574\u7684\u914d\u7f6e\u6587\u4ef6 cka-dev.kubeconfig \u3002 \u7531\u4e8e\u6211\u4eec\u6ca1\u6709\u5728 kubeconfig \u6587\u4ef6\u4e2d\u8bbe\u7f6e\u5f53\u524d\u4e0a\u4e0b\u6587\uff0c\u5f53\u6211\u4eec\u4f7f\u7528\u5b83\u6765\u83b7\u53d6\u8282\u70b9\u4fe1\u606f\u65f6\uff0c\u4f1a\u6536\u5230\u4ee5\u4e0b\u9519\u8bef\u3002 kubectl --kubeconfig = cka-dev.kubeconfig get nodes \u8fd0\u884c\u7ed3\u679c\uff1a The connection to the server localhost:8080 was refused - did you specify the right host or port? \u5f53\u524d\u4e0a\u4e0b\u6587\u5185\u5bb9\u662f\u7a7a\u767d\u3002 kubectl --kubeconfig = cka-dev.kubeconfig config get-contexts \u8f93\u51fa\u7ed3\u679c\uff1a CURRENT NAME CLUSTER AUTHINFO NAMESPACE","title":"\u914d\u7f6e\u7528\u6237"},{"location":"k8s/cka_cn/foundamentals/rbac/#_6","text":"\u914d\u7f6e\u4e0a\u4e0b\u6587\u3002 kubectl config set-context dev --cluster = kubernetes --user = cka-dev --kubeconfig = cka-dev.kubeconfig \u73b0\u5728\u6211\u4eec\u914d\u7f6e\u4e86\u4e0a\u4e0b\u6587\uff0c\u4f46\u5176\u4e2d CURRENT \u4ecd\u7136\u662f\u7a7a\u767d\u3002 kubectl --kubeconfig = cka-dev.kubeconfig config get-contexts \u8fd0\u884c\u7ed3\u679c\uff1a CURRENT NAME CLUSTER AUTHINFO NAMESPACE dev kubernetes cka-dev \u8bbe\u7f6e\u9ed8\u8ba4\u4e0a\u4e0b\u6587\u3002\u4e0a\u4e0b\u6587\u5c06\u4e3a\u591a\u96c6\u7fa4\u73af\u5883\u4e2d\u7684\u96c6\u7fa4\u548c\u7528\u6237\u94fe\u63a5\uff0c\u5e76\u4e14\u6211\u4eec\u53ef\u4ee5\u5207\u6362\u5230\u4e0d\u540c\u7684\u96c6\u7fa4\u3002 kubectl --kubeconfig = cka-dev.kubeconfig config use-context dev","title":"\u914d\u7f6e\u4e0a\u4e0b\u6587"},{"location":"k8s/cka_cn/foundamentals/rbac/#_7","text":"\u73b0\u5728 CURRENT \u5df2\u7ecf\u88ab\u6807\u8bb0\u4e3a * \u4e86\uff0c\u8fd9\u5c31\u8bf4\u660e\u5f53\u524d\u4e0a\u4e0b\u6587\u5df2\u7ecf\u914d\u7f6e\u597d\u4e86\u3002 kubectl --kubeconfig = cka-dev.kubeconfig config get-contexts \u8fd0\u884c\u7ed3\u679c\uff1a CURRENT NAME CLUSTER AUTHINFO NAMESPACE * dev kubernetes cka-dev \u56e0\u4e3a\u7528\u6237 cka-dev \u5728\u8be5\u96c6\u7fa4\u4e2d\u6ca1\u6709\u6388\u6743\uff0c\u6240\u4ee5\u5f53\u6211\u4eec\u5c1d\u8bd5\u83b7\u53d6 Pod \u6216 Node \u7684\u4fe1\u606f\u65f6\uff0c\u4f1a\u6536\u5230\u201c\u7981\u6b62\u8bbf\u95ee\uff08forbidden\uff09\u201d\u9519\u8bef\u3002 kubectl --kubeconfig = /etc/kubernetes/pki/cka-dev.kubeconfig get pod kubectl --kubeconfig = /etc/kubernetes/pki/cka-dev.kubeconfig get node","title":"\u9a8c\u8bc1"},{"location":"k8s/cka_cn/foundamentals/rbac/#kubeconfig_1","text":"\u62f7\u8d1d\u5f53\u524d\u914d\u7f6e\u6587\u4ef6\uff0c\u4f5c\u4e3a\u5907\u4efd\u3002 cp ~/.kube/config ~/.kube/config.old \u628a\u4e24\u4e2a\u914d\u7f6e\u6587\u4ef6\u5408\u5e76\u6210\u4e00\u4e2a\u65b0\u7684\u914d\u7f6e\u6587\u4ef6\uff0c\u5e76\u5b58\u653e\u5728 /tmp/config \u3002 KUBECONFIG = ~/.kube/config:/etc/kubernetes/pki/cka-dev.kubeconfig kubectl config view --flatten > /tmp/config \u7528\u5408\u5e76\u540e\u7684\u65b0\u914d\u7f6e\u6587\u4ef6\u66ff\u6362\u8001\u7684\u914d\u7f6e\u6587\u4ef6\u3002 mv /tmp/config ~/.kube/config \u65b0\u7684\u914d\u7f6e\u6587\u4ef6 ~/.kube/config \u7c7b\u4f3c\u5982\u4e0b\u3002 apiVersion : v1 clusters : - cluster : certificate-authority-data : server : https://:6443 name : kubernetes contexts : - context : cluster : kubernetes user : cka-dev name : dev - context : cluster : kubernetes user : kubernetes-admin name : kubernetes-admin@kubernetes current-context : kubernetes-admin@kubernetes kind : Config preferences : {} users : - name : cka-dev user : client-certificate-data : client-key-data : - name : kubernetes-admin user : client-certificate-data : client-key-data : \u68c0\u67e5\u57fa\u4e8e\u65b0\u7684\u914d\u7f6e\u6587\u4ef6\u4e0b\u7684\u5f53\u524d\u4e0a\u4e0b\u6587\u3002 kubectl config get-contexts \u5f53\u524d\u4e0a\u4e0b\u6587\u662f\u7cfb\u7edf\u9ed8\u8ba4\u914d\u7f6e kubernetes-admin@kubernetes \u3002 CURRENT NAME CLUSTER AUTHINFO NAMESPACE dev kubernetes cka-dev * kubernetes-admin@kubernetes kubernetes kubernetes-admin dev","title":"\u5408\u5e76kubeconfig\u6587\u4ef6"},{"location":"k8s/cka_cn/foundamentals/rbac/#_8","text":"\u67e5\u8be2\u5f53\u524d\u547d\u540d\u7a7a\u95f4namespace\u5217\u8868\u548c\u5bf9\u5e94\u6807\u7b7elabel\u7684\u4fe1\u606f\u3002 kubectl get ns --show-labels \u521b\u5efanamespace cka \u3002 kubectl create namespace cka \u4f7f\u7528\u4ee5\u4e0b\u547d\u4ee4\u66f4\u65b0\u4e0a\u4e0b\u6587\u4fe1\u606f\uff0c\u4f8b\u5982\uff0c\u66f4\u65b0\u9ed8\u8ba4\u547d\u540d\u7a7a\u95f4\u7b49\u3002 kubectl config set-context --cluster = --namespace = --user = \u4e0b\u9762\u9488\u5bf9\u6bcf\u4e2a\u4e0a\u4e0b\u6587context\u8bbe\u5b9a\u9ed8\u8ba4\u7684namespace\u3002 kubectl config set-context kubernetes-admin@kubernetes --cluster = kubernetes --namespace = default --user = kubernetes-admin kubectl config set-context dev --cluster = kubernetes --namespace = cka --user = cka-dev \u68c0\u67e5\u5f53\u524d\u4e0a\u4e0b\u6587context\u7684\u4fe1\u606f\u3002 kubectl config get-contexts \u8f93\u51fa\u7ed3\u679c\uff1a CURRENT NAME CLUSTER AUTHINFO NAMESPACE dev kubernetes cka-dev cka * kubernetes-admin@kubernetes kubernetes kubernetes-admin dev \u901a\u8fc7\u4e0b\u9762\u7684\u547d\u4ee4\uff0c\u53ef\u4ee5\u5207\u6362\u5230\u65b0\u7684context\u3002 kubectl config use-contexts \u4f8b\u5982\uff1a kubectl config use-context dev \u68c0\u67e5\u4e0a\u9762\u7684\u53d8\u66f4\u662f\u5426\u751f\u6548\u3002 kubectl config get-contexts \u8fd0\u884c\u7ed3\u679c\uff1b CURRENT NAME CLUSTER AUTHINFO NAMESPACE * dev kubernetes cka-dev cka kubernetes-admin@kubernetes kubernetes kubernetes-admin dev Be noted, four users beginning with cka-dev created don't have any authorizations, e.g., access namespaces, get pods, etc.. Referring RBAC to grant their authorizations. \u6ce8\u610f\uff1a\u524d\u9762\u521b\u5efa\u7684\u4ee5 cka-dev \u5f00\u5934\u7684\u7528\u6237\u5b9e\u9645\u6ca1\u6709\u4efb\u4f55\u6743\u9650\uff0c\u4f8b\u5982\u8bbf\u95ee\u547d\u540d\u7a7a\u95f4\u3001\u83b7\u53d6 pod \u7b49\uff0c\u4e0b\u9762\u5c06\u901a\u8fc7 RBAC \u6388\u4e88\u4ed6\u4eec\u6388\u6743\u3002","title":"\u547d\u540d\u7a7a\u95f4\u548c\u4e0a\u4e0b\u6587"},{"location":"k8s/cka_cn/foundamentals/rbac/#rolerolebinding","text":"\u5c06\u5f53\u524d\u5de5\u4f5c\u4e0a\u4e0b\u6587\u5207\u6362\u5230 kubernetes-admin@kubernetes \u3002 kubectl config use-context kubernetes-admin@kubernetes \u4f7f\u7528\u5e26\u6709\u9009\u9879 --dry-run=client \u548c -o yaml \u7684 kubectl create role \u547d\u4ee4\uff0c\u751f\u6210\u521b\u5efa\u89d2\u8272role\u7684 yaml \u6a21\u677f\u3002 kubectl create role admin-dev --resource = pods --verb = get --verb = list --verb = watch --dry-run = client -o yaml \u5728namespace cka \u4e0a\u521b\u5efa\u89d2\u8272role admin-dev \u3002 kubectl apply -f - << EOF apiVersion: rbac.authorization.k8s.io/v1 kind: Role metadata: namespace: cka name: admin-dev rules: - apiGroups: - \"\" resources: - pods verbs: - get - watch - list EOF \u4f7f\u7528\u5e26\u6709\u9009\u9879 --dry-run=client \u548c -o yaml \u7684 kubectl create rolebinding \u547d\u4ee4\uff0c\u751f\u6210\u521b\u5efa\u89d2\u8272\u7ed1\u5b9arolebinding\u7684 yaml \u6a21\u677f\u3002 kubectl create rolebinding admin --role = admin-dev --user = cka-dev --dry-run = client -o yaml \u5728namespace cka \u4e0a\u521b\u5efa\u4e00\u4e2a\u89d2\u8272\u7ed1\u5b9arolebinding admin \u3002 kubectl apply -f - << EOF apiVersion: rbac.authorization.k8s.io/v1 kind: RoleBinding metadata: name: admin namespace: cka roleRef: apiGroup: rbac.authorization.k8s.io kind: Role name: admin-dev subjects: - apiGroup: rbac.authorization.k8s.io kind: User name: cka-dev EOF \u9a8c\u8bc1namespace cka \u4e0a\u7684\u7528\u6237 cka-dev \u7684\u6743\u9650\u3002 \u5207\u6362\u5230\u4e0a\u4e0b\u6587 dev \u3002 kubectl config use-context dev \u67e5\u8be2namespace cka \u4e0apod\u7684\u72b6\u6001\uff0c\u6210\u529f\uff01 kubectl get pod -n cka \u67e5\u8be2namespace kube-system \u4e0apod\u7684\u72b6\u6001\uff0c\u5931\u8d25\uff01\u56e0\u4e3a\u524d\u9762\u6dfb\u52a0\u7684\u6743\u9650\u4ec5\u9650\u4e8enamespace cka \u3002 kubectl get pod -n kube-system \u67e5\u8be2\u8282\u70b9node\u7684\u72b6\u6001\uff0c\u5931\u8d25\uff01\u56e0\u4e3a\u5728\u89d2\u8272role\u91cc\u9762\u6211\u4eec\u53ea\u5b9a\u4e49\u4e86pod\u8fd9\u4e00\u79cd\u8d44\u6e90\u3002 kubectl get node \u5728namespace dev \u4e0a\u521b\u5efa\u4e00\u4e2apod\uff0c\u5931\u8d25\uff01\u56e0\u4e3a\u6211\u4eec\u5728\u53ea\u6709\u5bf9pod\u7684 get , watch , list \u4e09\u79cd\u64cd\u4f5c\u6743\u9650\uff0c\u6ca1\u6709 create \u6743\u9650\u3002 kubectl run nginx --image = nginx -n cka","title":"\u89d2\u8272Role\u548c\u89d2\u8272\u7ed1\u5b9aRoleBinding"},{"location":"k8s/cka_cn/foundamentals/rbac/#clusterroleclusterrolebinding","text":"\u5207\u6362\u5230\u4e0a\u4e0b\u6587 kubernetes-admin@kubernetes \u3002 kubectl config use-context kubernetes-admin@kubernetes \u521b\u5efa\u4e00\u4e2a\u540d\u4e3a nodes-admin \u7684 ClusterRole\uff0c\u5b83\u6388\u4e88 get \u3001 watch \u3001 list \u5bf9 nodes \u8d44\u6e90\u7684\u6388\u6743\u3002 kubectl apply -f - < nodeName \u00b6 \u6ce8\u610f\uff0c nodeName \u5177\u6709\u6700\u9ad8\u4f18\u5148\u7ea7\uff0c\u56e0\u4e3a\u5b83\u4e0d\u662f\u7531 Scheduler \u8fdb\u884c\u8c03\u5ea6\u7684\u3002 \u521b\u5efa\u4e00\u4e2a Pod nginx-nodename \uff0c\u5e76\u5c06\u5176\u6307\u5b9a\u5728 cka003 \u8282\u70b9\u4e0a\u3002 kubectl apply -f - < Affinity \u00b6 \u5728 Kubernetes \u96c6\u7fa4\u4e2d\uff0c\u6709\u4e9b Pod \u9700\u8981\u9891\u7e41\u4e0e\u5176\u4ed6 Pod \u8fdb\u884c\u4ea4\u4e92\u3002\u5728\u8fd9\u79cd\u60c5\u51b5\u4e0b\uff0c\u5efa\u8bae\u5c06\u8fd9\u4e9b Pod \u8c03\u5ea6\u5230\u540c\u4e00\u4e2a\u8282\u70b9\u4e0a\u8fd0\u884c\u3002\u4f8b\u5982\uff0c\u4e24\u4e2a Pod\uff1a Nginx \u548c Mysql \uff0c\u5982\u679c\u5b83\u4eec\u9891\u7e41\u901a\u4fe1\uff0c\u5219\u9700\u8981\u5728\u540c\u4e00\u4e2a\u8282\u70b9\u4e0a\u90e8\u7f72\u5b83\u4eec\u3002 \u57fa\u4e8epod\u4e4b\u95f4\u7684\u5173\u7cfb\uff0c\u6211\u4eec\u53ef\u4ee5\u4f7f\u7528 podAffinity \u8fdb\u884c\u9009\u62e9\u3002 podAffinity \u6709\u4e24\u79cd\u8c03\u5ea6\u7c7b\u578b\uff1a requiredDuringSchedulingIgnoredDuringExecution \uff08\u786c\u4eb2\u548c\uff09 preferredDuringSchedulingIgnoredDuringExecution \uff08\u8f6f\u4eb2\u548c\uff09 \u53ef\u4ee5\u4f7f\u7528\u4ee5\u4e0b\u7c7b\u578b\u8bbe\u7f6e topologyKey \uff1a kubernetes.io/hostname \uff03NodeName failure-domain.beta.kubernetes.io/zone \uff03\u533a\u57df Zone failure-domain.beta.kubernetes.io/region # \u533a\u57df Zone \u6211\u4eec\u53ef\u4ee5\u8bbe\u7f6e\u8282\u70b9\u6807\u7b7e\u6765\u5bf9\u8282\u70b9\u7684\u540d\u79f0/\u533a\u57df\u8fdb\u884c\u5206\u7c7b\uff0c\u8fd9\u6837\u5c31\u53ef\u4ee5\u88ab podAffinity \u6240\u4f7f\u7528\u3002 \u521b\u5efapod Nginx \u3002 kubectl apply -f - < ","title":"nodeSelector"},{"location":"k8s/cka_cn/foundamentals/scheduling/#nodename","text":"\u6ce8\u610f\uff0c nodeName \u5177\u6709\u6700\u9ad8\u4f18\u5148\u7ea7\uff0c\u56e0\u4e3a\u5b83\u4e0d\u662f\u7531 Scheduler \u8fdb\u884c\u8c03\u5ea6\u7684\u3002 \u521b\u5efa\u4e00\u4e2a Pod nginx-nodename \uff0c\u5e76\u5c06\u5176\u6307\u5b9a\u5728 cka003 \u8282\u70b9\u4e0a\u3002 kubectl apply -f - < ","title":"nodeName"},{"location":"k8s/cka_cn/foundamentals/scheduling/#affinity","text":"\u5728 Kubernetes \u96c6\u7fa4\u4e2d\uff0c\u6709\u4e9b Pod \u9700\u8981\u9891\u7e41\u4e0e\u5176\u4ed6 Pod \u8fdb\u884c\u4ea4\u4e92\u3002\u5728\u8fd9\u79cd\u60c5\u51b5\u4e0b\uff0c\u5efa\u8bae\u5c06\u8fd9\u4e9b Pod \u8c03\u5ea6\u5230\u540c\u4e00\u4e2a\u8282\u70b9\u4e0a\u8fd0\u884c\u3002\u4f8b\u5982\uff0c\u4e24\u4e2a Pod\uff1a Nginx \u548c Mysql \uff0c\u5982\u679c\u5b83\u4eec\u9891\u7e41\u901a\u4fe1\uff0c\u5219\u9700\u8981\u5728\u540c\u4e00\u4e2a\u8282\u70b9\u4e0a\u90e8\u7f72\u5b83\u4eec\u3002 \u57fa\u4e8epod\u4e4b\u95f4\u7684\u5173\u7cfb\uff0c\u6211\u4eec\u53ef\u4ee5\u4f7f\u7528 podAffinity \u8fdb\u884c\u9009\u62e9\u3002 podAffinity \u6709\u4e24\u79cd\u8c03\u5ea6\u7c7b\u578b\uff1a requiredDuringSchedulingIgnoredDuringExecution \uff08\u786c\u4eb2\u548c\uff09 preferredDuringSchedulingIgnoredDuringExecution \uff08\u8f6f\u4eb2\u548c\uff09 \u53ef\u4ee5\u4f7f\u7528\u4ee5\u4e0b\u7c7b\u578b\u8bbe\u7f6e topologyKey \uff1a kubernetes.io/hostname \uff03NodeName failure-domain.beta.kubernetes.io/zone \uff03\u533a\u57df Zone failure-domain.beta.kubernetes.io/region # \u533a\u57df Zone \u6211\u4eec\u53ef\u4ee5\u8bbe\u7f6e\u8282\u70b9\u6807\u7b7e\u6765\u5bf9\u8282\u70b9\u7684\u540d\u79f0/\u533a\u57df\u8fdb\u884c\u5206\u7c7b\uff0c\u8fd9\u6837\u5c31\u53ef\u4ee5\u88ab podAffinity \u6240\u4f7f\u7528\u3002 \u521b\u5efapod Nginx \u3002 kubectl apply -f - < 80/TCP 14s app=httpd NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES pod/httpd-app-6496d888c9-4nb6z 1/1 Running 0 77s 10.244.102.21 cka003 pod/httpd-app-6496d888c9-b7xht 1/1 Running 0 77s 10.244.112.19 cka002 \u6267\u884c\u4e0b\u9762\u7684\u547d\u4ee4\uff0c\u9a8c\u8bc1\u5bf9pod\u7684IP\u5730\u5740\u7684\u8bbf\u95ee\u3002 curl 10 .244.102.21 curl 10 .244.112.19 \u53ef\u4ee5\u5f97\u5230\u4e0b\u9762\u7684\u4fe1\u606f\uff0c\u8bf4\u660e\u8bbf\u95ee\u6210\u529f\u3002

It works!

\u6267\u884c\u4e0b\u9762\u7684\u547d\u4ee4\uff0c\u9a8c\u8bc1\u901a\u8fc7\u7aef\u53e3\u5bf9ClusterIP\u7684\u8bbf\u95ee\u3002 curl 11 .244.247.7:80 \u53ef\u4ee5\u5f97\u5230\u4e0b\u9762\u7684\u4fe1\u606f\uff0c\u8bf4\u660e\u8bbf\u95ee\u6210\u529f\u3002

It works!

\u66b4\u9732Service \u00b6 \u521b\u5efa\u4e00\u4e2a\u4e34\u65f6\u7684Pod nslookup \uff0c\u5e76\u9644\u52a0\u5230\u5b83\u4ee5\u9a8c\u8bc1DNS\u89e3\u6790\u3002\u9009\u9879 --rm \u8868\u793a\u5728\u9000\u51fa\u540e\u5220\u9664\u8be5Pod\u3002 kubectl run -it nslookup --rm --image = busybox:1.28 \u8fde\u63a5\u5230\u8fd9\u4e2aPod\u540e\uff0c\u8fd0\u884c\u547d\u4ee4 nslookup httpd-app \u3002\u6211\u4eec\u4f1a\u6536\u5230 httpd-app \u670d\u52a1\u7684 ClusterIP \u548c\u5b8c\u6574\u7684\u57df\u540d\u3002 / # nslookup httpd-app Server: 11.244.0.10 Address 1: 11.244.0.10 kube-dns.kube-system.svc.cluster.local Name: httpd-app Address 1: 11.244.247.7 httpd-app.dev.svc.cluster.local \u6211\u4eec\u53ef\u4ee5\u901a\u8fc7\u6267\u884c\u547d\u4ee4 kubectl get pod -o wide \u6765\u5728\u65b0\u7684\u7ec8\u7aef\u4e2d\u68c0\u67e5\u4e34\u65f6 Pod nslookup \u7684 IP \u5730\u5740\u3002Pod nslookup \u7684 IP \u5730\u5740\u4e3a 10.244.112.20 \u3002 kubectl get pod nslookup \u8fd0\u884c\u7ed3\u679c NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES nslookup 1/1 Running 0 2m44s 10.244.112.20 cka002 NodePort \u00b6 \u521b\u5efa\u5e76\u5e94\u7528\u6587\u4ef6 svc-nodeport.yaml \u6765\u521b\u5efaService httpd-app \u3002 kubectl apply -f - < will update configuration to existing resources. Here the Service httpd-app is changed from ClusterIP to NodePort type. No change to the Deployment httpd-app . \u6211\u4eec\u5c06\u6536\u5230\u4ee5\u4e0b\u8f93\u51fa\u3002 \u5176\u4e2d\uff0c\u547d\u4ee4 kubectl apply -f \u5c06\u66f4\u65b0\u73b0\u6709\u8d44\u6e90\u7684\u914d\u7f6e\u3002 \u5728\u8fd9\u91cc\uff0cService httpd-app \u4ece ClusterIP \u7c7b\u578b\u66f4\u6539\u4e3a NodePort \u7c7b\u578b\u3002 \u5bf9Deployment httpd-app \u6ca1\u6709\u4efb\u4f55\u66f4\u6539\u3002 service/httpd-app configured deployment.apps/httpd-app unchanged \u901a\u8fc7\u547d\u4ee4 kubectl get svc \u6765\u68c0\u67e5Service httpd-app \uff0c\u5176\u4e2d\uff1a Service\u7684IP\u5730\u5740\u4e0d\u53d8\u3002 Service\u7684\u7c7b\u578b\u53d8\u4e3a NodePort \u3002 Service\u7684\u7aef\u53e3\u53f7\u4ece 80/TCP \u53d8\u4e3a 80:30080/TCP \u3002 NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE httpd-app NodePort 11.244.247.7 80:30080/TCP 18m \u5728\u6bcf\u4e2a\u8282\u70b9node\u4e0a\u6267\u884c\u547d\u4ee4 curl :30080 \uff0c\u6d4b\u8bd5\u5bf9Service httpd-app \u7684\u8054\u901a\u6027\u3002 curl :30080 curl :30080 curl :30080 \u53ef\u4ee5\u5f97\u5230\u4e0b\u9762\u7684\u4fe1\u606f\uff0c\u8bf4\u660e\u8bbf\u95ee\u6210\u529f\u3002

It works!

Headless Service \u00b6 \u521b\u5efaHeadless Service web \u548cStatefulSet web . kubectl apply -f - < web-1 1/1 Running 0 6s 10.244.112.21 cka002 \u6267\u884c\u547d\u4ee4 kubectl describe svc -l app=web \uff0c\u68c0\u67e5\u521b\u5efa\u7684Service\u7684\u8be6\u7ec6\u4fe1\u606f\u3002 Name : web Namespace : dev Labels : app=web Annotations : Selector : app=web Type : ClusterIP IP Family Policy : SingleStack IP Families : IPv4 IP : None IPs : None Port : web 80/TCP TargetPort : 80/TCP Endpoints : 10.244.102.22:80,10.244.112.21:80 Session Affinity : None Events : \u8fde\u63a5\u5230\u4e34\u65f6Pod nslookup \uff0c\u901a\u8fc7 nslookup \u6765\u9a8c\u8bc1DNS\u5230\u89e3\u6790\u3002 kubectl run -it nslookup --rm --image = busybox:1.28 \u901a\u8fc7 nslookup \u547d\u4ee4\u8bbf\u95eeHeadless Service web \uff0c\u6211\u4eec\u53ef\u4ee5\u5f97\u52302\u4e2apod\u7684IP\u5730\u5740\uff0c\u6ce8\u610f\u4e0d\u662f\u96c6\u7fa4IP\u5730\u5740ClusterIP\uff08\u56e0\u4e3a\u662fHeadless Service\uff09\u3002 / # nslookup web Server: 11.244.0.10 Address 1: 11.244.0.10 kube-dns.kube-system.svc.cluster.local Name: web Address 1: 10.244.112.21 web-1.web.dev.svc.cluster.local Address 2: 10.244.102.22 web-0.web.dev.svc.cluster.local \u6211\u4eec\u4e5f\u53ef\u4ee5\u4f7f\u7528 nslookup \u547d\u4ee4\u6765\u67e5\u627e web-0.web \u548c web-1.web \u3002Headless Service\u7684\u6bcf\u4e2a Pod \u90fd\u6709\u81ea\u5df1\u7684\u670d\u52a1\u540d\u79f0\u7528\u4e8e DNS \u67e5\u627e\u3002 / # nslookup web-0.web Server: 11.244.0.10 Address 1: 11.244.0.10 kube-dns.kube-system.svc.cluster.local Name: web-0.web Address 1: 10.244.102.22 web-0.web.dev.svc.cluster.local / # nslookup web-1.web Server: 11.244.0.10 Address 1: 11.244.0.10 kube-dns.kube-system.svc.cluster.local Name: web-1.web Address 1: 10.244.112.21 web-1.web.dev.svc.cluster.local \u5220\u9664\u4e0a\u9762\u521b\u5efa\u7684\u4e34\u65f6\u8d44\u6e90\u3002 kubectl delete sts web kubectl delete service httpd-app web kubectl delete deployment httpd-app \u670d\u52a1\u5185\u90e8\u6d41\u91cf\u7b56\u7565 \u00b6 Service Internal Traffic Policy\uff08\u670d\u52a1\u5185\u90e8\u6d41\u91cf\u7b56\u7565\uff09\u662fKubernetes\u4e2d\u4e00\u79cd\u7528\u4e8e\u63a7\u5236\u670d\u52a1\u5185\u90e8\u6d41\u91cf\u7684\u7b56\u7565\u3002\u5b83\u7684\u4e3b\u8981\u76ee\u7684\u662f\u63a7\u5236Service\u5bf9\u8c61\u4e2dPod\u7684\u8bbf\u95ee\u7b56\u7565\u3002 \u5728Kubernetes\u4e2d\uff0cService\u5bf9\u8c61\u5c06\u4e00\u4e2a\u865a\u62dfIP\u5730\u5740\u7ed1\u5b9a\u5230\u4e00\u7ec4Pod\u4e0a\uff0c\u4ee5\u4fbf\u53ef\u4ee5\u901a\u8fc7\u8fd9\u4e2a\u865a\u62dfIP\u5730\u5740\u6765\u8bbf\u95ee\u8fd9\u7ec4Pod\u3002Service\u5bf9\u8c61\u5728\u67d0\u79cd\u7a0b\u5ea6\u4e0a\u50cf\u8d1f\u8f7d\u5747\u8861\u5668\uff0c\u53ef\u4ee5\u5c06\u8bf7\u6c42\u6d41\u91cf\u8def\u7531\u5230\u5176\u4e0b\u9762\u7684Pod\u3002 Service\u5bf9\u8c61\u901a\u5e38\u4f1a\u4f7f\u7528\u4ee5\u4e0b\u4e24\u79cd\u7c7b\u578b\u4e4b\u4e00\u6765\u8def\u7531\u6d41\u91cf\uff1a ClusterIP\uff1a\u6b64\u7c7b\u578b\u7684Service\u53ea\u80fd\u4ece\u540c\u4e00Kubernetes\u96c6\u7fa4\u5185\u7684\u5176\u4ed6Pod\u8bbf\u95ee\uff0c\u56e0\u4e3a\u5b83\u662f\u5728Kubernetes\u96c6\u7fa4\u5185\u90e8\u8def\u7531\u8bf7\u6c42\u6d41\u91cf\u7684\u3002 NodePort\uff1a\u6b64\u7c7b\u578b\u7684Service\u5728\u6240\u6709\u8282\u70b9\u4e0a\u516c\u5f00\u4e86\u4e00\u4e2a\u9759\u6001\u7aef\u53e3\uff0c\u4ece\u800c\u53ef\u4ee5\u4ece\u96c6\u7fa4\u5916\u90e8\u8bbf\u95ee\u5b83\u3002\u4f46\u662f\uff0c\u5b83\u4ecd\u7136\u53ef\u4ee5\u4ece\u96c6\u7fa4\u5185\u90e8\u8bbf\u95ee\u3002 Service Internal Traffic Policy\u5b9a\u4e49\u4e86Pod\u5982\u4f55\u8bbf\u95ee\u540c\u4e00\u4e2aService\u4e2d\u7684\u5176\u4ed6Pod\u3002\u53ef\u4ee5\u5c06\u5176\u8bbe\u7f6e\u4e3a\u4ee5\u4e0b\u4e09\u4e2a\u9009\u9879\u4e4b\u4e00\uff1a Cluster\uff1a\u8fd9\u662f\u9ed8\u8ba4\u8bbe\u7f6e\uff0c\u5b83\u5141\u8bb8Service\u4e2d\u7684\u4efb\u4f55Pod\u90fd\u53ef\u4ee5\u8bbf\u95ee\u53e6\u4e00\u4e2aPod\u3002 Local\uff1a\u6b64\u9009\u9879\u5141\u8bb8Pod\u4ec5\u8bbf\u95ee\u5728\u540c\u4e00\u8282\u70b9\u4e0a\u8fd0\u884c\u7684\u5176\u4ed6Pod\u3002\u5982\u679cPod\u9700\u8981\u5feb\u901f\u7684\u3001\u4f4e\u5ef6\u8fdf\u7684\u7f51\u7edc\u8bbf\u95ee\uff0c\u53ef\u4ee5\u4f7f\u7528\u6b64\u9009\u9879\u3002 Disabled\uff1a\u6b64\u9009\u9879\u5c06\u5b8c\u5168\u7981\u6b62Service\u5185\u90e8\u7684\u6d41\u91cf\u3002\u5b83\u9002\u7528\u4e8e\u7279\u5b9a\u7684\u73af\u5883\u548c\u90e8\u7f72\u4e2d\u3002 \u6f14\u793a\u573a\u666f\uff1a \u6a21\u62df Service \u5185\u90e8\u6d41\u91cf\u7b56\u7565\u7684\u5de5\u4f5c\u65b9\u5f0f\u3002 \u9884\u671f\u7ed3\u679c\uff1a \u901a\u8fc7\u8bbe\u7f6e Service \u7684 internalTrafficPolicy: Local \uff0cService \u53ea\u4f1a\u5c06\u6d41\u91cf\u8def\u7531\u5230 Pod \u6240\u5728\u7684\u8282\u70b9\u5185\u90e8\u3002 \u6f14\u793a\u76ee\u7684\uff1a Service Internal Traffic Policy\uff08\u670d\u52a1\u5185\u90e8\u6d41\u91cf\u7b56\u7565\uff09\u53ef\u4ee5\u9650\u5236\u5185\u90e8\u6d41\u91cf\u4ec5\u8def\u7531\u5230\u540c\u4e00\u8282\u70b9\u4e2d\u7684\u7ec8\u7aef\u8282\u70b9\u3002 \u8fd9\u91cc\u7684\u201c\u5185\u90e8\u201d\u6d41\u91cf\u662f\u6307\u6e90\u81ea\u5f53\u524d\u96c6\u7fa4\u4e2d\u7684Pod\u7684\u6d41\u91cf\u3002 \u901a\u8fc7\u5c06\u5176 .spec.internalTrafficPolicy \u8bbe\u7f6e\u4e3a Local\uff0c\u53ef\u4ee5\u544a\u8bc9 kube-proxy \u4ec5\u5bf9\u96c6\u7fa4\u5185\u90e8\u6d41\u91cf\u4f7f\u7528\u672c\u5730\u8282\u70b9\u7684\u7ec8\u7aef\u8282\u70b9\u3002 \u5bf9\u4e8e\u4f4d\u4e8e\u6ca1\u6709\u7ed9\u5b9a\u670d\u52a1\u7684\u7ec8\u7aef\u8282\u70b9\u7684\u8282\u70b9\u4e0a\u7684Pod\uff0c\u5373\u4f7f\u670d\u52a1\u5728\u5176\u4ed6\u8282\u70b9\u4e0a\u6709\u7ec8\u7aef\u8282\u70b9\uff0c\u8be5\u670d\u52a1\u4e5f\u4f1a\u88ab\u89c6\u4e3a\u5728\u8be5\u8282\u70b9\u4e0a\u6ca1\u6709\u7ec8\u7aef\u8282\u70b9\uff08\u5bf9\u4e8e\u8be5\u8282\u70b9\u4e0a\u7684Pod\uff09\u3002 \u6f14\u793a\uff1a \u521b\u5efa Deployment my-nginx \u548c Service my-nginx . kubectl apply -f - << EOF apiVersion: apps/v1 kind: Deployment metadata: name: my-nginx spec: selector: matchLabels: run: my-nginx replicas: 1 template: metadata: labels: run: my-nginx spec: containers: - name: my-nginx image: nginx ports: - containerPort: 80 --- apiVersion: v1 kind: Service metadata: name: my-nginx labels: run: my-nginx spec: ports: - port: 80 protocol: TCP selector: run: my-nginx EOF \u4f7f\u7528\u547d\u4ee4 kubectl get pod -o wide \uff0c\u6211\u4eec\u53ef\u4ee5\u5f97\u77e5 Deployment my-nginx \u7684 Pod \u6b63\u5728\u8fd0\u884c\u5728 cka003 \u8282\u70b9\u4e0a\u3002 NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES my-nginx-cf54cdbf7-bscf8 1/1 Running 0 9h 10.244.112.63 cka002 \u8ba9\u6211\u4eec\u4ece cka001 \u53d1\u9001 http \u8bf7\u6c42\u5230\u8fd0\u884c\u5728 cka002 \u4e0a\u7684 Pod\u3002 \u6211\u4eec\u5c06\u6536\u5230 Welcome to nginx! \u4fe1\u606f\uff0c\u8fd9\u610f\u5473\u7740\u8be5 Pod \u53ef\u4ee5\u4ece\u5176\u4ed6\u8282\u70b9\u8bbf\u95ee\u3002 curl 11 .244.163.60 \u73b0\u5728\u6765\u4fee\u6539Service my-nginx \u5e76\u6307\u5b9a internalTrafficPolicy: Local \u3002 kubectl apply -f - << EOF apiVersion: v1 kind: Service metadata: name: my-nginx labels: run: my-nginx spec: ports: - port: 80 protocol: TCP selector: run: my-nginx internalTrafficPolicy: Local EOF Let's send http request from cka001 to the http request to the Pod again. We will receive curl: (7) Failed to connect to 11.244.163.60 port 80: Connection refused error information. \u6211\u4eec\u518d\u6b21\u4ece cka001 \u53d1\u9001http\u8bf7\u6c42\u5230\u8be5Pod\u3002 \u6211\u4eec\u5c06\u6536\u5230\u9519\u8bef\u4fe1\u606f curl: (7) Failed to connect to 11.244.163.60 port 80: Connection refused \u3002 curl 11 .244.163.60 \u8ba9\u6211\u4eec\u767b\u5f55\u5230 cka002 \u8282\u70b9\u5e76\u518d\u6b21\u5411 Pod \u53d1\u9001 HTTP \u8bf7\u6c42\u3002 \u6211\u4eec\u5c06\u6536\u5230 Welcome to nginx! \u7684\u4fe1\u606f\u3002 curl 11 .244.163.60 \u6f14\u793a\u7ed3\u8bba\uff1a \u8bbe\u7f6e Service \u7684 internalTrafficPolicy: Local \u540e\uff0cService \u53ea\u4f1a\u5c06\u6d41\u91cf\u8def\u7531\u5230\u5f53\u524d Pod \u6240\u5728\u7684\u8282\u70b9\u5185\u90e8\u7684 Pod\u3002 \u6f14\u793a\u573a\u666f\uff1a \u521b\u5efa\u4e00\u4e2a nginx Deployment \u6dfb\u52a0 nginx Pod\u7684\u7aef\u53e3\u53f7\u548c\u522b\u540d \u4f7f\u7528\u672c\u5730\u6d41\u91cf\u5c06Deployment\u66b4\u9732\u51fa\u53bb\u3002 \u6f14\u793a\uff1a \u4f7f\u7528\u7aef\u53e3\u53f7\u4e3a 80 \u521b\u5efa my-nginx Deployment\u3002 kubectl create deployment my-nginx --image = nginx --port = 80 \u4fee\u6539Deployment\u3002 kubectl edit deployment my-nginx \u5728 my-nginx Deployment\u4e2d\u6dfb\u52a0\u7aef\u53e3\u522b\u540d http \u3002 \u8bf7\u53c2\u8003\u4ee5\u4e0b\u90e8\u7f72\u7684 YAML \u6a21\u677f\u94fe\u63a5\uff1a https://kubernetes.io/docs/concepts/workloads/controllers/deployment/ \u3002 spec : containers : - image : nginx imagePullPolicy : Always name : nginx ports : - containerPort : 80 protocol : TCP name : http \u4f7f\u7528 NodePort \u7c7b\u578b\u66b4\u9732 deployment\u3002 kubectl expose deployment my-nginx --port = 80 --target-port = http --name = my-nginx-svc --type = NodePort \u4fee\u6539service\uff0c\u628a internalTrafficPolicy \u4ece Cluster \u6539\u4e3a Local \u3002 kubectl edit svc my-nginx-svc \u9a8c\u8bc1\u8bbf\u95ee\u3002 \u6ce8\u610f\uff0cPod \u6b63\u5728\u8fd0\u884c\u5728\u8282\u70b9 cka003 \u4e0a\u3002\u6211\u4eec\u5c06\u770b\u5230\u4ee5\u4e0b\u9884\u671f\u7ed3\u679c\u3002 curl :80 # succeed on node cka003. internalTrafficPolicy is effective. curl :80 # succeed on all nodes. curl : # succeed on all nodes.","title":"Service"},{"location":"k8s/cka_cn/foundamentals/service/#cka10service","text":"","title":"CKA\u81ea\u5b66\u7b14\u8bb010:Service"},{"location":"k8s/cka_cn/foundamentals/service/#_1","text":"\u6f14\u793a\u573a\u666f\uff1a \u521b\u5efa\u540d\u4e3a httpd-app \u7684Deployment\u3002 \u521b\u5efa\u7c7b\u578b\u4e3a ClusterIP \u7684 httpd-app \u670d\u52a1\uff0c\u9ed8\u8ba4\u7c7b\u578b\u662f ClusterIP\uff0c\u53ea\u80fd\u5185\u90e8\u8bbf\u95ee\u3002 \u9a8c\u8bc1\u5bf9Pod\u7684IP\u548c\u670d\u52a1\u7684\u96c6\u7fa4IP\u7684\u8bbf\u95ee\u3002 \u5c06 httpd-app \u670d\u52a1\u7c7b\u578b\u66f4\u65b0\u4e3a NodePort \uff0c\u4e0d\u9700\u8981\u5bf9 httpd-app \u8fd9\u4e2aDeployment\u8fdb\u884c\u4efb\u4f55\u66f4\u6539\u3002 \u9a8c\u8bc1\u8282\u70b9node\u7684\u8bbf\u95ee\u3002\u5bf9\u8282\u70b9node\u5bf9\u8bbf\u95ee\u5c06\u88ab\u8def\u7531\u5230Pod\uff0c\u4ece\u800c\u5b9e\u73b0\u4ece\u5916\u90e8\u8bbf\u95ee\u6211\u4eec\u521b\u5efa\u7684\u670d\u52a1 httpd-app \u3002 \u521b\u5efa\u65e0\u5934\u670d\u52a1\uff08Headless Service\uff09 web \u548c \u6709\u72b6\u6001\u526f\u672c\u96c6\uff08StatefulSet\uff09 web \u3002 \u670d\u52a1\u7684\u5185\u90e8\u6d41\u91cf\u7b56\u7565\u3002 NodePort \u53ef\u4ee5\u7ffb\u8bd1\u4e3a\u201c\u8282\u70b9\u7aef\u53e3\u201d\uff0c\u662f\u4e00\u79cdService\u7684\u7c7b\u578b\uff0c\u53ef\u4ee5\u901a\u8fc7\u5728\u6bcf\u4e2a\u8282\u70b9\u4e0a\u6253\u5f00\u4e00\u4e2a\u7aef\u53e3\uff0c\u5c06Service\u66b4\u9732\u5230\u96c6\u7fa4\u5916\u90e8\u3002 ClusterIP \u53ef\u4ee5\u7ffb\u8bd1\u4e3a\u201c\u96c6\u7fa4IP\u201d\uff0c\u4e5f\u662f\u4e00\u79cdService\u7684\u7c7b\u578b\uff0c\u4e3aService\u63d0\u4f9b\u4e86\u4e00\u4e2a\u865a\u62dfIP\u5730\u5740\uff0c\u53ef\u4ee5\u5728\u96c6\u7fa4\u5185\u90e8\u8fdb\u884c\u8bbf\u95ee\u3002\u8fd9\u4e2aIP\u5730\u5740\u901a\u5e38\u7531\u96c6\u7fa4\u4e2d\u7684Kubernetes\u4ee3\u7406\u81ea\u52a8\u5206\u914d\uff0c\u5e76\u4e14\u53ea\u80fd\u5728\u96c6\u7fa4\u5185\u90e8\u4f7f\u7528\u3002","title":"\u6458\u8981"},{"location":"k8s/cka_cn/foundamentals/service/#clusterip","text":"","title":"ClusterIP"},{"location":"k8s/cka_cn/foundamentals/service/#service","text":"\u521b\u5efaDeployment http-app \u3002 \u521b\u5efaService httpd-app \u5e76\u901a\u8fc7\u6807\u7b7e\u9009\u62e9\u5668\uff08Label Selector\uff09\u5173\u8054\u5230Development http-app \u3002 Service\u7684\u7c7b\u578b\u662f ClusterIP \uff0c\u8fd9\u662fService\u7684\u9ed8\u8ba4\u7c7b\u578b\uff0c\u53ea\u9650\u4e8e\u5185\u90e8\u8bbf\u95ee\u3002 kubectl apply -f - < 80/TCP 14s app=httpd NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES pod/httpd-app-6496d888c9-4nb6z 1/1 Running 0 77s 10.244.102.21 cka003 pod/httpd-app-6496d888c9-b7xht 1/1 Running 0 77s 10.244.112.19 cka002 \u6267\u884c\u4e0b\u9762\u7684\u547d\u4ee4\uff0c\u9a8c\u8bc1\u5bf9pod\u7684IP\u5730\u5740\u7684\u8bbf\u95ee\u3002 curl 10 .244.102.21 curl 10 .244.112.19 \u53ef\u4ee5\u5f97\u5230\u4e0b\u9762\u7684\u4fe1\u606f\uff0c\u8bf4\u660e\u8bbf\u95ee\u6210\u529f\u3002

It works!

\u6267\u884c\u4e0b\u9762\u7684\u547d\u4ee4\uff0c\u9a8c\u8bc1\u901a\u8fc7\u7aef\u53e3\u5bf9ClusterIP\u7684\u8bbf\u95ee\u3002 curl 11 .244.247.7:80 \u53ef\u4ee5\u5f97\u5230\u4e0b\u9762\u7684\u4fe1\u606f\uff0c\u8bf4\u660e\u8bbf\u95ee\u6210\u529f\u3002

It works!

","title":"\u521b\u5efaService"},{"location":"k8s/cka_cn/foundamentals/service/#service_1","text":"\u521b\u5efa\u4e00\u4e2a\u4e34\u65f6\u7684Pod nslookup \uff0c\u5e76\u9644\u52a0\u5230\u5b83\u4ee5\u9a8c\u8bc1DNS\u89e3\u6790\u3002\u9009\u9879 --rm \u8868\u793a\u5728\u9000\u51fa\u540e\u5220\u9664\u8be5Pod\u3002 kubectl run -it nslookup --rm --image = busybox:1.28 \u8fde\u63a5\u5230\u8fd9\u4e2aPod\u540e\uff0c\u8fd0\u884c\u547d\u4ee4 nslookup httpd-app \u3002\u6211\u4eec\u4f1a\u6536\u5230 httpd-app \u670d\u52a1\u7684 ClusterIP \u548c\u5b8c\u6574\u7684\u57df\u540d\u3002 / # nslookup httpd-app Server: 11.244.0.10 Address 1: 11.244.0.10 kube-dns.kube-system.svc.cluster.local Name: httpd-app Address 1: 11.244.247.7 httpd-app.dev.svc.cluster.local \u6211\u4eec\u53ef\u4ee5\u901a\u8fc7\u6267\u884c\u547d\u4ee4 kubectl get pod -o wide \u6765\u5728\u65b0\u7684\u7ec8\u7aef\u4e2d\u68c0\u67e5\u4e34\u65f6 Pod nslookup \u7684 IP \u5730\u5740\u3002Pod nslookup \u7684 IP \u5730\u5740\u4e3a 10.244.112.20 \u3002 kubectl get pod nslookup \u8fd0\u884c\u7ed3\u679c NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES nslookup 1/1 Running 0 2m44s 10.244.112.20 cka002 ","title":"\u66b4\u9732Service"},{"location":"k8s/cka_cn/foundamentals/service/#nodeport","text":"\u521b\u5efa\u5e76\u5e94\u7528\u6587\u4ef6 svc-nodeport.yaml \u6765\u521b\u5efaService httpd-app \u3002 kubectl apply -f - < will update configuration to existing resources. Here the Service httpd-app is changed from ClusterIP to NodePort type. No change to the Deployment httpd-app . \u6211\u4eec\u5c06\u6536\u5230\u4ee5\u4e0b\u8f93\u51fa\u3002 \u5176\u4e2d\uff0c\u547d\u4ee4 kubectl apply -f \u5c06\u66f4\u65b0\u73b0\u6709\u8d44\u6e90\u7684\u914d\u7f6e\u3002 \u5728\u8fd9\u91cc\uff0cService httpd-app \u4ece ClusterIP \u7c7b\u578b\u66f4\u6539\u4e3a NodePort \u7c7b\u578b\u3002 \u5bf9Deployment httpd-app \u6ca1\u6709\u4efb\u4f55\u66f4\u6539\u3002 service/httpd-app configured deployment.apps/httpd-app unchanged \u901a\u8fc7\u547d\u4ee4 kubectl get svc \u6765\u68c0\u67e5Service httpd-app \uff0c\u5176\u4e2d\uff1a Service\u7684IP\u5730\u5740\u4e0d\u53d8\u3002 Service\u7684\u7c7b\u578b\u53d8\u4e3a NodePort \u3002 Service\u7684\u7aef\u53e3\u53f7\u4ece 80/TCP \u53d8\u4e3a 80:30080/TCP \u3002 NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE httpd-app NodePort 11.244.247.7 80:30080/TCP 18m \u5728\u6bcf\u4e2a\u8282\u70b9node\u4e0a\u6267\u884c\u547d\u4ee4 curl :30080 \uff0c\u6d4b\u8bd5\u5bf9Service httpd-app \u7684\u8054\u901a\u6027\u3002 curl :30080 curl :30080 curl :30080 \u53ef\u4ee5\u5f97\u5230\u4e0b\u9762\u7684\u4fe1\u606f\uff0c\u8bf4\u660e\u8bbf\u95ee\u6210\u529f\u3002

It works!

","title":"NodePort"},{"location":"k8s/cka_cn/foundamentals/service/#headless-service","text":"\u521b\u5efaHeadless Service web \u548cStatefulSet web . kubectl apply -f - < web-1 1/1 Running 0 6s 10.244.112.21 cka002 \u6267\u884c\u547d\u4ee4 kubectl describe svc -l app=web \uff0c\u68c0\u67e5\u521b\u5efa\u7684Service\u7684\u8be6\u7ec6\u4fe1\u606f\u3002 Name : web Namespace : dev Labels : app=web Annotations : Selector : app=web Type : ClusterIP IP Family Policy : SingleStack IP Families : IPv4 IP : None IPs : None Port : web 80/TCP TargetPort : 80/TCP Endpoints : 10.244.102.22:80,10.244.112.21:80 Session Affinity : None Events : \u8fde\u63a5\u5230\u4e34\u65f6Pod nslookup \uff0c\u901a\u8fc7 nslookup \u6765\u9a8c\u8bc1DNS\u5230\u89e3\u6790\u3002 kubectl run -it nslookup --rm --image = busybox:1.28 \u901a\u8fc7 nslookup \u547d\u4ee4\u8bbf\u95eeHeadless Service web \uff0c\u6211\u4eec\u53ef\u4ee5\u5f97\u52302\u4e2apod\u7684IP\u5730\u5740\uff0c\u6ce8\u610f\u4e0d\u662f\u96c6\u7fa4IP\u5730\u5740ClusterIP\uff08\u56e0\u4e3a\u662fHeadless Service\uff09\u3002 / # nslookup web Server: 11.244.0.10 Address 1: 11.244.0.10 kube-dns.kube-system.svc.cluster.local Name: web Address 1: 10.244.112.21 web-1.web.dev.svc.cluster.local Address 2: 10.244.102.22 web-0.web.dev.svc.cluster.local \u6211\u4eec\u4e5f\u53ef\u4ee5\u4f7f\u7528 nslookup \u547d\u4ee4\u6765\u67e5\u627e web-0.web \u548c web-1.web \u3002Headless Service\u7684\u6bcf\u4e2a Pod \u90fd\u6709\u81ea\u5df1\u7684\u670d\u52a1\u540d\u79f0\u7528\u4e8e DNS \u67e5\u627e\u3002 / # nslookup web-0.web Server: 11.244.0.10 Address 1: 11.244.0.10 kube-dns.kube-system.svc.cluster.local Name: web-0.web Address 1: 10.244.102.22 web-0.web.dev.svc.cluster.local / # nslookup web-1.web Server: 11.244.0.10 Address 1: 11.244.0.10 kube-dns.kube-system.svc.cluster.local Name: web-1.web Address 1: 10.244.112.21 web-1.web.dev.svc.cluster.local \u5220\u9664\u4e0a\u9762\u521b\u5efa\u7684\u4e34\u65f6\u8d44\u6e90\u3002 kubectl delete sts web kubectl delete service httpd-app web kubectl delete deployment httpd-app","title":"Headless Service"},{"location":"k8s/cka_cn/foundamentals/service/#_2","text":"Service Internal Traffic Policy\uff08\u670d\u52a1\u5185\u90e8\u6d41\u91cf\u7b56\u7565\uff09\u662fKubernetes\u4e2d\u4e00\u79cd\u7528\u4e8e\u63a7\u5236\u670d\u52a1\u5185\u90e8\u6d41\u91cf\u7684\u7b56\u7565\u3002\u5b83\u7684\u4e3b\u8981\u76ee\u7684\u662f\u63a7\u5236Service\u5bf9\u8c61\u4e2dPod\u7684\u8bbf\u95ee\u7b56\u7565\u3002 \u5728Kubernetes\u4e2d\uff0cService\u5bf9\u8c61\u5c06\u4e00\u4e2a\u865a\u62dfIP\u5730\u5740\u7ed1\u5b9a\u5230\u4e00\u7ec4Pod\u4e0a\uff0c\u4ee5\u4fbf\u53ef\u4ee5\u901a\u8fc7\u8fd9\u4e2a\u865a\u62dfIP\u5730\u5740\u6765\u8bbf\u95ee\u8fd9\u7ec4Pod\u3002Service\u5bf9\u8c61\u5728\u67d0\u79cd\u7a0b\u5ea6\u4e0a\u50cf\u8d1f\u8f7d\u5747\u8861\u5668\uff0c\u53ef\u4ee5\u5c06\u8bf7\u6c42\u6d41\u91cf\u8def\u7531\u5230\u5176\u4e0b\u9762\u7684Pod\u3002 Service\u5bf9\u8c61\u901a\u5e38\u4f1a\u4f7f\u7528\u4ee5\u4e0b\u4e24\u79cd\u7c7b\u578b\u4e4b\u4e00\u6765\u8def\u7531\u6d41\u91cf\uff1a ClusterIP\uff1a\u6b64\u7c7b\u578b\u7684Service\u53ea\u80fd\u4ece\u540c\u4e00Kubernetes\u96c6\u7fa4\u5185\u7684\u5176\u4ed6Pod\u8bbf\u95ee\uff0c\u56e0\u4e3a\u5b83\u662f\u5728Kubernetes\u96c6\u7fa4\u5185\u90e8\u8def\u7531\u8bf7\u6c42\u6d41\u91cf\u7684\u3002 NodePort\uff1a\u6b64\u7c7b\u578b\u7684Service\u5728\u6240\u6709\u8282\u70b9\u4e0a\u516c\u5f00\u4e86\u4e00\u4e2a\u9759\u6001\u7aef\u53e3\uff0c\u4ece\u800c\u53ef\u4ee5\u4ece\u96c6\u7fa4\u5916\u90e8\u8bbf\u95ee\u5b83\u3002\u4f46\u662f\uff0c\u5b83\u4ecd\u7136\u53ef\u4ee5\u4ece\u96c6\u7fa4\u5185\u90e8\u8bbf\u95ee\u3002 Service Internal Traffic Policy\u5b9a\u4e49\u4e86Pod\u5982\u4f55\u8bbf\u95ee\u540c\u4e00\u4e2aService\u4e2d\u7684\u5176\u4ed6Pod\u3002\u53ef\u4ee5\u5c06\u5176\u8bbe\u7f6e\u4e3a\u4ee5\u4e0b\u4e09\u4e2a\u9009\u9879\u4e4b\u4e00\uff1a Cluster\uff1a\u8fd9\u662f\u9ed8\u8ba4\u8bbe\u7f6e\uff0c\u5b83\u5141\u8bb8Service\u4e2d\u7684\u4efb\u4f55Pod\u90fd\u53ef\u4ee5\u8bbf\u95ee\u53e6\u4e00\u4e2aPod\u3002 Local\uff1a\u6b64\u9009\u9879\u5141\u8bb8Pod\u4ec5\u8bbf\u95ee\u5728\u540c\u4e00\u8282\u70b9\u4e0a\u8fd0\u884c\u7684\u5176\u4ed6Pod\u3002\u5982\u679cPod\u9700\u8981\u5feb\u901f\u7684\u3001\u4f4e\u5ef6\u8fdf\u7684\u7f51\u7edc\u8bbf\u95ee\uff0c\u53ef\u4ee5\u4f7f\u7528\u6b64\u9009\u9879\u3002 Disabled\uff1a\u6b64\u9009\u9879\u5c06\u5b8c\u5168\u7981\u6b62Service\u5185\u90e8\u7684\u6d41\u91cf\u3002\u5b83\u9002\u7528\u4e8e\u7279\u5b9a\u7684\u73af\u5883\u548c\u90e8\u7f72\u4e2d\u3002 \u6f14\u793a\u573a\u666f\uff1a \u6a21\u62df Service \u5185\u90e8\u6d41\u91cf\u7b56\u7565\u7684\u5de5\u4f5c\u65b9\u5f0f\u3002 \u9884\u671f\u7ed3\u679c\uff1a \u901a\u8fc7\u8bbe\u7f6e Service \u7684 internalTrafficPolicy: Local \uff0cService \u53ea\u4f1a\u5c06\u6d41\u91cf\u8def\u7531\u5230 Pod \u6240\u5728\u7684\u8282\u70b9\u5185\u90e8\u3002 \u6f14\u793a\u76ee\u7684\uff1a Service Internal Traffic Policy\uff08\u670d\u52a1\u5185\u90e8\u6d41\u91cf\u7b56\u7565\uff09\u53ef\u4ee5\u9650\u5236\u5185\u90e8\u6d41\u91cf\u4ec5\u8def\u7531\u5230\u540c\u4e00\u8282\u70b9\u4e2d\u7684\u7ec8\u7aef\u8282\u70b9\u3002 \u8fd9\u91cc\u7684\u201c\u5185\u90e8\u201d\u6d41\u91cf\u662f\u6307\u6e90\u81ea\u5f53\u524d\u96c6\u7fa4\u4e2d\u7684Pod\u7684\u6d41\u91cf\u3002 \u901a\u8fc7\u5c06\u5176 .spec.internalTrafficPolicy \u8bbe\u7f6e\u4e3a Local\uff0c\u53ef\u4ee5\u544a\u8bc9 kube-proxy \u4ec5\u5bf9\u96c6\u7fa4\u5185\u90e8\u6d41\u91cf\u4f7f\u7528\u672c\u5730\u8282\u70b9\u7684\u7ec8\u7aef\u8282\u70b9\u3002 \u5bf9\u4e8e\u4f4d\u4e8e\u6ca1\u6709\u7ed9\u5b9a\u670d\u52a1\u7684\u7ec8\u7aef\u8282\u70b9\u7684\u8282\u70b9\u4e0a\u7684Pod\uff0c\u5373\u4f7f\u670d\u52a1\u5728\u5176\u4ed6\u8282\u70b9\u4e0a\u6709\u7ec8\u7aef\u8282\u70b9\uff0c\u8be5\u670d\u52a1\u4e5f\u4f1a\u88ab\u89c6\u4e3a\u5728\u8be5\u8282\u70b9\u4e0a\u6ca1\u6709\u7ec8\u7aef\u8282\u70b9\uff08\u5bf9\u4e8e\u8be5\u8282\u70b9\u4e0a\u7684Pod\uff09\u3002 \u6f14\u793a\uff1a \u521b\u5efa Deployment my-nginx \u548c Service my-nginx . kubectl apply -f - << EOF apiVersion: apps/v1 kind: Deployment metadata: name: my-nginx spec: selector: matchLabels: run: my-nginx replicas: 1 template: metadata: labels: run: my-nginx spec: containers: - name: my-nginx image: nginx ports: - containerPort: 80 --- apiVersion: v1 kind: Service metadata: name: my-nginx labels: run: my-nginx spec: ports: - port: 80 protocol: TCP selector: run: my-nginx EOF \u4f7f\u7528\u547d\u4ee4 kubectl get pod -o wide \uff0c\u6211\u4eec\u53ef\u4ee5\u5f97\u77e5 Deployment my-nginx \u7684 Pod \u6b63\u5728\u8fd0\u884c\u5728 cka003 \u8282\u70b9\u4e0a\u3002 NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES my-nginx-cf54cdbf7-bscf8 1/1 Running 0 9h 10.244.112.63 cka002 \u8ba9\u6211\u4eec\u4ece cka001 \u53d1\u9001 http \u8bf7\u6c42\u5230\u8fd0\u884c\u5728 cka002 \u4e0a\u7684 Pod\u3002 \u6211\u4eec\u5c06\u6536\u5230 Welcome to nginx! \u4fe1\u606f\uff0c\u8fd9\u610f\u5473\u7740\u8be5 Pod \u53ef\u4ee5\u4ece\u5176\u4ed6\u8282\u70b9\u8bbf\u95ee\u3002 curl 11 .244.163.60 \u73b0\u5728\u6765\u4fee\u6539Service my-nginx \u5e76\u6307\u5b9a internalTrafficPolicy: Local \u3002 kubectl apply -f - << EOF apiVersion: v1 kind: Service metadata: name: my-nginx labels: run: my-nginx spec: ports: - port: 80 protocol: TCP selector: run: my-nginx internalTrafficPolicy: Local EOF Let's send http request from cka001 to the http request to the Pod again. We will receive curl: (7) Failed to connect to 11.244.163.60 port 80: Connection refused error information. \u6211\u4eec\u518d\u6b21\u4ece cka001 \u53d1\u9001http\u8bf7\u6c42\u5230\u8be5Pod\u3002 \u6211\u4eec\u5c06\u6536\u5230\u9519\u8bef\u4fe1\u606f curl: (7) Failed to connect to 11.244.163.60 port 80: Connection refused \u3002 curl 11 .244.163.60 \u8ba9\u6211\u4eec\u767b\u5f55\u5230 cka002 \u8282\u70b9\u5e76\u518d\u6b21\u5411 Pod \u53d1\u9001 HTTP \u8bf7\u6c42\u3002 \u6211\u4eec\u5c06\u6536\u5230 Welcome to nginx! \u7684\u4fe1\u606f\u3002 curl 11 .244.163.60 \u6f14\u793a\u7ed3\u8bba\uff1a \u8bbe\u7f6e Service \u7684 internalTrafficPolicy: Local \u540e\uff0cService \u53ea\u4f1a\u5c06\u6d41\u91cf\u8def\u7531\u5230\u5f53\u524d Pod \u6240\u5728\u7684\u8282\u70b9\u5185\u90e8\u7684 Pod\u3002 \u6f14\u793a\u573a\u666f\uff1a \u521b\u5efa\u4e00\u4e2a nginx Deployment \u6dfb\u52a0 nginx Pod\u7684\u7aef\u53e3\u53f7\u548c\u522b\u540d \u4f7f\u7528\u672c\u5730\u6d41\u91cf\u5c06Deployment\u66b4\u9732\u51fa\u53bb\u3002 \u6f14\u793a\uff1a \u4f7f\u7528\u7aef\u53e3\u53f7\u4e3a 80 \u521b\u5efa my-nginx Deployment\u3002 kubectl create deployment my-nginx --image = nginx --port = 80 \u4fee\u6539Deployment\u3002 kubectl edit deployment my-nginx \u5728 my-nginx Deployment\u4e2d\u6dfb\u52a0\u7aef\u53e3\u522b\u540d http \u3002 \u8bf7\u53c2\u8003\u4ee5\u4e0b\u90e8\u7f72\u7684 YAML \u6a21\u677f\u94fe\u63a5\uff1a https://kubernetes.io/docs/concepts/workloads/controllers/deployment/ \u3002 spec : containers : - image : nginx imagePullPolicy : Always name : nginx ports : - containerPort : 80 protocol : TCP name : http \u4f7f\u7528 NodePort \u7c7b\u578b\u66b4\u9732 deployment\u3002 kubectl expose deployment my-nginx --port = 80 --target-port = http --name = my-nginx-svc --type = NodePort \u4fee\u6539service\uff0c\u628a internalTrafficPolicy \u4ece Cluster \u6539\u4e3a Local \u3002 kubectl edit svc my-nginx-svc \u9a8c\u8bc1\u8bbf\u95ee\u3002 \u6ce8\u610f\uff0cPod \u6b63\u5728\u8fd0\u884c\u5728\u8282\u70b9 cka003 \u4e0a\u3002\u6211\u4eec\u5c06\u770b\u5230\u4ee5\u4e0b\u9884\u671f\u7ed3\u679c\u3002 curl :80 # succeed on node cka003. internalTrafficPolicy is effective. curl :80 # succeed on all nodes. curl : # succeed on all nodes.","title":"\u670d\u52a1\u5185\u90e8\u6d41\u91cf\u7b56\u7565"},{"location":"k8s/cka_cn/foundamentals/statefulset/","text":"CKA\u81ea\u5b66\u7b14\u8bb012:StatefulSet \u00b6 \u6f14\u793a\u573a\u666f \u00b6 \u521b\u5efa\u4e00\u4e2a Headless Service nginx \u548c\u4e00\u4e2aStatefulSet web \u6269\u5c55 StatefulSet web \u6f14\u793a \u00b6 \u521b\u5efa\u4e00\u4e2a Headless Service nginx \u548c\u4e00\u4e2aStatefulSet web kubectl apply -f - << EOF --- apiVersion: v1 kind: Service metadata: name: nginx labels: app: nginx spec: ports: - port: 80 name: web clusterIP: None selector: app: nginx --- apiVersion: apps/v1 kind: StatefulSet metadata: name: web spec: serviceName: \"nginx\" replicas: 2 selector: matchLabels: app: nginx template: metadata: labels: app: nginx spec: containers: - name: nginx image: nginx ports: - containerPort: 80 name: web EOF \u8bfb\u53d6\u4e0a\u4e00\u6b65\u521b\u5efa\u7684StatefulSet Pod \u7684\u8be6\u7ec6\u4fe1\u606f\u3002 kubectl get pod | grep web \u8fd0\u884c\u7ed3\u679c NAME READY STATUS RESTARTS AGE web-0 1 /1 Running 0 27s web-1 1 /1 Running 0 10s \u4f7f\u7528\u547d\u4ee4 kubectl edit sts web \u66f4\u65b0\u73b0\u6709\u7684 StatefulSet\u3002 \u53ea\u6709\u4ee5\u4e0b\u5b57\u6bb5\u53ef\u4ee5\u66f4\u65b0\uff1a replicas \u3001 image \u3001 rolling updates \u3001 labels \u3001 resource request/limit \u548c annotations \u3002 \u6ce8\u610f\uff1a\u5f53 StatefulSet Pod \u5728\u5f53\u524d\u8282\u70b9\u4e2d\u6b7b\u4ea1\u65f6\uff0c\u4e0d\u4f1a\u81ea\u52a8\u5728\u5176\u4ed6\u8282\u70b9\u4e2d\u521b\u5efa\u526f\u672c\u3002 \u6269\u5c55 StatefulSet\u3002 \u5c06 StatefulSet web \u7684\u526f\u672c\u6570\u6269\u5c55\u5230 5 \u3002 kubectl scale sts web --replicas = 5 \u53c2\u8003\uff1a Partition\u8868\u793a\u5728\u66f4\u65b0\u671f\u95f4\u5e94\u5c06 StatefulSet \u5212\u5206\u4e3a\u54ea\u4e2a\u5e8f\u53f7\u3002 \u5728\u6eda\u52a8\u66f4\u65b0\u671f\u95f4\uff0c\u4ece\u5e8f\u53f7 Replicas-1 \u5230 Partition \u7684\u6240\u6709 Pod \u90fd\u4f1a\u66f4\u65b0\u3002 \u4ece\u5e8f\u53f7 Partition-1 \u5230 0 \u7684\u6240\u6709 Pod \u90fd\u4fdd\u6301\u4e0d\u53d8\u3002\u8fd9\u5bf9\u4e8e\u8fdb\u884c\u91d1\u4e1d\u96c0\u90e8\u7f72\u975e\u5e38\u6709\u7528\u3002\u9ed8\u8ba4\u503c\u4e3a0\u3002 \u547d\u4ee4\uff1a kubectl explain statefulsets.spec.updateStrategy.rollingUpdate.partition \u91d1\u4e1d\u96c0\u90e8\u7f72\u662f\u4e00\u79cd\u8f6f\u4ef6\u90e8\u7f72\u6280\u672f\uff0c\u5176\u4e2d\u5728\u5c06\u65b0\u529f\u80fd\u6216\u7248\u672c\u53d1\u5e03\u7ed9\u66f4\u5927\u7684\u7528\u6237\u5b50\u96c6\u6216\u6240\u6709\u7528\u6237\u4e4b\u524d\uff0c\u5148\u5c06\u5176\u53d1\u5e03\u7ed9\u751f\u4ea7\u4e2d\u7684\u4e00\u5c0f\u90e8\u5206\u7528\u6237\u3002 \u8fd9\u79cd\u6280\u672f\u662f\u4f4e\u98ce\u9669\u7684\uff0c\u56e0\u4e3a\u65b0\u529f\u80fd\u6700\u521d\u53ea\u90e8\u7f72\u7ed9\u5c11\u91cf\u7528\u6237\u3002 \"Canary\"\u4e00\u8bcd\u6e90\u81ea\u65e7\u7684\u7164\u77ff\u6280\u672f\uff0c\u5f53\u65f6\u91d1\u4e1d\u96c0\u88ab\u7528\u4f5c\u7a7a\u6c14\u4e2d\u6bd2\u7d20\u7684\u65e9\u671f\u63a2\u6d4b\u5668\u3002 \u5728\u91d1\u4e1d\u96c0\u90e8\u7f72\u4e2d\uff0c\u76ee\u6807\u73af\u5883\u4e2d\u7684\u6240\u6709\u57fa\u7840\u8bbe\u65bd\u90fd\u4f1a\u4ee5\u5c0f\u9636\u6bb5\u8fdb\u884c\u66f4\u65b0\u3002 \u5b83\u7528\u4e8e\u6d4b\u8bd5\u65b0\u529f\u80fd\u548c\u5347\u7ea7\u4ee5\u67e5\u770b\u5b83\u4eec\u5982\u4f55\u5904\u7406\u751f\u4ea7\u73af\u5883\u3002 \u5220\u9664\u6240\u521b\u5efa\u7684\u8d44\u6e90\u3002 kubectl delete sts web kubectl delete service nginx","title":"StatefulSet"},{"location":"k8s/cka_cn/foundamentals/statefulset/#cka12statefulset","text":"","title":"CKA\u81ea\u5b66\u7b14\u8bb012:StatefulSet"},{"location":"k8s/cka_cn/foundamentals/statefulset/#_1","text":"\u521b\u5efa\u4e00\u4e2a Headless Service nginx \u548c\u4e00\u4e2aStatefulSet web \u6269\u5c55 StatefulSet web","title":"\u6f14\u793a\u573a\u666f"},{"location":"k8s/cka_cn/foundamentals/statefulset/#_2","text":"\u521b\u5efa\u4e00\u4e2a Headless Service nginx \u548c\u4e00\u4e2aStatefulSet web kubectl apply -f - << EOF --- apiVersion: v1 kind: Service metadata: name: nginx labels: app: nginx spec: ports: - port: 80 name: web clusterIP: None selector: app: nginx --- apiVersion: apps/v1 kind: StatefulSet metadata: name: web spec: serviceName: \"nginx\" replicas: 2 selector: matchLabels: app: nginx template: metadata: labels: app: nginx spec: containers: - name: nginx image: nginx ports: - containerPort: 80 name: web EOF \u8bfb\u53d6\u4e0a\u4e00\u6b65\u521b\u5efa\u7684StatefulSet Pod \u7684\u8be6\u7ec6\u4fe1\u606f\u3002 kubectl get pod | grep web \u8fd0\u884c\u7ed3\u679c NAME READY STATUS RESTARTS AGE web-0 1 /1 Running 0 27s web-1 1 /1 Running 0 10s \u4f7f\u7528\u547d\u4ee4 kubectl edit sts web \u66f4\u65b0\u73b0\u6709\u7684 StatefulSet\u3002 \u53ea\u6709\u4ee5\u4e0b\u5b57\u6bb5\u53ef\u4ee5\u66f4\u65b0\uff1a replicas \u3001 image \u3001 rolling updates \u3001 labels \u3001 resource request/limit \u548c annotations \u3002 \u6ce8\u610f\uff1a\u5f53 StatefulSet Pod \u5728\u5f53\u524d\u8282\u70b9\u4e2d\u6b7b\u4ea1\u65f6\uff0c\u4e0d\u4f1a\u81ea\u52a8\u5728\u5176\u4ed6\u8282\u70b9\u4e2d\u521b\u5efa\u526f\u672c\u3002 \u6269\u5c55 StatefulSet\u3002 \u5c06 StatefulSet web \u7684\u526f\u672c\u6570\u6269\u5c55\u5230 5 \u3002 kubectl scale sts web --replicas = 5 \u53c2\u8003\uff1a Partition\u8868\u793a\u5728\u66f4\u65b0\u671f\u95f4\u5e94\u5c06 StatefulSet \u5212\u5206\u4e3a\u54ea\u4e2a\u5e8f\u53f7\u3002 \u5728\u6eda\u52a8\u66f4\u65b0\u671f\u95f4\uff0c\u4ece\u5e8f\u53f7 Replicas-1 \u5230 Partition \u7684\u6240\u6709 Pod \u90fd\u4f1a\u66f4\u65b0\u3002 \u4ece\u5e8f\u53f7 Partition-1 \u5230 0 \u7684\u6240\u6709 Pod \u90fd\u4fdd\u6301\u4e0d\u53d8\u3002\u8fd9\u5bf9\u4e8e\u8fdb\u884c\u91d1\u4e1d\u96c0\u90e8\u7f72\u975e\u5e38\u6709\u7528\u3002\u9ed8\u8ba4\u503c\u4e3a0\u3002 \u547d\u4ee4\uff1a kubectl explain statefulsets.spec.updateStrategy.rollingUpdate.partition \u91d1\u4e1d\u96c0\u90e8\u7f72\u662f\u4e00\u79cd\u8f6f\u4ef6\u90e8\u7f72\u6280\u672f\uff0c\u5176\u4e2d\u5728\u5c06\u65b0\u529f\u80fd\u6216\u7248\u672c\u53d1\u5e03\u7ed9\u66f4\u5927\u7684\u7528\u6237\u5b50\u96c6\u6216\u6240\u6709\u7528\u6237\u4e4b\u524d\uff0c\u5148\u5c06\u5176\u53d1\u5e03\u7ed9\u751f\u4ea7\u4e2d\u7684\u4e00\u5c0f\u90e8\u5206\u7528\u6237\u3002 \u8fd9\u79cd\u6280\u672f\u662f\u4f4e\u98ce\u9669\u7684\uff0c\u56e0\u4e3a\u65b0\u529f\u80fd\u6700\u521d\u53ea\u90e8\u7f72\u7ed9\u5c11\u91cf\u7528\u6237\u3002 \"Canary\"\u4e00\u8bcd\u6e90\u81ea\u65e7\u7684\u7164\u77ff\u6280\u672f\uff0c\u5f53\u65f6\u91d1\u4e1d\u96c0\u88ab\u7528\u4f5c\u7a7a\u6c14\u4e2d\u6bd2\u7d20\u7684\u65e9\u671f\u63a2\u6d4b\u5668\u3002 \u5728\u91d1\u4e1d\u96c0\u90e8\u7f72\u4e2d\uff0c\u76ee\u6807\u73af\u5883\u4e2d\u7684\u6240\u6709\u57fa\u7840\u8bbe\u65bd\u90fd\u4f1a\u4ee5\u5c0f\u9636\u6bb5\u8fdb\u884c\u66f4\u65b0\u3002 \u5b83\u7528\u4e8e\u6d4b\u8bd5\u65b0\u529f\u80fd\u548c\u5347\u7ea7\u4ee5\u67e5\u770b\u5b83\u4eec\u5982\u4f55\u5904\u7406\u751f\u4ea7\u73af\u5883\u3002 \u5220\u9664\u6240\u521b\u5efa\u7684\u8d44\u6e90\u3002 kubectl delete sts web kubectl delete service nginx","title":"\u6f14\u793a"},{"location":"k8s/cka_cn/foundamentals/troubleshooting/","text":"CKA\u81ea\u5b66\u7b14\u8bb025:Troubleshooting \u00b6 \u4e8b\u4ef6 \u00b6 \u6f14\u793a\u573a\u666f\uff1a \u63cf\u8ff0pod\u4ee5\u83b7\u53d6\u4e8b\u4ef6\u4fe1\u606f\u3002 \u6f14\u793a\uff1a \u547d\u4ee4\u7528\u6cd5\uff1a kubectl describe --namespace = \u67e5\u8be2pod\u7684\u4e8b\u4ef6\u4fe1\u606f\u3002 \u521b\u5efa\u4e00\u4e2aTomcat\u7684pod\u3002 kubectl run tomcat --image = tomcat \u67e5\u8be2pod\u7684\u4e8b\u4ef6\u4fe1\u606f\u3002 kubectl describe pod/tomcat \u5f97\u5230\u7c7b\u4f3c\u4e0b\u9762\u7684\u4e8b\u4ef6\u4fe1\u606f\u3002 Events: Type Reason Age From Message ---- ------ ---- ---- ------- Normal Scheduled 55s default-scheduler Successfully assigned dev/tomcat to cka002 Normal Pulling 54s kubelet Pulling image \"tomcat\" Normal Pulled 21s kubelet Successfully pulled image \"tomcat\" in 33.134162692s Normal Created 19s kubelet Created container tomcat Normal Started 19s kubelet Started container tomcat \u67e5\u8be2namespace\u7684\u4e8b\u4ef6\u4fe1\u606f\u3002 kubectl get events -n \u5f97\u5230\u7c7b\u4f3c\u4e0b\u9762\u7684\u9ed8\u8ba4namespace\u7684\u4e8b\u4ef6\u4fe1\u606f\u3002 LAST SEEN TYPE REASON OBJECT MESSAGE 70s Warning FailedGetScale horizontalpodautoscaler/nginx deployments/scale.apps \"podinfo\" not found 2m16s Normal Scheduled pod/tomcat Successfully assigned dev/tomcat to cka002 2m15s Normal Pulling pod/tomcat Pulling image \"tomcat\" 102s Normal Pulled pod/tomcat Successfully pulled image \"tomcat\" in 33.134162692s 100s Normal Created pod/tomcat Created container tomcat 100s Normal Started pod/tomcat Started container tomcat \u5f97\u5230\u7c7b\u4f3c\u4e0b\u9762\u7684\u6240\u6709\u7684namespace\u7684\u4e8b\u4ef6\u4fe1\u606f\u3002 kubectl get events -A \u65e5\u5fd7 \u00b6 \u6f14\u793a\u573a\u666f\uff1a \u67e5\u8be2pod\u7684\u65e5\u5fd7 \u547d\u4ee4\u7528\u6cd5\uff1a kubectl logs -n \u9009\u9879\uff1a --tail : \u663e\u793a\u8f93\u51fa\u7684\u6700\u8fd1 \u884c\u3002 -f \uff1a\u5b9e\u65f6\u6d41\u5f0f\u663e\u793a\u8f93\u51fa\u3002 \u663e\u793a\u8f93\u51fa\u7684\u6700\u8fd1100\u884c\u8f93\u51fa\u3002 kubectl logs -f tomcat --tail 100 \u5982\u679c\u662f\u4e00\u4e2a\u591a\u5bb9\u5668pod\uff0c\u5219\u4f7f\u7528\u9009\u9879 -c \u6765\u6307\u5b9a\u67d0\u4e2a\u7279\u5b9a\u7684\u5bb9\u5668\u3002 kubectl logs -f tomcat --tail 100 -c tomcat \u8282\u70b9\u53ef\u7528\u6027 \u00b6 \u67e5\u770b\u53ef\u7528\u8282\u70b9 \u00b6 \u6f14\u793a\u573a\u666f\uff1a \u67e5\u770b\u8282\u70b9\u53ef\u7528\u6027 \u6f14\u793a\uff1a \u65b9\u5f0f1\uff1a kubectl describe node | grep -i taint \u624b\u5de5\u65b9\u5f0f\u68c0\u67e5\u65e5\u5fd7\uff0c\u4e0b\u9762\u7684\u4f8b\u5b50\u8bf4\u660e2\u4e2a\u8282\u70b9\u5904\u4e8e\u4e0d\u53ef\u7528\u72b6\u6001\u3002 Taints : node-role.kubernetes.io/control-plane:NoSchedule Taints : Taints : \u65b9\u5f0f2\uff1a kubectl describe node | grep -i taint | grep -vc NoSchedule \u8fd9\u91cc\u6211\u4eec\u4f1a\u5f97\u5230\u76f8\u540c\u7684\u7ed3\u679c\uff0c2\u4e2a\u8282\u70b9\u5904\u4e8e\u4e0d\u53ef\u7528\u72b6\u6001\u3002\u8fd9\u91cc\u7684 -v \u8868\u793a\u6392\u9664\uff0c -c \u8868\u793a\u8ba1\u6570\u3002 \u67e5\u770b\u4e0d\u53ef\u7528\u8282\u70b9 \u00b6 \u6f14\u793a\u573a\u666f\uff1a \u5f53\u6211\u4eec\u5728Worker\u8282\u70b9 cka002 \u4e0a\u505c\u6b62 kubelet \u670d\u52a1\u65f6\uff0c \u6bcf\u4e2a\u8282\u70b9\u7684\u72b6\u6001\u662f\u4ec0\u4e48\uff1f \u901a\u8fc7 nerdctl \u547d\u4ee4\u66f4\u6539\u4e86\u54ea\u4e9b\u5bb9\u5668\uff1f \u901a\u8fc7\u547d\u4ee4 kubectl get pod -owide -A \u67e5\u770b\u7684Pod\u72b6\u6001\u662f\u4ec0\u4e48\uff1f \u6f14\u793a\uff1a \u5728 cka002 \u8282\u70b9\u4e0a\u6267\u884c\u547d\u4ee4 systemctl stop kubelet.service \u3002 \u5728 cka001 \u6216 cka003 \u4e0a\u6267\u884c\u547d\u4ee4 kubectl get node \uff0c\u53ef\u4ee5\u770b\u5230 cka002 \u7684\u72b6\u6001\u4ece Ready \u53d8\u4e3a NotReady \u3002 \u5728 cka002 \u4e0a\u6267\u884c\u547d\u4ee4 nerdctl -n k8s.io container ls \uff0c\u53ef\u4ee5\u770b\u5230\u6240\u6709\u5bb9\u5668\u90fd\u4ecd\u5728\u8fd0\u884c\uff0c\u5305\u62ecPod my-first-pod \u3002 \u5728 cka002 \u4e0a\u6267\u884c\u547d\u4ee4 systemctl start kubelet.service \u3002 \u7ed3\u8bba\uff1a \u8282\u70b9\u72b6\u6001\u7531 Ready \u53d8\u4e3a NotReady \u3002 \u5bf9\u4e8e\u90a3\u4e9b\u7c7b\u4f3c calico \u3001 kube-proxy \u8fd9\u6837\u7684 DaemonSet Pod\uff0c\u5b83\u4eec\u4e13\u95e8\u5728\u6bcf\u4e2a\u8282\u70b9\u4e0a\u8fd0\u884c\u3002\u5728 kubelet \u505c\u6b62\u540e\u5b83\u4eec\u4e0d\u4f1a\u88ab\u7ec8\u6b62\u3002 Pod my-first-pod \u7684\u72b6\u6001\u5728\u6bcf\u4e2a\u8282\u70b9\u4e0a\u4ecd\u7136\u663e\u793a\u4e3a Terminating \uff0c\u56e0\u4e3a\u72b6\u6001\u65e0\u6cd5\u901a\u8fc7 apiserver \u4ece cka002 \u540c\u6b65\u5230\u5176\u4ed6\u8282\u70b9\uff0c\u56e0\u4e3a kubelet \u5df2\u505c\u6b62\u3002 Pod\u7684\u72b6\u6001\u7531\u63a7\u5236\u5668\u6807\u8bb0\u5e76\u7531 kubelet \u56de\u6536\u3002 \u5f53\u6211\u4eec\u5728 cka003 \u4e0a\u542f\u52a8 kubelet \u670d\u52a1\u65f6\uff0cPod my-first-pod \u5c06\u5b8c\u5168\u5728 cka002 \u4e0a\u88ab\u7ec8\u6b62\u3002 \u6b64\u5916\uff0c\u8ba9\u6211\u4eec\u521b\u5efa\u4e00\u4e2a\u526f\u672c\u6570\u4e3a3\u7684Deployment\u3002\u5176\u4e2d\u4e24\u4e2a\u526f\u672c\u8fd0\u884c\u5728 cka003 \u4e0a\uff0c\u53e6\u4e00\u4e2a\u526f\u672c\u8fd0\u884c\u5728 cka002 \u4e0a\u3002 kubectl get pod -o wide -w \u8fd0\u884c\u7ed3\u679c NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES nginx-deployment-9d745469b-2xdk4 1/1 Running 0 2m8s 10.244.2.3 cka003 nginx-deployment-9d745469b-4gvmr 1/1 Running 0 2m8s 10.244.2.4 cka003 nginx-deployment-9d745469b-5j927 1/1 Running 0 2m8s 10.244.1.3 cka002 \u5728\u6211\u4eec\u505c\u6b62 cka003 \u4e0a\u7684 kubelet \u670d\u52a1\u540e\uff0c\u539f\u5148\u5728 cka003 \u4e0a\u8fd0\u884c\u7684\u4e24\u4e2a\u526f\u672c\u4f1a\u88ab\u7ec8\u6b62\uff0c\u7136\u540e\u4f1a\u81ea\u52a8\u5728 cka002 \u4e0a\u521b\u5efa\u4e24\u4e2a\u65b0\u7684\u526f\u672c\u5e76\u8fd0\u884c\u3002 \u76d1\u63a7\u6307\u6807 \u00b6 \u6f14\u793a\u573a\u666f\uff1a \u67e5\u8be2pod\u7684\u76d1\u63a7\u6307\u6807 \u6f14\u793a\uff1a \u67e5\u8be2\u8282\u70b9\u7684\u5065\u5eb7\u4fe1\u606f\u3002 kubectl top node \u8fd0\u884c\u7ed3\u679c\uff1a NAME CPU(cores) CPU% MEMORY(bytes) MEMORY% cka001 147m 7% 1940Mi 50% cka002 62m 3% 2151Mi 56% cka003 63m 3% 1825Mi 47% \u67e5\u8be2pod\u7684\u76d1\u63a7\u6307\u6807\u3002 kubectl top pod \u8fd0\u884c\u7ed3\u679c\uff1a NAME CPU(cores) MEMORY(bytes) busybox-with-secret 0m 0Mi mysql 2m 366Mi mysql-774db46945-sztrp 2m 349Mi mysql-nodeselector-6b7d9c875d-227t6 2m 365Mi mysql-tolerations-5c5986944b-cg9bs 2m 366Mi mysql-with-sc-pvc-7c97d875f8-dwfkc 2m 349Mi nfs-client-provisioner-699db7fd58-bccqs 2m 7Mi nginx 0m 3Mi nginx-app-1-695b7b647d-l76bh 0m 3Mi nginx-app-2-7f6bf6f4d4-lvbz8 0m 3Mi nginx-nodename 0m 3Mi nginx-with-cm 0m 3Mi pod-configmap-env 0m 3Mi pod-configmap-env-2 0m 3Mi tomcat 1m 58Mi \u901a\u8fc7\u9009\u9879 --sort-by \uff0c\u5bf9\u8f93\u51fa\u7ed3\u679c\u6309\u7167CPU\u6216\u8005\u5185\u5b58\u7528\u91cf\u8fdb\u884c\u6392\u5e8f\u3002 kubectl top pod --sort-by = cpu kubectl top pod --sort-by = memory \u8fd0\u884c\u7ed3\u679c\uff1a NAME CPU(cores) MEMORY(bytes) nfs-client-provisioner-699db7fd58-bccqs 2m 7Mi mysql 2m 366Mi mysql-774db46945-sztrp 2m 349Mi mysql-nodeselector-6b7d9c875d-227t6 2m 365Mi mysql-tolerations-5c5986944b-cg9bs 2m 366Mi mysql-with-sc-pvc-7c97d875f8-dwfkc 2m 349Mi tomcat 1m 58Mi nginx 0m 3Mi nginx-app-1-695b7b647d-l76bh 0m 3Mi nginx-app-2-7f6bf6f4d4-lvbz8 0m 3Mi nginx-nodename 0m 3Mi nginx-with-cm 0m 3Mi pod-configmap-env 0m 3Mi pod-configmap-env-2 0m 3Mi busybox-with-secret 0m 0Mi \u8282\u70b9\u9a71\u9010 \u00b6 \u8282\u70b9\u7684\u53ef\u8c03\u5ea6\u6027 \u00b6 \u6f14\u793a\u573a\u666f\uff1a \u8282\u70b9\u8c03\u5ea6 \u6f14\u793a\uff1a \u7981\u6b62\u4e00\u4e2a\u8282\u70b9\u7684\u8c03\u5ea6\u3002 kubectl cordon \u4e3e\u4f8b\uff1a kubectl cordon cka003 \u8f93\u51fa\u7ed3\u679c\uff0c\u8282\u70b9\u72b6\u6001\u5982\u4e0b\uff1a NAME STATUS ROLES AGE VERSION cka001 Ready control-plane,master 18d v1.24.0 cka002 Ready 18d v1.24.0 cka003 Ready,SchedulingDisabled 18d v1.24.0 \u6fc0\u6d3b\u4e00\u4e2a\u8282\u70b9\u7684\u8c03\u5ea6\u3002 kubectl uncordon \u4e3e\u4f8b\uff1a kubectl uncordon cka003 \u8f93\u51fa\u7ed3\u679c\uff0c\u8282\u70b9\u72b6\u6001\u5982\u4e0b\uff1a NAME STATUS ROLES AGE VERSION cka001 Ready control-plane,master 18d v1.24.0 cka002 Ready 18d v1.24.0 cka003 Ready 18d v1.24.0 \u9a71\u9010\u8282\u70b9 \u00b6 \u6f14\u793a\u5185\u5bb9\uff1a \u9a71\u9010\u8282\u70b9 cka003 \u6f14\u793a\uff1a \u83b7\u53d6\u5f53\u524d\u8fd0\u884cpod\u7684\u5217\u8868\u3002 kubectl get pod -o wide \u5176\u4e2d\u6709\u4e00\u4e2apod\u8fd0\u884c\u5728\u8282\u70b9 cka003 \u4e0a\u3002 NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES nfs-client-provisioner-86d7fb78b6-xk8nw 1/1 Running 0 22h 10.244.102.3 cka003 \u9a71\u9010\u8282\u70b9 cka003 \u3002 kubectl drain cka003 --ignore-daemonsets --delete-emptydir-data --force \u8f93\u51fa\u7ed3\u679c\uff1a node/cka003 cordoned WARNING: ignoring DaemonSet-managed Pods: kube-system/calico-node-tr22l, kube-system/kube-proxy-g76kg evicting pod dev/nfs-client-provisioner-86d7fb78b6-xk8nw evicting pod cka/cka-demo-64f88f7f46-dkxmk pod/nfs-client-provisioner-86d7fb78b6-xk8nw evicted pod/cka-demo-64f88f7f46-dkxmk evicted node/cka003 drained \u518d\u6b21\u67e5\u770bpod\u7684\u72b6\u6001\u3002 kubectl get pod -o wide \u5148\u524d\u8fd0\u884c\u5728\u8282\u70b9 cka003 \u4e0a\u7684pod\u73b0\u5728\u6b63\u8fd0\u884c\u5728\u8282\u70b9 cka002 \u4e0a\u3002 NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES nfs-client-provisioner-86d7fb78b6-k8xnl 1/1 Running 0 2m20s 10.244.112.4 cka002 \u5907\u6ce8\uff1a cordon \u547d\u4ee4\u5df2\u7ecf\u5305\u542b\u5728 drain \u547d\u4ee4\u4e2d\uff0c\u4e0d\u9700\u8981\u5728\u6267\u884c drain \u4e4b\u524d\u5355\u72ec\u6267\u884c cordon \u6765\u7981\u6b62node\u7684\u8c03\u5ea6\u3002","title":"Troubleshooting"},{"location":"k8s/cka_cn/foundamentals/troubleshooting/#cka25troubleshooting","text":"","title":"CKA\u81ea\u5b66\u7b14\u8bb025:Troubleshooting"},{"location":"k8s/cka_cn/foundamentals/troubleshooting/#_1","text":"\u6f14\u793a\u573a\u666f\uff1a \u63cf\u8ff0pod\u4ee5\u83b7\u53d6\u4e8b\u4ef6\u4fe1\u606f\u3002 \u6f14\u793a\uff1a \u547d\u4ee4\u7528\u6cd5\uff1a kubectl describe --namespace = \u67e5\u8be2pod\u7684\u4e8b\u4ef6\u4fe1\u606f\u3002 \u521b\u5efa\u4e00\u4e2aTomcat\u7684pod\u3002 kubectl run tomcat --image = tomcat \u67e5\u8be2pod\u7684\u4e8b\u4ef6\u4fe1\u606f\u3002 kubectl describe pod/tomcat \u5f97\u5230\u7c7b\u4f3c\u4e0b\u9762\u7684\u4e8b\u4ef6\u4fe1\u606f\u3002 Events: Type Reason Age From Message ---- ------ ---- ---- ------- Normal Scheduled 55s default-scheduler Successfully assigned dev/tomcat to cka002 Normal Pulling 54s kubelet Pulling image \"tomcat\" Normal Pulled 21s kubelet Successfully pulled image \"tomcat\" in 33.134162692s Normal Created 19s kubelet Created container tomcat Normal Started 19s kubelet Started container tomcat \u67e5\u8be2namespace\u7684\u4e8b\u4ef6\u4fe1\u606f\u3002 kubectl get events -n \u5f97\u5230\u7c7b\u4f3c\u4e0b\u9762\u7684\u9ed8\u8ba4namespace\u7684\u4e8b\u4ef6\u4fe1\u606f\u3002 LAST SEEN TYPE REASON OBJECT MESSAGE 70s Warning FailedGetScale horizontalpodautoscaler/nginx deployments/scale.apps \"podinfo\" not found 2m16s Normal Scheduled pod/tomcat Successfully assigned dev/tomcat to cka002 2m15s Normal Pulling pod/tomcat Pulling image \"tomcat\" 102s Normal Pulled pod/tomcat Successfully pulled image \"tomcat\" in 33.134162692s 100s Normal Created pod/tomcat Created container tomcat 100s Normal Started pod/tomcat Started container tomcat \u5f97\u5230\u7c7b\u4f3c\u4e0b\u9762\u7684\u6240\u6709\u7684namespace\u7684\u4e8b\u4ef6\u4fe1\u606f\u3002 kubectl get events -A","title":"\u4e8b\u4ef6"},{"location":"k8s/cka_cn/foundamentals/troubleshooting/#_2","text":"\u6f14\u793a\u573a\u666f\uff1a \u67e5\u8be2pod\u7684\u65e5\u5fd7 \u547d\u4ee4\u7528\u6cd5\uff1a kubectl logs -n \u9009\u9879\uff1a --tail : \u663e\u793a\u8f93\u51fa\u7684\u6700\u8fd1 \u884c\u3002 -f \uff1a\u5b9e\u65f6\u6d41\u5f0f\u663e\u793a\u8f93\u51fa\u3002 \u663e\u793a\u8f93\u51fa\u7684\u6700\u8fd1100\u884c\u8f93\u51fa\u3002 kubectl logs -f tomcat --tail 100 \u5982\u679c\u662f\u4e00\u4e2a\u591a\u5bb9\u5668pod\uff0c\u5219\u4f7f\u7528\u9009\u9879 -c \u6765\u6307\u5b9a\u67d0\u4e2a\u7279\u5b9a\u7684\u5bb9\u5668\u3002 kubectl logs -f tomcat --tail 100 -c tomcat","title":"\u65e5\u5fd7"},{"location":"k8s/cka_cn/foundamentals/troubleshooting/#_3","text":"","title":"\u8282\u70b9\u53ef\u7528\u6027"},{"location":"k8s/cka_cn/foundamentals/troubleshooting/#_4","text":"\u6f14\u793a\u573a\u666f\uff1a \u67e5\u770b\u8282\u70b9\u53ef\u7528\u6027 \u6f14\u793a\uff1a \u65b9\u5f0f1\uff1a kubectl describe node | grep -i taint \u624b\u5de5\u65b9\u5f0f\u68c0\u67e5\u65e5\u5fd7\uff0c\u4e0b\u9762\u7684\u4f8b\u5b50\u8bf4\u660e2\u4e2a\u8282\u70b9\u5904\u4e8e\u4e0d\u53ef\u7528\u72b6\u6001\u3002 Taints : node-role.kubernetes.io/control-plane:NoSchedule Taints : Taints : \u65b9\u5f0f2\uff1a kubectl describe node | grep -i taint | grep -vc NoSchedule \u8fd9\u91cc\u6211\u4eec\u4f1a\u5f97\u5230\u76f8\u540c\u7684\u7ed3\u679c\uff0c2\u4e2a\u8282\u70b9\u5904\u4e8e\u4e0d\u53ef\u7528\u72b6\u6001\u3002\u8fd9\u91cc\u7684 -v \u8868\u793a\u6392\u9664\uff0c -c \u8868\u793a\u8ba1\u6570\u3002","title":"\u67e5\u770b\u53ef\u7528\u8282\u70b9"},{"location":"k8s/cka_cn/foundamentals/troubleshooting/#_5","text":"\u6f14\u793a\u573a\u666f\uff1a \u5f53\u6211\u4eec\u5728Worker\u8282\u70b9 cka002 \u4e0a\u505c\u6b62 kubelet \u670d\u52a1\u65f6\uff0c \u6bcf\u4e2a\u8282\u70b9\u7684\u72b6\u6001\u662f\u4ec0\u4e48\uff1f \u901a\u8fc7 nerdctl \u547d\u4ee4\u66f4\u6539\u4e86\u54ea\u4e9b\u5bb9\u5668\uff1f \u901a\u8fc7\u547d\u4ee4 kubectl get pod -owide -A \u67e5\u770b\u7684Pod\u72b6\u6001\u662f\u4ec0\u4e48\uff1f \u6f14\u793a\uff1a \u5728 cka002 \u8282\u70b9\u4e0a\u6267\u884c\u547d\u4ee4 systemctl stop kubelet.service \u3002 \u5728 cka001 \u6216 cka003 \u4e0a\u6267\u884c\u547d\u4ee4 kubectl get node \uff0c\u53ef\u4ee5\u770b\u5230 cka002 \u7684\u72b6\u6001\u4ece Ready \u53d8\u4e3a NotReady \u3002 \u5728 cka002 \u4e0a\u6267\u884c\u547d\u4ee4 nerdctl -n k8s.io container ls \uff0c\u53ef\u4ee5\u770b\u5230\u6240\u6709\u5bb9\u5668\u90fd\u4ecd\u5728\u8fd0\u884c\uff0c\u5305\u62ecPod my-first-pod \u3002 \u5728 cka002 \u4e0a\u6267\u884c\u547d\u4ee4 systemctl start kubelet.service \u3002 \u7ed3\u8bba\uff1a \u8282\u70b9\u72b6\u6001\u7531 Ready \u53d8\u4e3a NotReady \u3002 \u5bf9\u4e8e\u90a3\u4e9b\u7c7b\u4f3c calico \u3001 kube-proxy \u8fd9\u6837\u7684 DaemonSet Pod\uff0c\u5b83\u4eec\u4e13\u95e8\u5728\u6bcf\u4e2a\u8282\u70b9\u4e0a\u8fd0\u884c\u3002\u5728 kubelet \u505c\u6b62\u540e\u5b83\u4eec\u4e0d\u4f1a\u88ab\u7ec8\u6b62\u3002 Pod my-first-pod \u7684\u72b6\u6001\u5728\u6bcf\u4e2a\u8282\u70b9\u4e0a\u4ecd\u7136\u663e\u793a\u4e3a Terminating \uff0c\u56e0\u4e3a\u72b6\u6001\u65e0\u6cd5\u901a\u8fc7 apiserver \u4ece cka002 \u540c\u6b65\u5230\u5176\u4ed6\u8282\u70b9\uff0c\u56e0\u4e3a kubelet \u5df2\u505c\u6b62\u3002 Pod\u7684\u72b6\u6001\u7531\u63a7\u5236\u5668\u6807\u8bb0\u5e76\u7531 kubelet \u56de\u6536\u3002 \u5f53\u6211\u4eec\u5728 cka003 \u4e0a\u542f\u52a8 kubelet \u670d\u52a1\u65f6\uff0cPod my-first-pod \u5c06\u5b8c\u5168\u5728 cka002 \u4e0a\u88ab\u7ec8\u6b62\u3002 \u6b64\u5916\uff0c\u8ba9\u6211\u4eec\u521b\u5efa\u4e00\u4e2a\u526f\u672c\u6570\u4e3a3\u7684Deployment\u3002\u5176\u4e2d\u4e24\u4e2a\u526f\u672c\u8fd0\u884c\u5728 cka003 \u4e0a\uff0c\u53e6\u4e00\u4e2a\u526f\u672c\u8fd0\u884c\u5728 cka002 \u4e0a\u3002 kubectl get pod -o wide -w \u8fd0\u884c\u7ed3\u679c NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES nginx-deployment-9d745469b-2xdk4 1/1 Running 0 2m8s 10.244.2.3 cka003 nginx-deployment-9d745469b-4gvmr 1/1 Running 0 2m8s 10.244.2.4 cka003 nginx-deployment-9d745469b-5j927 1/1 Running 0 2m8s 10.244.1.3 cka002 \u5728\u6211\u4eec\u505c\u6b62 cka003 \u4e0a\u7684 kubelet \u670d\u52a1\u540e\uff0c\u539f\u5148\u5728 cka003 \u4e0a\u8fd0\u884c\u7684\u4e24\u4e2a\u526f\u672c\u4f1a\u88ab\u7ec8\u6b62\uff0c\u7136\u540e\u4f1a\u81ea\u52a8\u5728 cka002 \u4e0a\u521b\u5efa\u4e24\u4e2a\u65b0\u7684\u526f\u672c\u5e76\u8fd0\u884c\u3002","title":"\u67e5\u770b\u4e0d\u53ef\u7528\u8282\u70b9"},{"location":"k8s/cka_cn/foundamentals/troubleshooting/#_6","text":"\u6f14\u793a\u573a\u666f\uff1a \u67e5\u8be2pod\u7684\u76d1\u63a7\u6307\u6807 \u6f14\u793a\uff1a \u67e5\u8be2\u8282\u70b9\u7684\u5065\u5eb7\u4fe1\u606f\u3002 kubectl top node \u8fd0\u884c\u7ed3\u679c\uff1a NAME CPU(cores) CPU% MEMORY(bytes) MEMORY% cka001 147m 7% 1940Mi 50% cka002 62m 3% 2151Mi 56% cka003 63m 3% 1825Mi 47% \u67e5\u8be2pod\u7684\u76d1\u63a7\u6307\u6807\u3002 kubectl top pod \u8fd0\u884c\u7ed3\u679c\uff1a NAME CPU(cores) MEMORY(bytes) busybox-with-secret 0m 0Mi mysql 2m 366Mi mysql-774db46945-sztrp 2m 349Mi mysql-nodeselector-6b7d9c875d-227t6 2m 365Mi mysql-tolerations-5c5986944b-cg9bs 2m 366Mi mysql-with-sc-pvc-7c97d875f8-dwfkc 2m 349Mi nfs-client-provisioner-699db7fd58-bccqs 2m 7Mi nginx 0m 3Mi nginx-app-1-695b7b647d-l76bh 0m 3Mi nginx-app-2-7f6bf6f4d4-lvbz8 0m 3Mi nginx-nodename 0m 3Mi nginx-with-cm 0m 3Mi pod-configmap-env 0m 3Mi pod-configmap-env-2 0m 3Mi tomcat 1m 58Mi \u901a\u8fc7\u9009\u9879 --sort-by \uff0c\u5bf9\u8f93\u51fa\u7ed3\u679c\u6309\u7167CPU\u6216\u8005\u5185\u5b58\u7528\u91cf\u8fdb\u884c\u6392\u5e8f\u3002 kubectl top pod --sort-by = cpu kubectl top pod --sort-by = memory \u8fd0\u884c\u7ed3\u679c\uff1a NAME CPU(cores) MEMORY(bytes) nfs-client-provisioner-699db7fd58-bccqs 2m 7Mi mysql 2m 366Mi mysql-774db46945-sztrp 2m 349Mi mysql-nodeselector-6b7d9c875d-227t6 2m 365Mi mysql-tolerations-5c5986944b-cg9bs 2m 366Mi mysql-with-sc-pvc-7c97d875f8-dwfkc 2m 349Mi tomcat 1m 58Mi nginx 0m 3Mi nginx-app-1-695b7b647d-l76bh 0m 3Mi nginx-app-2-7f6bf6f4d4-lvbz8 0m 3Mi nginx-nodename 0m 3Mi nginx-with-cm 0m 3Mi pod-configmap-env 0m 3Mi pod-configmap-env-2 0m 3Mi busybox-with-secret 0m 0Mi","title":"\u76d1\u63a7\u6307\u6807"},{"location":"k8s/cka_cn/foundamentals/troubleshooting/#_7","text":"","title":"\u8282\u70b9\u9a71\u9010"},{"location":"k8s/cka_cn/foundamentals/troubleshooting/#_8","text":"\u6f14\u793a\u573a\u666f\uff1a \u8282\u70b9\u8c03\u5ea6 \u6f14\u793a\uff1a \u7981\u6b62\u4e00\u4e2a\u8282\u70b9\u7684\u8c03\u5ea6\u3002 kubectl cordon \u4e3e\u4f8b\uff1a kubectl cordon cka003 \u8f93\u51fa\u7ed3\u679c\uff0c\u8282\u70b9\u72b6\u6001\u5982\u4e0b\uff1a NAME STATUS ROLES AGE VERSION cka001 Ready control-plane,master 18d v1.24.0 cka002 Ready 18d v1.24.0 cka003 Ready,SchedulingDisabled 18d v1.24.0 \u6fc0\u6d3b\u4e00\u4e2a\u8282\u70b9\u7684\u8c03\u5ea6\u3002 kubectl uncordon \u4e3e\u4f8b\uff1a kubectl uncordon cka003 \u8f93\u51fa\u7ed3\u679c\uff0c\u8282\u70b9\u72b6\u6001\u5982\u4e0b\uff1a NAME STATUS ROLES AGE VERSION cka001 Ready control-plane,master 18d v1.24.0 cka002 Ready 18d v1.24.0 cka003 Ready 18d v1.24.0","title":"\u8282\u70b9\u7684\u53ef\u8c03\u5ea6\u6027"},{"location":"k8s/cka_cn/foundamentals/troubleshooting/#_9","text":"\u6f14\u793a\u5185\u5bb9\uff1a \u9a71\u9010\u8282\u70b9 cka003 \u6f14\u793a\uff1a \u83b7\u53d6\u5f53\u524d\u8fd0\u884cpod\u7684\u5217\u8868\u3002 kubectl get pod -o wide \u5176\u4e2d\u6709\u4e00\u4e2apod\u8fd0\u884c\u5728\u8282\u70b9 cka003 \u4e0a\u3002 NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES nfs-client-provisioner-86d7fb78b6-xk8nw 1/1 Running 0 22h 10.244.102.3 cka003 \u9a71\u9010\u8282\u70b9 cka003 \u3002 kubectl drain cka003 --ignore-daemonsets --delete-emptydir-data --force \u8f93\u51fa\u7ed3\u679c\uff1a node/cka003 cordoned WARNING: ignoring DaemonSet-managed Pods: kube-system/calico-node-tr22l, kube-system/kube-proxy-g76kg evicting pod dev/nfs-client-provisioner-86d7fb78b6-xk8nw evicting pod cka/cka-demo-64f88f7f46-dkxmk pod/nfs-client-provisioner-86d7fb78b6-xk8nw evicted pod/cka-demo-64f88f7f46-dkxmk evicted node/cka003 drained \u518d\u6b21\u67e5\u770bpod\u7684\u72b6\u6001\u3002 kubectl get pod -o wide \u5148\u524d\u8fd0\u884c\u5728\u8282\u70b9 cka003 \u4e0a\u7684pod\u73b0\u5728\u6b63\u8fd0\u884c\u5728\u8282\u70b9 cka002 \u4e0a\u3002 NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES nfs-client-provisioner-86d7fb78b6-k8xnl 1/1 Running 0 2m20s 10.244.112.4 cka002 \u5907\u6ce8\uff1a cordon \u547d\u4ee4\u5df2\u7ecf\u5305\u542b\u5728 drain \u547d\u4ee4\u4e2d\uff0c\u4e0d\u9700\u8981\u5728\u6267\u884c drain \u4e4b\u524d\u5355\u72ec\u6267\u884c cordon \u6765\u7981\u6b62node\u7684\u8c03\u5ea6\u3002","title":"\u9a71\u9010\u8282\u70b9"},{"location":"k8s/cka_cn/installation/aliyun-ubuntu/","text":"CKA\u81ea\u5b66\u7b14\u8bb03:\u963f\u91cc\u4e91ECS\u5b89\u88c5Kubernetes \u00b6 \u6458\u8981 \u00b6 \u5728\u963f\u91cc\u4e91ECS\u88c5\u4e09\u53f0Ubuntu\u865a\u62df\u673a\u3002\u5728Ubuntu\u865a\u62df\u673a\u4e2d\u5b89\u88c5\u57fa\u4e8eContainerd\u7684Kubernetes\u7cfb\u7edf\uff0c\u5e76\u5206\u522b\u914d\u7f6e\u4e00\u4e2a\u4e3b\u8282\u70b9Master\u548c\u4e24\u4e2a\u5de5\u4f5c\u8282\u70b9Worker\uff0c\u3002 \u51c6\u5907\u5de5\u4f5c \u00b6 \u6ce8\u518c\u963f\u91cc\u4e91\u8d26\u53f7\uff1a Alibaba Cloud home console \u3002\u6ce8\u610f\u4fdd\u7559\u8bbf\u95ee\u5bc6\u94a5key\u6587\u4ef6\uff0c\u53ea\u80fd\u5bfc\u51fa\u4e00\u6b21\uff0c\u5f53\u524d\u7ec3\u4e60\u4e2dkey\u6587\u4ef6\u662f aliyun-root \u3002 \u53c2\u8003\u4e0b\u9762\u914d\u7f6e\u6ce8\u518c\u7533\u8bf7\u4e09\u4e2aECS\uff08Elastic Computer Service\uff09\u670d\u52a1\u5b9e\u4f8b\uff1a \u4e3b\u673a\uff1a2vCPU+4GiB \u64cd\u4f5c\u7cfb\u7edf\uff1aUbuntu 20.04 x86_64 \u5b9e\u4f8b\u7c7b\u578b\uff1aecs.sn1.medium \u5b9e\u4f8b\u540d\u79f0\uff1acka001, cka002, cka003 \u7f51\u7edc\u914d\u7f6e\uff1aboth public IPs and private IPs \u6700\u5927\u7f51\u7edc\u5e26\u5bbd\uff1a100Mbps (Peak Value) \u4e91\u76d8\uff1a40GiB \u652f\u4ed8\u65b9\u5f0f\uff1a\u62a2\u5360\u5f0f\u5b9e\u4f8b \u5728\u672c\u5730\u6253\u5f00\u7ec8\u7aef\u7a97\u53e3\uff0c\u901a\u8fc7\u5bc6\u94a5\u6587\u4ef6 aliyun-root \u8bbf\u95ee\u8fdc\u7a0bECS\u8282\u70b9 cka001 \u3002 ssh -i aliyun-root root@cka001 \u521b\u5efa\u4e00\u4e2a\u666e\u901a\u7528\u6237\uff0c\u7528\u6765\u5b89\u88c5Kubernetes\uff0c\u5f53\u524d\u7ec3\u4e60\u4e2d\u521b\u5efa\u7528\u6237 vagrant \uff0c\u4e14\u4fee\u6539\u8be5\u7528\u6237\u7684\u4e3b\u8981\u7ec4\u4e3a sudo \u6b21\u8981\u7ec4\u5305\u542b root \u3002 adduser vagrant usermod -g sudo vagrant usermod -a -G root vagrant \u65b0\u5f00\u4e00\u4e2a\u672c\u5730\u7ec8\u7aef\u7a97\u53e3\uff0c\u4e3a\u7528\u6237 vagrant \u521b\u5efa\u5bc6\u94a5key\u3002 # Windows ssh-keygen.exe # Linux ssh-keygen \u4e0a\u9762\u7684\u547d\u4ee4\u4f1a\u751f\u62102\u4e2a\u6587\u4ef6\uff0c\u5f53\u524d\u7ec3\u4e60\u4e2d\u8fd92\u4e2a\u6587\u4ef6\u662f aliyun-vagrant and aliyun-vagrant.pub \u901a\u8fc7 sftp \u547d\u4ee4\u5c06\u516c\u94a5\u6587\u4ef6 aliyun-vagrant.pub \u4e0a\u4f20\u5230\u8fdc\u7a0b\u8282\u70b9 cka001 \u3002 sftp -i aliyun-root root@cka001 put aliyun-vagrant.pub \u65b0\u5f00\u4e00\u4e2a\u7ec8\u7aef\u7a97\u53e3\uff0c\u7528 root \u7684\u5bc6\u94a5\u767b\u5f55 cka001 \u8282\u70b9\u3002 \u5c06\u4e0a\u4e00\u6b65\u4e0a\u4f20\u7684\u5bc6\u94a5\u6587\u4ef6 aliyun-vagrant.pub \u4ece /root \u76ee\u5f55\u62f7\u8d1d\u5230 /home/vagrant/.ssh/ \u3002 \u5c06\u516c\u94a5\u6587\u4ef6 aliyun-vagrant.pub \u91cd\u547d\u540d\u4e3a authorized_keys \u3002 \u66f4\u6539\u6587\u4ef6 authorized_keys \u7684\u6240\u6709\u8005owner\u4e3a vagrant . \u66f4\u6539\u6587\u4ef6 authorized_keys \u7684\u4e3b\u8981\u7ec4\u4e3a sudo \u3002 mkdir /home/vagrant/.ssh/ mv aliyun-james.pub /home/vagrant/.ssh/authorized_keys chown vagrant.sudo /home/vagrant/.ssh/authorized_keys chmod 600 /home/vagrant/.ssh/authorized_keys \u68c0\u67e5\u6587\u4ef6 /etc/ssh/sshd_config \uff0c\u786e\u5b9a\u5bc6\u7801\u767b\u5f55\u9a8c\u8bc1\u53c2\u6570 asswordAuthentication \u8bbe\u5b9a\u4e3a no \uff0c\u5373\u53ea\u80fd\u901a\u8fc7\u8bc1\u4e66\u8fdc\u7a0b\u767b\u5f55\u3002 cat /etc/ssh/sshd_config \u65b0\u5f00\u4e00\u4e2a\u7ec8\u7aef\u7a97\u53e3\uff0c\u4f7f\u7528\u7528\u6237vagrant\u767b\u5f55\u8fdc\u7a0b\u8282\u70b9 cka001 \uff0c\u9a8c\u8bc1\u7528\u6237 vagrant \u80fd\u901a\u8fc7\u524d\u9762\u521b\u5efa\u7684\u8bc1\u4e66\u767b\u5f55\u8282\u70b9 cka001 \u3002 ssh -i aliyun-vagrant vagrant@cka001 \u91cd\u590d\u4e0a\u8ff0\u6b65\u9aa4\uff0c\u901a\u8fc7 sftp \u547d\u4ee4\u5c06\u516c\u94a5\u6587\u4ef6 aliyun-vagrant.pub \u5206\u522b\u4e0a\u4f20\u5230\u8fdc\u7a0b\u8282\u70b9 cka002 \u548c cka003 \uff0c\u4e14\u5b8c\u6210\u540c\u6837\u7684\u914d\u7f6e\uff0c\u4f7f\u7528\u6237 vagrant \u4e5f\u80fd\u901a\u8fc7\u5bc6\u94a5\u6587\u4ef6\u767b\u5f55\u8fdc\u7a0b\u8282\u70b9 cka002 \u548c cka003 \u3002 \u81f3\u6b64\uff0c\u7528\u6237 vagrant \u53ef\u4ee5\u901a\u8fc7\u5bc6\u94a5\u6587\u4ef6 aliyun-vagrant \u4ece\u672c\u5730\u7ec8\u7aef\u7a97\u53e3\u767b\u5f55\u8fdc\u7a0b\u8282\u70b9 cka001 , cka002 \u548c cka003 \u3002 \u4e0b\u9762\u6240\u6709\u6b65\u9aa4\u90fd\u662f\u901a\u8fc7\u7528\u6237 vagrant \u5b8c\u6210\u3002 \u521d\u59cb\u5316ECS\u8282\u70b9 \u00b6 \u914d\u7f6e\u6587\u4ef6/etc/hosts \u00b6 \u66f4\u65b0\u6240\u6709ECS\u8282\u70b9\u7684\u6587\u4ef6/etc/hosts\uff0c\u6dfb\u52a0\u5176\u4ed6\u8282\u70b9\u7684\u79c1\u6709IP\uff08private IP\uff09\u3002 vi /etc/hosts \u7981\u7528firewall \u00b6 \u5728\u6240\u6709\u8282\u70b9\u4e0a\u7981\u7528\u9632\u706b\u5899\u3002 sudo ufw disable \u68c0\u67e5\u9632\u706b\u5899\u72b6\u6001\u3002 sudo ufw status verbose \u5173\u95edswap \u00b6 \u5728\u6240\u6709\u8282\u70b9\u4e0a\u5173\u95edswap\u3002 sudo swapoff -a \u8bbe\u7f6e\u65f6\u533a\u548c\u5730\u57df \u00b6 \u5728\u6240\u6709\u8282\u70b9\u8bbe\u5b9a\u65f6\u533a\u548c\u5730\u57df\u3002\u8fd9\u4e00\u5e03\u5728\u521d\u59cb\u5316ECS\u65f6\u5019\u5df2\u7ecf\u5b8c\u6210\u3002\u53ef\u4ee5\u901a\u8fc7\u4e0b\u9762\u547d\u4ee4\u8fdb\u884c\u8bbe\u5b9a\u3002 ln -sf /usr/share/zoneinfo/Asia/Shanghai /etc/localtime sudo echo 'LANG=\"en_US.UTF-8\"' >> /etc/profile source /etc/profile \u901a\u8fc7\u4e0b\u9762\u547d\u4ee4\u68c0\u67e5\u65f6\u533a\u548c\u5730\u57df\u7684\u8bbe\u7f6e\u3002 ll /etc/localtime lrwxrwxrwx 1 root root 33 Jul 5 14:51 /etc/localtime -> /usr/share/zoneinfo/Asia/Shanghai \u5185\u6838\u8bbe\u7f6e \u00b6 \u5728\u6240\u6709\u8282\u70b9\u4e0a\u6267\u884c\u4e0b\u9762\u7684\u547d\u4ee4\u4ee5\u914d\u7f6e\u5185\u6838\u3002 \u4f7f\u7528\u6a21\u5757overlay\uff1a \u521b\u5efaContainerd\u670d\u52a1\u914d\u7f6e\u6587\u4ef6 /etc/modules-load.d/containerd.conf \uff0c\u5982\u679c\u5df2\u5b58\u5728\u5219\u8df3\u8fc7\u8fd9\u4e00\u6b65\u3002\u914d\u7f6e\u8fd9\u4e2a\u6587\u4ef6\u7684\u76ee\u7684\u662f\u4e3a\u4e86\u52a0\u8f7d\u6a21\u5757 overlay \u548c br_netfilter \u5230\u5185\u6838\u4e2d\u3002 \u670d\u52a1Containerd\u4f9d\u8d56\u6a21\u5757 overlay \u5b9e\u73b0 overlay-filesystem \u6587\u4ef6\u7cfb\u7edf\u529f\u80fd\u3002 Linux\u4e2d\u7684overlay\u6a21\u5757\u63d0\u4f9b\u4e86\u521b\u5efa\u4e24\u4e2a\u76ee\u5f55\u7684\u5408\u5e76\u89c6\u56fe\u7684\u80fd\u529b\uff0c\u8fd9\u4e24\u4e2a\u76ee\u5f55\u79f0\u4e3a\u5c42\u3002\u5b83\u7ecf\u5e38\u88ab\u7528\u4e8e\u5b9e\u73b0\u8054\u5408\u6302\u8f7d\uff0c\u8fd9\u662f\u4e00\u79cd\u5c06\u4e24\u4e2a\u6216\u66f4\u591a\u76ee\u5f55\u4e00\u8d77\u6302\u8f7d\u7684\u65b9\u5f0f\uff0c\u5c31\u50cf\u5b83\u4eec\u662f\u4e00\u4e2a\u76ee\u5f55\u4e00\u6837\uff08union-filesystems\uff09\u3002 overlay\u6a21\u5757\u5728\u5bb9\u5668\u6280\u672f\u4e2d\u88ab\u5e7f\u6cdb\u4f7f\u7528\uff0c\u6bd4\u5982Docker\uff0c\u56e0\u4e3a\u5b83\u5141\u8bb8\u591a\u4e2a\u5bb9\u5668\u5171\u4eab\u57fa\u7840\u955c\u50cf\uff0c\u540c\u65f6\u4fdd\u6301\u5b83\u4eec\u81ea\u5df1\u7684\u6587\u4ef6\u7cfb\u7edf\u3002 \u8981\u4f7f\u7528overlay\u6a21\u5757\uff0c\u9700\u8981\u4e24\u4e2a\u76ee\u5f55\uff1a\u8f83\u4f4e\u7684\u76ee\u5f55\uff08lower directory\uff09\u548c\u8f83\u9ad8\u7684\u76ee\u5f55\uff08upper directory\uff09\u3002\u8f83\u4f4e\u7684\u76ee\u5f55\u901a\u5e38\u662f\u53ea\u8bfb\u7684\uff0c\u5305\u542b\u539f\u59cb\u6587\u4ef6\uff0c\u800c\u8f83\u9ad8\u7684\u76ee\u5f55\u662f\u53ef\u8bfb\u5199\u7684\uff0c\u5305\u542b\u5bf9\u6587\u4ef6\u7684\u66f4\u6539\u3002\u5f53\u8bf7\u6c42\u6587\u4ef6\u65f6\uff0coverlay\u6a21\u5757\u9996\u5148\u67e5\u627e\u4e0a\u5c42\u76ee\u5f55\uff0c\u5982\u679c\u672a\u627e\u5230\uff0c\u5219\u67e5\u627e\u4e0b\u5c42\u76ee\u5f55\u3002 \u6bd4\u5982\uff1a \u521b\u5efa\u4e24\u4e2a\u76ee\u5f55\uff0c\u4e00\u4e2a\u7528\u4e8e\u8f83\u4f4e\u7684\u76ee\u5f55\uff0c\u4e00\u4e2a\u7528\u4e8e\u8f83\u9ad8\u7684\u76ee\u5f55\u3002\u7136\u540e\u4f7f\u7528overlay\u6587\u4ef6\u7cfb\u7edf\u7c7b\u578b\u5c06\u5b83\u4eec\u6302\u8f7d\u8d77\u6765\uff1a sudo mkdir /lower sudo mkdir /upper sudo mount -t overlay overlay -o lowerdir = /lower,upperdir = /upper /merged \u5728\u4e0a\u9762\u7684\u4f8b\u5b50\u4e2d\uff0c\u4e24\u4e2a\u76ee\u5f55\u7684\u5408\u5e76\u89c6\u56fe\u88ab\u521b\u5efa\u5728 /merged \u76ee\u5f55\u4e2d\u3002\u5728 /merged \u76ee\u5f55\u4e2d\u5bf9\u6587\u4ef6\u6240\u505a\u7684\u4efb\u4f55\u66f4\u6539\u90fd\u5b58\u50a8\u5728\u4e0a\u5c42\u76ee\u5f55\u4e2d\uff0c\u800c\u539f\u59cb\u6587\u4ef6\u4ecd\u7136\u5728\u4e0b\u5c42\u76ee\u5f55\u4e2d\u3002 \u4f7f\u7528\u6a21\u5757br_netfilter\uff1a br_netfilter \u662fLinux\u5185\u6838\u4e2d\u7684\u4e00\u4e2a\u6a21\u5757\uff0c\u5b83\u63d0\u4f9b\u4e86\u4e00\u79cd\u673a\u5236\u6765\u8fc7\u6ee4\u7f51\u6865\u7684\u7f51\u7edc\u6d41\u91cf\u3002\u8be5\u6a21\u5757\u5141\u8bb8\u7ba1\u7406\u5458\u914d\u7f6e\u89c4\u5219\uff0c\u4ee5\u5141\u8bb8\u6216\u62d2\u7edd\u7279\u5b9a\u7684\u7f51\u7edc\u6d41\u91cf\u901a\u8fc7\u7f51\u6865\u3002 \u7f51\u6865\u662f\u4e00\u79cd\u7f51\u7edc\u8bbe\u5907\uff0c\u5b83\u53ef\u4ee5\u8fde\u63a5\u591a\u4e2a\u7f51\u7edc\u6bb5\uff0c\u5e76\u8f6c\u53d1\u6d41\u91cf\u4ee5\u4f7f\u4e0d\u540c\u7684\u7f51\u7edc\u6bb5\u4e4b\u95f4\u901a\u4fe1\u3002 br_netfilter \u6a21\u5757\u53ef\u4ee5\u7528\u6765\u9650\u5236\u6216\u8fc7\u6ee4\u8fd9\u4e9b\u6d41\u91cf\u3002 \u5f53\u542f\u7528\u4e86 br_netfilter \u6a21\u5757\u65f6\uff0c\u5b83\u4f1a\u81ea\u52a8\u542f\u7528\u4e00\u4e2a\u79f0\u4e3a bridge-nf \u7684\u529f\u80fd\uff0c\u8be5\u529f\u80fd\u5c06\u5728\u7f51\u7edc\u6d41\u91cf\u901a\u8fc7\u7f51\u6865\u65f6\u5e94\u7528\u89c4\u5219\u3002\u7ba1\u7406\u5458\u53ef\u4ee5\u4f7f\u7528iptables\u7b49\u5de5\u5177\u6765\u914d\u7f6e\u8fd9\u4e9b\u89c4\u5219\u3002\u4f8b\u5982\uff0c\u6211\u4eec\u53ef\u4ee5\u8bbe\u5b9a\u5141\u8bb8\u4ece\u4e00\u4e2a\u7f51\u7edc\u6bb5\u5230\u53e6\u4e00\u4e2a\u7f51\u7edc\u6bb5\u7684\u6d41\u91cf\uff0c\u6216\u8005\u62d2\u7edd\u6765\u81ea\u7279\u5b9aIP\u5730\u5740\u6216\u7aef\u53e3\u7684\u6d41\u91cf\u3002 \u5728Kubernetes\u4e2d\uff0c br_netfilter \u6a21\u5757\u4e3b\u8981\u7528\u4e8e\u542f\u7528Kubernetes\u670d\u52a1\u7684\u6d41\u91cf\u8f6c\u53d1\u548c\u8d1f\u8f7d\u5747\u8861\u3002\u8fd9\u4e9b\u670d\u52a1\u4f7f\u7528\u4e86Linux\u5185\u6838\u4e2d\u7684iptables\u89c4\u5219\u6765\u7ba1\u7406\u6d41\u91cf\uff0c\u8fd9\u4e9b\u89c4\u5219\u662f\u901a\u8fc7 br_netfilter \u6a21\u5757\u5b9e\u73b0\u7684\u3002 \u5177\u4f53\u6765\u8bf4\uff0c\u5f53\u6211\u4eec\u5728Kubernetes\u96c6\u7fa4\u4e2d\u521b\u5efa\u4e00\u4e2a\u670d\u52a1\u65f6\uff0c\u8be5\u670d\u52a1\u5c06\u5206\u914d\u4e00\u4e2a\u865a\u62dfIP\u5730\u5740\uff0c\u7528\u4e8e\u4ee3\u8868\u670d\u52a1\u3002\u7136\u540e\uff0c\u901a\u8fc7iptables\u89c4\u5219\uff0c\u5c06\u8fd9\u4e2a\u865a\u62dfIP\u5730\u5740\u6620\u5c04\u5230\u4e00\u4e2a\u6216\u591a\u4e2a\u540e\u7aefPod\u7684IP\u5730\u5740\uff0c\u4ee5\u4fbf\u5728\u9700\u8981\u65f6\u5c06\u6d41\u91cf\u8def\u7531\u5230\u8fd9\u4e9bPod\u3002 \u5728\u8fd9\u4e2a\u8fc7\u7a0b\u4e2d\uff0c br_netfilter \u6a21\u5757\u8d1f\u8d23\u76d1\u89c6\u670d\u52a1\u7684\u6d41\u91cf\uff0c\u5e76\u6839\u636eiptables\u89c4\u5219\u8fdb\u884c\u8f6c\u53d1\u548c\u8d1f\u8f7d\u5747\u8861\u3002\u8fd9\u5305\u62ec\u8fc7\u6ee4\u6765\u81ea\u4e0d\u53d7\u4fe1\u4efb\u6e90\u7684\u6d41\u91cf\u4ee5\u53ca\u9650\u5236\u670d\u52a1\u7684\u8bbf\u95ee\u6743\u9650\u3002 \u9700\u8981\u6ce8\u610f\u7684\u662f\uff0c\u4e3a\u4e86\u542f\u7528Kubernetes\u670d\u52a1\u7684\u6d41\u91cf\u8f6c\u53d1\u548c\u8d1f\u8f7d\u5747\u8861\uff0c br_netfilter \u6a21\u5757\u5fc5\u987b\u5728\u6240\u6709\u8282\u70b9\u4e0a\u542f\u7528\uff0c\u5e76\u4e14\u5fc5\u987b\u914d\u7f6e\u6b63\u786e\u7684iptables\u89c4\u5219\u3002 \u7531\u4e8e br_netfilter \u6a21\u5757\u7684\u4f5c\u7528\u975e\u5e38\u5173\u952e\uff0c\u56e0\u6b64\u5728\u5347\u7ea7\u6216\u66f4\u6539\u7cfb\u7edf\u65f6\u9700\u8981\u7279\u522b\u6ce8\u610f\u5b83\u7684\u914d\u7f6e\u548c\u72b6\u6001\u3002 \u4e0b\u9762\u547d\u4ee4\u5c06\u6a21\u5757 overlay \u548c br_netfilter \u6dfb\u52a0\u5230\u914d\u7f6e\u6587\u4ef6 containerd.conf \u4e2d\u3002 cat < /etc/apt/sources.list << EOF deb http://mirrors.cloud.aliyuncs.com/ubuntu/ focal main restricted deb-src http://mirrors.cloud.aliyuncs.com/ubuntu/ focal main restricted deb http://mirrors.cloud.aliyuncs.com/ubuntu/ focal-updates main restricted deb-src http://mirrors.cloud.aliyuncs.com/ubuntu/ focal-updates main restricted deb http://mirrors.cloud.aliyuncs.com/ubuntu/ focal universe deb-src http://mirrors.cloud.aliyuncs.com/ubuntu/ focal universe deb http://mirrors.cloud.aliyuncs.com/ubuntu/ focal-updates universe deb-src http://mirrors.cloud.aliyuncs.com/ubuntu/ focal-updates universe deb http://mirrors.cloud.aliyuncs.com/ubuntu/ focal multiverse deb-src http://mirrors.cloud.aliyuncs.com/ubuntu/ focal multiverse deb http://mirrors.cloud.aliyuncs.com/ubuntu/ focal-updates multiverse deb-src http://mirrors.cloud.aliyuncs.com/ubuntu/ focal-updates multiverse deb http://mirrors.cloud.aliyuncs.com/ubuntu/ focal-backports main restricted universe multiverse deb-src http://mirrors.cloud.aliyuncs.com/ubuntu/ focal-backports main restricted universe multivers deb http://mirrors.cloud.aliyuncs.com/ubuntu focal-security main restricted deb-src http://mirrors.cloud.aliyuncs.com/ubuntu focal-security main restricted deb http://mirrors.cloud.aliyuncs.com/ubuntu focal-security universe deb-src http://mirrors.cloud.aliyuncs.com/ubuntu focal-security universe # deb http://mirrors.cloud.aliyuncs.com/ubuntu focal-security multiverse # deb-src http://mirrors.cloud.aliyuncs.com/ubuntu focal-security multiverse EOF \u5b89\u88c5Containered\u3002 sudo apt-get update && sudo apt-get install -y containerd \u914d\u7f6eContainerd\u3002\u4fee\u6539\u6587\u4ef6 /etc/containerd/config.toml \u3002 sudo mkdir -p /etc/containerd containerd config default | sudo tee /etc/containerd/config.toml sudo vi /etc/containerd/config.toml \u4fee\u6539\u53c2\u6570 sandbox_image \u7684\u503c\u4e3a \"registry.aliyuncs.com/google_containers/pause:3.6\" \u3002 \u4fee\u6539\u53c2\u6570 SystemdCgroup \u7684\u503c\u4e3a true \u3002 [plugins] [plugins.\"io.containerd.gc.v1.scheduler\"] [plugins.\"io.containerd.grpc.v1.cri\"] sandbox_image = \"registry.aliyuncs.com/google_containers/pause:3.6\" [plugins.\"io.containerd.grpc.v1.cri\".cni] [plugins.\"io.containerd.grpc.v1.cri\".containerd] [plugins.\"io.containerd.grpc.v1.cri\".containerd.default_runtime] [plugins.\"io.containerd.grpc.v1.cri\".containerd.default_runtime.options] [plugins.\"io.containerd.grpc.v1.cri\".containerd.runtimes] [plugins.\"io.containerd.grpc.v1.cri\".containerd.runtimes.runc] [plugins.\"io.containerd.grpc.v1.cri\".containerd.runtimes.runc.options] SystemdCgroup = true \u91cd\u542fContainerd\u670d\u52a1\u3002 sudo systemctl restart containerd sudo systemctl status containerd \u5b89\u88c5nerdctl \u00b6 \u5728\u6240\u6709\u8282\u70b9\u4e0a\u5b89\u88c5nerdctl\u670d\u52a1\u3002 nerdctl \u670d\u52a1\u652f\u6301Contanerd\u6240\u63d0\u4f9b\u7684\u5bb9\u5668\u5316\u7279\u6027\uff0c\u7279\u522b\u662f\u4e00\u4e9bDocker\u4e0d\u5177\u5907\u7684\u65b0\u7279\u6027\u3002 \u4e8c\u8fdb\u5236\u5b89\u88c5\u5305\u53ef\u4ee5\u901a\u8fc7\u8fd9\u4e2a\u94fe\u63a5\u53d6\u5f97: Releases \u00b7 containerd/nerdctl \u00b7 GitHub \u3002 wget https://github.com/containerd/nerdctl/releases/download/v0.22.2/nerdctl-0.22.2-linux-amd64.tar.gz tar -zxvf nerdctl-0.22.2-linux-amd64.tar.gz sudo cp nerdctl /usr/bin/ \u9a8c\u8bc1 nerdctl \u670d\u52a1\u3002 sudo nerdctl --help \u5217\u51fa\u521d\u59cb\u5b89\u88c5Kubernetes\u65f6\u7684\u5bb9\u5668container\u5217\u8868\u3002 nerdctl -n k8s.io ps \u5b89\u88c5kubeadm \u00b6 \u5728\u6240\u6709\u8282\u70b9\u4e0a\u5b89\u88c5Kubeadm\uff0ckubectl\uff0ckubelet\u3002 \u5b89\u88c5\u548c\u5347\u7ea7Ubuntu\u7cfb\u7edf\u4f9d\u8d56\u5305 apt-transport-https , ca-certificates , curl \u3002 sudo apt-get update && sudo apt-get install -y apt-transport-https ca-certificates curl \u5b89\u88c5gpg\u8bc1\u4e66\u3002 curl https://mirrors.aliyun.com/kubernetes/apt/doc/apt-key.gpg | sudo apt-key add - \u6dfb\u52a0Kubernetes\u5b89\u88c5\u6e90\u3002 cat << EOF > /etc/apt/sources.list.d/kubernetes.list deb https://mirrors.aliyun.com/kubernetes/apt/ kubernetes-xenial main EOF \u5b89\u88c5\u548c\u5347\u7ea7Ubuntu\u7cfb\u7edf\u4f9d\u8d56\u5305\u3002 sudo apt-get update sudo apt-get install ebtables sudo apt-get install libxtables12 sudo apt-get upgrade iptables \u68c0\u67e5\u5f53\u524d\u53ef\u7528\u7684 kubeadm \u7248\u672c\u3002 apt policy kubeadm \u5f53\u524d\u5b89\u88c5 1.24.0-00 \u7248\u672c\u7684 kubeadm \uff0c\u540e\u7eed\u4f1a\u5347\u7ea7\u5230 1.24.2 \u7248\u672c\u3002 sudo apt-get -y install kubelet = 1 .24.0-00 kubeadm = 1 .24.0-00 kubectl = 1 .24.0-00 --allow-downgrades \u914d\u7f6e\u4e3b\u8282\u70b9 \u00b6 kubeadm\u521d\u59cb\u5316 \u00b6 \u5728\u627f\u62c5\u4e3b\u8282\u70b9\u7684\u865a\u62df\u673a\u91cc\u914d\u7f6e\u63a7\u5236\u5e73\u9762\uff08Control Plane\uff09\u3002 \u68c0\u67e5 kubeadm \u5f53\u524d\u9ed8\u8ba4\u914d\u7f6e\u53c2\u6570\u3002 kubeadm config print init-defaults \u7c7b\u4f3c\u7ed3\u679c\u5982\u4e0b\u3002\u4fdd\u5b58\u9ed8\u8ba4\u914d\u7f6e\u7684\u7ed3\u679c\uff0c\u540e\u7eed\u4f1a\u4f5c\u4e3a\u53c2\u8003\u3002 apiVersion : kubeadm.k8s.io/v1beta3 bootstrapTokens : - groups : - system:bootstrappers:kubeadm:default-node-token token : abcdef.0123456789abcdef ttl : 24h0m0s usages : - signing - authentication kind : InitConfiguration localAPIEndpoint : advertiseAddress : 1.2.3.4 bindPort : 6443 nodeRegistration : criSocket : unix:///var/run/containerd/containerd.sock imagePullPolicy : IfNotPresent name : node taints : null --- apiServer : timeoutForControlPlane : 4m0s apiVersion : kubeadm.k8s.io/v1beta3 certificatesDir : /etc/kubernetes/pki clusterName : kubernetes controllerManager : {} dns : {} etcd : local : dataDir : /var/lib/etcd imageRepository : k8s.gcr.io kind : ClusterConfiguration kubernetesVersion : 1.24.0 networking : dnsDomain : cluster.local serviceSubnet : 10.96.0.0/12 scheduler : {} \u6a21\u62df\u5b89\u88c5\u548c\u6b63\u5f0f\u5b89\u88c5\u3002 \u901a\u8fc7\u547d\u4ee4 kubeadm init \u8fdb\u884c\u4e3b\u8282\u70b9\u7684\u521d\u59cb\u5316\uff0c\u4e0b\u9762\u662f\u8fd9\u4e2a\u547d\u4ee4\u4e3b\u8981\u53c2\u6570\u7684\u8bf4\u660e\uff0c\u7279\u522b\u662f\u7f51\u7edc\u53c2\u6570\u7684\u4e09\u4e2a\u9009\u62e9\u3002 --pod-network-cidr : \u6307\u5b9apod\u4f7f\u7528\u7684IP\u5730\u5740\u8303\u56f4\u3002\u5982\u679c\u6307\u5b9a\u4e86\u8be5\u53c2\u6570\uff0c\u5219Control Plane\u4f1a\u81ea\u52a8\u8bb2\u6307\u5b9a\u7684CIDR\u5206\u914d\u7ed9\u6bcf\u4e2a\u8282\u70b9\u3002 IP\u5730\u5740\u6bb5 10.244.0.0/16 \u662fFlannel\u7f51\u7edc\u7ec4\u4ef6\u9ed8\u8ba4\u7684\u5730\u5740\u8303\u56f4\u3002\u5982\u679c\u9700\u8981\u4fee\u6539Flannel\u7684IP\u5730\u5740\u6bb5\uff0c\u9700\u8981\u5728\u8fd9\u91cc\u6307\u5b9a\uff0c\u4e14\u5728\u90e8\u7f72Flannel\u65f6\u4e5f\u8981\u4fdd\u6301\u4e00\u81f4\u7684IP\u6bb5\u3002 --apiserver-bind-port : API\u670d\u52a1\uff08API Server\uff09\u7684\u7aef\u53e3\uff0c\u9ed8\u8ba4\u65f66443\u3002 --service-cidr : \u6307\u5b9a\u670d\u52a1\uff08service\uff09\u7684IP\u5730\u5740\u6bb5\uff0c\u9ed8\u8ba4\u662f 10.96.0.0/12 \u3002 \u63d0\u793a\uff1a \u670d\u52a1VIPs\uff08service VIPs\uff09\uff0c\u4e5f\u79f0\u4f5c\u96c6\u7fa4IP\uff08Cluster IP\uff09\uff0c\u901a\u8fc7\u53c2\u6570 --service-cidr \u6307\u5b9a\u3002 podCIDR\uff0c\u4e5f\u79f0\u4e3aendpoint IP\uff0c\u901a\u8fc7\u53c2\u6570 --pod-network-cidr \u6307\u5b9a\u3002 \u67094\u79cd\u5178\u578b\u7684\u7f51\u7edc\u95ee\u9898\uff1a \u9ad8\u5ea6\u8026\u5408\u7684\u5bb9\u5668\u4e0e\u5bb9\u5668\u4e4b\u95f4\u7684\u901a\u4fe1\uff1a\u8fd9\u53ef\u4ee5\u901a\u8fc7Pod\uff08podCIDR\uff09\u548c\u672c\u5730\u4e3b\u673a\u901a\u4fe1\u6765\u89e3\u51b3\u3002 Pod\u5bf9Pod\u901a\u4fe1\uff08Pod-to-Pod\uff09\uff1a \u4e5f\u88ab\u79f0\u4e3a\u5bb9\u5668\u5bf9\u5bb9\u5668\u901a\u4fe1\uff08container-to-container\uff09\u3002 \u5728Flannel\u7f51\u7edc\u63d2\u4ef6\u4e2d\u7684\u793a\u4f8b\u6d41\u7a0b\u662f\uff1aPod \u2192 veth\u5bf9 \u2192 cni0 \u2192 flannel.1 \u2192 \u5bbf\u4e3b\u673aeth0 \u2192 \u5bbf\u4e3b\u673aeth0 \u2192 flannel.1 \u2192 cni0 \u2192 veth\u5bf9 \u2192 Pod\u3002 Pod\u5bf9Service\u901a\u4fe1\uff08Pod-to-Service\uff09\uff1a \u6d41\u7a0b: Pod \u2192 \u5185\u6838 \u2192 Service iptables \u2192 Service \u2192 Pod iptables \u2192 Pod\u3002 \u5916\u90e8\u5bf9Service\u901a\u4fe1\uff08External-to-Service\uff09\uff1a \u8d1f\u8f7d\u5747\u8861\u5668: SLB \u2192 NodePort \u2192 Service \u2192 Pod\u3002 kube-proxy \u662f\u5bf9iptables\u8d1f\u8d23\uff0c\u4e0d\u662f\u7f51\u7edc\u6d41\u91cf\uff08traffic\uff09\u3002 kube-proxy \u662fKubernetes\u96c6\u7fa4\u4e2d\u7684\u4e00\u4e2a\u7ec4\u4ef6\uff0c\u8d1f\u8d23\u4e3aService\u63d0\u4f9b\u4ee3\u7406\u670d\u52a1\uff0c\u540c\u65f6\u4e5f\u662fKubernetes\u7f51\u7edc\u6a21\u578b\u4e2d\u7684\u91cd\u8981\u7ec4\u6210\u90e8\u5206\u4e4b\u4e00\u3002 kube-proxy \u4f1a\u5728\u6bcf\u4e2a\u8282\u70b9\u4e0a\u542f\u52a8\u4e00\u4e2a\u4ee3\u7406\u8fdb\u7a0b\uff0c\u901a\u8fc7\u76d1\u542cKubernetes API Server\u7684Service\u548cEndpoint\u7684\u53d8\u5316\u6765\u7ef4\u62a4\u4e00\u4e2a\u672c\u5730\u7684Service\u548cEndpoint\u7684\u7f13\u5b58\u3002\u5f53\u6709\u8bf7\u6c42\u5230\u8fbe\u67d0\u4e2aService\u65f6\uff0c kube-proxy \u4f1a\u6839\u636e\u8be5Service\u7684\u7c7b\u578b\uff08ClusterIP\u3001NodePort\u3001LoadBalancer\u3001ExternalName\uff09\u548c\u7aef\u53e3\u53f7\uff0c\u751f\u6210\u76f8\u5e94\u7684iptables\u89c4\u5219\uff0c\u5c06\u8bf7\u6c42\u8f6c\u53d1\u7ed9Service\u6240\u4ee3\u7406\u7684\u540e\u7aefPod\u3002 iptables\u662fLinux\u7cfb\u7edf\u4e2d\u7684\u4e00\u4e2a\u91cd\u8981\u7f51\u7edc\u5de5\u5177\uff0c\u53ef\u4ee5\u8bbe\u7f6eIP\u5305\u7684\u8fc7\u6ee4\u3001\u8f6c\u53d1\u548c\u4fee\u6539\u89c4\u5219\uff0c\u53ef\u4ee5\u5b9e\u73b0\u7f51\u7edc\u5c42\u7684\u9632\u706b\u5899\u3001NAT\u7b49\u529f\u80fd\u3002\u5728Kubernetes\u96c6\u7fa4\u4e2d\uff0c kube-proxy \u901a\u8fc7\u751f\u6210\u548c\u66f4\u65b0iptables\u89c4\u5219\uff0c\u6765\u5b9e\u73b0Service\u548cEndpoint\u4e4b\u95f4\u7684\u8f6c\u53d1\u548c\u4ee3\u7406\u3002\u5177\u4f53\u6765\u8bf4\uff0ckube-proxy\u4f1a\u4e3a\u6bcf\u4e2aService\u521b\u5efa\u4e09\u6761iptables\u89c4\u5219\u94fe\uff08nat\u8868\u4e2d\u7684KUBE-SERVICES\u548cKUBE-NODEPORTS\u94fe\uff0c\u4ee5\u53cafilter\u8868\u4e2d\u7684KUBE-SVC-XXXXX\u94fe\uff09\uff0c\u901a\u8fc7\u8fd9\u4e9b\u89c4\u5219\u94fe\uff0c\u5c06\u8bf7\u6c42\u8f6c\u53d1\u5230\u76f8\u5e94\u7684Pod\u6216\u8005Service\u4e0a\u3002 \u56e0\u6b64\uff0c kube-proxy \u548ciptables\u662f\u7d27\u5bc6\u76f8\u5173\u7684\u4e24\u4e2a\u7ec4\u4ef6\uff0c\u901a\u8fc7iptables\u89c4\u5219\u6765\u5b9e\u73b0Service\u548cPod\u4e4b\u95f4\u7684\u8f6c\u53d1\u548c\u4ee3\u7406\u3002\u8fd9\u79cd\u5b9e\u73b0\u65b9\u5f0f\u5177\u6709\u53ef\u6269\u5c55\u6027\u548c\u9ad8\u53ef\u7528\u6027\uff0c\u540c\u65f6\u4e5f\u63d0\u4f9b\u4e86\u4e00\u79cd\u7075\u6d3b\u7684\u7f51\u7edc\u6a21\u578b\uff0c\u53ef\u4ee5\u65b9\u4fbf\u5730\u5b9e\u73b0\u670d\u52a1\u53d1\u73b0\u3001\u8d1f\u8f7d\u5747\u8861\u7b49\u529f\u80fd\u3002 sudo kubeadm init \\ --dry-run \\ --pod-network-cidr = 10 .244.0.0/16 \\ --service-cidr 11 .244.0.0/16 \\ --image-repository = registry.aliyuncs.com/google_containers \\ --kubernetes-version = v1.24.0 sudo kubeadm init \\ --pod-network-cidr = 10 .244.0.0/16 \\ --service-cidr 11 .244.0.0/16 \\ --image-repository = registry.aliyuncs.com/google_containers \\ --kubernetes-version = v1.24.0 sudo kubeadm init \\ --pod-network-cidr = 10 .244.0.0/16 \\ --service-cidr 11 .244.0.0/16 \\ --kubernetes-version = v1.24.0 kubeconfig\u6587\u4ef6 \u00b6 \u7ed9\u5f53\u524d\u5b89\u88c5\u7528\u6237\u914d\u7f6e kubeconfig \u6587\u4ef6\uff08\u5f53\u524d\u4f8b\u5b50\u662f\u7528\u6237 vagrant \uff09\u3002 mkdir -p $HOME /.kube sudo cp -i /etc/kubernetes/admin.conf $HOME /.kube/config sudo chown $( id -u ) : $( id -g ) $HOME /.kube/config Kubernetes \u63d0\u4f9b\u4e86\u4e00\u4e2a\u547d\u4ee4\u884c\u5de5\u5177 kubectl \uff0c\u7528\u4e8e\u4f7f\u7528 Kubernetes API \u4e0e Kubernetes \u96c6\u7fa4\u7684\u63a7\u5236\u5e73\u9762\u8fdb\u884c\u901a\u4fe1\u3002 kubectl \u63a7\u5236 Kubernetes cluster manager \uff08\u96c6\u7fa4\u7ba1\u7406\u5668\uff09\u3002 \u5bf9\u4e8e\u914d\u7f6e\uff0ckubectl \u5728 $HOME/.kube \u76ee\u5f55\u4e2d\u67e5\u627e\u4e00\u4e2a\u540d\u4e3a config \u7684\u6587\u4ef6\uff0c\u8be5\u6587\u4ef6\u662f\u7531 kubeadm init \u751f\u6210\u7684\u6587\u4ef6 /etc/kubernetes/admin.conf \u7684\u526f\u672c\u3002 \u6211\u4eec\u53ef\u4ee5\u901a\u8fc7\u8bbe\u7f6e KUBECONFIG \u73af\u5883\u53d8\u91cf\u6216\u8bbe\u7f6e --kubeconfig flag \u6807\u5fd7\u6765\u6307\u5b9a\u5176\u4ed6 kubeconfig \u6587\u4ef6\u3002\u5982\u679c KUBECONFIG \u73af\u5883\u53d8\u91cf\u4e0d\u5b58\u5728\uff0ckubectl \u5c06\u4f7f\u7528\u9ed8\u8ba4\u7684 kubeconfig \u6587\u4ef6 $HOME/.kube/config \u3002 kubeconfig \u6587\u4ef6\u4e2d\u7684 context\uff08\u4e0a\u4e0b\u6587\uff09 \u5143\u7d20\u7528\u4e8e\u5c06\u8bbf\u95ee\u53c2\u6570\u5206\u7ec4\u5230\u4e00\u4e2a\u65b9\u4fbf\u7684\u540d\u79f0\u4e0b\u3002\u6bcf\u4e2a\u4e0a\u4e0b\u6587\u90fd\u6709\u4e09\u4e2a\u53c2\u6570\uff1a\u96c6\u7fa4\u3001\u547d\u540d\u7a7a\u95f4\u548c\u7528\u6237\u3002\u9ed8\u8ba4\u60c5\u51b5\u4e0b\uff0ckubectl \u547d\u4ee4\u884c\u5de5\u5177\u4f7f\u7528\u5f53\u524d\u4e0a\u4e0b\u6587\u4e2d\u7684\u53c2\u6570\u4e0e\u96c6\u7fa4\u901a\u4fe1\u3002 \u6587\u4ef6 .kube/config \u7684\u4f8b\u5b50\uff1a apiVersion : v1 clusters : - cluster : certificate-authority-data : server : https://:6443 name : contexts : - context : cluster : namespace : user : name : @ current-context : kind : Config preferences : {} users : - name : user : client-certificate-data : client-key-data : \u8bfb\u53d6\u5f53\u524d\u4e0a\u4e0b\u6587\uff1a kubectl config get-contexts \u8fd0\u884c\u7ed3\u679c\uff1a CURRENT NAME CLUSTER AUTHINFO NAMESPACE * kubernetes-admin@kubernetes kubernetes kubernetes-admin \u914d\u7f6e\u5de5\u4f5c\u8282\u70b9 \u00b6 \u4f7f\u7528 kubeadm token \u6765\u751f\u6210\u52a0\u5165\u96c6\u7fa4\u7684\u4ee4\u724c\uff08token\uff09\u548c\u54c8\u897f\u503c\uff08hash value\uff09\u3002 kubeadm token create --print-join-command \u5728\u6240\u6709\u5de5\u4f5c\u8282\u70b9\u4e0a\u6267\u884c\u4e0b\u9762\u7684\u547d\u4ee4\uff0c\u5c06\u5de5\u4f5c\u8282\u70b9\u52a0\u5165Kubernetes\u96c6\u7fa4\u3002 # kubeadm join :6443 --token --discovery-token-ca-cert-hash \u6267\u884c\u4e0b\u9762\u547d\u4ee4\u68c0\u67e5\u6240\u6709\u8282\u70b9\u7684\u72b6\u6001\u3002 \u5f53\u524d\u6240\u6709\u8282\u70b9\u7684\u72b6\u6001\u90fd\u662f NotReady \u3002\u76ee\u524d\u4e0d\u9700\u8981\u505a\u4ec0\u4e48\uff0c\u540e\u9762\u6211\u4eec\u4f1a\u5b89\u88c5\u76f8\u5173\u7684\u7f51\u7edc\u670d\u52a1\uff08Calico \u6216 Flannel\uff09\uff0c\u5404\u8282\u70b9\u7684\u72b6\u6001\u5c31\u4f1a\u53d8\u6210Ready\u72b6\u6001\u3002 \u5b89\u88c5Calico\u6216Flannel \u00b6 \u5728\u63a7\u5236\u5e73\u9762Control Plane\u4e0a\u5b89\u88c5Calico\u6216\u8005Flannel\u3002\u5982\u679c\u9700\u8981\u914d\u7f6e\u7f51\u7edc\u7b56\u7565\uff0c\u5219\u9009\u62e9Calico\u3002 \u5b89\u88c5Flannel \u00b6 Flannel \u662f\u4e3a Kubernetes \u8bbe\u8ba1\u7684\u4e00\u79cd\u7b80\u5355\u6613\u7528\u7684\u914d\u7f6e\u4e09\u5c42\u7f51\u7edc\u7684\u65b9\u6cd5\u3002 \u90e8\u7f72Flannel\uff1a \u5728 kube-flannel.yml \u4e2d\uff0c\u6211\u4eec\u53ef\u4ee5\u83b7\u53d6 Flannel \u7684\u9ed8\u8ba4\u7f51\u7edc\u8bbe\u7f6e\uff0c\u5b83\u4e0e\u6211\u4eec\u5728\u4f7f\u7528 kubeadm \u521d\u59cb\u5316\u96c6\u7fa4\u65f6\u6307\u5b9a\u7684\u53c2\u6570 --pod-network-cidr=10.244.0.0/16 \u76f8\u540c\u3002 net - co nf .jso n : | { \"Network\" : \"10.244.0.0/16\" , \"Backend\" : { \"Type\" : \"vxlan\" } } \u521b\u5efaFlannel\u670d\u52a1\u3002 apply -f https://raw.githubusercontent.com/coreos/flannel/master/Documentation/kube-flannel.yml \u8f93\u51fa\u7ed3\u679c\uff1a Warning: policy/v1beta1 PodSecurityPolicy is deprecated in v1.21+, unavailable in v1.25+ podsecuritypolicy.policy/psp.flannel.unprivileged created clusterrole.rbac.authorization.k8s.io/flannel created clusterrolebinding.rbac.authorization.k8s.io/flannel created serviceaccount/flannel created configmap/kube-flannel-cfg created daemonset.apps/kube-flannel-ds created \u5b89\u88c5Calico \u00b6 \u5b89\u88c5\u6307\u5bfc\u624b\u518c\uff1a End-to-end Calico installation \u3002 \u4e0b\u8f7d\u5e76\u5b89\u88c5Calico\u670d\u52a1\u3002 curl https://docs.projectcalico.org/manifests/calico.yaml -O kubectl apply -f calico.yaml \u8f93\u51fa\u7ed3\u679c\uff1a configmap/calico-config created customresourcedefinition.apiextensions.k8s.io/bgpconfigurations.crd.projectcalico.org created customresourcedefinition.apiextensions.k8s.io/bgppeers.crd.projectcalico.org created customresourcedefinition.apiextensions.k8s.io/blockaffinities.crd.projectcalico.org created customresourcedefinition.apiextensions.k8s.io/caliconodestatuses.crd.projectcalico.org created customresourcedefinition.apiextensions.k8s.io/clusterinformations.crd.projectcalico.org created customresourcedefinition.apiextensions.k8s.io/felixconfigurations.crd.projectcalico.org created customresourcedefinition.apiextensions.k8s.io/globalnetworkpolicies.crd.projectcalico.org created customresourcedefinition.apiextensions.k8s.io/globalnetworksets.crd.projectcalico.org created customresourcedefinition.apiextensions.k8s.io/hostendpoints.crd.projectcalico.org created customresourcedefinition.apiextensions.k8s.io/ipamblocks.crd.projectcalico.org created customresourcedefinition.apiextensions.k8s.io/ipamconfigs.crd.projectcalico.org created customresourcedefinition.apiextensions.k8s.io/ipamhandles.crd.projectcalico.org created customresourcedefinition.apiextensions.k8s.io/ippools.crd.projectcalico.org created customresourcedefinition.apiextensions.k8s.io/ipreservations.crd.projectcalico.org created customresourcedefinition.apiextensions.k8s.io/kubecontrollersconfigurations.crd.projectcalico.org created customresourcedefinition.apiextensions.k8s.io/networkpolicies.crd.projectcalico.org created customresourcedefinition.apiextensions.k8s.io/networksets.crd.projectcalico.org created clusterrole.rbac.authorization.k8s.io/calico-kube-controllers created clusterrolebinding.rbac.authorization.k8s.io/calico-kube-controllers created clusterrole.rbac.authorization.k8s.io/calico-node created clusterrolebinding.rbac.authorization.k8s.io/calico-node created daemonset.apps/calico-node created serviceaccount/calico-node created deployment.apps/calico-kube-controllers created serviceaccount/calico-kube-controllers created poddisruptionbudget.policy/calico-kube-controllers created \u9a8c\u8bc1Calico\u670d\u52a1\u72b6\u6001\uff1a kubectl get pod -n kube-system | grep calico \u8f93\u51fa\u7ed3\u679c\uff1a calico-kube-controllers-555bc4b957-l8bn2 0 /1 Pending 0 28s calico-node-255pc 0 /1 Init:1/3 0 29s calico-node-7tmnb 0 /1 Init:1/3 0 29s calico-node-w8nvl 0 /1 Init:1/3 0 29s \u68c0\u67e5\u96c6\u7fa4\u7684\u7f51\u7edc\u72b6\u6001\uff1a sudo nerdctl network ls \u8f93\u51fa\u7ed3\u679c\uff1a NETWORK ID NAME FILE k8s-pod-network /etc/cni/net.d/10-calico.conflist 0 bridge /etc/cni/net.d/nerdctl-bridge.conflist host none \u68c0\u67e5\u96c6\u7fa4\u72b6\u6001 \u00b6 \u5728\u4e3b\u8282\u70b9\u4e0a\u6267\u884c\u547d\u4ee4 kubectl cluster-info \u53ef\u4ee5\u5f97\u5230\u4e0b\u9762\u7684\u4fe1\u606f\uff1a \u63a7\u5236\u5e73\u9762\uff08control plane\uff09\u8fd0\u884c\u5728 https://:6443 CoreDNS\u670d\u52a1\u8fd0\u884c\u5728 https://:6443/api/v1/namespaces/kube-system/services/kube-dns:dns/proxy kubectl cluster-info \u67e5\u770b\u8282\u70b9\u8fd0\u884c\u72b6\u6001\u3002\u6b64\u65f6\uff0c\u6240\u6709\u8282\u70b9\u90fd\u662f Ready \u7684\u6b63\u5e38\u72b6\u6001\u4e86\u3002 OS Image: Ubuntu 20.04.4 LTS Kernel Version: 5.4.0-122-generic Container Runtime: containerd://1.5.9 kubectl get nodes -owide \u8f93\u51fa\u7ed3\u679c\uff1a NAME STATUS ROLES AGE VERSION cka001 Ready control-plane 13m v1.24.0 cka002 Ready 8m35s v1.24.0 cka003 Ready 8m26s v1.24.0 \u67e5\u770bPods\u7684\u72b6\u6001\u3002 kubectl get pod -A \u8f93\u51fa\u7ed3\u679c\uff1a NAMESPACE NAME READY STATUS RESTARTS AGE kube-system calico-kube-controllers-555bc4b957-l8bn2 1/1 Running 0 7m18s kube-system calico-node-255pc 1/1 Running 0 7m19s kube-system calico-node-7tmnb 1/1 Running 0 7m19s kube-system calico-node-w8nvl 1/1 Running 0 7m19s kube-system coredns-74586cf9b6-4jwmk 1/1 Running 0 15m kube-system coredns-74586cf9b6-c5mll 1/1 Running 0 15m kube-system etcd-cka001 1/1 Running 0 15m kube-system kube-apiserver-cka001 1/1 Running 0 15m kube-system kube-controller-manager-cka001 1/1 Running 0 15m kube-system kube-proxy-dmj2t 1/1 Running 0 15m kube-system kube-proxy-n77zw 1/1 Running 0 11m kube-system kube-proxy-qs6rf 1/1 Running 0 11m kube-system kube-scheduler-cka001 1/1 Running 0 15m \u66f4\u65b0\u5b89\u88c5 \u00b6 Bash\u81ea\u52a8\u8865\u5168 \u00b6 \u5728\u6bcf\u4e2a\u8282\u70b9\u4e0a\u914d\u7f6eBash\u81ea\u52a8\u8865\u5168\u529f\u80fd\u3002 \u53c2\u8003 \u6307\u5bfc \u8bbe\u7f6e kubectl \u81ea\u52a8\u8865\u5168\u529f\u80fdauto-completion \u3002 apt install -y bash-completion source /usr/share/bash-completion/bash_completion source < ( kubectl completion bash ) echo \"source <(kubectl completion bash)\" >> ~/.bashrc source ~/.bashrc \u522b\u540d \u00b6 \u5982\u679c\u6211\u4eec\u4e3a kubectl \u8bbe\u7f6e\u4e00\u4e2a\u522b\u540d\uff0c\u6211\u4eec\u53ef\u4ee5\u901a\u8fc7\u4e00\u4e9b\u65b9\u6cd5\u6765\u6269\u5c55 shell \u81ea\u52a8\u8865\u5168\u529f\u80fd\uff0c\u4f7f\u5176\u80fd\u591f\u4e0e\u8be5\u522b\u540d\u4e00\u8d77\u4f7f\u7528\u3002 \u4e00\u79cd\u65b9\u6cd5\u662f\u5728 Bash shell \u914d\u7f6e\u6587\u4ef6\uff08\u5982 .bashrc \u6216 .bash_profile\uff09\u4e2d\u8bbe\u7f6e\u522b\u540d\uff0c\u5e76\u4e3a\u8be5\u522b\u540d\u6307\u5b9a kubectl \u7684\u5b8c\u6574\u8def\u5f84\u3002\u4f8b\u5982\uff0c\u53ef\u4ee5\u5728 .bashrc \u6587\u4ef6\u4e2d\u6dfb\u52a0\u4ee5\u4e0b\u5185\u5bb9\uff1a alias k = 'path/to/kubectl' \u7136\u540e\uff0c\u53ef\u4ee5\u4f7f\u7528\u4ee5\u4e0b\u547d\u4ee4\u91cd\u65b0\u52a0\u8f7d .bashrc \u6587\u4ef6\uff1a source ~/.bashrc \u63a5\u4e0b\u6765\uff0c\u53ef\u4ee5\u4f7f\u7528 k \u547d\u4ee4\u6765\u4ee3\u66ff kubectl \u547d\u4ee4\uff0c\u5e76\u5728\u5176\u540e\u9762\u6dfb\u52a0\u76f8\u5e94\u7684\u53c2\u6570\u548c\u9009\u9879\u3002\u5f53\u4f7f\u7528\u81ea\u52a8\u8865\u5168\u529f\u80fd\u65f6\uff0cBash shell \u4f1a\u81ea\u52a8\u5c06 k \u522b\u540d\u8f6c\u6362\u4e3a kubectl \u7684\u5b8c\u6574\u8def\u5f84\uff0c\u5e76\u5bf9\u5176\u8fdb\u884c\u81ea\u52a8\u8865\u5168\u3002 \u53e6\u4e00\u79cd\u65b9\u6cd5\u662f\u4f7f\u7528 Bash shell \u5185\u7f6e\u7684 complete \u51fd\u6570\u6765\u4e3a\u522b\u540d\u8bbe\u7f6e\u81ea\u52a8\u8865\u5168\u529f\u80fd\u3002\u4f8b\u5982\uff0c\u53ef\u4ee5\u5728 .bashrc \u6587\u4ef6\u4e2d\u6dfb\u52a0\u4ee5\u4e0b\u5185\u5bb9\uff1a echo 'alias k=kubectl' >>~/.bashrc echo 'complete -o default -F __start_kubectl k' >>~/.bashrc \u8fd9\u5c06\u4e3a\u522b\u540d k \u8bbe\u7f6e\u81ea\u52a8\u8865\u5168\u529f\u80fd\uff0c\u5e76\u5c06\u5176\u4e0e kubectl \u7684\u81ea\u52a8\u8865\u5168\u51fd\u6570 __start_kubectl \u5173\u8054\u8d77\u6765\u3002\u8fd9\u6837\uff0c\u5f53\u7528\u6237\u5728 k \u547d\u4ee4\u540e\u8f93\u5165Tab\u952e\u65f6\uff0cBash shell \u4f1a\u81ea\u52a8\u8c03\u7528 __start_kubectl \u51fd\u6570\uff0c\u5e76\u4e3a\u7528\u6237\u63d0\u4f9b\u76f8\u5e94\u7684\u81ea\u52a8\u8865\u5168\u5efa\u8bae\u3002 \u66f4\u65b0\u9ed8\u8ba4Context \u00b6 \u67e5\u770b\u5f53\u524d\u7684 context \u5217\u8868\uff1a kubectl config get-contexts \u8fd9\u4e2a\u547d\u4ee4\u4f1a\u5217\u51fa\u6240\u6709\u53ef\u7528\u7684 context \u5217\u8868\uff0c\u5e76\u6807\u8bb0\u51fa\u5f53\u524d\u6b63\u5728\u4f7f\u7528\u7684 context\u3002 \u7c7b\u4f3c\u4e0b\u9762\u7ed3\u679c\uff1a kubernetes-admin@kubernetes \u662fContext\u540d\u3002 kubernetes \u662f\u96c6\u7fa4\u540d\u3002 kubernetes-admin \u662f\u7528\u6237\u540d\u3002 \u5f53\u524d\u4f8b\u5b50\u4e2d\u6ca1\u6709\u6307\u5b9a\u540d\u79f0\u7a7a\u95f4\u3002 CURRENT NAME CLUSTER AUTHINFO NAMESPACE * kubernetes-admin@kubernetes kubernetes kubernetes-admin \u66f4\u65b0context\u3002\u4f8b\u5982\uff0c\u66f4\u65b0context\u7684\u9ed8\u8ba4\u540d\u79f0\u7a7a\u95f4\u7b49\u3002 # Usage: kubectl config set-context --cluster = --namespace = --user = # Set default namespace kubectl config set-context kubernetes-admin@kubernetes --cluster = kubernetes --namespace = default --user = kubernetes-admin \u5728\u4e0d\u540c\u7684context\u4e4b\u95f4\u5207\u6362\u3002 # Usage: kubectl config use-context # Switch to new context kubectl config use-context kubernetes-admin@kubernetes \u53c2\u8003\u8d44\u6599\uff1a kubectl [commandline \u91cd\u7f6e\u96c6\u7fa4 \u00b6 \u6ce8\u610f\uff1a\u4e0b\u9762\u7684\u64cd\u4f5c\u4f1a\u91cd\u7f6e\u5f53\u524d\u96c6\u7fa4\uff08\u5220\u9664\u96c6\u7fa4\uff09\u3002 \u5220\u9664\u96c6\u7fa4\u4e2d\u6240\u6709\u8282\u70b9\u3002 kubeadm reset \u6e05\u9664 iptables \u4e2d\u5df2\u5b9a\u4e49\u7684\u89c4\u5219\u3002 iptables -F && iptables -t nat -F && iptables -t mangle -F && iptables -X \u6e05\u9664 IPVS \u4e2d\u5b9a\u4e49\u7684\u89c4\u5219\uff08\u5982\u679c\u4f7f\u7528 IPVS \uff09\u3002 ipvsadm --clear \u6392\u9519 \u00b6 \u9519\u8bef1 \u00b6 \u62a5\u9519\u4fe1\u606f\uff1a The connection to the server :6443 was refused - did you specify the right host or port? \u89e3\u51b3\u5c1d\u8bd5\uff1a Reference \u68c0\u67e5\u6587\u4ef6kubeconfig\u7684\u5185\u5bb9\u548c\u6587\u4ef6\u8def\u5f84\u662f\u5426\u6b63\u786e\u3002 \u68c0\u67e5\u73af\u5883\u53d8\u91cf\u8bbe\u7f6e\u3002 env | grep -i kub \u68c0\u67e5\u5bb9\u5668\u8fd0\u884c\u72b6\u6001\u3002 sudo systemctl status containerd.service \u68c0\u67e5kubelet\u670d\u52a1\u3002 sudo systemctl status kubelet.service \u68c0\u67e5 6443 \u7aef\u53e3\u76d1\u542c\u72b6\u6001\u3002 netstat -pnlt | grep 6443 \u68c0\u67e5\u9632\u706b\u5899\u72b6\u6001\u3002 sudo systemctl status firewalld.service \u68c0\u67e5kubelet\u65e5\u5fd7\u3002 journalctl -xeu kubelet \u9519\u8bef2 \u00b6 \u62a5\u9519\u4fe1\u606f\uff1a \"Container runtime network not ready\" networkReady=\"NetworkReady=false reason:NetworkPluginNotReady message:Network plugin returns error: cni plugin not initialized\" \u5c1d\u8bd5\u65b9\u6cd5\uff1a \u91cd\u542fContainerd\u670d\u52a1\u3002 sudo systemctl restart containerd sudo systemctl status containerd","title":"\u963f\u91cc\u4e91ECS\u5b89\u88c5Kubernetes"},{"location":"k8s/cka_cn/installation/aliyun-ubuntu/#cka3ecskubernetes","text":"","title":"CKA\u81ea\u5b66\u7b14\u8bb03:\u963f\u91cc\u4e91ECS\u5b89\u88c5Kubernetes"},{"location":"k8s/cka_cn/installation/aliyun-ubuntu/#_1","text":"\u5728\u963f\u91cc\u4e91ECS\u88c5\u4e09\u53f0Ubuntu\u865a\u62df\u673a\u3002\u5728Ubuntu\u865a\u62df\u673a\u4e2d\u5b89\u88c5\u57fa\u4e8eContainerd\u7684Kubernetes\u7cfb\u7edf\uff0c\u5e76\u5206\u522b\u914d\u7f6e\u4e00\u4e2a\u4e3b\u8282\u70b9Master\u548c\u4e24\u4e2a\u5de5\u4f5c\u8282\u70b9Worker\uff0c\u3002","title":"\u6458\u8981"},{"location":"k8s/cka_cn/installation/aliyun-ubuntu/#_2","text":"\u6ce8\u518c\u963f\u91cc\u4e91\u8d26\u53f7\uff1a Alibaba Cloud home console \u3002\u6ce8\u610f\u4fdd\u7559\u8bbf\u95ee\u5bc6\u94a5key\u6587\u4ef6\uff0c\u53ea\u80fd\u5bfc\u51fa\u4e00\u6b21\uff0c\u5f53\u524d\u7ec3\u4e60\u4e2dkey\u6587\u4ef6\u662f aliyun-root \u3002 \u53c2\u8003\u4e0b\u9762\u914d\u7f6e\u6ce8\u518c\u7533\u8bf7\u4e09\u4e2aECS\uff08Elastic Computer Service\uff09\u670d\u52a1\u5b9e\u4f8b\uff1a \u4e3b\u673a\uff1a2vCPU+4GiB \u64cd\u4f5c\u7cfb\u7edf\uff1aUbuntu 20.04 x86_64 \u5b9e\u4f8b\u7c7b\u578b\uff1aecs.sn1.medium \u5b9e\u4f8b\u540d\u79f0\uff1acka001, cka002, cka003 \u7f51\u7edc\u914d\u7f6e\uff1aboth public IPs and private IPs \u6700\u5927\u7f51\u7edc\u5e26\u5bbd\uff1a100Mbps (Peak Value) \u4e91\u76d8\uff1a40GiB \u652f\u4ed8\u65b9\u5f0f\uff1a\u62a2\u5360\u5f0f\u5b9e\u4f8b \u5728\u672c\u5730\u6253\u5f00\u7ec8\u7aef\u7a97\u53e3\uff0c\u901a\u8fc7\u5bc6\u94a5\u6587\u4ef6 aliyun-root \u8bbf\u95ee\u8fdc\u7a0bECS\u8282\u70b9 cka001 \u3002 ssh -i aliyun-root root@cka001 \u521b\u5efa\u4e00\u4e2a\u666e\u901a\u7528\u6237\uff0c\u7528\u6765\u5b89\u88c5Kubernetes\uff0c\u5f53\u524d\u7ec3\u4e60\u4e2d\u521b\u5efa\u7528\u6237 vagrant \uff0c\u4e14\u4fee\u6539\u8be5\u7528\u6237\u7684\u4e3b\u8981\u7ec4\u4e3a sudo \u6b21\u8981\u7ec4\u5305\u542b root \u3002 adduser vagrant usermod -g sudo vagrant usermod -a -G root vagrant \u65b0\u5f00\u4e00\u4e2a\u672c\u5730\u7ec8\u7aef\u7a97\u53e3\uff0c\u4e3a\u7528\u6237 vagrant \u521b\u5efa\u5bc6\u94a5key\u3002 # Windows ssh-keygen.exe # Linux ssh-keygen \u4e0a\u9762\u7684\u547d\u4ee4\u4f1a\u751f\u62102\u4e2a\u6587\u4ef6\uff0c\u5f53\u524d\u7ec3\u4e60\u4e2d\u8fd92\u4e2a\u6587\u4ef6\u662f aliyun-vagrant and aliyun-vagrant.pub \u901a\u8fc7 sftp \u547d\u4ee4\u5c06\u516c\u94a5\u6587\u4ef6 aliyun-vagrant.pub \u4e0a\u4f20\u5230\u8fdc\u7a0b\u8282\u70b9 cka001 \u3002 sftp -i aliyun-root root@cka001 put aliyun-vagrant.pub \u65b0\u5f00\u4e00\u4e2a\u7ec8\u7aef\u7a97\u53e3\uff0c\u7528 root \u7684\u5bc6\u94a5\u767b\u5f55 cka001 \u8282\u70b9\u3002 \u5c06\u4e0a\u4e00\u6b65\u4e0a\u4f20\u7684\u5bc6\u94a5\u6587\u4ef6 aliyun-vagrant.pub \u4ece /root \u76ee\u5f55\u62f7\u8d1d\u5230 /home/vagrant/.ssh/ \u3002 \u5c06\u516c\u94a5\u6587\u4ef6 aliyun-vagrant.pub \u91cd\u547d\u540d\u4e3a authorized_keys \u3002 \u66f4\u6539\u6587\u4ef6 authorized_keys \u7684\u6240\u6709\u8005owner\u4e3a vagrant . \u66f4\u6539\u6587\u4ef6 authorized_keys \u7684\u4e3b\u8981\u7ec4\u4e3a sudo \u3002 mkdir /home/vagrant/.ssh/ mv aliyun-james.pub /home/vagrant/.ssh/authorized_keys chown vagrant.sudo /home/vagrant/.ssh/authorized_keys chmod 600 /home/vagrant/.ssh/authorized_keys \u68c0\u67e5\u6587\u4ef6 /etc/ssh/sshd_config \uff0c\u786e\u5b9a\u5bc6\u7801\u767b\u5f55\u9a8c\u8bc1\u53c2\u6570 asswordAuthentication \u8bbe\u5b9a\u4e3a no \uff0c\u5373\u53ea\u80fd\u901a\u8fc7\u8bc1\u4e66\u8fdc\u7a0b\u767b\u5f55\u3002 cat /etc/ssh/sshd_config \u65b0\u5f00\u4e00\u4e2a\u7ec8\u7aef\u7a97\u53e3\uff0c\u4f7f\u7528\u7528\u6237vagrant\u767b\u5f55\u8fdc\u7a0b\u8282\u70b9 cka001 \uff0c\u9a8c\u8bc1\u7528\u6237 vagrant \u80fd\u901a\u8fc7\u524d\u9762\u521b\u5efa\u7684\u8bc1\u4e66\u767b\u5f55\u8282\u70b9 cka001 \u3002 ssh -i aliyun-vagrant vagrant@cka001 \u91cd\u590d\u4e0a\u8ff0\u6b65\u9aa4\uff0c\u901a\u8fc7 sftp \u547d\u4ee4\u5c06\u516c\u94a5\u6587\u4ef6 aliyun-vagrant.pub \u5206\u522b\u4e0a\u4f20\u5230\u8fdc\u7a0b\u8282\u70b9 cka002 \u548c cka003 \uff0c\u4e14\u5b8c\u6210\u540c\u6837\u7684\u914d\u7f6e\uff0c\u4f7f\u7528\u6237 vagrant \u4e5f\u80fd\u901a\u8fc7\u5bc6\u94a5\u6587\u4ef6\u767b\u5f55\u8fdc\u7a0b\u8282\u70b9 cka002 \u548c cka003 \u3002 \u81f3\u6b64\uff0c\u7528\u6237 vagrant \u53ef\u4ee5\u901a\u8fc7\u5bc6\u94a5\u6587\u4ef6 aliyun-vagrant \u4ece\u672c\u5730\u7ec8\u7aef\u7a97\u53e3\u767b\u5f55\u8fdc\u7a0b\u8282\u70b9 cka001 , cka002 \u548c cka003 \u3002 \u4e0b\u9762\u6240\u6709\u6b65\u9aa4\u90fd\u662f\u901a\u8fc7\u7528\u6237 vagrant \u5b8c\u6210\u3002","title":"\u51c6\u5907\u5de5\u4f5c"},{"location":"k8s/cka_cn/installation/aliyun-ubuntu/#ecs","text":"","title":"\u521d\u59cb\u5316ECS\u8282\u70b9"},{"location":"k8s/cka_cn/installation/aliyun-ubuntu/#etchosts","text":"\u66f4\u65b0\u6240\u6709ECS\u8282\u70b9\u7684\u6587\u4ef6/etc/hosts\uff0c\u6dfb\u52a0\u5176\u4ed6\u8282\u70b9\u7684\u79c1\u6709IP\uff08private IP\uff09\u3002 vi /etc/hosts","title":"\u914d\u7f6e\u6587\u4ef6/etc/hosts"},{"location":"k8s/cka_cn/installation/aliyun-ubuntu/#firewall","text":"\u5728\u6240\u6709\u8282\u70b9\u4e0a\u7981\u7528\u9632\u706b\u5899\u3002 sudo ufw disable \u68c0\u67e5\u9632\u706b\u5899\u72b6\u6001\u3002 sudo ufw status verbose","title":"\u7981\u7528firewall"},{"location":"k8s/cka_cn/installation/aliyun-ubuntu/#swap","text":"\u5728\u6240\u6709\u8282\u70b9\u4e0a\u5173\u95edswap\u3002 sudo swapoff -a","title":"\u5173\u95edswap"},{"location":"k8s/cka_cn/installation/aliyun-ubuntu/#_3","text":"\u5728\u6240\u6709\u8282\u70b9\u8bbe\u5b9a\u65f6\u533a\u548c\u5730\u57df\u3002\u8fd9\u4e00\u5e03\u5728\u521d\u59cb\u5316ECS\u65f6\u5019\u5df2\u7ecf\u5b8c\u6210\u3002\u53ef\u4ee5\u901a\u8fc7\u4e0b\u9762\u547d\u4ee4\u8fdb\u884c\u8bbe\u5b9a\u3002 ln -sf /usr/share/zoneinfo/Asia/Shanghai /etc/localtime sudo echo 'LANG=\"en_US.UTF-8\"' >> /etc/profile source /etc/profile \u901a\u8fc7\u4e0b\u9762\u547d\u4ee4\u68c0\u67e5\u65f6\u533a\u548c\u5730\u57df\u7684\u8bbe\u7f6e\u3002 ll /etc/localtime lrwxrwxrwx 1 root root 33 Jul 5 14:51 /etc/localtime -> /usr/share/zoneinfo/Asia/Shanghai","title":"\u8bbe\u7f6e\u65f6\u533a\u548c\u5730\u57df"},{"location":"k8s/cka_cn/installation/aliyun-ubuntu/#_4","text":"\u5728\u6240\u6709\u8282\u70b9\u4e0a\u6267\u884c\u4e0b\u9762\u7684\u547d\u4ee4\u4ee5\u914d\u7f6e\u5185\u6838\u3002 \u4f7f\u7528\u6a21\u5757overlay\uff1a \u521b\u5efaContainerd\u670d\u52a1\u914d\u7f6e\u6587\u4ef6 /etc/modules-load.d/containerd.conf \uff0c\u5982\u679c\u5df2\u5b58\u5728\u5219\u8df3\u8fc7\u8fd9\u4e00\u6b65\u3002\u914d\u7f6e\u8fd9\u4e2a\u6587\u4ef6\u7684\u76ee\u7684\u662f\u4e3a\u4e86\u52a0\u8f7d\u6a21\u5757 overlay \u548c br_netfilter \u5230\u5185\u6838\u4e2d\u3002 \u670d\u52a1Containerd\u4f9d\u8d56\u6a21\u5757 overlay \u5b9e\u73b0 overlay-filesystem \u6587\u4ef6\u7cfb\u7edf\u529f\u80fd\u3002 Linux\u4e2d\u7684overlay\u6a21\u5757\u63d0\u4f9b\u4e86\u521b\u5efa\u4e24\u4e2a\u76ee\u5f55\u7684\u5408\u5e76\u89c6\u56fe\u7684\u80fd\u529b\uff0c\u8fd9\u4e24\u4e2a\u76ee\u5f55\u79f0\u4e3a\u5c42\u3002\u5b83\u7ecf\u5e38\u88ab\u7528\u4e8e\u5b9e\u73b0\u8054\u5408\u6302\u8f7d\uff0c\u8fd9\u662f\u4e00\u79cd\u5c06\u4e24\u4e2a\u6216\u66f4\u591a\u76ee\u5f55\u4e00\u8d77\u6302\u8f7d\u7684\u65b9\u5f0f\uff0c\u5c31\u50cf\u5b83\u4eec\u662f\u4e00\u4e2a\u76ee\u5f55\u4e00\u6837\uff08union-filesystems\uff09\u3002 overlay\u6a21\u5757\u5728\u5bb9\u5668\u6280\u672f\u4e2d\u88ab\u5e7f\u6cdb\u4f7f\u7528\uff0c\u6bd4\u5982Docker\uff0c\u56e0\u4e3a\u5b83\u5141\u8bb8\u591a\u4e2a\u5bb9\u5668\u5171\u4eab\u57fa\u7840\u955c\u50cf\uff0c\u540c\u65f6\u4fdd\u6301\u5b83\u4eec\u81ea\u5df1\u7684\u6587\u4ef6\u7cfb\u7edf\u3002 \u8981\u4f7f\u7528overlay\u6a21\u5757\uff0c\u9700\u8981\u4e24\u4e2a\u76ee\u5f55\uff1a\u8f83\u4f4e\u7684\u76ee\u5f55\uff08lower directory\uff09\u548c\u8f83\u9ad8\u7684\u76ee\u5f55\uff08upper directory\uff09\u3002\u8f83\u4f4e\u7684\u76ee\u5f55\u901a\u5e38\u662f\u53ea\u8bfb\u7684\uff0c\u5305\u542b\u539f\u59cb\u6587\u4ef6\uff0c\u800c\u8f83\u9ad8\u7684\u76ee\u5f55\u662f\u53ef\u8bfb\u5199\u7684\uff0c\u5305\u542b\u5bf9\u6587\u4ef6\u7684\u66f4\u6539\u3002\u5f53\u8bf7\u6c42\u6587\u4ef6\u65f6\uff0coverlay\u6a21\u5757\u9996\u5148\u67e5\u627e\u4e0a\u5c42\u76ee\u5f55\uff0c\u5982\u679c\u672a\u627e\u5230\uff0c\u5219\u67e5\u627e\u4e0b\u5c42\u76ee\u5f55\u3002 \u6bd4\u5982\uff1a \u521b\u5efa\u4e24\u4e2a\u76ee\u5f55\uff0c\u4e00\u4e2a\u7528\u4e8e\u8f83\u4f4e\u7684\u76ee\u5f55\uff0c\u4e00\u4e2a\u7528\u4e8e\u8f83\u9ad8\u7684\u76ee\u5f55\u3002\u7136\u540e\u4f7f\u7528overlay\u6587\u4ef6\u7cfb\u7edf\u7c7b\u578b\u5c06\u5b83\u4eec\u6302\u8f7d\u8d77\u6765\uff1a sudo mkdir /lower sudo mkdir /upper sudo mount -t overlay overlay -o lowerdir = /lower,upperdir = /upper /merged \u5728\u4e0a\u9762\u7684\u4f8b\u5b50\u4e2d\uff0c\u4e24\u4e2a\u76ee\u5f55\u7684\u5408\u5e76\u89c6\u56fe\u88ab\u521b\u5efa\u5728 /merged \u76ee\u5f55\u4e2d\u3002\u5728 /merged \u76ee\u5f55\u4e2d\u5bf9\u6587\u4ef6\u6240\u505a\u7684\u4efb\u4f55\u66f4\u6539\u90fd\u5b58\u50a8\u5728\u4e0a\u5c42\u76ee\u5f55\u4e2d\uff0c\u800c\u539f\u59cb\u6587\u4ef6\u4ecd\u7136\u5728\u4e0b\u5c42\u76ee\u5f55\u4e2d\u3002 \u4f7f\u7528\u6a21\u5757br_netfilter\uff1a br_netfilter \u662fLinux\u5185\u6838\u4e2d\u7684\u4e00\u4e2a\u6a21\u5757\uff0c\u5b83\u63d0\u4f9b\u4e86\u4e00\u79cd\u673a\u5236\u6765\u8fc7\u6ee4\u7f51\u6865\u7684\u7f51\u7edc\u6d41\u91cf\u3002\u8be5\u6a21\u5757\u5141\u8bb8\u7ba1\u7406\u5458\u914d\u7f6e\u89c4\u5219\uff0c\u4ee5\u5141\u8bb8\u6216\u62d2\u7edd\u7279\u5b9a\u7684\u7f51\u7edc\u6d41\u91cf\u901a\u8fc7\u7f51\u6865\u3002 \u7f51\u6865\u662f\u4e00\u79cd\u7f51\u7edc\u8bbe\u5907\uff0c\u5b83\u53ef\u4ee5\u8fde\u63a5\u591a\u4e2a\u7f51\u7edc\u6bb5\uff0c\u5e76\u8f6c\u53d1\u6d41\u91cf\u4ee5\u4f7f\u4e0d\u540c\u7684\u7f51\u7edc\u6bb5\u4e4b\u95f4\u901a\u4fe1\u3002 br_netfilter \u6a21\u5757\u53ef\u4ee5\u7528\u6765\u9650\u5236\u6216\u8fc7\u6ee4\u8fd9\u4e9b\u6d41\u91cf\u3002 \u5f53\u542f\u7528\u4e86 br_netfilter \u6a21\u5757\u65f6\uff0c\u5b83\u4f1a\u81ea\u52a8\u542f\u7528\u4e00\u4e2a\u79f0\u4e3a bridge-nf \u7684\u529f\u80fd\uff0c\u8be5\u529f\u80fd\u5c06\u5728\u7f51\u7edc\u6d41\u91cf\u901a\u8fc7\u7f51\u6865\u65f6\u5e94\u7528\u89c4\u5219\u3002\u7ba1\u7406\u5458\u53ef\u4ee5\u4f7f\u7528iptables\u7b49\u5de5\u5177\u6765\u914d\u7f6e\u8fd9\u4e9b\u89c4\u5219\u3002\u4f8b\u5982\uff0c\u6211\u4eec\u53ef\u4ee5\u8bbe\u5b9a\u5141\u8bb8\u4ece\u4e00\u4e2a\u7f51\u7edc\u6bb5\u5230\u53e6\u4e00\u4e2a\u7f51\u7edc\u6bb5\u7684\u6d41\u91cf\uff0c\u6216\u8005\u62d2\u7edd\u6765\u81ea\u7279\u5b9aIP\u5730\u5740\u6216\u7aef\u53e3\u7684\u6d41\u91cf\u3002 \u5728Kubernetes\u4e2d\uff0c br_netfilter \u6a21\u5757\u4e3b\u8981\u7528\u4e8e\u542f\u7528Kubernetes\u670d\u52a1\u7684\u6d41\u91cf\u8f6c\u53d1\u548c\u8d1f\u8f7d\u5747\u8861\u3002\u8fd9\u4e9b\u670d\u52a1\u4f7f\u7528\u4e86Linux\u5185\u6838\u4e2d\u7684iptables\u89c4\u5219\u6765\u7ba1\u7406\u6d41\u91cf\uff0c\u8fd9\u4e9b\u89c4\u5219\u662f\u901a\u8fc7 br_netfilter \u6a21\u5757\u5b9e\u73b0\u7684\u3002 \u5177\u4f53\u6765\u8bf4\uff0c\u5f53\u6211\u4eec\u5728Kubernetes\u96c6\u7fa4\u4e2d\u521b\u5efa\u4e00\u4e2a\u670d\u52a1\u65f6\uff0c\u8be5\u670d\u52a1\u5c06\u5206\u914d\u4e00\u4e2a\u865a\u62dfIP\u5730\u5740\uff0c\u7528\u4e8e\u4ee3\u8868\u670d\u52a1\u3002\u7136\u540e\uff0c\u901a\u8fc7iptables\u89c4\u5219\uff0c\u5c06\u8fd9\u4e2a\u865a\u62dfIP\u5730\u5740\u6620\u5c04\u5230\u4e00\u4e2a\u6216\u591a\u4e2a\u540e\u7aefPod\u7684IP\u5730\u5740\uff0c\u4ee5\u4fbf\u5728\u9700\u8981\u65f6\u5c06\u6d41\u91cf\u8def\u7531\u5230\u8fd9\u4e9bPod\u3002 \u5728\u8fd9\u4e2a\u8fc7\u7a0b\u4e2d\uff0c br_netfilter \u6a21\u5757\u8d1f\u8d23\u76d1\u89c6\u670d\u52a1\u7684\u6d41\u91cf\uff0c\u5e76\u6839\u636eiptables\u89c4\u5219\u8fdb\u884c\u8f6c\u53d1\u548c\u8d1f\u8f7d\u5747\u8861\u3002\u8fd9\u5305\u62ec\u8fc7\u6ee4\u6765\u81ea\u4e0d\u53d7\u4fe1\u4efb\u6e90\u7684\u6d41\u91cf\u4ee5\u53ca\u9650\u5236\u670d\u52a1\u7684\u8bbf\u95ee\u6743\u9650\u3002 \u9700\u8981\u6ce8\u610f\u7684\u662f\uff0c\u4e3a\u4e86\u542f\u7528Kubernetes\u670d\u52a1\u7684\u6d41\u91cf\u8f6c\u53d1\u548c\u8d1f\u8f7d\u5747\u8861\uff0c br_netfilter \u6a21\u5757\u5fc5\u987b\u5728\u6240\u6709\u8282\u70b9\u4e0a\u542f\u7528\uff0c\u5e76\u4e14\u5fc5\u987b\u914d\u7f6e\u6b63\u786e\u7684iptables\u89c4\u5219\u3002 \u7531\u4e8e br_netfilter \u6a21\u5757\u7684\u4f5c\u7528\u975e\u5e38\u5173\u952e\uff0c\u56e0\u6b64\u5728\u5347\u7ea7\u6216\u66f4\u6539\u7cfb\u7edf\u65f6\u9700\u8981\u7279\u522b\u6ce8\u610f\u5b83\u7684\u914d\u7f6e\u548c\u72b6\u6001\u3002 \u4e0b\u9762\u547d\u4ee4\u5c06\u6a21\u5757 overlay \u548c br_netfilter \u6dfb\u52a0\u5230\u914d\u7f6e\u6587\u4ef6 containerd.conf \u4e2d\u3002 cat < /etc/apt/sources.list << EOF deb http://mirrors.cloud.aliyuncs.com/ubuntu/ focal main restricted deb-src http://mirrors.cloud.aliyuncs.com/ubuntu/ focal main restricted deb http://mirrors.cloud.aliyuncs.com/ubuntu/ focal-updates main restricted deb-src http://mirrors.cloud.aliyuncs.com/ubuntu/ focal-updates main restricted deb http://mirrors.cloud.aliyuncs.com/ubuntu/ focal universe deb-src http://mirrors.cloud.aliyuncs.com/ubuntu/ focal universe deb http://mirrors.cloud.aliyuncs.com/ubuntu/ focal-updates universe deb-src http://mirrors.cloud.aliyuncs.com/ubuntu/ focal-updates universe deb http://mirrors.cloud.aliyuncs.com/ubuntu/ focal multiverse deb-src http://mirrors.cloud.aliyuncs.com/ubuntu/ focal multiverse deb http://mirrors.cloud.aliyuncs.com/ubuntu/ focal-updates multiverse deb-src http://mirrors.cloud.aliyuncs.com/ubuntu/ focal-updates multiverse deb http://mirrors.cloud.aliyuncs.com/ubuntu/ focal-backports main restricted universe multiverse deb-src http://mirrors.cloud.aliyuncs.com/ubuntu/ focal-backports main restricted universe multivers deb http://mirrors.cloud.aliyuncs.com/ubuntu focal-security main restricted deb-src http://mirrors.cloud.aliyuncs.com/ubuntu focal-security main restricted deb http://mirrors.cloud.aliyuncs.com/ubuntu focal-security universe deb-src http://mirrors.cloud.aliyuncs.com/ubuntu focal-security universe # deb http://mirrors.cloud.aliyuncs.com/ubuntu focal-security multiverse # deb-src http://mirrors.cloud.aliyuncs.com/ubuntu focal-security multiverse EOF \u5b89\u88c5Containered\u3002 sudo apt-get update && sudo apt-get install -y containerd \u914d\u7f6eContainerd\u3002\u4fee\u6539\u6587\u4ef6 /etc/containerd/config.toml \u3002 sudo mkdir -p /etc/containerd containerd config default | sudo tee /etc/containerd/config.toml sudo vi /etc/containerd/config.toml \u4fee\u6539\u53c2\u6570 sandbox_image \u7684\u503c\u4e3a \"registry.aliyuncs.com/google_containers/pause:3.6\" \u3002 \u4fee\u6539\u53c2\u6570 SystemdCgroup \u7684\u503c\u4e3a true \u3002 [plugins] [plugins.\"io.containerd.gc.v1.scheduler\"] [plugins.\"io.containerd.grpc.v1.cri\"] sandbox_image = \"registry.aliyuncs.com/google_containers/pause:3.6\" [plugins.\"io.containerd.grpc.v1.cri\".cni] [plugins.\"io.containerd.grpc.v1.cri\".containerd] [plugins.\"io.containerd.grpc.v1.cri\".containerd.default_runtime] [plugins.\"io.containerd.grpc.v1.cri\".containerd.default_runtime.options] [plugins.\"io.containerd.grpc.v1.cri\".containerd.runtimes] [plugins.\"io.containerd.grpc.v1.cri\".containerd.runtimes.runc] [plugins.\"io.containerd.grpc.v1.cri\".containerd.runtimes.runc.options] SystemdCgroup = true \u91cd\u542fContainerd\u670d\u52a1\u3002 sudo systemctl restart containerd sudo systemctl status containerd","title":"\u5b89\u88c5Containerd"},{"location":"k8s/cka_cn/installation/aliyun-ubuntu/#nerdctl","text":"\u5728\u6240\u6709\u8282\u70b9\u4e0a\u5b89\u88c5nerdctl\u670d\u52a1\u3002 nerdctl \u670d\u52a1\u652f\u6301Contanerd\u6240\u63d0\u4f9b\u7684\u5bb9\u5668\u5316\u7279\u6027\uff0c\u7279\u522b\u662f\u4e00\u4e9bDocker\u4e0d\u5177\u5907\u7684\u65b0\u7279\u6027\u3002 \u4e8c\u8fdb\u5236\u5b89\u88c5\u5305\u53ef\u4ee5\u901a\u8fc7\u8fd9\u4e2a\u94fe\u63a5\u53d6\u5f97: Releases \u00b7 containerd/nerdctl \u00b7 GitHub \u3002 wget https://github.com/containerd/nerdctl/releases/download/v0.22.2/nerdctl-0.22.2-linux-amd64.tar.gz tar -zxvf nerdctl-0.22.2-linux-amd64.tar.gz sudo cp nerdctl /usr/bin/ \u9a8c\u8bc1 nerdctl \u670d\u52a1\u3002 sudo nerdctl --help \u5217\u51fa\u521d\u59cb\u5b89\u88c5Kubernetes\u65f6\u7684\u5bb9\u5668container\u5217\u8868\u3002 nerdctl -n k8s.io ps","title":"\u5b89\u88c5nerdctl"},{"location":"k8s/cka_cn/installation/aliyun-ubuntu/#kubeadm","text":"\u5728\u6240\u6709\u8282\u70b9\u4e0a\u5b89\u88c5Kubeadm\uff0ckubectl\uff0ckubelet\u3002 \u5b89\u88c5\u548c\u5347\u7ea7Ubuntu\u7cfb\u7edf\u4f9d\u8d56\u5305 apt-transport-https , ca-certificates , curl \u3002 sudo apt-get update && sudo apt-get install -y apt-transport-https ca-certificates curl \u5b89\u88c5gpg\u8bc1\u4e66\u3002 curl https://mirrors.aliyun.com/kubernetes/apt/doc/apt-key.gpg | sudo apt-key add - \u6dfb\u52a0Kubernetes\u5b89\u88c5\u6e90\u3002 cat << EOF > /etc/apt/sources.list.d/kubernetes.list deb https://mirrors.aliyun.com/kubernetes/apt/ kubernetes-xenial main EOF \u5b89\u88c5\u548c\u5347\u7ea7Ubuntu\u7cfb\u7edf\u4f9d\u8d56\u5305\u3002 sudo apt-get update sudo apt-get install ebtables sudo apt-get install libxtables12 sudo apt-get upgrade iptables \u68c0\u67e5\u5f53\u524d\u53ef\u7528\u7684 kubeadm \u7248\u672c\u3002 apt policy kubeadm \u5f53\u524d\u5b89\u88c5 1.24.0-00 \u7248\u672c\u7684 kubeadm \uff0c\u540e\u7eed\u4f1a\u5347\u7ea7\u5230 1.24.2 \u7248\u672c\u3002 sudo apt-get -y install kubelet = 1 .24.0-00 kubeadm = 1 .24.0-00 kubectl = 1 .24.0-00 --allow-downgrades","title":"\u5b89\u88c5kubeadm"},{"location":"k8s/cka_cn/installation/aliyun-ubuntu/#_5","text":"","title":"\u914d\u7f6e\u4e3b\u8282\u70b9"},{"location":"k8s/cka_cn/installation/aliyun-ubuntu/#kubeadm_1","text":"\u5728\u627f\u62c5\u4e3b\u8282\u70b9\u7684\u865a\u62df\u673a\u91cc\u914d\u7f6e\u63a7\u5236\u5e73\u9762\uff08Control Plane\uff09\u3002 \u68c0\u67e5 kubeadm \u5f53\u524d\u9ed8\u8ba4\u914d\u7f6e\u53c2\u6570\u3002 kubeadm config print init-defaults \u7c7b\u4f3c\u7ed3\u679c\u5982\u4e0b\u3002\u4fdd\u5b58\u9ed8\u8ba4\u914d\u7f6e\u7684\u7ed3\u679c\uff0c\u540e\u7eed\u4f1a\u4f5c\u4e3a\u53c2\u8003\u3002 apiVersion : kubeadm.k8s.io/v1beta3 bootstrapTokens : - groups : - system:bootstrappers:kubeadm:default-node-token token : abcdef.0123456789abcdef ttl : 24h0m0s usages : - signing - authentication kind : InitConfiguration localAPIEndpoint : advertiseAddress : 1.2.3.4 bindPort : 6443 nodeRegistration : criSocket : unix:///var/run/containerd/containerd.sock imagePullPolicy : IfNotPresent name : node taints : null --- apiServer : timeoutForControlPlane : 4m0s apiVersion : kubeadm.k8s.io/v1beta3 certificatesDir : /etc/kubernetes/pki clusterName : kubernetes controllerManager : {} dns : {} etcd : local : dataDir : /var/lib/etcd imageRepository : k8s.gcr.io kind : ClusterConfiguration kubernetesVersion : 1.24.0 networking : dnsDomain : cluster.local serviceSubnet : 10.96.0.0/12 scheduler : {} \u6a21\u62df\u5b89\u88c5\u548c\u6b63\u5f0f\u5b89\u88c5\u3002 \u901a\u8fc7\u547d\u4ee4 kubeadm init \u8fdb\u884c\u4e3b\u8282\u70b9\u7684\u521d\u59cb\u5316\uff0c\u4e0b\u9762\u662f\u8fd9\u4e2a\u547d\u4ee4\u4e3b\u8981\u53c2\u6570\u7684\u8bf4\u660e\uff0c\u7279\u522b\u662f\u7f51\u7edc\u53c2\u6570\u7684\u4e09\u4e2a\u9009\u62e9\u3002 --pod-network-cidr : \u6307\u5b9apod\u4f7f\u7528\u7684IP\u5730\u5740\u8303\u56f4\u3002\u5982\u679c\u6307\u5b9a\u4e86\u8be5\u53c2\u6570\uff0c\u5219Control Plane\u4f1a\u81ea\u52a8\u8bb2\u6307\u5b9a\u7684CIDR\u5206\u914d\u7ed9\u6bcf\u4e2a\u8282\u70b9\u3002 IP\u5730\u5740\u6bb5 10.244.0.0/16 \u662fFlannel\u7f51\u7edc\u7ec4\u4ef6\u9ed8\u8ba4\u7684\u5730\u5740\u8303\u56f4\u3002\u5982\u679c\u9700\u8981\u4fee\u6539Flannel\u7684IP\u5730\u5740\u6bb5\uff0c\u9700\u8981\u5728\u8fd9\u91cc\u6307\u5b9a\uff0c\u4e14\u5728\u90e8\u7f72Flannel\u65f6\u4e5f\u8981\u4fdd\u6301\u4e00\u81f4\u7684IP\u6bb5\u3002 --apiserver-bind-port : API\u670d\u52a1\uff08API Server\uff09\u7684\u7aef\u53e3\uff0c\u9ed8\u8ba4\u65f66443\u3002 --service-cidr : \u6307\u5b9a\u670d\u52a1\uff08service\uff09\u7684IP\u5730\u5740\u6bb5\uff0c\u9ed8\u8ba4\u662f 10.96.0.0/12 \u3002 \u63d0\u793a\uff1a \u670d\u52a1VIPs\uff08service VIPs\uff09\uff0c\u4e5f\u79f0\u4f5c\u96c6\u7fa4IP\uff08Cluster IP\uff09\uff0c\u901a\u8fc7\u53c2\u6570 --service-cidr \u6307\u5b9a\u3002 podCIDR\uff0c\u4e5f\u79f0\u4e3aendpoint IP\uff0c\u901a\u8fc7\u53c2\u6570 --pod-network-cidr \u6307\u5b9a\u3002 \u67094\u79cd\u5178\u578b\u7684\u7f51\u7edc\u95ee\u9898\uff1a \u9ad8\u5ea6\u8026\u5408\u7684\u5bb9\u5668\u4e0e\u5bb9\u5668\u4e4b\u95f4\u7684\u901a\u4fe1\uff1a\u8fd9\u53ef\u4ee5\u901a\u8fc7Pod\uff08podCIDR\uff09\u548c\u672c\u5730\u4e3b\u673a\u901a\u4fe1\u6765\u89e3\u51b3\u3002 Pod\u5bf9Pod\u901a\u4fe1\uff08Pod-to-Pod\uff09\uff1a \u4e5f\u88ab\u79f0\u4e3a\u5bb9\u5668\u5bf9\u5bb9\u5668\u901a\u4fe1\uff08container-to-container\uff09\u3002 \u5728Flannel\u7f51\u7edc\u63d2\u4ef6\u4e2d\u7684\u793a\u4f8b\u6d41\u7a0b\u662f\uff1aPod \u2192 veth\u5bf9 \u2192 cni0 \u2192 flannel.1 \u2192 \u5bbf\u4e3b\u673aeth0 \u2192 \u5bbf\u4e3b\u673aeth0 \u2192 flannel.1 \u2192 cni0 \u2192 veth\u5bf9 \u2192 Pod\u3002 Pod\u5bf9Service\u901a\u4fe1\uff08Pod-to-Service\uff09\uff1a \u6d41\u7a0b: Pod \u2192 \u5185\u6838 \u2192 Service iptables \u2192 Service \u2192 Pod iptables \u2192 Pod\u3002 \u5916\u90e8\u5bf9Service\u901a\u4fe1\uff08External-to-Service\uff09\uff1a \u8d1f\u8f7d\u5747\u8861\u5668: SLB \u2192 NodePort \u2192 Service \u2192 Pod\u3002 kube-proxy \u662f\u5bf9iptables\u8d1f\u8d23\uff0c\u4e0d\u662f\u7f51\u7edc\u6d41\u91cf\uff08traffic\uff09\u3002 kube-proxy \u662fKubernetes\u96c6\u7fa4\u4e2d\u7684\u4e00\u4e2a\u7ec4\u4ef6\uff0c\u8d1f\u8d23\u4e3aService\u63d0\u4f9b\u4ee3\u7406\u670d\u52a1\uff0c\u540c\u65f6\u4e5f\u662fKubernetes\u7f51\u7edc\u6a21\u578b\u4e2d\u7684\u91cd\u8981\u7ec4\u6210\u90e8\u5206\u4e4b\u4e00\u3002 kube-proxy \u4f1a\u5728\u6bcf\u4e2a\u8282\u70b9\u4e0a\u542f\u52a8\u4e00\u4e2a\u4ee3\u7406\u8fdb\u7a0b\uff0c\u901a\u8fc7\u76d1\u542cKubernetes API Server\u7684Service\u548cEndpoint\u7684\u53d8\u5316\u6765\u7ef4\u62a4\u4e00\u4e2a\u672c\u5730\u7684Service\u548cEndpoint\u7684\u7f13\u5b58\u3002\u5f53\u6709\u8bf7\u6c42\u5230\u8fbe\u67d0\u4e2aService\u65f6\uff0c kube-proxy \u4f1a\u6839\u636e\u8be5Service\u7684\u7c7b\u578b\uff08ClusterIP\u3001NodePort\u3001LoadBalancer\u3001ExternalName\uff09\u548c\u7aef\u53e3\u53f7\uff0c\u751f\u6210\u76f8\u5e94\u7684iptables\u89c4\u5219\uff0c\u5c06\u8bf7\u6c42\u8f6c\u53d1\u7ed9Service\u6240\u4ee3\u7406\u7684\u540e\u7aefPod\u3002 iptables\u662fLinux\u7cfb\u7edf\u4e2d\u7684\u4e00\u4e2a\u91cd\u8981\u7f51\u7edc\u5de5\u5177\uff0c\u53ef\u4ee5\u8bbe\u7f6eIP\u5305\u7684\u8fc7\u6ee4\u3001\u8f6c\u53d1\u548c\u4fee\u6539\u89c4\u5219\uff0c\u53ef\u4ee5\u5b9e\u73b0\u7f51\u7edc\u5c42\u7684\u9632\u706b\u5899\u3001NAT\u7b49\u529f\u80fd\u3002\u5728Kubernetes\u96c6\u7fa4\u4e2d\uff0c kube-proxy \u901a\u8fc7\u751f\u6210\u548c\u66f4\u65b0iptables\u89c4\u5219\uff0c\u6765\u5b9e\u73b0Service\u548cEndpoint\u4e4b\u95f4\u7684\u8f6c\u53d1\u548c\u4ee3\u7406\u3002\u5177\u4f53\u6765\u8bf4\uff0ckube-proxy\u4f1a\u4e3a\u6bcf\u4e2aService\u521b\u5efa\u4e09\u6761iptables\u89c4\u5219\u94fe\uff08nat\u8868\u4e2d\u7684KUBE-SERVICES\u548cKUBE-NODEPORTS\u94fe\uff0c\u4ee5\u53cafilter\u8868\u4e2d\u7684KUBE-SVC-XXXXX\u94fe\uff09\uff0c\u901a\u8fc7\u8fd9\u4e9b\u89c4\u5219\u94fe\uff0c\u5c06\u8bf7\u6c42\u8f6c\u53d1\u5230\u76f8\u5e94\u7684Pod\u6216\u8005Service\u4e0a\u3002 \u56e0\u6b64\uff0c kube-proxy \u548ciptables\u662f\u7d27\u5bc6\u76f8\u5173\u7684\u4e24\u4e2a\u7ec4\u4ef6\uff0c\u901a\u8fc7iptables\u89c4\u5219\u6765\u5b9e\u73b0Service\u548cPod\u4e4b\u95f4\u7684\u8f6c\u53d1\u548c\u4ee3\u7406\u3002\u8fd9\u79cd\u5b9e\u73b0\u65b9\u5f0f\u5177\u6709\u53ef\u6269\u5c55\u6027\u548c\u9ad8\u53ef\u7528\u6027\uff0c\u540c\u65f6\u4e5f\u63d0\u4f9b\u4e86\u4e00\u79cd\u7075\u6d3b\u7684\u7f51\u7edc\u6a21\u578b\uff0c\u53ef\u4ee5\u65b9\u4fbf\u5730\u5b9e\u73b0\u670d\u52a1\u53d1\u73b0\u3001\u8d1f\u8f7d\u5747\u8861\u7b49\u529f\u80fd\u3002 sudo kubeadm init \\ --dry-run \\ --pod-network-cidr = 10 .244.0.0/16 \\ --service-cidr 11 .244.0.0/16 \\ --image-repository = registry.aliyuncs.com/google_containers \\ --kubernetes-version = v1.24.0 sudo kubeadm init \\ --pod-network-cidr = 10 .244.0.0/16 \\ --service-cidr 11 .244.0.0/16 \\ --image-repository = registry.aliyuncs.com/google_containers \\ --kubernetes-version = v1.24.0 sudo kubeadm init \\ --pod-network-cidr = 10 .244.0.0/16 \\ --service-cidr 11 .244.0.0/16 \\ --kubernetes-version = v1.24.0","title":"kubeadm\u521d\u59cb\u5316"},{"location":"k8s/cka_cn/installation/aliyun-ubuntu/#kubeconfig","text":"\u7ed9\u5f53\u524d\u5b89\u88c5\u7528\u6237\u914d\u7f6e kubeconfig \u6587\u4ef6\uff08\u5f53\u524d\u4f8b\u5b50\u662f\u7528\u6237 vagrant \uff09\u3002 mkdir -p $HOME /.kube sudo cp -i /etc/kubernetes/admin.conf $HOME /.kube/config sudo chown $( id -u ) : $( id -g ) $HOME /.kube/config Kubernetes \u63d0\u4f9b\u4e86\u4e00\u4e2a\u547d\u4ee4\u884c\u5de5\u5177 kubectl \uff0c\u7528\u4e8e\u4f7f\u7528 Kubernetes API \u4e0e Kubernetes \u96c6\u7fa4\u7684\u63a7\u5236\u5e73\u9762\u8fdb\u884c\u901a\u4fe1\u3002 kubectl \u63a7\u5236 Kubernetes cluster manager \uff08\u96c6\u7fa4\u7ba1\u7406\u5668\uff09\u3002 \u5bf9\u4e8e\u914d\u7f6e\uff0ckubectl \u5728 $HOME/.kube \u76ee\u5f55\u4e2d\u67e5\u627e\u4e00\u4e2a\u540d\u4e3a config \u7684\u6587\u4ef6\uff0c\u8be5\u6587\u4ef6\u662f\u7531 kubeadm init \u751f\u6210\u7684\u6587\u4ef6 /etc/kubernetes/admin.conf \u7684\u526f\u672c\u3002 \u6211\u4eec\u53ef\u4ee5\u901a\u8fc7\u8bbe\u7f6e KUBECONFIG \u73af\u5883\u53d8\u91cf\u6216\u8bbe\u7f6e --kubeconfig flag \u6807\u5fd7\u6765\u6307\u5b9a\u5176\u4ed6 kubeconfig \u6587\u4ef6\u3002\u5982\u679c KUBECONFIG \u73af\u5883\u53d8\u91cf\u4e0d\u5b58\u5728\uff0ckubectl \u5c06\u4f7f\u7528\u9ed8\u8ba4\u7684 kubeconfig \u6587\u4ef6 $HOME/.kube/config \u3002 kubeconfig \u6587\u4ef6\u4e2d\u7684 context\uff08\u4e0a\u4e0b\u6587\uff09 \u5143\u7d20\u7528\u4e8e\u5c06\u8bbf\u95ee\u53c2\u6570\u5206\u7ec4\u5230\u4e00\u4e2a\u65b9\u4fbf\u7684\u540d\u79f0\u4e0b\u3002\u6bcf\u4e2a\u4e0a\u4e0b\u6587\u90fd\u6709\u4e09\u4e2a\u53c2\u6570\uff1a\u96c6\u7fa4\u3001\u547d\u540d\u7a7a\u95f4\u548c\u7528\u6237\u3002\u9ed8\u8ba4\u60c5\u51b5\u4e0b\uff0ckubectl \u547d\u4ee4\u884c\u5de5\u5177\u4f7f\u7528\u5f53\u524d\u4e0a\u4e0b\u6587\u4e2d\u7684\u53c2\u6570\u4e0e\u96c6\u7fa4\u901a\u4fe1\u3002 \u6587\u4ef6 .kube/config \u7684\u4f8b\u5b50\uff1a apiVersion : v1 clusters : - cluster : certificate-authority-data : server : https://:6443 name : contexts : - context : cluster : namespace : user : name : @ current-context : kind : Config preferences : {} users : - name : user : client-certificate-data : client-key-data : \u8bfb\u53d6\u5f53\u524d\u4e0a\u4e0b\u6587\uff1a kubectl config get-contexts \u8fd0\u884c\u7ed3\u679c\uff1a CURRENT NAME CLUSTER AUTHINFO NAMESPACE * kubernetes-admin@kubernetes kubernetes kubernetes-admin","title":"kubeconfig\u6587\u4ef6"},{"location":"k8s/cka_cn/installation/aliyun-ubuntu/#_6","text":"\u4f7f\u7528 kubeadm token \u6765\u751f\u6210\u52a0\u5165\u96c6\u7fa4\u7684\u4ee4\u724c\uff08token\uff09\u548c\u54c8\u897f\u503c\uff08hash value\uff09\u3002 kubeadm token create --print-join-command \u5728\u6240\u6709\u5de5\u4f5c\u8282\u70b9\u4e0a\u6267\u884c\u4e0b\u9762\u7684\u547d\u4ee4\uff0c\u5c06\u5de5\u4f5c\u8282\u70b9\u52a0\u5165Kubernetes\u96c6\u7fa4\u3002 # kubeadm join :6443 --token --discovery-token-ca-cert-hash \u6267\u884c\u4e0b\u9762\u547d\u4ee4\u68c0\u67e5\u6240\u6709\u8282\u70b9\u7684\u72b6\u6001\u3002 \u5f53\u524d\u6240\u6709\u8282\u70b9\u7684\u72b6\u6001\u90fd\u662f NotReady \u3002\u76ee\u524d\u4e0d\u9700\u8981\u505a\u4ec0\u4e48\uff0c\u540e\u9762\u6211\u4eec\u4f1a\u5b89\u88c5\u76f8\u5173\u7684\u7f51\u7edc\u670d\u52a1\uff08Calico \u6216 Flannel\uff09\uff0c\u5404\u8282\u70b9\u7684\u72b6\u6001\u5c31\u4f1a\u53d8\u6210Ready\u72b6\u6001\u3002","title":"\u914d\u7f6e\u5de5\u4f5c\u8282\u70b9"},{"location":"k8s/cka_cn/installation/aliyun-ubuntu/#calicoflannel","text":"\u5728\u63a7\u5236\u5e73\u9762Control Plane\u4e0a\u5b89\u88c5Calico\u6216\u8005Flannel\u3002\u5982\u679c\u9700\u8981\u914d\u7f6e\u7f51\u7edc\u7b56\u7565\uff0c\u5219\u9009\u62e9Calico\u3002","title":"\u5b89\u88c5Calico\u6216Flannel"},{"location":"k8s/cka_cn/installation/aliyun-ubuntu/#flannel","text":"Flannel \u662f\u4e3a Kubernetes \u8bbe\u8ba1\u7684\u4e00\u79cd\u7b80\u5355\u6613\u7528\u7684\u914d\u7f6e\u4e09\u5c42\u7f51\u7edc\u7684\u65b9\u6cd5\u3002 \u90e8\u7f72Flannel\uff1a \u5728 kube-flannel.yml \u4e2d\uff0c\u6211\u4eec\u53ef\u4ee5\u83b7\u53d6 Flannel \u7684\u9ed8\u8ba4\u7f51\u7edc\u8bbe\u7f6e\uff0c\u5b83\u4e0e\u6211\u4eec\u5728\u4f7f\u7528 kubeadm \u521d\u59cb\u5316\u96c6\u7fa4\u65f6\u6307\u5b9a\u7684\u53c2\u6570 --pod-network-cidr=10.244.0.0/16 \u76f8\u540c\u3002 net - co nf .jso n : | { \"Network\" : \"10.244.0.0/16\" , \"Backend\" : { \"Type\" : \"vxlan\" } } \u521b\u5efaFlannel\u670d\u52a1\u3002 apply -f https://raw.githubusercontent.com/coreos/flannel/master/Documentation/kube-flannel.yml \u8f93\u51fa\u7ed3\u679c\uff1a Warning: policy/v1beta1 PodSecurityPolicy is deprecated in v1.21+, unavailable in v1.25+ podsecuritypolicy.policy/psp.flannel.unprivileged created clusterrole.rbac.authorization.k8s.io/flannel created clusterrolebinding.rbac.authorization.k8s.io/flannel created serviceaccount/flannel created configmap/kube-flannel-cfg created daemonset.apps/kube-flannel-ds created","title":"\u5b89\u88c5Flannel"},{"location":"k8s/cka_cn/installation/aliyun-ubuntu/#calico","text":"\u5b89\u88c5\u6307\u5bfc\u624b\u518c\uff1a End-to-end Calico installation \u3002 \u4e0b\u8f7d\u5e76\u5b89\u88c5Calico\u670d\u52a1\u3002 curl https://docs.projectcalico.org/manifests/calico.yaml -O kubectl apply -f calico.yaml \u8f93\u51fa\u7ed3\u679c\uff1a configmap/calico-config created customresourcedefinition.apiextensions.k8s.io/bgpconfigurations.crd.projectcalico.org created customresourcedefinition.apiextensions.k8s.io/bgppeers.crd.projectcalico.org created customresourcedefinition.apiextensions.k8s.io/blockaffinities.crd.projectcalico.org created customresourcedefinition.apiextensions.k8s.io/caliconodestatuses.crd.projectcalico.org created customresourcedefinition.apiextensions.k8s.io/clusterinformations.crd.projectcalico.org created customresourcedefinition.apiextensions.k8s.io/felixconfigurations.crd.projectcalico.org created customresourcedefinition.apiextensions.k8s.io/globalnetworkpolicies.crd.projectcalico.org created customresourcedefinition.apiextensions.k8s.io/globalnetworksets.crd.projectcalico.org created customresourcedefinition.apiextensions.k8s.io/hostendpoints.crd.projectcalico.org created customresourcedefinition.apiextensions.k8s.io/ipamblocks.crd.projectcalico.org created customresourcedefinition.apiextensions.k8s.io/ipamconfigs.crd.projectcalico.org created customresourcedefinition.apiextensions.k8s.io/ipamhandles.crd.projectcalico.org created customresourcedefinition.apiextensions.k8s.io/ippools.crd.projectcalico.org created customresourcedefinition.apiextensions.k8s.io/ipreservations.crd.projectcalico.org created customresourcedefinition.apiextensions.k8s.io/kubecontrollersconfigurations.crd.projectcalico.org created customresourcedefinition.apiextensions.k8s.io/networkpolicies.crd.projectcalico.org created customresourcedefinition.apiextensions.k8s.io/networksets.crd.projectcalico.org created clusterrole.rbac.authorization.k8s.io/calico-kube-controllers created clusterrolebinding.rbac.authorization.k8s.io/calico-kube-controllers created clusterrole.rbac.authorization.k8s.io/calico-node created clusterrolebinding.rbac.authorization.k8s.io/calico-node created daemonset.apps/calico-node created serviceaccount/calico-node created deployment.apps/calico-kube-controllers created serviceaccount/calico-kube-controllers created poddisruptionbudget.policy/calico-kube-controllers created \u9a8c\u8bc1Calico\u670d\u52a1\u72b6\u6001\uff1a kubectl get pod -n kube-system | grep calico \u8f93\u51fa\u7ed3\u679c\uff1a calico-kube-controllers-555bc4b957-l8bn2 0 /1 Pending 0 28s calico-node-255pc 0 /1 Init:1/3 0 29s calico-node-7tmnb 0 /1 Init:1/3 0 29s calico-node-w8nvl 0 /1 Init:1/3 0 29s \u68c0\u67e5\u96c6\u7fa4\u7684\u7f51\u7edc\u72b6\u6001\uff1a sudo nerdctl network ls \u8f93\u51fa\u7ed3\u679c\uff1a NETWORK ID NAME FILE k8s-pod-network /etc/cni/net.d/10-calico.conflist 0 bridge /etc/cni/net.d/nerdctl-bridge.conflist host none","title":"\u5b89\u88c5Calico"},{"location":"k8s/cka_cn/installation/aliyun-ubuntu/#_7","text":"\u5728\u4e3b\u8282\u70b9\u4e0a\u6267\u884c\u547d\u4ee4 kubectl cluster-info \u53ef\u4ee5\u5f97\u5230\u4e0b\u9762\u7684\u4fe1\u606f\uff1a \u63a7\u5236\u5e73\u9762\uff08control plane\uff09\u8fd0\u884c\u5728 https://:6443 CoreDNS\u670d\u52a1\u8fd0\u884c\u5728 https://:6443/api/v1/namespaces/kube-system/services/kube-dns:dns/proxy kubectl cluster-info \u67e5\u770b\u8282\u70b9\u8fd0\u884c\u72b6\u6001\u3002\u6b64\u65f6\uff0c\u6240\u6709\u8282\u70b9\u90fd\u662f Ready \u7684\u6b63\u5e38\u72b6\u6001\u4e86\u3002 OS Image: Ubuntu 20.04.4 LTS Kernel Version: 5.4.0-122-generic Container Runtime: containerd://1.5.9 kubectl get nodes -owide \u8f93\u51fa\u7ed3\u679c\uff1a NAME STATUS ROLES AGE VERSION cka001 Ready control-plane 13m v1.24.0 cka002 Ready 8m35s v1.24.0 cka003 Ready 8m26s v1.24.0 \u67e5\u770bPods\u7684\u72b6\u6001\u3002 kubectl get pod -A \u8f93\u51fa\u7ed3\u679c\uff1a NAMESPACE NAME READY STATUS RESTARTS AGE kube-system calico-kube-controllers-555bc4b957-l8bn2 1/1 Running 0 7m18s kube-system calico-node-255pc 1/1 Running 0 7m19s kube-system calico-node-7tmnb 1/1 Running 0 7m19s kube-system calico-node-w8nvl 1/1 Running 0 7m19s kube-system coredns-74586cf9b6-4jwmk 1/1 Running 0 15m kube-system coredns-74586cf9b6-c5mll 1/1 Running 0 15m kube-system etcd-cka001 1/1 Running 0 15m kube-system kube-apiserver-cka001 1/1 Running 0 15m kube-system kube-controller-manager-cka001 1/1 Running 0 15m kube-system kube-proxy-dmj2t 1/1 Running 0 15m kube-system kube-proxy-n77zw 1/1 Running 0 11m kube-system kube-proxy-qs6rf 1/1 Running 0 11m kube-system kube-scheduler-cka001 1/1 Running 0 15m","title":"\u68c0\u67e5\u96c6\u7fa4\u72b6\u6001"},{"location":"k8s/cka_cn/installation/aliyun-ubuntu/#_8","text":"","title":"\u66f4\u65b0\u5b89\u88c5"},{"location":"k8s/cka_cn/installation/aliyun-ubuntu/#bash","text":"\u5728\u6bcf\u4e2a\u8282\u70b9\u4e0a\u914d\u7f6eBash\u81ea\u52a8\u8865\u5168\u529f\u80fd\u3002 \u53c2\u8003 \u6307\u5bfc \u8bbe\u7f6e kubectl \u81ea\u52a8\u8865\u5168\u529f\u80fdauto-completion \u3002 apt install -y bash-completion source /usr/share/bash-completion/bash_completion source < ( kubectl completion bash ) echo \"source <(kubectl completion bash)\" >> ~/.bashrc source ~/.bashrc","title":"Bash\u81ea\u52a8\u8865\u5168"},{"location":"k8s/cka_cn/installation/aliyun-ubuntu/#_9","text":"\u5982\u679c\u6211\u4eec\u4e3a kubectl \u8bbe\u7f6e\u4e00\u4e2a\u522b\u540d\uff0c\u6211\u4eec\u53ef\u4ee5\u901a\u8fc7\u4e00\u4e9b\u65b9\u6cd5\u6765\u6269\u5c55 shell \u81ea\u52a8\u8865\u5168\u529f\u80fd\uff0c\u4f7f\u5176\u80fd\u591f\u4e0e\u8be5\u522b\u540d\u4e00\u8d77\u4f7f\u7528\u3002 \u4e00\u79cd\u65b9\u6cd5\u662f\u5728 Bash shell \u914d\u7f6e\u6587\u4ef6\uff08\u5982 .bashrc \u6216 .bash_profile\uff09\u4e2d\u8bbe\u7f6e\u522b\u540d\uff0c\u5e76\u4e3a\u8be5\u522b\u540d\u6307\u5b9a kubectl \u7684\u5b8c\u6574\u8def\u5f84\u3002\u4f8b\u5982\uff0c\u53ef\u4ee5\u5728 .bashrc \u6587\u4ef6\u4e2d\u6dfb\u52a0\u4ee5\u4e0b\u5185\u5bb9\uff1a alias k = 'path/to/kubectl' \u7136\u540e\uff0c\u53ef\u4ee5\u4f7f\u7528\u4ee5\u4e0b\u547d\u4ee4\u91cd\u65b0\u52a0\u8f7d .bashrc \u6587\u4ef6\uff1a source ~/.bashrc \u63a5\u4e0b\u6765\uff0c\u53ef\u4ee5\u4f7f\u7528 k \u547d\u4ee4\u6765\u4ee3\u66ff kubectl \u547d\u4ee4\uff0c\u5e76\u5728\u5176\u540e\u9762\u6dfb\u52a0\u76f8\u5e94\u7684\u53c2\u6570\u548c\u9009\u9879\u3002\u5f53\u4f7f\u7528\u81ea\u52a8\u8865\u5168\u529f\u80fd\u65f6\uff0cBash shell \u4f1a\u81ea\u52a8\u5c06 k \u522b\u540d\u8f6c\u6362\u4e3a kubectl \u7684\u5b8c\u6574\u8def\u5f84\uff0c\u5e76\u5bf9\u5176\u8fdb\u884c\u81ea\u52a8\u8865\u5168\u3002 \u53e6\u4e00\u79cd\u65b9\u6cd5\u662f\u4f7f\u7528 Bash shell \u5185\u7f6e\u7684 complete \u51fd\u6570\u6765\u4e3a\u522b\u540d\u8bbe\u7f6e\u81ea\u52a8\u8865\u5168\u529f\u80fd\u3002\u4f8b\u5982\uff0c\u53ef\u4ee5\u5728 .bashrc \u6587\u4ef6\u4e2d\u6dfb\u52a0\u4ee5\u4e0b\u5185\u5bb9\uff1a echo 'alias k=kubectl' >>~/.bashrc echo 'complete -o default -F __start_kubectl k' >>~/.bashrc \u8fd9\u5c06\u4e3a\u522b\u540d k \u8bbe\u7f6e\u81ea\u52a8\u8865\u5168\u529f\u80fd\uff0c\u5e76\u5c06\u5176\u4e0e kubectl \u7684\u81ea\u52a8\u8865\u5168\u51fd\u6570 __start_kubectl \u5173\u8054\u8d77\u6765\u3002\u8fd9\u6837\uff0c\u5f53\u7528\u6237\u5728 k \u547d\u4ee4\u540e\u8f93\u5165Tab\u952e\u65f6\uff0cBash shell \u4f1a\u81ea\u52a8\u8c03\u7528 __start_kubectl \u51fd\u6570\uff0c\u5e76\u4e3a\u7528\u6237\u63d0\u4f9b\u76f8\u5e94\u7684\u81ea\u52a8\u8865\u5168\u5efa\u8bae\u3002","title":"\u522b\u540d"},{"location":"k8s/cka_cn/installation/aliyun-ubuntu/#context","text":"\u67e5\u770b\u5f53\u524d\u7684 context \u5217\u8868\uff1a kubectl config get-contexts \u8fd9\u4e2a\u547d\u4ee4\u4f1a\u5217\u51fa\u6240\u6709\u53ef\u7528\u7684 context \u5217\u8868\uff0c\u5e76\u6807\u8bb0\u51fa\u5f53\u524d\u6b63\u5728\u4f7f\u7528\u7684 context\u3002 \u7c7b\u4f3c\u4e0b\u9762\u7ed3\u679c\uff1a kubernetes-admin@kubernetes \u662fContext\u540d\u3002 kubernetes \u662f\u96c6\u7fa4\u540d\u3002 kubernetes-admin \u662f\u7528\u6237\u540d\u3002 \u5f53\u524d\u4f8b\u5b50\u4e2d\u6ca1\u6709\u6307\u5b9a\u540d\u79f0\u7a7a\u95f4\u3002 CURRENT NAME CLUSTER AUTHINFO NAMESPACE * kubernetes-admin@kubernetes kubernetes kubernetes-admin \u66f4\u65b0context\u3002\u4f8b\u5982\uff0c\u66f4\u65b0context\u7684\u9ed8\u8ba4\u540d\u79f0\u7a7a\u95f4\u7b49\u3002 # Usage: kubectl config set-context --cluster = --namespace = --user = # Set default namespace kubectl config set-context kubernetes-admin@kubernetes --cluster = kubernetes --namespace = default --user = kubernetes-admin \u5728\u4e0d\u540c\u7684context\u4e4b\u95f4\u5207\u6362\u3002 # Usage: kubectl config use-context # Switch to new context kubectl config use-context kubernetes-admin@kubernetes \u53c2\u8003\u8d44\u6599\uff1a kubectl [commandline","title":"\u66f4\u65b0\u9ed8\u8ba4Context"},{"location":"k8s/cka_cn/installation/aliyun-ubuntu/#_10","text":"\u6ce8\u610f\uff1a\u4e0b\u9762\u7684\u64cd\u4f5c\u4f1a\u91cd\u7f6e\u5f53\u524d\u96c6\u7fa4\uff08\u5220\u9664\u96c6\u7fa4\uff09\u3002 \u5220\u9664\u96c6\u7fa4\u4e2d\u6240\u6709\u8282\u70b9\u3002 kubeadm reset \u6e05\u9664 iptables \u4e2d\u5df2\u5b9a\u4e49\u7684\u89c4\u5219\u3002 iptables -F && iptables -t nat -F && iptables -t mangle -F && iptables -X \u6e05\u9664 IPVS \u4e2d\u5b9a\u4e49\u7684\u89c4\u5219\uff08\u5982\u679c\u4f7f\u7528 IPVS \uff09\u3002 ipvsadm --clear","title":"\u91cd\u7f6e\u96c6\u7fa4"},{"location":"k8s/cka_cn/installation/aliyun-ubuntu/#_11","text":"","title":"\u6392\u9519"},{"location":"k8s/cka_cn/installation/aliyun-ubuntu/#1","text":"\u62a5\u9519\u4fe1\u606f\uff1a The connection to the server :6443 was refused - did you specify the right host or port? \u89e3\u51b3\u5c1d\u8bd5\uff1a Reference \u68c0\u67e5\u6587\u4ef6kubeconfig\u7684\u5185\u5bb9\u548c\u6587\u4ef6\u8def\u5f84\u662f\u5426\u6b63\u786e\u3002 \u68c0\u67e5\u73af\u5883\u53d8\u91cf\u8bbe\u7f6e\u3002 env | grep -i kub \u68c0\u67e5\u5bb9\u5668\u8fd0\u884c\u72b6\u6001\u3002 sudo systemctl status containerd.service \u68c0\u67e5kubelet\u670d\u52a1\u3002 sudo systemctl status kubelet.service \u68c0\u67e5 6443 \u7aef\u53e3\u76d1\u542c\u72b6\u6001\u3002 netstat -pnlt | grep 6443 \u68c0\u67e5\u9632\u706b\u5899\u72b6\u6001\u3002 sudo systemctl status firewalld.service \u68c0\u67e5kubelet\u65e5\u5fd7\u3002 journalctl -xeu kubelet","title":"\u9519\u8bef1"},{"location":"k8s/cka_cn/installation/aliyun-ubuntu/#2","text":"\u62a5\u9519\u4fe1\u606f\uff1a \"Container runtime network not ready\" networkReady=\"NetworkReady=false reason:NetworkPluginNotReady message:Network plugin returns error: cni plugin not initialized\" \u5c1d\u8bd5\u65b9\u6cd5\uff1a \u91cd\u542fContainerd\u670d\u52a1\u3002 sudo systemctl restart containerd sudo systemctl status containerd","title":"\u9519\u8bef2"},{"location":"k8s/cka_cn/installation/multiple-local/","text":"CKA\u81ea\u5b66\u7b14\u8bb02:\u591a\u8282\u70b9\u865a\u62df\u673a\u5b89\u88c5Kubernetes \u00b6 \u6458\u8981 \u00b6 \u5728\u672c\u5730Windows\u73af\u5883\u4e2d\uff0c\u901a\u8fc7VMWare\u5b89\u88c5\u4e09\u53f0Ubuntu\u865a\u62df\u673a\u3002\u5728Ubuntu\u865a\u62df\u673a\u4e2d\u5b89\u88c5\u57fa\u4e8eContainerd\u7684Kubernetes\u7cfb\u7edf\uff0c\u5e76\u5206\u522b\u914d\u7f6e\u4e00\u4e2a\u4e3b\u8282\u70b9Master\u548c\u4e24\u4e2a\u5de5\u4f5c\u8282\u70b9Worker\u3002 \u672c\u5730\u865a\u62df\u673a\u8bbe\u7f6e \u00b6 VMWare \u8bbe\u7f6e VMnet1: host-only\u6a21\u5f0f, \u7f51\u7edcsubnet: 192.168.150.0/24 VMnet8: NAT\u6a21\u5f0f, \u7f51\u7edcsubnet: 11.0.1.0/24 \u901a\u8fc7VMWare\u521b\u5efa\u5ba2\u6237\u865a\u62df\u673a\u3002 \u5185\u5b58\uff1a4 GB CPU\uff1a1 CPUs with 2 Cores \u64cd\u4f5c\u7cfb\u7edf\uff1aUbuntu Server 22.04 \u7f51\u7edc\uff1aNAT \u63d0\u793a\uff1a \u5f53\u524d\u7ec3\u4e60\u4e2d\uff0cKubernetes\u662f\u57fa\u4e8eContainerd\uff0c\u4e0d\u662fDocker\u3002 Ubuntu\u9884\u914d\u7f6e \u00b6 \u6ce8\u610f\uff1a\u4e0b\u9762\u7684\u4efb\u52a1\uff0c\u9700\u8981\u5728\u6bcf\u53f0\u865a\u62df\u673a\u4e2d\u6267\u884c\u4e00\u6b21\u3002\u4ee5\u4e0b\u7b80\u79f0\u865a\u62df\u673a\u4e3a\u8282\u70b9\u3002 \u5728\u6240\u6709\u8282\u70b9\u4e2d\u521b\u5efa\u7528\u6237 vagrant \u3002 sudo adduser vagrant sudo usermod -g sudo vagrant sudo usermod -a -G root vagrant sudo passwd vagrant \u5728\u6240\u6709\u8282\u70b9\u4e2d\u8bbe\u7f6e\u7528\u6237 root \u7684\u5bc6\u7801\u3002 sudo passwd root \u4fee\u6539ssh\u670d\u52a1\u7684\u914d\u7f6e\u6587\u4ef6\u3002\u5f00\u653e root \u7528\u6237\u901a\u8fc7ssh\u767b\u5f55\uff08\u9ed8\u8ba4\u662f\u7981\u7528\u7684\uff09\u3002 sudo vi /etc/ssh/sshd_config \u628a\u53c2\u6570 PermitRootLogin \u7684\u503c\u4ece prohibit-password \u6539\u4e3a yes \u3002 PermitRootLogin yes # PermitRootLogin prohibit-password \u91cd\u65b0\u542f\u52a8sshd\u670d\u52a1\u3002 sudo systemctl restart sshd \u66f4\u6539\u4e3b\u673a\u540d\uff0c\u8fd9\u91cc\u662f ubu1 . sudo hostnamectl set-hostname ubu1 sudo hostnamectl set-hostname ubu1 --pretty \u9a8c\u8bc1\u4e3b\u673a\u540d\u662f\u5426\u88ab\u6b63\u786e\u4fee\u6539\u4e86\uff0c\u6bd4\u5982\u6539\u4e3a ubu1 \u3002 cat /etc/machine-info \u9a8c\u8bc1\u4e3b\u673a\u540d\u662f\u5426\u88ab\u6b63\u786e\u4fee\u6539\u4e86\uff0c\u6bd4\u5982\u6539\u4e3a ubu1 \u3002 cat /etc/hostname \u9a8c\u8bc1\u4e3b\u673aIP\u5730\u5740 127.0.1.1 \u5df2\u7ecf\u914d\u7f6e\u7ed9\u5f53\u524d\u8282\u70b9\uff0c\u6bd4\u5982 ubu1 \u3002\u540c\u65f6\uff0c\u5728\u6240\u6709\u8282\u70b9\u7684 /etc/hosts \u6587\u4ef6\u4e2d\u6dfb\u52a0\u5176\u4ed6\u8282\u70b9\u7684IP\u548c\u4e3b\u673a\u5bf9\u5e94\u4fe1\u606f\u3002 sudo vi /etc/hosts \u4ee5\u5f53\u524d\u7ec3\u4e60\u4e3a\u4f8b\uff0c\u4fee\u6539\u540e\u7684 /etc/hosts \u6587\u4ef6\u7c7b\u4f3c\u5982\u4e0b\u5185\u5bb9\u3002 127.0.1.1 ubu1 11.0.1.129 ubu1 11.0.1.130 ubu2 11.0.1.131 ubu3 11.0.1.132 ubu4 \u521b\u5efa\u6587\u4ef6 /etc/netplan/00-installer-config.yaml \u3002 sudo vi /etc/netplan/00-installer-config.yaml \u66f4\u65b0\u6b64\u6587\u4ef6\uff0c\u8bbe\u5b9a\u5f53\u524d\u8282\u70b9\u4f7f\u7528\u56fa\u5b9aIP\u5730\u5740\uff0c\u6bd4\u5982\uff0c 11.0.1.129 \u3002 network : ethernets : ens33 : dhcp4 : false addresses : - 11.0.1.129/24 nameservers : addresses : - 11.0.1.2 routes : - to : default via : 11.0.1.2 version : 2 \u6267\u884c\u4e0b\u9762\u547d\u4ee4\u65f6\uff0c\u4f7f\u4e0a\u8ff0\u6539\u52a8\u751f\u6548\u3002\u6ce8\u610f\uff0c\u5f53\u524dssh\u8fde\u63a5\u4f1a\u56e0\u6b64\u800c\u65ad\u5f00\u3002 sudo netplan apply \u5728\u6240\u6709\u8282\u70b9\u7981\u7528\u4ea4\u6362\u5206\u533aswap\u548c\u9632\u706b\u5899firewall\u3002 sudo swapoff -a sudo ufw disable sudo ufw status verbose \u5728\u6240\u6709\u8282\u70b9\u7684\u6587\u4ef6 /etc/fstab \u4e2d\u6ce8\u91ca\u6389\u6d89\u53caswap\u7684\u90a3\u4e00\u884c\uff0c\u4fee\u6539\u540e\u9700\u8981\u91cd\u542f\u5f53\u524d\u8282\u70b9\u3002 sudo vi /etc/fstab \u4fee\u6539\u540e\u7684\u7ed3\u679c\u7c7b\u4f3c\u5982\u4e0b\u3002 /dev/disk/by-uuid/df370d2a-83e5-4895-8c7f-633f2545e3fe / ext4 defaults 0 1 # /swap.img none swap sw 0 0 \u5728\u6240\u6709\u8282\u70b9\u8bbe\u7f6e\u7edf\u4e00\u7684\u65f6\u533a\u3002 sudo ln -sf /usr/share/zoneinfo/Asia/Shanghai /etc/localtime sudo cp /etc/profile /etc/profile.bak echo 'LANG=\"en_US.UTF-8\"' | sudo tee -a /etc/profile source /etc/profile \u6267\u884c\u547d\u4ee4 ll /etc/localtime \u6765\u9a8c\u8bc1\u65f6\u533a\u662f\u5426\u4fee\u6539\u6b63\u786e\u3002 lrwxrwxrwx 1 root root 33 Jul 15 22:00 /etc/localtime -> /usr/share/zoneinfo/Asia/Shanghai \u5728\u6240\u6709\u8282\u70b9\u4fee\u6539\u5185\u6838\u8bbe\u7f6e\u3002 cat < /etc/apt/sources.list.d/kubernetes.list deb https://mirrors.aliyun.com/kubernetes/apt/ kubernetes-xenial main EOF \u68c0\u67e5\u5f53\u524d kubeadm \u7684\u7248\u672c\u3002 apt policy kubeadm \u5b89\u88c5 1.24.1-00 \u7248\u672c\u7684 kubeadm . sudo apt-get -y install kubelet = 1 .24.1-00 kubeadm = 1 .24.1-00 kubectl = 1 .24.1-00 --allow-downgrades \u914d\u7f6e\u4e3b\u8282\u70b9 \u00b6 kubeadm\u521d\u59cb\u5316 \u00b6 \u5728\u627f\u62c5\u4e3b\u8282\u70b9\u7684\u865a\u62df\u673a\u91cc\u914d\u7f6e\u63a7\u5236\u5e73\u9762\uff08Control Plane\uff09\u3002 \u68c0\u67e5 kubeadm \u5f53\u524d\u9ed8\u8ba4\u914d\u7f6e\u53c2\u6570\u3002 kubeadm config print init-defaults \u7c7b\u4f3c\u7ed3\u679c\u5982\u4e0b\u3002\u4fdd\u5b58\u9ed8\u8ba4\u914d\u7f6e\u7684\u7ed3\u679c\uff0c\u540e\u7eed\u4f1a\u4f5c\u4e3a\u53c2\u8003\u3002 apiVersion : kubeadm.k8s.io/v1beta3 bootstrapTokens : - groups : - system:bootstrappers:kubeadm:default-node-token token : abcdef.0123456789abcdef ttl : 24h0m0s usages : - signing - authentication kind : InitConfiguration localAPIEndpoint : advertiseAddress : 1.2.3.4 bindPort : 6443 nodeRegistration : criSocket : unix:///var/run/containerd/containerd.sock imagePullPolicy : IfNotPresent name : node taints : null --- apiServer : timeoutForControlPlane : 4m0s apiVersion : kubeadm.k8s.io/v1beta3 certificatesDir : /etc/kubernetes/pki clusterName : kubernetes controllerManager : {} dns : {} etcd : local : dataDir : /var/lib/etcd imageRepository : k8s.gcr.io kind : ClusterConfiguration kubernetesVersion : 1.24.0 networking : dnsDomain : cluster.local serviceSubnet : 10.96.0.0/12 scheduler : {} \u6a21\u62df\u5b89\u88c5\u548c\u6b63\u5f0f\u5b89\u88c5\u3002 \u901a\u8fc7\u547d\u4ee4 kubeadm init \u8fdb\u884c\u4e3b\u8282\u70b9\u7684\u521d\u59cb\u5316\uff0c\u4e0b\u9762\u662f\u8fd9\u4e2a\u547d\u4ee4\u4e3b\u8981\u53c2\u6570\u7684\u8bf4\u660e\uff0c\u7279\u522b\u662f\u7f51\u7edc\u53c2\u6570\u7684\u4e09\u4e2a\u9009\u62e9\u3002 --pod-network-cidr : \u6307\u5b9apod\u4f7f\u7528\u7684IP\u5730\u5740\u8303\u56f4\u3002\u5982\u679c\u6307\u5b9a\u4e86\u8be5\u53c2\u6570\uff0c\u5219Control Plane\u4f1a\u81ea\u52a8\u8bb2\u6307\u5b9a\u7684CIDR\u5206\u914d\u7ed9\u6bcf\u4e2a\u8282\u70b9\u3002 IP\u5730\u5740\u6bb5 10.244.0.0/16 \u662fFlannel\u7f51\u7edc\u7ec4\u4ef6\u9ed8\u8ba4\u7684\u5730\u5740\u8303\u56f4\u3002\u5982\u679c\u9700\u8981\u4fee\u6539Flannel\u7684IP\u5730\u5740\u6bb5\uff0c\u9700\u8981\u5728\u8fd9\u91cc\u6307\u5b9a\uff0c\u4e14\u5728\u90e8\u7f72Flannel\u65f6\u4e5f\u8981\u4fdd\u6301\u4e00\u81f4\u7684IP\u6bb5\u3002 --apiserver-bind-port : API\u670d\u52a1\uff08API Server\uff09\u7684\u7aef\u53e3\uff0c\u9ed8\u8ba4\u65f66443\u3002 --service-cidr : \u6307\u5b9a\u670d\u52a1\uff08service\uff09\u7684IP\u5730\u5740\u6bb5\uff0c\u9ed8\u8ba4\u662f 10.96.0.0/12 \u3002 \u63d0\u793a\uff1a \u670d\u52a1VIPs\uff08service VIPs\uff09\uff0c\u4e5f\u79f0\u4f5c\u96c6\u7fa4IP\uff08Cluster IP\uff09\uff0c\u901a\u8fc7\u53c2\u6570 --service-cidr \u6307\u5b9a\u3002 podCIDR\uff0c\u4e5f\u79f0\u4e3aendpoint IP\uff0c\u901a\u8fc7\u53c2\u6570 --pod-network-cidr \u6307\u5b9a\u3002 \u67094\u79cd\u5178\u578b\u7684\u7f51\u7edc\u95ee\u9898\uff1a \u9ad8\u5ea6\u8026\u5408\u7684\u5bb9\u5668\u4e0e\u5bb9\u5668\u4e4b\u95f4\u7684\u901a\u4fe1\uff1a\u8fd9\u53ef\u4ee5\u901a\u8fc7Pod\uff08podCIDR\uff09\u548c\u672c\u5730\u4e3b\u673a\u901a\u4fe1\u6765\u89e3\u51b3\u3002 Pod\u5bf9Pod\u901a\u4fe1\uff08Pod-to-Pod\uff09\uff1a \u4e5f\u88ab\u79f0\u4e3a\u5bb9\u5668\u5bf9\u5bb9\u5668\u901a\u4fe1\uff08container-to-container\uff09\u3002 \u5728Flannel\u7f51\u7edc\u63d2\u4ef6\u4e2d\u7684\u793a\u4f8b\u6d41\u7a0b\u662f\uff1aPod \u2192 veth\u5bf9 \u2192 cni0 \u2192 flannel.1 \u2192 \u5bbf\u4e3b\u673aeth0 \u2192 \u5bbf\u4e3b\u673aeth0 \u2192 flannel.1 \u2192 cni0 \u2192 veth\u5bf9 \u2192 Pod\u3002 Pod\u5bf9Service\u901a\u4fe1\uff08Pod-to-Service\uff09\uff1a \u6d41\u7a0b: Pod \u2192 \u5185\u6838 \u2192 Service iptables \u2192 Service \u2192 Pod iptables \u2192 Pod\u3002 \u5916\u90e8\u5bf9Service\u901a\u4fe1\uff08External-to-Service\uff09\uff1a \u8d1f\u8f7d\u5747\u8861\u5668: SLB \u2192 NodePort \u2192 Service \u2192 Pod\u3002 kube-proxy \u662f\u5bf9iptables\u8d1f\u8d23\uff0c\u4e0d\u662f\u7f51\u7edc\u6d41\u91cf\uff08traffic\uff09\u3002 kube-proxy \u662fKubernetes\u96c6\u7fa4\u4e2d\u7684\u4e00\u4e2a\u7ec4\u4ef6\uff0c\u8d1f\u8d23\u4e3aService\u63d0\u4f9b\u4ee3\u7406\u670d\u52a1\uff0c\u540c\u65f6\u4e5f\u662fKubernetes\u7f51\u7edc\u6a21\u578b\u4e2d\u7684\u91cd\u8981\u7ec4\u6210\u90e8\u5206\u4e4b\u4e00\u3002 kube-proxy \u4f1a\u5728\u6bcf\u4e2a\u8282\u70b9\u4e0a\u542f\u52a8\u4e00\u4e2a\u4ee3\u7406\u8fdb\u7a0b\uff0c\u901a\u8fc7\u76d1\u542cKubernetes API Server\u7684Service\u548cEndpoint\u7684\u53d8\u5316\u6765\u7ef4\u62a4\u4e00\u4e2a\u672c\u5730\u7684Service\u548cEndpoint\u7684\u7f13\u5b58\u3002\u5f53\u6709\u8bf7\u6c42\u5230\u8fbe\u67d0\u4e2aService\u65f6\uff0c kube-proxy \u4f1a\u6839\u636e\u8be5Service\u7684\u7c7b\u578b\uff08ClusterIP\u3001NodePort\u3001LoadBalancer\u3001ExternalName\uff09\u548c\u7aef\u53e3\u53f7\uff0c\u751f\u6210\u76f8\u5e94\u7684iptables\u89c4\u5219\uff0c\u5c06\u8bf7\u6c42\u8f6c\u53d1\u7ed9Service\u6240\u4ee3\u7406\u7684\u540e\u7aefPod\u3002 iptables\u662fLinux\u7cfb\u7edf\u4e2d\u7684\u4e00\u4e2a\u91cd\u8981\u7f51\u7edc\u5de5\u5177\uff0c\u53ef\u4ee5\u8bbe\u7f6eIP\u5305\u7684\u8fc7\u6ee4\u3001\u8f6c\u53d1\u548c\u4fee\u6539\u89c4\u5219\uff0c\u53ef\u4ee5\u5b9e\u73b0\u7f51\u7edc\u5c42\u7684\u9632\u706b\u5899\u3001NAT\u7b49\u529f\u80fd\u3002\u5728Kubernetes\u96c6\u7fa4\u4e2d\uff0c kube-proxy \u901a\u8fc7\u751f\u6210\u548c\u66f4\u65b0iptables\u89c4\u5219\uff0c\u6765\u5b9e\u73b0Service\u548cEndpoint\u4e4b\u95f4\u7684\u8f6c\u53d1\u548c\u4ee3\u7406\u3002\u5177\u4f53\u6765\u8bf4\uff0ckube-proxy\u4f1a\u4e3a\u6bcf\u4e2aService\u521b\u5efa\u4e09\u6761iptables\u89c4\u5219\u94fe\uff08nat\u8868\u4e2d\u7684KUBE-SERVICES\u548cKUBE-NODEPORTS\u94fe\uff0c\u4ee5\u53cafilter\u8868\u4e2d\u7684KUBE-SVC-XXXXX\u94fe\uff09\uff0c\u901a\u8fc7\u8fd9\u4e9b\u89c4\u5219\u94fe\uff0c\u5c06\u8bf7\u6c42\u8f6c\u53d1\u5230\u76f8\u5e94\u7684Pod\u6216\u8005Service\u4e0a\u3002 \u56e0\u6b64\uff0c kube-proxy \u548ciptables\u662f\u7d27\u5bc6\u76f8\u5173\u7684\u4e24\u4e2a\u7ec4\u4ef6\uff0c\u901a\u8fc7iptables\u89c4\u5219\u6765\u5b9e\u73b0Service\u548cPod\u4e4b\u95f4\u7684\u8f6c\u53d1\u548c\u4ee3\u7406\u3002\u8fd9\u79cd\u5b9e\u73b0\u65b9\u5f0f\u5177\u6709\u53ef\u6269\u5c55\u6027\u548c\u9ad8\u53ef\u7528\u6027\uff0c\u540c\u65f6\u4e5f\u63d0\u4f9b\u4e86\u4e00\u79cd\u7075\u6d3b\u7684\u7f51\u7edc\u6a21\u578b\uff0c\u53ef\u4ee5\u65b9\u4fbf\u5730\u5b9e\u73b0\u670d\u52a1\u53d1\u73b0\u3001\u8d1f\u8f7d\u5747\u8861\u7b49\u529f\u80fd\u3002 sudo kubeadm init \\ --dry-run \\ --pod-network-cidr = 10 .244.0.0/16 \\ --service-cidr = 192 .244.0.0/16 \\ --image-repository = registry.aliyuncs.com/google_containers \\ --kubernetes-version = v1.24.0 sudo kubeadm init \\ --pod-network-cidr = 10 .244.0.0/16 \\ --service-cidr = 192 .244.0.0/16 \\ --image-repository = registry.aliyuncs.com/google_containers \\ --kubernetes-version = v1.24.0 kubeconfig\u6587\u4ef6 \u00b6 \u7ed9\u5f53\u524d\u5b89\u88c5\u7528\u6237\u914d\u7f6e kubeconfig \u6587\u4ef6\uff08\u5f53\u524d\u4f8b\u5b50\u662f\u7528\u6237 vagrant \uff09\u3002 mkdir -p $HOME /.kube sudo cp -i /etc/kubernetes/admin.conf $HOME /.kube/config sudo chown $( id -u ) : $( id -g ) $HOME /.kube/config Kubernetes \u63d0\u4f9b\u4e86\u4e00\u4e2a\u547d\u4ee4\u884c\u5de5\u5177 kubectl \uff0c\u7528\u4e8e\u4f7f\u7528 Kubernetes API \u4e0e Kubernetes \u96c6\u7fa4\u7684\u63a7\u5236\u5e73\u9762\u8fdb\u884c\u901a\u4fe1\u3002 kubectl \u63a7\u5236 Kubernetes cluster manager \uff08\u96c6\u7fa4\u7ba1\u7406\u5668\uff09\u3002 \u5bf9\u4e8e\u914d\u7f6e\uff0ckubectl \u5728 $HOME/.kube \u76ee\u5f55\u4e2d\u67e5\u627e\u4e00\u4e2a\u540d\u4e3a config \u7684\u6587\u4ef6\uff0c\u8be5\u6587\u4ef6\u662f\u7531 kubeadm init \u751f\u6210\u7684\u6587\u4ef6 /etc/kubernetes/admin.conf \u7684\u526f\u672c\u3002 \u6211\u4eec\u53ef\u4ee5\u901a\u8fc7\u8bbe\u7f6e KUBECONFIG \u73af\u5883\u53d8\u91cf\u6216\u8bbe\u7f6e --kubeconfig flag \u6807\u5fd7\u6765\u6307\u5b9a\u5176\u4ed6 kubeconfig \u6587\u4ef6\u3002\u5982\u679c KUBECONFIG \u73af\u5883\u53d8\u91cf\u4e0d\u5b58\u5728\uff0ckubectl \u5c06\u4f7f\u7528\u9ed8\u8ba4\u7684 kubeconfig \u6587\u4ef6 $HOME/.kube/config \u3002 kubeconfig \u6587\u4ef6\u4e2d\u7684 context\uff08\u4e0a\u4e0b\u6587\uff09 \u5143\u7d20\u7528\u4e8e\u5c06\u8bbf\u95ee\u53c2\u6570\u5206\u7ec4\u5230\u4e00\u4e2a\u65b9\u4fbf\u7684\u540d\u79f0\u4e0b\u3002\u6bcf\u4e2a\u4e0a\u4e0b\u6587\u90fd\u6709\u4e09\u4e2a\u53c2\u6570\uff1a\u96c6\u7fa4\u3001\u547d\u540d\u7a7a\u95f4\u548c\u7528\u6237\u3002\u9ed8\u8ba4\u60c5\u51b5\u4e0b\uff0ckubectl \u547d\u4ee4\u884c\u5de5\u5177\u4f7f\u7528\u5f53\u524d\u4e0a\u4e0b\u6587\u4e2d\u7684\u53c2\u6570\u4e0e\u96c6\u7fa4\u901a\u4fe1\u3002 \u6587\u4ef6 .kube/config \u7684\u4f8b\u5b50\uff1a apiVersion : v1 clusters : - cluster : certificate-authority-data : server : https://:6443 name : contexts : - context : cluster : namespace : user : name : @ current-context : kind : Config preferences : {} users : - name : user : client-certificate-data : client-key-data : \u8bfb\u53d6\u5f53\u524d\u4e0a\u4e0b\u6587\uff1a kubectl config get-contexts \u8fd0\u884c\u7ed3\u679c\uff1a CURRENT NAME CLUSTER AUTHINFO NAMESPACE * kubernetes-admin@kubernetes kubernetes kubernetes-admin \u5b89\u88c5Calico \u00b6 \u53c2\u8003\u5b89\u88c5\u6307\u5bfc End-to-end Calico installation \u3002 \u5feb\u901f\u5b89\u88c5\u624b\u518c QuickStart \u5b89\u88c5 Calico\uff1a kubectl create -f https://raw.githubusercontent.com/projectcalico/calico/v3.25.1/manifests/tigera-operator.yaml \u8fd0\u884c\u7ed3\u679c\uff1a namespace/tigera-operator created customresourcedefinition.apiextensions.k8s.io/bgpconfigurations.crd.projectcalico.org created customresourcedefinition.apiextensions.k8s.io/bgppeers.crd.projectcalico.org created customresourcedefinition.apiextensions.k8s.io/blockaffinities.crd.projectcalico.org created customresourcedefinition.apiextensions.k8s.io/caliconodestatuses.crd.projectcalico.org created customresourcedefinition.apiextensions.k8s.io/clusterinformations.crd.projectcalico.org created customresourcedefinition.apiextensions.k8s.io/felixconfigurations.crd.projectcalico.org created customresourcedefinition.apiextensions.k8s.io/globalnetworkpolicies.crd.projectcalico.org created customresourcedefinition.apiextensions.k8s.io/globalnetworksets.crd.projectcalico.org created customresourcedefinition.apiextensions.k8s.io/hostendpoints.crd.projectcalico.org created customresourcedefinition.apiextensions.k8s.io/ipamblocks.crd.projectcalico.org created customresourcedefinition.apiextensions.k8s.io/ipamconfigs.crd.projectcalico.org created customresourcedefinition.apiextensions.k8s.io/ipamhandles.crd.projectcalico.org created customresourcedefinition.apiextensions.k8s.io/ippools.crd.projectcalico.org created customresourcedefinition.apiextensions.k8s.io/ipreservations.crd.projectcalico.org created customresourcedefinition.apiextensions.k8s.io/kubecontrollersconfigurations.crd.projectcalico.org created customresourcedefinition.apiextensions.k8s.io/networkpolicies.crd.projectcalico.org created customresourcedefinition.apiextensions.k8s.io/networksets.crd.projectcalico.org created customresourcedefinition.apiextensions.k8s.io/apiservers.operator.tigera.io created customresourcedefinition.apiextensions.k8s.io/imagesets.operator.tigera.io created customresourcedefinition.apiextensions.k8s.io/installations.operator.tigera.io created customresourcedefinition.apiextensions.k8s.io/tigerastatuses.operator.tigera.io created serviceaccount/tigera-operator created clusterrole.rbac.authorization.k8s.io/tigera-operator created clusterrolebinding.rbac.authorization.k8s.io/tigera-operator created deployment.apps/tigera-operator created kubectl apply -f https://raw.githubusercontent.com/projectcalico/calico/v3.25.1/manifests/calicoctl.yaml \u8fd0\u884c\u7ed3\u679c\uff1a serviceaccount/calicoctl created pod/calicoctl created clusterrole.rbac.authorization.k8s.io/calicoctl created clusterrolebinding.rbac.authorization.k8s.io/calicoctl created \u9a8c\u8bc1Calico\u7684\u72b6\u6001\u3002Calico\u7684\u521d\u59cb\u5316\u8fc7\u7a0b\u53ef\u80fd\u9700\u8981\u51e0\u5206\u949f\u65f6\u95f4\u5b8c\u6210\u3002 kubectl get pod -n kube-system | grep calico \u8fd0\u884c\u7ed3\u679c\uff1a calico-kube-controllers-555bc4b957-l8bn2 0/1 Pending 0 28s calico-node-255pc 0/1 Init:1/3 0 29s calico-node-7tmnb 0/1 Init:1/3 0 29s calico-node-w8nvl 0/1 Init:1/3 0 29s \u9a8c\u8bc1\u7f51\u7edc\u72b6\u6001\u3002 sudo nerdctl network ls \u8fd0\u884c\u7ed3\u679c\uff1a NETWORK ID NAME FILE k8s-pod-network /etc/cni/net.d/10-calico.conflist 17f29b073143 bridge /etc/cni/net.d/nerdctl-bridge.conflist host none \u914d\u7f6e\u5de5\u4f5c\u8282\u70b9 \u00b6 \u4f7f\u7528 kubeadm token \u6765\u751f\u6210\u52a0\u5165\u96c6\u7fa4\u7684\u4ee4\u724c\uff08token\uff09\u548c\u54c8\u897f\u503c\uff08hash value\uff09\u3002 kubeadm token create --print-join-command \u547d\u4ee4\u7528\u6cd5\uff1a sudo kubeadm join :6443 --token --discovery-token-ca-cert-hash < hash key generated by kubeadm init> \u8fd0\u884c\u7ed3\u679c\uff1a [preflight] Running pre-flight checks [WARNING SystemVerification]: missing optional cgroups: blkio [preflight] Reading configuration from the cluster... [preflight] FYI: You can look at this config file with 'kubectl -n kube-system get cm kubeadm-config -o yaml' [kubelet-start] Writing kubelet configuration to file \"/var/lib/kubelet/config.yaml\" [kubelet-start] Writing kubelet environment file with flags to file \"/var/lib/kubelet/kubeadm-flags.env\" [kubelet-start] Starting the kubelet [kubelet-start] Waiting for the kubelet to perform the TLS Bootstrap... This node has joined the cluster: * Certificate signing request was sent to apiserver and a response was received. * The Kubelet was informed of the new secure connection details. Run 'kubectl get nodes' on the control-plane to see this node join the cluster. \u68c0\u67e5\u96c6\u7fa4\u72b6\u6001 \u00b6 \u67e5\u770b Kubernetes \u96c6\u7fa4\u7684\u4fe1\u606f\uff0c\u5305\u62ec\u96c6\u7fa4 API Server \u7684\u5730\u5740\u3001Kubernetes DNS \u670d\u52a1\u7684\u5730\u5740\u7b49\u3002 kubectl cluster-info \u8fd0\u884c\u7ed3\u679c\uff1a bKubernetes control plane is running at https://11.0.1.129:6443 CoreDNS is running at https://11.0.1.129:6443/api/v1/namespaces/kube-system/services/kube-dns:dns/proxy To further debug and diagnose cluster problems, use 'kubectl cluster-info dump'. \u5217\u51fa\u96c6\u7fa4\u4e2d\u6240\u6709\u8282\u70b9\u7684\u8be6\u7ec6\u4fe1\u606f\uff0c\u5305\u62ec\u8282\u70b9\u540d\u79f0\u3001\u8282\u70b9 IP\u3001\u8282\u70b9\u6807\u7b7e\u3001\u8282\u70b9\u72b6\u6001\u7b49\u3002 kubectl get nodes -owide \u5217\u51fa Kubernetes \u96c6\u7fa4\u4e2d\u6240\u6709 Namespace \u4e0b\u7684 Pod\u3002 kubectl get pod -A \u66f4\u65b0\u5b89\u88c5 \u00b6 Bash\u81ea\u52a8\u8865\u5168 \u00b6 \u5728\u6bcf\u4e2a\u8282\u70b9\u4e0a\u914d\u7f6eBash\u81ea\u52a8\u8865\u5168\u529f\u80fd\u3002 \u53c2\u8003 \u6307\u5bfc \u8bbe\u7f6e kubectl \u81ea\u52a8\u8865\u5168\u529f\u80fdauto-completion \u3002 apt install -y bash-completion source /usr/share/bash-completion/bash_completion source < ( kubectl completion bash ) echo \"source <(kubectl completion bash)\" >> ~/.bashrc source ~/.bashrc \u522b\u540d \u00b6 \u5982\u679c\u6211\u4eec\u4e3a kubectl \u8bbe\u7f6e\u4e00\u4e2a\u522b\u540d\uff0c\u6211\u4eec\u53ef\u4ee5\u901a\u8fc7\u4e00\u4e9b\u65b9\u6cd5\u6765\u6269\u5c55 shell \u81ea\u52a8\u8865\u5168\u529f\u80fd\uff0c\u4f7f\u5176\u80fd\u591f\u4e0e\u8be5\u522b\u540d\u4e00\u8d77\u4f7f\u7528\u3002 \u4e00\u79cd\u65b9\u6cd5\u662f\u5728 Bash shell \u914d\u7f6e\u6587\u4ef6\uff08\u5982 .bashrc \u6216 .bash_profile\uff09\u4e2d\u8bbe\u7f6e\u522b\u540d\uff0c\u5e76\u4e3a\u8be5\u522b\u540d\u6307\u5b9a kubectl \u7684\u5b8c\u6574\u8def\u5f84\u3002\u4f8b\u5982\uff0c\u53ef\u4ee5\u5728 .bashrc \u6587\u4ef6\u4e2d\u6dfb\u52a0\u4ee5\u4e0b\u5185\u5bb9\uff1a alias k = 'path/to/kubectl' \u7136\u540e\uff0c\u53ef\u4ee5\u4f7f\u7528\u4ee5\u4e0b\u547d\u4ee4\u91cd\u65b0\u52a0\u8f7d .bashrc \u6587\u4ef6\uff1a source ~/.bashrc \u63a5\u4e0b\u6765\uff0c\u53ef\u4ee5\u4f7f\u7528 k \u547d\u4ee4\u6765\u4ee3\u66ff kubectl \u547d\u4ee4\uff0c\u5e76\u5728\u5176\u540e\u9762\u6dfb\u52a0\u76f8\u5e94\u7684\u53c2\u6570\u548c\u9009\u9879\u3002\u5f53\u4f7f\u7528\u81ea\u52a8\u8865\u5168\u529f\u80fd\u65f6\uff0cBash shell \u4f1a\u81ea\u52a8\u5c06 k \u522b\u540d\u8f6c\u6362\u4e3a kubectl \u7684\u5b8c\u6574\u8def\u5f84\uff0c\u5e76\u5bf9\u5176\u8fdb\u884c\u81ea\u52a8\u8865\u5168\u3002 \u53e6\u4e00\u79cd\u65b9\u6cd5\u662f\u4f7f\u7528 Bash shell \u5185\u7f6e\u7684 complete \u51fd\u6570\u6765\u4e3a\u522b\u540d\u8bbe\u7f6e\u81ea\u52a8\u8865\u5168\u529f\u80fd\u3002\u4f8b\u5982\uff0c\u53ef\u4ee5\u5728 .bashrc \u6587\u4ef6\u4e2d\u6dfb\u52a0\u4ee5\u4e0b\u5185\u5bb9\uff1a echo 'alias k=kubectl' >>~/.bashrc echo 'complete -o default -F __start_kubectl k' >>~/.bashrc \u8fd9\u5c06\u4e3a\u522b\u540d k \u8bbe\u7f6e\u81ea\u52a8\u8865\u5168\u529f\u80fd\uff0c\u5e76\u5c06\u5176\u4e0e kubectl \u7684\u81ea\u52a8\u8865\u5168\u51fd\u6570 __start_kubectl \u5173\u8054\u8d77\u6765\u3002\u8fd9\u6837\uff0c\u5f53\u7528\u6237\u5728 k \u547d\u4ee4\u540e\u8f93\u5165Tab\u952e\u65f6\uff0cBash shell \u4f1a\u81ea\u52a8\u8c03\u7528 __start_kubectl \u51fd\u6570\uff0c\u5e76\u4e3a\u7528\u6237\u63d0\u4f9b\u76f8\u5e94\u7684\u81ea\u52a8\u8865\u5168\u5efa\u8bae\u3002 \u66f4\u65b0\u9ed8\u8ba4Context \u00b6 \u67e5\u770b\u5f53\u524d\u7684 context \u5217\u8868\uff1a kubectl config get-contexts \u8fd9\u4e2a\u547d\u4ee4\u4f1a\u5217\u51fa\u6240\u6709\u53ef\u7528\u7684 context \u5217\u8868\uff0c\u5e76\u6807\u8bb0\u51fa\u5f53\u524d\u6b63\u5728\u4f7f\u7528\u7684 context\u3002 \u7c7b\u4f3c\u4e0b\u9762\u7ed3\u679c\uff1a kubernetes-admin@kubernetes \u662fContext\u540d\u3002 kubernetes \u662f\u96c6\u7fa4\u540d\u3002 kubernetes-admin \u662f\u7528\u6237\u540d\u3002 \u5f53\u524d\u4f8b\u5b50\u4e2d\u6ca1\u6709\u6307\u5b9a\u540d\u79f0\u7a7a\u95f4\u3002 CURRENT NAME CLUSTER AUTHINFO NAMESPACE * kubernetes-admin@kubernetes kubernetes kubernetes-admin \u66f4\u65b0context\u3002\u4f8b\u5982\uff0c\u66f4\u65b0context\u7684\u9ed8\u8ba4\u540d\u79f0\u7a7a\u95f4\u7b49\u3002 # Usage: kubectl config set-context --cluster = --namespace = --user = # Set default namespace kubectl config set-context kubernetes-admin@kubernetes --cluster = kubernetes --namespace = default --user = kubernetes-admin \u5728\u4e0d\u540c\u7684context\u4e4b\u95f4\u5207\u6362\u3002 # Usage: kubectl config use-context # Switch to new context kubectl config use-context kubernetes-admin@kubernetes \u53c2\u8003\u8d44\u6599\uff1a * kubectl * commandline \u5b89\u88c5Helm \u00b6 Helm \u662f Kubernetes \u7684\u5305\u7ba1\u7406\u5de5\u5177\uff0c\u5b83\u4e0d\u968f Kubernetes \u4e00\u8d77\u63d0\u4f9b\u3002 Helm \u6709\u4e09\u4e2a\u6838\u5fc3\u6982\u5ff5\uff1a Chart\uff08\u56fe\u8868\uff09\u662f Helm \u7684\u8f6f\u4ef6\u5305\uff0c\u5b83\u5305\u542b\u4e86\u5728 Kubernetes \u96c6\u7fa4\u4e2d\u8fd0\u884c\u5e94\u7528\u7a0b\u5e8f\u3001\u5de5\u5177\u6216\u670d\u52a1\u6240\u9700\u7684\u6240\u6709\u8d44\u6e90\u5b9a\u4e49\u3002\u53ef\u4ee5\u5c06\u5176\u89c6\u4e3a Kubernetes \u7684 Homebrew \u516c\u5f0f\u3001Apt dpkg \u6216 Yum RPM \u6587\u4ef6\u7b49\u7b49\u3002 Repository\uff08\u4ed3\u5e93\uff09\u662f\u56fe\u8868\u53ef\u4ee5\u88ab\u6536\u96c6\u548c\u5171\u4eab\u7684\u5730\u65b9\uff0c\u7c7b\u4f3c\u4e8e Perl \u7684 CPAN \u5b58\u50a8\u5e93\u6216 Fedora \u7684\u8f6f\u4ef6\u5305\u6570\u636e\u5e93\uff0c\u4f46\u7528\u4e8e Kubernetes \u8f6f\u4ef6\u5305\u3002 Release\uff08\u53d1\u5e03\uff09\u662f\u5728 Kubernetes \u96c6\u7fa4\u4e2d\u8fd0\u884c\u7684\u56fe\u8868\u5b9e\u4f8b\u3002\u4e00\u4e2a\u56fe\u8868\u901a\u5e38\u53ef\u4ee5\u5728\u540c\u4e00\u96c6\u7fa4\u4e2d\u5b89\u88c5\u591a\u6b21\uff0c\u5e76\u4e14\u6bcf\u6b21\u5b89\u88c5\u90fd\u4f1a\u521b\u5efa\u4e00\u4e2a\u65b0\u7684\u53d1\u5e03\u3002\u4ee5 MySQL \u56fe\u8868\u4e3a\u4f8b\uff0c\u5982\u679c\u60f3\u8981\u5728\u96c6\u7fa4\u4e2d\u8fd0\u884c\u4e24\u4e2a\u6570\u636e\u5e93\uff0c\u5219\u53ef\u4ee5\u5b89\u88c5\u8be5\u56fe\u8868\u4e24\u6b21\uff0c\u6bcf\u6b21\u5b89\u88c5\u90fd\u4f1a\u521b\u5efa\u4e00\u4e2a\u65b0\u7684\u53d1\u5e03\uff0c\u6bcf\u4e2a\u53d1\u5e03\u90fd\u6709\u81ea\u5df1\u7684\u53d1\u5e03\u540d\u79f0\u3002 \u53c2\u8003\u6587\u6863\uff1a installation guide binary release source code . Helm\u5ba2\u6237\u7aef\u5b89\u88c5\uff1a curl -fsSL -o get_helm.sh https://raw.githubusercontent.com/helm/helm/main/scripts/get-helm-3 chmod 700 get_helm.sh ./get_helm.sh \u8fd0\u884c\u7ed3\u679c\uff1a Downloading https://get.helm.sh/helm-v3.9.1-linux-amd64.tar.gz Verifying checksum... Done. Preparing to install helm into /usr/local/bin helm installed into /usr/local/bin/helm \u63d0\u793a\uff1a * helm init \u5728Helm 3\u4e2d\u5df2\u53d6\u6d88\uff0c\u4e14Tiller\u4e5f\u4e00\u540c\u53d6\u6d88\u3002\u4eca\u540e\u5728\u96c6\u7fa4\u4e2d\u4f7f\u7528Helm\u65f6\u4e0d\u518d\u9700\u8981\u5b89\u88c5Tiller\u3002 * helm search \u53ef\u4ee5\u7528\u6765\u641c\u7d22\u4e24\u79cd\u4e0d\u540c\u7c7b\u578b\u7684\u8d44\u6e90\uff1a * helm search hub \u5728 Artifact Hub \u4e2d\u641c\u7d22\uff0c\u8fd9\u4e2ahub\u91cc\u5217\u51fa\u6765\u81ea\u6570\u5341\u4e2a\u4e0d\u540c\u4ed3\u5e93\u7684 Helm Chart\u3002 * helm search repo \u547d\u4ee4\u7528\u4e8e\u641c\u7d22\u5df2\u6dfb\u52a0\u5230\u672c\u5730 Helm \u5ba2\u6237\u7aef\u7684\u4ed3\u5e93\uff08\u4f7f\u7528 helm repo add \u547d\u4ee4\uff09\u3002\u6b64\u641c\u7d22\u662f\u5728\u672c\u5730\u6570\u636e\u4e0a\u8fdb\u884c\u7684\uff0c\u4e0d\u9700\u8981\u516c\u5171\u7f51\u7edc\u8fde\u63a5\u3002 \u53c2\u8003\u8d44\u6599\uff1a Helming development \u91cd\u7f6e\u96c6\u7fa4 \u00b6 \u6ce8\u610f\uff1a\u4e0b\u9762\u7684\u64cd\u4f5c\u4f1a\u91cd\u7f6e\u5f53\u524d\u96c6\u7fa4\uff08\u5220\u9664\u96c6\u7fa4\uff09\u3002 \u5220\u9664\u96c6\u7fa4\u4e2d\u6240\u6709\u8282\u70b9\u3002 kubeadm reset \u6e05\u9664 iptables \u4e2d\u5df2\u5b9a\u4e49\u7684\u89c4\u5219\u3002 iptables -F && iptables -t nat -F && iptables -t mangle -F && iptables -X \u6e05\u9664 IPVS \u4e2d\u5b9a\u4e49\u7684\u89c4\u5219\uff08\u5982\u679c\u4f7f\u7528 IPVS \uff09\u3002 ipvsadm --clear","title":"\u591a\u8282\u70b9\u865a\u62df\u673a\u5b89\u88c5Kubernetes"},{"location":"k8s/cka_cn/installation/multiple-local/#cka2kubernetes","text":"","title":"CKA\u81ea\u5b66\u7b14\u8bb02:\u591a\u8282\u70b9\u865a\u62df\u673a\u5b89\u88c5Kubernetes"},{"location":"k8s/cka_cn/installation/multiple-local/#_1","text":"\u5728\u672c\u5730Windows\u73af\u5883\u4e2d\uff0c\u901a\u8fc7VMWare\u5b89\u88c5\u4e09\u53f0Ubuntu\u865a\u62df\u673a\u3002\u5728Ubuntu\u865a\u62df\u673a\u4e2d\u5b89\u88c5\u57fa\u4e8eContainerd\u7684Kubernetes\u7cfb\u7edf\uff0c\u5e76\u5206\u522b\u914d\u7f6e\u4e00\u4e2a\u4e3b\u8282\u70b9Master\u548c\u4e24\u4e2a\u5de5\u4f5c\u8282\u70b9Worker\u3002","title":"\u6458\u8981"},{"location":"k8s/cka_cn/installation/multiple-local/#_2","text":"VMWare \u8bbe\u7f6e VMnet1: host-only\u6a21\u5f0f, \u7f51\u7edcsubnet: 192.168.150.0/24 VMnet8: NAT\u6a21\u5f0f, \u7f51\u7edcsubnet: 11.0.1.0/24 \u901a\u8fc7VMWare\u521b\u5efa\u5ba2\u6237\u865a\u62df\u673a\u3002 \u5185\u5b58\uff1a4 GB CPU\uff1a1 CPUs with 2 Cores \u64cd\u4f5c\u7cfb\u7edf\uff1aUbuntu Server 22.04 \u7f51\u7edc\uff1aNAT \u63d0\u793a\uff1a \u5f53\u524d\u7ec3\u4e60\u4e2d\uff0cKubernetes\u662f\u57fa\u4e8eContainerd\uff0c\u4e0d\u662fDocker\u3002","title":"\u672c\u5730\u865a\u62df\u673a\u8bbe\u7f6e"},{"location":"k8s/cka_cn/installation/multiple-local/#ubuntu","text":"\u6ce8\u610f\uff1a\u4e0b\u9762\u7684\u4efb\u52a1\uff0c\u9700\u8981\u5728\u6bcf\u53f0\u865a\u62df\u673a\u4e2d\u6267\u884c\u4e00\u6b21\u3002\u4ee5\u4e0b\u7b80\u79f0\u865a\u62df\u673a\u4e3a\u8282\u70b9\u3002 \u5728\u6240\u6709\u8282\u70b9\u4e2d\u521b\u5efa\u7528\u6237 vagrant \u3002 sudo adduser vagrant sudo usermod -g sudo vagrant sudo usermod -a -G root vagrant sudo passwd vagrant \u5728\u6240\u6709\u8282\u70b9\u4e2d\u8bbe\u7f6e\u7528\u6237 root \u7684\u5bc6\u7801\u3002 sudo passwd root \u4fee\u6539ssh\u670d\u52a1\u7684\u914d\u7f6e\u6587\u4ef6\u3002\u5f00\u653e root \u7528\u6237\u901a\u8fc7ssh\u767b\u5f55\uff08\u9ed8\u8ba4\u662f\u7981\u7528\u7684\uff09\u3002 sudo vi /etc/ssh/sshd_config \u628a\u53c2\u6570 PermitRootLogin \u7684\u503c\u4ece prohibit-password \u6539\u4e3a yes \u3002 PermitRootLogin yes # PermitRootLogin prohibit-password \u91cd\u65b0\u542f\u52a8sshd\u670d\u52a1\u3002 sudo systemctl restart sshd \u66f4\u6539\u4e3b\u673a\u540d\uff0c\u8fd9\u91cc\u662f ubu1 . sudo hostnamectl set-hostname ubu1 sudo hostnamectl set-hostname ubu1 --pretty \u9a8c\u8bc1\u4e3b\u673a\u540d\u662f\u5426\u88ab\u6b63\u786e\u4fee\u6539\u4e86\uff0c\u6bd4\u5982\u6539\u4e3a ubu1 \u3002 cat /etc/machine-info \u9a8c\u8bc1\u4e3b\u673a\u540d\u662f\u5426\u88ab\u6b63\u786e\u4fee\u6539\u4e86\uff0c\u6bd4\u5982\u6539\u4e3a ubu1 \u3002 cat /etc/hostname \u9a8c\u8bc1\u4e3b\u673aIP\u5730\u5740 127.0.1.1 \u5df2\u7ecf\u914d\u7f6e\u7ed9\u5f53\u524d\u8282\u70b9\uff0c\u6bd4\u5982 ubu1 \u3002\u540c\u65f6\uff0c\u5728\u6240\u6709\u8282\u70b9\u7684 /etc/hosts \u6587\u4ef6\u4e2d\u6dfb\u52a0\u5176\u4ed6\u8282\u70b9\u7684IP\u548c\u4e3b\u673a\u5bf9\u5e94\u4fe1\u606f\u3002 sudo vi /etc/hosts \u4ee5\u5f53\u524d\u7ec3\u4e60\u4e3a\u4f8b\uff0c\u4fee\u6539\u540e\u7684 /etc/hosts \u6587\u4ef6\u7c7b\u4f3c\u5982\u4e0b\u5185\u5bb9\u3002 127.0.1.1 ubu1 11.0.1.129 ubu1 11.0.1.130 ubu2 11.0.1.131 ubu3 11.0.1.132 ubu4 \u521b\u5efa\u6587\u4ef6 /etc/netplan/00-installer-config.yaml \u3002 sudo vi /etc/netplan/00-installer-config.yaml \u66f4\u65b0\u6b64\u6587\u4ef6\uff0c\u8bbe\u5b9a\u5f53\u524d\u8282\u70b9\u4f7f\u7528\u56fa\u5b9aIP\u5730\u5740\uff0c\u6bd4\u5982\uff0c 11.0.1.129 \u3002 network : ethernets : ens33 : dhcp4 : false addresses : - 11.0.1.129/24 nameservers : addresses : - 11.0.1.2 routes : - to : default via : 11.0.1.2 version : 2 \u6267\u884c\u4e0b\u9762\u547d\u4ee4\u65f6\uff0c\u4f7f\u4e0a\u8ff0\u6539\u52a8\u751f\u6548\u3002\u6ce8\u610f\uff0c\u5f53\u524dssh\u8fde\u63a5\u4f1a\u56e0\u6b64\u800c\u65ad\u5f00\u3002 sudo netplan apply \u5728\u6240\u6709\u8282\u70b9\u7981\u7528\u4ea4\u6362\u5206\u533aswap\u548c\u9632\u706b\u5899firewall\u3002 sudo swapoff -a sudo ufw disable sudo ufw status verbose \u5728\u6240\u6709\u8282\u70b9\u7684\u6587\u4ef6 /etc/fstab \u4e2d\u6ce8\u91ca\u6389\u6d89\u53caswap\u7684\u90a3\u4e00\u884c\uff0c\u4fee\u6539\u540e\u9700\u8981\u91cd\u542f\u5f53\u524d\u8282\u70b9\u3002 sudo vi /etc/fstab \u4fee\u6539\u540e\u7684\u7ed3\u679c\u7c7b\u4f3c\u5982\u4e0b\u3002 /dev/disk/by-uuid/df370d2a-83e5-4895-8c7f-633f2545e3fe / ext4 defaults 0 1 # /swap.img none swap sw 0 0 \u5728\u6240\u6709\u8282\u70b9\u8bbe\u7f6e\u7edf\u4e00\u7684\u65f6\u533a\u3002 sudo ln -sf /usr/share/zoneinfo/Asia/Shanghai /etc/localtime sudo cp /etc/profile /etc/profile.bak echo 'LANG=\"en_US.UTF-8\"' | sudo tee -a /etc/profile source /etc/profile \u6267\u884c\u547d\u4ee4 ll /etc/localtime \u6765\u9a8c\u8bc1\u65f6\u533a\u662f\u5426\u4fee\u6539\u6b63\u786e\u3002 lrwxrwxrwx 1 root root 33 Jul 15 22:00 /etc/localtime -> /usr/share/zoneinfo/Asia/Shanghai \u5728\u6240\u6709\u8282\u70b9\u4fee\u6539\u5185\u6838\u8bbe\u7f6e\u3002 cat < /etc/apt/sources.list.d/kubernetes.list deb https://mirrors.aliyun.com/kubernetes/apt/ kubernetes-xenial main EOF \u68c0\u67e5\u5f53\u524d kubeadm \u7684\u7248\u672c\u3002 apt policy kubeadm \u5b89\u88c5 1.24.1-00 \u7248\u672c\u7684 kubeadm . sudo apt-get -y install kubelet = 1 .24.1-00 kubeadm = 1 .24.1-00 kubectl = 1 .24.1-00 --allow-downgrades","title":"\u5b89\u88c5Kubernetes"},{"location":"k8s/cka_cn/installation/multiple-local/#_3","text":"","title":"\u914d\u7f6e\u4e3b\u8282\u70b9"},{"location":"k8s/cka_cn/installation/multiple-local/#kubeadm","text":"\u5728\u627f\u62c5\u4e3b\u8282\u70b9\u7684\u865a\u62df\u673a\u91cc\u914d\u7f6e\u63a7\u5236\u5e73\u9762\uff08Control Plane\uff09\u3002 \u68c0\u67e5 kubeadm \u5f53\u524d\u9ed8\u8ba4\u914d\u7f6e\u53c2\u6570\u3002 kubeadm config print init-defaults \u7c7b\u4f3c\u7ed3\u679c\u5982\u4e0b\u3002\u4fdd\u5b58\u9ed8\u8ba4\u914d\u7f6e\u7684\u7ed3\u679c\uff0c\u540e\u7eed\u4f1a\u4f5c\u4e3a\u53c2\u8003\u3002 apiVersion : kubeadm.k8s.io/v1beta3 bootstrapTokens : - groups : - system:bootstrappers:kubeadm:default-node-token token : abcdef.0123456789abcdef ttl : 24h0m0s usages : - signing - authentication kind : InitConfiguration localAPIEndpoint : advertiseAddress : 1.2.3.4 bindPort : 6443 nodeRegistration : criSocket : unix:///var/run/containerd/containerd.sock imagePullPolicy : IfNotPresent name : node taints : null --- apiServer : timeoutForControlPlane : 4m0s apiVersion : kubeadm.k8s.io/v1beta3 certificatesDir : /etc/kubernetes/pki clusterName : kubernetes controllerManager : {} dns : {} etcd : local : dataDir : /var/lib/etcd imageRepository : k8s.gcr.io kind : ClusterConfiguration kubernetesVersion : 1.24.0 networking : dnsDomain : cluster.local serviceSubnet : 10.96.0.0/12 scheduler : {} \u6a21\u62df\u5b89\u88c5\u548c\u6b63\u5f0f\u5b89\u88c5\u3002 \u901a\u8fc7\u547d\u4ee4 kubeadm init \u8fdb\u884c\u4e3b\u8282\u70b9\u7684\u521d\u59cb\u5316\uff0c\u4e0b\u9762\u662f\u8fd9\u4e2a\u547d\u4ee4\u4e3b\u8981\u53c2\u6570\u7684\u8bf4\u660e\uff0c\u7279\u522b\u662f\u7f51\u7edc\u53c2\u6570\u7684\u4e09\u4e2a\u9009\u62e9\u3002 --pod-network-cidr : \u6307\u5b9apod\u4f7f\u7528\u7684IP\u5730\u5740\u8303\u56f4\u3002\u5982\u679c\u6307\u5b9a\u4e86\u8be5\u53c2\u6570\uff0c\u5219Control Plane\u4f1a\u81ea\u52a8\u8bb2\u6307\u5b9a\u7684CIDR\u5206\u914d\u7ed9\u6bcf\u4e2a\u8282\u70b9\u3002 IP\u5730\u5740\u6bb5 10.244.0.0/16 \u662fFlannel\u7f51\u7edc\u7ec4\u4ef6\u9ed8\u8ba4\u7684\u5730\u5740\u8303\u56f4\u3002\u5982\u679c\u9700\u8981\u4fee\u6539Flannel\u7684IP\u5730\u5740\u6bb5\uff0c\u9700\u8981\u5728\u8fd9\u91cc\u6307\u5b9a\uff0c\u4e14\u5728\u90e8\u7f72Flannel\u65f6\u4e5f\u8981\u4fdd\u6301\u4e00\u81f4\u7684IP\u6bb5\u3002 --apiserver-bind-port : API\u670d\u52a1\uff08API Server\uff09\u7684\u7aef\u53e3\uff0c\u9ed8\u8ba4\u65f66443\u3002 --service-cidr : \u6307\u5b9a\u670d\u52a1\uff08service\uff09\u7684IP\u5730\u5740\u6bb5\uff0c\u9ed8\u8ba4\u662f 10.96.0.0/12 \u3002 \u63d0\u793a\uff1a \u670d\u52a1VIPs\uff08service VIPs\uff09\uff0c\u4e5f\u79f0\u4f5c\u96c6\u7fa4IP\uff08Cluster IP\uff09\uff0c\u901a\u8fc7\u53c2\u6570 --service-cidr \u6307\u5b9a\u3002 podCIDR\uff0c\u4e5f\u79f0\u4e3aendpoint IP\uff0c\u901a\u8fc7\u53c2\u6570 --pod-network-cidr \u6307\u5b9a\u3002 \u67094\u79cd\u5178\u578b\u7684\u7f51\u7edc\u95ee\u9898\uff1a \u9ad8\u5ea6\u8026\u5408\u7684\u5bb9\u5668\u4e0e\u5bb9\u5668\u4e4b\u95f4\u7684\u901a\u4fe1\uff1a\u8fd9\u53ef\u4ee5\u901a\u8fc7Pod\uff08podCIDR\uff09\u548c\u672c\u5730\u4e3b\u673a\u901a\u4fe1\u6765\u89e3\u51b3\u3002 Pod\u5bf9Pod\u901a\u4fe1\uff08Pod-to-Pod\uff09\uff1a \u4e5f\u88ab\u79f0\u4e3a\u5bb9\u5668\u5bf9\u5bb9\u5668\u901a\u4fe1\uff08container-to-container\uff09\u3002 \u5728Flannel\u7f51\u7edc\u63d2\u4ef6\u4e2d\u7684\u793a\u4f8b\u6d41\u7a0b\u662f\uff1aPod \u2192 veth\u5bf9 \u2192 cni0 \u2192 flannel.1 \u2192 \u5bbf\u4e3b\u673aeth0 \u2192 \u5bbf\u4e3b\u673aeth0 \u2192 flannel.1 \u2192 cni0 \u2192 veth\u5bf9 \u2192 Pod\u3002 Pod\u5bf9Service\u901a\u4fe1\uff08Pod-to-Service\uff09\uff1a \u6d41\u7a0b: Pod \u2192 \u5185\u6838 \u2192 Service iptables \u2192 Service \u2192 Pod iptables \u2192 Pod\u3002 \u5916\u90e8\u5bf9Service\u901a\u4fe1\uff08External-to-Service\uff09\uff1a \u8d1f\u8f7d\u5747\u8861\u5668: SLB \u2192 NodePort \u2192 Service \u2192 Pod\u3002 kube-proxy \u662f\u5bf9iptables\u8d1f\u8d23\uff0c\u4e0d\u662f\u7f51\u7edc\u6d41\u91cf\uff08traffic\uff09\u3002 kube-proxy \u662fKubernetes\u96c6\u7fa4\u4e2d\u7684\u4e00\u4e2a\u7ec4\u4ef6\uff0c\u8d1f\u8d23\u4e3aService\u63d0\u4f9b\u4ee3\u7406\u670d\u52a1\uff0c\u540c\u65f6\u4e5f\u662fKubernetes\u7f51\u7edc\u6a21\u578b\u4e2d\u7684\u91cd\u8981\u7ec4\u6210\u90e8\u5206\u4e4b\u4e00\u3002 kube-proxy \u4f1a\u5728\u6bcf\u4e2a\u8282\u70b9\u4e0a\u542f\u52a8\u4e00\u4e2a\u4ee3\u7406\u8fdb\u7a0b\uff0c\u901a\u8fc7\u76d1\u542cKubernetes API Server\u7684Service\u548cEndpoint\u7684\u53d8\u5316\u6765\u7ef4\u62a4\u4e00\u4e2a\u672c\u5730\u7684Service\u548cEndpoint\u7684\u7f13\u5b58\u3002\u5f53\u6709\u8bf7\u6c42\u5230\u8fbe\u67d0\u4e2aService\u65f6\uff0c kube-proxy \u4f1a\u6839\u636e\u8be5Service\u7684\u7c7b\u578b\uff08ClusterIP\u3001NodePort\u3001LoadBalancer\u3001ExternalName\uff09\u548c\u7aef\u53e3\u53f7\uff0c\u751f\u6210\u76f8\u5e94\u7684iptables\u89c4\u5219\uff0c\u5c06\u8bf7\u6c42\u8f6c\u53d1\u7ed9Service\u6240\u4ee3\u7406\u7684\u540e\u7aefPod\u3002 iptables\u662fLinux\u7cfb\u7edf\u4e2d\u7684\u4e00\u4e2a\u91cd\u8981\u7f51\u7edc\u5de5\u5177\uff0c\u53ef\u4ee5\u8bbe\u7f6eIP\u5305\u7684\u8fc7\u6ee4\u3001\u8f6c\u53d1\u548c\u4fee\u6539\u89c4\u5219\uff0c\u53ef\u4ee5\u5b9e\u73b0\u7f51\u7edc\u5c42\u7684\u9632\u706b\u5899\u3001NAT\u7b49\u529f\u80fd\u3002\u5728Kubernetes\u96c6\u7fa4\u4e2d\uff0c kube-proxy \u901a\u8fc7\u751f\u6210\u548c\u66f4\u65b0iptables\u89c4\u5219\uff0c\u6765\u5b9e\u73b0Service\u548cEndpoint\u4e4b\u95f4\u7684\u8f6c\u53d1\u548c\u4ee3\u7406\u3002\u5177\u4f53\u6765\u8bf4\uff0ckube-proxy\u4f1a\u4e3a\u6bcf\u4e2aService\u521b\u5efa\u4e09\u6761iptables\u89c4\u5219\u94fe\uff08nat\u8868\u4e2d\u7684KUBE-SERVICES\u548cKUBE-NODEPORTS\u94fe\uff0c\u4ee5\u53cafilter\u8868\u4e2d\u7684KUBE-SVC-XXXXX\u94fe\uff09\uff0c\u901a\u8fc7\u8fd9\u4e9b\u89c4\u5219\u94fe\uff0c\u5c06\u8bf7\u6c42\u8f6c\u53d1\u5230\u76f8\u5e94\u7684Pod\u6216\u8005Service\u4e0a\u3002 \u56e0\u6b64\uff0c kube-proxy \u548ciptables\u662f\u7d27\u5bc6\u76f8\u5173\u7684\u4e24\u4e2a\u7ec4\u4ef6\uff0c\u901a\u8fc7iptables\u89c4\u5219\u6765\u5b9e\u73b0Service\u548cPod\u4e4b\u95f4\u7684\u8f6c\u53d1\u548c\u4ee3\u7406\u3002\u8fd9\u79cd\u5b9e\u73b0\u65b9\u5f0f\u5177\u6709\u53ef\u6269\u5c55\u6027\u548c\u9ad8\u53ef\u7528\u6027\uff0c\u540c\u65f6\u4e5f\u63d0\u4f9b\u4e86\u4e00\u79cd\u7075\u6d3b\u7684\u7f51\u7edc\u6a21\u578b\uff0c\u53ef\u4ee5\u65b9\u4fbf\u5730\u5b9e\u73b0\u670d\u52a1\u53d1\u73b0\u3001\u8d1f\u8f7d\u5747\u8861\u7b49\u529f\u80fd\u3002 sudo kubeadm init \\ --dry-run \\ --pod-network-cidr = 10 .244.0.0/16 \\ --service-cidr = 192 .244.0.0/16 \\ --image-repository = registry.aliyuncs.com/google_containers \\ --kubernetes-version = v1.24.0 sudo kubeadm init \\ --pod-network-cidr = 10 .244.0.0/16 \\ --service-cidr = 192 .244.0.0/16 \\ --image-repository = registry.aliyuncs.com/google_containers \\ --kubernetes-version = v1.24.0","title":"kubeadm\u521d\u59cb\u5316"},{"location":"k8s/cka_cn/installation/multiple-local/#kubeconfig","text":"\u7ed9\u5f53\u524d\u5b89\u88c5\u7528\u6237\u914d\u7f6e kubeconfig \u6587\u4ef6\uff08\u5f53\u524d\u4f8b\u5b50\u662f\u7528\u6237 vagrant \uff09\u3002 mkdir -p $HOME /.kube sudo cp -i /etc/kubernetes/admin.conf $HOME /.kube/config sudo chown $( id -u ) : $( id -g ) $HOME /.kube/config Kubernetes \u63d0\u4f9b\u4e86\u4e00\u4e2a\u547d\u4ee4\u884c\u5de5\u5177 kubectl \uff0c\u7528\u4e8e\u4f7f\u7528 Kubernetes API \u4e0e Kubernetes \u96c6\u7fa4\u7684\u63a7\u5236\u5e73\u9762\u8fdb\u884c\u901a\u4fe1\u3002 kubectl \u63a7\u5236 Kubernetes cluster manager \uff08\u96c6\u7fa4\u7ba1\u7406\u5668\uff09\u3002 \u5bf9\u4e8e\u914d\u7f6e\uff0ckubectl \u5728 $HOME/.kube \u76ee\u5f55\u4e2d\u67e5\u627e\u4e00\u4e2a\u540d\u4e3a config \u7684\u6587\u4ef6\uff0c\u8be5\u6587\u4ef6\u662f\u7531 kubeadm init \u751f\u6210\u7684\u6587\u4ef6 /etc/kubernetes/admin.conf \u7684\u526f\u672c\u3002 \u6211\u4eec\u53ef\u4ee5\u901a\u8fc7\u8bbe\u7f6e KUBECONFIG \u73af\u5883\u53d8\u91cf\u6216\u8bbe\u7f6e --kubeconfig flag \u6807\u5fd7\u6765\u6307\u5b9a\u5176\u4ed6 kubeconfig \u6587\u4ef6\u3002\u5982\u679c KUBECONFIG \u73af\u5883\u53d8\u91cf\u4e0d\u5b58\u5728\uff0ckubectl \u5c06\u4f7f\u7528\u9ed8\u8ba4\u7684 kubeconfig \u6587\u4ef6 $HOME/.kube/config \u3002 kubeconfig \u6587\u4ef6\u4e2d\u7684 context\uff08\u4e0a\u4e0b\u6587\uff09 \u5143\u7d20\u7528\u4e8e\u5c06\u8bbf\u95ee\u53c2\u6570\u5206\u7ec4\u5230\u4e00\u4e2a\u65b9\u4fbf\u7684\u540d\u79f0\u4e0b\u3002\u6bcf\u4e2a\u4e0a\u4e0b\u6587\u90fd\u6709\u4e09\u4e2a\u53c2\u6570\uff1a\u96c6\u7fa4\u3001\u547d\u540d\u7a7a\u95f4\u548c\u7528\u6237\u3002\u9ed8\u8ba4\u60c5\u51b5\u4e0b\uff0ckubectl \u547d\u4ee4\u884c\u5de5\u5177\u4f7f\u7528\u5f53\u524d\u4e0a\u4e0b\u6587\u4e2d\u7684\u53c2\u6570\u4e0e\u96c6\u7fa4\u901a\u4fe1\u3002 \u6587\u4ef6 .kube/config \u7684\u4f8b\u5b50\uff1a apiVersion : v1 clusters : - cluster : certificate-authority-data : server : https://:6443 name : contexts : - context : cluster : namespace : user : name : @ current-context : kind : Config preferences : {} users : - name : user : client-certificate-data : client-key-data : \u8bfb\u53d6\u5f53\u524d\u4e0a\u4e0b\u6587\uff1a kubectl config get-contexts \u8fd0\u884c\u7ed3\u679c\uff1a CURRENT NAME CLUSTER AUTHINFO NAMESPACE * kubernetes-admin@kubernetes kubernetes kubernetes-admin","title":"kubeconfig\u6587\u4ef6"},{"location":"k8s/cka_cn/installation/multiple-local/#calico","text":"\u53c2\u8003\u5b89\u88c5\u6307\u5bfc End-to-end Calico installation \u3002 \u5feb\u901f\u5b89\u88c5\u624b\u518c QuickStart \u5b89\u88c5 Calico\uff1a kubectl create -f https://raw.githubusercontent.com/projectcalico/calico/v3.25.1/manifests/tigera-operator.yaml \u8fd0\u884c\u7ed3\u679c\uff1a namespace/tigera-operator created customresourcedefinition.apiextensions.k8s.io/bgpconfigurations.crd.projectcalico.org created customresourcedefinition.apiextensions.k8s.io/bgppeers.crd.projectcalico.org created customresourcedefinition.apiextensions.k8s.io/blockaffinities.crd.projectcalico.org created customresourcedefinition.apiextensions.k8s.io/caliconodestatuses.crd.projectcalico.org created customresourcedefinition.apiextensions.k8s.io/clusterinformations.crd.projectcalico.org created customresourcedefinition.apiextensions.k8s.io/felixconfigurations.crd.projectcalico.org created customresourcedefinition.apiextensions.k8s.io/globalnetworkpolicies.crd.projectcalico.org created customresourcedefinition.apiextensions.k8s.io/globalnetworksets.crd.projectcalico.org created customresourcedefinition.apiextensions.k8s.io/hostendpoints.crd.projectcalico.org created customresourcedefinition.apiextensions.k8s.io/ipamblocks.crd.projectcalico.org created customresourcedefinition.apiextensions.k8s.io/ipamconfigs.crd.projectcalico.org created customresourcedefinition.apiextensions.k8s.io/ipamhandles.crd.projectcalico.org created customresourcedefinition.apiextensions.k8s.io/ippools.crd.projectcalico.org created customresourcedefinition.apiextensions.k8s.io/ipreservations.crd.projectcalico.org created customresourcedefinition.apiextensions.k8s.io/kubecontrollersconfigurations.crd.projectcalico.org created customresourcedefinition.apiextensions.k8s.io/networkpolicies.crd.projectcalico.org created customresourcedefinition.apiextensions.k8s.io/networksets.crd.projectcalico.org created customresourcedefinition.apiextensions.k8s.io/apiservers.operator.tigera.io created customresourcedefinition.apiextensions.k8s.io/imagesets.operator.tigera.io created customresourcedefinition.apiextensions.k8s.io/installations.operator.tigera.io created customresourcedefinition.apiextensions.k8s.io/tigerastatuses.operator.tigera.io created serviceaccount/tigera-operator created clusterrole.rbac.authorization.k8s.io/tigera-operator created clusterrolebinding.rbac.authorization.k8s.io/tigera-operator created deployment.apps/tigera-operator created kubectl apply -f https://raw.githubusercontent.com/projectcalico/calico/v3.25.1/manifests/calicoctl.yaml \u8fd0\u884c\u7ed3\u679c\uff1a serviceaccount/calicoctl created pod/calicoctl created clusterrole.rbac.authorization.k8s.io/calicoctl created clusterrolebinding.rbac.authorization.k8s.io/calicoctl created \u9a8c\u8bc1Calico\u7684\u72b6\u6001\u3002Calico\u7684\u521d\u59cb\u5316\u8fc7\u7a0b\u53ef\u80fd\u9700\u8981\u51e0\u5206\u949f\u65f6\u95f4\u5b8c\u6210\u3002 kubectl get pod -n kube-system | grep calico \u8fd0\u884c\u7ed3\u679c\uff1a calico-kube-controllers-555bc4b957-l8bn2 0/1 Pending 0 28s calico-node-255pc 0/1 Init:1/3 0 29s calico-node-7tmnb 0/1 Init:1/3 0 29s calico-node-w8nvl 0/1 Init:1/3 0 29s \u9a8c\u8bc1\u7f51\u7edc\u72b6\u6001\u3002 sudo nerdctl network ls \u8fd0\u884c\u7ed3\u679c\uff1a NETWORK ID NAME FILE k8s-pod-network /etc/cni/net.d/10-calico.conflist 17f29b073143 bridge /etc/cni/net.d/nerdctl-bridge.conflist host none","title":"\u5b89\u88c5Calico"},{"location":"k8s/cka_cn/installation/multiple-local/#_4","text":"\u4f7f\u7528 kubeadm token \u6765\u751f\u6210\u52a0\u5165\u96c6\u7fa4\u7684\u4ee4\u724c\uff08token\uff09\u548c\u54c8\u897f\u503c\uff08hash value\uff09\u3002 kubeadm token create --print-join-command \u547d\u4ee4\u7528\u6cd5\uff1a sudo kubeadm join :6443 --token --discovery-token-ca-cert-hash < hash key generated by kubeadm init> \u8fd0\u884c\u7ed3\u679c\uff1a [preflight] Running pre-flight checks [WARNING SystemVerification]: missing optional cgroups: blkio [preflight] Reading configuration from the cluster... [preflight] FYI: You can look at this config file with 'kubectl -n kube-system get cm kubeadm-config -o yaml' [kubelet-start] Writing kubelet configuration to file \"/var/lib/kubelet/config.yaml\" [kubelet-start] Writing kubelet environment file with flags to file \"/var/lib/kubelet/kubeadm-flags.env\" [kubelet-start] Starting the kubelet [kubelet-start] Waiting for the kubelet to perform the TLS Bootstrap... This node has joined the cluster: * Certificate signing request was sent to apiserver and a response was received. * The Kubelet was informed of the new secure connection details. Run 'kubectl get nodes' on the control-plane to see this node join the cluster.","title":"\u914d\u7f6e\u5de5\u4f5c\u8282\u70b9"},{"location":"k8s/cka_cn/installation/multiple-local/#_5","text":"\u67e5\u770b Kubernetes \u96c6\u7fa4\u7684\u4fe1\u606f\uff0c\u5305\u62ec\u96c6\u7fa4 API Server \u7684\u5730\u5740\u3001Kubernetes DNS \u670d\u52a1\u7684\u5730\u5740\u7b49\u3002 kubectl cluster-info \u8fd0\u884c\u7ed3\u679c\uff1a bKubernetes control plane is running at https://11.0.1.129:6443 CoreDNS is running at https://11.0.1.129:6443/api/v1/namespaces/kube-system/services/kube-dns:dns/proxy To further debug and diagnose cluster problems, use 'kubectl cluster-info dump'. \u5217\u51fa\u96c6\u7fa4\u4e2d\u6240\u6709\u8282\u70b9\u7684\u8be6\u7ec6\u4fe1\u606f\uff0c\u5305\u62ec\u8282\u70b9\u540d\u79f0\u3001\u8282\u70b9 IP\u3001\u8282\u70b9\u6807\u7b7e\u3001\u8282\u70b9\u72b6\u6001\u7b49\u3002 kubectl get nodes -owide \u5217\u51fa Kubernetes \u96c6\u7fa4\u4e2d\u6240\u6709 Namespace \u4e0b\u7684 Pod\u3002 kubectl get pod -A","title":"\u68c0\u67e5\u96c6\u7fa4\u72b6\u6001"},{"location":"k8s/cka_cn/installation/multiple-local/#_6","text":"","title":"\u66f4\u65b0\u5b89\u88c5"},{"location":"k8s/cka_cn/installation/multiple-local/#bash","text":"\u5728\u6bcf\u4e2a\u8282\u70b9\u4e0a\u914d\u7f6eBash\u81ea\u52a8\u8865\u5168\u529f\u80fd\u3002 \u53c2\u8003 \u6307\u5bfc \u8bbe\u7f6e kubectl \u81ea\u52a8\u8865\u5168\u529f\u80fdauto-completion \u3002 apt install -y bash-completion source /usr/share/bash-completion/bash_completion source < ( kubectl completion bash ) echo \"source <(kubectl completion bash)\" >> ~/.bashrc source ~/.bashrc","title":"Bash\u81ea\u52a8\u8865\u5168"},{"location":"k8s/cka_cn/installation/multiple-local/#_7","text":"\u5982\u679c\u6211\u4eec\u4e3a kubectl \u8bbe\u7f6e\u4e00\u4e2a\u522b\u540d\uff0c\u6211\u4eec\u53ef\u4ee5\u901a\u8fc7\u4e00\u4e9b\u65b9\u6cd5\u6765\u6269\u5c55 shell \u81ea\u52a8\u8865\u5168\u529f\u80fd\uff0c\u4f7f\u5176\u80fd\u591f\u4e0e\u8be5\u522b\u540d\u4e00\u8d77\u4f7f\u7528\u3002 \u4e00\u79cd\u65b9\u6cd5\u662f\u5728 Bash shell \u914d\u7f6e\u6587\u4ef6\uff08\u5982 .bashrc \u6216 .bash_profile\uff09\u4e2d\u8bbe\u7f6e\u522b\u540d\uff0c\u5e76\u4e3a\u8be5\u522b\u540d\u6307\u5b9a kubectl \u7684\u5b8c\u6574\u8def\u5f84\u3002\u4f8b\u5982\uff0c\u53ef\u4ee5\u5728 .bashrc \u6587\u4ef6\u4e2d\u6dfb\u52a0\u4ee5\u4e0b\u5185\u5bb9\uff1a alias k = 'path/to/kubectl' \u7136\u540e\uff0c\u53ef\u4ee5\u4f7f\u7528\u4ee5\u4e0b\u547d\u4ee4\u91cd\u65b0\u52a0\u8f7d .bashrc \u6587\u4ef6\uff1a source ~/.bashrc \u63a5\u4e0b\u6765\uff0c\u53ef\u4ee5\u4f7f\u7528 k \u547d\u4ee4\u6765\u4ee3\u66ff kubectl \u547d\u4ee4\uff0c\u5e76\u5728\u5176\u540e\u9762\u6dfb\u52a0\u76f8\u5e94\u7684\u53c2\u6570\u548c\u9009\u9879\u3002\u5f53\u4f7f\u7528\u81ea\u52a8\u8865\u5168\u529f\u80fd\u65f6\uff0cBash shell \u4f1a\u81ea\u52a8\u5c06 k \u522b\u540d\u8f6c\u6362\u4e3a kubectl \u7684\u5b8c\u6574\u8def\u5f84\uff0c\u5e76\u5bf9\u5176\u8fdb\u884c\u81ea\u52a8\u8865\u5168\u3002 \u53e6\u4e00\u79cd\u65b9\u6cd5\u662f\u4f7f\u7528 Bash shell \u5185\u7f6e\u7684 complete \u51fd\u6570\u6765\u4e3a\u522b\u540d\u8bbe\u7f6e\u81ea\u52a8\u8865\u5168\u529f\u80fd\u3002\u4f8b\u5982\uff0c\u53ef\u4ee5\u5728 .bashrc \u6587\u4ef6\u4e2d\u6dfb\u52a0\u4ee5\u4e0b\u5185\u5bb9\uff1a echo 'alias k=kubectl' >>~/.bashrc echo 'complete -o default -F __start_kubectl k' >>~/.bashrc \u8fd9\u5c06\u4e3a\u522b\u540d k \u8bbe\u7f6e\u81ea\u52a8\u8865\u5168\u529f\u80fd\uff0c\u5e76\u5c06\u5176\u4e0e kubectl \u7684\u81ea\u52a8\u8865\u5168\u51fd\u6570 __start_kubectl \u5173\u8054\u8d77\u6765\u3002\u8fd9\u6837\uff0c\u5f53\u7528\u6237\u5728 k \u547d\u4ee4\u540e\u8f93\u5165Tab\u952e\u65f6\uff0cBash shell \u4f1a\u81ea\u52a8\u8c03\u7528 __start_kubectl \u51fd\u6570\uff0c\u5e76\u4e3a\u7528\u6237\u63d0\u4f9b\u76f8\u5e94\u7684\u81ea\u52a8\u8865\u5168\u5efa\u8bae\u3002","title":"\u522b\u540d"},{"location":"k8s/cka_cn/installation/multiple-local/#context","text":"\u67e5\u770b\u5f53\u524d\u7684 context \u5217\u8868\uff1a kubectl config get-contexts \u8fd9\u4e2a\u547d\u4ee4\u4f1a\u5217\u51fa\u6240\u6709\u53ef\u7528\u7684 context \u5217\u8868\uff0c\u5e76\u6807\u8bb0\u51fa\u5f53\u524d\u6b63\u5728\u4f7f\u7528\u7684 context\u3002 \u7c7b\u4f3c\u4e0b\u9762\u7ed3\u679c\uff1a kubernetes-admin@kubernetes \u662fContext\u540d\u3002 kubernetes \u662f\u96c6\u7fa4\u540d\u3002 kubernetes-admin \u662f\u7528\u6237\u540d\u3002 \u5f53\u524d\u4f8b\u5b50\u4e2d\u6ca1\u6709\u6307\u5b9a\u540d\u79f0\u7a7a\u95f4\u3002 CURRENT NAME CLUSTER AUTHINFO NAMESPACE * kubernetes-admin@kubernetes kubernetes kubernetes-admin \u66f4\u65b0context\u3002\u4f8b\u5982\uff0c\u66f4\u65b0context\u7684\u9ed8\u8ba4\u540d\u79f0\u7a7a\u95f4\u7b49\u3002 # Usage: kubectl config set-context --cluster = --namespace = --user = # Set default namespace kubectl config set-context kubernetes-admin@kubernetes --cluster = kubernetes --namespace = default --user = kubernetes-admin \u5728\u4e0d\u540c\u7684context\u4e4b\u95f4\u5207\u6362\u3002 # Usage: kubectl config use-context # Switch to new context kubectl config use-context kubernetes-admin@kubernetes \u53c2\u8003\u8d44\u6599\uff1a * kubectl * commandline","title":"\u66f4\u65b0\u9ed8\u8ba4Context"},{"location":"k8s/cka_cn/installation/multiple-local/#helm","text":"Helm \u662f Kubernetes \u7684\u5305\u7ba1\u7406\u5de5\u5177\uff0c\u5b83\u4e0d\u968f Kubernetes \u4e00\u8d77\u63d0\u4f9b\u3002 Helm \u6709\u4e09\u4e2a\u6838\u5fc3\u6982\u5ff5\uff1a Chart\uff08\u56fe\u8868\uff09\u662f Helm \u7684\u8f6f\u4ef6\u5305\uff0c\u5b83\u5305\u542b\u4e86\u5728 Kubernetes \u96c6\u7fa4\u4e2d\u8fd0\u884c\u5e94\u7528\u7a0b\u5e8f\u3001\u5de5\u5177\u6216\u670d\u52a1\u6240\u9700\u7684\u6240\u6709\u8d44\u6e90\u5b9a\u4e49\u3002\u53ef\u4ee5\u5c06\u5176\u89c6\u4e3a Kubernetes \u7684 Homebrew \u516c\u5f0f\u3001Apt dpkg \u6216 Yum RPM \u6587\u4ef6\u7b49\u7b49\u3002 Repository\uff08\u4ed3\u5e93\uff09\u662f\u56fe\u8868\u53ef\u4ee5\u88ab\u6536\u96c6\u548c\u5171\u4eab\u7684\u5730\u65b9\uff0c\u7c7b\u4f3c\u4e8e Perl \u7684 CPAN \u5b58\u50a8\u5e93\u6216 Fedora \u7684\u8f6f\u4ef6\u5305\u6570\u636e\u5e93\uff0c\u4f46\u7528\u4e8e Kubernetes \u8f6f\u4ef6\u5305\u3002 Release\uff08\u53d1\u5e03\uff09\u662f\u5728 Kubernetes \u96c6\u7fa4\u4e2d\u8fd0\u884c\u7684\u56fe\u8868\u5b9e\u4f8b\u3002\u4e00\u4e2a\u56fe\u8868\u901a\u5e38\u53ef\u4ee5\u5728\u540c\u4e00\u96c6\u7fa4\u4e2d\u5b89\u88c5\u591a\u6b21\uff0c\u5e76\u4e14\u6bcf\u6b21\u5b89\u88c5\u90fd\u4f1a\u521b\u5efa\u4e00\u4e2a\u65b0\u7684\u53d1\u5e03\u3002\u4ee5 MySQL \u56fe\u8868\u4e3a\u4f8b\uff0c\u5982\u679c\u60f3\u8981\u5728\u96c6\u7fa4\u4e2d\u8fd0\u884c\u4e24\u4e2a\u6570\u636e\u5e93\uff0c\u5219\u53ef\u4ee5\u5b89\u88c5\u8be5\u56fe\u8868\u4e24\u6b21\uff0c\u6bcf\u6b21\u5b89\u88c5\u90fd\u4f1a\u521b\u5efa\u4e00\u4e2a\u65b0\u7684\u53d1\u5e03\uff0c\u6bcf\u4e2a\u53d1\u5e03\u90fd\u6709\u81ea\u5df1\u7684\u53d1\u5e03\u540d\u79f0\u3002 \u53c2\u8003\u6587\u6863\uff1a installation guide binary release source code . Helm\u5ba2\u6237\u7aef\u5b89\u88c5\uff1a curl -fsSL -o get_helm.sh https://raw.githubusercontent.com/helm/helm/main/scripts/get-helm-3 chmod 700 get_helm.sh ./get_helm.sh \u8fd0\u884c\u7ed3\u679c\uff1a Downloading https://get.helm.sh/helm-v3.9.1-linux-amd64.tar.gz Verifying checksum... Done. Preparing to install helm into /usr/local/bin helm installed into /usr/local/bin/helm \u63d0\u793a\uff1a * helm init \u5728Helm 3\u4e2d\u5df2\u53d6\u6d88\uff0c\u4e14Tiller\u4e5f\u4e00\u540c\u53d6\u6d88\u3002\u4eca\u540e\u5728\u96c6\u7fa4\u4e2d\u4f7f\u7528Helm\u65f6\u4e0d\u518d\u9700\u8981\u5b89\u88c5Tiller\u3002 * helm search \u53ef\u4ee5\u7528\u6765\u641c\u7d22\u4e24\u79cd\u4e0d\u540c\u7c7b\u578b\u7684\u8d44\u6e90\uff1a * helm search hub \u5728 Artifact Hub \u4e2d\u641c\u7d22\uff0c\u8fd9\u4e2ahub\u91cc\u5217\u51fa\u6765\u81ea\u6570\u5341\u4e2a\u4e0d\u540c\u4ed3\u5e93\u7684 Helm Chart\u3002 * helm search repo \u547d\u4ee4\u7528\u4e8e\u641c\u7d22\u5df2\u6dfb\u52a0\u5230\u672c\u5730 Helm \u5ba2\u6237\u7aef\u7684\u4ed3\u5e93\uff08\u4f7f\u7528 helm repo add \u547d\u4ee4\uff09\u3002\u6b64\u641c\u7d22\u662f\u5728\u672c\u5730\u6570\u636e\u4e0a\u8fdb\u884c\u7684\uff0c\u4e0d\u9700\u8981\u516c\u5171\u7f51\u7edc\u8fde\u63a5\u3002 \u53c2\u8003\u8d44\u6599\uff1a Helming development","title":"\u5b89\u88c5Helm"},{"location":"k8s/cka_cn/installation/multiple-local/#_8","text":"\u6ce8\u610f\uff1a\u4e0b\u9762\u7684\u64cd\u4f5c\u4f1a\u91cd\u7f6e\u5f53\u524d\u96c6\u7fa4\uff08\u5220\u9664\u96c6\u7fa4\uff09\u3002 \u5220\u9664\u96c6\u7fa4\u4e2d\u6240\u6709\u8282\u70b9\u3002 kubeadm reset \u6e05\u9664 iptables \u4e2d\u5df2\u5b9a\u4e49\u7684\u89c4\u5219\u3002 iptables -F && iptables -t nat -F && iptables -t mangle -F && iptables -X \u6e05\u9664 IPVS \u4e2d\u5b9a\u4e49\u7684\u89c4\u5219\uff08\u5982\u679c\u4f7f\u7528 IPVS \uff09\u3002 ipvsadm --clear","title":"\u91cd\u7f6e\u96c6\u7fa4"},{"location":"k8s/cka_cn/installation/single-local/","text":"CKA\u81ea\u5b66\u7b14\u8bb01:\u5355\u8282\u70b9\u865a\u62df\u673a\u5b89\u88c5Kubernetes \u00b6 \u6458\u8981 \u00b6 \u5728\u672c\u5730Windows\u73af\u5883\u4e2d\uff0c\u901a\u8fc7VMWare\u5b89\u88c5Ubuntu\u865a\u62df\u673a\u3002\u5728Ubuntu\u865a\u62df\u673a\u4e2d\u5b89\u88c5\u57fa\u4e8eDocker\u7684Kubernetes\u7cfb\u7edf\u3002\u5728\u8be5\u865a\u62df\u673a\u4e2d\u540c\u65f6\u914d\u7f6e\u4e3b\u8282\u70b9Master\u548c\u5de5\u4f5c\u8282\u70b9Worker\u3002 \u672c\u5730\u865a\u62df\u673a\u8bbe\u7f6e \u00b6 VMWare\u865a\u62df\u673a\u8bbe\u7f6e\u3002 VMnet1: host-only\u6a21\u5f0f, \u7f51\u7edcsubnet: 192.168.150.0/24 VMnet8: NAT\u6a21\u5f0f, \u7f51\u7edcsubnet: 11.0.1.0/24 \u901a\u8fc7VMWare\u521b\u5efa\u5ba2\u6237\u673a\u3002 \u5185\u5b58\uff1a4 GB CPU\uff1a2 CPUs with 2 Cores \u64cd\u4f5c\u7cfb\u7edf\uff1aUbuntu Server 22.04 \u7f51\u7edc\uff1aNAT Kubernetes\u8fd0\u884c\u5728Docker\u4e0a\u3002 Ubuntu\u9884\u914d\u7f6e \u00b6 \u521b\u5efa\u7528\u6237 vagrant \u3002 sudo adduser vagrant sudo usermod -aG adm,sudo,syslog,cdrom,dip,plugdev,lxd vagrant sudo passwd vagrant \u8bbe\u7f6e\u7528\u6237 root \u7684\u5bc6\u7801\u3002 sudo passwd root \u66f4\u65b0\u5ba2\u6237\u673a\u7684\u4e3b\u673a\u540d\uff0c\u8fd9\u91cc\u662f ubusvr \u3002 sudo hostnamectl set-hostname ubusvr sudo hostnamectl set-hostname ubusvr --pretty \u9a8c\u8bc1\u4e3b\u673a\u540d\u662f\u5426\u5df2\u6210\u529f\u66f4\u65b0\u4e3a ubusvr \u3002 cat /etc/machine-info cat /etc/hostname \u9a8c\u8bc1\u4e3b\u673aIP\u5730\u5740 127.0.1.1 \u5df2\u7ecf\u914d\u7f6e\u7ed9\u5f53\u524d\u865a\u62df\u673a ubusvr \u3002 cat /etc/hosts 127.0.0.1 localhost 127.0.1.1 ubusrv # The following lines are desirable for IPv6 capable hosts ::1 ip6-localhost ip6-loopback fe00::0 ip6-localnet ff00::0 ip6-mcastprefix ff02::1 ip6-allnodes ff02::2 ip6-allrouters \u8bbe\u7f6e\u5ba2\u6237\u673a\u4e3a\u56fa\u5b9aIP\u5730\u5740\uff0c\u8fd9\u91cc\u662f 11.0.1.136 \u3002 sudo vi 00 -installer-config.yaml network : ethernets : ens33 : dhcp4 : false addresses : - 11.0.1.136/24 nameservers : addresses : - 11.0.1.2 routes : - to : default via : 11.0.1.2 version : 2 sudo netplan apply \u7981\u7528\u4ea4\u6362\u5206\u533aswap\u3002 sudo swapoff -a sudo ufw disable sudo ufw status verbose \u6ce8\u91ca\u6389\u6587\u4ef6 /etc/fstab \u7684\u6700\u540e\u4e00\u884c\uff0c\u5373\u7981\u7528\u4ea4\u6362\u5206\u533a\u3002\u9700\u8981\u91cd\u542f\u5ba2\u6237\u673a\u4f7f\u4e4b\u751f\u6548\u3002 /dev/disk/by-uuid/df370d2a-83e5-4895-8c7f-633f2545e3fe / ext4 defaults 0 1 # /swap.img none swap sw 0 0 \u8bbe\u7f6e\u5ba2\u6237\u673a\u65f6\u533a\u3002 sudo ln -sf /usr/share/zoneinfo/Asia/Shanghai /etc/localtime sudo echo 'LANG=\"en_US.UTF-8\"' >> /etc/profile source /etc/profile \u6267\u884c\u547d\u4ee4 ll /etc/localtime \u9a8c\u8bc1\u65f6\u533a\u662f\u5426\u5df2\u6b63\u786e\u8bbe\u7f6e\u5e76\u751f\u6548\u3002 lrwxrwxrwx 1 root root 33 Jul 15 22:00 /etc/localtime -> /usr/share/zoneinfo/Asia/Shanghai \u5ba2\u6237\u673a\u5185\u6838\u8bbe\u7f6e\u3002 cat < /dev/null sudo apt-get update sudo apt-get install docker-ce docker-ce-cli containerd.io docker-compose-plugin sudo systemctl status docker.service sudo systemctl status containerd.service sudo groupadd docker sudo usermod -aG docker $USER \u8bbe\u7f6eContainerd\u3002 containerd config default | sudo tee /etc/containerd/config.toml sudo vi /etc/containerd/config.toml sudo systemctl restart containerd sudo systemctl status containerd \u5b89\u88c5Kubernetes \u00b6 \u5b89\u88c5kubeadm sudo apt-get update && sudo apt-get install -y apt-transport-https ca-certificates curl curl https://mirrors.aliyun.com/kubernetes/apt/doc/apt-key.gpg | sudo apt-key add - cat << EOF > /etc/apt/sources.list.d/kubernetes.list deb https://mirrors.aliyun.com/kubernetes/apt/ kubernetes-xenial main EOF sudo apt-get update sudo apt-get install ebtables sudo apt-get install libxtables12 sudo apt-get upgrade iptables apt policy kubeadm sudo apt-get -y install kubelet = 1 .23.8-00 kubeadm = 1 .23.8-00 kubectl = 1 .23.8-00 --allow-downgrades \u914d\u7f6e\u4e3b\u8282\u70b9\uff08Master\uff09\u3002 sudo kubeadm config print init-defaults \u5b89\u88c5\u9884\u6f14Dry run\u3002 sudo kubeadm init --dry-run --pod-network-cidr = 10 .244.0.0/16 --image-repository = registry.aliyuncs.com/google_containers --kubernetes-version = v1.23.8 \u5b89\u88c5\u3002 sudo kubeadm init --pod-network-cidr = 10 .244.0.0/16 --image-repository = registry.aliyuncs.com/google_containers --kubernetes-version = v1.23.8 mkdir -p $HOME /.kube sudo cp -i /etc/kubernetes/admin.conf $HOME /.kube/config sudo chown $( id -u ) : $( id -g ) $HOME /.kube/config \u5b89\u88c5Flannel\u3002\u5982\u679c\u9700\u8981\u8003\u8651\u7f51\u7edc\u7b56\u7565\uff0c\u5219\u5b89\u88c5Calico\u3002\u53c2\u7167 \u963f\u91cc\u4e91ECS \u4e2dInstall Calico or Flannel\u90e8\u5206\u3002 kubectl apply -f https://raw.githubusercontent.com/coreos/flannel/master/Documentation/kube-flannel.yml \u914d\u7f6e\u5de5\u4f5c\u8282\u70b9\uff08Worker Node\uff09\u3002 kubeadm join :6443 --token --discovery-token-ca-cert-hash < hash key generated by kubeadm init> kubeadm join 11 .0.1.136:6443 --token 6zqh1u.8b4afzc2ov4e7iuj \\ --discovery-token-ca-cert-hash sha256:815fdb9dd9e3ae0af07ffaf6c216964388098b150ef01ee3ae900c261a429d24 \u5728\u6240\u6709\u8282\u70b9\u4e0a\u914d\u7f6ebash\u81ea\u52a8\u8865\u5168\u529f\u80fd\u3002 sudo apt install -y bash-completion source /usr/share/bash-completion/bash_completion source < ( kubectl completion bash ) echo \"source <(kubectl completion bash)\" >> ~/.bashrc \u5728\u6240\u6709\u8282\u70b9\u4e0a\u5b9a\u4e49\u522b\u540d\uff08alias\uff09\u3002 echo 'alias k=kubectl' >>~/.bashrc echo 'complete -o default -F __start_kubectl k' >>~/.bashrc \u67e5\u770b\u5f53\u524d\u96c6\u7fa4\u72b6\u6001\u3002 kubectl cluster-info kubectl get nodes -owide kubectl get pod -A \u5b89\u88c5Helm \u00b6 \u5b89\u88c5Helm\u5ba2\u6237\u7aef\u3002 curl -fsSL -o get_helm.sh https://raw.githubusercontent.com/helm/helm/main/scripts/get-helm-3 chmod 700 get_helm.sh ./get_helm.sh \u8f93\u51fa\u7ed3\u679c\uff1a Downloading https://get.helm.sh/helm-v3.9.0-linux-amd64.tar.gz Verifying checksum... Done. Preparing to install helm into /usr/local/bin helm installed into /usr/local/bin/helm \u91cd\u7f6e\u96c6\u7fa4 \u00b6 \u6ce8\u610f\uff1a\u4e0b\u9762\u7684\u64cd\u4f5c\u4f1a\u91cd\u7f6e\u5f53\u524d\u96c6\u7fa4\uff08\u5220\u9664\u96c6\u7fa4\uff09\u3002 \u5220\u9664\u96c6\u7fa4\u4e2d\u6240\u6709\u8282\u70b9\u3002 kubeadm reset \u6e05\u9664 iptables \u4e2d\u5df2\u5b9a\u4e49\u7684\u89c4\u5219\u3002 iptables -F && iptables -t nat -F && iptables -t mangle -F && iptables -X \u6e05\u9664 IPVS \u4e2d\u5b9a\u4e49\u7684\u89c4\u5219\uff08\u5982\u679c\u4f7f\u7528 IPVS \uff09\u3002 ipvsadm --clear","title":"\u5355\u8282\u70b9\u865a\u62df\u673a\u5b89\u88c5Kubernetes"},{"location":"k8s/cka_cn/installation/single-local/#cka1kubernetes","text":"","title":"CKA\u81ea\u5b66\u7b14\u8bb01:\u5355\u8282\u70b9\u865a\u62df\u673a\u5b89\u88c5Kubernetes"},{"location":"k8s/cka_cn/installation/single-local/#_1","text":"\u5728\u672c\u5730Windows\u73af\u5883\u4e2d\uff0c\u901a\u8fc7VMWare\u5b89\u88c5Ubuntu\u865a\u62df\u673a\u3002\u5728Ubuntu\u865a\u62df\u673a\u4e2d\u5b89\u88c5\u57fa\u4e8eDocker\u7684Kubernetes\u7cfb\u7edf\u3002\u5728\u8be5\u865a\u62df\u673a\u4e2d\u540c\u65f6\u914d\u7f6e\u4e3b\u8282\u70b9Master\u548c\u5de5\u4f5c\u8282\u70b9Worker\u3002","title":"\u6458\u8981"},{"location":"k8s/cka_cn/installation/single-local/#_2","text":"VMWare\u865a\u62df\u673a\u8bbe\u7f6e\u3002 VMnet1: host-only\u6a21\u5f0f, \u7f51\u7edcsubnet: 192.168.150.0/24 VMnet8: NAT\u6a21\u5f0f, \u7f51\u7edcsubnet: 11.0.1.0/24 \u901a\u8fc7VMWare\u521b\u5efa\u5ba2\u6237\u673a\u3002 \u5185\u5b58\uff1a4 GB CPU\uff1a2 CPUs with 2 Cores \u64cd\u4f5c\u7cfb\u7edf\uff1aUbuntu Server 22.04 \u7f51\u7edc\uff1aNAT Kubernetes\u8fd0\u884c\u5728Docker\u4e0a\u3002","title":"\u672c\u5730\u865a\u62df\u673a\u8bbe\u7f6e"},{"location":"k8s/cka_cn/installation/single-local/#ubuntu","text":"\u521b\u5efa\u7528\u6237 vagrant \u3002 sudo adduser vagrant sudo usermod -aG adm,sudo,syslog,cdrom,dip,plugdev,lxd vagrant sudo passwd vagrant \u8bbe\u7f6e\u7528\u6237 root \u7684\u5bc6\u7801\u3002 sudo passwd root \u66f4\u65b0\u5ba2\u6237\u673a\u7684\u4e3b\u673a\u540d\uff0c\u8fd9\u91cc\u662f ubusvr \u3002 sudo hostnamectl set-hostname ubusvr sudo hostnamectl set-hostname ubusvr --pretty \u9a8c\u8bc1\u4e3b\u673a\u540d\u662f\u5426\u5df2\u6210\u529f\u66f4\u65b0\u4e3a ubusvr \u3002 cat /etc/machine-info cat /etc/hostname \u9a8c\u8bc1\u4e3b\u673aIP\u5730\u5740 127.0.1.1 \u5df2\u7ecf\u914d\u7f6e\u7ed9\u5f53\u524d\u865a\u62df\u673a ubusvr \u3002 cat /etc/hosts 127.0.0.1 localhost 127.0.1.1 ubusrv # The following lines are desirable for IPv6 capable hosts ::1 ip6-localhost ip6-loopback fe00::0 ip6-localnet ff00::0 ip6-mcastprefix ff02::1 ip6-allnodes ff02::2 ip6-allrouters \u8bbe\u7f6e\u5ba2\u6237\u673a\u4e3a\u56fa\u5b9aIP\u5730\u5740\uff0c\u8fd9\u91cc\u662f 11.0.1.136 \u3002 sudo vi 00 -installer-config.yaml network : ethernets : ens33 : dhcp4 : false addresses : - 11.0.1.136/24 nameservers : addresses : - 11.0.1.2 routes : - to : default via : 11.0.1.2 version : 2 sudo netplan apply \u7981\u7528\u4ea4\u6362\u5206\u533aswap\u3002 sudo swapoff -a sudo ufw disable sudo ufw status verbose \u6ce8\u91ca\u6389\u6587\u4ef6 /etc/fstab \u7684\u6700\u540e\u4e00\u884c\uff0c\u5373\u7981\u7528\u4ea4\u6362\u5206\u533a\u3002\u9700\u8981\u91cd\u542f\u5ba2\u6237\u673a\u4f7f\u4e4b\u751f\u6548\u3002 /dev/disk/by-uuid/df370d2a-83e5-4895-8c7f-633f2545e3fe / ext4 defaults 0 1 # /swap.img none swap sw 0 0 \u8bbe\u7f6e\u5ba2\u6237\u673a\u65f6\u533a\u3002 sudo ln -sf /usr/share/zoneinfo/Asia/Shanghai /etc/localtime sudo echo 'LANG=\"en_US.UTF-8\"' >> /etc/profile source /etc/profile \u6267\u884c\u547d\u4ee4 ll /etc/localtime \u9a8c\u8bc1\u65f6\u533a\u662f\u5426\u5df2\u6b63\u786e\u8bbe\u7f6e\u5e76\u751f\u6548\u3002 lrwxrwxrwx 1 root root 33 Jul 15 22:00 /etc/localtime -> /usr/share/zoneinfo/Asia/Shanghai \u5ba2\u6237\u673a\u5185\u6838\u8bbe\u7f6e\u3002 cat < /dev/null sudo apt-get update sudo apt-get install docker-ce docker-ce-cli containerd.io docker-compose-plugin sudo systemctl status docker.service sudo systemctl status containerd.service sudo groupadd docker sudo usermod -aG docker $USER \u8bbe\u7f6eContainerd\u3002 containerd config default | sudo tee /etc/containerd/config.toml sudo vi /etc/containerd/config.toml sudo systemctl restart containerd sudo systemctl status containerd","title":"\u5b89\u88c5Docker"},{"location":"k8s/cka_cn/installation/single-local/#kubernetes","text":"\u5b89\u88c5kubeadm sudo apt-get update && sudo apt-get install -y apt-transport-https ca-certificates curl curl https://mirrors.aliyun.com/kubernetes/apt/doc/apt-key.gpg | sudo apt-key add - cat << EOF > /etc/apt/sources.list.d/kubernetes.list deb https://mirrors.aliyun.com/kubernetes/apt/ kubernetes-xenial main EOF sudo apt-get update sudo apt-get install ebtables sudo apt-get install libxtables12 sudo apt-get upgrade iptables apt policy kubeadm sudo apt-get -y install kubelet = 1 .23.8-00 kubeadm = 1 .23.8-00 kubectl = 1 .23.8-00 --allow-downgrades \u914d\u7f6e\u4e3b\u8282\u70b9\uff08Master\uff09\u3002 sudo kubeadm config print init-defaults \u5b89\u88c5\u9884\u6f14Dry run\u3002 sudo kubeadm init --dry-run --pod-network-cidr = 10 .244.0.0/16 --image-repository = registry.aliyuncs.com/google_containers --kubernetes-version = v1.23.8 \u5b89\u88c5\u3002 sudo kubeadm init --pod-network-cidr = 10 .244.0.0/16 --image-repository = registry.aliyuncs.com/google_containers --kubernetes-version = v1.23.8 mkdir -p $HOME /.kube sudo cp -i /etc/kubernetes/admin.conf $HOME /.kube/config sudo chown $( id -u ) : $( id -g ) $HOME /.kube/config \u5b89\u88c5Flannel\u3002\u5982\u679c\u9700\u8981\u8003\u8651\u7f51\u7edc\u7b56\u7565\uff0c\u5219\u5b89\u88c5Calico\u3002\u53c2\u7167 \u963f\u91cc\u4e91ECS \u4e2dInstall Calico or Flannel\u90e8\u5206\u3002 kubectl apply -f https://raw.githubusercontent.com/coreos/flannel/master/Documentation/kube-flannel.yml \u914d\u7f6e\u5de5\u4f5c\u8282\u70b9\uff08Worker Node\uff09\u3002 kubeadm join :6443 --token --discovery-token-ca-cert-hash < hash key generated by kubeadm init> kubeadm join 11 .0.1.136:6443 --token 6zqh1u.8b4afzc2ov4e7iuj \\ --discovery-token-ca-cert-hash sha256:815fdb9dd9e3ae0af07ffaf6c216964388098b150ef01ee3ae900c261a429d24 \u5728\u6240\u6709\u8282\u70b9\u4e0a\u914d\u7f6ebash\u81ea\u52a8\u8865\u5168\u529f\u80fd\u3002 sudo apt install -y bash-completion source /usr/share/bash-completion/bash_completion source < ( kubectl completion bash ) echo \"source <(kubectl completion bash)\" >> ~/.bashrc \u5728\u6240\u6709\u8282\u70b9\u4e0a\u5b9a\u4e49\u522b\u540d\uff08alias\uff09\u3002 echo 'alias k=kubectl' >>~/.bashrc echo 'complete -o default -F __start_kubectl k' >>~/.bashrc \u67e5\u770b\u5f53\u524d\u96c6\u7fa4\u72b6\u6001\u3002 kubectl cluster-info kubectl get nodes -owide kubectl get pod -A","title":"\u5b89\u88c5Kubernetes"},{"location":"k8s/cka_cn/installation/single-local/#helm","text":"\u5b89\u88c5Helm\u5ba2\u6237\u7aef\u3002 curl -fsSL -o get_helm.sh https://raw.githubusercontent.com/helm/helm/main/scripts/get-helm-3 chmod 700 get_helm.sh ./get_helm.sh \u8f93\u51fa\u7ed3\u679c\uff1a Downloading https://get.helm.sh/helm-v3.9.0-linux-amd64.tar.gz Verifying checksum... Done. Preparing to install helm into /usr/local/bin helm installed into /usr/local/bin/helm","title":"\u5b89\u88c5Helm"},{"location":"k8s/cka_cn/installation/single-local/#_3","text":"\u6ce8\u610f\uff1a\u4e0b\u9762\u7684\u64cd\u4f5c\u4f1a\u91cd\u7f6e\u5f53\u524d\u96c6\u7fa4\uff08\u5220\u9664\u96c6\u7fa4\uff09\u3002 \u5220\u9664\u96c6\u7fa4\u4e2d\u6240\u6709\u8282\u70b9\u3002 kubeadm reset \u6e05\u9664 iptables \u4e2d\u5df2\u5b9a\u4e49\u7684\u89c4\u5219\u3002 iptables -F && iptables -t nat -F && iptables -t mangle -F && iptables -X \u6e05\u9664 IPVS \u4e2d\u5b9a\u4e49\u7684\u89c4\u5219\uff08\u5982\u679c\u4f7f\u7528 IPVS \uff09\u3002 ipvsadm --clear","title":"\u91cd\u7f6e\u96c6\u7fa4"},{"location":"k8s/cka_en/foundamentals/basics/","text":"kubectl basics \u00b6 Scenario: get to know how to operate Kubernetes cluster using kubectl . via API via kubectl via Dashboard Demo: Check current kubeconfig file \u00b6 Use the kubectl config command to get current context of configuration file. echo $KUBECONFIG kubectl config view kubectl config get-contexts Get resource list \u00b6 Get a complete list of supported resources kubectl api-resources Get cluster status \u00b6 Kubernetes control plane is running at https://:6443 CoreDNS is running at https://:6443/api/v1/namespaces/kube-system/services/kube-dns:dns/proxy kubectl cluster-info kubectl cluster-info dump Display resources \u00b6 Use kubectl get --help to get examples of displaying one or many resources. Get health status of control plane. kubectl get componentstatuses kubectl get cs Result NAME STATUS MESSAGE ERROR etcd-0 Healthy {\"health\":\"true\",\"reason\":\"\"} scheduler Healthy ok controller-manager Healthy ok Get node status and details \u00b6 kubectl get nodes kubectl get nodes -o wide kubectl describe node cka001 Use command kubectl create --help to get examples of creating resources. Create namespace \u00b6 kubectl create namespace --help kubectl create namespace my-namespace Information Namespace is a cluster, which includes services. Service may be on a node, may be not. Create deployment \u00b6 Create Deployment on the namespace. kubectl -n my-namespace create deployment my-busybox \\ --image=busybox \\ --replicas=3 \\ --port=5701 Create ClusterRole \u00b6 kubectl create clusterrole --help kubectl create clusterrole pod-creater \\ -n my-namespace \\ --verb=create \\ --resource=deployment \\ --resource-name=my-busybox Create ServiceAccount \u00b6 kubectl create serviceaccount --help kubectl -n my-namespace create serviceaccount my-service-account Create RoleBinding \u00b6 Note RoleBinding can reference a Role in the same namespace or a ClusterRole in the global namespace. kubectl create rolebinding --help kubectl create rolebinding NAME \\ --clusterrole=NAME|--role=NAME \\ [--user=username] \\ [--group=groupname] \\ [--serviceaccount=namespace:serviceaccountname] \\ [--dry-run=server|client|none] kubectl create rolebinding my-admin \\ --clusterrole=pod-creater \\ --serviceaccount=my-namespace:my-service-account Use the proxy \u00b6 We can use kubectl proxy command to open a tunnel to the API server and make it available locally - usually on localhost:8001 / 127.0.0.1:8001. When I want to explore the API, this is an easy way to gain access. Run the command kubectl proxy & and open http://localhost:8001/api/v1 in browser. Just opening http://localhost:8001 will return an error because we are only allowed to access certain parts of the API. Hence the API path is important kubectl proxy & Output [1] 102358 Starting to serve on 127.0.0.1:8001 Example, get available API groups and so on via below link: http://127.0.0.1:8001/ http://127.0.0.1:8001/api/v1 http://127.0.0.1:8001/api/v1/namespaces http://127.0.0.1:8001/api/v1/namespaces/default http://127.0.0.1:8001/api/v1/namespaces/sock-shop/pods Access as application \u00b6 If we access kubernetes as an application rather than an administrator, we cannot use the kubectl . Instead of kubectl we can use the program curl . We have to send HTTP requests to the cluster. asking for the available nodes. Make sure kubectl proxy is running and serving on http://localhost:8001/ . Execute command below with a -v=9 flag, it shows all the information needed. kubectl get nodes Go through the command's output and find the correct curl request below. curl -v -XGET \\ -H \"Accept: application/json;as=Table;v=v1;g=meta.k8s.io,application/json;as=Table;v=v1beta1;g=meta.k8s.io,application/json\" \\ -H \"User-Agent: kubectl/v1.24.1 (linux/amd64) kubernetes/3ddd0f4\" \\ 'https:///api/v1/nodes?limit=500' Reference *There is a forum-like page hosted by K8s with lots of information around kubectl and how to use it best. * Manage multiple clusters and multiple config files * kubectl command documentation * Shell autocompletion * kubectl cheat sheet * jsonpath in kubectl * kubectl","title":"kubectl basics"},{"location":"k8s/cka_en/foundamentals/basics/#kubectl-basics","text":"Scenario: get to know how to operate Kubernetes cluster using kubectl . via API via kubectl via Dashboard Demo:","title":"kubectl basics"},{"location":"k8s/cka_en/foundamentals/basics/#check-current-kubeconfig-file","text":"Use the kubectl config command to get current context of configuration file. echo $KUBECONFIG kubectl config view kubectl config get-contexts","title":"Check current kubeconfig file"},{"location":"k8s/cka_en/foundamentals/basics/#get-resource-list","text":"Get a complete list of supported resources kubectl api-resources","title":"Get resource list"},{"location":"k8s/cka_en/foundamentals/basics/#get-cluster-status","text":"Kubernetes control plane is running at https://:6443 CoreDNS is running at https://:6443/api/v1/namespaces/kube-system/services/kube-dns:dns/proxy kubectl cluster-info kubectl cluster-info dump","title":"Get cluster status"},{"location":"k8s/cka_en/foundamentals/basics/#display-resources","text":"Use kubectl get --help to get examples of displaying one or many resources. Get health status of control plane. kubectl get componentstatuses kubectl get cs Result NAME STATUS MESSAGE ERROR etcd-0 Healthy {\"health\":\"true\",\"reason\":\"\"} scheduler Healthy ok controller-manager Healthy ok","title":"Display resources"},{"location":"k8s/cka_en/foundamentals/basics/#get-node-status-and-details","text":"kubectl get nodes kubectl get nodes -o wide kubectl describe node cka001 Use command kubectl create --help to get examples of creating resources.","title":"Get node status and details"},{"location":"k8s/cka_en/foundamentals/basics/#create-namespace","text":"kubectl create namespace --help kubectl create namespace my-namespace Information Namespace is a cluster, which includes services. Service may be on a node, may be not.","title":"Create namespace"},{"location":"k8s/cka_en/foundamentals/basics/#create-deployment","text":"Create Deployment on the namespace. kubectl -n my-namespace create deployment my-busybox \\ --image=busybox \\ --replicas=3 \\ --port=5701","title":"Create deployment"},{"location":"k8s/cka_en/foundamentals/basics/#create-clusterrole","text":"kubectl create clusterrole --help kubectl create clusterrole pod-creater \\ -n my-namespace \\ --verb=create \\ --resource=deployment \\ --resource-name=my-busybox","title":"Create ClusterRole"},{"location":"k8s/cka_en/foundamentals/basics/#create-serviceaccount","text":"kubectl create serviceaccount --help kubectl -n my-namespace create serviceaccount my-service-account","title":"Create ServiceAccount"},{"location":"k8s/cka_en/foundamentals/basics/#create-rolebinding","text":"Note RoleBinding can reference a Role in the same namespace or a ClusterRole in the global namespace. kubectl create rolebinding --help kubectl create rolebinding NAME \\ --clusterrole=NAME|--role=NAME \\ [--user=username] \\ [--group=groupname] \\ [--serviceaccount=namespace:serviceaccountname] \\ [--dry-run=server|client|none] kubectl create rolebinding my-admin \\ --clusterrole=pod-creater \\ --serviceaccount=my-namespace:my-service-account","title":"Create RoleBinding"},{"location":"k8s/cka_en/foundamentals/basics/#use-the-proxy","text":"We can use kubectl proxy command to open a tunnel to the API server and make it available locally - usually on localhost:8001 / 127.0.0.1:8001. When I want to explore the API, this is an easy way to gain access. Run the command kubectl proxy & and open http://localhost:8001/api/v1 in browser. Just opening http://localhost:8001 will return an error because we are only allowed to access certain parts of the API. Hence the API path is important kubectl proxy & Output [1] 102358 Starting to serve on 127.0.0.1:8001 Example, get available API groups and so on via below link: http://127.0.0.1:8001/ http://127.0.0.1:8001/api/v1 http://127.0.0.1:8001/api/v1/namespaces http://127.0.0.1:8001/api/v1/namespaces/default http://127.0.0.1:8001/api/v1/namespaces/sock-shop/pods","title":"Use the proxy"},{"location":"k8s/cka_en/foundamentals/basics/#access-as-application","text":"If we access kubernetes as an application rather than an administrator, we cannot use the kubectl . Instead of kubectl we can use the program curl . We have to send HTTP requests to the cluster. asking for the available nodes. Make sure kubectl proxy is running and serving on http://localhost:8001/ . Execute command below with a -v=9 flag, it shows all the information needed. kubectl get nodes Go through the command's output and find the correct curl request below. curl -v -XGET \\ -H \"Accept: application/json;as=Table;v=v1;g=meta.k8s.io,application/json;as=Table;v=v1beta1;g=meta.k8s.io,application/json\" \\ -H \"User-Agent: kubectl/v1.24.1 (linux/amd64) kubernetes/3ddd0f4\" \\ 'https:///api/v1/nodes?limit=500' Reference *There is a forum-like page hosted by K8s with lots of information around kubectl and how to use it best. * Manage multiple clusters and multiple config files * kubectl command documentation * Shell autocompletion * kubectl cheat sheet * jsonpath in kubectl * kubectl","title":"Access as application"},{"location":"k8s/cka_en/foundamentals/casestudy-calico/","text":"Case Study: Install Calico \u00b6 Scenario: Install Calico Calico Datastore Configure IP Pools Install CNI plugin Install Typha Install calico/node Test networking The Calico Datastore \u00b6 In order to use Kubernetes as the Calico datastore, we need to define the custom resources Calico uses. Download and examine the list of Calico custom resource definitions, and open it in a file editor. wget https://projectcalico.docs.tigera.io/manifests/crds.yaml Create the custom resource definitions in Kubernetes. kubectl apply -f crds.yaml Install calicoctl . To interact directly with the Calico datastore, use the calicoctl client tool. Download the calicoctl binary to a Linux host with access to Kubernetes. The latest release of calicoctl can be found in the git page and replace below v3.23.2 by actual release number. wget https://github.com/projectcalico/calico/releases/download/v3.23.3/calicoctl-linux-amd64 chmod +x calicoctl-linux-amd64 sudo cp calicoctl-linux-amd64 /usr/local/bin/calicoctl Configure calicoctl to access Kubernetes echo \"export KUBECONFIG=/root/.kube/config\" >> ~/.bashrc echo \"export DATASTORE_TYPE=kubernetes\" >> ~/.bashrc echo $KUBECONFIG echo $DATASTORE_TYPE Verify calicoctl can reach the datastore by running\uff1a calicoctl get nodes -o wide Output similar to below: NAME ASN IPV4 IPV6 cka001 cka002 cka003 Nodes are backed by the Kubernetes node object, so we should see names that match kubectl get nodes . kubectl get nodes -o wide NAME STATUS ROLES AGE VERSION OS-IMAGE KERNEL-VERSION CONTAINER-RUNTIME cka001 NotReady control-plane,master 23m v1.24.0 Ubuntu 20.04.4 LTS 5.4.0-113-generic containerd://1.5.9 cka002 NotReady 22m v1.24.0 Ubuntu 20.04.4 LTS 5.4.0-113-generic containerd://1.5.9 cka003 NotReady 21m v1.24.0 Ubuntu 20.04.4 LTS 5.4.0-113-generic containerd://1.5.9 Configure IP Pools \u00b6 A workload is a container or VM that Calico handles the virtual networking for. In Kubernetes, workloads are pods. A workload endpoint is the virtual network interface a workload uses to connect to the Calico network. IP pools are ranges of IP addresses that Calico uses for workload endpoints. Get current IP pools in the cluster. So far, it's empty after fresh installation. calicoctl get ippools NAME CIDR SELECTOR The Pod CIDR is 10.244.0.0/16 we specified via kubeadm init . Let's create two IP pools for use in the cluster. Each pool can not have any overlaps. ipv4-ippool-1: 10.244.0.0/18 ipv4-ippool-2: 10.244.192.0/19 calicoctl apply -f - < /etc/cni/net.d/10-calico.conflist < /etc/cni/net.d/10-calico.conflist < /etc/cni/net.d/10-calico.conflist < 4h49m v1.24.0 cka003 Ready 4h49m v1.24.0 Install Typha \u00b6 Typha sits between the Kubernetes API server and per-node daemons like Felix and confd (running in calico/node). It watches the Kubernetes resources and Calico custom resources used by these daemons, and whenever a resource changes it fans out the update to the daemons. This reduces the number of watches the Kubernetes API server needs to serve and improves scalability of the cluster. Provision Certificates We will use mutually authenticated TLS to ensure that calico/node and Typha communicate securely. We generate a certificate authority (CA) and use it to sign a certificate for Typha. Change to directory /etc/kubernetes/pki/ . cd /etc/kubernetes/pki/ Create the CA certificate and key openssl req -x509 -newkey rsa:4096 \\ -keyout typhaca.key \\ -nodes \\ -out typhaca.crt \\ -subj \"/CN=Calico Typha CA\" \\ -days 365 Store the CA certificate in a ConfigMap that Typha & calico/node will access. kubectl create configmap -n kube-system calico-typha-ca --from-file=typhaca.crt Create the Typha key and certificate signing request (CSR). openssl req -newkey rsa:4096 \\ -keyout typha.key \\ -nodes \\ -out typha.csr \\ -subj \"/CN=calico-typha\" The certificate presents the Common Name (CN) as calico-typha . calico/node will be configured to verify this name. Sign the Typha certificate with the CA. openssl x509 -req -in typha.csr \\ -CA typhaca.crt \\ -CAkey typhaca.key \\ -CAcreateserial \\ -out typha.crt \\ -days 365 Signature ok subject=CN = calico-typha Getting CA Private Key Store the Typha key and certificate in a secret that Typha will access kubectl create secret generic -n kube-system calico-typha-certs --from-file=typha.key --from-file=typha.crt Provision RBAC Change to home directory. cd ~ Create a ServiceAccount that will be used to run Typha. kubectl create serviceaccount -n kube-system calico-typha Define a cluster role for Typha with permission to watch Calico datastore objects. kubectl apply -f - < pingtest-585b76c894-s2tbs 1/1 Running 0 7s 10.244.31.0 cka002 pingtest-585b76c894-vm9wn 1/1 Running 0 7s 10.244.28.64 cka003 Note the IP addresses of the second two pods, then exec into the first one. From inside the pod, ping the other two pod IP addresses. For example: kubectl exec -ti pingtest-585b76c894-chwjq -- sh / # ping 10.244.31.1 -c 4 4 packets transmitted, 4 packets received, 0% packet loss / # ping 10.244.31.0 -c 4 4 packets transmitted, 4 packets received, 0% packet loss / # ping 10.244.28.64 -c 4 4 packets transmitted, 0 packets received, 100% packet loss Check routes \u00b6 From one of the nodes, verify that routes exist to each of the pingtest pods\u2019 IP addresses. For example ip route get 10.244.31.1 ip route get 10.244.31.0 ip route get 10.244.28.64 In the result, the via (it's control-plane) in this example indicates the next-hop for this pod IP, which matches the IP address of the node the pod is scheduled on, as expected. IPAM allocations from different pools. Recall that we created two IP pools, but left one disabled. calicoctl get ippools -o wide Result NAME CIDR NAT IPIPMODE VXLANMODE DISABLED DISABLEBGPEXPORT SELECTOR ipv4-ippool-1 10.244.0.0/18 true Never Never false false all() ipv4-ippool-2 10.244.192.0/19 true Never Never true false all() Enable the second pool. calicoctl --allow-version-mismatch apply -f - < Let's attach to the Pod pingtest-585b76c894-chwjq again. kubectl exec -ti pingtest-585b76c894-chwjq -- sh / # 10.244.203.192 -c 4 4 packets transmitted, 0 packets received, 100 % packet loss Mark here. it's failed. Need further check why the route does not work. Clean up kubectl delete deployments.apps pingtest kubectl delete pod pingtest-ippool-2 Reference End-to-end Calico installation","title":"Calico Installation"},{"location":"k8s/cka_en/foundamentals/casestudy-calico/#case-study-install-calico","text":"Scenario: Install Calico Calico Datastore Configure IP Pools Install CNI plugin Install Typha Install calico/node Test networking","title":"Case Study: Install Calico"},{"location":"k8s/cka_en/foundamentals/casestudy-calico/#the-calico-datastore","text":"In order to use Kubernetes as the Calico datastore, we need to define the custom resources Calico uses. Download and examine the list of Calico custom resource definitions, and open it in a file editor. wget https://projectcalico.docs.tigera.io/manifests/crds.yaml Create the custom resource definitions in Kubernetes. kubectl apply -f crds.yaml Install calicoctl . To interact directly with the Calico datastore, use the calicoctl client tool. Download the calicoctl binary to a Linux host with access to Kubernetes. The latest release of calicoctl can be found in the git page and replace below v3.23.2 by actual release number. wget https://github.com/projectcalico/calico/releases/download/v3.23.3/calicoctl-linux-amd64 chmod +x calicoctl-linux-amd64 sudo cp calicoctl-linux-amd64 /usr/local/bin/calicoctl Configure calicoctl to access Kubernetes echo \"export KUBECONFIG=/root/.kube/config\" >> ~/.bashrc echo \"export DATASTORE_TYPE=kubernetes\" >> ~/.bashrc echo $KUBECONFIG echo $DATASTORE_TYPE Verify calicoctl can reach the datastore by running\uff1a calicoctl get nodes -o wide Output similar to below: NAME ASN IPV4 IPV6 cka001 cka002 cka003 Nodes are backed by the Kubernetes node object, so we should see names that match kubectl get nodes . kubectl get nodes -o wide NAME STATUS ROLES AGE VERSION OS-IMAGE KERNEL-VERSION CONTAINER-RUNTIME cka001 NotReady control-plane,master 23m v1.24.0 Ubuntu 20.04.4 LTS 5.4.0-113-generic containerd://1.5.9 cka002 NotReady 22m v1.24.0 Ubuntu 20.04.4 LTS 5.4.0-113-generic containerd://1.5.9 cka003 NotReady 21m v1.24.0 Ubuntu 20.04.4 LTS 5.4.0-113-generic containerd://1.5.9","title":"The Calico Datastore"},{"location":"k8s/cka_en/foundamentals/casestudy-calico/#configure-ip-pools","text":"A workload is a container or VM that Calico handles the virtual networking for. In Kubernetes, workloads are pods. A workload endpoint is the virtual network interface a workload uses to connect to the Calico network. IP pools are ranges of IP addresses that Calico uses for workload endpoints. Get current IP pools in the cluster. So far, it's empty after fresh installation. calicoctl get ippools NAME CIDR SELECTOR The Pod CIDR is 10.244.0.0/16 we specified via kubeadm init . Let's create two IP pools for use in the cluster. Each pool can not have any overlaps. ipv4-ippool-1: 10.244.0.0/18 ipv4-ippool-2: 10.244.192.0/19 calicoctl apply -f - < /etc/cni/net.d/10-calico.conflist < /etc/cni/net.d/10-calico.conflist < /etc/cni/net.d/10-calico.conflist < 4h49m v1.24.0 cka003 Ready 4h49m v1.24.0","title":"Install CNI plugin"},{"location":"k8s/cka_en/foundamentals/casestudy-calico/#install-typha","text":"Typha sits between the Kubernetes API server and per-node daemons like Felix and confd (running in calico/node). It watches the Kubernetes resources and Calico custom resources used by these daemons, and whenever a resource changes it fans out the update to the daemons. This reduces the number of watches the Kubernetes API server needs to serve and improves scalability of the cluster. Provision Certificates We will use mutually authenticated TLS to ensure that calico/node and Typha communicate securely. We generate a certificate authority (CA) and use it to sign a certificate for Typha. Change to directory /etc/kubernetes/pki/ . cd /etc/kubernetes/pki/ Create the CA certificate and key openssl req -x509 -newkey rsa:4096 \\ -keyout typhaca.key \\ -nodes \\ -out typhaca.crt \\ -subj \"/CN=Calico Typha CA\" \\ -days 365 Store the CA certificate in a ConfigMap that Typha & calico/node will access. kubectl create configmap -n kube-system calico-typha-ca --from-file=typhaca.crt Create the Typha key and certificate signing request (CSR). openssl req -newkey rsa:4096 \\ -keyout typha.key \\ -nodes \\ -out typha.csr \\ -subj \"/CN=calico-typha\" The certificate presents the Common Name (CN) as calico-typha . calico/node will be configured to verify this name. Sign the Typha certificate with the CA. openssl x509 -req -in typha.csr \\ -CA typhaca.crt \\ -CAkey typhaca.key \\ -CAcreateserial \\ -out typha.crt \\ -days 365 Signature ok subject=CN = calico-typha Getting CA Private Key Store the Typha key and certificate in a secret that Typha will access kubectl create secret generic -n kube-system calico-typha-certs --from-file=typha.key --from-file=typha.crt Provision RBAC Change to home directory. cd ~ Create a ServiceAccount that will be used to run Typha. kubectl create serviceaccount -n kube-system calico-typha Define a cluster role for Typha with permission to watch Calico datastore objects. kubectl apply -f - < pingtest-585b76c894-s2tbs 1/1 Running 0 7s 10.244.31.0 cka002 pingtest-585b76c894-vm9wn 1/1 Running 0 7s 10.244.28.64 cka003 Note the IP addresses of the second two pods, then exec into the first one. From inside the pod, ping the other two pod IP addresses. For example: kubectl exec -ti pingtest-585b76c894-chwjq -- sh / # ping 10.244.31.1 -c 4 4 packets transmitted, 4 packets received, 0% packet loss / # ping 10.244.31.0 -c 4 4 packets transmitted, 4 packets received, 0% packet loss / # ping 10.244.28.64 -c 4 4 packets transmitted, 0 packets received, 100% packet loss","title":"Pod to pod pings"},{"location":"k8s/cka_en/foundamentals/casestudy-calico/#check-routes","text":"From one of the nodes, verify that routes exist to each of the pingtest pods\u2019 IP addresses. For example ip route get 10.244.31.1 ip route get 10.244.31.0 ip route get 10.244.28.64 In the result, the via (it's control-plane) in this example indicates the next-hop for this pod IP, which matches the IP address of the node the pod is scheduled on, as expected. IPAM allocations from different pools. Recall that we created two IP pools, but left one disabled. calicoctl get ippools -o wide Result NAME CIDR NAT IPIPMODE VXLANMODE DISABLED DISABLEBGPEXPORT SELECTOR ipv4-ippool-1 10.244.0.0/18 true Never Never false false all() ipv4-ippool-2 10.244.192.0/19 true Never Never true false all() Enable the second pool. calicoctl --allow-version-mismatch apply -f - < Let's attach to the Pod pingtest-585b76c894-chwjq again. kubectl exec -ti pingtest-585b76c894-chwjq -- sh / # 10.244.203.192 -c 4 4 packets transmitted, 0 packets received, 100 % packet loss Mark here. it's failed. Need further check why the route does not work. Clean up kubectl delete deployments.apps pingtest kubectl delete pod pingtest-ippool-2 Reference End-to-end Calico installation","title":"Check routes"},{"location":"k8s/cka_en/foundamentals/casestudy-health-check/","text":"Case Study: Health Check \u00b6 Scenario: Create Deployment and Service Simulate an error (delete index.html) Pod is in unhealth status and is removed from endpoint list Fix the error (revert the index.html) Pod is back to normal and in endpoint list Create Deployment and Service \u00b6 Create Deployment nginx-healthcheck and Service nginx-healthcheck . kubectl apply -f - < nginx-healthcheck-79fc55d944-nwwjc 1/1 Running 0 9s 10.244.112.13 cka002 Access Pod IP via curl command, e.g., above example. curl 10.244.102.14 curl 10.244.112.13 We see a successful index.html content of Nginx below with above example. Check details of Service craeted in above example. kubectl describe svc nginx-healthcheck We will see below output. There are two Pods information listed in Endpoints . Name: nginx-healthcheck Namespace: dev Labels: Annotations: Selector: name=nginx-healthcheck Type: NodePort IP Family Policy: SingleStack IP Families: IPv4 IP: 11.244.238.20 IPs: 11.244.238.20 Port: 80/TCP TargetPort: 80/TCP NodePort: 31795/TCP Endpoints: 10.244.102.14:80,10.244.112.13:80 Session Affinity: None External Traffic Policy: Cluster Events: We can also get information of Endpoints. kubectl get endpoints nginx-healthcheck Result NAME ENDPOINTS AGE nginx-healthcheck 10.244.102.14:80,10.244.112.13:80 72s Till now, two nginx-healthcheck Pods are working and providing service as expected. Simulate readinessProbe Failure \u00b6 Let's simulate an error by deleting and index.html file in on of nginx-healthcheck Pod and see what's readinessProbe will do. First, execute kubectl exec -it -- bash to log into nginx-healthcheck Pod, and delete the index.html file. kubectl exec -it nginx-healthcheck-79fc55d944-jw887 -- bash cd /usr/share/nginx/html/ rm -rf index.html exit After that, let's check the status of above Pod that index.html file was deleted. kubectl describe pod nginx-healthcheck-79fc55d944-jw887 We can now see Readiness probe failed error event message. ...... Events: Type Reason Age From Message ---- ------ ---- ---- ------- Normal Scheduled 2m8s default-scheduler Successfully assigned dev/nginx-healthcheck-79fc55d944-jw887 to cka003 Normal Pulled 2m7s kubelet Container image \"nginx:latest\" already present on machine Normal Created 2m7s kubelet Created container nginx-healthcheck Normal Started 2m7s kubelet Started container nginx-healthcheck Warning Unhealthy 2s (x2 over 7s) kubelet Readiness probe failed: HTTP probe failed with statuscode: 403 Let's check another Pod. kubectl describe pod nginx-healthcheck-79fc55d944-nwwjc There is no error info. ...... Events: Type Reason Age From Message ---- ------ ---- ---- ------- Normal Scheduled 3m46s default-scheduler Successfully assigned dev/nginx-healthcheck-79fc55d944-nwwjc to cka002 Normal Pulled 3m45s kubelet Container image \"nginx:latest\" already present on machine Normal Created 3m45s kubelet Created container nginx-healthcheck Normal Started 3m45s kubelet Started container nginx-healthcheck Now, access Pod IP via curl command and see what the result of each Pod. curl 10.244.102.14 curl 10.244.112.13 Result: curl 10.244.102.14 failed with 403 Forbidden error below. curl 10.244.112.13 works well. Let's check current status of Nginx Service after one of Pods runs into failure. kubectl describe svc nginx-healthcheck In below output, there is only one Pod information listed in Endpoint. Name: nginx-healthcheck Namespace: dev Labels: Annotations: Selector: name=nginx-healthcheck Type: NodePort IP Family Policy: SingleStack IP Families: IPv4 IP: 11.244.238.20 IPs: 11.244.238.20 Port: 80/TCP TargetPort: 80/TCP NodePort: 31795/TCP Endpoints: 10.244.112.13:80 Session Affinity: None External Traffic Policy: Cluster Events: Same result we can get by checking information of Endpoints, which is only Pod is running. kubectl get endpoints nginx-healthcheck Output: NAME ENDPOINTS AGE nginx-healthcheck 10.244.112.13:80 6m5s Fix readinessProbe Failure \u00b6 Let's re-create the index.html file again in the Pod. kubectl exec -it nginx-healthcheck-79fc55d944-jw887 -- bash cd /usr/share/nginx/html/ cat > index.html << EOF Welcome to nginx!

Welcome to nginx!

If you see this page, the nginx web server is successfully installed and working. Further configuration is required.

For online documentation and support please refer to nginx.org.
Commercial support is available at nginx.com.

Thank you for using nginx.

EOF exit We now can see that two Pods are back to Endpoints to provide service now. kubectl describe svc nginx-healthcheck kubectl get endpoints nginx-healthcheck Re-access Pod IP via curl command and we can see both are back to normal status. curl 10.244.102.14 curl 10.244.112.13 Verify the Pod status again. kubectl describe pod nginx-healthcheck-79fc55d944-jw887 Conclusion: By delete the index.html file, the Pod is in unhealth status and is removed from endpoint list. One one health Pod can provide normal service. Clean up kubectl delete service nginx-healthcheck kubectl delete deployment nginx-healthcheck Simulate livenessProbe Failure \u00b6 Re-create Deployment nginx-healthcheck and Service nginx-healthcheck . Deployment: NAME READY UP-TO-DATE AVAILABLE AGE nginx-healthcheck 0/2 2 0 7s Pods: NAME READY STATUS RESTARTS AGE nginx-healthcheck-79fc55d944-lknp9 1/1 Running 0 96s nginx-healthcheck-79fc55d944-wntmg 1/1 Running 0 96s Change nginx default listening port from 80 to 90 to simulate livenessProbe Failure. livenessProbe check the live status via port 80 . kubectl exec -it nginx-healthcheck-79fc55d944-lknp9 -- bash root@nginx-healthcheck-79fc55d944-lknp9:/# cd /etc/nginx/conf.d root@nginx-healthcheck-79fc55d944-lknp9:/etc/nginx/conf.d# sed -i 's/80/90/g' default.conf root@nginx-healthcheck-79fc55d944-lknp9:/etc/nginx/conf.d# nginx -s reload 2022/07/24 12:59:45 [notice] 79#79: signal process started The Pod runs into failure. kubectl describe pod nginx-healthcheck-79fc55d944-lknp9 We can see livenessProbe failed error event message. Events: Type Reason Age From Message ---- ------ ---- ---- ------- Normal Scheduled 17m default-scheduler Successfully assigned dev/nginx-healthcheck-79fc55d944-lknp9 to cka003 Normal Pulled 2m47s (x2 over 17m) kubelet Container image \"nginx:latest\" already present on machine Normal Created 2m47s (x2 over 17m) kubelet Created container nginx-healthcheck Normal Started 2m47s (x2 over 17m) kubelet Started container nginx-healthcheck Warning Unhealthy 2m47s (x4 over 2m57s) kubelet Readiness probe failed: Get \"http://10.244.102.46:80/\": dial tcp 10.244.102.46:80: connect: connection refused Warning Unhealthy 2m47s (x3 over 2m57s) kubelet Liveness probe failed: dial tcp 10.244.102.46:80: connect: connection refused Normal Killing 2m47s kubelet Container nginx-healthcheck failed liveness probe, will be restarted Once failure detected by livenessProbe , the container will restarted again automatically. The default.conf we modified will be replaced by default file and the container status is up and normal.","title":"Health Check"},{"location":"k8s/cka_en/foundamentals/casestudy-health-check/#case-study-health-check","text":"Scenario: Create Deployment and Service Simulate an error (delete index.html) Pod is in unhealth status and is removed from endpoint list Fix the error (revert the index.html) Pod is back to normal and in endpoint list","title":"Case Study: Health Check"},{"location":"k8s/cka_en/foundamentals/casestudy-health-check/#create-deployment-and-service","text":"Create Deployment nginx-healthcheck and Service nginx-healthcheck . kubectl apply -f - < nginx-healthcheck-79fc55d944-nwwjc 1/1 Running 0 9s 10.244.112.13 cka002 Access Pod IP via curl command, e.g., above example. curl 10.244.102.14 curl 10.244.112.13 We see a successful index.html content of Nginx below with above example. Check details of Service craeted in above example. kubectl describe svc nginx-healthcheck We will see below output. There are two Pods information listed in Endpoints . Name: nginx-healthcheck Namespace: dev Labels: Annotations: Selector: name=nginx-healthcheck Type: NodePort IP Family Policy: SingleStack IP Families: IPv4 IP: 11.244.238.20 IPs: 11.244.238.20 Port: 80/TCP TargetPort: 80/TCP NodePort: 31795/TCP Endpoints: 10.244.102.14:80,10.244.112.13:80 Session Affinity: None External Traffic Policy: Cluster Events: We can also get information of Endpoints. kubectl get endpoints nginx-healthcheck Result NAME ENDPOINTS AGE nginx-healthcheck 10.244.102.14:80,10.244.112.13:80 72s Till now, two nginx-healthcheck Pods are working and providing service as expected.","title":"Create Deployment and Service"},{"location":"k8s/cka_en/foundamentals/casestudy-health-check/#simulate-readinessprobe-failure","text":"Let's simulate an error by deleting and index.html file in on of nginx-healthcheck Pod and see what's readinessProbe will do. First, execute kubectl exec -it -- bash to log into nginx-healthcheck Pod, and delete the index.html file. kubectl exec -it nginx-healthcheck-79fc55d944-jw887 -- bash cd /usr/share/nginx/html/ rm -rf index.html exit After that, let's check the status of above Pod that index.html file was deleted. kubectl describe pod nginx-healthcheck-79fc55d944-jw887 We can now see Readiness probe failed error event message. ...... Events: Type Reason Age From Message ---- ------ ---- ---- ------- Normal Scheduled 2m8s default-scheduler Successfully assigned dev/nginx-healthcheck-79fc55d944-jw887 to cka003 Normal Pulled 2m7s kubelet Container image \"nginx:latest\" already present on machine Normal Created 2m7s kubelet Created container nginx-healthcheck Normal Started 2m7s kubelet Started container nginx-healthcheck Warning Unhealthy 2s (x2 over 7s) kubelet Readiness probe failed: HTTP probe failed with statuscode: 403 Let's check another Pod. kubectl describe pod nginx-healthcheck-79fc55d944-nwwjc There is no error info. ...... Events: Type Reason Age From Message ---- ------ ---- ---- ------- Normal Scheduled 3m46s default-scheduler Successfully assigned dev/nginx-healthcheck-79fc55d944-nwwjc to cka002 Normal Pulled 3m45s kubelet Container image \"nginx:latest\" already present on machine Normal Created 3m45s kubelet Created container nginx-healthcheck Normal Started 3m45s kubelet Started container nginx-healthcheck Now, access Pod IP via curl command and see what the result of each Pod. curl 10.244.102.14 curl 10.244.112.13 Result: curl 10.244.102.14 failed with 403 Forbidden error below. curl 10.244.112.13 works well. Let's check current status of Nginx Service after one of Pods runs into failure. kubectl describe svc nginx-healthcheck In below output, there is only one Pod information listed in Endpoint. Name: nginx-healthcheck Namespace: dev Labels: Annotations: Selector: name=nginx-healthcheck Type: NodePort IP Family Policy: SingleStack IP Families: IPv4 IP: 11.244.238.20 IPs: 11.244.238.20 Port: 80/TCP TargetPort: 80/TCP NodePort: 31795/TCP Endpoints: 10.244.112.13:80 Session Affinity: None External Traffic Policy: Cluster Events: Same result we can get by checking information of Endpoints, which is only Pod is running. kubectl get endpoints nginx-healthcheck Output: NAME ENDPOINTS AGE nginx-healthcheck 10.244.112.13:80 6m5s","title":"Simulate readinessProbe Failure"},{"location":"k8s/cka_en/foundamentals/casestudy-health-check/#fix-readinessprobe-failure","text":"Let's re-create the index.html file again in the Pod. kubectl exec -it nginx-healthcheck-79fc55d944-jw887 -- bash cd /usr/share/nginx/html/ cat > index.html << EOF Welcome to nginx!

Welcome to nginx!

If you see this page, the nginx web server is successfully installed and working. Further configuration is required.

For online documentation and support please refer to nginx.org.
Commercial support is available at nginx.com.

Thank you for using nginx.

EOF exit We now can see that two Pods are back to Endpoints to provide service now. kubectl describe svc nginx-healthcheck kubectl get endpoints nginx-healthcheck Re-access Pod IP via curl command and we can see both are back to normal status. curl 10.244.102.14 curl 10.244.112.13 Verify the Pod status again. kubectl describe pod nginx-healthcheck-79fc55d944-jw887 Conclusion: By delete the index.html file, the Pod is in unhealth status and is removed from endpoint list. One one health Pod can provide normal service. Clean up kubectl delete service nginx-healthcheck kubectl delete deployment nginx-healthcheck","title":"Fix readinessProbe Failure"},{"location":"k8s/cka_en/foundamentals/casestudy-health-check/#simulate-livenessprobe-failure","text":"Re-create Deployment nginx-healthcheck and Service nginx-healthcheck . Deployment: NAME READY UP-TO-DATE AVAILABLE AGE nginx-healthcheck 0/2 2 0 7s Pods: NAME READY STATUS RESTARTS AGE nginx-healthcheck-79fc55d944-lknp9 1/1 Running 0 96s nginx-healthcheck-79fc55d944-wntmg 1/1 Running 0 96s Change nginx default listening port from 80 to 90 to simulate livenessProbe Failure. livenessProbe check the live status via port 80 . kubectl exec -it nginx-healthcheck-79fc55d944-lknp9 -- bash root@nginx-healthcheck-79fc55d944-lknp9:/# cd /etc/nginx/conf.d root@nginx-healthcheck-79fc55d944-lknp9:/etc/nginx/conf.d# sed -i 's/80/90/g' default.conf root@nginx-healthcheck-79fc55d944-lknp9:/etc/nginx/conf.d# nginx -s reload 2022/07/24 12:59:45 [notice] 79#79: signal process started The Pod runs into failure. kubectl describe pod nginx-healthcheck-79fc55d944-lknp9 We can see livenessProbe failed error event message. Events: Type Reason Age From Message ---- ------ ---- ---- ------- Normal Scheduled 17m default-scheduler Successfully assigned dev/nginx-healthcheck-79fc55d944-lknp9 to cka003 Normal Pulled 2m47s (x2 over 17m) kubelet Container image \"nginx:latest\" already present on machine Normal Created 2m47s (x2 over 17m) kubelet Created container nginx-healthcheck Normal Started 2m47s (x2 over 17m) kubelet Started container nginx-healthcheck Warning Unhealthy 2m47s (x4 over 2m57s) kubelet Readiness probe failed: Get \"http://10.244.102.46:80/\": dial tcp 10.244.102.46:80: connect: connection refused Warning Unhealthy 2m47s (x3 over 2m57s) kubelet Liveness probe failed: dial tcp 10.244.102.46:80: connect: connection refused Normal Killing 2m47s kubelet Container nginx-healthcheck failed liveness probe, will be restarted Once failure detected by livenessProbe , the container will restarted again automatically. The default.conf we modified will be replaced by default file and the container status is up and normal.","title":"Simulate livenessProbe Failure"},{"location":"k8s/cka_en/foundamentals/casestudy-operation-resources/","text":"Case Study: Operations on Resources \u00b6 Scenario: Node Label Annotation Namespace ServiceAccount Authorization Grant API access authorization to default ServiceAccount Deployment Expose Service Scale out the Deployment Rolling update Rolling back update Event Logging Node Label \u00b6 Add/update/remove node Label. # Update node label kubectl label node cka002 node=demonode # Get node info with label info kubectl get node --show-labels # Search node by label kubectl get node -l node=demonode # Remove a lable of node kubectl label node cka002 node- Annotation \u00b6 Create Nginx deployment kubectl create deploy nginx --image=nginx:mainline Get Annotation info. kubectl describe deployment/nginx Result ...... Labels: app=nginx Annotations: deployment.kubernetes.io/revision: 1 Selector: app=nginx ...... Add new Annotation. kubectl annotate deployment nginx owner=James.H Now annotation looks like below. ...... Labels: app=nginx Annotations: deployment.kubernetes.io/revision: 1 owner: James.H Selector: app=nginx ...... Update/Overwrite Annotation. kubectl annotate deployment/nginx owner=K8s --overwrite Now annotation looks like below. ...... Annotations: deployment.kubernetes.io/revision: 1 owner: K8s Selector: app=nginx ...... Remove Annotation kubectl annotate deployment/nginx owner- ...... Labels: app=nginx Annotations: deployment.kubernetes.io/revision: 1 Selector: app=nginx ...... Clean up kubectl delete deployment nginx Namespace \u00b6 Get current available namespaces. kubectl get namespace Result NAME STATUS AGE default Active 3h45m dev Active 3h11m kube-node-lease Active 3h45m kube-public Active 3h45m kube-system Active 3h45m Get Pod under a specific namespace. kubectl get pod -n kube-system Result NAME READY STATUS RESTARTS AGE calico-kube-controllers-5c64b68895-jr4nl 1/1 Running 0 3h25m calico-node-dsx76 1/1 Running 0 3h25m calico-node-p5rf2 1/1 Running 0 3h25m calico-node-tr22l 1/1 Running 0 3h25m coredns-6d8c4cb4d-g4jxc 1/1 Running 0 3h45m coredns-6d8c4cb4d-sqcvj 1/1 Running 0 3h45m etcd-cka001 1/1 Running 0 3h45m kube-apiserver-cka001 1/1 Running 0 3h45m kube-controller-manager-cka001 1/1 Running 0 3h45m kube-proxy-5cdbj 1/1 Running 0 3h41m kube-proxy-cm4hc 1/1 Running 0 3h45m kube-proxy-g4w52 1/1 Running 0 3h41m kube-scheduler-cka001 1/1 Running 0 3h45m Get Pods in all namespaces. kubectl get pod --all-namespaces kubectl get pod -A ServiceAccount Authorization \u00b6 With Kubernetes 1.23 and lower version, when we create a new namespace, Kubernetes will automatically create a ServiceAccount default and a token default-token-xxxxx . With Kubernetes 1.24, only ServiceAccount default is created automatically when a new namespace is created, need manually create a toke linked to the ServiceAccount default . Here is an example to create a new namespace dev , we can see that only ServiceAcccount: default was created in namespace dev , no secretes (token) linked to the ServiceAccount default . kubectl create namespace dev kubectl get serviceaccount -n dev kubectl get secrets -n dev There is a default cluster role admin . But there is no clusterrole binding to the cluster role admin . kubectl get clusterrole admin kubectl get clusterrolebinding | grep ClusterRole/admin Role and rolebinding is namespaces based. On namespace dev , there is no role and rolebinding. kubectl get role -n dev kubectl get rolebinding -n dev A Secret in the Kubernetes cluster is an object and it is used to store sensitive information such as username, password, and token, etc. The objective of Secrets is to encode or hash the credentials. The secrets can be reused in the various Pod definition file. A kubernetes.io/service-account-token type of Secret is used to store a token that identifies a service account. When using this Secret type, you need to ensure that the kubernetes.io/service-account.name annotation is set to an existing service account name. Let's create token for the ServiceAcccount: default in namespace dev . kubectl apply -f - << EOF apiVersion: v1 kind: Secret metadata: name: default-token-dev namespace: dev annotations: kubernetes.io/service-account.name: \"default\" type: kubernetes.io/service-account-token EOF Now we get ServiceAcccount: default and Secret (token) default-token-dev in namespace dev . kubectl get serviceaccount -n dev kubectl get secrets -n dev Get token of the service account default . TOKEN=$(kubectl -n dev describe secret $(kubectl -n dev get secrets | grep default | cut -f1 -d ' ') | grep -E '^token' | cut -f2 -d':' | tr -d ' ') echo $TOKEN Get API Service address. APISERVER=$(kubectl config view | grep https | cut -f 2- -d \":\" | tr -d \" \") echo $APISERVER Get Pod resources in namespace dev via API server with JSON layout. curl $APISERVER/api/v1/namespaces/dev/pods --header \"Authorization: Bearer $TOKEN\" --insecure We will receive 403 forbidden error message. The ServiceAccount default does not have authorization to access pod in namespace dev . Let's create a rolebinding rolebinding-admin to bind cluster role admin to service account default in namespapce dev . Hence service account default is granted adminstrator authorization in namespace dev . # Usage: kubectl create rolebinding --clusterrole= --serviceaccount=: --namespace= # Crate rolebinding: kubectl create rolebinding rolebinding-admin --clusterrole=admin --serviceaccount=dev:default --namespace=dev Result looks like below by executing kubectl get rolebinding -n dev . NAME ROLE AGE rolebinding-admin ClusterRole/admin 10s Try again, get pod resources in namespace dev via API server with JSON layout. curl $APISERVER/api/v1/namespaces/dev/pods --header \"Authorization: Bearer $TOKEN\" --insecure Clean up. kubectl delete namespace dev Deployment \u00b6 Create a Ubuntu Pod for operation. And attach to the running Pod. kubectl create -f - << EOF apiVersion: v1 kind: Pod metadata: name: ubuntu labels: app: ubuntu spec: containers: - name: ubuntu image: ubuntu:latest command: [\"/bin/sleep\", \"3650d\"] imagePullPolicy: IfNotPresent restartPolicy: Always EOF kubectl exec --stdin --tty ubuntu -- /bin/bash Create a deployment, option --image specifies a image\uff0coption --port specifies port for external access. A pod is also created when deployment is created. kubectl create deployment myapp --image=docker.io/jocatalin/kubernetes-bootcamp:v1 --replicas=1 --port=8080 Get deployment status kubectl get deployment myapp -o wide Result NAME READY UP-TO-DATE AVAILABLE AGE CONTAINERS IMAGES SELECTOR myapp 1/1 1 1 79s kubernetes-bootcamp docker.io/jocatalin/kubernetes-bootcamp:v1 app=myapp Get detail information of deployment. kubectl describe deployment myapp Result Name: myapp Namespace: dev CreationTimestamp: Sat, 23 Jul 2022 14:36:43 +0800 Labels: app=myapp Annotations: deployment.kubernetes.io/revision: 1 Selector: app=myapp Replicas: 1 desired | 1 updated | 1 total | 1 available | 0 unavailable StrategyType: RollingUpdate MinReadySeconds: 0 RollingUpdateStrategy: 25% max unavailable, 25% max surge Pod Template: Labels: app=myapp Containers: kubernetes-bootcamp: Image: docker.io/jocatalin/kubernetes-bootcamp:v1 Port: 8080/TCP Host Port: 0/TCP Environment: Mounts: Volumes: Conditions: Type Status Reason ---- ------ ------ Available True MinimumReplicasAvailable Progressing True NewReplicaSetAvailable OldReplicaSets: NewReplicaSet: myapp-b5d775f5d (1/1 replicas created) Events: Type Reason Age From Message ---- ------ ---- ---- ------- Normal ScalingReplicaSet 95s deployment-controller Scaled up replica set myapp-b5d775f5d to 1 Expose Service \u00b6 Get the Pod and Deployment we created just now. kubectl get deployment myapp -o wide kubectl get pod -o wide Result NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES myapp-b5d775f5d-cx8dx 1/1 Running 0 2m34s 10.244.102.7 cka003 Send http request to the Pod curl 10.244.102.7:8080 with below result. Hello Kubernetes bootcamp! | Running on: myapp-b5d775f5d-6jtgs | v=1 To make pod be accessed outside, we need expose port 8080 to a node port. A related service will be created. kubectl expose deployment myapp --type=NodePort --port=8080 Get details of service myapp by executing kubectl get svc myapp -o wide . NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE SELECTOR myapp NodePort 11.244.74.3 8080:30514/TCP 7s app=myapp Send http request to service port. curl 11.244.74.3:8080 Hello Kubernetes bootcamp! | Running on: myapp-b5d775f5d-cx8dx | v=1 Get more details of the service. kubectl get svc myapp -o yaml kubectl describe svc myapp Get details of related endpoint myapp by executing kubectl get endpoints myapp -o wide . NAME ENDPOINTS AGE myapp 10.244.102.7:8080 43s Send http request to the service and node sucessfully. Pod port 8080 is mapped to node port 32566 . Send http request to node port on cka003 . curl :30514 Hello Kubernetes bootcamp! | Running on: myapp-b5d775f5d-6jtgs | v=1 Attach to Ubuntu Pod we created and send http request to the Service and Pod and Node of myapp . kubectl exec --stdin --tty ubuntu -- /bin/bash curl 10.244.102.7:8080 curl 11.244.74.3:8080 curl :30514 Hello Kubernetes bootcamp! | Running on: myapp-b5d775f5d-6jtgs | v=1 Scale out Deployment \u00b6 Scale out by replicaset. We set three replicasets to scale out deployment myapp . The number of deployment myapp is now three. kubectl scale deployment myapp --replicas=3 Get status of deployment kubectl get deployment myapp Get status of replicaset kubectl get replicaset Rolling update \u00b6 Command usage: kubectl set image (-f FILENAME | TYPE NAME) CONTAINER_NAME_1=CONTAINER_IMAGE_1 ... CONTAINER_NAME_N=CONTAINER_IMAGE_N . With the command kubectl get deployment , we will get deployment name myapp and related container name kubernetes-bootcamp . kubectl get deployment myapp -o wide With the command kubectl set image to update image to many versions and log the change under deployment's annotations with option --record . kubectl set image deployment/myapp kubernetes-bootcamp=docker.io/jocatalin/kubernetes-bootcamp:v2 --record Current replicas status kubectl get replicaset -o wide -l app=myapp Result. Pods are running on new Replicas. NAME DESIRED CURRENT READY AGE CONTAINERS IMAGES SELECTOR myapp-5dbd68cc99 1 1 0 8s kubernetes-bootcamp docker.io/jocatalin/kubernetes-bootcamp:v2 app=myapp,pod-template-hash=5dbd68cc99 myapp-b5d775f5d 3 3 3 14m kubernetes-bootcamp docker.io/jocatalin/kubernetes-bootcamp:v1 app=myapp,pod-template-hash=b5d775f5d We can get the change history under metadata.annotations . kubectl get deployment myapp -o yaml Result apiVersion : apps/v1 kind : Deployment metadata : annotations : deployment.kubernetes.io/revision : \"2\" kubernetes.io/change-cause : kubectl set image deployment/myapp kubernetes-bootcamp=docker.io/jocatalin/kubernetes-bootcamp:v2 --record=true ...... We can also get the change history by command kubectl rollout history , and show details with specific revision --revision= . kubectl rollout history deployment/myapp Result deployment.apps/myapp REVISION CHANGE-CAUSE 1 2 kubectl set image deployment/myapp kubernetes-bootcamp=docker.io/jocatalin/kubernetes-bootcamp:v2 --record=true Get rollout history with specific revision. kubectl rollout history deployment/myapp --revision=2 Roll back to previous revision with command kubectl rollout undo , or roll back to specific revision with option --to-revision= . kubectl rollout undo deployment/myapp --to-revision=1 Revision 1 was replaced by new revision 3 now. kubectl rollout history deployment/myapp Result deployment.apps/myapp REVISION CHANGE-CAUSE 2 kubectl set image deployment/myapp kubernetes-bootcamp=docker.io/jocatalin/kubernetes-bootcamp:v2 --record=true 3 Event \u00b6 Get detail event info of related Pod. kubectl describe pod myapp-b5d775f5d-jlx6g Result looks like below. ...... Events: Type Reason Age From Message ---- ------ ---- ---- ------- Normal Scheduled 54s default-scheduler Successfully assigned dev/myapp-b5d775f5d-jlx6g to cka003 Normal Pulled 53s kubelet Container image \"docker.io/jocatalin/kubernetes-bootcamp:v1\" already present on machine Normal Created 53s kubelet Created container kubernetes-bootcamp Normal Started 53s kubelet Started container kubernetes-bootcamp Get detail event info of entire cluster. kubectl get event Logging \u00b6 Get log info of Pod. kubectl logs -f kubectl logs -f -c Get a Pod logs kubectl logs -f myapp-b5d775f5d-jlx6g Kubernetes Bootcamp App Started At: 2022-07-23T06:54:18.532Z | Running On: myapp-b5d775f5d-jlx6g Get log info of K8s components. kubectl logs kube-apiserver-cka001 -n kube-system kubectl logs kube-controller-manager-cka001 -n kube-system kubectl logs kube-scheduler-cka001 -n kube-system kubectl logs etcd-cka001 -n kube-system systemctl status kubelet journalctl -fu kubelet kubectl logs kube-proxy-5cdbj -n kube-system Clean up. kubectl delete service myapp kubectl delete deployment myapp","title":"Operations on Resources"},{"location":"k8s/cka_en/foundamentals/casestudy-operation-resources/#case-study-operations-on-resources","text":"Scenario: Node Label Annotation Namespace ServiceAccount Authorization Grant API access authorization to default ServiceAccount Deployment Expose Service Scale out the Deployment Rolling update Rolling back update Event Logging","title":"Case Study: Operations on Resources"},{"location":"k8s/cka_en/foundamentals/casestudy-operation-resources/#node-label","text":"Add/update/remove node Label. # Update node label kubectl label node cka002 node=demonode # Get node info with label info kubectl get node --show-labels # Search node by label kubectl get node -l node=demonode # Remove a lable of node kubectl label node cka002 node-","title":"Node Label"},{"location":"k8s/cka_en/foundamentals/casestudy-operation-resources/#annotation","text":"Create Nginx deployment kubectl create deploy nginx --image=nginx:mainline Get Annotation info. kubectl describe deployment/nginx Result ...... Labels: app=nginx Annotations: deployment.kubernetes.io/revision: 1 Selector: app=nginx ...... Add new Annotation. kubectl annotate deployment nginx owner=James.H Now annotation looks like below. ...... Labels: app=nginx Annotations: deployment.kubernetes.io/revision: 1 owner: James.H Selector: app=nginx ...... Update/Overwrite Annotation. kubectl annotate deployment/nginx owner=K8s --overwrite Now annotation looks like below. ...... Annotations: deployment.kubernetes.io/revision: 1 owner: K8s Selector: app=nginx ...... Remove Annotation kubectl annotate deployment/nginx owner- ...... Labels: app=nginx Annotations: deployment.kubernetes.io/revision: 1 Selector: app=nginx ...... Clean up kubectl delete deployment nginx","title":"Annotation"},{"location":"k8s/cka_en/foundamentals/casestudy-operation-resources/#namespace","text":"Get current available namespaces. kubectl get namespace Result NAME STATUS AGE default Active 3h45m dev Active 3h11m kube-node-lease Active 3h45m kube-public Active 3h45m kube-system Active 3h45m Get Pod under a specific namespace. kubectl get pod -n kube-system Result NAME READY STATUS RESTARTS AGE calico-kube-controllers-5c64b68895-jr4nl 1/1 Running 0 3h25m calico-node-dsx76 1/1 Running 0 3h25m calico-node-p5rf2 1/1 Running 0 3h25m calico-node-tr22l 1/1 Running 0 3h25m coredns-6d8c4cb4d-g4jxc 1/1 Running 0 3h45m coredns-6d8c4cb4d-sqcvj 1/1 Running 0 3h45m etcd-cka001 1/1 Running 0 3h45m kube-apiserver-cka001 1/1 Running 0 3h45m kube-controller-manager-cka001 1/1 Running 0 3h45m kube-proxy-5cdbj 1/1 Running 0 3h41m kube-proxy-cm4hc 1/1 Running 0 3h45m kube-proxy-g4w52 1/1 Running 0 3h41m kube-scheduler-cka001 1/1 Running 0 3h45m Get Pods in all namespaces. kubectl get pod --all-namespaces kubectl get pod -A","title":"Namespace"},{"location":"k8s/cka_en/foundamentals/casestudy-operation-resources/#serviceaccount-authorization","text":"With Kubernetes 1.23 and lower version, when we create a new namespace, Kubernetes will automatically create a ServiceAccount default and a token default-token-xxxxx . With Kubernetes 1.24, only ServiceAccount default is created automatically when a new namespace is created, need manually create a toke linked to the ServiceAccount default . Here is an example to create a new namespace dev , we can see that only ServiceAcccount: default was created in namespace dev , no secretes (token) linked to the ServiceAccount default . kubectl create namespace dev kubectl get serviceaccount -n dev kubectl get secrets -n dev There is a default cluster role admin . But there is no clusterrole binding to the cluster role admin . kubectl get clusterrole admin kubectl get clusterrolebinding | grep ClusterRole/admin Role and rolebinding is namespaces based. On namespace dev , there is no role and rolebinding. kubectl get role -n dev kubectl get rolebinding -n dev A Secret in the Kubernetes cluster is an object and it is used to store sensitive information such as username, password, and token, etc. The objective of Secrets is to encode or hash the credentials. The secrets can be reused in the various Pod definition file. A kubernetes.io/service-account-token type of Secret is used to store a token that identifies a service account. When using this Secret type, you need to ensure that the kubernetes.io/service-account.name annotation is set to an existing service account name. Let's create token for the ServiceAcccount: default in namespace dev . kubectl apply -f - << EOF apiVersion: v1 kind: Secret metadata: name: default-token-dev namespace: dev annotations: kubernetes.io/service-account.name: \"default\" type: kubernetes.io/service-account-token EOF Now we get ServiceAcccount: default and Secret (token) default-token-dev in namespace dev . kubectl get serviceaccount -n dev kubectl get secrets -n dev Get token of the service account default . TOKEN=$(kubectl -n dev describe secret $(kubectl -n dev get secrets | grep default | cut -f1 -d ' ') | grep -E '^token' | cut -f2 -d':' | tr -d ' ') echo $TOKEN Get API Service address. APISERVER=$(kubectl config view | grep https | cut -f 2- -d \":\" | tr -d \" \") echo $APISERVER Get Pod resources in namespace dev via API server with JSON layout. curl $APISERVER/api/v1/namespaces/dev/pods --header \"Authorization: Bearer $TOKEN\" --insecure We will receive 403 forbidden error message. The ServiceAccount default does not have authorization to access pod in namespace dev . Let's create a rolebinding rolebinding-admin to bind cluster role admin to service account default in namespapce dev . Hence service account default is granted adminstrator authorization in namespace dev . # Usage: kubectl create rolebinding --clusterrole= --serviceaccount=: --namespace= # Crate rolebinding: kubectl create rolebinding rolebinding-admin --clusterrole=admin --serviceaccount=dev:default --namespace=dev Result looks like below by executing kubectl get rolebinding -n dev . NAME ROLE AGE rolebinding-admin ClusterRole/admin 10s Try again, get pod resources in namespace dev via API server with JSON layout. curl $APISERVER/api/v1/namespaces/dev/pods --header \"Authorization: Bearer $TOKEN\" --insecure Clean up. kubectl delete namespace dev","title":"ServiceAccount Authorization"},{"location":"k8s/cka_en/foundamentals/casestudy-operation-resources/#deployment","text":"Create a Ubuntu Pod for operation. And attach to the running Pod. kubectl create -f - << EOF apiVersion: v1 kind: Pod metadata: name: ubuntu labels: app: ubuntu spec: containers: - name: ubuntu image: ubuntu:latest command: [\"/bin/sleep\", \"3650d\"] imagePullPolicy: IfNotPresent restartPolicy: Always EOF kubectl exec --stdin --tty ubuntu -- /bin/bash Create a deployment, option --image specifies a image\uff0coption --port specifies port for external access. A pod is also created when deployment is created. kubectl create deployment myapp --image=docker.io/jocatalin/kubernetes-bootcamp:v1 --replicas=1 --port=8080 Get deployment status kubectl get deployment myapp -o wide Result NAME READY UP-TO-DATE AVAILABLE AGE CONTAINERS IMAGES SELECTOR myapp 1/1 1 1 79s kubernetes-bootcamp docker.io/jocatalin/kubernetes-bootcamp:v1 app=myapp Get detail information of deployment. kubectl describe deployment myapp Result Name: myapp Namespace: dev CreationTimestamp: Sat, 23 Jul 2022 14:36:43 +0800 Labels: app=myapp Annotations: deployment.kubernetes.io/revision: 1 Selector: app=myapp Replicas: 1 desired | 1 updated | 1 total | 1 available | 0 unavailable StrategyType: RollingUpdate MinReadySeconds: 0 RollingUpdateStrategy: 25% max unavailable, 25% max surge Pod Template: Labels: app=myapp Containers: kubernetes-bootcamp: Image: docker.io/jocatalin/kubernetes-bootcamp:v1 Port: 8080/TCP Host Port: 0/TCP Environment: Mounts: Volumes: Conditions: Type Status Reason ---- ------ ------ Available True MinimumReplicasAvailable Progressing True NewReplicaSetAvailable OldReplicaSets: NewReplicaSet: myapp-b5d775f5d (1/1 replicas created) Events: Type Reason Age From Message ---- ------ ---- ---- ------- Normal ScalingReplicaSet 95s deployment-controller Scaled up replica set myapp-b5d775f5d to 1","title":"Deployment"},{"location":"k8s/cka_en/foundamentals/casestudy-operation-resources/#expose-service","text":"Get the Pod and Deployment we created just now. kubectl get deployment myapp -o wide kubectl get pod -o wide Result NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES myapp-b5d775f5d-cx8dx 1/1 Running 0 2m34s 10.244.102.7 cka003 Send http request to the Pod curl 10.244.102.7:8080 with below result. Hello Kubernetes bootcamp! | Running on: myapp-b5d775f5d-6jtgs | v=1 To make pod be accessed outside, we need expose port 8080 to a node port. A related service will be created. kubectl expose deployment myapp --type=NodePort --port=8080 Get details of service myapp by executing kubectl get svc myapp -o wide . NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE SELECTOR myapp NodePort 11.244.74.3 8080:30514/TCP 7s app=myapp Send http request to service port. curl 11.244.74.3:8080 Hello Kubernetes bootcamp! | Running on: myapp-b5d775f5d-cx8dx | v=1 Get more details of the service. kubectl get svc myapp -o yaml kubectl describe svc myapp Get details of related endpoint myapp by executing kubectl get endpoints myapp -o wide . NAME ENDPOINTS AGE myapp 10.244.102.7:8080 43s Send http request to the service and node sucessfully. Pod port 8080 is mapped to node port 32566 . Send http request to node port on cka003 . curl :30514 Hello Kubernetes bootcamp! | Running on: myapp-b5d775f5d-6jtgs | v=1 Attach to Ubuntu Pod we created and send http request to the Service and Pod and Node of myapp . kubectl exec --stdin --tty ubuntu -- /bin/bash curl 10.244.102.7:8080 curl 11.244.74.3:8080 curl :30514 Hello Kubernetes bootcamp! | Running on: myapp-b5d775f5d-6jtgs | v=1","title":"Expose Service"},{"location":"k8s/cka_en/foundamentals/casestudy-operation-resources/#scale-out-deployment","text":"Scale out by replicaset. We set three replicasets to scale out deployment myapp . The number of deployment myapp is now three. kubectl scale deployment myapp --replicas=3 Get status of deployment kubectl get deployment myapp Get status of replicaset kubectl get replicaset","title":"Scale out Deployment"},{"location":"k8s/cka_en/foundamentals/casestudy-operation-resources/#rolling-update","text":"Command usage: kubectl set image (-f FILENAME | TYPE NAME) CONTAINER_NAME_1=CONTAINER_IMAGE_1 ... CONTAINER_NAME_N=CONTAINER_IMAGE_N . With the command kubectl get deployment , we will get deployment name myapp and related container name kubernetes-bootcamp . kubectl get deployment myapp -o wide With the command kubectl set image to update image to many versions and log the change under deployment's annotations with option --record . kubectl set image deployment/myapp kubernetes-bootcamp=docker.io/jocatalin/kubernetes-bootcamp:v2 --record Current replicas status kubectl get replicaset -o wide -l app=myapp Result. Pods are running on new Replicas. NAME DESIRED CURRENT READY AGE CONTAINERS IMAGES SELECTOR myapp-5dbd68cc99 1 1 0 8s kubernetes-bootcamp docker.io/jocatalin/kubernetes-bootcamp:v2 app=myapp,pod-template-hash=5dbd68cc99 myapp-b5d775f5d 3 3 3 14m kubernetes-bootcamp docker.io/jocatalin/kubernetes-bootcamp:v1 app=myapp,pod-template-hash=b5d775f5d We can get the change history under metadata.annotations . kubectl get deployment myapp -o yaml Result apiVersion : apps/v1 kind : Deployment metadata : annotations : deployment.kubernetes.io/revision : \"2\" kubernetes.io/change-cause : kubectl set image deployment/myapp kubernetes-bootcamp=docker.io/jocatalin/kubernetes-bootcamp:v2 --record=true ...... We can also get the change history by command kubectl rollout history , and show details with specific revision --revision= . kubectl rollout history deployment/myapp Result deployment.apps/myapp REVISION CHANGE-CAUSE 1 2 kubectl set image deployment/myapp kubernetes-bootcamp=docker.io/jocatalin/kubernetes-bootcamp:v2 --record=true Get rollout history with specific revision. kubectl rollout history deployment/myapp --revision=2 Roll back to previous revision with command kubectl rollout undo , or roll back to specific revision with option --to-revision= . kubectl rollout undo deployment/myapp --to-revision=1 Revision 1 was replaced by new revision 3 now. kubectl rollout history deployment/myapp Result deployment.apps/myapp REVISION CHANGE-CAUSE 2 kubectl set image deployment/myapp kubernetes-bootcamp=docker.io/jocatalin/kubernetes-bootcamp:v2 --record=true 3 ","title":"Rolling update"},{"location":"k8s/cka_en/foundamentals/casestudy-operation-resources/#event","text":"Get detail event info of related Pod. kubectl describe pod myapp-b5d775f5d-jlx6g Result looks like below. ...... Events: Type Reason Age From Message ---- ------ ---- ---- ------- Normal Scheduled 54s default-scheduler Successfully assigned dev/myapp-b5d775f5d-jlx6g to cka003 Normal Pulled 53s kubelet Container image \"docker.io/jocatalin/kubernetes-bootcamp:v1\" already present on machine Normal Created 53s kubelet Created container kubernetes-bootcamp Normal Started 53s kubelet Started container kubernetes-bootcamp Get detail event info of entire cluster. kubectl get event","title":"Event"},{"location":"k8s/cka_en/foundamentals/casestudy-operation-resources/#logging","text":"Get log info of Pod. kubectl logs -f kubectl logs -f -c Get a Pod logs kubectl logs -f myapp-b5d775f5d-jlx6g Kubernetes Bootcamp App Started At: 2022-07-23T06:54:18.532Z | Running On: myapp-b5d775f5d-jlx6g Get log info of K8s components. kubectl logs kube-apiserver-cka001 -n kube-system kubectl logs kube-controller-manager-cka001 -n kube-system kubectl logs kube-scheduler-cka001 -n kube-system kubectl logs etcd-cka001 -n kube-system systemctl status kubelet journalctl -fu kubelet kubectl logs kube-proxy-5cdbj -n kube-system Clean up. kubectl delete service myapp kubectl delete deployment myapp","title":"Logging"},{"location":"k8s/cka_en/foundamentals/clustermgt/","text":"Cluster Management \u00b6 Scenario: etcd Backup and Restore Install etcdctl Create Deployment Before Backup Backup etcd Create Deployment After Backup Stop Services Stop etcd Restore etcd Start Services Verify etcd Backup and Restore \u00b6 Install etcdctl \u00b6 Download etcd package from Github. wget https://github.com/etcd-io/etcd/releases/download/v3.5.3/etcd-v3.5.3-linux-amd64.tar.gz Unzip and grant execute permission. tar -zxvf etcd-v3.5.3-linux-amd64.tar.gz cp etcd-v3.5.3-linux-amd64/etcdctl /usr/local/bin/ sudo chmod u+x /usr/local/bin/etcdctl Verify etcdctl --help Create Deployment Before Backup \u00b6 Create Deployment before backup. kubectl create deployment app-before-backup --image=nginx Backup etcd \u00b6 Usage * is the actual IP address of Control Plane. * --endpoints : specify where to save backup of etcd, 2379 is etcd port. * --cert : sepcify etcd certificate, which was generated by kubeadm and saved in /etc/kubernetes/pki/etcd/ . * --key : specify etcd certificate key, which was generated by kubeadm and saved in /etc/kubernetes/pki/etcd/ . * --cacert : specify etcd certificate CA, which was generated by kubeadm and saved in /etc/kubernetes/pki/etcd/ . etcdctl \\ --endpoints=https://:2379 \\ --cert=/etc/kubernetes/pki/etcd/server.crt \\ --key=/etc/kubernetes/pki/etcd/server.key \\ --cacert=/etc/kubernetes/pki/etcd/ca.crt \\ snapshot save snapshot-$(date +\"%Y%m%d%H%M%S\").db etcdctl \\ --endpoints=https://:2379 \\ --cert=/etc/kubernetes/pki/etcd/server.crt \\ --key=/etc/kubernetes/pki/etcd/server.key \\ --cacert=/etc/kubernetes/pki/etcd/ca.crt \\ snapshot save snapshot-$(date +\"%Y%m%d%H%M%S\").db Output: {\"level\":\"info\",\"ts\":\"2022-07-24T18:51:21.328+0800\",\"caller\":\"snapshot/v3_snapshot.go:65\",\"msg\":\"created temporary db file\",\"path\":\"snapshot-20220724185121.db.part\"} {\"level\":\"info\",\"ts\":\"2022-07-24T18:51:21.337+0800\",\"logger\":\"client\",\"caller\":\"v3/maintenance.go:211\",\"msg\":\"opened snapshot stream; downloading\"} {\"level\":\"info\",\"ts\":\"2022-07-24T18:51:21.337+0800\",\"caller\":\"snapshot/v3_snapshot.go:73\",\"msg\":\"fetching snapshot\",\"endpoint\":\"https://:2379\"} {\"level\":\"info\",\"ts\":\"2022-07-24T18:51:21.415+0800\",\"logger\":\"client\",\"caller\":\"v3/maintenance.go:219\",\"msg\":\"completed snapshot read; closing\"} {\"level\":\"info\",\"ts\":\"2022-07-24T18:51:21.477+0800\",\"caller\":\"snapshot/v3_snapshot.go:88\",\"msg\":\"fetched snapshot\",\"endpoint\":\"https://:2379\",\"size\":\"3.6 MB\",\"took\":\"now\"} {\"level\":\"info\",\"ts\":\"2022-07-24T18:51:21.477+0800\",\"caller\":\"snapshot/v3_snapshot.go:97\",\"msg\":\"saved\",\"path\":\"snapshot-20220724185121.db\"} Snapshot saved at snapshot-20220724185121.db We can get the backup file in current directory with ls -al command. -rw------- 1 root root 3616800 Jul 24 18:51 snapshot-20220724185121.db Create Deployment After Backup \u00b6 Create Deployment after backup. kubectl create deployment app-after-backup --image=nginx Delete Deployment we created before backup. kubectl delete deployment app-before-backup Check Deployment status kubectl get deploy NAME READY UP-TO-DATE AVAILABLE AGE app-after-backup 1/1 1 1 108s Stop Services \u00b6 Delete etcd directory. mv /var/lib/etcd/ /var/lib/etcd.bak Stop kubelet systemctl stop kubelet Stop kube-apiserver nerdctl -n k8s.io ps -a | grep apiserver 0c5e69118f1b registry.aliyuncs.com/google_containers/kube-apiserver:v1.24.0 \"kube-apiserver --ad\u2026\" 32 hours ago Up k8s://kube-system/kube-apiserver-cka001/kube-apiserver 638bb602c310 registry.aliyuncs.com/google_containers/pause:3.6 \"/pause\" 32 hours ago Up k8s://kube-system/kube-apiserver-cka001 Stop those up status containers. nerdctl -n k8s.io stop nerdctl -n k8s.io stop 0c5e69118f1b nerdctl -n k8s.io stop 638bb602c310 No up status kube-apiserver now. nerdctl -n k8s.io ps -a | grep apiserver 0c5e69118f1b registry.aliyuncs.com/google_containers/kube-apiserver:v1.24.0 \"kube-apiserver --ad\u2026\" 32 hours ago Created k8s://kube-system/kube-apiserver-cka001/kube-apiserver 638bb602c310 registry.aliyuncs.com/google_containers/pause:3.6 \"/pause\" 32 hours ago Created k8s://kube-system/kube-apiserver-cka001 Stop etcd \u00b6 nerdctl -n k8s.io ps -a | grep etcd 0965b195f41a registry.aliyuncs.com/google_containers/etcd:3.5.1-0 \"etcd --advertise-cl\u2026\" 32 hours ago Up k8s://kube-system/etcd-cka001/etcd 9e1bea9f25d1 registry.aliyuncs.com/google_containers/pause:3.6 \"/pause\" 32 hours ago Up k8s://kube-system/etcd-cka001 Stop those up status containers. nerdctl -n k8s.io stop nerdctl -n k8s.io stop 0965b195f41a nerdctl -n k8s.io stop 9e1bea9f25d1 No up status etcd now. nerdctl -n k8s.io ps -a | grep etcd 0965b195f41a registry.aliyuncs.com/google_containers/etcd:3.5.1-0 \"etcd --advertise-cl\u2026\" 32 hours ago Created k8s://kube-system/etcd-cka001/etcd 9e1bea9f25d1 registry.aliyuncs.com/google_containers/pause:3.6 \"/pause\" 32 hours ago Created k8s://kube-system/etcd-cka001 Restore etcd \u00b6 Execute the restore operation on Control Plane node with actual backup file, here it's file snapshot-20220724185121.db . etcdctl snapshot restore snapshot-20220724185121.db \\ --endpoints=:2379 \\ --cert=/etc/kubernetes/pki/etcd/server.crt \\ --key=/etc/kubernetes/pki/etcd/server.key \\ --cacert=/etc/kubernetes/pki/etcd/ca.crt\\ --data-dir=/var/lib/etcd Output: Deprecated: Use `etcdutl snapshot restore` instead. 2022-07-24T18:57:49+08:00 info snapshot/v3_snapshot.go:248 restoring snapshot {\"path\": \"snapshot-20220724185121.db\", \"wal-dir\": \"/var/lib/etcd/member/wal\", \"data-dir\": \"/var/lib/etcd\", \"snap-dir\": \"/var/lib/etcd/member/snap\", \"stack\": \"go.etcd.io/etcd/etcdutl/v3/snapshot.(*v3Manager).Restore\\n\\t/go/src/go.etcd.io/etcd/release/etcd/etcdutl/snapshot/v3_snapshot.go:254\\ngo.etcd.io/etcd/etcdutl/v3/etcdutl.SnapshotRestoreCommandFunc\\n\\t/go/src/go.etcd.io/etcd/release/etcd/etcdutl/etcdutl/snapshot_command.go:147\\ngo.etcd.io/etcd/etcdctl/v3/ctlv3/command.snapshotRestoreCommandFunc\\n\\t/go/src/go.etcd.io/etcd/release/etcd/etcdctl/ctlv3/command/snapshot_command.go:129\\ngithub.com/spf13/cobra.(*Command).execute\\n\\t/go/pkg/mod/github.com/spf13/cobra@v1.1.3/command.go:856\\ngithub.com/spf13/cobra.(*Command).ExecuteC\\n\\t/go/pkg/mod/github.com/spf13/cobra@v1.1.3/command.go:960\\ngithub.com/spf13/cobra.(*Command).Execute\\n\\t/go/pkg/mod/github.com/spf13/cobra@v1.1.3/command.go:897\\ngo.etcd.io/etcd/etcdctl/v3/ctlv3.Start\\n\\t/go/src/go.etcd.io/etcd/release/etcd/etcdctl/ctlv3/ctl.go:107\\ngo.etcd.io/etcd/etcdctl/v3/ctlv3.MustStart\\n\\t/go/src/go.etcd.io/etcd/release/etcd/etcdctl/ctlv3/ctl.go:111\\nmain.main\\n\\t/go/src/go.etcd.io/etcd/release/etcd/etcdctl/main.go:59\\nruntime.main\\n\\t/go/gos/go1.16.15/src/runtime/proc.go:225\"} 2022-07-24T18:57:49+08:00 info membership/store.go:141 Trimming membership information from the backend... 2022-07-24T18:57:49+08:00 info membership/cluster.go:421 added member {\"cluster-id\": \"cdf818194e3a8c32\", \"local-member-id\": \"0\", \"added-peer-id\": \"8e9e05c52164694d\", \"added-peer-peer-urls\": [\"http://localhost:2380\"]} 2022-07-24T18:57:49+08:00 info snapshot/v3_snapshot.go:269 restored snapshot {\"path\": \"snapshot-20220724185121.db\", \"wal-dir\": \"/var/lib/etcd/member/wal\", \"data-dir\": \"/var/lib/etcd\", \"snap-dir\": \"/var/lib/etcd/member/snap\"} Check if etcd folder is back from restore. tree /var/lib/etcd /var/lib/etcd \u2514\u2500\u2500 member \u251c\u2500\u2500 snap \u2502 \u251c\u2500\u2500 0000000000000001-0000000000000001.snap \u2502 \u2514\u2500\u2500 db \u2514\u2500\u2500 wal \u2514\u2500\u2500 0000000000000000-0000000000000000.wal Start Services \u00b6 Start kubelet . The kube-apiserver and etcd will be started automatically by kubelet . systemctl start kubelet Execute below comamnds to make sure services are all up. systemctl status kubelet.service nerdctl -n k8s.io ps -a | grep etcd nerdctl -n k8s.io ps -a | grep apiserver The current status of etcd . 0965b195f41a registry.aliyuncs.com/google_containers/etcd:3.5.1-0 \"etcd --advertise-cl\u2026\" 32 hours ago Created k8s://kube-system/etcd-cka001/etcd 3b8f37c87782 registry.aliyuncs.com/google_containers/etcd:3.5.1-0 \"etcd --advertise-cl\u2026\" 6 seconds ago Up k8s://kube-system/etcd-cka001/etcd 9e1bea9f25d1 registry.aliyuncs.com/google_containers/pause:3.6 \"/pause\" 32 hours ago Created k8s://kube-system/etcd-cka001 fbbbb628a945 registry.aliyuncs.com/google_containers/pause:3.6 \"/pause\" 6 seconds ago Up k8s://kube-system/etcd-cka001 The current status of apiserver . 0c5e69118f1b registry.aliyuncs.com/google_containers/kube-apiserver:v1.24.0 \"kube-apiserver --ad\u2026\" 32 hours ago Created k8s://kube-system/kube-apiserver-cka001/kube-apiserver 281cf4c6670d registry.aliyuncs.com/google_containers/kube-apiserver:v1.24.0 \"kube-apiserver --ad\u2026\" 14 seconds ago Up k8s://kube-system/kube-apiserver-cka001/kube-apiserver 5ed8295d92da registry.aliyuncs.com/google_containers/pause:3.6 \"/pause\" 15 seconds ago Up k8s://kube-system/kube-apiserver-cka001 638bb602c310 registry.aliyuncs.com/google_containers/pause:3.6 \"/pause\" 32 hours ago Created k8s://kube-system/kube-apiserver-cka001 Verify \u00b6 Check cluster status, if the Pod app-before-backup is there. kubectl get deploy Result NAME READY UP-TO-DATE AVAILABLE AGE app-before-backup 1/1 1 1 11m Upgrade \u00b6 Scenario: Upgrade Evict Control Plane node Check current available version of kubeadm Upgrade kubeadm to new version Check upgrade plan Apply upgrade plan to upgrade to new version Upgrade kubelet and kubectl Enable Control Plane node scheduling Evict Worker nodes Upgrade kubeadm and kubelet Enable Worker node scheduling Reference documentation Upgrade Control Plane \u00b6 Preparation \u00b6 Evict Control Plane node. kubectl drain --ignore-daemonsets kubectl drain cka001 --ignore-daemonsets node/cka001 cordoned WARNING: ignoring DaemonSet-managed Pods: kube-system/calico-node-dsx76, kube-system/kube-proxy-cm4hc evicting pod kube-system/calico-kube-controllers-5c64b68895-jr4nl evicting pod kube-system/coredns-6d8c4cb4d-g4jxc evicting pod kube-system/coredns-6d8c4cb4d-sqcvj pod/calico-kube-controllers-5c64b68895-jr4nl evicted pod/coredns-6d8c4cb4d-g4jxc evicted pod/coredns-6d8c4cb4d-sqcvj evicted node/cka001 drained The Control Plane node is now in SchedulingDisabled status. kubectl get node -owide Result NAME STATUS ROLES AGE VERSION OS-IMAGE KERNEL-VERSION CONTAINER-RUNTIME cka001 Ready,SchedulingDisabled control-plane,master 32h v1.24.0 Ubuntu 20.04.4 LTS 5.4.0-122-generic containerd://1.5.9 cka002 Ready 32h v1.24.0 Ubuntu 20.04.4 LTS 5.4.0-122-generic containerd://1.5.9 cka003 Ready 32h v1.24.0 Ubuntu 20.04.4 LTS 5.4.0-122-generic containerd://1.5.9 Check current available version of kubeadm . apt policy kubeadm kubeadm: Installed: 1.24.0-00 Candidate: 1.24.3-00 Version table: 1.24.3-00 500 500 https://mirrors.aliyun.com/kubernetes/apt kubernetes-xenial/main amd64 Packages 1.24.2-00 500 500 https://mirrors.aliyun.com/kubernetes/apt kubernetes-xenial/main amd64 Packages 1.24.1-00 500 500 https://mirrors.aliyun.com/kubernetes/apt kubernetes-xenial/main amd64 Packages 1.24.0-00 500 500 https://mirrors.aliyun.com/kubernetes/apt kubernetes-xenial/main amd64 Packages 1.24.2-00 500 500 https://mirrors.aliyun.com/kubernetes/apt kubernetes-xenial/main amd64 Packages *** 1.24.0-00 500 500 https://mirrors.aliyun.com/kubernetes/apt kubernetes-xenial/main amd64 Packages 100 /var/lib/dpkg/status 1.23.7-00 500 500 https://mirrors.aliyun.com/kubernetes/apt kubernetes-xenial/main amd64 Packages ...... Upgrade kubeadm to Candidate: 1.24.2-00 version. sudo apt-get -y install kubeadm=1.24.2-00 --allow-downgrades Check upgrade plan. kubeadm upgrade plan Get below guideline of upgrade. [upgrade/config] Making sure the configuration is correct: [upgrade/config] Reading configuration from the cluster... [upgrade/config] FYI: You can look at this config file with 'kubectl -n kube-system get cm kubeadm-config -o yaml' [preflight] Running pre-flight checks. [upgrade] Running cluster health checks [upgrade] Fetching available versions to upgrade to [upgrade/versions] Cluster version: v1.24.0 [upgrade/versions] kubeadm version: v1.24.2 I0724 19:05:00.111855 1142460 version.go:255] remote version is much newer: v1.24.3; falling back to: stable-1.23 [upgrade/versions] Target version: v1.24.2 [upgrade/versions] Latest version in the v1.23 series: v1.24.2 Components that must be upgraded manually after you have upgraded the control plane with 'kubeadm upgrade apply': COMPONENT CURRENT TARGET kubelet 3 x v1.24.0 v1.24.2 Upgrade to the latest version in the v1.23 series: COMPONENT CURRENT TARGET kube-apiserver v1.24.0 v1.24.2 kube-controller-manager v1.24.0 v1.24.2 kube-scheduler v1.24.0 v1.24.2 kube-proxy v1.24.0 v1.24.2 CoreDNS v1.8.6 v1.8.6 etcd 3.5.1-0 3.5.1-0 You can now apply the upgrade by executing the following command: kubeadm upgrade apply v1.24.2 _____________________________________________________________________ The table below shows the current state of component configs as understood by this version of kubeadm. Configs that have a \"yes\" mark in the \"MANUAL UPGRADE REQUIRED\" column require manual config upgrade or resetting to kubeadm defaults before a successful upgrade can be performed. The version to manually upgrade to is denoted in the \"PREFERRED VERSION\" column. API GROUP CURRENT VERSION PREFERRED VERSION MANUAL UPGRADE REQUIRED kubeproxy.config.k8s.io v1alpha1 v1alpha1 no kubelet.config.k8s.io v1beta1 v1beta1 no _____________________________________________________________________ Upgrade Control Plane \u00b6 Refer to upgrade plan, let's upgrade to v1.24.2 version. kubeadm upgrade apply v1.24.2 With option --etcd-upgrade=false , the etcd can be excluded from the upgrade. kubeadm upgrade apply v1.24.2 --etcd-upgrade=false It's successful when receiving below message. [upgrade/successful] SUCCESS! Your cluster was upgraded to \"v1.24.2\". Enjoy! [upgrade/kubelet] Now that your control plane is upgraded, please proceed with upgrading your kubelets if you haven't already done so. Upgrade kubelet and kubectl . sudo apt-get -y install kubelet=1.24.2-00 kubectl=1.24.2-00 --allow-downgrades sudo systemctl daemon-reload sudo systemctl restart kubelet Get current node status. kubectl get node NAME STATUS ROLES AGE VERSION cka001 Ready,SchedulingDisabled control-plane,master 32h v1.24.2 cka002 Ready 32h v1.24.0 cka003 Ready 32h v1.24.0 After verify that each node is in Ready status, enable node scheduling. kubectl uncordon kubectl uncordon cka001 Output: node/cka001 uncordoned Check node status again. Make sure all nodes are in Ready status. kubectl get node Output: NAME STATUS ROLES AGE VERSION cka001 Ready control-plane,master 32h v1.24.2 cka002 Ready 32h v1.24.0 cka003 Ready 32h v1.24.0 Upgrade Worker \u00b6 Preparation for Worker \u00b6 Log on to cka001 Evict Worker nodes, explicitly specify to remove local storage if needed. kubectl drain --ignore-daemonsets --force kubectl drain --ignore-daemonsets --delete-emptydir-data --force If have error on dependency of emptydir , use the 2 nd command. kubectl drain cka002 --ignore-daemonsets --force kubectl drain cka002 --ignore-daemonsets --delete-emptydir-data --force node/cka002 cordoned WARNING: deleting Pods not managed by ReplicationController, ReplicaSet, Job, DaemonSet or StatefulSet: dev/ubuntu; ignoring DaemonSet-managed Pods: kube-system/calico-node-p5rf2, kube-system/kube-proxy-zvs68 evicting pod ns-netpol/pod-netpol-5b67b6b496-2cgnw evicting pod dev/ubuntu evicting pod dev/app-before-backup-66dc9d5cb-6xc8c evicting pod dev/nfs-client-provisioner-86d7fb78b6-2f5dx evicting pod dev/pod-netpol-2-77478d77ff-l6rzm evicting pod ingress-nginx/ingress-nginx-admission-patch-nk9fv evicting pod ingress-nginx/ingress-nginx-admission-create-lgtdj evicting pod kube-system/coredns-6d8c4cb4d-l4kx4 pod/ingress-nginx-admission-create-lgtdj evicted pod/ingress-nginx-admission-patch-nk9fv evicted pod/nfs-client-provisioner-86d7fb78b6-2f5dx evicted pod/app-before-backup-66dc9d5cb-6xc8c evicted pod/coredns-6d8c4cb4d-l4kx4 evicted pod/pod-netpol-5b67b6b496-2cgnw evicted pod/pod-netpol-2-77478d77ff-l6rzm evicted pod/ubuntu evicted node/cka002 drained Upgrade Workers \u00b6 Log on to cka002 . Download kubeadm with version v1.24.2 . sudo apt-get -y install kubeadm=1.24.2-00 --allow-downgrades Upgrade kubeadm . sudo kubeadm upgrade node Upgrade kubelet . sudo apt-get -y install kubelet=1.24.2-00 --allow-downgrades sudo systemctl daemon-reload sudo systemctl restart kubelet Make sure all nodes are in Ready status, then, enable node scheduling. kubectl uncordon kubectl uncordon cka002 Verify Upgrade \u00b6 Check node status. kubectl get node Result NAME STATUS ROLES AGE VERSION cka001 Ready control-plane,master 32h v1.24.2 cka002 Ready 32h v1.24.2 cka003 Ready 32h v1.24.0 Repeat the same on node cka003 . Log onto cka001 . If have error on dependency of emptydir , use the 2 nd command. kubectl drain cka003 --ignore-daemonsets --ignore-daemonsets --force kubectl drain cka003 --ignore-daemonsets --ignore-daemonsets --delete-emptydir-data --force Log onto cka003 and perform below commands. sudo apt-get -y install kubeadm=1.24.2-00 --allow-downgrades sudo kubeadm upgrade node sudo apt-get -y install kubelet=1.24.2-00 --allow-downgrades sudo systemctl daemon-reload sudo systemctl restart kubelet kubectl get node kubectl uncordon cka003 Get final status of all nodes. kubectl get node NAME STATUS ROLES AGE VERSION cka001 Ready control-plane,master 32h v1.24.2 cka002 Ready 32h v1.24.2 cka003 Ready 32h v1.24.2 Summary: Control Plane kubectl get node -owide kubectl drain cka001 --ignore-daemonsets kubectl get node -owide apt policy kubeadm apt-get -y install kubeadm=1.24.0-00 --allow-downgrades kubeadm upgrade plan kubeadm upgrade apply v1.24.0 # kubeadm upgrade apply v1.24.0 --etcd-upgrade = false apt-get -y install kubelet=1.24.0-00 kubectl=1.24.0-00 --allow-downgrades systemctl daemon-reload systemctl restart kubelet kubectl get node kubectl uncordon cka001 Worker Node On Control Plane kubectl drain cka002 --ignore-daemonsets On Workder Node apt-get -y install kubeadm=1.24.1-00 --allow-downgrades kubeadm upgrade node apt-get -y install kubelet=1.24.1-00 --allow-downgrades systemctl daemon-reload systemctl restart kubelet kubectl uncordon cka002 Repeat for other Worker nodes","title":"Cluster Management"},{"location":"k8s/cka_en/foundamentals/clustermgt/#cluster-management","text":"Scenario: etcd Backup and Restore Install etcdctl Create Deployment Before Backup Backup etcd Create Deployment After Backup Stop Services Stop etcd Restore etcd Start Services Verify","title":"Cluster Management"},{"location":"k8s/cka_en/foundamentals/clustermgt/#etcd-backup-and-restore","text":"","title":"etcd Backup and Restore"},{"location":"k8s/cka_en/foundamentals/clustermgt/#install-etcdctl","text":"Download etcd package from Github. wget https://github.com/etcd-io/etcd/releases/download/v3.5.3/etcd-v3.5.3-linux-amd64.tar.gz Unzip and grant execute permission. tar -zxvf etcd-v3.5.3-linux-amd64.tar.gz cp etcd-v3.5.3-linux-amd64/etcdctl /usr/local/bin/ sudo chmod u+x /usr/local/bin/etcdctl Verify etcdctl --help","title":"Install etcdctl"},{"location":"k8s/cka_en/foundamentals/clustermgt/#create-deployment-before-backup","text":"Create Deployment before backup. kubectl create deployment app-before-backup --image=nginx","title":"Create Deployment Before Backup"},{"location":"k8s/cka_en/foundamentals/clustermgt/#backup-etcd","text":"Usage * is the actual IP address of Control Plane. * --endpoints : specify where to save backup of etcd, 2379 is etcd port. * --cert : sepcify etcd certificate, which was generated by kubeadm and saved in /etc/kubernetes/pki/etcd/ . * --key : specify etcd certificate key, which was generated by kubeadm and saved in /etc/kubernetes/pki/etcd/ . * --cacert : specify etcd certificate CA, which was generated by kubeadm and saved in /etc/kubernetes/pki/etcd/ . etcdctl \\ --endpoints=https://:2379 \\ --cert=/etc/kubernetes/pki/etcd/server.crt \\ --key=/etc/kubernetes/pki/etcd/server.key \\ --cacert=/etc/kubernetes/pki/etcd/ca.crt \\ snapshot save snapshot-$(date +\"%Y%m%d%H%M%S\").db etcdctl \\ --endpoints=https://:2379 \\ --cert=/etc/kubernetes/pki/etcd/server.crt \\ --key=/etc/kubernetes/pki/etcd/server.key \\ --cacert=/etc/kubernetes/pki/etcd/ca.crt \\ snapshot save snapshot-$(date +\"%Y%m%d%H%M%S\").db Output: {\"level\":\"info\",\"ts\":\"2022-07-24T18:51:21.328+0800\",\"caller\":\"snapshot/v3_snapshot.go:65\",\"msg\":\"created temporary db file\",\"path\":\"snapshot-20220724185121.db.part\"} {\"level\":\"info\",\"ts\":\"2022-07-24T18:51:21.337+0800\",\"logger\":\"client\",\"caller\":\"v3/maintenance.go:211\",\"msg\":\"opened snapshot stream; downloading\"} {\"level\":\"info\",\"ts\":\"2022-07-24T18:51:21.337+0800\",\"caller\":\"snapshot/v3_snapshot.go:73\",\"msg\":\"fetching snapshot\",\"endpoint\":\"https://:2379\"} {\"level\":\"info\",\"ts\":\"2022-07-24T18:51:21.415+0800\",\"logger\":\"client\",\"caller\":\"v3/maintenance.go:219\",\"msg\":\"completed snapshot read; closing\"} {\"level\":\"info\",\"ts\":\"2022-07-24T18:51:21.477+0800\",\"caller\":\"snapshot/v3_snapshot.go:88\",\"msg\":\"fetched snapshot\",\"endpoint\":\"https://:2379\",\"size\":\"3.6 MB\",\"took\":\"now\"} {\"level\":\"info\",\"ts\":\"2022-07-24T18:51:21.477+0800\",\"caller\":\"snapshot/v3_snapshot.go:97\",\"msg\":\"saved\",\"path\":\"snapshot-20220724185121.db\"} Snapshot saved at snapshot-20220724185121.db We can get the backup file in current directory with ls -al command. -rw------- 1 root root 3616800 Jul 24 18:51 snapshot-20220724185121.db","title":"Backup etcd"},{"location":"k8s/cka_en/foundamentals/clustermgt/#create-deployment-after-backup","text":"Create Deployment after backup. kubectl create deployment app-after-backup --image=nginx Delete Deployment we created before backup. kubectl delete deployment app-before-backup Check Deployment status kubectl get deploy NAME READY UP-TO-DATE AVAILABLE AGE app-after-backup 1/1 1 1 108s","title":"Create Deployment After Backup"},{"location":"k8s/cka_en/foundamentals/clustermgt/#stop-services","text":"Delete etcd directory. mv /var/lib/etcd/ /var/lib/etcd.bak Stop kubelet systemctl stop kubelet Stop kube-apiserver nerdctl -n k8s.io ps -a | grep apiserver 0c5e69118f1b registry.aliyuncs.com/google_containers/kube-apiserver:v1.24.0 \"kube-apiserver --ad\u2026\" 32 hours ago Up k8s://kube-system/kube-apiserver-cka001/kube-apiserver 638bb602c310 registry.aliyuncs.com/google_containers/pause:3.6 \"/pause\" 32 hours ago Up k8s://kube-system/kube-apiserver-cka001 Stop those up status containers. nerdctl -n k8s.io stop nerdctl -n k8s.io stop 0c5e69118f1b nerdctl -n k8s.io stop 638bb602c310 No up status kube-apiserver now. nerdctl -n k8s.io ps -a | grep apiserver 0c5e69118f1b registry.aliyuncs.com/google_containers/kube-apiserver:v1.24.0 \"kube-apiserver --ad\u2026\" 32 hours ago Created k8s://kube-system/kube-apiserver-cka001/kube-apiserver 638bb602c310 registry.aliyuncs.com/google_containers/pause:3.6 \"/pause\" 32 hours ago Created k8s://kube-system/kube-apiserver-cka001","title":"Stop Services"},{"location":"k8s/cka_en/foundamentals/clustermgt/#stop-etcd","text":"nerdctl -n k8s.io ps -a | grep etcd 0965b195f41a registry.aliyuncs.com/google_containers/etcd:3.5.1-0 \"etcd --advertise-cl\u2026\" 32 hours ago Up k8s://kube-system/etcd-cka001/etcd 9e1bea9f25d1 registry.aliyuncs.com/google_containers/pause:3.6 \"/pause\" 32 hours ago Up k8s://kube-system/etcd-cka001 Stop those up status containers. nerdctl -n k8s.io stop nerdctl -n k8s.io stop 0965b195f41a nerdctl -n k8s.io stop 9e1bea9f25d1 No up status etcd now. nerdctl -n k8s.io ps -a | grep etcd 0965b195f41a registry.aliyuncs.com/google_containers/etcd:3.5.1-0 \"etcd --advertise-cl\u2026\" 32 hours ago Created k8s://kube-system/etcd-cka001/etcd 9e1bea9f25d1 registry.aliyuncs.com/google_containers/pause:3.6 \"/pause\" 32 hours ago Created k8s://kube-system/etcd-cka001","title":"Stop etcd"},{"location":"k8s/cka_en/foundamentals/clustermgt/#restore-etcd","text":"Execute the restore operation on Control Plane node with actual backup file, here it's file snapshot-20220724185121.db . etcdctl snapshot restore snapshot-20220724185121.db \\ --endpoints=:2379 \\ --cert=/etc/kubernetes/pki/etcd/server.crt \\ --key=/etc/kubernetes/pki/etcd/server.key \\ --cacert=/etc/kubernetes/pki/etcd/ca.crt\\ --data-dir=/var/lib/etcd Output: Deprecated: Use `etcdutl snapshot restore` instead. 2022-07-24T18:57:49+08:00 info snapshot/v3_snapshot.go:248 restoring snapshot {\"path\": \"snapshot-20220724185121.db\", \"wal-dir\": \"/var/lib/etcd/member/wal\", \"data-dir\": \"/var/lib/etcd\", \"snap-dir\": \"/var/lib/etcd/member/snap\", \"stack\": \"go.etcd.io/etcd/etcdutl/v3/snapshot.(*v3Manager).Restore\\n\\t/go/src/go.etcd.io/etcd/release/etcd/etcdutl/snapshot/v3_snapshot.go:254\\ngo.etcd.io/etcd/etcdutl/v3/etcdutl.SnapshotRestoreCommandFunc\\n\\t/go/src/go.etcd.io/etcd/release/etcd/etcdutl/etcdutl/snapshot_command.go:147\\ngo.etcd.io/etcd/etcdctl/v3/ctlv3/command.snapshotRestoreCommandFunc\\n\\t/go/src/go.etcd.io/etcd/release/etcd/etcdctl/ctlv3/command/snapshot_command.go:129\\ngithub.com/spf13/cobra.(*Command).execute\\n\\t/go/pkg/mod/github.com/spf13/cobra@v1.1.3/command.go:856\\ngithub.com/spf13/cobra.(*Command).ExecuteC\\n\\t/go/pkg/mod/github.com/spf13/cobra@v1.1.3/command.go:960\\ngithub.com/spf13/cobra.(*Command).Execute\\n\\t/go/pkg/mod/github.com/spf13/cobra@v1.1.3/command.go:897\\ngo.etcd.io/etcd/etcdctl/v3/ctlv3.Start\\n\\t/go/src/go.etcd.io/etcd/release/etcd/etcdctl/ctlv3/ctl.go:107\\ngo.etcd.io/etcd/etcdctl/v3/ctlv3.MustStart\\n\\t/go/src/go.etcd.io/etcd/release/etcd/etcdctl/ctlv3/ctl.go:111\\nmain.main\\n\\t/go/src/go.etcd.io/etcd/release/etcd/etcdctl/main.go:59\\nruntime.main\\n\\t/go/gos/go1.16.15/src/runtime/proc.go:225\"} 2022-07-24T18:57:49+08:00 info membership/store.go:141 Trimming membership information from the backend... 2022-07-24T18:57:49+08:00 info membership/cluster.go:421 added member {\"cluster-id\": \"cdf818194e3a8c32\", \"local-member-id\": \"0\", \"added-peer-id\": \"8e9e05c52164694d\", \"added-peer-peer-urls\": [\"http://localhost:2380\"]} 2022-07-24T18:57:49+08:00 info snapshot/v3_snapshot.go:269 restored snapshot {\"path\": \"snapshot-20220724185121.db\", \"wal-dir\": \"/var/lib/etcd/member/wal\", \"data-dir\": \"/var/lib/etcd\", \"snap-dir\": \"/var/lib/etcd/member/snap\"} Check if etcd folder is back from restore. tree /var/lib/etcd /var/lib/etcd \u2514\u2500\u2500 member \u251c\u2500\u2500 snap \u2502 \u251c\u2500\u2500 0000000000000001-0000000000000001.snap \u2502 \u2514\u2500\u2500 db \u2514\u2500\u2500 wal \u2514\u2500\u2500 0000000000000000-0000000000000000.wal","title":"Restore etcd"},{"location":"k8s/cka_en/foundamentals/clustermgt/#start-services","text":"Start kubelet . The kube-apiserver and etcd will be started automatically by kubelet . systemctl start kubelet Execute below comamnds to make sure services are all up. systemctl status kubelet.service nerdctl -n k8s.io ps -a | grep etcd nerdctl -n k8s.io ps -a | grep apiserver The current status of etcd . 0965b195f41a registry.aliyuncs.com/google_containers/etcd:3.5.1-0 \"etcd --advertise-cl\u2026\" 32 hours ago Created k8s://kube-system/etcd-cka001/etcd 3b8f37c87782 registry.aliyuncs.com/google_containers/etcd:3.5.1-0 \"etcd --advertise-cl\u2026\" 6 seconds ago Up k8s://kube-system/etcd-cka001/etcd 9e1bea9f25d1 registry.aliyuncs.com/google_containers/pause:3.6 \"/pause\" 32 hours ago Created k8s://kube-system/etcd-cka001 fbbbb628a945 registry.aliyuncs.com/google_containers/pause:3.6 \"/pause\" 6 seconds ago Up k8s://kube-system/etcd-cka001 The current status of apiserver . 0c5e69118f1b registry.aliyuncs.com/google_containers/kube-apiserver:v1.24.0 \"kube-apiserver --ad\u2026\" 32 hours ago Created k8s://kube-system/kube-apiserver-cka001/kube-apiserver 281cf4c6670d registry.aliyuncs.com/google_containers/kube-apiserver:v1.24.0 \"kube-apiserver --ad\u2026\" 14 seconds ago Up k8s://kube-system/kube-apiserver-cka001/kube-apiserver 5ed8295d92da registry.aliyuncs.com/google_containers/pause:3.6 \"/pause\" 15 seconds ago Up k8s://kube-system/kube-apiserver-cka001 638bb602c310 registry.aliyuncs.com/google_containers/pause:3.6 \"/pause\" 32 hours ago Created k8s://kube-system/kube-apiserver-cka001","title":"Start Services"},{"location":"k8s/cka_en/foundamentals/clustermgt/#verify","text":"Check cluster status, if the Pod app-before-backup is there. kubectl get deploy Result NAME READY UP-TO-DATE AVAILABLE AGE app-before-backup 1/1 1 1 11m","title":"Verify"},{"location":"k8s/cka_en/foundamentals/clustermgt/#upgrade","text":"Scenario: Upgrade Evict Control Plane node Check current available version of kubeadm Upgrade kubeadm to new version Check upgrade plan Apply upgrade plan to upgrade to new version Upgrade kubelet and kubectl Enable Control Plane node scheduling Evict Worker nodes Upgrade kubeadm and kubelet Enable Worker node scheduling Reference documentation","title":"Upgrade"},{"location":"k8s/cka_en/foundamentals/clustermgt/#upgrade-control-plane","text":"","title":"Upgrade Control Plane"},{"location":"k8s/cka_en/foundamentals/clustermgt/#preparation","text":"Evict Control Plane node. kubectl drain --ignore-daemonsets kubectl drain cka001 --ignore-daemonsets node/cka001 cordoned WARNING: ignoring DaemonSet-managed Pods: kube-system/calico-node-dsx76, kube-system/kube-proxy-cm4hc evicting pod kube-system/calico-kube-controllers-5c64b68895-jr4nl evicting pod kube-system/coredns-6d8c4cb4d-g4jxc evicting pod kube-system/coredns-6d8c4cb4d-sqcvj pod/calico-kube-controllers-5c64b68895-jr4nl evicted pod/coredns-6d8c4cb4d-g4jxc evicted pod/coredns-6d8c4cb4d-sqcvj evicted node/cka001 drained The Control Plane node is now in SchedulingDisabled status. kubectl get node -owide Result NAME STATUS ROLES AGE VERSION OS-IMAGE KERNEL-VERSION CONTAINER-RUNTIME cka001 Ready,SchedulingDisabled control-plane,master 32h v1.24.0 Ubuntu 20.04.4 LTS 5.4.0-122-generic containerd://1.5.9 cka002 Ready 32h v1.24.0 Ubuntu 20.04.4 LTS 5.4.0-122-generic containerd://1.5.9 cka003 Ready 32h v1.24.0 Ubuntu 20.04.4 LTS 5.4.0-122-generic containerd://1.5.9 Check current available version of kubeadm . apt policy kubeadm kubeadm: Installed: 1.24.0-00 Candidate: 1.24.3-00 Version table: 1.24.3-00 500 500 https://mirrors.aliyun.com/kubernetes/apt kubernetes-xenial/main amd64 Packages 1.24.2-00 500 500 https://mirrors.aliyun.com/kubernetes/apt kubernetes-xenial/main amd64 Packages 1.24.1-00 500 500 https://mirrors.aliyun.com/kubernetes/apt kubernetes-xenial/main amd64 Packages 1.24.0-00 500 500 https://mirrors.aliyun.com/kubernetes/apt kubernetes-xenial/main amd64 Packages 1.24.2-00 500 500 https://mirrors.aliyun.com/kubernetes/apt kubernetes-xenial/main amd64 Packages *** 1.24.0-00 500 500 https://mirrors.aliyun.com/kubernetes/apt kubernetes-xenial/main amd64 Packages 100 /var/lib/dpkg/status 1.23.7-00 500 500 https://mirrors.aliyun.com/kubernetes/apt kubernetes-xenial/main amd64 Packages ...... Upgrade kubeadm to Candidate: 1.24.2-00 version. sudo apt-get -y install kubeadm=1.24.2-00 --allow-downgrades Check upgrade plan. kubeadm upgrade plan Get below guideline of upgrade. [upgrade/config] Making sure the configuration is correct: [upgrade/config] Reading configuration from the cluster... [upgrade/config] FYI: You can look at this config file with 'kubectl -n kube-system get cm kubeadm-config -o yaml' [preflight] Running pre-flight checks. [upgrade] Running cluster health checks [upgrade] Fetching available versions to upgrade to [upgrade/versions] Cluster version: v1.24.0 [upgrade/versions] kubeadm version: v1.24.2 I0724 19:05:00.111855 1142460 version.go:255] remote version is much newer: v1.24.3; falling back to: stable-1.23 [upgrade/versions] Target version: v1.24.2 [upgrade/versions] Latest version in the v1.23 series: v1.24.2 Components that must be upgraded manually after you have upgraded the control plane with 'kubeadm upgrade apply': COMPONENT CURRENT TARGET kubelet 3 x v1.24.0 v1.24.2 Upgrade to the latest version in the v1.23 series: COMPONENT CURRENT TARGET kube-apiserver v1.24.0 v1.24.2 kube-controller-manager v1.24.0 v1.24.2 kube-scheduler v1.24.0 v1.24.2 kube-proxy v1.24.0 v1.24.2 CoreDNS v1.8.6 v1.8.6 etcd 3.5.1-0 3.5.1-0 You can now apply the upgrade by executing the following command: kubeadm upgrade apply v1.24.2 _____________________________________________________________________ The table below shows the current state of component configs as understood by this version of kubeadm. Configs that have a \"yes\" mark in the \"MANUAL UPGRADE REQUIRED\" column require manual config upgrade or resetting to kubeadm defaults before a successful upgrade can be performed. The version to manually upgrade to is denoted in the \"PREFERRED VERSION\" column. API GROUP CURRENT VERSION PREFERRED VERSION MANUAL UPGRADE REQUIRED kubeproxy.config.k8s.io v1alpha1 v1alpha1 no kubelet.config.k8s.io v1beta1 v1beta1 no _____________________________________________________________________","title":"Preparation"},{"location":"k8s/cka_en/foundamentals/clustermgt/#upgrade-control-plane_1","text":"Refer to upgrade plan, let's upgrade to v1.24.2 version. kubeadm upgrade apply v1.24.2 With option --etcd-upgrade=false , the etcd can be excluded from the upgrade. kubeadm upgrade apply v1.24.2 --etcd-upgrade=false It's successful when receiving below message. [upgrade/successful] SUCCESS! Your cluster was upgraded to \"v1.24.2\". Enjoy! [upgrade/kubelet] Now that your control plane is upgraded, please proceed with upgrading your kubelets if you haven't already done so. Upgrade kubelet and kubectl . sudo apt-get -y install kubelet=1.24.2-00 kubectl=1.24.2-00 --allow-downgrades sudo systemctl daemon-reload sudo systemctl restart kubelet Get current node status. kubectl get node NAME STATUS ROLES AGE VERSION cka001 Ready,SchedulingDisabled control-plane,master 32h v1.24.2 cka002 Ready 32h v1.24.0 cka003 Ready 32h v1.24.0 After verify that each node is in Ready status, enable node scheduling. kubectl uncordon kubectl uncordon cka001 Output: node/cka001 uncordoned Check node status again. Make sure all nodes are in Ready status. kubectl get node Output: NAME STATUS ROLES AGE VERSION cka001 Ready control-plane,master 32h v1.24.2 cka002 Ready 32h v1.24.0 cka003 Ready 32h v1.24.0","title":"Upgrade Control Plane"},{"location":"k8s/cka_en/foundamentals/clustermgt/#upgrade-worker","text":"","title":"Upgrade Worker"},{"location":"k8s/cka_en/foundamentals/clustermgt/#preparation-for-worker","text":"Log on to cka001 Evict Worker nodes, explicitly specify to remove local storage if needed. kubectl drain --ignore-daemonsets --force kubectl drain --ignore-daemonsets --delete-emptydir-data --force If have error on dependency of emptydir , use the 2 nd command. kubectl drain cka002 --ignore-daemonsets --force kubectl drain cka002 --ignore-daemonsets --delete-emptydir-data --force node/cka002 cordoned WARNING: deleting Pods not managed by ReplicationController, ReplicaSet, Job, DaemonSet or StatefulSet: dev/ubuntu; ignoring DaemonSet-managed Pods: kube-system/calico-node-p5rf2, kube-system/kube-proxy-zvs68 evicting pod ns-netpol/pod-netpol-5b67b6b496-2cgnw evicting pod dev/ubuntu evicting pod dev/app-before-backup-66dc9d5cb-6xc8c evicting pod dev/nfs-client-provisioner-86d7fb78b6-2f5dx evicting pod dev/pod-netpol-2-77478d77ff-l6rzm evicting pod ingress-nginx/ingress-nginx-admission-patch-nk9fv evicting pod ingress-nginx/ingress-nginx-admission-create-lgtdj evicting pod kube-system/coredns-6d8c4cb4d-l4kx4 pod/ingress-nginx-admission-create-lgtdj evicted pod/ingress-nginx-admission-patch-nk9fv evicted pod/nfs-client-provisioner-86d7fb78b6-2f5dx evicted pod/app-before-backup-66dc9d5cb-6xc8c evicted pod/coredns-6d8c4cb4d-l4kx4 evicted pod/pod-netpol-5b67b6b496-2cgnw evicted pod/pod-netpol-2-77478d77ff-l6rzm evicted pod/ubuntu evicted node/cka002 drained","title":"Preparation for Worker"},{"location":"k8s/cka_en/foundamentals/clustermgt/#upgrade-workers","text":"Log on to cka002 . Download kubeadm with version v1.24.2 . sudo apt-get -y install kubeadm=1.24.2-00 --allow-downgrades Upgrade kubeadm . sudo kubeadm upgrade node Upgrade kubelet . sudo apt-get -y install kubelet=1.24.2-00 --allow-downgrades sudo systemctl daemon-reload sudo systemctl restart kubelet Make sure all nodes are in Ready status, then, enable node scheduling. kubectl uncordon kubectl uncordon cka002","title":"Upgrade Workers"},{"location":"k8s/cka_en/foundamentals/clustermgt/#verify-upgrade","text":"Check node status. kubectl get node Result NAME STATUS ROLES AGE VERSION cka001 Ready control-plane,master 32h v1.24.2 cka002 Ready 32h v1.24.2 cka003 Ready 32h v1.24.0 Repeat the same on node cka003 . Log onto cka001 . If have error on dependency of emptydir , use the 2 nd command. kubectl drain cka003 --ignore-daemonsets --ignore-daemonsets --force kubectl drain cka003 --ignore-daemonsets --ignore-daemonsets --delete-emptydir-data --force Log onto cka003 and perform below commands. sudo apt-get -y install kubeadm=1.24.2-00 --allow-downgrades sudo kubeadm upgrade node sudo apt-get -y install kubelet=1.24.2-00 --allow-downgrades sudo systemctl daemon-reload sudo systemctl restart kubelet kubectl get node kubectl uncordon cka003 Get final status of all nodes. kubectl get node NAME STATUS ROLES AGE VERSION cka001 Ready control-plane,master 32h v1.24.2 cka002 Ready 32h v1.24.2 cka003 Ready 32h v1.24.2 Summary: Control Plane kubectl get node -owide kubectl drain cka001 --ignore-daemonsets kubectl get node -owide apt policy kubeadm apt-get -y install kubeadm=1.24.0-00 --allow-downgrades kubeadm upgrade plan kubeadm upgrade apply v1.24.0 # kubeadm upgrade apply v1.24.0 --etcd-upgrade = false apt-get -y install kubelet=1.24.0-00 kubectl=1.24.0-00 --allow-downgrades systemctl daemon-reload systemctl restart kubelet kubectl get node kubectl uncordon cka001 Worker Node On Control Plane kubectl drain cka002 --ignore-daemonsets On Workder Node apt-get -y install kubeadm=1.24.1-00 --allow-downgrades kubeadm upgrade node apt-get -y install kubelet=1.24.1-00 --allow-downgrades systemctl daemon-reload systemctl restart kubelet kubectl uncordon cka002 Repeat for other Worker nodes","title":"Verify Upgrade"},{"location":"k8s/cka_en/foundamentals/configuration/","text":"","title":"Configuration"},{"location":"k8s/cka_en/foundamentals/daemonset/","text":"DaemonSet \u00b6 Scenario: Create DaemonSet. The DaemonSet will run its pod on each node. Demo: Create DaemonSet daemonset-busybox . kubectl apply -f - << EOF apiVersion: apps/v1 kind: DaemonSet metadata: name: daemonset-busybox labels: app: daemonset-busybox spec: selector: matchLabels: app: daemonset-busybox template: metadata: labels: app: daemonset-busybox spec: tolerations: - key: node-role.kubernetes.io/control-plane effect: NoSchedule - key: node-role.kubernetes.io/master effect: NoSchedule containers: - name: busybox image: busybox:1.28 args: - sleep - \"10000\" EOF Get status of DaemonSet. kubectl get daemonsets daemonset-busybox Result NAME DESIRED CURRENT READY UP-TO-DATE AVAILABLE NODE SELECTOR AGE daemonset-busybox 3 3 3 3 3 5m33s Get DaemonSet Pod status. It's deployed on each node. kubectl get pod -o wide Result NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES daemonset-busybox-54cj5 1/1 Running 0 44s 10.244.102.4 cka003 daemonset-busybox-5tl55 1/1 Running 0 44s 10.244.228.197 cka001 daemonset-busybox-wg225 1/1 Running 0 44s 10.244.112.5 cka002 Clean up. kubectl delete daemonset daemonset-busybox","title":"DaemonSet"},{"location":"k8s/cka_en/foundamentals/daemonset/#daemonset","text":"Scenario: Create DaemonSet. The DaemonSet will run its pod on each node. Demo: Create DaemonSet daemonset-busybox . kubectl apply -f - << EOF apiVersion: apps/v1 kind: DaemonSet metadata: name: daemonset-busybox labels: app: daemonset-busybox spec: selector: matchLabels: app: daemonset-busybox template: metadata: labels: app: daemonset-busybox spec: tolerations: - key: node-role.kubernetes.io/control-plane effect: NoSchedule - key: node-role.kubernetes.io/master effect: NoSchedule containers: - name: busybox image: busybox:1.28 args: - sleep - \"10000\" EOF Get status of DaemonSet. kubectl get daemonsets daemonset-busybox Result NAME DESIRED CURRENT READY UP-TO-DATE AVAILABLE NODE SELECTOR AGE daemonset-busybox 3 3 3 3 3 5m33s Get DaemonSet Pod status. It's deployed on each node. kubectl get pod -o wide Result NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES daemonset-busybox-54cj5 1/1 Running 0 44s 10.244.102.4 cka003 daemonset-busybox-5tl55 1/1 Running 0 44s 10.244.228.197 cka001 daemonset-busybox-wg225 1/1 Running 0 44s 10.244.112.5 cka002 Clean up. kubectl delete daemonset daemonset-busybox","title":"DaemonSet"},{"location":"k8s/cka_en/foundamentals/deployment/","text":"Deployment \u00b6 Scenario: Modify Existing Deployment, e.g., add port number in below demo. Demo: Create Deployment nginx . kubectl create deployment nginx --image = nginx Execute command below to get yaml template with port number. The option --port=8080 specified the port that this container exposes. kubectl create deployment nginx --image = nginx --port = 8080 --dry-run = client -o yaml Then we get to know the path to add port number, like below. kubectl explain deployment.spec.template.spec.containers.ports.containerPort Execute command below to edit the Deployemnt. kubectl edit deployment nginx Add below two lines to specify port number with 8080 and protocol is TCP . spec : template : spec : containers : - image : nginx name : nginx ports : - containerPort : 8080 protocol : TCP Use command kubectl describe deployment , we can see the port number was added. Pod Template : Labels : app=nginx Containers : nginx : Image : nginx Port : 8080/TCP Host Port : 0/TCP Environment : Mounts : Volumes : With command kubectl describe pod , we can see the port number was added. Containers : nginx : Container ID : containerd://af4a1243f981497074b5c006ac55fcf795688399871d1dfe91a095321f5c91aa Image : nginx Image ID : docker.io/library/nginx@sha256:1761fb5661e4d77e107427d8012ad3a5955007d997e0f4a3d41acc9ff20467c7 Port : 8080/TCP Host Port : 0/TCP State : Running Started : Sun, 24 Jul 2022 22:50:12 +0800 Ready : True Restart Count : 0 Environment : Mounts : /var/run/secrets/kubernetes.io/serviceaccount from kube-api-access-hftdt (ro) Info: Some key fields of deployment (use kubectl explain ): deployment.spec.revisionHistoryLimit : The number of old ReplicaSets to retain to allow rollback. Defaults to 10 . deployment.spec.strategy.type : Type of deployment. Can be Recreate or RollingUpdate . Default is RollingUpdate . deployment.spec.strategy.rollingUpdate.maxUnavailable : The maximum number of pods that can be unavailable during the update. Defaults to 25%. deployment.spec.strategy.rollingUpdate.maxSurge : The maximum number of pods that can be scheduled above the desired number of pods. Defaults to 25%. This can not be 0 if MaxUnavailable is 0. deployment.spec.minReadySeconds : Minimum number of seconds for which a newly created pod should be ready without any of its container crashing, for it to be considered available. Defaults to 0 (pod will be considered available as soon as it is ready).","title":"Deployment"},{"location":"k8s/cka_en/foundamentals/deployment/#deployment","text":"Scenario: Modify Existing Deployment, e.g., add port number in below demo. Demo: Create Deployment nginx . kubectl create deployment nginx --image = nginx Execute command below to get yaml template with port number. The option --port=8080 specified the port that this container exposes. kubectl create deployment nginx --image = nginx --port = 8080 --dry-run = client -o yaml Then we get to know the path to add port number, like below. kubectl explain deployment.spec.template.spec.containers.ports.containerPort Execute command below to edit the Deployemnt. kubectl edit deployment nginx Add below two lines to specify port number with 8080 and protocol is TCP . spec : template : spec : containers : - image : nginx name : nginx ports : - containerPort : 8080 protocol : TCP Use command kubectl describe deployment , we can see the port number was added. Pod Template : Labels : app=nginx Containers : nginx : Image : nginx Port : 8080/TCP Host Port : 0/TCP Environment : Mounts : Volumes : With command kubectl describe pod , we can see the port number was added. Containers : nginx : Container ID : containerd://af4a1243f981497074b5c006ac55fcf795688399871d1dfe91a095321f5c91aa Image : nginx Image ID : docker.io/library/nginx@sha256:1761fb5661e4d77e107427d8012ad3a5955007d997e0f4a3d41acc9ff20467c7 Port : 8080/TCP Host Port : 0/TCP State : Running Started : Sun, 24 Jul 2022 22:50:12 +0800 Ready : True Restart Count : 0 Environment : Mounts : /var/run/secrets/kubernetes.io/serviceaccount from kube-api-access-hftdt (ro) Info: Some key fields of deployment (use kubectl explain ): deployment.spec.revisionHistoryLimit : The number of old ReplicaSets to retain to allow rollback. Defaults to 10 . deployment.spec.strategy.type : Type of deployment. Can be Recreate or RollingUpdate . Default is RollingUpdate . deployment.spec.strategy.rollingUpdate.maxUnavailable : The maximum number of pods that can be unavailable during the update. Defaults to 25%. deployment.spec.strategy.rollingUpdate.maxSurge : The maximum number of pods that can be scheduled above the desired number of pods. Defaults to 25%. This can not be 0 if MaxUnavailable is 0. deployment.spec.minReadySeconds : Minimum number of seconds for which a newly created pod should be ready without any of its container crashing, for it to be considered available. Defaults to 0 (pod will be considered available as soon as it is ready).","title":"Deployment"},{"location":"k8s/cka_en/foundamentals/docker/","text":"Docker Fundamentals \u00b6 Demo environment \u00b6 Linux: openSUSE 15.3 cat /etc/os-release Output NAME=\"openSUSE Leap\" VERSION=\"15.3\" ID=\"opensuse-leap\" ID_LIKE=\"suse opensuse\" VERSION_ID=\"15.3\" PRETTY_NAME=\"openSUSE Leap 15.3\" ANSI_COLOR=\"0;32\" CPE_NAME=\"cpe:/o:opensuse:leap:15.3\" BUG_REPORT_URL=\"https://bugs.opensuse.org\" HOME_URL=\"https://www.opensuse.org/\" Linux Primitives \u00b6 chroot(using pivot_root) Changes the root directory for a process to any given directory namespaces Different processes see different environments even though they are on the same host/OS mnt (mount points) pid (process tree) net (network interfaces and connectivity) ipc (interprocess communication framework) uts (unix timesharing - domain name, hostname, etc.) uid (user IDs and mappings) cgroups(control groups) manage/limit resource allocation to individual processes Prioritization of processes Apparmor and SELinux profiles Security profiles to govern access to resources Kernel capabilities without capabilities: root can do everything, everybody else may do nothing 38 granular facilities to control privileges seccomp policies Limitation of allowed kernel syscalls Unallowed syscalls lead to process termination Netlink A Linux kernel interface used for inter-process communication (IPC) between both the kernel and userspace processes, and between different userspace processes. Netfilter A framework provided by the Linux kernel that allows various networking-related operations Packet filtering, network address translation, and port translation(iptables/nftables) used to direct network packages to individual containers More inforamtion could refer to LXC/LXD Let's download an image alpine to simulate an root file system under /opt/test folder. mkdir test cd test wget https://dl-cdn.alpinelinux.org/alpine/v3.13/releases/x86_64/alpine-minirootfs-3.13.4-x86_64.tar.gz tar zxvf alpine-minirootfs-3.13.4-x86_64.tar.gz -C alpine-minirootfs/ Current directory structure. tree ./test -L 1 Output ./test \u251c\u2500\u2500 alpine-minirootfs-3.13.4-x86_64.tar.gz \u251c\u2500\u2500 bin \u251c\u2500\u2500 dev \u251c\u2500\u2500 etc \u251c\u2500\u2500 home \u251c\u2500\u2500 lib \u251c\u2500\u2500 media \u251c\u2500\u2500 mnt \u251c\u2500\u2500 opt \u251c\u2500\u2500 proc \u251c\u2500\u2500 root \u251c\u2500\u2500 run \u251c\u2500\u2500 sbin \u251c\u2500\u2500 srv \u251c\u2500\u2500 sys \u251c\u2500\u2500 tmp \u251c\u2500\u2500 usr \u2514\u2500\u2500 var Mount folder /opt/test/proc to a file and use command unshare to build a guest system. sudo mount -t tmpfs tmpfs /opt/test/proc sudo unshare --pid --mount-proc = $PWD /test/proc --fork chroot ./test/ /bin/sh / # ps -ef PID USER TIME COMMAND 1 root 0 :00 /bin/sh 2 root 0 :00 ps -ef / # touch 123 / # ls 123 123 The file 123 created in guest system is accessable and writable from host system. su - ls 123 echo hello > 123 We will see above change in guest system. / # cat 123 hello Let's create two folders /opt/test-1 and /opt/test-2 . mkdir test-1 mkdir test-2 Create two guests system. Mount /opt/test/home/ to different folders for different guests. sudo mount --bind /opt/test-1 /opt/test/home/ sudo unshare --pid --mount-proc = $PWD /test/proc --fork chroot ./test/ /bin/sh / # cd /home /home # echo \"test-1\" > 123.1 /home # cat 123.1 test-1 sudo mount --bind /opt/test-2 /opt/test/home/ sudo unshare --pid --mount-proc = $PWD /test/proc --fork chroot ./test/ /bin/sh / # cd /home /home # echo \"test-2\" > 123.2 /home # cat 123.2 test-2 ll test/home ll test-1/ ll test-2/ With above demo, the conclusion is that two guests share same home folder on host system and will impact each other. Installing Docker \u00b6 Install Docker engine by referring the guide , and Docker Desktop by referring the guide . Install engine via openSUSE repository automatically. sudo zypper in docker The docker group is automatically created at package installation time. The user can communicate with the local Docker daemon upon its next login. The Docker daemon listens on a local socket which is accessible only by the root user and by the members of the docker group. Add current user to docker group. sudo usermod -aG docker $USER Enable and start Docker engine. sudo systemctl enable docker.service sudo systemctl start docker.service sudo systemctl status docker.service Container lifecycle \u00b6 Overview \u00b6 Pull down below images in advance. docker image pull busybox docker image pull nginx docker image pull alpine docker image pull jenkins/jenkins:lts docker image pull golang:1.12-alpine docker image pull golang Download some docker images. Create and run a new busybox container interactively and connect a pseudo terminal to it. Inside the container, use the top command to find out that /bin/sh is running as process with the PID 1 and top process is also running. After that, just exit. docker image ls docker run -d -it --name busybox_v1 -v /opt/test:/docker busybox:latest /bin/sh docker container ps -a docker exec -it 185efe490507 /bin/sh / # top Mem: 3627396K used, 12731512K free, 10080K shrd, 2920K buff, 2999340K cached CPU: 0 .0% usr 0 .1% sys 0 .0% nic 99 .8% idle 0 .0% io 0 .0% irq 0 .0% sirq Load average: 0 .38 1 .09 1 .29 2 /277 14 PID PPID USER STAT VSZ %VSZ CPU %CPU COMMAND 1 0 root S 1332 0 .0 1 0 .0 /bin/sh 8 0 root S 1332 0 .0 2 0 .0 /bin/sh 14 8 root R 1328 0 .0 1 0 .0 top / # exitbuild Start a new nginx container in detached mode. Use the docker exec command to start another shell ( /bin/sh ) in the nginx container. Use ps to find out that sh and ps commands are running in your container. docker run -d -it --name nginx_v1 -v /opt/test:/docker nginx:latest /bin/sh docker container ps -a docker exec -it edb640127a0d /bin/sh # ps /bin/sh: 2 : ps: not found # apt-get update && apt-get install -y procps # ps PID TTY TIME CMD 8 pts/1 00 :00:00 sh 351 pts/1 00 :00:00 ps # exit Now we have two running containers below. docker container ps -a Let's use docker logs to display the logs of the container we just exited from. The option --since 35m means display log in last 35 minutes. docker logs nginx_v1 --details --since 35m docker logs busybox_v1 --details --since 35m Let's make use of this to create a new stage: Use the docker stop command to end your nginx container. docker stop busybox_v1 docker stop nginx_v1 docker container ps -a With above command docker container ps -a , we get a list of all running and exited containers. Remove them with docker rm. Use docker rm $(docker ps -aq) to clean up all containers on your host. Use it with caution! docker rm busybox_v1 docker container ps -a Ports and volumes \u00b6 Now, let's run an nginx webserver in a container and serve a website to the outside world. Start a new nginx container and export the port of the nginx webserver to a random port that is chosen by Docker. Use command docker ps to find you which port the webserver is forwarded. Access the docker with the forwarded port number on host http://localhost: . docker container ps -a docker run -d -P --name nginx_v2 nginx:latest docker container ps -a Start another nginx container and expose port to 1080 on host as an example via http://localhost:1080 . docker run -d -p 1080:80 --name nginx_v3 nginx:latest docker container ps -a Let's make use of this to create a new stage: Use command docker inspect to find out which port is exposed by the image. Network information (ip, gateway, ports, etc.) is part of the output JSON format. docker inspect nginx_v3 Create a file index.html in folder /opt/test with below sample content. < html > < head > < title > Sample Website from my container < body > < h1 > This is a custom website. < p > This website is served from my < a href = \"http://www.docker.com\" target = \"_blank\" > Docker container. Start a new container that bind-mounts host directory /opt/test to container directory /usr/share/nginx/html as a volume, so that NGINX will publish the HTML file wee just created instead of its default message via http://localhost:49159/ below. docker run -d -P --mount type=bind,source=/opt/test/,target=/usr/share/nginx/html --name nginx_v3-1 nginx:latest docker container ps -a Check nginx config file on where is the html home page stored in container. docker exec -it nginx_v3-1 /bin/sh # cd /etc/nginx/conf.d # ls default.conf # cat default.conf server { listen 80; listen [::]:80; server_name localhost; # access_log /var/log/nginx/host.access.log main ; location / { root /usr/share/nginx/html; <-- index index.html index.htm; } # error_page 404 /404.html ; # redirect server error pages to the static page /50x.html # error_page 500 502 503 504 /50x.html; location = /50x.html { root /usr/share/nginx/html; } # proxy the PHP scripts to Apache listening on 127 .0.0.1:80 # # location ~ \\. php$ { # proxy_pass http://127.0.0.1 ; # } # pass the PHP scripts to FastCGI server listening on 127 .0.0.1:9000 # # location ~ \\. php$ { # root html ; # fastcgi_pass 127 .0.0.1:9000 ; # fastcgi_index index.php ; # fastcgi_param SCRIPT_FILENAME /scripts $fastcgi_script_name ; # include fastcgi_params ; # } # deny access to .htaccess files, if Apache 's document root # concurs with nginx' s one # # location ~ / \\. ht { # deny all ; # } } # cd /usr/share/nginx/html # cat index.html Sample Website from my container

This is a custom website.

This website is served from my Docker container.

# It's recommendable to add a persistence with volumes API, instead of storing data in a docker container. Docker supports 2 ways of mount: Bind mounts: mount a local host directory onto a certain path in the container. Everything that was present before in the target directory is hidden (nature of the bind mount). For example, if you have some configuration you want to inject, write your config file, store it on your docker host at /home/container/config and mount the content of this directory to /usr/application/config (assuming the application reads config from there). Command: docker run --mount type=bind,source=,target= \u2026 Named volumes: docker can create a separated storage volume. Its lifecycle is independent from the container but still managed by docker. Upon creation, the content of the mount target is merged into the volume. Command: docker run --mount source=,target= \u2026 How to differentiate between bind mountbuild s and named volumes? When specifying an absolute path, docker assumes a bind mount. When you just give a name (like in a relative path \u201cconfig\u201d), it will assume a named volume and create a volume \u201cconfig\u201d. Note: Persistent storage is 'provided' by the host. It can be a part of the file system on the host directly but also an NFS mount. Dockerfile \u00b6 Let's build an image with a Dockerfile,build tag it and upload it to a registry. Get docker image build history. docker image history nginx:latest Create an empty directory /opt/tmp-1 , change to the directory and create an sample index.html file in /opt/tmp-1 . /opt/tmp-1> cat index.html Sample Website from my container

This is a custom website.

This website is served from my Docker container.

Use FROM to extend an existing image, specify the release number. Use COPY to copy a new default website into the image, e.g., /usr/share/nginx/html Create SSL configuration /opt/tmp-1/ssl.conf for nginx. server { listen 443 ssl; server_name localhost; ssl_certificate /etc/nginx/ssl/nginx.crt; ssl_certificate_key /etc/nginx/ssl/nginx.key; location / { root /usr/share/nginx/html; index index.html index.htm; } } Use OpenSSL to create a self-signed certificate so SSL/TLS to work would work. Use the following command to create an encryption key and a certificate. openssl req -x509 -nodes -newkey rsa:4096 -keyout nginx.key -out nginx.crt -days 365 -subj \"/CN=$(hostname)\" To enable encrypted HTTPS, we need to expose port 443 with the EXPOSE directive. The default nginx image only exposes port 80 for unencrypted HTTP. In summary, we create below Dockerfile in foder /opt/tmp-1 . cat Dockerfile Output FROM nginx:latest # copy the custom website into the image COPY index.html /usr/share/nginx/html # copy the SSL configuration file into the image COPY ssl.conf /etc/nginx/conf.d/ssl.conf # download the SSL key and certificate into the image COPY nginx.key /etc/nginx/ssl/ COPY nginx.crt /etc/nginx/ssl/ # expose the HTTPS port EXPOSE 443 We have five files in foder /opt/tmp-1 till now. ls /opt/tmp-1 Output Dockerfile index.html nginx.crt nginx.key ssl.conf Now let's use the docker build command to build the image, forward the containers ports 80 and 443. docker build -t nginx:my1 /opt/tmp-1/ docker image ls docker run -d -p 1086:80 -p 1088:443 --name nginx_v5 nginx:my1 docker container ps -a Above changes can be validated via below links: http://localhost:1086/ https://localhost:1088/ Register an account in DockerHub and enable access token in Docker Hub for CLI client authentication. docker login Input username and password. Username: Password: Tag the image to give image a nice name and a release number as tag, e.g., name is secure_nginx_0001 , tag is v1 . docker tag nginx:my1 secure_nginx_0001:v1 docker push secure_nginx_0001:v1 docker image ls Multi-stage Dockerfile \u00b6 Let's show an example of multi-stage build. The multi-stage in the context of Docker means, we can have more than one line with a FROM keyword. Create folder /opt/tmp-2 and /opt/tmp-2/tmpl . Create files edit.html , view.html , wiki.go and structure likes below. tree -l /opt/tmp-2 . \u251c\u2500\u2500 tmpl \u2502 \u251c\u2500\u2500 edit.html \u2502 \u2514\u2500\u2500 view.html \u2514\u2500\u2500 wiki.go Create an new Dockerfile that starts cat Dockerfile # app builder stage FROM golang:1.12-alpine as builder ## copy the go source code over and build the binary WORKDIR /go/src COPY wiki.go /go/src/wiki.go RUN go build wiki.go # app exec stage # separate & new image starts here!# FROM alpine:3.9 # prepare file system etc RUN mkdir -p /app/data /app/tmpl && adduser -S -D -H -h /app appuser COPY tmpl/* /app/tmpl/ # get the compiled binary from the previous stage COPY --from = builder /go/src/wiki /app/wiki # prepare runtime env RUN chown -R appuser /app USER appuser WORKDIR /app # expose app port & set default command EXPOSE 8080 CMD [ \"/app/wiki\" ] Build the images by Dockerfile we created above. docker build -t lizard/golang:my1 /opt/tmp-2/ Run the image in detached mode, create a port forwarding from port 8080 in the container to port 1090 on the host. docker run -d -p 1090:8080 --name golan_v1 lizard/golang:my1 Access the container via link http://localhost:1090 Tab the golang image we created and push it to DockerHub. docker tag lizard/golang:my1 /golang_0001:v1 docker push /golang_0001:v1","title":"Fundamentals"},{"location":"k8s/cka_en/foundamentals/docker/#docker-fundamentals","text":"","title":"Docker Fundamentals"},{"location":"k8s/cka_en/foundamentals/docker/#demo-environment","text":"Linux: openSUSE 15.3 cat /etc/os-release Output NAME=\"openSUSE Leap\" VERSION=\"15.3\" ID=\"opensuse-leap\" ID_LIKE=\"suse opensuse\" VERSION_ID=\"15.3\" PRETTY_NAME=\"openSUSE Leap 15.3\" ANSI_COLOR=\"0;32\" CPE_NAME=\"cpe:/o:opensuse:leap:15.3\" BUG_REPORT_URL=\"https://bugs.opensuse.org\" HOME_URL=\"https://www.opensuse.org/\"","title":"Demo environment"},{"location":"k8s/cka_en/foundamentals/docker/#linux-primitives","text":"chroot(using pivot_root) Changes the root directory for a process to any given directory namespaces Different processes see different environments even though they are on the same host/OS mnt (mount points) pid (process tree) net (network interfaces and connectivity) ipc (interprocess communication framework) uts (unix timesharing - domain name, hostname, etc.) uid (user IDs and mappings) cgroups(control groups) manage/limit resource allocation to individual processes Prioritization of processes Apparmor and SELinux profiles Security profiles to govern access to resources Kernel capabilities without capabilities: root can do everything, everybody else may do nothing 38 granular facilities to control privileges seccomp policies Limitation of allowed kernel syscalls Unallowed syscalls lead to process termination Netlink A Linux kernel interface used for inter-process communication (IPC) between both the kernel and userspace processes, and between different userspace processes. Netfilter A framework provided by the Linux kernel that allows various networking-related operations Packet filtering, network address translation, and port translation(iptables/nftables) used to direct network packages to individual containers More inforamtion could refer to LXC/LXD Let's download an image alpine to simulate an root file system under /opt/test folder. mkdir test cd test wget https://dl-cdn.alpinelinux.org/alpine/v3.13/releases/x86_64/alpine-minirootfs-3.13.4-x86_64.tar.gz tar zxvf alpine-minirootfs-3.13.4-x86_64.tar.gz -C alpine-minirootfs/ Current directory structure. tree ./test -L 1 Output ./test \u251c\u2500\u2500 alpine-minirootfs-3.13.4-x86_64.tar.gz \u251c\u2500\u2500 bin \u251c\u2500\u2500 dev \u251c\u2500\u2500 etc \u251c\u2500\u2500 home \u251c\u2500\u2500 lib \u251c\u2500\u2500 media \u251c\u2500\u2500 mnt \u251c\u2500\u2500 opt \u251c\u2500\u2500 proc \u251c\u2500\u2500 root \u251c\u2500\u2500 run \u251c\u2500\u2500 sbin \u251c\u2500\u2500 srv \u251c\u2500\u2500 sys \u251c\u2500\u2500 tmp \u251c\u2500\u2500 usr \u2514\u2500\u2500 var Mount folder /opt/test/proc to a file and use command unshare to build a guest system. sudo mount -t tmpfs tmpfs /opt/test/proc sudo unshare --pid --mount-proc = $PWD /test/proc --fork chroot ./test/ /bin/sh / # ps -ef PID USER TIME COMMAND 1 root 0 :00 /bin/sh 2 root 0 :00 ps -ef / # touch 123 / # ls 123 123 The file 123 created in guest system is accessable and writable from host system. su - ls 123 echo hello > 123 We will see above change in guest system. / # cat 123 hello Let's create two folders /opt/test-1 and /opt/test-2 . mkdir test-1 mkdir test-2 Create two guests system. Mount /opt/test/home/ to different folders for different guests. sudo mount --bind /opt/test-1 /opt/test/home/ sudo unshare --pid --mount-proc = $PWD /test/proc --fork chroot ./test/ /bin/sh / # cd /home /home # echo \"test-1\" > 123.1 /home # cat 123.1 test-1 sudo mount --bind /opt/test-2 /opt/test/home/ sudo unshare --pid --mount-proc = $PWD /test/proc --fork chroot ./test/ /bin/sh / # cd /home /home # echo \"test-2\" > 123.2 /home # cat 123.2 test-2 ll test/home ll test-1/ ll test-2/ With above demo, the conclusion is that two guests share same home folder on host system and will impact each other.","title":"Linux Primitives"},{"location":"k8s/cka_en/foundamentals/docker/#installing-docker","text":"Install Docker engine by referring the guide , and Docker Desktop by referring the guide . Install engine via openSUSE repository automatically. sudo zypper in docker The docker group is automatically created at package installation time. The user can communicate with the local Docker daemon upon its next login. The Docker daemon listens on a local socket which is accessible only by the root user and by the members of the docker group. Add current user to docker group. sudo usermod -aG docker $USER Enable and start Docker engine. sudo systemctl enable docker.service sudo systemctl start docker.service sudo systemctl status docker.service","title":"Installing Docker"},{"location":"k8s/cka_en/foundamentals/docker/#container-lifecycle","text":"","title":"Container lifecycle"},{"location":"k8s/cka_en/foundamentals/docker/#overview","text":"Pull down below images in advance. docker image pull busybox docker image pull nginx docker image pull alpine docker image pull jenkins/jenkins:lts docker image pull golang:1.12-alpine docker image pull golang Download some docker images. Create and run a new busybox container interactively and connect a pseudo terminal to it. Inside the container, use the top command to find out that /bin/sh is running as process with the PID 1 and top process is also running. After that, just exit. docker image ls docker run -d -it --name busybox_v1 -v /opt/test:/docker busybox:latest /bin/sh docker container ps -a docker exec -it 185efe490507 /bin/sh / # top Mem: 3627396K used, 12731512K free, 10080K shrd, 2920K buff, 2999340K cached CPU: 0 .0% usr 0 .1% sys 0 .0% nic 99 .8% idle 0 .0% io 0 .0% irq 0 .0% sirq Load average: 0 .38 1 .09 1 .29 2 /277 14 PID PPID USER STAT VSZ %VSZ CPU %CPU COMMAND 1 0 root S 1332 0 .0 1 0 .0 /bin/sh 8 0 root S 1332 0 .0 2 0 .0 /bin/sh 14 8 root R 1328 0 .0 1 0 .0 top / # exitbuild Start a new nginx container in detached mode. Use the docker exec command to start another shell ( /bin/sh ) in the nginx container. Use ps to find out that sh and ps commands are running in your container. docker run -d -it --name nginx_v1 -v /opt/test:/docker nginx:latest /bin/sh docker container ps -a docker exec -it edb640127a0d /bin/sh # ps /bin/sh: 2 : ps: not found # apt-get update && apt-get install -y procps # ps PID TTY TIME CMD 8 pts/1 00 :00:00 sh 351 pts/1 00 :00:00 ps # exit Now we have two running containers below. docker container ps -a Let's use docker logs to display the logs of the container we just exited from. The option --since 35m means display log in last 35 minutes. docker logs nginx_v1 --details --since 35m docker logs busybox_v1 --details --since 35m Let's make use of this to create a new stage: Use the docker stop command to end your nginx container. docker stop busybox_v1 docker stop nginx_v1 docker container ps -a With above command docker container ps -a , we get a list of all running and exited containers. Remove them with docker rm. Use docker rm $(docker ps -aq) to clean up all containers on your host. Use it with caution! docker rm busybox_v1 docker container ps -a","title":"Overview"},{"location":"k8s/cka_en/foundamentals/docker/#ports-and-volumes","text":"Now, let's run an nginx webserver in a container and serve a website to the outside world. Start a new nginx container and export the port of the nginx webserver to a random port that is chosen by Docker. Use command docker ps to find you which port the webserver is forwarded. Access the docker with the forwarded port number on host http://localhost: . docker container ps -a docker run -d -P --name nginx_v2 nginx:latest docker container ps -a Start another nginx container and expose port to 1080 on host as an example via http://localhost:1080 . docker run -d -p 1080:80 --name nginx_v3 nginx:latest docker container ps -a Let's make use of this to create a new stage: Use command docker inspect to find out which port is exposed by the image. Network information (ip, gateway, ports, etc.) is part of the output JSON format. docker inspect nginx_v3 Create a file index.html in folder /opt/test with below sample content. < html > < head > < title > Sample Website from my container < body > < h1 > This is a custom website. < p > This website is served from my < a href = \"http://www.docker.com\" target = \"_blank\" > Docker container. Start a new container that bind-mounts host directory /opt/test to container directory /usr/share/nginx/html as a volume, so that NGINX will publish the HTML file wee just created instead of its default message via http://localhost:49159/ below. docker run -d -P --mount type=bind,source=/opt/test/,target=/usr/share/nginx/html --name nginx_v3-1 nginx:latest docker container ps -a Check nginx config file on where is the html home page stored in container. docker exec -it nginx_v3-1 /bin/sh # cd /etc/nginx/conf.d # ls default.conf # cat default.conf server { listen 80; listen [::]:80; server_name localhost; # access_log /var/log/nginx/host.access.log main ; location / { root /usr/share/nginx/html; <-- index index.html index.htm; } # error_page 404 /404.html ; # redirect server error pages to the static page /50x.html # error_page 500 502 503 504 /50x.html; location = /50x.html { root /usr/share/nginx/html; } # proxy the PHP scripts to Apache listening on 127 .0.0.1:80 # # location ~ \\. php$ { # proxy_pass http://127.0.0.1 ; # } # pass the PHP scripts to FastCGI server listening on 127 .0.0.1:9000 # # location ~ \\. php$ { # root html ; # fastcgi_pass 127 .0.0.1:9000 ; # fastcgi_index index.php ; # fastcgi_param SCRIPT_FILENAME /scripts $fastcgi_script_name ; # include fastcgi_params ; # } # deny access to .htaccess files, if Apache 's document root # concurs with nginx' s one # # location ~ / \\. ht { # deny all ; # } } # cd /usr/share/nginx/html # cat index.html Sample Website from my container

This is a custom website.

This website is served from my Docker container.

# It's recommendable to add a persistence with volumes API, instead of storing data in a docker container. Docker supports 2 ways of mount: Bind mounts: mount a local host directory onto a certain path in the container. Everything that was present before in the target directory is hidden (nature of the bind mount). For example, if you have some configuration you want to inject, write your config file, store it on your docker host at /home/container/config and mount the content of this directory to /usr/application/config (assuming the application reads config from there). Command: docker run --mount type=bind,source=,target= \u2026 Named volumes: docker can create a separated storage volume. Its lifecycle is independent from the container but still managed by docker. Upon creation, the content of the mount target is merged into the volume. Command: docker run --mount source=,target= \u2026 How to differentiate between bind mountbuild s and named volumes? When specifying an absolute path, docker assumes a bind mount. When you just give a name (like in a relative path \u201cconfig\u201d), it will assume a named volume and create a volume \u201cconfig\u201d. Note: Persistent storage is 'provided' by the host. It can be a part of the file system on the host directly but also an NFS mount.","title":"Ports and volumes"},{"location":"k8s/cka_en/foundamentals/docker/#dockerfile","text":"Let's build an image with a Dockerfile,build tag it and upload it to a registry. Get docker image build history. docker image history nginx:latest Create an empty directory /opt/tmp-1 , change to the directory and create an sample index.html file in /opt/tmp-1 . /opt/tmp-1> cat index.html Sample Website from my container

This is a custom website.

This website is served from my Docker container.

Use FROM to extend an existing image, specify the release number. Use COPY to copy a new default website into the image, e.g., /usr/share/nginx/html Create SSL configuration /opt/tmp-1/ssl.conf for nginx. server { listen 443 ssl; server_name localhost; ssl_certificate /etc/nginx/ssl/nginx.crt; ssl_certificate_key /etc/nginx/ssl/nginx.key; location / { root /usr/share/nginx/html; index index.html index.htm; } } Use OpenSSL to create a self-signed certificate so SSL/TLS to work would work. Use the following command to create an encryption key and a certificate. openssl req -x509 -nodes -newkey rsa:4096 -keyout nginx.key -out nginx.crt -days 365 -subj \"/CN=$(hostname)\" To enable encrypted HTTPS, we need to expose port 443 with the EXPOSE directive. The default nginx image only exposes port 80 for unencrypted HTTP. In summary, we create below Dockerfile in foder /opt/tmp-1 . cat Dockerfile Output FROM nginx:latest # copy the custom website into the image COPY index.html /usr/share/nginx/html # copy the SSL configuration file into the image COPY ssl.conf /etc/nginx/conf.d/ssl.conf # download the SSL key and certificate into the image COPY nginx.key /etc/nginx/ssl/ COPY nginx.crt /etc/nginx/ssl/ # expose the HTTPS port EXPOSE 443 We have five files in foder /opt/tmp-1 till now. ls /opt/tmp-1 Output Dockerfile index.html nginx.crt nginx.key ssl.conf Now let's use the docker build command to build the image, forward the containers ports 80 and 443. docker build -t nginx:my1 /opt/tmp-1/ docker image ls docker run -d -p 1086:80 -p 1088:443 --name nginx_v5 nginx:my1 docker container ps -a Above changes can be validated via below links: http://localhost:1086/ https://localhost:1088/ Register an account in DockerHub and enable access token in Docker Hub for CLI client authentication. docker login Input username and password. Username: Password: Tag the image to give image a nice name and a release number as tag, e.g., name is secure_nginx_0001 , tag is v1 . docker tag nginx:my1 secure_nginx_0001:v1 docker push secure_nginx_0001:v1 docker image ls","title":"Dockerfile"},{"location":"k8s/cka_en/foundamentals/docker/#multi-stage-dockerfile","text":"Let's show an example of multi-stage build. The multi-stage in the context of Docker means, we can have more than one line with a FROM keyword. Create folder /opt/tmp-2 and /opt/tmp-2/tmpl . Create files edit.html , view.html , wiki.go and structure likes below. tree -l /opt/tmp-2 . \u251c\u2500\u2500 tmpl \u2502 \u251c\u2500\u2500 edit.html \u2502 \u2514\u2500\u2500 view.html \u2514\u2500\u2500 wiki.go Create an new Dockerfile that starts cat Dockerfile # app builder stage FROM golang:1.12-alpine as builder ## copy the go source code over and build the binary WORKDIR /go/src COPY wiki.go /go/src/wiki.go RUN go build wiki.go # app exec stage # separate & new image starts here!# FROM alpine:3.9 # prepare file system etc RUN mkdir -p /app/data /app/tmpl && adduser -S -D -H -h /app appuser COPY tmpl/* /app/tmpl/ # get the compiled binary from the previous stage COPY --from = builder /go/src/wiki /app/wiki # prepare runtime env RUN chown -R appuser /app USER appuser WORKDIR /app # expose app port & set default command EXPOSE 8080 CMD [ \"/app/wiki\" ] Build the images by Dockerfile we created above. docker build -t lizard/golang:my1 /opt/tmp-2/ Run the image in detached mode, create a port forwarding from port 8080 in the container to port 1090 on the host. docker run -d -p 1090:8080 --name golan_v1 lizard/golang:my1 Access the container via link http://localhost:1090 Tab the golang image we created and push it to DockerHub. docker tag lizard/golang:my1 /golang_0001:v1 docker push /golang_0001:v1","title":"Multi-stage Dockerfile"},{"location":"k8s/cka_en/foundamentals/healthcheck/","text":"Health Check \u00b6 Status of Pod and Container \u00b6 Scenario: Create a pod with two containers. Demo: Create a Pod multi-pods with two containers nginx and busybox . kubectl apply -f - << EOF apiVersion: v1 kind: Pod metadata: labels: run: multi-pods name: multi-pods spec: containers: - image: nginx name: nginx - image: busybox name: busybox dnsPolicy: ClusterFirst restartPolicy: Always EOF Minotor the status with option --watch . The status of Pod was changed from ContainerCreating to NotReady to CrashLoopBackOff . kubectl get pod multi-pods --watch Get details of the Pod multi-pods , focus on Container's state under segment Containers and Conditions of Pod under segment Conditions . kubectl describe pod multi-pods Result ...... Containers: nginx: ...... State: Running Started: Sat, 23 Jul 2022 15:06:56 +0800 Ready: True Restart Count: 0 ...... busybox: ...... State: Terminated Reason: Completed Exit Code: 0 ...... Conditions: Type Status Initialized True Ready False ContainersReady False PodScheduled True ...... LivenessProbe \u00b6 Scenario: Create pod with livenessProbe check. Detail description of the demo can be found on the Kubernetes document . Demo: Create a yaml file liveness.yaml with livenessProbe setting and apply it. kubectl apply -f - <> ~/.bashrc source <(helm completion bash) Install MySQL from Helm \u00b6 Add bitnami Chartes Repository. helm repo add bitnami https://charts.bitnami.com/bitnami Get current Charts repositories. helm repo list NAME URL bitnami https://charts.bitnami.com/bitnami Sync up local Charts repositories. helm repo update Search bitnami Charts in repositories. helm search repo bitnami Search bitnami/mysql Charts in repositories. helm search repo bitnami/mysql Install MySQL Chart on namespace dev \uff1a helm install mysql bitnami/mysql -n dev Output NAME: mysql LAST DEPLOYED: Sun Jul 24 19:37:20 2022 NAMESPACE: dev STATUS: deployed REVISION: 1 TEST SUITE: None NOTES: CHART NAME: mysql CHART VERSION: 9.2.1 APP VERSION: 8.0.29 ** Please be patient while the chart is being deployed ** Tip: Watch the deployment status using the command: kubectl get pods -w --namespace dev Services: echo Primary: mysql.dev.svc.cluster.local:3306 Execute the following to get the administrator credentials: echo Username: root MYSQL_ROOT_PASSWORD=$(kubectl get secret --namespace dev mysql -o jsonpath=\"{.data.mysql-root-password}\" | base64 -d) To connect to your database: 1. Run a pod that you can use as a client: kubectl run mysql-client --rm --tty -i --restart='Never' --image docker.io/bitnami/mysql:8.0.29-debian-11-r9 --namespace dev --env MYSQL_ROOT_PASSWORD=$MYSQL_ROOT_PASSWORD --command -- bash 2. To connect to primary service (read/write): mysql -h mysql.dev.svc.cluster.local -uroot -p\"$MYSQL_ROOT_PASSWORD\" Check installed release\uff1a helm list Result NAME NAMESPACE REVISION UPDATED STATUS CHART APP VERSION mysql dev 1 2022-07-24 19:37:20.710988009 +0800 CST deployed mysql-9.2.1 8.0.29 Check installed mysql release information. helm status mysql Check mysql Pod status. kubectl get pod Result NAME READY STATUS RESTARTS AGE mysql-0 1/1 Running 0 72s Develop a Chart \u00b6 Below is a demo on how to develop a Chart. Execute helm create to initiate a Chart\uff1a # Naming conventions of Chart: lowercase a~z and - ( minus sign ) helm create cka-demo A folder cka-demo was created. Check the folder structure. tree cka-demo/ Output cka-demo/ \u251c\u2500\u2500 charts \u251c\u2500\u2500 Chart.yaml \u251c\u2500\u2500 templates \u2502 \u251c\u2500\u2500 deployment.yaml \u2502 \u251c\u2500\u2500 _helpers.tpl \u2502 \u251c\u2500\u2500 hpa.yaml \u2502 \u251c\u2500\u2500 ingress.yaml \u2502 \u251c\u2500\u2500 NOTES.txt \u2502 \u251c\u2500\u2500 serviceaccount.yaml \u2502 \u251c\u2500\u2500 service.yaml \u2502 \u2514\u2500\u2500 tests \u2502 \u2514\u2500\u2500 test-connection.yaml \u2514\u2500\u2500 values.yaml Delete or empty some files, which will be re-created later. cd cka-demo rm -rf charts rm -rf templates/tests rm -rf templates/*.yaml echo \"\" > values.yaml echo \"\" > templates/NOTES.txt echo \"\" > templates/_helpers.tpl cd .. Now new structure looks like below. tree cka-demo/ Output cka-demo/ \u251c\u2500\u2500 Chart.yaml \u251c\u2500\u2500 templates \u2502 \u251c\u2500\u2500 _helpers.tpl \u2502 \u2514\u2500\u2500 NOTES.txt \u2514\u2500\u2500 values.yaml NOTES.txt \u00b6 NOTES.txt is used to provide summary information to Chart users. In the demo, we will use NOTES.txt to privide summary info about whether the user passed CKA certificate or not. cd cka-demo/ vi templates/NOTES.txt Add below info. {{- if .Values.passExam }} Congratulations! You have successfully completed Certified Kubernetes Administrator China Exam (CKA-CN). Your CKA score is: {{ .Values.ckaScore }} Click the link below to view and download your certificate. https://trainingportal.linuxfoundation.org/learn/dashboard {{- else }} Come on! you can do it next time! {{- end }} Deployment Template \u00b6 Let's use Busybox service to generate information. We use kubectl create deployment --dry-run=client -oyaml to generate Deployment yaml file and write it the yaml file content into file templates/deployment.yaml . kubectl create deployment cka-demo-busybox --image=busybox:latest --dry-run=client -oyaml > templates/deployment.yaml Check content of deployment yaml file templates/deployment.yaml . cat templates/deployment.yaml apiVersion : apps/v1 kind : Deployment metadata : creationTimestamp : null labels : app : cka-demo-busybox name : cka-demo-busybox spec : replicas : 1 selector : matchLabels : app : cka-demo-busybox strategy : {} template : metadata : creationTimestamp : null labels : app : cka-demo-busybox spec : containers : - image : busybox:latest name : busybox resources : {} status : {} Edit file templates/deployment.yaml . vi templates/deployment.yaml Let's replace value of .spec.replicas from 1 to a variable {{ .Values.replicaCount }} , so we can dynamicly assign replicas number for other Deployment. apiVersion : apps/v1 kind : Deployment metadata : creationTimestamp : null labels : app : cka-demo-busybox name : cka-demo-busybox spec : replicas : {{ .Values.replicaCount }} selector : matchLabels : app : cka-demo-busybox strategy : {} template : metadata : creationTimestamp : null labels : app : cka-demo-busybox spec : containers : - image : busybox:latest name : busybox resources : {} status : {} The .spec.replicas will be replaced by actula value of .Values.replicaCount during deployment. Let's create another file values.yaml and add a variable replicaCount with default value 1 into the file. Strong recommended to add comments for each value we defined in file values.yaml . vi values.yaml # Number of deployment replicas replicaCount: 1 Let's add more variables into file templates/deployment.yaml . Replace Release name .metadata.name by {{ .Release.Name }} and filled with variable defined in file values.yaml . Replace label name .metadata.labels by {{- include \"cka-demo.labels\" . | nindent 4 }} , and filled with labels name cka-demo.labels defined in file _helpers.tpl . Replace .spec.replicas by {{ .Values.replicaCount }} and filled with variable defined in file values.yaml . Replace .spec.selector.matchLabels by {{- include \"cka-demo.selectorLabels\" . | nindent 6 }} and filled with cka-demo.selectorLabels defined in file _helpers.tpl . Replace .spec.template.metadata.labels by {{- include \"cka-demo.selectorLabels\" . | nindent 8 }} and filled with cka-demo.selectorLabels defined in file _helpers.tpl . Replace .spec.template.spec.containers[0].image by {{ .Values.image.repository }} and {{ .Values.image.tag }} and filled with variables defined in values.yaml for image name and image tag. Replace .spec.template.spec.containers[0].command and add if-else statement, if .Values.passExam is true, execute commands defined in .Values.passCommand , if false, execute commands defined in .Values.lostCommand . Use key from ConfigMap from .spec.template.spec.containers[0].env as prefix of ConfigMap name and filled with {{ .Values.studentName }} defined in file values.yaml . Replace .spec.template.spec.containers[0].resources by {{ .Values.resources }} and filled with variable defined in file values.yaml . The .Release.Name is built-in object, no need to be specified in file values.yaml . It's generated by Release by helm install . Remove unused lines and final one looks like below. apiVersion : apps/v1 kind : Deployment metadata : name : {{ .Release.Name }} labels : {{ - include \"cka-demo.labels\" . | nindent 4 }} spec : replicas : {{ .Values.replicaCount }} selector : matchLabels : {{ - include \"cka-demo.selectorLabels\" . | nindent 6 }} template : metadata : labels : {{ - include \"cka-demo.selectorLabels\" . | nindent 8 }} spec : containers : - name : id-generator image : \"{{ .Values.image.repository }}:{{ .Values.image.tag }}\" {{ - if .Values.passExam }} {{ - with .Values.passCommand }} command : {{ range . }} - {{ . | quote }} {{ - end }} {{ - end }} {{ - else }} {{ - with .Values.lostCommand }} command : {{ range . }} - {{ . | quote }} {{ - end }} {{ - end }} {{ - end }} env : - name : CKA_SCORE valueFrom : configMapKeyRef : name : {{ .Values.studentName }} -cka-score key : cka_score {{ - with .Values.resources }} resources : {{ - toYaml . | nindent 12 }} {{ - end }} restartPolicy : Always Update file values.yaml with variables default values. Suggestions\uff1aadd variables one and test one, don't add all at one time. vi values.yaml # Number of deployment replicas replicaCount: 1 # Image repository and tag image: repository: busybox tag: latest # Container start command passCommand: - '/bin/sh' - '-c' - \"echo Your CKA score is $(CKA_SCORE) and your CKA certificate ID number is $(tr -dc 'A-Za-z0-9' < /dev/urandom | head -c 13; echo) ; sleep 86400\" lostCommand: - '/bin/sh' - '-c' - \"echo Your CKA score is $(CKA_SCORE), Come on! you can do it next time! ; sleep 86400\" # Container resources resources: limits: cpu: 200m memory: 256Mi requests: cpu: 100m memory: 128Mi # Student Name studentName: whoareyou # Student pass CKA exam or not passExam: true ConfigMap Template \u00b6 ConfigMap is referred in the Deployment, hence we need define the ConfigMap template. We will combine name of ConfigMap and cka_score as a variable, like name-cka-score . vi templates/configmap.yaml apiVersion : v1 kind : ConfigMap metadata : name : {{ .Values.studentName }} -cka-score labels : {{ - include \"cka-demo.labels\" . | nindent 4 }} data : cka_score : {{ .Values.ckaScore | quote }} The studentName was already defined in file values.yaml , we just need add ckaScore with default value. vi values.yaml # Student CKA Score ckaScore: 100 _helpers.tpl \u00b6 Define a common template _helpers.tpl to add labels and labels of Selector for labels of Deployment and ConfigMap. vi templates/_helpers.tpl {{/* Common labels */}} {{- define \"cka-demo.labels\" -}} {{ include \"cka-demo.selectorLabels\" . }} {{- if .Chart.AppVersion }} app.kubernetes.io/version: {{ .Chart.AppVersion | quote }} {{- end }} app.kubernetes.io/managed-by: {{ .Release.Service }} {{- end -}} {{/* Selector labels */}} {{- define \"cka-demo.selectorLabels\" -}} app: {{ .Chart.Name }} release: {{ .Release.Name }} {{- end -}} Chart.yaml \u00b6 We use CKA logo as the icon of Chart wget https://www.cncf.io/wp-content/uploads/2021/09/kubernetes-cka-color.svg Edit Chart.yaml file. vi Chart.yaml Append icon info in the file. icon: file://./kubernetes-cka-color.svg Add author info for the Chart vi Chart.yaml maintainers: - name: James.H Final Chart.yaml looks like below. Don't forget to update appVersion: \"v1.23\" to current Kubernetes API version. apiVersion : v2 name : cka-demo description : A Helm chart for CKA demo. type : application version : 0.1.0 appVersion : \"v1.23\" maintainers : - name : James.H icon : file://./kubernetes-cka-color.svg Chart Debug \u00b6 Use helm lint to verify above change. helm lint 1 chart(s) linted, 0 chart(s) failed helm lint only check format of Chart, won't check Manifest file. We can use helm install --debug --dry-run or helm template to check Manifest output in order to verify all yaml files are correct or not. helm template cka-demo ./ Use helm install --debug --dry-run to simulate the installation. We can get expected results from two different options (passed or failed the CKA certificate). helm install --debug --dry-run cka-demo ./ --create-namespace \\ -n cka \\ --set studentName=kubernetes \\ --set ckaScore=99 \\ --set passExam=true helm install --debug --dry-run cka-demo ./ --create-namespace \\ -n cka \\ --set studentName=kubernetes \\ --set ckaScore=0 \\ --set passExam=false Package Chart to .tgz file, and upload to repository, e.g., Chart Museum or OCI Repo. cd ../ helm package cka-demo Successfully packaged chart and saved it to: /root/cka-demo-0.1.0.tgz Till now, we have done our task to develop a Chart. Let's install the Chart. helm install cka-demo cka-demo-0.1.0.tgz --create-namespace \\ -n cka \\ --set studentName=kubernetes \\ --set ckaScore=0 \\ --set passExam=false Result NAME: cka-demo LAST DEPLOYED: Sun Jul 24 19:58:36 2022 NAMESPACE: cka STATUS: deployed REVISION: 1 TEST SUITE: None NOTES: Come on! you can do it next time! Check the deployment helm list --all-namespaces Result NAME NAMESPACE REVISION UPDATED STATUS CHART APP VERSION cka-demo cka 1 2022-07-24 19:58:36.272093383 +0800 CST deployed cka-demo-0.1.0 v1.23 mysql dev 1 2022-07-24 19:37:20.710988009 +0800 CST deployed mysql-9.2.1 8.0.29 If any error, need to unstall cka-demo and reinstall it. helm uninstall cka-demo -n Check log of cka-demo . kubectl logs -n cka -l app=cka-demo Result Your CKA score is 0, Come on! you can do it next time! Install cka-demo with different options. helm uninstall cka-demo -n cka helm install cka-demo cka-demo-0.1.0.tgz --create-namespace \\ -n cka \\ --set studentName=kubernetes \\ --set ckaScore=100 \\ --set passExam=true NAME: cka-demo LAST DEPLOYED: Sun Jul 24 20:01:34 2022 NAMESPACE: cka STATUS: deployed REVISION: 1 TEST SUITE: None NOTES: Congratulations! You have successfully completed Certified Kubernetes Administrator China Exam (CKA-CN). Your CKA score is: 100 Click the link below to view and download your certificate. https://trainingportal.linuxfoundation.org/learn/dashboard Check log of cka-demo . kubectl logs -n cka -l app=cka-demo Your CKA score is 100 and your CKA certificate ID number is BQKoVYVhjzl3G Built-in Objects: Release.Name # \u53d1\u5e03\u540d\u79f0 Release.Namespace # \u53d1\u5e03Namespace Release.Service # \u6e32\u67d3\u6a21\u677f\u7684\u670d\u52a1\uff0c\u5728Helm\u4e2d\u9ed8\u8ba4\u503c\u4e3a\"Helm\" Release.IsUpgrade # \u5982\u679c\u5f53\u524d\u662f\u5347\u7ea7\u6216\u56de\u6eda\uff0c\u8bbe\u7f6e\u4e3atrue Release.IsInstall # \u5982\u679c\u5f53\u524d\u662f\u5b89\u88c5\uff0c\u8bbe\u7f6e\u4e3atrue Release.Revision # \u53d1\u5e03\u7248\u672c\u53f7 Values # \u4ecevalues.yaml\u548c--set\u4f20\u5165\uff0c\u9ed8\u8ba4\u4e3a\u7a7a Chart # \u6240\u6709Chart.yaml\u4e2d\u7684\u5185\u5bb9 Chart.Version # Chart.Maintainers # Files # \u5728chart\u4e2d\u8bbf\u95ee\u975e\u7279\u6b8a\u6587\u4ef6 Capabilities # \u63d0\u4f9b\u5173\u4e8e\u652f\u6301\u80fd\u529b\u7684\u4fe1\u606f\uff08K8s API\u7248\u672c\u3001K8s\u7248\u672c\u3001Helm\u7248\u672c\uff09 Capabilities.KubeVersion # Kubernetes\u7684\u7248\u672c\u53f7 Capabilities.APIVersions.Has \"batch/v1\" # K8s API\u7248\u672c\u5305\u542b\"batch/v1\" Template # \u5f53\u524d\u6a21\u677f\u4fe1\u606f Template.Name # \u5f53\u524d\u6a21\u677f\u6587\u4ef6\u8def\u5f84 Template.BasePath # \u5f53\u524d\u6a21\u677f\u76ee\u5f55\u8def\u5f84 Reference: Helm \u5b98\u7f51 Helm \u7248\u672c\u652f\u6301\u7b56\u7565 Helm Chart \u8d44\u6e90\u5bf9\u8c61\u5b89\u88c5\u987a\u5e8f","title":"Helming"},{"location":"k8s/cka_en/foundamentals/helming/#helm-chart","text":"","title":"Helm Chart"},{"location":"k8s/cka_en/foundamentals/helming/#install-helm","text":"Install Helm on cka001 . # https://github.com/helm/helm/releases wget https://get.helm.sh/helm-v3.8.2-linux-amd64.tar.gz tar -zxvf helm-v3.8.2-linux-amd64.tar.gz cp linux-amd64/helm /usr/bin/ rm -rf linux-amd64 helm-v3.8.2-linux-amd64.tar.gz Or manually download the file via link https://get.helm.sh/helm-v3.8.2-linux-amd64.tar.gz , and remote copy to cka001 . scp -i cka-key-pair.pem ./Package/helm-v3.8.2-linux-amd64.tar.gz root@cka001:/root/ ssh -i cka-key-pair.pem root@cka001 tar -zxvf helm-v3.8.2-linux-amd64.tar.gz cp linux-amd64/helm /usr/bin/ rm -rf linux-amd64 helm-v3.8.2-linux-amd64.tar.gz","title":"Install Helm"},{"location":"k8s/cka_en/foundamentals/helming/#usage-of-helm","text":"Check helm version helm version version.BuildInfo{Version:\"v3.8.2\", GitCommit:\"6e3701edea09e5d55a8ca2aae03a68917630e91b\", GitTreeState:\"clean\", GoVersion:\"go1.17.5\"} Get help of helm . helm help Configure auto-completion for helm . echo \"source <(helm completion bash)\" >> ~/.bashrc source <(helm completion bash)","title":"Usage of Helm"},{"location":"k8s/cka_en/foundamentals/helming/#install-mysql-from-helm","text":"Add bitnami Chartes Repository. helm repo add bitnami https://charts.bitnami.com/bitnami Get current Charts repositories. helm repo list NAME URL bitnami https://charts.bitnami.com/bitnami Sync up local Charts repositories. helm repo update Search bitnami Charts in repositories. helm search repo bitnami Search bitnami/mysql Charts in repositories. helm search repo bitnami/mysql Install MySQL Chart on namespace dev \uff1a helm install mysql bitnami/mysql -n dev Output NAME: mysql LAST DEPLOYED: Sun Jul 24 19:37:20 2022 NAMESPACE: dev STATUS: deployed REVISION: 1 TEST SUITE: None NOTES: CHART NAME: mysql CHART VERSION: 9.2.1 APP VERSION: 8.0.29 ** Please be patient while the chart is being deployed ** Tip: Watch the deployment status using the command: kubectl get pods -w --namespace dev Services: echo Primary: mysql.dev.svc.cluster.local:3306 Execute the following to get the administrator credentials: echo Username: root MYSQL_ROOT_PASSWORD=$(kubectl get secret --namespace dev mysql -o jsonpath=\"{.data.mysql-root-password}\" | base64 -d) To connect to your database: 1. Run a pod that you can use as a client: kubectl run mysql-client --rm --tty -i --restart='Never' --image docker.io/bitnami/mysql:8.0.29-debian-11-r9 --namespace dev --env MYSQL_ROOT_PASSWORD=$MYSQL_ROOT_PASSWORD --command -- bash 2. To connect to primary service (read/write): mysql -h mysql.dev.svc.cluster.local -uroot -p\"$MYSQL_ROOT_PASSWORD\" Check installed release\uff1a helm list Result NAME NAMESPACE REVISION UPDATED STATUS CHART APP VERSION mysql dev 1 2022-07-24 19:37:20.710988009 +0800 CST deployed mysql-9.2.1 8.0.29 Check installed mysql release information. helm status mysql Check mysql Pod status. kubectl get pod Result NAME READY STATUS RESTARTS AGE mysql-0 1/1 Running 0 72s","title":"Install MySQL from Helm"},{"location":"k8s/cka_en/foundamentals/helming/#develop-a-chart","text":"Below is a demo on how to develop a Chart. Execute helm create to initiate a Chart\uff1a # Naming conventions of Chart: lowercase a~z and - ( minus sign ) helm create cka-demo A folder cka-demo was created. Check the folder structure. tree cka-demo/ Output cka-demo/ \u251c\u2500\u2500 charts \u251c\u2500\u2500 Chart.yaml \u251c\u2500\u2500 templates \u2502 \u251c\u2500\u2500 deployment.yaml \u2502 \u251c\u2500\u2500 _helpers.tpl \u2502 \u251c\u2500\u2500 hpa.yaml \u2502 \u251c\u2500\u2500 ingress.yaml \u2502 \u251c\u2500\u2500 NOTES.txt \u2502 \u251c\u2500\u2500 serviceaccount.yaml \u2502 \u251c\u2500\u2500 service.yaml \u2502 \u2514\u2500\u2500 tests \u2502 \u2514\u2500\u2500 test-connection.yaml \u2514\u2500\u2500 values.yaml Delete or empty some files, which will be re-created later. cd cka-demo rm -rf charts rm -rf templates/tests rm -rf templates/*.yaml echo \"\" > values.yaml echo \"\" > templates/NOTES.txt echo \"\" > templates/_helpers.tpl cd .. Now new structure looks like below. tree cka-demo/ Output cka-demo/ \u251c\u2500\u2500 Chart.yaml \u251c\u2500\u2500 templates \u2502 \u251c\u2500\u2500 _helpers.tpl \u2502 \u2514\u2500\u2500 NOTES.txt \u2514\u2500\u2500 values.yaml","title":"Develop a Chart"},{"location":"k8s/cka_en/foundamentals/helming/#notestxt","text":"NOTES.txt is used to provide summary information to Chart users. In the demo, we will use NOTES.txt to privide summary info about whether the user passed CKA certificate or not. cd cka-demo/ vi templates/NOTES.txt Add below info. {{- if .Values.passExam }} Congratulations! You have successfully completed Certified Kubernetes Administrator China Exam (CKA-CN). Your CKA score is: {{ .Values.ckaScore }} Click the link below to view and download your certificate. https://trainingportal.linuxfoundation.org/learn/dashboard {{- else }} Come on! you can do it next time! {{- end }}","title":"NOTES.txt"},{"location":"k8s/cka_en/foundamentals/helming/#deployment-template","text":"Let's use Busybox service to generate information. We use kubectl create deployment --dry-run=client -oyaml to generate Deployment yaml file and write it the yaml file content into file templates/deployment.yaml . kubectl create deployment cka-demo-busybox --image=busybox:latest --dry-run=client -oyaml > templates/deployment.yaml Check content of deployment yaml file templates/deployment.yaml . cat templates/deployment.yaml apiVersion : apps/v1 kind : Deployment metadata : creationTimestamp : null labels : app : cka-demo-busybox name : cka-demo-busybox spec : replicas : 1 selector : matchLabels : app : cka-demo-busybox strategy : {} template : metadata : creationTimestamp : null labels : app : cka-demo-busybox spec : containers : - image : busybox:latest name : busybox resources : {} status : {} Edit file templates/deployment.yaml . vi templates/deployment.yaml Let's replace value of .spec.replicas from 1 to a variable {{ .Values.replicaCount }} , so we can dynamicly assign replicas number for other Deployment. apiVersion : apps/v1 kind : Deployment metadata : creationTimestamp : null labels : app : cka-demo-busybox name : cka-demo-busybox spec : replicas : {{ .Values.replicaCount }} selector : matchLabels : app : cka-demo-busybox strategy : {} template : metadata : creationTimestamp : null labels : app : cka-demo-busybox spec : containers : - image : busybox:latest name : busybox resources : {} status : {} The .spec.replicas will be replaced by actula value of .Values.replicaCount during deployment. Let's create another file values.yaml and add a variable replicaCount with default value 1 into the file. Strong recommended to add comments for each value we defined in file values.yaml . vi values.yaml # Number of deployment replicas replicaCount: 1 Let's add more variables into file templates/deployment.yaml . Replace Release name .metadata.name by {{ .Release.Name }} and filled with variable defined in file values.yaml . Replace label name .metadata.labels by {{- include \"cka-demo.labels\" . | nindent 4 }} , and filled with labels name cka-demo.labels defined in file _helpers.tpl . Replace .spec.replicas by {{ .Values.replicaCount }} and filled with variable defined in file values.yaml . Replace .spec.selector.matchLabels by {{- include \"cka-demo.selectorLabels\" . | nindent 6 }} and filled with cka-demo.selectorLabels defined in file _helpers.tpl . Replace .spec.template.metadata.labels by {{- include \"cka-demo.selectorLabels\" . | nindent 8 }} and filled with cka-demo.selectorLabels defined in file _helpers.tpl . Replace .spec.template.spec.containers[0].image by {{ .Values.image.repository }} and {{ .Values.image.tag }} and filled with variables defined in values.yaml for image name and image tag. Replace .spec.template.spec.containers[0].command and add if-else statement, if .Values.passExam is true, execute commands defined in .Values.passCommand , if false, execute commands defined in .Values.lostCommand . Use key from ConfigMap from .spec.template.spec.containers[0].env as prefix of ConfigMap name and filled with {{ .Values.studentName }} defined in file values.yaml . Replace .spec.template.spec.containers[0].resources by {{ .Values.resources }} and filled with variable defined in file values.yaml . The .Release.Name is built-in object, no need to be specified in file values.yaml . It's generated by Release by helm install . Remove unused lines and final one looks like below. apiVersion : apps/v1 kind : Deployment metadata : name : {{ .Release.Name }} labels : {{ - include \"cka-demo.labels\" . | nindent 4 }} spec : replicas : {{ .Values.replicaCount }} selector : matchLabels : {{ - include \"cka-demo.selectorLabels\" . | nindent 6 }} template : metadata : labels : {{ - include \"cka-demo.selectorLabels\" . | nindent 8 }} spec : containers : - name : id-generator image : \"{{ .Values.image.repository }}:{{ .Values.image.tag }}\" {{ - if .Values.passExam }} {{ - with .Values.passCommand }} command : {{ range . }} - {{ . | quote }} {{ - end }} {{ - end }} {{ - else }} {{ - with .Values.lostCommand }} command : {{ range . }} - {{ . | quote }} {{ - end }} {{ - end }} {{ - end }} env : - name : CKA_SCORE valueFrom : configMapKeyRef : name : {{ .Values.studentName }} -cka-score key : cka_score {{ - with .Values.resources }} resources : {{ - toYaml . | nindent 12 }} {{ - end }} restartPolicy : Always Update file values.yaml with variables default values. Suggestions\uff1aadd variables one and test one, don't add all at one time. vi values.yaml # Number of deployment replicas replicaCount: 1 # Image repository and tag image: repository: busybox tag: latest # Container start command passCommand: - '/bin/sh' - '-c' - \"echo Your CKA score is $(CKA_SCORE) and your CKA certificate ID number is $(tr -dc 'A-Za-z0-9' < /dev/urandom | head -c 13; echo) ; sleep 86400\" lostCommand: - '/bin/sh' - '-c' - \"echo Your CKA score is $(CKA_SCORE), Come on! you can do it next time! ; sleep 86400\" # Container resources resources: limits: cpu: 200m memory: 256Mi requests: cpu: 100m memory: 128Mi # Student Name studentName: whoareyou # Student pass CKA exam or not passExam: true","title":"Deployment Template"},{"location":"k8s/cka_en/foundamentals/helming/#configmap-template","text":"ConfigMap is referred in the Deployment, hence we need define the ConfigMap template. We will combine name of ConfigMap and cka_score as a variable, like name-cka-score . vi templates/configmap.yaml apiVersion : v1 kind : ConfigMap metadata : name : {{ .Values.studentName }} -cka-score labels : {{ - include \"cka-demo.labels\" . | nindent 4 }} data : cka_score : {{ .Values.ckaScore | quote }} The studentName was already defined in file values.yaml , we just need add ckaScore with default value. vi values.yaml # Student CKA Score ckaScore: 100","title":"ConfigMap Template"},{"location":"k8s/cka_en/foundamentals/helming/#_helperstpl","text":"Define a common template _helpers.tpl to add labels and labels of Selector for labels of Deployment and ConfigMap. vi templates/_helpers.tpl {{/* Common labels */}} {{- define \"cka-demo.labels\" -}} {{ include \"cka-demo.selectorLabels\" . }} {{- if .Chart.AppVersion }} app.kubernetes.io/version: {{ .Chart.AppVersion | quote }} {{- end }} app.kubernetes.io/managed-by: {{ .Release.Service }} {{- end -}} {{/* Selector labels */}} {{- define \"cka-demo.selectorLabels\" -}} app: {{ .Chart.Name }} release: {{ .Release.Name }} {{- end -}}","title":"_helpers.tpl"},{"location":"k8s/cka_en/foundamentals/helming/#chartyaml","text":"We use CKA logo as the icon of Chart wget https://www.cncf.io/wp-content/uploads/2021/09/kubernetes-cka-color.svg Edit Chart.yaml file. vi Chart.yaml Append icon info in the file. icon: file://./kubernetes-cka-color.svg Add author info for the Chart vi Chart.yaml maintainers: - name: James.H Final Chart.yaml looks like below. Don't forget to update appVersion: \"v1.23\" to current Kubernetes API version. apiVersion : v2 name : cka-demo description : A Helm chart for CKA demo. type : application version : 0.1.0 appVersion : \"v1.23\" maintainers : - name : James.H icon : file://./kubernetes-cka-color.svg","title":"Chart.yaml"},{"location":"k8s/cka_en/foundamentals/helming/#chart-debug","text":"Use helm lint to verify above change. helm lint 1 chart(s) linted, 0 chart(s) failed helm lint only check format of Chart, won't check Manifest file. We can use helm install --debug --dry-run or helm template to check Manifest output in order to verify all yaml files are correct or not. helm template cka-demo ./ Use helm install --debug --dry-run to simulate the installation. We can get expected results from two different options (passed or failed the CKA certificate). helm install --debug --dry-run cka-demo ./ --create-namespace \\ -n cka \\ --set studentName=kubernetes \\ --set ckaScore=99 \\ --set passExam=true helm install --debug --dry-run cka-demo ./ --create-namespace \\ -n cka \\ --set studentName=kubernetes \\ --set ckaScore=0 \\ --set passExam=false Package Chart to .tgz file, and upload to repository, e.g., Chart Museum or OCI Repo. cd ../ helm package cka-demo Successfully packaged chart and saved it to: /root/cka-demo-0.1.0.tgz Till now, we have done our task to develop a Chart. Let's install the Chart. helm install cka-demo cka-demo-0.1.0.tgz --create-namespace \\ -n cka \\ --set studentName=kubernetes \\ --set ckaScore=0 \\ --set passExam=false Result NAME: cka-demo LAST DEPLOYED: Sun Jul 24 19:58:36 2022 NAMESPACE: cka STATUS: deployed REVISION: 1 TEST SUITE: None NOTES: Come on! you can do it next time! Check the deployment helm list --all-namespaces Result NAME NAMESPACE REVISION UPDATED STATUS CHART APP VERSION cka-demo cka 1 2022-07-24 19:58:36.272093383 +0800 CST deployed cka-demo-0.1.0 v1.23 mysql dev 1 2022-07-24 19:37:20.710988009 +0800 CST deployed mysql-9.2.1 8.0.29 If any error, need to unstall cka-demo and reinstall it. helm uninstall cka-demo -n Check log of cka-demo . kubectl logs -n cka -l app=cka-demo Result Your CKA score is 0, Come on! you can do it next time! Install cka-demo with different options. helm uninstall cka-demo -n cka helm install cka-demo cka-demo-0.1.0.tgz --create-namespace \\ -n cka \\ --set studentName=kubernetes \\ --set ckaScore=100 \\ --set passExam=true NAME: cka-demo LAST DEPLOYED: Sun Jul 24 20:01:34 2022 NAMESPACE: cka STATUS: deployed REVISION: 1 TEST SUITE: None NOTES: Congratulations! You have successfully completed Certified Kubernetes Administrator China Exam (CKA-CN). Your CKA score is: 100 Click the link below to view and download your certificate. https://trainingportal.linuxfoundation.org/learn/dashboard Check log of cka-demo . kubectl logs -n cka -l app=cka-demo Your CKA score is 100 and your CKA certificate ID number is BQKoVYVhjzl3G Built-in Objects: Release.Name # \u53d1\u5e03\u540d\u79f0 Release.Namespace # \u53d1\u5e03Namespace Release.Service # \u6e32\u67d3\u6a21\u677f\u7684\u670d\u52a1\uff0c\u5728Helm\u4e2d\u9ed8\u8ba4\u503c\u4e3a\"Helm\" Release.IsUpgrade # \u5982\u679c\u5f53\u524d\u662f\u5347\u7ea7\u6216\u56de\u6eda\uff0c\u8bbe\u7f6e\u4e3atrue Release.IsInstall # \u5982\u679c\u5f53\u524d\u662f\u5b89\u88c5\uff0c\u8bbe\u7f6e\u4e3atrue Release.Revision # \u53d1\u5e03\u7248\u672c\u53f7 Values # \u4ecevalues.yaml\u548c--set\u4f20\u5165\uff0c\u9ed8\u8ba4\u4e3a\u7a7a Chart # \u6240\u6709Chart.yaml\u4e2d\u7684\u5185\u5bb9 Chart.Version # Chart.Maintainers # Files # \u5728chart\u4e2d\u8bbf\u95ee\u975e\u7279\u6b8a\u6587\u4ef6 Capabilities # \u63d0\u4f9b\u5173\u4e8e\u652f\u6301\u80fd\u529b\u7684\u4fe1\u606f\uff08K8s API\u7248\u672c\u3001K8s\u7248\u672c\u3001Helm\u7248\u672c\uff09 Capabilities.KubeVersion # Kubernetes\u7684\u7248\u672c\u53f7 Capabilities.APIVersions.Has \"batch/v1\" # K8s API\u7248\u672c\u5305\u542b\"batch/v1\" Template # \u5f53\u524d\u6a21\u677f\u4fe1\u606f Template.Name # \u5f53\u524d\u6a21\u677f\u6587\u4ef6\u8def\u5f84 Template.BasePath # \u5f53\u524d\u6a21\u677f\u76ee\u5f55\u8def\u5f84 Reference: Helm \u5b98\u7f51 Helm \u7248\u672c\u652f\u6301\u7b56\u7565 Helm Chart \u8d44\u6e90\u5bf9\u8c61\u5b89\u88c5\u987a\u5e8f","title":"Chart Debug"},{"location":"k8s/cka_en/foundamentals/hpa/","text":"Horizontal Pod Autoscaling (HPA) \u00b6 Scenario: Install Metrics Server component Create Deployment podinfo and Service podinfo for stress testing Create HPA my-hpa Stress Testing Demo: Install Metrics Server component \u00b6 Download yaml file for Metrics Server component wget https://github.com/kubernetes-sigs/metrics-server/releases/latest/download/components.yaml Replace Google image by Aliyun image image: registry.aliyuncs.com/google_containers/metrics-server:v0.6.1 . sed -i 's/k8s\\.gcr\\.io\\/metrics-server\\/metrics-server\\:v0\\.6\\.1/registry\\.aliyuncs\\.com\\/google_containers\\/metrics-server\\:v0\\.6\\.1/g' components.yaml Change arg of deployment metrics-server by adding --kubelet-insecure-tls to disable tls certificate validation. vi components.yaml Updated arg of metrics-server is below. ...... template : metadata : labels : k8s-app : metrics-server spec : containers : - args : - --cert-dir=/tmp - --secure-port=4443 - --kubelet-preferred-address-types=InternalIP,ExternalIP,Hostname - --kubelet-use-node-status-port - --metric-resolution=15s - --kubelet-insecure-tls image : registry.aliyuncs.com/google_containers/metrics-server:v0.6.1 ...... Appy the yaml file components.yaml to deploy metrics-server . kubectl apply -f components.yaml Below resources were crested. serviceaccount/metrics-server created clusterrole.rbac.authorization.k8s.io/system:aggregated-metrics-reader created clusterrole.rbac.authorization.k8s.io/system:metrics-server created rolebinding.rbac.authorization.k8s.io/metrics-server-auth-reader created clusterrolebinding.rbac.authorization.k8s.io/metrics-server:system:auth-delegator created clusterrolebinding.rbac.authorization.k8s.io/system:metrics-server created service/metrics-server created deployment.apps/metrics-server created apiservice.apiregistration.k8s.io/v1beta1.metrics.k8s.io created Verify if metrics-server Pod is running as expected ( 1/1 running) kubectl get pod -n kube-system -owide | grep metrics-server Result NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES metrics-server-7fd564dc66-sdhdc 1/1 Running 0 61s 10.244.102.15 cka003 Get current usage of CPU, memory of each node. kubectl top node Result: NAME CPU(cores) CPU% MEMORY(bytes) MEMORY% cka001 595m 29% 1937Mi 50% cka002 75m 3% 1081Mi 28% cka003 79m 3% 1026Mi 26% Deploy a Service podinfo \u00b6 Create Deployment podinfo and Service podinfo for further stress testing. kubectl apply -f - << EOF apiVersion: v1 kind: Service metadata: name: podinfo labels: app: podinfo spec: type: NodePort ports: - port: 9898 targetPort: 9898 nodePort: 31198 protocol: TCP selector: app: podinfo --- apiVersion: apps/v1 kind: Deployment metadata: name: podinfo labels: app: podinfo spec: replicas: 2 selector: matchLabels: app: podinfo template: metadata: labels: app: podinfo spec: containers: - name: podinfod image: stefanprodan/podinfo:0.0.1 imagePullPolicy: Always command: - ./podinfo - -port=9898 - -logtostderr=true - -v=2 ports: - containerPort: 9898 protocol: TCP resources: requests: memory: \"32Mi\" cpu: \"10m\" limits: memory: \"256Mi\" cpu: \"100m\" EOF Config HPA \u00b6 Create HPA my-hpa by setting CPU threshold 50% to trigger auto-scalling with minimal 2 and maximal 10 Replicas. Use kubectl autoscal to create HPA my-hpa . kubectl autoscale deployment podinfo --cpu-percent=50 --min=1 --max=10 Use autoscaling/v1 version template to crreate HPA my-hpa . kubectl apply -f - < Get current usage of CPU, memory of each node. kubectl top node Result: NAME CPU(cores) CPU% MEMORY(bytes) MEMORY% cka001 595m 29% 1937Mi 50% cka002 75m 3% 1081Mi 28% cka003 79m 3% 1026Mi 26%","title":"Install Metrics Server component"},{"location":"k8s/cka_en/foundamentals/hpa/#deploy-a-service-podinfo","text":"Create Deployment podinfo and Service podinfo for further stress testing. kubectl apply -f - << EOF apiVersion: v1 kind: Service metadata: name: podinfo labels: app: podinfo spec: type: NodePort ports: - port: 9898 targetPort: 9898 nodePort: 31198 protocol: TCP selector: app: podinfo --- apiVersion: apps/v1 kind: Deployment metadata: name: podinfo labels: app: podinfo spec: replicas: 2 selector: matchLabels: app: podinfo template: metadata: labels: app: podinfo spec: containers: - name: podinfod image: stefanprodan/podinfo:0.0.1 imagePullPolicy: Always command: - ./podinfo - -port=9898 - -logtostderr=true - -v=2 ports: - containerPort: 9898 protocol: TCP resources: requests: memory: \"32Mi\" cpu: \"10m\" limits: memory: \"256Mi\" cpu: \"100m\" EOF","title":"Deploy a Service podinfo"},{"location":"k8s/cka_en/foundamentals/hpa/#config-hpa","text":"Create HPA my-hpa by setting CPU threshold 50% to trigger auto-scalling with minimal 2 and maximal 10 Replicas. Use kubectl autoscal to create HPA my-hpa . kubectl autoscale deployment podinfo --cpu-percent=50 --min=1 --max=10 Use autoscaling/v1 version template to crreate HPA my-hpa . kubectl apply -f - <

It works!

Clean up. kubectl delete ingress demo-localhost kubectl delete service demo kubectl delete deployment demo Create Deployments \u00b6 Create two deployment nginx-app-1 and nginx-app-2 . kubectl apply -f - << EOF apiVersion: apps/v1 kind: Deployment metadata: name: nginx-app-1 spec: selector: matchLabels: app: nginx-app-1 replicas: 1 template: metadata: labels: app: nginx-app-1 spec: containers: - name: nginx image: nginx ports: - containerPort: 80 volumeMounts: - name: html mountPath: /usr/share/nginx/html volumes: - name: html hostPath: path: /opt/html-1 --- apiVersion: apps/v1 kind: Deployment metadata: name: nginx-app-2 spec: selector: matchLabels: app: nginx-app-2 replicas: 1 template: metadata: labels: app: nginx-app-2 spec: containers: - name: nginx image: nginx ports: - containerPort: 80 volumeMounts: - name: html mountPath: /usr/share/nginx/html volumes: - name: html hostPath: path: /opt/html-2 EOF Get status of Pods by executing kubectl get pod -o wide . One pod is running on node cka002 , another pod is running on node cka003 . Directory /opt/html-2/ is on cka002 Directory /opt/html-1/ is on cka002 Access to two Pod via curl. We get 403 Forbidden error. curl 10.244.102.13 curl 10.244.112.19 Log onto node cka002 , create index.html file in path /opt/html-2/ with below command. cat < app1.com app2.com EOF Get IP address or FQDN with the following command: kubectl get service ingress-nginx-controller --namespace=ingress-nginx It will be the EXTERNAL-IP field. If that field shows like below, this means that the Kubernetes cluster wasn't able to provision the load balancer (generally, this is because it doesn't support services of type LoadBalancer). As there is no Aliyun ELB configured, use below two options to make the external IP in place. Option 1: manually add node ip to ingress controller, which the controller pod is running on. Execute command kubectl get pod -n ingress-nginx -o wide to see that ingress controller pod is running on node cka003 . Manually patch the external ip of cak003 to the EXTERNAL-IP field. kubectl patch svc ingress-nginx-controller \\ --namespace=ingress-nginx \\ -p '{\"spec\": {\"type\": \"LoadBalancer\", \"externalIPs\":[\"\"]}}' Option 2: change ingress controller from LoadBalancer to NodePort . Two files index.html are in two Pods, the web services are exposed to outside via node IP. The ingress-nginx-controller plays a central entry point for outside access, and provide two ports for different backend services from Pods. Send HTTP request to two hosts defined in Ingress. curl http://app1.com:30011 curl http://app2.com:30011 curl app1.com:30011 curl app2.com:30011 Get below successful information. This is test 1 !! This is test 2 !! Clean up. kubectl delete ingress ingress-nginx-app kubectl delete service nginx-app-1 kubectl delete service nginx-app-2 kubectl delete deployment nginx-app-1 kubectl delete deployment nginx-app-2","title":"Ingress"},{"location":"k8s/cka_en/foundamentals/ingress/#ingress-nginx","text":"Scenario *Deploy Ingress Controller. * Create two deployment nginx-app-1 and nginx-app-2 . *Host directory /root/html-1 and /root/html-2 will be created and mounted to two Deployments on running host. * Create Service. *Create Service nginx-app-1 and nginx-app-2 and map to related Deployment nginx-app-1 and nginx-app-2 . * Create Ingress. *Create Ingress resource nginx-app and map to two Services nginx-app-1 and nginx-app-1 . * Test Accessibility. * Send HTTP request to two hosts defined in Ingress Reference *Github ingress-nginx * Installation Guide","title":"Ingress-nginx"},{"location":"k8s/cka_en/foundamentals/ingress/#deploy-ingress-controller","text":"Get Ingress Controller yaml file. The latest version link is in Installation Guide . wget https://raw.githubusercontent.com/kubernetes/ingress-nginx/controller-v1.3.0/deploy/static/provider/cloud/deploy.yaml Below two images's sources needto be changed to Aliyun. image: k8s.gcr.io/ingress-nginx/controller:v1.2.1@sha256:5516d103a9c2ecc4f026efbd4b40662ce22dc1f824fb129ed121460aaa5c47f8 image: registry.k8s.io/ingress-nginx/controller:v1.3.0@sha256:d1707ca76d3b044ab8a28277a2466a02100ee9f58a86af1535a3edf9323ea1b5 image: k8s.gcr.io/ingress-nginx/kube-webhook-certgen:v1.1.1@sha256:64d8c73dca984af206adf9d6d7e46aa550362b1d7a01f3a0a91b20cc67868660 From grc.io to Aliyun. k8s.gcr.io/ingress-nginx/controller to registry.aliyuncs.com/google_containers/nginx-ingress-controller registry.k8s.io/ingress-nginx/controller to registry.aliyuncs.com/google_containers/nginx-ingress-controller * k8s.gcr.io/ingress-nginx/kube-webhook-certgen to registry.aliyuncs.com/google_containers/kube-webhook-certgen Commands: sed -i 's/k8s.gcr.io\\/ingress-nginx\\/kube-webhook-certgen/registry.aliyuncs.com\\/google\\_containers\\/kube-webhook-certgen/g' deploy.yaml sed -i 's/k8s.gcr.io\\/ingress-nginx\\/controller/registry.aliyuncs.com\\/google\\_containers\\/nginx-ingress-controller/g' deploy.yaml Apply the yaml file deploy.yaml to create Ingress Nginx. A new namespace ingress-nginx was created and Ingress Nginx resources are running under the new namespace. kubectl apply -f deploy.yaml Check the status of Pod. kubectl get pod -n ingress-nginx Make sure all pods are not in error status, like below. NAME READY STATUS RESTARTS AGE ingress-nginx-admission-create-lgtdj 0/1 Completed 0 49s ingress-nginx-admission-patch-nk9fv 0/1 Completed 0 49s ingress-nginx-controller-556fbd6d6f-6jl4x 1/1 Running 0 49s","title":"Deploy Ingress Controller"},{"location":"k8s/cka_en/foundamentals/ingress/#local-testing","text":"Let's create a simple web server and the associated service: kubectl create deployment demo --image=httpd --port=80 kubectl expose deployment demo Then create an ingress resource. The following example uses a host that maps to localhost: kubectl create ingress demo-localhost --class=nginx --rule=\"demo.localdev.me/*=demo:80\" Now, forward a local port to the ingress controller: kubectl port-forward --namespace=ingress-nginx service/ingress-nginx-controller 8080:80 At this point, open another terminal to access http://demo.localdev.me:8080/ , we should see an HTML page telling you \"It works!\". curl http://demo.localdev.me:8080/ Result

It works!

Clean up. kubectl delete ingress demo-localhost kubectl delete service demo kubectl delete deployment demo","title":"Local testing"},{"location":"k8s/cka_en/foundamentals/ingress/#create-deployments","text":"Create two deployment nginx-app-1 and nginx-app-2 . kubectl apply -f - << EOF apiVersion: apps/v1 kind: Deployment metadata: name: nginx-app-1 spec: selector: matchLabels: app: nginx-app-1 replicas: 1 template: metadata: labels: app: nginx-app-1 spec: containers: - name: nginx image: nginx ports: - containerPort: 80 volumeMounts: - name: html mountPath: /usr/share/nginx/html volumes: - name: html hostPath: path: /opt/html-1 --- apiVersion: apps/v1 kind: Deployment metadata: name: nginx-app-2 spec: selector: matchLabels: app: nginx-app-2 replicas: 1 template: metadata: labels: app: nginx-app-2 spec: containers: - name: nginx image: nginx ports: - containerPort: 80 volumeMounts: - name: html mountPath: /usr/share/nginx/html volumes: - name: html hostPath: path: /opt/html-2 EOF Get status of Pods by executing kubectl get pod -o wide . One pod is running on node cka002 , another pod is running on node cka003 . Directory /opt/html-2/ is on cka002 Directory /opt/html-1/ is on cka002 Access to two Pod via curl. We get 403 Forbidden error. curl 10.244.102.13 curl 10.244.112.19 Log onto node cka002 , create index.html file in path /opt/html-2/ with below command. cat < app1.com app2.com EOF Get IP address or FQDN with the following command: kubectl get service ingress-nginx-controller --namespace=ingress-nginx It will be the EXTERNAL-IP field. If that field shows like below, this means that the Kubernetes cluster wasn't able to provision the load balancer (generally, this is because it doesn't support services of type LoadBalancer). As there is no Aliyun ELB configured, use below two options to make the external IP in place. Option 1: manually add node ip to ingress controller, which the controller pod is running on. Execute command kubectl get pod -n ingress-nginx -o wide to see that ingress controller pod is running on node cka003 . Manually patch the external ip of cak003 to the EXTERNAL-IP field. kubectl patch svc ingress-nginx-controller \\ --namespace=ingress-nginx \\ -p '{\"spec\": {\"type\": \"LoadBalancer\", \"externalIPs\":[\"\"]}}' Option 2: change ingress controller from LoadBalancer to NodePort . Two files index.html are in two Pods, the web services are exposed to outside via node IP. The ingress-nginx-controller plays a central entry point for outside access, and provide two ports for different backend services from Pods. Send HTTP request to two hosts defined in Ingress. curl http://app1.com:30011 curl http://app2.com:30011 curl app1.com:30011 curl app2.com:30011 Get below successful information. This is test 1 !! This is test 2 !! Clean up. kubectl delete ingress ingress-nginx-app kubectl delete service nginx-app-1 kubectl delete service nginx-app-2 kubectl delete deployment nginx-app-1 kubectl delete deployment nginx-app-2","title":"Test Accessiblity"},{"location":"k8s/cka_en/foundamentals/job/","text":"Job and Cronjob \u00b6 Job \u00b6 Scenario Create Job. Demo: Create Job pi . kubectl apply -f - << EOF apiVersion: batch/v1 kind: Job metadata: name: pi spec: template: spec: containers: - name: pi image: perl:5.34 command: [\"perl\", \"-Mbignum=bpi\", \"-wle\", \"print bpi(2000)\"] restartPolicy: Never backoffLimit: 4 EOF Get details of Job. kubectl get jobs Get details of Job Pod. The status Completed means the job was done successfully. kubectl get pod Get log info of the Job Pod. kubectl pi-2s74d 3.141592653589793.............. Clean up kubectl delete job pi Cronjob \u00b6 Scenario Create Cronjob. Demo: Create Cronjob hello . kubectl apply -f - << EOF apiVersion: batch/v1 kind: CronJob metadata: name: hello spec: schedule: \"*/1 * * * *\" jobTemplate: spec: template: spec: containers: - name: hello image: busybox args: - /bin/sh - -c - date ; echo Hello from the kubernetes cluster restartPolicy: OnFailure EOF Get detail of Cronjob kubectl get cronjobs -o wide Result NAME SCHEDULE SUSPEND ACTIVE LAST SCHEDULE AGE CONTAINERS IMAGES SELECTOR hello */1 * * * * False 0 25s hello busybox Monitor Jobs. Every 1 minute a new job will be created. kubectl get jobs -w Clean up kubectl delete cronjob hello","title":"Job and Cronjob"},{"location":"k8s/cka_en/foundamentals/job/#job-and-cronjob","text":"","title":"Job and Cronjob"},{"location":"k8s/cka_en/foundamentals/job/#job","text":"Scenario Create Job. Demo: Create Job pi . kubectl apply -f - << EOF apiVersion: batch/v1 kind: Job metadata: name: pi spec: template: spec: containers: - name: pi image: perl:5.34 command: [\"perl\", \"-Mbignum=bpi\", \"-wle\", \"print bpi(2000)\"] restartPolicy: Never backoffLimit: 4 EOF Get details of Job. kubectl get jobs Get details of Job Pod. The status Completed means the job was done successfully. kubectl get pod Get log info of the Job Pod. kubectl pi-2s74d 3.141592653589793.............. Clean up kubectl delete job pi","title":"Job"},{"location":"k8s/cka_en/foundamentals/job/#cronjob","text":"Scenario Create Cronjob. Demo: Create Cronjob hello . kubectl apply -f - << EOF apiVersion: batch/v1 kind: CronJob metadata: name: hello spec: schedule: \"*/1 * * * *\" jobTemplate: spec: template: spec: containers: - name: hello image: busybox args: - /bin/sh - -c - date ; echo Hello from the kubernetes cluster restartPolicy: OnFailure EOF Get detail of Cronjob kubectl get cronjobs -o wide Result NAME SCHEDULE SUSPEND ACTIVE LAST SCHEDULE AGE CONTAINERS IMAGES SELECTOR hello */1 * * * * False 0 25s hello busybox Monitor Jobs. Every 1 minute a new job will be created. kubectl get jobs -w Clean up kubectl delete cronjob hello","title":"Cronjob"},{"location":"k8s/cka_en/foundamentals/kyma/","text":"Kyma \u00b6 Deploy Kyma on control plane node. Install Kyma CLI \u00b6 Install Kyma CLI on Linux, run: curl -Lo kyma.tar.gz \"https://github.com/kyma-project/cli/releases/download/$(curl -s https://api.github.com/repos/kyma-project/cli/releases/latest | grep tag_name | cut -d '\"' -f 4)/kyma_Linux_x86_64.tar.gz\" mkdir /opt/kyma-release tar -C /opt/kyma-release -zxvf kyma.tar.gz chmod +x /opt/kyma-release/kyma sudo cp /opt/kyma-release/kyma /usr/local/bin rm -rf kyma-release kyma.tar.gz Reference Install Kyma CLI Install Kyma \u00b6 Use the deploy command to install Kyma. kyma deploy Get file components.yaml to manually install failed components. If no Namespace provided, the default Namespace called kyma-system is used. For example: kyma deploy --component serverless@kyma-integration kyma deploy --component monitoring@kyma-integration kyma deploy --component kiali@kyma-integration File components.yaml looks like below. --- defaultNamespace: kyma-system prerequisites: - name: \"cluster-essentials\" - name: \"istio\" namespace: \"istio-system\" - name: \"certificates\" namespace: \"istio-system\" components: - name: \"istio-resources\" - name: \"logging\" - name: \"telemetry\" - name: \"tracing\" - name: \"kiali\" - name: \"monitoring\" - name: \"eventing\" - name: \"ory\" - name: \"api-gateway\" - name: \"cluster-users\" - name: \"serverless\" - name: \"application-connector\" namespace: \"kyma-integration\" Reference: By default, Kyma is installed with the default chart values defined in the values.yaml files. You can also control the allocation of resources, such as memory and CPU, that the components consume by installing Kyma with the following pre-defined profiles: Evaluation needs limited resources and is suited for trial purposes. Production is configured for high availability and scalability. It requires more resources than the evaluation profile but is a better choice for production workload. Install Kyma To see a complete list of all Kyma components go to the components.yaml file. Install specific components kyma deploy --components-file {COMPONENTS_FILE_PATH}","title":"Kyma"},{"location":"k8s/cka_en/foundamentals/kyma/#kyma","text":"Deploy Kyma on control plane node.","title":"Kyma"},{"location":"k8s/cka_en/foundamentals/kyma/#install-kyma-cli","text":"Install Kyma CLI on Linux, run: curl -Lo kyma.tar.gz \"https://github.com/kyma-project/cli/releases/download/$(curl -s https://api.github.com/repos/kyma-project/cli/releases/latest | grep tag_name | cut -d '\"' -f 4)/kyma_Linux_x86_64.tar.gz\" mkdir /opt/kyma-release tar -C /opt/kyma-release -zxvf kyma.tar.gz chmod +x /opt/kyma-release/kyma sudo cp /opt/kyma-release/kyma /usr/local/bin rm -rf kyma-release kyma.tar.gz Reference Install Kyma CLI","title":"Install Kyma CLI"},{"location":"k8s/cka_en/foundamentals/kyma/#install-kyma","text":"Use the deploy command to install Kyma. kyma deploy Get file components.yaml to manually install failed components. If no Namespace provided, the default Namespace called kyma-system is used. For example: kyma deploy --component serverless@kyma-integration kyma deploy --component monitoring@kyma-integration kyma deploy --component kiali@kyma-integration File components.yaml looks like below. --- defaultNamespace: kyma-system prerequisites: - name: \"cluster-essentials\" - name: \"istio\" namespace: \"istio-system\" - name: \"certificates\" namespace: \"istio-system\" components: - name: \"istio-resources\" - name: \"logging\" - name: \"telemetry\" - name: \"tracing\" - name: \"kiali\" - name: \"monitoring\" - name: \"eventing\" - name: \"ory\" - name: \"api-gateway\" - name: \"cluster-users\" - name: \"serverless\" - name: \"application-connector\" namespace: \"kyma-integration\" Reference: By default, Kyma is installed with the default chart values defined in the values.yaml files. You can also control the allocation of resources, such as memory and CPU, that the components consume by installing Kyma with the following pre-defined profiles: Evaluation needs limited resources and is suited for trial purposes. Production is configured for high availability and scalability. It requires more resources than the evaluation profile but is a better choice for production workload. Install Kyma To see a complete list of all Kyma components go to the components.yaml file. Install specific components kyma deploy --components-file {COMPONENTS_FILE_PATH}","title":"Install Kyma"},{"location":"k8s/cka_en/foundamentals/memo/","text":"Kubernetes Learning Memo \u00b6 Basic Concepts of Kubernetes \u00b6 Kubernetes Components \u00b6 A Kubernetes cluster consists of the components that represent the control plane and a set of machines called nodes . Kubernetes Components : Control Plane Components kube-apiserver: query and manipulate the state of objects in Kubernetes. play as \"communication hub\" among all resources in cluster. provide cluster security authentication, authorization, and role assignment. the only one can connect to etcd . etcd: all Kubernetes objects are stored on etcd. Kubernetes objects are persistent entities in the Kubernetes system, which are used to represent the state of your cluster. kube-scheduler: watches for newly created Pods with no assigned node, and selects a node for them to run on. kube-controller-manager: runs controller processes. Node controller : Responsible for noticing and responding when nodes go down. Job controller : Watches for Job objects that represent one-off tasks, then creates Pods to run those tasks to completion. Endpoints controller : Populates the Endpoints object (that is, joins Services & Pods). Service Account & Token controllers : Create default accounts and API access tokens for new namespaces. cloud-controller-manager: embeds cloud-specific control logic and only runs controllers that are specific to your cloud provider, no need for own premises and learning environment. Node controller : For checking the cloud provider to determine if a node has been deleted in the cloud after it stops responding Route controller : For setting up routes in the underlying cloud infrastructure Service controller : For creating, updating and deleting cloud provider load balancers Node Components kubelet: An agent that runs on each node in the cluster. Manage node. It makes sure that containers are running in a Pod. kubelet registers and updates nodes information to APIServer, and APIServer stores them into etcd . Manage pod. Watch pod via APIServer, and action on pods or containers in pods. Health check at container level. kube-proxy: is a network proxy that runs on each node in cluster. iptables ipvs maintains network rules on nodes. Container runtime: is the software that is responsible for running containers. Addons DNS: is a DNS server and required by all Kubernetes clusters. Web UI (Dashboard): web-based UI for Kubernetes clusters. Container Resource Monitoring: records generic time-series metrics about containers in a central database Cluster-level Logging: is responsible for saving container logs to a central log store with search/browsing interface. Scalability: Scaling out (horizontal scaling) by adding more servers to your architecture to spread the workload across more machines. Scaling up (vertical scaling) by adding more hard drives and memory to increase the computing capacity of physical servers. Kubernetes API \u00b6 The REST API is the fundamental fabric of Kubernetes. All operations and communications between components, and external user commands are REST API calls that the API Server handles. Consequently, everything in the Kubernetes platform is treated as an API object and has a corresponding entry in the API. The core of Kubernetes' control plane is the API server. CRI: Container Runtime Interface CNI: Container Network Interface CSI: Container Storage Interface The API server exposes an HTTP API that lets end users, different parts of cluster, and external components communicate with one another. The Kubernetes API lets we query and manipulate the state of API objects in Kubernetes (for example: Pods, Namespaces, ConfigMaps, and Events). Kubernetes API: OpenAPI specification OpenAPI V2 OpenAPI V3 Persistence. Kubernetes stores the serialized state of objects by writing them into etcd. API groups and versioning. Versioning is done at the API level. API resources are distinguished by their API group, resource type, namespace (for namespaced resources), and name. API changes API Extension API Version \u00b6 The API versioning and software versioning are indirectly related. The API and release versioning proposal describes the relationship between API versioning and software versioning. Different API versions indicate different levels of stability and support. Here's a summary of each level: Alpha: The version names contain alpha (for example, v1alpha1). The software may contain bugs. Enabling a feature may expose bugs. A feature may be disabled by default. The support for a feature may be dropped at any time without notice. The API may change in incompatible ways in a later software release without notice. The software is recommended for use only in short-lived testing clusters, due to increased risk of bugs and lack of long-term support. Beta: The version names contain beta (for example, v2beta3). The software is well tested. Enabling a feature is considered safe. Features are enabled by default. The support for a feature will not be dropped, though the details may change. The schema and/or semantics of objects may change in incompatible ways in a subsequent beta or stable release. When this happens, migration instructions are provided. Schema changes may require deleting, editing, and re-creating API objects. The editing process may not be straightforward. The migration may require downtime for applications that rely on the feature. The software is not recommended for production uses. Subsequent releases may introduce incompatible changes. If you have multiple clusters which can be upgraded independently, you may be able to relax this restriction. Note: Please try beta features and provide feedback. After the features exit beta, it may not be practical to make more changes. Stable: The version name is vX where X is an integer. The stable versions of features appear in released software for many subsequent versions. Command to get current API kubectl api-resources API Group \u00b6 API groups make it easier to extend the Kubernetes API. The API group is specified in a REST path and in the apiVersion field of a serialized object. There are several API groups in Kubernetes: The core (also called legacy) group is found at REST path /api/v1 . The core group is not specified as part of the apiVersion field, for example, apiVersion: v1. The named groups are at REST path /apis/$GROUP_NAME/$VERSION and use apiVersion: $GROUP_NAME/$VERSION (for example, apiVersion: batch/v1). Kubernetes Objects \u00b6 Objects Overview \u00b6 Object Spec: providing a description of the characteristics the resource created to have: its desired state . Object Status: describes the current state of the object. Example of Deployment as an object that can represent an application running on cluster. apiVersion : apps/v1 # Which version of the Kubernetes API you're using to create this object kind : Deployment # What kind of object you want to create metadata : # Data that helps uniquely identify the object, including a name string, UID, and optional namespace name : nginx-deployment spec : # What state you desire for the object selector : matchLabels : app : nginx replicas : 2 # tells deployment to run 2 pods matching the template template : metadata : labels : app : nginx spec : containers : - name : nginx image : nginx:1.14.2 ports : - containerPort : 80 Object Management \u00b6 The kubectl command-line tool supports several different ways to create and manage Kubernetes objects. Read the Kubectl book for details. A Kubernetes object should be managed using ONLY one technique. Mixing and matching techniques for the same object results in undefined behavior. Three management techniques: Imperative commands operates directly on live objects in a cluster. kubectl create deployment nginx --image nginx Imperative object configuration kubectl create -f nginx.yaml kubectl delete -f nginx.yaml -f redis.yaml kubectl replace -f nginx.yaml Declarative object configuration kubectl diff -f configs/ kubectl apply -f configs/ Object Names and IDs \u00b6 Each object in your cluster has a Name that is unique for that type of resource. DNS Subdomain Names Label Names Path Segment Names Every Kubernetes object also has a UID that is unique across the whole cluster. Namespaces \u00b6 In Kubernetes, namespaces provides a mechanism for isolating groups of resources within a single cluster. Names of resources need to be unique within a namespace, but not across namespaces. Namespace-based scoping is applicable only for namespaced objects (e.g. Deployments, Services, etc) and not for cluster-wide objects (e.g. StorageClass, Nodes, PersistentVolumes, etc) Not All Objects are in a Namespace. Kubernetes starts with four initial namespaces: default The default namespace for objects with no other namespace kube-system The namespace for objects created by the Kubernetes system kube-public This namespace is created automatically and is readable by all users (including those not authenticated). This namespace is mostly reserved for cluster usage, in case that some resources should be visible and readable publicly throughout the whole cluster. The public aspect of this namespace is only a convention, not a requirement. kube-node-lease This namespace holds Lease objects associated with each node. Node leases allow the kubelet to send heartbeats so that the control plane can detect node failure. Viewing namespaces: kubectl get namespace Setting the namespace for a request kubectl run nginx --image=nginx --namespace= kubectl get pods --namespace= Labels and Selectors \u00b6 Labels are key/value pairs that are attached to objects, such as pods. Valid label keys have two segments: an optional prefix and name, separated by a slash ( / ). Labels are intended to be used to specify identifying attributes of objects that are meaningful and relevant to users. Labels can be used to organize and to select subsets of objects. Labels can be attached to objects at creation time and subsequently added and modified at any time. Each object can have a set of key/value labels defined. Each Key must be unique for a given object. Example of labels: \"metadata\" : { \"labels\" : { \"key1\" : \"value1\" , \"key2\" : \"value2\" } } Unlike names and UIDs, labels do not provide uniqueness. In general, we expect many objects to carry the same label(s). The API currently supports two types of selectors: equality-based, e.g., environment = production , tier != frontend set-based, e.g., environment in (production, qa) , tier notin (frontend, backend) Sample commands: kubectl get pods -l environment=production,tier=frontend kubectl get pods -l 'environment in (production),tier in (frontend)' kubectl get pods -l 'environment in (production, qa)' kubectl get pods -l 'environment,environment notin (frontend)' Annotations \u00b6 Use Kubernetes annotations to attach arbitrary non-identifying metadata to objects. Clients such as tools and libraries can retrieve this metadata. Use either labels or annotations to attach metadata to Kubernetes objects. Labels can be used to select objects and to find collections of objects that satisfy certain conditions. Annotations are not used to identify and select objects. Annotations, like labels, are key/value maps. The keys and the values in the map must be strings. \"metadata\" : { \"annotations\" : { \"key1\" : \"value1\" , \"key2\" : \"value2\" } } Valid annotation keys have two segments: an optional prefix and name, separated by a slash ( / ). Field Selectors \u00b6 Field selectors let you select Kubernetes resources based on the value of one or more resource fields. Here are some examples of field selector queries: metadata.name=my-service metadata.namespace!=default status.phase=Pending This kubectl command selects all Pods for which the value of the status.phase field is Running: kubectl get pods --field-selector status.phase=Running Supported field selectors vary by Kubernetes resource type. All resource types support the metadata.name and metadata.namespace fields. Use the = , == , and != operators with field selectors ( = and == mean the same thing). For example: kubectl get ingress --field-selector foo.bar=baz With operators, kubectl get services --all-namespaces --field-selector metadata.namespace!=default Chained selectors, kubectl get pods --field-selector=status.phase!=Running,spec.restartPolicy=Always Multiple resource types, kubectl get statefulsets,services --all-namespaces --field-selector metadata.namespace!=default Finalizers \u00b6 Finalizers are namespaced keys that tell Kubernetes to wait until specific conditions are met before it fully deletes resources marked for deletion . Finalizers alert controllers to clean up resources the deleted object owned. Finalizers are usually added to resources for a reason, so forcefully removing them can lead to issues in the cluster. Like labels, owner references describe the relationships between objects in Kubernetes, but are used for a different purpose. Kubernetes uses the owner references (not labels) to determine which Pods in the cluster need cleanup. Kubernetes processes finalizers when it identifies owner references on a resource targeted for deletion. Owners and Dependents \u00b6 In Kubernetes, some objects are owners of other objects. For example, a ReplicaSet is the owner of a set of Pods. These owned objects are dependents of their owner. Dependent objects have a metadata.ownerReferences field that references their owner object. A valid owner reference consists of the object name and a UID within the same namespace as the dependent object. Dependent objects also have an ownerReferences.blockOwnerDeletion field that takes a boolean value and controls whether specific dependents can block garbage collection from deleting their owner object. Resource \u00b6 Kubernetes resources and \"records of intent\" are all stored as API objects, and modified via RESTful calls to the API. The API allows configuration to be managed in a declarative way. Users can interact with the Kubernetes API directly, or via tools like kubectl. The core Kubernetes API is flexible and can also be extended to support custom resources. Workload Resources Pod . Pod is a collection of containers that can run on a host. PodTemplate . PodTemplate describes a template for creating copies of a predefined pod. ReplicationController . ReplicationController represents the configuration of a replication controller. ReplicaSet . ReplicaSet ensures that a specified number of pod replicas are running at any given time. Deployment . Deployment enables declarative updates for Pods and ReplicaSets. StatefulSet . StatefulSet represents a set of pods with consistent identities. ControllerRevision . ControllerRevision implements an immutable snapshot of state data. DaemonSet . DaemonSet represents the configuration of a daemon set. Job . Job represents the configuration of a single job. CronJob . CronJob represents the configuration of a single cron job. HorizontalPodAutoscaler . configuration of a horizontal pod autoscaler. HorizontalPodAutoscaler . HorizontalPodAutoscaler is the configuration for a horizontal pod autoscaler, which automatically manages the replica count of any resource implementing the scale subresource based on the metrics specified. HorizontalPodAutoscaler v2beta2 . HorizontalPodAutoscaler is the configuration for a horizontal pod autoscaler, which automatically manages the replica count of any resource implementing the scale subresource based on the metrics specified. PriorityClass . PriorityClass defines mapping from a priority class name to the priority integer value. Service Resources Service . Service is a named abstraction of software service (for example, mysql) consisting of local port (for example 3306) that the proxy listens on, and the selector that determines which pods will answer requests sent through the proxy. Endpoints . Endpoints is a collection of endpoints that implement the actual service. EndpointSlice . EndpointSlice represents a subset of the endpoints that implement a service. Ingress . Ingress is a collection of rules that allow inbound connections to reach the endpoints defined by a backend. IngressClass . IngressClass represents the class of the Ingress, referenced by the Ingress Spec. Config and Storage Resources ConfigMap . ConfigMap holds configuration data for pods to consume. Secret . Secret holds secret data of a certain type. Volume . Volume represents a named volume in a pod that may be accessed by any container in the pod. PersistentVolumeClaim . PersistentVolumeClaim is a user's request for and claim to a persistent volume. PersistentVolume . PersistentVolume (PV) is a storage resource provisioned by an administrator. StorageClass . StorageClass describes the parameters for a class of storage for which PersistentVolumes can be dynamically provisioned. VolumeAttachment . VolumeAttachment captures the intent to attach or detach the specified volume to/from the specified node. CSIDriver . CSIDriver captures information about a Container Storage Interface (CSI) volume driver deployed on the cluster. CSINode . CSINode holds information about all CSI drivers installed on a node. CSIStorageCapacity . CSIStorageCapacity stores the result of one CSI GetCapacity call. Authentication Resources ServiceAccount . ServiceAccount binds together: a name, understood by users, and perhaps by peripheral systems, for an identity a principal that can be authenticated and authorized a set of secrets. TokenRequest . TokenRequest requests a token for a given service account. TokenReview . TokenReview attempts to authenticate a token to a known user. CertificateSigningRequest . CertificateSigningRequest objects provide a mechanism to obtain x509 certificates by submitting a certificate signing request, and having it asynchronously approved and issued. Authorization Resources LocalSubjectAccessReview . LocalSubjectAccessReview checks whether or not a user or group can perform an action in a given namespace. SelfSubjectAccessReview . SelfSubjectAccessReview checks whether or the current user can perform an action. SelfSubjectRulesReview . SelfSubjectRulesReview enumerates the set of actions the current user can perform within a namespace. SubjectAccessReview . SubjectAccessReview checks whether or not a user or group can perform an action. ClusterRole . ClusterRole is a cluster level, logical grouping of PolicyRules that can be referenced as a unit by a RoleBinding or ClusterRoleBinding. ClusterRoleBinding . ClusterRoleBinding references a ClusterRole, but not contain it. Role . Role is a namespaced, logical grouping of PolicyRules that can be referenced as a unit by a RoleBinding. RoleBinding . RoleBinding references a role, but does not contain it. Policy Resources LimitRange . LimitRange sets resource usage limits for each kind of resource in a Namespace. ResourceQuota . ResourceQuota sets aggregate quota restrictions enforced per namespace. NetworkPolicy . NetworkPolicy describes what network traffic is allowed for a set of Pods. PodDisruptionBudget . PodDisruptionBudget is an object to define the max disruption that can be caused to a collection of pods. PodSecurityPolicy v1beta1 . PodSecurityPolicy governs the ability to make requests that affect the Security Context that will be applied to a pod and container. Extend Resources CustomResourceDefinition . CustomResourceDefinition represents a resource that should be exposed on the API server. MutatingWebhookConfiguration . MutatingWebhookConfiguration describes the configuration of and admission webhook that accept or reject and may change the object. *ValidatingWebhookConfiguration(). ValidatingWebhookConfiguration describes the configuration of and admission webhook that accept or reject and object without changing it. Cluster Resources Node . Node is a worker node in Kubernetes. Namespace . Namespace provides a scope for Names. Event . Event is a report of an event somewhere in the cluster. APIService . APIService represents a server for a particular GroupVersion. Lease . Lease defines a lease concept. RuntimeClass . RuntimeClass defines a class of container runtime supported in the cluster. FlowSchema v1beta2 . FlowSchema defines the schema of a group of flows. PriorityLevelConfiguration v1beta2 . PriorityLevelConfiguration represents the configuration of a priority level. Binding . Binding ties one object to another; for example, a pod is bound to a node by a scheduler. ComponentStatus . ComponentStatus (and ComponentStatusList) holds the cluster validation info. Command kube api-resources to get the supported API resources. Command kubectl explain RESOURCE [options] describes the fields associated with each supported API resource. Fields are identified via a simple JSONPath identifier: kubectl explain binding kubectl explain binding.metadata kubectl explain binding.metadata.name Workload Resources \u00b6 Pods \u00b6 Pods are the smallest deployable units of computing that you can create and manage in Kubernetes. A Pod is a group of one or more containers, with shared storage and network resources, and a specification for how to run the containers. A Pod's contents are always co-located and co-scheduled, and run in a shared context. A Pod models an application-specific \"logical host\": it contains one or more application containers which are relatively tightly coupled. In non-cloud contexts, applications executed on the same physical or virtual machine are analogous to cloud applications executed on the same logical host. The shared context of a Pod is a set of Linux namespaces, cgroups, and potentially other facets of isolation - the same things that isolate a Docker container. In terms of Docker concepts, a Pod is similar to a group of Docker containers with shared namespaces and shared filesystem volumes. Usually you don't need to create Pods directly, even singleton Pods. Instead, create them using workload resources such as Deployment or Job . If your Pods need to track state, consider the StatefulSet resource. Pods in a Kubernetes cluster are used in two main ways: Pods that run a single container. Pods that run multiple containers that need to work together. The \"one-container-per-Pod\" model is the most common Kubernetes use case; in this case, you can think of a Pod as a wrapper around a single container; Kubernetes manages Pods rather than managing the containers directly. A Pod can encapsulate an application composed of multiple co-located containers that are tightly coupled and need to share resources. These co-located containers form a single cohesive unit of service\u2014for example, one container serving data stored in a shared volume to the public, while a separate sidecar container refreshes or updates those files. The Pod wraps these containers, storage resources, and an ephemeral network identity together as a single unit. Grouping multiple co-located and co-managed containers in a single Pod is a relatively advanced use case. You should use this pattern only in specific instances in which your containers are tightly coupled. Each Pod is meant to run a single instance of a given application. If you want to scale your application horizontally (to provide more overall resources by running more instances), you should use multiple Pods, one for each instance. In Kubernetes, this is typically referred to as replication . Replicated Pods are usually created and managed as a group by a workload resource and its controller. Pods natively provide two kinds of shared resources for their constituent containers: networking and storage . A Pod can specify a set of shared storage volumes. All containers in the Pod can access the shared volumes, allowing those containers to share data. Each Pod is assigned a unique IP address for each address family. Within a Pod, containers share an IP address and port space, and can find each other via localhost . Containers that want to interact with a container running in a different Pod can use IP networking to communicate. When a Pod gets created, the new Pod is scheduled to run on a Node in your cluster. The Pod remains on that node until the Pod finishes execution, the Pod object is deleted, the Pod is evicted for lack of resources, or the node fails. Restarting a container in a Pod should not be confused with restarting a Pod. A Pod is not a process, but an environment for running container(s). A Pod persists until it is deleted. You can use workload resources (e.g., Deployment, StatefulSet, DaemonSet) to create and manage multiple Pods for you. A controller for the resource handles replication and rollout and automatic healing in case of Pod failure. InitContainer \u00b6 Some Pods have init containers as well as app containers. Init containers run and complete before the app containers are started. You can specify init containers in the Pod specification alongside the containers array (which describes app containers). Static Pod \u00b6 Static Pods are managed directly by the kubelet daemon on a specific node, without the API server observing them. Static Pods are always bound to one Kubelet on a specific node. The main use for static Pods is to run a self-hosted control plane: in other words, using the kubelet to supervise the individual control plane components. The kubelet automatically tries to create a mirror Pod on the Kubernetes API server for each static Pod. This means that the Pods running on a node are visible on the API server, but cannot be controlled from there. Container probes \u00b6 A probe is a diagnostic performed periodically by the kubelet on a container. To perform a diagnostic, the kubelet either executes code within the container, or makes a network request. There are four different ways to check a container using a probe. Each probe must define exactly one of these four mechanisms: exec . The diagnostic is considered successful if the command exits with a status code of 0. grpc . The diagnostic is considered successful if the status of the response is SERVING. httpGet . The diagnostic is considered successful if the response has a status code greater than or equal to 200 and less than 400. tcpSocket . The diagnostic is considered successful if the port is open. Each probe has one of three results: Success Failure Unknown Types of probe: livenessProbe . Indicates whether the container is running. readinessProbe . Indicates whether the container is ready to respond to requests. startupProbe . Indicates whether the application within the container is started. Deployment \u00b6 ReplicaSet \u00b6 A ReplicaSet\u2019s purpose is to maintain a stable set of replica Pods running at any given time. As such, it is often used to guarantee the availability of a specified number of identical Pods. You may never need to manipulate ReplicaSet objects: use a Deployment instead, and define your application in the spec section. You can specify how many Pods should run concurrently by setting replicaset.spec.replicas . The ReplicaSet will create/delete its Pods to match this number. If you do not specify replicaset.spec.replicas , then it defaults to 1 . StatefulSet \u00b6 StatefulSet Characteristics (aka, stick ID): Pod's name is immutable after created. DNS hostname is immutable after created. Mounted volume is immutable after created. Stick ID of StatefulSet won't be changed after failure, scaling, and other operations. Naming convention of StatefulSet: - . StatefulSet can be scalling by itsself, but Deployment need rely on ReplicaSet for scalling. Recommendation: reduce StatefulSet to 0 first instead of delete it directly. headless Service and governing Service: Headless Service is a normal Kubernetes Service object that its spec.clusterIP is set to None . When spec.ServiceName of StatefulSet is set to the headless Service name, the StatefulSet is now a governing Service. General procedure to create a StatefulSet: Create a StorageClass Create Headless Service Create StatefulSet based on above two. DaemonSet \u00b6 A DaemonSet ensures that all (or some) Nodes run a copy of a Pod. As nodes are removed from the cluster, those Pods are garbage collected. Deleting a DaemonSet will clean up the Pods it created. Some typical uses of a DaemonSet are: running a cluster storage daemon on every node running a logs collection daemon on every node running a node monitoring daemon on every node In a simple case, one DaemonSet, covering all nodes, would be used for each type of daemon. A more complex setup might use multiple DaemonSets for a single type of daemon, but with different flags and/or different memory and cpu requests for different hardware types. The DaemonSet controller reconciliation process reviews both existing nodes and newly created nodes. By default, the Kubernetes scheduler ignores the pods created by the DamonSet, and lets them exist on the node until the node itself is shut down. Running Pods on select Nodes: If you specify a daemonset.spec.template.spec.nodeSelector , then the DaemonSet controller will create Pods on nodes which match that node selector. If you specify a daemonset.spec.template.spec.affinity , then DaemonSet controller will create Pods on nodes which match that node affinity. If you do not specify either, then the DaemonSet controller will create Pods on all nodes. There is no field replicas in kubectl explain daemonset.spec against with kubectl explain deployment.spec.replicas . When a DaemonSet is created, each node will have one DaemonSet Pod running. We\u2019ll use a Deployment / ReplicaSet for services, mostly stateless, where we don\u2019t care where the node is running, but we care more about the number of copies of our pod is running, and we can scale those copies/replicas up or down. Rolling updates would also be a benefit here. We\u2019ll use a DaemonSet when a copy of our pod must be running on the specific nodes that we require. Our daemon pod also needs to start before any of our other pods. A DaemonSet is a simple scalability strategy for background services. When more eligible nodes are added to the cluster, the background service scales up. When nodes are removed, it will automatically scale down. Job \u00b6 CronJob \u00b6 Service Resource \u00b6 Service \u00b6 Service is a named abstraction of software service (for example, mysql) consisting of local port (for example 3306) that the proxy listens on, and the selector that determines which pods will answer requests sent through the proxy. The set of Pods targeted by a Service is usually determined by a selector (label selector). Type of service resource: ClusterIP Service (default): Reliable IP, DNS, and Port. Internal acess only. NodePort Service: Expose to external access. LoadBalancer: Based on NodePort and integrated with loader balance provided by cloud venders (e.g., AWS, GCP, etc.). ExternalName: Acces will be trafficed to external service. Here is an example of yaml file to create a Service. apiVersion : v1 kind : Service metadata : name : nginx-service labels : tier : application spec : ports : - port : 80 protocol : TCP targetPort : 8080 selector : run : nginx type : NodePort Here is an example of Service. IP 10.96.17.77 is ClusterIP(VIP) of the service Port 80/TCP is the port on Pod that service listening within the cluster. TargetPort 8080/TCP is the port on the container that the service should direct traffic to. NodePort 31893/TCP is the port that can be accessed outside. Default range is 30000~32767 . The port is exposed across all nodes in cluster. Endpoints show the list of Pods matched the service labels. Name: nginx-deployment Namespace: jh-namespace Labels: tier=application Annotations: Selector: run=nginx Type: NodePort IP Family Policy: SingleStack IP Families: IPv4 IP: 10.96.17.77 IPs: 10.96.17.77 Port: 80/TCP TargetPort: 8080/TCP NodePort: 31893/TCP Endpoints: 10.244.1.177:8080,10.244.1.178:8080,10.244.1.179:8080 + 7 more... Session Affinity: None External Traffic Policy: Cluster Events: Service kube-dns beyond Deployment coredns provides cluster DNS service in Kubernetes cluster. Service registration: Kubernetes uses cluster DNS as service registration. Registration is Service based, not Pod based. Cluster DNS (CoreDNS) is monitoring and discvering new service actively. Service Name, IP, Port will be registered. Procedure of Service registration. POST new Service to API Server. Assign ClusterIP to the new Service. Save new Service configuration info to etcd. Create endpoints with related Pod IPs associated with the new Service. Explore the new Service by ClusterDNS. Create DNS info. kube-proxy fetch Service configration info. Create IPSV rule. Procedure of Service discovery. Request DNS name resolution for a Service name. Receive ClusterIP. Traffic access to ClusterIP. No router. Forward request to Pod's default gateway. Forward request to node. No router. Forward request to Node's default gateway. Proceed the request by Node kernel. Trap the request by IPSV rule. Put destination Pod's IP into the request's destination IP. The request arrives destination Pod. FQDN format: ..svc.cluster.local . We call as unqualified name, or short name. Namespaces can segregate the cluster's address space. At the same time, it can also be used to implement access control and resource quotas. Get DNS configuration in a Pod. The IP of nameserver is same with ClusterIP of kube-dns Service, which is well-known IP for request of DNS or service discovery. root@cka001:/etc# kubectl get service kube-dns -n kube-system NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE kube-dns ClusterIP 10.96.0.10 53/UDP,53/TCP,9153/TCP 7d7h root@cka001:~# kubectl exec -it nginx-5f5496dc9-bv5dx -- /bin/bash root@nginx-5f5496dc9-bv5dx:/# cat /etc/resolv.conf search jh-namespace.svc.cluster.local svc.cluster.local cluster.local nameserver 10.96.0.10 options ndots:5 Get information of kube-dns . root@cka001:~# kubectl describe service kube-dns -n kube-system Name: kube-dns Namespace: kube-system Labels: k8s-app=kube-dns kubernetes.io/cluster-service=true kubernetes.io/name=CoreDNS Annotations: prometheus.io/port: 9153 prometheus.io/scrape: true Selector: k8s-app=kube-dns Type: ClusterIP IP Family Policy: SingleStack IP Families: IPv4 IP: 10.96.0.10 IPs: 10.96.0.10 Port: dns 53/UDP TargetPort: 53/UDP Endpoints: 10.244.0.2:53,10.244.0.3:53 Port: dns-tcp 53/TCP TargetPort: 53/TCP Endpoints: 10.244.0.2:53,10.244.0.3:53 Port: metrics 9153/TCP TargetPort: 9153/TCP Endpoints: 10.244.0.2:9153,10.244.0.3:9153 Session Affinity: None Events: Endpoints \u00b6 Endpoints is a collection of endpoints that implement the actual service. When a service is created, it associates with a Endpoint object, kubectl get endpoints . A list of matched Pod by service label is maintained as Endpoint object, add new matched Pods and remove not matched Pods. Config and Storage Resources \u00b6 Volumes \u00b6 emptyDir \u00b6 An emptyDir volume is first created when a Pod is assigned to a node, and exists as long as that Pod is running on that node. The emptyDir volume is initially empty. All containers in the Pod can read and write the same files in the emptyDir volume, though that volume can be mounted at the same or different paths in each container. When a Pod is removed from a node for any reason, the data in the emptyDir is deleted permanently. A container crashing does not remove a Pod from a node. The data in an emptyDir volume is safe across container crashes. Usage: scratch space, such as for a disk-based merge sort checkpointing a long computation for recovery from crashes holding files that a content-manager container fetches while a webserver container serves the data hostPath \u00b6 A hostPath volume mounts a file or directory from the host node's filesystem into your Pod. This is not something that most Pods will need, but it offers a powerful escape hatch for some applications. hostPath volumes present many security risks, and it is a best practice to avoid the use of HostPaths when possible. When a HostPath volume MUST be used, it should be scoped to only the required file or directory, and mounted as ReadOnly. If restricting HostPath access to specific directories through AdmissionPolicy, volumeMounts MUST be required to use readOnly mounts for the policy to be effective. Usage: Running together with DaemonSet, e.g., EFK Fluentd mount log directory of local host in order to collect host log information. Running on a specific node by using hostPath volumne, which can get high performance disk I/O. Running a container that needs access to Docker internals; use a hostPath of /var/lib/docker . Running cAdvisor in a container; use a hostPath of /sys . Allowing a Pod to specify whether a given hostPath should exist prior to the Pod running, whether it should be created, and what it should exist as. Storage Class \u00b6 Procedure of StorageClass deployment and implementation: Create Kubernetes cluster and backend storage. Make sure the provisioner/plugin is ready in Kubernetes. Create a StorageClass object to link to backend storage. The StorageClass will create related PV automatically. Create a PVC object to link to the StorageClass we created. Deploy a Pod and use the PVC volume. PV \u00b6 PV Recycle Policy. Retain. Delete. Recycle. PV in-tree type: hostPath local NFS CSI Access Modes \u00b6 spec.accessModes defines mount option of a PV: ReadWriteOnce(RWO). A PV can be mounted only to a PVC with read/write mode, like block device. ReadWriteMany(RWM). A PV can be mounted to more than one PVC with read/write mode, like NFS. ReadOnlyMany(ROM). A PV can be mounted to more than one PVC with read only mode. ReadWriteOncePod (RWOP). Only support CSI type PV, can be mounted by single Pod. A PV can only be set with one option. Pod mount PVC, not PV.","title":"Memo"},{"location":"k8s/cka_en/foundamentals/memo/#kubernetes-learning-memo","text":"","title":"Kubernetes Learning Memo"},{"location":"k8s/cka_en/foundamentals/memo/#basic-concepts-of-kubernetes","text":"","title":"Basic Concepts of Kubernetes"},{"location":"k8s/cka_en/foundamentals/memo/#kubernetes-components","text":"A Kubernetes cluster consists of the components that represent the control plane and a set of machines called nodes . Kubernetes Components : Control Plane Components kube-apiserver: query and manipulate the state of objects in Kubernetes. play as \"communication hub\" among all resources in cluster. provide cluster security authentication, authorization, and role assignment. the only one can connect to etcd . etcd: all Kubernetes objects are stored on etcd. Kubernetes objects are persistent entities in the Kubernetes system, which are used to represent the state of your cluster. kube-scheduler: watches for newly created Pods with no assigned node, and selects a node for them to run on. kube-controller-manager: runs controller processes. Node controller : Responsible for noticing and responding when nodes go down. Job controller : Watches for Job objects that represent one-off tasks, then creates Pods to run those tasks to completion. Endpoints controller : Populates the Endpoints object (that is, joins Services & Pods). Service Account & Token controllers : Create default accounts and API access tokens for new namespaces. cloud-controller-manager: embeds cloud-specific control logic and only runs controllers that are specific to your cloud provider, no need for own premises and learning environment. Node controller : For checking the cloud provider to determine if a node has been deleted in the cloud after it stops responding Route controller : For setting up routes in the underlying cloud infrastructure Service controller : For creating, updating and deleting cloud provider load balancers Node Components kubelet: An agent that runs on each node in the cluster. Manage node. It makes sure that containers are running in a Pod. kubelet registers and updates nodes information to APIServer, and APIServer stores them into etcd . Manage pod. Watch pod via APIServer, and action on pods or containers in pods. Health check at container level. kube-proxy: is a network proxy that runs on each node in cluster. iptables ipvs maintains network rules on nodes. Container runtime: is the software that is responsible for running containers. Addons DNS: is a DNS server and required by all Kubernetes clusters. Web UI (Dashboard): web-based UI for Kubernetes clusters. Container Resource Monitoring: records generic time-series metrics about containers in a central database Cluster-level Logging: is responsible for saving container logs to a central log store with search/browsing interface. Scalability: Scaling out (horizontal scaling) by adding more servers to your architecture to spread the workload across more machines. Scaling up (vertical scaling) by adding more hard drives and memory to increase the computing capacity of physical servers.","title":"Kubernetes Components"},{"location":"k8s/cka_en/foundamentals/memo/#kubernetes-api","text":"The REST API is the fundamental fabric of Kubernetes. All operations and communications between components, and external user commands are REST API calls that the API Server handles. Consequently, everything in the Kubernetes platform is treated as an API object and has a corresponding entry in the API. The core of Kubernetes' control plane is the API server. CRI: Container Runtime Interface CNI: Container Network Interface CSI: Container Storage Interface The API server exposes an HTTP API that lets end users, different parts of cluster, and external components communicate with one another. The Kubernetes API lets we query and manipulate the state of API objects in Kubernetes (for example: Pods, Namespaces, ConfigMaps, and Events). Kubernetes API: OpenAPI specification OpenAPI V2 OpenAPI V3 Persistence. Kubernetes stores the serialized state of objects by writing them into etcd. API groups and versioning. Versioning is done at the API level. API resources are distinguished by their API group, resource type, namespace (for namespaced resources), and name. API changes API Extension","title":"Kubernetes API"},{"location":"k8s/cka_en/foundamentals/memo/#api-version","text":"The API versioning and software versioning are indirectly related. The API and release versioning proposal describes the relationship between API versioning and software versioning. Different API versions indicate different levels of stability and support. Here's a summary of each level: Alpha: The version names contain alpha (for example, v1alpha1). The software may contain bugs. Enabling a feature may expose bugs. A feature may be disabled by default. The support for a feature may be dropped at any time without notice. The API may change in incompatible ways in a later software release without notice. The software is recommended for use only in short-lived testing clusters, due to increased risk of bugs and lack of long-term support. Beta: The version names contain beta (for example, v2beta3). The software is well tested. Enabling a feature is considered safe. Features are enabled by default. The support for a feature will not be dropped, though the details may change. The schema and/or semantics of objects may change in incompatible ways in a subsequent beta or stable release. When this happens, migration instructions are provided. Schema changes may require deleting, editing, and re-creating API objects. The editing process may not be straightforward. The migration may require downtime for applications that rely on the feature. The software is not recommended for production uses. Subsequent releases may introduce incompatible changes. If you have multiple clusters which can be upgraded independently, you may be able to relax this restriction. Note: Please try beta features and provide feedback. After the features exit beta, it may not be practical to make more changes. Stable: The version name is vX where X is an integer. The stable versions of features appear in released software for many subsequent versions. Command to get current API kubectl api-resources","title":"API Version"},{"location":"k8s/cka_en/foundamentals/memo/#api-group","text":"API groups make it easier to extend the Kubernetes API. The API group is specified in a REST path and in the apiVersion field of a serialized object. There are several API groups in Kubernetes: The core (also called legacy) group is found at REST path /api/v1 . The core group is not specified as part of the apiVersion field, for example, apiVersion: v1. The named groups are at REST path /apis/$GROUP_NAME/$VERSION and use apiVersion: $GROUP_NAME/$VERSION (for example, apiVersion: batch/v1).","title":"API Group"},{"location":"k8s/cka_en/foundamentals/memo/#kubernetes-objects","text":"","title":"Kubernetes Objects"},{"location":"k8s/cka_en/foundamentals/memo/#objects-overview","text":"Object Spec: providing a description of the characteristics the resource created to have: its desired state . Object Status: describes the current state of the object. Example of Deployment as an object that can represent an application running on cluster. apiVersion : apps/v1 # Which version of the Kubernetes API you're using to create this object kind : Deployment # What kind of object you want to create metadata : # Data that helps uniquely identify the object, including a name string, UID, and optional namespace name : nginx-deployment spec : # What state you desire for the object selector : matchLabels : app : nginx replicas : 2 # tells deployment to run 2 pods matching the template template : metadata : labels : app : nginx spec : containers : - name : nginx image : nginx:1.14.2 ports : - containerPort : 80","title":"Objects Overview"},{"location":"k8s/cka_en/foundamentals/memo/#object-management","text":"The kubectl command-line tool supports several different ways to create and manage Kubernetes objects. Read the Kubectl book for details. A Kubernetes object should be managed using ONLY one technique. Mixing and matching techniques for the same object results in undefined behavior. Three management techniques: Imperative commands operates directly on live objects in a cluster. kubectl create deployment nginx --image nginx Imperative object configuration kubectl create -f nginx.yaml kubectl delete -f nginx.yaml -f redis.yaml kubectl replace -f nginx.yaml Declarative object configuration kubectl diff -f configs/ kubectl apply -f configs/","title":"Object Management"},{"location":"k8s/cka_en/foundamentals/memo/#object-names-and-ids","text":"Each object in your cluster has a Name that is unique for that type of resource. DNS Subdomain Names Label Names Path Segment Names Every Kubernetes object also has a UID that is unique across the whole cluster.","title":"Object Names and IDs"},{"location":"k8s/cka_en/foundamentals/memo/#namespaces","text":"In Kubernetes, namespaces provides a mechanism for isolating groups of resources within a single cluster. Names of resources need to be unique within a namespace, but not across namespaces. Namespace-based scoping is applicable only for namespaced objects (e.g. Deployments, Services, etc) and not for cluster-wide objects (e.g. StorageClass, Nodes, PersistentVolumes, etc) Not All Objects are in a Namespace. Kubernetes starts with four initial namespaces: default The default namespace for objects with no other namespace kube-system The namespace for objects created by the Kubernetes system kube-public This namespace is created automatically and is readable by all users (including those not authenticated). This namespace is mostly reserved for cluster usage, in case that some resources should be visible and readable publicly throughout the whole cluster. The public aspect of this namespace is only a convention, not a requirement. kube-node-lease This namespace holds Lease objects associated with each node. Node leases allow the kubelet to send heartbeats so that the control plane can detect node failure. Viewing namespaces: kubectl get namespace Setting the namespace for a request kubectl run nginx --image=nginx --namespace= kubectl get pods --namespace=","title":"Namespaces"},{"location":"k8s/cka_en/foundamentals/memo/#labels-and-selectors","text":"Labels are key/value pairs that are attached to objects, such as pods. Valid label keys have two segments: an optional prefix and name, separated by a slash ( / ). Labels are intended to be used to specify identifying attributes of objects that are meaningful and relevant to users. Labels can be used to organize and to select subsets of objects. Labels can be attached to objects at creation time and subsequently added and modified at any time. Each object can have a set of key/value labels defined. Each Key must be unique for a given object. Example of labels: \"metadata\" : { \"labels\" : { \"key1\" : \"value1\" , \"key2\" : \"value2\" } } Unlike names and UIDs, labels do not provide uniqueness. In general, we expect many objects to carry the same label(s). The API currently supports two types of selectors: equality-based, e.g., environment = production , tier != frontend set-based, e.g., environment in (production, qa) , tier notin (frontend, backend) Sample commands: kubectl get pods -l environment=production,tier=frontend kubectl get pods -l 'environment in (production),tier in (frontend)' kubectl get pods -l 'environment in (production, qa)' kubectl get pods -l 'environment,environment notin (frontend)'","title":"Labels and Selectors"},{"location":"k8s/cka_en/foundamentals/memo/#annotations","text":"Use Kubernetes annotations to attach arbitrary non-identifying metadata to objects. Clients such as tools and libraries can retrieve this metadata. Use either labels or annotations to attach metadata to Kubernetes objects. Labels can be used to select objects and to find collections of objects that satisfy certain conditions. Annotations are not used to identify and select objects. Annotations, like labels, are key/value maps. The keys and the values in the map must be strings. \"metadata\" : { \"annotations\" : { \"key1\" : \"value1\" , \"key2\" : \"value2\" } } Valid annotation keys have two segments: an optional prefix and name, separated by a slash ( / ).","title":"Annotations"},{"location":"k8s/cka_en/foundamentals/memo/#field-selectors","text":"Field selectors let you select Kubernetes resources based on the value of one or more resource fields. Here are some examples of field selector queries: metadata.name=my-service metadata.namespace!=default status.phase=Pending This kubectl command selects all Pods for which the value of the status.phase field is Running: kubectl get pods --field-selector status.phase=Running Supported field selectors vary by Kubernetes resource type. All resource types support the metadata.name and metadata.namespace fields. Use the = , == , and != operators with field selectors ( = and == mean the same thing). For example: kubectl get ingress --field-selector foo.bar=baz With operators, kubectl get services --all-namespaces --field-selector metadata.namespace!=default Chained selectors, kubectl get pods --field-selector=status.phase!=Running,spec.restartPolicy=Always Multiple resource types, kubectl get statefulsets,services --all-namespaces --field-selector metadata.namespace!=default","title":"Field Selectors"},{"location":"k8s/cka_en/foundamentals/memo/#finalizers","text":"Finalizers are namespaced keys that tell Kubernetes to wait until specific conditions are met before it fully deletes resources marked for deletion . Finalizers alert controllers to clean up resources the deleted object owned. Finalizers are usually added to resources for a reason, so forcefully removing them can lead to issues in the cluster. Like labels, owner references describe the relationships between objects in Kubernetes, but are used for a different purpose. Kubernetes uses the owner references (not labels) to determine which Pods in the cluster need cleanup. Kubernetes processes finalizers when it identifies owner references on a resource targeted for deletion.","title":"Finalizers"},{"location":"k8s/cka_en/foundamentals/memo/#owners-and-dependents","text":"In Kubernetes, some objects are owners of other objects. For example, a ReplicaSet is the owner of a set of Pods. These owned objects are dependents of their owner. Dependent objects have a metadata.ownerReferences field that references their owner object. A valid owner reference consists of the object name and a UID within the same namespace as the dependent object. Dependent objects also have an ownerReferences.blockOwnerDeletion field that takes a boolean value and controls whether specific dependents can block garbage collection from deleting their owner object.","title":"Owners and Dependents"},{"location":"k8s/cka_en/foundamentals/memo/#resource","text":"Kubernetes resources and \"records of intent\" are all stored as API objects, and modified via RESTful calls to the API. The API allows configuration to be managed in a declarative way. Users can interact with the Kubernetes API directly, or via tools like kubectl. The core Kubernetes API is flexible and can also be extended to support custom resources. Workload Resources Pod . Pod is a collection of containers that can run on a host. PodTemplate . PodTemplate describes a template for creating copies of a predefined pod. ReplicationController . ReplicationController represents the configuration of a replication controller. ReplicaSet . ReplicaSet ensures that a specified number of pod replicas are running at any given time. Deployment . Deployment enables declarative updates for Pods and ReplicaSets. StatefulSet . StatefulSet represents a set of pods with consistent identities. ControllerRevision . ControllerRevision implements an immutable snapshot of state data. DaemonSet . DaemonSet represents the configuration of a daemon set. Job . Job represents the configuration of a single job. CronJob . CronJob represents the configuration of a single cron job. HorizontalPodAutoscaler . configuration of a horizontal pod autoscaler. HorizontalPodAutoscaler . HorizontalPodAutoscaler is the configuration for a horizontal pod autoscaler, which automatically manages the replica count of any resource implementing the scale subresource based on the metrics specified. HorizontalPodAutoscaler v2beta2 . HorizontalPodAutoscaler is the configuration for a horizontal pod autoscaler, which automatically manages the replica count of any resource implementing the scale subresource based on the metrics specified. PriorityClass . PriorityClass defines mapping from a priority class name to the priority integer value. Service Resources Service . Service is a named abstraction of software service (for example, mysql) consisting of local port (for example 3306) that the proxy listens on, and the selector that determines which pods will answer requests sent through the proxy. Endpoints . Endpoints is a collection of endpoints that implement the actual service. EndpointSlice . EndpointSlice represents a subset of the endpoints that implement a service. Ingress . Ingress is a collection of rules that allow inbound connections to reach the endpoints defined by a backend. IngressClass . IngressClass represents the class of the Ingress, referenced by the Ingress Spec. Config and Storage Resources ConfigMap . ConfigMap holds configuration data for pods to consume. Secret . Secret holds secret data of a certain type. Volume . Volume represents a named volume in a pod that may be accessed by any container in the pod. PersistentVolumeClaim . PersistentVolumeClaim is a user's request for and claim to a persistent volume. PersistentVolume . PersistentVolume (PV) is a storage resource provisioned by an administrator. StorageClass . StorageClass describes the parameters for a class of storage for which PersistentVolumes can be dynamically provisioned. VolumeAttachment . VolumeAttachment captures the intent to attach or detach the specified volume to/from the specified node. CSIDriver . CSIDriver captures information about a Container Storage Interface (CSI) volume driver deployed on the cluster. CSINode . CSINode holds information about all CSI drivers installed on a node. CSIStorageCapacity . CSIStorageCapacity stores the result of one CSI GetCapacity call. Authentication Resources ServiceAccount . ServiceAccount binds together: a name, understood by users, and perhaps by peripheral systems, for an identity a principal that can be authenticated and authorized a set of secrets. TokenRequest . TokenRequest requests a token for a given service account. TokenReview . TokenReview attempts to authenticate a token to a known user. CertificateSigningRequest . CertificateSigningRequest objects provide a mechanism to obtain x509 certificates by submitting a certificate signing request, and having it asynchronously approved and issued. Authorization Resources LocalSubjectAccessReview . LocalSubjectAccessReview checks whether or not a user or group can perform an action in a given namespace. SelfSubjectAccessReview . SelfSubjectAccessReview checks whether or the current user can perform an action. SelfSubjectRulesReview . SelfSubjectRulesReview enumerates the set of actions the current user can perform within a namespace. SubjectAccessReview . SubjectAccessReview checks whether or not a user or group can perform an action. ClusterRole . ClusterRole is a cluster level, logical grouping of PolicyRules that can be referenced as a unit by a RoleBinding or ClusterRoleBinding. ClusterRoleBinding . ClusterRoleBinding references a ClusterRole, but not contain it. Role . Role is a namespaced, logical grouping of PolicyRules that can be referenced as a unit by a RoleBinding. RoleBinding . RoleBinding references a role, but does not contain it. Policy Resources LimitRange . LimitRange sets resource usage limits for each kind of resource in a Namespace. ResourceQuota . ResourceQuota sets aggregate quota restrictions enforced per namespace. NetworkPolicy . NetworkPolicy describes what network traffic is allowed for a set of Pods. PodDisruptionBudget . PodDisruptionBudget is an object to define the max disruption that can be caused to a collection of pods. PodSecurityPolicy v1beta1 . PodSecurityPolicy governs the ability to make requests that affect the Security Context that will be applied to a pod and container. Extend Resources CustomResourceDefinition . CustomResourceDefinition represents a resource that should be exposed on the API server. MutatingWebhookConfiguration . MutatingWebhookConfiguration describes the configuration of and admission webhook that accept or reject and may change the object. *ValidatingWebhookConfiguration(). ValidatingWebhookConfiguration describes the configuration of and admission webhook that accept or reject and object without changing it. Cluster Resources Node . Node is a worker node in Kubernetes. Namespace . Namespace provides a scope for Names. Event . Event is a report of an event somewhere in the cluster. APIService . APIService represents a server for a particular GroupVersion. Lease . Lease defines a lease concept. RuntimeClass . RuntimeClass defines a class of container runtime supported in the cluster. FlowSchema v1beta2 . FlowSchema defines the schema of a group of flows. PriorityLevelConfiguration v1beta2 . PriorityLevelConfiguration represents the configuration of a priority level. Binding . Binding ties one object to another; for example, a pod is bound to a node by a scheduler. ComponentStatus . ComponentStatus (and ComponentStatusList) holds the cluster validation info. Command kube api-resources to get the supported API resources. Command kubectl explain RESOURCE [options] describes the fields associated with each supported API resource. Fields are identified via a simple JSONPath identifier: kubectl explain binding kubectl explain binding.metadata kubectl explain binding.metadata.name","title":"Resource"},{"location":"k8s/cka_en/foundamentals/memo/#workload-resources","text":"","title":"Workload Resources"},{"location":"k8s/cka_en/foundamentals/memo/#pods","text":"Pods are the smallest deployable units of computing that you can create and manage in Kubernetes. A Pod is a group of one or more containers, with shared storage and network resources, and a specification for how to run the containers. A Pod's contents are always co-located and co-scheduled, and run in a shared context. A Pod models an application-specific \"logical host\": it contains one or more application containers which are relatively tightly coupled. In non-cloud contexts, applications executed on the same physical or virtual machine are analogous to cloud applications executed on the same logical host. The shared context of a Pod is a set of Linux namespaces, cgroups, and potentially other facets of isolation - the same things that isolate a Docker container. In terms of Docker concepts, a Pod is similar to a group of Docker containers with shared namespaces and shared filesystem volumes. Usually you don't need to create Pods directly, even singleton Pods. Instead, create them using workload resources such as Deployment or Job . If your Pods need to track state, consider the StatefulSet resource. Pods in a Kubernetes cluster are used in two main ways: Pods that run a single container. Pods that run multiple containers that need to work together. The \"one-container-per-Pod\" model is the most common Kubernetes use case; in this case, you can think of a Pod as a wrapper around a single container; Kubernetes manages Pods rather than managing the containers directly. A Pod can encapsulate an application composed of multiple co-located containers that are tightly coupled and need to share resources. These co-located containers form a single cohesive unit of service\u2014for example, one container serving data stored in a shared volume to the public, while a separate sidecar container refreshes or updates those files. The Pod wraps these containers, storage resources, and an ephemeral network identity together as a single unit. Grouping multiple co-located and co-managed containers in a single Pod is a relatively advanced use case. You should use this pattern only in specific instances in which your containers are tightly coupled. Each Pod is meant to run a single instance of a given application. If you want to scale your application horizontally (to provide more overall resources by running more instances), you should use multiple Pods, one for each instance. In Kubernetes, this is typically referred to as replication . Replicated Pods are usually created and managed as a group by a workload resource and its controller. Pods natively provide two kinds of shared resources for their constituent containers: networking and storage . A Pod can specify a set of shared storage volumes. All containers in the Pod can access the shared volumes, allowing those containers to share data. Each Pod is assigned a unique IP address for each address family. Within a Pod, containers share an IP address and port space, and can find each other via localhost . Containers that want to interact with a container running in a different Pod can use IP networking to communicate. When a Pod gets created, the new Pod is scheduled to run on a Node in your cluster. The Pod remains on that node until the Pod finishes execution, the Pod object is deleted, the Pod is evicted for lack of resources, or the node fails. Restarting a container in a Pod should not be confused with restarting a Pod. A Pod is not a process, but an environment for running container(s). A Pod persists until it is deleted. You can use workload resources (e.g., Deployment, StatefulSet, DaemonSet) to create and manage multiple Pods for you. A controller for the resource handles replication and rollout and automatic healing in case of Pod failure.","title":"Pods"},{"location":"k8s/cka_en/foundamentals/memo/#initcontainer","text":"Some Pods have init containers as well as app containers. Init containers run and complete before the app containers are started. You can specify init containers in the Pod specification alongside the containers array (which describes app containers).","title":"InitContainer"},{"location":"k8s/cka_en/foundamentals/memo/#static-pod","text":"Static Pods are managed directly by the kubelet daemon on a specific node, without the API server observing them. Static Pods are always bound to one Kubelet on a specific node. The main use for static Pods is to run a self-hosted control plane: in other words, using the kubelet to supervise the individual control plane components. The kubelet automatically tries to create a mirror Pod on the Kubernetes API server for each static Pod. This means that the Pods running on a node are visible on the API server, but cannot be controlled from there.","title":"Static Pod"},{"location":"k8s/cka_en/foundamentals/memo/#container-probes","text":"A probe is a diagnostic performed periodically by the kubelet on a container. To perform a diagnostic, the kubelet either executes code within the container, or makes a network request. There are four different ways to check a container using a probe. Each probe must define exactly one of these four mechanisms: exec . The diagnostic is considered successful if the command exits with a status code of 0. grpc . The diagnostic is considered successful if the status of the response is SERVING. httpGet . The diagnostic is considered successful if the response has a status code greater than or equal to 200 and less than 400. tcpSocket . The diagnostic is considered successful if the port is open. Each probe has one of three results: Success Failure Unknown Types of probe: livenessProbe . Indicates whether the container is running. readinessProbe . Indicates whether the container is ready to respond to requests. startupProbe . Indicates whether the application within the container is started.","title":"Container probes"},{"location":"k8s/cka_en/foundamentals/memo/#deployment","text":"","title":"Deployment"},{"location":"k8s/cka_en/foundamentals/memo/#replicaset","text":"A ReplicaSet\u2019s purpose is to maintain a stable set of replica Pods running at any given time. As such, it is often used to guarantee the availability of a specified number of identical Pods. You may never need to manipulate ReplicaSet objects: use a Deployment instead, and define your application in the spec section. You can specify how many Pods should run concurrently by setting replicaset.spec.replicas . The ReplicaSet will create/delete its Pods to match this number. If you do not specify replicaset.spec.replicas , then it defaults to 1 .","title":"ReplicaSet"},{"location":"k8s/cka_en/foundamentals/memo/#statefulset","text":"StatefulSet Characteristics (aka, stick ID): Pod's name is immutable after created. DNS hostname is immutable after created. Mounted volume is immutable after created. Stick ID of StatefulSet won't be changed after failure, scaling, and other operations. Naming convention of StatefulSet: - . StatefulSet can be scalling by itsself, but Deployment need rely on ReplicaSet for scalling. Recommendation: reduce StatefulSet to 0 first instead of delete it directly. headless Service and governing Service: Headless Service is a normal Kubernetes Service object that its spec.clusterIP is set to None . When spec.ServiceName of StatefulSet is set to the headless Service name, the StatefulSet is now a governing Service. General procedure to create a StatefulSet: Create a StorageClass Create Headless Service Create StatefulSet based on above two.","title":"StatefulSet"},{"location":"k8s/cka_en/foundamentals/memo/#daemonset","text":"A DaemonSet ensures that all (or some) Nodes run a copy of a Pod. As nodes are removed from the cluster, those Pods are garbage collected. Deleting a DaemonSet will clean up the Pods it created. Some typical uses of a DaemonSet are: running a cluster storage daemon on every node running a logs collection daemon on every node running a node monitoring daemon on every node In a simple case, one DaemonSet, covering all nodes, would be used for each type of daemon. A more complex setup might use multiple DaemonSets for a single type of daemon, but with different flags and/or different memory and cpu requests for different hardware types. The DaemonSet controller reconciliation process reviews both existing nodes and newly created nodes. By default, the Kubernetes scheduler ignores the pods created by the DamonSet, and lets them exist on the node until the node itself is shut down. Running Pods on select Nodes: If you specify a daemonset.spec.template.spec.nodeSelector , then the DaemonSet controller will create Pods on nodes which match that node selector. If you specify a daemonset.spec.template.spec.affinity , then DaemonSet controller will create Pods on nodes which match that node affinity. If you do not specify either, then the DaemonSet controller will create Pods on all nodes. There is no field replicas in kubectl explain daemonset.spec against with kubectl explain deployment.spec.replicas . When a DaemonSet is created, each node will have one DaemonSet Pod running. We\u2019ll use a Deployment / ReplicaSet for services, mostly stateless, where we don\u2019t care where the node is running, but we care more about the number of copies of our pod is running, and we can scale those copies/replicas up or down. Rolling updates would also be a benefit here. We\u2019ll use a DaemonSet when a copy of our pod must be running on the specific nodes that we require. Our daemon pod also needs to start before any of our other pods. A DaemonSet is a simple scalability strategy for background services. When more eligible nodes are added to the cluster, the background service scales up. When nodes are removed, it will automatically scale down.","title":"DaemonSet"},{"location":"k8s/cka_en/foundamentals/memo/#job","text":"","title":"Job"},{"location":"k8s/cka_en/foundamentals/memo/#cronjob","text":"","title":"CronJob"},{"location":"k8s/cka_en/foundamentals/memo/#service-resource","text":"","title":"Service Resource"},{"location":"k8s/cka_en/foundamentals/memo/#service","text":"Service is a named abstraction of software service (for example, mysql) consisting of local port (for example 3306) that the proxy listens on, and the selector that determines which pods will answer requests sent through the proxy. The set of Pods targeted by a Service is usually determined by a selector (label selector). Type of service resource: ClusterIP Service (default): Reliable IP, DNS, and Port. Internal acess only. NodePort Service: Expose to external access. LoadBalancer: Based on NodePort and integrated with loader balance provided by cloud venders (e.g., AWS, GCP, etc.). ExternalName: Acces will be trafficed to external service. Here is an example of yaml file to create a Service. apiVersion : v1 kind : Service metadata : name : nginx-service labels : tier : application spec : ports : - port : 80 protocol : TCP targetPort : 8080 selector : run : nginx type : NodePort Here is an example of Service. IP 10.96.17.77 is ClusterIP(VIP) of the service Port 80/TCP is the port on Pod that service listening within the cluster. TargetPort 8080/TCP is the port on the container that the service should direct traffic to. NodePort 31893/TCP is the port that can be accessed outside. Default range is 30000~32767 . The port is exposed across all nodes in cluster. Endpoints show the list of Pods matched the service labels. Name: nginx-deployment Namespace: jh-namespace Labels: tier=application Annotations: Selector: run=nginx Type: NodePort IP Family Policy: SingleStack IP Families: IPv4 IP: 10.96.17.77 IPs: 10.96.17.77 Port: 80/TCP TargetPort: 8080/TCP NodePort: 31893/TCP Endpoints: 10.244.1.177:8080,10.244.1.178:8080,10.244.1.179:8080 + 7 more... Session Affinity: None External Traffic Policy: Cluster Events: Service kube-dns beyond Deployment coredns provides cluster DNS service in Kubernetes cluster. Service registration: Kubernetes uses cluster DNS as service registration. Registration is Service based, not Pod based. Cluster DNS (CoreDNS) is monitoring and discvering new service actively. Service Name, IP, Port will be registered. Procedure of Service registration. POST new Service to API Server. Assign ClusterIP to the new Service. Save new Service configuration info to etcd. Create endpoints with related Pod IPs associated with the new Service. Explore the new Service by ClusterDNS. Create DNS info. kube-proxy fetch Service configration info. Create IPSV rule. Procedure of Service discovery. Request DNS name resolution for a Service name. Receive ClusterIP. Traffic access to ClusterIP. No router. Forward request to Pod's default gateway. Forward request to node. No router. Forward request to Node's default gateway. Proceed the request by Node kernel. Trap the request by IPSV rule. Put destination Pod's IP into the request's destination IP. The request arrives destination Pod. FQDN format: ..svc.cluster.local . We call as unqualified name, or short name. Namespaces can segregate the cluster's address space. At the same time, it can also be used to implement access control and resource quotas. Get DNS configuration in a Pod. The IP of nameserver is same with ClusterIP of kube-dns Service, which is well-known IP for request of DNS or service discovery. root@cka001:/etc# kubectl get service kube-dns -n kube-system NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE kube-dns ClusterIP 10.96.0.10 53/UDP,53/TCP,9153/TCP 7d7h root@cka001:~# kubectl exec -it nginx-5f5496dc9-bv5dx -- /bin/bash root@nginx-5f5496dc9-bv5dx:/# cat /etc/resolv.conf search jh-namespace.svc.cluster.local svc.cluster.local cluster.local nameserver 10.96.0.10 options ndots:5 Get information of kube-dns . root@cka001:~# kubectl describe service kube-dns -n kube-system Name: kube-dns Namespace: kube-system Labels: k8s-app=kube-dns kubernetes.io/cluster-service=true kubernetes.io/name=CoreDNS Annotations: prometheus.io/port: 9153 prometheus.io/scrape: true Selector: k8s-app=kube-dns Type: ClusterIP IP Family Policy: SingleStack IP Families: IPv4 IP: 10.96.0.10 IPs: 10.96.0.10 Port: dns 53/UDP TargetPort: 53/UDP Endpoints: 10.244.0.2:53,10.244.0.3:53 Port: dns-tcp 53/TCP TargetPort: 53/TCP Endpoints: 10.244.0.2:53,10.244.0.3:53 Port: metrics 9153/TCP TargetPort: 9153/TCP Endpoints: 10.244.0.2:9153,10.244.0.3:9153 Session Affinity: None Events: ","title":"Service"},{"location":"k8s/cka_en/foundamentals/memo/#endpoints","text":"Endpoints is a collection of endpoints that implement the actual service. When a service is created, it associates with a Endpoint object, kubectl get endpoints . A list of matched Pod by service label is maintained as Endpoint object, add new matched Pods and remove not matched Pods.","title":"Endpoints"},{"location":"k8s/cka_en/foundamentals/memo/#config-and-storage-resources","text":"","title":"Config and Storage Resources"},{"location":"k8s/cka_en/foundamentals/memo/#volumes","text":"","title":"Volumes"},{"location":"k8s/cka_en/foundamentals/memo/#emptydir","text":"An emptyDir volume is first created when a Pod is assigned to a node, and exists as long as that Pod is running on that node. The emptyDir volume is initially empty. All containers in the Pod can read and write the same files in the emptyDir volume, though that volume can be mounted at the same or different paths in each container. When a Pod is removed from a node for any reason, the data in the emptyDir is deleted permanently. A container crashing does not remove a Pod from a node. The data in an emptyDir volume is safe across container crashes. Usage: scratch space, such as for a disk-based merge sort checkpointing a long computation for recovery from crashes holding files that a content-manager container fetches while a webserver container serves the data","title":"emptyDir"},{"location":"k8s/cka_en/foundamentals/memo/#hostpath","text":"A hostPath volume mounts a file or directory from the host node's filesystem into your Pod. This is not something that most Pods will need, but it offers a powerful escape hatch for some applications. hostPath volumes present many security risks, and it is a best practice to avoid the use of HostPaths when possible. When a HostPath volume MUST be used, it should be scoped to only the required file or directory, and mounted as ReadOnly. If restricting HostPath access to specific directories through AdmissionPolicy, volumeMounts MUST be required to use readOnly mounts for the policy to be effective. Usage: Running together with DaemonSet, e.g., EFK Fluentd mount log directory of local host in order to collect host log information. Running on a specific node by using hostPath volumne, which can get high performance disk I/O. Running a container that needs access to Docker internals; use a hostPath of /var/lib/docker . Running cAdvisor in a container; use a hostPath of /sys . Allowing a Pod to specify whether a given hostPath should exist prior to the Pod running, whether it should be created, and what it should exist as.","title":"hostPath"},{"location":"k8s/cka_en/foundamentals/memo/#storage-class","text":"Procedure of StorageClass deployment and implementation: Create Kubernetes cluster and backend storage. Make sure the provisioner/plugin is ready in Kubernetes. Create a StorageClass object to link to backend storage. The StorageClass will create related PV automatically. Create a PVC object to link to the StorageClass we created. Deploy a Pod and use the PVC volume.","title":"Storage Class"},{"location":"k8s/cka_en/foundamentals/memo/#pv","text":"PV Recycle Policy. Retain. Delete. Recycle. PV in-tree type: hostPath local NFS CSI","title":"PV"},{"location":"k8s/cka_en/foundamentals/memo/#access-modes","text":"spec.accessModes defines mount option of a PV: ReadWriteOnce(RWO). A PV can be mounted only to a PVC with read/write mode, like block device. ReadWriteMany(RWM). A PV can be mounted to more than one PVC with read/write mode, like NFS. ReadOnlyMany(ROM). A PV can be mounted to more than one PVC with read only mode. ReadWriteOncePod (RWOP). Only support CSI type PV, can be mounted by single Pod. A PV can only be set with one option. Pod mount PVC, not PV.","title":"Access Modes"},{"location":"k8s/cka_en/foundamentals/namespace/","text":"Namespace \u00b6 Scenario: Get namespace list Create new namespace Label a namespace Delete a namespace Demo: Get list of Namespace kubectl get namespace Get list of Namespace with Label information. kubectl get ns --show-labels Create a Namespace kubectl create namespace cka Label the new created Namespace cka . kubectl label ns cka cka=true Create Nginx Deployment in Namespace cka . kubectl create deploy nginx --image=nginx --namespace cka Check Deployments and Pods running in namespace cka . kubectl get deploy,pod -n cka Result is below. NAME READY UP-TO-DATE AVAILABLE AGE deployment.apps/nginx 1/1 1 1 2m14s NAME READY STATUS RESTARTS AGE pod/nginx-85b98978db-bmkhf 1/1 Running 0 2m14s Delete namespace cka . All resources in the namespaces will be gone. kubectl delete ns cka Tip: Kubernetes Namespaces stuck in Terminating status. kubectl get namespace $NAMESPACE -o json | sed -e 's/\"kubernetes\"//' | kubectl replace --raw \"/api/v1/namespaces/$NAMESPACE/finalize\" -f -","title":"Namespace"},{"location":"k8s/cka_en/foundamentals/namespace/#namespace","text":"Scenario: Get namespace list Create new namespace Label a namespace Delete a namespace Demo: Get list of Namespace kubectl get namespace Get list of Namespace with Label information. kubectl get ns --show-labels Create a Namespace kubectl create namespace cka Label the new created Namespace cka . kubectl label ns cka cka=true Create Nginx Deployment in Namespace cka . kubectl create deploy nginx --image=nginx --namespace cka Check Deployments and Pods running in namespace cka . kubectl get deploy,pod -n cka Result is below. NAME READY UP-TO-DATE AVAILABLE AGE deployment.apps/nginx 1/1 1 1 2m14s NAME READY STATUS RESTARTS AGE pod/nginx-85b98978db-bmkhf 1/1 Running 0 2m14s Delete namespace cka . All resources in the namespaces will be gone. kubectl delete ns cka Tip: Kubernetes Namespaces stuck in Terminating status. kubectl get namespace $NAMESPACE -o json | sed -e 's/\"kubernetes\"//' | kubectl replace --raw \"/api/v1/namespaces/$NAMESPACE/finalize\" -f -","title":"Namespace"},{"location":"k8s/cka_en/foundamentals/networkpolicy/","text":"Network Policy \u00b6 Replace Flannel by Calico \u00b6 Scenario Remove Flannel Install Calico Demo: If Calico was installed at the installation phase, ignore this section. Delete Flannel kubectl delete -f https://raw.githubusercontent.com/coreos/flannel/v0.18.1/Documentation/kube-flannel.yml or kubectl delete -f kube-flannel.yml Output: Warning: policy/v1beta1 PodSecurityPolicy is deprecated in v1.21+, unavailable in v1.25+ podsecuritypolicy.policy \"psp.flannel.unprivileged\" deleted clusterrole.rbac.authorization.k8s.io \"flannel\" deleted clusterrolebinding.rbac.authorization.k8s.io \"flannel\" deleted serviceaccount \"flannel\" deleted configmap \"kube-flannel-cfg\" deleted daemonset.apps \"kube-flannel-ds\" deleted Clean up iptables for all nodes. rm -rf /var/run/flannel /opt/cni /etc/cni /var/lib/cni iptables -F && iptables -t nat -F && iptables -t mangle -F && iptables -X Log out and log on to host (e.g., cka001) again. Install Calico. curl https://docs.projectcalico.org/manifests/calico.yaml -O kubectl apply -f calico.yaml Output: configmap/calico-config created customresourcedefinition.apiextensions.k8s.io/bgpconfigurations.crd.projectcalico.org created customresourcedefinition.apiextensions.k8s.io/bgppeers.crd.projectcalico.org created customresourcedefinition.apiextensions.k8s.io/blockaffinities.crd.projectcalico.org created customresourcedefinition.apiextensions.k8s.io/caliconodestatuses.crd.projectcalico.org created customresourcedefinition.apiextensions.k8s.io/clusterinformations.crd.projectcalico.org created customresourcedefinition.apiextensions.k8s.io/felixconfigurations.crd.projectcalico.org created customresourcedefinition.apiextensions.k8s.io/globalnetworkpolicies.crd.projectcalico.org created customresourcedefinition.apiextensions.k8s.io/globalnetworksets.crd.projectcalico.org created customresourcedefinition.apiextensions.k8s.io/hostendpoints.crd.projectcalico.org created customresourcedefinition.apiextensions.k8s.io/ipamblocks.crd.projectcalico.org created customresourcedefinition.apiextensions.k8s.io/ipamconfigs.crd.projectcalico.org created customresourcedefinition.apiextensions.k8s.io/ipamhandles.crd.projectcalico.org created customresourcedefinition.apiextensions.k8s.io/ippools.crd.projectcalico.org created customresourcedefinition.apiextensions.k8s.io/ipreservations.crd.projectcalico.org created customresourcedefinition.apiextensions.k8s.io/kubecontrollersconfigurations.crd.projectcalico.org created customresourcedefinition.apiextensions.k8s.io/networkpolicies.crd.projectcalico.org created customresourcedefinition.apiextensions.k8s.io/networksets.crd.projectcalico.org created clusterrole.rbac.authorization.k8s.io/calico-kube-controllers created clusterrolebinding.rbac.authorization.k8s.io/calico-kube-controllers created clusterrole.rbac.authorization.k8s.io/calico-node created clusterrolebinding.rbac.authorization.k8s.io/calico-node created daemonset.apps/calico-node created serviceaccount/calico-node created deployment.apps/calico-kube-controllers created serviceaccount/calico-kube-controllers created poddisruptionbudget.policy/calico-kube-controllers created Verify status of Calico. Make sure all Pods are running kubectl get pod -n kube-system | grep calico Output: NAME READY STATUS RESTARTS AGE calico-kube-controllers-7bc6547ffb-tjfcg 1/1 Running 0 30m calico-node-7x8jm 1/1 Running 0 30m calico-node-cwxj5 1/1 Running 0 30m calico-node-rq978 1/1 Running 0 30m If facing any error, check log in the Container. # Get Container ID crictl ps # Get log info crictl logs As we change CNI from Flannel to Calico, we need delete all Pods. All of Pods will be created automatically again. kubectl delete pod -A --all Make sure all Pods are up and running successfully. kubectl get pod -A Inbound Rules \u00b6 Scenario Create workload for test. Deny For All Ingress Allow For Specific Ingress Verify NetworkPolicy Demo: Create workload for test. \u00b6 Create three Deployments pod-netpol-1 , pod-netpol-2 , pod-netpol-3 based on image busybox . kubectl apply -f - << EOF apiVersion: apps/v1 kind: Deployment metadata: labels: app: pod-netpol-1 name: pod-netpol-1 spec: replicas: 1 selector: matchLabels: app: pod-netpol-1 template: metadata: labels: app: pod-netpol-1 spec: containers: - image: busybox name: busybox command: [\"sh\", \"-c\", \"sleep 1h\"] --- apiVersion: apps/v1 kind: Deployment metadata: labels: app: pod-netpol-2 name: pod-netpol-2 spec: replicas: 1 selector: matchLabels: app: pod-netpol-2 template: metadata: labels: app: pod-netpol-2 spec: containers: - image: busybox name: busybox command: [\"sh\", \"-c\", \"sleep 1h\"] --- apiVersion: apps/v1 kind: Deployment metadata: labels: app: pod-netpol-3 name: pod-netpol-3 spec: replicas: 1 selector: matchLabels: app: pod-netpol-3 template: metadata: labels: app: pod-netpol-3 spec: containers: - image: busybox name: busybox command: [\"sh\", \"-c\", \"sleep 1h\"] EOF Check Pods IP. kubectl get pod -owide Output: NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES pod-netpol-1-6494f6bf8b-n58r9 1/1 Running 0 29s 10.244.102.30 cka003 pod-netpol-2-77478d77ff-l6rzm 1/1 Running 0 29s 10.244.112.30 cka002 pod-netpol-3-68977dcb48-ql5s6 1/1 Running 0 29s 10.244.102.31 cka003 Attach to Pod pod-netpol-1 kubectl exec -it pod-netpol-1-6494f6bf8b-n58r9 -- sh Execute command ping that pod-netpol-2 and pod-netpol-3 are both reachable. / # ping 10.244.112.30 3 packets transmitted, 3 packets received, 0% packet loss / # ping 10.244.102.31 3 packets transmitted, 3 packets received, 0% packet loss Deny For All Ingress \u00b6 Create deny policy for all ingress. kubectl apply -f - << EOF apiVersion: networking.k8s.io/v1 kind: NetworkPolicy metadata: name: default-deny-ingress spec: podSelector: {} policyTypes: - Ingress EOF Attach to Pod pod-netpol-1 again kubectl exec -it pod-netpol-1-6494f6bf8b-n58r9 -- sh Execute command ping that pod-netpol-2 and pod-netpol-3 are both unreachable as expected. / # ping 10.244.112.30 3 packets transmitted, 0 packets received, 100% packet loss / # ping 10.244.102.31 3 packets transmitted, 0 packets received, 100% packet loss Allow For Specific Ingress \u00b6 Create NetworkPlicy to allow ingress from pod-netpol-1 to pod-netpol-2 . kubectl apply -f - <:80 failed. Command curl :80 succeed. kubectl run centos --image=centos -n my-ns-1 -- \"/bin/sh\" \"-c\" \"sleep 3600\" kubectl exec -it mycentos -n my-ns-1 -- bash Create temp pod on namespace my-ns-2 . Attach to the pod and verify the access. Command curl :80 failed. Command curl :80 failed. kubectl run centos --image=centos -n my-ns-2 -- \"/bin/sh\" \"-c\" \"sleep 3600\" kubectl exec -it mycentos -n my-ns-2 -- bash Edit my-networkpolicy-1 to change ingress.from.namespaceSelector.matchLabels to my-ns-2 . Attach to temp pod on namespace my-ns-2 . Verify the access. Command curl :80 failed. Command curl :80 succeed. kubectl exec -it mycentos -n my-ns-2 -- bash Clean up: kubectl delete namespace my-ns-1 kubectl delete namespace my-ns-2","title":"Network Policy"},{"location":"k8s/cka_en/foundamentals/networkpolicy/#network-policy","text":"","title":"Network Policy"},{"location":"k8s/cka_en/foundamentals/networkpolicy/#replace-flannel-by-calico","text":"Scenario Remove Flannel Install Calico Demo: If Calico was installed at the installation phase, ignore this section. Delete Flannel kubectl delete -f https://raw.githubusercontent.com/coreos/flannel/v0.18.1/Documentation/kube-flannel.yml or kubectl delete -f kube-flannel.yml Output: Warning: policy/v1beta1 PodSecurityPolicy is deprecated in v1.21+, unavailable in v1.25+ podsecuritypolicy.policy \"psp.flannel.unprivileged\" deleted clusterrole.rbac.authorization.k8s.io \"flannel\" deleted clusterrolebinding.rbac.authorization.k8s.io \"flannel\" deleted serviceaccount \"flannel\" deleted configmap \"kube-flannel-cfg\" deleted daemonset.apps \"kube-flannel-ds\" deleted Clean up iptables for all nodes. rm -rf /var/run/flannel /opt/cni /etc/cni /var/lib/cni iptables -F && iptables -t nat -F && iptables -t mangle -F && iptables -X Log out and log on to host (e.g., cka001) again. Install Calico. curl https://docs.projectcalico.org/manifests/calico.yaml -O kubectl apply -f calico.yaml Output: configmap/calico-config created customresourcedefinition.apiextensions.k8s.io/bgpconfigurations.crd.projectcalico.org created customresourcedefinition.apiextensions.k8s.io/bgppeers.crd.projectcalico.org created customresourcedefinition.apiextensions.k8s.io/blockaffinities.crd.projectcalico.org created customresourcedefinition.apiextensions.k8s.io/caliconodestatuses.crd.projectcalico.org created customresourcedefinition.apiextensions.k8s.io/clusterinformations.crd.projectcalico.org created customresourcedefinition.apiextensions.k8s.io/felixconfigurations.crd.projectcalico.org created customresourcedefinition.apiextensions.k8s.io/globalnetworkpolicies.crd.projectcalico.org created customresourcedefinition.apiextensions.k8s.io/globalnetworksets.crd.projectcalico.org created customresourcedefinition.apiextensions.k8s.io/hostendpoints.crd.projectcalico.org created customresourcedefinition.apiextensions.k8s.io/ipamblocks.crd.projectcalico.org created customresourcedefinition.apiextensions.k8s.io/ipamconfigs.crd.projectcalico.org created customresourcedefinition.apiextensions.k8s.io/ipamhandles.crd.projectcalico.org created customresourcedefinition.apiextensions.k8s.io/ippools.crd.projectcalico.org created customresourcedefinition.apiextensions.k8s.io/ipreservations.crd.projectcalico.org created customresourcedefinition.apiextensions.k8s.io/kubecontrollersconfigurations.crd.projectcalico.org created customresourcedefinition.apiextensions.k8s.io/networkpolicies.crd.projectcalico.org created customresourcedefinition.apiextensions.k8s.io/networksets.crd.projectcalico.org created clusterrole.rbac.authorization.k8s.io/calico-kube-controllers created clusterrolebinding.rbac.authorization.k8s.io/calico-kube-controllers created clusterrole.rbac.authorization.k8s.io/calico-node created clusterrolebinding.rbac.authorization.k8s.io/calico-node created daemonset.apps/calico-node created serviceaccount/calico-node created deployment.apps/calico-kube-controllers created serviceaccount/calico-kube-controllers created poddisruptionbudget.policy/calico-kube-controllers created Verify status of Calico. Make sure all Pods are running kubectl get pod -n kube-system | grep calico Output: NAME READY STATUS RESTARTS AGE calico-kube-controllers-7bc6547ffb-tjfcg 1/1 Running 0 30m calico-node-7x8jm 1/1 Running 0 30m calico-node-cwxj5 1/1 Running 0 30m calico-node-rq978 1/1 Running 0 30m If facing any error, check log in the Container. # Get Container ID crictl ps # Get log info crictl logs As we change CNI from Flannel to Calico, we need delete all Pods. All of Pods will be created automatically again. kubectl delete pod -A --all Make sure all Pods are up and running successfully. kubectl get pod -A","title":"Replace Flannel by Calico"},{"location":"k8s/cka_en/foundamentals/networkpolicy/#inbound-rules","text":"Scenario Create workload for test. Deny For All Ingress Allow For Specific Ingress Verify NetworkPolicy Demo:","title":"Inbound Rules"},{"location":"k8s/cka_en/foundamentals/networkpolicy/#create-workload-for-test","text":"Create three Deployments pod-netpol-1 , pod-netpol-2 , pod-netpol-3 based on image busybox . kubectl apply -f - << EOF apiVersion: apps/v1 kind: Deployment metadata: labels: app: pod-netpol-1 name: pod-netpol-1 spec: replicas: 1 selector: matchLabels: app: pod-netpol-1 template: metadata: labels: app: pod-netpol-1 spec: containers: - image: busybox name: busybox command: [\"sh\", \"-c\", \"sleep 1h\"] --- apiVersion: apps/v1 kind: Deployment metadata: labels: app: pod-netpol-2 name: pod-netpol-2 spec: replicas: 1 selector: matchLabels: app: pod-netpol-2 template: metadata: labels: app: pod-netpol-2 spec: containers: - image: busybox name: busybox command: [\"sh\", \"-c\", \"sleep 1h\"] --- apiVersion: apps/v1 kind: Deployment metadata: labels: app: pod-netpol-3 name: pod-netpol-3 spec: replicas: 1 selector: matchLabels: app: pod-netpol-3 template: metadata: labels: app: pod-netpol-3 spec: containers: - image: busybox name: busybox command: [\"sh\", \"-c\", \"sleep 1h\"] EOF Check Pods IP. kubectl get pod -owide Output: NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES pod-netpol-1-6494f6bf8b-n58r9 1/1 Running 0 29s 10.244.102.30 cka003 pod-netpol-2-77478d77ff-l6rzm 1/1 Running 0 29s 10.244.112.30 cka002 pod-netpol-3-68977dcb48-ql5s6 1/1 Running 0 29s 10.244.102.31 cka003 Attach to Pod pod-netpol-1 kubectl exec -it pod-netpol-1-6494f6bf8b-n58r9 -- sh Execute command ping that pod-netpol-2 and pod-netpol-3 are both reachable. / # ping 10.244.112.30 3 packets transmitted, 3 packets received, 0% packet loss / # ping 10.244.102.31 3 packets transmitted, 3 packets received, 0% packet loss","title":"Create workload for test."},{"location":"k8s/cka_en/foundamentals/networkpolicy/#deny-for-all-ingress","text":"Create deny policy for all ingress. kubectl apply -f - << EOF apiVersion: networking.k8s.io/v1 kind: NetworkPolicy metadata: name: default-deny-ingress spec: podSelector: {} policyTypes: - Ingress EOF Attach to Pod pod-netpol-1 again kubectl exec -it pod-netpol-1-6494f6bf8b-n58r9 -- sh Execute command ping that pod-netpol-2 and pod-netpol-3 are both unreachable as expected. / # ping 10.244.112.30 3 packets transmitted, 0 packets received, 100% packet loss / # ping 10.244.102.31 3 packets transmitted, 0 packets received, 100% packet loss","title":"Deny For All Ingress"},{"location":"k8s/cka_en/foundamentals/networkpolicy/#allow-for-specific-ingress","text":"Create NetworkPlicy to allow ingress from pod-netpol-1 to pod-netpol-2 . kubectl apply -f - <:80 failed. Command curl :80 succeed. kubectl run centos --image=centos -n my-ns-1 -- \"/bin/sh\" \"-c\" \"sleep 3600\" kubectl exec -it mycentos -n my-ns-1 -- bash Create temp pod on namespace my-ns-2 . Attach to the pod and verify the access. Command curl :80 failed. Command curl :80 failed. kubectl run centos --image=centos -n my-ns-2 -- \"/bin/sh\" \"-c\" \"sleep 3600\" kubectl exec -it mycentos -n my-ns-2 -- bash Edit my-networkpolicy-1 to change ingress.from.namespaceSelector.matchLabels to my-ns-2 . Attach to temp pod on namespace my-ns-2 . Verify the access. Command curl :80 failed. Command curl :80 succeed. kubectl exec -it mycentos -n my-ns-2 -- bash Clean up: kubectl delete namespace my-ns-1 kubectl delete namespace my-ns-2","title":"NetworkPolicy"},{"location":"k8s/cka_en/foundamentals/overview/","text":"Cluster Overview \u00b6 Contents \u00b6 Container Layer Kubernetes Layer Information: For environment setup, refer to Installation on Aliyun Ubuntu Container Layer \u00b6 Scenario: Use Containerd service to manage our images and containers via command nerdctl , which is same concept with Docker. Get namespace. Get containers. Get images. Get volumes. Get overall status. Get network status. Demo: Get namespaces. sudo nerdctl namespace ls Result NAME CONTAINERS IMAGES VOLUMES LABELS k8s.io 21 30 0 Get containers under specific namespace k8s.io . sudo nerdctl -n k8s.io ps Result CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 0a3625f22f65 registry.aliyuncs.com/google_containers/pause:3.6 \"/pause\" 16 hours ago Up k8s://kube-system/coredns-74586cf9b6-4jwmk 121af2ecd1a1 registry.aliyuncs.com/google_containers/coredns:v1.8.6 \"/coredns -conf /etc\u2026\" 16 hours ago Up k8s://kube-system/coredns-74586cf9b6-c5mll/coredns 49f6c7e3efe5 registry.aliyuncs.com/google_containers/kube-proxy:v1.24.0 \"/usr/local/bin/kube\u2026\" 16 hours ago Up k8s://kube-system/kube-proxy-dmj2t/kube-proxy 4bba5fbd701d registry.aliyuncs.com/google_containers/pause:3.6 \"/pause\" 16 hours ago Up k8s://kube-system/kube-scheduler-cka001 57d47b57eb12 docker.io/calico/node:v3.23.3 \"start_runit\" 16 hours ago Up k8s://kube-system/calico-node-w8nvl/calico-node 5ce4c351a886 registry.aliyuncs.com/google_containers/pause:3.6 \"/pause\" 16 hours ago Up k8s://kube-system/calico-node-w8nvl 6456eef784bf registry.aliyuncs.com/google_containers/kube-scheduler:v1.24.0 \"kube-scheduler --au\u2026\" 16 hours ago Up k8s://kube-system/kube-scheduler-cka001/kube-scheduler 6a687305871c registry.aliyuncs.com/google_containers/kube-apiserver:v1.24.0 \"kube-apiserver --ad\u2026\" 16 hours ago Up k8s://kube-system/kube-apiserver-cka001/kube-apiserver 7dcb24568574 registry.aliyuncs.com/google_containers/pause:3.6 \"/pause\" 16 hours ago Up k8s://kube-system/coredns-74586cf9b6-c5mll a06b101118b8 registry.aliyuncs.com/google_containers/pause:3.6 \"/pause\" 16 hours ago Up k8s://kube-system/kube-controller-manager-cka001 a07ef8c3fc3a registry.aliyuncs.com/google_containers/pause:3.6 \"/pause\" 16 hours ago Up k8s://kube-system/etcd-cka001 b8566d3e4174 registry.aliyuncs.com/google_containers/kube-controller-manager:v1.24.0 \"kube-controller-man\u2026\" 16 hours ago Up k8s://kube-system/kube-controller-manager-cka001/kube-controller-manager ca6ac26314ff registry.aliyuncs.com/google_containers/coredns:v1.8.6 \"/coredns -conf /etc\u2026\" 16 hours ago Up k8s://kube-system/coredns-74586cf9b6-4jwmk/coredns cdc041b4791e registry.aliyuncs.com/google_containers/etcd:3.5.3-0 \"etcd --advertise-cl\u2026\" 16 hours ago Up k8s://kube-system/etcd-cka001/etcd e0c59abadf2e registry.aliyuncs.com/google_containers/pause:3.6 \"/pause\" 16 hours ago Up k8s://kube-system/kube-proxy-dmj2t e0d2e5f6ccff registry.aliyuncs.com/google_containers/pause:3.6 \"/pause\" 16 hours ago Up k8s://kube-system/kube-apiserver-cka001 Get images. sudo nerdctl -n k8s.io image ls -a Get volumes. After inintial installation, no volume within namespaces. sudo nerdctl -n k8s.io volume ls Get overall status sudo nerdctl stats Get network status. sudo nerdctl network ls sudo nerdctl network inspect bridge sudo nerdctl network inspect k8s-pod-network Result NETWORK ID NAME FILE k8s-pod-network /etc/cni/net.d/10-calico.conflist 0 bridge /etc/cni/net.d/nerdctl-bridge.conflist host none Get network interface in host cka001 with command ip addr list . IP pool of 10.4.0.1/24 is ipam and defined in /etc/cni/net.d/nerdctl-bridge.conflist . lo : inet 127.0.0.1/8 qlen 1000 eth0 : inet /24 brd xxx.xxx.xxx.255 scope global dynamic eth0 tunl0@NONE : inet 10.244.228.192/32 scope global tunl0 cali96e32d88db2@if4 : cali93613212490@if4 : Kubernetes Layer \u00b6 Scenario: Nodes Namespaces System Pods Demo: Information: In the demo, there are three nodes, cka001 , cka002 , and cka003 . Get nodes status. kubectl get node -o wide There are four initial namespaces across three nodes. kubectl get namespace -A Result NAME STATUS AGE default Active 56m kube-node-lease Active 56m kube-public Active 56m kube-system Active 56m There are some initial pods. kubectl get pod -A -o wide Result NAMESPACE NAME READY STATUS RESTARTS AGE NODE NOMINATED NODE READINESS GATES kube-system calico-kube-controllers-555bc4b957-l8bn2 1/1 Running 0 15h cka003 kube-system calico-node-255pc 1/1 Running 0 15h cka003 kube-system calico-node-7tmnb 1/1 Running 0 15h cka002 kube-system calico-node-w8nvl 1/1 Running 0 15h cka001 kube-system coredns-74586cf9b6-4jwmk 1/1 Running 0 15h cka001 kube-system coredns-74586cf9b6-c5mll 1/1 Running 0 15h cka001 kube-system etcd-cka001 1/1 Running 0 15h cka001 kube-system kube-apiserver-cka001 1/1 Running 0 15h cka001 kube-system kube-controller-manager-cka001 1/1 Running 0 15h cka001 kube-system kube-proxy-dmj2t 1/1 Running 0 15h cka001 kube-system kube-proxy-n77zw 1/1 Running 0 15h cka002 kube-system kube-proxy-qs6rf 1/1 Running 0 15h cka003 kube-system kube-scheduler-cka001 1/1 Running 0 15h cka001 Summary: Below shows the relationship between containers and pods. Master node: CoreDNS: 2 Pod etcd: 1 Pod apiserver: 1 Pod controller-manager: 1 Pod scheduler: 1 Pod Calico Controller: 1 Pod All nodes: Calico Node: 1 Pod each Proxy: 1 Pod each Reference Container pause: article and artical . nerdctl","title":"Overview"},{"location":"k8s/cka_en/foundamentals/overview/#cluster-overview","text":"","title":"Cluster Overview"},{"location":"k8s/cka_en/foundamentals/overview/#contents","text":"Container Layer Kubernetes Layer Information: For environment setup, refer to Installation on Aliyun Ubuntu","title":"Contents"},{"location":"k8s/cka_en/foundamentals/overview/#container-layer","text":"Scenario: Use Containerd service to manage our images and containers via command nerdctl , which is same concept with Docker. Get namespace. Get containers. Get images. Get volumes. Get overall status. Get network status. Demo: Get namespaces. sudo nerdctl namespace ls Result NAME CONTAINERS IMAGES VOLUMES LABELS k8s.io 21 30 0 Get containers under specific namespace k8s.io . sudo nerdctl -n k8s.io ps Result CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 0a3625f22f65 registry.aliyuncs.com/google_containers/pause:3.6 \"/pause\" 16 hours ago Up k8s://kube-system/coredns-74586cf9b6-4jwmk 121af2ecd1a1 registry.aliyuncs.com/google_containers/coredns:v1.8.6 \"/coredns -conf /etc\u2026\" 16 hours ago Up k8s://kube-system/coredns-74586cf9b6-c5mll/coredns 49f6c7e3efe5 registry.aliyuncs.com/google_containers/kube-proxy:v1.24.0 \"/usr/local/bin/kube\u2026\" 16 hours ago Up k8s://kube-system/kube-proxy-dmj2t/kube-proxy 4bba5fbd701d registry.aliyuncs.com/google_containers/pause:3.6 \"/pause\" 16 hours ago Up k8s://kube-system/kube-scheduler-cka001 57d47b57eb12 docker.io/calico/node:v3.23.3 \"start_runit\" 16 hours ago Up k8s://kube-system/calico-node-w8nvl/calico-node 5ce4c351a886 registry.aliyuncs.com/google_containers/pause:3.6 \"/pause\" 16 hours ago Up k8s://kube-system/calico-node-w8nvl 6456eef784bf registry.aliyuncs.com/google_containers/kube-scheduler:v1.24.0 \"kube-scheduler --au\u2026\" 16 hours ago Up k8s://kube-system/kube-scheduler-cka001/kube-scheduler 6a687305871c registry.aliyuncs.com/google_containers/kube-apiserver:v1.24.0 \"kube-apiserver --ad\u2026\" 16 hours ago Up k8s://kube-system/kube-apiserver-cka001/kube-apiserver 7dcb24568574 registry.aliyuncs.com/google_containers/pause:3.6 \"/pause\" 16 hours ago Up k8s://kube-system/coredns-74586cf9b6-c5mll a06b101118b8 registry.aliyuncs.com/google_containers/pause:3.6 \"/pause\" 16 hours ago Up k8s://kube-system/kube-controller-manager-cka001 a07ef8c3fc3a registry.aliyuncs.com/google_containers/pause:3.6 \"/pause\" 16 hours ago Up k8s://kube-system/etcd-cka001 b8566d3e4174 registry.aliyuncs.com/google_containers/kube-controller-manager:v1.24.0 \"kube-controller-man\u2026\" 16 hours ago Up k8s://kube-system/kube-controller-manager-cka001/kube-controller-manager ca6ac26314ff registry.aliyuncs.com/google_containers/coredns:v1.8.6 \"/coredns -conf /etc\u2026\" 16 hours ago Up k8s://kube-system/coredns-74586cf9b6-4jwmk/coredns cdc041b4791e registry.aliyuncs.com/google_containers/etcd:3.5.3-0 \"etcd --advertise-cl\u2026\" 16 hours ago Up k8s://kube-system/etcd-cka001/etcd e0c59abadf2e registry.aliyuncs.com/google_containers/pause:3.6 \"/pause\" 16 hours ago Up k8s://kube-system/kube-proxy-dmj2t e0d2e5f6ccff registry.aliyuncs.com/google_containers/pause:3.6 \"/pause\" 16 hours ago Up k8s://kube-system/kube-apiserver-cka001 Get images. sudo nerdctl -n k8s.io image ls -a Get volumes. After inintial installation, no volume within namespaces. sudo nerdctl -n k8s.io volume ls Get overall status sudo nerdctl stats Get network status. sudo nerdctl network ls sudo nerdctl network inspect bridge sudo nerdctl network inspect k8s-pod-network Result NETWORK ID NAME FILE k8s-pod-network /etc/cni/net.d/10-calico.conflist 0 bridge /etc/cni/net.d/nerdctl-bridge.conflist host none Get network interface in host cka001 with command ip addr list . IP pool of 10.4.0.1/24 is ipam and defined in /etc/cni/net.d/nerdctl-bridge.conflist . lo : inet 127.0.0.1/8 qlen 1000 eth0 : inet /24 brd xxx.xxx.xxx.255 scope global dynamic eth0 tunl0@NONE : inet 10.244.228.192/32 scope global tunl0 cali96e32d88db2@if4 : cali93613212490@if4 :","title":"Container Layer"},{"location":"k8s/cka_en/foundamentals/overview/#kubernetes-layer","text":"Scenario: Nodes Namespaces System Pods Demo: Information: In the demo, there are three nodes, cka001 , cka002 , and cka003 . Get nodes status. kubectl get node -o wide There are four initial namespaces across three nodes. kubectl get namespace -A Result NAME STATUS AGE default Active 56m kube-node-lease Active 56m kube-public Active 56m kube-system Active 56m There are some initial pods. kubectl get pod -A -o wide Result NAMESPACE NAME READY STATUS RESTARTS AGE NODE NOMINATED NODE READINESS GATES kube-system calico-kube-controllers-555bc4b957-l8bn2 1/1 Running 0 15h cka003 kube-system calico-node-255pc 1/1 Running 0 15h cka003 kube-system calico-node-7tmnb 1/1 Running 0 15h cka002 kube-system calico-node-w8nvl 1/1 Running 0 15h cka001 kube-system coredns-74586cf9b6-4jwmk 1/1 Running 0 15h cka001 kube-system coredns-74586cf9b6-c5mll 1/1 Running 0 15h cka001 kube-system etcd-cka001 1/1 Running 0 15h cka001 kube-system kube-apiserver-cka001 1/1 Running 0 15h cka001 kube-system kube-controller-manager-cka001 1/1 Running 0 15h cka001 kube-system kube-proxy-dmj2t 1/1 Running 0 15h cka001 kube-system kube-proxy-n77zw 1/1 Running 0 15h cka002 kube-system kube-proxy-qs6rf 1/1 Running 0 15h cka003 kube-system kube-scheduler-cka001 1/1 Running 0 15h cka001 Summary: Below shows the relationship between containers and pods. Master node: CoreDNS: 2 Pod etcd: 1 Pod apiserver: 1 Pod controller-manager: 1 Pod scheduler: 1 Pod Calico Controller: 1 Pod All nodes: Calico Node: 1 Pod each Proxy: 1 Pod each Reference Container pause: article and artical . nerdctl","title":"Kubernetes Layer"},{"location":"k8s/cka_en/foundamentals/persistence/","text":"Persistence \u00b6 Scenario Creat Pod with emptyDir type Volume. Container in the Pod will mount default directory /var/lib/kubelet/pods/ on running node. Create Deployment Deployment with hostPath type volume. Container in the Deployment will mount directory defined in hostPath: on running node. PV and PVC. Set up NFS Server and share folder /nfsdata/ . Create PV mysql-pv to link to the share folder /nfsdata/ and set StorageClassName nfs . Create PVC mysql-pvc mapped with StorageClassName nfs . Create Deployment mysql to consume PVC mysql-pvc . StorageClass Create ServiceAccount nfs-client-provisioner . Create ClusterRole nfs-client-provisioner-runner and Role leader-locking-nfs-client-provisioner and bind them to the ServiceAccount so the ServiceAccount has authorization to operate the Deployment created in next step. Create Deployment nfs-client-provisioner to to add connection information for your NFS server, e.g, PROVISIONER_NAME is k8s-sigs.io/ nfs-subdir-external-provisioner Create StorageClass nfs-client link to provisioner: k8s-sigs.io/nfs-subdir-external-provisioner . Releated PV is created automatically. Create PVC nfs-pvc-from-sc mapped to PV and StorageClass nfs-client . Configuration Create a ConfigMap for content of a file, and mount this ConfigMap to a specific file in a Pod. Create a ConfigMap for username and password, and consume them within a Pod. Use ConfigMap as environment variables in Pod. Tips Delete PVC first, then delete PV. If facing Terminating status when delete a PVC, use kubectl edit pvc and remove finalize: . emptyDir \u00b6 Create a Pod hello-producer with emptyDir type Volume. cat > pod-emptydir.yaml < /producer_dir/hello; sleep 30000 volumes: - name: shared-volume emptyDir: {} EOF kubectl apply -f pod-emptydir.yaml The Pod hello-producer is running on node cka003 . kubectl get pod hello-producer -owide The Pod is running on node cka003 . NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES hello-producer 1/1 Running 0 6s 10.244.102.24 cka003 Log onto cka003 because the Pod hello-producer is running on the node. Set up the environment CONTAINER_RUNTIME_ENDPOINT for command crictl . Suggest to do the same for all nodes. export CONTAINER_RUNTIME_ENDPOINT=unix:///run/containerd/containerd.sock Run command crictl ps to get the container ID of Pod hello-producer . crictl ps |grep hello-producer The ID of container producer is 05f5e1bb6a1bb . CONTAINER IMAGE CREATED STATE NAME ATTEMPT POD ID POD 50058afb3cba5 62aedd01bd852 About an hour ago Running producer 0 e6953bd4833a7 hello-producer Run command crictl inspect to get the path of mounted shared-volume , which is emptyDir . crictl inspect 50058afb3cba5 | grep source | grep empty The result is below. \"source\": \"/var/lib/kubelet/pods/d7424f86-534a-48f9-9001-9d2a6e822b12/volumes/kubernetes.io~empty-dir/shared-volume\", Change the path to the path of mounted shared-volume we get above. We will see the content hello world of file hello . cd /var/lib/kubelet/pods/d7424f86-534a-48f9-9001-9d2a6e822b12/volumes/kubernetes.io~empty-dir/shared-volume cat hello The path /producer_dir inside the Pod is mounted to the local host path /var/lib/kubelet/pods/d7424f86-534a-48f9-9001-9d2a6e822b12/volumes/kubernetes.io~empty-dir/shared-volume . The file /producer_dir/hello we created inside the Pod is actually in the host local path. Let's delete the container producer , the container producer will be started again with new container ID and the file hello is still there. crictl ps crictl stop crictl rm Let's delete the Pod hello-producer , the container producer is deleted, file hello is deleted. kubectl delete pod hello-producer hostPath \u00b6 Apply below yaml file to create a MySQL Pod and mount a hostPath . It'll mount host directory /tmp/mysql to Pod directory /var/lib/mysql . Check locally if directory /tmp/mysql is in place. If not, create it using mkdir /tmp/mysql . cat > mysql-hostpath.yaml < cka003 Attach into the MySQL Pod on the running node. kubectl exec -it -- bash Within the Pod, go to directory /var/lib/mysql , all files in the directory are same with all files in directory /tmp/mysql on node cka003 . Connect to the database in the Pod. mysql -h 127.0.0.1 -uroot -ppassword Operate the database. mysql> show databases; mysql> connect mysql; mysql> show tables; mysql> exit PV and PVC \u00b6 Here we will use NFS as backend storage to demo how to deploy PV and PVC. Set up NFS Share \u00b6 Install nfs-kernel-server Log onto cka002 . Choose one Worker cka002 to build NFS server. sudo apt-get install -y nfs-kernel-server Configure Share Folder Create share folder. mkdir /nfsdata Append one line in file /etc/exports . cat >> /etc/exports << EOF /nfsdata *(rw,sync,no_root_squash) EOF There are many different NFS sharing options, including these: * : accessable to all IPs, or specific IPs. rw : Share as read-write. Keep in mind that normal Linux permissions still apply. (Note that this is a default option.) ro : Share as read-only. sync : File data changes are made to disk immediately, which has an impact on performance, but is less likely to result in data loss. On som* `distributions this is the default. async : The opposite of sync; file data changes are made initially to memory. This speeds up performance but is more likely to result in data loss. O* `some distributions this is the default. root_squash : Map the root user and group account from the NFS client to the anonymous accounts, typically either the nobody account or the nfsnobod* `account. See the next section, \u201cUser ID Mapping,\u201d for more details. (Note that this is a default option.) no_root_squash : Map the root user and group account from the NFS client to the local root and group accounts. We will use password-free remote mount based on nfs and rpcbind services between Linux servers, not based on smb service. The two servers must first grant credit, install and set up nfs and rpcbind services on the server side, set the common directory, start the service, and mount it on the client Start rpcbind service. sudo systemctl enable rpcbind sudo systemctl restart rpcbind Start nfs service. sudo systemctl enable nfs-server sudo systemctl start nfs-server Once /etc/exports is changed, we need run below command to make change effected. exportfs -ra Result exportfs: /etc/exports [1]: Neither 'subtree_check' or 'no_subtree_check' specified for export \"*:/nfsdata\". Assuming default behaviour ('no_subtree_check'). NOTE: this default has changed since nfs-utils version 1.0.x Check whether sharefolder is configured. showmount -e And see below output. Export list for cka002: /nfsdata * Install NFS Client Install NFS client on all nodes. sudo apt-get install -y nfs-common Verify NFS Server Log onto any nodes to verify NFS service and sharefolder list. Log onto cka001 and check sharefolder status on cka002 . showmount -e cka002 Below result will be shown if no issues. Export list for cka002: /nfsdata * Mount NFS Execute below command to mount remote NFS folder on any other non-NFS-server node, e.g., cka001 or cka003 . mkdir /remote-nfs-dir mount -t nfs cka002:/nfsdata /remote-nfs-dir/ Use command df -h to verify mount point. Below is the sample output. Filesystem Size Used Avail Use% Mounted on cka002:/nfsdata 40G 5.8G 32G 16% /remote-nfs-dir Create PV \u00b6 Create a PV mysql-pv . Replace the NFS Server IP with actual IP (here is ) that NFS server cka002 is running on. kubectl apply -f - < EOF Check the PV. kubectl get pv The result: NAME CAPACITY ACCESS MODES RECLAIM POLICY STATUS CLAIM STORAGECLASS REASON AGE mysql-pv 1Gi RWO Retain Available nfs 19s Create PVC \u00b6 Create a PVC mysql-pvc and specify storage size, access mode, and storage class. The PVC mysql-pvc will be binded with PV automatically via storage class name. kubectl apply -f - < nfs-provisioner-rbac.yaml < ( cka002 ). Replace NFS server IP with actual IP (here is ) cat > nfs-provisioner-deployment.yaml < - name: NFS_PATH value: /nfsdata volumes: - name: nfs-client-root nfs: server: path: /nfsdata EOF kubectl apply -f nfs-provisioner-deployment.yaml Create NFS StorageClass \u00b6 Create StorageClass nfs-client . Define the NFS subdir external provisioner's Kubernetes Storage Class. vi nfs-storageclass.yaml And add below info to create NFS StorageClass. apiVersion : storage.k8s.io/v1 kind : StorageClass metadata : name : nfs-client annotations : storageclass.kubernetes.io/is-default-class : \"true\" provisioner : k8s-sigs.io/nfs-subdir-external-provisioner parameters : pathPattern : \"${.PVC.namespace}/${.PVC.annotations.nfs.io/storage-path}\" onDelete : delete Apply the yaml file. kubectl apply -f nfs-storageclass.yaml Create PVC \u00b6 Create PVC nfs-pvc-from-sc . kubectl apply -f - < mysql-with-sc-pvc-7c97d875f8-wkvr9 1/1 Running 0 3m37s 10.244.102.27 cka003 Let's check directory /nfsdata/ on NFS server cka002 . ll /nfsdata/ Two folders were created. Same content of /remote-nfs-dir/ on other nodes. drwxrwxrwx 6 systemd-coredump root 4096 Jul 23 23:35 dev/ drwxr-xr-x 6 systemd-coredump root 4096 Jul 23 22:29 mysqldata/ Namespace name is used as folder name under directory /nfsdata/ and it is mounted to Pod. By default, namespace name will be used at mount point. If we want to use customized folder for that purpose, we need claim an annotation nfs.io/storage-path , e.g., below example. Create PVC test-claim on Namespace kube-system and consume volume nfs-client . kubectl apply -f - < ..data/password lrwxrwxrwx 1 root root 15 Jul 23 16:30 username -> ..data/username And we can get the content of each element, which are predefined before. / # cat /tmp/secret/username admin / # cat /tmp/secret/password 123456 Additional Cases \u00b6 Various way to create ConfigMap \u00b6 ConfigMap can be created by file, directory, or value. Let's create a ConfigMap colors includes: Four files with four color names. One file with favorite color name. mkdir configmap cd configmap mkdir primary echo c > primary/cyan echo m > primary/magenta echo y > primary/yellow echo k > primary/black echo \"known as key\" >> primary/black echo blue > favorite Final structure looks like below via command tree configmap . configmap \u251c\u2500\u2500 favorite \u2514\u2500\u2500 primary \u251c\u2500\u2500 black \u251c\u2500\u2500 cyan \u251c\u2500\u2500 magenta \u2514\u2500\u2500 yellow Create ConfigMap referring above files we created. Make sure we are now in the path ~/configmap . kubectl create configmap colors \\ --from-literal=text=black \\ --from-file=./favorite \\ --from-file=./primary/ Check content of the ConfigMap colors . kubectl get configmap colors -o yaml apiVersion : v1 data : black : | k known as key cyan : | c favorite : | blue magenta : | m text : black yellow : | y kind : ConfigMap metadata : creationTimestamp : \"2022-07-12T16:38:27Z\" name : colors namespace : dev resourceVersion : \"2377258\" uid : d5ab133f-5e4d-41d4-bc9e-2bbb22a872a1 Set environment variable via ConfigMap \u00b6 Here we will create a Pod pod-configmap-env and set the environment variable ilike and assign value of favorite from ConfigMap colors . kubectl apply -f - << EOF apiVersion: v1 kind: Pod metadata: name: pod-configmap-env spec: containers: - name: nginx image: nginx env: - name: ilike valueFrom: configMapKeyRef: name: colors key: favorite EOF Attach to the Pod pod-configmap-env . kubectl exec -it pod-configmap-env -- bash Verify the value of env variable ilike is blue , which is the value of favorite of ConfigMap colors . root@pod-configmap-env:/# echo $ ilike blue We can also use all key-value of ConfigMap to set up environment variables of Pod. kubectl apply -f - << EOF apiVersion: v1 kind: Pod metadata: name: pod-configmap-env-2 spec: containers: - name: nginx image: nginx envFrom: - configMapRef: name: colors EOF Attach to the Pod pod-configmap-env-2 . kubectl exec -it pod-configmap-env-2 -- bash Verify the value of env variables based on key-values we defined in ConfigMap colors . root@pod-configmap-env-2:/# echo $ black k known as key root@pod-configmap-env-2:/# echo $ cyan c root@pod-configmap-env-2:/# echo $ favorite blue","title":"Persistence"},{"location":"k8s/cka_en/foundamentals/persistence/#persistence","text":"Scenario Creat Pod with emptyDir type Volume. Container in the Pod will mount default directory /var/lib/kubelet/pods/ on running node. Create Deployment Deployment with hostPath type volume. Container in the Deployment will mount directory defined in hostPath: on running node. PV and PVC. Set up NFS Server and share folder /nfsdata/ . Create PV mysql-pv to link to the share folder /nfsdata/ and set StorageClassName nfs . Create PVC mysql-pvc mapped with StorageClassName nfs . Create Deployment mysql to consume PVC mysql-pvc . StorageClass Create ServiceAccount nfs-client-provisioner . Create ClusterRole nfs-client-provisioner-runner and Role leader-locking-nfs-client-provisioner and bind them to the ServiceAccount so the ServiceAccount has authorization to operate the Deployment created in next step. Create Deployment nfs-client-provisioner to to add connection information for your NFS server, e.g, PROVISIONER_NAME is k8s-sigs.io/ nfs-subdir-external-provisioner Create StorageClass nfs-client link to provisioner: k8s-sigs.io/nfs-subdir-external-provisioner . Releated PV is created automatically. Create PVC nfs-pvc-from-sc mapped to PV and StorageClass nfs-client . Configuration Create a ConfigMap for content of a file, and mount this ConfigMap to a specific file in a Pod. Create a ConfigMap for username and password, and consume them within a Pod. Use ConfigMap as environment variables in Pod. Tips Delete PVC first, then delete PV. If facing Terminating status when delete a PVC, use kubectl edit pvc and remove finalize: .","title":"Persistence"},{"location":"k8s/cka_en/foundamentals/persistence/#emptydir","text":"Create a Pod hello-producer with emptyDir type Volume. cat > pod-emptydir.yaml < /producer_dir/hello; sleep 30000 volumes: - name: shared-volume emptyDir: {} EOF kubectl apply -f pod-emptydir.yaml The Pod hello-producer is running on node cka003 . kubectl get pod hello-producer -owide The Pod is running on node cka003 . NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES hello-producer 1/1 Running 0 6s 10.244.102.24 cka003 Log onto cka003 because the Pod hello-producer is running on the node. Set up the environment CONTAINER_RUNTIME_ENDPOINT for command crictl . Suggest to do the same for all nodes. export CONTAINER_RUNTIME_ENDPOINT=unix:///run/containerd/containerd.sock Run command crictl ps to get the container ID of Pod hello-producer . crictl ps |grep hello-producer The ID of container producer is 05f5e1bb6a1bb . CONTAINER IMAGE CREATED STATE NAME ATTEMPT POD ID POD 50058afb3cba5 62aedd01bd852 About an hour ago Running producer 0 e6953bd4833a7 hello-producer Run command crictl inspect to get the path of mounted shared-volume , which is emptyDir . crictl inspect 50058afb3cba5 | grep source | grep empty The result is below. \"source\": \"/var/lib/kubelet/pods/d7424f86-534a-48f9-9001-9d2a6e822b12/volumes/kubernetes.io~empty-dir/shared-volume\", Change the path to the path of mounted shared-volume we get above. We will see the content hello world of file hello . cd /var/lib/kubelet/pods/d7424f86-534a-48f9-9001-9d2a6e822b12/volumes/kubernetes.io~empty-dir/shared-volume cat hello The path /producer_dir inside the Pod is mounted to the local host path /var/lib/kubelet/pods/d7424f86-534a-48f9-9001-9d2a6e822b12/volumes/kubernetes.io~empty-dir/shared-volume . The file /producer_dir/hello we created inside the Pod is actually in the host local path. Let's delete the container producer , the container producer will be started again with new container ID and the file hello is still there. crictl ps crictl stop crictl rm Let's delete the Pod hello-producer , the container producer is deleted, file hello is deleted. kubectl delete pod hello-producer","title":"emptyDir"},{"location":"k8s/cka_en/foundamentals/persistence/#hostpath","text":"Apply below yaml file to create a MySQL Pod and mount a hostPath . It'll mount host directory /tmp/mysql to Pod directory /var/lib/mysql . Check locally if directory /tmp/mysql is in place. If not, create it using mkdir /tmp/mysql . cat > mysql-hostpath.yaml < cka003 Attach into the MySQL Pod on the running node. kubectl exec -it -- bash Within the Pod, go to directory /var/lib/mysql , all files in the directory are same with all files in directory /tmp/mysql on node cka003 . Connect to the database in the Pod. mysql -h 127.0.0.1 -uroot -ppassword Operate the database. mysql> show databases; mysql> connect mysql; mysql> show tables; mysql> exit","title":"hostPath"},{"location":"k8s/cka_en/foundamentals/persistence/#pv-and-pvc","text":"Here we will use NFS as backend storage to demo how to deploy PV and PVC.","title":"PV and PVC"},{"location":"k8s/cka_en/foundamentals/persistence/#set-up-nfs-share","text":"Install nfs-kernel-server Log onto cka002 . Choose one Worker cka002 to build NFS server. sudo apt-get install -y nfs-kernel-server Configure Share Folder Create share folder. mkdir /nfsdata Append one line in file /etc/exports . cat >> /etc/exports << EOF /nfsdata *(rw,sync,no_root_squash) EOF There are many different NFS sharing options, including these: * : accessable to all IPs, or specific IPs. rw : Share as read-write. Keep in mind that normal Linux permissions still apply. (Note that this is a default option.) ro : Share as read-only. sync : File data changes are made to disk immediately, which has an impact on performance, but is less likely to result in data loss. On som* `distributions this is the default. async : The opposite of sync; file data changes are made initially to memory. This speeds up performance but is more likely to result in data loss. O* `some distributions this is the default. root_squash : Map the root user and group account from the NFS client to the anonymous accounts, typically either the nobody account or the nfsnobod* `account. See the next section, \u201cUser ID Mapping,\u201d for more details. (Note that this is a default option.) no_root_squash : Map the root user and group account from the NFS client to the local root and group accounts. We will use password-free remote mount based on nfs and rpcbind services between Linux servers, not based on smb service. The two servers must first grant credit, install and set up nfs and rpcbind services on the server side, set the common directory, start the service, and mount it on the client Start rpcbind service. sudo systemctl enable rpcbind sudo systemctl restart rpcbind Start nfs service. sudo systemctl enable nfs-server sudo systemctl start nfs-server Once /etc/exports is changed, we need run below command to make change effected. exportfs -ra Result exportfs: /etc/exports [1]: Neither 'subtree_check' or 'no_subtree_check' specified for export \"*:/nfsdata\". Assuming default behaviour ('no_subtree_check'). NOTE: this default has changed since nfs-utils version 1.0.x Check whether sharefolder is configured. showmount -e And see below output. Export list for cka002: /nfsdata * Install NFS Client Install NFS client on all nodes. sudo apt-get install -y nfs-common Verify NFS Server Log onto any nodes to verify NFS service and sharefolder list. Log onto cka001 and check sharefolder status on cka002 . showmount -e cka002 Below result will be shown if no issues. Export list for cka002: /nfsdata * Mount NFS Execute below command to mount remote NFS folder on any other non-NFS-server node, e.g., cka001 or cka003 . mkdir /remote-nfs-dir mount -t nfs cka002:/nfsdata /remote-nfs-dir/ Use command df -h to verify mount point. Below is the sample output. Filesystem Size Used Avail Use% Mounted on cka002:/nfsdata 40G 5.8G 32G 16% /remote-nfs-dir","title":"Set up NFS Share"},{"location":"k8s/cka_en/foundamentals/persistence/#create-pv","text":"Create a PV mysql-pv . Replace the NFS Server IP with actual IP (here is ) that NFS server cka002 is running on. kubectl apply -f - < EOF Check the PV. kubectl get pv The result: NAME CAPACITY ACCESS MODES RECLAIM POLICY STATUS CLAIM STORAGECLASS REASON AGE mysql-pv 1Gi RWO Retain Available nfs 19s","title":"Create PV"},{"location":"k8s/cka_en/foundamentals/persistence/#create-pvc","text":"Create a PVC mysql-pvc and specify storage size, access mode, and storage class. The PVC mysql-pvc will be binded with PV automatically via storage class name. kubectl apply -f - < nfs-provisioner-rbac.yaml < ( cka002 ). Replace NFS server IP with actual IP (here is ) cat > nfs-provisioner-deployment.yaml < - name: NFS_PATH value: /nfsdata volumes: - name: nfs-client-root nfs: server: path: /nfsdata EOF kubectl apply -f nfs-provisioner-deployment.yaml","title":"Create Provisioner's Deloyment"},{"location":"k8s/cka_en/foundamentals/persistence/#create-nfs-storageclass","text":"Create StorageClass nfs-client . Define the NFS subdir external provisioner's Kubernetes Storage Class. vi nfs-storageclass.yaml And add below info to create NFS StorageClass. apiVersion : storage.k8s.io/v1 kind : StorageClass metadata : name : nfs-client annotations : storageclass.kubernetes.io/is-default-class : \"true\" provisioner : k8s-sigs.io/nfs-subdir-external-provisioner parameters : pathPattern : \"${.PVC.namespace}/${.PVC.annotations.nfs.io/storage-path}\" onDelete : delete Apply the yaml file. kubectl apply -f nfs-storageclass.yaml","title":"Create NFS StorageClass"},{"location":"k8s/cka_en/foundamentals/persistence/#create-pvc_1","text":"Create PVC nfs-pvc-from-sc . kubectl apply -f - < mysql-with-sc-pvc-7c97d875f8-wkvr9 1/1 Running 0 3m37s 10.244.102.27 cka003 Let's check directory /nfsdata/ on NFS server cka002 . ll /nfsdata/ Two folders were created. Same content of /remote-nfs-dir/ on other nodes. drwxrwxrwx 6 systemd-coredump root 4096 Jul 23 23:35 dev/ drwxr-xr-x 6 systemd-coredump root 4096 Jul 23 22:29 mysqldata/ Namespace name is used as folder name under directory /nfsdata/ and it is mounted to Pod. By default, namespace name will be used at mount point. If we want to use customized folder for that purpose, we need claim an annotation nfs.io/storage-path , e.g., below example. Create PVC test-claim on Namespace kube-system and consume volume nfs-client . kubectl apply -f - < ..data/password lrwxrwxrwx 1 root root 15 Jul 23 16:30 username -> ..data/username And we can get the content of each element, which are predefined before. / # cat /tmp/secret/username admin / # cat /tmp/secret/password 123456","title":"Secret"},{"location":"k8s/cka_en/foundamentals/persistence/#additional-cases","text":"","title":"Additional Cases"},{"location":"k8s/cka_en/foundamentals/persistence/#various-way-to-create-configmap","text":"ConfigMap can be created by file, directory, or value. Let's create a ConfigMap colors includes: Four files with four color names. One file with favorite color name. mkdir configmap cd configmap mkdir primary echo c > primary/cyan echo m > primary/magenta echo y > primary/yellow echo k > primary/black echo \"known as key\" >> primary/black echo blue > favorite Final structure looks like below via command tree configmap . configmap \u251c\u2500\u2500 favorite \u2514\u2500\u2500 primary \u251c\u2500\u2500 black \u251c\u2500\u2500 cyan \u251c\u2500\u2500 magenta \u2514\u2500\u2500 yellow Create ConfigMap referring above files we created. Make sure we are now in the path ~/configmap . kubectl create configmap colors \\ --from-literal=text=black \\ --from-file=./favorite \\ --from-file=./primary/ Check content of the ConfigMap colors . kubectl get configmap colors -o yaml apiVersion : v1 data : black : | k known as key cyan : | c favorite : | blue magenta : | m text : black yellow : | y kind : ConfigMap metadata : creationTimestamp : \"2022-07-12T16:38:27Z\" name : colors namespace : dev resourceVersion : \"2377258\" uid : d5ab133f-5e4d-41d4-bc9e-2bbb22a872a1","title":"Various way to create ConfigMap"},{"location":"k8s/cka_en/foundamentals/persistence/#set-environment-variable-via-configmap","text":"Here we will create a Pod pod-configmap-env and set the environment variable ilike and assign value of favorite from ConfigMap colors . kubectl apply -f - << EOF apiVersion: v1 kind: Pod metadata: name: pod-configmap-env spec: containers: - name: nginx image: nginx env: - name: ilike valueFrom: configMapKeyRef: name: colors key: favorite EOF Attach to the Pod pod-configmap-env . kubectl exec -it pod-configmap-env -- bash Verify the value of env variable ilike is blue , which is the value of favorite of ConfigMap colors . root@pod-configmap-env:/# echo $ ilike blue We can also use all key-value of ConfigMap to set up environment variables of Pod. kubectl apply -f - << EOF apiVersion: v1 kind: Pod metadata: name: pod-configmap-env-2 spec: containers: - name: nginx image: nginx envFrom: - configMapRef: name: colors EOF Attach to the Pod pod-configmap-env-2 . kubectl exec -it pod-configmap-env-2 -- bash Verify the value of env variables based on key-values we defined in ConfigMap colors . root@pod-configmap-env-2:/# echo $ black k known as key root@pod-configmap-env-2:/# echo $ cyan c root@pod-configmap-env-2:/# echo $ favorite blue","title":"Set environment variable via ConfigMap"},{"location":"k8s/cka_en/foundamentals/pod/","text":"Work on pod \u00b6 Create pod \u00b6 Create pod my-first-podl . kubectl apply -f - << EOF apiVersion: v1 kind: Pod metadata: name: my-first-pod spec: containers: - name: nginx image: nginx:mainline ports: - containerPort: 80 EOF Verify status of the pod just created. kubectl get pods -o wide Track pod \u00b6 Check logs of the pod just created. kubectl logs my-first-pod In case logs or describe or any other of the output generating commands don't help us to get to the root cause of an issue, we can use use kubectl exec -it -- bash command to look into it ourselves. kubectl exec -it my-first-pod -- bash root@my-first-pod:/# ls root@my-first-pod:/# cd bin root@my-first-pod:/bin# ls root@my-first-pod:/bin# exit Execute command kubectl explain pod.spec will get details of Spec segment of Pod kind in yaml file. We can check the official API reference of the pod resource for help or use kubectl explain pod to get a command-line based description of the resource. By appending . to the resource type, the explain command will provide more details on the specified field. kubectl explain pod.kind kubectl explain pod.spec kubectl explain pod.spec.containers kubectl explain pod.spec.containers.name Label pod \u00b6 Get pod's label with option --show-labels . kubectl get pods kubectl get pods --show-labels Add two labels to the pod pod my-first-pod . kubectl label pod my-first-pod nginx=mainline kubectl label pod my-first-pod env=demo kubectl get pods --show-labels Search pod by labels. kubectl get pod -l env=demo kubectl get pod -l env=demo,nginx=mainline kubectl get pod -l env=training Remove label kubectl label pods my-first-pod env- kubectl get pods --show-labels Describe pod. kubectl describe pod my-first-pod Delete pod. Run watch kubectl get pods to monitor the pod status. kubectl delete pod my-first-pod watch kubectl get pods Static Pod \u00b6 Scenario *Create a static pod. * kubectl will automatically check yaml file in /etc/kubernetes/manifests/ and create the static pod once it's detected. Demo: Some system static Pods are already in place. ll /etc/kubernetes/manifests/ Result -rw------- 1 root root 2292 Jul 23 10:45 etcd.yaml -rw------- 1 root root 3889 Jul 23 10:45 kube-apiserver.yaml -rw------- 1 root root 3395 Jul 23 10:45 kube-controller-manager.yaml -rw------- 1 root root 1464 Jul 23 10:45 kube-scheduler.yaml Create yaml file my-nginx.yaml in directory /etc/kubernetes/manifests/ . Once the file is created, the static pod my-nginx is created automatically. kubectl run my-nginx --image=nginx:mainline --dry-run=client -n default -oyaml | sudo tee /etc/kubernetes/manifests/my-nginx.yaml Check status of the Pod my-nginx . The node name cka001 is part of the Pod name, which means the Pod is running on node cka001 . kubectl get pod -o wide Result NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES my-nginx-cka001 1/1 Running 0 20s 10.244.228.196 cka001 Delete the yaml file /etc/kubernetes/manifests/my-nginx.yaml , the static pod will be deleted automatically. sudo rm /etc/kubernetes/manifests/my-nginx.yaml Multi-Container Pod \u00b6 Scenario: Create Multi-Container Pod Describe the Pod Check the log of Pod Check the log of Containers Create a Pod multi-container-pod with multiple container container-1-nginx and container-2-alpine . kubectl apply -f - << EOF apiVersion: v1 kind: Pod metadata: name: multi-container-pod spec: containers: - name: container-1-nginx image: nginx ports: - containerPort: 80 - name: container-2-alpine image: alpine command: [\"watch\", \"wget\", \"-qO-\", \"localhost\"] EOF Get the status. kubectl get pod multi-container-pod Result NAME READY STATUS RESTARTS AGE multi-container-pod 2/2 Running 0 81s Get details of the pod. kubectl describe pod multi-container-pod Result ....... Events: Type Reason Age From Message ---- ------ ---- ---- ------- Normal Scheduled 41s default-scheduler Successfully assigned dev/multi-container-pod to cka002 Normal Pulling 40s kubelet Pulling image \"nginx\" Normal Pulled 23s kubelet Successfully pulled image \"nginx\" in 16.767129903s Normal Created 22s kubelet Created container container-1-nginx Normal Started 22s kubelet Started container container-1-nginx Normal Pulling 22s kubelet Pulling image \"alpine\" Normal Pulled 14s kubelet Successfully pulled image \"alpine\" in 7.776104353s Normal Created 14s kubelet Created container container-2-alpine Normal Started 14s kubelet Started container container-2-alpine For multi-container pod, container name is needed if we want to get log of pod via command kubectl logs . Without the container name, we receive error. kubectl logs multi-container-pod Result error: a container name must be specified for pod multi-container-pod, choose one of: [container-1-nginx container-2-alpine] With specified container name, we get the log info. kubectl logs multi-container-pod container-1-nginx Result ...... ::1 - - [23/Jul/2022:04:06:37 +0000] \"GET / HTTP/1.1\" 200 615 \"-\" \"Wget\" \"-\" Same if we need specify container name to login into the pod via command kubectl exec -it -c -- . kubectl exec -it multi-container-pod -c container-1-nginx -- /bin/bash root@multi-container-pod:/# ls Clean up kubectl delete pod multi-container-pod Quick reference of a simple yaml file to create Multiple Containers. kubectl apply -f - << EOF apiVersion: v1 kind: Pod metadata: name: my-multi-pod spec: containers: - image: nginx name: nginx - image: memcached name: memcached - image: redis name: redis EOF Scenario: Create a Pod my-busybox with a container container-1-busybox . The container will write message to file /var/log/my-pod-busybox.log . Add another container container-2-busybox (Sidecar) to the Pod my-busybox . The sidecar container read message from file /var/log/my-pod-busybox.log . Tips: create a Volume to store the log file, which is shared with two containers. Demo: Create a Pod my-busybox with a container container-1-busybox . kubectl apply -f - << EOF apiVersion: v1 kind: Pod metadata: name: my-busybox spec: containers: - name: container-1-busybox image: busybox args: - /bin/sh - -c - > i=0; while true; do echo \"Hello message from container-1: $i\" >> /var/log/my-pod-busybox.log; i=$((i+1)); sleep 1; done EOF Search emptyDir in the Kubernetes documetation. Refer to below template for emptyDir via https://kubernetes.io/zh-cn/docs/concepts/storage/volumes/ Add below new features into the Pod Volume: volume name: logfile type: emptyDir Update existing container: name: container-1-busybox volumeMounts name: logfile mounthPath: /var/log Add new container: name: container-2-busybox image: busybox args: ['/bin/sh', '-c', 'tail -n+1 -f /var/log/my-pod-busybox.log'] volumeMounts: name: logfile mountPath: /var/log kubectl get pod my-busybox -o yaml > my-busybox.yaml vi my-busybox.yaml kubectl delete pod my-busybox kubectl apply -f my-busybox.yaml kubectl logs my-busybox -c container-2-busybox The final file my-busybox.yaml looks like below. apiVersion: v1 kind: Pod metadata: annotations: cni.projectcalico.org/containerID: 89644b6b073cd152f94b4cae7bdea6bbc3292cf59afd4f28102bd74f0205c9e4 cni.projectcalico.org/podIP: 10.244.102.20/32 cni.projectcalico.org/podIPs: 10.244.102.20/32 kubectl.kubernetes.io/last-applied-configuration: | {\"apiVersion\":\"v1\",\"kind\":\"Pod\",\"metadata\":{\"annotations\":{},\"name\":\"my-busybox\",\"namespace\":\"dev\"},\"spec\":{\"containers\":[{\"args\":[\"/bin/sh\",\"-c\",\"i=0; while true; do\\n echo \\\"Hello message from container-1: \\\" \\u003e\\u003e /var/log/my-pod-busybox.log;\\n i=1;\\n sleep 1;\\ndone\\n\"],\"image\":\"busybox\",\"name\":\"container-1-busybox\"}]}} creationTimestamp: \"2022-07-29T22:58:27Z\" name: my-busybox namespace: dev resourceVersion: \"1185720\" uid: c5e62a16-4459-4828-a441-7d1471b89a56 spec: containers: - name: container-2-busybox image: busybox args: ['/bin/sh', '-c', 'tail -n+1 -f /var/log/my-pod-busybox.log'] volumeMounts: - name: logfile mountPath: /var/log - args: - /bin/sh - -c - | i=0; while true; do echo \"Hello message from container-1: $i\" >> /var/log/my-pod-busybox.log; i=1; sleep 1; done image: busybox imagePullPolicy: Always name: container-1-busybox resources: {} terminationMessagePath: /dev/termination-log terminationMessagePolicy: File volumeMounts: - name: logfile mountPath: /var/log - mountPath: /var/run/secrets/kubernetes.io/serviceaccount name: kube-api-access-mhxlf readOnly: true dnsPolicy: ClusterFirst enableServiceLinks: true nodeName: cka003 preemptionPolicy: PreemptLowerPriority priority: 0 restartPolicy: Always schedulerName: default-scheduler securityContext: {} serviceAccount: default serviceAccountName: default terminationGracePeriodSeconds: 30 tolerations: - effect: NoExecute key: node.kubernetes.io/not-ready operator: Exists tolerationSeconds: 300 - effect: NoExecute key: node.kubernetes.io/unreachable operator: Exists tolerationSeconds: 300 volumes: - name: logfile emptyDir: {} - name: kube-api-access-mhxlf projected: defaultMode: 420 sources: - serviceAccountToken: expirationSeconds: 3607 path: token - configMap: items: - key: ca.crt path: ca.crt name: kube-root-ca.crt - downwardAPI: items: - fieldRef: apiVersion: v1 fieldPath: metadata.namespace path: namespace status: conditions: - lastProbeTime: null lastTransitionTime: \"2022-07-29T22:58:27Z\" status: \"True\" type: Initialized - lastProbeTime: null lastTransitionTime: \"2022-07-29T22:58:30Z\" status: \"True\" type: Ready - lastProbeTime: null lastTransitionTime: \"2022-07-29T22:58:30Z\" status: \"True\" type: ContainersReady - lastProbeTime: null lastTransitionTime: \"2022-07-29T22:58:27Z\" status: \"True\" type: PodScheduled containerStatuses: - containerID: containerd://fd42d4ba4d94d8918d8846327b1db2328be13c5f93f381877ff0228ed7b5468d image: docker.io/library/busybox:latest imageID: docker.io/library/busybox@sha256:0e97a8ca6955f22dbc7db9e9dbe970971f423541e52c34b8cb96ccc88d6a3883 lastState: {} name: container-1-busybox ready: true restartCount: 0 started: true state: running: startedAt: \"2022-07-29T22:58:30Z\" hostIP: phase: Running podIP: 10.244.102.20 podIPs: - ip: 10.244.102.20 qosClass: BestEffort startTime: \"2022-07-29T22:58:27Z\" Clean up: kubectl delete pod my-busybox initContainer Pod \u00b6 Scenario: Create Pod myapp-pod that has two init containers. myapp-container init-mydb Create two Services. myservice mydb Conclusion: myapp-container waits for Service myservice up in order to resolve the name myservice.dev.svc.cluster.local init-mydb waits for Service mydb up in order to resolve the name mydb.dev.svc.cluster.local . Demo: Create Pod myapp-pod with below yaml file. Create yaml file myapp-pod.yaml and add below content. Note: Due to the command $(cat /var/..... will be treated as host variable, we can not use echo to generate the file. It's the variabel in container itself. vi myapp-pod.yaml Content apiVersion: v1 kind: Pod metadata: name: myapp-pod labels: app: myapp spec: containers: - name: myapp-container image: busybox:1.28 command: ['sh', '-c', 'echo The app is running! && sleep 3600'] initContainers: - name: init-myservice image: busybox:1.28 command: ['sh', '-c', \"until nslookup myservice.$(cat /var/run/secrets/kubernetes.io/serviceaccount/namespace).svc.cluster.local; do echo waiting for myservice; sleep 2; done\"] - name: init-mydb image: busybox:1.28 command: ['sh', '-c', \"until nslookup mydb.$(cat /var/run/secrets/kubernetes.io/serviceaccount/namespace).svc.cluster.local; do echo waiting for mydb; sleep 2; done\"] Apply the yaml file to create the Pod. kubectl apply -f myapp-pod.yaml Check Pod status. kubectl get pod myapp-pod Result NAME READY STATUS RESTARTS AGE myapp-pod 0/1 Init:0/2 0 12m Inspect Pods. Get two errors: nslookup: can't resolve 'myservice.dev.svc.cluster.local' container \"init-mydb\" in pod \"myapp-pod\" is waiting to start: PodInitializing kubectl logs myapp-pod -c init-myservice # Inspect the first init container kubectl logs myapp-pod -c init-mydb # Inspect the second init container At this point, those init containers will be waiting to discover Services named mydb and myservice. Create the mydb and myservice services: kubectl apply -f - << EOF apiVersion: v1 kind: Service metadata: name: myservice spec: ports: - protocol: TCP port: 80 targetPort: 9376 --- apiVersion: v1 kind: Service metadata: name: mydb spec: ports: - protocol: TCP port: 80 targetPort: 9377 EOF Get current status of Services. kubectl get service Both of Services are up. NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE mydb ClusterIP 11.244.239.149 80/TCP 6s myservice ClusterIP 11.244.116.126 80/TCP 6s Get current Pod status. kubectl get pod myapp-pod -o wide The Pod is up. NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES myapp-pod 0/1 Init:0/2 0 2m40s 10.244.112.2 cka002 We now see that those init containers complete, and that the myapp-pod Pod moves into the Running state. Clean up. kubectl delete service mydb myservice kubectl delete pod myapp-pod References: Pod basics Lifecycle & phases Kubernetes pod design pattern","title":"Pod"},{"location":"k8s/cka_en/foundamentals/pod/#work-on-pod","text":"","title":"Work on pod"},{"location":"k8s/cka_en/foundamentals/pod/#create-pod","text":"Create pod my-first-podl . kubectl apply -f - << EOF apiVersion: v1 kind: Pod metadata: name: my-first-pod spec: containers: - name: nginx image: nginx:mainline ports: - containerPort: 80 EOF Verify status of the pod just created. kubectl get pods -o wide","title":"Create pod"},{"location":"k8s/cka_en/foundamentals/pod/#track-pod","text":"Check logs of the pod just created. kubectl logs my-first-pod In case logs or describe or any other of the output generating commands don't help us to get to the root cause of an issue, we can use use kubectl exec -it -- bash command to look into it ourselves. kubectl exec -it my-first-pod -- bash root@my-first-pod:/# ls root@my-first-pod:/# cd bin root@my-first-pod:/bin# ls root@my-first-pod:/bin# exit Execute command kubectl explain pod.spec will get details of Spec segment of Pod kind in yaml file. We can check the official API reference of the pod resource for help or use kubectl explain pod to get a command-line based description of the resource. By appending . to the resource type, the explain command will provide more details on the specified field. kubectl explain pod.kind kubectl explain pod.spec kubectl explain pod.spec.containers kubectl explain pod.spec.containers.name","title":"Track pod"},{"location":"k8s/cka_en/foundamentals/pod/#label-pod","text":"Get pod's label with option --show-labels . kubectl get pods kubectl get pods --show-labels Add two labels to the pod pod my-first-pod . kubectl label pod my-first-pod nginx=mainline kubectl label pod my-first-pod env=demo kubectl get pods --show-labels Search pod by labels. kubectl get pod -l env=demo kubectl get pod -l env=demo,nginx=mainline kubectl get pod -l env=training Remove label kubectl label pods my-first-pod env- kubectl get pods --show-labels Describe pod. kubectl describe pod my-first-pod Delete pod. Run watch kubectl get pods to monitor the pod status. kubectl delete pod my-first-pod watch kubectl get pods","title":"Label pod"},{"location":"k8s/cka_en/foundamentals/pod/#static-pod","text":"Scenario *Create a static pod. * kubectl will automatically check yaml file in /etc/kubernetes/manifests/ and create the static pod once it's detected. Demo: Some system static Pods are already in place. ll /etc/kubernetes/manifests/ Result -rw------- 1 root root 2292 Jul 23 10:45 etcd.yaml -rw------- 1 root root 3889 Jul 23 10:45 kube-apiserver.yaml -rw------- 1 root root 3395 Jul 23 10:45 kube-controller-manager.yaml -rw------- 1 root root 1464 Jul 23 10:45 kube-scheduler.yaml Create yaml file my-nginx.yaml in directory /etc/kubernetes/manifests/ . Once the file is created, the static pod my-nginx is created automatically. kubectl run my-nginx --image=nginx:mainline --dry-run=client -n default -oyaml | sudo tee /etc/kubernetes/manifests/my-nginx.yaml Check status of the Pod my-nginx . The node name cka001 is part of the Pod name, which means the Pod is running on node cka001 . kubectl get pod -o wide Result NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES my-nginx-cka001 1/1 Running 0 20s 10.244.228.196 cka001 Delete the yaml file /etc/kubernetes/manifests/my-nginx.yaml , the static pod will be deleted automatically. sudo rm /etc/kubernetes/manifests/my-nginx.yaml","title":"Static Pod"},{"location":"k8s/cka_en/foundamentals/pod/#multi-container-pod","text":"Scenario: Create Multi-Container Pod Describe the Pod Check the log of Pod Check the log of Containers Create a Pod multi-container-pod with multiple container container-1-nginx and container-2-alpine . kubectl apply -f - << EOF apiVersion: v1 kind: Pod metadata: name: multi-container-pod spec: containers: - name: container-1-nginx image: nginx ports: - containerPort: 80 - name: container-2-alpine image: alpine command: [\"watch\", \"wget\", \"-qO-\", \"localhost\"] EOF Get the status. kubectl get pod multi-container-pod Result NAME READY STATUS RESTARTS AGE multi-container-pod 2/2 Running 0 81s Get details of the pod. kubectl describe pod multi-container-pod Result ....... Events: Type Reason Age From Message ---- ------ ---- ---- ------- Normal Scheduled 41s default-scheduler Successfully assigned dev/multi-container-pod to cka002 Normal Pulling 40s kubelet Pulling image \"nginx\" Normal Pulled 23s kubelet Successfully pulled image \"nginx\" in 16.767129903s Normal Created 22s kubelet Created container container-1-nginx Normal Started 22s kubelet Started container container-1-nginx Normal Pulling 22s kubelet Pulling image \"alpine\" Normal Pulled 14s kubelet Successfully pulled image \"alpine\" in 7.776104353s Normal Created 14s kubelet Created container container-2-alpine Normal Started 14s kubelet Started container container-2-alpine For multi-container pod, container name is needed if we want to get log of pod via command kubectl logs . Without the container name, we receive error. kubectl logs multi-container-pod Result error: a container name must be specified for pod multi-container-pod, choose one of: [container-1-nginx container-2-alpine] With specified container name, we get the log info. kubectl logs multi-container-pod container-1-nginx Result ...... ::1 - - [23/Jul/2022:04:06:37 +0000] \"GET / HTTP/1.1\" 200 615 \"-\" \"Wget\" \"-\" Same if we need specify container name to login into the pod via command kubectl exec -it -c -- . kubectl exec -it multi-container-pod -c container-1-nginx -- /bin/bash root@multi-container-pod:/# ls Clean up kubectl delete pod multi-container-pod Quick reference of a simple yaml file to create Multiple Containers. kubectl apply -f - << EOF apiVersion: v1 kind: Pod metadata: name: my-multi-pod spec: containers: - image: nginx name: nginx - image: memcached name: memcached - image: redis name: redis EOF Scenario: Create a Pod my-busybox with a container container-1-busybox . The container will write message to file /var/log/my-pod-busybox.log . Add another container container-2-busybox (Sidecar) to the Pod my-busybox . The sidecar container read message from file /var/log/my-pod-busybox.log . Tips: create a Volume to store the log file, which is shared with two containers. Demo: Create a Pod my-busybox with a container container-1-busybox . kubectl apply -f - << EOF apiVersion: v1 kind: Pod metadata: name: my-busybox spec: containers: - name: container-1-busybox image: busybox args: - /bin/sh - -c - > i=0; while true; do echo \"Hello message from container-1: $i\" >> /var/log/my-pod-busybox.log; i=$((i+1)); sleep 1; done EOF Search emptyDir in the Kubernetes documetation. Refer to below template for emptyDir via https://kubernetes.io/zh-cn/docs/concepts/storage/volumes/ Add below new features into the Pod Volume: volume name: logfile type: emptyDir Update existing container: name: container-1-busybox volumeMounts name: logfile mounthPath: /var/log Add new container: name: container-2-busybox image: busybox args: ['/bin/sh', '-c', 'tail -n+1 -f /var/log/my-pod-busybox.log'] volumeMounts: name: logfile mountPath: /var/log kubectl get pod my-busybox -o yaml > my-busybox.yaml vi my-busybox.yaml kubectl delete pod my-busybox kubectl apply -f my-busybox.yaml kubectl logs my-busybox -c container-2-busybox The final file my-busybox.yaml looks like below. apiVersion: v1 kind: Pod metadata: annotations: cni.projectcalico.org/containerID: 89644b6b073cd152f94b4cae7bdea6bbc3292cf59afd4f28102bd74f0205c9e4 cni.projectcalico.org/podIP: 10.244.102.20/32 cni.projectcalico.org/podIPs: 10.244.102.20/32 kubectl.kubernetes.io/last-applied-configuration: | {\"apiVersion\":\"v1\",\"kind\":\"Pod\",\"metadata\":{\"annotations\":{},\"name\":\"my-busybox\",\"namespace\":\"dev\"},\"spec\":{\"containers\":[{\"args\":[\"/bin/sh\",\"-c\",\"i=0; while true; do\\n echo \\\"Hello message from container-1: \\\" \\u003e\\u003e /var/log/my-pod-busybox.log;\\n i=1;\\n sleep 1;\\ndone\\n\"],\"image\":\"busybox\",\"name\":\"container-1-busybox\"}]}} creationTimestamp: \"2022-07-29T22:58:27Z\" name: my-busybox namespace: dev resourceVersion: \"1185720\" uid: c5e62a16-4459-4828-a441-7d1471b89a56 spec: containers: - name: container-2-busybox image: busybox args: ['/bin/sh', '-c', 'tail -n+1 -f /var/log/my-pod-busybox.log'] volumeMounts: - name: logfile mountPath: /var/log - args: - /bin/sh - -c - | i=0; while true; do echo \"Hello message from container-1: $i\" >> /var/log/my-pod-busybox.log; i=1; sleep 1; done image: busybox imagePullPolicy: Always name: container-1-busybox resources: {} terminationMessagePath: /dev/termination-log terminationMessagePolicy: File volumeMounts: - name: logfile mountPath: /var/log - mountPath: /var/run/secrets/kubernetes.io/serviceaccount name: kube-api-access-mhxlf readOnly: true dnsPolicy: ClusterFirst enableServiceLinks: true nodeName: cka003 preemptionPolicy: PreemptLowerPriority priority: 0 restartPolicy: Always schedulerName: default-scheduler securityContext: {} serviceAccount: default serviceAccountName: default terminationGracePeriodSeconds: 30 tolerations: - effect: NoExecute key: node.kubernetes.io/not-ready operator: Exists tolerationSeconds: 300 - effect: NoExecute key: node.kubernetes.io/unreachable operator: Exists tolerationSeconds: 300 volumes: - name: logfile emptyDir: {} - name: kube-api-access-mhxlf projected: defaultMode: 420 sources: - serviceAccountToken: expirationSeconds: 3607 path: token - configMap: items: - key: ca.crt path: ca.crt name: kube-root-ca.crt - downwardAPI: items: - fieldRef: apiVersion: v1 fieldPath: metadata.namespace path: namespace status: conditions: - lastProbeTime: null lastTransitionTime: \"2022-07-29T22:58:27Z\" status: \"True\" type: Initialized - lastProbeTime: null lastTransitionTime: \"2022-07-29T22:58:30Z\" status: \"True\" type: Ready - lastProbeTime: null lastTransitionTime: \"2022-07-29T22:58:30Z\" status: \"True\" type: ContainersReady - lastProbeTime: null lastTransitionTime: \"2022-07-29T22:58:27Z\" status: \"True\" type: PodScheduled containerStatuses: - containerID: containerd://fd42d4ba4d94d8918d8846327b1db2328be13c5f93f381877ff0228ed7b5468d image: docker.io/library/busybox:latest imageID: docker.io/library/busybox@sha256:0e97a8ca6955f22dbc7db9e9dbe970971f423541e52c34b8cb96ccc88d6a3883 lastState: {} name: container-1-busybox ready: true restartCount: 0 started: true state: running: startedAt: \"2022-07-29T22:58:30Z\" hostIP: phase: Running podIP: 10.244.102.20 podIPs: - ip: 10.244.102.20 qosClass: BestEffort startTime: \"2022-07-29T22:58:27Z\" Clean up: kubectl delete pod my-busybox","title":"Multi-Container Pod"},{"location":"k8s/cka_en/foundamentals/pod/#initcontainer-pod","text":"Scenario: Create Pod myapp-pod that has two init containers. myapp-container init-mydb Create two Services. myservice mydb Conclusion: myapp-container waits for Service myservice up in order to resolve the name myservice.dev.svc.cluster.local init-mydb waits for Service mydb up in order to resolve the name mydb.dev.svc.cluster.local . Demo: Create Pod myapp-pod with below yaml file. Create yaml file myapp-pod.yaml and add below content. Note: Due to the command $(cat /var/..... will be treated as host variable, we can not use echo to generate the file. It's the variabel in container itself. vi myapp-pod.yaml Content apiVersion: v1 kind: Pod metadata: name: myapp-pod labels: app: myapp spec: containers: - name: myapp-container image: busybox:1.28 command: ['sh', '-c', 'echo The app is running! && sleep 3600'] initContainers: - name: init-myservice image: busybox:1.28 command: ['sh', '-c', \"until nslookup myservice.$(cat /var/run/secrets/kubernetes.io/serviceaccount/namespace).svc.cluster.local; do echo waiting for myservice; sleep 2; done\"] - name: init-mydb image: busybox:1.28 command: ['sh', '-c', \"until nslookup mydb.$(cat /var/run/secrets/kubernetes.io/serviceaccount/namespace).svc.cluster.local; do echo waiting for mydb; sleep 2; done\"] Apply the yaml file to create the Pod. kubectl apply -f myapp-pod.yaml Check Pod status. kubectl get pod myapp-pod Result NAME READY STATUS RESTARTS AGE myapp-pod 0/1 Init:0/2 0 12m Inspect Pods. Get two errors: nslookup: can't resolve 'myservice.dev.svc.cluster.local' container \"init-mydb\" in pod \"myapp-pod\" is waiting to start: PodInitializing kubectl logs myapp-pod -c init-myservice # Inspect the first init container kubectl logs myapp-pod -c init-mydb # Inspect the second init container At this point, those init containers will be waiting to discover Services named mydb and myservice. Create the mydb and myservice services: kubectl apply -f - << EOF apiVersion: v1 kind: Service metadata: name: myservice spec: ports: - protocol: TCP port: 80 targetPort: 9376 --- apiVersion: v1 kind: Service metadata: name: mydb spec: ports: - protocol: TCP port: 80 targetPort: 9377 EOF Get current status of Services. kubectl get service Both of Services are up. NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE mydb ClusterIP 11.244.239.149 80/TCP 6s myservice ClusterIP 11.244.116.126 80/TCP 6s Get current Pod status. kubectl get pod myapp-pod -o wide The Pod is up. NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES myapp-pod 0/1 Init:0/2 0 2m40s 10.244.112.2 cka002 We now see that those init containers complete, and that the myapp-pod Pod moves into the Running state. Clean up. kubectl delete service mydb myservice kubectl delete pod myapp-pod References: Pod basics Lifecycle & phases Kubernetes pod design pattern","title":"initContainer Pod"},{"location":"k8s/cka_en/foundamentals/policy/","text":"Policy \u00b6 ResourceQuota \u00b6 Scenario: Create ResourceQuota object-quota-demo for namespace quota-object-example . Test ResourceQuota object-quota-demo for NodePort Test ResourceQuota object-quota-demo for PVC Create Namespace \u00b6 Ceate a Namespace kubectl create ns quota-object-example Create ResourceQuota for Namespace \u00b6 Create ResourceQuota object-quota-demo for namespace quota-object-example . Within the namespace, we can only create 1 PVC, 1 LoadBalancer Service, can not create NodePort Service. kubectl apply -f - <@ ) CURRENT NAME CLUSTER AUTHINFO NAMESPACE * kubernetes-admin@kubernetes kubernetes kubernetes-admin dev Create CA Config File \u00b6 Get overview of directory /etc/kubernetes/pki . tree /etc/kubernetes/pki Result /etc/kubernetes/pki \u251c\u2500\u2500 apiserver.crt \u251c\u2500\u2500 apiserver-etcd-client.crt \u251c\u2500\u2500 apiserver-etcd-client.key \u251c\u2500\u2500 apiserver.key \u251c\u2500\u2500 apiserver-kubelet-client.crt \u251c\u2500\u2500 apiserver-kubelet-client.key \u251c\u2500\u2500 ca.crt \u251c\u2500\u2500 ca.key \u251c\u2500\u2500 etcd \u2502 \u251c\u2500\u2500 ca.crt \u2502 \u251c\u2500\u2500 ca.key \u2502 \u251c\u2500\u2500 healthcheck-client.crt \u2502 \u251c\u2500\u2500 healthcheck-client.key \u2502 \u251c\u2500\u2500 peer.crt \u2502 \u251c\u2500\u2500 peer.key \u2502 \u251c\u2500\u2500 server.crt \u2502 \u2514\u2500\u2500 server.key \u251c\u2500\u2500 front-proxy-ca.crt \u251c\u2500\u2500 front-proxy-ca.key \u251c\u2500\u2500 front-proxy-client.crt \u251c\u2500\u2500 front-proxy-client.key \u251c\u2500\u2500 sa.key \u2514\u2500\u2500 sa.pub Change to directory /etc/kubernetes/pki . cd /etc/kubernetes/pki Check if file ca-config.json is in place in current directory. ll ca-config.json If not, create it. We can add multiple profiles to specify different expiry date, scenario, parameters, etc.. Profile will be used to sign certificate. 87600 hours are about 10 years. Here we will create 1 additional profile dev . cat > ca-config.json < cka-dev-csr.json < here) to composite evn variable APISERVER ( https://: ). kubectl get node -owide NAME STATUS ROLES AGE VERSION OS-IMAGE KERNEL-VERSION CONTAINER-RUNTIME cka001 Ready control-plane,master 14h v1.24.0 Ubuntu 20.04.4 LTS 5.4.0-122-generic containerd://1.5.9 cka002 Ready 14h v1.24.0 Ubuntu 20.04.4 LTS 5.4.0-122-generic containerd://1.5.9 cka003 Ready 14h v1.24.0 Ubuntu 20.04.4 LTS 5.4.0-122-generic containerd://1.5.9 Export env APISERVER . echo \"export APISERVER=\\\"https://:6443\\\"\" >> ~/.bashrc source ~/.bashrc Verify the setting. echo $APISERVER Output: https://:6443 1.Set up cluster Stay in the directory /etc/kubernetes/pki . Generate kubeconfig file. kubectl config set-cluster kubernetes \\ --certificate-authority=/etc/kubernetes/pki/ca.crt \\ --embed-certs=true \\ --server=${APISERVER} \\ --kubeconfig=cka-dev.kubeconfig Now we get the new config file cka-dev.kubeconfig ll -tr | grep cka-dev Output: -rw-r--r-- 1 root root 222 Jul 24 08:49 cka-dev-csr.json -rw-r--r-- 1 root root 1281 Jul 24 09:14 cka-dev.pem -rw------- 1 root root 1675 Jul 24 09:14 cka-dev-key.pem -rw-r--r-- 1 root root 1001 Jul 24 09:14 cka-dev.csr -rw------- 1 root root 1671 Jul 24 09:16 cka-dev.kubeconfig Get content of file cka-dev.kubeconfig . cat cka-dev.kubeconfig apiVersion : v1 clusters : - cluster : certificate-authority-data : server : https://:6443 name : kubernetes contexts : null current-context : \"\" kind : Config preferences : {} users : null 2.Set up user In file cka-dev.kubeconfig , user info is null. Set up user cka-dev . kubectl config set-credentials cka-dev \\ --client-certificate=/etc/kubernetes/pki/cka-dev.pem \\ --client-key=/etc/kubernetes/pki/cka-dev-key.pem \\ --embed-certs=true \\ --kubeconfig=cka-dev.kubeconfig Now file cka-dev.kubeconfig was updated and user information was added. cat cka-dev.kubeconfig apiVersion : v1 clusters : - cluster : certificate-authority-data : server : https://:6443 name : kubernetes contexts : null current-context : \"\" kind : Config preferences : {} users : - name : cka-dev user : client-certificate-data : client-key-data : Now we have a complete kubeconfig file cka-dev.kubeconfig . When we use it to get node information, receive error below because we did not set up current-context in kubeconfig file. kubectl --kubeconfig=cka-dev.kubeconfig get nodes The connection to the server localhost:8080 was refused - did you specify the right host or port? Current contents is empty. kubectl --kubeconfig=cka-dev.kubeconfig config get-contexts CURRENT NAME CLUSTER AUTHINFO NAMESPACE 3.Set up Context Set up context. kubectl config set-context dev --cluster=kubernetes --user=cka-dev --kubeconfig=cka-dev.kubeconfig Now we have context now but the CURRENT flag is empty. kubectl --kubeconfig=cka-dev.kubeconfig config get-contexts Output: CURRENT NAME CLUSTER AUTHINFO NAMESPACE dev kubernetes cka-dev Set up default context. The context will link clusters and users for multiple clusters environment and we can switch to different cluster. kubectl --kubeconfig=cka-dev.kubeconfig config use-context dev 4.Verify Now CURRENT is marked with * , that is, current-context is set up. kubectl --kubeconfig=cka-dev.kubeconfig config get-contexts CURRENT NAME CLUSTER AUTHINFO NAMESPACE * dev kubernetes cka-dev Because user cka-dev does not have authorization in the cluster, we will receive forbidden error when we try to get information of Pods or Nodes. kubectl --kubeconfig=/etc/kubernetes/pki/cka-dev.kubeconfig get pod kubectl --kubeconfig=/etc/kubernetes/pki/cka-dev.kubeconfig get node Merge kubeconfig files \u00b6 Make a copy of your existing config cp ~/.kube/config ~/.kube/config.old Merge the two config files together into a new config file /tmp/config . KUBECONFIG=~/.kube/config:/etc/kubernetes/pki/cka-dev.kubeconfig kubectl config view --flatten > /tmp/config Replace the old config with the new merged config mv /tmp/config ~/.kube/config Now the new ~/.kube/config looks like below. apiVersion: v1 clusters: - cluster: certificate-authority-data: server: https://:6443 name: kubernetes contexts: - context: cluster: kubernetes user: cka-dev name: dev - context: cluster: kubernetes user: kubernetes-admin name: kubernetes-admin@kubernetes current-context: kubernetes-admin@kubernetes kind: Config preferences: {} users: - name: cka-dev user: client-certificate-data: client-key-data: - name: kubernetes-admin user: client-certificate-data: client-key-data: Verify contexts after kubeconfig merged. kubectl config get-contexts Current context is the system default kubernetes-admin@kubernetes . CURRENT NAME CLUSTER AUTHINFO NAMESPACE dev kubernetes cka-dev * kubernetes-admin@kubernetes kubernetes kubernetes-admin dev Namespaces & Contexts \u00b6 Get list of Namespace with Label information. kubectl get ns --show-labels Create Namespace cka . kubectl create namespace cka Use below command to set a context with new update, e.g, update default namespace, etc.. kubectl config set-context --cluster= --namespace= --user= Let's set default namespace to each context. kubectl config set-context kubernetes-admin@kubernetes --cluster=kubernetes --namespace=default --user=kubernetes-admin kubectl config set-context dev --cluster=kubernetes --namespace=cka --user=cka-dev Let's check current context information. kubectl config get-contexts Output: CURRENT NAME CLUSTER AUTHINFO NAMESPACE dev kubernetes cka-dev cka * kubernetes-admin@kubernetes kubernetes kubernetes-admin dev To switch to a new context, use below command. kubectl config use-contexts For example. kubectl config use-context dev Verify if it's changed as expected. kubectl config get-contexts CURRENT NAME CLUSTER AUTHINFO NAMESPACE * dev kubernetes cka-dev cka kubernetes-admin@kubernetes kubernetes kubernetes-admin dev Be noted, four users beginning with cka-dev created don't have any authorizations, e.g., access namespaces, get pods, etc.. Referring RBAC to grant their authorizations. Role & RoleBinding \u00b6 Switch to context kubernetes-admin@kubernetes . kubectl config use-context kubernetes-admin@kubernetes Use kubectl create role command with option --dry-run=client and -o yaml to generate yaml template for customizing. kubectl create role admin-dev --resource=pods --verb=get --verb=list --verb=watch --dry-run=client -o yaml Create role admin-dev on namespace cka . kubectl apply -f - << EOF apiVersion: rbac.authorization.k8s.io/v1 kind: Role metadata: namespace: cka name: admin-dev rules: - apiGroups: - \"\" resources: - pods verbs: - get - watch - list EOF Use kubectl create rolebinding command with option --dry-run=client and -o yaml to generate yaml template for customizing. kubectl create rolebinding admin --role=admin-dev --user=cka-dev --dry-run=client -o yaml Create rolebinding admin on namespace cka . kubectl apply -f - << EOF apiVersion: rbac.authorization.k8s.io/v1 kind: RoleBinding metadata: name: admin namespace: cka roleRef: apiGroup: rbac.authorization.k8s.io kind: Role name: admin-dev subjects: - apiGroup: rbac.authorization.k8s.io kind: User name: cka-dev EOF Verify authorzation of user cka-dev on Namespace cka . Switch to context dev . kubectl config use-context dev Get Pods status in Namespace cka . Success! kubectl get pod -n cka Get Pods status in Namespace kube-system . Failed, because the authorzation is only for Namespace cka . kubectl get pod -n kube-system Get Nodes status. Failed, because the role we defined is only for Pod resource. kubectl get node Create a Pod in Namespace dev . Failed because we only have get , watch , list for Pod, no create authorization. kubectl run nginx --image=nginx -n cka ClusterRole & ClusterRoleBinding \u00b6 Switch to context kubernetes-admin@kubernetes . kubectl config use-context kubernetes-admin@kubernetes Create a ClusterRole nodes-admin with authorization get , watch , list for nodes resource. kubectl apply -f - <@ ) CURRENT NAME CLUSTER AUTHINFO NAMESPACE * kubernetes-admin@kubernetes kubernetes kubernetes-admin dev","title":"Current Context"},{"location":"k8s/cka_en/foundamentals/rbac/#create-ca-config-file","text":"Get overview of directory /etc/kubernetes/pki . tree /etc/kubernetes/pki Result /etc/kubernetes/pki \u251c\u2500\u2500 apiserver.crt \u251c\u2500\u2500 apiserver-etcd-client.crt \u251c\u2500\u2500 apiserver-etcd-client.key \u251c\u2500\u2500 apiserver.key \u251c\u2500\u2500 apiserver-kubelet-client.crt \u251c\u2500\u2500 apiserver-kubelet-client.key \u251c\u2500\u2500 ca.crt \u251c\u2500\u2500 ca.key \u251c\u2500\u2500 etcd \u2502 \u251c\u2500\u2500 ca.crt \u2502 \u251c\u2500\u2500 ca.key \u2502 \u251c\u2500\u2500 healthcheck-client.crt \u2502 \u251c\u2500\u2500 healthcheck-client.key \u2502 \u251c\u2500\u2500 peer.crt \u2502 \u251c\u2500\u2500 peer.key \u2502 \u251c\u2500\u2500 server.crt \u2502 \u2514\u2500\u2500 server.key \u251c\u2500\u2500 front-proxy-ca.crt \u251c\u2500\u2500 front-proxy-ca.key \u251c\u2500\u2500 front-proxy-client.crt \u251c\u2500\u2500 front-proxy-client.key \u251c\u2500\u2500 sa.key \u2514\u2500\u2500 sa.pub Change to directory /etc/kubernetes/pki . cd /etc/kubernetes/pki Check if file ca-config.json is in place in current directory. ll ca-config.json If not, create it. We can add multiple profiles to specify different expiry date, scenario, parameters, etc.. Profile will be used to sign certificate. 87600 hours are about 10 years. Here we will create 1 additional profile dev . cat > ca-config.json < cka-dev-csr.json < here) to composite evn variable APISERVER ( https://: ). kubectl get node -owide NAME STATUS ROLES AGE VERSION OS-IMAGE KERNEL-VERSION CONTAINER-RUNTIME cka001 Ready control-plane,master 14h v1.24.0 Ubuntu 20.04.4 LTS 5.4.0-122-generic containerd://1.5.9 cka002 Ready 14h v1.24.0 Ubuntu 20.04.4 LTS 5.4.0-122-generic containerd://1.5.9 cka003 Ready 14h v1.24.0 Ubuntu 20.04.4 LTS 5.4.0-122-generic containerd://1.5.9 Export env APISERVER . echo \"export APISERVER=\\\"https://:6443\\\"\" >> ~/.bashrc source ~/.bashrc Verify the setting. echo $APISERVER Output: https://:6443 1.Set up cluster Stay in the directory /etc/kubernetes/pki . Generate kubeconfig file. kubectl config set-cluster kubernetes \\ --certificate-authority=/etc/kubernetes/pki/ca.crt \\ --embed-certs=true \\ --server=${APISERVER} \\ --kubeconfig=cka-dev.kubeconfig Now we get the new config file cka-dev.kubeconfig ll -tr | grep cka-dev Output: -rw-r--r-- 1 root root 222 Jul 24 08:49 cka-dev-csr.json -rw-r--r-- 1 root root 1281 Jul 24 09:14 cka-dev.pem -rw------- 1 root root 1675 Jul 24 09:14 cka-dev-key.pem -rw-r--r-- 1 root root 1001 Jul 24 09:14 cka-dev.csr -rw------- 1 root root 1671 Jul 24 09:16 cka-dev.kubeconfig Get content of file cka-dev.kubeconfig . cat cka-dev.kubeconfig apiVersion : v1 clusters : - cluster : certificate-authority-data : server : https://:6443 name : kubernetes contexts : null current-context : \"\" kind : Config preferences : {} users : null 2.Set up user In file cka-dev.kubeconfig , user info is null. Set up user cka-dev . kubectl config set-credentials cka-dev \\ --client-certificate=/etc/kubernetes/pki/cka-dev.pem \\ --client-key=/etc/kubernetes/pki/cka-dev-key.pem \\ --embed-certs=true \\ --kubeconfig=cka-dev.kubeconfig Now file cka-dev.kubeconfig was updated and user information was added. cat cka-dev.kubeconfig apiVersion : v1 clusters : - cluster : certificate-authority-data : server : https://:6443 name : kubernetes contexts : null current-context : \"\" kind : Config preferences : {} users : - name : cka-dev user : client-certificate-data : client-key-data : Now we have a complete kubeconfig file cka-dev.kubeconfig . When we use it to get node information, receive error below because we did not set up current-context in kubeconfig file. kubectl --kubeconfig=cka-dev.kubeconfig get nodes The connection to the server localhost:8080 was refused - did you specify the right host or port? Current contents is empty. kubectl --kubeconfig=cka-dev.kubeconfig config get-contexts CURRENT NAME CLUSTER AUTHINFO NAMESPACE 3.Set up Context Set up context. kubectl config set-context dev --cluster=kubernetes --user=cka-dev --kubeconfig=cka-dev.kubeconfig Now we have context now but the CURRENT flag is empty. kubectl --kubeconfig=cka-dev.kubeconfig config get-contexts Output: CURRENT NAME CLUSTER AUTHINFO NAMESPACE dev kubernetes cka-dev Set up default context. The context will link clusters and users for multiple clusters environment and we can switch to different cluster. kubectl --kubeconfig=cka-dev.kubeconfig config use-context dev 4.Verify Now CURRENT is marked with * , that is, current-context is set up. kubectl --kubeconfig=cka-dev.kubeconfig config get-contexts CURRENT NAME CLUSTER AUTHINFO NAMESPACE * dev kubernetes cka-dev Because user cka-dev does not have authorization in the cluster, we will receive forbidden error when we try to get information of Pods or Nodes. kubectl --kubeconfig=/etc/kubernetes/pki/cka-dev.kubeconfig get pod kubectl --kubeconfig=/etc/kubernetes/pki/cka-dev.kubeconfig get node","title":"Create file kubeconfig"},{"location":"k8s/cka_en/foundamentals/rbac/#merge-kubeconfig-files","text":"Make a copy of your existing config cp ~/.kube/config ~/.kube/config.old Merge the two config files together into a new config file /tmp/config . KUBECONFIG=~/.kube/config:/etc/kubernetes/pki/cka-dev.kubeconfig kubectl config view --flatten > /tmp/config Replace the old config with the new merged config mv /tmp/config ~/.kube/config Now the new ~/.kube/config looks like below. apiVersion: v1 clusters: - cluster: certificate-authority-data: server: https://:6443 name: kubernetes contexts: - context: cluster: kubernetes user: cka-dev name: dev - context: cluster: kubernetes user: kubernetes-admin name: kubernetes-admin@kubernetes current-context: kubernetes-admin@kubernetes kind: Config preferences: {} users: - name: cka-dev user: client-certificate-data: client-key-data: - name: kubernetes-admin user: client-certificate-data: client-key-data: Verify contexts after kubeconfig merged. kubectl config get-contexts Current context is the system default kubernetes-admin@kubernetes . CURRENT NAME CLUSTER AUTHINFO NAMESPACE dev kubernetes cka-dev * kubernetes-admin@kubernetes kubernetes kubernetes-admin dev","title":"Merge kubeconfig files"},{"location":"k8s/cka_en/foundamentals/rbac/#namespaces-contexts","text":"Get list of Namespace with Label information. kubectl get ns --show-labels Create Namespace cka . kubectl create namespace cka Use below command to set a context with new update, e.g, update default namespace, etc.. kubectl config set-context --cluster= --namespace= --user= Let's set default namespace to each context. kubectl config set-context kubernetes-admin@kubernetes --cluster=kubernetes --namespace=default --user=kubernetes-admin kubectl config set-context dev --cluster=kubernetes --namespace=cka --user=cka-dev Let's check current context information. kubectl config get-contexts Output: CURRENT NAME CLUSTER AUTHINFO NAMESPACE dev kubernetes cka-dev cka * kubernetes-admin@kubernetes kubernetes kubernetes-admin dev To switch to a new context, use below command. kubectl config use-contexts For example. kubectl config use-context dev Verify if it's changed as expected. kubectl config get-contexts CURRENT NAME CLUSTER AUTHINFO NAMESPACE * dev kubernetes cka-dev cka kubernetes-admin@kubernetes kubernetes kubernetes-admin dev Be noted, four users beginning with cka-dev created don't have any authorizations, e.g., access namespaces, get pods, etc.. Referring RBAC to grant their authorizations.","title":"Namespaces & Contexts"},{"location":"k8s/cka_en/foundamentals/rbac/#role-rolebinding","text":"Switch to context kubernetes-admin@kubernetes . kubectl config use-context kubernetes-admin@kubernetes Use kubectl create role command with option --dry-run=client and -o yaml to generate yaml template for customizing. kubectl create role admin-dev --resource=pods --verb=get --verb=list --verb=watch --dry-run=client -o yaml Create role admin-dev on namespace cka . kubectl apply -f - << EOF apiVersion: rbac.authorization.k8s.io/v1 kind: Role metadata: namespace: cka name: admin-dev rules: - apiGroups: - \"\" resources: - pods verbs: - get - watch - list EOF Use kubectl create rolebinding command with option --dry-run=client and -o yaml to generate yaml template for customizing. kubectl create rolebinding admin --role=admin-dev --user=cka-dev --dry-run=client -o yaml Create rolebinding admin on namespace cka . kubectl apply -f - << EOF apiVersion: rbac.authorization.k8s.io/v1 kind: RoleBinding metadata: name: admin namespace: cka roleRef: apiGroup: rbac.authorization.k8s.io kind: Role name: admin-dev subjects: - apiGroup: rbac.authorization.k8s.io kind: User name: cka-dev EOF Verify authorzation of user cka-dev on Namespace cka . Switch to context dev . kubectl config use-context dev Get Pods status in Namespace cka . Success! kubectl get pod -n cka Get Pods status in Namespace kube-system . Failed, because the authorzation is only for Namespace cka . kubectl get pod -n kube-system Get Nodes status. Failed, because the role we defined is only for Pod resource. kubectl get node Create a Pod in Namespace dev . Failed because we only have get , watch , list for Pod, no create authorization. kubectl run nginx --image=nginx -n cka","title":"Role & RoleBinding"},{"location":"k8s/cka_en/foundamentals/rbac/#clusterrole-clusterrolebinding","text":"Switch to context kubernetes-admin@kubernetes . kubectl config use-context kubernetes-admin@kubernetes Create a ClusterRole nodes-admin with authorization get , watch , list for nodes resource. kubectl apply -f - < nodeName \u00b6 Be noted, nodeName has hightest priority as it's not scheduled by Scheduler . Create a Pod nginx-nodename with nodeName=cka003 . kubectl apply -f - < Affinity \u00b6 In Kubernetes cluster, some Pods have frequent interaction with other Pods. With that situation, it's suggested to schedule these Pods running on same node. For example, Two Pods Nginx and Mysql, we need deploy them on one node if they frequently communicate. We can use podAffinity to select Pods based on their relationship. There are two scheduling type of podAffinity . requiredDuringSchedulingIgnoredDuringExecution (\u786c\u4eb2\u548c) preferredDuringSchedulingIgnoredDuringExecution (\u8f6f\u4eb2\u548c) topologyKey could be set by below types: kubernetes.io/hostname \uff03NodeName failure-domain.beta.kubernetes.io/zone \uff03Zone failure-domain.beta.kubernetes.io/region # Region We can set node Label to classify Name/Zone/Region of node, which can be used by podAffinity . Create a Pod Nginx. kubectl apply -f - < ","title":"nodeSelector"},{"location":"k8s/cka_en/foundamentals/scheduling/#nodename","text":"Be noted, nodeName has hightest priority as it's not scheduled by Scheduler . Create a Pod nginx-nodename with nodeName=cka003 . kubectl apply -f - < ","title":"nodeName"},{"location":"k8s/cka_en/foundamentals/scheduling/#affinity","text":"In Kubernetes cluster, some Pods have frequent interaction with other Pods. With that situation, it's suggested to schedule these Pods running on same node. For example, Two Pods Nginx and Mysql, we need deploy them on one node if they frequently communicate. We can use podAffinity to select Pods based on their relationship. There are two scheduling type of podAffinity . requiredDuringSchedulingIgnoredDuringExecution (\u786c\u4eb2\u548c) preferredDuringSchedulingIgnoredDuringExecution (\u8f6f\u4eb2\u548c) topologyKey could be set by below types: kubernetes.io/hostname \uff03NodeName failure-domain.beta.kubernetes.io/zone \uff03Zone failure-domain.beta.kubernetes.io/region # Region We can set node Label to classify Name/Zone/Region of node, which can be used by podAffinity . Create a Pod Nginx. kubectl apply -f - < 80/TCP 14s app=httpd NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES pod/httpd-app-6496d888c9-4nb6z 1/1 Running 0 77s 10.244.102.21 cka003 pod/httpd-app-6496d888c9-b7xht 1/1 Running 0 77s 10.244.112.19 cka002 Verify the access to Pod IPs. curl 10.244.102.21 curl 10.244.112.19 And receive below successful information.

It works!

Verify the access via ClusterIP with Port. curl 11.244.247.7:80 And receive below successful information.

It works!

Expose Service \u00b6 Create and attach to a temporary Pod nslookup and to verify DNS resolution. The option --rm means delete the Pod after exit. kubectl run -it nslookup --rm --image=busybox:1.28 After attach to the Pod, run command nslookup httpd-app . We receive the ClusterIP of Service httpd-app and full domain name. / # nslookup httpd-app Server: 11.244.0.10 Address 1: 11.244.0.10 kube-dns.kube-system.svc.cluster.local Name: httpd-app Address 1: 11.244.247.7 httpd-app.dev.svc.cluster.local We can check the IP of temporary Pod nslookup in a new terminal by executing command kubectl get pod -o wide . The Pod nslookup has Pod IP 10.244.112.20 . kubectl get pod nslookup Result NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES nslookup 1/1 Running 0 2m44s 10.244.112.20 cka002 NodePort \u00b6 Create and apply yaml file svc-nodeport.yaml to create a Service httpd-app . kubectl apply -f - < will update configuration to existing resources. Here the Service httpd-app is changed from ClusterIP to NodePort type. No change to the Deployment httpd-app . service/httpd-app configured deployment.apps/httpd-app unchanged Check the Service httpd-app via kubectl get svc . IP is the same. Type is changed to NodePort. Port numbers is changed from 80/TCP to 80:30080/TCP . NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE httpd-app NodePort 11.244.247.7 80:30080/TCP 18m Test the connection to the Service httpd-app via command curl :30080 to each node. curl :30080 curl :30080 curl :30080 We will receive below successful information.

It works!

Headless Service \u00b6 Create Headless Service web and StatefulSet web . kubectl apply -f - < web-1 1/1 Running 0 6s 10.244.112.21 cka002 Get details of the Service by command kubectl describe svc -l app=web . Name: web Namespace: dev Labels: app=web Annotations: Selector: app=web Type: ClusterIP IP Family Policy: SingleStack IP Families: IPv4 IP: None IPs: None Port: web 80/TCP TargetPort: 80/TCP Endpoints: 10.244.102.22:80,10.244.112.21:80 Session Affinity: None Events: Attach to the temporary Pod nslookup and use nslookup to verify DNS resolution. kubectl run -it nslookup --rm --image=busybox:1.28 With nslookup command for Headless Service web , we received two Pod IPs, not ClusterIP due to Headless Service. / # nslookup web Server: 11.244.0.10 Address 1: 11.244.0.10 kube-dns.kube-system.svc.cluster.local Name: web Address 1: 10.244.112.21 web-1.web.dev.svc.cluster.local Address 2: 10.244.102.22 web-0.web.dev.svc.cluster.local We can also use nslookup for web-0.web and web-1.web . Every Pod of Headless Service has own Service Name for DNS lookup. / # nslookup web-0.web Server: 11.244.0.10 Address 1: 11.244.0.10 kube-dns.kube-system.svc.cluster.local Name: web-0.web Address 1: 10.244.102.22 web-0.web.dev.svc.cluster.local / # nslookup web-1.web Server: 11.244.0.10 Address 1: 11.244.0.10 kube-dns.kube-system.svc.cluster.local Name: web-1.web Address 1: 10.244.112.21 web-1.web.dev.svc.cluster.local Clean up. kubectl delete sts web kubectl delete service httpd-app web kubectl delete deployment httpd-app Service Internal Traffic Policy \u00b6 Scenario Simulate how Service Internal Traffic Policy works. Expected result: With setting Service internalTrafficPolicy: Local , the Service only route internal traffic within the nodes that Pods are running. Backgroud: Service Internal Traffic Policy enables internal traffic restrictions to only route internal traffic to endpoints within the node the traffic originated from. The \"internal\" traffic here refers to traffic originated from Pods in the current cluster. By setting its .spec.internalTrafficPolicy to Local. This tells kube-proxy to only use node local endpoints for cluster internal traffic. For pods on nodes with no endpoints for a given Service, the Service behaves as if it has zero endpoints (for Pods on this node) even if the service does have endpoints on other nodes. Demo: Create Deployment my-nginx and Service my-nginx . kubectl apply -f - << EOF apiVersion: apps/v1 kind: Deployment metadata: name: my-nginx spec: selector: matchLabels: run: my-nginx replicas: 1 template: metadata: labels: run: my-nginx spec: containers: - name: my-nginx image: nginx ports: - containerPort: 80 --- apiVersion: v1 kind: Service metadata: name: my-nginx labels: run: my-nginx spec: ports: - port: 80 protocol: TCP selector: run: my-nginx EOF With command kubectl get pod -o wide , we know the Pod of Deployment my-nginx is running on node cka003 . NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES my-nginx-cf54cdbf7-bscf8 1/1 Running 0 9h 10.244.112.63 cka002 Let's send http request from cka001 to the Pod on cka002 . We will receive Welcome to nginx! information, which means the Pod is accessable from other nodes. curl 11.244.163.60 Let's modify the Serivce my-nginx and specify internalTrafficPolicy: Local . kubectl apply -f - << EOF apiVersion: v1 kind: Service metadata: name: my-nginx labels: run: my-nginx spec: ports: - port: 80 protocol: TCP selector: run: my-nginx internalTrafficPolicy: Local EOF Let's send http request from cka001 to the http request to the Pod again. We will receive curl: (7) Failed to connect to 11.244.163.60 port 80: Connection refused error information. curl 11.244.163.60 Let's log onto cka002 and the http request to the Pod again. We will receive Welcome to nginx! information, curl 11.244.163.60 Conclution With setting Service internalTrafficPolicy: Local , the Service only route internal traffic within the nodes that Pods are running. Scenario *Create a nginx deployment * Add port number and alias name of the nginx Pod. * Expose the deployment with internal traffic to local only. Demo: Create deployment my-nginx with port number 80 . kubectl create deployment my-nginx --image=nginx --port=80 Edit deployment. kubectl edit deployment my-nginx Add port alias name http . Refer to the link for deployment yaml template https://kubernetes.io/docs/concepts/workloads/controllers/deployment/ spec : containers : - image : nginx imagePullPolicy : Always name : nginx ports : - containerPort : 80 protocol : TCP name : http Expose the deployment with NodePort type. kubectl expose deployment my-nginx --port=80 --target-port=http --name=my-nginx-svc --type=NodePort Edit the service. Change internalTrafficPolicy from Cluster to Local . kubectl edit svc my-nginx-svc Verify the access. Note, the pod is running on node cka003 . We will see below expected results. curl :80 # succeed on node cka003. internalTrafficPolicy is effective. curl :80 # succeed on all nodes. curl : # succeed on all nodes.","title":"Service"},{"location":"k8s/cka_en/foundamentals/service/#service","text":"Scenario: Create Deployment httpd-app . Create Service httpd-app with type ClusterIP , which is default type and accessable internally. Verify the access to Pod IP and Service ClusterIP. Update Service httpd-app with type NodePort . No change to the Deployment httpd-app . Verify the access to Node. The access will route to Pod. The service is now accesable from outside. Create Headless Service web and StatefulSet web . Service Internal Traffic Policy","title":"Service"},{"location":"k8s/cka_en/foundamentals/service/#clusterip","text":"","title":"ClusterIP"},{"location":"k8s/cka_en/foundamentals/service/#create-service","text":"Create a Deployment http-app . Create a Service httpd-app link to Development http-app by Label Selector. Service type is ClusterIP , which is default type and accessable internally. kubectl apply -f - < 80/TCP 14s app=httpd NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES pod/httpd-app-6496d888c9-4nb6z 1/1 Running 0 77s 10.244.102.21 cka003 pod/httpd-app-6496d888c9-b7xht 1/1 Running 0 77s 10.244.112.19 cka002 Verify the access to Pod IPs. curl 10.244.102.21 curl 10.244.112.19 And receive below successful information.

It works!

Verify the access via ClusterIP with Port. curl 11.244.247.7:80 And receive below successful information.

It works!

","title":"Create Service"},{"location":"k8s/cka_en/foundamentals/service/#expose-service","text":"Create and attach to a temporary Pod nslookup and to verify DNS resolution. The option --rm means delete the Pod after exit. kubectl run -it nslookup --rm --image=busybox:1.28 After attach to the Pod, run command nslookup httpd-app . We receive the ClusterIP of Service httpd-app and full domain name. / # nslookup httpd-app Server: 11.244.0.10 Address 1: 11.244.0.10 kube-dns.kube-system.svc.cluster.local Name: httpd-app Address 1: 11.244.247.7 httpd-app.dev.svc.cluster.local We can check the IP of temporary Pod nslookup in a new terminal by executing command kubectl get pod -o wide . The Pod nslookup has Pod IP 10.244.112.20 . kubectl get pod nslookup Result NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES nslookup 1/1 Running 0 2m44s 10.244.112.20 cka002 ","title":"Expose Service"},{"location":"k8s/cka_en/foundamentals/service/#nodeport","text":"Create and apply yaml file svc-nodeport.yaml to create a Service httpd-app . kubectl apply -f - < will update configuration to existing resources. Here the Service httpd-app is changed from ClusterIP to NodePort type. No change to the Deployment httpd-app . service/httpd-app configured deployment.apps/httpd-app unchanged Check the Service httpd-app via kubectl get svc . IP is the same. Type is changed to NodePort. Port numbers is changed from 80/TCP to 80:30080/TCP . NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE httpd-app NodePort 11.244.247.7 80:30080/TCP 18m Test the connection to the Service httpd-app via command curl :30080 to each node. curl :30080 curl :30080 curl :30080 We will receive below successful information.

It works!

","title":"NodePort"},{"location":"k8s/cka_en/foundamentals/service/#headless-service","text":"Create Headless Service web and StatefulSet web . kubectl apply -f - < web-1 1/1 Running 0 6s 10.244.112.21 cka002 Get details of the Service by command kubectl describe svc -l app=web . Name: web Namespace: dev Labels: app=web Annotations: Selector: app=web Type: ClusterIP IP Family Policy: SingleStack IP Families: IPv4 IP: None IPs: None Port: web 80/TCP TargetPort: 80/TCP Endpoints: 10.244.102.22:80,10.244.112.21:80 Session Affinity: None Events: Attach to the temporary Pod nslookup and use nslookup to verify DNS resolution. kubectl run -it nslookup --rm --image=busybox:1.28 With nslookup command for Headless Service web , we received two Pod IPs, not ClusterIP due to Headless Service. / # nslookup web Server: 11.244.0.10 Address 1: 11.244.0.10 kube-dns.kube-system.svc.cluster.local Name: web Address 1: 10.244.112.21 web-1.web.dev.svc.cluster.local Address 2: 10.244.102.22 web-0.web.dev.svc.cluster.local We can also use nslookup for web-0.web and web-1.web . Every Pod of Headless Service has own Service Name for DNS lookup. / # nslookup web-0.web Server: 11.244.0.10 Address 1: 11.244.0.10 kube-dns.kube-system.svc.cluster.local Name: web-0.web Address 1: 10.244.102.22 web-0.web.dev.svc.cluster.local / # nslookup web-1.web Server: 11.244.0.10 Address 1: 11.244.0.10 kube-dns.kube-system.svc.cluster.local Name: web-1.web Address 1: 10.244.112.21 web-1.web.dev.svc.cluster.local Clean up. kubectl delete sts web kubectl delete service httpd-app web kubectl delete deployment httpd-app","title":"Headless Service"},{"location":"k8s/cka_en/foundamentals/service/#service-internal-traffic-policy","text":"Scenario Simulate how Service Internal Traffic Policy works. Expected result: With setting Service internalTrafficPolicy: Local , the Service only route internal traffic within the nodes that Pods are running. Backgroud: Service Internal Traffic Policy enables internal traffic restrictions to only route internal traffic to endpoints within the node the traffic originated from. The \"internal\" traffic here refers to traffic originated from Pods in the current cluster. By setting its .spec.internalTrafficPolicy to Local. This tells kube-proxy to only use node local endpoints for cluster internal traffic. For pods on nodes with no endpoints for a given Service, the Service behaves as if it has zero endpoints (for Pods on this node) even if the service does have endpoints on other nodes. Demo: Create Deployment my-nginx and Service my-nginx . kubectl apply -f - << EOF apiVersion: apps/v1 kind: Deployment metadata: name: my-nginx spec: selector: matchLabels: run: my-nginx replicas: 1 template: metadata: labels: run: my-nginx spec: containers: - name: my-nginx image: nginx ports: - containerPort: 80 --- apiVersion: v1 kind: Service metadata: name: my-nginx labels: run: my-nginx spec: ports: - port: 80 protocol: TCP selector: run: my-nginx EOF With command kubectl get pod -o wide , we know the Pod of Deployment my-nginx is running on node cka003 . NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES my-nginx-cf54cdbf7-bscf8 1/1 Running 0 9h 10.244.112.63 cka002 Let's send http request from cka001 to the Pod on cka002 . We will receive Welcome to nginx! information, which means the Pod is accessable from other nodes. curl 11.244.163.60 Let's modify the Serivce my-nginx and specify internalTrafficPolicy: Local . kubectl apply -f - << EOF apiVersion: v1 kind: Service metadata: name: my-nginx labels: run: my-nginx spec: ports: - port: 80 protocol: TCP selector: run: my-nginx internalTrafficPolicy: Local EOF Let's send http request from cka001 to the http request to the Pod again. We will receive curl: (7) Failed to connect to 11.244.163.60 port 80: Connection refused error information. curl 11.244.163.60 Let's log onto cka002 and the http request to the Pod again. We will receive Welcome to nginx! information, curl 11.244.163.60 Conclution With setting Service internalTrafficPolicy: Local , the Service only route internal traffic within the nodes that Pods are running. Scenario *Create a nginx deployment * Add port number and alias name of the nginx Pod. * Expose the deployment with internal traffic to local only. Demo: Create deployment my-nginx with port number 80 . kubectl create deployment my-nginx --image=nginx --port=80 Edit deployment. kubectl edit deployment my-nginx Add port alias name http . Refer to the link for deployment yaml template https://kubernetes.io/docs/concepts/workloads/controllers/deployment/ spec : containers : - image : nginx imagePullPolicy : Always name : nginx ports : - containerPort : 80 protocol : TCP name : http Expose the deployment with NodePort type. kubectl expose deployment my-nginx --port=80 --target-port=http --name=my-nginx-svc --type=NodePort Edit the service. Change internalTrafficPolicy from Cluster to Local . kubectl edit svc my-nginx-svc Verify the access. Note, the pod is running on node cka003 . We will see below expected results. curl :80 # succeed on node cka003. internalTrafficPolicy is effective. curl :80 # succeed on all nodes. curl : # succeed on all nodes.","title":"Service Internal Traffic Policy"},{"location":"k8s/cka_en/foundamentals/statefulset/","text":"StatefulSet \u00b6 Scenario: Create Headless Service nginx and StatefulSet web Scale out StatefulSet web Demo: Create Headless Service nginx and StatefulSet web . kubectl apply -f - << EOF --- apiVersion: v1 kind: Service metadata: name: nginx labels: app: nginx spec: ports: - port: 80 name: web clusterIP: None selector: app: nginx --- apiVersion: apps/v1 kind: StatefulSet metadata: name: web spec: serviceName: \"nginx\" replicas: 2 selector: matchLabels: app: nginx template: metadata: labels: app: nginx spec: containers: - name: nginx image: nginx ports: - containerPort: 80 name: web EOF Get details of StatefulSet Pod created just now. kubectl get pod | grep web Result NAME READY STATUS RESTARTS AGE web-0 1/1 Running 0 27s web-1 1/1 Running 0 10s Use command kubectl edit sts web to update an existing StatefulSet. ONLY these fields can be updated: replicas \u3001 image \u3001 rolling updates \u3001 labels \u3001 resource request/limit and annotations . Note: When StatefulSet Pod is dead in current node, no copies will be created in other node automatically. Scale out StatefulSet. Scale StatefulSet web to 5 Replicas. kubectl scale sts web --replicas=5 Info Partition indicates the ordinal at which the StatefulSet should be partitioned for updates. During a rolling update, all pods from ordinal Replicas-1 to Partition are updated. All pods from ordinal Partition-1 to 0 remain untouched. This is helpful in being able to do a canary based deployment. The default value is 0. Command: kubectl explain statefulsets.spec.updateStrategy.rollingUpdate.partition Clean up. kubectl delete sts web kubectl delete service nginx","title":"StatefulSet"},{"location":"k8s/cka_en/foundamentals/statefulset/#statefulset","text":"Scenario: Create Headless Service nginx and StatefulSet web Scale out StatefulSet web Demo: Create Headless Service nginx and StatefulSet web . kubectl apply -f - << EOF --- apiVersion: v1 kind: Service metadata: name: nginx labels: app: nginx spec: ports: - port: 80 name: web clusterIP: None selector: app: nginx --- apiVersion: apps/v1 kind: StatefulSet metadata: name: web spec: serviceName: \"nginx\" replicas: 2 selector: matchLabels: app: nginx template: metadata: labels: app: nginx spec: containers: - name: nginx image: nginx ports: - containerPort: 80 name: web EOF Get details of StatefulSet Pod created just now. kubectl get pod | grep web Result NAME READY STATUS RESTARTS AGE web-0 1/1 Running 0 27s web-1 1/1 Running 0 10s Use command kubectl edit sts web to update an existing StatefulSet. ONLY these fields can be updated: replicas \u3001 image \u3001 rolling updates \u3001 labels \u3001 resource request/limit and annotations . Note: When StatefulSet Pod is dead in current node, no copies will be created in other node automatically. Scale out StatefulSet. Scale StatefulSet web to 5 Replicas. kubectl scale sts web --replicas=5 Info Partition indicates the ordinal at which the StatefulSet should be partitioned for updates. During a rolling update, all pods from ordinal Replicas-1 to Partition are updated. All pods from ordinal Partition-1 to 0 remain untouched. This is helpful in being able to do a canary based deployment. The default value is 0. Command: kubectl explain statefulsets.spec.updateStrategy.rollingUpdate.partition Clean up. kubectl delete sts web kubectl delete service nginx","title":"StatefulSet"},{"location":"k8s/cka_en/foundamentals/troubleshooting/","text":"Troubleshooting \u00b6 Event \u00b6 Scenario Describe pod to get event information. Demo: Usage: kubectl describe --namespace= Get event information of a Pod Create a Tomcat Pod. kubectl run tomcat --image=tomcat Check event of above deplyment. kubectl describe pod/tomcat Get below event information. Events: Type Reason Age From Message ---- ------ ---- ---- ------- Normal Scheduled 55s default-scheduler Successfully assigned dev/tomcat to cka002 Normal Pulling 54s kubelet Pulling image \"tomcat\" Normal Pulled 21s kubelet Successfully pulled image \"tomcat\" in 33.134162692s Normal Created 19s kubelet Created container tomcat Normal Started 19s kubelet Started container tomcat Get event information for a Namespace. kubectl get events -n Get current default namespace event information. LAST SEEN TYPE REASON OBJECT MESSAGE 70s Warning FailedGetScale horizontalpodautoscaler/nginx deployments/scale.apps \"podinfo\" not found 2m16s Normal Scheduled pod/tomcat Successfully assigned dev/tomcat to cka002 2m15s Normal Pulling pod/tomcat Pulling image \"tomcat\" 102s Normal Pulled pod/tomcat Successfully pulled image \"tomcat\" in 33.134162692s 100s Normal Created pod/tomcat Created container tomcat 100s Normal Started pod/tomcat Started container tomcat Get event information for all Namespace. kubectl get events -A Logs \u00b6 Scenario Get log of pod Usage: kubectl logs -n Options: --tail : display only the most recent lines of output -f : streaming the output Get the most recent 100 lines of output. kubectl logs -f tomcat --tail 100 If it's multipPod, use -c to specify Container. kubectl logs -f tomcat --tail 100 -c tomcat Node Availability \u00b6 Check Available Node \u00b6 Scenario Check node availibility. Demo: Option 1: kubectl describe node | grep -i taint Manual check the result, here it's 2 nodes are available Taints: node-role.kubernetes.io/control-plane:NoSchedule Taints: Taints: Option 2: kubectl describe node | grep -i taint |grep -vc NoSchedule We will get same result 2 . Here -v means exclude, -c count numbers. Node NotReady \u00b6 Scenario: When we stop kubelet service on worker node cka002 , What's the status of each node? What's containers changed via command nerdctl ? What's pods status via command kubectl get pod -owide -A ? Demo: Execute command systemctl stop kubelet.service on cka002 . Execute command kubectl get node on either cka001 or cka003 , the status of cka002 is NotReady . Execute command nerdctl -n k8s.io container ls on cka002 and we can observe all containers are still up and running, including the pod my-first-pod . Execute command systemctl start kubelet.service on cka002 . Conclusion: The node status is changed to NotReady from Ready . For those DaemonSet pods, like calico \u3001 kube-proxy , are exclusively running on each node. They won't be terminated after kubelet is down. The status of pod my-first-pod keeps showing Terminating on each node because status can not be synced to other nodes via apiserver from cka002 because kubelet is down. The status of pod is marked by controller and recycled by kubelet . When we start kubelet service on cka003 , the pod my-first-pod will be termiated completely on cka002 . In addition, let's create a deployment with 3 replicas. Two are running on cka003 and one is running on cka002 . root@cka001:~# kubectl get pod -o wide -w NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES nginx-deployment-9d745469b-2xdk4 1/1 Running 0 2m8s 10.244.2.3 cka003 nginx-deployment-9d745469b-4gvmr 1/1 Running 0 2m8s 10.244.2.4 cka003 nginx-deployment-9d745469b-5j927 1/1 Running 0 2m8s 10.244.1.3 cka002 After we stop kubelet service on cka003 , the two running on cka003 are terminated and another two are created and running on cka002 automatically. Monitoring Indicators \u00b6 Scenario: Get monitoring indicators of pod Demo: Get node monitoring information kubectl top node Output: NAME CPU(cores) CPU% MEMORY(bytes) MEMORY% cka001 147m 7% 1940Mi 50% cka002 62m 3% 2151Mi 56% cka003 63m 3% 1825Mi 47% Get Pod monitoring information kubectl top pod Output: root@cka001:~# kubectl top pod NAME CPU(cores) MEMORY(bytes) busybox-with-secret 0m 0Mi mysql 2m 366Mi mysql-774db46945-sztrp 2m 349Mi mysql-nodeselector-6b7d9c875d-227t6 2m 365Mi mysql-tolerations-5c5986944b-cg9bs 2m 366Mi mysql-with-sc-pvc-7c97d875f8-dwfkc 2m 349Mi nfs-client-provisioner-699db7fd58-bccqs 2m 7Mi nginx 0m 3Mi nginx-app-1-695b7b647d-l76bh 0m 3Mi nginx-app-2-7f6bf6f4d4-lvbz8 0m 3Mi nginx-nodename 0m 3Mi nginx-with-cm 0m 3Mi pod-configmap-env 0m 3Mi pod-configmap-env-2 0m 3Mi tomcat 1m 58Mi Sort output by CPU or Memory using option --sort-by , the field can be either 'cpu' or 'memory'. kubectl top pod --sort-by=cpu kubectl top pod --sort-by=memory Output: NAME CPU(cores) MEMORY(bytes) nfs-client-provisioner-699db7fd58-bccqs 2m 7Mi mysql 2m 366Mi mysql-774db46945-sztrp 2m 349Mi mysql-nodeselector-6b7d9c875d-227t6 2m 365Mi mysql-tolerations-5c5986944b-cg9bs 2m 366Mi mysql-with-sc-pvc-7c97d875f8-dwfkc 2m 349Mi tomcat 1m 58Mi nginx 0m 3Mi nginx-app-1-695b7b647d-l76bh 0m 3Mi nginx-app-2-7f6bf6f4d4-lvbz8 0m 3Mi nginx-nodename 0m 3Mi nginx-with-cm 0m 3Mi pod-configmap-env 0m 3Mi pod-configmap-env-2 0m 3Mi busybox-with-secret 0m 0Mi Node Eviction \u00b6 Cordon/Uncordon \u00b6 Scenario Scheduling for a node Demo: Disable scheduling for a Node. kubectl cordon Example: kubectl cordon cka003 Node status: NAME STATUS ROLES AGE VERSION cka001 Ready control-plane,master 18d v1.24.0 cka002 Ready 18d v1.24.0 cka003 Ready,SchedulingDisabled 18d v1.24.0 Enable scheduling for a Node. kubectl uncordon Example: kubectl uncordon cka003 Node status: NAME STATUS ROLES AGE VERSION cka001 Ready control-plane,master 18d v1.24.0 cka002 Ready 18d v1.24.0 cka003 Ready 18d v1.24.0 Drain Node \u00b6 Scenario Drain the node cka003 Demo: Get list of Pods running. kubectl get pod -o wide We know that a Pod is running on cka003 . NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES nfs-client-provisioner-86d7fb78b6-xk8nw 1/1 Running 0 22h 10.244.102.3 cka003 Evict node cka003 . kubectl drain cka003 --ignore-daemonsets --delete-emptydir-data --force Output looks like below. node/cka003 cordoned WARNING: ignoring DaemonSet-managed Pods: kube-system/calico-node-tr22l, kube-system/kube-proxy-g76kg evicting pod dev/nfs-client-provisioner-86d7fb78b6-xk8nw evicting pod cka/cka-demo-64f88f7f46-dkxmk pod/nfs-client-provisioner-86d7fb78b6-xk8nw evicted pod/cka-demo-64f88f7f46-dkxmk evicted node/cka003 drained Check pod status again. kubectl get pod -o wide The pod is running on cka002 now. NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES nfs-client-provisioner-86d7fb78b6-k8xnl 1/1 Running 0 2m20s 10.244.112.4 cka002 Note cordon is included in drain , no need additional step to cordon node before drain node.","title":"Troubleshooting"},{"location":"k8s/cka_en/foundamentals/troubleshooting/#troubleshooting","text":"","title":"Troubleshooting"},{"location":"k8s/cka_en/foundamentals/troubleshooting/#event","text":"Scenario Describe pod to get event information. Demo: Usage: kubectl describe --namespace= Get event information of a Pod Create a Tomcat Pod. kubectl run tomcat --image=tomcat Check event of above deplyment. kubectl describe pod/tomcat Get below event information. Events: Type Reason Age From Message ---- ------ ---- ---- ------- Normal Scheduled 55s default-scheduler Successfully assigned dev/tomcat to cka002 Normal Pulling 54s kubelet Pulling image \"tomcat\" Normal Pulled 21s kubelet Successfully pulled image \"tomcat\" in 33.134162692s Normal Created 19s kubelet Created container tomcat Normal Started 19s kubelet Started container tomcat Get event information for a Namespace. kubectl get events -n Get current default namespace event information. LAST SEEN TYPE REASON OBJECT MESSAGE 70s Warning FailedGetScale horizontalpodautoscaler/nginx deployments/scale.apps \"podinfo\" not found 2m16s Normal Scheduled pod/tomcat Successfully assigned dev/tomcat to cka002 2m15s Normal Pulling pod/tomcat Pulling image \"tomcat\" 102s Normal Pulled pod/tomcat Successfully pulled image \"tomcat\" in 33.134162692s 100s Normal Created pod/tomcat Created container tomcat 100s Normal Started pod/tomcat Started container tomcat Get event information for all Namespace. kubectl get events -A","title":"Event"},{"location":"k8s/cka_en/foundamentals/troubleshooting/#logs","text":"Scenario Get log of pod Usage: kubectl logs -n Options: --tail : display only the most recent lines of output -f : streaming the output Get the most recent 100 lines of output. kubectl logs -f tomcat --tail 100 If it's multipPod, use -c to specify Container. kubectl logs -f tomcat --tail 100 -c tomcat","title":"Logs"},{"location":"k8s/cka_en/foundamentals/troubleshooting/#node-availability","text":"","title":"Node Availability"},{"location":"k8s/cka_en/foundamentals/troubleshooting/#check-available-node","text":"Scenario Check node availibility. Demo: Option 1: kubectl describe node | grep -i taint Manual check the result, here it's 2 nodes are available Taints: node-role.kubernetes.io/control-plane:NoSchedule Taints: Taints: Option 2: kubectl describe node | grep -i taint |grep -vc NoSchedule We will get same result 2 . Here -v means exclude, -c count numbers.","title":"Check Available Node"},{"location":"k8s/cka_en/foundamentals/troubleshooting/#node-notready","text":"Scenario: When we stop kubelet service on worker node cka002 , What's the status of each node? What's containers changed via command nerdctl ? What's pods status via command kubectl get pod -owide -A ? Demo: Execute command systemctl stop kubelet.service on cka002 . Execute command kubectl get node on either cka001 or cka003 , the status of cka002 is NotReady . Execute command nerdctl -n k8s.io container ls on cka002 and we can observe all containers are still up and running, including the pod my-first-pod . Execute command systemctl start kubelet.service on cka002 . Conclusion: The node status is changed to NotReady from Ready . For those DaemonSet pods, like calico \u3001 kube-proxy , are exclusively running on each node. They won't be terminated after kubelet is down. The status of pod my-first-pod keeps showing Terminating on each node because status can not be synced to other nodes via apiserver from cka002 because kubelet is down. The status of pod is marked by controller and recycled by kubelet . When we start kubelet service on cka003 , the pod my-first-pod will be termiated completely on cka002 . In addition, let's create a deployment with 3 replicas. Two are running on cka003 and one is running on cka002 . root@cka001:~# kubectl get pod -o wide -w NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES nginx-deployment-9d745469b-2xdk4 1/1 Running 0 2m8s 10.244.2.3 cka003 nginx-deployment-9d745469b-4gvmr 1/1 Running 0 2m8s 10.244.2.4 cka003 nginx-deployment-9d745469b-5j927 1/1 Running 0 2m8s 10.244.1.3 cka002 After we stop kubelet service on cka003 , the two running on cka003 are terminated and another two are created and running on cka002 automatically.","title":"Node NotReady"},{"location":"k8s/cka_en/foundamentals/troubleshooting/#monitoring-indicators","text":"Scenario: Get monitoring indicators of pod Demo: Get node monitoring information kubectl top node Output: NAME CPU(cores) CPU% MEMORY(bytes) MEMORY% cka001 147m 7% 1940Mi 50% cka002 62m 3% 2151Mi 56% cka003 63m 3% 1825Mi 47% Get Pod monitoring information kubectl top pod Output: root@cka001:~# kubectl top pod NAME CPU(cores) MEMORY(bytes) busybox-with-secret 0m 0Mi mysql 2m 366Mi mysql-774db46945-sztrp 2m 349Mi mysql-nodeselector-6b7d9c875d-227t6 2m 365Mi mysql-tolerations-5c5986944b-cg9bs 2m 366Mi mysql-with-sc-pvc-7c97d875f8-dwfkc 2m 349Mi nfs-client-provisioner-699db7fd58-bccqs 2m 7Mi nginx 0m 3Mi nginx-app-1-695b7b647d-l76bh 0m 3Mi nginx-app-2-7f6bf6f4d4-lvbz8 0m 3Mi nginx-nodename 0m 3Mi nginx-with-cm 0m 3Mi pod-configmap-env 0m 3Mi pod-configmap-env-2 0m 3Mi tomcat 1m 58Mi Sort output by CPU or Memory using option --sort-by , the field can be either 'cpu' or 'memory'. kubectl top pod --sort-by=cpu kubectl top pod --sort-by=memory Output: NAME CPU(cores) MEMORY(bytes) nfs-client-provisioner-699db7fd58-bccqs 2m 7Mi mysql 2m 366Mi mysql-774db46945-sztrp 2m 349Mi mysql-nodeselector-6b7d9c875d-227t6 2m 365Mi mysql-tolerations-5c5986944b-cg9bs 2m 366Mi mysql-with-sc-pvc-7c97d875f8-dwfkc 2m 349Mi tomcat 1m 58Mi nginx 0m 3Mi nginx-app-1-695b7b647d-l76bh 0m 3Mi nginx-app-2-7f6bf6f4d4-lvbz8 0m 3Mi nginx-nodename 0m 3Mi nginx-with-cm 0m 3Mi pod-configmap-env 0m 3Mi pod-configmap-env-2 0m 3Mi busybox-with-secret 0m 0Mi","title":"Monitoring Indicators"},{"location":"k8s/cka_en/foundamentals/troubleshooting/#node-eviction","text":"","title":"Node Eviction"},{"location":"k8s/cka_en/foundamentals/troubleshooting/#cordonuncordon","text":"Scenario Scheduling for a node Demo: Disable scheduling for a Node. kubectl cordon Example: kubectl cordon cka003 Node status: NAME STATUS ROLES AGE VERSION cka001 Ready control-plane,master 18d v1.24.0 cka002 Ready 18d v1.24.0 cka003 Ready,SchedulingDisabled 18d v1.24.0 Enable scheduling for a Node. kubectl uncordon Example: kubectl uncordon cka003 Node status: NAME STATUS ROLES AGE VERSION cka001 Ready control-plane,master 18d v1.24.0 cka002 Ready 18d v1.24.0 cka003 Ready 18d v1.24.0","title":"Cordon/Uncordon"},{"location":"k8s/cka_en/foundamentals/troubleshooting/#drain-node","text":"Scenario Drain the node cka003 Demo: Get list of Pods running. kubectl get pod -o wide We know that a Pod is running on cka003 . NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES nfs-client-provisioner-86d7fb78b6-xk8nw 1/1 Running 0 22h 10.244.102.3 cka003 Evict node cka003 . kubectl drain cka003 --ignore-daemonsets --delete-emptydir-data --force Output looks like below. node/cka003 cordoned WARNING: ignoring DaemonSet-managed Pods: kube-system/calico-node-tr22l, kube-system/kube-proxy-g76kg evicting pod dev/nfs-client-provisioner-86d7fb78b6-xk8nw evicting pod cka/cka-demo-64f88f7f46-dkxmk pod/nfs-client-provisioner-86d7fb78b6-xk8nw evicted pod/cka-demo-64f88f7f46-dkxmk evicted node/cka003 drained Check pod status again. kubectl get pod -o wide The pod is running on cka002 now. NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES nfs-client-provisioner-86d7fb78b6-k8xnl 1/1 Running 0 2m20s 10.244.112.4 cka002 Note cordon is included in drain , no need additional step to cordon node before drain node.","title":"Drain Node"},{"location":"k8s/cka_en/installation/aliyun-ubuntu/","text":"Installation on Aliyun Ubuntu \u00b6 Preparation \u00b6 Register Aliyun account via Alibaba Cloud home console . Request three Elastic Computer Service(ECS) instances with below sizing: System: 2vCPU+4GiB OS: Ubuntu 20.04 x86_64 Instance Type: ecs.sn1.medium Instance Name: cka001, cka002, cka003 Network: both public IPs and private IPs Maximum Bandwidth: 100Mbps (Peak Value) Cloud disk: 40GiB Billing Method: Preemptible instance (spot price) Open a local terminal, log onto remote ECS cka001 using the key pair (e.g., aliyun-root ) from Aliyun cloud. ssh -i aliyun-root root@cka001 Create a common user (e.g., james ), and set primary group as sudo and other group as root . adduser james usermod -g sudo james usermod -a -G root james Back to the local terminal, generate key for common user james by below command. # Windows ssh-keygen.exe # Linux ssh-keygen Two files will be created, e.g., aliyun-james and aliyun-james.pub Upload the public key aliyun-james.pub to remote cka001 using sftp command. sftp -i aliyun-root root@cka001 put aliyun-james.pub Log onto remote ECS cka001 using root account again. Move the key aliyun-james.pub to /home/james/.ssh/ . Rename file aliyun-james.pub to authorized_keys . Change ower of file authorized_keys to james . Change default group of file authorized_keys to sudo . mkdir /home/james/.ssh/ mv aliyun-james.pub /home/james/.ssh/authorized_keys chown james.sudo /home/james/.ssh/authorized_keys chmod 600 /home/james/.ssh/authorized_keys Check file /etc/ssh/sshd_config , make sure password authentication is disabled PasswordAuthentication no cat /etc/ssh/sshd_config Back to the local terminal, use james to log onto remote cka001 . ssh -i aliyun-james james@cka001 Upload the public key aliyun-james.pub to remote cka002 and cka003 using sftp command and do the same set up on cka002 and cka003 in order to enable user james to log onto cka002 and cka003 . Till now, user james can log onto cka001 , cka002 and cka003 using key aliyun-james . All demo below will be done by user james . Initialize VMs \u00b6 Configure /etc/hosts file \u00b6 Add private IPs in the /etc/hosts file in all VMs. vi /etc/hosts Disable firewall \u00b6 Disable firewall by command ufw disable in all VMs. Disable swap on Ubuntu. sudo ufw disable Check status of swap on Ubuntu. sudo ufw status verbose Turn off swap \u00b6 Turn off swap in all VMs. sudo swapoff -a Set timezone and locale \u00b6 Set timezone and local for all VMs. This step was already done during Aliyun ECS installation. ln -sf /usr/share/zoneinfo/Asia/Shanghai /etc/localtime sudo echo 'LANG=\"en_US.UTF-8\"' >> /etc/profile source /etc/profile Something like this: ll /etc/localtime lrwxrwxrwx 1 root root 33 Jul 5 14 :51 /etc/localtime -> /usr/share/zoneinfo/Asia/Shanghai Kernel setting \u00b6 Perform below kernel setting in all VMs. Create file /etc/modules-load.d/containerd.conf to set up containerd configure file. It's to load two modules overlay and br_netfilter . Service containerd depends on overlay filesystem. Sometimes referred to as union-filesystems. An overlay-filesystem tries to present a filesystem which is the result over overlaying one filesystem on top of the other. The br_netfilter module is required to enable transparent masquerading and to facilitate Virtual Extensible LAN (VxLAN) traffic for communication between Kubernetes pods across the cluster. cat < /etc/apt/sources.list << EOF deb http://mirrors.cloud.aliyuncs.com/ubuntu/ focal main restricted deb-src http://mirrors.cloud.aliyuncs.com/ubuntu/ focal main restricted deb http://mirrors.cloud.aliyuncs.com/ubuntu/ focal-updates main restricted deb-src http://mirrors.cloud.aliyuncs.com/ubuntu/ focal-updates main restricted deb http://mirrors.cloud.aliyuncs.com/ubuntu/ focal universe deb-src http://mirrors.cloud.aliyuncs.com/ubuntu/ focal universe deb http://mirrors.cloud.aliyuncs.com/ubuntu/ focal-updates universe deb-src http://mirrors.cloud.aliyuncs.com/ubuntu/ focal-updates universe deb http://mirrors.cloud.aliyuncs.com/ubuntu/ focal multiverse deb-src http://mirrors.cloud.aliyuncs.com/ubuntu/ focal multiverse deb http://mirrors.cloud.aliyuncs.com/ubuntu/ focal-updates multiverse deb-src http://mirrors.cloud.aliyuncs.com/ubuntu/ focal-updates multiverse deb http://mirrors.cloud.aliyuncs.com/ubuntu/ focal-backports main restricted universe multiverse deb-src http://mirrors.cloud.aliyuncs.com/ubuntu/ focal-backports main restricted universe multivers deb http://mirrors.cloud.aliyuncs.com/ubuntu focal-security main restricted deb-src http://mirrors.cloud.aliyuncs.com/ubuntu focal-security main restricted deb http://mirrors.cloud.aliyuncs.com/ubuntu focal-security universe deb-src http://mirrors.cloud.aliyuncs.com/ubuntu focal-security universe # deb http://mirrors.cloud.aliyuncs.com/ubuntu focal-security multiverse # deb-src http://mirrors.cloud.aliyuncs.com/ubuntu focal-security multiverse EOF Install Containered. sudo apt-get update && sudo apt-get install -y containerd Configure Containerd. Modify file /etc/containerd/config.toml . sudo mkdir -p /etc/containerd containerd config default | sudo tee /etc/containerd/config.toml sudo vi /etc/containerd/config.toml Update sandbox_image with new value \"registry.aliyuncs.com/google_containers/pause:3.6\" . Update SystemdCgroup with new value true . [plugins] [plugins.\"io.containerd.gc.v1.scheduler\"] [plugins.\"io.containerd.grpc.v1.cri\"] sandbox_image = \"registry.aliyuncs.com/google_containers/pause:3.6\" [plugins.\"io.containerd.grpc.v1.cri\".cni] [plugins.\"io.containerd.grpc.v1.cri\".containerd] [plugins.\"io.containerd.grpc.v1.cri\".containerd.default_runtime] [plugins.\"io.containerd.grpc.v1.cri\".containerd.default_runtime.options] [plugins.\"io.containerd.grpc.v1.cri\".containerd.runtimes] [plugins.\"io.containerd.grpc.v1.cri\".containerd.runtimes.runc] [plugins.\"io.containerd.grpc.v1.cri\".containerd.runtimes.runc.options] SystemdCgroup = true Restart Containerd service. sudo systemctl restart containerd sudo systemctl status containerd Install nerdctl \u00b6 Install nerdctl sevice fro all VMs. The goal of nerdctl is to facilitate experimenting the cutting-edge features of containerd that are not present in Docker. Get the release from the link https://github.com/containerd/nerdctl/releases . wget https://github.com/containerd/nerdctl/releases/download/v0.22.0/nerdctl-0.22.0-linux-amd64.tar.gz tar -zxvf nerdctl-0.22.0-linux-amd64.tar.gz sudo cp nerdctl /usr/bin/ sudo cp containerd-rootless* /usr/bin/ Verify nerdctl. nerdctl --help To list local Kubernetes containers. nerdctl -n k8s.io ps Install kubeadm \u00b6 Update apt-transport-https , ca-certificates , and curl . sudo apt-get update && sudo apt-get install -y apt-transport-https ca-certificates curl Install gpg certificate. sudo curl -fsSLo /usr/share/keyrings/kubernetes-archive-keyring.gpg https://mirrors.aliyun.com/kubernetes/apt/doc/apt-key.gpg Add Kubernetes repo. Just choose one of below command and execute. echo \"deb [signed-by=/usr/share/keyrings/kubernetes-archive-keyring.gpg] https://mirrors.aliyun.com/kubernetes/apt/ \\ kubernetes-xenial main\" | sudo tee /etc/apt/sources.list.d/kubernetes.list Update and install dependencied packages. sudo apt-get update sudo apt-get install ebtables sudo apt-get install libxtables12 sudo apt-get upgrade iptables Check available versions of kubeadm. apt policy kubeadm Install 1.24.0-00 version of kubeadm and will upgrade to 1.24.2 later. sudo apt-get -y install kubelet = 1 .24.0-00 kubeadm = 1 .24.0-00 kubectl = 1 .24.0-00 --allow-downgrades Setup Master Node \u00b6 kubeadm init \u00b6 Set up Control Plane on VM playing master node. Check kubeadm default parameters for initialization. kubeadm config print init-defaults Reuslt: apiVersion : kubeadm.k8s.io/v1beta3 bootstrapTokens : - groups : - system:bootstrappers:kubeadm:default-node-token token : abcdef.0123456789abcdef ttl : 24h0m0s usages : - signing - authentication kind : InitConfiguration localAPIEndpoint : advertiseAddress : 1.2.3.4 bindPort : 6443 nodeRegistration : criSocket : unix:///var/run/containerd/containerd.sock imagePullPolicy : IfNotPresent name : node taints : null --- apiServer : timeoutForControlPlane : 4m0s apiVersion : kubeadm.k8s.io/v1beta3 certificatesDir : /etc/kubernetes/pki clusterName : kubernetes controllerManager : {} dns : {} etcd : local : dataDir : /var/lib/etcd imageRepository : k8s.gcr.io kind : ClusterConfiguration kubernetesVersion : 1.24.0 networking : dnsDomain : cluster.local serviceSubnet : 10.96.0.0/12 scheduler : {} Dry rune and run. Save the output, which will be used later on work nodes. With kubeadm init to initiate cluster, we need understand below three options about network. --pod-network-cidr : Specify range of IP addresses for the pod network. If set, the control plane will automatically allocate CIDRs for every node. Be noted that 10.244.0.0/16 is default range of flannel. If it's changed here, please do change the same when deploy Flannel . --apiserver-bind-port : Port for the API Server to bind to. (default 6443) --service-cidr : Use alternative range of IP address for service VIPs. (default \"10.96.0.0/12\") Note: service VIPs (a.k.a. Cluster IP), specified by option --service-cidr . podCIDR (a.k.a. endpoint IP)\uff0cspecified by option --pod-network-cidr . There are 4 distinct networking problems to address: Highly-coupled container-to-container communications: this is solved by Pods (podCIDR) and localhost communications. Pod-to-Pod communications: a.k.a. container-to-container. Example with Flannel, the flow is: Pod \u2192 veth pair \u2192 cni0 \u2192 flannel.1 \u2192 host eth0 \u2192 host eth0 \u2192 flannel.1 \u2192 cni0 \u2192 veth pair \u2192 Pod. Pod-to-Service communications: Flow: Pod \u2192 Kernel \u2192 Servive iptables \u2192 service \u2192 Pod iptables \u2192 Pod External-to-Service communications: LoadBalancer: SLB \u2192 NodePort \u2192 Service \u2192 Pod kube-proxy is responsible for iptables, not traffic. sudo kubeadm init \\ --dry-run \\ --pod-network-cidr = 10 .244.0.0/16 \\ --service-cidr 11 .244.0.0/16 \\ --image-repository = registry.aliyuncs.com/google_containers \\ --kubernetes-version = v1.24.0 sudo kubeadm init \\ --pod-network-cidr = 10 .244.0.0/16 \\ --service-cidr 11 .244.0.0/16 \\ --image-repository = registry.aliyuncs.com/google_containers \\ --kubernetes-version = v1.24.0 sudo kubeadm init \\ --pod-network-cidr = 10 .244.0.0/16 \\ --service-cidr 11 .244.0.0/16 \\ --kubernetes-version = v1.24.0 kubeconfig file \u00b6 Set kubeconfig file for current user (here it's james ). mkdir -p $HOME /.kube sudo cp -i /etc/kubernetes/admin.conf $HOME /.kube/config sudo chown $( id -u ) : $( id -g ) $HOME /.kube/config Kubernetes provides a command line tool kubectl for communicating with a Kubernetes cluster's control plane, using the Kubernetes API. kubectl controls the Kubernetes cluster manager . For configuration, kubectl looks for a file named config in the $HOME/.kube directory, which is a copy of file /etc/kubernetes/admin.conf generated by kubeadm init . We can specify other kubeconfig files by setting the KUBECONFIG environment variable or by setting the --kubeconfig flag . If the KUBECONFIG environment variable doesn't exist, kubectl uses the default kubeconfig file, $HOME/.kube/config . A context element in a kubeconfig file is used to group access parameters under a convenient name. Each context has three parameters: cluster, namespace, and user. By default, the kubectl command-line tool uses parameters from the current context to communicate with the cluster. A sample of .kube/config . apiVersion : v1 clusters : - cluster : certificate-authority-data : server : https://:6443 name : contexts : - context : cluster : namespace : user : name : @ current-context : kind : Config preferences : {} users : - name : user : client-certificate-data : client-key-data : To get the current context: kubectl config get-contexts Result CURRENT NAME CLUSTER AUTHINFO NAMESPACE * kubernetes-admin@kubernetes kubernetes kubernetes-admin Setup Work Nodes \u00b6 Perform on all VMs playing work nodes. # kubeadm join :6443 --token --discovery-token-ca-cert-hash Use kubeadm token to generate the join token and hash value. kubeadm token create --print-join-command Execute the command generated above on each node that we want to join the cluster as Worker node. Verify status on master node. All nodes' status is NotReady . Leave it at the moment and continue to install network plugin. kubectl get node -o wide Install Calico or Flannel \u00b6 Choose Calico or Flannel on control plane node. For NetworkPolicy purpose, choose Calico. Install Flannel \u00b6 Flannel is a simple and easy way to configure a layer 3 network fabric designed for Kubernetes. Deploy Flannel. In the kube-flannel.yml we can get the default network setting of Flannel, which is same with --pod-network-cidr=10.244.0.0/16 we defined before when we initiated kubeadm . net-conf.json : | { \"Network\": \"10.244.0.0/16\", \"Backend\": { \"Type\": \"vxlan\" } } Create Flannel apply -f https://raw.githubusercontent.com/coreos/flannel/master/Documentation/kube-flannel.yml Result Warning: policy/v1beta1 PodSecurityPolicy is deprecated in v1.21+, unavailable in v1.25+ podsecuritypolicy.policy/psp.flannel.unprivileged created clusterrole.rbac.authorization.k8s.io/flannel created clusterrolebinding.rbac.authorization.k8s.io/flannel created serviceaccount/flannel created configmap/kube-flannel-cfg created daemonset.apps/kube-flannel-ds created Install Calico \u00b6 Here is guidance of End-to-end Calico installation . Detail practice demo, can be found in section \"Install Calico\" of \"A1.Discussion\" below. Install Calico curl https://docs.projectcalico.org/manifests/calico.yaml -O kubectl apply -f calico.yaml Result configmap/calico-config created customresourcedefinition.apiextensions.k8s.io/bgpconfigurations.crd.projectcalico.org created customresourcedefinition.apiextensions.k8s.io/bgppeers.crd.projectcalico.org created customresourcedefinition.apiextensions.k8s.io/blockaffinities.crd.projectcalico.org created customresourcedefinition.apiextensions.k8s.io/caliconodestatuses.crd.projectcalico.org created customresourcedefinition.apiextensions.k8s.io/clusterinformations.crd.projectcalico.org created customresourcedefinition.apiextensions.k8s.io/felixconfigurations.crd.projectcalico.org created customresourcedefinition.apiextensions.k8s.io/globalnetworkpolicies.crd.projectcalico.org created customresourcedefinition.apiextensions.k8s.io/globalnetworksets.crd.projectcalico.org created customresourcedefinition.apiextensions.k8s.io/hostendpoints.crd.projectcalico.org created customresourcedefinition.apiextensions.k8s.io/ipamblocks.crd.projectcalico.org created customresourcedefinition.apiextensions.k8s.io/ipamconfigs.crd.projectcalico.org created customresourcedefinition.apiextensions.k8s.io/ipamhandles.crd.projectcalico.org created customresourcedefinition.apiextensions.k8s.io/ippools.crd.projectcalico.org created customresourcedefinition.apiextensions.k8s.io/ipreservations.crd.projectcalico.org created customresourcedefinition.apiextensions.k8s.io/kubecontrollersconfigurations.crd.projectcalico.org created customresourcedefinition.apiextensions.k8s.io/networkpolicies.crd.projectcalico.org created customresourcedefinition.apiextensions.k8s.io/networksets.crd.projectcalico.org created clusterrole.rbac.authorization.k8s.io/calico-kube-controllers created clusterrolebinding.rbac.authorization.k8s.io/calico-kube-controllers created clusterrole.rbac.authorization.k8s.io/calico-node created clusterrolebinding.rbac.authorization.k8s.io/calico-node created daemonset.apps/calico-node created serviceaccount/calico-node created deployment.apps/calico-kube-controllers created serviceaccount/calico-kube-controllers created poddisruptionbudget.policy/calico-kube-controllers created Verify status of Calico. kubectl get pod -n kube-system | grep calico Result calico-kube-controllers-555bc4b957-l8bn2 0/1 Pending 0 28s calico-node-255pc 0/1 Init:1/3 0 29s calico-node-7tmnb 0/1 Init:1/3 0 29s calico-node-w8nvl 0/1 Init:1/3 0 29s Verify network status. sudo nerdctl network ls Result NETWORK ID NAME FILE k8s-pod-network /etc/cni/net.d/10-calico.conflist 0 bridge /etc/cni/net.d/nerdctl-bridge.conflist host none Check Cluster Status \u00b6 Perform kubectl cluster-info command on master node we will get below information. Kubernetes control plane is running at https://:6443 CoreDNS is running at https://:6443/api/v1/namespaces/kube-system/services/kube-dns:dns/proxy kubectl cluster-info Get nodes status. kubectl get nodes -owide All nodes are up with normal status. OS Image: Ubuntu 20.04.4 LTS Kernel Version: 5.4.0-122-generic Container Runtime: containerd://1.5.9 NAME STATUS ROLES AGE VERSION cka001 Ready control-plane 13m v1.24.0 cka002 Ready 8m35s v1.24.0 cka003 Ready 8m26s v1.24.0 Get pods status kubectl get pod -A Result: NAMESPACE NAME READY STATUS RESTARTS AGE kube-system calico-kube-controllers-555bc4b957-l8bn2 1/1 Running 0 7m18s kube-system calico-node-255pc 1/1 Running 0 7m19s kube-system calico-node-7tmnb 1/1 Running 0 7m19s kube-system calico-node-w8nvl 1/1 Running 0 7m19s kube-system coredns-74586cf9b6-4jwmk 1/1 Running 0 15m kube-system coredns-74586cf9b6-c5mll 1/1 Running 0 15m kube-system etcd-cka001 1/1 Running 0 15m kube-system kube-apiserver-cka001 1/1 Running 0 15m kube-system kube-controller-manager-cka001 1/1 Running 0 15m kube-system kube-proxy-dmj2t 1/1 Running 0 15m kube-system kube-proxy-n77zw 1/1 Running 0 11m kube-system kube-proxy-qs6rf 1/1 Running 0 11m kube-system kube-scheduler-cka001 1/1 Running 0 15m Reset cluster \u00b6 CAUTION: below steps will destroy current cluster. Delete all nodes in the cluster. kubeadm reset Output: [reset] Reading configuration from the cluster... [reset] FYI: You can look at this config file with 'kubectl -n kube-system get cm kubeadm-config -o yaml' W0717 08:15:17.411992 3913615 preflight.go:55] [reset] WARNING: Changes made to this host by 'kubeadm init' or 'kubeadm join' will be reverted. [reset] Are you sure you want to proceed? [y/N]: y [preflight] Running pre-flight checks [reset] Stopping the kubelet service [reset] Unmounting mounted directories in \"/var/lib/kubelet\" [reset] Deleting contents of directories: [/etc/kubernetes/manifests /etc/kubernetes/pki] [reset] Deleting files: [/etc/kubernetes/admin.conf /etc/kubernetes/kubelet.conf /etc/kubernetes/bootstrap-kubelet.conf /etc/kubernetes/controller-manager.conf /etc/kubernetes/scheduler.conf] [reset] Deleting contents of stateful directories: [/var/lib/etcd /var/lib/kubelet /var/lib/dockershim /var/run/kubernetes /var/lib/cni] The reset process does not clean CNI configuration. To do so, you must remove /etc/cni/net.d The reset process does not reset or clean up iptables rules or IPVS tables. If you wish to reset iptables, you must do so manually by using the \"iptables\" command. If your cluster was setup to utilize IPVS, run ipvsadm --clear (or similar) to reset your system's IPVS tables. The reset process does not clean your kubeconfig files and you must remove them manually. Please, check the contents of the $HOME/.kube/config file. Clean up network setting rm -rf /var/run/flannel /opt/cni /etc/cni /var/lib/cni Clean up rule of iptables . iptables -F && iptables -t nat -F && iptables -t mangle -F && iptables -X Clean up rule of IPVS if using IPVS . ipvsadm --clear Troubleshooting \u00b6 Issue 1 \u00b6 The connection to the server :6443 was refused - did you specify the right host or port? Try : Reference Check if the kubeconfig file is update to udpate and exists in right place. Check environment setting. env | grep -i kub Check container status. sudo systemctl status containerd.service Check kubelet service. sudo systemctl status kubelet.service Check port listening status. netstat -pnlt | grep 6443 Check firewall status. sudo systemctl status firewalld.service Check log. journalctl -xeu kubelet Issue 2 \u00b6 \"Container runtime network not ready\" networkReady=\"NetworkReady=false reason:NetworkPluginNotReady message:Network plugin returns error: cni plugin not initialized\" Try : Restart Containerd service. sudo systemctl restart containerd sudo systemctl status containerd Post Installation \u00b6 Bash Autocomplete \u00b6 On each node. Set kubectl auto-completion following the guideline . apt install -y bash-completion source /usr/share/bash-completion/bash_completion source < ( kubectl completion bash ) echo \"source <(kubectl completion bash)\" >> ~/.bashrc Alias \u00b6 If we set an alias for kubectl, we can extend shell completion to work with that alias: echo 'alias k=kubectl' >>~/.bashrc echo 'complete -o default -F __start_kubectl k' >>~/.bashrc Update Default Context \u00b6 Get current context. kubectl config get-contexts In below result, we know: Contenxt name is kubernetes-admin@kubernetes . Cluster name is kubernetes . User is kubernetes-admin . No namespace explicitly defined. CURRENT NAME CLUSTER AUTHINFO NAMESPACE * kubernetes-admin@kubernetes kubernetes kubernetes-admin To set a context with new update, e.g, update default namespace, etc.. # Usage: kubectl config set-context --cluster = --namespace = --user = # Set default namespace kubectl config set-context kubernetes-admin@kubernetes --cluster = kubernetes --namespace = default --user = kubernetes-admin To switch to a new context. kubectl config use-context kubectl config use-context kubernetes-admin@kubernetes Reference of kubectl and commandline .","title":"Installation on Aliyun ECS"},{"location":"k8s/cka_en/installation/aliyun-ubuntu/#installation-on-aliyun-ubuntu","text":"","title":"Installation on Aliyun Ubuntu"},{"location":"k8s/cka_en/installation/aliyun-ubuntu/#preparation","text":"Register Aliyun account via Alibaba Cloud home console . Request three Elastic Computer Service(ECS) instances with below sizing: System: 2vCPU+4GiB OS: Ubuntu 20.04 x86_64 Instance Type: ecs.sn1.medium Instance Name: cka001, cka002, cka003 Network: both public IPs and private IPs Maximum Bandwidth: 100Mbps (Peak Value) Cloud disk: 40GiB Billing Method: Preemptible instance (spot price) Open a local terminal, log onto remote ECS cka001 using the key pair (e.g., aliyun-root ) from Aliyun cloud. ssh -i aliyun-root root@cka001 Create a common user (e.g., james ), and set primary group as sudo and other group as root . adduser james usermod -g sudo james usermod -a -G root james Back to the local terminal, generate key for common user james by below command. # Windows ssh-keygen.exe # Linux ssh-keygen Two files will be created, e.g., aliyun-james and aliyun-james.pub Upload the public key aliyun-james.pub to remote cka001 using sftp command. sftp -i aliyun-root root@cka001 put aliyun-james.pub Log onto remote ECS cka001 using root account again. Move the key aliyun-james.pub to /home/james/.ssh/ . Rename file aliyun-james.pub to authorized_keys . Change ower of file authorized_keys to james . Change default group of file authorized_keys to sudo . mkdir /home/james/.ssh/ mv aliyun-james.pub /home/james/.ssh/authorized_keys chown james.sudo /home/james/.ssh/authorized_keys chmod 600 /home/james/.ssh/authorized_keys Check file /etc/ssh/sshd_config , make sure password authentication is disabled PasswordAuthentication no cat /etc/ssh/sshd_config Back to the local terminal, use james to log onto remote cka001 . ssh -i aliyun-james james@cka001 Upload the public key aliyun-james.pub to remote cka002 and cka003 using sftp command and do the same set up on cka002 and cka003 in order to enable user james to log onto cka002 and cka003 . Till now, user james can log onto cka001 , cka002 and cka003 using key aliyun-james . All demo below will be done by user james .","title":"Preparation"},{"location":"k8s/cka_en/installation/aliyun-ubuntu/#initialize-vms","text":"","title":"Initialize VMs"},{"location":"k8s/cka_en/installation/aliyun-ubuntu/#configure-etchosts-file","text":"Add private IPs in the /etc/hosts file in all VMs. vi /etc/hosts","title":"Configure /etc/hosts file"},{"location":"k8s/cka_en/installation/aliyun-ubuntu/#disable-firewall","text":"Disable firewall by command ufw disable in all VMs. Disable swap on Ubuntu. sudo ufw disable Check status of swap on Ubuntu. sudo ufw status verbose","title":"Disable firewall"},{"location":"k8s/cka_en/installation/aliyun-ubuntu/#turn-off-swap","text":"Turn off swap in all VMs. sudo swapoff -a","title":"Turn off swap"},{"location":"k8s/cka_en/installation/aliyun-ubuntu/#set-timezone-and-locale","text":"Set timezone and local for all VMs. This step was already done during Aliyun ECS installation. ln -sf /usr/share/zoneinfo/Asia/Shanghai /etc/localtime sudo echo 'LANG=\"en_US.UTF-8\"' >> /etc/profile source /etc/profile Something like this: ll /etc/localtime lrwxrwxrwx 1 root root 33 Jul 5 14 :51 /etc/localtime -> /usr/share/zoneinfo/Asia/Shanghai","title":"Set timezone and locale"},{"location":"k8s/cka_en/installation/aliyun-ubuntu/#kernel-setting","text":"Perform below kernel setting in all VMs. Create file /etc/modules-load.d/containerd.conf to set up containerd configure file. It's to load two modules overlay and br_netfilter . Service containerd depends on overlay filesystem. Sometimes referred to as union-filesystems. An overlay-filesystem tries to present a filesystem which is the result over overlaying one filesystem on top of the other. The br_netfilter module is required to enable transparent masquerading and to facilitate Virtual Extensible LAN (VxLAN) traffic for communication between Kubernetes pods across the cluster. cat < /etc/apt/sources.list << EOF deb http://mirrors.cloud.aliyuncs.com/ubuntu/ focal main restricted deb-src http://mirrors.cloud.aliyuncs.com/ubuntu/ focal main restricted deb http://mirrors.cloud.aliyuncs.com/ubuntu/ focal-updates main restricted deb-src http://mirrors.cloud.aliyuncs.com/ubuntu/ focal-updates main restricted deb http://mirrors.cloud.aliyuncs.com/ubuntu/ focal universe deb-src http://mirrors.cloud.aliyuncs.com/ubuntu/ focal universe deb http://mirrors.cloud.aliyuncs.com/ubuntu/ focal-updates universe deb-src http://mirrors.cloud.aliyuncs.com/ubuntu/ focal-updates universe deb http://mirrors.cloud.aliyuncs.com/ubuntu/ focal multiverse deb-src http://mirrors.cloud.aliyuncs.com/ubuntu/ focal multiverse deb http://mirrors.cloud.aliyuncs.com/ubuntu/ focal-updates multiverse deb-src http://mirrors.cloud.aliyuncs.com/ubuntu/ focal-updates multiverse deb http://mirrors.cloud.aliyuncs.com/ubuntu/ focal-backports main restricted universe multiverse deb-src http://mirrors.cloud.aliyuncs.com/ubuntu/ focal-backports main restricted universe multivers deb http://mirrors.cloud.aliyuncs.com/ubuntu focal-security main restricted deb-src http://mirrors.cloud.aliyuncs.com/ubuntu focal-security main restricted deb http://mirrors.cloud.aliyuncs.com/ubuntu focal-security universe deb-src http://mirrors.cloud.aliyuncs.com/ubuntu focal-security universe # deb http://mirrors.cloud.aliyuncs.com/ubuntu focal-security multiverse # deb-src http://mirrors.cloud.aliyuncs.com/ubuntu focal-security multiverse EOF Install Containered. sudo apt-get update && sudo apt-get install -y containerd Configure Containerd. Modify file /etc/containerd/config.toml . sudo mkdir -p /etc/containerd containerd config default | sudo tee /etc/containerd/config.toml sudo vi /etc/containerd/config.toml Update sandbox_image with new value \"registry.aliyuncs.com/google_containers/pause:3.6\" . Update SystemdCgroup with new value true . [plugins] [plugins.\"io.containerd.gc.v1.scheduler\"] [plugins.\"io.containerd.grpc.v1.cri\"] sandbox_image = \"registry.aliyuncs.com/google_containers/pause:3.6\" [plugins.\"io.containerd.grpc.v1.cri\".cni] [plugins.\"io.containerd.grpc.v1.cri\".containerd] [plugins.\"io.containerd.grpc.v1.cri\".containerd.default_runtime] [plugins.\"io.containerd.grpc.v1.cri\".containerd.default_runtime.options] [plugins.\"io.containerd.grpc.v1.cri\".containerd.runtimes] [plugins.\"io.containerd.grpc.v1.cri\".containerd.runtimes.runc] [plugins.\"io.containerd.grpc.v1.cri\".containerd.runtimes.runc.options] SystemdCgroup = true Restart Containerd service. sudo systemctl restart containerd sudo systemctl status containerd","title":"Install Containerd"},{"location":"k8s/cka_en/installation/aliyun-ubuntu/#install-nerdctl","text":"Install nerdctl sevice fro all VMs. The goal of nerdctl is to facilitate experimenting the cutting-edge features of containerd that are not present in Docker. Get the release from the link https://github.com/containerd/nerdctl/releases . wget https://github.com/containerd/nerdctl/releases/download/v0.22.0/nerdctl-0.22.0-linux-amd64.tar.gz tar -zxvf nerdctl-0.22.0-linux-amd64.tar.gz sudo cp nerdctl /usr/bin/ sudo cp containerd-rootless* /usr/bin/ Verify nerdctl. nerdctl --help To list local Kubernetes containers. nerdctl -n k8s.io ps","title":"Install nerdctl"},{"location":"k8s/cka_en/installation/aliyun-ubuntu/#install-kubeadm","text":"Update apt-transport-https , ca-certificates , and curl . sudo apt-get update && sudo apt-get install -y apt-transport-https ca-certificates curl Install gpg certificate. sudo curl -fsSLo /usr/share/keyrings/kubernetes-archive-keyring.gpg https://mirrors.aliyun.com/kubernetes/apt/doc/apt-key.gpg Add Kubernetes repo. Just choose one of below command and execute. echo \"deb [signed-by=/usr/share/keyrings/kubernetes-archive-keyring.gpg] https://mirrors.aliyun.com/kubernetes/apt/ \\ kubernetes-xenial main\" | sudo tee /etc/apt/sources.list.d/kubernetes.list Update and install dependencied packages. sudo apt-get update sudo apt-get install ebtables sudo apt-get install libxtables12 sudo apt-get upgrade iptables Check available versions of kubeadm. apt policy kubeadm Install 1.24.0-00 version of kubeadm and will upgrade to 1.24.2 later. sudo apt-get -y install kubelet = 1 .24.0-00 kubeadm = 1 .24.0-00 kubectl = 1 .24.0-00 --allow-downgrades","title":"Install kubeadm"},{"location":"k8s/cka_en/installation/aliyun-ubuntu/#setup-master-node","text":"","title":"Setup Master Node"},{"location":"k8s/cka_en/installation/aliyun-ubuntu/#kubeadm-init","text":"Set up Control Plane on VM playing master node. Check kubeadm default parameters for initialization. kubeadm config print init-defaults Reuslt: apiVersion : kubeadm.k8s.io/v1beta3 bootstrapTokens : - groups : - system:bootstrappers:kubeadm:default-node-token token : abcdef.0123456789abcdef ttl : 24h0m0s usages : - signing - authentication kind : InitConfiguration localAPIEndpoint : advertiseAddress : 1.2.3.4 bindPort : 6443 nodeRegistration : criSocket : unix:///var/run/containerd/containerd.sock imagePullPolicy : IfNotPresent name : node taints : null --- apiServer : timeoutForControlPlane : 4m0s apiVersion : kubeadm.k8s.io/v1beta3 certificatesDir : /etc/kubernetes/pki clusterName : kubernetes controllerManager : {} dns : {} etcd : local : dataDir : /var/lib/etcd imageRepository : k8s.gcr.io kind : ClusterConfiguration kubernetesVersion : 1.24.0 networking : dnsDomain : cluster.local serviceSubnet : 10.96.0.0/12 scheduler : {} Dry rune and run. Save the output, which will be used later on work nodes. With kubeadm init to initiate cluster, we need understand below three options about network. --pod-network-cidr : Specify range of IP addresses for the pod network. If set, the control plane will automatically allocate CIDRs for every node. Be noted that 10.244.0.0/16 is default range of flannel. If it's changed here, please do change the same when deploy Flannel . --apiserver-bind-port : Port for the API Server to bind to. (default 6443) --service-cidr : Use alternative range of IP address for service VIPs. (default \"10.96.0.0/12\") Note: service VIPs (a.k.a. Cluster IP), specified by option --service-cidr . podCIDR (a.k.a. endpoint IP)\uff0cspecified by option --pod-network-cidr . There are 4 distinct networking problems to address: Highly-coupled container-to-container communications: this is solved by Pods (podCIDR) and localhost communications. Pod-to-Pod communications: a.k.a. container-to-container. Example with Flannel, the flow is: Pod \u2192 veth pair \u2192 cni0 \u2192 flannel.1 \u2192 host eth0 \u2192 host eth0 \u2192 flannel.1 \u2192 cni0 \u2192 veth pair \u2192 Pod. Pod-to-Service communications: Flow: Pod \u2192 Kernel \u2192 Servive iptables \u2192 service \u2192 Pod iptables \u2192 Pod External-to-Service communications: LoadBalancer: SLB \u2192 NodePort \u2192 Service \u2192 Pod kube-proxy is responsible for iptables, not traffic. sudo kubeadm init \\ --dry-run \\ --pod-network-cidr = 10 .244.0.0/16 \\ --service-cidr 11 .244.0.0/16 \\ --image-repository = registry.aliyuncs.com/google_containers \\ --kubernetes-version = v1.24.0 sudo kubeadm init \\ --pod-network-cidr = 10 .244.0.0/16 \\ --service-cidr 11 .244.0.0/16 \\ --image-repository = registry.aliyuncs.com/google_containers \\ --kubernetes-version = v1.24.0 sudo kubeadm init \\ --pod-network-cidr = 10 .244.0.0/16 \\ --service-cidr 11 .244.0.0/16 \\ --kubernetes-version = v1.24.0","title":"kubeadm init"},{"location":"k8s/cka_en/installation/aliyun-ubuntu/#kubeconfig-file","text":"Set kubeconfig file for current user (here it's james ). mkdir -p $HOME /.kube sudo cp -i /etc/kubernetes/admin.conf $HOME /.kube/config sudo chown $( id -u ) : $( id -g ) $HOME /.kube/config Kubernetes provides a command line tool kubectl for communicating with a Kubernetes cluster's control plane, using the Kubernetes API. kubectl controls the Kubernetes cluster manager . For configuration, kubectl looks for a file named config in the $HOME/.kube directory, which is a copy of file /etc/kubernetes/admin.conf generated by kubeadm init . We can specify other kubeconfig files by setting the KUBECONFIG environment variable or by setting the --kubeconfig flag . If the KUBECONFIG environment variable doesn't exist, kubectl uses the default kubeconfig file, $HOME/.kube/config . A context element in a kubeconfig file is used to group access parameters under a convenient name. Each context has three parameters: cluster, namespace, and user. By default, the kubectl command-line tool uses parameters from the current context to communicate with the cluster. A sample of .kube/config . apiVersion : v1 clusters : - cluster : certificate-authority-data : server : https://:6443 name : contexts : - context : cluster : namespace : user : name : @ current-context : kind : Config preferences : {} users : - name : user : client-certificate-data : client-key-data : To get the current context: kubectl config get-contexts Result CURRENT NAME CLUSTER AUTHINFO NAMESPACE * kubernetes-admin@kubernetes kubernetes kubernetes-admin","title":"kubeconfig file"},{"location":"k8s/cka_en/installation/aliyun-ubuntu/#setup-work-nodes","text":"Perform on all VMs playing work nodes. # kubeadm join :6443 --token --discovery-token-ca-cert-hash Use kubeadm token to generate the join token and hash value. kubeadm token create --print-join-command Execute the command generated above on each node that we want to join the cluster as Worker node. Verify status on master node. All nodes' status is NotReady . Leave it at the moment and continue to install network plugin. kubectl get node -o wide","title":"Setup Work Nodes"},{"location":"k8s/cka_en/installation/aliyun-ubuntu/#install-calico-or-flannel","text":"Choose Calico or Flannel on control plane node. For NetworkPolicy purpose, choose Calico.","title":"Install Calico or Flannel"},{"location":"k8s/cka_en/installation/aliyun-ubuntu/#install-flannel","text":"Flannel is a simple and easy way to configure a layer 3 network fabric designed for Kubernetes. Deploy Flannel. In the kube-flannel.yml we can get the default network setting of Flannel, which is same with --pod-network-cidr=10.244.0.0/16 we defined before when we initiated kubeadm . net-conf.json : | { \"Network\": \"10.244.0.0/16\", \"Backend\": { \"Type\": \"vxlan\" } } Create Flannel apply -f https://raw.githubusercontent.com/coreos/flannel/master/Documentation/kube-flannel.yml Result Warning: policy/v1beta1 PodSecurityPolicy is deprecated in v1.21+, unavailable in v1.25+ podsecuritypolicy.policy/psp.flannel.unprivileged created clusterrole.rbac.authorization.k8s.io/flannel created clusterrolebinding.rbac.authorization.k8s.io/flannel created serviceaccount/flannel created configmap/kube-flannel-cfg created daemonset.apps/kube-flannel-ds created","title":"Install Flannel"},{"location":"k8s/cka_en/installation/aliyun-ubuntu/#install-calico","text":"Here is guidance of End-to-end Calico installation . Detail practice demo, can be found in section \"Install Calico\" of \"A1.Discussion\" below. Install Calico curl https://docs.projectcalico.org/manifests/calico.yaml -O kubectl apply -f calico.yaml Result configmap/calico-config created customresourcedefinition.apiextensions.k8s.io/bgpconfigurations.crd.projectcalico.org created customresourcedefinition.apiextensions.k8s.io/bgppeers.crd.projectcalico.org created customresourcedefinition.apiextensions.k8s.io/blockaffinities.crd.projectcalico.org created customresourcedefinition.apiextensions.k8s.io/caliconodestatuses.crd.projectcalico.org created customresourcedefinition.apiextensions.k8s.io/clusterinformations.crd.projectcalico.org created customresourcedefinition.apiextensions.k8s.io/felixconfigurations.crd.projectcalico.org created customresourcedefinition.apiextensions.k8s.io/globalnetworkpolicies.crd.projectcalico.org created customresourcedefinition.apiextensions.k8s.io/globalnetworksets.crd.projectcalico.org created customresourcedefinition.apiextensions.k8s.io/hostendpoints.crd.projectcalico.org created customresourcedefinition.apiextensions.k8s.io/ipamblocks.crd.projectcalico.org created customresourcedefinition.apiextensions.k8s.io/ipamconfigs.crd.projectcalico.org created customresourcedefinition.apiextensions.k8s.io/ipamhandles.crd.projectcalico.org created customresourcedefinition.apiextensions.k8s.io/ippools.crd.projectcalico.org created customresourcedefinition.apiextensions.k8s.io/ipreservations.crd.projectcalico.org created customresourcedefinition.apiextensions.k8s.io/kubecontrollersconfigurations.crd.projectcalico.org created customresourcedefinition.apiextensions.k8s.io/networkpolicies.crd.projectcalico.org created customresourcedefinition.apiextensions.k8s.io/networksets.crd.projectcalico.org created clusterrole.rbac.authorization.k8s.io/calico-kube-controllers created clusterrolebinding.rbac.authorization.k8s.io/calico-kube-controllers created clusterrole.rbac.authorization.k8s.io/calico-node created clusterrolebinding.rbac.authorization.k8s.io/calico-node created daemonset.apps/calico-node created serviceaccount/calico-node created deployment.apps/calico-kube-controllers created serviceaccount/calico-kube-controllers created poddisruptionbudget.policy/calico-kube-controllers created Verify status of Calico. kubectl get pod -n kube-system | grep calico Result calico-kube-controllers-555bc4b957-l8bn2 0/1 Pending 0 28s calico-node-255pc 0/1 Init:1/3 0 29s calico-node-7tmnb 0/1 Init:1/3 0 29s calico-node-w8nvl 0/1 Init:1/3 0 29s Verify network status. sudo nerdctl network ls Result NETWORK ID NAME FILE k8s-pod-network /etc/cni/net.d/10-calico.conflist 0 bridge /etc/cni/net.d/nerdctl-bridge.conflist host none","title":"Install Calico"},{"location":"k8s/cka_en/installation/aliyun-ubuntu/#check-cluster-status","text":"Perform kubectl cluster-info command on master node we will get below information. Kubernetes control plane is running at https://:6443 CoreDNS is running at https://:6443/api/v1/namespaces/kube-system/services/kube-dns:dns/proxy kubectl cluster-info Get nodes status. kubectl get nodes -owide All nodes are up with normal status. OS Image: Ubuntu 20.04.4 LTS Kernel Version: 5.4.0-122-generic Container Runtime: containerd://1.5.9 NAME STATUS ROLES AGE VERSION cka001 Ready control-plane 13m v1.24.0 cka002 Ready 8m35s v1.24.0 cka003 Ready 8m26s v1.24.0 Get pods status kubectl get pod -A Result: NAMESPACE NAME READY STATUS RESTARTS AGE kube-system calico-kube-controllers-555bc4b957-l8bn2 1/1 Running 0 7m18s kube-system calico-node-255pc 1/1 Running 0 7m19s kube-system calico-node-7tmnb 1/1 Running 0 7m19s kube-system calico-node-w8nvl 1/1 Running 0 7m19s kube-system coredns-74586cf9b6-4jwmk 1/1 Running 0 15m kube-system coredns-74586cf9b6-c5mll 1/1 Running 0 15m kube-system etcd-cka001 1/1 Running 0 15m kube-system kube-apiserver-cka001 1/1 Running 0 15m kube-system kube-controller-manager-cka001 1/1 Running 0 15m kube-system kube-proxy-dmj2t 1/1 Running 0 15m kube-system kube-proxy-n77zw 1/1 Running 0 11m kube-system kube-proxy-qs6rf 1/1 Running 0 11m kube-system kube-scheduler-cka001 1/1 Running 0 15m","title":"Check Cluster Status"},{"location":"k8s/cka_en/installation/aliyun-ubuntu/#reset-cluster","text":"CAUTION: below steps will destroy current cluster. Delete all nodes in the cluster. kubeadm reset Output: [reset] Reading configuration from the cluster... [reset] FYI: You can look at this config file with 'kubectl -n kube-system get cm kubeadm-config -o yaml' W0717 08:15:17.411992 3913615 preflight.go:55] [reset] WARNING: Changes made to this host by 'kubeadm init' or 'kubeadm join' will be reverted. [reset] Are you sure you want to proceed? [y/N]: y [preflight] Running pre-flight checks [reset] Stopping the kubelet service [reset] Unmounting mounted directories in \"/var/lib/kubelet\" [reset] Deleting contents of directories: [/etc/kubernetes/manifests /etc/kubernetes/pki] [reset] Deleting files: [/etc/kubernetes/admin.conf /etc/kubernetes/kubelet.conf /etc/kubernetes/bootstrap-kubelet.conf /etc/kubernetes/controller-manager.conf /etc/kubernetes/scheduler.conf] [reset] Deleting contents of stateful directories: [/var/lib/etcd /var/lib/kubelet /var/lib/dockershim /var/run/kubernetes /var/lib/cni] The reset process does not clean CNI configuration. To do so, you must remove /etc/cni/net.d The reset process does not reset or clean up iptables rules or IPVS tables. If you wish to reset iptables, you must do so manually by using the \"iptables\" command. If your cluster was setup to utilize IPVS, run ipvsadm --clear (or similar) to reset your system's IPVS tables. The reset process does not clean your kubeconfig files and you must remove them manually. Please, check the contents of the $HOME/.kube/config file. Clean up network setting rm -rf /var/run/flannel /opt/cni /etc/cni /var/lib/cni Clean up rule of iptables . iptables -F && iptables -t nat -F && iptables -t mangle -F && iptables -X Clean up rule of IPVS if using IPVS . ipvsadm --clear","title":"Reset cluster"},{"location":"k8s/cka_en/installation/aliyun-ubuntu/#troubleshooting","text":"","title":"Troubleshooting"},{"location":"k8s/cka_en/installation/aliyun-ubuntu/#issue-1","text":"The connection to the server :6443 was refused - did you specify the right host or port? Try : Reference Check if the kubeconfig file is update to udpate and exists in right place. Check environment setting. env | grep -i kub Check container status. sudo systemctl status containerd.service Check kubelet service. sudo systemctl status kubelet.service Check port listening status. netstat -pnlt | grep 6443 Check firewall status. sudo systemctl status firewalld.service Check log. journalctl -xeu kubelet","title":"Issue 1"},{"location":"k8s/cka_en/installation/aliyun-ubuntu/#issue-2","text":"\"Container runtime network not ready\" networkReady=\"NetworkReady=false reason:NetworkPluginNotReady message:Network plugin returns error: cni plugin not initialized\" Try : Restart Containerd service. sudo systemctl restart containerd sudo systemctl status containerd","title":"Issue 2"},{"location":"k8s/cka_en/installation/aliyun-ubuntu/#post-installation","text":"","title":"Post Installation"},{"location":"k8s/cka_en/installation/aliyun-ubuntu/#bash-autocomplete","text":"On each node. Set kubectl auto-completion following the guideline . apt install -y bash-completion source /usr/share/bash-completion/bash_completion source < ( kubectl completion bash ) echo \"source <(kubectl completion bash)\" >> ~/.bashrc","title":"Bash Autocomplete"},{"location":"k8s/cka_en/installation/aliyun-ubuntu/#alias","text":"If we set an alias for kubectl, we can extend shell completion to work with that alias: echo 'alias k=kubectl' >>~/.bashrc echo 'complete -o default -F __start_kubectl k' >>~/.bashrc","title":"Alias"},{"location":"k8s/cka_en/installation/aliyun-ubuntu/#update-default-context","text":"Get current context. kubectl config get-contexts In below result, we know: Contenxt name is kubernetes-admin@kubernetes . Cluster name is kubernetes . User is kubernetes-admin . No namespace explicitly defined. CURRENT NAME CLUSTER AUTHINFO NAMESPACE * kubernetes-admin@kubernetes kubernetes kubernetes-admin To set a context with new update, e.g, update default namespace, etc.. # Usage: kubectl config set-context --cluster = --namespace = --user = # Set default namespace kubectl config set-context kubernetes-admin@kubernetes --cluster = kubernetes --namespace = default --user = kubernetes-admin To switch to a new context. kubectl config use-context kubectl config use-context kubernetes-admin@kubernetes Reference of kubectl and commandline .","title":"Update Default Context"},{"location":"k8s/cka_en/installation/multiple-local/","text":"Multiple Nodes Installation \u00b6 Local VM setting \u00b6 VMWare Setting. VMnet1: host-only, subnet: 192.168.150.0/24 VMnet8: NAT, subnet: 11.0.1.0/24 Create guest machine with VMWare Player. 4 GB RAM 1 CPUs with 2 Cores Ubuntu Server 22.04 NAT Info: Kubernetes running on Containerd. Ubuntu Post Installation \u00b6 Info: Log onto each VM with the account created during Ubuntu installation, and perform below tasks on every VM. Create user vagrant on all guests. sudo adduser vagrant sudo usermod -aG adm,sudo,syslog,cdrom,dip,plugdev,lxd,root vagrant sudo passwd vagrant Set password for root on all guests. sudo passwd root Enable root ssh logon. sudo vi /etc/ssh/sshd_config Update parameter PermitRootLogin from prohibit-password to yes . PermitRootLogin yes # PermitRootLogin prohibit-password Restart the sshd service. sudo systemctl restart sshd Change host name, e.g., ubu1 . sudo hostnamectl set-hostname ubu1 sudo hostnamectl set-hostname ubu1 --pretty Verify if the hostname is set to expected name, e.g., ubu1 . cat /etc/machine-info Verify if the hostname is set to expected name, e.g., ubu1 . cat /etc/hostname Verify if the hostname of 127.0.1.1 is set to expected name, e.g., ubu1 . And add all nodes into the file /etc/hosts . sudo vi /etc/hosts Related setting looks like below. 127.0.1.1 ubu1 11.0.1.129 ubu1 11.0.1.130 ubu2 11.0.1.131 ubu3 11.0.1.132 ubu4 Create file /etc/netplan/00-installer-config.yaml . sudo vi /etc/netplan/00-installer-config.yaml Update it with information below to set VM with fixed IP with actual IP address, e.g, 11.0.1.129 . network : ethernets : ens33 : dhcp4 : false addresses : - 11.0.1.129/24 nameservers : addresses : - 11.0.1.2 routes : - to : default via : 11.0.1.2 version : 2 Effect above change. sudo netplan apply Attention: The current ssh connection will be broken due to network setting change. Disable swap and firewall on all nodes. sudo swapoff -a sudo ufw disable sudo ufw status verbose And comment the last line of swap setting in file /etc/fstab . Need reboot guest here. sudo vi /etc/fstab Result likes below. /dev/disk/by-uuid/df370d2a-83e5-4895-8c7f-633f2545e3fe / ext4 defaults 0 1 # /swap.img none swap sw 0 0 Setup timezone on all nodes sudo ln -sf /usr/share/zoneinfo/Asia/Shanghai /etc/localtime sudo cp /etc/profile /etc/profile.bak echo 'LANG=\"en_US.UTF-8\"' | sudo tee -a /etc/profile source /etc/profile Something like this after execute command ll /etc/localtime lrwxrwxrwx 1 root root 33 Jul 15 22:00 /etc/localtime -> /usr/share/zoneinfo/Asia/Shanghai Kernel setting. cat < server : https://:6443 name : contexts : - context : cluster : namespace : user : name : @ current-context : kind : Config preferences : {} users : - name : user : client-certificate-data : client-key-data : To get the current context: kubectl config get-contexts Result CURRENT NAME CLUSTER AUTHINFO NAMESPACE * kubernetes-admin@kubernetes kubernetes kubernetes-admin Install Calico \u00b6 Here is guidance of End-to-end Calico installation . Detail practice demo, can be found in section \"Install Calico\" of \"A1.Discussion\" below. Install Calico curl https://docs.projectcalico.org/manifests/calico.yaml -O kubectl apply -f calico.yaml Result configmap/calico-config created customresourcedefinition.apiextensions.k8s.io/bgpconfigurations.crd.projectcalico.org created customresourcedefinition.apiextensions.k8s.io/bgppeers.crd.projectcalico.org created customresourcedefinition.apiextensions.k8s.io/blockaffinities.crd.projectcalico.org created customresourcedefinition.apiextensions.k8s.io/caliconodestatuses.crd.projectcalico.org created customresourcedefinition.apiextensions.k8s.io/clusterinformations.crd.projectcalico.org created customresourcedefinition.apiextensions.k8s.io/felixconfigurations.crd.projectcalico.org created customresourcedefinition.apiextensions.k8s.io/globalnetworkpolicies.crd.projectcalico.org created customresourcedefinition.apiextensions.k8s.io/globalnetworksets.crd.projectcalico.org created customresourcedefinition.apiextensions.k8s.io/hostendpoints.crd.projectcalico.org created customresourcedefinition.apiextensions.k8s.io/ipamblocks.crd.projectcalico.org created customresourcedefinition.apiextensions.k8s.io/ipamconfigs.crd.projectcalico.org created customresourcedefinition.apiextensions.k8s.io/ipamhandles.crd.projectcalico.org created customresourcedefinition.apiextensions.k8s.io/ippools.crd.projectcalico.org created customresourcedefinition.apiextensions.k8s.io/ipreservations.crd.projectcalico.org created customresourcedefinition.apiextensions.k8s.io/kubecontrollersconfigurations.crd.projectcalico.org created customresourcedefinition.apiextensions.k8s.io/networkpolicies.crd.projectcalico.org created customresourcedefinition.apiextensions.k8s.io/networksets.crd.projectcalico.org created clusterrole.rbac.authorization.k8s.io/calico-kube-controllers created clusterrolebinding.rbac.authorization.k8s.io/calico-kube-controllers created clusterrole.rbac.authorization.k8s.io/calico-node created clusterrolebinding.rbac.authorization.k8s.io/calico-node created daemonset.apps/calico-node created serviceaccount/calico-node created deployment.apps/calico-kube-controllers created serviceaccount/calico-kube-controllers created poddisruptionbudget.policy/calico-kube-controllers created Verify status of Calico. It may take minutes to complete initialization. kubectl get pod -n kube-system | grep calico Result calico-kube-controllers-555bc4b957-l8bn2 0/1 Pending 0 28s calico-node-255pc 0/1 Init:1/3 0 29s calico-node-7tmnb 0/1 Init:1/3 0 29s calico-node-w8nvl 0/1 Init:1/3 0 29s Verify network status. sudo nerdctl network ls Result NETWORK ID NAME FILE k8s-pod-network /etc/cni/net.d/10-calico.conflist 17f29b073143 bridge /etc/cni/net.d/nerdctl-bridge.conflist host none Setup Work Nodes \u00b6 Use kubeadm token to generate the join token and hash value. kubeadm token create --print-join-command Command usage: sudo kubeadm join :6443 --token --discovery-token-ca-cert-hash < hash key generated by kubeadm init> Result looks like below. [preflight] Running pre-flight checks [WARNING SystemVerification]: missing optional cgroups: blkio [preflight] Reading configuration from the cluster... [preflight] FYI: You can look at this config file with 'kubectl -n kube-system get cm kubeadm-config -o yaml' [kubelet-start] Writing kubelet configuration to file \"/var/lib/kubelet/config.yaml\" [kubelet-start] Writing kubelet environment file with flags to file \"/var/lib/kubelet/kubeadm-flags.env\" [kubelet-start] Starting the kubelet [kubelet-start] Waiting for the kubelet to perform the TLS Bootstrap... This node has joined the cluster: * Certificate signing request was sent to apiserver and a response was received. * The Kubelet was informed of the new secure connection details. Run 'kubectl get nodes' on the control-plane to see this node join the cluster. Check Cluster Status \u00b6 Cluster info: kubectl cluster-info Output Kubernetes control plane is running at https://11.0.1.129:6443 CoreDNS is running at https://11.0.1.129:6443/api/v1/namespaces/kube-system/services/kube-dns:dns/proxy To further debug and diagnose cluster problems, use 'kubectl cluster-info dump'. Node info: kubectl get nodes -owide Pod info: kubectl get pod -A Post Installation \u00b6 Bash Autocomplete \u00b6 On each node. Set kubectl auto-completion following the guideline . apt install -y bash-completion source /usr/share/bash-completion/bash_completion source < ( kubectl completion bash ) echo \"source <(kubectl completion bash)\" >> ~/.bashrc source ~/.bashrc Alias \u00b6 If we set an alias for kubectl, we can extend shell completion to work with that alias: echo 'alias k=kubectl' >>~/.bashrc echo 'complete -o default -F __start_kubectl k' >>~/.bashrc Update Default Context \u00b6 Get current context. kubectl config get-contexts In below result, we know: Contenxt name is kubernetes-admin@kubernetes . Cluster name is kubernetes . User is kubernetes-admin . No namespace explicitly defined. CURRENT NAME CLUSTER AUTHINFO NAMESPACE * kubernetes-admin@kubernetes kubernetes kubernetes-admin To set a context with new update, e.g, update default namespace, etc.. # Usage: kubectl config set-context --cluster = --namespace = --user = # Set default namespace kubectl config set-context kubernetes-admin@kubernetes --cluster = kubernetes --namespace = default --user = kubernetes-admin To switch to a new context. kubectl config use-context kubectl config use-context kubernetes-admin@kubernetes Reference: kubectl commandline Install Helm \u00b6 Helm is the Kubernetes package manager. It doesn't come with Kubernetes. Three concepts of helm: A Chart is a Helm package. It contains all of the resource definitions necessary to run an application, tool, or service inside of a Kubernetes cluster. Think of it like the Kubernetes equivalent of a Homebrew formula, an Apt dpkg, or a Yum RPM file. A Repository is the place where charts can be collected and shared. It's like Perl's CPAN archive or the Fedora Package Database, but for Kubernetes packages. A Release is an instance of a chart running in a Kubernetes cluster. One chart can often be installed many times into the same cluster. And each time it is installed, a new release is created. Consider a MySQL chart. If you want two databases running in your cluster, you can install that chart twice. Each one will have its own release, which will in turn have its own release name. Reference: installation guide binary release source code . Helm Client Installation: curl -fsSL -o get_helm.sh https://raw.githubusercontent.com/helm/helm/main/scripts/get-helm-3 chmod 700 get_helm.sh ./get_helm.sh Output: Downloading https://get.helm.sh/helm-v3.9.1-linux-amd64.tar.gz Verifying checksum... Done. Preparing to install helm into /usr/local/bin helm installed into /usr/local/bin/helm Note: helm init does not exist in Helm 3, following the removal of Tiller. You no longer need to install Tiller in your cluster in order to use Helm. helm search can be used to search two different types of source: helm search hub searches the Artifact Hub , which lists helm charts from dozens of different repositories. helm search repo searches the repositories that you have added to your local helm client (with helm repo add). This search is done over local data, and no public network connection is needed. Reference: Helming development Reset cluster \u00b6 Caution: below steps will destroy current cluster. Delete all nodes in the cluster. kubeadm reset Clean up rule of iptables . iptables -F && iptables -t nat -F && iptables -t mangle -F && iptables -X Clean up rule of IPVS if using IPVS . ipvsadm --clear","title":"Multiple Nodes Installation"},{"location":"k8s/cka_en/installation/multiple-local/#multiple-nodes-installation","text":"","title":"Multiple Nodes Installation"},{"location":"k8s/cka_en/installation/multiple-local/#local-vm-setting","text":"VMWare Setting. VMnet1: host-only, subnet: 192.168.150.0/24 VMnet8: NAT, subnet: 11.0.1.0/24 Create guest machine with VMWare Player. 4 GB RAM 1 CPUs with 2 Cores Ubuntu Server 22.04 NAT Info: Kubernetes running on Containerd.","title":"Local VM setting"},{"location":"k8s/cka_en/installation/multiple-local/#ubuntu-post-installation","text":"Info: Log onto each VM with the account created during Ubuntu installation, and perform below tasks on every VM. Create user vagrant on all guests. sudo adduser vagrant sudo usermod -aG adm,sudo,syslog,cdrom,dip,plugdev,lxd,root vagrant sudo passwd vagrant Set password for root on all guests. sudo passwd root Enable root ssh logon. sudo vi /etc/ssh/sshd_config Update parameter PermitRootLogin from prohibit-password to yes . PermitRootLogin yes # PermitRootLogin prohibit-password Restart the sshd service. sudo systemctl restart sshd Change host name, e.g., ubu1 . sudo hostnamectl set-hostname ubu1 sudo hostnamectl set-hostname ubu1 --pretty Verify if the hostname is set to expected name, e.g., ubu1 . cat /etc/machine-info Verify if the hostname is set to expected name, e.g., ubu1 . cat /etc/hostname Verify if the hostname of 127.0.1.1 is set to expected name, e.g., ubu1 . And add all nodes into the file /etc/hosts . sudo vi /etc/hosts Related setting looks like below. 127.0.1.1 ubu1 11.0.1.129 ubu1 11.0.1.130 ubu2 11.0.1.131 ubu3 11.0.1.132 ubu4 Create file /etc/netplan/00-installer-config.yaml . sudo vi /etc/netplan/00-installer-config.yaml Update it with information below to set VM with fixed IP with actual IP address, e.g, 11.0.1.129 . network : ethernets : ens33 : dhcp4 : false addresses : - 11.0.1.129/24 nameservers : addresses : - 11.0.1.2 routes : - to : default via : 11.0.1.2 version : 2 Effect above change. sudo netplan apply Attention: The current ssh connection will be broken due to network setting change. Disable swap and firewall on all nodes. sudo swapoff -a sudo ufw disable sudo ufw status verbose And comment the last line of swap setting in file /etc/fstab . Need reboot guest here. sudo vi /etc/fstab Result likes below. /dev/disk/by-uuid/df370d2a-83e5-4895-8c7f-633f2545e3fe / ext4 defaults 0 1 # /swap.img none swap sw 0 0 Setup timezone on all nodes sudo ln -sf /usr/share/zoneinfo/Asia/Shanghai /etc/localtime sudo cp /etc/profile /etc/profile.bak echo 'LANG=\"en_US.UTF-8\"' | sudo tee -a /etc/profile source /etc/profile Something like this after execute command ll /etc/localtime lrwxrwxrwx 1 root root 33 Jul 15 22:00 /etc/localtime -> /usr/share/zoneinfo/Asia/Shanghai Kernel setting. cat < server : https://:6443 name : contexts : - context : cluster : namespace : user : name : @ current-context : kind : Config preferences : {} users : - name : user : client-certificate-data : client-key-data : To get the current context: kubectl config get-contexts Result CURRENT NAME CLUSTER AUTHINFO NAMESPACE * kubernetes-admin@kubernetes kubernetes kubernetes-admin","title":"kubeconfig file"},{"location":"k8s/cka_en/installation/multiple-local/#install-calico","text":"Here is guidance of End-to-end Calico installation . Detail practice demo, can be found in section \"Install Calico\" of \"A1.Discussion\" below. Install Calico curl https://docs.projectcalico.org/manifests/calico.yaml -O kubectl apply -f calico.yaml Result configmap/calico-config created customresourcedefinition.apiextensions.k8s.io/bgpconfigurations.crd.projectcalico.org created customresourcedefinition.apiextensions.k8s.io/bgppeers.crd.projectcalico.org created customresourcedefinition.apiextensions.k8s.io/blockaffinities.crd.projectcalico.org created customresourcedefinition.apiextensions.k8s.io/caliconodestatuses.crd.projectcalico.org created customresourcedefinition.apiextensions.k8s.io/clusterinformations.crd.projectcalico.org created customresourcedefinition.apiextensions.k8s.io/felixconfigurations.crd.projectcalico.org created customresourcedefinition.apiextensions.k8s.io/globalnetworkpolicies.crd.projectcalico.org created customresourcedefinition.apiextensions.k8s.io/globalnetworksets.crd.projectcalico.org created customresourcedefinition.apiextensions.k8s.io/hostendpoints.crd.projectcalico.org created customresourcedefinition.apiextensions.k8s.io/ipamblocks.crd.projectcalico.org created customresourcedefinition.apiextensions.k8s.io/ipamconfigs.crd.projectcalico.org created customresourcedefinition.apiextensions.k8s.io/ipamhandles.crd.projectcalico.org created customresourcedefinition.apiextensions.k8s.io/ippools.crd.projectcalico.org created customresourcedefinition.apiextensions.k8s.io/ipreservations.crd.projectcalico.org created customresourcedefinition.apiextensions.k8s.io/kubecontrollersconfigurations.crd.projectcalico.org created customresourcedefinition.apiextensions.k8s.io/networkpolicies.crd.projectcalico.org created customresourcedefinition.apiextensions.k8s.io/networksets.crd.projectcalico.org created clusterrole.rbac.authorization.k8s.io/calico-kube-controllers created clusterrolebinding.rbac.authorization.k8s.io/calico-kube-controllers created clusterrole.rbac.authorization.k8s.io/calico-node created clusterrolebinding.rbac.authorization.k8s.io/calico-node created daemonset.apps/calico-node created serviceaccount/calico-node created deployment.apps/calico-kube-controllers created serviceaccount/calico-kube-controllers created poddisruptionbudget.policy/calico-kube-controllers created Verify status of Calico. It may take minutes to complete initialization. kubectl get pod -n kube-system | grep calico Result calico-kube-controllers-555bc4b957-l8bn2 0/1 Pending 0 28s calico-node-255pc 0/1 Init:1/3 0 29s calico-node-7tmnb 0/1 Init:1/3 0 29s calico-node-w8nvl 0/1 Init:1/3 0 29s Verify network status. sudo nerdctl network ls Result NETWORK ID NAME FILE k8s-pod-network /etc/cni/net.d/10-calico.conflist 17f29b073143 bridge /etc/cni/net.d/nerdctl-bridge.conflist host none","title":"Install Calico"},{"location":"k8s/cka_en/installation/multiple-local/#setup-work-nodes","text":"Use kubeadm token to generate the join token and hash value. kubeadm token create --print-join-command Command usage: sudo kubeadm join :6443 --token --discovery-token-ca-cert-hash < hash key generated by kubeadm init> Result looks like below. [preflight] Running pre-flight checks [WARNING SystemVerification]: missing optional cgroups: blkio [preflight] Reading configuration from the cluster... [preflight] FYI: You can look at this config file with 'kubectl -n kube-system get cm kubeadm-config -o yaml' [kubelet-start] Writing kubelet configuration to file \"/var/lib/kubelet/config.yaml\" [kubelet-start] Writing kubelet environment file with flags to file \"/var/lib/kubelet/kubeadm-flags.env\" [kubelet-start] Starting the kubelet [kubelet-start] Waiting for the kubelet to perform the TLS Bootstrap... This node has joined the cluster: * Certificate signing request was sent to apiserver and a response was received. * The Kubelet was informed of the new secure connection details. Run 'kubectl get nodes' on the control-plane to see this node join the cluster.","title":"Setup Work Nodes"},{"location":"k8s/cka_en/installation/multiple-local/#check-cluster-status","text":"Cluster info: kubectl cluster-info Output Kubernetes control plane is running at https://11.0.1.129:6443 CoreDNS is running at https://11.0.1.129:6443/api/v1/namespaces/kube-system/services/kube-dns:dns/proxy To further debug and diagnose cluster problems, use 'kubectl cluster-info dump'. Node info: kubectl get nodes -owide Pod info: kubectl get pod -A","title":"Check Cluster Status"},{"location":"k8s/cka_en/installation/multiple-local/#post-installation","text":"","title":"Post Installation"},{"location":"k8s/cka_en/installation/multiple-local/#bash-autocomplete","text":"On each node. Set kubectl auto-completion following the guideline . apt install -y bash-completion source /usr/share/bash-completion/bash_completion source < ( kubectl completion bash ) echo \"source <(kubectl completion bash)\" >> ~/.bashrc source ~/.bashrc","title":"Bash Autocomplete"},{"location":"k8s/cka_en/installation/multiple-local/#alias","text":"If we set an alias for kubectl, we can extend shell completion to work with that alias: echo 'alias k=kubectl' >>~/.bashrc echo 'complete -o default -F __start_kubectl k' >>~/.bashrc","title":"Alias"},{"location":"k8s/cka_en/installation/multiple-local/#update-default-context","text":"Get current context. kubectl config get-contexts In below result, we know: Contenxt name is kubernetes-admin@kubernetes . Cluster name is kubernetes . User is kubernetes-admin . No namespace explicitly defined. CURRENT NAME CLUSTER AUTHINFO NAMESPACE * kubernetes-admin@kubernetes kubernetes kubernetes-admin To set a context with new update, e.g, update default namespace, etc.. # Usage: kubectl config set-context --cluster = --namespace = --user = # Set default namespace kubectl config set-context kubernetes-admin@kubernetes --cluster = kubernetes --namespace = default --user = kubernetes-admin To switch to a new context. kubectl config use-context kubectl config use-context kubernetes-admin@kubernetes Reference: kubectl commandline","title":"Update Default Context"},{"location":"k8s/cka_en/installation/multiple-local/#install-helm","text":"Helm is the Kubernetes package manager. It doesn't come with Kubernetes. Three concepts of helm: A Chart is a Helm package. It contains all of the resource definitions necessary to run an application, tool, or service inside of a Kubernetes cluster. Think of it like the Kubernetes equivalent of a Homebrew formula, an Apt dpkg, or a Yum RPM file. A Repository is the place where charts can be collected and shared. It's like Perl's CPAN archive or the Fedora Package Database, but for Kubernetes packages. A Release is an instance of a chart running in a Kubernetes cluster. One chart can often be installed many times into the same cluster. And each time it is installed, a new release is created. Consider a MySQL chart. If you want two databases running in your cluster, you can install that chart twice. Each one will have its own release, which will in turn have its own release name. Reference: installation guide binary release source code . Helm Client Installation: curl -fsSL -o get_helm.sh https://raw.githubusercontent.com/helm/helm/main/scripts/get-helm-3 chmod 700 get_helm.sh ./get_helm.sh Output: Downloading https://get.helm.sh/helm-v3.9.1-linux-amd64.tar.gz Verifying checksum... Done. Preparing to install helm into /usr/local/bin helm installed into /usr/local/bin/helm Note: helm init does not exist in Helm 3, following the removal of Tiller. You no longer need to install Tiller in your cluster in order to use Helm. helm search can be used to search two different types of source: helm search hub searches the Artifact Hub , which lists helm charts from dozens of different repositories. helm search repo searches the repositories that you have added to your local helm client (with helm repo add). This search is done over local data, and no public network connection is needed. Reference: Helming development","title":"Install Helm"},{"location":"k8s/cka_en/installation/multiple-local/#reset-cluster","text":"Caution: below steps will destroy current cluster. Delete all nodes in the cluster. kubeadm reset Clean up rule of iptables . iptables -F && iptables -t nat -F && iptables -t mangle -F && iptables -X Clean up rule of IPVS if using IPVS . ipvsadm --clear","title":"Reset cluster"},{"location":"k8s/cka_en/installation/single-local/","text":"Single Node Installation \u00b6 Local VM setting \u00b6 VMWare Setting. VMnet1: host-only, subnet: 192.168.150.0/24 VMnet8: NAT, subnet: 11.0.1.0/24 Create guest machine with VMWare Player. 4 GB RAM 2 CPUs with 2 Cores Ubuntu Server 22.04 NAT Kubernetes running on Docker. Ubuntu Post Installation \u00b6 Create user vagrant . sudo adduser vagrant sudo usermod -aG adm,sudo,syslog,cdrom,dip,plugdev,lxd vagrant sudo passwd vagrant Set password for root . sudo passwd root Update guest's hostname. Here it's ubusvr . sudo hostnamectl set-hostname ubusvr sudo hostnamectl set-hostname ubusvr --pretty Verify if the hostname is set to ubusvr . cat /etc/machine-info Verify if the hostname is set to ubusvr . cat /etc/hostname Verify if the hostname of 127.0.1.1 is set to ubusvr . cat /etc/hosts 127 .0.0.1 localhost 127 .0.1.1 ubusrv # The following lines are desirable for IPv6 capable hosts ::1 ip6-localhost ip6-loopback fe00::0 ip6-localnet ff00::0 ip6-mcastprefix ff02::1 ip6-allnodes ff02::2 ip6-allrouters Set guest with fix ip, e.g, 11.0.1.136 . sudo vi 00 -installer-config.yaml network: ethernets: ens33: dhcp4: false addresses: - 11 .0.1.136/24 nameservers: addresses: - 11 .0.1.2 routes: - to: default via: 11 .0.1.2 version: 2 sudo netplan apply Disable swap sudo swapoff -a sudo ufw disable sudo ufw status verbose And comment the last line of swap setting in file /etc/fstab . Need reboot guest here. /dev/disk/by-uuid/df370d2a-83e5-4895-8c7f-633f2545e3fe / ext4 defaults 0 1 # /swap.img none swap sw 0 0 Setup timezone sudo ln -sf /usr/share/zoneinfo/Asia/Shanghai /etc/localtime sudo echo 'LANG=\"en_US.UTF-8\"' >> /etc/profile source /etc/profile Something like this after execute command ll /etc/localtime lrwxrwxrwx 1 root root 33 Jul 15 22 :00 /etc/localtime -> /usr/share/zoneinfo/Asia/Shanghai Kernel setting cat < /dev/null sudo apt-get update sudo apt-get install docker-ce docker-ce-cli containerd.io docker-compose-plugin sudo systemctl status docker.service sudo systemctl status containerd.service sudo groupadd docker sudo usermod -aG docker $USER Setup Containerd containerd config default | sudo tee /etc/containerd/config.toml sudo vi /etc/containerd/config.toml sudo systemctl restart containerd sudo systemctl status containerd Install Kubernetes \u00b6 Install kubeadm sudo apt-get update && sudo apt-get install -y apt-transport-https ca-certificates curl sudo curl -fsSLo /usr/share/keyrings/kubernetes-archive-keyring.gpg https://mirrors.aliyun.com/kubernetes/apt/doc/apt-key.gpg echo \"deb [signed-by=/usr/share/keyrings/kubernetes-archive-keyring.gpg] https://mirrors.aliyun.com/kubernetes/apt/ kubernetes-xenial main\" | sudo tee /etc/apt/sources.list.d/kubernetes.list sudo apt-get update sudo apt-get install ebtables sudo apt-get install libxtables12 sudo apt-get upgrade iptables apt policy kubeadm sudo apt-get -y install kubelet = 1 .23.8-00 kubeadm = 1 .23.8-00 kubectl = 1 .23.8-00 --allow-downgrades Setup Master Node sudo kubeadm config print init-defaults Dry run sudo kubeadm init --dry-run --pod-network-cidr = 10 .244.0.0/16 --image-repository = registry.aliyuncs.com/google_containers --kubernetes-version = v1.23.8 Run sudo kubeadm init --pod-network-cidr = 10 .244.0.0/16 --image-repository = registry.aliyuncs.com/google_containers --kubernetes-version = v1.23.8 mkdir -p $HOME /.kube sudo cp -i /etc/kubernetes/admin.conf $HOME /.kube/config sudo chown $( id -u ) : $( id -g ) $HOME /.kube/config Install Flannel. If NetworkPolicy is the case, then install Calico. Refer to the \"Install Calico or Flannel\" of below section \"Installation on Aliyun Ubuntu\". kubectl apply -f https://raw.githubusercontent.com/coreos/flannel/master/Documentation/kube-flannel.yml Setup on Worker Node Command usage: kubeadm join :6443 --token --discovery-token-ca-cert-hash < hash key generated by kubeadm init> kubeadm join 11 .0.1.136:6443 --token 6zqh1u.8b4afzc2ov4e7iuj \\ --discovery-token-ca-cert-hash sha256:815fdb9dd9e3ae0af07ffaf6c216964388098b150ef01ee3ae900c261a429d24 Setup bash auto completion on all nodes sudo apt install -y bash-completion source /usr/share/bash-completion/bash_completion source < ( kubectl completion bash ) echo \"source <(kubectl completion bash)\" >> ~/.bashrc Create alias echo 'alias k=kubectl' >>~/.bashrc echo 'complete -o default -F __start_kubectl k' >>~/.bashrc Check Cluster Status kubectl cluster-info kubectl get nodes -owide kubectl get pod -A Reset cluster \u00b6 CAUTION: below steps will destroy current cluster. Delete all nodes in the cluster. kubeadm reset Clean up rule of iptables . iptables -F && iptables -t nat -F && iptables -t mangle -F && iptables -X Clean up rule of IPVS if using IPVS . ipvsadm --clear Install Helm \u00b6 Helm Client Installation: curl -fsSL -o get_helm.sh https://raw.githubusercontent.com/helm/helm/main/scripts/get-helm-3 chmod 700 get_helm.sh ./get_helm.sh Output: Downloading https://get.helm.sh/helm-v3.9.0-linux-amd64.tar.gz Verifying checksum... Done. Preparing to install helm into /usr/local/bin helm installed into /usr/local/bin/helm","title":"Single Node Installation"},{"location":"k8s/cka_en/installation/single-local/#single-node-installation","text":"","title":"Single Node Installation"},{"location":"k8s/cka_en/installation/single-local/#local-vm-setting","text":"VMWare Setting. VMnet1: host-only, subnet: 192.168.150.0/24 VMnet8: NAT, subnet: 11.0.1.0/24 Create guest machine with VMWare Player. 4 GB RAM 2 CPUs with 2 Cores Ubuntu Server 22.04 NAT Kubernetes running on Docker.","title":"Local VM setting"},{"location":"k8s/cka_en/installation/single-local/#ubuntu-post-installation","text":"Create user vagrant . sudo adduser vagrant sudo usermod -aG adm,sudo,syslog,cdrom,dip,plugdev,lxd vagrant sudo passwd vagrant Set password for root . sudo passwd root Update guest's hostname. Here it's ubusvr . sudo hostnamectl set-hostname ubusvr sudo hostnamectl set-hostname ubusvr --pretty Verify if the hostname is set to ubusvr . cat /etc/machine-info Verify if the hostname is set to ubusvr . cat /etc/hostname Verify if the hostname of 127.0.1.1 is set to ubusvr . cat /etc/hosts 127 .0.0.1 localhost 127 .0.1.1 ubusrv # The following lines are desirable for IPv6 capable hosts ::1 ip6-localhost ip6-loopback fe00::0 ip6-localnet ff00::0 ip6-mcastprefix ff02::1 ip6-allnodes ff02::2 ip6-allrouters Set guest with fix ip, e.g, 11.0.1.136 . sudo vi 00 -installer-config.yaml network: ethernets: ens33: dhcp4: false addresses: - 11 .0.1.136/24 nameservers: addresses: - 11 .0.1.2 routes: - to: default via: 11 .0.1.2 version: 2 sudo netplan apply Disable swap sudo swapoff -a sudo ufw disable sudo ufw status verbose And comment the last line of swap setting in file /etc/fstab . Need reboot guest here. /dev/disk/by-uuid/df370d2a-83e5-4895-8c7f-633f2545e3fe / ext4 defaults 0 1 # /swap.img none swap sw 0 0 Setup timezone sudo ln -sf /usr/share/zoneinfo/Asia/Shanghai /etc/localtime sudo echo 'LANG=\"en_US.UTF-8\"' >> /etc/profile source /etc/profile Something like this after execute command ll /etc/localtime lrwxrwxrwx 1 root root 33 Jul 15 22 :00 /etc/localtime -> /usr/share/zoneinfo/Asia/Shanghai Kernel setting cat < /dev/null sudo apt-get update sudo apt-get install docker-ce docker-ce-cli containerd.io docker-compose-plugin sudo systemctl status docker.service sudo systemctl status containerd.service sudo groupadd docker sudo usermod -aG docker $USER Setup Containerd containerd config default | sudo tee /etc/containerd/config.toml sudo vi /etc/containerd/config.toml sudo systemctl restart containerd sudo systemctl status containerd","title":"Install Docker"},{"location":"k8s/cka_en/installation/single-local/#install-kubernetes","text":"Install kubeadm sudo apt-get update && sudo apt-get install -y apt-transport-https ca-certificates curl sudo curl -fsSLo /usr/share/keyrings/kubernetes-archive-keyring.gpg https://mirrors.aliyun.com/kubernetes/apt/doc/apt-key.gpg echo \"deb [signed-by=/usr/share/keyrings/kubernetes-archive-keyring.gpg] https://mirrors.aliyun.com/kubernetes/apt/ kubernetes-xenial main\" | sudo tee /etc/apt/sources.list.d/kubernetes.list sudo apt-get update sudo apt-get install ebtables sudo apt-get install libxtables12 sudo apt-get upgrade iptables apt policy kubeadm sudo apt-get -y install kubelet = 1 .23.8-00 kubeadm = 1 .23.8-00 kubectl = 1 .23.8-00 --allow-downgrades Setup Master Node sudo kubeadm config print init-defaults Dry run sudo kubeadm init --dry-run --pod-network-cidr = 10 .244.0.0/16 --image-repository = registry.aliyuncs.com/google_containers --kubernetes-version = v1.23.8 Run sudo kubeadm init --pod-network-cidr = 10 .244.0.0/16 --image-repository = registry.aliyuncs.com/google_containers --kubernetes-version = v1.23.8 mkdir -p $HOME /.kube sudo cp -i /etc/kubernetes/admin.conf $HOME /.kube/config sudo chown $( id -u ) : $( id -g ) $HOME /.kube/config Install Flannel. If NetworkPolicy is the case, then install Calico. Refer to the \"Install Calico or Flannel\" of below section \"Installation on Aliyun Ubuntu\". kubectl apply -f https://raw.githubusercontent.com/coreos/flannel/master/Documentation/kube-flannel.yml Setup on Worker Node Command usage: kubeadm join :6443 --token --discovery-token-ca-cert-hash < hash key generated by kubeadm init> kubeadm join 11 .0.1.136:6443 --token 6zqh1u.8b4afzc2ov4e7iuj \\ --discovery-token-ca-cert-hash sha256:815fdb9dd9e3ae0af07ffaf6c216964388098b150ef01ee3ae900c261a429d24 Setup bash auto completion on all nodes sudo apt install -y bash-completion source /usr/share/bash-completion/bash_completion source < ( kubectl completion bash ) echo \"source <(kubectl completion bash)\" >> ~/.bashrc Create alias echo 'alias k=kubectl' >>~/.bashrc echo 'complete -o default -F __start_kubectl k' >>~/.bashrc Check Cluster Status kubectl cluster-info kubectl get nodes -owide kubectl get pod -A","title":"Install Kubernetes"},{"location":"k8s/cka_en/installation/single-local/#reset-cluster","text":"CAUTION: below steps will destroy current cluster. Delete all nodes in the cluster. kubeadm reset Clean up rule of iptables . iptables -F && iptables -t nat -F && iptables -t mangle -F && iptables -X Clean up rule of IPVS if using IPVS . ipvsadm --clear","title":"Reset cluster"},{"location":"k8s/cka_en/installation/single-local/#install-helm","text":"Helm Client Installation: curl -fsSL -o get_helm.sh https://raw.githubusercontent.com/helm/helm/main/scripts/get-helm-3 chmod 700 get_helm.sh ./get_helm.sh Output: Downloading https://get.helm.sh/helm-v3.9.0-linux-amd64.tar.gz Verifying checksum... Done. Preparing to install helm into /usr/local/bin helm installed into /usr/local/bin/helm","title":"Install Helm"},{"location":"k8s/demo/cap_on_kyma/","text":"Build CAP Application on Kyma \u00b6 This is the memo of self-practice following the tutorials from Deploy Your CAP Application on SAP BTP Kyma Runtime . Prerequisites: Register account in Developer@SAP . Register trial account in SAP BTP . Tasks: Configure Kyma in SAP Business Technology Platform (SAP BTP) subaccount and prepare Kyma development environment. Create an HDI container for an SAP HANA Cloud instance on Cloud Foundry and create credentials for this SAP HANA cloud instance in Kyma cluster. Develop a business application using SAP Cloud Application Programming Model (CAP). Start on local environment, enhance it with an SAP Fiori UI, add business logic to it, and also roles and authorization check. Add a Helm chart to the application, build docker images, push them to your container registry, and deploy your application to your Kyma cluster on SAP BTP. Local environment: Applel Silicon M1 chipset macOS 12.6 (command sw_vers ) Nodejs version: CDS version: jq - for JSON processing in CLI ( brew install jq ) SAP BTP subaccount configuration \u00b6 For the SAP BTP free tier, the recommendation is as well to use an AWS-based subaccount. Kyma runtime in the free tier is only available on AWS. Choose the entitlements for the subdomain: Alert Notification: Standard plan Continuous Integration & Delivery: default (Application) or the trial (Application) or free (Application) plans which are not charged Kyma runtime: any available plan in the list (trial and free are not charged) Launchpad Service: standard (Application) or free (Application) SAP HANA Cloud: hana SAP HANA Schemas & HDI Containers: hdi-shared Set up local BTP environment \u00b6 Here we will use btp command to set up cloud environment. Details we can refer to help document Working with Environments Using the btp CLI . Download BTP CLI package btp-cli-darwin-amd64-.tar.gz via link and unpackage it. tar xvf btp-cli-darwin-amd64-.tar.gz A new subfolder darwin-amd64 will be created in current path and a bin file btp is under the subfolder. Move file btp to folder /usr/local/bin/ . sudo mv ./darwin-amd64/btp /usr/local/bin/ Log on to the subaccount on BTP. btp login --url https://cpcli.cf.eu10.hana.ondemand.com --subdomain --user Configuration file was stored at /Users/$USER/Library/Application Support/.btp/config.json . In Linux, the configuration file is on /home/$USER/.config/.btp/config.json . We can get current user via command echo $USER . Tips: Commands are executed in the target, unless specified otherwise using a parameter. To change the target, use btp target . For an explanation of the targeting mechanism, use btp help target . Get the subaccount ID in BTP and we will know that kyma and cloundfoundry are available in current trial account. btp list accounts/available-environment --subaccount Get details about an environment available for a subaccount btp get accounts/available-environment --subaccount --environment cloudfoundry --service cloudfoundry --plan standard btp get accounts/available-environment --subaccount --environment kyma --service kymaruntime --plan trial Get status running instances. Here we will also get environment ID of running instances. btp list accounts/environment-instance --subaccount Delete a running instance if needed. btp delete accounts/environment-instance --subaccount Create Kyma instance. btp create accounts/environment-instance --subaccount --environment kyma --service kymaruntime --plan trial --parameters '{\"name\": \"\"}' btp get accounts/environment-instance --subaccount Create CloudFoundry instance btp create accounts/environment-instance --subaccount --environment cloudfoundry --service cloudfoundry --plan standard --parameters '{\"instance_name\": \"\"}' btp get accounts/environment-instance --subaccount Log onto CF to create space DEV by providing API endpoint, Email and Password, which are ready in the subaccount overview page. cf login cf create-space DEV Install Homebrew \u00b6 Refer to installation guide . Set environment variables export HOMEBREW_BREW_GIT_REMOTE = \"https://mirrors.ustc.edu.cn/brew.git\" export HOMEBREW_CORE_GIT_REMOTE = \"https://mirrors.ustc.edu.cn/homebrew-core.git\" export HOMEBREW_BOTTLE_DOMAIN = \"https://mirrors.ustc.edu.cn/homebrew-bottles\" Install Homebrew /bin/bash -c \" $( curl -fsSL https://github.com/Homebrew/install/raw/HEAD/install.sh ) \" Add below in file ~/.zprofile . export HOMEBREW_BREW_GIT_REMOTE = \"https://mirrors.ustc.edu.cn/brew.git\" export HOMEBREW_CORE_GIT_REMOTE = \"https://mirrors.ustc.edu.cn/homebrew-core.git\" export HOMEBREW_BOTTLE_DOMAIN = \"https://mirrors.ustc.edu.cn/homebrew-bottles\" eval \" $( /opt/homebrew/bin/brew shellenv ) \" Make it effected. source ~/.zprofile Install kubetcl \u00b6 The kubectl installation guide curl -LO \"https://dl.k8s.io/release/ $( curl -L -s https://dl.k8s.io/release/stable.txt ) /bin/darwin/arm64/kubectl\" chmod +x ./kubectl sudo mv ./kubectl /usr/local/bin/kubectl sudo chown root: /usr/local/bin/kubectl kubectl version --client Install plugin oidc-login . curl -fsSLO https://github.com/kubernetes-sigs/krew/releases/latest/download/krew-darwin_arm64.tar.gz tar xvf krew-darwin_arm64.tar.gz ./krew-darwin_arm64 install krew Add the $HOME/.krew/bin directory to the PATH environment variable by updating ~/.zprofile . export PATH = $HOME /.krew/bin: $PATH : $PATH Make it effected source ~/.zprofile Run kubectl krew to check the installation. Install/uninstall plugin oidc-login . kubectl krew install oidc-login kubectl krew uninstall oidc-login SAP Kyma runtime \u00b6 In the Overview area of your subaccount open the Link to dashboard link which appears next to the Console URL under the Kyma Environment area. At the top left of the window choose the Clusters Overview drop down and choose your cluster. In the Clusters Overview window choose the Download Kubeconfig for your Kyma runtime to download your KUBECONFIG. Add below to ~/.zprofile to set the kubeconfig to an environment variable. export KUBECONFIG = Make above change effected. source ~/.zprofile chmod 600 Test connection between kubectl and Kyma on BTP. kubectl cluster-info Install Node.js \u00b6 Refer to installation guide brew search node brew install node@16 brew unlink node brew link node@16 node -v Install SQLite \u00b6 Install SQLite via brew . brew search sqlite brew install sqlite Add below to ~/.zprofile export PATH = /opt/homebrew/opt/sqlite/bin: $PATH Make it effected source ~/.zprofile Install Xcode \u00b6 (For macOS) We have to install Command-Line Tools for Xcode , cause some node modules need binary modules (node-gyp). xcode-select --install xcode-select --help Install Git \u00b6 Refer to installation guide . brew install git git version Install SAPUI5 \u00b6 Install the UI5 CLI. npm search --global @ui5/cli npm install --global @ui5/cli npm list --global @ui5/cli ui5 --version npm search --global grunt-cli npm install --global grunt-cli npm list --global grunt-cli Install CF CLI \u00b6 Refer to installation guide . brew install cloudfoundry/tap/cf-cli@8 cf --version Install CAP Tooling \u00b6 See the details in the CAP documentation . npm search --global @sap/cds-dk npm install --global @sap/cds-dk npm list --global @sap/cds-dk cds --version Install VSCode \u00b6 In VS Code, invoke the Command Palette ( View \u2192 Command Palette or \u21e7\u2318P) and type shell command to find the Shell Command: Install 'code' command in PATH . Install SAP CDS Language Support extension. Install SAP Fiori tools - Extension Pack extension. Install Yeoman \u00b6 Yeoman is a tool for scaffolding web apps. You\u2019ll need it if you want to carry out the tutorial Add the SAP Launchpad Service. npm install --global yo yo --version Install Docker \u00b6 brew install docker --cask Install Helm \u00b6 Refer to installation guide brew install helm Install Paketo(pack) \u00b6 Refer to installation guide . brew install buildpacks/tap/pack Install Rancher Desktop \u00b6 Download the Rancher Desktop installer for macOS from the release page . Refer to installation guide . Download tutorial \u00b6 Go to tutorial root directory and clone the code. git clone https://github.com/SAP-samples/cloud-cap-risk-management tutorial Initialize the project \u00b6 Install required Node.js modules in the app directory cpapp . cd app cds init npm install cds watch Add files to the project \u00b6 Copy the file schema.cds from templates/create-cap-application/db to the db folder of the app. It creates two entities in the namespace sap.ui.riskmanagement : Risks and Mitigations . Copy the file risk-service.cds from templates/create-cap-application/srv to the srv folder of the app. It creates a new service RiskService in the namespace sap.ui.riskmanagement . This service exposes two entities: Risks and Mitigations , which are exposing the entities of the database schema we've created in the step before. Copy the folder data from templates/create-cap-application/db to the db folder of the app. There are two comma-separated value (CSV) files that contain local data for both the Risks and the Mitigations entities. Use Fiori Application Generator (VSCode extension) to generate Risk UI with Fiori element template. The generation will create a risks and a webapp folder with a Component.js file in the app folder of the project. Copy the file risks-service-ui.cds from templates/create-ui-fiori-elements/srv to the srv folder of the app. It defines annotations to show a work list with some columns and the data from the service in the Risk UI. Edit app/risks/webapp/manifest.json file to make the header fields editable, that is, shows title and description in Risk UI. Copy the file risk-service.js from templates/cap-business-logic/srv to the srv folder of the app. It now shows the work list in Risk UI with the columns Priority and Impact with color and an icon, depending on the amount in Impact . Use Fiori Application Generator (VSCode extension) to generate Migration UI with Fiori free-style template. The generation will create a migrations and a webapp folder with a Component.js file in the app folder of the project. Update file cpapp/app/mitigations/webapp/view/Worklist.view.xml to show Description , Owner , and Timeline columns, as well as in detail object page. Till now, our risks and mitigations application have been generated by the SAP Fiori Tools Generator and can be started independently. They are launched without a launch page. Copy the file launchpage.html from templates/launchpage/app to the app folder of the app. There are two applications in the launch page with URLs that point to the respective apps. We now see the Mitigations app next to the Risks app on the launch page. Open the file srv/risk-service.cds and add role restrictions to entities. Copy the file templates/cap-roles/.cdsrc.json to the project directory cpapp . The file defines two users risk.viewer@tester.sap.com and risk.manager@tester.sap.com . The default password can be found in the file .cdsrc.json . We will see the CAP server to show above applications via link http://localhost:4004 . Prepare Kyma Development Environment \u00b6 Execute cds version to make sure the package.json is using @sap/cds 6.0.1 or newer and we have @sap/cds-dk 6.0.1 or newer globally installed. Create namespace on Kyma. kubectl create namespace risk-management Switch to the namespace. kubectl config set-context --current --namespace risk-management Create container registry secret. Copy the folder scripts from templates/Kyma-Prepare-Dev-Environment to the project root folder cpapp . In the root folder cpapp of the project, run the script to create the secret. ./scripts/create-container-registry-secret.sh Need provide below input: docker-server = https://registry-1.docker.io docker-username = docker-email = docker-password = Verify kubectl get secret Set Up SAP HANA Cloud for Kyma \u00b6 Add SAP HANA support to your project. This adds the db module for SAP HANA access to the package.json file. Execute the command below in the project root directory cpapp . cds add hana --for production Verify the access to both CF and Kyma by executing below commands. cf login kubectl cluster-info Create HANA Cloud instance cpapp-db in CloudFoundry DEV namespace. The admin user id is DBADMIN . In the root folder cpapp of the project, execute: ./scripts/create-db-secret.sh cpapp-db Get the host name pattern of the cluster with the following command. Result looks like *.c-.sap.kyma.ondemand.com . kubectl get gateway -n kyma-system kyma-gateway -o jsonpath = '{.spec.servers[0].hosts[0]}' The script will: Create service key cpapp-db-key for HANA Cloud service instance cpapp-db as . Create Kubernetes secret cpapp-db for HANA DB instance. View it using kubectl get secret cpapp-db -o yaml . User Authentication and Authorization (XSUAA) Setup \u00b6 Set up XSUAA. cds add xsuaa --for production Above command will do: Adds the XSUAA service to the package.json file of the project Creates the XSUAA security configuration xs-security.json for the project Add Helm Chart \u00b6 Add Helm Chart. cds add helm Get docker server URL by command: cat ~/.docker/config.json Get the image pull secret for container registry. In the demo, it's container-registry . kubectl get secret Get the host name pattern of the cluster. kubectl get gateway -n kyma-system kyma-gateway -o jsonpath = '{.spec.servers[0].hosts[0]}' Open the file chart/values.yaml : Replace the placeholder with docker server URL https://docker.io/ . Set imagePullSecret with value name: container-registry . Add host name of the cluster without leading *. . Add the binding db pointing to the SAP HANA Cloud instance secret cpapp-db . Point the binding hana of the SAP HANA Cloud instance secret cpapp-db . Add the Authorization and Trust Management service to allow user login. Deploy CAP Application to Kyma \u00b6 Build docker image. CONTAINER_REGISTRY = https://index.docker.io/v1 CONTAINER_REGISTRY = https://registry-1.docker.io/yuhuihu CONTAINER_REGISTRY = yuhuihu CAP build. cds build --production Build CAP service. pack build $CONTAINER_REGISTRY /cpapp-srv --path gen/srv \\ --buildpack gcr.io/paketo-buildpacks/nodejs \\ --builder paketobuildpacks/builder:base","title":"Build CAP Application on Kyma"},{"location":"k8s/demo/cap_on_kyma/#build-cap-application-on-kyma","text":"This is the memo of self-practice following the tutorials from Deploy Your CAP Application on SAP BTP Kyma Runtime . Prerequisites: Register account in Developer@SAP . Register trial account in SAP BTP . Tasks: Configure Kyma in SAP Business Technology Platform (SAP BTP) subaccount and prepare Kyma development environment. Create an HDI container for an SAP HANA Cloud instance on Cloud Foundry and create credentials for this SAP HANA cloud instance in Kyma cluster. Develop a business application using SAP Cloud Application Programming Model (CAP). Start on local environment, enhance it with an SAP Fiori UI, add business logic to it, and also roles and authorization check. Add a Helm chart to the application, build docker images, push them to your container registry, and deploy your application to your Kyma cluster on SAP BTP. Local environment: Applel Silicon M1 chipset macOS 12.6 (command sw_vers ) Nodejs version: CDS version: jq - for JSON processing in CLI ( brew install jq )","title":"Build CAP Application on Kyma"},{"location":"k8s/demo/cap_on_kyma/#sap-btp-subaccount-configuration","text":"For the SAP BTP free tier, the recommendation is as well to use an AWS-based subaccount. Kyma runtime in the free tier is only available on AWS. Choose the entitlements for the subdomain: Alert Notification: Standard plan Continuous Integration & Delivery: default (Application) or the trial (Application) or free (Application) plans which are not charged Kyma runtime: any available plan in the list (trial and free are not charged) Launchpad Service: standard (Application) or free (Application) SAP HANA Cloud: hana SAP HANA Schemas & HDI Containers: hdi-shared","title":"SAP BTP subaccount configuration"},{"location":"k8s/demo/cap_on_kyma/#set-up-local-btp-environment","text":"Here we will use btp command to set up cloud environment. Details we can refer to help document Working with Environments Using the btp CLI . Download BTP CLI package btp-cli-darwin-amd64-.tar.gz via link and unpackage it. tar xvf btp-cli-darwin-amd64-.tar.gz A new subfolder darwin-amd64 will be created in current path and a bin file btp is under the subfolder. Move file btp to folder /usr/local/bin/ . sudo mv ./darwin-amd64/btp /usr/local/bin/ Log on to the subaccount on BTP. btp login --url https://cpcli.cf.eu10.hana.ondemand.com --subdomain --user Configuration file was stored at /Users/$USER/Library/Application Support/.btp/config.json . In Linux, the configuration file is on /home/$USER/.config/.btp/config.json . We can get current user via command echo $USER . Tips: Commands are executed in the target, unless specified otherwise using a parameter. To change the target, use btp target . For an explanation of the targeting mechanism, use btp help target . Get the subaccount ID in BTP and we will know that kyma and cloundfoundry are available in current trial account. btp list accounts/available-environment --subaccount Get details about an environment available for a subaccount btp get accounts/available-environment --subaccount --environment cloudfoundry --service cloudfoundry --plan standard btp get accounts/available-environment --subaccount --environment kyma --service kymaruntime --plan trial Get status running instances. Here we will also get environment ID of running instances. btp list accounts/environment-instance --subaccount Delete a running instance if needed. btp delete accounts/environment-instance --subaccount Create Kyma instance. btp create accounts/environment-instance --subaccount --environment kyma --service kymaruntime --plan trial --parameters '{\"name\": \"\"}' btp get accounts/environment-instance --subaccount Create CloudFoundry instance btp create accounts/environment-instance --subaccount --environment cloudfoundry --service cloudfoundry --plan standard --parameters '{\"instance_name\": \"\"}' btp get accounts/environment-instance --subaccount Log onto CF to create space DEV by providing API endpoint, Email and Password, which are ready in the subaccount overview page. cf login cf create-space DEV","title":"Set up local BTP environment"},{"location":"k8s/demo/cap_on_kyma/#install-homebrew","text":"Refer to installation guide . Set environment variables export HOMEBREW_BREW_GIT_REMOTE = \"https://mirrors.ustc.edu.cn/brew.git\" export HOMEBREW_CORE_GIT_REMOTE = \"https://mirrors.ustc.edu.cn/homebrew-core.git\" export HOMEBREW_BOTTLE_DOMAIN = \"https://mirrors.ustc.edu.cn/homebrew-bottles\" Install Homebrew /bin/bash -c \" $( curl -fsSL https://github.com/Homebrew/install/raw/HEAD/install.sh ) \" Add below in file ~/.zprofile . export HOMEBREW_BREW_GIT_REMOTE = \"https://mirrors.ustc.edu.cn/brew.git\" export HOMEBREW_CORE_GIT_REMOTE = \"https://mirrors.ustc.edu.cn/homebrew-core.git\" export HOMEBREW_BOTTLE_DOMAIN = \"https://mirrors.ustc.edu.cn/homebrew-bottles\" eval \" $( /opt/homebrew/bin/brew shellenv ) \" Make it effected. source ~/.zprofile","title":"Install Homebrew"},{"location":"k8s/demo/cap_on_kyma/#install-kubetcl","text":"The kubectl installation guide curl -LO \"https://dl.k8s.io/release/ $( curl -L -s https://dl.k8s.io/release/stable.txt ) /bin/darwin/arm64/kubectl\" chmod +x ./kubectl sudo mv ./kubectl /usr/local/bin/kubectl sudo chown root: /usr/local/bin/kubectl kubectl version --client Install plugin oidc-login . curl -fsSLO https://github.com/kubernetes-sigs/krew/releases/latest/download/krew-darwin_arm64.tar.gz tar xvf krew-darwin_arm64.tar.gz ./krew-darwin_arm64 install krew Add the $HOME/.krew/bin directory to the PATH environment variable by updating ~/.zprofile . export PATH = $HOME /.krew/bin: $PATH : $PATH Make it effected source ~/.zprofile Run kubectl krew to check the installation. Install/uninstall plugin oidc-login . kubectl krew install oidc-login kubectl krew uninstall oidc-login","title":"Install kubetcl"},{"location":"k8s/demo/cap_on_kyma/#sap-kyma-runtime","text":"In the Overview area of your subaccount open the Link to dashboard link which appears next to the Console URL under the Kyma Environment area. At the top left of the window choose the Clusters Overview drop down and choose your cluster. In the Clusters Overview window choose the Download Kubeconfig for your Kyma runtime to download your KUBECONFIG. Add below to ~/.zprofile to set the kubeconfig to an environment variable. export KUBECONFIG = Make above change effected. source ~/.zprofile chmod 600 Test connection between kubectl and Kyma on BTP. kubectl cluster-info","title":"SAP Kyma runtime"},{"location":"k8s/demo/cap_on_kyma/#install-nodejs","text":"Refer to installation guide brew search node brew install node@16 brew unlink node brew link node@16 node -v","title":"Install Node.js"},{"location":"k8s/demo/cap_on_kyma/#install-sqlite","text":"Install SQLite via brew . brew search sqlite brew install sqlite Add below to ~/.zprofile export PATH = /opt/homebrew/opt/sqlite/bin: $PATH Make it effected source ~/.zprofile","title":"Install SQLite"},{"location":"k8s/demo/cap_on_kyma/#install-xcode","text":"(For macOS) We have to install Command-Line Tools for Xcode , cause some node modules need binary modules (node-gyp). xcode-select --install xcode-select --help","title":"Install Xcode"},{"location":"k8s/demo/cap_on_kyma/#install-git","text":"Refer to installation guide . brew install git git version","title":"Install Git"},{"location":"k8s/demo/cap_on_kyma/#install-sapui5","text":"Install the UI5 CLI. npm search --global @ui5/cli npm install --global @ui5/cli npm list --global @ui5/cli ui5 --version npm search --global grunt-cli npm install --global grunt-cli npm list --global grunt-cli","title":"Install SAPUI5"},{"location":"k8s/demo/cap_on_kyma/#install-cf-cli","text":"Refer to installation guide . brew install cloudfoundry/tap/cf-cli@8 cf --version","title":"Install CF CLI"},{"location":"k8s/demo/cap_on_kyma/#install-cap-tooling","text":"See the details in the CAP documentation . npm search --global @sap/cds-dk npm install --global @sap/cds-dk npm list --global @sap/cds-dk cds --version","title":"Install CAP Tooling"},{"location":"k8s/demo/cap_on_kyma/#install-vscode","text":"In VS Code, invoke the Command Palette ( View \u2192 Command Palette or \u21e7\u2318P) and type shell command to find the Shell Command: Install 'code' command in PATH . Install SAP CDS Language Support extension. Install SAP Fiori tools - Extension Pack extension.","title":"Install VSCode"},{"location":"k8s/demo/cap_on_kyma/#install-yeoman","text":"Yeoman is a tool for scaffolding web apps. You\u2019ll need it if you want to carry out the tutorial Add the SAP Launchpad Service. npm install --global yo yo --version","title":"Install Yeoman"},{"location":"k8s/demo/cap_on_kyma/#install-docker","text":"brew install docker --cask","title":"Install Docker"},{"location":"k8s/demo/cap_on_kyma/#install-helm","text":"Refer to installation guide brew install helm","title":"Install Helm"},{"location":"k8s/demo/cap_on_kyma/#install-paketopack","text":"Refer to installation guide . brew install buildpacks/tap/pack","title":"Install Paketo(pack)"},{"location":"k8s/demo/cap_on_kyma/#install-rancher-desktop","text":"Download the Rancher Desktop installer for macOS from the release page . Refer to installation guide .","title":"Install Rancher Desktop"},{"location":"k8s/demo/cap_on_kyma/#download-tutorial","text":"Go to tutorial root directory and clone the code. git clone https://github.com/SAP-samples/cloud-cap-risk-management tutorial","title":"Download tutorial"},{"location":"k8s/demo/cap_on_kyma/#initialize-the-project","text":"Install required Node.js modules in the app directory cpapp . cd app cds init npm install cds watch","title":"Initialize the project"},{"location":"k8s/demo/cap_on_kyma/#add-files-to-the-project","text":"Copy the file schema.cds from templates/create-cap-application/db to the db folder of the app. It creates two entities in the namespace sap.ui.riskmanagement : Risks and Mitigations . Copy the file risk-service.cds from templates/create-cap-application/srv to the srv folder of the app. It creates a new service RiskService in the namespace sap.ui.riskmanagement . This service exposes two entities: Risks and Mitigations , which are exposing the entities of the database schema we've created in the step before. Copy the folder data from templates/create-cap-application/db to the db folder of the app. There are two comma-separated value (CSV) files that contain local data for both the Risks and the Mitigations entities. Use Fiori Application Generator (VSCode extension) to generate Risk UI with Fiori element template. The generation will create a risks and a webapp folder with a Component.js file in the app folder of the project. Copy the file risks-service-ui.cds from templates/create-ui-fiori-elements/srv to the srv folder of the app. It defines annotations to show a work list with some columns and the data from the service in the Risk UI. Edit app/risks/webapp/manifest.json file to make the header fields editable, that is, shows title and description in Risk UI. Copy the file risk-service.js from templates/cap-business-logic/srv to the srv folder of the app. It now shows the work list in Risk UI with the columns Priority and Impact with color and an icon, depending on the amount in Impact . Use Fiori Application Generator (VSCode extension) to generate Migration UI with Fiori free-style template. The generation will create a migrations and a webapp folder with a Component.js file in the app folder of the project. Update file cpapp/app/mitigations/webapp/view/Worklist.view.xml to show Description , Owner , and Timeline columns, as well as in detail object page. Till now, our risks and mitigations application have been generated by the SAP Fiori Tools Generator and can be started independently. They are launched without a launch page. Copy the file launchpage.html from templates/launchpage/app to the app folder of the app. There are two applications in the launch page with URLs that point to the respective apps. We now see the Mitigations app next to the Risks app on the launch page. Open the file srv/risk-service.cds and add role restrictions to entities. Copy the file templates/cap-roles/.cdsrc.json to the project directory cpapp . The file defines two users risk.viewer@tester.sap.com and risk.manager@tester.sap.com . The default password can be found in the file .cdsrc.json . We will see the CAP server to show above applications via link http://localhost:4004 .","title":"Add files to the project"},{"location":"k8s/demo/cap_on_kyma/#prepare-kyma-development-environment","text":"Execute cds version to make sure the package.json is using @sap/cds 6.0.1 or newer and we have @sap/cds-dk 6.0.1 or newer globally installed. Create namespace on Kyma. kubectl create namespace risk-management Switch to the namespace. kubectl config set-context --current --namespace risk-management Create container registry secret. Copy the folder scripts from templates/Kyma-Prepare-Dev-Environment to the project root folder cpapp . In the root folder cpapp of the project, run the script to create the secret. ./scripts/create-container-registry-secret.sh Need provide below input: docker-server = https://registry-1.docker.io docker-username = docker-email = docker-password = Verify kubectl get secret","title":"Prepare Kyma Development Environment"},{"location":"k8s/demo/cap_on_kyma/#set-up-sap-hana-cloud-for-kyma","text":"Add SAP HANA support to your project. This adds the db module for SAP HANA access to the package.json file. Execute the command below in the project root directory cpapp . cds add hana --for production Verify the access to both CF and Kyma by executing below commands. cf login kubectl cluster-info Create HANA Cloud instance cpapp-db in CloudFoundry DEV namespace. The admin user id is DBADMIN . In the root folder cpapp of the project, execute: ./scripts/create-db-secret.sh cpapp-db Get the host name pattern of the cluster with the following command. Result looks like *.c-.sap.kyma.ondemand.com . kubectl get gateway -n kyma-system kyma-gateway -o jsonpath = '{.spec.servers[0].hosts[0]}' The script will: Create service key cpapp-db-key for HANA Cloud service instance cpapp-db as . Create Kubernetes secret cpapp-db for HANA DB instance. View it using kubectl get secret cpapp-db -o yaml .","title":"Set Up SAP HANA Cloud for Kyma"},{"location":"k8s/demo/cap_on_kyma/#user-authentication-and-authorization-xsuaa-setup","text":"Set up XSUAA. cds add xsuaa --for production Above command will do: Adds the XSUAA service to the package.json file of the project Creates the XSUAA security configuration xs-security.json for the project","title":"User Authentication and Authorization (XSUAA) Setup"},{"location":"k8s/demo/cap_on_kyma/#add-helm-chart","text":"Add Helm Chart. cds add helm Get docker server URL by command: cat ~/.docker/config.json Get the image pull secret for container registry. In the demo, it's container-registry . kubectl get secret Get the host name pattern of the cluster. kubectl get gateway -n kyma-system kyma-gateway -o jsonpath = '{.spec.servers[0].hosts[0]}' Open the file chart/values.yaml : Replace the placeholder with docker server URL https://docker.io/ . Set imagePullSecret with value name: container-registry . Add host name of the cluster without leading *. . Add the binding db pointing to the SAP HANA Cloud instance secret cpapp-db . Point the binding hana of the SAP HANA Cloud instance secret cpapp-db . Add the Authorization and Trust Management service to allow user login.","title":"Add Helm Chart"},{"location":"k8s/demo/cap_on_kyma/#deploy-cap-application-to-kyma","text":"Build docker image. CONTAINER_REGISTRY = https://index.docker.io/v1 CONTAINER_REGISTRY = https://registry-1.docker.io/yuhuihu CONTAINER_REGISTRY = yuhuihu CAP build. cds build --production Build CAP service. pack build $CONTAINER_REGISTRY /cpapp-srv --path gen/srv \\ --buildpack gcr.io/paketo-buildpacks/nodejs \\ --builder paketobuildpacks/builder:base","title":"Deploy CAP Application to Kyma"},{"location":"linux/","text":"Content \u00b6 Memo Linux SRE is online training hosted by Magedu that I am taking part in. SUSE Linux Administration is the learning memo for certificate of SLES Administration. SUSE Enterprise Storage Foundation is the learning memo for certificate of SES Basic Ops and Data Access. Linux SRE SUSE Linux Adminstration SUSE Enterprise Storage Foundation","title":"Index"},{"location":"linux/#content","text":"Memo Linux SRE is online training hosted by Magedu that I am taking part in. SUSE Linux Administration is the learning memo for certificate of SLES Administration. SUSE Enterprise Storage Foundation is the learning memo for certificate of SES Basic Ops and Data Access. Linux SRE SUSE Linux Adminstration SUSE Enterprise Storage Foundation","title":"Content"},{"location":"linux/Administration/01/","text":"Linux File System Overview \u00b6 Linux File System Overview \u00b6 Filesystem Hierarchy Standard (FHS), which is part of the LSB (Linux Standards Base) specifications. The Root directory \"/\". Refers to the highest layer of the file system tree. This root partition is mounted first at system boot. All programs that are run at system startup must be in this partition. The following directories must be in the root partition: /bin - User binaries. \u57fa\u672c\u7a0b\u5e8f Contains executables required when no other file systems are mounted. For example, programs required for system booting, working with files and configuration. /bin/bash - The bash shell /bin/cat - Display file contents /bin/cp - Copy files /bin/dd - Copy files byte-wise /bin/gzip - Compress files /bin/mount - Mount file systems /bin/rm - Delete files /bin/vi - Edit files /sbin - System binaries. \u7cfb\u7edf\u7a0b\u5e8f Contains programs important for system administration. \u5b58\u653e\u7cfb\u7edf\u7ba1\u7406\u7684\u7a0b\u5e8f Typically are intended to be run by the root user and therefore it is not in the regular users path. \u9ed8\u8ba4\u662froot\u7528\u6237\u6709\u6743\u9650\u6267\u884c Some important files: /sbin/yast - Administration tool /sbin/fdisk* - Modifies partitions /sbin/fsck* - File system check \u4e0d\u80fd\u5728\u8fd0\u884c\u7684\u7cfb\u7edf\u4e0a\u9762\u76f4\u63a5\u6267\u884cfsck\uff0c\u635f\u574f\u6839\u6587\u4ef6\u7cfb\u7edf\uff0c\u9700\u8981umount /sbin/mkfs - Creates file systems /sbin/shutdown - Shuts down the system /dev - Device files Each system hardware component is represented (except network cards, which are kernel modules). \u4ee5\u592a\u7f51\u5361\u662f\u5185\u6838\u6a21\u5757\uff0c\u5176\u4ed6\u786c\u4ef6\u90fd\u4ee5\u8bbe\u5907dev\u7684\u65b9\u5f0f\u5c55\u73b0 Applications read from and write to these files to address hardware components. Two kinds of device files: Character-oriented \u2013 Sequential devices (printer, tape and mouse) \u5b57\u7b26\u8bbe\u5907 Block-oriented \u2013 Hard disks and DVDs \u5757\u8bbe\u5907 Connections to device drivers are implemented in the kernel using channels called major device numbers. \u4e0e\u8bbe\u5907\u9a71\u52a8\u7a0b\u5e8f\u7684\u8fde\u63a5\u901a\u8fc7\u5185\u6838\u4e2d\u79f0\u4e3a\u4e3b\u8bbe\u5907\u53f7\u7684\u901a\u9053\u5b9e\u73b0\u3002 When using ls -l the file size is replaced with the device numbers, such as 8, 0. In the past these files were created manually using the mknod command. Today they are created automatically (by udev) when the devices are discovered by the kernel. Some important device files: Null device: - /dev/null Zero device: - /dev/zero System Console: - /dev/console Virtual Terminal: - /dev/tty1 Serial ports - /dev/ttyS0 Parallel port: - /dev/lp0 Floppy disk drive: - /dev/fd0 Hard drive: - /dev/sda Hard disk partition: - /dev/sda1 CD-ROM drive: - /dev/scd0 /etc - Configuration files Contains system and services configuration files. \u5b58\u653e\u7cfb\u7edf\u548c\u670d\u52a1\u7684\u914d\u7f6e\u6587\u4ef6 Most of these files are ASCII files. \u5927\u90e8\u5206\u90fd\u662fASCII\u6587\u4ef6 Normal users can read most of these by default. This can be a security issue since some of these files contain passwords so it important that these files are only readable by the rootuser. \u666e\u901a\u7528\u6237\u53ef\u4ee5\u9ed8\u8ba4\u8bfb\u53d6\u5176\u4e2d\u7684\u5927\u90e8\u5206\u5185\u5bb9\u3002 \u8fd9\u53ef\u80fd\u662f\u4e00\u4e2a\u5b89\u5168\u95ee\u9898\uff0c\u56e0\u4e3a\u5176\u4e2d\u4e00\u4e9b\u6587\u4ef6\u5305\u542b\u5bc6\u7801\uff0c\u56e0\u6b64\u91cd\u8981\u7684\u662f\u8fd9\u4e9b\u6587\u4ef6\u53ea\u80fd\u7531root\u7528\u6237\u8bfb\u53d6 No executables can be put here according to the FHS, however subdirectories may contain shell scripts. \u6839\u636eFHS\uff0c\u6b64\u5904\u4e0d\u80fd\u653e\u7f6e\u4efb\u4f55\u53ef\u6267\u884c\u6587\u4ef6\uff0c\u4f46\u5b50\u76ee\u5f55\u53ef\u80fd\u5305\u542bshell\u811a\u672c\u3002 Almost every installed service has at least one configuration file in /etc or a subdirectory. \u51e0\u4e4e\u6bcf\u4e2a\u5df2\u5b89\u88c5\u7684\u670d\u52a1\u5728/ etc\u6216\u5b50\u76ee\u5f55\u4e2d\u81f3\u5c11\u6709\u4e00\u4e2a\u914d\u7f6e\u6587\u4ef6\u3002 Some important configuration files: /etc/SuSE-release - Version of installed system /etc/DIR_COLORS - Colors for the ls command /etc/fstab - For file systems to be mounted /etc/profile - Shell login script /etc/passwd - User database, except passwords /etc/shadow - Password and password info /etc/group - Database of user groups /etc/cups/* - For the CUPS printing system (CUPS=Common UNIX Printing System) /etc/hosts - Host names to IP addresses /etc/motd - Message after login /etc/issue - Message before login /etc/sysconfig/* - System configuration files /lib - Libraries. Many programs have common functions they need. The functions can be kept in a shared library. Libraries are called shared objects and end with the .so extension. \u5171\u4eab\u5e93 Libraries in /lib are used by programs in /bin and /sbin . There are additional libraries in subdirectories. Kernel modules are located in /lib/modules . /lib64 - 64-Bit Libraries. Similar to the /lib directory. This is an architecture dependent directory. Some systems support different binary formats and keep different versions of the same shared library. /usr - Contains application programs, graphical interface files, libraries, local programs, documentation and more. /usr means Unix System Resources. Examples: /usr/X11R6/ - X Window System Files /usr/bin/ - Almost all executables /usr/lib/ - Libraries and application directories /usr/local/ - Locally installed programs (i.e. on local system if /usr is mounted from the network). The content is not overwritten by system updates. \u4e0b\u97623\u4e2a\u76ee\u5f55\u5728\u521d\u59cb\u5b89\u88c5\u540e\u662f\u7a7a\u7684 /usr/local/bin - /usr/local/sbin - /usr/local/lib - /usr/sbin/ - System administration programs /usr/share/doc/ - Documentation /usr/src/ - Source code of kernel and programs /usr/src/linux - /usr/share/man/ - Manual pages /opt - Optional Application Directory Where optional or third party applications that are not considered to be \u201cpart of the distribution\u201d store their static files. Applications considered to be \u201cpart of the distribution\u201d are usually installed under /usr/lib/ rather than /opt . At installation a directory is created for each application's files with the name of the application. Example: /opt/novell - /boot - The Boot Directory /boot/grub2 - Contains static boot loader files for GRUB2. (GRUB = Grand Unified Boot Loader) Contains the kernel and initrd file identified with the links vmlinuz and initrd. /root - Administrator's Home Directory The root user's home directory. Not under /home with regular users' home directories. Needs to be in the root partition so that root can always log in with his configured environment. /home - User Directories Every system user has an assigned file area which becomes the current working directory after log in. By default they exist in /home . The files and directories in /home could be in a separate partition or on another computer on the network. The user profile and configuration files are found here: .profile - Private user login script .bashrc - Configuration file for bash .bash_history - Previous commands run in bash /run/media//* - Mount Point for Removable Media SLE 12 creates directories here for mounting removable media. The name depends on the device that is mounted/discovered. Examples: /run/media/media_name/ (Created if labeled media is inserted) /run/media/cdrom/ - /run/media/dvd/ - /run/media/usbdisk/ - /mnt - Temporarily Mounted File Systems \u6587\u4ef6\u7cfb\u7edf\u4e34\u65f6\u6302\u8f7d\u70b9 Standard directory for integrating file systems that are used temporarily. File systems are mounted using the mount command and removed using the umount command. Subdirectories do not exist by default and are not automatically created. /srv - Service Data Directories Contains subdirectories for various services. Examples: \u5b58\u653e\u5404\u79cd\u670d\u52a1\u7684\u6570\u636e /srv/www - for the Apache Web Server /srv/ftp - for an FTP server /var - Variable Files Contains files that can be modified while the system is running. \u5728\u7cfb\u7edf\u8fd0\u884c\u8fc7\u7a0b\u4e2d\u4f1a\u88ab\u4fee\u6539\u7684\u6587\u4ef6 Important subdirectories: /var/lib/ - Variable libraries, like databases \u53ef\u53d8\u5e93\u6587\u4ef6 /var/log/ - Services log files \u65e5\u5fd7\u6587\u4ef6 /var/run/ - Information on running processes \u8fd0\u884c\u4e2d\u7684\u7ebf\u7a0b\u7684\u4fe1\u606f /var/spool/ - Queues (printers, email) /var/spool/mail - /var/spool/cron - /var/lock/ - Lock files for multiuser access /var/cache - /var/mail - /tmp - Temporary Area Where programs create temporary files while they are running /proc - Process Files A virtual file system that exists only in memory and is used to display the current state of processes running on the system. (Takes no space - file size always 0) \u865a\u62df\u6587\u4ef6\u7cfb\u7edf\uff0c\u4e0d\u5360\u95f4\uff0c\u5927\u5c0f* \u59cb\u7ec8\u96f6\uff0c\u663e\u793a\u5f53\u524d\u8fdb\u7a0b\u7684\u72b6\u6001\u4fe1\u606f Directories containing information about individual processes are named according to the PID number of the process. Some values can be modified to change how things are running in real time. Any changes made are lost at reboot. Examples: \u6709\u4e9b\u503c\u53ef\u4ee5\u4e34\u65f6\u5728\u7ebf\u66f4\u6539\u751f\u6548\uff0c\u4f46\u91cd\u542f\u540e\u4e22\u5931 /proc/cpuinfo/ - Processor information /proc/dma/ - Use of DMA ports /proc/interrupts/ - Use of interrupts /proc/ioports/ - Use of I/O ports /proc/filesystems/ - File system formats the kernel knows /proc/modules/ - Active modules /proc/mounts/ - Mounted file systems /proc/net/* - Network information and statistics /proc/partitions/ - Existing partitions /proc/bus/pci/ - Connected PCI devices /proc/bus/scsi/ - Connected SCSI devices /proc/sys/* - System and kernel information /proc/version - Kernel version /sys - System Information Directory A virtual file system that exists only in memory. Takes no space so file size always 0 \u865a\u62df\u6587\u4ef6\u7cfb\u7edf Provides information on: hardware buses hardware devices active devices drivers Lab: Explore Filesystem Hierarchy \u00b6 Show the directory structure of the /data folder hierarchy of current logon user: mySUSE:~ # tree /data /data \u2514\u2500\u2500 linktype \u251c\u2500\u2500 file \u251c\u2500\u2500 hardlinkfile1 \u251c\u2500\u2500 hardlinkfile2 \u251c\u2500\u2500 symlinkfile1 -> file \u251c\u2500\u2500 symlinkfile1-1 -> symlinkfile1 \u2514\u2500\u2500 symlinkfile2 -> file Show only directories in the /data hierarchhy, not the files in them: mySUSE:~ # tree -d /data /data \u2514\u2500\u2500 linktype Show the files and directories in the /data hierarchy, including the full path and filename of each object. mySUSE:~ # tree -f /data /data \u2514\u2500\u2500 /data/linktype \u251c\u2500\u2500 /data/linktype/file \u251c\u2500\u2500 /data/linktype/hardlinkfile1 \u251c\u2500\u2500 /data/linktype/hardlinkfile2 \u251c\u2500\u2500 /data/linktype/symlinkfile1 -> file \u251c\u2500\u2500 /data/linktype/symlinkfile1-1 -> symlinkfile1 \u2514\u2500\u2500 /data/linktype/symlinkfile2 -> file Seven Different types of files \u00b6 Normal files , examples: ASCII text files Executable files Graphics files Directories Organize files on the disk Contain files and subdirectories Implement the hierarchical file system Links Hard links Secondary file names for files on the disk Multiple file names referencing a single inode Referenced file must reside in the same file system Symbolic links: References to other files on the disk The inode contains a reference to another file name .Referenced files can exist in the same file system or in other file systems A symbolic link can reference a non-existent file (broken link) Sockets - Used for two-way communication between processes. \u5957\u63a5\u5b57 Pipes (FIFOs) - Used for one-way communication from one process to another. \u7ba1\u9053 Block Devices \u5757\u8bbe\u5907 Character Devices \u5b57\u7b26\u8bbe\u5907 Linux Link Type \u00b6 Hard links : A hard link is a directory reference, or pointer, to a file on a storage volume. The name associated with the file is a label stored in a directory structure that refers the operating system to the file data. As such, more than one name can be associated with the same file. When accessed through different names, any changes made will affect the same file data. \u786c\u94fe\u63a5\u662f\u5b58\u50a8\u5377\u4e0a\u6587\u4ef6\u7684\u76ee\u5f55\u5f15\u7528\u6216\u6307\u9488\u3002 \u6587\u4ef6\u540d\u662f\u5b58\u50a8\u5728\u76ee\u5f55\u7ed3\u6784\u4e2d\u7684\u6807\u7b7e\uff0c\u76ee\u5f55\u7ed3\u6784\u6307\u5411\u6587\u4ef6\u6570\u636e\u3002 \u56e0\u6b64\uff0c\u53ef\u4ee5\u5c06\u591a\u4e2a\u6587\u4ef6\u540d\u4e0e\u540c\u4e00\u6587\u4ef6\u5173\u8054\u3002 \u901a\u8fc7\u4e0d\u540c\u7684\u6587\u4ef6\u540d\u8bbf\u95ee\u65f6\uff0c\u6240\u505a\u7684\u4efb\u4f55\u66f4\u6539\u90fd\u662f\u9488\u5bf9\u6e90\u6587\u4ef6\u6570\u636e\u3002 Symbolic links : A symbolic link contains a text string that is interpreted and followed by the operating system as a path to another file or directory. It is a file on its own and can exist independently of its target. If a symbolic link is deleted, its target remains unaffected. If the target is moved, renamed or deleted, any symbolic link that used to point to it continues to exist but now points to a non-existing file. \u7b26\u53f7\u94fe\u63a5\u5305\u542b\u4e00\u4e2a\u6587\u672c\u5b57\u7b26\u4e32\uff0c\u64cd\u4f5c\u7cfb\u7edf\u5c06\u5176\u89e3\u91ca\u5e76\u4f5c\u4e3a\u53e6\u4e00\u4e2a\u6587\u4ef6\u6216\u76ee\u5f55\u7684\u8def\u5f84\u3002 \u5b83\u672c\u8eab\u5c31\u662f\u4e00\u4e2a\u6587\u4ef6\uff0c\u53ef\u4ee5\u72ec\u7acb\u4e8e\u76ee\u6807\u800c\u5b58\u5728\u3002 \u5982\u679c\u5220\u9664\u4e86\u7b26\u53f7\u94fe\u63a5\uff0c\u5219\u5176\u76ee\u6807\u4e0d\u53d7\u5f71\u54cd\u3002 \u5982\u679c\u79fb\u52a8\uff0c\u91cd\u547d\u540d\u6216\u5220\u9664\u76ee\u6807\uff0c\u5219\u7528\u4e8e\u6307\u5411\u5b83\u7684\u4efb\u4f55\u7b26\u53f7\u94fe\u63a5\u5c06\u7ee7\u7eed\u5b58\u5728\uff0c\u4f46\u73b0\u5728\u6307\u5411\u4e0d\u5b58\u5728\u7684\u6587\u4ef6\u3002 Hard links can only be used when both the file and the link are in the same file system (on the same partition), because inode numbers are only unique within the same file system. You create a hard link by using the ln command, which points to the inode of an already existing file. Thereafter, the file can be accessed under both names\u2013that of the file and that of the link, and you can no longer discern which name existed first or how the original file and the link differ. \u4ec5\u5f53\u6587\u4ef6\u548c\u94fe\u63a5\u6587\u4ef6\u4f4d\u4e8e\u540c\u4e00\u6587\u4ef6\u7cfb\u7edf\uff08\u5728\u540c\u4e00\u5206\u533a\u4e0a\uff09\u65f6\uff0c\u624d\u80fd\u4f7f\u7528\u786c\u94fe\u63a5\uff0c\u56e0\u4e3ainode\u7f16\u53f7\u5728\u540c\u4e00\u6587\u4ef6\u7cfb\u7edf\u4e2d\u4ec5\u662f\u552f\u4e00\u7684\u3002 \u60a8\u53ef\u4ee5\u4f7f\u7528ln\u547d\u4ee4\u521b\u5efa\u786c\u94fe\u63a5\uff0c\u8be5\u547d\u4ee4\u6307\u5411\u5df2\u5b58\u5728\u6587\u4ef6\u7684inode\u3002 \u6b64\u540e\uff0c\u53ef\u4ee5\u5728\u6587\u4ef6\u7684\u540d\u79f0\u548c\u94fe\u63a5\u7684\u540d\u79f0\u4e0b\u8bbf\u95ee\u6587\u4ef6\uff0c\u5e76\u4e14\u65e0\u6cd5\u518d\u8bc6\u522b\u9996\u5148\u5b58\u5728\u7684\u540d\u79f0\u6216\u539f\u59cb\u6587\u4ef6\u548c\u94fe\u63a5\u7684\u4e0d\u540c\u4e4b\u5904\u3002 You can create a symbolic link with the ln command and the -s option. A symbolic link is assigned its own inode\u2014the link refers to a file, so a distinction can always be made between the link and the actual file. \u8f6f\u8fde\u63a5\u53ef\u4ee5\u9488\u5bf9\u76ee\u5f55\uff0c\u786c\u8fde\u63a5\u53ea\u80fd\u9488\u5bf9\u6587\u4ef6\u3002 A file system is essentially a database that is used to keep track of files in a volume. For normal files, data blocks are allocated to store the file's data, an inode is allocated to point to the data blocks as well as store the metadata about the file and then a file name is assigned to the inode. A hard link is a secondary file name associated with an existing inode. For symbolic links, a new inode is allocated with a new file name associated with it but the inode references another file name rather than referencing datablocks. \u6587\u4ef6\u7cfb\u7edf\u672c\u8d28\u4e0a\u662f\u4e00\u4e2a\u7528\u4e8e\u8ddf\u8e2a\u5377\u4e2d\u6587\u4ef6\u7684\u6570\u636e\u5e93\u3002 \u5bf9\u4e8e\u666e\u901a\u6587\u4ef6\uff0c\u5206\u914d\u6570\u636e\u5757\u4ee5\u5b58\u50a8\u6587\u4ef6\u7684\u6570\u636e\uff0c\u5206\u914dinode\u4ee5\u6307\u5411\u6570\u636e\u5757\u4ee5\u53ca\u5b58\u50a8\u5173\u4e8e\u6587\u4ef6\u7684\u5143\u6570\u636e\uff0c\u7136\u540e\u5c06\u6587\u4ef6\u540d\u5206\u914d\u7ed9inode\u3002 \u786c\u94fe\u63a5\u662f\u4e0e\u73b0\u6709inode\u5173\u8054\u7684\u8f85\u52a9\u6587\u4ef6\u540d\u3002 \u5bf9\u4e8e\u7b26\u53f7\u94fe\u63a5\uff0c\u5c06\u4e3a\u65b0\u7684inode\u5206\u914d\u4e00\u4e2a\u4e0e\u4e4b\u5173\u8054\u7684\u65b0\u6587\u4ef6\u540d\uff0c\u4f46inode\u5f15\u7528\u53e6\u4e00\u4e2a\u6587\u4ef6\u540d\u800c\u4e0d\u662f\u5f15\u7528\u6570\u636e\u5757\u3002 A good way to see the relationship between file names and inodes is to use the ls -il command. The typical size of an inode is 128 Bit and data blocks can range in size from 1k, 2k, 4k or larger depending on the file system type. \u67e5\u770b\u6587\u4ef6\u540d\u548cinode\u4e4b\u95f4\u5173\u7cfb\u7684\u597d\u65b9\u6cd5\u662f\u4f7f\u7528ls -il\u547d\u4ee4\u3002inode\u7684\u5178\u578b\u5927\u5c0f\u4e3a128\u4f4d\uff0c\u6570\u636e\u5757\u7684\u5927\u5c0f\u8303\u56f4\u53ef\u4ee5\u662f1k\uff0c2k\uff0c4k\u6216\u66f4\u5927\uff0c\u5177\u4f53\u53d6\u51b3\u4e8e\u6587\u4ef6\u7cfb\u7edf\u7c7b\u578b\u3002 \u786c\u94fe\u63a5\u76f8\u5f53\u4e8e\u589e\u52a0\u4e86\u4e00\u4e2a\u767b\u8bb0\u9879\uff0c\u4f7f\u5f97\u539f\u6765\u7684\u6587\u4ef6\u591a\u4e86\u4e00\u4e2a\u540d\u5b57\uff0c\u81f3\u4e8einode\u90fd\u6ca1\u53d8\u3002\u6240\u8c13\u7684\u767b\u8bb0\u9879\u5176\u5b9e\u662f\u76ee\u5f55\u6587\u4ef6\u4e2d\u7684\u4e00\u4e2a\u6761\u76ee(\u76ee\u5f55\u9879)\uff0c\u4f7f\u7528hard link \u662f\u8ba9\u591a\u4e2a\u4e0d\u540c\u7684\u76ee\u5f55\u9879\u6307\u5411\u540c\u4e00\u4e2a\u6587\u4ef6\u7684inode\uff0c\u6ca1\u6709\u591a\u4f59\u7684\u5185\u5bb9\u9700\u8981\u5b58\u50a8\u5728\u78c1\u76d8\u6247\u533a\u4e2d\uff0c\u6240\u4ee5hardlink\u4e0d\u5360\u7528\u989d\u5916\u7684\u7a7a\u95f4\u3002 \u7b26\u53f7\u94fe\u63a5\u6709\u5355\u72ec\u7684inode\uff0c\u5728inode\u4e2d\u5b58\u653e\u53e6\u4e00\u4e2a\u6587\u4ef6\u7684\u8def\u5f84\u800c\u4e0d\u662f\u6587\u4ef6\u6570\u636e\uff0c\u6240\u4ee5\u7b26\u53f7\u94fe\u63a5\u4f1a\u5360\u7528\u989d\u5916\u7684\u7a7a\u95f4\u3002 Lab: File Link Type \u00b6 Create original file mySUSE:/data/linktype # echo \"it's original file\" > file mySUSE:/data/linktype # l -rw-r--r-- 1 root root 19 Mar 28 15 :20 file Create hardlink file (\u6ce8\u610ffile\u3001hardlinkfile1\u3001hardlinkfile2\u7684link\u4f4d\u7f6e\u7684\u6570\u503c\u7684\u53d8\u5316[\u7ea2\u8272]) mySUSE:/data/linktype # ln file hardlinkfile1 mySUSE:/data/linktype # ln -s file symlinkfile1 mySUSE:/data/linktype # ln -s file symlinkfile2 mySUSE:/data/linktype # l -rw-r--r-- 2 root root 19 Mar 28 15 :20 file -rw-r--r-- 2 root root 19 Mar 28 15 :20 hardlinkfile1 lrwxrwxrwx 1 root root 4 Mar 28 15 :21 symlinkfile1 -> file lrwxrwxrwx 1 root root 4 Mar 28 15 :23 symlinkfile2 -> file mySUSE:/data/linktype # ln file hardlinkfile2 mySUSE:/data/linktype # l -rw-r--r-- 3 root root 19 Mar 28 15 :20 file ( \u5305\u62ec\u81ea\u5df1\uff0c\u4e00\u5171\u67093\u4e2a\u786c\u94fe\u63a5 ) -rw-r--r-- 3 root root 19 Mar 28 15 :20 hardlinkfile1 ( \u7ee7\u627f\u4e86\u539f\u6587\u4ef6\u7684\u786c\u94fe\u63a5\u6570\u91cf ) -rw-r--r-- 3 root root 19 Mar 28 15 :20 hardlinkfile2 ( \u7ee7\u627f\u4e86\u539f\u6587\u4ef6\u7684\u786c\u94fe\u63a5\u6570\u91cf ) lrwxrwxrwx 1 root root 4 Mar 28 15 :21 symlinkfile1 -> file lrwxrwxrwx 1 root root 4 Mar 28 15 :23 symlinkfile2 -> file Modify content of file (original file). Content change were shown in all hard/soft link files mySUSE:/data/linktype # echo \"add oneline\" >> file mySUSE:/data/linktype # cat file it 's original file add oneline mySUSE:/data/linktype # cat hardlinkfile1 it' s original file add oneline mySUSE:/data/linktype # cat hardlinkfile2 it 's original file add oneline mySUSE:/data/linktype # cat symlinkfile1 it' s original file add oneline mySUSE:/data/linktype # cat symlinkfile2 it ' s original file add oneline To view the value stored in a symbolic link use the command readlink. mySUSE:/data/linktype # ln -s symlinkfile1 symlinkfile1-1 mySUSE:/data/linktype # ls -il 258 -rw-r--r-- 3 root root 31 Mar 28 15 :42 file 258 -rw-r--r-- 3 root root 31 Mar 28 15 :42 hardlinkfile1 258 -rw-r--r-- 3 root root 31 Mar 28 15 :42 hardlinkfile2 259 lrwxrwxrwx 1 root root 4 Mar 28 15 :21 symlinkfile1 -> file 265 lrwxrwxrwx 1 root root 12 Mar 28 15 :49 symlinkfile1-1 -> symlinkfile1 260 lrwxrwxrwx 1 root root 4 Mar 28 15 :23 symlinkfile2 -> file mySUSE:/data/linktype # readlink symlinkfile1 file mySUSE:/data/linktype # readlink symlinkfile2 file mySUSE:/data/linktype # readlink symlinkfile1-1 symlinkfile1 ( \u6ce8\u610f\uff1a\u8fd9\u4ecd\u7136\u662f\u4e00\u4e2a\u7b26\u53f7\u94fe\u63a5\u6587\u4ef6 ) mySUSE:/data/linktype # readlink -f symlinkfile1-1(\u53c2\u6570-f\u53ef\u4ee5\u76f4\u63a5\u5b9a\u4f4d\u771f\u6b63\u7684\u6e90\u6587\u4ef6) /data/linktype/file ( \u6ce8\u610f\uff1a\u8fd9\u624d\u662f\u771f\u6b63\u7684\u539f\u6587\u4ef6 ) Linux Device File \u00b6 Represent hardware (except network cards). Each piece of hardware is represented by a device file. Network cards are interfaces. (\u533a\u522b) Link between hardware devices and the kernel drivers \u8bbe\u5907\u6587\u4ef6\u628a\u5185\u6838\u9a71\u52a8\u548c\u7269\u7406\u786c\u4ef6\u8bbe\u5907\u8fde\u63a5\u8d77\u6765 Kernel drivers read from and write to the device file \u5185\u6838\u9a71\u52a8\u7a0b\u5e8f\u5bf9\u8bbe\u5907\u6587\u4ef6\u8fdb\u884c\u8bfb\u5199\u6765\u5b9e\u73b0\u5bf9\u786c\u4ef6\u7684\u8bfb\u5199 The kernel gets the data to the actual hardware in the correct format \u5185\u6838\u4ee5\u6b63\u786e\u7684\u683c\u5f0f\u5bf9\u7269\u7406\u8bbe\u5907\u8fdb\u884c\u8bfb\u5199 Types: Block Devices. A block device reads/writes information in (normally) 512 byte large blocks. Character Devices. A character device reads/writes information character wise. Character devices provide unbuffered access directly to a hardware device. \u76f4\u63a5\u8bfb\u5199\uff0c\u4e0d\u901a\u8fc7\u7f13\u5b58 Sometimes referred to as raw devices. \u88f8\u8bbe\u5907\uff08\u6ce8\u610f\uff1a\u88f8\u8bbe\u5907\u88ab\u89c6\u4e3a\u5b57\u7b26\u8bbe\u5907\uff0c\u4e0d\u662f\u5757\u8bbe\u5907\uff09 any different options for character devices, making their use and application wide and varied. Created automatically by the OS (udev) when the device is discovered by the kernel. \u5185\u6838\u76f4\u63a5\u521b\u5efa\u5bf9\u5e94\u786c\u4ef6\u7684\u8bbe\u5907\u6587\u4ef6","title":"Linux File System Overview"},{"location":"linux/Administration/01/#linux-file-system-overview","text":"","title":"Linux File System Overview"},{"location":"linux/Administration/01/#linux-file-system-overview_1","text":"Filesystem Hierarchy Standard (FHS), which is part of the LSB (Linux Standards Base) specifications. The Root directory \"/\". Refers to the highest layer of the file system tree. This root partition is mounted first at system boot. All programs that are run at system startup must be in this partition. The following directories must be in the root partition: /bin - User binaries. \u57fa\u672c\u7a0b\u5e8f Contains executables required when no other file systems are mounted. For example, programs required for system booting, working with files and configuration. /bin/bash - The bash shell /bin/cat - Display file contents /bin/cp - Copy files /bin/dd - Copy files byte-wise /bin/gzip - Compress files /bin/mount - Mount file systems /bin/rm - Delete files /bin/vi - Edit files /sbin - System binaries. \u7cfb\u7edf\u7a0b\u5e8f Contains programs important for system administration. \u5b58\u653e\u7cfb\u7edf\u7ba1\u7406\u7684\u7a0b\u5e8f Typically are intended to be run by the root user and therefore it is not in the regular users path. \u9ed8\u8ba4\u662froot\u7528\u6237\u6709\u6743\u9650\u6267\u884c Some important files: /sbin/yast - Administration tool /sbin/fdisk* - Modifies partitions /sbin/fsck* - File system check \u4e0d\u80fd\u5728\u8fd0\u884c\u7684\u7cfb\u7edf\u4e0a\u9762\u76f4\u63a5\u6267\u884cfsck\uff0c\u635f\u574f\u6839\u6587\u4ef6\u7cfb\u7edf\uff0c\u9700\u8981umount /sbin/mkfs - Creates file systems /sbin/shutdown - Shuts down the system /dev - Device files Each system hardware component is represented (except network cards, which are kernel modules). \u4ee5\u592a\u7f51\u5361\u662f\u5185\u6838\u6a21\u5757\uff0c\u5176\u4ed6\u786c\u4ef6\u90fd\u4ee5\u8bbe\u5907dev\u7684\u65b9\u5f0f\u5c55\u73b0 Applications read from and write to these files to address hardware components. Two kinds of device files: Character-oriented \u2013 Sequential devices (printer, tape and mouse) \u5b57\u7b26\u8bbe\u5907 Block-oriented \u2013 Hard disks and DVDs \u5757\u8bbe\u5907 Connections to device drivers are implemented in the kernel using channels called major device numbers. \u4e0e\u8bbe\u5907\u9a71\u52a8\u7a0b\u5e8f\u7684\u8fde\u63a5\u901a\u8fc7\u5185\u6838\u4e2d\u79f0\u4e3a\u4e3b\u8bbe\u5907\u53f7\u7684\u901a\u9053\u5b9e\u73b0\u3002 When using ls -l the file size is replaced with the device numbers, such as 8, 0. In the past these files were created manually using the mknod command. Today they are created automatically (by udev) when the devices are discovered by the kernel. Some important device files: Null device: - /dev/null Zero device: - /dev/zero System Console: - /dev/console Virtual Terminal: - /dev/tty1 Serial ports - /dev/ttyS0 Parallel port: - /dev/lp0 Floppy disk drive: - /dev/fd0 Hard drive: - /dev/sda Hard disk partition: - /dev/sda1 CD-ROM drive: - /dev/scd0 /etc - Configuration files Contains system and services configuration files. \u5b58\u653e\u7cfb\u7edf\u548c\u670d\u52a1\u7684\u914d\u7f6e\u6587\u4ef6 Most of these files are ASCII files. \u5927\u90e8\u5206\u90fd\u662fASCII\u6587\u4ef6 Normal users can read most of these by default. This can be a security issue since some of these files contain passwords so it important that these files are only readable by the rootuser. \u666e\u901a\u7528\u6237\u53ef\u4ee5\u9ed8\u8ba4\u8bfb\u53d6\u5176\u4e2d\u7684\u5927\u90e8\u5206\u5185\u5bb9\u3002 \u8fd9\u53ef\u80fd\u662f\u4e00\u4e2a\u5b89\u5168\u95ee\u9898\uff0c\u56e0\u4e3a\u5176\u4e2d\u4e00\u4e9b\u6587\u4ef6\u5305\u542b\u5bc6\u7801\uff0c\u56e0\u6b64\u91cd\u8981\u7684\u662f\u8fd9\u4e9b\u6587\u4ef6\u53ea\u80fd\u7531root\u7528\u6237\u8bfb\u53d6 No executables can be put here according to the FHS, however subdirectories may contain shell scripts. \u6839\u636eFHS\uff0c\u6b64\u5904\u4e0d\u80fd\u653e\u7f6e\u4efb\u4f55\u53ef\u6267\u884c\u6587\u4ef6\uff0c\u4f46\u5b50\u76ee\u5f55\u53ef\u80fd\u5305\u542bshell\u811a\u672c\u3002 Almost every installed service has at least one configuration file in /etc or a subdirectory. \u51e0\u4e4e\u6bcf\u4e2a\u5df2\u5b89\u88c5\u7684\u670d\u52a1\u5728/ etc\u6216\u5b50\u76ee\u5f55\u4e2d\u81f3\u5c11\u6709\u4e00\u4e2a\u914d\u7f6e\u6587\u4ef6\u3002 Some important configuration files: /etc/SuSE-release - Version of installed system /etc/DIR_COLORS - Colors for the ls command /etc/fstab - For file systems to be mounted /etc/profile - Shell login script /etc/passwd - User database, except passwords /etc/shadow - Password and password info /etc/group - Database of user groups /etc/cups/* - For the CUPS printing system (CUPS=Common UNIX Printing System) /etc/hosts - Host names to IP addresses /etc/motd - Message after login /etc/issue - Message before login /etc/sysconfig/* - System configuration files /lib - Libraries. Many programs have common functions they need. The functions can be kept in a shared library. Libraries are called shared objects and end with the .so extension. \u5171\u4eab\u5e93 Libraries in /lib are used by programs in /bin and /sbin . There are additional libraries in subdirectories. Kernel modules are located in /lib/modules . /lib64 - 64-Bit Libraries. Similar to the /lib directory. This is an architecture dependent directory. Some systems support different binary formats and keep different versions of the same shared library. /usr - Contains application programs, graphical interface files, libraries, local programs, documentation and more. /usr means Unix System Resources. Examples: /usr/X11R6/ - X Window System Files /usr/bin/ - Almost all executables /usr/lib/ - Libraries and application directories /usr/local/ - Locally installed programs (i.e. on local system if /usr is mounted from the network). The content is not overwritten by system updates. \u4e0b\u97623\u4e2a\u76ee\u5f55\u5728\u521d\u59cb\u5b89\u88c5\u540e\u662f\u7a7a\u7684 /usr/local/bin - /usr/local/sbin - /usr/local/lib - /usr/sbin/ - System administration programs /usr/share/doc/ - Documentation /usr/src/ - Source code of kernel and programs /usr/src/linux - /usr/share/man/ - Manual pages /opt - Optional Application Directory Where optional or third party applications that are not considered to be \u201cpart of the distribution\u201d store their static files. Applications considered to be \u201cpart of the distribution\u201d are usually installed under /usr/lib/ rather than /opt . At installation a directory is created for each application's files with the name of the application. Example: /opt/novell - /boot - The Boot Directory /boot/grub2 - Contains static boot loader files for GRUB2. (GRUB = Grand Unified Boot Loader) Contains the kernel and initrd file identified with the links vmlinuz and initrd. /root - Administrator's Home Directory The root user's home directory. Not under /home with regular users' home directories. Needs to be in the root partition so that root can always log in with his configured environment. /home - User Directories Every system user has an assigned file area which becomes the current working directory after log in. By default they exist in /home . The files and directories in /home could be in a separate partition or on another computer on the network. The user profile and configuration files are found here: .profile - Private user login script .bashrc - Configuration file for bash .bash_history - Previous commands run in bash /run/media//* - Mount Point for Removable Media SLE 12 creates directories here for mounting removable media. The name depends on the device that is mounted/discovered. Examples: /run/media/media_name/ (Created if labeled media is inserted) /run/media/cdrom/ - /run/media/dvd/ - /run/media/usbdisk/ - /mnt - Temporarily Mounted File Systems \u6587\u4ef6\u7cfb\u7edf\u4e34\u65f6\u6302\u8f7d\u70b9 Standard directory for integrating file systems that are used temporarily. File systems are mounted using the mount command and removed using the umount command. Subdirectories do not exist by default and are not automatically created. /srv - Service Data Directories Contains subdirectories for various services. Examples: \u5b58\u653e\u5404\u79cd\u670d\u52a1\u7684\u6570\u636e /srv/www - for the Apache Web Server /srv/ftp - for an FTP server /var - Variable Files Contains files that can be modified while the system is running. \u5728\u7cfb\u7edf\u8fd0\u884c\u8fc7\u7a0b\u4e2d\u4f1a\u88ab\u4fee\u6539\u7684\u6587\u4ef6 Important subdirectories: /var/lib/ - Variable libraries, like databases \u53ef\u53d8\u5e93\u6587\u4ef6 /var/log/ - Services log files \u65e5\u5fd7\u6587\u4ef6 /var/run/ - Information on running processes \u8fd0\u884c\u4e2d\u7684\u7ebf\u7a0b\u7684\u4fe1\u606f /var/spool/ - Queues (printers, email) /var/spool/mail - /var/spool/cron - /var/lock/ - Lock files for multiuser access /var/cache - /var/mail - /tmp - Temporary Area Where programs create temporary files while they are running /proc - Process Files A virtual file system that exists only in memory and is used to display the current state of processes running on the system. (Takes no space - file size always 0) \u865a\u62df\u6587\u4ef6\u7cfb\u7edf\uff0c\u4e0d\u5360\u95f4\uff0c\u5927\u5c0f* \u59cb\u7ec8\u96f6\uff0c\u663e\u793a\u5f53\u524d\u8fdb\u7a0b\u7684\u72b6\u6001\u4fe1\u606f Directories containing information about individual processes are named according to the PID number of the process. Some values can be modified to change how things are running in real time. Any changes made are lost at reboot. Examples: \u6709\u4e9b\u503c\u53ef\u4ee5\u4e34\u65f6\u5728\u7ebf\u66f4\u6539\u751f\u6548\uff0c\u4f46\u91cd\u542f\u540e\u4e22\u5931 /proc/cpuinfo/ - Processor information /proc/dma/ - Use of DMA ports /proc/interrupts/ - Use of interrupts /proc/ioports/ - Use of I/O ports /proc/filesystems/ - File system formats the kernel knows /proc/modules/ - Active modules /proc/mounts/ - Mounted file systems /proc/net/* - Network information and statistics /proc/partitions/ - Existing partitions /proc/bus/pci/ - Connected PCI devices /proc/bus/scsi/ - Connected SCSI devices /proc/sys/* - System and kernel information /proc/version - Kernel version /sys - System Information Directory A virtual file system that exists only in memory. Takes no space so file size always 0 \u865a\u62df\u6587\u4ef6\u7cfb\u7edf Provides information on: hardware buses hardware devices active devices drivers","title":"Linux File System Overview"},{"location":"linux/Administration/01/#lab-explore-filesystem-hierarchy","text":"Show the directory structure of the /data folder hierarchy of current logon user: mySUSE:~ # tree /data /data \u2514\u2500\u2500 linktype \u251c\u2500\u2500 file \u251c\u2500\u2500 hardlinkfile1 \u251c\u2500\u2500 hardlinkfile2 \u251c\u2500\u2500 symlinkfile1 -> file \u251c\u2500\u2500 symlinkfile1-1 -> symlinkfile1 \u2514\u2500\u2500 symlinkfile2 -> file Show only directories in the /data hierarchhy, not the files in them: mySUSE:~ # tree -d /data /data \u2514\u2500\u2500 linktype Show the files and directories in the /data hierarchy, including the full path and filename of each object. mySUSE:~ # tree -f /data /data \u2514\u2500\u2500 /data/linktype \u251c\u2500\u2500 /data/linktype/file \u251c\u2500\u2500 /data/linktype/hardlinkfile1 \u251c\u2500\u2500 /data/linktype/hardlinkfile2 \u251c\u2500\u2500 /data/linktype/symlinkfile1 -> file \u251c\u2500\u2500 /data/linktype/symlinkfile1-1 -> symlinkfile1 \u2514\u2500\u2500 /data/linktype/symlinkfile2 -> file","title":"Lab: Explore Filesystem Hierarchy"},{"location":"linux/Administration/01/#seven-different-types-of-files","text":"Normal files , examples: ASCII text files Executable files Graphics files Directories Organize files on the disk Contain files and subdirectories Implement the hierarchical file system Links Hard links Secondary file names for files on the disk Multiple file names referencing a single inode Referenced file must reside in the same file system Symbolic links: References to other files on the disk The inode contains a reference to another file name .Referenced files can exist in the same file system or in other file systems A symbolic link can reference a non-existent file (broken link) Sockets - Used for two-way communication between processes. \u5957\u63a5\u5b57 Pipes (FIFOs) - Used for one-way communication from one process to another. \u7ba1\u9053 Block Devices \u5757\u8bbe\u5907 Character Devices \u5b57\u7b26\u8bbe\u5907","title":"Seven Different types of files"},{"location":"linux/Administration/01/#linux-link-type","text":"Hard links : A hard link is a directory reference, or pointer, to a file on a storage volume. The name associated with the file is a label stored in a directory structure that refers the operating system to the file data. As such, more than one name can be associated with the same file. When accessed through different names, any changes made will affect the same file data. \u786c\u94fe\u63a5\u662f\u5b58\u50a8\u5377\u4e0a\u6587\u4ef6\u7684\u76ee\u5f55\u5f15\u7528\u6216\u6307\u9488\u3002 \u6587\u4ef6\u540d\u662f\u5b58\u50a8\u5728\u76ee\u5f55\u7ed3\u6784\u4e2d\u7684\u6807\u7b7e\uff0c\u76ee\u5f55\u7ed3\u6784\u6307\u5411\u6587\u4ef6\u6570\u636e\u3002 \u56e0\u6b64\uff0c\u53ef\u4ee5\u5c06\u591a\u4e2a\u6587\u4ef6\u540d\u4e0e\u540c\u4e00\u6587\u4ef6\u5173\u8054\u3002 \u901a\u8fc7\u4e0d\u540c\u7684\u6587\u4ef6\u540d\u8bbf\u95ee\u65f6\uff0c\u6240\u505a\u7684\u4efb\u4f55\u66f4\u6539\u90fd\u662f\u9488\u5bf9\u6e90\u6587\u4ef6\u6570\u636e\u3002 Symbolic links : A symbolic link contains a text string that is interpreted and followed by the operating system as a path to another file or directory. It is a file on its own and can exist independently of its target. If a symbolic link is deleted, its target remains unaffected. If the target is moved, renamed or deleted, any symbolic link that used to point to it continues to exist but now points to a non-existing file. \u7b26\u53f7\u94fe\u63a5\u5305\u542b\u4e00\u4e2a\u6587\u672c\u5b57\u7b26\u4e32\uff0c\u64cd\u4f5c\u7cfb\u7edf\u5c06\u5176\u89e3\u91ca\u5e76\u4f5c\u4e3a\u53e6\u4e00\u4e2a\u6587\u4ef6\u6216\u76ee\u5f55\u7684\u8def\u5f84\u3002 \u5b83\u672c\u8eab\u5c31\u662f\u4e00\u4e2a\u6587\u4ef6\uff0c\u53ef\u4ee5\u72ec\u7acb\u4e8e\u76ee\u6807\u800c\u5b58\u5728\u3002 \u5982\u679c\u5220\u9664\u4e86\u7b26\u53f7\u94fe\u63a5\uff0c\u5219\u5176\u76ee\u6807\u4e0d\u53d7\u5f71\u54cd\u3002 \u5982\u679c\u79fb\u52a8\uff0c\u91cd\u547d\u540d\u6216\u5220\u9664\u76ee\u6807\uff0c\u5219\u7528\u4e8e\u6307\u5411\u5b83\u7684\u4efb\u4f55\u7b26\u53f7\u94fe\u63a5\u5c06\u7ee7\u7eed\u5b58\u5728\uff0c\u4f46\u73b0\u5728\u6307\u5411\u4e0d\u5b58\u5728\u7684\u6587\u4ef6\u3002 Hard links can only be used when both the file and the link are in the same file system (on the same partition), because inode numbers are only unique within the same file system. You create a hard link by using the ln command, which points to the inode of an already existing file. Thereafter, the file can be accessed under both names\u2013that of the file and that of the link, and you can no longer discern which name existed first or how the original file and the link differ. \u4ec5\u5f53\u6587\u4ef6\u548c\u94fe\u63a5\u6587\u4ef6\u4f4d\u4e8e\u540c\u4e00\u6587\u4ef6\u7cfb\u7edf\uff08\u5728\u540c\u4e00\u5206\u533a\u4e0a\uff09\u65f6\uff0c\u624d\u80fd\u4f7f\u7528\u786c\u94fe\u63a5\uff0c\u56e0\u4e3ainode\u7f16\u53f7\u5728\u540c\u4e00\u6587\u4ef6\u7cfb\u7edf\u4e2d\u4ec5\u662f\u552f\u4e00\u7684\u3002 \u60a8\u53ef\u4ee5\u4f7f\u7528ln\u547d\u4ee4\u521b\u5efa\u786c\u94fe\u63a5\uff0c\u8be5\u547d\u4ee4\u6307\u5411\u5df2\u5b58\u5728\u6587\u4ef6\u7684inode\u3002 \u6b64\u540e\uff0c\u53ef\u4ee5\u5728\u6587\u4ef6\u7684\u540d\u79f0\u548c\u94fe\u63a5\u7684\u540d\u79f0\u4e0b\u8bbf\u95ee\u6587\u4ef6\uff0c\u5e76\u4e14\u65e0\u6cd5\u518d\u8bc6\u522b\u9996\u5148\u5b58\u5728\u7684\u540d\u79f0\u6216\u539f\u59cb\u6587\u4ef6\u548c\u94fe\u63a5\u7684\u4e0d\u540c\u4e4b\u5904\u3002 You can create a symbolic link with the ln command and the -s option. A symbolic link is assigned its own inode\u2014the link refers to a file, so a distinction can always be made between the link and the actual file. \u8f6f\u8fde\u63a5\u53ef\u4ee5\u9488\u5bf9\u76ee\u5f55\uff0c\u786c\u8fde\u63a5\u53ea\u80fd\u9488\u5bf9\u6587\u4ef6\u3002 A file system is essentially a database that is used to keep track of files in a volume. For normal files, data blocks are allocated to store the file's data, an inode is allocated to point to the data blocks as well as store the metadata about the file and then a file name is assigned to the inode. A hard link is a secondary file name associated with an existing inode. For symbolic links, a new inode is allocated with a new file name associated with it but the inode references another file name rather than referencing datablocks. \u6587\u4ef6\u7cfb\u7edf\u672c\u8d28\u4e0a\u662f\u4e00\u4e2a\u7528\u4e8e\u8ddf\u8e2a\u5377\u4e2d\u6587\u4ef6\u7684\u6570\u636e\u5e93\u3002 \u5bf9\u4e8e\u666e\u901a\u6587\u4ef6\uff0c\u5206\u914d\u6570\u636e\u5757\u4ee5\u5b58\u50a8\u6587\u4ef6\u7684\u6570\u636e\uff0c\u5206\u914dinode\u4ee5\u6307\u5411\u6570\u636e\u5757\u4ee5\u53ca\u5b58\u50a8\u5173\u4e8e\u6587\u4ef6\u7684\u5143\u6570\u636e\uff0c\u7136\u540e\u5c06\u6587\u4ef6\u540d\u5206\u914d\u7ed9inode\u3002 \u786c\u94fe\u63a5\u662f\u4e0e\u73b0\u6709inode\u5173\u8054\u7684\u8f85\u52a9\u6587\u4ef6\u540d\u3002 \u5bf9\u4e8e\u7b26\u53f7\u94fe\u63a5\uff0c\u5c06\u4e3a\u65b0\u7684inode\u5206\u914d\u4e00\u4e2a\u4e0e\u4e4b\u5173\u8054\u7684\u65b0\u6587\u4ef6\u540d\uff0c\u4f46inode\u5f15\u7528\u53e6\u4e00\u4e2a\u6587\u4ef6\u540d\u800c\u4e0d\u662f\u5f15\u7528\u6570\u636e\u5757\u3002 A good way to see the relationship between file names and inodes is to use the ls -il command. The typical size of an inode is 128 Bit and data blocks can range in size from 1k, 2k, 4k or larger depending on the file system type. \u67e5\u770b\u6587\u4ef6\u540d\u548cinode\u4e4b\u95f4\u5173\u7cfb\u7684\u597d\u65b9\u6cd5\u662f\u4f7f\u7528ls -il\u547d\u4ee4\u3002inode\u7684\u5178\u578b\u5927\u5c0f\u4e3a128\u4f4d\uff0c\u6570\u636e\u5757\u7684\u5927\u5c0f\u8303\u56f4\u53ef\u4ee5\u662f1k\uff0c2k\uff0c4k\u6216\u66f4\u5927\uff0c\u5177\u4f53\u53d6\u51b3\u4e8e\u6587\u4ef6\u7cfb\u7edf\u7c7b\u578b\u3002 \u786c\u94fe\u63a5\u76f8\u5f53\u4e8e\u589e\u52a0\u4e86\u4e00\u4e2a\u767b\u8bb0\u9879\uff0c\u4f7f\u5f97\u539f\u6765\u7684\u6587\u4ef6\u591a\u4e86\u4e00\u4e2a\u540d\u5b57\uff0c\u81f3\u4e8einode\u90fd\u6ca1\u53d8\u3002\u6240\u8c13\u7684\u767b\u8bb0\u9879\u5176\u5b9e\u662f\u76ee\u5f55\u6587\u4ef6\u4e2d\u7684\u4e00\u4e2a\u6761\u76ee(\u76ee\u5f55\u9879)\uff0c\u4f7f\u7528hard link \u662f\u8ba9\u591a\u4e2a\u4e0d\u540c\u7684\u76ee\u5f55\u9879\u6307\u5411\u540c\u4e00\u4e2a\u6587\u4ef6\u7684inode\uff0c\u6ca1\u6709\u591a\u4f59\u7684\u5185\u5bb9\u9700\u8981\u5b58\u50a8\u5728\u78c1\u76d8\u6247\u533a\u4e2d\uff0c\u6240\u4ee5hardlink\u4e0d\u5360\u7528\u989d\u5916\u7684\u7a7a\u95f4\u3002 \u7b26\u53f7\u94fe\u63a5\u6709\u5355\u72ec\u7684inode\uff0c\u5728inode\u4e2d\u5b58\u653e\u53e6\u4e00\u4e2a\u6587\u4ef6\u7684\u8def\u5f84\u800c\u4e0d\u662f\u6587\u4ef6\u6570\u636e\uff0c\u6240\u4ee5\u7b26\u53f7\u94fe\u63a5\u4f1a\u5360\u7528\u989d\u5916\u7684\u7a7a\u95f4\u3002","title":"Linux Link Type"},{"location":"linux/Administration/01/#lab-file-link-type","text":"Create original file mySUSE:/data/linktype # echo \"it's original file\" > file mySUSE:/data/linktype # l -rw-r--r-- 1 root root 19 Mar 28 15 :20 file Create hardlink file (\u6ce8\u610ffile\u3001hardlinkfile1\u3001hardlinkfile2\u7684link\u4f4d\u7f6e\u7684\u6570\u503c\u7684\u53d8\u5316[\u7ea2\u8272]) mySUSE:/data/linktype # ln file hardlinkfile1 mySUSE:/data/linktype # ln -s file symlinkfile1 mySUSE:/data/linktype # ln -s file symlinkfile2 mySUSE:/data/linktype # l -rw-r--r-- 2 root root 19 Mar 28 15 :20 file -rw-r--r-- 2 root root 19 Mar 28 15 :20 hardlinkfile1 lrwxrwxrwx 1 root root 4 Mar 28 15 :21 symlinkfile1 -> file lrwxrwxrwx 1 root root 4 Mar 28 15 :23 symlinkfile2 -> file mySUSE:/data/linktype # ln file hardlinkfile2 mySUSE:/data/linktype # l -rw-r--r-- 3 root root 19 Mar 28 15 :20 file ( \u5305\u62ec\u81ea\u5df1\uff0c\u4e00\u5171\u67093\u4e2a\u786c\u94fe\u63a5 ) -rw-r--r-- 3 root root 19 Mar 28 15 :20 hardlinkfile1 ( \u7ee7\u627f\u4e86\u539f\u6587\u4ef6\u7684\u786c\u94fe\u63a5\u6570\u91cf ) -rw-r--r-- 3 root root 19 Mar 28 15 :20 hardlinkfile2 ( \u7ee7\u627f\u4e86\u539f\u6587\u4ef6\u7684\u786c\u94fe\u63a5\u6570\u91cf ) lrwxrwxrwx 1 root root 4 Mar 28 15 :21 symlinkfile1 -> file lrwxrwxrwx 1 root root 4 Mar 28 15 :23 symlinkfile2 -> file Modify content of file (original file). Content change were shown in all hard/soft link files mySUSE:/data/linktype # echo \"add oneline\" >> file mySUSE:/data/linktype # cat file it 's original file add oneline mySUSE:/data/linktype # cat hardlinkfile1 it' s original file add oneline mySUSE:/data/linktype # cat hardlinkfile2 it 's original file add oneline mySUSE:/data/linktype # cat symlinkfile1 it' s original file add oneline mySUSE:/data/linktype # cat symlinkfile2 it ' s original file add oneline To view the value stored in a symbolic link use the command readlink. mySUSE:/data/linktype # ln -s symlinkfile1 symlinkfile1-1 mySUSE:/data/linktype # ls -il 258 -rw-r--r-- 3 root root 31 Mar 28 15 :42 file 258 -rw-r--r-- 3 root root 31 Mar 28 15 :42 hardlinkfile1 258 -rw-r--r-- 3 root root 31 Mar 28 15 :42 hardlinkfile2 259 lrwxrwxrwx 1 root root 4 Mar 28 15 :21 symlinkfile1 -> file 265 lrwxrwxrwx 1 root root 12 Mar 28 15 :49 symlinkfile1-1 -> symlinkfile1 260 lrwxrwxrwx 1 root root 4 Mar 28 15 :23 symlinkfile2 -> file mySUSE:/data/linktype # readlink symlinkfile1 file mySUSE:/data/linktype # readlink symlinkfile2 file mySUSE:/data/linktype # readlink symlinkfile1-1 symlinkfile1 ( \u6ce8\u610f\uff1a\u8fd9\u4ecd\u7136\u662f\u4e00\u4e2a\u7b26\u53f7\u94fe\u63a5\u6587\u4ef6 ) mySUSE:/data/linktype # readlink -f symlinkfile1-1(\u53c2\u6570-f\u53ef\u4ee5\u76f4\u63a5\u5b9a\u4f4d\u771f\u6b63\u7684\u6e90\u6587\u4ef6) /data/linktype/file ( \u6ce8\u610f\uff1a\u8fd9\u624d\u662f\u771f\u6b63\u7684\u539f\u6587\u4ef6 )","title":"Lab: File Link Type"},{"location":"linux/Administration/01/#linux-device-file","text":"Represent hardware (except network cards). Each piece of hardware is represented by a device file. Network cards are interfaces. (\u533a\u522b) Link between hardware devices and the kernel drivers \u8bbe\u5907\u6587\u4ef6\u628a\u5185\u6838\u9a71\u52a8\u548c\u7269\u7406\u786c\u4ef6\u8bbe\u5907\u8fde\u63a5\u8d77\u6765 Kernel drivers read from and write to the device file \u5185\u6838\u9a71\u52a8\u7a0b\u5e8f\u5bf9\u8bbe\u5907\u6587\u4ef6\u8fdb\u884c\u8bfb\u5199\u6765\u5b9e\u73b0\u5bf9\u786c\u4ef6\u7684\u8bfb\u5199 The kernel gets the data to the actual hardware in the correct format \u5185\u6838\u4ee5\u6b63\u786e\u7684\u683c\u5f0f\u5bf9\u7269\u7406\u8bbe\u5907\u8fdb\u884c\u8bfb\u5199 Types: Block Devices. A block device reads/writes information in (normally) 512 byte large blocks. Character Devices. A character device reads/writes information character wise. Character devices provide unbuffered access directly to a hardware device. \u76f4\u63a5\u8bfb\u5199\uff0c\u4e0d\u901a\u8fc7\u7f13\u5b58 Sometimes referred to as raw devices. \u88f8\u8bbe\u5907\uff08\u6ce8\u610f\uff1a\u88f8\u8bbe\u5907\u88ab\u89c6\u4e3a\u5b57\u7b26\u8bbe\u5907\uff0c\u4e0d\u662f\u5757\u8bbe\u5907\uff09 any different options for character devices, making their use and application wide and varied. Created automatically by the OS (udev) when the device is discovered by the kernel. \u5185\u6838\u76f4\u63a5\u521b\u5efa\u5bf9\u5e94\u786c\u4ef6\u7684\u8bbe\u5907\u6587\u4ef6","title":"Linux Device File"},{"location":"linux/Administration/02/","text":"Useful Commands \u00b6 Some common abbreviations \u00b6 Abbreviations Description . represents the current directory .. represents the parent directory ~ represents the home directory ~username represents the home directory of user username Software package documentation \u00b6 /usr/share/doc/packages/ Release Notes \u00b6 /usr/share/doc/release-notes/ Command help \u00b6 -h or --help # tree --help Manual pages \u00b6 man [ section ] command # man 5 crontab # man /sestion options Show tree command manual: # man tree List for keywords: # man -k keyword Force mandb to update. Normally this is done daily via a cron job. # mandb Search for all instances of a command or a file named crontab # man -f crontab # whatis crontab (same output with above command) # man -k crontab # apropos crontab (same output with above command) To go directly to a given man page: # man 5 crontab * 1G : go to the 1 st line * 10G : go to the 10 th line * G : go to the end of the page * /^SELinux : search the word SELinux * /section OPTIONS : go to the section OPTIONS man\u5171\u6709\u4ee5\u4e0b\u51e0\u4e2a\u7ae0\u8282\uff0c\u6bd4\u5982\uff0cman 5 crontab\u5c31\u662f\u8fdb\u5165crontab\u7684\u7b2c5\u7ae0\u8282\uff1a Executable programs or shell commands \uff08\u6807\u51c6\u547d\u4ee4\uff09 System calls (functions provided by the kernel)\uff08\u7cfb\u7edf\u8c03\u7528\uff09 Library calls (functions within program libraries)\uff08\u5e93\u51fd\u6570\uff09 Special files (usually found in /dev)\uff08\u8bbe\u5907\u8bf4\u660e\uff09 File formats and conventions eg /etc/passwd \uff08\u6587\u4ef6\u683c\u5f0f\uff09 Games \uff08\u6e38\u620f\u548c\u5a31\u4e50\uff09 Miscellaneous (including macro packages and conventions)\uff08\u6742\u9879\uff0c\u60ef\u4f8b\u4e0e\u534f\u5b9a\u7b49\u7f51\u7edc\u534f\u5b9a\u3001ASCII code\u7b49\u7b49\u7684\u8aaa\u660e\uff09 System administration commands (usually only for root) \uff08\u7ba1\u7406\u5458\u547d\u4ee4\uff09 Kernel routines [Non standard] \uff08\u5176\u4ed6Linux\u7279\u5b9a\u7684\uff0c\u7528\u6765\u5b58\u653e\u5185\u6838\u4f8b\u884c\u7a0b\u5e8f\u7684\u6587\u6863\u3002\uff09 man\u5e38\u7528\u5feb\u6377\u952e \u7ffb\u5c4f \u5411\u540e\u7ffb\u4e00\u5c4f\uff1aspace(\u7a7a\u683c\u952e) \u5411\u524d\u7ffb\u4e00\u5c4f\uff1ab \u5411\u540e\u7ffb\u4e00\u884c\uff1aEnter(\u56de\u8f66\u952e) \u5411\u524d\u7ffb\u4e00\u884c\uff1ak \u67e5\u627e /\u5173\u952e\u8bcd ?\u5173\u952e\u8bcd n (\u4e0b\u4e00\u4e2a) N (\u524d\u4e00\u4e2a) man \u4e2d\u6587\u5316\u3002\u5728 /etc/profile \u52a0\u5165\u4e0b\u9762alias\uff0c\u53ef\u4ee5\u5728man\u4e2d\u8f93\u51fa\u4e2d\u6587 # For man in zh_CH alias cman='man -M /usr/share/man/zh_CN' Display descriptions: \u00b6 whatis command Info pages: \u00b6 info command # info # info top From the terminal window display the info pages for the info command by entering: # info info Move the cursor to the line referring to (Invoking Info) by pressing Tab Tab Follow the link by pressing Enter Move the cursor to the link Note Custom Key Bindings: by pressing Tab (6 times) Follow the link by pressing Enter Return to the page Note Custom Key Bindings: by typing (lowercase L): l Exit the info file by typing: q pwd command \u00b6 Display the current working directory cd command \u00b6 Change directory ls command \u00b6 Display directory contents * Display hidden files with -a option * Detailed listing with -l option * Output is recursive, including all subdirectories with -R option * With option -F After each name, a character indicates the file type (\u201c/\u201d for directories, \u201c*\u201d for executable files, \u201c|\u201d for FIFO files, \u201c@\u201d symbolic link). cp command \u00b6 Copy a file or directory Syntax: cp [option] Option -a : Copies a directory and subdirectories (compare -R ); symbolic links, file permissions, owners, and time stamps are not changed. \u5b83\u4fdd\u7559\u7b26\u53f7\u94fe\u63a5\u3001\u6587\u4ef6\u5c5e\u6027\uff0c\u5e76\u590d\u5236\u76ee\u5f55\u4e0b\u7684\u6240\u6709\u5185\u5bb9\u3002\u5176\u4f5c\u7528\u7b49\u4e8e-dpR\u53c2\u6570\u7ec4\u5408\u3002 Option -I : Asks before overwriting. Option -R , -r : Copies directories recursively (the directory and any subdirectories). \u9012\u5f52\u62f7\u8d1d\uff0c\u5305\u542b\u5b50\u76ee\u5f55\u53ca\uff08\u9690\u542b\uff09\u6587\u4ef6\uff0c\u7ee7\u627f\u76ee\u6807\u76ee\u5f55\u7684\u6743\u9650\u548c\u5c5e\u6027\u7b49 Option -l : Makes hardlinks instead of copying (\u521b\u5efa\u786c\u94fe\u63a5\u7684\u53e6\u5916\u4e00\u4e2a\u65b9\u6cd5) Option -s : Makes symbolic instead of copying (\u521b\u5efa\u7b26\u53f7\u94fe\u63a5\u7684\u53e6\u5916\u4e00\u4e2a\u65b9\u6cd5) Option -u : Copies a file only when the source file is newer than the destination file or when the destination file is missing. Option -p : \u8fde\u540c\u6863\u6848\u7684\u5c5e\u6027\u4e00\u8d77\u590d\u5236\u8fc7\u53bb\uff0c\u5305\u62ec\u4fee\u6539\u65f6\u95f4\u3001\u8bbf\u95ee\u6743\u9650\u3001\u6240\u6709\u8005\u7ec4\u7b49\uff0c\u800c\u975e\u4f7f\u7528\u9884\u8bbe\u5c5e\u6027\uff1b Labs: Initiate directories and files mySUSE:~ # su - pmgr pmgr@mySUSE:~> mkdir /data/program pmgr@mySUSE:~> mkdir /data/program/general pmgr@mySUSE:~> mkdir /data/program/general/staffing pmgr@mySUSE:~> touch /data/program/general/program_scope pmgr@mySUSE:~> touch /data/program/general/staffing/assignment mySUSE:~ # su - pm1 pm1@mySUSE:~> mkdir /data/project1 pm1@mySUSE:~> mkdir /data/project1/iot pm1@mySUSE:~> mkdir /data/project1/iot/bigdata pm1@mySUSE:~> touch /data/project1/iot/devicelist pm1@mySUSE:~> touch /data/project1/iot/bigdata/math_lib mySUSE:~ # su - pm2 pm2@mySUSE:~> mkdir /data/project2 pm2@mySUSE:~> mkdir /data/project2/erp pm2@mySUSE:~> mkdir /data/project2/erp/fin pm2@mySUSE:~> touch /data/project2/erp/erp_vision pm2@mySUSE:~> touch /data/project2/erp/fin/fin_ar pm2@mySUSE:~> chmod g+w /data/project2/erp/erp_vision pmgr@mySUSE:~> ln /data/project2/erp/erp_vision /data/program/general/p2_erp_version ( \u521b\u5efa\u786c\u94fe\u63a5\uff0c\u5f53\u524d\u7528\u6237\u9700\u8981\u5bf9\u6e90\u6587\u4ef6erp_vision\u6709w\u6743\u9650 ) pmgr@mySUSE:~> ln -s /data/project1/iot/devicelist /data/program/general/p1_devicelist ( \u521b\u5efa\u7b26\u53f7\u94fe\u63a5\uff0c\u4e0d\u9a8c\u8bc1\u5f53\u524d\u7528\u6237\u662f\u5426\u5bf9\u6e90\u6587\u4ef6devicelist\u6709\u6743\u9650 ) mySUSE:~ # tree /data /data \u251c\u2500\u2500 program \u2502 \u2514\u2500\u2500 general \u2502 \u251c\u2500\u2500 p1_devicelist -> /data/project1/iot/devicelist \u2502 \u251c\u2500\u2500 p2_erp_version \u2502 \u251c\u2500\u2500 program_scope \u2502 \u2514\u2500\u2500 staffing \u2502 \u2514\u2500\u2500 assignment \u251c\u2500\u2500 project1 \u2502 \u2514\u2500\u2500 iot \u2502 \u251c\u2500\u2500 bigdata \u2502 \u2502 \u2514\u2500\u2500 math_lib \u2502 \u2514\u2500\u2500 devicelist \u2514\u2500\u2500 project2 \u2514\u2500\u2500 erp \u251c\u2500\u2500 erp_vision \u2514\u2500\u2500 fin \u2514\u2500\u2500 fin_ar pmgr@mySUSE:~> cp -R /data/project1 /data/program/ ( /data/program/project1\u7684\u7528\u6237\u548c\u7ec4\u90fd\u7ee7\u627f\u4e86/data/program/ ) pmgr@mySUSE:~> cp -a /data/project2 /data/program/ ( /data/program/project2\u7684\u7528\u6237\u7ee7\u627f\u4e86/data/program/\uff0c\u4f46\u7ec4\u8fd8\u662f\u4fdd\u7559\u539f\u6765\u7684 ) mv command \u00b6 Move or rename a file or directory Option -i : Asks for confirmation before moving or renaming a file. This prevents existing files with the same name from being overwritten. Option -u : Only moves files that are newer than the target files of the same name. pmgr@mySUSE:/data/program/general> cp program_scope ./staffing/ pmgr@mySUSE:/data/program/general> mv -i program_scope ./staffing/ mv: overwrite './staffing/program_scope'? n rm command \u00b6 Delete a file or directory Option -i : Asks for confirmation before deleting. Option -r : (recursively) Allows full directories to be deleted. Option -f : (force) By default, rm asks for confirmation if the file that should be deleted is read-only. Using this option, the files are deleted without asking for confirmation. mkdir command \u00b6 Create a new directory Option -p lets you create a complete path (\u5c42\u7ea7\u8def\u5f84\u4e00\u6b21\u521b\u5efa) pmgr@mySUSE:/data> mkdir -p industry/utilities pmgr@mySUSE:/data> tree ./industry/ ./industry/ \u2514\u2500\u2500 utilities rmdir command \u00b6 Remove an empty directory. The directory or directories must be empty before you can delete them. ln command \u00b6 Create a link Default: Hard link Symbolic link with -s option Syntax: ln [-s] touch command \u00b6 Change the access and modification times Create an empty file if the given file does not exist. Change the time stamp of a file. Option -a : Changes only the time of the last read access (access time). Option -m : Changes only the time of the last modification (modification time). Option -r file : Sets the time stamp of file instead of the current time. Option -t time : Instead of the current time, sets time (structure: [[CC]YY]MMDDhhmm.[ss] ([Century]Year] Month Day Hour Minute [Seconds], two digits in each)) pmgr@mySUSE:/data/industry> touch readme pmgr@mySUSE:/data/industry> touch -a readme pmgr@mySUSE:/data/industry> touch -m readme pmgr@mySUSE:/data/industry> stat readme File: readme Size: 0 Blocks: 0 IO Block: 4096 regular empty file Device: 3dh/61d Inode: 338 Links: 1 Access: (0644/-rw-r--r--) Uid: ( 1003/ pmgr) Gid: ( 1000/ admins) Access: 2019-03-31 10:07:47.489055973 +0800 Modify: 2019-03-31 10:07:58.805109884 +0800 Change: 2019-03-31 10:07:58.805109884 +0800 Birth: - cat command \u00b6 Concatenates files tac command \u00b6 Same as cat, but displays the file(s) in reverse pmgr@mySUSE:/data/industry> cat readme line 1 line 2 line 3 pmgr@mySUSE:/data/industry> tac readme line 3 line 2 line 1 more command \u00b6 Display file contents one page at a time less command \u00b6 Displays file contents for better navigation head command \u00b6 Displays the first 10 lines of a file. To set the number of lines use the -n option pmgr@mySUSE:/data/industry> head readme line 1 line 2 line 3 line 4 line 5 line 6 line 7 line 8 line 9 line 10 pmgr@mySUSE:/data/industry> head -n 5 readme line 1 line 2 line 3 line 4 line 5 tail command \u00b6 Display the last lines of a file To set the number of lines use the -n option To output appended data use -f option, displays a continuously updated view of the last lines of a file. To exit tail -f, press Ctrl+C. pmgr@mySUSE:/data/industry> tail -n 6 readme line 10 line 11 line 12 line 13 line 14 line 15 tar command \u00b6 Create, expand or list archive files Use option c to create an archive Use option f to specify the archive file name Use option v for verbose mode Use option x to extract an archive Use option t to list the content of an archive Use option z to (un-)compress the archive with gzip Use option j to (un-)compress the archive with bzip The /etc directory (include sub-directories) is backed up to the /backup/etc.tar file pmgr@mySUSE:~> tar -cvf /data/backup/project1.tar /data/project1/ pmgr@mySUSE:~> tar -cvf /data/backup/project2.tar /data/project2/ pmgr@mySUSE:~> tar -cv --exclude='*.conf' -f /data/backup/project2a.tar /data/project2/ View the contents of an archive. Some .conf files are excluded in project2a.tar file. pmgr@mySUSE:~> tar -tvf /data/backup/project2.tar drwxr-xr-x pm2/project2 0 2019-03-31 16:47 data/project2/ drwxr-xr-x pm2/project2 0 2019-03-31 16:47 data/project2/erp/ drwxr-xr-x pm2/project2 0 2019-03-31 16:47 data/project2/erp/fin/ -rw-r--r-- pm2/project2 0 2019-03-29 16:06 data/project2/erp/fin/fin_ar -rw-r--r-- pm2/project2 0 2019-03-31 16:47 data/project2/erp/fin/fin.conf -rw-rw-r-- pm2/project2 0 2019-03-29 16:06 data/project2/erp/erp_vision -rw-r--r-- pm2/project2 0 2019-03-31 16:47 data/project2/erp/erp.conf -rw-r--r-- pm2/project2 0 2019-03-31 16:47 data/project2/project2.conf pmgr@mySUSE:~> tar -tvf /data/backup/project2a.tar drwxr-xr-x pm2/project2 0 2019-03-31 16:47 data/project2/ drwxr-xr-x pm2/project2 0 2019-03-31 16:47 data/project2/erp/ drwxr-xr-x pm2/project2 0 2019-03-31 16:47 data/project2/erp/fin/ -rw-r--r-- pm2/project2 0 2019-03-29 16:06 data/project2/erp/fin/fin_ar -rw-rw-r-- pm2/project2 0 2019-03-29 16:06 data/project2/erp/erp_vision Unpack and write all files in the archive to the current directory. Extract to another directory by using the -C option pmgr@mySUSE:~> mkdir project1.backup pmgr@mySUSE:~> tar -xvf /data/backup/project1.tar -C /data/backup/project1.backup/ Incremental backup with tar command pmgr@mySUSE:~> tar -g snapshot_program -cvf /data/backup/bkp_program_full.tar /data/program/ pmgr@mySUSE:~> tar -tvf /data/backup/bkp_program_full.tar pmgr@mySUSE:~> touch /data/program/general/general.conf pmgr@mySUSE:~> tar -g snapshot_program -cvf /data/backup/bkp_program_inc.tar /data/program/ pmgr@mySUSE:~> rm -rf program/ pmgr@mySUSE:~> tar -xvf /data/backup/bkp_program_inc.tar -C /data/ cpio command \u00b6 Another archiving command gzip command \u00b6 Compress files using the gzip algorithm Option -c : Compresses the file without modifying the original file. The result is written to the standard output (usually the screen). From there, it can be redirected to a file with \u201c>\u201d. Option -d : Decompresses the specified file (gunzip) Option -r : Compresses and decompresses files in all subdirectories. Option -1 to -9, --fast, --best : Controls the compression speed: -1 means --fast and causes a quick compression but produces larger files, -9 corresponds to --best and requires more computing time but produces smaller files. The default setting is -6. gunzip command \u00b6 Expand files compressed with gzip bzip2 command \u00b6 Compress files using the bzip2 algorithm Option -c : Option -d : Decompresses the specified file (bunzip2). Option -1 to -9 : Controls the compression speed: -1 causes a quick compression but produces larger files, -9 requires more computing time but produces smaller files. The default setting is -9 . bunzip2 command \u00b6 Expand files compressed with bzip rsync command \u00b6 Copy only deltas between two directories. A key benefit of using rsync is that when copying data, rsync compares the source and the target directory and transfers only data that has changed or has been created. \u4ec5\u590d\u5236\u4e24\u4e2a\u76ee\u5f55\u4e4b\u95f4\u7684\u589e\u91cf\u3002 \u4f7f\u7528rsync\u7684\u4e00\u4e2a\u4e3b\u8981\u597d\u5904\u662f\uff0c\u5728\u590d\u5236\u6570\u636e\u65f6\uff0crsync\u4f1a\u6bd4\u8f83\u6e90\u76ee\u5f55\u548c\u76ee\u6807\u76ee\u5f55\uff0c\u5e76\u4ec5\u4f20\u8f93\u5df2\u66f4\u6539\u6216\u5df2\u521b\u5efa\u7684\u6570\u636e\u3002 Local or via network \u672c\u5730\u6216\u901a\u8fc7\u7f51\u7edc Uses ssh as default transport \u4f7f\u7528ssh\u4f5c\u4e3a\u9ed8\u8ba4\u4f20\u8f93 Can talk to rsync daemon on the remote machine \u53ef\u4ee5\u4e0e\u8fdc\u7a0b\u8ba1\u7b97\u673a\u4e0a\u7684rsync\u5b88\u62a4\u7a0b\u5e8f\u901a\u4fe1 Note: rsync must be installed on both the source and the target computer for this to work. \u5fc5\u987b\u5728\u6e90\u8ba1\u7b97\u673a\u548c\u76ee\u6807\u8ba1\u7b97\u673a\u4e0a\u5b89\u88c5rsync\u624d\u80fd\u4f7f\u5176\u6b63\u5e38\u5de5\u4f5c\u3002 As the default shell used by rsync is ssh, the -e option only needs to be used when you want to use something else than ssh. \u7531\u4e8ersync\u4f7f\u7528\u7684\u9ed8\u8ba4shell\u662fssh\uff0c\u56e0\u6b64\u53ea\u6709\u5728\u60f3\u8981\u4f7f\u7528\u9664ssh\u4ee5\u5916\u7684\u5176\u4ed6\u5de5\u5177\u65f6\u624d\u9700\u8981\u4f7f\u7528-e\u9009\u9879\u3002 Options Option -a : Puts rsync into the archive mode. The -a option ensures the following are preserved \u4fdd\u7559 in the mirrored copy of the directory: Symbolic links (l option) Access permissions (p option) Owners (o option) Group membership (g option) Time stamp (t option) Option -x : Saves files on one file system only, which means that rsync does not follow symbolic links to other file systems. \u4e0d\u8de8\u6587\u4ef6\u7cfb\u7edf\uff0c\u53ea\u5728\u4e00\u4e2a\u6587\u4ef6\u7cfb\u7edf\u5185(don't cross filesyste* undaries) Option -v : Enables the verbose mode. Use this mode to output information about the transferred files and the progress of the copying process. \u8f93\u51fa\u4f20\u8f93\u8fc7\u7a0b\u7684\u7ec6\u8282\u4fe1\u606f Option -z : Compresses the data during the transfer. This is especially useful for remote synchronization. \u538b\u7f29\u65b9\u5f0f\u4f20\u8f93 Option --delete : Deletes files from the mirrored directory that no longer exist in the original directory. Option --exclude-from : Does not back up files listed in an exclude file. Local backup via rsync command pmgr@mySUSE:/data> rsync -av /data/industry/* /data/backup/industry/ sending incremental file list created directory /data/backup/industry readme utilities/ sent 264 bytes received 87 bytes 702.00 bytes/sec total size is 111 speedup is 0.32 pmgr@mySUSE:/data/industry/utilities> touch roadmap.txt pmgr@mySUSE:/data> rsync -av /data/industry/* /data/backup/industry/ sending incremental file list utilities/ utilities/roadmap.txt sent 171 bytes received 39 bytes 420.00 bytes/sec total size is 111 speedup is 0.53 pmgr@mySUSE:/data> rm roadmap.txt pmgr@mySUSE:/data> rsync -av /data/industry/* --delete /data/backup/industry/ sending incremental file list deleting utilities/roadmap.txt utilities/ sent 102 bytes received 41 bytes 286.00 bytes/sec total size is 111 speedup is 0.78 dd command \u00b6 Copies files block by block Used to create disk or partition images Most important options: if =input_file `of``=output_file bs =block_size You can use the dd command to convert and copy files byte-wise. Normally dd reads from the standard input and writes the result to the standard output. But with the appropriate parameters, regular files can be addressed as well. You can copy all kinds of Linux data with this command, including entire hard disk partitions. You can even copy an entire installed system (or just parts of it). Copy file /etc/protocols to protocols.old. The default size for a record is 512 bytes. Below 45+1 means, 45 complete record of standard size and 1 incomplete record (less than 512 bytes pmgr@mySUSE:/data/program> dd if=/etc/protocols of=protocols.old bs=512 45+1 records in 45+1 records out 23259 bytes (23 kB, 23 KiB) copied, 0.000595392 s, 39.1 MB/s \u521b\u5efa\u4e00\u4e2a100M\u7684\u7a7a\u6587\u4ef6 pmgr@mySUSE:/data/program> dd if=/dev/zero of=datafile bs=100M count=2 2+0 records in 2+0 records out 209715200 bytes (210 MB, 200 MiB) copied, 2.79311 s, 75.1 MB/s \u5907\u4efd\u6574\u4e2a\u5206\u533a #dd if=/dev/sda1 of=boot.partition \u5236\u4f5cU\u76d8\u542f\u52a8\u76d8\uff08U\u76d8\u6302\u8f7d\u5230/dev/sdb\uff09 #dd if=/root/diskboot.img of=/dev/sdb bs=125682176 \u5907\u4efd\u786c\u76d8\u4e3b\u5f15\u5bfc\u8bb0\u5f55 #dd if=/dev/sda of=/tmp/mbr_copy bs=512 count=1 \u8fd8\u539f\u786c\u76d8\u4e3b\u5f15\u5bfc\u8bb0\u5f55 #dd if=/disk.mbr of=/dev/hda bs=512 count=1 \u5c06\u5185\u5b58\u91cc\u7684\u6570\u636e\u62f7\u8d1d\u5230root\u76ee\u5f55\u4e0b\u7684mem.bin\u6587\u4ef6 # dd if=/dev/mem of=/root/mem.bin bs=1024 \u62f7\u8d1d\u5149\u76d8\u6570\u636e\u5230root\u6587\u4ef6\u5939\u4e0b\uff0c\u5e76\u4fdd\u5b58\u4e3acd.iso\u6587\u4ef6 # dd if=/dev/cdrom of=/root/cd.iso \u5229\u7528\u968f\u673a\u7684\u6570\u636e\u586b\u5145\u786c\u76d8(\u9500\u6bc1\u786c\u76d8\u6570\u636e) # dd if=/dev/urandom of=/dev/hda1 \u6d4b\u8bd5\u786c\u76d8\u8bfb\u5199\u901f\u5ea6\u3002\u901a\u8fc7\u4e24\u4e2a\u547d\u4ee4\u8f93\u51fa\u7684\u6267\u884c\u65f6\u95f4\uff0c\u53ef\u4ee5\u8ba1\u7b97\u51fa\u6d4b\u8bd5\u786c\u76d8\u7684\u8bfb\uff0f\u5199\u901f\u5ea6\uff1a mySUSE:/data # dd if=/data/program/datafile bs=64k | dd of=/dev/null 3200+0 records in 3200+0 records out 209715200 bytes (210 MB, 200 MiB) copied, 0.67138 s, 312 MB/s 409600+0 records in 409600+0 records out 209715200 bytes (210 MB, 200 MiB) copied, 0.675912 s, 310 MB/s # dd if=/dev/zero of=/data/program/datafile bs=1024 count=100 \u5207\u5272\u5927\u6587\u4ef6bigfile\uff0c\u517198336321\u5b57\u8282\uff0c\u5219\uff1a # dd if=bigfile of=smallfile1 bs=1 count=20000000 # dd if=bigfile of=smallfile2 bs=1 count=20000000 skip=20000000 # dd if=bigfile of=smallfile3 bs=1 count=20000000 skip=40000000 # dd if=bigfile of=smallfile4 bs=1 count=20000000 skip=60000000 # dd if=bigfile of=smallfile5 bs=1 count=18336321 skip=80000000 \u5c06\u5207\u5272\u6587\u4ef6\u7ec4\u88c5 # dd if=smallfile1 of=bigfile bs=1 count=20000000 # dd if=smallfile2 of=bigfile bs=1 count=20000000 seek=20000000 # dd if=smallfile3 of=bigfile bs=1 count=20000000 seek=40000000 # dd if=smallfile4 of=bigfile bs=1 count=20000000 seek=60000000 # dd if=smallfile5 of=bigfile bs=1 count=18336321 seek=80000000 if: \u8981\u5207\u5272\u7684\u5927\u6587\u4ef6\u540d of: \u5207\u5272\u540e\u7684\u5b50\u6587\u4ef6\u540d bs: \u4ee5\u591a\u5c11\u5b57\u8282\u4f5c\u4e3a\u4e00\u4e2a\u5207\u5272\u8bb0\u5f55\u5355\u4f4d count: \u662f\u8981\u5207\u5272\u7684\u5355\u4f4d\u8bb0\u5f55\u6570 skip: \u8bf4\u660e\u5207\u5272\u65f6\u7684\u8d77\u70b9 seek: \u660e\u786e\u6307\u51fa\u5f00\u59cb\u4f4d\u7f6e find command \u00b6 Search for files or directories Syntax: find path criterion [action] The find command has a multitude of options, a few of which are explained here. You can use the following arguments with the command: path: The section of the file system to search (the specified directory and all its subdirectories). If nothing is specified, the file system below the current directory is used. criterion: The properties the file should have (see below) action: Options that influence the following conditions or control the search as a whole The most important actions are: -print (default) -exec command With the -exec option, you can call up another command. This option is frequently used to link find and grep, as in the following: \u627e\u51fagen\u5f00\u5934\u7684\u6587\u4ef6 pmgr@dcmaster:/data> find . -name gen\\* ./program/general ./program/general/general.conf \u627e\u51fagen\u5f00\u5934\u7684\u6587\u4ef6\uff0c\u5e76\u5728\u6587\u4ef6\u5185\u5bb9\u4e2d\u67e5\u627exen\uff0c\u627e\u5230\u540e\u7ed3\u679c\u8f93\u51faxen pmgr@dcmaster:/data> find . -name gen\\* -type f -exec grep xen {} \\; xen xening The two brackets \u201c{}\u201d stand as placeholders for the file names which are found and passed to the grep command. The semicolon closes the -exec instruction. Because this is a special character, it is masked by placing a backslash in front of it. -ctime [\u00b1]days Searches for files whose last change took place no later than (no earlier than) a specified number of days ago. \u5728\u8fc7\u53bbn\u5929\u5185\u88ab\u4fee\u6539\u8fc7\u7684\u6587\u4ef6 mgr@dcmaster:/data> find . -ctime 1 . ./program/datafile -gid number Searches for files with the numeric GID (Group ID) number. (gid \u662f n) -group name Searches for files that are owned by the group name. Instead of a name, the numeric GID is allowed. (group \u540d\u79f0\u662f name) -name pattern Searches for files whose names contain the given pattern. If the pattern contains meta characters or wild cards, the name must be enclosed by quotation marks. Otherwise thename will be interpreted by the shell and not by find. -newer file Searches for files that were modified more recently than file. \u6bd4\u6587\u4ef6 file \u66f4\u65b0\u7684\u6587\u4ef6 pmgr@dcmaster:/data> find . -cnewer ./program/datafile . -size [\u00b1]size Matches files that are above or below a certain size. The size (in blocks of 512 bytes) is given as an argument. The suffix \u201cc\u201cswitches to byte and \u201ck\u201d to blocks of 1024bytes. A preceding \u201c+\u201d stands for all larger files and a \u201c-\u201d for all smaller files. (\u6587\u4ef6\u5927\u5c0f \u662f n \u2022 b \u4ee3\u8868 512 \u4f4d\u5143\u7ec4\u7684\u533a\u5757 \u2022 c \u8868\u793a\u5b57\u5143\u6570 \u2022 k \u8868\u793a kilo bytes \u2022 w \u662f\u4e8c\u4e2a\u4f4d\u5143\u7ec4 pmgr@dcmaster:/data> find . -size 20k ./backup/project2.tar -type file_type Searches for a file type. A file type can be one of the following: * c : \u6587\u4ef6\u7c7b\u578b\u662f c \u7684\u6587\u4ef6\u3002 * d: \u76ee\u5f55 * c: \u5b57\u578b\u88c5\u7f6e\u6587\u4ef6 * b: \u533a\u5757\u88c5\u7f6e\u6587\u4ef6 * p: \u5177\u540d\u8d2e\u5217 * f: \u4e00\u822c\u6587\u4ef6 * l: \u7b26\u53f7\u8fde\u7ed3 * s: socket -uid number Searches for files with the numeric UID (User ID) number. -user name Searches for files, which are owned by user name. Instead of a name, the numeric UID is allowed. \u5e38\u7528\u53c2\u6570 mount, -xdev : \u53ea\u68c0\u67e5\u548c\u6307\u5b9a\u76ee\u5f55\u5728\u540c\u4e00\u4e2a\u6587\u4ef6\u7cfb\u7edf\u4e0b\u7684\u6587\u4ef6\uff0c\u907f\u514d\u5217\u51fa\u5176\u5b83\u6587\u4ef6\u7cfb\u7edf\u4e2d\u7684\u6587\u4ef6 amin n : \u5728\u8fc7\u53bb n \u5206\u949f\u5185\u88ab\u8bfb\u53d6\u8fc7 anewer file : \u6bd4\u6587\u4ef6 file \u66f4\u665a\u88ab\u8bfb\u53d6\u8fc7\u7684\u6587\u4ef6 atime n : \u5728\u8fc7\u53bbn\u5929\u5185\u88ab\u8bfb\u53d6\u8fc7\u7684\u6587\u4ef6 pmgr@dcmaster:/data> find . -atime 1 ./program/datafile cmin n : \u5728\u8fc7\u53bb n \u5206\u949f\u5185\u88ab\u4fee\u6539\u8fc7 pmgr@dcmaster:/data> find . -cmin 20 empty : \u7a7a\u7684\u6587\u4ef6 ipath p, -path p : \u8def\u5f84\u540d\u79f0\u7b26\u5408 p \u7684\u6587\u4ef6\uff0cipath \u4f1a\u5ffd\u7565\u5927\u5c0f\u5199 name name, -iname name : \u6587\u4ef6\u540d\u79f0\u7b26\u5408 name \u7684\u6587\u4ef6\u3002iname \u4f1a\u5ffd\u7565\u5927\u5c0f\u5199 pid n : process id \u662f n \u7684\u6587\u4ef6 \u67e5\u627e\u5f53\u524d\u76ee\u5f55\u53ca\u5b50\u76ee\u5f55\u4e2d\u6240\u6709\u6587\u4ef6\u957f\u5ea6\u4e3a0\u7684\u666e\u901a\u6587\u4ef6\uff0c\u5e76\u5217\u51fa\u5b83\u4eec\u7684\u5b8c\u6574\u8def\u5f84 pmgr@dcmaster:/data> find . -type f -size 0 -exec ls -l {} \\; \u67e5\u627e\u524d\u76ee\u5f55\u4e2d\u6587\u4ef6\u5c5e\u4e3b\u5177\u6709\u8bfb\u3001\u5199\u6743\u9650\uff0c\u5e76\u4e14\u6587\u4ef6\u6240\u5c5e\u7ec4\u7684\u7528\u6237\u548c\u5176\u4ed6\u7528\u6237\u5177\u6709\u8bfb\u6743\u9650\u7684\u6587\u4ef6 pmgr@dcmaster:/data> find . -type f -perm 644 -exec ls -l {} \\; \u67e5\u627e/var/log\u76ee\u5f55\u4e2d\u66f4\u6539\u65f6\u95f4\u572817\u65e5\u4ee5\u524d\u7684\u666e\u901a\u6587\u4ef6\uff0c\u5e76\u5728\u5220\u9664\u4e4b\u524d\u8be2\u95ee\u5b83\u4eec pmgr@dcmaster:/data> find /var/log -type f -mtime +17 -ok rm {} \\; \u5c06\u76ee\u524d\u76ee\u5f55\u53ca\u5176\u5b50\u76ee\u5f55\u4e0b\u6240\u6709\u6700\u8fd1 1 \u5929\u5185\u66f4\u65b0\u8fc7\u7684\u6587\u4ef6\u5217\u51fa mgr@dcmaster:/data> find . -ctime 1 \u5c06\u76ee\u524d\u76ee\u5f55\u5176\u5176\u4e0b\u5b50\u76ee\u5f55\u4e2d\u6240\u6709\u4e00\u822c\u6587\u4ef6\u5217\u51fa pmgr@dcmaster:/data> find . -type f \u5c06\u76ee\u524d\u76ee\u5f55\u53ca\u5176\u5b50\u76ee\u5f55\u4e0b\u6240\u6709\u5ef6\u4f38\u6863\u540d\u662fconf \u7684\u6587\u4ef6\u5217\u51fa\u6765 pmgr@dcmaster:/data> find . -name \"*.conf\" which command \u00b6 Searches all paths listed in the variable $PATH and returns the full path of the command The which command searches all paths listed in the variable $PATH for the specified command and returns the full path of the command. In the variable \\(PATH, the most important directoriesare listed where the shell looks for executable files. which\u547d\u4ee4\u641c\u7d22\u53d8\u91cf\\) PATH\u4e2d\u5217\u51fa\u7684\u6240\u6709\u8def\u5f84\u4ee5\u83b7\u53d6\u6307\u5b9a\u547d\u4ee4\uff0c\u5e76\u8fd4\u56de\u547d\u4ee4\u7684\u5b8c\u6574\u8def\u5f84\u3002 The which command is especially useful if several versions of a command exist in different directories and you want to know which version is executed when entered without specifying apath. \u5982\u679c\u547d\u4ee4\u7684\u591a\u4e2a\u7248\u672c\u5b58\u5728\u4e8e\u4e0d\u540c\u7684\u76ee\u5f55\u4e2d\uff0c\u5e76\u4e14\u60a8\u60f3\u77e5\u9053\u5728\u8f93\u5165\u65f6\u6267\u884c\u4e86\u54ea\u4e2a\u7248\u672c\u800c\u672a\u6307\u5b9a\u8def\u5f84\uff0c\u90a3\u4e48which\u547d\u4ee4\u7279\u522b\u6709\u7528\u3002 NOTE: To see the content of a variable, use the echo command Options Description -n<\u6587\u4ef6\u540d\u957f\u5ea6> \u6307\u5b9a\u6587\u4ef6\u540d\u957f\u5ea6\uff0c\u6307\u5b9a\u7684\u957f\u5ea6\u5fc5\u987b\u5927\u4e8e\u6216\u7b49\u4e8e\u6240\u6709\u6587\u4ef6\u4e2d\u6700\u957f\u7684\u6587\u4ef6\u540d\u3002 -p<\u6587\u4ef6\u540d\u957f\u5ea6> \u4e0e-n\u53c2\u6570\u76f8\u540c\uff0c\u4f46\u6b64\u5904\u7684<\u6587\u4ef6\u540d\u957f\u5ea6>\u5305\u62ec\u4e86\u6587\u4ef6\u7684\u8def\u5f84\u3002 -w \u6307\u5b9a\u8f93\u51fa\u65f6\u680f\u4f4d\u7684\u5bbd\u5ea6\u3002 -V \u663e\u793a\u7248\u672c\u4fe1\u606f # which grep /usr/bin/grep # which -V grep GNU which v2.21, Copyright (C) 1999 - 2015 Carlo Wood. GNU which comes with ABSOLUTELY NO WARRANTY; This program is free software; your freedom to use, change and distribute this program is protected by the GPL. whereis command \u00b6 The whereis command returns the binaries (option -b), manual pages (option -m), and the source code (option -s) of the specified command. If no option is used, all this information is returned, provided the information is available. This command is faster than find, but it is less thorough. Attempts to locate the desired program in the standard Linux places, and in the places specified by $PATH and $MANPATH . \u5c1d\u8bd5\u5728\u6807\u51c6Linux\u4f4d\u7f6e\u548c\u6307\u5b9a\u4f4d\u7f6e( \\(PATH\u548c\\) MANPATH)\u627e\u5230\u6240\u9700\u7684\u7a0b\u5e8f Options Description -b \u53ea\u67e5\u627e\u4e8c\u8fdb\u5236\u6587\u4ef6\u3002 -B<\u76ee\u5f55> \u53ea\u5728\u8bbe\u7f6e\u7684\u76ee\u5f55\u4e0b\u67e5\u627e\u4e8c\u8fdb\u5236\u6587\u4ef6\u3002 -f \u4e0d\u663e\u793a\u6587\u4ef6\u540d\u524d\u7684\u8def\u5f84\u540d\u79f0\u3002 -m \u53ea\u67e5\u627e\u8bf4\u660e\u6587\u4ef6\u3002 -M<\u76ee\u5f55> \u53ea\u5728\u8bbe\u7f6e\u7684\u76ee\u5f55\u4e0b\u67e5\u627e\u8bf4\u660e\u6587\u4ef6\u3002 -s \u53ea\u67e5\u627e\u539f\u59cb\u4ee3\u7801\u6587\u4ef6\u3002 -S<\u76ee\u5f55> \u53ea\u5728\u8bbe\u7f6e\u7684\u76ee\u5f55\u4e0b\u67e5\u627e\u539f\u59cb\u4ee3\u7801\u6587\u4ef6\u3002 -u \u67e5\u627e\u4e0d\u5305\u542b\u6307\u5b9a\u7c7b\u578b\u7684\u6587\u4ef6\u3002 \u4ee5\u4e0b\u8f93\u51fa\u4fe1\u606f\u4ece\u5de6\u81f3\u53f3\u5206\u522b\u4e3a\u67e5\u8be2\u7684\u7a0b\u5e8f\u540d\u3001bash\u8def\u5f84\u3001bash\u7684man\u624b\u518c\u9875\u8def\u5f84\u3002 # whereis grep grep: /usr/bin/grep /bin/grep /usr/share/man/man1/grep.1.gz /usr/share/info/grep.info.gz \u663e\u793abash \u547d\u4ee4\u7684\u4e8c\u8fdb\u5236\u7a0b\u5e8f # whereis -b grep grep: /usr/bin/grep /bin/grep \u663e\u793abash \u547d\u4ee4\u7684\u5e2e\u52a9\u6587\u4ef6 # whereis -m grep grep: /usr/share/man/man1/grep.1.gz /usr/share/info/grep.info.gz type command \u00b6 The type command shows what kind of command is executed when you enter it: \u547d\u4ee4\u7684\u7c7b\u578b a shell built-in command (an essential command that is hard coded in the shell), for example type or cd an external command (called by the shell) an alias, for example ls. An alias defines shortcuts and synonyms for commonly used shell commands. a function The -a option delivers all instances of a command bearing this name in the file system. NOTE: If you want to have more information about a file format, you can use the file command. \u4e0d\u9002\u7528\u4e8e\u666e\u901a\u6587\u4ef6 dcmaster:/data/shell # type pwd.txt -bash: type: pwd.txt: not found \u4e0d\u9002\u7528\u4e8e\u81ea\u5b9a\u4e49\u53ef\u6267\u884c\u811a\u672c dcmaster:/data/shell # type math.sh -bash: type: math.sh: not found \u7cfb\u7edf\u547d\u4ee4 dcmaster:/data/shell # type rsync rsync is /usr/bin/rsync \u522b\u540d dcmaster:/data/shell # type l l is aliased to `ls -alF' file command \u00b6 file\u547d\u4ee4\u7528\u4e8e\u8fa8\u8bc6\u6587\u4ef6\u7c7b\u578b -b \u5217\u51fa\u8fa8\u8bc6\u7ed3\u679c\u65f6\uff0c\u4e0d\u663e\u793a\u6587\u4ef6\u540d\u79f0\u3002 -c \u8be6\u7ec6\u663e\u793a\u6307\u4ee4\u6267\u884c\u8fc7\u7a0b\uff0c\u4fbf\u4e8e\u6392\u9519\u6216\u5206\u6790\u7a0b\u5e8f\u6267\u884c\u7684\u60c5\u5f62\u3002 -f <\u540d\u79f0\u6587\u4ef6> \u6307\u5b9a\u540d\u79f0\u6587\u4ef6\uff0c\u5176\u5185\u5bb9\u6709\u4e00\u4e2a\u6216\u591a\u4e2a\u6587\u4ef6\u540d\u79f0\u65f6\uff0c\u8ba9file\u4f9d\u5e8f\u8fa8\u8bc6\u8fd9\u4e9b\u6587\u4ef6\uff0c\u683c\u5f0f\u4e3a\u6bcf\u5217\u4e00\u4e2a\u6587\u4ef6\u540d\u79f0\u3002 -L \u76f4\u63a5\u663e\u793a\u7b26\u53f7\u8fde\u63a5\u6240\u6307\u5411\u7684\u6587\u4ef6\u7684\u7c7b\u522b\u3002 -m<\u9b54\u6cd5\u6570\u5b57\u6587\u4ef6> \u6307\u5b9a\u9b54\u6cd5\u6570\u5b57\u6587\u4ef6\u3002 -v \u663e\u793a\u7248\u672c\u4fe1\u606f\u3002 -z \u5c1d\u8bd5\u53bb\u89e3\u8bfb\u538b\u7f29\u6587\u4ef6\u7684\u5185\u5bb9\u3002 dcmaster:/data/linktype # l -rw-r--r-- 3 root root 44 May 3 09:50 file -rw-r--r-- 3 root root 44 May 3 09:50 hardlinkfile1 -rw-r--r-- 3 root root 44 May 3 09:50 hardlinkfile2 lrwxrwxrwx 1 root root 4 Mar 28 15:21 symlinkfile1 -> file lrwxrwxrwx 1 root root 12 Mar 28 15:49 symlinkfile1-1 -> symlinkfile1 lrwxrwxrwx 1 root root 4 Mar 28 15:23 symlinkfile2 -> file dcmaster:/data/linktype # file hardlinkfile1 hardlinkfile1: ASCII text dcmaster:/data/linktype # file -i hardlinkfile1 hardlinkfile1: text/plain; charset=us-ascii dcmaster:/data/linktype # file /data/linktype/ /data/linktype/: directory dcmaster:/data/linktype # file -L /data/linktype/ /data/linktype/: directory dcmaster:/data/linktype # file -i /data/linktype/ /data/linktype/: inode/directory; charset=binary dcmaster:/data/linktype # file symlinkfile1 symlinkfile1: symbolic link to file dcmaster:/data/linktype # file -i symlinkfile1 symlinkfile1: inode/symlink; charset=binary grep command \u00b6 You can specify search patterns in the form of regular expressions, although the basic grep command is limited in this regard. To search for more complex patterns, use the egrep command (or grep -E ) instead, which accepts extended regular expressions. To avoid having special characters in search patterns interpreted by the shell, enclose the pattern in quotation marks. Syntax: grep [options] search_pattern filename * egrep = grep -E * rgrep \u53c2\u6570 -a \u6216 --text : \u4e0d\u8981\u5ffd\u7565\u4e8c\u8fdb\u5236\u7684\u6570\u636e\u3002 -A<\u663e\u793a\u884c\u6570> \u6216 --after-context=<\u663e\u793a\u884c\u6570> : \u9664\u4e86\u663e\u793a\u7b26\u5408\u8303\u672c\u6837\u5f0f\u7684\u90a3\u4e00\u5217\u4e4b\u5916\uff0c\u5e76\u663e\u793a\u8be5\u884c\u4e4b\u540e\u7684\u5185\u5bb9\u3002 -b \u6216 --byte-offset : \u5728\u663e\u793a\u7b26\u5408\u6837\u5f0f\u7684\u90a3\u4e00\u884c\u4e4b\u524d\uff0c\u6807\u793a\u51fa\u8be5\u884c\u7b2c\u4e00\u4e2a\u5b57\u7b26\u7684\u7f16\u53f7\u3002 -B<\u663e\u793a\u884c\u6570> \u6216 --before-context=<\u663e\u793a\u884c\u6570> : \u9664\u4e86\u663e\u793a\u7b26\u5408\u6837\u5f0f\u7684\u90a3\u4e00\u884c\u4e4b\u5916\uff0c\u5e76\u663e\u793a\u8be5\u884c\u4e4b\u524d\u7684\u5185\u5bb9\u3002 -c \u6216 --count : \u8ba1\u7b97\u7b26\u5408\u6837\u5f0f\u7684\u5217\u6570\u3002 -C<\u663e\u793a\u884c\u6570> \u6216 --context=<\u663e\u793a\u884c\u6570> \u6216 -<\u663e\u793a\u884c\u6570> : \u9664\u4e86\u663e\u793a\u7b26\u5408\u6837\u5f0f\u7684\u90a3\u4e00\u884c\u4e4b\u5916\uff0c\u5e76\u663e\u793a\u8be5\u884c\u4e4b\u524d\u540e\u7684\u5185\u5bb9\u3002 -d <\u52a8\u4f5c> \u6216 --directories=<\u52a8\u4f5c> : \u5f53\u6307\u5b9a\u8981\u67e5\u627e\u7684\u662f\u76ee\u5f55\u800c\u975e\u6587\u4ef6\u65f6\uff0c\u5fc5\u987b\u4f7f\u7528\u8fd9\u9879\u53c2\u6570\uff0c\u5426\u5219grep\u6307\u4ee4\u5c06\u56de\u62a5\u4fe1\u606f\u5e76\u505c\u6b62\u52a8\u4f5c\u3002 -e<\u8303\u672c\u6837\u5f0f> \u6216 --regexp=<\u8303\u672c\u6837\u5f0f> : \u6307\u5b9a\u5b57\u7b26\u4e32\u505a\u4e3a\u67e5\u627e\u6587\u4ef6\u5185\u5bb9\u7684\u6837\u5f0f\u3002 -E \u6216 --extended-regexp : \u5c06\u6837\u5f0f\u4e3a\u5ef6\u4f38\u7684\u666e\u901a\u8868\u793a\u6cd5\u6765\u4f7f\u7528\u3002 -f<\u89c4\u5219\u6587\u4ef6> \u6216 --file=<\u89c4\u5219\u6587\u4ef6> : \u6307\u5b9a\u89c4\u5219\u6587\u4ef6\uff0c\u5176\u5185\u5bb9\u542b\u6709\u4e00\u4e2a\u6216\u591a\u4e2a\u89c4\u5219\u6837\u5f0f\uff0c\u8ba9grep\u67e5\u627e\u7b26\u5408\u89c4\u5219\u6761\u4ef6\u7684\u6587\u4ef6\u5185\u5bb9\uff0c\u683c\u5f0f\u4e3a\u6bcf\u884c\u4e00\u4e2a\u89c4\u5219\u6837\u5f0f\u3002 -F \u6216 --fixed-regexp : \u5c06\u6837\u5f0f\u89c6\u4e3a\u56fa\u5b9a\u5b57\u7b26\u4e32\u7684\u5217\u8868\u3002 -G \u6216 --basic-regexp : \u5c06\u6837\u5f0f\u89c6\u4e3a\u666e\u901a\u7684\u8868\u793a\u6cd5\u6765\u4f7f\u7528\u3002 -h \u6216 --no-filename : \u5728\u663e\u793a\u7b26\u5408\u6837\u5f0f\u7684\u90a3\u4e00\u884c\u4e4b\u524d\uff0c\u4e0d\u6807\u793a\u8be5\u884c\u6240\u5c5e\u7684\u6587\u4ef6\u540d\u79f0\u3002 -H \u6216 --with-filename : \u5728\u663e\u793a\u7b26\u5408\u6837\u5f0f\u7684\u90a3\u4e00\u884c\u4e4b\u524d\uff0c\u8868\u793a\u8be5\u884c\u6240\u5c5e\u7684\u6587\u4ef6\u540d\u79f0\u3002 -i \u6216 --ignore-case : \u5ffd\u7565\u5b57\u7b26\u5927\u5c0f\u5199\u7684\u5dee\u522b\u3002 -l \u6216 --file-with-matches : \u5217\u51fa\u6587\u4ef6\u5185\u5bb9\u7b26\u5408\u6307\u5b9a\u7684\u6837\u5f0f\u7684\u6587\u4ef6\u540d\u79f0\u3002 -L \u6216 --files-without-match : \u5217\u51fa\u6587\u4ef6\u5185\u5bb9\u4e0d\u7b26\u5408\u6307\u5b9a\u7684\u6837\u5f0f\u7684\u6587\u4ef6\u540d\u79f0\u3002 -n \u6216 --line-number : \u5728\u663e\u793a\u7b26\u5408\u6837\u5f0f\u7684\u90a3\u4e00\u884c\u4e4b\u524d\uff0c\u6807\u793a\u51fa\u8be5\u884c\u7684\u5217\u6570\u7f16\u53f7\u3002 -o \u6216 --only-matching : \u53ea\u663e\u793a\u5339\u914dPATTERN \u90e8\u5206\u3002 -q \u6216 --quiet\u6216--silent : \u4e0d\u663e\u793a\u4efb\u4f55\u4fe1\u606f\u3002 -r \u6216 --recursive : \u6b64\u53c2\u6570\u7684\u6548\u679c\u548c\u6307\u5b9a\"-d recurse\"\u53c2\u6570\u76f8\u540c\u3002 -s \u6216 --no-messages : \u4e0d\u663e\u793a\u9519\u8bef\u4fe1\u606f\u3002 -v \u6216 --revert-match : \u663e\u793a\u4e0d\u5305\u542b\u5339\u914d\u6587\u672c\u7684\u6240\u6709\u884c\u3002 -V \u6216 --version : \u663e\u793a\u7248\u672c\u4fe1\u606f\u3002 -w \u6216 --word-regexp : \u53ea\u663e\u793a\u5168\u5b57\u7b26\u5408\u7684\u5217\u3002 -x --line-regexp : \u53ea\u663e\u793a\u5168\u5217\u7b26\u5408\u7684\u5217\u3002 -y : \u6b64\u53c2\u6570\u7684\u6548\u679c\u548c\u6307\u5b9a\"-i\"\u53c2\u6570\u76f8\u540c\u3002 \u5728\u5f53\u524d\u76ee\u5f55\u4e2d\uff0c\u67e5\u627e\u540e\u7f00\u6709conf\u5b57\u6837\u7684\u6587\u4ef6\u4e2d\u5305\u542bxen\u5b57\u7b26\u4e32\u7684\u6587\u4ef6\uff0c\u5e76\u6253\u5370\u51fa\u8be5\u5b57\u7b26\u4e32\u7684\u884c\u3002 pmgr@dcmaster:/data/program/general> grep xen *.conf xen xening \u67e5\u627e\u524d\u7f00\u6709gen\u7684\u6587\u4ef6\u5305\u542bxen\u5b57\u7b26\u4e32\u7684\u6587\u4ef6 pmgr@dcmaster:/data/program/general> grep xen gen* xen xening \u4ee5\u9012\u5f52\u7684\u65b9\u5f0f\u67e5\u627e\u7b26\u5408\u6761\u4ef6\u7684\u6587\u4ef6\u3002\u67e5\u627e\u6307\u5b9a\u76ee\u5f55/data/program/\u53ca\u5176\u5b50\u76ee\u5f55\uff08\u5982\u679c\u5b58\u5728\u5b50\u76ee\u5f55\u7684\u8bdd\uff09\u4e0b\u6240\u6709\u6587\u4ef6\u4e2d\u5305\u542b\u5b57\u7b26\u4e32xen\u7684\u6587\u4ef6\uff0c\u5e76\u6253\u5370\u51fa\u8be5\u5b57\u7b26\u4e32\u6240\u5728\u884c\u7684\u5185\u5bb9 pmgr@dcmaster:/data> grep -r xen /data/program/ ./program/general/general.conf:xen ./program/general/general.conf:xening \u53cd\u5411\u67e5\u627e\u3002\u524d\u9762\u5404\u4e2a\u4f8b\u5b50\u662f\u67e5\u627e\u5e76\u6253\u5370\u51fa\u7b26\u5408\u6761\u4ef6\u7684\u884c\uff0c\u901a\u8fc7 -v \u53c2\u6570\u53ef\u4ee5\u6253\u5370\u51fa\u4e0d\u7b26\u5408\u6761\u4ef6\u884c\u7684\u5185\u5bb9\u3002\u67e5\u627e\u6587\u4ef6\u540d\u4e2d\u5305\u542bxen\u7684\u6587\u4ef6\u4e2d\u4e0d\u5305\u542bxen\u7684\u884c pmgr@dcmaster:/data/program/general> grep -v xen gen* Linux Test test \u67e5\u627e\u5f53\u524d\u76ee\u5f55\u4e0b\u5305\u542b\u5b57\u7b26\u4e32\u201cLinux\u201d\u7684\u6587\u4ef6 pmgr@dcmaster:/data/program/general> grep Linux * general.conf:Linux grep: staffing: Is a directory pmgr@dcmaster:/data/program/general> egrep Linux * general.conf:Linux grep: staffing: Is a directory","title":"Useful Commands"},{"location":"linux/Administration/02/#useful-commands","text":"","title":"Useful Commands"},{"location":"linux/Administration/02/#some-common-abbreviations","text":"Abbreviations Description . represents the current directory .. represents the parent directory ~ represents the home directory ~username represents the home directory of user username","title":"Some common abbreviations"},{"location":"linux/Administration/02/#software-package-documentation","text":"/usr/share/doc/packages/","title":"Software package documentation"},{"location":"linux/Administration/02/#release-notes","text":"/usr/share/doc/release-notes/","title":"Release Notes"},{"location":"linux/Administration/02/#command-help","text":" -h or --help # tree --help","title":"Command help"},{"location":"linux/Administration/02/#manual-pages","text":"man [ section ] command # man 5 crontab # man /sestion options Show tree command manual: # man tree List for keywords: # man -k keyword Force mandb to update. Normally this is done daily via a cron job. # mandb Search for all instances of a command or a file named crontab # man -f crontab # whatis crontab (same output with above command) # man -k crontab # apropos crontab (same output with above command) To go directly to a given man page: # man 5 crontab * 1G : go to the 1 st line * 10G : go to the 10 th line * G : go to the end of the page * /^SELinux : search the word SELinux * /section OPTIONS : go to the section OPTIONS man\u5171\u6709\u4ee5\u4e0b\u51e0\u4e2a\u7ae0\u8282\uff0c\u6bd4\u5982\uff0cman 5 crontab\u5c31\u662f\u8fdb\u5165crontab\u7684\u7b2c5\u7ae0\u8282\uff1a Executable programs or shell commands \uff08\u6807\u51c6\u547d\u4ee4\uff09 System calls (functions provided by the kernel)\uff08\u7cfb\u7edf\u8c03\u7528\uff09 Library calls (functions within program libraries)\uff08\u5e93\u51fd\u6570\uff09 Special files (usually found in /dev)\uff08\u8bbe\u5907\u8bf4\u660e\uff09 File formats and conventions eg /etc/passwd \uff08\u6587\u4ef6\u683c\u5f0f\uff09 Games \uff08\u6e38\u620f\u548c\u5a31\u4e50\uff09 Miscellaneous (including macro packages and conventions)\uff08\u6742\u9879\uff0c\u60ef\u4f8b\u4e0e\u534f\u5b9a\u7b49\u7f51\u7edc\u534f\u5b9a\u3001ASCII code\u7b49\u7b49\u7684\u8aaa\u660e\uff09 System administration commands (usually only for root) \uff08\u7ba1\u7406\u5458\u547d\u4ee4\uff09 Kernel routines [Non standard] \uff08\u5176\u4ed6Linux\u7279\u5b9a\u7684\uff0c\u7528\u6765\u5b58\u653e\u5185\u6838\u4f8b\u884c\u7a0b\u5e8f\u7684\u6587\u6863\u3002\uff09 man\u5e38\u7528\u5feb\u6377\u952e \u7ffb\u5c4f \u5411\u540e\u7ffb\u4e00\u5c4f\uff1aspace(\u7a7a\u683c\u952e) \u5411\u524d\u7ffb\u4e00\u5c4f\uff1ab \u5411\u540e\u7ffb\u4e00\u884c\uff1aEnter(\u56de\u8f66\u952e) \u5411\u524d\u7ffb\u4e00\u884c\uff1ak \u67e5\u627e /\u5173\u952e\u8bcd ?\u5173\u952e\u8bcd n (\u4e0b\u4e00\u4e2a) N (\u524d\u4e00\u4e2a) man \u4e2d\u6587\u5316\u3002\u5728 /etc/profile \u52a0\u5165\u4e0b\u9762alias\uff0c\u53ef\u4ee5\u5728man\u4e2d\u8f93\u51fa\u4e2d\u6587 # For man in zh_CH alias cman='man -M /usr/share/man/zh_CN'","title":"Manual pages"},{"location":"linux/Administration/02/#display-descriptions","text":"whatis command","title":"Display descriptions:"},{"location":"linux/Administration/02/#info-pages","text":"info command # info # info top From the terminal window display the info pages for the info command by entering: # info info Move the cursor to the line referring to (Invoking Info) by pressing Tab Tab Follow the link by pressing Enter Move the cursor to the link Note Custom Key Bindings: by pressing Tab (6 times) Follow the link by pressing Enter Return to the page Note Custom Key Bindings: by typing (lowercase L): l Exit the info file by typing: q","title":"Info pages:"},{"location":"linux/Administration/02/#pwd-command","text":"Display the current working directory","title":"pwd command"},{"location":"linux/Administration/02/#cd-command","text":"Change directory","title":"cd command"},{"location":"linux/Administration/02/#ls-command","text":"Display directory contents * Display hidden files with -a option * Detailed listing with -l option * Output is recursive, including all subdirectories with -R option * With option -F After each name, a character indicates the file type (\u201c/\u201d for directories, \u201c*\u201d for executable files, \u201c|\u201d for FIFO files, \u201c@\u201d symbolic link).","title":"ls command"},{"location":"linux/Administration/02/#cp-command","text":"Copy a file or directory Syntax: cp [option] Option -a : Copies a directory and subdirectories (compare -R ); symbolic links, file permissions, owners, and time stamps are not changed. \u5b83\u4fdd\u7559\u7b26\u53f7\u94fe\u63a5\u3001\u6587\u4ef6\u5c5e\u6027\uff0c\u5e76\u590d\u5236\u76ee\u5f55\u4e0b\u7684\u6240\u6709\u5185\u5bb9\u3002\u5176\u4f5c\u7528\u7b49\u4e8e-dpR\u53c2\u6570\u7ec4\u5408\u3002 Option -I : Asks before overwriting. Option -R , -r : Copies directories recursively (the directory and any subdirectories). \u9012\u5f52\u62f7\u8d1d\uff0c\u5305\u542b\u5b50\u76ee\u5f55\u53ca\uff08\u9690\u542b\uff09\u6587\u4ef6\uff0c\u7ee7\u627f\u76ee\u6807\u76ee\u5f55\u7684\u6743\u9650\u548c\u5c5e\u6027\u7b49 Option -l : Makes hardlinks instead of copying (\u521b\u5efa\u786c\u94fe\u63a5\u7684\u53e6\u5916\u4e00\u4e2a\u65b9\u6cd5) Option -s : Makes symbolic instead of copying (\u521b\u5efa\u7b26\u53f7\u94fe\u63a5\u7684\u53e6\u5916\u4e00\u4e2a\u65b9\u6cd5) Option -u : Copies a file only when the source file is newer than the destination file or when the destination file is missing. Option -p : \u8fde\u540c\u6863\u6848\u7684\u5c5e\u6027\u4e00\u8d77\u590d\u5236\u8fc7\u53bb\uff0c\u5305\u62ec\u4fee\u6539\u65f6\u95f4\u3001\u8bbf\u95ee\u6743\u9650\u3001\u6240\u6709\u8005\u7ec4\u7b49\uff0c\u800c\u975e\u4f7f\u7528\u9884\u8bbe\u5c5e\u6027\uff1b Labs: Initiate directories and files mySUSE:~ # su - pmgr pmgr@mySUSE:~> mkdir /data/program pmgr@mySUSE:~> mkdir /data/program/general pmgr@mySUSE:~> mkdir /data/program/general/staffing pmgr@mySUSE:~> touch /data/program/general/program_scope pmgr@mySUSE:~> touch /data/program/general/staffing/assignment mySUSE:~ # su - pm1 pm1@mySUSE:~> mkdir /data/project1 pm1@mySUSE:~> mkdir /data/project1/iot pm1@mySUSE:~> mkdir /data/project1/iot/bigdata pm1@mySUSE:~> touch /data/project1/iot/devicelist pm1@mySUSE:~> touch /data/project1/iot/bigdata/math_lib mySUSE:~ # su - pm2 pm2@mySUSE:~> mkdir /data/project2 pm2@mySUSE:~> mkdir /data/project2/erp pm2@mySUSE:~> mkdir /data/project2/erp/fin pm2@mySUSE:~> touch /data/project2/erp/erp_vision pm2@mySUSE:~> touch /data/project2/erp/fin/fin_ar pm2@mySUSE:~> chmod g+w /data/project2/erp/erp_vision pmgr@mySUSE:~> ln /data/project2/erp/erp_vision /data/program/general/p2_erp_version ( \u521b\u5efa\u786c\u94fe\u63a5\uff0c\u5f53\u524d\u7528\u6237\u9700\u8981\u5bf9\u6e90\u6587\u4ef6erp_vision\u6709w\u6743\u9650 ) pmgr@mySUSE:~> ln -s /data/project1/iot/devicelist /data/program/general/p1_devicelist ( \u521b\u5efa\u7b26\u53f7\u94fe\u63a5\uff0c\u4e0d\u9a8c\u8bc1\u5f53\u524d\u7528\u6237\u662f\u5426\u5bf9\u6e90\u6587\u4ef6devicelist\u6709\u6743\u9650 ) mySUSE:~ # tree /data /data \u251c\u2500\u2500 program \u2502 \u2514\u2500\u2500 general \u2502 \u251c\u2500\u2500 p1_devicelist -> /data/project1/iot/devicelist \u2502 \u251c\u2500\u2500 p2_erp_version \u2502 \u251c\u2500\u2500 program_scope \u2502 \u2514\u2500\u2500 staffing \u2502 \u2514\u2500\u2500 assignment \u251c\u2500\u2500 project1 \u2502 \u2514\u2500\u2500 iot \u2502 \u251c\u2500\u2500 bigdata \u2502 \u2502 \u2514\u2500\u2500 math_lib \u2502 \u2514\u2500\u2500 devicelist \u2514\u2500\u2500 project2 \u2514\u2500\u2500 erp \u251c\u2500\u2500 erp_vision \u2514\u2500\u2500 fin \u2514\u2500\u2500 fin_ar pmgr@mySUSE:~> cp -R /data/project1 /data/program/ ( /data/program/project1\u7684\u7528\u6237\u548c\u7ec4\u90fd\u7ee7\u627f\u4e86/data/program/ ) pmgr@mySUSE:~> cp -a /data/project2 /data/program/ ( /data/program/project2\u7684\u7528\u6237\u7ee7\u627f\u4e86/data/program/\uff0c\u4f46\u7ec4\u8fd8\u662f\u4fdd\u7559\u539f\u6765\u7684 )","title":"cp command"},{"location":"linux/Administration/02/#mv-command","text":"Move or rename a file or directory Option -i : Asks for confirmation before moving or renaming a file. This prevents existing files with the same name from being overwritten. Option -u : Only moves files that are newer than the target files of the same name. pmgr@mySUSE:/data/program/general> cp program_scope ./staffing/ pmgr@mySUSE:/data/program/general> mv -i program_scope ./staffing/ mv: overwrite './staffing/program_scope'? n","title":"mv command"},{"location":"linux/Administration/02/#rm-command","text":"Delete a file or directory Option -i : Asks for confirmation before deleting. Option -r : (recursively) Allows full directories to be deleted. Option -f : (force) By default, rm asks for confirmation if the file that should be deleted is read-only. Using this option, the files are deleted without asking for confirmation.","title":"rm command"},{"location":"linux/Administration/02/#mkdir-command","text":"Create a new directory Option -p lets you create a complete path (\u5c42\u7ea7\u8def\u5f84\u4e00\u6b21\u521b\u5efa) pmgr@mySUSE:/data> mkdir -p industry/utilities pmgr@mySUSE:/data> tree ./industry/ ./industry/ \u2514\u2500\u2500 utilities","title":"mkdir command"},{"location":"linux/Administration/02/#rmdir-command","text":"Remove an empty directory. The directory or directories must be empty before you can delete them.","title":"rmdir command"},{"location":"linux/Administration/02/#ln-command","text":"Create a link Default: Hard link Symbolic link with -s option Syntax: ln [-s] ","title":"ln command"},{"location":"linux/Administration/02/#touch-command","text":"Change the access and modification times Create an empty file if the given file does not exist. Change the time stamp of a file. Option -a : Changes only the time of the last read access (access time). Option -m : Changes only the time of the last modification (modification time). Option -r file : Sets the time stamp of file instead of the current time. Option -t time : Instead of the current time, sets time (structure: [[CC]YY]MMDDhhmm.[ss] ([Century]Year] Month Day Hour Minute [Seconds], two digits in each)) pmgr@mySUSE:/data/industry> touch readme pmgr@mySUSE:/data/industry> touch -a readme pmgr@mySUSE:/data/industry> touch -m readme pmgr@mySUSE:/data/industry> stat readme File: readme Size: 0 Blocks: 0 IO Block: 4096 regular empty file Device: 3dh/61d Inode: 338 Links: 1 Access: (0644/-rw-r--r--) Uid: ( 1003/ pmgr) Gid: ( 1000/ admins) Access: 2019-03-31 10:07:47.489055973 +0800 Modify: 2019-03-31 10:07:58.805109884 +0800 Change: 2019-03-31 10:07:58.805109884 +0800 Birth: -","title":"touch command"},{"location":"linux/Administration/02/#cat-command","text":"Concatenates files","title":"cat command"},{"location":"linux/Administration/02/#tac-command","text":"Same as cat, but displays the file(s) in reverse pmgr@mySUSE:/data/industry> cat readme line 1 line 2 line 3 pmgr@mySUSE:/data/industry> tac readme line 3 line 2 line 1","title":"tac command"},{"location":"linux/Administration/02/#more-command","text":"Display file contents one page at a time","title":"more command"},{"location":"linux/Administration/02/#less-command","text":"Displays file contents for better navigation","title":"less command"},{"location":"linux/Administration/02/#head-command","text":"Displays the first 10 lines of a file. To set the number of lines use the -n option pmgr@mySUSE:/data/industry> head readme line 1 line 2 line 3 line 4 line 5 line 6 line 7 line 8 line 9 line 10 pmgr@mySUSE:/data/industry> head -n 5 readme line 1 line 2 line 3 line 4 line 5","title":"head command"},{"location":"linux/Administration/02/#tail-command","text":"Display the last lines of a file To set the number of lines use the -n option To output appended data use -f option, displays a continuously updated view of the last lines of a file. To exit tail -f, press Ctrl+C. pmgr@mySUSE:/data/industry> tail -n 6 readme line 10 line 11 line 12 line 13 line 14 line 15","title":"tail command"},{"location":"linux/Administration/02/#tar-command","text":"Create, expand or list archive files Use option c to create an archive Use option f to specify the archive file name Use option v for verbose mode Use option x to extract an archive Use option t to list the content of an archive Use option z to (un-)compress the archive with gzip Use option j to (un-)compress the archive with bzip The /etc directory (include sub-directories) is backed up to the /backup/etc.tar file pmgr@mySUSE:~> tar -cvf /data/backup/project1.tar /data/project1/ pmgr@mySUSE:~> tar -cvf /data/backup/project2.tar /data/project2/ pmgr@mySUSE:~> tar -cv --exclude='*.conf' -f /data/backup/project2a.tar /data/project2/ View the contents of an archive. Some .conf files are excluded in project2a.tar file. pmgr@mySUSE:~> tar -tvf /data/backup/project2.tar drwxr-xr-x pm2/project2 0 2019-03-31 16:47 data/project2/ drwxr-xr-x pm2/project2 0 2019-03-31 16:47 data/project2/erp/ drwxr-xr-x pm2/project2 0 2019-03-31 16:47 data/project2/erp/fin/ -rw-r--r-- pm2/project2 0 2019-03-29 16:06 data/project2/erp/fin/fin_ar -rw-r--r-- pm2/project2 0 2019-03-31 16:47 data/project2/erp/fin/fin.conf -rw-rw-r-- pm2/project2 0 2019-03-29 16:06 data/project2/erp/erp_vision -rw-r--r-- pm2/project2 0 2019-03-31 16:47 data/project2/erp/erp.conf -rw-r--r-- pm2/project2 0 2019-03-31 16:47 data/project2/project2.conf pmgr@mySUSE:~> tar -tvf /data/backup/project2a.tar drwxr-xr-x pm2/project2 0 2019-03-31 16:47 data/project2/ drwxr-xr-x pm2/project2 0 2019-03-31 16:47 data/project2/erp/ drwxr-xr-x pm2/project2 0 2019-03-31 16:47 data/project2/erp/fin/ -rw-r--r-- pm2/project2 0 2019-03-29 16:06 data/project2/erp/fin/fin_ar -rw-rw-r-- pm2/project2 0 2019-03-29 16:06 data/project2/erp/erp_vision Unpack and write all files in the archive to the current directory. Extract to another directory by using the -C option pmgr@mySUSE:~> mkdir project1.backup pmgr@mySUSE:~> tar -xvf /data/backup/project1.tar -C /data/backup/project1.backup/ Incremental backup with tar command pmgr@mySUSE:~> tar -g snapshot_program -cvf /data/backup/bkp_program_full.tar /data/program/ pmgr@mySUSE:~> tar -tvf /data/backup/bkp_program_full.tar pmgr@mySUSE:~> touch /data/program/general/general.conf pmgr@mySUSE:~> tar -g snapshot_program -cvf /data/backup/bkp_program_inc.tar /data/program/ pmgr@mySUSE:~> rm -rf program/ pmgr@mySUSE:~> tar -xvf /data/backup/bkp_program_inc.tar -C /data/","title":"tar command"},{"location":"linux/Administration/02/#cpio-command","text":"Another archiving command","title":"cpio command"},{"location":"linux/Administration/02/#gzip-command","text":"Compress files using the gzip algorithm Option -c : Compresses the file without modifying the original file. The result is written to the standard output (usually the screen). From there, it can be redirected to a file with \u201c>\u201d. Option -d : Decompresses the specified file (gunzip) Option -r : Compresses and decompresses files in all subdirectories. Option -1 to -9, --fast, --best : Controls the compression speed: -1 means --fast and causes a quick compression but produces larger files, -9 corresponds to --best and requires more computing time but produces smaller files. The default setting is -6.","title":"gzip command"},{"location":"linux/Administration/02/#gunzip-command","text":"Expand files compressed with gzip","title":"gunzip command"},{"location":"linux/Administration/02/#bzip2-command","text":"Compress files using the bzip2 algorithm Option -c : Option -d : Decompresses the specified file (bunzip2). Option -1 to -9 : Controls the compression speed: -1 causes a quick compression but produces larger files, -9 requires more computing time but produces smaller files. The default setting is -9 .","title":"bzip2 command"},{"location":"linux/Administration/02/#bunzip2-command","text":"Expand files compressed with bzip","title":"bunzip2 command"},{"location":"linux/Administration/02/#rsync-command","text":"Copy only deltas between two directories. A key benefit of using rsync is that when copying data, rsync compares the source and the target directory and transfers only data that has changed or has been created. \u4ec5\u590d\u5236\u4e24\u4e2a\u76ee\u5f55\u4e4b\u95f4\u7684\u589e\u91cf\u3002 \u4f7f\u7528rsync\u7684\u4e00\u4e2a\u4e3b\u8981\u597d\u5904\u662f\uff0c\u5728\u590d\u5236\u6570\u636e\u65f6\uff0crsync\u4f1a\u6bd4\u8f83\u6e90\u76ee\u5f55\u548c\u76ee\u6807\u76ee\u5f55\uff0c\u5e76\u4ec5\u4f20\u8f93\u5df2\u66f4\u6539\u6216\u5df2\u521b\u5efa\u7684\u6570\u636e\u3002 Local or via network \u672c\u5730\u6216\u901a\u8fc7\u7f51\u7edc Uses ssh as default transport \u4f7f\u7528ssh\u4f5c\u4e3a\u9ed8\u8ba4\u4f20\u8f93 Can talk to rsync daemon on the remote machine \u53ef\u4ee5\u4e0e\u8fdc\u7a0b\u8ba1\u7b97\u673a\u4e0a\u7684rsync\u5b88\u62a4\u7a0b\u5e8f\u901a\u4fe1 Note: rsync must be installed on both the source and the target computer for this to work. \u5fc5\u987b\u5728\u6e90\u8ba1\u7b97\u673a\u548c\u76ee\u6807\u8ba1\u7b97\u673a\u4e0a\u5b89\u88c5rsync\u624d\u80fd\u4f7f\u5176\u6b63\u5e38\u5de5\u4f5c\u3002 As the default shell used by rsync is ssh, the -e option only needs to be used when you want to use something else than ssh. \u7531\u4e8ersync\u4f7f\u7528\u7684\u9ed8\u8ba4shell\u662fssh\uff0c\u56e0\u6b64\u53ea\u6709\u5728\u60f3\u8981\u4f7f\u7528\u9664ssh\u4ee5\u5916\u7684\u5176\u4ed6\u5de5\u5177\u65f6\u624d\u9700\u8981\u4f7f\u7528-e\u9009\u9879\u3002 Options Option -a : Puts rsync into the archive mode. The -a option ensures the following are preserved \u4fdd\u7559 in the mirrored copy of the directory: Symbolic links (l option) Access permissions (p option) Owners (o option) Group membership (g option) Time stamp (t option) Option -x : Saves files on one file system only, which means that rsync does not follow symbolic links to other file systems. \u4e0d\u8de8\u6587\u4ef6\u7cfb\u7edf\uff0c\u53ea\u5728\u4e00\u4e2a\u6587\u4ef6\u7cfb\u7edf\u5185(don't cross filesyste* undaries) Option -v : Enables the verbose mode. Use this mode to output information about the transferred files and the progress of the copying process. \u8f93\u51fa\u4f20\u8f93\u8fc7\u7a0b\u7684\u7ec6\u8282\u4fe1\u606f Option -z : Compresses the data during the transfer. This is especially useful for remote synchronization. \u538b\u7f29\u65b9\u5f0f\u4f20\u8f93 Option --delete : Deletes files from the mirrored directory that no longer exist in the original directory. Option --exclude-from : Does not back up files listed in an exclude file. Local backup via rsync command pmgr@mySUSE:/data> rsync -av /data/industry/* /data/backup/industry/ sending incremental file list created directory /data/backup/industry readme utilities/ sent 264 bytes received 87 bytes 702.00 bytes/sec total size is 111 speedup is 0.32 pmgr@mySUSE:/data/industry/utilities> touch roadmap.txt pmgr@mySUSE:/data> rsync -av /data/industry/* /data/backup/industry/ sending incremental file list utilities/ utilities/roadmap.txt sent 171 bytes received 39 bytes 420.00 bytes/sec total size is 111 speedup is 0.53 pmgr@mySUSE:/data> rm roadmap.txt pmgr@mySUSE:/data> rsync -av /data/industry/* --delete /data/backup/industry/ sending incremental file list deleting utilities/roadmap.txt utilities/ sent 102 bytes received 41 bytes 286.00 bytes/sec total size is 111 speedup is 0.78","title":"rsync command"},{"location":"linux/Administration/02/#dd-command","text":"Copies files block by block Used to create disk or partition images Most important options: if =input_file `of``=output_file bs =block_size You can use the dd command to convert and copy files byte-wise. Normally dd reads from the standard input and writes the result to the standard output. But with the appropriate parameters, regular files can be addressed as well. You can copy all kinds of Linux data with this command, including entire hard disk partitions. You can even copy an entire installed system (or just parts of it). Copy file /etc/protocols to protocols.old. The default size for a record is 512 bytes. Below 45+1 means, 45 complete record of standard size and 1 incomplete record (less than 512 bytes pmgr@mySUSE:/data/program> dd if=/etc/protocols of=protocols.old bs=512 45+1 records in 45+1 records out 23259 bytes (23 kB, 23 KiB) copied, 0.000595392 s, 39.1 MB/s \u521b\u5efa\u4e00\u4e2a100M\u7684\u7a7a\u6587\u4ef6 pmgr@mySUSE:/data/program> dd if=/dev/zero of=datafile bs=100M count=2 2+0 records in 2+0 records out 209715200 bytes (210 MB, 200 MiB) copied, 2.79311 s, 75.1 MB/s \u5907\u4efd\u6574\u4e2a\u5206\u533a #dd if=/dev/sda1 of=boot.partition \u5236\u4f5cU\u76d8\u542f\u52a8\u76d8\uff08U\u76d8\u6302\u8f7d\u5230/dev/sdb\uff09 #dd if=/root/diskboot.img of=/dev/sdb bs=125682176 \u5907\u4efd\u786c\u76d8\u4e3b\u5f15\u5bfc\u8bb0\u5f55 #dd if=/dev/sda of=/tmp/mbr_copy bs=512 count=1 \u8fd8\u539f\u786c\u76d8\u4e3b\u5f15\u5bfc\u8bb0\u5f55 #dd if=/disk.mbr of=/dev/hda bs=512 count=1 \u5c06\u5185\u5b58\u91cc\u7684\u6570\u636e\u62f7\u8d1d\u5230root\u76ee\u5f55\u4e0b\u7684mem.bin\u6587\u4ef6 # dd if=/dev/mem of=/root/mem.bin bs=1024 \u62f7\u8d1d\u5149\u76d8\u6570\u636e\u5230root\u6587\u4ef6\u5939\u4e0b\uff0c\u5e76\u4fdd\u5b58\u4e3acd.iso\u6587\u4ef6 # dd if=/dev/cdrom of=/root/cd.iso \u5229\u7528\u968f\u673a\u7684\u6570\u636e\u586b\u5145\u786c\u76d8(\u9500\u6bc1\u786c\u76d8\u6570\u636e) # dd if=/dev/urandom of=/dev/hda1 \u6d4b\u8bd5\u786c\u76d8\u8bfb\u5199\u901f\u5ea6\u3002\u901a\u8fc7\u4e24\u4e2a\u547d\u4ee4\u8f93\u51fa\u7684\u6267\u884c\u65f6\u95f4\uff0c\u53ef\u4ee5\u8ba1\u7b97\u51fa\u6d4b\u8bd5\u786c\u76d8\u7684\u8bfb\uff0f\u5199\u901f\u5ea6\uff1a mySUSE:/data # dd if=/data/program/datafile bs=64k | dd of=/dev/null 3200+0 records in 3200+0 records out 209715200 bytes (210 MB, 200 MiB) copied, 0.67138 s, 312 MB/s 409600+0 records in 409600+0 records out 209715200 bytes (210 MB, 200 MiB) copied, 0.675912 s, 310 MB/s # dd if=/dev/zero of=/data/program/datafile bs=1024 count=100 \u5207\u5272\u5927\u6587\u4ef6bigfile\uff0c\u517198336321\u5b57\u8282\uff0c\u5219\uff1a # dd if=bigfile of=smallfile1 bs=1 count=20000000 # dd if=bigfile of=smallfile2 bs=1 count=20000000 skip=20000000 # dd if=bigfile of=smallfile3 bs=1 count=20000000 skip=40000000 # dd if=bigfile of=smallfile4 bs=1 count=20000000 skip=60000000 # dd if=bigfile of=smallfile5 bs=1 count=18336321 skip=80000000 \u5c06\u5207\u5272\u6587\u4ef6\u7ec4\u88c5 # dd if=smallfile1 of=bigfile bs=1 count=20000000 # dd if=smallfile2 of=bigfile bs=1 count=20000000 seek=20000000 # dd if=smallfile3 of=bigfile bs=1 count=20000000 seek=40000000 # dd if=smallfile4 of=bigfile bs=1 count=20000000 seek=60000000 # dd if=smallfile5 of=bigfile bs=1 count=18336321 seek=80000000 if: \u8981\u5207\u5272\u7684\u5927\u6587\u4ef6\u540d of: \u5207\u5272\u540e\u7684\u5b50\u6587\u4ef6\u540d bs: \u4ee5\u591a\u5c11\u5b57\u8282\u4f5c\u4e3a\u4e00\u4e2a\u5207\u5272\u8bb0\u5f55\u5355\u4f4d count: \u662f\u8981\u5207\u5272\u7684\u5355\u4f4d\u8bb0\u5f55\u6570 skip: \u8bf4\u660e\u5207\u5272\u65f6\u7684\u8d77\u70b9 seek: \u660e\u786e\u6307\u51fa\u5f00\u59cb\u4f4d\u7f6e","title":"dd command"},{"location":"linux/Administration/02/#find-command","text":"Search for files or directories Syntax: find path criterion [action] The find command has a multitude of options, a few of which are explained here. You can use the following arguments with the command: path: The section of the file system to search (the specified directory and all its subdirectories). If nothing is specified, the file system below the current directory is used. criterion: The properties the file should have (see below) action: Options that influence the following conditions or control the search as a whole The most important actions are: -print (default) -exec command With the -exec option, you can call up another command. This option is frequently used to link find and grep, as in the following: \u627e\u51fagen\u5f00\u5934\u7684\u6587\u4ef6 pmgr@dcmaster:/data> find . -name gen\\* ./program/general ./program/general/general.conf \u627e\u51fagen\u5f00\u5934\u7684\u6587\u4ef6\uff0c\u5e76\u5728\u6587\u4ef6\u5185\u5bb9\u4e2d\u67e5\u627exen\uff0c\u627e\u5230\u540e\u7ed3\u679c\u8f93\u51faxen pmgr@dcmaster:/data> find . -name gen\\* -type f -exec grep xen {} \\; xen xening The two brackets \u201c{}\u201d stand as placeholders for the file names which are found and passed to the grep command. The semicolon closes the -exec instruction. Because this is a special character, it is masked by placing a backslash in front of it. -ctime [\u00b1]days Searches for files whose last change took place no later than (no earlier than) a specified number of days ago. \u5728\u8fc7\u53bbn\u5929\u5185\u88ab\u4fee\u6539\u8fc7\u7684\u6587\u4ef6 mgr@dcmaster:/data> find . -ctime 1 . ./program/datafile -gid number Searches for files with the numeric GID (Group ID) number. (gid \u662f n) -group name Searches for files that are owned by the group name. Instead of a name, the numeric GID is allowed. (group \u540d\u79f0\u662f name) -name pattern Searches for files whose names contain the given pattern. If the pattern contains meta characters or wild cards, the name must be enclosed by quotation marks. Otherwise thename will be interpreted by the shell and not by find. -newer file Searches for files that were modified more recently than file. \u6bd4\u6587\u4ef6 file \u66f4\u65b0\u7684\u6587\u4ef6 pmgr@dcmaster:/data> find . -cnewer ./program/datafile . -size [\u00b1]size Matches files that are above or below a certain size. The size (in blocks of 512 bytes) is given as an argument. The suffix \u201cc\u201cswitches to byte and \u201ck\u201d to blocks of 1024bytes. A preceding \u201c+\u201d stands for all larger files and a \u201c-\u201d for all smaller files. (\u6587\u4ef6\u5927\u5c0f \u662f n \u2022 b \u4ee3\u8868 512 \u4f4d\u5143\u7ec4\u7684\u533a\u5757 \u2022 c \u8868\u793a\u5b57\u5143\u6570 \u2022 k \u8868\u793a kilo bytes \u2022 w \u662f\u4e8c\u4e2a\u4f4d\u5143\u7ec4 pmgr@dcmaster:/data> find . -size 20k ./backup/project2.tar -type file_type Searches for a file type. A file type can be one of the following: * c : \u6587\u4ef6\u7c7b\u578b\u662f c \u7684\u6587\u4ef6\u3002 * d: \u76ee\u5f55 * c: \u5b57\u578b\u88c5\u7f6e\u6587\u4ef6 * b: \u533a\u5757\u88c5\u7f6e\u6587\u4ef6 * p: \u5177\u540d\u8d2e\u5217 * f: \u4e00\u822c\u6587\u4ef6 * l: \u7b26\u53f7\u8fde\u7ed3 * s: socket -uid number Searches for files with the numeric UID (User ID) number. -user name Searches for files, which are owned by user name. Instead of a name, the numeric UID is allowed. \u5e38\u7528\u53c2\u6570 mount, -xdev : \u53ea\u68c0\u67e5\u548c\u6307\u5b9a\u76ee\u5f55\u5728\u540c\u4e00\u4e2a\u6587\u4ef6\u7cfb\u7edf\u4e0b\u7684\u6587\u4ef6\uff0c\u907f\u514d\u5217\u51fa\u5176\u5b83\u6587\u4ef6\u7cfb\u7edf\u4e2d\u7684\u6587\u4ef6 amin n : \u5728\u8fc7\u53bb n \u5206\u949f\u5185\u88ab\u8bfb\u53d6\u8fc7 anewer file : \u6bd4\u6587\u4ef6 file \u66f4\u665a\u88ab\u8bfb\u53d6\u8fc7\u7684\u6587\u4ef6 atime n : \u5728\u8fc7\u53bbn\u5929\u5185\u88ab\u8bfb\u53d6\u8fc7\u7684\u6587\u4ef6 pmgr@dcmaster:/data> find . -atime 1 ./program/datafile cmin n : \u5728\u8fc7\u53bb n \u5206\u949f\u5185\u88ab\u4fee\u6539\u8fc7 pmgr@dcmaster:/data> find . -cmin 20 empty : \u7a7a\u7684\u6587\u4ef6 ipath p, -path p : \u8def\u5f84\u540d\u79f0\u7b26\u5408 p \u7684\u6587\u4ef6\uff0cipath \u4f1a\u5ffd\u7565\u5927\u5c0f\u5199 name name, -iname name : \u6587\u4ef6\u540d\u79f0\u7b26\u5408 name \u7684\u6587\u4ef6\u3002iname \u4f1a\u5ffd\u7565\u5927\u5c0f\u5199 pid n : process id \u662f n \u7684\u6587\u4ef6 \u67e5\u627e\u5f53\u524d\u76ee\u5f55\u53ca\u5b50\u76ee\u5f55\u4e2d\u6240\u6709\u6587\u4ef6\u957f\u5ea6\u4e3a0\u7684\u666e\u901a\u6587\u4ef6\uff0c\u5e76\u5217\u51fa\u5b83\u4eec\u7684\u5b8c\u6574\u8def\u5f84 pmgr@dcmaster:/data> find . -type f -size 0 -exec ls -l {} \\; \u67e5\u627e\u524d\u76ee\u5f55\u4e2d\u6587\u4ef6\u5c5e\u4e3b\u5177\u6709\u8bfb\u3001\u5199\u6743\u9650\uff0c\u5e76\u4e14\u6587\u4ef6\u6240\u5c5e\u7ec4\u7684\u7528\u6237\u548c\u5176\u4ed6\u7528\u6237\u5177\u6709\u8bfb\u6743\u9650\u7684\u6587\u4ef6 pmgr@dcmaster:/data> find . -type f -perm 644 -exec ls -l {} \\; \u67e5\u627e/var/log\u76ee\u5f55\u4e2d\u66f4\u6539\u65f6\u95f4\u572817\u65e5\u4ee5\u524d\u7684\u666e\u901a\u6587\u4ef6\uff0c\u5e76\u5728\u5220\u9664\u4e4b\u524d\u8be2\u95ee\u5b83\u4eec pmgr@dcmaster:/data> find /var/log -type f -mtime +17 -ok rm {} \\; \u5c06\u76ee\u524d\u76ee\u5f55\u53ca\u5176\u5b50\u76ee\u5f55\u4e0b\u6240\u6709\u6700\u8fd1 1 \u5929\u5185\u66f4\u65b0\u8fc7\u7684\u6587\u4ef6\u5217\u51fa mgr@dcmaster:/data> find . -ctime 1 \u5c06\u76ee\u524d\u76ee\u5f55\u5176\u5176\u4e0b\u5b50\u76ee\u5f55\u4e2d\u6240\u6709\u4e00\u822c\u6587\u4ef6\u5217\u51fa pmgr@dcmaster:/data> find . -type f \u5c06\u76ee\u524d\u76ee\u5f55\u53ca\u5176\u5b50\u76ee\u5f55\u4e0b\u6240\u6709\u5ef6\u4f38\u6863\u540d\u662fconf \u7684\u6587\u4ef6\u5217\u51fa\u6765 pmgr@dcmaster:/data> find . -name \"*.conf\"","title":"find command"},{"location":"linux/Administration/02/#which-command","text":"Searches all paths listed in the variable $PATH and returns the full path of the command The which command searches all paths listed in the variable $PATH for the specified command and returns the full path of the command. In the variable \\(PATH, the most important directoriesare listed where the shell looks for executable files. which\u547d\u4ee4\u641c\u7d22\u53d8\u91cf\\) PATH\u4e2d\u5217\u51fa\u7684\u6240\u6709\u8def\u5f84\u4ee5\u83b7\u53d6\u6307\u5b9a\u547d\u4ee4\uff0c\u5e76\u8fd4\u56de\u547d\u4ee4\u7684\u5b8c\u6574\u8def\u5f84\u3002 The which command is especially useful if several versions of a command exist in different directories and you want to know which version is executed when entered without specifying apath. \u5982\u679c\u547d\u4ee4\u7684\u591a\u4e2a\u7248\u672c\u5b58\u5728\u4e8e\u4e0d\u540c\u7684\u76ee\u5f55\u4e2d\uff0c\u5e76\u4e14\u60a8\u60f3\u77e5\u9053\u5728\u8f93\u5165\u65f6\u6267\u884c\u4e86\u54ea\u4e2a\u7248\u672c\u800c\u672a\u6307\u5b9a\u8def\u5f84\uff0c\u90a3\u4e48which\u547d\u4ee4\u7279\u522b\u6709\u7528\u3002 NOTE: To see the content of a variable, use the echo command Options Description -n<\u6587\u4ef6\u540d\u957f\u5ea6> \u6307\u5b9a\u6587\u4ef6\u540d\u957f\u5ea6\uff0c\u6307\u5b9a\u7684\u957f\u5ea6\u5fc5\u987b\u5927\u4e8e\u6216\u7b49\u4e8e\u6240\u6709\u6587\u4ef6\u4e2d\u6700\u957f\u7684\u6587\u4ef6\u540d\u3002 -p<\u6587\u4ef6\u540d\u957f\u5ea6> \u4e0e-n\u53c2\u6570\u76f8\u540c\uff0c\u4f46\u6b64\u5904\u7684<\u6587\u4ef6\u540d\u957f\u5ea6>\u5305\u62ec\u4e86\u6587\u4ef6\u7684\u8def\u5f84\u3002 -w \u6307\u5b9a\u8f93\u51fa\u65f6\u680f\u4f4d\u7684\u5bbd\u5ea6\u3002 -V \u663e\u793a\u7248\u672c\u4fe1\u606f # which grep /usr/bin/grep # which -V grep GNU which v2.21, Copyright (C) 1999 - 2015 Carlo Wood. GNU which comes with ABSOLUTELY NO WARRANTY; This program is free software; your freedom to use, change and distribute this program is protected by the GPL.","title":"which command"},{"location":"linux/Administration/02/#whereis-command","text":"The whereis command returns the binaries (option -b), manual pages (option -m), and the source code (option -s) of the specified command. If no option is used, all this information is returned, provided the information is available. This command is faster than find, but it is less thorough. Attempts to locate the desired program in the standard Linux places, and in the places specified by $PATH and $MANPATH . \u5c1d\u8bd5\u5728\u6807\u51c6Linux\u4f4d\u7f6e\u548c\u6307\u5b9a\u4f4d\u7f6e( \\(PATH\u548c\\) MANPATH)\u627e\u5230\u6240\u9700\u7684\u7a0b\u5e8f Options Description -b \u53ea\u67e5\u627e\u4e8c\u8fdb\u5236\u6587\u4ef6\u3002 -B<\u76ee\u5f55> \u53ea\u5728\u8bbe\u7f6e\u7684\u76ee\u5f55\u4e0b\u67e5\u627e\u4e8c\u8fdb\u5236\u6587\u4ef6\u3002 -f \u4e0d\u663e\u793a\u6587\u4ef6\u540d\u524d\u7684\u8def\u5f84\u540d\u79f0\u3002 -m \u53ea\u67e5\u627e\u8bf4\u660e\u6587\u4ef6\u3002 -M<\u76ee\u5f55> \u53ea\u5728\u8bbe\u7f6e\u7684\u76ee\u5f55\u4e0b\u67e5\u627e\u8bf4\u660e\u6587\u4ef6\u3002 -s \u53ea\u67e5\u627e\u539f\u59cb\u4ee3\u7801\u6587\u4ef6\u3002 -S<\u76ee\u5f55> \u53ea\u5728\u8bbe\u7f6e\u7684\u76ee\u5f55\u4e0b\u67e5\u627e\u539f\u59cb\u4ee3\u7801\u6587\u4ef6\u3002 -u \u67e5\u627e\u4e0d\u5305\u542b\u6307\u5b9a\u7c7b\u578b\u7684\u6587\u4ef6\u3002 \u4ee5\u4e0b\u8f93\u51fa\u4fe1\u606f\u4ece\u5de6\u81f3\u53f3\u5206\u522b\u4e3a\u67e5\u8be2\u7684\u7a0b\u5e8f\u540d\u3001bash\u8def\u5f84\u3001bash\u7684man\u624b\u518c\u9875\u8def\u5f84\u3002 # whereis grep grep: /usr/bin/grep /bin/grep /usr/share/man/man1/grep.1.gz /usr/share/info/grep.info.gz \u663e\u793abash \u547d\u4ee4\u7684\u4e8c\u8fdb\u5236\u7a0b\u5e8f # whereis -b grep grep: /usr/bin/grep /bin/grep \u663e\u793abash \u547d\u4ee4\u7684\u5e2e\u52a9\u6587\u4ef6 # whereis -m grep grep: /usr/share/man/man1/grep.1.gz /usr/share/info/grep.info.gz","title":"whereis command"},{"location":"linux/Administration/02/#type-command","text":"The type command shows what kind of command is executed when you enter it: \u547d\u4ee4\u7684\u7c7b\u578b a shell built-in command (an essential command that is hard coded in the shell), for example type or cd an external command (called by the shell) an alias, for example ls. An alias defines shortcuts and synonyms for commonly used shell commands. a function The -a option delivers all instances of a command bearing this name in the file system. NOTE: If you want to have more information about a file format, you can use the file command. \u4e0d\u9002\u7528\u4e8e\u666e\u901a\u6587\u4ef6 dcmaster:/data/shell # type pwd.txt -bash: type: pwd.txt: not found \u4e0d\u9002\u7528\u4e8e\u81ea\u5b9a\u4e49\u53ef\u6267\u884c\u811a\u672c dcmaster:/data/shell # type math.sh -bash: type: math.sh: not found \u7cfb\u7edf\u547d\u4ee4 dcmaster:/data/shell # type rsync rsync is /usr/bin/rsync \u522b\u540d dcmaster:/data/shell # type l l is aliased to `ls -alF'","title":"type command"},{"location":"linux/Administration/02/#file-command","text":"file\u547d\u4ee4\u7528\u4e8e\u8fa8\u8bc6\u6587\u4ef6\u7c7b\u578b -b \u5217\u51fa\u8fa8\u8bc6\u7ed3\u679c\u65f6\uff0c\u4e0d\u663e\u793a\u6587\u4ef6\u540d\u79f0\u3002 -c \u8be6\u7ec6\u663e\u793a\u6307\u4ee4\u6267\u884c\u8fc7\u7a0b\uff0c\u4fbf\u4e8e\u6392\u9519\u6216\u5206\u6790\u7a0b\u5e8f\u6267\u884c\u7684\u60c5\u5f62\u3002 -f <\u540d\u79f0\u6587\u4ef6> \u6307\u5b9a\u540d\u79f0\u6587\u4ef6\uff0c\u5176\u5185\u5bb9\u6709\u4e00\u4e2a\u6216\u591a\u4e2a\u6587\u4ef6\u540d\u79f0\u65f6\uff0c\u8ba9file\u4f9d\u5e8f\u8fa8\u8bc6\u8fd9\u4e9b\u6587\u4ef6\uff0c\u683c\u5f0f\u4e3a\u6bcf\u5217\u4e00\u4e2a\u6587\u4ef6\u540d\u79f0\u3002 -L \u76f4\u63a5\u663e\u793a\u7b26\u53f7\u8fde\u63a5\u6240\u6307\u5411\u7684\u6587\u4ef6\u7684\u7c7b\u522b\u3002 -m<\u9b54\u6cd5\u6570\u5b57\u6587\u4ef6> \u6307\u5b9a\u9b54\u6cd5\u6570\u5b57\u6587\u4ef6\u3002 -v \u663e\u793a\u7248\u672c\u4fe1\u606f\u3002 -z \u5c1d\u8bd5\u53bb\u89e3\u8bfb\u538b\u7f29\u6587\u4ef6\u7684\u5185\u5bb9\u3002 dcmaster:/data/linktype # l -rw-r--r-- 3 root root 44 May 3 09:50 file -rw-r--r-- 3 root root 44 May 3 09:50 hardlinkfile1 -rw-r--r-- 3 root root 44 May 3 09:50 hardlinkfile2 lrwxrwxrwx 1 root root 4 Mar 28 15:21 symlinkfile1 -> file lrwxrwxrwx 1 root root 12 Mar 28 15:49 symlinkfile1-1 -> symlinkfile1 lrwxrwxrwx 1 root root 4 Mar 28 15:23 symlinkfile2 -> file dcmaster:/data/linktype # file hardlinkfile1 hardlinkfile1: ASCII text dcmaster:/data/linktype # file -i hardlinkfile1 hardlinkfile1: text/plain; charset=us-ascii dcmaster:/data/linktype # file /data/linktype/ /data/linktype/: directory dcmaster:/data/linktype # file -L /data/linktype/ /data/linktype/: directory dcmaster:/data/linktype # file -i /data/linktype/ /data/linktype/: inode/directory; charset=binary dcmaster:/data/linktype # file symlinkfile1 symlinkfile1: symbolic link to file dcmaster:/data/linktype # file -i symlinkfile1 symlinkfile1: inode/symlink; charset=binary","title":"file command"},{"location":"linux/Administration/02/#grep-command","text":"You can specify search patterns in the form of regular expressions, although the basic grep command is limited in this regard. To search for more complex patterns, use the egrep command (or grep -E ) instead, which accepts extended regular expressions. To avoid having special characters in search patterns interpreted by the shell, enclose the pattern in quotation marks. Syntax: grep [options] search_pattern filename * egrep = grep -E * rgrep \u53c2\u6570 -a \u6216 --text : \u4e0d\u8981\u5ffd\u7565\u4e8c\u8fdb\u5236\u7684\u6570\u636e\u3002 -A<\u663e\u793a\u884c\u6570> \u6216 --after-context=<\u663e\u793a\u884c\u6570> : \u9664\u4e86\u663e\u793a\u7b26\u5408\u8303\u672c\u6837\u5f0f\u7684\u90a3\u4e00\u5217\u4e4b\u5916\uff0c\u5e76\u663e\u793a\u8be5\u884c\u4e4b\u540e\u7684\u5185\u5bb9\u3002 -b \u6216 --byte-offset : \u5728\u663e\u793a\u7b26\u5408\u6837\u5f0f\u7684\u90a3\u4e00\u884c\u4e4b\u524d\uff0c\u6807\u793a\u51fa\u8be5\u884c\u7b2c\u4e00\u4e2a\u5b57\u7b26\u7684\u7f16\u53f7\u3002 -B<\u663e\u793a\u884c\u6570> \u6216 --before-context=<\u663e\u793a\u884c\u6570> : \u9664\u4e86\u663e\u793a\u7b26\u5408\u6837\u5f0f\u7684\u90a3\u4e00\u884c\u4e4b\u5916\uff0c\u5e76\u663e\u793a\u8be5\u884c\u4e4b\u524d\u7684\u5185\u5bb9\u3002 -c \u6216 --count : \u8ba1\u7b97\u7b26\u5408\u6837\u5f0f\u7684\u5217\u6570\u3002 -C<\u663e\u793a\u884c\u6570> \u6216 --context=<\u663e\u793a\u884c\u6570> \u6216 -<\u663e\u793a\u884c\u6570> : \u9664\u4e86\u663e\u793a\u7b26\u5408\u6837\u5f0f\u7684\u90a3\u4e00\u884c\u4e4b\u5916\uff0c\u5e76\u663e\u793a\u8be5\u884c\u4e4b\u524d\u540e\u7684\u5185\u5bb9\u3002 -d <\u52a8\u4f5c> \u6216 --directories=<\u52a8\u4f5c> : \u5f53\u6307\u5b9a\u8981\u67e5\u627e\u7684\u662f\u76ee\u5f55\u800c\u975e\u6587\u4ef6\u65f6\uff0c\u5fc5\u987b\u4f7f\u7528\u8fd9\u9879\u53c2\u6570\uff0c\u5426\u5219grep\u6307\u4ee4\u5c06\u56de\u62a5\u4fe1\u606f\u5e76\u505c\u6b62\u52a8\u4f5c\u3002 -e<\u8303\u672c\u6837\u5f0f> \u6216 --regexp=<\u8303\u672c\u6837\u5f0f> : \u6307\u5b9a\u5b57\u7b26\u4e32\u505a\u4e3a\u67e5\u627e\u6587\u4ef6\u5185\u5bb9\u7684\u6837\u5f0f\u3002 -E \u6216 --extended-regexp : \u5c06\u6837\u5f0f\u4e3a\u5ef6\u4f38\u7684\u666e\u901a\u8868\u793a\u6cd5\u6765\u4f7f\u7528\u3002 -f<\u89c4\u5219\u6587\u4ef6> \u6216 --file=<\u89c4\u5219\u6587\u4ef6> : \u6307\u5b9a\u89c4\u5219\u6587\u4ef6\uff0c\u5176\u5185\u5bb9\u542b\u6709\u4e00\u4e2a\u6216\u591a\u4e2a\u89c4\u5219\u6837\u5f0f\uff0c\u8ba9grep\u67e5\u627e\u7b26\u5408\u89c4\u5219\u6761\u4ef6\u7684\u6587\u4ef6\u5185\u5bb9\uff0c\u683c\u5f0f\u4e3a\u6bcf\u884c\u4e00\u4e2a\u89c4\u5219\u6837\u5f0f\u3002 -F \u6216 --fixed-regexp : \u5c06\u6837\u5f0f\u89c6\u4e3a\u56fa\u5b9a\u5b57\u7b26\u4e32\u7684\u5217\u8868\u3002 -G \u6216 --basic-regexp : \u5c06\u6837\u5f0f\u89c6\u4e3a\u666e\u901a\u7684\u8868\u793a\u6cd5\u6765\u4f7f\u7528\u3002 -h \u6216 --no-filename : \u5728\u663e\u793a\u7b26\u5408\u6837\u5f0f\u7684\u90a3\u4e00\u884c\u4e4b\u524d\uff0c\u4e0d\u6807\u793a\u8be5\u884c\u6240\u5c5e\u7684\u6587\u4ef6\u540d\u79f0\u3002 -H \u6216 --with-filename : \u5728\u663e\u793a\u7b26\u5408\u6837\u5f0f\u7684\u90a3\u4e00\u884c\u4e4b\u524d\uff0c\u8868\u793a\u8be5\u884c\u6240\u5c5e\u7684\u6587\u4ef6\u540d\u79f0\u3002 -i \u6216 --ignore-case : \u5ffd\u7565\u5b57\u7b26\u5927\u5c0f\u5199\u7684\u5dee\u522b\u3002 -l \u6216 --file-with-matches : \u5217\u51fa\u6587\u4ef6\u5185\u5bb9\u7b26\u5408\u6307\u5b9a\u7684\u6837\u5f0f\u7684\u6587\u4ef6\u540d\u79f0\u3002 -L \u6216 --files-without-match : \u5217\u51fa\u6587\u4ef6\u5185\u5bb9\u4e0d\u7b26\u5408\u6307\u5b9a\u7684\u6837\u5f0f\u7684\u6587\u4ef6\u540d\u79f0\u3002 -n \u6216 --line-number : \u5728\u663e\u793a\u7b26\u5408\u6837\u5f0f\u7684\u90a3\u4e00\u884c\u4e4b\u524d\uff0c\u6807\u793a\u51fa\u8be5\u884c\u7684\u5217\u6570\u7f16\u53f7\u3002 -o \u6216 --only-matching : \u53ea\u663e\u793a\u5339\u914dPATTERN \u90e8\u5206\u3002 -q \u6216 --quiet\u6216--silent : \u4e0d\u663e\u793a\u4efb\u4f55\u4fe1\u606f\u3002 -r \u6216 --recursive : \u6b64\u53c2\u6570\u7684\u6548\u679c\u548c\u6307\u5b9a\"-d recurse\"\u53c2\u6570\u76f8\u540c\u3002 -s \u6216 --no-messages : \u4e0d\u663e\u793a\u9519\u8bef\u4fe1\u606f\u3002 -v \u6216 --revert-match : \u663e\u793a\u4e0d\u5305\u542b\u5339\u914d\u6587\u672c\u7684\u6240\u6709\u884c\u3002 -V \u6216 --version : \u663e\u793a\u7248\u672c\u4fe1\u606f\u3002 -w \u6216 --word-regexp : \u53ea\u663e\u793a\u5168\u5b57\u7b26\u5408\u7684\u5217\u3002 -x --line-regexp : \u53ea\u663e\u793a\u5168\u5217\u7b26\u5408\u7684\u5217\u3002 -y : \u6b64\u53c2\u6570\u7684\u6548\u679c\u548c\u6307\u5b9a\"-i\"\u53c2\u6570\u76f8\u540c\u3002 \u5728\u5f53\u524d\u76ee\u5f55\u4e2d\uff0c\u67e5\u627e\u540e\u7f00\u6709conf\u5b57\u6837\u7684\u6587\u4ef6\u4e2d\u5305\u542bxen\u5b57\u7b26\u4e32\u7684\u6587\u4ef6\uff0c\u5e76\u6253\u5370\u51fa\u8be5\u5b57\u7b26\u4e32\u7684\u884c\u3002 pmgr@dcmaster:/data/program/general> grep xen *.conf xen xening \u67e5\u627e\u524d\u7f00\u6709gen\u7684\u6587\u4ef6\u5305\u542bxen\u5b57\u7b26\u4e32\u7684\u6587\u4ef6 pmgr@dcmaster:/data/program/general> grep xen gen* xen xening \u4ee5\u9012\u5f52\u7684\u65b9\u5f0f\u67e5\u627e\u7b26\u5408\u6761\u4ef6\u7684\u6587\u4ef6\u3002\u67e5\u627e\u6307\u5b9a\u76ee\u5f55/data/program/\u53ca\u5176\u5b50\u76ee\u5f55\uff08\u5982\u679c\u5b58\u5728\u5b50\u76ee\u5f55\u7684\u8bdd\uff09\u4e0b\u6240\u6709\u6587\u4ef6\u4e2d\u5305\u542b\u5b57\u7b26\u4e32xen\u7684\u6587\u4ef6\uff0c\u5e76\u6253\u5370\u51fa\u8be5\u5b57\u7b26\u4e32\u6240\u5728\u884c\u7684\u5185\u5bb9 pmgr@dcmaster:/data> grep -r xen /data/program/ ./program/general/general.conf:xen ./program/general/general.conf:xening \u53cd\u5411\u67e5\u627e\u3002\u524d\u9762\u5404\u4e2a\u4f8b\u5b50\u662f\u67e5\u627e\u5e76\u6253\u5370\u51fa\u7b26\u5408\u6761\u4ef6\u7684\u884c\uff0c\u901a\u8fc7 -v \u53c2\u6570\u53ef\u4ee5\u6253\u5370\u51fa\u4e0d\u7b26\u5408\u6761\u4ef6\u884c\u7684\u5185\u5bb9\u3002\u67e5\u627e\u6587\u4ef6\u540d\u4e2d\u5305\u542bxen\u7684\u6587\u4ef6\u4e2d\u4e0d\u5305\u542bxen\u7684\u884c pmgr@dcmaster:/data/program/general> grep -v xen gen* Linux Test test \u67e5\u627e\u5f53\u524d\u76ee\u5f55\u4e0b\u5305\u542b\u5b57\u7b26\u4e32\u201cLinux\u201d\u7684\u6587\u4ef6 pmgr@dcmaster:/data/program/general> grep Linux * general.conf:Linux grep: staffing: Is a directory pmgr@dcmaster:/data/program/general> egrep Linux * general.conf:Linux grep: staffing: Is a directory","title":"grep command"},{"location":"linux/Administration/03/","text":"Shell \u00b6","title":"Shell"},{"location":"linux/Administration/03/#shell","text":"","title":"Shell"},{"location":"linux/SES/linux_ses_demo/","text":"SUSE Enterprise Storage 6 Installation and Basic Operation \u00b6 1. Installation \u00b6 1.1. Environment Setup \u00b6 In this demo, I use below environment, including VM setting and software installed. All VMs installed here was built on a physical host 10.58.121.68 . Host Server: 10.58.121.68 root / rootroot Account root / root123 Gateway: 10.58.120.1 Network Mask: 255.255.254.0 Nameserver: 10.58.32.32 10.33.50.20 Domain Search sha.me.corp dhcp.sha.me.corp me.corp ind.me.corp bgr.me.corp SUSE Server 15 SP1 Extensions and Modules were installed as below. [x] SUSE Enterprise Storage 6 [x] Basesystem Module 15 SP1 x86_64 [x] Server Applications Module 15 SP1 x86_64 Disable Services is as below: AppArmor Firewall Enable Services is as below. SSH Register SLES15.1 to local SMT. # SUSEConnect --url https://smtproxy.ind.me.corp Demo Environment summary is below. Alias Host Name Memory Disk eth0 eth0 mac address sles01 admin (salt-master) 16GB Disk1: 20G 10.58.121.181/23 52:54:00:23:7d:cd sles02 data1 16GB Disk1: 20G 10.58.121.182/23 52:54:00:5f:ce:6f Disk2: 8G Disk3: 8G Disk4: 8G sles03 data2 16GB Disk1: 20G 10.58.121.183/23 52:54:00:6f:f2:23 Disk2: 8G Disk3: 8G Disk4: 8G sles04 data3 16GB Disk1: 20G 10.58.121.184/23 52:54:00:93:4c:67 Disk2: 8G Disk3: 8G Disk4: 8G sles05 data4 16GB Disk1: 20G 10.58.121.185/23 52:54:00:90:b0:b0 Disk2: 8G Disk3: 8G Disk4: 8G sles06 mon1 16GB Disk1: 20G 10.58.121.186/23 52:54:00:46:43:7a sles07 mon2 16GB Disk1: 20G 10.58.121.187/23 52:54:00:00:fe:6b sles08 mon3 16GB Disk1: 20G 10.58.121.188/23 52:54:00:60:a3:92 Add hostname to file /etc/hosts (all nodes) If you do not specify a cluster network during Ceph deployment, it assumes a single public network environment. Make sure that the fully qualified domain name (FQDN) of each node can be resolved to the public network IP address by all other nodes. # vi /etc/hosts 10.58.121.181 admin.sha.me.corp admin salt 10.58.121.182 data1.sha.me.corp data1 10.58.121.183 data2.sha.me.corp data2 10.58.121.184 data3.sha.me.corp data3 10.58.121.185 data4.sha.me.corp data4 10.58.121.186 mon1.sha.me.corp mon1 10.58.121.187 mon2.sha.me.corp mon2 10.58.121.188 mon3.sha.me.corp mon3 Add all nodes as trust ssh access (root account) # cd ~ # ssh-keygen -t rsa # ssh-copy-id -i ~/.ssh/id_rsa.pub root@admin # ssh-copy-id -i ~/.ssh/id_rsa.pub root@data1 # ssh-copy-id -i ~/.ssh/id_rsa.pub root@data2 # ssh-copy-id -i ~/.ssh/id_rsa.pub root@data3 # ssh-copy-id -i ~/.ssh/id_rsa.pub root@data4 # ssh-copy-id -i ~/.ssh/id_rsa.pub root@mon1 # ssh-copy-id -i ~/.ssh/id_rsa.pub root@mon2 # ssh-copy-id -i ~/.ssh/id_rsa.pub root@mon3 # ssh admin.sha.me.corp # ssh data1.sha.me.corp # ssh data2.sha.me.corp # ssh data3.sha.me.corp # ssh data4.sha.me.corp # ssh mon1.sha.me.corp # ssh mon2.sha.me.corp # ssh mon3.sha.me.corp # ssh salt # ssh admin # ssh data1 # ssh data2 # ssh data3 # ssh data4 # ssh mon1 # ssh mon2 # ssh mon3 Disable firewall (all nodes) # sudo /sbin/SuSEfirewall2 off # firewall-cmd --state not running # systemctl stop firewalld.service # systemctl status firewalld.service firewalld.service - firewalld - dynamic firewall daemon Loaded: loaded (/usr/lib/systemd/system/firewalld.service; disabled; vendor preset: disabled) Active: inactive (dead) Docs: man:firewalld(1) Disable IPv6 (all nodes) and Set kernel pid to max value (all nodes) # vi /etc/sysctl.conf net.ipv6.conf.all.disable_ipv6 = 1 net.ipv6.conf.default.disable_ipv6 = 1 net.ipv6.conf.lo.disable_ipv6 = 1 kernel.pid_max = 4194303 # sysctl -p Set DEV_ENV=true in /etc/profile.local in all nodes Install basic software (all nodes) # zypper in -y -t pattern yast2_basis base # zypper in -y net-tools vim man sudo tuned irqbalance # zypper in -y ethtool rsyslog iputils less supportutils-plugin-ses # zypper in -y net-tools-deprecated tree wget Configure NTP service (all nodes), Setting via YaST2 and add server cn.pool.ntp.,org . And /etc/chrony.conf file looks like below. admin:~ # cat /etc/chrony.conf # Use public servers from the pool.ntp.org project. pool cn.pool.ntp.org iburst ! pool pool.ntp.org iburst # Record the rate at which the system clock gains/losses time. driftfile /var/lib/chrony/drift # Allow the system clock to be stepped in the first three updates # if its offset is larger than 1 second. makestep 1.0 3 # Enable kernel synchronization of the real-time clock (RTC). rtcsync # Enable hardware timestamping on all interfaces that support it. #hwtimestamp * # Increase the minimum numbgr of selectable sources required to adjust # the system clock. #minsources 2 # Allow NTP client access from local network. #allow 192.168.0.0/16 # Serve time even if not synchronized to a time source. #local stratum 10 # Specify file containing keys for NTP authentication. #keyfile /etc/chrony.keys # Get TAI-UTC offset and leap seconds from the system tz database. #leapsectz right/UTC # Specify directory for log files. logdir /var/log/chrony # Select which information is logged. #log measurements statistics tracking # Also include any directives found in configuration files in /etc/chrony.d include /etc/chrony.d/*.conf Make /etc/chrony.conf effective. # systemctl enable chronyd.service # systemctl restart chronyd.service # systemctl status chronyd.service # chronyc sources 1.2. Install Packages \u00b6 Install salt-minion on all nodes. And start the service. Hostname is in file `/etc/salt/minion_id` # zypper in -y salt-minion Uncomment below to let all nodes know who is master # vi /etc/salt/minion master: salt # systemctl enable salt-minion.service # systemctl start salt-minion.service # systemctl status salt-minion.service Install Ceph in admin node. Check log in /var/log/salt admin:~ # zypper in -y salt-master admin:~ # systemctl enable salt-master.service admin:~ # systemctl start salt-master.service admin:~ # systemctl status salt-master.service Note: ganesha will be installed on mon1, not admin node. admin:~ # zypper se ganesha admin:~ # zypper in nfs-ganesha admin:~ # systemctl enable nfs-ganesha admin:~ # systemctl start nfs-ganesha admin:~ # systemctl status nfs-ganesha admin:~ # cd /var/log/salt List fingerprints of all unaccepted minion keys on the Salt master. admin:~ # salt-key -F Local Keys: master.pem: c0:e5:***:04:c7 master.pub: 43:73:***:6a:34 Unaccepted Keys: admin.sha.me.corp: fe:51:***:b9:48 mon1.sha.me.corp: 94:13:***:91:63 mon2.sha.me.corp: c0:fd:***:39:3f mon3.sha.me.corp: 38:fc:***:2e:05 data1.sha.me.corp: b6:6c:***:63:4f data2.sha.me.corp: ab:14:***:c8:ac data3.sha.me.corp: 90:3f:***:76:3b data4.sha.me.corp: d8:12:***:f1:20 If the minions' fingerprints match, accept them admin:~ # salt-key --accept-all The following keys are going to be accepted: Unaccepted Keys: admin.sha.me.corp mon1.sha.me.corp mon2.sha.me.corp mon3.sha.me.corp data1.sha.me.corp data2.sha.me.corp data3.sha.me.corp data4.sha.me.corp Proceed? [n/Y] Y Key for minion admin.sha.me.corp accepted. Key for minion mon1.sha.me.corp accepted. Key for minion mon2.sha.me.corp accepted. Key for minion mon3.sha.me.corp accepted. Key for minion data1.sha.me.corp accepted. Key for minion data2.sha.me.corp accepted. Key for minion data3.sha.me.corp accepted. Key for minion data4.sha.me.corp accepted. Verify that the keys have been accepted admin:~ # salt-key -F admin:~ # salt-key --list-all Accepted Keys: admin.sha.me.corp data1.sha.me.corp data2.sha.me.corp data3.sha.me.corp data4.sha.me.corp mon1.sha.me.corp mon2.sha.me.corp mon3.sha.me.corp Denied Keys: Unaccepted Keys: Rejected Keys: Zero out all drivers which will be used as OSDs (optional) data1:~ lsblk data1:~ # for I in {b,c,d}; do dd if=/dev/zero of=dev/sd$i bs=512 count=40 oflag=direct; done data2:~ # for I in {b,c,d}; do dd if=/dev/zero of=dev/sd$i bs=512 count=40 oflag=direct; done data3:~ # for I in {b,c,d}; do dd if=/dev/zero of=dev/sd$i bs=512 count=40 oflag=direct; done Install DeepSea admin:~ # zypper in -y deepsea Edit the /srv/pillar/ceph/deepsea_minions.sls file on the Salt master (admin node) and add or replace the following line: admin:~ # vi /srv/pillar/ceph/deepsea_minions.sls # Choose minions with a deepsea grain deepsea_minions: 'G@deepsea:*' #Match all Salt minions in the cluster # Choose all minions # deepsea_minions: '*' #Match all minions with the 'deepsea' grain # Choose custom Salt targeting # deepsea_minions: 'ses*' # deepsea_minions: 'ceph* or salt' Target the Minions Affirm salt-master (admin node) can communicate with the minions. And deploy the grains from admin node to all minions. admin:~ # salt '*' test.ping mon1.sha.me.corp: True data4.sha.me.corp: True data3.sha.me.corp: True data2.sha.me.corp: True data1.sha.me.corp: True mon3.sha.me.corp: True admin.sha.me.corp: True mon2.sha.me.corp: True Apply the 'deepsea' grain to a group of minions, and target with a DeepSea Grain admin:~ # salt '*' grains.append deepsea default data3.sha.me.corp: The val default was already in the list deepsea mon2.sha.me.corp: The val default was already in the list deepsea data1.sha.me.corp: The val default was already in the list deepsea data4.sha.me.corp: The val default was already in the list deepsea data2.sha.me.corp: The val default was already in the list deepsea mon3.sha.me.corp: The val default was already in the list deepsea admin.sha.me.corp: The val default was already in the list deepsea mon1.sha.me.corp: The val default was already in the list deepsea admin:~ # salt -G 'deepsea:*' test.ping (The following command is an equivalent) admin:~ # salt -C 'G@deepsea:*' test.ping admin.sha.me.corp: True data3.sha.me.corp: True mon1.sha.me.corp: True mon2.sha.me.corp: True data2.sha.me.corp: True data4.sha.me.corp: True mon3.sha.me.corp: True data1.sha.me.corp: True 1.3. Stage 0 \u2014 the preparation \u00b6 Run Stage 0\u2014the preparation During this stage, all required updates are applied and your system may be rebooted. If there are errors, re-run the stage. admin:~ # deepsea stage run ceph.stage.0 (The following commands are equivalents) admin:~ # salt-run state.orch ceph.stage.0 admin:~ # salt-run state.orch ceph.stage.prep Run Stage 1\u2014the discovery Here all hardware in your cluster is being detected and necessary information for the Ceph configuration is being collected. The discovery stage collects data from all minions and creates configuration fragments that are stored in the directory /srv/pillar/ceph/proposals . The data are stored in the YAML format in *.sls or *.yml files admin:~ # deepsea stage run ceph.stage.1 (The following commands are equivalents) admin:~ # salt-run state.orch ceph.stage.1 admin:~ # salt-run state.orch ceph.stage.discovery 1.4. Stage 2 \u2014 the configuration \u00b6 Run Stage 2 \u2014 the configuration \u2014 you need to prepare configuration data in a particular format. The assignment follows this pattern: role-ROLE_NAME/PATH/FILES_TO_INCLUDE (NOTE, the parent directory of PATH is /srv/pillar/ceph/ ) To avoid trouble with performance and the upgrade procedure, do not deploy the Ceph OSD, Metadata Server, or Ceph Monitor role to the Admin Node. Monitors, Metadata Server, and gateways can be co-located on the OSD nodes. If you are using CephFS, S3/Swift, iSCSI, at least two instances of the respective roles (Metadata Server, Object Gateway, iSCSI) are required for redundancy and availability. admin:~ # cp /usr/share/doc/packages/deepsea/examples/policy.cfg-rolebased /srv/pillar/ceph/proposals/policy.cfg admin:~ # vi /srv/pillar/ceph/proposals/policy.cfg ## Cluster Assignment # Add all nodes into Ceph cluster cluster-ceph/cluster/*.sls ## Roles # The Admin node fills the \u201cmaster\u201d and \u201cadmin\u201d roles for DeepSea # The master role is mandatory, always add a similar line to the following role-master/cluster/admin*.sls role-admin/cluster/admin*.sls # Monitoring # Cluster monitoring and data graphs, most commonly they run on Admin node # NFS Ganesha is configured via the file /etc/ganesha/ganesha.conf # As additional configuration is required to install NFS Ganesha, you can install NFS Ganesha later. # The following requirements need to be met before DeepSea stages 2 and 4 can be executed to install NFS Ganesha: # a)At least one node needs to be assigned the role-ganesha. # b)You can define only one role-ganesha per minion. # c)NFS Ganesha needs either an Object Gateway or CephFS to work, otherwise the validation will fail in Stage 3. # d)The kernel based NFS needs to be disabled on minions with the role-ganesha role. role-prometheus/cluster/admin*.sls role-grafana/cluster/mon1*.sls # MON # The minion will provide the monitor service to the Ceph cluster role-mon/cluster/mon*.sls # MGR # The Ceph manager daemon which collects all the state information from the whole cluster # Deploy it on all minions where you plan to deploy the Ceph monitor role role-mgr/cluster/mon1*.sls # MDS # The minion will provide the metadata service to support CephFS role-mds/cluster/mon*.sls # IGW # The minion will act as an iSCSI Gateway role-igw/cluster/mon2*.sls # RGW # The minion will act as an Object Gateway role-rgw/cluster/mon3*.sls # Storage # Use this role to specify storage nodes # It points to data1~4 nodes with a wildcard. role-storage/cluster/data*.sls # COMMON # It includes configuration files generated during the discovery (Stage 1) # Accept the default values for common configuration parameters such as fsid and public_network config/stack/default/global.yml config/stack/default/ceph/cluster.yml admin:~ # deepsea stage run ceph.stage.2 (The following commands are equivalents) admin:~ # salt-run state.orch ceph.stage.2 admin:~ # salt-run state.orch ceph.stage.configure After the command succeeds, run below command to view the pillar data for the specified minions admin:~ # salt 'mon*' pillar.items admin:~ # salt '*' saltutil.pillar_refresh Check time server (admin node) (the directory /srv/pillar/ceph/stack was initialized after deepsea installed, but global.yml file was not created yet until stage 2) By default, DeepSea uses the Admin Node as the time server for other cluster nodes. admin:~ # cat /srv/pillar/ceph/stack/default/global.yml (this file will be generated after stage 2) monitoring: prometheus: metric_relabel_config: ceph: [] grafana: [] node_exporter: [] prometheus: [] relabel_config: ceph: [] grafana: [] node_exporter: [] prometheus: [] rule_files: [] scrape_interval: ceph: 10s grafana: 10s node_exporter: 10s prometheus: 10s target_partition: ceph: 1/1 grafana: 1/1 node_exporter: 1/1 prometheus: 1/1 time_server: admin.sha.me.corp Verify network (the directory /srv/pillar/ceph/stack was initialized after deepsea installed, but cluster.yml file was not created until stage 2 ) admin:~ # cat /srv/pillar/ceph/stack/ceph/cluster.yml --nothing admin:~ # cat /srv/pillar/ceph/stack/default/ceph/cluster.yml available_roles: - storage - admin - mon - mds - mgr - igw - grafana - prometheus - storage - rgw - ganesha - client-cephfs - client-radosgw - client-iscsi - client-nfs - benchmark-rbd - benchmark-blockdev - benchmark-fs - master cluster_network: 10.58.120.0/23 fsid: 343ee7d3-232f-4c71-8216-1edbc55ac6e0 public_network: 10.58.120.0/23 Note: customized file will overwrite default one. Default file: /srv/pillar/ceph/stack/default/ceph/cluster.yml Customized file: /srv/pillar/ceph/stack/ceph/cluster.yml Check DriveGroup DriveGroups specify the layouts of OSDs in the Ceph cluster. They are defined in a single file /srv/salt/ceph/configuration/files/drive_groups.yml admin:~ # cat /srv/salt/ceph/configuration/files/drive_groups.yml default_drive_group_name: target: 'data*' <--original: 'I@role:storage' data_devices: all: true admin:~ # salt 'data*' pillar.items | grep -B5 stroage 1.5. Stage 3 \u2014 the deployment \u00b6 Run Stage 3 \u2014 the deployment \u2014 creates a basic Ceph cluster with mandatory Ceph services. This Deployment stage has more than 60 automated steps. Be patient and make sure the stage completes successfully before proceeding. Set dev environment and disable subvolume: admin:~ # vi /srv/pillar/ceph/stack/global.yml admin:~ # vi /srv/pillar/ceph/stack/default/global.yml monitoring: prometheus: metric_relabel_config: ceph: [] grafana: [] node_exporter: [] prometheus: [] relabel_config: ceph: [] grafana: [] node_exporter: [] prometheus: [] rule_files: [] scrape_interval: ceph: 10s grafana: 10s node_exporter: 10s prometheus: 10s target_partition: ceph: 1/1 grafana: 1/1 node_exporter: 1/1 prometheus: 1/1 time_server: admin.sha.me.corp DEV_ENV: True subvolume_init: disabled admin:~ # salt '*' saltutil.pillar_refresh Note: customized file will overwrite default one. Default file: /srv/pillar/ceph/stack/default/global.yml Customized file: /srv/pillar/ceph/stack/global.yml admin:~ # deepsea stage run ceph.stage.3 (The following commands are equivalents) admin:~ # salt-run state.orch ceph.stage.3 admin:~ # salt-run state.orch ceph.stage.deploy After the command succeeds, run the following to check the status: admin:~ # ceph -s Below comands return you a structure of matching disks based on your DriveGroups. (will show available information after stage 3) admin:~ # salt-run disks.Report admin:~ # salt-run disks.list admin:~ # salt-run disks.details 1.6. Stage 4 \u2014 the services \u00b6 Run Stage 4 \u2014 the services \u2014 additional features of Ceph like iSCSI, Object Gateway and CephFS can be installed in this stage. Each is optional. admin:~ # deepsea stage run ceph.stage.4 (The following commands are equivalents) admin:~ # salt-run state.orch ceph.stage.4 admin:~ # salt-run state.orch ceph.stage.services admin:~ # ceph osd lspools 1 iscsi-images 2 cephfs_data 3 cephfs_metadata 4 .rgw.root 5 default.rgw.control 6 default.rgw.meta 7 default.rgw.log Before logon to dashboard via url, need get credentials first admin:~ # salt-call grains.get dashboard_creds local: ---------- admin: --> the password was changed to mypassword to log on to dashboard admin:~ # ceph mgr services { \"dashboard\": \"https://mon1.sha.me.corp:8443/\", \"prometheus\": \"http://mon1.sha.me.corp:9283/\" } https://10.58.121.186:8443 http://10.58.121.186:9283 admin:~ # watch ceph -s Every 2.0s: ceph -s admin: Mon Oct 5 14:41:51 2020 cluster: id: health: HEALTH_OK services:s: ceph -s mon: 3 daemons, quorum mon1,mon2,mon3 (age 87m) mgr: mon1(active, since 82m) mds: cephfs:1 {0=mon3=up:active} 2 up:standby osd: 12 osds: 12 up (since 85m), 12 in (since 85m) rgw: 1 daemon active (mon3) task status: scrub status: mds.mon3: idle data: pools: 7 pools, 576 pgs objects: 213 objects, 4.2 KiB usage: 12 GiB used, 84 GiB / 96 GiB avail pgs: 576 active+clean io: client: 852 B/s rd, 0 op/s rd, 0 op/s wr 1.7. Stage 5 \u2014 the removal stage \u00b6 Run Stage 5 \u2014 the removal stage. This stage is not mandatory and during the initial setup it is usually not needed. In this stage the roles of minions and also the cluster configuration are removed. You need to run this stage when you need to remove a storage node from your cluster. admin:~ # deepsea stage run ceph.stage. 1.8. Installation Guide \u00b6 Deployment Guide (EN) Deployment Guide (ZH) 1.9. Issues during installation \u00b6 [ERROR]: The Salt Master has cached the public key for this node SOLUTION : Restart minions service [ERROR]: This server_id is computed nor by Adler32 neither by CRC32 [QUESTION]: How to change new salt key Stop salt-minion service # systemctl stop salt-minion Delete salt-minion pulic key # rm /etc/salt/pki/minion/minion.pub # rm /etc/salt/pki/minion/minion.pem Change new minion_id admin:~ # echo admin.sha.me.corp > /etc/salt/minion_id data1:~ # echo data1.sha.me.corp > /etc/salt/minion_id data2:~ # echo data2.sha.me.corp > /etc/salt/minion_id data3:~ # echo data3.sha.me.corp > /etc/salt/minion_id data4:~ # echo data4.sha.me.corp > /etc/salt/minion_id mon1:~ # echo mon1.sha.me.corp > /etc/salt/minion_id mon2:~ # echo mon2.sha.me.corp > /etc/salt/minion_id mon3:~ # echo mon3.sha.me.corp > /etc/salt/minion_id Delete old ID on admin node # salt-key -D Restart salt-minion service # systemctl restart salt-minion Accept all new key on admin node admin:~ # salt-key -L admin:~ # salt-key -A or admin:~ # salt-key -a admin.sha.me.corp data1:~ # salt-key -a data1.sha.me.corp data2:~ # salt-key -a data2.sha.me.corp data3:~ # salt-key -a data3.sha.me.corp data4:~ # salt-key -a data4.sha.me.corp mon1:~ # salt-key -a mon1.sha.me.corp mon2:~ # salt-key -a mon2.sha.me.corp mon3:~ # salt-key -a mon3.sha.me.corp [ERROR] ['/var/lib/ceph subvolume missing on mon3.sha.me.corp', '/var/lib/ceph subvolume missing on mon1.sha.me.corp', '/var/lib/ceph subvolume missing on mon2.sha.me.corp', 'See /srv/salt/ceph/subvolume/README.md'] SOLUTION Edit /srv/pillar/ceph/stack/global.yml and add the following line: subvolume_init: disabled Then refresh the Salt pillar and re-run DeepSea stage.3: admin:~ # salt '*' saltutil.refresh_pillar admin:~ # salt-run state.orch ceph.stage.3 After DeepSea successfully finished stage.3, the Ceph Dashboard will be running. Refer to Book \u201cAdministration Guide\u201d, Chapter 20 \u201cCeph Dashboard\u201d for a detailed overview of Ceph Dashboard features. To list nodes running dashboard, run: admin:~ # ceph mgr services | grep dashboard To list admin credentials, run: admin:~ # salt-call grains.get dashboard_creds [ERROR] module function cephprocesses.wait executed on nodes mon1~3 and data1~4 in Stage 0 SOLUTION Check below on all nodes # salt-call cephprocesses.check ERROR: process ceph-mds for role mds is not running ERROR: process radosgw for role rgw is not running admin:~ # ceph -s Clock skew detected on mon ceph (mon.mon2, mon.mon3) Set time server to public server (China) # chronyc sources 1.10. Shutting Down the Whole Ceph Cluster \u00b6 Shut down or disconnect any clients accessing the cluster. To prevent CRUSH from automatically rebalancing the cluster, set the cluster to noout: # ceph osd set noout Other flags you can set per osd: nodown noup noin noout Disable safety measures and run the ceph.shutdown runner: admin:~ # salt-run disengage.safety safety is now disabled for cluster ceph admin:~ # salt-run state.orch ceph.shutdown admin.sha.me.corp_master: Name: set noout - Function: salt.state - Result: Changed Started: - 14:32:14.398022 Duration: 2266.75 ms Name: Shutting down radosgw for rgw - Function: salt.state - Result: Changed Started: - 14:32:16.665452 Duration: 1461.23 ms Name: Shutting down cephfs - Function: salt.state - Result: Changed Started: - 14:32:18.127353 Duration: 30326.193 ms Name: Shutting down iscsi - Function: salt.state - Result: Clean Started: - 14:32:48.454187 Duration: 30142.468 ms Name: Shutting down storage - Function: salt.state - Result: Changed Started: - 14:33:18.597321 Duration: 10841.45 ms Name: Shutting down mgr - Function: salt.state - Result: Changed Started: - 14:33:29.439442 Duration: 29209.141 ms Name: Shutting down mon - Function: salt.state - Result: Changed Started: - 14:33:58.649221 Duration: 30519.97 ms Summary for admin.sha.me.corp_master ------------ Succeeded: 7 (changed=6) Failed: 0 ------------ Total states run: 7 Total run time: 134.767 s Power off all cluster nodes: admin:~ # salt -C 'G@deepsea:*' cmd.run \"shutdown -h\" Broadcast message from root@admin (Sat 2021-03-06 14:40:37 CST): The system is going down for poweroff at Sat 2021-03-06 14:41:37 CST! admin.sha.me.corp: Shutdown scheduled for Sat 2021-03-06 14:41:37 CST, use 'shutdown -c' to cancel. mon2.sha.me.corp: Shutdown scheduled for Sat 2021-03-06 14:41:37 CST, use 'shutdown -c' to cancel. data2.sha.me.corp: Shutdown scheduled for Sat 2021-03-06 14:41:37 CST, use 'shutdown -c' to cancel. mon3.sha.me.corp: Shutdown scheduled for Sat 2021-03-06 14:41:37 CST, use 'shutdown -c' to cancel. data3.sha.me.corp: Shutdown scheduled for Sat 2021-03-06 14:41:37 CST, use 'shutdown -c' to cancel. data4.sha.me.corp: Shutdown scheduled for Sat 2021-03-06 14:41:37 CST, use 'shutdown -c' to cancel. mon1.sha.me.corp: Shutdown scheduled for Sat 2021-03-06 14:41:37 CST, use 'shutdown -c' to cancel. data1.sha.me.corp: Shutdown scheduled for Sat 2021-03-06 14:41:37 CST, use 'shutdown -c' to cancel. 1.11. Starting, Stopping, and Restarting Services Using Targets \u00b6 # ls /usr/lib/systemd/system/ceph*.target ceph.target ceph-osd.target ceph-mon.target ceph-mgr.target ceph-mds.target ceph-radosgw.target ceph-rbd-mirror.target To start/stop/restart all Ceph services on the node, run: # systemctl start ceph.target # systemctl stop ceph.target # systemctl restart ceph.target To start/stop/restart all OSDs on the node, run: # systemctl start ceph-osd.target # systemctl stop ceph-osd.target # systemctl restart ceph-osd.target Starting, Stopping, and Restarting Individual Services # systemctl list-unit-files --all --type=service ceph* ceph-osd@.service ceph-mon@.service ceph-mds@.service ceph-mgr@.service ceph-radosgw@.service ceph-rbd-mirror@.service Example : # systemctl status ceph-mon@HOSTNAME.service (e.g., ceph-mon@mon1.service) # systemctl start ceph-osd@1.service # systemctl stop ceph-osd@1.service # systemctl restart ceph-osd@1.service # systemctl status ceph-osd@1.service 1.12. Restarting All Services \u00b6 # salt-run state.orch ceph.restart 1.13. Restarting Specific Services \u00b6 Example: salt-run state.orch ceph.restart.service_name # salt-run state.orch ceph.restart.mon # salt-run state.orch ceph.restart.mgr # salt-run state.orch ceph.restart.osd # salt-run state.orch ceph.restart.mds # salt-run state.orch ceph.restart.rgw # salt-run state.orch ceph.restart.igw # salt-run state.orch ceph.restart.ganesha Default log file path of salt-run: /var/log/salt/master 2. Basic Operation \u00b6 2.1. Pools and Data Placement \u00b6 2.1.1. Enable the PG Autoscaler and Balancer Modules \u00b6 Task 1: View the state of all the Manager Modules \u00b6 List all the existing Manager Modules admin:~ # ceph mgr module ls | less Task 2: List the Existing Pools \u00b6 List the pools that already exist in the cluster admin:~ # ceph osd lspools 1 iscsi-images 2 cephfs_data 3 cephfs_metadata 4 .rgw.root 5 default.rgw.control 6 default.rgw.meta 7 default.rgw.log List the pools again, but this time using the rados command: admin:~ # rados lspools iscsi-images cephfs_data cephfs_metadata .rgw.root default.rgw.control default.rgw.meta default.rgw.log View the output of placement group autoscale-status command for the pools admin:~ # ceph osd pool autoscale-status Error ENOTSUP: Module 'pg_autoscaler' is not enabled (required by command 'osd pool autoscale-status'): use `ceph mgr module enable pg_autoscaler` to enable it Task 3: Enable the pg_autoscaler module \u00b6 Enable the pg_autoscaler module admin:~ # ceph mgr module enable pg_autoscaler admin:~ # ceph osd pool autoscale-status POOL SIZE TARGET SIZE RATE RAW CAPACITY RATIO TARGET RATIO EFFECTIVE RATIO BIAS PG_NUM NEW PG_NUM AUTOSCALE iscsi-images 389 3.0 98256M 0.0000 1.0 128 32 warn cephfs_data 0 3.0 98256M 0.0000 1.0 256 32 warn cephfs_metadata 7285 3.0 98256M 0.0000 4.0 64 16 warn .rgw.root 1245 3.0 98256M 0.0000 1.0 32 warn default.rgw.control 0 3.0 98256M 0.0000 1.0 32 warn default.rgw.meta 381 3.0 98256M 0.0000 1.0 32 warn default.rgw.log 18078 3.0 98256M 0.0000 1.0 32 warn Note that for the iscsi-images pool the PG_NUM value is 128. And note that the NEW PG_NUM value is 32. The PGs won\u2019t be adjusted automatically because the default setting for the autoscaler is \u201cwarn\u201d. Note the last column (mode) that shows status \u201cwarn\u201d for all the pools. Check current status. \u201chave too many placement groups\u201d. That\u2019s exactly what we want the pg_autoscaler to tell us. admin:~ # ceph health HEALTH_WARN 3 pools have too many placement groups Turn off the pg_autoscaler feature for CephFS pools admin:~ # ceph osd pool set cephfs_data pg_autoscale_mode off set pool 2 pg_autoscale_mode to off admin:~ # ceph osd pool set cephfs_metadata pg_autoscale_mode off set pool 3 pg_autoscale_mode to off admin:~ # ceph health HEALTH_WARN 1 pools have too many placement groups Set the pg_autoscaler mode to \u201con\u201d for the iscs-images pool: admin:~ # ceph osd pool set iscsi-images pg_autoscale_mode on set pool 1 pg_autoscale_mode to on admin:~ # ceph osd pool autoscale-status POOL SIZE TARGET SIZE RATE RAW CAPACITY RATIO TARGET RATIO EFFECTIVE RATIO BIAS PG_NUM NEW PG_NUM AUTOSCALE iscsi-images 389 3.0 98256M 0.0000 1.0 128 32 on cephfs_data 0 3.0 98256M 0.0000 1.0 256 32 off cephfs_metadata 7412 3.0 98256M 0.0000 4.0 64 16 off .rgw.root 1245 3.0 98256M 0.0000 1.0 32 warn default.rgw.control 0 3.0 98256M 0.0000 1.0 32 warn default.rgw.meta 381 3.0 98256M 0.0000 1.0 32 warn default.rgw.log 18078 3.0 98256M 0.0000 1.0 32 warn Turn on the pg_autoscaler feature for CephFS pools admin:~ # ceph osd pool set cephfs_data pg_autoscale_mode on set pool 2 pg_autoscale_mode to on admin:~ # ceph osd pool set cephfs_metadata pg_autoscale_mode on set pool 3 pg_autoscale_mode to on PG numbgrs must always be a power of 2 admin:~ # ceph osd pool autoscale-status POOL SIZE TARGET SIZE RATE RAW CAPACITY RATIO TARGET RATIO EFFECTIVE RATIO BIAS PG_NUM NEW PG_NUM AUTOSCALE iscsi-images 389 3.0 98256M 0.0000 1.0 32 on cephfs_data 0 3.0 98256M 0.0000 1.0 32 off cephfs_metadata 7412 3.0 98256M 0.0000 4.0 16 off .rgw.root 1245 3.0 98256M 0.0000 1.0 32 warn default.rgw.control 0 3.0 98256M 0.0000 1.0 32 warn default.rgw.meta 381 3.0 98256M 0.0000 1.0 32 warn default.rgw.log 35900 3.0 98256M 0.0000 1.0 32 warn Show the cluster health admin:~ # ceph -s cluster: id: health: HEALTH_OK services: mon: 3 daemons, quorum mon1,mon2,mon3 (age 4w) mgr: mon1(active, since 46h) mds: cephfs:1 {0=mon3=up:active} 2 up:standby osd: 12 osds: 12 up (since 8w), 12 in (since 8w) rgw: 1 daemon active (mon3) task status: scrub status: mds.mon3: idle data: pools: 7 pools, 433 pgs objects: 246 objects, 4.7 KiB usage: 13 GiB used, 83 GiB / 96 GiB avail pgs: 0.462% pgs not active 431 active+clean 2 peering io: client: 45 KiB/s rd, 0 B/s wr, 44 op/s rd, 28 op/s wr Task 4: Turn on the Placement Group balancer feature \u00b6 1). Show the \u201cstatus\u201d of the balancer: admin:~ # ceph balancer status { \"plans\": [], \"active\": false, \"last_optimize_started\": \"\", \"last_optimize_duration\": \"\", \"optimize_result\": \"\", \"mode\": \"none\" } admin:~ # ceph balancer on admin:~ # ceph balancer status { \"plans\": [], \"active\": true, \"last_optimize_started\": \"Mon Jan 4 20:22:57 2021\", \"last_optimize_duration\": \"0:00:00.001379\", \"optimize_result\": \"Please do \\\"ceph balancer mode\\\" to choose a valid mode first\", \"mode\": \"none\" } 2). Set the mode for the balancer to \u201cupmap\u201d: admin:~ # ceph balancer mode upmap Error EPERM: min_compat_client \"jewel\" < \"luminous\", which is required for pg-upmap. Try \"ceph osd set-require-min-compat-client luminous\" before enabling this mode admin:~ # ceph osd set-require-min-compat-client luminous --yes-i-really-mean-it set require_min_compat_client to luminous admin:~ # ceph balancer mode upmap admin:~ # ceph balancer status { \"plans\": [], \"active\": true, \"last_optimize_started\": \"Mon Jan 4 20:23:57 2021\", \"last_optimize_duration\": \"0:00:00.001807\", \"optimize_result\": \"Please do \\\"ceph balancer mode\\\" to choose a valid mode first\", \"mode\": \"upmap\" } 3). Create a balancer optimization plan called basic-plan. Ceph won\u2019t let you do this yet. Because you just recently enabled the pg_autoscaler, Ceph is moving objects around, and the PGs are quite busy with re-peering. admin:~ # ceph balancer optimize basic-plan Error EINVAL: Balancer enabled, disable to optimize manually 4). Show the details of the plan: This shows what \u201cexecute\u201d-ing the plan will do, itemizing which PGs will be affected. admin:~ # ceph balancer show basic-plan Error ENOENT: plan basic-plan not found <--- failed here 5). Show the effectiveness of the plan by comparing the current score for the pre-planned balancing and the score for the planned balancing: admin:~ # ceph balancer eval current cluster score 0.118731 (lower is better) admin:~ # ceph balancer eval basic-plan Error EINVAL: option \"basic-plan\" not a plan or a pool 6). Show the status of the balancer, now with all of these settings having been set, but before putting them into effect: The pg_autoscaler has already optimized the balance of PGs sufficiently. That\u2019s because this cluster is very small and has no significant content stored in it yet. If that\u2019s the case, you would see a message like \u201cError EALREADY: Unable to find further optimization, or pool(s)' pg_num is decreasing, or distribution is already perfect.\u201d If you receive this message, then you will not be able to complete this task. At some later time in the course you may choose to revisit this task to complete it. admin:~ # ceph balancer status { \"plans\": [], \"active\": true, \"last_optimize_started\": \"Mon Jan 4 20:32:59 2021\", \"last_optimize_duration\": \"0:00:00.004170\", \"optimize_result\": \"Unable to find further optimization, or pool(s) pg_num is decreasing, or distribution is already perfect\", \"mode\": \"upmap\" } 7). Set the basic-plan into effect: admin:~ # ceph balancer execute basic-plan Error EINVAL: Balancer enabled, disable to execute a plan 8). Now re-show the current score for the balanced cluster: admin:~ # ceph balancer eval current cluster score 0.118731 (lower is better) 2.1.2. Manipulate Erasure Code Profiles \u00b6 Task 1: Display a list of the current Erasure Code profiles \u00b6 admin:~ # ceph osd erasure-code-profile no valid command found; 4 closest matches: osd erasure-code-profile set { [...]} {--force} osd erasure-code-profile get osd erasure-code-profile rm osd erasure-code-profile ls Error EINVAL: invalid command admin:~ # ceph osd erasure-code-profile ls default Task 2: Examine the details of the default EC profile \u00b6 admin:~ # ceph osd erasure-code-profile get default k=2 m=1 plugin=jerasure technique=reed_sol_van Task 3: Create and remove a new EC profile \u00b6 1. Create a new EC profile from the command line. This is going to be a \u201cbad\u201d profile that will be removed in a moment: admin:~ # ceph osd erasure-code-profile set bad_profile k=2 m=4 plugin=jerasure admin:~ # ceph osd erasure-code-profile ls bad_profile default admin:~ # ceph osd erasure-code-profile get bad_profile crush-device-class= crush-failure-domain=host crush-root=default jerasure-per-chunk-alignment=false k=2 m=4 plugin=jerasure technique=reed_sol_van w=8 admin:~ # ceph osd erasure-code-profile rm bad_profile admin:~ # ceph osd erasure-code-profile ls default Task 4: Create a better EC profile \u00b6 admin:~ # ceph osd erasure-code-profile set usable_profile k=2 m=1 plugin=jerasure technique=reed_sol_van stripe_unit=4K crush-failure-domain=host admin:~ # ceph osd erasure-code-profile get usable_profile crush-device-class= crush-failure-domain=host crush-root=default jerasure-per-chunk-alignment=false k=2 m=1 plugin=jerasure stripe_unit=4K technique=reed_sol_van w=8 2.1.3. Manipulate CRUSH Map Rulesets \u00b6 Task 1: Display a list of the current CRUSH Map rules \u00b6 admin:~ # ceph osd crush rule ls replicated_rule admin:~ # ceph osd crush osd crush rule ls osd crush rule ls-by-class osd crush rule dump {} osd crush dump osd crush set {} osd crush add-bucket { [...]} osd crush rename-bucket osd crush set [...] osd crush add [...] osd crush set-all-straw-buckets-to-straw2 admin:~ # ceph osd crush rule osd crush rule ls osd crush rule ls-by-class osd crush rule dump {} osd crush rule create-simple {firstn|indep} osd crush rule create-replicated {} osd crush rule create-erasure {} osd crush rule rm osd crush rule rename List the existing CRUSH Map rulesets that have been defined according to a particular device class: admin:~ # ceph osd crush rule ls-by-class hdd admin:~ # ceph osd crush rule ls-by-class ssd Error ENOENT: failed to get rules by class 'ssd' admin:~ # ceph osd crush rule ls-by-class nvme Error ENOENT: failed to get rules by class 'nvme' Task 2: Examine the details of the default CRUSH Map rule \u00b6 Show the details of the default CRUSH Map rule with the dump sub-command: The \u201crule_id\u201d and \u201cruleset\u201d values just numbgrs to keep track of rules similar to a DB key id. \u201cmin_size\u201d and \u201cmax_size\u201d are related to how CRUSH behaves when a certain numbgr of replicas are created. The \u201csteps\u201d section is the most functional portion of the rule, providing an ordered set of rules for how CRUSH should behave. Note that there are three \u201cop\u201d parts, one each for \u201ctake\u201d, \u201cchooseleaf_firstn\u201d, and \u201cemit\u201d. \u201ctake\u201d in a replicated rule is always the first step, and \u201cemit\u201d is always the last step. The \u201citem_type\u201d in the \u201ctake\u201d step is the crush_root value, and the \u201chost\u201d in the \u201cchooseleaf_firstn\u201d step is the failure_domain. admin:~ # ceph osd crush rule dump replicated_rule { \"rule_id\": 0, \"rule_name\": \"replicated_rule\", \"ruleset\": 0, \"type\": 1, \"min_size\": 1, \"max_size\": 10, \"steps\": [ { \"op\": \"take\", \"item\": -1, \"item_name\": \"default\" }, { \"op\": \"chooseleaf_firstn\", \"num\": 0, \"type\": \"host\" }, { \"op\": \"emit\" } ] } Task 3: Create and remove a new CRUSH Map rule \u00b6 1). Create a new CRUSH ruleset from the command line.We made two mistakes here: First, we named it \u201cbud\u201d instead of \u201cbad\u201d. admin:~ # ceph osd crush rule create-replicated bud_ruleset default host admin:~ # ceph osd crush rule ls replicated_rule bud_ruleset 2). Rename the ruleset: admin:~ # ceph osd crush rule rename bud_ruleset bad_ruleset admin:~ # ceph osd crush rule ls replicated_rule bad_ruleset 3). The second mistake was that we specified the failure-domain at the host-bucket level. This is technically not a bad thing to do, in fact it would be a common use case. But for this demo we want to set the failure domain at the rack-bucket level. We can\u2019t change a defined CRUSH Map ruleset, so delete the bad one: admin:~ # ceph osd crush rule rm bad_ruleset admin:~ # ceph osd crush rule ls replicated_rule Task 4: Create a better CRUSH Map rule \u00b6 Create a more appropriate CRUSH Map rule from the CLI, that will survive the failure of a rack: admin:~ # ceph osd crush rule create-replicated better_ruleset default rack admin:~ # ceph osd crush rule dump better_ruleset { \"rule_id\": 1, \"rule_name\": \"better_ruleset\", \"ruleset\": 1, \"type\": 1, \"min_size\": 1, \"max_size\": 10, \"steps\": [ { \"op\": \"take\", \"item\": -1, \"item_name\": \"default\" }, { \"op\": \"chooseleaf_firstn\", \"num\": 0, \"type\": \"rack\" }, { \"op\": \"emit\" } ] } Task 5: Create CRUSH Map rules for different classes of devices \u00b6 1). Create two different CRUSH Map rules from the CLI, that will accommodate a slow set of devices (HDDs) and a fast set of devices (SDDs): The error of 2 nd is because the cluster does not have any SSD devices. admin:~ # ceph osd crush rule create-replicated slow_devices default host hdd admin:~ # ceph osd crush rule create-replicated fast_devices default host sdd Error EINVAL: device class sdd does not exist 2). Display the details of the new \u201cslow\u201d rule: admin:~ # ceph osd crush rule dump slow_devices { \"rule_id\": 2, \"rule_name\": \"slow_devices\", \"ruleset\": 2, \"type\": 1, \"min_size\": 1, \"max_size\": 10, \"steps\": [ { \"op\": \"take\", \"item\": -2, \"item_name\": \"default~hdd\" }, { \"op\": \"chooseleaf_firstn\", \"num\": 0, \"type\": \"host\" }, { \"op\": \"emit\" } ] } Task 6: Change the ruleset used by a pool \u00b6 1). Show which CRUSH Map Ruleset is being used by the cephfs_data pool: The rule should be listed as replicated_rule. admin:~ # ceph osd pool get cephfs_data crush_rule crush_rule: replicated_rule 2). Change the cephfs_data pool to use the new CRUSH Map ruleset that you created in the previous task. admin:~ # ceph osd pool set cephfs_data crush_rule better_ruleset set pool 2 crush_rule to better_ruleset 3). Verify that the rule has been changed by re-running the earlier command: admin:~ # ceph osd pool get cephfs_data crush_rule crush_rule: better_ruleset 4). In this demo cluster, making the cephfs_data pool use the \u201cbetter_ruleset\u201d will result in problems. (There\u2019s no rack for the CRUSH Map, and not enough nodes to accommodate the requirement for a large numbgr of PGs.) So change the setting back to the replicated_rule. admin:~ # ceph osd pool set cephfs_data crush_rule replicated_rule set pool 2 crush_rule to replicated_rule admin:~ # ceph osd pool get cephfs_data crush_rule crush_rule: replicated_rule Task 7: Create a CRUSH Map rule enhanced with an EC profile 1). Combine the benefits of Erasure Coding with a CRUSH Map rule: This will only work if you have already created an appropriate EC profile called usable_profile. In this demo you would have done in an earlier exercise. And in this demo you need to tie this ec_rule to the usable_profile, not the better_profile.Or else any pool that you create using the ec_rule will fail due to insufficient resources. admin:~ # ceph osd crush rule create-erasure ec_rule usable_profile Link the CRUSH map rule (ec_rule) to EC profile (usable_profile) created rule ec_rule at 3 P.S., The useable_profile was created by : admin:~ # ceph osd erasure-code-profile set usable_profile k=2 m=1 plugin=jerasure technique=reed_sol_van stripe_unit=4K crush-failure-domain=host 2). Display the details of the EC-enhanced CRUSH Map rule: See the added, extra \u201cop\u201d steps. You might also notice the different values for \u201ctype,\u201d \u201cmin_size,\u201d and \u201cmax_size\u201d than what you saw in the standard replicated rules. admin:~ # ceph osd crush rule dump ec_rule { \"rule_id\": 3, \"rule_name\": \"ec_rule\", \"ruleset\": 3, \"type\": 3, \"min_size\": 3, \"max_size\": 3, \"steps\": [ { \"op\": \"set_chooseleaf_tries\", \"num\": 5 }, { \"op\": \"set_choose_tries\", \"num\": 100 }, { \"op\": \"take\", \"item\": -1, \"item_name\": \"default\" }, { \"op\": \"chooseleaf_indep\", \"num\": 0, \"type\": \"host\" }, { \"op\": \"emit\" } ] } admin:~ # ceph osd crush rule ls replicated_rule better_ruleset slow_devices ec_rule admin:~ # ceph osd crush rule create-replicated better_ruleset default rack admin:~ # ceph osd crush rule create-replicated slow_devices default host hdd admin:~ # ceph osd crush rule create-erasure ec_rule usable_profile admin:~ # ceph osd crush rule dump replicated_rule { \"rule_id\": 0, \"rule_name\": \"replicated_rule\", \"ruleset\": 0, \"type\": 1, \"min_size\": 1, \"max_size\": 10, \"steps\": [ { \"op\": \"take\", \"item\": -1, \"item_name\": \"default\" }, { \"op\": \"chooseleaf_firstn\", \"num\": 0, \"type\": \"host\" }, { \"op\": \"emit\" } ] } admin:~ # ceph osd crush rule dump better_ruleset { \"rule_id\": 1, \"rule_name\": \"better_ruleset\", \"ruleset\": 1, \"type\": 1, \"min_size\": 1, \"max_size\": 10, \"steps\": [ { \"op\": \"take\", \"item\": -1, \"item_name\": \"default\" }, { \"op\": \"chooseleaf_firstn\", \"num\": 0, \"type\": \"rack\" }, { \"op\": \"emit\" } ] } admin:~ # ceph osd crush rule dump slow_devices { \"rule_id\": 2, \"rule_name\": \"slow_devices\", \"ruleset\": 2, \"type\": 1, \"min_size\": 1, \"max_size\": 10, \"steps\": [ { \"op\": \"take\", \"item\": -2, \"item_name\": \"default~hdd\" }, { \"op\": \"chooseleaf_firstn\", \"num\": 0, \"type\": \"host\" }, { \"op\": \"emit\" } ] } admin:~ # ceph osd pool osd pool stats {} osd pool scrub [...] osd pool deep-scrub [...] osd pool repair [...] osd pool force-recovery [...] osd pool force-backfill [...] osd pool cancel-force-recovery [...] osd pool cancel-force-backfill [...] osd pool autoscale-status osd pool mksnap admin:~ # ceph osd pool get size min_size pg_num pgp_num crush_rule Hashpspool Nodelete Nopgchange Nosizechange write_fadvise_dontneed Noscrub nodeep-scrub hit_set_type hit_set_period hit_set_count hit_set_fpp use_gmt_hitset target_max_objects target_max_bytes cache_target_dirty_ratio cache_target_dirty_high_ratio cache_target_full_ratio cache_min_flush_age cache_min_evict_age erasure_code_profile min_read_recency_for_promote All min_write_recency_for_promote fast_read hit_set_grade_decay_rate hit_set_search_last_n scrub_min_interval scrub_max_interval deep_scrub_interval recovery_priority recovery_op_priority scrub_priority compression_mode compression_algorithm compression_required_ratio compression_max_blob_size compression_min_blob_size csum_type csum_min_block csum_max_block allow_ec_overwrites fingerprint_algorithm pg_autoscale_mode pg_autoscale_bias pg_num_min target_size_bytes target_size_ratio 2.1.4. Investigate BlueStore \u00b6 Task 1: Explore the drive_groups.yml configuration \u00b6 After deployment, the drive_groups.yml file is where the storage administrator defines the configuration of the cluster\u2019s storage devices. Note the \u201cdata_devices\u201d parameter. In this demo, \u201call\u201d storage devices are data devices for BlueStore. Note that there are no definitions for \u201cwal_devices\u201d or \u201cdb_devices.\u201d That\u2019s because in this demo environment we don\u2019t have any other \u201cfast\u201d devices that would be appropriate for these roles. Since BlueStore is the default, there is no definition of a \u201cformat\u201d for the devices. Otherwise, a \u201cFormat: bluestore\u201d key-value pair might exist to ensure that BlueStore is used. admin:~ # cd /srv/salt/ceph/configuration/files admin:/srv/salt/ceph/configuration/files # cat drive_groups.yml # default: <- just a name - can be anything # target: 'data*' <- must be resolvable by salt's targeting processor # data_devices: # size: 20G # db_devices: # size: 10G # rotational: 1 # allflash: # target: 'fast_nodes*' # data_devices: # size: 100G # db_devices: # size: 50G # rotational: 0 # This is the default configuration and # will create an OSD on all available drives default: target: 'data*' data_devices: all: true Task 2: Examine a storage host\u2019s storage devices \u00b6 admin:~ # ssh data1 Last login: Tue Jan 5 18:06:40 2021 from 10.58.121.181 Should see 3 devices, which are named ceph LVM-type devices data1:~ # lsblk NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINT sda 8:0 0 8G 0 disk \u2514\u2500ceph--14c886af--269d--475f--8ee3--f5e4abbb222d-osd--data--38911b2d--f30a--4b09--9010--8dd6fad2fcc6 254:0 0 8G 0 lvm sdb 8:16 0 8G 0 disk \u2514\u2500ceph--9ec4a77a--5d67--4b21--be53--d7e9221082de-osd--data--00cb3dc6--c28b--41ae--95de--efb86da254da 254:1 0 8G 0 lvm sdc 8:32 0 8G 0 disk \u2514\u2500ceph--5eaea8a8--bb68--49dd--a1e3--b82c5464ab1f-osd--data--a4a05f70--53d9--41d4--a273--4f47a088968a 254:2 0 8G 0 lvm sr0 11:0 1 672M 0 rom vda 253:0 0 20G 0 disk \u251c\u2500vda1 253:1 0 8M 0 part \u251c\u2500vda2 253:2 0 18.4G 0 part / \u2514\u2500vda3 253:3 0 1.7G 0 part [SWAP] See the raw ceph devices data1:~ # ls -lad /dev/ceph* drwxr-xr-x 2 root root 60 Oct 5 13:15 /dev/ceph-14c886af-269d-475f-8ee3-f5e4abbb222d drwxr-xr-x 2 root root 60 Oct 5 13:16 /dev/ceph-5eaea8a8-bb68-49dd-a1e3-b82c5464ab1f drwxr-xr-x 2 root root 60 Oct 5 13:15 /dev/ceph-9ec4a77a-5d67-4b21-be53-d7e9221082de Dig down even farther by examining the content of one of the directories, see a symlink to an LVM device-mapper device. All the devices are tied together with LVM. Note that the name of the symlink is named osd-data- . data1:~ # ls -l /dev/ceph-14c886af-269d-475f-8ee3-f5e4abbb222d lrwxrwxrwx 1 ceph ceph 7 Oct 5 13:15 osd-data-38911b2d-f30a-4b09-9010-8dd6fad2fcc6 -> ../dm-0 data1:~ # l /dev/dm* brw-rw---- 1 ceph ceph 254, 0 Jan 5 18:10 /dev/dm-0 brw-rw---- 1 ceph ceph 254, 1 Jan 5 18:10 /dev/dm-1 brw-rw---- 1 ceph ceph 254, 2 Jan 5 18:10 /dev/dm-2 Task 3: Examine a storage host\u2019s OSD details \u00b6 data1:~ # cd /var/lib/ceph/ data1:/var/lib/ceph # ls -l drwxr-x--- 1 ceph ceph 0 Aug 24 22:03 bootstrap-mds drwxr-x--- 1 ceph ceph 0 Aug 24 22:03 bootstrap-mgr drwxr-x--- 1 ceph ceph 24 Oct 5 13:15 bootstrap-osd drwxr-x--- 1 ceph ceph 0 Aug 24 22:03 bootstrap-rbd drwxr-x--- 1 ceph ceph 0 Aug 24 22:03 bootstrap-rbd-mirror drwxr-x--- 1 ceph ceph 0 Aug 24 22:03 bootstrap-rgw drwxr-x--- 1 ceph ceph 12 Oct 5 09:04 crash drwxr-x--- 1 ceph ceph 0 Aug 24 22:03 mds drwxr-x--- 1 ceph ceph 0 Aug 24 22:03 mgr drwxr-x--- 1 ceph ceph 0 Aug 24 22:03 mon drwxr-x--- 1 ceph ceph 38 Oct 5 13:16 osd drwxr-x--- 1 ceph ceph 0 Aug 24 22:03 tmp See 3 different sub-directories, each representing the 3 different OSDs (ceph-2, ceph-6, ceph-10) that are running on this storage server data1:/var/lib/ceph # cd osd/ data1:/var/lib/ceph/osd # ls -l drwxrwxrwt 2 ceph ceph 320 Oct 5 13:16 ceph-10 drwxrwxrwt 2 ceph ceph 320 Oct 5 13:15 ceph-2 drwxrwxrwt 2 ceph ceph 320 Oct 5 13:16 ceph-6 See some functional files associated with the OSD and BlueStore. See a block file, which is a symlink to one of the ceph devices, which stores the raw objects for the OSD. data1:/var/lib/ceph/osd # cd ceph-2 data1:/var/lib/ceph/osd/ceph-2 # ls -l -rw-r--r-- 1 ceph ceph 400 Oct 5 13:15 activate.monmap lrwxrwxrwx 1 ceph ceph 92 Oct 5 13:15 block -> /dev/ceph-14c886af-269d-475f-8ee3-f5e4abbb222d/osd-data-38911b2d-f30a-4b09-9010-8dd6fad2fcc6 -rw------- 1 ceph ceph 2 Oct 5 13:15 bluefs -rw------- 1 ceph ceph 37 Oct 5 13:15 ceph_fsid -rw-r--r-- 1 ceph ceph 37 Oct 5 13:15 fsid -rw------- 1 ceph ceph 55 Oct 5 13:15 keyring -rw------- 1 ceph ceph 8 Oct 5 13:15 kv_backend -rw------- 1 ceph ceph 21 Oct 5 13:15 magic -rw------- 1 ceph ceph 4 Oct 5 13:15 mkfs_done -rw------- 1 ceph ceph 41 Oct 5 13:15 osd_key -rw------- 1 ceph ceph 6 Oct 5 13:15 ready -rw------- 1 ceph ceph 3 Oct 5 13:15 require_osd_release -rw------- 1 ceph ceph 10 Oct 5 13:15 type -rw------- 1 ceph ceph 2 Oct 5 13:15 whoami data1:/var/lib/ceph/osd/ceph-2 # cat ceph_fsid # The unique ID of this Ceph cluster 343ee7d3-232f-4c71-8216-1edbc55ac6e0 data1:/var/lib/ceph/osd/ceph-2 # cat fsid # The unique ID of this OSD 6df58ebc-dbfe-4822-9714-90212c06ea05 data1:/var/lib/ceph/osd/ceph-2 # cat keyring # The Ceph key for this OSD [osd.2] key = data1:/var/lib/ceph/osd/ceph-2 # cat ready # Indication of the readiness of this OSD ready data1:/var/lib/ceph/osd/ceph-2 # cat type # filestore or bluestore (in this case: bluestore) bluestore data1:/var/lib/ceph/osd/ceph-2 # cat whoami # The integer id of this OSD (in this case: 2) 2 Task 4: Display BlueStore information using ceph-bluestore-tool \u00b6 Show BlueStore metadata for osd.2: data1:/var/lib/ceph/osd/ceph-2 # ceph-bluestore-tool show-label --path /var/lib/ceph/osd/ceph-2 inferring bluefs devices from bluestore path { \"/var/lib/ceph/osd/ceph-2/block\": { \"osd_uuid\": \"6df58ebc-dbfe-4822-9714-90212c06ea05\", \"size\": 8585740288, \"btime\": \"2020-10-05 13:15:51.227799\", \"description\": \"main\", \"bluefs\": \"1\", \"ceph_fsid\": \"343ee7d3-232f-4c71-8216-1edbc55ac6e0\", \"kv_backend\": \"rocksdb\", \"magic\": \"ceph osd volume v026\", \"mkfs_done\": \"yes\", \"osd_key\": , \"ready\": \"ready\", \"require_osd_release\": \"14\", \"whoami\": \"2\" } Run a manual \u201cscrub\u201d on osd.7 using ceph-blestore-tool. (Received error, the tool won\u2019t allow you to do this while the OSD is running.) data1:/var/lib/ceph/osd/ceph-2 # ceph-bluestore-tool fsck --path /var/lib/ceph/osd/ceph-2 error from fsck: (11) Resource temporarily unavailable 2021-01-05 18:32:25.528 7f4abad6e180 -1 bluestore(/var/lib/ceph/osd/ceph-2) _lock_fsid failed to lock /var/lib/ceph/osd/ceph-2/fsid (is another ceph-osd still running?)(11) Resource temporarily unavailable Simulate that the OSD is down, shutdown the OSD: data1:/var/lib/ceph/osd/ceph-2 # systemctl stop ceph-osd@2.service Now run the \u201cfsck\u201d command again. This time the \u201cfsck\u201d has worked, with the output showing: \u201cfsck success\u201d data1:/var/lib/ceph/osd/ceph-2 # ceph-bluestore-tool fsck --path /var/lib/ceph/osd/ceph-2 fsck success Restart the OSD: data1:/var/lib/ceph/osd/ceph-2 # systemctl start ceph-osd@2.service data1:/var/lib/ceph/osd/ceph-2 # ceph-bluestore-tool show-label --path /var/lib/ceph/osd/ceph-2 inferring bluefs devices from bluestore path { \"/var/lib/ceph/osd/ceph-2/block\": { \"osd_uuid\": \"6df58ebc-dbfe-4822-9714-90212c06ea05\", \"size\": 8585740288, \"btime\": \"2020-10-05 13:15:51.227799\", \"description\": \"main\", \"bluefs\": \"1\", \"ceph_fsid\": \"343ee7d3-232f-4c71-8216-1edbc55ac6e0\", \"kv_backend\": \"rocksdb\", \"magic\": \"ceph osd volume v026\", \"mkfs_done\": \"yes\", \"osd_key\": , \"ready\": \"ready\", \"require_osd_release\": \"14\", \"whoami\": \"2\" } } 2.2. Common Day 1 Tasks Using the CLI \u00b6 Including ollowing topics in relation to the commandline: Users and Ceph Configuration Health commands Erasure Code Profiles CRUSH Map rules Pools Scrubbing OSDs and Placement Groups Manager modules The tell commands 2.2.1. Ceph Users and Configuration \u00b6 Task 1: View the current user keyrings \u00b6 Ceph keyrings are stored in below directory admin:~ # cd /etc/ceph/ admin:/etc/ceph # ls -l -rw------- 1 root root 151 Oct 5 13:13 ceph.client.admin.keyring -rw-r--r-- 1 root root 980 Oct 5 13:13 ceph.conf -rw-r--r-- 1 root root 92 Aug 24 22:03 rbdmap The value of 'key' is the key that\u2019s on the keyring. The admin keyring is \u201callow\u201ded all capabilities (permissions) to all services in the cluster, as expected. there are more than just client keys. admin:/etc/ceph # cat ceph.client.admin.keyring [client.admin] key = caps mds = \"allow *\" caps mon = \"allow *\" caps osd = \"allow *\" caps mgr = \"allow *\" Display the existing users with the \u201cauth\u201d command: Below two commands are equivalent admin:/etc/ceph # ceph -n client.admin -keyring=/etc/ceph/ceph.client.admin.keyring auth ls -- failed??? no valid command found admin:/etc/ceph # ceph auth ls installed auth entries: mds.mon1 key: caps: [mds] allow * caps: [mgr] allow profile mds caps: [mon] allow profile mds caps: [osd] allow rwx mds.mon2 key: caps: [mds] allow * caps: [mgr] allow profile mds caps: [mon] allow profile mds caps: [osd] allow rwx mds.mon3 key: caps: [mds] allow * caps: [mgr] allow profile mds caps: [mon] allow profile mds caps: [osd] allow rwx osd.0 key: caps: [mgr] allow profile osd caps: [mon] allow profile osd caps: [osd] allow * osd.1 key: caps: [mgr] allow profile osd caps: [mon] allow profile osd caps: [osd] allow * osd.10 key: caps: [mgr] allow profile osd caps: [mon] allow profile osd caps: [osd] allow * osd.11 key: caps: [mgr] allow profile osd caps: [mon] allow profile osd caps: [osd] allow * osd.2 key: caps: [mgr] allow profile osd caps: [mon] allow profile osd caps: [osd] allow * osd.3 key: caps: [mgr] allow profile osd caps: [mon] allow profile osd caps: [osd] allow * osd.4 key: caps: [mgr] allow profile osd caps: [mon] allow profile osd caps: [osd] allow * osd.5 key: caps: [mgr] allow profile osd caps: [mon] allow profile osd caps: [osd] allow * osd.6 key: caps: [mgr] allow profile osd caps: [mon] allow profile osd caps: [osd] allow * osd.7 key: caps: [mgr] allow profile osd caps: [mon] allow profile osd caps: [osd] allow * osd.8 key: caps: [mgr] allow profile osd caps: [mon] allow profile osd caps: [osd] allow * osd.9 key: caps: [mgr] allow profile osd caps: [mon] allow profile osd caps: [osd] allow * client.admin key: caps: [mds] allow * caps: [mgr] allow * caps: [mon] allow * caps: [osd] allow * client.bootstrap-mds key: caps: [mon] allow profile bootstrap-mds client.bootstrap-mgr key: caps: [mon] allow profile bootstrap-mgr client.bootstrap-osd key: caps: [mgr] allow r caps: [mon] allow profile bootstrap-osd client.bootstrap-rbd key: caps: [mon] allow profile bootstrap-rbd client.bootstrap-rbd-mirror key: caps: [mon] allow profile bootstrap-rbd-mirror client.bootstrap-rgw key: caps: [mon] allow profile bootstrap-rgw client.igw.mon2 key: caps: [mgr] allow r caps: [mon] allow * caps: [osd] allow * client.rgw.mon3 key: caps: [mgr] allow r caps: [mon] allow rwx caps: [osd] allow rwx client.storage key: caps: [mon] allow rw mgr.mon1 key: caps: [mds] allow * caps: [mon] allow profile mgr caps: [osd] allow * Task 2: Create a new keyring and associated user \u00b6 1). There are several different ways to create a new keyring and user. This is just one way. Create a new keyring and associated user named James . Remembgr that typically all new users will need read rights for the mon capability, and will need read/write rights for the osd capability, including a specification of rights to a pool. admin:/etc/ceph # ceph-authtool -g -n client.james --cap mon 'allow r' --cap osd 'allow rw pool=iscsi-images' -C /etc/ceph/ceph.client.james.keyring creating /etc/ceph/ceph.client.james.keyring admin:/etc/ceph # l total 16 drwxr-xr-x 1 root root 130 Jan 5 19:31 ./ drwxr-xr-x 1 root root 4392 Oct 5 13:03 ../ -rw------- 1 root root 151 Oct 5 13:13 ceph.client.admin.keyring -rw------- 1 root root 126 Jan 5 19:31 ceph.client.james.keyring -rw-r--r-- 1 root root 980 Oct 5 13:13 ceph.conf -rw-r--r-- 1 root root 92 Aug 24 22:03 rbdmap 2). Show the content of the newly created keyring: admin:/etc/ceph # cat ceph.client.james.keyring [client.james] key = caps mon = \"allow r\" caps osd = \"allow rw pool=iscsi-images\" 3). Officially add the new keyring to Ceph: admin:/etc/ceph # ceph auth add client.james -i /etc/ceph/ceph.client.james.keyring added key for client.james 4). Show the key information using the \u201cauth\u201d function: admin:/etc/ceph # ceph auth get client.james exported keyring for client.james [client.james] key = caps mon = \"allow r\" caps osd = \"allow rw pool=iscsi-images\" Task 3: Create a client key for RBD \u00b6 1). Change to the directory that contains the ceph keyrings. admin:~ # cd /etc/ceph/ 2). List the content of the directory: Although you see the admin users\u2019s keyring, ceph.client.admin.keyring, there is not yet a file that is appropriate for a specific application to use. Also note that the permissions on the keyring file are quite restrictive: 0600 admin:/etc/ceph # ls -l -rw------- 1 root root 151 Oct 5 13:13 ceph.client.admin.keyring -rw------- 1 root root 126 Jan 5 19:31 ceph.client.james.keyring -rw-r--r-- 1 root root 980 Oct 5 13:13 ceph.conf -rw-r--r-- 1 root root 92 Aug 24 22:03 rbdmap 3). Show the content of the admin user\u2019s keyring: You will use the value associated with the \u201ckey\u201d key to create a new file. Copy the \u201ckey\u201d value using your favorite method. admin:/etc/ceph # cat ceph.client.admin.keyring [client.admin] key = caps mds = \"allow *\" caps mon = \"allow *\" caps osd = \"allow *\" caps mgr = \"allow *\" 4). Open a new file for editing called admin.secret using your favorite editor (such as vi): The name of the file isn\u2019t very important, but naming it this way will help to identify its purpose: it\u2019s a secret key for the admin user. Note that there are many ways to do this. An alternative way is mentioned in the tip below that will do this in one step using grep and awk. admin:/etc/ceph # vi admin.secret 5). Paste the \u201ckey\u201d value into the new file. It will be the only content of the file. It will look like this (in fact it\u2019s probably exactly the same as this, if you\u2019re using the demo environment provided to you): admin:/etc/ceph # cat admin.secret 6). Save the file and exist out of the editor. 7). Change the permissions of the file so that no other user on the host can see the content of the file: admin:/etc/ceph # chmod 0600 admin.secret admin:/etc/ceph # l drwxr-xr-x 1 root root 154 Jan 5 20:03 ./ drwxr-xr-x 1 root root 4392 Oct 5 13:03 ../ -rw------- 1 root root 41 Jan 5 20:03 admin.secret -rw------- 1 root root 151 Oct 5 13:13 ceph.client.admin.keyring -rw------- 1 root root 126 Jan 5 19:31 ceph.client.james.keyring -rw-r--r-- 1 root root 980 Oct 5 13:13 ceph.conf -rw-r--r-- 1 root root 92 Aug 24 22:03 rbdmap Tip: An alternative way to create this key file is to simply use grep/awk together in one bash command, like this: admin:/etc/ceph # grep \"key =\" ceph.client.admin.keyring | awk -F\" = \" '{ print $2 }' admin:/etc/ceph # grep \"key =\" ceph.client.admin.keyring | awk -F\" = \" '{ print $2 }' > admin.secret admin:/etc/ceph # cat admin.secret Task 4: View the Ceph master configuration file \u00b6 View the content of the file. The file is managed and controlled by DeepSea. The comment makes reference to the control files in the /srv/salt/ceph/configuration/ directory hierarchy. This is a very simple storage cluster. In a more diverse and sophisticated ceph cluster there may be more configuration settings defined. Although this exercise doesn\u2019t call out any more specific information about this configuration file, you may take a moment to consider the content of the file before finishing the task. admin:/etc/ceph # cat ceph.conf # DeepSea default configuration. Changes in this file will be overwritten on # package update. Include custom configuration fragments in # /srv/salt/ceph/configuration/files/ceph.conf.d/[global,osd,mon,mgr,mds,client].conf [global] fsid = 343ee7d3-232f-4c71-8216-1edbc55ac6e0 mon_initial_membgrs = mon1, mon2, mon3 mon_host = 10.58.121.186, 10.58.121.187, 10.58.121.188 auth_cluster_required = cephx auth_service_required = cephx auth_client_required = cephx public_network = 10.58.120.0/23 cluster_network = 10.58.120.0/23 ms_bind_msgr2 = false # enable old ceph health format in the json output. This fixes the # ceph_exporter. This option will only stay until the prometheus plugin takes # over mon_health_preluminous_compat = true mon health preluminous compat warning = false rbd default features = 3 [client.rgw.mon3] rgw frontends = \"beast port=80\" rgw dns name = mon3.sha.me.corp rgw enable usage log = true [osd] [mon] [mgr] [mds] [client] admin:/etc/ceph # ls -l /srv/salt/ceph/configuration/ drwxr-xr-x 1 salt salt 18 Oct 5 13:13 cache drwxr-xr-x 1 root root 38 Oct 5 09:04 check drwxr-xr-x 1 root root 74 Oct 5 09:04 create -rw-r--r-- 1 root root 217 May 14 2020 default-import.sls -rw-r--r-- 1 root root 222 May 14 2020 default.sls drwxr-xr-x 1 root root 276 Oct 5 12:55 files -rw-r--r-- 1 root root 74 May 14 2020 init.sls 2.2.2. Run the Ceph Health Commands \u00b6 Get overall health status admin:~ # ceph health HEALTH_OK admin:~ # ceph -s admin:~ # ceph status cluster: id: 343ee7d3-232f-4c71-8216-1edbc55ac6e0 health: HEALTH_OK services: mon: 3 daemons, quorum mon1,mon2,mon3 (age 9w) mgr: mon1(active, since 5w) mds: cephfs:1 {0=mon3=up:active} 2 up:standby osd: 12 osds: 12 up (since 98m), 12 in (since 3M) rgw: 1 daemon active (mon3) task status: scrub status: mds.mon3: idle data: pools: 7 pools, 208 pgs objects: 246 objects, 4.7 KiB usage: 14 GiB used, 82 GiB / 96 GiB avail pgs: 208 active+clean io: client: 852 B/s rd, 0 op/s rd, 0 op/s wr Run the \u201cstatus\u201d command for the monitors: admin:~ # ceph mon stat e1: 3 mons at { mon1=[v2:10.58.121.186:3300/0,v1:10.58.121.186:6789/0], mon2=[v2:10.58.121.187:3300/0,v1:10.58.121.187:6789/0], mon3=[v2:10.58.121.188:3300/0,v1:10.58.121.188:6789/0] }, election epoch 22, leader 0 mon1, quorum 0,1,2 mon1,mon2,mon3 Run the \u201cstatus\u201d command for the placement groups: admin:~ # ceph pg stat 208 pgs: 208 active+clean; 4.7 KiB data, 2.1 GiB used, 82 GiB / 96 GiB avail; 852 B/s rd, 0 op/s Run the ceph \u201cstatus\u201d command while watching for changes to the status: admin:~ # ceph -s --watch-debug cluster: id: 343ee7d3-232f-4c71-8216-1edbc55ac6e0 health: HEALTH_OK services: mon: 3 daemons, quorum mon1,mon2,mon3 (age 9w) mgr: mon1(active, since 5w) mds: cephfs:1 {0=mon3=up:active} 2 up:standby osd: 12 osds: 12 up (since 104m), 12 in (since 3M) rgw: 1 daemon active (mon3) task status: scrub status: mds.mon3: idle data: pools: 7 pools, 208 pgs objects: 246 objects, 4.7 KiB usage: 14 GiB used, 82 GiB / 96 GiB avail pgs: 208 active+clean io: client: 1.2 KiB/s rd, 1 op/s rd, 0 op/s wr 2021-01-05 20:20:53.947298 mgr.mon1 [DBG] pgmap v1597415: 208 pgs: 208 active+clean; 4.7 KiB data, 2.1 GiB used, 82 GiB / 96 GiB avail; 852 B/s rd, 0 op/s 2021-01-05 20:20:55.949294 mgr.mon1 [DBG] pgmap v1597416: 208 pgs: 208 active+clean; 4.7 KiB data, 2.1 GiB used, 82 GiB / 96 GiB avail; 1.2 KiB/s rd, 1 op/s ....... 2.2.3. Manipulate Pools \u00b6 Task 1: Display a list of the current pools \u00b6 admin:~ # ceph osd pool ls iscsi-images cephfs_data cephfs_metadata .rgw.root default.rgw.control default.rgw.meta default.rgw.log admin:~ # ceph osd pool ls detail pool 1 'iscsi-images' replicated size 3 min_size 2 crush_rule 0 object_hash rjenkins pg_num 32 pgp_num 32 autoscale_mode on last_change 448 lfor 0/448/446 flags hashpspool stripe_width 0 application rbd pool 2 'cephfs_data' replicated size 3 min_size 2 crush_rule 0 object_hash rjenkins pg_num 32 pgp_num 32 last_change 1395 lfor 0/1374/1372 flags hashpspool stripe_width 0 application cephfs pool 3 'cephfs_metadata' replicated size 3 min_size 2 crush_rule 0 object_hash rjenkins pg_num 16 pgp_num 16 last_change 1385 lfor 0/975/973 flags hashpspool stripe_width 0 pg_autoscale_bias 4 pg_num_min 16 recovery_priority 5 application cephfs pool 4 '.rgw.root' replicated size 3 min_size 2 crush_rule 0 object_hash rjenkins pg_num 32 pgp_num 32 autoscale_mode warn last_change 31 flags hashpspool stripe_width 0 application rgw pool 5 'default.rgw.control' replicated size 3 min_size 2 crush_rule 0 object_hash rjenkins pg_num 32 pgp_num 32 autoscale_mode warn last_change 33 flags hashpspool stripe_width 0 application rgw pool 6 'default.rgw.meta' replicated size 3 min_size 2 crush_rule 0 object_hash rjenkins pg_num 32 pgp_num 32 autoscale_mode warn last_change 35 flags hashpspool stripe_width 0 application rgw pool 7 'default.rgw.log' replicated size 3 min_size 2 crush_rule 0 object_hash rjenkins pg_num 32 pgp_num 32 autoscale_mode warn last_change 37 flags hashpspool stripe_width 0 application rgw List pools with their index numbgr. Note how the index numbgr matches the index numbgr of the detail listing above. admin:~ # ceph osd lspools 1 iscsi-images 2 cephfs_data 3 cephfs_metadata 4 .rgw.root 5 default.rgw.control 6 default.rgw.meta 7 default.rgw.log Task 2: Display the usage data and stats of the current pools \u00b6 Display pool usages. Note again index \u201cID\u201d for the pool. admin:~ # ceph df RAW STORAGE: CLASS SIZE AVAIL USED RAW USED %RAW USED hdd 96 GiB 82 GiB 2.1 GiB 14 GiB 14.81 TOTAL 96 GiB 82 GiB 2.1 GiB 14 GiB 14.81 POOLS: POOL ID STORED OBJECTS USED %USED MAX AVAIL iscsi-images 1 389 B 2 192 KiB 0 25 GiB cephfs_data 2 0 B 0 0 B 0 25 GiB cephfs_metadata 3 7.2 KiB 48 1.5 MiB 0 25 GiB .rgw.root 4 1.2 KiB 4 768 KiB 0 25 GiB default.rgw.control 5 0 B 8 0 B 0 25 GiB default.rgw.meta 6 381 B 3 576 KiB 0 25 GiB default.rgw.log 7 35 KiB 208 35 KiB 0 25 GiB admin:~ # ceph df detail RAW STORAGE: CLASS SIZE AVAIL USED RAW USED %RAW USED hdd 96 GiB 82 GiB 2.1 GiB 14 GiB 14.81 TOTAL 96 GiB 82 GiB 2.1 GiB 14 GiB 14.81 POOLS: POOL ID STORED OBJECTS USED %USED MAX AVAIL QUOTA OBJECTS QUOTA BYTES DIRTY USED COMPR UNDER COMPR iscsi-images 1 389 B 2 192 KiB 0 25 GiB N/A N/A 2 0 B 0 B cephfs_data 2 0 B 0 0 B 0 25 GiB N/A N/A 0 0 B 0 B cephfs_metadata 3 7.2 KiB 48 1.5 MiB 0 25 GiB N/A N/A 48 0 B 0 B .rgw.root 4 1.2 KiB 4 768 KiB 0 25 GiB N/A N/A 4 0 B 0 B default.rgw.control 5 0 B 8 0 B 0 25 GiB N/A N/A 8 0 B 0 B default.rgw.meta 6 381 B 3 576 KiB 0 25 GiB N/A N/A 3 0 B 0 B default.rgw.log 7 35 KiB 208 35 KiB 0 25 GiB N/A N/A 208 0 B 0 B Display pool usages using rados command admin:~ # rados df POOL_NAME USED OBJECTS CLONES COPIES MISSING_ON_PRIMARY UNFOUND DEGRADED RD_OPS RD WR_OPS WR USED COMPR UNDER COMPR .rgw.root 768 KiB 4 0 12 0 0 0 40 40 KiB 4 4 KiB 0 B 0 B cephfs_data 0 B 0 0 0 0 0 0 0 0 B 0 0 B 0 B 0 B cephfs_metadata 1.5 MiB 48 0 144 0 0 0 0 0 B 111 42 KiB 0 B 0 B default.rgw.control 0 B 8 0 24 0 0 0 0 0 B 0 0 B 0 B 0 B default.rgw.log 35 KiB 208 0 624 0 0 0 5919671 5.6 GiB 3945118 946 KiB 0 B 0 B default.rgw.meta 576 KiB 3 0 9 0 0 0 38 28 KiB 4 3 KiB 0 B 0 B iscsi-images 192 KiB 2 0 6 0 0 0 4184657 4.0 GiB 8 2 KiB 0 B 0 B total_objects 246 total_used 14 GiB total_avail 82 GiB total_space 96 GiB Show the statistics of the pools: admin:~ # ceph osd pool stats pool iscsi-images id 1 client io 1.2 KiB/s rd, 1 op/s rd, 0 op/s wr pool cephfs_data id 2 nothing is going on pool cephfs_metadata id 3 nothing is going on pool .rgw.root id 4 nothing is going on pool default.rgw.control id 5 nothing is going on pool default.rgw.meta id 6 nothing is going on pool default.rgw.log id 7 nothing is going on Show only the statistics about a specific pool: admin:~ # ceph osd pool stats .rgw.root pool .rgw.root id 4 nothing is going on Show which CRUSH Map ruleset was used to create the .rgw.root pool: admin:~ # ceph osd pool get .rgw.root crush_rule crush_rule: replicated_rule Show the list of all the attributes of a pool that can be queried: admin:~ # ceph osd pool get .rgw.root size min_size pg_num pgp_num crush_rule Hashpspool Nodelete Nopgchange Nosizechange write_fadvise_dontneed noscrub|nodeep-scrub hit_set_type hit_set_period hit_set_count hit_set_fpp use_gmt_hitset target_max_objects target_max_bytes cache_target_dirty_ratio cache_target_dirty_high_ratio cache_target_full_ratio cache_min_flush_age cache_min_evict_age erasure_code_profile min_read_recency_for_promote all|min_write_recency_for_promote fast_read|hit_set_grade_decay_rate hit_set_search_last_n scrub_min_interval scrub_max_interval deep_scrub_interval recovery_priority recovery_op_priority scrub_priority compression_mode compression_algorithm compression_required_ratio compression_max_blob_size compression_min_blob_size csum_type|csum_min_block csum_max_block allow_ec_overwrites fingerprint_algorithm pg_autoscale_mode pg_autoscale_bias pg_num_min target_size_bytes target_size_ratio Task 3: Create two new pools, one replicated, one EC \u00b6 1). Create a new replicated pool that will be used for storing block data for RBD. Use the standard replicated_ruleset CRUSH Map: It would be tempting to the use the better_ruleset, but this demo environment doesn\u2019t have enough resources for that. This is a demo environment, so the PG numbgrs will be low. In your production environments, be sure to assign an appropriately high numbgr, or use the pg_autoscaler manager module. admin:~ # ceph osd pool create rbd_pool 4 4 replicated replicated_rule pool 'rbd_pool' created 2). Tell the cluster that you expect to have this new rbd_pool to use 50% of the total capacity: admin:~ # ceph osd pool set rbd_pool target_size_ratio .5 set pool 8 target_size_ratio to .5 3). Create a new EC pool that will be used for storing RGW buckets and objects. Use the usable_profile Erasure Code profile that was created in an earlier exercise. And use the ec_rule CRUSH Map ruleset that was created in an earlier exercise: admin:~ # ceph osd pool create bucket_pool 4 4 erasure usable_profile ec_rule pool 'bucket_pool' created 4). Tell the cluster that you expect to have this new bucket_pool to use 100GB of data: POOL_TARGET_SIZE_BYTES_OVERCOMMITTED admin:~ # ceph osd pool set bucket_pool target_size_bytes 100000000000 set pool 9 target_size_bytes to 100000000000 5). Enable the PG Autoscaler feature on the two new pools, to ensure that we have an appropriate assignment of placement groups in the demo cluster: This presumes that you completed an earlier exercise that enable the pg_autoscaler manager module. admin:~ # ceph osd pool set bucket_pool pg_autoscale_mode on set pool 9 pg_autoscale_mode to on admin:~ # ceph osd pool set rbd_pool pg_autoscale_mode on set pool 8 pg_autoscale_mode to on 6). Again display a list of all the pools, which will now include the two new pools that you\u2019ve just created: Notice in the detail listing that the two new pools don\u2019t have an application attribute assigned to them. admin:~ # ceph osd lspools 1 iscsi-images 2 cephfs_data 3 cephfs_metadata 4 .rgw.root 5 default.rgw.control 6 default.rgw.meta 7 default.rgw.log 8 rbd_pool 9 bucket_pool admin:~ # ceph osd pool ls detail pool 1 'iscsi-images' replicated size 3 min_size 2 crush_rule 0 object_hash rjenkins pg_num 32 pgp_num 32 autoscale_mode on last_change 448 lfor 0/448/446 flags hashpspool stripe_width 0 application rbd pool 2 'cephfs_data' replicated size 3 min_size 2 crush_rule 0 object_hash rjenkins pg_num 32 pgp_num 32 last_change 1395 lfor 0/1374/1372 flags hashpspool stripe_width 0 application cephfs pool 3 'cephfs_metadata' replicated size 3 min_size 2 crush_rule 0 object_hash rjenkins pg_num 16 pgp_num 16 last_change 1385 lfor 0/975/973 flags hashpspool stripe_width 0 pg_autoscale_bias 4 pg_num_min 16 recovery_priority 5 application cephfs pool 4 '.rgw.root' replicated size 3 min_size 2 crush_rule 0 object_hash rjenkins pg_num 32 pgp_num 32 autoscale_mode warn last_change 31 flags hashpspool stripe_width 0 application rgw pool 5 'default.rgw.control' replicated size 3 min_size 2 crush_rule 0 object_hash rjenkins pg_num 32 pgp_num 32 autoscale_mode warn last_change 33 flags hashpspool stripe_width 0 application rgw pool 6 'default.rgw.meta' replicated size 3 min_size 2 crush_rule 0 object_hash rjenkins pg_num 32 pgp_num 32 autoscale_mode warn last_change 35 flags hashpspool stripe_width 0 application rgw pool 7 'default.rgw.log' replicated size 3 min_size 2 crush_rule 0 object_hash rjenkins pg_num 32 pgp_num 32 autoscale_mode warn last_change 37 flags hashpspool stripe_width 0 application rgw pool 8 'rbd_pool' replicated size 3 min_size 2 crush_rule 0 object_hash rjenkins pg_num 32 pgp_num 32 autoscale_mode on last_change 1415 lfor 0/0/1413 flags hashpspool stripe_width 0 target_size_ratio 0.5 pool 9 'bucket_pool' erasure size 3 min_size 2 crush_rule 3 object_hash rjenkins pg_num 4 pgp_num 4 autoscale_mode on last_change 1410 flags hashpspool stripe_width 8192 target_size_bytes 100000000000 7). Check the pg_autoscale status, particularly to see a comparison of how much raw space is being consumed by the two pools: See that the RATE column for all of the replicated pools shows the value of 3.0, while the value for the bucket_pool \u2013 which is an EC pool \u2013 is 1.5. The EC pool, with a K+M of 2+1 consumes considerably less raw storage space. See the TARGET RATIO for the rbd_pool. Notice that the autoscaler has automatically adjusted the numbgr PGs assigned to rbd_pool from \u201c4\u201d to \u201c128\u201d because you told the cluster to have the pool use 50% of the capacity. See the TARGET SIZE for the bucket_pool, roughly 100GB. But the cluster may not have changed the PG_NUM value yet. The autoscaler will adjust the numbgr of PGs gradually, so as not to disrupt the performance too dramatically. While you\u2019re here, you might also notice the RAW CAPACITY column. All pools are expecting to divide the cluster space equally, even though you\u2019ve explicitly told the cluster that rbd_pool and bucket_pool will deviate from that even division. admin:~ # ceph osd pool autoscale-status POOL SIZE TARGET SIZE RATE RAW CAPACITY RATIO TARGET RATIO EFFECTIVE RATIO BIAS PG_NUM NEW PG_NUM AUTOSCALE iscsi-images 389 3.0 98256M 0.0000 1.0 32 on cephfs_data 0 3.0 98256M 0.0000 1.0 32 off cephfs_metadata 7412 3.0 98256M 0.0000 4.0 16 off .rgw.root 1245 3.0 98256M 0.0000 1.0 32 warn default.rgw.control 0 3.0 98256M 0.0000 1.0 32 warn default.rgw.meta 381 3.0 98256M 0.0000 1.0 32 warn default.rgw.log 35900 3.0 98256M 0.0000 1.0 32 warn rbd_pool 0 3.0 98256M 0.0000 0.5000 1.0 32 on bucket_pool 0 95367M 1.5 98256M 1.4559 1.0 4 on Task 4: Assign an application to the two new pools \u00b6 1). Assign the rbd application to the new rbd_pool that you created in the previous task: admin:~ # ceph osd pool application enable rbd_pool rbd enabled application 'rbd' on pool 'rbd_pool' 2). Instruct the cluster to prepare the new rbd_pool for storing block device images: admin:~ # rbd pool init rbd_pool 3). Assign the rgw application to the new bucket_pool that you created in the previous task: admin:~ # ceph osd pool application enable bucket_pool rgw enabled application 'rgw' on pool 'bucket_pool' 4). Display a list of all the pools again, this time noticing that the application attribute is set on the two new pools. admin:~ # ceph osd lspools 1 iscsi-images 2 cephfs_data 3 cephfs_metadata 4 .rgw.root 5 default.rgw.control 6 default.rgw.meta 7 default.rgw.log 8 rbd_pool 9 bucket_pool admin:~ # ceph osd pool ls detail pool 1 'iscsi-images' replicated size 3 min_size 2 crush_rule 0 object_hash rjenkins pg_num 32 pgp_num 32 autoscale_mode on last_change 448 lfor 0/448/446 flags hashpspool stripe_width 0 application rbd pool 2 'cephfs_data' replicated size 3 min_size 2 crush_rule 0 object_hash rjenkins pg_num 32 pgp_num 32 last_change 1395 lfor 0/1374/1372 flags hashpspool stripe_width 0 application cephfs pool 3 'cephfs_metadata' replicated size 3 min_size 2 crush_rule 0 object_hash rjenkins pg_num 16 pgp_num 16 last_change 1385 lfor 0/975/973 flags hashpspool stripe_width 0 pg_autoscale_bias 4 pg_num_min 16 recovery_priority 5 application cephfs pool 4 '.rgw.root' replicated size 3 min_size 2 crush_rule 0 object_hash rjenkins pg_num 32 pgp_num 32 autoscale_mode warn last_change 31 flags hashpspool stripe_width 0 application rgw pool 5 'default.rgw.control' replicated size 3 min_size 2 crush_rule 0 object_hash rjenkins pg_num 32 pgp_num 32 autoscale_mode warn last_change 33 flags hashpspool stripe_width 0 application rgw pool 6 'default.rgw.meta' replicated size 3 min_size 2 crush_rule 0 object_hash rjenkins pg_num 32 pgp_num 32 autoscale_mode warn last_change 35 flags hashpspool stripe_width 0 application rgw pool 7 'default.rgw.log' replicated size 3 min_size 2 crush_rule 0 object_hash rjenkins pg_num 32 pgp_num 32 autoscale_mode warn last_change 37 flags hashpspool stripe_width 0 application rgw pool 8 'rbd_pool' replicated size 3 min_size 2 crush_rule 0 object_hash rjenkins pg_num 32 pgp_num 32 autoscale_mode on last_change 1420 lfor 0/0/1413 flags hashpspool,selfmanaged_snaps stripe_width 0 target_size_ratio 0.5 application rbd removed_snaps [1~3] pool 9 'bucket_pool' erasure size 3 min_size 2 crush_rule 3 object_hash rjenkins pg_num 4 pgp_num 4 autoscale_mode on last_change 1422 flags hashpspool stripe_width 8192 target_size_bytes 100000000000 application rgw 5). Another way to display which application is assigned to a pool is: admin:~ # ceph osd pool application get bucket_pool { \"rgw\": {} } admin:~ # ceph osd pool application get rbd_pool { \"rbd\": {} } Task 5: Manage snapshots of the new RGW bucket pool \u00b6 1). Display a list of the snapshots that exist of the bucket_pool that you created in the previous task: The output show that there are \u201c0 snaps.\u201d Right, it is a little funny that you only list the snapshots with rados command; no such functionality exists with the ceph osd pool command. admin:~ # rados -p bucket_pool lssnap 0 snaps 2). Take (make) a snapshot of the rbd_pool: admin:~ # ceph osd pool mksnap bucket_pool brand_new_pool_snapshot created pool bucket_pool snap brand_new_pool_snapshot 3). Display the list of the snapshots again: admin:~ # rados -p bucket_pool lssnap 1 brand_new_pool_snapshot 2021.01.05 22:23:23 1 snaps 4). Remove the snapshot: admin:~ # ceph osd pool rmsnap bucket_pool brand_new_pool_snapshot removed pool bucket_pool snap brand_new_pool_snapshot 5). Display the list of the snapshots again: admin:~ # rados -p bucket_pool lssnap 0 snaps 2.2.4. Maintain consistency of data with Scrub and Repair \u00b6 Scrubbing is like \u201cfsck,\u201d which ensures that OSDs have durable, consistent data. Most of the scrubbing of OSDs happens automatically on a periodic basis. Task 1: Display a few of the Scrub settings \u00b6 1). Show the possible configuration settings related to scrub: If you simply grep for \u201cscrub\u201d you\u2019ll get more than you really want; there are some mon_scrub settings that aren\u2019t related to this exercise. admin:~ # ceph config ls | grep osd_scrub osd_scrub_invalid_stats osd_scrub_during_recovery osd_scrub_begin_hour osd_scrub_end_hour osd_scrub_begin_week_day osd_scrub_end_week_day osd_scrub_load_threshold osd_scrub_min_interval osd_scrub_max_interval osd_scrub_interval_randomize_ratio osd_scrub_backoff_ratio osd_scrub_chunk_min osd_scrub_chunk_max osd_scrub_sleep osd_scrub_auto_repair osd_scrub_auto_repair_num_errors osd_scrub_max_preemptions osd_scrub_priority osd_scrub_cost admin:~ # ceph config ls | grep osd_deep_scrub osd_deep_scrub_interval osd_deep_scrub_randomize_ratio osd_deep_scrub_stride osd_deep_scrub_keys osd_deep_scrub_update_digest_min_age osd_deep_scrub_large_omap_object_key_threshold osd_deep_scrub_large_omap_object_value_sum_threshold admin:~ # ceph config ls | grep scrub mon_warn_pg_not_scrubbed_ratio mon_warn_pg_not_deep_scrubbed_ratio mon_scrub_interval mon_scrub_timeout mon_scrub_max_keys mon_scrub_inject_crc_mismatch mon_scrub_inject_missing_keys osd_op_queue_mclock_scrub_res osd_op_queue_mclock_scrub_wgt osd_op_queue_mclock_scrub_lim osd_scrub_invalid_stats osd_max_scrubs osd_scrub_during_recovery osd_scrub_begin_hour osd_scrub_end_hour osd_scrub_begin_week_day osd_scrub_end_week_day osd_scrub_load_threshold osd_scrub_min_interval osd_scrub_max_interval osd_scrub_interval_randomize_ratio osd_scrub_backoff_ratio osd_scrub_chunk_min osd_scrub_chunk_max osd_scrub_sleep osd_scrub_auto_repair osd_scrub_auto_repair_num_errors osd_scrub_max_preemptions osd_deep_scrub_interval osd_deep_scrub_randomize_ratio osd_deep_scrub_stride osd_deep_scrub_keys osd_deep_scrub_update_digest_min_age osd_deep_scrub_large_omap_object_key_threshold osd_deep_scrub_large_omap_object_value_sum_threshold osd_debug_deep_scrub_sleep osd_scrub_priority osd_scrub_cost osd_requested_scrub_priority mds_max_scrub_ops_in_progress 2). Get the value of a few of the different scrub schedule settings: Note that \u201c0\u201d and \u201c24\u201d are the same setting. admin:~ # ceph config get osd.* osd_scrub_begin_hour 0 admin:~ # ceph config get osd.* osd_scrub_end_hour 24 3). Get the value of the scrub and repair settings: The \u201cauto repair\u201d feature is turned off, and the maximum numbgr of errors that \u201cauto repair\u201d would automatically repair is 5. admin:~ # ceph config get osd.* osd_scrub_auto_repair false admin:~ # ceph config get osd.* osd_scrub_auto_repair_num_errors 5 Task 2: Change the Scrub settings in ceph.conf \u00b6 1). Display the ceph.conf, and verify that the file doesn\u2019t have any settings defined yet that are related to scrub. The settings would be located in the [global] section of the file: # DeepSea default configuration. Changes in this file will be overwritten on # package update. Include custom configuration fragments in # /srv/salt/ceph/configuration/files/ceph.conf.d/[global,osd,mon,mgr,mds,client].conf [global] fsid = 343ee7d3-232f-4c71-8216-1edbc55ac6e0 mon_initial_membgrs = mon1, mon2, mon3 mon_host = 10.58.121.186, 10.58.121.187, 10.58.121.188 auth_cluster_required = cephx auth_service_required = cephx auth_client_required = cephx public_network = 10.58.120.0/23 cluster_network = 10.58.120.0/23 ms_bind_msgr2 = false # enable old ceph health format in the json output. This fixes the # ceph_exporter. This option will only stay until the prometheus plugin takes # over mon_health_preluminous_compat = true mon health preluminous compat warning = false rbd default features = 3 [client.rgw.mon3] rgw frontends = \"beast port=80\" rgw dns name = mon3.sha.me.corp rgw enable usage log = true [osd] [mon] [mgr] [mds] [client] 2). Change to the Salt File Server directory that will have Salt control the master ceph.conf configuration file: admin:~ # cd /srv/salt/ceph/configuration/files/ceph.conf.d/ 3). List the content of the directory: The directory is empty. (Well, there is a README, but no other functional files.) admin:/srv/salt/ceph/configuration/files/ceph.conf.d # ls -l -rw-r--r-- 1 root root 1989 May 14 2020 README 4). Create and edit a new file called global.conf. You don\u2019t have to use vi, but this step uses vi as one way of doing it: Be sure that you spell everything correctly, including the absence of \u201c_\u201d characters; there are spaces. Save the file and exit out of the editor. admin:/srv/salt/ceph/configuration/files/ceph.conf.d # vi global.conf Add the following content to the file: osd scrub begin hour = 23 osd scrub end hour = 5 osd scrub auto repair = True osd scrub auto repair num errors = 10 5). Use DeepSea (Salt) to stage the file properly in Salt\u2019s File Server on the Salt Master (admin): admin:/srv/salt/ceph/configuration/files/ceph.conf.d # salt admin* state.apply ceph.configuration.create admin.sha.me.corp: Name: /var/cache/salt/minion/files/base/ceph/configuration - Function: file.absent - Result: Changed Started: - 22:42:34.900173 Duration: 20.891 ms Name: /srv/salt/ceph/configuration/cache/ceph.conf - Function: file.managed - Result: Changed Started: - 22:42:34.921454 Duration: 8576.516 ms Name: find /var/cache/salt/master/jobs -user root -exec chown salt:salt {} ';' - Function: cmd.run - Result: Changed Started: - 22:42:43.535022 Duration: 71.957 ms Summary for admin.sha.me.corp ------------ Succeeded: 3 (changed=3) Failed: 0 ------------ Total states run: 3 Total run time: 8.669 s 6). Using DeepSea (Salt), distribute the new ceph.conf configuration settings to all the nodes in the cluster: admin:/srv/salt/ceph/configuration/files/ceph.conf.d # salt \\* state.apply ceph.configuration mon3.sha.me.corp: Name: /etc/ceph/ceph.conf - Function: file.managed - Result: Changed Started: - 22:44:07.986661 Duration: 101.977 ms Summary for mon3.sha.me.corp ------------ Succeeded: 1 (changed=1) Failed: 0 ------------ Total states run: 1 Total run time: 101.977 ms mon1.sha.me.corp: Name: /etc/ceph/ceph.conf - Function: file.managed - Result: Changed Started: - 22:44:08.012479 Duration: 108.888 ms Summary for mon1.sha.me.corp ------------ Succeeded: 1 (changed=1) Failed: 0 ------------ Total states run: 1 Total run time: 108.888 ms data3.sha.me.corp: Name: /etc/ceph/ceph.conf - Function: file.managed - Result: Changed Started: - 22:44:08.052247 Duration: 98.681 ms Summary for data3.sha.me.corp ------------ Succeeded: 1 (changed=1) Failed: 0 ------------ Total states run: 1 Total run time: 98.681 ms admin.sha.me.corp: Name: /etc/ceph/ceph.conf - Function: file.managed - Result: Changed Started: - 22:44:08.072402 Duration: 97.231 ms Summary for admin.sha.me.corp ------------ Succeeded: 1 (changed=1) Failed: 0 ------------ Total states run: 1 Total run time: 97.231 ms data1.sha.me.corp: Name: /etc/ceph/ceph.conf - Function: file.managed - Result: Changed Started: - 22:44:08.076279 Duration: 104.169 ms Summary for data1.sha.me.corp ------------ Succeeded: 1 (changed=1) Failed: 0 ------------ Total states run: 1 Total run time: 104.169 ms data4.sha.me.corp: Name: /etc/ceph/ceph.conf - Function: file.managed - Result: Changed Started: - 22:44:08.081635 Duration: 105.13 ms Summary for data4.sha.me.corp ------------ Succeeded: 1 (changed=1) Failed: 0 ------------ Total states run: 1 Total run time: 105.130 ms mon2.sha.me.corp: Name: /etc/ceph/ceph.conf - Function: file.managed - Result: Changed Started: - 22:44:08.155758 Duration: 105.004 ms Summary for mon2.sha.me.corp ------------ Succeeded: 1 (changed=1) Failed: 0 ------------ Total states run: 1 Total run time: 105.004 ms data2.sha.me.corp: Name: /etc/ceph/ceph.conf - Function: file.managed - Result: Changed Started: - 22:44:08.252200 Duration: 109.552 ms Summary for data2.sha.me.corp ------------ Succeeded: 1 (changed=1) Failed: 0 ------------ Total states run: 1 Total run time: 109.552 ms 7). Verify that the new ceph.conf settings have been put into place on the admin node: admin:/srv/salt/ceph/configuration/files/ceph.conf.d # cat /etc/ceph/ceph.conf # DeepSea default configuration. Changes in this file will be overwritten on # package update. Include custom configuration fragments in # /srv/salt/ceph/configuration/files/ceph.conf.d/[global,osd,mon,mgr,mds,client].conf [global] fsid = 343ee7d3-232f-4c71-8216-1edbc55ac6e0 mon_initial_membgrs = mon1, mon2, mon3 mon_host = 10.58.121.188, 10.58.121.187, 10.58.121.186 auth_cluster_required = cephx auth_service_required = cephx auth_client_required = cephx public_network = 10.58.120.0/23 cluster_network = 10.58.120.0/23 ms_bind_msgr2 = false # enable old ceph health format in the json output. This fixes the # ceph_exporter. This option will only stay until the prometheus plugin takes # over mon_health_preluminous_compat = true mon health preluminous compat warning = false rbd default features = 3 osd scrub begin hour = 23 osd scrub end hour = 5 osd scrub auto repair = True osd scrub auto repair num errors = 10 [client.rgw.mon3] rgw frontends = \"beast port=80\" rgw dns name = mon3.sha.me.corp rgw enable usage log = true [osd] [mon] [mgr] [mds] [client] 8). Also verify that other minions in the cluster have also received the updated configuration file, such as on the mon1 and data2 nodes: admin:/srv/salt/ceph/configuration/files/ceph.conf.d # ssh mon1 cat /etc/ceph/ceph.conf # DeepSea default configuration. Changes in this file will be overwritten on # package update. Include custom configuration fragments in # /srv/salt/ceph/configuration/files/ceph.conf.d/[global,osd,mon,mgr,mds,client].conf [global] fsid = 343ee7d3-232f-4c71-8216-1edbc55ac6e0 mon_initial_membgrs = mon1, mon2, mon3 mon_host = 10.58.121.188, 10.58.121.187, 10.58.121.186 auth_cluster_required = cephx auth_service_required = cephx auth_client_required = cephx public_network = 10.58.120.0/23 cluster_network = 10.58.120.0/23 ms_bind_msgr2 = false # enable old ceph health format in the json output. This fixes the # ceph_exporter. This option will only stay until the prometheus plugin takes # over mon_health_preluminous_compat = true mon health preluminous compat warning = false rbd default features = 3 osd scrub begin hour = 23 osd scrub end hour = 5 osd scrub auto repair = True osd scrub auto repair num errors = 10 [client.rgw.mon3] rgw frontends = \"beast port=80\" rgw dns name = mon3.sha.me.corp rgw enable usage log = true [osd] [mon] [mgr] [mds] [client] admin:/srv/salt/ceph/configuration/files/ceph.conf.d # ssh data1 cat /etc/ceph/ceph.conf # DeepSea default configuration. Changes in this file will be overwritten on # package update. Include custom configuration fragments in # /srv/salt/ceph/configuration/files/ceph.conf.d/[global,osd,mon,mgr,mds,client].conf [global] fsid = 343ee7d3-232f-4c71-8216-1edbc55ac6e0 mon_initial_membgrs = mon1, mon2, mon3 mon_host = 10.58.121.188, 10.58.121.187, 10.58.121.186 auth_cluster_required = cephx auth_service_required = cephx auth_client_required = cephx public_network = 10.58.120.0/23 cluster_network = 10.58.120.0/23 ms_bind_msgr2 = false # enable old ceph health format in the json output. This fixes the # ceph_exporter. This option will only stay until the prometheus plugin takes # over mon_health_preluminous_compat = true mon health preluminous compat warning = false rbd default features = 3 osd scrub begin hour = 23 osd scrub end hour = 5 osd scrub auto repair = True osd scrub auto repair num errors = 10 [client.rgw.mon3] rgw frontends = \"beast port=80\" rgw dns name = mon3.sha.me.corp rgw enable usage log = true [osd] [mon] [mgr] [mds] [client] 9). Apply the settings of the ceph.conf file to appropriate nodes in the cluster: admin:/srv/salt/ceph/configuration/files/ceph.conf.d # ceph config assimilate-conf -i /etc/ceph/ceph.conf [global] fsid = 343ee7d3-232f-4c71-8216-1edbc55ac6e0 mon_health_preluminous_compat = true mon_health_preluminous_compat_warning = false mon_host = 10.58.121.188, 10.58.121.187, 10.58.121.186 mon_initial_membgrs = mon1, mon2, mon3 Task 3: Change the Scrub settings directly in the Configuration DB \u00b6 1). Query the configuration database to see the value of \u201cosd_scrub_auto_repair_num_errors\u201d: You changed this value to \u201c10\u201d in the previous Task. admin:~ # ceph config get osd.* osd_scrub_auto_repair_num_errors 10 2). Change the value of \u201cosd_scrub_auto_repair_num_errors\u201d to \u201c8\u201d: admin:~ # ceph config set osd.* osd_scrub_auto_repair_num_errors 8 3). Show that the change has taken immediate effect by re-running the same command that was used in the first step: admin:~ # ceph config get osd.* osd_scrub_auto_repair_num_errors 8 Task 4: Manually scrub and repair an OSD and a PG \u00b6 This won\u2019t do much in this demo environment, because the OSDs aren\u2019t storing very much data. But it\u2019s worth having some practice. 1). Start a scrubbing of one of the OSDs: admin:~ # ceph osd scrub osd.1 instructed osd(s) 1 to scrub 2). Scrub a Placement Group: admin:~ # ceph pg scrub 8.1 instructing pg 8.1 on osd.0 to scrub 3). Repair an OSD: admin:~ # ceph osd repair osd.1 instructed osd(s) 1 to repair 4). Repair a PG: admin:~ # ceph pg repair 8.1 instructing pg 8.1 on osd.0 to repair 5). Show what\u2019s currently happening to the OSD that you instructed to have scrubbed and repaired: admin:~ # ceph osd dump | grep osd.1 max_osd 12 osd.1 up in weight 1 up_from 10 up_thru 1415 down_at 0 last_clean_interval [0,0) v1:10.58.121.185:6800/11157 v1:10.58.121.185:6801/11157 exists,up 32c78078-1878-4fac-9738-00d8bf80deea osd.10 up in weight 1 up_from 18 up_thru 1413 down_at 0 last_clean_interval [0,0) v1:10.58.121.182:6808/11130 v1:10.58.121.182:6809/11130 exists,up 6cb26fdc-09b1-42de-8855-7203931a0101 osd.11 up in weight 1 up_from 18 up_thru 1415 down_at 0 last_clean_interval [0,0) v1:10.58.121.185:6808/11995 v1:10.58.121.185:6809/11995 exists,up cc22107d-0239-4874-8308-6c137c8a0931 6). Show what\u2019s currently happening to the PG that you instructed to have scrubbed and repaired: admin:~ # ceph pg dump | grep \"8\\.1\" dumped all 8.16 0 0 0 0 0 0 0 0 0 0 active+clean 2021-01-05 21:01:16.383909 0'0 1423:27 [6,4,5] 6 [6,4,5] 6 0'0 2021-01-05 20:53:47.314062 0'0 2021-01-05 20:53:47.314062 0 8.17 0 0 0 0 0 0 0 0 0 0 active+clean 2021-01-05 22:57:01.044252 0'0 1424:30 [1,6,8] 1 [1,6,8] 1 0'0 2021-01-05 22:57:01.044098 0'0 2021-01-05 22:57:01.044098 0 8.14 0 0 0 0 0 0 0 0 0 0 active+clean 2021-01-05 22:56:56.081480 0'0 1424:30 [1,2,4] 1 [1,2,4] 1 0'0 2021-01-05 22:56:56.081356 0'0 2021-01-05 22:56:56.081356 0 8.15 0 0 0 0 0 0 0 0 0 0 active+clean 2021-01-05 21:01:16.375386 0'0 1423:27 [3,5,0] 3 [3,5,0] 3 0'0 2021-01-05 20:53:53.231124 0'0 2021-01-05 20:48:05.301705 0 8.12 0 0 0 0 0 0 0 0 0 0 active+clean 2021-01-05 21:01:16.370121 0'0 1423:27 [11,2,8] 11 [11,2,8] 11 0'0 2021-01-05 20:53:48.149449 0'0 2021-01-05 20:48:05.301705 0 2.18 0 0 0 0 0 0 0 0 0 0 active+clean 2021-01-05 16:44:58.986205 0'0 1423:1630 [10,1,8] 10 [10,1,8] 10 0'0 2021-01-05 13:02:00.365382 0'0 2021-01-02 00:38:58.134100 0 8.13 0 0 0 0 0 0 0 0 0 0 active+clean 2021-01-05 21:01:16.387832 0'0 1423:27 [0,8,1] 0 [0,8,1] 0 0'0 2021-01-05 20:53:56.132358 0'0 2021-01-05 20:48:05.301705 0 8.10 0 0 0 0 0 0 0 0 0 0 active+clean 2021-01-05 21:01:16.368416 0'0 1423:27 [11,3,6] 11 [11,3,6] 11 0'0 2021-01-05 20:53:51.152790 0'0 2021-01-05 20:48:05.301705 0 8.11 0 0 0 0 0 0 0 0 0 0 active+clean 2021-01-05 21:01:16.377871 0'0 1423:24 [3,10,5] 3 [3,10,5] 3 0'0 2021-01-05 20:53:45.195257 0'0 2021-01-05 20:48:05.301705 0 8.1e 0 0 0 0 0 0 0 0 0 0 active+clean 2021-01-05 21:01:16.391754 0'0 1423:47 [0,11,8] 0 [0,11,8] 0 0'0 2021-01-05 20:53:55.081582 0'0 2021-01-05 20:48:05.301705 0 8.1 0 0 0 0 0 0 0 0 0 0 active+clean 2021-01-05 22:56:39.829397 0'0 1424:54 [0,7,10] 0 [0,7,10] 0 0'0 2021-01-05 22:56:39.829241 0'0 2021-01-05 22:56:39.829241 0 8.1f 0 0 0 0 0 0 0 0 0 0 active+clean 2021-01-05 21:01:16.392315 0'0 1423:27 [7,5,9] 7 [7,5,9] 7 0'0 2021-01-05 20:53:59.988252 0'0 2021-01-05 20:48:05.301705 0 5.4 0 0 0 0 0 0 0 0 0 0 active+clean 2021-01-05 18:21:28.179266 0'0 1423:1554 [7,9,6] 7 [7,9,6] 7 0'0 2021-01-05 18:21:28.179166 0'0 2021-01-05 18:21:28.179166 0 5.b 0 0 0 0 0 0 0 0 0 0 active+clean 2021-01-05 18:37:01.467457 0'0 1423:1547 [2,0,11] 2 [2,0,11] 2 0'0 2021-01-04 23:46:58.132824 0'0 2021-01-02 03:35:41.214192 0 8.19 0 0 0 0 0 0 0 0 0 0 active+clean 2021-01-05 22:57:06.059090 0'0 1424:30 [1,8,2] 1 [1,8,2] 1 0'0 2021-01-05 22:57:06.058935 0'0 2021-01-05 22:57:06.058935 0 8.18 0 0 0 0 0 0 0 0 0 0 active+clean 2021-01-05 22:57:05.097742 0'0 1424:30 [1,3,6] 1 [1,3,6] 1 0'0 2021-01-05 22:57:05.097670 0'0 2021-01-05 22:57:05.097670 0 1.11 0 0 0 0 0 0 0 0 0 0 active+clean 2021-01-05 00:30:18.193988 0'0 1423:1605 [0,8,6] 0 [0,8,6] 0 0'0 2021-01-05 00:30:18.193868 0'0 2020-12-29 06:30:58.897565 0 8.1b 0 0 0 0 0 0 0 0 0 0 active+clean 2021-01-05 22:57:13.146469 0'0 1424:30 [1,4,6] 1 [1,4,6] 1 0'0 2021-01-05 22:57:13.146390 0'0 2021-01-05 22:57:13.146390 0 8.1a 1 0 0 0 0 19 0 0 2 2 active+clean 2021-01-05 21:01:16.386166 1420'2 1423:29 [9,11,10] 9 [9,11,10] 9 0'0 2021-01-05 20:53:48.690239 0'0 2021-01-05 20:48:05.301705 0 8.1d 0 0 0 0 0 0 0 0 0 0 active+clean 2021-01-05 21:01:16.388079 0'0 1423:56 [0,2,3] 0 [0,2,3] 0 0'0 2021-01-05 20:53:54.121281 0'0 2021-01-05 20:48:05.301705 0 8.1c 0 0 0 0 0 0 0 0 0 0 active+clean 2021-01-05 21:01:16.385846 0'0 1423:27 [2,11,7] 2 [2,11,7] 2 0'0 2021-01-05 20:53:55.458714 0'0 2021-01-05 20:48:05.301705 0 2.2.5. Manipulate Manager Modules \u00b6 Task 1: Display the list of enabled Manager Modules \u00b6 1). Run the following command to show the list of enabled manager modules: Note that several modules are already enabled, such as: dashboard, iostat, pg_autosclater, prometheus, and restful. Even though they are not listed, the crash module and the balancer module are already enabled by default. admin:~ # ceph mgr module ls | head { \"always_on_modules\": [ \"balancer\", \"crash\", \"devicehealth\", \"orchestrator_cli\", \"progress\", \"rbd_support\", \"status\", \"volumes\" 2). Demonstrate that the crash module is enabled by running its command with no arguments: A list of \u201c7 closest matches\u201d is displayed, representing possible additional arguments to be used with the crash command. The crash module is therefore available. admin:~ # ceph crash crash info crash ls crash ls-new crash post crash prune crash rm crash stat crash json_report crash archive crash archive-all admin:~ # ceph crash stat 0 crashes recorded Task 2: Use the iostat module to display statistics for the IO of the cluster The iostat module is really simple, but very helpful. Run the command: admin:~ # ceph iostat +-----------------------------+-----------------------------+-----------------------------+-----------------------------+-----------------------------+-----------------------------+ | Read | Write | Total | Read IOPS | Write IOPS | Total IOPS | +-----------------------------+-----------------------------+-----------------------------+-----------------------------+-----------------------------+-----------------------------+ | 1024 B/s | 0 B/s | 1024 B/s | 1 | 0 | 1 | | 1024 B/s | 0 B/s | 1024 B/s | 1 | 0 | 1 | | 0 B/s | 0 B/s | 0 B/s | 0 | 0 | 0 | Task 3: Enable and configure the telemetry manager module 1). Enable the telemetry manager module: admin:~ # ceph mgr module enable telemetry 2). Show the various sub-commands that are associated with the telemetry command: A list of \u201c5 closest matches\u201d is displayed, showing various options. admin:~ # ceph telemetry telemetry status telemetry send {ceph|device [ceph|device...]} {} telemetry show { [...]} telemetry show-device telemetry on {} telemetry off 3). Show the status of the telemetry module: Notice that the output is returned as key/value pairs. Notice also that although the module has been enabled (which you accomplished in the first step of this task), the functionality is not enabled (enable=false). And for most of the keys, a null value is set. See that the url value is set to https://telemetry.ceph.com/report. That means that crash reports and other usage information about this cluster are going to be sent to the Ceph Community. admin:~ # ceph telemetry status { \"url\": \"https://telemetry.ceph.com/report\", \"device_url\": \"https://telemetry.ceph.com/device\", \"enabled\": false, \"last_opt_revision\": 1, \"leaderboard\": false, \"description\": null, \"contact\": null, \"organization\": null, \"proxy\": null, \"interval\": 24, \"channel_basic\": true, \"channel_ident\": false, \"channel_crash\": true, \"channel_device\": true, \"last_upload\": null } 4). Set the description, contact, and organization values: admin:~ # ceph config set mgr mgr/telemetry/contact 'JD ' admin:~ # ceph config set mgr mgr/telemetry/description 'Training Cluster' admin:~ # ceph config set mgr mgr/telemetry/organization 'SUSE Training' 5). Display the telemetry data that is collected to be sent: admin:~ # ceph telemetry show | less 6). With the contact information properly set, enable the telemetry functionality: This is a demo cluster with no connection to the internet, so no telemetry data will actually be sent. admin:~ # ceph telemetry on Error EPERM: Telemetry data is licensed under the Community Data License Agreement - Sharing - Version 1.0 (https://cdla.io/sharing-1-0/). To enable, add '--license sharing-1-0' to the 'ceph telemetry on' command. admin:~ # ceph telemetry on --license sharing-1-0 7). Disable the telemetry module: admin:~ # ceph mgr module disable telemetry admin:~ # ceph telemetry show | less Error ENOTSUP: Module 'telemetry' is not enabled (required by command 'telemetry show'): use `ceph mgr module enable telemetry` to enable it Task 4: Briefly attempt to use the crash manager module \u00b6 1). Show (again) the various sub-commands that are associated with the crash command: admin:~ # ceph crash crash info crash ls crash ls-new crash post crash prune crash rm crash stat crash json_report crash archive crash archive-all 2). Show the current status of the crash database, including the numbgr of crash reports that have been collected so far: It\u2019s likely that the numbgr of crashes recorded in the demo environment is 0. admin:~ # ceph crash stat 0 crashes recorded 2.2.6. Introduction to the Tell command \u00b6 Tell is a very powerful command within Ceph to control the cluster. You don\u2019t use it everyday, but you need to know how to use it when the occasion to use it arises. It\u2019s mostly an Advanced Command, but exposure to it now reduces the stress of learning about it in a more advanced setting later. Run the tell command in a few different circumstances to control the behavior of various Ceph services. Task 1: Run a benchmark test on an OSD \u00b6 1). Run the following command to run and see the result of a benchmark test on osd.8: admin:~ # ceph tell osd.8 bench { \"bytes_written\": 1073741824, \"blocksize\": 4194304, \"elapsed_sec\": 3.7797023200000002, \"bytes_per_sec\": 284081055.35676152, \"iops\": 67.730201567831401 } Task 2: Change the protection setting regarding the deletion of pools \u00b6 1). The default behavior in Ceph is that you can\u2019t delete pools. Try to delete a pool: The output says that you have to be VERY careful and provide more arguments in order to delete a pool admin:~ # ceph osd pool delete rbd_pool Error EPERM: WARNING: this will *PERMANENTLY DESTROY* all data stored in pool rbd_pool. If you are *ABSOLUTELY CERTAIN* that is what you want, pass the pool name *twice*, followed by --yes-i-really-really-mean-it. 2). Try deleting the pool again, this time with the extra arguments: Ceph still won\u2019t let you do it because the mon allow pool delete setting has the value of false. admin:~ # ceph osd pool delete rbd_pool rbd_pool --yes-i-really-really-mean-it Error EPERM: pool deletion is disabled; you must first set the mon_allow_pool_delete config option to true before you can destroy a pool 3). Show that the mon allow pool delete setting has the value of false: Indeed, the output shows that the value is false. admin:~ # ceph config get mon.mon\\* mon_allow_pool_delete false 4). Change to value of the setting using injectargs: Note that the \u201c-\u201d and \u201c_\u201d characters can be confusing. And note that the setting is preceded with the double \u201c--\u201d. The injected args must be enclosed in single quotes. You could have done this with ceph config set, but this is an alternative way to directly \u201ctell\u201d the cluster to change a setting. admin:~ # ceph tell mon.\\* injectargs '--mon-allow-pool-delete=true' mon.mon1: injectargs:mon_allow_pool_delete = 'true' mon.mon2: injectargs:mon_allow_pool_delete = 'true' mon.mon3: injectargs:mon_allow_pool_delete = 'true' 2.3. Ceph Dashboard \u00b6 2.3.1. Access Dashboard \u00b6 Task 1: Set the password for the admin user of the Ceph Dashboard \u00b6 1). In a Bash terminal as the root user, show that the Dashboard module is enabled: \u201cdashboard\u201d should be included in the list of \u201cenabled_modules\u201d at the top of the output. admin:~ # ceph mgr module ls | more \"enabled_modules\": [ \"dashboard\", \"iostat\", \"pg_autoscaler\", \"prometheus\", \"restful\" ], 2). Show the valid dashboard users that have already been created by DeepSea during initial deployment: It\u2019s possible that other users will be listed, but at least the \u201cadmin\u201d user should be displayed in the output. admin:~ # ceph dashboard ac-user-show [\"admin\"] 3). Show the \u201cadmin\u201d user\u2019s information as stored in the user database: You can see that the admin user has a password set, but it is stored as a hash. So you don\u2019t really know what the password is, and have no way of discovering it. admin:~ # ceph dashboard ac-user-show admin {\"username\": \"admin\", \"password\": , \"roles\": [\"administrator\"], \"name\": null, \"email\": null, \"lastUpdate\": 1601874928} 4). Change the \u201cadmin\u201d user\u2019s password for the dashboard: This sets the \u201cadmin\u201d user\u2019s password to the string: mypassword admin:~ # ceph dashboard ac-user-set-password admin mypassword {\"username\": \"admin\", \"password\": , \"roles\": [\"administrator\"], \"name\": null, \"email\": null, \"lastUpdate\": 1609860842} admin:~ # Task 3: Visit the Ceph Dashboard URL \u00b6 admin:~ # salt-call grains.get dashboard_creds local: ---------- admin: admin:~ # ceph mgr services { \"dashboard\": \"https://mon1.sha.me.corp:8443/\", \"prometheus\": \"http://mon1.sha.me.corp:9283/\" } admin:~ # ceph -s cluster: id: 343ee7d3-232f-4c71-8216-1edbc55ac6e0 health: HEALTH_WARN 1 subtrees have overcommitted pool target_size_bytes services: mon: 3 daemons, quorum mon1,mon2,mon3 (age 9w) mgr: mon1(active, since 25m) mds: cephfs:1 {0=mon3=up:active} 2 up:standby osd: 12 osds: 12 up (since 5h), 12 in (since 3M) rgw: 1 daemon active (mon3) task status: scrub status: mds.mon3: idle data: pools: 9 pools, 244 pgs objects: 247 objects, 5.7 KiB usage: 14 GiB used, 82 GiB / 96 GiB avail pgs: 244 active+clean io: client: 1.2 KiB/s rd, 1 op/s rd, 0 op/s wr URL: https://mon1.sha.me.corp:8443/ https://10.58.121.186:8443 2.3.2. Explore the Dashboard Health, Performance, Status \u00b6 Dashboard Status Cluster Status Monitors OSDs Manager Daemons Hosts Object Gateway Metadata Service iSCSI Gateway Performance Client IOPS Client Throughput Client Read/Write Recovery Throughput Scrub Capacity Pools Raw Capacity Objects PGs per OSD PG Status [SUSE Enterprise Storage Portal Cluster\u2192Configuration Cluster\u2192Manager Modules Pools\u2192Create Pool 2.4. Storage Data Access \u00b6 2.4.1. Ensure the SES Cluster is Healthy \u00b6 Task 1: Check the Cluster\u2019s health \u00b6 1). Run the following command to check the status (health) of the SES cluster: admin:~ # ceph -s cluster: id: 343ee7d3-232f-4c71-8216-1edbc55ac6e0 health: HEALTH_WARN 1 subtrees have overcommitted pool target_size_bytes 1 pools have too few placement groups services: mon: 3 daemons, quorum mon1,mon2,mon3 (age 9w) mgr: mon1(active, since 18h) mds: cephfs:1 {0=mon3=up:active} 2 up:standby osd: 12 osds: 12 up (since 23h), 12 in (since 3M) rgw: 1 daemon active (mon3) task status: scrub status: mds.mon3: idle data: pools: 10 pools, 248 pgs objects: 247 objects, 5.7 KiB usage: 14 GiB used, 82 GiB / 96 GiB avail pgs: 248 active+clean io: client: 1.2 KiB/s rd, 1 op/s rd, 0 op/s wr 2). Evaluate the output. The cluster in this demonstration environment often doesn\u2019t startup correctly due to the nature of a demo environment and it\u2019s less-predictable resources. Depending on whether any of the following tasks are necessary, followup accordingly to ensure that the cluster is healthy before proceeding with the course lectures or any further exercises. 3). Run the following series of commands to restart the Monitor daemons on each of the Monitor nodes: It\u2019s certainly not necessary to restart the monitor daemons on all of the monitor nodes if only one is down. If you prefer, you can take a different approach to starting the daemon on a single monitor node. admin:~ # for h in mon1 mon2 mon3; \\ do \\ ssh $h systemctl restart ceph-mon@$h; \\ done 4). After waiting a few moments for the daemons to restart, check the status again: admin:~ # ceph -s cluster: id: 343ee7d3-232f-4c71-8216-1edbc55ac6e0 health: HEALTH_WARN 1 subtrees have overcommitted pool target_size_bytes 1 pools have too few placement groups services: mon: 3 daemons, quorum mon1,mon2,mon3 (age 15s) mgr: mon1(active, since 21h) mds: cephfs:1 {0=mon3=up:active} 2 up:standby osd: 12 osds: 12 up (since 26h), 12 in (since 3M) rgw: 1 daemon active (mon3) task status: scrub status: mds.mon3: idle data: pools: 10 pools, 248 pgs objects: 247 objects, 5.7 KiB usage: 14 GiB used, 82 GiB / 96 GiB avail pgs: 248 active+clean io: client: 767 B/s rd, 0 op/s rd, 0 op/s wr 5). Run the following series of commands to restart the Manager daemons on each of the Monitor nodes: admin:~ # for h in mon1 mon2 mon3; \\ do \\ ssh $h systemctl restart ceph-mgr@$h; \\ done 6). After waiting a few moments for the daemons to restart, check the status again: admin:~ # ceph -s cluster: id: 343ee7d3-232f-4c71-8216-1edbc55ac6e0 health: HEALTH_OK services: mon: 3 daemons, quorum mon1,mon2,mon3 (age 8m) mgr: mon1(active, since 18s) mds: cephfs:1 {0=mon3=up:active} 2 up:standby osd: 12 osds: 12 up (since 26h), 12 in (since 3M) rgw: 1 daemon active (mon3) task status: scrub status: mds.mon3: idle data: pools: 10 pools, 248 pgs objects: 247 objects, 6.1 KiB usage: 14 GiB used, 82 GiB / 96 GiB avail pgs: 248 active+clean io: client: 852 B/s rd, 0 op/s rd, 0 op/s wr 7). Run the following command to restart the MDS daemon on the MDS node (mon1): admin:~ # ssh mon1 systemctl restart ceph-mds@mon1.service 8). After waiting a few moments for the mds daemon to restart, check the status again: Look for the mds service to be plain active rather than laggy or crashed admin:~ # ceph -s cluster: id: 343ee7d3-232f-4c71-8216-1edbc55ac6e0 health: HEALTH_WARN 1 subtrees have overcommitted pool target_size_bytes 1 pools have too few placement groups services: mon: 3 daemons, quorum mon1,mon2,mon3 (age 17m) mgr: mon1(active, since 8m) mds: cephfs:1 {0=mon3=up:active} 2 up:standby osd: 12 osds: 12 up (since 26h), 12 in (since 3M) rgw: 1 daemon active (mon3) task status: scrub status: mds.mon3: idle data: pools: 10 pools, 248 pgs objects: 247 objects, 6.2 KiB usage: 14 GiB used, 82 GiB / 96 GiB avail pgs: 248 active+clean io: client: 852 B/s rd, 0 op/s rd, 0 op/s wr 9). Verify if the OSDs \u201cup\u201d and running properly. It is only necessary if the output of ceph -s shows that there are fewer than 9 OSDs shown as being \u201cup\u201d. It\u2019s most likely that a storage node is simply not quite fully booted yet, such that the OSD daemons haven\u2019t fully come up. But if you suspect that the solution requires something different than simply waiting a little longer, you should try the following steps. First, identify which server is hosting the down\u2019d OSDs. One way of doing that is with this command: admin:~ # ceph osd tree ID CLASS WEIGHT TYPE NAME STATUS REWEIGHT PRI-AFF -1 0.09357 root default -9 0.02339 host data1 2 hdd 0.00780 osd.2 up 1.00000 1.00000 6 hdd 0.00780 osd.6 up 1.00000 1.00000 10 hdd 0.00780 osd.10 up 1.00000 1.00000 -3 0.02339 host data2 0 hdd 0.00780 osd.0 up 1.00000 1.00000 4 hdd 0.00780 osd.4 up 1.00000 1.00000 9 hdd 0.00780 osd.9 up 1.00000 1.00000 -7 0.02339 host data3 3 hdd 0.00780 osd.3 up 1.00000 1.00000 7 hdd 0.00780 osd.7 up 1.00000 1.00000 8 hdd 0.00780 osd.8 up 1.00000 1.00000 -5 0.02339 host data4 1 hdd 0.00780 osd.1 up 1.00000 1.00000 5 hdd 0.00780 osd.5 up 1.00000 1.00000 11 hdd 0.00780 osd.11 up 1.00000 1.00000 Simply try restarting the storage daemon processes on the affected host, such as with this example: admin:~ # ssh data2 systemctl restart ceph-osd@9.service admin:~ # ceph -s cluster: id: 343ee7d3-232f-4c71-8216-1edbc55ac6e0 health: HEALTH_WARN 1 subtrees have overcommitted pool target_size_bytes 1 pools have too few placement groups services: mon: 3 daemons, quorum mon1,mon2,mon3 (age 32m) mgr: mon1(active, since 24m) mds: cephfs:1 {0=mon3=up:active} 2 up:standby osd: 12 osds: 12 up (since 27s), 12 in (since 3M) rgw: 1 daemon active (mon3) task status: scrub status: mds.mon3: idle data: pools: 10 pools, 248 pgs objects: 247 objects, 6.2 KiB usage: 14 GiB used, 82 GiB / 96 GiB avail pgs: 248 active+clean io: client: 852 B/s rd, 0 op/s rd, 0 op/s wr If the OSD daemon processes are being stubborn and uncooperative, you may choose to reboot the storage virtual machine entirely. This is one way to do that: admin:~ # ssh data1 systemctl reboot After waiting some time for the daemons to get started, verify that all the OSDs are \u201cup\u201d and that the cluster is healthy: admin:~ # ceph osd tree admin:~ # ceph status 10). Run the following command to restart the RADOS Gateway daemon on the node that is hosting the gateway (mon3): admin:~ # ssh mon3 systemctl restart ceph-radosgw@rgw.mon3.service admin:~ # ssh mon3 systemctl status ceph-radosgw@rgw.mon3.service \u25cf ceph-radosgw@rgw.mon3.service - Ceph rados gateway Loaded: loaded (/usr/lib/systemd/system/ceph-radosgw@.service; enabled; vendor preset: disabled) Active: active (running) since Wed 2021-01-06 21:37:53 CST; 23s ago Main PID: 781880 (radosgw) Tasks: 588 CGroup: /system.slice/system-ceph\\x2dradosgw.slice/ceph-radosgw@rgw.mon3.service \u2514\u2500781880 /usr/bin/radosgw -f --cluster ceph --name client.rgw.mon3 --setuser ceph --setgroup ceph Jan 06 21:37:53 mon3 systemd[1]: Started Ceph rados gateway. 11). After waiting a few moments for the daemon to restart, check the status again: admin:~ # ceph -s cluster: id: 343ee7d3-232f-4c71-8216-1edbc55ac6e0 health: HEALTH_WARN 1 subtrees have overcommitted pool target_size_bytes 1 pools have too few placement groups services: mon: 3 daemons, quorum mon1,mon2,mon3 (age 39m) mgr: mon1(active, since 30m) mds: cephfs:1 {0=mon3=up:active} 2 up:standby osd: 12 osds: 12 up (since 6m), 12 in (since 3M) rgw: 1 daemon active (mon3) task status: scrub status: mds.mon3: idle data: pools: 10 pools, 248 pgs objects: 247 objects, 6.2 KiB usage: 14 GiB used, 82 GiB / 96 GiB avail pgs: 248 active+clean io: client: 1.2 KiB/s rd, 1 op/s rd, 0 op/s wr 2.4.2. Use the S3 API to Interact with the RADOS Gateway \u00b6 In this lab we used the s3cmd and radosgw-admin utilities to interact with the SUSE Enterprise Storage cluster. We created a new user, a new bucket, and a new file. We then uploaded the file to the cluster and verified that the object gateway stored it to the cluster. Task 1: Using the s3cmd tool and create an S3 user \u00b6 1). As the root user (password is linux) in a shell or terminal, verify that the s3cmd is available on the admin node: You will likely see an error about configuration files missing, etc. This is enough information to validate the utility is installed. admin:~ # pip --version pip 10.0.1 from /usr/lib/python3.6/site-packages/pip (python 3.6) admin:~ # pip install s3cmd Collecting s3cmd Downloading https://files.pythonhosted.org/packages/26/44/19e08f69b2169003f7307565f19449d997895251c6a6566ce21d5d636435/s3cmd-2.1.0-py2.py3-none-any.whl (145kB) 100% | 153kB 2.7MB/s Collecting python-magic (from s3cmd) Downloading https://files.pythonhosted.org/packages/59/77/c76dc35249df428ce2c38a3196e2b2e8f9d2f847a8ca1d4d7a3973c28601/python_magic-0.4.18-py2.py3-none-any.whl Requirement already satisfied: python-dateutil in /usr/lib/python3.6/site-packages (from s3cmd) (2.7.3) Requirement already satisfied: six>=1.5 in /usr/lib/python3.6/site-packages (from python-dateutil->s3cmd) (1.11.0) Installing collected packages: python-magic, s3cmd Successfully installed python-magic-0.4.18 s3cmd-2.1.0 2). Create a new S3 user to be used: The output will include an access_key value and a secret_key value. You will need both of those values in later steps. admin:~ # radosgw-admin user create --uid=s3user --display-name=S3 User --email=s3user@example.net { \"user_id\": \"s3user\", \"display_name\": \"S3\", \"email\": \"s3user@example.net\", \"suspended\": 0, \"max_buckets\": 1000, \"subusers\": [], \"keys\": [ { \"user\": \"s3user\", \"access_key\": , \"secret_key\": } ], \"swift_keys\": [], \"caps\": [], \"op_mask\": \"read, write, delete\", \"default_placement\": \"\", \"default_storage_class\": \"\", \"placement_tags\": [], \"bucket_quota\": { \"enabled\": false, \"check_on_raw\": false, \"max_size\": -1, \"max_size_kb\": 0, \"max_objects\": -1 }, \"user_quota\": { \"enabled\": false, \"check_on_raw\": false, \"max_size\": -1, \"max_size_kb\": 0, \"max_objects\": -1 }, \"temp_url_keys\": [], \"type\": \"rgw\", \"mfa_ids\": [] } Retrieve above information admin:~ # radosgw-admin user info --uid=s3user Task 2: Create a new s3cmd configuration file and a new S3 bucket \u00b6 1). Generate a new s3cmd configuration file from a shell on the admin node: Fill in as listed below: admin:~ # cd ~ admin:~ # s3cmd --configure Enter new values or accept defaults in brackets with Enter. Refer to user manual for detailed description of all options. Access key and Secret key are your identifiers for Amazon S3. Leave them empty for using the env variables. Access Key: Secret Key: Default Region [US]: Use \"s3.amazonaws.com\" for S3 Endpoint and not modify it to the target Amazon S3. S3 Endpoint [s3.amazonaws.com]: mon3.sha.me.corp Use \"%(bucket)s.s3.amazonaws.com\" to the target Amazon S3. \"%(bucket)s\" and \"%(location)s\" vars can be used if the target S3 system supports dns based buckets. DNS-style bucket+hostname:port template for accessing a bucket [%(bucket)s.s3.amazonaws.com]: %(bucket)s.mon3.sha.me.corp Encryption password is used to protect your files from reading by unauthorized persons while in transfer to S3 Encryption password: Path to GPG program [/usr/bin/gpg]: When using secure HTTPS protocol all communication with Amazon S3 servers is protected from 3 rd party eavesdropping. This method is slower than plain HTTP, and can only be proxied with Python 2.7 or newer Use HTTPS protocol [Yes]: No On some networks all internet access must go through a HTTP proxy. Try setting it here if you can't connect to S3 directly HTTP Proxy server name: New settings: Access Key: Secret Key: Default Region: US S3 Endpoint: mon3.sha.me.corp DNS-style bucket+hostname:port template for accessing a bucket: %(bucket)s.mon3.sha.me.corp Encryption password: Path to GPG program: /usr/bin/gpg Use HTTPS protocol: False HTTP Proxy server name: HTTP Proxy server port: 0 Test access with supplied credentials? [Y/n] n Save settings? [y/N] y Configuration saved to '/root/.s3cfg' 2). Test the configuration by checking for existing files or directories: Since no buckets or files have been made available for the user, no items are listed and the command returns you to the prompt with no output. This is normal. If there is an error, your configuration may have a typo in it. The configuration file will have been saved as .s3cfg. Edit the file to match the configuration in step one. admin:~ # s3cmd ls 3). Create a new bucket for uploading files to using the s3cmd: You should see feedback that the bucket has been created. Although not technically required by the S3 API, the bucket name needs to be in all uppercase to avoid a bug with the s3cmd tool itself. admin:~ # s3cmd mb s3://S3CMDTEST Bucket 's3://S3CMDTEST/' created admin:~ # s3cmd ls 2021-01-06 14:04 s3://S3CMDTEST (it's GMT timezone) Task3: Create and upload a file to a bucket using the S3 API \u00b6 1). Create a file with a few words of text: admin:~ # echo \"The mountains are beautiful\" > newfile 2). Put the new file into your bucket using s3cmd: You should see the file being uploaded. admin:~ # s3cmd put newfile s3://S3CMDTEST upload: 'newfile' -> 's3://S3CMDTEST/newfile' [1 of 1] 28 of 28 100% in 3s 7.66 B/s done 3). Verify the file is now in your bucket, safely stored in you SES cluster: admin:~ # s3cmd ls s3://S3CMDTEST 2021-01-06 14:11 28 s3://S3CMDTEST/newfile 2.4.3. Use the swift API to Interact with the RADOS Gateway \u00b6 OpenStack packages for SUSE Install and configure the storage nodes for openSUSE and SUSE Linux Enterprise SUSE Package Hub: python-PasteDeploy Enable SUSE Package Hub extension admin:~ # SUSEConnect -p PackageHub/15.1/x86_64 Install python3-PasteDeploy, which is dependency of python-swift installation admin:~ # zypper in python3-PasteDeploy admin:~ # rpm -ivh python3-PyECLib-1.6.0-1.6.x86_64.rpm warning: python3-PyECLib-1.6.0-1.6.x86_64.rpm: Header V3 RSA/SHA256 Signature, key ID 3dbdc284: NOKEY error: Failed dependencies: python(abi) = 3.8 is needed by python3-PyECLib-1.6.0-1.6.x86_64 rpmlib(PayloadIsZstd) <= 5.4.18-1 is needed by python3-PyECLib-1.6.0-1.6.x86_64 Add OpenStack Swift Repository for SUSE admin:~ # zypper addrepo -f obs://Cloud:OpenStack:Train/SLE_15_SP1 Train admin:~ # zypper in openstack-swift openstack-swift-account openstack-swift-container openstack-swift-object Task 1: Create a swift subuser \u00b6 1). In a shell or terminal as the root user (password of linux) on the admin node, create a new subuser: The output will contain the access and secret keys for the s3user and a secret key for the new swift subuser.. admin:~ # radosgw-admin subuser create --uid=s3user --subuser=s3user:swift --access=full { \"user_id\": \"s3user\", \"display_name\": \"S3\", \"email\": \"s3user@example.net\", \"suspended\": 0, \"max_buckets\": 1000, \"subusers\": [ { \"id\": \"s3user:swift\", \"permissions\": \"full-control\" } ], \"keys\": [ { \"user\": \"s3user\", \"access_key\": , \"secret_key\": } ], \"swift_keys\": [ { \"user\": \"s3user:swift\", \"secret_key\": } ], \"caps\": [], \"op_mask\": \"read, write, delete\", \"default_placement\": \"\", \"default_storage_class\": \"\", \"placement_tags\": [], \"bucket_quota\": { \"enabled\": false, \"check_on_raw\": false, \"max_size\": -1, \"max_size_kb\": 0, \"max_objects\": -1 }, \"user_quota\": { \"enabled\": false, \"check_on_raw\": false, \"max_size\": -1, \"max_size_kb\": 0, \"max_objects\": -1 }, \"temp_url_keys\": [], \"type\": \"rgw\", \"mfa_ids\": [] } 2). Verify that the subuser has access to at least one bucket and list the buckets with a swift command: swift -A http://mon3.sha.me.corp/auth/1.0 -U s3user:swift -K '{SECRET_KEY_FROM_STEP_1}' list admin:~ # swift -A http://mon3.sha.me.corp/auth/1.0 -U s3user:swift -K '' list S3CMDTEST Task 2: Use the swift command to access a file created with the S3cmd tool \u00b6 1). Since the S3 API and the swift API are accessing the same SUSE Enterprise Storage cluster, and since the RADOS gateway is built to be inter-operable with both, you can use the swift API to retrieve the object which was uploaded to SES via the S3 API: swift -A http://mon3.example.net/auth/1.0 -U s3user:swift -K '{SECRET_KEY_FROM_STEP_1}' download -a An example of the command is listed here: admin:~ # swift -A http://mon3.sha.me.corp/auth/1.0 -U s3user:swift -K '' download -a Although we have taken a shortcut by using the -a option (meaning grab every object this user has access to), it illustrates the tool\u2019s capability. We\u2019ve uploaded the newfile with S3, we\u2019ve retrieved it with swift. 2.4.4. Create Snapshots on SES using RBD \u00b6 In this lab we worked with rbd images. We mapped an rbd image to a Linux device file, then created a filesystem and mounted it. Then we created snapshots to preserve the images data state at a particular time, and rolled it back to demonstrate functionality. Task 1: Create a new pool for RBD images \u00b6 1). Access https://mon1.pvg.me.corp:8443 or https://10.58.121.186:8443 2). Log in with the following credentials: Username: admin Password: mypassword 3). Click on the Pools tab near the top of the page 4). Click the Create button and use the following in the available fields: Name: rbd-images Pool type: replicated Placement groups: 16 Crush ruleset: replicated_rule Replicted size: 2 Applications: rbd Compression Mode: none 5). Click Create Pool Task 2: Create a new RBD image in the rbd-images pool \u00b6 6). Create a new RBD image using the rbd command: admin:~ # rbd create --size 1024 rbd-images/barfoo 7). Verify the new image has been created in the rbd-images pool: The new image named barfoo should be displayed. admin:~ # rbd ls -p rbd-images barfoo Task 3: Mount the new image on the admin node and create a filesystem \u00b6 1). As the root user in a shell or terminal on the admin node, map the new rbd image to a block device: admin:~ # rbd map rbd-images/barfoo /dev/rbd0 2). Create a filesystem on the newly mapped device: admin:~ # mkfs.ext4 /dev/rbd0 mke2fs 1.43.8 (1-Jan-2018) Discarding device blocks: done Creating filesystem with 262144 4k blocks and 65536 inodes Filesystem UUID: 19da6b86-1989-4834-a365-2f654fcce6f6 Superblock backups stored on blocks: 32768, 98304, 163840, 229376 Allocating group tables: done Writing inode tables: done Creating journal (8192 blocks): done Writing superblocks and filesystem accounting information: done 3). Mount the image to the /mnt directory: admin:~ # mount /dev/rbd0 /mnt admin:~ # l /mnt total 20 drwxr-xr-x 3 root root 4096 Jan 6 23:48 ./ drwxr-xr-x 1 root root 156 Oct 5 08:53 ../ drwx------ 2 root root 16384 Jan 6 23:48 lost+found/ Task 4: Create a file on the new filesystem and snapshot the rbd image and make some additional changes \u00b6 1). Change to the /mnt directory and create a simple file: admin:~ # cd /mnt admin:/mnt # echo \"This is some sample text\" > start.txt 2). List the directories contents to see that the start.txt file has been created on the storage cluster. admin:/mnt # ls -l total 20 drwx------ 2 root root 16384 Jan 6 23:48 lost+found -rw-r--r-- 1 root root 25 Jan 6 23:50 start.txt 3). Create a snapshot of what the rbd image contained: Wait for confirmation that the snapshot has been created. It should only take a few seconds. admin:/mnt # rbd snap create rbd-images/barfoo@begin 4). List the rbd snapshots for the rbd-images/barfoo image: You should see the new snap called begin listed. admin:/mnt # rbd snap ls rbd-images/barfoo SNAPID NAME SIZE PROTECTED TIMESTAMP 4 begin 1 GiB Wed Jan 6 23:51:12 2021 5). Add another file to the filesystem: admin:/mnt # echo \"Some more text\" > end.txt 6). List the contents of the /mnt to verify the existence of two files. admin:/mnt # ls -l total 24 -rw-r--r-- 1 root root 15 Jan 6 23:52 end.txt drwx------ 2 root root 16384 Jan 6 23:48 lost+found -rw-r--r-- 1 root root 25 Jan 6 23:50 start.txt 7). Create a second snapshot of the rbd-images/barfoo image: admin:/mnt # rbd snap create rbd-images/barfoo@finish 8). List the rbd snapshots: There should be begin and finish snapshots. admin:/mnt # rbd snap ls rbd-images/barfoo SNAPID NAME SIZE PROTECTED TIMESTAMP 4 begin 1 GiB Wed Jan 6 23:51:12 2021 5 finish 1 GiB Wed Jan 6 23:53:15 2021 9). List the contents of the /mnt directory again and verify the two files. 10). Rollback the data to the begin snapshot: This process will be relatively quick because the size of the image is small and we have very little data on it. admin:/mnt # rbd snap rollback rbd-images/barfoo@begin Rolling back to snapshot: 100% complete...done. 11). Change to the root user\u2019s home directory, then remount the image in order to see that the rbd image has been rolled back: admin:/mnt # cd ~ admin:~ # umount /mnt admin:~ # mount /dev/rbd0 /mnt 12). List the contents of the /mnt directory to verify that only the start.txt file exists on the image. admin:/mnt # ls -l total 20 drwx------ 2 root root 16384 Jan 6 23:48 lost+found -rw-r--r-- 1 root root 25 Jan 6 23:50 start.txt 13). Rollback the data to the finish snapshot: admin:/mnt # rbd snap rollback rbd-images/barfoo@finish Rolling back to snapshot: 100% complete...done. 14). Unmount and remount the image: admin:/mnt # cd ~ admin:~ # umount /mnt admin:~ # mount /dev/rbd0 /mnt 15). List the contents of the /mnt directory to show it has indeed been rolled back and contains the start.txt and end.txt files admin:/mnt # ls -l total 24 -rw-r--r-- 1 root root 15 Jan 6 23:52 end.txt drwx------ 2 root root 16384 Jan 6 23:48 lost+found -rw-r--r-- 1 root root 25 Jan 6 23:50 start.txt 16). Change to the root user\u2019s home directory and unmount the image: admin:/mnt # cd ~ admin:~ # umount /mnt 2.4.5. Create and manage COW Clones with rbd \u00b6 In this lab you will created a new pool and block device image in the pool. You then mapped the block storage to a linux device and took a snapshot. Finally you protected the snapshot from modification. This would be done so the snapshot can be safely used as a parent cow image which can then be cloned to create new virtual machines. Task 1: Create a new pool \u00b6 1). View the current osds and pools: admin:~ # ceph osd ls 0 1 2 3 4 5 6 7 8 9 10 11 admin:~ # ceph osd pool ls iscsi-images cephfs_data cephfs_metadata .rgw.root default.rgw.control default.rgw.meta default.rgw.log rbd_pool bucket_pool EC_RBD_Pool default.rgw.buckets.index default.rgw.buckets.data rbd-images 2). Create a new pool called cow-pool: admin:~ # ceph osd pool create cow-pool 128 pool 'cow-pool' created 3). List the available pools to view the new pool using either of the following commands: admin:~ # ceph osd pool ls iscsi-images cephfs_data cephfs_metadata .rgw.root default.rgw.control default.rgw.meta default.rgw.log rbd_pool bucket_pool EC_RBD_Pool default.rgw.buckets.index default.rgw.buckets.data rbd-images cow-pool admin:~ # rados lspools iscsi-images cephfs_data cephfs_metadata .rgw.root default.rgw.control default.rgw.meta default.rgw.log rbd_pool bucket_pool EC_RBD_Pool default.rgw.buckets.index default.rgw.buckets.data rbd-images cow-pool Task 2: Create a block device image in a pool 1). Create a format 2 rbd image called cow-base in the cow-pool storage pool with a size of 1GB *Note that the \u2013image-format statement is optional as format 2 is default admin:~ # rbd create -p cow-pool cow-base --size 1024 --image-format 2 2). Check that the image has been created, that the format is 2 and that layering (COW Clones) is supported admin:~ # rbd -p cow-pool list cow-base admin:~ # rbd -p cow-pool info cow-base rbd image 'cow-base': size 1 GiB in 256 objects order 22 (4 MiB objects) snapshot_count: 0 id: 269d5b817222aa block_name_prefix: rbd_data.269d5b817222aa format: 2 features: layering op_features: flags: create_timestamp: Thu Jan 7 10:12:31 2021 access_timestamp: Thu Jan 7 10:12:31 2021 modify_timestamp: Thu Jan 7 10:12:31 2021 Task 3: Map the block storage image to a Linux host 1). In a shell or terminal as user root open a terminal window. Using the rbd map command, map an rbd device to the block-storage image created above. admin:~ # rbd map -p cow-pool --image cow-base /dev/rbd1 2). View the mapped block devices admin:~ # rbd showmapped id pool namespace image snap device 0 rbd-images barfoo - /dev/rbd0 1 cow-pool cow-base - /dev/rbd1 3). Note the rbd index numbgr (e.g. rbd0, rbd1) associated with the cow-base image: RBD ___1____ 4). View the devices in /dev. Note the device name(s) admin:~ # ls -l /dev/rbd* brw-rw---- 1 root disk 252, 0 Jan 6 23:49 /dev/rbd0 brw-rw---- 1 root disk 252, 16 Jan 7 10:14 /dev/rbd1 /dev/rbd: total 0 drwxr-xr-x 2 root root 60 Jan 7 10:14 cow-pool drwxr-xr-x 2 root root 60 Jan 6 23:48 rbd-images 5). View the block device:(use the device numbgr from step above) admin:~ # fdisk -l /dev/rbd1 Disk /dev/rbd1: 1 GiB, 1073741824 bytes, 2097152 sectors Units: sectors of 1 * 512 = 512 bytes Sector size (logical/physical): 512 bytes / 512 bytes I/O size (minimum/optimal): 4194304 bytes / 4194304 bytes 6). Format the device with an ext4 filesystem: admin:~ # mkfs.ext4 /dev/rbd1 mke2fs 1.43.8 (1-Jan-2018) Discarding device blocks: done Creating filesystem with 262144 4k blocks and 65536 inodes Filesystem UUID: 64c9a973-cf31-4239-881f-ec5642bf34e3 Superblock backups stored on blocks: 32768, 98304, 163840, 229376 Allocating group tables: done Writing inode tables: done Creating journal (8192 blocks): done Writing superblocks and filesystem accounting information: done 7). Mount the block device on the local filesystem: admin:~ # mkdir /mnt/cow-base admin:~ # mount /dev/rbd1 /mnt/cow-base 8). Test the storage access by creating a file: admin:~ # cd /mnt/cow-base admin:/mnt/cow-base # touch base-image-file admin:/mnt/cow-base # ls base-image-file lost+found Task 4: Snapshot the rbd image and protect the snapshot \u00b6 1). List the snapshots in the cow-base image: admin:/mnt/cow-base # rbd snap ls cow-pool/cow-base 2). Create a snapshot of the cow-base rbd image which contains the base-image-file file admin:/mnt/cow-base # rbd snap create cow-pool/cow-base@base-snap 3). List the snapshot: admin:/mnt/cow-base # rbd snap ls cow-pool/cow-base SNAPID NAME SIZE PROTECTED TIMESTAMP 4 base-snap 1 GiB Thu Jan 7 10:37:13 2021 4). This snapshot will form the parent snapshot for COW clone images so you will now protected it from modification: admin:/mnt/cow-base # rbd snap protect cow-pool/cow-base@base-snap admin:/mnt/cow-base # rbd snap ls cow-pool/cow-base SNAPID NAME SIZE PROTECTED TIMESTAMP 4 base-snap 1 GiB yes Thu Jan 7 10:37:13 2021 Task 5: Create writable COW clones from the parent snapshot 1). Create a COW clone from the cow-base with the base-snap snapshot as the parent image admin:/mnt/cow-base # rbd clone cow-pool/cow-base@base-snap cow-pool/cow-image1 2). Check the information for the new image admin:/mnt/cow-base # rbd -p cow-pool --image cow-image1 info rbd image 'cow-image1': size 1 GiB in 256 objects order 22 (4 MiB objects) snapshot_count: 0 id: 26a1209678cad4 block_name_prefix: rbd_data.26a1209678cad4 format: 2 features: layering op_features: flags: create_timestamp: Thu Jan 7 10:38:58 2021 access_timestamp: Thu Jan 7 10:38:58 2021 modify_timestamp: Thu Jan 7 10:38:58 2021 parent: cow-pool/cow-base@base-snap overlap: 1 GiB 3). Note that the image has details of the parent image and overlap 4). Repeat steps 2 & 3 for an additional image called cow-image2 admin:/mnt/cow-base # rbd clone cow-pool/cow-base@base-snap cow-pool/cow-image2 admin:/mnt/cow-base # rbd -p cow-pool --image cow-image2 info rbd image 'cow-image2': size 1 GiB in 256 objects order 22 (4 MiB objects) snapshot_count: 0 id: 26a2fbcec7b8d9 block_name_prefix: rbd_data.26a2fbcec7b8d9 format: 2 features: layering op_features: flags: create_timestamp: Thu Jan 7 10:47:28 2021 access_timestamp: Thu Jan 7 10:47:28 2021 modify_timestamp: Thu Jan 7 10:47:28 2021 parent: cow-pool/cow-base@base-snap overlap: 1 GiB Task 6: Test that the COW clones are functional 1). Create a new directory and mount the COW clone called cow-image1 Note the rbd device name and use it to mount the file system admin:/mnt # mkdir /mnt/cow-image1 admin:/mnt # rbd map -p cow-pool --image cow-image1 /dev/rbd2 admin:/mnt # l total 4 drwxr-xr-x 1 root root 36 Jan 7 10:54 ./ drwxr-xr-x 1 root root 156 Oct 5 08:53 ../ drwxr-xr-x 3 root root 4096 Jan 7 10:19 cow-base/ drwxr-xr-x 1 root root 0 Jan 7 10:54 cow-image1/ admin:/mnt # ls -l /dev/rbd* brw-rw---- 1 root disk 252, 0 Jan 6 23:49 /dev/rbd0 brw-rw---- 1 root disk 252, 16 Jan 7 10:18 /dev/rbd1 brw-rw---- 1 root disk 252, 32 Jan 7 10:55 /dev/rbd2 /dev/rbd: total 0 drwxr-xr-x 2 root root 80 Jan 7 10:55 cow-pool drwxr-xr-x 2 root root 60 Jan 6 23:48 rbd-images admin:/mnt # mount /dev/rbd2 /mnt/cow-image1 2). Check that the base-image-file which was created in the parent snapshot is present admin:/mnt # cd /mnt/cow-image1 admin:/mnt/cow-image1 # ls base-image-file lost+found 3). Repeat steps 1 and 2 for cow-image2 admin:/mnt # mkdir /mnt/cow-image2 admin:/mnt # rbd map -p cow-pool --image cow-image2 /dev/rbd3 admin:/mnt # mount /dev/rbd3 /mnt/cow-image2 admin:/mnt # ls ./cow-image2/ base-image-file lost+found --> same file with image1 4). Create a new file in the directory where cow-image1 is mounted admin:/mnt # cd cow-image1 admin:/mnt/cow-image1 # touch additional-file admin:/mnt/cow-image1 # ls additional-file base-image-file lost+found 5). Look in the cow-image2 directory. Although they share the same parent snapshot, you can see that the files contained in each COW image are now different. admin:/mnt # ls ./cow-image2/ base-image-file lost+found Task 7: Flatten a COW Clone and remove the parent image \u00b6 1). Convert the COW clone called cow-image1 to a standalone rbd image Wait while the flatten process completes. Unlike a clone process this is not instantaneous and can take considerable time. admin:/mnt # rbd flatten cow-pool/cow-image1 Image flatten: 100% complete...done. 2). Check to see that the flatten process has removed the link to the parent snapshot admin:/mnt # rbd -p cow-pool --image cow-image1 info rbd image 'cow-image1': size 1 GiB in 256 objects order 22 (4 MiB objects) snapshot_count: 0 id: 26a1209678cad4 block_name_prefix: rbd_data.26a1209678cad4 format: 2 features: layering op_features: flags: create_timestamp: Thu Jan 7 10:38:58 2021 access_timestamp: Thu Jan 7 10:38:58 2021 modify_timestamp: Thu Jan 7 10:38:58 2021 admin:/mnt # rbd -p cow-pool --image cow-image2 info rbd image 'cow-image2': size 1 GiB in 256 objects order 22 (4 MiB objects) snapshot_count: 0 id: 26a2fbcec7b8d9 block_name_prefix: rbd_data.26a2fbcec7b8d9 format: 2 features: layering op_features: flags: create_timestamp: Thu Jan 7 10:47:28 2021 access_timestamp: Thu Jan 7 10:47:28 2021 modify_timestamp: Thu Jan 7 10:47:28 2021 parent: cow-pool/cow-base@base-snap overlap: 1 GiB 3). Unmount the images admin:/mnt # umount /mnt/cow-image1 admin:/mnt # umount /mnt/cow-image2 admin:/mnt # umount /mnt/cow-base 2.4.6. Configure iSCSI on SES \u00b6 In this lab an iSCSI Target was configured via the iSCSI gateway on our SUSE Enterprise Storage. An image was added to it. An iSCSI initiator then connected to the target, created a filesystem, and mounted it. Task 1: Create a new RBD image in the iscsi-images pool \u00b6 1). Create a new RBD image using the rbd command: admin:~ # rbd create --size 1024 iscsi-images/fooiscsi 2). Verify the new image has been created in the iscsi-images pool: The new image named fooiscsi should be displayed. admin:~ # rbd ls iscsi-images fooiscsi Task 2: Define a new iSCSI target with the Ceph Dashboard \u00b6 1). Access the Ceph Dashboard and log in: https://mon1.pvg.me.corp:8443 or https://10.58.121.186:8443 Username: admin Password: mypassword 2). Once logged in, click on the Block drop-down item near the top. Select iSCSI. 3). With the Overview tab showing for iSCSI, click on the Targets tab near the top. Note: When clicking on the Targets tab, if you see an error that says something about \u201cUnsupported `ceph-iscsi` config version\u2026\u201d, perform the following steps: 1. Close the browser window where the error occurred 2. Restart the mon1 virtual machine. Do this with the following steps: from the Virtual Machine Manager on your lab machine (not in the admin virtual machine), restart the mon1 virtual machine by right-clicking on the mon1 virtual machine > Shut Down > Reboot 3. Wait at least 30 seconds, then from the admin node, open up the browser again and log in to the Ceph Dashboard: https://mon1.pvg.me.corp:8443 or https://10.58.121.186:8443 Username: admin Password: mypassword 4. Continue the lab as directed below by navigating to the Block > iSCSI section, clicking on the Targets tab, and completing the steps below 4). Click Add. Use the following values: Target IQN: Portals: mon2.example.net:172.17.6.132 Images: iscsi-images/fooiscsi ACL authentication: Click Create Target. Task 3: Access the new iSCSI target from the admin node \u00b6 1). On the admin node, launch YaST either the ncurses or GUI interface, and select the iSCSI Initiator module: YaST > Network Services > iSCSI Initiator 2). Select the Discovered Targets tab (alt-v) 3). Select Discovery at the bottom of the frame (alt-d) 4). Add the ip address of mon2: 10.58.121.187. Leave the port as the default of 3260. Select Next. 5). Once again on the Discovered Targets tab, the mon2 target should be listed. With the new target highlighted, select Connect (alt-e) at the bottom of the frame. 6). Leave the Startup (in YaST2) or On boot (in YaST) value as manual. Select Next. 7). Select OK to exit the iscsi client configuration module 8). To verify that the iscsi device is now connected, use the lsscsi command to list devices: You should see there is one disk of type RBD connected on a device file similar to the following: admin:~ # lsscsi [0:0:0:0] cd/dvd QEMU QEMU DVD-ROM 1.4. /dev/sr0 [2:0:0:0] disk SUSE RBD 4.0 /dev/sda 9). Create an ext4 filesystem on the connected device file: admin:~ # mkfs.ext4 /dev/sda mke2fs 1.43.8 (1-Jan-2018) Creating filesystem with 262144 4k blocks and 65536 inodes Filesystem UUID: e3896f7e-0664-4b14-85db-0f77cb234c43 Superblock backups stored on blocks: 32768, 98304, 163840, 229376 Allocating group tables: done Writing inode tables: done Creating journal (8192 blocks): done Writing superblocks and filesystem accounting information: done 10). Mount the device to /mnt: admin:~ # mount /dev/sda /mnt 11). Use the mount command to list the connected device: admin:/mnt # mount | grep sda /dev/sda on /mnt type ext4 (rw,relatime,stripe=1024,data=ordered) 12).Change the root user\u2019s home directory and unmount the device: admin:/mnt # cd .. admin:/ # umount /mnt 2.4.7. Mount CephFS Provided by SUSE Enterprise Storage \u00b6 In this lab a ceph user was configured to mount the ceph filesystem provided by the SUSE Enterprise Cluster. A keyfile was generated, then used in the process. Task 1: Verify cephfs configuration of the SES cluster \u00b6 1). Cephfs requires two pools for operation: one for data, the other for metadata. Verify that the cluster has two pools for this purpose: admin:~ # ceph fs ls name: cephfs, metadata pool: cephfs_metadata, data pools: [cephfs_data ] Task 2: Create a secret key file for the admin user on the admin node 1). Because cephx authentication is enabled by default on SUSE Enterprise Storage, a secret key will need to be provided to allow access to mount the ceph filesystem. The admin user (identified \u2013 in this case \u2013 on the system as root) on the admin node has a key, but we will need to either provide it on the command line during the mount process (less secure), or put it in a permissions-restricted file and point to the file when mounting (more secure). If we do not specify the key or a file with the key, we will get an error. The following command will return an error: admin:~ # mount -t ceph mon1:6789:/ /mnt 2021-01-07 14:16:36.924 7f45108a9d80 -1 auth: unable to find a keyring on /etc/ceph/ceph.client.guest.keyring,/etc/ceph/ceph.keyring,/etc/ceph/keyring,/etc/ceph/keyring.bin,: (2) No such file or directory mount error 22 = Invalid argument 2). Take secret key value found in the /etc/ceph/ceph.client.admin.keyring file and put it in a new file: admin:~ # cat /etc/ceph/ceph.client.admin.keyring [client.admin] key = caps mds = \"allow *\" caps mon = \"allow *\" caps osd = \"allow *\" caps mgr = \"allow *\" 3). Create a new file and paste the secret key value into it: admin:~ # vi /etc/ceph/admin.secret Put the key value into the file and save it. 4). Change the permissions of the file to be read only by the user: admin:~ # ls -l /etc/ceph/admin.secret -r-------- 1 root root 41 Jan 5 20:05 /etc/ceph/admin.secret Task 3: Mount the ceph filesystem on the admin node \u00b6 1). Now that the keyfile is created, we can mount the filesystem: admin:~ # mount -t ceph mon1:6789:/ /mnt -o name=admin,secretfile=/etc/ceph/admin.secret admin:~ # ls -l /mnt total 0 2). Verify that the mount shows as expected: admin:~ # mount | grep ceph 10.58.121.186:6789:/ on /mnt type ceph (rw,relatime,name=admin,secret=,acl) 3). Change to the root user\u2019s home directory and unmount the filesystem: admin:~ # cd ~ admin:~ # umount /mnt 2.4.8. Export an NFS Share from SES with NFS Ganesha \u00b6 Task 0: Install and configure Ganesha (Ganesha config location is not configured. Please set the GANESHA_RADOS_POOL_NAMESPACE setting.) \u00b6 admin:~ # zypper in nfs-ganesha admin:/etc/ganesha # cat ganesha.conf NFSv4 { RecoveryBackend = 'rados_cluster'; #RecoveryBackend = 'rados_ng'; } RADOS_URLS { ceph_conf = '/etc/ceph/ceph.conf'; userid = \"admin\"; watch_url = \"rados://data/ganesha-export-index/conf-nfs1\"; } RADOS_KV { pool = \"metadata\"; namespace = \"ganesha-grace\"; nodeid = \"nfs1\"; } %url rados://data/ganesha-export-index/conf-nfs1 admin:/etc/ganesha # ganesha-rados-grace -p metadata -n ganesha-grace add nfs1 nfs2 nfs3 admin:/etc/ganesha # ganesha-rados-grace -p metadata -n ganesha-grace cur=1 rec=0 ====================================================== nfs1 E nfs2 E nfs3 E http://images.45drives.com/ceph/cephfs/nfs-ganesha-ceph.conf Task 1: Create an NFS export using the Ceph Dashboard \u00b6 1). In a browser, navigate to a monitor to access the Ceph Dashboard and log in: https://10.58.121.186:8443/ Username: admin Password: mypassword 2). Click on the NFS tab near the top of the page 3). Click on the green Add button 4). Click on the Add daemon button to the right and select mon1 5). Complete the configuration with the following values: Storage Backend: Object Gateway Object Storage User: s3user Path: S3CMDTEST NFS Protocol: NFSv3 and NFSv4 checked NFS Tag: Pseudo: /S3BKT Access Type: RW Squash: root_squash Transport Protocol: UDP and TCP checked Clients: Click Submit Task 2: Mount the NFS export on the admin node \u00b6 1). As the root user on the admin node, query the NFS Ganesha gateway node to see what mounts are available: showmount -e mon1 You should see something similar to the following: Export list for mon1: S3CMDTEST (everyone) 2). Mount the available nfs share to the /mnt directory on the admin server: mount -t nfs mon1:/S3BKT /mnt 3). List the nfs mount: mount | grep mnt Note the type listed as nfs4 4). Change to the root user\u2019s home directory and unmount the export: cd umount /mnt 2.4.9. Configure and Mount CIFS \u00b6 In this lab the Samba gateway was configured. A keyring for the Samba gateway was created, the Samba service was modified, and a user created to allow CIFS access to the SES cluster. Task 1: Prepare the CephFS share for CIFS \u00b6 1). In order for CIFS to work in our SES environment, a valid CephFS share must be available. The CephFS lab previously done in this workbook is sufficient. Using the same configuration that we used previously, mount the CephFS share and give permissions to all users at the root of the share: admin:~ # mount -t ceph mon1:6789:/ /mnt -o name=admin,secretfile=/etc/ceph/admin.secret admin:~ # chmod 777 /mnt admin:~ # l /mnt total 0 drwxrwxrwx 2 root root 0 Oct 5 14:30 ./ drwxr-xr-x 1 root root 156 Oct 5 08:53 ../ admin:~ # umount /mnt Task 2: Create a Samba gateway specific keyring on the Ceph admin node and copy it to the Samba gateway node \u00b6 1). A new keyring will be needed for the Samba gateway to allow access to the Ceph cluster. As root, perform the following: admin:~ # ceph auth get-or-create client.samba.gw mon 'allow r' osd 'allow *' mds 'allow *' -o ceph.client.samba.gw.keyring 2). Copy the new keyring to the Samba gateway node: admin:~ # scp ceph.client.samba.gw.keyring mon1:/etc/ceph/ ceph.client.samba.gw.keyring admin:~ # ssh mon1 Last login: Thu Jan 7 14:35:58 2021 from 10.58.121.181 mon1:~ # ls -l /etc/ceph/ total 12 -rw-r--r-- 1 root root 66 Jan 7 15:15 ceph.client.samba.gw.keyring -rw-r--r-- 1 root root 1095 Jan 5 22:44 ceph.conf -rw-r--r-- 1 root root 92 Aug 24 22:03 rbdmap Task 3: Configure Samba on the Samba gateway node \u00b6 1). The /etc/samba/smb.conf file will need to be edited to allow CIFS access to the storage cluster. On the mon1 node, replace all of the contents of the file with the following: admin:~ # ssh mon1 mon1:~ # vi /etc/samba/smb.conf mon1:/etc/samba # cat smb.conf [global] netbios name = SAMBA-GW clustering = no idmap config * : backend = tdb2 passdb backend = tdbsam # disable print server load printers = no smbd: backgroundqueue = no [ceph-smb] path = / vfs objects = ceph ceph: config_file = /etc/ceph/ceph.conf ceph: user_id = samba.gw read only = no oplocks = no kernel share modes = no 2). Create a smb user on the mon1 node named joesmb with a password of mypassword: mon1:/etc/samba # useradd joesmb mon1:/etc/samba # passwd joesmb ---> 123 Add joesmb to the smb password database with a password of mypassword: mon1:/etc/samba # smbpasswd -a joesmb New SMB password: ---> 123 Retype new SMB password: ---> 123 Added user joesmb. 3). Start and enable the smb and nmb daemons on mon1: mon1:/etc/samba # systemctl start smb nmb mon1:/etc/samba # systemctl enable smb nmb Created symlink /etc/systemd/system/multi-user.target.wants/smb.service \u2192 /usr/lib/systemd/system/smb.service. Created symlink /etc/systemd/system/multi-user.target.wants/nmb.service \u2192 /usr/lib/systemd/system/nmb.service. 4). Unmount the filesystem: mon1:~ # umount /mnt umount: /mnt: not mounted. Task 4: Connect a client to the Samba gateway \u00b6 1). On the admin node, verify that the Samba gateway is sharing via CIFS. The password is 123 admin:~ # smbclient -U joesmb -L //mon1 Enter WORKGROUP\\joesmb's password: ---> 123 Sharename Type Comment --------- ---- ------- ceph-smb Disk IPC$ IPC IPC Service (Samba 4.9.5-git.373.26895a83dbf3.44.1-SUSE-oS15.0-x86_64) Reconnecting with SMB1 for workgroup listing. Server Comment --------- ------- Workgroup Master --------- ------- GLOBAL CNPVGVSYB900 WORKGROUP SAMBA-GW 2). Connect to the ceph-smb share as joesmb. The password is 123 admin:~ # smbclient -U joesmb //mon1/ceph-smb Enter WORKGROUP\\joesmb's password: ---> 123 tree connect failed: NT_STATUS_BAD_NETWORK_NAME You should see output similar to the following: Try \u201chelp\u201d to get a list of possible commands. smb: \\>","title":"SUSE Enterprise Storage Basic Operation"},{"location":"linux/SES/linux_ses_demo/#suse-enterprise-storage-6-installation-and-basic-operation","text":"","title":"SUSE Enterprise Storage 6 Installation and Basic Operation"},{"location":"linux/SES/linux_ses_demo/#1-installation","text":"","title":"1. Installation"},{"location":"linux/SES/linux_ses_demo/#11-environment-setup","text":"In this demo, I use below environment, including VM setting and software installed. All VMs installed here was built on a physical host 10.58.121.68 . Host Server: 10.58.121.68 root / rootroot Account root / root123 Gateway: 10.58.120.1 Network Mask: 255.255.254.0 Nameserver: 10.58.32.32 10.33.50.20 Domain Search sha.me.corp dhcp.sha.me.corp me.corp ind.me.corp bgr.me.corp SUSE Server 15 SP1 Extensions and Modules were installed as below. [x] SUSE Enterprise Storage 6 [x] Basesystem Module 15 SP1 x86_64 [x] Server Applications Module 15 SP1 x86_64 Disable Services is as below: AppArmor Firewall Enable Services is as below. SSH Register SLES15.1 to local SMT. # SUSEConnect --url https://smtproxy.ind.me.corp Demo Environment summary is below. Alias Host Name Memory Disk eth0 eth0 mac address sles01 admin (salt-master) 16GB Disk1: 20G 10.58.121.181/23 52:54:00:23:7d:cd sles02 data1 16GB Disk1: 20G 10.58.121.182/23 52:54:00:5f:ce:6f Disk2: 8G Disk3: 8G Disk4: 8G sles03 data2 16GB Disk1: 20G 10.58.121.183/23 52:54:00:6f:f2:23 Disk2: 8G Disk3: 8G Disk4: 8G sles04 data3 16GB Disk1: 20G 10.58.121.184/23 52:54:00:93:4c:67 Disk2: 8G Disk3: 8G Disk4: 8G sles05 data4 16GB Disk1: 20G 10.58.121.185/23 52:54:00:90:b0:b0 Disk2: 8G Disk3: 8G Disk4: 8G sles06 mon1 16GB Disk1: 20G 10.58.121.186/23 52:54:00:46:43:7a sles07 mon2 16GB Disk1: 20G 10.58.121.187/23 52:54:00:00:fe:6b sles08 mon3 16GB Disk1: 20G 10.58.121.188/23 52:54:00:60:a3:92 Add hostname to file /etc/hosts (all nodes) If you do not specify a cluster network during Ceph deployment, it assumes a single public network environment. Make sure that the fully qualified domain name (FQDN) of each node can be resolved to the public network IP address by all other nodes. # vi /etc/hosts 10.58.121.181 admin.sha.me.corp admin salt 10.58.121.182 data1.sha.me.corp data1 10.58.121.183 data2.sha.me.corp data2 10.58.121.184 data3.sha.me.corp data3 10.58.121.185 data4.sha.me.corp data4 10.58.121.186 mon1.sha.me.corp mon1 10.58.121.187 mon2.sha.me.corp mon2 10.58.121.188 mon3.sha.me.corp mon3 Add all nodes as trust ssh access (root account) # cd ~ # ssh-keygen -t rsa # ssh-copy-id -i ~/.ssh/id_rsa.pub root@admin # ssh-copy-id -i ~/.ssh/id_rsa.pub root@data1 # ssh-copy-id -i ~/.ssh/id_rsa.pub root@data2 # ssh-copy-id -i ~/.ssh/id_rsa.pub root@data3 # ssh-copy-id -i ~/.ssh/id_rsa.pub root@data4 # ssh-copy-id -i ~/.ssh/id_rsa.pub root@mon1 # ssh-copy-id -i ~/.ssh/id_rsa.pub root@mon2 # ssh-copy-id -i ~/.ssh/id_rsa.pub root@mon3 # ssh admin.sha.me.corp # ssh data1.sha.me.corp # ssh data2.sha.me.corp # ssh data3.sha.me.corp # ssh data4.sha.me.corp # ssh mon1.sha.me.corp # ssh mon2.sha.me.corp # ssh mon3.sha.me.corp # ssh salt # ssh admin # ssh data1 # ssh data2 # ssh data3 # ssh data4 # ssh mon1 # ssh mon2 # ssh mon3 Disable firewall (all nodes) # sudo /sbin/SuSEfirewall2 off # firewall-cmd --state not running # systemctl stop firewalld.service # systemctl status firewalld.service firewalld.service - firewalld - dynamic firewall daemon Loaded: loaded (/usr/lib/systemd/system/firewalld.service; disabled; vendor preset: disabled) Active: inactive (dead) Docs: man:firewalld(1) Disable IPv6 (all nodes) and Set kernel pid to max value (all nodes) # vi /etc/sysctl.conf net.ipv6.conf.all.disable_ipv6 = 1 net.ipv6.conf.default.disable_ipv6 = 1 net.ipv6.conf.lo.disable_ipv6 = 1 kernel.pid_max = 4194303 # sysctl -p Set DEV_ENV=true in /etc/profile.local in all nodes Install basic software (all nodes) # zypper in -y -t pattern yast2_basis base # zypper in -y net-tools vim man sudo tuned irqbalance # zypper in -y ethtool rsyslog iputils less supportutils-plugin-ses # zypper in -y net-tools-deprecated tree wget Configure NTP service (all nodes), Setting via YaST2 and add server cn.pool.ntp.,org . And /etc/chrony.conf file looks like below. admin:~ # cat /etc/chrony.conf # Use public servers from the pool.ntp.org project. pool cn.pool.ntp.org iburst ! pool pool.ntp.org iburst # Record the rate at which the system clock gains/losses time. driftfile /var/lib/chrony/drift # Allow the system clock to be stepped in the first three updates # if its offset is larger than 1 second. makestep 1.0 3 # Enable kernel synchronization of the real-time clock (RTC). rtcsync # Enable hardware timestamping on all interfaces that support it. #hwtimestamp * # Increase the minimum numbgr of selectable sources required to adjust # the system clock. #minsources 2 # Allow NTP client access from local network. #allow 192.168.0.0/16 # Serve time even if not synchronized to a time source. #local stratum 10 # Specify file containing keys for NTP authentication. #keyfile /etc/chrony.keys # Get TAI-UTC offset and leap seconds from the system tz database. #leapsectz right/UTC # Specify directory for log files. logdir /var/log/chrony # Select which information is logged. #log measurements statistics tracking # Also include any directives found in configuration files in /etc/chrony.d include /etc/chrony.d/*.conf Make /etc/chrony.conf effective. # systemctl enable chronyd.service # systemctl restart chronyd.service # systemctl status chronyd.service # chronyc sources","title":"1.1. Environment Setup"},{"location":"linux/SES/linux_ses_demo/#12-install-packages","text":"Install salt-minion on all nodes. And start the service. Hostname is in file `/etc/salt/minion_id` # zypper in -y salt-minion Uncomment below to let all nodes know who is master # vi /etc/salt/minion master: salt # systemctl enable salt-minion.service # systemctl start salt-minion.service # systemctl status salt-minion.service Install Ceph in admin node. Check log in /var/log/salt admin:~ # zypper in -y salt-master admin:~ # systemctl enable salt-master.service admin:~ # systemctl start salt-master.service admin:~ # systemctl status salt-master.service Note: ganesha will be installed on mon1, not admin node. admin:~ # zypper se ganesha admin:~ # zypper in nfs-ganesha admin:~ # systemctl enable nfs-ganesha admin:~ # systemctl start nfs-ganesha admin:~ # systemctl status nfs-ganesha admin:~ # cd /var/log/salt List fingerprints of all unaccepted minion keys on the Salt master. admin:~ # salt-key -F Local Keys: master.pem: c0:e5:***:04:c7 master.pub: 43:73:***:6a:34 Unaccepted Keys: admin.sha.me.corp: fe:51:***:b9:48 mon1.sha.me.corp: 94:13:***:91:63 mon2.sha.me.corp: c0:fd:***:39:3f mon3.sha.me.corp: 38:fc:***:2e:05 data1.sha.me.corp: b6:6c:***:63:4f data2.sha.me.corp: ab:14:***:c8:ac data3.sha.me.corp: 90:3f:***:76:3b data4.sha.me.corp: d8:12:***:f1:20 If the minions' fingerprints match, accept them admin:~ # salt-key --accept-all The following keys are going to be accepted: Unaccepted Keys: admin.sha.me.corp mon1.sha.me.corp mon2.sha.me.corp mon3.sha.me.corp data1.sha.me.corp data2.sha.me.corp data3.sha.me.corp data4.sha.me.corp Proceed? [n/Y] Y Key for minion admin.sha.me.corp accepted. Key for minion mon1.sha.me.corp accepted. Key for minion mon2.sha.me.corp accepted. Key for minion mon3.sha.me.corp accepted. Key for minion data1.sha.me.corp accepted. Key for minion data2.sha.me.corp accepted. Key for minion data3.sha.me.corp accepted. Key for minion data4.sha.me.corp accepted. Verify that the keys have been accepted admin:~ # salt-key -F admin:~ # salt-key --list-all Accepted Keys: admin.sha.me.corp data1.sha.me.corp data2.sha.me.corp data3.sha.me.corp data4.sha.me.corp mon1.sha.me.corp mon2.sha.me.corp mon3.sha.me.corp Denied Keys: Unaccepted Keys: Rejected Keys: Zero out all drivers which will be used as OSDs (optional) data1:~ lsblk data1:~ # for I in {b,c,d}; do dd if=/dev/zero of=dev/sd$i bs=512 count=40 oflag=direct; done data2:~ # for I in {b,c,d}; do dd if=/dev/zero of=dev/sd$i bs=512 count=40 oflag=direct; done data3:~ # for I in {b,c,d}; do dd if=/dev/zero of=dev/sd$i bs=512 count=40 oflag=direct; done Install DeepSea admin:~ # zypper in -y deepsea Edit the /srv/pillar/ceph/deepsea_minions.sls file on the Salt master (admin node) and add or replace the following line: admin:~ # vi /srv/pillar/ceph/deepsea_minions.sls # Choose minions with a deepsea grain deepsea_minions: 'G@deepsea:*' #Match all Salt minions in the cluster # Choose all minions # deepsea_minions: '*' #Match all minions with the 'deepsea' grain # Choose custom Salt targeting # deepsea_minions: 'ses*' # deepsea_minions: 'ceph* or salt' Target the Minions Affirm salt-master (admin node) can communicate with the minions. And deploy the grains from admin node to all minions. admin:~ # salt '*' test.ping mon1.sha.me.corp: True data4.sha.me.corp: True data3.sha.me.corp: True data2.sha.me.corp: True data1.sha.me.corp: True mon3.sha.me.corp: True admin.sha.me.corp: True mon2.sha.me.corp: True Apply the 'deepsea' grain to a group of minions, and target with a DeepSea Grain admin:~ # salt '*' grains.append deepsea default data3.sha.me.corp: The val default was already in the list deepsea mon2.sha.me.corp: The val default was already in the list deepsea data1.sha.me.corp: The val default was already in the list deepsea data4.sha.me.corp: The val default was already in the list deepsea data2.sha.me.corp: The val default was already in the list deepsea mon3.sha.me.corp: The val default was already in the list deepsea admin.sha.me.corp: The val default was already in the list deepsea mon1.sha.me.corp: The val default was already in the list deepsea admin:~ # salt -G 'deepsea:*' test.ping (The following command is an equivalent) admin:~ # salt -C 'G@deepsea:*' test.ping admin.sha.me.corp: True data3.sha.me.corp: True mon1.sha.me.corp: True mon2.sha.me.corp: True data2.sha.me.corp: True data4.sha.me.corp: True mon3.sha.me.corp: True data1.sha.me.corp: True","title":"1.2. Install Packages"},{"location":"linux/SES/linux_ses_demo/#13-stage-0-the-preparation","text":"Run Stage 0\u2014the preparation During this stage, all required updates are applied and your system may be rebooted. If there are errors, re-run the stage. admin:~ # deepsea stage run ceph.stage.0 (The following commands are equivalents) admin:~ # salt-run state.orch ceph.stage.0 admin:~ # salt-run state.orch ceph.stage.prep Run Stage 1\u2014the discovery Here all hardware in your cluster is being detected and necessary information for the Ceph configuration is being collected. The discovery stage collects data from all minions and creates configuration fragments that are stored in the directory /srv/pillar/ceph/proposals . The data are stored in the YAML format in *.sls or *.yml files admin:~ # deepsea stage run ceph.stage.1 (The following commands are equivalents) admin:~ # salt-run state.orch ceph.stage.1 admin:~ # salt-run state.orch ceph.stage.discovery","title":"1.3. Stage 0 \u2014 the preparation"},{"location":"linux/SES/linux_ses_demo/#14-stage-2-the-configuration","text":"Run Stage 2 \u2014 the configuration \u2014 you need to prepare configuration data in a particular format. The assignment follows this pattern: role-ROLE_NAME/PATH/FILES_TO_INCLUDE (NOTE, the parent directory of PATH is /srv/pillar/ceph/ ) To avoid trouble with performance and the upgrade procedure, do not deploy the Ceph OSD, Metadata Server, or Ceph Monitor role to the Admin Node. Monitors, Metadata Server, and gateways can be co-located on the OSD nodes. If you are using CephFS, S3/Swift, iSCSI, at least two instances of the respective roles (Metadata Server, Object Gateway, iSCSI) are required for redundancy and availability. admin:~ # cp /usr/share/doc/packages/deepsea/examples/policy.cfg-rolebased /srv/pillar/ceph/proposals/policy.cfg admin:~ # vi /srv/pillar/ceph/proposals/policy.cfg ## Cluster Assignment # Add all nodes into Ceph cluster cluster-ceph/cluster/*.sls ## Roles # The Admin node fills the \u201cmaster\u201d and \u201cadmin\u201d roles for DeepSea # The master role is mandatory, always add a similar line to the following role-master/cluster/admin*.sls role-admin/cluster/admin*.sls # Monitoring # Cluster monitoring and data graphs, most commonly they run on Admin node # NFS Ganesha is configured via the file /etc/ganesha/ganesha.conf # As additional configuration is required to install NFS Ganesha, you can install NFS Ganesha later. # The following requirements need to be met before DeepSea stages 2 and 4 can be executed to install NFS Ganesha: # a)At least one node needs to be assigned the role-ganesha. # b)You can define only one role-ganesha per minion. # c)NFS Ganesha needs either an Object Gateway or CephFS to work, otherwise the validation will fail in Stage 3. # d)The kernel based NFS needs to be disabled on minions with the role-ganesha role. role-prometheus/cluster/admin*.sls role-grafana/cluster/mon1*.sls # MON # The minion will provide the monitor service to the Ceph cluster role-mon/cluster/mon*.sls # MGR # The Ceph manager daemon which collects all the state information from the whole cluster # Deploy it on all minions where you plan to deploy the Ceph monitor role role-mgr/cluster/mon1*.sls # MDS # The minion will provide the metadata service to support CephFS role-mds/cluster/mon*.sls # IGW # The minion will act as an iSCSI Gateway role-igw/cluster/mon2*.sls # RGW # The minion will act as an Object Gateway role-rgw/cluster/mon3*.sls # Storage # Use this role to specify storage nodes # It points to data1~4 nodes with a wildcard. role-storage/cluster/data*.sls # COMMON # It includes configuration files generated during the discovery (Stage 1) # Accept the default values for common configuration parameters such as fsid and public_network config/stack/default/global.yml config/stack/default/ceph/cluster.yml admin:~ # deepsea stage run ceph.stage.2 (The following commands are equivalents) admin:~ # salt-run state.orch ceph.stage.2 admin:~ # salt-run state.orch ceph.stage.configure After the command succeeds, run below command to view the pillar data for the specified minions admin:~ # salt 'mon*' pillar.items admin:~ # salt '*' saltutil.pillar_refresh Check time server (admin node) (the directory /srv/pillar/ceph/stack was initialized after deepsea installed, but global.yml file was not created yet until stage 2) By default, DeepSea uses the Admin Node as the time server for other cluster nodes. admin:~ # cat /srv/pillar/ceph/stack/default/global.yml (this file will be generated after stage 2) monitoring: prometheus: metric_relabel_config: ceph: [] grafana: [] node_exporter: [] prometheus: [] relabel_config: ceph: [] grafana: [] node_exporter: [] prometheus: [] rule_files: [] scrape_interval: ceph: 10s grafana: 10s node_exporter: 10s prometheus: 10s target_partition: ceph: 1/1 grafana: 1/1 node_exporter: 1/1 prometheus: 1/1 time_server: admin.sha.me.corp Verify network (the directory /srv/pillar/ceph/stack was initialized after deepsea installed, but cluster.yml file was not created until stage 2 ) admin:~ # cat /srv/pillar/ceph/stack/ceph/cluster.yml --nothing admin:~ # cat /srv/pillar/ceph/stack/default/ceph/cluster.yml available_roles: - storage - admin - mon - mds - mgr - igw - grafana - prometheus - storage - rgw - ganesha - client-cephfs - client-radosgw - client-iscsi - client-nfs - benchmark-rbd - benchmark-blockdev - benchmark-fs - master cluster_network: 10.58.120.0/23 fsid: 343ee7d3-232f-4c71-8216-1edbc55ac6e0 public_network: 10.58.120.0/23 Note: customized file will overwrite default one. Default file: /srv/pillar/ceph/stack/default/ceph/cluster.yml Customized file: /srv/pillar/ceph/stack/ceph/cluster.yml Check DriveGroup DriveGroups specify the layouts of OSDs in the Ceph cluster. They are defined in a single file /srv/salt/ceph/configuration/files/drive_groups.yml admin:~ # cat /srv/salt/ceph/configuration/files/drive_groups.yml default_drive_group_name: target: 'data*' <--original: 'I@role:storage' data_devices: all: true admin:~ # salt 'data*' pillar.items | grep -B5 stroage","title":"1.4. Stage 2 \u2014 the configuration"},{"location":"linux/SES/linux_ses_demo/#15-stage-3-the-deployment","text":"Run Stage 3 \u2014 the deployment \u2014 creates a basic Ceph cluster with mandatory Ceph services. This Deployment stage has more than 60 automated steps. Be patient and make sure the stage completes successfully before proceeding. Set dev environment and disable subvolume: admin:~ # vi /srv/pillar/ceph/stack/global.yml admin:~ # vi /srv/pillar/ceph/stack/default/global.yml monitoring: prometheus: metric_relabel_config: ceph: [] grafana: [] node_exporter: [] prometheus: [] relabel_config: ceph: [] grafana: [] node_exporter: [] prometheus: [] rule_files: [] scrape_interval: ceph: 10s grafana: 10s node_exporter: 10s prometheus: 10s target_partition: ceph: 1/1 grafana: 1/1 node_exporter: 1/1 prometheus: 1/1 time_server: admin.sha.me.corp DEV_ENV: True subvolume_init: disabled admin:~ # salt '*' saltutil.pillar_refresh Note: customized file will overwrite default one. Default file: /srv/pillar/ceph/stack/default/global.yml Customized file: /srv/pillar/ceph/stack/global.yml admin:~ # deepsea stage run ceph.stage.3 (The following commands are equivalents) admin:~ # salt-run state.orch ceph.stage.3 admin:~ # salt-run state.orch ceph.stage.deploy After the command succeeds, run the following to check the status: admin:~ # ceph -s Below comands return you a structure of matching disks based on your DriveGroups. (will show available information after stage 3) admin:~ # salt-run disks.Report admin:~ # salt-run disks.list admin:~ # salt-run disks.details","title":"1.5. Stage 3 \u2014 the deployment"},{"location":"linux/SES/linux_ses_demo/#16-stage-4-the-services","text":"Run Stage 4 \u2014 the services \u2014 additional features of Ceph like iSCSI, Object Gateway and CephFS can be installed in this stage. Each is optional. admin:~ # deepsea stage run ceph.stage.4 (The following commands are equivalents) admin:~ # salt-run state.orch ceph.stage.4 admin:~ # salt-run state.orch ceph.stage.services admin:~ # ceph osd lspools 1 iscsi-images 2 cephfs_data 3 cephfs_metadata 4 .rgw.root 5 default.rgw.control 6 default.rgw.meta 7 default.rgw.log Before logon to dashboard via url, need get credentials first admin:~ # salt-call grains.get dashboard_creds local: ---------- admin: --> the password was changed to mypassword to log on to dashboard admin:~ # ceph mgr services { \"dashboard\": \"https://mon1.sha.me.corp:8443/\", \"prometheus\": \"http://mon1.sha.me.corp:9283/\" } https://10.58.121.186:8443 http://10.58.121.186:9283 admin:~ # watch ceph -s Every 2.0s: ceph -s admin: Mon Oct 5 14:41:51 2020 cluster: id: health: HEALTH_OK services:s: ceph -s mon: 3 daemons, quorum mon1,mon2,mon3 (age 87m) mgr: mon1(active, since 82m) mds: cephfs:1 {0=mon3=up:active} 2 up:standby osd: 12 osds: 12 up (since 85m), 12 in (since 85m) rgw: 1 daemon active (mon3) task status: scrub status: mds.mon3: idle data: pools: 7 pools, 576 pgs objects: 213 objects, 4.2 KiB usage: 12 GiB used, 84 GiB / 96 GiB avail pgs: 576 active+clean io: client: 852 B/s rd, 0 op/s rd, 0 op/s wr","title":"1.6. Stage 4 \u2014 the services"},{"location":"linux/SES/linux_ses_demo/#17-stage-5-the-removal-stage","text":"Run Stage 5 \u2014 the removal stage. This stage is not mandatory and during the initial setup it is usually not needed. In this stage the roles of minions and also the cluster configuration are removed. You need to run this stage when you need to remove a storage node from your cluster. admin:~ # deepsea stage run ceph.stage.","title":"1.7. Stage 5 \u2014 the removal stage"},{"location":"linux/SES/linux_ses_demo/#18-installation-guide","text":"Deployment Guide (EN) Deployment Guide (ZH)","title":"1.8. Installation Guide"},{"location":"linux/SES/linux_ses_demo/#19-issues-during-installation","text":"[ERROR]: The Salt Master has cached the public key for this node SOLUTION : Restart minions service [ERROR]: This server_id is computed nor by Adler32 neither by CRC32 [QUESTION]: How to change new salt key Stop salt-minion service # systemctl stop salt-minion Delete salt-minion pulic key # rm /etc/salt/pki/minion/minion.pub # rm /etc/salt/pki/minion/minion.pem Change new minion_id admin:~ # echo admin.sha.me.corp > /etc/salt/minion_id data1:~ # echo data1.sha.me.corp > /etc/salt/minion_id data2:~ # echo data2.sha.me.corp > /etc/salt/minion_id data3:~ # echo data3.sha.me.corp > /etc/salt/minion_id data4:~ # echo data4.sha.me.corp > /etc/salt/minion_id mon1:~ # echo mon1.sha.me.corp > /etc/salt/minion_id mon2:~ # echo mon2.sha.me.corp > /etc/salt/minion_id mon3:~ # echo mon3.sha.me.corp > /etc/salt/minion_id Delete old ID on admin node # salt-key -D Restart salt-minion service # systemctl restart salt-minion Accept all new key on admin node admin:~ # salt-key -L admin:~ # salt-key -A or admin:~ # salt-key -a admin.sha.me.corp data1:~ # salt-key -a data1.sha.me.corp data2:~ # salt-key -a data2.sha.me.corp data3:~ # salt-key -a data3.sha.me.corp data4:~ # salt-key -a data4.sha.me.corp mon1:~ # salt-key -a mon1.sha.me.corp mon2:~ # salt-key -a mon2.sha.me.corp mon3:~ # salt-key -a mon3.sha.me.corp [ERROR] ['/var/lib/ceph subvolume missing on mon3.sha.me.corp', '/var/lib/ceph subvolume missing on mon1.sha.me.corp', '/var/lib/ceph subvolume missing on mon2.sha.me.corp', 'See /srv/salt/ceph/subvolume/README.md'] SOLUTION Edit /srv/pillar/ceph/stack/global.yml and add the following line: subvolume_init: disabled Then refresh the Salt pillar and re-run DeepSea stage.3: admin:~ # salt '*' saltutil.refresh_pillar admin:~ # salt-run state.orch ceph.stage.3 After DeepSea successfully finished stage.3, the Ceph Dashboard will be running. Refer to Book \u201cAdministration Guide\u201d, Chapter 20 \u201cCeph Dashboard\u201d for a detailed overview of Ceph Dashboard features. To list nodes running dashboard, run: admin:~ # ceph mgr services | grep dashboard To list admin credentials, run: admin:~ # salt-call grains.get dashboard_creds [ERROR] module function cephprocesses.wait executed on nodes mon1~3 and data1~4 in Stage 0 SOLUTION Check below on all nodes # salt-call cephprocesses.check ERROR: process ceph-mds for role mds is not running ERROR: process radosgw for role rgw is not running admin:~ # ceph -s Clock skew detected on mon ceph (mon.mon2, mon.mon3) Set time server to public server (China) # chronyc sources","title":"1.9. Issues during installation"},{"location":"linux/SES/linux_ses_demo/#110-shutting-down-the-whole-ceph-cluster","text":"Shut down or disconnect any clients accessing the cluster. To prevent CRUSH from automatically rebalancing the cluster, set the cluster to noout: # ceph osd set noout Other flags you can set per osd: nodown noup noin noout Disable safety measures and run the ceph.shutdown runner: admin:~ # salt-run disengage.safety safety is now disabled for cluster ceph admin:~ # salt-run state.orch ceph.shutdown admin.sha.me.corp_master: Name: set noout - Function: salt.state - Result: Changed Started: - 14:32:14.398022 Duration: 2266.75 ms Name: Shutting down radosgw for rgw - Function: salt.state - Result: Changed Started: - 14:32:16.665452 Duration: 1461.23 ms Name: Shutting down cephfs - Function: salt.state - Result: Changed Started: - 14:32:18.127353 Duration: 30326.193 ms Name: Shutting down iscsi - Function: salt.state - Result: Clean Started: - 14:32:48.454187 Duration: 30142.468 ms Name: Shutting down storage - Function: salt.state - Result: Changed Started: - 14:33:18.597321 Duration: 10841.45 ms Name: Shutting down mgr - Function: salt.state - Result: Changed Started: - 14:33:29.439442 Duration: 29209.141 ms Name: Shutting down mon - Function: salt.state - Result: Changed Started: - 14:33:58.649221 Duration: 30519.97 ms Summary for admin.sha.me.corp_master ------------ Succeeded: 7 (changed=6) Failed: 0 ------------ Total states run: 7 Total run time: 134.767 s Power off all cluster nodes: admin:~ # salt -C 'G@deepsea:*' cmd.run \"shutdown -h\" Broadcast message from root@admin (Sat 2021-03-06 14:40:37 CST): The system is going down for poweroff at Sat 2021-03-06 14:41:37 CST! admin.sha.me.corp: Shutdown scheduled for Sat 2021-03-06 14:41:37 CST, use 'shutdown -c' to cancel. mon2.sha.me.corp: Shutdown scheduled for Sat 2021-03-06 14:41:37 CST, use 'shutdown -c' to cancel. data2.sha.me.corp: Shutdown scheduled for Sat 2021-03-06 14:41:37 CST, use 'shutdown -c' to cancel. mon3.sha.me.corp: Shutdown scheduled for Sat 2021-03-06 14:41:37 CST, use 'shutdown -c' to cancel. data3.sha.me.corp: Shutdown scheduled for Sat 2021-03-06 14:41:37 CST, use 'shutdown -c' to cancel. data4.sha.me.corp: Shutdown scheduled for Sat 2021-03-06 14:41:37 CST, use 'shutdown -c' to cancel. mon1.sha.me.corp: Shutdown scheduled for Sat 2021-03-06 14:41:37 CST, use 'shutdown -c' to cancel. data1.sha.me.corp: Shutdown scheduled for Sat 2021-03-06 14:41:37 CST, use 'shutdown -c' to cancel.","title":"1.10. Shutting Down the Whole Ceph Cluster"},{"location":"linux/SES/linux_ses_demo/#111-starting-stopping-and-restarting-services-using-targets","text":"# ls /usr/lib/systemd/system/ceph*.target ceph.target ceph-osd.target ceph-mon.target ceph-mgr.target ceph-mds.target ceph-radosgw.target ceph-rbd-mirror.target To start/stop/restart all Ceph services on the node, run: # systemctl start ceph.target # systemctl stop ceph.target # systemctl restart ceph.target To start/stop/restart all OSDs on the node, run: # systemctl start ceph-osd.target # systemctl stop ceph-osd.target # systemctl restart ceph-osd.target Starting, Stopping, and Restarting Individual Services # systemctl list-unit-files --all --type=service ceph* ceph-osd@.service ceph-mon@.service ceph-mds@.service ceph-mgr@.service ceph-radosgw@.service ceph-rbd-mirror@.service Example : # systemctl status ceph-mon@HOSTNAME.service (e.g., ceph-mon@mon1.service) # systemctl start ceph-osd@1.service # systemctl stop ceph-osd@1.service # systemctl restart ceph-osd@1.service # systemctl status ceph-osd@1.service","title":"1.11. Starting, Stopping, and Restarting Services Using Targets"},{"location":"linux/SES/linux_ses_demo/#112-restarting-all-services","text":"# salt-run state.orch ceph.restart","title":"1.12. Restarting All Services"},{"location":"linux/SES/linux_ses_demo/#113-restarting-specific-services","text":"Example: salt-run state.orch ceph.restart.service_name # salt-run state.orch ceph.restart.mon # salt-run state.orch ceph.restart.mgr # salt-run state.orch ceph.restart.osd # salt-run state.orch ceph.restart.mds # salt-run state.orch ceph.restart.rgw # salt-run state.orch ceph.restart.igw # salt-run state.orch ceph.restart.ganesha Default log file path of salt-run: /var/log/salt/master","title":"1.13. Restarting Specific Services"},{"location":"linux/SES/linux_ses_demo/#2-basic-operation","text":"","title":"2. Basic Operation"},{"location":"linux/SES/linux_ses_demo/#21-pools-and-data-placement","text":"","title":"2.1. Pools and Data Placement"},{"location":"linux/SES/linux_ses_demo/#211-enable-the-pg-autoscaler-and-balancer-modules","text":"","title":"2.1.1. Enable the PG Autoscaler and Balancer Modules"},{"location":"linux/SES/linux_ses_demo/#task-1-view-the-state-of-all-the-manager-modules","text":"List all the existing Manager Modules admin:~ # ceph mgr module ls | less","title":"Task 1: View the state of all the Manager Modules"},{"location":"linux/SES/linux_ses_demo/#task-2-list-the-existing-pools","text":"List the pools that already exist in the cluster admin:~ # ceph osd lspools 1 iscsi-images 2 cephfs_data 3 cephfs_metadata 4 .rgw.root 5 default.rgw.control 6 default.rgw.meta 7 default.rgw.log List the pools again, but this time using the rados command: admin:~ # rados lspools iscsi-images cephfs_data cephfs_metadata .rgw.root default.rgw.control default.rgw.meta default.rgw.log View the output of placement group autoscale-status command for the pools admin:~ # ceph osd pool autoscale-status Error ENOTSUP: Module 'pg_autoscaler' is not enabled (required by command 'osd pool autoscale-status'): use `ceph mgr module enable pg_autoscaler` to enable it","title":"Task 2: List the Existing Pools"},{"location":"linux/SES/linux_ses_demo/#task-3-enable-the-pg_autoscaler-module","text":"Enable the pg_autoscaler module admin:~ # ceph mgr module enable pg_autoscaler admin:~ # ceph osd pool autoscale-status POOL SIZE TARGET SIZE RATE RAW CAPACITY RATIO TARGET RATIO EFFECTIVE RATIO BIAS PG_NUM NEW PG_NUM AUTOSCALE iscsi-images 389 3.0 98256M 0.0000 1.0 128 32 warn cephfs_data 0 3.0 98256M 0.0000 1.0 256 32 warn cephfs_metadata 7285 3.0 98256M 0.0000 4.0 64 16 warn .rgw.root 1245 3.0 98256M 0.0000 1.0 32 warn default.rgw.control 0 3.0 98256M 0.0000 1.0 32 warn default.rgw.meta 381 3.0 98256M 0.0000 1.0 32 warn default.rgw.log 18078 3.0 98256M 0.0000 1.0 32 warn Note that for the iscsi-images pool the PG_NUM value is 128. And note that the NEW PG_NUM value is 32. The PGs won\u2019t be adjusted automatically because the default setting for the autoscaler is \u201cwarn\u201d. Note the last column (mode) that shows status \u201cwarn\u201d for all the pools. Check current status. \u201chave too many placement groups\u201d. That\u2019s exactly what we want the pg_autoscaler to tell us. admin:~ # ceph health HEALTH_WARN 3 pools have too many placement groups Turn off the pg_autoscaler feature for CephFS pools admin:~ # ceph osd pool set cephfs_data pg_autoscale_mode off set pool 2 pg_autoscale_mode to off admin:~ # ceph osd pool set cephfs_metadata pg_autoscale_mode off set pool 3 pg_autoscale_mode to off admin:~ # ceph health HEALTH_WARN 1 pools have too many placement groups Set the pg_autoscaler mode to \u201con\u201d for the iscs-images pool: admin:~ # ceph osd pool set iscsi-images pg_autoscale_mode on set pool 1 pg_autoscale_mode to on admin:~ # ceph osd pool autoscale-status POOL SIZE TARGET SIZE RATE RAW CAPACITY RATIO TARGET RATIO EFFECTIVE RATIO BIAS PG_NUM NEW PG_NUM AUTOSCALE iscsi-images 389 3.0 98256M 0.0000 1.0 128 32 on cephfs_data 0 3.0 98256M 0.0000 1.0 256 32 off cephfs_metadata 7412 3.0 98256M 0.0000 4.0 64 16 off .rgw.root 1245 3.0 98256M 0.0000 1.0 32 warn default.rgw.control 0 3.0 98256M 0.0000 1.0 32 warn default.rgw.meta 381 3.0 98256M 0.0000 1.0 32 warn default.rgw.log 18078 3.0 98256M 0.0000 1.0 32 warn Turn on the pg_autoscaler feature for CephFS pools admin:~ # ceph osd pool set cephfs_data pg_autoscale_mode on set pool 2 pg_autoscale_mode to on admin:~ # ceph osd pool set cephfs_metadata pg_autoscale_mode on set pool 3 pg_autoscale_mode to on PG numbgrs must always be a power of 2 admin:~ # ceph osd pool autoscale-status POOL SIZE TARGET SIZE RATE RAW CAPACITY RATIO TARGET RATIO EFFECTIVE RATIO BIAS PG_NUM NEW PG_NUM AUTOSCALE iscsi-images 389 3.0 98256M 0.0000 1.0 32 on cephfs_data 0 3.0 98256M 0.0000 1.0 32 off cephfs_metadata 7412 3.0 98256M 0.0000 4.0 16 off .rgw.root 1245 3.0 98256M 0.0000 1.0 32 warn default.rgw.control 0 3.0 98256M 0.0000 1.0 32 warn default.rgw.meta 381 3.0 98256M 0.0000 1.0 32 warn default.rgw.log 35900 3.0 98256M 0.0000 1.0 32 warn Show the cluster health admin:~ # ceph -s cluster: id: health: HEALTH_OK services: mon: 3 daemons, quorum mon1,mon2,mon3 (age 4w) mgr: mon1(active, since 46h) mds: cephfs:1 {0=mon3=up:active} 2 up:standby osd: 12 osds: 12 up (since 8w), 12 in (since 8w) rgw: 1 daemon active (mon3) task status: scrub status: mds.mon3: idle data: pools: 7 pools, 433 pgs objects: 246 objects, 4.7 KiB usage: 13 GiB used, 83 GiB / 96 GiB avail pgs: 0.462% pgs not active 431 active+clean 2 peering io: client: 45 KiB/s rd, 0 B/s wr, 44 op/s rd, 28 op/s wr","title":"Task 3: Enable the pg_autoscaler module"},{"location":"linux/SES/linux_ses_demo/#task-4-turn-on-the-placement-group-balancer-feature","text":"1). Show the \u201cstatus\u201d of the balancer: admin:~ # ceph balancer status { \"plans\": [], \"active\": false, \"last_optimize_started\": \"\", \"last_optimize_duration\": \"\", \"optimize_result\": \"\", \"mode\": \"none\" } admin:~ # ceph balancer on admin:~ # ceph balancer status { \"plans\": [], \"active\": true, \"last_optimize_started\": \"Mon Jan 4 20:22:57 2021\", \"last_optimize_duration\": \"0:00:00.001379\", \"optimize_result\": \"Please do \\\"ceph balancer mode\\\" to choose a valid mode first\", \"mode\": \"none\" } 2). Set the mode for the balancer to \u201cupmap\u201d: admin:~ # ceph balancer mode upmap Error EPERM: min_compat_client \"jewel\" < \"luminous\", which is required for pg-upmap. Try \"ceph osd set-require-min-compat-client luminous\" before enabling this mode admin:~ # ceph osd set-require-min-compat-client luminous --yes-i-really-mean-it set require_min_compat_client to luminous admin:~ # ceph balancer mode upmap admin:~ # ceph balancer status { \"plans\": [], \"active\": true, \"last_optimize_started\": \"Mon Jan 4 20:23:57 2021\", \"last_optimize_duration\": \"0:00:00.001807\", \"optimize_result\": \"Please do \\\"ceph balancer mode\\\" to choose a valid mode first\", \"mode\": \"upmap\" } 3). Create a balancer optimization plan called basic-plan. Ceph won\u2019t let you do this yet. Because you just recently enabled the pg_autoscaler, Ceph is moving objects around, and the PGs are quite busy with re-peering. admin:~ # ceph balancer optimize basic-plan Error EINVAL: Balancer enabled, disable to optimize manually 4). Show the details of the plan: This shows what \u201cexecute\u201d-ing the plan will do, itemizing which PGs will be affected. admin:~ # ceph balancer show basic-plan Error ENOENT: plan basic-plan not found <--- failed here 5). Show the effectiveness of the plan by comparing the current score for the pre-planned balancing and the score for the planned balancing: admin:~ # ceph balancer eval current cluster score 0.118731 (lower is better) admin:~ # ceph balancer eval basic-plan Error EINVAL: option \"basic-plan\" not a plan or a pool 6). Show the status of the balancer, now with all of these settings having been set, but before putting them into effect: The pg_autoscaler has already optimized the balance of PGs sufficiently. That\u2019s because this cluster is very small and has no significant content stored in it yet. If that\u2019s the case, you would see a message like \u201cError EALREADY: Unable to find further optimization, or pool(s)' pg_num is decreasing, or distribution is already perfect.\u201d If you receive this message, then you will not be able to complete this task. At some later time in the course you may choose to revisit this task to complete it. admin:~ # ceph balancer status { \"plans\": [], \"active\": true, \"last_optimize_started\": \"Mon Jan 4 20:32:59 2021\", \"last_optimize_duration\": \"0:00:00.004170\", \"optimize_result\": \"Unable to find further optimization, or pool(s) pg_num is decreasing, or distribution is already perfect\", \"mode\": \"upmap\" } 7). Set the basic-plan into effect: admin:~ # ceph balancer execute basic-plan Error EINVAL: Balancer enabled, disable to execute a plan 8). Now re-show the current score for the balanced cluster: admin:~ # ceph balancer eval current cluster score 0.118731 (lower is better)","title":"Task 4: Turn on the Placement Group balancer feature"},{"location":"linux/SES/linux_ses_demo/#212-manipulate-erasure-code-profiles","text":"","title":"2.1.2. Manipulate Erasure Code Profiles"},{"location":"linux/SES/linux_ses_demo/#task-1-display-a-list-of-the-current-erasure-code-profiles","text":"admin:~ # ceph osd erasure-code-profile no valid command found; 4 closest matches: osd erasure-code-profile set { [...]} {--force} osd erasure-code-profile get osd erasure-code-profile rm osd erasure-code-profile ls Error EINVAL: invalid command admin:~ # ceph osd erasure-code-profile ls default","title":"Task 1: Display a list of the current Erasure Code profiles"},{"location":"linux/SES/linux_ses_demo/#task-2-examine-the-details-of-the-default-ec-profile","text":"admin:~ # ceph osd erasure-code-profile get default k=2 m=1 plugin=jerasure technique=reed_sol_van","title":"Task 2: Examine the details of the default EC profile"},{"location":"linux/SES/linux_ses_demo/#task-3-create-and-remove-a-new-ec-profile","text":"1. Create a new EC profile from the command line. This is going to be a \u201cbad\u201d profile that will be removed in a moment: admin:~ # ceph osd erasure-code-profile set bad_profile k=2 m=4 plugin=jerasure admin:~ # ceph osd erasure-code-profile ls bad_profile default admin:~ # ceph osd erasure-code-profile get bad_profile crush-device-class= crush-failure-domain=host crush-root=default jerasure-per-chunk-alignment=false k=2 m=4 plugin=jerasure technique=reed_sol_van w=8 admin:~ # ceph osd erasure-code-profile rm bad_profile admin:~ # ceph osd erasure-code-profile ls default","title":"Task 3: Create and remove a new EC profile"},{"location":"linux/SES/linux_ses_demo/#task-4-create-a-better-ec-profile","text":"admin:~ # ceph osd erasure-code-profile set usable_profile k=2 m=1 plugin=jerasure technique=reed_sol_van stripe_unit=4K crush-failure-domain=host admin:~ # ceph osd erasure-code-profile get usable_profile crush-device-class= crush-failure-domain=host crush-root=default jerasure-per-chunk-alignment=false k=2 m=1 plugin=jerasure stripe_unit=4K technique=reed_sol_van w=8","title":"Task 4: Create a better EC profile"},{"location":"linux/SES/linux_ses_demo/#213-manipulate-crush-map-rulesets","text":"","title":"2.1.3. Manipulate CRUSH Map Rulesets"},{"location":"linux/SES/linux_ses_demo/#task-1-display-a-list-of-the-current-crush-map-rules","text":"admin:~ # ceph osd crush rule ls replicated_rule admin:~ # ceph osd crush osd crush rule ls osd crush rule ls-by-class osd crush rule dump {} osd crush dump osd crush set {} osd crush add-bucket { [...]} osd crush rename-bucket osd crush set [...] osd crush add [...] osd crush set-all-straw-buckets-to-straw2 admin:~ # ceph osd crush rule osd crush rule ls osd crush rule ls-by-class osd crush rule dump {} osd crush rule create-simple {firstn|indep} osd crush rule create-replicated {} osd crush rule create-erasure {} osd crush rule rm osd crush rule rename List the existing CRUSH Map rulesets that have been defined according to a particular device class: admin:~ # ceph osd crush rule ls-by-class hdd admin:~ # ceph osd crush rule ls-by-class ssd Error ENOENT: failed to get rules by class 'ssd' admin:~ # ceph osd crush rule ls-by-class nvme Error ENOENT: failed to get rules by class 'nvme'","title":"Task 1: Display a list of the current CRUSH Map rules"},{"location":"linux/SES/linux_ses_demo/#task-2-examine-the-details-of-the-default-crush-map-rule","text":"Show the details of the default CRUSH Map rule with the dump sub-command: The \u201crule_id\u201d and \u201cruleset\u201d values just numbgrs to keep track of rules similar to a DB key id. \u201cmin_size\u201d and \u201cmax_size\u201d are related to how CRUSH behaves when a certain numbgr of replicas are created. The \u201csteps\u201d section is the most functional portion of the rule, providing an ordered set of rules for how CRUSH should behave. Note that there are three \u201cop\u201d parts, one each for \u201ctake\u201d, \u201cchooseleaf_firstn\u201d, and \u201cemit\u201d. \u201ctake\u201d in a replicated rule is always the first step, and \u201cemit\u201d is always the last step. The \u201citem_type\u201d in the \u201ctake\u201d step is the crush_root value, and the \u201chost\u201d in the \u201cchooseleaf_firstn\u201d step is the failure_domain. admin:~ # ceph osd crush rule dump replicated_rule { \"rule_id\": 0, \"rule_name\": \"replicated_rule\", \"ruleset\": 0, \"type\": 1, \"min_size\": 1, \"max_size\": 10, \"steps\": [ { \"op\": \"take\", \"item\": -1, \"item_name\": \"default\" }, { \"op\": \"chooseleaf_firstn\", \"num\": 0, \"type\": \"host\" }, { \"op\": \"emit\" } ] }","title":"Task 2: Examine the details of the default CRUSH Map rule"},{"location":"linux/SES/linux_ses_demo/#task-3-create-and-remove-a-new-crush-map-rule","text":"1). Create a new CRUSH ruleset from the command line.We made two mistakes here: First, we named it \u201cbud\u201d instead of \u201cbad\u201d. admin:~ # ceph osd crush rule create-replicated bud_ruleset default host admin:~ # ceph osd crush rule ls replicated_rule bud_ruleset 2). Rename the ruleset: admin:~ # ceph osd crush rule rename bud_ruleset bad_ruleset admin:~ # ceph osd crush rule ls replicated_rule bad_ruleset 3). The second mistake was that we specified the failure-domain at the host-bucket level. This is technically not a bad thing to do, in fact it would be a common use case. But for this demo we want to set the failure domain at the rack-bucket level. We can\u2019t change a defined CRUSH Map ruleset, so delete the bad one: admin:~ # ceph osd crush rule rm bad_ruleset admin:~ # ceph osd crush rule ls replicated_rule","title":"Task 3: Create and remove a new CRUSH Map rule"},{"location":"linux/SES/linux_ses_demo/#task-4-create-a-better-crush-map-rule","text":"Create a more appropriate CRUSH Map rule from the CLI, that will survive the failure of a rack: admin:~ # ceph osd crush rule create-replicated better_ruleset default rack admin:~ # ceph osd crush rule dump better_ruleset { \"rule_id\": 1, \"rule_name\": \"better_ruleset\", \"ruleset\": 1, \"type\": 1, \"min_size\": 1, \"max_size\": 10, \"steps\": [ { \"op\": \"take\", \"item\": -1, \"item_name\": \"default\" }, { \"op\": \"chooseleaf_firstn\", \"num\": 0, \"type\": \"rack\" }, { \"op\": \"emit\" } ] }","title":"Task 4: Create a better CRUSH Map rule"},{"location":"linux/SES/linux_ses_demo/#task-5-create-crush-map-rules-for-different-classes-of-devices","text":"1). Create two different CRUSH Map rules from the CLI, that will accommodate a slow set of devices (HDDs) and a fast set of devices (SDDs): The error of 2 nd is because the cluster does not have any SSD devices. admin:~ # ceph osd crush rule create-replicated slow_devices default host hdd admin:~ # ceph osd crush rule create-replicated fast_devices default host sdd Error EINVAL: device class sdd does not exist 2). Display the details of the new \u201cslow\u201d rule: admin:~ # ceph osd crush rule dump slow_devices { \"rule_id\": 2, \"rule_name\": \"slow_devices\", \"ruleset\": 2, \"type\": 1, \"min_size\": 1, \"max_size\": 10, \"steps\": [ { \"op\": \"take\", \"item\": -2, \"item_name\": \"default~hdd\" }, { \"op\": \"chooseleaf_firstn\", \"num\": 0, \"type\": \"host\" }, { \"op\": \"emit\" } ] }","title":"Task 5: Create CRUSH Map rules for different classes of devices"},{"location":"linux/SES/linux_ses_demo/#task-6-change-the-ruleset-used-by-a-pool","text":"1). Show which CRUSH Map Ruleset is being used by the cephfs_data pool: The rule should be listed as replicated_rule. admin:~ # ceph osd pool get cephfs_data crush_rule crush_rule: replicated_rule 2). Change the cephfs_data pool to use the new CRUSH Map ruleset that you created in the previous task. admin:~ # ceph osd pool set cephfs_data crush_rule better_ruleset set pool 2 crush_rule to better_ruleset 3). Verify that the rule has been changed by re-running the earlier command: admin:~ # ceph osd pool get cephfs_data crush_rule crush_rule: better_ruleset 4). In this demo cluster, making the cephfs_data pool use the \u201cbetter_ruleset\u201d will result in problems. (There\u2019s no rack for the CRUSH Map, and not enough nodes to accommodate the requirement for a large numbgr of PGs.) So change the setting back to the replicated_rule. admin:~ # ceph osd pool set cephfs_data crush_rule replicated_rule set pool 2 crush_rule to replicated_rule admin:~ # ceph osd pool get cephfs_data crush_rule crush_rule: replicated_rule Task 7: Create a CRUSH Map rule enhanced with an EC profile 1). Combine the benefits of Erasure Coding with a CRUSH Map rule: This will only work if you have already created an appropriate EC profile called usable_profile. In this demo you would have done in an earlier exercise. And in this demo you need to tie this ec_rule to the usable_profile, not the better_profile.Or else any pool that you create using the ec_rule will fail due to insufficient resources. admin:~ # ceph osd crush rule create-erasure ec_rule usable_profile Link the CRUSH map rule (ec_rule) to EC profile (usable_profile) created rule ec_rule at 3 P.S., The useable_profile was created by : admin:~ # ceph osd erasure-code-profile set usable_profile k=2 m=1 plugin=jerasure technique=reed_sol_van stripe_unit=4K crush-failure-domain=host 2). Display the details of the EC-enhanced CRUSH Map rule: See the added, extra \u201cop\u201d steps. You might also notice the different values for \u201ctype,\u201d \u201cmin_size,\u201d and \u201cmax_size\u201d than what you saw in the standard replicated rules. admin:~ # ceph osd crush rule dump ec_rule { \"rule_id\": 3, \"rule_name\": \"ec_rule\", \"ruleset\": 3, \"type\": 3, \"min_size\": 3, \"max_size\": 3, \"steps\": [ { \"op\": \"set_chooseleaf_tries\", \"num\": 5 }, { \"op\": \"set_choose_tries\", \"num\": 100 }, { \"op\": \"take\", \"item\": -1, \"item_name\": \"default\" }, { \"op\": \"chooseleaf_indep\", \"num\": 0, \"type\": \"host\" }, { \"op\": \"emit\" } ] } admin:~ # ceph osd crush rule ls replicated_rule better_ruleset slow_devices ec_rule admin:~ # ceph osd crush rule create-replicated better_ruleset default rack admin:~ # ceph osd crush rule create-replicated slow_devices default host hdd admin:~ # ceph osd crush rule create-erasure ec_rule usable_profile admin:~ # ceph osd crush rule dump replicated_rule { \"rule_id\": 0, \"rule_name\": \"replicated_rule\", \"ruleset\": 0, \"type\": 1, \"min_size\": 1, \"max_size\": 10, \"steps\": [ { \"op\": \"take\", \"item\": -1, \"item_name\": \"default\" }, { \"op\": \"chooseleaf_firstn\", \"num\": 0, \"type\": \"host\" }, { \"op\": \"emit\" } ] } admin:~ # ceph osd crush rule dump better_ruleset { \"rule_id\": 1, \"rule_name\": \"better_ruleset\", \"ruleset\": 1, \"type\": 1, \"min_size\": 1, \"max_size\": 10, \"steps\": [ { \"op\": \"take\", \"item\": -1, \"item_name\": \"default\" }, { \"op\": \"chooseleaf_firstn\", \"num\": 0, \"type\": \"rack\" }, { \"op\": \"emit\" } ] } admin:~ # ceph osd crush rule dump slow_devices { \"rule_id\": 2, \"rule_name\": \"slow_devices\", \"ruleset\": 2, \"type\": 1, \"min_size\": 1, \"max_size\": 10, \"steps\": [ { \"op\": \"take\", \"item\": -2, \"item_name\": \"default~hdd\" }, { \"op\": \"chooseleaf_firstn\", \"num\": 0, \"type\": \"host\" }, { \"op\": \"emit\" } ] } admin:~ # ceph osd pool osd pool stats {} osd pool scrub [...] osd pool deep-scrub [...] osd pool repair [...] osd pool force-recovery [...] osd pool force-backfill [...] osd pool cancel-force-recovery [...] osd pool cancel-force-backfill [...] osd pool autoscale-status osd pool mksnap admin:~ # ceph osd pool get size min_size pg_num pgp_num crush_rule Hashpspool Nodelete Nopgchange Nosizechange write_fadvise_dontneed Noscrub nodeep-scrub hit_set_type hit_set_period hit_set_count hit_set_fpp use_gmt_hitset target_max_objects target_max_bytes cache_target_dirty_ratio cache_target_dirty_high_ratio cache_target_full_ratio cache_min_flush_age cache_min_evict_age erasure_code_profile min_read_recency_for_promote All min_write_recency_for_promote fast_read hit_set_grade_decay_rate hit_set_search_last_n scrub_min_interval scrub_max_interval deep_scrub_interval recovery_priority recovery_op_priority scrub_priority compression_mode compression_algorithm compression_required_ratio compression_max_blob_size compression_min_blob_size csum_type csum_min_block csum_max_block allow_ec_overwrites fingerprint_algorithm pg_autoscale_mode pg_autoscale_bias pg_num_min target_size_bytes target_size_ratio","title":"Task 6: Change the ruleset used by a pool"},{"location":"linux/SES/linux_ses_demo/#214-investigate-bluestore","text":"","title":"2.1.4. Investigate BlueStore"},{"location":"linux/SES/linux_ses_demo/#task-1-explore-the-drive_groupsyml-configuration","text":"After deployment, the drive_groups.yml file is where the storage administrator defines the configuration of the cluster\u2019s storage devices. Note the \u201cdata_devices\u201d parameter. In this demo, \u201call\u201d storage devices are data devices for BlueStore. Note that there are no definitions for \u201cwal_devices\u201d or \u201cdb_devices.\u201d That\u2019s because in this demo environment we don\u2019t have any other \u201cfast\u201d devices that would be appropriate for these roles. Since BlueStore is the default, there is no definition of a \u201cformat\u201d for the devices. Otherwise, a \u201cFormat: bluestore\u201d key-value pair might exist to ensure that BlueStore is used. admin:~ # cd /srv/salt/ceph/configuration/files admin:/srv/salt/ceph/configuration/files # cat drive_groups.yml # default: <- just a name - can be anything # target: 'data*' <- must be resolvable by salt's targeting processor # data_devices: # size: 20G # db_devices: # size: 10G # rotational: 1 # allflash: # target: 'fast_nodes*' # data_devices: # size: 100G # db_devices: # size: 50G # rotational: 0 # This is the default configuration and # will create an OSD on all available drives default: target: 'data*' data_devices: all: true","title":"Task 1: Explore the drive_groups.yml configuration"},{"location":"linux/SES/linux_ses_demo/#task-2-examine-a-storage-hosts-storage-devices","text":"admin:~ # ssh data1 Last login: Tue Jan 5 18:06:40 2021 from 10.58.121.181 Should see 3 devices, which are named ceph LVM-type devices data1:~ # lsblk NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINT sda 8:0 0 8G 0 disk \u2514\u2500ceph--14c886af--269d--475f--8ee3--f5e4abbb222d-osd--data--38911b2d--f30a--4b09--9010--8dd6fad2fcc6 254:0 0 8G 0 lvm sdb 8:16 0 8G 0 disk \u2514\u2500ceph--9ec4a77a--5d67--4b21--be53--d7e9221082de-osd--data--00cb3dc6--c28b--41ae--95de--efb86da254da 254:1 0 8G 0 lvm sdc 8:32 0 8G 0 disk \u2514\u2500ceph--5eaea8a8--bb68--49dd--a1e3--b82c5464ab1f-osd--data--a4a05f70--53d9--41d4--a273--4f47a088968a 254:2 0 8G 0 lvm sr0 11:0 1 672M 0 rom vda 253:0 0 20G 0 disk \u251c\u2500vda1 253:1 0 8M 0 part \u251c\u2500vda2 253:2 0 18.4G 0 part / \u2514\u2500vda3 253:3 0 1.7G 0 part [SWAP] See the raw ceph devices data1:~ # ls -lad /dev/ceph* drwxr-xr-x 2 root root 60 Oct 5 13:15 /dev/ceph-14c886af-269d-475f-8ee3-f5e4abbb222d drwxr-xr-x 2 root root 60 Oct 5 13:16 /dev/ceph-5eaea8a8-bb68-49dd-a1e3-b82c5464ab1f drwxr-xr-x 2 root root 60 Oct 5 13:15 /dev/ceph-9ec4a77a-5d67-4b21-be53-d7e9221082de Dig down even farther by examining the content of one of the directories, see a symlink to an LVM device-mapper device. All the devices are tied together with LVM. Note that the name of the symlink is named osd-data- . data1:~ # ls -l /dev/ceph-14c886af-269d-475f-8ee3-f5e4abbb222d lrwxrwxrwx 1 ceph ceph 7 Oct 5 13:15 osd-data-38911b2d-f30a-4b09-9010-8dd6fad2fcc6 -> ../dm-0 data1:~ # l /dev/dm* brw-rw---- 1 ceph ceph 254, 0 Jan 5 18:10 /dev/dm-0 brw-rw---- 1 ceph ceph 254, 1 Jan 5 18:10 /dev/dm-1 brw-rw---- 1 ceph ceph 254, 2 Jan 5 18:10 /dev/dm-2","title":"Task 2: Examine a storage host\u2019s storage devices"},{"location":"linux/SES/linux_ses_demo/#task-3-examine-a-storage-hosts-osd-details","text":"data1:~ # cd /var/lib/ceph/ data1:/var/lib/ceph # ls -l drwxr-x--- 1 ceph ceph 0 Aug 24 22:03 bootstrap-mds drwxr-x--- 1 ceph ceph 0 Aug 24 22:03 bootstrap-mgr drwxr-x--- 1 ceph ceph 24 Oct 5 13:15 bootstrap-osd drwxr-x--- 1 ceph ceph 0 Aug 24 22:03 bootstrap-rbd drwxr-x--- 1 ceph ceph 0 Aug 24 22:03 bootstrap-rbd-mirror drwxr-x--- 1 ceph ceph 0 Aug 24 22:03 bootstrap-rgw drwxr-x--- 1 ceph ceph 12 Oct 5 09:04 crash drwxr-x--- 1 ceph ceph 0 Aug 24 22:03 mds drwxr-x--- 1 ceph ceph 0 Aug 24 22:03 mgr drwxr-x--- 1 ceph ceph 0 Aug 24 22:03 mon drwxr-x--- 1 ceph ceph 38 Oct 5 13:16 osd drwxr-x--- 1 ceph ceph 0 Aug 24 22:03 tmp See 3 different sub-directories, each representing the 3 different OSDs (ceph-2, ceph-6, ceph-10) that are running on this storage server data1:/var/lib/ceph # cd osd/ data1:/var/lib/ceph/osd # ls -l drwxrwxrwt 2 ceph ceph 320 Oct 5 13:16 ceph-10 drwxrwxrwt 2 ceph ceph 320 Oct 5 13:15 ceph-2 drwxrwxrwt 2 ceph ceph 320 Oct 5 13:16 ceph-6 See some functional files associated with the OSD and BlueStore. See a block file, which is a symlink to one of the ceph devices, which stores the raw objects for the OSD. data1:/var/lib/ceph/osd # cd ceph-2 data1:/var/lib/ceph/osd/ceph-2 # ls -l -rw-r--r-- 1 ceph ceph 400 Oct 5 13:15 activate.monmap lrwxrwxrwx 1 ceph ceph 92 Oct 5 13:15 block -> /dev/ceph-14c886af-269d-475f-8ee3-f5e4abbb222d/osd-data-38911b2d-f30a-4b09-9010-8dd6fad2fcc6 -rw------- 1 ceph ceph 2 Oct 5 13:15 bluefs -rw------- 1 ceph ceph 37 Oct 5 13:15 ceph_fsid -rw-r--r-- 1 ceph ceph 37 Oct 5 13:15 fsid -rw------- 1 ceph ceph 55 Oct 5 13:15 keyring -rw------- 1 ceph ceph 8 Oct 5 13:15 kv_backend -rw------- 1 ceph ceph 21 Oct 5 13:15 magic -rw------- 1 ceph ceph 4 Oct 5 13:15 mkfs_done -rw------- 1 ceph ceph 41 Oct 5 13:15 osd_key -rw------- 1 ceph ceph 6 Oct 5 13:15 ready -rw------- 1 ceph ceph 3 Oct 5 13:15 require_osd_release -rw------- 1 ceph ceph 10 Oct 5 13:15 type -rw------- 1 ceph ceph 2 Oct 5 13:15 whoami data1:/var/lib/ceph/osd/ceph-2 # cat ceph_fsid # The unique ID of this Ceph cluster 343ee7d3-232f-4c71-8216-1edbc55ac6e0 data1:/var/lib/ceph/osd/ceph-2 # cat fsid # The unique ID of this OSD 6df58ebc-dbfe-4822-9714-90212c06ea05 data1:/var/lib/ceph/osd/ceph-2 # cat keyring # The Ceph key for this OSD [osd.2] key = data1:/var/lib/ceph/osd/ceph-2 # cat ready # Indication of the readiness of this OSD ready data1:/var/lib/ceph/osd/ceph-2 # cat type # filestore or bluestore (in this case: bluestore) bluestore data1:/var/lib/ceph/osd/ceph-2 # cat whoami # The integer id of this OSD (in this case: 2) 2","title":"Task 3: Examine a storage host\u2019s OSD details"},{"location":"linux/SES/linux_ses_demo/#task-4-display-bluestore-information-using-ceph-bluestore-tool","text":"Show BlueStore metadata for osd.2: data1:/var/lib/ceph/osd/ceph-2 # ceph-bluestore-tool show-label --path /var/lib/ceph/osd/ceph-2 inferring bluefs devices from bluestore path { \"/var/lib/ceph/osd/ceph-2/block\": { \"osd_uuid\": \"6df58ebc-dbfe-4822-9714-90212c06ea05\", \"size\": 8585740288, \"btime\": \"2020-10-05 13:15:51.227799\", \"description\": \"main\", \"bluefs\": \"1\", \"ceph_fsid\": \"343ee7d3-232f-4c71-8216-1edbc55ac6e0\", \"kv_backend\": \"rocksdb\", \"magic\": \"ceph osd volume v026\", \"mkfs_done\": \"yes\", \"osd_key\": , \"ready\": \"ready\", \"require_osd_release\": \"14\", \"whoami\": \"2\" } Run a manual \u201cscrub\u201d on osd.7 using ceph-blestore-tool. (Received error, the tool won\u2019t allow you to do this while the OSD is running.) data1:/var/lib/ceph/osd/ceph-2 # ceph-bluestore-tool fsck --path /var/lib/ceph/osd/ceph-2 error from fsck: (11) Resource temporarily unavailable 2021-01-05 18:32:25.528 7f4abad6e180 -1 bluestore(/var/lib/ceph/osd/ceph-2) _lock_fsid failed to lock /var/lib/ceph/osd/ceph-2/fsid (is another ceph-osd still running?)(11) Resource temporarily unavailable Simulate that the OSD is down, shutdown the OSD: data1:/var/lib/ceph/osd/ceph-2 # systemctl stop ceph-osd@2.service Now run the \u201cfsck\u201d command again. This time the \u201cfsck\u201d has worked, with the output showing: \u201cfsck success\u201d data1:/var/lib/ceph/osd/ceph-2 # ceph-bluestore-tool fsck --path /var/lib/ceph/osd/ceph-2 fsck success Restart the OSD: data1:/var/lib/ceph/osd/ceph-2 # systemctl start ceph-osd@2.service data1:/var/lib/ceph/osd/ceph-2 # ceph-bluestore-tool show-label --path /var/lib/ceph/osd/ceph-2 inferring bluefs devices from bluestore path { \"/var/lib/ceph/osd/ceph-2/block\": { \"osd_uuid\": \"6df58ebc-dbfe-4822-9714-90212c06ea05\", \"size\": 8585740288, \"btime\": \"2020-10-05 13:15:51.227799\", \"description\": \"main\", \"bluefs\": \"1\", \"ceph_fsid\": \"343ee7d3-232f-4c71-8216-1edbc55ac6e0\", \"kv_backend\": \"rocksdb\", \"magic\": \"ceph osd volume v026\", \"mkfs_done\": \"yes\", \"osd_key\": , \"ready\": \"ready\", \"require_osd_release\": \"14\", \"whoami\": \"2\" } }","title":"Task 4: Display BlueStore information using ceph-bluestore-tool"},{"location":"linux/SES/linux_ses_demo/#22-common-day-1-tasks-using-the-cli","text":"Including ollowing topics in relation to the commandline: Users and Ceph Configuration Health commands Erasure Code Profiles CRUSH Map rules Pools Scrubbing OSDs and Placement Groups Manager modules The tell commands","title":"2.2. Common Day 1 Tasks Using the CLI"},{"location":"linux/SES/linux_ses_demo/#221-ceph-users-and-configuration","text":"","title":"2.2.1. Ceph Users and Configuration"},{"location":"linux/SES/linux_ses_demo/#task-1-view-the-current-user-keyrings","text":"Ceph keyrings are stored in below directory admin:~ # cd /etc/ceph/ admin:/etc/ceph # ls -l -rw------- 1 root root 151 Oct 5 13:13 ceph.client.admin.keyring -rw-r--r-- 1 root root 980 Oct 5 13:13 ceph.conf -rw-r--r-- 1 root root 92 Aug 24 22:03 rbdmap The value of 'key' is the key that\u2019s on the keyring. The admin keyring is \u201callow\u201ded all capabilities (permissions) to all services in the cluster, as expected. there are more than just client keys. admin:/etc/ceph # cat ceph.client.admin.keyring [client.admin] key = caps mds = \"allow *\" caps mon = \"allow *\" caps osd = \"allow *\" caps mgr = \"allow *\" Display the existing users with the \u201cauth\u201d command: Below two commands are equivalent admin:/etc/ceph # ceph -n client.admin -keyring=/etc/ceph/ceph.client.admin.keyring auth ls -- failed??? no valid command found admin:/etc/ceph # ceph auth ls installed auth entries: mds.mon1 key: caps: [mds] allow * caps: [mgr] allow profile mds caps: [mon] allow profile mds caps: [osd] allow rwx mds.mon2 key: caps: [mds] allow * caps: [mgr] allow profile mds caps: [mon] allow profile mds caps: [osd] allow rwx mds.mon3 key: caps: [mds] allow * caps: [mgr] allow profile mds caps: [mon] allow profile mds caps: [osd] allow rwx osd.0 key: caps: [mgr] allow profile osd caps: [mon] allow profile osd caps: [osd] allow * osd.1 key: caps: [mgr] allow profile osd caps: [mon] allow profile osd caps: [osd] allow * osd.10 key: caps: [mgr] allow profile osd caps: [mon] allow profile osd caps: [osd] allow * osd.11 key: caps: [mgr] allow profile osd caps: [mon] allow profile osd caps: [osd] allow * osd.2 key: caps: [mgr] allow profile osd caps: [mon] allow profile osd caps: [osd] allow * osd.3 key: caps: [mgr] allow profile osd caps: [mon] allow profile osd caps: [osd] allow * osd.4 key: caps: [mgr] allow profile osd caps: [mon] allow profile osd caps: [osd] allow * osd.5 key: caps: [mgr] allow profile osd caps: [mon] allow profile osd caps: [osd] allow * osd.6 key: caps: [mgr] allow profile osd caps: [mon] allow profile osd caps: [osd] allow * osd.7 key: caps: [mgr] allow profile osd caps: [mon] allow profile osd caps: [osd] allow * osd.8 key: caps: [mgr] allow profile osd caps: [mon] allow profile osd caps: [osd] allow * osd.9 key: caps: [mgr] allow profile osd caps: [mon] allow profile osd caps: [osd] allow * client.admin key: caps: [mds] allow * caps: [mgr] allow * caps: [mon] allow * caps: [osd] allow * client.bootstrap-mds key: caps: [mon] allow profile bootstrap-mds client.bootstrap-mgr key: caps: [mon] allow profile bootstrap-mgr client.bootstrap-osd key: caps: [mgr] allow r caps: [mon] allow profile bootstrap-osd client.bootstrap-rbd key: caps: [mon] allow profile bootstrap-rbd client.bootstrap-rbd-mirror key: caps: [mon] allow profile bootstrap-rbd-mirror client.bootstrap-rgw key: caps: [mon] allow profile bootstrap-rgw client.igw.mon2 key: caps: [mgr] allow r caps: [mon] allow * caps: [osd] allow * client.rgw.mon3 key: caps: [mgr] allow r caps: [mon] allow rwx caps: [osd] allow rwx client.storage key: caps: [mon] allow rw mgr.mon1 key: caps: [mds] allow * caps: [mon] allow profile mgr caps: [osd] allow *","title":"Task 1: View the current user keyrings"},{"location":"linux/SES/linux_ses_demo/#task-2-create-a-new-keyring-and-associated-user","text":"1). There are several different ways to create a new keyring and user. This is just one way. Create a new keyring and associated user named James . Remembgr that typically all new users will need read rights for the mon capability, and will need read/write rights for the osd capability, including a specification of rights to a pool. admin:/etc/ceph # ceph-authtool -g -n client.james --cap mon 'allow r' --cap osd 'allow rw pool=iscsi-images' -C /etc/ceph/ceph.client.james.keyring creating /etc/ceph/ceph.client.james.keyring admin:/etc/ceph # l total 16 drwxr-xr-x 1 root root 130 Jan 5 19:31 ./ drwxr-xr-x 1 root root 4392 Oct 5 13:03 ../ -rw------- 1 root root 151 Oct 5 13:13 ceph.client.admin.keyring -rw------- 1 root root 126 Jan 5 19:31 ceph.client.james.keyring -rw-r--r-- 1 root root 980 Oct 5 13:13 ceph.conf -rw-r--r-- 1 root root 92 Aug 24 22:03 rbdmap 2). Show the content of the newly created keyring: admin:/etc/ceph # cat ceph.client.james.keyring [client.james] key = caps mon = \"allow r\" caps osd = \"allow rw pool=iscsi-images\" 3). Officially add the new keyring to Ceph: admin:/etc/ceph # ceph auth add client.james -i /etc/ceph/ceph.client.james.keyring added key for client.james 4). Show the key information using the \u201cauth\u201d function: admin:/etc/ceph # ceph auth get client.james exported keyring for client.james [client.james] key = caps mon = \"allow r\" caps osd = \"allow rw pool=iscsi-images\"","title":"Task 2: Create a new keyring and associated user"},{"location":"linux/SES/linux_ses_demo/#task-3-create-a-client-key-for-rbd","text":"1). Change to the directory that contains the ceph keyrings. admin:~ # cd /etc/ceph/ 2). List the content of the directory: Although you see the admin users\u2019s keyring, ceph.client.admin.keyring, there is not yet a file that is appropriate for a specific application to use. Also note that the permissions on the keyring file are quite restrictive: 0600 admin:/etc/ceph # ls -l -rw------- 1 root root 151 Oct 5 13:13 ceph.client.admin.keyring -rw------- 1 root root 126 Jan 5 19:31 ceph.client.james.keyring -rw-r--r-- 1 root root 980 Oct 5 13:13 ceph.conf -rw-r--r-- 1 root root 92 Aug 24 22:03 rbdmap 3). Show the content of the admin user\u2019s keyring: You will use the value associated with the \u201ckey\u201d key to create a new file. Copy the \u201ckey\u201d value using your favorite method. admin:/etc/ceph # cat ceph.client.admin.keyring [client.admin] key = caps mds = \"allow *\" caps mon = \"allow *\" caps osd = \"allow *\" caps mgr = \"allow *\" 4). Open a new file for editing called admin.secret using your favorite editor (such as vi): The name of the file isn\u2019t very important, but naming it this way will help to identify its purpose: it\u2019s a secret key for the admin user. Note that there are many ways to do this. An alternative way is mentioned in the tip below that will do this in one step using grep and awk. admin:/etc/ceph # vi admin.secret 5). Paste the \u201ckey\u201d value into the new file. It will be the only content of the file. It will look like this (in fact it\u2019s probably exactly the same as this, if you\u2019re using the demo environment provided to you): admin:/etc/ceph # cat admin.secret 6). Save the file and exist out of the editor. 7). Change the permissions of the file so that no other user on the host can see the content of the file: admin:/etc/ceph # chmod 0600 admin.secret admin:/etc/ceph # l drwxr-xr-x 1 root root 154 Jan 5 20:03 ./ drwxr-xr-x 1 root root 4392 Oct 5 13:03 ../ -rw------- 1 root root 41 Jan 5 20:03 admin.secret -rw------- 1 root root 151 Oct 5 13:13 ceph.client.admin.keyring -rw------- 1 root root 126 Jan 5 19:31 ceph.client.james.keyring -rw-r--r-- 1 root root 980 Oct 5 13:13 ceph.conf -rw-r--r-- 1 root root 92 Aug 24 22:03 rbdmap Tip: An alternative way to create this key file is to simply use grep/awk together in one bash command, like this: admin:/etc/ceph # grep \"key =\" ceph.client.admin.keyring | awk -F\" = \" '{ print $2 }' admin:/etc/ceph # grep \"key =\" ceph.client.admin.keyring | awk -F\" = \" '{ print $2 }' > admin.secret admin:/etc/ceph # cat admin.secret ","title":"Task 3: Create a client key for RBD"},{"location":"linux/SES/linux_ses_demo/#task-4-view-the-ceph-master-configuration-file","text":"View the content of the file. The file is managed and controlled by DeepSea. The comment makes reference to the control files in the /srv/salt/ceph/configuration/ directory hierarchy. This is a very simple storage cluster. In a more diverse and sophisticated ceph cluster there may be more configuration settings defined. Although this exercise doesn\u2019t call out any more specific information about this configuration file, you may take a moment to consider the content of the file before finishing the task. admin:/etc/ceph # cat ceph.conf # DeepSea default configuration. Changes in this file will be overwritten on # package update. Include custom configuration fragments in # /srv/salt/ceph/configuration/files/ceph.conf.d/[global,osd,mon,mgr,mds,client].conf [global] fsid = 343ee7d3-232f-4c71-8216-1edbc55ac6e0 mon_initial_membgrs = mon1, mon2, mon3 mon_host = 10.58.121.186, 10.58.121.187, 10.58.121.188 auth_cluster_required = cephx auth_service_required = cephx auth_client_required = cephx public_network = 10.58.120.0/23 cluster_network = 10.58.120.0/23 ms_bind_msgr2 = false # enable old ceph health format in the json output. This fixes the # ceph_exporter. This option will only stay until the prometheus plugin takes # over mon_health_preluminous_compat = true mon health preluminous compat warning = false rbd default features = 3 [client.rgw.mon3] rgw frontends = \"beast port=80\" rgw dns name = mon3.sha.me.corp rgw enable usage log = true [osd] [mon] [mgr] [mds] [client] admin:/etc/ceph # ls -l /srv/salt/ceph/configuration/ drwxr-xr-x 1 salt salt 18 Oct 5 13:13 cache drwxr-xr-x 1 root root 38 Oct 5 09:04 check drwxr-xr-x 1 root root 74 Oct 5 09:04 create -rw-r--r-- 1 root root 217 May 14 2020 default-import.sls -rw-r--r-- 1 root root 222 May 14 2020 default.sls drwxr-xr-x 1 root root 276 Oct 5 12:55 files -rw-r--r-- 1 root root 74 May 14 2020 init.sls","title":"Task 4: View the Ceph master configuration file"},{"location":"linux/SES/linux_ses_demo/#222-run-the-ceph-health-commands","text":"Get overall health status admin:~ # ceph health HEALTH_OK admin:~ # ceph -s admin:~ # ceph status cluster: id: 343ee7d3-232f-4c71-8216-1edbc55ac6e0 health: HEALTH_OK services: mon: 3 daemons, quorum mon1,mon2,mon3 (age 9w) mgr: mon1(active, since 5w) mds: cephfs:1 {0=mon3=up:active} 2 up:standby osd: 12 osds: 12 up (since 98m), 12 in (since 3M) rgw: 1 daemon active (mon3) task status: scrub status: mds.mon3: idle data: pools: 7 pools, 208 pgs objects: 246 objects, 4.7 KiB usage: 14 GiB used, 82 GiB / 96 GiB avail pgs: 208 active+clean io: client: 852 B/s rd, 0 op/s rd, 0 op/s wr Run the \u201cstatus\u201d command for the monitors: admin:~ # ceph mon stat e1: 3 mons at { mon1=[v2:10.58.121.186:3300/0,v1:10.58.121.186:6789/0], mon2=[v2:10.58.121.187:3300/0,v1:10.58.121.187:6789/0], mon3=[v2:10.58.121.188:3300/0,v1:10.58.121.188:6789/0] }, election epoch 22, leader 0 mon1, quorum 0,1,2 mon1,mon2,mon3 Run the \u201cstatus\u201d command for the placement groups: admin:~ # ceph pg stat 208 pgs: 208 active+clean; 4.7 KiB data, 2.1 GiB used, 82 GiB / 96 GiB avail; 852 B/s rd, 0 op/s Run the ceph \u201cstatus\u201d command while watching for changes to the status: admin:~ # ceph -s --watch-debug cluster: id: 343ee7d3-232f-4c71-8216-1edbc55ac6e0 health: HEALTH_OK services: mon: 3 daemons, quorum mon1,mon2,mon3 (age 9w) mgr: mon1(active, since 5w) mds: cephfs:1 {0=mon3=up:active} 2 up:standby osd: 12 osds: 12 up (since 104m), 12 in (since 3M) rgw: 1 daemon active (mon3) task status: scrub status: mds.mon3: idle data: pools: 7 pools, 208 pgs objects: 246 objects, 4.7 KiB usage: 14 GiB used, 82 GiB / 96 GiB avail pgs: 208 active+clean io: client: 1.2 KiB/s rd, 1 op/s rd, 0 op/s wr 2021-01-05 20:20:53.947298 mgr.mon1 [DBG] pgmap v1597415: 208 pgs: 208 active+clean; 4.7 KiB data, 2.1 GiB used, 82 GiB / 96 GiB avail; 852 B/s rd, 0 op/s 2021-01-05 20:20:55.949294 mgr.mon1 [DBG] pgmap v1597416: 208 pgs: 208 active+clean; 4.7 KiB data, 2.1 GiB used, 82 GiB / 96 GiB avail; 1.2 KiB/s rd, 1 op/s .......","title":"2.2.2. Run the Ceph Health Commands"},{"location":"linux/SES/linux_ses_demo/#223-manipulate-pools","text":"","title":"2.2.3. Manipulate Pools"},{"location":"linux/SES/linux_ses_demo/#task-1-display-a-list-of-the-current-pools","text":"admin:~ # ceph osd pool ls iscsi-images cephfs_data cephfs_metadata .rgw.root default.rgw.control default.rgw.meta default.rgw.log admin:~ # ceph osd pool ls detail pool 1 'iscsi-images' replicated size 3 min_size 2 crush_rule 0 object_hash rjenkins pg_num 32 pgp_num 32 autoscale_mode on last_change 448 lfor 0/448/446 flags hashpspool stripe_width 0 application rbd pool 2 'cephfs_data' replicated size 3 min_size 2 crush_rule 0 object_hash rjenkins pg_num 32 pgp_num 32 last_change 1395 lfor 0/1374/1372 flags hashpspool stripe_width 0 application cephfs pool 3 'cephfs_metadata' replicated size 3 min_size 2 crush_rule 0 object_hash rjenkins pg_num 16 pgp_num 16 last_change 1385 lfor 0/975/973 flags hashpspool stripe_width 0 pg_autoscale_bias 4 pg_num_min 16 recovery_priority 5 application cephfs pool 4 '.rgw.root' replicated size 3 min_size 2 crush_rule 0 object_hash rjenkins pg_num 32 pgp_num 32 autoscale_mode warn last_change 31 flags hashpspool stripe_width 0 application rgw pool 5 'default.rgw.control' replicated size 3 min_size 2 crush_rule 0 object_hash rjenkins pg_num 32 pgp_num 32 autoscale_mode warn last_change 33 flags hashpspool stripe_width 0 application rgw pool 6 'default.rgw.meta' replicated size 3 min_size 2 crush_rule 0 object_hash rjenkins pg_num 32 pgp_num 32 autoscale_mode warn last_change 35 flags hashpspool stripe_width 0 application rgw pool 7 'default.rgw.log' replicated size 3 min_size 2 crush_rule 0 object_hash rjenkins pg_num 32 pgp_num 32 autoscale_mode warn last_change 37 flags hashpspool stripe_width 0 application rgw List pools with their index numbgr. Note how the index numbgr matches the index numbgr of the detail listing above. admin:~ # ceph osd lspools 1 iscsi-images 2 cephfs_data 3 cephfs_metadata 4 .rgw.root 5 default.rgw.control 6 default.rgw.meta 7 default.rgw.log","title":"Task 1: Display a list of the current pools"},{"location":"linux/SES/linux_ses_demo/#task-2-display-the-usage-data-and-stats-of-the-current-pools","text":"Display pool usages. Note again index \u201cID\u201d for the pool. admin:~ # ceph df RAW STORAGE: CLASS SIZE AVAIL USED RAW USED %RAW USED hdd 96 GiB 82 GiB 2.1 GiB 14 GiB 14.81 TOTAL 96 GiB 82 GiB 2.1 GiB 14 GiB 14.81 POOLS: POOL ID STORED OBJECTS USED %USED MAX AVAIL iscsi-images 1 389 B 2 192 KiB 0 25 GiB cephfs_data 2 0 B 0 0 B 0 25 GiB cephfs_metadata 3 7.2 KiB 48 1.5 MiB 0 25 GiB .rgw.root 4 1.2 KiB 4 768 KiB 0 25 GiB default.rgw.control 5 0 B 8 0 B 0 25 GiB default.rgw.meta 6 381 B 3 576 KiB 0 25 GiB default.rgw.log 7 35 KiB 208 35 KiB 0 25 GiB admin:~ # ceph df detail RAW STORAGE: CLASS SIZE AVAIL USED RAW USED %RAW USED hdd 96 GiB 82 GiB 2.1 GiB 14 GiB 14.81 TOTAL 96 GiB 82 GiB 2.1 GiB 14 GiB 14.81 POOLS: POOL ID STORED OBJECTS USED %USED MAX AVAIL QUOTA OBJECTS QUOTA BYTES DIRTY USED COMPR UNDER COMPR iscsi-images 1 389 B 2 192 KiB 0 25 GiB N/A N/A 2 0 B 0 B cephfs_data 2 0 B 0 0 B 0 25 GiB N/A N/A 0 0 B 0 B cephfs_metadata 3 7.2 KiB 48 1.5 MiB 0 25 GiB N/A N/A 48 0 B 0 B .rgw.root 4 1.2 KiB 4 768 KiB 0 25 GiB N/A N/A 4 0 B 0 B default.rgw.control 5 0 B 8 0 B 0 25 GiB N/A N/A 8 0 B 0 B default.rgw.meta 6 381 B 3 576 KiB 0 25 GiB N/A N/A 3 0 B 0 B default.rgw.log 7 35 KiB 208 35 KiB 0 25 GiB N/A N/A 208 0 B 0 B Display pool usages using rados command admin:~ # rados df POOL_NAME USED OBJECTS CLONES COPIES MISSING_ON_PRIMARY UNFOUND DEGRADED RD_OPS RD WR_OPS WR USED COMPR UNDER COMPR .rgw.root 768 KiB 4 0 12 0 0 0 40 40 KiB 4 4 KiB 0 B 0 B cephfs_data 0 B 0 0 0 0 0 0 0 0 B 0 0 B 0 B 0 B cephfs_metadata 1.5 MiB 48 0 144 0 0 0 0 0 B 111 42 KiB 0 B 0 B default.rgw.control 0 B 8 0 24 0 0 0 0 0 B 0 0 B 0 B 0 B default.rgw.log 35 KiB 208 0 624 0 0 0 5919671 5.6 GiB 3945118 946 KiB 0 B 0 B default.rgw.meta 576 KiB 3 0 9 0 0 0 38 28 KiB 4 3 KiB 0 B 0 B iscsi-images 192 KiB 2 0 6 0 0 0 4184657 4.0 GiB 8 2 KiB 0 B 0 B total_objects 246 total_used 14 GiB total_avail 82 GiB total_space 96 GiB Show the statistics of the pools: admin:~ # ceph osd pool stats pool iscsi-images id 1 client io 1.2 KiB/s rd, 1 op/s rd, 0 op/s wr pool cephfs_data id 2 nothing is going on pool cephfs_metadata id 3 nothing is going on pool .rgw.root id 4 nothing is going on pool default.rgw.control id 5 nothing is going on pool default.rgw.meta id 6 nothing is going on pool default.rgw.log id 7 nothing is going on Show only the statistics about a specific pool: admin:~ # ceph osd pool stats .rgw.root pool .rgw.root id 4 nothing is going on Show which CRUSH Map ruleset was used to create the .rgw.root pool: admin:~ # ceph osd pool get .rgw.root crush_rule crush_rule: replicated_rule Show the list of all the attributes of a pool that can be queried: admin:~ # ceph osd pool get .rgw.root size min_size pg_num pgp_num crush_rule Hashpspool Nodelete Nopgchange Nosizechange write_fadvise_dontneed noscrub|nodeep-scrub hit_set_type hit_set_period hit_set_count hit_set_fpp use_gmt_hitset target_max_objects target_max_bytes cache_target_dirty_ratio cache_target_dirty_high_ratio cache_target_full_ratio cache_min_flush_age cache_min_evict_age erasure_code_profile min_read_recency_for_promote all|min_write_recency_for_promote fast_read|hit_set_grade_decay_rate hit_set_search_last_n scrub_min_interval scrub_max_interval deep_scrub_interval recovery_priority recovery_op_priority scrub_priority compression_mode compression_algorithm compression_required_ratio compression_max_blob_size compression_min_blob_size csum_type|csum_min_block csum_max_block allow_ec_overwrites fingerprint_algorithm pg_autoscale_mode pg_autoscale_bias pg_num_min target_size_bytes target_size_ratio","title":"Task 2: Display the usage data and stats of the current pools"},{"location":"linux/SES/linux_ses_demo/#task-3-create-two-new-pools-one-replicated-one-ec","text":"1). Create a new replicated pool that will be used for storing block data for RBD. Use the standard replicated_ruleset CRUSH Map: It would be tempting to the use the better_ruleset, but this demo environment doesn\u2019t have enough resources for that. This is a demo environment, so the PG numbgrs will be low. In your production environments, be sure to assign an appropriately high numbgr, or use the pg_autoscaler manager module. admin:~ # ceph osd pool create rbd_pool 4 4 replicated replicated_rule pool 'rbd_pool' created 2). Tell the cluster that you expect to have this new rbd_pool to use 50% of the total capacity: admin:~ # ceph osd pool set rbd_pool target_size_ratio .5 set pool 8 target_size_ratio to .5 3). Create a new EC pool that will be used for storing RGW buckets and objects. Use the usable_profile Erasure Code profile that was created in an earlier exercise. And use the ec_rule CRUSH Map ruleset that was created in an earlier exercise: admin:~ # ceph osd pool create bucket_pool 4 4 erasure usable_profile ec_rule pool 'bucket_pool' created 4). Tell the cluster that you expect to have this new bucket_pool to use 100GB of data: POOL_TARGET_SIZE_BYTES_OVERCOMMITTED admin:~ # ceph osd pool set bucket_pool target_size_bytes 100000000000 set pool 9 target_size_bytes to 100000000000 5). Enable the PG Autoscaler feature on the two new pools, to ensure that we have an appropriate assignment of placement groups in the demo cluster: This presumes that you completed an earlier exercise that enable the pg_autoscaler manager module. admin:~ # ceph osd pool set bucket_pool pg_autoscale_mode on set pool 9 pg_autoscale_mode to on admin:~ # ceph osd pool set rbd_pool pg_autoscale_mode on set pool 8 pg_autoscale_mode to on 6). Again display a list of all the pools, which will now include the two new pools that you\u2019ve just created: Notice in the detail listing that the two new pools don\u2019t have an application attribute assigned to them. admin:~ # ceph osd lspools 1 iscsi-images 2 cephfs_data 3 cephfs_metadata 4 .rgw.root 5 default.rgw.control 6 default.rgw.meta 7 default.rgw.log 8 rbd_pool 9 bucket_pool admin:~ # ceph osd pool ls detail pool 1 'iscsi-images' replicated size 3 min_size 2 crush_rule 0 object_hash rjenkins pg_num 32 pgp_num 32 autoscale_mode on last_change 448 lfor 0/448/446 flags hashpspool stripe_width 0 application rbd pool 2 'cephfs_data' replicated size 3 min_size 2 crush_rule 0 object_hash rjenkins pg_num 32 pgp_num 32 last_change 1395 lfor 0/1374/1372 flags hashpspool stripe_width 0 application cephfs pool 3 'cephfs_metadata' replicated size 3 min_size 2 crush_rule 0 object_hash rjenkins pg_num 16 pgp_num 16 last_change 1385 lfor 0/975/973 flags hashpspool stripe_width 0 pg_autoscale_bias 4 pg_num_min 16 recovery_priority 5 application cephfs pool 4 '.rgw.root' replicated size 3 min_size 2 crush_rule 0 object_hash rjenkins pg_num 32 pgp_num 32 autoscale_mode warn last_change 31 flags hashpspool stripe_width 0 application rgw pool 5 'default.rgw.control' replicated size 3 min_size 2 crush_rule 0 object_hash rjenkins pg_num 32 pgp_num 32 autoscale_mode warn last_change 33 flags hashpspool stripe_width 0 application rgw pool 6 'default.rgw.meta' replicated size 3 min_size 2 crush_rule 0 object_hash rjenkins pg_num 32 pgp_num 32 autoscale_mode warn last_change 35 flags hashpspool stripe_width 0 application rgw pool 7 'default.rgw.log' replicated size 3 min_size 2 crush_rule 0 object_hash rjenkins pg_num 32 pgp_num 32 autoscale_mode warn last_change 37 flags hashpspool stripe_width 0 application rgw pool 8 'rbd_pool' replicated size 3 min_size 2 crush_rule 0 object_hash rjenkins pg_num 32 pgp_num 32 autoscale_mode on last_change 1415 lfor 0/0/1413 flags hashpspool stripe_width 0 target_size_ratio 0.5 pool 9 'bucket_pool' erasure size 3 min_size 2 crush_rule 3 object_hash rjenkins pg_num 4 pgp_num 4 autoscale_mode on last_change 1410 flags hashpspool stripe_width 8192 target_size_bytes 100000000000 7). Check the pg_autoscale status, particularly to see a comparison of how much raw space is being consumed by the two pools: See that the RATE column for all of the replicated pools shows the value of 3.0, while the value for the bucket_pool \u2013 which is an EC pool \u2013 is 1.5. The EC pool, with a K+M of 2+1 consumes considerably less raw storage space. See the TARGET RATIO for the rbd_pool. Notice that the autoscaler has automatically adjusted the numbgr PGs assigned to rbd_pool from \u201c4\u201d to \u201c128\u201d because you told the cluster to have the pool use 50% of the capacity. See the TARGET SIZE for the bucket_pool, roughly 100GB. But the cluster may not have changed the PG_NUM value yet. The autoscaler will adjust the numbgr of PGs gradually, so as not to disrupt the performance too dramatically. While you\u2019re here, you might also notice the RAW CAPACITY column. All pools are expecting to divide the cluster space equally, even though you\u2019ve explicitly told the cluster that rbd_pool and bucket_pool will deviate from that even division. admin:~ # ceph osd pool autoscale-status POOL SIZE TARGET SIZE RATE RAW CAPACITY RATIO TARGET RATIO EFFECTIVE RATIO BIAS PG_NUM NEW PG_NUM AUTOSCALE iscsi-images 389 3.0 98256M 0.0000 1.0 32 on cephfs_data 0 3.0 98256M 0.0000 1.0 32 off cephfs_metadata 7412 3.0 98256M 0.0000 4.0 16 off .rgw.root 1245 3.0 98256M 0.0000 1.0 32 warn default.rgw.control 0 3.0 98256M 0.0000 1.0 32 warn default.rgw.meta 381 3.0 98256M 0.0000 1.0 32 warn default.rgw.log 35900 3.0 98256M 0.0000 1.0 32 warn rbd_pool 0 3.0 98256M 0.0000 0.5000 1.0 32 on bucket_pool 0 95367M 1.5 98256M 1.4559 1.0 4 on","title":"Task 3: Create two new pools, one replicated, one EC"},{"location":"linux/SES/linux_ses_demo/#task-4-assign-an-application-to-the-two-new-pools","text":"1). Assign the rbd application to the new rbd_pool that you created in the previous task: admin:~ # ceph osd pool application enable rbd_pool rbd enabled application 'rbd' on pool 'rbd_pool' 2). Instruct the cluster to prepare the new rbd_pool for storing block device images: admin:~ # rbd pool init rbd_pool 3). Assign the rgw application to the new bucket_pool that you created in the previous task: admin:~ # ceph osd pool application enable bucket_pool rgw enabled application 'rgw' on pool 'bucket_pool' 4). Display a list of all the pools again, this time noticing that the application attribute is set on the two new pools. admin:~ # ceph osd lspools 1 iscsi-images 2 cephfs_data 3 cephfs_metadata 4 .rgw.root 5 default.rgw.control 6 default.rgw.meta 7 default.rgw.log 8 rbd_pool 9 bucket_pool admin:~ # ceph osd pool ls detail pool 1 'iscsi-images' replicated size 3 min_size 2 crush_rule 0 object_hash rjenkins pg_num 32 pgp_num 32 autoscale_mode on last_change 448 lfor 0/448/446 flags hashpspool stripe_width 0 application rbd pool 2 'cephfs_data' replicated size 3 min_size 2 crush_rule 0 object_hash rjenkins pg_num 32 pgp_num 32 last_change 1395 lfor 0/1374/1372 flags hashpspool stripe_width 0 application cephfs pool 3 'cephfs_metadata' replicated size 3 min_size 2 crush_rule 0 object_hash rjenkins pg_num 16 pgp_num 16 last_change 1385 lfor 0/975/973 flags hashpspool stripe_width 0 pg_autoscale_bias 4 pg_num_min 16 recovery_priority 5 application cephfs pool 4 '.rgw.root' replicated size 3 min_size 2 crush_rule 0 object_hash rjenkins pg_num 32 pgp_num 32 autoscale_mode warn last_change 31 flags hashpspool stripe_width 0 application rgw pool 5 'default.rgw.control' replicated size 3 min_size 2 crush_rule 0 object_hash rjenkins pg_num 32 pgp_num 32 autoscale_mode warn last_change 33 flags hashpspool stripe_width 0 application rgw pool 6 'default.rgw.meta' replicated size 3 min_size 2 crush_rule 0 object_hash rjenkins pg_num 32 pgp_num 32 autoscale_mode warn last_change 35 flags hashpspool stripe_width 0 application rgw pool 7 'default.rgw.log' replicated size 3 min_size 2 crush_rule 0 object_hash rjenkins pg_num 32 pgp_num 32 autoscale_mode warn last_change 37 flags hashpspool stripe_width 0 application rgw pool 8 'rbd_pool' replicated size 3 min_size 2 crush_rule 0 object_hash rjenkins pg_num 32 pgp_num 32 autoscale_mode on last_change 1420 lfor 0/0/1413 flags hashpspool,selfmanaged_snaps stripe_width 0 target_size_ratio 0.5 application rbd removed_snaps [1~3] pool 9 'bucket_pool' erasure size 3 min_size 2 crush_rule 3 object_hash rjenkins pg_num 4 pgp_num 4 autoscale_mode on last_change 1422 flags hashpspool stripe_width 8192 target_size_bytes 100000000000 application rgw 5). Another way to display which application is assigned to a pool is: admin:~ # ceph osd pool application get bucket_pool { \"rgw\": {} } admin:~ # ceph osd pool application get rbd_pool { \"rbd\": {} }","title":"Task 4: Assign an application to the two new pools"},{"location":"linux/SES/linux_ses_demo/#task-5-manage-snapshots-of-the-new-rgw-bucket-pool","text":"1). Display a list of the snapshots that exist of the bucket_pool that you created in the previous task: The output show that there are \u201c0 snaps.\u201d Right, it is a little funny that you only list the snapshots with rados command; no such functionality exists with the ceph osd pool command. admin:~ # rados -p bucket_pool lssnap 0 snaps 2). Take (make) a snapshot of the rbd_pool: admin:~ # ceph osd pool mksnap bucket_pool brand_new_pool_snapshot created pool bucket_pool snap brand_new_pool_snapshot 3). Display the list of the snapshots again: admin:~ # rados -p bucket_pool lssnap 1 brand_new_pool_snapshot 2021.01.05 22:23:23 1 snaps 4). Remove the snapshot: admin:~ # ceph osd pool rmsnap bucket_pool brand_new_pool_snapshot removed pool bucket_pool snap brand_new_pool_snapshot 5). Display the list of the snapshots again: admin:~ # rados -p bucket_pool lssnap 0 snaps","title":"Task 5: Manage snapshots of the new RGW bucket pool"},{"location":"linux/SES/linux_ses_demo/#224-maintain-consistency-of-data-with-scrub-and-repair","text":"Scrubbing is like \u201cfsck,\u201d which ensures that OSDs have durable, consistent data. Most of the scrubbing of OSDs happens automatically on a periodic basis.","title":"2.2.4. Maintain consistency of data with Scrub and Repair"},{"location":"linux/SES/linux_ses_demo/#task-1-display-a-few-of-the-scrub-settings","text":"1). Show the possible configuration settings related to scrub: If you simply grep for \u201cscrub\u201d you\u2019ll get more than you really want; there are some mon_scrub settings that aren\u2019t related to this exercise. admin:~ # ceph config ls | grep osd_scrub osd_scrub_invalid_stats osd_scrub_during_recovery osd_scrub_begin_hour osd_scrub_end_hour osd_scrub_begin_week_day osd_scrub_end_week_day osd_scrub_load_threshold osd_scrub_min_interval osd_scrub_max_interval osd_scrub_interval_randomize_ratio osd_scrub_backoff_ratio osd_scrub_chunk_min osd_scrub_chunk_max osd_scrub_sleep osd_scrub_auto_repair osd_scrub_auto_repair_num_errors osd_scrub_max_preemptions osd_scrub_priority osd_scrub_cost admin:~ # ceph config ls | grep osd_deep_scrub osd_deep_scrub_interval osd_deep_scrub_randomize_ratio osd_deep_scrub_stride osd_deep_scrub_keys osd_deep_scrub_update_digest_min_age osd_deep_scrub_large_omap_object_key_threshold osd_deep_scrub_large_omap_object_value_sum_threshold admin:~ # ceph config ls | grep scrub mon_warn_pg_not_scrubbed_ratio mon_warn_pg_not_deep_scrubbed_ratio mon_scrub_interval mon_scrub_timeout mon_scrub_max_keys mon_scrub_inject_crc_mismatch mon_scrub_inject_missing_keys osd_op_queue_mclock_scrub_res osd_op_queue_mclock_scrub_wgt osd_op_queue_mclock_scrub_lim osd_scrub_invalid_stats osd_max_scrubs osd_scrub_during_recovery osd_scrub_begin_hour osd_scrub_end_hour osd_scrub_begin_week_day osd_scrub_end_week_day osd_scrub_load_threshold osd_scrub_min_interval osd_scrub_max_interval osd_scrub_interval_randomize_ratio osd_scrub_backoff_ratio osd_scrub_chunk_min osd_scrub_chunk_max osd_scrub_sleep osd_scrub_auto_repair osd_scrub_auto_repair_num_errors osd_scrub_max_preemptions osd_deep_scrub_interval osd_deep_scrub_randomize_ratio osd_deep_scrub_stride osd_deep_scrub_keys osd_deep_scrub_update_digest_min_age osd_deep_scrub_large_omap_object_key_threshold osd_deep_scrub_large_omap_object_value_sum_threshold osd_debug_deep_scrub_sleep osd_scrub_priority osd_scrub_cost osd_requested_scrub_priority mds_max_scrub_ops_in_progress 2). Get the value of a few of the different scrub schedule settings: Note that \u201c0\u201d and \u201c24\u201d are the same setting. admin:~ # ceph config get osd.* osd_scrub_begin_hour 0 admin:~ # ceph config get osd.* osd_scrub_end_hour 24 3). Get the value of the scrub and repair settings: The \u201cauto repair\u201d feature is turned off, and the maximum numbgr of errors that \u201cauto repair\u201d would automatically repair is 5. admin:~ # ceph config get osd.* osd_scrub_auto_repair false admin:~ # ceph config get osd.* osd_scrub_auto_repair_num_errors 5","title":"Task 1: Display a few of the Scrub settings"},{"location":"linux/SES/linux_ses_demo/#task-2-change-the-scrub-settings-in-cephconf","text":"1). Display the ceph.conf, and verify that the file doesn\u2019t have any settings defined yet that are related to scrub. The settings would be located in the [global] section of the file: # DeepSea default configuration. Changes in this file will be overwritten on # package update. Include custom configuration fragments in # /srv/salt/ceph/configuration/files/ceph.conf.d/[global,osd,mon,mgr,mds,client].conf [global] fsid = 343ee7d3-232f-4c71-8216-1edbc55ac6e0 mon_initial_membgrs = mon1, mon2, mon3 mon_host = 10.58.121.186, 10.58.121.187, 10.58.121.188 auth_cluster_required = cephx auth_service_required = cephx auth_client_required = cephx public_network = 10.58.120.0/23 cluster_network = 10.58.120.0/23 ms_bind_msgr2 = false # enable old ceph health format in the json output. This fixes the # ceph_exporter. This option will only stay until the prometheus plugin takes # over mon_health_preluminous_compat = true mon health preluminous compat warning = false rbd default features = 3 [client.rgw.mon3] rgw frontends = \"beast port=80\" rgw dns name = mon3.sha.me.corp rgw enable usage log = true [osd] [mon] [mgr] [mds] [client] 2). Change to the Salt File Server directory that will have Salt control the master ceph.conf configuration file: admin:~ # cd /srv/salt/ceph/configuration/files/ceph.conf.d/ 3). List the content of the directory: The directory is empty. (Well, there is a README, but no other functional files.) admin:/srv/salt/ceph/configuration/files/ceph.conf.d # ls -l -rw-r--r-- 1 root root 1989 May 14 2020 README 4). Create and edit a new file called global.conf. You don\u2019t have to use vi, but this step uses vi as one way of doing it: Be sure that you spell everything correctly, including the absence of \u201c_\u201d characters; there are spaces. Save the file and exit out of the editor. admin:/srv/salt/ceph/configuration/files/ceph.conf.d # vi global.conf Add the following content to the file: osd scrub begin hour = 23 osd scrub end hour = 5 osd scrub auto repair = True osd scrub auto repair num errors = 10 5). Use DeepSea (Salt) to stage the file properly in Salt\u2019s File Server on the Salt Master (admin): admin:/srv/salt/ceph/configuration/files/ceph.conf.d # salt admin* state.apply ceph.configuration.create admin.sha.me.corp: Name: /var/cache/salt/minion/files/base/ceph/configuration - Function: file.absent - Result: Changed Started: - 22:42:34.900173 Duration: 20.891 ms Name: /srv/salt/ceph/configuration/cache/ceph.conf - Function: file.managed - Result: Changed Started: - 22:42:34.921454 Duration: 8576.516 ms Name: find /var/cache/salt/master/jobs -user root -exec chown salt:salt {} ';' - Function: cmd.run - Result: Changed Started: - 22:42:43.535022 Duration: 71.957 ms Summary for admin.sha.me.corp ------------ Succeeded: 3 (changed=3) Failed: 0 ------------ Total states run: 3 Total run time: 8.669 s 6). Using DeepSea (Salt), distribute the new ceph.conf configuration settings to all the nodes in the cluster: admin:/srv/salt/ceph/configuration/files/ceph.conf.d # salt \\* state.apply ceph.configuration mon3.sha.me.corp: Name: /etc/ceph/ceph.conf - Function: file.managed - Result: Changed Started: - 22:44:07.986661 Duration: 101.977 ms Summary for mon3.sha.me.corp ------------ Succeeded: 1 (changed=1) Failed: 0 ------------ Total states run: 1 Total run time: 101.977 ms mon1.sha.me.corp: Name: /etc/ceph/ceph.conf - Function: file.managed - Result: Changed Started: - 22:44:08.012479 Duration: 108.888 ms Summary for mon1.sha.me.corp ------------ Succeeded: 1 (changed=1) Failed: 0 ------------ Total states run: 1 Total run time: 108.888 ms data3.sha.me.corp: Name: /etc/ceph/ceph.conf - Function: file.managed - Result: Changed Started: - 22:44:08.052247 Duration: 98.681 ms Summary for data3.sha.me.corp ------------ Succeeded: 1 (changed=1) Failed: 0 ------------ Total states run: 1 Total run time: 98.681 ms admin.sha.me.corp: Name: /etc/ceph/ceph.conf - Function: file.managed - Result: Changed Started: - 22:44:08.072402 Duration: 97.231 ms Summary for admin.sha.me.corp ------------ Succeeded: 1 (changed=1) Failed: 0 ------------ Total states run: 1 Total run time: 97.231 ms data1.sha.me.corp: Name: /etc/ceph/ceph.conf - Function: file.managed - Result: Changed Started: - 22:44:08.076279 Duration: 104.169 ms Summary for data1.sha.me.corp ------------ Succeeded: 1 (changed=1) Failed: 0 ------------ Total states run: 1 Total run time: 104.169 ms data4.sha.me.corp: Name: /etc/ceph/ceph.conf - Function: file.managed - Result: Changed Started: - 22:44:08.081635 Duration: 105.13 ms Summary for data4.sha.me.corp ------------ Succeeded: 1 (changed=1) Failed: 0 ------------ Total states run: 1 Total run time: 105.130 ms mon2.sha.me.corp: Name: /etc/ceph/ceph.conf - Function: file.managed - Result: Changed Started: - 22:44:08.155758 Duration: 105.004 ms Summary for mon2.sha.me.corp ------------ Succeeded: 1 (changed=1) Failed: 0 ------------ Total states run: 1 Total run time: 105.004 ms data2.sha.me.corp: Name: /etc/ceph/ceph.conf - Function: file.managed - Result: Changed Started: - 22:44:08.252200 Duration: 109.552 ms Summary for data2.sha.me.corp ------------ Succeeded: 1 (changed=1) Failed: 0 ------------ Total states run: 1 Total run time: 109.552 ms 7). Verify that the new ceph.conf settings have been put into place on the admin node: admin:/srv/salt/ceph/configuration/files/ceph.conf.d # cat /etc/ceph/ceph.conf # DeepSea default configuration. Changes in this file will be overwritten on # package update. Include custom configuration fragments in # /srv/salt/ceph/configuration/files/ceph.conf.d/[global,osd,mon,mgr,mds,client].conf [global] fsid = 343ee7d3-232f-4c71-8216-1edbc55ac6e0 mon_initial_membgrs = mon1, mon2, mon3 mon_host = 10.58.121.188, 10.58.121.187, 10.58.121.186 auth_cluster_required = cephx auth_service_required = cephx auth_client_required = cephx public_network = 10.58.120.0/23 cluster_network = 10.58.120.0/23 ms_bind_msgr2 = false # enable old ceph health format in the json output. This fixes the # ceph_exporter. This option will only stay until the prometheus plugin takes # over mon_health_preluminous_compat = true mon health preluminous compat warning = false rbd default features = 3 osd scrub begin hour = 23 osd scrub end hour = 5 osd scrub auto repair = True osd scrub auto repair num errors = 10 [client.rgw.mon3] rgw frontends = \"beast port=80\" rgw dns name = mon3.sha.me.corp rgw enable usage log = true [osd] [mon] [mgr] [mds] [client] 8). Also verify that other minions in the cluster have also received the updated configuration file, such as on the mon1 and data2 nodes: admin:/srv/salt/ceph/configuration/files/ceph.conf.d # ssh mon1 cat /etc/ceph/ceph.conf # DeepSea default configuration. Changes in this file will be overwritten on # package update. Include custom configuration fragments in # /srv/salt/ceph/configuration/files/ceph.conf.d/[global,osd,mon,mgr,mds,client].conf [global] fsid = 343ee7d3-232f-4c71-8216-1edbc55ac6e0 mon_initial_membgrs = mon1, mon2, mon3 mon_host = 10.58.121.188, 10.58.121.187, 10.58.121.186 auth_cluster_required = cephx auth_service_required = cephx auth_client_required = cephx public_network = 10.58.120.0/23 cluster_network = 10.58.120.0/23 ms_bind_msgr2 = false # enable old ceph health format in the json output. This fixes the # ceph_exporter. This option will only stay until the prometheus plugin takes # over mon_health_preluminous_compat = true mon health preluminous compat warning = false rbd default features = 3 osd scrub begin hour = 23 osd scrub end hour = 5 osd scrub auto repair = True osd scrub auto repair num errors = 10 [client.rgw.mon3] rgw frontends = \"beast port=80\" rgw dns name = mon3.sha.me.corp rgw enable usage log = true [osd] [mon] [mgr] [mds] [client] admin:/srv/salt/ceph/configuration/files/ceph.conf.d # ssh data1 cat /etc/ceph/ceph.conf # DeepSea default configuration. Changes in this file will be overwritten on # package update. Include custom configuration fragments in # /srv/salt/ceph/configuration/files/ceph.conf.d/[global,osd,mon,mgr,mds,client].conf [global] fsid = 343ee7d3-232f-4c71-8216-1edbc55ac6e0 mon_initial_membgrs = mon1, mon2, mon3 mon_host = 10.58.121.188, 10.58.121.187, 10.58.121.186 auth_cluster_required = cephx auth_service_required = cephx auth_client_required = cephx public_network = 10.58.120.0/23 cluster_network = 10.58.120.0/23 ms_bind_msgr2 = false # enable old ceph health format in the json output. This fixes the # ceph_exporter. This option will only stay until the prometheus plugin takes # over mon_health_preluminous_compat = true mon health preluminous compat warning = false rbd default features = 3 osd scrub begin hour = 23 osd scrub end hour = 5 osd scrub auto repair = True osd scrub auto repair num errors = 10 [client.rgw.mon3] rgw frontends = \"beast port=80\" rgw dns name = mon3.sha.me.corp rgw enable usage log = true [osd] [mon] [mgr] [mds] [client] 9). Apply the settings of the ceph.conf file to appropriate nodes in the cluster: admin:/srv/salt/ceph/configuration/files/ceph.conf.d # ceph config assimilate-conf -i /etc/ceph/ceph.conf [global] fsid = 343ee7d3-232f-4c71-8216-1edbc55ac6e0 mon_health_preluminous_compat = true mon_health_preluminous_compat_warning = false mon_host = 10.58.121.188, 10.58.121.187, 10.58.121.186 mon_initial_membgrs = mon1, mon2, mon3","title":"Task 2: Change the Scrub settings in ceph.conf"},{"location":"linux/SES/linux_ses_demo/#task-3-change-the-scrub-settings-directly-in-the-configuration-db","text":"1). Query the configuration database to see the value of \u201cosd_scrub_auto_repair_num_errors\u201d: You changed this value to \u201c10\u201d in the previous Task. admin:~ # ceph config get osd.* osd_scrub_auto_repair_num_errors 10 2). Change the value of \u201cosd_scrub_auto_repair_num_errors\u201d to \u201c8\u201d: admin:~ # ceph config set osd.* osd_scrub_auto_repair_num_errors 8 3). Show that the change has taken immediate effect by re-running the same command that was used in the first step: admin:~ # ceph config get osd.* osd_scrub_auto_repair_num_errors 8","title":"Task 3: Change the Scrub settings directly in the Configuration DB"},{"location":"linux/SES/linux_ses_demo/#task-4-manually-scrub-and-repair-an-osd-and-a-pg","text":"This won\u2019t do much in this demo environment, because the OSDs aren\u2019t storing very much data. But it\u2019s worth having some practice. 1). Start a scrubbing of one of the OSDs: admin:~ # ceph osd scrub osd.1 instructed osd(s) 1 to scrub 2). Scrub a Placement Group: admin:~ # ceph pg scrub 8.1 instructing pg 8.1 on osd.0 to scrub 3). Repair an OSD: admin:~ # ceph osd repair osd.1 instructed osd(s) 1 to repair 4). Repair a PG: admin:~ # ceph pg repair 8.1 instructing pg 8.1 on osd.0 to repair 5). Show what\u2019s currently happening to the OSD that you instructed to have scrubbed and repaired: admin:~ # ceph osd dump | grep osd.1 max_osd 12 osd.1 up in weight 1 up_from 10 up_thru 1415 down_at 0 last_clean_interval [0,0) v1:10.58.121.185:6800/11157 v1:10.58.121.185:6801/11157 exists,up 32c78078-1878-4fac-9738-00d8bf80deea osd.10 up in weight 1 up_from 18 up_thru 1413 down_at 0 last_clean_interval [0,0) v1:10.58.121.182:6808/11130 v1:10.58.121.182:6809/11130 exists,up 6cb26fdc-09b1-42de-8855-7203931a0101 osd.11 up in weight 1 up_from 18 up_thru 1415 down_at 0 last_clean_interval [0,0) v1:10.58.121.185:6808/11995 v1:10.58.121.185:6809/11995 exists,up cc22107d-0239-4874-8308-6c137c8a0931 6). Show what\u2019s currently happening to the PG that you instructed to have scrubbed and repaired: admin:~ # ceph pg dump | grep \"8\\.1\" dumped all 8.16 0 0 0 0 0 0 0 0 0 0 active+clean 2021-01-05 21:01:16.383909 0'0 1423:27 [6,4,5] 6 [6,4,5] 6 0'0 2021-01-05 20:53:47.314062 0'0 2021-01-05 20:53:47.314062 0 8.17 0 0 0 0 0 0 0 0 0 0 active+clean 2021-01-05 22:57:01.044252 0'0 1424:30 [1,6,8] 1 [1,6,8] 1 0'0 2021-01-05 22:57:01.044098 0'0 2021-01-05 22:57:01.044098 0 8.14 0 0 0 0 0 0 0 0 0 0 active+clean 2021-01-05 22:56:56.081480 0'0 1424:30 [1,2,4] 1 [1,2,4] 1 0'0 2021-01-05 22:56:56.081356 0'0 2021-01-05 22:56:56.081356 0 8.15 0 0 0 0 0 0 0 0 0 0 active+clean 2021-01-05 21:01:16.375386 0'0 1423:27 [3,5,0] 3 [3,5,0] 3 0'0 2021-01-05 20:53:53.231124 0'0 2021-01-05 20:48:05.301705 0 8.12 0 0 0 0 0 0 0 0 0 0 active+clean 2021-01-05 21:01:16.370121 0'0 1423:27 [11,2,8] 11 [11,2,8] 11 0'0 2021-01-05 20:53:48.149449 0'0 2021-01-05 20:48:05.301705 0 2.18 0 0 0 0 0 0 0 0 0 0 active+clean 2021-01-05 16:44:58.986205 0'0 1423:1630 [10,1,8] 10 [10,1,8] 10 0'0 2021-01-05 13:02:00.365382 0'0 2021-01-02 00:38:58.134100 0 8.13 0 0 0 0 0 0 0 0 0 0 active+clean 2021-01-05 21:01:16.387832 0'0 1423:27 [0,8,1] 0 [0,8,1] 0 0'0 2021-01-05 20:53:56.132358 0'0 2021-01-05 20:48:05.301705 0 8.10 0 0 0 0 0 0 0 0 0 0 active+clean 2021-01-05 21:01:16.368416 0'0 1423:27 [11,3,6] 11 [11,3,6] 11 0'0 2021-01-05 20:53:51.152790 0'0 2021-01-05 20:48:05.301705 0 8.11 0 0 0 0 0 0 0 0 0 0 active+clean 2021-01-05 21:01:16.377871 0'0 1423:24 [3,10,5] 3 [3,10,5] 3 0'0 2021-01-05 20:53:45.195257 0'0 2021-01-05 20:48:05.301705 0 8.1e 0 0 0 0 0 0 0 0 0 0 active+clean 2021-01-05 21:01:16.391754 0'0 1423:47 [0,11,8] 0 [0,11,8] 0 0'0 2021-01-05 20:53:55.081582 0'0 2021-01-05 20:48:05.301705 0 8.1 0 0 0 0 0 0 0 0 0 0 active+clean 2021-01-05 22:56:39.829397 0'0 1424:54 [0,7,10] 0 [0,7,10] 0 0'0 2021-01-05 22:56:39.829241 0'0 2021-01-05 22:56:39.829241 0 8.1f 0 0 0 0 0 0 0 0 0 0 active+clean 2021-01-05 21:01:16.392315 0'0 1423:27 [7,5,9] 7 [7,5,9] 7 0'0 2021-01-05 20:53:59.988252 0'0 2021-01-05 20:48:05.301705 0 5.4 0 0 0 0 0 0 0 0 0 0 active+clean 2021-01-05 18:21:28.179266 0'0 1423:1554 [7,9,6] 7 [7,9,6] 7 0'0 2021-01-05 18:21:28.179166 0'0 2021-01-05 18:21:28.179166 0 5.b 0 0 0 0 0 0 0 0 0 0 active+clean 2021-01-05 18:37:01.467457 0'0 1423:1547 [2,0,11] 2 [2,0,11] 2 0'0 2021-01-04 23:46:58.132824 0'0 2021-01-02 03:35:41.214192 0 8.19 0 0 0 0 0 0 0 0 0 0 active+clean 2021-01-05 22:57:06.059090 0'0 1424:30 [1,8,2] 1 [1,8,2] 1 0'0 2021-01-05 22:57:06.058935 0'0 2021-01-05 22:57:06.058935 0 8.18 0 0 0 0 0 0 0 0 0 0 active+clean 2021-01-05 22:57:05.097742 0'0 1424:30 [1,3,6] 1 [1,3,6] 1 0'0 2021-01-05 22:57:05.097670 0'0 2021-01-05 22:57:05.097670 0 1.11 0 0 0 0 0 0 0 0 0 0 active+clean 2021-01-05 00:30:18.193988 0'0 1423:1605 [0,8,6] 0 [0,8,6] 0 0'0 2021-01-05 00:30:18.193868 0'0 2020-12-29 06:30:58.897565 0 8.1b 0 0 0 0 0 0 0 0 0 0 active+clean 2021-01-05 22:57:13.146469 0'0 1424:30 [1,4,6] 1 [1,4,6] 1 0'0 2021-01-05 22:57:13.146390 0'0 2021-01-05 22:57:13.146390 0 8.1a 1 0 0 0 0 19 0 0 2 2 active+clean 2021-01-05 21:01:16.386166 1420'2 1423:29 [9,11,10] 9 [9,11,10] 9 0'0 2021-01-05 20:53:48.690239 0'0 2021-01-05 20:48:05.301705 0 8.1d 0 0 0 0 0 0 0 0 0 0 active+clean 2021-01-05 21:01:16.388079 0'0 1423:56 [0,2,3] 0 [0,2,3] 0 0'0 2021-01-05 20:53:54.121281 0'0 2021-01-05 20:48:05.301705 0 8.1c 0 0 0 0 0 0 0 0 0 0 active+clean 2021-01-05 21:01:16.385846 0'0 1423:27 [2,11,7] 2 [2,11,7] 2 0'0 2021-01-05 20:53:55.458714 0'0 2021-01-05 20:48:05.301705 0","title":"Task 4: Manually scrub and repair an OSD and a PG"},{"location":"linux/SES/linux_ses_demo/#225-manipulate-manager-modules","text":"","title":"2.2.5. Manipulate Manager Modules"},{"location":"linux/SES/linux_ses_demo/#task-1-display-the-list-of-enabled-manager-modules","text":"1). Run the following command to show the list of enabled manager modules: Note that several modules are already enabled, such as: dashboard, iostat, pg_autosclater, prometheus, and restful. Even though they are not listed, the crash module and the balancer module are already enabled by default. admin:~ # ceph mgr module ls | head { \"always_on_modules\": [ \"balancer\", \"crash\", \"devicehealth\", \"orchestrator_cli\", \"progress\", \"rbd_support\", \"status\", \"volumes\" 2). Demonstrate that the crash module is enabled by running its command with no arguments: A list of \u201c7 closest matches\u201d is displayed, representing possible additional arguments to be used with the crash command. The crash module is therefore available. admin:~ # ceph crash crash info crash ls crash ls-new crash post crash prune crash rm crash stat crash json_report crash archive crash archive-all admin:~ # ceph crash stat 0 crashes recorded Task 2: Use the iostat module to display statistics for the IO of the cluster The iostat module is really simple, but very helpful. Run the command: admin:~ # ceph iostat +-----------------------------+-----------------------------+-----------------------------+-----------------------------+-----------------------------+-----------------------------+ | Read | Write | Total | Read IOPS | Write IOPS | Total IOPS | +-----------------------------+-----------------------------+-----------------------------+-----------------------------+-----------------------------+-----------------------------+ | 1024 B/s | 0 B/s | 1024 B/s | 1 | 0 | 1 | | 1024 B/s | 0 B/s | 1024 B/s | 1 | 0 | 1 | | 0 B/s | 0 B/s | 0 B/s | 0 | 0 | 0 | Task 3: Enable and configure the telemetry manager module 1). Enable the telemetry manager module: admin:~ # ceph mgr module enable telemetry 2). Show the various sub-commands that are associated with the telemetry command: A list of \u201c5 closest matches\u201d is displayed, showing various options. admin:~ # ceph telemetry telemetry status telemetry send {ceph|device [ceph|device...]} {} telemetry show { [...]} telemetry show-device telemetry on {} telemetry off 3). Show the status of the telemetry module: Notice that the output is returned as key/value pairs. Notice also that although the module has been enabled (which you accomplished in the first step of this task), the functionality is not enabled (enable=false). And for most of the keys, a null value is set. See that the url value is set to https://telemetry.ceph.com/report. That means that crash reports and other usage information about this cluster are going to be sent to the Ceph Community. admin:~ # ceph telemetry status { \"url\": \"https://telemetry.ceph.com/report\", \"device_url\": \"https://telemetry.ceph.com/device\", \"enabled\": false, \"last_opt_revision\": 1, \"leaderboard\": false, \"description\": null, \"contact\": null, \"organization\": null, \"proxy\": null, \"interval\": 24, \"channel_basic\": true, \"channel_ident\": false, \"channel_crash\": true, \"channel_device\": true, \"last_upload\": null } 4). Set the description, contact, and organization values: admin:~ # ceph config set mgr mgr/telemetry/contact 'JD ' admin:~ # ceph config set mgr mgr/telemetry/description 'Training Cluster' admin:~ # ceph config set mgr mgr/telemetry/organization 'SUSE Training' 5). Display the telemetry data that is collected to be sent: admin:~ # ceph telemetry show | less 6). With the contact information properly set, enable the telemetry functionality: This is a demo cluster with no connection to the internet, so no telemetry data will actually be sent. admin:~ # ceph telemetry on Error EPERM: Telemetry data is licensed under the Community Data License Agreement - Sharing - Version 1.0 (https://cdla.io/sharing-1-0/). To enable, add '--license sharing-1-0' to the 'ceph telemetry on' command. admin:~ # ceph telemetry on --license sharing-1-0 7). Disable the telemetry module: admin:~ # ceph mgr module disable telemetry admin:~ # ceph telemetry show | less Error ENOTSUP: Module 'telemetry' is not enabled (required by command 'telemetry show'): use `ceph mgr module enable telemetry` to enable it","title":"Task 1: Display the list of enabled Manager Modules"},{"location":"linux/SES/linux_ses_demo/#task-4-briefly-attempt-to-use-the-crash-manager-module","text":"1). Show (again) the various sub-commands that are associated with the crash command: admin:~ # ceph crash crash info crash ls crash ls-new crash post crash prune crash rm crash stat crash json_report crash archive crash archive-all 2). Show the current status of the crash database, including the numbgr of crash reports that have been collected so far: It\u2019s likely that the numbgr of crashes recorded in the demo environment is 0. admin:~ # ceph crash stat 0 crashes recorded","title":"Task 4: Briefly attempt to use the crash manager module"},{"location":"linux/SES/linux_ses_demo/#226-introduction-to-the-tell-command","text":"Tell is a very powerful command within Ceph to control the cluster. You don\u2019t use it everyday, but you need to know how to use it when the occasion to use it arises. It\u2019s mostly an Advanced Command, but exposure to it now reduces the stress of learning about it in a more advanced setting later. Run the tell command in a few different circumstances to control the behavior of various Ceph services.","title":"2.2.6. Introduction to the Tell command"},{"location":"linux/SES/linux_ses_demo/#task-1-run-a-benchmark-test-on-an-osd","text":"1). Run the following command to run and see the result of a benchmark test on osd.8: admin:~ # ceph tell osd.8 bench { \"bytes_written\": 1073741824, \"blocksize\": 4194304, \"elapsed_sec\": 3.7797023200000002, \"bytes_per_sec\": 284081055.35676152, \"iops\": 67.730201567831401 }","title":"Task 1: Run a benchmark test on an OSD"},{"location":"linux/SES/linux_ses_demo/#task-2-change-the-protection-setting-regarding-the-deletion-of-pools","text":"1). The default behavior in Ceph is that you can\u2019t delete pools. Try to delete a pool: The output says that you have to be VERY careful and provide more arguments in order to delete a pool admin:~ # ceph osd pool delete rbd_pool Error EPERM: WARNING: this will *PERMANENTLY DESTROY* all data stored in pool rbd_pool. If you are *ABSOLUTELY CERTAIN* that is what you want, pass the pool name *twice*, followed by --yes-i-really-really-mean-it. 2). Try deleting the pool again, this time with the extra arguments: Ceph still won\u2019t let you do it because the mon allow pool delete setting has the value of false. admin:~ # ceph osd pool delete rbd_pool rbd_pool --yes-i-really-really-mean-it Error EPERM: pool deletion is disabled; you must first set the mon_allow_pool_delete config option to true before you can destroy a pool 3). Show that the mon allow pool delete setting has the value of false: Indeed, the output shows that the value is false. admin:~ # ceph config get mon.mon\\* mon_allow_pool_delete false 4). Change to value of the setting using injectargs: Note that the \u201c-\u201d and \u201c_\u201d characters can be confusing. And note that the setting is preceded with the double \u201c--\u201d. The injected args must be enclosed in single quotes. You could have done this with ceph config set, but this is an alternative way to directly \u201ctell\u201d the cluster to change a setting. admin:~ # ceph tell mon.\\* injectargs '--mon-allow-pool-delete=true' mon.mon1: injectargs:mon_allow_pool_delete = 'true' mon.mon2: injectargs:mon_allow_pool_delete = 'true' mon.mon3: injectargs:mon_allow_pool_delete = 'true'","title":"Task 2: Change the protection setting regarding the deletion of pools"},{"location":"linux/SES/linux_ses_demo/#23-ceph-dashboard","text":"","title":"2.3. Ceph Dashboard"},{"location":"linux/SES/linux_ses_demo/#231-access-dashboard","text":"","title":"2.3.1. Access Dashboard"},{"location":"linux/SES/linux_ses_demo/#task-1-set-the-password-for-the-admin-user-of-the-ceph-dashboard","text":"1). In a Bash terminal as the root user, show that the Dashboard module is enabled: \u201cdashboard\u201d should be included in the list of \u201cenabled_modules\u201d at the top of the output. admin:~ # ceph mgr module ls | more \"enabled_modules\": [ \"dashboard\", \"iostat\", \"pg_autoscaler\", \"prometheus\", \"restful\" ], 2). Show the valid dashboard users that have already been created by DeepSea during initial deployment: It\u2019s possible that other users will be listed, but at least the \u201cadmin\u201d user should be displayed in the output. admin:~ # ceph dashboard ac-user-show [\"admin\"] 3). Show the \u201cadmin\u201d user\u2019s information as stored in the user database: You can see that the admin user has a password set, but it is stored as a hash. So you don\u2019t really know what the password is, and have no way of discovering it. admin:~ # ceph dashboard ac-user-show admin {\"username\": \"admin\", \"password\": , \"roles\": [\"administrator\"], \"name\": null, \"email\": null, \"lastUpdate\": 1601874928} 4). Change the \u201cadmin\u201d user\u2019s password for the dashboard: This sets the \u201cadmin\u201d user\u2019s password to the string: mypassword admin:~ # ceph dashboard ac-user-set-password admin mypassword {\"username\": \"admin\", \"password\": , \"roles\": [\"administrator\"], \"name\": null, \"email\": null, \"lastUpdate\": 1609860842} admin:~ #","title":"Task 1: Set the password for the admin user of the Ceph Dashboard"},{"location":"linux/SES/linux_ses_demo/#task-3-visit-the-ceph-dashboard-url","text":"admin:~ # salt-call grains.get dashboard_creds local: ---------- admin: admin:~ # ceph mgr services { \"dashboard\": \"https://mon1.sha.me.corp:8443/\", \"prometheus\": \"http://mon1.sha.me.corp:9283/\" } admin:~ # ceph -s cluster: id: 343ee7d3-232f-4c71-8216-1edbc55ac6e0 health: HEALTH_WARN 1 subtrees have overcommitted pool target_size_bytes services: mon: 3 daemons, quorum mon1,mon2,mon3 (age 9w) mgr: mon1(active, since 25m) mds: cephfs:1 {0=mon3=up:active} 2 up:standby osd: 12 osds: 12 up (since 5h), 12 in (since 3M) rgw: 1 daemon active (mon3) task status: scrub status: mds.mon3: idle data: pools: 9 pools, 244 pgs objects: 247 objects, 5.7 KiB usage: 14 GiB used, 82 GiB / 96 GiB avail pgs: 244 active+clean io: client: 1.2 KiB/s rd, 1 op/s rd, 0 op/s wr URL: https://mon1.sha.me.corp:8443/ https://10.58.121.186:8443","title":"Task 3: Visit the Ceph Dashboard URL"},{"location":"linux/SES/linux_ses_demo/#232-explore-the-dashboard-health-performance-status","text":"Dashboard Status Cluster Status Monitors OSDs Manager Daemons Hosts Object Gateway Metadata Service iSCSI Gateway Performance Client IOPS Client Throughput Client Read/Write Recovery Throughput Scrub Capacity Pools Raw Capacity Objects PGs per OSD PG Status [SUSE Enterprise Storage Portal Cluster\u2192Configuration Cluster\u2192Manager Modules Pools\u2192Create Pool","title":"2.3.2. Explore the Dashboard Health, Performance, Status"},{"location":"linux/SES/linux_ses_demo/#24-storage-data-access","text":"","title":"2.4. Storage Data Access"},{"location":"linux/SES/linux_ses_demo/#241-ensure-the-ses-cluster-is-healthy","text":"","title":"2.4.1. Ensure the SES Cluster is Healthy"},{"location":"linux/SES/linux_ses_demo/#task-1-check-the-clusters-health","text":"1). Run the following command to check the status (health) of the SES cluster: admin:~ # ceph -s cluster: id: 343ee7d3-232f-4c71-8216-1edbc55ac6e0 health: HEALTH_WARN 1 subtrees have overcommitted pool target_size_bytes 1 pools have too few placement groups services: mon: 3 daemons, quorum mon1,mon2,mon3 (age 9w) mgr: mon1(active, since 18h) mds: cephfs:1 {0=mon3=up:active} 2 up:standby osd: 12 osds: 12 up (since 23h), 12 in (since 3M) rgw: 1 daemon active (mon3) task status: scrub status: mds.mon3: idle data: pools: 10 pools, 248 pgs objects: 247 objects, 5.7 KiB usage: 14 GiB used, 82 GiB / 96 GiB avail pgs: 248 active+clean io: client: 1.2 KiB/s rd, 1 op/s rd, 0 op/s wr 2). Evaluate the output. The cluster in this demonstration environment often doesn\u2019t startup correctly due to the nature of a demo environment and it\u2019s less-predictable resources. Depending on whether any of the following tasks are necessary, followup accordingly to ensure that the cluster is healthy before proceeding with the course lectures or any further exercises. 3). Run the following series of commands to restart the Monitor daemons on each of the Monitor nodes: It\u2019s certainly not necessary to restart the monitor daemons on all of the monitor nodes if only one is down. If you prefer, you can take a different approach to starting the daemon on a single monitor node. admin:~ # for h in mon1 mon2 mon3; \\ do \\ ssh $h systemctl restart ceph-mon@$h; \\ done 4). After waiting a few moments for the daemons to restart, check the status again: admin:~ # ceph -s cluster: id: 343ee7d3-232f-4c71-8216-1edbc55ac6e0 health: HEALTH_WARN 1 subtrees have overcommitted pool target_size_bytes 1 pools have too few placement groups services: mon: 3 daemons, quorum mon1,mon2,mon3 (age 15s) mgr: mon1(active, since 21h) mds: cephfs:1 {0=mon3=up:active} 2 up:standby osd: 12 osds: 12 up (since 26h), 12 in (since 3M) rgw: 1 daemon active (mon3) task status: scrub status: mds.mon3: idle data: pools: 10 pools, 248 pgs objects: 247 objects, 5.7 KiB usage: 14 GiB used, 82 GiB / 96 GiB avail pgs: 248 active+clean io: client: 767 B/s rd, 0 op/s rd, 0 op/s wr 5). Run the following series of commands to restart the Manager daemons on each of the Monitor nodes: admin:~ # for h in mon1 mon2 mon3; \\ do \\ ssh $h systemctl restart ceph-mgr@$h; \\ done 6). After waiting a few moments for the daemons to restart, check the status again: admin:~ # ceph -s cluster: id: 343ee7d3-232f-4c71-8216-1edbc55ac6e0 health: HEALTH_OK services: mon: 3 daemons, quorum mon1,mon2,mon3 (age 8m) mgr: mon1(active, since 18s) mds: cephfs:1 {0=mon3=up:active} 2 up:standby osd: 12 osds: 12 up (since 26h), 12 in (since 3M) rgw: 1 daemon active (mon3) task status: scrub status: mds.mon3: idle data: pools: 10 pools, 248 pgs objects: 247 objects, 6.1 KiB usage: 14 GiB used, 82 GiB / 96 GiB avail pgs: 248 active+clean io: client: 852 B/s rd, 0 op/s rd, 0 op/s wr 7). Run the following command to restart the MDS daemon on the MDS node (mon1): admin:~ # ssh mon1 systemctl restart ceph-mds@mon1.service 8). After waiting a few moments for the mds daemon to restart, check the status again: Look for the mds service to be plain active rather than laggy or crashed admin:~ # ceph -s cluster: id: 343ee7d3-232f-4c71-8216-1edbc55ac6e0 health: HEALTH_WARN 1 subtrees have overcommitted pool target_size_bytes 1 pools have too few placement groups services: mon: 3 daemons, quorum mon1,mon2,mon3 (age 17m) mgr: mon1(active, since 8m) mds: cephfs:1 {0=mon3=up:active} 2 up:standby osd: 12 osds: 12 up (since 26h), 12 in (since 3M) rgw: 1 daemon active (mon3) task status: scrub status: mds.mon3: idle data: pools: 10 pools, 248 pgs objects: 247 objects, 6.2 KiB usage: 14 GiB used, 82 GiB / 96 GiB avail pgs: 248 active+clean io: client: 852 B/s rd, 0 op/s rd, 0 op/s wr 9). Verify if the OSDs \u201cup\u201d and running properly. It is only necessary if the output of ceph -s shows that there are fewer than 9 OSDs shown as being \u201cup\u201d. It\u2019s most likely that a storage node is simply not quite fully booted yet, such that the OSD daemons haven\u2019t fully come up. But if you suspect that the solution requires something different than simply waiting a little longer, you should try the following steps. First, identify which server is hosting the down\u2019d OSDs. One way of doing that is with this command: admin:~ # ceph osd tree ID CLASS WEIGHT TYPE NAME STATUS REWEIGHT PRI-AFF -1 0.09357 root default -9 0.02339 host data1 2 hdd 0.00780 osd.2 up 1.00000 1.00000 6 hdd 0.00780 osd.6 up 1.00000 1.00000 10 hdd 0.00780 osd.10 up 1.00000 1.00000 -3 0.02339 host data2 0 hdd 0.00780 osd.0 up 1.00000 1.00000 4 hdd 0.00780 osd.4 up 1.00000 1.00000 9 hdd 0.00780 osd.9 up 1.00000 1.00000 -7 0.02339 host data3 3 hdd 0.00780 osd.3 up 1.00000 1.00000 7 hdd 0.00780 osd.7 up 1.00000 1.00000 8 hdd 0.00780 osd.8 up 1.00000 1.00000 -5 0.02339 host data4 1 hdd 0.00780 osd.1 up 1.00000 1.00000 5 hdd 0.00780 osd.5 up 1.00000 1.00000 11 hdd 0.00780 osd.11 up 1.00000 1.00000 Simply try restarting the storage daemon processes on the affected host, such as with this example: admin:~ # ssh data2 systemctl restart ceph-osd@9.service admin:~ # ceph -s cluster: id: 343ee7d3-232f-4c71-8216-1edbc55ac6e0 health: HEALTH_WARN 1 subtrees have overcommitted pool target_size_bytes 1 pools have too few placement groups services: mon: 3 daemons, quorum mon1,mon2,mon3 (age 32m) mgr: mon1(active, since 24m) mds: cephfs:1 {0=mon3=up:active} 2 up:standby osd: 12 osds: 12 up (since 27s), 12 in (since 3M) rgw: 1 daemon active (mon3) task status: scrub status: mds.mon3: idle data: pools: 10 pools, 248 pgs objects: 247 objects, 6.2 KiB usage: 14 GiB used, 82 GiB / 96 GiB avail pgs: 248 active+clean io: client: 852 B/s rd, 0 op/s rd, 0 op/s wr If the OSD daemon processes are being stubborn and uncooperative, you may choose to reboot the storage virtual machine entirely. This is one way to do that: admin:~ # ssh data1 systemctl reboot After waiting some time for the daemons to get started, verify that all the OSDs are \u201cup\u201d and that the cluster is healthy: admin:~ # ceph osd tree admin:~ # ceph status 10). Run the following command to restart the RADOS Gateway daemon on the node that is hosting the gateway (mon3): admin:~ # ssh mon3 systemctl restart ceph-radosgw@rgw.mon3.service admin:~ # ssh mon3 systemctl status ceph-radosgw@rgw.mon3.service \u25cf ceph-radosgw@rgw.mon3.service - Ceph rados gateway Loaded: loaded (/usr/lib/systemd/system/ceph-radosgw@.service; enabled; vendor preset: disabled) Active: active (running) since Wed 2021-01-06 21:37:53 CST; 23s ago Main PID: 781880 (radosgw) Tasks: 588 CGroup: /system.slice/system-ceph\\x2dradosgw.slice/ceph-radosgw@rgw.mon3.service \u2514\u2500781880 /usr/bin/radosgw -f --cluster ceph --name client.rgw.mon3 --setuser ceph --setgroup ceph Jan 06 21:37:53 mon3 systemd[1]: Started Ceph rados gateway. 11). After waiting a few moments for the daemon to restart, check the status again: admin:~ # ceph -s cluster: id: 343ee7d3-232f-4c71-8216-1edbc55ac6e0 health: HEALTH_WARN 1 subtrees have overcommitted pool target_size_bytes 1 pools have too few placement groups services: mon: 3 daemons, quorum mon1,mon2,mon3 (age 39m) mgr: mon1(active, since 30m) mds: cephfs:1 {0=mon3=up:active} 2 up:standby osd: 12 osds: 12 up (since 6m), 12 in (since 3M) rgw: 1 daemon active (mon3) task status: scrub status: mds.mon3: idle data: pools: 10 pools, 248 pgs objects: 247 objects, 6.2 KiB usage: 14 GiB used, 82 GiB / 96 GiB avail pgs: 248 active+clean io: client: 1.2 KiB/s rd, 1 op/s rd, 0 op/s wr","title":"Task 1: Check the Cluster\u2019s health"},{"location":"linux/SES/linux_ses_demo/#242-use-the-s3-api-to-interact-with-the-rados-gateway","text":"In this lab we used the s3cmd and radosgw-admin utilities to interact with the SUSE Enterprise Storage cluster. We created a new user, a new bucket, and a new file. We then uploaded the file to the cluster and verified that the object gateway stored it to the cluster.","title":"2.4.2. Use the S3 API to Interact with the RADOS Gateway"},{"location":"linux/SES/linux_ses_demo/#task-1-using-the-s3cmd-tool-and-create-an-s3-user","text":"1). As the root user (password is linux) in a shell or terminal, verify that the s3cmd is available on the admin node: You will likely see an error about configuration files missing, etc. This is enough information to validate the utility is installed. admin:~ # pip --version pip 10.0.1 from /usr/lib/python3.6/site-packages/pip (python 3.6) admin:~ # pip install s3cmd Collecting s3cmd Downloading https://files.pythonhosted.org/packages/26/44/19e08f69b2169003f7307565f19449d997895251c6a6566ce21d5d636435/s3cmd-2.1.0-py2.py3-none-any.whl (145kB) 100% | 153kB 2.7MB/s Collecting python-magic (from s3cmd) Downloading https://files.pythonhosted.org/packages/59/77/c76dc35249df428ce2c38a3196e2b2e8f9d2f847a8ca1d4d7a3973c28601/python_magic-0.4.18-py2.py3-none-any.whl Requirement already satisfied: python-dateutil in /usr/lib/python3.6/site-packages (from s3cmd) (2.7.3) Requirement already satisfied: six>=1.5 in /usr/lib/python3.6/site-packages (from python-dateutil->s3cmd) (1.11.0) Installing collected packages: python-magic, s3cmd Successfully installed python-magic-0.4.18 s3cmd-2.1.0 2). Create a new S3 user to be used: The output will include an access_key value and a secret_key value. You will need both of those values in later steps. admin:~ # radosgw-admin user create --uid=s3user --display-name=S3 User --email=s3user@example.net { \"user_id\": \"s3user\", \"display_name\": \"S3\", \"email\": \"s3user@example.net\", \"suspended\": 0, \"max_buckets\": 1000, \"subusers\": [], \"keys\": [ { \"user\": \"s3user\", \"access_key\": , \"secret_key\": } ], \"swift_keys\": [], \"caps\": [], \"op_mask\": \"read, write, delete\", \"default_placement\": \"\", \"default_storage_class\": \"\", \"placement_tags\": [], \"bucket_quota\": { \"enabled\": false, \"check_on_raw\": false, \"max_size\": -1, \"max_size_kb\": 0, \"max_objects\": -1 }, \"user_quota\": { \"enabled\": false, \"check_on_raw\": false, \"max_size\": -1, \"max_size_kb\": 0, \"max_objects\": -1 }, \"temp_url_keys\": [], \"type\": \"rgw\", \"mfa_ids\": [] } Retrieve above information admin:~ # radosgw-admin user info --uid=s3user","title":"Task 1: Using the s3cmd tool and create an S3 user"},{"location":"linux/SES/linux_ses_demo/#task-2-create-a-new-s3cmd-configuration-file-and-a-new-s3-bucket","text":"1). Generate a new s3cmd configuration file from a shell on the admin node: Fill in as listed below: admin:~ # cd ~ admin:~ # s3cmd --configure Enter new values or accept defaults in brackets with Enter. Refer to user manual for detailed description of all options. Access key and Secret key are your identifiers for Amazon S3. Leave them empty for using the env variables. Access Key: Secret Key: Default Region [US]: Use \"s3.amazonaws.com\" for S3 Endpoint and not modify it to the target Amazon S3. S3 Endpoint [s3.amazonaws.com]: mon3.sha.me.corp Use \"%(bucket)s.s3.amazonaws.com\" to the target Amazon S3. \"%(bucket)s\" and \"%(location)s\" vars can be used if the target S3 system supports dns based buckets. DNS-style bucket+hostname:port template for accessing a bucket [%(bucket)s.s3.amazonaws.com]: %(bucket)s.mon3.sha.me.corp Encryption password is used to protect your files from reading by unauthorized persons while in transfer to S3 Encryption password: Path to GPG program [/usr/bin/gpg]: When using secure HTTPS protocol all communication with Amazon S3 servers is protected from 3 rd party eavesdropping. This method is slower than plain HTTP, and can only be proxied with Python 2.7 or newer Use HTTPS protocol [Yes]: No On some networks all internet access must go through a HTTP proxy. Try setting it here if you can't connect to S3 directly HTTP Proxy server name: New settings: Access Key: Secret Key: Default Region: US S3 Endpoint: mon3.sha.me.corp DNS-style bucket+hostname:port template for accessing a bucket: %(bucket)s.mon3.sha.me.corp Encryption password: Path to GPG program: /usr/bin/gpg Use HTTPS protocol: False HTTP Proxy server name: HTTP Proxy server port: 0 Test access with supplied credentials? [Y/n] n Save settings? [y/N] y Configuration saved to '/root/.s3cfg' 2). Test the configuration by checking for existing files or directories: Since no buckets or files have been made available for the user, no items are listed and the command returns you to the prompt with no output. This is normal. If there is an error, your configuration may have a typo in it. The configuration file will have been saved as .s3cfg. Edit the file to match the configuration in step one. admin:~ # s3cmd ls 3). Create a new bucket for uploading files to using the s3cmd: You should see feedback that the bucket has been created. Although not technically required by the S3 API, the bucket name needs to be in all uppercase to avoid a bug with the s3cmd tool itself. admin:~ # s3cmd mb s3://S3CMDTEST Bucket 's3://S3CMDTEST/' created admin:~ # s3cmd ls 2021-01-06 14:04 s3://S3CMDTEST (it's GMT timezone)","title":"Task 2: Create a new s3cmd configuration file and a new S3 bucket"},{"location":"linux/SES/linux_ses_demo/#task3-create-and-upload-a-file-to-a-bucket-using-the-s3-api","text":"1). Create a file with a few words of text: admin:~ # echo \"The mountains are beautiful\" > newfile 2). Put the new file into your bucket using s3cmd: You should see the file being uploaded. admin:~ # s3cmd put newfile s3://S3CMDTEST upload: 'newfile' -> 's3://S3CMDTEST/newfile' [1 of 1] 28 of 28 100% in 3s 7.66 B/s done 3). Verify the file is now in your bucket, safely stored in you SES cluster: admin:~ # s3cmd ls s3://S3CMDTEST 2021-01-06 14:11 28 s3://S3CMDTEST/newfile","title":"Task3: Create and upload a file to a bucket using the S3 API"},{"location":"linux/SES/linux_ses_demo/#243-use-the-swift-api-to-interact-with-the-rados-gateway","text":"OpenStack packages for SUSE Install and configure the storage nodes for openSUSE and SUSE Linux Enterprise SUSE Package Hub: python-PasteDeploy Enable SUSE Package Hub extension admin:~ # SUSEConnect -p PackageHub/15.1/x86_64 Install python3-PasteDeploy, which is dependency of python-swift installation admin:~ # zypper in python3-PasteDeploy admin:~ # rpm -ivh python3-PyECLib-1.6.0-1.6.x86_64.rpm warning: python3-PyECLib-1.6.0-1.6.x86_64.rpm: Header V3 RSA/SHA256 Signature, key ID 3dbdc284: NOKEY error: Failed dependencies: python(abi) = 3.8 is needed by python3-PyECLib-1.6.0-1.6.x86_64 rpmlib(PayloadIsZstd) <= 5.4.18-1 is needed by python3-PyECLib-1.6.0-1.6.x86_64 Add OpenStack Swift Repository for SUSE admin:~ # zypper addrepo -f obs://Cloud:OpenStack:Train/SLE_15_SP1 Train admin:~ # zypper in openstack-swift openstack-swift-account openstack-swift-container openstack-swift-object","title":"2.4.3. Use the swift API to Interact with the RADOS Gateway"},{"location":"linux/SES/linux_ses_demo/#task-1-create-a-swift-subuser","text":"1). In a shell or terminal as the root user (password of linux) on the admin node, create a new subuser: The output will contain the access and secret keys for the s3user and a secret key for the new swift subuser.. admin:~ # radosgw-admin subuser create --uid=s3user --subuser=s3user:swift --access=full { \"user_id\": \"s3user\", \"display_name\": \"S3\", \"email\": \"s3user@example.net\", \"suspended\": 0, \"max_buckets\": 1000, \"subusers\": [ { \"id\": \"s3user:swift\", \"permissions\": \"full-control\" } ], \"keys\": [ { \"user\": \"s3user\", \"access_key\": , \"secret_key\": } ], \"swift_keys\": [ { \"user\": \"s3user:swift\", \"secret_key\": } ], \"caps\": [], \"op_mask\": \"read, write, delete\", \"default_placement\": \"\", \"default_storage_class\": \"\", \"placement_tags\": [], \"bucket_quota\": { \"enabled\": false, \"check_on_raw\": false, \"max_size\": -1, \"max_size_kb\": 0, \"max_objects\": -1 }, \"user_quota\": { \"enabled\": false, \"check_on_raw\": false, \"max_size\": -1, \"max_size_kb\": 0, \"max_objects\": -1 }, \"temp_url_keys\": [], \"type\": \"rgw\", \"mfa_ids\": [] } 2). Verify that the subuser has access to at least one bucket and list the buckets with a swift command: swift -A http://mon3.sha.me.corp/auth/1.0 -U s3user:swift -K '{SECRET_KEY_FROM_STEP_1}' list admin:~ # swift -A http://mon3.sha.me.corp/auth/1.0 -U s3user:swift -K '' list S3CMDTEST","title":"Task 1: Create a swift subuser"},{"location":"linux/SES/linux_ses_demo/#task-2-use-the-swift-command-to-access-a-file-created-with-the-s3cmd-tool","text":"1). Since the S3 API and the swift API are accessing the same SUSE Enterprise Storage cluster, and since the RADOS gateway is built to be inter-operable with both, you can use the swift API to retrieve the object which was uploaded to SES via the S3 API: swift -A http://mon3.example.net/auth/1.0 -U s3user:swift -K '{SECRET_KEY_FROM_STEP_1}' download -a An example of the command is listed here: admin:~ # swift -A http://mon3.sha.me.corp/auth/1.0 -U s3user:swift -K '' download -a Although we have taken a shortcut by using the -a option (meaning grab every object this user has access to), it illustrates the tool\u2019s capability. We\u2019ve uploaded the newfile with S3, we\u2019ve retrieved it with swift.","title":"Task 2: Use the swift command to access a file created with the S3cmd tool"},{"location":"linux/SES/linux_ses_demo/#244-create-snapshots-on-ses-using-rbd","text":"In this lab we worked with rbd images. We mapped an rbd image to a Linux device file, then created a filesystem and mounted it. Then we created snapshots to preserve the images data state at a particular time, and rolled it back to demonstrate functionality.","title":"2.4.4. Create Snapshots on SES using RBD"},{"location":"linux/SES/linux_ses_demo/#task-1-create-a-new-pool-for-rbd-images","text":"1). Access https://mon1.pvg.me.corp:8443 or https://10.58.121.186:8443 2). Log in with the following credentials: Username: admin Password: mypassword 3). Click on the Pools tab near the top of the page 4). Click the Create button and use the following in the available fields: Name: rbd-images Pool type: replicated Placement groups: 16 Crush ruleset: replicated_rule Replicted size: 2 Applications: rbd Compression Mode: none 5). Click Create Pool","title":"Task 1: Create a new pool for RBD images"},{"location":"linux/SES/linux_ses_demo/#task-2-create-a-new-rbd-image-in-the-rbd-images-pool","text":"6). Create a new RBD image using the rbd command: admin:~ # rbd create --size 1024 rbd-images/barfoo 7). Verify the new image has been created in the rbd-images pool: The new image named barfoo should be displayed. admin:~ # rbd ls -p rbd-images barfoo","title":"Task 2: Create a new RBD image in the rbd-images pool"},{"location":"linux/SES/linux_ses_demo/#task-3-mount-the-new-image-on-the-admin-node-and-create-a-filesystem","text":"1). As the root user in a shell or terminal on the admin node, map the new rbd image to a block device: admin:~ # rbd map rbd-images/barfoo /dev/rbd0 2). Create a filesystem on the newly mapped device: admin:~ # mkfs.ext4 /dev/rbd0 mke2fs 1.43.8 (1-Jan-2018) Discarding device blocks: done Creating filesystem with 262144 4k blocks and 65536 inodes Filesystem UUID: 19da6b86-1989-4834-a365-2f654fcce6f6 Superblock backups stored on blocks: 32768, 98304, 163840, 229376 Allocating group tables: done Writing inode tables: done Creating journal (8192 blocks): done Writing superblocks and filesystem accounting information: done 3). Mount the image to the /mnt directory: admin:~ # mount /dev/rbd0 /mnt admin:~ # l /mnt total 20 drwxr-xr-x 3 root root 4096 Jan 6 23:48 ./ drwxr-xr-x 1 root root 156 Oct 5 08:53 ../ drwx------ 2 root root 16384 Jan 6 23:48 lost+found/","title":"Task 3: Mount the new image on the admin node and create a filesystem"},{"location":"linux/SES/linux_ses_demo/#task-4-create-a-file-on-the-new-filesystem-and-snapshot-the-rbd-image-and-make-some-additional-changes","text":"1). Change to the /mnt directory and create a simple file: admin:~ # cd /mnt admin:/mnt # echo \"This is some sample text\" > start.txt 2). List the directories contents to see that the start.txt file has been created on the storage cluster. admin:/mnt # ls -l total 20 drwx------ 2 root root 16384 Jan 6 23:48 lost+found -rw-r--r-- 1 root root 25 Jan 6 23:50 start.txt 3). Create a snapshot of what the rbd image contained: Wait for confirmation that the snapshot has been created. It should only take a few seconds. admin:/mnt # rbd snap create rbd-images/barfoo@begin 4). List the rbd snapshots for the rbd-images/barfoo image: You should see the new snap called begin listed. admin:/mnt # rbd snap ls rbd-images/barfoo SNAPID NAME SIZE PROTECTED TIMESTAMP 4 begin 1 GiB Wed Jan 6 23:51:12 2021 5). Add another file to the filesystem: admin:/mnt # echo \"Some more text\" > end.txt 6). List the contents of the /mnt to verify the existence of two files. admin:/mnt # ls -l total 24 -rw-r--r-- 1 root root 15 Jan 6 23:52 end.txt drwx------ 2 root root 16384 Jan 6 23:48 lost+found -rw-r--r-- 1 root root 25 Jan 6 23:50 start.txt 7). Create a second snapshot of the rbd-images/barfoo image: admin:/mnt # rbd snap create rbd-images/barfoo@finish 8). List the rbd snapshots: There should be begin and finish snapshots. admin:/mnt # rbd snap ls rbd-images/barfoo SNAPID NAME SIZE PROTECTED TIMESTAMP 4 begin 1 GiB Wed Jan 6 23:51:12 2021 5 finish 1 GiB Wed Jan 6 23:53:15 2021 9). List the contents of the /mnt directory again and verify the two files. 10). Rollback the data to the begin snapshot: This process will be relatively quick because the size of the image is small and we have very little data on it. admin:/mnt # rbd snap rollback rbd-images/barfoo@begin Rolling back to snapshot: 100% complete...done. 11). Change to the root user\u2019s home directory, then remount the image in order to see that the rbd image has been rolled back: admin:/mnt # cd ~ admin:~ # umount /mnt admin:~ # mount /dev/rbd0 /mnt 12). List the contents of the /mnt directory to verify that only the start.txt file exists on the image. admin:/mnt # ls -l total 20 drwx------ 2 root root 16384 Jan 6 23:48 lost+found -rw-r--r-- 1 root root 25 Jan 6 23:50 start.txt 13). Rollback the data to the finish snapshot: admin:/mnt # rbd snap rollback rbd-images/barfoo@finish Rolling back to snapshot: 100% complete...done. 14). Unmount and remount the image: admin:/mnt # cd ~ admin:~ # umount /mnt admin:~ # mount /dev/rbd0 /mnt 15). List the contents of the /mnt directory to show it has indeed been rolled back and contains the start.txt and end.txt files admin:/mnt # ls -l total 24 -rw-r--r-- 1 root root 15 Jan 6 23:52 end.txt drwx------ 2 root root 16384 Jan 6 23:48 lost+found -rw-r--r-- 1 root root 25 Jan 6 23:50 start.txt 16). Change to the root user\u2019s home directory and unmount the image: admin:/mnt # cd ~ admin:~ # umount /mnt","title":"Task 4: Create a file on the new filesystem and snapshot the rbd image and make some additional changes"},{"location":"linux/SES/linux_ses_demo/#245-create-and-manage-cow-clones-with-rbd","text":"In this lab you will created a new pool and block device image in the pool. You then mapped the block storage to a linux device and took a snapshot. Finally you protected the snapshot from modification. This would be done so the snapshot can be safely used as a parent cow image which can then be cloned to create new virtual machines.","title":"2.4.5. Create and manage COW Clones with rbd"},{"location":"linux/SES/linux_ses_demo/#task-1-create-a-new-pool","text":"1). View the current osds and pools: admin:~ # ceph osd ls 0 1 2 3 4 5 6 7 8 9 10 11 admin:~ # ceph osd pool ls iscsi-images cephfs_data cephfs_metadata .rgw.root default.rgw.control default.rgw.meta default.rgw.log rbd_pool bucket_pool EC_RBD_Pool default.rgw.buckets.index default.rgw.buckets.data rbd-images 2). Create a new pool called cow-pool: admin:~ # ceph osd pool create cow-pool 128 pool 'cow-pool' created 3). List the available pools to view the new pool using either of the following commands: admin:~ # ceph osd pool ls iscsi-images cephfs_data cephfs_metadata .rgw.root default.rgw.control default.rgw.meta default.rgw.log rbd_pool bucket_pool EC_RBD_Pool default.rgw.buckets.index default.rgw.buckets.data rbd-images cow-pool admin:~ # rados lspools iscsi-images cephfs_data cephfs_metadata .rgw.root default.rgw.control default.rgw.meta default.rgw.log rbd_pool bucket_pool EC_RBD_Pool default.rgw.buckets.index default.rgw.buckets.data rbd-images cow-pool Task 2: Create a block device image in a pool 1). Create a format 2 rbd image called cow-base in the cow-pool storage pool with a size of 1GB *Note that the \u2013image-format statement is optional as format 2 is default admin:~ # rbd create -p cow-pool cow-base --size 1024 --image-format 2 2). Check that the image has been created, that the format is 2 and that layering (COW Clones) is supported admin:~ # rbd -p cow-pool list cow-base admin:~ # rbd -p cow-pool info cow-base rbd image 'cow-base': size 1 GiB in 256 objects order 22 (4 MiB objects) snapshot_count: 0 id: 269d5b817222aa block_name_prefix: rbd_data.269d5b817222aa format: 2 features: layering op_features: flags: create_timestamp: Thu Jan 7 10:12:31 2021 access_timestamp: Thu Jan 7 10:12:31 2021 modify_timestamp: Thu Jan 7 10:12:31 2021 Task 3: Map the block storage image to a Linux host 1). In a shell or terminal as user root open a terminal window. Using the rbd map command, map an rbd device to the block-storage image created above. admin:~ # rbd map -p cow-pool --image cow-base /dev/rbd1 2). View the mapped block devices admin:~ # rbd showmapped id pool namespace image snap device 0 rbd-images barfoo - /dev/rbd0 1 cow-pool cow-base - /dev/rbd1 3). Note the rbd index numbgr (e.g. rbd0, rbd1) associated with the cow-base image: RBD ___1____ 4). View the devices in /dev. Note the device name(s) admin:~ # ls -l /dev/rbd* brw-rw---- 1 root disk 252, 0 Jan 6 23:49 /dev/rbd0 brw-rw---- 1 root disk 252, 16 Jan 7 10:14 /dev/rbd1 /dev/rbd: total 0 drwxr-xr-x 2 root root 60 Jan 7 10:14 cow-pool drwxr-xr-x 2 root root 60 Jan 6 23:48 rbd-images 5). View the block device:(use the device numbgr from step above) admin:~ # fdisk -l /dev/rbd1 Disk /dev/rbd1: 1 GiB, 1073741824 bytes, 2097152 sectors Units: sectors of 1 * 512 = 512 bytes Sector size (logical/physical): 512 bytes / 512 bytes I/O size (minimum/optimal): 4194304 bytes / 4194304 bytes 6). Format the device with an ext4 filesystem: admin:~ # mkfs.ext4 /dev/rbd1 mke2fs 1.43.8 (1-Jan-2018) Discarding device blocks: done Creating filesystem with 262144 4k blocks and 65536 inodes Filesystem UUID: 64c9a973-cf31-4239-881f-ec5642bf34e3 Superblock backups stored on blocks: 32768, 98304, 163840, 229376 Allocating group tables: done Writing inode tables: done Creating journal (8192 blocks): done Writing superblocks and filesystem accounting information: done 7). Mount the block device on the local filesystem: admin:~ # mkdir /mnt/cow-base admin:~ # mount /dev/rbd1 /mnt/cow-base 8). Test the storage access by creating a file: admin:~ # cd /mnt/cow-base admin:/mnt/cow-base # touch base-image-file admin:/mnt/cow-base # ls base-image-file lost+found","title":"Task 1: Create a new pool"},{"location":"linux/SES/linux_ses_demo/#task-4-snapshot-the-rbd-image-and-protect-the-snapshot","text":"1). List the snapshots in the cow-base image: admin:/mnt/cow-base # rbd snap ls cow-pool/cow-base 2). Create a snapshot of the cow-base rbd image which contains the base-image-file file admin:/mnt/cow-base # rbd snap create cow-pool/cow-base@base-snap 3). List the snapshot: admin:/mnt/cow-base # rbd snap ls cow-pool/cow-base SNAPID NAME SIZE PROTECTED TIMESTAMP 4 base-snap 1 GiB Thu Jan 7 10:37:13 2021 4). This snapshot will form the parent snapshot for COW clone images so you will now protected it from modification: admin:/mnt/cow-base # rbd snap protect cow-pool/cow-base@base-snap admin:/mnt/cow-base # rbd snap ls cow-pool/cow-base SNAPID NAME SIZE PROTECTED TIMESTAMP 4 base-snap 1 GiB yes Thu Jan 7 10:37:13 2021 Task 5: Create writable COW clones from the parent snapshot 1). Create a COW clone from the cow-base with the base-snap snapshot as the parent image admin:/mnt/cow-base # rbd clone cow-pool/cow-base@base-snap cow-pool/cow-image1 2). Check the information for the new image admin:/mnt/cow-base # rbd -p cow-pool --image cow-image1 info rbd image 'cow-image1': size 1 GiB in 256 objects order 22 (4 MiB objects) snapshot_count: 0 id: 26a1209678cad4 block_name_prefix: rbd_data.26a1209678cad4 format: 2 features: layering op_features: flags: create_timestamp: Thu Jan 7 10:38:58 2021 access_timestamp: Thu Jan 7 10:38:58 2021 modify_timestamp: Thu Jan 7 10:38:58 2021 parent: cow-pool/cow-base@base-snap overlap: 1 GiB 3). Note that the image has details of the parent image and overlap 4). Repeat steps 2 & 3 for an additional image called cow-image2 admin:/mnt/cow-base # rbd clone cow-pool/cow-base@base-snap cow-pool/cow-image2 admin:/mnt/cow-base # rbd -p cow-pool --image cow-image2 info rbd image 'cow-image2': size 1 GiB in 256 objects order 22 (4 MiB objects) snapshot_count: 0 id: 26a2fbcec7b8d9 block_name_prefix: rbd_data.26a2fbcec7b8d9 format: 2 features: layering op_features: flags: create_timestamp: Thu Jan 7 10:47:28 2021 access_timestamp: Thu Jan 7 10:47:28 2021 modify_timestamp: Thu Jan 7 10:47:28 2021 parent: cow-pool/cow-base@base-snap overlap: 1 GiB Task 6: Test that the COW clones are functional 1). Create a new directory and mount the COW clone called cow-image1 Note the rbd device name and use it to mount the file system admin:/mnt # mkdir /mnt/cow-image1 admin:/mnt # rbd map -p cow-pool --image cow-image1 /dev/rbd2 admin:/mnt # l total 4 drwxr-xr-x 1 root root 36 Jan 7 10:54 ./ drwxr-xr-x 1 root root 156 Oct 5 08:53 ../ drwxr-xr-x 3 root root 4096 Jan 7 10:19 cow-base/ drwxr-xr-x 1 root root 0 Jan 7 10:54 cow-image1/ admin:/mnt # ls -l /dev/rbd* brw-rw---- 1 root disk 252, 0 Jan 6 23:49 /dev/rbd0 brw-rw---- 1 root disk 252, 16 Jan 7 10:18 /dev/rbd1 brw-rw---- 1 root disk 252, 32 Jan 7 10:55 /dev/rbd2 /dev/rbd: total 0 drwxr-xr-x 2 root root 80 Jan 7 10:55 cow-pool drwxr-xr-x 2 root root 60 Jan 6 23:48 rbd-images admin:/mnt # mount /dev/rbd2 /mnt/cow-image1 2). Check that the base-image-file which was created in the parent snapshot is present admin:/mnt # cd /mnt/cow-image1 admin:/mnt/cow-image1 # ls base-image-file lost+found 3). Repeat steps 1 and 2 for cow-image2 admin:/mnt # mkdir /mnt/cow-image2 admin:/mnt # rbd map -p cow-pool --image cow-image2 /dev/rbd3 admin:/mnt # mount /dev/rbd3 /mnt/cow-image2 admin:/mnt # ls ./cow-image2/ base-image-file lost+found --> same file with image1 4). Create a new file in the directory where cow-image1 is mounted admin:/mnt # cd cow-image1 admin:/mnt/cow-image1 # touch additional-file admin:/mnt/cow-image1 # ls additional-file base-image-file lost+found 5). Look in the cow-image2 directory. Although they share the same parent snapshot, you can see that the files contained in each COW image are now different. admin:/mnt # ls ./cow-image2/ base-image-file lost+found","title":"Task 4: Snapshot the rbd image and protect the snapshot"},{"location":"linux/SES/linux_ses_demo/#task-7-flatten-a-cow-clone-and-remove-the-parent-image","text":"1). Convert the COW clone called cow-image1 to a standalone rbd image Wait while the flatten process completes. Unlike a clone process this is not instantaneous and can take considerable time. admin:/mnt # rbd flatten cow-pool/cow-image1 Image flatten: 100% complete...done. 2). Check to see that the flatten process has removed the link to the parent snapshot admin:/mnt # rbd -p cow-pool --image cow-image1 info rbd image 'cow-image1': size 1 GiB in 256 objects order 22 (4 MiB objects) snapshot_count: 0 id: 26a1209678cad4 block_name_prefix: rbd_data.26a1209678cad4 format: 2 features: layering op_features: flags: create_timestamp: Thu Jan 7 10:38:58 2021 access_timestamp: Thu Jan 7 10:38:58 2021 modify_timestamp: Thu Jan 7 10:38:58 2021 admin:/mnt # rbd -p cow-pool --image cow-image2 info rbd image 'cow-image2': size 1 GiB in 256 objects order 22 (4 MiB objects) snapshot_count: 0 id: 26a2fbcec7b8d9 block_name_prefix: rbd_data.26a2fbcec7b8d9 format: 2 features: layering op_features: flags: create_timestamp: Thu Jan 7 10:47:28 2021 access_timestamp: Thu Jan 7 10:47:28 2021 modify_timestamp: Thu Jan 7 10:47:28 2021 parent: cow-pool/cow-base@base-snap overlap: 1 GiB 3). Unmount the images admin:/mnt # umount /mnt/cow-image1 admin:/mnt # umount /mnt/cow-image2 admin:/mnt # umount /mnt/cow-base","title":"Task 7: Flatten a COW Clone and remove the parent image"},{"location":"linux/SES/linux_ses_demo/#246-configure-iscsi-on-ses","text":"In this lab an iSCSI Target was configured via the iSCSI gateway on our SUSE Enterprise Storage. An image was added to it. An iSCSI initiator then connected to the target, created a filesystem, and mounted it.","title":"2.4.6. Configure iSCSI on SES"},{"location":"linux/SES/linux_ses_demo/#task-1-create-a-new-rbd-image-in-the-iscsi-images-pool","text":"1). Create a new RBD image using the rbd command: admin:~ # rbd create --size 1024 iscsi-images/fooiscsi 2). Verify the new image has been created in the iscsi-images pool: The new image named fooiscsi should be displayed. admin:~ # rbd ls iscsi-images fooiscsi","title":"Task 1: Create a new RBD image in the iscsi-images pool"},{"location":"linux/SES/linux_ses_demo/#task-2-define-a-new-iscsi-target-with-the-ceph-dashboard","text":"1). Access the Ceph Dashboard and log in: https://mon1.pvg.me.corp:8443 or https://10.58.121.186:8443 Username: admin Password: mypassword 2). Once logged in, click on the Block drop-down item near the top. Select iSCSI. 3). With the Overview tab showing for iSCSI, click on the Targets tab near the top. Note: When clicking on the Targets tab, if you see an error that says something about \u201cUnsupported `ceph-iscsi` config version\u2026\u201d, perform the following steps: 1. Close the browser window where the error occurred 2. Restart the mon1 virtual machine. Do this with the following steps: from the Virtual Machine Manager on your lab machine (not in the admin virtual machine), restart the mon1 virtual machine by right-clicking on the mon1 virtual machine > Shut Down > Reboot 3. Wait at least 30 seconds, then from the admin node, open up the browser again and log in to the Ceph Dashboard: https://mon1.pvg.me.corp:8443 or https://10.58.121.186:8443 Username: admin Password: mypassword 4. Continue the lab as directed below by navigating to the Block > iSCSI section, clicking on the Targets tab, and completing the steps below 4). Click Add. Use the following values: Target IQN: Portals: mon2.example.net:172.17.6.132 Images: iscsi-images/fooiscsi ACL authentication: Click Create Target.","title":"Task 2: Define a new iSCSI target with the Ceph Dashboard"},{"location":"linux/SES/linux_ses_demo/#task-3-access-the-new-iscsi-target-from-the-admin-node","text":"1). On the admin node, launch YaST either the ncurses or GUI interface, and select the iSCSI Initiator module: YaST > Network Services > iSCSI Initiator 2). Select the Discovered Targets tab (alt-v) 3). Select Discovery at the bottom of the frame (alt-d) 4). Add the ip address of mon2: 10.58.121.187. Leave the port as the default of 3260. Select Next. 5). Once again on the Discovered Targets tab, the mon2 target should be listed. With the new target highlighted, select Connect (alt-e) at the bottom of the frame. 6). Leave the Startup (in YaST2) or On boot (in YaST) value as manual. Select Next. 7). Select OK to exit the iscsi client configuration module 8). To verify that the iscsi device is now connected, use the lsscsi command to list devices: You should see there is one disk of type RBD connected on a device file similar to the following: admin:~ # lsscsi [0:0:0:0] cd/dvd QEMU QEMU DVD-ROM 1.4. /dev/sr0 [2:0:0:0] disk SUSE RBD 4.0 /dev/sda 9). Create an ext4 filesystem on the connected device file: admin:~ # mkfs.ext4 /dev/sda mke2fs 1.43.8 (1-Jan-2018) Creating filesystem with 262144 4k blocks and 65536 inodes Filesystem UUID: e3896f7e-0664-4b14-85db-0f77cb234c43 Superblock backups stored on blocks: 32768, 98304, 163840, 229376 Allocating group tables: done Writing inode tables: done Creating journal (8192 blocks): done Writing superblocks and filesystem accounting information: done 10). Mount the device to /mnt: admin:~ # mount /dev/sda /mnt 11). Use the mount command to list the connected device: admin:/mnt # mount | grep sda /dev/sda on /mnt type ext4 (rw,relatime,stripe=1024,data=ordered) 12).Change the root user\u2019s home directory and unmount the device: admin:/mnt # cd .. admin:/ # umount /mnt","title":"Task 3: Access the new iSCSI target from the admin node"},{"location":"linux/SES/linux_ses_demo/#247-mount-cephfs-provided-by-suse-enterprise-storage","text":"In this lab a ceph user was configured to mount the ceph filesystem provided by the SUSE Enterprise Cluster. A keyfile was generated, then used in the process.","title":"2.4.7. Mount CephFS Provided by SUSE Enterprise Storage"},{"location":"linux/SES/linux_ses_demo/#task-1-verify-cephfs-configuration-of-the-ses-cluster","text":"1). Cephfs requires two pools for operation: one for data, the other for metadata. Verify that the cluster has two pools for this purpose: admin:~ # ceph fs ls name: cephfs, metadata pool: cephfs_metadata, data pools: [cephfs_data ] Task 2: Create a secret key file for the admin user on the admin node 1). Because cephx authentication is enabled by default on SUSE Enterprise Storage, a secret key will need to be provided to allow access to mount the ceph filesystem. The admin user (identified \u2013 in this case \u2013 on the system as root) on the admin node has a key, but we will need to either provide it on the command line during the mount process (less secure), or put it in a permissions-restricted file and point to the file when mounting (more secure). If we do not specify the key or a file with the key, we will get an error. The following command will return an error: admin:~ # mount -t ceph mon1:6789:/ /mnt 2021-01-07 14:16:36.924 7f45108a9d80 -1 auth: unable to find a keyring on /etc/ceph/ceph.client.guest.keyring,/etc/ceph/ceph.keyring,/etc/ceph/keyring,/etc/ceph/keyring.bin,: (2) No such file or directory mount error 22 = Invalid argument 2). Take secret key value found in the /etc/ceph/ceph.client.admin.keyring file and put it in a new file: admin:~ # cat /etc/ceph/ceph.client.admin.keyring [client.admin] key = caps mds = \"allow *\" caps mon = \"allow *\" caps osd = \"allow *\" caps mgr = \"allow *\" 3). Create a new file and paste the secret key value into it: admin:~ # vi /etc/ceph/admin.secret Put the key value into the file and save it. 4). Change the permissions of the file to be read only by the user: admin:~ # ls -l /etc/ceph/admin.secret -r-------- 1 root root 41 Jan 5 20:05 /etc/ceph/admin.secret","title":"Task 1: Verify cephfs configuration of the SES cluster"},{"location":"linux/SES/linux_ses_demo/#task-3-mount-the-ceph-filesystem-on-the-admin-node","text":"1). Now that the keyfile is created, we can mount the filesystem: admin:~ # mount -t ceph mon1:6789:/ /mnt -o name=admin,secretfile=/etc/ceph/admin.secret admin:~ # ls -l /mnt total 0 2). Verify that the mount shows as expected: admin:~ # mount | grep ceph 10.58.121.186:6789:/ on /mnt type ceph (rw,relatime,name=admin,secret=,acl) 3). Change to the root user\u2019s home directory and unmount the filesystem: admin:~ # cd ~ admin:~ # umount /mnt","title":"Task 3: Mount the ceph filesystem on the admin node"},{"location":"linux/SES/linux_ses_demo/#248-export-an-nfs-share-from-ses-with-nfs-ganesha","text":"","title":"2.4.8. Export an NFS Share from SES with NFS Ganesha"},{"location":"linux/SES/linux_ses_demo/#task-0-install-and-configure-ganesha-ganesha-config-location-is-not-configured-please-set-the-ganesha_rados_pool_namespace-setting","text":"admin:~ # zypper in nfs-ganesha admin:/etc/ganesha # cat ganesha.conf NFSv4 { RecoveryBackend = 'rados_cluster'; #RecoveryBackend = 'rados_ng'; } RADOS_URLS { ceph_conf = '/etc/ceph/ceph.conf'; userid = \"admin\"; watch_url = \"rados://data/ganesha-export-index/conf-nfs1\"; } RADOS_KV { pool = \"metadata\"; namespace = \"ganesha-grace\"; nodeid = \"nfs1\"; } %url rados://data/ganesha-export-index/conf-nfs1 admin:/etc/ganesha # ganesha-rados-grace -p metadata -n ganesha-grace add nfs1 nfs2 nfs3 admin:/etc/ganesha # ganesha-rados-grace -p metadata -n ganesha-grace cur=1 rec=0 ====================================================== nfs1 E nfs2 E nfs3 E http://images.45drives.com/ceph/cephfs/nfs-ganesha-ceph.conf","title":"Task 0: Install and configure Ganesha (Ganesha config location is not configured. Please set the GANESHA_RADOS_POOL_NAMESPACE setting.)"},{"location":"linux/SES/linux_ses_demo/#task-1-create-an-nfs-export-using-the-ceph-dashboard","text":"1). In a browser, navigate to a monitor to access the Ceph Dashboard and log in: https://10.58.121.186:8443/ Username: admin Password: mypassword 2). Click on the NFS tab near the top of the page 3). Click on the green Add button 4). Click on the Add daemon button to the right and select mon1 5). Complete the configuration with the following values: Storage Backend: Object Gateway Object Storage User: s3user Path: S3CMDTEST NFS Protocol: NFSv3 and NFSv4 checked NFS Tag: Pseudo: /S3BKT Access Type: RW Squash: root_squash Transport Protocol: UDP and TCP checked Clients: Click Submit","title":"Task 1: Create an NFS export using the Ceph Dashboard"},{"location":"linux/SES/linux_ses_demo/#task-2-mount-the-nfs-export-on-the-admin-node","text":"1). As the root user on the admin node, query the NFS Ganesha gateway node to see what mounts are available: showmount -e mon1 You should see something similar to the following: Export list for mon1: S3CMDTEST (everyone) 2). Mount the available nfs share to the /mnt directory on the admin server: mount -t nfs mon1:/S3BKT /mnt 3). List the nfs mount: mount | grep mnt Note the type listed as nfs4 4). Change to the root user\u2019s home directory and unmount the export: cd umount /mnt","title":"Task 2: Mount the NFS export on the admin node"},{"location":"linux/SES/linux_ses_demo/#249-configure-and-mount-cifs","text":"In this lab the Samba gateway was configured. A keyring for the Samba gateway was created, the Samba service was modified, and a user created to allow CIFS access to the SES cluster.","title":"2.4.9. Configure and Mount CIFS"},{"location":"linux/SES/linux_ses_demo/#task-1-prepare-the-cephfs-share-for-cifs","text":"1). In order for CIFS to work in our SES environment, a valid CephFS share must be available. The CephFS lab previously done in this workbook is sufficient. Using the same configuration that we used previously, mount the CephFS share and give permissions to all users at the root of the share: admin:~ # mount -t ceph mon1:6789:/ /mnt -o name=admin,secretfile=/etc/ceph/admin.secret admin:~ # chmod 777 /mnt admin:~ # l /mnt total 0 drwxrwxrwx 2 root root 0 Oct 5 14:30 ./ drwxr-xr-x 1 root root 156 Oct 5 08:53 ../ admin:~ # umount /mnt","title":"Task 1: Prepare the CephFS share for CIFS"},{"location":"linux/SES/linux_ses_demo/#task-2-create-a-samba-gateway-specific-keyring-on-the-ceph-admin-node-and-copy-it-to-the-samba-gateway-node","text":"1). A new keyring will be needed for the Samba gateway to allow access to the Ceph cluster. As root, perform the following: admin:~ # ceph auth get-or-create client.samba.gw mon 'allow r' osd 'allow *' mds 'allow *' -o ceph.client.samba.gw.keyring 2). Copy the new keyring to the Samba gateway node: admin:~ # scp ceph.client.samba.gw.keyring mon1:/etc/ceph/ ceph.client.samba.gw.keyring admin:~ # ssh mon1 Last login: Thu Jan 7 14:35:58 2021 from 10.58.121.181 mon1:~ # ls -l /etc/ceph/ total 12 -rw-r--r-- 1 root root 66 Jan 7 15:15 ceph.client.samba.gw.keyring -rw-r--r-- 1 root root 1095 Jan 5 22:44 ceph.conf -rw-r--r-- 1 root root 92 Aug 24 22:03 rbdmap","title":"Task 2: Create a Samba gateway specific keyring on the Ceph admin node and copy it to the Samba gateway node"},{"location":"linux/SES/linux_ses_demo/#task-3-configure-samba-on-the-samba-gateway-node","text":"1). The /etc/samba/smb.conf file will need to be edited to allow CIFS access to the storage cluster. On the mon1 node, replace all of the contents of the file with the following: admin:~ # ssh mon1 mon1:~ # vi /etc/samba/smb.conf mon1:/etc/samba # cat smb.conf [global] netbios name = SAMBA-GW clustering = no idmap config * : backend = tdb2 passdb backend = tdbsam # disable print server load printers = no smbd: backgroundqueue = no [ceph-smb] path = / vfs objects = ceph ceph: config_file = /etc/ceph/ceph.conf ceph: user_id = samba.gw read only = no oplocks = no kernel share modes = no 2). Create a smb user on the mon1 node named joesmb with a password of mypassword: mon1:/etc/samba # useradd joesmb mon1:/etc/samba # passwd joesmb ---> 123 Add joesmb to the smb password database with a password of mypassword: mon1:/etc/samba # smbpasswd -a joesmb New SMB password: ---> 123 Retype new SMB password: ---> 123 Added user joesmb. 3). Start and enable the smb and nmb daemons on mon1: mon1:/etc/samba # systemctl start smb nmb mon1:/etc/samba # systemctl enable smb nmb Created symlink /etc/systemd/system/multi-user.target.wants/smb.service \u2192 /usr/lib/systemd/system/smb.service. Created symlink /etc/systemd/system/multi-user.target.wants/nmb.service \u2192 /usr/lib/systemd/system/nmb.service. 4). Unmount the filesystem: mon1:~ # umount /mnt umount: /mnt: not mounted.","title":"Task 3: Configure Samba on the Samba gateway node"},{"location":"linux/SES/linux_ses_demo/#task-4-connect-a-client-to-the-samba-gateway","text":"1). On the admin node, verify that the Samba gateway is sharing via CIFS. The password is 123 admin:~ # smbclient -U joesmb -L //mon1 Enter WORKGROUP\\joesmb's password: ---> 123 Sharename Type Comment --------- ---- ------- ceph-smb Disk IPC$ IPC IPC Service (Samba 4.9.5-git.373.26895a83dbf3.44.1-SUSE-oS15.0-x86_64) Reconnecting with SMB1 for workgroup listing. Server Comment --------- ------- Workgroup Master --------- ------- GLOBAL CNPVGVSYB900 WORKGROUP SAMBA-GW 2). Connect to the ceph-smb share as joesmb. The password is 123 admin:~ # smbclient -U joesmb //mon1/ceph-smb Enter WORKGROUP\\joesmb's password: ---> 123 tree connect failed: NT_STATUS_BAD_NETWORK_NAME You should see output similar to the following: Try \u201chelp\u201d to get a list of possible commands. smb: \\>","title":"Task 4: Connect a client to the Samba gateway"},{"location":"linux/SES/linux_ses_memo/","text":"SUSE Enterprise Storage Foundation \u00b6 Ceph\u2019s RADOS \u00b6 Everything in Ceph is stored in the RADOS cluster as Objects. Ceph\u2019s RADOS: Reliable Autonomous Distributed Object Store Ceph\u2019s RADOS is composed of storage devices represented as: Raw storage device with LVM (BlueStore) Standard filesystem (FileStore) The Object Storage Daemon (OSD) integrates each disk device as part of the RADOS cluster. Ceph architecture \u00b6 Ceph is made of two groups of core components The RADOS cluster Provides the clustered object storage Native Object Access methods Gateways Access to the object store via standard protocols librados Direct access to the object store using a native API Examples: iSCSI Gateway (block) -- IGW - iSCSI is a storage area network (SAN) protocol. Exports RADOS Block Device (--RBD) (images as iSCSI disks). iSCSI access to RDB images. lrbd is no longer used in SES6. RADOS Gateway (object) -- RGW Is an object storage interface built on top of librados CephFS (file) A MetaData Service (MDS) is required. Direct access to RADOS (no LIBRADOS layer) Traditional filesystem interface. NFS Ganesha (object, file) Provides NFS exports to: RGW buckets for access the object store The CephFS filesystem Client access the storage services of the cluster via Gateways and Librados The librados API allows interaction with the following daemons: The Ceph Monitor, which maintains a master copy of the cluster map The Ceph OSD Daemon (OSD), which stores data as objects on a storage node. Enhanced SES Architecture Diagram \u00b6 Object Storage \u00b6 The state of the art of distributed SDS storage Unstructured, to better accommodate large files and large quantities of files For large files and large quantities of files, it performs far better than other storage mechanisms Agile, scalable, extensible, and very customizable Invisible to the end-user, ideal for backends Perfect for systemic, application-based use cases. Not necessarily perfect for direct Human use Through associated metadata, ideal for computational analytics And CRUSH takes full advantage of this (CRUSH = Controllable Replication Under Scalable Hashing) Ceph Object Storage supports two interfaces: S3-compatible Swift-compatible Object-based storage has become the standard backend storage mechanism for nearly all modern Enterprise Storage Solutions. Ceph OSDs (Object Storage Daemon) \u00b6 A Ceph OSD (object storage daemon, ceph-osd) stores data, handles data replication, recovery, rebalancing, and provides some monitoring information to Ceph Monitors and Managers by checking other Ceph OSD Daemons for a heartbeat. The Ceph Storage Cluster receives data from Ceph Clients. Clients (dedicated access points, e.g., gateway) could be a Ceph Block Device, Ceph Object Storage, the Ceph Filesystem or a custom implementation using librados. The client requests the cluster status from a monitor node The client uses the status information to identify the location of objects in the cluster The client accesses the objects directly via the OSD node The OSD then stores the data as objects. Each object corresponds to a file in a filesystem which is stored on an OSD. The OSD Daemons take care of the reads and writes on the storage disks. When OSDs are deployed in SES5 the default is to use BlueStore which uses the raw disk and does not require a linux file system to be placed on the disk before it can be used. OSD Daemons store all data as objects in a flat namespace, i.e. no hierarchy of directories. At least 3 Ceph OSDs are normally required for redundancy and high availability. Ceph Mons (Monitor Servers) \u00b6 A Ceph Monitor (ceph-mon) maintains maps of the cluster state, including Monitor Map Manager Map OSD Map PG Map CRUSH Map Epoch These maps are critical cluster state required for Ceph daemons to coordinate with each other. Monitors are also responsible for managing authentication between daemons and clients. At least 3 monitors are normally required for redundancy and high availability. An odd number of MONs is required (Paxos requires). Typically 5 is sufficient for mid or large size cluster. Paxos is an algorithm used for cluster durability. Leader MON expects 50% quality to create quorum. Lowest IP address becomes leader. After new leader selected, all MONs polled for epoch. Leader Mon provides lease to non-leader MONs. MONs are NOT in the data path. They merely serve maps to clients so that the client can go directly to the appropriate OSD storage daemon. Monitor nodes MONs do not serve objects to clients Ceph MGRs (Manager Daemon) \u00b6 A Ceph Manager daemon (ceph-mgr) is responsible for keeping track of runtime metrics and the current state of the Ceph cluster, including storage utilization current performance metrics system load The Ceph Manager daemons also host python-based plugins to manage and expose Ceph cluster information, including a web-based dashboard and REST API. At least two managers are normally required for high availability. MON/MGR daemons are required to run on the same node in SES Ceph MDS (Metadata) \u00b6 A Ceph Metadata Server (MDS, ceph-mds) stores metadata on behalf of the Ceph Filesystem. Ceph Metadata Servers allow POSIX file system users to execute basic commands, for example ls -al without placing an large load on the Ceph Storage Cluster. Ceph Admin Node \u00b6 The Admin node fills the \u201cmaster\u201d and \u201cadmin\u201d roles for DeepSea. Salt is central to SES. SES\u2019s deployment and life-cycle management tool. The Admin node keeps master Ceph authentication keys. Prometheus and Grafana provide cluster monitoring and data graphs Ceph Dashboard \u00b6 Runs as a Ceph Manager module; runs via the MON/MGR node. Client Access \u00b6 Object Storage (RADOSGW or RGW) Block Storage (RDB). RBD is built on top of librados. CephFS iSCSI Gateway NFS Ganesha SMB/CIFS Native protocols via librados Objects in Ceph \u00b6 Everything stored in the Ceph cluster is an object. Default object size is 4MB. Each object has a unique ID. ID is unique across the entire cluster. Objects have associated metadata, in Key: Value pairs. In Ceph we use Storage Pools to organize or arrange our objects. Pools are logical partitions to manage objects Parameters to manage Pools Number of data replicas (Replica pools), or configuration of Erasure Code (size) (Erasure Code pools) Erasure Code is an alternative to Replication SIZE for Erasure Coding is K+M K = Data chunks, M = \u201cParity\u201d chunks EC reduces the hit to raw storage capacity EC incurs a greater hit to CPU on the OSDs as a tradeoff Placement Groups (PG) PG is used to manage objects within a pool. PGs are associated with OSDs for data placement PGs are a central feature of CRUSH that help to provide data durability by way of distribution No PG is owned by an OSD. (And an OSD is not owned by a PG.) PGs are just randomly assigned by CRUSH through all of the OSDs to spread the distribution of data Locating data among PGs is all handled economically, deterministically by way of CRUSH calculations PGs are subdivisions of pools Number of PGs = (Number of OSDs * 100) / Size (Size = either num of replicas, or K+M) The final PG number must be a power of 2 The default number of PGs for a new pool is 8 (it's too small for enterprise solution) In general, PG and PGP numbers should be the same pg_num is the number of placement groups for the pool (placement group, \u5b58\u50a8\u6c60\u7684\u76ee\u5f55\u4e2a\u6570 ) pgp_num is the number of placement groups that will be considered for placement (placement group for placement purpose, pg\u53ef\u7528\u7684osd\u6392\u5217\u7ec4\u5408\u6570\u91cf) \u4ec5\u589e\u5927pg_num\uff1a \u56e0\u4e3apgp_num\u6ca1\u53d8\uff0cpg\u7684osd\u7ec4\u5408\u4ecd\u53ea\u80fd\u4ece\u5f53\u524dpgp_num\u79cd\u7ec4\u5408\u91cc\u9762\u6311\u9009\uff0c\u5bfc\u81f4\u65b0\u589e\u7684pg\u548c\u65e7pg\u4f1a\u6709\u91cd\u590d\u7684osd\u7ec4\u5408\uff0c\u8be5\u73b0\u8c61\u79f0\u4e4b\u4e3a\u5206\u88c2\uff1b\u6b64\u65f6pg\u548cosd\u7684\u6620\u5c04\u6ca1\u6709\u53d8\uff1b \u7ee7\u7eed\u589e\u5927pgp_num\uff0c\u4f7f\u5176\u7b49\u4e8epg_num\uff1a \u65e7pg\u6ca1\u6709\u53d8\u5316\uff0c\u4f46\u65b0\u589epg\u7684osd\u7ec4\u5408\u53d1\u751f\u53d8\u5316\uff0c\u5373\u5f00\u59cb\u91cd\u65b0\u5206\u5e03 Placement Group (PG) \u5f52\u7f6e\u7ec4\u72b6\u6001 Creating \u521b\u5efa\u5b58\u50a8\u6c60\u65f6\uff0c\u5b83\u4f1a\u521b\u5efa\u6307\u5b9a\u6570\u91cf\u7684\u5f52\u7f6e\u7ec4\u3002 ceph \u5728\u521b\u5efa\u4e00\u6216\u591a\u4e2a\u5f52\u7f6e\u7ec4\u65f6\u4f1a\u663e\u793a creating\u3002 \u521b\u5efa\u5b8c\u540e\uff0c\u5728\u5176\u5f52\u7f6e\u7ec4\u7684 Acting Set \u91cc\u7684 OSD \u5c06\u5efa\u7acb\u4e92\u8054\u3002 \u4e00\u65e6\u4e92\u8054\u5b8c\u6210\uff0c\u5f52\u7f6e\u7ec4\u72b6\u6001\u5e94\u8be5\u53d8\u4e3a active+clean\uff0c\u610f\u601d\u662fceph \u5ba2\u6237\u7aef\u53ef\u4ee5\u5411\u5f52\u7f6e\u7ec4\u5199\u5165\u6570\u636e\u4e86\u3002 peering ceph \u4e3a\u5f52\u7f6e\u7ec4\u5efa\u7acb\u4e92\u8054\u65f6\uff0c\u4f1a\u8ba9\u5b58\u50a8\u5f52\u7f6e\u7ec4\u526f\u672c\u7684 OSD \u4e4b\u95f4\u5c31\u5176\u4e2d\u7684\u5bf9\u8c61\u548c\u5143\u6570\u636e\u72b6\u6001\u8fbe\u6210\u4e00\u81f4\u3002 ceph \u5b8c\u6210\u4e86\u4e92\u8054\uff0c\u4e5f\u5c31\u610f\u5473\u7740\u5b58\u50a8\u7740\u5f52\u7f6e\u7ec4\u7684 OSD \u5c31\u5176\u5f53\u524d\u72b6\u6001\u8fbe\u6210\u4e86\u4e00\u81f4\u3002 \u7136\u800c\uff0c\u4e92\u8054\u8fc7\u7a0b\u7684\u5b8c\u6210\u5e76\u4e0d\u80fd\u8868\u660e\u5404\u526f\u672c\u90fd\u6709\u4e86\u6570\u636e\u7684\u6700\u65b0\u7248\u672c\u3002 active ceph \u5b8c\u6210\u4e92\u8054\u8fdb\u7a0b\u540e,\u4e00\u5f52\u7f6e\u7ec4\u5c31\u53ef\u53d8\u4e3a active\u3002 active \u72b6\u6001\u901a\u5e38\u610f\u5473\u7740\u5728\u4e3b\u5f52\u7f6e\u7ec4\u548c\u526f\u672c\u4e2d\u7684\u6570\u636e\u90fd\u53ef\u4ee5\u8bfb\u5199\u3002 clean \u67d0\u4e00\u5f52\u7f6e\u7ec4\u5904\u4e8e clean \u72b6\u6001\u65f6\uff0c\u4e3b OSD \u548c\u526f\u672c OSD \u5df2\u6210\u529f\u4e92\u8054\uff0c\u5e76\u4e14\u6ca1\u6709\u504f\u79bb\u7684\u5f52\u7f6e\u7ec4\u3002 ceph \u5df2\u628a\u5f52\u7f6e\u7ec4\u4e2d\u7684\u5bf9\u8c61\u590d\u5236\u4e86\u89c4\u5b9a\u6b21\u6570\u3002 degraded \u5f53\u5ba2\u6237\u7aef\u5411\u4e3b OSD \u5199\u5165\u6570\u636e\u65f6\uff0c\u7531\u4e3b OSD \u8d1f\u8d23\u628a\u526f\u672c\u5199\u5165\u5176\u4f59\u590d\u5236 OSD\u3002 \u4e3b OSD \u628a\u5bf9\u8c61\u5199\u5165\u590d\u5236 OSD \u540e\uff0c\u5728\u6ca1\u6536\u5230\u6210\u529f\u5b8c\u6210\u7684\u786e\u8ba4\u524d\uff0c\u4e3b OSD \u4f1a\u4e00\u76f4\u505c\u7559\u5728 degraded \u72b6\u6001\u3002 \u5f52\u7f6e\u7ec4\u72b6\u6001\u53ef\u4ee5\u662f active+degraded \u72b6\u6001\uff0c\u539f\u56e0\u5728\u4e8e\u4e00 OSD \u5373\u4f7f\u6ca1\u6240\u6709\u5bf9\u8c61\u4e5f\u53ef\u4ee5\u5904\u4e8e active \u72b6\u6001\u3002 \u5982\u679c\u4e00OSD \u6302\u4e86\uff0cceph \u4f1a\u628a\u76f8\u5173\u7684\u5f52\u7f6e\u7ec4\u90fd\u6807\u8bb0\u4e3a degraded\u3002 \u90a3\u4e2a OSD \u91cd\u751f\u540e\uff0c\u5b83\u4eec\u5fc5\u987b\u91cd\u65b0\u4e92\u8054\u3002 \u7136\u800c\uff0c\u5982\u679c\u5f52\u7f6e\u7ec4\u4ecd\u5904\u4e8e active \u72b6\u6001\uff0c\u5373\u4fbf\u5b83\u5904\u4e8e degraded \u72b6\u6001\uff0c\u5ba2\u6237\u7aef\u8fd8\u53ef\u4ee5\u5411\u5176\u5199\u5165\u65b0\u5bf9\u8c61\u3002 \u5982\u679c\u4e00 OSD \u6302\u4e86\uff0c\u4e14 degraded \u72b6\u6001\u6301\u7eed\uff0cceph \u4f1a\u628a down \u7684 OSD \u6807\u8bb0\u4e3a\u5728\u96c6\u7fa4\u5916(out)\u3001\u5e76\u628a\u90a3\u4e9b down \u6389\u7684 OSD \u4e0a\u7684\u6570\u636e\u91cd\u6620\u5c04\u5230\u5176\u5b83 OSD\u3002 \u4ece\u6807\u8bb0\u4e3a down \u5230 out \u7684\u65f6\u95f4\u95f4\u9694\u7531 mon osd down out interval \u63a7\u5236,\u9ed8\u8ba4\u662f 300 \u79d2\u3002 \u5f52\u7f6e\u7ec4\u4e5f\u4f1a\u88ab\u964d\u7ea7(degraded)\uff0c\u56e0\u4e3a\u5f52\u7f6e\u7ec4\u627e\u4e0d\u5230\u672c\u5e94\u5b58\u5728\u4e8e\u5f52\u7f6e\u7ec4\u4e2d\u7684\u4e00\u6216\u591a\u4e2a\u5bf9\u8c61\uff0c\u8fd9\u65f6\uff0c\u4f60\u4e0d\u80fd\u8bfb\u6216\u5199\u627e\u4e0d\u5230\u7684\u5bf9\u8c61\uff0c\u4f46\u4ecd\u80fd\u8bbf\u95ee\u5176\u5b83\u4f4d\u4e8e\u964d\u7ea7\u5f52\u7f6e\u7ec4\u4e2d\u7684\u5bf9\u8c61\u3002 recovering ceph \u88ab\u8bbe\u8ba1\u4e3a\u53ef\u5bb9\u9519\uff0c\u53ef\u62b5\u5fa1\u4e00\u5b9a\u89c4\u6a21\u7684\u8f6f\u3001\u786c\u4ef6\u95ee\u9898\u3002 \u5f53\u67d0 OSD \u6302\u4e86(down)\u65f6\uff0c\u5176\u5185\u5bb9\u7248\u672c\u4f1a\u843d\u540e\u4e8e\u5f52\u7f6e\u7ec4\u5185\u7684\u5176\u5b83\u526f\u672c\u3002 \u5b83\u91cd\u751f(up)\u65f6\uff0c\u5f52\u7f6e\u7ec4\u5185\u5bb9\u5fc5\u987b\u66f4\u65b0\uff0c\u4ee5\u53cd\u6620\u5f53\u524d\u72b6\u6001\u3002 \u5728\u6b64\u671f\u95f4\uff0cOSD \u5728recovering \u72b6\u6001\u3002 \u4e00\u6b21\u786c\u4ef6\u5931\u8d25\u53ef\u80fd\u7275\u8fde\u591a\u4e2a OSD\u3002\u6bd4\u5982\u4e00\u4e2a\u673a\u67dc\u7684\u7f51\u7edc\u4ea4\u6362\u673a\u5931\u8d25\u4e86\uff0c\u8fd9\u4f1a\u5bfc\u81f4\u591a\u4e2a\u4e3b\u673a\u843d\u540e\u4e8e\u96c6\u7fa4\u7684\u5f53\u524d\u72b6\u6001\uff0c\u95ee\u9898\u89e3\u51b3\u540e\u6bcf\u4e00\u4e2a OSD \u90fd\u5fc5\u987b\u6062\u590d\u3002 ceph \u63d0\u4f9b\u4e86\u5f88\u591a\u9009\u9879\u6765\u5747\u8861\u8d44\u6e90\u7ade\u4e89\uff0c\u5982\u65b0\u670d\u52a1\u8bf7\u6c42\u3001\u6062\u590d\u6570\u636e\u5bf9\u8c61\u548c\u6062\u590d\u5f52\u7f6e\u7ec4\u5230\u5f53\u524d\u72b6\u6001\u3002 osd recovery delay start \u9009\u9879\u5141\u8bb8\u4e00 OSD \u5728\u5f00\u59cb\u6062\u590d\u8fdb\u7a0b\u524d\uff0c\u5148\u91cd\u542f\u3001\u91cd\u5efa\u4e92\u8054\u3001\u751a\u81f3\u5904\u7406\u4e00\u4e9b\u91cd\u653e\u8bf7\u6c42\u3002 osd recovery threads \u9009\u9879\u9650\u5236\u6062\u590d\u8fdb\u7a0b\u7684\u7ebf\u7a0b\u6570\uff0c\u9ed8\u8ba4\u4e3a 1 \u7ebf\u7a0b\u3002 osd recovery thread timeout \u8bbe\u7f6e\u7ebf\u7a0b\u8d85\u65f6\uff0c\u56e0\u4e3a\u591a\u4e2aOSD \u53ef\u80fd\u4ea4\u66ff\u5931\u8d25\u3001\u91cd\u542f\u548c\u91cd\u5efa\u4e92\u8054\u3002 osd recovery max active \u9009\u9879\u9650\u5236\u4e00 OSD \u6700\u591a\u540c\u65f6\u63a5\u53d7\u591a\u5c11\u8bf7\u6c42\uff0c\u4ee5\u9632\u5b83\u538b\u529b\u8fc7\u5927\u800c\u4e0d\u80fd\u6b63\u5e38\u670d\u52a1\u3002 osd recovery max chunk \u9009\u9879\u9650\u5236\u6062\u590d\u6570\u636e\u5757\u5c3a\u5bf8\uff0c\u4ee5\u9632\u7f51\u7edc\u62e5\u585e\u3002 back filling \u6709\u65b0 OSD \u52a0\u5165\u96c6\u7fa4\u65f6\uff0cCRUSH \u4f1a\u628a\u73b0\u6709\u96c6\u7fa4\u5185\u7684\u5f52\u7f6e\u7ec4\u91cd\u5206\u914d\u7ed9\u5b83\u3002 \u5f3a\u5236\u65b0 OSD \u7acb\u5373\u63a5\u53d7\u91cd\u5206\u914d\u7684\u5f52\u7f6e\u7ec4\u4f1a\u4f7f\u4e4b\u8fc7\u8f7d\uff0c\u7528\u5f52\u7f6e\u7ec4\u56de\u586b\u53ef\u4f7f\u8fd9\u4e2a\u8fc7\u7a0b\u5728\u540e\u53f0\u5f00\u59cb\u3002 \u56de\u586b\u5b8c\u6210\u540e\uff0c\u65b0 OSD \u51c6\u5907\u597d\u65f6\u5c31\u53ef\u4ee5\u5bf9\u5916\u670d\u52a1\u4e86\u3002 remapped \u67d0\u4e00\u5f52\u7f6e\u7ec4\u7684 Acting Set \u53d8\u66f4\u65f6\uff0c\u6570\u636e\u8981\u4ece\u65e7\u96c6\u5408\u8fc1\u79fb\u5230\u65b0\u7684\u3002 \u4e3b OSD \u8981\u82b1\u8d39\u4e00\u4e9b\u65f6\u95f4\u624d\u80fd\u63d0\u4f9b\u670d\u52a1\uff0c\u6240\u4ee5\u5b83\u53ef\u4ee5\u8ba9\u8001\u7684\u4e3b OSD \u6301\u7eed\u670d\u52a1\u3001\u76f4\u5230\u5f52\u7f6e\u7ec4\u8fc1\u79fb\u5b8c\u3002 \u6570\u636e\u8fc1\u79fb\u5b8c\u540e,\u4e3b OSD \u4f1a\u6620\u5c04\u5230\u65b0 acting set\u3002 stale \u867d\u7136 ceph \u7528\u5fc3\u8df3\u6765\u4fdd\u8bc1\u4e3b\u673a\u548c\u5b88\u62a4\u8fdb\u7a0b\u5728\u8fd0\u884c\uff0c\u4f46\u662f ceph-osd \u4ecd\u6709\u53ef\u80fd\u8fdb\u5165 stuck \u72b6\u6001\uff0c\u5b83\u4eec\u6ca1\u6709\u6309\u65f6\u62a5\u544a\u5176\u72b6\u6001(\u5982\u7f51\u7edc\u77ac\u65ad)\u3002 \u9ed8\u8ba4OSD \u5b88\u62a4\u8fdb\u7a0b\u6bcf\u534a\u79d2(0.5)\u4f1a\u4e00\u6b21\u62a5\u544a\u5176\u5f52\u7f6e\u7ec4\u3001\u51fa\u6d41\u91cf\u3001\u5f15\u5bfc\u548c\u5931\u8d25\u7edf\u8ba1\u72b6\u6001\uff0c\u6b64\u9891\u7387\u9ad8\u4e8e\u5fc3\u8df3\u9600\u503c\u3002 \u5982\u679c\u4e00\u5f52\u7f6e\u7ec4\u7684\u4e3b OSD \u6240\u5728\u7684 acting set \u6ca1\u80fd\u5411\u76d1\u89c6\u5668\u62a5\u544a\u3001\u6216\u8005\u5176\u5b83\u76d1\u89c6\u5668\u5df2\u7ecf\u62a5\u544a\u4e86\u90a3\u4e2a\u4e3b OSD \u5df2 down\uff0c\u76d1\u89c6\u5668\u4eec\u5c31\u4f1a\u628a\u6b64\u5f52\u7f6e\u7ec4\u6807\u8bb0\u4e3a stale\u3002 \u542f\u52a8\u96c6\u7fa4\u65f6\uff0c\u4f1a\u7ecf\u5e38\u770b\u5230 stale \u72b6\u6001\uff0c\u76f4\u5230\u4e92\u8054\u5b8c\u6210\u3002 \u96c6\u7fa4\u8fd0\u884c\u4e00\u9635\u540e\uff0c\u5982\u679c\u8fd8\u80fd\u770b\u5230\u6709\u5f52\u7f6e\u7ec4\u4f4d\u4e8e stale \u72b6\u6001\uff0c\u5c31\u8bf4\u660e\u90a3\u4e9b\u5f52\u7f6e\u7ec4\u7684\u4e3b OSD \u6302\u4e86(down)\u3001\u6216\u6ca1\u5728\u5411\u76d1\u89c6\u5668\u62a5\u544a\u7edf\u8ba1\u4fe1\u606f\u3002 Each pool has its own autoscaler settings The PG balancer optimizes the placement of PGs across OSD crush-compat mode It's default mode Uses the compat weight-set feature upmap mode. It's perfect mode, which an equal number of PGs on each OSD Use fine-grained control over the PG mapping Snapshots Rulesets to manage CRUSH placement Each pool has a defined CRUSH ruleset A CRUSH ruleset is a definition of how the OSDs organize data This allows configuration of data distribution to be managed per pool A single CRUSH ruleset can be reused by multiple pools A ruleset can take into account: \u9700\u8981\u8003\u8651\u7684\u70b9 physical layout of nodes in the cluster organization of network infrastructure selection of OSDs backed by SSDs versus HDDs, etc Each pool can use either Replication or Erasure Coding Replication is the original, default approach to resiliency Erasure Coded pools have an EC Profile assigned Different than CRUSH rulesets, but similar: define how OSDs organize data The profile defines K, M values; encoding method/plugin; etc CRUSH (Controllable Replication Under Scalable Hashing) \u00b6 CRUSH is a key piece of the Ceph storage solution With the CRUSH algorithm used by Ceph: Data is not centrally stored, it is distributed CRUSH calculates the storage location for each object dynamically No requirement to store a global index of object locations CRUSH Algorithm \u00b6 The CRUSH algorithm deterministically calculates the location of any object in the Ceph RADOS cluster Overhead is low and calculation is performed by each client As no metadata store is required, CRUSH removes the limitations of traditional metadata based management No direct control over the placement of your data in the cluster Higher CPU requirements CRUSH Maps and Rulesets \u00b6 CRUSH Rulesets are the named sets of rules: Combining all of the customizable CRUSH behavior settings Assigned to pool to govern how the pool\u2019s data is distributed in the cluster CRUSH Maps are central to how Ceph distributes data, and maintaining the durability of the data When the cluster is deployed, Ceph creates a simple default ruleset for replicated pools: replicated_rule CRUSH behavior depends on the behaviors and performance of storage devices CRUSH Maps should be crafted to take advantage of those behaviors Rulesets should be used to clearly identify how the devices in your environment should be employed Device Classes exist to indicate performance behavior: hdd, ssd, nvme Ceph OSDs will automatically set the Device Class of a storage device when the OSD is started Working with CRUSH Map Rulesets List the OSDs, which host each OSD belongs to: ceph osd tree ceph osd df tree ceph osd df tree -f json-pretty Find the host of a specific OSD: ceph osd find 8 Show the existing defined rulesets: ceph osd crush rule ls Examine the definition of an existing ruleset: ceph osd crush rule dump There are 3 options for creating a new ruleset: simple replicated erasure Creating new rulesets: ceph osd crush rule create-replicated ceph osd crush rule create-erasure Create a new ruleset using a Device Class: create-replicated Description : The name of the node under which data should be placed. Type : String Example : default (rarely would you need to make this different than \u201cdefault\u201d) or Description : The type of CRUSH node (bucket) across which replicas should be separated. Type : String Example : rack Description : The device class data should be placed on. Type : String Example : ssd CRUSH Weight \u00b6 You may need to move data around New nodes degraded nodes rebalancing View the current CRUSH weights ceph osd crush tree ceph osd df tree Change the weight for an OSD ceph osd crush reweight The important difference between ceph osd reweight and ceph osd crush reweight \"ceph osd crush reweight\" sets the CRUSH weight of the OSD. This weight is an arbitrary value (generally the size of the disk in TB or something) and controls how much data the system tries to allocate to the OSD. \"ceph osd reweight\" sets an override weight on the OSD. This value is in the range 0 to 1, and forces CRUSH to re-place (1-weight) of the data that would otherwise live on this drive. It does not change the weights assigned to the buckets above the OSD, and is a corrective measure in case the normal CRUSH distribution isn\u2019t working out quite right. \"ceph osd reweight\" is temporary. \"ceph osd crush reweight\" is sticky, permanent (until you change it again). Setting a weight of an OSD to 0 is effectively setting the OSD \"out\" - you don\u2019t want it to store data. The Monitor\u2019s Cluster Map contains \u00b6 Monitor Map Unique Cluster ID, details of each Mon node, current epoch, date/time of last change OSD Map Contains the cluster fsid, when the map was created and last modified, a list of pools, replica sizes, PG numbers, a list of OSDs and their status PG Map Contains the PG version, its time stamp, the last OSD map epoch, the full ratios, and details on each placement group such as the PG ID, the Up Set, the Acting Set, the state of the PG (e.g., active + clean), and data usage statistics for each pool MDS Map Contains the current MDS map epoch, references to pool(s) for storing metadata, list of MDS servers, and which metadata servers are up and in CRUSH Map Contains a list of storage devices, the failure domain hierarchy (e.g., device, host, rack, row, room, etc.), and rules for traversing the hierarchy when storing data CRUSH Hierarchy \u00b6 The CRUSH Map includes details of physical & network infrastructure The CRUSH Map hierarchy is defined by a storage architect The default hierarchical list of infrastructure elements: (Hierarchy of CRUSH buckets) OSD host chassis \u5200\u7247\u673a\u7bb1 rack \u673a\u67b6 row pdu \u7535\u6e90\u5206\u914d\u5355\u5143 pod \u6027\u80fd\u4f18\u5316\u7684\u6570\u636e\u4e2d\u5fc3(Performance Optimize Datacenter)\uff0c\u57fa\u4e8e\u6807\u51c6\u5316\u8bbe\u65bd\u7684\u6700\u4f73\u5b9e\u8df5\uff0c\u6bcf\u4e2aPOD\u5185IT\u90e8\u5206\u5305\u542b\u76845000\u53f0\u670d\u52a1\u5668\uff0c\u5206\u5c5e\u5230200\u4e2a\u673a\u67b6\uff0c\u5982\u679c\u4ee5\u6bcf\u53f0\u670d\u52a1\u5668400W\u529f\u7387\u8ba1\u7b97\u7684\u8bdd\uff0c\u6bcf\u4e2a\u673a\u67dc\u9700\u898110KW\u7684\u4f9b\u7535\uff0c\u5373\u6bcf\u4e2aPOD\u7684IT\u8d1f\u8f7d\u5bb9\u91cf\u662f2MW\u3002 room datacenter region root CRUSH is the algorithm and calculation for distributing data through the cluster. CRUSH Map obviously plays a part in how those CRUSH calculations work. CRUSH Map Sections (Six main sections) \u00b6 tunables: adjustments to legacy behavior devices: The list of OSDs (usually no customization needed) \u25cb \"device class\" is meaningful; useful in relation to creating/using CRUSH rulesets \u25cb Standard \"device class\" values are \"hdd.\", \"ssd.\", and \"nvme.\" \u25cb Example: device 7 osd.7 types: types of buckets (usually no customization needed) buckets: the most functional, customizable aspect of the Map \u25cb A bucket typically represents a physical location in the cluster, has a \u201ctype\u201d \u25cb Nodes (containers such as hosts) and leaves (storage devices such as OSDs) rules: define policies of how data should be distributed \u25cb The behind-the-scenes rules that CRUSH follows for data placement \u25cb IMPORTANT: this is NOT the same as the \"ruleset\". In fact, a ruleset is the combined set of all of these six Map sections. choose_args (optional): Rarely used exceptional settings to adjust weights From the documentation: \"choose_args are alternative weights associated with the hierarchy that have been adjusted to optimize data placement. A single choose_args map can be used for the entire cluster, or one can be created for each individual pool.\" Erasure Coding \u00b6 In information theory : an erasure code is a forward error correction (FEC, \u524d\u5411\u7ea0\u9519) code for the binary erasure channel, which transforms a message of k symbols into a longer message (code word) with n symbols such that the original message can be recovered from a subset of the n symbols. The fraction r = k/n is called the code rate The fraction k\u2019/k, where k\u2019 denotes the number of symbols required for recovery, is called reception efficiency Another (easier) way of describing EC: It\u2019s like RAID in Clustered Storage Erasure Coding in SES \u00b6 The default resilience strategy in SES is simple replication * SES Simple replication has overheads, size=3 means 3 times the storage requirements Simplistic EC details: k = number of \u201cdata\u201d chunks, split across \u201ck\u201d number of OSDs m = number of \u201cparity\u201d chunks, split across \u201cm\u201d number of OSDs Ceph calls these \u201ccoding chunks\u201d r (size) = k + m admin:~ # ceph osd crush rule ls replicated_rule Replication vs Erasure Code \u00b6 Replication (default): Use Case: active data Simple and fast Uses more disk space Erasure coding: Use Case: archive data, more static data Calculates recovery data (needs more CPU power) Definable redundancy level Example: K data chunks = 2 , M code chunks = 1 Similar to a replication size of 2 But with only 50% more raw storage consumed Example: for 1GB of effective storage replication pool of size of 2 needs 2GB raw storage erasure coded pool with k=2/m=1 only requires 1.5GB raw storage EC Overwrites \u00b6 Historically, EC only works properly with Objects EC only allowed appends; overwrites were not allowed Works perfectly for objects in buckets but doesn\u2019t work well with Block or CephFS With recent releases of SES, EC can work well with Block and CephFS Facilitated by \u201cEC Overwrites\u201d feature Store data in an EC Pool, and store object metadata in a Replicated Pool Requires a little extra work when defining pools, but worth it ceph osd pool set allow_ec_overwrites true EC Profiles \u00b6 Using Erasure Coding, each Pool is assigned an EC Profile Multiple pools can share a single Profile The profile is just a definition Each Profile has multiple settings The common required settings for all Profiles are K, M EC Profiles must be created before EC Pools can be created Created from the Dashboard or CLI Once an EC Profile is created, you can create a CRUSH Ruleset based on the EC profile Once a pool is created, its EC Profile properties cannot be changed Main profile parameters K: M: stripe_unit - allows you to adjust the size of the data chunk Default size is 4K stripe_unit : size of data striped across devices; default 4K This variable can also be set in the master configuration (osd_erasure_code_stripe_unit) EC plugins - choose your favorite EC algorithm via a plugin jerasure/gf-complete (default, free, open, and very fast) (www.jerasure.org) ISA (Intel library; optimized for modern Intel processors) (only runs on Intel processors) LRC (\u201cLocally Repairable Code\u201d; layers over existing plugins) SHEC (\u201cShingled EC\u201d; trades extra storage for recovery efficiency) CLAY (\u201cCoupled LAYer\u201d; good for reduced network traffic) Creating Erasure Code Profiles and Pools \u00b6 Syntax: ceph osd erasure-code-profile OPTIONS Option Description get - view details of an existing EC profile set - set a profile (create a profile), requires k and m values, with optional values such as ruleset, plugin. Once you create a profile, you can\u2019t change it. ceph osd erasure-code-profile set k= m= [plugin=] [stripe_unit=] ls - list profiles rm - Remove an EC profile ceph osd erasure-code-profile rm Common example (below) The default profile \u2012 2+1=3; data is written over 3 OSDs \u2012 Two data chunks \u2012 One code (parity) chunk \u2012 Uses jerasure plugin with standard Reed/Solomon (reed_sol_van) technique Setting a Custom EC Profile Option: \u2012 Profile name \u2012 K : number of stripes required \u2012 M : number of failed units Example: ceph osd erasure-code-profile set example-profile k=8 m=2 ruleset-failure-domain=host ruleset-failure-domain = crush bucket level for failure admin:/etc/ceph # ceph osd erasure-code-profile \\ set common_profile \\ k=4 \\ m=2 \\ plugin=jerasure \\ technique=reed_sol_van \\ stripe_unit=4K \\ crush-root=default \\ crush-failure-domain=rackcrush-device-class=ssd admin:/etc/ceph # ceph osd erasure-code-profile ls default admin:~ # ceph osd erasure-code-profile get default k=2 m=1 plugin=jerasure technique=reed_sol_van Pools Pools are at the heart of Storage Pools are tied to OSDs Display a list of existing pools: ceph osd pool ls or ceph osd lspools View the statistics and characteristics of pools: ceph osd pool stats ceph osd pool stats ceph osd pool get Show usage and related details of existing pools: rados df or ceph df or ceph df detail All storage revolves around Pools Each pool must be dedicated to a purpose: Object, Block, File Must specify # of Placement Groups and PG Placements Must specify whether using Replication or EC Must specify a CRUSH ruleset Create a Replicated Pool Syntax: ceph osd pool create replicated = number of placement groups for the pool = number of PGs for placement; routinely will be the same as pg_num Always a power of 2 Don\u2019t make the number too small; don\u2019t err on the high side, either Practices For a new pool, the pgp_num will generally (likley) just be the same as the pg_num When increasing the PGs in a pool, you may want to retain the smaller pgp_num to minimize rebalancing, and increase pgp_num later when rebalancing is more convenient If decreasing the PGs in a pool, the pgp_num is adjusted automatically Create an EC Pool (using an EC Profile) Syntax: ceph osd pool create erasure Example: ceph osd pool create EC-pool 128 128 erasure my-ec-profile Pools \u2013 Application Assignment Each Pool must have a stated purpose; application This defines which capabilities the Pool must support The applications are: Block (rbd), Object (rgw), and File (cephfs) There are subtypes of cephfs: i.e. cephfs:data, cephfs:metadata Application assignment happens after creating a pool It\u2019s effortless (and required) to assign an application on a new pool ceph osd pool application enable Changing application assignment after a pool is in use is \u201chard\u201d. Not recommended, only to be done as an expert Pools \u2013 Quotas One of the more desirable features of SDS is to set a maximum usage of a Pool - Quotas Prevent the over-use of a pool Set quotas based on number of objects or number of bytes ceph osd pool set-quota max_objects ceph osd pool set-quota max_bytes Show quota settings ceph osd pool get-quota To remove a quota, set the existing quota setting to 0 There are also application-level quotas For rgw and cephfs (not rbd; images are already limited in size) Pool Quotas vs. Application Quotas. When a pool quota nears its limit, the HEALTH mechanisms will display a \u201cPOOL_NEAR_FULL\u201d warning to the storage administrator. When the quota limit has been exceeded, the HEALTH mechanisms will display a \u201cPOOL_FULL\u201d warning to the storage administrator. Applications (clients) don\u2019t always handle the quotas cleanly. In most cases, once the Pool Quota is exceeded, the application will simply stop writing to the pool, and error messages and behavior at the application are inconsistent (if there are any messages at all). Pools \u2013 Snapshots Take (make) a snapshot of an existing pool ceph osd pool mksnap Remove a snapshot of a pool ceph osd pool rmsnap List pool snapshots rados -p lssnap Rollback the pool to an earlier snapshot rados -p rollback Images and cephfs have their own snapshot facilities. Object and Bucket snapshotting features related to rgw don\u2019t exist. Pools Snapshots versus App Snapshots The two different snapshot features cannot be used at the same time on a pool Either Pool Snapshots, or Application Snapshots; not both. (snap_mode = pool versus snap_mode = selfmanaged) Once you commit to pool snapshots for an RBD pool, you can\u2019t change to using RBD snapshots Pros and Cons of each, depending on your Use Case admin:~ # ceph osd pool ls detail -f json-pretty | grep snap_mode \"snap_mode\": \"selfmanaged\", \"snap_mode\": \"selfmanaged\", \"snap_mode\": \"selfmanaged\", \"snap_mode\": \"selfmanaged\", \"snap_mode\": \"selfmanaged\", \"snap_mode\": \"selfmanaged\", \"snap_mode\": \"selfmanaged\", BlueStore \u00b6 BlueStore is the default storage backend in SES Highlighted features: compressing, no double-writes, faster checksums Ceph FileStore Model It is not ideal for a specialized purpose like a highly scalable distributed storage system. Only recommend that XFS be used. Both btrfs and ext4 have known bugs. The FileStore model uses cache from the filesystem (XFS). Memory for cache is managed by filesystem kernel module. Ceph BlueStore Model BlueStore consumes raw block devices. Metadata management with RocksDB. BlueStore employs RocksDB\u2019s key/value database in order to manage internal metadata, such as the mapping from object names to block locations on disk. Full data and metadata checksumming. By default all data and metadata written to BlueStore is protected by one or more checksums. A small specialized filesystem called BlueFS. This provides just enough of a filesystem to allow RocksDB to store its \"key/value files\" to share metadata across all the raw device(s) No data or metadata will be read from disk or returned to the user without being verified. Multi-device metadata tiering. BlueStore allows its internal journal (write-ahead log) to be written to a separate, highspeed device (like an SSD, NVMe, or NVDIMM) to increased performance. Efficient copy-on-write. RBD and CephFS snapshots rely on a copy-on-write clone mechanism that is implemented efficiently in BlueStore. BlueStore is a userspace model that provides its own memory management and cache. No need to clear the storage device cache OSDs help facilitate the performance of caching Default: cache the reads, don\u2019t cache the writes RocksDB\uff1a rocksdb\u662ffacebook\u57fa\u4e8eleveldb\u5f00\u53d1\u7684\u4e00\u6b3ekv\u6570\u636e\u5e93\uff0cBlueStore\u5c06\u5143\u6570\u636e\u5168\u90e8\u5b58\u653e\u81f3RocksDB\u4e2d\uff0c\u8fd9\u4e9b\u5143\u6570\u636e\u5305\u62ec\u5b58\u50a8\u9884\u5199\u5f0f\u65e5\u5fd7\u3001\u6570\u636e\u5bf9\u8c61\u5143\u6570\u636e\u3001Ceph\u7684omap\u6570\u636e\u4fe1\u606f\u3001\u4ee5\u53ca\u5206\u914d\u5668\u7684\u5143\u6570\u636e \u3002 BlueRocksEnv\uff1a \u662fRocksDB\u4e0eBlueFS\u4ea4\u4e92\u7684\u63a5\u53e3\uff1bRocksDB\u63d0\u4f9b\u4e86\u6587\u4ef6\u64cd\u4f5c\u7684\u63a5\u53e3EnvWrapper\uff0c\u7528\u6237\u53ef\u4ee5\u901a\u8fc7\u7ee7\u627f\u5b9e\u73b0\u8be5\u63a5\u53e3\u6765\u81ea\u5b9a\u4e49\u5e95\u5c42\u7684\u8bfb\u5199\u64cd\u4f5c\uff0cBlueRocksEnv\u5c31\u662f\u7ee7\u627f\u81eaEnvWrapper\u5b9e\u73b0\u5bf9BlueFS\u7684\u8bfb\u5199\u3002 BlueFS\uff1a BlueFS\u662fBlueStore\u9488\u5bf9RocksDB\u5f00\u53d1\u7684\u8f7b\u91cf\u7ea7\u6587\u4ef6\u7cfb\u7edf\uff0c\u7528\u4e8e\u5b58\u653eRocksDB\u4ea7\u751f\u7684.sst\u548c.log\u7b49\u6587\u4ef6\u3002 BlockDecive\uff1a BlueStore\u629b\u5f03\u4e86\u4f20\u7edf\u7684ext4\u3001xfs\u6587\u4ef6\u7cfb\u7edf\uff0c\u4f7f\u7528\u76f4\u63a5\u7ba1\u7406\u88f8\u76d8\u7684\u65b9\u5f0f\uff1b BlueStore\u652f\u6301\u540c\u65f6\u4f7f\u7528\u591a\u79cd\u4e0d\u540c\u7c7b\u578b\u7684\u8bbe\u5907\uff0c\u5728\u903b\u8f91\u4e0aBlueStore\u5c06\u5b58\u50a8\u7a7a\u95f4\u5212\u5206\u4e3a\u4e09\u5c42\uff1a\u6162\u901f\uff08Slow\uff09\u7a7a\u95f4\u3001\u9ad8\u901f\uff08DB\uff09\u7a7a\u95f4\u3001\u8d85\u9ad8\u901f\uff08WAL\uff09\u7a7a\u95f4\uff0c\u4e0d\u540c\u7684\u7a7a\u95f4\u53ef\u4ee5\u6307\u5b9a\u4f7f\u7528\u4e0d\u540c\u7684\u8bbe\u5907\u7c7b\u578b\uff0c\u5f53\u7136\u4e5f\u53ef\u4f7f\u7528\u540c\u4e00\u5757\u8bbe\u5907\u3002 Allocator\uff1a\u8d1f\u8d23\u88f8\u8bbe\u5907\u7684\u7a7a\u95f4\u7ba1\u7406\uff0c\u53ea\u5728\u5185\u5b58\u505a\u6807\u8bb0\uff0c\u76ee\u524d\u652f\u6301StupidAllocator\u548cBitmapAllocator\u4e24\u79cd\u5206\u914d\u5668,Stupid\u57fa\u4e8eextent\u7684\u65b9\u5f0f\u5b9e\u73b0 Ceph BlueStore with Mixed Devices BlueStore Cache Parameters \u00b6 Under most circumstances, autotune is best bluestore_cache_autotune Description: Automatically tune the ratios assigned to different bluestore caches while respecting minimum values Type: Boolean Required: Yes Default: True (enabled) Related settings: bluestore_cache_autotune_chunk_size, bluestore_cache_autotune_interval, and others bluestore_cache_size Description: The amount of memory BlueStore will use for its cache. If zero, bluestore_cache_size_hdd or bluestore_cache_size_ssd will be used instead. Type: Integer Required: Yes Default: 0 bluestore_cache_size_hdd Description: The default amount of memory BlueStore will use for its cache when backed by an HDD Type: Integer Required: Yes Default: 1 * 1024 * 1024 * 1024 (1 GB) bluestore_cache_size_ssd Description: The default amount of memory BlueStore will use for its cache when backed by an SSD. Type: Integer Required: Yes Default: 3 * 1024 * 1024 * 1024 (3 GB) bluestore_cache_meta_ratio Description: The ratio of cache devoted to metadata. Type: Floating point Default: .01 bluestore_cache_kv_ratio Description: The ratio of cache devoted to key/value data (rocksdb). Type : Floating point Default: .99 bluestore_cache_kv_max Description : The maximum amount of cache devoted to key/value data (rocksdb). Type : Unsigned Integer Default : 512 * 1024*1024 (512 MB) BlueStore Device Types \u00b6 BlueStore has three types of roles for devices: The DATA role: Required: main device (block symlink) stores all object data. If no other types: \u201cdata\u201d device serves all the other roles The DB role: Optional: DB device (block.db symlink) stores metadata in RocksDB Whatever doesn\u2019t fit will spill back onto the \u201cdata\u201d device The Write Ahead Log (WAL/Journal) role: Optional: WAL device (block.wal symlink) stores the internal journal Can combine all 3 roles into one physical device Or combine DB/WAL onto a single device with the DATA device separate Or all three on seperate devices BlueStore Configuration Recommendations \u00b6 Devote DB and WAL to SSD or NVMe Allocate 64 GB to the RocksDB Allocate 4-6 GB to the WAL Assign the \u201cdata\u201d role to the slower (HDD) devices If combining WAL/DB on one device, use a single partition for both You can use a single SSD/NVMe to store multiple journals Architecture Overview of Object, Block, Filesystem Access \u00b6 Object Storage \u00b6 The state of the art of distributed storage Object storage is the Cloud Storage mechanism of choice Unstructured, to better accommodate large files and large quantities of files Ideal for large media files, like streaming videos, audio Scales really well, large capacities Ceph provides access to the storage via all three major data access methods: Block, Object, and File. For the storage backend, Object Storage is ideal Block Storage \u00b6 Traditional Block Storage: Volumes as a collection of blocks Blocks can be of various sizes, but all the same within a volume Typically a filesystem is installed on top of the volume Hard Drives, CDs, USB sticks, etc The standard disk device mechanism for Unix, Linux, Windows, etc. Ceph presents RADOS as block device (RBD = RADOS Block Device) Ceph calls these block devices \u201cimages\u201d Provides clients with access like a \u201cdisk drive\u201d KVM/QEMU; libvirt; or remote Linux system A native Windows client that can access the Block storage of Ceph directly is in progress RADOS Block Device (RBD) \u00b6 RBD is the RADOS Block Device A specific RBD instance in the cluster is called an \u201cimage\u201d RBD images can be accessed by OSs other than linux librbd provides interface for gateways like iSCSI RBD allows the client to decide what to do with the storage Filesystem type; raw disk, such as for a DB; etc RBD images can accommodate 16Eb file system sizes No matter the size, the storage is distributed durably throughout the cluster Data is striped across the RADOS cluster in object sized chunks 4MB default Provides high performance and durability Notable Benefits Ability to mount with Linux or QEMU KVM clients Thinly provisioned Resizable images Image import/export Image copy or rename Read-only snapshots Revert to snapshots Copy on Write clones Useful for standing up lots of virtual machines with same base configuration High performance due to striping across cluster nodes RBD image definition: Defined storage area presented as a block device to a client RBD Storage File Storage \u00b6 POSIX Filesystem via CephFS File access is a significant use case Home directories Historical comfort with files and directories Ease of managing \u201csmall\u201d stuff broadly, in a distributed system A Use Case that\u2019s growing in popularity: HPC CephFS is fast, scalable, and flexible Fits into many existing paradigms, rather seamlessly In particular: NFS, Samba/CIFS But even better: extending Linux filesystems Requires Metadata Service (MDS) for POSIX capabilities SUSE does NOT support any FUSE clients. Ceph Users and Authentication \u00b6 Ceph Users are generally applications; applications that use the storage cluster The must common user is Admin A ceph admin user and credentials must exist Additional users and associated credentials are useful Each user must have credentials to access the storage cluster The most fundamental form of credentials in Ceph is keys Ceph Users and Keys The admin user has rights to all Ceph resources. Other users can be setup to have a subset of rights There are basically two types of Users (Actors): An individual (a person) An application (like a gateway, or some other kind of system) Most users are of the type client, and are represented as a dotted string, such as: client.admin, or client.steve, or client.swift The root linux user on the Admin node is effectively the Admin Ceph user, since the root user has all privileges to all filesystem objects on the Adminnode, including the ceph.client.admin.keyring. The root user on any of the nodes in the cluster can \u201cimpersonate\u201d all of the Ceph clients. Linux user accounts do not have any affect on the Ceph Users as managed in the dashboard. Take care to keep backups of the /etc/ceph/ directory structure, so that you don\u2019t lose these keys/keyrings. Each user must have a key/keyring, for example: /etc/ceph/ceph.client.admin.keyring on the Admin node /etc/ceph/ceph.client.storage.keyring on a storage node admin:/etc/ceph # cat ceph.client.admin.keyring [client.admin] key = AQD6pHpfAAAAABAAHJvkvLhOKZyQxm9lgnR5Qg== caps mds = \"allow *\" caps mon = \"allow *\" caps osd = \"allow *\" caps mgr = \"allow *\" data1:/etc/ceph # cat ceph.client.storage.keyring [client.storage] key = AQD8pHpfAAAAABAAHecCBgBsLIyPrJf+27eXUQ== caps mon = \"allow rw\" Ceph Keys and Keyrings A keyring contains one or more keys Each user can have its own keyring A keyring can contain multiple keys Different clients and users must have their own key, but multiple keys can be joined together in a single keyring Normally a key will be contained in a keyring Core Ceph will only recognize and use keys from keyrings Stand-alone keys are useful for other tools, like clients Ceph Authentication List The Admin node (and client.admin) can list all Users ceph auth list Create a Ceph User A typical user will have read rights to MONs, and read/write rights to a pool (osd) ceph auth get/add/get-or-create xxxxxx Create a User with ceph-authtool Create a keyring ceph-authtool -C /etc/ceph/ceph.client.richard.keyring Create a key, and place it on the keyring ceph-authtool --gen-key -n client.richard --cap osd 'allow rw pool=data' --cap mon 'allow r' /etc/ceph/ceph.client.richard.keyring Now officially tell the cluster about the key (add user to the key) ceph auth add client.richard -i /etc/ceph/ceph.client.richard.keyring Authentication with cephx The mechanism for passing keys around is cephx Authentication for users and daemons Does not provide data encryption, only authentication with keys cephx simply ensures the authenticity of actors So that no man-in-the-middle attacks can occur Other authentication mechanisms are theoretically possible Attempts to integrate LDAP and Kerberos have been made \u2026 but they have not come to full fruition yet Ceph Configuration \u00b6 Historically, the Ceph configuration was kept only in a file on the Admin node: /etc/ceph/ceph.conf, and sync'd to MONs and Storage Nodes SES DeepSea manages the ceph.conf file. Don\u2019t edit it directly; use Salt and DeepSea With Ceph Nautilus, most configuration held as objects in the Monitors using Dashboard or CLI for operation Ceph Configuration Stored in the MONs The MONs keep a configuration database Show all the configuration keys: admin:/etc/ceph # ceph config ls |less Show the configuration settings that have been customized. The dumped output also indicates an EXPERTISE LEVEL The keys also have a \u201cwho\u201d attribute. In below case, \"osd.*\" represents the \"who\", which is getting the general setting for all OSDs Ceph Configuration Settings Show configuration settings that have been customized: admin:/etc/ceph # ceph config dump WHO MASK LEVEL OPTION VALUE RO mgr advanced mgr/dashboard/GRAFANA_API_URL https://mon1.pvgl.sap.corp:3000 * mgr advanced mgr/dashboard/RGW_API_ACCESS_KEY M11I3JGQHAQM94CS910K * mgr advanced mgr/dashboard/RGW_API_HOST mon3.pvgl.sap.corp * mgr advanced mgr/dashboard/RGW_API_PORT 80 * mgr advanced mgr/dashboard/RGW_API_SECRET_KEY YWyRc3mayEPiOEUzQ2o76KePSKmVKN4fIWxgqTt6 * mgr advanced mgr/dashboard/RGW_API_USER_ID admin * mgr advanced mgr/dashboard/ssl_server_port 8443 admin:/etc/ceph # ceph config get osd.* osd_max_object_size 134217728 admin:/etc/ceph # ceph config show osd.0 \u2026\u2026 admin:/etc/ceph # ceph config show osd.11 (4 data nodes, 3 osds in each node) \u25cb Each of the configuration settings have default values ceph config show-with-defaults osd.2 | less \u25cb Ceph keeps a log of configuration changes admin:/etc/ceph # ceph config log --- 8 --- 2020-10-05 14:31:51.425902 --- + mgr/mgr/dashboard/RGW_API_USER_ID = admin --- 7 --- 2020-10-05 14:31:50.418622 --- + mgr/mgr/dashboard/RGW_API_HOST = mon3.pvgl.sap.corp --- 6 --- 2020-10-05 14:31:49.398448 --- + mgr/mgr/dashboard/RGW_API_PORT = 80 --- 5 --- 2020-10-05 14:31:48.403965 --- + mgr/mgr/dashboard/RGW_API_SECRET_KEY = YWyRc3mayEPiOEUzQ2o76KePSKmVKN4fIWxgqTt6 --- 4 --- 2020-10-05 14:31:46.905701 --- + mgr/mgr/dashboard/RGW_API_ACCESS_KEY = M11I3JGQHAQM94CS910K --- 3 --- 2020-10-05 13:15:29.530355 --- + mgr/mgr/dashboard/GRAFANA_API_URL = https://mon1.pvgl.sap.corp:3000 --- 2 --- 2020-10-05 13:15:14.349623 --- + mgr/mgr/dashboard/ssl_server_port = 8443 --- 1 --- 2020-10-05 13:13:55.637896 --- Health \u00b6 Show status admin:/etc/ceph # ceph status cluster: id: 343ee7d3-232f-4c71-8216-1edbc55ac6e0 health: HEALTH_OK services: mon: 3 daemons, quorum mon1,mon2,mon3 (age 6w) mgr: mon1(active, since 13d) mds: cephfs:1 {0=mon3=up:active} 2 up:standby osd: 12 osds: 12 up (since 9w), 12 in (since 9w) rgw: 1 daemon active (mon3) task status: scrub status: mds.mon3: idle data: pools: 7 pools, 208 pgs objects: 246 objects, 4.7 KiB usage: 14 GiB used, 82 GiB / 96 GiB avail pgs: 208 active+clean io: client: 11 KiB/s rd, 0 B/s wr, 11 op/s rd, 6 op/s wr admin:/etc/ceph # ceph health HEALTH_OK admin:/etc/ceph # ceph health detail HEALTH_OK admin:/etc/ceph # ceph mon stat e1: 3 mons at {mon1=[v2:10.58.121.186:3300/0,v1:10.58.121.186:6789/0],mon2=[v2:10.58.121.187:3300/0,v1:10.58.121.187:6789/0],mon3=[v2:10.58.121.188:3300/0v1:10.58.121.188:6789/0]}, election epoch 22, leader 0 mon1, quorum 0,1,2 mon1,mon2,mon3 admin:/etc/ceph # ceph osd stat 12 osds: 12 up (since 9w), 12 in (since 9w); epoch: e1375 admin:/etc/ceph # ceph pg stat 208 pgs: 208 active+clean; 4.7 KiB data, 2.0 GiB used, 82 GiB / 96 GiB avail; 1.2 KiB/s rd, 1 op/s Watch status -w, --watch : Watch live cluster changes --watch-debug : Watch debug events --watch-info : Watch info events --watch-sec : Watch security events --watch-warn : Watch warning events --watch-error : Watch error Scrub and Deep-Scrub \u00b6 \"Scrub\" is the process of doing a data consistency check Basically like running fsck on the cluster In Replicas: compare object metadata among replicas In EC: verify \u201ccode\u201d chunks Manual scrubbing can be done per OSD or per PG. \"osd scrub\" is just a collaborative wrapper of \"pg scrub\". ceph osd scrub osd.11 ceph pg scrub 3.33 \"scrub\" is a light process, daily Checks object size and attributes \"deep-scrub\" is a more thorough process, weekly Reads all data and checks the checksums Scrub \u2013 Manual vs Automatic You can let Ceph just do the default Run scrub daily, run deep-scrub weekly Ceph pays attention to usage and backs off when necessary You can change the defaults for both scrub and deepscrub, examples: osd_scrub_begin_week_day=6 (Saturday) osd_scrub_end_week_day=7 (Sunday) You can manually run scrubbings at any time if you suspect it\u2019s wanted or needed Manual scrubbings are not common Adjustments to Scrub Settings For most circumstances the default behavior of Scrub is adequate See current Scrub configuration settings: ceph config ls | grep osd_scrub ceph config ls | grep osd_deep_scrub ceph config get osd.* osd_scrub_begin_hour Change the settings immediately in the MON DB ceph config set osd.* osd_scrub_begin_hour 23 ceph config set osd.* osd_scrub_end_hour 5 Adjust Settings in ceph.conf with DeepSea To permanently change settings in ceph.conf This is the \u201cold\u201d way, but is still valid Remember that ceph.conf is controlled by DeepSea Add changes to /srv/salt/ceph/configuration/files/ceph.conf.d/global.conf Run the following DeepSea (Salt) commands: salt admin* state.apply ceph.configuration.create salt \\* state.apply ceph.configuration Wait for services/servers to be restarted, or tell Ceph to assimilate the ceph.conf settings now ceph config assimilate-conf -i /etc/ceph/ceph.conf Repair \u00b6 Problems Found by Scrubbing * If data (in an OSD or PG) becomes inconsistent, it will need to be repaired. You can configure scrubbing to automatically repair errors * osd_scrub_auto_repair=True * osd_scrub_auto_repair_num_errors=5 * Manually repair when appropriate * ceph osd repair osd.11 * ceph pg repair 3.33 Ceph Manager Modules \u00b6 Manager Modules help to extend the capabilities of Ceph List of Modules Supported in SES Balancer (always on) rash (always on) Dashboard DeepSea iostat Orchestrator (always on) progress (always on, tech preview) Prometheus RESTful rbd_support (always on) status (always on) telemetry volume (always on) Zabbix (plugin only, not the required agent) Enabling Manager Modules Show a list of Manager Modules ceph mgr module ls | less The output is quite long; best to pipe it through less The top of the output shows those modules that have been enabled The exhaustive output also displays the \u201cAPI\u201d of each module Manager modules are quite easy to enable and disable ceph mgr module enable ceph mgr module disable Show list of services that are active from the Modules ceph mgr services Module Capabilities Each module has its own settings, configuration Once the module is enabled, the ceph command accepts commands for the module No need to run the command as ceph mgr ... Examples: ceph crash stat ceph telemetry show Setting parameters (key/value pairs) of Modules ceph config set mgr mgr/telemetry/contact 'JD ' ceph config set mgr mgr/telemetry/description 'Training Cluster' Ceph Tell \u00b6 Tell commands are actually directed to the target service by way of the MONs ceph tell is a tool to tell a ceph daemon to perform a task \u2026 change a setting \u2026 execute a subroutine The target of ceph tell can be a single daemon or a collection of daemons All MONs: ceph tell mon.* injectargs '--mon-pg-warn-max-per-osd 4096' A specific OSD: ceph tell osd.9 bench ceph tell is the most common way to change logging for troubleshooting ceph tell . injectargs '--debug- ' ceph tell osd.7 injectargs '--debug-osd 20' ceph tell osd.7 config set debug_osd 20 A \u201c/\u201d allows you to change both the file log and memory log settings simultaneously ceph tell mon.3 injectargs '--debug-mon 0/10' (The first is the file parameter, the second is the memory parameter) Since logging can fill space, important to restore settings after investigating ceph tell mon.3 injectargs '--debug-mon 1/5' ceph tell sends its instructions via the Monitors. So what if the MONs are having problems? To avoid running commands through the MONs, go directly to thenode running the daemon ssh storage1 ceph daemon osd.29 config show ceph daemon osd.29 config set debug_osd 0/20 Use with great care Ceph Dashboard \u00b6 What's Ceph Dashboard SES WEB-based Management Interface A Ceph MGR module, built-in to Ceph The open source \"port\" of openATTIC to Ceph. Technically it\u2019s not a port of openATTIC. SUSE and Ceph Community worked on implementing the openATTIC capabilities directly within Ceph Role-based and Multi-User Management of the SES cluster Create, manage, and monitor Pools, RBDs Manage users, access keys, quotas and buckets of RGW Manage NFS exports, iSCSI targets and portals, CephFS View cluster nodes/roles, monitor performance metrics Manage Ceph settings/configuration Reduces the need to understand complex Ceph commands The dashboard is stateless, it will reflect any changes to the Ceph cluster, Highlighted Enterprise Behavior via Ceph Dashboard Uses SSL/TLS By default will use a CA and certificate created by DeepSea or provide your own CA and certificate Can run without SSL/TLS (not recommended) Multi-User and Role Management Variety of mappings, i.e.: read, create, update, delete Single Sign-On, complying with SAML 2.0 Single Sign-On, complying with SAML 2.0 Auditing on the backend, to monitor specific user activity Internationalization (I18N), with a variety of language translations Ceph Dashboard Architecture Backend is based on CherryPy framework (CherryPy is a Minimalist Python Web Framework) Frontend WebUI is based on Angular/TypeScript A custom REST API Monitoring facilitated by Prometheus Visualization of data facilitated by Grafana Dependent upon DBUS, systemd, and systems\u2019 shell Dashboard as Manager Module Ceph Dashboard runs as a Manager module Runs on each MON/MGR node Really only actively available via the active MGR Runs on \u201cstandby\u201d on the standby MGR nodes Standby Dashboards will redirect to active MGR URL Dashboard automatically switches to active MGR node Helpful High Availability feature As a MGR module, enabled and configured by DeepSea Can be disabled if unwanted URL example: https://10.58.121.186:8443 Grafana and Prometheus Prometheus collects various data about the cluster Grafana represents the data as graphs Ceph Dashboard uses both to improve insight into SES Prometheus Open source event monitoring software \"Scrapes\" (collects) data from nodes/services in the cluster Real-time Time series Custom scrapers have been created for Ceph Stores scraped data in memory and on disk Presents data to other software for graphical representation Integrated nicely with Grafana Grafana The leading open source software for time series analytics \"Dashboards\" of panels, graphs, metrics, etc. \"Dashboard\" is a slightly conflicting term, but still meaningful Renders data in a graphical way collected from Prometheus Graphs are customized for use on the Ceph Dashboard Dashboard Users Always need an \u201cAdmin\u201d user for the Dashboard \u00a7 The admin keys of the root user on the \u201cAdmin\u201d node in the cluster Dashboard Users are accounts that relate only to using the Dashboard \u00a7 Not the same as Ceph CLI users and client keys; but could coincide Any person who wants to interact with the storage cluster via the Dashboard must have a user account Variety of Users established by the Admin User, and various permissions based on Admin-defined Roles User Authentication Dashboard Administrators can setup users with specific privileges The privileges and permissions are managed as \"roles\" User accounts can be created directly in the Dashboard Stored as objects in Ceph User accounts can also be tied to other authentication mechanisms: Single Sign-On Service; SAML 2.0 compliant protocol Dashboard accounts can be managed from the Dashboard or from the CLI Example: ceph dashboard ac-user-show [] The Admin Dashboard User (the term \u201cadmin\u201d is used differently in different places) The Dashboard Admin User is not the same as other admins The \u201cadmin\u201d node is obviously not directly tied to any admin user The Admin Dashboard User is created at Deployment time Given a random password by DeepSea You must use the CLI to establish the admin password ceph dashboard ac-user-show admin ceph dashboard ac-user-set-password admin \u25cb The SES Deployment Course has set the password to mypassword admin:~ # ceph dashboard ac-user-show [\"admin\"] admin:~ # ceph dashboard ac-user-show admin {\"username\": \"admin\", \"password\": \"$2b$12$4lC/AU7jc6midTZufj4P4.rBtVzRGf7Zy7fUbD6G9YfdfVEwkwuUy\", \"roles\": [\"administrator\"], \"name\": null \"email\":null\"lastUpdate\": 1601874928} Health from the Dashboard Cluster Status Monitors OSDs Manager Daemons Hosts Object Gateways Metadata Service iSCSI Gateways Cluster Performance from Dashboard Client IOPS Client Throughput Client Read/Write Recovery Throughput Scrub Performance Data Hosts: Overall Performance Monitors: Performance Counters OSDs: Relative Read/Write bar graphs, and Overall Performance Pools: Relative Read/Write bar graphs, and Overall Performance Block images: Overall Performance CephFS: Performance Details RGW: Overall Performance Cluster Capacity from Dashboard Capacity data: Number of Pools Raw Capacity Number of Objects (Ceph objects, not user objects from RGW) Placement Groups per OSD Placement Group Status Basic Troubleshooting \u00b6 Ceph Logs Logs normally stored in /var/log/ceph/ No real logs on the admin node Each service has its own log on the MON, Storage and Gateway nodes Logs handled routinely by logrotate Ceph has logs that are stored to files and in memory (triggered by event or manual request) There are 21 different levels of logging: 0-20 (0 is no logging; 20 is the most verbose logging) There are many subsystems that do their own logging, and can be configured independently Most common: mon, osd, mgr, rados, rbd, mds, rgw Others: asok, auth, client, filestore, journal, monc, ms, paxos, and more There are only 3 types of daemons: osd, mon, mds Using Tell to Change Log Levels 1) Check the Dashboard and Health. Common commands ceph status ceph osd status ceph osd df ceph osd utilization ceph osd pool stats ceph osd tree ceph pg stat 2) Network Troubleshooting Always be sure that the network (and related services) are working properly Ceph depends heavily on tightly synchronized time; make sure network time services are working on each node DNS hostnames are similarly essential 3) Check the Logs Go to the node of the component implicated in HEALTH 4: Raise the DEBUG Level. Follow this simple formula: Raise the debug level (a little each time until you see the problem) Check the logs Repeat as necessary Don\u2019t forget to restore the debug level back to its normal level 5) Check the Storage Device If the problem is with an OSD or a storage device, go straight to the device: hdparm smartctl And check out the details of the combination of OSD and storage device: lsblk /var/lib/ceph/osd/ 6) Scrub (or not) Sometimes simply scrubbing an OSD or PG can cause the checksum-ing process to reveal problems At least some problems can be made more clear with the result of scrub and/or deep-scrub Even doing a scrub can kick Ceph into fixing the problem itself And don\u2019t forget ceph osd repair On the other hand, sometimes Scrub can make things worse. If you suspect Scrub is part of the problem, turn it off: ceph osd set noscrub ceph osd unset noscrub 7) Placement Groups When Placement Groups cause problems: * ceph pg dump summary * ceph pg dump pools * ceph pg dump_jason * ceph pg dump | less Followed by a strategic \u201crepair\u201d of the PG * ceph pg repair 8) Running supportconfig YaST Support Module From CLI: supportconfig The collected data is stored in a file called /var/log/nts__.txz","title":"SUSE Enterprise Storage Foundation"},{"location":"linux/SES/linux_ses_memo/#suse-enterprise-storage-foundation","text":"","title":"SUSE Enterprise Storage Foundation"},{"location":"linux/SES/linux_ses_memo/#cephs-rados","text":"Everything in Ceph is stored in the RADOS cluster as Objects. Ceph\u2019s RADOS: Reliable Autonomous Distributed Object Store Ceph\u2019s RADOS is composed of storage devices represented as: Raw storage device with LVM (BlueStore) Standard filesystem (FileStore) The Object Storage Daemon (OSD) integrates each disk device as part of the RADOS cluster.","title":"Ceph\u2019s RADOS"},{"location":"linux/SES/linux_ses_memo/#ceph-architecture","text":"Ceph is made of two groups of core components The RADOS cluster Provides the clustered object storage Native Object Access methods Gateways Access to the object store via standard protocols librados Direct access to the object store using a native API Examples: iSCSI Gateway (block) -- IGW - iSCSI is a storage area network (SAN) protocol. Exports RADOS Block Device (--RBD) (images as iSCSI disks). iSCSI access to RDB images. lrbd is no longer used in SES6. RADOS Gateway (object) -- RGW Is an object storage interface built on top of librados CephFS (file) A MetaData Service (MDS) is required. Direct access to RADOS (no LIBRADOS layer) Traditional filesystem interface. NFS Ganesha (object, file) Provides NFS exports to: RGW buckets for access the object store The CephFS filesystem Client access the storage services of the cluster via Gateways and Librados The librados API allows interaction with the following daemons: The Ceph Monitor, which maintains a master copy of the cluster map The Ceph OSD Daemon (OSD), which stores data as objects on a storage node.","title":"Ceph architecture"},{"location":"linux/SES/linux_ses_memo/#enhanced-ses-architecture-diagram","text":"","title":"Enhanced SES Architecture Diagram"},{"location":"linux/SES/linux_ses_memo/#object-storage","text":"The state of the art of distributed SDS storage Unstructured, to better accommodate large files and large quantities of files For large files and large quantities of files, it performs far better than other storage mechanisms Agile, scalable, extensible, and very customizable Invisible to the end-user, ideal for backends Perfect for systemic, application-based use cases. Not necessarily perfect for direct Human use Through associated metadata, ideal for computational analytics And CRUSH takes full advantage of this (CRUSH = Controllable Replication Under Scalable Hashing) Ceph Object Storage supports two interfaces: S3-compatible Swift-compatible Object-based storage has become the standard backend storage mechanism for nearly all modern Enterprise Storage Solutions.","title":"Object Storage"},{"location":"linux/SES/linux_ses_memo/#ceph-osds-object-storage-daemon","text":"A Ceph OSD (object storage daemon, ceph-osd) stores data, handles data replication, recovery, rebalancing, and provides some monitoring information to Ceph Monitors and Managers by checking other Ceph OSD Daemons for a heartbeat. The Ceph Storage Cluster receives data from Ceph Clients. Clients (dedicated access points, e.g., gateway) could be a Ceph Block Device, Ceph Object Storage, the Ceph Filesystem or a custom implementation using librados. The client requests the cluster status from a monitor node The client uses the status information to identify the location of objects in the cluster The client accesses the objects directly via the OSD node The OSD then stores the data as objects. Each object corresponds to a file in a filesystem which is stored on an OSD. The OSD Daemons take care of the reads and writes on the storage disks. When OSDs are deployed in SES5 the default is to use BlueStore which uses the raw disk and does not require a linux file system to be placed on the disk before it can be used. OSD Daemons store all data as objects in a flat namespace, i.e. no hierarchy of directories. At least 3 Ceph OSDs are normally required for redundancy and high availability.","title":"Ceph OSDs (Object Storage Daemon)"},{"location":"linux/SES/linux_ses_memo/#ceph-mons-monitor-servers","text":"A Ceph Monitor (ceph-mon) maintains maps of the cluster state, including Monitor Map Manager Map OSD Map PG Map CRUSH Map Epoch These maps are critical cluster state required for Ceph daemons to coordinate with each other. Monitors are also responsible for managing authentication between daemons and clients. At least 3 monitors are normally required for redundancy and high availability. An odd number of MONs is required (Paxos requires). Typically 5 is sufficient for mid or large size cluster. Paxos is an algorithm used for cluster durability. Leader MON expects 50% quality to create quorum. Lowest IP address becomes leader. After new leader selected, all MONs polled for epoch. Leader Mon provides lease to non-leader MONs. MONs are NOT in the data path. They merely serve maps to clients so that the client can go directly to the appropriate OSD storage daemon. Monitor nodes MONs do not serve objects to clients","title":"Ceph Mons (Monitor Servers)"},{"location":"linux/SES/linux_ses_memo/#ceph-mgrs-manager-daemon","text":"A Ceph Manager daemon (ceph-mgr) is responsible for keeping track of runtime metrics and the current state of the Ceph cluster, including storage utilization current performance metrics system load The Ceph Manager daemons also host python-based plugins to manage and expose Ceph cluster information, including a web-based dashboard and REST API. At least two managers are normally required for high availability. MON/MGR daemons are required to run on the same node in SES","title":"Ceph MGRs (Manager Daemon)"},{"location":"linux/SES/linux_ses_memo/#ceph-mds-metadata","text":"A Ceph Metadata Server (MDS, ceph-mds) stores metadata on behalf of the Ceph Filesystem. Ceph Metadata Servers allow POSIX file system users to execute basic commands, for example ls -al without placing an large load on the Ceph Storage Cluster.","title":"Ceph MDS (Metadata)"},{"location":"linux/SES/linux_ses_memo/#ceph-admin-node","text":"The Admin node fills the \u201cmaster\u201d and \u201cadmin\u201d roles for DeepSea. Salt is central to SES. SES\u2019s deployment and life-cycle management tool. The Admin node keeps master Ceph authentication keys. Prometheus and Grafana provide cluster monitoring and data graphs","title":"Ceph Admin Node"},{"location":"linux/SES/linux_ses_memo/#ceph-dashboard","text":"Runs as a Ceph Manager module; runs via the MON/MGR node.","title":"Ceph Dashboard"},{"location":"linux/SES/linux_ses_memo/#client-access","text":"Object Storage (RADOSGW or RGW) Block Storage (RDB). RBD is built on top of librados. CephFS iSCSI Gateway NFS Ganesha SMB/CIFS Native protocols via librados","title":"Client Access"},{"location":"linux/SES/linux_ses_memo/#objects-in-ceph","text":"Everything stored in the Ceph cluster is an object. Default object size is 4MB. Each object has a unique ID. ID is unique across the entire cluster. Objects have associated metadata, in Key: Value pairs. In Ceph we use Storage Pools to organize or arrange our objects. Pools are logical partitions to manage objects Parameters to manage Pools Number of data replicas (Replica pools), or configuration of Erasure Code (size) (Erasure Code pools) Erasure Code is an alternative to Replication SIZE for Erasure Coding is K+M K = Data chunks, M = \u201cParity\u201d chunks EC reduces the hit to raw storage capacity EC incurs a greater hit to CPU on the OSDs as a tradeoff Placement Groups (PG) PG is used to manage objects within a pool. PGs are associated with OSDs for data placement PGs are a central feature of CRUSH that help to provide data durability by way of distribution No PG is owned by an OSD. (And an OSD is not owned by a PG.) PGs are just randomly assigned by CRUSH through all of the OSDs to spread the distribution of data Locating data among PGs is all handled economically, deterministically by way of CRUSH calculations PGs are subdivisions of pools Number of PGs = (Number of OSDs * 100) / Size (Size = either num of replicas, or K+M) The final PG number must be a power of 2 The default number of PGs for a new pool is 8 (it's too small for enterprise solution) In general, PG and PGP numbers should be the same pg_num is the number of placement groups for the pool (placement group, \u5b58\u50a8\u6c60\u7684\u76ee\u5f55\u4e2a\u6570 ) pgp_num is the number of placement groups that will be considered for placement (placement group for placement purpose, pg\u53ef\u7528\u7684osd\u6392\u5217\u7ec4\u5408\u6570\u91cf) \u4ec5\u589e\u5927pg_num\uff1a \u56e0\u4e3apgp_num\u6ca1\u53d8\uff0cpg\u7684osd\u7ec4\u5408\u4ecd\u53ea\u80fd\u4ece\u5f53\u524dpgp_num\u79cd\u7ec4\u5408\u91cc\u9762\u6311\u9009\uff0c\u5bfc\u81f4\u65b0\u589e\u7684pg\u548c\u65e7pg\u4f1a\u6709\u91cd\u590d\u7684osd\u7ec4\u5408\uff0c\u8be5\u73b0\u8c61\u79f0\u4e4b\u4e3a\u5206\u88c2\uff1b\u6b64\u65f6pg\u548cosd\u7684\u6620\u5c04\u6ca1\u6709\u53d8\uff1b \u7ee7\u7eed\u589e\u5927pgp_num\uff0c\u4f7f\u5176\u7b49\u4e8epg_num\uff1a \u65e7pg\u6ca1\u6709\u53d8\u5316\uff0c\u4f46\u65b0\u589epg\u7684osd\u7ec4\u5408\u53d1\u751f\u53d8\u5316\uff0c\u5373\u5f00\u59cb\u91cd\u65b0\u5206\u5e03 Placement Group (PG) \u5f52\u7f6e\u7ec4\u72b6\u6001 Creating \u521b\u5efa\u5b58\u50a8\u6c60\u65f6\uff0c\u5b83\u4f1a\u521b\u5efa\u6307\u5b9a\u6570\u91cf\u7684\u5f52\u7f6e\u7ec4\u3002 ceph \u5728\u521b\u5efa\u4e00\u6216\u591a\u4e2a\u5f52\u7f6e\u7ec4\u65f6\u4f1a\u663e\u793a creating\u3002 \u521b\u5efa\u5b8c\u540e\uff0c\u5728\u5176\u5f52\u7f6e\u7ec4\u7684 Acting Set \u91cc\u7684 OSD \u5c06\u5efa\u7acb\u4e92\u8054\u3002 \u4e00\u65e6\u4e92\u8054\u5b8c\u6210\uff0c\u5f52\u7f6e\u7ec4\u72b6\u6001\u5e94\u8be5\u53d8\u4e3a active+clean\uff0c\u610f\u601d\u662fceph \u5ba2\u6237\u7aef\u53ef\u4ee5\u5411\u5f52\u7f6e\u7ec4\u5199\u5165\u6570\u636e\u4e86\u3002 peering ceph \u4e3a\u5f52\u7f6e\u7ec4\u5efa\u7acb\u4e92\u8054\u65f6\uff0c\u4f1a\u8ba9\u5b58\u50a8\u5f52\u7f6e\u7ec4\u526f\u672c\u7684 OSD \u4e4b\u95f4\u5c31\u5176\u4e2d\u7684\u5bf9\u8c61\u548c\u5143\u6570\u636e\u72b6\u6001\u8fbe\u6210\u4e00\u81f4\u3002 ceph \u5b8c\u6210\u4e86\u4e92\u8054\uff0c\u4e5f\u5c31\u610f\u5473\u7740\u5b58\u50a8\u7740\u5f52\u7f6e\u7ec4\u7684 OSD \u5c31\u5176\u5f53\u524d\u72b6\u6001\u8fbe\u6210\u4e86\u4e00\u81f4\u3002 \u7136\u800c\uff0c\u4e92\u8054\u8fc7\u7a0b\u7684\u5b8c\u6210\u5e76\u4e0d\u80fd\u8868\u660e\u5404\u526f\u672c\u90fd\u6709\u4e86\u6570\u636e\u7684\u6700\u65b0\u7248\u672c\u3002 active ceph \u5b8c\u6210\u4e92\u8054\u8fdb\u7a0b\u540e,\u4e00\u5f52\u7f6e\u7ec4\u5c31\u53ef\u53d8\u4e3a active\u3002 active \u72b6\u6001\u901a\u5e38\u610f\u5473\u7740\u5728\u4e3b\u5f52\u7f6e\u7ec4\u548c\u526f\u672c\u4e2d\u7684\u6570\u636e\u90fd\u53ef\u4ee5\u8bfb\u5199\u3002 clean \u67d0\u4e00\u5f52\u7f6e\u7ec4\u5904\u4e8e clean \u72b6\u6001\u65f6\uff0c\u4e3b OSD \u548c\u526f\u672c OSD \u5df2\u6210\u529f\u4e92\u8054\uff0c\u5e76\u4e14\u6ca1\u6709\u504f\u79bb\u7684\u5f52\u7f6e\u7ec4\u3002 ceph \u5df2\u628a\u5f52\u7f6e\u7ec4\u4e2d\u7684\u5bf9\u8c61\u590d\u5236\u4e86\u89c4\u5b9a\u6b21\u6570\u3002 degraded \u5f53\u5ba2\u6237\u7aef\u5411\u4e3b OSD \u5199\u5165\u6570\u636e\u65f6\uff0c\u7531\u4e3b OSD \u8d1f\u8d23\u628a\u526f\u672c\u5199\u5165\u5176\u4f59\u590d\u5236 OSD\u3002 \u4e3b OSD \u628a\u5bf9\u8c61\u5199\u5165\u590d\u5236 OSD \u540e\uff0c\u5728\u6ca1\u6536\u5230\u6210\u529f\u5b8c\u6210\u7684\u786e\u8ba4\u524d\uff0c\u4e3b OSD \u4f1a\u4e00\u76f4\u505c\u7559\u5728 degraded \u72b6\u6001\u3002 \u5f52\u7f6e\u7ec4\u72b6\u6001\u53ef\u4ee5\u662f active+degraded \u72b6\u6001\uff0c\u539f\u56e0\u5728\u4e8e\u4e00 OSD \u5373\u4f7f\u6ca1\u6240\u6709\u5bf9\u8c61\u4e5f\u53ef\u4ee5\u5904\u4e8e active \u72b6\u6001\u3002 \u5982\u679c\u4e00OSD \u6302\u4e86\uff0cceph \u4f1a\u628a\u76f8\u5173\u7684\u5f52\u7f6e\u7ec4\u90fd\u6807\u8bb0\u4e3a degraded\u3002 \u90a3\u4e2a OSD \u91cd\u751f\u540e\uff0c\u5b83\u4eec\u5fc5\u987b\u91cd\u65b0\u4e92\u8054\u3002 \u7136\u800c\uff0c\u5982\u679c\u5f52\u7f6e\u7ec4\u4ecd\u5904\u4e8e active \u72b6\u6001\uff0c\u5373\u4fbf\u5b83\u5904\u4e8e degraded \u72b6\u6001\uff0c\u5ba2\u6237\u7aef\u8fd8\u53ef\u4ee5\u5411\u5176\u5199\u5165\u65b0\u5bf9\u8c61\u3002 \u5982\u679c\u4e00 OSD \u6302\u4e86\uff0c\u4e14 degraded \u72b6\u6001\u6301\u7eed\uff0cceph \u4f1a\u628a down \u7684 OSD \u6807\u8bb0\u4e3a\u5728\u96c6\u7fa4\u5916(out)\u3001\u5e76\u628a\u90a3\u4e9b down \u6389\u7684 OSD \u4e0a\u7684\u6570\u636e\u91cd\u6620\u5c04\u5230\u5176\u5b83 OSD\u3002 \u4ece\u6807\u8bb0\u4e3a down \u5230 out \u7684\u65f6\u95f4\u95f4\u9694\u7531 mon osd down out interval \u63a7\u5236,\u9ed8\u8ba4\u662f 300 \u79d2\u3002 \u5f52\u7f6e\u7ec4\u4e5f\u4f1a\u88ab\u964d\u7ea7(degraded)\uff0c\u56e0\u4e3a\u5f52\u7f6e\u7ec4\u627e\u4e0d\u5230\u672c\u5e94\u5b58\u5728\u4e8e\u5f52\u7f6e\u7ec4\u4e2d\u7684\u4e00\u6216\u591a\u4e2a\u5bf9\u8c61\uff0c\u8fd9\u65f6\uff0c\u4f60\u4e0d\u80fd\u8bfb\u6216\u5199\u627e\u4e0d\u5230\u7684\u5bf9\u8c61\uff0c\u4f46\u4ecd\u80fd\u8bbf\u95ee\u5176\u5b83\u4f4d\u4e8e\u964d\u7ea7\u5f52\u7f6e\u7ec4\u4e2d\u7684\u5bf9\u8c61\u3002 recovering ceph \u88ab\u8bbe\u8ba1\u4e3a\u53ef\u5bb9\u9519\uff0c\u53ef\u62b5\u5fa1\u4e00\u5b9a\u89c4\u6a21\u7684\u8f6f\u3001\u786c\u4ef6\u95ee\u9898\u3002 \u5f53\u67d0 OSD \u6302\u4e86(down)\u65f6\uff0c\u5176\u5185\u5bb9\u7248\u672c\u4f1a\u843d\u540e\u4e8e\u5f52\u7f6e\u7ec4\u5185\u7684\u5176\u5b83\u526f\u672c\u3002 \u5b83\u91cd\u751f(up)\u65f6\uff0c\u5f52\u7f6e\u7ec4\u5185\u5bb9\u5fc5\u987b\u66f4\u65b0\uff0c\u4ee5\u53cd\u6620\u5f53\u524d\u72b6\u6001\u3002 \u5728\u6b64\u671f\u95f4\uff0cOSD \u5728recovering \u72b6\u6001\u3002 \u4e00\u6b21\u786c\u4ef6\u5931\u8d25\u53ef\u80fd\u7275\u8fde\u591a\u4e2a OSD\u3002\u6bd4\u5982\u4e00\u4e2a\u673a\u67dc\u7684\u7f51\u7edc\u4ea4\u6362\u673a\u5931\u8d25\u4e86\uff0c\u8fd9\u4f1a\u5bfc\u81f4\u591a\u4e2a\u4e3b\u673a\u843d\u540e\u4e8e\u96c6\u7fa4\u7684\u5f53\u524d\u72b6\u6001\uff0c\u95ee\u9898\u89e3\u51b3\u540e\u6bcf\u4e00\u4e2a OSD \u90fd\u5fc5\u987b\u6062\u590d\u3002 ceph \u63d0\u4f9b\u4e86\u5f88\u591a\u9009\u9879\u6765\u5747\u8861\u8d44\u6e90\u7ade\u4e89\uff0c\u5982\u65b0\u670d\u52a1\u8bf7\u6c42\u3001\u6062\u590d\u6570\u636e\u5bf9\u8c61\u548c\u6062\u590d\u5f52\u7f6e\u7ec4\u5230\u5f53\u524d\u72b6\u6001\u3002 osd recovery delay start \u9009\u9879\u5141\u8bb8\u4e00 OSD \u5728\u5f00\u59cb\u6062\u590d\u8fdb\u7a0b\u524d\uff0c\u5148\u91cd\u542f\u3001\u91cd\u5efa\u4e92\u8054\u3001\u751a\u81f3\u5904\u7406\u4e00\u4e9b\u91cd\u653e\u8bf7\u6c42\u3002 osd recovery threads \u9009\u9879\u9650\u5236\u6062\u590d\u8fdb\u7a0b\u7684\u7ebf\u7a0b\u6570\uff0c\u9ed8\u8ba4\u4e3a 1 \u7ebf\u7a0b\u3002 osd recovery thread timeout \u8bbe\u7f6e\u7ebf\u7a0b\u8d85\u65f6\uff0c\u56e0\u4e3a\u591a\u4e2aOSD \u53ef\u80fd\u4ea4\u66ff\u5931\u8d25\u3001\u91cd\u542f\u548c\u91cd\u5efa\u4e92\u8054\u3002 osd recovery max active \u9009\u9879\u9650\u5236\u4e00 OSD \u6700\u591a\u540c\u65f6\u63a5\u53d7\u591a\u5c11\u8bf7\u6c42\uff0c\u4ee5\u9632\u5b83\u538b\u529b\u8fc7\u5927\u800c\u4e0d\u80fd\u6b63\u5e38\u670d\u52a1\u3002 osd recovery max chunk \u9009\u9879\u9650\u5236\u6062\u590d\u6570\u636e\u5757\u5c3a\u5bf8\uff0c\u4ee5\u9632\u7f51\u7edc\u62e5\u585e\u3002 back filling \u6709\u65b0 OSD \u52a0\u5165\u96c6\u7fa4\u65f6\uff0cCRUSH \u4f1a\u628a\u73b0\u6709\u96c6\u7fa4\u5185\u7684\u5f52\u7f6e\u7ec4\u91cd\u5206\u914d\u7ed9\u5b83\u3002 \u5f3a\u5236\u65b0 OSD \u7acb\u5373\u63a5\u53d7\u91cd\u5206\u914d\u7684\u5f52\u7f6e\u7ec4\u4f1a\u4f7f\u4e4b\u8fc7\u8f7d\uff0c\u7528\u5f52\u7f6e\u7ec4\u56de\u586b\u53ef\u4f7f\u8fd9\u4e2a\u8fc7\u7a0b\u5728\u540e\u53f0\u5f00\u59cb\u3002 \u56de\u586b\u5b8c\u6210\u540e\uff0c\u65b0 OSD \u51c6\u5907\u597d\u65f6\u5c31\u53ef\u4ee5\u5bf9\u5916\u670d\u52a1\u4e86\u3002 remapped \u67d0\u4e00\u5f52\u7f6e\u7ec4\u7684 Acting Set \u53d8\u66f4\u65f6\uff0c\u6570\u636e\u8981\u4ece\u65e7\u96c6\u5408\u8fc1\u79fb\u5230\u65b0\u7684\u3002 \u4e3b OSD \u8981\u82b1\u8d39\u4e00\u4e9b\u65f6\u95f4\u624d\u80fd\u63d0\u4f9b\u670d\u52a1\uff0c\u6240\u4ee5\u5b83\u53ef\u4ee5\u8ba9\u8001\u7684\u4e3b OSD \u6301\u7eed\u670d\u52a1\u3001\u76f4\u5230\u5f52\u7f6e\u7ec4\u8fc1\u79fb\u5b8c\u3002 \u6570\u636e\u8fc1\u79fb\u5b8c\u540e,\u4e3b OSD \u4f1a\u6620\u5c04\u5230\u65b0 acting set\u3002 stale \u867d\u7136 ceph \u7528\u5fc3\u8df3\u6765\u4fdd\u8bc1\u4e3b\u673a\u548c\u5b88\u62a4\u8fdb\u7a0b\u5728\u8fd0\u884c\uff0c\u4f46\u662f ceph-osd \u4ecd\u6709\u53ef\u80fd\u8fdb\u5165 stuck \u72b6\u6001\uff0c\u5b83\u4eec\u6ca1\u6709\u6309\u65f6\u62a5\u544a\u5176\u72b6\u6001(\u5982\u7f51\u7edc\u77ac\u65ad)\u3002 \u9ed8\u8ba4OSD \u5b88\u62a4\u8fdb\u7a0b\u6bcf\u534a\u79d2(0.5)\u4f1a\u4e00\u6b21\u62a5\u544a\u5176\u5f52\u7f6e\u7ec4\u3001\u51fa\u6d41\u91cf\u3001\u5f15\u5bfc\u548c\u5931\u8d25\u7edf\u8ba1\u72b6\u6001\uff0c\u6b64\u9891\u7387\u9ad8\u4e8e\u5fc3\u8df3\u9600\u503c\u3002 \u5982\u679c\u4e00\u5f52\u7f6e\u7ec4\u7684\u4e3b OSD \u6240\u5728\u7684 acting set \u6ca1\u80fd\u5411\u76d1\u89c6\u5668\u62a5\u544a\u3001\u6216\u8005\u5176\u5b83\u76d1\u89c6\u5668\u5df2\u7ecf\u62a5\u544a\u4e86\u90a3\u4e2a\u4e3b OSD \u5df2 down\uff0c\u76d1\u89c6\u5668\u4eec\u5c31\u4f1a\u628a\u6b64\u5f52\u7f6e\u7ec4\u6807\u8bb0\u4e3a stale\u3002 \u542f\u52a8\u96c6\u7fa4\u65f6\uff0c\u4f1a\u7ecf\u5e38\u770b\u5230 stale \u72b6\u6001\uff0c\u76f4\u5230\u4e92\u8054\u5b8c\u6210\u3002 \u96c6\u7fa4\u8fd0\u884c\u4e00\u9635\u540e\uff0c\u5982\u679c\u8fd8\u80fd\u770b\u5230\u6709\u5f52\u7f6e\u7ec4\u4f4d\u4e8e stale \u72b6\u6001\uff0c\u5c31\u8bf4\u660e\u90a3\u4e9b\u5f52\u7f6e\u7ec4\u7684\u4e3b OSD \u6302\u4e86(down)\u3001\u6216\u6ca1\u5728\u5411\u76d1\u89c6\u5668\u62a5\u544a\u7edf\u8ba1\u4fe1\u606f\u3002 Each pool has its own autoscaler settings The PG balancer optimizes the placement of PGs across OSD crush-compat mode It's default mode Uses the compat weight-set feature upmap mode. It's perfect mode, which an equal number of PGs on each OSD Use fine-grained control over the PG mapping Snapshots Rulesets to manage CRUSH placement Each pool has a defined CRUSH ruleset A CRUSH ruleset is a definition of how the OSDs organize data This allows configuration of data distribution to be managed per pool A single CRUSH ruleset can be reused by multiple pools A ruleset can take into account: \u9700\u8981\u8003\u8651\u7684\u70b9 physical layout of nodes in the cluster organization of network infrastructure selection of OSDs backed by SSDs versus HDDs, etc Each pool can use either Replication or Erasure Coding Replication is the original, default approach to resiliency Erasure Coded pools have an EC Profile assigned Different than CRUSH rulesets, but similar: define how OSDs organize data The profile defines K, M values; encoding method/plugin; etc","title":"Objects in Ceph"},{"location":"linux/SES/linux_ses_memo/#crush-controllable-replication-under-scalable-hashing","text":"CRUSH is a key piece of the Ceph storage solution With the CRUSH algorithm used by Ceph: Data is not centrally stored, it is distributed CRUSH calculates the storage location for each object dynamically No requirement to store a global index of object locations","title":"CRUSH (Controllable Replication Under Scalable Hashing)"},{"location":"linux/SES/linux_ses_memo/#crush-algorithm","text":"The CRUSH algorithm deterministically calculates the location of any object in the Ceph RADOS cluster Overhead is low and calculation is performed by each client As no metadata store is required, CRUSH removes the limitations of traditional metadata based management No direct control over the placement of your data in the cluster Higher CPU requirements","title":"CRUSH Algorithm"},{"location":"linux/SES/linux_ses_memo/#crush-maps-and-rulesets","text":"CRUSH Rulesets are the named sets of rules: Combining all of the customizable CRUSH behavior settings Assigned to pool to govern how the pool\u2019s data is distributed in the cluster CRUSH Maps are central to how Ceph distributes data, and maintaining the durability of the data When the cluster is deployed, Ceph creates a simple default ruleset for replicated pools: replicated_rule CRUSH behavior depends on the behaviors and performance of storage devices CRUSH Maps should be crafted to take advantage of those behaviors Rulesets should be used to clearly identify how the devices in your environment should be employed Device Classes exist to indicate performance behavior: hdd, ssd, nvme Ceph OSDs will automatically set the Device Class of a storage device when the OSD is started Working with CRUSH Map Rulesets List the OSDs, which host each OSD belongs to: ceph osd tree ceph osd df tree ceph osd df tree -f json-pretty Find the host of a specific OSD: ceph osd find 8 Show the existing defined rulesets: ceph osd crush rule ls Examine the definition of an existing ruleset: ceph osd crush rule dump There are 3 options for creating a new ruleset: simple replicated erasure Creating new rulesets: ceph osd crush rule create-replicated ceph osd crush rule create-erasure Create a new ruleset using a Device Class: create-replicated Description : The name of the node under which data should be placed. Type : String Example : default (rarely would you need to make this different than \u201cdefault\u201d) or Description : The type of CRUSH node (bucket) across which replicas should be separated. Type : String Example : rack Description : The device class data should be placed on. Type : String Example : ssd","title":"CRUSH Maps and Rulesets"},{"location":"linux/SES/linux_ses_memo/#crush-weight","text":"You may need to move data around New nodes degraded nodes rebalancing View the current CRUSH weights ceph osd crush tree ceph osd df tree Change the weight for an OSD ceph osd crush reweight The important difference between ceph osd reweight and ceph osd crush reweight \"ceph osd crush reweight\" sets the CRUSH weight of the OSD. This weight is an arbitrary value (generally the size of the disk in TB or something) and controls how much data the system tries to allocate to the OSD. \"ceph osd reweight\" sets an override weight on the OSD. This value is in the range 0 to 1, and forces CRUSH to re-place (1-weight) of the data that would otherwise live on this drive. It does not change the weights assigned to the buckets above the OSD, and is a corrective measure in case the normal CRUSH distribution isn\u2019t working out quite right. \"ceph osd reweight\" is temporary. \"ceph osd crush reweight\" is sticky, permanent (until you change it again). Setting a weight of an OSD to 0 is effectively setting the OSD \"out\" - you don\u2019t want it to store data.","title":"CRUSH Weight"},{"location":"linux/SES/linux_ses_memo/#the-monitors-cluster-map-contains","text":"Monitor Map Unique Cluster ID, details of each Mon node, current epoch, date/time of last change OSD Map Contains the cluster fsid, when the map was created and last modified, a list of pools, replica sizes, PG numbers, a list of OSDs and their status PG Map Contains the PG version, its time stamp, the last OSD map epoch, the full ratios, and details on each placement group such as the PG ID, the Up Set, the Acting Set, the state of the PG (e.g., active + clean), and data usage statistics for each pool MDS Map Contains the current MDS map epoch, references to pool(s) for storing metadata, list of MDS servers, and which metadata servers are up and in CRUSH Map Contains a list of storage devices, the failure domain hierarchy (e.g., device, host, rack, row, room, etc.), and rules for traversing the hierarchy when storing data","title":"The Monitor\u2019s Cluster Map contains"},{"location":"linux/SES/linux_ses_memo/#crush-hierarchy","text":"The CRUSH Map includes details of physical & network infrastructure The CRUSH Map hierarchy is defined by a storage architect The default hierarchical list of infrastructure elements: (Hierarchy of CRUSH buckets) OSD host chassis \u5200\u7247\u673a\u7bb1 rack \u673a\u67b6 row pdu \u7535\u6e90\u5206\u914d\u5355\u5143 pod \u6027\u80fd\u4f18\u5316\u7684\u6570\u636e\u4e2d\u5fc3(Performance Optimize Datacenter)\uff0c\u57fa\u4e8e\u6807\u51c6\u5316\u8bbe\u65bd\u7684\u6700\u4f73\u5b9e\u8df5\uff0c\u6bcf\u4e2aPOD\u5185IT\u90e8\u5206\u5305\u542b\u76845000\u53f0\u670d\u52a1\u5668\uff0c\u5206\u5c5e\u5230200\u4e2a\u673a\u67b6\uff0c\u5982\u679c\u4ee5\u6bcf\u53f0\u670d\u52a1\u5668400W\u529f\u7387\u8ba1\u7b97\u7684\u8bdd\uff0c\u6bcf\u4e2a\u673a\u67dc\u9700\u898110KW\u7684\u4f9b\u7535\uff0c\u5373\u6bcf\u4e2aPOD\u7684IT\u8d1f\u8f7d\u5bb9\u91cf\u662f2MW\u3002 room datacenter region root CRUSH is the algorithm and calculation for distributing data through the cluster. CRUSH Map obviously plays a part in how those CRUSH calculations work.","title":"CRUSH Hierarchy"},{"location":"linux/SES/linux_ses_memo/#crush-map-sections-six-main-sections","text":"tunables: adjustments to legacy behavior devices: The list of OSDs (usually no customization needed) \u25cb \"device class\" is meaningful; useful in relation to creating/using CRUSH rulesets \u25cb Standard \"device class\" values are \"hdd.\", \"ssd.\", and \"nvme.\" \u25cb Example: device 7 osd.7 types: types of buckets (usually no customization needed) buckets: the most functional, customizable aspect of the Map \u25cb A bucket typically represents a physical location in the cluster, has a \u201ctype\u201d \u25cb Nodes (containers such as hosts) and leaves (storage devices such as OSDs) rules: define policies of how data should be distributed \u25cb The behind-the-scenes rules that CRUSH follows for data placement \u25cb IMPORTANT: this is NOT the same as the \"ruleset\". In fact, a ruleset is the combined set of all of these six Map sections. choose_args (optional): Rarely used exceptional settings to adjust weights From the documentation: \"choose_args are alternative weights associated with the hierarchy that have been adjusted to optimize data placement. A single choose_args map can be used for the entire cluster, or one can be created for each individual pool.\"","title":"CRUSH Map Sections (Six main sections)"},{"location":"linux/SES/linux_ses_memo/#erasure-coding","text":"In information theory : an erasure code is a forward error correction (FEC, \u524d\u5411\u7ea0\u9519) code for the binary erasure channel, which transforms a message of k symbols into a longer message (code word) with n symbols such that the original message can be recovered from a subset of the n symbols. The fraction r = k/n is called the code rate The fraction k\u2019/k, where k\u2019 denotes the number of symbols required for recovery, is called reception efficiency Another (easier) way of describing EC: It\u2019s like RAID in Clustered Storage","title":"Erasure Coding"},{"location":"linux/SES/linux_ses_memo/#erasure-coding-in-ses","text":"The default resilience strategy in SES is simple replication * SES Simple replication has overheads, size=3 means 3 times the storage requirements Simplistic EC details: k = number of \u201cdata\u201d chunks, split across \u201ck\u201d number of OSDs m = number of \u201cparity\u201d chunks, split across \u201cm\u201d number of OSDs Ceph calls these \u201ccoding chunks\u201d r (size) = k + m admin:~ # ceph osd crush rule ls replicated_rule","title":"Erasure Coding in SES"},{"location":"linux/SES/linux_ses_memo/#replication-vs-erasure-code","text":"Replication (default): Use Case: active data Simple and fast Uses more disk space Erasure coding: Use Case: archive data, more static data Calculates recovery data (needs more CPU power) Definable redundancy level Example: K data chunks = 2 , M code chunks = 1 Similar to a replication size of 2 But with only 50% more raw storage consumed Example: for 1GB of effective storage replication pool of size of 2 needs 2GB raw storage erasure coded pool with k=2/m=1 only requires 1.5GB raw storage","title":"Replication vs Erasure Code"},{"location":"linux/SES/linux_ses_memo/#ec-overwrites","text":"Historically, EC only works properly with Objects EC only allowed appends; overwrites were not allowed Works perfectly for objects in buckets but doesn\u2019t work well with Block or CephFS With recent releases of SES, EC can work well with Block and CephFS Facilitated by \u201cEC Overwrites\u201d feature Store data in an EC Pool, and store object metadata in a Replicated Pool Requires a little extra work when defining pools, but worth it ceph osd pool set allow_ec_overwrites true","title":"EC Overwrites"},{"location":"linux/SES/linux_ses_memo/#ec-profiles","text":"Using Erasure Coding, each Pool is assigned an EC Profile Multiple pools can share a single Profile The profile is just a definition Each Profile has multiple settings The common required settings for all Profiles are K, M EC Profiles must be created before EC Pools can be created Created from the Dashboard or CLI Once an EC Profile is created, you can create a CRUSH Ruleset based on the EC profile Once a pool is created, its EC Profile properties cannot be changed Main profile parameters K: M: stripe_unit - allows you to adjust the size of the data chunk Default size is 4K stripe_unit : size of data striped across devices; default 4K This variable can also be set in the master configuration (osd_erasure_code_stripe_unit) EC plugins - choose your favorite EC algorithm via a plugin jerasure/gf-complete (default, free, open, and very fast) (www.jerasure.org) ISA (Intel library; optimized for modern Intel processors) (only runs on Intel processors) LRC (\u201cLocally Repairable Code\u201d; layers over existing plugins) SHEC (\u201cShingled EC\u201d; trades extra storage for recovery efficiency) CLAY (\u201cCoupled LAYer\u201d; good for reduced network traffic)","title":"EC Profiles"},{"location":"linux/SES/linux_ses_memo/#creating-erasure-code-profiles-and-pools","text":"Syntax: ceph osd erasure-code-profile OPTIONS Option Description get - view details of an existing EC profile set - set a profile (create a profile), requires k and m values, with optional values such as ruleset, plugin. Once you create a profile, you can\u2019t change it. ceph osd erasure-code-profile set k= m= [plugin=] [stripe_unit=] ls - list profiles rm - Remove an EC profile ceph osd erasure-code-profile rm Common example (below) The default profile \u2012 2+1=3; data is written over 3 OSDs \u2012 Two data chunks \u2012 One code (parity) chunk \u2012 Uses jerasure plugin with standard Reed/Solomon (reed_sol_van) technique Setting a Custom EC Profile Option: \u2012 Profile name \u2012 K : number of stripes required \u2012 M : number of failed units Example: ceph osd erasure-code-profile set example-profile k=8 m=2 ruleset-failure-domain=host ruleset-failure-domain = crush bucket level for failure admin:/etc/ceph # ceph osd erasure-code-profile \\ set common_profile \\ k=4 \\ m=2 \\ plugin=jerasure \\ technique=reed_sol_van \\ stripe_unit=4K \\ crush-root=default \\ crush-failure-domain=rackcrush-device-class=ssd admin:/etc/ceph # ceph osd erasure-code-profile ls default admin:~ # ceph osd erasure-code-profile get default k=2 m=1 plugin=jerasure technique=reed_sol_van Pools Pools are at the heart of Storage Pools are tied to OSDs Display a list of existing pools: ceph osd pool ls or ceph osd lspools View the statistics and characteristics of pools: ceph osd pool stats ceph osd pool stats ceph osd pool get Show usage and related details of existing pools: rados df or ceph df or ceph df detail All storage revolves around Pools Each pool must be dedicated to a purpose: Object, Block, File Must specify # of Placement Groups and PG Placements Must specify whether using Replication or EC Must specify a CRUSH ruleset Create a Replicated Pool Syntax: ceph osd pool create replicated = number of placement groups for the pool = number of PGs for placement; routinely will be the same as pg_num Always a power of 2 Don\u2019t make the number too small; don\u2019t err on the high side, either Practices For a new pool, the pgp_num will generally (likley) just be the same as the pg_num When increasing the PGs in a pool, you may want to retain the smaller pgp_num to minimize rebalancing, and increase pgp_num later when rebalancing is more convenient If decreasing the PGs in a pool, the pgp_num is adjusted automatically Create an EC Pool (using an EC Profile) Syntax: ceph osd pool create erasure Example: ceph osd pool create EC-pool 128 128 erasure my-ec-profile Pools \u2013 Application Assignment Each Pool must have a stated purpose; application This defines which capabilities the Pool must support The applications are: Block (rbd), Object (rgw), and File (cephfs) There are subtypes of cephfs: i.e. cephfs:data, cephfs:metadata Application assignment happens after creating a pool It\u2019s effortless (and required) to assign an application on a new pool ceph osd pool application enable Changing application assignment after a pool is in use is \u201chard\u201d. Not recommended, only to be done as an expert Pools \u2013 Quotas One of the more desirable features of SDS is to set a maximum usage of a Pool - Quotas Prevent the over-use of a pool Set quotas based on number of objects or number of bytes ceph osd pool set-quota max_objects ceph osd pool set-quota max_bytes Show quota settings ceph osd pool get-quota To remove a quota, set the existing quota setting to 0 There are also application-level quotas For rgw and cephfs (not rbd; images are already limited in size) Pool Quotas vs. Application Quotas. When a pool quota nears its limit, the HEALTH mechanisms will display a \u201cPOOL_NEAR_FULL\u201d warning to the storage administrator. When the quota limit has been exceeded, the HEALTH mechanisms will display a \u201cPOOL_FULL\u201d warning to the storage administrator. Applications (clients) don\u2019t always handle the quotas cleanly. In most cases, once the Pool Quota is exceeded, the application will simply stop writing to the pool, and error messages and behavior at the application are inconsistent (if there are any messages at all). Pools \u2013 Snapshots Take (make) a snapshot of an existing pool ceph osd pool mksnap Remove a snapshot of a pool ceph osd pool rmsnap List pool snapshots rados -p lssnap Rollback the pool to an earlier snapshot rados -p rollback Images and cephfs have their own snapshot facilities. Object and Bucket snapshotting features related to rgw don\u2019t exist. Pools Snapshots versus App Snapshots The two different snapshot features cannot be used at the same time on a pool Either Pool Snapshots, or Application Snapshots; not both. (snap_mode = pool versus snap_mode = selfmanaged) Once you commit to pool snapshots for an RBD pool, you can\u2019t change to using RBD snapshots Pros and Cons of each, depending on your Use Case admin:~ # ceph osd pool ls detail -f json-pretty | grep snap_mode \"snap_mode\": \"selfmanaged\", \"snap_mode\": \"selfmanaged\", \"snap_mode\": \"selfmanaged\", \"snap_mode\": \"selfmanaged\", \"snap_mode\": \"selfmanaged\", \"snap_mode\": \"selfmanaged\", \"snap_mode\": \"selfmanaged\",","title":"Creating Erasure Code Profiles and Pools"},{"location":"linux/SES/linux_ses_memo/#bluestore","text":"BlueStore is the default storage backend in SES Highlighted features: compressing, no double-writes, faster checksums Ceph FileStore Model It is not ideal for a specialized purpose like a highly scalable distributed storage system. Only recommend that XFS be used. Both btrfs and ext4 have known bugs. The FileStore model uses cache from the filesystem (XFS). Memory for cache is managed by filesystem kernel module. Ceph BlueStore Model BlueStore consumes raw block devices. Metadata management with RocksDB. BlueStore employs RocksDB\u2019s key/value database in order to manage internal metadata, such as the mapping from object names to block locations on disk. Full data and metadata checksumming. By default all data and metadata written to BlueStore is protected by one or more checksums. A small specialized filesystem called BlueFS. This provides just enough of a filesystem to allow RocksDB to store its \"key/value files\" to share metadata across all the raw device(s) No data or metadata will be read from disk or returned to the user without being verified. Multi-device metadata tiering. BlueStore allows its internal journal (write-ahead log) to be written to a separate, highspeed device (like an SSD, NVMe, or NVDIMM) to increased performance. Efficient copy-on-write. RBD and CephFS snapshots rely on a copy-on-write clone mechanism that is implemented efficiently in BlueStore. BlueStore is a userspace model that provides its own memory management and cache. No need to clear the storage device cache OSDs help facilitate the performance of caching Default: cache the reads, don\u2019t cache the writes RocksDB\uff1a rocksdb\u662ffacebook\u57fa\u4e8eleveldb\u5f00\u53d1\u7684\u4e00\u6b3ekv\u6570\u636e\u5e93\uff0cBlueStore\u5c06\u5143\u6570\u636e\u5168\u90e8\u5b58\u653e\u81f3RocksDB\u4e2d\uff0c\u8fd9\u4e9b\u5143\u6570\u636e\u5305\u62ec\u5b58\u50a8\u9884\u5199\u5f0f\u65e5\u5fd7\u3001\u6570\u636e\u5bf9\u8c61\u5143\u6570\u636e\u3001Ceph\u7684omap\u6570\u636e\u4fe1\u606f\u3001\u4ee5\u53ca\u5206\u914d\u5668\u7684\u5143\u6570\u636e \u3002 BlueRocksEnv\uff1a \u662fRocksDB\u4e0eBlueFS\u4ea4\u4e92\u7684\u63a5\u53e3\uff1bRocksDB\u63d0\u4f9b\u4e86\u6587\u4ef6\u64cd\u4f5c\u7684\u63a5\u53e3EnvWrapper\uff0c\u7528\u6237\u53ef\u4ee5\u901a\u8fc7\u7ee7\u627f\u5b9e\u73b0\u8be5\u63a5\u53e3\u6765\u81ea\u5b9a\u4e49\u5e95\u5c42\u7684\u8bfb\u5199\u64cd\u4f5c\uff0cBlueRocksEnv\u5c31\u662f\u7ee7\u627f\u81eaEnvWrapper\u5b9e\u73b0\u5bf9BlueFS\u7684\u8bfb\u5199\u3002 BlueFS\uff1a BlueFS\u662fBlueStore\u9488\u5bf9RocksDB\u5f00\u53d1\u7684\u8f7b\u91cf\u7ea7\u6587\u4ef6\u7cfb\u7edf\uff0c\u7528\u4e8e\u5b58\u653eRocksDB\u4ea7\u751f\u7684.sst\u548c.log\u7b49\u6587\u4ef6\u3002 BlockDecive\uff1a BlueStore\u629b\u5f03\u4e86\u4f20\u7edf\u7684ext4\u3001xfs\u6587\u4ef6\u7cfb\u7edf\uff0c\u4f7f\u7528\u76f4\u63a5\u7ba1\u7406\u88f8\u76d8\u7684\u65b9\u5f0f\uff1b BlueStore\u652f\u6301\u540c\u65f6\u4f7f\u7528\u591a\u79cd\u4e0d\u540c\u7c7b\u578b\u7684\u8bbe\u5907\uff0c\u5728\u903b\u8f91\u4e0aBlueStore\u5c06\u5b58\u50a8\u7a7a\u95f4\u5212\u5206\u4e3a\u4e09\u5c42\uff1a\u6162\u901f\uff08Slow\uff09\u7a7a\u95f4\u3001\u9ad8\u901f\uff08DB\uff09\u7a7a\u95f4\u3001\u8d85\u9ad8\u901f\uff08WAL\uff09\u7a7a\u95f4\uff0c\u4e0d\u540c\u7684\u7a7a\u95f4\u53ef\u4ee5\u6307\u5b9a\u4f7f\u7528\u4e0d\u540c\u7684\u8bbe\u5907\u7c7b\u578b\uff0c\u5f53\u7136\u4e5f\u53ef\u4f7f\u7528\u540c\u4e00\u5757\u8bbe\u5907\u3002 Allocator\uff1a\u8d1f\u8d23\u88f8\u8bbe\u5907\u7684\u7a7a\u95f4\u7ba1\u7406\uff0c\u53ea\u5728\u5185\u5b58\u505a\u6807\u8bb0\uff0c\u76ee\u524d\u652f\u6301StupidAllocator\u548cBitmapAllocator\u4e24\u79cd\u5206\u914d\u5668,Stupid\u57fa\u4e8eextent\u7684\u65b9\u5f0f\u5b9e\u73b0 Ceph BlueStore with Mixed Devices","title":"BlueStore"},{"location":"linux/SES/linux_ses_memo/#bluestore-cache-parameters","text":"Under most circumstances, autotune is best bluestore_cache_autotune Description: Automatically tune the ratios assigned to different bluestore caches while respecting minimum values Type: Boolean Required: Yes Default: True (enabled) Related settings: bluestore_cache_autotune_chunk_size, bluestore_cache_autotune_interval, and others bluestore_cache_size Description: The amount of memory BlueStore will use for its cache. If zero, bluestore_cache_size_hdd or bluestore_cache_size_ssd will be used instead. Type: Integer Required: Yes Default: 0 bluestore_cache_size_hdd Description: The default amount of memory BlueStore will use for its cache when backed by an HDD Type: Integer Required: Yes Default: 1 * 1024 * 1024 * 1024 (1 GB) bluestore_cache_size_ssd Description: The default amount of memory BlueStore will use for its cache when backed by an SSD. Type: Integer Required: Yes Default: 3 * 1024 * 1024 * 1024 (3 GB) bluestore_cache_meta_ratio Description: The ratio of cache devoted to metadata. Type: Floating point Default: .01 bluestore_cache_kv_ratio Description: The ratio of cache devoted to key/value data (rocksdb). Type : Floating point Default: .99 bluestore_cache_kv_max Description : The maximum amount of cache devoted to key/value data (rocksdb). Type : Unsigned Integer Default : 512 * 1024*1024 (512 MB)","title":"BlueStore Cache Parameters"},{"location":"linux/SES/linux_ses_memo/#bluestore-device-types","text":"BlueStore has three types of roles for devices: The DATA role: Required: main device (block symlink) stores all object data. If no other types: \u201cdata\u201d device serves all the other roles The DB role: Optional: DB device (block.db symlink) stores metadata in RocksDB Whatever doesn\u2019t fit will spill back onto the \u201cdata\u201d device The Write Ahead Log (WAL/Journal) role: Optional: WAL device (block.wal symlink) stores the internal journal Can combine all 3 roles into one physical device Or combine DB/WAL onto a single device with the DATA device separate Or all three on seperate devices","title":"BlueStore Device Types"},{"location":"linux/SES/linux_ses_memo/#bluestore-configuration-recommendations","text":"Devote DB and WAL to SSD or NVMe Allocate 64 GB to the RocksDB Allocate 4-6 GB to the WAL Assign the \u201cdata\u201d role to the slower (HDD) devices If combining WAL/DB on one device, use a single partition for both You can use a single SSD/NVMe to store multiple journals","title":"BlueStore Configuration Recommendations"},{"location":"linux/SES/linux_ses_memo/#architecture-overview-of-object-block-filesystem-access","text":"","title":"Architecture Overview of Object, Block, Filesystem Access"},{"location":"linux/SES/linux_ses_memo/#object-storage_1","text":"The state of the art of distributed storage Object storage is the Cloud Storage mechanism of choice Unstructured, to better accommodate large files and large quantities of files Ideal for large media files, like streaming videos, audio Scales really well, large capacities Ceph provides access to the storage via all three major data access methods: Block, Object, and File. For the storage backend, Object Storage is ideal","title":"Object Storage"},{"location":"linux/SES/linux_ses_memo/#block-storage","text":"Traditional Block Storage: Volumes as a collection of blocks Blocks can be of various sizes, but all the same within a volume Typically a filesystem is installed on top of the volume Hard Drives, CDs, USB sticks, etc The standard disk device mechanism for Unix, Linux, Windows, etc. Ceph presents RADOS as block device (RBD = RADOS Block Device) Ceph calls these block devices \u201cimages\u201d Provides clients with access like a \u201cdisk drive\u201d KVM/QEMU; libvirt; or remote Linux system A native Windows client that can access the Block storage of Ceph directly is in progress","title":"Block Storage"},{"location":"linux/SES/linux_ses_memo/#rados-block-device-rbd","text":"RBD is the RADOS Block Device A specific RBD instance in the cluster is called an \u201cimage\u201d RBD images can be accessed by OSs other than linux librbd provides interface for gateways like iSCSI RBD allows the client to decide what to do with the storage Filesystem type; raw disk, such as for a DB; etc RBD images can accommodate 16Eb file system sizes No matter the size, the storage is distributed durably throughout the cluster Data is striped across the RADOS cluster in object sized chunks 4MB default Provides high performance and durability Notable Benefits Ability to mount with Linux or QEMU KVM clients Thinly provisioned Resizable images Image import/export Image copy or rename Read-only snapshots Revert to snapshots Copy on Write clones Useful for standing up lots of virtual machines with same base configuration High performance due to striping across cluster nodes RBD image definition: Defined storage area presented as a block device to a client RBD Storage","title":"RADOS Block Device (RBD)"},{"location":"linux/SES/linux_ses_memo/#file-storage","text":"POSIX Filesystem via CephFS File access is a significant use case Home directories Historical comfort with files and directories Ease of managing \u201csmall\u201d stuff broadly, in a distributed system A Use Case that\u2019s growing in popularity: HPC CephFS is fast, scalable, and flexible Fits into many existing paradigms, rather seamlessly In particular: NFS, Samba/CIFS But even better: extending Linux filesystems Requires Metadata Service (MDS) for POSIX capabilities SUSE does NOT support any FUSE clients.","title":"File Storage"},{"location":"linux/SES/linux_ses_memo/#ceph-users-and-authentication","text":"Ceph Users are generally applications; applications that use the storage cluster The must common user is Admin A ceph admin user and credentials must exist Additional users and associated credentials are useful Each user must have credentials to access the storage cluster The most fundamental form of credentials in Ceph is keys Ceph Users and Keys The admin user has rights to all Ceph resources. Other users can be setup to have a subset of rights There are basically two types of Users (Actors): An individual (a person) An application (like a gateway, or some other kind of system) Most users are of the type client, and are represented as a dotted string, such as: client.admin, or client.steve, or client.swift The root linux user on the Admin node is effectively the Admin Ceph user, since the root user has all privileges to all filesystem objects on the Adminnode, including the ceph.client.admin.keyring. The root user on any of the nodes in the cluster can \u201cimpersonate\u201d all of the Ceph clients. Linux user accounts do not have any affect on the Ceph Users as managed in the dashboard. Take care to keep backups of the /etc/ceph/ directory structure, so that you don\u2019t lose these keys/keyrings. Each user must have a key/keyring, for example: /etc/ceph/ceph.client.admin.keyring on the Admin node /etc/ceph/ceph.client.storage.keyring on a storage node admin:/etc/ceph # cat ceph.client.admin.keyring [client.admin] key = AQD6pHpfAAAAABAAHJvkvLhOKZyQxm9lgnR5Qg== caps mds = \"allow *\" caps mon = \"allow *\" caps osd = \"allow *\" caps mgr = \"allow *\" data1:/etc/ceph # cat ceph.client.storage.keyring [client.storage] key = AQD8pHpfAAAAABAAHecCBgBsLIyPrJf+27eXUQ== caps mon = \"allow rw\" Ceph Keys and Keyrings A keyring contains one or more keys Each user can have its own keyring A keyring can contain multiple keys Different clients and users must have their own key, but multiple keys can be joined together in a single keyring Normally a key will be contained in a keyring Core Ceph will only recognize and use keys from keyrings Stand-alone keys are useful for other tools, like clients Ceph Authentication List The Admin node (and client.admin) can list all Users ceph auth list Create a Ceph User A typical user will have read rights to MONs, and read/write rights to a pool (osd) ceph auth get/add/get-or-create xxxxxx Create a User with ceph-authtool Create a keyring ceph-authtool -C /etc/ceph/ceph.client.richard.keyring Create a key, and place it on the keyring ceph-authtool --gen-key -n client.richard --cap osd 'allow rw pool=data' --cap mon 'allow r' /etc/ceph/ceph.client.richard.keyring Now officially tell the cluster about the key (add user to the key) ceph auth add client.richard -i /etc/ceph/ceph.client.richard.keyring Authentication with cephx The mechanism for passing keys around is cephx Authentication for users and daemons Does not provide data encryption, only authentication with keys cephx simply ensures the authenticity of actors So that no man-in-the-middle attacks can occur Other authentication mechanisms are theoretically possible Attempts to integrate LDAP and Kerberos have been made \u2026 but they have not come to full fruition yet","title":"Ceph Users and Authentication"},{"location":"linux/SES/linux_ses_memo/#ceph-configuration","text":"Historically, the Ceph configuration was kept only in a file on the Admin node: /etc/ceph/ceph.conf, and sync'd to MONs and Storage Nodes SES DeepSea manages the ceph.conf file. Don\u2019t edit it directly; use Salt and DeepSea With Ceph Nautilus, most configuration held as objects in the Monitors using Dashboard or CLI for operation Ceph Configuration Stored in the MONs The MONs keep a configuration database Show all the configuration keys: admin:/etc/ceph # ceph config ls |less Show the configuration settings that have been customized. The dumped output also indicates an EXPERTISE LEVEL The keys also have a \u201cwho\u201d attribute. In below case, \"osd.*\" represents the \"who\", which is getting the general setting for all OSDs Ceph Configuration Settings Show configuration settings that have been customized: admin:/etc/ceph # ceph config dump WHO MASK LEVEL OPTION VALUE RO mgr advanced mgr/dashboard/GRAFANA_API_URL https://mon1.pvgl.sap.corp:3000 * mgr advanced mgr/dashboard/RGW_API_ACCESS_KEY M11I3JGQHAQM94CS910K * mgr advanced mgr/dashboard/RGW_API_HOST mon3.pvgl.sap.corp * mgr advanced mgr/dashboard/RGW_API_PORT 80 * mgr advanced mgr/dashboard/RGW_API_SECRET_KEY YWyRc3mayEPiOEUzQ2o76KePSKmVKN4fIWxgqTt6 * mgr advanced mgr/dashboard/RGW_API_USER_ID admin * mgr advanced mgr/dashboard/ssl_server_port 8443 admin:/etc/ceph # ceph config get osd.* osd_max_object_size 134217728 admin:/etc/ceph # ceph config show osd.0 \u2026\u2026 admin:/etc/ceph # ceph config show osd.11 (4 data nodes, 3 osds in each node) \u25cb Each of the configuration settings have default values ceph config show-with-defaults osd.2 | less \u25cb Ceph keeps a log of configuration changes admin:/etc/ceph # ceph config log --- 8 --- 2020-10-05 14:31:51.425902 --- + mgr/mgr/dashboard/RGW_API_USER_ID = admin --- 7 --- 2020-10-05 14:31:50.418622 --- + mgr/mgr/dashboard/RGW_API_HOST = mon3.pvgl.sap.corp --- 6 --- 2020-10-05 14:31:49.398448 --- + mgr/mgr/dashboard/RGW_API_PORT = 80 --- 5 --- 2020-10-05 14:31:48.403965 --- + mgr/mgr/dashboard/RGW_API_SECRET_KEY = YWyRc3mayEPiOEUzQ2o76KePSKmVKN4fIWxgqTt6 --- 4 --- 2020-10-05 14:31:46.905701 --- + mgr/mgr/dashboard/RGW_API_ACCESS_KEY = M11I3JGQHAQM94CS910K --- 3 --- 2020-10-05 13:15:29.530355 --- + mgr/mgr/dashboard/GRAFANA_API_URL = https://mon1.pvgl.sap.corp:3000 --- 2 --- 2020-10-05 13:15:14.349623 --- + mgr/mgr/dashboard/ssl_server_port = 8443 --- 1 --- 2020-10-05 13:13:55.637896 ---","title":"Ceph Configuration"},{"location":"linux/SES/linux_ses_memo/#health","text":"Show status admin:/etc/ceph # ceph status cluster: id: 343ee7d3-232f-4c71-8216-1edbc55ac6e0 health: HEALTH_OK services: mon: 3 daemons, quorum mon1,mon2,mon3 (age 6w) mgr: mon1(active, since 13d) mds: cephfs:1 {0=mon3=up:active} 2 up:standby osd: 12 osds: 12 up (since 9w), 12 in (since 9w) rgw: 1 daemon active (mon3) task status: scrub status: mds.mon3: idle data: pools: 7 pools, 208 pgs objects: 246 objects, 4.7 KiB usage: 14 GiB used, 82 GiB / 96 GiB avail pgs: 208 active+clean io: client: 11 KiB/s rd, 0 B/s wr, 11 op/s rd, 6 op/s wr admin:/etc/ceph # ceph health HEALTH_OK admin:/etc/ceph # ceph health detail HEALTH_OK admin:/etc/ceph # ceph mon stat e1: 3 mons at {mon1=[v2:10.58.121.186:3300/0,v1:10.58.121.186:6789/0],mon2=[v2:10.58.121.187:3300/0,v1:10.58.121.187:6789/0],mon3=[v2:10.58.121.188:3300/0v1:10.58.121.188:6789/0]}, election epoch 22, leader 0 mon1, quorum 0,1,2 mon1,mon2,mon3 admin:/etc/ceph # ceph osd stat 12 osds: 12 up (since 9w), 12 in (since 9w); epoch: e1375 admin:/etc/ceph # ceph pg stat 208 pgs: 208 active+clean; 4.7 KiB data, 2.0 GiB used, 82 GiB / 96 GiB avail; 1.2 KiB/s rd, 1 op/s Watch status -w, --watch : Watch live cluster changes --watch-debug : Watch debug events --watch-info : Watch info events --watch-sec : Watch security events --watch-warn : Watch warning events --watch-error : Watch error","title":"Health"},{"location":"linux/SES/linux_ses_memo/#scrub-and-deep-scrub","text":"\"Scrub\" is the process of doing a data consistency check Basically like running fsck on the cluster In Replicas: compare object metadata among replicas In EC: verify \u201ccode\u201d chunks Manual scrubbing can be done per OSD or per PG. \"osd scrub\" is just a collaborative wrapper of \"pg scrub\". ceph osd scrub osd.11 ceph pg scrub 3.33 \"scrub\" is a light process, daily Checks object size and attributes \"deep-scrub\" is a more thorough process, weekly Reads all data and checks the checksums Scrub \u2013 Manual vs Automatic You can let Ceph just do the default Run scrub daily, run deep-scrub weekly Ceph pays attention to usage and backs off when necessary You can change the defaults for both scrub and deepscrub, examples: osd_scrub_begin_week_day=6 (Saturday) osd_scrub_end_week_day=7 (Sunday) You can manually run scrubbings at any time if you suspect it\u2019s wanted or needed Manual scrubbings are not common Adjustments to Scrub Settings For most circumstances the default behavior of Scrub is adequate See current Scrub configuration settings: ceph config ls | grep osd_scrub ceph config ls | grep osd_deep_scrub ceph config get osd.* osd_scrub_begin_hour Change the settings immediately in the MON DB ceph config set osd.* osd_scrub_begin_hour 23 ceph config set osd.* osd_scrub_end_hour 5 Adjust Settings in ceph.conf with DeepSea To permanently change settings in ceph.conf This is the \u201cold\u201d way, but is still valid Remember that ceph.conf is controlled by DeepSea Add changes to /srv/salt/ceph/configuration/files/ceph.conf.d/global.conf Run the following DeepSea (Salt) commands: salt admin* state.apply ceph.configuration.create salt \\* state.apply ceph.configuration Wait for services/servers to be restarted, or tell Ceph to assimilate the ceph.conf settings now ceph config assimilate-conf -i /etc/ceph/ceph.conf","title":"Scrub and Deep-Scrub"},{"location":"linux/SES/linux_ses_memo/#repair","text":"Problems Found by Scrubbing * If data (in an OSD or PG) becomes inconsistent, it will need to be repaired. You can configure scrubbing to automatically repair errors * osd_scrub_auto_repair=True * osd_scrub_auto_repair_num_errors=5 * Manually repair when appropriate * ceph osd repair osd.11 * ceph pg repair 3.33","title":"Repair"},{"location":"linux/SES/linux_ses_memo/#ceph-manager-modules","text":"Manager Modules help to extend the capabilities of Ceph List of Modules Supported in SES Balancer (always on) rash (always on) Dashboard DeepSea iostat Orchestrator (always on) progress (always on, tech preview) Prometheus RESTful rbd_support (always on) status (always on) telemetry volume (always on) Zabbix (plugin only, not the required agent) Enabling Manager Modules Show a list of Manager Modules ceph mgr module ls | less The output is quite long; best to pipe it through less The top of the output shows those modules that have been enabled The exhaustive output also displays the \u201cAPI\u201d of each module Manager modules are quite easy to enable and disable ceph mgr module enable ceph mgr module disable Show list of services that are active from the Modules ceph mgr services Module Capabilities Each module has its own settings, configuration Once the module is enabled, the ceph command accepts commands for the module No need to run the command as ceph mgr ... Examples: ceph crash stat ceph telemetry show Setting parameters (key/value pairs) of Modules ceph config set mgr mgr/telemetry/contact 'JD ' ceph config set mgr mgr/telemetry/description 'Training Cluster'","title":"Ceph Manager Modules"},{"location":"linux/SES/linux_ses_memo/#ceph-tell","text":"Tell commands are actually directed to the target service by way of the MONs ceph tell is a tool to tell a ceph daemon to perform a task \u2026 change a setting \u2026 execute a subroutine The target of ceph tell can be a single daemon or a collection of daemons All MONs: ceph tell mon.* injectargs '--mon-pg-warn-max-per-osd 4096' A specific OSD: ceph tell osd.9 bench ceph tell is the most common way to change logging for troubleshooting ceph tell . injectargs '--debug- ' ceph tell osd.7 injectargs '--debug-osd 20' ceph tell osd.7 config set debug_osd 20 A \u201c/\u201d allows you to change both the file log and memory log settings simultaneously ceph tell mon.3 injectargs '--debug-mon 0/10' (The first is the file parameter, the second is the memory parameter) Since logging can fill space, important to restore settings after investigating ceph tell mon.3 injectargs '--debug-mon 1/5' ceph tell sends its instructions via the Monitors. So what if the MONs are having problems? To avoid running commands through the MONs, go directly to thenode running the daemon ssh storage1 ceph daemon osd.29 config show ceph daemon osd.29 config set debug_osd 0/20 Use with great care","title":"Ceph Tell"},{"location":"linux/SES/linux_ses_memo/#ceph-dashboard_1","text":"What's Ceph Dashboard SES WEB-based Management Interface A Ceph MGR module, built-in to Ceph The open source \"port\" of openATTIC to Ceph. Technically it\u2019s not a port of openATTIC. SUSE and Ceph Community worked on implementing the openATTIC capabilities directly within Ceph Role-based and Multi-User Management of the SES cluster Create, manage, and monitor Pools, RBDs Manage users, access keys, quotas and buckets of RGW Manage NFS exports, iSCSI targets and portals, CephFS View cluster nodes/roles, monitor performance metrics Manage Ceph settings/configuration Reduces the need to understand complex Ceph commands The dashboard is stateless, it will reflect any changes to the Ceph cluster, Highlighted Enterprise Behavior via Ceph Dashboard Uses SSL/TLS By default will use a CA and certificate created by DeepSea or provide your own CA and certificate Can run without SSL/TLS (not recommended) Multi-User and Role Management Variety of mappings, i.e.: read, create, update, delete Single Sign-On, complying with SAML 2.0 Single Sign-On, complying with SAML 2.0 Auditing on the backend, to monitor specific user activity Internationalization (I18N), with a variety of language translations Ceph Dashboard Architecture Backend is based on CherryPy framework (CherryPy is a Minimalist Python Web Framework) Frontend WebUI is based on Angular/TypeScript A custom REST API Monitoring facilitated by Prometheus Visualization of data facilitated by Grafana Dependent upon DBUS, systemd, and systems\u2019 shell Dashboard as Manager Module Ceph Dashboard runs as a Manager module Runs on each MON/MGR node Really only actively available via the active MGR Runs on \u201cstandby\u201d on the standby MGR nodes Standby Dashboards will redirect to active MGR URL Dashboard automatically switches to active MGR node Helpful High Availability feature As a MGR module, enabled and configured by DeepSea Can be disabled if unwanted URL example: https://10.58.121.186:8443 Grafana and Prometheus Prometheus collects various data about the cluster Grafana represents the data as graphs Ceph Dashboard uses both to improve insight into SES Prometheus Open source event monitoring software \"Scrapes\" (collects) data from nodes/services in the cluster Real-time Time series Custom scrapers have been created for Ceph Stores scraped data in memory and on disk Presents data to other software for graphical representation Integrated nicely with Grafana Grafana The leading open source software for time series analytics \"Dashboards\" of panels, graphs, metrics, etc. \"Dashboard\" is a slightly conflicting term, but still meaningful Renders data in a graphical way collected from Prometheus Graphs are customized for use on the Ceph Dashboard Dashboard Users Always need an \u201cAdmin\u201d user for the Dashboard \u00a7 The admin keys of the root user on the \u201cAdmin\u201d node in the cluster Dashboard Users are accounts that relate only to using the Dashboard \u00a7 Not the same as Ceph CLI users and client keys; but could coincide Any person who wants to interact with the storage cluster via the Dashboard must have a user account Variety of Users established by the Admin User, and various permissions based on Admin-defined Roles User Authentication Dashboard Administrators can setup users with specific privileges The privileges and permissions are managed as \"roles\" User accounts can be created directly in the Dashboard Stored as objects in Ceph User accounts can also be tied to other authentication mechanisms: Single Sign-On Service; SAML 2.0 compliant protocol Dashboard accounts can be managed from the Dashboard or from the CLI Example: ceph dashboard ac-user-show [] The Admin Dashboard User (the term \u201cadmin\u201d is used differently in different places) The Dashboard Admin User is not the same as other admins The \u201cadmin\u201d node is obviously not directly tied to any admin user The Admin Dashboard User is created at Deployment time Given a random password by DeepSea You must use the CLI to establish the admin password ceph dashboard ac-user-show admin ceph dashboard ac-user-set-password admin \u25cb The SES Deployment Course has set the password to mypassword admin:~ # ceph dashboard ac-user-show [\"admin\"] admin:~ # ceph dashboard ac-user-show admin {\"username\": \"admin\", \"password\": \"$2b$12$4lC/AU7jc6midTZufj4P4.rBtVzRGf7Zy7fUbD6G9YfdfVEwkwuUy\", \"roles\": [\"administrator\"], \"name\": null \"email\":null\"lastUpdate\": 1601874928} Health from the Dashboard Cluster Status Monitors OSDs Manager Daemons Hosts Object Gateways Metadata Service iSCSI Gateways Cluster Performance from Dashboard Client IOPS Client Throughput Client Read/Write Recovery Throughput Scrub Performance Data Hosts: Overall Performance Monitors: Performance Counters OSDs: Relative Read/Write bar graphs, and Overall Performance Pools: Relative Read/Write bar graphs, and Overall Performance Block images: Overall Performance CephFS: Performance Details RGW: Overall Performance Cluster Capacity from Dashboard Capacity data: Number of Pools Raw Capacity Number of Objects (Ceph objects, not user objects from RGW) Placement Groups per OSD Placement Group Status","title":"Ceph Dashboard"},{"location":"linux/SES/linux_ses_memo/#basic-troubleshooting","text":"Ceph Logs Logs normally stored in /var/log/ceph/ No real logs on the admin node Each service has its own log on the MON, Storage and Gateway nodes Logs handled routinely by logrotate Ceph has logs that are stored to files and in memory (triggered by event or manual request) There are 21 different levels of logging: 0-20 (0 is no logging; 20 is the most verbose logging) There are many subsystems that do their own logging, and can be configured independently Most common: mon, osd, mgr, rados, rbd, mds, rgw Others: asok, auth, client, filestore, journal, monc, ms, paxos, and more There are only 3 types of daemons: osd, mon, mds Using Tell to Change Log Levels 1) Check the Dashboard and Health. Common commands ceph status ceph osd status ceph osd df ceph osd utilization ceph osd pool stats ceph osd tree ceph pg stat 2) Network Troubleshooting Always be sure that the network (and related services) are working properly Ceph depends heavily on tightly synchronized time; make sure network time services are working on each node DNS hostnames are similarly essential 3) Check the Logs Go to the node of the component implicated in HEALTH 4: Raise the DEBUG Level. Follow this simple formula: Raise the debug level (a little each time until you see the problem) Check the logs Repeat as necessary Don\u2019t forget to restore the debug level back to its normal level 5) Check the Storage Device If the problem is with an OSD or a storage device, go straight to the device: hdparm smartctl And check out the details of the combination of OSD and storage device: lsblk /var/lib/ceph/osd/ 6) Scrub (or not) Sometimes simply scrubbing an OSD or PG can cause the checksum-ing process to reveal problems At least some problems can be made more clear with the result of scrub and/or deep-scrub Even doing a scrub can kick Ceph into fixing the problem itself And don\u2019t forget ceph osd repair On the other hand, sometimes Scrub can make things worse. If you suspect Scrub is part of the problem, turn it off: ceph osd set noscrub ceph osd unset noscrub 7) Placement Groups When Placement Groups cause problems: * ceph pg dump summary * ceph pg dump pools * ceph pg dump_jason * ceph pg dump | less Followed by a strategic \u201crepair\u201d of the PG * ceph pg repair 8) Running supportconfig YaST Support Module From CLI: supportconfig The collected data is stored in a file called /var/log/nts__.txz","title":"Basic Troubleshooting"},{"location":"linux/SRE/01-fundamentals/","text":"\u7b2c\u4e00\u7ae0 Linux\u57fa\u7840 \u00b6 1.\u5b98\u65b9\u6587\u6863 \u00b6 Rocky Linux Instructional Books openSUSE Documentation Ubuntu Documentation 2.\u7cfb\u7edf\u73af\u5883 \u00b6 2.1.Rocky \u00b6 \u4f7f\u7528\u7248\u672c\uff1a Rocky 9.0 \u3002 \u4ece\u7f51\u7ad9\u4e0b\u8f7dRocky\u7cfb\u7edf ISO\u955c\u50cf \uff0c\u6216\u8005\u901a\u8fc7 wget \u547d\u4ee4\u4e0b\u8f7dRocky\u7cfb\u7edfISO\u955c\u50cf\u3002 wget https://download.rockylinux.org/pub/rocky/9.0/isos/x86_64/Rocky-9.0-x86_64-dvd.iso \u5b89\u88c5\u65f6\u6211\u9009\u62e9\u4e86\u6fc0\u6d3b root \u7528\u6237\uff0c\u9009\u62e9\u4e86Server\u6a21\u5f0f\u5b89\u88c5\uff08\u6ca1\u6709GUI\uff09\u3002 \u4ee5 root \u767b\u5f55\uff0c\u6267\u884c\u4e0b\u9762\u547d\u4ee4\u4fee\u6539 sudo \u6743\u9650\u3002 visudo \u5e76\u6fc0\u6d3b\u4e0b\u9762\u4e00\u884c\uff08\u4e0d\u8bbe\u5bc6\u7801\uff0c\u65b9\u4fbf\u7ec3\u4e60\uff09\uff1a %wheel ALL =( ALL ) NOPASSWD: ALL \u521b\u5efa\u7528\u6237 vagrant \uff0c\u5e76\u8bbe\u7f6e wheel \u4e3a\u4e3b\u8981\u7ec4\u548c\u4fee\u6539\u5bc6\u7801\u3002 adduser vagrant usermod -g wheel vagrant passwd vagrant \u8bbe\u5b9ahostname\uff08\u5305\u62ec\u522b\u540d\uff09\uff0c\u5e76\u67e5\u770b\u7ed3\u679c\u3002 hostnamectl set-hostname --static \"rocky9\" hostnamectl set-hostname --pretty \"rocky9\" hostnamectl cat /etc/hostname \u5c0f\u8d34\u58eb\uff1a \u7531systemd\u63a7\u5236\u7684\u4e3b\u673a\u540d\u7684\u670d\u52a1\u914d\u7f6e\u4fe1\u606f\uff1a /usr/lib/systemd/system/systemd-hostnamed.service Rocky\u7684\u8f6f\u4ef6\u6e90\u7684\u914d\u7f6e\u4fe1\u606f\u4fdd\u5b58\u5728\u76ee\u5f55 /etc/yum.repos.d/ \u4e0b\u3002\u5982\u679c\u8bbf\u95ee\u9ed8\u8ba4\u6e90\u6bd4\u8f83\u6162\uff0c\u53ef\u4ee5\u66f4\u65b0\u963f\u91cc\u6e90\u6216\u8005\u79d1\u5927\u6e90\u3002 \u66f4\u6362\u963f\u91cc\u6e90\u3002 sed -e 's|^mirrorlist=|#mirrorlist=|g' \\ -e 's|^#baseurl=http://dl.rockylinux.org/$contentdir|baseurl=https://mirrors.aliyun.com/rockylinux|g' \\ -i.bak \\ /etc/yum.repos.d/Rocky-*.repo \u66f4\u6362\u79d1\u5927\u6e90\u3002 sed -e 's|^mirrorlist=|#mirrorlist=|g' \\ -e 's|^#baseurl=http://dl.rockylinux.org/$contentdir|baseurl=https://mirrors.ustc.edu.cn/rocky|g' \\ -i.bak \\ /etc/yum.repos.d/rocky-extras.repo \\ /etc/yum.repos.d/rocky.repo \u5237\u65b0\u7f13\u5b58\u3002 dnf makecache 2.2.Ubuntu \u00b6 \u4f7f\u7528\u7248\u672c\uff1a Ubuntu 2204 \u3002 \u8bbe\u5b9aroot\u7528\u6237\u7684\u5bc6\u7801\u3002 sudo passwd root \u901a\u8fc7\u5b89\u88c5\u65f6\u5df2\u521b\u5efa\u7684\u7528\u6237 vagrant \u767b\u5f55\u3002\u6267\u884c\u4e0b\u9762\u547d\u4ee4\u4fee\u6539 sudo \u6743\u9650\u3002 sudo visudo \u6dfb\u52a0 vagrant \u5230\u7279\u6743\u7528\u6237\uff08Rocky\u548copenSUSE\u4e0d\u9700\u8981\u6dfb\u52a0\uff09\uff0c\u5e76\u6fc0\u6d3bsudo\u4e00\u884c\uff08\u4e0d\u8bbe\u5bc6\u7801\uff0c\u65b9\u4fbf\u7ec3\u4e60\uff09\uff1a # User privilege specification root ALL =( ALL:ALL ) ALL vagrant ALL =( ALL:ALL ) ALL # Allow members of group sudo to execute any command sudo ALL =( ALL:ALL ) NOPASSWD: ALL \u4fee\u6539\u7528\u6237 vagrant \u7684\u4e3b\u8981\u7ec4\u4e3a sudo \u3002 sudo usermod -g sudo vagrant \u4fee\u6539\u4e3b\u673a\u540d\u548c\u522b\u540d\u3002 sudo hostnamectl set-hostname ubuntu2204 sudo hostnamectl set-hostname ubuntu2204 --pretty \u5c0f\u8d34\u58eb\uff1a \u5982\u4f55\u5904\u7406 Username is not in the sudoers file. This incident will be reported \u95ee\u9898\u3002 \u5982\u679c\u6ca1\u6709\u521d\u59cb\u5316 root \u7528\u6237\u7684\u5bc6\u7801\uff0c\u4e14\u5f53\u524d\u7528\u6237\u4e5f\u65e0\u6cd5\u6267\u884c sudo \u547d\u4ee4\uff0c\u53ef\u4ee5\u901a\u8fc7\u4e0b\u9762\u6b65\u9aa4\u901a\u8fc7recovery\u6551\u63f4\u6a21\u5f0f\u8fdb\u884c\u6062\u590d\u3002 \u6309 shift \u952e\u5f00\u673a\uff0c\u8fdb\u5165grub\u542f\u52a8\u83dc\u5355\u3002\uff08VMWare\u4e5f\u9002\u7528\uff09 \u5411\u4e0b\u79fb\u52a8\u9ad8\u4eae\u6761\uff0c\u9009\u62e9\u83dc\u5355 Advanced options for Ubuntu \uff0c\u5e76\u786e\u8ba4\u56de\u8f66\u3002 \u9009\u62e9\u5e26\u6709 recovery mode \u7684\u5185\u6838\uff0c\u786e\u8ba4\u56de\u8f66\u3002 \u5411\u4e0b\u79fb\u52a8\u9ad8\u4eae\u6761\uff0c\u9009\u62e9\u83dc\u5355 root Drop to root shell prompt \uff0c\u5e76\u786e\u8ba4\u56de\u8f66\u3002 \u56de\u8f66\u786e\u8ba4 press Enter for maintenance \u3002 \u51fa\u73b0 root \u7684\u547d\u4ee4\u63d0\u793a\u7b26\u540e\uff0c\u6267\u884c\u547d\u4ee4 mount -o rw,remount / \u3002 \u6267\u884c\u547d\u4ee4 passwd \u7ed9 root \u8bbe\u5b9a\u5bc6\u7801\u3002 \u6267\u884c\u547d\u4ee4 adduser username sudo \u628a\u6307\u5b9a\u7528\u6237\u52a0\u5165 sudo \u7ec4\u3002 \u6267\u884c\u547d\u4ee4 visudo \u8fdb\u884c\u5fc5\u8981\u7684\u4fee\u6b63\u6216\u4fee\u6539\u3002 2.3.openSUSE \u00b6 \u4f7f\u7528\u7248\u672c\uff1a Leap 15.4 \u3002 \u9009\u62e9\u670d\u52a1\u5668\u6a21\u5f0f\u5b89\u88c5\uff0c\u65e0\u56fe\u5f62\u754c\u9762\u3002\u5b89\u88c5\u4e2d\u4e0d\u521b\u5efa\u7528\u6237\u3002 \u521b\u5efa\u7528\u6237 vagrant \uff0c\u5e76\u8bbe\u7f6e wheel \u4e3a\u4e3b\u8981\u7ec4\u3002 useradd -m -g wheel -G root -c \"vagrant\" vagrant passwd vagrant \u6267\u884c visudo \u547d\u4ee4\uff0c\u6fc0\u6d3b\u4e0b\u9762\u4e00\u884c\uff0c\u6dfb\u52a0 sudo \u6743\u9650\u3002 % wheel ALL =( ALL ) NOPASSWD: ALL \u4fee\u6539\u4e3b\u673a\u540d\u548c\u522b\u540d\u3002 sudo hostnamectl set-hostname lizard sudo hostnamectl set-hostname lizard --pretty 3.\u5e38\u7528\u547d\u4ee4 \u00b6 \u8bf4\u660e\uff1a \u9ed8\u8ba4\u5f53\u524d\u64cd\u4f5c\u7528\u6237\u4e3a vagrant \u3002 3.1.\u4fee\u6539\u63d0\u793a\u7b26\u98ce\u683c \u00b6 \u6267\u884c\u4e0b\u9762\u547d\u4ee4\u53ef\u4ee5\u770b\u5230\u5f53\u524d\u7cfb\u7edf\u7684\u547d\u4ee4\u63d0\u793a\u7b26\u683c\u5f0f\u3002 echo $PS1 \u5404\u7cfb\u7edf\u9ed8\u8ba4\u8bbe\u7f6e\u662f\u6709\u5dee\u5f02\u7684\u3002 # Rocky [ \\u @ \\h \\W ] \\$ # Ubuntu \\[\\e ] 0 ; \\u @ \\h : \\w\\a\\] ${ debian_chroot :+( $debian_chroot ) } \\[\\0 33 [ 01 ; 32m \\]\\u @ \\h\\[\\0 33 [ 00m \\] : \\[\\0 33 [ 01 ; 34m \\]\\w\\[\\0 33 [ 00m \\]\\$ # openSUSE \\u @ \\h : \\w > \u5c0f\u8d34\u58eb\uff1a bash\u53ef\u8bc6\u522b\u7684\u8f6c\u4e49\u5e8f\u5217\u6709\u4e0b\u9762\u8fd9\u4e9b\uff1a \\u : \u5f53\u524d\u7528\u6237\u7684\u8d26\u53f7\u540d\u79f0 \\h : \u4e3b\u673a\u540d\u7b2c\u4e00\u90e8\u5206 \\H : \u5b8c\u6574\u7684\u4e3b\u673a\u540d\u79f0 \\w : \u5b8c\u6574\u7684\u5de5\u4f5c\u76ee\u5f55\u540d\u79f0\uff08\u5982 \"/home/username/mywork\"\uff09 \\W : \u5f53\u524d\u5de5\u4f5c\u76ee\u5f55\u7684\"\u57fa\u540d (basename)\"\uff08\u5982 \"mywork\") \\t : \u663e\u793a\u65f6\u95f4\u4e3a24\u5c0f\u65f6\u683c\u5f0f\uff0c\u5982\uff1aHH:MM:SS \\T : \u663e\u793a\u65f6\u95f4\u4e3a12\u5c0f\u65f6\u683c\u5f0f \\A : \u663e\u793a\u65f6\u95f4\u4e3a24\u5c0f\u65f6\u683c\u5f0f\uff1aHH:MM \\@ : \u5e26\u6709 am/pm \u7684 12 \u5c0f\u65f6\u5236\u65f6\u95f4 \\d : \u4ee3\u8868\u65e5\u671f\uff0c\u683c\u5f0f\u4e3aweekday month date\uff0c\u4f8b\u5982\uff1a\"Mon Aug 1\" \\s : shell \u7684\u540d\u79f0\uff08\u5982 \"bash\") \\v : bash\u7684\u7248\u672c\uff08\u5982 2.04\uff09 \\V : bash\u7684\u7248\u672c\uff08\u5305\u62ec\u8865\u4e01\u7ea7\u522b\uff09 \\n : \u6362\u884c\u7b26 \\r : \u56de\u8f66\u7b26 \\\\ : \u53cd\u659c\u6760 \\a : ASCII \u54cd\u94c3\u5b57\u7b26\uff08\u4e5f\u53ef\u4ee5\u952e\u5165 07 \uff09 \\e : ASCII \u8f6c\u4e49\u5b57\u7b26\uff08\u4e5f\u53ef\u4ee5\u952e\u5165 33 ) \\[ : \u8fd9\u4e2a\u5e8f\u5217\u5e94\u8be5\u51fa\u73b0\u5728\u4e0d\u79fb\u52a8\u5149\u6807\u7684\u5b57\u7b26\u5e8f\u5217\uff08\u5982\u989c\u8272\u8f6c\u4e49\u5e8f\u5217\uff09\u4e4b\u524d\u3002\u5b83\u4f7fbash\u80fd\u591f\u6b63\u786e\u8ba1\u7b97\u81ea\u52a8\u6362\u884c \\] : \u8fd9\u4e2a\u5e8f\u5217\u5e94\u8be5\u51fa\u73b0\u5728\u975e\u6253\u5370\u5b57\u7b26\u5e8f\u5217\u4e4b\u540e \\# : \u4e0b\u8fbe\u7684\u7b2c\u51e0\u4e2a\u547d\u4ee4 \\$ : \u63d0\u793a\u5b57\u7b26\uff0c\u5982\u679c\u662froot\u7528\u6237\uff0c\u63d0\u793a\u7b26\u4e3a # \uff0c\u666e\u901a\u7528\u6237\u5219\u4e3a $ \u5728PS1\u4e2d\u8bbe\u7f6e\u5b57\u7b26\u989c\u8272\u7684\u683c\u5f0f\u4e3a\uff1a [\\e[F;Bm]........[\\e[0m] \uff0c\u5176\u4e2d [\\e[0m] \u4f5c\u4e3a\u989c\u8272\u8bbe\u5b9a\u7684\u7ed3\u675f\u3002 \u5176\u4e2d\"F\"\u4e3a\u5b57\u4f53\u989c\u8272\uff0c\u7f16\u53f7\u4e3a30-37\uff0c\"B\"\u4e3a\u80cc\u666f\u989c\u8272\uff0c\u7f16\u53f7\u4e3a40-47\u3002 \u5c0f\u8d34\u58eb\uff1a \u989c\u8272\u5bf9\u7167\u8868: F:30 , B:40 : \u9ed1\u8272 F:31 , B:41 : \u7ea2\u8272 F:32 , B:42 : \u7eff\u8272 F:33 , B:43 : \u9ec4\u8272 F:34 , B:44 : \u84dd\u8272 F:35 , B:45 : \u7d2b\u7ea2\u8272 F:36 , B:46 : \u9752\u84dd\u8272 F:37 , B:47 : \u767d\u8272 \u4ee5\u4e0b\u9762\u7684PS1\u8bbe\u5b9a\u4e3a\u4f8b\u8bf4\u660e\u989c\u8272\u8bbe\u5b9a\u3002 PS1 = \"\\[\\e[37;40m\\][\\[\\e[32;40m\\]\\u\\[\\e[37;40m\\]@\\h:\\[\\e[36;40m\\]\\w\\[\\e[0m\\]]\\$ \" \u62c6\u89e3\u5206\u6790\uff1a PS1=\" \\[\\e[37;40m\\] # \u6574\u4e2a\u63d0\u793a\u7b26\u533a\u57df\u524d\u666f\u767d\u8272\uff0c\u80cc\u666f\u9ed1\u8272 [ # \u663e\u793a\u5b57\u7b26[ \\[\\e[32;40m\\] # \u4fee\u9970\u540e\u9762\u7684\\u\uff0c\u524d\u666f\u7eff\u8272\uff0c\u80cc\u666f\u9ed1\u8272 \\u # \u663e\u793a\u5f53\u524d\u7528\u6237\u7684\u8d26\u53f7\u540d\u79f0 \\[\\e[37;40m\\] # \u4fee\u9970\u540e\u9762\u7684\u5b57\u7b26@\u548c\u4e3b\u673a\u540d @ # \u663e\u793a\u5b57\u7b26@ \\h # \u663e\u793a\u4e3b\u673a\u540d : # \u663e\u793a\u5b57\u7b26: \\[\\e[36;40m\\] # \u4fee\u9970\u540e\u9762\u7684\\w\uff0c\u524d\u666f\u9752\u84dd\u8272\uff0c\u80cc\u666f\u9ed1\u8272 \\w # \u663e\u793a\u5b8c\u6574\u5de5\u4f5c\u76ee\u5f55 \\[\\e[0m\\] # \u7ed3\u675f\u989c\u8272\u8bbe\u5b9a ] # \u663e\u793a\u5b57\u7b26] \\$\" # \u5982\u679c\u662froot\u7528\u6237\uff0c\u63d0\u793a\u7b26\u4e3a# \uff0c\u666e\u901a\u7528\u6237\u5219\u4e3a$ \u5bf9\u4e0d\u540c\u4e3b\u673a\u505a\u4e0d\u540c\u8bbe\u7f6e\uff1a # Rocky PS1 = \"\\[\\e[37;40m\\][\\[\\e[32;40m\\]\\u\\[\\e[37;40m\\]@\\h:\\[\\e[36;40m\\]\\w\\[\\e[0m\\]]\\$ \" # Ubuntu PS1 = \"\\[\\e[37;40m\\][\\[\\e[32;40m\\]\\u\\[\\e[33;40m\\]@\\h:\\[\\e[36;40m\\]\\w\\[\\e[0m\\]]\\$ \" # openSUSE PS1 = \"\\[\\e[37;40m\\][\\[\\e[32;40m\\]\\u\\[\\e[35;40m\\]@\\h:\\[\\e[36;40m\\]\\w\\[\\e[0m\\]]\\$ \" \u5c06\u4e0a\u8ff0PS1\u7684\u8bbe\u5b9a\uff0c\u8ffd\u52a0\u5230\u5f53\u524d\u7528\u6237\u7684 ~/.bashrc \u6587\u4ef6\u672b\u5c3e\uff0c\u4ee5\u5b9e\u73b0\u5bf9\u5f53\u524d\u7528\u6237\u7684\u63d0\u793a\u7b26\u98ce\u683c\u505a\u6301\u4e45\u4fdd\u5b58\u3002 3.2.Linux\u7684\u5185\u5916\u90e8\u547d\u4ee4 \u00b6 \u5185\u90e8\u547d\u4ee4 (internal command)\u5b9e\u9645\u4e0a\u662fshell\u7a0b\u5e8f\u7684\u4e00\u90e8\u5206\uff0c\u5305\u542b\u7684\u662f\u4e00\u4e9b\u6bd4\u8f83\u7b80\u5355\u7684linux\u7cfb\u7edf\u547d\u4ee4\uff0c\u8fd9\u4e9b\u547d\u4ee4\u7531shell\u7a0b\u5e8f\u8bc6\u522b\u5e76\u5728shell\u7a0b\u5e8f\u5185\u90e8\u5b8c\u6210\u8fd0\u884c\uff0c\u901a\u5e38\u5728linux\u7cfb\u7edf\u52a0\u8f7d\u8fd0\u884c\u65f6shell\u5c31\u88ab\u52a0\u8f7d\u5e76\u9a7b\u7559\u5728\u7cfb\u7edf\u5185\u5b58\u4e2d\u3002 \u5916\u90e8\u547d\u4ee4 (external command)\u662flinux\u7cfb\u7edf\u4e2d\u7684\u5b9e\u7528\u7a0b\u5e8f\u90e8\u5206\uff0c\u7cfb\u7edf\u52a0\u8f7d\u65f6\u5e76\u4e0d\u968f\u7cfb\u7edf\u4e00\u8d77\u88ab\u52a0\u8f7d\u5230\u5185\u5b58\u4e2d\uff0c\u800c\u662f\u5728\u9700\u8981\u65f6\u624d\u5c06\u5176\u8c03\u7528\u5185\u5b58\u3002\u901a\u5e38\u5916\u90e8\u547d\u4ee4\u7684\u5b9e\u4f53\u5e76\u4e0d\u5305\u542b\u5728shell\u4e2d\uff0c\u4f46\u662f\u5176\u547d\u4ee4\u6267\u884c\u8fc7\u7a0b\u662f\u7531shell\u7a0b\u5e8f\u63a7\u5236\u7684\u3002 \u6bd4\u5982\uff1a \u6267\u884c\u547d\u4ee4 type -t cp \uff0c\u7cfb\u7edf\u8fd4\u56de\u7ed3\u679c\u662f file \uff0c\u5916\u90e8\u547d\u4ee4\u3002 \u6267\u884c\u547d\u4ee4 type -t cd \uff0c\u7cfb\u7edf\u8fd4\u56de\u7ed3\u679c builtin \uff0c\u5185\u90e8\u547d\u4ee4\u3002 \u6267\u884c\u547d\u4ee4 enable -a cp \uff0c\u7cfb\u7edf\u8fd4\u56de -bash: enable: cp: not a shell builtin \uff0c\u4e5f\u53ef\u4ee5\u5224\u65ad\u662f\u5426\u4e3a\u5185\u90e8\u547d\u4ee4\u3002 \u5bf9\u4e8e\u5185\u90e8\u547d\u4ee4\uff0c\u53ef\u4ee5\u901a\u8fc7enable\u547d\u4ee4\u6765\u542f\u7528\u6216\u8005\u7981\u7528\u3002 # \u7981\u7528cd\u547d\u4ee4 enable -n cd # \u67e5\u770b\u6240\u6709\u88ab\u7981\u7528\u7684\u547d\u4ee4 enable -n # \u542f\u7528cd\u547d\u4ee4 enable cd \u5bf9\u4e8e\u547d\u4ee4\uff0c\u53ef\u4ee5\u901a\u8fc7 whereis \u547d\u4ee4\u6765\u67e5\u770b\u8def\u5f84\u3002 whereis cp whereis cd 3.3.CPU\u4fe1\u606f \u00b6 lscpu cat /proc/cpuinfo 3.4.\u5185\u5b58\u4f7f\u7528\u72b6\u6001 \u00b6 free cat /proc/meminfo 3.5.\u786c\u76d8\u548c\u5206\u533a\u60c5\u51b5 \u00b6 lsblk openSUSE\u5728VMWare\u9ed8\u8ba4\u5b89\u88c5\u7684\u72b6\u6001\uff1a NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINTS sda 8 :0 0 200G 0 disk \u251c\u2500sda1 8 :1 0 8M 0 part \u251c\u2500sda2 8 :2 0 198G 0 part /home \u2502 /var \u2502 /opt \u2502 /usr/local \u2502 /root \u2502 /tmp \u2502 /srv \u2502 /boot/grub2/x86_64-efi \u2502 /boot/grub2/i386-pc \u2502 /.snapshots \u2502 / \u2514\u2500sda3 8 :3 0 2G 0 part [ SWAP ] sr0 11 :0 1 3 .8G 0 rom Ubuntu\u5728VMWare\u9ed8\u8ba4\u5b89\u88c5\u7684\u72b6\u6001\uff1a NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINTS loop0 7 :0 0 61 .9M 1 loop /snap/core20/1405 loop1 7 :1 0 63 .2M 1 loop /snap/core20/1623 loop2 7 :2 0 79 .9M 1 loop /snap/lxd/22923 loop3 7 :3 0 48M 1 loop /snap/snapd/17029 loop4 7 :4 0 103M 1 loop /snap/lxd/23541 loop5 7 :5 0 48M 1 loop /snap/snapd/17336 sda 8 :0 0 50G 0 disk \u251c\u2500sda1 8 :1 0 1M 0 part \u251c\u2500sda2 8 :2 0 2G 0 part /boot \u2514\u2500sda3 8 :3 0 48G 0 part \u2514\u2500ubuntu--vg-ubuntu--lv 253 :0 0 24G 0 lvm / sr0 11 :0 1 1 .4G 0 rom Rocky\u5728VMWare\u9ed8\u8ba4\u5b89\u88c5\u7684\u72b6\u6001\uff1a NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINTS sda 8 :0 0 50G 0 disk \u251c\u2500sda1 8 :1 0 1G 0 part /boot \u2514\u2500sda2 8 :2 0 49G 0 part \u251c\u2500rl-root 253 :0 0 45 .1G 0 lvm / \u2514\u2500rl-swap 253 :1 0 3 .9G 0 lvm [ SWAP ] sr0 11 :0 1 7 .9G 0 rom 3.6.\u7cfb\u7edf\u67b6\u6784\u4fe1\u606f \u00b6 arch openSUSE\uff0cUbuntu\u548cRocky\u7684\u8fd4\u56de\u7ed3\u679c\u90fd\u662f x86_64 \u3002 3.7.\u5185\u6838\u7248\u672c \u00b6 uname -r \u4e09\u4e2a\u53d1\u884c\u7248\u8fd4\u56de\u7684\u7ed3\u679c\u4e0d\u5c3d\u76f8\u540c\uff1a # openSUSE 5 .14.21-150400.24.21-default # Ubuntu 5 .15.0-52-generic # Rocky 5 .14.0-70.17.1.el9_0.x86_64 3.8.\u64cd\u4f5c\u7cfb\u7edf\u7248\u672c \u00b6 cat /etc/os-release cat /etc/issue # Rocky 9 sudo cat /etc/redhat-release lsb-release -a lsb_release -cs lsb_release -is lsb_release -rs \u5728openSUSE\u4e2d\uff0c\u9700\u8981\u5b89\u88c5 lsb-release \u5305\u3002\u6267\u884c lsb-release -a \u548c lsb_release -a \u8fd4\u56de\u7684\u7ed3\u679c\u662f\u4e00\u6837\u7684\u3002 sudo zypper in lsb-release \u5728Ubuntu\u4e2d\uff0c\u9700\u8981\u5b89\u88c5 lsb-release \u5305\u3002\u53ea\u80fd\u6267\u884c lsb_release -a \u3002 sudo apt install lsb-release \u5728Rocky 9\u4e2d\uff0c\u627e\u4e0d\u5230 lsb-release \u76f8\u5173\u7684\u5305\u3002 3.9.\u65e5\u671f\u548c\u65f6\u95f4 \u00b6 \u663e\u793a\u9ed8\u8ba4\u683c\u5f0f\u7684\u5f53\u524d\u65e5\u671f\u3002 date \u4e09\u4e2a\u7cfb\u7edf\u7684\u9ed8\u8ba4\u65e5\u671f\u683c\u5f0f\u7565\u6709\u4e0d\u540c\u3002 # openSUSE Mon 24 Oct 2022 09 :28:06 AM CST # Ubuntu Mon Oct 24 01 :28:09 AM UTC 2022 # Rocky Mon Oct 24 09 :24:01 AM CST 2022 \u663e\u793a\u81ea1970-01-01 00:00:00 UTC\u5230\u5f53\u524d\u7684\u79d2\u6570\u3002 date +%s \u5c06\u4e0a\u4e00\u547d\u4ee4\u4e2d\u7684\u63cf\u8ff0\u8f6c\u6362\u4e3a\u7cfb\u7edf\u9ed8\u8ba4\u65e5\u671f\u683c\u5f0f\u3002 date -d @ ` date +%s ` date --date = @ '1666575347' \u663e\u793a\u786c\u4ef6\u65f6\u949f\u3002 hwclock \u4e5f\u88ab\u79f0\u4e3a Real Time Clock (RTC)\u3002 \u5728Rocky9\u4e2d\uff0c clock \u6709\u4e00\u4e2a\u8f6f\u8fde\u63a5\u6307\u5411 hwclock \uff1a /usr/sbin/clock -> hwclock \u3002\u5728openSUSE\u548cUbuntu\u4e2d\u53ea\u6709 hwclock \u3002 ll /usr/sbin/clock ll /usr/sbin/hwclock \u8bfb\u53d6RTC\u65f6\u95f4\u3002 sudo hwclock --get sudo hwclock -r \u6821\u51c6\u65f6\u95f4\uff1a -s, \u2013hctosys : \u4ee5RTC\u786c\u4ef6\u65f6\u95f4\u6765\u6821\u51c6\u7cfb\u7edf\u65f6\u95f4\u3002 -w, \u2013systohoc : \u4ee5\u7cfb\u7edf\u65f6\u95f4\u6765\u6821\u51c6RTC\u786c\u4ef6\u65f6\u95f4\u3002 \u663e\u793a\u5f53\u524d\u7cfb\u7edf\u65f6\u533a\u3002 ll /etc/localtime \u7cfb\u7edf\u53ef\u80fd\u4f1a\u8fd4\u56de\u4e0d\u540c\u7ed3\u679c\uff0c\u4f8b\u5982\uff1a /etc/localtime -> /usr/share/zoneinfo/Asia/Shanghai /etc/localtime -> /usr/share/zoneinfo/Etc/UTC \u663e\u793a\u5f53\u524d\u53ef\u4ee5\u65f6\u533a\u5217\u8868\u3002 timedatectl list-timezones timedatectl list-timezones | grep -i Asia \u4fee\u6539\u5f53\u524d\u7cfb\u7edf\u65f6\u533a\u3002 sudo timedatectl set-timezone Asia/Shanghai \u663e\u793a\u65e5\u5386\u3002 cal -y openSUSE\u548cRocky\u4e2d\uff0c\u4f7f\u7528 cal \u547d\u4ee4\u9700\u8981\u5b89\u88c5 util-linux \u5305\u3002 Ubuntu\u4e2d\uff0c\u4f7f\u7528 cal \u547d\u4ee4\u9700\u8981\u5b89\u88c5 ncal \u5305\u3002 sudo apt install ncal sudo zypper se util-linux sudo yum install util-linux 3.10.\u7528\u6237\u767b\u5f55\u4fe1\u606f \u00b6 whoami \uff1a\u5f53\u524d\u767b\u5f55\u7528\u6237 who \uff1a\u7cfb\u7edf\u5f53\u524d\u6240\u6709\u7684\u767b\u5f55\u4f1a\u8bdd w \uff1a\u7cfb\u7edf\u5f53\u524d\u6240\u6709\u7684\u767b\u5f55\u4f1a\u8bdd\u53ca\u6240\u4f5c\u7684\u64cd\u4f5c \u63d0\u793a\uff1a MOTD is the abbreviation of \"Message Of The Day\", and it is used to display a message when a remote user login to the Linux Operating system using SSH. Linux administrators often need to display different messages on the login of the user, like displaying custom information about the server or any necessary information. \u7f16\u8f91\u6587\u4ef6 /etc/motd \u53ef\u4ee5\u81ea\u5b9a\u4e49\"Message Of The Day\"\u7684\u4fe1\u606f\u3002 Ubuntu 2204\u65b0\u5b89\u88c5\u540e\u6ca1\u6709\u8fd9\u4e2a\u6587\u4ef6\uff0c\u9700\u8981\u81ea\u5df1\u521b\u5efa\u3002 openSUSE\u65b0\u5b89\u88c5\u540e\u6709\u9884\u5b9a\u4e49\u7684\u4fe1\u606f\u3002 Rocky9 \u65b0\u5b89\u88c5\u540e\u6709\u8be5\u6587\u4ef6\uff0c\u7a7a\u767d\u6587\u4ef6\u65e0\u5185\u5bb9\u3002 3.11.\u4f1a\u8bdd\u7ba1\u7406\u5de5\u5177 \u00b6 screen \u5de5\u5177 screen -S (Create new screen session) screen -ls (list current screen sessions) screen -x (Attach to existing screeen session, sync between both) screen -r (Reattach existing screen session) tmux \u5de5\u5177 tmux \u662f\u6307 Terminal Multiplexer . \u5b89\u88c5 tmux \u5de5\u5177\u3002 # Rocky sudo yum install tmux # Ubuntu sudo apt install tmux # openSUSE sudo zypper in tmux \u5e38\u7528\u65b9\u6cd5\uff1a tmux new -s (Create new session) tmux detach (Detach current session) tmux ls (list current sessions) tmux attach -t (Reattach existing session) tmux switch -t (Switch to another session) tmux kill-session -t (Kill existing session) tmux list-keys (List all short keys) tmux list-commands (List commands and parameters) tmux info (List all sessions info) tmux split-window (Split window) 3.12. echo \u547d\u4ee4 \u00b6 echo \u547d\u4ee4\u4e2d\u53ef\u4ee5\u8f93\u51fa\u53d8\u91cf\uff0c\u5982\u679c\u53d8\u91cf\u662f\u7528\u662f\u5355\u5f15\u53f7\u5f15\u8d77\u6765\uff0c\u8868\u793a\u8fd9\u4e2a\u53d8\u91cf\u4e0d\u7528IFS\u66ff\u6362\uff01\uff01 echo \"Home=$HOME\" \u7684\u8f93\u51fa\u7ed3\u679c\u662f Home=/home/vagrant echo 'Home=$HOME' \u7684\u8f93\u51fa\u7ed3\u679c\u662f Home=$HOME echo -e \u542f\u7528 \\ \u5b57\u7b26\u7684\u89e3\u91ca\u529f\u80fd\uff0c\u6bd4\u5982\uff1a echo -e \"a\\x0Ab\" \uff0c\u8f93\u51fa\u5b57\u7b26 a \u548c b \uff0c\u4e2d\u95f4 \\x0A \u4ee3\u8868\u5341\u516d\u8fdb\u5236 OA \uff08\u5373\u56de\u8f66\uff09 echo -e \"\\x4A \\x41 \\x4D \\x45 \\x53\" \uff0c\u8f93\u51fa\u7ed3\u679c\u662f J A M E S \u63d0\u793a\uff1a \u4ee5\u901a\u8fc7man 7 ascii\u6765\u67e5\u770b\u5404\u8fdb\u5236\u7684\u542b\u4e49\u3002 echo -e \u8f93\u51fa\u5e26\u989c\u8272\u5b57\u7b26\u3002 \u793a\u4f8b\uff1a echo -e \"\\e[35m \u7d2b\u8272 \\e[0m\" echo -e \"\\e[43m \u9ec4\u5e95 \\e[0m\" echo -e \"\\e[93m \u9ed1\u5e95\u9ec4\u5b57 \\e[0m\" \u53c2\u8003\u4fe1\u606f\uff1a \u5b57\u4f53\u989c\u8272\uff1a \\e[30m \uff1a \u9ed1\u8272 \\e[31m \uff1a \u7ea2\u8272 \\e[32m \uff1a \u7eff\u8272 \\e[33m \uff1a \u9ec4\u8272 \\e[34m \uff1a \u84dd\u8272 \\e[35m \uff1a \u7d2b\u8272 \\e[36m \uff1a \u9752\u8272 \\e[37m \uff1a \u767d\u8272 \\e[40m \uff1a \u9ed1\u5e95 \\e[41m \uff1a \u7ea2\u5e95 \\e[42m \uff1a \u7eff\u5e95 \\e[43m \uff1a \u9ec4\u5e95 \\e[44m \uff1a \u84dd\u5e95 \\e[45m \uff1a \u7d2b\u5e95 \\e[46m \uff1a \u9752\u5e95 \\e[47m \uff1a \u767d\u5e95 \u80cc\u666f\u989c\u8272\uff1a \\e[90m \uff1a \u9ed1\u5e95\u9ed1\u5b57 \\e[91m \uff1a \u9ed1\u5e95\u7ea2\u5b57 \\e[92m \uff1a \u9ed1\u5e95\u7eff\u5b57 \\e[93m \uff1a \u9ed1\u5e95\u9ec4\u5b57 \\e[94m \uff1a \u9ed1\u5e95\u84dd\u5b57 \\e[95m \uff1a \u9ed1\u5e95\u7d2b\u5b57 \\e[96m \uff1a \u9ed1\u5e95\u9752\u5b57 \\e[97m \uff1a \u9ed1\u5e95\u767d\u5b57 \u63a7\u5236\u5c5e\u6027\uff1a \\e[0m \u5173\u95ed\u6240\u6709\u5c5e\u6027 \\e[1m \u8bbe\u7f6e\u9ad8\u4eae\u5ea6 \\e[4m \u4e0b\u5212\u7ebf \\e[5m \u95ea\u70c1 \\e[7m \u53cd\u663e\uff0c\u649e\u8272\u663e\u793a\uff0c\u663e\u793a\u4e3a\u767d\u5b57\u9ed1\u5e95\uff0c\u6216\u8005\u663e\u793a\u4e3a\u9ed1\u5e95\u767d\u5b57 \\e[8m \u6d88\u5f71\uff0c\u5b57\u7b26\u989c\u8272\u5c06\u4f1a\u4e0e\u80cc\u666f\u989c\u8272\u76f8\u540c \\e[nA \u5149\u6807\u4e0a\u79fb n \u884c \\e[nB \u5149\u6807\u4e0b\u79fb n \u884c \\e[nC \u5149\u6807\u53f3\u79fb n \u884c \\e[nD \u5149\u6807\u5de6\u79fb n \u884c \\e[y;xH \u8bbe\u7f6e\u5149\u6807\u4f4d\u7f6e \\e[2J \u6e05\u5c4f \\e[K \u6e05\u9664\u4ece\u5149\u6807\u5230\u884c\u5c3e\u7684\u5185\u5bb9 \\e[s \u4fdd\u5b58\u5149\u6807\u4f4d\u7f6e \\e[u \u6062\u590d\u5149\u6807\u4f4d\u7f6e \\e[?25 \u9690\u85cf\u5149\u6807 \\e[?25h \u663e\u793a\u5149\u6807 3.13. man \u547d\u4ee4 \u00b6 \u5b89\u88c5\u5305\uff1a # openSUSE sudo zypper install man-pages man-pages-zh_CN man-pages-posix # Rocky sudo yum install man-pages # Ubuntu sudo apt install man-db manpages-posix manpages manpages-zh sudo apt install manpages-dev manpages-posix-dev \u66f4\u65b0mandb mandb \u67e5\u627e\u67d0\u4e2a\u547d\u4ee4\u7684man\u4fe1\u606f\uff0c\u4f8b\u5982\u67e5\u627e crontab \u547d\u4ee4\u7684\u4fe1\u606f\u3002 # \u7cbe\u786e\u67e5\u627e man -f crontab whatis crontab # \u6a21\u7cca\u67e5\u8be2 man -k crontab apropos crontab \u8f93\u51fa\u7ed3\u679c\u5982\u4e0b\uff1a crontab (5) - files used to schedule the execution of programs crontab (1) - maintains crontab files for individual users crontab (1p) - schedule periodic background work \u67e5\u627ecrontab\u7b2c5\u7ae0\u7684\u5185\u5bb9\uff0c\u5219\u53ef\u4ee5\u6267\u884c\uff1a man 5 crontab \u5e38\u7528\u5feb\u6377\u952e\u793a\u4f8bs\uff1a 1G : go to the 1 st line 10G : go to the 10 th line G : go to the end of the page /^SELinux : search the word SELinux /section OPTIONS : go to the section OPTIONS 3.14. tr \u547d\u4ee4 \u00b6 tr \u547d\u4ee4\u53ef\u4ee5\u5bf9\u6765\u81ea\u6807\u51c6\u8f93\u5165\u7684\u5b57\u7b26\u8fdb\u884c\u66ff\u6362\u3001\u538b\u7f29\u548c\u5220\u9664\u3002\u5b83\u53ef\u4ee5\u5c06\u4e00\u7ec4\u5b57\u7b26\u53d8\u6210\u53e6\u4e00\u7ec4\u5b57\u7b26\u3002 \u683c\u5f0f\uff1a tr [OPTION]... SET1 [SET2] \u4e3e\u4f8b\uff1a # \u5c06\u8f93\u5165\u5b57\u7b26\u7531\u5927\u5199\u8f6c\u6362\u4e3a\u5c0f\u5199 $ echo \"HELLO WORLD\" | tr 'A-Z' 'a-z' hello world # \u5220\u9664\u51fa\u73b0\u7684\u6570\u5b57 $ echo \"HELLO 1234 WORLD 4567\" | tr -d '0-9' HELLO WORLD # \u4ece\u8f93\u5165\u6587\u672c\u4e2d\u5c06\u4e0d\u5728\u8865\u96c6\u4e2d\u7684\u6240\u6709\u5b57\u7b26\u5220\u9664\uff08\u53ea\u4fdd\u7559\u6570\u5b571\uff0c2\uff0c3\uff0c4\uff0c5\uff09 $ echo \"HELLO 1234 WORLD 4567\" | tr -d -c '1-5' 123445 # \u5c06\u8fde\u7eed\u91cd\u590d\u7684\u5b57\u7b26\u4ee5\u5355\u72ec\u4e00\u4e2a\u5b57\u7b26\u8868\u793a $ echo \"HELLOOO 1222235555555554\" | tr -s 'O215' HELLO 12354 # \u5220\u9664\u7531\u4e8eWindows\u6587\u4ef6\u9020\u6210\u7684'^M'\u5b57\u7b26 $ cat file.txt | tr -s '\\r' '\\n' > new.txt $ cat file.txt | tr -d '\\r' > new.txt # \u5c06\u6362\u884c\u7b26\u66ff\u6362\u6210\u5236\u8868\u7b26 $ cat file.txt | tr '\\n' '\\t' > new.txt # \u5c06\u5927\u5199\u5b57\u6bcd\u8f6c\u6362\u4e3a\u5c0f\u5199\u5b57\u6bcd $ echo \"HELLO 1234 WORLD 4567\" | tr '[:upper:]' '[:lower:]' hello 1234 world 4567 3.15. tee \u547d\u4ee4 \u00b6 tee \u547d\u4ee4\u57fa\u4e8e\u6807\u51c6\u8f93\u5165\u8bfb\u53d6\u6570\u636e\uff0c\u6807\u51c6\u8f93\u51fa\u6216\u6587\u4ef6\u5199\u5165\u6570\u636e\u3002 \u4e3e\u4f8b\uff1a # ping\u547d\u4ee4\u7684\u8f93\u51fa\uff0c\u4e0d\u4ec5\u8f93\u51fa\u5230\u5c4f\u5e55\uff0c\u4e5f\u540c\u65f6\u5199\u5165\u6587\u4ef6output.txt\u4e2d\uff08\u8986\u76d6\u5f0f\u5199\u5165\uff09\u3002 $ ping www.baidu.com | tee output.txt # ping\u547d\u4ee4\u7684\u8f93\u51fa\uff0c\u4e0d\u4ec5\u8f93\u51fa\u5230\u5c4f\u5e55\uff0c\u4e5f\u540c\u65f6\u5199\u5165\u6587\u4ef6output.txt\u4e2d\uff08\u8ffd\u52a0\u5f0f\u5199\u5165\uff09\u3002 $ ping www.baidu.com | tee -a output.txt # ping\u547d\u4ee4\u7684\u8f93\u51fa\uff0c\u4e0d\u4ec5\u8f93\u51fa\u5230\u5c4f\u5e55\uff0c\u4e5f\u540c\u65f6\u5199\u5165\u591a\u4e2a\u6587\u4ef6\u4e2d\uff08\u8986\u76d6\u5f0f\u5199\u5165\uff09\u3002 $ ping www.baidu.com | tee output1.txt output2.txt output3.txt # ls\u547d\u4ee4\u7684\u8f93\u51fa\u5199\u5165\u6587\u4ef6output.txt\u4e2d\uff0c\u5e76\u4f5c\u4e3awc\u547d\u4ee4\u7684\u8f93\u5165\u3002 $ ls *.txt | tee output.txt | wc -l 4 # cat output.txt f1.txt f2.txt output.txt test.txt \u6280\u5de7\uff1a \u5728vi\u4f7f\u7528\u4e2d\uff0c\u901a\u8fc7 tee \u547d\u4ee4\u63d0\u5347\u6587\u4ef6\u5199\u5165\u6743\u9650\u3002 \u6bd4\u5982\u975eroot\u7528\u6237\u6267\u884c vi /etc/hosts \uff0c\u5728vi\u4e2d\u4f7f\u7528 :w !sudo tee % \u53ef\u4ee5\u63d0\u9ad8\u6743\u9650\u4fdd\u5b58\u8fd9\u4e2a\u6587\u4ef6\u3002 3.16.\u8bed\u8a00\u73af\u5883LANG \u00b6 \u5b89\u88c5\u8bed\u8a00\u5305\u3002 # Ubuntu sudo apt install locales-all # Rocky sudo yum install glibc-langpack-zh.x86_64 # openSUSE sudo zypper install glibc-locale glibc-locale-32bit glibc-locale-base \u67e5\u770b\u5f53\u524d\u8bed\u8a00\u8bbe\u7f6e\uff1a echo $LANG locale -a locale -k LC_TIME localectl status localectl list-locales \u5168\u5c40locale\u914d\u7f6e(Global locale settings)\u3002 # openSUSE & Rocky sudo cat /etc/locale.conf # Ubuntu sudo cat /etc/default/locale \u4e34\u65f6\u4fee\u6539\u5f53\u524dsession\u7684locale\u3002 LANG = \"zh_CN.utf8\" \u6c38\u4e45\u4fee\u6539locale\u8bbe\u7f6e\u3002 sudo localectl set-locale LANG = zh_CN.utf8 \u4fee\u6539\u56de\u539f\u8bbe\u7f6e\u3002 sudo localectl set-locale LANG = en_US.utf8 Tips: Mac OS ssh\u767b\u9646Linux\u662f\u7ec8\u7aef\u63d0\u793a /usr/bin/manpath: can't set the locale; make sure $LC_* and $LANG are correct \u89e3\u51b3\u65b9\u6cd5\uff1a\u5728\u672c\u5730mac\u7535\u8111\u4e0a\u4fee\u6539/etc/ssh/ssh_config\u6216\u8005/etc/ssh/ssh_config\u6587\u4ef6\uff0c\u5220\u9664\u6389\u6216\u8005\u6ce8\u91ca\u6389\u8fd9\u4e00\u884c\u914d\u7f6e\u5185\u5bb9 # SendEnv LANG LC_* \u3002 \u5982\u679c\u4f7f\u7528\u7684\u662f Iterm2 \uff0c\u53ef\u4ee5\u6253\u5f00 iterm2 \u7684 preferences -> Profiles -> Terminal \u83dc\u5355\u91cc\u5173\u95ed Set locale variables automatically \u9009\u9879\u3002 3.17.\u7b26\u53f7 $ \u7528\u6cd5 \u00b6 \u7b26\u53f7 $ \u7684\u7528\u6cd5\uff1a $ \uff0c\u83b7\u53d6\u53d8\u96f6\u503c\u3002 x = 1 echo $x echo \" $x \" \u5efa\u8bae\u4f7f\u7528\"$x\"\uff0c\u4ee5\u907f\u514dshell\u7f16\u7a0b\u4e2d\u4ea7\u751f\u6b67\u4e49\u3002\u5982\u4e0b\u4f8b\uff1a s = \"this is a string\" echo $s echo \"this is a string\" \u6267\u884c [ $s == \"this is a string\" ] \u4f1a\u62a5\u9519\uff0c\u8fd9\u662f\u5b9e\u9645\u751f\u6210\u7684\u6bd4\u8f83\u5f0f this is a string == \"this is a string\" \u3002 \u6211\u4eec\u9884\u671f\u7684\u662f \"this is a string\" == \"this is a string\" \uff0c\u6240\u4ee5\u9700\u8981\u6539\u6210 [ \"$s\" == \"this is a string\" ] \u3002 $0 , $1 , $n , $# \uff1a \u751f\u6210\u4e00\u4e2a\u6d4b\u8bd5\u811a\u672c\u3002 echo 'echo $0 $1 $2 $#' > test.sh chmod 755 test.sh \u9a8c\u8bc1\u5404\u4e2a\u53c2\u6570\u4f4d\u7f6e\u3002 ./test.sh a b c d e \u8f93\u51fa\u7ed3\u679c\uff1a ./test.sh a b 5 \u7ed3\u8bba\uff1a $0 \u8f93\u51fa\u811a\u672c\u6587\u4ef6\u540d\uff1b $1 \u8f93\u51fa\u7b2c\u4e00\u4e2a\u53c2\u6570\uff1b $2 \u8f93\u51fa\u7b2c\u4e8c\u4e2a\u53c2\u6570\uff1b $# \u8f93\u51fa\u53c2\u6570\u4e2a\u6570\u3002 ${} ${} \u7528\u4e8e\u533a\u5206\u53d8\u91cf\u7684\u8fb9\u754c\u3002 \u4e0b\u9762\u4f8b\u5b50\u4e2d\uff0c $abc \u65e0\u7ed3\u679c\u8f93\u51fa\uff0c ${a}bc \u8f93\u51fa\u7ed3\u679c stringbc \uff0c\u901a\u8fc7{}\u6307\u5b9a\u4e86\u67d0\u4e2a\u5b57\u7b26\u5c5e\u4e8e\u53d8\u91cf\u3002 a = \"string\" echo ${ a } bc echo $abc ${#} ${#} \u662f\u8fd4\u56de\u53d8\u91cf\u503c\u7684\u957f\u5ea6\u3002 s = 'this is a string' echo \" $s \" echo \" ${# s } \" \u547d\u4ee4 echo \"${#s}\" \u8f93\u51fa\u7ed3\u679c\u662f\u5b57\u4e32 this is a string \u7684\u957f\u5ea6 16 \u3002 $? $? \u662f\u8fd4\u56de\u4e0a\u4e00\u547d\u4ee4\u662f\u5426\u6210\u529f\u7684\u72b6\u6001\uff0c 0 \u4ee3\u8868\u6210\u529f\uff0c\u975e\u96f6\u4ee3\u8868\u5931\u8d25\u3002 ls \u662f\u4e00\u4e2a\u547d\u4ee4\uff0c\u6240\u4ee5\u8fd4\u56de\u503c\u662f 0 \u3002 tom \u662f\u4e00\u4e2a\u4e0d\u5b58\u5728\u7684\u547d\u4ee4\uff0c\u5219\u8fd4\u56de 127 \u3002 ls echo $? tom echo $? $() $() \u7b49\u540c\u4e8e\u53cd\u5f15\u53f7\u3002 echo $(ls) \u7b49\u540c\u4e8e\u6267\u884c ls \u547d\u4ee4\u3002 $() \u7684\u5f0a\u7aef\u662f\uff0c\u4e0d\u662f\u6240\u6709\u7684\u7c7bunix\u7cfb\u7edf\u90fd\u652f\u6301\uff0c\u53cd\u5f15\u53f7\u662f\u80af\u5b9a\u652f\u6301\u7684\u3002 $() \u7684\u4f18\u52bf\u662f\u76f4\u89c2\uff0c\u5728\u8f6c\u79fb\u5904\u7406\u65f6\uff0c\u6bd4\u53cd\u5f15\u53f7\u76f4\u89c2\u5bb9\u6613\u4e9b\u3002 echo $( ls ) # test.sh echo $( cat $( ls )) # echo $0 $1 $2 $# \u4e0a\u8ff0\u5d4c\u5957\u683c\u5f0f\u4e2d\uff0cls\u547d\u4ee4\u7684\u8f93\u51fa\uff0c\u662fcat\u547d\u4ee4\u7684\u8f93\u5165\uff0c\u53ef\u4ee5\u8fdb\u884c\u591a\u5c42\u5d4c\u5957\uff0c\u5185\u5c42\u547d\u4ee4\u7684\u8f93\u51fa\u662f\u5916\u5c42\u547d\u4ee4\u7684\u8f93\u5165\u3002 $[] $[] \u662f\u8868\u8fbe\u5f0f\u8ba1\u7b97\u3002 echo $ [ 3 + 2 ] $- $- \u663e\u793ashell\u5f53\u524d\u6240\u4f7f\u7528\u7684\u9009\u9879\u3002 \u6267\u884c echo $- \uff0c\u8f93\u51fa\u7ed3\u679c himBHs \u3002himBH\u6bcf\u4e00\u4e2a\u5b57\u7b26\u662f\u4e00\u4e2ashell\u7684\u9009\u9879\u3002 $! $! \u83b7\u53d6\u6700\u540e\u4e00\u4e2a\u8fd0\u884c\u7684\u540e\u53f0\u8fdb\u7a0b\u7684pid\u3002 \u6bd4\u5982\u6267\u884c cat test.sh & \uff0c\u7ed3\u679c\u4e2d\u4f1a\u5305\u542b\u4e00\u4e2apid\u53f7\uff0c\u9a6c\u4e0a\u7740\u6267\u884c echo $! \uff0c\u5982\u679c2\u4e2a\u547d\u4ee4\u95f4\u9694\u4e4b\u95f4\u6ca1\u6709\u5176\u4ed6\u540e\u53f0\u8fdb\u7a0b\u6267\u884c\uff0c\u5219\u53ef\u4ee5\u5f97\u5230\u548c\u524d\u9762\u4e00\u81f4\u7684pid\u53f7\u3002 !$ !$ \u8fd4\u56de\u4e0a\u4e00\u6761\u547d\u4ee4\u7684\u6700\u540e\u4e00\u4e2a\u53c2\u6570\u3002 \u6267\u884c ./test.sh a b c iamhere \uff0c\u5f97\u5230\u7ed3\u679c ./test.sh a b 4 \u3002 \u6267\u884c echo !$ \uff0c\u5f97\u52302\u4e2a\u7ed3\u679c\uff0c echo iamhere \u548c iamhere \u3002 !! !! \u8f93\u51fa\u4e0a\u4e00\u6761\u547d\u4ee4\uff0c\u5e76\u6267\u884c\u3002 !! \u4f1a\u5148\u8f93\u51fa\u4e0a\u4e00\u6761\u547d\u4ee4 cat test.sh \uff0c\u7136\u540e\u518d\u6267\u884c\u8fd9\u6761\u547d\u4ee4\uff0c\u7b2c\u4e8c\u884c\u5373\u6267\u884c\u7ed3\u679c\u3002 [ vagrant@lizard:~ ] $ cat test.sh echo $0 $1 $2 $# [ vagrant@lizard:~ ] $ !! cat test.sh echo $0 $1 $2 $# $$ $$ \u8f93\u51fa\u5f53\u524d\u8fdb\u7a0b\u7684pid\u3002 echo $$ $@ & $* $@ \u548c $* \u662f\u5bf9\u4f20\u5165\u53c2\u6570\u7684\u4e0d\u540c\u4f53\u73b0\uff0c $@ \u662f\u4ee5\u53d8\u91cf\u5f62\u5f0f\u5f15\u7528\u4f20\u5165\u53c2\u6570\uff0c $* \u662f\u4ee5\u6570\u7ec4\u7684\u5f62\u5f0f\u5f15\u7528\u4f20\u5165\u53c2\u6570\u3002 \u521b\u5efa\u4e00\u4e2a\u6587\u4ef6 script.sh \u5305\u542b\u4e0b\u9762\u7684\u811a\u672c\u3002\u5e76\u6dfb\u52a0\u6267\u884c\u6743\u9650 chmod 755 script.sh \u3002 echo '$@\u4ee5\u53d8\u91cf\u65b9\u5f0f\u5f15\u7528\u4f20\u5165\u53c2\u6570\uff1a' for x in \" $@ \" do echo $x done echo '$*\u4ee5\u6570\u7ec4\u7684\u5f62\u5f0f\u5f15\u7528\u4f20\u5165\u53c2\u6570\uff1a' for x in \" $* \" do echo $x done \u8f93\u51fa\u7ed3\u679c\uff1a $@ \u4ee5\u53d8\u91cf\u65b9\u5f0f\u5f15\u7528\u4f20\u5165\u53c2\u6570\uff1a a b 3 5 d $* \u4ee5\u6570\u7ec4\u7684\u5f62\u5f0f\u5f15\u7528\u4f20\u5165\u53c2\u6570\uff1a a b 3 5 d","title":"\u7b2c\u4e00\u7ae0 Linux\u57fa\u7840"},{"location":"linux/SRE/01-fundamentals/#linux","text":"","title":"\u7b2c\u4e00\u7ae0 Linux\u57fa\u7840"},{"location":"linux/SRE/01-fundamentals/#1","text":"Rocky Linux Instructional Books openSUSE Documentation Ubuntu Documentation","title":"1.\u5b98\u65b9\u6587\u6863"},{"location":"linux/SRE/01-fundamentals/#2","text":"","title":"2.\u7cfb\u7edf\u73af\u5883"},{"location":"linux/SRE/01-fundamentals/#21rocky","text":"\u4f7f\u7528\u7248\u672c\uff1a Rocky 9.0 \u3002 \u4ece\u7f51\u7ad9\u4e0b\u8f7dRocky\u7cfb\u7edf ISO\u955c\u50cf \uff0c\u6216\u8005\u901a\u8fc7 wget \u547d\u4ee4\u4e0b\u8f7dRocky\u7cfb\u7edfISO\u955c\u50cf\u3002 wget https://download.rockylinux.org/pub/rocky/9.0/isos/x86_64/Rocky-9.0-x86_64-dvd.iso \u5b89\u88c5\u65f6\u6211\u9009\u62e9\u4e86\u6fc0\u6d3b root \u7528\u6237\uff0c\u9009\u62e9\u4e86Server\u6a21\u5f0f\u5b89\u88c5\uff08\u6ca1\u6709GUI\uff09\u3002 \u4ee5 root \u767b\u5f55\uff0c\u6267\u884c\u4e0b\u9762\u547d\u4ee4\u4fee\u6539 sudo \u6743\u9650\u3002 visudo \u5e76\u6fc0\u6d3b\u4e0b\u9762\u4e00\u884c\uff08\u4e0d\u8bbe\u5bc6\u7801\uff0c\u65b9\u4fbf\u7ec3\u4e60\uff09\uff1a %wheel ALL =( ALL ) NOPASSWD: ALL \u521b\u5efa\u7528\u6237 vagrant \uff0c\u5e76\u8bbe\u7f6e wheel \u4e3a\u4e3b\u8981\u7ec4\u548c\u4fee\u6539\u5bc6\u7801\u3002 adduser vagrant usermod -g wheel vagrant passwd vagrant \u8bbe\u5b9ahostname\uff08\u5305\u62ec\u522b\u540d\uff09\uff0c\u5e76\u67e5\u770b\u7ed3\u679c\u3002 hostnamectl set-hostname --static \"rocky9\" hostnamectl set-hostname --pretty \"rocky9\" hostnamectl cat /etc/hostname \u5c0f\u8d34\u58eb\uff1a \u7531systemd\u63a7\u5236\u7684\u4e3b\u673a\u540d\u7684\u670d\u52a1\u914d\u7f6e\u4fe1\u606f\uff1a /usr/lib/systemd/system/systemd-hostnamed.service Rocky\u7684\u8f6f\u4ef6\u6e90\u7684\u914d\u7f6e\u4fe1\u606f\u4fdd\u5b58\u5728\u76ee\u5f55 /etc/yum.repos.d/ \u4e0b\u3002\u5982\u679c\u8bbf\u95ee\u9ed8\u8ba4\u6e90\u6bd4\u8f83\u6162\uff0c\u53ef\u4ee5\u66f4\u65b0\u963f\u91cc\u6e90\u6216\u8005\u79d1\u5927\u6e90\u3002 \u66f4\u6362\u963f\u91cc\u6e90\u3002 sed -e 's|^mirrorlist=|#mirrorlist=|g' \\ -e 's|^#baseurl=http://dl.rockylinux.org/$contentdir|baseurl=https://mirrors.aliyun.com/rockylinux|g' \\ -i.bak \\ /etc/yum.repos.d/Rocky-*.repo \u66f4\u6362\u79d1\u5927\u6e90\u3002 sed -e 's|^mirrorlist=|#mirrorlist=|g' \\ -e 's|^#baseurl=http://dl.rockylinux.org/$contentdir|baseurl=https://mirrors.ustc.edu.cn/rocky|g' \\ -i.bak \\ /etc/yum.repos.d/rocky-extras.repo \\ /etc/yum.repos.d/rocky.repo \u5237\u65b0\u7f13\u5b58\u3002 dnf makecache","title":"2.1.Rocky"},{"location":"linux/SRE/01-fundamentals/#22ubuntu","text":"\u4f7f\u7528\u7248\u672c\uff1a Ubuntu 2204 \u3002 \u8bbe\u5b9aroot\u7528\u6237\u7684\u5bc6\u7801\u3002 sudo passwd root \u901a\u8fc7\u5b89\u88c5\u65f6\u5df2\u521b\u5efa\u7684\u7528\u6237 vagrant \u767b\u5f55\u3002\u6267\u884c\u4e0b\u9762\u547d\u4ee4\u4fee\u6539 sudo \u6743\u9650\u3002 sudo visudo \u6dfb\u52a0 vagrant \u5230\u7279\u6743\u7528\u6237\uff08Rocky\u548copenSUSE\u4e0d\u9700\u8981\u6dfb\u52a0\uff09\uff0c\u5e76\u6fc0\u6d3bsudo\u4e00\u884c\uff08\u4e0d\u8bbe\u5bc6\u7801\uff0c\u65b9\u4fbf\u7ec3\u4e60\uff09\uff1a # User privilege specification root ALL =( ALL:ALL ) ALL vagrant ALL =( ALL:ALL ) ALL # Allow members of group sudo to execute any command sudo ALL =( ALL:ALL ) NOPASSWD: ALL \u4fee\u6539\u7528\u6237 vagrant \u7684\u4e3b\u8981\u7ec4\u4e3a sudo \u3002 sudo usermod -g sudo vagrant \u4fee\u6539\u4e3b\u673a\u540d\u548c\u522b\u540d\u3002 sudo hostnamectl set-hostname ubuntu2204 sudo hostnamectl set-hostname ubuntu2204 --pretty \u5c0f\u8d34\u58eb\uff1a \u5982\u4f55\u5904\u7406 Username is not in the sudoers file. This incident will be reported \u95ee\u9898\u3002 \u5982\u679c\u6ca1\u6709\u521d\u59cb\u5316 root \u7528\u6237\u7684\u5bc6\u7801\uff0c\u4e14\u5f53\u524d\u7528\u6237\u4e5f\u65e0\u6cd5\u6267\u884c sudo \u547d\u4ee4\uff0c\u53ef\u4ee5\u901a\u8fc7\u4e0b\u9762\u6b65\u9aa4\u901a\u8fc7recovery\u6551\u63f4\u6a21\u5f0f\u8fdb\u884c\u6062\u590d\u3002 \u6309 shift \u952e\u5f00\u673a\uff0c\u8fdb\u5165grub\u542f\u52a8\u83dc\u5355\u3002\uff08VMWare\u4e5f\u9002\u7528\uff09 \u5411\u4e0b\u79fb\u52a8\u9ad8\u4eae\u6761\uff0c\u9009\u62e9\u83dc\u5355 Advanced options for Ubuntu \uff0c\u5e76\u786e\u8ba4\u56de\u8f66\u3002 \u9009\u62e9\u5e26\u6709 recovery mode \u7684\u5185\u6838\uff0c\u786e\u8ba4\u56de\u8f66\u3002 \u5411\u4e0b\u79fb\u52a8\u9ad8\u4eae\u6761\uff0c\u9009\u62e9\u83dc\u5355 root Drop to root shell prompt \uff0c\u5e76\u786e\u8ba4\u56de\u8f66\u3002 \u56de\u8f66\u786e\u8ba4 press Enter for maintenance \u3002 \u51fa\u73b0 root \u7684\u547d\u4ee4\u63d0\u793a\u7b26\u540e\uff0c\u6267\u884c\u547d\u4ee4 mount -o rw,remount / \u3002 \u6267\u884c\u547d\u4ee4 passwd \u7ed9 root \u8bbe\u5b9a\u5bc6\u7801\u3002 \u6267\u884c\u547d\u4ee4 adduser username sudo \u628a\u6307\u5b9a\u7528\u6237\u52a0\u5165 sudo \u7ec4\u3002 \u6267\u884c\u547d\u4ee4 visudo \u8fdb\u884c\u5fc5\u8981\u7684\u4fee\u6b63\u6216\u4fee\u6539\u3002","title":"2.2.Ubuntu"},{"location":"linux/SRE/01-fundamentals/#23opensuse","text":"\u4f7f\u7528\u7248\u672c\uff1a Leap 15.4 \u3002 \u9009\u62e9\u670d\u52a1\u5668\u6a21\u5f0f\u5b89\u88c5\uff0c\u65e0\u56fe\u5f62\u754c\u9762\u3002\u5b89\u88c5\u4e2d\u4e0d\u521b\u5efa\u7528\u6237\u3002 \u521b\u5efa\u7528\u6237 vagrant \uff0c\u5e76\u8bbe\u7f6e wheel \u4e3a\u4e3b\u8981\u7ec4\u3002 useradd -m -g wheel -G root -c \"vagrant\" vagrant passwd vagrant \u6267\u884c visudo \u547d\u4ee4\uff0c\u6fc0\u6d3b\u4e0b\u9762\u4e00\u884c\uff0c\u6dfb\u52a0 sudo \u6743\u9650\u3002 % wheel ALL =( ALL ) NOPASSWD: ALL \u4fee\u6539\u4e3b\u673a\u540d\u548c\u522b\u540d\u3002 sudo hostnamectl set-hostname lizard sudo hostnamectl set-hostname lizard --pretty","title":"2.3.openSUSE"},{"location":"linux/SRE/01-fundamentals/#3","text":"\u8bf4\u660e\uff1a \u9ed8\u8ba4\u5f53\u524d\u64cd\u4f5c\u7528\u6237\u4e3a vagrant \u3002","title":"3.\u5e38\u7528\u547d\u4ee4"},{"location":"linux/SRE/01-fundamentals/#31","text":"\u6267\u884c\u4e0b\u9762\u547d\u4ee4\u53ef\u4ee5\u770b\u5230\u5f53\u524d\u7cfb\u7edf\u7684\u547d\u4ee4\u63d0\u793a\u7b26\u683c\u5f0f\u3002 echo $PS1 \u5404\u7cfb\u7edf\u9ed8\u8ba4\u8bbe\u7f6e\u662f\u6709\u5dee\u5f02\u7684\u3002 # Rocky [ \\u @ \\h \\W ] \\$ # Ubuntu \\[\\e ] 0 ; \\u @ \\h : \\w\\a\\] ${ debian_chroot :+( $debian_chroot ) } \\[\\0 33 [ 01 ; 32m \\]\\u @ \\h\\[\\0 33 [ 00m \\] : \\[\\0 33 [ 01 ; 34m \\]\\w\\[\\0 33 [ 00m \\]\\$ # openSUSE \\u @ \\h : \\w > \u5c0f\u8d34\u58eb\uff1a bash\u53ef\u8bc6\u522b\u7684\u8f6c\u4e49\u5e8f\u5217\u6709\u4e0b\u9762\u8fd9\u4e9b\uff1a \\u : \u5f53\u524d\u7528\u6237\u7684\u8d26\u53f7\u540d\u79f0 \\h : \u4e3b\u673a\u540d\u7b2c\u4e00\u90e8\u5206 \\H : \u5b8c\u6574\u7684\u4e3b\u673a\u540d\u79f0 \\w : \u5b8c\u6574\u7684\u5de5\u4f5c\u76ee\u5f55\u540d\u79f0\uff08\u5982 \"/home/username/mywork\"\uff09 \\W : \u5f53\u524d\u5de5\u4f5c\u76ee\u5f55\u7684\"\u57fa\u540d (basename)\"\uff08\u5982 \"mywork\") \\t : \u663e\u793a\u65f6\u95f4\u4e3a24\u5c0f\u65f6\u683c\u5f0f\uff0c\u5982\uff1aHH:MM:SS \\T : \u663e\u793a\u65f6\u95f4\u4e3a12\u5c0f\u65f6\u683c\u5f0f \\A : \u663e\u793a\u65f6\u95f4\u4e3a24\u5c0f\u65f6\u683c\u5f0f\uff1aHH:MM \\@ : \u5e26\u6709 am/pm \u7684 12 \u5c0f\u65f6\u5236\u65f6\u95f4 \\d : \u4ee3\u8868\u65e5\u671f\uff0c\u683c\u5f0f\u4e3aweekday month date\uff0c\u4f8b\u5982\uff1a\"Mon Aug 1\" \\s : shell \u7684\u540d\u79f0\uff08\u5982 \"bash\") \\v : bash\u7684\u7248\u672c\uff08\u5982 2.04\uff09 \\V : bash\u7684\u7248\u672c\uff08\u5305\u62ec\u8865\u4e01\u7ea7\u522b\uff09 \\n : \u6362\u884c\u7b26 \\r : \u56de\u8f66\u7b26 \\\\ : \u53cd\u659c\u6760 \\a : ASCII \u54cd\u94c3\u5b57\u7b26\uff08\u4e5f\u53ef\u4ee5\u952e\u5165 07 \uff09 \\e : ASCII \u8f6c\u4e49\u5b57\u7b26\uff08\u4e5f\u53ef\u4ee5\u952e\u5165 33 ) \\[ : \u8fd9\u4e2a\u5e8f\u5217\u5e94\u8be5\u51fa\u73b0\u5728\u4e0d\u79fb\u52a8\u5149\u6807\u7684\u5b57\u7b26\u5e8f\u5217\uff08\u5982\u989c\u8272\u8f6c\u4e49\u5e8f\u5217\uff09\u4e4b\u524d\u3002\u5b83\u4f7fbash\u80fd\u591f\u6b63\u786e\u8ba1\u7b97\u81ea\u52a8\u6362\u884c \\] : \u8fd9\u4e2a\u5e8f\u5217\u5e94\u8be5\u51fa\u73b0\u5728\u975e\u6253\u5370\u5b57\u7b26\u5e8f\u5217\u4e4b\u540e \\# : \u4e0b\u8fbe\u7684\u7b2c\u51e0\u4e2a\u547d\u4ee4 \\$ : \u63d0\u793a\u5b57\u7b26\uff0c\u5982\u679c\u662froot\u7528\u6237\uff0c\u63d0\u793a\u7b26\u4e3a # \uff0c\u666e\u901a\u7528\u6237\u5219\u4e3a $ \u5728PS1\u4e2d\u8bbe\u7f6e\u5b57\u7b26\u989c\u8272\u7684\u683c\u5f0f\u4e3a\uff1a [\\e[F;Bm]........[\\e[0m] \uff0c\u5176\u4e2d [\\e[0m] \u4f5c\u4e3a\u989c\u8272\u8bbe\u5b9a\u7684\u7ed3\u675f\u3002 \u5176\u4e2d\"F\"\u4e3a\u5b57\u4f53\u989c\u8272\uff0c\u7f16\u53f7\u4e3a30-37\uff0c\"B\"\u4e3a\u80cc\u666f\u989c\u8272\uff0c\u7f16\u53f7\u4e3a40-47\u3002 \u5c0f\u8d34\u58eb\uff1a \u989c\u8272\u5bf9\u7167\u8868: F:30 , B:40 : \u9ed1\u8272 F:31 , B:41 : \u7ea2\u8272 F:32 , B:42 : \u7eff\u8272 F:33 , B:43 : \u9ec4\u8272 F:34 , B:44 : \u84dd\u8272 F:35 , B:45 : \u7d2b\u7ea2\u8272 F:36 , B:46 : \u9752\u84dd\u8272 F:37 , B:47 : \u767d\u8272 \u4ee5\u4e0b\u9762\u7684PS1\u8bbe\u5b9a\u4e3a\u4f8b\u8bf4\u660e\u989c\u8272\u8bbe\u5b9a\u3002 PS1 = \"\\[\\e[37;40m\\][\\[\\e[32;40m\\]\\u\\[\\e[37;40m\\]@\\h:\\[\\e[36;40m\\]\\w\\[\\e[0m\\]]\\$ \" \u62c6\u89e3\u5206\u6790\uff1a PS1=\" \\[\\e[37;40m\\] # \u6574\u4e2a\u63d0\u793a\u7b26\u533a\u57df\u524d\u666f\u767d\u8272\uff0c\u80cc\u666f\u9ed1\u8272 [ # \u663e\u793a\u5b57\u7b26[ \\[\\e[32;40m\\] # \u4fee\u9970\u540e\u9762\u7684\\u\uff0c\u524d\u666f\u7eff\u8272\uff0c\u80cc\u666f\u9ed1\u8272 \\u # \u663e\u793a\u5f53\u524d\u7528\u6237\u7684\u8d26\u53f7\u540d\u79f0 \\[\\e[37;40m\\] # \u4fee\u9970\u540e\u9762\u7684\u5b57\u7b26@\u548c\u4e3b\u673a\u540d @ # \u663e\u793a\u5b57\u7b26@ \\h # \u663e\u793a\u4e3b\u673a\u540d : # \u663e\u793a\u5b57\u7b26: \\[\\e[36;40m\\] # \u4fee\u9970\u540e\u9762\u7684\\w\uff0c\u524d\u666f\u9752\u84dd\u8272\uff0c\u80cc\u666f\u9ed1\u8272 \\w # \u663e\u793a\u5b8c\u6574\u5de5\u4f5c\u76ee\u5f55 \\[\\e[0m\\] # \u7ed3\u675f\u989c\u8272\u8bbe\u5b9a ] # \u663e\u793a\u5b57\u7b26] \\$\" # \u5982\u679c\u662froot\u7528\u6237\uff0c\u63d0\u793a\u7b26\u4e3a# \uff0c\u666e\u901a\u7528\u6237\u5219\u4e3a$ \u5bf9\u4e0d\u540c\u4e3b\u673a\u505a\u4e0d\u540c\u8bbe\u7f6e\uff1a # Rocky PS1 = \"\\[\\e[37;40m\\][\\[\\e[32;40m\\]\\u\\[\\e[37;40m\\]@\\h:\\[\\e[36;40m\\]\\w\\[\\e[0m\\]]\\$ \" # Ubuntu PS1 = \"\\[\\e[37;40m\\][\\[\\e[32;40m\\]\\u\\[\\e[33;40m\\]@\\h:\\[\\e[36;40m\\]\\w\\[\\e[0m\\]]\\$ \" # openSUSE PS1 = \"\\[\\e[37;40m\\][\\[\\e[32;40m\\]\\u\\[\\e[35;40m\\]@\\h:\\[\\e[36;40m\\]\\w\\[\\e[0m\\]]\\$ \" \u5c06\u4e0a\u8ff0PS1\u7684\u8bbe\u5b9a\uff0c\u8ffd\u52a0\u5230\u5f53\u524d\u7528\u6237\u7684 ~/.bashrc \u6587\u4ef6\u672b\u5c3e\uff0c\u4ee5\u5b9e\u73b0\u5bf9\u5f53\u524d\u7528\u6237\u7684\u63d0\u793a\u7b26\u98ce\u683c\u505a\u6301\u4e45\u4fdd\u5b58\u3002","title":"3.1.\u4fee\u6539\u63d0\u793a\u7b26\u98ce\u683c"},{"location":"linux/SRE/01-fundamentals/#32linux","text":"\u5185\u90e8\u547d\u4ee4 (internal command)\u5b9e\u9645\u4e0a\u662fshell\u7a0b\u5e8f\u7684\u4e00\u90e8\u5206\uff0c\u5305\u542b\u7684\u662f\u4e00\u4e9b\u6bd4\u8f83\u7b80\u5355\u7684linux\u7cfb\u7edf\u547d\u4ee4\uff0c\u8fd9\u4e9b\u547d\u4ee4\u7531shell\u7a0b\u5e8f\u8bc6\u522b\u5e76\u5728shell\u7a0b\u5e8f\u5185\u90e8\u5b8c\u6210\u8fd0\u884c\uff0c\u901a\u5e38\u5728linux\u7cfb\u7edf\u52a0\u8f7d\u8fd0\u884c\u65f6shell\u5c31\u88ab\u52a0\u8f7d\u5e76\u9a7b\u7559\u5728\u7cfb\u7edf\u5185\u5b58\u4e2d\u3002 \u5916\u90e8\u547d\u4ee4 (external command)\u662flinux\u7cfb\u7edf\u4e2d\u7684\u5b9e\u7528\u7a0b\u5e8f\u90e8\u5206\uff0c\u7cfb\u7edf\u52a0\u8f7d\u65f6\u5e76\u4e0d\u968f\u7cfb\u7edf\u4e00\u8d77\u88ab\u52a0\u8f7d\u5230\u5185\u5b58\u4e2d\uff0c\u800c\u662f\u5728\u9700\u8981\u65f6\u624d\u5c06\u5176\u8c03\u7528\u5185\u5b58\u3002\u901a\u5e38\u5916\u90e8\u547d\u4ee4\u7684\u5b9e\u4f53\u5e76\u4e0d\u5305\u542b\u5728shell\u4e2d\uff0c\u4f46\u662f\u5176\u547d\u4ee4\u6267\u884c\u8fc7\u7a0b\u662f\u7531shell\u7a0b\u5e8f\u63a7\u5236\u7684\u3002 \u6bd4\u5982\uff1a \u6267\u884c\u547d\u4ee4 type -t cp \uff0c\u7cfb\u7edf\u8fd4\u56de\u7ed3\u679c\u662f file \uff0c\u5916\u90e8\u547d\u4ee4\u3002 \u6267\u884c\u547d\u4ee4 type -t cd \uff0c\u7cfb\u7edf\u8fd4\u56de\u7ed3\u679c builtin \uff0c\u5185\u90e8\u547d\u4ee4\u3002 \u6267\u884c\u547d\u4ee4 enable -a cp \uff0c\u7cfb\u7edf\u8fd4\u56de -bash: enable: cp: not a shell builtin \uff0c\u4e5f\u53ef\u4ee5\u5224\u65ad\u662f\u5426\u4e3a\u5185\u90e8\u547d\u4ee4\u3002 \u5bf9\u4e8e\u5185\u90e8\u547d\u4ee4\uff0c\u53ef\u4ee5\u901a\u8fc7enable\u547d\u4ee4\u6765\u542f\u7528\u6216\u8005\u7981\u7528\u3002 # \u7981\u7528cd\u547d\u4ee4 enable -n cd # \u67e5\u770b\u6240\u6709\u88ab\u7981\u7528\u7684\u547d\u4ee4 enable -n # \u542f\u7528cd\u547d\u4ee4 enable cd \u5bf9\u4e8e\u547d\u4ee4\uff0c\u53ef\u4ee5\u901a\u8fc7 whereis \u547d\u4ee4\u6765\u67e5\u770b\u8def\u5f84\u3002 whereis cp whereis cd","title":"3.2.Linux\u7684\u5185\u5916\u90e8\u547d\u4ee4"},{"location":"linux/SRE/01-fundamentals/#33cpu","text":"lscpu cat /proc/cpuinfo","title":"3.3.CPU\u4fe1\u606f"},{"location":"linux/SRE/01-fundamentals/#34","text":"free cat /proc/meminfo","title":"3.4.\u5185\u5b58\u4f7f\u7528\u72b6\u6001"},{"location":"linux/SRE/01-fundamentals/#35","text":"lsblk openSUSE\u5728VMWare\u9ed8\u8ba4\u5b89\u88c5\u7684\u72b6\u6001\uff1a NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINTS sda 8 :0 0 200G 0 disk \u251c\u2500sda1 8 :1 0 8M 0 part \u251c\u2500sda2 8 :2 0 198G 0 part /home \u2502 /var \u2502 /opt \u2502 /usr/local \u2502 /root \u2502 /tmp \u2502 /srv \u2502 /boot/grub2/x86_64-efi \u2502 /boot/grub2/i386-pc \u2502 /.snapshots \u2502 / \u2514\u2500sda3 8 :3 0 2G 0 part [ SWAP ] sr0 11 :0 1 3 .8G 0 rom Ubuntu\u5728VMWare\u9ed8\u8ba4\u5b89\u88c5\u7684\u72b6\u6001\uff1a NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINTS loop0 7 :0 0 61 .9M 1 loop /snap/core20/1405 loop1 7 :1 0 63 .2M 1 loop /snap/core20/1623 loop2 7 :2 0 79 .9M 1 loop /snap/lxd/22923 loop3 7 :3 0 48M 1 loop /snap/snapd/17029 loop4 7 :4 0 103M 1 loop /snap/lxd/23541 loop5 7 :5 0 48M 1 loop /snap/snapd/17336 sda 8 :0 0 50G 0 disk \u251c\u2500sda1 8 :1 0 1M 0 part \u251c\u2500sda2 8 :2 0 2G 0 part /boot \u2514\u2500sda3 8 :3 0 48G 0 part \u2514\u2500ubuntu--vg-ubuntu--lv 253 :0 0 24G 0 lvm / sr0 11 :0 1 1 .4G 0 rom Rocky\u5728VMWare\u9ed8\u8ba4\u5b89\u88c5\u7684\u72b6\u6001\uff1a NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINTS sda 8 :0 0 50G 0 disk \u251c\u2500sda1 8 :1 0 1G 0 part /boot \u2514\u2500sda2 8 :2 0 49G 0 part \u251c\u2500rl-root 253 :0 0 45 .1G 0 lvm / \u2514\u2500rl-swap 253 :1 0 3 .9G 0 lvm [ SWAP ] sr0 11 :0 1 7 .9G 0 rom","title":"3.5.\u786c\u76d8\u548c\u5206\u533a\u60c5\u51b5"},{"location":"linux/SRE/01-fundamentals/#36","text":"arch openSUSE\uff0cUbuntu\u548cRocky\u7684\u8fd4\u56de\u7ed3\u679c\u90fd\u662f x86_64 \u3002","title":"3.6.\u7cfb\u7edf\u67b6\u6784\u4fe1\u606f"},{"location":"linux/SRE/01-fundamentals/#37","text":"uname -r \u4e09\u4e2a\u53d1\u884c\u7248\u8fd4\u56de\u7684\u7ed3\u679c\u4e0d\u5c3d\u76f8\u540c\uff1a # openSUSE 5 .14.21-150400.24.21-default # Ubuntu 5 .15.0-52-generic # Rocky 5 .14.0-70.17.1.el9_0.x86_64","title":"3.7.\u5185\u6838\u7248\u672c"},{"location":"linux/SRE/01-fundamentals/#38","text":"cat /etc/os-release cat /etc/issue # Rocky 9 sudo cat /etc/redhat-release lsb-release -a lsb_release -cs lsb_release -is lsb_release -rs \u5728openSUSE\u4e2d\uff0c\u9700\u8981\u5b89\u88c5 lsb-release \u5305\u3002\u6267\u884c lsb-release -a \u548c lsb_release -a \u8fd4\u56de\u7684\u7ed3\u679c\u662f\u4e00\u6837\u7684\u3002 sudo zypper in lsb-release \u5728Ubuntu\u4e2d\uff0c\u9700\u8981\u5b89\u88c5 lsb-release \u5305\u3002\u53ea\u80fd\u6267\u884c lsb_release -a \u3002 sudo apt install lsb-release \u5728Rocky 9\u4e2d\uff0c\u627e\u4e0d\u5230 lsb-release \u76f8\u5173\u7684\u5305\u3002","title":"3.8.\u64cd\u4f5c\u7cfb\u7edf\u7248\u672c"},{"location":"linux/SRE/01-fundamentals/#39","text":"\u663e\u793a\u9ed8\u8ba4\u683c\u5f0f\u7684\u5f53\u524d\u65e5\u671f\u3002 date \u4e09\u4e2a\u7cfb\u7edf\u7684\u9ed8\u8ba4\u65e5\u671f\u683c\u5f0f\u7565\u6709\u4e0d\u540c\u3002 # openSUSE Mon 24 Oct 2022 09 :28:06 AM CST # Ubuntu Mon Oct 24 01 :28:09 AM UTC 2022 # Rocky Mon Oct 24 09 :24:01 AM CST 2022 \u663e\u793a\u81ea1970-01-01 00:00:00 UTC\u5230\u5f53\u524d\u7684\u79d2\u6570\u3002 date +%s \u5c06\u4e0a\u4e00\u547d\u4ee4\u4e2d\u7684\u63cf\u8ff0\u8f6c\u6362\u4e3a\u7cfb\u7edf\u9ed8\u8ba4\u65e5\u671f\u683c\u5f0f\u3002 date -d @ ` date +%s ` date --date = @ '1666575347' \u663e\u793a\u786c\u4ef6\u65f6\u949f\u3002 hwclock \u4e5f\u88ab\u79f0\u4e3a Real Time Clock (RTC)\u3002 \u5728Rocky9\u4e2d\uff0c clock \u6709\u4e00\u4e2a\u8f6f\u8fde\u63a5\u6307\u5411 hwclock \uff1a /usr/sbin/clock -> hwclock \u3002\u5728openSUSE\u548cUbuntu\u4e2d\u53ea\u6709 hwclock \u3002 ll /usr/sbin/clock ll /usr/sbin/hwclock \u8bfb\u53d6RTC\u65f6\u95f4\u3002 sudo hwclock --get sudo hwclock -r \u6821\u51c6\u65f6\u95f4\uff1a -s, \u2013hctosys : \u4ee5RTC\u786c\u4ef6\u65f6\u95f4\u6765\u6821\u51c6\u7cfb\u7edf\u65f6\u95f4\u3002 -w, \u2013systohoc : \u4ee5\u7cfb\u7edf\u65f6\u95f4\u6765\u6821\u51c6RTC\u786c\u4ef6\u65f6\u95f4\u3002 \u663e\u793a\u5f53\u524d\u7cfb\u7edf\u65f6\u533a\u3002 ll /etc/localtime \u7cfb\u7edf\u53ef\u80fd\u4f1a\u8fd4\u56de\u4e0d\u540c\u7ed3\u679c\uff0c\u4f8b\u5982\uff1a /etc/localtime -> /usr/share/zoneinfo/Asia/Shanghai /etc/localtime -> /usr/share/zoneinfo/Etc/UTC \u663e\u793a\u5f53\u524d\u53ef\u4ee5\u65f6\u533a\u5217\u8868\u3002 timedatectl list-timezones timedatectl list-timezones | grep -i Asia \u4fee\u6539\u5f53\u524d\u7cfb\u7edf\u65f6\u533a\u3002 sudo timedatectl set-timezone Asia/Shanghai \u663e\u793a\u65e5\u5386\u3002 cal -y openSUSE\u548cRocky\u4e2d\uff0c\u4f7f\u7528 cal \u547d\u4ee4\u9700\u8981\u5b89\u88c5 util-linux \u5305\u3002 Ubuntu\u4e2d\uff0c\u4f7f\u7528 cal \u547d\u4ee4\u9700\u8981\u5b89\u88c5 ncal \u5305\u3002 sudo apt install ncal sudo zypper se util-linux sudo yum install util-linux","title":"3.9.\u65e5\u671f\u548c\u65f6\u95f4"},{"location":"linux/SRE/01-fundamentals/#310","text":"whoami \uff1a\u5f53\u524d\u767b\u5f55\u7528\u6237 who \uff1a\u7cfb\u7edf\u5f53\u524d\u6240\u6709\u7684\u767b\u5f55\u4f1a\u8bdd w \uff1a\u7cfb\u7edf\u5f53\u524d\u6240\u6709\u7684\u767b\u5f55\u4f1a\u8bdd\u53ca\u6240\u4f5c\u7684\u64cd\u4f5c \u63d0\u793a\uff1a MOTD is the abbreviation of \"Message Of The Day\", and it is used to display a message when a remote user login to the Linux Operating system using SSH. Linux administrators often need to display different messages on the login of the user, like displaying custom information about the server or any necessary information. \u7f16\u8f91\u6587\u4ef6 /etc/motd \u53ef\u4ee5\u81ea\u5b9a\u4e49\"Message Of The Day\"\u7684\u4fe1\u606f\u3002 Ubuntu 2204\u65b0\u5b89\u88c5\u540e\u6ca1\u6709\u8fd9\u4e2a\u6587\u4ef6\uff0c\u9700\u8981\u81ea\u5df1\u521b\u5efa\u3002 openSUSE\u65b0\u5b89\u88c5\u540e\u6709\u9884\u5b9a\u4e49\u7684\u4fe1\u606f\u3002 Rocky9 \u65b0\u5b89\u88c5\u540e\u6709\u8be5\u6587\u4ef6\uff0c\u7a7a\u767d\u6587\u4ef6\u65e0\u5185\u5bb9\u3002","title":"3.10.\u7528\u6237\u767b\u5f55\u4fe1\u606f"},{"location":"linux/SRE/01-fundamentals/#311","text":"screen \u5de5\u5177 screen -S (Create new screen session) screen -ls (list current screen sessions) screen -x (Attach to existing screeen session, sync between both) screen -r (Reattach existing screen session) tmux \u5de5\u5177 tmux \u662f\u6307 Terminal Multiplexer . \u5b89\u88c5 tmux \u5de5\u5177\u3002 # Rocky sudo yum install tmux # Ubuntu sudo apt install tmux # openSUSE sudo zypper in tmux \u5e38\u7528\u65b9\u6cd5\uff1a tmux new -s (Create new session) tmux detach (Detach current session) tmux ls (list current sessions) tmux attach -t (Reattach existing session) tmux switch -t (Switch to another session) tmux kill-session -t (Kill existing session) tmux list-keys (List all short keys) tmux list-commands (List commands and parameters) tmux info (List all sessions info) tmux split-window (Split window)","title":"3.11.\u4f1a\u8bdd\u7ba1\u7406\u5de5\u5177"},{"location":"linux/SRE/01-fundamentals/#312echo","text":"echo \u547d\u4ee4\u4e2d\u53ef\u4ee5\u8f93\u51fa\u53d8\u91cf\uff0c\u5982\u679c\u53d8\u91cf\u662f\u7528\u662f\u5355\u5f15\u53f7\u5f15\u8d77\u6765\uff0c\u8868\u793a\u8fd9\u4e2a\u53d8\u91cf\u4e0d\u7528IFS\u66ff\u6362\uff01\uff01 echo \"Home=$HOME\" \u7684\u8f93\u51fa\u7ed3\u679c\u662f Home=/home/vagrant echo 'Home=$HOME' \u7684\u8f93\u51fa\u7ed3\u679c\u662f Home=$HOME echo -e \u542f\u7528 \\ \u5b57\u7b26\u7684\u89e3\u91ca\u529f\u80fd\uff0c\u6bd4\u5982\uff1a echo -e \"a\\x0Ab\" \uff0c\u8f93\u51fa\u5b57\u7b26 a \u548c b \uff0c\u4e2d\u95f4 \\x0A \u4ee3\u8868\u5341\u516d\u8fdb\u5236 OA \uff08\u5373\u56de\u8f66\uff09 echo -e \"\\x4A \\x41 \\x4D \\x45 \\x53\" \uff0c\u8f93\u51fa\u7ed3\u679c\u662f J A M E S \u63d0\u793a\uff1a \u4ee5\u901a\u8fc7man 7 ascii\u6765\u67e5\u770b\u5404\u8fdb\u5236\u7684\u542b\u4e49\u3002 echo -e \u8f93\u51fa\u5e26\u989c\u8272\u5b57\u7b26\u3002 \u793a\u4f8b\uff1a echo -e \"\\e[35m \u7d2b\u8272 \\e[0m\" echo -e \"\\e[43m \u9ec4\u5e95 \\e[0m\" echo -e \"\\e[93m \u9ed1\u5e95\u9ec4\u5b57 \\e[0m\" \u53c2\u8003\u4fe1\u606f\uff1a \u5b57\u4f53\u989c\u8272\uff1a \\e[30m \uff1a \u9ed1\u8272 \\e[31m \uff1a \u7ea2\u8272 \\e[32m \uff1a \u7eff\u8272 \\e[33m \uff1a \u9ec4\u8272 \\e[34m \uff1a \u84dd\u8272 \\e[35m \uff1a \u7d2b\u8272 \\e[36m \uff1a \u9752\u8272 \\e[37m \uff1a \u767d\u8272 \\e[40m \uff1a \u9ed1\u5e95 \\e[41m \uff1a \u7ea2\u5e95 \\e[42m \uff1a \u7eff\u5e95 \\e[43m \uff1a \u9ec4\u5e95 \\e[44m \uff1a \u84dd\u5e95 \\e[45m \uff1a \u7d2b\u5e95 \\e[46m \uff1a \u9752\u5e95 \\e[47m \uff1a \u767d\u5e95 \u80cc\u666f\u989c\u8272\uff1a \\e[90m \uff1a \u9ed1\u5e95\u9ed1\u5b57 \\e[91m \uff1a \u9ed1\u5e95\u7ea2\u5b57 \\e[92m \uff1a \u9ed1\u5e95\u7eff\u5b57 \\e[93m \uff1a \u9ed1\u5e95\u9ec4\u5b57 \\e[94m \uff1a \u9ed1\u5e95\u84dd\u5b57 \\e[95m \uff1a \u9ed1\u5e95\u7d2b\u5b57 \\e[96m \uff1a \u9ed1\u5e95\u9752\u5b57 \\e[97m \uff1a \u9ed1\u5e95\u767d\u5b57 \u63a7\u5236\u5c5e\u6027\uff1a \\e[0m \u5173\u95ed\u6240\u6709\u5c5e\u6027 \\e[1m \u8bbe\u7f6e\u9ad8\u4eae\u5ea6 \\e[4m \u4e0b\u5212\u7ebf \\e[5m \u95ea\u70c1 \\e[7m \u53cd\u663e\uff0c\u649e\u8272\u663e\u793a\uff0c\u663e\u793a\u4e3a\u767d\u5b57\u9ed1\u5e95\uff0c\u6216\u8005\u663e\u793a\u4e3a\u9ed1\u5e95\u767d\u5b57 \\e[8m \u6d88\u5f71\uff0c\u5b57\u7b26\u989c\u8272\u5c06\u4f1a\u4e0e\u80cc\u666f\u989c\u8272\u76f8\u540c \\e[nA \u5149\u6807\u4e0a\u79fb n \u884c \\e[nB \u5149\u6807\u4e0b\u79fb n \u884c \\e[nC \u5149\u6807\u53f3\u79fb n \u884c \\e[nD \u5149\u6807\u5de6\u79fb n \u884c \\e[y;xH \u8bbe\u7f6e\u5149\u6807\u4f4d\u7f6e \\e[2J \u6e05\u5c4f \\e[K \u6e05\u9664\u4ece\u5149\u6807\u5230\u884c\u5c3e\u7684\u5185\u5bb9 \\e[s \u4fdd\u5b58\u5149\u6807\u4f4d\u7f6e \\e[u \u6062\u590d\u5149\u6807\u4f4d\u7f6e \\e[?25 \u9690\u85cf\u5149\u6807 \\e[?25h \u663e\u793a\u5149\u6807","title":"3.12.echo\u547d\u4ee4"},{"location":"linux/SRE/01-fundamentals/#313man","text":"\u5b89\u88c5\u5305\uff1a # openSUSE sudo zypper install man-pages man-pages-zh_CN man-pages-posix # Rocky sudo yum install man-pages # Ubuntu sudo apt install man-db manpages-posix manpages manpages-zh sudo apt install manpages-dev manpages-posix-dev \u66f4\u65b0mandb mandb \u67e5\u627e\u67d0\u4e2a\u547d\u4ee4\u7684man\u4fe1\u606f\uff0c\u4f8b\u5982\u67e5\u627e crontab \u547d\u4ee4\u7684\u4fe1\u606f\u3002 # \u7cbe\u786e\u67e5\u627e man -f crontab whatis crontab # \u6a21\u7cca\u67e5\u8be2 man -k crontab apropos crontab \u8f93\u51fa\u7ed3\u679c\u5982\u4e0b\uff1a crontab (5) - files used to schedule the execution of programs crontab (1) - maintains crontab files for individual users crontab (1p) - schedule periodic background work \u67e5\u627ecrontab\u7b2c5\u7ae0\u7684\u5185\u5bb9\uff0c\u5219\u53ef\u4ee5\u6267\u884c\uff1a man 5 crontab \u5e38\u7528\u5feb\u6377\u952e\u793a\u4f8bs\uff1a 1G : go to the 1 st line 10G : go to the 10 th line G : go to the end of the page /^SELinux : search the word SELinux /section OPTIONS : go to the section OPTIONS","title":"3.13.man\u547d\u4ee4"},{"location":"linux/SRE/01-fundamentals/#314tr","text":"tr \u547d\u4ee4\u53ef\u4ee5\u5bf9\u6765\u81ea\u6807\u51c6\u8f93\u5165\u7684\u5b57\u7b26\u8fdb\u884c\u66ff\u6362\u3001\u538b\u7f29\u548c\u5220\u9664\u3002\u5b83\u53ef\u4ee5\u5c06\u4e00\u7ec4\u5b57\u7b26\u53d8\u6210\u53e6\u4e00\u7ec4\u5b57\u7b26\u3002 \u683c\u5f0f\uff1a tr [OPTION]... SET1 [SET2] \u4e3e\u4f8b\uff1a # \u5c06\u8f93\u5165\u5b57\u7b26\u7531\u5927\u5199\u8f6c\u6362\u4e3a\u5c0f\u5199 $ echo \"HELLO WORLD\" | tr 'A-Z' 'a-z' hello world # \u5220\u9664\u51fa\u73b0\u7684\u6570\u5b57 $ echo \"HELLO 1234 WORLD 4567\" | tr -d '0-9' HELLO WORLD # \u4ece\u8f93\u5165\u6587\u672c\u4e2d\u5c06\u4e0d\u5728\u8865\u96c6\u4e2d\u7684\u6240\u6709\u5b57\u7b26\u5220\u9664\uff08\u53ea\u4fdd\u7559\u6570\u5b571\uff0c2\uff0c3\uff0c4\uff0c5\uff09 $ echo \"HELLO 1234 WORLD 4567\" | tr -d -c '1-5' 123445 # \u5c06\u8fde\u7eed\u91cd\u590d\u7684\u5b57\u7b26\u4ee5\u5355\u72ec\u4e00\u4e2a\u5b57\u7b26\u8868\u793a $ echo \"HELLOOO 1222235555555554\" | tr -s 'O215' HELLO 12354 # \u5220\u9664\u7531\u4e8eWindows\u6587\u4ef6\u9020\u6210\u7684'^M'\u5b57\u7b26 $ cat file.txt | tr -s '\\r' '\\n' > new.txt $ cat file.txt | tr -d '\\r' > new.txt # \u5c06\u6362\u884c\u7b26\u66ff\u6362\u6210\u5236\u8868\u7b26 $ cat file.txt | tr '\\n' '\\t' > new.txt # \u5c06\u5927\u5199\u5b57\u6bcd\u8f6c\u6362\u4e3a\u5c0f\u5199\u5b57\u6bcd $ echo \"HELLO 1234 WORLD 4567\" | tr '[:upper:]' '[:lower:]' hello 1234 world 4567","title":"3.14.tr\u547d\u4ee4"},{"location":"linux/SRE/01-fundamentals/#315tee","text":"tee \u547d\u4ee4\u57fa\u4e8e\u6807\u51c6\u8f93\u5165\u8bfb\u53d6\u6570\u636e\uff0c\u6807\u51c6\u8f93\u51fa\u6216\u6587\u4ef6\u5199\u5165\u6570\u636e\u3002 \u4e3e\u4f8b\uff1a # ping\u547d\u4ee4\u7684\u8f93\u51fa\uff0c\u4e0d\u4ec5\u8f93\u51fa\u5230\u5c4f\u5e55\uff0c\u4e5f\u540c\u65f6\u5199\u5165\u6587\u4ef6output.txt\u4e2d\uff08\u8986\u76d6\u5f0f\u5199\u5165\uff09\u3002 $ ping www.baidu.com | tee output.txt # ping\u547d\u4ee4\u7684\u8f93\u51fa\uff0c\u4e0d\u4ec5\u8f93\u51fa\u5230\u5c4f\u5e55\uff0c\u4e5f\u540c\u65f6\u5199\u5165\u6587\u4ef6output.txt\u4e2d\uff08\u8ffd\u52a0\u5f0f\u5199\u5165\uff09\u3002 $ ping www.baidu.com | tee -a output.txt # ping\u547d\u4ee4\u7684\u8f93\u51fa\uff0c\u4e0d\u4ec5\u8f93\u51fa\u5230\u5c4f\u5e55\uff0c\u4e5f\u540c\u65f6\u5199\u5165\u591a\u4e2a\u6587\u4ef6\u4e2d\uff08\u8986\u76d6\u5f0f\u5199\u5165\uff09\u3002 $ ping www.baidu.com | tee output1.txt output2.txt output3.txt # ls\u547d\u4ee4\u7684\u8f93\u51fa\u5199\u5165\u6587\u4ef6output.txt\u4e2d\uff0c\u5e76\u4f5c\u4e3awc\u547d\u4ee4\u7684\u8f93\u5165\u3002 $ ls *.txt | tee output.txt | wc -l 4 # cat output.txt f1.txt f2.txt output.txt test.txt \u6280\u5de7\uff1a \u5728vi\u4f7f\u7528\u4e2d\uff0c\u901a\u8fc7 tee \u547d\u4ee4\u63d0\u5347\u6587\u4ef6\u5199\u5165\u6743\u9650\u3002 \u6bd4\u5982\u975eroot\u7528\u6237\u6267\u884c vi /etc/hosts \uff0c\u5728vi\u4e2d\u4f7f\u7528 :w !sudo tee % \u53ef\u4ee5\u63d0\u9ad8\u6743\u9650\u4fdd\u5b58\u8fd9\u4e2a\u6587\u4ef6\u3002","title":"3.15.tee\u547d\u4ee4"},{"location":"linux/SRE/01-fundamentals/#316lang","text":"\u5b89\u88c5\u8bed\u8a00\u5305\u3002 # Ubuntu sudo apt install locales-all # Rocky sudo yum install glibc-langpack-zh.x86_64 # openSUSE sudo zypper install glibc-locale glibc-locale-32bit glibc-locale-base \u67e5\u770b\u5f53\u524d\u8bed\u8a00\u8bbe\u7f6e\uff1a echo $LANG locale -a locale -k LC_TIME localectl status localectl list-locales \u5168\u5c40locale\u914d\u7f6e(Global locale settings)\u3002 # openSUSE & Rocky sudo cat /etc/locale.conf # Ubuntu sudo cat /etc/default/locale \u4e34\u65f6\u4fee\u6539\u5f53\u524dsession\u7684locale\u3002 LANG = \"zh_CN.utf8\" \u6c38\u4e45\u4fee\u6539locale\u8bbe\u7f6e\u3002 sudo localectl set-locale LANG = zh_CN.utf8 \u4fee\u6539\u56de\u539f\u8bbe\u7f6e\u3002 sudo localectl set-locale LANG = en_US.utf8 Tips: Mac OS ssh\u767b\u9646Linux\u662f\u7ec8\u7aef\u63d0\u793a /usr/bin/manpath: can't set the locale; make sure $LC_* and $LANG are correct \u89e3\u51b3\u65b9\u6cd5\uff1a\u5728\u672c\u5730mac\u7535\u8111\u4e0a\u4fee\u6539/etc/ssh/ssh_config\u6216\u8005/etc/ssh/ssh_config\u6587\u4ef6\uff0c\u5220\u9664\u6389\u6216\u8005\u6ce8\u91ca\u6389\u8fd9\u4e00\u884c\u914d\u7f6e\u5185\u5bb9 # SendEnv LANG LC_* \u3002 \u5982\u679c\u4f7f\u7528\u7684\u662f Iterm2 \uff0c\u53ef\u4ee5\u6253\u5f00 iterm2 \u7684 preferences -> Profiles -> Terminal \u83dc\u5355\u91cc\u5173\u95ed Set locale variables automatically \u9009\u9879\u3002","title":"3.16.\u8bed\u8a00\u73af\u5883LANG"},{"location":"linux/SRE/01-fundamentals/#317","text":"\u7b26\u53f7 $ \u7684\u7528\u6cd5\uff1a $ \uff0c\u83b7\u53d6\u53d8\u96f6\u503c\u3002 x = 1 echo $x echo \" $x \" \u5efa\u8bae\u4f7f\u7528\"$x\"\uff0c\u4ee5\u907f\u514dshell\u7f16\u7a0b\u4e2d\u4ea7\u751f\u6b67\u4e49\u3002\u5982\u4e0b\u4f8b\uff1a s = \"this is a string\" echo $s echo \"this is a string\" \u6267\u884c [ $s == \"this is a string\" ] \u4f1a\u62a5\u9519\uff0c\u8fd9\u662f\u5b9e\u9645\u751f\u6210\u7684\u6bd4\u8f83\u5f0f this is a string == \"this is a string\" \u3002 \u6211\u4eec\u9884\u671f\u7684\u662f \"this is a string\" == \"this is a string\" \uff0c\u6240\u4ee5\u9700\u8981\u6539\u6210 [ \"$s\" == \"this is a string\" ] \u3002 $0 , $1 , $n , $# \uff1a \u751f\u6210\u4e00\u4e2a\u6d4b\u8bd5\u811a\u672c\u3002 echo 'echo $0 $1 $2 $#' > test.sh chmod 755 test.sh \u9a8c\u8bc1\u5404\u4e2a\u53c2\u6570\u4f4d\u7f6e\u3002 ./test.sh a b c d e \u8f93\u51fa\u7ed3\u679c\uff1a ./test.sh a b 5 \u7ed3\u8bba\uff1a $0 \u8f93\u51fa\u811a\u672c\u6587\u4ef6\u540d\uff1b $1 \u8f93\u51fa\u7b2c\u4e00\u4e2a\u53c2\u6570\uff1b $2 \u8f93\u51fa\u7b2c\u4e8c\u4e2a\u53c2\u6570\uff1b $# \u8f93\u51fa\u53c2\u6570\u4e2a\u6570\u3002 ${} ${} \u7528\u4e8e\u533a\u5206\u53d8\u91cf\u7684\u8fb9\u754c\u3002 \u4e0b\u9762\u4f8b\u5b50\u4e2d\uff0c $abc \u65e0\u7ed3\u679c\u8f93\u51fa\uff0c ${a}bc \u8f93\u51fa\u7ed3\u679c stringbc \uff0c\u901a\u8fc7{}\u6307\u5b9a\u4e86\u67d0\u4e2a\u5b57\u7b26\u5c5e\u4e8e\u53d8\u91cf\u3002 a = \"string\" echo ${ a } bc echo $abc ${#} ${#} \u662f\u8fd4\u56de\u53d8\u91cf\u503c\u7684\u957f\u5ea6\u3002 s = 'this is a string' echo \" $s \" echo \" ${# s } \" \u547d\u4ee4 echo \"${#s}\" \u8f93\u51fa\u7ed3\u679c\u662f\u5b57\u4e32 this is a string \u7684\u957f\u5ea6 16 \u3002 $? $? \u662f\u8fd4\u56de\u4e0a\u4e00\u547d\u4ee4\u662f\u5426\u6210\u529f\u7684\u72b6\u6001\uff0c 0 \u4ee3\u8868\u6210\u529f\uff0c\u975e\u96f6\u4ee3\u8868\u5931\u8d25\u3002 ls \u662f\u4e00\u4e2a\u547d\u4ee4\uff0c\u6240\u4ee5\u8fd4\u56de\u503c\u662f 0 \u3002 tom \u662f\u4e00\u4e2a\u4e0d\u5b58\u5728\u7684\u547d\u4ee4\uff0c\u5219\u8fd4\u56de 127 \u3002 ls echo $? tom echo $? $() $() \u7b49\u540c\u4e8e\u53cd\u5f15\u53f7\u3002 echo $(ls) \u7b49\u540c\u4e8e\u6267\u884c ls \u547d\u4ee4\u3002 $() \u7684\u5f0a\u7aef\u662f\uff0c\u4e0d\u662f\u6240\u6709\u7684\u7c7bunix\u7cfb\u7edf\u90fd\u652f\u6301\uff0c\u53cd\u5f15\u53f7\u662f\u80af\u5b9a\u652f\u6301\u7684\u3002 $() \u7684\u4f18\u52bf\u662f\u76f4\u89c2\uff0c\u5728\u8f6c\u79fb\u5904\u7406\u65f6\uff0c\u6bd4\u53cd\u5f15\u53f7\u76f4\u89c2\u5bb9\u6613\u4e9b\u3002 echo $( ls ) # test.sh echo $( cat $( ls )) # echo $0 $1 $2 $# \u4e0a\u8ff0\u5d4c\u5957\u683c\u5f0f\u4e2d\uff0cls\u547d\u4ee4\u7684\u8f93\u51fa\uff0c\u662fcat\u547d\u4ee4\u7684\u8f93\u5165\uff0c\u53ef\u4ee5\u8fdb\u884c\u591a\u5c42\u5d4c\u5957\uff0c\u5185\u5c42\u547d\u4ee4\u7684\u8f93\u51fa\u662f\u5916\u5c42\u547d\u4ee4\u7684\u8f93\u5165\u3002 $[] $[] \u662f\u8868\u8fbe\u5f0f\u8ba1\u7b97\u3002 echo $ [ 3 + 2 ] $- $- \u663e\u793ashell\u5f53\u524d\u6240\u4f7f\u7528\u7684\u9009\u9879\u3002 \u6267\u884c echo $- \uff0c\u8f93\u51fa\u7ed3\u679c himBHs \u3002himBH\u6bcf\u4e00\u4e2a\u5b57\u7b26\u662f\u4e00\u4e2ashell\u7684\u9009\u9879\u3002 $! $! \u83b7\u53d6\u6700\u540e\u4e00\u4e2a\u8fd0\u884c\u7684\u540e\u53f0\u8fdb\u7a0b\u7684pid\u3002 \u6bd4\u5982\u6267\u884c cat test.sh & \uff0c\u7ed3\u679c\u4e2d\u4f1a\u5305\u542b\u4e00\u4e2apid\u53f7\uff0c\u9a6c\u4e0a\u7740\u6267\u884c echo $! \uff0c\u5982\u679c2\u4e2a\u547d\u4ee4\u95f4\u9694\u4e4b\u95f4\u6ca1\u6709\u5176\u4ed6\u540e\u53f0\u8fdb\u7a0b\u6267\u884c\uff0c\u5219\u53ef\u4ee5\u5f97\u5230\u548c\u524d\u9762\u4e00\u81f4\u7684pid\u53f7\u3002 !$ !$ \u8fd4\u56de\u4e0a\u4e00\u6761\u547d\u4ee4\u7684\u6700\u540e\u4e00\u4e2a\u53c2\u6570\u3002 \u6267\u884c ./test.sh a b c iamhere \uff0c\u5f97\u5230\u7ed3\u679c ./test.sh a b 4 \u3002 \u6267\u884c echo !$ \uff0c\u5f97\u52302\u4e2a\u7ed3\u679c\uff0c echo iamhere \u548c iamhere \u3002 !! !! \u8f93\u51fa\u4e0a\u4e00\u6761\u547d\u4ee4\uff0c\u5e76\u6267\u884c\u3002 !! \u4f1a\u5148\u8f93\u51fa\u4e0a\u4e00\u6761\u547d\u4ee4 cat test.sh \uff0c\u7136\u540e\u518d\u6267\u884c\u8fd9\u6761\u547d\u4ee4\uff0c\u7b2c\u4e8c\u884c\u5373\u6267\u884c\u7ed3\u679c\u3002 [ vagrant@lizard:~ ] $ cat test.sh echo $0 $1 $2 $# [ vagrant@lizard:~ ] $ !! cat test.sh echo $0 $1 $2 $# $$ $$ \u8f93\u51fa\u5f53\u524d\u8fdb\u7a0b\u7684pid\u3002 echo $$ $@ & $* $@ \u548c $* \u662f\u5bf9\u4f20\u5165\u53c2\u6570\u7684\u4e0d\u540c\u4f53\u73b0\uff0c $@ \u662f\u4ee5\u53d8\u91cf\u5f62\u5f0f\u5f15\u7528\u4f20\u5165\u53c2\u6570\uff0c $* \u662f\u4ee5\u6570\u7ec4\u7684\u5f62\u5f0f\u5f15\u7528\u4f20\u5165\u53c2\u6570\u3002 \u521b\u5efa\u4e00\u4e2a\u6587\u4ef6 script.sh \u5305\u542b\u4e0b\u9762\u7684\u811a\u672c\u3002\u5e76\u6dfb\u52a0\u6267\u884c\u6743\u9650 chmod 755 script.sh \u3002 echo '$@\u4ee5\u53d8\u91cf\u65b9\u5f0f\u5f15\u7528\u4f20\u5165\u53c2\u6570\uff1a' for x in \" $@ \" do echo $x done echo '$*\u4ee5\u6570\u7ec4\u7684\u5f62\u5f0f\u5f15\u7528\u4f20\u5165\u53c2\u6570\uff1a' for x in \" $* \" do echo $x done \u8f93\u51fa\u7ed3\u679c\uff1a $@ \u4ee5\u53d8\u91cf\u65b9\u5f0f\u5f15\u7528\u4f20\u5165\u53c2\u6570\uff1a a b 3 5 d $* \u4ee5\u6570\u7ec4\u7684\u5f62\u5f0f\u5f15\u7528\u4f20\u5165\u53c2\u6570\uff1a a b 3 5 d","title":"3.17.\u7b26\u53f7$\u7528\u6cd5"},{"location":"linux/SRE/02-filesystem/","text":"\u7b2c\u4e8c\u7ae0 \u6587\u4ef6\u7cfb\u7edf \u00b6 \u6587\u4ef6\u7cfb\u7edf\u5c42\u6b21\u6807\u51c6\uff08Filesystem Hierarchy Standard, FHS\uff09\uff0c\u5b83\u662fLinux \u6807\u51c6\u5e93\uff08Linux Standards Base, LSB\uff09\u89c4\u8303\u7684\u4e00\u90e8\u5206\u3002 \u6839\u76ee\u5f55 / \u6307\u6587\u4ef6\u7cfb\u7edf\u6811\u7684\u6700\u9ad8\u5c42\u3002 \u6839\u5206\u533a\u5728\u7cfb\u7edf\u542f\u52a8\u65f6\u9996\u5148\u6302\u8f7d\u3002 \u7cfb\u7edf\u542f\u52a8\u65f6\u8fd0\u884c\u7684\u6240\u6709\u7a0b\u5e8f\u90fd\u5fc5\u987b\u5728\u6b64\u5206\u533a\u4e2d\u3002 1.\u4e3b\u8981\u76ee\u5f55 \u00b6 \u4ee5\u4e0b\u76ee\u5f55\u5fc5\u987b\u5728\u6839\u5206\u533a\u4e2d\uff1a /bin - \u7528\u6237\u57fa\u672c\u7a0b\u5e8f\u3002 \u5305\u542b\u672a\u6302\u8f7d\u5176\u4ed6\u6587\u4ef6\u7cfb\u7edf\u65f6\u6240\u9700\u7684\u53ef\u6267\u884c\u6587\u4ef6\u3002 \u4f8b\u5982\uff0c\u7cfb\u7edf\u542f\u52a8\u3001\u5904\u7406\u6587\u4ef6\u548c\u914d\u7f6e\u6240\u9700\u7684\u7a0b\u5e8f\u3002 \u4e0d\u80fd\u5173\u8054\u5230\u72ec\u7acb\u5206\u533a\uff0c\u64cd\u4f5c\u7cfb\u7edf\u542f\u52a8\u5373\u4f1a\u8c03\u7528\u7684\u7a0b\u5e8f\u3002 /bin/bash - bash \u811a\u672c\u5904\u7406 /bin/cat - \u663e\u793a\u6587\u4ef6\u5185\u5bb9 /bin/cp - \u62f7\u8d1d\u6587\u4ef6 /bin/dd - \u62f7\u8d1d\u6587\u4ef6\uff08\u57fa\u4e8e\u5b57\u8282byte\uff09 /bin/gzip - \u538b\u7f29\u6587\u4ef6 /bin/mount - \u6302\u8f7d\u6587\u4ef6\u7cfb\u7edf /bin/rm - \u5220\u9664\u6587\u4ef6 /bin/vi - \u6587\u4ef6\u7f16\u8f91 /sbin - \u7cfb\u7edf\u57fa\u672c\u7a0b\u5e8f\u3002 \u5305\u542b\u57fa\u672c\u7cfb\u7edf\u7ba1\u7406\u7684\u7a0b\u5e8f\u3002 \u9ed8\u8ba4\u662froot\u7528\u6237\u6709\u6743\u9650\u6267\u884c\uff0c\u56e0\u6b64\u5b83\u4e0d\u5728\u5e38\u89c4\u7528\u6237\u8def\u5f84\u4e2d\u3002 \u4e0d\u80fd\u5173\u8054\u5230\u72ec\u7acb\u5206\u533a\uff0c\u64cd\u4f5c\u7cfb\u7edf\u542f\u52a8\u5373\u4f1a\u8c03\u7528\u7684\u7a0b\u5e8f \u4e00\u4e9b\u91cd\u8981\u7ba1\u7406\u7a0b\u5e8f\uff1a /sbin/fdisk* - \u7ba1\u7406\u786c\u76d8\u5206\u533a /sbin/fsck* - \u6587\u4ef6\u7cfb\u7edf\u68c0\u67e5\u3002\u4e0d\u80fd\u5728\u8fd0\u884c\u7684\u7cfb\u7edf\u4e0a\u9762\u76f4\u63a5\u6267\u884c fsck \uff0c\u635f\u574f\u6839\u6587\u4ef6\u7cfb\u7edf\uff0c\u6267\u884c\u524d\u9700\u8981 umount \u3002 /sbin/mkfs - \u521b\u5efa\u6587\u4ef6\u7cfb\u7edf /sbin/shutdown - \u5173\u95ed\u7cfb\u7edf /dev - \u8bbe\u5907\u6587\u4ef6 \u4ee5\u592a\u7f51\u5361\u662f\u5185\u6838\u6a21\u5757\uff0c\u5176\u4ed6\u786c\u4ef6\u90fd\u4ee5\u8bbe\u5907dev\u7684\u65b9\u5f0f\u5c55\u73b0\u3002 \u5e94\u7528\u7a0b\u5e8f\u8bfb\u53d6\u548c\u5199\u5165\u8fd9\u4e9b\u6587\u4ef6\u4ee5\u64cd\u4f5c\u4f7f\u7528\u786c\u4ef6\u7ec4\u4ef6\u3002 \u4e24\u79cd\u7c7b\u578b\u8bbe\u5907\u6587\u4ef6\uff1a \u5b57\u7b26\u8bbe\u5907\uff08Character-oriented\uff09\u2013 \u5e8f\u5217\u8bbe\u5907\uff08\u6253\u5370\u673a\uff0c\u78c1\u5e26\u673a\uff0c\u9f20\u6807\u7b49\uff09 \u5757\u8bbe\u5907\uff08Block-oriented\uff09\u2013 \u786c\u76d8\uff0cDVD\u7b49 \u4e0e\u8bbe\u5907\u9a71\u52a8\u7a0b\u5e8f\u7684\u8fde\u63a5\u901a\u8fc7\u5185\u6838\u4e2d\u79f0\u4e3a\u4e3b\u8bbe\u5907\u53f7\u7684\u901a\u9053\u5b9e\u73b0\u3002 \u8fc7\u53bb\uff0c\u8fd9\u4e9b\u6587\u4ef6\u662f\u4f7f\u7528 mknod \u547d\u4ee4\u624b\u52a8\u521b\u5efa\u7684\u3002 \u73b0\u5728\u5f53\u5185\u6838\u53d1\u73b0\u8bbe\u5907\u65f6\uff0c\u5b83\u4eec\u4f1a\u7531 udev \u81ea\u52a8\u521b\u5efa\u3002 \u4e00\u4e9b\u91cd\u8981\u7684\u8bbe\u5907\u6587\u4ef6\uff1a Null\u8bbe\u5907: - /dev/null Zero\u8bbe\u5907: - /dev/zero \u7cfb\u7edf\u7ec8\u7aef: - /dev/console \u865a\u62df\u7ec8\u7aef: - /dev/tty1 \u4e32\u884c\u7aef\u53e3 - /dev/ttyS0 \u5e76\u884c\u7aef\u53e3: - /dev/lp0 \u8f6f\u76d8\u9a71\u52a8\u5668: - /dev/fd0 \u786c\u76d8\u9a71\u52a8\u5668: - /dev/sda \u786c\u76d8\u5206\u533a: - /dev/sda1 CD-ROM\u9a71\u52a8\u5668: - /dev/scd0 /etc - \u914d\u7f6e\u6587\u4ef6 \u5b58\u653e\u7cfb\u7edf\u548c\u670d\u52a1\u7684\u914d\u7f6e\u6587\u4ef6\u3002 \u5927\u90e8\u5206\u90fd\u662fASCII\u6587\u4ef6 \u666e\u901a\u7528\u6237\u53ef\u4ee5\u9ed8\u8ba4\u8bfb\u53d6\u5176\u4e2d\u7684\u5927\u90e8\u5206\u5185\u5bb9\u3002 \u8fd9\u4f1a\u5e26\u6765\u4e00\u4e2a\u6f5c\u5728\u7684\u5168\u95ee\u9898\uff0c\u56e0\u4e3a\u5176\u4e2d\u4e00\u4e9b\u6587\u4ef6\u5305\u542b\u5bc6\u7801\uff0c\u56e0\u6b64\u91cd\u8981\u7684\u662f\u8981\u786e\u4fdd\u8fd9\u4e9b\u6587\u4ef6\u53ea\u80fd\u7531root\u7528\u6237\u8bfb\u53d6\u3002 \u6839\u636eFHS\u6807\u51c6\uff0c\u6b64\u5904\u4e0d\u80fd\u653e\u7f6e\u4efb\u4f55\u53ef\u6267\u884c\u6587\u4ef6\uff0c\u4f46\u5b50\u76ee\u5f55\u53ef\u80fd\u5305\u542bshell\u811a\u672c\u3002 \u51e0\u4e4e\u6bcf\u4e2a\u5df2\u5b89\u88c5\u7684\u670d\u52a1\u5728 /etc \u6216\u5176\u5b50\u76ee\u5f55\u4e2d\u81f3\u5c11\u6709\u4e00\u4e2a\u914d\u7f6e\u6587\u4ef6\u3002 \u4e00\u4e9b\u91cd\u8981\u7684\u914d\u7f6e\u6587\u4ef6: /etc/os-release - \u7cfb\u7edf\u7248\u672c\u4fe1\u606f /etc/DIR_COLORS - ls \u547d\u4ee4\u4e2d\u7684\u989c\u8272\u914d\u7f6e\u4fe1\u606f\uff08openSUSE\u548cRocky\uff09 /etc/fstab - \u914d\u7f6e\u8981\u6302\u8f7d\u7684\u6587\u4ef6\u7cfb\u7edf /etc/profile - Shell\u767b\u5f55\u811a\u672c /etc/passwd - \u7528\u6237\u4fe1\u606f\u96c6\u5408\uff08\u4e0d\u542b\u5bc6\u7801\uff09 /etc/shadow - \u5bc6\u7801\u548c\u76f8\u5173\u4fe1\u606f /etc/group - \u7528\u6237\u7ec4\u4fe1\u606f\u96c6\u5408 /etc/cups/* - \u7528\u4e8eCUPS\u6253\u5370\u7cfb\u7edf\uff08CUPS=Common UNIX Printing System\uff09 /etc/hosts - \u4e3b\u673a\u540d\u673a\u5668IP\u5730\u5740 /etc/motd - \u767b\u5f55\u540e\u663e\u793a\u7684\u6b22\u8fce\u4fe1\u606f /etc/issue - \u767b\u5f55\u524d\u663e\u793a\u7684\u6b22\u8fce\u4fe1\u606f /etc/sysconfig/* - \u7cfb\u7edf\u914d\u7f6e\u6587\u4ef6 /lib - \u5e93\uff08Libraries\uff09 \u8bb8\u591a\u7a0b\u5e8f\u90fd\u5177\u6709\u4e00\u4e9b\u901a\u7528\u529f\u80fd\u3002 \u8fd9\u4e9b\u901a\u7528\u529f\u80fd\u53ef\u4ee5\u4fdd\u5b58\u5728\u5171\u4eab\u5e93\u4e2d\u3002 \u5171\u4eab\u5e93\u4e2d\u6587\u4ef6\u7684\u6269\u5c55\u540d\u662f .so \u3002 \u76ee\u5f55 /lib \u5305\u542b\u7684\u5171\u4eab\u5e93\u6587\u4ef6\u4e3b\u8981\u662f\u88ab /bin \u548c /sbin \u76ee\u5f55\u5305\u542b\u7684\u7a0b\u5e8f\u6240\u8c03\u7528\u3002 \u76ee\u5f55 /lib \u7684\u5b50\u76ee\u5f55\u5305\u542b\u4e00\u4e9b\u989d\u5916\u9700\u8981\u7684\u5171\u4eab\u5e93\u3002 \u5185\u6838\u6a21\u5757\u5b58\u50a8\u5728\u76ee\u5f55 /lib/modules \u3002 /lib64 - 64\u4f4d\u5171\u4eab\u5e93\uff0864-Bit Libraries\uff09\uff0c\u7c7b\u4f3c\u76ee\u5f55 /lib \u3002 \u8fd9\u4e2a\u76ee\u5f55\u56e0\u7cfb\u7edf\u67b6\u6784\u4e0d\u540c\u800c\u4e0d\u540c\u3002 \u4e00\u4e9b\u7cfb\u7edf\u652f\u6301\u4e0d\u540c\u7684\u4e8c\u8fdb\u5236\u683c\u5f0f\u5e76\u4fdd\u7559\u540c\u4e00\u4e2a\u5171\u4eab\u5e93\u7684\u4e0d\u540c\u7248\u672c\u3002 /usr - \u5305\u542b\u5e94\u7528\u7a0b\u5e8f\u3001\u56fe\u5f62\u754c\u9762\u6587\u4ef6\u3001\u5e93\u3001\u672c\u5730\u7a0b\u5e8f\u3001\u6587\u6863\u7b49\u3002 /usr \u5373 Unix System Resources. \u4f8b\u5982\uff1a /usr/X11R6/ - X Window \u7cfb\u7edf\u6587\u4ef6 /usr/bin/ - \u51e0\u4e4e\u5305\u542b\u6240\u6709\u53ef\u6267\u884c\u6587\u4ef6 /usr/lib/ - \u5305\u542b\u5e93\u548c\u5e94\u7528\u7a0b\u5e8f /usr/lib64/ - \u5305\u542b64\u4f4d\u5e93\u548c\u5e94\u7528\u7a0b\u5e8f /usr/include/ - \u5305\u542bC\u7a0b\u5e8f\u7684\u5934\u6587\u4ef6\uff08head file\uff09 /usr/local/ - \u5305\u542b\u672c\u5730\u5b89\u88c5\u7a0b\u5e8f\u3002\u8fd9\u4e2a\u76ee\u5f55\u4e0b\u7684\u5185\u5bb9\u4e0d\u4f1a\u88ab\u7cfb\u7edf\u5347\u7ea7\u6240\u8986\u76d6\u3002\u4e0b\u97623\u4e2a\u76ee\u5f55\u5728\u521d\u59cb\u5b89\u88c5\u540e\u662f\u7a7a\u7684\u3002 /usr/local/bin - /usr/local/sbin - /usr/local/lib - /usr/sbin/ - \u7cfb\u7edf\u7ba1\u7406\u7a0b\u5e8f /usr/src/ - \u5185\u6838\u548c\u5e94\u7528\u7a0b\u5e8f\u7684\u6e90\u4ee3\u7801 /usr/src/linux - /usr/share/ - \u7ed3\u6784\u5316\u72ec\u7acb\u6570\u636e /usr/share/doc/ - \u6587\u6863 /usr/share/man/ - man \u547d\u4ee4\u4f7f\u7528\u7684\u5185\u5bb9 /opt - \u7b2c\u4e09\u65b9\u5e94\u7528\u7a0b\u5e8f\u76ee\u5f55 \u5404\u53d1\u884c\u7248\u5305\u542b\u7684\u5e94\u7528\u7a0b\u5e8f\u4e00\u822c\u5b58\u50a8\u5728\u76ee\u5f55 /usr/lib/ \u3002 \u5404\u53d1\u884c\u7248\u53ef\u9009\u7a0b\u5e8f\uff0c\u6216\u7b2c\u4e09\u65b9\u5e94\u7528\u7a0b\u5e8f\u5219\u5b58\u50a8\u5728\u76ee\u5f55 /opt \u3002 \u5728\u5b89\u88c5\u65f6\uff0c\u4f1a\u4e3a\u6bcf\u4e2a\u5e94\u7528\u7a0b\u5e8f\u7684\u6587\u4ef6\u521b\u5efa\u4e00\u4e2a\u76ee\u5f55\uff0c\u5176\u4e2d\u5305\u542b\u5e94\u7528\u7a0b\u5e8f\u7684\u540d\u79f0\u3002\u6bd4\u5982\uff1a /opt/novell - /boot - \u5f15\u5bfc\u76ee\u5f55 /boot/grub2 - \u5305\u542bGRUB2\u7684\u9759\u6001\u5f15\u5bfc\u52a0\u8f7d\u7a0b\u5e8f\u6587\u4ef6\uff08GRUB = Grand Unified Boot Loader\uff09\u3002 \u5305\u542b\u4ee5\u94fe\u63a5 vmlinuz \u548c initrd \u6807\u8bc6\u7684\u5185\u6838\u548c initrd \u6587\u4ef6\u3002 /root - \u7ba1\u7406\u5458\u7684\u4e3b\u76ee\u5f55\uff08home directory\uff09\u3002 root \u7528\u6237\u7684\u4e3b\u76ee\u5f55\u3002\u5176\u4ed6\u7528\u6237\u7684\u4e3b\u76ee\u5f55\u662f\u5728\u76ee\u5f55 /home \u4e0b\u3002 root \u7528\u6237\u7684\u767b\u5f55\u73af\u5883\u914d\u7f6e\u4fdd\u5b58\u81f3 /root \u5206\u533a\u4e2d\u3002 /home - \u7528\u6237\u4e3b\u76ee\u5f55 \u6bcf\u4e2a\u7cfb\u7edf\u7528\u6237\u90fd\u6709\u4e00\u4e2a\u5206\u914d\u7684\u6587\u4ef6\u533a\u57df\uff0c\u8be5\u6587\u4ef6\u533a\u57df\u5728\u767b\u5f55\u540e\u6210\u4e3a\u5f53\u524d\u5de5\u4f5c\u76ee\u5f55\u3002 \u9ed8\u8ba4\u60c5\u51b5\u4e0b\uff0c\u5b83\u4eec\u5b58\u5728\u4e8e /home \u4e2d\u3002 /home \u4e2d\u7684\u6587\u4ef6\u548c\u76ee\u5f55\u53ef\u4ee5\u4f4d\u4e8e\u5355\u72ec\u7684\u5206\u533a\u4e2d\uff0c\u4e5f\u53ef\u4ee5\u4f4d\u4e8e\u7f51\u7edc\u4e0a\u7684\u53e6\u4e00\u53f0\u8ba1\u7b97\u673a\u4e0a\u3002 \u7528\u6237\u914d\u7f6e\u4fe1\u606f\u548c\u914d\u7f6e\u6587\u4ef6\uff08user profile and configuration files\uff09\u4e3b\u8981\u6709\uff1a .profile - \u7528\u6237\u79c1\u6709\u767b\u5f55\u811a\u672c .bashrc - bash \u7684\u914d\u7f6e\u6587\u4ef6 .bash_history - bash \u73af\u5883\u4e0b\u4fdd\u6301\u547d\u4ee4\u5386\u53f2\u8bb0\u5f55 run - \u5e94\u7528\u7a0b\u5e8f\u72b6\u6001\u6587\u4ef6 \u4e3a\u5e94\u7528\u7a0b\u5e8f\u63d0\u4f9b\u4e86\u4e00\u4e2a\u6807\u51c6\u4f4d\u7f6e\u6765\u5b58\u50a8\u5b83\u4eec\u9700\u8981\u7684\u4e34\u65f6\u6587\u4ef6\uff0c\u4f8b\u5982\u5957\u63a5\u5b57\u548c\u8fdb\u7a0bID\u3002 \u8fd9\u4e9b\u6587\u4ef6\u4e0d\u80fd\u5b58\u50a8\u5728 /tmp \u4e2d\uff0c\u56e0\u4e3a /tmp \u4e2d\u7684\u6587\u4ef6\u53ef\u80fd\u4f1a\u88ab\u5220\u9664\u3002 /run/media//* - \u53ef\u79fb\u52a8\u8bbe\u5907\u7684\u6302\u8f7d\u70b9\uff0c\u4f8b\u5982\uff1a /run/media/media_name/ /run/media/cdrom/ - /run/media/dvd/ - /run/media/usbdisk/ - /mnt - \u6587\u4ef6\u7cfb\u7edf\u4e34\u65f6\u6302\u8f7d\u70b9 \u7528\u4e8e\u6302\u8f7d\u4e34\u65f6\u4f7f\u7528\u7684\u6587\u4ef6\u7cfb\u7edf\u7684\u76ee\u5f55\u3002 \u6587\u4ef6\u7cfb\u7edf\u4f7f\u7528 mount \u547d\u4ee4\u6302\u8f7d\uff0c\u4f7f\u7528 umount \u547d\u4ee4\u5220\u9664\u3002 \u5b50\u76ee\u5f55\u9ed8\u8ba4\u4e0d\u5b58\u5728\uff0c\u4e5f\u4e0d\u4f1a\u81ea\u52a8\u521b\u5efa\u3002 /srv - \u670d\u52a1\u6570\u636e\u76ee\u5f55 \u5b58\u653e\u5404\u79cd\u670d\u52a1\u7684\u6570\u636e\uff0c\u6bd4\u5982\uff1a /srv/www - \u7528\u4e8e\u5b58\u653e Apache Web Server \u7684\u6570\u636e /srv/ftp - \u7528\u4e8e\u5b58\u653e FTP server \u7684\u6570\u636e /var - \u53ef\u53d8\u6587\u4ef6\uff08Variable Files\uff09 \u5728\u7cfb\u7edf\u8fd0\u884c\u8fc7\u7a0b\u4e2d\u4f1a\u88ab\u4fee\u6539\u7684\u6587\u4ef6 Important subdirectories: /var/lib/ - \u53ef\u53d8\u5e93\u6587\u4ef6\uff0c\u5e94\u7528\u7a0b\u5e8f\u72b6\u6001\u4fe1\u606f\u6570\u636e /var/log/ - \u65e5\u5fd7\u6587\u4ef6 /var/run/ - \u8fd0\u884c\u4e2d\u7684\u8fdb\u7a0b\u7684\u4fe1\u606f /var/lock/ - \u591a\u7528\u6237\u8bbf\u95ee\u65f6\u7684\u9501\u6587\u4ef6 /var/cache - \u5e94\u7528\u7a0b\u5e8f\u7f13\u5b58\u6570\u636e\u76ee\u5f55 /var/opt - \u4e13\u4e3a /opt \u4e0b\u7684\u5e94\u7528\u7a0b\u5e8f\u5b58\u50a8\u53ef\u53d8\u6570\u636e /var/mail - /var/spool/ - \u5e94\u7528\u7a0b\u5e8f\u6570\u636e\u6c60\uff0c\u6bd4\u5982\uff1a\u6253\u5370\u673a\uff0c\u90ae\u4ef6 /var/spool/mail - /var/spool/cron - /tmp - \u4e34\u65f6\u6587\u4ef6 \u7a0b\u5e8f\u5728\u8fd0\u884c\u65f6\u521b\u5efa\u4e34\u65f6\u6587\u4ef6\u7684\u4f4d\u7f6e /proc - \u8fdb\u7a0b\u6587\u4ef6 \u865a\u62df\u6587\u4ef6\u7cfb\u7edf\uff0c\u4e0d\u5360\u7a7a\u95f4\uff0c\u5927\u5c0f\u59cb\u7ec8\u4e3a\u96f6\uff0c\u4fdd\u6301\u5f53\u524d\u8fdb\u7a0b\u7684\u72b6\u6001\u4fe1\u606f \u5305\u542b\u6709\u5173\u5404\u4e2a\u8fdb\u7a0b\u7684\u4fe1\u606f\u7684\u76ee\u5f55\uff0c\u6839\u636e\u8fdb\u7a0b\u7684 PID \u53f7\u547d\u540d \u6709\u4e9b\u503c\u53ef\u4ee5\u4e34\u65f6\u5728\u7ebf\u66f4\u6539\u751f\u6548\uff0c\u4f46\u91cd\u542f\u540e\u4e22\u5931 /proc/cpuinfo/ - Processor information /proc/dma/ - Use of DMA ports /proc/interrupts/ - Use of interrupts /proc/ioports/ - Use of I/O ports /proc/filesystems/ - File system formats the kernel knows /proc/modules/ - Active modules /proc/mounts/ - Mounted file systems /proc/net/* - Network information and statistics /proc/partitions/ - Existing partitions /proc/bus/pci/ - Connected PCI devices /proc/bus/scsi/ - Connected SCSI devices /proc/sys/* - System and kernel information /proc/version - Kernel version /sys - \u7cfb\u7edf\u4fe1\u606f\u76ee\u5f55 \u865a\u62df\u6587\u4ef6\u7cfb\u7edf\uff0c\u4ec5\u5b58\u5728\u4e8e\u5185\u5b58\u4e2d\uff0c\u6587\u4ef6\u5927\u5c0f\u4e3a\u96f6\u3002\u4e3b\u8981\u63d0\u4f9b\u5982\u4e0b\u4fe1\u606f\uff1a \u786c\u4ef6\u603b\u7ebf\uff08hardware buses\uff09 \u786c\u4ef6\u8bbe\u5907\uff08hardware devices\uff09 \u6709\u6e90\u8bbe\u5907\uff08active devices\uff09 \u9a71\u52a8\u7a0b\u5e8f\uff08drivers\uff09 2.\u6587\u4ef6\u64cd\u4f5c\u547d\u4ee4 \u00b6 2.1.\u663e\u793a\u5f53\u524d\u5de5\u4f5c\u76ee\u5f55 \u00b6 pwd\u547d\u4ee4\uff08print working directory\uff09: -L: \u663e\u793a\u94fe\u63a5\u8def\u5f84 -P\uff1a\u663e\u793a\u771f\u5b9e\u7269\u7406\u8def\u5f84 2.2.\u76f8\u5bf9\u548c\u7edd\u5bf9\u8def\u5f84 \u00b6 \u5bf9\u4e8e\u7edd\u5bf9\u8def\u5f84 /etc/firewalld/policies \uff0c\u53ef\u4ee5\u901a\u8fc7\u4e0b\u9762\u547d\u4ee4\u5f97\u5230\u8be5\u8def\u5f84\u7684\u57fa\u540d policies \u548c\u76ee\u5f55\u540d /etc/firewalld \u3002 basename /etc/firewalld/policies dirname /etc/firewalld/policies 2.3.\u66f4\u6539\u76ee\u5f55 \u00b6 . \u6307\u5f53\u524d\u76ee\u5f55\uff0c\u5373 pwd \u547d\u4ee4\u6240\u8fd4\u56de\u7684\u76ee\u5f55\u3002 .. \u6307\u5f53\u524d\u76ee\u5f55\u7684\u4e0a\u4e00\u7ea7\u76ee\u5f55\uff0c\u53ca\u5f53\u524d\u76ee\u5f55\u7684\u7236\u76ee\u5f55\u3002 \u5207\u6362\u81f3\u7236\u76ee\u5f55\uff1a cd .. \u5207\u6362\u81f3\u5f53\u524d\u7528\u6237\u4e3b\u76ee\u5f55\uff1a cd ~ \u5207\u6362\u81f3\u4e0a\u6b21\u5de5\u4f5c\u76ee\u5f55\uff1a cd - echo $PWD \uff1a\u5f53\u524d\u5de5\u4f5c\u76ee\u5f55 echo $OLDPWD \uff1a\u4e0a\u6b21\u5de5\u4f5c\u76ee\u5f55 2.4.\u5217\u51fa\u76ee\u5f55\u5185\u5bb9 \u00b6 ls \u547d\u4ee4\uff1a -a \u663e\u793a\u6240\u6709\u6587\u4ef6\u53ca\u76ee\u5f55 (. \u5f00\u5934\u7684\u9690\u85cf\u6587\u4ef6\u4e5f\u4f1a\u5217\u51fa) -A \u540c -a \uff0c\u4f46\u4e0d\u5217\u51fa . (\u76ee\u524d\u76ee\u5f55) \u53ca .. (\u7236\u76ee\u5f55) -l \u9664\u6587\u4ef6\u540d\u79f0\u5916\uff0c\u4ea6\u5c06\u6587\u4ef6\u578b\u6001\u3001\u6743\u9650\u3001\u62e5\u6709\u8005\u3001\u6587\u4ef6\u5927\u5c0f\u7b49\u8d44\u8baf\u8be6\u7ec6\u5217\u51fa -r \u5c06\u6587\u4ef6\u4ee5\u76f8\u53cd\u6b21\u5e8f\u663e\u793a(\u539f\u5b9a\u4f9d\u82f1\u6587\u5b57\u6bcd\u6b21\u5e8f) -t \u5c06\u6587\u4ef6\u4f9d\u5efa\u7acb\u65f6\u95f4\u4e4b\u5148\u540e\u6b21\u5e8f\u5217\u51fa -F \u5728\u5217\u51fa\u7684\u6587\u4ef6\u540d\u79f0\u540e\u52a0\u4e00\u7b26\u53f7\uff1b\u4f8b\u5982\u53ef\u6267\u884c\u6863\u5219\u52a0 \"*\", \u76ee\u5f55\u5219\u52a0 \"/\" -R \u9012\u5f52\u5217\u51fa\u5b50\u76ee\u5f55 -S \u6309\u6587\u4ef6\u5927\u5c0f\u6392\u5e8f\uff0c\u4ece\u5927\u5230\u5c0f -1 \u6309\u4e00\u4e2a\u6587\u4ef6\u4e00\u884c\u5217\u51fa -t \u6309\u6587\u4ef6\u65f6\u95f4\u6392\u5e8f\uff0c\u6700\u65b0\u7684\u5728\u524d -U \u4e0d\u6392\u5e8f\u8f93\u51fa\uff0c\u6309\u76ee\u5f55\u5b58\u653e\u987a\u5e8f\u5217\u51fa -u \u914d\u5408 -lt \uff0c\u6309\u8bbf\u95ee\u65f6\u95f4\u6392\u5e8f\u5e76\u663e\u793a\uff1b\u914d\u5408 -l \uff0c\u663e\u793a\u8bbf\u95ee\u65f6\u95f4\u5e76\u6309\u540d\u79f0\u6392\u5e8f\uff1b \u5426\u5219\u6309\u8bbf\u95ee\u65f6\u95f4\u6392\u5e8f\uff0c\u6700\u65b0\u7684\u5728\u524d -X \u6309\u6587\u4ef6\u6269\u5c55\u540d\u5b57\u6bcd\u987a\u5e8f\u6392\u5e8f\u8f93\u51fa -F \u5bf9\u4e0d\u540c\u7c7b\u578b\u6587\u4ef6\u663e\u793a\u65f6\u9644\u52a0\u4e0d\u540c\u7684\u7b26\u53f7\uff0c * / = > @ | \u4e4b\u4e00 ls \u547d\u4ee4\u67e5\u770b\u4e0d\u540c\u6587\u4ef6\u662f\u7684\u989c\u8272\uff0c\u7531 /etc/DIR_COLORS \u548c\u53d8\u91cf @LS_COLORS \u5b9a\u4e49\u3002 2.5.\u6587\u4ef6\u72b6\u6001stat \u00b6 \u6bcf\u4e2a\u6587\u4ef6\u6709\u4e09\u4e2a\u65f6\u95f4\u6233\uff1a \u8bbf\u95ee\u65f6\u95f4 Access Time atime : \u8bfb\u53d6\u6587\u4ef6\u5185\u5bb9\u3002 \u4fee\u6539\u65f6\u95f4 Modify Time mtime : \u6539\u53d8\u6587\u4ef6\u5185\u5bb9\uff08\u6570\u636e\uff09\u3002 \u6539\u53d8\u65f6\u95f4 Change Time ctime : \u5143\u6570\u636e\u53d1\u751f\u6539\u53d8\u3002 \u8bfb\u53d6\u4e09\u4e2a\u65f6\u95f4\u6233\u7684\u547d\u4ee4 stat \uff1a stat /etc/fstab \u8f93\u51fa\u7ed3\u679c\uff1a File: /etc/fstab Size: 927 Blocks: 8 IO Block: 4096 regular file Device: 30h/48d Inode: 263 Links: 1 Access: (0644/-rw-r--r--) Uid: ( 0/ root) Gid: ( 0/ root) Access: 2022-10-31 10:26:34.987466959 +0800 Modify: 2022-06-24 14:50:24.387992912 +0800 Change: 2022-06-24 14:50:24.387992912 +0800 Birth: 2022-06-24 14:50:23.755992937 +0800 2.6.\u786e\u5b9a\u6587\u4ef6\u7c7b\u578b \u00b6 \u547d\u4ee4 file \u68c0\u67e5\u6587\u4ef6\u7c7b\u578b\u3002 -b \uff1a\u5217\u51fa\u8fa8\u8bc6\u7ed3\u679c\u65f6\uff0c\u4e0d\u663e\u793a\u6587\u4ef6\u540d\u79f0\u3002 -c \uff1a\u8be6\u7ec6\u663e\u793a\u6307\u4ee4\u6267\u884c\u8fc7\u7a0b\uff0c\u4fbf\u4e8e\u6392\u9519\u6216\u5206\u6790\u7a0b\u5e8f\u6267\u884c\u7684\u60c5\u5f62\u3002 -f <\u540d\u79f0\u6587\u4ef6> \uff1a\u6307\u5b9a\u540d\u79f0\u6587\u4ef6\uff0c\u5176\u5185\u5bb9\u6709\u4e00\u4e2a\u6216\u591a\u4e2a\u6587\u4ef6\u540d\u79f0\u65f6\uff0c\u8ba9file\u4f9d\u5e8f\u8fa8\u8bc6\u8fd9\u4e9b\u6587\u4ef6\uff0c\u683c\u5f0f\u4e3a\u6bcf\u5217\u4e00\u4e2a\u6587\u4ef6\u540d\u79f0\u3002 -L \uff1a \u76f4\u63a5\u663e\u793a\u7b26\u53f7\u8fde\u63a5\u6240\u6307\u5411\u7684\u6587\u4ef6\u7684\u7c7b\u522b\u3002 -v \uff1a \u663e\u793a\u7248\u672c\u4fe1\u606f\u3002 -z \uff1a \u5c1d\u8bd5\u53bb\u89e3\u8bfb\u538b\u7f29\u6587\u4ef6\u7684\u5185\u5bb9\u3002 \u7f16\u8f91\u6587\u4ef6 list.txt \u5305\u542b\u4e00\u4e0b\u5185\u5bb9\uff1a /etc/ /bin /etc/issue \u8fd0\u884c\u547d\u4ee4 file -f list.txt \uff0c\u7ed3\u679c\u5982\u4e0b\uff1a /etc/: directory /bin: directory /etc/issue: symbolic link to ../run/issue 2.7.\u6587\u4ef6\u7f16\u7801\u8f6c\u6362 \u00b6 iconv \u547d\u4ee4\u7528\u4e8e\u5c06\u4e00\u79cd\u7f16\u7801\u4e2d\u7684\u67d0\u4e9b\u6587\u672c\u8f6c\u6362\u4e3a\u53e6\u4e00\u79cd\u7f16\u7801\u3002 \u5982\u679c\u6ca1\u6709\u63d0\u4f9b\u8f93\u5165\u6587\u4ef6\uff0c\u5219\u5b83\u4ece\u6807\u51c6\u8f93\u5165\u4e2d\u8bfb\u53d6\u3002 \u540c\u6837\uff0c\u5982\u679c\u6ca1\u6709\u7ed9\u51fa\u8f93\u51fa\u6587\u4ef6\uff0c\u90a3\u4e48\u5b83\u4f1a\u5199\u5165\u6807\u51c6\u8f93\u51fa\u3002 \u5982\u679c\u6ca1\u6709\u63d0\u4f9b from-encoding \u6216 to-encoding \uff0c\u5219\u5b83\u4f7f\u7528\u5f53\u524d\u672c\u5730\u7684\u5b57\u7b26\u7f16\u7801\u3002 \u5c06\u6587\u672c\u4ece ISO 8859-15 \u5b57\u7b26\u7f16\u7801\u8f6c\u6362\u4e3a UTF-8\uff0c\u8bfb\u5165 input.txt \uff0c\u8f93\u51fa output.txt \u3002 iconv -f ISO-8859-15 -t UTF-8 < input.txt > output.txt \u4ece UTF-8 \u8f6c\u6362\u4e3a ASCII\uff0c\u5c3d\u53ef\u80fd\u8fdb\u884c\u97f3\u8bd1\uff08transliterating\uff09\uff1a echo abc \u00df \u03b1 \u20ac \u00e0\u1e03\u00e7 | iconv -f UTF-8 -t ASCII//TRANSLIT \u8fd0\u884c\u7ed3\u679c\uff1a abc ss ? EUR abc 2.8.\u901a\u914d\u7b26 \u00b6 \u901a\u914d\u7b26\uff0c\u6307\u5305\u542b\u8fd9\u4e9b\u5b57\u7b26\u7684\u5b57\u7b26\u4e32 ? \uff1a\u8868\u793a\u4efb\u610f\u4e00\u4e2a\u5b57\u7b26 * \uff1a\u8868\u793a\u4efb\u610f\u957f\u5ea6\u7684\u4efb\u610f\u5b57\u7b26 [] \uff1a\u5339\u914d\u6307\u5b9a\u8303\u56f4\u5185\u4efb\u610f\u4e00\u4e2a\u5b57\u7b26 [abcd] \uff1a\u5339\u914dabcd\u4e2d\u7684\u4efb\u4f55\u4e00\u4e2a\u5b57\u7b26 [a-z] \uff1a\u5339\u914d\u8303\u56f4a\u5230z\u5185\u4efb\u610f\u4e00\u4e2a\u5b57\u7b26 [!abcd] \uff1a\u4e0d\u5339\u914d\u62ec\u53f7\u91cc\u9762\u4efb\u4f55\u4e00\u4e2a\u5b57\u7b26 {} \uff1a\u8868\u793a\u751f\u6210\u5e8f\u5217\uff0c\u4ee5\u9017\u53f7\u5206\u5272\uff0c\u4e0d\u80fd\u6709\u7a7a\u683c \u793a\u4f8b\uff1a $ touch file_ { a..z } .txt $ touch file_ { A..Z } .txt $ ls file_a.txt file_C.txt file_f.txt file_H.txt file_k.txt file_M.txt file_p.txt file_R.txt file_u.txt file_W.txt file_z.txt file_A.txt file_d.txt file_F.txt file_i.txt file_K.txt file_n.txt file_P.txt file_s.txt file_U.txt file_x.txt file_Z.txt file_b.txt file_D.txt file_g.txt file_I.txt file_l.txt file_N.txt file_q.txt file_S.txt file_v.txt file_X.txt file_B.txt file_e.txt file_G.txt file_j.txt file_L.txt file_o.txt file_Q.txt file_t.txt file_V.txt file_y.txt file_c.txt file_E.txt file_h.txt file_J.txt file_m.txt file_O.txt file_r.txt file_T.txt file_w.txt file_Y.txt $ ls file_ [ a..d ] .* file_a.txt file_d.txt $ ls file_ [ a...d ] .* file_a.txt file_d.txt $ ls file_ [ ad ] .* file_a.txt file_d.txt $ ls file_ [ a-c ] .* file_a.txt file_A.txt file_b.txt file_B.txt file_c.txt $ ls file_ [ a-C ] .* file_a.txt file_A.txt file_b.txt file_B.txt file_c.txt file_C.txt $ ls file_ [ !d-W ] .* file_a.txt file_b.txt file_c.txt file_x.txt file_y.txt file_z.txt file_A.txt file_B.txt file_C.txt file_X.txt file_Y.txt file_Z.txt \u6bd4\u8f83\u6709\u65e0 * \u7684\u533a\u522b\uff1a $ ls -a * file_a.txt file_D.txt file_h.txt file_K.txt file_o.txt file_R.txt file_v.txt file_Y.txt file_A.txt file_e.txt file_H.txt file_l.txt file_O.txt file_s.txt file_V.txt file_z.txt file_b.txt file_E.txt file_i.txt file_L.txt file_p.txt file_S.txt file_w.txt file_Z.txt file_B.txt file_f.txt file_I.txt file_m.txt file_P.txt file_t.txt file_W.txt file_c.txt file_F.txt file_j.txt file_M.txt file_q.txt file_T.txt file_x.txt file_C.txt file_g.txt file_J.txt file_n.txt file_Q.txt file_u.txt file_X.txt file_d.txt file_G.txt file_k.txt file_N.txt file_r.txt file_U.txt file_y.txt $ ls -a . file_C.txt file_g.txt file_J.txt file_n.txt file_Q.txt file_u.txt file_X.txt .. file_d.txt file_G.txt file_k.txt file_N.txt file_r.txt file_U.txt file_y.txt file_a.txt file_D.txt file_h.txt file_K.txt file_o.txt file_R.txt file_v.txt file_Y.txt file_A.txt file_e.txt file_H.txt file_l.txt file_O.txt file_s.txt file_V.txt file_z.txt file_b.txt file_E.txt file_i.txt file_L.txt file_p.txt file_S.txt file_w.txt file_Z.txt file_B.txt file_f.txt file_I.txt file_m.txt file_P.txt file_t.txt file_W.txt file_c.txt file_F.txt file_j.txt file_M.txt file_q.txt file_T.txt file_x.txt 2.9.\u5b57\u7b26\u96c6 \u00b6 [:alpha:] \uff1a\u8868\u793a\u6240\u6709\u7684\u5b57\u6bcd\uff08\u4e0d\u533a\u5206\u5927\u5c0f\u5199\uff09\uff0c\u6548\u679c\u540c [a-z] [:digit:] \uff1a\u8868\u793a\u4efb\u610f\u5355\u4e2a\u6570\u5b57\uff0c\u6548\u679c\u540c [0-9] [:xdigit:] \uff1a\u8868\u793a\u5341\u516d\u8fdb\u5236\u6570\u5b57 [:lower:] \uff1a\u8868\u793a\u4efb\u610f\u5355\u4e2a\u5c0f\u5199\u5b57\u6bcd [:upper:] \uff1a\u8868\u793a\u4efb\u610f\u5355\u4e2a\u5927\u5199\u5b57\u6bcd [:alnum:] \uff1a\u8868\u793a\u4efb\u610f\u5355\u4e2a\u5b57\u6bcd\u6216\u6570\u5b57 [:blank:] \uff1a\u8868\u793a\u7a7a\u767d\u5b57\u7b26\uff08\u7a7a\u683c\u548c\u5236\u8868\u7b26\uff09 [:space:] \uff1a\u8868\u793a\u5305\u62ec\u7a7a\u683c\u3001\u5236\u8868\u7b26\uff08\u6c34\u5e73\u548c\u5782\u76f4\uff09\u3001\u6362\u884c\u7b26\u3001\u56de\u8f66\u7b26\u7b49\u5404\u79cd\u7c7b\u578b\u7684\u7a7a\u767d\uff0c\u6bd4 [:blank:] \u8303\u56f4\u66f4\u5e7f [:cntrl:] \uff1a\u8868\u793a\u4e0d\u53ef\u6253\u5370\u7684\u63a7\u5236\u5b57\u7b26\uff08\u9000\u683c\u3001\u5220\u9664\u3001\u8b66\u94c3\u7b49\uff09 [:graph:] \uff1a\u8868\u793a\u53ef\u6253\u5370\u7684\u975e\u7a7a\u767d\u5b57\u7b26 [:print:] \uff1a\u8868\u793a\u53ef\u6253\u5370\u5b57\u7b26 [:punct:] \uff1a\u8868\u793a\u6807\u70b9\u7b26\u53f7 \u4e3e\u4f8b\uff1a ls -d [[:alpha:]] \u5373 ls -d [a-Z] \uff1a\u663e\u793a\u5f53\u524d\u76ee\u5f55\u4e0b\u6240\u6709\u5355\u4e2a\u5b57\u6bcd\u7684\u76ee\u5f55\u548c\u6587\u4ef6 ls -d *[[:digit:]] \u5373 ls -d *[0-9] \uff1a\u663e\u793a\u5f53\u524d\u76ee\u5f55\u4e0b\u6240\u6709\u4ee5\u6570\u5b57\u7ed3\u5c3e\u7684\u76ee\u5f55\u548c\u6587\u4ef6 ls [[:lower:]].txt \uff1a\u663e\u793a\u5f53\u524d\u76ee\u5f55\u4e0b\u6240\u6709\u4ee5\u5355\u4e2a\u5c0f\u5199\u5b57\u6bcd\u4e3a\u540d\u7684.txt\u683c\u5f0f\u7684\u6587\u4ef6 ls -d [[:alnum:]] \uff1a\u663e\u793a\u5f53\u524d\u76ee\u5f55\u4e0b\u6240\u6709\u5355\u4e2a\u5b57\u6bcd\uff08\u4e0d\u533a\u5206\u5927\u5c0f\u5199\uff09\u6216\u6570\u5b57\u4e3a\u540d\u7684\u76ee\u5f55\u6216\u6587\u4ef6 2.10.\u7279\u6b8a\u7b26\u53f7 \u00b6 | \uff1a\u7ba1\u9053\u7b26\uff0c\u6216\u8005\uff08\u6b63\u5219\uff09 > \uff1a\u8f93\u51fa\u91cd\u5b9a\u5411 >> \uff1a\u8f93\u51fa\u8ffd\u52a0\u91cd\u5b9a\u5411 < \uff1a\u8f93\u5165\u91cd\u5b9a\u5411 << \uff1a\u8ffd\u52a0\u8f93\u5165\u91cd\u5b9a\u5411 ~ \uff1a\u5f53\u524d\u7528\u6237\u5bb6\u76ee\u5f55 $() \uff1a\u5f15\u7528\u547d\u4ee4\u88ab\u6267\u884c\u540e\u7684\u7ed3\u679c $ \uff1a\u4ee5...\u7ed3\u5c3e\uff08\u6b63\u5219\uff09 ^ \uff1a\u4ee5...\u5f00\u5934\uff08\u6b63\u5219\uff09 * \uff1a\u5339\u914d\u5168\u90e8\u5b57\u7b26\uff0c\u901a\u914d\u7b26 ? \uff1a\u4efb\u610f\u4e00\u4e2a\u5b57\u7b26\uff0c\u901a\u914d\u7b26 # \uff1a\u6ce8\u91ca & \uff1a\u8ba9\u7a0b\u5e8f\u6216\u811a\u672c\u5207\u6362\u5230\u540e\u53f0\u6267\u884c && \uff1a\u5e76\u4e14\uff0c\u540c\u65f6\u6210\u7acb [] \uff1a\u8868\u793a\u4e00\u4e2a\u8303\u56f4\uff08\u6b63\u5219\uff0c\u901a\u914d\u7b26\uff09 {} \uff1a\u4ea7\u751f\u4e00\u4e2a\u5e8f\u5217\uff08\u901a\u914d\u7b26\uff09 . \uff1a\u5f53\u524d\u76ee\u5f55\u7684\u786c\u94fe\u63a5 .. \uff1a\u4e0a\u7ea7\u76ee\u5f55\u7684\u786c\u94fe\u63a5 2.11.\u5237\u65b0\u6587\u4ef6\u65f6\u95f4 touch \u00b6 touch \u547d\u4ee4\u53ef\u4ee5\u521b\u5efa\u7a7a\u6587\u4ef6\uff0c\u4e5f\u53ef\u4ee5\u5237\u65b0\u6587\u4ef6\u65f6\u95f4\u3002\u53c2\u6570\u5982\u4e0b\uff1a -a \uff1a\u4ec5\u6539\u53d8 atime \u548c ctime -m \uff1a\u4ec5\u6539\u53d8 mtime \u548c ctime -t [[CC]YY]MMDDhhmm[.ss] \uff1a\u6307\u5b9a atime \u548c mtime -c \uff1a\u5982\u679c\u6587\u4ef6\u4e0d\u5b58\u5728\uff0c\u5219\u4e0d\u521b\u5efa $ touch file1 $ touch file2 $ ll -rw-r--r--. 1 vagrant wheel 5 Nov 8 20 :49 file1 -rw-r--r--. 1 vagrant wheel 0 Nov 8 20 :28 file2 \u521b\u5efa\u6587\u4ef6file-non.log\uff0c\u5982\u679c\u4e0d\u5b58\u5728\u5219\u4e0d\u521b\u5efa\u3002 touch -c file-non.log \u66f4\u65b0 file1 \u7684\u65f6\u95f4\u548c file2 \u4e00\u81f4\u3002 $ touch -r file1 file2 $ ll -rw-r--r--. 1 vagrant wheel 5 Nov 8 20 :49 file1 -rw-r--r--. 1 vagrant wheel 0 Nov 8 20 :49 file2 \u6307\u5b9a file2 \u7684\u65f6\u95f4\u3002 202210012135.25 \u4ee3\u8868 YYYYMMDDHHMM.SS \u3002 $ touch -t 202210012135 .25 file2 $ ll -rw-r--r--. 1 vagrant wheel 5 Nov 8 20 :49 file1 -rw-r--r--. 1 vagrant wheel 0 Oct 1 21 :35 file2 $ stat file2 File: file2 Size: 0 Blocks: 0 IO Block: 4096 regular empty file Device: fd02h/64770d Inode: 140 Links: 1 Access: ( 0644 /-rw-r--r-- ) Uid: ( 1000 / vagrant ) Gid: ( 10 / wheel ) Context: unconfined_u:object_r:user_home_t:s0 Access: 2022 -10-01 21 :35:25.000000000 +0800 Modify: 2022 -10-01 21 :35:25.000000000 +0800 Change: 2022 -11-08 20 :56:18.306315887 +0800 Birth: 2022 -11-08 20 :28:37.809551441 +0800 2.12.\u590d\u5236\u6587\u4ef6\u548c\u76ee\u5f55 cp \u00b6 cp \u547d\u4ee4\uff1aCopy SOURCE to DEST, or multiple SOURCE(s) to DIRECTORY. \u5e38\u7528\u53c2\u6570\uff1a -a \uff1a\u5f52\u6863\uff0c\u76f8\u5f53\u4e8e -dR --preserv=all \u53c2\u6570\u7ec4\u5408\uff0c\u5e38\u7528\u4e8e\u5907\u4efd\u3002 -d \uff1a\u4e0d\u590d\u5236\u539f\u6587\u4ef6\uff0c\u53ea\u590d\u5236\u94fe\u63a5\u540d\u3002\u76f8\u5f53\u4e8e --no-dereference --preserve=links \u53c2\u6570\u7ec4\u5408\u3002 -f \uff1a\u8986\u76d6\u5df2\u7ecf\u5b58\u5728\u7684\u76ee\u6807\u6587\u4ef6\u3002 -i \uff1a\u8986\u76d6\u76ee\u6807\u6587\u4ef6\u4e4b\u524d\u7ed9\u51fa\u63d0\u793a\u3002 -p \uff1a\u9664\u590d\u5236\u6587\u4ef6\u7684\u5185\u5bb9\u5916\uff0c\u4e5f\u590d\u5236\u6587\u4ef6\u6743\u9650\uff0c\u65f6\u95f4\u6233\uff0c\u5c5e\u4e3b\u5c5e\u7ec4\u3002\u76f8\u5f53\u4e8e --preserve=mode,ownership,timestamps \u3002 -r, -R, --recursive \uff1a\u9012\u5f52\u590d\u5236\u76ee\u5f55\u6240\u5305\u542b\u7684\u5168\u90e8\u5185\u5bb9\u3002 -l \uff1a\u4e0d\u590d\u5236\u6587\u4ef6\uff0c\u53ea\u662f\u751f\u6210\u786c\u94fe\u63a5\u6587\u4ef6\u3002 \u53c2\u6570 --preserv \u53ef\u9009\u9879\uff1a mode\uff1a\u6743\u9650 ownership\uff1a\u5c5e\u4e3b\u5c5e\u7ec4 timestamp links xattr context all \u521b\u5efa\u6d4b\u8bd5\u76ee\u5f55\u3002 cd ~ mkdir test \u5bf9\u6bd4\u53c2\u6570 -p \u7684\u5dee\u522b\u3002 $ cp /etc/issue ~/test/issue1 $ cp -p /etc/issue ~/test/issue1 $ sudo cp /etc/issue ~/test/issue3 $ sudo cp -p /etc/issue ~/test/issue4 $ ll ~/test -rw-r--r--. 1 vagrant wheel 23 Nov 8 22 :25 issue1 -rw-r--r--. 1 vagrant wheel 23 Jul 21 01 :10 issue2 -rw-r--r--. 1 root root 23 Nov 8 22 :43 issue3 -rw-r--r--. 1 root root 23 Jul 21 01 :10 issue4 $ ll /etc/issue -rw-r--r--. 1 root root 23 Jul 21 01 :10 /etc/issue \u5bf9\u6bd4\u53c2\u6570 -r \u3002 $ sudo cp /etc/sysconfig/ ~/test cp: -r not specified ; omitting directory '/etc/sysconfig/' $ sudo cp -r /etc/sysconfig/ ~/test $ tree -L 2 ~/test /home/vagrant/test \u251c\u2500\u2500 issue1 \u251c\u2500\u2500 issue2 \u251c\u2500\u2500 issue3 \u251c\u2500\u2500 issue4 \u2514\u2500\u2500 sysconfig \u251c\u2500\u2500 anaconda \u251c\u2500\u2500 atd \u251c\u2500\u2500 chronyd \u251c\u2500\u2500 cpupower \u251c\u2500\u2500 crond \u251c\u2500\u2500 firewalld \u251c\u2500\u2500 irqbalance \u251c\u2500\u2500 kdump \u251c\u2500\u2500 kernel \u251c\u2500\u2500 man-db \u251c\u2500\u2500 network \u251c\u2500\u2500 network-scripts \u251c\u2500\u2500 nftables.conf \u251c\u2500\u2500 raid-check \u251c\u2500\u2500 rsyslog \u251c\u2500\u2500 run-parts \u251c\u2500\u2500 samba \u251c\u2500\u2500 selinux -> ../selinux/config \u251c\u2500\u2500 smartmontools \u2514\u2500\u2500 sshd \u53c2\u6570 -b \uff0c\u5982\u679c\u76ee\u6807\u6587\u4ef6\u5b58\u5728\uff0c\u590d\u5236\u524d\u5148\u5c06\u539f\u6587\u4ef6\u590d\u5236\u5e76\u4ee5 ~ \u7ed3\u5c3e\u3002 $ ll /etc/motd -rw-r--r--. 1 root root 0 Jun 23 2020 /etc/motd $ ll ~/test/issue1 -rw-r--r--. 1 vagrant wheel 23 Nov 8 22 :25 /home/vagrant/test/issue1 $ cp -b /etc/motd ~/test/issue $ cp -b /etc/motd ~/test/issue1 $ ll ~/test -rw-r--r--. 1 vagrant wheel 0 Nov 8 23 :00 issue -rw-r--r--. 1 vagrant wheel 0 Nov 8 22 :57 issue1 -rw-r--r--. 1 vagrant wheel 23 Nov 8 22 :25 issue1~ -rw-r--r--. 1 vagrant wheel 23 Jul 21 01 :10 issue2 -rw-r--r--. 1 root root 23 Nov 8 22 :43 issue3 -rw-r--r--. 1 root root 23 Jul 21 01 :10 issue4 drwxr-xr-x. 3 root root 4096 Nov 8 22 :49 sysconfig \u53c2\u6570 --backup=numbered \u4f1a\u5728\u590d\u5236\u539f\u6587\u4ef6\u65f6\u52a0\u4e0a\u6570\u5b57\u5e8f\u53f7\uff0c\u5e8f\u53f71\u4ee3\u8868\u539f\u59cb\u7684\u6587\u4ef6\u3002 $ cp --backup = numbered /etc/motd ~/test/issue2 $ cp --backup = numbered /etc/motd ~/test/issue2 $ cp --backup = numbered /etc/motd ~/test/issue2 $ ll ~/test -rw-r--r--. 1 vagrant wheel 0 Nov 8 23 :00 issue -rw-r--r--. 1 vagrant wheel 0 Nov 8 22 :57 issue1 -rw-r--r--. 1 vagrant wheel 23 Nov 8 22 :25 issue1~ -rw-r--r--. 1 vagrant wheel 0 Nov 8 23 :09 issue2 -rw-r--r--. 1 vagrant wheel 23 Jul 21 01 :10 issue2.~1~ -rw-r--r--. 1 vagrant wheel 0 Nov 8 23 :09 issue2.~2~ -rw-r--r--. 1 vagrant wheel 0 Nov 8 23 :09 issue2.~3~ -rw-r--r--. 1 root root 23 Nov 8 22 :43 issue3 -rw-r--r--. 1 root root 23 Jul 21 01 :10 issue4 drwxr-xr-x. 3 root root 4096 Nov 8 22 :49 sysconfig 2.13.\u79fb\u52a8\u6587\u4ef6\u548c\u76ee\u5f55 mv \u00b6 mv \u547d\u4ee4\u3002Rename SOURCE to DEST, or move SOURCE(s) to DIRECTORY. \u5e38\u7528\u53c2\u6570\uff1a -v \uff1a\u663e\u793a\u547d\u4ee4\u6267\u884c\u7684\u4fe1\u606f\u3002 -i \uff1a\u4ea4\u4e92\u5f0f\uff0c\u6bd4\u5982\uff0c\u91cd\u540d\u8986\u76d6\u65f6\u4f1a\u63d0\u5347\u662f\u5426\u786e\u8ba4\u3002 -b \uff1a\u8986\u76d6\u65f6\u521b\u5efa\u5907\u4efd\u3002\u9ed8\u8ba4\u60c5\u51b5\u4e0b\uff0c\u79fb\u52a8\u6587\u4ef6\u5c06\u4f1a\u8986\u76d6\u5df2\u5b58\u5728\u7684\u76ee\u6807\u6587\u4ef6\u3002 \u79fb\u52a8\u591a\u4e2a\u6587\u4ef6\u5230\u67d0\u4e2a\u76ee\u5f55\u3002 mv file1 file2 file3 ~/dest mv file* ~/dest \u79fb\u52a8\u76ee\u5f55\u3002 mv ~/test ~/dest/new/one/ \u91cd\u547d\u540d\u6587\u4ef6\u548c\u76ee\u5f55\u3002 mv file1 file2 mv ~/test ~/dest 2.14.\u91cd\u547d\u540d\u6587\u4ef6\u548c\u76ee\u5f55 rename \u00b6 rename \u547d\u4ee4\u3002\u5206\u4e3aperl\u7248\u672c\u548cC\u8bed\u8a00\u7248\u672c\u3002 \u533a\u5206\u65b9\u6cd5: rename --version \u3002\u5982\u679c\u8fd4\u56de\u7ed3\u679c\u4e2d\u5305\u542b util-linux \uff0c\u8bf4\u660e\u662fC\u8bed\u8a00\u7248\u672c, \u53cd\u4e4b\u662fPerl\u7248\u672c\u3002 openSUSE\u548cRocy\u662fC\u8bed\u8a00\u7248\u672c\uff0cUbuntu\u662fPerl\u7248\u672c\u3002 \u4e3e\u4f8b\uff1a\u4fee\u6539\u5f53\u524d\u76ee\u5f55\u6240\u6709\u6269\u5c55\u540d\u4e3a s \u7684\u6587\u4ef6\u6539\u4e3a\u6269\u5c55\u540d\u4e3a gz \u3002 $ touch file { 1 ..3 } .s $ rename -v '.s' '.gz' *.s $ rename -v \".s\" \".gz\" *.s ` file1.txt ' -> `file1.html' ` file2.txt ' -> `file2.html' ` file3.txt ' -> `file3.html' \u5728Ubuntu\u4e0a\u5b8c\u6210\u540c\u6837\u4efb\u52a1\uff0c\u5219\u9700\u8981\u4f7f\u7528\u6b63\u5219\u3002 rename -v \"s/s/gz/g\" *.s 2.15.\u5220\u9664\u6587\u4ef6 rm \u00b6 rm \u547d\u4ee4\u3002\u5efa\u8bae\u4f7f\u7528 mv \u547d\u4ee4\u4ee3\u66ff rm \u547d\u4ee4\u3002 2.16.\u76ee\u5f55\u64cd\u4f5c\u547d\u4ee4 \u00b6 \u521b\u5efa\u76ee\u5f55\uff1a mkdir \u5220\u9664\u7a7a\u76ee\u5f55\uff1a rmdir \u5220\u9664\u975e\u7a7a\u76ee\u5f55\uff1a rm -r \u663e\u793a\u76ee\u5f55\u6811\uff1a tree 2.17.\u7ec3\u4e60 \u00b6 \u663e\u793a /etc \u76ee\u5f55\u4e0b\u6240\u6709\u4ee5 l \u5f00\u5934\uff0c\u4ee5\u4e00\u4e2a\u5c0f\u5199\u5b57\u6bcd\u7ed3\u5c3e\uff0c\u4e14\u4e2d\u95f4\u51fa\u73b0\u81f3\u5c11\u4e00\u4f4d\u6570\u5b57\u7684\u6587\u4ef6\u6216\u76ee\u5f55\u5217\u8868\u3002 ls -d /etc/l* [ 0 -9 ] * [ a-z ] ls -d /etc/l* [[ :digit: ]] * [[ :lower: ]] \u5982\u679c\u65e0\u7b26\u5408\u6761\u4ef6\u7684\u8bb0\u5f55\u8fd4\u56de\uff0c\u53ef\u4ee5\u624b\u5de5\u521b\u5efa\u4e00\u4e2a\u7b26\u5408\u6761\u4ef6\u7684\u6587\u4ef6\u548c\u76ee\u5f55\u3002 sudo touch /etc/lam4you sudo mkdir /etc/lam5you \u9a8c\u8bc1\u540e\u5220\u9664\u3002 sudo rm /etc/lam4you sudo rm -rf /etc/lam5you \u663e\u793a /etc \u76ee\u5f55\u4e0b\u4ee5\u4efb\u610f\u4e00\u4f4d\u6570\u5b57\u5f00\u5934\uff0c\u4e14\u4ee5\u975e\u6570\u5b57\u7ed3\u5c3e\u7684\u6587\u4ef6\u6216\u76ee\u5f55\u5217\u8868\u3002 ls /etc/ [ 0 -9 ] * [ !0-9 ] ls /etc/ [[ :digit: ]] * [ ^ [ :digit: ]] \u5982\u679c\u65e0\u7b26\u5408\u6761\u4ef6\u7684\u8bb0\u5f55\u8fd4\u56de\uff0c\u53ef\u4ee5\u624b\u5de5\u521b\u5efa\u4e00\u4e2a\u7b26\u5408\u6761\u4ef6\u7684\u6587\u4ef6\u548c\u76ee\u5f55\u3002 sudo touch /etc/5am4yo. sudo mkdir /etc/5am5yo. \u9a8c\u8bc1\u540e\u5220\u9664\u3002 sudo rm /etc/5am4yo. sudo rm -rf /etc/5am5yo. \u663e\u793a /etc \u76ee\u5f55\u4e0b\u4ee5\u975e\u5b57\u6bcd\u5f00\u5934\uff0c\u540e\u9762\u8ddf\u4e86\u4e00\u4e2a\u5b57\u6bcd\u53ca\u5176\u5b83\u4efb\u610f\u957f\u5ea6\u4efb\u610f\u5b57\u7b26\u7684\u6587\u4ef6\u6216\u76ee\u5f55\u5217\u8868\u3002 ls /etc/ [ !a-zA-Z ][ a-zA-Z ] * ls /etc/ [ ^ [ :alpha: ]][[ :alpha: ]] * \u5982\u679c\u65e0\u7b26\u5408\u6761\u4ef6\u7684\u8bb0\u5f55\u8fd4\u56de\uff0c\u53ef\u4ee5\u624b\u5de5\u521b\u5efa\u4e00\u4e2a\u7b26\u5408\u6761\u4ef6\u7684\u6587\u4ef6\u548c\u76ee\u5f55\u3002 sudo touch /etc/5Ato3 sudo mkdir /etc/6dog6 \u9a8c\u8bc1\u540e\u5220\u9664\u3002 sudo rm /etc/5Ato3 sudo rm -rf /etc/6dog6 \u663e\u793a /etc \u76ee\u5f55\u4e0b\uff0c\u6240\u6709\u4ee5 rc \u5f00\u5934\uff0c\u5e76\u540e\u9762\u662f0-6\u4e4b\u95f4\u7684\u6570\u5b57\uff0c\u5176\u5b83\u4e3a\u4efb\u610f\u5b57\u7b26\u7684\u6587\u4ef6\u6216\u76ee\u5f55\u5217\u8868\u3002 ls /etc/rc [ 0 -6 ] * \u5982\u679c\u65e0\u7b26\u5408\u6761\u4ef6\u7684\u8bb0\u5f55\u8fd4\u56de\uff0c\u53ef\u4ee5\u624b\u5de5\u521b\u5efa\u4e00\u4e2a\u7b26\u5408\u6761\u4ef6\u7684\u6587\u4ef6\u548c\u76ee\u5f55\u3002 sudo touch /etc/rc5come sudo mkdir /etc/rc0123 \u9a8c\u8bc1\u540e\u5220\u9664\u3002 sudo rm /etc/rc5come sudo rm -rf /etc/rc0123 \u663e\u793a /etc \u76ee\u5f55\u4e0b\uff0c\u6240\u6709\u4ee5 .conf \u7ed3\u5c3e\uff0c\u4e14\u4ee5 m \u3001 n \u3001 r \u3001 p \u5f00\u5934\u7684\u6587\u4ef6\u6216\u76ee\u5f55\u5217\u8868\u3002 ls /etc/ [ mnrp ] *.conf \u53ea\u663e\u793a /root \u4e0b\u7684\u9690\u85cf\u6587\u4ef6\u548c\u76ee\u5f55\u5217\u8868\u3002 ls .* \u53ea\u663e\u793a/etc\u4e0b\u975e\u9690\u85cf\u76ee\u5f55\u5217\u8868\u3002 ls /etc/ [ ^. ] */ \u5c06 /etc \u76ee\u5f55\u4e0b\u6240\u6709\u6587\u4ef6\uff0c\u5907\u4efd\u5230 ~/test/ \u76ee\u5f55\u4e0b\uff0c\u5e76\u8981\u6c42\u5b50\u76ee\u5f55\u683c\u5f0f\u4e3a backupYYYY-mm-dd \uff0c\u5907\u4efd\u8fc7\u7a0b\u53ef\u89c1\u3002 sudo cp -av /etc/ ~/test/backup ` date +%F ` sudo cp -av /etc/ ~/test/backup ` date +%F_%H-%M-%S ` \u521b\u5efa\u76ee\u5f55 ~/testdir/dir1/x \uff0c ~/testdir/dir1/y \uff0c ~/testdir/dir1/x/a \uff0c ~/testdir/dir1/x/b \uff0c ~/testdir/dir1/y/a \uff0c ~/testdir/dir1/y/b \u3002 $ mkdir -p ~/testdir/dir1/ { x,y } / { a,b } $ tree ~/testdir/dir1/ /home/vagrant/testdir/dir1/ \u251c\u2500\u2500 x \u2502 \u251c\u2500\u2500 a \u2502 \u2514\u2500\u2500 b \u2514\u2500\u2500 y \u251c\u2500\u2500 a \u2514\u2500\u2500 b \u521b\u5efa\u76ee\u5f55 ~/testdir/dir2/x \uff0c ~/testdir/dir2/y \uff0c ~/testdir/dir2/x/a \uff0c ~/testdir/dir2/x/b \u3002 $ mkdir -p ~/testdir/dir2/ { x/ { a,b } ,y } $ tree ~/testdir/dir2/ /home/vagrant/testdir/dir2/ \u251c\u2500\u2500 x \u2502 \u251c\u2500\u2500 a \u2502 \u2514\u2500\u2500 b \u2514\u2500\u2500 y \u521b\u5efa\u76ee\u5f55 ~/testdir/dir3 \u3001 ~/testdir/dir4 \u3001 ~/testdir/dir5 \u3001 ~/testdir/dir5/dir6 \u3001 ~/testdir/dir5/dir7 \u3002 $ mkdir -p ~/testdir/dir { 3 ,4,5/dir { 6 ,7 }} $ tree ~/testdir /home/vagrant/testdir \u251c\u2500\u2500 dir1 \u2502 \u251c\u2500\u2500 x \u2502 \u2502 \u251c\u2500\u2500 a \u2502 \u2502 \u2514\u2500\u2500 b \u2502 \u2514\u2500\u2500 y \u2502 \u251c\u2500\u2500 a \u2502 \u2514\u2500\u2500 b \u251c\u2500\u2500 dir2 \u2502 \u251c\u2500\u2500 x \u2502 \u2502 \u251c\u2500\u2500 a \u2502 \u2502 \u2514\u2500\u2500 b \u2502 \u2514\u2500\u2500 y \u251c\u2500\u2500 dir3 \u251c\u2500\u2500 dir4 \u2514\u2500\u2500 dir5 \u251c\u2500\u2500 dir6 \u2514\u2500\u2500 dir7 3.\u4e03\u79cd\u6587\u4ef6\u7c7b\u578b \u00b6 \u666e\u901a\u6587\u4ef6\uff08Normal Files\uff09 ASCII \u6587\u672c\u6587\u4ef6 \u53ef\u6267\u884c\u6587\u4ef6 \u56fe\u5f62\u6587\u4ef6 \u76ee\u5f55\uff08Directories\uff09 \u7ec4\u7ec7\u89c4\u5212\u78c1\u76d8\u4e0a\u7684\u6587\u4ef6 \u5305\u542b\u6587\u4ef6\u548c\u5b50\u76ee\u5f55 \u5b9e\u73b0\u5206\u5c42\u6587\u4ef6\u7cfb\u7edf \u94fe\u63a5\uff08Links\uff09 \u786c\u94fe\u63a5\uff08Hard links\uff09 \u78c1\u76d8\u4e0a\u6587\u4ef6\u7684\u8f85\u52a9\u6587\u4ef6\u540d \u591a\u4e2a\u6587\u4ef6\u540d\u5f15\u7528\u5355\u4e2a inode \u5f15\u7528\u7684\u6587\u4ef6\u5fc5\u987b\u5b58\u5728\u4e8e\u540c\u4e00\u4e2a\u6587\u4ef6\u7cfb\u7edf\u4e2d \u7b26\u53f7\u94fe\u63a5\uff08Symbolic links\uff09 \u5bf9\u78c1\u76d8\u4e0a\u5176\u4ed6\u6587\u4ef6\u7684\u5f15\u7528 inode \u5305\u542b\u5bf9\u53e6\u4e00\u4e2a\u6587\u4ef6\u540d\u7684\u5f15\u7528 \u88ab\u5f15\u7528\u7684\u6587\u4ef6\u53ef\u4ee5\u5b58\u5728\u4e8e\u540c\u4e00\u4e2a\u6587\u4ef6\u7cfb\u7edf\u4e2d\uff0c\u4e5f\u53ef\u4ee5\u5b58\u5728\u4e8e\u5176\u4ed6\u6587\u4ef6\u7cfb\u7edf\u4e2d \u7b26\u53f7\u94fe\u63a5\u53ef\u4ee5\u5f15\u7528\u4e0d\u5b58\u5728\u7684\u6587\u4ef6\uff08\u65ad\u5f00\u7684\u94fe\u63a5\uff09 \u5957\u63a5\u5b57Sockets - \u7528\u4e8e\u8fdb\u7a0b\u4e4b\u95f4\u7684\u53cc\u5411\u901a\u4fe1\u3002 \u7ba1\u9053\uff08Pipes\uff09(FIFOs) - \u7528\u4e8e\u4ece\u4e00\u4e2a\u8fdb\u7a0b\u5230\u53e6\u4e00\u4e2a\u8fdb\u7a0b\u7684\u5355\u5411\u901a\u4fe1\u3002 \u5757\u8bbe\u5907\uff08Block Devices\uff09 \u5b57\u7b26\u8bbe\u5907\uff08Character Devices\uff09 3.1.inode\u7ed3\u6784 \u00b6 \u6587\u4ef6\u50a8\u5b58\u5728\u786c\u76d8\u4e0a\uff0c\u786c\u76d8\u7684\u6700\u5c0f\u5b58\u50a8\u5355\u4f4d\u53eb\u505a\u201c\u6247\u533a\u201d\uff08Sector\uff09\u3002\u6bcf\u4e2a\u6247\u533a\u50a8\u5b58512\u5b57\u8282\uff08\u76f8\u5f53\u4e8e0.5KB\uff09\u3002 \u64cd\u4f5c\u7cfb\u7edf\u8bfb\u53d6\u786c\u76d8\u7684\u65f6\u5019\uff0c\u4e0d\u662f\u4e00\u4e2a\u4e00\u4e2a\u6247\u533a\u8bfb\u53d6\uff0c\u800c\u662f\u4e00\u6b21\u6027\u8fde\u7eed\u8bfb\u53d6\u591a\u4e2a\u6247\u533a\uff0c\u6211\u4eec\u79f0\u4e3a\u8bfb\u53d6\u4e00\u4e2a\u201c\u5757\u201d\uff08block\uff09\u3002 \u5e38\u89c1\u7684block\u7684\u5927\u5c0f\u662f4KB\uff08\u8fde\u7eed\u516b\u4e2asector\u7ec4\u6210\u4e00\u4e2ablock\uff09\u3002 \u591a\u4e2a\u6247\u533a\u7ec4\u6210\u7684block\u662f\u6587\u4ef6\u5b58\u53d6\u7684*\u6700\u5c0f\u5355\u4f4d*\u3002 \u6587\u4ef6\u6570\u636e\u50a8\u5b58\u5728block\u4e2d\uff0c\u6587\u4ef6\u7684\u5143\u4fe1\u606f\uff0c\u6bd4\u5982\u6587\u4ef6\u7684\u521b\u5efa\u8005\u3001\u521b\u5efa\u65e5\u671f\u3001\u6587\u5927\u5c0f\u7b49\uff0c\u5b58\u50a8\u5728inode\uff0c\u5373\u201c\u7d22\u5f15\u8282\u70b9\u201d\u3002 \u6bcf\u4e00\u4e2a\u6587\u4ef6\u90fd\u6709\u5bf9\u5e94\u7684inode\uff0c\u91cc\u9762\u5305\u542b\u4e86\u4e0e\u8be5\u6587\u4ef6\u6709\u5173\u7684\u4e00\u4e9b\u4fe1\u606f\u3002\u6ce8\u610f\uff0c\u9664\u4e86\u6587\u4ef6\u540d\u4ee5\u5916\u7684\u5176\u5b83\u6587\u4ef6\u4fe1\u606f\uff0c\u90fd\u5b58\u5728inode\u4e4b\u4e2d\u3002 inode\u5305\u542b\u6587\u4ef6\u7684\u5143\u4fe1\u606f\u4e3b\u8981\u6709\uff1a \u6587\u4ef6\u7684\u5b57\u8282\u6570 \u6587\u4ef6\u62e5\u6709\u8005\u7684 User ID \u6587\u4ef6\u7684 Group ID \u6587\u4ef6\u7684\u8bfb\u3001\u5199\u3001\u6267\u884c\u6743\u9650 \u6587\u4ef6\u7684\u65f6\u95f4\u6233\uff0c\u5171\u6709\u4e09\u4e2a\uff1actime\u6307inode\u4e0a\u4e00\u6b21\u53d8\u52a8\u7684\u65f6\u95f4\uff0cmtime\u6307\u6587\u4ef6\u5185\u5bb9\u4e0a\u4e00\u6b21\u53d8\u52a8\u7684\u65f6\u95f4\uff0catime\u6307\u6587\u4ef6\u4e0a\u4e00\u6b21\u6253\u5f00\u7684\u65f6\u95f4\u3002 \u94fe\u63a5\u6570\uff0c\u5373\u6709\u591a\u5c11\u6587\u4ef6\u540d\u6307\u5411\u8fd9\u4e2ainode \u6587\u4ef6\u6570\u636eblock\u7684\u4f4d\u7f6e \u67e5\u770binode\u4fe1\u606f\u7684\u547d\u4ee4 stat \uff1a $ stat file1 File: file1 Size: 5 Blocks: 8 IO Block: 4096 regular file Device: fd02h/64770d Inode: 143 Links: 1 Access: ( 0644 /-rw-r--r-- ) Uid: ( 1000 / vagrant ) Gid: ( 10 / wheel ) Context: unconfined_u:object_r:user_home_t:s0 Access: 2022 -11-08 20 :49:26.019678244 +0800 Modify: 2022 -11-08 20 :49:26.019678244 +0800 Change: 2022 -11-08 20 :49:26.028678455 +0800 Birth: 2022 -11-08 20 :49:26.019678244 +0800 \u683c\u5f0f\u5316\u786c\u76d8\u65f6\uff0c\u64cd\u4f5c\u7cfb\u7edf\u4f1a\u81ea\u52a8\u5c06\u786c\u76d8\u5206\u6210\u4e24\u4e2a\u533a\u57df\u3002\u4e00\u4e2a\u662f\u6570\u636e\u533a\uff0c\u5b58\u653e\u6587\u4ef6\u6570\u636e\u3002\u53e6\u4e00\u4e2a\u662finode\u533a\uff08inode table\uff09\uff0c\u5b58\u653einode\u6240\u5305\u542b\u7684\u6587\u4ef6\u7684\u5143\u4fe1\u606f\u3002 \u6bcf\u4e2ainode\u8282\u70b9\u7684\u5927\u5c0f\uff0c\u4e00\u822c\u662f128\u5b57\u8282\u6216256\u5b57\u8282\u3002inode\u8282\u70b9\u7684\u603b\u6570\uff0c\u5728\u683c\u5f0f\u5316\u65f6\u5c31\u786e\u5b9a\u4e86\uff0c\u4e00\u822c\u662f\u6bcf1KB\u6216\u6bcf2KB\u5c31\u8bbe\u7f6e\u4e00\u4e2ainode\u3002 \u5047\u5b9a\u4e00\u57571GB\u7684\u786c\u76d8\uff0c\u5982\u679c\u6bcf\u4e2ainode\u8282\u70b9\u7684\u5927\u5c0f\u4e3a128\u5b57\u8282\uff0c\u4e14\u6bcf1KB\u5c31\u8bbe\u7f6e\u4e00\u4e2ainode\uff0c\u5219inode table\u7684\u5927\u5c0f\u5c31\u4f1a\u8fbe\u5230128MB\uff0c\u5360\u6574\u5757\u786c\u76d8\u768412.8%\u3002 \u901a\u8fc7 df \u547d\u4ee4\u67e5\u770b\u6bcf\u4e2a\u786c\u76d8\u5206\u533a\u7684inode\u603b\u6570\u548c\u5df2\u7ecf\u4f7f\u7528\u7684\u6570\u91cf\u3002 \u7531\u4e8e\u6bcf\u4e2a\u6587\u4ef6\u90fd\u5fc5\u987b\u6709\u4e00\u4e2ainode\uff0c\u56e0\u6b64\u6709\u53ef\u80fd\u53d1\u751finode\u5df2\u7ecf\u7528\u5149\uff0c\u4f46\u662f\u786c\u76d8\u8fd8\u672a\u5b58\u6ee1\u7684\u60c5\u51b5\uff0c\u4e5f\u5c31\u65e0\u6cd5\u5728\u786c\u76d8\u4e0a\u521b\u5efa\u65b0\u6587\u4ef6\u3002 $ df -i Filesystem Inodes IUsed IFree IUse% Mounted on tmpfs 497897 872 497025 1 % /run /dev/mapper/ubuntu--vg-ubuntu--lv 3211264 81473 3129791 3 % / tmpfs 497897 1 497896 1 % /dev/shm tmpfs 497897 3 497894 1 % /run/lock /dev/sda2 131072 316 130756 1 % /boot tmpfs 99579 25 99554 1 % /run/user/1000 \u4e0b\u9762\u547d\u4ee4\u53ef\u4ee5\u67e5\u770b\u6bcf\u4e2ainode\u8282\u70b9\u7684\u5927\u5c0f\uff1a $ sudo dumpe2fs -h /dev/sda2 | grep \"Inode size\" dumpe2fs 1 .46.5 ( 30 -Dec-2021 ) Inode size: 256 \u6bcf\u4e2ainode\u90fd\u6709\u4e00\u4e2a\u53f7\u7801\uff0c\u64cd\u4f5c\u7cfb\u7edf\u7528inode\u53f7\u7801\u6765\u8bc6\u522b\u4e0d\u540c\u7684\u6587\u4ef6\uff0c\u6ce8\u610f\uff0c\u4e0d\u662f\u901a\u8fc7\u6587\u4ef6\u540d\u6765\u8bc6\u522b\u4e0d\u540c\u6587\u4ef6\u3002\u4ece\u64cd\u4f5c\u7cfb\u7edf\u89d2\u5ea6\u770b\uff0c\u6587\u4ef6\u540d\u53ea\u662finode\u53f7\u7801\u5bf9\u4e00\u4e2a\u522b\u540d\u3002 \u7528\u6237\u901a\u8fc7\u6587\u4ef6\u540d\uff0c\u6253\u5f00\u67d0\u4e2a\u6587\u4ef6\u7684\u8fc7\u7a0b\uff0c\u64cd\u4f5c\u7cfb\u7edf\u5206\u6210\u4e09\u6b65\u5b8c\u6210\uff1a \u9996\u5148\uff0c\u7cfb\u7edf\u627e\u5230\u8fd9\u4e2a\u6587\u4ef6\u540d\u5bf9\u5e94\u7684inode\u53f7\u7801\u3002 \u5176\u6b21\uff0c\u901a\u8fc7inode\u53f7\uff0c\u83b7\u53d6inode\u4fe1\u606f\u3002 \u7b2c\u4e09\uff0c\u901a\u8fc7inode\u4fe1\u606f\uff0c\u627e\u5230\u6587\u4ef6\u6570\u636e\u6240\u5728\u7684block\uff0c\u8bfb\u51fa\u6570\u636e\u3002 \u901a\u8fc7 ls -i \u547d\u4ee4\uff0c\u53ef\u4ee5\u5f97\u5230\u6587\u4ef6\u5bf9\u5e94\u7684inode\u53f7\uff1a $ ls -i file1 143 file1 \u76ee\u5f55\uff08directory\uff09\u4e5f\u662f\u4e00\u79cd\u6587\u4ef6\u3002\u6253\u5f00\u76ee\u5f55\uff0c\u5b9e\u9645\u4e0a\u5c31\u662f\u6253\u5f00\u76ee\u5f55\u6587\u4ef6\u3002 \u76ee\u5f55\u6587\u4ef6\u7684\u7ed3\u6784\u662f\u7531\u4e00\u4e2a\u5305\u542b\u4e00\u7cfb\u5217\u76ee\u5f55\u9879\uff08dirent\uff09\u7684\u5217\u8868\u7ec4\u6210\u3002 \u6bcf\u4e2a\u76ee\u5f55\u9879\u7531\u4e24\u90e8\u5206\u7ec4\u6210\uff1a\u6240\u5305\u542b\u6587\u4ef6\u7684\u6587\u4ef6\u540d\uff0c\u4ee5\u53ca\u8be5\u6587\u4ef6\u540d\u5bf9\u5e94\u7684inode\u53f7\u3002 \u547d\u4ee4 ls -i \u5217\u51fa\u6574\u4e2a\u76ee\u5f55\u6587\u4ef6\uff0c\u5373\u6587\u4ef6\u540d\u548cinode\u53f7\uff1a $ ls -i 143 file1 140 file2 139 test $ ls -il 143 -rw-r--r--. 1 vagrant wheel 5 Nov 8 20 :49 file1 140 -rw-r--r--. 1 vagrant wheel 0 Oct 1 21 :35 file2 139 drwxr-xr-x. 5 vagrant wheel 4096 Nov 9 22 :00 test 3.2.\u94fe\u63a5\u7c7b\u578b \u00b6 \u786c\u94fe\u63a5 \uff08Hard links\uff09\u786c\u94fe\u63a5\u662f\u5b58\u50a8\u5377\u4e0a\u6587\u4ef6\u7684\u76ee\u5f55\u5f15\u7528\u6216\u6307\u9488\u3002 \u6587\u4ef6\u540d\u662f\u5b58\u50a8\u5728\u76ee\u5f55\u7ed3\u6784\u4e2d\u7684\u6807\u7b7e\uff0c\u76ee\u5f55\u7ed3\u6784\u6307\u5411\u6587\u4ef6\u6570\u636e\u3002 \u56e0\u6b64\uff0c\u53ef\u4ee5\u5c06\u591a\u4e2a\u6587\u4ef6\u540d\u4e0e\u540c\u4e00\u6587\u4ef6\u5173\u8054\u3002 \u901a\u8fc7\u4e0d\u540c\u7684\u6587\u4ef6\u540d\u8bbf\u95ee\u65f6\uff0c\u6240\u505a\u7684\u4efb\u4f55\u66f4\u6539\u90fd\u662f\u9488\u5bf9\u6e90\u6587\u4ef6\u6570\u636e\u3002 \u7b26\u53f7\u94fe\u63a5 \uff08Symbolic links\uff09: \u7b26\u53f7\u94fe\u63a5\u5305\u542b\u4e00\u4e2a\u6587\u672c\u5b57\u7b26\u4e32\uff0c\u64cd\u4f5c\u7cfb\u7edf\u5c06\u5176\u89e3\u91ca\u4e3a\u53e6\u4e00\u4e2a\u6587\u4ef6\u6216\u76ee\u5f55\u3002 \u5b83\u672c\u8eab\u5c31\u662f\u4e00\u4e2a\u6587\u4ef6\uff0c\u53ef\u4ee5\u72ec\u7acb\u4e8e\u76ee\u6807\u800c\u5b58\u5728\u3002 \u5982\u679c\u5220\u9664\u4e86\u7b26\u53f7\u94fe\u63a5\uff0c\u5219\u5176\u76ee\u6807\u6587\u4ef6\u6216\u76ee\u5f55\u4e0d\u53d7\u5f71\u54cd\u3002 \u5982\u679c\u79fb\u52a8\uff0c\u91cd\u547d\u540d\u6216\u5220\u9664\u76ee\u6807\u6587\u4ef6\u6216\u76ee\u5f55\uff0c\u5219\u7528\u4e8e\u6307\u5411\u5b83\u7684\u4efb\u4f55\u7b26\u53f7\u94fe\u63a5\u5c06\u7ee7\u7eed\u5b58\u5728\uff0c\u4f46\u6307\u5411\u7684\u662f\u4e00\u4e2a\u4e0d\u5b58\u5728\u7684\u6587\u4ef6\u3002 \u4ec5\u5f53\u6587\u4ef6\u548c\u94fe\u63a5\u6587\u4ef6\u4f4d\u4e8e\u540c\u4e00\u6587\u4ef6\u7cfb\u7edf\uff08\u5728\u540c\u4e00\u5206\u533a\u4e0a\uff09\u65f6\uff0c\u624d\u80fd\u4f7f\u7528\u786c\u94fe\u63a5\uff0c\u56e0\u4e3ainode\u7f16\u53f7\u5728\u540c\u4e00\u6587\u4ef6\u7cfb\u7edf\u4e2d\u4ec5\u662f\u552f\u4e00\u7684\u3002 \u53ef\u4ee5\u4f7f\u7528 ln \u547d\u4ee4\u521b\u5efa\u786c\u94fe\u63a5\uff0c\u6307\u5411\u5df2\u5b58\u5728\u6587\u4ef6\u7684inode\uff0c\u53ef\u4ee5\u901a\u8fc7\u6587\u4ef6\u540d\u6216\u8005\u786c\u94fe\u63a5\u540d\u8bbf\u95ee\u6587\u4ef6\u3002 \u53ef\u4ee5\u4f7f\u7528 ln -s \u9009\u9879\u521b\u5efa\u7b26\u53f7\u94fe\u63a5\u3002 \u4e00\u4e2a\u7b26\u53f7\u94fe\u63a5\u4f1a\u88ab\u5206\u914d\u4e00\u4e2a\u5355\u72ec\u7684inode\uff0c\u5e76\u6307\u5411\u4e00\u4e2a\u6587\u4ef6\uff0c\u6240\u4ee5\u53ef\u4ee5\u660e\u663e\u533a\u5206\u7b26\u53f7\u94fe\u63a5\u6587\u4ef6\u548c\u5b9e\u9645\u6587\u4ef6\u3002 \u6587\u4ef6\u7cfb\u7edf\u672c\u8d28\u4e0a\u662f\u4e00\u4e2a\u7528\u4e8e\u8ddf\u8e2a\u5206\u533a\u5377\u4e2d\u7684\u6587\u4ef6\u7684\u6570\u636e\u5e93\u3002 \u5bf9\u4e8e\u666e\u901a\u6587\u4ef6\uff0c\u5206\u914d\u6570\u636e\u5757\u4ee5\u5b58\u50a8\u6587\u4ef6\u7684\u6570\u636e\uff0c\u5206\u914dinode\u4ee5\u6307\u5411\u6570\u636e\u5757\u4ee5\u53ca\u5b58\u50a8\u5173\u4e8e\u6587\u4ef6\u7684\u5143\u6570\u636e\uff0c\u7136\u540e\u5c06\u6587\u4ef6\u540d\u5206\u914d\u7ed9inode\u3002 \u786c\u94fe\u63a5\u662f\u4e0e\u73b0\u6709inode\u5173\u8054\u7684\u8f85\u52a9\u6587\u4ef6\u540d\u3002 \u5bf9\u4e8e\u7b26\u53f7\u94fe\u63a5\uff0c\u5c06\u4e3a\u65b0\u7684inode\u5206\u914d\u4e00\u4e2a\u4e0e\u4e4b\u5173\u8054\u7684\u65b0\u6587\u4ef6\u540d\uff0c\u4f46inode\u5f15\u7528\u53e6\u4e00\u4e2a\u6587\u4ef6\u540d\u800c\u4e0d\u662f\u5f15\u7528\u6570\u636e\u5757\u3002 \u67e5\u770b\u6587\u4ef6\u540d\u548cinode\u4e4b\u95f4\u5173\u7cfb\u7684\u4e00\u4e2a\u65b9\u6cd5\u662f\u4f7f\u7528 ls -il \u547d\u4ee4\u3002inode\u7684\u5178\u578b\u5927\u5c0f\u4e3a128\u4f4d\uff0c\u6570\u636e\u5757\u7684\u5927\u5c0f\u8303\u56f4\u53ef\u4ee5\u662f1k\uff0c2k\uff0c4k\u6216\u66f4\u5927\uff0c\u5177\u4f53\u53d6\u51b3\u4e8e\u6587\u4ef6\u7cfb\u7edf\u7c7b\u578b\u3002 \u8f6f\u8fde\u63a5\u53ef\u4ee5\u9488\u5bf9\u76ee\u5f55\uff0c\u786c\u8fde\u63a5\u53ea\u80fd\u9488\u5bf9\u6587\u4ef6\u3002 \u786c\u94fe\u63a5\u76f8\u5f53\u4e8e\u589e\u52a0\u4e86\u4e00\u4e2a\u767b\u8bb0\u9879\uff0c\u4f7f\u5f97\u539f\u6765\u7684\u6587\u4ef6\u591a\u4e86\u4e00\u4e2a\u540d\u5b57\uff0c\u81f3\u4e8einode\u90fd\u6ca1\u53d8\u3002\u6240\u8c13\u7684\u767b\u8bb0\u9879\u5176\u5b9e\u662f\u76ee\u5f55\u6587\u4ef6\u4e2d\u7684\u4e00\u4e2a\u6761\u76ee(\u76ee\u5f55\u9879)\uff0c\u4f7f\u7528hard link \u662f\u8ba9\u591a\u4e2a\u4e0d\u540c\u7684\u76ee\u5f55\u9879\u6307\u5411\u540c\u4e00\u4e2a\u6587\u4ef6\u7684inode\uff0c\u6ca1\u6709\u591a\u4f59\u7684\u5185\u5bb9\u9700\u8981\u5b58\u50a8\u5728\u78c1\u76d8\u6247\u533a\u4e2d\uff0c\u6240\u4ee5hardlink\u4e0d\u5360\u7528\u989d\u5916\u7684\u7a7a\u95f4\u3002 \u7b26\u53f7\u94fe\u63a5\u6709\u5355\u72ec\u7684inode\uff0c\u5728inode\u4e2d\u5b58\u653e\u53e6\u4e00\u4e2a\u6587\u4ef6\u7684\u8def\u5f84\u800c\u4e0d\u662f\u6587\u4ef6\u6570\u636e\uff0c\u6240\u4ee5\u7b26\u53f7\u94fe\u63a5\u4f1a\u5360\u7528\u989d\u5916\u7684\u7a7a\u95f4\u3002 \u7279\u5f81 \u786c\u94fe\u63a5 \u7b26\u53f7\u94fe\u63a5 \u672c\u8d28 \u540c\u4e00\u4e2a\u6587\u4ef6 \u4e0d\u662f\u540c\u4e00\u4e2a\u6587\u4ef6 \u8de8\u8bbe\u5907 \u4e0d\u652f\u6301 \u652f\u6301 inode \u76f8\u540c \u4e0d\u540c \u94fe\u63a5\u6570 \u521b\u5efa\u786c\u94fe\u63a5\uff0c\u94fe\u63a5\u6570\u4f1a\u589e\u52a0\uff0c\u5220\u9664\u5219\u51cf\u5c11 \u521b\u5efa\u6216\u5220\u9664\uff0c\u94fe\u63a5\u6570\u90fd\u4e0d\u53d8 \u6587\u4ef6\u5939 \u4e0d\u652f\u6301 \u652f\u6301 \u76f8\u5bf9\u8def\u5f84 \u539f\u59cb\u6587\u4ef6\u7684\u76f8\u5bf9\u8def\u5f84\u662f\u76f8\u5bf9\u4e8e\u5f53\u524d\u5de5\u4f5c\u76ee\u5f55 \u539f\u59cb\u6587\u4ef6\u7684\u76f8\u5bf9\u8def\u5f84\u662f\u76f8\u5bf9\u4e8e\u94fe\u63a5\u6587\u4ef6\u7684\u76f8\u5bf9\u8def\u5f84 \u5220\u9664\u6e90\u6587\u4ef6 \u53ea\u662f\u94fe\u63a5\u6570\u51cf\u5c11\uff0c\u94fe\u63a5\u6587\u4ef6\u8bbf\u95ee\u4e0d\u53d7\u5f71\u54cd \u94fe\u63a5\u6587\u4ef6\u5c06\u65e0\u6cd5\u8bbf\u95ee \u6587\u4ef6\u7c7b\u578b \u548c\u6e90\u6587\u4ef6\u76f8\u540c \u94fe\u63a5\u6587\u4ef6\uff0c\u548c\u6e90\u6587\u4ef6\u65e0\u5173 \u6587\u4ef6\u5927\u5c0f \u548c\u6e90\u6587\u4ef6\u76f8\u540c \u6e90\u6587\u4ef6\u7684\u8def\u5f84\u7684\u957f\u5ea6 3.3.\u8bbe\u5907\u6587\u4ef6 \u00b6 \u8bbe\u5907\u6587\u4ef6 \uff08Device File\uff09\u8868\u793a\u786c\u4ef6\uff08\u7f51\u5361\u9664\u5916\uff09\u3002 \u6bcf\u4e2a\u786c\u4ef6\u90fd\u7531\u4e00\u4e2a\u8bbe\u5907\u6587\u4ef6\u8868\u793a\u3002 \u7f51\u5361\u662f\u63a5\u53e3\u3002 \u8bbe\u5907\u6587\u4ef6\u628a\u5185\u6838\u9a71\u52a8\u548c\u7269\u7406\u786c\u4ef6\u8bbe\u5907\u8fde\u63a5\u8d77\u6765\u3002 \u5185\u6838\u9a71\u52a8\u7a0b\u5e8f\u901a\u8fc7\u5bf9\u8bbe\u5907\u6587\u4ef6\u8fdb\u884c\u8bfb\u5199\uff08\u6b63\u786e\u7684\u683c\u5f0f\uff09\u6765\u5b9e\u73b0\u5bf9\u786c\u4ef6\u7684\u8bfb\u5199\u3002 \u7c7b\u578b\uff1a \u5757\u8bbe\u5907\uff08Block Devices\uff09\uff1a\u5757\u8bbe\u5907\uff08\u901a\u5e38\uff09\u5728512\u5b57\u8282\u7684\u5927\u5757\u4e2d\u8bfb\u53d6/\u5199\u5165\u4fe1\u606f\u3002 \u5b57\u7b26\u8bbe\u5907\uff08Character Devices\uff09\uff1a\u5b57\u7b26\u8bbe\u5907\u4ee5\u5b57\u7b26\u65b9\u5f0f\u8bfb\u53d6/\u5199\u5165\u4fe1\u606f\u3002 \u5b57\u7b26\u8bbe\u5907\u76f4\u63a5\u63d0\u4f9b\u5bf9\u786c\u4ef6\u8bbe\u5907\u7684\u65e0\u7f13\u51b2\u8bbf\u95ee\u3002 \u6709\u65f6\u79f0\u4e3a\u88f8\u8bbe\u5907\uff08raw devices\uff09\u3002\uff08\u6ce8\u610f\uff1a\u88f8\u8bbe\u5907\u88ab\u89c6\u4e3a\u5b57\u7b26\u8bbe\u5907\uff0c\u4e0d\u662f\u5757\u8bbe\u5907\uff09 \u901a\u8fc7\u8f85\u4ee5\u4e0d\u540c\u9009\u9879\uff0c\u53ef\u4ee5\u5e7f\u6cdb\u800c\u591a\u6837\u5730\u5e94\u7528\u548c\u4f7f\u7528\u5b57\u7b26\u8bbe\u5907\u3002 \u5f53\u5185\u6838\u53d1\u73b0\u8bbe\u5907\u65f6\u7531\u64cd\u4f5c\u7cfb\u7edf udev \u81ea\u52a8\u521b\u5efa\u3002 3.4.\u7ec3\u4e60 \u00b6 \u76ee\u6807\uff1a\u4ee5Rocky 9\u4e3a\u4f8b\u3002 \u67e5\u770b\u8f6f/\u786c\u94fe\u63a5\u6587\u4ef6\u7684\u7279\u5f81\u3002 \u67e5\u770b\u76ee\u5f55\u7ed3\u6784\u3002 \u53ef\u4ee5\u901a\u8fc7\u4e0b\u9762\u547d\u4ee4\u5f97\u5230\u5f53\u524d\u7cfb\u7edf\u76842\u7ea7\u76ee\u5f55\u7684\u7ed3\u6784\u3002 tree -L 2 -d / \u521b\u5efa\u7ec3\u4e60\u76ee\u5f55\u3002 mkdir data mkdir -p data/typelink cd data \u521b\u5efa\u786c\u94fe\u63a5\u3002\u6ce8\u610f\uff1a file \u3001 hardlinkfile1 \u3001 hardlinkfile2 \u6587\u4ef6\u7684\u94fe\u63a5\u4f4d\u7f6e\u7684\u6570\u503c\u7684\u53d8\u5316) echo \"it's original file\" > file ln file hardlinkfile1 ln -s file symlinkfile1 ln -s file symlinkfile2 \u6267\u884c ls -l \u547d\u4ee4\u53ef\u4ee5\u5f97\u5230\u4e0b\u9762\u7684\u7ed3\u679c\uff1a -rw-r--r--. 2 vagrant wheel 19 Nov 1 10 :42 file -rw-r--r--. 2 vagrant wheel 19 Nov 1 10 :42 hardlinkfile1 lrwxrwxrwx. 1 vagrant wheel 4 Nov 1 10 :43 symlinkfile1 -> file lrwxrwxrwx. 1 vagrant wheel 4 Nov 1 10 :43 symlinkfile2 -> file \u521b\u5efa\u53e6\u5916\u4e00\u4e2a\u786c\u94fe\u63a5\u3002 ln file hardlinkfile2 \u6267\u884c ls -l \u547d\u4ee4\u53ef\u4ee5\u5f97\u5230\u4e0b\u9762\u7684\u7ed3\u679c\uff1a -rw-r--r--. 3 vagrant wheel 19 Nov 1 10 :42 file -rw-r--r--. 3 vagrant wheel 19 Nov 1 10 :42 hardlinkfile1 -rw-r--r--. 3 vagrant wheel 19 Nov 1 10 :42 hardlinkfile2 lrwxrwxrwx. 1 vagrant wheel 4 Nov 1 10 :43 symlinkfile1 -> file lrwxrwxrwx. 1 vagrant wheel 4 Nov 1 10 :43 symlinkfile2 -> file \u4fee\u6539 file \u6587\u4ef6\u7684\u5185\u5bb9\u3002 echo \"add oneline\" >> file \u901a\u8fc7\u547d\u4ee4 cat file \u67e5\u770b\u5f53\u524d file \u7684\u5185\u5bb9\u3002 it ' s original file add oneline \u901a\u8fc7\u4e0b\u9762\u7684\u547d\u4ee4\uff0c\u53ef\u4ee5\u770b\u5230\u6240\u4ee5\u8f6f/\u786c\u94fe\u63a5\u6587\u4ef6\u5185\u5bb9\u90fd\u66f4\u65b0\u4e86\uff0c\u548c file \u6587\u4ef6\u66f4\u65b0\u540e\u7684\u5185\u5bb9\u4fdd\u6301\u4e00\u81f4\u3002 cat hardlinkfile1 cat hardlinkfile2 cat symlinkfile1 cat symlinkfile2 \u5bf9\u6587\u4ef6 symlinkfile1 \u518d\u521b\u5efa\u65b0\u7684\u8f6f\u8fde\u63a5\u3002 ln -s symlinkfile1 symlinkfile1-1 \u901a\u8fc7\u547d\u4ee4 ls -il \u67e5\u770b\u73b0\u5728\u7684\u76ee\u5f55\u4fe1\u606f\u3002 67274680 -rw-r--r--. 3 vagrant wheel 31 Nov 1 11 :14 file 67274680 -rw-r--r--. 3 vagrant wheel 31 Nov 1 11 :14 hardlinkfile1 67274680 -rw-r--r--. 3 vagrant wheel 31 Nov 1 11 :14 hardlinkfile2 67274681 lrwxrwxrwx. 1 vagrant wheel 4 Nov 1 10 :43 symlinkfile1 -> file 67274683 lrwxrwxrwx. 1 vagrant wheel 12 Nov 1 11 :20 symlinkfile1-1 -> symlinkfile1 67274682 lrwxrwxrwx. 1 vagrant wheel 4 Nov 1 10 :43 symlinkfile2 -> file \u8bfb\u53d6\u8f6f\u94fe\u63a5\u6587\u4ef6\u7684\u6e90\u6587\u4ef6\u4fe1\u606f readlink symlinkfile1 readlink symlinkfile2 \u6ce8\u610f\uff0c\u5bf9\u4e8e symlinkfile1-1 \u7684\u60c5\u51b5\u6709\u4e9b\u4e0d\u540c\u3002 readlink symlinkfile1-1 \u4e0a\u9762\u547d\u4ee4\u8fd4\u56de\u7ed3\u679c symlinkfile1 \u4ecd\u7136\u662f\u4e00\u4e2a\u7b26\u53f7\u94fe\u63a5\u6587\u4ef6\u3002\u901a\u8fc7 readlink -f \u53ef\u4ee5\u76f4\u63a5\u5b9a\u4f4d\u771f\u6b63\u7684\u6e90\u6587\u4ef6\u3002 readlink -f symlinkfile1-1 \u4e0a\u9762\u7684\u8fd4\u56de\u7ed3\u679c /data/linktype/file \u662f symlinkfile1-1 \u771f\u6b63\u7684\u6e90\u6587\u4ef6\u3002 \u663e\u793a data \u76ee\u5f55\u4e0b\u7684\u6587\u4ef6\u548c\u5b50\u76ee\u5f55\uff1a cd ~ tree ./data \u8fd0\u884c\u7ed3\u679c\uff1a ./data \u251c\u2500\u2500 file \u251c\u2500\u2500 hardlinkfile1 \u251c\u2500\u2500 hardlinkfile2 \u251c\u2500\u2500 symlinkfile1 -> file \u251c\u2500\u2500 symlinkfile1-1 -> symlinkfile1 \u251c\u2500\u2500 symlinkfile2 -> file \u2514\u2500\u2500 typelink \u53ea\u663e\u793a data \u76ee\u5f55\u4e0b\u7684\u5b50\u76ee\u5f55\uff1a tree -d ./data \u8fd0\u884c\u7ed3\u679c\uff1a ./data \u2514\u2500\u2500 typelink \u663e\u793a data \u76ee\u5f55\u4e0b\u7684\u6587\u4ef6\u548c\u5b50\u76ee\u5f55\uff0c\u5305\u542b\u5168\u76ee\u5f55\uff1a tree -f ./data \u8fd0\u884c\u7ed3\u679c\uff1a ./data \u251c\u2500\u2500 ./data/file \u251c\u2500\u2500 ./data/hardlinkfile1 \u251c\u2500\u2500 ./data/hardlinkfile2 \u251c\u2500\u2500 ./data/symlinkfile1 -> file \u251c\u2500\u2500 ./data/symlinkfile1-1 -> symlinkfile1 \u251c\u2500\u2500 ./data/symlinkfile2 -> file \u2514\u2500\u2500 ./data/typelink 4.\u6587\u4ef6\u5c5e\u6027\u8bf4\u660e \u00b6 \u6267\u884c\u547d\u4ee4 ls -ihl \uff0c\u53ef\u4ee5\u5f97\u5230\u4e0b\u9762\u7684\u8f93\u51fa\u7ed3\u679c\uff08Rocky 9\uff09\u3002 67274680 -rw-r--r--. 3 vagrant wheel 31 Nov 1 11 :14 file 67274680 -rw-r--r--. 3 vagrant wheel 31 Nov 1 11 :14 hardlinkfile1 67274680 -rw-r--r--. 3 vagrant wheel 31 Nov 1 11 :14 hardlinkfile2 67274681 lrwxrwxrwx. 1 vagrant wheel 4 Nov 1 10 :43 symlinkfile1 -> file 67274683 lrwxrwxrwx. 1 vagrant wheel 12 Nov 1 11 :20 symlinkfile1-1 -> symlinkfile1 67274682 lrwxrwxrwx. 1 vagrant wheel 4 Nov 1 10 :43 symlinkfile2 -> file 33555262 drwxr-xr-x. 2 vagrant wheel 6 Nov 1 11 :30 typelink \u4ee5 67274680 -rw-r--r--. 3 vagrant wheel 31 Nov 1 11:14 file \u4e3a\u4f8b\uff1a 67274680 : inode \u7d22\u5f15\u8282\u70b9\u7f16\u53f7\u3002 -rw-r--r-- \uff1a\u6587\u4ef6\u7c7b\u578b\u53ca\u6743\u9650 - \uff1a\u6587\u4ef6\u7c7b\u578b\uff0c\u4f8b\u5b50\u4e2d\u51fa\u73b0\u4e86\u4e09\u79cd\uff0c - \uff0c l \u548c d \u3002 - \uff1a\u666e\u901a\u6587\u4ef6 d \uff1a\u76ee\u5f55 l \uff1a\u7b26\u53f7\u94fe\u63a5\u6587\u4ef6\uff08link\uff09 b \uff1a\u5757\u8bbe\u5907\uff08block\uff09 c \uff1a\u5b57\u7b26\u8bbe\u5907\uff08character\uff09 p \uff1a\u7ba1\u9053\u6587\u4ef6\uff08pipe\uff09 s \uff1a\u5957\u63a5\u5b57\u6587\u4ef6\uff08socket\uff09 rw-r--r-- \uff1a\u6587\u4ef6\u6743\u9650\uff0c\u4ece\u5de6\u5230\u53f3\u4f9d\u6b21\u4e3a\uff1a rw- \uff1a\u6587\u4ef6\u5c5e\u4e3b\u6743\u9650\uff0c\u4f8b\u5b50\u4e2d\u662f vagrant \u3002 r-- \uff1a\u6587\u4ef6\u5c5e\u7ec4\u7684\u6743\u9650\uff0c\u4f8b\u5b50\u4e2d\u662f wheel \u3002 r-- \uff1a\u5176\u4ed6\u7ec4\u7684\u6743\u9650\u3002 . \uff1a\u8fd9\u4e2a\u70b9\u8868\u793a\u6587\u4ef6\u5e26\u6709SELinux\u7684\u5b89\u5168\u4e0a\u4e0b\u6587\uff08SELinux Contexts\uff09\u3002\u5173\u95edSELinux\uff0c\u65b0\u521b\u5efa\u7684\u6587\u4ef6\u5c31\u4e0d\u4f1a\u518d\u6709\u8fd9\u4e2a\u70b9\u4e86\u3002\u4f46\u662f\uff0c\u4ee5\u524d\u521b\u5efa\u7684\u6587\u4ef6\u672c\u6765\u6709\u8fd9\u4e2a\u70b9\u7684\u8fd8\u4f1a\u663e\u793a\u8fd9\u4e2a\u70b9\uff08\u867d\u7136SELinux\u4e0d\u8d77\u4f5c\u7528\u4e86\uff09\u3002 3 \uff1a\u786c\u94fe\u63a5\u6570\uff0c\u4f8b\u5b50\u4e2d file \u548c hardlinkfile1 \u548c hardlinkfile2 \u4e4b\u95f4\u662f\u786c\u94fe\u63a5\uff0c\u6240\u4ee5\u8fd9\u4e09\u4e2a\u6587\u4ef6\u7684\u786c\u94fe\u63a5\u6570\u90fd\u662f 3 \u3002 vagrant \uff1a\u6587\u4ef6\u5c5e\u4e3b wheel \uff1a\u6587\u4ef6\u5c5e\u7ec4 31 \uff1a\u6587\u4ef6\u6216\u76ee\u5f55\u7684\u5927\u5c0f Nov 1 11:14 \uff1a\u6587\u4ef6\u6216\u76ee\u5f55\u7684\u521b\u5efa\u65e5\u671f\u548c\u65f6\u95f4 file \uff1a\u6587\u4ef6\u6216\u76ee\u5f55\u540d\u79f0 \u4e0b\u9762\u662f\u547d\u4ee4 ls -ihl \u5728openSUSE\u548cUbuntu\u4e0a\u7684\u663e\u793a\u7ed3\u679c\u3002 $ ls -ihl 233647 -rw-r--r-- 3 vagrant wheel 31 Nov 1 15 :52 file 233647 -rw-r--r-- 3 vagrant wheel 31 Nov 1 15 :52 hardlinkfile1 233647 -rw-r--r-- 3 vagrant wheel 31 Nov 1 15 :52 hardlinkfile2 233648 lrwxrwxrwx 1 vagrant wheel 4 Nov 1 15 :52 symlinkfile1 -> file 233650 lrwxrwxrwx 1 vagrant wheel 12 Nov 1 15 :52 symlinkfile1-1 -> symlinkfile1 233649 lrwxrwxrwx 1 vagrant wheel 4 Nov 1 15 :52 symlinkfile2 -> file 233646 drwxr-xr-x 1 vagrant wheel 0 Nov 1 15 :51 typelink 5.\u6807\u51c6\u8f93\u5165\u8f93\u51fa \u00b6 \u6807\u51c6\u8f93\u5165\u8f93\u51fa\uff0c\u5373I/O\uff0cI/O\u7684I\u662fInput\uff0cO\u662foutput\u3002 I\uff1a\u4ece\u5916\u90e8\u8bbe\u5907\u8f93\u5165\u5230\u5185\u5b58 O\uff1a\u4ece\u5185\u5b58\u8f93\u51fa\u5230\u5916\u90e8\u8bbe\u5907 \u6807\u51c6\u8f93\u5165\u548c\u6807\u51c6\u8f93\u51fa\u662f\u7528\u4e8eIO\u7684\uff0c\u5b83\u4eec\u5c5e\u4e8e\u5916\u90e8\u8bbe\u5907\uff08\u903b\u8f91\u4e0a\u7684\u5916\u90e8\u8bbe\u5907\uff09\uff0c\u4e0d\u662f\u5185\u5b58\u3002 linux\u4e2d\u4e00\u5207\u8bbe\u5907\u7686\u662f\u6587\u4ef6\uff01\u56e0\u6b64\u6807\u51c6\u8f93\u5165\u548c\u8f93\u51fa\u672c\u8d28\u5c31\u662f\u6587\u4ef6\uff0c\u5916\u90e8\u8bbe\u5907\u4ee5\u6587\u4ef6\u5f62\u5f0f\u8868\u73b0\u3002 \u5728Linux\u7cfb\u7edf\u4e2d\uff0c\u6807\u51c6\u8f93\u5165\u548c\u6807\u51c6\u8f93\u51fa\u5bf9\u5e94\u7684\u6587\u4ef6\u662f /dev/stdin \u548c /dev/stdout \u8fd9\u4e24\u4e2a\u6587\u4ef6\u3002 \u4ece\u6807\u51c6\u8f93\u5165\u8bfb\uff0c\u4ece\u903b\u8f91\u4e0a\u8bb2\uff0c\u5c31\u662f\u6253\u5f00 /dev/stdin \u8fd9\u4e2a\u6587\u4ef6\uff0c\u5e76\u8bfb\u5165\u6587\u4ef6\u5185\u5bb9\u3002 \u8f93\u51fa\u5230\u6807\u51c6\u8f93\u51fa\uff0c\u4ece\u903b\u8f91\u4e0a\u8bb2\uff0c\u5c31\u662f\u6253\u5f00 /dev/stdout \u8fd9\u4e2a\u6587\u4ef6\uff0c\u5e76\u628a\u5185\u5bb9\u8f93\u51fa\u5230\u8fd9\u4e2a\u6587\u4ef6\u91cc\u53bb\u3002 \u8fd9\u91cc\u5f3a\u8c03\u7684\u662f\u201c\u903b\u8f91\u4e0a\u201d\uff0c\u56e0\u4e3a /dev/stdin \u548c /dev/stdout \u8fd92\u4e2a\u6587\u4ef6\u672c\u8eab\u4e0d\u662f\u8bbe\u5907\u6587\u4ef6\u3002Linux\u4e2d\u8bbe\u5907\u662f\u6587\u4ef6\uff0c\u4f46\u662f\u6587\u4ef6\u4e0d\u4e00\u5b9a\u662f\u8bbe\u5907\u3002 \u56e0\u6b64\uff0c\u64cd\u4f5c /dev/stdin \u548c/dev/stdout`\u8fd92\u4e2a\u6587\u4ef6\uff0c\u5b9e\u9645\u4e0a\u662f\u64cd\u4f5c\u4e24\u4e2a\u6587\u4ef6\u5b58\u653e\u5730\u5740\u5bf9\u5e94\u7684\u8bbe\u5907\u6587\u4ef6\u3002 \u901a\u8fc7\u4e0b\u9762\u547d\u4ee4\u53ef\u4ee5\u770b\u5230\u6807\u51c6\u8f93\u5165\u8f93\u51fa\u6587\u4ef6\u7684\u7279\u70b9\uff0c\u4ed6\u4eec\u867d\u7136\u5728 /dev \u76ee\u5f55\u4e0b\uff0c\u90fd\u662f\u4ee5 l \u5f00\u5934\u7684\u94fe\u63a5\u6587\u4ef6\uff0c\u6307\u5411\u7684\u662f\u53e6\u4e00\u4e2a\u6587\u4ef6\u7684\u5730\u5740\u3002 $ ls -l /dev/std* lrwxrwxrwx 1 root root 15 Nov 13 10 :39 /dev/stderr -> /proc/self/fd/2 lrwxrwxrwx 1 root root 15 Nov 13 10 :39 /dev/stdin -> /proc/self/fd/0 lrwxrwxrwx 1 root root 15 Nov 13 10 :39 /dev/stdout -> /proc/self/fd/1 # Rocky $ ll /proc/self/fd/ lrwx------. 1 vagrant wheel 64 Nov 13 22 :38 0 -> /dev/pts/0 lrwx------. 1 vagrant wheel 64 Nov 13 22 :38 1 -> /dev/pts/0 lrwx------. 1 vagrant wheel 64 Nov 13 22 :38 2 -> /dev/pts/0 lr-x------. 1 vagrant wheel 64 Nov 13 22 :38 3 -> /proc/1702/fd # Ubuntu $ ll /proc/self/fd/ lrwx------ 1 vagrant sudo 64 Nov 13 14 :38 0 -> /dev/pts/0 lrwx------ 1 vagrant sudo 64 Nov 13 14 :38 1 -> /dev/pts/0 lrwx------ 1 vagrant sudo 64 Nov 13 14 :38 2 -> /dev/pts/0 lr-x------ 1 vagrant sudo 64 Nov 13 14 :38 3 -> /proc/2062/fd/ # openSUSE $ ll /proc/self/fd/* ls: cannot access '/proc/self/fd/255' : No such file or directory ls: cannot access '/proc/self/fd/3' : No such file or directory lrwx------ 1 vagrant wheel 64 Nov 13 22 :37 /proc/self/fd/0 -> /dev/pts/0 lrwx------ 1 vagrant wheel 64 Nov 13 22 :37 /proc/self/fd/1 -> /dev/pts/0 lrwx------ 1 vagrant wheel 64 Nov 13 22 :37 /proc/self/fd/2 -> /dev/pts/0 Linux\u8fdb\u7a0b\u9ed8\u8ba4\u4f1a\u6253\u5f00\u7684\u4e09\u4e2a\u6587\u4ef6\uff1a \u6807\u51c6\u8f93\u5165 /dev/stdin \uff0c\u63cf\u8ff0\u7b26\u4e3a 0\uff0c\u9ed8\u8ba4\u662f\u952e\u76d8\u8f93\u5165\u3002 \u6807\u51c6\u8f93\u51fa /dev/stdout \uff0c\u63cf\u8ff0\u7b26\u4e3a 1\uff0c\u9ed8\u8ba4\u662f\u8f93\u51fa\u5230\u5c4f\u5e55\u3002 \u6807\u51c6\u8f93\u51fa /dev/stderr \uff0c\u63cf\u8ff0\u7b26\u4e3a 2\uff0c\u9ed8\u8ba4\u662f\u8f93\u51fa\u5230\u5c4f\u5e55\u3002 \u4ee5Rocky\u4e3a\u4f8b\uff0c\u521b\u5efa file.py \u6587\u4ef6\u3002 $ cat > file.py < test.txt \u8fd0\u884c file.py \u7a0b\u5e8f\u3002 python3 file.py \u6253\u5f00\u65b0\u7684\u7ec8\u7aef\u7a97\u53e3\uff0c\u6267\u884c\u4e0b\u9762\u547d\u4ee4\uff0c\u5f97\u5230python3\u8fd9\u4e2a\u7a0b\u5e8f\u8fd0\u884c\u7684process ID\u3002\u5176\u4e2d\u53ef\u4ee5\u770b\u5230\u6709\u4e00\u4e2a\u6765\u81ea\u6587\u4ef6test.txt\u88ab\u7a0b\u5e8ffile.py\u6253\u5f00\uff08\u8f93\u5165\uff09\u3002 $ pidof python3 1739 788 $ sudo ls -l /proc/788/fd/ lr-x------. 1 root root 64 Nov 13 23 :00 0 -> /dev/null l-wx------. 1 root root 64 Nov 13 23 :00 1 -> /dev/null lrwx------. 1 root root 64 Nov 13 23 :00 10 -> 'socket:[24677]' lrwx------. 1 root root 64 Nov 13 23 :00 11 -> 'socket:[24678]' l-wx------. 1 root root 64 Nov 13 23 :00 2 -> /dev/null l-wx------. 1 root root 64 Nov 13 10 :41 3 -> /var/log/firewalld lrwx------. 1 root root 64 Nov 13 23 :00 4 -> 'socket:[23421]' lrwx------. 1 root root 64 Nov 13 23 :00 5 -> 'anon_inode:[eventfd]' lrwx------. 1 root root 64 Nov 13 23 :00 6 -> 'socket:[24586]' lr-x------. 1 root root 64 Nov 13 23 :00 7 -> anon_inode:inotify lrwx------. 1 root root 64 Nov 13 23 :00 8 -> 'anon_inode:[eventfd]' lrwx------. 1 root root 64 Nov 13 23 :00 9 -> '/memfd:libffi (deleted)' $ sudo ls -l /proc/1739/fd/ lrwx------. 1 vagrant wheel 64 Nov 13 23 :00 0 -> /dev/pts/0 lrwx------. 1 vagrant wheel 64 Nov 13 23 :00 1 -> /dev/pts/0 lrwx------. 1 vagrant wheel 64 Nov 13 23 :00 2 -> /dev/pts/0 lr-x------. 1 vagrant wheel 64 Nov 13 23 :00 3 -> /home/vagrant/test.txt \u5728Ubuntu\u4e2d\u8fd0\u884c file.py \u7a0b\u5e8f\uff0cpidof\u4f1a\u53d6\u5f973\u4e2aprocess IDs\u3002 $ pidof python3 2128 924 873 $ sudo ls -l /proc/2128/fd/ lrwx------ 1 vagrant sudo 64 Nov 13 15 :10 0 -> /dev/pts/0 lrwx------ 1 vagrant sudo 64 Nov 13 15 :10 1 -> /dev/pts/0 lrwx------ 1 vagrant sudo 64 Nov 13 15 :10 2 -> /dev/pts/0 lr-x------ 1 vagrant sudo 64 Nov 13 15 :10 3 -> /home/vagrant/test.txt $ sudo ls -l /proc/924/fd/ lr-x------ 1 root root 64 Nov 13 15 :11 0 -> /dev/null lrwx------ 1 root root 64 Nov 13 15 :11 1 -> 'socket:[31593]' lrwx------ 1 root root 64 Nov 13 15 :11 2 -> 'socket:[31593]' l-wx------ 1 root root 64 Nov 13 02 :40 3 -> /var/log/unattended-upgrades/unattended-upgrades-shutdown.log lrwx------ 1 root root 64 Nov 13 15 :11 4 -> 'socket:[31652]' lrwx------ 1 root root 64 Nov 13 15 :11 5 -> 'anon_inode:[eventfd]' lrwx------ 1 root root 64 Nov 13 15 :11 6 -> 'anon_inode:[eventfd]' lrwx------ 1 root root 64 Nov 13 15 :11 7 -> 'socket:[31657]' l-wx------ 1 root root 64 Nov 13 15 :11 8 -> /run/systemd/inhibit/1.ref lrwx------ 1 root root 64 Nov 13 15 :11 9 -> 'socket:[31658]' $ sudo ls -l /proc/873/fd/ lr-x------ 1 root root 64 Nov 13 15 :11 0 -> /dev/null lrwx------ 1 root root 64 Nov 13 15 :11 1 -> 'socket:[31412]' lrwx------ 1 root root 64 Nov 13 15 :11 2 -> 'socket:[31412]' lrwx------ 1 root root 64 Nov 13 02 :40 3 -> 'socket:[31650]' lrwx------ 1 root root 64 Nov 13 15 :11 4 -> 'anon_inode:[eventfd]' lrwx------ 1 root root 64 Nov 13 15 :11 5 -> 'socket:[31663]' lrwx------ 1 root root 64 Nov 13 15 :11 6 -> 'socket:[31664]' openSUSE\u9700\u8981\u5b89\u88c5\u5305 sysvinit-tools \u624d\u80fd\u4f7f\u7528 pidof \u547d\u4ee4\u3002 sudo zypper in sysvinit-tools \u7531\u4e8eopenSUSE\u4e2dpidof python3\u53ea\u8fd4\u56de\u4e00\u4e2aprocess ID\uff0c\u6240\u4ee5\u53ef\u4ee5\u7b80\u5316\u547d\u4ee4\u884c\u5f97\u5230process ID\u7684\u8be6\u7ec6\u4fe1\u606f\u3002 $ sudo ls -l /proc/ ` pidof python3 ` /fd/ lrwx------ 1 vagrant wheel 64 Nov 13 23 :21 0 -> /dev/pts/0 lrwx------ 1 vagrant wheel 64 Nov 13 23 :21 1 -> /dev/pts/0 lrwx------ 1 vagrant wheel 64 Nov 13 23 :21 2 -> /dev/pts/0 lr-x------ 1 vagrant wheel 64 Nov 13 23 :21 3 -> /home/vagrant/test.txt \u53c2\u8003\uff1a \u5f53\u952e\u76d8\u548c\u9f20\u6807\u7b49\u8bbe\u5907\u901a\u8fc7\u4e32\u53e3\u76f4\u63a5\u8fde\u63a5\u5230\u8ba1\u7b97\u673a\u65f6\uff0c\u8fd9\u79cd\u8fde\u63a5\u79f0\u4e3aTTY\u3002 \u4f2a\u7ec8\u7aefpseudoterminal\uff08\u7f29\u5199\u4e3a\u201cpty\u201d\uff09\u662f\u4e00\u5bf9\u63d0\u4f9b\u53cc\u5411\u901a\u4fe1\u901a\u9053\u7684\u865a\u62df\u5b57\u7b26\u8bbe\u5907\u3002 \u901a\u9053\u7684\u4e00\u7aef\u79f0\u4e3a\u4e3b\u7aefmaster\uff1b \u53e6\u4e00\u7aef\u79f0\u4e3a\u4ece\u7aefslave\u3002 /dev/pts \u8868\u793a\u4e0e\u4f2a\u7ec8\u7aefpseudoterminal\u7684\u4e3b\u7aefmaster\u6216\u4ece\u7aefslave\u76f8\u5173\u7684master\u6587\u4ef6\uff0c\u64cd\u4f5c\u7cfb\u7edf\u5c06\u5176\u4fdd\u5b58\u4e3a /dev/ptmx \u6587\u4ef6\u3002 telnet \u548c ssh \u7b49\u7a0b\u5e8f\u80fd\u591f\u4eff \u7aef\u7528\u6237> \u4e0e\u5b83\u4eec\u7684\u4ea4\u4e92\uff0c\u867d\u7136\u672c\u8d28\u4e0a\u662f\u4e0e\u6587\u4ef6 /dev/ptmx \u8fdb\u884c\u4ea4\u4e92\uff0c\u4f46\u5448\u73b0\u7ed9\u7528\u6237\u7684\u5374\u662f\u597d\u50cf\u8fd0\u884c\u5728\u771f\u6b63\u7684\u7ec8\u7aef\u7a97\u53e3\u4e00\u6837\uff0c\u4ece\u7aef\u7684\u6587\u4ef6\u662f\u4e3b\u7aef\u7684\u8f93\u5165\u3002 \u4f2a\u7ec8\u7aef\u8fdb\u7a0b\u5728Linux\u4e2d\u88ab\u5b58\u50a8\u5728 /dev/pts/ \u76ee\u5f55\u4e0b\u3002 /dev/pts/ \u76ee\u5f55\u4e0b\u7684\u5185\u5bb9\u662f\u4e00\u4e9b\u7279\u6b8a\u7684\u76ee\u5f55\uff0c\u7531Linux\u5185\u6838\u6240\u521b\u5efa\u3002 \u6bcf\u4e2a\u552f\u4e00\u7684\u7ec8\u7aef\u7a97\u53e3\u90fd\u4e0e /dev/pts \u7cfb\u7edf\u4e2d\u7684\u4e00\u4e2aLinux pts \u6761\u76ee\u76f8\u5173\u3002 \u4e0b\u9762\u8fd4\u56de\u7684\u7ed3\u679c\u8bf4\u660e\u67092\u4e2a\u8fdc\u7a0b\u7ec8\u7aef\u8fde\u63a5\u5230\u5f53\u524d\u7684\u673a\u5668\u3002 $ ll /dev/pts/ crw--w----. 1 vagrant tty 136 , 0 Nov 13 23 :18 0 crw--w----. 1 vagrant tty 136 , 1 Nov 13 23 :48 1 c---------. 1 root root 5 , 2 Nov 13 10 :41 ptmx \u4e5f\u53ef\u4ee5\u901a\u8fc7 w \u547d\u4ee4\u770b\u52302\u4e2a\u7ec8\u7aef\u8fdb\u7a0b\u3002 $ w 23 :55:05 up 13 :14, 2 users, load average: 0 .00, 0 .00, 0 .00 USER TTY LOGIN@ IDLE JCPU PCPU WHAT vagrant pts/0 10 :51 37 :03 0 .05s 0 .05s -bash vagrant pts/1 23 :48 0 .00s 0 .03s 0 .00s w \u5355\u4e2a\u4f2a\u7ec8\u7aefpseudoterminal\u53ef\u4ee5\u540c\u65f6\u63a5\u6536\u6765\u81ea\u4e0d\u540c\u7684\u7a0b\u5e8f\u7684\u8f93\u51fa\u3002 \u591a\u4e2a\u7a0b\u5e8f\u540c\u65f6\u5bf9\u4e00\u4e2a\u4f2a\u7ec8\u7aefpseudoterminal\u8fdb\u884c\u8bfb\u53d6\u4f1a\u5f15\u8d77\u6df7\u6dc6\u3002 \u5b58\u50a8\u5728 /dev/pts \u76ee\u5f55\u4e2d\u7684\u6587\u4ef6\u662f\u62bd\u8c61\u6587\u4ef6\u800c\u4e0d\u662f\u771f\u5b9e\u6587\u4ef6\uff0c\u662f\u4f2a\u7ec8\u7aef\u4e2d\u6267\u884c\u7a0b\u5e8f\u65f6\u4e34\u65f6\u5b58\u50a8\u7684\u6570\u636e\u3002 \u6253\u5f00 /dev/pts \u4e0b\u7684\u6587\u4ef6\u901a\u5e38\u6ca1\u6709\u4ec0\u4e48\u5b9e\u9645\u610f\u4e49\u3002 6.\u91cd\u5b9a\u5411\u548c\u7ba1\u9053 \u00b6 6.1.\u8f93\u5165\u91cd\u5b9a\u5411 \u00b6 \u5e38\u7528\u547d\u4ee4\u683c\u5f0f\uff1a command < file \uff1a\u5c06\u6307\u5b9a\u6587\u4ef6 file \u4f5c\u4e3a\u547d\u4ee4\u7684\u8f93\u5165\u8bbe\u5907\u3002 command << delimiter \uff1a\u8868\u793a\u4ece\u6807\u51c6\u8f93\u5165\u8bbe\u5907\uff08\u952e\u76d8\uff09\u4e2d\u8bfb\u5165\uff0c\u76f4\u5230\u9047\u5230\u5206\u754c\u7b26 delimiter \u505c\u6b62\uff08\u8bfb\u5165\u7684\u6570\u636e\u4e0d\u5305\u62ec\u5206\u754c\u7b26\uff09\uff0c\u8fd9\u91cc\u7684\u5206\u754c\u7b26\u53ef\u4ee5\u7406\u89e3\u4e3a\u81ea\u5b9a\u4e49\u7684\u5b57\u7b26\u4e32\u3002 command < file1 > file2 \uff1a\u5c06 file1 \u4f5c\u4e3a\u547d\u4ee4\u7684\u8f93\u5165\u8bbe\u5907\uff0c\u8be5\u547d\u4ee4\u7684\u6267\u884c\u7ed3\u679c\u8f93\u51fa\u5230 file2 \u4e2d\u3002 # \u8f93\u51fa\u6587\u4ef6file.py\u5185\u5bb9\uff08\u8f93\u5165\u8bbe\u5907\u662f\u952e\u76d8\uff09 $ cat file.py # \u8f93\u51fa\u6587\u4ef6file.py\u5185\u5bb9\uff08\u8f93\u5165\u8bbe\u5907\u662f\u6587\u4ef6file.py\uff09 $ cat < file.py # \u6307\u5b9a\u5206\u754c\u7b26\uff08\u8fd9\u91cc\u662fEOF\uff09\uff0c\u8bfb\u53d6\u952e\u76d8\u8f93\u5165\u5185\u5bb9\uff0c\u76f4\u5230\u9047\u5230\u6307\u5b9a\u5206\u754c\u7b26\u4e3a\u6b62\uff0c\u5c06\u6240\u8bfb\u53d6\u7684\u5185\u5bb9\u8f93\u51fa\u5230\u6587\u4ef6file.py\u3002 $ cat > file.py < new.py 6.2.\u8f93\u51fa\u91cd\u5b9a\u5411 \u00b6 \u8f93\u51fa\u91cd\u5b9a\u5411\u5206\u4e3a\u6807\u51c6\u8f93\u51fa\u91cd\u5b9a\u5411\u548c\u9519\u8bef\u8f93\u51fa\u91cd\u5b9a\u5411\u4e24\u79cd\u3002 \u5e38\u7528\u547d\u4ee4\u683c\u5f0f\uff1a command > file \uff1a\u5c06\u547d\u4ee4 command \u6267\u884c\u7684\u6807\u51c6\u8f93\u51fa\u7ed3\u679c\u91cd\u5b9a\u5411\u8f93\u51fa\u5230\u6307\u5b9a\u7684\u6587\u4ef6 file \u4e2d\uff0c\u5982\u679c\u8be5\u6587\u4ef6\u5df2\u5305\u542b\u6570\u636e\uff0c\u4f1a\u6e05\u7a7a\u539f\u6709\u6570\u636e\uff0c\u518d\u5199\u5165\u65b0\u6570\u636e\u3002 command 2> file \uff1a\u5c06\u547d\u4ee4 command \u6267\u884c\u7684\u9519\u8bef\u8f93\u51fa\u7ed3\u679c\u91cd\u5b9a\u5411\u5230\u6307\u5b9a\u7684\u6587\u4ef6 file \u4e2d\uff0c\u5982\u679c\u8be5\u6587\u4ef6\u4e2d\u5df2\u5305\u542b\u6570\u636e\uff0c\u4f1a\u6e05\u7a7a\u539f\u6709\u6570\u636e\uff0c\u518d\u5199\u5165\u65b0\u6570\u636e\u3002 command >> file \uff1a\u5c06\u547d\u4ee4 command \u6267\u884c\u7684\u6807\u51c6\u8f93\u51fa\u7ed3\u679c\u91cd\u5b9a\u5411\u8f93\u51fa\u5230\u6307\u5b9a\u7684\u6587\u4ef6 file \u4e2d\uff0c\u5982\u679c\u8be5\u6587\u4ef6\u5df2\u5305\u542b\u6570\u636e\uff0c\u65b0\u6570\u636e\u5c06\u8ffd\u52a0\u5199\u5165\u5230\u539f\u6709\u5185\u5bb9\u7684\u540e\u9762\u3002 command 2>> file \uff1a\u5c06\u547d\u4ee4 command \u6267\u884c\u7684\u9519\u8bef\u8f93\u51fa\u7ed3\u679c\u91cd\u5b9a\u5411\u5230\u6307\u5b9a\u7684\u6587\u4ef6 file \u4e2d\uff0c\u5982\u679c\u8be5\u6587\u4ef6\u4e2d\u5df2\u5305\u542b\u6570\u636e\uff0c\u65b0\u6570\u636e\u5c06\u8ffd\u52a0\u5199\u5165\u5230\u539f\u6709\u5185\u5bb9\u7684\u540e\u9762\u3002 command >> file 2>&1 \u6216\u8005 command &>> file \uff1a\u5c06\u6807\u51c6\u8f93\u51fa\u6216\u8005\u9519\u8bef\u8f93\u51fa\u5199\u5165\u5230\u6307\u5b9a\u6587\u4ef6 file \u4e2d\uff0c\u5982\u679c\u8be5\u6587\u4ef6\u4e2d\u5df2\u5305\u542b\u6570\u636e\uff0c\u65b0\u6570\u636e\u5c06\u8ffd\u52a0\u5199\u5165\u5230\u539f\u6709\u5185\u5bb9\u7684\u540e\u9762\u3002 \u6ce8\u610f\uff1a\u4e0a\u9762\u7684 file \u53ef\u4ee5\u662f\u4e00\u4e2a\u666e\u901a\u6587\u4ef6\uff0c\u4e5f\u53ef\u4ee5\u4f7f\u7528\u4e00\u4e2a\u7279\u6b8a\u7684\u6587\u4ef6 /dev/null \u3002 /dev/null \u5e76\u4e0d\u4fdd\u5b58\u6570\u636e\uff0c\u88ab\u5199\u5165 /dev/null \u7684\u6570\u636e\u6700\u7ec8\u90fd\u4f1a\u4e22\u5931\u3002 \u4e3e\u4f8b\uff1a2\u4e2apython\u6587\u4ef6\u5b58\u5728\uff0c\u5176\u4ed62\u4e2a\u65e0\u6269\u5c55\u540d\u7684\u6587\u4ef6\u4e0d\u5b58\u5728\u3002 ls file.py > out ls file 2 > out.err ls new.py >> out ls new 2 >> out.err \u53ef\u4ee5\u5f97\u5230\u9884\u671f\u7684\u7ed3\u679c\u3002\u4e24\u4e2a\u9519\u8bef\u8bb0\u5f55\u90fd\u88ab\u8ffd\u52a0\u5230 out.err \u6587\u4ef6\u4e2d\u3002\u4e24\u4e2a\u6210\u529f\u6267\u884c\u7684\u547d\u4ee4\u7684\u8fd4\u56de\u7ed3\u679c\u4e5f\u8f93\u51fa\u5230 out \u6587\u4ef6\u4e2d\u3002 $ccat out file.py new.py $ cat out.err ls: cannot access 'file' : No such file or directory ls: cannot access 'new' : No such file or directory \u4e0a\u4f8b\u547d\u4ee4\u4e5f\u53ef\u4ee5\u5408\u5e76\u3002 ls file.py > out 2 > out.err ls file >> out 2 >> out.err 2>&1 \u683c\u5f0f\u4e3e\u4f8b\uff1a $ ls file >> out.txt 2 > & 1 $ cat out.txt ls: cannot access 'file' : No such file or directory $ ls file.py & >> out.txt $ cat out.txt ls: cannot access 'file' : No such file or directory file.py 6.3.\u7279\u6b8a\u91cd\u5b9a\u5411 \u00b6 \u683c\u5f0f\uff1a command1 < <(command2) tr 'a-z' 'A-Z' < < ( echo \"Hello World\" ) \u5e94\u7528\uff1a\u4fee\u6539\u5bc6\u7801 \u5bc6\u7801\u4fdd\u5b58\u5728 passwd.txt \u6587\u4ef6\u4e2d\uff0c\u5e76\u4e25\u683c\u9650\u5236\u6539\u6587\u4ef6\u7684\u6743\u9650\u3002 \u901a\u8fc7\u53c2\u6570 --stdin \u5b9e\u73b0\u6a21\u62df\u952e\u76d8\u8f93\u5165\u64cd\u4f5c\u8f93\u5165\u7528\u6237\u540d\u3002 \u5728Rocky\u4e2d\u53ef\u4ee5\u4f7f\u7528 --stdin \u53c2\u6570\u3002 passwd --stdin vagrant < passwd.txt \u5728openSUSE\u548cUbuntu\u4e2d\uff0c --stdin \u53c2\u6570\u65e0\u6cd5\u8bc6\u522b\u3002\u53ef\u4ee5\u6539\u7528\u4e0b\u9762\u7684\u65b9\u6cd5\u3002 echo passwd.txt | chpasswd \u5176\u4e2dpasswd.txt\u7684\u683c\u5f0f\u4e3a username:password \u3002 \u53c2\u8003\uff1a Here-document(Here-doc)\uff1a\u8f93\u5165\u7684\u6587\u672c\u5757\u91cd\u5b9a\u5411\u81f3\u6807\u51c6\u8f93\u5165\u6d41\uff0c\u76f4\u81f3\u9047\u5230\u7279\u6b8a\u7684\u6587\u4ef6\u7ed3\u675f\u6807\u8bb0\u7b26\u4e3a\u6b62\uff08\u6587\u4ef6\u7ed3\u675f\u6807\u8bb0\u7b26\u53ef\u4ee5\u662f\u4efb\u610f\u7684\u552f\u4e00\u7684\u5b57\u7b26\u4e32\uff0c\u4f46\u5927\u90e8\u5206\u4eba\u90fd\u9ed8\u8ba4\u4f7f\u7528 EOF \uff09\u3002 cat < \u5c06\u547d\u4ee4\u4e0e\u6587\u4ef6\u8fde\u63a5\u8d77\u6765\uff0c\u7528\u6587\u4ef6\u6765\u63a5\u6536\u547d\u4ee4\u7684\u8f93\u51fa\uff1b\u800c\u7ba1\u9053\u7b26 | \u5c06\u547d\u4ee4\u4e0e\u547d\u4ee4\u8fde\u63a5\u8d77\u6765\uff0c\u7528\u53f3\u8fb9\u547d\u4ee4\u6765\u63a5\u6536\u5de6\u8fb9\u547d\u4ee4\u7684\u8f93\u51fa\u3002 $ ls | tr 'a-z' 'A-Z' BIN F1.TXT F2.TXT FILE.PY NEW.PY OUT OUT.ERR TEST.TXT","title":"\u7b2c\u4e8c\u7ae0 \u6587\u4ef6\u7cfb\u7edf"},{"location":"linux/SRE/02-filesystem/#_1","text":"\u6587\u4ef6\u7cfb\u7edf\u5c42\u6b21\u6807\u51c6\uff08Filesystem Hierarchy Standard, FHS\uff09\uff0c\u5b83\u662fLinux \u6807\u51c6\u5e93\uff08Linux Standards Base, LSB\uff09\u89c4\u8303\u7684\u4e00\u90e8\u5206\u3002 \u6839\u76ee\u5f55 / \u6307\u6587\u4ef6\u7cfb\u7edf\u6811\u7684\u6700\u9ad8\u5c42\u3002 \u6839\u5206\u533a\u5728\u7cfb\u7edf\u542f\u52a8\u65f6\u9996\u5148\u6302\u8f7d\u3002 \u7cfb\u7edf\u542f\u52a8\u65f6\u8fd0\u884c\u7684\u6240\u6709\u7a0b\u5e8f\u90fd\u5fc5\u987b\u5728\u6b64\u5206\u533a\u4e2d\u3002","title":"\u7b2c\u4e8c\u7ae0 \u6587\u4ef6\u7cfb\u7edf"},{"location":"linux/SRE/02-filesystem/#1","text":"\u4ee5\u4e0b\u76ee\u5f55\u5fc5\u987b\u5728\u6839\u5206\u533a\u4e2d\uff1a /bin - \u7528\u6237\u57fa\u672c\u7a0b\u5e8f\u3002 \u5305\u542b\u672a\u6302\u8f7d\u5176\u4ed6\u6587\u4ef6\u7cfb\u7edf\u65f6\u6240\u9700\u7684\u53ef\u6267\u884c\u6587\u4ef6\u3002 \u4f8b\u5982\uff0c\u7cfb\u7edf\u542f\u52a8\u3001\u5904\u7406\u6587\u4ef6\u548c\u914d\u7f6e\u6240\u9700\u7684\u7a0b\u5e8f\u3002 \u4e0d\u80fd\u5173\u8054\u5230\u72ec\u7acb\u5206\u533a\uff0c\u64cd\u4f5c\u7cfb\u7edf\u542f\u52a8\u5373\u4f1a\u8c03\u7528\u7684\u7a0b\u5e8f\u3002 /bin/bash - bash \u811a\u672c\u5904\u7406 /bin/cat - \u663e\u793a\u6587\u4ef6\u5185\u5bb9 /bin/cp - \u62f7\u8d1d\u6587\u4ef6 /bin/dd - \u62f7\u8d1d\u6587\u4ef6\uff08\u57fa\u4e8e\u5b57\u8282byte\uff09 /bin/gzip - \u538b\u7f29\u6587\u4ef6 /bin/mount - \u6302\u8f7d\u6587\u4ef6\u7cfb\u7edf /bin/rm - \u5220\u9664\u6587\u4ef6 /bin/vi - \u6587\u4ef6\u7f16\u8f91 /sbin - \u7cfb\u7edf\u57fa\u672c\u7a0b\u5e8f\u3002 \u5305\u542b\u57fa\u672c\u7cfb\u7edf\u7ba1\u7406\u7684\u7a0b\u5e8f\u3002 \u9ed8\u8ba4\u662froot\u7528\u6237\u6709\u6743\u9650\u6267\u884c\uff0c\u56e0\u6b64\u5b83\u4e0d\u5728\u5e38\u89c4\u7528\u6237\u8def\u5f84\u4e2d\u3002 \u4e0d\u80fd\u5173\u8054\u5230\u72ec\u7acb\u5206\u533a\uff0c\u64cd\u4f5c\u7cfb\u7edf\u542f\u52a8\u5373\u4f1a\u8c03\u7528\u7684\u7a0b\u5e8f \u4e00\u4e9b\u91cd\u8981\u7ba1\u7406\u7a0b\u5e8f\uff1a /sbin/fdisk* - \u7ba1\u7406\u786c\u76d8\u5206\u533a /sbin/fsck* - \u6587\u4ef6\u7cfb\u7edf\u68c0\u67e5\u3002\u4e0d\u80fd\u5728\u8fd0\u884c\u7684\u7cfb\u7edf\u4e0a\u9762\u76f4\u63a5\u6267\u884c fsck \uff0c\u635f\u574f\u6839\u6587\u4ef6\u7cfb\u7edf\uff0c\u6267\u884c\u524d\u9700\u8981 umount \u3002 /sbin/mkfs - \u521b\u5efa\u6587\u4ef6\u7cfb\u7edf /sbin/shutdown - \u5173\u95ed\u7cfb\u7edf /dev - \u8bbe\u5907\u6587\u4ef6 \u4ee5\u592a\u7f51\u5361\u662f\u5185\u6838\u6a21\u5757\uff0c\u5176\u4ed6\u786c\u4ef6\u90fd\u4ee5\u8bbe\u5907dev\u7684\u65b9\u5f0f\u5c55\u73b0\u3002 \u5e94\u7528\u7a0b\u5e8f\u8bfb\u53d6\u548c\u5199\u5165\u8fd9\u4e9b\u6587\u4ef6\u4ee5\u64cd\u4f5c\u4f7f\u7528\u786c\u4ef6\u7ec4\u4ef6\u3002 \u4e24\u79cd\u7c7b\u578b\u8bbe\u5907\u6587\u4ef6\uff1a \u5b57\u7b26\u8bbe\u5907\uff08Character-oriented\uff09\u2013 \u5e8f\u5217\u8bbe\u5907\uff08\u6253\u5370\u673a\uff0c\u78c1\u5e26\u673a\uff0c\u9f20\u6807\u7b49\uff09 \u5757\u8bbe\u5907\uff08Block-oriented\uff09\u2013 \u786c\u76d8\uff0cDVD\u7b49 \u4e0e\u8bbe\u5907\u9a71\u52a8\u7a0b\u5e8f\u7684\u8fde\u63a5\u901a\u8fc7\u5185\u6838\u4e2d\u79f0\u4e3a\u4e3b\u8bbe\u5907\u53f7\u7684\u901a\u9053\u5b9e\u73b0\u3002 \u8fc7\u53bb\uff0c\u8fd9\u4e9b\u6587\u4ef6\u662f\u4f7f\u7528 mknod \u547d\u4ee4\u624b\u52a8\u521b\u5efa\u7684\u3002 \u73b0\u5728\u5f53\u5185\u6838\u53d1\u73b0\u8bbe\u5907\u65f6\uff0c\u5b83\u4eec\u4f1a\u7531 udev \u81ea\u52a8\u521b\u5efa\u3002 \u4e00\u4e9b\u91cd\u8981\u7684\u8bbe\u5907\u6587\u4ef6\uff1a Null\u8bbe\u5907: - /dev/null Zero\u8bbe\u5907: - /dev/zero \u7cfb\u7edf\u7ec8\u7aef: - /dev/console \u865a\u62df\u7ec8\u7aef: - /dev/tty1 \u4e32\u884c\u7aef\u53e3 - /dev/ttyS0 \u5e76\u884c\u7aef\u53e3: - /dev/lp0 \u8f6f\u76d8\u9a71\u52a8\u5668: - /dev/fd0 \u786c\u76d8\u9a71\u52a8\u5668: - /dev/sda \u786c\u76d8\u5206\u533a: - /dev/sda1 CD-ROM\u9a71\u52a8\u5668: - /dev/scd0 /etc - \u914d\u7f6e\u6587\u4ef6 \u5b58\u653e\u7cfb\u7edf\u548c\u670d\u52a1\u7684\u914d\u7f6e\u6587\u4ef6\u3002 \u5927\u90e8\u5206\u90fd\u662fASCII\u6587\u4ef6 \u666e\u901a\u7528\u6237\u53ef\u4ee5\u9ed8\u8ba4\u8bfb\u53d6\u5176\u4e2d\u7684\u5927\u90e8\u5206\u5185\u5bb9\u3002 \u8fd9\u4f1a\u5e26\u6765\u4e00\u4e2a\u6f5c\u5728\u7684\u5168\u95ee\u9898\uff0c\u56e0\u4e3a\u5176\u4e2d\u4e00\u4e9b\u6587\u4ef6\u5305\u542b\u5bc6\u7801\uff0c\u56e0\u6b64\u91cd\u8981\u7684\u662f\u8981\u786e\u4fdd\u8fd9\u4e9b\u6587\u4ef6\u53ea\u80fd\u7531root\u7528\u6237\u8bfb\u53d6\u3002 \u6839\u636eFHS\u6807\u51c6\uff0c\u6b64\u5904\u4e0d\u80fd\u653e\u7f6e\u4efb\u4f55\u53ef\u6267\u884c\u6587\u4ef6\uff0c\u4f46\u5b50\u76ee\u5f55\u53ef\u80fd\u5305\u542bshell\u811a\u672c\u3002 \u51e0\u4e4e\u6bcf\u4e2a\u5df2\u5b89\u88c5\u7684\u670d\u52a1\u5728 /etc \u6216\u5176\u5b50\u76ee\u5f55\u4e2d\u81f3\u5c11\u6709\u4e00\u4e2a\u914d\u7f6e\u6587\u4ef6\u3002 \u4e00\u4e9b\u91cd\u8981\u7684\u914d\u7f6e\u6587\u4ef6: /etc/os-release - \u7cfb\u7edf\u7248\u672c\u4fe1\u606f /etc/DIR_COLORS - ls \u547d\u4ee4\u4e2d\u7684\u989c\u8272\u914d\u7f6e\u4fe1\u606f\uff08openSUSE\u548cRocky\uff09 /etc/fstab - \u914d\u7f6e\u8981\u6302\u8f7d\u7684\u6587\u4ef6\u7cfb\u7edf /etc/profile - Shell\u767b\u5f55\u811a\u672c /etc/passwd - \u7528\u6237\u4fe1\u606f\u96c6\u5408\uff08\u4e0d\u542b\u5bc6\u7801\uff09 /etc/shadow - \u5bc6\u7801\u548c\u76f8\u5173\u4fe1\u606f /etc/group - \u7528\u6237\u7ec4\u4fe1\u606f\u96c6\u5408 /etc/cups/* - \u7528\u4e8eCUPS\u6253\u5370\u7cfb\u7edf\uff08CUPS=Common UNIX Printing System\uff09 /etc/hosts - \u4e3b\u673a\u540d\u673a\u5668IP\u5730\u5740 /etc/motd - \u767b\u5f55\u540e\u663e\u793a\u7684\u6b22\u8fce\u4fe1\u606f /etc/issue - \u767b\u5f55\u524d\u663e\u793a\u7684\u6b22\u8fce\u4fe1\u606f /etc/sysconfig/* - \u7cfb\u7edf\u914d\u7f6e\u6587\u4ef6 /lib - \u5e93\uff08Libraries\uff09 \u8bb8\u591a\u7a0b\u5e8f\u90fd\u5177\u6709\u4e00\u4e9b\u901a\u7528\u529f\u80fd\u3002 \u8fd9\u4e9b\u901a\u7528\u529f\u80fd\u53ef\u4ee5\u4fdd\u5b58\u5728\u5171\u4eab\u5e93\u4e2d\u3002 \u5171\u4eab\u5e93\u4e2d\u6587\u4ef6\u7684\u6269\u5c55\u540d\u662f .so \u3002 \u76ee\u5f55 /lib \u5305\u542b\u7684\u5171\u4eab\u5e93\u6587\u4ef6\u4e3b\u8981\u662f\u88ab /bin \u548c /sbin \u76ee\u5f55\u5305\u542b\u7684\u7a0b\u5e8f\u6240\u8c03\u7528\u3002 \u76ee\u5f55 /lib \u7684\u5b50\u76ee\u5f55\u5305\u542b\u4e00\u4e9b\u989d\u5916\u9700\u8981\u7684\u5171\u4eab\u5e93\u3002 \u5185\u6838\u6a21\u5757\u5b58\u50a8\u5728\u76ee\u5f55 /lib/modules \u3002 /lib64 - 64\u4f4d\u5171\u4eab\u5e93\uff0864-Bit Libraries\uff09\uff0c\u7c7b\u4f3c\u76ee\u5f55 /lib \u3002 \u8fd9\u4e2a\u76ee\u5f55\u56e0\u7cfb\u7edf\u67b6\u6784\u4e0d\u540c\u800c\u4e0d\u540c\u3002 \u4e00\u4e9b\u7cfb\u7edf\u652f\u6301\u4e0d\u540c\u7684\u4e8c\u8fdb\u5236\u683c\u5f0f\u5e76\u4fdd\u7559\u540c\u4e00\u4e2a\u5171\u4eab\u5e93\u7684\u4e0d\u540c\u7248\u672c\u3002 /usr - \u5305\u542b\u5e94\u7528\u7a0b\u5e8f\u3001\u56fe\u5f62\u754c\u9762\u6587\u4ef6\u3001\u5e93\u3001\u672c\u5730\u7a0b\u5e8f\u3001\u6587\u6863\u7b49\u3002 /usr \u5373 Unix System Resources. \u4f8b\u5982\uff1a /usr/X11R6/ - X Window \u7cfb\u7edf\u6587\u4ef6 /usr/bin/ - \u51e0\u4e4e\u5305\u542b\u6240\u6709\u53ef\u6267\u884c\u6587\u4ef6 /usr/lib/ - \u5305\u542b\u5e93\u548c\u5e94\u7528\u7a0b\u5e8f /usr/lib64/ - \u5305\u542b64\u4f4d\u5e93\u548c\u5e94\u7528\u7a0b\u5e8f /usr/include/ - \u5305\u542bC\u7a0b\u5e8f\u7684\u5934\u6587\u4ef6\uff08head file\uff09 /usr/local/ - \u5305\u542b\u672c\u5730\u5b89\u88c5\u7a0b\u5e8f\u3002\u8fd9\u4e2a\u76ee\u5f55\u4e0b\u7684\u5185\u5bb9\u4e0d\u4f1a\u88ab\u7cfb\u7edf\u5347\u7ea7\u6240\u8986\u76d6\u3002\u4e0b\u97623\u4e2a\u76ee\u5f55\u5728\u521d\u59cb\u5b89\u88c5\u540e\u662f\u7a7a\u7684\u3002 /usr/local/bin - /usr/local/sbin - /usr/local/lib - /usr/sbin/ - \u7cfb\u7edf\u7ba1\u7406\u7a0b\u5e8f /usr/src/ - \u5185\u6838\u548c\u5e94\u7528\u7a0b\u5e8f\u7684\u6e90\u4ee3\u7801 /usr/src/linux - /usr/share/ - \u7ed3\u6784\u5316\u72ec\u7acb\u6570\u636e /usr/share/doc/ - \u6587\u6863 /usr/share/man/ - man \u547d\u4ee4\u4f7f\u7528\u7684\u5185\u5bb9 /opt - \u7b2c\u4e09\u65b9\u5e94\u7528\u7a0b\u5e8f\u76ee\u5f55 \u5404\u53d1\u884c\u7248\u5305\u542b\u7684\u5e94\u7528\u7a0b\u5e8f\u4e00\u822c\u5b58\u50a8\u5728\u76ee\u5f55 /usr/lib/ \u3002 \u5404\u53d1\u884c\u7248\u53ef\u9009\u7a0b\u5e8f\uff0c\u6216\u7b2c\u4e09\u65b9\u5e94\u7528\u7a0b\u5e8f\u5219\u5b58\u50a8\u5728\u76ee\u5f55 /opt \u3002 \u5728\u5b89\u88c5\u65f6\uff0c\u4f1a\u4e3a\u6bcf\u4e2a\u5e94\u7528\u7a0b\u5e8f\u7684\u6587\u4ef6\u521b\u5efa\u4e00\u4e2a\u76ee\u5f55\uff0c\u5176\u4e2d\u5305\u542b\u5e94\u7528\u7a0b\u5e8f\u7684\u540d\u79f0\u3002\u6bd4\u5982\uff1a /opt/novell - /boot - \u5f15\u5bfc\u76ee\u5f55 /boot/grub2 - \u5305\u542bGRUB2\u7684\u9759\u6001\u5f15\u5bfc\u52a0\u8f7d\u7a0b\u5e8f\u6587\u4ef6\uff08GRUB = Grand Unified Boot Loader\uff09\u3002 \u5305\u542b\u4ee5\u94fe\u63a5 vmlinuz \u548c initrd \u6807\u8bc6\u7684\u5185\u6838\u548c initrd \u6587\u4ef6\u3002 /root - \u7ba1\u7406\u5458\u7684\u4e3b\u76ee\u5f55\uff08home directory\uff09\u3002 root \u7528\u6237\u7684\u4e3b\u76ee\u5f55\u3002\u5176\u4ed6\u7528\u6237\u7684\u4e3b\u76ee\u5f55\u662f\u5728\u76ee\u5f55 /home \u4e0b\u3002 root \u7528\u6237\u7684\u767b\u5f55\u73af\u5883\u914d\u7f6e\u4fdd\u5b58\u81f3 /root \u5206\u533a\u4e2d\u3002 /home - \u7528\u6237\u4e3b\u76ee\u5f55 \u6bcf\u4e2a\u7cfb\u7edf\u7528\u6237\u90fd\u6709\u4e00\u4e2a\u5206\u914d\u7684\u6587\u4ef6\u533a\u57df\uff0c\u8be5\u6587\u4ef6\u533a\u57df\u5728\u767b\u5f55\u540e\u6210\u4e3a\u5f53\u524d\u5de5\u4f5c\u76ee\u5f55\u3002 \u9ed8\u8ba4\u60c5\u51b5\u4e0b\uff0c\u5b83\u4eec\u5b58\u5728\u4e8e /home \u4e2d\u3002 /home \u4e2d\u7684\u6587\u4ef6\u548c\u76ee\u5f55\u53ef\u4ee5\u4f4d\u4e8e\u5355\u72ec\u7684\u5206\u533a\u4e2d\uff0c\u4e5f\u53ef\u4ee5\u4f4d\u4e8e\u7f51\u7edc\u4e0a\u7684\u53e6\u4e00\u53f0\u8ba1\u7b97\u673a\u4e0a\u3002 \u7528\u6237\u914d\u7f6e\u4fe1\u606f\u548c\u914d\u7f6e\u6587\u4ef6\uff08user profile and configuration files\uff09\u4e3b\u8981\u6709\uff1a .profile - \u7528\u6237\u79c1\u6709\u767b\u5f55\u811a\u672c .bashrc - bash \u7684\u914d\u7f6e\u6587\u4ef6 .bash_history - bash \u73af\u5883\u4e0b\u4fdd\u6301\u547d\u4ee4\u5386\u53f2\u8bb0\u5f55 run - \u5e94\u7528\u7a0b\u5e8f\u72b6\u6001\u6587\u4ef6 \u4e3a\u5e94\u7528\u7a0b\u5e8f\u63d0\u4f9b\u4e86\u4e00\u4e2a\u6807\u51c6\u4f4d\u7f6e\u6765\u5b58\u50a8\u5b83\u4eec\u9700\u8981\u7684\u4e34\u65f6\u6587\u4ef6\uff0c\u4f8b\u5982\u5957\u63a5\u5b57\u548c\u8fdb\u7a0bID\u3002 \u8fd9\u4e9b\u6587\u4ef6\u4e0d\u80fd\u5b58\u50a8\u5728 /tmp \u4e2d\uff0c\u56e0\u4e3a /tmp \u4e2d\u7684\u6587\u4ef6\u53ef\u80fd\u4f1a\u88ab\u5220\u9664\u3002 /run/media//* - \u53ef\u79fb\u52a8\u8bbe\u5907\u7684\u6302\u8f7d\u70b9\uff0c\u4f8b\u5982\uff1a /run/media/media_name/ /run/media/cdrom/ - /run/media/dvd/ - /run/media/usbdisk/ - /mnt - \u6587\u4ef6\u7cfb\u7edf\u4e34\u65f6\u6302\u8f7d\u70b9 \u7528\u4e8e\u6302\u8f7d\u4e34\u65f6\u4f7f\u7528\u7684\u6587\u4ef6\u7cfb\u7edf\u7684\u76ee\u5f55\u3002 \u6587\u4ef6\u7cfb\u7edf\u4f7f\u7528 mount \u547d\u4ee4\u6302\u8f7d\uff0c\u4f7f\u7528 umount \u547d\u4ee4\u5220\u9664\u3002 \u5b50\u76ee\u5f55\u9ed8\u8ba4\u4e0d\u5b58\u5728\uff0c\u4e5f\u4e0d\u4f1a\u81ea\u52a8\u521b\u5efa\u3002 /srv - \u670d\u52a1\u6570\u636e\u76ee\u5f55 \u5b58\u653e\u5404\u79cd\u670d\u52a1\u7684\u6570\u636e\uff0c\u6bd4\u5982\uff1a /srv/www - \u7528\u4e8e\u5b58\u653e Apache Web Server \u7684\u6570\u636e /srv/ftp - \u7528\u4e8e\u5b58\u653e FTP server \u7684\u6570\u636e /var - \u53ef\u53d8\u6587\u4ef6\uff08Variable Files\uff09 \u5728\u7cfb\u7edf\u8fd0\u884c\u8fc7\u7a0b\u4e2d\u4f1a\u88ab\u4fee\u6539\u7684\u6587\u4ef6 Important subdirectories: /var/lib/ - \u53ef\u53d8\u5e93\u6587\u4ef6\uff0c\u5e94\u7528\u7a0b\u5e8f\u72b6\u6001\u4fe1\u606f\u6570\u636e /var/log/ - \u65e5\u5fd7\u6587\u4ef6 /var/run/ - \u8fd0\u884c\u4e2d\u7684\u8fdb\u7a0b\u7684\u4fe1\u606f /var/lock/ - \u591a\u7528\u6237\u8bbf\u95ee\u65f6\u7684\u9501\u6587\u4ef6 /var/cache - \u5e94\u7528\u7a0b\u5e8f\u7f13\u5b58\u6570\u636e\u76ee\u5f55 /var/opt - \u4e13\u4e3a /opt \u4e0b\u7684\u5e94\u7528\u7a0b\u5e8f\u5b58\u50a8\u53ef\u53d8\u6570\u636e /var/mail - /var/spool/ - \u5e94\u7528\u7a0b\u5e8f\u6570\u636e\u6c60\uff0c\u6bd4\u5982\uff1a\u6253\u5370\u673a\uff0c\u90ae\u4ef6 /var/spool/mail - /var/spool/cron - /tmp - \u4e34\u65f6\u6587\u4ef6 \u7a0b\u5e8f\u5728\u8fd0\u884c\u65f6\u521b\u5efa\u4e34\u65f6\u6587\u4ef6\u7684\u4f4d\u7f6e /proc - \u8fdb\u7a0b\u6587\u4ef6 \u865a\u62df\u6587\u4ef6\u7cfb\u7edf\uff0c\u4e0d\u5360\u7a7a\u95f4\uff0c\u5927\u5c0f\u59cb\u7ec8\u4e3a\u96f6\uff0c\u4fdd\u6301\u5f53\u524d\u8fdb\u7a0b\u7684\u72b6\u6001\u4fe1\u606f \u5305\u542b\u6709\u5173\u5404\u4e2a\u8fdb\u7a0b\u7684\u4fe1\u606f\u7684\u76ee\u5f55\uff0c\u6839\u636e\u8fdb\u7a0b\u7684 PID \u53f7\u547d\u540d \u6709\u4e9b\u503c\u53ef\u4ee5\u4e34\u65f6\u5728\u7ebf\u66f4\u6539\u751f\u6548\uff0c\u4f46\u91cd\u542f\u540e\u4e22\u5931 /proc/cpuinfo/ - Processor information /proc/dma/ - Use of DMA ports /proc/interrupts/ - Use of interrupts /proc/ioports/ - Use of I/O ports /proc/filesystems/ - File system formats the kernel knows /proc/modules/ - Active modules /proc/mounts/ - Mounted file systems /proc/net/* - Network information and statistics /proc/partitions/ - Existing partitions /proc/bus/pci/ - Connected PCI devices /proc/bus/scsi/ - Connected SCSI devices /proc/sys/* - System and kernel information /proc/version - Kernel version /sys - \u7cfb\u7edf\u4fe1\u606f\u76ee\u5f55 \u865a\u62df\u6587\u4ef6\u7cfb\u7edf\uff0c\u4ec5\u5b58\u5728\u4e8e\u5185\u5b58\u4e2d\uff0c\u6587\u4ef6\u5927\u5c0f\u4e3a\u96f6\u3002\u4e3b\u8981\u63d0\u4f9b\u5982\u4e0b\u4fe1\u606f\uff1a \u786c\u4ef6\u603b\u7ebf\uff08hardware buses\uff09 \u786c\u4ef6\u8bbe\u5907\uff08hardware devices\uff09 \u6709\u6e90\u8bbe\u5907\uff08active devices\uff09 \u9a71\u52a8\u7a0b\u5e8f\uff08drivers\uff09","title":"1.\u4e3b\u8981\u76ee\u5f55"},{"location":"linux/SRE/02-filesystem/#2","text":"","title":"2.\u6587\u4ef6\u64cd\u4f5c\u547d\u4ee4"},{"location":"linux/SRE/02-filesystem/#21","text":"pwd\u547d\u4ee4\uff08print working directory\uff09: -L: \u663e\u793a\u94fe\u63a5\u8def\u5f84 -P\uff1a\u663e\u793a\u771f\u5b9e\u7269\u7406\u8def\u5f84","title":"2.1.\u663e\u793a\u5f53\u524d\u5de5\u4f5c\u76ee\u5f55"},{"location":"linux/SRE/02-filesystem/#22","text":"\u5bf9\u4e8e\u7edd\u5bf9\u8def\u5f84 /etc/firewalld/policies \uff0c\u53ef\u4ee5\u901a\u8fc7\u4e0b\u9762\u547d\u4ee4\u5f97\u5230\u8be5\u8def\u5f84\u7684\u57fa\u540d policies \u548c\u76ee\u5f55\u540d /etc/firewalld \u3002 basename /etc/firewalld/policies dirname /etc/firewalld/policies","title":"2.2.\u76f8\u5bf9\u548c\u7edd\u5bf9\u8def\u5f84"},{"location":"linux/SRE/02-filesystem/#23","text":". \u6307\u5f53\u524d\u76ee\u5f55\uff0c\u5373 pwd \u547d\u4ee4\u6240\u8fd4\u56de\u7684\u76ee\u5f55\u3002 .. \u6307\u5f53\u524d\u76ee\u5f55\u7684\u4e0a\u4e00\u7ea7\u76ee\u5f55\uff0c\u53ca\u5f53\u524d\u76ee\u5f55\u7684\u7236\u76ee\u5f55\u3002 \u5207\u6362\u81f3\u7236\u76ee\u5f55\uff1a cd .. \u5207\u6362\u81f3\u5f53\u524d\u7528\u6237\u4e3b\u76ee\u5f55\uff1a cd ~ \u5207\u6362\u81f3\u4e0a\u6b21\u5de5\u4f5c\u76ee\u5f55\uff1a cd - echo $PWD \uff1a\u5f53\u524d\u5de5\u4f5c\u76ee\u5f55 echo $OLDPWD \uff1a\u4e0a\u6b21\u5de5\u4f5c\u76ee\u5f55","title":"2.3.\u66f4\u6539\u76ee\u5f55"},{"location":"linux/SRE/02-filesystem/#24","text":"ls \u547d\u4ee4\uff1a -a \u663e\u793a\u6240\u6709\u6587\u4ef6\u53ca\u76ee\u5f55 (. \u5f00\u5934\u7684\u9690\u85cf\u6587\u4ef6\u4e5f\u4f1a\u5217\u51fa) -A \u540c -a \uff0c\u4f46\u4e0d\u5217\u51fa . (\u76ee\u524d\u76ee\u5f55) \u53ca .. (\u7236\u76ee\u5f55) -l \u9664\u6587\u4ef6\u540d\u79f0\u5916\uff0c\u4ea6\u5c06\u6587\u4ef6\u578b\u6001\u3001\u6743\u9650\u3001\u62e5\u6709\u8005\u3001\u6587\u4ef6\u5927\u5c0f\u7b49\u8d44\u8baf\u8be6\u7ec6\u5217\u51fa -r \u5c06\u6587\u4ef6\u4ee5\u76f8\u53cd\u6b21\u5e8f\u663e\u793a(\u539f\u5b9a\u4f9d\u82f1\u6587\u5b57\u6bcd\u6b21\u5e8f) -t \u5c06\u6587\u4ef6\u4f9d\u5efa\u7acb\u65f6\u95f4\u4e4b\u5148\u540e\u6b21\u5e8f\u5217\u51fa -F \u5728\u5217\u51fa\u7684\u6587\u4ef6\u540d\u79f0\u540e\u52a0\u4e00\u7b26\u53f7\uff1b\u4f8b\u5982\u53ef\u6267\u884c\u6863\u5219\u52a0 \"*\", \u76ee\u5f55\u5219\u52a0 \"/\" -R \u9012\u5f52\u5217\u51fa\u5b50\u76ee\u5f55 -S \u6309\u6587\u4ef6\u5927\u5c0f\u6392\u5e8f\uff0c\u4ece\u5927\u5230\u5c0f -1 \u6309\u4e00\u4e2a\u6587\u4ef6\u4e00\u884c\u5217\u51fa -t \u6309\u6587\u4ef6\u65f6\u95f4\u6392\u5e8f\uff0c\u6700\u65b0\u7684\u5728\u524d -U \u4e0d\u6392\u5e8f\u8f93\u51fa\uff0c\u6309\u76ee\u5f55\u5b58\u653e\u987a\u5e8f\u5217\u51fa -u \u914d\u5408 -lt \uff0c\u6309\u8bbf\u95ee\u65f6\u95f4\u6392\u5e8f\u5e76\u663e\u793a\uff1b\u914d\u5408 -l \uff0c\u663e\u793a\u8bbf\u95ee\u65f6\u95f4\u5e76\u6309\u540d\u79f0\u6392\u5e8f\uff1b \u5426\u5219\u6309\u8bbf\u95ee\u65f6\u95f4\u6392\u5e8f\uff0c\u6700\u65b0\u7684\u5728\u524d -X \u6309\u6587\u4ef6\u6269\u5c55\u540d\u5b57\u6bcd\u987a\u5e8f\u6392\u5e8f\u8f93\u51fa -F \u5bf9\u4e0d\u540c\u7c7b\u578b\u6587\u4ef6\u663e\u793a\u65f6\u9644\u52a0\u4e0d\u540c\u7684\u7b26\u53f7\uff0c * / = > @ | \u4e4b\u4e00 ls \u547d\u4ee4\u67e5\u770b\u4e0d\u540c\u6587\u4ef6\u662f\u7684\u989c\u8272\uff0c\u7531 /etc/DIR_COLORS \u548c\u53d8\u91cf @LS_COLORS \u5b9a\u4e49\u3002","title":"2.4.\u5217\u51fa\u76ee\u5f55\u5185\u5bb9"},{"location":"linux/SRE/02-filesystem/#25stat","text":"\u6bcf\u4e2a\u6587\u4ef6\u6709\u4e09\u4e2a\u65f6\u95f4\u6233\uff1a \u8bbf\u95ee\u65f6\u95f4 Access Time atime : \u8bfb\u53d6\u6587\u4ef6\u5185\u5bb9\u3002 \u4fee\u6539\u65f6\u95f4 Modify Time mtime : \u6539\u53d8\u6587\u4ef6\u5185\u5bb9\uff08\u6570\u636e\uff09\u3002 \u6539\u53d8\u65f6\u95f4 Change Time ctime : \u5143\u6570\u636e\u53d1\u751f\u6539\u53d8\u3002 \u8bfb\u53d6\u4e09\u4e2a\u65f6\u95f4\u6233\u7684\u547d\u4ee4 stat \uff1a stat /etc/fstab \u8f93\u51fa\u7ed3\u679c\uff1a File: /etc/fstab Size: 927 Blocks: 8 IO Block: 4096 regular file Device: 30h/48d Inode: 263 Links: 1 Access: (0644/-rw-r--r--) Uid: ( 0/ root) Gid: ( 0/ root) Access: 2022-10-31 10:26:34.987466959 +0800 Modify: 2022-06-24 14:50:24.387992912 +0800 Change: 2022-06-24 14:50:24.387992912 +0800 Birth: 2022-06-24 14:50:23.755992937 +0800","title":"2.5.\u6587\u4ef6\u72b6\u6001stat"},{"location":"linux/SRE/02-filesystem/#26","text":"\u547d\u4ee4 file \u68c0\u67e5\u6587\u4ef6\u7c7b\u578b\u3002 -b \uff1a\u5217\u51fa\u8fa8\u8bc6\u7ed3\u679c\u65f6\uff0c\u4e0d\u663e\u793a\u6587\u4ef6\u540d\u79f0\u3002 -c \uff1a\u8be6\u7ec6\u663e\u793a\u6307\u4ee4\u6267\u884c\u8fc7\u7a0b\uff0c\u4fbf\u4e8e\u6392\u9519\u6216\u5206\u6790\u7a0b\u5e8f\u6267\u884c\u7684\u60c5\u5f62\u3002 -f <\u540d\u79f0\u6587\u4ef6> \uff1a\u6307\u5b9a\u540d\u79f0\u6587\u4ef6\uff0c\u5176\u5185\u5bb9\u6709\u4e00\u4e2a\u6216\u591a\u4e2a\u6587\u4ef6\u540d\u79f0\u65f6\uff0c\u8ba9file\u4f9d\u5e8f\u8fa8\u8bc6\u8fd9\u4e9b\u6587\u4ef6\uff0c\u683c\u5f0f\u4e3a\u6bcf\u5217\u4e00\u4e2a\u6587\u4ef6\u540d\u79f0\u3002 -L \uff1a \u76f4\u63a5\u663e\u793a\u7b26\u53f7\u8fde\u63a5\u6240\u6307\u5411\u7684\u6587\u4ef6\u7684\u7c7b\u522b\u3002 -v \uff1a \u663e\u793a\u7248\u672c\u4fe1\u606f\u3002 -z \uff1a \u5c1d\u8bd5\u53bb\u89e3\u8bfb\u538b\u7f29\u6587\u4ef6\u7684\u5185\u5bb9\u3002 \u7f16\u8f91\u6587\u4ef6 list.txt \u5305\u542b\u4e00\u4e0b\u5185\u5bb9\uff1a /etc/ /bin /etc/issue \u8fd0\u884c\u547d\u4ee4 file -f list.txt \uff0c\u7ed3\u679c\u5982\u4e0b\uff1a /etc/: directory /bin: directory /etc/issue: symbolic link to ../run/issue","title":"2.6.\u786e\u5b9a\u6587\u4ef6\u7c7b\u578b"},{"location":"linux/SRE/02-filesystem/#27","text":"iconv \u547d\u4ee4\u7528\u4e8e\u5c06\u4e00\u79cd\u7f16\u7801\u4e2d\u7684\u67d0\u4e9b\u6587\u672c\u8f6c\u6362\u4e3a\u53e6\u4e00\u79cd\u7f16\u7801\u3002 \u5982\u679c\u6ca1\u6709\u63d0\u4f9b\u8f93\u5165\u6587\u4ef6\uff0c\u5219\u5b83\u4ece\u6807\u51c6\u8f93\u5165\u4e2d\u8bfb\u53d6\u3002 \u540c\u6837\uff0c\u5982\u679c\u6ca1\u6709\u7ed9\u51fa\u8f93\u51fa\u6587\u4ef6\uff0c\u90a3\u4e48\u5b83\u4f1a\u5199\u5165\u6807\u51c6\u8f93\u51fa\u3002 \u5982\u679c\u6ca1\u6709\u63d0\u4f9b from-encoding \u6216 to-encoding \uff0c\u5219\u5b83\u4f7f\u7528\u5f53\u524d\u672c\u5730\u7684\u5b57\u7b26\u7f16\u7801\u3002 \u5c06\u6587\u672c\u4ece ISO 8859-15 \u5b57\u7b26\u7f16\u7801\u8f6c\u6362\u4e3a UTF-8\uff0c\u8bfb\u5165 input.txt \uff0c\u8f93\u51fa output.txt \u3002 iconv -f ISO-8859-15 -t UTF-8 < input.txt > output.txt \u4ece UTF-8 \u8f6c\u6362\u4e3a ASCII\uff0c\u5c3d\u53ef\u80fd\u8fdb\u884c\u97f3\u8bd1\uff08transliterating\uff09\uff1a echo abc \u00df \u03b1 \u20ac \u00e0\u1e03\u00e7 | iconv -f UTF-8 -t ASCII//TRANSLIT \u8fd0\u884c\u7ed3\u679c\uff1a abc ss ? EUR abc","title":"2.7.\u6587\u4ef6\u7f16\u7801\u8f6c\u6362"},{"location":"linux/SRE/02-filesystem/#28","text":"\u901a\u914d\u7b26\uff0c\u6307\u5305\u542b\u8fd9\u4e9b\u5b57\u7b26\u7684\u5b57\u7b26\u4e32 ? \uff1a\u8868\u793a\u4efb\u610f\u4e00\u4e2a\u5b57\u7b26 * \uff1a\u8868\u793a\u4efb\u610f\u957f\u5ea6\u7684\u4efb\u610f\u5b57\u7b26 [] \uff1a\u5339\u914d\u6307\u5b9a\u8303\u56f4\u5185\u4efb\u610f\u4e00\u4e2a\u5b57\u7b26 [abcd] \uff1a\u5339\u914dabcd\u4e2d\u7684\u4efb\u4f55\u4e00\u4e2a\u5b57\u7b26 [a-z] \uff1a\u5339\u914d\u8303\u56f4a\u5230z\u5185\u4efb\u610f\u4e00\u4e2a\u5b57\u7b26 [!abcd] \uff1a\u4e0d\u5339\u914d\u62ec\u53f7\u91cc\u9762\u4efb\u4f55\u4e00\u4e2a\u5b57\u7b26 {} \uff1a\u8868\u793a\u751f\u6210\u5e8f\u5217\uff0c\u4ee5\u9017\u53f7\u5206\u5272\uff0c\u4e0d\u80fd\u6709\u7a7a\u683c \u793a\u4f8b\uff1a $ touch file_ { a..z } .txt $ touch file_ { A..Z } .txt $ ls file_a.txt file_C.txt file_f.txt file_H.txt file_k.txt file_M.txt file_p.txt file_R.txt file_u.txt file_W.txt file_z.txt file_A.txt file_d.txt file_F.txt file_i.txt file_K.txt file_n.txt file_P.txt file_s.txt file_U.txt file_x.txt file_Z.txt file_b.txt file_D.txt file_g.txt file_I.txt file_l.txt file_N.txt file_q.txt file_S.txt file_v.txt file_X.txt file_B.txt file_e.txt file_G.txt file_j.txt file_L.txt file_o.txt file_Q.txt file_t.txt file_V.txt file_y.txt file_c.txt file_E.txt file_h.txt file_J.txt file_m.txt file_O.txt file_r.txt file_T.txt file_w.txt file_Y.txt $ ls file_ [ a..d ] .* file_a.txt file_d.txt $ ls file_ [ a...d ] .* file_a.txt file_d.txt $ ls file_ [ ad ] .* file_a.txt file_d.txt $ ls file_ [ a-c ] .* file_a.txt file_A.txt file_b.txt file_B.txt file_c.txt $ ls file_ [ a-C ] .* file_a.txt file_A.txt file_b.txt file_B.txt file_c.txt file_C.txt $ ls file_ [ !d-W ] .* file_a.txt file_b.txt file_c.txt file_x.txt file_y.txt file_z.txt file_A.txt file_B.txt file_C.txt file_X.txt file_Y.txt file_Z.txt \u6bd4\u8f83\u6709\u65e0 * \u7684\u533a\u522b\uff1a $ ls -a * file_a.txt file_D.txt file_h.txt file_K.txt file_o.txt file_R.txt file_v.txt file_Y.txt file_A.txt file_e.txt file_H.txt file_l.txt file_O.txt file_s.txt file_V.txt file_z.txt file_b.txt file_E.txt file_i.txt file_L.txt file_p.txt file_S.txt file_w.txt file_Z.txt file_B.txt file_f.txt file_I.txt file_m.txt file_P.txt file_t.txt file_W.txt file_c.txt file_F.txt file_j.txt file_M.txt file_q.txt file_T.txt file_x.txt file_C.txt file_g.txt file_J.txt file_n.txt file_Q.txt file_u.txt file_X.txt file_d.txt file_G.txt file_k.txt file_N.txt file_r.txt file_U.txt file_y.txt $ ls -a . file_C.txt file_g.txt file_J.txt file_n.txt file_Q.txt file_u.txt file_X.txt .. file_d.txt file_G.txt file_k.txt file_N.txt file_r.txt file_U.txt file_y.txt file_a.txt file_D.txt file_h.txt file_K.txt file_o.txt file_R.txt file_v.txt file_Y.txt file_A.txt file_e.txt file_H.txt file_l.txt file_O.txt file_s.txt file_V.txt file_z.txt file_b.txt file_E.txt file_i.txt file_L.txt file_p.txt file_S.txt file_w.txt file_Z.txt file_B.txt file_f.txt file_I.txt file_m.txt file_P.txt file_t.txt file_W.txt file_c.txt file_F.txt file_j.txt file_M.txt file_q.txt file_T.txt file_x.txt","title":"2.8.\u901a\u914d\u7b26"},{"location":"linux/SRE/02-filesystem/#29","text":"[:alpha:] \uff1a\u8868\u793a\u6240\u6709\u7684\u5b57\u6bcd\uff08\u4e0d\u533a\u5206\u5927\u5c0f\u5199\uff09\uff0c\u6548\u679c\u540c [a-z] [:digit:] \uff1a\u8868\u793a\u4efb\u610f\u5355\u4e2a\u6570\u5b57\uff0c\u6548\u679c\u540c [0-9] [:xdigit:] \uff1a\u8868\u793a\u5341\u516d\u8fdb\u5236\u6570\u5b57 [:lower:] \uff1a\u8868\u793a\u4efb\u610f\u5355\u4e2a\u5c0f\u5199\u5b57\u6bcd [:upper:] \uff1a\u8868\u793a\u4efb\u610f\u5355\u4e2a\u5927\u5199\u5b57\u6bcd [:alnum:] \uff1a\u8868\u793a\u4efb\u610f\u5355\u4e2a\u5b57\u6bcd\u6216\u6570\u5b57 [:blank:] \uff1a\u8868\u793a\u7a7a\u767d\u5b57\u7b26\uff08\u7a7a\u683c\u548c\u5236\u8868\u7b26\uff09 [:space:] \uff1a\u8868\u793a\u5305\u62ec\u7a7a\u683c\u3001\u5236\u8868\u7b26\uff08\u6c34\u5e73\u548c\u5782\u76f4\uff09\u3001\u6362\u884c\u7b26\u3001\u56de\u8f66\u7b26\u7b49\u5404\u79cd\u7c7b\u578b\u7684\u7a7a\u767d\uff0c\u6bd4 [:blank:] \u8303\u56f4\u66f4\u5e7f [:cntrl:] \uff1a\u8868\u793a\u4e0d\u53ef\u6253\u5370\u7684\u63a7\u5236\u5b57\u7b26\uff08\u9000\u683c\u3001\u5220\u9664\u3001\u8b66\u94c3\u7b49\uff09 [:graph:] \uff1a\u8868\u793a\u53ef\u6253\u5370\u7684\u975e\u7a7a\u767d\u5b57\u7b26 [:print:] \uff1a\u8868\u793a\u53ef\u6253\u5370\u5b57\u7b26 [:punct:] \uff1a\u8868\u793a\u6807\u70b9\u7b26\u53f7 \u4e3e\u4f8b\uff1a ls -d [[:alpha:]] \u5373 ls -d [a-Z] \uff1a\u663e\u793a\u5f53\u524d\u76ee\u5f55\u4e0b\u6240\u6709\u5355\u4e2a\u5b57\u6bcd\u7684\u76ee\u5f55\u548c\u6587\u4ef6 ls -d *[[:digit:]] \u5373 ls -d *[0-9] \uff1a\u663e\u793a\u5f53\u524d\u76ee\u5f55\u4e0b\u6240\u6709\u4ee5\u6570\u5b57\u7ed3\u5c3e\u7684\u76ee\u5f55\u548c\u6587\u4ef6 ls [[:lower:]].txt \uff1a\u663e\u793a\u5f53\u524d\u76ee\u5f55\u4e0b\u6240\u6709\u4ee5\u5355\u4e2a\u5c0f\u5199\u5b57\u6bcd\u4e3a\u540d\u7684.txt\u683c\u5f0f\u7684\u6587\u4ef6 ls -d [[:alnum:]] \uff1a\u663e\u793a\u5f53\u524d\u76ee\u5f55\u4e0b\u6240\u6709\u5355\u4e2a\u5b57\u6bcd\uff08\u4e0d\u533a\u5206\u5927\u5c0f\u5199\uff09\u6216\u6570\u5b57\u4e3a\u540d\u7684\u76ee\u5f55\u6216\u6587\u4ef6","title":"2.9.\u5b57\u7b26\u96c6"},{"location":"linux/SRE/02-filesystem/#210","text":"| \uff1a\u7ba1\u9053\u7b26\uff0c\u6216\u8005\uff08\u6b63\u5219\uff09 > \uff1a\u8f93\u51fa\u91cd\u5b9a\u5411 >> \uff1a\u8f93\u51fa\u8ffd\u52a0\u91cd\u5b9a\u5411 < \uff1a\u8f93\u5165\u91cd\u5b9a\u5411 << \uff1a\u8ffd\u52a0\u8f93\u5165\u91cd\u5b9a\u5411 ~ \uff1a\u5f53\u524d\u7528\u6237\u5bb6\u76ee\u5f55 $() \uff1a\u5f15\u7528\u547d\u4ee4\u88ab\u6267\u884c\u540e\u7684\u7ed3\u679c $ \uff1a\u4ee5...\u7ed3\u5c3e\uff08\u6b63\u5219\uff09 ^ \uff1a\u4ee5...\u5f00\u5934\uff08\u6b63\u5219\uff09 * \uff1a\u5339\u914d\u5168\u90e8\u5b57\u7b26\uff0c\u901a\u914d\u7b26 ? \uff1a\u4efb\u610f\u4e00\u4e2a\u5b57\u7b26\uff0c\u901a\u914d\u7b26 # \uff1a\u6ce8\u91ca & \uff1a\u8ba9\u7a0b\u5e8f\u6216\u811a\u672c\u5207\u6362\u5230\u540e\u53f0\u6267\u884c && \uff1a\u5e76\u4e14\uff0c\u540c\u65f6\u6210\u7acb [] \uff1a\u8868\u793a\u4e00\u4e2a\u8303\u56f4\uff08\u6b63\u5219\uff0c\u901a\u914d\u7b26\uff09 {} \uff1a\u4ea7\u751f\u4e00\u4e2a\u5e8f\u5217\uff08\u901a\u914d\u7b26\uff09 . \uff1a\u5f53\u524d\u76ee\u5f55\u7684\u786c\u94fe\u63a5 .. \uff1a\u4e0a\u7ea7\u76ee\u5f55\u7684\u786c\u94fe\u63a5","title":"2.10.\u7279\u6b8a\u7b26\u53f7"},{"location":"linux/SRE/02-filesystem/#211touch","text":"touch \u547d\u4ee4\u53ef\u4ee5\u521b\u5efa\u7a7a\u6587\u4ef6\uff0c\u4e5f\u53ef\u4ee5\u5237\u65b0\u6587\u4ef6\u65f6\u95f4\u3002\u53c2\u6570\u5982\u4e0b\uff1a -a \uff1a\u4ec5\u6539\u53d8 atime \u548c ctime -m \uff1a\u4ec5\u6539\u53d8 mtime \u548c ctime -t [[CC]YY]MMDDhhmm[.ss] \uff1a\u6307\u5b9a atime \u548c mtime -c \uff1a\u5982\u679c\u6587\u4ef6\u4e0d\u5b58\u5728\uff0c\u5219\u4e0d\u521b\u5efa $ touch file1 $ touch file2 $ ll -rw-r--r--. 1 vagrant wheel 5 Nov 8 20 :49 file1 -rw-r--r--. 1 vagrant wheel 0 Nov 8 20 :28 file2 \u521b\u5efa\u6587\u4ef6file-non.log\uff0c\u5982\u679c\u4e0d\u5b58\u5728\u5219\u4e0d\u521b\u5efa\u3002 touch -c file-non.log \u66f4\u65b0 file1 \u7684\u65f6\u95f4\u548c file2 \u4e00\u81f4\u3002 $ touch -r file1 file2 $ ll -rw-r--r--. 1 vagrant wheel 5 Nov 8 20 :49 file1 -rw-r--r--. 1 vagrant wheel 0 Nov 8 20 :49 file2 \u6307\u5b9a file2 \u7684\u65f6\u95f4\u3002 202210012135.25 \u4ee3\u8868 YYYYMMDDHHMM.SS \u3002 $ touch -t 202210012135 .25 file2 $ ll -rw-r--r--. 1 vagrant wheel 5 Nov 8 20 :49 file1 -rw-r--r--. 1 vagrant wheel 0 Oct 1 21 :35 file2 $ stat file2 File: file2 Size: 0 Blocks: 0 IO Block: 4096 regular empty file Device: fd02h/64770d Inode: 140 Links: 1 Access: ( 0644 /-rw-r--r-- ) Uid: ( 1000 / vagrant ) Gid: ( 10 / wheel ) Context: unconfined_u:object_r:user_home_t:s0 Access: 2022 -10-01 21 :35:25.000000000 +0800 Modify: 2022 -10-01 21 :35:25.000000000 +0800 Change: 2022 -11-08 20 :56:18.306315887 +0800 Birth: 2022 -11-08 20 :28:37.809551441 +0800","title":"2.11.\u5237\u65b0\u6587\u4ef6\u65f6\u95f4touch"},{"location":"linux/SRE/02-filesystem/#212cp","text":"cp \u547d\u4ee4\uff1aCopy SOURCE to DEST, or multiple SOURCE(s) to DIRECTORY. \u5e38\u7528\u53c2\u6570\uff1a -a \uff1a\u5f52\u6863\uff0c\u76f8\u5f53\u4e8e -dR --preserv=all \u53c2\u6570\u7ec4\u5408\uff0c\u5e38\u7528\u4e8e\u5907\u4efd\u3002 -d \uff1a\u4e0d\u590d\u5236\u539f\u6587\u4ef6\uff0c\u53ea\u590d\u5236\u94fe\u63a5\u540d\u3002\u76f8\u5f53\u4e8e --no-dereference --preserve=links \u53c2\u6570\u7ec4\u5408\u3002 -f \uff1a\u8986\u76d6\u5df2\u7ecf\u5b58\u5728\u7684\u76ee\u6807\u6587\u4ef6\u3002 -i \uff1a\u8986\u76d6\u76ee\u6807\u6587\u4ef6\u4e4b\u524d\u7ed9\u51fa\u63d0\u793a\u3002 -p \uff1a\u9664\u590d\u5236\u6587\u4ef6\u7684\u5185\u5bb9\u5916\uff0c\u4e5f\u590d\u5236\u6587\u4ef6\u6743\u9650\uff0c\u65f6\u95f4\u6233\uff0c\u5c5e\u4e3b\u5c5e\u7ec4\u3002\u76f8\u5f53\u4e8e --preserve=mode,ownership,timestamps \u3002 -r, -R, --recursive \uff1a\u9012\u5f52\u590d\u5236\u76ee\u5f55\u6240\u5305\u542b\u7684\u5168\u90e8\u5185\u5bb9\u3002 -l \uff1a\u4e0d\u590d\u5236\u6587\u4ef6\uff0c\u53ea\u662f\u751f\u6210\u786c\u94fe\u63a5\u6587\u4ef6\u3002 \u53c2\u6570 --preserv \u53ef\u9009\u9879\uff1a mode\uff1a\u6743\u9650 ownership\uff1a\u5c5e\u4e3b\u5c5e\u7ec4 timestamp links xattr context all \u521b\u5efa\u6d4b\u8bd5\u76ee\u5f55\u3002 cd ~ mkdir test \u5bf9\u6bd4\u53c2\u6570 -p \u7684\u5dee\u522b\u3002 $ cp /etc/issue ~/test/issue1 $ cp -p /etc/issue ~/test/issue1 $ sudo cp /etc/issue ~/test/issue3 $ sudo cp -p /etc/issue ~/test/issue4 $ ll ~/test -rw-r--r--. 1 vagrant wheel 23 Nov 8 22 :25 issue1 -rw-r--r--. 1 vagrant wheel 23 Jul 21 01 :10 issue2 -rw-r--r--. 1 root root 23 Nov 8 22 :43 issue3 -rw-r--r--. 1 root root 23 Jul 21 01 :10 issue4 $ ll /etc/issue -rw-r--r--. 1 root root 23 Jul 21 01 :10 /etc/issue \u5bf9\u6bd4\u53c2\u6570 -r \u3002 $ sudo cp /etc/sysconfig/ ~/test cp: -r not specified ; omitting directory '/etc/sysconfig/' $ sudo cp -r /etc/sysconfig/ ~/test $ tree -L 2 ~/test /home/vagrant/test \u251c\u2500\u2500 issue1 \u251c\u2500\u2500 issue2 \u251c\u2500\u2500 issue3 \u251c\u2500\u2500 issue4 \u2514\u2500\u2500 sysconfig \u251c\u2500\u2500 anaconda \u251c\u2500\u2500 atd \u251c\u2500\u2500 chronyd \u251c\u2500\u2500 cpupower \u251c\u2500\u2500 crond \u251c\u2500\u2500 firewalld \u251c\u2500\u2500 irqbalance \u251c\u2500\u2500 kdump \u251c\u2500\u2500 kernel \u251c\u2500\u2500 man-db \u251c\u2500\u2500 network \u251c\u2500\u2500 network-scripts \u251c\u2500\u2500 nftables.conf \u251c\u2500\u2500 raid-check \u251c\u2500\u2500 rsyslog \u251c\u2500\u2500 run-parts \u251c\u2500\u2500 samba \u251c\u2500\u2500 selinux -> ../selinux/config \u251c\u2500\u2500 smartmontools \u2514\u2500\u2500 sshd \u53c2\u6570 -b \uff0c\u5982\u679c\u76ee\u6807\u6587\u4ef6\u5b58\u5728\uff0c\u590d\u5236\u524d\u5148\u5c06\u539f\u6587\u4ef6\u590d\u5236\u5e76\u4ee5 ~ \u7ed3\u5c3e\u3002 $ ll /etc/motd -rw-r--r--. 1 root root 0 Jun 23 2020 /etc/motd $ ll ~/test/issue1 -rw-r--r--. 1 vagrant wheel 23 Nov 8 22 :25 /home/vagrant/test/issue1 $ cp -b /etc/motd ~/test/issue $ cp -b /etc/motd ~/test/issue1 $ ll ~/test -rw-r--r--. 1 vagrant wheel 0 Nov 8 23 :00 issue -rw-r--r--. 1 vagrant wheel 0 Nov 8 22 :57 issue1 -rw-r--r--. 1 vagrant wheel 23 Nov 8 22 :25 issue1~ -rw-r--r--. 1 vagrant wheel 23 Jul 21 01 :10 issue2 -rw-r--r--. 1 root root 23 Nov 8 22 :43 issue3 -rw-r--r--. 1 root root 23 Jul 21 01 :10 issue4 drwxr-xr-x. 3 root root 4096 Nov 8 22 :49 sysconfig \u53c2\u6570 --backup=numbered \u4f1a\u5728\u590d\u5236\u539f\u6587\u4ef6\u65f6\u52a0\u4e0a\u6570\u5b57\u5e8f\u53f7\uff0c\u5e8f\u53f71\u4ee3\u8868\u539f\u59cb\u7684\u6587\u4ef6\u3002 $ cp --backup = numbered /etc/motd ~/test/issue2 $ cp --backup = numbered /etc/motd ~/test/issue2 $ cp --backup = numbered /etc/motd ~/test/issue2 $ ll ~/test -rw-r--r--. 1 vagrant wheel 0 Nov 8 23 :00 issue -rw-r--r--. 1 vagrant wheel 0 Nov 8 22 :57 issue1 -rw-r--r--. 1 vagrant wheel 23 Nov 8 22 :25 issue1~ -rw-r--r--. 1 vagrant wheel 0 Nov 8 23 :09 issue2 -rw-r--r--. 1 vagrant wheel 23 Jul 21 01 :10 issue2.~1~ -rw-r--r--. 1 vagrant wheel 0 Nov 8 23 :09 issue2.~2~ -rw-r--r--. 1 vagrant wheel 0 Nov 8 23 :09 issue2.~3~ -rw-r--r--. 1 root root 23 Nov 8 22 :43 issue3 -rw-r--r--. 1 root root 23 Jul 21 01 :10 issue4 drwxr-xr-x. 3 root root 4096 Nov 8 22 :49 sysconfig","title":"2.12.\u590d\u5236\u6587\u4ef6\u548c\u76ee\u5f55cp"},{"location":"linux/SRE/02-filesystem/#213mv","text":"mv \u547d\u4ee4\u3002Rename SOURCE to DEST, or move SOURCE(s) to DIRECTORY. \u5e38\u7528\u53c2\u6570\uff1a -v \uff1a\u663e\u793a\u547d\u4ee4\u6267\u884c\u7684\u4fe1\u606f\u3002 -i \uff1a\u4ea4\u4e92\u5f0f\uff0c\u6bd4\u5982\uff0c\u91cd\u540d\u8986\u76d6\u65f6\u4f1a\u63d0\u5347\u662f\u5426\u786e\u8ba4\u3002 -b \uff1a\u8986\u76d6\u65f6\u521b\u5efa\u5907\u4efd\u3002\u9ed8\u8ba4\u60c5\u51b5\u4e0b\uff0c\u79fb\u52a8\u6587\u4ef6\u5c06\u4f1a\u8986\u76d6\u5df2\u5b58\u5728\u7684\u76ee\u6807\u6587\u4ef6\u3002 \u79fb\u52a8\u591a\u4e2a\u6587\u4ef6\u5230\u67d0\u4e2a\u76ee\u5f55\u3002 mv file1 file2 file3 ~/dest mv file* ~/dest \u79fb\u52a8\u76ee\u5f55\u3002 mv ~/test ~/dest/new/one/ \u91cd\u547d\u540d\u6587\u4ef6\u548c\u76ee\u5f55\u3002 mv file1 file2 mv ~/test ~/dest","title":"2.13.\u79fb\u52a8\u6587\u4ef6\u548c\u76ee\u5f55mv"},{"location":"linux/SRE/02-filesystem/#214rename","text":"rename \u547d\u4ee4\u3002\u5206\u4e3aperl\u7248\u672c\u548cC\u8bed\u8a00\u7248\u672c\u3002 \u533a\u5206\u65b9\u6cd5: rename --version \u3002\u5982\u679c\u8fd4\u56de\u7ed3\u679c\u4e2d\u5305\u542b util-linux \uff0c\u8bf4\u660e\u662fC\u8bed\u8a00\u7248\u672c, \u53cd\u4e4b\u662fPerl\u7248\u672c\u3002 openSUSE\u548cRocy\u662fC\u8bed\u8a00\u7248\u672c\uff0cUbuntu\u662fPerl\u7248\u672c\u3002 \u4e3e\u4f8b\uff1a\u4fee\u6539\u5f53\u524d\u76ee\u5f55\u6240\u6709\u6269\u5c55\u540d\u4e3a s \u7684\u6587\u4ef6\u6539\u4e3a\u6269\u5c55\u540d\u4e3a gz \u3002 $ touch file { 1 ..3 } .s $ rename -v '.s' '.gz' *.s $ rename -v \".s\" \".gz\" *.s ` file1.txt ' -> `file1.html' ` file2.txt ' -> `file2.html' ` file3.txt ' -> `file3.html' \u5728Ubuntu\u4e0a\u5b8c\u6210\u540c\u6837\u4efb\u52a1\uff0c\u5219\u9700\u8981\u4f7f\u7528\u6b63\u5219\u3002 rename -v \"s/s/gz/g\" *.s","title":"2.14.\u91cd\u547d\u540d\u6587\u4ef6\u548c\u76ee\u5f55rename"},{"location":"linux/SRE/02-filesystem/#215rm","text":"rm \u547d\u4ee4\u3002\u5efa\u8bae\u4f7f\u7528 mv \u547d\u4ee4\u4ee3\u66ff rm \u547d\u4ee4\u3002","title":"2.15.\u5220\u9664\u6587\u4ef6rm"},{"location":"linux/SRE/02-filesystem/#216","text":"\u521b\u5efa\u76ee\u5f55\uff1a mkdir \u5220\u9664\u7a7a\u76ee\u5f55\uff1a rmdir \u5220\u9664\u975e\u7a7a\u76ee\u5f55\uff1a rm -r \u663e\u793a\u76ee\u5f55\u6811\uff1a tree","title":"2.16.\u76ee\u5f55\u64cd\u4f5c\u547d\u4ee4"},{"location":"linux/SRE/02-filesystem/#217","text":"\u663e\u793a /etc \u76ee\u5f55\u4e0b\u6240\u6709\u4ee5 l \u5f00\u5934\uff0c\u4ee5\u4e00\u4e2a\u5c0f\u5199\u5b57\u6bcd\u7ed3\u5c3e\uff0c\u4e14\u4e2d\u95f4\u51fa\u73b0\u81f3\u5c11\u4e00\u4f4d\u6570\u5b57\u7684\u6587\u4ef6\u6216\u76ee\u5f55\u5217\u8868\u3002 ls -d /etc/l* [ 0 -9 ] * [ a-z ] ls -d /etc/l* [[ :digit: ]] * [[ :lower: ]] \u5982\u679c\u65e0\u7b26\u5408\u6761\u4ef6\u7684\u8bb0\u5f55\u8fd4\u56de\uff0c\u53ef\u4ee5\u624b\u5de5\u521b\u5efa\u4e00\u4e2a\u7b26\u5408\u6761\u4ef6\u7684\u6587\u4ef6\u548c\u76ee\u5f55\u3002 sudo touch /etc/lam4you sudo mkdir /etc/lam5you \u9a8c\u8bc1\u540e\u5220\u9664\u3002 sudo rm /etc/lam4you sudo rm -rf /etc/lam5you \u663e\u793a /etc \u76ee\u5f55\u4e0b\u4ee5\u4efb\u610f\u4e00\u4f4d\u6570\u5b57\u5f00\u5934\uff0c\u4e14\u4ee5\u975e\u6570\u5b57\u7ed3\u5c3e\u7684\u6587\u4ef6\u6216\u76ee\u5f55\u5217\u8868\u3002 ls /etc/ [ 0 -9 ] * [ !0-9 ] ls /etc/ [[ :digit: ]] * [ ^ [ :digit: ]] \u5982\u679c\u65e0\u7b26\u5408\u6761\u4ef6\u7684\u8bb0\u5f55\u8fd4\u56de\uff0c\u53ef\u4ee5\u624b\u5de5\u521b\u5efa\u4e00\u4e2a\u7b26\u5408\u6761\u4ef6\u7684\u6587\u4ef6\u548c\u76ee\u5f55\u3002 sudo touch /etc/5am4yo. sudo mkdir /etc/5am5yo. \u9a8c\u8bc1\u540e\u5220\u9664\u3002 sudo rm /etc/5am4yo. sudo rm -rf /etc/5am5yo. \u663e\u793a /etc \u76ee\u5f55\u4e0b\u4ee5\u975e\u5b57\u6bcd\u5f00\u5934\uff0c\u540e\u9762\u8ddf\u4e86\u4e00\u4e2a\u5b57\u6bcd\u53ca\u5176\u5b83\u4efb\u610f\u957f\u5ea6\u4efb\u610f\u5b57\u7b26\u7684\u6587\u4ef6\u6216\u76ee\u5f55\u5217\u8868\u3002 ls /etc/ [ !a-zA-Z ][ a-zA-Z ] * ls /etc/ [ ^ [ :alpha: ]][[ :alpha: ]] * \u5982\u679c\u65e0\u7b26\u5408\u6761\u4ef6\u7684\u8bb0\u5f55\u8fd4\u56de\uff0c\u53ef\u4ee5\u624b\u5de5\u521b\u5efa\u4e00\u4e2a\u7b26\u5408\u6761\u4ef6\u7684\u6587\u4ef6\u548c\u76ee\u5f55\u3002 sudo touch /etc/5Ato3 sudo mkdir /etc/6dog6 \u9a8c\u8bc1\u540e\u5220\u9664\u3002 sudo rm /etc/5Ato3 sudo rm -rf /etc/6dog6 \u663e\u793a /etc \u76ee\u5f55\u4e0b\uff0c\u6240\u6709\u4ee5 rc \u5f00\u5934\uff0c\u5e76\u540e\u9762\u662f0-6\u4e4b\u95f4\u7684\u6570\u5b57\uff0c\u5176\u5b83\u4e3a\u4efb\u610f\u5b57\u7b26\u7684\u6587\u4ef6\u6216\u76ee\u5f55\u5217\u8868\u3002 ls /etc/rc [ 0 -6 ] * \u5982\u679c\u65e0\u7b26\u5408\u6761\u4ef6\u7684\u8bb0\u5f55\u8fd4\u56de\uff0c\u53ef\u4ee5\u624b\u5de5\u521b\u5efa\u4e00\u4e2a\u7b26\u5408\u6761\u4ef6\u7684\u6587\u4ef6\u548c\u76ee\u5f55\u3002 sudo touch /etc/rc5come sudo mkdir /etc/rc0123 \u9a8c\u8bc1\u540e\u5220\u9664\u3002 sudo rm /etc/rc5come sudo rm -rf /etc/rc0123 \u663e\u793a /etc \u76ee\u5f55\u4e0b\uff0c\u6240\u6709\u4ee5 .conf \u7ed3\u5c3e\uff0c\u4e14\u4ee5 m \u3001 n \u3001 r \u3001 p \u5f00\u5934\u7684\u6587\u4ef6\u6216\u76ee\u5f55\u5217\u8868\u3002 ls /etc/ [ mnrp ] *.conf \u53ea\u663e\u793a /root \u4e0b\u7684\u9690\u85cf\u6587\u4ef6\u548c\u76ee\u5f55\u5217\u8868\u3002 ls .* \u53ea\u663e\u793a/etc\u4e0b\u975e\u9690\u85cf\u76ee\u5f55\u5217\u8868\u3002 ls /etc/ [ ^. ] */ \u5c06 /etc \u76ee\u5f55\u4e0b\u6240\u6709\u6587\u4ef6\uff0c\u5907\u4efd\u5230 ~/test/ \u76ee\u5f55\u4e0b\uff0c\u5e76\u8981\u6c42\u5b50\u76ee\u5f55\u683c\u5f0f\u4e3a backupYYYY-mm-dd \uff0c\u5907\u4efd\u8fc7\u7a0b\u53ef\u89c1\u3002 sudo cp -av /etc/ ~/test/backup ` date +%F ` sudo cp -av /etc/ ~/test/backup ` date +%F_%H-%M-%S ` \u521b\u5efa\u76ee\u5f55 ~/testdir/dir1/x \uff0c ~/testdir/dir1/y \uff0c ~/testdir/dir1/x/a \uff0c ~/testdir/dir1/x/b \uff0c ~/testdir/dir1/y/a \uff0c ~/testdir/dir1/y/b \u3002 $ mkdir -p ~/testdir/dir1/ { x,y } / { a,b } $ tree ~/testdir/dir1/ /home/vagrant/testdir/dir1/ \u251c\u2500\u2500 x \u2502 \u251c\u2500\u2500 a \u2502 \u2514\u2500\u2500 b \u2514\u2500\u2500 y \u251c\u2500\u2500 a \u2514\u2500\u2500 b \u521b\u5efa\u76ee\u5f55 ~/testdir/dir2/x \uff0c ~/testdir/dir2/y \uff0c ~/testdir/dir2/x/a \uff0c ~/testdir/dir2/x/b \u3002 $ mkdir -p ~/testdir/dir2/ { x/ { a,b } ,y } $ tree ~/testdir/dir2/ /home/vagrant/testdir/dir2/ \u251c\u2500\u2500 x \u2502 \u251c\u2500\u2500 a \u2502 \u2514\u2500\u2500 b \u2514\u2500\u2500 y \u521b\u5efa\u76ee\u5f55 ~/testdir/dir3 \u3001 ~/testdir/dir4 \u3001 ~/testdir/dir5 \u3001 ~/testdir/dir5/dir6 \u3001 ~/testdir/dir5/dir7 \u3002 $ mkdir -p ~/testdir/dir { 3 ,4,5/dir { 6 ,7 }} $ tree ~/testdir /home/vagrant/testdir \u251c\u2500\u2500 dir1 \u2502 \u251c\u2500\u2500 x \u2502 \u2502 \u251c\u2500\u2500 a \u2502 \u2502 \u2514\u2500\u2500 b \u2502 \u2514\u2500\u2500 y \u2502 \u251c\u2500\u2500 a \u2502 \u2514\u2500\u2500 b \u251c\u2500\u2500 dir2 \u2502 \u251c\u2500\u2500 x \u2502 \u2502 \u251c\u2500\u2500 a \u2502 \u2502 \u2514\u2500\u2500 b \u2502 \u2514\u2500\u2500 y \u251c\u2500\u2500 dir3 \u251c\u2500\u2500 dir4 \u2514\u2500\u2500 dir5 \u251c\u2500\u2500 dir6 \u2514\u2500\u2500 dir7","title":"2.17.\u7ec3\u4e60"},{"location":"linux/SRE/02-filesystem/#3","text":"\u666e\u901a\u6587\u4ef6\uff08Normal Files\uff09 ASCII \u6587\u672c\u6587\u4ef6 \u53ef\u6267\u884c\u6587\u4ef6 \u56fe\u5f62\u6587\u4ef6 \u76ee\u5f55\uff08Directories\uff09 \u7ec4\u7ec7\u89c4\u5212\u78c1\u76d8\u4e0a\u7684\u6587\u4ef6 \u5305\u542b\u6587\u4ef6\u548c\u5b50\u76ee\u5f55 \u5b9e\u73b0\u5206\u5c42\u6587\u4ef6\u7cfb\u7edf \u94fe\u63a5\uff08Links\uff09 \u786c\u94fe\u63a5\uff08Hard links\uff09 \u78c1\u76d8\u4e0a\u6587\u4ef6\u7684\u8f85\u52a9\u6587\u4ef6\u540d \u591a\u4e2a\u6587\u4ef6\u540d\u5f15\u7528\u5355\u4e2a inode \u5f15\u7528\u7684\u6587\u4ef6\u5fc5\u987b\u5b58\u5728\u4e8e\u540c\u4e00\u4e2a\u6587\u4ef6\u7cfb\u7edf\u4e2d \u7b26\u53f7\u94fe\u63a5\uff08Symbolic links\uff09 \u5bf9\u78c1\u76d8\u4e0a\u5176\u4ed6\u6587\u4ef6\u7684\u5f15\u7528 inode \u5305\u542b\u5bf9\u53e6\u4e00\u4e2a\u6587\u4ef6\u540d\u7684\u5f15\u7528 \u88ab\u5f15\u7528\u7684\u6587\u4ef6\u53ef\u4ee5\u5b58\u5728\u4e8e\u540c\u4e00\u4e2a\u6587\u4ef6\u7cfb\u7edf\u4e2d\uff0c\u4e5f\u53ef\u4ee5\u5b58\u5728\u4e8e\u5176\u4ed6\u6587\u4ef6\u7cfb\u7edf\u4e2d \u7b26\u53f7\u94fe\u63a5\u53ef\u4ee5\u5f15\u7528\u4e0d\u5b58\u5728\u7684\u6587\u4ef6\uff08\u65ad\u5f00\u7684\u94fe\u63a5\uff09 \u5957\u63a5\u5b57Sockets - \u7528\u4e8e\u8fdb\u7a0b\u4e4b\u95f4\u7684\u53cc\u5411\u901a\u4fe1\u3002 \u7ba1\u9053\uff08Pipes\uff09(FIFOs) - \u7528\u4e8e\u4ece\u4e00\u4e2a\u8fdb\u7a0b\u5230\u53e6\u4e00\u4e2a\u8fdb\u7a0b\u7684\u5355\u5411\u901a\u4fe1\u3002 \u5757\u8bbe\u5907\uff08Block Devices\uff09 \u5b57\u7b26\u8bbe\u5907\uff08Character Devices\uff09","title":"3.\u4e03\u79cd\u6587\u4ef6\u7c7b\u578b"},{"location":"linux/SRE/02-filesystem/#31inode","text":"\u6587\u4ef6\u50a8\u5b58\u5728\u786c\u76d8\u4e0a\uff0c\u786c\u76d8\u7684\u6700\u5c0f\u5b58\u50a8\u5355\u4f4d\u53eb\u505a\u201c\u6247\u533a\u201d\uff08Sector\uff09\u3002\u6bcf\u4e2a\u6247\u533a\u50a8\u5b58512\u5b57\u8282\uff08\u76f8\u5f53\u4e8e0.5KB\uff09\u3002 \u64cd\u4f5c\u7cfb\u7edf\u8bfb\u53d6\u786c\u76d8\u7684\u65f6\u5019\uff0c\u4e0d\u662f\u4e00\u4e2a\u4e00\u4e2a\u6247\u533a\u8bfb\u53d6\uff0c\u800c\u662f\u4e00\u6b21\u6027\u8fde\u7eed\u8bfb\u53d6\u591a\u4e2a\u6247\u533a\uff0c\u6211\u4eec\u79f0\u4e3a\u8bfb\u53d6\u4e00\u4e2a\u201c\u5757\u201d\uff08block\uff09\u3002 \u5e38\u89c1\u7684block\u7684\u5927\u5c0f\u662f4KB\uff08\u8fde\u7eed\u516b\u4e2asector\u7ec4\u6210\u4e00\u4e2ablock\uff09\u3002 \u591a\u4e2a\u6247\u533a\u7ec4\u6210\u7684block\u662f\u6587\u4ef6\u5b58\u53d6\u7684*\u6700\u5c0f\u5355\u4f4d*\u3002 \u6587\u4ef6\u6570\u636e\u50a8\u5b58\u5728block\u4e2d\uff0c\u6587\u4ef6\u7684\u5143\u4fe1\u606f\uff0c\u6bd4\u5982\u6587\u4ef6\u7684\u521b\u5efa\u8005\u3001\u521b\u5efa\u65e5\u671f\u3001\u6587\u5927\u5c0f\u7b49\uff0c\u5b58\u50a8\u5728inode\uff0c\u5373\u201c\u7d22\u5f15\u8282\u70b9\u201d\u3002 \u6bcf\u4e00\u4e2a\u6587\u4ef6\u90fd\u6709\u5bf9\u5e94\u7684inode\uff0c\u91cc\u9762\u5305\u542b\u4e86\u4e0e\u8be5\u6587\u4ef6\u6709\u5173\u7684\u4e00\u4e9b\u4fe1\u606f\u3002\u6ce8\u610f\uff0c\u9664\u4e86\u6587\u4ef6\u540d\u4ee5\u5916\u7684\u5176\u5b83\u6587\u4ef6\u4fe1\u606f\uff0c\u90fd\u5b58\u5728inode\u4e4b\u4e2d\u3002 inode\u5305\u542b\u6587\u4ef6\u7684\u5143\u4fe1\u606f\u4e3b\u8981\u6709\uff1a \u6587\u4ef6\u7684\u5b57\u8282\u6570 \u6587\u4ef6\u62e5\u6709\u8005\u7684 User ID \u6587\u4ef6\u7684 Group ID \u6587\u4ef6\u7684\u8bfb\u3001\u5199\u3001\u6267\u884c\u6743\u9650 \u6587\u4ef6\u7684\u65f6\u95f4\u6233\uff0c\u5171\u6709\u4e09\u4e2a\uff1actime\u6307inode\u4e0a\u4e00\u6b21\u53d8\u52a8\u7684\u65f6\u95f4\uff0cmtime\u6307\u6587\u4ef6\u5185\u5bb9\u4e0a\u4e00\u6b21\u53d8\u52a8\u7684\u65f6\u95f4\uff0catime\u6307\u6587\u4ef6\u4e0a\u4e00\u6b21\u6253\u5f00\u7684\u65f6\u95f4\u3002 \u94fe\u63a5\u6570\uff0c\u5373\u6709\u591a\u5c11\u6587\u4ef6\u540d\u6307\u5411\u8fd9\u4e2ainode \u6587\u4ef6\u6570\u636eblock\u7684\u4f4d\u7f6e \u67e5\u770binode\u4fe1\u606f\u7684\u547d\u4ee4 stat \uff1a $ stat file1 File: file1 Size: 5 Blocks: 8 IO Block: 4096 regular file Device: fd02h/64770d Inode: 143 Links: 1 Access: ( 0644 /-rw-r--r-- ) Uid: ( 1000 / vagrant ) Gid: ( 10 / wheel ) Context: unconfined_u:object_r:user_home_t:s0 Access: 2022 -11-08 20 :49:26.019678244 +0800 Modify: 2022 -11-08 20 :49:26.019678244 +0800 Change: 2022 -11-08 20 :49:26.028678455 +0800 Birth: 2022 -11-08 20 :49:26.019678244 +0800 \u683c\u5f0f\u5316\u786c\u76d8\u65f6\uff0c\u64cd\u4f5c\u7cfb\u7edf\u4f1a\u81ea\u52a8\u5c06\u786c\u76d8\u5206\u6210\u4e24\u4e2a\u533a\u57df\u3002\u4e00\u4e2a\u662f\u6570\u636e\u533a\uff0c\u5b58\u653e\u6587\u4ef6\u6570\u636e\u3002\u53e6\u4e00\u4e2a\u662finode\u533a\uff08inode table\uff09\uff0c\u5b58\u653einode\u6240\u5305\u542b\u7684\u6587\u4ef6\u7684\u5143\u4fe1\u606f\u3002 \u6bcf\u4e2ainode\u8282\u70b9\u7684\u5927\u5c0f\uff0c\u4e00\u822c\u662f128\u5b57\u8282\u6216256\u5b57\u8282\u3002inode\u8282\u70b9\u7684\u603b\u6570\uff0c\u5728\u683c\u5f0f\u5316\u65f6\u5c31\u786e\u5b9a\u4e86\uff0c\u4e00\u822c\u662f\u6bcf1KB\u6216\u6bcf2KB\u5c31\u8bbe\u7f6e\u4e00\u4e2ainode\u3002 \u5047\u5b9a\u4e00\u57571GB\u7684\u786c\u76d8\uff0c\u5982\u679c\u6bcf\u4e2ainode\u8282\u70b9\u7684\u5927\u5c0f\u4e3a128\u5b57\u8282\uff0c\u4e14\u6bcf1KB\u5c31\u8bbe\u7f6e\u4e00\u4e2ainode\uff0c\u5219inode table\u7684\u5927\u5c0f\u5c31\u4f1a\u8fbe\u5230128MB\uff0c\u5360\u6574\u5757\u786c\u76d8\u768412.8%\u3002 \u901a\u8fc7 df \u547d\u4ee4\u67e5\u770b\u6bcf\u4e2a\u786c\u76d8\u5206\u533a\u7684inode\u603b\u6570\u548c\u5df2\u7ecf\u4f7f\u7528\u7684\u6570\u91cf\u3002 \u7531\u4e8e\u6bcf\u4e2a\u6587\u4ef6\u90fd\u5fc5\u987b\u6709\u4e00\u4e2ainode\uff0c\u56e0\u6b64\u6709\u53ef\u80fd\u53d1\u751finode\u5df2\u7ecf\u7528\u5149\uff0c\u4f46\u662f\u786c\u76d8\u8fd8\u672a\u5b58\u6ee1\u7684\u60c5\u51b5\uff0c\u4e5f\u5c31\u65e0\u6cd5\u5728\u786c\u76d8\u4e0a\u521b\u5efa\u65b0\u6587\u4ef6\u3002 $ df -i Filesystem Inodes IUsed IFree IUse% Mounted on tmpfs 497897 872 497025 1 % /run /dev/mapper/ubuntu--vg-ubuntu--lv 3211264 81473 3129791 3 % / tmpfs 497897 1 497896 1 % /dev/shm tmpfs 497897 3 497894 1 % /run/lock /dev/sda2 131072 316 130756 1 % /boot tmpfs 99579 25 99554 1 % /run/user/1000 \u4e0b\u9762\u547d\u4ee4\u53ef\u4ee5\u67e5\u770b\u6bcf\u4e2ainode\u8282\u70b9\u7684\u5927\u5c0f\uff1a $ sudo dumpe2fs -h /dev/sda2 | grep \"Inode size\" dumpe2fs 1 .46.5 ( 30 -Dec-2021 ) Inode size: 256 \u6bcf\u4e2ainode\u90fd\u6709\u4e00\u4e2a\u53f7\u7801\uff0c\u64cd\u4f5c\u7cfb\u7edf\u7528inode\u53f7\u7801\u6765\u8bc6\u522b\u4e0d\u540c\u7684\u6587\u4ef6\uff0c\u6ce8\u610f\uff0c\u4e0d\u662f\u901a\u8fc7\u6587\u4ef6\u540d\u6765\u8bc6\u522b\u4e0d\u540c\u6587\u4ef6\u3002\u4ece\u64cd\u4f5c\u7cfb\u7edf\u89d2\u5ea6\u770b\uff0c\u6587\u4ef6\u540d\u53ea\u662finode\u53f7\u7801\u5bf9\u4e00\u4e2a\u522b\u540d\u3002 \u7528\u6237\u901a\u8fc7\u6587\u4ef6\u540d\uff0c\u6253\u5f00\u67d0\u4e2a\u6587\u4ef6\u7684\u8fc7\u7a0b\uff0c\u64cd\u4f5c\u7cfb\u7edf\u5206\u6210\u4e09\u6b65\u5b8c\u6210\uff1a \u9996\u5148\uff0c\u7cfb\u7edf\u627e\u5230\u8fd9\u4e2a\u6587\u4ef6\u540d\u5bf9\u5e94\u7684inode\u53f7\u7801\u3002 \u5176\u6b21\uff0c\u901a\u8fc7inode\u53f7\uff0c\u83b7\u53d6inode\u4fe1\u606f\u3002 \u7b2c\u4e09\uff0c\u901a\u8fc7inode\u4fe1\u606f\uff0c\u627e\u5230\u6587\u4ef6\u6570\u636e\u6240\u5728\u7684block\uff0c\u8bfb\u51fa\u6570\u636e\u3002 \u901a\u8fc7 ls -i \u547d\u4ee4\uff0c\u53ef\u4ee5\u5f97\u5230\u6587\u4ef6\u5bf9\u5e94\u7684inode\u53f7\uff1a $ ls -i file1 143 file1 \u76ee\u5f55\uff08directory\uff09\u4e5f\u662f\u4e00\u79cd\u6587\u4ef6\u3002\u6253\u5f00\u76ee\u5f55\uff0c\u5b9e\u9645\u4e0a\u5c31\u662f\u6253\u5f00\u76ee\u5f55\u6587\u4ef6\u3002 \u76ee\u5f55\u6587\u4ef6\u7684\u7ed3\u6784\u662f\u7531\u4e00\u4e2a\u5305\u542b\u4e00\u7cfb\u5217\u76ee\u5f55\u9879\uff08dirent\uff09\u7684\u5217\u8868\u7ec4\u6210\u3002 \u6bcf\u4e2a\u76ee\u5f55\u9879\u7531\u4e24\u90e8\u5206\u7ec4\u6210\uff1a\u6240\u5305\u542b\u6587\u4ef6\u7684\u6587\u4ef6\u540d\uff0c\u4ee5\u53ca\u8be5\u6587\u4ef6\u540d\u5bf9\u5e94\u7684inode\u53f7\u3002 \u547d\u4ee4 ls -i \u5217\u51fa\u6574\u4e2a\u76ee\u5f55\u6587\u4ef6\uff0c\u5373\u6587\u4ef6\u540d\u548cinode\u53f7\uff1a $ ls -i 143 file1 140 file2 139 test $ ls -il 143 -rw-r--r--. 1 vagrant wheel 5 Nov 8 20 :49 file1 140 -rw-r--r--. 1 vagrant wheel 0 Oct 1 21 :35 file2 139 drwxr-xr-x. 5 vagrant wheel 4096 Nov 9 22 :00 test","title":"3.1.inode\u7ed3\u6784"},{"location":"linux/SRE/02-filesystem/#32","text":"\u786c\u94fe\u63a5 \uff08Hard links\uff09\u786c\u94fe\u63a5\u662f\u5b58\u50a8\u5377\u4e0a\u6587\u4ef6\u7684\u76ee\u5f55\u5f15\u7528\u6216\u6307\u9488\u3002 \u6587\u4ef6\u540d\u662f\u5b58\u50a8\u5728\u76ee\u5f55\u7ed3\u6784\u4e2d\u7684\u6807\u7b7e\uff0c\u76ee\u5f55\u7ed3\u6784\u6307\u5411\u6587\u4ef6\u6570\u636e\u3002 \u56e0\u6b64\uff0c\u53ef\u4ee5\u5c06\u591a\u4e2a\u6587\u4ef6\u540d\u4e0e\u540c\u4e00\u6587\u4ef6\u5173\u8054\u3002 \u901a\u8fc7\u4e0d\u540c\u7684\u6587\u4ef6\u540d\u8bbf\u95ee\u65f6\uff0c\u6240\u505a\u7684\u4efb\u4f55\u66f4\u6539\u90fd\u662f\u9488\u5bf9\u6e90\u6587\u4ef6\u6570\u636e\u3002 \u7b26\u53f7\u94fe\u63a5 \uff08Symbolic links\uff09: \u7b26\u53f7\u94fe\u63a5\u5305\u542b\u4e00\u4e2a\u6587\u672c\u5b57\u7b26\u4e32\uff0c\u64cd\u4f5c\u7cfb\u7edf\u5c06\u5176\u89e3\u91ca\u4e3a\u53e6\u4e00\u4e2a\u6587\u4ef6\u6216\u76ee\u5f55\u3002 \u5b83\u672c\u8eab\u5c31\u662f\u4e00\u4e2a\u6587\u4ef6\uff0c\u53ef\u4ee5\u72ec\u7acb\u4e8e\u76ee\u6807\u800c\u5b58\u5728\u3002 \u5982\u679c\u5220\u9664\u4e86\u7b26\u53f7\u94fe\u63a5\uff0c\u5219\u5176\u76ee\u6807\u6587\u4ef6\u6216\u76ee\u5f55\u4e0d\u53d7\u5f71\u54cd\u3002 \u5982\u679c\u79fb\u52a8\uff0c\u91cd\u547d\u540d\u6216\u5220\u9664\u76ee\u6807\u6587\u4ef6\u6216\u76ee\u5f55\uff0c\u5219\u7528\u4e8e\u6307\u5411\u5b83\u7684\u4efb\u4f55\u7b26\u53f7\u94fe\u63a5\u5c06\u7ee7\u7eed\u5b58\u5728\uff0c\u4f46\u6307\u5411\u7684\u662f\u4e00\u4e2a\u4e0d\u5b58\u5728\u7684\u6587\u4ef6\u3002 \u4ec5\u5f53\u6587\u4ef6\u548c\u94fe\u63a5\u6587\u4ef6\u4f4d\u4e8e\u540c\u4e00\u6587\u4ef6\u7cfb\u7edf\uff08\u5728\u540c\u4e00\u5206\u533a\u4e0a\uff09\u65f6\uff0c\u624d\u80fd\u4f7f\u7528\u786c\u94fe\u63a5\uff0c\u56e0\u4e3ainode\u7f16\u53f7\u5728\u540c\u4e00\u6587\u4ef6\u7cfb\u7edf\u4e2d\u4ec5\u662f\u552f\u4e00\u7684\u3002 \u53ef\u4ee5\u4f7f\u7528 ln \u547d\u4ee4\u521b\u5efa\u786c\u94fe\u63a5\uff0c\u6307\u5411\u5df2\u5b58\u5728\u6587\u4ef6\u7684inode\uff0c\u53ef\u4ee5\u901a\u8fc7\u6587\u4ef6\u540d\u6216\u8005\u786c\u94fe\u63a5\u540d\u8bbf\u95ee\u6587\u4ef6\u3002 \u53ef\u4ee5\u4f7f\u7528 ln -s \u9009\u9879\u521b\u5efa\u7b26\u53f7\u94fe\u63a5\u3002 \u4e00\u4e2a\u7b26\u53f7\u94fe\u63a5\u4f1a\u88ab\u5206\u914d\u4e00\u4e2a\u5355\u72ec\u7684inode\uff0c\u5e76\u6307\u5411\u4e00\u4e2a\u6587\u4ef6\uff0c\u6240\u4ee5\u53ef\u4ee5\u660e\u663e\u533a\u5206\u7b26\u53f7\u94fe\u63a5\u6587\u4ef6\u548c\u5b9e\u9645\u6587\u4ef6\u3002 \u6587\u4ef6\u7cfb\u7edf\u672c\u8d28\u4e0a\u662f\u4e00\u4e2a\u7528\u4e8e\u8ddf\u8e2a\u5206\u533a\u5377\u4e2d\u7684\u6587\u4ef6\u7684\u6570\u636e\u5e93\u3002 \u5bf9\u4e8e\u666e\u901a\u6587\u4ef6\uff0c\u5206\u914d\u6570\u636e\u5757\u4ee5\u5b58\u50a8\u6587\u4ef6\u7684\u6570\u636e\uff0c\u5206\u914dinode\u4ee5\u6307\u5411\u6570\u636e\u5757\u4ee5\u53ca\u5b58\u50a8\u5173\u4e8e\u6587\u4ef6\u7684\u5143\u6570\u636e\uff0c\u7136\u540e\u5c06\u6587\u4ef6\u540d\u5206\u914d\u7ed9inode\u3002 \u786c\u94fe\u63a5\u662f\u4e0e\u73b0\u6709inode\u5173\u8054\u7684\u8f85\u52a9\u6587\u4ef6\u540d\u3002 \u5bf9\u4e8e\u7b26\u53f7\u94fe\u63a5\uff0c\u5c06\u4e3a\u65b0\u7684inode\u5206\u914d\u4e00\u4e2a\u4e0e\u4e4b\u5173\u8054\u7684\u65b0\u6587\u4ef6\u540d\uff0c\u4f46inode\u5f15\u7528\u53e6\u4e00\u4e2a\u6587\u4ef6\u540d\u800c\u4e0d\u662f\u5f15\u7528\u6570\u636e\u5757\u3002 \u67e5\u770b\u6587\u4ef6\u540d\u548cinode\u4e4b\u95f4\u5173\u7cfb\u7684\u4e00\u4e2a\u65b9\u6cd5\u662f\u4f7f\u7528 ls -il \u547d\u4ee4\u3002inode\u7684\u5178\u578b\u5927\u5c0f\u4e3a128\u4f4d\uff0c\u6570\u636e\u5757\u7684\u5927\u5c0f\u8303\u56f4\u53ef\u4ee5\u662f1k\uff0c2k\uff0c4k\u6216\u66f4\u5927\uff0c\u5177\u4f53\u53d6\u51b3\u4e8e\u6587\u4ef6\u7cfb\u7edf\u7c7b\u578b\u3002 \u8f6f\u8fde\u63a5\u53ef\u4ee5\u9488\u5bf9\u76ee\u5f55\uff0c\u786c\u8fde\u63a5\u53ea\u80fd\u9488\u5bf9\u6587\u4ef6\u3002 \u786c\u94fe\u63a5\u76f8\u5f53\u4e8e\u589e\u52a0\u4e86\u4e00\u4e2a\u767b\u8bb0\u9879\uff0c\u4f7f\u5f97\u539f\u6765\u7684\u6587\u4ef6\u591a\u4e86\u4e00\u4e2a\u540d\u5b57\uff0c\u81f3\u4e8einode\u90fd\u6ca1\u53d8\u3002\u6240\u8c13\u7684\u767b\u8bb0\u9879\u5176\u5b9e\u662f\u76ee\u5f55\u6587\u4ef6\u4e2d\u7684\u4e00\u4e2a\u6761\u76ee(\u76ee\u5f55\u9879)\uff0c\u4f7f\u7528hard link \u662f\u8ba9\u591a\u4e2a\u4e0d\u540c\u7684\u76ee\u5f55\u9879\u6307\u5411\u540c\u4e00\u4e2a\u6587\u4ef6\u7684inode\uff0c\u6ca1\u6709\u591a\u4f59\u7684\u5185\u5bb9\u9700\u8981\u5b58\u50a8\u5728\u78c1\u76d8\u6247\u533a\u4e2d\uff0c\u6240\u4ee5hardlink\u4e0d\u5360\u7528\u989d\u5916\u7684\u7a7a\u95f4\u3002 \u7b26\u53f7\u94fe\u63a5\u6709\u5355\u72ec\u7684inode\uff0c\u5728inode\u4e2d\u5b58\u653e\u53e6\u4e00\u4e2a\u6587\u4ef6\u7684\u8def\u5f84\u800c\u4e0d\u662f\u6587\u4ef6\u6570\u636e\uff0c\u6240\u4ee5\u7b26\u53f7\u94fe\u63a5\u4f1a\u5360\u7528\u989d\u5916\u7684\u7a7a\u95f4\u3002 \u7279\u5f81 \u786c\u94fe\u63a5 \u7b26\u53f7\u94fe\u63a5 \u672c\u8d28 \u540c\u4e00\u4e2a\u6587\u4ef6 \u4e0d\u662f\u540c\u4e00\u4e2a\u6587\u4ef6 \u8de8\u8bbe\u5907 \u4e0d\u652f\u6301 \u652f\u6301 inode \u76f8\u540c \u4e0d\u540c \u94fe\u63a5\u6570 \u521b\u5efa\u786c\u94fe\u63a5\uff0c\u94fe\u63a5\u6570\u4f1a\u589e\u52a0\uff0c\u5220\u9664\u5219\u51cf\u5c11 \u521b\u5efa\u6216\u5220\u9664\uff0c\u94fe\u63a5\u6570\u90fd\u4e0d\u53d8 \u6587\u4ef6\u5939 \u4e0d\u652f\u6301 \u652f\u6301 \u76f8\u5bf9\u8def\u5f84 \u539f\u59cb\u6587\u4ef6\u7684\u76f8\u5bf9\u8def\u5f84\u662f\u76f8\u5bf9\u4e8e\u5f53\u524d\u5de5\u4f5c\u76ee\u5f55 \u539f\u59cb\u6587\u4ef6\u7684\u76f8\u5bf9\u8def\u5f84\u662f\u76f8\u5bf9\u4e8e\u94fe\u63a5\u6587\u4ef6\u7684\u76f8\u5bf9\u8def\u5f84 \u5220\u9664\u6e90\u6587\u4ef6 \u53ea\u662f\u94fe\u63a5\u6570\u51cf\u5c11\uff0c\u94fe\u63a5\u6587\u4ef6\u8bbf\u95ee\u4e0d\u53d7\u5f71\u54cd \u94fe\u63a5\u6587\u4ef6\u5c06\u65e0\u6cd5\u8bbf\u95ee \u6587\u4ef6\u7c7b\u578b \u548c\u6e90\u6587\u4ef6\u76f8\u540c \u94fe\u63a5\u6587\u4ef6\uff0c\u548c\u6e90\u6587\u4ef6\u65e0\u5173 \u6587\u4ef6\u5927\u5c0f \u548c\u6e90\u6587\u4ef6\u76f8\u540c \u6e90\u6587\u4ef6\u7684\u8def\u5f84\u7684\u957f\u5ea6","title":"3.2.\u94fe\u63a5\u7c7b\u578b"},{"location":"linux/SRE/02-filesystem/#33","text":"\u8bbe\u5907\u6587\u4ef6 \uff08Device File\uff09\u8868\u793a\u786c\u4ef6\uff08\u7f51\u5361\u9664\u5916\uff09\u3002 \u6bcf\u4e2a\u786c\u4ef6\u90fd\u7531\u4e00\u4e2a\u8bbe\u5907\u6587\u4ef6\u8868\u793a\u3002 \u7f51\u5361\u662f\u63a5\u53e3\u3002 \u8bbe\u5907\u6587\u4ef6\u628a\u5185\u6838\u9a71\u52a8\u548c\u7269\u7406\u786c\u4ef6\u8bbe\u5907\u8fde\u63a5\u8d77\u6765\u3002 \u5185\u6838\u9a71\u52a8\u7a0b\u5e8f\u901a\u8fc7\u5bf9\u8bbe\u5907\u6587\u4ef6\u8fdb\u884c\u8bfb\u5199\uff08\u6b63\u786e\u7684\u683c\u5f0f\uff09\u6765\u5b9e\u73b0\u5bf9\u786c\u4ef6\u7684\u8bfb\u5199\u3002 \u7c7b\u578b\uff1a \u5757\u8bbe\u5907\uff08Block Devices\uff09\uff1a\u5757\u8bbe\u5907\uff08\u901a\u5e38\uff09\u5728512\u5b57\u8282\u7684\u5927\u5757\u4e2d\u8bfb\u53d6/\u5199\u5165\u4fe1\u606f\u3002 \u5b57\u7b26\u8bbe\u5907\uff08Character Devices\uff09\uff1a\u5b57\u7b26\u8bbe\u5907\u4ee5\u5b57\u7b26\u65b9\u5f0f\u8bfb\u53d6/\u5199\u5165\u4fe1\u606f\u3002 \u5b57\u7b26\u8bbe\u5907\u76f4\u63a5\u63d0\u4f9b\u5bf9\u786c\u4ef6\u8bbe\u5907\u7684\u65e0\u7f13\u51b2\u8bbf\u95ee\u3002 \u6709\u65f6\u79f0\u4e3a\u88f8\u8bbe\u5907\uff08raw devices\uff09\u3002\uff08\u6ce8\u610f\uff1a\u88f8\u8bbe\u5907\u88ab\u89c6\u4e3a\u5b57\u7b26\u8bbe\u5907\uff0c\u4e0d\u662f\u5757\u8bbe\u5907\uff09 \u901a\u8fc7\u8f85\u4ee5\u4e0d\u540c\u9009\u9879\uff0c\u53ef\u4ee5\u5e7f\u6cdb\u800c\u591a\u6837\u5730\u5e94\u7528\u548c\u4f7f\u7528\u5b57\u7b26\u8bbe\u5907\u3002 \u5f53\u5185\u6838\u53d1\u73b0\u8bbe\u5907\u65f6\u7531\u64cd\u4f5c\u7cfb\u7edf udev \u81ea\u52a8\u521b\u5efa\u3002","title":"3.3.\u8bbe\u5907\u6587\u4ef6"},{"location":"linux/SRE/02-filesystem/#34","text":"\u76ee\u6807\uff1a\u4ee5Rocky 9\u4e3a\u4f8b\u3002 \u67e5\u770b\u8f6f/\u786c\u94fe\u63a5\u6587\u4ef6\u7684\u7279\u5f81\u3002 \u67e5\u770b\u76ee\u5f55\u7ed3\u6784\u3002 \u53ef\u4ee5\u901a\u8fc7\u4e0b\u9762\u547d\u4ee4\u5f97\u5230\u5f53\u524d\u7cfb\u7edf\u76842\u7ea7\u76ee\u5f55\u7684\u7ed3\u6784\u3002 tree -L 2 -d / \u521b\u5efa\u7ec3\u4e60\u76ee\u5f55\u3002 mkdir data mkdir -p data/typelink cd data \u521b\u5efa\u786c\u94fe\u63a5\u3002\u6ce8\u610f\uff1a file \u3001 hardlinkfile1 \u3001 hardlinkfile2 \u6587\u4ef6\u7684\u94fe\u63a5\u4f4d\u7f6e\u7684\u6570\u503c\u7684\u53d8\u5316) echo \"it's original file\" > file ln file hardlinkfile1 ln -s file symlinkfile1 ln -s file symlinkfile2 \u6267\u884c ls -l \u547d\u4ee4\u53ef\u4ee5\u5f97\u5230\u4e0b\u9762\u7684\u7ed3\u679c\uff1a -rw-r--r--. 2 vagrant wheel 19 Nov 1 10 :42 file -rw-r--r--. 2 vagrant wheel 19 Nov 1 10 :42 hardlinkfile1 lrwxrwxrwx. 1 vagrant wheel 4 Nov 1 10 :43 symlinkfile1 -> file lrwxrwxrwx. 1 vagrant wheel 4 Nov 1 10 :43 symlinkfile2 -> file \u521b\u5efa\u53e6\u5916\u4e00\u4e2a\u786c\u94fe\u63a5\u3002 ln file hardlinkfile2 \u6267\u884c ls -l \u547d\u4ee4\u53ef\u4ee5\u5f97\u5230\u4e0b\u9762\u7684\u7ed3\u679c\uff1a -rw-r--r--. 3 vagrant wheel 19 Nov 1 10 :42 file -rw-r--r--. 3 vagrant wheel 19 Nov 1 10 :42 hardlinkfile1 -rw-r--r--. 3 vagrant wheel 19 Nov 1 10 :42 hardlinkfile2 lrwxrwxrwx. 1 vagrant wheel 4 Nov 1 10 :43 symlinkfile1 -> file lrwxrwxrwx. 1 vagrant wheel 4 Nov 1 10 :43 symlinkfile2 -> file \u4fee\u6539 file \u6587\u4ef6\u7684\u5185\u5bb9\u3002 echo \"add oneline\" >> file \u901a\u8fc7\u547d\u4ee4 cat file \u67e5\u770b\u5f53\u524d file \u7684\u5185\u5bb9\u3002 it ' s original file add oneline \u901a\u8fc7\u4e0b\u9762\u7684\u547d\u4ee4\uff0c\u53ef\u4ee5\u770b\u5230\u6240\u4ee5\u8f6f/\u786c\u94fe\u63a5\u6587\u4ef6\u5185\u5bb9\u90fd\u66f4\u65b0\u4e86\uff0c\u548c file \u6587\u4ef6\u66f4\u65b0\u540e\u7684\u5185\u5bb9\u4fdd\u6301\u4e00\u81f4\u3002 cat hardlinkfile1 cat hardlinkfile2 cat symlinkfile1 cat symlinkfile2 \u5bf9\u6587\u4ef6 symlinkfile1 \u518d\u521b\u5efa\u65b0\u7684\u8f6f\u8fde\u63a5\u3002 ln -s symlinkfile1 symlinkfile1-1 \u901a\u8fc7\u547d\u4ee4 ls -il \u67e5\u770b\u73b0\u5728\u7684\u76ee\u5f55\u4fe1\u606f\u3002 67274680 -rw-r--r--. 3 vagrant wheel 31 Nov 1 11 :14 file 67274680 -rw-r--r--. 3 vagrant wheel 31 Nov 1 11 :14 hardlinkfile1 67274680 -rw-r--r--. 3 vagrant wheel 31 Nov 1 11 :14 hardlinkfile2 67274681 lrwxrwxrwx. 1 vagrant wheel 4 Nov 1 10 :43 symlinkfile1 -> file 67274683 lrwxrwxrwx. 1 vagrant wheel 12 Nov 1 11 :20 symlinkfile1-1 -> symlinkfile1 67274682 lrwxrwxrwx. 1 vagrant wheel 4 Nov 1 10 :43 symlinkfile2 -> file \u8bfb\u53d6\u8f6f\u94fe\u63a5\u6587\u4ef6\u7684\u6e90\u6587\u4ef6\u4fe1\u606f readlink symlinkfile1 readlink symlinkfile2 \u6ce8\u610f\uff0c\u5bf9\u4e8e symlinkfile1-1 \u7684\u60c5\u51b5\u6709\u4e9b\u4e0d\u540c\u3002 readlink symlinkfile1-1 \u4e0a\u9762\u547d\u4ee4\u8fd4\u56de\u7ed3\u679c symlinkfile1 \u4ecd\u7136\u662f\u4e00\u4e2a\u7b26\u53f7\u94fe\u63a5\u6587\u4ef6\u3002\u901a\u8fc7 readlink -f \u53ef\u4ee5\u76f4\u63a5\u5b9a\u4f4d\u771f\u6b63\u7684\u6e90\u6587\u4ef6\u3002 readlink -f symlinkfile1-1 \u4e0a\u9762\u7684\u8fd4\u56de\u7ed3\u679c /data/linktype/file \u662f symlinkfile1-1 \u771f\u6b63\u7684\u6e90\u6587\u4ef6\u3002 \u663e\u793a data \u76ee\u5f55\u4e0b\u7684\u6587\u4ef6\u548c\u5b50\u76ee\u5f55\uff1a cd ~ tree ./data \u8fd0\u884c\u7ed3\u679c\uff1a ./data \u251c\u2500\u2500 file \u251c\u2500\u2500 hardlinkfile1 \u251c\u2500\u2500 hardlinkfile2 \u251c\u2500\u2500 symlinkfile1 -> file \u251c\u2500\u2500 symlinkfile1-1 -> symlinkfile1 \u251c\u2500\u2500 symlinkfile2 -> file \u2514\u2500\u2500 typelink \u53ea\u663e\u793a data \u76ee\u5f55\u4e0b\u7684\u5b50\u76ee\u5f55\uff1a tree -d ./data \u8fd0\u884c\u7ed3\u679c\uff1a ./data \u2514\u2500\u2500 typelink \u663e\u793a data \u76ee\u5f55\u4e0b\u7684\u6587\u4ef6\u548c\u5b50\u76ee\u5f55\uff0c\u5305\u542b\u5168\u76ee\u5f55\uff1a tree -f ./data \u8fd0\u884c\u7ed3\u679c\uff1a ./data \u251c\u2500\u2500 ./data/file \u251c\u2500\u2500 ./data/hardlinkfile1 \u251c\u2500\u2500 ./data/hardlinkfile2 \u251c\u2500\u2500 ./data/symlinkfile1 -> file \u251c\u2500\u2500 ./data/symlinkfile1-1 -> symlinkfile1 \u251c\u2500\u2500 ./data/symlinkfile2 -> file \u2514\u2500\u2500 ./data/typelink","title":"3.4.\u7ec3\u4e60"},{"location":"linux/SRE/02-filesystem/#4","text":"\u6267\u884c\u547d\u4ee4 ls -ihl \uff0c\u53ef\u4ee5\u5f97\u5230\u4e0b\u9762\u7684\u8f93\u51fa\u7ed3\u679c\uff08Rocky 9\uff09\u3002 67274680 -rw-r--r--. 3 vagrant wheel 31 Nov 1 11 :14 file 67274680 -rw-r--r--. 3 vagrant wheel 31 Nov 1 11 :14 hardlinkfile1 67274680 -rw-r--r--. 3 vagrant wheel 31 Nov 1 11 :14 hardlinkfile2 67274681 lrwxrwxrwx. 1 vagrant wheel 4 Nov 1 10 :43 symlinkfile1 -> file 67274683 lrwxrwxrwx. 1 vagrant wheel 12 Nov 1 11 :20 symlinkfile1-1 -> symlinkfile1 67274682 lrwxrwxrwx. 1 vagrant wheel 4 Nov 1 10 :43 symlinkfile2 -> file 33555262 drwxr-xr-x. 2 vagrant wheel 6 Nov 1 11 :30 typelink \u4ee5 67274680 -rw-r--r--. 3 vagrant wheel 31 Nov 1 11:14 file \u4e3a\u4f8b\uff1a 67274680 : inode \u7d22\u5f15\u8282\u70b9\u7f16\u53f7\u3002 -rw-r--r-- \uff1a\u6587\u4ef6\u7c7b\u578b\u53ca\u6743\u9650 - \uff1a\u6587\u4ef6\u7c7b\u578b\uff0c\u4f8b\u5b50\u4e2d\u51fa\u73b0\u4e86\u4e09\u79cd\uff0c - \uff0c l \u548c d \u3002 - \uff1a\u666e\u901a\u6587\u4ef6 d \uff1a\u76ee\u5f55 l \uff1a\u7b26\u53f7\u94fe\u63a5\u6587\u4ef6\uff08link\uff09 b \uff1a\u5757\u8bbe\u5907\uff08block\uff09 c \uff1a\u5b57\u7b26\u8bbe\u5907\uff08character\uff09 p \uff1a\u7ba1\u9053\u6587\u4ef6\uff08pipe\uff09 s \uff1a\u5957\u63a5\u5b57\u6587\u4ef6\uff08socket\uff09 rw-r--r-- \uff1a\u6587\u4ef6\u6743\u9650\uff0c\u4ece\u5de6\u5230\u53f3\u4f9d\u6b21\u4e3a\uff1a rw- \uff1a\u6587\u4ef6\u5c5e\u4e3b\u6743\u9650\uff0c\u4f8b\u5b50\u4e2d\u662f vagrant \u3002 r-- \uff1a\u6587\u4ef6\u5c5e\u7ec4\u7684\u6743\u9650\uff0c\u4f8b\u5b50\u4e2d\u662f wheel \u3002 r-- \uff1a\u5176\u4ed6\u7ec4\u7684\u6743\u9650\u3002 . \uff1a\u8fd9\u4e2a\u70b9\u8868\u793a\u6587\u4ef6\u5e26\u6709SELinux\u7684\u5b89\u5168\u4e0a\u4e0b\u6587\uff08SELinux Contexts\uff09\u3002\u5173\u95edSELinux\uff0c\u65b0\u521b\u5efa\u7684\u6587\u4ef6\u5c31\u4e0d\u4f1a\u518d\u6709\u8fd9\u4e2a\u70b9\u4e86\u3002\u4f46\u662f\uff0c\u4ee5\u524d\u521b\u5efa\u7684\u6587\u4ef6\u672c\u6765\u6709\u8fd9\u4e2a\u70b9\u7684\u8fd8\u4f1a\u663e\u793a\u8fd9\u4e2a\u70b9\uff08\u867d\u7136SELinux\u4e0d\u8d77\u4f5c\u7528\u4e86\uff09\u3002 3 \uff1a\u786c\u94fe\u63a5\u6570\uff0c\u4f8b\u5b50\u4e2d file \u548c hardlinkfile1 \u548c hardlinkfile2 \u4e4b\u95f4\u662f\u786c\u94fe\u63a5\uff0c\u6240\u4ee5\u8fd9\u4e09\u4e2a\u6587\u4ef6\u7684\u786c\u94fe\u63a5\u6570\u90fd\u662f 3 \u3002 vagrant \uff1a\u6587\u4ef6\u5c5e\u4e3b wheel \uff1a\u6587\u4ef6\u5c5e\u7ec4 31 \uff1a\u6587\u4ef6\u6216\u76ee\u5f55\u7684\u5927\u5c0f Nov 1 11:14 \uff1a\u6587\u4ef6\u6216\u76ee\u5f55\u7684\u521b\u5efa\u65e5\u671f\u548c\u65f6\u95f4 file \uff1a\u6587\u4ef6\u6216\u76ee\u5f55\u540d\u79f0 \u4e0b\u9762\u662f\u547d\u4ee4 ls -ihl \u5728openSUSE\u548cUbuntu\u4e0a\u7684\u663e\u793a\u7ed3\u679c\u3002 $ ls -ihl 233647 -rw-r--r-- 3 vagrant wheel 31 Nov 1 15 :52 file 233647 -rw-r--r-- 3 vagrant wheel 31 Nov 1 15 :52 hardlinkfile1 233647 -rw-r--r-- 3 vagrant wheel 31 Nov 1 15 :52 hardlinkfile2 233648 lrwxrwxrwx 1 vagrant wheel 4 Nov 1 15 :52 symlinkfile1 -> file 233650 lrwxrwxrwx 1 vagrant wheel 12 Nov 1 15 :52 symlinkfile1-1 -> symlinkfile1 233649 lrwxrwxrwx 1 vagrant wheel 4 Nov 1 15 :52 symlinkfile2 -> file 233646 drwxr-xr-x 1 vagrant wheel 0 Nov 1 15 :51 typelink","title":"4.\u6587\u4ef6\u5c5e\u6027\u8bf4\u660e"},{"location":"linux/SRE/02-filesystem/#5","text":"\u6807\u51c6\u8f93\u5165\u8f93\u51fa\uff0c\u5373I/O\uff0cI/O\u7684I\u662fInput\uff0cO\u662foutput\u3002 I\uff1a\u4ece\u5916\u90e8\u8bbe\u5907\u8f93\u5165\u5230\u5185\u5b58 O\uff1a\u4ece\u5185\u5b58\u8f93\u51fa\u5230\u5916\u90e8\u8bbe\u5907 \u6807\u51c6\u8f93\u5165\u548c\u6807\u51c6\u8f93\u51fa\u662f\u7528\u4e8eIO\u7684\uff0c\u5b83\u4eec\u5c5e\u4e8e\u5916\u90e8\u8bbe\u5907\uff08\u903b\u8f91\u4e0a\u7684\u5916\u90e8\u8bbe\u5907\uff09\uff0c\u4e0d\u662f\u5185\u5b58\u3002 linux\u4e2d\u4e00\u5207\u8bbe\u5907\u7686\u662f\u6587\u4ef6\uff01\u56e0\u6b64\u6807\u51c6\u8f93\u5165\u548c\u8f93\u51fa\u672c\u8d28\u5c31\u662f\u6587\u4ef6\uff0c\u5916\u90e8\u8bbe\u5907\u4ee5\u6587\u4ef6\u5f62\u5f0f\u8868\u73b0\u3002 \u5728Linux\u7cfb\u7edf\u4e2d\uff0c\u6807\u51c6\u8f93\u5165\u548c\u6807\u51c6\u8f93\u51fa\u5bf9\u5e94\u7684\u6587\u4ef6\u662f /dev/stdin \u548c /dev/stdout \u8fd9\u4e24\u4e2a\u6587\u4ef6\u3002 \u4ece\u6807\u51c6\u8f93\u5165\u8bfb\uff0c\u4ece\u903b\u8f91\u4e0a\u8bb2\uff0c\u5c31\u662f\u6253\u5f00 /dev/stdin \u8fd9\u4e2a\u6587\u4ef6\uff0c\u5e76\u8bfb\u5165\u6587\u4ef6\u5185\u5bb9\u3002 \u8f93\u51fa\u5230\u6807\u51c6\u8f93\u51fa\uff0c\u4ece\u903b\u8f91\u4e0a\u8bb2\uff0c\u5c31\u662f\u6253\u5f00 /dev/stdout \u8fd9\u4e2a\u6587\u4ef6\uff0c\u5e76\u628a\u5185\u5bb9\u8f93\u51fa\u5230\u8fd9\u4e2a\u6587\u4ef6\u91cc\u53bb\u3002 \u8fd9\u91cc\u5f3a\u8c03\u7684\u662f\u201c\u903b\u8f91\u4e0a\u201d\uff0c\u56e0\u4e3a /dev/stdin \u548c /dev/stdout \u8fd92\u4e2a\u6587\u4ef6\u672c\u8eab\u4e0d\u662f\u8bbe\u5907\u6587\u4ef6\u3002Linux\u4e2d\u8bbe\u5907\u662f\u6587\u4ef6\uff0c\u4f46\u662f\u6587\u4ef6\u4e0d\u4e00\u5b9a\u662f\u8bbe\u5907\u3002 \u56e0\u6b64\uff0c\u64cd\u4f5c /dev/stdin \u548c/dev/stdout`\u8fd92\u4e2a\u6587\u4ef6\uff0c\u5b9e\u9645\u4e0a\u662f\u64cd\u4f5c\u4e24\u4e2a\u6587\u4ef6\u5b58\u653e\u5730\u5740\u5bf9\u5e94\u7684\u8bbe\u5907\u6587\u4ef6\u3002 \u901a\u8fc7\u4e0b\u9762\u547d\u4ee4\u53ef\u4ee5\u770b\u5230\u6807\u51c6\u8f93\u5165\u8f93\u51fa\u6587\u4ef6\u7684\u7279\u70b9\uff0c\u4ed6\u4eec\u867d\u7136\u5728 /dev \u76ee\u5f55\u4e0b\uff0c\u90fd\u662f\u4ee5 l \u5f00\u5934\u7684\u94fe\u63a5\u6587\u4ef6\uff0c\u6307\u5411\u7684\u662f\u53e6\u4e00\u4e2a\u6587\u4ef6\u7684\u5730\u5740\u3002 $ ls -l /dev/std* lrwxrwxrwx 1 root root 15 Nov 13 10 :39 /dev/stderr -> /proc/self/fd/2 lrwxrwxrwx 1 root root 15 Nov 13 10 :39 /dev/stdin -> /proc/self/fd/0 lrwxrwxrwx 1 root root 15 Nov 13 10 :39 /dev/stdout -> /proc/self/fd/1 # Rocky $ ll /proc/self/fd/ lrwx------. 1 vagrant wheel 64 Nov 13 22 :38 0 -> /dev/pts/0 lrwx------. 1 vagrant wheel 64 Nov 13 22 :38 1 -> /dev/pts/0 lrwx------. 1 vagrant wheel 64 Nov 13 22 :38 2 -> /dev/pts/0 lr-x------. 1 vagrant wheel 64 Nov 13 22 :38 3 -> /proc/1702/fd # Ubuntu $ ll /proc/self/fd/ lrwx------ 1 vagrant sudo 64 Nov 13 14 :38 0 -> /dev/pts/0 lrwx------ 1 vagrant sudo 64 Nov 13 14 :38 1 -> /dev/pts/0 lrwx------ 1 vagrant sudo 64 Nov 13 14 :38 2 -> /dev/pts/0 lr-x------ 1 vagrant sudo 64 Nov 13 14 :38 3 -> /proc/2062/fd/ # openSUSE $ ll /proc/self/fd/* ls: cannot access '/proc/self/fd/255' : No such file or directory ls: cannot access '/proc/self/fd/3' : No such file or directory lrwx------ 1 vagrant wheel 64 Nov 13 22 :37 /proc/self/fd/0 -> /dev/pts/0 lrwx------ 1 vagrant wheel 64 Nov 13 22 :37 /proc/self/fd/1 -> /dev/pts/0 lrwx------ 1 vagrant wheel 64 Nov 13 22 :37 /proc/self/fd/2 -> /dev/pts/0 Linux\u8fdb\u7a0b\u9ed8\u8ba4\u4f1a\u6253\u5f00\u7684\u4e09\u4e2a\u6587\u4ef6\uff1a \u6807\u51c6\u8f93\u5165 /dev/stdin \uff0c\u63cf\u8ff0\u7b26\u4e3a 0\uff0c\u9ed8\u8ba4\u662f\u952e\u76d8\u8f93\u5165\u3002 \u6807\u51c6\u8f93\u51fa /dev/stdout \uff0c\u63cf\u8ff0\u7b26\u4e3a 1\uff0c\u9ed8\u8ba4\u662f\u8f93\u51fa\u5230\u5c4f\u5e55\u3002 \u6807\u51c6\u8f93\u51fa /dev/stderr \uff0c\u63cf\u8ff0\u7b26\u4e3a 2\uff0c\u9ed8\u8ba4\u662f\u8f93\u51fa\u5230\u5c4f\u5e55\u3002 \u4ee5Rocky\u4e3a\u4f8b\uff0c\u521b\u5efa file.py \u6587\u4ef6\u3002 $ cat > file.py < test.txt \u8fd0\u884c file.py \u7a0b\u5e8f\u3002 python3 file.py \u6253\u5f00\u65b0\u7684\u7ec8\u7aef\u7a97\u53e3\uff0c\u6267\u884c\u4e0b\u9762\u547d\u4ee4\uff0c\u5f97\u5230python3\u8fd9\u4e2a\u7a0b\u5e8f\u8fd0\u884c\u7684process ID\u3002\u5176\u4e2d\u53ef\u4ee5\u770b\u5230\u6709\u4e00\u4e2a\u6765\u81ea\u6587\u4ef6test.txt\u88ab\u7a0b\u5e8ffile.py\u6253\u5f00\uff08\u8f93\u5165\uff09\u3002 $ pidof python3 1739 788 $ sudo ls -l /proc/788/fd/ lr-x------. 1 root root 64 Nov 13 23 :00 0 -> /dev/null l-wx------. 1 root root 64 Nov 13 23 :00 1 -> /dev/null lrwx------. 1 root root 64 Nov 13 23 :00 10 -> 'socket:[24677]' lrwx------. 1 root root 64 Nov 13 23 :00 11 -> 'socket:[24678]' l-wx------. 1 root root 64 Nov 13 23 :00 2 -> /dev/null l-wx------. 1 root root 64 Nov 13 10 :41 3 -> /var/log/firewalld lrwx------. 1 root root 64 Nov 13 23 :00 4 -> 'socket:[23421]' lrwx------. 1 root root 64 Nov 13 23 :00 5 -> 'anon_inode:[eventfd]' lrwx------. 1 root root 64 Nov 13 23 :00 6 -> 'socket:[24586]' lr-x------. 1 root root 64 Nov 13 23 :00 7 -> anon_inode:inotify lrwx------. 1 root root 64 Nov 13 23 :00 8 -> 'anon_inode:[eventfd]' lrwx------. 1 root root 64 Nov 13 23 :00 9 -> '/memfd:libffi (deleted)' $ sudo ls -l /proc/1739/fd/ lrwx------. 1 vagrant wheel 64 Nov 13 23 :00 0 -> /dev/pts/0 lrwx------. 1 vagrant wheel 64 Nov 13 23 :00 1 -> /dev/pts/0 lrwx------. 1 vagrant wheel 64 Nov 13 23 :00 2 -> /dev/pts/0 lr-x------. 1 vagrant wheel 64 Nov 13 23 :00 3 -> /home/vagrant/test.txt \u5728Ubuntu\u4e2d\u8fd0\u884c file.py \u7a0b\u5e8f\uff0cpidof\u4f1a\u53d6\u5f973\u4e2aprocess IDs\u3002 $ pidof python3 2128 924 873 $ sudo ls -l /proc/2128/fd/ lrwx------ 1 vagrant sudo 64 Nov 13 15 :10 0 -> /dev/pts/0 lrwx------ 1 vagrant sudo 64 Nov 13 15 :10 1 -> /dev/pts/0 lrwx------ 1 vagrant sudo 64 Nov 13 15 :10 2 -> /dev/pts/0 lr-x------ 1 vagrant sudo 64 Nov 13 15 :10 3 -> /home/vagrant/test.txt $ sudo ls -l /proc/924/fd/ lr-x------ 1 root root 64 Nov 13 15 :11 0 -> /dev/null lrwx------ 1 root root 64 Nov 13 15 :11 1 -> 'socket:[31593]' lrwx------ 1 root root 64 Nov 13 15 :11 2 -> 'socket:[31593]' l-wx------ 1 root root 64 Nov 13 02 :40 3 -> /var/log/unattended-upgrades/unattended-upgrades-shutdown.log lrwx------ 1 root root 64 Nov 13 15 :11 4 -> 'socket:[31652]' lrwx------ 1 root root 64 Nov 13 15 :11 5 -> 'anon_inode:[eventfd]' lrwx------ 1 root root 64 Nov 13 15 :11 6 -> 'anon_inode:[eventfd]' lrwx------ 1 root root 64 Nov 13 15 :11 7 -> 'socket:[31657]' l-wx------ 1 root root 64 Nov 13 15 :11 8 -> /run/systemd/inhibit/1.ref lrwx------ 1 root root 64 Nov 13 15 :11 9 -> 'socket:[31658]' $ sudo ls -l /proc/873/fd/ lr-x------ 1 root root 64 Nov 13 15 :11 0 -> /dev/null lrwx------ 1 root root 64 Nov 13 15 :11 1 -> 'socket:[31412]' lrwx------ 1 root root 64 Nov 13 15 :11 2 -> 'socket:[31412]' lrwx------ 1 root root 64 Nov 13 02 :40 3 -> 'socket:[31650]' lrwx------ 1 root root 64 Nov 13 15 :11 4 -> 'anon_inode:[eventfd]' lrwx------ 1 root root 64 Nov 13 15 :11 5 -> 'socket:[31663]' lrwx------ 1 root root 64 Nov 13 15 :11 6 -> 'socket:[31664]' openSUSE\u9700\u8981\u5b89\u88c5\u5305 sysvinit-tools \u624d\u80fd\u4f7f\u7528 pidof \u547d\u4ee4\u3002 sudo zypper in sysvinit-tools \u7531\u4e8eopenSUSE\u4e2dpidof python3\u53ea\u8fd4\u56de\u4e00\u4e2aprocess ID\uff0c\u6240\u4ee5\u53ef\u4ee5\u7b80\u5316\u547d\u4ee4\u884c\u5f97\u5230process ID\u7684\u8be6\u7ec6\u4fe1\u606f\u3002 $ sudo ls -l /proc/ ` pidof python3 ` /fd/ lrwx------ 1 vagrant wheel 64 Nov 13 23 :21 0 -> /dev/pts/0 lrwx------ 1 vagrant wheel 64 Nov 13 23 :21 1 -> /dev/pts/0 lrwx------ 1 vagrant wheel 64 Nov 13 23 :21 2 -> /dev/pts/0 lr-x------ 1 vagrant wheel 64 Nov 13 23 :21 3 -> /home/vagrant/test.txt \u53c2\u8003\uff1a \u5f53\u952e\u76d8\u548c\u9f20\u6807\u7b49\u8bbe\u5907\u901a\u8fc7\u4e32\u53e3\u76f4\u63a5\u8fde\u63a5\u5230\u8ba1\u7b97\u673a\u65f6\uff0c\u8fd9\u79cd\u8fde\u63a5\u79f0\u4e3aTTY\u3002 \u4f2a\u7ec8\u7aefpseudoterminal\uff08\u7f29\u5199\u4e3a\u201cpty\u201d\uff09\u662f\u4e00\u5bf9\u63d0\u4f9b\u53cc\u5411\u901a\u4fe1\u901a\u9053\u7684\u865a\u62df\u5b57\u7b26\u8bbe\u5907\u3002 \u901a\u9053\u7684\u4e00\u7aef\u79f0\u4e3a\u4e3b\u7aefmaster\uff1b \u53e6\u4e00\u7aef\u79f0\u4e3a\u4ece\u7aefslave\u3002 /dev/pts \u8868\u793a\u4e0e\u4f2a\u7ec8\u7aefpseudoterminal\u7684\u4e3b\u7aefmaster\u6216\u4ece\u7aefslave\u76f8\u5173\u7684master\u6587\u4ef6\uff0c\u64cd\u4f5c\u7cfb\u7edf\u5c06\u5176\u4fdd\u5b58\u4e3a /dev/ptmx \u6587\u4ef6\u3002 telnet \u548c ssh \u7b49\u7a0b\u5e8f\u80fd\u591f\u4eff \u7aef\u7528\u6237> \u4e0e\u5b83\u4eec\u7684\u4ea4\u4e92\uff0c\u867d\u7136\u672c\u8d28\u4e0a\u662f\u4e0e\u6587\u4ef6 /dev/ptmx \u8fdb\u884c\u4ea4\u4e92\uff0c\u4f46\u5448\u73b0\u7ed9\u7528\u6237\u7684\u5374\u662f\u597d\u50cf\u8fd0\u884c\u5728\u771f\u6b63\u7684\u7ec8\u7aef\u7a97\u53e3\u4e00\u6837\uff0c\u4ece\u7aef\u7684\u6587\u4ef6\u662f\u4e3b\u7aef\u7684\u8f93\u5165\u3002 \u4f2a\u7ec8\u7aef\u8fdb\u7a0b\u5728Linux\u4e2d\u88ab\u5b58\u50a8\u5728 /dev/pts/ \u76ee\u5f55\u4e0b\u3002 /dev/pts/ \u76ee\u5f55\u4e0b\u7684\u5185\u5bb9\u662f\u4e00\u4e9b\u7279\u6b8a\u7684\u76ee\u5f55\uff0c\u7531Linux\u5185\u6838\u6240\u521b\u5efa\u3002 \u6bcf\u4e2a\u552f\u4e00\u7684\u7ec8\u7aef\u7a97\u53e3\u90fd\u4e0e /dev/pts \u7cfb\u7edf\u4e2d\u7684\u4e00\u4e2aLinux pts \u6761\u76ee\u76f8\u5173\u3002 \u4e0b\u9762\u8fd4\u56de\u7684\u7ed3\u679c\u8bf4\u660e\u67092\u4e2a\u8fdc\u7a0b\u7ec8\u7aef\u8fde\u63a5\u5230\u5f53\u524d\u7684\u673a\u5668\u3002 $ ll /dev/pts/ crw--w----. 1 vagrant tty 136 , 0 Nov 13 23 :18 0 crw--w----. 1 vagrant tty 136 , 1 Nov 13 23 :48 1 c---------. 1 root root 5 , 2 Nov 13 10 :41 ptmx \u4e5f\u53ef\u4ee5\u901a\u8fc7 w \u547d\u4ee4\u770b\u52302\u4e2a\u7ec8\u7aef\u8fdb\u7a0b\u3002 $ w 23 :55:05 up 13 :14, 2 users, load average: 0 .00, 0 .00, 0 .00 USER TTY LOGIN@ IDLE JCPU PCPU WHAT vagrant pts/0 10 :51 37 :03 0 .05s 0 .05s -bash vagrant pts/1 23 :48 0 .00s 0 .03s 0 .00s w \u5355\u4e2a\u4f2a\u7ec8\u7aefpseudoterminal\u53ef\u4ee5\u540c\u65f6\u63a5\u6536\u6765\u81ea\u4e0d\u540c\u7684\u7a0b\u5e8f\u7684\u8f93\u51fa\u3002 \u591a\u4e2a\u7a0b\u5e8f\u540c\u65f6\u5bf9\u4e00\u4e2a\u4f2a\u7ec8\u7aefpseudoterminal\u8fdb\u884c\u8bfb\u53d6\u4f1a\u5f15\u8d77\u6df7\u6dc6\u3002 \u5b58\u50a8\u5728 /dev/pts \u76ee\u5f55\u4e2d\u7684\u6587\u4ef6\u662f\u62bd\u8c61\u6587\u4ef6\u800c\u4e0d\u662f\u771f\u5b9e\u6587\u4ef6\uff0c\u662f\u4f2a\u7ec8\u7aef\u4e2d\u6267\u884c\u7a0b\u5e8f\u65f6\u4e34\u65f6\u5b58\u50a8\u7684\u6570\u636e\u3002 \u6253\u5f00 /dev/pts \u4e0b\u7684\u6587\u4ef6\u901a\u5e38\u6ca1\u6709\u4ec0\u4e48\u5b9e\u9645\u610f\u4e49\u3002","title":"5.\u6807\u51c6\u8f93\u5165\u8f93\u51fa"},{"location":"linux/SRE/02-filesystem/#6","text":"","title":"6.\u91cd\u5b9a\u5411\u548c\u7ba1\u9053"},{"location":"linux/SRE/02-filesystem/#61","text":"\u5e38\u7528\u547d\u4ee4\u683c\u5f0f\uff1a command < file \uff1a\u5c06\u6307\u5b9a\u6587\u4ef6 file \u4f5c\u4e3a\u547d\u4ee4\u7684\u8f93\u5165\u8bbe\u5907\u3002 command << delimiter \uff1a\u8868\u793a\u4ece\u6807\u51c6\u8f93\u5165\u8bbe\u5907\uff08\u952e\u76d8\uff09\u4e2d\u8bfb\u5165\uff0c\u76f4\u5230\u9047\u5230\u5206\u754c\u7b26 delimiter \u505c\u6b62\uff08\u8bfb\u5165\u7684\u6570\u636e\u4e0d\u5305\u62ec\u5206\u754c\u7b26\uff09\uff0c\u8fd9\u91cc\u7684\u5206\u754c\u7b26\u53ef\u4ee5\u7406\u89e3\u4e3a\u81ea\u5b9a\u4e49\u7684\u5b57\u7b26\u4e32\u3002 command < file1 > file2 \uff1a\u5c06 file1 \u4f5c\u4e3a\u547d\u4ee4\u7684\u8f93\u5165\u8bbe\u5907\uff0c\u8be5\u547d\u4ee4\u7684\u6267\u884c\u7ed3\u679c\u8f93\u51fa\u5230 file2 \u4e2d\u3002 # \u8f93\u51fa\u6587\u4ef6file.py\u5185\u5bb9\uff08\u8f93\u5165\u8bbe\u5907\u662f\u952e\u76d8\uff09 $ cat file.py # \u8f93\u51fa\u6587\u4ef6file.py\u5185\u5bb9\uff08\u8f93\u5165\u8bbe\u5907\u662f\u6587\u4ef6file.py\uff09 $ cat < file.py # \u6307\u5b9a\u5206\u754c\u7b26\uff08\u8fd9\u91cc\u662fEOF\uff09\uff0c\u8bfb\u53d6\u952e\u76d8\u8f93\u5165\u5185\u5bb9\uff0c\u76f4\u5230\u9047\u5230\u6307\u5b9a\u5206\u754c\u7b26\u4e3a\u6b62\uff0c\u5c06\u6240\u8bfb\u53d6\u7684\u5185\u5bb9\u8f93\u51fa\u5230\u6587\u4ef6file.py\u3002 $ cat > file.py < new.py","title":"6.1.\u8f93\u5165\u91cd\u5b9a\u5411"},{"location":"linux/SRE/02-filesystem/#62","text":"\u8f93\u51fa\u91cd\u5b9a\u5411\u5206\u4e3a\u6807\u51c6\u8f93\u51fa\u91cd\u5b9a\u5411\u548c\u9519\u8bef\u8f93\u51fa\u91cd\u5b9a\u5411\u4e24\u79cd\u3002 \u5e38\u7528\u547d\u4ee4\u683c\u5f0f\uff1a command > file \uff1a\u5c06\u547d\u4ee4 command \u6267\u884c\u7684\u6807\u51c6\u8f93\u51fa\u7ed3\u679c\u91cd\u5b9a\u5411\u8f93\u51fa\u5230\u6307\u5b9a\u7684\u6587\u4ef6 file \u4e2d\uff0c\u5982\u679c\u8be5\u6587\u4ef6\u5df2\u5305\u542b\u6570\u636e\uff0c\u4f1a\u6e05\u7a7a\u539f\u6709\u6570\u636e\uff0c\u518d\u5199\u5165\u65b0\u6570\u636e\u3002 command 2> file \uff1a\u5c06\u547d\u4ee4 command \u6267\u884c\u7684\u9519\u8bef\u8f93\u51fa\u7ed3\u679c\u91cd\u5b9a\u5411\u5230\u6307\u5b9a\u7684\u6587\u4ef6 file \u4e2d\uff0c\u5982\u679c\u8be5\u6587\u4ef6\u4e2d\u5df2\u5305\u542b\u6570\u636e\uff0c\u4f1a\u6e05\u7a7a\u539f\u6709\u6570\u636e\uff0c\u518d\u5199\u5165\u65b0\u6570\u636e\u3002 command >> file \uff1a\u5c06\u547d\u4ee4 command \u6267\u884c\u7684\u6807\u51c6\u8f93\u51fa\u7ed3\u679c\u91cd\u5b9a\u5411\u8f93\u51fa\u5230\u6307\u5b9a\u7684\u6587\u4ef6 file \u4e2d\uff0c\u5982\u679c\u8be5\u6587\u4ef6\u5df2\u5305\u542b\u6570\u636e\uff0c\u65b0\u6570\u636e\u5c06\u8ffd\u52a0\u5199\u5165\u5230\u539f\u6709\u5185\u5bb9\u7684\u540e\u9762\u3002 command 2>> file \uff1a\u5c06\u547d\u4ee4 command \u6267\u884c\u7684\u9519\u8bef\u8f93\u51fa\u7ed3\u679c\u91cd\u5b9a\u5411\u5230\u6307\u5b9a\u7684\u6587\u4ef6 file \u4e2d\uff0c\u5982\u679c\u8be5\u6587\u4ef6\u4e2d\u5df2\u5305\u542b\u6570\u636e\uff0c\u65b0\u6570\u636e\u5c06\u8ffd\u52a0\u5199\u5165\u5230\u539f\u6709\u5185\u5bb9\u7684\u540e\u9762\u3002 command >> file 2>&1 \u6216\u8005 command &>> file \uff1a\u5c06\u6807\u51c6\u8f93\u51fa\u6216\u8005\u9519\u8bef\u8f93\u51fa\u5199\u5165\u5230\u6307\u5b9a\u6587\u4ef6 file \u4e2d\uff0c\u5982\u679c\u8be5\u6587\u4ef6\u4e2d\u5df2\u5305\u542b\u6570\u636e\uff0c\u65b0\u6570\u636e\u5c06\u8ffd\u52a0\u5199\u5165\u5230\u539f\u6709\u5185\u5bb9\u7684\u540e\u9762\u3002 \u6ce8\u610f\uff1a\u4e0a\u9762\u7684 file \u53ef\u4ee5\u662f\u4e00\u4e2a\u666e\u901a\u6587\u4ef6\uff0c\u4e5f\u53ef\u4ee5\u4f7f\u7528\u4e00\u4e2a\u7279\u6b8a\u7684\u6587\u4ef6 /dev/null \u3002 /dev/null \u5e76\u4e0d\u4fdd\u5b58\u6570\u636e\uff0c\u88ab\u5199\u5165 /dev/null \u7684\u6570\u636e\u6700\u7ec8\u90fd\u4f1a\u4e22\u5931\u3002 \u4e3e\u4f8b\uff1a2\u4e2apython\u6587\u4ef6\u5b58\u5728\uff0c\u5176\u4ed62\u4e2a\u65e0\u6269\u5c55\u540d\u7684\u6587\u4ef6\u4e0d\u5b58\u5728\u3002 ls file.py > out ls file 2 > out.err ls new.py >> out ls new 2 >> out.err \u53ef\u4ee5\u5f97\u5230\u9884\u671f\u7684\u7ed3\u679c\u3002\u4e24\u4e2a\u9519\u8bef\u8bb0\u5f55\u90fd\u88ab\u8ffd\u52a0\u5230 out.err \u6587\u4ef6\u4e2d\u3002\u4e24\u4e2a\u6210\u529f\u6267\u884c\u7684\u547d\u4ee4\u7684\u8fd4\u56de\u7ed3\u679c\u4e5f\u8f93\u51fa\u5230 out \u6587\u4ef6\u4e2d\u3002 $ccat out file.py new.py $ cat out.err ls: cannot access 'file' : No such file or directory ls: cannot access 'new' : No such file or directory \u4e0a\u4f8b\u547d\u4ee4\u4e5f\u53ef\u4ee5\u5408\u5e76\u3002 ls file.py > out 2 > out.err ls file >> out 2 >> out.err 2>&1 \u683c\u5f0f\u4e3e\u4f8b\uff1a $ ls file >> out.txt 2 > & 1 $ cat out.txt ls: cannot access 'file' : No such file or directory $ ls file.py & >> out.txt $ cat out.txt ls: cannot access 'file' : No such file or directory file.py","title":"6.2.\u8f93\u51fa\u91cd\u5b9a\u5411"},{"location":"linux/SRE/02-filesystem/#63","text":"\u683c\u5f0f\uff1a command1 < <(command2) tr 'a-z' 'A-Z' < < ( echo \"Hello World\" ) \u5e94\u7528\uff1a\u4fee\u6539\u5bc6\u7801 \u5bc6\u7801\u4fdd\u5b58\u5728 passwd.txt \u6587\u4ef6\u4e2d\uff0c\u5e76\u4e25\u683c\u9650\u5236\u6539\u6587\u4ef6\u7684\u6743\u9650\u3002 \u901a\u8fc7\u53c2\u6570 --stdin \u5b9e\u73b0\u6a21\u62df\u952e\u76d8\u8f93\u5165\u64cd\u4f5c\u8f93\u5165\u7528\u6237\u540d\u3002 \u5728Rocky\u4e2d\u53ef\u4ee5\u4f7f\u7528 --stdin \u53c2\u6570\u3002 passwd --stdin vagrant < passwd.txt \u5728openSUSE\u548cUbuntu\u4e2d\uff0c --stdin \u53c2\u6570\u65e0\u6cd5\u8bc6\u522b\u3002\u53ef\u4ee5\u6539\u7528\u4e0b\u9762\u7684\u65b9\u6cd5\u3002 echo passwd.txt | chpasswd \u5176\u4e2dpasswd.txt\u7684\u683c\u5f0f\u4e3a username:password \u3002 \u53c2\u8003\uff1a Here-document(Here-doc)\uff1a\u8f93\u5165\u7684\u6587\u672c\u5757\u91cd\u5b9a\u5411\u81f3\u6807\u51c6\u8f93\u5165\u6d41\uff0c\u76f4\u81f3\u9047\u5230\u7279\u6b8a\u7684\u6587\u4ef6\u7ed3\u675f\u6807\u8bb0\u7b26\u4e3a\u6b62\uff08\u6587\u4ef6\u7ed3\u675f\u6807\u8bb0\u7b26\u53ef\u4ee5\u662f\u4efb\u610f\u7684\u552f\u4e00\u7684\u5b57\u7b26\u4e32\uff0c\u4f46\u5927\u90e8\u5206\u4eba\u90fd\u9ed8\u8ba4\u4f7f\u7528 EOF \uff09\u3002 cat < \u5c06\u547d\u4ee4\u4e0e\u6587\u4ef6\u8fde\u63a5\u8d77\u6765\uff0c\u7528\u6587\u4ef6\u6765\u63a5\u6536\u547d\u4ee4\u7684\u8f93\u51fa\uff1b\u800c\u7ba1\u9053\u7b26 | \u5c06\u547d\u4ee4\u4e0e\u547d\u4ee4\u8fde\u63a5\u8d77\u6765\uff0c\u7528\u53f3\u8fb9\u547d\u4ee4\u6765\u63a5\u6536\u5de6\u8fb9\u547d\u4ee4\u7684\u8f93\u51fa\u3002 $ ls | tr 'a-z' 'A-Z' BIN F1.TXT F2.TXT FILE.PY NEW.PY OUT OUT.ERR TEST.TXT","title":"7.\u7ba1\u9053"},{"location":"linux/SRE/03-identity-security/","text":"\u7b2c\u4e09\u7ae0 \u8eab\u4efd\u4e0e\u5b89\u5168 \u00b6 1.\u7528\u6237\u3001\u7ec4\u3001\u6743\u9650 \u00b6 \u7528\u6237\u548c\u7ec4 \u7528\u6237user\u548c\u7ec4group\u5728Linux\u7cfb\u7edf\u4e2d\u4ee5\u6570\u5b57\u5f62\u5f0f\u8fdb\u884c\u7ba1\u7406\u3002 \u7528\u6237\u88ab\u5206\u914d\u7684\u53f7\u7801\u79f0\u4e3a\u7528\u6237ID\uff08UID\uff09\u3002 \u6bcf\u4e2aLinux\u7cfb\u7edf\u90fd\u6709\u4e00\u4e2a\u7279\u6743\u7528\u6237\uff0c\u5373 root \u7528\u6237\u3002 root \u662f\u7cfb\u7edf\u7ba1\u7406\u5458\u3002 \u6b64\u7528\u6237\u7684UID\u59cb\u7ec8\u4e3a0\u3002 \u666e\u901a\u7528\u6237\u7684UID\u7f16\u53f7\uff08\u9ed8\u8ba4\u60c5\u51b5\u4e0b\uff09\u4e3a1000\u3002 \u6bcf\u4e2a\u7ec4\u4e5f\u5206\u914d\u4e86\u4e00\u4e2a\u79f0\u4e3a\u7ec4ID\uff08GID\uff09\u7684\u7f16\u53f7\u3002 \u6bcf\u4e2a\u7528\u6237\u6709\u4e00\u4e2a\u4e3b\u8981\u7ec4\uff08primary group\uff09\uff0c\u6709\u96f6\u4e2a\u6216\u8005\u4efb\u610f\u4e2a\u9644\u52a0\u7ec4\uff08supplementary group\uff09\u3002 \u4ee5openSUSE\u4e3a\u4f8b\uff1a UID 0: root 1 \u2013 99: System 100 \u2013 499: System accounts \u2265 1000: Normal (unprivileged) accounts GID 0: root 1 \u2013 99: System Groups 100 \u2013 499: Dynamically Allocated System Groups \u2265 1000: Normal Groups \u4e3e\u4f8b\uff1a $ id postfix uid = 51 ( postfix ) gid = 51 ( postfix ) groups = 482 ( mail ) ,59 ( maildrop ) ,51 ( postfix ) $ id vagrant uid = 1000 ( vagrant ) gid = 478 ( wheel ) groups = 0 ( root ) ,478 ( wheel ) \u63d0\u793a\uff1a UID\u548cGID\u7b49\u7f16\u53f7\u89c4\u5219\uff0c\u662f\u5728\u6587\u4ef6 /etc/login.defs \u4e2d\u7ea6\u5b9a\u7684\u3002 2.SELinux \u00b6 Security-Enhanced Linux (SELinux) \u662f\u4e00\u79cdLinux\u7cfb\u7edf\u7684\u5b89\u5168\u67b6\u6784\uff0c\u5b83\u5141\u8bb8\u7ba1\u7406\u5458\u66f4\u597d\u5730\u63a7\u5236\u8c01\u53ef\u4ee5\u8bbf\u95ee\u7cfb\u7edf\u3002 SELinux\u4e8e2000\u5e74\u5411\u5f00\u6e90\u793e\u533a\u53d1\u5e03\uff0c\u5e76\u4e8e2003\u5e74\u96c6\u6210\u5230\u4e0a\u6e38 Linux \u5185\u6838\u4e2d\u3002 SELinux\u4e3a\u7cfb\u7edf\u4e0a\u7684\u5e94\u7528\u7a0b\u5e8f\u3001\u8fdb\u7a0b\u548c\u6587\u4ef6\u5b9a\u4e49\u4e86\u8bbf\u95ee\u63a7\u5236\u3002 \u5b83\u4f7f\u7528\u5b89\u5168\u7b56\u7565\uff08\u4e00\u7ec4\u89c4\u5219\u544a\u8bc9SELinux\u4ec0\u4e48\u53ef\u4ee5\u8bbf\u95ee\u6216\u4e0d\u53ef\u4ee5\u8bbf\u95ee\uff09\u6765\u5f3a\u5236\u6267\u884c\u7b56\u7565\u5141\u8bb8\u7684\u8bbf\u95ee\u3002 \u5f53\u79f0\u4e3a\u4e3b\u4f53\uff08subject\uff09\u7684\u5e94\u7528\u7a0b\u5e8f\u6216\u8fdb\u7a0b\u8bf7\u6c42\u8bbf\u95ee\u5bf9\u8c61\uff08\u5982\u6587\u4ef6\uff09\u65f6\uff0cSELinux\u4f1a\u68c0\u67e5\u8bbf\u95ee\u5411\u91cf\u7f13\u5b58(AVC, Access Vector Cache)\uff0c\u5176\u4e2d\u7f13\u5b58\u4e86\u4e3b\u4f53\u548c\u5bf9\u8c61\u7684\u6743\u9650\u3002 \u5982\u679cSELinux\u65e0\u6cd5\u6839\u636e\u7f13\u5b58\u7684\u6743\u9650\u505a\u51fa\u8bbf\u95ee\u51b3\u5b9a\uff0c\u5b83\u4f1a\u5c06\u8bf7\u6c42\u53d1\u9001\u5230\u5b89\u5168\u670d\u52a1\u5668\u3002 \u5b89\u5168\u670d\u52a1\u5668\u68c0\u67e5\u5e94\u7528\u7a0b\u5e8f\u6216\u8fdb\u7a0b\u548c\u6587\u4ef6\u7684\u5b89\u5168\u4e0a\u4e0b\u6587\u3002 \u4eceSELinux\u7b56\u7565\u6570\u636e\u5e93\u5e94\u7528\u5b89\u5168\u4e0a\u4e0b\u6587\uff08Security context\uff09\uff0c\u7136\u540e\u6388\u4e88\u6216\u62d2\u7edd\u8bb8\u53ef\u3002 \u5982\u679c\u6743\u9650\u88ab\u62d2\u7edd\uff0c avc: denied \u6d88\u606f\u5c06\u5728 /var/log.messages \u4e2d\u4f53\u73b0\u3002 \u4f20\u7edf\u4e0a\uff0cLinux\u548cUNIX\u7cfb\u7edf\u90fd\u4f7f\u7528DAC\uff08Discretionary Access Control\uff09\u3002 SELinux\u662fLinux\u7684MAC\uff08Mandatory Access Control\uff09\u7cfb\u7edf\u7684\u4e00\u4e2a\u793a\u4f8b\u3002 \u5728DAC\u65b9\u5f0f\u4e0b\uff0c\u6587\u4ef6\u548c\u8fdb\u7a0b\u6709\u81ea\u5df1\u7684\u5c5e\u4e3b\uff08\u6240\u6709\u8005\uff09\u3002 \u7528\u6237\u53ef\u4ee5\u62e5\u6709\u4e00\u4e2a\u6587\u4ef6\uff0c\u4e00\u4e2a\u7ec4\u4e5f\u53ef\u4ee5\u62e5\u6709\u4e00\u4e2a\u6587\u4ef6\uff0c\u6216\u8005\u5176\u4ed6\u4eba\u3002 \u7528\u6237\u53ef\u4ee5\u66f4\u6539\u81ea\u5df1\u6587\u4ef6\u7684\u6743\u9650\u3002 root \u7528\u6237\u5bf9DAC\u7cfb\u7edf\u5177\u6709\u5b8c\u5168\u8bbf\u95ee\u63a7\u5236\u6743\u3002 \u4f46\u662f\u5728\u50cfSELinux\u8fd9\u6837\u7684MAC\u7cfb\u7edf\u4e0a\uff0c\u5bf9\u4e8e\u8bbf\u95ee\u7684\u7ba1\u7406\u662f\u901a\u8fc7\u8bbe\u7f6e\u7b56\u7565\u6765\u5b9e\u73b0\u7684\u3002\u5373\u4f7f\u7528\u6237\u4e3b\u76ee\u5f55\u4e0a\u7684DAC\u8bbe\u7f6e\u53d1\u751f\u66f4\u6539\uff0c\u7528\u4e8e\u9632\u6b62\u5176\u4ed6\u7528\u6237\u6216\u8fdb\u7a0b\u8bbf\u95ee\u8be5\u76ee\u5f55\u7684SELinux\u7b56\u7565\u4e5f\u5c06\u7ee7\u7eed\u786e\u4fdd\u7cfb\u7edf\u5b89\u5168\u3002 MAC\u65b9\u5f0f\u662f\u63a7\u5236\u4e00\u4e2a\u8fdb\u7a0b\u5bf9\u5177\u4f53\u6587\u4ef6\u7cfb\u7edf\u4e0a\u9762\u7684\u6587\u4ef6\u6216\u76ee\u5f55\u662f\u5426\u62e5\u6709\u8bbf\u95ee\u6743\u9650\u3002\u5224\u65ad\u8fdb\u7a0b\u662f\u5426\u53ef\u4ee5\u8bbf\u95ee\u6587\u4ef6\u6216\u76ee\u5f55\u7684\u4f9d\u636e\uff0c\u53d6\u51b3\u4e8eSELinux\u4e2d\u8bbe\u5b9a\u7684\u5f88\u591a\u7b56\u7565\u89c4\u5219\u3002 \u8bbf\u95ee\u63a7\u5236\u5217\u8868 (ACL\uff0cAccess Control List) \u4e3a\u6587\u4ef6\u7cfb\u7edf\u63d0\u4f9b\u4e86\u4e00\u79cd\u989d\u5916\u7684\u3001\u66f4\u7075\u6d3b\u7684\u6743\u9650\u673a\u5236\u3002 \u5b83\u65e8\u5728\u534f\u52a9 UNIX \u6587\u4ef6\u6743\u9650\u3002ACL\u5141\u8bb8\u6388\u4e88\u4efb\u4f55\u7528\u6237\u6216\u7ec4\u5bf9\u4efb\u4f55\u78c1\u76d8\u8d44\u6e90\u7684\u6743\u9650\u3002ACL\u9002\u7528\u4e8e\u5728\u4e0d\u4f7f\u67d0\u4e2a\u7528\u6237\u6210\u4e3a\u7ec4\u6210\u5458\u7684\u60c5\u51b5\u4e0b\uff0c\u4ecd\u65e7\u6388\u4e88\u4e00\u4e9b\u8bfb\u6216\u5199\u8bbf\u95ee\u6743\u9650\u3002 \u4e0b\u9762\u793a\u4f8b\u5bf9\u6bd4\u8bf4\u660e\u4e86SELinux\u548cACL\u5728\u6587\u4ef6\u5c5e\u6027\u5c55\u73b0\u4e0a\u7684\u7279\u70b9\u3002 -rwxr-xr-- vagrant wheel \uff1a\u6ca1\u6709selinux\u4e0a\u4e0b\u6587\uff0c\u6ca1\u6709ACL -rwx--xr-x+ vagrant wheel \uff1a\u53ea\u6709ACL\uff0c\u6ca1\u6709selinux\u4e0a\u4e0b\u6587 -rw-r--r--. vagrant wheel \uff1a\u53ea\u6709selinux\u4e0a\u4e0b\u6587\uff0c\u6ca1\u6709ACL -rwxrwxr--+ vagrant wheel \uff1a\u6709selinux\u4e0a\u4e0b\u6587\uff0c\u6709ACL 2.1.SELinux\u4e3b\u8981\u6982\u5ff5 \u00b6 \u7528\u6237(Users)\uff1a SELinux\u7684\u7528\u6237\u4e0d\u7b49\u540c\u4e0eLinux\u7528\u6237\u3002 SELinux\u7528\u6237\u4ee5\u540e\u7f00 _u \u7ed3\u5c3e\u3002 \u89d2\u8272(Roles)\uff1a \u89d2\u8272Roles\u662f\u7531\u7b56\u7565Policies\u5b9a\u4e49\u7684\uff0c\u89d2\u8272\u51b3\u5b9a\u4e86\u4f7f\u7528\u54ea\u4e2a\u7b56\u7565\u3002 SELinux\u89d2\u8272\u4ee5\u540e\u7f00 _r \u7ed3\u5c3e\u3002 \u7c7b\u578b(Types)\uff1a SELinux\u662f\u7c7b\u578b\u5f3a\u5236\u7684\uff0c\u7c7b\u578bTypes\u51b3\u5b9a\u8fdb\u7a0b\u80fd\u5426\u8bbf\u95ee\u67d0\u4e2a\u6587\u4ef6\u3002 SELinux\u7c7b\u578b\u662f\u4ee5\u540e\u7f00 _t \u7ed3\u5c3e\u3002 \u4e0a\u4e0b\u6587(Contexts)\uff1a \u7528\u6765\u6807\u8bb0\u8fdb\u7a0b\u548c\u6587\u4ef6\u3002\u5206\u522b\u662f\u7528\u6237Users\uff0c\u89d2\u8272Roles\uff0c\u7c7b\u578bTypes\uff0c\u8303\u56f4Ranges\u3002 \u683c\u5f0f\uff1a user:role:type:range \u6587\u4ef6\u7c7b\u578b(Object Classes)\uff1a \u6bcf\u4e2a\u6587\u4ef6\u7c7b\u578bTypes\u90fd\u5bf9\u5e94\u4e00\u5957\u7b56\u7565Policies\u3002\u7b56\u7565Policies\u51b3\u5b9a\u4e86\u8fdb\u7a0b\u5bf9\u8fd9\u7c7b\u6587\u4ef6\u7684\u8bbf\u95ee\u6743\u9650\u3002 \u8bbf\u95ee\u6743\u9650\u67094\u79cd\uff1a \u521b\u5efacreate \u8bfb\u53d6read \u5199\u5165write \u5220\u9664unlink\uff08\u6ce8\u610f\uff0c\u8fd9\u91cc\u4e0d\u662f\u94fe\u63a5\u7684\u610f\u601d\uff09 \u89c4\u5219(Rules) \u683c\u5f0f\uff1a allow user_t user_home_t:file {create read write unlink}; \u542b\u4e49\uff1a user_t \u7c7b\u578b\u5bf9 user_home_t \u7c7b\u578b\u6709\u521b\u5efacreate\uff0c\u8bfb\u53d6read\uff0c\u5199\u5165write\uff0c\u5220\u9664unlink\u6743\u9650\u3002 2.2.SELinux in openSUSE \u00b6 \u4f5c\u4e3aSELinux\u7684\u66ff\u4ee3\u54c1\uff0c2005\u5e74\u88abNovell\u6536\u8d2d\u7684Immunix\u516c\u53f8\u5f00\u53d1\u4e86AppArmor\u3002SUSE\u5728openSUSE Leap\u4e2d\u63d0\u4f9b\u5bf9SELinux\u6846\u67b6\u7684\u652f\u6301\u3002\u8fd9\u5e76\u4e0d\u610f\u5473\u7740openSUSE Leap\u7684\u9ed8\u8ba4\u5b89\u88c5\u4f1a\u5728\u4e0d\u4e45\u7684\u5c06\u6765\u4eceAppArmor\u5207\u6362\u5230SELinux\u3002 \u6dfb\u52a0SELinux\u7684\u6e90\u3002\u53ef\u4ee5\u4ece https://download.opensuse.org/repositories/security:/SELinux/ \u4e0b\u8f7d\u5bf9\u5e94\u7684\u7b56\u7565policy\u3002 sudo zypper ar -f https://download.opensuse.org/repositories/security:/SELinux/openSUSE_Factory/ Security-SELinux \u5b89\u88c5C++\u7b49\u57fa\u7840\u5f00\u53d1\u5305\uff1a # \u5217\u51fa\u5f53\u524d\u53ef\u5b89\u88c5\u7684Pattern sudo zypper pt # \u5b89\u88c5\u4e0b\u9762\u51e0\u4e2a\u5f00\u53d1\u76f8\u5173\u7684Pattern sudo zypper in -t pattern devel_C_C++ devel_basis devel_kernel \u5b89\u88c5SELinux packages\uff1a zypper se --search-descriptions selinux sudo zypper in restorecond policycoreutils setools-console sudo zypper in selinux-tools libselinux-devel \u5b89\u88c5SELinux policy\uff1a sudo zypper in selinux-policy-targeted selinux-policy-devel selinux-autorelabel \u66f4\u65b0GRUB2 bootloader\uff08GRUB2\u5f15\u5bfc\u52a0\u8f7d\u7a0b\u5e8f\uff09\uff1a \u7f16\u8f91\u6587\u4ef6 /etc/default/grub \uff0c\u6dfb\u52a0\u4e0b\u9762\u5185\u5bb9\u5230 GRUB_CMDLINE_LINUX_DEFAULT= \u8fd9\u4e00\u884c\uff1a security = selinux selinux = 1 \u8bb0\u5f55\u8fd9\u4e00\u884c\u7684\u539f\u59cb\u4fe1\u606f\uff1a GRUB_CMDLINE_LINUX_DEFAULT = \"splash=silent resume=/dev/disk/by-uuid/47c36ad7-f49f-4ecd-9b72-4801c5bb3a04 preempt=full mitigations=auto quiet security=apparmor\" \u8fd0\u884c\u4e0b\u9762\u7684\u547d\u4ee4\u751f\u6210\u65b0\u7684GRUB2\u5f15\u5bfc\u52a0\u8f7d\u7a0b\u5e8f\u914d\u7f6e\u6587\u4ef6\u3002 sudo grub2-mkconfig -o /boot/grub2/grub.cfg \u7f16\u8f91\u6587\u4ef6 /etc/selinux/config \u5e76\u8bbe\u7f6e SELINUX=permissive \u6765\u542f\u7528SElinux\u3002\u8fd9\u4e0e\u524d\u9762GRUB2\u7684\u542f\u52a8\u914d\u7f6e\u662f\u4e00\u81f4\u7684\u3002 \u5982\u6587\u4ef6\u4e0d\u5b58\u5728\uff0c\u5219\u521b\u5efa\u3002 $ sudo cat /etc/selinux/config SELINUX = permissive SELINUXTYPE = targeted \u91cd\u542f\u7cfb\u7edf\u3002\u7cfb\u7edf\u542f\u52a8\u53ef\u80fd\u9700\u8981\u4e00\u4e9b\u65f6\u95f4\uff0cSELinux\u9700\u8981\u7ed9\u6574\u4e2a\u6587\u4ef6\u7cfb\u7edf\u91cd\u65b0\u8fdb\u884c\u6807\u7b7e\u5316\u3002 \u91cd\u542f\u540e\uff0c\u8fd0\u884c\u4e0b\u9762\u7684\u547d\u4ee4\u6765\u67e5\u770bSELinux\u662f\u5426\u8fd0\u884c\u6b63\u5e38\u3002 $ sudo getenforce Permissive $ sudo sestatus -v SELinux status: enabled SELinuxfs mount: /sys/fs/selinux SELinux root directory: /etc/selinux Loaded policy name: targeted Current mode: permissive Mode from config file: permissive Policy MLS status: enabled Policy deny_unknown status: allowed Memory protection checking: requested ( insecure ) Max kernel policy version: 33 Process contexts: Current context: unconfined_u:unconfined_r:unconfined_t:s0 Init context: system_u:system_r:kernel_t:s0 /sbin/agetty system_u:system_r:kernel_t:s0 /usr/sbin/sshd system_u:system_r:kernel_t:s0 File contexts: Controlling terminal: unconfined_u:object_r:devpts_t:s0 /etc/passwd system_u:object_r:unlabeled_t:s0 /etc/shadow system_u:object_r:unlabeled_t:s0 /bin/bash system_u:object_r:unlabeled_t:s0 -> system_u:object_r:unlabeled_t:s0 /bin/login system_u:object_r:unlabeled_t:s0 /bin/sh system_u:object_r:unlabeled_t:s0 -> system_u:object_r:unlabeled_t:s0 /sbin/agetty system_u:object_r:unlabeled_t:s0 -> system_u:object_r:unlabeled_t:s0 /sbin/init system_u:object_r:unlabeled_t:s0 -> system_u:object_r:unlabeled_t:s0 /usr/sbin/sshd system_u:object_r:unlabeled_t:s0 \u53c2\u8003\uff1a GRUB2\u5f15\u5bfc\u52a0\u8f7d\u7a0b\u5e8f\u4e2d\u6dfb\u52a0\u7684\u4e09\u4e2a\u53c2\u6570\u7684\u89e3\u91ca\uff1a security=selinux : This option tells the kernel to use SELinux and not AppArmor. selinux=1 : This option switches on SELinux. enforcing=0 : This option puts SELinux in permissive mode. In this mode, SELinux is fully functional, but does not enforce any of the security settings in the policy. Use this mode for testing and configuring your system. To switch on SELinux protection, when the system is fully operational, change the option to enforcing=1 and add SELINUX=enforcing in /etc/selinux/config . \u5c0f\u8d34\u58eb\uff1a \u5728\u9996\u6b21\u542f\u7528SELinux\u540e\uff0c\u5982\u679c\u53ea\u5728grub2\u91cc\u9762\u6dfb\u52a0selinux=1\uff0c\u901a\u8fc7 getenforce \u547d\u4ee4\u770b\u7684SELinux\u4e00\u76f4\u5c31\u662fdisabled\u7684\u72b6\u6001\uff0c\u9700\u8981\u624b\u5de5\u521b\u5efa/etc/selinux/config\u6587\u4ef6\u6dfb\u52a0\u914d\u7f6e\u624d\u884c\u3002\u611f\u89c9grub2\u91cc\u9762\u65e0\u9700\u8bbe\u7f6e\uff0c\u76f4\u63a5\u914d\u7f6e/etc/selinux/config\u6587\u4ef6\u3002\u4e0d\u786e\u5b9a\u8fd9\u4e2a\u60f3\u6cd5\u662f\u5426\u6b63\u786e\u3002 \u5728grub2\u4e2d\u8bbe\u5b9aselinux=1\uff0c\u5728/etc/selinux/config\u6587\u4ef6\u4e2d\uff1a \u8bbe\u5b9aSELINUX=permissive\uff0c\u91cd\u542f\u540e\u901a\u8fc7 getenforce \u547d\u4ee4\u770b\u5230\u7684\u662fpermissive\u3002 \u8bbe\u5b9aSELINUX=disabled\uff0c\u5219\u91cd\u542f\u540e getenforce \u547d\u4ee4\u770b\u5230\u7684\u662fdisabled\u3002 \u8fd9\u8bf4\u660e\u914d\u7f6e\u6587\u4ef6\u540e\u542f\u52a8\uff0c\u8986\u76d6\u4e86\u5185\u6838\u8bbe\u7f6e\u3002 \u6ce8\u610f\uff0c\u5982\u679c\u4ec5\u4ec5\u5b8c\u6210\u4e86\u4e0a\u9762\u7684enable SELinux\uff0c\u7acb\u523b\u8bbe\u5b9aSELINUX=enforcing\uff0c\u4f1a\u5f15\u8d77ssh\u65e0\u6cd5\u767b\u5f55\uff0c\u9519\u8bef\u4fe1\u606f\u662f /bin/bash: Permission denied \u3002 \u914d\u7f6eSELinux\u3002 $ sudo semanage boolean -l Failed to use semanage \u6dfb\u52a0\u4e0b\u9762\u5185\u5bb9\u5230.bashrc\u6587\u4ef6\u3002 export PATH = /usr/local/bin:/home/ $USER /.local/bin: $PATH \u66f4\u65b0pip3. pip3 install --upgrade pip \u5b89\u88c5\u4e0b\u9762\u51e0\u4e2a\u5305 sudo zypper in libselinux libselinux-devel sudo zypper in python3-semanage sudo zypper in libsemanage-devel libsemanage-devel-static sudo zypper in policycoreutils-python-utils sudo zypper in cross-x86_64-linux-glibc-devel glibc-utils glibc-profile sudo zypper in policycoreutils-devel 2.3.SELinux in Ubuntu \u00b6 2.4.SELinux in Rocky \u00b6 3.\u7528\u6237\u548c\u7ec4\u7684\u914d\u7f6e\u6587\u4ef6 \u00b6 /etc/passwd \uff1a\u7528\u6237\u53ca\u5176\u5c5e\u6027\u4fe1\u606f\uff08\u7528\u6237\u540d\uff0cUID\uff0c\u4e3b\u7ec4ID\u7b49\uff09 /etc/shadow \uff1a\u7528\u6237\u5bc6\u7801\u673a\u5668\u5c5e\u6027 /etc/group \uff1a\u7ec4\u53ca\u5176\u5c5e\u6027 /etc/gshadow \uff1a\u7ec4\u5bc6\u7801\u53ca\u5176\u5c5e\u6027 3.1./etc/passwd \u00b6 \u683c\u5f0f\u8bf4\u660e\uff1a vagrant:x:1001:474:vagrant:/home/vagrant:/bin/bash [ ----- ] - [ -- ] [ - ] [ ----- ] [ ----------- ] [ ------- ] | | | | | | +--------> 7 . Login shell | | | | | +--------------------> 6 . Home directory | | | | +-------------------------------> 5 . GECOS or the full name of the user | | | +-------------------------------------> 4 . GID | | +------------------------------------------> 3 . UID | +---------------------------------------------> 2 . Password +--------------------------------------------------> 1 . Username 3.2./etc/shadow \u00b6 \u683c\u5f0f\u8bf4\u660e\uff1a vagrant: $6 $.n.:17736:0:99999:7::: [ ----- ] [ ---- ] [ --- ] - [ --- ] ---- | | | | | || | +-----------> 9 . Unused | | | | | || +------------> 8 . Expiration date since Jan 1 , 1970 | | | | | | +-------------> 7 . Inactivity period \u5bc6\u7801\u8fc7\u671f\u540e\u7684\u5bbd\u9650\u671f | | | | | +--------------> 6 . Warning period, default 7 days | | | | +------------------> 5 . Maximum password age | | | +----------------------> 4 . Minimum password age | | +--------------------------> 3 . Last password change since Jan 1 , 1970 | +---------------------------------> 2 . Encrypted Password +-------------------------------------------> 1 . Username 3.3./etc/group \u00b6 \u683c\u5f0f\u8bf4\u660e\uff1a audio:x:492:pulse [ --- ] - [ - ] [ --- ] | | | +----> 4 . username-list, who have this group as their supplementary | | +---------> 3 . GID | +------------> 2 . group-password. Real password is in /etc/gshadow +----------------> 1 . groupname 3.4./etc/gshadow \u00b6 \u683c\u5f0f\u8bf4\u660e\uff1a general:!!:shelley:juan,bob [ ----- ] -- [ ----- ] [ ------ ] | | | +-------> 4 . group members ( in a comma delimited list ) | | +---------------> 3 . group adminstrators ( in a comma delimited list ) | +---------------------> 2 . encrypted password. ` ! ` , ` !! ` , and null +---------------------------> 1 . group name Encrypted password ! \uff1ano user is allowed to access the group using the newgrp command. !! \uff1athe same as a value of ! \u2014 however, it also indicates that a password has never been set before. null\uff1aonly group members can log into the group. 3.5.\u751f\u6210\u968f\u673a\u5bc6\u7801 \u00b6 # \u901a\u8fc7`/dev/urandom`\u751f\u6210\u968f\u673a\u6570\uff0c\u901a\u8fc7`tr -dc`\u8fc7\u6ee4\u968f\u673a\u6570\uff0c\u53ea\u4fdd\u7559\u5b57\u6bcd\u548c\u6570\u5b57\uff0c\u901a\u8fc7`head -c`\u4fdd\u7559\u6307\u5b9a\u4f4d\u6570 $ tr -dc '[:alnum:]' < /dev/urandom | head -c 12 xFw7vfma54D8 $ openssl rand -base64 9 I5TZXJfpd3Pg 3.6.vipw/vigr/pwck/grpck\u547d\u4ee4 \u00b6 vipw \u548c vigr \u547d\u4ee4\u5206\u522b\u7f16\u8f91\u6587\u4ef6 /etc/passwd \u548c /etc/group \u3002 \u5982\u679c\u6307\u5b9a\u4e86 -s \u6807\u5fd7\uff0c\u8fd9\u4e9b\u547d\u4ee4\u5c06\u5206\u522b\u7f16\u8f91\u5176\u6587\u4ef6\u7684\u5f71\u5b50\uff08\u5b89\u5168\uff09\u7248\u672c\uff1a /etc/shadow \u548c /etc/gshadow \u3002 vipw \u548c vigr \u547d\u4ee4\u5728\u7f16\u8f91\u6587\u4ef6\u65f6\u4f1a\u8bbe\u7f6e\u9501\u4ee5\u9632\u6b62\u6587\u4ef6\u635f\u574f\u3002 vipw \u548c vigr \u547d\u4ee4\u4f1a\u9996\u5148\u5c1d\u8bd5\u73af\u5883\u53d8\u91cf $VISUAL \uff0c\u7136\u540e\u662f\u73af\u5883\u53d8\u91cf $EDITOR \uff0c\u6700\u540e\u662f\u9ed8\u8ba4\u7f16\u8f91\u5668 vi \u3002 sudo vipw sudo vipw -s sudo vigr sudo vigr -s pwck \u547d\u4ee4\u5b9e\u73b0\u9a8c\u8bc1\u7cfb\u7edf\u8ba4\u8bc1\u4fe1\u606f\u7684\u5b8c\u6574\u6027\u3002 \u68c0\u67e5 /etc/passwd \u548c /etc/shadow \u4e2d\u7684\u6240\u6709\u6761\u76ee\u6bcf\u4e2a\u5b57\u6bb5\u662f\u5426\u5177\u6709\u6b63\u786e\u7684\u683c\u5f0f\u548c\u6709\u6548\u6570\u636e\u3002 \u7cfb\u7edf\u4f1a\u63d0\u793a\u7528\u6237\u5220\u9664\u683c\u5f0f\u4e0d\u6b63\u786e\u6216\u5b58\u5728\u5176\u4ed6\u9519\u8bef\u7684\u6761\u76ee\u3002 pwck \u8fd4\u56de\u503c\uff1a 0 : success 1 : invalid command syntax 2 : one or more bad password entries 3 : can\u2019t open password files 4 : can\u2019t lock password files 5 : can\u2019t update password files grpck \u547d\u4ee4\u5b9e\u73b0\u9a8c\u8bc1\u7cfb\u7edf\u8ba4\u8bc1\u4fe1\u606f\u7684\u5b8c\u6574\u6027\u3002 \u68c0\u67e5 /etc/group \u548c /etc/gshadow \u4e2d\u7684\u6240\u6709\u6761\u76ee\u6bcf\u4e2a\u5b57\u6bb5\u662f\u5426\u5177\u6709\u6b63\u786e\u7684\u683c\u5f0f\u548c\u6709\u6548\u6570\u636e\u3002 \u7cfb\u7edf\u4f1a\u63d0\u793a\u7528\u6237\u5220\u9664\u683c\u5f0f\u4e0d\u6b63\u786e\u6216\u5b58\u5728\u5176\u4ed6\u9519\u8bef\u7684\u6761\u76ee\u3002 grpck \u8fd4\u56de\u503c\uff1a 0 : success 1 : invalid command syntax 2 : one or more bad group entries 3 : can\u2019t open group files 4 : can\u2019t lock group files 5 : can\u2019t update group files 4.\u7528\u6237\u7ba1\u7406 \u00b6 \u7528\u6237\u7ba1\u7406\u547d\u4ee4\uff1a useradd usermod userdel 4.1.\u521b\u5efa\u7528\u6237 useradd \u00b6 \u4e3e\u4f8b\uff1a # \u666e\u901a\u7528\u6237 $ useradd -m -g wheel -G root -c \"vagrant\" vagrant # \u975e\u4ea4\u4e92\u7528\u6237 $ useradd -r -u 48 -g apache -d /var/www -s /sbin/nologin -g postfix -c \"Apache\" apache 2 >/dev/null useradd \u547d\u4ee4\u7684\u9ed8\u8ba4\u503c\u662f\u5728 /etc/default/useradd \u6587\u4ef6\u4e2d\u8bbe\u5b9a\u3002 openSUSE\u7684 /etc/default/useradd \u6587\u4ef6\u5185\u5bb9\uff1a GROUP = 100 HOME = /home INACTIVE = -1 # \u5bf9\u5e94/etc/shadow\u6587\u4ef6\u7b2c7\u5217\uff0cInactivity period\uff0c\u5bc6\u7801\u8fc7\u671f\u540e\u7684\u5bbd\u9650\u671f\uff0c-1\u8868\u793a\u4e0d\u9650\u5236 EXPIRE = # \u5bf9\u5e94/etc/shadow\u6587\u4ef6\u7b2c8\u5217\uff0cExpiration date since Jan 1, 1970\uff0c\u5373\u8d26\u53f7\u6709\u6548\u671f SHELL = /bin/bash SKEL = /etc/skel # \u7528\u4e8e\u751f\u6210\u7528\u6237\u4e3b\u76ee\u5f55\u7684\u6a21\u7248\u6587\u4ef6 USRSKEL = /usr/etc/skel CREATE_MAIL_SPOOL = yes Rocky\u7684 /etc/default/useradd \u6587\u4ef6\u5185\u5bb9\uff1a GROUP = 100 HOME = /home INACTIVE = -1 EXPIRE = SHELL = /bin/bash SKEL = /etc/skel CREATE_MAIL_SPOOL = yes \u5728Ubuntu\u4e2d /etc/default/useradd \u6587\u4ef6\u53ea\u6709\u4e0b\u9762\u8fd9\u4e00\u884c\u3002 SHELL = /bin/sh 4.1.1.\u6279\u91cf\u521b\u5efa\u7528\u6237 newusers \u00b6 \u683c\u5f0f\uff1a newusers \u3002\u5176\u4e2d\u6587\u4ef6 \u7684\u683c\u5f0f\u5982\u4e0b\uff1a :::::: \u4e3e\u4f8b\uff0c\u521b\u5efa\u6587\u4ef6 users.txt \uff1a $ cat ~/users.txt tester1:123:600:1530: \"Test User1,testuser1@abc.com\" :/home/tester1:/bin/bash tester2:123:601:1529:::/bin/bash tester3:123::::: tester4:123::::/home/tester4:/bin/tsh \u770b\u7ed3\u679c\uff1a $ cat /etc/passwd | grep tester tester1:x:600:1530: \"Test User1,testuser1@abc.com\" :/home/tester1:/bin/bash tester2:x:601:1529:::/bin/bash tester3:x:1001:1001::: tester4:x:1002:1002::/home/tester4:/bin/tsh $ cat /etc/group | grep tester tester1:*:1530: tester2:*:1529: tester3:*:1001: tester4:*:1002: $ sudo cat /etc/shadow | grep tester tester1:!:19321:0:99999:7::: tester2:!:19321:0:99999:7::: tester3:!:19321:0:99999:7::: tester4:!:19321:0:99999:7::: $ ls -ld /home/tester* drwxr-xr-x. 1 tester1 tester1 0 Nov 26 00 :32 /home/tester1 drwxr-xr-x. 1 tester4 tester4 0 Nov 26 00 :32 /home/tester4 4.1.2.\u6279\u91cf\u4fee\u6539\u5bc6\u7801 chpasswd \u00b6 \u4e0d\u540c\u65b9\u6cd5\uff1a echo username:password | chpasswd chpasswd < file.txt # file.txt\u6bcf\u884c\u7684\u683c\u5f0f\u662fusername:password paste -d \":\" user.txt passwd.txt | chpasswd \u53c2\u6570 -e \uff1a\u53e3\u4ee4\u4ee5\u52a0\u5bc6\u7684\u65b9\u5f0f\u4f20\u9012\u3002\u5426\u5219\u53e3\u4ee4\u4ee5\u660e\u6587\u7684\u5f62\u5f0f\u4f20\u9012\u3002 \u6ce8\u610f\uff1a \u7528\u6237\u540dusername\u5fc5\u987b\u662f\u5df2\u5b58\u5728\u7684\u7528\u6237 \u666e\u901a\u7528\u6237\u6ca1\u6709\u4f7f\u7528\u8fd9\u4e2a\u6307\u4ee4\u7684\u6743\u9650 \u5982\u679c\u8f93\u5165\u6587\u4ef6\u662f\u6309\u975e\u52a0\u5bc6\u65b9\u5f0f\u4f20\u9012\u7684\u8bdd\uff0c\u8bf7\u5bf9\u8be5\u6587\u4ef6\u8fdb\u884c\u9002\u5f53\u7684\u52a0\u5bc6\u3002 \u6307\u4ee4\u6587\u4ef6\u4e0d\u80fd\u6709\u7a7a\u884c \u4e3e\u4f8b\uff1a echo tester1:112233 | sudo chpasswd $ cat chpasswd.txt tester1:112233 tester2:33445566 $ sudo chpasswd < chpasswd.txt 4.1.3.\u751f\u6210\u52a0\u5bc6\u5bc6\u7801 openssl passwd \u00b6 \u547d\u4ee4 openssl passwd \u683c\u5f0f\u53ef\u4ee5\u5982\u4e0b\u65b9\u6cd5\u83b7\u5f97\u3002 $ man -f passwd passwd ( 1 ) - change user password passwd ( 1ssl ) - compute password hashes passwd ( 5 ) - password file $ man passwd Man: find all matching manual pages ( set MAN_POSIXLY_CORRECT to avoid this ) * passwd ( 1 ) passwd ( 5 ) passwd ( 1ssl ) Man: What manual page do you want? Man: 1ssl \u4e3e\u4f8b\uff08\u8fd9\u91cc\u7528 \u4ee3\u66ff\u5b9e\u9645\u5bc6\u7801\uff09\uff1a # \u57fa\u4e8e\u7ed9\u5b9a\u5b57\u4e32newpasswd\u751f\u6210sha256\u52a0\u5bc6\u7801\uff0c $ openssl passwd -6 newpasswd # \u521b\u5efa\u65b0\u7528\u6237tester5\uff0c\u8d4b\u4e88\u52a0\u5bc6\u5bc6\u7801 $ useradd -p '' tester1 # \u8bfb\u53d6\u7528\u6237tester5\u7684\u5bc6\u7801\uff0c\u53ef\u4ee5\u9a8c\u8bc1\u662f\u5426\u548c\u4e4b\u524d\u7684\u4e00\u81f4 $ sudo getent shadow tester5 tester5::19321:0:99999:7::: 4.2.\u4fee\u6539\u7528\u6237\u5c5e\u6027 usermod \u00b6 \u6dfb\u52a0\u7528\u6237\u5230\u9644\u52a0\u7ec4 usermod -a -G GROUP USER usermod -a -G GROUP1,GROUP2,GROUP3 USER \u4fee\u6539\u7528\u6237\u4e3b\u7ec4 usermod -a -g GROUP USER \u4fee\u6539\u7528\u6237\u4fe1\u606f usermod -c \"GECOS Comments\" USER \u4fee\u6539\u7528\u6237\u4e3b\u76ee\u5f55\uff0c\u4f7f\u7528\u7edd\u5bf9\u8def\u5f84\uff0c -m \u53c2\u6570\u4f1a\u628a\u539f\u4e3b\u76ee\u5f55\u7684\u5185\u5bb9\u79fb\u52a8\u5230\u65b0\u4e3b\u76ee\u5f55\u3002 usermod -d NEW_HOME_DIR USER usermod -d NEW_HOME_DIR -m USER \u4fee\u6539\u7528\u6237shell usermod -s SHELL USER \u4fee\u6539\u7528\u6237UID usermod -u UID USER \u4fee\u6539\u7528\u6237\u540d\uff08\u4e0d\u5e38\u7528\uff09\uff0c\u540c\u65f6\u4e5f\u9700\u8981\u4fee\u6539\u7528\u6237\u4e3b\u76ee\u5f55\u3002 usermod -l NEW_USER USER \u4fee\u6539\u7528\u6237\u8fc7\u671f\u5c5e\u6027\uff0c\u65e5\u671f\u683c\u5f0f\u662f YYYY-MM-DD usermod -e DATE USER \u5982\u679c\u8bbe\u5b9a\u6c38\u4e0d\u8fc7\u671f\uff0c\u5219\u7f6e\u7a7a\u65e5\u671f\uff1a usermod -e \"\" USER \u67e5\u770b\u5f53\u524d\u7528\u6237\u7684\u8fc7\u671f\u65e5\u671f $ sudo chage -l vagrant Last password change : Oct 30 , 2022 Password expires : never Password inactive : never Account expires : never Minimum number of days between password change : 0 Maximum number of days between password change : 99999 Number of days of warning before password expires : 7 \u9501\u5b9a\u7528\u6237\u3002 \u6b64\u547d\u4ee4\u5c06\u5728\u52a0\u5bc6\u5bc6\u7801\u524d\u63d2\u5165\u4e00\u4e2a\u611f\u53f9\u53f7 (!) \u6807\u8bb0\u3002 \u5f53 /etc/shadow \u6587\u4ef6\u4e2d\u7684\u5bc6\u7801\u5b57\u6bb5\u5305\u542b\u611f\u53f9\u53f7\u65f6\uff0c\u7528\u6237\u5c06\u65e0\u6cd5\u4f7f\u7528\u5bc6\u7801\u9a8c\u8bc1\u767b\u5f55\u7cfb\u7edf\u3002 \u5176\u4ed6\u767b\u5f55\u65b9\u6cd5\u4ecd\u7136\u5141\u8bb8\uff0c\u4f8b\u5982\u57fa\u4e8e\u5bc6\u94a5\u7684\u8eab\u4efd\u9a8c\u8bc1\u6216\u5207\u6362\u5230\u7528\u6237\u3002 \u5982\u679c\u8981\u9501\u5b9a\u8d26\u6237\u5e76\u7981\u7528\u6240\u6709\u767b\u5f55\u65b9\u5f0f\uff0c\u8fd8\u9700\u8981\u5c06\u5230\u671f\u65e5\u671f\u8bbe\u7f6e\u4e3a1\u3002 usermod -L USER usermod -L -e 1 USER \u89e3\u9501\u7528\u6237 usermod -U USER 4.3.\u5220\u9664\u7528\u6237 userdel \u00b6 userdel \u547d\u4ee4\u6267\u884c\u65f6\uff0c\u4f1a\u8bfb\u53d6 /etc/login.defs \u6587\u4ef6\u7684\u5185\u5bb9\u3002 \u6b64\u6587\u4ef6\u4e2d\u5b9a\u4e49\u7684\u5c5e\u6027\u4f1a\u8986\u76d6 userdel \u7684\u9ed8\u8ba4\u884c\u4e3a\u3002 \u5982\u679c\u5728\u6b64\u6587\u4ef6\u4e2d\u5c06 USERGROUPS_ENAB \u8bbe\u7f6e\u4e3a yes \uff0c userdel \u5c06\u5220\u9664\u4e0e\u7528\u6237\u540c\u540d\u7684\u7ec4\uff0c\u524d\u63d0\u662f\u6ca1\u6709\u5176\u4ed6\u7528\u6237\u662f\u8be5\u7ec4\u7684\u6210\u5458\u3002 userdel \u547d\u4ee4\u4ece /etc/passwd \u548c /etc/shadow \u6587\u4ef6\u4e2d\u5220\u9664\u7528\u6237\u6761\u76ee\u3002 userdel \u547d\u4ee4\u5220\u9664\u7528\u6237\u5e10\u6237\u65f6\uff0c\u4e00\u822c\u4e0d\u4f1a\u5220\u9664\u7528\u6237\u4e3b\u76ee\u5f55\u548c\u90ae\u4ef6\u5047\u8131\u673amail spool\u76ee\u5f55\u3002 \u4f7f\u7528 -r \u9009\u9879\u5f3a\u5236\u5220\u9664\u7528\u6237\u7684\u4e3b\u76ee\u5f55\u548c\u90ae\u4ef6\u5047\u8131\u673a\u76ee\u5f55\u3002 \u5982\u679c\u8981\u5220\u9664\u7684\u7528\u6237\u4ecd\u7136\u5904\u4e8e\u767b\u5f55\u72b6\u6001\uff0c\u6216\u8005\u6709\u5c5e\u4e8e\u8be5\u7528\u6237\u7684\u6b63\u5728\u8fd0\u884c\u7684\u8fdb\u7a0b\uff0c\u5219 userdel \u547d\u4ee4\u4e0d\u5141\u8bb8\u5220\u9664\u8be5\u7528\u6237\u3002 \u4f7f\u7528 -f \u9009\u9879\u5f3a\u5236\u5220\u9664\u7528\u6237\u5e10\u6237\uff0c\u5373\u4f7f\u7528\u6237\u4ecd\u7136\u767b\u5f55\u6216\u6709\u5c5e\u4e8e\u8be5\u7528\u6237\u7684\u6b63\u5728\u8fd0\u884c\u7684\u8fdb\u7a0b\u4e5f\u662f\u5982\u6b64\u3002 userdel USER userdel -r USER 4.4.\u67e5\u770b\u7528\u6237\u4fe1\u606f id \u00b6 \u7c7bUnix\u64cd\u4f5c\u7cfb\u7edf\u4e2d\u7684\u6bcf\u4e2a\u7528\u6237\u90fd\u7531\u4e00\u4e2a\u4e0d\u540c\u7684\u6574\u6570\u6807\u8bc6\uff0c\u8fd9\u4e2a\u552f\u4e00\u7684\u6570\u5b57\u79f0\u4e3aUserID\u3002 \u4e3a\u8fdb\u7a0bprocess\u5b9a\u4e49\u4e86\u4e09\u79cd\u7c7b\u578b\u7684UID\uff0c\u53ef\u4ee5\u6839\u636e\u4efb\u52a1\u7684\u6743\u9650\u52a8\u6001\u66f4\u6539\u3002 \u5b9a\u4e49\u7684\u4e09\u79cd\u4e0d\u540c\u7c7b\u578b\u7684UID\u662f\uff1a \u771f\u5b9e\u7528\u6237ID\uff08Real UserId\uff09\uff1a\u5bf9\u4e8e\u4e00\u4e2a\u8fdb\u7a0b\uff0cReal UserId\u5c31\u662f\u542f\u52a8\u5b83\u7684\u7528\u6237\u7684 UserID\u3002 \u5b83\u5b9a\u4e49\u4e86\u8fd9\u4e2a\u8fdb\u7a0b\u53ef\u4ee5\u8bbf\u95ee\u54ea\u4e9b\u6587\u4ef6\u3002 \u6709\u6548\u7528\u6237\u540d\uff08Effective UserID\uff09\uff1a\u5b83\u901a\u5e38\u4e0e Real UserID \u76f8\u540c\uff0c\u4f46\u6709\u65f6\u4f1a\u66f4\u6539\u4e3a\u4f7f\u975e\u7279\u6743\u7528\u6237\u80fd\u591f\u8bbf\u95ee\u90a3\u4e9b\u53ea\u80fd\u7531\u7279\u6743\u7528\u6237\uff08\u5982 root \uff09\u8bbf\u95ee\u7684\u6587\u4ef6\u3002 \u4fdd\u5b58\u7684\u7528\u6237ID\uff08Saved UserID\uff09 \uff1a\u5f53\u4e00\u4e2a\u4ee5\u63d0\u5347\u7684\u6743\u9650\uff08\u901a\u5e38\u662f root \uff09\u8fd0\u884c\u7684\u8fdb\u7a0b\u9700\u8981\u505a\u4e00\u4e9b\u4f4e\u6743\u9650\u7684\u4efb\u52a1\u65f6\u4f7f\u7528\uff0c\u53ef\u4ee5\u901a\u8fc7\u4e34\u65f6\u5207\u6362\u5230\u975e\u7279\u6743\u5e10\u6237\u6765\u5b9e\u73b0\u3002\u5728\u6267\u884c\u4f4e\u6743\u9650\u4efb\u52a1\u65f6\uff0c\u6709\u6548\u7684 UID \u88ab\u66f4\u6539\u4e3a\u67d0\u4e2a\u8f83\u4f4e\u6743\u9650\u7684\u503c\uff0c\u5e76\u4e14 euid \u88ab\u4fdd\u5b58\u5230\u5df2\u4fdd\u5b58\u7684 userID (suid)\u4e2d\uff0c\u4ee5\u4fbf\u5728\u4efb\u52a1\u5b8c\u6210\u65f6\u7528\u4e8e\u5207\u6362\u56de\u7279\u6743\u5e10\u6237\u3002 \u5728\u4e00\u4e2a\u7ec8\u7aef\u7a97\u53e3\u6267\u884c\u4e0b\u9762\u547d\u4ee4\uff0c\u6682\u505c\u5728\u65b0\u5bc6\u7801\u8f93\u5165\u8fd9\u4e00\u6b65\u3002 $ ls -ltr /usr/bin/passwd -rwsr-xr-x. 1 root shadow 65208 May 8 2022 /usr/bin/passwd $ passwd Changing password for vagrant. Current password: New password: \u65b0\u5f00\u4e00\u4e2a\u7ec8\u7aef\u7a97\u53e3\u3002 $ ps -a | grep passwd 3040 pts/0 00 :00:00 passwd $ ps -eo pid,euid,ruid | grep 3040 3040 0 1000 \u4e0a\u9762\u8f93\u51fa\u53ef\u4ee5\u770b\u51fa\uff0c passwd \u8fd9\u4e2a\u8fdb\u7a0b\u7684Effective UserID\u662f 0 \u3002Real UserId\u662f 1000 . id \u547d\u4ee4\u67e5\u770b\u7528\u6237\u6709\u6548\u7684UID\u548cGID\u3002 \u67e5\u770b\u5f53\u524d\u7528\u6237\u7684\u4fe1\u606f\uff1a $ id uid = 1000 ( vagrant ) gid = 478 ( wheel ) groups = 478 ( wheel ) ,0 ( root ) context = unconfined_u:unconfined_r:unconfined_t:s0 \u67e5\u770b\u6307\u5b9a\u7528\u6237\u7684\u4fe1\u606f\uff1a $ id vagrant uid = 1000 ( vagrant ) gid = 478 ( wheel ) groups = 0 ( root ) ,478 ( wheel ) \u67e5\u770b\u5f53\u524d\u7528\u6237\u7684GID\uff1a $ id -g 478 \u67e5\u770b\u5f53\u524d\u7528\u6237\u7684UID\uff1a $ id -u 1000 \u67e5\u770b\u5f53\u524d\u7528\u6237\u6240\u6709\u7ec4\u7684GID\uff1a $ id -G 478 0 \u67e5\u770b\u5f53\u524d\u7528\u6237\u540d\uff1a $ id -un vagrant \u67e5\u770b\u5f53\u524d\u7528\u6237\u7684GID $ id -ur 1000 \u53ea\u6709SELinux\u6fc0\u6d3b\u540e\u624d\u6709 $ id -Z unconfined_u:unconfined_r:unconfined_t:s0 \u7c7b\u4f3c\u4e8e whoami \u547d\u4ee4 $ id -znG wheelroot 4.5.\u5207\u6362\u7528\u6237 su \u00b6 \u547d\u4ee4 su - username \u662f\u767b\u5f55\u5f0f\u5207\u6362\u7528\u6237\u3002\u4f1a\u8bfb\u53d6\u76ee\u6807\u7528\u6237\u7684\u914d\u7f6e\u6587\u4ef6\uff0c\u5207\u6362\u81f3\u76ee\u6807\u7528\u6237\u7684\u4e3b\u76ee\u5f55\u3002 \u547d\u4ee4 su username \u662f\u975e\u767b\u5f55\u5f0f\u5207\u6362\u7528\u6237\u3002\u4e0d\u8bfb\u53d6\u76ee\u6807\u7528\u6237\u7684\u914d\u7f6e\u6587\u4ef6\uff0c\u4e0d\u6539\u53d8\u5f53\u524d\u5de5\u4f5c\u76ee\u5f55\u3002 \u5207\u6362\u6210root\u7528\u6237\uff0c\u5e76\u4f7f\u7528zsh shell\u3002 su -s /usr/bin/zsh su -s /usr/bin/zsh root \u5207\u6362\u6210tester1\u7528\u6237\uff0c\u4f7f\u7528bash shell su - tester1 -s /bin/bash su - -s /bin/bash tester1 \u4fdd\u7559\u5f53\u524d\u7528\u6237\u73af\u5883\u4e0d\u53d8\u3002 su -p root \u4e0d\u4ea4\u4e92\u5f0f\u5207\u6362\u7528\u6237\uff0c\u53ea\u7528\u76ee\u6807\u7528\u6237\u6267\u884c\u67d0\u4e9b\u547d\u4ee4\u3002 su -c ps su - root -c \"getent passwd\" su - root -s /bin/bash -c \"getent passwd\" root \u7528\u6237\u5207\u6362\u81f3\u5176\u4ed6\u7528\u6237\u4e0d\u9700\u8981\u5bc6\u7801\uff0c\u975e root \u7528\u6237\u5207\u6362\u5176\u4ed6\u7528\u6237\u9700\u8981\u5bc6\u7801\u3002 4.6.\u8bbe\u7f6e\u5bc6\u7801 \u00b6 4.6.1. passwd \u00b6 \u4fee\u6539\u5f53\u524d\u7528\u6237\u81ea\u5df1\u7684\u5bc6\u7801\uff1a passwd \u4fee\u6539\u5176\u4ed6\u7528\u6237\u7684\u5bc6\u7801\uff1a sudo passwd root \u67e5\u770b\u67d0\u4e2a\u7528\u6237\u5bc6\u7801\u72b6\u6001\uff1a $ sudo passwd -S root root P 10 /30/2022 -1 -1 -1 -1 $ sudo passwd -S vagrant vagrant P 10 /30/2022 0 99999 7 -1 \u68c0\u67e5\u5168\u90e8\u7528\u6237\u7684\u5bc6\u7801\u72b6\u6001\uff1a sudo passwd -Sa \u5bc6\u7801\u72b6\u6001\u8bf4\u660e\uff1a Username Status Date Last Changed Minimum Age Maximum Age Warning Period Inactivity Period vagrant P 10 /30/2022 0 99999 7 -1 root P 10 /30/2022 -1 -1 -1 -1 Status\u7684\u63cf\u8ff0\uff1a P : Usable password NP : No password L : Locked password Age\u7684\u4e00\u4e9b\u7279\u6b8a\u503c\uff1a 9999 : Never expires 0 : Can be changed at anytime -1 : Not active \u5f3a\u5236\u8981\u6c42\u7528\u6237\u4e0b\u6b21\u767b\u5f55\u65f6\u4fee\u6539\u5bc6\u7801\uff1a $ sudo passwd -e tester1 $ sudo passwd -S tester1 tester1 P 01 /01/1970 0 99999 7 -1 \u7528\u6237tester1\u7684\u5bc6\u7801\u65e5\u671f\u5df2\u7ecf\u88ab\u6539\u6210 01/01/1970 \u4e86\u3002\u8fd9\u4e2a\u65e5\u671f\u7b97\u662fUnix\u7684\u201c\u7eaa\u5143\uff08epoch\uff09\u201d\u65e5\u671f\uff0c\u610f\u5473\u7740Unix\u7684\u65e5\u671f\u8d77\u70b9\uff0c0\u5929\u3002 \u9501\u5b9a\u67d0\u4e2a\u7528\u6237\uff1a $ sudo passwd -l tester1 $ sudo passwd -S tester1 tester1 L 01 /01/1970 0 99999 7 -1 \u6b64\u65f6\u7528\u6237 tester1 \u7684\u72b6\u6001\u680f\u5df2\u7ecf\u53d8\u6210\u4e86 L \uff0c\u9501\u5b9a\u72b6\u6001\u3002 \u89e3\u9501\u67d0\u4e2a\u7528\u6237\uff1a $ sudo passwd -u tester1 $ sudo passwd -S tester1 tester1 P 01 /01/1970 0 99999 7 -1 \u6b64\u65f6\u7528\u6237 tester1 \u7684\u72b6\u6001\u680f\u5df2\u7ecf\u4ece L \u53d8\u56de\u4e86 P \uff0c\u89e3\u9664\u4e86\u9501\u5b9a\u72b6\u6001\u3002 \u5220\u9664\u7528\u6237\u5bc6\u7801\u3002\u8fd9\u4e2a\u64cd\u4f5c\u614e\u91cd\uff0c\u5bc6\u7801\u5220\u9664\u540e\u8be5\u7528\u6237\u53ef\u4ee5\u4e0d\u9700\u8981\u5bc6\u7801\u5c31\u80fd\u8bbf\u95ee\u7cfb\u7edf\u3002 $ sudo passwd -d tester1 $ sudo passwd -S tester1 tester1 NP 01 /01/1970 0 99999 7 -1 \u6b64\u65f6\u7528\u6237 tester1 \u7684\u72b6\u6001\u680f\u662f NP \u3002 4.6.2. pwgen \u00b6 \u5b89\u88c5\u5305\u3002 mkpasswd\u547d\u4ee4\u6709\u6b67\u4e49\uff0c2\u4e2a\u540c\u540d\u547d\u4ee4\u5b9e\u73b0\u4e0d\u540c\u529f\u80fd\uff0c\u751f\u6210\u968f\u673a\u5bc6\u7801\u5efa\u8bae\u4f7f\u7528 pwgen \u547d\u4ee4\u3002Rocky9\u6ca1\u6709\u627e\u5230pwgen\u5305\u3002 sudo zypper in pwgen sudo apt install pwgen \u968f\u673a\u751f\u6210\u957f\u5ea68\u4f4d\u5b89\u5168\u5bc6\u7801\u3002 pwgen -s -1 \u968f\u673a\u751f\u6210\u957f\u5ea614\u4f4d\u5b89\u5168\u5bc6\u7801\u3002 pwgen -s -1 14 \u968f\u673a\u751f\u62102\u4e2a\u957f\u5ea615\u4f4d\u5b89\u5168\u5bc6\u7801\u3002 pwgen -s -1 15 2 \u968f\u673a\u751f\u62105\u4e2a\u5bc6\u7801\uff0c\u957f\u5ea610\u4f4d\uff0c\u6bcf\u4e2a\u5bc6\u7801\u81f3\u5c11\u542b\u4e00\u4e2a\u7279\u6b8a\u5b57\u7b26\uff0c\u7ed3\u679c\u4ee5\u5217\u5f62\u5f0f\u8f93\u51fa\u3002 pwgen -s -1 -y 10 5 \u751f\u6210\u957f\u5ea68\uff0c\u542b\u6709\u6570\u5b57\uff0c\u542b\u6709\u5927\u5c0f\u5199\u5b57\u6bcd\u7684\u5bc6\u78014\u4e2a\uff0c\u5217\u6253\u5370 pwgen -s -n -c -C -1 8 4 \u751f\u6210\u957f\u5ea68\uff0c\u4e0d\u542b\u6570\u5b57\uff0c\u53ea\u542b\u5c0f\u5199\u5b57\u6bcd\uff0c\u5217\u6253\u5370 pwgen -s -c -A -0 -1 8 4 \u751f\u6210\u957f\u5ea616\uff0c\u542b\u6709\u6570\u5b57\uff0c\u542b\u6709\u5927\u5c0f\u5199\u5b57\u6bcd\uff0c\u542b\u6709\u7279\u6b8a\u5b57\u7b26\u7684\u5bc6\u78013\u4e2a\uff0c\u884c\u6253\u5370 pwgen -s -n -c -y -1 16 3 \u751f\u6210\u957f\u5ea680\uff0c\u4e0d\u542b\u5143\u97f3\u548c\u6570\u5b57\uff0c\u81f3\u5c11\u542b\u6709\u4e00\u4e2a\u5927\u5199\u5b57\u6bcd\uff0c\u884c\u6253\u5370 pwgen -s -v -c -0 80 1 4.6.3.\u975e\u4ea4\u4e92\u5f0f\u8bbe\u7f6e\u5bc6\u7801 \u00b6 \u65b9\u6cd51\uff1a $ echo -e '123456\\n123456' | sudo passwd tester1 New password: BAD PASSWORD: it is too simplistic/systematic BAD PASSWORD: is too simple Retype new password: passwd: password updated successfully \u65b9\u6cd52\uff1a Rocky\u4e2d\u53ef\u4ee5\u4f7f\u7528\u4e0b\u9762\u65b9\u6cd5\u3002 pwgen -ncy1 16 1 | tee passwd.txt | sudo passwd --stdin tester1 openSUSE\u548cUbuntu\u53ef\u4ee5\u7528\u4e0b\u9762\u65b9\u6cd5\u3002 echo \"tester1:\" ` pwgen -ncy1 16 1 ` | tee passwd.txt | sudo chpasswd \u65b9\u6cd53\uff1a\u6839\u636e\u9884\u5148\u7ed9\u5b9a\u7684\u7528\u6237\u5217\u8868\uff0c\u6279\u91cf\u751f\u6210\u5bc6\u7801\u3002 $ cat > user-list.txt < user.txt < file 67274683 lrwxrwxrwx. 1 vagrant wheel 12 Nov 1 11 :20 symlinkfile1-1 -> symlinkfile1 67274682 lrwxrwxrwx. 1 vagrant wheel 4 Nov 1 10 :43 symlinkfile2 -> file 33555262 drwxr-xr-x. 2 vagrant wheel 6 Nov 1 11 :30 typelink \u4ee5 67274680 -rw-r--r--. 3 vagrant wheel 31 Nov 1 11:14 file \u4e3a\u4f8b\uff1a 67274680 : inode \u7d22\u5f15\u8282\u70b9\u7f16\u53f7\u3002 -rw-r--r-- \uff1a\u6587\u4ef6\u7c7b\u578b\u53ca\u6743\u9650 - \uff1a\u6587\u4ef6\u7c7b\u578b\uff0c\u4f8b\u5b50\u4e2d\u51fa\u73b0\u4e86\u4e09\u79cd\uff0c - \uff0c l \u548c d \u3002 - \uff1a\u666e\u901a\u6587\u4ef6 d \uff1a\u76ee\u5f55 l \uff1a\u7b26\u53f7\u94fe\u63a5\u6587\u4ef6\uff08link\uff09 b \uff1a\u5757\u8bbe\u5907\uff08block\uff09 c \uff1a\u5b57\u7b26\u8bbe\u5907\uff08character\uff09 p \uff1a\u7ba1\u9053\u6587\u4ef6\uff08pipe\uff09 s \uff1a\u5957\u63a5\u5b57\u6587\u4ef6\uff08socket\uff09 rw-r--r-- \uff1a\u6587\u4ef6\u6743\u9650\uff0c\u4ece\u5de6\u5230\u53f3\u4f9d\u6b21\u4e3a\uff1a\uff08\u7528\u6237\u7684\u6700\u7ec8\u6743\u9650\uff0c\u662f\u4ece\u5de6\u5411\u53f3\u5339\u914d\uff0c\u4e00\u65e6\u5339\u914d\u5219\u6743\u9650\u7acb\u5373\u751f\u6548\uff0c\u4e0d\u518d\u5411\u53f3\u7ee7\u7eed\u5339\u914d\uff09 rw- \uff1a\u6587\u4ef6\u5c5e\u4e3b\u6743\u9650\uff08u\uff09\uff0c\u4f8b\u5b50\u4e2d\u662f vagrant \u3002 r-- \uff1a\u6587\u4ef6\u5c5e\u7ec4\u7684\u6743\u9650\uff08g\uff09\uff0c\u4f8b\u5b50\u4e2d\u662f wheel \u3002 r-- \uff1a\u5176\u4ed6\u7ec4\u7684\u6743\u9650\uff08o\uff09\u3002 . \uff1a\u8fd9\u4e2a\u70b9\u8868\u793a\u6587\u4ef6\u5e26\u6709SELinux\u7684\u5b89\u5168\u4e0a\u4e0b\u6587\uff08SELinux Contexts\uff09\u3002\u5173\u95edSELinux\uff0c\u65b0\u521b\u5efa\u7684\u6587\u4ef6\u5c31\u4e0d\u4f1a\u518d\u6709\u8fd9\u4e2a\u70b9\u4e86\u3002\u4f46\u662f\uff0c\u4ee5\u524d\u521b\u5efa\u7684\u6587\u4ef6\u672c\u6765\u6709\u8fd9\u4e2a\u70b9\u7684\u8fd8\u4f1a\u663e\u793a\u8fd9\u4e2a\u70b9\uff08\u867d\u7136SELinux\u4e0d\u8d77\u4f5c\u7528\u4e86\uff09\u3002 3 \uff1a\u786c\u94fe\u63a5\u6570\uff0c\u4f8b\u5b50\u4e2d file \u548c hardlinkfile1 \u548c hardlinkfile2 \u4e4b\u95f4\u662f\u786c\u94fe\u63a5\uff0c\u6240\u4ee5\u8fd9\u4e09\u4e2a\u6587\u4ef6\u7684\u786c\u94fe\u63a5\u6570\u90fd\u662f 3 \u3002 vagrant \uff1a\u6587\u4ef6\u5c5e\u4e3bowner wheel \uff1a\u6587\u4ef6\u5c5e\u7ec4group 31 \uff1a\u6587\u4ef6\u6216\u76ee\u5f55\u7684\u5927\u5c0f Nov 1 11:14 \uff1a\u6587\u4ef6\u6216\u76ee\u5f55\u7684\u521b\u5efa\u65e5\u671f\u548c\u65f6\u95f4 file \uff1a\u6587\u4ef6\u6216\u76ee\u5f55\u540d\u79f0 \u4e0b\u9762\u662f\u547d\u4ee4 ls -ihl \u5728openSUSE\u548cUbuntu\u4e0a\u7684\u663e\u793a\u7ed3\u679c\u3002 $ ls -ihl 233647 -rw-r--r-- 3 vagrant wheel 31 Nov 1 15 :52 file 233647 -rw-r--r-- 3 vagrant wheel 31 Nov 1 15 :52 hardlinkfile1 233647 -rw-r--r-- 3 vagrant wheel 31 Nov 1 15 :52 hardlinkfile2 233648 lrwxrwxrwx 1 vagrant wheel 4 Nov 1 15 :52 symlinkfile1 -> file 233650 lrwxrwxrwx 1 vagrant wheel 12 Nov 1 15 :52 symlinkfile1-1 -> symlinkfile1 233649 lrwxrwxrwx 1 vagrant wheel 4 Nov 1 15 :52 symlinkfile2 -> file 233646 drwxr-xr-x 1 vagrant wheel 0 Nov 1 15 :51 typelink 7.1.\u4fee\u6539\u5c5e\u4e3b chown \u00b6 chown \u547d\u4ee4\u4fee\u6539\u6587\u4ef6\u5c5e\u4e3b\uff08\u6240\u6709\u8005\uff0cowner\uff09\u3002 \u4fee\u6539\u6587\u4ef6\u5c5e\u4e3b\u4e3aroot\u3002 $ ll f1.txt -rw-r--r--. 1 vagrant wheel 41 Nov 14 22 :23 f1.txt $ sudo chown root f1.txt $ ll f1.txt -rw-r--r--. 1 root wheel 41 Nov 14 22 :23 f1.txt \u4fee\u6539\u6587\u4ef6\u7684\u5c5e\u7ec4\u4e3abin\u3002 $ sudo chown :bin f1.txt $ ll f1.txt -rw-r--r--. 1 root bin 41 Nov 14 22 :23 f1.txt \u540c\u65f6\u4fee\u6539\u6587\u4ef6\u7684\u5c5e\u4e3b\u548c\u5c5e\u7ec4\u3002 $ sudo chown vagrant.wheel f1.txt $ ll f1.txt -rw-r--r--. 1 vagrant wheel 41 Nov 14 22 :23 f1.txt \u53c2\u7167\u67d0\u6587\u4ef6\u4fee\u6539\u53e6\u4e00\u6587\u4ef6\u7684\u5c5e\u6027\u3002 $ ll file.py -rw-r--r--. 1 vagrant wheel 56 Nov 13 22 :50 file.py $ ll user.txt -rw-r--r--. 1 root bin 21 Nov 27 23 :59 user.txt $ sudo chown root.bin user.txt $ sudo chown --reference = user.txt file.py $ ll file.py -rw-r--r--. 1 root bin 56 Nov 13 22 :50 file.py \u9012\u5f52\u4fee\u6539\u6240\u6709\u5b50\u76ee\u5f55\u53ca\u6587\u4ef6\u7684\u5c5e\u4e3b\u548c\u5c5e\u7ec4\u3002 sudo chown -R vagrant.wheel ~ 7.2.\u4fee\u6539\u5c5e\u7ec4 chgrp \u00b6 \u4fee\u6539\u76ee\u5f55\u7684\u5c5e\u7ec4\u3002 sudo chgrp bin ~~ \u4fee\u6539\u76ee\u5f55\u53ca\u5b50\u76ee\u5f55\u53ca\u6587\u4ef6\u7684\u5c5e\u7ec4\u3002 sudo chgrp -R bin ~~ 7.3.\u6587\u4ef6\u548c\u76ee\u5f55\u6743\u9650 \u00b6 \u6587\u4ef6\uff1a r \uff1a\u53ef\u4ee5\u8bfb\u53d6\u8be5\u6587\u4ef6\u5185\u5bb9\uff0c\u6bd4\u5982\u901a\u8fc7 cat \u547d\u4ee4\u3002 w \uff1a\u53ef\u4ee5\u4fee\u6539\u8be5\u6587\u4ef6\u5185\u5bb9\uff0c\u53ef\u4ee5\u53ea\u6709 w \u800c\u6ca1\u6709 r \u3002 x \uff1a\u53ef\u4ee5\u628a\u8be5\u6587\u4ef6\u63d0\u8bf7\u5185\u6838\u542f\u52a8\u4e3a\u4e00\u4e2a\u8fdb\u7a0b\uff0c\u5373\u53ef\u4ee5\u6267\u884c\u8be5\u6587\u4ef6\uff08\u8be5\u6587\u4ef6\u7684\u5185\u5bb9\u5fc5\u987b\u662f\u53ef\u4ee5\u6267\u884c\uff09\u3002 \u76ee\u5f55\uff1a\uff08\u5bf9\u76ee\u5f55\u800c\u8a00\uff0c\u901a\u5e38\u9700\u8981\u7ed9 r \u548c x \u6743\u9650\uff09\uff08\u4ece\u76ee\u5f55\u89d2\u5ea6\u770b\uff0c\u76ee\u5f55\u5185\u6587\u4ef6\u5217\u8868\u7b49\u4e8e\u76ee\u5f55\u8282\u70b9\u7684\u5185\u5bb9\uff09 r \uff1a\u80fd\u770b\u6587\u4ef6\u5217\u8868\uff0c\u4f46\u4e0d\u80fd\u8bbf\u95ee\u6240\u542b\u6587\u4ef6\u7684\u5185\u5bb9\u53ca\u5176\u5c5e\u6027\u4fe1\u606f\uff0c\u5305\u62ecinode\u53f7\u3002 w \uff1a\u80fd\u5728\u8be5\u76ee\u5f55\u5185\u521b\u5efa\u548c\u5220\u9664\u6587\u4ef6\uff0c\u4e0d\u7531\u76ee\u5f55\u5185\u6587\u4ef6\u672c\u8eab\u7684\u6743\u9650\u51b3\u5b9a\u3002 x \uff1a\u80fdcd\u8fdb\u76ee\u5f55\uff0c\u80fd\u901a\u8fc7 ls -l file \u548c stat file \u67e5\u770b\u8be5\u76ee\u5f55\u4e2d\u5236\u5b9a\u6587\u4ef6\u7684\u5143\u6570\u636e\u3002 X \uff1a\u8868\u793a\u53ea\u6709\u5f53\u8be5\u6587\u4ef6\u662f\u4e2a\u5b50\u76ee\u5f55\u6216\u8005\u8be5\u6587\u4ef6\u5df2\u7ecf\u88ab\u8bbe\u5b9a\u8fc7\u4e3a\u53ef\u6267\u884c\u3002 \u6709\u53ea\u8bfb\u6743\u9650\u7684\u7528\u6237\u4e0d\u80fd\u7528cd\u8fdb\u5165\u8be5\u76ee\u5f55\uff0c\u8fd8\u5fc5\u987b\u6709\u6267\u884c\u6743\u9650\u624d\u80fd\u8fdb\u5165\u3002 \u6709\u6267\u884c\u6743\u9650\u7684\u7528\u6237\u53ea\u6709\u5728\u77e5\u9053\u6587\u4ef6\u540d\uff0c\u5e76\u62e5\u6709\u8bfb\u6743\u5229\u7684\u60c5\u51b5\u4e0b\u624d\u53ef\u4ee5\u8bbf\u95ee\u76ee\u5f55\u4e0b\u7684\u6587\u4ef6\u3002 \u5fc5\u987b\u6709\u8bfb\u548c\u6267\u884c\u6743\u9650\u624d\u53ef\u4ee5ls\u5217\u51fa\u76ee\u5f55\u6e05\u5355\uff0c\u6216\u4f7f\u7528cd\u547d\u4ee4\u8fdb\u5165\u76ee\u5f55\u3002 \u6709\u76ee\u5f55\u7684\u5199\u6743\u9650\uff0c\u53ef\u4ee5\u521b\u5efa\u3001\u5220\u9664\u6216\u4fee\u6539\u76ee\u5f55\u4e0b\u7684\u4efb\u4f55\u6587\u4ef6\u6216\u5b50\u76ee\u5f55\uff0c\u5373\u4f7f\u4f7f\u8be5\u6587\u4ef6\u6216\u5b50\u76ee\u5f55\u5c5e\u4e8e\u5176\u4ed6\u7528\u6237\u4e5f\u662f\u5982\u6b64\u3002 \u5e38\u7528\u6743\u9650\u4f8b\u5b50\uff1a -rw------- ( 600 ) \u53ea\u6709\u6240\u6709\u8005\u624d\u6709\u8bfb\u548c\u5199\u7684\u6743\u9650 -rw-r--r-- ( 644 ) \u53ea\u6709\u6240\u6709\u8005\u624d\u6709\u8bfb\u548c\u5199\u7684\u6743\u9650\uff0c\u7ec4\u548c\u5176\u4ed6\u4eba\u53ea\u6709\u8bfb\u7684\u6743\u9650 -rwx------ ( 700 ) \u53ea\u6709\u6240\u6709\u8005\u624d\u6709\u8bfb\uff0c\u5199\uff0c\u6267\u884c\u7684\u6743\u9650 -rwxr-xr-x ( 755 ) \u53ea\u6709\u6240\u6709\u8005\u624d\u6709\u8bfb\uff0c\u5199\uff0c\u6267\u884c\u7684\u6743\u9650\uff0c\u7ec4\u548c\u5176\u4ed6\u4eba\u53ea\u6709\u8bfb\u548c\u6267\u884c\u7684\u6743\u9650 -rwx--x--x ( 711 ) \u53ea\u6709\u6240\u6709\u8005\u624d\u6709\u8bfb\uff0c\u5199\uff0c\u6267\u884c\u7684\u6743\u9650\uff0c\u7ec4\u548c\u5176\u4ed6\u4eba\u53ea\u6709\u6267\u884c\u7684\u6743\u9650 -rw-rw-rw- ( 666 ) \u6bcf\u4e2a\u4eba\u90fd\u6709\u8bfb\u5199\u7684\u6743\u9650 -rwxrwxrwx ( 777 ) \u6bcf\u4e2a\u4eba\u90fd\u6709\u8bfb\u5199\u548c\u6267\u884c\u7684\u6743\u9650 7.4.\u6743\u9650\u4fee\u6539 chmod \u00b6 \u547d\u4ee4\u683c\u5f0f\uff1a chmod [ -cfvR ] [ --help ] [ --version ] mode file mode \u5b57\u4e32\u683c\u5f0f\u4e3a\uff1a [ ugoa ][ +- =][ rwxXst ] who: u \u6587\u4ef6\u6240\u6709\u8005 g \u6587\u4ef6\u6240\u6709\u8005\u6240\u5728\u7ec4 o \u5176\u4ed6\u7528\u6237 a \u6240\u6709\u7528\u6237\uff0c\u76f8\u5f53\u4e8e ugo operator: + \u4e3a\u6307\u5b9a\u7684\u7528\u6237\u7c7b\u578b\u589e\u52a0\u6743\u9650 - \u53bb\u9664\u6307\u5b9a\u7528\u6237\u7c7b\u578b\u7684\u6743\u9650 = \u8bbe\u7f6e\u6307\u5b9a\u7528\u6237\u6743\u9650\u7684\u8bbe\u7f6e\uff0c\u5373\u5c06\u7528\u6237\u7c7b\u578b\u7684\u6240\u6709\u6743\u9650\u91cd\u65b0\u8bbe\u7f6e permission: r \u8bbe\u7f6e\u4e3a\u53ef\u8bfb\u6743\u9650 w \u8bbe\u7f6e\u4e3a\u53ef\u5199\u6743\u9650 x \u8bbe\u7f6e\u4e3a\u53ef\u6267\u884c\u6743\u9650 X \u7279\u6b8a\u6267\u884c\u6743\u9650\uff0c\u53ea\u6709\u5f53\u6587\u4ef6\u4e3a\u76ee\u5f55\u6587\u4ef6\uff0c\u6216\u8005\u5176\u4ed6\u7c7b\u578b\u7684\u7528\u6237\u6709\u53ef\u6267\u884c\u6743\u9650\u65f6\uff0c\u624d\u5c06\u6587\u4ef6\u6743\u9650\u8bbe\u7f6e\u53ef\u6267\u884c s \u5f53\u6587\u4ef6\u88ab\u6267\u884c\u65f6\uff0c\u6839\u636ewho\u53c2\u6570\u6307\u5b9a\u7684\u7528\u6237\u7c7b\u578b\u8bbe\u7f6e\u6587\u4ef6\u7684 setuid \u6216\u8005 setgid \u6743\u9650 t \u8bbe\u7f6e\u7c98\u8d34\u4f4d\uff0c\u53ea\u6709\u8d85\u7ea7\u7528\u6237\u53ef\u4ee5\u8bbe\u7f6e\u8be5\u4f4d\uff0c\u53ea\u6709\u6587\u4ef6\u6240\u6709\u8005u\u53ef\u4ee5\u4f7f\u7528\u8be5\u4f4d\u3002 \u793a\u4f8b\uff1a \u5c06\u6587\u4ef6 file1.txt \u8bbe\u4e3a\u6240\u6709\u4eba\u7686\u53ef\u8bfb\u53d6\u3002 chmod ugo+r file1.txt \u5c06\u6587\u4ef6 file1.txt \u8bbe\u4e3a\u6240\u6709\u4eba\u7686\u53ef\u8bfb\u53d6\u3002 chmod a+r file1.txt \u5c06\u6587\u4ef6 file1.txt \u4e0e file2.txt \u8bbe\u4e3a\u8be5\u6587\u4ef6\u5c5e\u4e3b\u548c\u5c5e\u7ec4\u90fd\u53ef\u5199\u5165\uff0c\u4f46\u5176\u4ed6\u7528\u6237\u4e0d\u53ef\u5199\u5165\u3002 chmod ug+w,o-w file1.txt file2.txt \u4e3a ex1.py \u6587\u4ef6\u5c5e\u4e3b\u589e\u52a0\u53ef\u6267\u884c\u6743\u9650\u3002 chmod u+x ex1.py \u5c06\u76ee\u524d\u76ee\u5f55\u4e0b\u7684\u6240\u6709\u6587\u4ef6\u4e0e\u5b50\u76ee\u5f55\u7686\u8bbe\u4e3a\u4efb\u4f55\u4eba\u53ef\u8bfb\u53d6\u3002 chmod -R a+r * \u7ed9 file \u7684\u6240\u6709\u7528\u6237\u589e\u52a0\u8bfb\u6743\u9650 chmod a+r file \u5220\u9664 file \u7684\u6240\u6709\u7528\u6237\u7684\u6267\u884c\u6743\u9650 chmod a-x file \u7ed9 file \u7684\u6240\u6709\u7528\u6237\u589e\u52a0\u8bfb\u5199\u6743\u9650 chmod a+rw file \u7ed9 file \u7684\u6240\u6709\u7528\u6237\u589e\u52a0\u8bfb\u5199\u6267\u884c\u6743\u9650 chmod +rwx file \u5bf9 file \u7684\u5c5e\u4e3b\u8bbe\u7f6e\u8bfb\u5199\u6743\u9650\uff0c\u6e05\u7a7a\u5c5e\u7ec4\u548c\u5176\u4ed6\u7528\u6237\u5bf9 file \u7684\u6240\u6709\u6743\u9650\uff08\u7a7a\u683c\u4ee3\u8868\u65e0\u6743\u9650\uff09 chmod u = rw,go = file \u5bf9\u76ee\u5f55 docs \u548c\u5176\u5b50\u76ee\u5f55\u4e2d\u7684\u6240\u6709\u6587\u4ef6\u7ed9\u5c5e\u4e3b\u589e\u52a0\u8bfb\u6743\u9650\uff0c\u800c\u5bf9\u5c5e\u7ec4\u548c\u5176\u4ed6\u7528\u6237\u5220\u9664\u8bfb\u6743\u9650 chmod -R u+r,go-r docs \u5bf9 file \u7684\u5c5e\u4e3b\u548c\u5c5e\u7ec4\u8bbe\u7f6e\u8bfb\u5199\u6743\u9650, \u4e3a\u5176\u4ed6\u7528\u6237\u8bbe\u7f6e\u8bfb\u6743\u9650 chmod 664 file \u5bf9 file \u7684\u5c5e\u4e3b\u8bbe\u7f6e\u8bfb\u5199\u6267\u884c\u6743\u9650\uff0c\u76f8\u5f53\u4e8e u=rwx (4+2+1)\uff0c\u8bbe\u7f6e\u5c5e\u7ec4\u8bfb\u548c\u6267\u884c\u6743\u9650\uff0c\u76f8\u5f53\u4e8e go=rx (4+1 & 4+1)\u3002 0 \u6ca1\u6709\u7279\u6b8a\u6a21\u5f0f chmod 0755 file 4 \u8bbe\u7f6e\u4e86\u8bbe\u7f6e\u7528\u6237ID\u4f4d\uff0c\u5269\u4e0b\u7684\u76f8\u5f53\u4e8e u=rwx (4+2+1)\u548c go=rx (4+1 & 4+1)\u3002 chmod 4755 file \u5220\u9664\u53ef\u6267\u884c\u6743\u9650\u5bf9 path/ \u4ee5\u53ca\u5176\u6240\u6709\u7684\u76ee\u5f55\uff08\u4e0d\u5305\u62ec\u6587\u4ef6\uff09\u7684\u6240\u6709\u7528\u6237\uff0c\u4f7f\u7528 -type f \u5339\u914d\u6587\u4ef6 find path/ -type d -exec chmod a-x {} \\; \u5141\u8bb8\u6240\u6709\u7528\u6237\u6d4f\u89c8\u6216\u901a\u8fc7\u76ee\u5f55 path/ find path/ -type d -exec chmod a+x {} \\; 7.5.\u9ed8\u8ba4\u6743\u9650 umask \u00b6 umask \u7684\u503c\uff0c\u5b9a\u4e49\u4e86\u6240\u6709\u65b0\u5efa\u7684\u6587\u4ef6\u548c\u76ee\u5f55\u7684\u521d\u59cb\u6743\u9650\u7684\u3002 \u67e5\u770b\u5f53\u524d\u6743\u9650\u63a9\u7801\uff1a $ umask 0022 \u5728\u4e0d\u8003\u8651 umask \u7684\u60c5\u51b5\u4e0b\uff0c\u6587\u4ef6\u7684\u9ed8\u8ba4\u6743\u9650\u662f 666 (rw-rw-rw-)\uff0c\u76ee\u5f55\u7684\u9ed8\u8ba4\u6743\u9650\u662f 777 (rwxrwxrwx)\u3002 \u5728 umask \u7684\u503c\u4e3a 0022 \u7684\u60c5\u51b5\u4e0b\uff0c\u6587\u4ef6\u7684\u9ed8\u8ba4\u6743\u9650\u662f 644 (rw-r--r--)\uff0c\u76ee\u5f55\u7684\u9ed8\u8ba4\u6743\u9650\u662f 755 (rwxr-xr-x)\u3002 \u8ba1\u7b97\u65b9\u6cd5\uff1a Files: ( Default ) 6 6 6 ( umask ) 0 2 2 ---------------- ( Result ) 6 4 4 Directories: ( Default ) 7 7 7 ( umask ) 0 2 2 ---------------- ( Result ) 7 5 5 \u5982\u679c umask \u7684\u503c\u4e3a 0077 \u7684\u60c5\u51b5\u4e0b\uff0c\u6587\u4ef6\u7684\u9ed8\u8ba4\u6743\u9650\u662f 600 (rw-------)\uff0c\u76ee\u5f55\u7684\u9ed8\u8ba4\u6743\u9650\u662f 700 (rwx------)\u3002 \u8ba1\u7b97\u65b9\u6cd5\uff1a Files: ( Default ) 6 6 6 ( umask ) 0 7 7 ---------------- ( Result ) 6 0 0 Directories: ( Default ) 7 7 7 ( umask ) 0 7 7 ---------------- ( Result ) 7 0 0 \u4e3e\u4f8b\uff1a $ umask 022 $ touch file2 $ ll file2 -rw-r--r--. 1 vagrant wheel 0 Nov 28 23 :13 file2 $ umask 077 $ touch file1 $ ll file1 -rw-------. 1 vagrant wheel 0 Nov 28 23 :12 file1 $ umask 022 $ mkdir ./tmp1 $ umask 077 $ mkdir ./tmp2 $ ls -dl tmp* drwxr-xr-x. 1 vagrant wheel 0 Nov 28 23 :14 tmp1 drwx------. 1 vagrant wheel 0 Nov 28 23 :14 tmp2 7.6.\u7279\u6b8a\u6743\u9650 \u00b6 \u9664\u4e86\u4e09\u79cd\u5e38\u89c1\u7684\u6743\u9650rwx\uff0c\u8fd8\u6709\u4e09\u79cd\u7279\u6b8a\u6743\u9650\uff1aSUID\uff0cSGID\uff0cSticky\u3002 SUID\uff1a\u5c5e\u4e3bs\u6743\u9650\uff0c\u79f0\u4e3aSet UID \u524d\u63d0\uff1a\u8fdb\u7a0b\u6709\u5c5e\u4e3b\u548c\u5c5e\u7ec4\uff0c\u6587\u4ef6\u6709\u5c5e\u4e3b\u548c\u5c5e\u7ec4 \u4efb\u4f55\u53ef\u6267\u884c\u7a0b\u5e8f\u6587\u4ef6\u80fd\u4e0d\u80fd\u542f\u52a8\u4e3a\u8fdb\u7a0b\uff0c\u53d6\u51b3\u4e8e\u53d1\u8d77\u8005\u5bf9\u7a0b\u5e8f\u6587\u4ef6\u662f\u5426\u62e5\u6709\u6267\u884c\u6743\u9650\u3002 \u542f\u52a8\u4e3a\u8fdb\u7a0b\u4e4b\u540e\uff0c\u5176\u8fdb\u7a0b\u7684\u5c5e\u4e3b\u4e3a\u53d1\u8d77\u8005\u3002 \u8fdb\u7a0b\u8bbf\u95ee\u6587\u4ef6\u662f\u7684\u6743\u9650\uff0c\u53d6\u51b3\u4e8e\u8fdb\u7a0b\u7684\u53d1\u8d77\u8005\u3002 \u53ea\u5bf9\u4e8c\u8fdb\u5236\u53ef\u6267\u884c\u7a0b\u5e8f\u6587\u4ef6\u6709\u6548\u3002\u5f53\u6267\u884c\u8be5\u6587\u4ef6\u65f6\uff0c\u53d1\u8d77\u8005\u5c06\u81ea\u52a8\u5177\u6709\u8be5\u6587\u4ef6\u6240\u6709\u8005\u7684\u6743\u9650\u3002 \u5bf9\u76ee\u5f55\u65e0\u6548\u3002 $ ll file1 -rw-------. 1 vagrant wheel 0 Nov 28 23 :12 file1 $ sudo chmod u+s file1 $ ll file1 -rwS------. 1 vagrant wheel 0 Nov 28 23 :12 file1 \u5982\u679c\u5c5e\u4e3b\u7684 x \u4f4d\u4e0a\u662f-\uff0c\u5219\u5728\u5c5e\u4e3b\u7684 x \u4f4d\u4e0a\u6807\u8bb0\u5927\u5199 S \uff0c\u5426\u5219\u6807\u8bb0\u5c0f\u5199 s \u3002\u5982\u4e0b\uff1a $ chmod 777 file1 $ ll file1 -rwxrwxrwx. 1 vagrant wheel 0 Nov 28 23 :12 file1 $ sudo chmod u+s file1 $ ll file1 -rwsrwxrwx. 1 vagrant wheel 0 Nov 28 23 :12 file1 \u4e0b\u97622\u7ec4\u547d\u4ee4\u5b9e\u73b0\u540c\u6837\u6548\u679c\u3002 sudo chmod 4xxx file1 chmod 777 file1 sudo chmod u+s file1 \u53d6\u6d88SUID\u3002 sudo chmod u-s file1 SGID\uff1a\u5c5e\u7ec4s\u6743\u9650\uff0c\u79f0\u4e3aSet GID \u5982\u679c\u4f5c\u7528\u4e8e\u4e8c\u8fdb\u5236\u53ef\u6267\u884c\u6587\u4ef6\u4e0a\uff0c\u5f53\u6267\u884c\u8be5\u6587\u4ef6\u4e3a\u8fdb\u7a0b\u4e4b\u540e\uff0c\u53d1\u8d77\u8005\u5c06\u81ea\u52a8\u5177\u6709\u8be5\u6587\u4ef6\u6240\u5c5e\u7ec4\u7684\u6743\u9650\uff0c\u8fdb\u7a0b\u7684\u5c5e\u7ec4\u4e3a\u53d1\u8d77\u8005\u7684\u5c5e\u7ec4\u3002 \u5982\u679c\u4f5c\u7528\u4e8e\u76ee\u5f55\u4e0a\uff0c\u5219\u8be5\u76ee\u5f55\u4e0b\u65b0\u5efa\u7acb\u7684\u76ee\u5f55\u548c\u6587\u4ef6\u90fd\u81ea\u52a8\u4ece\u6b64\u76ee\u5f55\u7ee7\u627f\u3002 $ sudo chmod g+s file2 $ ll file2 -rw-r-Sr--. 1 vagrant wheel 0 Nov 28 23 :13 file2 \u5982\u679c\u5c5e\u7ec4\u7684 x \u4f4d\u4e0a\u662f-\uff0c\u5219\u5728\u5c5e\u7ec4\u7684 x \u4f4d\u4e0a\u6807\u8bb0\u5927\u5199 S \uff0c\u5426\u5219\u6807\u8bb0\u5c0f\u5199 s \u3002\u5982\u4e0b\uff1a $ chmod 777 file2 $ ll file2 -rwxrwxrwx. 1 vagrant wheel 0 Nov 28 23 :13 file2 $ sudo chmod g+s file2 $ ll file2 -rwxrwsrwx. 1 vagrant wheel 0 Nov 28 23 :13 file2 \u4e0b\u97622\u7ec4\u547d\u4ee4\u5b9e\u73b0\u540c\u6837\u6548\u679c\u3002 sudo chmod 2xxx file2 chmod 777 file2 sudo chmod g+s file2 \u53d6\u6d88SGID\u3002 sudo chmod g-s file2 \u5bf9\u4e8e\u76ee\u5f55\uff0c\u4e0b\u9762\u6f14\u793a\u53ef\u4ee5\u770b\u5230\u76ee\u5f55\u4e0b\u7684\u6587\u4ef6\u548c\u5b50\u76ee\u5f55\u7684\u7ee7\u627f\u6027\u3002 $ ll -d data drwxr-xr-x. 1 vagrant bin 0 Nov 28 20 :55 data $ sudo chmod g+s .~ $ ll -d data drwxr-sr-x. 1 vagrant bin 0 Nov 28 20 :55 data $ cd data $ touch file2 $ ll file2 -rw-r--r--. 1 vagrant bin 0 Nov 29 21 :10 file2 $ mkdir tmp3 $ ll -d tmp3 drwxr-sr-x. 1 vagrant bin 0 Nov 29 21 :10 tmp3 Sticky Bit\uff1a\u7b80\u79f0\u4e3aSBIT\u6743\u9650 \u53ea\u9488\u5bf9\u76ee\u5f55\u6709\u6548\u3002\u5b83\u8868\u793a\u53ea\u80fd\u8ba9\u5176\u5c5e\u4e3b\u4ee5\u53caroot\u53ef\u4ee5\u5220\u9664\u3001\u91cd\u547d\u540d\u3001\u79fb\u52a8\u8be5\u76ee\u5f55\u4e0b\u7684\u6587\u4ef6\u3002 Sticky\u8bbe\u7f6e\u5728\u6587\u4ef6\u4e0a\u65e0\u610f\u4e49\u3002 \u5982\u679c\u5176\u4ed6\u7684 x \u4f4d\u4e0a\u662f-\uff0c\u5219\u5728\u5176\u4ed6\u7684 x \u4f4d\u4e0a\u6807\u8bb0\u5927\u5199 T \uff0c\u5426\u5219\u6807\u8bb0\u5c0f\u5199 t \u3002 $ ll -d .~ drwxr-sr-x. 1 vagrant bin 18 Nov 29 21 :10 .~ $ sudo chmod o+t .~ $ ll -d .~ drwxr-sr-t. 1 vagrant bin 18 Nov 29 21 :10 .~ $ cd data $ touch file1 $ mkdir tmp1 $ ll file1 -rw-r--r--. 1 vagrant bin 0 Nov 29 21 :37 file1 $ ll -d tmp1 drwxr-sr-x. 1 vagrant bin 0 Nov 29 21 :37 tmp1 \u7279\u6b8a\u6743\u9650\u8bbe\u7f6e\u6570\u5b57\u6cd5\uff1a \u8bbe\u7f6eSUID User Group Others r w s r w s r w x r w S BIN 100 1 1 1 1 1 1 1 1 1 1 1 0 OCT 4 7 7 7 6 \u8bbe\u7f6eSGID User Group Others r w x r w s r w x r w S BIN 010 1 1 1 1 1 1 1 1 1 1 1 0 OCT 2 7 7 7 6 \u8bbe\u7f6eSticky Bit - SBIT User Group Others r w x r w x r w t r w T BIN 001 1 1 1 1 1 1 1 1 1 1 1 0 OCT 1 7 7 7 6 7.7.\u8bbe\u5b9a\u6587\u4ef6\u7279\u6b8a\u5c5e\u6027 chattr \u00b6 \u547d\u4ee4\u683c\u5f0f\uff1a chattr [ -RVf ] [ -v version ] [ mode ] files... \u5176\u4e2dmode\u7684\u5b57\u4e32\u683c\u5f0f\uff1a {+|-|=}[aAcCdDeijsStTu] \u5c5e\u6027 i \uff1a \u5982\u679c\u5bf9\u6587\u4ef6\u8bbe\u7f6e i \u5c5e\u6027\uff0c\u90a3\u4e48\u4e0d\u5141\u8bb8\u5bf9\u6587\u4ef6\u8fdb\u884c\u5220\u9664\u3001\u6539\u540d\uff0c\u4e5f\u4e0d\u80fd\u6dfb\u52a0\u548c\u4fee\u6539\u6570\u636e\uff1b \u5982\u679c\u5bf9\u76ee\u5f55\u8bbe\u7f6e i \u5c5e\u6027\uff0c\u90a3\u4e48\u53ea\u80fd\u4fee\u6539\u76ee\u5f55\u4e0b\u6587\u4ef6\u4e2d\u7684\u6570\u636e\uff0c\u4f46\u4e0d\u5141\u8bb8\u5efa\u7acb\u548c\u5220\u9664\u6587\u4ef6\uff1b \u5728openSUSE\u4e0b\u6267\u884c\uff0c\u5206\u533a\u6587\u4ef6\u7c7b\u578b\u662fbtrfs\u683c\u5f0f\u3002 $ touch filetest $ lsattr filetest ---------------------- filetest $ chattr +i filetest chattr: Operation not permitted while setting flags on filetest $ sudo chattr +i filetest $ lsattr filetest ----i----------------- filetest $ rm filetest rm: cannot remove 'filetest' : Operation not permitted $ sudo rm filetest rm: cannot remove 'filetest' : Operation not permitted $ echo \"test\" >> filetest -bash: filetest: Operation not permitted $ sudo echo \"test\" >> filetest -bash: filetest: Operation not permitted $ sudo chattr -i filetest \u5c5e\u6027 a \uff1a \u5982\u679c\u5bf9\u6587\u4ef6\u8bbe\u7f6e a \u5c5e\u6027\uff0c\u90a3\u4e48\u53ea\u80fd\u5728\u6587\u4ef6\u4e2d\u5897\u52a0\u6570\u636e\uff0c\u4f46\u662f\u4e0d\u80fd\u5220\u9664\u548c\u4fee\u6539\u6570\u636e\uff1b \u5982\u679c\u5bf9\u76ee\u5f55\u8bbe\u7f6e a \u5c5e\u6027\uff0c\u90a3\u4e48\u53ea\u5141\u8bb8\u5728\u76ee\u5f55\u4e2d\u5efa\u7acb\u548c\u4fee\u6539\u6587\u4ef6\uff0c\u4f46\u662f\u4e0d\u5141\u8bb8\u5220\u9664\u6587\u4ef6\uff1b \u5728openSUSE\u4e0b\u6267\u884c\uff0c\u5206\u533a\u6587\u4ef6\u7c7b\u578b\u662fbtrfs\u683c\u5f0f\u3002 lsattr filetest ---------------------- filetest $ chattr +a filetest chattr: Operation not permitted while setting flags on filetest $ sudo chattr +a filetest $ echo \"test\" >> filetest $ rm filetest rm: cannot remove 'filetest' : Operation not permitted $ sudo rm filetest rm: cannot remove 'filetest' : Operation not permitted $ sudo chattr -a filetest \u5c5e\u6027 u \uff1a \u8bbe\u7f6e\u6b64\u5c5e\u6027\u7684\u6587\u4ef6\u6216\u76ee\u5f55\uff0c\u5728\u5220\u9664\u65f6\uff0c\u5176\u5185\u5bb9\u4f1a\u88ab\u4fdd\u5b58\uff0c\u4ee5\u4fdd\u8bc1\u540e\u671f\u80fd\u591f\u6062\u590d\uff0c\u5e38\u7528\u6765\u9632\u6b62\u610f\u5916\u5220\u9664\u6587\u4ef6\u6216\u76ee\u5f55\u3002 \u5728Ubuntu\u4e0b\u6267\u884c\uff0c\u5206\u533a\u6587\u4ef6\u7c7b\u578b\u662fext4\u683c\u5f0f\u3002 $ touch filetest $ sudo chattr +u filetest $ lsattr filetest -u------------e------- filetest $ rm filetest \u5c5e\u6027 s \uff1a \u548c u \u76f8\u53cd\uff0c\u5220\u9664\u6587\u4ef6\u6216\u76ee\u5f55\u65f6\uff0c\u4f1a\u88ab\u5f7b\u5e95\u5220\u9664\uff08\u76f4\u63a5\u4ece\u786c\u76d8\u4e0a\u5220\u9664\uff0c\u7136\u540e\u75280\u586b\u5145\u6240\u5360\u7528\u7684\u533a\u57df\uff09\uff0c\u4e0d\u53ef\u6062\u590d\u3002 \u63d0\u793a\uff1a \u547d\u4ee4 chattr \u548c lsattr \u7684\u53ef\u64cd\u4f5c\u5c5e\u6027\u4f9d\u8d56\u4e8e\u6587\u4ef6\u6240\u5904\u5206\u533a\u7684\u6587\u4ef6\u7cfb\u7edf\u7c7b\u578b\uff0c\u4f8b\u5982\uff0cext4\u548cxfs\u7684\u7ed3\u679c\u4f1a\u6709\u4e0d\u540c\u3002 \u5386\u53f2\uff1a\u547d\u4ee4 chattr \uff08\u7528\u4e8e\u64cd\u4f5c\u5c5e\u6027\uff09\u548c lsattr \uff08\u7528\u4e8e\u5217\u51fa\u5c5e\u6027\uff09\u6700\u521d\u4e13\u7528\u4e8e\u7b2c\u4e8c\u4e2a\u6269\u5c55\u6587\u4ef6\u7cfb\u7edf\u7cfb\u5217\uff08ext2\u3001ext3\u3001ext4\uff09\uff0c\u5e76\u4e14\u4f5c\u4e3a e2fsprogs \u5305\u7684\u4e00\u90e8\u5206\u63d0\u4f9b\u3002\u7136\u800c\uff0c\u6b64\u529f\u80fd\u5df2\u5168\u90e8\u6216\u90e8\u5206\u6269\u5c55\u5230\u8bb8\u591a\u5176\u4ed6\u7cfb\u7edf\uff0c\u5305\u62ec XFS\u3001ReiserFS\u3001JFS \u548c OCFS2\u3002 btrfs \u6587\u4ef6\u7cfb\u7edf\u5305\u62ec\u5c5e\u6027\u529f\u80fd\uff0c\u5305\u62ec C \u6807\u5fd7\uff0c\u7531\u4e8e\u4e0e CoW \u76f8\u5173\u7684\u6027\u80fd\u8f83\u6162\uff0c\u5b83\u5173\u95ed\u4e86btrfs\u7684\u5185\u7f6e\u5199\u65f6\u590d\u5236 (CoW) \u529f\u80fd\u3002 8.\u8bbf\u95ee\u63a7\u5236\u5217\u8868ACL \u00b6 8.1.ACL \u00b6 ACL\u7684\u5168\u79f0\u662fAccess Control List\u3002 \u4f20\u7edf\u7684POSIX\u6743\u9650\u6982\u5ff5\u4f7f\u7528\u4e09\u79cd\u7528\u6237\u7c7b\u578b\u6765\u5206\u914d\u6587\u4ef6\u7cfb\u7edf\u4e2d\u7684\u6743\u9650\uff1a\u6240\u6709\u8005Owning Owner\uff0c\u6240\u6709\u8005\u7ec4Owning Group\u548c\u5176\u4ed6\u7528\u6237Other Users\u3002\u53ef\u4ee5\u4e3a\u6bcf\u4e2a\u7528\u6237\u7c7b\u578b\u8bbe\u7f6e\u4e09\u4e2a\u6743\u9650\u4f4d\uff0c\u8d4b\u4e88\u8bfb\uff08r\uff09\uff0c\u5199\uff08w\uff09\u548c\u6267\u884c\uff08x\uff09\u7684\u6743\u9650\u3002 \u6240\u6709\u8005Owning Owner\u6743\u9650\uff08\u5c5e\u4e3b\u6743\u9650\uff09 \u5c5e\u7ec4Owning Group\u6743\u9650 \u5176\u4ed6\uff08\u7ecf\u8fc7\u8eab\u4efd\u9a8c\u8bc1\u7684\uff09\u7528\u6237Other Users\u7684\u6743\u9650 \u4f20\u7edf\u7684\u4e09\u79cd\u6743\u9650\u9002\u7528\u4e8e\u5927\u591a\u6570\u5b9e\u9645\u6848\u4f8b\u3002\u4f46\u662f\uff0c\u5bf9\u4e8e\u66f4\u590d\u6742\u7684\u573a\u666f\u6216\u66f4\u9ad8\u7ea7\u7684\u5e94\u7528\u7a0b\u5e8f\uff0c\u7cfb\u7edf\u7ba1\u7406\u5458\u5fc5\u987b\u4f7f\u7528\u8bb8\u591a\u6280\u5de7\u6765\u89c4\u907f\u4f20\u7edf\u6743\u9650\u7684\u9650\u5236\u3002 \u8bbf\u95ee\u63a7\u5236\u5217\u8868ACL\u63d0\u4f9b\u4e86\u5bf9\u4f20\u7edf\u6587\u4ef6\u6743\u9650\u6982\u5ff5\u7684\u6269\u5c55\u3002\u5b83\u4eec\u5141\u8bb8\u6211\u4eec\u4e3a\u5355\u4e2a\u7528\u6237\u6216\u7ec4\u5206\u914d\u6743\u9650\uff0c\u5373\u4f7f\u8fd9\u4e9b\u7528\u6237\u6216\u7ec4\u4e0e\u539f\u59cb\u6240\u6709\u8005\u6216\u5c5e\u7ec4\u4e0d\u5bf9\u5e94\u3002 ACL\u662fLinux\u5185\u6838\u7684\u4e00\u9879\u529f\u80fd\uff0c\u652f\u6301Ext\u2154/4\uff0cXFS\u548cBtrFS\u6587\u4ef6\u7cfb\u7edf\u4ee5\u53ca\u5176\u4ed6\u6587\u4ef6\u7cfb\u7edf\u3002 \u4f7f\u7528ACL\uff0c\u6211\u4eec\u53ef\u4ee5\u521b\u5efa\u590d\u6742\u7684\u65b9\u6848\uff0c\u800c\u65e0\u9700\u5728\u5e94\u7528\u7a0b\u5e8f\u7ea7\u522b\u4e0a\u53bb\u5b9e\u73b0\u590d\u6742\u7684\u6743\u9650\u6a21\u578b\u3002\u5728\u4f7f\u7528\u63d0\u4f9bSamba\u6587\u4ef6\u548c\u6253\u5370\u670d\u52a1\u7684Linux\u670d\u52a1\u5668\u66ff\u6362Windows\u670d\u52a1\u5668\u7684\u60c5\u51b5\u4e0b\uff0cACL\u7684\u4f18\u52bf\u975e\u5e38\u660e\u663e\u3002\u7531\u4e8eSamba\u652f\u6301ACL\uff0c\u56e0\u6b64\u53ef\u4ee5\u5728Linux\u670d\u52a1\u5668\u548cWindows\u4e2d\u914d\u7f6e\u7528\u6237\u6743\u9650\u3002 \u901a\u8fc7ACL\u6765\u5141\u8bb8\u5bf9\u6240\u6709\u8005\u7528\u6237\u4e4b\u5916\u7684\u5355\u4e2a\u7528\u6237\u8fdb\u884c\u6587\u4ef6\u5199\u6743\u9650\u662f\u4e00\u79cd\u7b80\u5355\u7684\u65b9\u6848\u3002\u4f7f\u7528\u4f20\u7edf\u65b9\u6cd5\uff0c\u6211\u4eec\u5fc5\u987b\u521b\u5efa\u4e00\u4e2a\u65b0\u7ec4\uff0c\u4f7f\u4e24\u4e2a\u7528\u6237\u6210\u4e3a\u8be5\u7ec4\u7684\u6210\u5458\uff0c\u5c06\u8be5\u6587\u4ef6\u7684\u6240\u6709\u7ec4\u66f4\u6539\u4e3a\u65b0\u7ec4\uff0c\u7136\u540e\u6388\u4e88\u8be5\u7ec4\u6587\u4ef6\u7684\u5199\u6743\u9650\u3002\u521b\u5efa\u7ec4\u5e76\u4f7f\u4e24\u4e2a\u7528\u6237\u6210\u4e3a\u8be5\u7ec4\u7684\u6210\u5458\u5219\u9700\u8981\u5229\u7528root\u6743\u9650\u6765\u5b9e\u73b0\u3002 \u4f7f\u7528ACL\uff0c\u6211\u4eec\u53ef\u4ee5\u901a\u8fc7\u4f7f\u6240\u6709\u8005\u548c\u6307\u5b9a\u7528\u6237\u5bf9\u6587\u4ef6\u5177\u6709\u5199\u6743\u9650\u6765\u5b9e\u73b0\u76f8\u540c\u7684\u7ed3\u679c\u3002 \u6b64\u65b9\u6cd5\u7684\u53e6\u4e00\u4e2a\u4f18\u70b9\u662f\u7cfb\u7edf\u7ba1\u7406\u5458\u65e0\u9700\u53c2\u4e0e\u521b\u5efa\u7ec4\u3002\u7528\u6237\u53ef\u4ee5\u81ea\u5df1\u51b3\u5b9a\u6388\u4e88\u8c01\u8bbf\u95ee\u5176\u6587\u4ef6\u7684\u6743\u9650\u3002 \u63d0\u793a\uff1a \u4f7f\u7528ACL\u65f6 ls \u7684\u8f93\u51fa\u7ed3\u679c\u4f1a\u53d1\u751f\u53d8\u5316\u3002\u6dfb\u52a0\u4e00\u4e2a\u52a0\u53f7+ \u6765\u8bf4\u660e\u5df2\u4e3a\u6b64\u6587\u4ef6\u5b9a\u4e49ACL\uff0c\u4e14\u5b9a\u4e49ACL\u540e\uff0c\u6240\u663e\u793a\u7684\u5c5e\u7ec4\u6743\u9650\u662fACL\u63a9\u7801\u7684\u503c\uff0c\u800c\u4e0d\u518d\u662f\u539f\u6765\u5c5e\u7ec4\u7684\u6743\u9650\u3002 8.2.ACL\u7684\u57fa\u672c\u7c7b\u578b \u00b6 Minimal ACLs\uff08\u6700\u5c0fACL\uff09\uff08\u5b9e\u9645\u7528\u9014\uff1a\u4e0ePOSIX\u6743\u9650\u76f8\u540c\uff09 \u4e0e\u6587\u4ef6\u6a21\u5f0f\u6743\u9650\u4f4d\u7b49\u6548\u7684ACL\u79f0\u4e3a\u6700\u5c0fACL \u5206\u4e09\u79cd\u7c7b\u578b\u7684ACL\u6761\u76ee\uff0c\u8fd9\u4e9b\u5bf9\u5e94\u4e8e\u6587\u4ef6\u548c\u76ee\u5f55\u7684\u4f20\u7edf\u6743\u9650\u4f4d Owning User \u6240\u6709\u8005 Owning Group \u6240\u6709\u8005\u7ec4 Others \u5176\u4ed6\u7ec4 Extended ACLs\uff08\u6269\u5c55ACL\uff09 \u5177\u6709\u591a\u4e8e\u4e0a\u8ff0\u4e09\u4e2aACL\u6761\u76ee\u7684ACL\u79f0\u4e3a\u6269\u5c55ACL \u6269\u5c55ACL\u8fd8\u5305\u542b\u63a9\u7801\u6761\u76ee\uff0c\u53ef\u4ee5\u5305\u542b\u4efb\u610f\u6570\u91cf\u7684\u6307\u5b9a\u7528\u6237\u548c\u6307\u5b9a\u7ec4\u6761\u76ee 8.3.ACL\u672f\u8bed \u00b6 \u7528\u6237\u7c7b\uff08User classes\uff09\u3002 \u4f20\u7edf\u7684POSIX\u6743\u9650\u6982\u5ff5\u4f7f\u7528\u4e09\u79cd\u7528\u6237\u7c7b\u6765\u5206\u914d\u6587\u4ef6\u7cfb\u7edf\u4e2d\u7684\u6743\u9650\uff1a\u6240\u6709\u8005Owning Owner\uff0c\u6240\u6709\u8005\u7ec4Owning Group\u548c\u5176\u4ed6\u7528\u6237Other Users\u3002\u53ef\u4ee5\u4e3a\u6bcf\u4e2a\u7528\u6237\u7c7b\u578b\u8bbe\u7f6e\u4e09\u4e2a\u6743\u9650\u4f4d\uff0c\u8d4b\u4e88\u8bfb\uff08r\uff09\uff0c\u5199\uff08w\uff09\u548c\u6267\u884c\uff08x\uff09\u7684\u6743\u9650\u3002 Owner class \u6240\u6709\u8005\u7c7b Group class \u7ec4\u7c7b Other class \u5176\u4ed6\u7c7b ACL\u8bbf\u95ee\u6743\u9650\uff08Access ACL\uff09\uff1a\u786e\u5b9a\u5404\u79cd\u6587\u4ef6\u7cfb\u7edf\u5bf9\u8c61\uff08\u6587\u4ef6\u548c\u76ee\u5f55\uff09\u7684\u7528\u6237\u548c\u7ec4\u7684\u8bbf\u95ee\u6743\u9650\u3002 \u9ed8\u8ba4ACL\uff08Default ACL\uff09\uff1a\u53ea\u80fd\u5e94\u7528\u4e8e\u76ee\u5f55\u3002 \u5b83\u4eec\u786e\u5b9a\u6587\u4ef6\u7cfb\u7edf\u5bf9\u8c61\u5728\u521b\u5efa\u65f6\u4ece\u5176\u7236\u76ee\u5f55\u7ee7\u627f\u7684\u6743\u9650\u3002 ACL\u6761\u76ee\uff08ACL entry\uff09\uff1a \u6bcf\u4e2aACL\u7531\u4e00\u7ec4ACL\u6761\u76ee\u7ec4\u6210\u3002 ACL\u6761\u76ee\u5305\u542b\u7c7b\u578b\uff08type\uff09\uff0c\u6761\u76ee\u5f15\u7528\u7684\u7528\u6237\u6216\u7ec4\u7684\u9650\u5b9a\u7b26\uff08qualifier\uff09\uff0c\u4ee5\u53ca\u4e00\u7ec4\u6743\u9650\uff08permissions\uff09\u3002 \u5bf9\u4e8e\u67d0\u4e9b\u6761\u76ee\u7c7b\u578b\uff0c\u672a\u5b9a\u4e49\u7ec4\u6216\u7528\u6237\u7684\u9650\u5b9a\u7b26\u3002 8.4.ACL\u6743\u9650\u5206\u7c7b \u00b6 Named user \u6307\u5b9a\u7528\u6237: Lets you assign permissions to individual users. \u5141\u8bb8\u6211\u4eec\u4e3a\u6307\u5b9a\u7528\u6237\u5206\u914d\u6743\u9650\u3002 Named group \u6307\u5b9a\u7ec4: Lets you assign permissions to individual groups. \u5141\u8bb8\u6211\u4eec\u4e3a\u5236\u5b9a\u7ec4\u5206\u914d\u6743\u9650\u3002 Mask \u63a9\u7801: Lets you limit the permissions granted to named users or groups. \u5141\u8bb8\u6211\u4eec\u9650\u5236\u7ed9\u4e88\u6307\u5b9a\u7528\u6237\u6216\u6307\u5b9a\u7ec4\u7684\u6743\u9650\u3002 \u6240\u4ee5\u53ef\u80fd\u7684ACL\u7c7b\u578b Type Text Form owner user::rwx named user user:name:rwx owning group group::rwx named group group:name:rwx mask mask::rwx other other::rwx \u4e0ePOSIX.1\u6743\u9650\u6a21\u578b\u4e0d\u540c\uff0c\u7ec4\u7c7bgroup class\u53ef\u4ee5\u5305\u542b\u5177\u6709\u4e0d\u540c\u6743\u9650\u96c6\u7684ACL\u6761\u76ee\uff0c\u56e0\u6b64\u5355\u72ec\u7684\u7ec4\u7c7b\u6743\u9650\u4e0d\u518d\u8db3\u4ee5\u8868\u793a\u5b83\u5305\u542b\u7684\u6240\u6709ACL\u6761\u76ee\u7684\u6240\u6709\u8be6\u7ec6\u6743\u9650\u3002 \u56e0\u6b64\uff0c\u7ec4\u7c7b\u578b\u6743\u9650\u7684\u542b\u4e49\u88ab\u91cd\u65b0\u5b9a\u4e49\u3002\u5728\u65b0\u8bed\u4e49\u4e0b\uff0c\u7ec4\u7c7b\u578b\u6743\u9650\u8868\u793a\u7ec4\u7c7b\u4e2d\u7684\u4efb\u4f55\u6761\u76ee\u5c06\u6388\u4e88\u7684\u6743\u9650\u7684**\u4e0a\u9650**\uff08upper bound\uff09\u3002 \u6b64\u4e0a\u9650\u5c5e\u6027\u53ef\u786e\u4fdd\u5728\u4f7f\u7528ACL\u63a7\u5236\u540e\uff0c\u5e94\u7528\u7a0b\u5e8f\u4e0d\u4f1a\u7a81\u7136\u6216\u8005\u610f\u5916\u5730\u6388\u4e88\u989d\u5916\u7684\u6743\u9650\u3002 \u5728\u6700\u5c0fACL\u4e2d\uff0c\u7ec4\u7c7b\u6743\u9650\u4e0e\u6240\u6709\u8005\u7ec4\u6743\u9650\u76f8\u540c\u3002\u5728\u6269\u5c55ACL\u4e2d\uff0c\u7ec4\u7c7b\u53ef\u4ee5\u5305\u542b\u5176\u4ed6\u7528\u6237\u6216\u7ec4\u7684\u6761\u76ee\u3002\u8fd9\u4f1a\u5bfc\u81f4\u4e00\u4e2a\u95ee\u9898\uff1a\u8fd9\u4e9b\u9644\u52a0\u6761\u76ee\u4e2d\u7684\u4e00\u4e9b\u53ef\u80fd\u62e5\u6709\u672a\u5305\u542b\u5728\u6240\u6709\u8005\u7ec4\u6761\u76ee\uff08owning group entry\uff09\u4e2d\u7684\u6743\u9650\uff0c\u56e0\u6b64\u6240\u6709\u8005\u7ec4\u6761\u76ee\u6743\u9650\u53ef\u80fd\u4e0e\u7ec4\u7c7b\u6743\u9650\uff08group class\uff09\u4e0d\u540c\u3002 \u901a\u8fc7\u63a9\u7801\uff08mask entry\uff09\u89e3\u51b3\u4e86\u8fd9\u4e2a\u95ee\u9898\u3002 \u4f7f\u7528\u6700\u5c0fACL\uff0c\u7ec4\u7c7b\u6743\u9650\u6620\u5c04\u5230\u6240\u6709\u8005\u7ec4\u6761\u76ee\u6743\u9650\u3002With minimal ACLs, the group class permissions map to the owning group entry permissions. \u4f7f\u7528\u6269\u5c55ACL\u65f6\uff0c\u7ec4\u7c7b\u6743\u9650\u6620\u5c04\u5230\u63a9\u7801\u6761\u76ee\u6743\u9650\uff0c\u800c\u6240\u6709\u8005\u7ec4\u6761\u76ee\u4ecd\u5b9a\u4e49\u62e5\u6709\u7ec4\u6743\u9650\u3002With extended ACLs, the group class permissions map to the mask entry permissions, whereas the owning group entry still defines the owning group permissions. 8.5.ACL\u64cd\u4f5c\u547d\u4ee4 \u00b6 \u8bbe\u5b9aACL\u6743\u9650\uff1a setfacl Syntax: setfacl [OPTIONS] [ACL-ENTRIES] Option Description -m : Add or modify an ACL entry -x : Remove an ACL entry -d : Set a default ACL -b : Remove all extended ACL entries -M : restore ACLs that have been written to a file \u6ce8\u610f\uff1a--set\u9009\u9879\u4f1a\u628a\u539f\u6709\u7684ACL\u9879\u90fd\u5220\u9664\uff0c\u7528\u65b0\u7684\u66ff\u4ee3\uff0c\u6240\u4ee5\u4e00\u5b9a\u8981\u5305\u542bUGO\u7684\u8bbe\u7f6e\uff0c\u4e0d\u80fd\u50cf-m\u533b\u9662\u53ea\u6dfb\u52a0ACL\u3002 setfacl --set u::rw,u:vagrant:rw,g::r,o::- file1 \u8bfb\u53d6ACL\u6743\u9650\uff1a getfacl Syntax: getfacl [OPTIONS] Option Description -a : Display the file access control list -d : Display the default access control list -R : List the ACLs of all files and directories recursively 8.6.ACL\u5b9e\u4f8b\u89e3\u6790 \u00b6 8.6.1.\u5b9e\u4f8b\u63cf\u8ff0 \u00b6 \u9879\u76ee\u76ee\u5f55 ~/project1 \u9879\u76ee\u7ecf\u7406 pm1 \u5bf9\u8fd9\u4e2a\u76ee\u5f55\u62e5\u6709\u8bbf\u95ee\u548c\u4fee\u6539\u6743\u9650 \u9879\u76ee\u6210\u5458 tm1 \u53ef\u4ee5\u8bbf\u95ee\u548c\u4fee\u6539\u8fd9\u4e2a\u76ee\u5f55 \u975e\u9879\u76ee\u6210\u5458 tm2 \u4e0d\u80fd\u8bbf\u95ee ~/project1 \u76ee\u5f55\u3002 \u9879\u76ee\u76ee\u5f55 ~/project1 \u7684\u6743\u9650\u89c4\u5212 \u9879\u76ee\u7ecf\u7406 pm1 \u662f\u8fd9\u4e2a\u76ee\u5f55\u7684\u5c5e\u4e3b\uff0c\u6743\u9650\u4e3a rwx \u9879\u76ee\u7ecf\u7406 pm1 \u5c5e\u4e8e project1 \u7ec4 \u9879\u76ee\u6210\u5458 tm1 \u4e0e pm1 \u5728\u540c\u4e00\u4e2a project1 \u7ec4\uff0c\u6743\u9650\u662f rw \u5176\u4ed6\u4eba\u7684\u6743\u9650\u8bbe\u5b9a\u4e3a 0 \u9879\u76ee\u4e34\u65f6\u6210\u5458tm2\u7684\u6743\u9650\u9700\u6c42 \u80fd\u8bbf\u95ee project1 \u76ee\u5f55\uff0c\u4f46\u53ea\u80fd\u5177\u6709 r \u548c x \u6743\u9650 \u89e3\u51b3\u65b9\u6cd5 \u5f53\u51fa\u73b0\u8fd9\u79cd\u60c5\u51b5\u65f6\uff0c\u666e\u901a\u6743\u9650\u4e2d\u7684\u4e09\u79cd\u8eab\u4efd\uff08owner\uff0cgroup\uff0cothers\uff09\u5c31\u4e0d\u80fd\u89e3\u51b3\u8fd9\u4e2a\u95ee\u9898\uff0c\u800cACL\u6743\u9650\u53ef\u4ee5\u3002 \u5728\u4f7f\u7528ACL\u6743\u9650\u7ed9\u7528\u6237 tm2 \u965a\u4e88\u6743\u9650\u65f6\uff0c tm2 \u65e2\u4e0d\u662f ~/project1 \u76ee\u5f55\u7684\u5c5e\u4e3b\uff0c\u4e5f\u4e0d\u662f\u5c5e\u7ec4\uff0c\u4ec5\u4ec5\u8d4b\u4e88\u7528\u6237 tm2 \u9488\u5bf9 ~/project1 \u76ee\u5f55\u7684r-x\u6743\u9650\uff0c \u5c5e\u4e8e\u5355\u72ec\u6307\u5b9a\u7528\u6237\u5e76\u5355\u72ec\u5206\u914d\u6743\u9650\uff0c\u89e3\u51b3\u4e86\u7528\u6237\u8eab\u4efd\u4e0d\u8db3\u7684\u95ee\u9898\u3002 \u62d3\u5c55\u95ee\u9898 \u7ed9 ~/project1 \u76ee\u5f55\u6dfb\u52a0\u5176\u4ed6\u7ec4 project2 \u7684\u8bbf\u95ee\u6743\u9650 \u901a\u8fc7 mask \u6765\u8c03\u6574\u7528\u6237 tm2 \u5b9e\u9645\u6709\u6548\u6743\u9650 \u9ed8\u8ba4ACL\u6743\u9650 \u9012\u5f52ACL\u6743\u9650 \u5220\u9664ACL\u6743\u9650 8.6.2.\u521d\u59cb\u5316\u73af\u5883 \u00b6 \u521b\u5efa\u6d4b\u8bd5\u7528\u6237 $ whoami vagrant $ sudo groupadd project1 $ sudo groupadd project2 $ sudo useradd -m -g project1 pm1 $ sudo useradd -m -g project1 tm1 $ sudo useradd -m -g project2 tm2 $ sudo passwd pm1 $ sudo passwd tm1 $ sudo passwd tm2 $ cat /etc/group ...... project1:x:1535: project2:x:1536: ...... $ cat /etc/passwd ...... pm1:x:2003:1535::/home/pm1:/bin/bash tm1:x:2004:1535::/home/tm1:/bin/bash tm2:x:2005:1536::/home/tm2:/bin/bash ...... \u521b\u5efa\u6d4b\u8bd5\u76ee\u5f55 project1 , \u6307\u5b9a project1 \u76ee\u5f55\u7684\u6743\u9650\uff0c\u521b\u5efa\u6d4b\u8bd5\u6587\u4ef6 file1 \u3002 $ su - pm1 $ cd ~ $ mkdir project1 $ ls -dl project1 drwxr-xr-x. 1 pm1 project1 0 Dec 4 06 :25 project1 $ chmod 770 project1/ $ ls -dl project1 drwxrwx---. 1 pm1 project1 0 Dec 4 06 :25 project1 $ echo \"hello from $USER \" > ./project1/file1 $ cat ./project1/file1 hello from pm1 \u76ee\u5f55 project1 \u5f53\u524d\u6743\u9650\u5feb\u7167 \u5c5e\u4e3b\uff1a pm1 \uff0c\u5bf9 ~/project1 \u76ee\u5f55\u6709 rwx \u6743\u9650 \u5c5e\u7ec4\uff1a project1 \uff0c\u5305\u542b\u7528\u6237 pm1 \u548c tm1 \uff0c\u5bf9 ~/project1 \u76ee\u5f55\u6709 rwx \u6743\u9650 \u5176\u4ed6\u7ec4\uff1a\u6ca1\u6709\u8bbf\u95ee\u6743\u9650 \u76ee\u5f55 ~/project1 \u5f53\u524d\u7684ACL\u5feb\u7167 $ getfacl ./project1/ # file: home/pm1/project1/ # owner: pm1 # group: project1 user::rwx group::rwx other::--- 8.6.3.\u6dfb\u52a0ACL\u6743\u9650 \u00b6 \u7ed9 ~/project1 \u76ee\u5f55\u6dfb\u52a0\u65b0\u7528\u6237 tm2 \uff0c\u6743\u9650\u4e3a rwx \u3002\u76ee\u5f55 ~/project1 \u7684\u66f4\u65b0\u540e\u7684\u6743\u9650\u4f4d\u53d8\u6210\u4e86 drwxrwx---+ \u3002 $ su - pm1 $ setfacl -m u:tm2:rx ./project1/ $ ls -dl ./project1 drwxrwx---+ 1 pm1 project1 0 Dec 4 06 :25 project1 $ getfacl ~/project1/ # file: project1 \uff08\u6587\u4ef6\u540d\uff09 # owner: pm1 \uff08Owner \u6587\u4ef6\u5c5e\u4e3b\uff09 # group: project1 \uff08Owing Group \u6587\u4ef6\u5c5e\u7ec4\uff09 user::rwx \uff08Ower\u6587\u4ef6\u5c5e\u4e3b\u7684\u6743\u9650\uff0c\u7528\u6237\u540d\u680f\u662f\u7a7a\u7684\uff0c\u8bf4\u660e\u662f\u5c5e\u4e3bOwner\u7684\u6743\u9650\uff09 user:tm2:r-x \uff08Named User \u6307\u5b9a\u7528\u6237\u7684\u6743\u9650\uff0c\u7528\u6237tm2\u7684\u6743\u9650\uff09 group::rwx \uff08Owing Group \u6587\u4ef6\u5c5e\u7ec4\u7684\u6743\u9650\uff0c\u7ec4\u540d\u680f\u662f\u7a7a\u7684\uff0c\u8bf4\u660e\u662f\u5c5e\u7ec4\u7684\u6743\u9650\uff09 \uff08Named Group \u6307\u5b9a\u7528\u6237\u7ec4\u7684\u6743\u9650\uff0c\u6b64\u65f6\u672a\u6307\u5b9a\uff09 mask::rwx \uff08mask\u6743\u9650\uff09 other::--- \uff08\u5176\u4ed6\u4ebaother\u7684\u6743\u9650\uff09 \u7ed9 ~/project1 \u76ee\u5f55\u6dfb\u52a0\u65b0\u7ec4 project2 \u7684\u6743\u9650 rwx $ su - pm1 $ setfacl -m g:project2:rwx ./project1/ $ ls -dl ./project1 drwxrwx---+ 1 pm1 project1 0 Dec 4 06 :46 ./project1 $ getfacl ./project1 # file: project1 # owner: pm1 # group: project1 user::rwx user:tm2:r-x ( \u7528\u6237tm2\u62e5\u6709\u4e86r-x\u6743\u9650\uff09 group::rwx group:project2:rwx ( \u7528\u6237\u7ec4project2\u62e5\u6709\u4e86rwx\u6743\u9650\uff09 mask::rwx other::--- \u6709\u6548\u6743\u9650\u7684\u8ba1\u7b97\uff1a \u5f53\u524d ~/project1 \u76ee\u5f55\u7684 mask \u662f rwx \uff0c tm2 \u7684\u6743\u9650\u662f r-x \uff0c\u4e8c\u8005\u8fdb\u884cAND\u64cd\u4f5c\uff0c tm2 \u7684\u5b9e\u9645\u6743\u9650\u662f r-x tm2: r - x ( 1 0 1 ) mask: r w x ( 1 1 1 ) --------------------- result: r - x ( 1 0 1 ) \u5bf9\u7167\u4e0b\u9762\u7684\u89c4\u5219\uff0c\u9a8c\u8bc1\u7528\u6237 tm2 \u5bf9 ~/project1 \u76ee\u5f55\u7684\u5b9e\u9645\u6743\u9650\u3002 su - tm2 \u80fd\u8fdb\u5165\u76ee\u5f55 project1 \uff0c\u8bf4\u660e\u5f53\u524d\u7528\u6237\u5177\u6709\u76ee\u5f55 project1 \u7684 r-x \u6743\u9650\u3002 $ whoami tm2 $ cd /home/pm1/project1/ \u80fd\u5217\u51fa\u76ee\u5f55 project1 \u4e0b\u6587\u4ef6\u5217\u8868\uff0c\u53ef\u4ee5\u67e5\u770b\u6587\u4ef6 file \u7684\u5185\u5bb9\uff0c\u8bf4\u660e\u5f53\u524d\u7528\u6237\u5177\u6709\u76ee\u5f55 project1 \u7684 r-x \u6743\u9650\u3002 $ pwd /home/pm1/project1 $ whoami tm2 $ ls -l -rw-r--r--. 1 pm1 project1 15 Dec 4 07 :15 file1 $ cat file1 hello from pm1 \u5bf9\u76ee\u5f55 project1 \u4e0d\u5177\u6709 w \u6743\u9650\uff0c\u6240\u4ee5\u65e0\u6cd5\u521b\u5efa\u3001\u5220\u9664\u6216\u4fee\u6539\u76ee\u5f55\u4e0b\u7684\u4efb\u4f55\u6587\u4ef6\u6216\u5b50\u76ee\u5f55\u3002 $ pwd /home/pm1/project1 $ whoami tm2 $ touch file2 touch: cannot touch 'file2' : Permission denied $ echo \"hello from $USER \" >> file1 -bash: file1: Permission denied 8.6.4.\u4fee\u6539mask\u6743\u9650 \u00b6 \u8c03\u6574 ~/project1 \u76ee\u5f55\u7684 mask \u4e3a r-- \uff0c\u5219 tm2 \u7684\u5b9e\u9645\u6743\u9650\u662f r-- $ su - pm1 $ cd ~ $ setfacl -m m::r ./project1/ $ getfacl ./project1/ # file: project1/ # owner: pm1 # group: project1 user::rwx user:tm2:r-x #effective:r-- (\u7528\u6237tm2\u7684\u5b9e\u9645\u6709\u6548\u6743\u9650\u53d8\u4e3ar--) group::rwx #effective:r-- (\u5c5e\u7ec4project1\u7ec4\u7684\u5b9e\u9645\u6709\u6548\u6743\u9650\u53d8\u4e3ar--) group:project2:rwx #effective:r-- (\u5176\u4ed6\u7ec4project2\u7ec4\u7684\u5b9e\u9645\u6709\u6548\u6743\u9650\u53d8\u4e3ar--) mask::r-- ( mask\u53d8\u5316\uff0c\u5bfc\u81f4\u4e0a\u8ff0\u4e24\u4e2agroup\u7684\u6709\u6548\u6743\u9650\u90fd\u53d1\u751f\u4e86\u53d8\u5316 ) other::--- \u6709\u6548\u6743\u9650\u7684\u8ba1\u7b97\uff1a \u5f53\u524d ~/project1 \u76ee\u5f55\u7684 mask \u662f r-- \uff0c\u7528\u6237 tm2 \u3001\u7ec4 project2 \u7684\u5b9e\u9645\u6743\u9650\u662f r-- \u3002 tm2: r - w ( 1 0 1 ) mask: r - - ( 1 0 0 ) --------------------- result: r - - ( 1 0 0 ) \u63d0\u793a\uff1a \u7528\u6237\u548c\u7528\u6237\u7ec4\u6240\u8bbe\u5b9a\u7684\u6743\u9650\u5fc5\u987b\u5728mask\u6743\u9650\u8bbe\u5b9a\u7684\u8303\u56f4\u4e4b\u5185\u624d\u80fd\u751f\u6548\uff0cmask\u6743\u9650\u5c31\u662f\u6700\u5927\u6709\u6548\u6743\u9650\u3002 8.6.5.\u6709\u6548\u6743\u9650\u5206\u6790 \u00b6 \u5728POSIX\u6743\u9650\u6a21\u578b\u548cACL\u6743\u9650\u53e0\u52a0\u4f5c\u7528\u4e0b\uff0c\u7528\u6237\u7684\u5b9e\u9645\u6743\u9650\u5206\u6790\u3002 $ getfacl ./project1/ # file: project1/ # owner: pm1 <----Owner # group: project1 <----owning group user::rwx <----owner 's permissions user:tm2:r-x #effective:r-- <----named user' s permissions group::rwx #effective:r-- <----owning group's permissions group:project2:rwx #effective:r-- <----named group's permissions mask::r-- <----masks for named user and named group other::--- default:user::rwx default:user:tm2:r-x default:group::rwx default:mask::rwx default:other::--- \u6240\u6709\u8005ower\u548c\u5176\u4ed6\u7528\u6237other\u6761\u76ee\u4e2d\u5b9a\u4e49\u7684\u6743\u9650\u603b\u662f\u6709\u6548\u7684\u3002\u4e0a\u4f8b\u4e2d\u7684user\u6761\u76ee\u548cother\u6761\u76ee\u3002 \u9664\u4e86\u63a9\u7801\u6761\u76ee\uff0c\u6240\u6709\u5176\u4ed6\u6761\u76ee\uff08\u6bd4\u5982\u6307\u5b9a\u7528\u6237named user\uff09\u53ef\u4ee5\u662f\u6709\u6548\u7684\u6216\u88ab\u5c4f\u853d\u7684\u3002 \u6307\u5b9a\u7528\u6237\uff08named user\uff09\uff0c\u6240\u6709\u8005\u7ec4\uff08owning group\uff09\u6216\u6307\u5b9a\u7ec4\uff08named group\uff09\u4ee5\u53ca\u63a9\u7801mask\u6761\u76ee\u4e2d\u5b9a\u4e49\u7684\u6743\u9650\uff0c\u6709\u6548\u6743\u9650\u662f\u4ed6\u4eec\u6743\u9650\u8fdb\u884c\u903b\u8f91AND\u540e\u7684\u7ed3\u679c\uff0c\u800c\u4e0d\u662f\u5355\u72ec\u7684\u63a9\u7801\u4e2d\u5b9a\u4e49\u7684\u6743\u9650\u6216\u8005\u5404\u81ea\u6761\u76ee\u4e2d\u5b9a\u4e49\u7684\u6743\u3002 \u6709\u6548\u6743\u9650\u8ba1\u7b97\u65b9\u6cd5\u5982\u4e0b\uff0c\u6ce8\u610f\uff0c ls \u547d\u4ee4\u4e2d\u663e\u793a\u51fa\u6765\u7684\u6743\u9650\uff0c\u4e0e\u5b9e\u9645\u7684ACL\u6743\u9650\u662f\u6709\u5dee\u522b\u7684\u3002 tm2: r - w ( 1 0 1 ) group: r w x ( 1 1 1 ) named group: r w x ( 1 1 1 ) mask: r - - ( 1 0 0 ) --------------------------- result: r - - ( 1 0 0 ) \u5c0f\u8d34\u58eb\uff1a \u4e0e\u6587\u4ef6\u6a21\u5f0f\u6743\u9650\u4f4d\u7b49\u6548\u7684ACL\u79f0\u4e3a\u6700\u5c0fACL\uff0c\u5373POSIX\u4f20\u7edf\u6743\u9650\u3002 \u542b\u63a9\u7801mask\u7b49\u5176\u4ed6\u6743\u9650\u6761\u76ee\u7684ACL\u79f0\u4e3a\u6269\u5c55ACL\u3002 \u5728\u6700\u5c0f\u548c\u6269\u5c55ACL\u60c5\u5f62\u4e0b\uff0c\u6240\u6709\u8005\u7c7b\u6743\u9650\uff08owner\uff09\u90fd\u662f\u6620\u5c04\u5230ACL\u7684\u6240\u6709\u8005\u6761\u76ee\u3002 \u5176\u4ed6\u7c7b\u6743\u9650\u6620\u5c04\u5230\u5176\u5404\u81ea\u7684ACL\u6761\u76ee\u3002 \u5728\u6269\u5c55ACL\u60c5\u5f62\u4e0b\uff0c\u7ec4\u7c7b\u6743\u9650\u7684\u6620\u5c04\u662f\u4e0d\u540c\u7684\u3002 \u5bf9\u4e8e\u6ca1\u6709\u63a9\u7801\u7684\u6700\u5c0fACL\uff0c\u7ec4\u7c7b\u6743\u9650\u5c06\u6620\u5c04\u5230ACL\u6240\u6709\u8005\u7ec4\u6761\u76ee\u3002 \u5bf9\u4e8e\u5e26\u6709\u63a9\u7801\u7684\u6269\u5c55ACL\uff0c\u7ec4\u7c7b\u6743\u9650\u5c06\u6620\u5c04\u5230\u63a9\u7801\u6761\u76ee\u3002 \u901a\u8fc7\u6743\u9650\u4f4d\u8fdb\u884c\u5206\u914d\u7684\u6743\u9650\u4ee3\u8868\u4e86\u901a\u8fc7ACL\u8fdb\u884c\u5206\u914d\u7684\u6743\u9650\u7684\u4e0a\u9650\u3002 \u6ca1\u6709\u5728\u8fd9\u91cc\u4f53\u73b0\u7684\u4efb\u4f55\u6743\u9650\uff0c\u8981\u4e48\u4e0d\u5728ACL\u4e2d\uff0c\u8981\u4e48\u65e0\u6548\u3002 \u5bf9\u6743\u9650\u4f4d\u6240\u505a\u7684\u66f4\u6539\u5c06\u7531ACL\u53cd\u6620\uff0c\u53cd\u4e4b\u4ea6\u7136\u3002 8.6.6.\u9ed8\u8ba4ACL\u6743\u9650 \u00b6 $ su - pm1 $ touch ./project1/file2 $ mkdir ./project1/cloud $ ll ./project1/ drwxr-xr-x. 1 pm1 project1 0 Dec 4 08 :52 cloud -rw-r--r--. 1 pm1 project1 15 Dec 4 07 :15 file1 -rw-r--r--. 1 pm1 project1 0 Dec 4 08 :52 file2 $ ll -d project1/ drwxr-----+ 1 pm1 project1 30 Dec 4 08 :52 project1/ \u6587\u4ef6 file1 \u548c\u76ee\u5f55 cloud \u6ca1\u6709\u7ee7\u627f project1 \u76ee\u5f55\u7684ACL\u6743\u9650\u3002 \u63d0\u793a\uff1a \u9ed8\u8ba4 ACL\u9650\u53ea\u5bf9\u76ee\u5f55\u751f\u6548\u3002 \u9ed8\u8ba4ACL\u6743\u9650\u7684\u4f5c\u7528\u662f\uff1a\u5982\u679c\u7ed9\u7236\u76ee\u5f55\u8bbe\u5b9a\u4e86\u9ed8\u8ba4 ACL \u6743\u9650\uff0c\u90a3\u4e48\u7236\u76ee\u5f55\u4e2d\u6240\u6709\u65b0\u5efa\u7684\u5b50\u6587\u4ef6\u90fd\u4f1a\u7ee7\u627f\u7236\u76ee\u5f55\u7684ACL\u6743\u9650\u3002 \u4e0b\u9762\u589e\u52a0 ~/project1 \u76ee\u5f55\u7684\u9ed8\u8ba4ACL\u6743\u9650\u3002 $ su - pm1 $ cd ~ $ getfacl ./project1/ # file: project1/ # owner: pm1 # group: project1 user::rwx user:tm2:r-x #effective:r-- group::rwx #effective:r-- group:project2:rwx #effective:r-- mask::r-- other::--- $ setfacl -m d:u:tm2:rx ./project1/ $ getfacl ./project1/ # file: project1/ # owner: pm1 # group: project1 user::rwx user:tm2:r-x #effective:r-- group::rwx #effective:r-- group:project2:rwx #effective:r-- mask::r-- other::--- default:user::rwx default:user:tm2:r-x default:group::rwx default:mask::rwx default:other::--- \u521b\u5efa\u65b0\u5b50\u76ee\u5f55 leonardo \uff0c\u5c31\u7ee7\u627f\u4e86 ~/project1 \u76ee\u5f55\u7684default ACL\u6743\u9650\u8bbe\u5b9a\u3002 \u6ce8\u610f\uff0c\u9ed8\u8ba4ACL\u6743\u9650\u662f\u9488\u5bf9\u65b0\u5efa\u7acb\u7684\u6587\u4ef6\u751f\u6548\u7684\uff0c\u76ee\u5f55cloud\u548c\u6587\u4ef6file1\u5e76\u6ca1\u6709\u56e0\u4e3a\u589e\u52a0\u4e86\u7236\u76ee\u5f55\u7684\u9ed8\u8ba4ACL\u8bbe\u5b9a\u800c\u7ee7\u627f\u9ed8\u8ba4ACL\u6743\u9650\u8bbe\u5b9a. $ su - pm1 $ cd ~ $ mkdir ./project1/leonardo $ ll ./project1/ drwxr-xr-x. 1 pm1 project1 0 Dec 4 08 :52 cloud -rw-r--r--. 1 pm1 project1 15 Dec 4 07 :15 file1 -rw-r--r--. 1 pm1 project1 0 Dec 4 08 :52 file2 drwxrwx---+ 1 pm1 project1 0 Dec 4 09 :07 leonardo 8.6.7.\u9012\u5f52ACL\u6743\u9650 \u00b6 \u9012\u5f52 ACL \u6743\u9650\uff0c\u662f\u6307\u7236\u76ee\u5f55\u5728\u8bbe\u5b9aACL\u6743\u9650\u65f6\uff0c\u6240\u6709\u7684\u5b50\u76ee\u5f55\u4e5f\u4f1a\u62e5\u6709\u76f8\u540c\u7684ACL\u6743\u9650\u3002 $ su - pm1 $ cd ~ $ getfacl ./project1/ # file: project1/ # owner: pm1 # group: project1 user::rwx user:tm2:r-x #effective:r-- group::rwx #effective:r-- group:project2:rwx #effective:r-- mask::r-- other::--- default:user::rwx default:user:tm2:r-x default:group::rwx default:mask::rwx default:other::--- $ setfacl -m d:u:tm2:rx -R ./project1/ $ ll ./project1 drwxr-xr-x+ 1 pm1 project1 0 Dec 4 08 :52 cloud -rw-r--r--. 1 pm1 project1 15 Dec 4 07 :15 file1 -rw-r--r--. 1 pm1 project1 0 Dec 4 08 :52 file2 drwxrwx---+ 1 pm1 project1 0 Dec 4 09 :07 leonardo 8.6.8.\u5220\u9664ACL\u6743\u9650 \u00b6 \u5220\u9664\u7528\u6237 tm2 \u7684ACL\u6743\u9650\u3002 $ su - pm1 $ cd ~ $ setfacl -x u:tm2 ./project1/ $ getfacl ./project1/ # file: project1/ # owner: pm1 # group: project1 user::rwx group::rwx group:project2:rwx mask::rwx other::--- default:user::rwx default:user:tm2:r-x default:group::rwx default:mask::rwx default:other::--- \u5220\u9664\u6240\u6709\u7684ACL\u6743\u9650\u3002 $ setfacl -b ./project1 $ getfacl ./project1 # file: project1/ # owner: pm1 # group: project1 user::rwx group::rwx other::--- $ ll ./project1 drwxr-xr-x+ 1 pm1 project1 0 Dec 4 08 :52 cloud -rw-r--r--. 1 pm1 project1 15 Dec 4 07 :15 file1 -rw-r--r--. 1 pm1 project1 0 Dec 4 08 :52 file2 drwxrwx---+ 1 pm1 project1 0 Dec 4 09 :07 leonardo \u9012\u5f52\u5220\u9664\u5168\u90e8ACL\u6743\u9650\u3002 $ setfacl -b -R ./project1 $ ll ./project1/ total 4 drwxr-xr-x. 1 pm1 project1 0 Dec 4 08 :52 cloud -rw-r--r--. 1 pm1 project1 15 Dec 4 07 :15 file1 -rw-r--r--. 1 pm1 project1 0 Dec 4 08 :52 file2 drwxrwx---. 1 pm1 project1 0 Dec 4 09 :07 leonardo 8.7.ACL\u76ee\u5f55\u5b9e\u4f8b\u89e3\u6790 \u00b6 8.7.1.\u76ee\u5f55ACL \u00b6 \u5207\u6362\u5230pm1\u7528\u6237\uff0c\u5728\u5176\u4e3b\u76ee\u5f55\u4e2d\uff0c\u57fa\u4e8e\u4e0d\u540c\u7684\u63a9\u7801\u521b\u5efa2\u4e2a\u5b50\u76ee\u5f55\u3002 $ su - pm1 $ umask 0022 $ mkdir mydir1 $ umask 0027 $ mkdir mydir2 $ ll -d mydir* drwxr-xr-x. 1 pm1 project1 0 Dec 4 12 :30 mydir1 drwxr-x---. 1 pm1 project1 0 Dec 4 12 :31 mydir2 \u8fd92\u4e2a\u76ee\u5f55\u5f53\u524d\u7684ACL\u72b6\u6001\u5982\u4e0b\uff1a $ getfacl mydir1 # file: mydir1 # owner: pm1 # group: project1 user::rwx group::r-x other::r-x $ getfacl mydir2 # file: mydir2 # owner: pm1 # group: project1 user::rwx group::r-x other::--- \u4fee\u6539\u76ee\u5f55 mydir2 \u7684ACL\u3002 $ setfacl -m u:tm2:rwx,g:project2:rwx mydir2 $ getfacl mydir2 getfacl mydir2 # file: mydir2 # owner: pm1 # group: project1 user::rwx user:tm2:rwx group::r-x group:project2:rwx mask::rwx other::--- $ ll -d mydir2 drwxrwx---+ 1 pm1 project1 0 Dec 4 12 :31 mydir2 \u73b0\u5728\uff0c\u7528\u6237 tm2 \u548c\u7ec4 project2 \u5bf9\u76ee\u5f55 mydir2 \u90fd\u5177\u6709rwx\u6743\u9650\uff0c\u4f20\u7edfPOSIX\u6743\u9650\u548cACL\u6743\u9650\u4e00\u81f4\u3002 \u73b0\u5728\u5bf9mydir2\u76ee\u5f55\u7ec4\u6743\u9650\u64a4\u9500w\u6743\u9650\u3002 \u7528\u6237 tm2 \u548c\u7ec4 project2 \u5bf9\u76ee\u5f55 mydir2 \u7684\u6709\u6548\u6743\u9650\u53d8\u6210\u4e86 r-x \u3002 mask\u4e5f\u53d7\u7ec4\u6743\u9650\u53d8\u5316\u5f71\u54cd\uff0c\u53d8\u6210\u4e86 r-x \u3002 $ chmod g-w mydir2 $ ll -d mydir2 drwxr-x---+ 1 pm1 project1 0 Dec 4 12 :31 mydir2 $ getfacl mydir2 # file: mydir2 # owner: pm1 # group: project1 user::rwx user:tm2:rwx #effective:r-x group::r-x group:project2:rwx #effective:r-x mask::r-x other::--- \u901a\u8fc7 chmod \u548c setfacl \u4e24\u79cd\u4e0d\u540c\u7684\u65b9\u6cd5\u5bf9\u76ee\u5f55 mydir2 \u7684\u7ec4\u6743\u9650\u8fdb\u884c\u4fee\u6539\uff0c\u5728ls\u547d\u4ee4\u4e2d\u4f53\u73b0\u662f\u4e00\u6837\u7684\uff0c\u5bf9\u7ec4\u7684\u5b9e\u9645\u6709\u6548\u6743\u9650\u7684\u5f71\u54cd\u4e5f\u662f\u4e00\u6837\u7684\u3002 chmod \u4fee\u6539\u7684\u662f mask \uff0c mask \u53ea\u5f71\u54cd\u9664\u6240\u6709\u8005\u548cother\u7684\u4e4b\u5916\u7684\u4eba\u548c\u7ec4\u7684\u6700\u5927\u6743\u9650\uff0c mask \u9700\u8981\u4e0e\u7528\u6237\u7684\u6743\u9650\u8fdb\u884c\u903b\u8f91\u4e0e\u8fd0\u7b97\u540e\uff0c\u624d\u80fd\u53d8\u6210\u6709\u6548\u6743\u9650\uff0c\u7528\u6237\u6216\u7ec4\u7684\u8bbe\u7f6e\u5fc5\u987b\u5728mask\u6743\u9650\u8bbe\u5b9a\u8303\u56f4\u5185\u624d\u4f1a\u751f\u6548\u3002 setfacl \u53ef\u4ee5\u4e0d\u4fee\u6539mask\u7684\u60c5\u51b5\u4e0b\u53ea\u4fee\u6539 owning group \u7684\u6743\u9650\uff0c\u4e0b\u9762\u7684\u4f8b\u5b50\u8bf4\u660e\u4e86\u8fd9\u4e00\u60c5\u51b5\u3002POSIX\u7ec4\u6743\u9650\u4ecd\u7136\u662f rwx \uff0c\u4f46ACL\u4e2d\u6240\u6709\u8005\u7ec4\u7684\u6743\u9650\u53d8\u6210\u4e86 r-- \u3002 $ setfacl -m g::r mydir2 $ ll -d mydir2 drwxrwx---+ 1 pm1 project1 0 Dec 4 12 :31 mydir2 $ getfacl mydir2 # file: mydir2 # owner: pm1 # group: project1 user::rwx user:tm2:rwx group::r-- group:project2:rwx mask::rwx other::--- 8.7.2.\u76ee\u5f55\u7684\u9ed8\u8ba4ACL \u00b6 \u76ee\u5f55\u53ef\u4ee5\u5177\u6709\u9ed8\u8ba4ACL\uff0c\u8fd9\u662f\u4e00\u79cd\u7279\u6b8a\u7684ACL\uff0c\u7528\u4e8e\u5b9a\u4e49\u76ee\u5f55\u4e0b\u7684\u5bf9\u8c61\u5728\u521b\u5efa\u65f6\u7ee7\u627f\u7684\u8bbf\u95ee\u6743\u9650\u3002\u9ed8\u8ba4ACL\u4f1a\u5f71\u54cd\u5b50\u76ee\u5f55\u548c\u6587\u4ef6\u3002 \u76ee\u5f55\u7684\u9ed8\u8ba4ACL\u7684\u6743\u9650\u6709\u4e24\u79cd\u4e0d\u540c\u7684\u65b9\u5f0f\u4f20\u9012\u7ed9\u5176\u4e2d\u7684\u6587\u4ef6\u548c\u5b50\u76ee\u5f55\uff1a \u5b50\u76ee\u5f55\u7ee7\u627f\u7236\u76ee\u5f55\u7684\u9ed8\u8ba4ACL\uff0c\u65e2\u4f5c\u4e3a\u81ea\u5df1\u7684\u9ed8\u8ba4ACL\uff0c\u53c8\u4f5c\u4e3a\u81ea\u5df1\u7684\u8bbf\u95eeACL\u3002 \u6587\u4ef6\u7ee7\u627f\u76ee\u5f55\u9ed8\u8ba4ACL\u4f5c\u4e3a\u5176\u81ea\u5df1\u7684\u8bbf\u95eeACL\u3002 \u521b\u5efa\u6587\u4ef6\u7cfb\u7edf\u5bf9\u8c61\u7684\u6240\u6709\u7cfb\u7edf\u51fd\u6570\u90fd\u4f7f\u7528mode\u53c2\u6570\uff0c\u8be5\u53c2\u6570\u5b9a\u4e49\u4e86\u65b0\u521b\u5efa\u7684\u6587\u4ef6\u7cfb\u7edf\u5bf9\u8c61\u7684\u8bbf\u95ee\u6743\u9650\u3002 \u5982\u679c\u7236\u76ee\u5f55\u6ca1\u6709\u9ed8\u8ba4ACL\uff0c\u5219\u6839\u636eumask\u7684\u8bbe\u7f6e\u8bbe\u7f6e\u6743\u9650\u4f4d\u3002 \u5982\u679c\u7236\u76ee\u5f55\u5b58\u5728\u9ed8\u8ba4ACL\uff0c\u5219\u5206\u914d\u7ed9\u65b0\u5bf9\u8c61\u7684\u6743\u9650\u4f4d\u5219\u662fmode\u53c2\u6570\u6743\u9650\u4e0e\u9ed8\u8ba4ACL\u4e2d\u5b9a\u4e49\u7684\u6743\u9650\u7684\u903b\u8f91\u4e0e\u7684\u7ed3\u679c\u3002\u5728\u8fd9\u79cd\u60c5\u51b5\u4e0b\uff0c\u5ffd\u7565umask\u547d\u4ee4\u3002 \u9ed8\u8ba4ACL\u4e0d\u4f1a\u7acb\u5373\u5f71\u54cd\u8bbf\u95ee\u6743\u9650\u3002\u5b83\u4eec\u4ec5\u5728\u521b\u5efa\u6587\u4ef6\u7cfb\u7edf\u5bf9\u8c61\u65f6\u624d\u8d77\u4f5c\u7528\u3002\u8fd9\u4e9b\u65b0\u5bf9\u8c61\u4ec5\u4ece\u5176\u7236\u76ee\u5f55\u7684\u9ed8\u8ba4ACL\u7ee7\u627f\u6743\u9650\u3002 \u547d\u4ee4 mkdir \u5728\u521b\u5efa\u76ee\u5f55\u65f6\u4f1a\u7ee7\u627f\u9ed8\u8ba4ACL\u3002 $ su - pm1 $ getfacl mydir2 # file: mydir2 # owner: pm1 # group: project1 user::rwx user:tm2:rwx group::r-- group:project2:rwx mask::rwx other::--- $ mkdir ./mydir2/sub1 $ ll ./mydir2 drwxr-x---. 1 pm1 project1 0 Dec 4 13 :23 sub1 $ setfacl -d -m g:project2:-w- mydir2 $ mkdir ./mydir2/sub2 $ ll ./mydir2 drwxr-x---. 1 pm1 project1 0 Dec 4 13 :23 sub1 drwxrw----+ 1 pm1 project1 0 Dec 4 13 :27 sub2 $ getfacl ./mydir2/sub2 # file: mydir2/sub2 # owner: pm1 # group: project1 user::rwx group::r-- group:project2:-w- mask::rw- other::--- default:user::rwx default:group::r-- default:group:project2:-w- default:mask::rw- default:other::--- \u5728\u5bf9 mydir2 \u76ee\u5f55\u6dfb\u52a0\u9ed8\u8ba4ACL\u524d\uff0c\u521b\u5efa\u5b50\u76ee\u5f55 sub1 \uff0c\u6dfb\u52a0\u540e\u521b\u5efa\u5b50\u76ee\u5f55 sub2 \u3002\u53ef\u4ee5\u89c2\u5bdf\u5230 sub2 \u5230\u7ee7\u627f\u4e86 mydir2 \u7684\u9ed8\u8ba4ACL\u3002 $ su - tm2 $ cd /home/pm1/mydir2/sub2 -bash: cd: /home/pm1/mydir2/sub2: Permission denied \u4e0a\u4f8b\u4e2d\uff0c\u9ed8\u8ba4ACL\u4e2d\u6307\u5b9a\u7ec4 project2 \u53ea\u5177\u6709w\u6743\u9650\uff0c\u6240\u4ee5\u65e0\u6cd5\u6267\u884c cd \u547d\u4ee4\u8fdb\u5165\u8be5\u76ee\u5f55\u3002 \u8fd9\u8bf4\u660e\u6a21\u5f0f\u503cmode\u4e2d\u7ed9\u4e88\u7684\u6743\u9650 r \u88ab\u5c4f\u853d\u4e86\uff0c\u53ea\u4fdd\u7559\u4e86ACL\u4e2d\u6700\u5c0f\u7684\u6743\u9650 w \u3002 8.8.ACL\u68c0\u67e5\u903b\u8f91 \u00b6 ACL\u68c0\u67e5\u987a\u5e8f\uff1a Owner Named user Owning group Named group Other If \u8fdb\u7a0b\u7684\u7528\u6237\u6807\u8bc6\u662fOwner\uff0c\u5219owner\u7684ACL\u6761\u76ee\u51b3\u5b9a\u8bbf\u95ee\u6743\u9650 else if \u8fdb\u7a0b\u7684\u7528\u6237\u6807\u8bc6\u662fnamed user\uff0c\u5219name user\u7684ACL\u6761\u76ee\u7684\u6743\u9650\u51b3\u5b9a\u7533\u8bf7\u7684\u8bbf\u95ee\u6743\u9650 else if \u8fdb\u7a0b\u7684\u7ec4\u5c5e\u4e8eowning group\uff0c\u4e14owning group\u7684ACL\u6761\u76ee\u5305\u542b\u6240\u8bf7\u6c42\u7684\u8bbf\u95ee\u6743\u9650\uff0c\u5219\u6388\u4e88\u6240\u8bf7\u6c42\u7684\u6743\u9650 else if \u8fdb\u7a0b\u7684\u7ec4\u5c5e\u4e8enamed group\uff0c\u4e14named group\u7684ACL\u6761\u76ee\u5305\u542b\u6240\u8bf7\u6c42\u7684\u8bbf\u95ee\u6743\u9650\uff0c\u5219\u6388\u4e88\u6240\u8bf7\u6c42\u7684\u6743\u9650 else if \u8fdb\u7a0b\u7684\u7ec4\u5c5e\u4e8eowning group\u6216\u8005named group\uff0c\u4f46owning group\u6216\u8005named group\u7684ACL\u6761\u76ee\u4e0d\u5305\u542b\u6240\u8bf7\u6c42\u7684\u8bbf\u95ee\u6743\u9650\uff0c\u5219\u62d2\u7edd\u6240\u8bf7\u6c42\u7684\u6743\u9650 else ACL\u4e2d\u7684other\u6761\u76ee\u5904\u7406\u7533\u8bf7\u7684\u6743\u9650 If \u5982\u679c\u8fdb\u7a0b\u5339\u914d\u5230owner\u6216\u8005other\u6761\u76ee\u4e2d\u5305\u542b\u6240\u7533\u8bf7\u7684\u6743\u9650\uff0c\u5219\u6388\u4e88\u6743\u9650 else if \u5982\u679c\u8fdb\u7a0b\u5339\u914d\u5230named user\uff0cowning group\uff0c\u6216\u8005named group\u6761\u76ee\u4e2d\u5305\u542b\u6240\u7533\u8bf7\u7684\u6743\u9650\uff0c\u4e14maks\u6761\u76ee\u4e5f\u5305\u542b\u6240\u7533\u8bf7\u7684\u6743\u9650\uff0c\u5219\u6388\u4e88\u6743\u9650 else \u62d2\u7edd\u6743\u9650\u7533\u8bf7 \u5b9e\u9645\u5e94\u7528\u4e3e\u4f8b\uff1a udev\u4f7f\u7528ACL\u7ed9\u4e88\u767b\u5f55\u5230\u56fe\u5f62\u754c\u9762\u7684\u7528\u6237\u8bbf\u95ee\u8bbe\u5907\u7684\u6743\u9650\uff0c\u4f8b\u5982DVD\u9a71\u52a8\u5668 \u67d0\u4e9b\u5e94\u7528\u7a0b\u5e8f\u4e0d\u652f\u6301ACL Star Archiver\u662f\u4e00\u4e2a\u5b8c\u5168\u4fdd\u7559ACL\u7684\u5907\u4efd\u5e94\u7528\u7a0b\u5e8f\uff0c\u5176\u4ed6\u4eba\u53ef\u80fd\u4f1a\u4e5f\u53ef\u80fd\u4e0d\u4f1a\u4fdd\u7559\u5b83 \u8bb8\u591a\u7f16\u8f91\u5668\u548c\u6587\u4ef6\u7ba1\u7406\u5668\u4e0d\u5141\u8bb8\u5728\u5e94\u7528\u7a0b\u5e8f\u4e2d\u67e5\u770b\u6216\u8bbe\u7f6eACL","title":"\u7b2c\u4e09\u7ae0 \u8eab\u4efd\u4e0e\u5b89\u5168"},{"location":"linux/SRE/03-identity-security/#_1","text":"","title":"\u7b2c\u4e09\u7ae0 \u8eab\u4efd\u4e0e\u5b89\u5168"},{"location":"linux/SRE/03-identity-security/#1","text":"\u7528\u6237\u548c\u7ec4 \u7528\u6237user\u548c\u7ec4group\u5728Linux\u7cfb\u7edf\u4e2d\u4ee5\u6570\u5b57\u5f62\u5f0f\u8fdb\u884c\u7ba1\u7406\u3002 \u7528\u6237\u88ab\u5206\u914d\u7684\u53f7\u7801\u79f0\u4e3a\u7528\u6237ID\uff08UID\uff09\u3002 \u6bcf\u4e2aLinux\u7cfb\u7edf\u90fd\u6709\u4e00\u4e2a\u7279\u6743\u7528\u6237\uff0c\u5373 root \u7528\u6237\u3002 root \u662f\u7cfb\u7edf\u7ba1\u7406\u5458\u3002 \u6b64\u7528\u6237\u7684UID\u59cb\u7ec8\u4e3a0\u3002 \u666e\u901a\u7528\u6237\u7684UID\u7f16\u53f7\uff08\u9ed8\u8ba4\u60c5\u51b5\u4e0b\uff09\u4e3a1000\u3002 \u6bcf\u4e2a\u7ec4\u4e5f\u5206\u914d\u4e86\u4e00\u4e2a\u79f0\u4e3a\u7ec4ID\uff08GID\uff09\u7684\u7f16\u53f7\u3002 \u6bcf\u4e2a\u7528\u6237\u6709\u4e00\u4e2a\u4e3b\u8981\u7ec4\uff08primary group\uff09\uff0c\u6709\u96f6\u4e2a\u6216\u8005\u4efb\u610f\u4e2a\u9644\u52a0\u7ec4\uff08supplementary group\uff09\u3002 \u4ee5openSUSE\u4e3a\u4f8b\uff1a UID 0: root 1 \u2013 99: System 100 \u2013 499: System accounts \u2265 1000: Normal (unprivileged) accounts GID 0: root 1 \u2013 99: System Groups 100 \u2013 499: Dynamically Allocated System Groups \u2265 1000: Normal Groups \u4e3e\u4f8b\uff1a $ id postfix uid = 51 ( postfix ) gid = 51 ( postfix ) groups = 482 ( mail ) ,59 ( maildrop ) ,51 ( postfix ) $ id vagrant uid = 1000 ( vagrant ) gid = 478 ( wheel ) groups = 0 ( root ) ,478 ( wheel ) \u63d0\u793a\uff1a UID\u548cGID\u7b49\u7f16\u53f7\u89c4\u5219\uff0c\u662f\u5728\u6587\u4ef6 /etc/login.defs \u4e2d\u7ea6\u5b9a\u7684\u3002","title":"1.\u7528\u6237\u3001\u7ec4\u3001\u6743\u9650"},{"location":"linux/SRE/03-identity-security/#2selinux","text":"Security-Enhanced Linux (SELinux) \u662f\u4e00\u79cdLinux\u7cfb\u7edf\u7684\u5b89\u5168\u67b6\u6784\uff0c\u5b83\u5141\u8bb8\u7ba1\u7406\u5458\u66f4\u597d\u5730\u63a7\u5236\u8c01\u53ef\u4ee5\u8bbf\u95ee\u7cfb\u7edf\u3002 SELinux\u4e8e2000\u5e74\u5411\u5f00\u6e90\u793e\u533a\u53d1\u5e03\uff0c\u5e76\u4e8e2003\u5e74\u96c6\u6210\u5230\u4e0a\u6e38 Linux \u5185\u6838\u4e2d\u3002 SELinux\u4e3a\u7cfb\u7edf\u4e0a\u7684\u5e94\u7528\u7a0b\u5e8f\u3001\u8fdb\u7a0b\u548c\u6587\u4ef6\u5b9a\u4e49\u4e86\u8bbf\u95ee\u63a7\u5236\u3002 \u5b83\u4f7f\u7528\u5b89\u5168\u7b56\u7565\uff08\u4e00\u7ec4\u89c4\u5219\u544a\u8bc9SELinux\u4ec0\u4e48\u53ef\u4ee5\u8bbf\u95ee\u6216\u4e0d\u53ef\u4ee5\u8bbf\u95ee\uff09\u6765\u5f3a\u5236\u6267\u884c\u7b56\u7565\u5141\u8bb8\u7684\u8bbf\u95ee\u3002 \u5f53\u79f0\u4e3a\u4e3b\u4f53\uff08subject\uff09\u7684\u5e94\u7528\u7a0b\u5e8f\u6216\u8fdb\u7a0b\u8bf7\u6c42\u8bbf\u95ee\u5bf9\u8c61\uff08\u5982\u6587\u4ef6\uff09\u65f6\uff0cSELinux\u4f1a\u68c0\u67e5\u8bbf\u95ee\u5411\u91cf\u7f13\u5b58(AVC, Access Vector Cache)\uff0c\u5176\u4e2d\u7f13\u5b58\u4e86\u4e3b\u4f53\u548c\u5bf9\u8c61\u7684\u6743\u9650\u3002 \u5982\u679cSELinux\u65e0\u6cd5\u6839\u636e\u7f13\u5b58\u7684\u6743\u9650\u505a\u51fa\u8bbf\u95ee\u51b3\u5b9a\uff0c\u5b83\u4f1a\u5c06\u8bf7\u6c42\u53d1\u9001\u5230\u5b89\u5168\u670d\u52a1\u5668\u3002 \u5b89\u5168\u670d\u52a1\u5668\u68c0\u67e5\u5e94\u7528\u7a0b\u5e8f\u6216\u8fdb\u7a0b\u548c\u6587\u4ef6\u7684\u5b89\u5168\u4e0a\u4e0b\u6587\u3002 \u4eceSELinux\u7b56\u7565\u6570\u636e\u5e93\u5e94\u7528\u5b89\u5168\u4e0a\u4e0b\u6587\uff08Security context\uff09\uff0c\u7136\u540e\u6388\u4e88\u6216\u62d2\u7edd\u8bb8\u53ef\u3002 \u5982\u679c\u6743\u9650\u88ab\u62d2\u7edd\uff0c avc: denied \u6d88\u606f\u5c06\u5728 /var/log.messages \u4e2d\u4f53\u73b0\u3002 \u4f20\u7edf\u4e0a\uff0cLinux\u548cUNIX\u7cfb\u7edf\u90fd\u4f7f\u7528DAC\uff08Discretionary Access Control\uff09\u3002 SELinux\u662fLinux\u7684MAC\uff08Mandatory Access Control\uff09\u7cfb\u7edf\u7684\u4e00\u4e2a\u793a\u4f8b\u3002 \u5728DAC\u65b9\u5f0f\u4e0b\uff0c\u6587\u4ef6\u548c\u8fdb\u7a0b\u6709\u81ea\u5df1\u7684\u5c5e\u4e3b\uff08\u6240\u6709\u8005\uff09\u3002 \u7528\u6237\u53ef\u4ee5\u62e5\u6709\u4e00\u4e2a\u6587\u4ef6\uff0c\u4e00\u4e2a\u7ec4\u4e5f\u53ef\u4ee5\u62e5\u6709\u4e00\u4e2a\u6587\u4ef6\uff0c\u6216\u8005\u5176\u4ed6\u4eba\u3002 \u7528\u6237\u53ef\u4ee5\u66f4\u6539\u81ea\u5df1\u6587\u4ef6\u7684\u6743\u9650\u3002 root \u7528\u6237\u5bf9DAC\u7cfb\u7edf\u5177\u6709\u5b8c\u5168\u8bbf\u95ee\u63a7\u5236\u6743\u3002 \u4f46\u662f\u5728\u50cfSELinux\u8fd9\u6837\u7684MAC\u7cfb\u7edf\u4e0a\uff0c\u5bf9\u4e8e\u8bbf\u95ee\u7684\u7ba1\u7406\u662f\u901a\u8fc7\u8bbe\u7f6e\u7b56\u7565\u6765\u5b9e\u73b0\u7684\u3002\u5373\u4f7f\u7528\u6237\u4e3b\u76ee\u5f55\u4e0a\u7684DAC\u8bbe\u7f6e\u53d1\u751f\u66f4\u6539\uff0c\u7528\u4e8e\u9632\u6b62\u5176\u4ed6\u7528\u6237\u6216\u8fdb\u7a0b\u8bbf\u95ee\u8be5\u76ee\u5f55\u7684SELinux\u7b56\u7565\u4e5f\u5c06\u7ee7\u7eed\u786e\u4fdd\u7cfb\u7edf\u5b89\u5168\u3002 MAC\u65b9\u5f0f\u662f\u63a7\u5236\u4e00\u4e2a\u8fdb\u7a0b\u5bf9\u5177\u4f53\u6587\u4ef6\u7cfb\u7edf\u4e0a\u9762\u7684\u6587\u4ef6\u6216\u76ee\u5f55\u662f\u5426\u62e5\u6709\u8bbf\u95ee\u6743\u9650\u3002\u5224\u65ad\u8fdb\u7a0b\u662f\u5426\u53ef\u4ee5\u8bbf\u95ee\u6587\u4ef6\u6216\u76ee\u5f55\u7684\u4f9d\u636e\uff0c\u53d6\u51b3\u4e8eSELinux\u4e2d\u8bbe\u5b9a\u7684\u5f88\u591a\u7b56\u7565\u89c4\u5219\u3002 \u8bbf\u95ee\u63a7\u5236\u5217\u8868 (ACL\uff0cAccess Control List) \u4e3a\u6587\u4ef6\u7cfb\u7edf\u63d0\u4f9b\u4e86\u4e00\u79cd\u989d\u5916\u7684\u3001\u66f4\u7075\u6d3b\u7684\u6743\u9650\u673a\u5236\u3002 \u5b83\u65e8\u5728\u534f\u52a9 UNIX \u6587\u4ef6\u6743\u9650\u3002ACL\u5141\u8bb8\u6388\u4e88\u4efb\u4f55\u7528\u6237\u6216\u7ec4\u5bf9\u4efb\u4f55\u78c1\u76d8\u8d44\u6e90\u7684\u6743\u9650\u3002ACL\u9002\u7528\u4e8e\u5728\u4e0d\u4f7f\u67d0\u4e2a\u7528\u6237\u6210\u4e3a\u7ec4\u6210\u5458\u7684\u60c5\u51b5\u4e0b\uff0c\u4ecd\u65e7\u6388\u4e88\u4e00\u4e9b\u8bfb\u6216\u5199\u8bbf\u95ee\u6743\u9650\u3002 \u4e0b\u9762\u793a\u4f8b\u5bf9\u6bd4\u8bf4\u660e\u4e86SELinux\u548cACL\u5728\u6587\u4ef6\u5c5e\u6027\u5c55\u73b0\u4e0a\u7684\u7279\u70b9\u3002 -rwxr-xr-- vagrant wheel \uff1a\u6ca1\u6709selinux\u4e0a\u4e0b\u6587\uff0c\u6ca1\u6709ACL -rwx--xr-x+ vagrant wheel \uff1a\u53ea\u6709ACL\uff0c\u6ca1\u6709selinux\u4e0a\u4e0b\u6587 -rw-r--r--. vagrant wheel \uff1a\u53ea\u6709selinux\u4e0a\u4e0b\u6587\uff0c\u6ca1\u6709ACL -rwxrwxr--+ vagrant wheel \uff1a\u6709selinux\u4e0a\u4e0b\u6587\uff0c\u6709ACL","title":"2.SELinux"},{"location":"linux/SRE/03-identity-security/#21selinux","text":"\u7528\u6237(Users)\uff1a SELinux\u7684\u7528\u6237\u4e0d\u7b49\u540c\u4e0eLinux\u7528\u6237\u3002 SELinux\u7528\u6237\u4ee5\u540e\u7f00 _u \u7ed3\u5c3e\u3002 \u89d2\u8272(Roles)\uff1a \u89d2\u8272Roles\u662f\u7531\u7b56\u7565Policies\u5b9a\u4e49\u7684\uff0c\u89d2\u8272\u51b3\u5b9a\u4e86\u4f7f\u7528\u54ea\u4e2a\u7b56\u7565\u3002 SELinux\u89d2\u8272\u4ee5\u540e\u7f00 _r \u7ed3\u5c3e\u3002 \u7c7b\u578b(Types)\uff1a SELinux\u662f\u7c7b\u578b\u5f3a\u5236\u7684\uff0c\u7c7b\u578bTypes\u51b3\u5b9a\u8fdb\u7a0b\u80fd\u5426\u8bbf\u95ee\u67d0\u4e2a\u6587\u4ef6\u3002 SELinux\u7c7b\u578b\u662f\u4ee5\u540e\u7f00 _t \u7ed3\u5c3e\u3002 \u4e0a\u4e0b\u6587(Contexts)\uff1a \u7528\u6765\u6807\u8bb0\u8fdb\u7a0b\u548c\u6587\u4ef6\u3002\u5206\u522b\u662f\u7528\u6237Users\uff0c\u89d2\u8272Roles\uff0c\u7c7b\u578bTypes\uff0c\u8303\u56f4Ranges\u3002 \u683c\u5f0f\uff1a user:role:type:range \u6587\u4ef6\u7c7b\u578b(Object Classes)\uff1a \u6bcf\u4e2a\u6587\u4ef6\u7c7b\u578bTypes\u90fd\u5bf9\u5e94\u4e00\u5957\u7b56\u7565Policies\u3002\u7b56\u7565Policies\u51b3\u5b9a\u4e86\u8fdb\u7a0b\u5bf9\u8fd9\u7c7b\u6587\u4ef6\u7684\u8bbf\u95ee\u6743\u9650\u3002 \u8bbf\u95ee\u6743\u9650\u67094\u79cd\uff1a \u521b\u5efacreate \u8bfb\u53d6read \u5199\u5165write \u5220\u9664unlink\uff08\u6ce8\u610f\uff0c\u8fd9\u91cc\u4e0d\u662f\u94fe\u63a5\u7684\u610f\u601d\uff09 \u89c4\u5219(Rules) \u683c\u5f0f\uff1a allow user_t user_home_t:file {create read write unlink}; \u542b\u4e49\uff1a user_t \u7c7b\u578b\u5bf9 user_home_t \u7c7b\u578b\u6709\u521b\u5efacreate\uff0c\u8bfb\u53d6read\uff0c\u5199\u5165write\uff0c\u5220\u9664unlink\u6743\u9650\u3002","title":"2.1.SELinux\u4e3b\u8981\u6982\u5ff5"},{"location":"linux/SRE/03-identity-security/#22selinux-in-opensuse","text":"\u4f5c\u4e3aSELinux\u7684\u66ff\u4ee3\u54c1\uff0c2005\u5e74\u88abNovell\u6536\u8d2d\u7684Immunix\u516c\u53f8\u5f00\u53d1\u4e86AppArmor\u3002SUSE\u5728openSUSE Leap\u4e2d\u63d0\u4f9b\u5bf9SELinux\u6846\u67b6\u7684\u652f\u6301\u3002\u8fd9\u5e76\u4e0d\u610f\u5473\u7740openSUSE Leap\u7684\u9ed8\u8ba4\u5b89\u88c5\u4f1a\u5728\u4e0d\u4e45\u7684\u5c06\u6765\u4eceAppArmor\u5207\u6362\u5230SELinux\u3002 \u6dfb\u52a0SELinux\u7684\u6e90\u3002\u53ef\u4ee5\u4ece https://download.opensuse.org/repositories/security:/SELinux/ \u4e0b\u8f7d\u5bf9\u5e94\u7684\u7b56\u7565policy\u3002 sudo zypper ar -f https://download.opensuse.org/repositories/security:/SELinux/openSUSE_Factory/ Security-SELinux \u5b89\u88c5C++\u7b49\u57fa\u7840\u5f00\u53d1\u5305\uff1a # \u5217\u51fa\u5f53\u524d\u53ef\u5b89\u88c5\u7684Pattern sudo zypper pt # \u5b89\u88c5\u4e0b\u9762\u51e0\u4e2a\u5f00\u53d1\u76f8\u5173\u7684Pattern sudo zypper in -t pattern devel_C_C++ devel_basis devel_kernel \u5b89\u88c5SELinux packages\uff1a zypper se --search-descriptions selinux sudo zypper in restorecond policycoreutils setools-console sudo zypper in selinux-tools libselinux-devel \u5b89\u88c5SELinux policy\uff1a sudo zypper in selinux-policy-targeted selinux-policy-devel selinux-autorelabel \u66f4\u65b0GRUB2 bootloader\uff08GRUB2\u5f15\u5bfc\u52a0\u8f7d\u7a0b\u5e8f\uff09\uff1a \u7f16\u8f91\u6587\u4ef6 /etc/default/grub \uff0c\u6dfb\u52a0\u4e0b\u9762\u5185\u5bb9\u5230 GRUB_CMDLINE_LINUX_DEFAULT= \u8fd9\u4e00\u884c\uff1a security = selinux selinux = 1 \u8bb0\u5f55\u8fd9\u4e00\u884c\u7684\u539f\u59cb\u4fe1\u606f\uff1a GRUB_CMDLINE_LINUX_DEFAULT = \"splash=silent resume=/dev/disk/by-uuid/47c36ad7-f49f-4ecd-9b72-4801c5bb3a04 preempt=full mitigations=auto quiet security=apparmor\" \u8fd0\u884c\u4e0b\u9762\u7684\u547d\u4ee4\u751f\u6210\u65b0\u7684GRUB2\u5f15\u5bfc\u52a0\u8f7d\u7a0b\u5e8f\u914d\u7f6e\u6587\u4ef6\u3002 sudo grub2-mkconfig -o /boot/grub2/grub.cfg \u7f16\u8f91\u6587\u4ef6 /etc/selinux/config \u5e76\u8bbe\u7f6e SELINUX=permissive \u6765\u542f\u7528SElinux\u3002\u8fd9\u4e0e\u524d\u9762GRUB2\u7684\u542f\u52a8\u914d\u7f6e\u662f\u4e00\u81f4\u7684\u3002 \u5982\u6587\u4ef6\u4e0d\u5b58\u5728\uff0c\u5219\u521b\u5efa\u3002 $ sudo cat /etc/selinux/config SELINUX = permissive SELINUXTYPE = targeted \u91cd\u542f\u7cfb\u7edf\u3002\u7cfb\u7edf\u542f\u52a8\u53ef\u80fd\u9700\u8981\u4e00\u4e9b\u65f6\u95f4\uff0cSELinux\u9700\u8981\u7ed9\u6574\u4e2a\u6587\u4ef6\u7cfb\u7edf\u91cd\u65b0\u8fdb\u884c\u6807\u7b7e\u5316\u3002 \u91cd\u542f\u540e\uff0c\u8fd0\u884c\u4e0b\u9762\u7684\u547d\u4ee4\u6765\u67e5\u770bSELinux\u662f\u5426\u8fd0\u884c\u6b63\u5e38\u3002 $ sudo getenforce Permissive $ sudo sestatus -v SELinux status: enabled SELinuxfs mount: /sys/fs/selinux SELinux root directory: /etc/selinux Loaded policy name: targeted Current mode: permissive Mode from config file: permissive Policy MLS status: enabled Policy deny_unknown status: allowed Memory protection checking: requested ( insecure ) Max kernel policy version: 33 Process contexts: Current context: unconfined_u:unconfined_r:unconfined_t:s0 Init context: system_u:system_r:kernel_t:s0 /sbin/agetty system_u:system_r:kernel_t:s0 /usr/sbin/sshd system_u:system_r:kernel_t:s0 File contexts: Controlling terminal: unconfined_u:object_r:devpts_t:s0 /etc/passwd system_u:object_r:unlabeled_t:s0 /etc/shadow system_u:object_r:unlabeled_t:s0 /bin/bash system_u:object_r:unlabeled_t:s0 -> system_u:object_r:unlabeled_t:s0 /bin/login system_u:object_r:unlabeled_t:s0 /bin/sh system_u:object_r:unlabeled_t:s0 -> system_u:object_r:unlabeled_t:s0 /sbin/agetty system_u:object_r:unlabeled_t:s0 -> system_u:object_r:unlabeled_t:s0 /sbin/init system_u:object_r:unlabeled_t:s0 -> system_u:object_r:unlabeled_t:s0 /usr/sbin/sshd system_u:object_r:unlabeled_t:s0 \u53c2\u8003\uff1a GRUB2\u5f15\u5bfc\u52a0\u8f7d\u7a0b\u5e8f\u4e2d\u6dfb\u52a0\u7684\u4e09\u4e2a\u53c2\u6570\u7684\u89e3\u91ca\uff1a security=selinux : This option tells the kernel to use SELinux and not AppArmor. selinux=1 : This option switches on SELinux. enforcing=0 : This option puts SELinux in permissive mode. In this mode, SELinux is fully functional, but does not enforce any of the security settings in the policy. Use this mode for testing and configuring your system. To switch on SELinux protection, when the system is fully operational, change the option to enforcing=1 and add SELINUX=enforcing in /etc/selinux/config . \u5c0f\u8d34\u58eb\uff1a \u5728\u9996\u6b21\u542f\u7528SELinux\u540e\uff0c\u5982\u679c\u53ea\u5728grub2\u91cc\u9762\u6dfb\u52a0selinux=1\uff0c\u901a\u8fc7 getenforce \u547d\u4ee4\u770b\u7684SELinux\u4e00\u76f4\u5c31\u662fdisabled\u7684\u72b6\u6001\uff0c\u9700\u8981\u624b\u5de5\u521b\u5efa/etc/selinux/config\u6587\u4ef6\u6dfb\u52a0\u914d\u7f6e\u624d\u884c\u3002\u611f\u89c9grub2\u91cc\u9762\u65e0\u9700\u8bbe\u7f6e\uff0c\u76f4\u63a5\u914d\u7f6e/etc/selinux/config\u6587\u4ef6\u3002\u4e0d\u786e\u5b9a\u8fd9\u4e2a\u60f3\u6cd5\u662f\u5426\u6b63\u786e\u3002 \u5728grub2\u4e2d\u8bbe\u5b9aselinux=1\uff0c\u5728/etc/selinux/config\u6587\u4ef6\u4e2d\uff1a \u8bbe\u5b9aSELINUX=permissive\uff0c\u91cd\u542f\u540e\u901a\u8fc7 getenforce \u547d\u4ee4\u770b\u5230\u7684\u662fpermissive\u3002 \u8bbe\u5b9aSELINUX=disabled\uff0c\u5219\u91cd\u542f\u540e getenforce \u547d\u4ee4\u770b\u5230\u7684\u662fdisabled\u3002 \u8fd9\u8bf4\u660e\u914d\u7f6e\u6587\u4ef6\u540e\u542f\u52a8\uff0c\u8986\u76d6\u4e86\u5185\u6838\u8bbe\u7f6e\u3002 \u6ce8\u610f\uff0c\u5982\u679c\u4ec5\u4ec5\u5b8c\u6210\u4e86\u4e0a\u9762\u7684enable SELinux\uff0c\u7acb\u523b\u8bbe\u5b9aSELINUX=enforcing\uff0c\u4f1a\u5f15\u8d77ssh\u65e0\u6cd5\u767b\u5f55\uff0c\u9519\u8bef\u4fe1\u606f\u662f /bin/bash: Permission denied \u3002 \u914d\u7f6eSELinux\u3002 $ sudo semanage boolean -l Failed to use semanage \u6dfb\u52a0\u4e0b\u9762\u5185\u5bb9\u5230.bashrc\u6587\u4ef6\u3002 export PATH = /usr/local/bin:/home/ $USER /.local/bin: $PATH \u66f4\u65b0pip3. pip3 install --upgrade pip \u5b89\u88c5\u4e0b\u9762\u51e0\u4e2a\u5305 sudo zypper in libselinux libselinux-devel sudo zypper in python3-semanage sudo zypper in libsemanage-devel libsemanage-devel-static sudo zypper in policycoreutils-python-utils sudo zypper in cross-x86_64-linux-glibc-devel glibc-utils glibc-profile sudo zypper in policycoreutils-devel","title":"2.2.SELinux in openSUSE"},{"location":"linux/SRE/03-identity-security/#23selinux-in-ubuntu","text":"","title":"2.3.SELinux in Ubuntu"},{"location":"linux/SRE/03-identity-security/#24selinux-in-rocky","text":"","title":"2.4.SELinux in Rocky"},{"location":"linux/SRE/03-identity-security/#3","text":"/etc/passwd \uff1a\u7528\u6237\u53ca\u5176\u5c5e\u6027\u4fe1\u606f\uff08\u7528\u6237\u540d\uff0cUID\uff0c\u4e3b\u7ec4ID\u7b49\uff09 /etc/shadow \uff1a\u7528\u6237\u5bc6\u7801\u673a\u5668\u5c5e\u6027 /etc/group \uff1a\u7ec4\u53ca\u5176\u5c5e\u6027 /etc/gshadow \uff1a\u7ec4\u5bc6\u7801\u53ca\u5176\u5c5e\u6027","title":"3.\u7528\u6237\u548c\u7ec4\u7684\u914d\u7f6e\u6587\u4ef6"},{"location":"linux/SRE/03-identity-security/#31etcpasswd","text":"\u683c\u5f0f\u8bf4\u660e\uff1a vagrant:x:1001:474:vagrant:/home/vagrant:/bin/bash [ ----- ] - [ -- ] [ - ] [ ----- ] [ ----------- ] [ ------- ] | | | | | | +--------> 7 . Login shell | | | | | +--------------------> 6 . Home directory | | | | +-------------------------------> 5 . GECOS or the full name of the user | | | +-------------------------------------> 4 . GID | | +------------------------------------------> 3 . UID | +---------------------------------------------> 2 . Password +--------------------------------------------------> 1 . Username","title":"3.1./etc/passwd"},{"location":"linux/SRE/03-identity-security/#32etcshadow","text":"\u683c\u5f0f\u8bf4\u660e\uff1a vagrant: $6 $.n.:17736:0:99999:7::: [ ----- ] [ ---- ] [ --- ] - [ --- ] ---- | | | | | || | +-----------> 9 . Unused | | | | | || +------------> 8 . Expiration date since Jan 1 , 1970 | | | | | | +-------------> 7 . Inactivity period \u5bc6\u7801\u8fc7\u671f\u540e\u7684\u5bbd\u9650\u671f | | | | | +--------------> 6 . Warning period, default 7 days | | | | +------------------> 5 . Maximum password age | | | +----------------------> 4 . Minimum password age | | +--------------------------> 3 . Last password change since Jan 1 , 1970 | +---------------------------------> 2 . Encrypted Password +-------------------------------------------> 1 . Username","title":"3.2./etc/shadow"},{"location":"linux/SRE/03-identity-security/#33etcgroup","text":"\u683c\u5f0f\u8bf4\u660e\uff1a audio:x:492:pulse [ --- ] - [ - ] [ --- ] | | | +----> 4 . username-list, who have this group as their supplementary | | +---------> 3 . GID | +------------> 2 . group-password. Real password is in /etc/gshadow +----------------> 1 . groupname","title":"3.3./etc/group"},{"location":"linux/SRE/03-identity-security/#34etcgshadow","text":"\u683c\u5f0f\u8bf4\u660e\uff1a general:!!:shelley:juan,bob [ ----- ] -- [ ----- ] [ ------ ] | | | +-------> 4 . group members ( in a comma delimited list ) | | +---------------> 3 . group adminstrators ( in a comma delimited list ) | +---------------------> 2 . encrypted password. ` ! ` , ` !! ` , and null +---------------------------> 1 . group name Encrypted password ! \uff1ano user is allowed to access the group using the newgrp command. !! \uff1athe same as a value of ! \u2014 however, it also indicates that a password has never been set before. null\uff1aonly group members can log into the group.","title":"3.4./etc/gshadow"},{"location":"linux/SRE/03-identity-security/#35","text":"# \u901a\u8fc7`/dev/urandom`\u751f\u6210\u968f\u673a\u6570\uff0c\u901a\u8fc7`tr -dc`\u8fc7\u6ee4\u968f\u673a\u6570\uff0c\u53ea\u4fdd\u7559\u5b57\u6bcd\u548c\u6570\u5b57\uff0c\u901a\u8fc7`head -c`\u4fdd\u7559\u6307\u5b9a\u4f4d\u6570 $ tr -dc '[:alnum:]' < /dev/urandom | head -c 12 xFw7vfma54D8 $ openssl rand -base64 9 I5TZXJfpd3Pg","title":"3.5.\u751f\u6210\u968f\u673a\u5bc6\u7801"},{"location":"linux/SRE/03-identity-security/#36vipwvigrpwckgrpck","text":"vipw \u548c vigr \u547d\u4ee4\u5206\u522b\u7f16\u8f91\u6587\u4ef6 /etc/passwd \u548c /etc/group \u3002 \u5982\u679c\u6307\u5b9a\u4e86 -s \u6807\u5fd7\uff0c\u8fd9\u4e9b\u547d\u4ee4\u5c06\u5206\u522b\u7f16\u8f91\u5176\u6587\u4ef6\u7684\u5f71\u5b50\uff08\u5b89\u5168\uff09\u7248\u672c\uff1a /etc/shadow \u548c /etc/gshadow \u3002 vipw \u548c vigr \u547d\u4ee4\u5728\u7f16\u8f91\u6587\u4ef6\u65f6\u4f1a\u8bbe\u7f6e\u9501\u4ee5\u9632\u6b62\u6587\u4ef6\u635f\u574f\u3002 vipw \u548c vigr \u547d\u4ee4\u4f1a\u9996\u5148\u5c1d\u8bd5\u73af\u5883\u53d8\u91cf $VISUAL \uff0c\u7136\u540e\u662f\u73af\u5883\u53d8\u91cf $EDITOR \uff0c\u6700\u540e\u662f\u9ed8\u8ba4\u7f16\u8f91\u5668 vi \u3002 sudo vipw sudo vipw -s sudo vigr sudo vigr -s pwck \u547d\u4ee4\u5b9e\u73b0\u9a8c\u8bc1\u7cfb\u7edf\u8ba4\u8bc1\u4fe1\u606f\u7684\u5b8c\u6574\u6027\u3002 \u68c0\u67e5 /etc/passwd \u548c /etc/shadow \u4e2d\u7684\u6240\u6709\u6761\u76ee\u6bcf\u4e2a\u5b57\u6bb5\u662f\u5426\u5177\u6709\u6b63\u786e\u7684\u683c\u5f0f\u548c\u6709\u6548\u6570\u636e\u3002 \u7cfb\u7edf\u4f1a\u63d0\u793a\u7528\u6237\u5220\u9664\u683c\u5f0f\u4e0d\u6b63\u786e\u6216\u5b58\u5728\u5176\u4ed6\u9519\u8bef\u7684\u6761\u76ee\u3002 pwck \u8fd4\u56de\u503c\uff1a 0 : success 1 : invalid command syntax 2 : one or more bad password entries 3 : can\u2019t open password files 4 : can\u2019t lock password files 5 : can\u2019t update password files grpck \u547d\u4ee4\u5b9e\u73b0\u9a8c\u8bc1\u7cfb\u7edf\u8ba4\u8bc1\u4fe1\u606f\u7684\u5b8c\u6574\u6027\u3002 \u68c0\u67e5 /etc/group \u548c /etc/gshadow \u4e2d\u7684\u6240\u6709\u6761\u76ee\u6bcf\u4e2a\u5b57\u6bb5\u662f\u5426\u5177\u6709\u6b63\u786e\u7684\u683c\u5f0f\u548c\u6709\u6548\u6570\u636e\u3002 \u7cfb\u7edf\u4f1a\u63d0\u793a\u7528\u6237\u5220\u9664\u683c\u5f0f\u4e0d\u6b63\u786e\u6216\u5b58\u5728\u5176\u4ed6\u9519\u8bef\u7684\u6761\u76ee\u3002 grpck \u8fd4\u56de\u503c\uff1a 0 : success 1 : invalid command syntax 2 : one or more bad group entries 3 : can\u2019t open group files 4 : can\u2019t lock group files 5 : can\u2019t update group files","title":"3.6.vipw/vigr/pwck/grpck\u547d\u4ee4"},{"location":"linux/SRE/03-identity-security/#4","text":"\u7528\u6237\u7ba1\u7406\u547d\u4ee4\uff1a useradd usermod userdel","title":"4.\u7528\u6237\u7ba1\u7406"},{"location":"linux/SRE/03-identity-security/#41useradd","text":"\u4e3e\u4f8b\uff1a # \u666e\u901a\u7528\u6237 $ useradd -m -g wheel -G root -c \"vagrant\" vagrant # \u975e\u4ea4\u4e92\u7528\u6237 $ useradd -r -u 48 -g apache -d /var/www -s /sbin/nologin -g postfix -c \"Apache\" apache 2 >/dev/null useradd \u547d\u4ee4\u7684\u9ed8\u8ba4\u503c\u662f\u5728 /etc/default/useradd \u6587\u4ef6\u4e2d\u8bbe\u5b9a\u3002 openSUSE\u7684 /etc/default/useradd \u6587\u4ef6\u5185\u5bb9\uff1a GROUP = 100 HOME = /home INACTIVE = -1 # \u5bf9\u5e94/etc/shadow\u6587\u4ef6\u7b2c7\u5217\uff0cInactivity period\uff0c\u5bc6\u7801\u8fc7\u671f\u540e\u7684\u5bbd\u9650\u671f\uff0c-1\u8868\u793a\u4e0d\u9650\u5236 EXPIRE = # \u5bf9\u5e94/etc/shadow\u6587\u4ef6\u7b2c8\u5217\uff0cExpiration date since Jan 1, 1970\uff0c\u5373\u8d26\u53f7\u6709\u6548\u671f SHELL = /bin/bash SKEL = /etc/skel # \u7528\u4e8e\u751f\u6210\u7528\u6237\u4e3b\u76ee\u5f55\u7684\u6a21\u7248\u6587\u4ef6 USRSKEL = /usr/etc/skel CREATE_MAIL_SPOOL = yes Rocky\u7684 /etc/default/useradd \u6587\u4ef6\u5185\u5bb9\uff1a GROUP = 100 HOME = /home INACTIVE = -1 EXPIRE = SHELL = /bin/bash SKEL = /etc/skel CREATE_MAIL_SPOOL = yes \u5728Ubuntu\u4e2d /etc/default/useradd \u6587\u4ef6\u53ea\u6709\u4e0b\u9762\u8fd9\u4e00\u884c\u3002 SHELL = /bin/sh","title":"4.1.\u521b\u5efa\u7528\u6237useradd"},{"location":"linux/SRE/03-identity-security/#411newusers","text":"\u683c\u5f0f\uff1a newusers \u3002\u5176\u4e2d\u6587\u4ef6 \u7684\u683c\u5f0f\u5982\u4e0b\uff1a :::::: \u4e3e\u4f8b\uff0c\u521b\u5efa\u6587\u4ef6 users.txt \uff1a $ cat ~/users.txt tester1:123:600:1530: \"Test User1,testuser1@abc.com\" :/home/tester1:/bin/bash tester2:123:601:1529:::/bin/bash tester3:123::::: tester4:123::::/home/tester4:/bin/tsh \u770b\u7ed3\u679c\uff1a $ cat /etc/passwd | grep tester tester1:x:600:1530: \"Test User1,testuser1@abc.com\" :/home/tester1:/bin/bash tester2:x:601:1529:::/bin/bash tester3:x:1001:1001::: tester4:x:1002:1002::/home/tester4:/bin/tsh $ cat /etc/group | grep tester tester1:*:1530: tester2:*:1529: tester3:*:1001: tester4:*:1002: $ sudo cat /etc/shadow | grep tester tester1:!:19321:0:99999:7::: tester2:!:19321:0:99999:7::: tester3:!:19321:0:99999:7::: tester4:!:19321:0:99999:7::: $ ls -ld /home/tester* drwxr-xr-x. 1 tester1 tester1 0 Nov 26 00 :32 /home/tester1 drwxr-xr-x. 1 tester4 tester4 0 Nov 26 00 :32 /home/tester4","title":"4.1.1.\u6279\u91cf\u521b\u5efa\u7528\u6237newusers"},{"location":"linux/SRE/03-identity-security/#412chpasswd","text":"\u4e0d\u540c\u65b9\u6cd5\uff1a echo username:password | chpasswd chpasswd < file.txt # file.txt\u6bcf\u884c\u7684\u683c\u5f0f\u662fusername:password paste -d \":\" user.txt passwd.txt | chpasswd \u53c2\u6570 -e \uff1a\u53e3\u4ee4\u4ee5\u52a0\u5bc6\u7684\u65b9\u5f0f\u4f20\u9012\u3002\u5426\u5219\u53e3\u4ee4\u4ee5\u660e\u6587\u7684\u5f62\u5f0f\u4f20\u9012\u3002 \u6ce8\u610f\uff1a \u7528\u6237\u540dusername\u5fc5\u987b\u662f\u5df2\u5b58\u5728\u7684\u7528\u6237 \u666e\u901a\u7528\u6237\u6ca1\u6709\u4f7f\u7528\u8fd9\u4e2a\u6307\u4ee4\u7684\u6743\u9650 \u5982\u679c\u8f93\u5165\u6587\u4ef6\u662f\u6309\u975e\u52a0\u5bc6\u65b9\u5f0f\u4f20\u9012\u7684\u8bdd\uff0c\u8bf7\u5bf9\u8be5\u6587\u4ef6\u8fdb\u884c\u9002\u5f53\u7684\u52a0\u5bc6\u3002 \u6307\u4ee4\u6587\u4ef6\u4e0d\u80fd\u6709\u7a7a\u884c \u4e3e\u4f8b\uff1a echo tester1:112233 | sudo chpasswd $ cat chpasswd.txt tester1:112233 tester2:33445566 $ sudo chpasswd < chpasswd.txt","title":"4.1.2.\u6279\u91cf\u4fee\u6539\u5bc6\u7801chpasswd"},{"location":"linux/SRE/03-identity-security/#413openssl-passwd","text":"\u547d\u4ee4 openssl passwd \u683c\u5f0f\u53ef\u4ee5\u5982\u4e0b\u65b9\u6cd5\u83b7\u5f97\u3002 $ man -f passwd passwd ( 1 ) - change user password passwd ( 1ssl ) - compute password hashes passwd ( 5 ) - password file $ man passwd Man: find all matching manual pages ( set MAN_POSIXLY_CORRECT to avoid this ) * passwd ( 1 ) passwd ( 5 ) passwd ( 1ssl ) Man: What manual page do you want? Man: 1ssl \u4e3e\u4f8b\uff08\u8fd9\u91cc\u7528 \u4ee3\u66ff\u5b9e\u9645\u5bc6\u7801\uff09\uff1a # \u57fa\u4e8e\u7ed9\u5b9a\u5b57\u4e32newpasswd\u751f\u6210sha256\u52a0\u5bc6\u7801\uff0c $ openssl passwd -6 newpasswd # \u521b\u5efa\u65b0\u7528\u6237tester5\uff0c\u8d4b\u4e88\u52a0\u5bc6\u5bc6\u7801 $ useradd -p '' tester1 # \u8bfb\u53d6\u7528\u6237tester5\u7684\u5bc6\u7801\uff0c\u53ef\u4ee5\u9a8c\u8bc1\u662f\u5426\u548c\u4e4b\u524d\u7684\u4e00\u81f4 $ sudo getent shadow tester5 tester5::19321:0:99999:7:::","title":"4.1.3.\u751f\u6210\u52a0\u5bc6\u5bc6\u7801openssl passwd"},{"location":"linux/SRE/03-identity-security/#42usermod","text":"\u6dfb\u52a0\u7528\u6237\u5230\u9644\u52a0\u7ec4 usermod -a -G GROUP USER usermod -a -G GROUP1,GROUP2,GROUP3 USER \u4fee\u6539\u7528\u6237\u4e3b\u7ec4 usermod -a -g GROUP USER \u4fee\u6539\u7528\u6237\u4fe1\u606f usermod -c \"GECOS Comments\" USER \u4fee\u6539\u7528\u6237\u4e3b\u76ee\u5f55\uff0c\u4f7f\u7528\u7edd\u5bf9\u8def\u5f84\uff0c -m \u53c2\u6570\u4f1a\u628a\u539f\u4e3b\u76ee\u5f55\u7684\u5185\u5bb9\u79fb\u52a8\u5230\u65b0\u4e3b\u76ee\u5f55\u3002 usermod -d NEW_HOME_DIR USER usermod -d NEW_HOME_DIR -m USER \u4fee\u6539\u7528\u6237shell usermod -s SHELL USER \u4fee\u6539\u7528\u6237UID usermod -u UID USER \u4fee\u6539\u7528\u6237\u540d\uff08\u4e0d\u5e38\u7528\uff09\uff0c\u540c\u65f6\u4e5f\u9700\u8981\u4fee\u6539\u7528\u6237\u4e3b\u76ee\u5f55\u3002 usermod -l NEW_USER USER \u4fee\u6539\u7528\u6237\u8fc7\u671f\u5c5e\u6027\uff0c\u65e5\u671f\u683c\u5f0f\u662f YYYY-MM-DD usermod -e DATE USER \u5982\u679c\u8bbe\u5b9a\u6c38\u4e0d\u8fc7\u671f\uff0c\u5219\u7f6e\u7a7a\u65e5\u671f\uff1a usermod -e \"\" USER \u67e5\u770b\u5f53\u524d\u7528\u6237\u7684\u8fc7\u671f\u65e5\u671f $ sudo chage -l vagrant Last password change : Oct 30 , 2022 Password expires : never Password inactive : never Account expires : never Minimum number of days between password change : 0 Maximum number of days between password change : 99999 Number of days of warning before password expires : 7 \u9501\u5b9a\u7528\u6237\u3002 \u6b64\u547d\u4ee4\u5c06\u5728\u52a0\u5bc6\u5bc6\u7801\u524d\u63d2\u5165\u4e00\u4e2a\u611f\u53f9\u53f7 (!) \u6807\u8bb0\u3002 \u5f53 /etc/shadow \u6587\u4ef6\u4e2d\u7684\u5bc6\u7801\u5b57\u6bb5\u5305\u542b\u611f\u53f9\u53f7\u65f6\uff0c\u7528\u6237\u5c06\u65e0\u6cd5\u4f7f\u7528\u5bc6\u7801\u9a8c\u8bc1\u767b\u5f55\u7cfb\u7edf\u3002 \u5176\u4ed6\u767b\u5f55\u65b9\u6cd5\u4ecd\u7136\u5141\u8bb8\uff0c\u4f8b\u5982\u57fa\u4e8e\u5bc6\u94a5\u7684\u8eab\u4efd\u9a8c\u8bc1\u6216\u5207\u6362\u5230\u7528\u6237\u3002 \u5982\u679c\u8981\u9501\u5b9a\u8d26\u6237\u5e76\u7981\u7528\u6240\u6709\u767b\u5f55\u65b9\u5f0f\uff0c\u8fd8\u9700\u8981\u5c06\u5230\u671f\u65e5\u671f\u8bbe\u7f6e\u4e3a1\u3002 usermod -L USER usermod -L -e 1 USER \u89e3\u9501\u7528\u6237 usermod -U USER","title":"4.2.\u4fee\u6539\u7528\u6237\u5c5e\u6027usermod"},{"location":"linux/SRE/03-identity-security/#43userdel","text":"userdel \u547d\u4ee4\u6267\u884c\u65f6\uff0c\u4f1a\u8bfb\u53d6 /etc/login.defs \u6587\u4ef6\u7684\u5185\u5bb9\u3002 \u6b64\u6587\u4ef6\u4e2d\u5b9a\u4e49\u7684\u5c5e\u6027\u4f1a\u8986\u76d6 userdel \u7684\u9ed8\u8ba4\u884c\u4e3a\u3002 \u5982\u679c\u5728\u6b64\u6587\u4ef6\u4e2d\u5c06 USERGROUPS_ENAB \u8bbe\u7f6e\u4e3a yes \uff0c userdel \u5c06\u5220\u9664\u4e0e\u7528\u6237\u540c\u540d\u7684\u7ec4\uff0c\u524d\u63d0\u662f\u6ca1\u6709\u5176\u4ed6\u7528\u6237\u662f\u8be5\u7ec4\u7684\u6210\u5458\u3002 userdel \u547d\u4ee4\u4ece /etc/passwd \u548c /etc/shadow \u6587\u4ef6\u4e2d\u5220\u9664\u7528\u6237\u6761\u76ee\u3002 userdel \u547d\u4ee4\u5220\u9664\u7528\u6237\u5e10\u6237\u65f6\uff0c\u4e00\u822c\u4e0d\u4f1a\u5220\u9664\u7528\u6237\u4e3b\u76ee\u5f55\u548c\u90ae\u4ef6\u5047\u8131\u673amail spool\u76ee\u5f55\u3002 \u4f7f\u7528 -r \u9009\u9879\u5f3a\u5236\u5220\u9664\u7528\u6237\u7684\u4e3b\u76ee\u5f55\u548c\u90ae\u4ef6\u5047\u8131\u673a\u76ee\u5f55\u3002 \u5982\u679c\u8981\u5220\u9664\u7684\u7528\u6237\u4ecd\u7136\u5904\u4e8e\u767b\u5f55\u72b6\u6001\uff0c\u6216\u8005\u6709\u5c5e\u4e8e\u8be5\u7528\u6237\u7684\u6b63\u5728\u8fd0\u884c\u7684\u8fdb\u7a0b\uff0c\u5219 userdel \u547d\u4ee4\u4e0d\u5141\u8bb8\u5220\u9664\u8be5\u7528\u6237\u3002 \u4f7f\u7528 -f \u9009\u9879\u5f3a\u5236\u5220\u9664\u7528\u6237\u5e10\u6237\uff0c\u5373\u4f7f\u7528\u6237\u4ecd\u7136\u767b\u5f55\u6216\u6709\u5c5e\u4e8e\u8be5\u7528\u6237\u7684\u6b63\u5728\u8fd0\u884c\u7684\u8fdb\u7a0b\u4e5f\u662f\u5982\u6b64\u3002 userdel USER userdel -r USER","title":"4.3.\u5220\u9664\u7528\u6237userdel"},{"location":"linux/SRE/03-identity-security/#44id","text":"\u7c7bUnix\u64cd\u4f5c\u7cfb\u7edf\u4e2d\u7684\u6bcf\u4e2a\u7528\u6237\u90fd\u7531\u4e00\u4e2a\u4e0d\u540c\u7684\u6574\u6570\u6807\u8bc6\uff0c\u8fd9\u4e2a\u552f\u4e00\u7684\u6570\u5b57\u79f0\u4e3aUserID\u3002 \u4e3a\u8fdb\u7a0bprocess\u5b9a\u4e49\u4e86\u4e09\u79cd\u7c7b\u578b\u7684UID\uff0c\u53ef\u4ee5\u6839\u636e\u4efb\u52a1\u7684\u6743\u9650\u52a8\u6001\u66f4\u6539\u3002 \u5b9a\u4e49\u7684\u4e09\u79cd\u4e0d\u540c\u7c7b\u578b\u7684UID\u662f\uff1a \u771f\u5b9e\u7528\u6237ID\uff08Real UserId\uff09\uff1a\u5bf9\u4e8e\u4e00\u4e2a\u8fdb\u7a0b\uff0cReal UserId\u5c31\u662f\u542f\u52a8\u5b83\u7684\u7528\u6237\u7684 UserID\u3002 \u5b83\u5b9a\u4e49\u4e86\u8fd9\u4e2a\u8fdb\u7a0b\u53ef\u4ee5\u8bbf\u95ee\u54ea\u4e9b\u6587\u4ef6\u3002 \u6709\u6548\u7528\u6237\u540d\uff08Effective UserID\uff09\uff1a\u5b83\u901a\u5e38\u4e0e Real UserID \u76f8\u540c\uff0c\u4f46\u6709\u65f6\u4f1a\u66f4\u6539\u4e3a\u4f7f\u975e\u7279\u6743\u7528\u6237\u80fd\u591f\u8bbf\u95ee\u90a3\u4e9b\u53ea\u80fd\u7531\u7279\u6743\u7528\u6237\uff08\u5982 root \uff09\u8bbf\u95ee\u7684\u6587\u4ef6\u3002 \u4fdd\u5b58\u7684\u7528\u6237ID\uff08Saved UserID\uff09 \uff1a\u5f53\u4e00\u4e2a\u4ee5\u63d0\u5347\u7684\u6743\u9650\uff08\u901a\u5e38\u662f root \uff09\u8fd0\u884c\u7684\u8fdb\u7a0b\u9700\u8981\u505a\u4e00\u4e9b\u4f4e\u6743\u9650\u7684\u4efb\u52a1\u65f6\u4f7f\u7528\uff0c\u53ef\u4ee5\u901a\u8fc7\u4e34\u65f6\u5207\u6362\u5230\u975e\u7279\u6743\u5e10\u6237\u6765\u5b9e\u73b0\u3002\u5728\u6267\u884c\u4f4e\u6743\u9650\u4efb\u52a1\u65f6\uff0c\u6709\u6548\u7684 UID \u88ab\u66f4\u6539\u4e3a\u67d0\u4e2a\u8f83\u4f4e\u6743\u9650\u7684\u503c\uff0c\u5e76\u4e14 euid \u88ab\u4fdd\u5b58\u5230\u5df2\u4fdd\u5b58\u7684 userID (suid)\u4e2d\uff0c\u4ee5\u4fbf\u5728\u4efb\u52a1\u5b8c\u6210\u65f6\u7528\u4e8e\u5207\u6362\u56de\u7279\u6743\u5e10\u6237\u3002 \u5728\u4e00\u4e2a\u7ec8\u7aef\u7a97\u53e3\u6267\u884c\u4e0b\u9762\u547d\u4ee4\uff0c\u6682\u505c\u5728\u65b0\u5bc6\u7801\u8f93\u5165\u8fd9\u4e00\u6b65\u3002 $ ls -ltr /usr/bin/passwd -rwsr-xr-x. 1 root shadow 65208 May 8 2022 /usr/bin/passwd $ passwd Changing password for vagrant. Current password: New password: \u65b0\u5f00\u4e00\u4e2a\u7ec8\u7aef\u7a97\u53e3\u3002 $ ps -a | grep passwd 3040 pts/0 00 :00:00 passwd $ ps -eo pid,euid,ruid | grep 3040 3040 0 1000 \u4e0a\u9762\u8f93\u51fa\u53ef\u4ee5\u770b\u51fa\uff0c passwd \u8fd9\u4e2a\u8fdb\u7a0b\u7684Effective UserID\u662f 0 \u3002Real UserId\u662f 1000 . id \u547d\u4ee4\u67e5\u770b\u7528\u6237\u6709\u6548\u7684UID\u548cGID\u3002 \u67e5\u770b\u5f53\u524d\u7528\u6237\u7684\u4fe1\u606f\uff1a $ id uid = 1000 ( vagrant ) gid = 478 ( wheel ) groups = 478 ( wheel ) ,0 ( root ) context = unconfined_u:unconfined_r:unconfined_t:s0 \u67e5\u770b\u6307\u5b9a\u7528\u6237\u7684\u4fe1\u606f\uff1a $ id vagrant uid = 1000 ( vagrant ) gid = 478 ( wheel ) groups = 0 ( root ) ,478 ( wheel ) \u67e5\u770b\u5f53\u524d\u7528\u6237\u7684GID\uff1a $ id -g 478 \u67e5\u770b\u5f53\u524d\u7528\u6237\u7684UID\uff1a $ id -u 1000 \u67e5\u770b\u5f53\u524d\u7528\u6237\u6240\u6709\u7ec4\u7684GID\uff1a $ id -G 478 0 \u67e5\u770b\u5f53\u524d\u7528\u6237\u540d\uff1a $ id -un vagrant \u67e5\u770b\u5f53\u524d\u7528\u6237\u7684GID $ id -ur 1000 \u53ea\u6709SELinux\u6fc0\u6d3b\u540e\u624d\u6709 $ id -Z unconfined_u:unconfined_r:unconfined_t:s0 \u7c7b\u4f3c\u4e8e whoami \u547d\u4ee4 $ id -znG wheelroot","title":"4.4.\u67e5\u770b\u7528\u6237\u4fe1\u606fid"},{"location":"linux/SRE/03-identity-security/#45su","text":"\u547d\u4ee4 su - username \u662f\u767b\u5f55\u5f0f\u5207\u6362\u7528\u6237\u3002\u4f1a\u8bfb\u53d6\u76ee\u6807\u7528\u6237\u7684\u914d\u7f6e\u6587\u4ef6\uff0c\u5207\u6362\u81f3\u76ee\u6807\u7528\u6237\u7684\u4e3b\u76ee\u5f55\u3002 \u547d\u4ee4 su username \u662f\u975e\u767b\u5f55\u5f0f\u5207\u6362\u7528\u6237\u3002\u4e0d\u8bfb\u53d6\u76ee\u6807\u7528\u6237\u7684\u914d\u7f6e\u6587\u4ef6\uff0c\u4e0d\u6539\u53d8\u5f53\u524d\u5de5\u4f5c\u76ee\u5f55\u3002 \u5207\u6362\u6210root\u7528\u6237\uff0c\u5e76\u4f7f\u7528zsh shell\u3002 su -s /usr/bin/zsh su -s /usr/bin/zsh root \u5207\u6362\u6210tester1\u7528\u6237\uff0c\u4f7f\u7528bash shell su - tester1 -s /bin/bash su - -s /bin/bash tester1 \u4fdd\u7559\u5f53\u524d\u7528\u6237\u73af\u5883\u4e0d\u53d8\u3002 su -p root \u4e0d\u4ea4\u4e92\u5f0f\u5207\u6362\u7528\u6237\uff0c\u53ea\u7528\u76ee\u6807\u7528\u6237\u6267\u884c\u67d0\u4e9b\u547d\u4ee4\u3002 su -c ps su - root -c \"getent passwd\" su - root -s /bin/bash -c \"getent passwd\" root \u7528\u6237\u5207\u6362\u81f3\u5176\u4ed6\u7528\u6237\u4e0d\u9700\u8981\u5bc6\u7801\uff0c\u975e root \u7528\u6237\u5207\u6362\u5176\u4ed6\u7528\u6237\u9700\u8981\u5bc6\u7801\u3002","title":"4.5.\u5207\u6362\u7528\u6237su"},{"location":"linux/SRE/03-identity-security/#46","text":"","title":"4.6.\u8bbe\u7f6e\u5bc6\u7801"},{"location":"linux/SRE/03-identity-security/#461passwd","text":"\u4fee\u6539\u5f53\u524d\u7528\u6237\u81ea\u5df1\u7684\u5bc6\u7801\uff1a passwd \u4fee\u6539\u5176\u4ed6\u7528\u6237\u7684\u5bc6\u7801\uff1a sudo passwd root \u67e5\u770b\u67d0\u4e2a\u7528\u6237\u5bc6\u7801\u72b6\u6001\uff1a $ sudo passwd -S root root P 10 /30/2022 -1 -1 -1 -1 $ sudo passwd -S vagrant vagrant P 10 /30/2022 0 99999 7 -1 \u68c0\u67e5\u5168\u90e8\u7528\u6237\u7684\u5bc6\u7801\u72b6\u6001\uff1a sudo passwd -Sa \u5bc6\u7801\u72b6\u6001\u8bf4\u660e\uff1a Username Status Date Last Changed Minimum Age Maximum Age Warning Period Inactivity Period vagrant P 10 /30/2022 0 99999 7 -1 root P 10 /30/2022 -1 -1 -1 -1 Status\u7684\u63cf\u8ff0\uff1a P : Usable password NP : No password L : Locked password Age\u7684\u4e00\u4e9b\u7279\u6b8a\u503c\uff1a 9999 : Never expires 0 : Can be changed at anytime -1 : Not active \u5f3a\u5236\u8981\u6c42\u7528\u6237\u4e0b\u6b21\u767b\u5f55\u65f6\u4fee\u6539\u5bc6\u7801\uff1a $ sudo passwd -e tester1 $ sudo passwd -S tester1 tester1 P 01 /01/1970 0 99999 7 -1 \u7528\u6237tester1\u7684\u5bc6\u7801\u65e5\u671f\u5df2\u7ecf\u88ab\u6539\u6210 01/01/1970 \u4e86\u3002\u8fd9\u4e2a\u65e5\u671f\u7b97\u662fUnix\u7684\u201c\u7eaa\u5143\uff08epoch\uff09\u201d\u65e5\u671f\uff0c\u610f\u5473\u7740Unix\u7684\u65e5\u671f\u8d77\u70b9\uff0c0\u5929\u3002 \u9501\u5b9a\u67d0\u4e2a\u7528\u6237\uff1a $ sudo passwd -l tester1 $ sudo passwd -S tester1 tester1 L 01 /01/1970 0 99999 7 -1 \u6b64\u65f6\u7528\u6237 tester1 \u7684\u72b6\u6001\u680f\u5df2\u7ecf\u53d8\u6210\u4e86 L \uff0c\u9501\u5b9a\u72b6\u6001\u3002 \u89e3\u9501\u67d0\u4e2a\u7528\u6237\uff1a $ sudo passwd -u tester1 $ sudo passwd -S tester1 tester1 P 01 /01/1970 0 99999 7 -1 \u6b64\u65f6\u7528\u6237 tester1 \u7684\u72b6\u6001\u680f\u5df2\u7ecf\u4ece L \u53d8\u56de\u4e86 P \uff0c\u89e3\u9664\u4e86\u9501\u5b9a\u72b6\u6001\u3002 \u5220\u9664\u7528\u6237\u5bc6\u7801\u3002\u8fd9\u4e2a\u64cd\u4f5c\u614e\u91cd\uff0c\u5bc6\u7801\u5220\u9664\u540e\u8be5\u7528\u6237\u53ef\u4ee5\u4e0d\u9700\u8981\u5bc6\u7801\u5c31\u80fd\u8bbf\u95ee\u7cfb\u7edf\u3002 $ sudo passwd -d tester1 $ sudo passwd -S tester1 tester1 NP 01 /01/1970 0 99999 7 -1 \u6b64\u65f6\u7528\u6237 tester1 \u7684\u72b6\u6001\u680f\u662f NP \u3002","title":"4.6.1.passwd"},{"location":"linux/SRE/03-identity-security/#462pwgen","text":"\u5b89\u88c5\u5305\u3002 mkpasswd\u547d\u4ee4\u6709\u6b67\u4e49\uff0c2\u4e2a\u540c\u540d\u547d\u4ee4\u5b9e\u73b0\u4e0d\u540c\u529f\u80fd\uff0c\u751f\u6210\u968f\u673a\u5bc6\u7801\u5efa\u8bae\u4f7f\u7528 pwgen \u547d\u4ee4\u3002Rocky9\u6ca1\u6709\u627e\u5230pwgen\u5305\u3002 sudo zypper in pwgen sudo apt install pwgen \u968f\u673a\u751f\u6210\u957f\u5ea68\u4f4d\u5b89\u5168\u5bc6\u7801\u3002 pwgen -s -1 \u968f\u673a\u751f\u6210\u957f\u5ea614\u4f4d\u5b89\u5168\u5bc6\u7801\u3002 pwgen -s -1 14 \u968f\u673a\u751f\u62102\u4e2a\u957f\u5ea615\u4f4d\u5b89\u5168\u5bc6\u7801\u3002 pwgen -s -1 15 2 \u968f\u673a\u751f\u62105\u4e2a\u5bc6\u7801\uff0c\u957f\u5ea610\u4f4d\uff0c\u6bcf\u4e2a\u5bc6\u7801\u81f3\u5c11\u542b\u4e00\u4e2a\u7279\u6b8a\u5b57\u7b26\uff0c\u7ed3\u679c\u4ee5\u5217\u5f62\u5f0f\u8f93\u51fa\u3002 pwgen -s -1 -y 10 5 \u751f\u6210\u957f\u5ea68\uff0c\u542b\u6709\u6570\u5b57\uff0c\u542b\u6709\u5927\u5c0f\u5199\u5b57\u6bcd\u7684\u5bc6\u78014\u4e2a\uff0c\u5217\u6253\u5370 pwgen -s -n -c -C -1 8 4 \u751f\u6210\u957f\u5ea68\uff0c\u4e0d\u542b\u6570\u5b57\uff0c\u53ea\u542b\u5c0f\u5199\u5b57\u6bcd\uff0c\u5217\u6253\u5370 pwgen -s -c -A -0 -1 8 4 \u751f\u6210\u957f\u5ea616\uff0c\u542b\u6709\u6570\u5b57\uff0c\u542b\u6709\u5927\u5c0f\u5199\u5b57\u6bcd\uff0c\u542b\u6709\u7279\u6b8a\u5b57\u7b26\u7684\u5bc6\u78013\u4e2a\uff0c\u884c\u6253\u5370 pwgen -s -n -c -y -1 16 3 \u751f\u6210\u957f\u5ea680\uff0c\u4e0d\u542b\u5143\u97f3\u548c\u6570\u5b57\uff0c\u81f3\u5c11\u542b\u6709\u4e00\u4e2a\u5927\u5199\u5b57\u6bcd\uff0c\u884c\u6253\u5370 pwgen -s -v -c -0 80 1","title":"4.6.2.pwgen"},{"location":"linux/SRE/03-identity-security/#463","text":"\u65b9\u6cd51\uff1a $ echo -e '123456\\n123456' | sudo passwd tester1 New password: BAD PASSWORD: it is too simplistic/systematic BAD PASSWORD: is too simple Retype new password: passwd: password updated successfully \u65b9\u6cd52\uff1a Rocky\u4e2d\u53ef\u4ee5\u4f7f\u7528\u4e0b\u9762\u65b9\u6cd5\u3002 pwgen -ncy1 16 1 | tee passwd.txt | sudo passwd --stdin tester1 openSUSE\u548cUbuntu\u53ef\u4ee5\u7528\u4e0b\u9762\u65b9\u6cd5\u3002 echo \"tester1:\" ` pwgen -ncy1 16 1 ` | tee passwd.txt | sudo chpasswd \u65b9\u6cd53\uff1a\u6839\u636e\u9884\u5148\u7ed9\u5b9a\u7684\u7528\u6237\u5217\u8868\uff0c\u6279\u91cf\u751f\u6210\u5bc6\u7801\u3002 $ cat > user-list.txt < user.txt < file 67274683 lrwxrwxrwx. 1 vagrant wheel 12 Nov 1 11 :20 symlinkfile1-1 -> symlinkfile1 67274682 lrwxrwxrwx. 1 vagrant wheel 4 Nov 1 10 :43 symlinkfile2 -> file 33555262 drwxr-xr-x. 2 vagrant wheel 6 Nov 1 11 :30 typelink \u4ee5 67274680 -rw-r--r--. 3 vagrant wheel 31 Nov 1 11:14 file \u4e3a\u4f8b\uff1a 67274680 : inode \u7d22\u5f15\u8282\u70b9\u7f16\u53f7\u3002 -rw-r--r-- \uff1a\u6587\u4ef6\u7c7b\u578b\u53ca\u6743\u9650 - \uff1a\u6587\u4ef6\u7c7b\u578b\uff0c\u4f8b\u5b50\u4e2d\u51fa\u73b0\u4e86\u4e09\u79cd\uff0c - \uff0c l \u548c d \u3002 - \uff1a\u666e\u901a\u6587\u4ef6 d \uff1a\u76ee\u5f55 l \uff1a\u7b26\u53f7\u94fe\u63a5\u6587\u4ef6\uff08link\uff09 b \uff1a\u5757\u8bbe\u5907\uff08block\uff09 c \uff1a\u5b57\u7b26\u8bbe\u5907\uff08character\uff09 p \uff1a\u7ba1\u9053\u6587\u4ef6\uff08pipe\uff09 s \uff1a\u5957\u63a5\u5b57\u6587\u4ef6\uff08socket\uff09 rw-r--r-- \uff1a\u6587\u4ef6\u6743\u9650\uff0c\u4ece\u5de6\u5230\u53f3\u4f9d\u6b21\u4e3a\uff1a\uff08\u7528\u6237\u7684\u6700\u7ec8\u6743\u9650\uff0c\u662f\u4ece\u5de6\u5411\u53f3\u5339\u914d\uff0c\u4e00\u65e6\u5339\u914d\u5219\u6743\u9650\u7acb\u5373\u751f\u6548\uff0c\u4e0d\u518d\u5411\u53f3\u7ee7\u7eed\u5339\u914d\uff09 rw- \uff1a\u6587\u4ef6\u5c5e\u4e3b\u6743\u9650\uff08u\uff09\uff0c\u4f8b\u5b50\u4e2d\u662f vagrant \u3002 r-- \uff1a\u6587\u4ef6\u5c5e\u7ec4\u7684\u6743\u9650\uff08g\uff09\uff0c\u4f8b\u5b50\u4e2d\u662f wheel \u3002 r-- \uff1a\u5176\u4ed6\u7ec4\u7684\u6743\u9650\uff08o\uff09\u3002 . \uff1a\u8fd9\u4e2a\u70b9\u8868\u793a\u6587\u4ef6\u5e26\u6709SELinux\u7684\u5b89\u5168\u4e0a\u4e0b\u6587\uff08SELinux Contexts\uff09\u3002\u5173\u95edSELinux\uff0c\u65b0\u521b\u5efa\u7684\u6587\u4ef6\u5c31\u4e0d\u4f1a\u518d\u6709\u8fd9\u4e2a\u70b9\u4e86\u3002\u4f46\u662f\uff0c\u4ee5\u524d\u521b\u5efa\u7684\u6587\u4ef6\u672c\u6765\u6709\u8fd9\u4e2a\u70b9\u7684\u8fd8\u4f1a\u663e\u793a\u8fd9\u4e2a\u70b9\uff08\u867d\u7136SELinux\u4e0d\u8d77\u4f5c\u7528\u4e86\uff09\u3002 3 \uff1a\u786c\u94fe\u63a5\u6570\uff0c\u4f8b\u5b50\u4e2d file \u548c hardlinkfile1 \u548c hardlinkfile2 \u4e4b\u95f4\u662f\u786c\u94fe\u63a5\uff0c\u6240\u4ee5\u8fd9\u4e09\u4e2a\u6587\u4ef6\u7684\u786c\u94fe\u63a5\u6570\u90fd\u662f 3 \u3002 vagrant \uff1a\u6587\u4ef6\u5c5e\u4e3bowner wheel \uff1a\u6587\u4ef6\u5c5e\u7ec4group 31 \uff1a\u6587\u4ef6\u6216\u76ee\u5f55\u7684\u5927\u5c0f Nov 1 11:14 \uff1a\u6587\u4ef6\u6216\u76ee\u5f55\u7684\u521b\u5efa\u65e5\u671f\u548c\u65f6\u95f4 file \uff1a\u6587\u4ef6\u6216\u76ee\u5f55\u540d\u79f0 \u4e0b\u9762\u662f\u547d\u4ee4 ls -ihl \u5728openSUSE\u548cUbuntu\u4e0a\u7684\u663e\u793a\u7ed3\u679c\u3002 $ ls -ihl 233647 -rw-r--r-- 3 vagrant wheel 31 Nov 1 15 :52 file 233647 -rw-r--r-- 3 vagrant wheel 31 Nov 1 15 :52 hardlinkfile1 233647 -rw-r--r-- 3 vagrant wheel 31 Nov 1 15 :52 hardlinkfile2 233648 lrwxrwxrwx 1 vagrant wheel 4 Nov 1 15 :52 symlinkfile1 -> file 233650 lrwxrwxrwx 1 vagrant wheel 12 Nov 1 15 :52 symlinkfile1-1 -> symlinkfile1 233649 lrwxrwxrwx 1 vagrant wheel 4 Nov 1 15 :52 symlinkfile2 -> file 233646 drwxr-xr-x 1 vagrant wheel 0 Nov 1 15 :51 typelink","title":"7.\u6743\u9650\u7ba1\u7406"},{"location":"linux/SRE/03-identity-security/#71chown","text":"chown \u547d\u4ee4\u4fee\u6539\u6587\u4ef6\u5c5e\u4e3b\uff08\u6240\u6709\u8005\uff0cowner\uff09\u3002 \u4fee\u6539\u6587\u4ef6\u5c5e\u4e3b\u4e3aroot\u3002 $ ll f1.txt -rw-r--r--. 1 vagrant wheel 41 Nov 14 22 :23 f1.txt $ sudo chown root f1.txt $ ll f1.txt -rw-r--r--. 1 root wheel 41 Nov 14 22 :23 f1.txt \u4fee\u6539\u6587\u4ef6\u7684\u5c5e\u7ec4\u4e3abin\u3002 $ sudo chown :bin f1.txt $ ll f1.txt -rw-r--r--. 1 root bin 41 Nov 14 22 :23 f1.txt \u540c\u65f6\u4fee\u6539\u6587\u4ef6\u7684\u5c5e\u4e3b\u548c\u5c5e\u7ec4\u3002 $ sudo chown vagrant.wheel f1.txt $ ll f1.txt -rw-r--r--. 1 vagrant wheel 41 Nov 14 22 :23 f1.txt \u53c2\u7167\u67d0\u6587\u4ef6\u4fee\u6539\u53e6\u4e00\u6587\u4ef6\u7684\u5c5e\u6027\u3002 $ ll file.py -rw-r--r--. 1 vagrant wheel 56 Nov 13 22 :50 file.py $ ll user.txt -rw-r--r--. 1 root bin 21 Nov 27 23 :59 user.txt $ sudo chown root.bin user.txt $ sudo chown --reference = user.txt file.py $ ll file.py -rw-r--r--. 1 root bin 56 Nov 13 22 :50 file.py \u9012\u5f52\u4fee\u6539\u6240\u6709\u5b50\u76ee\u5f55\u53ca\u6587\u4ef6\u7684\u5c5e\u4e3b\u548c\u5c5e\u7ec4\u3002 sudo chown -R vagrant.wheel ~","title":"7.1.\u4fee\u6539\u5c5e\u4e3bchown"},{"location":"linux/SRE/03-identity-security/#72chgrp","text":"\u4fee\u6539\u76ee\u5f55\u7684\u5c5e\u7ec4\u3002 sudo chgrp bin ~~ \u4fee\u6539\u76ee\u5f55\u53ca\u5b50\u76ee\u5f55\u53ca\u6587\u4ef6\u7684\u5c5e\u7ec4\u3002 sudo chgrp -R bin ~~","title":"7.2.\u4fee\u6539\u5c5e\u7ec4chgrp"},{"location":"linux/SRE/03-identity-security/#73","text":"\u6587\u4ef6\uff1a r \uff1a\u53ef\u4ee5\u8bfb\u53d6\u8be5\u6587\u4ef6\u5185\u5bb9\uff0c\u6bd4\u5982\u901a\u8fc7 cat \u547d\u4ee4\u3002 w \uff1a\u53ef\u4ee5\u4fee\u6539\u8be5\u6587\u4ef6\u5185\u5bb9\uff0c\u53ef\u4ee5\u53ea\u6709 w \u800c\u6ca1\u6709 r \u3002 x \uff1a\u53ef\u4ee5\u628a\u8be5\u6587\u4ef6\u63d0\u8bf7\u5185\u6838\u542f\u52a8\u4e3a\u4e00\u4e2a\u8fdb\u7a0b\uff0c\u5373\u53ef\u4ee5\u6267\u884c\u8be5\u6587\u4ef6\uff08\u8be5\u6587\u4ef6\u7684\u5185\u5bb9\u5fc5\u987b\u662f\u53ef\u4ee5\u6267\u884c\uff09\u3002 \u76ee\u5f55\uff1a\uff08\u5bf9\u76ee\u5f55\u800c\u8a00\uff0c\u901a\u5e38\u9700\u8981\u7ed9 r \u548c x \u6743\u9650\uff09\uff08\u4ece\u76ee\u5f55\u89d2\u5ea6\u770b\uff0c\u76ee\u5f55\u5185\u6587\u4ef6\u5217\u8868\u7b49\u4e8e\u76ee\u5f55\u8282\u70b9\u7684\u5185\u5bb9\uff09 r \uff1a\u80fd\u770b\u6587\u4ef6\u5217\u8868\uff0c\u4f46\u4e0d\u80fd\u8bbf\u95ee\u6240\u542b\u6587\u4ef6\u7684\u5185\u5bb9\u53ca\u5176\u5c5e\u6027\u4fe1\u606f\uff0c\u5305\u62ecinode\u53f7\u3002 w \uff1a\u80fd\u5728\u8be5\u76ee\u5f55\u5185\u521b\u5efa\u548c\u5220\u9664\u6587\u4ef6\uff0c\u4e0d\u7531\u76ee\u5f55\u5185\u6587\u4ef6\u672c\u8eab\u7684\u6743\u9650\u51b3\u5b9a\u3002 x \uff1a\u80fdcd\u8fdb\u76ee\u5f55\uff0c\u80fd\u901a\u8fc7 ls -l file \u548c stat file \u67e5\u770b\u8be5\u76ee\u5f55\u4e2d\u5236\u5b9a\u6587\u4ef6\u7684\u5143\u6570\u636e\u3002 X \uff1a\u8868\u793a\u53ea\u6709\u5f53\u8be5\u6587\u4ef6\u662f\u4e2a\u5b50\u76ee\u5f55\u6216\u8005\u8be5\u6587\u4ef6\u5df2\u7ecf\u88ab\u8bbe\u5b9a\u8fc7\u4e3a\u53ef\u6267\u884c\u3002 \u6709\u53ea\u8bfb\u6743\u9650\u7684\u7528\u6237\u4e0d\u80fd\u7528cd\u8fdb\u5165\u8be5\u76ee\u5f55\uff0c\u8fd8\u5fc5\u987b\u6709\u6267\u884c\u6743\u9650\u624d\u80fd\u8fdb\u5165\u3002 \u6709\u6267\u884c\u6743\u9650\u7684\u7528\u6237\u53ea\u6709\u5728\u77e5\u9053\u6587\u4ef6\u540d\uff0c\u5e76\u62e5\u6709\u8bfb\u6743\u5229\u7684\u60c5\u51b5\u4e0b\u624d\u53ef\u4ee5\u8bbf\u95ee\u76ee\u5f55\u4e0b\u7684\u6587\u4ef6\u3002 \u5fc5\u987b\u6709\u8bfb\u548c\u6267\u884c\u6743\u9650\u624d\u53ef\u4ee5ls\u5217\u51fa\u76ee\u5f55\u6e05\u5355\uff0c\u6216\u4f7f\u7528cd\u547d\u4ee4\u8fdb\u5165\u76ee\u5f55\u3002 \u6709\u76ee\u5f55\u7684\u5199\u6743\u9650\uff0c\u53ef\u4ee5\u521b\u5efa\u3001\u5220\u9664\u6216\u4fee\u6539\u76ee\u5f55\u4e0b\u7684\u4efb\u4f55\u6587\u4ef6\u6216\u5b50\u76ee\u5f55\uff0c\u5373\u4f7f\u4f7f\u8be5\u6587\u4ef6\u6216\u5b50\u76ee\u5f55\u5c5e\u4e8e\u5176\u4ed6\u7528\u6237\u4e5f\u662f\u5982\u6b64\u3002 \u5e38\u7528\u6743\u9650\u4f8b\u5b50\uff1a -rw------- ( 600 ) \u53ea\u6709\u6240\u6709\u8005\u624d\u6709\u8bfb\u548c\u5199\u7684\u6743\u9650 -rw-r--r-- ( 644 ) \u53ea\u6709\u6240\u6709\u8005\u624d\u6709\u8bfb\u548c\u5199\u7684\u6743\u9650\uff0c\u7ec4\u548c\u5176\u4ed6\u4eba\u53ea\u6709\u8bfb\u7684\u6743\u9650 -rwx------ ( 700 ) \u53ea\u6709\u6240\u6709\u8005\u624d\u6709\u8bfb\uff0c\u5199\uff0c\u6267\u884c\u7684\u6743\u9650 -rwxr-xr-x ( 755 ) \u53ea\u6709\u6240\u6709\u8005\u624d\u6709\u8bfb\uff0c\u5199\uff0c\u6267\u884c\u7684\u6743\u9650\uff0c\u7ec4\u548c\u5176\u4ed6\u4eba\u53ea\u6709\u8bfb\u548c\u6267\u884c\u7684\u6743\u9650 -rwx--x--x ( 711 ) \u53ea\u6709\u6240\u6709\u8005\u624d\u6709\u8bfb\uff0c\u5199\uff0c\u6267\u884c\u7684\u6743\u9650\uff0c\u7ec4\u548c\u5176\u4ed6\u4eba\u53ea\u6709\u6267\u884c\u7684\u6743\u9650 -rw-rw-rw- ( 666 ) \u6bcf\u4e2a\u4eba\u90fd\u6709\u8bfb\u5199\u7684\u6743\u9650 -rwxrwxrwx ( 777 ) \u6bcf\u4e2a\u4eba\u90fd\u6709\u8bfb\u5199\u548c\u6267\u884c\u7684\u6743\u9650","title":"7.3.\u6587\u4ef6\u548c\u76ee\u5f55\u6743\u9650"},{"location":"linux/SRE/03-identity-security/#74chmod","text":"\u547d\u4ee4\u683c\u5f0f\uff1a chmod [ -cfvR ] [ --help ] [ --version ] mode file mode \u5b57\u4e32\u683c\u5f0f\u4e3a\uff1a [ ugoa ][ +- =][ rwxXst ] who: u \u6587\u4ef6\u6240\u6709\u8005 g \u6587\u4ef6\u6240\u6709\u8005\u6240\u5728\u7ec4 o \u5176\u4ed6\u7528\u6237 a \u6240\u6709\u7528\u6237\uff0c\u76f8\u5f53\u4e8e ugo operator: + \u4e3a\u6307\u5b9a\u7684\u7528\u6237\u7c7b\u578b\u589e\u52a0\u6743\u9650 - \u53bb\u9664\u6307\u5b9a\u7528\u6237\u7c7b\u578b\u7684\u6743\u9650 = \u8bbe\u7f6e\u6307\u5b9a\u7528\u6237\u6743\u9650\u7684\u8bbe\u7f6e\uff0c\u5373\u5c06\u7528\u6237\u7c7b\u578b\u7684\u6240\u6709\u6743\u9650\u91cd\u65b0\u8bbe\u7f6e permission: r \u8bbe\u7f6e\u4e3a\u53ef\u8bfb\u6743\u9650 w \u8bbe\u7f6e\u4e3a\u53ef\u5199\u6743\u9650 x \u8bbe\u7f6e\u4e3a\u53ef\u6267\u884c\u6743\u9650 X \u7279\u6b8a\u6267\u884c\u6743\u9650\uff0c\u53ea\u6709\u5f53\u6587\u4ef6\u4e3a\u76ee\u5f55\u6587\u4ef6\uff0c\u6216\u8005\u5176\u4ed6\u7c7b\u578b\u7684\u7528\u6237\u6709\u53ef\u6267\u884c\u6743\u9650\u65f6\uff0c\u624d\u5c06\u6587\u4ef6\u6743\u9650\u8bbe\u7f6e\u53ef\u6267\u884c s \u5f53\u6587\u4ef6\u88ab\u6267\u884c\u65f6\uff0c\u6839\u636ewho\u53c2\u6570\u6307\u5b9a\u7684\u7528\u6237\u7c7b\u578b\u8bbe\u7f6e\u6587\u4ef6\u7684 setuid \u6216\u8005 setgid \u6743\u9650 t \u8bbe\u7f6e\u7c98\u8d34\u4f4d\uff0c\u53ea\u6709\u8d85\u7ea7\u7528\u6237\u53ef\u4ee5\u8bbe\u7f6e\u8be5\u4f4d\uff0c\u53ea\u6709\u6587\u4ef6\u6240\u6709\u8005u\u53ef\u4ee5\u4f7f\u7528\u8be5\u4f4d\u3002 \u793a\u4f8b\uff1a \u5c06\u6587\u4ef6 file1.txt \u8bbe\u4e3a\u6240\u6709\u4eba\u7686\u53ef\u8bfb\u53d6\u3002 chmod ugo+r file1.txt \u5c06\u6587\u4ef6 file1.txt \u8bbe\u4e3a\u6240\u6709\u4eba\u7686\u53ef\u8bfb\u53d6\u3002 chmod a+r file1.txt \u5c06\u6587\u4ef6 file1.txt \u4e0e file2.txt \u8bbe\u4e3a\u8be5\u6587\u4ef6\u5c5e\u4e3b\u548c\u5c5e\u7ec4\u90fd\u53ef\u5199\u5165\uff0c\u4f46\u5176\u4ed6\u7528\u6237\u4e0d\u53ef\u5199\u5165\u3002 chmod ug+w,o-w file1.txt file2.txt \u4e3a ex1.py \u6587\u4ef6\u5c5e\u4e3b\u589e\u52a0\u53ef\u6267\u884c\u6743\u9650\u3002 chmod u+x ex1.py \u5c06\u76ee\u524d\u76ee\u5f55\u4e0b\u7684\u6240\u6709\u6587\u4ef6\u4e0e\u5b50\u76ee\u5f55\u7686\u8bbe\u4e3a\u4efb\u4f55\u4eba\u53ef\u8bfb\u53d6\u3002 chmod -R a+r * \u7ed9 file \u7684\u6240\u6709\u7528\u6237\u589e\u52a0\u8bfb\u6743\u9650 chmod a+r file \u5220\u9664 file \u7684\u6240\u6709\u7528\u6237\u7684\u6267\u884c\u6743\u9650 chmod a-x file \u7ed9 file \u7684\u6240\u6709\u7528\u6237\u589e\u52a0\u8bfb\u5199\u6743\u9650 chmod a+rw file \u7ed9 file \u7684\u6240\u6709\u7528\u6237\u589e\u52a0\u8bfb\u5199\u6267\u884c\u6743\u9650 chmod +rwx file \u5bf9 file \u7684\u5c5e\u4e3b\u8bbe\u7f6e\u8bfb\u5199\u6743\u9650\uff0c\u6e05\u7a7a\u5c5e\u7ec4\u548c\u5176\u4ed6\u7528\u6237\u5bf9 file \u7684\u6240\u6709\u6743\u9650\uff08\u7a7a\u683c\u4ee3\u8868\u65e0\u6743\u9650\uff09 chmod u = rw,go = file \u5bf9\u76ee\u5f55 docs \u548c\u5176\u5b50\u76ee\u5f55\u4e2d\u7684\u6240\u6709\u6587\u4ef6\u7ed9\u5c5e\u4e3b\u589e\u52a0\u8bfb\u6743\u9650\uff0c\u800c\u5bf9\u5c5e\u7ec4\u548c\u5176\u4ed6\u7528\u6237\u5220\u9664\u8bfb\u6743\u9650 chmod -R u+r,go-r docs \u5bf9 file \u7684\u5c5e\u4e3b\u548c\u5c5e\u7ec4\u8bbe\u7f6e\u8bfb\u5199\u6743\u9650, \u4e3a\u5176\u4ed6\u7528\u6237\u8bbe\u7f6e\u8bfb\u6743\u9650 chmod 664 file \u5bf9 file \u7684\u5c5e\u4e3b\u8bbe\u7f6e\u8bfb\u5199\u6267\u884c\u6743\u9650\uff0c\u76f8\u5f53\u4e8e u=rwx (4+2+1)\uff0c\u8bbe\u7f6e\u5c5e\u7ec4\u8bfb\u548c\u6267\u884c\u6743\u9650\uff0c\u76f8\u5f53\u4e8e go=rx (4+1 & 4+1)\u3002 0 \u6ca1\u6709\u7279\u6b8a\u6a21\u5f0f chmod 0755 file 4 \u8bbe\u7f6e\u4e86\u8bbe\u7f6e\u7528\u6237ID\u4f4d\uff0c\u5269\u4e0b\u7684\u76f8\u5f53\u4e8e u=rwx (4+2+1)\u548c go=rx (4+1 & 4+1)\u3002 chmod 4755 file \u5220\u9664\u53ef\u6267\u884c\u6743\u9650\u5bf9 path/ \u4ee5\u53ca\u5176\u6240\u6709\u7684\u76ee\u5f55\uff08\u4e0d\u5305\u62ec\u6587\u4ef6\uff09\u7684\u6240\u6709\u7528\u6237\uff0c\u4f7f\u7528 -type f \u5339\u914d\u6587\u4ef6 find path/ -type d -exec chmod a-x {} \\; \u5141\u8bb8\u6240\u6709\u7528\u6237\u6d4f\u89c8\u6216\u901a\u8fc7\u76ee\u5f55 path/ find path/ -type d -exec chmod a+x {} \\;","title":"7.4.\u6743\u9650\u4fee\u6539chmod"},{"location":"linux/SRE/03-identity-security/#75umask","text":"umask \u7684\u503c\uff0c\u5b9a\u4e49\u4e86\u6240\u6709\u65b0\u5efa\u7684\u6587\u4ef6\u548c\u76ee\u5f55\u7684\u521d\u59cb\u6743\u9650\u7684\u3002 \u67e5\u770b\u5f53\u524d\u6743\u9650\u63a9\u7801\uff1a $ umask 0022 \u5728\u4e0d\u8003\u8651 umask \u7684\u60c5\u51b5\u4e0b\uff0c\u6587\u4ef6\u7684\u9ed8\u8ba4\u6743\u9650\u662f 666 (rw-rw-rw-)\uff0c\u76ee\u5f55\u7684\u9ed8\u8ba4\u6743\u9650\u662f 777 (rwxrwxrwx)\u3002 \u5728 umask \u7684\u503c\u4e3a 0022 \u7684\u60c5\u51b5\u4e0b\uff0c\u6587\u4ef6\u7684\u9ed8\u8ba4\u6743\u9650\u662f 644 (rw-r--r--)\uff0c\u76ee\u5f55\u7684\u9ed8\u8ba4\u6743\u9650\u662f 755 (rwxr-xr-x)\u3002 \u8ba1\u7b97\u65b9\u6cd5\uff1a Files: ( Default ) 6 6 6 ( umask ) 0 2 2 ---------------- ( Result ) 6 4 4 Directories: ( Default ) 7 7 7 ( umask ) 0 2 2 ---------------- ( Result ) 7 5 5 \u5982\u679c umask \u7684\u503c\u4e3a 0077 \u7684\u60c5\u51b5\u4e0b\uff0c\u6587\u4ef6\u7684\u9ed8\u8ba4\u6743\u9650\u662f 600 (rw-------)\uff0c\u76ee\u5f55\u7684\u9ed8\u8ba4\u6743\u9650\u662f 700 (rwx------)\u3002 \u8ba1\u7b97\u65b9\u6cd5\uff1a Files: ( Default ) 6 6 6 ( umask ) 0 7 7 ---------------- ( Result ) 6 0 0 Directories: ( Default ) 7 7 7 ( umask ) 0 7 7 ---------------- ( Result ) 7 0 0 \u4e3e\u4f8b\uff1a $ umask 022 $ touch file2 $ ll file2 -rw-r--r--. 1 vagrant wheel 0 Nov 28 23 :13 file2 $ umask 077 $ touch file1 $ ll file1 -rw-------. 1 vagrant wheel 0 Nov 28 23 :12 file1 $ umask 022 $ mkdir ./tmp1 $ umask 077 $ mkdir ./tmp2 $ ls -dl tmp* drwxr-xr-x. 1 vagrant wheel 0 Nov 28 23 :14 tmp1 drwx------. 1 vagrant wheel 0 Nov 28 23 :14 tmp2","title":"7.5.\u9ed8\u8ba4\u6743\u9650umask"},{"location":"linux/SRE/03-identity-security/#76","text":"\u9664\u4e86\u4e09\u79cd\u5e38\u89c1\u7684\u6743\u9650rwx\uff0c\u8fd8\u6709\u4e09\u79cd\u7279\u6b8a\u6743\u9650\uff1aSUID\uff0cSGID\uff0cSticky\u3002 SUID\uff1a\u5c5e\u4e3bs\u6743\u9650\uff0c\u79f0\u4e3aSet UID \u524d\u63d0\uff1a\u8fdb\u7a0b\u6709\u5c5e\u4e3b\u548c\u5c5e\u7ec4\uff0c\u6587\u4ef6\u6709\u5c5e\u4e3b\u548c\u5c5e\u7ec4 \u4efb\u4f55\u53ef\u6267\u884c\u7a0b\u5e8f\u6587\u4ef6\u80fd\u4e0d\u80fd\u542f\u52a8\u4e3a\u8fdb\u7a0b\uff0c\u53d6\u51b3\u4e8e\u53d1\u8d77\u8005\u5bf9\u7a0b\u5e8f\u6587\u4ef6\u662f\u5426\u62e5\u6709\u6267\u884c\u6743\u9650\u3002 \u542f\u52a8\u4e3a\u8fdb\u7a0b\u4e4b\u540e\uff0c\u5176\u8fdb\u7a0b\u7684\u5c5e\u4e3b\u4e3a\u53d1\u8d77\u8005\u3002 \u8fdb\u7a0b\u8bbf\u95ee\u6587\u4ef6\u662f\u7684\u6743\u9650\uff0c\u53d6\u51b3\u4e8e\u8fdb\u7a0b\u7684\u53d1\u8d77\u8005\u3002 \u53ea\u5bf9\u4e8c\u8fdb\u5236\u53ef\u6267\u884c\u7a0b\u5e8f\u6587\u4ef6\u6709\u6548\u3002\u5f53\u6267\u884c\u8be5\u6587\u4ef6\u65f6\uff0c\u53d1\u8d77\u8005\u5c06\u81ea\u52a8\u5177\u6709\u8be5\u6587\u4ef6\u6240\u6709\u8005\u7684\u6743\u9650\u3002 \u5bf9\u76ee\u5f55\u65e0\u6548\u3002 $ ll file1 -rw-------. 1 vagrant wheel 0 Nov 28 23 :12 file1 $ sudo chmod u+s file1 $ ll file1 -rwS------. 1 vagrant wheel 0 Nov 28 23 :12 file1 \u5982\u679c\u5c5e\u4e3b\u7684 x \u4f4d\u4e0a\u662f-\uff0c\u5219\u5728\u5c5e\u4e3b\u7684 x \u4f4d\u4e0a\u6807\u8bb0\u5927\u5199 S \uff0c\u5426\u5219\u6807\u8bb0\u5c0f\u5199 s \u3002\u5982\u4e0b\uff1a $ chmod 777 file1 $ ll file1 -rwxrwxrwx. 1 vagrant wheel 0 Nov 28 23 :12 file1 $ sudo chmod u+s file1 $ ll file1 -rwsrwxrwx. 1 vagrant wheel 0 Nov 28 23 :12 file1 \u4e0b\u97622\u7ec4\u547d\u4ee4\u5b9e\u73b0\u540c\u6837\u6548\u679c\u3002 sudo chmod 4xxx file1 chmod 777 file1 sudo chmod u+s file1 \u53d6\u6d88SUID\u3002 sudo chmod u-s file1 SGID\uff1a\u5c5e\u7ec4s\u6743\u9650\uff0c\u79f0\u4e3aSet GID \u5982\u679c\u4f5c\u7528\u4e8e\u4e8c\u8fdb\u5236\u53ef\u6267\u884c\u6587\u4ef6\u4e0a\uff0c\u5f53\u6267\u884c\u8be5\u6587\u4ef6\u4e3a\u8fdb\u7a0b\u4e4b\u540e\uff0c\u53d1\u8d77\u8005\u5c06\u81ea\u52a8\u5177\u6709\u8be5\u6587\u4ef6\u6240\u5c5e\u7ec4\u7684\u6743\u9650\uff0c\u8fdb\u7a0b\u7684\u5c5e\u7ec4\u4e3a\u53d1\u8d77\u8005\u7684\u5c5e\u7ec4\u3002 \u5982\u679c\u4f5c\u7528\u4e8e\u76ee\u5f55\u4e0a\uff0c\u5219\u8be5\u76ee\u5f55\u4e0b\u65b0\u5efa\u7acb\u7684\u76ee\u5f55\u548c\u6587\u4ef6\u90fd\u81ea\u52a8\u4ece\u6b64\u76ee\u5f55\u7ee7\u627f\u3002 $ sudo chmod g+s file2 $ ll file2 -rw-r-Sr--. 1 vagrant wheel 0 Nov 28 23 :13 file2 \u5982\u679c\u5c5e\u7ec4\u7684 x \u4f4d\u4e0a\u662f-\uff0c\u5219\u5728\u5c5e\u7ec4\u7684 x \u4f4d\u4e0a\u6807\u8bb0\u5927\u5199 S \uff0c\u5426\u5219\u6807\u8bb0\u5c0f\u5199 s \u3002\u5982\u4e0b\uff1a $ chmod 777 file2 $ ll file2 -rwxrwxrwx. 1 vagrant wheel 0 Nov 28 23 :13 file2 $ sudo chmod g+s file2 $ ll file2 -rwxrwsrwx. 1 vagrant wheel 0 Nov 28 23 :13 file2 \u4e0b\u97622\u7ec4\u547d\u4ee4\u5b9e\u73b0\u540c\u6837\u6548\u679c\u3002 sudo chmod 2xxx file2 chmod 777 file2 sudo chmod g+s file2 \u53d6\u6d88SGID\u3002 sudo chmod g-s file2 \u5bf9\u4e8e\u76ee\u5f55\uff0c\u4e0b\u9762\u6f14\u793a\u53ef\u4ee5\u770b\u5230\u76ee\u5f55\u4e0b\u7684\u6587\u4ef6\u548c\u5b50\u76ee\u5f55\u7684\u7ee7\u627f\u6027\u3002 $ ll -d data drwxr-xr-x. 1 vagrant bin 0 Nov 28 20 :55 data $ sudo chmod g+s .~ $ ll -d data drwxr-sr-x. 1 vagrant bin 0 Nov 28 20 :55 data $ cd data $ touch file2 $ ll file2 -rw-r--r--. 1 vagrant bin 0 Nov 29 21 :10 file2 $ mkdir tmp3 $ ll -d tmp3 drwxr-sr-x. 1 vagrant bin 0 Nov 29 21 :10 tmp3 Sticky Bit\uff1a\u7b80\u79f0\u4e3aSBIT\u6743\u9650 \u53ea\u9488\u5bf9\u76ee\u5f55\u6709\u6548\u3002\u5b83\u8868\u793a\u53ea\u80fd\u8ba9\u5176\u5c5e\u4e3b\u4ee5\u53caroot\u53ef\u4ee5\u5220\u9664\u3001\u91cd\u547d\u540d\u3001\u79fb\u52a8\u8be5\u76ee\u5f55\u4e0b\u7684\u6587\u4ef6\u3002 Sticky\u8bbe\u7f6e\u5728\u6587\u4ef6\u4e0a\u65e0\u610f\u4e49\u3002 \u5982\u679c\u5176\u4ed6\u7684 x \u4f4d\u4e0a\u662f-\uff0c\u5219\u5728\u5176\u4ed6\u7684 x \u4f4d\u4e0a\u6807\u8bb0\u5927\u5199 T \uff0c\u5426\u5219\u6807\u8bb0\u5c0f\u5199 t \u3002 $ ll -d .~ drwxr-sr-x. 1 vagrant bin 18 Nov 29 21 :10 .~ $ sudo chmod o+t .~ $ ll -d .~ drwxr-sr-t. 1 vagrant bin 18 Nov 29 21 :10 .~ $ cd data $ touch file1 $ mkdir tmp1 $ ll file1 -rw-r--r--. 1 vagrant bin 0 Nov 29 21 :37 file1 $ ll -d tmp1 drwxr-sr-x. 1 vagrant bin 0 Nov 29 21 :37 tmp1 \u7279\u6b8a\u6743\u9650\u8bbe\u7f6e\u6570\u5b57\u6cd5\uff1a \u8bbe\u7f6eSUID User Group Others r w s r w s r w x r w S BIN 100 1 1 1 1 1 1 1 1 1 1 1 0 OCT 4 7 7 7 6 \u8bbe\u7f6eSGID User Group Others r w x r w s r w x r w S BIN 010 1 1 1 1 1 1 1 1 1 1 1 0 OCT 2 7 7 7 6 \u8bbe\u7f6eSticky Bit - SBIT User Group Others r w x r w x r w t r w T BIN 001 1 1 1 1 1 1 1 1 1 1 1 0 OCT 1 7 7 7 6","title":"7.6.\u7279\u6b8a\u6743\u9650"},{"location":"linux/SRE/03-identity-security/#77chattr","text":"\u547d\u4ee4\u683c\u5f0f\uff1a chattr [ -RVf ] [ -v version ] [ mode ] files... \u5176\u4e2dmode\u7684\u5b57\u4e32\u683c\u5f0f\uff1a {+|-|=}[aAcCdDeijsStTu] \u5c5e\u6027 i \uff1a \u5982\u679c\u5bf9\u6587\u4ef6\u8bbe\u7f6e i \u5c5e\u6027\uff0c\u90a3\u4e48\u4e0d\u5141\u8bb8\u5bf9\u6587\u4ef6\u8fdb\u884c\u5220\u9664\u3001\u6539\u540d\uff0c\u4e5f\u4e0d\u80fd\u6dfb\u52a0\u548c\u4fee\u6539\u6570\u636e\uff1b \u5982\u679c\u5bf9\u76ee\u5f55\u8bbe\u7f6e i \u5c5e\u6027\uff0c\u90a3\u4e48\u53ea\u80fd\u4fee\u6539\u76ee\u5f55\u4e0b\u6587\u4ef6\u4e2d\u7684\u6570\u636e\uff0c\u4f46\u4e0d\u5141\u8bb8\u5efa\u7acb\u548c\u5220\u9664\u6587\u4ef6\uff1b \u5728openSUSE\u4e0b\u6267\u884c\uff0c\u5206\u533a\u6587\u4ef6\u7c7b\u578b\u662fbtrfs\u683c\u5f0f\u3002 $ touch filetest $ lsattr filetest ---------------------- filetest $ chattr +i filetest chattr: Operation not permitted while setting flags on filetest $ sudo chattr +i filetest $ lsattr filetest ----i----------------- filetest $ rm filetest rm: cannot remove 'filetest' : Operation not permitted $ sudo rm filetest rm: cannot remove 'filetest' : Operation not permitted $ echo \"test\" >> filetest -bash: filetest: Operation not permitted $ sudo echo \"test\" >> filetest -bash: filetest: Operation not permitted $ sudo chattr -i filetest \u5c5e\u6027 a \uff1a \u5982\u679c\u5bf9\u6587\u4ef6\u8bbe\u7f6e a \u5c5e\u6027\uff0c\u90a3\u4e48\u53ea\u80fd\u5728\u6587\u4ef6\u4e2d\u5897\u52a0\u6570\u636e\uff0c\u4f46\u662f\u4e0d\u80fd\u5220\u9664\u548c\u4fee\u6539\u6570\u636e\uff1b \u5982\u679c\u5bf9\u76ee\u5f55\u8bbe\u7f6e a \u5c5e\u6027\uff0c\u90a3\u4e48\u53ea\u5141\u8bb8\u5728\u76ee\u5f55\u4e2d\u5efa\u7acb\u548c\u4fee\u6539\u6587\u4ef6\uff0c\u4f46\u662f\u4e0d\u5141\u8bb8\u5220\u9664\u6587\u4ef6\uff1b \u5728openSUSE\u4e0b\u6267\u884c\uff0c\u5206\u533a\u6587\u4ef6\u7c7b\u578b\u662fbtrfs\u683c\u5f0f\u3002 lsattr filetest ---------------------- filetest $ chattr +a filetest chattr: Operation not permitted while setting flags on filetest $ sudo chattr +a filetest $ echo \"test\" >> filetest $ rm filetest rm: cannot remove 'filetest' : Operation not permitted $ sudo rm filetest rm: cannot remove 'filetest' : Operation not permitted $ sudo chattr -a filetest \u5c5e\u6027 u \uff1a \u8bbe\u7f6e\u6b64\u5c5e\u6027\u7684\u6587\u4ef6\u6216\u76ee\u5f55\uff0c\u5728\u5220\u9664\u65f6\uff0c\u5176\u5185\u5bb9\u4f1a\u88ab\u4fdd\u5b58\uff0c\u4ee5\u4fdd\u8bc1\u540e\u671f\u80fd\u591f\u6062\u590d\uff0c\u5e38\u7528\u6765\u9632\u6b62\u610f\u5916\u5220\u9664\u6587\u4ef6\u6216\u76ee\u5f55\u3002 \u5728Ubuntu\u4e0b\u6267\u884c\uff0c\u5206\u533a\u6587\u4ef6\u7c7b\u578b\u662fext4\u683c\u5f0f\u3002 $ touch filetest $ sudo chattr +u filetest $ lsattr filetest -u------------e------- filetest $ rm filetest \u5c5e\u6027 s \uff1a \u548c u \u76f8\u53cd\uff0c\u5220\u9664\u6587\u4ef6\u6216\u76ee\u5f55\u65f6\uff0c\u4f1a\u88ab\u5f7b\u5e95\u5220\u9664\uff08\u76f4\u63a5\u4ece\u786c\u76d8\u4e0a\u5220\u9664\uff0c\u7136\u540e\u75280\u586b\u5145\u6240\u5360\u7528\u7684\u533a\u57df\uff09\uff0c\u4e0d\u53ef\u6062\u590d\u3002 \u63d0\u793a\uff1a \u547d\u4ee4 chattr \u548c lsattr \u7684\u53ef\u64cd\u4f5c\u5c5e\u6027\u4f9d\u8d56\u4e8e\u6587\u4ef6\u6240\u5904\u5206\u533a\u7684\u6587\u4ef6\u7cfb\u7edf\u7c7b\u578b\uff0c\u4f8b\u5982\uff0cext4\u548cxfs\u7684\u7ed3\u679c\u4f1a\u6709\u4e0d\u540c\u3002 \u5386\u53f2\uff1a\u547d\u4ee4 chattr \uff08\u7528\u4e8e\u64cd\u4f5c\u5c5e\u6027\uff09\u548c lsattr \uff08\u7528\u4e8e\u5217\u51fa\u5c5e\u6027\uff09\u6700\u521d\u4e13\u7528\u4e8e\u7b2c\u4e8c\u4e2a\u6269\u5c55\u6587\u4ef6\u7cfb\u7edf\u7cfb\u5217\uff08ext2\u3001ext3\u3001ext4\uff09\uff0c\u5e76\u4e14\u4f5c\u4e3a e2fsprogs \u5305\u7684\u4e00\u90e8\u5206\u63d0\u4f9b\u3002\u7136\u800c\uff0c\u6b64\u529f\u80fd\u5df2\u5168\u90e8\u6216\u90e8\u5206\u6269\u5c55\u5230\u8bb8\u591a\u5176\u4ed6\u7cfb\u7edf\uff0c\u5305\u62ec XFS\u3001ReiserFS\u3001JFS \u548c OCFS2\u3002 btrfs \u6587\u4ef6\u7cfb\u7edf\u5305\u62ec\u5c5e\u6027\u529f\u80fd\uff0c\u5305\u62ec C \u6807\u5fd7\uff0c\u7531\u4e8e\u4e0e CoW \u76f8\u5173\u7684\u6027\u80fd\u8f83\u6162\uff0c\u5b83\u5173\u95ed\u4e86btrfs\u7684\u5185\u7f6e\u5199\u65f6\u590d\u5236 (CoW) \u529f\u80fd\u3002","title":"7.7.\u8bbe\u5b9a\u6587\u4ef6\u7279\u6b8a\u5c5e\u6027chattr"},{"location":"linux/SRE/03-identity-security/#8acl","text":"","title":"8.\u8bbf\u95ee\u63a7\u5236\u5217\u8868ACL"},{"location":"linux/SRE/03-identity-security/#81acl","text":"ACL\u7684\u5168\u79f0\u662fAccess Control List\u3002 \u4f20\u7edf\u7684POSIX\u6743\u9650\u6982\u5ff5\u4f7f\u7528\u4e09\u79cd\u7528\u6237\u7c7b\u578b\u6765\u5206\u914d\u6587\u4ef6\u7cfb\u7edf\u4e2d\u7684\u6743\u9650\uff1a\u6240\u6709\u8005Owning Owner\uff0c\u6240\u6709\u8005\u7ec4Owning Group\u548c\u5176\u4ed6\u7528\u6237Other Users\u3002\u53ef\u4ee5\u4e3a\u6bcf\u4e2a\u7528\u6237\u7c7b\u578b\u8bbe\u7f6e\u4e09\u4e2a\u6743\u9650\u4f4d\uff0c\u8d4b\u4e88\u8bfb\uff08r\uff09\uff0c\u5199\uff08w\uff09\u548c\u6267\u884c\uff08x\uff09\u7684\u6743\u9650\u3002 \u6240\u6709\u8005Owning Owner\u6743\u9650\uff08\u5c5e\u4e3b\u6743\u9650\uff09 \u5c5e\u7ec4Owning Group\u6743\u9650 \u5176\u4ed6\uff08\u7ecf\u8fc7\u8eab\u4efd\u9a8c\u8bc1\u7684\uff09\u7528\u6237Other Users\u7684\u6743\u9650 \u4f20\u7edf\u7684\u4e09\u79cd\u6743\u9650\u9002\u7528\u4e8e\u5927\u591a\u6570\u5b9e\u9645\u6848\u4f8b\u3002\u4f46\u662f\uff0c\u5bf9\u4e8e\u66f4\u590d\u6742\u7684\u573a\u666f\u6216\u66f4\u9ad8\u7ea7\u7684\u5e94\u7528\u7a0b\u5e8f\uff0c\u7cfb\u7edf\u7ba1\u7406\u5458\u5fc5\u987b\u4f7f\u7528\u8bb8\u591a\u6280\u5de7\u6765\u89c4\u907f\u4f20\u7edf\u6743\u9650\u7684\u9650\u5236\u3002 \u8bbf\u95ee\u63a7\u5236\u5217\u8868ACL\u63d0\u4f9b\u4e86\u5bf9\u4f20\u7edf\u6587\u4ef6\u6743\u9650\u6982\u5ff5\u7684\u6269\u5c55\u3002\u5b83\u4eec\u5141\u8bb8\u6211\u4eec\u4e3a\u5355\u4e2a\u7528\u6237\u6216\u7ec4\u5206\u914d\u6743\u9650\uff0c\u5373\u4f7f\u8fd9\u4e9b\u7528\u6237\u6216\u7ec4\u4e0e\u539f\u59cb\u6240\u6709\u8005\u6216\u5c5e\u7ec4\u4e0d\u5bf9\u5e94\u3002 ACL\u662fLinux\u5185\u6838\u7684\u4e00\u9879\u529f\u80fd\uff0c\u652f\u6301Ext\u2154/4\uff0cXFS\u548cBtrFS\u6587\u4ef6\u7cfb\u7edf\u4ee5\u53ca\u5176\u4ed6\u6587\u4ef6\u7cfb\u7edf\u3002 \u4f7f\u7528ACL\uff0c\u6211\u4eec\u53ef\u4ee5\u521b\u5efa\u590d\u6742\u7684\u65b9\u6848\uff0c\u800c\u65e0\u9700\u5728\u5e94\u7528\u7a0b\u5e8f\u7ea7\u522b\u4e0a\u53bb\u5b9e\u73b0\u590d\u6742\u7684\u6743\u9650\u6a21\u578b\u3002\u5728\u4f7f\u7528\u63d0\u4f9bSamba\u6587\u4ef6\u548c\u6253\u5370\u670d\u52a1\u7684Linux\u670d\u52a1\u5668\u66ff\u6362Windows\u670d\u52a1\u5668\u7684\u60c5\u51b5\u4e0b\uff0cACL\u7684\u4f18\u52bf\u975e\u5e38\u660e\u663e\u3002\u7531\u4e8eSamba\u652f\u6301ACL\uff0c\u56e0\u6b64\u53ef\u4ee5\u5728Linux\u670d\u52a1\u5668\u548cWindows\u4e2d\u914d\u7f6e\u7528\u6237\u6743\u9650\u3002 \u901a\u8fc7ACL\u6765\u5141\u8bb8\u5bf9\u6240\u6709\u8005\u7528\u6237\u4e4b\u5916\u7684\u5355\u4e2a\u7528\u6237\u8fdb\u884c\u6587\u4ef6\u5199\u6743\u9650\u662f\u4e00\u79cd\u7b80\u5355\u7684\u65b9\u6848\u3002\u4f7f\u7528\u4f20\u7edf\u65b9\u6cd5\uff0c\u6211\u4eec\u5fc5\u987b\u521b\u5efa\u4e00\u4e2a\u65b0\u7ec4\uff0c\u4f7f\u4e24\u4e2a\u7528\u6237\u6210\u4e3a\u8be5\u7ec4\u7684\u6210\u5458\uff0c\u5c06\u8be5\u6587\u4ef6\u7684\u6240\u6709\u7ec4\u66f4\u6539\u4e3a\u65b0\u7ec4\uff0c\u7136\u540e\u6388\u4e88\u8be5\u7ec4\u6587\u4ef6\u7684\u5199\u6743\u9650\u3002\u521b\u5efa\u7ec4\u5e76\u4f7f\u4e24\u4e2a\u7528\u6237\u6210\u4e3a\u8be5\u7ec4\u7684\u6210\u5458\u5219\u9700\u8981\u5229\u7528root\u6743\u9650\u6765\u5b9e\u73b0\u3002 \u4f7f\u7528ACL\uff0c\u6211\u4eec\u53ef\u4ee5\u901a\u8fc7\u4f7f\u6240\u6709\u8005\u548c\u6307\u5b9a\u7528\u6237\u5bf9\u6587\u4ef6\u5177\u6709\u5199\u6743\u9650\u6765\u5b9e\u73b0\u76f8\u540c\u7684\u7ed3\u679c\u3002 \u6b64\u65b9\u6cd5\u7684\u53e6\u4e00\u4e2a\u4f18\u70b9\u662f\u7cfb\u7edf\u7ba1\u7406\u5458\u65e0\u9700\u53c2\u4e0e\u521b\u5efa\u7ec4\u3002\u7528\u6237\u53ef\u4ee5\u81ea\u5df1\u51b3\u5b9a\u6388\u4e88\u8c01\u8bbf\u95ee\u5176\u6587\u4ef6\u7684\u6743\u9650\u3002 \u63d0\u793a\uff1a \u4f7f\u7528ACL\u65f6 ls \u7684\u8f93\u51fa\u7ed3\u679c\u4f1a\u53d1\u751f\u53d8\u5316\u3002\u6dfb\u52a0\u4e00\u4e2a\u52a0\u53f7+ \u6765\u8bf4\u660e\u5df2\u4e3a\u6b64\u6587\u4ef6\u5b9a\u4e49ACL\uff0c\u4e14\u5b9a\u4e49ACL\u540e\uff0c\u6240\u663e\u793a\u7684\u5c5e\u7ec4\u6743\u9650\u662fACL\u63a9\u7801\u7684\u503c\uff0c\u800c\u4e0d\u518d\u662f\u539f\u6765\u5c5e\u7ec4\u7684\u6743\u9650\u3002","title":"8.1.ACL"},{"location":"linux/SRE/03-identity-security/#82acl","text":"Minimal ACLs\uff08\u6700\u5c0fACL\uff09\uff08\u5b9e\u9645\u7528\u9014\uff1a\u4e0ePOSIX\u6743\u9650\u76f8\u540c\uff09 \u4e0e\u6587\u4ef6\u6a21\u5f0f\u6743\u9650\u4f4d\u7b49\u6548\u7684ACL\u79f0\u4e3a\u6700\u5c0fACL \u5206\u4e09\u79cd\u7c7b\u578b\u7684ACL\u6761\u76ee\uff0c\u8fd9\u4e9b\u5bf9\u5e94\u4e8e\u6587\u4ef6\u548c\u76ee\u5f55\u7684\u4f20\u7edf\u6743\u9650\u4f4d Owning User \u6240\u6709\u8005 Owning Group \u6240\u6709\u8005\u7ec4 Others \u5176\u4ed6\u7ec4 Extended ACLs\uff08\u6269\u5c55ACL\uff09 \u5177\u6709\u591a\u4e8e\u4e0a\u8ff0\u4e09\u4e2aACL\u6761\u76ee\u7684ACL\u79f0\u4e3a\u6269\u5c55ACL \u6269\u5c55ACL\u8fd8\u5305\u542b\u63a9\u7801\u6761\u76ee\uff0c\u53ef\u4ee5\u5305\u542b\u4efb\u610f\u6570\u91cf\u7684\u6307\u5b9a\u7528\u6237\u548c\u6307\u5b9a\u7ec4\u6761\u76ee","title":"8.2.ACL\u7684\u57fa\u672c\u7c7b\u578b"},{"location":"linux/SRE/03-identity-security/#83acl","text":"\u7528\u6237\u7c7b\uff08User classes\uff09\u3002 \u4f20\u7edf\u7684POSIX\u6743\u9650\u6982\u5ff5\u4f7f\u7528\u4e09\u79cd\u7528\u6237\u7c7b\u6765\u5206\u914d\u6587\u4ef6\u7cfb\u7edf\u4e2d\u7684\u6743\u9650\uff1a\u6240\u6709\u8005Owning Owner\uff0c\u6240\u6709\u8005\u7ec4Owning Group\u548c\u5176\u4ed6\u7528\u6237Other Users\u3002\u53ef\u4ee5\u4e3a\u6bcf\u4e2a\u7528\u6237\u7c7b\u578b\u8bbe\u7f6e\u4e09\u4e2a\u6743\u9650\u4f4d\uff0c\u8d4b\u4e88\u8bfb\uff08r\uff09\uff0c\u5199\uff08w\uff09\u548c\u6267\u884c\uff08x\uff09\u7684\u6743\u9650\u3002 Owner class \u6240\u6709\u8005\u7c7b Group class \u7ec4\u7c7b Other class \u5176\u4ed6\u7c7b ACL\u8bbf\u95ee\u6743\u9650\uff08Access ACL\uff09\uff1a\u786e\u5b9a\u5404\u79cd\u6587\u4ef6\u7cfb\u7edf\u5bf9\u8c61\uff08\u6587\u4ef6\u548c\u76ee\u5f55\uff09\u7684\u7528\u6237\u548c\u7ec4\u7684\u8bbf\u95ee\u6743\u9650\u3002 \u9ed8\u8ba4ACL\uff08Default ACL\uff09\uff1a\u53ea\u80fd\u5e94\u7528\u4e8e\u76ee\u5f55\u3002 \u5b83\u4eec\u786e\u5b9a\u6587\u4ef6\u7cfb\u7edf\u5bf9\u8c61\u5728\u521b\u5efa\u65f6\u4ece\u5176\u7236\u76ee\u5f55\u7ee7\u627f\u7684\u6743\u9650\u3002 ACL\u6761\u76ee\uff08ACL entry\uff09\uff1a \u6bcf\u4e2aACL\u7531\u4e00\u7ec4ACL\u6761\u76ee\u7ec4\u6210\u3002 ACL\u6761\u76ee\u5305\u542b\u7c7b\u578b\uff08type\uff09\uff0c\u6761\u76ee\u5f15\u7528\u7684\u7528\u6237\u6216\u7ec4\u7684\u9650\u5b9a\u7b26\uff08qualifier\uff09\uff0c\u4ee5\u53ca\u4e00\u7ec4\u6743\u9650\uff08permissions\uff09\u3002 \u5bf9\u4e8e\u67d0\u4e9b\u6761\u76ee\u7c7b\u578b\uff0c\u672a\u5b9a\u4e49\u7ec4\u6216\u7528\u6237\u7684\u9650\u5b9a\u7b26\u3002","title":"8.3.ACL\u672f\u8bed"},{"location":"linux/SRE/03-identity-security/#84acl","text":"Named user \u6307\u5b9a\u7528\u6237: Lets you assign permissions to individual users. \u5141\u8bb8\u6211\u4eec\u4e3a\u6307\u5b9a\u7528\u6237\u5206\u914d\u6743\u9650\u3002 Named group \u6307\u5b9a\u7ec4: Lets you assign permissions to individual groups. \u5141\u8bb8\u6211\u4eec\u4e3a\u5236\u5b9a\u7ec4\u5206\u914d\u6743\u9650\u3002 Mask \u63a9\u7801: Lets you limit the permissions granted to named users or groups. \u5141\u8bb8\u6211\u4eec\u9650\u5236\u7ed9\u4e88\u6307\u5b9a\u7528\u6237\u6216\u6307\u5b9a\u7ec4\u7684\u6743\u9650\u3002 \u6240\u4ee5\u53ef\u80fd\u7684ACL\u7c7b\u578b Type Text Form owner user::rwx named user user:name:rwx owning group group::rwx named group group:name:rwx mask mask::rwx other other::rwx \u4e0ePOSIX.1\u6743\u9650\u6a21\u578b\u4e0d\u540c\uff0c\u7ec4\u7c7bgroup class\u53ef\u4ee5\u5305\u542b\u5177\u6709\u4e0d\u540c\u6743\u9650\u96c6\u7684ACL\u6761\u76ee\uff0c\u56e0\u6b64\u5355\u72ec\u7684\u7ec4\u7c7b\u6743\u9650\u4e0d\u518d\u8db3\u4ee5\u8868\u793a\u5b83\u5305\u542b\u7684\u6240\u6709ACL\u6761\u76ee\u7684\u6240\u6709\u8be6\u7ec6\u6743\u9650\u3002 \u56e0\u6b64\uff0c\u7ec4\u7c7b\u578b\u6743\u9650\u7684\u542b\u4e49\u88ab\u91cd\u65b0\u5b9a\u4e49\u3002\u5728\u65b0\u8bed\u4e49\u4e0b\uff0c\u7ec4\u7c7b\u578b\u6743\u9650\u8868\u793a\u7ec4\u7c7b\u4e2d\u7684\u4efb\u4f55\u6761\u76ee\u5c06\u6388\u4e88\u7684\u6743\u9650\u7684**\u4e0a\u9650**\uff08upper bound\uff09\u3002 \u6b64\u4e0a\u9650\u5c5e\u6027\u53ef\u786e\u4fdd\u5728\u4f7f\u7528ACL\u63a7\u5236\u540e\uff0c\u5e94\u7528\u7a0b\u5e8f\u4e0d\u4f1a\u7a81\u7136\u6216\u8005\u610f\u5916\u5730\u6388\u4e88\u989d\u5916\u7684\u6743\u9650\u3002 \u5728\u6700\u5c0fACL\u4e2d\uff0c\u7ec4\u7c7b\u6743\u9650\u4e0e\u6240\u6709\u8005\u7ec4\u6743\u9650\u76f8\u540c\u3002\u5728\u6269\u5c55ACL\u4e2d\uff0c\u7ec4\u7c7b\u53ef\u4ee5\u5305\u542b\u5176\u4ed6\u7528\u6237\u6216\u7ec4\u7684\u6761\u76ee\u3002\u8fd9\u4f1a\u5bfc\u81f4\u4e00\u4e2a\u95ee\u9898\uff1a\u8fd9\u4e9b\u9644\u52a0\u6761\u76ee\u4e2d\u7684\u4e00\u4e9b\u53ef\u80fd\u62e5\u6709\u672a\u5305\u542b\u5728\u6240\u6709\u8005\u7ec4\u6761\u76ee\uff08owning group entry\uff09\u4e2d\u7684\u6743\u9650\uff0c\u56e0\u6b64\u6240\u6709\u8005\u7ec4\u6761\u76ee\u6743\u9650\u53ef\u80fd\u4e0e\u7ec4\u7c7b\u6743\u9650\uff08group class\uff09\u4e0d\u540c\u3002 \u901a\u8fc7\u63a9\u7801\uff08mask entry\uff09\u89e3\u51b3\u4e86\u8fd9\u4e2a\u95ee\u9898\u3002 \u4f7f\u7528\u6700\u5c0fACL\uff0c\u7ec4\u7c7b\u6743\u9650\u6620\u5c04\u5230\u6240\u6709\u8005\u7ec4\u6761\u76ee\u6743\u9650\u3002With minimal ACLs, the group class permissions map to the owning group entry permissions. \u4f7f\u7528\u6269\u5c55ACL\u65f6\uff0c\u7ec4\u7c7b\u6743\u9650\u6620\u5c04\u5230\u63a9\u7801\u6761\u76ee\u6743\u9650\uff0c\u800c\u6240\u6709\u8005\u7ec4\u6761\u76ee\u4ecd\u5b9a\u4e49\u62e5\u6709\u7ec4\u6743\u9650\u3002With extended ACLs, the group class permissions map to the mask entry permissions, whereas the owning group entry still defines the owning group permissions.","title":"8.4.ACL\u6743\u9650\u5206\u7c7b"},{"location":"linux/SRE/03-identity-security/#85acl","text":"\u8bbe\u5b9aACL\u6743\u9650\uff1a setfacl Syntax: setfacl [OPTIONS] [ACL-ENTRIES] Option Description -m : Add or modify an ACL entry -x : Remove an ACL entry -d : Set a default ACL -b : Remove all extended ACL entries -M : restore ACLs that have been written to a file \u6ce8\u610f\uff1a--set\u9009\u9879\u4f1a\u628a\u539f\u6709\u7684ACL\u9879\u90fd\u5220\u9664\uff0c\u7528\u65b0\u7684\u66ff\u4ee3\uff0c\u6240\u4ee5\u4e00\u5b9a\u8981\u5305\u542bUGO\u7684\u8bbe\u7f6e\uff0c\u4e0d\u80fd\u50cf-m\u533b\u9662\u53ea\u6dfb\u52a0ACL\u3002 setfacl --set u::rw,u:vagrant:rw,g::r,o::- file1 \u8bfb\u53d6ACL\u6743\u9650\uff1a getfacl Syntax: getfacl [OPTIONS] Option Description -a : Display the file access control list -d : Display the default access control list -R : List the ACLs of all files and directories recursively","title":"8.5.ACL\u64cd\u4f5c\u547d\u4ee4"},{"location":"linux/SRE/03-identity-security/#86acl","text":"","title":"8.6.ACL\u5b9e\u4f8b\u89e3\u6790"},{"location":"linux/SRE/03-identity-security/#861","text":"\u9879\u76ee\u76ee\u5f55 ~/project1 \u9879\u76ee\u7ecf\u7406 pm1 \u5bf9\u8fd9\u4e2a\u76ee\u5f55\u62e5\u6709\u8bbf\u95ee\u548c\u4fee\u6539\u6743\u9650 \u9879\u76ee\u6210\u5458 tm1 \u53ef\u4ee5\u8bbf\u95ee\u548c\u4fee\u6539\u8fd9\u4e2a\u76ee\u5f55 \u975e\u9879\u76ee\u6210\u5458 tm2 \u4e0d\u80fd\u8bbf\u95ee ~/project1 \u76ee\u5f55\u3002 \u9879\u76ee\u76ee\u5f55 ~/project1 \u7684\u6743\u9650\u89c4\u5212 \u9879\u76ee\u7ecf\u7406 pm1 \u662f\u8fd9\u4e2a\u76ee\u5f55\u7684\u5c5e\u4e3b\uff0c\u6743\u9650\u4e3a rwx \u9879\u76ee\u7ecf\u7406 pm1 \u5c5e\u4e8e project1 \u7ec4 \u9879\u76ee\u6210\u5458 tm1 \u4e0e pm1 \u5728\u540c\u4e00\u4e2a project1 \u7ec4\uff0c\u6743\u9650\u662f rw \u5176\u4ed6\u4eba\u7684\u6743\u9650\u8bbe\u5b9a\u4e3a 0 \u9879\u76ee\u4e34\u65f6\u6210\u5458tm2\u7684\u6743\u9650\u9700\u6c42 \u80fd\u8bbf\u95ee project1 \u76ee\u5f55\uff0c\u4f46\u53ea\u80fd\u5177\u6709 r \u548c x \u6743\u9650 \u89e3\u51b3\u65b9\u6cd5 \u5f53\u51fa\u73b0\u8fd9\u79cd\u60c5\u51b5\u65f6\uff0c\u666e\u901a\u6743\u9650\u4e2d\u7684\u4e09\u79cd\u8eab\u4efd\uff08owner\uff0cgroup\uff0cothers\uff09\u5c31\u4e0d\u80fd\u89e3\u51b3\u8fd9\u4e2a\u95ee\u9898\uff0c\u800cACL\u6743\u9650\u53ef\u4ee5\u3002 \u5728\u4f7f\u7528ACL\u6743\u9650\u7ed9\u7528\u6237 tm2 \u965a\u4e88\u6743\u9650\u65f6\uff0c tm2 \u65e2\u4e0d\u662f ~/project1 \u76ee\u5f55\u7684\u5c5e\u4e3b\uff0c\u4e5f\u4e0d\u662f\u5c5e\u7ec4\uff0c\u4ec5\u4ec5\u8d4b\u4e88\u7528\u6237 tm2 \u9488\u5bf9 ~/project1 \u76ee\u5f55\u7684r-x\u6743\u9650\uff0c \u5c5e\u4e8e\u5355\u72ec\u6307\u5b9a\u7528\u6237\u5e76\u5355\u72ec\u5206\u914d\u6743\u9650\uff0c\u89e3\u51b3\u4e86\u7528\u6237\u8eab\u4efd\u4e0d\u8db3\u7684\u95ee\u9898\u3002 \u62d3\u5c55\u95ee\u9898 \u7ed9 ~/project1 \u76ee\u5f55\u6dfb\u52a0\u5176\u4ed6\u7ec4 project2 \u7684\u8bbf\u95ee\u6743\u9650 \u901a\u8fc7 mask \u6765\u8c03\u6574\u7528\u6237 tm2 \u5b9e\u9645\u6709\u6548\u6743\u9650 \u9ed8\u8ba4ACL\u6743\u9650 \u9012\u5f52ACL\u6743\u9650 \u5220\u9664ACL\u6743\u9650","title":"8.6.1.\u5b9e\u4f8b\u63cf\u8ff0"},{"location":"linux/SRE/03-identity-security/#862","text":"\u521b\u5efa\u6d4b\u8bd5\u7528\u6237 $ whoami vagrant $ sudo groupadd project1 $ sudo groupadd project2 $ sudo useradd -m -g project1 pm1 $ sudo useradd -m -g project1 tm1 $ sudo useradd -m -g project2 tm2 $ sudo passwd pm1 $ sudo passwd tm1 $ sudo passwd tm2 $ cat /etc/group ...... project1:x:1535: project2:x:1536: ...... $ cat /etc/passwd ...... pm1:x:2003:1535::/home/pm1:/bin/bash tm1:x:2004:1535::/home/tm1:/bin/bash tm2:x:2005:1536::/home/tm2:/bin/bash ...... \u521b\u5efa\u6d4b\u8bd5\u76ee\u5f55 project1 , \u6307\u5b9a project1 \u76ee\u5f55\u7684\u6743\u9650\uff0c\u521b\u5efa\u6d4b\u8bd5\u6587\u4ef6 file1 \u3002 $ su - pm1 $ cd ~ $ mkdir project1 $ ls -dl project1 drwxr-xr-x. 1 pm1 project1 0 Dec 4 06 :25 project1 $ chmod 770 project1/ $ ls -dl project1 drwxrwx---. 1 pm1 project1 0 Dec 4 06 :25 project1 $ echo \"hello from $USER \" > ./project1/file1 $ cat ./project1/file1 hello from pm1 \u76ee\u5f55 project1 \u5f53\u524d\u6743\u9650\u5feb\u7167 \u5c5e\u4e3b\uff1a pm1 \uff0c\u5bf9 ~/project1 \u76ee\u5f55\u6709 rwx \u6743\u9650 \u5c5e\u7ec4\uff1a project1 \uff0c\u5305\u542b\u7528\u6237 pm1 \u548c tm1 \uff0c\u5bf9 ~/project1 \u76ee\u5f55\u6709 rwx \u6743\u9650 \u5176\u4ed6\u7ec4\uff1a\u6ca1\u6709\u8bbf\u95ee\u6743\u9650 \u76ee\u5f55 ~/project1 \u5f53\u524d\u7684ACL\u5feb\u7167 $ getfacl ./project1/ # file: home/pm1/project1/ # owner: pm1 # group: project1 user::rwx group::rwx other::---","title":"8.6.2.\u521d\u59cb\u5316\u73af\u5883"},{"location":"linux/SRE/03-identity-security/#863acl","text":"\u7ed9 ~/project1 \u76ee\u5f55\u6dfb\u52a0\u65b0\u7528\u6237 tm2 \uff0c\u6743\u9650\u4e3a rwx \u3002\u76ee\u5f55 ~/project1 \u7684\u66f4\u65b0\u540e\u7684\u6743\u9650\u4f4d\u53d8\u6210\u4e86 drwxrwx---+ \u3002 $ su - pm1 $ setfacl -m u:tm2:rx ./project1/ $ ls -dl ./project1 drwxrwx---+ 1 pm1 project1 0 Dec 4 06 :25 project1 $ getfacl ~/project1/ # file: project1 \uff08\u6587\u4ef6\u540d\uff09 # owner: pm1 \uff08Owner \u6587\u4ef6\u5c5e\u4e3b\uff09 # group: project1 \uff08Owing Group \u6587\u4ef6\u5c5e\u7ec4\uff09 user::rwx \uff08Ower\u6587\u4ef6\u5c5e\u4e3b\u7684\u6743\u9650\uff0c\u7528\u6237\u540d\u680f\u662f\u7a7a\u7684\uff0c\u8bf4\u660e\u662f\u5c5e\u4e3bOwner\u7684\u6743\u9650\uff09 user:tm2:r-x \uff08Named User \u6307\u5b9a\u7528\u6237\u7684\u6743\u9650\uff0c\u7528\u6237tm2\u7684\u6743\u9650\uff09 group::rwx \uff08Owing Group \u6587\u4ef6\u5c5e\u7ec4\u7684\u6743\u9650\uff0c\u7ec4\u540d\u680f\u662f\u7a7a\u7684\uff0c\u8bf4\u660e\u662f\u5c5e\u7ec4\u7684\u6743\u9650\uff09 \uff08Named Group \u6307\u5b9a\u7528\u6237\u7ec4\u7684\u6743\u9650\uff0c\u6b64\u65f6\u672a\u6307\u5b9a\uff09 mask::rwx \uff08mask\u6743\u9650\uff09 other::--- \uff08\u5176\u4ed6\u4ebaother\u7684\u6743\u9650\uff09 \u7ed9 ~/project1 \u76ee\u5f55\u6dfb\u52a0\u65b0\u7ec4 project2 \u7684\u6743\u9650 rwx $ su - pm1 $ setfacl -m g:project2:rwx ./project1/ $ ls -dl ./project1 drwxrwx---+ 1 pm1 project1 0 Dec 4 06 :46 ./project1 $ getfacl ./project1 # file: project1 # owner: pm1 # group: project1 user::rwx user:tm2:r-x ( \u7528\u6237tm2\u62e5\u6709\u4e86r-x\u6743\u9650\uff09 group::rwx group:project2:rwx ( \u7528\u6237\u7ec4project2\u62e5\u6709\u4e86rwx\u6743\u9650\uff09 mask::rwx other::--- \u6709\u6548\u6743\u9650\u7684\u8ba1\u7b97\uff1a \u5f53\u524d ~/project1 \u76ee\u5f55\u7684 mask \u662f rwx \uff0c tm2 \u7684\u6743\u9650\u662f r-x \uff0c\u4e8c\u8005\u8fdb\u884cAND\u64cd\u4f5c\uff0c tm2 \u7684\u5b9e\u9645\u6743\u9650\u662f r-x tm2: r - x ( 1 0 1 ) mask: r w x ( 1 1 1 ) --------------------- result: r - x ( 1 0 1 ) \u5bf9\u7167\u4e0b\u9762\u7684\u89c4\u5219\uff0c\u9a8c\u8bc1\u7528\u6237 tm2 \u5bf9 ~/project1 \u76ee\u5f55\u7684\u5b9e\u9645\u6743\u9650\u3002 su - tm2 \u80fd\u8fdb\u5165\u76ee\u5f55 project1 \uff0c\u8bf4\u660e\u5f53\u524d\u7528\u6237\u5177\u6709\u76ee\u5f55 project1 \u7684 r-x \u6743\u9650\u3002 $ whoami tm2 $ cd /home/pm1/project1/ \u80fd\u5217\u51fa\u76ee\u5f55 project1 \u4e0b\u6587\u4ef6\u5217\u8868\uff0c\u53ef\u4ee5\u67e5\u770b\u6587\u4ef6 file \u7684\u5185\u5bb9\uff0c\u8bf4\u660e\u5f53\u524d\u7528\u6237\u5177\u6709\u76ee\u5f55 project1 \u7684 r-x \u6743\u9650\u3002 $ pwd /home/pm1/project1 $ whoami tm2 $ ls -l -rw-r--r--. 1 pm1 project1 15 Dec 4 07 :15 file1 $ cat file1 hello from pm1 \u5bf9\u76ee\u5f55 project1 \u4e0d\u5177\u6709 w \u6743\u9650\uff0c\u6240\u4ee5\u65e0\u6cd5\u521b\u5efa\u3001\u5220\u9664\u6216\u4fee\u6539\u76ee\u5f55\u4e0b\u7684\u4efb\u4f55\u6587\u4ef6\u6216\u5b50\u76ee\u5f55\u3002 $ pwd /home/pm1/project1 $ whoami tm2 $ touch file2 touch: cannot touch 'file2' : Permission denied $ echo \"hello from $USER \" >> file1 -bash: file1: Permission denied","title":"8.6.3.\u6dfb\u52a0ACL\u6743\u9650"},{"location":"linux/SRE/03-identity-security/#864mask","text":"\u8c03\u6574 ~/project1 \u76ee\u5f55\u7684 mask \u4e3a r-- \uff0c\u5219 tm2 \u7684\u5b9e\u9645\u6743\u9650\u662f r-- $ su - pm1 $ cd ~ $ setfacl -m m::r ./project1/ $ getfacl ./project1/ # file: project1/ # owner: pm1 # group: project1 user::rwx user:tm2:r-x #effective:r-- (\u7528\u6237tm2\u7684\u5b9e\u9645\u6709\u6548\u6743\u9650\u53d8\u4e3ar--) group::rwx #effective:r-- (\u5c5e\u7ec4project1\u7ec4\u7684\u5b9e\u9645\u6709\u6548\u6743\u9650\u53d8\u4e3ar--) group:project2:rwx #effective:r-- (\u5176\u4ed6\u7ec4project2\u7ec4\u7684\u5b9e\u9645\u6709\u6548\u6743\u9650\u53d8\u4e3ar--) mask::r-- ( mask\u53d8\u5316\uff0c\u5bfc\u81f4\u4e0a\u8ff0\u4e24\u4e2agroup\u7684\u6709\u6548\u6743\u9650\u90fd\u53d1\u751f\u4e86\u53d8\u5316 ) other::--- \u6709\u6548\u6743\u9650\u7684\u8ba1\u7b97\uff1a \u5f53\u524d ~/project1 \u76ee\u5f55\u7684 mask \u662f r-- \uff0c\u7528\u6237 tm2 \u3001\u7ec4 project2 \u7684\u5b9e\u9645\u6743\u9650\u662f r-- \u3002 tm2: r - w ( 1 0 1 ) mask: r - - ( 1 0 0 ) --------------------- result: r - - ( 1 0 0 ) \u63d0\u793a\uff1a \u7528\u6237\u548c\u7528\u6237\u7ec4\u6240\u8bbe\u5b9a\u7684\u6743\u9650\u5fc5\u987b\u5728mask\u6743\u9650\u8bbe\u5b9a\u7684\u8303\u56f4\u4e4b\u5185\u624d\u80fd\u751f\u6548\uff0cmask\u6743\u9650\u5c31\u662f\u6700\u5927\u6709\u6548\u6743\u9650\u3002","title":"8.6.4.\u4fee\u6539mask\u6743\u9650"},{"location":"linux/SRE/03-identity-security/#865","text":"\u5728POSIX\u6743\u9650\u6a21\u578b\u548cACL\u6743\u9650\u53e0\u52a0\u4f5c\u7528\u4e0b\uff0c\u7528\u6237\u7684\u5b9e\u9645\u6743\u9650\u5206\u6790\u3002 $ getfacl ./project1/ # file: project1/ # owner: pm1 <----Owner # group: project1 <----owning group user::rwx <----owner 's permissions user:tm2:r-x #effective:r-- <----named user' s permissions group::rwx #effective:r-- <----owning group's permissions group:project2:rwx #effective:r-- <----named group's permissions mask::r-- <----masks for named user and named group other::--- default:user::rwx default:user:tm2:r-x default:group::rwx default:mask::rwx default:other::--- \u6240\u6709\u8005ower\u548c\u5176\u4ed6\u7528\u6237other\u6761\u76ee\u4e2d\u5b9a\u4e49\u7684\u6743\u9650\u603b\u662f\u6709\u6548\u7684\u3002\u4e0a\u4f8b\u4e2d\u7684user\u6761\u76ee\u548cother\u6761\u76ee\u3002 \u9664\u4e86\u63a9\u7801\u6761\u76ee\uff0c\u6240\u6709\u5176\u4ed6\u6761\u76ee\uff08\u6bd4\u5982\u6307\u5b9a\u7528\u6237named user\uff09\u53ef\u4ee5\u662f\u6709\u6548\u7684\u6216\u88ab\u5c4f\u853d\u7684\u3002 \u6307\u5b9a\u7528\u6237\uff08named user\uff09\uff0c\u6240\u6709\u8005\u7ec4\uff08owning group\uff09\u6216\u6307\u5b9a\u7ec4\uff08named group\uff09\u4ee5\u53ca\u63a9\u7801mask\u6761\u76ee\u4e2d\u5b9a\u4e49\u7684\u6743\u9650\uff0c\u6709\u6548\u6743\u9650\u662f\u4ed6\u4eec\u6743\u9650\u8fdb\u884c\u903b\u8f91AND\u540e\u7684\u7ed3\u679c\uff0c\u800c\u4e0d\u662f\u5355\u72ec\u7684\u63a9\u7801\u4e2d\u5b9a\u4e49\u7684\u6743\u9650\u6216\u8005\u5404\u81ea\u6761\u76ee\u4e2d\u5b9a\u4e49\u7684\u6743\u3002 \u6709\u6548\u6743\u9650\u8ba1\u7b97\u65b9\u6cd5\u5982\u4e0b\uff0c\u6ce8\u610f\uff0c ls \u547d\u4ee4\u4e2d\u663e\u793a\u51fa\u6765\u7684\u6743\u9650\uff0c\u4e0e\u5b9e\u9645\u7684ACL\u6743\u9650\u662f\u6709\u5dee\u522b\u7684\u3002 tm2: r - w ( 1 0 1 ) group: r w x ( 1 1 1 ) named group: r w x ( 1 1 1 ) mask: r - - ( 1 0 0 ) --------------------------- result: r - - ( 1 0 0 ) \u5c0f\u8d34\u58eb\uff1a \u4e0e\u6587\u4ef6\u6a21\u5f0f\u6743\u9650\u4f4d\u7b49\u6548\u7684ACL\u79f0\u4e3a\u6700\u5c0fACL\uff0c\u5373POSIX\u4f20\u7edf\u6743\u9650\u3002 \u542b\u63a9\u7801mask\u7b49\u5176\u4ed6\u6743\u9650\u6761\u76ee\u7684ACL\u79f0\u4e3a\u6269\u5c55ACL\u3002 \u5728\u6700\u5c0f\u548c\u6269\u5c55ACL\u60c5\u5f62\u4e0b\uff0c\u6240\u6709\u8005\u7c7b\u6743\u9650\uff08owner\uff09\u90fd\u662f\u6620\u5c04\u5230ACL\u7684\u6240\u6709\u8005\u6761\u76ee\u3002 \u5176\u4ed6\u7c7b\u6743\u9650\u6620\u5c04\u5230\u5176\u5404\u81ea\u7684ACL\u6761\u76ee\u3002 \u5728\u6269\u5c55ACL\u60c5\u5f62\u4e0b\uff0c\u7ec4\u7c7b\u6743\u9650\u7684\u6620\u5c04\u662f\u4e0d\u540c\u7684\u3002 \u5bf9\u4e8e\u6ca1\u6709\u63a9\u7801\u7684\u6700\u5c0fACL\uff0c\u7ec4\u7c7b\u6743\u9650\u5c06\u6620\u5c04\u5230ACL\u6240\u6709\u8005\u7ec4\u6761\u76ee\u3002 \u5bf9\u4e8e\u5e26\u6709\u63a9\u7801\u7684\u6269\u5c55ACL\uff0c\u7ec4\u7c7b\u6743\u9650\u5c06\u6620\u5c04\u5230\u63a9\u7801\u6761\u76ee\u3002 \u901a\u8fc7\u6743\u9650\u4f4d\u8fdb\u884c\u5206\u914d\u7684\u6743\u9650\u4ee3\u8868\u4e86\u901a\u8fc7ACL\u8fdb\u884c\u5206\u914d\u7684\u6743\u9650\u7684\u4e0a\u9650\u3002 \u6ca1\u6709\u5728\u8fd9\u91cc\u4f53\u73b0\u7684\u4efb\u4f55\u6743\u9650\uff0c\u8981\u4e48\u4e0d\u5728ACL\u4e2d\uff0c\u8981\u4e48\u65e0\u6548\u3002 \u5bf9\u6743\u9650\u4f4d\u6240\u505a\u7684\u66f4\u6539\u5c06\u7531ACL\u53cd\u6620\uff0c\u53cd\u4e4b\u4ea6\u7136\u3002","title":"8.6.5.\u6709\u6548\u6743\u9650\u5206\u6790"},{"location":"linux/SRE/03-identity-security/#866acl","text":"$ su - pm1 $ touch ./project1/file2 $ mkdir ./project1/cloud $ ll ./project1/ drwxr-xr-x. 1 pm1 project1 0 Dec 4 08 :52 cloud -rw-r--r--. 1 pm1 project1 15 Dec 4 07 :15 file1 -rw-r--r--. 1 pm1 project1 0 Dec 4 08 :52 file2 $ ll -d project1/ drwxr-----+ 1 pm1 project1 30 Dec 4 08 :52 project1/ \u6587\u4ef6 file1 \u548c\u76ee\u5f55 cloud \u6ca1\u6709\u7ee7\u627f project1 \u76ee\u5f55\u7684ACL\u6743\u9650\u3002 \u63d0\u793a\uff1a \u9ed8\u8ba4 ACL\u9650\u53ea\u5bf9\u76ee\u5f55\u751f\u6548\u3002 \u9ed8\u8ba4ACL\u6743\u9650\u7684\u4f5c\u7528\u662f\uff1a\u5982\u679c\u7ed9\u7236\u76ee\u5f55\u8bbe\u5b9a\u4e86\u9ed8\u8ba4 ACL \u6743\u9650\uff0c\u90a3\u4e48\u7236\u76ee\u5f55\u4e2d\u6240\u6709\u65b0\u5efa\u7684\u5b50\u6587\u4ef6\u90fd\u4f1a\u7ee7\u627f\u7236\u76ee\u5f55\u7684ACL\u6743\u9650\u3002 \u4e0b\u9762\u589e\u52a0 ~/project1 \u76ee\u5f55\u7684\u9ed8\u8ba4ACL\u6743\u9650\u3002 $ su - pm1 $ cd ~ $ getfacl ./project1/ # file: project1/ # owner: pm1 # group: project1 user::rwx user:tm2:r-x #effective:r-- group::rwx #effective:r-- group:project2:rwx #effective:r-- mask::r-- other::--- $ setfacl -m d:u:tm2:rx ./project1/ $ getfacl ./project1/ # file: project1/ # owner: pm1 # group: project1 user::rwx user:tm2:r-x #effective:r-- group::rwx #effective:r-- group:project2:rwx #effective:r-- mask::r-- other::--- default:user::rwx default:user:tm2:r-x default:group::rwx default:mask::rwx default:other::--- \u521b\u5efa\u65b0\u5b50\u76ee\u5f55 leonardo \uff0c\u5c31\u7ee7\u627f\u4e86 ~/project1 \u76ee\u5f55\u7684default ACL\u6743\u9650\u8bbe\u5b9a\u3002 \u6ce8\u610f\uff0c\u9ed8\u8ba4ACL\u6743\u9650\u662f\u9488\u5bf9\u65b0\u5efa\u7acb\u7684\u6587\u4ef6\u751f\u6548\u7684\uff0c\u76ee\u5f55cloud\u548c\u6587\u4ef6file1\u5e76\u6ca1\u6709\u56e0\u4e3a\u589e\u52a0\u4e86\u7236\u76ee\u5f55\u7684\u9ed8\u8ba4ACL\u8bbe\u5b9a\u800c\u7ee7\u627f\u9ed8\u8ba4ACL\u6743\u9650\u8bbe\u5b9a. $ su - pm1 $ cd ~ $ mkdir ./project1/leonardo $ ll ./project1/ drwxr-xr-x. 1 pm1 project1 0 Dec 4 08 :52 cloud -rw-r--r--. 1 pm1 project1 15 Dec 4 07 :15 file1 -rw-r--r--. 1 pm1 project1 0 Dec 4 08 :52 file2 drwxrwx---+ 1 pm1 project1 0 Dec 4 09 :07 leonardo","title":"8.6.6.\u9ed8\u8ba4ACL\u6743\u9650"},{"location":"linux/SRE/03-identity-security/#867acl","text":"\u9012\u5f52 ACL \u6743\u9650\uff0c\u662f\u6307\u7236\u76ee\u5f55\u5728\u8bbe\u5b9aACL\u6743\u9650\u65f6\uff0c\u6240\u6709\u7684\u5b50\u76ee\u5f55\u4e5f\u4f1a\u62e5\u6709\u76f8\u540c\u7684ACL\u6743\u9650\u3002 $ su - pm1 $ cd ~ $ getfacl ./project1/ # file: project1/ # owner: pm1 # group: project1 user::rwx user:tm2:r-x #effective:r-- group::rwx #effective:r-- group:project2:rwx #effective:r-- mask::r-- other::--- default:user::rwx default:user:tm2:r-x default:group::rwx default:mask::rwx default:other::--- $ setfacl -m d:u:tm2:rx -R ./project1/ $ ll ./project1 drwxr-xr-x+ 1 pm1 project1 0 Dec 4 08 :52 cloud -rw-r--r--. 1 pm1 project1 15 Dec 4 07 :15 file1 -rw-r--r--. 1 pm1 project1 0 Dec 4 08 :52 file2 drwxrwx---+ 1 pm1 project1 0 Dec 4 09 :07 leonardo","title":"8.6.7.\u9012\u5f52ACL\u6743\u9650"},{"location":"linux/SRE/03-identity-security/#868acl","text":"\u5220\u9664\u7528\u6237 tm2 \u7684ACL\u6743\u9650\u3002 $ su - pm1 $ cd ~ $ setfacl -x u:tm2 ./project1/ $ getfacl ./project1/ # file: project1/ # owner: pm1 # group: project1 user::rwx group::rwx group:project2:rwx mask::rwx other::--- default:user::rwx default:user:tm2:r-x default:group::rwx default:mask::rwx default:other::--- \u5220\u9664\u6240\u6709\u7684ACL\u6743\u9650\u3002 $ setfacl -b ./project1 $ getfacl ./project1 # file: project1/ # owner: pm1 # group: project1 user::rwx group::rwx other::--- $ ll ./project1 drwxr-xr-x+ 1 pm1 project1 0 Dec 4 08 :52 cloud -rw-r--r--. 1 pm1 project1 15 Dec 4 07 :15 file1 -rw-r--r--. 1 pm1 project1 0 Dec 4 08 :52 file2 drwxrwx---+ 1 pm1 project1 0 Dec 4 09 :07 leonardo \u9012\u5f52\u5220\u9664\u5168\u90e8ACL\u6743\u9650\u3002 $ setfacl -b -R ./project1 $ ll ./project1/ total 4 drwxr-xr-x. 1 pm1 project1 0 Dec 4 08 :52 cloud -rw-r--r--. 1 pm1 project1 15 Dec 4 07 :15 file1 -rw-r--r--. 1 pm1 project1 0 Dec 4 08 :52 file2 drwxrwx---. 1 pm1 project1 0 Dec 4 09 :07 leonardo","title":"8.6.8.\u5220\u9664ACL\u6743\u9650"},{"location":"linux/SRE/03-identity-security/#87acl","text":"","title":"8.7.ACL\u76ee\u5f55\u5b9e\u4f8b\u89e3\u6790"},{"location":"linux/SRE/03-identity-security/#871acl","text":"\u5207\u6362\u5230pm1\u7528\u6237\uff0c\u5728\u5176\u4e3b\u76ee\u5f55\u4e2d\uff0c\u57fa\u4e8e\u4e0d\u540c\u7684\u63a9\u7801\u521b\u5efa2\u4e2a\u5b50\u76ee\u5f55\u3002 $ su - pm1 $ umask 0022 $ mkdir mydir1 $ umask 0027 $ mkdir mydir2 $ ll -d mydir* drwxr-xr-x. 1 pm1 project1 0 Dec 4 12 :30 mydir1 drwxr-x---. 1 pm1 project1 0 Dec 4 12 :31 mydir2 \u8fd92\u4e2a\u76ee\u5f55\u5f53\u524d\u7684ACL\u72b6\u6001\u5982\u4e0b\uff1a $ getfacl mydir1 # file: mydir1 # owner: pm1 # group: project1 user::rwx group::r-x other::r-x $ getfacl mydir2 # file: mydir2 # owner: pm1 # group: project1 user::rwx group::r-x other::--- \u4fee\u6539\u76ee\u5f55 mydir2 \u7684ACL\u3002 $ setfacl -m u:tm2:rwx,g:project2:rwx mydir2 $ getfacl mydir2 getfacl mydir2 # file: mydir2 # owner: pm1 # group: project1 user::rwx user:tm2:rwx group::r-x group:project2:rwx mask::rwx other::--- $ ll -d mydir2 drwxrwx---+ 1 pm1 project1 0 Dec 4 12 :31 mydir2 \u73b0\u5728\uff0c\u7528\u6237 tm2 \u548c\u7ec4 project2 \u5bf9\u76ee\u5f55 mydir2 \u90fd\u5177\u6709rwx\u6743\u9650\uff0c\u4f20\u7edfPOSIX\u6743\u9650\u548cACL\u6743\u9650\u4e00\u81f4\u3002 \u73b0\u5728\u5bf9mydir2\u76ee\u5f55\u7ec4\u6743\u9650\u64a4\u9500w\u6743\u9650\u3002 \u7528\u6237 tm2 \u548c\u7ec4 project2 \u5bf9\u76ee\u5f55 mydir2 \u7684\u6709\u6548\u6743\u9650\u53d8\u6210\u4e86 r-x \u3002 mask\u4e5f\u53d7\u7ec4\u6743\u9650\u53d8\u5316\u5f71\u54cd\uff0c\u53d8\u6210\u4e86 r-x \u3002 $ chmod g-w mydir2 $ ll -d mydir2 drwxr-x---+ 1 pm1 project1 0 Dec 4 12 :31 mydir2 $ getfacl mydir2 # file: mydir2 # owner: pm1 # group: project1 user::rwx user:tm2:rwx #effective:r-x group::r-x group:project2:rwx #effective:r-x mask::r-x other::--- \u901a\u8fc7 chmod \u548c setfacl \u4e24\u79cd\u4e0d\u540c\u7684\u65b9\u6cd5\u5bf9\u76ee\u5f55 mydir2 \u7684\u7ec4\u6743\u9650\u8fdb\u884c\u4fee\u6539\uff0c\u5728ls\u547d\u4ee4\u4e2d\u4f53\u73b0\u662f\u4e00\u6837\u7684\uff0c\u5bf9\u7ec4\u7684\u5b9e\u9645\u6709\u6548\u6743\u9650\u7684\u5f71\u54cd\u4e5f\u662f\u4e00\u6837\u7684\u3002 chmod \u4fee\u6539\u7684\u662f mask \uff0c mask \u53ea\u5f71\u54cd\u9664\u6240\u6709\u8005\u548cother\u7684\u4e4b\u5916\u7684\u4eba\u548c\u7ec4\u7684\u6700\u5927\u6743\u9650\uff0c mask \u9700\u8981\u4e0e\u7528\u6237\u7684\u6743\u9650\u8fdb\u884c\u903b\u8f91\u4e0e\u8fd0\u7b97\u540e\uff0c\u624d\u80fd\u53d8\u6210\u6709\u6548\u6743\u9650\uff0c\u7528\u6237\u6216\u7ec4\u7684\u8bbe\u7f6e\u5fc5\u987b\u5728mask\u6743\u9650\u8bbe\u5b9a\u8303\u56f4\u5185\u624d\u4f1a\u751f\u6548\u3002 setfacl \u53ef\u4ee5\u4e0d\u4fee\u6539mask\u7684\u60c5\u51b5\u4e0b\u53ea\u4fee\u6539 owning group \u7684\u6743\u9650\uff0c\u4e0b\u9762\u7684\u4f8b\u5b50\u8bf4\u660e\u4e86\u8fd9\u4e00\u60c5\u51b5\u3002POSIX\u7ec4\u6743\u9650\u4ecd\u7136\u662f rwx \uff0c\u4f46ACL\u4e2d\u6240\u6709\u8005\u7ec4\u7684\u6743\u9650\u53d8\u6210\u4e86 r-- \u3002 $ setfacl -m g::r mydir2 $ ll -d mydir2 drwxrwx---+ 1 pm1 project1 0 Dec 4 12 :31 mydir2 $ getfacl mydir2 # file: mydir2 # owner: pm1 # group: project1 user::rwx user:tm2:rwx group::r-- group:project2:rwx mask::rwx other::---","title":"8.7.1.\u76ee\u5f55ACL"},{"location":"linux/SRE/03-identity-security/#872acl","text":"\u76ee\u5f55\u53ef\u4ee5\u5177\u6709\u9ed8\u8ba4ACL\uff0c\u8fd9\u662f\u4e00\u79cd\u7279\u6b8a\u7684ACL\uff0c\u7528\u4e8e\u5b9a\u4e49\u76ee\u5f55\u4e0b\u7684\u5bf9\u8c61\u5728\u521b\u5efa\u65f6\u7ee7\u627f\u7684\u8bbf\u95ee\u6743\u9650\u3002\u9ed8\u8ba4ACL\u4f1a\u5f71\u54cd\u5b50\u76ee\u5f55\u548c\u6587\u4ef6\u3002 \u76ee\u5f55\u7684\u9ed8\u8ba4ACL\u7684\u6743\u9650\u6709\u4e24\u79cd\u4e0d\u540c\u7684\u65b9\u5f0f\u4f20\u9012\u7ed9\u5176\u4e2d\u7684\u6587\u4ef6\u548c\u5b50\u76ee\u5f55\uff1a \u5b50\u76ee\u5f55\u7ee7\u627f\u7236\u76ee\u5f55\u7684\u9ed8\u8ba4ACL\uff0c\u65e2\u4f5c\u4e3a\u81ea\u5df1\u7684\u9ed8\u8ba4ACL\uff0c\u53c8\u4f5c\u4e3a\u81ea\u5df1\u7684\u8bbf\u95eeACL\u3002 \u6587\u4ef6\u7ee7\u627f\u76ee\u5f55\u9ed8\u8ba4ACL\u4f5c\u4e3a\u5176\u81ea\u5df1\u7684\u8bbf\u95eeACL\u3002 \u521b\u5efa\u6587\u4ef6\u7cfb\u7edf\u5bf9\u8c61\u7684\u6240\u6709\u7cfb\u7edf\u51fd\u6570\u90fd\u4f7f\u7528mode\u53c2\u6570\uff0c\u8be5\u53c2\u6570\u5b9a\u4e49\u4e86\u65b0\u521b\u5efa\u7684\u6587\u4ef6\u7cfb\u7edf\u5bf9\u8c61\u7684\u8bbf\u95ee\u6743\u9650\u3002 \u5982\u679c\u7236\u76ee\u5f55\u6ca1\u6709\u9ed8\u8ba4ACL\uff0c\u5219\u6839\u636eumask\u7684\u8bbe\u7f6e\u8bbe\u7f6e\u6743\u9650\u4f4d\u3002 \u5982\u679c\u7236\u76ee\u5f55\u5b58\u5728\u9ed8\u8ba4ACL\uff0c\u5219\u5206\u914d\u7ed9\u65b0\u5bf9\u8c61\u7684\u6743\u9650\u4f4d\u5219\u662fmode\u53c2\u6570\u6743\u9650\u4e0e\u9ed8\u8ba4ACL\u4e2d\u5b9a\u4e49\u7684\u6743\u9650\u7684\u903b\u8f91\u4e0e\u7684\u7ed3\u679c\u3002\u5728\u8fd9\u79cd\u60c5\u51b5\u4e0b\uff0c\u5ffd\u7565umask\u547d\u4ee4\u3002 \u9ed8\u8ba4ACL\u4e0d\u4f1a\u7acb\u5373\u5f71\u54cd\u8bbf\u95ee\u6743\u9650\u3002\u5b83\u4eec\u4ec5\u5728\u521b\u5efa\u6587\u4ef6\u7cfb\u7edf\u5bf9\u8c61\u65f6\u624d\u8d77\u4f5c\u7528\u3002\u8fd9\u4e9b\u65b0\u5bf9\u8c61\u4ec5\u4ece\u5176\u7236\u76ee\u5f55\u7684\u9ed8\u8ba4ACL\u7ee7\u627f\u6743\u9650\u3002 \u547d\u4ee4 mkdir \u5728\u521b\u5efa\u76ee\u5f55\u65f6\u4f1a\u7ee7\u627f\u9ed8\u8ba4ACL\u3002 $ su - pm1 $ getfacl mydir2 # file: mydir2 # owner: pm1 # group: project1 user::rwx user:tm2:rwx group::r-- group:project2:rwx mask::rwx other::--- $ mkdir ./mydir2/sub1 $ ll ./mydir2 drwxr-x---. 1 pm1 project1 0 Dec 4 13 :23 sub1 $ setfacl -d -m g:project2:-w- mydir2 $ mkdir ./mydir2/sub2 $ ll ./mydir2 drwxr-x---. 1 pm1 project1 0 Dec 4 13 :23 sub1 drwxrw----+ 1 pm1 project1 0 Dec 4 13 :27 sub2 $ getfacl ./mydir2/sub2 # file: mydir2/sub2 # owner: pm1 # group: project1 user::rwx group::r-- group:project2:-w- mask::rw- other::--- default:user::rwx default:group::r-- default:group:project2:-w- default:mask::rw- default:other::--- \u5728\u5bf9 mydir2 \u76ee\u5f55\u6dfb\u52a0\u9ed8\u8ba4ACL\u524d\uff0c\u521b\u5efa\u5b50\u76ee\u5f55 sub1 \uff0c\u6dfb\u52a0\u540e\u521b\u5efa\u5b50\u76ee\u5f55 sub2 \u3002\u53ef\u4ee5\u89c2\u5bdf\u5230 sub2 \u5230\u7ee7\u627f\u4e86 mydir2 \u7684\u9ed8\u8ba4ACL\u3002 $ su - tm2 $ cd /home/pm1/mydir2/sub2 -bash: cd: /home/pm1/mydir2/sub2: Permission denied \u4e0a\u4f8b\u4e2d\uff0c\u9ed8\u8ba4ACL\u4e2d\u6307\u5b9a\u7ec4 project2 \u53ea\u5177\u6709w\u6743\u9650\uff0c\u6240\u4ee5\u65e0\u6cd5\u6267\u884c cd \u547d\u4ee4\u8fdb\u5165\u8be5\u76ee\u5f55\u3002 \u8fd9\u8bf4\u660e\u6a21\u5f0f\u503cmode\u4e2d\u7ed9\u4e88\u7684\u6743\u9650 r \u88ab\u5c4f\u853d\u4e86\uff0c\u53ea\u4fdd\u7559\u4e86ACL\u4e2d\u6700\u5c0f\u7684\u6743\u9650 w \u3002","title":"8.7.2.\u76ee\u5f55\u7684\u9ed8\u8ba4ACL"},{"location":"linux/SRE/03-identity-security/#88acl","text":"ACL\u68c0\u67e5\u987a\u5e8f\uff1a Owner Named user Owning group Named group Other If \u8fdb\u7a0b\u7684\u7528\u6237\u6807\u8bc6\u662fOwner\uff0c\u5219owner\u7684ACL\u6761\u76ee\u51b3\u5b9a\u8bbf\u95ee\u6743\u9650 else if \u8fdb\u7a0b\u7684\u7528\u6237\u6807\u8bc6\u662fnamed user\uff0c\u5219name user\u7684ACL\u6761\u76ee\u7684\u6743\u9650\u51b3\u5b9a\u7533\u8bf7\u7684\u8bbf\u95ee\u6743\u9650 else if \u8fdb\u7a0b\u7684\u7ec4\u5c5e\u4e8eowning group\uff0c\u4e14owning group\u7684ACL\u6761\u76ee\u5305\u542b\u6240\u8bf7\u6c42\u7684\u8bbf\u95ee\u6743\u9650\uff0c\u5219\u6388\u4e88\u6240\u8bf7\u6c42\u7684\u6743\u9650 else if \u8fdb\u7a0b\u7684\u7ec4\u5c5e\u4e8enamed group\uff0c\u4e14named group\u7684ACL\u6761\u76ee\u5305\u542b\u6240\u8bf7\u6c42\u7684\u8bbf\u95ee\u6743\u9650\uff0c\u5219\u6388\u4e88\u6240\u8bf7\u6c42\u7684\u6743\u9650 else if \u8fdb\u7a0b\u7684\u7ec4\u5c5e\u4e8eowning group\u6216\u8005named group\uff0c\u4f46owning group\u6216\u8005named group\u7684ACL\u6761\u76ee\u4e0d\u5305\u542b\u6240\u8bf7\u6c42\u7684\u8bbf\u95ee\u6743\u9650\uff0c\u5219\u62d2\u7edd\u6240\u8bf7\u6c42\u7684\u6743\u9650 else ACL\u4e2d\u7684other\u6761\u76ee\u5904\u7406\u7533\u8bf7\u7684\u6743\u9650 If \u5982\u679c\u8fdb\u7a0b\u5339\u914d\u5230owner\u6216\u8005other\u6761\u76ee\u4e2d\u5305\u542b\u6240\u7533\u8bf7\u7684\u6743\u9650\uff0c\u5219\u6388\u4e88\u6743\u9650 else if \u5982\u679c\u8fdb\u7a0b\u5339\u914d\u5230named user\uff0cowning group\uff0c\u6216\u8005named group\u6761\u76ee\u4e2d\u5305\u542b\u6240\u7533\u8bf7\u7684\u6743\u9650\uff0c\u4e14maks\u6761\u76ee\u4e5f\u5305\u542b\u6240\u7533\u8bf7\u7684\u6743\u9650\uff0c\u5219\u6388\u4e88\u6743\u9650 else \u62d2\u7edd\u6743\u9650\u7533\u8bf7 \u5b9e\u9645\u5e94\u7528\u4e3e\u4f8b\uff1a udev\u4f7f\u7528ACL\u7ed9\u4e88\u767b\u5f55\u5230\u56fe\u5f62\u754c\u9762\u7684\u7528\u6237\u8bbf\u95ee\u8bbe\u5907\u7684\u6743\u9650\uff0c\u4f8b\u5982DVD\u9a71\u52a8\u5668 \u67d0\u4e9b\u5e94\u7528\u7a0b\u5e8f\u4e0d\u652f\u6301ACL Star Archiver\u662f\u4e00\u4e2a\u5b8c\u5168\u4fdd\u7559ACL\u7684\u5907\u4efd\u5e94\u7528\u7a0b\u5e8f\uff0c\u5176\u4ed6\u4eba\u53ef\u80fd\u4f1a\u4e5f\u53ef\u80fd\u4e0d\u4f1a\u4fdd\u7559\u5b83 \u8bb8\u591a\u7f16\u8f91\u5668\u548c\u6587\u4ef6\u7ba1\u7406\u5668\u4e0d\u5141\u8bb8\u5728\u5e94\u7528\u7a0b\u5e8f\u4e2d\u67e5\u770b\u6216\u8bbe\u7f6eACL","title":"8.8.ACL\u68c0\u67e5\u903b\u8f91"},{"location":"linux/SRE/04-TextTools/","text":"\u7b2c\u56db\u7ae0 \u6587\u672c\u7f16\u8f91 \u00b6 1.\u6587\u672c\u7f16\u8f91\u5668 \u00b6 1.1.vim\u5de5\u5177 \u00b6 vim\u547d\u4ee4\u683c\u5f0f\uff1a +# file : \u6253\u5f00\u6587\u4ef6\u540e\uff0c\u8ba9\u5149\u6807\u5904\u4e8e\u7b2c#\u884c\u9996\uff0c+\u9ed8\u8ba4\u884c\u5c3e +/PATTERN file : \u6253\u5f00\u6587\u4ef6\u6709\uff0c\u8ba9\u5149\u6807\u5904\u4e8e\u7b2c\u4e00\u4e2a\u88abPATTERN\u5339\u914d\u5230\u7684\u884c\u9996 -b file : \u4e8c\u8fdb\u5236\u65b9\u5f0f\u6253\u5f00\u6587\u4ef6 -d file1 file2 ... : \u6bd4\u8f83\u591a\u4e2a\u6587\u4ef6\uff0c\u76f8\u5f53\u4e8e vimdiff -m file : \u53ea\u8bfb\u65b9\u5f0f\u6253\u5f00\u6587\u4ef6 -e file : \u8fdb\u5165ex\u6a21\u5f0f\uff0c\u76f8\u5f53\u4e8e ex file -y file : vim\u4e09\u79cd\u5e38\u89c1\u6a21\u5f0f\uff1a \u666e\u901a\u6a21\u5f0fNormal\u6216\u547d\u4ee4\u6a21\u5f0f \u63d2\u5165Insert\u6216\u7f16\u8f91\u6a21\u5f0f \u6269\u5c55\u547d\u4ee4\u6a21\u5f0fExtended Command \u4e09\u79cd\u6a21\u5f0f\u5207\u6362 \u547d\u4ee4\u6a21\u5f0f\u2192\u63d2\u5165\u6a21\u5f0f i\uff1ainsert\uff0c\u5728\u5149\u6807\u5904\u8f93\u5165 I\uff1a\u5728\u5149\u6807\u6240\u5728\u884c\u9996\u8f93\u5165 a\uff1aappend\uff0c\u5728\u5149\u6807\u5904\u540e\u9762\u8f93\u5165 A\uff1a\u5728\u5149\u6807\u6240\u5728\u884c\u5c3e\u8f93\u5165 o\uff1a\u5728\u5149\u6807\u6240\u5728\u884c\u7684\u4e0b\u65b9\u6253\u5f00\u4e00\u4e2a\u65b0\u884c O\uff1a\u5728\u5149\u6807\u6240\u5728\u884c\u7684\u4e0a\u65b9\u6253\u5f00\u4e00\u4e2a\u65b0\u884c \u63d2\u5165\u6a21\u5f0f\u2192 ESC \u2192 \u547d\u4ee4\u6a21\u5f0f \u547d\u4ee4\u6a21\u5f0f\u2192 : \u2192 \u6269\u5c55\u547d\u4ee4\u6a21\u5f0f \u6269\u5c55\u547d\u4ee4\u6a21\u5f0f\u2192 ESC, enter \u2192 \u547d\u4ee4\u6a21\u5f0f \u6269\u5c55\u547d\u4ee4\u6a21\u5f0f\u5e38\u7528\u547d\u4ee4\uff1a :wq : \u4fdd\u5b58\u6587\u4ef6\u5e76\u9000\u51fa :w : \u4fdd\u5b58\u6587\u4ef6 :w filename : \u5199\u5165\u6307\u5b9a\u6587\u4ef6\uff0c\u76f8\u5f53\u4e8e\u53e6\u5b58\u4e3a :q! : \u653e\u5f03\u4efb\u4f55\u4fee\u6539\u5e76\u9000\u51fa ZQ : \u65e0\u6761\u4ef6\u9000\u51fa :join : \u5408\u5e76\u591a\u884c J : \u5408\u5e76\u4e24\u884c \u8bbe\u7f6e\uff1a\uff08\u53ef\u4ee5\u5728 /etc/vimrc \u6587\u4ef6\u4e2d\u914d\u7f6e\uff09 :set textwidth : \u8bbe\u7f6e\u6587\u672c\u5bbd\u5ea6\uff08\u4ece\u5de6\u5411\u53f3\u8ba1\u6570\uff09 :set wrapmargin=# : \u8bbe\u7f6e\u884c\u8fb9\u8ddd\uff08\u4ece\u53f3\u5411\u5de6\u8ba1\u6570\uff09 :set endofline : \u8bbe\u7f6e\u6587\u4ef6\u7ed3\u675f\u7b26 :set noendofline : \u53d6\u6d88\u6587\u4ef6\u7ed3\u675f\u7b26 :set wrap : \u81ea\u52a8\u6362\u884c :set nowrap : \u53d6\u6d88\u81ea\u52a8\u6362\u884c :set number : \u663e\u793a\u884c\u53f7 :set nonumber : \u53d6\u6d88\u663e\u793a\u884c\u53f7 :set list : \u8fdb\u5165List Mode\uff0c\u663e\u793aTab ^I\uff0c\u6362\u884c\u7b26\uff0c\u548c$\u663e\u793a :set nolist : \u9000\u51faList Mode :set ignorecase : \u5ffd\u7565\u5b57\u7b26\u7684\u5927\u5c0f\u5199 :set noic : \u4e0d\u5ffd\u7565\u5b57\u7b26\u5927\u5c0f\u5199 :set autoindent : \u542f\u7528\u81ea\u52a8\u7f29\u8fdb :set noai : \u5173\u95ed\u81ea\u52a8\u7f29\u8fdb :set hlsearch : \u542f\u7528\u9ad8\u4eae\u641c\u7d22 :set nohlsearch : \u5173\u95ed\u9ad8\u4eae\u641c\u7d22 :set fileformat=dos : \u542f\u7528windows\u683c\u5f0f :set fileformat=unix : \u542f\u7528unix\u683c\u5f0f :set expandtab : \u542f\u7528\u7a7a\u683c\u4ee3\u66ffTAB\uff0c\u9ed8\u8ba48\u4e2a\u7a7a\u683c\u4ee3\u66ff\u4e00\u4e2aTAB :set noexpandtab : \u5173\u95ed\u7a7a\u683c\u4ee3\u66ffTAB :set tabstop=# : \u6307\u5b9a#\u4e2a\u7a7a\u683c\u4ee3\u66ff\u4e00\u4e2aTAB :set shiftwidth=# : \u8bbe\u7f6e#\u4e2a\u7f29\u8fdb\u5bbd\u5ea6 :set cursorline : \u8bbe\u7f6e\u5149\u6807\u6240\u5728\u884c\u7684\u8868\u793a\u7ebf :set cursorline : \u5173\u95ed\u5149\u6807\u6240\u5728\u884c\u7684\u8868\u793a\u7ebf :set key=PASSWORD : \u542f\u7528\u5bc6\u7801\u4fdd\u62a4 :set key= : \u5173\u95ed\u5bc6\u7801\u4fdd\u62a4 :help option-list : \u83b7\u53d6\u5e2e\u52a9 \u67e5\u627e /pattern : \u4ece\u5149\u6807\u5f00\u59cb\u5904\u5411\u6587\u4ef6\u5c3e\u641c\u7d22pattern ?pattern : \u4ece\u5149\u6807\u5f00\u59cb\u5904\u5411\u6587\u4ef6\u9996\u641c\u7d22pattern n : \u5728\u540c\u4e00\u65b9\u5411\u91cd\u590d\u4e0a\u4e00\u6b21\u641c\u7d22\u547d\u4ee4 N : \u5728\u53cd\u65b9\u5411\u4e0a\u91cd\u590d\u4e0a\u4e00\u6b21\u641c\u7d22\u547d\u4ee4 # : \u5411\u4e0a\u5b8c\u6574\u5339\u914d\u5149\u6807\u4e0b\u7684\u5355\u8bcd, \u76f8\u5f53\u4e8e\uff1fword * : \u5411\u4e0b\u5b8c\u6574\u5339\u914d\u5149\u6807\u4e0b\u7684\u5355\u8bcd, \u76f8\u5f53\u4e8e/word % : \u67e5\u627e\u5bf9\u5e94\u7684( [ {\u5339\u914d nfx : \u5728\u5f53\u524d\u884c\u67e5\u627e\u5149\u6807\u540e\u7b2cn\u4e2ax\uff08\u4e00\u822c\u76f4\u63a5fx\uff09 \u66ff\u6362 :%s/\\n//g : \u5220\u9664\u6362\u884c\u7b26 :s/p1/p2/g : \u5c06\u5f53\u524d\u884c\u4e2d\u6240\u6709p1\u5747\u7528p2\u66ff\u4ee3, \u65e0g\uff0c\u5219\u53ea\u66ff\u6362\u7b2c\u4e00\u4e2a :s/p1/p2/c : \u67e5\u627e\u66ff\u6362\u8981\u6c42\u786e\u8ba4 :n1,n2s/p1/p2/g : \u5c06\u7b2cn1\u81f3n2\u884c\u4e2d\u6240\u6709p1\u5747\u7528p2\u66ff\u4ee3 :%s/p1/p2/g : \u5168\u5c40\uff0c\u4f7f\u7528p2\u66ff\u6362p1 :%s/p1/p2/gc : \u66ff\u6362\u524d\u8be2\u95ee :n,$s/vivian/sky/ : \u66ff\u6362\u7b2cn\u884c\u5f00\u59cb\u5230\u6700\u540e\u4e00\u884c\u4e2d\u6bcf\u4e00\u884c\u7684\u7b2c\u4e00\u4e2avivian\u4e3asky\uff0cn\u4e3a\u6570\u5b57 :.,$s/vivian/sky/g : \u66ff\u6362\u5f53\u524d\u884c\u5f00\u59cb\u5230\u6700\u540e\u4e00\u884c\u4e2d\u6bcf\u4e00\u884c\u6240\u6709vivian\u4e3asky :s/vivian\\//sky\\// : \u66ff\u6362\u5f53\u524d\u884c\u7b2c\u4e00\u4e2avivian/\u4e3asky/\uff0c\u53ef\u4ee5\u4f7f\u7528\\\u4f5c\u4e3a\u8f6c\u4e49\u7b26 :1,$s/^/some string/ : \u5728\u6587\u4ef6\u7684\u7b2c\u4e00\u884c\u81f3\u6700\u540e\u4e00\u884c\u7684\u884c\u9996\u524d\u63d2\u5165some string :%s/$/some string/g : \u5728\u6574\u4e2a\u6587\u4ef6\u6bcf\u4e00\u884c\u7684\u884c\u5c3e\u6dfb\u52a0some string :%s/\\s\\+$// : \u53bb\u6389\u6240\u6709\u7684\u884c\u5c3e\u7a7a\u683c\uff0c\u201c\\s\u201d\u8868\u793a\u7a7a\u767d\u5b57\u7b26\uff08\u7a7a\u683c\u548c\u5236\u8868\u7b26\uff09\uff0c\u201c+\u201d\u5bf9\u524d\u9762\u7684\u5b57\u7b26\u5339\u914d\u4e00\u6b21\u6216\u591a\u6b21\uff08\u8d8a\u591a\u8d8a\u597d\uff09\uff0c\u201c \\(\u201d\u5339\u914d\u884c\u5c3e\uff08\u4f7f\u7528\u201c\\$\u201d\u8868\u793a\u5355\u7eaf\u7684\u201c\\) \u201d\u5b57\u7b26\uff09 :%s/\\s\u2217\\n\\+/\\r/ : \u53bb\u6389\u6240\u6709\u7684\u7a7a\u767d\u884c\uff0c\u201c \\(\u201d\u548c\u201c\\) \u201d\u5bf9\u8868\u8fbe\u5f0f\u8fdb\u884c\u5206\u7ec4\uff0c\u4f7f\u5176\u88ab\u89c6\u4f5c\u4e00\u4e2a\u4e0d\u53ef\u5206\u5272\u7684\u6574\u4f53 :%s!\\s*//.*!! : \u53bb\u6389\u6240\u6709\u7684\u201c//\u201d\u6ce8\u91ca :%s!\\s*/\\*\\_.\\{-}\\*/\\s*!!g : \u53bb\u6389\u6240\u6709\u7684\u201c/**/\u201d\u6ce8\u91ca :%s= *$== : \u5c06\u6240\u6709\u884c\u5c3e\u591a\u4f59\u7684\u7a7a\u683c\u5220\u9664 :g/^\\s*$/d : \u5c06\u6240\u6709\u4e0d\u5305\u542b\u5b57\u7b26(\u7a7a\u683c\u4e5f\u4e0d\u5305\u542b)\u7684\u7a7a\u884c\u5220\u9664 r : \u66ff\u6362\u5f53\u524d\u5b57\u7b26 R : \u66ff\u6362\u5f53\u524d\u5b57\u7b26\u53ca\u5176\u540e\u7684\u5b57\u7b26\uff0c\u76f4\u81f3\u6309ESC\u952e \u7f16\u8f91 h : \u5149\u6807\u5de6\u79fb\u4e00\u4e2a\u5b57\u7b26[\u56de\u9000\u952eBackspace] l : \u5149\u6807\u53f3\u79fb\u4e00\u4e2a\u5b57\u7b26[\u7a7a\u683c\u952eSpace] K : \u5149\u6807\u4e0a\u79fb\u4e00\u884c j : \u5149\u6807\u4e0b\u79fb\u4e00\u884c w : \u5149\u6807\u8df3\u5230\u4e0b\u4e2aword\u7684\u7b2c\u4e00\u4e2a\u5b57\u6bcd(\u5305\u62ec\u6807\u70b9\u7b26\u53f7) [\u5e38\u7528] W : \u79fb\u5230\u4e0b\u4e00\u4e2a\u5b57\u7684\u5f00\u5934\uff0c\u5ffd\u7565\u6807\u70b9\u7b26\u53f7 B : \u5149\u6807\u56de\u5230\u4e0a\u4e2aword\u7684\u7b2c\u4e00\u4e2a\u5b57\u6bcd B : \u79fb\u5230\u524d\u4e00\u4e2a\u5b57\u7684\u5f00\u5934\uff0c\u5ffd\u7565\u6807\u70b9\u7b26\u53f7 BACK E : \u5149\u6807\u8df3\u5230\u4e0b\u4e2aword\u7684\u6700\u540e\u4e00\u4e2a\u5b57\u6bcd E : \u79fb\u5230\u4e0b\u4e00\u4e2a\u5b57\u7684\u7ed3\u5c3e\uff0c\u5ffd\u7565\u6807\u70b9\u7b26\u53f7 END 0 : \u79fb\u5230\u5f53\u524d\u4e00\u884c\u7684\u5f00\u59cb[Home] $ : \u79fb\u5230\u5f53\u524d\u4e00\u884c\u7684\u6700\u540e[End] ^ : \u547d\u4ee4\u5c06\u5149\u6807\u79fb\u52a8\u5230\u5f53\u524d\u884c\u7684\u7b2c\u4e00\u4e2a\u975e\u7a7a\u767d\u5b57\u7b26\u4e0a g_ : \u5230\u672c\u884c\u6700\u540e\u4e00\u4e2a\u4e0d\u662fblank\u5b57\u7b26\u7684\u4f4d\u7f6e Enter : \u5149\u6807\u4e0b\u79fb\u4e00\u884c n+ : \u5149\u6807\u4e0b\u79fbn\u884c\u3010\u6309\u4e0a\u6863\u952e \u6570\u5b57shift +\u3011 n- : \u5149\u6807\u4e0a\u79fbn\u884c G : \u79fb\u5230\u6587\u4ef6\u7684\u6700\u540e\u4e00\u884c nG \u6216\u8005 :n : \u79fb\u5230\u6587\u4ef6\u7684\u7b2cn\u884c\ue5e5\ue5e5\ue5e5 gg : \u79fb\u52a8\u5230\u6587\u6863\u7684\u5f00\u59cb [[ : \u6587\u4ef6\u5f00\u59cb\u4f4d\u7f6e\u2014\u2014\u5f00\u59cb\u884c ]] : \u6587\u4ef6\u7ed3\u675f\u4f4d\u7f6e\u2014\u2014\u672b\u5c3e\u884c H : \u5149\u6807\u79fb\u81f3\u5c4f\u5e55\u9876\u884cHEAD\u3002\u5149\u6807\u5b9a\u4f4d\u5728\u663e\u793a\u5c4f\u7684\u7b2c\u4e00\u884c M : \u79fb\u5230\u5c4f\u5e55\u7684\u4e2d\u95f4\u884c\u5f00\u5934 Middle\u3002\u5149\u6807\u5b9a\u4f4d\u5728\u663e\u793a\u5c4f\u7684\u4e2d\u95f4 L : \u79fb\u5230\u5c4f\u5e55\u7684\u6700\u540e\u4e00\u884cLAST\u3002\u5149\u6807\u5b9a\u4f4d\u5728\u663e\u793a\u5c4f\u7684\u6700\u540e\u4e00\u884c ( : \u5149\u6807\u79fb\u81f3\u53e5\u9996 ) : \u5149\u6807\u79fb\u81f3\u53e5\u5c3e { : \u79fb\u5230\u6bb5\u843d\u7684\u5f00\u5934 } : \u79fb\u5230\u4e0b\u4e00\u4e2a\u6bb5\u843d\u7684\u5f00\u5934 % : \u5339\u914d\u62ec\u53f7\u79fb\u52a8\uff0c\u5305\u62ec (, {, [.\uff08\u9700\u8981\u628a\u5149\u6807\u5148\u79fb\u5230\u62ec\u53f7\u4e0a\uff09\u8df3\u8f6c\u5230\u4e0e\u4e4b\u5339\u914d\u7684\u62ec\u53f7\u5904 * \u548c # : \u5339\u914d\u5149\u6807\u5f53\u524d\u6240\u5728\u7684\u5355\u8bcd\uff0c\u79fb\u52a8\u5149\u6807\u5230\u4e0b\u4e00\u4e2a\uff08\u6216\u4e0a\u4e00\u4e2a\uff09\u5339\u914d\u5355\u8bcd\uff08*\u662f\u4e0b\u4e00\u4e2a\uff0c#\u662f\u4e0a\u4e00\u4e2a\uff09 zf : \u6298\u53e0\uff08\u9700\u52a0\u65b9\u5411\u952e\uff09 zo : \u5c55\u5f00\uff08\u7a7a\u683c\u4e5f\u53ef\u4ee5\u5c55\u5f00\uff09 CTRL+u : \u5411\u6587\u4ef6\u9996\u7ffb\u534a\u5c4fup CTRL+d : \u5411\u6587\u4ef6\u5c3e\u7ffb\u534a\u5c4fdown CTRL+f : \u5411\u6587\u4ef6\u5c3e\u7ffb\u4e00\u5c4f forward (fact\u6574\u5c4f\u53bb\u4e24\u884c) CTRL+b : \u5411\u6587\u4ef6\u9996\u7ffb\u4e00\u5c4fback (fact\u6574\u5c4f\u53bb\u4e24\u884c) CTRL-] : \u8df3\u8f6c\u5230\u5f53\u524d\u5149\u6807\u6240\u5728\u5355\u8bcd\u5bf9\u5e94\u7684\u4e3b\u9898 CTRL-O : \u56de\u5230\u524d\u4e00\u4e2a\u4f4d\u7f6e SHIFT+V : \u9009\u62e9\u6574\u884c zz : \u547d\u4ee4\u4f1a\u628a\u5f53\u524d\u884c\u7f6e\u4e3a\u5c4f\u5e55\u6b63\u4e2d\u592e(z\u5b57\u53d6\u5176\u8c61\u5f62\u610f\u4e49\u6a21\u62df\u4e00\u5f20\u7eb8\u7684\u6298\u53e0\u53ca\u53d8\u5f62\u4f4d\u7f6e\u91cd\u7f6e) zt : \u547d\u4ee4\u4f1a\u628a\u5f53\u524d\u884c\u7f6e\u4e8e\u5c4f\u5e55\u9876\u7aef(top) zb : \u547d\u4ee4\u4f1a\u628a\u5f53\u524d\u884c\u7f6e\u4e8e\u5c4f\u5e55\u5e95\u7aef(bottom) 50% : \u5149\u6807\u5b9a\u4f4d\u5728\u6587\u4ef6\u7684\u4e2d\u95f4 ` : \u8df3\u8f6c\u5230\u6700\u8fd1\u5149\u6807\u5b9a\u4f4d\u7684\u4f4d\u7f6e\uff08\u53ea\u80fd\u8bb0\u5fc6\u6700\u8fd1\u4e24\u4e2a\u4f4d\u7f6e\uff09 \u53cd\u5f15\u53f7 I : \u5728\u5149\u6807\u524d\u5f00\u59cb\u63d2\u5165\u5b57\u7b26 insert I : \u5728\u5f53\u524d\u884c\u9996\u5f00\u59cb\u63d2\u5165\u5b57\u7b26 A : \u5728\u5149\u6807\u4f4d\u7f6e\u540e\u5f00\u59cb\u52a0\u5b57 append A : \u5728\u5149\u6807\u6240\u5728\u884c\u7684\u6700\u540e\u9762\u5f00\u59cb\u52a0\u5b57 O : \u5728\u5149\u6807\u4e0b\u52a0\u4e00\u7a7a\u767d\u884c\u5e76\u5f00\u59cb\u52a0\u5b57 open O : \u5728\u5149\u6807\u4e0a\u52a0\u4e00\u7a7a\u767d\u884c\u5e76\u5f00\u59cb\u52a0\u5b57 R : \u66ff\u6362\u5f53\u524d\u5b57\u7b26 R : \u66ff\u6362\u5f53\u524d\u5b57\u7b26\u53ca\u5176\u540e\u7684\u5b57\u7b26\u3010\u5f53\u524d\u53ca\u5176\u540e\u5b57\u7b26\u88ab\u8986\u76d6\u3011 S : \u9ed8\u8ba4\u5220\u9664\u5149\u6807\u6240\u5728\u5b57\u7b26\uff0c\u8f93\u5165\u5185\u5bb9\u63d2\u5165\u4e4b= xi S : \u9ed8\u8ba4\u5220\u9664\u5f53\u524d\u884c\u5185\u5bb9\uff0c\u8f93\u5165\u5185\u5bb9\u4f5c\u4e3a\u5f53\u524d\u884c\u65b0\u5185\u5bb9= dd+o nx : \u5220\u9664\u7531\u5149\u6807\u4f4d\u7f6e\u8d77\u59cb\u540e\u7684n\u4e2a\u5b57\u7b26\uff08\u542b\u5149\u6807\u4f4d\u7f6e\uff09x =dl(\u5220\u9664\u5f53\u524d\u5149\u6807\u4e0b\u7684\u5b57\u7b26) nX : \u5220\u9664\u7531\u5149\u6807\u4f4d\u7f6e\u8d77\u59cb\u524d\u7684n\u4e2a\u5b57\u7b26\uff08\u542b\u5149\u6807\u4f4d\u7f6e\uff09X =dh(\u5220\u9664\u5f53\u524d\u5149\u6807\u5de6\u8fb9\u7684\u5b57\u7b26) d0 : \u5220\u81f3\u884c\u9996 d$ : \u5220\u81f3\u884c\u5c3e dfa : \u8868\u793a\u5220\u9664\u4ece\u5f53\u524d\u5149\u6807\u5230\u5149\u6807\u540e\u9762\u7684\u7b2c\u4e00\u4e2aa\u5b57\u7b26\u4e4b\u95f4\u7684\u5185\u5bb9 D : \u4ee3\u8868d$(\u5220\u9664\u5230\u884c\u5c3e\u7684\u5185\u5bb9) C : \u4ee3\u8868c$(\u4fee\u6539\u5230\u884c\u5c3e\u7684\u5185\u5bb9) ndw : \u5220\u9664\u5149\u6807\u5904\u5f00\u59cb\u53ca\u5176\u540e\u7684n-1\u4e2a\u5b57 ndb : \u5220\u9664\u5149\u6807\u5904\u5f00\u59cb\u53ca\u5176\u524d\u7684n-1\u4e2a\u5b57 diw : \u5220\u9664\u5f53\u524d\u5149\u6807\u6240\u5728\u7684word(\u4e0d\u5305\u62ec\u7a7a\u767d\u5b57\u7b26)\uff0c\u610f\u4e3aDelete Inner Word \u4e24\u4e2a\u7b26\u53f7\u4e4b\u95f4\u7684\u5355\u8bcd daw : \u5220\u9664\u5f53\u524d\u5149\u6807\u6240\u5728\u7684word(\u5305\u62ec\u7a7a\u767d\u5b57\u7b26)\uff0c\u610f\u4e3aDelete A Word ndd : \u5220\u9664\u5f53\u524d\u884c\u53ca\u5176\u540en-1\u884c :n1,n2 d : \u5c06 n1\u884c\u5230n2\u884c\u4e4b\u95f4\u7684\u5185\u5bb9\u5220\u9664 dG : \u5220\u9664\u5f53\u524d\u884c\u81f3\u6587\u4ef6\u5c3e\u7684\u5185\u5bb9 Dgg : \u5220\u9664\u5f53\u524d\u884c\u81f3\u6587\u4ef6\u5934\u7684\u5185\u5bb9 d+enter : \u5220\u96642\u884c\u3010\u5305\u62ec\u5149\u6807\u4e00\u884c\u3011 cw : \u5220\u9664\u5f53\u524d\u5b57\uff0c\u5e76\u8fdb\u5165\u8f93\u5165\u6a21\u5f0f\u3010\u5f88\u597d\u7528\uff0c\u5feb\u901f\u66f4\u6539\u4e00\u4e2a\u5355\u8bcd\u3011\u76f8\u5f53\u4e8edw+i ncw : \u5220\u9664\u5f53\u524d\u5b57\u53ca\u5176\u540e\u7684n-1\u4e2a\u5b57\uff0c\u5e76\u8fdb\u5165\u8f93\u5165\u6a21\u5f0f\\\u4fee\u6539\u6307\u5b9a\u6570\u76ee\u7684\u5b57 cc : \u5220\u9664\u5f53\u524d\u884c\uff0c\u5e76\u8fdb\u5165\u8f93\u5165\u6a21\u5f0f ncc : \u5220\u9664\u5f53\u524d\u884c\u53ca\u5176\u540e\u7684n-1\u884c\uff0c\u5e76\u8fdb\u5165\u8f93\u5165\u6a21\u5f0f guw : \u5149\u6807\u4e0b\u7684\u5355\u8bcd\u53d8\u4e3a\u5c0f\u5199 gUw : \u5149\u6807\u4e0b\u7684\u5355\u8bcd\u53d8\u4e3a\u5927\u5199 xp : \u5de6\u53f3\u4ea4\u6362\u5149\u6807\u5904\u4e24\u5b57\u7b26\u7684\u4f4d\u7f6e ga : \u663e\u793a\u5149\u6807\u4e0b\u7684\u5b57\u7b26\u5728\u5f53\u524d\u4f7f\u7528\u7684encoding\u4e0b\u7684\u5185\u7801 nyl : \u590d\u5236n\u4e2a\u5b57\u7b26(\u4e5f\u53efnyh) yw : \u590d\u5236\u4e00\u4e2a\u5355\u8bcd y0 : \u8868\u793a\u62f7\u8d1d\u4ece\u5f53\u524d\u5149\u6807\u5230\u5149\u6807\u6240\u5728\u884c\u9996\u7684\u5185\u5bb9 y$ : \u590d\u5236\u4ece\u5f53\u524d\u4f4d\u7f6e\u5230\u884c\u5c3e yfa : \u8868\u793a\u62f7\u8d1d\u4ece\u5f53\u524d\u5149\u6807\u5230\u5149\u6807\u540e\u9762\u7684\u7b2c\u4e00\u4e2aa\u5b57\u7b26\u4e4b\u95f4\u7684\u5185\u5bb9 yG : \u590d\u5236\u4ece\u6240\u5728\u884c\u5230\u6700\u540e\u4e00\u884c nyy : \u5c06\u5149\u6807\u6240\u5728\u4f4d\u7f6e\u5f00\u59cb\u7684n\u884c\u6570\u636e\u590d\u5236\u6682\u5b58, \u590d\u5236\u4e00\u6574\u884c CTRL+v \u65b9\u5411y : \u5217\u9009\u62e9\u6a21\u5f0f\uff0c\u590d\u5236\u9009\u62e9\u7684\u5f88\u591a\u884c\uff1a\u5148\u4f7f\u7528V\u8fdb\u5165visual\u6a21\u5f0f\uff0c\u7136\u540ej\u5411\u4e0b\u79fb\u52a8\u5230\u4f60\u60f3\u590d\u5236\u7684\u884c\u4e3a\u6b62\uff0c\u7136\u540ey p : \u590d\u5236\u6682\u5b58\u6570\u636e\u5728\u5149\u6807\u7684\u4e0b\u4e00\u884c P : \u590d\u5236\u6682\u5b58\u6570\u636e\u5728\u5149\u6807\u7684\u4e0a\u4e00\u884c :n1,n2 co n3 : \u5c06n1\u884c\u5230n2\u884c\u4e4b\u95f4\u7684\u5185\u5bb9\u62f7\u8d1d\u5230\u7b2cn3+1\u884c\u3010n3\u884c\u7684\u4e0b\u4e00\u884c\u3011 :n1,n2 m n3 : \u5c06n1\u884c\u5230n2\u884c\u4e4b\u95f4\u7684\u5185\u5bb9\u79fb\u81f3\u5230\u7b2cn3\u884c\u4e0b J : \u628a\u4e0b\u4e00\u884c\u7684\u6570\u636e\u8fde\u63a5\u5230\u672c\u884c\u4e4b\u540e, \u591a\u4e00\u7a7a\u683c ~ : \u6539\u53d8\u5f53\u524d\u5149\u6807\u4e0b\u5b57\u7b26\u7684\u5927\u5c0f\u5199 \u5176\u4ed6 . : \u91cd\u590d\u524d\u4e00\u6307\u4ee4 u : \u53d6\u6d88\u524d\u4e00\u6307\u4ee4undo, :u\u4e5f\u884c\uff0c\u4e00\u822c\u4e0d\u7528\uff0c\u64cd\u4f5c\u592a\u591a Ctrl + r : \u6062\u590d\u3010\u53ea\u5bf9u\u6709\u6548\u3011redo Ctrl + l : \u5237\u65b0\u5c4f\u5e55\u663e\u793a Ctrl+v \u7136\u540e ctrl+A\u662f^A Ctrl+I\u662f\\t : \u8f93\u5165\u7279\u6b8a\u5b57\u7b26 Ctrl+v\u7136\u540e\u7528j\u3001k\u3001l\u3001h\u6216\u65b9\u5411\u952e\u4e0a\u4e0b\u9009\u4e2d\u591a\u5217\uff0c\u4e4b\u540e I I a A r x\u7b49\uff0c\u6700\u540e\u6309esc\uff0c\u751f\u6548 : Vim\u5217\u64cd\u4f5c 2.\u6587\u672c\u5904\u7406\u5de5\u5177 \u00b6 2.1.\u663e\u793a\u6587\u672c\u5185\u5bb9 cat \u00b6 \u547d\u4ee4 cat \u4e3b\u8981\u53c2\u6570\u8bf4\u660e\uff1a -E \uff1a\u663e\u793a\u884c\u7ed3\u675f\u7b26 $ -A \uff1a\u663e\u793a\u6240\u6709\u63a7\u5236\u7b26 -n \uff1a\u5bf9\u663e\u793a\u51fa\u7684\u6bcf\u4e00\u884c\u8fdb\u884c\u7f16\u53f7 -b \uff1a\u975e\u7a7a\u884c\u7f16\u53f7 -s \uff1a\u538b\u7f29\u8fde\u7eed\u7684\u7a7a\u884c\u6210\u4e00\u884c \u4e3e\u4f8b\uff1a cat -nA user-list.txt 1 user0$ 2 user1$ 3 user2$ 4 user3$ 5 user4$ 6 user5$ 7 user6$ 8 user7$ 9 user8$ 10 user9$ 2.2.\u663e\u793a\u6587\u672c\u884c\u53f7 nl \u00b6 \u76f8\u5f53\u4e8e\u547d\u4ee4 cat -b \u3002 \u547d\u4ee4 nl \u4e3b\u8981\u53c2\u6570\u8bf4\u660e\uff1a -b \uff1a\u6307\u5b9a\u884c\u53f7\u6307\u5b9a\u7684\u65b9\u5f0f\uff0c\u4e3b\u8981\u6709\u4e24\u79cd\uff1a -b a \uff1a\u8868\u793a\u4e0d\u8bba\u662f\u5426\u4e3a\u7a7a\u884c\uff0c\u4e5f\u540c\u6837\u5217\u51fa\u884c\u53f7\uff08\u7c7b\u4f3c cat -n\uff09\uff1b -b t \uff1a\u5982\u679c\u6709\u7a7a\u884c\uff0c\u7a7a\u7684\u90a3\u4e00\u884c\u4e0d\u8981\u5217\u51fa\u884c\u53f7\uff08\u9ed8\u8ba4\u503c\uff09\uff1b -n \uff1a\u5217\u51fa\u884c\u53f7\u8868\u793a\u7684\u65b9\u6cd5\uff0c\u4e3b\u8981\u6709\u4e09\u79cd\uff1a -n ln \uff1a\u884c\u53f7\u5728\u5c4f\u5e55\u7684\u6700\u5de6\u65b9\u663e\u793a\uff1b\u6ca1\u6709\u524d\u5bfc0\uff1b -n rn \uff1a\u884c\u53f7\u5728\u81ea\u5df1\u680f\u4f4d\u7684\u6700\u53f3\u65b9\u663e\u793a\uff0c\u6ca1\u6709\u524d\u5bfc0\uff1b -n rz \uff1a\u884c\u53f7\u5728\u81ea\u5df1\u680f\u4f4d\u7684\u6700\u53f3\u65b9\u663e\u793a\uff0c\u6709\u524d\u5bfc0\uff1b -w \uff1a\u884c\u53f7\u680f\u4f4d\u7684\u5360\u7528\u7684\u4f4d\u6570\u3002 -p \uff1a\u5728\u903b\u8f91\u5b9a\u754c\u7b26\u5904\u4e0d\u91cd\u65b0\u5f00\u59cb\u8ba1 \u4e3e\u4f8b\uff1a $ nl -b a -n rz user-list.txt 000001 user0 000002 user1 000003 user2 000004 user3 000005 user4 000006 user5 000007 user6 000008 user7 000009 user8 000010 user9 2.3.\u9006\u5411\u663e\u793a\u6587\u672c\u5185\u5bb9 tac \u00b6 \u547d\u4ee4 tac \u9006\u5411\u663e\u793a\u6587\u672c\u5185\u5bb9\u3002 \u4e3e\u4f8b\uff1a $ tac user-list.txt user9 user8 user7 user6 user5 user4 user3 user2 user1 user0 \u4e3e\u4f8b\uff1a $ seq 10 | tac 10 9 8 7 6 5 4 3 2 1 2.4.\u9006\u5411\u663e\u793a\u540c\u884c\u5185\u5bb9 rev \u00b6 \u547d\u4ee4 rev \u9006\u5411\u663e\u793a\u540c\u4e00\u884c\u7684\u5185\u5bb9\u3002 \u4e3e\u4f8b\uff1a $ rev user-list.txt 0resu 1resu 2resu 3resu 4resu 5resu 6resu 7resu 8resu 9resu \u4e3e\u4f8b\uff1a $ echo { 1 ..10 } | rev 01 9 8 7 6 5 4 3 2 1 2.5.\u663e\u793a\u975e\u6587\u672c\u6587\u4ef6\u5185\u5bb9 hexdump \u00b6 \u547d\u4ee4 hexdump \u547d\u4ee4\u4e00\u822c\u7528\u6765\u67e5\u770b\u201c\u4e8c\u8fdb\u5236\u201d\u6587\u4ef6\u7684\u5341\u516d\u8fdb\u5236\u7f16\u7801 \u4e3e\u4f8b\uff1a $ hexdump -C -n 32 cp 00000000 7f 45 4c 46 02 01 01 00 00 00 00 00 00 00 00 00 | .ELF............ | 00000010 03 00 3e 00 01 00 00 00 e0 48 00 00 00 00 00 00 | ..>......H...... | 00000020 2.6.\u5206\u9875\u67e5\u770b\u6587\u4ef6\u5185\u5bb9 \u00b6 \u547d\u4ee4 more \u548c less \u53ef\u4ee5\u5b9e\u73b0\u5206\u9875\u67e5\u770b\u6587\u4ef6\u5185\u5bb9\u3002 \u547d\u4ee4 less \u914d\u5408\u7ba1\u9053\u7b26\u4f7f\u7528\u3002 tree -d /etc | less 2.7.\u663e\u793a\u6587\u4ef6\u5934\u90e8\u5185\u5bb9 head \u00b6 \u547d\u4ee4 head \u663e\u793a\u6587\u4ef6\u5934\u90e8\u5185\u5bb9\u3002 head -c 20 cp : \u663e\u793a\u6587\u4ef6\u524d20\u5b57\u8282\u5185\u5bb9 head -n 20 zdiff : \u663e\u793a\u6587\u4ef6\u524d20\u884c\u5185\u5bb9 head -20 zdiff : \u663e\u793a\u6587\u4ef6\u524d20\u884c\u5185\u5bb9 $ echo \"\u6211\u662f\u8c01\" | head -c3 \u6211 $ echo \"\u6211\u662f\u8c01\" | head -c6 \u6211\u662f cat /dev/urandom | tr -dc '[:alnum]' | head -c 10 | tee passwd.txt $ cat user-list.txt user0 user1 user2 user3 user4 user5 user6 user7 user8 user9 $ head -n -3 user-list.txt user0 user1 user2 user3 user4 user5 user6 2.8.\u663e\u793a\u6587\u4ef6\u5c3e\u90e8\u5185\u5bb9 tail \u00b6 \u547d\u4ee4 tail \u663e\u793a\u6587\u4ef6\u5934\u90e8\u5185\u5bb9\u3002 tail -c 200 cp : \u663e\u793a\u6587\u4ef6\u5c3e\u90e8200\u4e2a\u5b57\u8282\u7684\u5185\u5bb9 tail -n 3 user-list.txt : \u663e\u793a\u6587\u4ef6\u6700\u540e3\u884c tail -n -3 user-list.txt : \u663e\u793a\u4ece-3\u884c\u5230\u6587\u4ef6\u7ed3\u675f\uff08\u5373\u6700\u540e\u4e09\u884c\uff09 tail -3 user-list.txt : \u663e\u793a\u6587\u4ef6\u6700\u540e3\u884c tail -f /var/log/messages : \u8ddf\u8e2a\u663e\u793a\u6587\u4ef6redo.log\u6587\u4ef6\u5185\u5bb9\uff0c\u5f53\u6587\u4ef6\u5220\u9664\uff0c\u518d\u5efa\u540c\u540d\u6587\u4ef6\uff0c\u65e0\u6cd5\u7ee7\u7eed\u8ffd\u8e2a tail -F /var/log/messages : \u8ddf\u8e2a\u663e\u793a\u6587\u4ef6redo.log\u6587\u4ef6\u5185\u5bb9\uff0c\u5f53\u6587\u4ef6\u5220\u9664\uff0c\u518d\u5efa\u540c\u540d\u6587\u4ef6\uff0c\u7ee7\u7eed\u8ffd\u8e2a 2.9.\u6309\u5217\u62bd\u53d6\u6587\u672c cut \u00b6 \u547d\u4ee4 cut \u53ef\u4ee5\u63d0\u53d6\u6587\u672c\u6587\u4ef6\u6216\u8005stdin\u6570\u636e\u7684\u6307\u5b9a\u5217\u5185\u5bb9\u3002 \u9009\u9879\uff1a -f : \u901a\u8fc7\u6307\u5b9a\u54ea\u4e00\u4e2a\u5b57\u6bb5\u8fdb\u884c\u63d0\u53d6\u3002cut\u547d\u4ee4\u4f7f\u7528\u201cTAB\u201d\u4f5c\u4e3a\u9ed8\u8ba4\u7684\u5b57\u6bb5\u5206\u9694\u7b26 -d : \u201cTAB\u201d\u662f\u9ed8\u8ba4\u7684\u5206\u9694\u7b26\uff0c\u4f7f\u7528\u6b64\u9009\u9879\u53ef\u4ee5\u66f4\u6539\u4e3a\u5176\u4ed6\u7684\u5206\u9694\u7b26 --complement : \u6b64\u9009\u9879\u7528\u4e8e\u6392\u9664\u6240\u6307\u5b9a\u7684\u5b57\u6bb5 --output-delimiter=STRING : \u6307\u5b9a\u8f93\u51fa\u5185\u5bb9\u7684\u5206\u9694\u7b26 -c : \u6309\u5b57\u7b26\u5207\u5272 \u53d6/etc/passwd\u6587\u4ef6\u7b2c1\u5217\u5185\u5bb9\uff0c\u4ee5 : \u4e3a\u5206\u9694\u7b26\uff08\u53ea\u53d6\u524d\u4e09\u884c\uff09 $ cut -d ':' -f 1 /etc/passwd | head -3 root messagebus systemd-network \u53d6/etc/passwd\u6587\u4ef6\u7b2c1\u548c6\u5217\u5185\u5bb9\uff0c\u4ee5 : \u4e3a\u5206\u9694\u7b26\uff08\u53ea\u53d6\u524d\u4e09\u884c\uff09 cut -d ':' -f 1 ,6 /etc/passwd | head -3 root:/root messagebus:/run/dbus systemd-network:/ \u53d6/etc/passwd\u6587\u4ef6\u7b2c1\u52303\u5217\u4ee5\u53ca\u7b2c6\u5217\u5185\u5bb9\uff0c\u4ee5 : \u4e3a\u5206\u9694\u7b26\uff08\u53ea\u53d6\u524d\u4e09\u884c\uff09 $ cut -d ':' -f 1 -3,6 /etc/passwd | head -3 root:x:0:/root messagebus:x:499:/run/dbus systemd-network:x:497:/ \u4e0b\u9762\u4f7f\u7528 --output-delimiter \u9009\u9879\uff0c\u628a\u8f93\u51fa\u7ed3\u679c\u4e2d\u7684\u5206\u9694\u7b26 : \u5168\u90e8\u66ff\u6362\u6210 --- \u3002 $ cat /etc/passwd | sort | head -3 admin3:x:1020:100::/home/admin3:/bin/bash at:x:25:25:Batch jobs daemon:/var/spool/atjobs:/usr/sbin/nologin bin:x:1:1:bin:/bin:/usr/sbin/nologin $ cut -d \":\" -f 1 ,7 /etc/passwd | sort | head -3 admin3:/bin/bash at:/usr/sbin/nologin bin:/usr/sbin/nologin $ cut -d \":\" -f 1 ,7 --output-delimiter = \"---\" /etc/passwd | sort | head -3 admin3---/bin/bash at---/usr/sbin/nologin bin---/usr/sbin/nologin --output-delimiter \u9009\u9879\u4e5f\u53ef\u4ee5\u5229\u7528\u6765\u8fdb\u884c\u8ba1\u7b97\u3002 $ echo { 1 ..10 } | cut -d \" \" -f 1 -10 --output-delimiter = \"+\" | bc 55 \u4ece ifconfig \u547d\u4ee4\u4e2d\u622a\u53d6\u5f53\u524d\u4e3b\u673a\u7684ip\u5730\u5740\u3002\uff08openSUSE\u9700\u8981\u5b89\u88c5\u5305 net-tools-deprecated \uff09 $ ifconfig | head -2 | tail -1 inet 192 .168.10.210 netmask 255 .255.255.0 broadcast 192 .168.10.255 $ ifconfig | head -2 | tail -1 | cut -d \" \" -f 10 192 .168.10.210 \u6216\u8005 $ ip addr list | grep eth0 | tail -1 | cut -d \" \" -f 6 192 .168.10.210/24 \u57fa\u4e8e\u4e0a\u9762\u7ed3\u679c\uff0c\u53ef\u4ee5\u5c1d\u8bd5\u901a\u8fc7 --complement \u53c2\u6570\uff0c\u4ee5 / \u4e3a\u5206\u9694\u7b26\uff0c\u6392\u9664\u7b2c\u4e8c\u5217 24 \uff0c\u53ea\u8f93\u51fa\u7b2c\u4e00\u5217IP\u5730\u5740\u3002 ip addr list | grep eth0 | tail -1 | cut -d \" \" -f 6 | cut -d \"/\" --complement -f 2 192 .168.10.210 \u663e\u793a df \u547d\u4ee4\u8f93\u51fa\u4e2d\u7684\u5206\u533a\u4f7f\u7528\u7387\u3002 $ df | tr -s ' ' | cut -d ' ' -f 5 | tr -d % Use 0 0 2 0 8 8 8 8 8 8 8 8 8 8 8 0 \u65b9\u6cd52\uff1a\u5148\u628a\u7a7a\u683c\u5168\u90e8\u66ff\u6362\u6210%\uff0c\u518d\u53bb\u91cd\u3002 df | tr -s ' ' % | cut -d % -f 5 Use 0 0 2 0 8 8 8 8 8 8 8 8 8 8 8 0 2.10.\u5408\u5e76\u591a\u4e2a\u6587\u4ef6 paste \u00b6 \u547d\u4ee4 paste \u5e38\u7528\u9009\u9879\uff1a -d \uff1a\u6307\u5b9a\u5206\u9694\u7b26\uff0c\u9ed8\u8ba4\u662fTAB -s \uff1a\u6240\u6709\u884c\u5408\u6210\u4e00\u884c\u663e\u793a \u751f\u6210 alpha.log \u548c seq.log \u3002 for i in { a..z } ; do echo $i >> alpha.log ; done seq 10 > seq.log \u7528 paste \u547d\u4ee4\u5408\u5e76\u8fd92\u4e2a\u6587\u4ef6\u3002 $ paste alpha.log seq.log a 1 b 2 c 3 d 4 e 5 f 6 g 7 h 8 i 9 j 10 k l m n o p q r s t u v w x y z $ paste -d \":\" alpha.log seq.log a:1 b:2 c:3 d:4 e:5 f:6 g:7 h:8 i:9 j:10 k: l: m: n: o: p: q: r: s: t: u: v: w: x: y: z: \u539f\u6587\u4ef6\u90fd\u662f\u5217\u8f93\u51fa\uff0c\u6539\u6210\u884c\u8f93\u51fa\u3002 $ paste -d \"-\" -s alpha.log a-b-c-d-e-f-g-h-i-j-k-l-m-n-o-p-q-r-s-t-u-v-w-x-y-z $ paste -d \"-\" -s seq.log $ paste -d \":\" -s alpha.log seq.log a:b:c:d:e:f:g:h:i:j:k:l:m:n:o:p:q:r:s:t:u:v:w:x:y:z 1 :2:3:4:5:6:7:8:9:10 $ paste -d \":\" -s seq.log alpha.log 1 :2:3:4:5:6:7:8:9:10 a:b:c:d:e:f:g:h:i:j:k:l:m:n:o:p:q:r:s:t:u:v:w:x:y:z 2.11.\u6587\u672c\u7edf\u8ba1\u6570\u636e wc \u00b6 \u5e38\u7528\u9009\u9879\uff1a -l \uff1a\u53ea\u8ba1\u6570\u884c\u6570 -w \uff1a\u53ea\u8ba1\u6570\u5355\u8bcd\u603b\u6570 -c \uff1a\u53ea\u8ba1\u6570\u5b57\u8282\u603b\u6570 -m \uff1a\u53ea\u8ba1\u6570\u5b57\u7b26\u603b\u6570 -L \uff1a\u663e\u793a\u6587\u4ef6\u4e2d\u6700\u957f\u884c\u7684\u957f\u5ea6 $ cat text Tom, 20 , Shanghai Jack, 30 , Beijing Smith, 40 , Guangzhou $ wc text # \u884c\u6570 \u5355\u8bcd\u6570 \u5b57\u8282\u6570 3 9 57 text $ wc -l text 3 text $ wc -w text 9 text $ wc -c text 57 text $ wc -m text 57 text $ wc -L text 20 text \u5bf9\u6bd4\u4e24\u79cd\u4e0d\u540c\u5408\u5e76\u7684\u65b9\u6cd5\u3002 $ cat text1 text2 Tom, 20 , Shanghai Jack, 30 , Beijing Smith, 40 , Guangzhou Tom, 20 , Shanghai Jack, 30 , Beijing Leo, 40 , Guangzhou $ paste text1 text2 Tom, 20 , Shanghai Tom, 20 , Shanghai Jack, 30 , Beijing Jack, 30 , Beijing Smith, 40 , Guangzhou Leo, 40 , Guangzhou 2.12.\u6587\u672c\u6392\u5e8f sort \u00b6 \u547d\u4ee4 sort \u628a\u6574\u7406\u8fc7\u7684\u6587\u672c\u663e\u793a\u5728stdout\u4e0a\uff0c\u4e0d\u6539\u53d8\u539f\u6587\u4ef6\u3002 \u5e38\u7528\u9009\u9879\uff1a -r \uff1a\u6267\u884c\u53cd\u65b9\u5411\uff08\u4ece\u4e0a\u81f3\u4e0b\uff09\u6392\u5e8f -R \uff1a\u968f\u673a\u6392\u5e8f -n \uff1a\u6309\u6570\u5b57\u5927\u5c0f\u6392\u5e8f -h \uff1a\u4eba\u7c7b\u53ef\u8bfb\u6392\u5e8f\uff0c\u5982\uff1a2K\uff0c1G -f \uff1a\u6392\u5e8f\u65f6\u5c06\u5c0f\u5199\u5b57\u6bcd\u89c6\u4e3a\u5927\u5199\u5b57\u6bcd -u \uff1a\u6392\u5e8f\u65f6\u5408\u5e76\u91cd\u590d\u9879 -t c \uff1a\u4f7f\u7528c\u4f5c\u4e3a\u5b57\u6bb5\u5206\u9694\u7b26 -k # \uff1a\u6309\u7167\u4ee5c\u4e3a\u5206\u9694\u7b26\u7684\u7b2c#\u5217\u6765\u6392\u5e8f \u4e3e\u4f8b\uff1a\u4ee5 , \u4e3a\u5206\u9694\u7b26\uff0c\u8bfb\u53d6 text \u6587\u4ef6\u5185\u5bb9\u4e2d\u7b2c1\uff0c3\u5217\uff0c\u5bf9\u8f93\u51fa\u7ed3\u679c\u4ee5 , \u4e3a\u5206\u9694\u7b26\uff0c\u6309\u7b2c\u4e8c\u5217\u6392\u5e8f\uff08\u6b63\u5e8f\u548c\u53cd\u5e8f\uff09\u3002 $ cat text Tom, 20 , Shanghai Jack, 30 , Beijing Smith, 40 , Guangzhou $ cut -d \",\" -f 1 ,3 text | sort -t \",\" -k 1 Jack, Beijing Smith, Guangzhou Tom, Shanghai $ cut -d \",\" -f 1 ,3 text | sort -t \",\" -k 1 -r Tom, Shanghai Smith, Guangzhou Jack, Beijing \u628a\u6587\u4ef6text1\u548c\u6587\u4ef6text2\u5408\u5e76\u540e\u53bb\u91cd\u8f93\u51fa\u3002 $ cat text2 Tom, 20 , Shanghai Jack, 30 , Beijing Leo, 40 , Guangzhou $ cat text1 Tom, 20 , Shanghai Jack, 30 , Beijing Smith, 40 , Guangzhou $ cat text1 text2 Tom, 20 , Shanghai Jack, 30 , Beijing Smith, 40 , Guangzhou Tom, 20 , Shanghai Jack, 30 , Beijing Leo, 40 , Guangzhou \u5e76\u96c6\uff0c\u91cd\u590d\u884c\u53ea\u4fdd\u7559\u4e00\u884c\u3002\u524d\u97622\u4e2a\u547d\u4ee4\u662f\u540c\u6837\u542b\u4e49\uff08\u76f8\u540c\u7684\u6392\u5e8f\u5217\uff09\uff0c\u7b2c\u4e09\u4e2a\u547d\u4ee4\u4e2d\u5bf9\u4e0d\u540c\u5217\u8fdb\u884c\u4e86\u6392\u5e8f\uff0c\u5bfc\u81f4\u53bb\u91cd\u7ed3\u679c\u4e0d\u540c\u3002 $ cat text1 text2 | sort -u Jack, 30 , Beijing Leo, 40 , Guangzhou Smith, 40 , Guangzhou Tom, 20 , Shanghai $ cat text1 text2 | sort -t \",\" -k 1 -u Jack, 30 , Beijing Leo, 40 , Guangzhou Smith, 40 , Guangzhou Tom, 20 , Shanghai $ cat text1 text2 | sort -t \",\" -k 2 -u Tom, 20 , Shanghai Jack, 30 , Beijing Smith, 40 , Guangzhou 2.13.\u53bb\u91cd uniq \u00b6 \u547d\u4ee4 uniq \u4ece\u8f93\u5165\u4e2d\u5220\u9664\u524d\u540e\u76f8\u90bb\u91cd\u590d\u7684\u884c\u3002\u7ecf\u5e38\u4e0e sort \u547d\u4ee4\u7ed3\u5408\u4f7f\u7528\u3002 \u4e3b\u8981\u53c2\u6570\uff1a -c \uff1a\u663e\u793a\u6bcf\u884c\u91cd\u590d\u51fa\u73b0\u7684\u6b21\u6570 -d \uff1a\u4ec5\u663e\u793a\u91cd\u590d\u7684\u884c -u \uff1a\u4ec5\u663e\u793a\u4e0d\u91cd\u590d\u7684\u884c \u4e3e\u4f8b\uff0c\u6ce8\u610f\u53ea\u6709\u5bf9\u76f8\u90bb\u884c\u8fdb\u884c\u53bb\u91cd\u3002 $ cat text3 test 30 Hello 95 Hello 95 Linux 85 Linux 85 Hello 95 test 30 $ uniq text3 test 30 Hello 95 Linux 85 Hello 95 test 30 \u628a\u6587\u4ef6text1\u548c\u6587\u4ef6text2\u5408\u5e76\u540e\uff0c\u8fdb\u884c\u4ea4\u96c6\u548c\u5e76\u96c6\uff0c\u5e76\u53bb\u91cd\u3002 $ cat text1 Tom, 20 , Shanghai Jack, 30 , Beijing Smith, 40 , Guangzhou $ cat text2 Tom, 20 , Shanghai Jack, 30 , Beijing Leo, 40 , Guangzhou # \u5e76\u96c6\uff0c\u6309\u9996\u5217\u6392\u5e8f\u53bb\u91cd $ cat text1 text2 | sort | uniq Jack, 30 , Beijing Leo, 40 , Guangzhou Smith, 40 , Guangzhou Tom, 20 , Shanghai # \u4ea4\u96c6 $ cat text1 text2 | sort | uniq -d Jack, 30 , Beijing Tom, 20 , Shanghai # \u5dee\u96c6 $ cat text1 text2 | sort | uniq -u Leo, 40 , Guangzhou Smith, 40 , Guangzhou \u67e5\u770b\u5e76\u53d1\u8fde\u63a5\u6570\u6700\u591a\u7684\u8fdc\u7a0b\u4e3b\u673aIP\u3002 $ ss -nt State Recv-Q Send-Q Local Address:Port Peer Address:Port Process ESTAB 0 0 192 .168.10.210:22 192 .168.10.210:41650 ESTAB 0 0 192 .168.10.210:22 192 .168.10.201:65330 ESTAB 0 64 192 .168.10.210:22 192 .168.10.201:63289 ESTAB 0 0 192 .168.10.210:41650 192 .168.10.210:22 ESTAB 0 0 192 .168.10.210:47992 192 .168.10.210:22 ESTAB 0 0 192 .168.10.210:60268 192 .168.10.210:22 ESTAB 0 0 192 .168.10.210:22 192 .168.10.201:65327 ESTAB 0 0 192 .168.10.210:35758 192 .168.10.220:22 ESTAB 0 0 192 .168.10.210:22 192 .168.10.210:56818 ESTAB 0 0 192 .168.10.210:56818 192 .168.10.210:22 ESTAB 0 0 192 .168.10.210:48006 192 .168.10.210:22 ESTAB 0 0 192 .168.10.210:22 192 .168.10.210:60268 ESTAB 0 0 192 .168.10.210:22 192 .168.10.220:33896 ESTAB 0 0 192 .168.10.210:22 192 .168.10.201:65324 ESTAB 0 0 192 .168.10.210:22 192 .168.10.210:47992 ESTAB 0 0 192 .168.10.210:59554 192 .168.10.210:22 ESTAB 0 0 192 .168.10.210:22 192 .168.10.210:59554 ESTAB 0 0 192 .168.10.210:22 192 .168.10.210:48006 $ ss -nt | tr -s \" \" \":\" | cut -d \":\" -f 6 ,7 | sort | uniq -c | sort -nr | head -n 1 6 192 .168.10.210:22 2.14.\u6587\u672c\u6bd4\u8f83 \u00b6 2.14.1. diff \u00b6 \u547d\u4ee4 diff \u6bd4\u8f83\u4e24\u4e2a\u6587\u4ef6\u4e4b\u95f4\u7684\u533a\u522b\u3002 \u5e38\u7528\u9009\u9879\uff1a -u \uff1a\u4ee5\u7edf\u4e00\u7684\u65b9\u5f0f\u6765\u663e\u793a\u6587\u4ef6\u5185\u5bb9\u7684\u4e0d\u540c -y \uff1a\u4ee5\u5e76\u5217\u7684\u65b9\u5f0f\u663e\u793a\u6587\u4ef6\u7684\u5f02\u540c\u4e4b\u5904 -W \uff1a\u5728\u4f7f\u7528-y\u53c2\u6570\u65f6\uff0c\u6307\u5b9a\u680f\u5bbd -c \uff1a\u663e\u793a\u5168\u90e8\u5185\u6587\uff0c\u5e76\u6807\u51fa\u4e0d\u540c\u4e4b\u5904 -N \uff1a\u7f3a\u5931\u6587\u4ef6\u4ee5\u7a7a\u6587\u4ef6\u5904\u7406 \u4e3e\u4f8b\uff1a $ cat text5 # \u6587\u4ef6\u5c3e\u90e8\u6ca1\u6709\u7a7a\u884c 1001 1002 1003 $ cat text6 # \u6587\u4ef6\u5c3e\u90e8\u6ca1\u6709\u7a7a\u884c 1001 1002 1003a 1004 \u663e\u793a\u4e0d\u540c\u3002 3c3,4 \u4ee3\u8868\u4e24\u4e2a\u6587\u4ef6\u5728\u7b2c3\uff0c4\u884c\u6709\u4e0d\u540c\u3002 $ diff text5 text6 3c3,4 < 1003 --- > 1003a > 1004 \u4ee5\u7edf\u4e00\u683c\u5f0f\u8f93\u51fa\u6bd4\u8f83\u7ed3\u679c\u3002 \u524d2\u884c\u662f\u6587\u4ef6\u4fe1\u606f\u3002\u5176\u4e2d --- \u8868\u793a\u53d8\u52a8\u524d\u7684\u6587\u4ef6\uff0c +++ \u8868\u793a\u53d8\u52a8\u540e\u7684\u6587\u4ef6\u3002 \u53d8\u52a8\u7684\u4f4d\u7f6e\u7528\u4e24\u4e2a@\u4f5c\u4e3a\u8d77\u9996\u548c\u7ed3\u675f\uff0c @@ -1,3 +1,4 @@ \u3002 -1,3 \u4e2d\uff0c - \u8868\u793a\u7b2c\u4e00\u4e2a\u6587\u4ef6\uff0c\u5373 text5 \u3002\u7b2c\u4e00\u4e2a\u6587\u4ef6\u4ece\u7b2c1\u884c\u5f00\u59cb\u8fde\u7eed3\u884c\u3002 +1,4 \u4e2d\uff0c + \u8868\u793a\u7b2c\u4e8c\u4e2a\u6587\u4ef6\uff0c\u5373 text6 \u3002\u5373\uff0c\u7b2c\u4e8c\u4e2a\u6587\u4ef6\u4ece\u7b2c1\u884c\u5f00\u59cb\u8fde\u7eed4\u884c\u3002 $ diff -u text5 text6 --- text5 2022 -12-07 08 :07:05.927805722 +0800 +++ text6 2022 -12-07 08 :07:24.692234585 +0800 @@ -1,3 +1,4 @@ 1001 1002 -1003 +1003a +1004 \u4ee5\u4e0a\u4e0b\u6587\u65b9\u5f0f\u8f93\u51fa\u6bd4\u8f83\u7ed3\u679c\u3002\u6807\u6709 ! \u4ee3\u8868\u5dee\u5f02\u884c\u3002 $ diff -c text5 text6 *** text5 2022 -12-07 08 :24:08.867168414 +0800 --- text6 2022 -12-07 08 :24:13.939284243 +0800 *************** *** 1 ,3 **** 1001 1002 ! 1003 --- 1 ,4 ---- 1001 1002 ! 1003a ! 1004 \u5e76\u6392\u683c\u5f0f\u8f93\u51fa\u6bd4\u8f83\u7ed3\u679c\u3002 | \u8868\u793a\u524d\u540e2\u4e2a\u6587\u4ef6\u5185\u5bb9\u6709\u4e0d\u540c < \u8868\u793a\u540e\u9762\u6587\u4ef6\u6bd4\u524d\u9762\u6587\u4ef6\u5c11\u4e861\u884c\u5185\u5bb9 > \u8868\u793a\u540e\u9762\u6587\u4ef6\u6bd4\u524d\u9762\u6587\u4ef6\u591a\u4e861\u884c\u5185\u5bb9 $ diff -y -W 50 text5 text6 1001 1001 1002 1002 1003 | 1003a > 1004 \u6bd4\u8f83\u6587\u4ef6\u5939\u5185\u5bb9\u3002\u6ce8\u610f\uff0c\u53ea\u6bd4\u8f83\u5185\u5bb9\uff0c\u4e0d\u6bd4\u8f83\u65f6\u95f4\u6233\u3002 $ mkdir dir1 $ mkdir dir2 $ cd dir1 $ touch file1 $ touch file2 $ cp file1 file2 ../dir2/ $ echo \"hello\" > file3 $ cd ../dir2 $ touch file3 $ touch file4 $ diff dir1 dir2 1d0 < hello Only in dir2: file4 2.14.2. patch \u00b6 \u547d\u4ee4 patch \u590d\u5236\u5176\u4ed6\u6587\u4ef6\u4e2d\u7684\u5185\u5bb9\u3002\u547d\u4ee4\u683c\u5f0f\uff1a patch -p [ num ] < patchfile patch [ options ] originalfile patchfile \u5f53\u7279\u5b9a\u8f6f\u4ef6\u6709\u53ef\u7528\u7684\u5b89\u5168\u4fee\u590d\u7a0b\u5e8f\u65f6\uff0c\u6211\u4eec\u901a\u5e38\u4f1a\u4f7f\u7528 yum \u6216 apt-get \u6216 zypper \u7b49\u5305\u7ba1\u7406\u5de5\u5177\u8fdb\u884c\u4e8c\u8fdb\u5236\u5347\u7ea7\u3002 \u4f46\u5982\u679c\u6211\u4eec\u662f\u901a\u8fc7\u4ece\u6e90\u4ee3\u7801\u7f16\u8bd1\u5b89\u88c5\u8f6f\u4ef6\u7684\u60c5\u51b5\u4e0b\uff0c\u6211\u4eec\u9700\u8981\u4e0b\u8f7d\u5b89\u5168\u8865\u4e01\u5e76\u5c06\u5176\u5e94\u7528\u4e8e\u539f\u59cb\u6e90\u4ee3\u7801\u5e76\u91cd\u65b0\u7f16\u8bd1\u8f6f\u4ef6\u3002 \u8fd9\u5c31\u662f\u6211\u4eec\u4f7f\u7528 diff \u521b\u5efa\u8865\u4e01\u6587\u4ef6\uff08patch file\uff09\uff0c\u5e76\u4f7f\u7528 patch \u547d\u4ee4\u5e94\u7528\u5b83\u3002 \u8865\u4e01\u6587\u4ef6\u662f\u4e00\u4e2a\u6587\u672c\u6587\u4ef6\uff0c\u5176\u4e2d\u5305\u542b\u540c\u4e00\u6587\u4ef6\uff08\u6216\u540c\u4e00\u6e90\u4ee3\u7801\u6811\uff09\u7684\u4e24\u4e2a\u7248\u672c\u4e4b\u95f4\u7684\u5dee\u5f02\u3002 \u8865\u4e01\u6587\u4ef6\u662f\u4f7f\u7528 diff \u547d\u4ee4\u521b\u5efa\u7684\u3002 \u7ee7\u7eed\u4e0a\u4f8b\u3002 \u5c06\u6587\u4ef6 text5 \u7684\u5185\u5bb9\u540c\u6b65\u5230\u6587\u4ef6 text6 \uff0c\u7136\u540e\u64a4\u9500\u8865\u4e01\u3002\u6ce8\u610f\u533a\u5206\u6e90\u6587\u4ef6\u548c\u76ee\u6807\u6587\u4ef6\u3002 $ cat text5 1001 1002 1003 $ cat text6 1001 1002 1003a 1004 # \u751f\u6210\u8865\u4e01\u6587\u4ef6 $ diff -ruN text5 text6 > patchfile $ cat patchfile --- text5 2022 -12-07 08 :24:08.867168414 +0800 +++ text6 2022 -12-07 08 :24:13.939284243 +0800 @@ -1,3 +1,4 @@ 1001 1002 -1003 +1003a +1004 # \u4e0d\u6307\u660e\u76ee\u6807\u6587\u4ef6\uff0c\u5219\u9ed8\u8ba4\u7ed9diff\u547d\u4ee4\u4e2d\u7684\u6e90\u6587\u4ef6\u8fdb\u884c\u6253\u8865\u4e01 $ patch < patchfile patching file text5 $ cat text5 1001 1002 1003a 1004 $ cat text6 1001 1002 1003a 1004 # \u64a4\u9500\u8865\u4e01 patch -R < patchfile patching file text5 # cat text5 1001 1002 1003 # \u7ed9text6\u6587\u4ef6\u6253\u8865\u4e01\uff08\u7528text5\u7684\u6587\u4ef6\u5185\u5bb9\u8986\u76d6text6\u7684\u5185\u5bb9\uff09 $ patch text6 patchfile patching file text6 Reversed ( or previously applied ) patch detected! Assume -R? [ n ] y $ cat text6 1001 1002 1003 # \u64a4\u9500\u7ed9text6\u6587\u4ef6\u6253\u7684\u8865\u4e01\uff08\u6062\u590dtext6\u6587\u4ef6\u8865\u4e01\u524d\u7684\u5185\u5bb9\uff09 $ patch -R text6 patchfile patching file text6 Unreversed patch detected! Ignore -R? [ n ] y $ cat text6 1001 1002 1003a 1004 \u4f7f\u7528 -b \u53c2\u6570\uff0c\u5728patch\u524d\u5148\u5907\u4efd\u6e90\u6587\u4ef6\u3002 $ patch -b < patchfile patching file text5 $ cat text5 1001 1002 1003a 1004 $ cat text5.orig 1001 1002 1003 $ cat text6.orig 1001 1002 1003 $ patch -R < patchfile patching file text5 \u5728-b\u53c2\u6570\u4e2d\u52a0\u5165-V\u53c2\u6570\uff0c\u6307\u5b9a\u5907\u4efd\u6587\u4ef6\u540d\u7684\u683c\u5f0f\uff0c\u5982\u4e0b\uff0c\u4f1a\u5f97\u5230\u6587\u4ef6 text5.~1~ \u3002 $patch -b -V numbered < patchfile patching file text5 $ cat text5 1001 1002 1003a 1004 $ cat text5.~1~ 1001 1002 1003 \u8bd5\u8fd0\u884c\uff0c\u4e0d\u505a\u5b9e\u9645\u66f4\u6539\u3002 patch --dry-run < patchfile \u5bf9\u76ee\u5f55\u6253\u8865\u4e01\u3002 \u6267\u884c diff \u548c patch \u547d\u4ee4\u662f\u5728\u5f53\u524d\u7528\u6237 vagrant \u7684\u4e3b\u76ee\u5f55\u4e0b\uff0c\u7edd\u5bf9\u8def\u5f84\u662f /home/vagrant \u3002 diff \u547d\u4ee4\u4e2d\uff0c\u6e90\u76ee\u5f55\u662f /home/vagrant/dir1 \u3002\u76ee\u6807\u76ee\u5f55\u662f /home/vagrant/dir2 \u3002 -p3 \u662f\u544a\u8bc9 patch \u547d\u4ee4\u5ffd\u7565\u4e0a\u9762\u7edd\u5bf9\u8def\u5f84\u4e2d\u524d\u4e09\u4e2a\u659c\u6760 / \u3002 patch \u547d\u4ee4\u4e2d\u7528 diff \u7684\u76ee\u6807\u76ee\u5f55\u53bb\u8986\u76d6\u6e90\u76ee\u5f55\u3002\u4e92\u6362\u4f1a\u62a5\u9519\u3002 -R \uff1a\u64a4\u9500\u8865\u4e01\u3002 # file3\u548cfile4\u6709\u5185\u5bb9 $ tree ./dir1 ./dir1 \u251c\u2500\u2500 file1 \u251c\u2500\u2500 file2 \u251c\u2500\u2500 file3 \u2514\u2500\u2500 subdir1 \u2514\u2500\u2500 file4 \u90fd\u662f\u7a7a\u6587\u4ef6 $ tree ./dir2 ./dir2 \u251c\u2500\u2500 file1 \u251c\u2500\u2500 file2 \u251c\u2500\u2500 file3 \u2514\u2500\u2500 subdir1 \u2514\u2500\u2500 file4 $ diff -ruN /home/vagrant/dir1 /home/vagrant/dir2 > patchdir $ cat patchdir diff -ruN /home/vagrant/dir1/file3 /home/vagrant/dir2/file3 --- /home/vagrant/dir1/file3 2022 -12-07 08 :42:33.108418336 +0800 +++ /home/vagrant/dir2/file3 2022 -12-07 21 :25:48.156056360 +0800 @@ -1 +0,0 @@ -hello diff -ruN /home/vagrant/dir1/subdir1/file4 /home/vagrant/dir2/subdir1/file4 --- /home/vagrant/dir1/subdir1/file4 2022 -12-07 21 :15:09.689912160 +0800 +++ /home/vagrant/dir2/subdir1/file4 2022 -12-07 21 :26:55.405546177 +0800 @@ -1 +0,0 @@ -/home/vagrant/dir1/subdir1 # \u7528dir2\u7684\u5185\u5bb9\u8986\u76d6dir1\u7684\u5185\u5bb9 $ patch -p3 < patchdir patching file dir1/file3 patching file dir1/subdir1/file4 # \u73b0\u5728dir1\u76ee\u5f55\u4e0b\u7684\u5185\u5bb9\u5df2\u7ecf\u88abdir2\u76ee\u5f55\u8986\u76d6\u4e86\u3002file3\u548cfile4\u90fd\u662f\u7a7a\u6587\u4ef6 $ ll ./dir1 total 0 -rw-r--r--. 1 vagrant wheel 0 Dec 7 08 :34 file1 -rw-r--r--. 1 vagrant wheel 0 Dec 7 08 :35 file2 -rw-r--r--. 1 vagrant wheel 0 Dec 7 21 :40 file3 drwxr-xr-x. 1 vagrant wheel 10 Dec 7 21 :40 subdir1 $ ll ./dir1/subdir1 total 0 -rw-r--r--. 1 vagrant wheel 0 Dec 7 21 :40 file4 # \u64a4\u9500\u8865\u4e01\uff0cfile3\u548cfile4\u5df2\u7ecf\u6062\u590d\u4e3a\u539f\u6587\u4ef6 $ patch -R -p3 < patchdir patching file dir1/file3 patching file dir1/subdir1/file4 $ ll ./dir1 -rw-r--r--. 1 vagrant wheel 0 Dec 7 08 :34 file1 -rw-r--r--. 1 vagrant wheel 0 Dec 7 08 :35 file2 -rw-r--r--. 1 vagrant wheel 6 Dec 7 21 :45 file3 drwxr-xr-x. 1 vagrant wheel 10 Dec 7 21 :45 subdir1 $ ll ./dir1/subdir1 -rw-r--r--. 1 vagrant wheel 27 Dec 7 21 :45 file4 # \u7528dir1\u7684\u5185\u5bb9\u8986\u76d6dir2\u7684\u5185\u5bb9\uff0c\u7cfb\u7edf\u62d2\u7edd\u3002 patch dir2 -p3 < patchdir File dir2 is not a regular file -- refusing to patch 1 out of 1 hunk ignored -- saving rejects to file dir2.rej File dir2 is not a regular file -- refusing to patch 1 out of 1 hunk ignored -- saving rejects to file dir2.rej $ patch /home/vagrant/dir2 -p3 < patchdir File /home/vagrant/dir2 is not a regular file -- refusing to patch 1 out of 1 hunk ignored -- saving rejects to file /home/vagrant/dir2.rej File /home/vagrant/dir2 is not a regular file -- refusing to patch 1 out of 1 hunk ignored -- saving rejects to file /home/vagrant/dir2.rej 2.14.3. vimdiff \u00b6 \u547d\u4ee4 vimdiff \u76f8\u5f53\u4e8e vim -d \u3002 \u4e3e\u4f8b\uff1a vimdiff text1 text2 2.14.4. cmp \u00b6 \u547d\u4ee4 cmp \u67e5\u770b\u4e8c\u8fdb\u5236\u6587\u4ef6\u7684\u4e0d\u540c\u3002 $ cmp cp grep cp grep differ: byte 25 , line 1 $ cmp /usr/bin/ls /usr/bin/dir /usr/bin/ls /usr/bin/dir differ: byte 613 , line 1 # \u8df3\u8fc7\u524d735\u4e2a\u5b57\u8282\uff0c\u8f93\u51fa\u540e\u976230\u4e2a\u5b57\u8282\u5185\u5bb9 $ hexdump -s 735 -Cn 30 /usr/bin/ls 000002df 00 00 00 00 00 5d 00 00 00 50 00 00 00 68 00 00 | ..... ] ...P...h.. | 000002ef 00 6a 00 00 00 4f 00 00 00 00 00 00 00 1d | .j...O........ | 000002fd $ hexdump -s 735 -Cn 30 /usr/bin/dir 000002df 00 00 00 00 00 5d 00 00 00 50 00 00 00 68 00 00 | ..... ] ...P...h.. | 000002ef 00 6a 00 00 00 4f 00 00 00 00 00 00 00 1d | .j...O........ | 000002fd","title":"\u7b2c\u56db\u7ae0 \u6587\u672c\u7f16\u8f91"},{"location":"linux/SRE/04-TextTools/#_1","text":"","title":"\u7b2c\u56db\u7ae0 \u6587\u672c\u7f16\u8f91"},{"location":"linux/SRE/04-TextTools/#1","text":"","title":"1.\u6587\u672c\u7f16\u8f91\u5668"},{"location":"linux/SRE/04-TextTools/#11vim","text":"vim\u547d\u4ee4\u683c\u5f0f\uff1a +# file : \u6253\u5f00\u6587\u4ef6\u540e\uff0c\u8ba9\u5149\u6807\u5904\u4e8e\u7b2c#\u884c\u9996\uff0c+\u9ed8\u8ba4\u884c\u5c3e +/PATTERN file : \u6253\u5f00\u6587\u4ef6\u6709\uff0c\u8ba9\u5149\u6807\u5904\u4e8e\u7b2c\u4e00\u4e2a\u88abPATTERN\u5339\u914d\u5230\u7684\u884c\u9996 -b file : \u4e8c\u8fdb\u5236\u65b9\u5f0f\u6253\u5f00\u6587\u4ef6 -d file1 file2 ... : \u6bd4\u8f83\u591a\u4e2a\u6587\u4ef6\uff0c\u76f8\u5f53\u4e8e vimdiff -m file : \u53ea\u8bfb\u65b9\u5f0f\u6253\u5f00\u6587\u4ef6 -e file : \u8fdb\u5165ex\u6a21\u5f0f\uff0c\u76f8\u5f53\u4e8e ex file -y file : vim\u4e09\u79cd\u5e38\u89c1\u6a21\u5f0f\uff1a \u666e\u901a\u6a21\u5f0fNormal\u6216\u547d\u4ee4\u6a21\u5f0f \u63d2\u5165Insert\u6216\u7f16\u8f91\u6a21\u5f0f \u6269\u5c55\u547d\u4ee4\u6a21\u5f0fExtended Command \u4e09\u79cd\u6a21\u5f0f\u5207\u6362 \u547d\u4ee4\u6a21\u5f0f\u2192\u63d2\u5165\u6a21\u5f0f i\uff1ainsert\uff0c\u5728\u5149\u6807\u5904\u8f93\u5165 I\uff1a\u5728\u5149\u6807\u6240\u5728\u884c\u9996\u8f93\u5165 a\uff1aappend\uff0c\u5728\u5149\u6807\u5904\u540e\u9762\u8f93\u5165 A\uff1a\u5728\u5149\u6807\u6240\u5728\u884c\u5c3e\u8f93\u5165 o\uff1a\u5728\u5149\u6807\u6240\u5728\u884c\u7684\u4e0b\u65b9\u6253\u5f00\u4e00\u4e2a\u65b0\u884c O\uff1a\u5728\u5149\u6807\u6240\u5728\u884c\u7684\u4e0a\u65b9\u6253\u5f00\u4e00\u4e2a\u65b0\u884c \u63d2\u5165\u6a21\u5f0f\u2192 ESC \u2192 \u547d\u4ee4\u6a21\u5f0f \u547d\u4ee4\u6a21\u5f0f\u2192 : \u2192 \u6269\u5c55\u547d\u4ee4\u6a21\u5f0f \u6269\u5c55\u547d\u4ee4\u6a21\u5f0f\u2192 ESC, enter \u2192 \u547d\u4ee4\u6a21\u5f0f \u6269\u5c55\u547d\u4ee4\u6a21\u5f0f\u5e38\u7528\u547d\u4ee4\uff1a :wq : \u4fdd\u5b58\u6587\u4ef6\u5e76\u9000\u51fa :w : \u4fdd\u5b58\u6587\u4ef6 :w filename : \u5199\u5165\u6307\u5b9a\u6587\u4ef6\uff0c\u76f8\u5f53\u4e8e\u53e6\u5b58\u4e3a :q! : \u653e\u5f03\u4efb\u4f55\u4fee\u6539\u5e76\u9000\u51fa ZQ : \u65e0\u6761\u4ef6\u9000\u51fa :join : \u5408\u5e76\u591a\u884c J : \u5408\u5e76\u4e24\u884c \u8bbe\u7f6e\uff1a\uff08\u53ef\u4ee5\u5728 /etc/vimrc \u6587\u4ef6\u4e2d\u914d\u7f6e\uff09 :set textwidth : \u8bbe\u7f6e\u6587\u672c\u5bbd\u5ea6\uff08\u4ece\u5de6\u5411\u53f3\u8ba1\u6570\uff09 :set wrapmargin=# : \u8bbe\u7f6e\u884c\u8fb9\u8ddd\uff08\u4ece\u53f3\u5411\u5de6\u8ba1\u6570\uff09 :set endofline : \u8bbe\u7f6e\u6587\u4ef6\u7ed3\u675f\u7b26 :set noendofline : \u53d6\u6d88\u6587\u4ef6\u7ed3\u675f\u7b26 :set wrap : \u81ea\u52a8\u6362\u884c :set nowrap : \u53d6\u6d88\u81ea\u52a8\u6362\u884c :set number : \u663e\u793a\u884c\u53f7 :set nonumber : \u53d6\u6d88\u663e\u793a\u884c\u53f7 :set list : \u8fdb\u5165List Mode\uff0c\u663e\u793aTab ^I\uff0c\u6362\u884c\u7b26\uff0c\u548c$\u663e\u793a :set nolist : \u9000\u51faList Mode :set ignorecase : \u5ffd\u7565\u5b57\u7b26\u7684\u5927\u5c0f\u5199 :set noic : \u4e0d\u5ffd\u7565\u5b57\u7b26\u5927\u5c0f\u5199 :set autoindent : \u542f\u7528\u81ea\u52a8\u7f29\u8fdb :set noai : \u5173\u95ed\u81ea\u52a8\u7f29\u8fdb :set hlsearch : \u542f\u7528\u9ad8\u4eae\u641c\u7d22 :set nohlsearch : \u5173\u95ed\u9ad8\u4eae\u641c\u7d22 :set fileformat=dos : \u542f\u7528windows\u683c\u5f0f :set fileformat=unix : \u542f\u7528unix\u683c\u5f0f :set expandtab : \u542f\u7528\u7a7a\u683c\u4ee3\u66ffTAB\uff0c\u9ed8\u8ba48\u4e2a\u7a7a\u683c\u4ee3\u66ff\u4e00\u4e2aTAB :set noexpandtab : \u5173\u95ed\u7a7a\u683c\u4ee3\u66ffTAB :set tabstop=# : \u6307\u5b9a#\u4e2a\u7a7a\u683c\u4ee3\u66ff\u4e00\u4e2aTAB :set shiftwidth=# : \u8bbe\u7f6e#\u4e2a\u7f29\u8fdb\u5bbd\u5ea6 :set cursorline : \u8bbe\u7f6e\u5149\u6807\u6240\u5728\u884c\u7684\u8868\u793a\u7ebf :set cursorline : \u5173\u95ed\u5149\u6807\u6240\u5728\u884c\u7684\u8868\u793a\u7ebf :set key=PASSWORD : \u542f\u7528\u5bc6\u7801\u4fdd\u62a4 :set key= : \u5173\u95ed\u5bc6\u7801\u4fdd\u62a4 :help option-list : \u83b7\u53d6\u5e2e\u52a9 \u67e5\u627e /pattern : \u4ece\u5149\u6807\u5f00\u59cb\u5904\u5411\u6587\u4ef6\u5c3e\u641c\u7d22pattern ?pattern : \u4ece\u5149\u6807\u5f00\u59cb\u5904\u5411\u6587\u4ef6\u9996\u641c\u7d22pattern n : \u5728\u540c\u4e00\u65b9\u5411\u91cd\u590d\u4e0a\u4e00\u6b21\u641c\u7d22\u547d\u4ee4 N : \u5728\u53cd\u65b9\u5411\u4e0a\u91cd\u590d\u4e0a\u4e00\u6b21\u641c\u7d22\u547d\u4ee4 # : \u5411\u4e0a\u5b8c\u6574\u5339\u914d\u5149\u6807\u4e0b\u7684\u5355\u8bcd, \u76f8\u5f53\u4e8e\uff1fword * : \u5411\u4e0b\u5b8c\u6574\u5339\u914d\u5149\u6807\u4e0b\u7684\u5355\u8bcd, \u76f8\u5f53\u4e8e/word % : \u67e5\u627e\u5bf9\u5e94\u7684( [ {\u5339\u914d nfx : \u5728\u5f53\u524d\u884c\u67e5\u627e\u5149\u6807\u540e\u7b2cn\u4e2ax\uff08\u4e00\u822c\u76f4\u63a5fx\uff09 \u66ff\u6362 :%s/\\n//g : \u5220\u9664\u6362\u884c\u7b26 :s/p1/p2/g : \u5c06\u5f53\u524d\u884c\u4e2d\u6240\u6709p1\u5747\u7528p2\u66ff\u4ee3, \u65e0g\uff0c\u5219\u53ea\u66ff\u6362\u7b2c\u4e00\u4e2a :s/p1/p2/c : \u67e5\u627e\u66ff\u6362\u8981\u6c42\u786e\u8ba4 :n1,n2s/p1/p2/g : \u5c06\u7b2cn1\u81f3n2\u884c\u4e2d\u6240\u6709p1\u5747\u7528p2\u66ff\u4ee3 :%s/p1/p2/g : \u5168\u5c40\uff0c\u4f7f\u7528p2\u66ff\u6362p1 :%s/p1/p2/gc : \u66ff\u6362\u524d\u8be2\u95ee :n,$s/vivian/sky/ : \u66ff\u6362\u7b2cn\u884c\u5f00\u59cb\u5230\u6700\u540e\u4e00\u884c\u4e2d\u6bcf\u4e00\u884c\u7684\u7b2c\u4e00\u4e2avivian\u4e3asky\uff0cn\u4e3a\u6570\u5b57 :.,$s/vivian/sky/g : \u66ff\u6362\u5f53\u524d\u884c\u5f00\u59cb\u5230\u6700\u540e\u4e00\u884c\u4e2d\u6bcf\u4e00\u884c\u6240\u6709vivian\u4e3asky :s/vivian\\//sky\\// : \u66ff\u6362\u5f53\u524d\u884c\u7b2c\u4e00\u4e2avivian/\u4e3asky/\uff0c\u53ef\u4ee5\u4f7f\u7528\\\u4f5c\u4e3a\u8f6c\u4e49\u7b26 :1,$s/^/some string/ : \u5728\u6587\u4ef6\u7684\u7b2c\u4e00\u884c\u81f3\u6700\u540e\u4e00\u884c\u7684\u884c\u9996\u524d\u63d2\u5165some string :%s/$/some string/g : \u5728\u6574\u4e2a\u6587\u4ef6\u6bcf\u4e00\u884c\u7684\u884c\u5c3e\u6dfb\u52a0some string :%s/\\s\\+$// : \u53bb\u6389\u6240\u6709\u7684\u884c\u5c3e\u7a7a\u683c\uff0c\u201c\\s\u201d\u8868\u793a\u7a7a\u767d\u5b57\u7b26\uff08\u7a7a\u683c\u548c\u5236\u8868\u7b26\uff09\uff0c\u201c+\u201d\u5bf9\u524d\u9762\u7684\u5b57\u7b26\u5339\u914d\u4e00\u6b21\u6216\u591a\u6b21\uff08\u8d8a\u591a\u8d8a\u597d\uff09\uff0c\u201c \\(\u201d\u5339\u914d\u884c\u5c3e\uff08\u4f7f\u7528\u201c\\$\u201d\u8868\u793a\u5355\u7eaf\u7684\u201c\\) \u201d\u5b57\u7b26\uff09 :%s/\\s\u2217\\n\\+/\\r/ : \u53bb\u6389\u6240\u6709\u7684\u7a7a\u767d\u884c\uff0c\u201c \\(\u201d\u548c\u201c\\) \u201d\u5bf9\u8868\u8fbe\u5f0f\u8fdb\u884c\u5206\u7ec4\uff0c\u4f7f\u5176\u88ab\u89c6\u4f5c\u4e00\u4e2a\u4e0d\u53ef\u5206\u5272\u7684\u6574\u4f53 :%s!\\s*//.*!! : \u53bb\u6389\u6240\u6709\u7684\u201c//\u201d\u6ce8\u91ca :%s!\\s*/\\*\\_.\\{-}\\*/\\s*!!g : \u53bb\u6389\u6240\u6709\u7684\u201c/**/\u201d\u6ce8\u91ca :%s= *$== : \u5c06\u6240\u6709\u884c\u5c3e\u591a\u4f59\u7684\u7a7a\u683c\u5220\u9664 :g/^\\s*$/d : \u5c06\u6240\u6709\u4e0d\u5305\u542b\u5b57\u7b26(\u7a7a\u683c\u4e5f\u4e0d\u5305\u542b)\u7684\u7a7a\u884c\u5220\u9664 r : \u66ff\u6362\u5f53\u524d\u5b57\u7b26 R : \u66ff\u6362\u5f53\u524d\u5b57\u7b26\u53ca\u5176\u540e\u7684\u5b57\u7b26\uff0c\u76f4\u81f3\u6309ESC\u952e \u7f16\u8f91 h : \u5149\u6807\u5de6\u79fb\u4e00\u4e2a\u5b57\u7b26[\u56de\u9000\u952eBackspace] l : \u5149\u6807\u53f3\u79fb\u4e00\u4e2a\u5b57\u7b26[\u7a7a\u683c\u952eSpace] K : \u5149\u6807\u4e0a\u79fb\u4e00\u884c j : \u5149\u6807\u4e0b\u79fb\u4e00\u884c w : \u5149\u6807\u8df3\u5230\u4e0b\u4e2aword\u7684\u7b2c\u4e00\u4e2a\u5b57\u6bcd(\u5305\u62ec\u6807\u70b9\u7b26\u53f7) [\u5e38\u7528] W : \u79fb\u5230\u4e0b\u4e00\u4e2a\u5b57\u7684\u5f00\u5934\uff0c\u5ffd\u7565\u6807\u70b9\u7b26\u53f7 B : \u5149\u6807\u56de\u5230\u4e0a\u4e2aword\u7684\u7b2c\u4e00\u4e2a\u5b57\u6bcd B : \u79fb\u5230\u524d\u4e00\u4e2a\u5b57\u7684\u5f00\u5934\uff0c\u5ffd\u7565\u6807\u70b9\u7b26\u53f7 BACK E : \u5149\u6807\u8df3\u5230\u4e0b\u4e2aword\u7684\u6700\u540e\u4e00\u4e2a\u5b57\u6bcd E : \u79fb\u5230\u4e0b\u4e00\u4e2a\u5b57\u7684\u7ed3\u5c3e\uff0c\u5ffd\u7565\u6807\u70b9\u7b26\u53f7 END 0 : \u79fb\u5230\u5f53\u524d\u4e00\u884c\u7684\u5f00\u59cb[Home] $ : \u79fb\u5230\u5f53\u524d\u4e00\u884c\u7684\u6700\u540e[End] ^ : \u547d\u4ee4\u5c06\u5149\u6807\u79fb\u52a8\u5230\u5f53\u524d\u884c\u7684\u7b2c\u4e00\u4e2a\u975e\u7a7a\u767d\u5b57\u7b26\u4e0a g_ : \u5230\u672c\u884c\u6700\u540e\u4e00\u4e2a\u4e0d\u662fblank\u5b57\u7b26\u7684\u4f4d\u7f6e Enter : \u5149\u6807\u4e0b\u79fb\u4e00\u884c n+ : \u5149\u6807\u4e0b\u79fbn\u884c\u3010\u6309\u4e0a\u6863\u952e \u6570\u5b57shift +\u3011 n- : \u5149\u6807\u4e0a\u79fbn\u884c G : \u79fb\u5230\u6587\u4ef6\u7684\u6700\u540e\u4e00\u884c nG \u6216\u8005 :n : \u79fb\u5230\u6587\u4ef6\u7684\u7b2cn\u884c\ue5e5\ue5e5\ue5e5 gg : \u79fb\u52a8\u5230\u6587\u6863\u7684\u5f00\u59cb [[ : \u6587\u4ef6\u5f00\u59cb\u4f4d\u7f6e\u2014\u2014\u5f00\u59cb\u884c ]] : \u6587\u4ef6\u7ed3\u675f\u4f4d\u7f6e\u2014\u2014\u672b\u5c3e\u884c H : \u5149\u6807\u79fb\u81f3\u5c4f\u5e55\u9876\u884cHEAD\u3002\u5149\u6807\u5b9a\u4f4d\u5728\u663e\u793a\u5c4f\u7684\u7b2c\u4e00\u884c M : \u79fb\u5230\u5c4f\u5e55\u7684\u4e2d\u95f4\u884c\u5f00\u5934 Middle\u3002\u5149\u6807\u5b9a\u4f4d\u5728\u663e\u793a\u5c4f\u7684\u4e2d\u95f4 L : \u79fb\u5230\u5c4f\u5e55\u7684\u6700\u540e\u4e00\u884cLAST\u3002\u5149\u6807\u5b9a\u4f4d\u5728\u663e\u793a\u5c4f\u7684\u6700\u540e\u4e00\u884c ( : \u5149\u6807\u79fb\u81f3\u53e5\u9996 ) : \u5149\u6807\u79fb\u81f3\u53e5\u5c3e { : \u79fb\u5230\u6bb5\u843d\u7684\u5f00\u5934 } : \u79fb\u5230\u4e0b\u4e00\u4e2a\u6bb5\u843d\u7684\u5f00\u5934 % : \u5339\u914d\u62ec\u53f7\u79fb\u52a8\uff0c\u5305\u62ec (, {, [.\uff08\u9700\u8981\u628a\u5149\u6807\u5148\u79fb\u5230\u62ec\u53f7\u4e0a\uff09\u8df3\u8f6c\u5230\u4e0e\u4e4b\u5339\u914d\u7684\u62ec\u53f7\u5904 * \u548c # : \u5339\u914d\u5149\u6807\u5f53\u524d\u6240\u5728\u7684\u5355\u8bcd\uff0c\u79fb\u52a8\u5149\u6807\u5230\u4e0b\u4e00\u4e2a\uff08\u6216\u4e0a\u4e00\u4e2a\uff09\u5339\u914d\u5355\u8bcd\uff08*\u662f\u4e0b\u4e00\u4e2a\uff0c#\u662f\u4e0a\u4e00\u4e2a\uff09 zf : \u6298\u53e0\uff08\u9700\u52a0\u65b9\u5411\u952e\uff09 zo : \u5c55\u5f00\uff08\u7a7a\u683c\u4e5f\u53ef\u4ee5\u5c55\u5f00\uff09 CTRL+u : \u5411\u6587\u4ef6\u9996\u7ffb\u534a\u5c4fup CTRL+d : \u5411\u6587\u4ef6\u5c3e\u7ffb\u534a\u5c4fdown CTRL+f : \u5411\u6587\u4ef6\u5c3e\u7ffb\u4e00\u5c4f forward (fact\u6574\u5c4f\u53bb\u4e24\u884c) CTRL+b : \u5411\u6587\u4ef6\u9996\u7ffb\u4e00\u5c4fback (fact\u6574\u5c4f\u53bb\u4e24\u884c) CTRL-] : \u8df3\u8f6c\u5230\u5f53\u524d\u5149\u6807\u6240\u5728\u5355\u8bcd\u5bf9\u5e94\u7684\u4e3b\u9898 CTRL-O : \u56de\u5230\u524d\u4e00\u4e2a\u4f4d\u7f6e SHIFT+V : \u9009\u62e9\u6574\u884c zz : \u547d\u4ee4\u4f1a\u628a\u5f53\u524d\u884c\u7f6e\u4e3a\u5c4f\u5e55\u6b63\u4e2d\u592e(z\u5b57\u53d6\u5176\u8c61\u5f62\u610f\u4e49\u6a21\u62df\u4e00\u5f20\u7eb8\u7684\u6298\u53e0\u53ca\u53d8\u5f62\u4f4d\u7f6e\u91cd\u7f6e) zt : \u547d\u4ee4\u4f1a\u628a\u5f53\u524d\u884c\u7f6e\u4e8e\u5c4f\u5e55\u9876\u7aef(top) zb : \u547d\u4ee4\u4f1a\u628a\u5f53\u524d\u884c\u7f6e\u4e8e\u5c4f\u5e55\u5e95\u7aef(bottom) 50% : \u5149\u6807\u5b9a\u4f4d\u5728\u6587\u4ef6\u7684\u4e2d\u95f4 ` : \u8df3\u8f6c\u5230\u6700\u8fd1\u5149\u6807\u5b9a\u4f4d\u7684\u4f4d\u7f6e\uff08\u53ea\u80fd\u8bb0\u5fc6\u6700\u8fd1\u4e24\u4e2a\u4f4d\u7f6e\uff09 \u53cd\u5f15\u53f7 I : \u5728\u5149\u6807\u524d\u5f00\u59cb\u63d2\u5165\u5b57\u7b26 insert I : \u5728\u5f53\u524d\u884c\u9996\u5f00\u59cb\u63d2\u5165\u5b57\u7b26 A : \u5728\u5149\u6807\u4f4d\u7f6e\u540e\u5f00\u59cb\u52a0\u5b57 append A : \u5728\u5149\u6807\u6240\u5728\u884c\u7684\u6700\u540e\u9762\u5f00\u59cb\u52a0\u5b57 O : \u5728\u5149\u6807\u4e0b\u52a0\u4e00\u7a7a\u767d\u884c\u5e76\u5f00\u59cb\u52a0\u5b57 open O : \u5728\u5149\u6807\u4e0a\u52a0\u4e00\u7a7a\u767d\u884c\u5e76\u5f00\u59cb\u52a0\u5b57 R : \u66ff\u6362\u5f53\u524d\u5b57\u7b26 R : \u66ff\u6362\u5f53\u524d\u5b57\u7b26\u53ca\u5176\u540e\u7684\u5b57\u7b26\u3010\u5f53\u524d\u53ca\u5176\u540e\u5b57\u7b26\u88ab\u8986\u76d6\u3011 S : \u9ed8\u8ba4\u5220\u9664\u5149\u6807\u6240\u5728\u5b57\u7b26\uff0c\u8f93\u5165\u5185\u5bb9\u63d2\u5165\u4e4b= xi S : \u9ed8\u8ba4\u5220\u9664\u5f53\u524d\u884c\u5185\u5bb9\uff0c\u8f93\u5165\u5185\u5bb9\u4f5c\u4e3a\u5f53\u524d\u884c\u65b0\u5185\u5bb9= dd+o nx : \u5220\u9664\u7531\u5149\u6807\u4f4d\u7f6e\u8d77\u59cb\u540e\u7684n\u4e2a\u5b57\u7b26\uff08\u542b\u5149\u6807\u4f4d\u7f6e\uff09x =dl(\u5220\u9664\u5f53\u524d\u5149\u6807\u4e0b\u7684\u5b57\u7b26) nX : \u5220\u9664\u7531\u5149\u6807\u4f4d\u7f6e\u8d77\u59cb\u524d\u7684n\u4e2a\u5b57\u7b26\uff08\u542b\u5149\u6807\u4f4d\u7f6e\uff09X =dh(\u5220\u9664\u5f53\u524d\u5149\u6807\u5de6\u8fb9\u7684\u5b57\u7b26) d0 : \u5220\u81f3\u884c\u9996 d$ : \u5220\u81f3\u884c\u5c3e dfa : \u8868\u793a\u5220\u9664\u4ece\u5f53\u524d\u5149\u6807\u5230\u5149\u6807\u540e\u9762\u7684\u7b2c\u4e00\u4e2aa\u5b57\u7b26\u4e4b\u95f4\u7684\u5185\u5bb9 D : \u4ee3\u8868d$(\u5220\u9664\u5230\u884c\u5c3e\u7684\u5185\u5bb9) C : \u4ee3\u8868c$(\u4fee\u6539\u5230\u884c\u5c3e\u7684\u5185\u5bb9) ndw : \u5220\u9664\u5149\u6807\u5904\u5f00\u59cb\u53ca\u5176\u540e\u7684n-1\u4e2a\u5b57 ndb : \u5220\u9664\u5149\u6807\u5904\u5f00\u59cb\u53ca\u5176\u524d\u7684n-1\u4e2a\u5b57 diw : \u5220\u9664\u5f53\u524d\u5149\u6807\u6240\u5728\u7684word(\u4e0d\u5305\u62ec\u7a7a\u767d\u5b57\u7b26)\uff0c\u610f\u4e3aDelete Inner Word \u4e24\u4e2a\u7b26\u53f7\u4e4b\u95f4\u7684\u5355\u8bcd daw : \u5220\u9664\u5f53\u524d\u5149\u6807\u6240\u5728\u7684word(\u5305\u62ec\u7a7a\u767d\u5b57\u7b26)\uff0c\u610f\u4e3aDelete A Word ndd : \u5220\u9664\u5f53\u524d\u884c\u53ca\u5176\u540en-1\u884c :n1,n2 d : \u5c06 n1\u884c\u5230n2\u884c\u4e4b\u95f4\u7684\u5185\u5bb9\u5220\u9664 dG : \u5220\u9664\u5f53\u524d\u884c\u81f3\u6587\u4ef6\u5c3e\u7684\u5185\u5bb9 Dgg : \u5220\u9664\u5f53\u524d\u884c\u81f3\u6587\u4ef6\u5934\u7684\u5185\u5bb9 d+enter : \u5220\u96642\u884c\u3010\u5305\u62ec\u5149\u6807\u4e00\u884c\u3011 cw : \u5220\u9664\u5f53\u524d\u5b57\uff0c\u5e76\u8fdb\u5165\u8f93\u5165\u6a21\u5f0f\u3010\u5f88\u597d\u7528\uff0c\u5feb\u901f\u66f4\u6539\u4e00\u4e2a\u5355\u8bcd\u3011\u76f8\u5f53\u4e8edw+i ncw : \u5220\u9664\u5f53\u524d\u5b57\u53ca\u5176\u540e\u7684n-1\u4e2a\u5b57\uff0c\u5e76\u8fdb\u5165\u8f93\u5165\u6a21\u5f0f\\\u4fee\u6539\u6307\u5b9a\u6570\u76ee\u7684\u5b57 cc : \u5220\u9664\u5f53\u524d\u884c\uff0c\u5e76\u8fdb\u5165\u8f93\u5165\u6a21\u5f0f ncc : \u5220\u9664\u5f53\u524d\u884c\u53ca\u5176\u540e\u7684n-1\u884c\uff0c\u5e76\u8fdb\u5165\u8f93\u5165\u6a21\u5f0f guw : \u5149\u6807\u4e0b\u7684\u5355\u8bcd\u53d8\u4e3a\u5c0f\u5199 gUw : \u5149\u6807\u4e0b\u7684\u5355\u8bcd\u53d8\u4e3a\u5927\u5199 xp : \u5de6\u53f3\u4ea4\u6362\u5149\u6807\u5904\u4e24\u5b57\u7b26\u7684\u4f4d\u7f6e ga : \u663e\u793a\u5149\u6807\u4e0b\u7684\u5b57\u7b26\u5728\u5f53\u524d\u4f7f\u7528\u7684encoding\u4e0b\u7684\u5185\u7801 nyl : \u590d\u5236n\u4e2a\u5b57\u7b26(\u4e5f\u53efnyh) yw : \u590d\u5236\u4e00\u4e2a\u5355\u8bcd y0 : \u8868\u793a\u62f7\u8d1d\u4ece\u5f53\u524d\u5149\u6807\u5230\u5149\u6807\u6240\u5728\u884c\u9996\u7684\u5185\u5bb9 y$ : \u590d\u5236\u4ece\u5f53\u524d\u4f4d\u7f6e\u5230\u884c\u5c3e yfa : \u8868\u793a\u62f7\u8d1d\u4ece\u5f53\u524d\u5149\u6807\u5230\u5149\u6807\u540e\u9762\u7684\u7b2c\u4e00\u4e2aa\u5b57\u7b26\u4e4b\u95f4\u7684\u5185\u5bb9 yG : \u590d\u5236\u4ece\u6240\u5728\u884c\u5230\u6700\u540e\u4e00\u884c nyy : \u5c06\u5149\u6807\u6240\u5728\u4f4d\u7f6e\u5f00\u59cb\u7684n\u884c\u6570\u636e\u590d\u5236\u6682\u5b58, \u590d\u5236\u4e00\u6574\u884c CTRL+v \u65b9\u5411y : \u5217\u9009\u62e9\u6a21\u5f0f\uff0c\u590d\u5236\u9009\u62e9\u7684\u5f88\u591a\u884c\uff1a\u5148\u4f7f\u7528V\u8fdb\u5165visual\u6a21\u5f0f\uff0c\u7136\u540ej\u5411\u4e0b\u79fb\u52a8\u5230\u4f60\u60f3\u590d\u5236\u7684\u884c\u4e3a\u6b62\uff0c\u7136\u540ey p : \u590d\u5236\u6682\u5b58\u6570\u636e\u5728\u5149\u6807\u7684\u4e0b\u4e00\u884c P : \u590d\u5236\u6682\u5b58\u6570\u636e\u5728\u5149\u6807\u7684\u4e0a\u4e00\u884c :n1,n2 co n3 : \u5c06n1\u884c\u5230n2\u884c\u4e4b\u95f4\u7684\u5185\u5bb9\u62f7\u8d1d\u5230\u7b2cn3+1\u884c\u3010n3\u884c\u7684\u4e0b\u4e00\u884c\u3011 :n1,n2 m n3 : \u5c06n1\u884c\u5230n2\u884c\u4e4b\u95f4\u7684\u5185\u5bb9\u79fb\u81f3\u5230\u7b2cn3\u884c\u4e0b J : \u628a\u4e0b\u4e00\u884c\u7684\u6570\u636e\u8fde\u63a5\u5230\u672c\u884c\u4e4b\u540e, \u591a\u4e00\u7a7a\u683c ~ : \u6539\u53d8\u5f53\u524d\u5149\u6807\u4e0b\u5b57\u7b26\u7684\u5927\u5c0f\u5199 \u5176\u4ed6 . : \u91cd\u590d\u524d\u4e00\u6307\u4ee4 u : \u53d6\u6d88\u524d\u4e00\u6307\u4ee4undo, :u\u4e5f\u884c\uff0c\u4e00\u822c\u4e0d\u7528\uff0c\u64cd\u4f5c\u592a\u591a Ctrl + r : \u6062\u590d\u3010\u53ea\u5bf9u\u6709\u6548\u3011redo Ctrl + l : \u5237\u65b0\u5c4f\u5e55\u663e\u793a Ctrl+v \u7136\u540e ctrl+A\u662f^A Ctrl+I\u662f\\t : \u8f93\u5165\u7279\u6b8a\u5b57\u7b26 Ctrl+v\u7136\u540e\u7528j\u3001k\u3001l\u3001h\u6216\u65b9\u5411\u952e\u4e0a\u4e0b\u9009\u4e2d\u591a\u5217\uff0c\u4e4b\u540e I I a A r x\u7b49\uff0c\u6700\u540e\u6309esc\uff0c\u751f\u6548 : Vim\u5217\u64cd\u4f5c","title":"1.1.vim\u5de5\u5177"},{"location":"linux/SRE/04-TextTools/#2","text":"","title":"2.\u6587\u672c\u5904\u7406\u5de5\u5177"},{"location":"linux/SRE/04-TextTools/#21cat","text":"\u547d\u4ee4 cat \u4e3b\u8981\u53c2\u6570\u8bf4\u660e\uff1a -E \uff1a\u663e\u793a\u884c\u7ed3\u675f\u7b26 $ -A \uff1a\u663e\u793a\u6240\u6709\u63a7\u5236\u7b26 -n \uff1a\u5bf9\u663e\u793a\u51fa\u7684\u6bcf\u4e00\u884c\u8fdb\u884c\u7f16\u53f7 -b \uff1a\u975e\u7a7a\u884c\u7f16\u53f7 -s \uff1a\u538b\u7f29\u8fde\u7eed\u7684\u7a7a\u884c\u6210\u4e00\u884c \u4e3e\u4f8b\uff1a cat -nA user-list.txt 1 user0$ 2 user1$ 3 user2$ 4 user3$ 5 user4$ 6 user5$ 7 user6$ 8 user7$ 9 user8$ 10 user9$","title":"2.1.\u663e\u793a\u6587\u672c\u5185\u5bb9cat"},{"location":"linux/SRE/04-TextTools/#22nl","text":"\u76f8\u5f53\u4e8e\u547d\u4ee4 cat -b \u3002 \u547d\u4ee4 nl \u4e3b\u8981\u53c2\u6570\u8bf4\u660e\uff1a -b \uff1a\u6307\u5b9a\u884c\u53f7\u6307\u5b9a\u7684\u65b9\u5f0f\uff0c\u4e3b\u8981\u6709\u4e24\u79cd\uff1a -b a \uff1a\u8868\u793a\u4e0d\u8bba\u662f\u5426\u4e3a\u7a7a\u884c\uff0c\u4e5f\u540c\u6837\u5217\u51fa\u884c\u53f7\uff08\u7c7b\u4f3c cat -n\uff09\uff1b -b t \uff1a\u5982\u679c\u6709\u7a7a\u884c\uff0c\u7a7a\u7684\u90a3\u4e00\u884c\u4e0d\u8981\u5217\u51fa\u884c\u53f7\uff08\u9ed8\u8ba4\u503c\uff09\uff1b -n \uff1a\u5217\u51fa\u884c\u53f7\u8868\u793a\u7684\u65b9\u6cd5\uff0c\u4e3b\u8981\u6709\u4e09\u79cd\uff1a -n ln \uff1a\u884c\u53f7\u5728\u5c4f\u5e55\u7684\u6700\u5de6\u65b9\u663e\u793a\uff1b\u6ca1\u6709\u524d\u5bfc0\uff1b -n rn \uff1a\u884c\u53f7\u5728\u81ea\u5df1\u680f\u4f4d\u7684\u6700\u53f3\u65b9\u663e\u793a\uff0c\u6ca1\u6709\u524d\u5bfc0\uff1b -n rz \uff1a\u884c\u53f7\u5728\u81ea\u5df1\u680f\u4f4d\u7684\u6700\u53f3\u65b9\u663e\u793a\uff0c\u6709\u524d\u5bfc0\uff1b -w \uff1a\u884c\u53f7\u680f\u4f4d\u7684\u5360\u7528\u7684\u4f4d\u6570\u3002 -p \uff1a\u5728\u903b\u8f91\u5b9a\u754c\u7b26\u5904\u4e0d\u91cd\u65b0\u5f00\u59cb\u8ba1 \u4e3e\u4f8b\uff1a $ nl -b a -n rz user-list.txt 000001 user0 000002 user1 000003 user2 000004 user3 000005 user4 000006 user5 000007 user6 000008 user7 000009 user8 000010 user9","title":"2.2.\u663e\u793a\u6587\u672c\u884c\u53f7nl"},{"location":"linux/SRE/04-TextTools/#23tac","text":"\u547d\u4ee4 tac \u9006\u5411\u663e\u793a\u6587\u672c\u5185\u5bb9\u3002 \u4e3e\u4f8b\uff1a $ tac user-list.txt user9 user8 user7 user6 user5 user4 user3 user2 user1 user0 \u4e3e\u4f8b\uff1a $ seq 10 | tac 10 9 8 7 6 5 4 3 2 1","title":"2.3.\u9006\u5411\u663e\u793a\u6587\u672c\u5185\u5bb9tac"},{"location":"linux/SRE/04-TextTools/#24rev","text":"\u547d\u4ee4 rev \u9006\u5411\u663e\u793a\u540c\u4e00\u884c\u7684\u5185\u5bb9\u3002 \u4e3e\u4f8b\uff1a $ rev user-list.txt 0resu 1resu 2resu 3resu 4resu 5resu 6resu 7resu 8resu 9resu \u4e3e\u4f8b\uff1a $ echo { 1 ..10 } | rev 01 9 8 7 6 5 4 3 2 1","title":"2.4.\u9006\u5411\u663e\u793a\u540c\u884c\u5185\u5bb9rev"},{"location":"linux/SRE/04-TextTools/#25hexdump","text":"\u547d\u4ee4 hexdump \u547d\u4ee4\u4e00\u822c\u7528\u6765\u67e5\u770b\u201c\u4e8c\u8fdb\u5236\u201d\u6587\u4ef6\u7684\u5341\u516d\u8fdb\u5236\u7f16\u7801 \u4e3e\u4f8b\uff1a $ hexdump -C -n 32 cp 00000000 7f 45 4c 46 02 01 01 00 00 00 00 00 00 00 00 00 | .ELF............ | 00000010 03 00 3e 00 01 00 00 00 e0 48 00 00 00 00 00 00 | ..>......H...... | 00000020","title":"2.5.\u663e\u793a\u975e\u6587\u672c\u6587\u4ef6\u5185\u5bb9hexdump"},{"location":"linux/SRE/04-TextTools/#26","text":"\u547d\u4ee4 more \u548c less \u53ef\u4ee5\u5b9e\u73b0\u5206\u9875\u67e5\u770b\u6587\u4ef6\u5185\u5bb9\u3002 \u547d\u4ee4 less \u914d\u5408\u7ba1\u9053\u7b26\u4f7f\u7528\u3002 tree -d /etc | less","title":"2.6.\u5206\u9875\u67e5\u770b\u6587\u4ef6\u5185\u5bb9"},{"location":"linux/SRE/04-TextTools/#27head","text":"\u547d\u4ee4 head \u663e\u793a\u6587\u4ef6\u5934\u90e8\u5185\u5bb9\u3002 head -c 20 cp : \u663e\u793a\u6587\u4ef6\u524d20\u5b57\u8282\u5185\u5bb9 head -n 20 zdiff : \u663e\u793a\u6587\u4ef6\u524d20\u884c\u5185\u5bb9 head -20 zdiff : \u663e\u793a\u6587\u4ef6\u524d20\u884c\u5185\u5bb9 $ echo \"\u6211\u662f\u8c01\" | head -c3 \u6211 $ echo \"\u6211\u662f\u8c01\" | head -c6 \u6211\u662f cat /dev/urandom | tr -dc '[:alnum]' | head -c 10 | tee passwd.txt $ cat user-list.txt user0 user1 user2 user3 user4 user5 user6 user7 user8 user9 $ head -n -3 user-list.txt user0 user1 user2 user3 user4 user5 user6","title":"2.7.\u663e\u793a\u6587\u4ef6\u5934\u90e8\u5185\u5bb9head"},{"location":"linux/SRE/04-TextTools/#28tail","text":"\u547d\u4ee4 tail \u663e\u793a\u6587\u4ef6\u5934\u90e8\u5185\u5bb9\u3002 tail -c 200 cp : \u663e\u793a\u6587\u4ef6\u5c3e\u90e8200\u4e2a\u5b57\u8282\u7684\u5185\u5bb9 tail -n 3 user-list.txt : \u663e\u793a\u6587\u4ef6\u6700\u540e3\u884c tail -n -3 user-list.txt : \u663e\u793a\u4ece-3\u884c\u5230\u6587\u4ef6\u7ed3\u675f\uff08\u5373\u6700\u540e\u4e09\u884c\uff09 tail -3 user-list.txt : \u663e\u793a\u6587\u4ef6\u6700\u540e3\u884c tail -f /var/log/messages : \u8ddf\u8e2a\u663e\u793a\u6587\u4ef6redo.log\u6587\u4ef6\u5185\u5bb9\uff0c\u5f53\u6587\u4ef6\u5220\u9664\uff0c\u518d\u5efa\u540c\u540d\u6587\u4ef6\uff0c\u65e0\u6cd5\u7ee7\u7eed\u8ffd\u8e2a tail -F /var/log/messages : \u8ddf\u8e2a\u663e\u793a\u6587\u4ef6redo.log\u6587\u4ef6\u5185\u5bb9\uff0c\u5f53\u6587\u4ef6\u5220\u9664\uff0c\u518d\u5efa\u540c\u540d\u6587\u4ef6\uff0c\u7ee7\u7eed\u8ffd\u8e2a","title":"2.8.\u663e\u793a\u6587\u4ef6\u5c3e\u90e8\u5185\u5bb9tail"},{"location":"linux/SRE/04-TextTools/#29cut","text":"\u547d\u4ee4 cut \u53ef\u4ee5\u63d0\u53d6\u6587\u672c\u6587\u4ef6\u6216\u8005stdin\u6570\u636e\u7684\u6307\u5b9a\u5217\u5185\u5bb9\u3002 \u9009\u9879\uff1a -f : \u901a\u8fc7\u6307\u5b9a\u54ea\u4e00\u4e2a\u5b57\u6bb5\u8fdb\u884c\u63d0\u53d6\u3002cut\u547d\u4ee4\u4f7f\u7528\u201cTAB\u201d\u4f5c\u4e3a\u9ed8\u8ba4\u7684\u5b57\u6bb5\u5206\u9694\u7b26 -d : \u201cTAB\u201d\u662f\u9ed8\u8ba4\u7684\u5206\u9694\u7b26\uff0c\u4f7f\u7528\u6b64\u9009\u9879\u53ef\u4ee5\u66f4\u6539\u4e3a\u5176\u4ed6\u7684\u5206\u9694\u7b26 --complement : \u6b64\u9009\u9879\u7528\u4e8e\u6392\u9664\u6240\u6307\u5b9a\u7684\u5b57\u6bb5 --output-delimiter=STRING : \u6307\u5b9a\u8f93\u51fa\u5185\u5bb9\u7684\u5206\u9694\u7b26 -c : \u6309\u5b57\u7b26\u5207\u5272 \u53d6/etc/passwd\u6587\u4ef6\u7b2c1\u5217\u5185\u5bb9\uff0c\u4ee5 : \u4e3a\u5206\u9694\u7b26\uff08\u53ea\u53d6\u524d\u4e09\u884c\uff09 $ cut -d ':' -f 1 /etc/passwd | head -3 root messagebus systemd-network \u53d6/etc/passwd\u6587\u4ef6\u7b2c1\u548c6\u5217\u5185\u5bb9\uff0c\u4ee5 : \u4e3a\u5206\u9694\u7b26\uff08\u53ea\u53d6\u524d\u4e09\u884c\uff09 cut -d ':' -f 1 ,6 /etc/passwd | head -3 root:/root messagebus:/run/dbus systemd-network:/ \u53d6/etc/passwd\u6587\u4ef6\u7b2c1\u52303\u5217\u4ee5\u53ca\u7b2c6\u5217\u5185\u5bb9\uff0c\u4ee5 : \u4e3a\u5206\u9694\u7b26\uff08\u53ea\u53d6\u524d\u4e09\u884c\uff09 $ cut -d ':' -f 1 -3,6 /etc/passwd | head -3 root:x:0:/root messagebus:x:499:/run/dbus systemd-network:x:497:/ \u4e0b\u9762\u4f7f\u7528 --output-delimiter \u9009\u9879\uff0c\u628a\u8f93\u51fa\u7ed3\u679c\u4e2d\u7684\u5206\u9694\u7b26 : \u5168\u90e8\u66ff\u6362\u6210 --- \u3002 $ cat /etc/passwd | sort | head -3 admin3:x:1020:100::/home/admin3:/bin/bash at:x:25:25:Batch jobs daemon:/var/spool/atjobs:/usr/sbin/nologin bin:x:1:1:bin:/bin:/usr/sbin/nologin $ cut -d \":\" -f 1 ,7 /etc/passwd | sort | head -3 admin3:/bin/bash at:/usr/sbin/nologin bin:/usr/sbin/nologin $ cut -d \":\" -f 1 ,7 --output-delimiter = \"---\" /etc/passwd | sort | head -3 admin3---/bin/bash at---/usr/sbin/nologin bin---/usr/sbin/nologin --output-delimiter \u9009\u9879\u4e5f\u53ef\u4ee5\u5229\u7528\u6765\u8fdb\u884c\u8ba1\u7b97\u3002 $ echo { 1 ..10 } | cut -d \" \" -f 1 -10 --output-delimiter = \"+\" | bc 55 \u4ece ifconfig \u547d\u4ee4\u4e2d\u622a\u53d6\u5f53\u524d\u4e3b\u673a\u7684ip\u5730\u5740\u3002\uff08openSUSE\u9700\u8981\u5b89\u88c5\u5305 net-tools-deprecated \uff09 $ ifconfig | head -2 | tail -1 inet 192 .168.10.210 netmask 255 .255.255.0 broadcast 192 .168.10.255 $ ifconfig | head -2 | tail -1 | cut -d \" \" -f 10 192 .168.10.210 \u6216\u8005 $ ip addr list | grep eth0 | tail -1 | cut -d \" \" -f 6 192 .168.10.210/24 \u57fa\u4e8e\u4e0a\u9762\u7ed3\u679c\uff0c\u53ef\u4ee5\u5c1d\u8bd5\u901a\u8fc7 --complement \u53c2\u6570\uff0c\u4ee5 / \u4e3a\u5206\u9694\u7b26\uff0c\u6392\u9664\u7b2c\u4e8c\u5217 24 \uff0c\u53ea\u8f93\u51fa\u7b2c\u4e00\u5217IP\u5730\u5740\u3002 ip addr list | grep eth0 | tail -1 | cut -d \" \" -f 6 | cut -d \"/\" --complement -f 2 192 .168.10.210 \u663e\u793a df \u547d\u4ee4\u8f93\u51fa\u4e2d\u7684\u5206\u533a\u4f7f\u7528\u7387\u3002 $ df | tr -s ' ' | cut -d ' ' -f 5 | tr -d % Use 0 0 2 0 8 8 8 8 8 8 8 8 8 8 8 0 \u65b9\u6cd52\uff1a\u5148\u628a\u7a7a\u683c\u5168\u90e8\u66ff\u6362\u6210%\uff0c\u518d\u53bb\u91cd\u3002 df | tr -s ' ' % | cut -d % -f 5 Use 0 0 2 0 8 8 8 8 8 8 8 8 8 8 8 0","title":"2.9.\u6309\u5217\u62bd\u53d6\u6587\u672ccut"},{"location":"linux/SRE/04-TextTools/#210paste","text":"\u547d\u4ee4 paste \u5e38\u7528\u9009\u9879\uff1a -d \uff1a\u6307\u5b9a\u5206\u9694\u7b26\uff0c\u9ed8\u8ba4\u662fTAB -s \uff1a\u6240\u6709\u884c\u5408\u6210\u4e00\u884c\u663e\u793a \u751f\u6210 alpha.log \u548c seq.log \u3002 for i in { a..z } ; do echo $i >> alpha.log ; done seq 10 > seq.log \u7528 paste \u547d\u4ee4\u5408\u5e76\u8fd92\u4e2a\u6587\u4ef6\u3002 $ paste alpha.log seq.log a 1 b 2 c 3 d 4 e 5 f 6 g 7 h 8 i 9 j 10 k l m n o p q r s t u v w x y z $ paste -d \":\" alpha.log seq.log a:1 b:2 c:3 d:4 e:5 f:6 g:7 h:8 i:9 j:10 k: l: m: n: o: p: q: r: s: t: u: v: w: x: y: z: \u539f\u6587\u4ef6\u90fd\u662f\u5217\u8f93\u51fa\uff0c\u6539\u6210\u884c\u8f93\u51fa\u3002 $ paste -d \"-\" -s alpha.log a-b-c-d-e-f-g-h-i-j-k-l-m-n-o-p-q-r-s-t-u-v-w-x-y-z $ paste -d \"-\" -s seq.log $ paste -d \":\" -s alpha.log seq.log a:b:c:d:e:f:g:h:i:j:k:l:m:n:o:p:q:r:s:t:u:v:w:x:y:z 1 :2:3:4:5:6:7:8:9:10 $ paste -d \":\" -s seq.log alpha.log 1 :2:3:4:5:6:7:8:9:10 a:b:c:d:e:f:g:h:i:j:k:l:m:n:o:p:q:r:s:t:u:v:w:x:y:z","title":"2.10.\u5408\u5e76\u591a\u4e2a\u6587\u4ef6paste"},{"location":"linux/SRE/04-TextTools/#211wc","text":"\u5e38\u7528\u9009\u9879\uff1a -l \uff1a\u53ea\u8ba1\u6570\u884c\u6570 -w \uff1a\u53ea\u8ba1\u6570\u5355\u8bcd\u603b\u6570 -c \uff1a\u53ea\u8ba1\u6570\u5b57\u8282\u603b\u6570 -m \uff1a\u53ea\u8ba1\u6570\u5b57\u7b26\u603b\u6570 -L \uff1a\u663e\u793a\u6587\u4ef6\u4e2d\u6700\u957f\u884c\u7684\u957f\u5ea6 $ cat text Tom, 20 , Shanghai Jack, 30 , Beijing Smith, 40 , Guangzhou $ wc text # \u884c\u6570 \u5355\u8bcd\u6570 \u5b57\u8282\u6570 3 9 57 text $ wc -l text 3 text $ wc -w text 9 text $ wc -c text 57 text $ wc -m text 57 text $ wc -L text 20 text \u5bf9\u6bd4\u4e24\u79cd\u4e0d\u540c\u5408\u5e76\u7684\u65b9\u6cd5\u3002 $ cat text1 text2 Tom, 20 , Shanghai Jack, 30 , Beijing Smith, 40 , Guangzhou Tom, 20 , Shanghai Jack, 30 , Beijing Leo, 40 , Guangzhou $ paste text1 text2 Tom, 20 , Shanghai Tom, 20 , Shanghai Jack, 30 , Beijing Jack, 30 , Beijing Smith, 40 , Guangzhou Leo, 40 , Guangzhou","title":"2.11.\u6587\u672c\u7edf\u8ba1\u6570\u636ewc"},{"location":"linux/SRE/04-TextTools/#212sort","text":"\u547d\u4ee4 sort \u628a\u6574\u7406\u8fc7\u7684\u6587\u672c\u663e\u793a\u5728stdout\u4e0a\uff0c\u4e0d\u6539\u53d8\u539f\u6587\u4ef6\u3002 \u5e38\u7528\u9009\u9879\uff1a -r \uff1a\u6267\u884c\u53cd\u65b9\u5411\uff08\u4ece\u4e0a\u81f3\u4e0b\uff09\u6392\u5e8f -R \uff1a\u968f\u673a\u6392\u5e8f -n \uff1a\u6309\u6570\u5b57\u5927\u5c0f\u6392\u5e8f -h \uff1a\u4eba\u7c7b\u53ef\u8bfb\u6392\u5e8f\uff0c\u5982\uff1a2K\uff0c1G -f \uff1a\u6392\u5e8f\u65f6\u5c06\u5c0f\u5199\u5b57\u6bcd\u89c6\u4e3a\u5927\u5199\u5b57\u6bcd -u \uff1a\u6392\u5e8f\u65f6\u5408\u5e76\u91cd\u590d\u9879 -t c \uff1a\u4f7f\u7528c\u4f5c\u4e3a\u5b57\u6bb5\u5206\u9694\u7b26 -k # \uff1a\u6309\u7167\u4ee5c\u4e3a\u5206\u9694\u7b26\u7684\u7b2c#\u5217\u6765\u6392\u5e8f \u4e3e\u4f8b\uff1a\u4ee5 , \u4e3a\u5206\u9694\u7b26\uff0c\u8bfb\u53d6 text \u6587\u4ef6\u5185\u5bb9\u4e2d\u7b2c1\uff0c3\u5217\uff0c\u5bf9\u8f93\u51fa\u7ed3\u679c\u4ee5 , \u4e3a\u5206\u9694\u7b26\uff0c\u6309\u7b2c\u4e8c\u5217\u6392\u5e8f\uff08\u6b63\u5e8f\u548c\u53cd\u5e8f\uff09\u3002 $ cat text Tom, 20 , Shanghai Jack, 30 , Beijing Smith, 40 , Guangzhou $ cut -d \",\" -f 1 ,3 text | sort -t \",\" -k 1 Jack, Beijing Smith, Guangzhou Tom, Shanghai $ cut -d \",\" -f 1 ,3 text | sort -t \",\" -k 1 -r Tom, Shanghai Smith, Guangzhou Jack, Beijing \u628a\u6587\u4ef6text1\u548c\u6587\u4ef6text2\u5408\u5e76\u540e\u53bb\u91cd\u8f93\u51fa\u3002 $ cat text2 Tom, 20 , Shanghai Jack, 30 , Beijing Leo, 40 , Guangzhou $ cat text1 Tom, 20 , Shanghai Jack, 30 , Beijing Smith, 40 , Guangzhou $ cat text1 text2 Tom, 20 , Shanghai Jack, 30 , Beijing Smith, 40 , Guangzhou Tom, 20 , Shanghai Jack, 30 , Beijing Leo, 40 , Guangzhou \u5e76\u96c6\uff0c\u91cd\u590d\u884c\u53ea\u4fdd\u7559\u4e00\u884c\u3002\u524d\u97622\u4e2a\u547d\u4ee4\u662f\u540c\u6837\u542b\u4e49\uff08\u76f8\u540c\u7684\u6392\u5e8f\u5217\uff09\uff0c\u7b2c\u4e09\u4e2a\u547d\u4ee4\u4e2d\u5bf9\u4e0d\u540c\u5217\u8fdb\u884c\u4e86\u6392\u5e8f\uff0c\u5bfc\u81f4\u53bb\u91cd\u7ed3\u679c\u4e0d\u540c\u3002 $ cat text1 text2 | sort -u Jack, 30 , Beijing Leo, 40 , Guangzhou Smith, 40 , Guangzhou Tom, 20 , Shanghai $ cat text1 text2 | sort -t \",\" -k 1 -u Jack, 30 , Beijing Leo, 40 , Guangzhou Smith, 40 , Guangzhou Tom, 20 , Shanghai $ cat text1 text2 | sort -t \",\" -k 2 -u Tom, 20 , Shanghai Jack, 30 , Beijing Smith, 40 , Guangzhou","title":"2.12.\u6587\u672c\u6392\u5e8fsort"},{"location":"linux/SRE/04-TextTools/#213uniq","text":"\u547d\u4ee4 uniq \u4ece\u8f93\u5165\u4e2d\u5220\u9664\u524d\u540e\u76f8\u90bb\u91cd\u590d\u7684\u884c\u3002\u7ecf\u5e38\u4e0e sort \u547d\u4ee4\u7ed3\u5408\u4f7f\u7528\u3002 \u4e3b\u8981\u53c2\u6570\uff1a -c \uff1a\u663e\u793a\u6bcf\u884c\u91cd\u590d\u51fa\u73b0\u7684\u6b21\u6570 -d \uff1a\u4ec5\u663e\u793a\u91cd\u590d\u7684\u884c -u \uff1a\u4ec5\u663e\u793a\u4e0d\u91cd\u590d\u7684\u884c \u4e3e\u4f8b\uff0c\u6ce8\u610f\u53ea\u6709\u5bf9\u76f8\u90bb\u884c\u8fdb\u884c\u53bb\u91cd\u3002 $ cat text3 test 30 Hello 95 Hello 95 Linux 85 Linux 85 Hello 95 test 30 $ uniq text3 test 30 Hello 95 Linux 85 Hello 95 test 30 \u628a\u6587\u4ef6text1\u548c\u6587\u4ef6text2\u5408\u5e76\u540e\uff0c\u8fdb\u884c\u4ea4\u96c6\u548c\u5e76\u96c6\uff0c\u5e76\u53bb\u91cd\u3002 $ cat text1 Tom, 20 , Shanghai Jack, 30 , Beijing Smith, 40 , Guangzhou $ cat text2 Tom, 20 , Shanghai Jack, 30 , Beijing Leo, 40 , Guangzhou # \u5e76\u96c6\uff0c\u6309\u9996\u5217\u6392\u5e8f\u53bb\u91cd $ cat text1 text2 | sort | uniq Jack, 30 , Beijing Leo, 40 , Guangzhou Smith, 40 , Guangzhou Tom, 20 , Shanghai # \u4ea4\u96c6 $ cat text1 text2 | sort | uniq -d Jack, 30 , Beijing Tom, 20 , Shanghai # \u5dee\u96c6 $ cat text1 text2 | sort | uniq -u Leo, 40 , Guangzhou Smith, 40 , Guangzhou \u67e5\u770b\u5e76\u53d1\u8fde\u63a5\u6570\u6700\u591a\u7684\u8fdc\u7a0b\u4e3b\u673aIP\u3002 $ ss -nt State Recv-Q Send-Q Local Address:Port Peer Address:Port Process ESTAB 0 0 192 .168.10.210:22 192 .168.10.210:41650 ESTAB 0 0 192 .168.10.210:22 192 .168.10.201:65330 ESTAB 0 64 192 .168.10.210:22 192 .168.10.201:63289 ESTAB 0 0 192 .168.10.210:41650 192 .168.10.210:22 ESTAB 0 0 192 .168.10.210:47992 192 .168.10.210:22 ESTAB 0 0 192 .168.10.210:60268 192 .168.10.210:22 ESTAB 0 0 192 .168.10.210:22 192 .168.10.201:65327 ESTAB 0 0 192 .168.10.210:35758 192 .168.10.220:22 ESTAB 0 0 192 .168.10.210:22 192 .168.10.210:56818 ESTAB 0 0 192 .168.10.210:56818 192 .168.10.210:22 ESTAB 0 0 192 .168.10.210:48006 192 .168.10.210:22 ESTAB 0 0 192 .168.10.210:22 192 .168.10.210:60268 ESTAB 0 0 192 .168.10.210:22 192 .168.10.220:33896 ESTAB 0 0 192 .168.10.210:22 192 .168.10.201:65324 ESTAB 0 0 192 .168.10.210:22 192 .168.10.210:47992 ESTAB 0 0 192 .168.10.210:59554 192 .168.10.210:22 ESTAB 0 0 192 .168.10.210:22 192 .168.10.210:59554 ESTAB 0 0 192 .168.10.210:22 192 .168.10.210:48006 $ ss -nt | tr -s \" \" \":\" | cut -d \":\" -f 6 ,7 | sort | uniq -c | sort -nr | head -n 1 6 192 .168.10.210:22","title":"2.13.\u53bb\u91cduniq"},{"location":"linux/SRE/04-TextTools/#214","text":"","title":"2.14.\u6587\u672c\u6bd4\u8f83"},{"location":"linux/SRE/04-TextTools/#2141diff","text":"\u547d\u4ee4 diff \u6bd4\u8f83\u4e24\u4e2a\u6587\u4ef6\u4e4b\u95f4\u7684\u533a\u522b\u3002 \u5e38\u7528\u9009\u9879\uff1a -u \uff1a\u4ee5\u7edf\u4e00\u7684\u65b9\u5f0f\u6765\u663e\u793a\u6587\u4ef6\u5185\u5bb9\u7684\u4e0d\u540c -y \uff1a\u4ee5\u5e76\u5217\u7684\u65b9\u5f0f\u663e\u793a\u6587\u4ef6\u7684\u5f02\u540c\u4e4b\u5904 -W \uff1a\u5728\u4f7f\u7528-y\u53c2\u6570\u65f6\uff0c\u6307\u5b9a\u680f\u5bbd -c \uff1a\u663e\u793a\u5168\u90e8\u5185\u6587\uff0c\u5e76\u6807\u51fa\u4e0d\u540c\u4e4b\u5904 -N \uff1a\u7f3a\u5931\u6587\u4ef6\u4ee5\u7a7a\u6587\u4ef6\u5904\u7406 \u4e3e\u4f8b\uff1a $ cat text5 # \u6587\u4ef6\u5c3e\u90e8\u6ca1\u6709\u7a7a\u884c 1001 1002 1003 $ cat text6 # \u6587\u4ef6\u5c3e\u90e8\u6ca1\u6709\u7a7a\u884c 1001 1002 1003a 1004 \u663e\u793a\u4e0d\u540c\u3002 3c3,4 \u4ee3\u8868\u4e24\u4e2a\u6587\u4ef6\u5728\u7b2c3\uff0c4\u884c\u6709\u4e0d\u540c\u3002 $ diff text5 text6 3c3,4 < 1003 --- > 1003a > 1004 \u4ee5\u7edf\u4e00\u683c\u5f0f\u8f93\u51fa\u6bd4\u8f83\u7ed3\u679c\u3002 \u524d2\u884c\u662f\u6587\u4ef6\u4fe1\u606f\u3002\u5176\u4e2d --- \u8868\u793a\u53d8\u52a8\u524d\u7684\u6587\u4ef6\uff0c +++ \u8868\u793a\u53d8\u52a8\u540e\u7684\u6587\u4ef6\u3002 \u53d8\u52a8\u7684\u4f4d\u7f6e\u7528\u4e24\u4e2a@\u4f5c\u4e3a\u8d77\u9996\u548c\u7ed3\u675f\uff0c @@ -1,3 +1,4 @@ \u3002 -1,3 \u4e2d\uff0c - \u8868\u793a\u7b2c\u4e00\u4e2a\u6587\u4ef6\uff0c\u5373 text5 \u3002\u7b2c\u4e00\u4e2a\u6587\u4ef6\u4ece\u7b2c1\u884c\u5f00\u59cb\u8fde\u7eed3\u884c\u3002 +1,4 \u4e2d\uff0c + \u8868\u793a\u7b2c\u4e8c\u4e2a\u6587\u4ef6\uff0c\u5373 text6 \u3002\u5373\uff0c\u7b2c\u4e8c\u4e2a\u6587\u4ef6\u4ece\u7b2c1\u884c\u5f00\u59cb\u8fde\u7eed4\u884c\u3002 $ diff -u text5 text6 --- text5 2022 -12-07 08 :07:05.927805722 +0800 +++ text6 2022 -12-07 08 :07:24.692234585 +0800 @@ -1,3 +1,4 @@ 1001 1002 -1003 +1003a +1004 \u4ee5\u4e0a\u4e0b\u6587\u65b9\u5f0f\u8f93\u51fa\u6bd4\u8f83\u7ed3\u679c\u3002\u6807\u6709 ! \u4ee3\u8868\u5dee\u5f02\u884c\u3002 $ diff -c text5 text6 *** text5 2022 -12-07 08 :24:08.867168414 +0800 --- text6 2022 -12-07 08 :24:13.939284243 +0800 *************** *** 1 ,3 **** 1001 1002 ! 1003 --- 1 ,4 ---- 1001 1002 ! 1003a ! 1004 \u5e76\u6392\u683c\u5f0f\u8f93\u51fa\u6bd4\u8f83\u7ed3\u679c\u3002 | \u8868\u793a\u524d\u540e2\u4e2a\u6587\u4ef6\u5185\u5bb9\u6709\u4e0d\u540c < \u8868\u793a\u540e\u9762\u6587\u4ef6\u6bd4\u524d\u9762\u6587\u4ef6\u5c11\u4e861\u884c\u5185\u5bb9 > \u8868\u793a\u540e\u9762\u6587\u4ef6\u6bd4\u524d\u9762\u6587\u4ef6\u591a\u4e861\u884c\u5185\u5bb9 $ diff -y -W 50 text5 text6 1001 1001 1002 1002 1003 | 1003a > 1004 \u6bd4\u8f83\u6587\u4ef6\u5939\u5185\u5bb9\u3002\u6ce8\u610f\uff0c\u53ea\u6bd4\u8f83\u5185\u5bb9\uff0c\u4e0d\u6bd4\u8f83\u65f6\u95f4\u6233\u3002 $ mkdir dir1 $ mkdir dir2 $ cd dir1 $ touch file1 $ touch file2 $ cp file1 file2 ../dir2/ $ echo \"hello\" > file3 $ cd ../dir2 $ touch file3 $ touch file4 $ diff dir1 dir2 1d0 < hello Only in dir2: file4","title":"2.14.1.diff"},{"location":"linux/SRE/04-TextTools/#2142patch","text":"\u547d\u4ee4 patch \u590d\u5236\u5176\u4ed6\u6587\u4ef6\u4e2d\u7684\u5185\u5bb9\u3002\u547d\u4ee4\u683c\u5f0f\uff1a patch -p [ num ] < patchfile patch [ options ] originalfile patchfile \u5f53\u7279\u5b9a\u8f6f\u4ef6\u6709\u53ef\u7528\u7684\u5b89\u5168\u4fee\u590d\u7a0b\u5e8f\u65f6\uff0c\u6211\u4eec\u901a\u5e38\u4f1a\u4f7f\u7528 yum \u6216 apt-get \u6216 zypper \u7b49\u5305\u7ba1\u7406\u5de5\u5177\u8fdb\u884c\u4e8c\u8fdb\u5236\u5347\u7ea7\u3002 \u4f46\u5982\u679c\u6211\u4eec\u662f\u901a\u8fc7\u4ece\u6e90\u4ee3\u7801\u7f16\u8bd1\u5b89\u88c5\u8f6f\u4ef6\u7684\u60c5\u51b5\u4e0b\uff0c\u6211\u4eec\u9700\u8981\u4e0b\u8f7d\u5b89\u5168\u8865\u4e01\u5e76\u5c06\u5176\u5e94\u7528\u4e8e\u539f\u59cb\u6e90\u4ee3\u7801\u5e76\u91cd\u65b0\u7f16\u8bd1\u8f6f\u4ef6\u3002 \u8fd9\u5c31\u662f\u6211\u4eec\u4f7f\u7528 diff \u521b\u5efa\u8865\u4e01\u6587\u4ef6\uff08patch file\uff09\uff0c\u5e76\u4f7f\u7528 patch \u547d\u4ee4\u5e94\u7528\u5b83\u3002 \u8865\u4e01\u6587\u4ef6\u662f\u4e00\u4e2a\u6587\u672c\u6587\u4ef6\uff0c\u5176\u4e2d\u5305\u542b\u540c\u4e00\u6587\u4ef6\uff08\u6216\u540c\u4e00\u6e90\u4ee3\u7801\u6811\uff09\u7684\u4e24\u4e2a\u7248\u672c\u4e4b\u95f4\u7684\u5dee\u5f02\u3002 \u8865\u4e01\u6587\u4ef6\u662f\u4f7f\u7528 diff \u547d\u4ee4\u521b\u5efa\u7684\u3002 \u7ee7\u7eed\u4e0a\u4f8b\u3002 \u5c06\u6587\u4ef6 text5 \u7684\u5185\u5bb9\u540c\u6b65\u5230\u6587\u4ef6 text6 \uff0c\u7136\u540e\u64a4\u9500\u8865\u4e01\u3002\u6ce8\u610f\u533a\u5206\u6e90\u6587\u4ef6\u548c\u76ee\u6807\u6587\u4ef6\u3002 $ cat text5 1001 1002 1003 $ cat text6 1001 1002 1003a 1004 # \u751f\u6210\u8865\u4e01\u6587\u4ef6 $ diff -ruN text5 text6 > patchfile $ cat patchfile --- text5 2022 -12-07 08 :24:08.867168414 +0800 +++ text6 2022 -12-07 08 :24:13.939284243 +0800 @@ -1,3 +1,4 @@ 1001 1002 -1003 +1003a +1004 # \u4e0d\u6307\u660e\u76ee\u6807\u6587\u4ef6\uff0c\u5219\u9ed8\u8ba4\u7ed9diff\u547d\u4ee4\u4e2d\u7684\u6e90\u6587\u4ef6\u8fdb\u884c\u6253\u8865\u4e01 $ patch < patchfile patching file text5 $ cat text5 1001 1002 1003a 1004 $ cat text6 1001 1002 1003a 1004 # \u64a4\u9500\u8865\u4e01 patch -R < patchfile patching file text5 # cat text5 1001 1002 1003 # \u7ed9text6\u6587\u4ef6\u6253\u8865\u4e01\uff08\u7528text5\u7684\u6587\u4ef6\u5185\u5bb9\u8986\u76d6text6\u7684\u5185\u5bb9\uff09 $ patch text6 patchfile patching file text6 Reversed ( or previously applied ) patch detected! Assume -R? [ n ] y $ cat text6 1001 1002 1003 # \u64a4\u9500\u7ed9text6\u6587\u4ef6\u6253\u7684\u8865\u4e01\uff08\u6062\u590dtext6\u6587\u4ef6\u8865\u4e01\u524d\u7684\u5185\u5bb9\uff09 $ patch -R text6 patchfile patching file text6 Unreversed patch detected! Ignore -R? [ n ] y $ cat text6 1001 1002 1003a 1004 \u4f7f\u7528 -b \u53c2\u6570\uff0c\u5728patch\u524d\u5148\u5907\u4efd\u6e90\u6587\u4ef6\u3002 $ patch -b < patchfile patching file text5 $ cat text5 1001 1002 1003a 1004 $ cat text5.orig 1001 1002 1003 $ cat text6.orig 1001 1002 1003 $ patch -R < patchfile patching file text5 \u5728-b\u53c2\u6570\u4e2d\u52a0\u5165-V\u53c2\u6570\uff0c\u6307\u5b9a\u5907\u4efd\u6587\u4ef6\u540d\u7684\u683c\u5f0f\uff0c\u5982\u4e0b\uff0c\u4f1a\u5f97\u5230\u6587\u4ef6 text5.~1~ \u3002 $patch -b -V numbered < patchfile patching file text5 $ cat text5 1001 1002 1003a 1004 $ cat text5.~1~ 1001 1002 1003 \u8bd5\u8fd0\u884c\uff0c\u4e0d\u505a\u5b9e\u9645\u66f4\u6539\u3002 patch --dry-run < patchfile \u5bf9\u76ee\u5f55\u6253\u8865\u4e01\u3002 \u6267\u884c diff \u548c patch \u547d\u4ee4\u662f\u5728\u5f53\u524d\u7528\u6237 vagrant \u7684\u4e3b\u76ee\u5f55\u4e0b\uff0c\u7edd\u5bf9\u8def\u5f84\u662f /home/vagrant \u3002 diff \u547d\u4ee4\u4e2d\uff0c\u6e90\u76ee\u5f55\u662f /home/vagrant/dir1 \u3002\u76ee\u6807\u76ee\u5f55\u662f /home/vagrant/dir2 \u3002 -p3 \u662f\u544a\u8bc9 patch \u547d\u4ee4\u5ffd\u7565\u4e0a\u9762\u7edd\u5bf9\u8def\u5f84\u4e2d\u524d\u4e09\u4e2a\u659c\u6760 / \u3002 patch \u547d\u4ee4\u4e2d\u7528 diff \u7684\u76ee\u6807\u76ee\u5f55\u53bb\u8986\u76d6\u6e90\u76ee\u5f55\u3002\u4e92\u6362\u4f1a\u62a5\u9519\u3002 -R \uff1a\u64a4\u9500\u8865\u4e01\u3002 # file3\u548cfile4\u6709\u5185\u5bb9 $ tree ./dir1 ./dir1 \u251c\u2500\u2500 file1 \u251c\u2500\u2500 file2 \u251c\u2500\u2500 file3 \u2514\u2500\u2500 subdir1 \u2514\u2500\u2500 file4 \u90fd\u662f\u7a7a\u6587\u4ef6 $ tree ./dir2 ./dir2 \u251c\u2500\u2500 file1 \u251c\u2500\u2500 file2 \u251c\u2500\u2500 file3 \u2514\u2500\u2500 subdir1 \u2514\u2500\u2500 file4 $ diff -ruN /home/vagrant/dir1 /home/vagrant/dir2 > patchdir $ cat patchdir diff -ruN /home/vagrant/dir1/file3 /home/vagrant/dir2/file3 --- /home/vagrant/dir1/file3 2022 -12-07 08 :42:33.108418336 +0800 +++ /home/vagrant/dir2/file3 2022 -12-07 21 :25:48.156056360 +0800 @@ -1 +0,0 @@ -hello diff -ruN /home/vagrant/dir1/subdir1/file4 /home/vagrant/dir2/subdir1/file4 --- /home/vagrant/dir1/subdir1/file4 2022 -12-07 21 :15:09.689912160 +0800 +++ /home/vagrant/dir2/subdir1/file4 2022 -12-07 21 :26:55.405546177 +0800 @@ -1 +0,0 @@ -/home/vagrant/dir1/subdir1 # \u7528dir2\u7684\u5185\u5bb9\u8986\u76d6dir1\u7684\u5185\u5bb9 $ patch -p3 < patchdir patching file dir1/file3 patching file dir1/subdir1/file4 # \u73b0\u5728dir1\u76ee\u5f55\u4e0b\u7684\u5185\u5bb9\u5df2\u7ecf\u88abdir2\u76ee\u5f55\u8986\u76d6\u4e86\u3002file3\u548cfile4\u90fd\u662f\u7a7a\u6587\u4ef6 $ ll ./dir1 total 0 -rw-r--r--. 1 vagrant wheel 0 Dec 7 08 :34 file1 -rw-r--r--. 1 vagrant wheel 0 Dec 7 08 :35 file2 -rw-r--r--. 1 vagrant wheel 0 Dec 7 21 :40 file3 drwxr-xr-x. 1 vagrant wheel 10 Dec 7 21 :40 subdir1 $ ll ./dir1/subdir1 total 0 -rw-r--r--. 1 vagrant wheel 0 Dec 7 21 :40 file4 # \u64a4\u9500\u8865\u4e01\uff0cfile3\u548cfile4\u5df2\u7ecf\u6062\u590d\u4e3a\u539f\u6587\u4ef6 $ patch -R -p3 < patchdir patching file dir1/file3 patching file dir1/subdir1/file4 $ ll ./dir1 -rw-r--r--. 1 vagrant wheel 0 Dec 7 08 :34 file1 -rw-r--r--. 1 vagrant wheel 0 Dec 7 08 :35 file2 -rw-r--r--. 1 vagrant wheel 6 Dec 7 21 :45 file3 drwxr-xr-x. 1 vagrant wheel 10 Dec 7 21 :45 subdir1 $ ll ./dir1/subdir1 -rw-r--r--. 1 vagrant wheel 27 Dec 7 21 :45 file4 # \u7528dir1\u7684\u5185\u5bb9\u8986\u76d6dir2\u7684\u5185\u5bb9\uff0c\u7cfb\u7edf\u62d2\u7edd\u3002 patch dir2 -p3 < patchdir File dir2 is not a regular file -- refusing to patch 1 out of 1 hunk ignored -- saving rejects to file dir2.rej File dir2 is not a regular file -- refusing to patch 1 out of 1 hunk ignored -- saving rejects to file dir2.rej $ patch /home/vagrant/dir2 -p3 < patchdir File /home/vagrant/dir2 is not a regular file -- refusing to patch 1 out of 1 hunk ignored -- saving rejects to file /home/vagrant/dir2.rej File /home/vagrant/dir2 is not a regular file -- refusing to patch 1 out of 1 hunk ignored -- saving rejects to file /home/vagrant/dir2.rej","title":"2.14.2.patch"},{"location":"linux/SRE/04-TextTools/#2143vimdiff","text":"\u547d\u4ee4 vimdiff \u76f8\u5f53\u4e8e vim -d \u3002 \u4e3e\u4f8b\uff1a vimdiff text1 text2","title":"2.14.3.vimdiff"},{"location":"linux/SRE/04-TextTools/#2144cmp","text":"\u547d\u4ee4 cmp \u67e5\u770b\u4e8c\u8fdb\u5236\u6587\u4ef6\u7684\u4e0d\u540c\u3002 $ cmp cp grep cp grep differ: byte 25 , line 1 $ cmp /usr/bin/ls /usr/bin/dir /usr/bin/ls /usr/bin/dir differ: byte 613 , line 1 # \u8df3\u8fc7\u524d735\u4e2a\u5b57\u8282\uff0c\u8f93\u51fa\u540e\u976230\u4e2a\u5b57\u8282\u5185\u5bb9 $ hexdump -s 735 -Cn 30 /usr/bin/ls 000002df 00 00 00 00 00 5d 00 00 00 50 00 00 00 68 00 00 | ..... ] ...P...h.. | 000002ef 00 6a 00 00 00 4f 00 00 00 00 00 00 00 1d | .j...O........ | 000002fd $ hexdump -s 735 -Cn 30 /usr/bin/dir 000002df 00 00 00 00 00 5d 00 00 00 50 00 00 00 68 00 00 | ..... ] ...P...h.. | 000002ef 00 6a 00 00 00 4f 00 00 00 00 00 00 00 1d | .j...O........ | 000002fd","title":"2.14.4.cmp"},{"location":"linux/SRE/05-RegExpress/","text":"\u7b2c\u4e94\u7ae0 \u6b63\u5219\u8868\u8fbe\u5f0f \u00b6 \u6b63\u5219\u8868\u8fbe\u5f0f\u5206\u4e24\u7c7b\uff1a \u57fa\u672c\u6b63\u5219\u8868\u8fbe\u5f0f\uff08Basic Regular Expression\uff0c \u53c8\u53ebBasic RegEx\uff0c\u7b80\u79f0BREs\uff09 \u6269\u5c55\u6b63\u5219\u8868\u8fbe\u5f0f\uff08Extended Regular Expression\uff0c \u53c8\u53ebExtended RegEx\uff0c\u7b80\u79f0EREs\uff09 Perl\u6b63\u5219\u8868\u8fbe\u5f0f\uff08Perl Regular Expression\uff0c \u53c8\u53ebPerl RegEx \u7b80\u79f0PREs \u57fa\u672c\u7684\u6b63\u5219\u8868\u8fbe\u5f0f\u548c\u6269\u5c55\u6b63\u5219\u8868\u8fbe\u5f0f\u7684\u533a\u522b\u5c31\u662f\u5143\u5b57\u7b26\u7684\u4e0d\u540c\u3002 5.1.\u57fa\u672c\u6b63\u5219\u8868\u8fbe\u5f0f\u7b26\u53f7 \u00b6 ^ \uff1a\u8868\u793a\u4ee5\u67d0\u4e2a\u5b57\u7b26\u5f00\u59cb $ \uff1a\u8868\u793a\u4ee5\u67d0\u4e2a\u5b57\u7b26\u7ed3\u5c3e . \uff1a\u8868\u793a\u5339\u914d\u4e00\u4e2a\u4e14\u53ea\u5339\u914d\u4e00\u4e2a\u5b57\u7b26 * \uff1a\u8868\u793a\u5339\u914d\u524d\u8fb9\u4e00\u4e2a\u5b57\u7b26\u51fa\u73b00\u6b21\u6216\u8005\u591a\u6b21 [] \uff1a\u8868\u793a\u5339\u914d\u62ec\u53f7\u5185\u7684\u591a\u4e2a\u5b57\u7b26\u4fe1\u606f,\u4e00\u4e2a\u4e00\u4e2a\u5339\u914d .* \uff1a\u8868\u793a\u5339\u914d\u6240\u6709\uff0c\u7a7a\u884c\u4e5f\u4f1a\u8fdb\u884c\u5339\u914d [^] \uff1a\u8868\u793a\u4e0d\u5339\u914d\u62ec\u53f7\u5185\u7684\u6bcf\u4e00\u4e2a\u5b57\u7b26 ^$ \uff1a\u8868\u793a\u5339\u914d\u7a7a\u884c\u4fe1\u606f \\ \uff1a\u5c06\u6709\u7279\u6b8a\u542b\u4e49\u7684\u5b57\u7b26\u8f6c\u4e49\u4e3a\u901a\u914d\u7b26 5.2.\u6269\u5c55\u6b63\u5219\u8868\u8fbe\u5f0f\u7b26\u53f7 \u00b6 + \uff1a\u8868\u793a\u524d\u4e00\u4e2a\u5b57\u7b26\u51fa\u73b0\u4e00\u6b21\u6216\u4e00\u6b21\u4ee5\u4e0a ? \uff1a\u8868\u793a\u524d\u4e00\u4e2a\u5b57\u7b26\u51fa\u73b00\u6b21\u6216\u8005\u4e00\u6b21\u4ee5\u4e0a | \uff1a\u8868\u793a\u6216\u8005\u7684\u5173\u7cfb,\u5339\u914d\u591a\u4e2a\u4fe1\u606f () \uff1a\u5339\u914d\u4e00\u4e2a\u6574\u4f53\u4fe1\u606f\uff0c\u4e5f\u53ef\u4ee5\u63a5\u540e\u9879\u5f15\u7528 {} \uff1a\u5b9a\u4e49\u524d\u8fb9\u5b57\u7b26\u51fa\u73b0\u51e0\u6b21 \u63d0\u793a\uff1a grep -E \u6216\u8005 egrep \u53ea\u662f\u8868\u793a\u6269\u5c55\u6b63\u5219\uff0c\u4e0d\u4ee3\u8868\u52a0\u4e86e\u5c31\u8868\u793a\u8f6c\u4e49\u4e86\u3002 \u5f53 grep \u4f7f\u7528\u6269\u5c55\u6b63\u5219\u7684\u7b26\u53f7\u65f6\u5019\u9700\u8981\u7528 \\ \u8f6c\u4e49\u4e3a\u901a\u914d\u7b26\u624d\u80fd\u4f7f\u7528\u3002 5.3.\u5b57\u7b26\u5339\u914d \u00b6 [:alpha:] \uff1a\u8868\u793a\u6240\u6709\u7684\u5b57\u6bcd\uff08\u4e0d\u533a\u5206\u5927\u5c0f\u5199\uff09\uff0c\u6548\u679c\u540c [a-z] [:digit:] \uff1a\u8868\u793a\u4efb\u610f\u5355\u4e2a\u6570\u5b57\uff0c\u6548\u679c\u540c [0-9] [:xdigit:] \uff1a\u8868\u793a\u5341\u516d\u8fdb\u5236\u6570\u5b57 [:lower:] \uff1a\u8868\u793a\u4efb\u610f\u5355\u4e2a\u5c0f\u5199\u5b57\u6bcd [:upper:] \uff1a\u8868\u793a\u4efb\u610f\u5355\u4e2a\u5927\u5199\u5b57\u6bcd [:alnum:] \uff1a\u8868\u793a\u4efb\u610f\u5355\u4e2a\u5b57\u6bcd\u6216\u6570\u5b57 [:blank:] \uff1a\u8868\u793a\u7a7a\u767d\u5b57\u7b26\uff08\u7a7a\u683c\u548c\u5236\u8868\u7b26\uff09 [:space:] \uff1a\u8868\u793a\u5305\u62ec\u7a7a\u683c\u3001\u5236\u8868\u7b26\uff08\u6c34\u5e73\u548c\u5782\u76f4\uff09\u3001\u6362\u884c\u7b26\u3001\u56de\u8f66\u7b26\u7b49\u5404\u79cd\u7c7b\u578b\u7684\u7a7a\u767d\uff0c\u6bd4 [:blank:] \u8303\u56f4\u66f4\u5e7f [:cntrl:] \uff1a\u8868\u793a\u4e0d\u53ef\u6253\u5370\u7684\u63a7\u5236\u5b57\u7b26\uff08\u9000\u683c\u3001\u5220\u9664\u3001\u8b66\u94c3\u7b49\uff09 [:graph:] \uff1a\u8868\u793a\u53ef\u6253\u5370\u7684\u975e\u7a7a\u767d\u5b57\u7b26 [:print:] \uff1a\u8868\u793a\u53ef\u6253\u5370\u5b57\u7b26 [:punct:] \uff1a\u8868\u793a\u6807\u70b9\u7b26\u53f7 5.4.\u4f4d\u7f6e\u6807\u8bb0 \u00b6 \u4f4d\u7f6e\u6807\u8bb0\u951a\u70b9\uff08position marker anchor\uff09\u662f\u6807\u8bc6\u5b57\u7b26\u4e32\u4f4d\u7f6e\u7684\u6b63\u5219\u8868\u8fbe\u5f0f\u3002\u9ed8\u8ba4\u60c5\u51b5\u4e0b\uff0c\u6b63\u5219\u8868\u8fbe\u5f0f\u6240\u5339\u914d\u7684\u5b57\u7b26\u53ef\u4ee5\u51fa\u73b0\u5728\u5b57\u7b26\u4e32\u4e2d\u4efb\u4f55\u4f4d\u7f6e\u3002 ^ \uff1a\u884c\u9996\u951a\u5b9a\uff0c\u6307\u5b9a\u4e86\u5339\u914d\u6b63\u5219\u8868\u8fbe\u5f0f\u7684\u6587\u672c\u5fc5\u987b\u8d77\u59cb\u4e8e\u5b57\u7b26\u4e32\u7684\u9996\u90e8\u3002 \u4f8b\u5982\uff1a ^tux \u80fd\u591f\u5339\u914d\u4ee5 tux \u8d77\u59cb\u7684\u884c $ \uff1a\u884c\u5c3e\u951a\u5b9a\uff0c\u6307\u5b9a\u4e86\u5339\u914d\u6b63\u5219\u8868\u8fbe\u5f0f\u7684\u6587\u672c\u5fc5\u987b\u7ed3\u675f\u4e8e\u76ee\u6807\u5b57\u7b26\u4e32\u7684\u5c3e\u90e8\u3002 \\< \u6216 \\b \uff1a\u8bcd\u9996\u951a\u5b9a\uff0c\u7528\u4e8e\u5355\u8bcd\u6a21\u5f0f\u5339\u914d\u5de6\u4fa7\u3002\uff08\u5355\u8bcd\u662f\u6709\u5b57\u6bcd\u3001\u6570\u5b57\u3001\u4e0b\u5212\u7ebf\u7ec4\u6210\uff09 \\> \u6216 \\b \uff1a\u8bcd\u5c3e\u951a\u5b9a\uff0c\u7528\u4e8e\u5355\u8bcd\u6a21\u5f0f\u5339\u914d\u53f3\u4fa7\u3002\uff08\u5355\u8bcd\u662f\u6709\u5b57\u6bcd\u3001\u6570\u5b57\u3001\u4e0b\u5212\u7ebf\u7ec4\u6210\uff09 ^PATTERN$ \uff1a\u7528\u6a21\u5f0fPATTERN\u5339\u914d\u6574\u884c\u3002 ^$ \uff1a\u5339\u914d\u7a7a\u884c\u3002 ^[[:space:]]*$ \uff1a\u5339\u914d\u7a7a\u767d\u884c\uff08\u6574\u884c\uff09\u3002 \\ \uff1a\u5339\u914d\u6574\u4e2a\u5355\u8bcd\u3002\uff08\u5355\u8bcd\u662f\u6709\u5b57\u6bcd\u3001\u6570\u5b57\u3001\u4e0b\u5212\u7ebf\u7ec4\u6210\uff09 \u5173\u4e8e\u884c\u9996\u951a\u5b9a\u548c\u8bcd\u9996\u951a\u5b9a\uff0c\u5bf9\u6bd4\u4e0b\u9762\u4f8b\u5b50\u3002\u8bcd\u5c3e\u951a\u5b9a\u4e5f\u662f\u7c7b\u4f3c\u60c5\u51b5\u3002 ; \u548c - \u90fd\u88ab\u8ba4\u5b9a\u4e3a\u5355\u8bcd\u5206\u9694\u7b26\u3002 # \u7b26\u5408\u8bcd\u9996\u5339\u914d $ echo \"tux_01-tux02\" | grep '\\ mtu 1500 inet 192 .168.10.210 netmask 255 .255.255.0 broadcast 192 .168.10.255 inet6 fe80::20c:29ff:fea4:e17a prefixlen 64 scopeid 0x20 ether 00 :0c:29:a4:e1:7a txqueuelen 1000 ( Ethernet ) RX packets 7654 bytes 635932 ( 621 .0 KiB ) RX errors 0 dropped 1 overruns 0 frame 0 TX packets 1934 bytes 279649 ( 273 .0 KiB ) TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0 $ ifconfig eth0 | grep netmask | grep -o '[0-9]\\{1,3\\}\\.[0-9]\\{1,3\\}\\.[0-9]\\{1,3\\}\\.[0-9]\\{1,3\\}' 192 .168.10.210 255 .255.255.0 192 .168.10.255 $ ifconfig eth0 | grep netmask | grep -o '[0-9]\\{1,3\\}\\.[0-9]\\{1,3\\}\\.[0-9]\\{1,3\\}\\.[0-9]\\{1,3\\}' | head -n 1 192 .168.10.210 $ ifconfig eth0 | grep -o '[0-9]\\{1,3\\}\\.[0-9]\\{1,3\\}\\.[0-9]\\{1,3\\}\\.[0-9]\\{1,3\\}' 192 .168.10.210 255 .255.255.0 192 .168.10.255 ifconfig eth0 | grep -o '[0-9]\\{1,3\\}\\.[0-9]\\{1,3\\}\\.[0-9]\\{1,3\\}\\.[0-9]\\{1,3\\}' | head -n 1 192 .168.10.210 \u5339\u914d\u7a7a\u884c\u548c\u975e\u7a7a\u884c\uff1a grep '^$' /etc/profile grep -v '^$' /etc/profile \u5339\u914d\u975e\u7a7a\u884c\u548c\u975e#\u5f00\u5934\u7684\u884c\uff1a\uff08\u4e09\u79cd\u65b9\u6cd5\uff09 grep -v '^$' /etc/profile | grep -v '^#' grep -v '^$\\|#' /etc/profile grep '^[^$#]' /etc/profile \u6ce8\u610f\uff0c\u5982\u679c\u5199\u6210\u4e0b\u9762\u8fd9\u6837\uff0c\u5219\u4e0d\u4f1a\u8fc7\u6ee4\u6389\u7a7a\u884c\uff0c [$] \u4f1a\u88ab\u89c6\u4e3a $ \u7b26\u53f7\u3002 \u6240\u4ee5\u6b63\u5219\u8868\u8fbe\u5f0f\u7684\u5143\u5b57\u7b26\u653e\u5728\u4e2d\u62ec\u53f7 [] \u5185\u5c31\u88ab\u89c6\u4e3a\u666e\u901a\u5b57\u7b26\u3002 grep -v '^[$#]' /etc/profile 5.8.\u4e09\u5251\u5ba2 grep \u547d\u4ee4 \u00b6 \u683c\u5f0f\uff1a grep [OPTIONS] PATTERN [FILE...] grep [OPTIONS] -e PATTERN ... [FILE...] grep [OPTIONS] -f FILE ... [FILE...] \u53c2\u6570\uff1a -n \uff1a\u663e\u793a\u8fc7\u6ee4\u51fa\u6765\u7684\u6587\u4ef6\u5728\u6587\u4ef6\u5f53\u4e2d\u7684\u884c\u53f7 -c \uff1a\u663e\u793a\u5339\u914d\u5230\u7684\u884c\u6570 -o \uff1a\u53ea\u663e\u793a\u5339\u914d\u5230\u7684\u5185\u5bb9 -q \uff1a\u9759\u9ed8\u8f93\u51fa\uff08\u4e00\u822c\u7528\u5728shell\u811a\u672c\u5f53\u4e2d\uff0c\u901a\u8fc7 echo $? \u67e5\u770b\u547d\u4ee4\u6267\u884c\u7ed3\u679c\uff0c0\u8868\u793a\u6210\u529f\uff0c\u975e0\u8868\u793a\u5931\u8d25\uff09\uff09 -i \uff1a\u5ffd\u7565\u5927\u5c0f\u5199 -v \uff1a\u53cd\u5411\u67e5\u627e -w \uff1a\u5339\u914d\u67d0\u4e2a\u8bcd\u8bcd\uff1a\u5728Linux\u4e2d\uff0c\u8bcd\u4e3a\u4e00\u8fde\u4e32\u5b57\u6bcd\u3001\u6570\u5b57\u548c\u4e0b\u5212\u7ebf\u7ec4\u6210\u7684\u5b57\u7b26\u4e32 -E \uff1a\u4f7f\u7528\u6269\u5c55\u6b63\u5219 -R \uff1a\u9012\u5f52\u67e5\u8be2 -l \uff1a\u53ea\u6253\u5370\u6587\u4ef6\u8def\u5f84 \u6269\u5c55\u53c2\u6570\uff1a -A \uff1a\u663e\u793a\u5339\u914d\u5230\u7684\u6570\u636e\u7684\u540e\u51e0n\u884c -B \uff1a\u663e\u793a\u5339\u914d\u5230\u7684\u6570\u636e\u7684\u524d\u51e0n\u884c -C \uff1a\u663e\u793a\u5339\u914d\u5230\u7684\u6570\u636e\u7684\u524d\u540e\u5404\u51e0n\u884c \u793a\u4f8b\uff1a \u5339\u914d\u7528\u6237\uff1a grep root /etc/passwd root:x:0:0:root:/root:/bin/bash $ grep \"USER\" /etc/passwd $ grep \" $USER \" /etc/passwd vagrant:x:1000:478:vagrant:/home/vagrant:/bin/bash $ grep '$USER' /etc/passwd \u5339\u914d\u5173\u952e\u5b57\uff1a $ grep processor /proc/cpuinfo processor : 0 processor : 1 $ grep -o processor /proc/cpuinfo processor processor $ grep \"cpu family\" /proc/cpuinfo cpu family : 6 cpu family : 6 $ grep -o \"cpu family\" /proc/cpuinfo cpu family cpu family \u901a\u8fc7grep\u8fdb\u884c\u6587\u4ef6\u6bd4\u8f83\u3002 # \u6700\u540e\u4e00\u884c\u662f\u7a7a\u884c $ cat f1 a b 1 c # \u6700\u540e\u4e00\u884c\u662f\u7a7a\u884c $ cat f2 b e f c 1 2 # \u9ad8\u4eae\u663e\u793a\u76f8\u540c\u5185\u5bb9\u7684\u884c\uff0c\u5305\u542b\u6700\u540e\u4e00\u884c\u7a7a\u884c $ grep -f f1 f2 b e f c 1 2 # \u53ea\u663e\u793a\u76f8\u540c\u5185\u5bb9\u7684\u884c\uff0c\u5305\u542b\u6700\u540e\u4e00\u884c\u7a7a\u884c $ grep -wf f1 f2 b c 1 # \u53ea\u663e\u793a\u4e0d\u540c\u5185\u5bb9\u7684\u884c $ grep -wvf f1 f2 e f 2 \u63d0\u793a\uff1a grep -wvf f1 f2 \u6216\u8005 grep -w -v -f f1 f2 \u4e2d\uff0c -f \u53ea\u80fd\u4f5c\u4e3a\u6700\u540e\u4e00\u4e2a\u53c2\u6570\uff0c\u5426\u5219\u4f1a\u62a5\u9519\u3002 \u4f53\u4f1a\u57fa\u672c\u6b63\u5219\u548c\u6269\u5c55\u6b63\u5219\u7684\u5dee\u5f02\u3002 \u4f8b1\uff1a\u8f6c\u4e49\u3002 # \u4e0b\u9762\u51e0\u4e2a\u547d\u4ee4\u8fd4\u56de\u7684\u7ed3\u679c\u662f\u4e00\u6837\u7684\u3002 $ grep \"root\\|bash\" /etc/passwd $ grep -E \"root|bash\" /etc/passwd $ grep -e \"root\" -e \"bash\" /etc/passwd # \u4e0b\u9762\u7684\u547d\u4ee4\u6ca1\u6709\u5339\u914d\u7ed3\u679c\u8fd4\u56de\u3002 $ grep \"root|bash\" /etc/passwd \u4f8b2\uff1a\u4e0b\u97624\u4e2a\u547d\u4ee4\u8fd4\u56de\u540c\u6837\u7684\u7ed3\u679c\u3002 grep \"root\" /etc/passwd grep -E \"root\" /etc/passwd grep \"\\\" /etc/passwd grep -E \"\\\" /etc/passwd \u4f8b3\uff1a\u884c\u9996\u884c\u5c3e\u951a\u5b9a\u3002 $ grep \"^\\(.*\\)\\>.*\\<\\1 $ \" /etc/passwd $ grep -E \"^(.*)\\>.*\\<\\1 $ \" /etc/passwd $ egrep \"^(.*)\\>.*\\<\\1 $ \" /etc/passwd sync:x:5:0:sync:/sbin:/bin/sync shutdown:x:6:0:shutdown:/sbin:/sbin/shutdown halt:x:7:0:halt:/sbin:/sbin/halt \u4f8b4\uff1a\u4e09\u79cd\u65b9\u6cd5\u6c42\u548c\u8ba1\u7b97\uff0c\u8fd0\u7528 grep \uff0c cut \uff0c bc \u548c paste \u547d\u4ee4\u3002 $cat age Jason = 20 Tom = 30 Jack = 40 # \u65b9\u6cd51 $ cat age | cut -d \"=\" -f 2 | tr \"\\n\" + | grep -Eo \".*[0-9]\" | bc 90 # \u65b9\u6cd52 $ grep -Eo \"[0-9]+\" age | tr \"\\n\" + | grep -Eo \".*[0-9]\" | bc 90 # \u65b9\u6cd53 $ grep -Eo \"[0-9]+\" age | paste -s -d \"+\" | bc 90 5.9.\u4e09\u5251\u5ba2 sed \u547d\u4ee4 \u00b6 sed \u662fstream editor\u7684\u7f29\u5199\uff0c\u4e2d\u6587\u79f0\u4e4b\u4e3a\u201c\u6d41\u7f16\u8f91\u5668\u201d\u3002 sed \u547d\u4ee4\u662f\u4e00\u4e2a\u9762\u5411\u884c\u5904\u7406\u7684\u5de5\u5177\uff0c\u5b83\u4ee5\u201c\u884c\u201d\u4e3a\u5904\u7406\u5355\u4f4d\uff0c\u9488\u5bf9\u6bcf\u4e00\u884c\u8fdb\u884c\u5904\u7406\uff0c\u5904\u7406\u540e\u7684\u7ed3\u679c\u4f1a\u8f93\u51fa\u5230\u6807\u51c6\u8f93\u51fa STDOUT \uff0c\u4e0d\u4f1a\u5bf9\u8bfb\u53d6\u7684\u6587\u4ef6\u505a\u4efb\u4f55\u4fee\u6539\u3002 sed \u7684\u5de5\u4f5c\u539f\u7406\uff1a sed \u547d\u4ee4\u662f\u9762\u5411\u201c\u884c\u201d\u8fdb\u884c\u5904\u7406\u7684\uff0c\u6bcf\u4e00\u6b21\u5904\u7406\u4e00\u884c\u5185\u5bb9\u3002 \u5904\u7406\u65f6\uff0c sed \u4f1a\u628a\u8981\u5904\u7406\u7684\u884c\u5b58\u50a8\u5728\u7f13\u51b2\u533a\u4e2d\uff0c\u63a5\u7740\u7528 sed \u547d\u4ee4\u5904\u7406\u7f13\u51b2\u533a\u4e2d\u7684\u5185\u5bb9\uff0c\u5904\u7406\u5b8c\u6210\u540e\uff0c\u628a\u7f13\u51b2\u533a\u7684\u5185\u5bb9\u9001\u5f80\u5c4f\u5e55\u3002\u63a5\u7740\u5904\u7406\u4e0b\u4e00\u884c\uff0c\u8fd9\u6837\u4e0d\u65ad\u91cd\u590d\uff0c\u76f4\u5230\u6587\u4ef6\u672b\u5c3e\u3002\u8fd9\u4e2a\u7f13\u51b2\u533a\u88ab\u79f0\u4e3a\u201c \u6a21\u5f0f\u7a7a\u95f4 \u201d\uff08pattern space\uff09\u3002 \u4fdd\u6301\u7a7a\u95f4(hold space) sed \u7684\u4fdd\u6301\u7a7a\u95f4\u50cf\u4e00\u4e2a\u957f\u671f\u50a8\u5b58\uff0c \u53ef\u4ee5\u628a\u83b7\u53d6\u7684\u4fe1\u606f\u50a8\u5b58\u5230\u5176\u4e2d\uff0c\u5f85\u540e\u7eed\u8c03\u7528\u3002\u4e0d\u80fd\u76f4\u63a5\u5bf9\u4fdd\u6301\u7a7a\u95f4\u8fdb\u884c\u64cd\u4f5c\uff0c \u800c\u662f\u5c06\u4fdd\u6301\u7a7a\u95f4\u7684\u5185\u5bb9\u590d\u5236\u6216\u8005\u6dfb\u52a0\u5230\u6a21\u5f0f\u7a7a\u95f4\u8fdb\u884c\u64cd\u4f5c\u3002 \u975e\u4ea4\u4e92\u5f0f\u6279\u91cf\u4fee\u6539\u6587\u4ef6\u3002 sed \u547d\u4ee4\u683c\u5f0f\uff1a sed [ option ] command file option \u5e38\u7528\u9009\u9879\uff1a -n \uff1a\u4e0d\u8f93\u51fa\u6a21\u5f0fpattern\u7684\u5185\u5bb9\u5230\u5c4f\u5e55\uff08\u5373\u4e0d\u81ea\u52a8\u6253\u5370\uff09 -e \uff1a\u591a\u70b9\u7f16\u8f91 -f filename \uff1a\u4ece\u6307\u5b9a\u6587\u4ef6\u8bfb\u53d6\u7f16\u8f91\u811a\u672c -r \uff0c -E \uff1a\u4f7f\u7528\u6269\u5c55\u6b63\u5219\u8868\u8fbe\u5f0f -i .bak \uff1a\u5907\u4efd\u6587\u4ef6\u5e76\u539f\u5904\u7f16\u8f91 -s \uff1a\u5c06\u591a\u4e2a\u6587\u4ef6\u89c6\u4e3a\u72ec\u7acb\u6587\u4ef6\uff0c\u800c\u4e0d\u662f\u5355\u4e2a\u8fde\u7eed\u7684\u957f\u6587\u4ef6\u6d41 -ir \uff1a \u4e0d\u652f\u6301 -i -r \uff1a \u652f\u6301 -ri \uff1a \u652f\u6301 -ni \uff1a \u5371\u9669\u9009\u9879\uff0c\u4f1a\u6e05\u7a7a\u6587\u4ef6 command \u90e8\u5206\u53ef\u4ee5\u5206\u4e3a\u4e24\u90e8\u5206\uff1a \u8303\u56f4\u8bbe\u5b9a\uff0c\u53ef\u4ee5\u91c7\u7528\u4e24\u79cd\u4e0d\u540c\u7684\u65b9\u5f0f\u6765\u8868\u8fbe\uff1a \u6307\u5b9a\u884c\u6570\uff1a\u5982\uff1a 3,5 \u8868\u793a\u7b2c3\u30014\u30015\u884c 5,$ \u8868\u793a\u7b2c5\u884c\u81f3\u6587\u4ef6\u6700\u540e\u4e00\u884c \u6a21\u5f0f\u5339\u914d\uff1a\u5982\uff1a /^[^dD]/ \u8868\u793a\u5339\u914d\u884c\u9996\u4e0d\u662f\u4ee5 d \u6216 D \u5f00\u5934\u7684\u884c \u52a8\u4f5c\u5904\u7406\uff0c\u4e0b\u9762\u662f\u5e38\u7528\u7684\u52a8\u4f5c\uff1a a \uff1a\u65b0\u589e\uff0c a \u540e\u9762\u7684\u5b57\u4e32\u4f1a\u5728\u65b0\u7684\u4e00\u884c\u51fa\u73b0\uff08\u5f53\u524d\u884c\u7684\u4e0b\u4e00\u884c\uff09 i \uff1a\u63d2\u5165\uff0c i \u540e\u9762\u7684\u5b57\u4e32\u4f1a\u5728\u65b0\u7684\u4e00\u884c\u51fa\u73b0\uff08\u5f53\u524d\u884c\u7684\u4e0a\u4e00\u884c\uff09 r filename \uff1a\u8bfb\u53d6\u6307\u5b9a\u6587\u4ef6 fllename \u7684\u5185\u5bb9\uff0c\u8ffd\u52a0\u5230\u5f53\u524d\u884c\u7684\u4e0b\u4e00\u884c R filename \uff1a\u8bfb\u53d6\u6307\u5b9a\u6587\u4ef6 fllename \u7684\u4e00\u884c\uff0c\u8ffd\u52a0\u5230\u5f53\u524d\u884c\u7684\u4e0b\u4e00\u884c d \uff1a\u5220\u9664\u8be5\u884c p \uff1a\u6253\u5370\u8be5\u884c Ip \uff1a\u5ffd\u7565\u5927\u5c0f\u5199\u8f93\u51fa w filename \uff1a\u5199\u5165\u5230\u6307\u5b9a\u6587\u4ef6filename\u4e2d\u3002 s/regexp/replacement/ \uff1a\u53d6\u4ee3\uff0c\u7528replacement\u53d6\u4ee3\u6b63\u5219regexp\u5339\u914d\u5230\u7684\u5185\u5bb9 = \uff1a\u4e3a\u6a21\u5f0fpattern\u4e2d\u7684\u5339\u914d\u884c\u6253\u5370\u884c\u53f7 ! \uff1a\u4e3a\u6a21\u5f0fpattern\u4e2d\u7684\u5339\u914d\u884c\u53d6\u53cd\u64cd\u4f5c q \uff1a\u7ed3\u675f\u6216\u9000\u51fased \u521b\u5efa\u4e00\u4e2a testfile \u6587\u4ef6\u3002 $ cat < testfile HELLO LINUX! Linux is a free unix-type opterating system. This is a linux testfile! Linux test Google Taobao Banbooob Tesetfile Wiki EOF \u5339\u914d\u5b9a\u4f4d\u6587\u4ef6 testfile \u7b2c\u4e8c\u884c\uff0c\u5e76\u8f93\u51fa\uff08\u5305\u542b\u5339\u914d\u7b2c\u4e8c\u884c\u548c\u8f93\u51fa\u7b2c\u4e8c\u884c\uff09\u3002 # nl testfile | sed '2p' 1 HELLO LINUX! 2 Linux is a free unix-type opterating system. 2 Linux is a free unix-type opterating system. 3 This is a linux testfile! 4 Linux test 5 Google 6 Taobao 7 Banbooob 8 Tesetfile 9 Wiki \u5339\u914d\u5b9a\u4f4d\u6587\u4ef6 testfile \u7b2c\u4e8c\u884c\uff0c\u4e0d\u8f93\u51fa\u3002 # nl testfile | sed -n '2p' 2 Linux is a free unix-type opterating system. \u5339\u914d\u5b9a\u4f4d\u6587\u4ef6 testfile \u6700\u540e\u4e00\u884c\u3002 $ nl testfile | sed -n '$p' 9 Wiki \u5339\u914d\u5b9a\u4f4d\u6587\u4ef6 testfile \u5012\u6570\u7b2c\u4e8c\u884c\u3002 # sed -n \"$(echo $[`cat testfile | wc -l`-1])p\" testfile Tesetfile \u5c06 testfile \u7684\u5185\u5bb9\u5217\u51fa\u7b2c2\uff5e3\u884c\uff0c\u5e76\u4e14\u6253\u5370\u884c\u53f7\u3002 $ nl testfile | sed -n '2,3p' 2 Linux is a free unix-type opterating system. 3 This is a linux testfile! \u5c06 testfile \u7684\u5185\u5bb9\u4ece\u7b2c2\u884c\u5f00\u59cb\uff0c\u5411\u540e\u8f93\u51fa\u989d\u5916\u76843\u884c\uff0c\u5e76\u4e14\u6253\u5370\u884c\u53f7\u3002 $ nl testfile | sed -n '2,+3p' 2 Linux is a free unix-type opterating system. 3 This is a linux testfile! 4 Linux test 5 Google \u5c06 testfile \u7684\u5185\u5bb9\u4ece\u7b2c2\u884c\u5f00\u59cb\uff0c\u5411\u540e\u4ee52\u4e3a\u6b65\u8fdb\u5355\u4f4d\u8f93\u51fa\u6240\u6709\u5339\u914d\u884c\uff0c\u5e76\u4e14\u6253\u5370\u884c\u53f7\uff08\u5373\uff0c\u4ece\u7b2c2\u884c\u5f00\u59cb\u8f93\u51fa\u5076\u6570\u884c\uff09\u3002 nl testfile | sed -n '2~2p' 2 Linux is a free unix-type opterating system. 4 Linux test 6 Taobao 8 Tesetfile \u5c06 testfile \u7684\u5185\u5bb9\u4ece\u7b2c2\u884c\u5f00\u59cb\uff0c\u5411\u540e\u4ee52\u4e3a\u6b65\u8fdb\u5355\u4f4d\u5220\u9664\u6240\u6709\u5339\u914d\u884c\uff0c\u8f93\u51fa\u5269\u4f59\u884c\uff0c\u5e76\u4e14\u6253\u5370\u884c\u53f7\uff08\u5373\uff0c\u4ece\u7b2c2\u884c\u5f00\u59cb\u5220\u9664\u5076\u6570\u884c\uff0c\u8f93\u51fa\u5947\u6570\u884c\uff09\u3002 $ nl testfile | sed '2~2d' 1 HELLO LINUX! 3 This is a linux testfile! 5 Google 7 Banbooob 9 Wiki \u5c06 testfile \u7684\u5185\u5bb9\u8f93\u51fa\uff0c\u5220\u9664\u7b2c2\u884c\u548c\u7b2c5\u884c\uff0c\u5e76\u6253\u5370\u884c\u53f7\u3002 $ nl testfile | sed -e '2d' -e '5d' $ nl testfile | sed -e '2d;5d' $ nl testfile | sed '2d;5d' 1 HELLO LINUX! 3 This is a linux testfile! 4 Linux test 6 Taobao 7 Banbooob 8 Tesetfile 9 Wiki \u5c06 testfile \u7684\u5185\u5bb9\u8f93\u51fa\uff0c\u8f93\u51fa\u533a\u95f4\u662f\u4ece\u884c\u9996 L \u7684\u884c\u5230\u884c\u9996 G \u7684\u884c\u7ed3\u675f\u3002\u4e0d\u4fee\u6539\u539f\u6587\u4ef6\u3002 \u5982\u679c\u884c\u9996\u5339\u914d\u4e0d\u5230\uff0c\u5219\u65e0\u7ed3\u679c\u8f93\u51fa\uff1b\u5982\u679c\u884c\u5c3e\u5339\u914d\u4e0d\u5230\uff0c\u5219\u8f93\u51fa\u5230\u6587\u4ef6\u7ed3\u675f\u3002 $ sed -n '/^L/,/^G/p' testfile Linux is a free unix-type opterating system. This is a linux testfile! Linux test Google \u5c06 testfile \u7684\u5185\u5bb9\u8f93\u51fa\uff0c\u4e14\u5728\u7b2c6\u884c\u540e\u52a0\u4e0a I love Linux \u3002\u4e0d\u4fee\u6539\u539f\u6587\u4ef6\u3002 $ sed -e '6a I love Linux' testfile HELLO LINUX! Linux is a free unix-type opterating system. This is a linux testfile! Linux test Google Taobao I love Linux Banbooob Tesetfile Wiki \u5c06 testfile \u7684\u5185\u5bb9\u5217\u51fa\u5e76\u4e14\u6253\u5370\u884c\u53f7\uff0c\u4e14\u5728\u7b2c6\u884c\u540e\u6dfb\u52a0 I love Linux \u3002\u4e0d\u4fee\u6539\u539f\u6587\u4ef6\u3002 $ nl testfile | sed '6a I love Linux' $ nl testfile | sed '6a\\I love Linux' 1 HELLO LINUX! 2 Linux is a free unix-type opterating system. 3 This is a linux testfile! 4 Linux test 5 Google 6 Taobao I love Linux 7 Banbooob 8 Tesetfile 9 Wiki \u5c06 testfile \u7684\u5185\u5bb9\u5217\u51fa\u5e76\u4e14\u6253\u5370\u884c\u53f7\uff0c\u4e14\u5728\u7b2c3\u884c\u524d\u6dfb\u52a0 I am a journer learner \u3002\u4e0d\u4fee\u6539\u539f\u6587\u4ef6\u3002 $ nl testfile | sed '3i\\I am a journer learner' 1 HELLO LINUX! 2 Linux is a free unix-type opterating system. I am a journer learner 3 This is a linux testfile! 4 Linux test 5 Google 6 Taobao 7 Banbooob 8 Tesetfile 9 Wiki \u5c06 testfile \u7684\u5185\u5bb9\u5217\u51fa\u5e76\u4e14\u6253\u5370\u884c\u53f7\uff0c\u4e14\u5728\u7b2c3\u884c\u524d\u6dfb\u52a0\u4e09\u884c\u5185\u5bb9 Add line 1 \uff0c Add line 2 \uff0c Add line 3 \u3002\u7528\u7b26\u5408 \\ \u8fdb\u884c\u6362\u884c\u3002\u4e0d\u4fee\u6539\u539f\u6587\u4ef6\u3002 $ nl testfile | sed '3i\\Add line 1 \\ Add line 2 \\ Add line 3' 1 HELLO LINUX! 2 Linux is a free unix-type opterating system. Add line 1 Add line 2 Add line 3 3 This is a linux testfile! 4 Linux test 5 Google 6 Taobao 7 Banbooob 8 Tesetfile 9 Wiki \u5c06 testfile \u7684\u5185\u5bb9\u5217\u51fa\u5e76\u4e14\u6253\u5370\u884c\u53f7\uff0c\u4e14\u5c06\u7b2c2-5\u884c\u7684\u5185\u5bb9\u53d6\u4ee3\u6210\u4e3a replaced \u3002\u4e0d\u4fee\u6539\u539f\u6587\u4ef6\u3002 $ nl testfile | sed '2,5c\\replaced' $ nl testfile | sed '2,5c replaced' $ nl testfile | sed '2,5creplaced' 1 HELLO LINUX! replaced 6 Taobao 7 Banbooob 8 Tesetfile 9 Wiki \u5c06 testfile \u7684\u5185\u5bb9\u5217\u51fa\u5e76\u4e14\u6253\u5370\u884c\u53f7\uff0c\u4e14\u5220\u9664\u7b2c2~5\u884c\u3002\u4e0d\u4fee\u6539\u539f\u6587\u4ef6\u3002 $ nl testfile | sed '2,5d' 1 HELLO LINUX! 6 Taobao 7 Banbooob 8 Tesetfile 9 Wiki \u5c06 testfile \u7684\u5185\u5bb9\u5217\u51fa\u5e76\u4e14\u6253\u5370\u884c\u53f7\uff0c\u4e14\u5220\u9664\u7b2c5\u884c\u5230\u6700\u540e\u4e00\u884c\u3002 $ nl testfile | sed '5,$d' 1 HELLO LINUX! 2 Linux is a free unix-type opterating system. 3 This is a linux testfile! 4 Linux test \u5339\u914d\u5b9a\u4f4d\u6587\u4ef6 testfile \u4e2d\u5305\u542b\u5173\u952e\u5b57 linux \u7684\u884c\u3002 $ sed -n '/linux/p' testfile This is a linux testfile! \u5339\u914d\u5b9a\u4f4d\u547d\u4ee4 df \u8f93\u51fa\u4e2d\u4ee5 /dev/sd \u5173\u952e\u5b57\u5f00\u5934\u7684\u884c\u3002\uff08\u9700\u8981\u8f6c\u4e49\u7b26 \\ \uff09 $ df | sed -n '/^\\/dev\\/sd/p' /dev/sda2 102750208 7077280 92055312 8 % / /dev/sda2 102750208 7077280 92055312 8 % /.snapshots /dev/sda2 102750208 7077280 92055312 8 % /home /dev/sda2 102750208 7077280 92055312 8 % /opt /dev/sda2 102750208 7077280 92055312 8 % /root /dev/sda2 102750208 7077280 92055312 8 % /boot/grub2/x86_64-efi /dev/sda2 102750208 7077280 92055312 8 % /boot/grub2/i386-pc /dev/sda2 102750208 7077280 92055312 8 % /srv /dev/sda2 102750208 7077280 92055312 8 % /tmp /dev/sda2 102750208 7077280 92055312 8 % /usr/local /dev/sda2 102750208 7077280 92055312 8 % /var \u5339\u914d\u5b9a\u4f4d\u547d\u4ee4 df \u8f93\u51fa\u4e2d\u4e0d\u4ee5 /dev/sd \u5173\u952e\u5b57\u5f00\u5934\u7684\u884c\u3002\u901a\u8fc7 !p \u8fdb\u884c\u6c42\u53cd\u8f93\u51fa\u3002 $ df | sed -n '/^\\/dev\\/sd/!p' Filesystem 1K-blocks Used Available Use% Mounted on devtmpfs 4096 0 4096 0 % /dev tmpfs 1971208 0 1971208 0 % /dev/shm tmpfs 788484 9612 778872 2 % /run tmpfs 4096 0 4096 0 % /sys/fs/cgroup tmpfs 394240 0 394240 0 % /run/user/1000 \u5339\u914d\u5b9a\u4f4d\u547d\u4ee4 df \u8f93\u51fa\u4e2d\u4e0d\u4ee5 /dev/sd \u548c tmp \u5173\u952e\u5b57\u5f00\u5934\u7684\u884c\u3002 $ df | sed '/^\\/dev\\/sd/d;/^tmp/d' Filesystem 1K-blocks Used Available Use% Mounted on devtmpfs 4096 0 4096 0 % /dev $ df | grep -Ev '^\\/dev\\/sd|^tmp' Filesystem 1K-blocks Used Available Use% Mounted on devtmpfs 4096 0 4096 0 % /dev \u641c\u7d22\u6587\u4ef6 testfile \u6240\u6709\u5305\u542b oo \u5173\u952e\u5b57\u7684\u884c\u5e76\u5339\u914d\u8f93\u51fa\u3002\u4e0d\u4fee\u6539\u539f\u6587\u4ef6\u3002 $ sed -n '/ooo/p' testfile Banbooob $ sed -n '/oo/p' testfile Google Banbooob \u641c\u7d22\u6587\u4ef6 testfile \u6240\u6709\u5305\u542b oo \u5173\u952e\u5b57\u7684\u884c\u5e76\u5220\u9664\u3002\u4e0d\u4fee\u6539\u539f\u6587\u4ef6\u3002 $ sed '/oo/d' testfile HELLO LINUX! Linux is a free unix-type opterating system. This is a linux testfile! Linux test Taobao Tesetfile Wiki \u641c\u7d22\u6587\u4ef6 testfile \u6240\u6709\u5305\u542b oo \u7684\u884c\uff0c\u628a oo \u66ff\u6362\u4e3a kk \uff0c\u518d\u8f93\u51fa\u8fd9\u884c\u3002\u4e0d\u4fee\u6539\u539f\u6587\u4ef6\u3002 $ sed -n '/oo/{s/oo/kk/;p;q}' testfile $ sed -ne '/oo/{s/oo/kk/;p;q}' testfile Gkkgle \u5c06 testfile \u7684\u6bcf\u884c\u4e2d\u7b2c\u4e00\u6b21\u51fa\u73b0 ao \u7684\u66ff\u6362\u6210 HH \u3002 $ sed 's/ao/HH/' testfile HELLO LINUX! Linux is a free unix-type opterating system. This is a linux testfile! Linux test Google THHbao Banbooob Tesetfile Wiki \u4e0b\u9762\u662f\u628a testfile \u7684\u5339\u914d\u5230 ao \u7684\u884c\u66ff\u6362\u6210 HH \u3002 sed '/ao/cHH' testfile HELLO LINUX! SUSE This is a linux testfile! SUSE Google Taobao Banbooob Tesetfile Wiki \u641c\u7d22\u6587\u4ef6 testfile \u6240\u6709\u5305\u542b ao \u7684\u5168\u90e8\u66ff\u6362\u6210 HH \u3002 g \u8868\u793a\u5168\u5c40\u5339\u914d\u3002\u4e0d\u4fee\u6539\u539f\u6587\u4ef6\u3002 $ sed -e 's/ao/HH/g' testfile $ sed 's/ao/HH/g' testfile HELLO LINUX! Linux is a free unix-type opterating system. This is a linux testfile! Linux test Google THHbHH Banbooob Tesetfile Wiki \u5728\u6587\u4ef6 /etc/passwd \u4e2d\u67e5\u627e\u5339\u914d\u6240\u6709\u7b26\u5408 r \u5f00\u5934 t \u7ed3\u5c3e\u4e14\u4e2d\u95f4\u542b\u4efb\u610f\u4e24\u4e2a\u5b57\u7b26\u7684\u884c\uff0c\u5e76\u5728 t \u5b57\u6bcd\u540e\u6dfb\u52a0 er \u3002 $ sed -nr 's/r..t/&er/gp' /etc/passwd rooter:x:0:0:rooter:/rooter:/bin/bash lp:x:493:487:Printering daemon:/var/spool/lpd:/usr/sbin/nologin tftp:x:487:474:TFTP account:/srv/terftpboot:/bin/false vagranter:x:1000:478:vagranter:/home/vagranter:/bin/bash tester1:x:600:1530: \"Test User1,terestuser1@abc.com\" :/home/tester1:/bin/bash \u5c06\u4e0a\u8ff0\u7ed3\u679c\u548c\u539f\u59cb\u5185\u5bb9\u8fdb\u884c\u5bf9\u6bd4\uff0c\u80fd\u66f4\u597d\u7684\u7406\u89e3 s/r..t/&er \u7684\u64cd\u4f5c\u3002 rooter:x:0:0:rooter:/rooter:/bin/bash root:x:0:0:root:/root:/bin/bash lp:x:493:487:Printering daemon:/var/spool/lpd:/usr/sbin/nologin lp:x:493:487:Printing daemon:/var/spool/lpd:/usr/sbin/nologin tftp:x:487:474:TFTP account:/srv/terftpboot:/bin/false tftp:x:487:474:TFTP account:/srv/tftpboot:/bin/false vagranter:x:1000:478:vagranter:/home/vagranter:/bin/bash vagrant:x:1000:478:vagrant:/home/vagrant:/bin/bash tester1:x:600:1530: \"Test User1,terestuser1@abc.com\" :/home/tester1:/bin/bash tester1:x:600:1530: \"Test User1,testuser1@abc.com\" :/home/tester1:/bin/bash \u4f53\u4f1a & \u7684\u4f4d\u7f6e\u4e0d\u540c\u7684\u4e0d\u540c\u542b\u4e49\u3002 # \u9644\u52a0\u5728root\u5355\u8bcd\u540e $ sed -n 's/root/&superman/p' /etc/passwd rootsuperman:x:0:0:root:/root:/bin/bash # \u9644\u52a0\u5728root\u5355\u8bcd\u524d $ sed -n 's/root/superman&/p' /etc/passwd supermanroot:x:0:0:root:/root:/bin/bash \u4f7f\u7528\u53c2\u6570 -i \u8fdb\u884c\u6e90\u6587\u4ef6\u4fee\u6539\u3002 $ sed -i 's/ao/HH/' testfile $ cat testfile HELLO LINUX! Linux is a free unix-type opterating system. This is a linux testfile! Linux test Google THHbao Banbooob Tesetfile Wiki \u6e90\u6587\u4ef6\u4fee\u6539\u524d\uff0c\u5907\u4efd\u5728\u65b0\u6587\u4ef6 testfile.new \u3002 $ sed -i.new 's/ao/HH/' testfile $ cat testfile.new HELLO LINUX! Linux is a free unix-type opterating system. This is a linux testfile! Linux test Google Taobao Banbooob Tesetfile Wiki $ cat testfile HELLO LINUX! Linux is a free unix-type opterating system. This is a linux testfile! Linux test Google THHbao Banbooob Tesetfile Wiki \u8303\u4f8b\uff1a\u9664\u6307\u5b9a\u6587\u4ef6\u5916\uff0c\u5176\u4f59\u90fd\u5220\u9664\u3002 $ touch { 1 ..9 } file.txt $ ls 1file.txt 2file.txt 3file.txt 4file.txt 5file.txt 6file.txt 7file.txt 8file.txt 9file.txt $ ls | grep -E '(3|5|7)file\\.txt' 3file.txt 5file.txt 7file.txt $ ls | grep -Ev '(3|5|7)file\\.txt' 1file.txt 2file.txt 4file.txt 6file.txt 8file.txt 9file.txt \u4e0b\u9762\u56db\u79cd\u65b9\u6cd5\u5b9e\u73b0\u540c\u6837\u7684\u529f\u80fd $ rm ` ls | grep -Ev '(3|5|7)file\\.txt' ` $ ls | sed -n '/^[357]file.txt/!p' | xargs rm $ ls | grep -Ev '(3|5|7)file\\.txt' | sed -n 's/.*/rm &/p' | bash $ ls | grep -Ev '(3|5|7)file\\.txt' | sed -En 's/(.*)/rm &/p' | bash $ ls | grep -Ev '(3|5|7)file\\.txt' | sed -En 's/(.*)/rm \\1/p' | bash $ ls 3file.txt 5file.txt 7file.txt \u540e\u5411\u5f15\u7528 \\0 \\1 \\2 \u7b49\u3002 $ $echo 123456789 | sed -nE 's/(123)(456)(789)/\\1/p' 123 $ echo 123456789 | sed -nE 's/(123)(456)(789)/\\2/p' 456 $ echo 123456789 | sed -nE 's/(123)(456)(789)/\\3/p' 789 $ echo 123456789 | sed -nE 's/(123)(456)(789)/\\3\\1\\2/p' 789123456 $ echo 123456789 | sed -nE 's/(123)(456)(789)/\\1xyz\\2/p' 123xyz456 \u8303\u4f8b\uff1a\u83b7\u53d6\u5206\u533a\u5229\u7528\u7387 $ df | sed -En '/^\\/dev\\/sd/p' /dev/sda2 102750208 7079236 92053692 8 % / /dev/sda2 102750208 7079236 92053692 8 % /.snapshots /dev/sda2 102750208 7079236 92053692 8 % /boot/grub2/i386-pc /dev/sda2 102750208 7079236 92053692 8 % /boot/grub2/x86_64-efi /dev/sda2 102750208 7079236 92053692 8 % /home /dev/sda2 102750208 7079236 92053692 8 % /opt /dev/sda2 102750208 7079236 92053692 8 % /root /dev/sda2 102750208 7079236 92053692 8 % /srv /dev/sda2 102750208 7079236 92053692 8 % /usr/local /dev/sda2 102750208 7079236 92053692 8 % /tmp /dev/sda2 102750208 7079236 92053692 8 % /var $ df | sed -En '/^\\/dev\\/sd/s@.*([0-9]+)%.*@\\1@p' $ df | sed -En '/^\\/dev\\/sd/s#.*([0-9]+)%.*#\\1#p' # df | sed -En '/^\\/dev\\/sd/s/.*([0-9]+)%.*/\\1/p' 8 8 8 8 8 8 8 8 8 8 8 \u4f53\u4f1a\u4e0b\u9762\u7a7a\u683c\u548c\u62ec\u5f27\u5e26\u6765\u7684\u4e0d\u540c\u3002 $ df | sed -En '/^\\/dev\\/sd/s# .*([0-9]+)%.*# \\1#p' /dev/sda2 8 /dev/sda2 8 /dev/sda2 8 /dev/sda2 8 /dev/sda2 8 /dev/sda2 8 /dev/sda2 8 /dev/sda2 8 /dev/sda2 8 /dev/sda2 8 /dev/sda2 8 $ df | sed -En '/^\\/dev\\/sd/s#( .*)([0-9]+)%.*# \\1#p' /dev/sda2 102750208 7079804 92053156 /dev/sda2 102750208 7079804 92053156 /dev/sda2 102750208 7079804 92053156 /dev/sda2 102750208 7079804 92053156 /dev/sda2 102750208 7079804 92053156 /dev/sda2 102750208 7079804 92053156 /dev/sda2 102750208 7079804 92053156 /dev/sda2 102750208 7079804 92053156 /dev/sda2 102750208 7079804 92053156 /dev/sda2 102750208 7079804 92053156 /dev/sda2 102750208 7079804 92053156 $ df | sed -En '/^\\/dev\\/sd/s#( .*)([0-9]+)%.*# \\2#p' /dev/sda2 8 /dev/sda2 8 /dev/sda2 8 /dev/sda2 8 /dev/sda2 8 /dev/sda2 8 /dev/sda2 8 /dev/sda2 8 /dev/sda2 8 /dev/sda2 8 /dev/sda2 8 \u8303\u4f8b\uff1a\u53d6\u5f97\u5f53\u524dIP\u5730\u5740\u3002 $ ifconfig eth0 eth0: flags = 4163 mtu 1500 inet 192 .168.10.210 netmask 255 .255.255.0 broadcast 192 .168.10.255 inet6 fe80::20c:29ff:fea4:e17a prefixlen 64 scopeid 0x20 ether 00 :0c:29:a4:e1:7a txqueuelen 1000 ( Ethernet ) RX packets 22923 bytes 1658298 ( 1 .5 MiB ) RX errors 0 dropped 0 overruns 0 frame 0 TX packets 3763 bytes 442641 ( 432 .2 KiB ) TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0 $ ip addr show eth0 2 : eth0: mtu 1500 qdisc pfifo_fast state UP group default qlen 1000 link/ether 00 :0c:29:a4:e1:7a brd ff:ff:ff:ff:ff:ff altname enp2s1 altname ens33 inet 192 .168.10.210/24 brd 192 .168.10.255 scope global eth0 valid_lft forever preferred_lft forever inet6 fe80::20c:29ff:fea4:e17a/64 scope link valid_lft forever preferred_lft forever $ ifconfig eth0 | sed -En '2s/[^0-9]+([0-9.]+).*/\\1/p' $ ifconfig eth0 | sed -En '2s/^[^0-9]+([0-9.]{7,15}).*/\\1/p' $ ifconfig eth0 | sed -En '2s/^[^0-9]+([0-9.]{7,15}).*$/\\1/p' $ ifconfig eth0 | sed -n '2s/^.*inet //p' | sed -n 's/netmask.*//p' $ ifconfig eth0 | sed -n '2s/^.*inet //;s/ netmask.*//p' $ ifconfig eth0 | sed -En '2s/(.*inet )([0-9].*)(netmask.*)/\\2/p' 192 .168.10.210 192 .168.10.210 192 .168.10.210 \u4f7f\u7528 \\0 \u8f93\u51fa\u5168\u90e8\u53d8\u91cf\u3002 $ ifconfig eth0 | sed -En '2s/(.*inet )([0-9].*)(netmask.*)/\\0/p' inet 192 .168.10.210 netmask 255 .255.255.0 broadcast 192 .168.10.255 $ ifconfig eth0 | sed -En '2s/(.*inet )([0-9].*)(netmask.*)/\\1/p' inet $ ifconfig eth0 | sed -En '2s/(.*inet )([0-9].*)(netmask.*)/\\2/p' 192 .168.10.210 $ ifconfig eth0 | sed -En '2s/(.*inet )([0-9].*)(netmask.*)/\\3/p' netmask 255 .255.255.0 broadcast 192 .168.10.255 \u5bf9\u6bd4\u4e0b\u9762\u4e24\u4e2a\u6307\u4ee4\u7684\u5339\u914d\u5dee\u5f02\u3002 $ ifconfig eth0 | sed -n '2s/^.*inet //p' | sed -n 's/ netmask.*//p' 192 .168.10.210 $ ifconfig eth0 | sed -n '2s/^.*inet //p' | sed -n 's/netmask.* //p' 192 .168.10.210 192 .168.10.255 $ ifconfig eth0 | sed -n '2s/^.*inet //p' | sed -n 's/netmask .*//p' 192 .168.10.210 $ ifconfig eth0 | sed -n '2s/^.*inet //p' | sed -n 's/netmask.*//p' 192 .168.10.210 \u8303\u4f8b\uff1a\u53d6\u57fa\u540d\u548c\u76ee\u5f55\u540d\u3002 \uff08 /etc/sysconfig/network-scripts/ \u76ee\u5f55\u5728Rocky9\u4e2d\u9ed8\u8ba4\u5df2\u521b\u5efa\uff0c\u5728openSUSE\u548cUbuntu\u4e2d\u6ca1\u6709\uff09 # \u53d6\u76ee\u5f55\u540d $ echo \"/etc/sysconfig/network-scripts/\" | sed -E 's#(^/.*/)([^/]+/?)#\\1#' $ echo \"/etc/sysconfig/network-scripts/\" | sed -E 's/(^\\/.*\\/)([^\\/]+\\/?)/\\1/' /etc/sysconfig/ # \u53d6\u57fa\u540d $ echo \"/etc/sysconfig/network-scripts/\" | sed -E 's#(^/.*/)([^/]+/?)#\\2#' $ echo \"/etc/sysconfig/network-scripts/\" | sed -E 's/(^\\/.*\\/)([^\\/]+\\/?)/\\2/' network-scripts/ # \u53d6\u76ee\u5f55\u540d $ echo \"/etc/sysconfig/network-scripts/dummyfile\" | sed -E 's#(^/.*/)([^/]+/?)#\\1#' $ echo \"/etc/sysconfig/network-scripts/dummyfille\" | sed -E 's/(^\\/.*\\/)([^\\/]+\\/?)/\\1/' /etc/sysconfig/network-scripts/ # \u53d6\u57fa\u540d $ echo \"/etc/sysconfig/network-scripts/dummyfile\" | sed -E 's#(^/.*/)([^/]+/?)#\\2#' $ echo \"/etc/sysconfig/network-scripts/dummyfille\" | sed -E 's/(^\\/.*\\/)([^\\/]+\\/?)/\\2/' dummyfille \u8303\u4f8b\uff1a\u53d6\u6587\u4ef6\u540d\u548c\u6587\u4ef6\u6269\u5c55\u540d $ echo 1_.file.tar.gz | sed -En 's/(.*)\\.([^.]+)$/\\1/p' $ echo 1_.file.tar.gz | sed -En 's@(.*)\\.([^.]+)$@\\1@p' 1_.file.tar $ echo 1_.file.tar.gz | sed -En 's/(.*)\\.([^.]+)$/\\2/p' $ echo 1_.file.tar.gz | sed -En 's@(.*)\\.([^.]+)$@\\2@p' gz $ echo 1_.file.tar.gz | grep -Eo '.*\\.' 1_.file.tar. $ echo 1_.file.tar.gz | grep -Eo '[^.]+$' gz \u8303\u4f8b\uff1a\u5c06\u975e # \u5f00\u5934\u7684\u884c\u6dfb\u52a0 # $ cat < testfile HELLO LINUX! Linux is a free unix-type opterating system. This is a linux testfile! Linux test Google Taobao Banbooob #Tesetfile #Wiki EOF $ sed -En 's/^[^#]/#&/p' testfile $ sed -En 's/^[^#](.*)/#\\1/p' testfile #HELLO LINUX! #Linux is a free unix-type opterating system. #This is a linux testfile! #Linux test #Google #Taobao #Banbooob \u8303\u4f8b\uff1a\u5c06 # \u5f00\u5934\u7684\u884c\u5220\u9664 # $ cat < testfile HELLO LINUX! Linux is a free unix-type opterating system. This is a linux testfile! Linux test Google Taobao Banbooob #Tesetfile #Wiki EOF $ sed -Ei.bak '/^#/s/^#//' testfile $ cat testfile HELLO LINUX! Linux is a free unix-type opterating system. This is a linux testfile! Linux test Google Taobao Banbooob Tesetfile Wiki sed \u4fdd\u6301\u7a7a\u95f4\uff08hold space\uff09\u7684\u4f8b\u5b50\uff1a d \uff1a\u5220\u9664pattern space\u7684\u5185\u5bb9\uff0c\u5f00\u59cb\u4e0b\u4e00\u4e2a\u5faa\u73af\u3002 D \uff1a\u5982\u679c\u6a21\u5f0f\u7a7a\u95f4\u4fdd\u62a4\u6362\u884c\u7b26\uff0c\u5219\u5220\u9664\u76f4\u5230\u7b2c\u4e00\u4e2a\u6362\u884c\u7b26\u5230\u6a21\u5f0f\u7a7a\u95f4\u4e2d\u7684\u6587\u672c\uff0c\u5e76\u4e0d\u8bfb\u53d6\u65b0\u7684\u8f93\u5165\u884c\uff0c\u800c\u4f7f\u7528\u5408\u6210\u7684\u6a21\u5f0f\u7a7a\u95f4\u91cd\u65b0\u542f\u52a8\u5faa\u73af\u3002\u5982\u679c\u6a21\u5f0f\u7a7a\u95f4\u4e0d\u5305\u542b\u6362\u884c\u7b26\uff0c\u5219\u7c7b\u4f3c d \u547d\u4ee4\u542f\u52a8\u6b63\u5e38\u7684\u65b0\u5faa\u73af\u3002 h \u3001 H \uff1a\u590d\u5236/\u8ffd\u52a0\u6a21\u5f0f\u7a7a\u95f4\u7684\u5185\u5bb9\u5230\u4fdd\u6301\u7a7a\u95f4\u3002 g \u3001 G \uff1a\u590d\u5236/\u8ffd\u52a0\u4fdd\u6301\u7a7a\u95f4\u7684\u5185\u5bb9\u5230\u6a21\u5f0f\u7a7a\u95f4\u3002 n \u3001 N \uff1a\u590d\u5236/\u8ffd\u52a0\u5339\u914d\u5230\u7684\u4e0b\u4e00\u884c\u5230\u6a21\u5f0f\u7a7a\u95f4\u3002 p\uff1a\u6253\u5370\u5f53\u524d\u6a21\u5f0f\u7a7a\u95f4\u5185\u5bb9\u3002 P\uff1a\u6253\u5370\u6a21\u5f0f\u7a7a\u95f4\u5f00\u5934\u81f3 \\n \u7684\u5185\u5bb9\uff0c\u5e76\u8ffd\u52a0\u5230\u9ed8\u8ba4\u8f93\u51fa\u4e4b\u524d\u3002 x \uff1a\u4ea4\u6362\u4fdd\u6301\u7a7a\u95f4\u548c\u6a21\u5f0f\u7a7a\u95f4\u7684\u5185\u5bb9. \u4e3e\u4f8b\u89e3\u8bfb1\uff1a seq 10 \u547d\u4ee4\u8f93\u51fa1\uff5e10\u4e2a\u6570\u5b57\uff0c\u6bcf\u4e2a\u6570\u5b57\u4e00\u884c\u3002 sed \u547d\u4ee4\u8bfb\u53d6\u7b2c\u4e00\u884c 1 \u5230\u6a21\u5f0f\u7a7a\u95f4\u3002\u56e0\u4e3a\u53c2\u6570 -n \uff0c\u6240\u4ee5\u8bfb\u53d6\u5230\u7684 1 \u4e0d\u6253\u5370\u5230\u5c4f\u5e55\u3002 \u6267\u884c n \u547d\u4ee4\uff0c\u5373\u8bfb\u53d6\u5339\u914d\u5230\u7684\u4e0b\u4e00\u884c\u5230\u6a21\u5f0f\u7a7a\u95f4\uff0c\u5373\u628a\u7b2c\u4e8c\u884c\u7684 2 \u8bfb\u53d6\u5e76\u8986\u76d6\u5230\u6a21\u5f0f\u7a7a\u95f4\u3002 \u6267\u884c p \u547d\u4ee4\uff0c\u628a 2 \u8f93\u51fa\u5230\u5c4f\u5e55\u3002 \u4ee5\u6b64\u7c7b\u63a8\uff0c\u8bfb\u53d6\u7b2c\u4e09\u884c\u7684 3 \u5230\u6a21\u5f0f\u7a7a\u95f4\uff0c\u6267\u884c n \u547d\u4ee4\uff0c\u5c06\u7b2c\u56db\u884c\u7684 4 \u8bfb\u53d6\u5e76\u8986\u76d6\u5230\u6a21\u5f0f\u7a7a\u95f4\u3002\u6267\u884c p \u547d\u4ee4\uff0c\u8f93\u51fa 4 \u5230\u5c4f\u5e55\u3002 \u4ee5\u6b64\u7c7b\u63a8\u3002 $ seq 10 | sed -n 'n;p' 2 4 6 8 10 seq 10 | sed 'n;p' 1 2 2 3 4 4 5 6 6 7 8 8 9 10 10 \u4e3e\u4f8b\u89e3\u8bfb2\uff1a seq 10 \u547d\u4ee4\u8f93\u51fa1\uff5e10\u4e2a\u6570\u5b57\uff0c\u6bcf\u4e2a\u6570\u5b57\u4e00\u884c\u3002 sed \u547d\u4ee4\u8bfb\u53d6\u7b2c\u4e00\u884c\u5230 1 \u5230\u6a21\u5f0f\u7a7a\u95f4\uff08\u8986\u76d6\uff09\u3002 \u6267\u884c\u547d\u4ee4 N \uff0c\u5373\u8bfb\u53d6\u4e0b\u4e00\u884c\uff0c\u5373\u7b2c\u4e8c\u884c\u7684 2 \uff0c\u8ffd\u52a0\u5230\u6a21\u5f0f\u7a7a\u95f4\u3002\u6240\u4ee5\u5f53\u524d\u6a21\u5f0f\u7a7a\u95f4\u6709 1 \u548c 2 \u8fd92\u884c\u8bb0\u5f55\u3002 \u6267\u884c s/\\n// \uff0c\u628a\u6a21\u5f0f\u7a7a\u95f4\u4e2d\u7684\u7b2c\u4e00\u884c\u7684 1 \u540e\u9762\u7684 \\n \u66ff\u6362\u4e3a\u7a7a\uff0c\u5373\uff0c\u539f\u6765\u6a21\u5f0f\u7a7a\u95f4\u7684\u4e24\u884c 1 \u548c 2 \u73b0\u5728\u5408\u5e76\u4e3a\u4e00\u884c\uff0c\u5373 12 \u3002 \u8bfb\u53d6\u7b2c\u4e09\u884c\u7684 3 \u5230\u6a21\u5f0f\u7a7a\u95f4\uff08\u8986\u76d6\uff09\u3002 \u6267\u884c\u547d\u4ee4 N \uff0c\u5373\u8bfb\u53d6\u4e0b\u4e00\u884c\uff0c\u5373\u7b2c\u56db\u884c\u7684 4 \uff0c\u8ffd\u52a0\u5230\u6a21\u5f0f\u7a7a\u95f4\u3002\u6240\u4ee5\u5f53\u524d\u6a21\u5f0f\u7a7a\u95f4\u6709 3 \u548c 4 \u8fd92\u884c\u8bb0\u5f55\u3002 \u6267\u884c s/\\n// \uff0c\u628a\u6a21\u5f0f\u7a7a\u95f4\u4e2d\u7684\u7b2c\u4e00\u884c 3 \u540e\u9762\u7684 \\n \u66ff\u6362\u4e3a\u7a7a\uff0c\u5373\uff0c\u539f\u6765\u6a21\u5f0f\u7a7a\u95f4\u7684\u4e24\u884c 3 \u548c 4 \u73b0\u5728\u5408\u5e76\u4e3a\u4e00\u884c\uff0c\u5373 34 \u3002 \u4ee5\u6b64\u7c7b\u63a8\u3002 $ seq 10 | sed 'N;s/\\n//' 12 34 56 78 910 \u4e3e\u4f8b\u89e3\u8bfb3\uff1a seq 10 \u547d\u4ee4\u8f93\u51fa1\uff5e10\u4e2a\u6570\u5b57\uff0c\u6bcf\u4e2a\u6570\u5b57\u4e00\u884c\u3002 sed \u547d\u4ee4\u8bfb\u53d6\u7b2c\u4e00\u884c\u5230 1 \u5230\u6a21\u5f0f\u7a7a\u95f4\uff08\u8986\u76d6\uff09\u3002 \u6267\u884c !G \uff0c\u5373\u5bf9\u7b2c\u4e00\u884c\u7684 1 \u4e0d\u6267\u884c G \u547d\u4ee4\u3002 \u6267\u884c h \u547d\u4ee4\uff0c\u5373\u628a 1 \u4ece\u6a21\u5f0f\u7a7a\u95f4\u8986\u76d6\u81f3\u4fdd\u6301\u7a7a\u95f4\u3002\u81f3\u6b64\uff0c\u4fdd\u6301\u7a7a\u95f4\u548c\u6a21\u5f0f\u7a7a\u95f4\u90fd\u5b58\u6709 1 \u3002 \u6267\u884c $!d \uff0c\u5373\u4e0d\u662f\u6700\u540e\u4e00\u884c\u5c31\u4ece\u6a21\u5f0f\u7a7a\u95f4\u5220\u9664\uff0c\u6240\u4ee5\u628a 1 \u4ece\u6a21\u5f0f\u7a7a\u95f4\u4e2d\u5220\u9664\u3002 sed \u547d\u4ee4\u8bfb\u53d6\u7b2c\u4e8c\u884c\u5230 2 \u5230\u6a21\u5f0f\u7a7a\u95f4\uff08\u8986\u76d6\uff09\u3002 \u6267\u884c !G \uff0c\u5373\u5bf9\u7b2c\u4e8c\u884c\u7684 2 \u6267\u884c G \u547d\u4ee4\uff0c\u628a 1 \u4ece\u4fdd\u6301\u7a7a\u95f4\u8ffd\u52a0\u5230\u6a21\u5f0f\u7a7a\u95f4\u3002\u81f3\u6b64\uff0c\u4fdd\u6301\u7a7a\u95f4\u5b58\u6709 1 \uff0c\u6a21\u5f0f\u7a7a\u95f4\u5b58\u6709 2 \u548c 1 \u3002 \u6267\u884c h \u547d\u4ee4\uff0c\u5373\u628a 2 \u548c 1 \u4ece\u6a21\u5f0f\u7a7a\u95f4\u8986\u76d6\u81f3\u4fdd\u6301\u7a7a\u95f4\u3002\u81f3\u6b64\uff0c\u4fdd\u6301\u7a7a\u95f4\u548c\u6a21\u5f0f\u7a7a\u95f4\u90fd\u5b58\u6709 2 \u548c 1 \u3002 \u6267\u884c $!d \uff0c\u5373\u4e0d\u662f\u6700\u540e\u4e00\u884c\u5c31\u4ece\u6a21\u5f0f\u7a7a\u95f4\u5220\u9664\uff0c\u6240\u4ee5\u628a 2 \u548c 1 \u4ece\u6a21\u5f0f\u7a7a\u95f4\u4e2d\u5220\u9664\u3002 \u4ee5\u6b64\u7c7b\u63a8\uff0c\u76f4\u81f3\u8bfb\u53d6\u6700\u540e\u4e00\u884c10\u3002\u6b64\u65f6\uff0c\u6a21\u5f0f\u7a7a\u95f4\u662f 10 \uff0c\u4fdd\u6301\u7a7a\u95f4\u5b58\u6709 9 \u3001 8 \u3001 7 \u3001 6 \u3001 5 \u3001 4 \u3001 3 \u3001 2 \u3001 1 \u3002 \u6267\u884c !G \uff0c\u5373\u5bf9\u6700\u540e\u4e00\u884c\u7684 10 \u6267\u884c G \u547d\u4ee4\uff0c\u628a 9 \u3001 8 \u3001 7 \u3001 6 \u3001 5 \u3001 4 \u3001 3 \u3001 2 \u3001 1 \u4ece\u4fdd\u6301\u7a7a\u95f4\u8ffd\u52a0\u5230\u6a21\u5f0f\u7a7a\u95f4\u3002\u81f3\u6b64\uff0c\u4fdd\u6301\u7a7a\u95f4\u5b58\u6709 9 \u3001 8 \u3001 7 \u3001 6 \u3001 5 \u3001 4 \u3001 3 \u3001 2 \u3001 1 \u3002\uff0c\u6a21\u5f0f\u7a7a\u95f4\u5b58\u6709 10 \u3001 9 \u3001 8 \u3001 7 \u3001 6 \u3001 5 \u3001 4 \u3001 3 \u3001 2 \u3001 1 \u3002 \u6267\u884c h \u547d\u4ee4\uff0c\u5373\u628a 10 \u3001 9 \u3001 8 \u3001 7 \u3001 6 \u3001 5 \u3001 4 \u3001 3 \u3001 2 \u3001 1 \u4ece\u6a21\u5f0f\u7a7a\u95f4\u8986\u76d6\u81f3\u4fdd\u6301\u7a7a\u95f4\u3002\u81f3\u6b64\uff0c\u4fdd\u6301\u7a7a\u95f4\u548c\u6a21\u5f0f\u7a7a\u95f4\u90fd\u5b58\u6709 10 \u3001 9 \u3001 8 \u3001 7 \u3001 6 \u3001 5 \u3001 4 \u3001 3 \u3001 2 \u3001 1 \u3002 \u6267\u884c $!d \uff0c\u5f53\u524d\u662f\u6700\u540e\u4e00\u884c\uff0c\u6240\u4ee5\u4e0d\u4ece\u6a21\u5f0f\u7a7a\u95f4\u5220\u9664\u5f53\u524d\u5185\u5bb9\u3002 \u8f93\u51fa\u6a21\u5f0f\u7a7a\u95f4\u5185\u5bb9\u81f3\u5c4f\u5e55\u3002\u537310\uff5e1\u3002 $ seq 10 | sed '1!G;h;$!d' 10 9 8 7 6 5 4 3 2 1 \u5176\u4ed6\u4e00\u4e9b\u4f8b\u5b50\uff1a $ seq 10 | sed -n '/3/{g;1!p;};h' 2 $ seq 10 | sed -nr '/3/{n;p}' 4 $ seq 10 | sed 'N;D' 10 $ seq 10 | sed '3h;9G;9!d' 9 3 $ seq 10 | sed '$!N;$!D' 9 10 $ seq 10 | sed '$!d' 10 $ seq 10 | sed 'G' 1 2 3 4 5 6 7 8 9 10 $ seq 10 | sed 'g' $ seq 10 | sed '/^$/d;G' 1 2 3 4 5 6 7 8 9 10 $ seq 10 | sed 'n;d' 1 3 5 7 9 $ seq 10 | sed -n '1!G;h;$p' 10 9 8 7 6 5 4 3 2 1 5.10.\u4e09\u5251\u5ba2 awk \u547d\u4ee4 \u00b6 awk \u662f\u4e00\u4e2a\u6587\u672c\u5206\u6790\u5de5\u5177\u3002 grep \u64c5\u957f\u67e5\u627e\uff0c sed \u64c5\u957f\u7f16\u8f91\uff0c awk \u64c5\u957f\u6570\u636e\u5206\u6790\u5e76\u751f\u6210\u62a5\u544a\u3002 awk \u7684\u540d\u79f0\u5f97\u81ea\u4e8e\u5b83\u7684\u521b\u59cb\u4ebaAlfred Aho \u3001Peter Weinberger \u548c Brian Kernighan \u59d3\u6c0f\u7684\u9996\u4e2a\u5b57\u6bcd\u3002 awk \u67093\u4e2a\u4e0d\u540c\u7248\u672c: awk \u3001 nawk \u548c gawk \u3002\u6211\u4eec\u8bf4\u7684 awk \u4e00\u822c\u6307 gawk \u3002 gawk \u662f awk \u7684GNU\u7248\u672c\u3002 awk \u628a\u6587\u4ef6\u9010\u884c\u8bfb\u5165\uff0c\u4ee5\u7a7a\u683c\u4e3a\u9ed8\u8ba4\u5206\u9694\u7b26\u5c06\u6bcf\u884c\u5207\u7247\uff0c\u518d\u5bf9\u5207\u7247\u8fdb\u884c\u5206\u6790\u5904\u7406\u3002 5.10.1.\u547d\u4ee4\u683c\u5f0f \u00b6 awk 'pattern{action statements;...}' {filenames} pattern \u8868\u793a awk \u5728\u6570\u636e\u4e2d\u67e5\u627e\u7684\u5185\u5bb9\u3002\u662f\u8981\u8868\u793a\u7684\u6b63\u5219\u8868\u8fbe\u5f0f\uff0c\u7528\u659c\u6760\u62ec\u8d77\u6765\u3002 action \u662f\u5728\u627e\u5230\u5339\u914d\u5185\u5bb9\u65f6\u6240\u6267\u884c\u7684\u4e00\u7cfb\u5217\u547d\u4ee4\u3002 -F \uff1a\u6307\u5b9a\u5206\u9694\u7b26\uff0c\u540e\u9762\u7d27\u8ddf\u5355\u5f15\u53f7\uff0c\u5355\u5f15\u53f7\u5185\u662f\u5206\u9694\u7b26\u3002\u5982\u4e0d\u52a0 -F \u9009\u9879\uff0c\u5219\u4ee5\u7a7a\u683c\u6216\u8005tab\u4f5c\u4e3a\u5206\u9694\u7b26\u3002 -v \uff1avar=value\uff0c\u53d8\u91cf\u8d4b\u503c\u3002 \u63d0\u793a\uff1a -F \"\" \u6307\u5b9a\u7a7a\u5b57\u7b26\u4e32\u4f5c\u4e3a\u5b57\u6bb5\u5206\u9694\u7b26\uff0c\u4ece\u800c\u5c06\u8f93\u5165\u5b57\u7b26\u4e32\u4e2d\u7684\u6bcf\u4e2a\u5b57\u7b26\u4f5c\u4e3a\u4e00\u4e2a\u72ec\u7acb\u7684\u5b57\u6bb5\u8fdb\u884c\u5904\u7406\u3002\u7136\u540e\uff0c\u4f7f\u7528\u5faa\u73af\u904d\u5386\u6bcf\u4e2a\u5b57\u6bb5\uff0c\u5982\u679c\u5b57\u6bb5\u4e2d\u5305\u542b\u6570\u5b57\uff0c\u5219\u5c06\u5176\u6dfb\u52a0\u5230str1\u53d8\u91cf\u4e2d\u3002\u6700\u540e\uff0c\u6253\u5370str1\u7684\u503c\u3002 -F '' \u4e2d\u7684\u4e24\u4e2a\u5355\u5f15\u53f7\u4e4b\u95f4\u6ca1\u6709\u63d0\u4f9b\u6709\u6548\u7684\u5b57\u6bb5\u5206\u9694\u7b26\u3002\u5728awk\u4e2d\uff0c\u5b57\u6bb5\u5206\u9694\u7b26\u5fc5\u987b\u662f\u4e00\u4e2a\u975e\u7a7a\u5b57\u7b26\u4e32\u3002 \u793a\u4f8b\uff1a\u7b2c\u4e00\u4e2a\u548c\u7b2c\u4e09\u4e2a\u547d\u4ee4\u662f\u6b63\u786e\u7684\u3002 $ echo 'Yd$@C#M05MD9&8923+Vip3wZ!33*44&55' | awk -F \"\" '{for(i=1;i<=NF;i++){if($i ~ /[[:digit:]]/){str=$i;str1=(str1 str)}};print str1}' 05989233334455 $ echo 'Yd$@C#M05MD9&8923+Vip3wZ!33*44&55' | awk -F \"\" '{for(i=1;i<=NF;i++){if($i ~ /[[:digit:]]/){str=$i;str1=(str1 str)}};print str1}' $ echo 'Yd$@C#M05MD9&8923+Vip3wZ!33*44&55' | awk -F '' '{for(i=1;i<=NF;i++){if($i ~ /[[:digit:]]/){str=$i;str1=(str1 str)}};print str1}' 05989233334455 $ echo 'Yd$@C#M05MD9&8923+Vip3wZ!33*44&55' | awk -F '' '{for(i=1;i<=NF;i++){if($i ~ /[[:digit:]]/){str=$i;str1=(str1 str)}};print str1}' 5.10.2.\u5de5\u4f5c\u8fc7\u7a0b \u00b6 \u6267\u884cBEGIN{action;...}\u8bed\u53e5\u5757\u4e2d\u7684\u8bed\u53e5\u3002 BEGIN\u8bed\u53e5\u5757\u518dawk\u8bfb\u5165\u8f93\u5165\u6d41\u4e4b\u524d\u88ab\u6267\u884c\u3002 \u662f\u53ef\u9009\u8bed\u53e5\u5757\u3002 \u5305\u542b\u521d\u59cb\u5316\u53d8\u91cf\uff0c\u6253\u5370\u8f93\u51fa\u8868\u683c\u7684\u8868\u5934\u7b49\u8bed\u53e5\u3002 \u4ece\u6587\u4ef6\u6216\u8005\u6807\u51c6\u8f93\u5165stdin\u8bfb\u53d6\u4e00\u884c\uff0c\u7136\u540e\u6267\u884cpattern{action;...}\u8bed\u53e5\u5757\u3002\u4ece\u7b2c\u4e00\u884c\u5f00\u59cb\u5230\u6700\u540e\u4e00\u884c\uff0c\u9010\u884c\u626b\u63cf\u6587\u4ef6\uff0c\u91cd\u590d\u8fd9\u4e2a\u52a8\u4f5c\uff0c\u76f4\u5230\u6587\u4ef6\u6216\u8005\u8f93\u5165\u6d41\u5168\u90e8\u88ab\u8bfb\u53d6\u5b8c\u6bd5\u3002 \u53ef\u9009\u8bed\u53e5\u5757\u3002 \u5982\u679c\u6ca1\u6709\u63d0\u4f9bpattern\u8bed\u53e5\u5757\uff0c\u5219\u9ed8\u8ba4\u6267\u884c{print}\u3002 \u5f53\u8bfb\u81f3\u6587\u4ef6\u6216\u8005\u8f93\u5165\u6d41\u672b\u5c3e\u65f6\uff0c\u6267\u884cEND{action;...}\u8bed\u53e5\u5757\uff0c\u6bd4\u5982\u6253\u5370\u6240\u6709\u884c\u7684\u5206\u6790\u7ed3\u679c\u8fd9\u7c7b\u6c47\u603b\u4fe1\u606f\u3002\u4e5f\u662f\u4e00\u4e2a\u53ef\u9009\u8bed\u53e5\u5757\u3002 5.10.3.\u5206\u9694\u7b26\u3001\u57df\u548c\u8bb0\u5f55 \u00b6 \u6709\u5206\u9694\u7b26\u5206\u9694\u7684\u5b57\u6bb5\uff08\u5217column\uff0c\u57dffield\uff09\uff0c\u6807\u8bb0 $1 \u3001 $2 \u3001 $3 \u3001...\u3001 $n \u79f0\u4e3a\u57df\u6807\u8bc6\uff0c $0 \u4e3a\u6240\u6709\u57df\u3002\u6ce8\u610f\uff0c\u548cshell\u53d8\u91cf\u4e2d\u7684 $ \u4e0d\u540c\u3002 \u6bcf\u4e00\u884c\u6210\u4e3a\u8bb0\u5f55\uff08record\uff09\u3002 \u5982\u679c\u7701\u7565action\uff0c\u5219\u9ed8\u8ba4\u6267\u884c print $0 \u64cd\u4f5c\u3002 5.10.4.\u5e38\u7528action\u5206\u7c7b \u00b6 Output statements: print , printf Expressions: \u7b97\u672f\u3001\u6bd4\u8f83\u8868\u8fbe\u5f0f Compund statements: \u7ec4\u5408\u8bed\u53e5 Control statements: if , while \u8bed\u53e5 Input statements: \u52a8\u4f5c print \u683c\u5f0f\uff1a print item1, item2, ... \u8bf4\u660e\uff1a \u9017\u53f7\u5206\u9694\u7b26 \u8f93\u51faitem\u53ef\u4ee5\u662f\u5b57\u7b26\u4e32\uff0c\u4e5f\u53ef\u4ee5\u662f\u6570\u503c\uff0c\u662f\u5f53\u524d\u8bb0\u5f55\u7684\u5b57\u6bb5\u3001\u53d8\u91cf\u6216 awk \u8868\u8fbe\u5f0f\u3002 \u5982\u679c\u7701\u7565item\uff0c\u76f8\u5f53\u4e8e print $0 \u56fa\u5b9a\u5b57\u7b26\u9700\u8981\u7528\u53cc\u5f15\u53f7\uff0c\u800c\u53d8\u91cf\u548c\u6570\u5b57\u4e0d\u9700\u8981\u3002 \u793a\u4f8b\uff1a $ seq 5 | awk '{print \"hello awk\"}' hello awk hello awk hello awk hello awk hello awk $ seq 5 | awk '{print 3*5}' 15 15 15 15 15 $ awk -F ':' '{print \"hello\"}' /etc/passwd | head -5 hello hello hello hello hello $ awk -F ':' '{print}' /etc/passwd | head -5 root:x:0:0:root:/root:/bin/bash messagebus:x:499:499:User for D-Bus:/run/dbus:/usr/bin/false systemd-network:x:497:497:systemd Network Management:/:/usr/sbin/nologin systemd-timesync:x:496:496:systemd Time Synchronization:/:/usr/sbin/nologin nobody:x:65534:65534:nobody:/var/lib/nobody:/bin/bash $ awk -F ':' '{print $0}' /etc/passwd | head -5 root:x:0:0:root:/root:/bin/bash messagebus:x:499:499:User for D-Bus:/run/dbus:/usr/bin/false systemd-network:x:497:497:systemd Network Management:/:/usr/sbin/nologin systemd-timesync:x:496:496:systemd Time Synchronization:/:/usr/sbin/nologin nobody:x:65534:65534:nobody:/var/lib/nobody:/bin/bash $ awk -F ':' '{print $1,$3}' /etc/passwd | head -5 root 0 messagebus 499 systemd-network 497 systemd-timesync 496 nobody 65534 $ awk -F ':' '{print $1\"\\t\"$3}' /etc/passwd | head -5 root 0 messagebus 499 systemd-network 497 systemd-timesync 496 nobody 65534 $ grep \"^UUID\" /etc/fstab | awk '{print $2,$3}' / btrfs /var btrfs /usr/local btrfs /tmp btrfs /srv btrfs /root btrfs /opt btrfs /home btrfs /boot/grub2/x86_64-efi btrfs /boot/grub2/i386-pc btrfs /.snapshots btrfs swap swap \u793a\u4f8b\uff1a\u8bfb\u53d6\u5206\u533a\u5229\u7528\u7387\u3002 \u5206\u9694\u7b26\u4e2d\u7684\u5b9a\u4e49 [[:space:]]+|% \u7684\u542b\u4e49\uff0c\u4e00\u4e2a\u6216\u591a\u4e2a\u7a7a\u683c\u6216\u8005 % \u4f5c\u4e3a\u5206\u9694\u7b26\u3002 $ df | awk '{print $1,$5}' Filesystem Use% devtmpfs 0 % tmpfs 0 % tmpfs 2 % tmpfs 0 % /dev/sda2 8 % /dev/sda2 8 % /dev/sda2 8 % /dev/sda2 8 % /dev/sda2 8 % /dev/sda2 8 % /dev/sda2 8 % /dev/sda2 8 % /dev/sda2 8 % /dev/sda2 8 % /dev/sda2 8 % tmpfs 0 % $ df | grep '^/dev/sd' | awk -F '[[:space:]]+|%' '{print $1,$5}' $ df | grep '^/dev/sd' | awk -F ' +|%' '{print $1,$5}' /dev/sda2 8 /dev/sda2 8 /dev/sda2 8 /dev/sda2 8 /dev/sda2 8 /dev/sda2 8 /dev/sda2 8 /dev/sda2 8 /dev/sda2 8 /dev/sda2 8 /dev/sda2 8 \u793a\u4f8b\uff1a\u8bfb\u53d6ifconfig\u8f93\u51fa\u7ed3\u679c\u4e2d\u7684ip\u5730\u5740\u3002 $ ifconfig eth0 | sed -n '2p' | awk '/netmask/{print $2}' 192 .168.10.210 $ ifconfig eth0 | sed -n '2p' | awk '{print $2}' 192 .168.10.210 5.10.5.\u6a21\u5f0fPattern \u00b6 \u6839\u636epattern\u6761\u4ef6\uff0c\u8fc7\u6ee4\u5339\u914d\u7684\u884c\uff0c\u518d\u505a\u5904\u7406\u3002 \u5982\u679c\u672a\u6307\u5b9a\uff0c\u5373\u7a7a\u6a21\u5f0f\uff0c\u5219\u5339\u914d\u6bcf\u4e00\u884c\u3002 /regular expression/ \uff0c\u4ec5\u5904\u7406\u80fd\u591f\u6a21\u5f0f\u5339\u914d\u5230\u7684\u884c\uff08\u5373\u7ed3\u679c\u4e3a\u771f\uff09\uff0c\u9700\u8981\u7528 / \u8fdb\u884c\u62ec\u8d77\u6765\u3002 \u7ed3\u679c\u4e3a\u771f\uff0c\u5373\u975e0\u503c\u3001\u975e\u7a7a\u5b57\u7b26\u4e32 \u7ed3\u679c\u4e3a\u5047\uff0c\u53730\u503c\u3001\u7a7a\u5b57\u7b26\u4e32 \u793a\u4f8b\uff1a\u7a7a\u6a21\u5f0f awk -F \":\" '{print $1, $3}' /etc/passwd | head -n5 root 0 messagebus 499 systemd-network 497 systemd-timesync 496 nobody 65534 \u793a\u4f8b\uff1a\u975e\u7a7a\u6a21\u5f0f $ seq 5 | awk '0' $ seq 5 | awk '1' 1 2 3 4 5 $ seq 5 | awk '2' 1 2 3 4 5 $ seq 5 | awk '\"true\"' 1 2 3 4 5 $ seq 5 | awk '\"false\"' 1 2 3 4 5 $ seq 5 | awk 'true' $ seq 5 | awk 'false' $ seq 5 | awk '' $ seq 5 | awk '\"\"' $ seq 5 | awk '\"0\"' 1 2 3 4 5 \u4f53\u4f1a\u4e0b\u9762\u53d8\u91cf\u7684\u503c\u548c\u6b63\u786e\u4f7f\u7528\u53d8\u91cf\uff08\u5b57\u7b26\u4e32\u8fd8\u662f\u53d8\u91cf\uff1f\uff09 $ seq 5 | awk '\"test\"' 1 2 3 4 5 $ seq 5 | awk 'test' $ seq 5 | awk -v test = 0 '\"test\"' $ seq 5 | awk -v test = 0 'test' $ seq 5 | awk -v test = \"0\" 'test' $ seq 5 | awk -v test = \"0\" '\"test\"' 1 2 3 4 5 $ seq 5 | awk -v test = 1 'test' 1 2 3 4 5 \u4f53\u4f1a\u4e0b\u9762\u7684\u4e0e\u975e\u5224\u65ad\u3002 $ awk '1' /etc/passwd | head -n3 root:x:0:0:root:/root:/bin/bash messagebus:x:499:499:User for D-Bus:/run/dbus:/usr/bin/false systemd-network:x:497:497:systemd Network Management:/:/usr/sbin/nologin $ awk '0' /etc/passwd | head -n3 $ awk '!1' /etc/passwd | head -n3 $ awk '!0' /etc/passwd | head -n3 root:x:0:0:root:/root:/bin/bash messagebus:x:499:499:User for D-Bus:/run/dbus:/usr/bin/false systemd-network:x:497:497:systemd Network Management:/:/usr/sbin/nologin # i\u6ca1\u6709\u8d4b\u503c\uff0c\u4e3a\u5047\uff0c\u6ca1\u6709\u8f93\u51fa $ seq 5 | awk 'i' # i\u8d4b\u503c\u4e3a0\uff0c\u4e3a\u5047\uff0c\u6ca1\u6709\u8f93\u51fa $ seq 5 | awk 'i=0' # i\u8d4b\u503c\u4e3a1\uff0c\u4e3a\u771f\uff0c\u8f93\u51fa\u7b2c\u4e00\u884c\u7ed3\u679c\uff0c\u4ee5\u6b64\u7c7b\u63a8\uff0c\u6bcf\u884c\u90fd\u4e3a\u771f\uff0c\u8f93\u51fa\u5168\u90e8seq\u7684\u7ed3\u679c $ seq 5 | awk 'i=1' 1 2 3 4 5 # \u7b2c\u4e00\u6b21\u521d\u59cbi\u672a\u8d4b\u503c\uff0c\u4e3a\u5047\uff0c!i\u5219\u4e3a\u771f\uff0c\u8d4b\u503c\u7ed9i\uff0c\u6240\u4ee5i\u4e3a\u771f,\u8f93\u51faseq\u7b2c1\u884c\u7ed3\u679c # \u7b2c\u4e8c\u6b21\u521d\u59cbi\u4e3a\u771f\uff0c!i\u5219\u4e3a\u5047\uff0c\u8d4b\u503c\u7ed9i\uff0c\u6240\u4ee5i\u4e3a\u5047\uff0c\u4e0d\u8f93\u51faseq\u7b2c2\u884c\u7ed3\u679c # \u7b2c\u4e09\u6b21\u521d\u59cbi\u4e3a\u5047\uff0c!i\u5219\u4e3a\u771f\uff0c\u8d4b\u503c\u7ed9i\uff0c\u6240\u4ee5i\u4e3a\u771f\uff0c\u8f93\u51faseq\u7b2c3\u884c\u7ed3\u679c # \u4ee5\u6b64\u7c7b\u63a8\uff0c\u8f93\u51faseq\u7ed3\u679c\u7684\u5947\u6570\u884c $ seq 5 | awk 'i=!i' 1 3 5 # \u4e0e\u4e0a\u4f8b\u7684\u533a\u522b\u5728\u4e8ei\u521d\u59cb\u503c\u672a\u771f\uff0c\u7b2c\u4e00\u6b21\u7684i\u503c\u4e3a\u5047\uff0c\u4e0d\u8f93\u51faseq\u7b2c1\u884c\u7ed3\u679c # \u7b2c\u4e8c\u6b21i\u7684\u521d\u59cb\u503c\u4e3a\u5047\uff0c\u901a\u8fc7i=!i\u53d8\u4e3a\u771f\uff0c\u6240\u4ee5\u8f93\u51faseq\u7684\u7b2c2\u884c\u7ed3\u679c # \u4ee5\u6b64\u7c7b\u63a8\uff0c\u8f93\u51faseq\u7ed3\u679c\u7684\u5076\u6570\u884c $ seq 5 | awk -v i = 1 'i=!i' 2 4 # \u8f93\u51fa\u8ba1\u6570\u884c $ seq 5 | awk -v i = 0 'i=!i' 1 3 5 # \u53ea\u8f93\u51fai\u7684\u503c\uff0c\u4e0d\u8f93\u51faseq\u7684\u503c $ seq 5 | awk '{i=!i;print i}' 1 0 1 0 1 $ seq 5 | awk '{i=!i}' $ seq 5 | awk '(i=!i)' 1 3 5 $ seq 5 | awk '!(i=!i)' 2 4 5.10.6.\u622a\u53d6\u7247\u6bb5 \u00b6 \u793a\u4f8b\uff1a $ head -n2 /etc/passwd | awk -F ':' '{print $0}' root:x:0:0:root:/root:/bin/bash messagebus:x:499:499:User for D-Bus:/run/dbus:/usr/bin/false $ head -n2 /etc/passwd | awk -F ':' '{print $2}' x x $ head -n2 /etc/passwd | awk -F ':' '{print $1}' root messagebus $ head -n2 /etc/passwd | awk -F ':' '{print $1\"#\"$2\"#\"$3\"#\"$4}' root#x#0#0 messagebus#x#499#499 5.10.7.\u64cd\u4f5c\u7b26 \u00b6 5.10.7.1.\u7b97\u6570\u64cd\u4f5c\u7b26 \u00b6 x+y \uff0c x-y \uff0c x*y \uff0c x/y \uff0c x^y \uff0c x%y \u3002 -x \uff1a\u8f6c\u6362\u4e3a\u8d1f\u6570 +x \uff1a\u5c06\u5b57\u7b26\u4e32\u8f6c\u6362\u4e3a\u6570\u503c \u5217\u503c\u4e4b\u95f4\u8fdb\u884c\u7b97\u672f\u8fd0\u7b97\u3002 $ awk -F ':' '{$7=$3+$4;print $1,$3,$4,$7}' /etc/passwd | head -n5 root 0 0 0 messagebus 499 499 998 systemd-network 497 497 994 systemd-timesync 496 496 992 nobody 65534 65534 131068 \u8ba1\u7b97\u67d0\u4e2a\u5217\u7684\u603b\u548c\u3002 END \u8868\u793a\u6240\u6709\u7684\u884c\u90fd\u5df2\u7ecf\u6267\u884c\u3002 $ awk -F ':' '{(total=total+$3)}; END {print total}' /etc/passwd 103011 5.10.7.2.\u5b57\u7b26\u4e32\u64cd\u4f5c\u7b26 \u00b6 \u6ca1\u6709\u64cd\u4f5c\u7b26\u53f7\uff0c\u5b57\u7b26\u4e32\u8fde\u63a5\u3002 5.10.7.3.\u8d4b\u503c\u64cd\u4f5c\u7b26 \u00b6 = \uff0c += \uff0c -= \uff0c *= \uff0c /= \uff0c %= \uff0c ^= \uff0c ++ \uff0c -- \u3002 \u793a\u4f8b\uff1a $ awk 'BEGIN{print i}' $ awk 'BEGIN{print i++}' #\u4ece0\u5f00\u59cb 0 $ awk 'BEGIN{print ++i}' 1 $ awk 'BEGIN{print i++, i}' 0 1 $ awk 'BEGIN{i=0;print i++, i}' 0 1 $ awk 'BEGIN{print ++i, i}' 1 1 $ awk 'BEGIN{i=0;print ++i, i}' 1 1 $ awk 'BEGIN{i=0;print i, i++}' 0 0 $ awk 'BEGIN{i=0;print i, ++i}' 0 1 $ seq 10 1 2 3 4 5 6 7 8 9 10 # n\u4ece0\u5f00\u59cb\u8ba1\u6570\uff0c\u8f93\u51fa\u7684\u662fn\u503c\uff0c\u4e0d\u662fseq\u7684\u8f93\u51fa\u7ed3\u679c $ seq 10 | awk '{print n++}' 0 1 2 3 4 5 6 7 8 9 # seq=1\u65f6\uff0c\u521d\u59cbn\u672a\u8d4b\u503c\uff0c\u4e3a\u5047\uff0c\u4e0d\u8f93\u51faseq\u7ed3\u679c\uff0cn++\u4e3a\u771f # seq=2\u65f6\uff0cn\u4e3a\u771f\uff0c\u8f93\u51faseq\u7ed3\u679c\uff0cn++\u4e3a\u771f # \u540e\u7eedn++\u90fd\u4e3a\u771f\uff0c\u6240\u4ee5seq\u7684\u7ed3\u679c\u51fa\u4e86\u7b2c\u4e00\u884c\u7531\u4e8en\u4e3a\u5047\u6ca1\u6709\u8f93\u51fa\uff0c\u5176\u4ed6\u884c\u90fd\u8f93\u51fa $ seq 10 | awk 'n++' 2 3 4 5 6 7 8 9 10 # \u53c2\u8003\u4e0a\u4f8b\uff0cn\u521d\u59cb\u672a\u8d4b\u503c\uff0c\u4f46\u6267\u884c++n\u540e\u4e3a\u771f\uff0c\u6240\u4ee5\u8f93\u51fa\u7b2c\u4e00\u884c\uff0c\u540e\u7eed\u884c\u90fd\u8f93\u51fa\u56e0\u4e3an\u4e00\u76f4\u4e3a\u771f $ seq 10 | awk '++n' 1 2 3 4 5 6 7 8 9 10 # n=0\u65f6++n=1\uff0c!++n=0\uff0c\u8f93\u51fa\u7b2c0\u884c $ awk -v n = 0 '!++n' /etc/passwd # n=0\u65f6n++=1\uff0c!n++=1\uff0c\u8f93\u51fa\u7b2c1\u884c $ awk -v n = 0 '!n++' /etc/passwd root:x:0:0:root:/root:/bin/bash $ awk -v n = 0 '!n++{print n}' /etc/passwd 1 # \u65e0\u7ed3\u679c\u8f93\u51fa $ awk -v n = 0 '!++n{print n}' /etc/passwd $ awk -v n = 1 '!n++{print n}' /etc/passwd $ awk -v n = 0 '!n++' /etc/passwd root:x:0:0:root:/root:/bin/bash # \u65e0\u7ed3\u679c\u8f93\u51fa $ awk -v n = 1 '!n++' /etc/passwd $ awk -v n = 2 '!n++' /etc/passwd 5.10.7.4.\u6bd4\u8f83\u64cd\u4f5c\u7b26 \u00b6 \u4f7f\u7528 == \u4ee3\u8868\u7b49\u4e8e\uff0c\u5373\u7cbe\u786e\u5339\u914d\u3002\u7c7b\u4f3c\u8fd8\u6709 > \u3001 >= \u3001 < \u3001 <= \u3001 != \u7b26\u53f7\u3002 \u4ee5 : \u4e3a\u5206\u9694\u7b26\uff0c\u5339\u914d\u7b2c\u4e09\u5217\u7684\u503c\u4e3a 1000 \u7684\u884c\u3002 $ awk -F ':' '$3==\"100\"' /etc/passwd vagrant:x:1000:478:vagrant:/home/vagrant:/bin/bash \u5728\u548c\u6570\u5b57\u6bd4\u8f83\u65f6\uff0c\u82e5\u628a\u8981\u6bd4\u8f83\u7684\u6570\u5b57\u7528\u53cc\u5f15\u53f7\u5f15\u8d77\u6765\uff0c awk \u4f1a\u6309\u5b57\u7b26\u5904\u7406\uff0c\u4e0d\u52a0\u53cc\u5f15\u53f7\uff0c\u5219\u4f1a\u6309\u6570\u5b57\u5904\u7406\u3002 $ awk -F ':' '$3<=\"100\"' /etc/passwd root:x:0:0:root:/root:/bin/bash bin:x:1:1:bin:/bin:/usr/sbin/nologin $ awk -F ':' '$3<=100' /etc/passwd root:x:0:0:root:/root:/bin/bash postfix:x:51:51:Postfix Daemon:/var/spool/postfix:/usr/sbin/nologin man:x:13:62:Manual pages viewer:/var/lib/empty:/usr/sbin/nologin daemon:x:2:2:Daemon:/sbin:/usr/sbin/nologin at:x:25:25:Batch jobs daemon:/var/spool/atjobs:/usr/sbin/nologin bin:x:1:1:bin:/bin:/usr/sbin/nologin awk -F ':' '{if ($1==\"root\") {print $0}}' /etc/passwd awk -F ':' '$7!=\"/bin/false\"' /etc/passwd awk -F ':' '$3<$2' /etc/passwd 5.10.7.5.\u903b\u8f91\u64cd\u4f5c\u7b26 \u00b6 && \u8868\u793a\u201c\u5e76\u4e14\u201d || \u8868\u793a\u201c\u6216\u8005\u201d ! \u8868\u793a\u201c\u975e\u201d\uff08\u53d6\u53cd\uff09 awk -F ':' '$3>10 && $3<100' /etc/passwd awk -F ':' '$3>10 || $3<100' /etc/passwd awk -F ':' '($3==0)' /etc/passwd awk -F ':' '!($3==0)' /etc/passwd \u6ce8\u610f\u4e0b\u9762\u5bf9\u5b57\u7b26\u548c\u6570\u503c\u8fdb\u884c\u53d6\u53cd\u64cd\u4f5c\u7684\u7ed3\u679c\u3002 $ awk 'BEGIN{print i}' $ awk 'BEGIN{print !i}' 1 $ awk -v i = 10 'BEGIN{print i}' 10 $ awk -v i = 10 'BEGIN{print !i}' 0 $ awk -v i = -5 'BEGIN{print i}' -5 $ awk -v i = -5 'BEGIN{print !i}' 0 $ awk -v i = \"abc\" 'BEGIN{print i}' abc $ awk -v i = \"abc\" 'BEGIN{print !i}' 0 $ awk -v i = abc 'BEGIN{print i}' abc $ awk -v i = abc 'BEGIN{print !i}' 0 $ awk -v i = \"\" 'BEGIN{print i}' $ awk -v i = \"\" 'BEGIN{print !i}' 1 \u5728\u5206\u9694\u7b26\u5b9a\u4e49\u4e2d\u4f7f\u7528\u6b63\u5219\u8868\u8fbe\u5f0f\u3002 $ df | awk -F \" +|%\" '{print $5}' Use 0 0 2 0 8 8 8 8 8 8 8 8 8 8 8 0 $ df | awk -F \"[[:space:]]+|%\" '{print $5}' Use 0 0 2 0 8 8 8 8 8 8 8 8 8 8 8 0 5.10.7.6.\u4e09\u76ee\u6761\u4ef6\u8868\u8fbe\u5f0f \u00b6 \u683c\u5f0f\uff1a selector?if-true-expression:if-false-expression $ awk -F ':' '{$3>1000?usertype=\"Common User\":usertype=\"Superuser\";printf\"%-20s:%12s\\n\", $1, usertype}' /etc/passwd | head -n5 root : Superuser messagebus : Superuser systemd-network : Superuser systemd-timesync : Superuser nobody : Common User 5.10.7.8.\u6a21\u5f0f\u5339\u914d\u7b26 \u00b6 ~ \uff1a\u5de6\u53f3\u662f\u5426\u5339\u914d !~ \uff1a\u5de6\u53f3\u662f\u5426\u4e0d\u5339\u914d \u793a\u4f8b\uff1a \u5339\u914d\u6587\u4ef6\u4e2d\u6307\u5b9a\u5b57\u7b26\u4e32 root \u7684\u6240\u6709\u884c\uff0c\u7c7b\u4f3cgrep\u547d\u4ee4\uff0c\u4f46\u6ca1\u6709\u9ad8\u4eae\u663e\u793a\u3002 $ awk '/root/' /etc/passwd root:x:0:0:root:/root:/bin/bash \u4ee5 : \u4e3a\u5206\u9694\u7b26\uff0c\u5339\u914d\u7b2c\u4e00\u5217 $1 \u4e2d\u5305\u542b\u6307\u5b9a\u5b57\u7b26\u4e32 oo \u7684\u884c\u3002 ~ \u662f\u4ee3\u8868\u5de6\u53f3\u5339\u914d\u3002 $ awk -F ':' '$1 ~/oo/' /etc/passwd root:x:0:0:root:/root:/bin/bash gentoo:x:1014:100:Gentoo Distribution:/home/gentoo:/bin/csh \u4ee5 : \u4e3a\u5206\u9694\u7b26\uff0c\u5339\u914d\u6240\u6709\u5217 $0 \uff08\u6574\u884c\uff09\u4e2d\u5305\u542b root \u884c\u7684\u7b2c\u4e00\u5217 $1 \u3002 $ awk -F: '$0 ~/root/{print $1}' /etc/passwd $ awk -F: '$0 ~\"root\"{print $1}' /etc/passwd root daemon _cvmsroot \u4ee5 : \u4e3a\u5206\u9694\u7b26\uff0c\u5339\u914d\u6240\u6709\u5217 $0 \uff08\u6574\u884c\uff09\u4e2d\u4ee5 root \u5f00\u5934\u884c\u7684\u7b2c\u4e00\u5217 $1 \u3002 $ awk -F: '$0 ~\"^root\"{print $1}' /etc/passwd $ awk -F: '$0 ~/^root/{print $1}' /etc/passwd root \u4ee5 : \u4e3a\u5206\u9694\u7b26\uff0c\u5339\u914d\u6240\u6709\u5217 $0 \uff08\u6574\u884c\uff09\u4e2d\u4e0d\u4ee5 root \u5f00\u5934\u884c\u7684\u7b2c\u4e00\u5217 $1 \u3002 awk -F: '$0 !~/^root/{print $1}' /etc/passwd awk -F: '$0 ~/^[^root]/{print $1}' /etc/passwd \u591a\u6761\u4ef6\u5339\u914d\uff0c\u4ee5 : \u4e3a\u5206\u9694\u7b26\uff0c\u5339\u914d\u6240\u6709\u542b\u6709 root \u6216 ftp \u7684\u884c\uff0c\u5e76\u6253\u5370\u7b2c1\u30013\u5217\u3002 awk -F ':' '/root/ {print $1,$3} /bin/ {print $1,$3}' /etc/passwd \u591a\u6761\u4ef6\u5339\u914d\uff0c\u4ee5 : \u4e3a\u5206\u9694\u7b26\uff0c\u5339\u914d\u7b2c\u4e00\u5217\u4e2d\u542b\u6709 root \u6216 bin \u7684\u884c\uff0c\u5e76\u6253\u5370\u7b2c1\u30013\u5217\u3002 $ awk -F ':' '$1 ~/root/ {print $1,$3} $1 ~/bin/ {print $1,$3}' /etc/passwd root 0 bin 1 \u4ee5 : \u4e3a\u5206\u9694\u7b26\uff0c\u5339\u914d\u7b2c\u4e09\u5217 $3 \u4e2d\u503c\u4e3a 0 \u7684\u884c\u3002 $ awk -F \":\" '$3==0' /etc/passwd root:x:0:0:root:/root:/bin/bash \u4ee5\u81f3\u5c11\u4e00\u4e2a\u7a7a\u683c\u6216%\u4e3a\u5206\u9694\u7b26\uff0c\u5339\u914d\u4ee5 /dev/sd \u5f00\u5934\u7684\u884c\uff0c\u6253\u5370\u7b2c\u4e94\u5217\u3002 $ df | awk -F \"[[:space:]]+|%\" '$0 ~ /^\\/dev\\/sd/{print $5}' 8 8 8 8 8 8 8 8 8 8 8 \u8bfb\u53d6 ifconfig eth0 \u8f93\u51fa\u7ed3\u679c\u7684\u7b2c\u4e8c\u884c NR==2 \u7684\u7b2c\u4e8c\u5217 $2 \u3002 $ ifconfig eth0 | awk 'NR==2{print $2}' 192 .168.10.210 5.10.8.\u53d8\u91cf \u00b6 5.10.8.1.\u5185\u7f6e\u53d8\u91cf \u00b6 awk \u5e38\u7528\u7684\u53d8\u91cf\u6709 FS \u3001 OFS \u3001 NF \u548c NR \u3002 FS \u7528\u6765\u5b9a\u4e49\u8f93\u5165\u5b57\u6bb5\u5206\u9694\u7b26\uff0c\u9ed8\u8ba4\u4e3a\u7a7a\u767d\u5b57\u7b26\u3002\u4e0e -F \u9009\u9879\u529f\u80fd\u7c7b\u4f3c\uff0c\u540c\u65f6\u4f7f\u7528\u4f1a\u62a5\u9519\u3002 OFS \u7528\u6765\u5b9a\u4e49\u8f93\u51fa\u5b57\u6bb5\u5206\u9694\u7b26\uff0c\u9ed8\u8ba4\u4e3a\u7a7a\u767d\u5b57\u7b26\u3002 RS \u6307\u5b9a\u8f93\u5165\u65f6\u7684\u6362\u884c\u7b26\u3002 ORS \u6307\u5b9a\u7b26\u53f7\u5728\u8f93\u51fa\u65f6\u66ff\u6362\u6362\u884c\u7b26\u3002 NF \u8868\u793a\u7528\u5206\u9694\u7b26\u5206\u9694\u540e\u4e00\u5171\u6709\u591a\u5c11\u5217\u3002 NR \u8868\u793a\u884c\u53f7\u3002 FNR \u8868\u793a\u4e2a\u6587\u4ef6\u5206\u522b\u8ba1\u6570\u5404\u81ea\u8bb0\u5f55\u7684\u7f16\u53f7\u3002 FILENAME \u8868\u793a\u5f53\u524d\u6587\u4ef6\u540d\u3002 ARGC \u8868\u793a\u547d\u4ee4\u884c\u53c2\u6570\u7684\u4e2a\u6570\u3002 ARVC \u4ee5\u6570\u7ec4\u5f62\u5f0f\u4fdd\u5b58\u547d\u4ee4\u884c\u6240\u7ed9\u5b9a\u7684\u5404\u53c2\u6570\uff0c\u6bcf\u4e2a\u53c2\u6570\uff1a ARGV[0] \uff0c......\u3002 FS \u7684\u7528\u6cd5\uff1a $ awk -v FS = ':' '{print $1, FS, $3}' /etc/passwd | head -n5 root : 0 messagebus : 499 systemd-network : 497 $ awk -F: '{print $1FS$3}' /etc/passwd | head -n3 root:0 messagebus:499 systemd-network:497 $ S = : ; awk -v FS = $S '{print $1FS$3}' /etc/passwd | head -n3 root:0 messagebus:499 systemd-network:497 systemd-timesync:496 nobody:65534 $ S = : ; awk -F $S '{print $1FS$3}' /etc/passwd | head -n3 root:0 messagebus:499 systemd-network:497 FS \u548c -F \u9009\u9879\u529f\u540c\u65f6\u4f7f\u7528\u4f1a\u51b2\u7a81\uff0c -F \u7684\u4f18\u5148\u7ea7\u66f4\u9ad8\u3002 $ awk -v FS = ':' -F ';' '{print $1FS$3}' /etc/passwd | head -n3 root:x:0:0:root:/root:/bin/bash ; messagebus:x:499:499:User for D-Bus:/run/dbus:/usr/bin/false ; systemd-network:x:497:497:systemd Network Management:/:/usr/sbin/nologin ; $ awk -v FS = ';' -F ':' '{print $1FS$3}' /etc/passwd | head -n3 root:0 messagebus:499 systemd-network:497 OFS \u7684\u7528\u6cd5\uff1a \u4ee5 : \u4e3a\u5206\u9694\u7b26\uff0c\u6253\u5370\u7b2c1\u30013\u30014\u5217\u7b2c\u5185\u5bb9\uff0c\u5e76\u4ee5 # \u4e3a\u5206\u9694\u7b26\u3002 $ awk -F ':' '{OFS=\"#\"} {print $1,$3,$4}' /etc/passwd | head -n5 root#0#0 messagebus#499#499 systemd-network#497#497 systemd-timesync#496#496 nobody#65534#65534 $ awk -v FS = ':' -v OFS = '#' '{print $1,$3,$4}' /etc/passwd | head -n5 root#0#0 messagebus#499#499 systemd-network#497#497 systemd-timesync#496#496 nobody#65534#65534 \u4ee5 : \u4e3a\u5206\u9694\u7b26\uff0c\u5f53\u7b2c\u4e09\u5217\u5927\u4e8e\u7b49\u4e8e5000\u65f6\uff0c\u6253\u5370\u7b2c1\u30012\u30013\u30014\u5217\u7b2c\u5185\u5bb9\uff0c\u5e76\u4ee5 # \u4e3a\u5206\u9694\u7b26\u3002 $ awk -F ':' '{OFS=\"#\"} {if ($3>=5000) {print $1,$2,$3,$4}}' /etc/passwd nobody#x#65534#65534 RS \u7684\u7528\u6cd5\uff1a # \u4ee5\u7a7a\u683c\u4e3a\u6362\u884c\u6807\u5fd7 $ awk -v RS = ' ' '{print $0}' /etc/passwd | head -n3 root:x:0:0:root:/root:/bin/bash messagebus:x:499:499:User for # \u4ee5\u5192\u53f7\u4e3a\u6362\u884c\u6807\u5fd7 $ awk -v RS = ':' '{print $0}' /etc/passwd | head -n3 root x 0 ORS \u7684\u7528\u6cd5\uff1a # \u4ee5\u5192\u53f7\u4e3a\u6362\u884c\u6807\u5fd7\uff0c\u66ff\u6362\u6210### $ awk -v RS = ':' -v ORS = '###' '{print $0}' /etc/passwd | head -n3 root###x###0###0###root###/root###/bin/bash messagebus###x###499###499###User for D-Bus###/run/dbus###/usr/bin/false systemd-network###x###497###497###systemd Network Management###/###/usr/sbin/nologin NF \u7684\u7528\u6cd5\uff1a \u5176\u4e2d NF \u662f\u591a\u5c11\u5217\uff0c $NF \u662f\u6700\u540e\u4e00\u5217\u7684\u503c\u3002 \u4e0b\u4f8b\u4e2d\u4ee5 : \u4e3a\u5206\u9694\u7b26\u4e00\u5171\u5206\u4e3a7\u5217\uff0c\u6700\u540e\u4e00\u5217\u7684\u503c\u662f $NF \u3002 $ awk -F ':' '{print $NF}' /etc/passwd | head -n2 /bin/bash /usr/bin/false $ awk -F ':' '{print NF}' /etc/passwd | head -n2 7 7 $ ss -nt | grep \"^ESTAB\" | awk -F \"[[:space:]]+|:\" '{print $(NF-2)}' 192 .168.10.103 $ ss -nt | awk -F \"[[:space:]]+|:\" '/^ESTAB/{print $(NF-2)}' 192 .168.10.103 NR \u7684\u7528\u6cd5\uff1a \u901a\u8fc7 NR \u8f93\u51fa\u884c\u53f7\u3002\u4ee5 : \u4e3a\u5206\u9694\u7b26\uff0c\u6253\u5370\u524d\u4e09\u884c\u7684\u884c\u53f7\u3002 $ awk -F ':' '{print NR}' /etc/passwd | head -n3 1 2 3 \u53d6\u5947\u3001\u5076\u6570\u884c\u3002 $ seq 10 | awk 'NR%2==0' 2 4 6 8 10 $ seq 10 | awk 'NR%2==1' 1 3 5 7 9 \u901a\u8fc7 NR \u8bbe\u5b9a\u884c\u53f7\u6761\u4ef6\u3002\u4ee5 : \u4e3a\u5206\u9694\u7b26\uff0c\u6253\u5370\u7b2c40\u884c\u4ee5\u540e\u7684\u884c\u5185\u5bb9\u3002 $ awk 'NR>45' /etc/passwd admin3:x:1020:100::/home/admin3:/bin/bash smith:x:2002:0:,,,:/home/admin2:/bin/bash pm1:x:2003:1535::/home/pm1:/bin/bash tm1:x:2004:1535::/home/tm1:/bin/bash tm2:x:2005:1536::/home/tm2:/bin/bash $ awk -F ':' 'NR>45' /etc/passwd admin3:x:1020:100::/home/admin3:/bin/bash smith:x:2002:0:,,,:/home/admin2:/bin/bash pm1:x:2003:1535::/home/pm1:/bin/bash tm1:x:2004:1535::/home/tm1:/bin/bash tm2:x:2005:1536::/home/tm2:/bin/bash $ awk -F ':' 'NR>45 {print NR,$1,$3}' /etc/passwd 46 admin3 1020 47 smith 2002 48 pm1 2003 49 tm1 2004 50 tm2 2005 $ awk -F ':' 'BEGIN{print NR}' /etc/passwd 0 $ awk -F ':' 'END{print NR}' /etc/passwd 50 $ ifconfig eth0 | awk '/netmask/{print $0}' inet 192 .168.10.210 netmask 255 .255.255.0 broadcast 192 .168.10.255 $ ifconfig eth0 | awk '/netmask/{print $1}' inet $ ifconfig eth0 | awk '/netmask/{print $2}' 192 .168.10.210 $ ifconfig eth0 | awk 'NR==2{print $0}' inet 192 .168.10.210 netmask 255 .255.255.0 broadcast 192 .168.10.255 $ ifconfig eth0 | awk 'NR==2{print $1}' inet $ ifconfig eth0 | awk 'NR==2{print $2}' 192 .168.10.210 \u901a\u8fc7 NR \u4e0e\u5217\u5339\u914d\u4e00\u8d77\u4f7f\u7528\u3002 $ awk -F ':' 'NR<5 && $1 ~/roo/' /etc/passwd root:x:0:0:root:/root:/bin/bash FNR \u7684\u7528\u6cd5\uff1a $ awk '{print FNR}' /etc/fstab /etc/networks 1 2 3 4 5 6 7 8 9 10 11 12 1 2 3 4 5 6 7 8 9 10 $ awk '{print NR, $0}' /etc/fstab /etc/networks 1 UUID = 5ffa8dbd-473e-4308-804a-0033c3b5f7af / btrfs defaults 0 0 2 UUID = 5ffa8dbd-473e-4308-804a-0033c3b5f7af /var btrfs subvol = /@/var 0 0 3 UUID = 5ffa8dbd-473e-4308-804a-0033c3b5f7af /usr/local btrfs subvol = /@/usr/local 0 0 4 UUID = 5ffa8dbd-473e-4308-804a-0033c3b5f7af /tmp btrfs subvol = /@/tmp 0 0 5 UUID = 5ffa8dbd-473e-4308-804a-0033c3b5f7af /srv btrfs subvol = /@/srv 0 0 6 UUID = 5ffa8dbd-473e-4308-804a-0033c3b5f7af /root btrfs subvol = /@/root 0 0 7 UUID = 5ffa8dbd-473e-4308-804a-0033c3b5f7af /opt btrfs subvol = /@/opt 0 0 8 UUID = 5ffa8dbd-473e-4308-804a-0033c3b5f7af /home btrfs subvol = /@/home 0 0 9 UUID = 5ffa8dbd-473e-4308-804a-0033c3b5f7af /boot/grub2/x86_64-efi btrfs subvol = /@/boot/grub2/x86_64-efi 0 0 10 UUID = 5ffa8dbd-473e-4308-804a-0033c3b5f7af /boot/grub2/i386-pc btrfs subvol = /@/boot/grub2/i386-pc 0 0 11 UUID = 5ffa8dbd-473e-4308-804a-0033c3b5f7af /.snapshots btrfs subvol = /@/.snapshots 0 0 12 UUID = 47c36ad7-f49f-4ecd-9b72-4801c5bb3a04 swap swap defaults 0 0 13 # 14 # networks This file describes a number of netname-to-address 15 # mappings for the TCP/IP subsystem. It is mostly 16 # used at boot time, when no name servers are running. 17 # 18 19 loopback 127 .0.0.0 20 link-local 169 .254.0.0 21 22 # End. $ awk '{print FNR, $0}' /etc/fstab /etc/networks 1 UUID = 5ffa8dbd-473e-4308-804a-0033c3b5f7af / btrfs defaults 0 0 2 UUID = 5ffa8dbd-473e-4308-804a-0033c3b5f7af /var btrfs subvol = /@/var 0 0 3 UUID = 5ffa8dbd-473e-4308-804a-0033c3b5f7af /usr/local btrfs subvol = /@/usr/local 0 0 4 UUID = 5ffa8dbd-473e-4308-804a-0033c3b5f7af /tmp btrfs subvol = /@/tmp 0 0 5 UUID = 5ffa8dbd-473e-4308-804a-0033c3b5f7af /srv btrfs subvol = /@/srv 0 0 6 UUID = 5ffa8dbd-473e-4308-804a-0033c3b5f7af /root btrfs subvol = /@/root 0 0 7 UUID = 5ffa8dbd-473e-4308-804a-0033c3b5f7af /opt btrfs subvol = /@/opt 0 0 8 UUID = 5ffa8dbd-473e-4308-804a-0033c3b5f7af /home btrfs subvol = /@/home 0 0 9 UUID = 5ffa8dbd-473e-4308-804a-0033c3b5f7af /boot/grub2/x86_64-efi btrfs subvol = /@/boot/grub2/x86_64-efi 0 0 10 UUID = 5ffa8dbd-473e-4308-804a-0033c3b5f7af /boot/grub2/i386-pc btrfs subvol = /@/boot/grub2/i386-pc 0 0 11 UUID = 5ffa8dbd-473e-4308-804a-0033c3b5f7af /.snapshots btrfs subvol = /@/.snapshots 0 0 12 UUID = 47c36ad7-f49f-4ecd-9b72-4801c5bb3a04 swap swap defaults 0 0 1 # 2 # networks This file describes a number of netname-to-address 3 # mappings for the TCP/IP subsystem. It is mostly 4 # used at boot time, when no name servers are running. 5 # 6 7 loopback 127 .0.0.0 8 link-local 169 .254.0.0 9 10 # End. FILENAME \u7684\u7528\u6cd5\uff1a $ awk '{print FILENAME}' /etc/fstab /etc/fstab /etc/fstab /etc/fstab /etc/fstab /etc/fstab /etc/fstab /etc/fstab /etc/fstab /etc/fstab /etc/fstab /etc/fstab /etc/fstab $ awk '{print FNR, FILENAME, $0}' /etc/fstab /etc/networks 1 /etc/fstab UUID = 5ffa8dbd-473e-4308-804a-0033c3b5f7af / btrfs defaults 0 0 2 /etc/fstab UUID = 5ffa8dbd-473e-4308-804a-0033c3b5f7af /var btrfs subvol = /@/var 0 0 3 /etc/fstab UUID = 5ffa8dbd-473e-4308-804a-0033c3b5f7af /usr/local btrfs subvol = /@/usr/local 0 0 4 /etc/fstab UUID = 5ffa8dbd-473e-4308-804a-0033c3b5f7af /tmp btrfs subvol = /@/tmp 0 0 5 /etc/fstab UUID = 5ffa8dbd-473e-4308-804a-0033c3b5f7af /srv btrfs subvol = /@/srv 0 0 6 /etc/fstab UUID = 5ffa8dbd-473e-4308-804a-0033c3b5f7af /root btrfs subvol = /@/root 0 0 7 /etc/fstab UUID = 5ffa8dbd-473e-4308-804a-0033c3b5f7af /opt btrfs subvol = /@/opt 0 0 8 /etc/fstab UUID = 5ffa8dbd-473e-4308-804a-0033c3b5f7af /home btrfs subvol = /@/home 0 0 9 /etc/fstab UUID = 5ffa8dbd-473e-4308-804a-0033c3b5f7af /boot/grub2/x86_64-efi btrfs subvol = /@/boot/grub2/x86_64-efi 0 0 10 /etc/fstab UUID = 5ffa8dbd-473e-4308-804a-0033c3b5f7af /boot/grub2/i386-pc btrfs subvol = /@/boot/grub2/i386-pc 0 0 11 /etc/fstab UUID = 5ffa8dbd-473e-4308-804a-0033c3b5f7af /.snapshots btrfs subvol = /@/.snapshots 0 0 12 /etc/fstab UUID = 47c36ad7-f49f-4ecd-9b72-4801c5bb3a04 swap swap defaults 0 0 1 /etc/networks # 2 /etc/networks # networks This file describes a number of netname-to-address 3 /etc/networks # mappings for the TCP/IP subsystem. It is mostly 4 /etc/networks # used at boot time, when no name servers are running. 5 /etc/networks # 6 /etc/networks 7 /etc/networks loopback 127 .0.0.0 8 /etc/networks link-local 169 .254.0.0 9 /etc/networks 10 /etc/networks # End. ARGC \u7684\u7528\u6cd5\uff1a \u6bcf\u4e2a\u53d8\u91cf\u7684\u540d\u5b57\u901a\u8fc7 ARGV \u83b7\u53d6\u3002 $ awk '{print ARGC}' /etc/fstab /etc/issue 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 $ awk 'BEGIN{print ARGC}' /etc/fstab /etc/issue 3 ARGV \u7684\u7528\u6cd5\uff1a $ awk 'BEGIN{print ARGV[0]}' /etc/fstab /etc/issue awk $ awk 'BEGIN{print ARGV[1]}' /etc/fstab /etc/issue /etc/fstab $ awk 'BEGIN{print ARGV[2]}' /etc/fstab /etc/issue /etc/issue $ awk 'BEGIN{print ARGV[3]}' /etc/fstab /etc/issue 5.10.8.2.\u81ea\u5b9a\u4e49\u53d8\u91cf \u00b6 \u81ea\u5b9a\u4e49\u53d8\u91cf\u662f\u533a\u5206\u5b57\u7b26\u5927\u5c0f\u5199\u7684\uff0c\u4f7f\u7528\u4e0b\u9762\u7684\u65b9\u5f0f\u8fdb\u884c\u8d4b\u503c\u3002 -v var=value \u5728program\u4e2d\u76f4\u63a5\u5b9a\u4e49 \u4e3e\u4f8b\uff1a $ awk -v t1 = t2 = \"hello awk\" 'BEGIN{print t1, t2}' t2 = hello awk $ awk -v t1 = t2 = \"hello awk\" 'BEGIN{t1=t2=\"gawk\"; print t1, t2}' gawk gawk $ awk 'BEGIN{t1=t2=\"hello awk\"; print t1, t2}' hello awk hello awk $ awk -v t1 = \"hello awk\" '{print t1}' /etc/issue hello awk hello awk hello awk hello awk hello awk $ awk -v t1 = \"hello awk\" 'BEGIN{print t1}' /etc/issue hello awk $ awk -v t1 = \"hello awk\" 'BEGIN{print t1}' hello awk $ awk -F: '{sex=\"male\"; print $1, sex, age; age=28}' /etc/passwd | head -n3 root male messagebus male 28 systemd-network male 28 $ cat < awkscript {print script,$1,$2} EOF $ awk -F: -f awkscript script = \"awk\" /etc/passwd | head -n2 awk root x awk messagebus x \u52a8\u4f5c printf \u3002 \u52a8\u4f5cprintf\u53ef\u4ee5\u5b9e\u73b0\u683c\u5f0f\u5316\u8f93\u51fa\u3002 \u683c\u5f0f\uff1a printf \"FORMAT\", item1, item2, ...... \u8bf4\u660e\uff1a \u5fc5\u987b\u6307\u5b9aFORMAT \u4e0d\u4f1a\u81ea\u52a8\u6362\u884c\uff0c\u9700\u8981\u663e\u5f0f\u7ed9\u51fa\u6362\u884c\u63a7\u5236\u7b26 \\n \u3002 FORMAT\u4e2d\u9700\u8981\u5206\u522b\u4e3a\u540e\u9762\u6bcf\u4e2aitem\u6307\u5b9a\u683c\u5f0f\u7b26\u3002 \u683c\u5f0f\u7b26\uff1a\u4e0eitem\u662f\u4e00\u4e00\u5bf9\u5e94\u7684 %s \uff1a\u663e\u793a\u5b57\u7b26\u4e32 %d , %i \uff1a\u663e\u793a\u5341\u8fdb\u5236\u6574\u6570 %f \uff1a\u663e\u793a\u4e3a\u6d6e\u70b9\u6570 %e , %E \uff1a\u663e\u793a\u79d1\u5b66\u8ba1\u6570\u6cd5\u6570\u503c %c \uff1a\u663e\u793a\u5b57\u7b26\u7684ASCII\u7801 %g , %G \uff1a\u4ee5\u79d1\u5b66\u8ba1\u6570\u6cd5\u6216\u6d6e\u70b9\u5f62\u5f0f\u663e\u793a\u6570\u503c %u \uff1a\u65e0\u7b26\u53f7\u6574\u6570 %% \uff1a\u663e\u793a % \u81ea\u8eab \u4fee\u9970\u7b26\uff1a #[.#] \uff1a\u7b2c\u4e00\u4e2a\u6570\u5b57\u63a7\u5236\u663e\u793a\u7684\u5bbd\u5ea6\uff0c\u7b2c\u4e8c\u4e2a#\u8868\u793a\u5c0f\u6570\u70b9\u540e\u7cbe\u5ea6\uff0c\u5982 %3.1f - \uff1a\u5de6\u5bf9\u9f50\uff08\u9ed8\u8ba4\u53f3\u5bf9\u9f50\uff09\uff0c\u5982 %-15s + \uff1a\u663e\u793a\u6570\u503c\u7684\u6b63\u8d1f\u7b26\u53f7\uff0c\u5982 %+d \u793a\u4f8b\uff1a $ awk -F: '{printf \"%s\", $1}' /etc/passwd | head -n3 rootmessagebussystemd-networksystemd-timesyncnobodymailchronypostfixmanlpgamesftpdaemonrpcnscdpolkitdattftpftpsecurebinstatdsshdvagrantpesignsvntester1tester2tester3tester4tester5user0user1user2user3user4user5user6user7user8user9gentoonginxvarnishmysqlwebuseradmin3smithpm1tm1tm2 $ awk -F: '{printf \"%s\\n\", $1}' /etc/passwd | head -n3 root messagebus systemd-network $ awk -F: '{printf \"%20s\\n\", $1}' /etc/passwd | head -n3 root messagebus systemd-network $ awk -F: '{printf \"%-20s\\n\", $1}' /etc/passwd | head -n3 root messagebus systemd-network $ awk -F: '{printf \"%-20s %10d\\n\", $1, $3}' /etc/passwd | head -n3 root 0 messagebus 499 systemd-network 497 $ awk -F: '{printf \"Username: %s\\n\", $1}' /etc/passwd | head -n3 Username: root Username: messagebus Username: systemd-network $ awk -F: '{printf \"Username: %s UID:%d\\n\", $1, $3}' /etc/passwd | head -n3 Username: root UID:0 Username: messagebus UID:499 Username: systemd-network UID:497 $ awk -F: '{printf \"Username: %25s UID:%d\\n\", $1, $3}' /etc/passwd | head -n3 Username: root UID:0 Username: messagebus UID:499 Username: systemd-network UID:497 $ awk -F: '{printf \"Username: %-25s UID:%d\\n\", $1, $3}' /etc/passwd | head -n3 Username: root UID:0 Username: messagebus UID:499 Username: systemd-network UID:497 5.10.9.BEGIN/END \u00b6 \u793a\u4f8b\uff1a awk -F \":\" 'BEGIN{printf \"--------------------------------\\n%-20s|%10s|\\n--------------------------------\\n\", \"Username\", \"UID\"}{printf \"%-20s|%-10d|\\n--------------------------------\\n\", $1, $3}END{print \"end\"}' /etc/passwd -------------------------------- Username | UID | -------------------------------- root | 0 | -------------------------------- daemon | 1 | -------------------------------- bin | 2 | ------------------------------- ... ... -------------------------------- mfe | 997 | -------------------------------- end 5.10.10.\u5e38\u7528\u63a7\u5236\u8bed\u53e5 \u00b6 {statements;...} \u7ec4\u5408\u8bed\u53e5 if(condition){statements;...} if(condition){statements;...} else(statements;...) switch(expression){case VALUE1 or /REGEXP/: statement1; case VALUE2 or /REGEXP2/: statement2;......;default: statementn} while(condition){statements;...} do(statements;...) while{condition} for(expr1;expr2;expr3) {statements;...} break continue exit if-else\u793a\u4f8b\uff1a $ cat < score.txt Name Score Tom 100 Jack 91 Bill 81 Jim 51 EOF $ awk 'NR!=1{score=$2;if($2>=80){print $1, \"Good\"}else if($2>=60){print $1, \"Pass\"}else{print $1, \"failed\"}}' score.txt Tom Good Jack Good Bill Good Jim failed switch\u793a\u4f8b\uff1a $ awk 'NR!=1{switch($2){case 100:print $1,\"good\"; case 60:print $1,\"Pass\"; default:print $1,\"others\"}}' score.txt Tom good Tom Pass Tom others Jack others Bill others Jim others while\u793a\u4f8b\uff1a $ awk 'BEGIN{i=0;sum=0;while(i<=100){sum+=i;i++};print sum}' 5050 do-while\u793a\u4f8b\uff1a $ awk 'BEGIN{i=0;sum=0;do{sum+=i;i++}while(i<101);print sum}' 5050 for\u793a\u4f8b\uff1a $ awk 'BEGIN{i=0;sum=0;for(i=1;i<=100;i++){sum+=i};print sum}' 5050 \u547d\u4ee4\u6548\u7387\u6bd4\u8f83\uff1a $ time ( awk 'BEGIN{i=0;sum=0;while(i<=100000){sum+=i;i++};print sum}' ) 5000050000 real 0m0.028s user 0m0.027s sys 0m0.001s $ time ( seq -s+ 1000000 | bc ) 500000500000 real 0m0.329s user 0m0.240s sys 0m0.094s $ time ( awk 'BEGIN{i=0;sum=0;for(i=1;i<=1000000;i++){sum+=i};print sum}' ) 500000500000 real 0m0.050s user 0m0.046s sys 0m0.004s contine\u793a\u4f8b\uff1a\u4e2d\u65ad\u5f53\u524d\u5faa\u73af\uff0c\u8fdb\u5165\u4e0b\u4e00\u6b21\u5faa\u73af\u3002 $ awk 'BEGIN{i=0;sum=0;for(i=1;i<=100;i++){if(i==50)continue;sum+=i};print sum}' 5000 contine\u793a\u4f8b\uff1a\u4e2d\u65ad\u6574\u4e2a\u5faa\u73af\u3002 $ awk 'BEGIN{i=0;sum=0;for(i=1;i<=100;i++){if(i==50)break;sum+=i};print sum}' 1225 next\u793a\u4f8b\uff1a\u63d0\u524d\u7ed3\u675f\u5bf9\u672c\u884c\u5904\u7406\uff0c\u76f4\u63a5\u8fdb\u5165\u4e0b\u4e00\u884c\u5904\u7406\uff08\u6ce8\uff0cawk\u81ea\u5faa\u73af\uff0c\u5e76\u975e\u524d\u9762\u7684for\u6216while\u5faa\u73af\uff09 $ awk -F: '{if($3%2!=0)next;print $1,$3}' /etc/passwd # \u5947\u6570\u884c\u6253\u5370 root 0 systemd-timesync 496 nobody 65534 chrony 494 games 492 daemon 2 rpc 490 polkitd 488 ftpsecure 486 sshd 484 vagrant 1000 svn 482 tester1 600 tester4 1002 user0 1004 user2 1006 user4 1008 user6 1010 user8 1012 gentoo 1014 varnish 1016 webuser 666 admin3 1020 smith 2002 tm1 2004 $ awk -F: '{if($3%2==0)next;print $1,$3}' /etc/passwd # \u5076\u6570\u884c\u6253\u5370 messagebus 499 systemd-network 497 mail 495 postfix 51 man 13 lp 493 ftp 491 nscd 489 at 25 tftp 487 bin 1 statd 485 pesign 483 tester2 601 tester3 1001 tester5 1003 user1 1005 user3 1007 user5 1009 user7 1011 user9 1013 nginx 1015 mysql 1017 pm1 2003 tm2 2005 5.10.11.\u6570\u7ec4 \u00b6 \u5173\u8054\u6570\u7ec4\u662f\u4e00\u79cd\u6570\u636e\u7ed3\u6784\uff0c\u4e5f\u79f0\u4e3a\u5b57\u5178\u6216\u6620\u5c04\u3002\u4e0e\u4f20\u7edf\u7684\u6570\u7ec4\u4e0d\u540c\uff0c\u5173\u8054\u6570\u7ec4\u7684\u7d22\u5f15\u53ef\u4ee5\u662f\u4efb\u4f55\u7c7b\u578b\u7684\u6570\u636e\uff0c\u4f8b\u5982\u5b57\u7b26\u4e32\u6216\u5bf9\u8c61\uff0c\u800c\u4e0d\u4ec5\u4ec5\u662f\u6574\u6570\u3002 \u63d0\u793a\uff1a \u5728\u8ba1\u7b97\u673a\u7f16\u7a0b\u4e2d\uff0c\u9664\u4e86\u5173\u8054\u6570\u7ec4\uff0c\u8fd8\u6709\u5176\u4ed6\u51e0\u79cd\u5e38\u89c1\u7684\u6570\u7ec4\u7c7b\u578b\uff0c\u5305\u62ec\uff1a \u7ebf\u6027\u6570\u7ec4\uff08\u6216\u79f0\u4e3a\u7d22\u5f15\u6570\u7ec4\uff09\uff1a\u8fd9\u662f\u6700\u5e38\u89c1\u7684\u6570\u7ec4\u7c7b\u578b\uff0c\u5176\u4e2d\u6bcf\u4e2a\u5143\u7d20\u90fd\u6709\u4e00\u4e2a\u6570\u5b57\u7d22\u5f15\uff0c\u53ef\u4ee5\u7528\u6765\u5feb\u901f\u8bbf\u95ee\u6570\u7ec4\u4e2d\u7684\u5143\u7d20\u3002\u4f8b\u5982\uff0c\u5728C\u8bed\u8a00\u4e2d\uff0c\u6570\u7ec4\u7684\u6bcf\u4e2a\u5143\u7d20\u90fd\u53ef\u4ee5\u901a\u8fc7\u6570\u7ec4\u4e0b\u6807\u6765\u8bbf\u95ee\u3002 \u591a\u7ef4\u6570\u7ec4\uff1a\u591a\u7ef4\u6570\u7ec4\u662f\u4e00\u79cd\u6570\u7ec4\uff0c\u5176\u4e2d\u6bcf\u4e2a\u5143\u7d20\u4e5f\u662f\u4e00\u4e2a\u6570\u7ec4\u3002\u5728\u4e8c\u7ef4\u6570\u7ec4\u4e2d\uff0c\u6bcf\u4e2a\u5143\u7d20\u90fd\u6709\u4e24\u4e2a\u7d22\u5f15\uff08\u4f8b\u5982\uff0c\u884c\u548c\u5217\uff09\uff0c\u53ef\u4ee5\u7528\u4e8e\u8bbf\u95ee\u6570\u7ec4\u4e2d\u7684\u5143\u7d20\u3002\u5728\u9ad8\u7ef4\u6570\u7ec4\u4e2d\uff0c\u6bcf\u4e2a\u5143\u7d20\u90fd\u5177\u6709\u66f4\u591a\u7684\u7d22\u5f15\u3002 \u52a8\u6001\u6570\u7ec4\uff1a\u52a8\u6001\u6570\u7ec4\u662f\u4e00\u79cd\u53ef\u4ee5\u52a8\u6001\u8c03\u6574\u5927\u5c0f\u7684\u6570\u7ec4\u3002\u5728\u8bb8\u591a\u7f16\u7a0b\u8bed\u8a00\u4e2d\uff0c\u52a8\u6001\u6570\u7ec4\u53ef\u4ee5\u52a8\u6001\u5206\u914d\u5185\u5b58\uff0c\u4ee5\u4fbf\u5728\u7a0b\u5e8f\u8fd0\u884c\u65f6\u6839\u636e\u9700\u8981\u8c03\u6574\u6570\u7ec4\u7684\u5927\u5c0f\u3002 \u5411\u91cf\uff1a\u5411\u91cf\u662f\u4e00\u79cd\u6570\u7ec4\uff0c\u5176\u4e2d\u6bcf\u4e2a\u5143\u7d20\u90fd\u662f\u76f8\u540c\u7684\u6570\u636e\u7c7b\u578b\u3002\u5411\u91cf\u901a\u5e38\u7528\u4e8e\u6267\u884c\u6570\u5b66\u8fd0\u7b97\u6216\u5904\u7406\u5927\u91cf\u6570\u5b57\u6570\u636e\u3002 \u5728 awk \u4e2d\u4f7f\u7528\u6570\u7ec4\u65f6\uff0c\u901a\u5e38\u4f1a\u5c06\u67d0\u4e9b\u503c\u4e0e\u4e00\u4e2a\u5b57\u7b26\u4e32\u76f8\u5173\u8054\uff0c\u4ee5\u4fbf\u5728\u9700\u8981\u65f6\u53ef\u4ee5\u901a\u8fc7\u8be5\u5b57\u7b26\u4e32\u5feb\u901f\u5730\u68c0\u7d22\u8be5\u503c\u3002 awk \u7684\u6570\u7ec4\u662f\u4e00\u4e2a\u5173\u8054\u6570\u7ec4\uff0c\u5176\u4e2d\u6bcf\u4e2a\u5143\u7d20\u90fd\u7531\u4e00\u4e2a\u552f\u4e00\u7684\u952e\u503c\u548c\u4e00\u4e2a\u5bf9\u5e94\u7684\u503c\u7ec4\u6210\u3002\u952e\u503c\uff08\u6216\u79f0\u4e3a\u7d22\u5f15\uff09\u53ef\u4ee5\u662f\u4efb\u4f55\u7c7b\u578b\u7684\u5b57\u7b26\u4e32\u3002 \u6570\u7ec4\u53ef\u4ee5\u901a\u8fc7\u4ee5\u4e0b\u8bed\u6cd5\u8fdb\u884c\u58f0\u660e\uff1a array_name [ index ] = value \u5176\u4e2d\uff0c array_name \u662f\u6570\u7ec4\u7684\u540d\u79f0\uff0c index \u662f\u5143\u7d20\u7684\u7d22\u5f15\u503c\uff0c value \u662f\u5143\u7d20\u7684\u503c\u3002 \u4f8b\u5982\uff0c\u4ee5\u4e0b\u662f\u4e00\u4e2a\u5305\u542b\u4e09\u4e2a\u5143\u7d20\u7684\u5173\u8054\u6570\u7ec4\u7684\u793a\u4f8b\uff1a array [ \"apple\" ] = 1 array [ \"banana\" ] = 2 array [ \"orange\" ] = 3 \u5728\u4e0a\u9762\u7684\u793a\u4f8b\u4e2d\uff0c array \u662f\u4e00\u4e2a\u5173\u8054\u6570\u7ec4\uff0c\u5176\u7d22\u5f15\u4e3a\u5b57\u7b26\u4e32\u7c7b\u578b\uff0c\u800c\u503c\u4e3a\u6574\u6570\u7c7b\u578b\u3002\u53ef\u4ee5\u4f7f\u7528\u4ee5\u4e0b\u7684\u65b9\u5f0f\u8bbf\u95ee\u8be5\u6570\u7ec4\u4e2d\u7684\u5143\u7d20\uff1a value = array [ \"apple\" ] \u5728\u4e0a\u9762\u7684\u793a\u4f8b\u4e2d\uff0c value \u7684\u503c\u5c06\u4e3a 1 \uff0c\u56e0\u4e3a array[\"apple\"] \u7684\u503c\u4e3a 1 \u3002 \u4ee5\u4e0b\u662f\u7528 awk \u547d\u4ee4\u6765\u521b\u5efa\u4e0a\u9762\u90a3\u4e2a\u5305\u542b\u4e09\u4e2a\u5143\u7d20\u7684\u5173\u8054\u6570\u7ec4\uff0c\u904d\u5386\u5e76\u8f93\u51fa\u6570\u7ec4\u503c\uff1a awk 'BEGIN { array[\"apple\"]=1; array[\"banana\"]=2; array[\"orange\"]=3; for(i in array){print array[i]}}' 3 1 2 \u4e0b\u9762\u4f8b\u5b50\u4e2d\uff0c\u6211\u4eec\u4e92\u6362\u4e86\u6570\u7ec4\u7684\u952e\u548c\u503c\u3002 $ awk 'BEGIN {arr[1]=\"apple\";arr[2]=\"banana\";arr[3]=\"orange\";for(i in arr){print arr[i]}}' apple banana orange \u5728\u4e0a\u9762\u7684\u793a\u4f8b\u4e2d\uff0c i \u662f\u6570\u7ec4 arr \u7684\u7d22\u5f15\u503c\uff0c arr[i] \u662f\u6570\u7ec4\u4e2d\u5bf9\u5e94\u7684\u5143\u7d20\u503c\u3002\u901a\u8fc7\u8fd9\u79cd\u65b9\u5f0f\u53ef\u4ee5\u5faa\u73af\u904d\u5386\u6574\u4e2a\u6570\u7ec4\uff0c\u5e76\u8f93\u51fa\u5176\u4e2d\u7684\u5143\u7d20\u3002 \u9664\u4e86\u4f7f\u7528\u5faa\u73af\u904d\u5386\u6570\u7ec4\u4e4b\u5916\uff0c\u8fd8\u53ef\u4ee5\u4f7f\u7528 length \u51fd\u6570\u83b7\u53d6\u6570\u7ec4\u4e2d\u5143\u7d20\u7684\u6570\u91cf\u3002\u4f8b\u5982\uff1a $ awk 'BEGIN { arr[1]=\"apple\"; arr[2]=\"banana\"; arr[3]=\"orange\"; print length(arr) }' 3 \u4e0a\u9762\u7684\u793a\u4f8b\u5c06\u8f93\u51fa\u6570\u5b573\uff0c\u8868\u793a\u6570\u7ec4 arr \u4e2d\u5305\u542b\u4e09\u4e2a\u5143\u7d20\u3002 \u4e3e\u4f8b\uff1a\u53bb\u91cd\u590d\u8bb0\u5f55\u3002 line \u662f\u6570\u7ec4\u540d\uff0c $0 \u662f awk \u8bfb\u53d6\u7684\u5f53\u524d\u884c\u7684\u5185\u5bb9\u3002 line[$0] \u7b49\u4ef7\u4e8e line[\"a\"] \uff0c line[\"b\"] \uff0c......\u3002 \u6211\u4eec\u770b\u6267\u884c\u8fc7\u7a0b\uff1a awk\u8bfb\u5165\u7b2c1\u884c\uff1b \u6267\u884c line[\"a\"] \uff0c\u503c\u4e3a\u7a7a\uff1b \u6c42\u53cd\uff0c\u5219\u7b2c\u4e00\u884c\u7684\u503c\u53d8\u4e3a true \uff0c\u5373 !line[\"a\"]=true \uff1b \u5f53 !line[\"a\"] \u4e3a true \uff0c\u5219\u6253\u5370\u5f53\u524d\u884c\uff0c\u5373\u8f93\u51fa a \u5230\u5c4f\u5e55\uff1b \u6267\u884c line[\"a\"]++ \uff0c\u6ce8\u610f\u7b2c2\u6b65\u4e2d line[\"a\"] \u7684\u503c\u662f\u7a7a\uff0c\u6267\u884c ++ \u540e\u503c\u53d8\u4e3a 1 \u3002 \u540c\u7406\uff0c\u6211\u4eec\u53ef\u4ee5\u770b\u5230\u7b2c2\uff0c3\uff0c4\u884c\u90fd\u8f93\u51fa\u4e86\u3002 \u5f53\u8bfb\u5165\u7b2c5\u884c\u65f6\uff08\u7b2c\u4e8c\u4e2a a \uff09\uff0c\u6267\u884c line[\"a\"] \uff0c\u503c\u4e3a 1 \uff1b !line[\"a\"]=0 \uff0c\u5373false\uff1b\u5219\u4e0d\u6253\u5370\u5f53\u524d\u884c\uff0c\u5373\u4e0d\u8f93\u51fa a \u5230\u5c4f\u5e55\uff1b\u6267\u884c ++ \u540e\u503c\u53d8\u4e3a 2 \u5f53\u8bfb\u5165\u7b2c8\u884c\u65f6\uff08\u7b2c\u4e09\u4e2a a \uff09\uff0c\u6267\u884c line[\"a\"] \uff0c\u503c\u4e3a 2 \uff1b !line[\"a\"]=0 \uff0c\u5373false\uff1b\u5219\u4e0d\u6253\u5370\u5f53\u524d\u884c\uff0c\u5373\u4e0d\u8f93\u51fa a \u5230\u5c4f\u5e55\uff1b\u6267\u884c ++ \u540e\u503c\u53d8\u4e3a 3 \u4ee5\u6b64\u7c7b\u63a8\uff0c\u8bfb\u5165\u7b2c\u4e8c\u4e2a b \uff0c c \uff0c d \uff0c e \uff0c\u90fd\u4e0d\u4f1a\u518d\u8f93\u51fa\u5230\u5c4f\u5e55\uff0c\u4ece\u800c\u5b9e\u73b0\u53bb\u91cd\u8f93\u51fa\u5230\u529f\u80fd\u3002 $ cat > test << EOF a b c d a c d a b b e EOF $ awk '!line[$0]++' test a b c d e \u4e3e\u4f8b\uff1a\u5224\u65ad\u6570\u7ec4\u7d22\u5f15\u662f\u5426\u5b58\u5728\u3002 \u65b9\u6cd5\uff1a in array \uff0c 0 \u8868\u793a\u4e0d\u5b58\u5728\uff0c 1 \u8868\u793a\u5b58\u5728\u3002 $ awk 'BEGIN{array[\"i\"]=\"x\";array[\"j\"]=\"j\";print \"i\" in array, \"y\" in array}' 1 0 $ awk 'BEGIN{array[\"i\"]=\"x\";array[\"j\"]=\"j\";if(\"i\" in array){print \"exits!\"}else{print \"not exists!\"}}' exits! $ awk 'BEGIN{array[\"i\"]=\"x\";array[\"j\"]=\"j\";if(\"abc\" in array){print \"exits!\"}else{print \"not exists!\"}}' not exists! \u4e3e\u4f8b\uff1a\u904d\u5386\u6570\u7ec4\u4e2d\u6bcf\u4e2a\u5143\u7d20\u3002 \u65b9\u6cd5\uff1a for(your_var in array){your_for_body} \uff0c\u6ce8\u610f\uff0cyour_var\u4f1a\u904d\u5386\u6bcf\u4e2a\u7d22\u5f15\u3002 $ awk 'BEGIN{weekday[\"mon\"]=\"Monday\";weekday[\"tue\"]=\"Tuesday\";for(i in weekday){print i,weekday[i]}}' tue Tuesday mon Monday $ awk 'BEGIN{weekday[\"mon\"]=\"Monday\";weekday[\"tue\"]=\"Tuesday\";for(i in weekday){print i\": \"weekday[i]}}' tue: Tuesday mon: Monday \u6ce8\u610f\u4e0b\u9762\u7684\u6362\u884c\u5199\u6cd5\uff0c\u4e0d\u9700\u8981\u53cd\u659c\u6760 \\ \u3002 $ awk 'BEGIN{ arr[\"x\"]=\"welcome\" arr[\"y\"]=\"to\" arr[\"z\"]=\"Shanghai\" for (i in arr) { print i, arr[i] } }' x welcome y to z Shanghai \u793a\u4f8b\uff1a\u683c\u5f0f\u5316\u8f93\u51fa\u7528\u6237\u540d\u548c\u5bc6\u7801\u3002 $ awk -F: '{user[$1]=$3}END{for (i in user){print \"Username: \" i, \"UID: \" user[i]}}' /etc/passwd Username: sshd UID: 476 Username: rpc UID: 482 Username: tftp UID: 488 Username: usbmux UID: 480 Username: srvGeoClue UID: 487 ...... \u793a\u4f8b\uff1a\u663e\u793a\u4e3b\u673a\u8fde\u63a5\u72b6\u6001\u51fa\u73b0\u7684\u6b21\u6570\u3002 # \u4f20\u7edf\u65b9\u6cd5 $ ss -ant | awk 'NR>=2{print $1}' | sort | uniq -c $ ss -ant | awk 'NR!=1{print $1}' | sort | uniq -c 1 ESTAB 6 LISTEN # \u4f7f\u7528awk\u6570\u7ec4 $ ss -ant | awk 'NR>=2{state[$1]++}END{for(i in state){print state[i], i}}' $ ss -ant | awk 'NR!=1{state[$1]++}END{for(i in state){print state[i], i}}' 6 LISTEN 1 ESTAB 5.10.12.awk\u51fd\u6570 \u00b6 \u53c2\u8003\uff1a awk \u51fd\u6570\u5b98\u7f51 5.10.12.1.\u5185\u7f6e\u51fd\u6570 \u00b6 \u5728 awk \u4e2d\uff0c\u51fd\u6570\u662f\u4e00\u79cd\u7528\u4e8e\u6267\u884c\u7279\u5b9a\u4efb\u52a1\u6216\u8ba1\u7b97\u7279\u5b9a\u503c\u7684\u53ef\u91cd\u7528\u4ee3\u7801\u5757\u3002 awk \u63d0\u4f9b\u4e86\u8bb8\u591a\u5185\u7f6e\u51fd\u6570\uff0c\u53ef\u4ee5\u7528\u4e8e\u5904\u7406\u6587\u672c\u6570\u636e\u3001\u6267\u884c\u6570\u5b66\u8fd0\u7b97\u3001\u64cd\u4f5c\u5b57\u7b26\u4e32\u7b49\u3002 \u4ee5\u4e0b\u662f\u4e00\u4e9b\u5e38\u7528\u7684awk\u51fd\u6570\u793a\u4f8b\uff1a length(string) \uff1a\u8fd4\u56de\u5b57\u7b26\u4e32\u7684\u957f\u5ea6\u3002 $ awk 'BEGIN { str = \"Hello World\"; len = length(str); print len }' 11 $ cut -d: -f1 /etc/passwd | awk '{print length($1)}' | head -3 4 10 15 substr(string, start, length) \uff1a\u4ece\u6307\u5b9a\u4f4d\u7f6e\u5f00\u59cb\u63d0\u53d6\u5b57\u7b26\u4e32\u7684\u5b50\u4e32\u3002 $ awk 'BEGIN { str = \"Hello World\"; substring = substr(str, 7, 5); print substring }' World sub(regexp, replacement [, target]) \uff1a\u4ece\u5b57\u7b26\u4e32target\u4e2d\u641c\u7d22\u5339\u914dregexp\u7684\u5185\u5bb9\uff0c\u5e76\u628a\u7b2c\u4e00\u4e2a\u5339\u914d\u7684\u5185\u5bb9\u66ff\u6362\u4e3areplacement\u3002\u61d2\u60f0\u6a21\u5f0f\u3002 \u6ce8\u610f\uff1a sub() \u51fd\u6570\u5728\u539f\u59cb\u5b57\u7b26\u4e32\u4e0a\u8fdb\u884c\u66ff\u6362\u64cd\u4f5c\uff0c\u5e76\u8fd4\u56de\u66ff\u6362\u7684\u6b21\u6570\u3002 # \u5728\u539f\u59cb\u5b57\u7b26\u4e32\u4e2d\uff0c\u7b2c\u4e00\u4e2a\u5339\u914d\u5230\u7684\"at\"\u88ab\u66ff\u6362\u4e3a\"ith\"\uff0c\u56e0\u6b64\u8f93\u51fa\u7ed3\u679c\u4e2d\u7684\"at\"\u53d8\u4e3a\"ith\"\uff0c\u5176\u4ed6\u5730\u65b9\u7684\"at\"\u4fdd\u6301\u4e0d\u53d8 $ awk 'BEGIN { str = \"water, water, everywhere\"; sub(/at/, \"ith\", str); print str }' wither, water, everywhere # \u8fd4\u56de\u5339\u914d\u6b21\u6570 $ awk 'BEGIN { str = \"water, water, everywhere\"; str_new = sub(/at/, \"ith\", str); print str_new }' 1 $ echo \"2023:15:35 08:15:26\" | awk 'sub(/:/, \"-\", $0)' 2023 -15:35 08 :15:26 $ echo \"2023:15:35 08:15:26\" | awk 'sub(/:/, \"-\", $1)' 2023 -15:35 08 :15:26 $ echo \"2023:15:35 08:15:26\" | awk 'sub(/:/, \"-\", $2)' 2023 :15:35 08 -15:26 gsub(regexp, replacement [, target])\uff1a\u4ece\u5b57\u7b26\u4e32target\u4e2d\u641c\u7d22\u5339\u914dregexp\u7684\u5185\u5bb9\uff0c\u5e76\u628a\u5168\u90e8\u5339\u914d\u7684\u5185\u5bb9\u66ff\u6362\u4e3areplacement\u3002\u8d2a\u5a6a\u6a21\u5f0f\u3002 # \u5728\u539f\u59cb\u5b57\u7b26\u4e32\u4e2d\uff0c\u5c06\u6240\u6709\u5339\u914d\u5230\u7684\"at\"\u88ab\u66ff\u6362\u4e3a\"ith\" $ awk 'BEGIN { str = \"water, water, everywhere\"; gsub(/at/, \"ith\", str); print str }' wither, wither, everywhere # \u8fd4\u56de\u5339\u914d\u6b21\u6570 $ awk 'BEGIN { str = \"water, water, everywhere\"; str_new = gsub(/at/, \"ith\", str); print str_new }' 2 $ echo \"2023:15:35 08:15:26\" | awk 'gsub(/:/, \"-\", $0)' 2023 -15-35 08 -15-26 $ echo \"2023:15:35 08:15:26\" | awk 'gsub(/:/, \"-\", $1)' 2023 -15-35 08 :15:26 $ echo \"2023:15:35 08:15:26\" | awk 'gsub(/:/, \"-\", $2)' 2023 :15:35 08 -15-26 split(string, array, delimiter) \uff1a\u5c06\u5b57\u7b26\u4e32string\u6309\u6307\u5b9a\u5206\u9694\u7b26delimiter\u62c6\u5206\u6210\u6570\u7ec4array\u7684\u5143\u7d20\u3002 \u6ce8\u610f\uff1a\u7b2c\u4e00\u4e2a\u7d22\u5f15\u503c\u4e3a 1 \uff0c\u7b2c\u4e8c\u4e2a\u7d22\u5f15\u503c\u4e3a 2 . $ awk 'BEGIN { str = \"apple,banana,orange\"; split(str, fruits, \",\"); print fruits[2] }' banana $ head -n2 /etc/passwd | awk '{split($0, array, \":\")}END{print array[1]}' messagebus $ head -n2 /etc/passwd | awk '{split($0, array, \":\")}END{print array[2]}' x $ head -n2 /etc/passwd | awk '{split($0, array, \":\")}END{print array[3]}' 499 $ head -n2 /etc/passwd | awk '{split($0, array, \":\")}END{print array[7]}' /usr/bin/false index(string, search) \uff1a\u5728\u5b57\u7b26\u4e32\u4e2d\u67e5\u627e\u6307\u5b9a\u5b50\u4e32\u7684\u4f4d\u7f6e\u3002 $ awk 'BEGIN { str = \"Hello World\"; pos = index(str, \"World\"); print pos }' 7 sprintf(format, expression) \uff1a\u6839\u636e\u6307\u5b9a\u7684\u683c\u5f0f\u5c06\u8868\u8fbe\u5f0f\u8f6c\u6362\u4e3a\u5b57\u7b26\u4e32\u3002 $ awk 'BEGIN { num = 3.14159; str = sprintf(\"%.2f\", num); print str }' 3 .14 rand() \uff1a\u8fd4\u56de\u4e00\u4e2a\u968f\u673a\u6570\uff0c\u503c\u5728 0 \u548c 1 \u4e4b\u95f4\u5747\u5300\u5206\u5e03\u3002\u8fd9\u4e2a\u503c\u53ef\u4ee5\u662f 0 \uff0c\u4f46\u4e0d\u4f1a\u662f 1 \u3002\u4ece\u4e0b\u9762\u7684\u4f8b\u5b50\u53ef\u4ee5\u770b\u51fa\uff0c\u8fd0\u884c\u7ed3\u679c\u90fd\u662f\u4e00\u6837\u7684\uff0c\u6240\u4ee5\u4ea7\u751f\u968f\u673a\u6570\u7684\u79cd\u5b50\u662f\u4e00\u6837\u7684\u3002 $ awk 'BEGIN{print rand()}' 0 .924046 $ awk 'BEGIN{print rand()}' 0 .924046 $ awk 'BEGIN{print rand()}' 0 .924046 srand() \uff1a\u914d\u5408 rand() \u51fd\u6570\uff0c\u751f\u6210\u968f\u673a\u6570\u79cd\u5b50\u3002 $ awk 'BEGIN{srand();print rand()}' 0 .112006 $ awk 'BEGIN{srand();print rand()}' 0 .663431 $ awk 'BEGIN{srand();print rand()}' 0 .541305 int() \uff1a\u8fd4\u56de\u6574\u6570\u3002 $ awk 'BEGIN{srand();print int(rand()*100)}' 84 $ awk 'BEGIN{srand();print int(rand()*100)}' 66 $ awk 'BEGIN{srand();print int(rand()*100)}' 8 system(command) \uff1a\u6267\u884ccommand\u547d\u4ee4\uff08\u53ef\u4ee5\u662f\u4efb\u4f55\u6709\u6548\u7684Shell\u547d\u4ee4\uff09\u5e76\u8fd4\u56de\u547d\u4ee4\u7684\u9000\u51fa\u72b6\u6001\u7801\u3002\u5141\u8bb8\u5728 awk \u811a\u672c\u4e2d\u6267\u884c\u5916\u90e8\u547d\u4ee4\uff0c\u5e76\u83b7\u53d6\u547d\u4ee4\u6267\u884c\u7684\u7ed3\u679c\u3002 # \u6267\u884cls -l\u547d\u4ee4\uff0c\u5e76\u5c06\u547d\u4ee4\u7684\u9000\u51fa\u72b6\u6001\u7801\u5b58\u50a8\u5728status\u53d8\u91cf\u4e2d\uff0c\u5e76\u6253\u5370status\u53d8\u91cf\u7684\u503c $ awk 'BEGIN { status = system(\"ls -l\"); print \"Exit status:\", status }' total 0 drwxr-xr-x 1 vagrant users 70 Jan 2 15 :54 Desktop drwxr-xr-x 1 vagrant users 0 Jan 2 15 :54 Documents drwxr-xr-x 1 vagrant users 0 Jan 2 15 :54 Downloads drwxr-xr-x 1 vagrant users 0 Jan 2 15 :54 Music drwxr-xr-x 1 vagrant users 0 Jan 2 15 :54 Pictures drwxr-xr-x 1 vagrant users 0 Jan 2 15 :54 Public drwxr-xr-x 1 vagrant users 0 Jan 2 15 :54 Templates drwxr-xr-x 1 vagrant users 0 Jan 2 15 :54 Videos drwxr-xr-x 1 vagrant users 0 Mar 15 2022 bin Exit status: 0 $ awk 'BEGIN{score=100; system(\"echo your score is \" score)}' your score is 100 systime() \uff1a\u5f53\u524d\u65f6\u95f4\u52301970\u5e741\u67081\u65e5\u5230\u79d2\u6570 $ awk 'BEGIN{print systime()}' 1684158395 strftime(format, timestamp) \uff1a\u5c06\u65f6\u95f4\u6233timestamp\u8f6c\u6362\u4e3a\u6307\u5b9a\u683c\u5f0fformat\u7684\u65e5\u671f\u548c\u65f6\u95f4\u5b57\u7b26\u4e32\u3002timestamp\u901a\u5e38\u662f\u4e00\u4e2a\u4ee5\u79d2\u4e3a\u5355\u4f4d\u8868\u793a\u7684\u6574\u6570\u3002 \u5e38\u89c1\u7684\u683c\u5f0f\u5316\u5b57\u7b26\u4e32\u9009\u9879\uff1a %Y \uff1a\u56db\u4f4d\u6570\u7684\u5e74\u4efd\uff08\u4f8b\u5982\uff1a2023\uff09 %m \uff1a\u4e24\u4f4d\u6570\u7684\u6708\u4efd\uff0801-12\uff09 %d \uff1a\u4e24\u4f4d\u6570\u7684\u65e5\u671f\uff0801-31\uff09 %H \uff1a\u4e24\u4f4d\u6570\u7684\u5c0f\u65f6\uff0800-23\uff09 %M \uff1a\u4e24\u4f4d\u6570\u7684\u5206\u949f\uff0800-59\uff09 %S \uff1a\u4e24\u4f4d\u6570\u7684\u79d2\uff0800-60\uff09 %Z \uff1a\u65f6\u533a\u540d\u79f0\uff08\u4f8b\u5982\uff1aGMT\uff09 # \u5c06\u5f53\u524d\u65f6\u95f4\u6233\u8f6c\u6362\u4e3a\u683c\u5f0f\u4e3a\"YYYY-MM-DD HH:MM:SS\"\u7684\u65e5\u671f\u548c\u65f6\u95f4\u5b57\u7b26\u4e32 $ awk 'BEGIN { timestamp = systime(); str = strftime(\"%Y-%m-%d %H:%M:%S\", timestamp); print str }' 2023 -05-15 22 :01:35 # \u5c06\u5f53\u524d\u65f6\u95f4\u6233\u7684\u524d\u4e00\u5c0f\u65f6\uff083600\u79d2\uff09\u8f6c\u6362\u4e3a\u683c\u5f0f\u4e3a\"YYYY-MM-DD HH:MM:SS\"\u7684\u65e5\u671f\u548c\u65f6\u95f4\u5b57\u7b26\u4e32 $ awk 'BEGIN { timestamp = systime()-3600; str = strftime(\"%Y-%m-%d %H:%M:%S\", timestamp); print str }' 2023 -05-15 21 :01:43 5.10.12.2.\u81ea\u5b9a\u4e49\u51fd\u6570 \u00b6 \u4e3e\u4f8b\uff1a $ cat > func.awk << EOF function max(x,y){ x>y?var=x:var=y return var } BEGIN{print max(a,b)} EOF $ awk -v a = 30 -v b = 20 -f func.awk 30 \u4e3e\u4f8b\uff1a \u5728\u4e0b\u9762\u7684\u4f8b\u5b50\u4e2d\uff0c\u6211\u4eec\u5b9a\u4e49\u4e86\u4e00\u4e2a\u540d\u4e3a square() \u7684\u81ea\u5b9a\u4e49\u51fd\u6570\uff0c\u5b83\u63a5\u53d7\u4e00\u4e2a\u53c2\u6570 x \uff0c\u5e76\u8fd4\u56de x \u7684\u5e73\u65b9\u3002\u7136\u540e\uff0c\u5728\u4e3b\u4ee3\u7801\u5757\u4e2d\uff0c\u6211\u4eec\u58f0\u660e\u4e86\u4e00\u4e2a\u53d8\u91cf num \u5e76\u8d4b\u503c\u4e3a 5 \u3002\u63a5\u4e0b\u6765\uff0c\u6211\u4eec\u8c03\u7528\u4e86\u81ea\u5b9a\u4e49\u51fd\u6570 square() \uff0c\u4f20\u9012 num \u4f5c\u4e3a\u53c2\u6570\uff0c\u5e76\u5c06\u8fd4\u56de\u503c\u5b58\u50a8\u5728\u53d8\u91cf result \u4e2d\u3002\u6700\u540e\uff0c\u6211\u4eec\u6253\u5370\u51fa result \u7684\u503c\u3002 $ cat > func.awk << EOF # \u81ea\u5b9a\u4e49\u51fd\u6570\uff1a\u8ba1\u7b97\u5e73\u65b9 function square(x) { return x * x; } # \u4f7f\u7528\u81ea\u5b9a\u4e49\u51fd\u6570 { num = 5; result = square(num); print \"\u5e73\u65b9\u7ed3\u679c\uff1a\" result; } EOF $ awk -f func.awk \u5e73\u65b9\u7ed3\u679c\uff1a25 \u4e3e\u4f8b\uff1a $ cat > func.awk << EOF # \u81ea\u5b9a\u4e49\u51fd\u6570\uff1a\u8ba1\u7b97\u6570\u7ec4\u5e73\u5747\u503c function calculateAverage(arr, size) { sum = 0; for (i = 1; i <= size; i++) { sum += arr[i]; } return sum / size; } # \u4f7f\u7528\u81ea\u5b9a\u4e49\u51fd\u6570 { # \u5b9a\u4e49\u6570\u7ec4 numbers[1] = 10; numbers[2] = 20; numbers[3] = 30; numbers[4] = 40; numbers[5] = 50; # \u8ba1\u7b97\u6570\u7ec4\u7684\u5e73\u5747\u503c size = 5; average = calculateAverage(numbers, size); print \"\u6570\u7ec4\u7684\u5e73\u5747\u503c\uff1a\" average; } EOF $ awk -f func.awk \u6570\u7ec4\u7684\u5e73\u5747\u503c\uff1a30 5.10.12.3.awk\u811a\u672c \u00b6 \u4e3e\u4f8b\uff1a # \u6ce8\u610f\u8f6c\u4e49 $ cat > passwd.awk << EOF {if(\\$3>=1000)print \\$1,\\$3} EOF $ awk -F: -f passwd.awk /etc/passwd nobody 65534 vagrant 1000 \u4e0a\u9762\u4f8b\u5b50\u4e5f\u53ef\u4ee5\u5199\u6210\u5982\u4e0b\u811a\u6b65\u683c\u5f0f\u3002 $ cat > test.awk << EOF #!/bin/awk -f # This is an awk script {if(\\$3>=1000)print \\$1,\\$3} EOF $ chmod +x test.awk $ ./test.awk -F: /etc/passwd nobody 65534 vagrant 1000 \u5411awk\u811a\u672c\u4f20\u9012\u53c2\u6570\uff1a \u683c\u5f0f\uff1a awkfile var=value var2=value2 ... inputfile \u8bf4\u660e\uff1a \u4e0a\u9762\u683c\u5f0f\u53d8\u91cf\u5728 BEGIN \u8fc7\u7a0b\u4e2d\u4e0d\u53ef\u7528\uff0c\u76f4\u5230\u9996\u884c\u8f93\u5165\u5b8c\u6210\u4ee5\u540e\uff0c\u53d8\u91cf\u624d\u53ef\u7528\u3002 \u53ef\u4ee5\u901a\u8fc7 -v \u53c2\u6570\uff0c\u8ba9 awk \u5728\u6267\u884c BEGIN \u4e4b\u524d\u5f97\u5230\u53d8\u91cf\u3002 \u547d\u4ee4\u884c\u4e2d\u6bcf\u4e00\u4e2a\u6307\u5b9a\u7684\u53d8\u91cf\u90fd\u9700\u8981\u4e00\u4e2a -v \u53c2\u6570\u3002 \u4e3e\u4f8b\uff1a # x=100\u5728BEGIN{print x}\u533a\u6bb5\u53ef\u7528 $ awk -v x = 100 'BEGIN{print x}{print x+100}' /etc/hosts 100 200 200 200 200 200 200 200 200 200 200 200 200 200 200 200 200 200 200 200 200 200 200 200 # \u4e0d\u52a0-v\u5219x=100\u5728BEGIN{print x}\u533a\u6bb5\u4e0d\u53ef\u7528 $ awk x = 100 'BEGIN{print x}{print x+100}' /etc/hosts awk: fatal: cannot open file ` BEGIN { print x }{ print x+100 } ' for reading (No such file or directory) # \u4fee\u6b63\u4e0a\u9762\u7684\u9519\u8bef\uff0c\u5c06x=100\u653e\u5728\u540e\u9762\uff0c\u56e0\u4e3a\u6ca1\u6709-v\uff0c\u6240\u4ee5x=100\u5728BEGIN{print x}\u533a\u6bb5\u4e0d\u53ef\u7528\uff0c\u7b2c\u4e00\u884c\u8f93\u51fa\u7a7a\u767d $ awk ' BEGIN { print x }{ print x+100 } ' x = 100 /etc/hosts 200 200 200 200 200 200 200 200 200 200 200 200 200 200 200 200 200 200 200 200 200 200 200 5.11.\u5c0f\u7ec3\u4e60 \u00b6 \u663e\u793a /proc/meminfo \u6587\u4ef6\u4e2d\u4ee5\u5927\u5c0fs\u5f00\u5934\u7684\u884c\uff0c\u8981\u6c42\u4f7f\u7528\u4e24\u79cd\u65b9\u6cd5\u3002 cat /proc/meminfo | grep -i \"^s\" cat /proc/meminfo | grep \"^[sS]\" \u663e\u793a /etc/passwd \u6587\u4ef6\u4e2d\u4e0d\u4ee5 /bin/bash \u7ed3\u5c3e\u7684\u884c\u3002 grep -v \"/bin/bash $ \" /etc/passwd \u663e\u793a\u7528\u6237 rpc \u9ed8\u8ba4\u7684shell\u7a0b\u5e8f\u3002 $ grep \"rpc\" /etc/passwd | cut -d \":\" -f 7 /sbin/nologin \u627e\u51fa /etc/passwd \u4e2d\u7684\u4e24\u4f4d\u6216\u4e09\u4f4d\u6570\u3002 grep -Eo \"[:digit:]{2,3}\" /etc/passwd grep -Eo \"[0-9]{2,3}\" /etc/passwd \u8fd9\u91cc\u7528\u5230\u4e86 {} \uff0c\u5c5e\u4e8e\u6269\u5c55\u6b63\u5219\u7b26\u53f7\uff0c\u6240\u4ee5\u8981\u7528 -E \u3002 \u663e\u793aRocky 9\u7684 /etc/grub2.cfg \u6587\u4ef6\u4e2d\uff0c\u81f3\u5c11\u4ee5\u4e00\u4e2a\u7a7a\u767d\u5b57\u7b26\u5f00\u5934\u7684\u4e14\u540e\u9762\u6709\u975e\u7a7a\u767d\u5b57\u7b26\u7684\u884c\u3002\uff08\u6ce8\uff1a /etc/grub2.cfg \u5728openSUSE\u548cUbuntu\u4e2d\u6ca1\u6709\uff09 # \u4e0d\u542b\u9996\u5b57\u7b26\u4e3atab $ sudo grep \"^ \" /etc/grub2.cfg # \u5305\u542b\u9996\u5b57\u7b26\u4e3atab $ sudo grep \"^[[:space:]]\" /etc/grub2.cfg \u627e\u51fa netstat -tan \u547d\u4ee4\u7ed3\u679c\u4e2d\u4ee5 LISTEN \u540e\u8ddf\u4efb\u610f\u591a\u4e2a\u7a7a\u767d\u5b57\u7b26\u7ed3\u5c3e\u7684\u884c\u3002 netstat -tan | grep -E \"LISTEN[[:space:]]+\" \u663e\u793aRocky 9\u4e0a\u6240\u6709UID\u5c0f\u4e8e1000\u4ee5\u5185\u7684\u7528\u6237\u540d\u548cUID\u3002 cat /etc/passwd | cut -d \":\" -f 1 ,3 | grep -E \"\\:[0-9]{1,3} $ \" grep -E \"\\:[0-9]{1,3}\\:[0-9]{1,}\" /etc/passwd | cut -d \":\" -f 1 ,3 \u5728Rocky 9\u4e0a\u663e\u793a\u6587\u4ef6 /etc/passwd \u7528\u6237\u540d\u548cshell\u540c\u540d\u7684\u884c\u3002 $ grep -E \"^([[:alnum:]]+\\b).*\\1 $ \" /etc/passwd sync:x:5:0:sync:/sbin:/bin/sync shutdown:x:6:0:shutdown:/sbin:/sbin/shutdown halt:x:7:0:halt:/sbin:/sbin/halt \u5229\u7528 df \u548c grep \uff0c\u53d6\u51fa\u78c1\u76d8\u5404\u5206\u533a\u5229\u7528\u7387,\u5e76\u4ece\u5927\u5230\u5c0f\u6392\u5e8f\u3002 $ df | tr -s \" \" | cut -d \" \" -f 1 ,5 | sort -n -t \" \" -k 2 devtmpfs 0 % Filesystem Use% tmpfs 0 % tmpfs 0 % /dev/mapper/rl-home 1 % tmpfs 2 % /dev/mapper/rl-root 5 % /dev/nvme0n1p1 23 % \u663e\u793a\u4e09\u4e2a\u7528\u6237 root \uff0c sync \uff0c bin \u7684UID\u548c\u9ed8\u8ba4shell\u3002 $ grep \"^root:\\|^sync:\\|^bin:\" /etc/passwd | cut -d \":\" -f 1 ,7 root:/bin/bash bin:/usr/sbin/nologin \u4f7f\u7528 egrep \u53d6\u51fa /etc/default-1/text_2/local.3/grub \u4e2d\u5176\u57fa\u540d\u548c\u76ee\u5f55\u540d\u3002 # \u57fa\u540d $ echo \"/etc/default-1/text_2/local.3/grub\" | egrep -io \"[[:alpha:]]+ $ \" grub # \u76ee\u5f55\u540d $ echo \"/etc/default-1/text_2/local.3/grub\" | egrep -io \"/([[:alpha:]]+.|_?[[:alpha:]]|[[:alnum:]]+/){7}\" /etc/default-1/text_2/local.3/ \u7edf\u8ba1 last \u547d\u4ee4\u4e2d\u4ee5 vagrant \u767b\u5f55\u7684\u6bcf\u4e2a\u4e3b\u673aIP\u5730\u5740\u767b\u5f55\u6b21\u6570\u3002 $ last | grep vagrant | tr -s \" \" | cut -d \" \" -f 3 | grep -E \"([0-9]{1,3}\\.){1,3}[0-9]{1,3}\" | sort -n | uniq -c 24 192 .168.10.107 38 192 .168.10.109 17 192 .168.10.201 6 192 .168.10.210 2 192 .168.10.220 \u5229\u7528\u6269\u5c55\u6b63\u5219\u8868\u8fbe\u5f0f\u5206\u522b\u8868\u793a0-9\u300110-99\u3001100-199\u3001200-249\u3001250-255\u3002 [ 0 -9 ] | [ 0 -9 ]{ 2 } | 1 [ 0 -9 ]{ 2 } | 2 [ 0 -4 ][ 0 -9 ] | 25 [ 0 -5 ] \u663e\u793a ifconfig \u547d\u4ee4\u7ed3\u679c\u4e2d\u6240\u6709IPv4\u5730\u5740\u3002 $ ifconfig | grep -Eo \"([0-9]{1,3}\\.){3}[0-9]{1,3}\" | grep -v \"^255\" 192 .168.10.210 192 .168.10.255 127 .0.0.1 \u663e\u793a ip addr \u547d\u4ee4\u7ed3\u679c\u4e2d\u6240\u6709IPv4\u5730\u5740\u3002 $ ip addr show eth0 | grep inet | grep eth0 | tr -s \" \" | cut -d \" \" -f 3 | cut -d \"/\" -f 1 192 .168.10.210 $ ip addr show | grep -Eo \"([0-9]{1,3}\\.){3}[0-9]{1,3}\" | grep -v \"^255\" 127 .0.0.1 192 .168.10.210 192 .168.10.255 \u5c06\u6b64\u5b57\u7b26\u4e32Welcome to the linux world\u4e2d\u7684\u6bcf\u4e2a\u5b57\u7b26\u53bb\u91cd\u5e76\u6392\u5e8f\uff0c\u91cd\u590d\u6b21\u6570\u591a\u7684\u6392\u5230\u524d\u9762\u3002 $ echo \"Welcome to the linux world\" | grep -o [[ :alpha: ]] | sort | uniq -c | sort -nr 3 o 3 l 3 e 2 t 1 x 1 W 1 w 1 u 1 r 1 n 1 m 1 i 1 h 1 d 1 c \u5220\u9664 /etc/default/grub \u6587\u4ef6\u4e2d\u6240\u6709\u4ee5\u7a7a\u767d\u5f00\u5934\u7684\u884c\u884c\u9996\u7684\u7a7a\u767d\u5b57\u7b26\u3002 sed '/^$/d' /etc/default/grub \u5220\u9664 /etc/default/grub \u6587\u4ef6\u4e2d\u6240\u6709\u4ee5 # \u5f00\u5934\uff0c\u540e\u9762\u81f3\u5c11\u8ddf\u4e00\u4e2a\u7a7a\u767d\u5b57\u7b26\u7684\u884c\u7684\u884c\u9996\u7684 # \u548c\u7a7a\u767d\u5b57\u7b26\u3002 sed -r '/#[[:space:]]+/d;/#/d' /etc/default/grub \u4e0a\u9762\u8f93\u51fa\u7ed3\u679c\u4e2d\u5305\u542b\u7a7a\u767d\u884c\u3002 \u82e5\u8f93\u51fa\u4e2d\u5220\u9664\u7a7a\u767d\u884c\uff0c\u5219\uff1a sed -r '/#[[:space:]]+/d;/#/d;/^$/d' /etc/default/grub \u5728 /etc/fstab \u6bcf\u4e00\u884c\u884c\u9996\u589e\u52a0 # \u53f7\u3002 sed -r 's/(.*)/#&/' /etc/fstab \u5728 /etc/fstab \u6587\u4ef6\u4e2d\u4e0d\u4ee5 # \u5f00\u5934\u7684\u884c\u7684\u884c\u9996\u589e\u52a0 # \u53f7\uff08\u5305\u62ec\u7a7a\u884c\uff09\u3002 sed -r 's/^[^#].*/#&/' -r 's/^$/#/' /etc/default/grub \u901a\u8fc7\u547d\u4ee4 rpm -qa --last |awk -F ' ' '{print $1}' \u5f97\u5230\u6700\u65b0\u5b89\u88c5\u7684\u5305\u5217\u8868\u3002\u7edf\u8ba1\u6240\u6709 x86_64 \u7ed3\u5c3e\u7684\u5b89\u88c5\u5305\u540d\u4ee5 . \u5206\u9694\u5012\u6570\u7b2c\u4e8c\u4e2a\u5b57\u6bb5\u7684\u91cd\u590d\u6b21\u6570\u3002 $ rpm -qa --last | awk -F ' ' '{print $1}' | sed -nr '/x86_64$/s@.*\\.(.*)\\.x86_64@\\1@p' | sort -r | uniq -c 75 el9_0 563 el9 3 7 1 5 2 4 2 3 10 2 29 1 \u5728openSUSE\u4e2d\u7edf\u8ba1 /etc/rc.status \u6587\u4ef6\u4e2d\u6bcf\u4e2a\u5355\u8bcd\u7684\u51fa\u73b0\u6b21\u6570\uff0c\u5e76\u6392\u5e8f\uff08\u7528grep\u548csed\u4e24\u79cd\u65b9\u6cd5\u5206\u522b\u5b9e\u73b0\uff09\u3002 grep -Eo \"[a-zA-Z]+\" /etc/rc.status | sort | uniq -c cat /etc/rc.status | sed -r 's/[^[:alpha:]]+/\\n/g' | sed '/^$/d' | sort | uniq -c | sort -nr \u5c06\u6587\u672c\u6587\u4ef6\u7684n\u548cn+1\u884c\u5408\u5e76\u4e3a\u4e00\u884c\uff0cn\u4e3a\u5947\u6570\u884c\u3002 $ cat < sed.txt 1aa 2bb 3cc 4dd 5ee 6ff 7gg EOF $ sed -n 'N;s/\\n//p' sed.txt 1aa2bb 3cc4dd 5ee6ff $ sed 'N;s/\\n//' sed.txt 1aa2bb 3cc4dd 5ee6ff 7gg \u5bf9\u4e00\u4e32\u6570\u5b57\u8fdb\u884c\u6c42\u548c\u3002 $ cat < number.txt 1 2 3 4 5 6 EOF $ tr ' ' + < number.txt | bc 21 $ sum = 0 ; for i in ` cat number.txt ` ; do let sum += i ; done ; echo $sum 21 $ awk '{sum=0;for(i=1;i<=NF;i++){sum+=i};print sum}' number.txt 21 \u53d6\u51fa\u5b57\u7b26\u4e32\u4e2d\u7684\u6570\u5b57\u3002 $ echo 'kdajl;3k8jd33la5kj23f90ld02sakjflakjdslf' | awk -F \"\" ' { for(i=1;i<=NF;i++) { if($i ~ /[0-9]/) { str=(str $i) } }; print str }' 38335239002 host.log \u6587\u4ef6\u5185\u5bb9\u5982\u4e0b\uff0c\u63d0\u53d6 .edu.cn \u524d\u9762\u7684\u4e3b\u673a\u540d\uff0c\u5e76\u56de\u5199\u5230\u8be5\u6587\u4ef6\u4e2d\u3002 $ cat > host.log << EOF 1 www.edu.cn 2 blog.edu.cn 3 learning.edu.cn 4 java.edu.cn 5 nodejs.edu.cn 6 k8s.eud.cn 7 linux.edu.cn 8 python.edu.cn 9 learning.edu.cn 10 java.edu.cn 11 nodejs.edu.cn 12 www.edu.cn EOF # \u5bf9\u6bd4 $ awk -F '[ .]' '{print $1}' host.log 1 2 3 4 5 6 7 8 9 10 11 12 $ awk -F '[ .]' '{print $2}' host.log www blog learning java nodejs k8s linux python learning java nodejs www # \u4ee5\u7a7a\u683c\u6216\u8005.\u4e3a\u5206\u9694\u7b26\uff0c\u6253\u5370\u7b2c\u4e8c\u5217\uff08\u4e3b\u673a\u540d\uff09\uff0c\u8ffd\u52a0\u5199\u5165\u539f\u6587\u4ef6 $ awk -F '[ .]' '{print $2}' host.log >> host.log $ cat host.log 1 www.edu.cn 2 blog.edu.cn 3 learning.edu.cn 4 java.edu.cn 5 nodejs.edu.cn 6 k8s.eud.cn 7 linux.edu.cn 8 python.edu.cn 9 learning.edu.cn 10 java.edu.cn 11 nodejs.edu.cn 12 www.edu.cn www blog learning java nodejs k8s linux python learning java nodejs www \u7edf\u8ba1\u6587\u4ef6 /etc/fstab \u4e2d\u6bcf\u4e2a\u6587\u4ef6\u7cfb\u7edf\u7c7b\u578b\u51fa\u73b0\u7684\u6b21\u6570\u3002 # \u4ee5UUID\u5f00\u5934\uff0c\u4e00\u4e2a\u6216\u591a\u4e2a\u7a7a\u683c\u4e3a\u5206\u9694\u7b26\uff0c\u8bfb\u53d6\u7b2c\u4e09\u5217\uff08\u5373\u6587\u4ef6\u7cfb\u7edf\u7c7b\u578b\uff09\u5e76\u8ba1\u6570\u3002 $ awk -F ' +' '/^UUID/{fs[$3]++}END{for(i in fs){print i, fs[i]}}' /etc/fstab swap 1 btrfs 10 vfat 1 # \u65b9\u6cd52 $ awk -F ' +' '/^UUID/{print $3}' /etc/fstab | uniq -c 10 btrfs 1 swap 1 vfat \u7edf\u8ba1\u6587\u4ef6 /etc/fstab \u4e2d\u6bcf\u4e2a\u5355\u8bcd\u51fa\u73b0\u7684\u6b21\u6570\u3002 $ awk -F \"[^[:alpha:]]\" '{for(i=1;i<=NF;i++)word[$i]++}END{for(a in word)if(a!=\"\")print a,word[a]}' /etc/fstab swap 2 B 1 srv 2 btrfs 10 snapshots 2 vfat 1 opt 2 cbaef 10 UUID 12 E 1 ecf 1 CD 1 cf 1 arm 2 a 11 c 2 tmp 2 usr 2 var 2 afa 20 home 2 d 10 utf 1 e 2 efi 3 grub 2 boot 3 subvol 9 root 2 local 2 defaults 2 f 10 \u63d0\u53d6\u5b57\u7b26\u4e32 Yd$@C#M05MD9&8923+Vip3wZ!33*44&55 \u4e2d\u6240\u6709\u7684\u6570\u5b57\u3002 # \u5bf9\u6bd4\u5355\u5f15\u53f7\u548c\u53cc\u5f15\u53f7\u7684\u533a\u522b\u3002 $ echo \"Yd $@ C#M05MD9&8923+Vip3wZ!33*44&55\" echo \"Yd $@ C#M05MD9&8923+Vip3wZcgcreate -g cpu:mygroup44&55\" YdC#M05MD9 & 8923 +Vip3wZcgcreate -g cpu:mygroup44 & 55 $ echo 'Yd$@C#M05MD9&8923+Vip3wZ!33*44&55' Yd $@ C#M05MD9 & 8923 +Vip3wZ!33*44 & 55 $ echo 'Yd$@C#M05MD9&8923+Vip3wZ!33*44&55' | awk '{gsub(/[^0-9]/,\"\");print $0}' 05989233334455 $ echo 'Yd$@C#M05MD9&8923+Vip3wZ!33*44&55' | awk -F '[^0-9]' '{for(i=1;i<=NF;i++){printf \"%s\", $i}}' 05989233334455 $ echo 'Yd$@C#M05MD9&8923+Vip3wZ!33*44&55' | awk -F \"\" '{for(i=1;i<=NF;i++){if($i ~ /[[:digit:]]/){str=$i;str1=(str1 str)}};print str1}' 05989233334455 $ echo 'Yd$@C#M05MD9&8923+Vip3wZ!33*44&55' | awk -F '' '{for(i=1;i<=NF;i++){if($i ~ /[[:digit:]]/){str=$i;str1=(str1 str)}};print str1}' # \u6ce8\u610f\uff0c\u5982\u679c\u5199\u6210\u5982\u4e0b\u683c\u5f0f\uff0c\u5219\u62a5\u9519\u3002 $ echo 'Yd$@C#M05MD9&8923+Vip3wZ!33*44&55' | awk -F '' '{for(i=1;i<=NF;i++){if($i ~ /[[:digit:]]/){str=$i;str1=(str1 str)}};print str1}' # \u6ce8\u610f\uff0c\u5982\u679c\u5199\u6210\u5982\u4e0b\u683c\u5f0f\uff0c\u5219\u8f93\u51fa\u539f\u5b57\u7b26\u4e32\u3002 $ echo 'Yd$@C#M05MD9&8923+Vip3wZ!33*44&55' | awk -F ' ' '{for(i=1;i<=NF;i++){if($i ~ /[[:digit:]]/){str=$i;str1=(str1 str)}};print str1}' \u751f\u6210500\u4e2a\u968f\u673a\u6570\uff0c\u4fdd\u5b58\u5230\u6587\u4ef6random.txt\u4e2d\uff0c\u683c\u5f0f\u4e3a 100,20,61,98... \uff0c\u53d6\u51fa\u5176\u4e2d\u6700\u5927\u6574\u6570\u548c\u6700\u5c0f\u6574\u6570\u3002 $ str = \"\" ; for (( i = 1 ; i< = 500 ; i++ )) ; do if [ $i -ne 500 ] ; then str += \" $RANDOM ,\" ; else str += \" $RANDOM \" ; fi ; done ; echo \" $str \" > random.txt $ cat random.txt 11308 ,8764,2075,9411,...... $ awk -F, '{max=$1;min=$1;for(i=1;i<=NF;i++){if($i>max){max=$i}else{if($i200){system(\"iptables -A INPUT -s \" i \" -j REJECT;\")}}}' \u5c06\u4e0b\u9762\u5185\u5bb9\u4e2dFQDN\u53d6\u51fa\uff0c\u5e76\u6839\u636e\u5176\u8fdb\u884c\u8ba1\u6570\uff0c\u4ece\u9ad8\u5230\u4f4e\u6392\u5e8f\u3002 $ cat > fqdn.txt << EOF http://mail.edu.com/index.html http://www.edu.com/test.html http://study.edu.com/index.html http://blog.edu.com/index.html http://www.edu.com/images/logo.jpg http://blog.edu.com/20080102.html EOF $ awk -F \"/\" '{url[$3]++}END{for(i in url){print url[i], i}}' fqdn.txt | sort -nr 2 www.edu.com 2 blog.edu.com 1 study.edu.com 1 mail.edu.com \u5c06\u4ee5\u4e0b\u2f42\u672c\u4ee5inode\u4e3a\u6807\u8bb0\uff0c\u5bf9inode\u76f8\u540c\u7684counts\u8fdb\u2f8f\u7d2f\u52a0\uff0c\u5e76\u4e14\u7edf\u8ba1\u51fa\u540c\u4e00inode\u4e2d\uff0cbeginnumber\u7684\u6700\u5c0f\u503c\u548cendnumber\u7684\u6700\u5927\u503c\u3002 inode | beginnumber | endnumber | counts | 106 | 3363120000 | 3363129999 | 10000 | 106 | 3368560000 | 3368579999 | 20000 | 310 | 3337000000 | 3337000100 | 101 | 310 | 3342950000 | 3342959999 | 10000 | 310 | 3362120960 | 3362120961 | 2 | 311 | 3313460102 | 3313469999 | 9898 | 311 | 3313470000 | 3313499999 | 30000 | 311 | 3362120962 | 3362120963 | 2 | \u8f93\u51fa\u7684\u7ed3\u679c\u683c\u5f0f\u4e3a\uff1a 310 | 3337000000 | 3362120961 | 10103 | 311 | 3313460102 | 3362120963 | 39900 | 106 | 3363120000 | 3368579999 | 30000 | $ cat > inode.text << EOF inode|beginnumber|endnumber|counts| 106|3363120000|3363129999|10000| 106|3368560000|3368579999|20000| 310|3337000000|3337000100|101| 310|3342950000|3342959999|10000| 310|3362120960|3362120961|2| 311|3313460102|3313469999|9898| 311|3313470000|3313499999|30000| 311|3362120962|3362120963|2| EOF $ awk -F '|' -v OFS = '|' '/^[0-9]/{inode[$1]++; if(!bn[$1]){bn[$1]=$2}else if(bn[$1]>$2) {bn[$1]=$2}; if(en[$1]<$3)en[$1]=$3;cnt[$1]+=$(NF-1)} END{for(i in inode)print i,bn[i],en[i],cnt[i]}' inode.text 106 | 3363120000 | 3368579999 | 30000 310 | 3337000000 | 3362120961 | 10103 311 | 3313460102 | 3362120963 | 39900","title":"\u7b2c\u4e94\u7ae0 \u6b63\u5219\u8868\u8fbe\u5f0f"},{"location":"linux/SRE/05-RegExpress/#_1","text":"\u6b63\u5219\u8868\u8fbe\u5f0f\u5206\u4e24\u7c7b\uff1a \u57fa\u672c\u6b63\u5219\u8868\u8fbe\u5f0f\uff08Basic Regular Expression\uff0c \u53c8\u53ebBasic RegEx\uff0c\u7b80\u79f0BREs\uff09 \u6269\u5c55\u6b63\u5219\u8868\u8fbe\u5f0f\uff08Extended Regular Expression\uff0c \u53c8\u53ebExtended RegEx\uff0c\u7b80\u79f0EREs\uff09 Perl\u6b63\u5219\u8868\u8fbe\u5f0f\uff08Perl Regular Expression\uff0c \u53c8\u53ebPerl RegEx \u7b80\u79f0PREs \u57fa\u672c\u7684\u6b63\u5219\u8868\u8fbe\u5f0f\u548c\u6269\u5c55\u6b63\u5219\u8868\u8fbe\u5f0f\u7684\u533a\u522b\u5c31\u662f\u5143\u5b57\u7b26\u7684\u4e0d\u540c\u3002","title":"\u7b2c\u4e94\u7ae0 \u6b63\u5219\u8868\u8fbe\u5f0f"},{"location":"linux/SRE/05-RegExpress/#51","text":"^ \uff1a\u8868\u793a\u4ee5\u67d0\u4e2a\u5b57\u7b26\u5f00\u59cb $ \uff1a\u8868\u793a\u4ee5\u67d0\u4e2a\u5b57\u7b26\u7ed3\u5c3e . \uff1a\u8868\u793a\u5339\u914d\u4e00\u4e2a\u4e14\u53ea\u5339\u914d\u4e00\u4e2a\u5b57\u7b26 * \uff1a\u8868\u793a\u5339\u914d\u524d\u8fb9\u4e00\u4e2a\u5b57\u7b26\u51fa\u73b00\u6b21\u6216\u8005\u591a\u6b21 [] \uff1a\u8868\u793a\u5339\u914d\u62ec\u53f7\u5185\u7684\u591a\u4e2a\u5b57\u7b26\u4fe1\u606f,\u4e00\u4e2a\u4e00\u4e2a\u5339\u914d .* \uff1a\u8868\u793a\u5339\u914d\u6240\u6709\uff0c\u7a7a\u884c\u4e5f\u4f1a\u8fdb\u884c\u5339\u914d [^] \uff1a\u8868\u793a\u4e0d\u5339\u914d\u62ec\u53f7\u5185\u7684\u6bcf\u4e00\u4e2a\u5b57\u7b26 ^$ \uff1a\u8868\u793a\u5339\u914d\u7a7a\u884c\u4fe1\u606f \\ \uff1a\u5c06\u6709\u7279\u6b8a\u542b\u4e49\u7684\u5b57\u7b26\u8f6c\u4e49\u4e3a\u901a\u914d\u7b26","title":"5.1.\u57fa\u672c\u6b63\u5219\u8868\u8fbe\u5f0f\u7b26\u53f7"},{"location":"linux/SRE/05-RegExpress/#52","text":"+ \uff1a\u8868\u793a\u524d\u4e00\u4e2a\u5b57\u7b26\u51fa\u73b0\u4e00\u6b21\u6216\u4e00\u6b21\u4ee5\u4e0a ? \uff1a\u8868\u793a\u524d\u4e00\u4e2a\u5b57\u7b26\u51fa\u73b00\u6b21\u6216\u8005\u4e00\u6b21\u4ee5\u4e0a | \uff1a\u8868\u793a\u6216\u8005\u7684\u5173\u7cfb,\u5339\u914d\u591a\u4e2a\u4fe1\u606f () \uff1a\u5339\u914d\u4e00\u4e2a\u6574\u4f53\u4fe1\u606f\uff0c\u4e5f\u53ef\u4ee5\u63a5\u540e\u9879\u5f15\u7528 {} \uff1a\u5b9a\u4e49\u524d\u8fb9\u5b57\u7b26\u51fa\u73b0\u51e0\u6b21 \u63d0\u793a\uff1a grep -E \u6216\u8005 egrep \u53ea\u662f\u8868\u793a\u6269\u5c55\u6b63\u5219\uff0c\u4e0d\u4ee3\u8868\u52a0\u4e86e\u5c31\u8868\u793a\u8f6c\u4e49\u4e86\u3002 \u5f53 grep \u4f7f\u7528\u6269\u5c55\u6b63\u5219\u7684\u7b26\u53f7\u65f6\u5019\u9700\u8981\u7528 \\ \u8f6c\u4e49\u4e3a\u901a\u914d\u7b26\u624d\u80fd\u4f7f\u7528\u3002","title":"5.2.\u6269\u5c55\u6b63\u5219\u8868\u8fbe\u5f0f\u7b26\u53f7"},{"location":"linux/SRE/05-RegExpress/#53","text":"[:alpha:] \uff1a\u8868\u793a\u6240\u6709\u7684\u5b57\u6bcd\uff08\u4e0d\u533a\u5206\u5927\u5c0f\u5199\uff09\uff0c\u6548\u679c\u540c [a-z] [:digit:] \uff1a\u8868\u793a\u4efb\u610f\u5355\u4e2a\u6570\u5b57\uff0c\u6548\u679c\u540c [0-9] [:xdigit:] \uff1a\u8868\u793a\u5341\u516d\u8fdb\u5236\u6570\u5b57 [:lower:] \uff1a\u8868\u793a\u4efb\u610f\u5355\u4e2a\u5c0f\u5199\u5b57\u6bcd [:upper:] \uff1a\u8868\u793a\u4efb\u610f\u5355\u4e2a\u5927\u5199\u5b57\u6bcd [:alnum:] \uff1a\u8868\u793a\u4efb\u610f\u5355\u4e2a\u5b57\u6bcd\u6216\u6570\u5b57 [:blank:] \uff1a\u8868\u793a\u7a7a\u767d\u5b57\u7b26\uff08\u7a7a\u683c\u548c\u5236\u8868\u7b26\uff09 [:space:] \uff1a\u8868\u793a\u5305\u62ec\u7a7a\u683c\u3001\u5236\u8868\u7b26\uff08\u6c34\u5e73\u548c\u5782\u76f4\uff09\u3001\u6362\u884c\u7b26\u3001\u56de\u8f66\u7b26\u7b49\u5404\u79cd\u7c7b\u578b\u7684\u7a7a\u767d\uff0c\u6bd4 [:blank:] \u8303\u56f4\u66f4\u5e7f [:cntrl:] \uff1a\u8868\u793a\u4e0d\u53ef\u6253\u5370\u7684\u63a7\u5236\u5b57\u7b26\uff08\u9000\u683c\u3001\u5220\u9664\u3001\u8b66\u94c3\u7b49\uff09 [:graph:] \uff1a\u8868\u793a\u53ef\u6253\u5370\u7684\u975e\u7a7a\u767d\u5b57\u7b26 [:print:] \uff1a\u8868\u793a\u53ef\u6253\u5370\u5b57\u7b26 [:punct:] \uff1a\u8868\u793a\u6807\u70b9\u7b26\u53f7","title":"5.3.\u5b57\u7b26\u5339\u914d"},{"location":"linux/SRE/05-RegExpress/#54","text":"\u4f4d\u7f6e\u6807\u8bb0\u951a\u70b9\uff08position marker anchor\uff09\u662f\u6807\u8bc6\u5b57\u7b26\u4e32\u4f4d\u7f6e\u7684\u6b63\u5219\u8868\u8fbe\u5f0f\u3002\u9ed8\u8ba4\u60c5\u51b5\u4e0b\uff0c\u6b63\u5219\u8868\u8fbe\u5f0f\u6240\u5339\u914d\u7684\u5b57\u7b26\u53ef\u4ee5\u51fa\u73b0\u5728\u5b57\u7b26\u4e32\u4e2d\u4efb\u4f55\u4f4d\u7f6e\u3002 ^ \uff1a\u884c\u9996\u951a\u5b9a\uff0c\u6307\u5b9a\u4e86\u5339\u914d\u6b63\u5219\u8868\u8fbe\u5f0f\u7684\u6587\u672c\u5fc5\u987b\u8d77\u59cb\u4e8e\u5b57\u7b26\u4e32\u7684\u9996\u90e8\u3002 \u4f8b\u5982\uff1a ^tux \u80fd\u591f\u5339\u914d\u4ee5 tux \u8d77\u59cb\u7684\u884c $ \uff1a\u884c\u5c3e\u951a\u5b9a\uff0c\u6307\u5b9a\u4e86\u5339\u914d\u6b63\u5219\u8868\u8fbe\u5f0f\u7684\u6587\u672c\u5fc5\u987b\u7ed3\u675f\u4e8e\u76ee\u6807\u5b57\u7b26\u4e32\u7684\u5c3e\u90e8\u3002 \\< \u6216 \\b \uff1a\u8bcd\u9996\u951a\u5b9a\uff0c\u7528\u4e8e\u5355\u8bcd\u6a21\u5f0f\u5339\u914d\u5de6\u4fa7\u3002\uff08\u5355\u8bcd\u662f\u6709\u5b57\u6bcd\u3001\u6570\u5b57\u3001\u4e0b\u5212\u7ebf\u7ec4\u6210\uff09 \\> \u6216 \\b \uff1a\u8bcd\u5c3e\u951a\u5b9a\uff0c\u7528\u4e8e\u5355\u8bcd\u6a21\u5f0f\u5339\u914d\u53f3\u4fa7\u3002\uff08\u5355\u8bcd\u662f\u6709\u5b57\u6bcd\u3001\u6570\u5b57\u3001\u4e0b\u5212\u7ebf\u7ec4\u6210\uff09 ^PATTERN$ \uff1a\u7528\u6a21\u5f0fPATTERN\u5339\u914d\u6574\u884c\u3002 ^$ \uff1a\u5339\u914d\u7a7a\u884c\u3002 ^[[:space:]]*$ \uff1a\u5339\u914d\u7a7a\u767d\u884c\uff08\u6574\u884c\uff09\u3002 \\ \uff1a\u5339\u914d\u6574\u4e2a\u5355\u8bcd\u3002\uff08\u5355\u8bcd\u662f\u6709\u5b57\u6bcd\u3001\u6570\u5b57\u3001\u4e0b\u5212\u7ebf\u7ec4\u6210\uff09 \u5173\u4e8e\u884c\u9996\u951a\u5b9a\u548c\u8bcd\u9996\u951a\u5b9a\uff0c\u5bf9\u6bd4\u4e0b\u9762\u4f8b\u5b50\u3002\u8bcd\u5c3e\u951a\u5b9a\u4e5f\u662f\u7c7b\u4f3c\u60c5\u51b5\u3002 ; \u548c - \u90fd\u88ab\u8ba4\u5b9a\u4e3a\u5355\u8bcd\u5206\u9694\u7b26\u3002 # \u7b26\u5408\u8bcd\u9996\u5339\u914d $ echo \"tux_01-tux02\" | grep '\\ mtu 1500 inet 192 .168.10.210 netmask 255 .255.255.0 broadcast 192 .168.10.255 inet6 fe80::20c:29ff:fea4:e17a prefixlen 64 scopeid 0x20 ether 00 :0c:29:a4:e1:7a txqueuelen 1000 ( Ethernet ) RX packets 7654 bytes 635932 ( 621 .0 KiB ) RX errors 0 dropped 1 overruns 0 frame 0 TX packets 1934 bytes 279649 ( 273 .0 KiB ) TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0 $ ifconfig eth0 | grep netmask | grep -o '[0-9]\\{1,3\\}\\.[0-9]\\{1,3\\}\\.[0-9]\\{1,3\\}\\.[0-9]\\{1,3\\}' 192 .168.10.210 255 .255.255.0 192 .168.10.255 $ ifconfig eth0 | grep netmask | grep -o '[0-9]\\{1,3\\}\\.[0-9]\\{1,3\\}\\.[0-9]\\{1,3\\}\\.[0-9]\\{1,3\\}' | head -n 1 192 .168.10.210 $ ifconfig eth0 | grep -o '[0-9]\\{1,3\\}\\.[0-9]\\{1,3\\}\\.[0-9]\\{1,3\\}\\.[0-9]\\{1,3\\}' 192 .168.10.210 255 .255.255.0 192 .168.10.255 ifconfig eth0 | grep -o '[0-9]\\{1,3\\}\\.[0-9]\\{1,3\\}\\.[0-9]\\{1,3\\}\\.[0-9]\\{1,3\\}' | head -n 1 192 .168.10.210 \u5339\u914d\u7a7a\u884c\u548c\u975e\u7a7a\u884c\uff1a grep '^$' /etc/profile grep -v '^$' /etc/profile \u5339\u914d\u975e\u7a7a\u884c\u548c\u975e#\u5f00\u5934\u7684\u884c\uff1a\uff08\u4e09\u79cd\u65b9\u6cd5\uff09 grep -v '^$' /etc/profile | grep -v '^#' grep -v '^$\\|#' /etc/profile grep '^[^$#]' /etc/profile \u6ce8\u610f\uff0c\u5982\u679c\u5199\u6210\u4e0b\u9762\u8fd9\u6837\uff0c\u5219\u4e0d\u4f1a\u8fc7\u6ee4\u6389\u7a7a\u884c\uff0c [$] \u4f1a\u88ab\u89c6\u4e3a $ \u7b26\u53f7\u3002 \u6240\u4ee5\u6b63\u5219\u8868\u8fbe\u5f0f\u7684\u5143\u5b57\u7b26\u653e\u5728\u4e2d\u62ec\u53f7 [] \u5185\u5c31\u88ab\u89c6\u4e3a\u666e\u901a\u5b57\u7b26\u3002 grep -v '^[$#]' /etc/profile","title":"5.7.\u5206\u7ec4"},{"location":"linux/SRE/05-RegExpress/#58grep","text":"\u683c\u5f0f\uff1a grep [OPTIONS] PATTERN [FILE...] grep [OPTIONS] -e PATTERN ... [FILE...] grep [OPTIONS] -f FILE ... [FILE...] \u53c2\u6570\uff1a -n \uff1a\u663e\u793a\u8fc7\u6ee4\u51fa\u6765\u7684\u6587\u4ef6\u5728\u6587\u4ef6\u5f53\u4e2d\u7684\u884c\u53f7 -c \uff1a\u663e\u793a\u5339\u914d\u5230\u7684\u884c\u6570 -o \uff1a\u53ea\u663e\u793a\u5339\u914d\u5230\u7684\u5185\u5bb9 -q \uff1a\u9759\u9ed8\u8f93\u51fa\uff08\u4e00\u822c\u7528\u5728shell\u811a\u672c\u5f53\u4e2d\uff0c\u901a\u8fc7 echo $? \u67e5\u770b\u547d\u4ee4\u6267\u884c\u7ed3\u679c\uff0c0\u8868\u793a\u6210\u529f\uff0c\u975e0\u8868\u793a\u5931\u8d25\uff09\uff09 -i \uff1a\u5ffd\u7565\u5927\u5c0f\u5199 -v \uff1a\u53cd\u5411\u67e5\u627e -w \uff1a\u5339\u914d\u67d0\u4e2a\u8bcd\u8bcd\uff1a\u5728Linux\u4e2d\uff0c\u8bcd\u4e3a\u4e00\u8fde\u4e32\u5b57\u6bcd\u3001\u6570\u5b57\u548c\u4e0b\u5212\u7ebf\u7ec4\u6210\u7684\u5b57\u7b26\u4e32 -E \uff1a\u4f7f\u7528\u6269\u5c55\u6b63\u5219 -R \uff1a\u9012\u5f52\u67e5\u8be2 -l \uff1a\u53ea\u6253\u5370\u6587\u4ef6\u8def\u5f84 \u6269\u5c55\u53c2\u6570\uff1a -A \uff1a\u663e\u793a\u5339\u914d\u5230\u7684\u6570\u636e\u7684\u540e\u51e0n\u884c -B \uff1a\u663e\u793a\u5339\u914d\u5230\u7684\u6570\u636e\u7684\u524d\u51e0n\u884c -C \uff1a\u663e\u793a\u5339\u914d\u5230\u7684\u6570\u636e\u7684\u524d\u540e\u5404\u51e0n\u884c \u793a\u4f8b\uff1a \u5339\u914d\u7528\u6237\uff1a grep root /etc/passwd root:x:0:0:root:/root:/bin/bash $ grep \"USER\" /etc/passwd $ grep \" $USER \" /etc/passwd vagrant:x:1000:478:vagrant:/home/vagrant:/bin/bash $ grep '$USER' /etc/passwd \u5339\u914d\u5173\u952e\u5b57\uff1a $ grep processor /proc/cpuinfo processor : 0 processor : 1 $ grep -o processor /proc/cpuinfo processor processor $ grep \"cpu family\" /proc/cpuinfo cpu family : 6 cpu family : 6 $ grep -o \"cpu family\" /proc/cpuinfo cpu family cpu family \u901a\u8fc7grep\u8fdb\u884c\u6587\u4ef6\u6bd4\u8f83\u3002 # \u6700\u540e\u4e00\u884c\u662f\u7a7a\u884c $ cat f1 a b 1 c # \u6700\u540e\u4e00\u884c\u662f\u7a7a\u884c $ cat f2 b e f c 1 2 # \u9ad8\u4eae\u663e\u793a\u76f8\u540c\u5185\u5bb9\u7684\u884c\uff0c\u5305\u542b\u6700\u540e\u4e00\u884c\u7a7a\u884c $ grep -f f1 f2 b e f c 1 2 # \u53ea\u663e\u793a\u76f8\u540c\u5185\u5bb9\u7684\u884c\uff0c\u5305\u542b\u6700\u540e\u4e00\u884c\u7a7a\u884c $ grep -wf f1 f2 b c 1 # \u53ea\u663e\u793a\u4e0d\u540c\u5185\u5bb9\u7684\u884c $ grep -wvf f1 f2 e f 2 \u63d0\u793a\uff1a grep -wvf f1 f2 \u6216\u8005 grep -w -v -f f1 f2 \u4e2d\uff0c -f \u53ea\u80fd\u4f5c\u4e3a\u6700\u540e\u4e00\u4e2a\u53c2\u6570\uff0c\u5426\u5219\u4f1a\u62a5\u9519\u3002 \u4f53\u4f1a\u57fa\u672c\u6b63\u5219\u548c\u6269\u5c55\u6b63\u5219\u7684\u5dee\u5f02\u3002 \u4f8b1\uff1a\u8f6c\u4e49\u3002 # \u4e0b\u9762\u51e0\u4e2a\u547d\u4ee4\u8fd4\u56de\u7684\u7ed3\u679c\u662f\u4e00\u6837\u7684\u3002 $ grep \"root\\|bash\" /etc/passwd $ grep -E \"root|bash\" /etc/passwd $ grep -e \"root\" -e \"bash\" /etc/passwd # \u4e0b\u9762\u7684\u547d\u4ee4\u6ca1\u6709\u5339\u914d\u7ed3\u679c\u8fd4\u56de\u3002 $ grep \"root|bash\" /etc/passwd \u4f8b2\uff1a\u4e0b\u97624\u4e2a\u547d\u4ee4\u8fd4\u56de\u540c\u6837\u7684\u7ed3\u679c\u3002 grep \"root\" /etc/passwd grep -E \"root\" /etc/passwd grep \"\\\" /etc/passwd grep -E \"\\\" /etc/passwd \u4f8b3\uff1a\u884c\u9996\u884c\u5c3e\u951a\u5b9a\u3002 $ grep \"^\\(.*\\)\\>.*\\<\\1 $ \" /etc/passwd $ grep -E \"^(.*)\\>.*\\<\\1 $ \" /etc/passwd $ egrep \"^(.*)\\>.*\\<\\1 $ \" /etc/passwd sync:x:5:0:sync:/sbin:/bin/sync shutdown:x:6:0:shutdown:/sbin:/sbin/shutdown halt:x:7:0:halt:/sbin:/sbin/halt \u4f8b4\uff1a\u4e09\u79cd\u65b9\u6cd5\u6c42\u548c\u8ba1\u7b97\uff0c\u8fd0\u7528 grep \uff0c cut \uff0c bc \u548c paste \u547d\u4ee4\u3002 $cat age Jason = 20 Tom = 30 Jack = 40 # \u65b9\u6cd51 $ cat age | cut -d \"=\" -f 2 | tr \"\\n\" + | grep -Eo \".*[0-9]\" | bc 90 # \u65b9\u6cd52 $ grep -Eo \"[0-9]+\" age | tr \"\\n\" + | grep -Eo \".*[0-9]\" | bc 90 # \u65b9\u6cd53 $ grep -Eo \"[0-9]+\" age | paste -s -d \"+\" | bc 90","title":"5.8.\u4e09\u5251\u5ba2grep\u547d\u4ee4"},{"location":"linux/SRE/05-RegExpress/#59sed","text":"sed \u662fstream editor\u7684\u7f29\u5199\uff0c\u4e2d\u6587\u79f0\u4e4b\u4e3a\u201c\u6d41\u7f16\u8f91\u5668\u201d\u3002 sed \u547d\u4ee4\u662f\u4e00\u4e2a\u9762\u5411\u884c\u5904\u7406\u7684\u5de5\u5177\uff0c\u5b83\u4ee5\u201c\u884c\u201d\u4e3a\u5904\u7406\u5355\u4f4d\uff0c\u9488\u5bf9\u6bcf\u4e00\u884c\u8fdb\u884c\u5904\u7406\uff0c\u5904\u7406\u540e\u7684\u7ed3\u679c\u4f1a\u8f93\u51fa\u5230\u6807\u51c6\u8f93\u51fa STDOUT \uff0c\u4e0d\u4f1a\u5bf9\u8bfb\u53d6\u7684\u6587\u4ef6\u505a\u4efb\u4f55\u4fee\u6539\u3002 sed \u7684\u5de5\u4f5c\u539f\u7406\uff1a sed \u547d\u4ee4\u662f\u9762\u5411\u201c\u884c\u201d\u8fdb\u884c\u5904\u7406\u7684\uff0c\u6bcf\u4e00\u6b21\u5904\u7406\u4e00\u884c\u5185\u5bb9\u3002 \u5904\u7406\u65f6\uff0c sed \u4f1a\u628a\u8981\u5904\u7406\u7684\u884c\u5b58\u50a8\u5728\u7f13\u51b2\u533a\u4e2d\uff0c\u63a5\u7740\u7528 sed \u547d\u4ee4\u5904\u7406\u7f13\u51b2\u533a\u4e2d\u7684\u5185\u5bb9\uff0c\u5904\u7406\u5b8c\u6210\u540e\uff0c\u628a\u7f13\u51b2\u533a\u7684\u5185\u5bb9\u9001\u5f80\u5c4f\u5e55\u3002\u63a5\u7740\u5904\u7406\u4e0b\u4e00\u884c\uff0c\u8fd9\u6837\u4e0d\u65ad\u91cd\u590d\uff0c\u76f4\u5230\u6587\u4ef6\u672b\u5c3e\u3002\u8fd9\u4e2a\u7f13\u51b2\u533a\u88ab\u79f0\u4e3a\u201c \u6a21\u5f0f\u7a7a\u95f4 \u201d\uff08pattern space\uff09\u3002 \u4fdd\u6301\u7a7a\u95f4(hold space) sed \u7684\u4fdd\u6301\u7a7a\u95f4\u50cf\u4e00\u4e2a\u957f\u671f\u50a8\u5b58\uff0c \u53ef\u4ee5\u628a\u83b7\u53d6\u7684\u4fe1\u606f\u50a8\u5b58\u5230\u5176\u4e2d\uff0c\u5f85\u540e\u7eed\u8c03\u7528\u3002\u4e0d\u80fd\u76f4\u63a5\u5bf9\u4fdd\u6301\u7a7a\u95f4\u8fdb\u884c\u64cd\u4f5c\uff0c \u800c\u662f\u5c06\u4fdd\u6301\u7a7a\u95f4\u7684\u5185\u5bb9\u590d\u5236\u6216\u8005\u6dfb\u52a0\u5230\u6a21\u5f0f\u7a7a\u95f4\u8fdb\u884c\u64cd\u4f5c\u3002 \u975e\u4ea4\u4e92\u5f0f\u6279\u91cf\u4fee\u6539\u6587\u4ef6\u3002 sed \u547d\u4ee4\u683c\u5f0f\uff1a sed [ option ] command file option \u5e38\u7528\u9009\u9879\uff1a -n \uff1a\u4e0d\u8f93\u51fa\u6a21\u5f0fpattern\u7684\u5185\u5bb9\u5230\u5c4f\u5e55\uff08\u5373\u4e0d\u81ea\u52a8\u6253\u5370\uff09 -e \uff1a\u591a\u70b9\u7f16\u8f91 -f filename \uff1a\u4ece\u6307\u5b9a\u6587\u4ef6\u8bfb\u53d6\u7f16\u8f91\u811a\u672c -r \uff0c -E \uff1a\u4f7f\u7528\u6269\u5c55\u6b63\u5219\u8868\u8fbe\u5f0f -i .bak \uff1a\u5907\u4efd\u6587\u4ef6\u5e76\u539f\u5904\u7f16\u8f91 -s \uff1a\u5c06\u591a\u4e2a\u6587\u4ef6\u89c6\u4e3a\u72ec\u7acb\u6587\u4ef6\uff0c\u800c\u4e0d\u662f\u5355\u4e2a\u8fde\u7eed\u7684\u957f\u6587\u4ef6\u6d41 -ir \uff1a \u4e0d\u652f\u6301 -i -r \uff1a \u652f\u6301 -ri \uff1a \u652f\u6301 -ni \uff1a \u5371\u9669\u9009\u9879\uff0c\u4f1a\u6e05\u7a7a\u6587\u4ef6 command \u90e8\u5206\u53ef\u4ee5\u5206\u4e3a\u4e24\u90e8\u5206\uff1a \u8303\u56f4\u8bbe\u5b9a\uff0c\u53ef\u4ee5\u91c7\u7528\u4e24\u79cd\u4e0d\u540c\u7684\u65b9\u5f0f\u6765\u8868\u8fbe\uff1a \u6307\u5b9a\u884c\u6570\uff1a\u5982\uff1a 3,5 \u8868\u793a\u7b2c3\u30014\u30015\u884c 5,$ \u8868\u793a\u7b2c5\u884c\u81f3\u6587\u4ef6\u6700\u540e\u4e00\u884c \u6a21\u5f0f\u5339\u914d\uff1a\u5982\uff1a /^[^dD]/ \u8868\u793a\u5339\u914d\u884c\u9996\u4e0d\u662f\u4ee5 d \u6216 D \u5f00\u5934\u7684\u884c \u52a8\u4f5c\u5904\u7406\uff0c\u4e0b\u9762\u662f\u5e38\u7528\u7684\u52a8\u4f5c\uff1a a \uff1a\u65b0\u589e\uff0c a \u540e\u9762\u7684\u5b57\u4e32\u4f1a\u5728\u65b0\u7684\u4e00\u884c\u51fa\u73b0\uff08\u5f53\u524d\u884c\u7684\u4e0b\u4e00\u884c\uff09 i \uff1a\u63d2\u5165\uff0c i \u540e\u9762\u7684\u5b57\u4e32\u4f1a\u5728\u65b0\u7684\u4e00\u884c\u51fa\u73b0\uff08\u5f53\u524d\u884c\u7684\u4e0a\u4e00\u884c\uff09 r filename \uff1a\u8bfb\u53d6\u6307\u5b9a\u6587\u4ef6 fllename \u7684\u5185\u5bb9\uff0c\u8ffd\u52a0\u5230\u5f53\u524d\u884c\u7684\u4e0b\u4e00\u884c R filename \uff1a\u8bfb\u53d6\u6307\u5b9a\u6587\u4ef6 fllename \u7684\u4e00\u884c\uff0c\u8ffd\u52a0\u5230\u5f53\u524d\u884c\u7684\u4e0b\u4e00\u884c d \uff1a\u5220\u9664\u8be5\u884c p \uff1a\u6253\u5370\u8be5\u884c Ip \uff1a\u5ffd\u7565\u5927\u5c0f\u5199\u8f93\u51fa w filename \uff1a\u5199\u5165\u5230\u6307\u5b9a\u6587\u4ef6filename\u4e2d\u3002 s/regexp/replacement/ \uff1a\u53d6\u4ee3\uff0c\u7528replacement\u53d6\u4ee3\u6b63\u5219regexp\u5339\u914d\u5230\u7684\u5185\u5bb9 = \uff1a\u4e3a\u6a21\u5f0fpattern\u4e2d\u7684\u5339\u914d\u884c\u6253\u5370\u884c\u53f7 ! \uff1a\u4e3a\u6a21\u5f0fpattern\u4e2d\u7684\u5339\u914d\u884c\u53d6\u53cd\u64cd\u4f5c q \uff1a\u7ed3\u675f\u6216\u9000\u51fased \u521b\u5efa\u4e00\u4e2a testfile \u6587\u4ef6\u3002 $ cat < testfile HELLO LINUX! Linux is a free unix-type opterating system. This is a linux testfile! Linux test Google Taobao Banbooob Tesetfile Wiki EOF \u5339\u914d\u5b9a\u4f4d\u6587\u4ef6 testfile \u7b2c\u4e8c\u884c\uff0c\u5e76\u8f93\u51fa\uff08\u5305\u542b\u5339\u914d\u7b2c\u4e8c\u884c\u548c\u8f93\u51fa\u7b2c\u4e8c\u884c\uff09\u3002 # nl testfile | sed '2p' 1 HELLO LINUX! 2 Linux is a free unix-type opterating system. 2 Linux is a free unix-type opterating system. 3 This is a linux testfile! 4 Linux test 5 Google 6 Taobao 7 Banbooob 8 Tesetfile 9 Wiki \u5339\u914d\u5b9a\u4f4d\u6587\u4ef6 testfile \u7b2c\u4e8c\u884c\uff0c\u4e0d\u8f93\u51fa\u3002 # nl testfile | sed -n '2p' 2 Linux is a free unix-type opterating system. \u5339\u914d\u5b9a\u4f4d\u6587\u4ef6 testfile \u6700\u540e\u4e00\u884c\u3002 $ nl testfile | sed -n '$p' 9 Wiki \u5339\u914d\u5b9a\u4f4d\u6587\u4ef6 testfile \u5012\u6570\u7b2c\u4e8c\u884c\u3002 # sed -n \"$(echo $[`cat testfile | wc -l`-1])p\" testfile Tesetfile \u5c06 testfile \u7684\u5185\u5bb9\u5217\u51fa\u7b2c2\uff5e3\u884c\uff0c\u5e76\u4e14\u6253\u5370\u884c\u53f7\u3002 $ nl testfile | sed -n '2,3p' 2 Linux is a free unix-type opterating system. 3 This is a linux testfile! \u5c06 testfile \u7684\u5185\u5bb9\u4ece\u7b2c2\u884c\u5f00\u59cb\uff0c\u5411\u540e\u8f93\u51fa\u989d\u5916\u76843\u884c\uff0c\u5e76\u4e14\u6253\u5370\u884c\u53f7\u3002 $ nl testfile | sed -n '2,+3p' 2 Linux is a free unix-type opterating system. 3 This is a linux testfile! 4 Linux test 5 Google \u5c06 testfile \u7684\u5185\u5bb9\u4ece\u7b2c2\u884c\u5f00\u59cb\uff0c\u5411\u540e\u4ee52\u4e3a\u6b65\u8fdb\u5355\u4f4d\u8f93\u51fa\u6240\u6709\u5339\u914d\u884c\uff0c\u5e76\u4e14\u6253\u5370\u884c\u53f7\uff08\u5373\uff0c\u4ece\u7b2c2\u884c\u5f00\u59cb\u8f93\u51fa\u5076\u6570\u884c\uff09\u3002 nl testfile | sed -n '2~2p' 2 Linux is a free unix-type opterating system. 4 Linux test 6 Taobao 8 Tesetfile \u5c06 testfile \u7684\u5185\u5bb9\u4ece\u7b2c2\u884c\u5f00\u59cb\uff0c\u5411\u540e\u4ee52\u4e3a\u6b65\u8fdb\u5355\u4f4d\u5220\u9664\u6240\u6709\u5339\u914d\u884c\uff0c\u8f93\u51fa\u5269\u4f59\u884c\uff0c\u5e76\u4e14\u6253\u5370\u884c\u53f7\uff08\u5373\uff0c\u4ece\u7b2c2\u884c\u5f00\u59cb\u5220\u9664\u5076\u6570\u884c\uff0c\u8f93\u51fa\u5947\u6570\u884c\uff09\u3002 $ nl testfile | sed '2~2d' 1 HELLO LINUX! 3 This is a linux testfile! 5 Google 7 Banbooob 9 Wiki \u5c06 testfile \u7684\u5185\u5bb9\u8f93\u51fa\uff0c\u5220\u9664\u7b2c2\u884c\u548c\u7b2c5\u884c\uff0c\u5e76\u6253\u5370\u884c\u53f7\u3002 $ nl testfile | sed -e '2d' -e '5d' $ nl testfile | sed -e '2d;5d' $ nl testfile | sed '2d;5d' 1 HELLO LINUX! 3 This is a linux testfile! 4 Linux test 6 Taobao 7 Banbooob 8 Tesetfile 9 Wiki \u5c06 testfile \u7684\u5185\u5bb9\u8f93\u51fa\uff0c\u8f93\u51fa\u533a\u95f4\u662f\u4ece\u884c\u9996 L \u7684\u884c\u5230\u884c\u9996 G \u7684\u884c\u7ed3\u675f\u3002\u4e0d\u4fee\u6539\u539f\u6587\u4ef6\u3002 \u5982\u679c\u884c\u9996\u5339\u914d\u4e0d\u5230\uff0c\u5219\u65e0\u7ed3\u679c\u8f93\u51fa\uff1b\u5982\u679c\u884c\u5c3e\u5339\u914d\u4e0d\u5230\uff0c\u5219\u8f93\u51fa\u5230\u6587\u4ef6\u7ed3\u675f\u3002 $ sed -n '/^L/,/^G/p' testfile Linux is a free unix-type opterating system. This is a linux testfile! Linux test Google \u5c06 testfile \u7684\u5185\u5bb9\u8f93\u51fa\uff0c\u4e14\u5728\u7b2c6\u884c\u540e\u52a0\u4e0a I love Linux \u3002\u4e0d\u4fee\u6539\u539f\u6587\u4ef6\u3002 $ sed -e '6a I love Linux' testfile HELLO LINUX! Linux is a free unix-type opterating system. This is a linux testfile! Linux test Google Taobao I love Linux Banbooob Tesetfile Wiki \u5c06 testfile \u7684\u5185\u5bb9\u5217\u51fa\u5e76\u4e14\u6253\u5370\u884c\u53f7\uff0c\u4e14\u5728\u7b2c6\u884c\u540e\u6dfb\u52a0 I love Linux \u3002\u4e0d\u4fee\u6539\u539f\u6587\u4ef6\u3002 $ nl testfile | sed '6a I love Linux' $ nl testfile | sed '6a\\I love Linux' 1 HELLO LINUX! 2 Linux is a free unix-type opterating system. 3 This is a linux testfile! 4 Linux test 5 Google 6 Taobao I love Linux 7 Banbooob 8 Tesetfile 9 Wiki \u5c06 testfile \u7684\u5185\u5bb9\u5217\u51fa\u5e76\u4e14\u6253\u5370\u884c\u53f7\uff0c\u4e14\u5728\u7b2c3\u884c\u524d\u6dfb\u52a0 I am a journer learner \u3002\u4e0d\u4fee\u6539\u539f\u6587\u4ef6\u3002 $ nl testfile | sed '3i\\I am a journer learner' 1 HELLO LINUX! 2 Linux is a free unix-type opterating system. I am a journer learner 3 This is a linux testfile! 4 Linux test 5 Google 6 Taobao 7 Banbooob 8 Tesetfile 9 Wiki \u5c06 testfile \u7684\u5185\u5bb9\u5217\u51fa\u5e76\u4e14\u6253\u5370\u884c\u53f7\uff0c\u4e14\u5728\u7b2c3\u884c\u524d\u6dfb\u52a0\u4e09\u884c\u5185\u5bb9 Add line 1 \uff0c Add line 2 \uff0c Add line 3 \u3002\u7528\u7b26\u5408 \\ \u8fdb\u884c\u6362\u884c\u3002\u4e0d\u4fee\u6539\u539f\u6587\u4ef6\u3002 $ nl testfile | sed '3i\\Add line 1 \\ Add line 2 \\ Add line 3' 1 HELLO LINUX! 2 Linux is a free unix-type opterating system. Add line 1 Add line 2 Add line 3 3 This is a linux testfile! 4 Linux test 5 Google 6 Taobao 7 Banbooob 8 Tesetfile 9 Wiki \u5c06 testfile \u7684\u5185\u5bb9\u5217\u51fa\u5e76\u4e14\u6253\u5370\u884c\u53f7\uff0c\u4e14\u5c06\u7b2c2-5\u884c\u7684\u5185\u5bb9\u53d6\u4ee3\u6210\u4e3a replaced \u3002\u4e0d\u4fee\u6539\u539f\u6587\u4ef6\u3002 $ nl testfile | sed '2,5c\\replaced' $ nl testfile | sed '2,5c replaced' $ nl testfile | sed '2,5creplaced' 1 HELLO LINUX! replaced 6 Taobao 7 Banbooob 8 Tesetfile 9 Wiki \u5c06 testfile \u7684\u5185\u5bb9\u5217\u51fa\u5e76\u4e14\u6253\u5370\u884c\u53f7\uff0c\u4e14\u5220\u9664\u7b2c2~5\u884c\u3002\u4e0d\u4fee\u6539\u539f\u6587\u4ef6\u3002 $ nl testfile | sed '2,5d' 1 HELLO LINUX! 6 Taobao 7 Banbooob 8 Tesetfile 9 Wiki \u5c06 testfile \u7684\u5185\u5bb9\u5217\u51fa\u5e76\u4e14\u6253\u5370\u884c\u53f7\uff0c\u4e14\u5220\u9664\u7b2c5\u884c\u5230\u6700\u540e\u4e00\u884c\u3002 $ nl testfile | sed '5,$d' 1 HELLO LINUX! 2 Linux is a free unix-type opterating system. 3 This is a linux testfile! 4 Linux test \u5339\u914d\u5b9a\u4f4d\u6587\u4ef6 testfile \u4e2d\u5305\u542b\u5173\u952e\u5b57 linux \u7684\u884c\u3002 $ sed -n '/linux/p' testfile This is a linux testfile! \u5339\u914d\u5b9a\u4f4d\u547d\u4ee4 df \u8f93\u51fa\u4e2d\u4ee5 /dev/sd \u5173\u952e\u5b57\u5f00\u5934\u7684\u884c\u3002\uff08\u9700\u8981\u8f6c\u4e49\u7b26 \\ \uff09 $ df | sed -n '/^\\/dev\\/sd/p' /dev/sda2 102750208 7077280 92055312 8 % / /dev/sda2 102750208 7077280 92055312 8 % /.snapshots /dev/sda2 102750208 7077280 92055312 8 % /home /dev/sda2 102750208 7077280 92055312 8 % /opt /dev/sda2 102750208 7077280 92055312 8 % /root /dev/sda2 102750208 7077280 92055312 8 % /boot/grub2/x86_64-efi /dev/sda2 102750208 7077280 92055312 8 % /boot/grub2/i386-pc /dev/sda2 102750208 7077280 92055312 8 % /srv /dev/sda2 102750208 7077280 92055312 8 % /tmp /dev/sda2 102750208 7077280 92055312 8 % /usr/local /dev/sda2 102750208 7077280 92055312 8 % /var \u5339\u914d\u5b9a\u4f4d\u547d\u4ee4 df \u8f93\u51fa\u4e2d\u4e0d\u4ee5 /dev/sd \u5173\u952e\u5b57\u5f00\u5934\u7684\u884c\u3002\u901a\u8fc7 !p \u8fdb\u884c\u6c42\u53cd\u8f93\u51fa\u3002 $ df | sed -n '/^\\/dev\\/sd/!p' Filesystem 1K-blocks Used Available Use% Mounted on devtmpfs 4096 0 4096 0 % /dev tmpfs 1971208 0 1971208 0 % /dev/shm tmpfs 788484 9612 778872 2 % /run tmpfs 4096 0 4096 0 % /sys/fs/cgroup tmpfs 394240 0 394240 0 % /run/user/1000 \u5339\u914d\u5b9a\u4f4d\u547d\u4ee4 df \u8f93\u51fa\u4e2d\u4e0d\u4ee5 /dev/sd \u548c tmp \u5173\u952e\u5b57\u5f00\u5934\u7684\u884c\u3002 $ df | sed '/^\\/dev\\/sd/d;/^tmp/d' Filesystem 1K-blocks Used Available Use% Mounted on devtmpfs 4096 0 4096 0 % /dev $ df | grep -Ev '^\\/dev\\/sd|^tmp' Filesystem 1K-blocks Used Available Use% Mounted on devtmpfs 4096 0 4096 0 % /dev \u641c\u7d22\u6587\u4ef6 testfile \u6240\u6709\u5305\u542b oo \u5173\u952e\u5b57\u7684\u884c\u5e76\u5339\u914d\u8f93\u51fa\u3002\u4e0d\u4fee\u6539\u539f\u6587\u4ef6\u3002 $ sed -n '/ooo/p' testfile Banbooob $ sed -n '/oo/p' testfile Google Banbooob \u641c\u7d22\u6587\u4ef6 testfile \u6240\u6709\u5305\u542b oo \u5173\u952e\u5b57\u7684\u884c\u5e76\u5220\u9664\u3002\u4e0d\u4fee\u6539\u539f\u6587\u4ef6\u3002 $ sed '/oo/d' testfile HELLO LINUX! Linux is a free unix-type opterating system. This is a linux testfile! Linux test Taobao Tesetfile Wiki \u641c\u7d22\u6587\u4ef6 testfile \u6240\u6709\u5305\u542b oo \u7684\u884c\uff0c\u628a oo \u66ff\u6362\u4e3a kk \uff0c\u518d\u8f93\u51fa\u8fd9\u884c\u3002\u4e0d\u4fee\u6539\u539f\u6587\u4ef6\u3002 $ sed -n '/oo/{s/oo/kk/;p;q}' testfile $ sed -ne '/oo/{s/oo/kk/;p;q}' testfile Gkkgle \u5c06 testfile \u7684\u6bcf\u884c\u4e2d\u7b2c\u4e00\u6b21\u51fa\u73b0 ao \u7684\u66ff\u6362\u6210 HH \u3002 $ sed 's/ao/HH/' testfile HELLO LINUX! Linux is a free unix-type opterating system. This is a linux testfile! Linux test Google THHbao Banbooob Tesetfile Wiki \u4e0b\u9762\u662f\u628a testfile \u7684\u5339\u914d\u5230 ao \u7684\u884c\u66ff\u6362\u6210 HH \u3002 sed '/ao/cHH' testfile HELLO LINUX! SUSE This is a linux testfile! SUSE Google Taobao Banbooob Tesetfile Wiki \u641c\u7d22\u6587\u4ef6 testfile \u6240\u6709\u5305\u542b ao \u7684\u5168\u90e8\u66ff\u6362\u6210 HH \u3002 g \u8868\u793a\u5168\u5c40\u5339\u914d\u3002\u4e0d\u4fee\u6539\u539f\u6587\u4ef6\u3002 $ sed -e 's/ao/HH/g' testfile $ sed 's/ao/HH/g' testfile HELLO LINUX! Linux is a free unix-type opterating system. This is a linux testfile! Linux test Google THHbHH Banbooob Tesetfile Wiki \u5728\u6587\u4ef6 /etc/passwd \u4e2d\u67e5\u627e\u5339\u914d\u6240\u6709\u7b26\u5408 r \u5f00\u5934 t \u7ed3\u5c3e\u4e14\u4e2d\u95f4\u542b\u4efb\u610f\u4e24\u4e2a\u5b57\u7b26\u7684\u884c\uff0c\u5e76\u5728 t \u5b57\u6bcd\u540e\u6dfb\u52a0 er \u3002 $ sed -nr 's/r..t/&er/gp' /etc/passwd rooter:x:0:0:rooter:/rooter:/bin/bash lp:x:493:487:Printering daemon:/var/spool/lpd:/usr/sbin/nologin tftp:x:487:474:TFTP account:/srv/terftpboot:/bin/false vagranter:x:1000:478:vagranter:/home/vagranter:/bin/bash tester1:x:600:1530: \"Test User1,terestuser1@abc.com\" :/home/tester1:/bin/bash \u5c06\u4e0a\u8ff0\u7ed3\u679c\u548c\u539f\u59cb\u5185\u5bb9\u8fdb\u884c\u5bf9\u6bd4\uff0c\u80fd\u66f4\u597d\u7684\u7406\u89e3 s/r..t/&er \u7684\u64cd\u4f5c\u3002 rooter:x:0:0:rooter:/rooter:/bin/bash root:x:0:0:root:/root:/bin/bash lp:x:493:487:Printering daemon:/var/spool/lpd:/usr/sbin/nologin lp:x:493:487:Printing daemon:/var/spool/lpd:/usr/sbin/nologin tftp:x:487:474:TFTP account:/srv/terftpboot:/bin/false tftp:x:487:474:TFTP account:/srv/tftpboot:/bin/false vagranter:x:1000:478:vagranter:/home/vagranter:/bin/bash vagrant:x:1000:478:vagrant:/home/vagrant:/bin/bash tester1:x:600:1530: \"Test User1,terestuser1@abc.com\" :/home/tester1:/bin/bash tester1:x:600:1530: \"Test User1,testuser1@abc.com\" :/home/tester1:/bin/bash \u4f53\u4f1a & \u7684\u4f4d\u7f6e\u4e0d\u540c\u7684\u4e0d\u540c\u542b\u4e49\u3002 # \u9644\u52a0\u5728root\u5355\u8bcd\u540e $ sed -n 's/root/&superman/p' /etc/passwd rootsuperman:x:0:0:root:/root:/bin/bash # \u9644\u52a0\u5728root\u5355\u8bcd\u524d $ sed -n 's/root/superman&/p' /etc/passwd supermanroot:x:0:0:root:/root:/bin/bash \u4f7f\u7528\u53c2\u6570 -i \u8fdb\u884c\u6e90\u6587\u4ef6\u4fee\u6539\u3002 $ sed -i 's/ao/HH/' testfile $ cat testfile HELLO LINUX! Linux is a free unix-type opterating system. This is a linux testfile! Linux test Google THHbao Banbooob Tesetfile Wiki \u6e90\u6587\u4ef6\u4fee\u6539\u524d\uff0c\u5907\u4efd\u5728\u65b0\u6587\u4ef6 testfile.new \u3002 $ sed -i.new 's/ao/HH/' testfile $ cat testfile.new HELLO LINUX! Linux is a free unix-type opterating system. This is a linux testfile! Linux test Google Taobao Banbooob Tesetfile Wiki $ cat testfile HELLO LINUX! Linux is a free unix-type opterating system. This is a linux testfile! Linux test Google THHbao Banbooob Tesetfile Wiki \u8303\u4f8b\uff1a\u9664\u6307\u5b9a\u6587\u4ef6\u5916\uff0c\u5176\u4f59\u90fd\u5220\u9664\u3002 $ touch { 1 ..9 } file.txt $ ls 1file.txt 2file.txt 3file.txt 4file.txt 5file.txt 6file.txt 7file.txt 8file.txt 9file.txt $ ls | grep -E '(3|5|7)file\\.txt' 3file.txt 5file.txt 7file.txt $ ls | grep -Ev '(3|5|7)file\\.txt' 1file.txt 2file.txt 4file.txt 6file.txt 8file.txt 9file.txt \u4e0b\u9762\u56db\u79cd\u65b9\u6cd5\u5b9e\u73b0\u540c\u6837\u7684\u529f\u80fd $ rm ` ls | grep -Ev '(3|5|7)file\\.txt' ` $ ls | sed -n '/^[357]file.txt/!p' | xargs rm $ ls | grep -Ev '(3|5|7)file\\.txt' | sed -n 's/.*/rm &/p' | bash $ ls | grep -Ev '(3|5|7)file\\.txt' | sed -En 's/(.*)/rm &/p' | bash $ ls | grep -Ev '(3|5|7)file\\.txt' | sed -En 's/(.*)/rm \\1/p' | bash $ ls 3file.txt 5file.txt 7file.txt \u540e\u5411\u5f15\u7528 \\0 \\1 \\2 \u7b49\u3002 $ $echo 123456789 | sed -nE 's/(123)(456)(789)/\\1/p' 123 $ echo 123456789 | sed -nE 's/(123)(456)(789)/\\2/p' 456 $ echo 123456789 | sed -nE 's/(123)(456)(789)/\\3/p' 789 $ echo 123456789 | sed -nE 's/(123)(456)(789)/\\3\\1\\2/p' 789123456 $ echo 123456789 | sed -nE 's/(123)(456)(789)/\\1xyz\\2/p' 123xyz456 \u8303\u4f8b\uff1a\u83b7\u53d6\u5206\u533a\u5229\u7528\u7387 $ df | sed -En '/^\\/dev\\/sd/p' /dev/sda2 102750208 7079236 92053692 8 % / /dev/sda2 102750208 7079236 92053692 8 % /.snapshots /dev/sda2 102750208 7079236 92053692 8 % /boot/grub2/i386-pc /dev/sda2 102750208 7079236 92053692 8 % /boot/grub2/x86_64-efi /dev/sda2 102750208 7079236 92053692 8 % /home /dev/sda2 102750208 7079236 92053692 8 % /opt /dev/sda2 102750208 7079236 92053692 8 % /root /dev/sda2 102750208 7079236 92053692 8 % /srv /dev/sda2 102750208 7079236 92053692 8 % /usr/local /dev/sda2 102750208 7079236 92053692 8 % /tmp /dev/sda2 102750208 7079236 92053692 8 % /var $ df | sed -En '/^\\/dev\\/sd/s@.*([0-9]+)%.*@\\1@p' $ df | sed -En '/^\\/dev\\/sd/s#.*([0-9]+)%.*#\\1#p' # df | sed -En '/^\\/dev\\/sd/s/.*([0-9]+)%.*/\\1/p' 8 8 8 8 8 8 8 8 8 8 8 \u4f53\u4f1a\u4e0b\u9762\u7a7a\u683c\u548c\u62ec\u5f27\u5e26\u6765\u7684\u4e0d\u540c\u3002 $ df | sed -En '/^\\/dev\\/sd/s# .*([0-9]+)%.*# \\1#p' /dev/sda2 8 /dev/sda2 8 /dev/sda2 8 /dev/sda2 8 /dev/sda2 8 /dev/sda2 8 /dev/sda2 8 /dev/sda2 8 /dev/sda2 8 /dev/sda2 8 /dev/sda2 8 $ df | sed -En '/^\\/dev\\/sd/s#( .*)([0-9]+)%.*# \\1#p' /dev/sda2 102750208 7079804 92053156 /dev/sda2 102750208 7079804 92053156 /dev/sda2 102750208 7079804 92053156 /dev/sda2 102750208 7079804 92053156 /dev/sda2 102750208 7079804 92053156 /dev/sda2 102750208 7079804 92053156 /dev/sda2 102750208 7079804 92053156 /dev/sda2 102750208 7079804 92053156 /dev/sda2 102750208 7079804 92053156 /dev/sda2 102750208 7079804 92053156 /dev/sda2 102750208 7079804 92053156 $ df | sed -En '/^\\/dev\\/sd/s#( .*)([0-9]+)%.*# \\2#p' /dev/sda2 8 /dev/sda2 8 /dev/sda2 8 /dev/sda2 8 /dev/sda2 8 /dev/sda2 8 /dev/sda2 8 /dev/sda2 8 /dev/sda2 8 /dev/sda2 8 /dev/sda2 8 \u8303\u4f8b\uff1a\u53d6\u5f97\u5f53\u524dIP\u5730\u5740\u3002 $ ifconfig eth0 eth0: flags = 4163 mtu 1500 inet 192 .168.10.210 netmask 255 .255.255.0 broadcast 192 .168.10.255 inet6 fe80::20c:29ff:fea4:e17a prefixlen 64 scopeid 0x20 ether 00 :0c:29:a4:e1:7a txqueuelen 1000 ( Ethernet ) RX packets 22923 bytes 1658298 ( 1 .5 MiB ) RX errors 0 dropped 0 overruns 0 frame 0 TX packets 3763 bytes 442641 ( 432 .2 KiB ) TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0 $ ip addr show eth0 2 : eth0: mtu 1500 qdisc pfifo_fast state UP group default qlen 1000 link/ether 00 :0c:29:a4:e1:7a brd ff:ff:ff:ff:ff:ff altname enp2s1 altname ens33 inet 192 .168.10.210/24 brd 192 .168.10.255 scope global eth0 valid_lft forever preferred_lft forever inet6 fe80::20c:29ff:fea4:e17a/64 scope link valid_lft forever preferred_lft forever $ ifconfig eth0 | sed -En '2s/[^0-9]+([0-9.]+).*/\\1/p' $ ifconfig eth0 | sed -En '2s/^[^0-9]+([0-9.]{7,15}).*/\\1/p' $ ifconfig eth0 | sed -En '2s/^[^0-9]+([0-9.]{7,15}).*$/\\1/p' $ ifconfig eth0 | sed -n '2s/^.*inet //p' | sed -n 's/netmask.*//p' $ ifconfig eth0 | sed -n '2s/^.*inet //;s/ netmask.*//p' $ ifconfig eth0 | sed -En '2s/(.*inet )([0-9].*)(netmask.*)/\\2/p' 192 .168.10.210 192 .168.10.210 192 .168.10.210 \u4f7f\u7528 \\0 \u8f93\u51fa\u5168\u90e8\u53d8\u91cf\u3002 $ ifconfig eth0 | sed -En '2s/(.*inet )([0-9].*)(netmask.*)/\\0/p' inet 192 .168.10.210 netmask 255 .255.255.0 broadcast 192 .168.10.255 $ ifconfig eth0 | sed -En '2s/(.*inet )([0-9].*)(netmask.*)/\\1/p' inet $ ifconfig eth0 | sed -En '2s/(.*inet )([0-9].*)(netmask.*)/\\2/p' 192 .168.10.210 $ ifconfig eth0 | sed -En '2s/(.*inet )([0-9].*)(netmask.*)/\\3/p' netmask 255 .255.255.0 broadcast 192 .168.10.255 \u5bf9\u6bd4\u4e0b\u9762\u4e24\u4e2a\u6307\u4ee4\u7684\u5339\u914d\u5dee\u5f02\u3002 $ ifconfig eth0 | sed -n '2s/^.*inet //p' | sed -n 's/ netmask.*//p' 192 .168.10.210 $ ifconfig eth0 | sed -n '2s/^.*inet //p' | sed -n 's/netmask.* //p' 192 .168.10.210 192 .168.10.255 $ ifconfig eth0 | sed -n '2s/^.*inet //p' | sed -n 's/netmask .*//p' 192 .168.10.210 $ ifconfig eth0 | sed -n '2s/^.*inet //p' | sed -n 's/netmask.*//p' 192 .168.10.210 \u8303\u4f8b\uff1a\u53d6\u57fa\u540d\u548c\u76ee\u5f55\u540d\u3002 \uff08 /etc/sysconfig/network-scripts/ \u76ee\u5f55\u5728Rocky9\u4e2d\u9ed8\u8ba4\u5df2\u521b\u5efa\uff0c\u5728openSUSE\u548cUbuntu\u4e2d\u6ca1\u6709\uff09 # \u53d6\u76ee\u5f55\u540d $ echo \"/etc/sysconfig/network-scripts/\" | sed -E 's#(^/.*/)([^/]+/?)#\\1#' $ echo \"/etc/sysconfig/network-scripts/\" | sed -E 's/(^\\/.*\\/)([^\\/]+\\/?)/\\1/' /etc/sysconfig/ # \u53d6\u57fa\u540d $ echo \"/etc/sysconfig/network-scripts/\" | sed -E 's#(^/.*/)([^/]+/?)#\\2#' $ echo \"/etc/sysconfig/network-scripts/\" | sed -E 's/(^\\/.*\\/)([^\\/]+\\/?)/\\2/' network-scripts/ # \u53d6\u76ee\u5f55\u540d $ echo \"/etc/sysconfig/network-scripts/dummyfile\" | sed -E 's#(^/.*/)([^/]+/?)#\\1#' $ echo \"/etc/sysconfig/network-scripts/dummyfille\" | sed -E 's/(^\\/.*\\/)([^\\/]+\\/?)/\\1/' /etc/sysconfig/network-scripts/ # \u53d6\u57fa\u540d $ echo \"/etc/sysconfig/network-scripts/dummyfile\" | sed -E 's#(^/.*/)([^/]+/?)#\\2#' $ echo \"/etc/sysconfig/network-scripts/dummyfille\" | sed -E 's/(^\\/.*\\/)([^\\/]+\\/?)/\\2/' dummyfille \u8303\u4f8b\uff1a\u53d6\u6587\u4ef6\u540d\u548c\u6587\u4ef6\u6269\u5c55\u540d $ echo 1_.file.tar.gz | sed -En 's/(.*)\\.([^.]+)$/\\1/p' $ echo 1_.file.tar.gz | sed -En 's@(.*)\\.([^.]+)$@\\1@p' 1_.file.tar $ echo 1_.file.tar.gz | sed -En 's/(.*)\\.([^.]+)$/\\2/p' $ echo 1_.file.tar.gz | sed -En 's@(.*)\\.([^.]+)$@\\2@p' gz $ echo 1_.file.tar.gz | grep -Eo '.*\\.' 1_.file.tar. $ echo 1_.file.tar.gz | grep -Eo '[^.]+$' gz \u8303\u4f8b\uff1a\u5c06\u975e # \u5f00\u5934\u7684\u884c\u6dfb\u52a0 # $ cat < testfile HELLO LINUX! Linux is a free unix-type opterating system. This is a linux testfile! Linux test Google Taobao Banbooob #Tesetfile #Wiki EOF $ sed -En 's/^[^#]/#&/p' testfile $ sed -En 's/^[^#](.*)/#\\1/p' testfile #HELLO LINUX! #Linux is a free unix-type opterating system. #This is a linux testfile! #Linux test #Google #Taobao #Banbooob \u8303\u4f8b\uff1a\u5c06 # \u5f00\u5934\u7684\u884c\u5220\u9664 # $ cat < testfile HELLO LINUX! Linux is a free unix-type opterating system. This is a linux testfile! Linux test Google Taobao Banbooob #Tesetfile #Wiki EOF $ sed -Ei.bak '/^#/s/^#//' testfile $ cat testfile HELLO LINUX! Linux is a free unix-type opterating system. This is a linux testfile! Linux test Google Taobao Banbooob Tesetfile Wiki sed \u4fdd\u6301\u7a7a\u95f4\uff08hold space\uff09\u7684\u4f8b\u5b50\uff1a d \uff1a\u5220\u9664pattern space\u7684\u5185\u5bb9\uff0c\u5f00\u59cb\u4e0b\u4e00\u4e2a\u5faa\u73af\u3002 D \uff1a\u5982\u679c\u6a21\u5f0f\u7a7a\u95f4\u4fdd\u62a4\u6362\u884c\u7b26\uff0c\u5219\u5220\u9664\u76f4\u5230\u7b2c\u4e00\u4e2a\u6362\u884c\u7b26\u5230\u6a21\u5f0f\u7a7a\u95f4\u4e2d\u7684\u6587\u672c\uff0c\u5e76\u4e0d\u8bfb\u53d6\u65b0\u7684\u8f93\u5165\u884c\uff0c\u800c\u4f7f\u7528\u5408\u6210\u7684\u6a21\u5f0f\u7a7a\u95f4\u91cd\u65b0\u542f\u52a8\u5faa\u73af\u3002\u5982\u679c\u6a21\u5f0f\u7a7a\u95f4\u4e0d\u5305\u542b\u6362\u884c\u7b26\uff0c\u5219\u7c7b\u4f3c d \u547d\u4ee4\u542f\u52a8\u6b63\u5e38\u7684\u65b0\u5faa\u73af\u3002 h \u3001 H \uff1a\u590d\u5236/\u8ffd\u52a0\u6a21\u5f0f\u7a7a\u95f4\u7684\u5185\u5bb9\u5230\u4fdd\u6301\u7a7a\u95f4\u3002 g \u3001 G \uff1a\u590d\u5236/\u8ffd\u52a0\u4fdd\u6301\u7a7a\u95f4\u7684\u5185\u5bb9\u5230\u6a21\u5f0f\u7a7a\u95f4\u3002 n \u3001 N \uff1a\u590d\u5236/\u8ffd\u52a0\u5339\u914d\u5230\u7684\u4e0b\u4e00\u884c\u5230\u6a21\u5f0f\u7a7a\u95f4\u3002 p\uff1a\u6253\u5370\u5f53\u524d\u6a21\u5f0f\u7a7a\u95f4\u5185\u5bb9\u3002 P\uff1a\u6253\u5370\u6a21\u5f0f\u7a7a\u95f4\u5f00\u5934\u81f3 \\n \u7684\u5185\u5bb9\uff0c\u5e76\u8ffd\u52a0\u5230\u9ed8\u8ba4\u8f93\u51fa\u4e4b\u524d\u3002 x \uff1a\u4ea4\u6362\u4fdd\u6301\u7a7a\u95f4\u548c\u6a21\u5f0f\u7a7a\u95f4\u7684\u5185\u5bb9. \u4e3e\u4f8b\u89e3\u8bfb1\uff1a seq 10 \u547d\u4ee4\u8f93\u51fa1\uff5e10\u4e2a\u6570\u5b57\uff0c\u6bcf\u4e2a\u6570\u5b57\u4e00\u884c\u3002 sed \u547d\u4ee4\u8bfb\u53d6\u7b2c\u4e00\u884c 1 \u5230\u6a21\u5f0f\u7a7a\u95f4\u3002\u56e0\u4e3a\u53c2\u6570 -n \uff0c\u6240\u4ee5\u8bfb\u53d6\u5230\u7684 1 \u4e0d\u6253\u5370\u5230\u5c4f\u5e55\u3002 \u6267\u884c n \u547d\u4ee4\uff0c\u5373\u8bfb\u53d6\u5339\u914d\u5230\u7684\u4e0b\u4e00\u884c\u5230\u6a21\u5f0f\u7a7a\u95f4\uff0c\u5373\u628a\u7b2c\u4e8c\u884c\u7684 2 \u8bfb\u53d6\u5e76\u8986\u76d6\u5230\u6a21\u5f0f\u7a7a\u95f4\u3002 \u6267\u884c p \u547d\u4ee4\uff0c\u628a 2 \u8f93\u51fa\u5230\u5c4f\u5e55\u3002 \u4ee5\u6b64\u7c7b\u63a8\uff0c\u8bfb\u53d6\u7b2c\u4e09\u884c\u7684 3 \u5230\u6a21\u5f0f\u7a7a\u95f4\uff0c\u6267\u884c n \u547d\u4ee4\uff0c\u5c06\u7b2c\u56db\u884c\u7684 4 \u8bfb\u53d6\u5e76\u8986\u76d6\u5230\u6a21\u5f0f\u7a7a\u95f4\u3002\u6267\u884c p \u547d\u4ee4\uff0c\u8f93\u51fa 4 \u5230\u5c4f\u5e55\u3002 \u4ee5\u6b64\u7c7b\u63a8\u3002 $ seq 10 | sed -n 'n;p' 2 4 6 8 10 seq 10 | sed 'n;p' 1 2 2 3 4 4 5 6 6 7 8 8 9 10 10 \u4e3e\u4f8b\u89e3\u8bfb2\uff1a seq 10 \u547d\u4ee4\u8f93\u51fa1\uff5e10\u4e2a\u6570\u5b57\uff0c\u6bcf\u4e2a\u6570\u5b57\u4e00\u884c\u3002 sed \u547d\u4ee4\u8bfb\u53d6\u7b2c\u4e00\u884c\u5230 1 \u5230\u6a21\u5f0f\u7a7a\u95f4\uff08\u8986\u76d6\uff09\u3002 \u6267\u884c\u547d\u4ee4 N \uff0c\u5373\u8bfb\u53d6\u4e0b\u4e00\u884c\uff0c\u5373\u7b2c\u4e8c\u884c\u7684 2 \uff0c\u8ffd\u52a0\u5230\u6a21\u5f0f\u7a7a\u95f4\u3002\u6240\u4ee5\u5f53\u524d\u6a21\u5f0f\u7a7a\u95f4\u6709 1 \u548c 2 \u8fd92\u884c\u8bb0\u5f55\u3002 \u6267\u884c s/\\n// \uff0c\u628a\u6a21\u5f0f\u7a7a\u95f4\u4e2d\u7684\u7b2c\u4e00\u884c\u7684 1 \u540e\u9762\u7684 \\n \u66ff\u6362\u4e3a\u7a7a\uff0c\u5373\uff0c\u539f\u6765\u6a21\u5f0f\u7a7a\u95f4\u7684\u4e24\u884c 1 \u548c 2 \u73b0\u5728\u5408\u5e76\u4e3a\u4e00\u884c\uff0c\u5373 12 \u3002 \u8bfb\u53d6\u7b2c\u4e09\u884c\u7684 3 \u5230\u6a21\u5f0f\u7a7a\u95f4\uff08\u8986\u76d6\uff09\u3002 \u6267\u884c\u547d\u4ee4 N \uff0c\u5373\u8bfb\u53d6\u4e0b\u4e00\u884c\uff0c\u5373\u7b2c\u56db\u884c\u7684 4 \uff0c\u8ffd\u52a0\u5230\u6a21\u5f0f\u7a7a\u95f4\u3002\u6240\u4ee5\u5f53\u524d\u6a21\u5f0f\u7a7a\u95f4\u6709 3 \u548c 4 \u8fd92\u884c\u8bb0\u5f55\u3002 \u6267\u884c s/\\n// \uff0c\u628a\u6a21\u5f0f\u7a7a\u95f4\u4e2d\u7684\u7b2c\u4e00\u884c 3 \u540e\u9762\u7684 \\n \u66ff\u6362\u4e3a\u7a7a\uff0c\u5373\uff0c\u539f\u6765\u6a21\u5f0f\u7a7a\u95f4\u7684\u4e24\u884c 3 \u548c 4 \u73b0\u5728\u5408\u5e76\u4e3a\u4e00\u884c\uff0c\u5373 34 \u3002 \u4ee5\u6b64\u7c7b\u63a8\u3002 $ seq 10 | sed 'N;s/\\n//' 12 34 56 78 910 \u4e3e\u4f8b\u89e3\u8bfb3\uff1a seq 10 \u547d\u4ee4\u8f93\u51fa1\uff5e10\u4e2a\u6570\u5b57\uff0c\u6bcf\u4e2a\u6570\u5b57\u4e00\u884c\u3002 sed \u547d\u4ee4\u8bfb\u53d6\u7b2c\u4e00\u884c\u5230 1 \u5230\u6a21\u5f0f\u7a7a\u95f4\uff08\u8986\u76d6\uff09\u3002 \u6267\u884c !G \uff0c\u5373\u5bf9\u7b2c\u4e00\u884c\u7684 1 \u4e0d\u6267\u884c G \u547d\u4ee4\u3002 \u6267\u884c h \u547d\u4ee4\uff0c\u5373\u628a 1 \u4ece\u6a21\u5f0f\u7a7a\u95f4\u8986\u76d6\u81f3\u4fdd\u6301\u7a7a\u95f4\u3002\u81f3\u6b64\uff0c\u4fdd\u6301\u7a7a\u95f4\u548c\u6a21\u5f0f\u7a7a\u95f4\u90fd\u5b58\u6709 1 \u3002 \u6267\u884c $!d \uff0c\u5373\u4e0d\u662f\u6700\u540e\u4e00\u884c\u5c31\u4ece\u6a21\u5f0f\u7a7a\u95f4\u5220\u9664\uff0c\u6240\u4ee5\u628a 1 \u4ece\u6a21\u5f0f\u7a7a\u95f4\u4e2d\u5220\u9664\u3002 sed \u547d\u4ee4\u8bfb\u53d6\u7b2c\u4e8c\u884c\u5230 2 \u5230\u6a21\u5f0f\u7a7a\u95f4\uff08\u8986\u76d6\uff09\u3002 \u6267\u884c !G \uff0c\u5373\u5bf9\u7b2c\u4e8c\u884c\u7684 2 \u6267\u884c G \u547d\u4ee4\uff0c\u628a 1 \u4ece\u4fdd\u6301\u7a7a\u95f4\u8ffd\u52a0\u5230\u6a21\u5f0f\u7a7a\u95f4\u3002\u81f3\u6b64\uff0c\u4fdd\u6301\u7a7a\u95f4\u5b58\u6709 1 \uff0c\u6a21\u5f0f\u7a7a\u95f4\u5b58\u6709 2 \u548c 1 \u3002 \u6267\u884c h \u547d\u4ee4\uff0c\u5373\u628a 2 \u548c 1 \u4ece\u6a21\u5f0f\u7a7a\u95f4\u8986\u76d6\u81f3\u4fdd\u6301\u7a7a\u95f4\u3002\u81f3\u6b64\uff0c\u4fdd\u6301\u7a7a\u95f4\u548c\u6a21\u5f0f\u7a7a\u95f4\u90fd\u5b58\u6709 2 \u548c 1 \u3002 \u6267\u884c $!d \uff0c\u5373\u4e0d\u662f\u6700\u540e\u4e00\u884c\u5c31\u4ece\u6a21\u5f0f\u7a7a\u95f4\u5220\u9664\uff0c\u6240\u4ee5\u628a 2 \u548c 1 \u4ece\u6a21\u5f0f\u7a7a\u95f4\u4e2d\u5220\u9664\u3002 \u4ee5\u6b64\u7c7b\u63a8\uff0c\u76f4\u81f3\u8bfb\u53d6\u6700\u540e\u4e00\u884c10\u3002\u6b64\u65f6\uff0c\u6a21\u5f0f\u7a7a\u95f4\u662f 10 \uff0c\u4fdd\u6301\u7a7a\u95f4\u5b58\u6709 9 \u3001 8 \u3001 7 \u3001 6 \u3001 5 \u3001 4 \u3001 3 \u3001 2 \u3001 1 \u3002 \u6267\u884c !G \uff0c\u5373\u5bf9\u6700\u540e\u4e00\u884c\u7684 10 \u6267\u884c G \u547d\u4ee4\uff0c\u628a 9 \u3001 8 \u3001 7 \u3001 6 \u3001 5 \u3001 4 \u3001 3 \u3001 2 \u3001 1 \u4ece\u4fdd\u6301\u7a7a\u95f4\u8ffd\u52a0\u5230\u6a21\u5f0f\u7a7a\u95f4\u3002\u81f3\u6b64\uff0c\u4fdd\u6301\u7a7a\u95f4\u5b58\u6709 9 \u3001 8 \u3001 7 \u3001 6 \u3001 5 \u3001 4 \u3001 3 \u3001 2 \u3001 1 \u3002\uff0c\u6a21\u5f0f\u7a7a\u95f4\u5b58\u6709 10 \u3001 9 \u3001 8 \u3001 7 \u3001 6 \u3001 5 \u3001 4 \u3001 3 \u3001 2 \u3001 1 \u3002 \u6267\u884c h \u547d\u4ee4\uff0c\u5373\u628a 10 \u3001 9 \u3001 8 \u3001 7 \u3001 6 \u3001 5 \u3001 4 \u3001 3 \u3001 2 \u3001 1 \u4ece\u6a21\u5f0f\u7a7a\u95f4\u8986\u76d6\u81f3\u4fdd\u6301\u7a7a\u95f4\u3002\u81f3\u6b64\uff0c\u4fdd\u6301\u7a7a\u95f4\u548c\u6a21\u5f0f\u7a7a\u95f4\u90fd\u5b58\u6709 10 \u3001 9 \u3001 8 \u3001 7 \u3001 6 \u3001 5 \u3001 4 \u3001 3 \u3001 2 \u3001 1 \u3002 \u6267\u884c $!d \uff0c\u5f53\u524d\u662f\u6700\u540e\u4e00\u884c\uff0c\u6240\u4ee5\u4e0d\u4ece\u6a21\u5f0f\u7a7a\u95f4\u5220\u9664\u5f53\u524d\u5185\u5bb9\u3002 \u8f93\u51fa\u6a21\u5f0f\u7a7a\u95f4\u5185\u5bb9\u81f3\u5c4f\u5e55\u3002\u537310\uff5e1\u3002 $ seq 10 | sed '1!G;h;$!d' 10 9 8 7 6 5 4 3 2 1 \u5176\u4ed6\u4e00\u4e9b\u4f8b\u5b50\uff1a $ seq 10 | sed -n '/3/{g;1!p;};h' 2 $ seq 10 | sed -nr '/3/{n;p}' 4 $ seq 10 | sed 'N;D' 10 $ seq 10 | sed '3h;9G;9!d' 9 3 $ seq 10 | sed '$!N;$!D' 9 10 $ seq 10 | sed '$!d' 10 $ seq 10 | sed 'G' 1 2 3 4 5 6 7 8 9 10 $ seq 10 | sed 'g' $ seq 10 | sed '/^$/d;G' 1 2 3 4 5 6 7 8 9 10 $ seq 10 | sed 'n;d' 1 3 5 7 9 $ seq 10 | sed -n '1!G;h;$p' 10 9 8 7 6 5 4 3 2 1","title":"5.9.\u4e09\u5251\u5ba2sed\u547d\u4ee4"},{"location":"linux/SRE/05-RegExpress/#510awk","text":"awk \u662f\u4e00\u4e2a\u6587\u672c\u5206\u6790\u5de5\u5177\u3002 grep \u64c5\u957f\u67e5\u627e\uff0c sed \u64c5\u957f\u7f16\u8f91\uff0c awk \u64c5\u957f\u6570\u636e\u5206\u6790\u5e76\u751f\u6210\u62a5\u544a\u3002 awk \u7684\u540d\u79f0\u5f97\u81ea\u4e8e\u5b83\u7684\u521b\u59cb\u4ebaAlfred Aho \u3001Peter Weinberger \u548c Brian Kernighan \u59d3\u6c0f\u7684\u9996\u4e2a\u5b57\u6bcd\u3002 awk \u67093\u4e2a\u4e0d\u540c\u7248\u672c: awk \u3001 nawk \u548c gawk \u3002\u6211\u4eec\u8bf4\u7684 awk \u4e00\u822c\u6307 gawk \u3002 gawk \u662f awk \u7684GNU\u7248\u672c\u3002 awk \u628a\u6587\u4ef6\u9010\u884c\u8bfb\u5165\uff0c\u4ee5\u7a7a\u683c\u4e3a\u9ed8\u8ba4\u5206\u9694\u7b26\u5c06\u6bcf\u884c\u5207\u7247\uff0c\u518d\u5bf9\u5207\u7247\u8fdb\u884c\u5206\u6790\u5904\u7406\u3002","title":"5.10.\u4e09\u5251\u5ba2awk\u547d\u4ee4"},{"location":"linux/SRE/05-RegExpress/#5101","text":"awk 'pattern{action statements;...}' {filenames} pattern \u8868\u793a awk \u5728\u6570\u636e\u4e2d\u67e5\u627e\u7684\u5185\u5bb9\u3002\u662f\u8981\u8868\u793a\u7684\u6b63\u5219\u8868\u8fbe\u5f0f\uff0c\u7528\u659c\u6760\u62ec\u8d77\u6765\u3002 action \u662f\u5728\u627e\u5230\u5339\u914d\u5185\u5bb9\u65f6\u6240\u6267\u884c\u7684\u4e00\u7cfb\u5217\u547d\u4ee4\u3002 -F \uff1a\u6307\u5b9a\u5206\u9694\u7b26\uff0c\u540e\u9762\u7d27\u8ddf\u5355\u5f15\u53f7\uff0c\u5355\u5f15\u53f7\u5185\u662f\u5206\u9694\u7b26\u3002\u5982\u4e0d\u52a0 -F \u9009\u9879\uff0c\u5219\u4ee5\u7a7a\u683c\u6216\u8005tab\u4f5c\u4e3a\u5206\u9694\u7b26\u3002 -v \uff1avar=value\uff0c\u53d8\u91cf\u8d4b\u503c\u3002 \u63d0\u793a\uff1a -F \"\" \u6307\u5b9a\u7a7a\u5b57\u7b26\u4e32\u4f5c\u4e3a\u5b57\u6bb5\u5206\u9694\u7b26\uff0c\u4ece\u800c\u5c06\u8f93\u5165\u5b57\u7b26\u4e32\u4e2d\u7684\u6bcf\u4e2a\u5b57\u7b26\u4f5c\u4e3a\u4e00\u4e2a\u72ec\u7acb\u7684\u5b57\u6bb5\u8fdb\u884c\u5904\u7406\u3002\u7136\u540e\uff0c\u4f7f\u7528\u5faa\u73af\u904d\u5386\u6bcf\u4e2a\u5b57\u6bb5\uff0c\u5982\u679c\u5b57\u6bb5\u4e2d\u5305\u542b\u6570\u5b57\uff0c\u5219\u5c06\u5176\u6dfb\u52a0\u5230str1\u53d8\u91cf\u4e2d\u3002\u6700\u540e\uff0c\u6253\u5370str1\u7684\u503c\u3002 -F '' \u4e2d\u7684\u4e24\u4e2a\u5355\u5f15\u53f7\u4e4b\u95f4\u6ca1\u6709\u63d0\u4f9b\u6709\u6548\u7684\u5b57\u6bb5\u5206\u9694\u7b26\u3002\u5728awk\u4e2d\uff0c\u5b57\u6bb5\u5206\u9694\u7b26\u5fc5\u987b\u662f\u4e00\u4e2a\u975e\u7a7a\u5b57\u7b26\u4e32\u3002 \u793a\u4f8b\uff1a\u7b2c\u4e00\u4e2a\u548c\u7b2c\u4e09\u4e2a\u547d\u4ee4\u662f\u6b63\u786e\u7684\u3002 $ echo 'Yd$@C#M05MD9&8923+Vip3wZ!33*44&55' | awk -F \"\" '{for(i=1;i<=NF;i++){if($i ~ /[[:digit:]]/){str=$i;str1=(str1 str)}};print str1}' 05989233334455 $ echo 'Yd$@C#M05MD9&8923+Vip3wZ!33*44&55' | awk -F \"\" '{for(i=1;i<=NF;i++){if($i ~ /[[:digit:]]/){str=$i;str1=(str1 str)}};print str1}' $ echo 'Yd$@C#M05MD9&8923+Vip3wZ!33*44&55' | awk -F '' '{for(i=1;i<=NF;i++){if($i ~ /[[:digit:]]/){str=$i;str1=(str1 str)}};print str1}' 05989233334455 $ echo 'Yd$@C#M05MD9&8923+Vip3wZ!33*44&55' | awk -F '' '{for(i=1;i<=NF;i++){if($i ~ /[[:digit:]]/){str=$i;str1=(str1 str)}};print str1}'","title":"5.10.1.\u547d\u4ee4\u683c\u5f0f"},{"location":"linux/SRE/05-RegExpress/#5102","text":"\u6267\u884cBEGIN{action;...}\u8bed\u53e5\u5757\u4e2d\u7684\u8bed\u53e5\u3002 BEGIN\u8bed\u53e5\u5757\u518dawk\u8bfb\u5165\u8f93\u5165\u6d41\u4e4b\u524d\u88ab\u6267\u884c\u3002 \u662f\u53ef\u9009\u8bed\u53e5\u5757\u3002 \u5305\u542b\u521d\u59cb\u5316\u53d8\u91cf\uff0c\u6253\u5370\u8f93\u51fa\u8868\u683c\u7684\u8868\u5934\u7b49\u8bed\u53e5\u3002 \u4ece\u6587\u4ef6\u6216\u8005\u6807\u51c6\u8f93\u5165stdin\u8bfb\u53d6\u4e00\u884c\uff0c\u7136\u540e\u6267\u884cpattern{action;...}\u8bed\u53e5\u5757\u3002\u4ece\u7b2c\u4e00\u884c\u5f00\u59cb\u5230\u6700\u540e\u4e00\u884c\uff0c\u9010\u884c\u626b\u63cf\u6587\u4ef6\uff0c\u91cd\u590d\u8fd9\u4e2a\u52a8\u4f5c\uff0c\u76f4\u5230\u6587\u4ef6\u6216\u8005\u8f93\u5165\u6d41\u5168\u90e8\u88ab\u8bfb\u53d6\u5b8c\u6bd5\u3002 \u53ef\u9009\u8bed\u53e5\u5757\u3002 \u5982\u679c\u6ca1\u6709\u63d0\u4f9bpattern\u8bed\u53e5\u5757\uff0c\u5219\u9ed8\u8ba4\u6267\u884c{print}\u3002 \u5f53\u8bfb\u81f3\u6587\u4ef6\u6216\u8005\u8f93\u5165\u6d41\u672b\u5c3e\u65f6\uff0c\u6267\u884cEND{action;...}\u8bed\u53e5\u5757\uff0c\u6bd4\u5982\u6253\u5370\u6240\u6709\u884c\u7684\u5206\u6790\u7ed3\u679c\u8fd9\u7c7b\u6c47\u603b\u4fe1\u606f\u3002\u4e5f\u662f\u4e00\u4e2a\u53ef\u9009\u8bed\u53e5\u5757\u3002","title":"5.10.2.\u5de5\u4f5c\u8fc7\u7a0b"},{"location":"linux/SRE/05-RegExpress/#5103","text":"\u6709\u5206\u9694\u7b26\u5206\u9694\u7684\u5b57\u6bb5\uff08\u5217column\uff0c\u57dffield\uff09\uff0c\u6807\u8bb0 $1 \u3001 $2 \u3001 $3 \u3001...\u3001 $n \u79f0\u4e3a\u57df\u6807\u8bc6\uff0c $0 \u4e3a\u6240\u6709\u57df\u3002\u6ce8\u610f\uff0c\u548cshell\u53d8\u91cf\u4e2d\u7684 $ \u4e0d\u540c\u3002 \u6bcf\u4e00\u884c\u6210\u4e3a\u8bb0\u5f55\uff08record\uff09\u3002 \u5982\u679c\u7701\u7565action\uff0c\u5219\u9ed8\u8ba4\u6267\u884c print $0 \u64cd\u4f5c\u3002","title":"5.10.3.\u5206\u9694\u7b26\u3001\u57df\u548c\u8bb0\u5f55"},{"location":"linux/SRE/05-RegExpress/#5104action","text":"Output statements: print , printf Expressions: \u7b97\u672f\u3001\u6bd4\u8f83\u8868\u8fbe\u5f0f Compund statements: \u7ec4\u5408\u8bed\u53e5 Control statements: if , while \u8bed\u53e5 Input statements: \u52a8\u4f5c print \u683c\u5f0f\uff1a print item1, item2, ... \u8bf4\u660e\uff1a \u9017\u53f7\u5206\u9694\u7b26 \u8f93\u51faitem\u53ef\u4ee5\u662f\u5b57\u7b26\u4e32\uff0c\u4e5f\u53ef\u4ee5\u662f\u6570\u503c\uff0c\u662f\u5f53\u524d\u8bb0\u5f55\u7684\u5b57\u6bb5\u3001\u53d8\u91cf\u6216 awk \u8868\u8fbe\u5f0f\u3002 \u5982\u679c\u7701\u7565item\uff0c\u76f8\u5f53\u4e8e print $0 \u56fa\u5b9a\u5b57\u7b26\u9700\u8981\u7528\u53cc\u5f15\u53f7\uff0c\u800c\u53d8\u91cf\u548c\u6570\u5b57\u4e0d\u9700\u8981\u3002 \u793a\u4f8b\uff1a $ seq 5 | awk '{print \"hello awk\"}' hello awk hello awk hello awk hello awk hello awk $ seq 5 | awk '{print 3*5}' 15 15 15 15 15 $ awk -F ':' '{print \"hello\"}' /etc/passwd | head -5 hello hello hello hello hello $ awk -F ':' '{print}' /etc/passwd | head -5 root:x:0:0:root:/root:/bin/bash messagebus:x:499:499:User for D-Bus:/run/dbus:/usr/bin/false systemd-network:x:497:497:systemd Network Management:/:/usr/sbin/nologin systemd-timesync:x:496:496:systemd Time Synchronization:/:/usr/sbin/nologin nobody:x:65534:65534:nobody:/var/lib/nobody:/bin/bash $ awk -F ':' '{print $0}' /etc/passwd | head -5 root:x:0:0:root:/root:/bin/bash messagebus:x:499:499:User for D-Bus:/run/dbus:/usr/bin/false systemd-network:x:497:497:systemd Network Management:/:/usr/sbin/nologin systemd-timesync:x:496:496:systemd Time Synchronization:/:/usr/sbin/nologin nobody:x:65534:65534:nobody:/var/lib/nobody:/bin/bash $ awk -F ':' '{print $1,$3}' /etc/passwd | head -5 root 0 messagebus 499 systemd-network 497 systemd-timesync 496 nobody 65534 $ awk -F ':' '{print $1\"\\t\"$3}' /etc/passwd | head -5 root 0 messagebus 499 systemd-network 497 systemd-timesync 496 nobody 65534 $ grep \"^UUID\" /etc/fstab | awk '{print $2,$3}' / btrfs /var btrfs /usr/local btrfs /tmp btrfs /srv btrfs /root btrfs /opt btrfs /home btrfs /boot/grub2/x86_64-efi btrfs /boot/grub2/i386-pc btrfs /.snapshots btrfs swap swap \u793a\u4f8b\uff1a\u8bfb\u53d6\u5206\u533a\u5229\u7528\u7387\u3002 \u5206\u9694\u7b26\u4e2d\u7684\u5b9a\u4e49 [[:space:]]+|% \u7684\u542b\u4e49\uff0c\u4e00\u4e2a\u6216\u591a\u4e2a\u7a7a\u683c\u6216\u8005 % \u4f5c\u4e3a\u5206\u9694\u7b26\u3002 $ df | awk '{print $1,$5}' Filesystem Use% devtmpfs 0 % tmpfs 0 % tmpfs 2 % tmpfs 0 % /dev/sda2 8 % /dev/sda2 8 % /dev/sda2 8 % /dev/sda2 8 % /dev/sda2 8 % /dev/sda2 8 % /dev/sda2 8 % /dev/sda2 8 % /dev/sda2 8 % /dev/sda2 8 % /dev/sda2 8 % tmpfs 0 % $ df | grep '^/dev/sd' | awk -F '[[:space:]]+|%' '{print $1,$5}' $ df | grep '^/dev/sd' | awk -F ' +|%' '{print $1,$5}' /dev/sda2 8 /dev/sda2 8 /dev/sda2 8 /dev/sda2 8 /dev/sda2 8 /dev/sda2 8 /dev/sda2 8 /dev/sda2 8 /dev/sda2 8 /dev/sda2 8 /dev/sda2 8 \u793a\u4f8b\uff1a\u8bfb\u53d6ifconfig\u8f93\u51fa\u7ed3\u679c\u4e2d\u7684ip\u5730\u5740\u3002 $ ifconfig eth0 | sed -n '2p' | awk '/netmask/{print $2}' 192 .168.10.210 $ ifconfig eth0 | sed -n '2p' | awk '{print $2}' 192 .168.10.210","title":"5.10.4.\u5e38\u7528action\u5206\u7c7b"},{"location":"linux/SRE/05-RegExpress/#5105pattern","text":"\u6839\u636epattern\u6761\u4ef6\uff0c\u8fc7\u6ee4\u5339\u914d\u7684\u884c\uff0c\u518d\u505a\u5904\u7406\u3002 \u5982\u679c\u672a\u6307\u5b9a\uff0c\u5373\u7a7a\u6a21\u5f0f\uff0c\u5219\u5339\u914d\u6bcf\u4e00\u884c\u3002 /regular expression/ \uff0c\u4ec5\u5904\u7406\u80fd\u591f\u6a21\u5f0f\u5339\u914d\u5230\u7684\u884c\uff08\u5373\u7ed3\u679c\u4e3a\u771f\uff09\uff0c\u9700\u8981\u7528 / \u8fdb\u884c\u62ec\u8d77\u6765\u3002 \u7ed3\u679c\u4e3a\u771f\uff0c\u5373\u975e0\u503c\u3001\u975e\u7a7a\u5b57\u7b26\u4e32 \u7ed3\u679c\u4e3a\u5047\uff0c\u53730\u503c\u3001\u7a7a\u5b57\u7b26\u4e32 \u793a\u4f8b\uff1a\u7a7a\u6a21\u5f0f awk -F \":\" '{print $1, $3}' /etc/passwd | head -n5 root 0 messagebus 499 systemd-network 497 systemd-timesync 496 nobody 65534 \u793a\u4f8b\uff1a\u975e\u7a7a\u6a21\u5f0f $ seq 5 | awk '0' $ seq 5 | awk '1' 1 2 3 4 5 $ seq 5 | awk '2' 1 2 3 4 5 $ seq 5 | awk '\"true\"' 1 2 3 4 5 $ seq 5 | awk '\"false\"' 1 2 3 4 5 $ seq 5 | awk 'true' $ seq 5 | awk 'false' $ seq 5 | awk '' $ seq 5 | awk '\"\"' $ seq 5 | awk '\"0\"' 1 2 3 4 5 \u4f53\u4f1a\u4e0b\u9762\u53d8\u91cf\u7684\u503c\u548c\u6b63\u786e\u4f7f\u7528\u53d8\u91cf\uff08\u5b57\u7b26\u4e32\u8fd8\u662f\u53d8\u91cf\uff1f\uff09 $ seq 5 | awk '\"test\"' 1 2 3 4 5 $ seq 5 | awk 'test' $ seq 5 | awk -v test = 0 '\"test\"' $ seq 5 | awk -v test = 0 'test' $ seq 5 | awk -v test = \"0\" 'test' $ seq 5 | awk -v test = \"0\" '\"test\"' 1 2 3 4 5 $ seq 5 | awk -v test = 1 'test' 1 2 3 4 5 \u4f53\u4f1a\u4e0b\u9762\u7684\u4e0e\u975e\u5224\u65ad\u3002 $ awk '1' /etc/passwd | head -n3 root:x:0:0:root:/root:/bin/bash messagebus:x:499:499:User for D-Bus:/run/dbus:/usr/bin/false systemd-network:x:497:497:systemd Network Management:/:/usr/sbin/nologin $ awk '0' /etc/passwd | head -n3 $ awk '!1' /etc/passwd | head -n3 $ awk '!0' /etc/passwd | head -n3 root:x:0:0:root:/root:/bin/bash messagebus:x:499:499:User for D-Bus:/run/dbus:/usr/bin/false systemd-network:x:497:497:systemd Network Management:/:/usr/sbin/nologin # i\u6ca1\u6709\u8d4b\u503c\uff0c\u4e3a\u5047\uff0c\u6ca1\u6709\u8f93\u51fa $ seq 5 | awk 'i' # i\u8d4b\u503c\u4e3a0\uff0c\u4e3a\u5047\uff0c\u6ca1\u6709\u8f93\u51fa $ seq 5 | awk 'i=0' # i\u8d4b\u503c\u4e3a1\uff0c\u4e3a\u771f\uff0c\u8f93\u51fa\u7b2c\u4e00\u884c\u7ed3\u679c\uff0c\u4ee5\u6b64\u7c7b\u63a8\uff0c\u6bcf\u884c\u90fd\u4e3a\u771f\uff0c\u8f93\u51fa\u5168\u90e8seq\u7684\u7ed3\u679c $ seq 5 | awk 'i=1' 1 2 3 4 5 # \u7b2c\u4e00\u6b21\u521d\u59cbi\u672a\u8d4b\u503c\uff0c\u4e3a\u5047\uff0c!i\u5219\u4e3a\u771f\uff0c\u8d4b\u503c\u7ed9i\uff0c\u6240\u4ee5i\u4e3a\u771f,\u8f93\u51faseq\u7b2c1\u884c\u7ed3\u679c # \u7b2c\u4e8c\u6b21\u521d\u59cbi\u4e3a\u771f\uff0c!i\u5219\u4e3a\u5047\uff0c\u8d4b\u503c\u7ed9i\uff0c\u6240\u4ee5i\u4e3a\u5047\uff0c\u4e0d\u8f93\u51faseq\u7b2c2\u884c\u7ed3\u679c # \u7b2c\u4e09\u6b21\u521d\u59cbi\u4e3a\u5047\uff0c!i\u5219\u4e3a\u771f\uff0c\u8d4b\u503c\u7ed9i\uff0c\u6240\u4ee5i\u4e3a\u771f\uff0c\u8f93\u51faseq\u7b2c3\u884c\u7ed3\u679c # \u4ee5\u6b64\u7c7b\u63a8\uff0c\u8f93\u51faseq\u7ed3\u679c\u7684\u5947\u6570\u884c $ seq 5 | awk 'i=!i' 1 3 5 # \u4e0e\u4e0a\u4f8b\u7684\u533a\u522b\u5728\u4e8ei\u521d\u59cb\u503c\u672a\u771f\uff0c\u7b2c\u4e00\u6b21\u7684i\u503c\u4e3a\u5047\uff0c\u4e0d\u8f93\u51faseq\u7b2c1\u884c\u7ed3\u679c # \u7b2c\u4e8c\u6b21i\u7684\u521d\u59cb\u503c\u4e3a\u5047\uff0c\u901a\u8fc7i=!i\u53d8\u4e3a\u771f\uff0c\u6240\u4ee5\u8f93\u51faseq\u7684\u7b2c2\u884c\u7ed3\u679c # \u4ee5\u6b64\u7c7b\u63a8\uff0c\u8f93\u51faseq\u7ed3\u679c\u7684\u5076\u6570\u884c $ seq 5 | awk -v i = 1 'i=!i' 2 4 # \u8f93\u51fa\u8ba1\u6570\u884c $ seq 5 | awk -v i = 0 'i=!i' 1 3 5 # \u53ea\u8f93\u51fai\u7684\u503c\uff0c\u4e0d\u8f93\u51faseq\u7684\u503c $ seq 5 | awk '{i=!i;print i}' 1 0 1 0 1 $ seq 5 | awk '{i=!i}' $ seq 5 | awk '(i=!i)' 1 3 5 $ seq 5 | awk '!(i=!i)' 2 4","title":"5.10.5.\u6a21\u5f0fPattern"},{"location":"linux/SRE/05-RegExpress/#5106","text":"\u793a\u4f8b\uff1a $ head -n2 /etc/passwd | awk -F ':' '{print $0}' root:x:0:0:root:/root:/bin/bash messagebus:x:499:499:User for D-Bus:/run/dbus:/usr/bin/false $ head -n2 /etc/passwd | awk -F ':' '{print $2}' x x $ head -n2 /etc/passwd | awk -F ':' '{print $1}' root messagebus $ head -n2 /etc/passwd | awk -F ':' '{print $1\"#\"$2\"#\"$3\"#\"$4}' root#x#0#0 messagebus#x#499#499","title":"5.10.6.\u622a\u53d6\u7247\u6bb5"},{"location":"linux/SRE/05-RegExpress/#5107","text":"","title":"5.10.7.\u64cd\u4f5c\u7b26"},{"location":"linux/SRE/05-RegExpress/#51071","text":"x+y \uff0c x-y \uff0c x*y \uff0c x/y \uff0c x^y \uff0c x%y \u3002 -x \uff1a\u8f6c\u6362\u4e3a\u8d1f\u6570 +x \uff1a\u5c06\u5b57\u7b26\u4e32\u8f6c\u6362\u4e3a\u6570\u503c \u5217\u503c\u4e4b\u95f4\u8fdb\u884c\u7b97\u672f\u8fd0\u7b97\u3002 $ awk -F ':' '{$7=$3+$4;print $1,$3,$4,$7}' /etc/passwd | head -n5 root 0 0 0 messagebus 499 499 998 systemd-network 497 497 994 systemd-timesync 496 496 992 nobody 65534 65534 131068 \u8ba1\u7b97\u67d0\u4e2a\u5217\u7684\u603b\u548c\u3002 END \u8868\u793a\u6240\u6709\u7684\u884c\u90fd\u5df2\u7ecf\u6267\u884c\u3002 $ awk -F ':' '{(total=total+$3)}; END {print total}' /etc/passwd 103011","title":"5.10.7.1.\u7b97\u6570\u64cd\u4f5c\u7b26"},{"location":"linux/SRE/05-RegExpress/#51072","text":"\u6ca1\u6709\u64cd\u4f5c\u7b26\u53f7\uff0c\u5b57\u7b26\u4e32\u8fde\u63a5\u3002","title":"5.10.7.2.\u5b57\u7b26\u4e32\u64cd\u4f5c\u7b26"},{"location":"linux/SRE/05-RegExpress/#51073","text":"= \uff0c += \uff0c -= \uff0c *= \uff0c /= \uff0c %= \uff0c ^= \uff0c ++ \uff0c -- \u3002 \u793a\u4f8b\uff1a $ awk 'BEGIN{print i}' $ awk 'BEGIN{print i++}' #\u4ece0\u5f00\u59cb 0 $ awk 'BEGIN{print ++i}' 1 $ awk 'BEGIN{print i++, i}' 0 1 $ awk 'BEGIN{i=0;print i++, i}' 0 1 $ awk 'BEGIN{print ++i, i}' 1 1 $ awk 'BEGIN{i=0;print ++i, i}' 1 1 $ awk 'BEGIN{i=0;print i, i++}' 0 0 $ awk 'BEGIN{i=0;print i, ++i}' 0 1 $ seq 10 1 2 3 4 5 6 7 8 9 10 # n\u4ece0\u5f00\u59cb\u8ba1\u6570\uff0c\u8f93\u51fa\u7684\u662fn\u503c\uff0c\u4e0d\u662fseq\u7684\u8f93\u51fa\u7ed3\u679c $ seq 10 | awk '{print n++}' 0 1 2 3 4 5 6 7 8 9 # seq=1\u65f6\uff0c\u521d\u59cbn\u672a\u8d4b\u503c\uff0c\u4e3a\u5047\uff0c\u4e0d\u8f93\u51faseq\u7ed3\u679c\uff0cn++\u4e3a\u771f # seq=2\u65f6\uff0cn\u4e3a\u771f\uff0c\u8f93\u51faseq\u7ed3\u679c\uff0cn++\u4e3a\u771f # \u540e\u7eedn++\u90fd\u4e3a\u771f\uff0c\u6240\u4ee5seq\u7684\u7ed3\u679c\u51fa\u4e86\u7b2c\u4e00\u884c\u7531\u4e8en\u4e3a\u5047\u6ca1\u6709\u8f93\u51fa\uff0c\u5176\u4ed6\u884c\u90fd\u8f93\u51fa $ seq 10 | awk 'n++' 2 3 4 5 6 7 8 9 10 # \u53c2\u8003\u4e0a\u4f8b\uff0cn\u521d\u59cb\u672a\u8d4b\u503c\uff0c\u4f46\u6267\u884c++n\u540e\u4e3a\u771f\uff0c\u6240\u4ee5\u8f93\u51fa\u7b2c\u4e00\u884c\uff0c\u540e\u7eed\u884c\u90fd\u8f93\u51fa\u56e0\u4e3an\u4e00\u76f4\u4e3a\u771f $ seq 10 | awk '++n' 1 2 3 4 5 6 7 8 9 10 # n=0\u65f6++n=1\uff0c!++n=0\uff0c\u8f93\u51fa\u7b2c0\u884c $ awk -v n = 0 '!++n' /etc/passwd # n=0\u65f6n++=1\uff0c!n++=1\uff0c\u8f93\u51fa\u7b2c1\u884c $ awk -v n = 0 '!n++' /etc/passwd root:x:0:0:root:/root:/bin/bash $ awk -v n = 0 '!n++{print n}' /etc/passwd 1 # \u65e0\u7ed3\u679c\u8f93\u51fa $ awk -v n = 0 '!++n{print n}' /etc/passwd $ awk -v n = 1 '!n++{print n}' /etc/passwd $ awk -v n = 0 '!n++' /etc/passwd root:x:0:0:root:/root:/bin/bash # \u65e0\u7ed3\u679c\u8f93\u51fa $ awk -v n = 1 '!n++' /etc/passwd $ awk -v n = 2 '!n++' /etc/passwd","title":"5.10.7.3.\u8d4b\u503c\u64cd\u4f5c\u7b26"},{"location":"linux/SRE/05-RegExpress/#51074","text":"\u4f7f\u7528 == \u4ee3\u8868\u7b49\u4e8e\uff0c\u5373\u7cbe\u786e\u5339\u914d\u3002\u7c7b\u4f3c\u8fd8\u6709 > \u3001 >= \u3001 < \u3001 <= \u3001 != \u7b26\u53f7\u3002 \u4ee5 : \u4e3a\u5206\u9694\u7b26\uff0c\u5339\u914d\u7b2c\u4e09\u5217\u7684\u503c\u4e3a 1000 \u7684\u884c\u3002 $ awk -F ':' '$3==\"100\"' /etc/passwd vagrant:x:1000:478:vagrant:/home/vagrant:/bin/bash \u5728\u548c\u6570\u5b57\u6bd4\u8f83\u65f6\uff0c\u82e5\u628a\u8981\u6bd4\u8f83\u7684\u6570\u5b57\u7528\u53cc\u5f15\u53f7\u5f15\u8d77\u6765\uff0c awk \u4f1a\u6309\u5b57\u7b26\u5904\u7406\uff0c\u4e0d\u52a0\u53cc\u5f15\u53f7\uff0c\u5219\u4f1a\u6309\u6570\u5b57\u5904\u7406\u3002 $ awk -F ':' '$3<=\"100\"' /etc/passwd root:x:0:0:root:/root:/bin/bash bin:x:1:1:bin:/bin:/usr/sbin/nologin $ awk -F ':' '$3<=100' /etc/passwd root:x:0:0:root:/root:/bin/bash postfix:x:51:51:Postfix Daemon:/var/spool/postfix:/usr/sbin/nologin man:x:13:62:Manual pages viewer:/var/lib/empty:/usr/sbin/nologin daemon:x:2:2:Daemon:/sbin:/usr/sbin/nologin at:x:25:25:Batch jobs daemon:/var/spool/atjobs:/usr/sbin/nologin bin:x:1:1:bin:/bin:/usr/sbin/nologin awk -F ':' '{if ($1==\"root\") {print $0}}' /etc/passwd awk -F ':' '$7!=\"/bin/false\"' /etc/passwd awk -F ':' '$3<$2' /etc/passwd","title":"5.10.7.4.\u6bd4\u8f83\u64cd\u4f5c\u7b26"},{"location":"linux/SRE/05-RegExpress/#51075","text":"&& \u8868\u793a\u201c\u5e76\u4e14\u201d || \u8868\u793a\u201c\u6216\u8005\u201d ! \u8868\u793a\u201c\u975e\u201d\uff08\u53d6\u53cd\uff09 awk -F ':' '$3>10 && $3<100' /etc/passwd awk -F ':' '$3>10 || $3<100' /etc/passwd awk -F ':' '($3==0)' /etc/passwd awk -F ':' '!($3==0)' /etc/passwd \u6ce8\u610f\u4e0b\u9762\u5bf9\u5b57\u7b26\u548c\u6570\u503c\u8fdb\u884c\u53d6\u53cd\u64cd\u4f5c\u7684\u7ed3\u679c\u3002 $ awk 'BEGIN{print i}' $ awk 'BEGIN{print !i}' 1 $ awk -v i = 10 'BEGIN{print i}' 10 $ awk -v i = 10 'BEGIN{print !i}' 0 $ awk -v i = -5 'BEGIN{print i}' -5 $ awk -v i = -5 'BEGIN{print !i}' 0 $ awk -v i = \"abc\" 'BEGIN{print i}' abc $ awk -v i = \"abc\" 'BEGIN{print !i}' 0 $ awk -v i = abc 'BEGIN{print i}' abc $ awk -v i = abc 'BEGIN{print !i}' 0 $ awk -v i = \"\" 'BEGIN{print i}' $ awk -v i = \"\" 'BEGIN{print !i}' 1 \u5728\u5206\u9694\u7b26\u5b9a\u4e49\u4e2d\u4f7f\u7528\u6b63\u5219\u8868\u8fbe\u5f0f\u3002 $ df | awk -F \" +|%\" '{print $5}' Use 0 0 2 0 8 8 8 8 8 8 8 8 8 8 8 0 $ df | awk -F \"[[:space:]]+|%\" '{print $5}' Use 0 0 2 0 8 8 8 8 8 8 8 8 8 8 8 0","title":"5.10.7.5.\u903b\u8f91\u64cd\u4f5c\u7b26"},{"location":"linux/SRE/05-RegExpress/#51076","text":"\u683c\u5f0f\uff1a selector?if-true-expression:if-false-expression $ awk -F ':' '{$3>1000?usertype=\"Common User\":usertype=\"Superuser\";printf\"%-20s:%12s\\n\", $1, usertype}' /etc/passwd | head -n5 root : Superuser messagebus : Superuser systemd-network : Superuser systemd-timesync : Superuser nobody : Common User","title":"5.10.7.6.\u4e09\u76ee\u6761\u4ef6\u8868\u8fbe\u5f0f"},{"location":"linux/SRE/05-RegExpress/#51078","text":"~ \uff1a\u5de6\u53f3\u662f\u5426\u5339\u914d !~ \uff1a\u5de6\u53f3\u662f\u5426\u4e0d\u5339\u914d \u793a\u4f8b\uff1a \u5339\u914d\u6587\u4ef6\u4e2d\u6307\u5b9a\u5b57\u7b26\u4e32 root \u7684\u6240\u6709\u884c\uff0c\u7c7b\u4f3cgrep\u547d\u4ee4\uff0c\u4f46\u6ca1\u6709\u9ad8\u4eae\u663e\u793a\u3002 $ awk '/root/' /etc/passwd root:x:0:0:root:/root:/bin/bash \u4ee5 : \u4e3a\u5206\u9694\u7b26\uff0c\u5339\u914d\u7b2c\u4e00\u5217 $1 \u4e2d\u5305\u542b\u6307\u5b9a\u5b57\u7b26\u4e32 oo \u7684\u884c\u3002 ~ \u662f\u4ee3\u8868\u5de6\u53f3\u5339\u914d\u3002 $ awk -F ':' '$1 ~/oo/' /etc/passwd root:x:0:0:root:/root:/bin/bash gentoo:x:1014:100:Gentoo Distribution:/home/gentoo:/bin/csh \u4ee5 : \u4e3a\u5206\u9694\u7b26\uff0c\u5339\u914d\u6240\u6709\u5217 $0 \uff08\u6574\u884c\uff09\u4e2d\u5305\u542b root \u884c\u7684\u7b2c\u4e00\u5217 $1 \u3002 $ awk -F: '$0 ~/root/{print $1}' /etc/passwd $ awk -F: '$0 ~\"root\"{print $1}' /etc/passwd root daemon _cvmsroot \u4ee5 : \u4e3a\u5206\u9694\u7b26\uff0c\u5339\u914d\u6240\u6709\u5217 $0 \uff08\u6574\u884c\uff09\u4e2d\u4ee5 root \u5f00\u5934\u884c\u7684\u7b2c\u4e00\u5217 $1 \u3002 $ awk -F: '$0 ~\"^root\"{print $1}' /etc/passwd $ awk -F: '$0 ~/^root/{print $1}' /etc/passwd root \u4ee5 : \u4e3a\u5206\u9694\u7b26\uff0c\u5339\u914d\u6240\u6709\u5217 $0 \uff08\u6574\u884c\uff09\u4e2d\u4e0d\u4ee5 root \u5f00\u5934\u884c\u7684\u7b2c\u4e00\u5217 $1 \u3002 awk -F: '$0 !~/^root/{print $1}' /etc/passwd awk -F: '$0 ~/^[^root]/{print $1}' /etc/passwd \u591a\u6761\u4ef6\u5339\u914d\uff0c\u4ee5 : \u4e3a\u5206\u9694\u7b26\uff0c\u5339\u914d\u6240\u6709\u542b\u6709 root \u6216 ftp \u7684\u884c\uff0c\u5e76\u6253\u5370\u7b2c1\u30013\u5217\u3002 awk -F ':' '/root/ {print $1,$3} /bin/ {print $1,$3}' /etc/passwd \u591a\u6761\u4ef6\u5339\u914d\uff0c\u4ee5 : \u4e3a\u5206\u9694\u7b26\uff0c\u5339\u914d\u7b2c\u4e00\u5217\u4e2d\u542b\u6709 root \u6216 bin \u7684\u884c\uff0c\u5e76\u6253\u5370\u7b2c1\u30013\u5217\u3002 $ awk -F ':' '$1 ~/root/ {print $1,$3} $1 ~/bin/ {print $1,$3}' /etc/passwd root 0 bin 1 \u4ee5 : \u4e3a\u5206\u9694\u7b26\uff0c\u5339\u914d\u7b2c\u4e09\u5217 $3 \u4e2d\u503c\u4e3a 0 \u7684\u884c\u3002 $ awk -F \":\" '$3==0' /etc/passwd root:x:0:0:root:/root:/bin/bash \u4ee5\u81f3\u5c11\u4e00\u4e2a\u7a7a\u683c\u6216%\u4e3a\u5206\u9694\u7b26\uff0c\u5339\u914d\u4ee5 /dev/sd \u5f00\u5934\u7684\u884c\uff0c\u6253\u5370\u7b2c\u4e94\u5217\u3002 $ df | awk -F \"[[:space:]]+|%\" '$0 ~ /^\\/dev\\/sd/{print $5}' 8 8 8 8 8 8 8 8 8 8 8 \u8bfb\u53d6 ifconfig eth0 \u8f93\u51fa\u7ed3\u679c\u7684\u7b2c\u4e8c\u884c NR==2 \u7684\u7b2c\u4e8c\u5217 $2 \u3002 $ ifconfig eth0 | awk 'NR==2{print $2}' 192 .168.10.210","title":"5.10.7.8.\u6a21\u5f0f\u5339\u914d\u7b26"},{"location":"linux/SRE/05-RegExpress/#5108","text":"","title":"5.10.8.\u53d8\u91cf"},{"location":"linux/SRE/05-RegExpress/#51081","text":"awk \u5e38\u7528\u7684\u53d8\u91cf\u6709 FS \u3001 OFS \u3001 NF \u548c NR \u3002 FS \u7528\u6765\u5b9a\u4e49\u8f93\u5165\u5b57\u6bb5\u5206\u9694\u7b26\uff0c\u9ed8\u8ba4\u4e3a\u7a7a\u767d\u5b57\u7b26\u3002\u4e0e -F \u9009\u9879\u529f\u80fd\u7c7b\u4f3c\uff0c\u540c\u65f6\u4f7f\u7528\u4f1a\u62a5\u9519\u3002 OFS \u7528\u6765\u5b9a\u4e49\u8f93\u51fa\u5b57\u6bb5\u5206\u9694\u7b26\uff0c\u9ed8\u8ba4\u4e3a\u7a7a\u767d\u5b57\u7b26\u3002 RS \u6307\u5b9a\u8f93\u5165\u65f6\u7684\u6362\u884c\u7b26\u3002 ORS \u6307\u5b9a\u7b26\u53f7\u5728\u8f93\u51fa\u65f6\u66ff\u6362\u6362\u884c\u7b26\u3002 NF \u8868\u793a\u7528\u5206\u9694\u7b26\u5206\u9694\u540e\u4e00\u5171\u6709\u591a\u5c11\u5217\u3002 NR \u8868\u793a\u884c\u53f7\u3002 FNR \u8868\u793a\u4e2a\u6587\u4ef6\u5206\u522b\u8ba1\u6570\u5404\u81ea\u8bb0\u5f55\u7684\u7f16\u53f7\u3002 FILENAME \u8868\u793a\u5f53\u524d\u6587\u4ef6\u540d\u3002 ARGC \u8868\u793a\u547d\u4ee4\u884c\u53c2\u6570\u7684\u4e2a\u6570\u3002 ARVC \u4ee5\u6570\u7ec4\u5f62\u5f0f\u4fdd\u5b58\u547d\u4ee4\u884c\u6240\u7ed9\u5b9a\u7684\u5404\u53c2\u6570\uff0c\u6bcf\u4e2a\u53c2\u6570\uff1a ARGV[0] \uff0c......\u3002 FS \u7684\u7528\u6cd5\uff1a $ awk -v FS = ':' '{print $1, FS, $3}' /etc/passwd | head -n5 root : 0 messagebus : 499 systemd-network : 497 $ awk -F: '{print $1FS$3}' /etc/passwd | head -n3 root:0 messagebus:499 systemd-network:497 $ S = : ; awk -v FS = $S '{print $1FS$3}' /etc/passwd | head -n3 root:0 messagebus:499 systemd-network:497 systemd-timesync:496 nobody:65534 $ S = : ; awk -F $S '{print $1FS$3}' /etc/passwd | head -n3 root:0 messagebus:499 systemd-network:497 FS \u548c -F \u9009\u9879\u529f\u540c\u65f6\u4f7f\u7528\u4f1a\u51b2\u7a81\uff0c -F \u7684\u4f18\u5148\u7ea7\u66f4\u9ad8\u3002 $ awk -v FS = ':' -F ';' '{print $1FS$3}' /etc/passwd | head -n3 root:x:0:0:root:/root:/bin/bash ; messagebus:x:499:499:User for D-Bus:/run/dbus:/usr/bin/false ; systemd-network:x:497:497:systemd Network Management:/:/usr/sbin/nologin ; $ awk -v FS = ';' -F ':' '{print $1FS$3}' /etc/passwd | head -n3 root:0 messagebus:499 systemd-network:497 OFS \u7684\u7528\u6cd5\uff1a \u4ee5 : \u4e3a\u5206\u9694\u7b26\uff0c\u6253\u5370\u7b2c1\u30013\u30014\u5217\u7b2c\u5185\u5bb9\uff0c\u5e76\u4ee5 # \u4e3a\u5206\u9694\u7b26\u3002 $ awk -F ':' '{OFS=\"#\"} {print $1,$3,$4}' /etc/passwd | head -n5 root#0#0 messagebus#499#499 systemd-network#497#497 systemd-timesync#496#496 nobody#65534#65534 $ awk -v FS = ':' -v OFS = '#' '{print $1,$3,$4}' /etc/passwd | head -n5 root#0#0 messagebus#499#499 systemd-network#497#497 systemd-timesync#496#496 nobody#65534#65534 \u4ee5 : \u4e3a\u5206\u9694\u7b26\uff0c\u5f53\u7b2c\u4e09\u5217\u5927\u4e8e\u7b49\u4e8e5000\u65f6\uff0c\u6253\u5370\u7b2c1\u30012\u30013\u30014\u5217\u7b2c\u5185\u5bb9\uff0c\u5e76\u4ee5 # \u4e3a\u5206\u9694\u7b26\u3002 $ awk -F ':' '{OFS=\"#\"} {if ($3>=5000) {print $1,$2,$3,$4}}' /etc/passwd nobody#x#65534#65534 RS \u7684\u7528\u6cd5\uff1a # \u4ee5\u7a7a\u683c\u4e3a\u6362\u884c\u6807\u5fd7 $ awk -v RS = ' ' '{print $0}' /etc/passwd | head -n3 root:x:0:0:root:/root:/bin/bash messagebus:x:499:499:User for # \u4ee5\u5192\u53f7\u4e3a\u6362\u884c\u6807\u5fd7 $ awk -v RS = ':' '{print $0}' /etc/passwd | head -n3 root x 0 ORS \u7684\u7528\u6cd5\uff1a # \u4ee5\u5192\u53f7\u4e3a\u6362\u884c\u6807\u5fd7\uff0c\u66ff\u6362\u6210### $ awk -v RS = ':' -v ORS = '###' '{print $0}' /etc/passwd | head -n3 root###x###0###0###root###/root###/bin/bash messagebus###x###499###499###User for D-Bus###/run/dbus###/usr/bin/false systemd-network###x###497###497###systemd Network Management###/###/usr/sbin/nologin NF \u7684\u7528\u6cd5\uff1a \u5176\u4e2d NF \u662f\u591a\u5c11\u5217\uff0c $NF \u662f\u6700\u540e\u4e00\u5217\u7684\u503c\u3002 \u4e0b\u4f8b\u4e2d\u4ee5 : \u4e3a\u5206\u9694\u7b26\u4e00\u5171\u5206\u4e3a7\u5217\uff0c\u6700\u540e\u4e00\u5217\u7684\u503c\u662f $NF \u3002 $ awk -F ':' '{print $NF}' /etc/passwd | head -n2 /bin/bash /usr/bin/false $ awk -F ':' '{print NF}' /etc/passwd | head -n2 7 7 $ ss -nt | grep \"^ESTAB\" | awk -F \"[[:space:]]+|:\" '{print $(NF-2)}' 192 .168.10.103 $ ss -nt | awk -F \"[[:space:]]+|:\" '/^ESTAB/{print $(NF-2)}' 192 .168.10.103 NR \u7684\u7528\u6cd5\uff1a \u901a\u8fc7 NR \u8f93\u51fa\u884c\u53f7\u3002\u4ee5 : \u4e3a\u5206\u9694\u7b26\uff0c\u6253\u5370\u524d\u4e09\u884c\u7684\u884c\u53f7\u3002 $ awk -F ':' '{print NR}' /etc/passwd | head -n3 1 2 3 \u53d6\u5947\u3001\u5076\u6570\u884c\u3002 $ seq 10 | awk 'NR%2==0' 2 4 6 8 10 $ seq 10 | awk 'NR%2==1' 1 3 5 7 9 \u901a\u8fc7 NR \u8bbe\u5b9a\u884c\u53f7\u6761\u4ef6\u3002\u4ee5 : \u4e3a\u5206\u9694\u7b26\uff0c\u6253\u5370\u7b2c40\u884c\u4ee5\u540e\u7684\u884c\u5185\u5bb9\u3002 $ awk 'NR>45' /etc/passwd admin3:x:1020:100::/home/admin3:/bin/bash smith:x:2002:0:,,,:/home/admin2:/bin/bash pm1:x:2003:1535::/home/pm1:/bin/bash tm1:x:2004:1535::/home/tm1:/bin/bash tm2:x:2005:1536::/home/tm2:/bin/bash $ awk -F ':' 'NR>45' /etc/passwd admin3:x:1020:100::/home/admin3:/bin/bash smith:x:2002:0:,,,:/home/admin2:/bin/bash pm1:x:2003:1535::/home/pm1:/bin/bash tm1:x:2004:1535::/home/tm1:/bin/bash tm2:x:2005:1536::/home/tm2:/bin/bash $ awk -F ':' 'NR>45 {print NR,$1,$3}' /etc/passwd 46 admin3 1020 47 smith 2002 48 pm1 2003 49 tm1 2004 50 tm2 2005 $ awk -F ':' 'BEGIN{print NR}' /etc/passwd 0 $ awk -F ':' 'END{print NR}' /etc/passwd 50 $ ifconfig eth0 | awk '/netmask/{print $0}' inet 192 .168.10.210 netmask 255 .255.255.0 broadcast 192 .168.10.255 $ ifconfig eth0 | awk '/netmask/{print $1}' inet $ ifconfig eth0 | awk '/netmask/{print $2}' 192 .168.10.210 $ ifconfig eth0 | awk 'NR==2{print $0}' inet 192 .168.10.210 netmask 255 .255.255.0 broadcast 192 .168.10.255 $ ifconfig eth0 | awk 'NR==2{print $1}' inet $ ifconfig eth0 | awk 'NR==2{print $2}' 192 .168.10.210 \u901a\u8fc7 NR \u4e0e\u5217\u5339\u914d\u4e00\u8d77\u4f7f\u7528\u3002 $ awk -F ':' 'NR<5 && $1 ~/roo/' /etc/passwd root:x:0:0:root:/root:/bin/bash FNR \u7684\u7528\u6cd5\uff1a $ awk '{print FNR}' /etc/fstab /etc/networks 1 2 3 4 5 6 7 8 9 10 11 12 1 2 3 4 5 6 7 8 9 10 $ awk '{print NR, $0}' /etc/fstab /etc/networks 1 UUID = 5ffa8dbd-473e-4308-804a-0033c3b5f7af / btrfs defaults 0 0 2 UUID = 5ffa8dbd-473e-4308-804a-0033c3b5f7af /var btrfs subvol = /@/var 0 0 3 UUID = 5ffa8dbd-473e-4308-804a-0033c3b5f7af /usr/local btrfs subvol = /@/usr/local 0 0 4 UUID = 5ffa8dbd-473e-4308-804a-0033c3b5f7af /tmp btrfs subvol = /@/tmp 0 0 5 UUID = 5ffa8dbd-473e-4308-804a-0033c3b5f7af /srv btrfs subvol = /@/srv 0 0 6 UUID = 5ffa8dbd-473e-4308-804a-0033c3b5f7af /root btrfs subvol = /@/root 0 0 7 UUID = 5ffa8dbd-473e-4308-804a-0033c3b5f7af /opt btrfs subvol = /@/opt 0 0 8 UUID = 5ffa8dbd-473e-4308-804a-0033c3b5f7af /home btrfs subvol = /@/home 0 0 9 UUID = 5ffa8dbd-473e-4308-804a-0033c3b5f7af /boot/grub2/x86_64-efi btrfs subvol = /@/boot/grub2/x86_64-efi 0 0 10 UUID = 5ffa8dbd-473e-4308-804a-0033c3b5f7af /boot/grub2/i386-pc btrfs subvol = /@/boot/grub2/i386-pc 0 0 11 UUID = 5ffa8dbd-473e-4308-804a-0033c3b5f7af /.snapshots btrfs subvol = /@/.snapshots 0 0 12 UUID = 47c36ad7-f49f-4ecd-9b72-4801c5bb3a04 swap swap defaults 0 0 13 # 14 # networks This file describes a number of netname-to-address 15 # mappings for the TCP/IP subsystem. It is mostly 16 # used at boot time, when no name servers are running. 17 # 18 19 loopback 127 .0.0.0 20 link-local 169 .254.0.0 21 22 # End. $ awk '{print FNR, $0}' /etc/fstab /etc/networks 1 UUID = 5ffa8dbd-473e-4308-804a-0033c3b5f7af / btrfs defaults 0 0 2 UUID = 5ffa8dbd-473e-4308-804a-0033c3b5f7af /var btrfs subvol = /@/var 0 0 3 UUID = 5ffa8dbd-473e-4308-804a-0033c3b5f7af /usr/local btrfs subvol = /@/usr/local 0 0 4 UUID = 5ffa8dbd-473e-4308-804a-0033c3b5f7af /tmp btrfs subvol = /@/tmp 0 0 5 UUID = 5ffa8dbd-473e-4308-804a-0033c3b5f7af /srv btrfs subvol = /@/srv 0 0 6 UUID = 5ffa8dbd-473e-4308-804a-0033c3b5f7af /root btrfs subvol = /@/root 0 0 7 UUID = 5ffa8dbd-473e-4308-804a-0033c3b5f7af /opt btrfs subvol = /@/opt 0 0 8 UUID = 5ffa8dbd-473e-4308-804a-0033c3b5f7af /home btrfs subvol = /@/home 0 0 9 UUID = 5ffa8dbd-473e-4308-804a-0033c3b5f7af /boot/grub2/x86_64-efi btrfs subvol = /@/boot/grub2/x86_64-efi 0 0 10 UUID = 5ffa8dbd-473e-4308-804a-0033c3b5f7af /boot/grub2/i386-pc btrfs subvol = /@/boot/grub2/i386-pc 0 0 11 UUID = 5ffa8dbd-473e-4308-804a-0033c3b5f7af /.snapshots btrfs subvol = /@/.snapshots 0 0 12 UUID = 47c36ad7-f49f-4ecd-9b72-4801c5bb3a04 swap swap defaults 0 0 1 # 2 # networks This file describes a number of netname-to-address 3 # mappings for the TCP/IP subsystem. It is mostly 4 # used at boot time, when no name servers are running. 5 # 6 7 loopback 127 .0.0.0 8 link-local 169 .254.0.0 9 10 # End. FILENAME \u7684\u7528\u6cd5\uff1a $ awk '{print FILENAME}' /etc/fstab /etc/fstab /etc/fstab /etc/fstab /etc/fstab /etc/fstab /etc/fstab /etc/fstab /etc/fstab /etc/fstab /etc/fstab /etc/fstab /etc/fstab $ awk '{print FNR, FILENAME, $0}' /etc/fstab /etc/networks 1 /etc/fstab UUID = 5ffa8dbd-473e-4308-804a-0033c3b5f7af / btrfs defaults 0 0 2 /etc/fstab UUID = 5ffa8dbd-473e-4308-804a-0033c3b5f7af /var btrfs subvol = /@/var 0 0 3 /etc/fstab UUID = 5ffa8dbd-473e-4308-804a-0033c3b5f7af /usr/local btrfs subvol = /@/usr/local 0 0 4 /etc/fstab UUID = 5ffa8dbd-473e-4308-804a-0033c3b5f7af /tmp btrfs subvol = /@/tmp 0 0 5 /etc/fstab UUID = 5ffa8dbd-473e-4308-804a-0033c3b5f7af /srv btrfs subvol = /@/srv 0 0 6 /etc/fstab UUID = 5ffa8dbd-473e-4308-804a-0033c3b5f7af /root btrfs subvol = /@/root 0 0 7 /etc/fstab UUID = 5ffa8dbd-473e-4308-804a-0033c3b5f7af /opt btrfs subvol = /@/opt 0 0 8 /etc/fstab UUID = 5ffa8dbd-473e-4308-804a-0033c3b5f7af /home btrfs subvol = /@/home 0 0 9 /etc/fstab UUID = 5ffa8dbd-473e-4308-804a-0033c3b5f7af /boot/grub2/x86_64-efi btrfs subvol = /@/boot/grub2/x86_64-efi 0 0 10 /etc/fstab UUID = 5ffa8dbd-473e-4308-804a-0033c3b5f7af /boot/grub2/i386-pc btrfs subvol = /@/boot/grub2/i386-pc 0 0 11 /etc/fstab UUID = 5ffa8dbd-473e-4308-804a-0033c3b5f7af /.snapshots btrfs subvol = /@/.snapshots 0 0 12 /etc/fstab UUID = 47c36ad7-f49f-4ecd-9b72-4801c5bb3a04 swap swap defaults 0 0 1 /etc/networks # 2 /etc/networks # networks This file describes a number of netname-to-address 3 /etc/networks # mappings for the TCP/IP subsystem. It is mostly 4 /etc/networks # used at boot time, when no name servers are running. 5 /etc/networks # 6 /etc/networks 7 /etc/networks loopback 127 .0.0.0 8 /etc/networks link-local 169 .254.0.0 9 /etc/networks 10 /etc/networks # End. ARGC \u7684\u7528\u6cd5\uff1a \u6bcf\u4e2a\u53d8\u91cf\u7684\u540d\u5b57\u901a\u8fc7 ARGV \u83b7\u53d6\u3002 $ awk '{print ARGC}' /etc/fstab /etc/issue 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 $ awk 'BEGIN{print ARGC}' /etc/fstab /etc/issue 3 ARGV \u7684\u7528\u6cd5\uff1a $ awk 'BEGIN{print ARGV[0]}' /etc/fstab /etc/issue awk $ awk 'BEGIN{print ARGV[1]}' /etc/fstab /etc/issue /etc/fstab $ awk 'BEGIN{print ARGV[2]}' /etc/fstab /etc/issue /etc/issue $ awk 'BEGIN{print ARGV[3]}' /etc/fstab /etc/issue","title":"5.10.8.1.\u5185\u7f6e\u53d8\u91cf"},{"location":"linux/SRE/05-RegExpress/#51082","text":"\u81ea\u5b9a\u4e49\u53d8\u91cf\u662f\u533a\u5206\u5b57\u7b26\u5927\u5c0f\u5199\u7684\uff0c\u4f7f\u7528\u4e0b\u9762\u7684\u65b9\u5f0f\u8fdb\u884c\u8d4b\u503c\u3002 -v var=value \u5728program\u4e2d\u76f4\u63a5\u5b9a\u4e49 \u4e3e\u4f8b\uff1a $ awk -v t1 = t2 = \"hello awk\" 'BEGIN{print t1, t2}' t2 = hello awk $ awk -v t1 = t2 = \"hello awk\" 'BEGIN{t1=t2=\"gawk\"; print t1, t2}' gawk gawk $ awk 'BEGIN{t1=t2=\"hello awk\"; print t1, t2}' hello awk hello awk $ awk -v t1 = \"hello awk\" '{print t1}' /etc/issue hello awk hello awk hello awk hello awk hello awk $ awk -v t1 = \"hello awk\" 'BEGIN{print t1}' /etc/issue hello awk $ awk -v t1 = \"hello awk\" 'BEGIN{print t1}' hello awk $ awk -F: '{sex=\"male\"; print $1, sex, age; age=28}' /etc/passwd | head -n3 root male messagebus male 28 systemd-network male 28 $ cat < awkscript {print script,$1,$2} EOF $ awk -F: -f awkscript script = \"awk\" /etc/passwd | head -n2 awk root x awk messagebus x \u52a8\u4f5c printf \u3002 \u52a8\u4f5cprintf\u53ef\u4ee5\u5b9e\u73b0\u683c\u5f0f\u5316\u8f93\u51fa\u3002 \u683c\u5f0f\uff1a printf \"FORMAT\", item1, item2, ...... \u8bf4\u660e\uff1a \u5fc5\u987b\u6307\u5b9aFORMAT \u4e0d\u4f1a\u81ea\u52a8\u6362\u884c\uff0c\u9700\u8981\u663e\u5f0f\u7ed9\u51fa\u6362\u884c\u63a7\u5236\u7b26 \\n \u3002 FORMAT\u4e2d\u9700\u8981\u5206\u522b\u4e3a\u540e\u9762\u6bcf\u4e2aitem\u6307\u5b9a\u683c\u5f0f\u7b26\u3002 \u683c\u5f0f\u7b26\uff1a\u4e0eitem\u662f\u4e00\u4e00\u5bf9\u5e94\u7684 %s \uff1a\u663e\u793a\u5b57\u7b26\u4e32 %d , %i \uff1a\u663e\u793a\u5341\u8fdb\u5236\u6574\u6570 %f \uff1a\u663e\u793a\u4e3a\u6d6e\u70b9\u6570 %e , %E \uff1a\u663e\u793a\u79d1\u5b66\u8ba1\u6570\u6cd5\u6570\u503c %c \uff1a\u663e\u793a\u5b57\u7b26\u7684ASCII\u7801 %g , %G \uff1a\u4ee5\u79d1\u5b66\u8ba1\u6570\u6cd5\u6216\u6d6e\u70b9\u5f62\u5f0f\u663e\u793a\u6570\u503c %u \uff1a\u65e0\u7b26\u53f7\u6574\u6570 %% \uff1a\u663e\u793a % \u81ea\u8eab \u4fee\u9970\u7b26\uff1a #[.#] \uff1a\u7b2c\u4e00\u4e2a\u6570\u5b57\u63a7\u5236\u663e\u793a\u7684\u5bbd\u5ea6\uff0c\u7b2c\u4e8c\u4e2a#\u8868\u793a\u5c0f\u6570\u70b9\u540e\u7cbe\u5ea6\uff0c\u5982 %3.1f - \uff1a\u5de6\u5bf9\u9f50\uff08\u9ed8\u8ba4\u53f3\u5bf9\u9f50\uff09\uff0c\u5982 %-15s + \uff1a\u663e\u793a\u6570\u503c\u7684\u6b63\u8d1f\u7b26\u53f7\uff0c\u5982 %+d \u793a\u4f8b\uff1a $ awk -F: '{printf \"%s\", $1}' /etc/passwd | head -n3 rootmessagebussystemd-networksystemd-timesyncnobodymailchronypostfixmanlpgamesftpdaemonrpcnscdpolkitdattftpftpsecurebinstatdsshdvagrantpesignsvntester1tester2tester3tester4tester5user0user1user2user3user4user5user6user7user8user9gentoonginxvarnishmysqlwebuseradmin3smithpm1tm1tm2 $ awk -F: '{printf \"%s\\n\", $1}' /etc/passwd | head -n3 root messagebus systemd-network $ awk -F: '{printf \"%20s\\n\", $1}' /etc/passwd | head -n3 root messagebus systemd-network $ awk -F: '{printf \"%-20s\\n\", $1}' /etc/passwd | head -n3 root messagebus systemd-network $ awk -F: '{printf \"%-20s %10d\\n\", $1, $3}' /etc/passwd | head -n3 root 0 messagebus 499 systemd-network 497 $ awk -F: '{printf \"Username: %s\\n\", $1}' /etc/passwd | head -n3 Username: root Username: messagebus Username: systemd-network $ awk -F: '{printf \"Username: %s UID:%d\\n\", $1, $3}' /etc/passwd | head -n3 Username: root UID:0 Username: messagebus UID:499 Username: systemd-network UID:497 $ awk -F: '{printf \"Username: %25s UID:%d\\n\", $1, $3}' /etc/passwd | head -n3 Username: root UID:0 Username: messagebus UID:499 Username: systemd-network UID:497 $ awk -F: '{printf \"Username: %-25s UID:%d\\n\", $1, $3}' /etc/passwd | head -n3 Username: root UID:0 Username: messagebus UID:499 Username: systemd-network UID:497","title":"5.10.8.2.\u81ea\u5b9a\u4e49\u53d8\u91cf"},{"location":"linux/SRE/05-RegExpress/#5109beginend","text":"\u793a\u4f8b\uff1a awk -F \":\" 'BEGIN{printf \"--------------------------------\\n%-20s|%10s|\\n--------------------------------\\n\", \"Username\", \"UID\"}{printf \"%-20s|%-10d|\\n--------------------------------\\n\", $1, $3}END{print \"end\"}' /etc/passwd -------------------------------- Username | UID | -------------------------------- root | 0 | -------------------------------- daemon | 1 | -------------------------------- bin | 2 | ------------------------------- ... ... -------------------------------- mfe | 997 | -------------------------------- end","title":"5.10.9.BEGIN/END"},{"location":"linux/SRE/05-RegExpress/#51010","text":"{statements;...} \u7ec4\u5408\u8bed\u53e5 if(condition){statements;...} if(condition){statements;...} else(statements;...) switch(expression){case VALUE1 or /REGEXP/: statement1; case VALUE2 or /REGEXP2/: statement2;......;default: statementn} while(condition){statements;...} do(statements;...) while{condition} for(expr1;expr2;expr3) {statements;...} break continue exit if-else\u793a\u4f8b\uff1a $ cat < score.txt Name Score Tom 100 Jack 91 Bill 81 Jim 51 EOF $ awk 'NR!=1{score=$2;if($2>=80){print $1, \"Good\"}else if($2>=60){print $1, \"Pass\"}else{print $1, \"failed\"}}' score.txt Tom Good Jack Good Bill Good Jim failed switch\u793a\u4f8b\uff1a $ awk 'NR!=1{switch($2){case 100:print $1,\"good\"; case 60:print $1,\"Pass\"; default:print $1,\"others\"}}' score.txt Tom good Tom Pass Tom others Jack others Bill others Jim others while\u793a\u4f8b\uff1a $ awk 'BEGIN{i=0;sum=0;while(i<=100){sum+=i;i++};print sum}' 5050 do-while\u793a\u4f8b\uff1a $ awk 'BEGIN{i=0;sum=0;do{sum+=i;i++}while(i<101);print sum}' 5050 for\u793a\u4f8b\uff1a $ awk 'BEGIN{i=0;sum=0;for(i=1;i<=100;i++){sum+=i};print sum}' 5050 \u547d\u4ee4\u6548\u7387\u6bd4\u8f83\uff1a $ time ( awk 'BEGIN{i=0;sum=0;while(i<=100000){sum+=i;i++};print sum}' ) 5000050000 real 0m0.028s user 0m0.027s sys 0m0.001s $ time ( seq -s+ 1000000 | bc ) 500000500000 real 0m0.329s user 0m0.240s sys 0m0.094s $ time ( awk 'BEGIN{i=0;sum=0;for(i=1;i<=1000000;i++){sum+=i};print sum}' ) 500000500000 real 0m0.050s user 0m0.046s sys 0m0.004s contine\u793a\u4f8b\uff1a\u4e2d\u65ad\u5f53\u524d\u5faa\u73af\uff0c\u8fdb\u5165\u4e0b\u4e00\u6b21\u5faa\u73af\u3002 $ awk 'BEGIN{i=0;sum=0;for(i=1;i<=100;i++){if(i==50)continue;sum+=i};print sum}' 5000 contine\u793a\u4f8b\uff1a\u4e2d\u65ad\u6574\u4e2a\u5faa\u73af\u3002 $ awk 'BEGIN{i=0;sum=0;for(i=1;i<=100;i++){if(i==50)break;sum+=i};print sum}' 1225 next\u793a\u4f8b\uff1a\u63d0\u524d\u7ed3\u675f\u5bf9\u672c\u884c\u5904\u7406\uff0c\u76f4\u63a5\u8fdb\u5165\u4e0b\u4e00\u884c\u5904\u7406\uff08\u6ce8\uff0cawk\u81ea\u5faa\u73af\uff0c\u5e76\u975e\u524d\u9762\u7684for\u6216while\u5faa\u73af\uff09 $ awk -F: '{if($3%2!=0)next;print $1,$3}' /etc/passwd # \u5947\u6570\u884c\u6253\u5370 root 0 systemd-timesync 496 nobody 65534 chrony 494 games 492 daemon 2 rpc 490 polkitd 488 ftpsecure 486 sshd 484 vagrant 1000 svn 482 tester1 600 tester4 1002 user0 1004 user2 1006 user4 1008 user6 1010 user8 1012 gentoo 1014 varnish 1016 webuser 666 admin3 1020 smith 2002 tm1 2004 $ awk -F: '{if($3%2==0)next;print $1,$3}' /etc/passwd # \u5076\u6570\u884c\u6253\u5370 messagebus 499 systemd-network 497 mail 495 postfix 51 man 13 lp 493 ftp 491 nscd 489 at 25 tftp 487 bin 1 statd 485 pesign 483 tester2 601 tester3 1001 tester5 1003 user1 1005 user3 1007 user5 1009 user7 1011 user9 1013 nginx 1015 mysql 1017 pm1 2003 tm2 2005","title":"5.10.10.\u5e38\u7528\u63a7\u5236\u8bed\u53e5"},{"location":"linux/SRE/05-RegExpress/#51011","text":"\u5173\u8054\u6570\u7ec4\u662f\u4e00\u79cd\u6570\u636e\u7ed3\u6784\uff0c\u4e5f\u79f0\u4e3a\u5b57\u5178\u6216\u6620\u5c04\u3002\u4e0e\u4f20\u7edf\u7684\u6570\u7ec4\u4e0d\u540c\uff0c\u5173\u8054\u6570\u7ec4\u7684\u7d22\u5f15\u53ef\u4ee5\u662f\u4efb\u4f55\u7c7b\u578b\u7684\u6570\u636e\uff0c\u4f8b\u5982\u5b57\u7b26\u4e32\u6216\u5bf9\u8c61\uff0c\u800c\u4e0d\u4ec5\u4ec5\u662f\u6574\u6570\u3002 \u63d0\u793a\uff1a \u5728\u8ba1\u7b97\u673a\u7f16\u7a0b\u4e2d\uff0c\u9664\u4e86\u5173\u8054\u6570\u7ec4\uff0c\u8fd8\u6709\u5176\u4ed6\u51e0\u79cd\u5e38\u89c1\u7684\u6570\u7ec4\u7c7b\u578b\uff0c\u5305\u62ec\uff1a \u7ebf\u6027\u6570\u7ec4\uff08\u6216\u79f0\u4e3a\u7d22\u5f15\u6570\u7ec4\uff09\uff1a\u8fd9\u662f\u6700\u5e38\u89c1\u7684\u6570\u7ec4\u7c7b\u578b\uff0c\u5176\u4e2d\u6bcf\u4e2a\u5143\u7d20\u90fd\u6709\u4e00\u4e2a\u6570\u5b57\u7d22\u5f15\uff0c\u53ef\u4ee5\u7528\u6765\u5feb\u901f\u8bbf\u95ee\u6570\u7ec4\u4e2d\u7684\u5143\u7d20\u3002\u4f8b\u5982\uff0c\u5728C\u8bed\u8a00\u4e2d\uff0c\u6570\u7ec4\u7684\u6bcf\u4e2a\u5143\u7d20\u90fd\u53ef\u4ee5\u901a\u8fc7\u6570\u7ec4\u4e0b\u6807\u6765\u8bbf\u95ee\u3002 \u591a\u7ef4\u6570\u7ec4\uff1a\u591a\u7ef4\u6570\u7ec4\u662f\u4e00\u79cd\u6570\u7ec4\uff0c\u5176\u4e2d\u6bcf\u4e2a\u5143\u7d20\u4e5f\u662f\u4e00\u4e2a\u6570\u7ec4\u3002\u5728\u4e8c\u7ef4\u6570\u7ec4\u4e2d\uff0c\u6bcf\u4e2a\u5143\u7d20\u90fd\u6709\u4e24\u4e2a\u7d22\u5f15\uff08\u4f8b\u5982\uff0c\u884c\u548c\u5217\uff09\uff0c\u53ef\u4ee5\u7528\u4e8e\u8bbf\u95ee\u6570\u7ec4\u4e2d\u7684\u5143\u7d20\u3002\u5728\u9ad8\u7ef4\u6570\u7ec4\u4e2d\uff0c\u6bcf\u4e2a\u5143\u7d20\u90fd\u5177\u6709\u66f4\u591a\u7684\u7d22\u5f15\u3002 \u52a8\u6001\u6570\u7ec4\uff1a\u52a8\u6001\u6570\u7ec4\u662f\u4e00\u79cd\u53ef\u4ee5\u52a8\u6001\u8c03\u6574\u5927\u5c0f\u7684\u6570\u7ec4\u3002\u5728\u8bb8\u591a\u7f16\u7a0b\u8bed\u8a00\u4e2d\uff0c\u52a8\u6001\u6570\u7ec4\u53ef\u4ee5\u52a8\u6001\u5206\u914d\u5185\u5b58\uff0c\u4ee5\u4fbf\u5728\u7a0b\u5e8f\u8fd0\u884c\u65f6\u6839\u636e\u9700\u8981\u8c03\u6574\u6570\u7ec4\u7684\u5927\u5c0f\u3002 \u5411\u91cf\uff1a\u5411\u91cf\u662f\u4e00\u79cd\u6570\u7ec4\uff0c\u5176\u4e2d\u6bcf\u4e2a\u5143\u7d20\u90fd\u662f\u76f8\u540c\u7684\u6570\u636e\u7c7b\u578b\u3002\u5411\u91cf\u901a\u5e38\u7528\u4e8e\u6267\u884c\u6570\u5b66\u8fd0\u7b97\u6216\u5904\u7406\u5927\u91cf\u6570\u5b57\u6570\u636e\u3002 \u5728 awk \u4e2d\u4f7f\u7528\u6570\u7ec4\u65f6\uff0c\u901a\u5e38\u4f1a\u5c06\u67d0\u4e9b\u503c\u4e0e\u4e00\u4e2a\u5b57\u7b26\u4e32\u76f8\u5173\u8054\uff0c\u4ee5\u4fbf\u5728\u9700\u8981\u65f6\u53ef\u4ee5\u901a\u8fc7\u8be5\u5b57\u7b26\u4e32\u5feb\u901f\u5730\u68c0\u7d22\u8be5\u503c\u3002 awk \u7684\u6570\u7ec4\u662f\u4e00\u4e2a\u5173\u8054\u6570\u7ec4\uff0c\u5176\u4e2d\u6bcf\u4e2a\u5143\u7d20\u90fd\u7531\u4e00\u4e2a\u552f\u4e00\u7684\u952e\u503c\u548c\u4e00\u4e2a\u5bf9\u5e94\u7684\u503c\u7ec4\u6210\u3002\u952e\u503c\uff08\u6216\u79f0\u4e3a\u7d22\u5f15\uff09\u53ef\u4ee5\u662f\u4efb\u4f55\u7c7b\u578b\u7684\u5b57\u7b26\u4e32\u3002 \u6570\u7ec4\u53ef\u4ee5\u901a\u8fc7\u4ee5\u4e0b\u8bed\u6cd5\u8fdb\u884c\u58f0\u660e\uff1a array_name [ index ] = value \u5176\u4e2d\uff0c array_name \u662f\u6570\u7ec4\u7684\u540d\u79f0\uff0c index \u662f\u5143\u7d20\u7684\u7d22\u5f15\u503c\uff0c value \u662f\u5143\u7d20\u7684\u503c\u3002 \u4f8b\u5982\uff0c\u4ee5\u4e0b\u662f\u4e00\u4e2a\u5305\u542b\u4e09\u4e2a\u5143\u7d20\u7684\u5173\u8054\u6570\u7ec4\u7684\u793a\u4f8b\uff1a array [ \"apple\" ] = 1 array [ \"banana\" ] = 2 array [ \"orange\" ] = 3 \u5728\u4e0a\u9762\u7684\u793a\u4f8b\u4e2d\uff0c array \u662f\u4e00\u4e2a\u5173\u8054\u6570\u7ec4\uff0c\u5176\u7d22\u5f15\u4e3a\u5b57\u7b26\u4e32\u7c7b\u578b\uff0c\u800c\u503c\u4e3a\u6574\u6570\u7c7b\u578b\u3002\u53ef\u4ee5\u4f7f\u7528\u4ee5\u4e0b\u7684\u65b9\u5f0f\u8bbf\u95ee\u8be5\u6570\u7ec4\u4e2d\u7684\u5143\u7d20\uff1a value = array [ \"apple\" ] \u5728\u4e0a\u9762\u7684\u793a\u4f8b\u4e2d\uff0c value \u7684\u503c\u5c06\u4e3a 1 \uff0c\u56e0\u4e3a array[\"apple\"] \u7684\u503c\u4e3a 1 \u3002 \u4ee5\u4e0b\u662f\u7528 awk \u547d\u4ee4\u6765\u521b\u5efa\u4e0a\u9762\u90a3\u4e2a\u5305\u542b\u4e09\u4e2a\u5143\u7d20\u7684\u5173\u8054\u6570\u7ec4\uff0c\u904d\u5386\u5e76\u8f93\u51fa\u6570\u7ec4\u503c\uff1a awk 'BEGIN { array[\"apple\"]=1; array[\"banana\"]=2; array[\"orange\"]=3; for(i in array){print array[i]}}' 3 1 2 \u4e0b\u9762\u4f8b\u5b50\u4e2d\uff0c\u6211\u4eec\u4e92\u6362\u4e86\u6570\u7ec4\u7684\u952e\u548c\u503c\u3002 $ awk 'BEGIN {arr[1]=\"apple\";arr[2]=\"banana\";arr[3]=\"orange\";for(i in arr){print arr[i]}}' apple banana orange \u5728\u4e0a\u9762\u7684\u793a\u4f8b\u4e2d\uff0c i \u662f\u6570\u7ec4 arr \u7684\u7d22\u5f15\u503c\uff0c arr[i] \u662f\u6570\u7ec4\u4e2d\u5bf9\u5e94\u7684\u5143\u7d20\u503c\u3002\u901a\u8fc7\u8fd9\u79cd\u65b9\u5f0f\u53ef\u4ee5\u5faa\u73af\u904d\u5386\u6574\u4e2a\u6570\u7ec4\uff0c\u5e76\u8f93\u51fa\u5176\u4e2d\u7684\u5143\u7d20\u3002 \u9664\u4e86\u4f7f\u7528\u5faa\u73af\u904d\u5386\u6570\u7ec4\u4e4b\u5916\uff0c\u8fd8\u53ef\u4ee5\u4f7f\u7528 length \u51fd\u6570\u83b7\u53d6\u6570\u7ec4\u4e2d\u5143\u7d20\u7684\u6570\u91cf\u3002\u4f8b\u5982\uff1a $ awk 'BEGIN { arr[1]=\"apple\"; arr[2]=\"banana\"; arr[3]=\"orange\"; print length(arr) }' 3 \u4e0a\u9762\u7684\u793a\u4f8b\u5c06\u8f93\u51fa\u6570\u5b573\uff0c\u8868\u793a\u6570\u7ec4 arr \u4e2d\u5305\u542b\u4e09\u4e2a\u5143\u7d20\u3002 \u4e3e\u4f8b\uff1a\u53bb\u91cd\u590d\u8bb0\u5f55\u3002 line \u662f\u6570\u7ec4\u540d\uff0c $0 \u662f awk \u8bfb\u53d6\u7684\u5f53\u524d\u884c\u7684\u5185\u5bb9\u3002 line[$0] \u7b49\u4ef7\u4e8e line[\"a\"] \uff0c line[\"b\"] \uff0c......\u3002 \u6211\u4eec\u770b\u6267\u884c\u8fc7\u7a0b\uff1a awk\u8bfb\u5165\u7b2c1\u884c\uff1b \u6267\u884c line[\"a\"] \uff0c\u503c\u4e3a\u7a7a\uff1b \u6c42\u53cd\uff0c\u5219\u7b2c\u4e00\u884c\u7684\u503c\u53d8\u4e3a true \uff0c\u5373 !line[\"a\"]=true \uff1b \u5f53 !line[\"a\"] \u4e3a true \uff0c\u5219\u6253\u5370\u5f53\u524d\u884c\uff0c\u5373\u8f93\u51fa a \u5230\u5c4f\u5e55\uff1b \u6267\u884c line[\"a\"]++ \uff0c\u6ce8\u610f\u7b2c2\u6b65\u4e2d line[\"a\"] \u7684\u503c\u662f\u7a7a\uff0c\u6267\u884c ++ \u540e\u503c\u53d8\u4e3a 1 \u3002 \u540c\u7406\uff0c\u6211\u4eec\u53ef\u4ee5\u770b\u5230\u7b2c2\uff0c3\uff0c4\u884c\u90fd\u8f93\u51fa\u4e86\u3002 \u5f53\u8bfb\u5165\u7b2c5\u884c\u65f6\uff08\u7b2c\u4e8c\u4e2a a \uff09\uff0c\u6267\u884c line[\"a\"] \uff0c\u503c\u4e3a 1 \uff1b !line[\"a\"]=0 \uff0c\u5373false\uff1b\u5219\u4e0d\u6253\u5370\u5f53\u524d\u884c\uff0c\u5373\u4e0d\u8f93\u51fa a \u5230\u5c4f\u5e55\uff1b\u6267\u884c ++ \u540e\u503c\u53d8\u4e3a 2 \u5f53\u8bfb\u5165\u7b2c8\u884c\u65f6\uff08\u7b2c\u4e09\u4e2a a \uff09\uff0c\u6267\u884c line[\"a\"] \uff0c\u503c\u4e3a 2 \uff1b !line[\"a\"]=0 \uff0c\u5373false\uff1b\u5219\u4e0d\u6253\u5370\u5f53\u524d\u884c\uff0c\u5373\u4e0d\u8f93\u51fa a \u5230\u5c4f\u5e55\uff1b\u6267\u884c ++ \u540e\u503c\u53d8\u4e3a 3 \u4ee5\u6b64\u7c7b\u63a8\uff0c\u8bfb\u5165\u7b2c\u4e8c\u4e2a b \uff0c c \uff0c d \uff0c e \uff0c\u90fd\u4e0d\u4f1a\u518d\u8f93\u51fa\u5230\u5c4f\u5e55\uff0c\u4ece\u800c\u5b9e\u73b0\u53bb\u91cd\u8f93\u51fa\u5230\u529f\u80fd\u3002 $ cat > test << EOF a b c d a c d a b b e EOF $ awk '!line[$0]++' test a b c d e \u4e3e\u4f8b\uff1a\u5224\u65ad\u6570\u7ec4\u7d22\u5f15\u662f\u5426\u5b58\u5728\u3002 \u65b9\u6cd5\uff1a in array \uff0c 0 \u8868\u793a\u4e0d\u5b58\u5728\uff0c 1 \u8868\u793a\u5b58\u5728\u3002 $ awk 'BEGIN{array[\"i\"]=\"x\";array[\"j\"]=\"j\";print \"i\" in array, \"y\" in array}' 1 0 $ awk 'BEGIN{array[\"i\"]=\"x\";array[\"j\"]=\"j\";if(\"i\" in array){print \"exits!\"}else{print \"not exists!\"}}' exits! $ awk 'BEGIN{array[\"i\"]=\"x\";array[\"j\"]=\"j\";if(\"abc\" in array){print \"exits!\"}else{print \"not exists!\"}}' not exists! \u4e3e\u4f8b\uff1a\u904d\u5386\u6570\u7ec4\u4e2d\u6bcf\u4e2a\u5143\u7d20\u3002 \u65b9\u6cd5\uff1a for(your_var in array){your_for_body} \uff0c\u6ce8\u610f\uff0cyour_var\u4f1a\u904d\u5386\u6bcf\u4e2a\u7d22\u5f15\u3002 $ awk 'BEGIN{weekday[\"mon\"]=\"Monday\";weekday[\"tue\"]=\"Tuesday\";for(i in weekday){print i,weekday[i]}}' tue Tuesday mon Monday $ awk 'BEGIN{weekday[\"mon\"]=\"Monday\";weekday[\"tue\"]=\"Tuesday\";for(i in weekday){print i\": \"weekday[i]}}' tue: Tuesday mon: Monday \u6ce8\u610f\u4e0b\u9762\u7684\u6362\u884c\u5199\u6cd5\uff0c\u4e0d\u9700\u8981\u53cd\u659c\u6760 \\ \u3002 $ awk 'BEGIN{ arr[\"x\"]=\"welcome\" arr[\"y\"]=\"to\" arr[\"z\"]=\"Shanghai\" for (i in arr) { print i, arr[i] } }' x welcome y to z Shanghai \u793a\u4f8b\uff1a\u683c\u5f0f\u5316\u8f93\u51fa\u7528\u6237\u540d\u548c\u5bc6\u7801\u3002 $ awk -F: '{user[$1]=$3}END{for (i in user){print \"Username: \" i, \"UID: \" user[i]}}' /etc/passwd Username: sshd UID: 476 Username: rpc UID: 482 Username: tftp UID: 488 Username: usbmux UID: 480 Username: srvGeoClue UID: 487 ...... \u793a\u4f8b\uff1a\u663e\u793a\u4e3b\u673a\u8fde\u63a5\u72b6\u6001\u51fa\u73b0\u7684\u6b21\u6570\u3002 # \u4f20\u7edf\u65b9\u6cd5 $ ss -ant | awk 'NR>=2{print $1}' | sort | uniq -c $ ss -ant | awk 'NR!=1{print $1}' | sort | uniq -c 1 ESTAB 6 LISTEN # \u4f7f\u7528awk\u6570\u7ec4 $ ss -ant | awk 'NR>=2{state[$1]++}END{for(i in state){print state[i], i}}' $ ss -ant | awk 'NR!=1{state[$1]++}END{for(i in state){print state[i], i}}' 6 LISTEN 1 ESTAB","title":"5.10.11.\u6570\u7ec4"},{"location":"linux/SRE/05-RegExpress/#51012awk","text":"\u53c2\u8003\uff1a awk \u51fd\u6570\u5b98\u7f51","title":"5.10.12.awk\u51fd\u6570"},{"location":"linux/SRE/05-RegExpress/#510121","text":"\u5728 awk \u4e2d\uff0c\u51fd\u6570\u662f\u4e00\u79cd\u7528\u4e8e\u6267\u884c\u7279\u5b9a\u4efb\u52a1\u6216\u8ba1\u7b97\u7279\u5b9a\u503c\u7684\u53ef\u91cd\u7528\u4ee3\u7801\u5757\u3002 awk \u63d0\u4f9b\u4e86\u8bb8\u591a\u5185\u7f6e\u51fd\u6570\uff0c\u53ef\u4ee5\u7528\u4e8e\u5904\u7406\u6587\u672c\u6570\u636e\u3001\u6267\u884c\u6570\u5b66\u8fd0\u7b97\u3001\u64cd\u4f5c\u5b57\u7b26\u4e32\u7b49\u3002 \u4ee5\u4e0b\u662f\u4e00\u4e9b\u5e38\u7528\u7684awk\u51fd\u6570\u793a\u4f8b\uff1a length(string) \uff1a\u8fd4\u56de\u5b57\u7b26\u4e32\u7684\u957f\u5ea6\u3002 $ awk 'BEGIN { str = \"Hello World\"; len = length(str); print len }' 11 $ cut -d: -f1 /etc/passwd | awk '{print length($1)}' | head -3 4 10 15 substr(string, start, length) \uff1a\u4ece\u6307\u5b9a\u4f4d\u7f6e\u5f00\u59cb\u63d0\u53d6\u5b57\u7b26\u4e32\u7684\u5b50\u4e32\u3002 $ awk 'BEGIN { str = \"Hello World\"; substring = substr(str, 7, 5); print substring }' World sub(regexp, replacement [, target]) \uff1a\u4ece\u5b57\u7b26\u4e32target\u4e2d\u641c\u7d22\u5339\u914dregexp\u7684\u5185\u5bb9\uff0c\u5e76\u628a\u7b2c\u4e00\u4e2a\u5339\u914d\u7684\u5185\u5bb9\u66ff\u6362\u4e3areplacement\u3002\u61d2\u60f0\u6a21\u5f0f\u3002 \u6ce8\u610f\uff1a sub() \u51fd\u6570\u5728\u539f\u59cb\u5b57\u7b26\u4e32\u4e0a\u8fdb\u884c\u66ff\u6362\u64cd\u4f5c\uff0c\u5e76\u8fd4\u56de\u66ff\u6362\u7684\u6b21\u6570\u3002 # \u5728\u539f\u59cb\u5b57\u7b26\u4e32\u4e2d\uff0c\u7b2c\u4e00\u4e2a\u5339\u914d\u5230\u7684\"at\"\u88ab\u66ff\u6362\u4e3a\"ith\"\uff0c\u56e0\u6b64\u8f93\u51fa\u7ed3\u679c\u4e2d\u7684\"at\"\u53d8\u4e3a\"ith\"\uff0c\u5176\u4ed6\u5730\u65b9\u7684\"at\"\u4fdd\u6301\u4e0d\u53d8 $ awk 'BEGIN { str = \"water, water, everywhere\"; sub(/at/, \"ith\", str); print str }' wither, water, everywhere # \u8fd4\u56de\u5339\u914d\u6b21\u6570 $ awk 'BEGIN { str = \"water, water, everywhere\"; str_new = sub(/at/, \"ith\", str); print str_new }' 1 $ echo \"2023:15:35 08:15:26\" | awk 'sub(/:/, \"-\", $0)' 2023 -15:35 08 :15:26 $ echo \"2023:15:35 08:15:26\" | awk 'sub(/:/, \"-\", $1)' 2023 -15:35 08 :15:26 $ echo \"2023:15:35 08:15:26\" | awk 'sub(/:/, \"-\", $2)' 2023 :15:35 08 -15:26 gsub(regexp, replacement [, target])\uff1a\u4ece\u5b57\u7b26\u4e32target\u4e2d\u641c\u7d22\u5339\u914dregexp\u7684\u5185\u5bb9\uff0c\u5e76\u628a\u5168\u90e8\u5339\u914d\u7684\u5185\u5bb9\u66ff\u6362\u4e3areplacement\u3002\u8d2a\u5a6a\u6a21\u5f0f\u3002 # \u5728\u539f\u59cb\u5b57\u7b26\u4e32\u4e2d\uff0c\u5c06\u6240\u6709\u5339\u914d\u5230\u7684\"at\"\u88ab\u66ff\u6362\u4e3a\"ith\" $ awk 'BEGIN { str = \"water, water, everywhere\"; gsub(/at/, \"ith\", str); print str }' wither, wither, everywhere # \u8fd4\u56de\u5339\u914d\u6b21\u6570 $ awk 'BEGIN { str = \"water, water, everywhere\"; str_new = gsub(/at/, \"ith\", str); print str_new }' 2 $ echo \"2023:15:35 08:15:26\" | awk 'gsub(/:/, \"-\", $0)' 2023 -15-35 08 -15-26 $ echo \"2023:15:35 08:15:26\" | awk 'gsub(/:/, \"-\", $1)' 2023 -15-35 08 :15:26 $ echo \"2023:15:35 08:15:26\" | awk 'gsub(/:/, \"-\", $2)' 2023 :15:35 08 -15-26 split(string, array, delimiter) \uff1a\u5c06\u5b57\u7b26\u4e32string\u6309\u6307\u5b9a\u5206\u9694\u7b26delimiter\u62c6\u5206\u6210\u6570\u7ec4array\u7684\u5143\u7d20\u3002 \u6ce8\u610f\uff1a\u7b2c\u4e00\u4e2a\u7d22\u5f15\u503c\u4e3a 1 \uff0c\u7b2c\u4e8c\u4e2a\u7d22\u5f15\u503c\u4e3a 2 . $ awk 'BEGIN { str = \"apple,banana,orange\"; split(str, fruits, \",\"); print fruits[2] }' banana $ head -n2 /etc/passwd | awk '{split($0, array, \":\")}END{print array[1]}' messagebus $ head -n2 /etc/passwd | awk '{split($0, array, \":\")}END{print array[2]}' x $ head -n2 /etc/passwd | awk '{split($0, array, \":\")}END{print array[3]}' 499 $ head -n2 /etc/passwd | awk '{split($0, array, \":\")}END{print array[7]}' /usr/bin/false index(string, search) \uff1a\u5728\u5b57\u7b26\u4e32\u4e2d\u67e5\u627e\u6307\u5b9a\u5b50\u4e32\u7684\u4f4d\u7f6e\u3002 $ awk 'BEGIN { str = \"Hello World\"; pos = index(str, \"World\"); print pos }' 7 sprintf(format, expression) \uff1a\u6839\u636e\u6307\u5b9a\u7684\u683c\u5f0f\u5c06\u8868\u8fbe\u5f0f\u8f6c\u6362\u4e3a\u5b57\u7b26\u4e32\u3002 $ awk 'BEGIN { num = 3.14159; str = sprintf(\"%.2f\", num); print str }' 3 .14 rand() \uff1a\u8fd4\u56de\u4e00\u4e2a\u968f\u673a\u6570\uff0c\u503c\u5728 0 \u548c 1 \u4e4b\u95f4\u5747\u5300\u5206\u5e03\u3002\u8fd9\u4e2a\u503c\u53ef\u4ee5\u662f 0 \uff0c\u4f46\u4e0d\u4f1a\u662f 1 \u3002\u4ece\u4e0b\u9762\u7684\u4f8b\u5b50\u53ef\u4ee5\u770b\u51fa\uff0c\u8fd0\u884c\u7ed3\u679c\u90fd\u662f\u4e00\u6837\u7684\uff0c\u6240\u4ee5\u4ea7\u751f\u968f\u673a\u6570\u7684\u79cd\u5b50\u662f\u4e00\u6837\u7684\u3002 $ awk 'BEGIN{print rand()}' 0 .924046 $ awk 'BEGIN{print rand()}' 0 .924046 $ awk 'BEGIN{print rand()}' 0 .924046 srand() \uff1a\u914d\u5408 rand() \u51fd\u6570\uff0c\u751f\u6210\u968f\u673a\u6570\u79cd\u5b50\u3002 $ awk 'BEGIN{srand();print rand()}' 0 .112006 $ awk 'BEGIN{srand();print rand()}' 0 .663431 $ awk 'BEGIN{srand();print rand()}' 0 .541305 int() \uff1a\u8fd4\u56de\u6574\u6570\u3002 $ awk 'BEGIN{srand();print int(rand()*100)}' 84 $ awk 'BEGIN{srand();print int(rand()*100)}' 66 $ awk 'BEGIN{srand();print int(rand()*100)}' 8 system(command) \uff1a\u6267\u884ccommand\u547d\u4ee4\uff08\u53ef\u4ee5\u662f\u4efb\u4f55\u6709\u6548\u7684Shell\u547d\u4ee4\uff09\u5e76\u8fd4\u56de\u547d\u4ee4\u7684\u9000\u51fa\u72b6\u6001\u7801\u3002\u5141\u8bb8\u5728 awk \u811a\u672c\u4e2d\u6267\u884c\u5916\u90e8\u547d\u4ee4\uff0c\u5e76\u83b7\u53d6\u547d\u4ee4\u6267\u884c\u7684\u7ed3\u679c\u3002 # \u6267\u884cls -l\u547d\u4ee4\uff0c\u5e76\u5c06\u547d\u4ee4\u7684\u9000\u51fa\u72b6\u6001\u7801\u5b58\u50a8\u5728status\u53d8\u91cf\u4e2d\uff0c\u5e76\u6253\u5370status\u53d8\u91cf\u7684\u503c $ awk 'BEGIN { status = system(\"ls -l\"); print \"Exit status:\", status }' total 0 drwxr-xr-x 1 vagrant users 70 Jan 2 15 :54 Desktop drwxr-xr-x 1 vagrant users 0 Jan 2 15 :54 Documents drwxr-xr-x 1 vagrant users 0 Jan 2 15 :54 Downloads drwxr-xr-x 1 vagrant users 0 Jan 2 15 :54 Music drwxr-xr-x 1 vagrant users 0 Jan 2 15 :54 Pictures drwxr-xr-x 1 vagrant users 0 Jan 2 15 :54 Public drwxr-xr-x 1 vagrant users 0 Jan 2 15 :54 Templates drwxr-xr-x 1 vagrant users 0 Jan 2 15 :54 Videos drwxr-xr-x 1 vagrant users 0 Mar 15 2022 bin Exit status: 0 $ awk 'BEGIN{score=100; system(\"echo your score is \" score)}' your score is 100 systime() \uff1a\u5f53\u524d\u65f6\u95f4\u52301970\u5e741\u67081\u65e5\u5230\u79d2\u6570 $ awk 'BEGIN{print systime()}' 1684158395 strftime(format, timestamp) \uff1a\u5c06\u65f6\u95f4\u6233timestamp\u8f6c\u6362\u4e3a\u6307\u5b9a\u683c\u5f0fformat\u7684\u65e5\u671f\u548c\u65f6\u95f4\u5b57\u7b26\u4e32\u3002timestamp\u901a\u5e38\u662f\u4e00\u4e2a\u4ee5\u79d2\u4e3a\u5355\u4f4d\u8868\u793a\u7684\u6574\u6570\u3002 \u5e38\u89c1\u7684\u683c\u5f0f\u5316\u5b57\u7b26\u4e32\u9009\u9879\uff1a %Y \uff1a\u56db\u4f4d\u6570\u7684\u5e74\u4efd\uff08\u4f8b\u5982\uff1a2023\uff09 %m \uff1a\u4e24\u4f4d\u6570\u7684\u6708\u4efd\uff0801-12\uff09 %d \uff1a\u4e24\u4f4d\u6570\u7684\u65e5\u671f\uff0801-31\uff09 %H \uff1a\u4e24\u4f4d\u6570\u7684\u5c0f\u65f6\uff0800-23\uff09 %M \uff1a\u4e24\u4f4d\u6570\u7684\u5206\u949f\uff0800-59\uff09 %S \uff1a\u4e24\u4f4d\u6570\u7684\u79d2\uff0800-60\uff09 %Z \uff1a\u65f6\u533a\u540d\u79f0\uff08\u4f8b\u5982\uff1aGMT\uff09 # \u5c06\u5f53\u524d\u65f6\u95f4\u6233\u8f6c\u6362\u4e3a\u683c\u5f0f\u4e3a\"YYYY-MM-DD HH:MM:SS\"\u7684\u65e5\u671f\u548c\u65f6\u95f4\u5b57\u7b26\u4e32 $ awk 'BEGIN { timestamp = systime(); str = strftime(\"%Y-%m-%d %H:%M:%S\", timestamp); print str }' 2023 -05-15 22 :01:35 # \u5c06\u5f53\u524d\u65f6\u95f4\u6233\u7684\u524d\u4e00\u5c0f\u65f6\uff083600\u79d2\uff09\u8f6c\u6362\u4e3a\u683c\u5f0f\u4e3a\"YYYY-MM-DD HH:MM:SS\"\u7684\u65e5\u671f\u548c\u65f6\u95f4\u5b57\u7b26\u4e32 $ awk 'BEGIN { timestamp = systime()-3600; str = strftime(\"%Y-%m-%d %H:%M:%S\", timestamp); print str }' 2023 -05-15 21 :01:43","title":"5.10.12.1.\u5185\u7f6e\u51fd\u6570"},{"location":"linux/SRE/05-RegExpress/#510122","text":"\u4e3e\u4f8b\uff1a $ cat > func.awk << EOF function max(x,y){ x>y?var=x:var=y return var } BEGIN{print max(a,b)} EOF $ awk -v a = 30 -v b = 20 -f func.awk 30 \u4e3e\u4f8b\uff1a \u5728\u4e0b\u9762\u7684\u4f8b\u5b50\u4e2d\uff0c\u6211\u4eec\u5b9a\u4e49\u4e86\u4e00\u4e2a\u540d\u4e3a square() \u7684\u81ea\u5b9a\u4e49\u51fd\u6570\uff0c\u5b83\u63a5\u53d7\u4e00\u4e2a\u53c2\u6570 x \uff0c\u5e76\u8fd4\u56de x \u7684\u5e73\u65b9\u3002\u7136\u540e\uff0c\u5728\u4e3b\u4ee3\u7801\u5757\u4e2d\uff0c\u6211\u4eec\u58f0\u660e\u4e86\u4e00\u4e2a\u53d8\u91cf num \u5e76\u8d4b\u503c\u4e3a 5 \u3002\u63a5\u4e0b\u6765\uff0c\u6211\u4eec\u8c03\u7528\u4e86\u81ea\u5b9a\u4e49\u51fd\u6570 square() \uff0c\u4f20\u9012 num \u4f5c\u4e3a\u53c2\u6570\uff0c\u5e76\u5c06\u8fd4\u56de\u503c\u5b58\u50a8\u5728\u53d8\u91cf result \u4e2d\u3002\u6700\u540e\uff0c\u6211\u4eec\u6253\u5370\u51fa result \u7684\u503c\u3002 $ cat > func.awk << EOF # \u81ea\u5b9a\u4e49\u51fd\u6570\uff1a\u8ba1\u7b97\u5e73\u65b9 function square(x) { return x * x; } # \u4f7f\u7528\u81ea\u5b9a\u4e49\u51fd\u6570 { num = 5; result = square(num); print \"\u5e73\u65b9\u7ed3\u679c\uff1a\" result; } EOF $ awk -f func.awk \u5e73\u65b9\u7ed3\u679c\uff1a25 \u4e3e\u4f8b\uff1a $ cat > func.awk << EOF # \u81ea\u5b9a\u4e49\u51fd\u6570\uff1a\u8ba1\u7b97\u6570\u7ec4\u5e73\u5747\u503c function calculateAverage(arr, size) { sum = 0; for (i = 1; i <= size; i++) { sum += arr[i]; } return sum / size; } # \u4f7f\u7528\u81ea\u5b9a\u4e49\u51fd\u6570 { # \u5b9a\u4e49\u6570\u7ec4 numbers[1] = 10; numbers[2] = 20; numbers[3] = 30; numbers[4] = 40; numbers[5] = 50; # \u8ba1\u7b97\u6570\u7ec4\u7684\u5e73\u5747\u503c size = 5; average = calculateAverage(numbers, size); print \"\u6570\u7ec4\u7684\u5e73\u5747\u503c\uff1a\" average; } EOF $ awk -f func.awk \u6570\u7ec4\u7684\u5e73\u5747\u503c\uff1a30","title":"5.10.12.2.\u81ea\u5b9a\u4e49\u51fd\u6570"},{"location":"linux/SRE/05-RegExpress/#510123awk","text":"\u4e3e\u4f8b\uff1a # \u6ce8\u610f\u8f6c\u4e49 $ cat > passwd.awk << EOF {if(\\$3>=1000)print \\$1,\\$3} EOF $ awk -F: -f passwd.awk /etc/passwd nobody 65534 vagrant 1000 \u4e0a\u9762\u4f8b\u5b50\u4e5f\u53ef\u4ee5\u5199\u6210\u5982\u4e0b\u811a\u6b65\u683c\u5f0f\u3002 $ cat > test.awk << EOF #!/bin/awk -f # This is an awk script {if(\\$3>=1000)print \\$1,\\$3} EOF $ chmod +x test.awk $ ./test.awk -F: /etc/passwd nobody 65534 vagrant 1000 \u5411awk\u811a\u672c\u4f20\u9012\u53c2\u6570\uff1a \u683c\u5f0f\uff1a awkfile var=value var2=value2 ... inputfile \u8bf4\u660e\uff1a \u4e0a\u9762\u683c\u5f0f\u53d8\u91cf\u5728 BEGIN \u8fc7\u7a0b\u4e2d\u4e0d\u53ef\u7528\uff0c\u76f4\u5230\u9996\u884c\u8f93\u5165\u5b8c\u6210\u4ee5\u540e\uff0c\u53d8\u91cf\u624d\u53ef\u7528\u3002 \u53ef\u4ee5\u901a\u8fc7 -v \u53c2\u6570\uff0c\u8ba9 awk \u5728\u6267\u884c BEGIN \u4e4b\u524d\u5f97\u5230\u53d8\u91cf\u3002 \u547d\u4ee4\u884c\u4e2d\u6bcf\u4e00\u4e2a\u6307\u5b9a\u7684\u53d8\u91cf\u90fd\u9700\u8981\u4e00\u4e2a -v \u53c2\u6570\u3002 \u4e3e\u4f8b\uff1a # x=100\u5728BEGIN{print x}\u533a\u6bb5\u53ef\u7528 $ awk -v x = 100 'BEGIN{print x}{print x+100}' /etc/hosts 100 200 200 200 200 200 200 200 200 200 200 200 200 200 200 200 200 200 200 200 200 200 200 200 # \u4e0d\u52a0-v\u5219x=100\u5728BEGIN{print x}\u533a\u6bb5\u4e0d\u53ef\u7528 $ awk x = 100 'BEGIN{print x}{print x+100}' /etc/hosts awk: fatal: cannot open file ` BEGIN { print x }{ print x+100 } ' for reading (No such file or directory) # \u4fee\u6b63\u4e0a\u9762\u7684\u9519\u8bef\uff0c\u5c06x=100\u653e\u5728\u540e\u9762\uff0c\u56e0\u4e3a\u6ca1\u6709-v\uff0c\u6240\u4ee5x=100\u5728BEGIN{print x}\u533a\u6bb5\u4e0d\u53ef\u7528\uff0c\u7b2c\u4e00\u884c\u8f93\u51fa\u7a7a\u767d $ awk ' BEGIN { print x }{ print x+100 } ' x = 100 /etc/hosts 200 200 200 200 200 200 200 200 200 200 200 200 200 200 200 200 200 200 200 200 200 200 200","title":"5.10.12.3.awk\u811a\u672c"},{"location":"linux/SRE/05-RegExpress/#511","text":"\u663e\u793a /proc/meminfo \u6587\u4ef6\u4e2d\u4ee5\u5927\u5c0fs\u5f00\u5934\u7684\u884c\uff0c\u8981\u6c42\u4f7f\u7528\u4e24\u79cd\u65b9\u6cd5\u3002 cat /proc/meminfo | grep -i \"^s\" cat /proc/meminfo | grep \"^[sS]\" \u663e\u793a /etc/passwd \u6587\u4ef6\u4e2d\u4e0d\u4ee5 /bin/bash \u7ed3\u5c3e\u7684\u884c\u3002 grep -v \"/bin/bash $ \" /etc/passwd \u663e\u793a\u7528\u6237 rpc \u9ed8\u8ba4\u7684shell\u7a0b\u5e8f\u3002 $ grep \"rpc\" /etc/passwd | cut -d \":\" -f 7 /sbin/nologin \u627e\u51fa /etc/passwd \u4e2d\u7684\u4e24\u4f4d\u6216\u4e09\u4f4d\u6570\u3002 grep -Eo \"[:digit:]{2,3}\" /etc/passwd grep -Eo \"[0-9]{2,3}\" /etc/passwd \u8fd9\u91cc\u7528\u5230\u4e86 {} \uff0c\u5c5e\u4e8e\u6269\u5c55\u6b63\u5219\u7b26\u53f7\uff0c\u6240\u4ee5\u8981\u7528 -E \u3002 \u663e\u793aRocky 9\u7684 /etc/grub2.cfg \u6587\u4ef6\u4e2d\uff0c\u81f3\u5c11\u4ee5\u4e00\u4e2a\u7a7a\u767d\u5b57\u7b26\u5f00\u5934\u7684\u4e14\u540e\u9762\u6709\u975e\u7a7a\u767d\u5b57\u7b26\u7684\u884c\u3002\uff08\u6ce8\uff1a /etc/grub2.cfg \u5728openSUSE\u548cUbuntu\u4e2d\u6ca1\u6709\uff09 # \u4e0d\u542b\u9996\u5b57\u7b26\u4e3atab $ sudo grep \"^ \" /etc/grub2.cfg # \u5305\u542b\u9996\u5b57\u7b26\u4e3atab $ sudo grep \"^[[:space:]]\" /etc/grub2.cfg \u627e\u51fa netstat -tan \u547d\u4ee4\u7ed3\u679c\u4e2d\u4ee5 LISTEN \u540e\u8ddf\u4efb\u610f\u591a\u4e2a\u7a7a\u767d\u5b57\u7b26\u7ed3\u5c3e\u7684\u884c\u3002 netstat -tan | grep -E \"LISTEN[[:space:]]+\" \u663e\u793aRocky 9\u4e0a\u6240\u6709UID\u5c0f\u4e8e1000\u4ee5\u5185\u7684\u7528\u6237\u540d\u548cUID\u3002 cat /etc/passwd | cut -d \":\" -f 1 ,3 | grep -E \"\\:[0-9]{1,3} $ \" grep -E \"\\:[0-9]{1,3}\\:[0-9]{1,}\" /etc/passwd | cut -d \":\" -f 1 ,3 \u5728Rocky 9\u4e0a\u663e\u793a\u6587\u4ef6 /etc/passwd \u7528\u6237\u540d\u548cshell\u540c\u540d\u7684\u884c\u3002 $ grep -E \"^([[:alnum:]]+\\b).*\\1 $ \" /etc/passwd sync:x:5:0:sync:/sbin:/bin/sync shutdown:x:6:0:shutdown:/sbin:/sbin/shutdown halt:x:7:0:halt:/sbin:/sbin/halt \u5229\u7528 df \u548c grep \uff0c\u53d6\u51fa\u78c1\u76d8\u5404\u5206\u533a\u5229\u7528\u7387,\u5e76\u4ece\u5927\u5230\u5c0f\u6392\u5e8f\u3002 $ df | tr -s \" \" | cut -d \" \" -f 1 ,5 | sort -n -t \" \" -k 2 devtmpfs 0 % Filesystem Use% tmpfs 0 % tmpfs 0 % /dev/mapper/rl-home 1 % tmpfs 2 % /dev/mapper/rl-root 5 % /dev/nvme0n1p1 23 % \u663e\u793a\u4e09\u4e2a\u7528\u6237 root \uff0c sync \uff0c bin \u7684UID\u548c\u9ed8\u8ba4shell\u3002 $ grep \"^root:\\|^sync:\\|^bin:\" /etc/passwd | cut -d \":\" -f 1 ,7 root:/bin/bash bin:/usr/sbin/nologin \u4f7f\u7528 egrep \u53d6\u51fa /etc/default-1/text_2/local.3/grub \u4e2d\u5176\u57fa\u540d\u548c\u76ee\u5f55\u540d\u3002 # \u57fa\u540d $ echo \"/etc/default-1/text_2/local.3/grub\" | egrep -io \"[[:alpha:]]+ $ \" grub # \u76ee\u5f55\u540d $ echo \"/etc/default-1/text_2/local.3/grub\" | egrep -io \"/([[:alpha:]]+.|_?[[:alpha:]]|[[:alnum:]]+/){7}\" /etc/default-1/text_2/local.3/ \u7edf\u8ba1 last \u547d\u4ee4\u4e2d\u4ee5 vagrant \u767b\u5f55\u7684\u6bcf\u4e2a\u4e3b\u673aIP\u5730\u5740\u767b\u5f55\u6b21\u6570\u3002 $ last | grep vagrant | tr -s \" \" | cut -d \" \" -f 3 | grep -E \"([0-9]{1,3}\\.){1,3}[0-9]{1,3}\" | sort -n | uniq -c 24 192 .168.10.107 38 192 .168.10.109 17 192 .168.10.201 6 192 .168.10.210 2 192 .168.10.220 \u5229\u7528\u6269\u5c55\u6b63\u5219\u8868\u8fbe\u5f0f\u5206\u522b\u8868\u793a0-9\u300110-99\u3001100-199\u3001200-249\u3001250-255\u3002 [ 0 -9 ] | [ 0 -9 ]{ 2 } | 1 [ 0 -9 ]{ 2 } | 2 [ 0 -4 ][ 0 -9 ] | 25 [ 0 -5 ] \u663e\u793a ifconfig \u547d\u4ee4\u7ed3\u679c\u4e2d\u6240\u6709IPv4\u5730\u5740\u3002 $ ifconfig | grep -Eo \"([0-9]{1,3}\\.){3}[0-9]{1,3}\" | grep -v \"^255\" 192 .168.10.210 192 .168.10.255 127 .0.0.1 \u663e\u793a ip addr \u547d\u4ee4\u7ed3\u679c\u4e2d\u6240\u6709IPv4\u5730\u5740\u3002 $ ip addr show eth0 | grep inet | grep eth0 | tr -s \" \" | cut -d \" \" -f 3 | cut -d \"/\" -f 1 192 .168.10.210 $ ip addr show | grep -Eo \"([0-9]{1,3}\\.){3}[0-9]{1,3}\" | grep -v \"^255\" 127 .0.0.1 192 .168.10.210 192 .168.10.255 \u5c06\u6b64\u5b57\u7b26\u4e32Welcome to the linux world\u4e2d\u7684\u6bcf\u4e2a\u5b57\u7b26\u53bb\u91cd\u5e76\u6392\u5e8f\uff0c\u91cd\u590d\u6b21\u6570\u591a\u7684\u6392\u5230\u524d\u9762\u3002 $ echo \"Welcome to the linux world\" | grep -o [[ :alpha: ]] | sort | uniq -c | sort -nr 3 o 3 l 3 e 2 t 1 x 1 W 1 w 1 u 1 r 1 n 1 m 1 i 1 h 1 d 1 c \u5220\u9664 /etc/default/grub \u6587\u4ef6\u4e2d\u6240\u6709\u4ee5\u7a7a\u767d\u5f00\u5934\u7684\u884c\u884c\u9996\u7684\u7a7a\u767d\u5b57\u7b26\u3002 sed '/^$/d' /etc/default/grub \u5220\u9664 /etc/default/grub \u6587\u4ef6\u4e2d\u6240\u6709\u4ee5 # \u5f00\u5934\uff0c\u540e\u9762\u81f3\u5c11\u8ddf\u4e00\u4e2a\u7a7a\u767d\u5b57\u7b26\u7684\u884c\u7684\u884c\u9996\u7684 # \u548c\u7a7a\u767d\u5b57\u7b26\u3002 sed -r '/#[[:space:]]+/d;/#/d' /etc/default/grub \u4e0a\u9762\u8f93\u51fa\u7ed3\u679c\u4e2d\u5305\u542b\u7a7a\u767d\u884c\u3002 \u82e5\u8f93\u51fa\u4e2d\u5220\u9664\u7a7a\u767d\u884c\uff0c\u5219\uff1a sed -r '/#[[:space:]]+/d;/#/d;/^$/d' /etc/default/grub \u5728 /etc/fstab \u6bcf\u4e00\u884c\u884c\u9996\u589e\u52a0 # \u53f7\u3002 sed -r 's/(.*)/#&/' /etc/fstab \u5728 /etc/fstab \u6587\u4ef6\u4e2d\u4e0d\u4ee5 # \u5f00\u5934\u7684\u884c\u7684\u884c\u9996\u589e\u52a0 # \u53f7\uff08\u5305\u62ec\u7a7a\u884c\uff09\u3002 sed -r 's/^[^#].*/#&/' -r 's/^$/#/' /etc/default/grub \u901a\u8fc7\u547d\u4ee4 rpm -qa --last |awk -F ' ' '{print $1}' \u5f97\u5230\u6700\u65b0\u5b89\u88c5\u7684\u5305\u5217\u8868\u3002\u7edf\u8ba1\u6240\u6709 x86_64 \u7ed3\u5c3e\u7684\u5b89\u88c5\u5305\u540d\u4ee5 . \u5206\u9694\u5012\u6570\u7b2c\u4e8c\u4e2a\u5b57\u6bb5\u7684\u91cd\u590d\u6b21\u6570\u3002 $ rpm -qa --last | awk -F ' ' '{print $1}' | sed -nr '/x86_64$/s@.*\\.(.*)\\.x86_64@\\1@p' | sort -r | uniq -c 75 el9_0 563 el9 3 7 1 5 2 4 2 3 10 2 29 1 \u5728openSUSE\u4e2d\u7edf\u8ba1 /etc/rc.status \u6587\u4ef6\u4e2d\u6bcf\u4e2a\u5355\u8bcd\u7684\u51fa\u73b0\u6b21\u6570\uff0c\u5e76\u6392\u5e8f\uff08\u7528grep\u548csed\u4e24\u79cd\u65b9\u6cd5\u5206\u522b\u5b9e\u73b0\uff09\u3002 grep -Eo \"[a-zA-Z]+\" /etc/rc.status | sort | uniq -c cat /etc/rc.status | sed -r 's/[^[:alpha:]]+/\\n/g' | sed '/^$/d' | sort | uniq -c | sort -nr \u5c06\u6587\u672c\u6587\u4ef6\u7684n\u548cn+1\u884c\u5408\u5e76\u4e3a\u4e00\u884c\uff0cn\u4e3a\u5947\u6570\u884c\u3002 $ cat < sed.txt 1aa 2bb 3cc 4dd 5ee 6ff 7gg EOF $ sed -n 'N;s/\\n//p' sed.txt 1aa2bb 3cc4dd 5ee6ff $ sed 'N;s/\\n//' sed.txt 1aa2bb 3cc4dd 5ee6ff 7gg \u5bf9\u4e00\u4e32\u6570\u5b57\u8fdb\u884c\u6c42\u548c\u3002 $ cat < number.txt 1 2 3 4 5 6 EOF $ tr ' ' + < number.txt | bc 21 $ sum = 0 ; for i in ` cat number.txt ` ; do let sum += i ; done ; echo $sum 21 $ awk '{sum=0;for(i=1;i<=NF;i++){sum+=i};print sum}' number.txt 21 \u53d6\u51fa\u5b57\u7b26\u4e32\u4e2d\u7684\u6570\u5b57\u3002 $ echo 'kdajl;3k8jd33la5kj23f90ld02sakjflakjdslf' | awk -F \"\" ' { for(i=1;i<=NF;i++) { if($i ~ /[0-9]/) { str=(str $i) } }; print str }' 38335239002 host.log \u6587\u4ef6\u5185\u5bb9\u5982\u4e0b\uff0c\u63d0\u53d6 .edu.cn \u524d\u9762\u7684\u4e3b\u673a\u540d\uff0c\u5e76\u56de\u5199\u5230\u8be5\u6587\u4ef6\u4e2d\u3002 $ cat > host.log << EOF 1 www.edu.cn 2 blog.edu.cn 3 learning.edu.cn 4 java.edu.cn 5 nodejs.edu.cn 6 k8s.eud.cn 7 linux.edu.cn 8 python.edu.cn 9 learning.edu.cn 10 java.edu.cn 11 nodejs.edu.cn 12 www.edu.cn EOF # \u5bf9\u6bd4 $ awk -F '[ .]' '{print $1}' host.log 1 2 3 4 5 6 7 8 9 10 11 12 $ awk -F '[ .]' '{print $2}' host.log www blog learning java nodejs k8s linux python learning java nodejs www # \u4ee5\u7a7a\u683c\u6216\u8005.\u4e3a\u5206\u9694\u7b26\uff0c\u6253\u5370\u7b2c\u4e8c\u5217\uff08\u4e3b\u673a\u540d\uff09\uff0c\u8ffd\u52a0\u5199\u5165\u539f\u6587\u4ef6 $ awk -F '[ .]' '{print $2}' host.log >> host.log $ cat host.log 1 www.edu.cn 2 blog.edu.cn 3 learning.edu.cn 4 java.edu.cn 5 nodejs.edu.cn 6 k8s.eud.cn 7 linux.edu.cn 8 python.edu.cn 9 learning.edu.cn 10 java.edu.cn 11 nodejs.edu.cn 12 www.edu.cn www blog learning java nodejs k8s linux python learning java nodejs www \u7edf\u8ba1\u6587\u4ef6 /etc/fstab \u4e2d\u6bcf\u4e2a\u6587\u4ef6\u7cfb\u7edf\u7c7b\u578b\u51fa\u73b0\u7684\u6b21\u6570\u3002 # \u4ee5UUID\u5f00\u5934\uff0c\u4e00\u4e2a\u6216\u591a\u4e2a\u7a7a\u683c\u4e3a\u5206\u9694\u7b26\uff0c\u8bfb\u53d6\u7b2c\u4e09\u5217\uff08\u5373\u6587\u4ef6\u7cfb\u7edf\u7c7b\u578b\uff09\u5e76\u8ba1\u6570\u3002 $ awk -F ' +' '/^UUID/{fs[$3]++}END{for(i in fs){print i, fs[i]}}' /etc/fstab swap 1 btrfs 10 vfat 1 # \u65b9\u6cd52 $ awk -F ' +' '/^UUID/{print $3}' /etc/fstab | uniq -c 10 btrfs 1 swap 1 vfat \u7edf\u8ba1\u6587\u4ef6 /etc/fstab \u4e2d\u6bcf\u4e2a\u5355\u8bcd\u51fa\u73b0\u7684\u6b21\u6570\u3002 $ awk -F \"[^[:alpha:]]\" '{for(i=1;i<=NF;i++)word[$i]++}END{for(a in word)if(a!=\"\")print a,word[a]}' /etc/fstab swap 2 B 1 srv 2 btrfs 10 snapshots 2 vfat 1 opt 2 cbaef 10 UUID 12 E 1 ecf 1 CD 1 cf 1 arm 2 a 11 c 2 tmp 2 usr 2 var 2 afa 20 home 2 d 10 utf 1 e 2 efi 3 grub 2 boot 3 subvol 9 root 2 local 2 defaults 2 f 10 \u63d0\u53d6\u5b57\u7b26\u4e32 Yd$@C#M05MD9&8923+Vip3wZ!33*44&55 \u4e2d\u6240\u6709\u7684\u6570\u5b57\u3002 # \u5bf9\u6bd4\u5355\u5f15\u53f7\u548c\u53cc\u5f15\u53f7\u7684\u533a\u522b\u3002 $ echo \"Yd $@ C#M05MD9&8923+Vip3wZ!33*44&55\" echo \"Yd $@ C#M05MD9&8923+Vip3wZcgcreate -g cpu:mygroup44&55\" YdC#M05MD9 & 8923 +Vip3wZcgcreate -g cpu:mygroup44 & 55 $ echo 'Yd$@C#M05MD9&8923+Vip3wZ!33*44&55' Yd $@ C#M05MD9 & 8923 +Vip3wZ!33*44 & 55 $ echo 'Yd$@C#M05MD9&8923+Vip3wZ!33*44&55' | awk '{gsub(/[^0-9]/,\"\");print $0}' 05989233334455 $ echo 'Yd$@C#M05MD9&8923+Vip3wZ!33*44&55' | awk -F '[^0-9]' '{for(i=1;i<=NF;i++){printf \"%s\", $i}}' 05989233334455 $ echo 'Yd$@C#M05MD9&8923+Vip3wZ!33*44&55' | awk -F \"\" '{for(i=1;i<=NF;i++){if($i ~ /[[:digit:]]/){str=$i;str1=(str1 str)}};print str1}' 05989233334455 $ echo 'Yd$@C#M05MD9&8923+Vip3wZ!33*44&55' | awk -F '' '{for(i=1;i<=NF;i++){if($i ~ /[[:digit:]]/){str=$i;str1=(str1 str)}};print str1}' # \u6ce8\u610f\uff0c\u5982\u679c\u5199\u6210\u5982\u4e0b\u683c\u5f0f\uff0c\u5219\u62a5\u9519\u3002 $ echo 'Yd$@C#M05MD9&8923+Vip3wZ!33*44&55' | awk -F '' '{for(i=1;i<=NF;i++){if($i ~ /[[:digit:]]/){str=$i;str1=(str1 str)}};print str1}' # \u6ce8\u610f\uff0c\u5982\u679c\u5199\u6210\u5982\u4e0b\u683c\u5f0f\uff0c\u5219\u8f93\u51fa\u539f\u5b57\u7b26\u4e32\u3002 $ echo 'Yd$@C#M05MD9&8923+Vip3wZ!33*44&55' | awk -F ' ' '{for(i=1;i<=NF;i++){if($i ~ /[[:digit:]]/){str=$i;str1=(str1 str)}};print str1}' \u751f\u6210500\u4e2a\u968f\u673a\u6570\uff0c\u4fdd\u5b58\u5230\u6587\u4ef6random.txt\u4e2d\uff0c\u683c\u5f0f\u4e3a 100,20,61,98... \uff0c\u53d6\u51fa\u5176\u4e2d\u6700\u5927\u6574\u6570\u548c\u6700\u5c0f\u6574\u6570\u3002 $ str = \"\" ; for (( i = 1 ; i< = 500 ; i++ )) ; do if [ $i -ne 500 ] ; then str += \" $RANDOM ,\" ; else str += \" $RANDOM \" ; fi ; done ; echo \" $str \" > random.txt $ cat random.txt 11308 ,8764,2075,9411,...... $ awk -F, '{max=$1;min=$1;for(i=1;i<=NF;i++){if($i>max){max=$i}else{if($i200){system(\"iptables -A INPUT -s \" i \" -j REJECT;\")}}}' \u5c06\u4e0b\u9762\u5185\u5bb9\u4e2dFQDN\u53d6\u51fa\uff0c\u5e76\u6839\u636e\u5176\u8fdb\u884c\u8ba1\u6570\uff0c\u4ece\u9ad8\u5230\u4f4e\u6392\u5e8f\u3002 $ cat > fqdn.txt << EOF http://mail.edu.com/index.html http://www.edu.com/test.html http://study.edu.com/index.html http://blog.edu.com/index.html http://www.edu.com/images/logo.jpg http://blog.edu.com/20080102.html EOF $ awk -F \"/\" '{url[$3]++}END{for(i in url){print url[i], i}}' fqdn.txt | sort -nr 2 www.edu.com 2 blog.edu.com 1 study.edu.com 1 mail.edu.com \u5c06\u4ee5\u4e0b\u2f42\u672c\u4ee5inode\u4e3a\u6807\u8bb0\uff0c\u5bf9inode\u76f8\u540c\u7684counts\u8fdb\u2f8f\u7d2f\u52a0\uff0c\u5e76\u4e14\u7edf\u8ba1\u51fa\u540c\u4e00inode\u4e2d\uff0cbeginnumber\u7684\u6700\u5c0f\u503c\u548cendnumber\u7684\u6700\u5927\u503c\u3002 inode | beginnumber | endnumber | counts | 106 | 3363120000 | 3363129999 | 10000 | 106 | 3368560000 | 3368579999 | 20000 | 310 | 3337000000 | 3337000100 | 101 | 310 | 3342950000 | 3342959999 | 10000 | 310 | 3362120960 | 3362120961 | 2 | 311 | 3313460102 | 3313469999 | 9898 | 311 | 3313470000 | 3313499999 | 30000 | 311 | 3362120962 | 3362120963 | 2 | \u8f93\u51fa\u7684\u7ed3\u679c\u683c\u5f0f\u4e3a\uff1a 310 | 3337000000 | 3362120961 | 10103 | 311 | 3313460102 | 3362120963 | 39900 | 106 | 3363120000 | 3368579999 | 30000 | $ cat > inode.text << EOF inode|beginnumber|endnumber|counts| 106|3363120000|3363129999|10000| 106|3368560000|3368579999|20000| 310|3337000000|3337000100|101| 310|3342950000|3342959999|10000| 310|3362120960|3362120961|2| 311|3313460102|3313469999|9898| 311|3313470000|3313499999|30000| 311|3362120962|3362120963|2| EOF $ awk -F '|' -v OFS = '|' '/^[0-9]/{inode[$1]++; if(!bn[$1]){bn[$1]=$2}else if(bn[$1]>$2) {bn[$1]=$2}; if(en[$1]<$3)en[$1]=$3;cnt[$1]+=$(NF-1)} END{for(i in inode)print i,bn[i],en[i],cnt[i]}' inode.text 106 | 3363120000 | 3368579999 | 30000 310 | 3337000000 | 3362120961 | 10103 311 | 3313460102 | 3362120963 | 39900","title":"5.11.\u5c0f\u7ec3\u4e60"},{"location":"linux/SRE/06-FileLookup/","text":"\u7b2c\u516d\u7ae0 \u6587\u4ef6\u67e5\u627e \u00b6 \u5e38\u7528\u6587\u4ef6\u67e5\u627e\u547d\u4ee4\uff1a locate\u547d\u4ee4 \u00b6 locate \u662f\u4e00\u4e2a\u5728 Linux \u7cfb\u7edf\u4e0a\u7528\u4e8e\u5feb\u901f\u641c\u7d22\u6587\u4ef6\u548c\u76ee\u5f55\u7684\u547d\u4ee4\u3002\u5b83\u4f7f\u7528\u9884\u5148\u6784\u5efa\u7684\u6587\u4ef6\u6570\u636e\u5e93 /var/lib/mlocate/mlocate.db \u8fdb\u884c\u641c\u7d22\uff0c\u56e0\u6b64\u6bd4\u76f4\u63a5\u5728\u6587\u4ef6\u7cfb\u7edf\u4e0a\u641c\u7d22\u8981\u5feb\u5f97\u591a\u3002 \u4f7f\u7528 updatedb \u547d\u4ee4\u624b\u52a8\u66f4\u65b0\u6587\u4ef6\u6570\u636e\u5e93 /var/lib/mlocate/mlocate.db \uff0c\u7d22\u5f15\u6784\u5efa\u8fc7\u7a0b\u9700\u8981\u904d\u5386\u6574\u4e2a\u6839\u6587\u4ef6\u7cfb\u7edf\uff0c\u5f88\u6d88\u8017\u8d44\u6e90\u3002 \u6ce8\u610f\uff0c\u7531\u4e8e locate \u4f7f\u7528\u9884\u5148\u6784\u5efa\u7684\u6587\u4ef6\u6570\u636e\u5e93\uff0c\u56e0\u6b64\u5728\u66f4\u65b0\u6587\u4ef6\u6570\u636e\u5e93\u4e4b\u524d\uff0c\u65b0\u521b\u5efa\u6216\u79fb\u52a8\u7684\u6587\u4ef6\u53ef\u80fd\u4e0d\u4f1a\u7acb\u5373\u51fa\u73b0\u5728\u641c\u7d22\u7ed3\u679c\u4e2d\u3002 \u5728openSUSE 15\u4e2d\u9ed8\u8ba4\u6ca1\u6709\u5b89\u88c5\uff0c\u9700\u8981\u624b\u52a8\u5b89\u88c5\u4e0b\u9762\u7684\u8f6f\u4ef6\u5305\u3002 sudo zypper ref sudo zypper in mlocate sudo updatedb locate \u547d\u4ee4\u7684\u7279\u70b9\uff1a \u67e5\u627e\u901f\u5ea6\u5feb \u6a21\u7cca\u67e5\u627e \u975e\u5b9e\u65f6\u67e5\u627e \u641c\u7d22\u7684\u662f\u6587\u4ef6\u7684\u5168\u8def\u5f84\uff0c\u4e0d\u4ec5\u4ec5\u662f\u6587\u4ef6\u540d \u53ef\u80fd\u53ea\u641c\u7d22\u5f53\u524d\u7528\u6237\u5177\u5907\u8bfb\u53d6 r \u548c\u6267\u884c x \u6743\u9650\u7684\u76ee\u5f55 locate \u547d\u4ee4\u7684\u683c\u5f0f\uff1a locate [OPTIONS] PATTERN \u5e38\u7528\u9009\u9879\uff1a -i \uff1a\u5ffd\u7565\u5927\u5c0f\u5199\u3002 -r \uff1a\u4f7f\u7528\u6b63\u5219\u8868\u8fbe\u5f0f\u8fdb\u884c\u6a21\u5f0f\u5339\u914d\u3002 -l \uff1a\u4ec5\u663e\u793a\u6587\u4ef6\u8def\u5f84\uff0c\u800c\u4e0d\u663e\u793a\u6587\u4ef6\u540d\u3002 -c \uff1a\u4ec5\u663e\u793a\u5339\u914d\u7ed3\u679c\u7684\u8ba1\u6570\u3002 -b \uff1a\u53ea\u5339\u914d\u57fa\u672c\u540d\u79f0\u800c\u4e0d\u662f\u5168\u8def\u5f84\u540d\u3002 -n N \uff1a\u53ea\u5217\u4e3e\u524dN\u4e2a\u5339\u914d\u9879\u76ee\u3002 -q \uff1a\u5b89\u9759\u6a21\u5f0f\uff0c\u4e0d\u663e\u793a\u4efb\u4f55\u9519\u8bef\u4fe1\u606f\u3002 man locate \u83b7\u53d6\u66f4\u591a\u8be6\u7ec6\u4fe1\u606f\u548c\u9009\u9879\u8bf4\u660e\u3002 \u4e3e\u4f8b\uff1a\u641c\u7d22\u540d\u4e3a bashrc \u7684\u6587\u4ef6\uff0c\u6ce8\u610f\uff0c\u8fd9\u91cc\u662f\u641c\u7d22\u6587\u4ef6\u540d\u6216\u8def\u5f84\u540d\u4e2d\u5305\u542b bashrc \u7684\u6587\u4ef6 $ locate bashrc /etc/bash.bashrc /etc/skel/.bashrc /home/vagrant/.bashrc \u8981\u641c\u7d22\u4ee5 \"image\" \u5f00\u5934\u7684\u6587\u4ef6\uff0c\u5ffd\u7565\u5927\u5c0f\u5199\uff1a locate -i '^image' \u4e3e\u4f8b\uff1a\u4f7f\u7528\u6b63\u5219\u8868\u8fbe\u5f0f\u641c\u7d22\u4ee5 .conf \u4e3a\u6269\u5c55\u540d\u7684\u6587\u4ef6\uff1a locate -r '\\.conf$' find\u547d\u4ee4 \u00b6 find \u547d\u4ee4\u662f\u5b9e\u65f6\u67e5\u627e\u5de5\u5177\uff0c\u901a\u8fc7\u904d\u5386\u6307\u5b9a\u8def\u5f84\u5b8c\u6210\u6587\u4ef6\u67e5\u627e\u3002 \u7279\u70b9\uff1a \u67e5\u627e\u901f\u5ea6\u7565\u6162 \u7cbe\u786e\u67e5\u627e \u5b9e\u65f6\u67e5\u627e \u67e5\u627e\u6761\u4ef6\u4e30\u5bcc \u53ef\u80fd\u53ea\u641c\u7d22\u5f53\u524d\u7528\u6237\u5177\u5907\u8bfb\u53d6 r \u548c\u6267\u884c x \u6743\u9650\u7684\u76ee\u5f55 find \u547d\u4ee4\u7684\u683c\u5f0f\uff1a find [OPTIONS] [PATH] [CONDITIONS] [ACTIONS] [PATH]\uff1a\u6307\u5b9a\u5177\u4f53\u76ee\u6807\u8def\u5f84\uff0c\u9ed8\u8ba4\u4e3a\u5f53\u524d\u76ee\u5f55\u3002 [CONDITIONS]\uff1a\u6307\u5b9a\u67e5\u627e\u6807\u51c6\uff0c\u53ef\u4ee5\u662f\u6587\u4ef6\u540d\u3001\u6587\u4ef6\u5927\u5c0f\u3001\u6587\u4ef6\u7c7b\u578b\u3001\u6743\u9650\u7b49\uff0c\u9ed8\u8ba4\u4e3a\u627e\u51fa\u6307\u5b9a\u8def\u5f84\u4e0b\u6240\u6709\u6587\u4ef6\u3002 [ACTIONS]\uff1a\u5bf9\u7b26\u5408\u6761\u4ef6\u7684\u6587\u4ef6\u6267\u884c\u7684\u64cd\u4f5c\uff0c\u9ed8\u8ba4\u8f93\u51fa\u5230\u5c4f\u5e55\u3002 -maxdepth level \uff1a\u6700\u5927\u641c\u7d22\u76ee\u5f55\u6df1\u5ea6\uff0c\u6307\u5b9a\u76ee\u5f55\u4e0b\u7684\u6587\u4ef6\u4e3a\u7b2c\u4e00\u7ea7\u3002 -mindepth level \uff1a\u6700\u5c0f\u641c\u7d22\u76ee\u5f55\u6df1\u5ea6\u3002 \u4e3e\u4f8b\uff1a\u53ea\u641c\u7d22 /etc \u76ee\u5f55\u7b2c\u4e8c\u7ea7\u3002 find /etc -maxdepth 2 -mindepth 2 find \u547d\u4ee4\u9ed8\u8ba4\u662f\u5148\u5904\u7406\u76ee\u5f55\uff0c\u518d\u5904\u7406\u76ee\u5f55\u5185\u90e8\u7684\u6587\u4ef6\u3002\u9009\u9879 -depth \u4f1a\u4fee\u6539 find \u547d\u4ee4\u5904\u7406\u4f18\u5148\u987a\u5e8f\uff0c\u5148\u5904\u7406\u76ee\u5f55\u5185\u90e8\u7684\u6587\u4ef6\uff0c\u518d\u5904\u7406\u76ee\u5f55\u3002 \u6839\u636e\u6587\u4ef6\u540d\u548cinode\u67e5\u627e\uff1a -name \"FILENAME\" \uff1a\u652f\u6301\u4f7f\u7528\u901a\u914d\u7b26\uff0c\u5982 * \uff0c \uff1f \uff0c [] \uff0c [^] \uff0c\u6ce8\u610f\uff0c\u901a\u914d\u7b26\u8981\u7528\u53cc\u5f15\u53f7\u3002 -iname \"FILENAME\" \uff1a\u4e0d\u533a\u5206\u5b57\u6bcd\u5927\u5c0f\u5199\u3002 -inum N \uff1a\u6309inode\u53f7\u67e5\u627e\u3002 -samefile NAME \uff1a\u67e5\u627e\u76f8\u540cinode\u53f7\u7684\u6587\u4ef6\u3002 -links N \uff1a\u94fe\u63a5\u6570\u4e3a N \u7684\u6587\u4ef6\u3002 -regex \"PATTERN\" \uff1a\u4ee5PATTERN\u5339\u914d\u6574\u4e2a\u6587\u4ef6\u8def\u5f84\uff0c\u800c\u975e\u6587\u4ef6\u540d\u79f0\u3002 xargs\u547d\u4ee4 \u00b6","title":"\u7b2c\u516d\u7ae0 \u6587\u4ef6\u67e5\u627e"},{"location":"linux/SRE/06-FileLookup/#_1","text":"\u5e38\u7528\u6587\u4ef6\u67e5\u627e\u547d\u4ee4\uff1a","title":"\u7b2c\u516d\u7ae0 \u6587\u4ef6\u67e5\u627e"},{"location":"linux/SRE/06-FileLookup/#locate","text":"locate \u662f\u4e00\u4e2a\u5728 Linux \u7cfb\u7edf\u4e0a\u7528\u4e8e\u5feb\u901f\u641c\u7d22\u6587\u4ef6\u548c\u76ee\u5f55\u7684\u547d\u4ee4\u3002\u5b83\u4f7f\u7528\u9884\u5148\u6784\u5efa\u7684\u6587\u4ef6\u6570\u636e\u5e93 /var/lib/mlocate/mlocate.db \u8fdb\u884c\u641c\u7d22\uff0c\u56e0\u6b64\u6bd4\u76f4\u63a5\u5728\u6587\u4ef6\u7cfb\u7edf\u4e0a\u641c\u7d22\u8981\u5feb\u5f97\u591a\u3002 \u4f7f\u7528 updatedb \u547d\u4ee4\u624b\u52a8\u66f4\u65b0\u6587\u4ef6\u6570\u636e\u5e93 /var/lib/mlocate/mlocate.db \uff0c\u7d22\u5f15\u6784\u5efa\u8fc7\u7a0b\u9700\u8981\u904d\u5386\u6574\u4e2a\u6839\u6587\u4ef6\u7cfb\u7edf\uff0c\u5f88\u6d88\u8017\u8d44\u6e90\u3002 \u6ce8\u610f\uff0c\u7531\u4e8e locate \u4f7f\u7528\u9884\u5148\u6784\u5efa\u7684\u6587\u4ef6\u6570\u636e\u5e93\uff0c\u56e0\u6b64\u5728\u66f4\u65b0\u6587\u4ef6\u6570\u636e\u5e93\u4e4b\u524d\uff0c\u65b0\u521b\u5efa\u6216\u79fb\u52a8\u7684\u6587\u4ef6\u53ef\u80fd\u4e0d\u4f1a\u7acb\u5373\u51fa\u73b0\u5728\u641c\u7d22\u7ed3\u679c\u4e2d\u3002 \u5728openSUSE 15\u4e2d\u9ed8\u8ba4\u6ca1\u6709\u5b89\u88c5\uff0c\u9700\u8981\u624b\u52a8\u5b89\u88c5\u4e0b\u9762\u7684\u8f6f\u4ef6\u5305\u3002 sudo zypper ref sudo zypper in mlocate sudo updatedb locate \u547d\u4ee4\u7684\u7279\u70b9\uff1a \u67e5\u627e\u901f\u5ea6\u5feb \u6a21\u7cca\u67e5\u627e \u975e\u5b9e\u65f6\u67e5\u627e \u641c\u7d22\u7684\u662f\u6587\u4ef6\u7684\u5168\u8def\u5f84\uff0c\u4e0d\u4ec5\u4ec5\u662f\u6587\u4ef6\u540d \u53ef\u80fd\u53ea\u641c\u7d22\u5f53\u524d\u7528\u6237\u5177\u5907\u8bfb\u53d6 r \u548c\u6267\u884c x \u6743\u9650\u7684\u76ee\u5f55 locate \u547d\u4ee4\u7684\u683c\u5f0f\uff1a locate [OPTIONS] PATTERN \u5e38\u7528\u9009\u9879\uff1a -i \uff1a\u5ffd\u7565\u5927\u5c0f\u5199\u3002 -r \uff1a\u4f7f\u7528\u6b63\u5219\u8868\u8fbe\u5f0f\u8fdb\u884c\u6a21\u5f0f\u5339\u914d\u3002 -l \uff1a\u4ec5\u663e\u793a\u6587\u4ef6\u8def\u5f84\uff0c\u800c\u4e0d\u663e\u793a\u6587\u4ef6\u540d\u3002 -c \uff1a\u4ec5\u663e\u793a\u5339\u914d\u7ed3\u679c\u7684\u8ba1\u6570\u3002 -b \uff1a\u53ea\u5339\u914d\u57fa\u672c\u540d\u79f0\u800c\u4e0d\u662f\u5168\u8def\u5f84\u540d\u3002 -n N \uff1a\u53ea\u5217\u4e3e\u524dN\u4e2a\u5339\u914d\u9879\u76ee\u3002 -q \uff1a\u5b89\u9759\u6a21\u5f0f\uff0c\u4e0d\u663e\u793a\u4efb\u4f55\u9519\u8bef\u4fe1\u606f\u3002 man locate \u83b7\u53d6\u66f4\u591a\u8be6\u7ec6\u4fe1\u606f\u548c\u9009\u9879\u8bf4\u660e\u3002 \u4e3e\u4f8b\uff1a\u641c\u7d22\u540d\u4e3a bashrc \u7684\u6587\u4ef6\uff0c\u6ce8\u610f\uff0c\u8fd9\u91cc\u662f\u641c\u7d22\u6587\u4ef6\u540d\u6216\u8def\u5f84\u540d\u4e2d\u5305\u542b bashrc \u7684\u6587\u4ef6 $ locate bashrc /etc/bash.bashrc /etc/skel/.bashrc /home/vagrant/.bashrc \u8981\u641c\u7d22\u4ee5 \"image\" \u5f00\u5934\u7684\u6587\u4ef6\uff0c\u5ffd\u7565\u5927\u5c0f\u5199\uff1a locate -i '^image' \u4e3e\u4f8b\uff1a\u4f7f\u7528\u6b63\u5219\u8868\u8fbe\u5f0f\u641c\u7d22\u4ee5 .conf \u4e3a\u6269\u5c55\u540d\u7684\u6587\u4ef6\uff1a locate -r '\\.conf$'","title":"locate\u547d\u4ee4"},{"location":"linux/SRE/06-FileLookup/#find","text":"find \u547d\u4ee4\u662f\u5b9e\u65f6\u67e5\u627e\u5de5\u5177\uff0c\u901a\u8fc7\u904d\u5386\u6307\u5b9a\u8def\u5f84\u5b8c\u6210\u6587\u4ef6\u67e5\u627e\u3002 \u7279\u70b9\uff1a \u67e5\u627e\u901f\u5ea6\u7565\u6162 \u7cbe\u786e\u67e5\u627e \u5b9e\u65f6\u67e5\u627e \u67e5\u627e\u6761\u4ef6\u4e30\u5bcc \u53ef\u80fd\u53ea\u641c\u7d22\u5f53\u524d\u7528\u6237\u5177\u5907\u8bfb\u53d6 r \u548c\u6267\u884c x \u6743\u9650\u7684\u76ee\u5f55 find \u547d\u4ee4\u7684\u683c\u5f0f\uff1a find [OPTIONS] [PATH] [CONDITIONS] [ACTIONS] [PATH]\uff1a\u6307\u5b9a\u5177\u4f53\u76ee\u6807\u8def\u5f84\uff0c\u9ed8\u8ba4\u4e3a\u5f53\u524d\u76ee\u5f55\u3002 [CONDITIONS]\uff1a\u6307\u5b9a\u67e5\u627e\u6807\u51c6\uff0c\u53ef\u4ee5\u662f\u6587\u4ef6\u540d\u3001\u6587\u4ef6\u5927\u5c0f\u3001\u6587\u4ef6\u7c7b\u578b\u3001\u6743\u9650\u7b49\uff0c\u9ed8\u8ba4\u4e3a\u627e\u51fa\u6307\u5b9a\u8def\u5f84\u4e0b\u6240\u6709\u6587\u4ef6\u3002 [ACTIONS]\uff1a\u5bf9\u7b26\u5408\u6761\u4ef6\u7684\u6587\u4ef6\u6267\u884c\u7684\u64cd\u4f5c\uff0c\u9ed8\u8ba4\u8f93\u51fa\u5230\u5c4f\u5e55\u3002 -maxdepth level \uff1a\u6700\u5927\u641c\u7d22\u76ee\u5f55\u6df1\u5ea6\uff0c\u6307\u5b9a\u76ee\u5f55\u4e0b\u7684\u6587\u4ef6\u4e3a\u7b2c\u4e00\u7ea7\u3002 -mindepth level \uff1a\u6700\u5c0f\u641c\u7d22\u76ee\u5f55\u6df1\u5ea6\u3002 \u4e3e\u4f8b\uff1a\u53ea\u641c\u7d22 /etc \u76ee\u5f55\u7b2c\u4e8c\u7ea7\u3002 find /etc -maxdepth 2 -mindepth 2 find \u547d\u4ee4\u9ed8\u8ba4\u662f\u5148\u5904\u7406\u76ee\u5f55\uff0c\u518d\u5904\u7406\u76ee\u5f55\u5185\u90e8\u7684\u6587\u4ef6\u3002\u9009\u9879 -depth \u4f1a\u4fee\u6539 find \u547d\u4ee4\u5904\u7406\u4f18\u5148\u987a\u5e8f\uff0c\u5148\u5904\u7406\u76ee\u5f55\u5185\u90e8\u7684\u6587\u4ef6\uff0c\u518d\u5904\u7406\u76ee\u5f55\u3002 \u6839\u636e\u6587\u4ef6\u540d\u548cinode\u67e5\u627e\uff1a -name \"FILENAME\" \uff1a\u652f\u6301\u4f7f\u7528\u901a\u914d\u7b26\uff0c\u5982 * \uff0c \uff1f \uff0c [] \uff0c [^] \uff0c\u6ce8\u610f\uff0c\u901a\u914d\u7b26\u8981\u7528\u53cc\u5f15\u53f7\u3002 -iname \"FILENAME\" \uff1a\u4e0d\u533a\u5206\u5b57\u6bcd\u5927\u5c0f\u5199\u3002 -inum N \uff1a\u6309inode\u53f7\u67e5\u627e\u3002 -samefile NAME \uff1a\u67e5\u627e\u76f8\u540cinode\u53f7\u7684\u6587\u4ef6\u3002 -links N \uff1a\u94fe\u63a5\u6570\u4e3a N \u7684\u6587\u4ef6\u3002 -regex \"PATTERN\" \uff1a\u4ee5PATTERN\u5339\u914d\u6574\u4e2a\u6587\u4ef6\u8def\u5f84\uff0c\u800c\u975e\u6587\u4ef6\u540d\u79f0\u3002","title":"find\u547d\u4ee4"},{"location":"linux/SRE/06-FileLookup/#xargs","text":"","title":"xargs\u547d\u4ee4"},{"location":"linux/SRE/07-FilePacking/","text":"\u7b2c\u4e03\u7ae0 \u6587\u4ef6\u6253\u5305\u548c\u89e3\u5305 \u00b6 \u5e38\u7528\u6587\u4ef6\u6253\u5305\u548c\u89e3\u5305\u547d\u4ee4\uff1a compress\u548cuncompress gzip\u548cgunzip bzip2\u548cbunzip2 xz\u548cunxz zip\u548cunzip tar","title":"\u7b2c\u4e03\u7ae0 \u6587\u4ef6\u6253\u5305\u548c\u89e3\u5305"},{"location":"linux/SRE/07-FilePacking/#_1","text":"\u5e38\u7528\u6587\u4ef6\u6253\u5305\u548c\u89e3\u5305\u547d\u4ee4\uff1a compress\u548cuncompress gzip\u548cgunzip bzip2\u548cbunzip2 xz\u548cunxz zip\u548cunzip tar","title":"\u7b2c\u4e03\u7ae0 \u6587\u4ef6\u6253\u5305\u548c\u89e3\u5305"},{"location":"python/","text":"Content \u00b6 Memo Python\u5b66\u4e60\u7684\u7b14\u8bb0\u3002 Python\u57fa\u7840\u77e5\u8bc6\uff0c\u6765\u6e90\u4e8e\u53c2\u52a0\u7684\u5404\u79cd\u5728\u7ebf\u57fa\u7840\u8bfe\u7a0b\u6c47\u96c6\u800c\u6210\u3002 \u300a\u5229\u7528Python\u8fdb\u884c\u6570\u636e\u5206\u6790\uff08\u539f\u4e66\u7b2c2\u7248\uff09\u300b\uff08Python for Data Analysis, 2rd Edition\uff09\u5b66\u4e60\u7b14\u8bb0 Git: Python For Data Analysis \u300a\u6570\u636e\u7ed3\u6784\uff08Python\u8bed\u8a00\u63cf\u8ff0\uff09\uff08\u7b2c2\u7248\uff09\u300b\uff08Fundamentals of Python: Data Structures 2 nd Edition\uff09\u5b66\u4e60\u7b14\u8bb0\u3002 \u300aEffective Python\uff1a\u7f16\u5199\u9ad8\u8d28\u91cfPython\u4ee3\u7801\u768490\u4e2a\u6709\u6548\u65b9\u6cd5\uff08\u539f\u4e66\u7b2c2\u7248\uff09\u300b\uff08Effective Python: 90 Specific Ways to Write Better Python, Second Edition\uff09 Git: Effective Python \u5c0f\u7a0b\u5e8f\u6f14\u793a\uff0c\u6765\u6e90\u4e8e\u53c2\u52a0\u7684\u5404\u79cd\u5728\u7ebf\u57fa\u7840\u8bfe\u7a0b\u3002","title":"Index"},{"location":"python/#content","text":"Memo Python\u5b66\u4e60\u7684\u7b14\u8bb0\u3002 Python\u57fa\u7840\u77e5\u8bc6\uff0c\u6765\u6e90\u4e8e\u53c2\u52a0\u7684\u5404\u79cd\u5728\u7ebf\u57fa\u7840\u8bfe\u7a0b\u6c47\u96c6\u800c\u6210\u3002 \u300a\u5229\u7528Python\u8fdb\u884c\u6570\u636e\u5206\u6790\uff08\u539f\u4e66\u7b2c2\u7248\uff09\u300b\uff08Python for Data Analysis, 2rd Edition\uff09\u5b66\u4e60\u7b14\u8bb0 Git: Python For Data Analysis \u300a\u6570\u636e\u7ed3\u6784\uff08Python\u8bed\u8a00\u63cf\u8ff0\uff09\uff08\u7b2c2\u7248\uff09\u300b\uff08Fundamentals of Python: Data Structures 2 nd Edition\uff09\u5b66\u4e60\u7b14\u8bb0\u3002 \u300aEffective Python\uff1a\u7f16\u5199\u9ad8\u8d28\u91cfPython\u4ee3\u7801\u768490\u4e2a\u6709\u6548\u65b9\u6cd5\uff08\u539f\u4e66\u7b2c2\u7248\uff09\u300b\uff08Effective Python: 90 Specific Ways to Write Better Python, Second Edition\uff09 Git: Effective Python \u5c0f\u7a0b\u5e8f\u6f14\u793a\uff0c\u6765\u6e90\u4e8e\u53c2\u52a0\u7684\u5404\u79cd\u5728\u7ebf\u57fa\u7840\u8bfe\u7a0b\u3002","title":"Content"},{"location":"python/DataAnalysis/ch01/","text":"NumPy\u57fa\u7840 \u00b6 \u5305\u542b\u4ee5\u4e0b\u5185\u5bb9\uff1a \u591a\u7ef4\u6570\u7ec4\u5bf9\u8c61 \u901a\u7528\u51fd\u6570 \u9762\u5411\u6570\u7ec4\u7f16\u7a0b \u4f7f\u7528\u6570\u7ec4\u8fdb\u884c\u6587\u4ef6\u8f93\u5165\u548c\u8f93\u51fa \u7ebf\u6027\u4ee3\u6570 \u4f2a\u968f\u673a\u6570\u751f\u6210 \u793a\u4f8b\uff1a\u968f\u673a\u6f2b\u6b65 \u591a\u7ef4\u6570\u7ec4\u5bf9\u8c61ndarry \u00b6 \u522b\u540d\u7ea6\u5b9a \u00b6 import numpy as np import pandas as pd import matplotlib.pyplot as plt \u5b89\u88c5matplotlib\u4e2d\u6587\u5b57\u4f53 \u00b6 \u67e5\u770b\u5b57\u4f53\u8def\u5f84 >>> import matplotlib >>> print(matplotlib.matplotlib_fname()) /home/james/.local/lib/python3.6/site-packages/matplotlib/mpl-data/matplotlibrc \u4e0b\u8f7d\u4e2d\u6587\u5b57\u4f53\u3002\u7f51\u5740 https://www.fontpalace.com/font-download/SimHei/,\u5e76\u62f7\u8d1d\u5230\u4e0b\u9762\u7684\u8def\u5f84\u4e0b james@lizard:~/Downloads> cp SimHei.ttf /home/james/.local/lib/python3.6/site-packages/matplotlib/mpl-data/fonts/ttf/ \u67e5\u770bmatplotlib\u7684\u5b57\u4f53\u7f13\u5b58\u76ee\u5f55\u3002 >>> import matplotlib >>> print(matplotlib.get_cachedir()) /home/james/.cache/matplotlib \u5220\u9664\u8fd9\u4e2a\u76ee\u5f55 james@lizard:~> rm -rf /home/james/.cache/matplotlib \u7f16\u8f91matplotlibrc\u6587\u4ef6 /home/james/.local/lib/python3.6/site-packages/matplotlib/mpl-data/matplotlibrc \uff0c\u505a\u5982\u4e0b\u4fee\u6539\u3002 \u5b9a\u4f4d\u8fd9\u4e00\u884c\uff0c\u53bb\u6389\u6ce8\u91ca\u7b26 # font.family: sans-serif \u5b9a\u4f4d\u8fd9\u4e00\u884c\uff0c\u53bb\u6389\u6ce8\u91ca\u7b26 # \uff0c\u5e76\u6dfb\u52a0 SimHei \uff0c\u4fee\u6539\u540e\u4e3a font.serif: SimHei, DejaVu Serif, Bitstream Vera Serif, Computer Modern Roman, New Century Schoolbook, Century Schoolbook L, Utopia, ITC Bookman, Bookman, Nimbus Roman No9 L, Times New Roman, Times, Palatino, Charter, serif \u5b9a\u4f4d\u8fd9\u4e00\u884c\uff0c\u53bb\u6389\u6ce8\u91ca\u7b26 # \uff0c\u5e76\u6dfb\u52a0 SimHei \uff0c\u4fee\u6539\u540e\u4e3a font.sans-serif: SimHei, DejaVu Sans, Bitstream Vera Sans, Computer Modern Sans Serif, Lucida Grande, Verdana, Geneva, Lucid, Arial, Helvetica, Avant Garde, sans-serif \u5b9a\u4f4d\u8fd9\u4e00\u884c\uff0c\u53bb\u6389\u6ce8\u91ca\u7b26 # \uff0c\u5e76\u628a True \u6539\u4e3a False \uff0c\u4fee\u6539\u540e\u4e3a axes.unicode_minus: False \u8bbe\u7f6ematplotlib\u540e\u7aef\u6e32\u67d3\u5668 \u00b6 \u5728\u4f7f\u7528matplotlib\u8f93\u51fa\u56fe\u50cf\u65f6\uff0c\u5982\u679c\u9047\u5230\u65e0\u6cd5\u663e\u793a\u56fe\u50cf\u7684\u9519\u8bef UserWarning: Matplotlib is currently using agg, which is a non-GUI backend, so cannot show the figure\u3002 \uff0c\u53ef\u4ee5\u5c1d\u8bd5\u4e0b\u9762\u7684\u6b65\u9aa4\u89e3\u51b3\u3002 \u5b89\u88c5 python3-tk \u5305 james@lizard:~> sudo zypper in python3-tk \u6216\u8005\u901a\u8fc7 pip \u5b89\u88c5 tk \u5305 james@lizard:~> pip3 install tk Defaulting to user installation because normal site-packages is not writeable Collecting tk Downloading tk-0.1.0-py3-none-any.whl (3.9 kB) Installing collected packages: tk Successfully installed tk-0.1.0 \u4e00\u822c\u5b8c\u6210\u4e0a\u9762\u5b89\u88c5\u540e\uff0c\u7a0b\u5e8f\u5c31\u80fd\u81ea\u52a8\u663e\u793a\u56fe\u4e86\uff0c\u5982\u679c\u8fd8\u662f\u4e0d\u80fd\u663e\u793a\uff0c\u518d\u5c1d\u8bd5\u91cd\u65b0\u5b89\u88c5 matplotlib \u3002 pip3 ininstall matplotlib pip3 install matplotlib ndarray: N-\u7ef4\u6570\u7ec4\u5bf9\u8c61 \u00b6 \u4e00\u4e2andarray\u662f\u4e00\u4e2a\u901a\u7528\u7684\u591a\u7ef4\u540c\u7c7b\u6570\u636e\u5bb9\u5668\uff0c\u4e5f\u5c31\u662f\u8bf4\uff0c\u5b83\u5305\u542b\u7684\u6bcf\u4e00\u4e2a\u5143\u7d20\u5747\u4e3a**\u76f8\u540c\u7c7b\u578b**\uff1b \u6bcf\u4e00\u4e2a\u6570\u7ec4\u90fd\u6709\u4e00\u4e2ashape\u5c5e\u6027\uff0c\u7528\u6765\u8868\u5f81\u6570\u7ec4\u6bcf\u4e00\u7ef4\u5ea6\u7684\u6570\u91cf\uff1b \u6bcf\u4e00\u4e2a\u6570\u7ec4\u90fd\u6709\u4e00\u4e2adtype\u5c5e\u6027\uff0c\u7528\u6765\u63cf\u8ff0\u6570\u7ec4\u7684\u6570\u636e\u7c7b\u578b\uff1b \u4e0b\u9762\u662f\u6807\u51c6\u6570\u7ec4\u7684\u751f\u6210\u51fd\u6570 array: \u5c06\u8f93\u5165\u6570\u636e\uff08\u5217\u8868\u3001\u5143\u7ec4\u3001\u6570\u7ec4\uff0c\u5176\u4ed6\u5e8f\u5217\uff09\u8f6c\u6362\u4e3andarray\uff0c\u5982\u679c\u4e0d\u663e\u5f0f\u6307\u660e\u6570\u636e\u7c7b\u578b\uff0c\u5c06\u81ea\u52a8\u63a8\u65ad\uff1b\u9ed8\u8ba4\u590d\u5236\u6240\u6709\u7684\u8f93\u5165\u6570\u636e\u3002 asarray\uff1a\u5c06\u8f93\u5165\u8f6c\u6362\u4e3andarray\uff0c\u4f46\u5982\u679c\u8f93\u5165\u5df2\u7ecf\u662fndarray\u5219\u4e0d\u518d\u590d\u5236\u3002 arange\uff1aPython\u5185\u7f6e\u51fd\u6570range\u7684\u6570\u7ec4\u7248\uff0c\u8fd4\u56de\u4e00\u4e2a\u6570\u7ec4\u3002 \u4e0b\u9762\u662f\u7528 Numpy.random() \u4e00\u4e2a\u751f\u6210\u4e00\u4e2a\u968f\u673a\u6570\u7ec4\u7684\u4f8b\u5b50\uff0c\u6ce8\u610f data01 \u7684\u7c7b\u578b\u662f'numpy.ndarray'\u3002\u53ef\u4ee5\u5728ndarray\u7c7b\u578b\u6570\u7ec4\u4e0a\u53e0\u52a0\u4e00\u4e0b\u6570\u5b66\u64cd\u4f5c\u3002 data01 = np.random.randn(2, 3) print(type(data01)) # print(data01) # [[ 0.12047302 -1.13499045 -0.39311368] # [ 1.54046881 0.01254838 -3.65090952]] print(data01 * 10) # \u7ed9data\u52a0\u4e0a\u4e00\u4e2a\u6570\u5b66\u64cd\u4f5c, \u6240\u6709\u7684\u5143\u7d20\u90fd\u540c\u65f6\u4e58\u4ee5\u4e8610 # [[ 1.20473022 -11.3499045 -3.93113676] # [ 15.40468806 0.12548383 -36.50909515]] print(data01 + data01) # \u7ed9data\u52a0\u4e0a\u4e00\u4e2a\u6570\u5b66\u64cd\u4f5c, \u6570\u7ec4\u4e2d\u7684\u5bf9\u5e94\u5143\u7d20\u8fdb\u884c\u4e86\u76f8\u52a0 # [[ 0.24094604 -2.2699809 -0.78622735] # [ 3.08093761 0.02509677 -7.30181903]] print(data01.shape) # (2, 3) print(data01.dtype) # float64 \u5f53\u8868\u8fbe\u201c\u6570\u7ec4\u201d\u3001\u201cNumPy\u6570\u7ec4\u201d\u6216\u201cndarray\u201d\u65f6\uff0c\u90fd\u8868\u793a\u540c\u4e00\u4e2a\u5bf9\u8c61\uff1andarray\u5bf9\u8c61\u3002 \u770b\u4e0b\u9762\u7684\u4f8b\u5b50\uff1a data01 \u662f\u4e00\u4e2a\u5217\u8868\uff08list\uff09\u7c7b\u578b\uff0c\u901a\u8fc7 Numpy.array \u8f6c\u6362\u6210Numpy\u7684 ndarray \u7c7b\u578b\u3002 \u5728 np.array \u4e2d\uff0c\u9664\u975e\u663e\u5f0f\u5730\u6307\u5b9a\uff0c\u5982 np.array(data01, dtype=np.int8) \uff0c\u5426\u5219np.array\u4f1a\u81ea\u52a8\u63a8\u65ad\u751f\u6210\u6570\u7ec4\u7684\u6570\u636e\u7c7b\u578b array01.dtype \u3002 \u4f7f\u7528 astype() \u65b9\u6cd5\u663e\u5f0f\u5730\u8f6c\u6362\u6570\u7ec4\u7684\u6570\u636e\u7c7b\u578b\u3002\u4f7f\u7528 astype() \u65f6\u603b\u662f\u751f\u6210\u4e00\u4e2a*\u65b0\u7684\u6570\u7ec4*\uff0c\u5373\u4f7f\u4f60\u4f20\u5165\u7684dtype\u4e0e\u4e4b\u524d\u4e00\u6837\u3002 data02 \u662f\u4e00\u4e2a\u5d4c\u5957\u5217\u8868 [[1, 2, 3, 4], [5, 6, 7, 8]] \uff0c\u901a\u8fc7np.array()\u65b9\u6cd5\u8f6c\u6362\u6210\u591a\u7ef4\u6570\u7ec4\uff0c\u524d\u63d0\u662f\u6bcf\u4e2a\u5b50\u5217\u8868\u7684\u957f\u5ea6\u8981\u4e00\u81f4\u3002 data01 = [6, 7.5, 8, 0, 1] print(data01) # [6, 7.5, 8, 0, 1] print(type(data01)) # array01 = np.array(data01) print(\"\u77e9\u9635\u7c7b\u578b\", type(array01)) # \u77e9\u9635\u7c7b\u578b print(\"\u6837\u672c\u77e9\u9635\", array01) # \u6837\u672c\u77e9\u9635 [6. 7.5 8. 0. 1. ] print(\"\u6570\u7ec4\u7ef4\u5ea6\", array01.ndim) # \u6570\u7ec4\u7ef4\u5ea6 1 print(\"\u77e9\u9635\u5f62\u72b6\", array01.shape) # \u77e9\u9635\u5f62\u72b6 (5,) \u4e00\u884c\u4e94\u5217 print(\"\u77e9\u9635\u6570\u636e\u7c7b\u578b\", array01.dtype) # float64 data02 = [[1, 2, 3, 4], [5, 6, 7, 8]] array02 = np.array(data02) print(\"\u6837\u672c\u77e9\u9635\\n\", array02) # \u6837\u672c\u77e9\u9635 # [[1 2 3 4] # [5 6 7 8]] print(\"\u6570\u7ec4\u7ef4\u5ea6\", array02.ndim) # \u6570\u7ec4\u7ef4\u5ea6 2 print(\"\u77e9\u9635\u5f62\u72b6\", array02.shape) # \u77e9\u9635\u5f62\u72b6 (2, 4) print(\"\u77e9\u9635\u6570\u636e\u7c7b\u578b\", array02.dtype) # \u77e9\u9635\u6570\u636e\u7c7b\u578b int64 print(\"\u77e9\u96350\u8f74\u5411\u6c42\u548c\", array02.sum(axis=0)) # \u77e9\u96350\u8f74\u5411\u6c42\u548c [ 6 8 10 12] print(\"\u77e9\u96351\u8f74\u5411\u6c42\u548c\", array02.sum(axis=1)) # \u77e9\u96351\u8f74\u5411\u6c42\u548c [10 26] array03 = array02.astype(np.float64) print(array03.dtype) # float64 print(array03) # [[1. 2. 3. 4.] # [5. 6. 7. 8.]] zeros() \u65b9\u6cd5\u53ef\u4ee5\u4e00\u6b21\u6027\u521b\u9020\u51680\u6570\u7ec4\u3002 print(np.zeros(10)) # [0. 0. 0. 0. 0. 0. 0. 0. 0. 0.] ones() \u65b9\u6cd5\u53ef\u4ee5\u4e00\u6b21\u6027\u521b\u9020\u51681\u6570\u7ec4\u3002\u6ce8\u610f\uff0c\u4f20\u53c2shape\u662f\u4e00\u4e2a\u5143\u7ec4 (3, 5) \u3002 print(np.ones((3, 5))) # [[1. 1. 1. 1. 1.] # [1. 1. 1. 1. 1.] # [1. 1. 1. 1. 1.]] empty() \u65b9\u6cd5\u53ef\u4ee5\u521b\u5efa\u4e00\u4e2a\u6ca1\u6709\u521d\u59cb\u5316\u6570\u503c\u7684\u6570\u7ec4\u3002\u4f46\u662f\uff0c\u4f7f\u7528np.empty\u6765\u751f\u6210\u4e00\u4e2a\u51680\u6570\u7ec4\uff0c\u5e76\u4e0d\u53ef\u9760\uff0c\u6709\u4e9b\u65f6\u5019\u5b83\u53ef\u80fd\u4f1a\u8fd4\u56de\u672a\u521d\u59cb\u5316\u7684\u5783\u573e\u6570\u503c print(np.empty((2, 3, 2))) # [[[2.30116964e-316 0.00000000e+000] # [2.10077583e-312 6.79038654e-313] # [2.22809558e-312 2.14321575e-312]] # # [[2.35541533e-312 6.79038654e-313] # [2.22809558e-312 2.14321575e-312] # [2.46151512e-312 2.41907520e-312]]] NumPy\u8f74 \u00b6 \u4e00\u53e5\u8bdd\u603b\u7ed3\uff1a\u5c06NumPy\u8f74\u89c6\u4e3a\u6211\u4eec\u53ef\u4ee5\u6267\u884c\u64cd\u4f5c\u7684\u65b9\u5411\u3002 \u770b\u4e0b\u9762\u7684\u4f8b\u5b50\uff1a arr_1 = np.array([[1, 1, 1], [1, 1, 1]]) arr_2 = np.array([[9, 9, 9], [9, 9, 9]]) print(arr_1) # [[1 1 1] # [1 1 1]] print(arr_2) # [[9 9 9] # [9 9 9]] \u6cbf0\u8f74\u5408\u5e76\u7684\u601d\u8def\u662f\uff0c\u4e24\u4e2a\u6570\u7ec4\u6cbf0\u8f74\u65b9\u5411\uff0c\u54110\u8f74\u201c\u584c\u7f29\u201d\uff08collapse\uff09\u3002 result = np.concatenate([arr_1, arr_2], axis=0) print(result) # [[1 1 1] # [1 1 1] # [9 9 9] # [9 9 9]] \u6cbf1\u8f74\u5408\u5e76\u7684\u601d\u8def\u662f\uff0c\u4e24\u4e2a\u6570\u7ec4\u6cbf1\u8f74\u65b9\u5411\uff0c\u54111\u8f74\u201c\u584c\u7f29\u201d result = np.concatenate([arr_1, arr_2], axis=1) print(result) # [[1 1 1 9 9 9] # [1 1 1 9 9 9]] \u6211\u4eec\u6765\u770bNumPy\u7684\u4e09\u7ef4\u6570\u7ec4\u3002 array1 = np.arange(36).reshape((3, 3, 4)) print(array1) # [[[ 0 1 2 3] # [ 4 5 6 7] # [ 8 9 10 11]] # # [[12 13 14 15] # [16 17 18 19] # [20 21 22 23]] # # [[24 25 26 27] # [28 29 30 31] # [32 33 34 35]]] \u8fd9\u6837\u770b\u4f1a\u5bb9\u6613\u7406\u89e3\u4e00\u4e9b\uff0c0\u8f74\u67093\u884c\uff0c1\u8f74\u67093\u5217\uff0c2\u8f74\u67094\u4e2a\u5143\u7d20\uff1a [[[ 0 1 2 3], [ 4 5 6 7], [ 8 9 10 11]] [[12 13 14 15], [16 17 18 19], [20 21 22 23]] [[24 25 26 27], [28 29 30 31], [32 33 34 35]]] \u8f93\u51fa\uff1a\u8f740\u7d22\u5f15\u53f7\uff1a0\uff1b\u8f741\u7d22\u5f15\u53f7\uff1a0\uff1b\u8f742\u7d22\u5f15\u53f7\uff1a\u5168\u90e8 print(array1[0, 0, :]) # [0 1 2 3] \u8f93\u51fa\uff1a\u8f740\u7d22\u5f15\u53f7\uff1a0\uff1b\u8f741\u7d22\u5f15\u53f7\uff1a0\uff1b\u8f742\u7d22\u5f15\u53f7\uff1a1 print(array1[0, 0, 1]) # 1 NumPy\u6570\u7ec4\u7b97\u672f \u00b6 \u4e00\u4e2a**\u6807\u91cf**\u5c31\u662f\u4e00\u4e2a\u5355\u72ec\u7684\u6570\u3002\u4e00\u4e2a\u5411\u91cf\u5c31\u662f\u4e00\u5217\u6570\uff0c\u8fd9\u4e9b\u6570\u662f\u6709\u5e8f\u6392\u5217\u7684\u3002 \u77e9\u9635\u662f\u4e8c\u7ef4\u6570\u7ec4\uff0c\u5176\u4e2d\u7684\u6bcf\u4e00\u4e2a\u5143\u7d20\u88ab\u4e24\u4e2a\u7d22\u5f15\u800c\u975e\u4e00\u4e2a\u6240\u786e\u5b9a\u3002 \u51e0\u4f55\u4ee3\u6570\u4e2d\u5b9a\u4e49\u7684**\u5f20\u91cf**\u662f\u57fa\u4e8e\u5411\u91cf\u548c\u77e9\u9635\u7684\u63a8\u5e7f\uff0c\u6211\u4eec\u53ef\u4ee5**\u5c06\u6807\u91cf\u89c6\u4e3a\u96f6\u9636\u5f20\u91cf**\uff0c \u77e2\u91cf**\u89c6\u4e3a\u4e00\u9636\u5f20\u91cf\uff0c\u90a3\u4e48**\u77e9\u9635\u5c31\u662f\u4e8c\u9636\u5f20\u91cf \u3002 \u5e26\u6709\u6807\u91cf\u8ba1\u7b97\u7684\u7b97\u672f\u64cd\u4f5c\uff0c\u4f1a\u628a\u8ba1\u7b97\u53c2\u6570\u4f20\u9012\u7ed9\u6570\u7ec4\u7684\u6bcf\u4e00\u4e2a\u5143\u7d20\u3002 \u540c\u5c3a\u5bf8\u6570\u7ec4\u4e4b\u95f4\u7684\u6bd4\u8f83 array04 == array04 \uff0c\u4f1a\u4ea7\u751f\u4e00\u4e2a\u5e03\u5c14\u503c\u6570\u7ec4 \u4e0d\u540c\u5c3a\u5bf8\u7684\u6570\u7ec4\u95f4\u7684\u64cd\u4f5c\uff0c\u5c06\u4f1a\u7528\u5230 \u5e7f\u64ad\u7279\u6027\uff08broadcasting\uff09 \u3002 array04 = np.array([ [1, 2, 3, 4, 5], [3, 4, 5, 6, 7], [5, 6, 7, 8, 9] ], dtype=int) print(array04 + array04) # [[ 2 4 6 8 10] # [ 6 8 10 12 14] # [10 12 14 16 18]] print(array04 - array04) # [[0 0 0 0 0] # [0 0 0 0 0] # [0 0 0 0 0]] print(array04 * array04) # [[ 1 4 9 16 25] # [ 9 16 25 36 49] # [25 36 49 64 81]] print(array04 / array04) # [[1. 1. 1. 1. 1.] # [1. 1. 1. 1. 1.] # [1. 1. 1. 1. 1.]] print(1 / array04) # [[1. 0.5 0.33333333 0.25 0.2 ] # [0.33333333 0.25 0.2 0.16666667 0.14285714] # [0.2 0.16666667 0.14285714 0.125 0.11111111]] print(array04 == array04) # [[ True True True True True] # [ True True True True True] # [ True True True True True]] \u57fa\u7840\u7d22\u5f15\u4e0e\u5207\u7247 \u00b6 ndarray\u5bf9\u8c61\u7684\u5185\u5bb9\u53ef\u4ee5\u901a\u8fc7\u7d22\u5f15\uff08indexing\uff09\u6216\u5207\u7247\uff08slicing\uff09\u6765\u8bbf\u95ee\u548c\u4fee\u6539\uff0cndarray\u5bf9\u8c61\u4e2d\u7684\u5143\u7d20\u7d22\u5f15\u4ece\u96f6\u5f00\u59cb\u3002 \u6709\u4e09\u79cd\u53ef\u7528\u7684\u7d22\u5f15\u65b9\u6cd5\uff1a\u5b57\u6bb5\u8bbf\u95ee\uff0c\u57fa\u672c\u5207\u7247\u548c\u9ad8\u7ea7\u7d22\u5f15\u3002 \u7d22\u5f15\uff08indexing\uff09\uff1a\u83b7\u53d6\u6570\u7ec4\u4e2d\u7279\u5b9a\u4f4d\u7f6e\u5143\u7d20\u7684\u8fc7\u7a0b\u3002 \u5207\u7247\uff08slicing\uff09\uff1a\u83b7\u53d6\u6570\u7ec4\u5143\u7d20\u5b50\u96c6\u7684\u8fc7\u7a0b\u3002\u6570\u7ec4\u7684\u5207\u7247\u662f\u539f\u6570\u7ec4\u7684\u89c6\u56fe\u3002\u8fd9\u610f\u5473\u7740\u4efb\u4f55**\u5bf9\u4e8e\u89c6\u56fe\u7684\u4fee\u6539\u90fd\u4f1a\u53cd\u6620\u5230\u539f\u6570\u7ec4\u4e0a**\u3002\u6570\u7ec4\u7684\u5207\u7247, \u8fd4\u56de\u7684\u5bf9\u8c61\u662f\u964d\u4f4e\u4e00\u4e2a\u7ef4\u5ea6\u7684\u6570\u7ec4\u3002 \u4e00\u7ef4\u6570\u7ec4\u7684\u7d22\u5f15\u548c\u5207\u7247\uff1a\u4e0ePython\u7684\u5217\u8868\u7c7b\u4f3c\uff1a a[n] \uff1a\u8fd4\u56de\u7b2c n+1 \u4e2a\u5143\u7d20\u3002\u5982\u679c n \u4e3a\u8d1f\u6570\uff0c\u5219\u8fd4\u56de\u5012\u6570\u7b2c n \u4e2a\u5143\u7d20\u3002 a[n:m:k] \uff1a\u8d77\u59cb\u7f16\u53f7 n \uff0c\u7ec8\u6b62\u7f16\u53f7 m \uff0c\u6b65\u957f k \uff0c\u7528\u5192\u53f7\u5206\u5272\u3002 \u9075\u5faa\u5de6\u95ed\u53f3\u5f00\u7684\u539f\u5219 \uff0c\u5373 [n, m) \u3002\u5982\u679c n \u4e3a\u7a7a\uff0c\u5373 n = 0 \uff1b\u5982\u679c m \u4e3a\u7a7a\uff0c\u5373 m = len(a) \u3002 \u591a\u7ef4\u6570\u7ec4\u7684\u7d22\u5f15\u548c\u5207\u7247\uff1a a[n,m,k,...] \uff1a\u6bcf\u4e2a\u7ef4\u5ea6\u4e00\u4e2a\u7d22\u5f15\u503c\uff0c\u6700\u5916\u5c42\u5217\u8868\uff08list\uff09\u4e2d\u7b2c n \u4e2a\u5143\u7d20\uff0c\u6b21\u5916\u5c42\u5217\u8868\uff08list\uff09\u4e2d\u7b2c m \u4e2a\u5143\u7d20\uff0c\u4ee5\u6b64\u7c7b\u63a8\u3002\u5982\u679c n \u4e3a\u8d1f\u6570\uff0c\u5219\u8fd4\u56de\u5012\u6570\u7b2c n \u4e2a\u5143\u7d20\u3002 a[n1:m1:k1,n2:m2:k2,n3:m3:k3,...] \uff1a\u6bcf\u4e2a\u7ef4\u5ea6\u7684\u5207\u7247\u65b9\u6cd5\u4e0e\u4e00\u7ef4\u6570\u7ec4\u76f8\u540c\u3002\u987a\u5e8f\u4e3a\u4ece\u5916\u5230\u5185\u3002 array05 = np.arange(10) print(array05) # [0 1 2 3 4 5 6 7 8 9] # \u4ece\u7d22\u5f15\u503c5\u5f00\u59cb\u5230\u7d22\u5f15\u503c7\u7684\u4e00\u4e2a\u5207\u7247\u3002 print(array05[5:8]) # [5 6 7] array06 = array05[5:8] # \u4f20\u5165\u4e00\u4e2a\u6570\u503c\u7ed9\u6570\u7ec4\u7684\u5207\u7247\uff0c\u6570\u503c\u88ab\u4f20\u9012\u7ed9\u4e86\u6574\u4e2a\u5207\u7247\u3002\u4e0d\u5199\u5207\u7247\u503c\u7684[:]\u5c06\u4f1a\u5f15\u7528\u6570\u7ec4\u7684\u6240\u6709\u503c array06[:] = 12 print(array06) # [12 12 12] # \u5207\u7247\u7684\u4fee\u6539\u4f1a\u53cd\u6620\u5230\u539f\u6570\u7ec4\u4e0a print(array05) # [ 0 1 2 3 4 12 12 12 8 9] # \u8f93\u51fa3\u7ef4\u77e9\u9635\uff0c3\u884c3\u5217\uff0c\u51719\u4e2a\u5143\u7d20\uff0c\u6bcf\u4e2a\u5143\u7d20\u662f\u4e00\u4e2a\u542b3\u4e2a\u5143\u7d20\u7684\u5217\u8868 array07 = np.array([ [[0, 1, 2], [3, 4, 5], [6, 7, 8]], [[9, 0, 1], [2, 3, 4], [5, 6, 7]], [[8, 9, 0], [1, 2, 3], [4, 5, 6]], ]) # \u8f93\u51fa3\u7ef4\u77e9\u9635\uff0c\u663e\u793a\u539f\u77e9\u9635\u7684\u7b2c1\uff0c2\u884c\u76842\uff0c3\u5217\u5143\u7d20\uff0c\u4e0d\u8981\u628a\u7d22\u5f15\u53f7\u548c\u8fd9\u91cc\u7684\u8868\u8ff0\u884c\u53f7\u6df7\u6dc6\u3002 print(array07[:2, 1:]) # [[[3 4 5] [6 7 8]] # [[2 3 4] [5 6 7]]] print(array07[:2, 1:].shape) # (2, 2, 3) # \u964d\u7ef4\uff0c\u8f93\u51fa\u539f\u77e9\u9635\u7684\u7b2c3\u884c print(array07[2]) # [[8 9 0] [1 2 3] [4 5 6]] print(array07[2].shape) # (3, 3) # \u964d\u7ef4\uff0c\u8f93\u51fa\u539f\u77e9\u9635\u7684\u7b2c3\u884c print(array07[2, :]) # [[8 9 0] [1 2 3] [4 5 6]] print(array07[2, :].shape) # (3, 3) # \u964d\u7ef4\uff0c\u8f93\u51fa\u539f\u77e9\u9635\u7684\u7b2c3\u884c\uff08\u53ea\u6709\u4e09\u884c\uff0c\u6240\u4ee5[2:, :]\u7b49\u540c\u4e8e[2, :]\uff09 print(array07[2:, :]) # [[[8 9 0] [1 2 3] [4 5 6]]] print(array07[2:, :].shape) # (1, 3, 3) # \u8f93\u51fa\u539f\u77e9\u9635\u76841\uff0c2\u5217 print(array07[:, :2]) # [[[0 1 2] [3 4 5]] # [[9 0 1] [2 3 4]] # [[8 9 0] [1 2 3]]] print(array07[:, :2].shape) # (3, 2, 3) # \u964d\u7ef4\uff0c\u8f93\u51fa\u539f\u77e9\u9635\u7684\u7b2c2\u884c\u524d2\u4e2a\u5143\u7d20 print(array07[1, :2]) # [[9 0 1] [2 3 4]] print(array07[1, :2].shape) # (2, 3) # \u8f93\u51fa\u539f\u77e9\u9635\u7684\u7b2c2\u884c\u524d2\u4e2a\u5143\u7d20 print(array07[1:2, :2]) # [[[9 0 1] [2 3 4]]] print(array07[1:2, :2].shape) # (1, 2, 3) # \u5c06\u539f\u77e9\u9635\u7684\u7b2c2\u884c\u8d4b\u503c\u7ed9\u53d8\u91cf old_value = array07[2].copy() print(old_value) # [[8 9 0] [1 2 3] [4 5 6]] # \u4fee\u6539\u539f\u77e9\u9635\u7684\u7b2c2\u884c\u7684\u503c\uff0c\u6807\u91cf\u548c\u6570\u7ec4\u90fd\u53ef\u4ee5\u4f20\u9012\u7ed9 array07[2] array07[2] = 25 print(array07) # [[[ 0 1 2] [ 3 4 5] [ 6 7 8]] # [[ 9 0 1] [ 2 3 4] [ 5 6 7]] # [[25 25 25] [25 25 25] [25 25 25]]] # \u5c06\u53d8\u91cf\u503c\u8d4b\u503c\u7ed9\u539f\u77e9\u9635\u7684\u7b2c2\u884c array07[2] = old_value print(array07) # [[[0 1 2] [3 4 5] [6 7 8]] # [[9 0 1] [2 3 4] [5 6 7]] # [[8 9 0] [1 2 3] [4 5 6]]] \u5e03\u5c14\u7d22\u5f15 \u00b6 \u5e03\u5c14\u503c\u7d22\u5f15\uff08Boolean indexing\uff09\u662f\u901a\u8fc7\u4e00\u4e2a\u5e03\u5c14\u6570\u7ec4\u6765\u7d22\u5f15\u76ee\u6807\u6570\u7ec4\uff0c\u4ee5\u6b64\u627e\u51fa\u4e0e\u5e03\u5c14\u6570\u7ec4\u4e2d\u503c\u4e3aTrue\u7684\u5bf9\u5e94\u7684\u76ee\u6807\u6570\u7ec4\u4e2d\u7684\u6570\u636e\u3002\u5e03\u5c14\u6570\u7ec4\u7684\u957f\u5ea6\u5fc5\u987b\u4e0e\u76ee\u6807\u6570\u7ec4\u5bf9\u5e94\u7684\u8f74\u7684\u957f\u5ea6\u4e00\u81f4\u3002 \u4f7f\u7528\u5e03\u5c14\u503c\u7d22\u5f15\uff08Boolean indexing\uff09\u9009\u62e9\u6570\u636e\u65f6\uff0c\u603b\u662f\u751f\u6210\u6570\u636e\u7684\u62f7\u8d1d\uff0c\u5373\u4f7f\u8fd4\u56de\u7684\u6570\u7ec4\u5e76\u6ca1\u6709\u4efb\u4f55\u53d8\u5316\u3002 \u5047\u8bbe\u6211\u4eec\u7684\u6570\u636e\u90fd\u5728\u6570\u7ec4\u4e2d\uff0c\u5e76\u4e14\u6570\u7ec4\u4e2d\u7684\u6570\u636e\u662f\u4e00\u4e9b\u5b58\u5728\u91cd\u590d\u7684\u4eba\u540d\u3002\u7528randn\u51fd\u6570\u751f\u6210\u4e00\u4e9b\u6807\u51c6\u6b63\u6001(standard normal)\u5206\u5e03\u7684\u6570\u636e\u3002\u5047\u8bbe\u6bcf\u4e2a\u4eba\u540d\u90fd\u548cdata\u6570\u7ec4\u4e2d\u7684\u4e00\u884c\u76f8\u5bf9\u5e94\uff0c\u5e76\u4e14\u6211\u4eec\u60f3\u8981\u9009\u4e2d\u6240\u6709\u2019Bob\u2019\u5bf9\u5e94\u7684\u884c\u3002 names = np.array(['Bob', 'Joe', 'Will', 'Bob', 'Will', 'Joe', 'Joe'], dtype=' # \u56fe\u50cf\u6807\u9898 plt.title(\"$\\sqrt{x^2 + y^2}$ \u8ba1\u7b97\u503c\u7684\u7f51\u683c\u56fe\") # \u8f93\u51fa\u56fe\u50cf plt.show() \u8f93\u51fa\u56fe\u50cf\u4e3a\uff1a \u901a\u8fc7\u6761\u4ef6\u903b\u8f91\u64cd\u4f5c\u6570\u7ec4 \u00b6 numpy.where \u51fd\u6570\u662f\u4e09\u5143\u8868\u8fbe\u5f0f x if condition else y \u7684\u5411\u91cf\u5316\u7248\u672c\u3002 np.where \u7684\u7b2c\u4e8c\u4e2a\u548c\u7b2c\u4e09\u4e2a\u53c2\u6570\u5e76\u4e0d\u9700\u8981\u662f\u6570\u7ec4\uff0c\u5b83\u4eec\u53ef\u4ee5\u662f\u6807\u91cf\u3002 np.where \u5728\u6570\u636e\u5206\u6790\u4e2d\u7684\u4e00\u4e2a\u5178\u578b\u7528\u6cd5\u662f\u6839\u636e\u4e00\u4e2a\u6570\u7ec4\u6765\u751f\u6210\u4e00\u4e2a\u65b0\u7684\u6570\u7ec4\u3002 \u5047\u8bbe\u6211\u4eec\u6709\u4e00\u4e2a\u5e03\u5c14\u503c\u6570\u7ec4\u548c\u4e24\u4e2a\u6570\u503c\u6570\u7ec4\u3002\u5047\u8bbe cond \u4e2d\u7684\u5143\u7d20\u4e3a True \u65f6\uff0c\u6211\u4eec\u53d6 xarr \u4e2d\u7684\u5bf9\u5e94\u5143\u7d20\u503c\uff0c\u5426\u5219\u53d6 yarr \u4e2d\u7684\u5143\u7d20\u3002 xarray = np.array([1.1, 1.2, 1.3, 1.4, 1.5]) yarray = np.array([2.1, 2.2, 2.3, 2.4, 2.5]) cond = np.array([True, False, True, True, False]) \u901a\u8fc7\u5217\u8868\u63a8\u5bfc\u5f0f\u6765\u5b9e\u73b0\u4e0a\u8ff0\u9700\u6c42\u3002 \u7f3a\u70b9: \u9996\u5148\uff0c\u5982\u679c\u6570\u7ec4\u5f88\u5927\u7684\u8bdd\uff0c\u901f\u5ea6\u4f1a\u5f88\u6162\uff08\u56e0\u4e3a\u6240\u6709\u7684\u5de5\u4f5c\u90fd\u662f\u901a\u8fc7\u89e3\u91ca\u5668\u6765\u89e3\u91caPython\u4ee3\u7801\u5b8c\u6210\uff09\u3002 \u5176\u6b21\uff0c\u5f53\u6570\u7ec4\u662f\u591a\u7ef4\u65f6\uff0c\u5c31\u65e0\u6cd5\u51d1\u6548\u4e86\u3002 # \u901a\u8fc7\u5217\u8868\u63a8\u5bfc\u5f0f\u6765\u5b9e\u73b0 result = [(x if c else y) for x, y, c in zip(xarray, yarray, cond)] print(result) # [1.1, 2.2, 1.3, 1.4, 2.5] \u901a\u8fc7 np.where \u6765\u5b9e\u73b0\u4e0a\u8ff0\u9700\u6c42\u3002 result = np.where(cond, xarray, yarray) print(result) # [1.1 2.2 1.3 1.4 2.5] \u5047\u8bbe\u6709\u4e00\u4e2a\u968f\u673a\u751f\u6210\u7684\u77e9\u9635\u6570\u636e\uff0c\u4e0b\u9762\u4f7f\u7528np.where\u5b9e\u73b0\u66ff\u6362\u3002 array = np.random.randn(4, 4) print(\"\u6837\u672c\u77e9\u9635 \\n\", array) print(\"\u77e9\u9635\u5143\u7d20\u662f\u5426\u5927\u4e8e0 \\n\", array > 0) # \u5c06\u5176\u4e2d\u7684\u6b63\u503c\u90fd\u66ff\u6362\u4e3a2\uff0c\u5c06\u6240\u6709\u7684\u8d1f\u503c\u66ff\u6362\u4e3a-2 result03 = np.where(array > 0, 2, -2) print(\"\u5c06\u5176\u4e2d\u7684\u6b63\u503c\u90fd\u66ff\u6362\u4e3a2\uff0c\u5c06\u6240\u6709\u7684\u8d1f\u503c\u66ff\u6362\u4e3a-2 \\n\", result03) # \u4ec5\u5c06\u5176\u4e2d\u7684\u6b63\u503c\u90fd\u66ff\u6362\u4e3a2 result04 = np.where(array > 0, 2, array) print(\"\u4ec5\u5c06\u5176\u4e2d\u7684\u6b63\u503c\u90fd\u66ff\u6362\u4e3a2 \\n\", result04) # \u6837\u672c\u77e9\u9635 # [[-0.57177422 -0.34917512 2.20268075 1.99959296] # [ 0.67966599 2.67915099 -0.40528454 -0.80339907] # [-0.74406888 2.33802717 -0.74582936 0.59347128] # [ 0.68624473 0.65953112 -0.40871415 -0.68698878]] # \u77e9\u9635\u5143\u7d20\u662f\u5426\u5927\u4e8e0 # [[False False True True] # [ True True False False] # [False True False True] # [ True True False False]] # \u5c06\u5176\u4e2d\u7684\u6b63\u503c\u90fd\u66ff\u6362\u4e3a2\uff0c\u5c06\u6240\u6709\u7684\u8d1f\u503c\u66ff\u6362\u4e3a-2 # [[-2 -2 2 2] # [ 2 2 -2 -2] # [-2 2 -2 2] # [ 2 2 -2 -2]] # \u4ec5\u5c06\u5176\u4e2d\u7684\u6b63\u503c\u90fd\u66ff\u6362\u4e3a2 # [[-0.57177422 -0.34917512 2. 2. ] # [ 2. 2. -0.40528454 -0.80339907] # [-0.74406888 2. -0.74582936 2. ] # [ 2. 2. -0.40871415 -0.68698878]] \u6570\u5b66\u548c\u7edf\u8ba1\u65b9\u6cd5 \u00b6 NumPy\u6709\u4e00\u4e9b\u4e13\u95e8\u7684\u6570\u5b66\u51fd\u6570\uff0c\u7528\u6765\u8ba1\u7b97\u6574\u4e2a\u6570\u7ec4\u7edf\u8ba1\u503c\u6216\u8f74\u5411\u6570\u636e\u7684\u8ba1\u7b97\u3002\u4f8b\u5982\uff0c\u805a\u5408\u51fd\u6570\uff08\u901a\u5e38\u4e5f\u53eb\u7f29\u51cf\u51fd\u6570\uff09\uff0c\u5982sum\u3001mean\u548cstd\uff08\u6807\u51c6\u5dee\uff09\u3002 \u65e2\u53ef\u4ee5\u76f4\u63a5\u8c03\u7528\u6570\u7ec4\u5b9e\u4f8b\u7684\u65b9\u6cd5\uff0c\u4e5f\u53ef\u4ee5\u4f7f\u7528\u9876\u5c42\u7684NumPy\u51fd\u6570\u3002 \u4e3e\u4f8b\uff1a\u751f\u6210\u4e00\u4e9b\u6b63\u6001\u5206\u5e03\u7684\u968f\u673a\u6570\uff0c\u8ba1\u7b97\u90e8\u5206\u805a\u5408\u7edf\u8ba1\u6570\u636e\u3002 \u8fd9\u91cc\u518d\u5bf9\u8f74\u5411\u505a\u4e2a\u89e3\u91ca\uff0c np.random.randn(5, 4) \u4ea7\u751f\u7684\u4e8c\u7ef4\u6570\u7ec4\u662f\uff1a0\u8f74\u54115\u4e2a\u5143\u7d20, 1\u8f74\u54114\u4e2a\u5143\u7d20\u3002 # \u751f\u62102\u8f74\u6570\u7ec4 array = np.random.randn(5, 4) print(\"\u6837\u672c\u77e9\u9635 \\n\", array) print(\"\u77e9\u9635\u5143\u7d20\u5e73\u5747\u503c\", array.mean()) print(\"\u77e9\u9635\u5143\u7d20\u5e73\u5747\u503c\", np.mean(array)) print(\"\u77e9\u9635\u5143\u7d20\u548c\", array.sum()) print(\"\u77e9\u9635\u5143\u7d20\u548c\", np.sum(array)) print(\"0\u8f74\u5411\u7684\u7d2f\u548c\", array.sum(axis=0)) print(\"1\u8f74\u5411\u7684\u7d2f\u548c\", array.sum(axis=1)) print(\"1\u8f74\u5411\u7684\u5e73\u5747\u503c\", array.mean(axis=1)) # \u6837\u672c\u77e9\u9635 shape=(5, 4) 0\u8f74\u54115\u4e2a\u5143\u7d20, 1\u8f74\u54114\u4e2a\u5143\u7d20 # [[ 0.32532911 -0.00177984 -1.59432632 1.58375133] # [ 1.48921763 0.25202456 0.44076148 -1.02277289] # [-0.73490219 0.19197171 -0.22374362 0.52610852] # [-1.03531076 1.0595528 -0.11566501 0.34063544] # [-0.2122241 -0.81348187 1.70989712 -0.00732696]] # \u77e9\u9635\u5143\u7d20\u5e73\u5747\u503c 0.10788580775057008 # \u77e9\u9635\u5143\u7d20\u5e73\u5747\u503c 0.10788580775057008 # \u77e9\u9635\u5143\u7d20\u548c 2.1577161550114017 # \u77e9\u9635\u5143\u7d20\u548c 2.1577161550114017 # 0\u8f74\u5411\u7684\u7d2f\u548c [-0.16789031 0.68828737 0.21692365 1.42039545] # 1\u8f74\u5411\u7684\u7d2f\u548c [ 0.31297429 1.15923078 -0.24056558 0.24921247 0.67686419] # 1\u8f74\u5411\u7684\u5e73\u5747\u503c [ 0.07824357 0.28980769 -0.06014139 0.06230312 0.16921605] \u4e0b\u9762\u5217\u4e3e\u4e86\u5e38\u7528\u7684\u57fa\u7840\u6570\u7ec4\u7edf\u8ba1\u65b9\u6cd5\u3002 array = np.array([ [1, 2, 3, 4, 5], [3, 4, 5, 6, 7], [5, 6, 7, 8, 9] ], dtype=int) print(\"\u6837\u672c\u77e9\u9635 \\n\", array) print(\"\u8f74\u5411\u6c42\u548c\", array.sum()) print(\"\u8f74\u5411\u6c42\u548c\", array.sum(axis=0)) print(\"\u6570\u5b66\u5e73\u5747\", array.mean()) print(\"\u8f74\u5411\u6570\u5b66\u5e73\u5747\", array.mean(axis=0)) print(\"\u6807\u51c6\u5dee\", array.std(), \"\u65b9\u5dee\", array.var()) print(\"\u8f74\u5411\u6807\u51c6\u5dee\", array.std(axis=0), \"\u8f74\u5411\u65b9\u5dee\", array.var(axis=0)) print(\"\u6700\u5c0f\u503c\", array.min(), \"\u6700\u5927\u503c\", array.max()) print(\"\u8f74\u5411\u6700\u5c0f\u503c\", array.min(axis=0), \"\u8f74\u5411\u6700\u5927\u503c\", array.max(axis=0)) print(\"\u6700\u5c0f\u503c\u4f4d\u7f6e\", array.argmin(), \"\u6700\u5927\u503c\u4f4d\u7f6e\", array.argmax()) print(\"\u8f74\u5411\u6700\u5c0f\u503c\u4f4d\u7f6e\", array.argmin(axis=0), \"\u8f74\u5411\u6700\u5927\u503c\u4f4d\u7f6e\", array.argmax(axis=0)) print(\"\u7d2f\u79ef\u548c \\n\", array.cumsum()) print(\"\u8f74\u5411\u7d2f\u79ef\u548c \\n\", array.cumsum(axis=1)) print(\"\u7d2f\u79ef\u4e58\u79ef \\n\", array.cumprod()) print(\"\u8f74\u5411\u7d2f\u79ef\u4e58\u79ef \\n\", array.cumprod(axis=1)) # \u6837\u672c\u77e9\u9635 # [[1 2 3 4 5] # [3 4 5 6 7] # [5 6 7 8 9]] # \u8f74\u5411\u6c42\u548c 75 # \u8f74\u5411\u6c42\u548c [ 9 12 15 18 21] # \u6570\u5b66\u5e73\u5747 5.0 # \u8f74\u5411\u6570\u5b66\u5e73\u5747 [3. 4. 5. 6. 7.] # \u6807\u51c6\u5dee 2.160246899469287 \u65b9\u5dee 4.666666666666667 # \u8f74\u5411\u6807\u51c6\u5dee [1.63299316 1.63299316 1.63299316 1.63299316 1.63299316] \u8f74\u5411\u65b9\u5dee [2.66666667 2.66666667 2.66666667 2.66666667 2.66666667] # \u6700\u5c0f\u503c 1 \u6700\u5927\u503c 9 # \u8f74\u5411\u6700\u5c0f\u503c [1 2 3 4 5] \u8f74\u5411\u6700\u5927\u503c [5 6 7 8 9] # \u6700\u5c0f\u503c\u4f4d\u7f6e 0 \u6700\u5927\u503c\u4f4d\u7f6e 14 # \u8f74\u5411\u6700\u5c0f\u503c\u4f4d\u7f6e [0 0 0 0 0] \u8f74\u5411\u6700\u5927\u503c\u4f4d\u7f6e [2 2 2 2 2] # \u7d2f\u79ef\u548c # [ 1 3 6 10 15 18 22 27 33 40 45 51 58 66 75] # \u8f74\u5411\u7d2f\u79ef\u548c # [[ 1 3 6 10 15] # [ 3 7 12 18 25] # [ 5 11 18 26 35]] # \u7d2f\u79ef\u4e58\u79ef # [ 1 2 6 24 120 360 # 1440 7200 43200 302400 1512000 9072000 # 63504000 508032000 4572288000] # \u8f74\u5411\u7d2f\u79ef\u4e58\u79ef # [[ 1 2 6 24 120] # [ 3 12 60 360 2520] # [ 5 30 210 1680 15120]] \u5e03\u5c14\u503c\u6570\u7ec4(Boolean Array)\u7684\u65b9\u6cd5 \u00b6 \u5e03\u5c14\u503c\u6570\u7ec4\uff0c\u6709\u4e24\u4e2a\u975e\u5e38\u6709\u7528\u7684\u65b9\u6cd5any\u548call\u3002 * any\u68c0\u67e5\u6570\u7ec4\u4e2d\u662f\u5426\u81f3\u5c11\u6709\u4e00\u4e2aTrue\uff0c * all\u68c0\u67e5\u662f\u5426\u6bcf\u4e2a\u503c\u90fd\u662fTrue bools = np.array([False, False, True, False]) print(bools.any()) # True print(bools.all()) # False \u4e0b\u9762\u662f\u4e00\u4e2a\u8fd0\u7528\u5e03\u5c14\u503c\u6570\u7ec4\uff08Boolean Array\uff09\u8fdb\u884c\u6c42\u548c\u7684\u4e00\u4e2a\u4f8b\u5b50\uff0c\u5176\u4e2d (array > 0) \u672c\u8eab\u662f\u4e00\u4e2a\u5e03\u5c14\u578b\u7684\u6570\u7ec4\u3002 array = np.random.randn(100) result = (array > 0).sum() # \u8ba1\u7b97\u6b63\u503c\u7684\u4e2a\u6570 print(result) # 59 \u4e0b\u9762\u662f\u8fd0\u7528\u5e03\u5c14\u503c\u6570\u7ec4\u7684\u751f\u6210\u65b0\u6570\u7ec4\u7684\u4f8b\u5b50\u3002 arr = [[8, 9, 10, 11], [0, 1, 2, 3], [4, 5, 6, 7]] arr = np.array(arr) print(arr.shape) # (3, 4) print(arr) # [[ 8 9 10 11] # [ 0 1 2 3] # [ 4 5 6 7]] idx = [[1, 0, 0, 0], [0, 1, 0, 0], [0, 0, 1, 0]] idx = np.array(idx) print(idx.shape) # (3, 4) print(idx) # [[1 0 0 0] # [0 1 0 0] # [0 0 1 0]] result = arr[idx] # print(result.shape) # (3, 4, 4) print(result) # [[[ 0 1 2 3] # [ 8 9 10 11] # [ 8 9 10 11] # [ 8 9 10 11]] # [[ 8 9 10 11] # [ 0 1 2 3] # [ 8 9 10 11] # [ 8 9 10 11]] # [[ 8 9 10 11] # [ 8 9 10 11] # [ 0 1 2 3] # [ 8 9 10 11]]] result = arr[idx == 1] print(result.shape) print(result) # [8 1 6] \u6392\u5e8f \u00b6 \u548cPython\u7684\u5185\u5efa\u5217\u8868\u7c7b\u578b\u76f8\u4f3c\uff0cNumPy\u6570\u7ec4\u53ef\u4ee5\u4f7f\u7528sort\u65b9\u6cd5\u6309\u4f4d\u7f6e\u6392\u5e8f\u3002 \u9876\u5c42\u7684np.sort\u65b9\u6cd5\u8fd4\u56de\u7684\u662f\u5df2\u7ecf\u6392\u5e8f\u597d\u7684\u6570\u7ec4*\u62f7\u8d1d*\uff0c\u800c\u4e0d\u662f\u5bf9\u539f\u6570\u7ec4\u6309\u4f4d\u7f6e\u6392\u5e8f\u3002 array = np.random.randn(6) print(\"\u6837\u672c\u77e9\u9635\", array) array.sort() print(\"\u6392\u5e8f\u540e\u77e9\u9635\", array) # \u6837\u672c\u77e9\u9635 [-0.03119521 0.01839556 0.79238537 -2.46622775 0.62522211 0.22430846] # \u6392\u5e8f\u540e\u77e9\u9635 [-2.46622775 -0.03119521 0.01839556 0.22430846 0.62522211 0.79238537] \u591a\u7ef4\u6570\u7ec4\u4e2d\u6839\u636e\u4f20\u9012\u7684axis\u503c\uff0c\u6cbf\u7740\u8f74\u5411\u5bf9\u6bcf\u4e2a\u4e00\u7ef4\u6570\u636e\u6bb5\u8fdb\u884c\u6392\u5e8f\u3002 array = np.random.randn(5, 3) print(\"\u6837\u672c\u77e9\u9635 \\n\", array) array.sort(1) print(\"\u5bf91\u8f74\u6392\u5e8f\u540e\u77e9\u9635 \\n\", array) # \u6837\u672c\u77e9\u9635 # [[-0.88057833 0.30160954 -2.08788148] # [ 0.27969618 0.62923028 -0.58157581] # [-1.87194465 -1.1102104 1.09589605] # [ 0.1467938 -1.01558304 -0.25905165] # [-0.17294279 0.62369511 0.17947059]] # \u5bf91\u8f74\u6392\u5e8f\u540e\u77e9\u9635 # [[-2.08788148 -0.88057833 0.30160954] # [-0.58157581 0.27969618 0.62923028] # [-1.87194465 -1.1102104 1.09589605] # [-1.01558304 -0.25905165 0.1467938 ] # [-0.17294279 0.17947059 0.62369511]] \u552f\u4e00\u503c\u4e0e\u5176\u4ed6\u96c6\u5408\u903b\u8f91 \u00b6 NumPy\u5305\u542b\u4e00\u4e9b\u9488\u5bf9\u4e00\u7ef4 ndarray \u6570\u7ec4\u7684\u57fa\u7840\u96c6\u5408\u64cd\u4f5c\u3002 np.unique(x, y) \u8ba1\u7b97x\u7684\u552f\u4e00\u503c\uff0c\u5e76\u6392\u5e8f\u3002 names = np.array(['Bob', 'Joe', 'Will', 'Bob', 'Will', 'Joe', 'Joe']) result = np.unique(names) # NumPy\u5b9e\u73b0 print(result) # ['Bob' 'Joe' 'Will'] result = sorted(set(names)) # \u7eafPython\u5b9e\u73b0 print(result) # ['Bob' 'Joe' 'Will'] inits = np.array([3, 3, 3, 2, 2, 1, 1, 5, 5]) result = np.unique(inits) print(result) # [1 2 3 5] np.in1d(x, y) \u8ba1\u7b97x\u4e2d\u7684\u5143\u7d20\u662f\u5426\u5305\u542b\u5728y\u4e2d\uff0c\u5e76\u8fd4\u56de\u4e00\u4e2a\u5e03\u5c14\u503c\u6570\u7ec4\u3002 inits = np.array([3, 3, 3, 2, 2, 1, 1, 5, 5]) print(np.in1d(inits, [3, 4, 5])) # [ True True True False False False False True True] np.intersect1d(x, y) \uff0c\u8ba1\u7b97x\u548cy\u7684\u4ea4\u96c6\uff0c\u5e76\u6392\u5e8f\u3002 inits = np.array([3, 3, 3, 2, 2, 1, 1, 5, 5]) print(np.intersect1d(inits, [3, 4, 5])) # [3 5] np.union1d(x, y) \u8ba1\u7b97x\u548cy\u7684\u5e76\u96c6\uff0c\u5e76\u6392\u5e8f\u3002 inits = np.array([3, 3, 3, 2, 2, 1, 1, 5, 5]) print(np.union1d(inits, [3, 4, 5])) # [1 2 3 4 5] np.setdiff1d(x, y) \u5dee\u96c6\uff0c\u5728x\u4e2d\u4f46\u4e0d\u5728y\u4e2d\u7684\u5143\u7d20\u3002 inits = np.array([3, 3, 3, 2, 2, 1, 1, 5, 5]) print(np.setdiff1d(inits, [3, 4, 5])) # [1 2] np.setxor1d(x, y) \u5f02\u6216\u96c6\uff0c\u5728x\u6216\u8005y\u4e2d\uff0c\u4f46\u4e0d\u5c5e\u4e8ex\uff0cy\u4ea4\u96c6\u7684\u5143\u7d20\u3002 inits = np.array([3, 3, 3, 2, 2, 1, 1, 5, 5]) print(np.setxor1d(inits, [3, 4, 5])) # [1 2 4] \u4f7f\u7528\u6570\u7ec4\u8fdb\u884c\u6587\u4ef6\u8f93\u5165\u548c\u8f93\u51fa \u00b6 NumPy\u53ef\u4ee5\u5728\u786c\u76d8\u4e2d\u5c06\u6570\u636e\u4ee5\u6587\u672c\u6216\u4e8c\u8fdb\u5236\u6587\u4ef6\u7684\u5f62\u5f0f\u8fdb\u884c\u5b58\u5165\u786c\u76d8\u6216\u7531\u786c\u76d8\u8f7d\u5165\u3002 \u5f53\u524d\u53ea\u5173\u6ce8NumPy\u7684\u5185\u5efa\u4e8c\u8fdb\u5236\u683c\u5f0f\uff0c\u56e0\u4e3a\u5927\u90e8\u5206\u7528\u6237\u66f4\u503e\u5411\u4e8e\u4f7f\u7528pandas\u6216\u5176\u4ed6\u5de5\u5177\u6765\u8f7d\u5165\u6587\u672c\u6216\u8868\u683c\u578b\u6570\u636e\u3002 np.save \u548c np.load \u662f\u9ad8\u6548\u5b58\u53d6\u786c\u76d8\u6570\u636e\u7684\u4e24\u5927\u5de5\u5177\u51fd\u6570\u3002\u6570\u7ec4\u5728\u9ed8\u8ba4\u60c5\u51b5\u4e0b\u662f\u4ee5*\u672a\u538b\u7f29*\u7684\u683c\u5f0f\u8fdb\u884c\u5b58\u50a8\u7684\uff0c\u540e\u7f00\u540d\u662f.npy\u3002 import numpy as np array1 = np.arange(10) array2 = np.arange(15).reshape(3, 5) array3 = np.arange(30).reshape(3, 2, 5) print(array1) # [0 1 2 3 4 5 6 7 8 9] print(array2) # [[ 0 1 2 3 4] # [ 5 6 7 8 9] # [10 11 12 13 14]] print(array3) # [[[ 0 1 2 3 4] # [ 5 6 7 8 9]] # [[10 11 12 13 14] # [15 16 17 18 19]] # [[20 21 22 23 24] # [25 26 27 28 29]]] # \u67e5\u770b\u5f53\u524d\u8def\u5f84 os.getcwd() # '/opt/myProject/mySite' # \u66f4\u6539\u9ed8\u8ba4\u8def\u5f84 os.chdir('/opt/myProject/mySite/docs/python/datasets/examples') # \u4fdd\u5b58\u5230\u9ed8\u8ba4\u8def\u5f84\u3002npy\u540e\u7f00\u540d\u4f1a\u88ab\u81ea\u52a8\u52a0\u4e0a np.save('some_array', array1) # \u8bfb\u53d6\u6240\u4fdd\u5b58\u7684\u6587\u4ef6 result = np.load('some_array.npy') # \u5bf9\u6bd4\u7ed3\u679c\u4e00\u81f4\u3002 print(result) # [0 1 2 3 4 5 6 7 8 9] # \u5c06\u591a\u4e2a\u6570\u7ec4\u4fdd\u5b58\u5230\u672a\u538b\u7f29\u7684\u5355\u4e2a\u6587\u4ef6\u4e2d\uff0c.npz\u683c\u5f0f np.savez('some_array_archive.npz', a=array2, b=array3) result = np.load('some_array_archive.npz') # reslt\u662f\u4e00\u4e2a\u5b57\u5178\u578b\u7684\u5bf9\u8c61 print(result['b']) # \u8f7d\u5165\u5355\u4e2a\u6570\u7ec4b # [[[ 0 1 2 3 4] # [ 5 6 7 8 9]] # [[10 11 12 13 14] # [15 16 17 18 19]] # [[20 21 22 23 24] # [25 26 27 28 29]]] \u7ebf\u6027\u4ee3\u6570 \u00b6 \u53c2\u8003\u94fe\u63a5\uff1a https://www.numpy.org.cn/reference/routines/linalg.html https://github.com/teadocs/numpy-cn \u5e0c\u814a\u5b57\u6bcd: \u0391 \u03b1 /'\u00e6lf\u0259/ alpha \u0392 \u03b2 /'bi:t\u0259/ beta \u0393 \u03b3 /'g\u00e6m\u0259/ gamma \u0394 \u03b4 /'delt\u0259/ delta \u0395 \u03b5 /'eps\u026al\u0252n/ epsilon \u0396 \u03b6 /'zi:t\u0259/ zeta \u0397 \u03b7 /'i:t\u0259/ eta \u0398 \u03b8 /'\u03b8i:t\u0259/ theta \u0399 \u03b9 /'a\u026a\u0259\u028at\u0259/ iota \u039a \u03ba /'k\u00e6p\u0259/ kappa \u2227 \u03bb /'l\u00e6md\u0259/ lambda \u039c \u03bc /mju:/ mu \u039d \u03bd /nju:/ nu \u039e \u03be /ksi/ xi \u039f \u03bf /\u0259u\u02c8maikr\u0259n/ omicron \u220f \u03c0 /pa\u026a/ pi \u03a1 \u03c1 /r\u0259\u028a/ rho \u2211 \u03c3 /'s\u026a\u0261m\u0259/ sigma \u03a4 \u03c4 /t\u0254:/ tau \u03a5 \u03c5 /\u02c8ips\u026alon/ upsilon \u03a6 \u03c6 /fa\u026a/ phi \u03a7 \u03c7 /ka\u026a/ chi \u03a8 \u03c8 /psa\u026a/ psi \u03a9 \u03c9 /'\u0259\u028am\u026a\u0261\u0259/ omega numpy.linalg \u6a21\u5757\u5305\u542b\u7ebf\u6027\u4ee3\u6570\u7684\u51fd\u6570\u3002\u4f7f\u7528\u8fd9\u4e2a\u6a21\u5757\uff0c\u53ef\u4ee5\u8ba1\u7b97\u9006\u77e9\u9635\u3001\u6c42\u7279\u5f81\u503c\u3001\u89e3\u7ebf\u6027\u65b9\u7a0b\u7ec4\u4ee5\u53ca\u6c42\u89e3\u884c\u5217\u5f0f\u7b49\u3002 import numpy as np from numpy import linalg as LA from numpy import * from numpy.linalg import inv import matplotlib.pyplot as plt diag \u00b6 np.diag \u5c06\u4e00\u4e2a\u65b9\u9635\u7684\u5bf9\u89d2\uff08\u6216\u975e\u5bf9\u89d2\uff09\u5143\u7d20\u4f5c\u4e3a\u4e00\u7ef4\u6570\u7ec4\u8fd4\u56de\uff0c\u6216\u8005\u5c06\u4e00\u7ef4\u6570\u7ec4\u8f6c\u6362\u6210\u4e00\u4e2a\u65b9\u9635\uff0c\u5e76\u4e14\u5728\u975e\u5bf9\u89d2\u7ebf\u4e0a\u6709\u96f6\u70b9\u3002 a1 = np.arange(9, dtype=float).reshape((3, 3)) r1 = np.diag(a1) r2 = np.diag(a1, k=1) r3 = np.diag(a1, k=-1) r4 = np.diag(np.diag(a1)) # \u5bf9\u89d2\u77e9\u9635 print(\"\u6837\u672c\u77e9\u9635 \\n\", a1) print(\"\u77e9\u9635\u5bf9\u89d2\u7ebf\", r1) print(\"\u77e9\u9635\u5bf9\u89d2\u7ebf\u5411\u4e0a\u504f\u79fb\", r2) print(\"\u77e9\u9635\u5bf9\u89d2\u7ebf\u5411\u4e0b\u504f\u79fb\", r3) print(\"\u5bf9\u89d2\u77e9\u9635 \\n\", r4) # \u6837\u672c\u77e9\u9635 # [[0. 1. 2.] # [3. 4. 5.] # [6. 7. 8.]] # \u77e9\u9635\u5bf9\u89d2\u7ebf [0. 4. 8.] # \u77e9\u9635\u5bf9\u89d2\u7ebf\u5411\u4e0a\u504f\u79fb [1. 5.] # \u77e9\u9635\u5bf9\u89d2\u7ebf\u5411\u4e0b\u504f\u79fb [3. 7.] # \u5bf9\u89d2\u77e9\u9635 # [[0. 0. 0.] # [0. 4. 0.] # [0. 0. 8.]] dot \u00b6 np.dot \u5c06\u5411\u91cf\u4e2d\u5bf9\u5e94\u5143\u7d20\u76f8\u4e58\uff0c\u518d\u76f8\u52a0\u6240\u5f97\u3002\u5373\u666e\u901a\u7684\u5411\u91cf\u4e58\u6cd5\u8fd0\u7b97\uff0c\u6216**\u77e9\u9635\u70b9\u4e58**\u3002 a1 = np.dot(3, 4) print(a1) # 12 a2 = np.arange(9, dtype=float).reshape((3, 3)) r2 = np.dot(a2, a2) print(a2) # [[0. 1. 2.] # [3. 4. 5.] # [6. 7. 8.]] print(r2) # [[ 15. 18. 21.] # [ 42. 54. 66.] # [ 69. 90. 111.]] r3 = np.dot([2j, 3j], [2j, 3j]) print(r3) # (-13+0j) trace \u00b6 np.trace \u8ba1\u7b97\u5bf9\u89d2\u5143\u7d20\u548c\u3002 a1 = np.arange(9, dtype=float).reshape((3, 3)) print(\"\u6837\u672c\u77e9\u9635 \\n\", a1) r1 = np.trace(a1) print(\"\u5bf9\u89d2\u7ebf\u5143\u7d20\u6c42\u548c\", r1) a2 = np.arange(24, dtype=float).reshape((2, 3, 4)) r2 = np.trace(a2) print(\"\u6837\u672c\u77e9\u9635 \\n\", a2) print(\"\u5bf9\u89d2\u7ebf\u5143\u7d20\u6c42\u548c\", r2) # \u6837\u672c\u77e9\u9635 # [[0. 1. 2.] # [3. 4. 5.] # [6. 7. 8.]] # \u5bf9\u89d2\u7ebf\u5143\u7d20\u6c42\u548c 12.0 # \u6837\u672c\u77e9\u9635 # [[[ 0. 1. 2. 3.] # [ 4. 5. 6. 7.] # [ 8. 9. 10. 11.]] # # [[12. 13. 14. 15.] # [16. 17. 18. 19.] # [20. 21. 22. 23.]]] # \u5bf9\u89d2\u7ebf\u5143\u7d20\u6c42\u548c [16. 18. 20. 22.] det \u00b6 np.det \u8ba1\u7b97\u77e9\u9635\u7684\u884c\u5217\u5f0f\uff08\u65b9\u9635\uff09\u3002 \u4e8c\u9636\u884c\u5217\u5f0f[[a, b], [c, d]]\u7684\u503c\u662fad - bc \u4e09\u9636\u884c\u5217\u5f0f [[a, b, c], [d, e, f], [g, h, i]]\u7684\u503c\u662f aei + bfd + cdh - ceg - bdi - afh \u4e09\u9636\u884c\u5217\u5f0f\u7684\u6027\u8d28 \u6027\u8d281\uff1a\u884c\u5217\u5f0f\u4e0e\u5b83\u7684\u8f6c\u7f6e\u884c\u5217\u5f0f\u76f8\u7b49\u3002 \u6027\u8d282\uff1a\u4e92\u6362\u884c\u5217\u5f0f\u7684\u4e24\u884c(\u5217)\uff0c\u884c\u5217\u5f0f\u53d8\u53f7\u3002 \u63a8\u8bba\uff1a\u5982\u679c\u884c\u5217\u5f0f\u6709\u4e24\u884c(\u5217)\u5b8c\u5168\u76f8\u540c\uff0c\u5219\u6b64\u884c\u5217\u5f0f\u4e3a\u96f6\u3002 \u6027\u8d283\uff1a\u884c\u5217\u5f0f\u7684\u67d0\u4e00\u884c(\u5217)\u4e2d\u6240\u6709\u7684\u5143\u7d20\u90fd\u4e58\u4ee5\u540c\u4e00\u6570k\uff0c\u7b49\u4e8e\u7528\u6570k\u4e58\u6b64\u884c\u5217\u5f0f\u3002 \u63a8\u8bba\uff1a\u884c\u5217\u5f0f\u4e2d\u67d0\u4e00\u884c(\u5217)\u7684\u6240\u6709\u5143\u7d20\u7684\u516c\u56e0\u5b50\u53ef\u4ee5\u63d0\u5230\u884c\u5217\u5f0f\u7b26\u53f7\u7684\u5916\u9762\u3002 \u6027\u8d284\uff1a\u884c\u5217\u5f0f\u4e2d\u5982\u679c\u6709\u4e24\u884c(\u5217)\u5143\u7d20\u6210\u6bd4\u4f8b\uff0c\u5219\u6b64\u884c\u5217\u5f0f\u7b49\u4e8e\u96f6\u3002 \u6027\u8d285\uff1a\u628a\u884c\u5217\u5f0f\u7684\u67d0\u4e00\u5217(\u884c)\u7684\u5404\u5143\u7d20\u4e58\u4ee5\u540c\u4e00\u6570\u7136\u540e\u52a0\u5230\u53e6\u4e00\u5217(\u884c)\u5bf9\u5e94\u7684\u5143\u7d20\u4e0a\u53bb\uff0c\u884c\u5217\u5f0f\u4e0d\u53d8\u3002 a1 = np.array([[1, 2], [3, 4]]) r1 = np.linalg.det(a1) print(\"\u4e8c\u9636\u65b9\u9635 \\n\", a1) print(\"\u4e8c\u9636\u884c\u5217\u5f0f\u7684\u503c\", r1) # \u4e8c\u9636\u65b9\u9635 # [[1 2] # [3 4]] # \u4e8c\u9636\u884c\u5217\u5f0f\u7684\u503c -2.0000000000000004 # \u5e0c\u814a\u5b57\u6bcd # \u03b1, \u03b2, \u03b3,\u03b4, \u03b5, \u03b6, \u03b7, \u03b8, \u03b9, \u03ba, \u03bb, \u03bc, \u03bd, # \u03be, \u03bf, \u03c0, \u03c1, \u03c2, \u03c3, \u03c4, \u03c5, \u03c6, \u03c7, \u03c8, \u03c9, a2 = np.arange(9).reshape(3, 3) r2 = np.linalg.det(a2) print(\"\u4e09\u9636\u65b9\u9635 \\n\", a2) print(\"\u4e09\u9636\u884c\u5217\u5f0f\u7684\u503c\", r2) # \u4e09\u9636\u65b9\u9635 # [[0 1 2] # [3 4 5] # [6 7 8]] # \u4e09\u9636\u884c\u5217\u5f0f\u7684\u503c 0.0 a3 = np.arange(16).reshape(4, 4) r3 = np.linalg.det(a3) print(\"\u56db\u9636\u65b9\u9635 \\n\", a3) print(\"\u56db\u9636\u884c\u5217\u5f0f\u7684\u503c\", r3) # \u56db\u9636\u65b9\u9635 # [[ 0 1 2 3] # [ 4 5 6 7] # [ 8 9 10 11]# \u5e0c\u814a\u5b57\u6bcd # \u03b1, \u03b2, \u03b3,\u03b4, \u03b5, \u03b6, \u03b7, \u03b8, \u03b9, \u03ba, \u03bb, \u03bc, \u03bd, # \u03be, \u03bf, \u03c0, \u03c1, \u03c2, \u03c3, \u03c4, \u03c5, \u03c6, \u03c7, \u03c8, \u03c9, # [12 13 14 15]] # \u56db\u9636\u884c\u5217\u5f0f\u7684\u503c 0.0 eig \u00b6 np.eig \u8ba1\u7b97\u65b9\u9635\u7684\u7279\u5f81\u503c\u548c\u7279\u5f81\u5411\u91cf\u3002 \u7279\u5f81\u503c\u4e0e\u7279\u5f81\u5411\u91cf\u7684\u5b9a\u4e49\uff1a\u8bbeA\u662fn\u9636\u65b9\u9635\uff0c\u82e5\u6570\u03bb\u548cn\u7ef4\u975e\u96f6\u5217\u5411\u91cfx\uff0c\u4f7f\u5f97Ax = \u03bbx\u6210\u7acb\uff0c\u5219\u79f0\u03bb\u662f\u65b9\u9635A\u7684\u4e00\u4e2a\u7279\u5f81\u503c\uff0cx\u4e3a\u65b9\u9635A\u7684\u5bf9\u5e94\u4e8e\u7279\u5f81\u503c\u03bb\u7684\u4e00\u4e2a\u7279\u5f81\u5411\u91cf\u3002 A\u662f\u65b9\u9635\u3002\uff08\u5bf9\u4e8e\u975e\u65b9\u9635\uff0c\u662f\u6ca1\u6709\u7279\u5f81\u503c\u7684\uff0c\u4f46\u4f1a\u6709\u6761\u4ef6\u6570\u3002\uff09\u7279\u5f81\u5411\u91cfx\u4e3a\u975e\u96f6\u5217\u5411\u91cf\u3002 v_eigenvectors, v_eigenvalues = LA.eig(np.diag((1, 2, 3))) print(\"\u7279\u5f81\u5411\u91cf\", v_eigenvectors) print(\"\u7279\u5f81\u503c \\n\", v_eigenvalues) # \u7279\u5f81\u5411\u91cf [1. 2. 3.] # \u7279\u5f81\u503c # [[1. 0. 0.] # [0. 1. 0.] # [0. 0. 1.]] v_eigenvectors, v_eigenvalues = LA.eig(np.array([[1, -1], [1, 1]])) print(\"\u7279\u5f81\u5411\u91cf\", v_eigenvectors) print(\"\u7279\u5f81\u503c \\n\", v_eigenvalues) # \u7279\u5f81\u5411\u91cf [1.+1.j 1.-1.j] # \u7279\u5f81\u503c # [[0.70710678+0.j 0.70710678-0.j ] # [0. -0.70710678j 0. +0.70710678j]] inv \u00b6 np.inv \u8ba1\u7b97\u65b9\u9635\u7684\u9006\u77e9\u9635\u3002 a1 = np.array([[1, 2], [3, 4]]) r1 = inv(a1) r2 = inv(np.matrix(a1)) print(\"\u539f\u77e9\u9635 \\n\", a1) print(\"\u9006\u77e9\u9635 \\n\", r1) print(\"\u9006\u77e9\u9635 \\n\", r2) # \u539f\u77e9\u9635 # [[1 2] # [3 4]] # \u9006\u77e9\u9635 # [[-2. 1. ] # [ 1.5 -0.5]] # \u9006\u77e9\u9635 # [[-2. 1. ] # [ 1.5 -0.5]] pinv \u00b6 np.pinv \u8ba1\u7b97\u77e9\u9635\u7684Moore-Penrose\u4f2a\u9006(\u6469\u5c14\uff0d\u5f6d\u82e5\u65af\u5e7f\u4e49\u9006)\u3002 \u4e0b\u9762\u7684\u4f8b\u5b50\u68c0\u9a8c a * a+ * a == a \u548c a+ * a * a+ == a+ a = np.random.randn(9, 6) B = np.linalg.pinv(a) r1 = np.allclose(a, np.dot(a, np.dot(B, a))) r2 = np.allclose(B, np.dot(B, np.dot(a, B))) print(a) print(B) print(r1) # True print(r2) # True # a: # [[-2.30316101 -0.63217332 1.24134743 -0.72492307 0.12456801 -0.14192548] # [ 1.37573495 0.07626697 -0.71870843 1.26824984 -0.79485727 -0.24630455] # [ 0.29003175 -1.23931665 -0.50864107 -0.31140718 0.45467649 -2.44973999] # [-0.70748664 -1.2995059 0.85126149 -1.10918804 -2.10042342 0.75942293] # [ 1.91765238 1.23892103 1.58516486 -1.65520154 0.11894439 0.84536298] # [ 1.03220791 0.1715148 0.85595408 0.58569706 1.34066384 -1.5782386 ] # [-0.54432889 -0.0114189 1.55403934 0.89852512 1.15586365 -0.30733805] # [-0.80874673 0.14602121 1.04680044 1.98722514 0.39766383 0.75178788] # [ 0.01664663 0.06243353 -0.50725334 -0.37707204 -1.76701091 -0.33866559]] # B: # [[-0.25055838 0.13963115 0.08990923 0.16280282 0.12997291 0.05088469 -0.01541299 -0.01656133 -0.21731387] # [ 0.22862622 -0.05108109 -0.2639602 -0.47835978 0.11776862 0.09324694 0.00436756 -0.00609393 0.61995597] # [ 0.10422554 0.03985857 0.00198025 0.15139023 0.17165026 0.15697725 0.17360246 0.13150089 0.08378135] # [-0.07021378 0.17665487 -0.04109252 0.0015022 -0.11998477 0.0543575 0.08649033 0.21190785 0.04065729] # [-0.08110336 -0.15274536 0.05601496 -0.07967802 -0.02454705 -0.04152356 0.00071268 -0.05981012 -0.43996066] # [-0.17998537 -0.03160871 -0.12587707 0.16856246 0.00565094 -0.21038026 -0.06060039 0.04322126 -0.42038066]] qr \u00b6 np.qr \u8ba1\u7b97QR\u5206\u89e3\u3002QR\uff08\u6b63\u4ea4\u4e09\u89d2\uff09\u5206\u89e3\u6cd5\u662f\u6c42\u4e00\u822c\u77e9\u9635\u5168\u90e8\u7279\u5f81\u503c\u7684\u6700\u6709\u6548\u5e76\u5e7f\u6cdb\u5e94\u7528\u7684\u65b9\u6cd5\u3002 \u4e00\u822c\u77e9\u9635\u5148\u7ecf\u8fc7\u6b63\u4ea4\u76f8\u4f3c\u53d8\u5316\u6210\u4e3aHessenberg\u77e9\u9635\uff0c\u7136\u540e\u518d\u5e94\u7528QR\u65b9\u6cd5\u6c42\u7279\u5f81\u503c\u548c\u7279\u5f81\u5411\u91cf\u3002QR\u5206\u89e3\u6cd5\u662f\u5c06\u77e9\u9635\u5206\u89e3\u6210\u4e00\u4e2a\u6b63\u89c4\u6b63\u4ea4\u77e9\u9635Q\u4e0e\u4e0a\u4e09\u89d2\u5f62\u77e9\u9635R\uff0c\u6240\u4ee5\u79f0\u4e3aQR\u5206\u89e3\u6cd5\u3002 a = np.arange(9).reshape(3, 3) q, r = np.linalg.qr(a) print(\"\u539f\u77e9\u9635 \\n\", a) print(\"\u6b63\u4ea4\u77e9\u9635 \\n\", q) print(\"\u4e0a\u4e09\u89d2\u77e9\u9635 \\n\", r) # \u539f\u77e9\u9635 # [[0 1 2] # [3 4 5] # [6 7 8]] # \u6b63\u4ea4\u77e9\u9635 # [[ 0. 0.91287093 0.40824829] # [-0.4472136 0.36514837 -0.81649658] # [-0.89442719 -0.18257419 0.40824829]] # \u4e0a\u4e09\u89d2\u77e9\u9635 # [[-6.70820393e+00 -8.04984472e+00 -9.39148551e+00] # [ 0.00000000e+00 1.09544512e+00 2.19089023e+00] # [ 0.00000000e+00 0.00000000e+00 -8.88178420e-16]] svd \u00b6 np.svd \u8ba1\u7b97\u5947\u5f02\u503c\u5206\u89e3\uff08SVD\uff09\u3002 \u51e0\u4f55\u610f\u4e49\uff1aSVD\u5206\u89e3\u7684\u51e0\u4f55\u610f\u4e49\u662f\u4efb\u4f55\u4e00\u4e2a\u77e9\u9635A\u5728\u4e00\u7cfb\u5217\u65cb\u8f6c\u548c\u5e73\u79fb\u4e0b\u90fd\u80fd\u8f6c\u5316\u6210\u4e00\u4e2a\u5bf9\u89d2\u77e9\u9635\u2211 , \u5176\u4e2d\u9149\u9635U, V\u7684\u51e0\u4f55\u610f\u4e49\u5c31\u662f\u4e00\u7cfb\u5217\u65cb\u8f6c\u548c\u5e73\u79fb\u7684\u53e0\u52a0\u3002 a = mat([[1, 2, 3],[4, 5, 6]]) U, sigma, V = np.linalg.svd(a) print(\"\u539f\u77e9\u9635 \\n\", a) print(\"\u5de6\u5947\u5f02\u503cU \\n\", U) print(\"\u5947\u5f02\u503cSigma \\n\", sigma) print(\"\u53f3\u5947\u5f02\u503cV \\n\", V) # \u539f\u77e9\u9635 # [[1 2 3] # [4 5 6]] # \u5de6\u5947\u5f02\u503cU # [[-0.3863177 -0.92236578] # [-0.92236578 0.3863177 ]] # \u5947\u5f02\u503cSigma # [9.508032 0.77286964] # \u53f3\u5947\u5f02\u503cV # [[-0.42866713 -0.56630692 -0.7039467 ] # [ 0.80596391 0.11238241 -0.58119908] # [ 0.40824829 -0.81649658 0.40824829]] solve \u00b6 np.solve \u6c42\u89e3x\u7684\u7ebf\u6027\u7cfb\u7edfAx = b\uff0c\u5176\u4e2dA\u662f\u65b9\u9635\u3002 \u89e3\u65b9\u7a0b\u7ec4\uff1a x + 2y = 1 3x + 5y = 2 a = np.array([[1, 2], [3, 5]]) b = np.array([1, 2]) x = np.linalg.solve(a, b) print(x) # [-1. 1.] lstsq \u00b6 np.lstsq \u8ba1\u7b97Ax = b\u7684\u6700\u5c0f\u4e8c\u4e58\u89e3\u3002 \u7528\u6700\u5c0f\u4e8c\u4e58\u6cd5\u62df\u5408\u6570\u636e\u5f97\u5230\u4e00\u4e2a\u5f62\u5982y = mx + c\u7684\u7ebf\u6027\u65b9\u7a0b\uff08Return the least-squares solution to a linear matrix equation\uff09\u3002 x = np.array([0, 1, 2, 3]) # \u539f\u59cb\u6570\u636e\u70b9\u7684\u6a2a\u5750\u6807 y = np.array([-1, 0.2, 0.9, 2.1]) # \u539f\u59cb\u6570\u636e\u70b9\u7684\u7eb5\u5750\u6807 print(x) # [0 1 2 3] print(y) # [-1. 0.2 0.9 2.1] A = np.vstack([x, np.ones(len(x))]).T # \u6784\u9020\u7cfb\u6570\u77e9\u9635 print(A) # [[0. 1.] # [1. 1.] # [2. 1.] # [3. 1.]] m, c = np.linalg.lstsq(A, y, rcond=None)[0] # \u89e3\u51fa\u659c\u7387a\u548c\u7eb5\u622a\u8dddc plt.plot(x, y, 'o', label='Original data', markersize=10) # \u505a\u51fa\u539f\u59cb\u6570\u636e\u6563\u70b9\u56fe plt.plot(x, m*x + c, 'r', label='Fitted line') # \u7528\u4e0a\u9762\u89e3\u51fa\u7684\u53c2\u6570\u505a\u51fa\u62df\u5408\u66f2\u7ebfy=mx+c plt.legend() plt.show() \u4f2a\u968f\u673a\u6570\u751f\u6210 \u00b6 numpy.random \u6a21\u5757\u586b\u8865\u4e86Python\u5185\u5efa\u7684 random \u6a21\u5757\u7684\u4e0d\u8db3\uff0c\u53ef\u4ee5\u9ad8\u6548\u5730\u751f\u6210\u591a\u79cd\u6982\u7387\u5206\u5e03\u4e0b\u7684\u5b8c\u6574\u6837\u672c\u503c\u6570\u7ec4\u3002 numpy.random \u4e2d\u7684\u6570\u636e\u751f\u6210\u51fd\u6570\u516c\u7528\u4e86\u4e00\u4e2a\u5168\u5c40\u7684\u968f\u673a\u6570\u79cd\u5b50\u3002 \u4f7f\u7528 numpy.random.RandomState \u751f\u6210\u4e00\u4e2a\u968f\u673a\u6570\u751f\u6210\u5668\uff0c\u4f7f\u6570\u636e\u72ec\u7acb\u4e8e\u5176\u4ed6\u7684\u968f\u673a\u6570\u72b6\u6001\u3002 \u901a\u8fc7 np.random.seed \u66f4\u6539NumPy\u7684\u968f\u673a\u6570\u79cd\u5b50\u3002 numpy.random \u4e2d\u7684\u90e8\u5206\u51fd\u6570\u5217\u8868 seed: \u5411\u968f\u673a\u6570\u751f\u6210\u5668\u4f20\u9012\u968f\u673a\u72b6\u6001\u79cd\u5b50 permutation: \u8fd4\u56de\u4e00\u4e2a\u5e8f\u5217\u7684\u968f\u673a\u6392\u5217\uff0c\u6216\u8005\u8fd4\u56de\u4e00\u4e2a\u4e71\u5e8f\u7684\u6574\u6570\u8303\u56f4\u5e8f\u5217 shuffle: \u968f\u673a\u6392\u5217\u4e00\u4e2a\u5e8f\u5217 rand: \u4ece\u5747\u5300\u5206\u5e03\u4e2d\u62bd\u53d6\u6837\u672c randint: \u6839\u636e\u7ed9\u5b9a\u7684\u7531\u4f4e\u5230\u9ad8\u7684\u8303\u56f4\u62bd\u53d6\u968f\u673a\u6574\u6570 randn: \u4ece\u5747\u503c0\u65b9\u5dee1\u7684\u6b63\u6001\u5206\u5e03\u4e2d\u62bd\u53d6\u6837\u672c(MATLAB\u578b\u63a5\u53e3\uff09 binomial: \u4ece\u4e8c\u9879\u5206\u5e03\u4e2d\u62bd\u53d6\u6837\u672c normal: \u4ece\u6b63\u6001\uff08\u9ad8\u65af\uff09\u5206\u5e03\u4e2d\u62bd\u53d6\u6837\u672c beta\u4ecebeta: \u5206\u5e03\u4e2d\u62bd\u53d6\u6837\u672c chisquare: \u4ece\u5361\u65b9\u5206\u5e03\u4e2d\u62bd\u53d6\u6837\u672c \u4f8b\u5982\uff0c\u4f7f\u7528normal\u6765\u83b7\u5f97\u4e00\u4e2a4\u00d74\u7684\u6b63\u6001\u5206\u5e03\u6837\u672c\u6570\u7ec4\uff0c\u79f0\u4e3a\u4f2a\u968f\u673a\u6570\u3002 import numpy as np samples = np.random.normal(size=(4, 4)) print(samples) # [[ 0.78583658 -0.27462104 -0.53027675 -0.62675004] # [ 0.39054781 1.20503691 -0.0057432 0.17243182] # [-0.41516669 -0.93335854 0.01996088 -0.12707275] # [ 0.42952379 2.56998319 0.14848737 -0.42871493]] \u793a\u4f8b\uff1a\u968f\u673a\u6f2b\u6b65 \u00b6 import matplotlib.pyplot as plt import numpy as np position = 0 walk = [position] nwalks = 5000 nsteps = 1000 draws = np.random.randint(0, 2, size=(nwalks, nsteps)) steps = np.where(draws > 0, 1, -1) walks = steps.cumsum() plt.plot(walks[:500000000000000000000000000]) plt.show() \u8f93\u51fa\u56fe\u50cf\uff1a","title":"NumPy\u57fa\u7840"},{"location":"python/DataAnalysis/ch01/#numpy","text":"\u5305\u542b\u4ee5\u4e0b\u5185\u5bb9\uff1a \u591a\u7ef4\u6570\u7ec4\u5bf9\u8c61 \u901a\u7528\u51fd\u6570 \u9762\u5411\u6570\u7ec4\u7f16\u7a0b \u4f7f\u7528\u6570\u7ec4\u8fdb\u884c\u6587\u4ef6\u8f93\u5165\u548c\u8f93\u51fa \u7ebf\u6027\u4ee3\u6570 \u4f2a\u968f\u673a\u6570\u751f\u6210 \u793a\u4f8b\uff1a\u968f\u673a\u6f2b\u6b65","title":"NumPy\u57fa\u7840"},{"location":"python/DataAnalysis/ch01/#ndarry","text":"","title":"\u591a\u7ef4\u6570\u7ec4\u5bf9\u8c61ndarry"},{"location":"python/DataAnalysis/ch01/#_1","text":"import numpy as np import pandas as pd import matplotlib.pyplot as plt","title":"\u522b\u540d\u7ea6\u5b9a"},{"location":"python/DataAnalysis/ch01/#matplotlib","text":"\u67e5\u770b\u5b57\u4f53\u8def\u5f84 >>> import matplotlib >>> print(matplotlib.matplotlib_fname()) /home/james/.local/lib/python3.6/site-packages/matplotlib/mpl-data/matplotlibrc \u4e0b\u8f7d\u4e2d\u6587\u5b57\u4f53\u3002\u7f51\u5740 https://www.fontpalace.com/font-download/SimHei/,\u5e76\u62f7\u8d1d\u5230\u4e0b\u9762\u7684\u8def\u5f84\u4e0b james@lizard:~/Downloads> cp SimHei.ttf /home/james/.local/lib/python3.6/site-packages/matplotlib/mpl-data/fonts/ttf/ \u67e5\u770bmatplotlib\u7684\u5b57\u4f53\u7f13\u5b58\u76ee\u5f55\u3002 >>> import matplotlib >>> print(matplotlib.get_cachedir()) /home/james/.cache/matplotlib \u5220\u9664\u8fd9\u4e2a\u76ee\u5f55 james@lizard:~> rm -rf /home/james/.cache/matplotlib \u7f16\u8f91matplotlibrc\u6587\u4ef6 /home/james/.local/lib/python3.6/site-packages/matplotlib/mpl-data/matplotlibrc \uff0c\u505a\u5982\u4e0b\u4fee\u6539\u3002 \u5b9a\u4f4d\u8fd9\u4e00\u884c\uff0c\u53bb\u6389\u6ce8\u91ca\u7b26 # font.family: sans-serif \u5b9a\u4f4d\u8fd9\u4e00\u884c\uff0c\u53bb\u6389\u6ce8\u91ca\u7b26 # \uff0c\u5e76\u6dfb\u52a0 SimHei \uff0c\u4fee\u6539\u540e\u4e3a font.serif: SimHei, DejaVu Serif, Bitstream Vera Serif, Computer Modern Roman, New Century Schoolbook, Century Schoolbook L, Utopia, ITC Bookman, Bookman, Nimbus Roman No9 L, Times New Roman, Times, Palatino, Charter, serif \u5b9a\u4f4d\u8fd9\u4e00\u884c\uff0c\u53bb\u6389\u6ce8\u91ca\u7b26 # \uff0c\u5e76\u6dfb\u52a0 SimHei \uff0c\u4fee\u6539\u540e\u4e3a font.sans-serif: SimHei, DejaVu Sans, Bitstream Vera Sans, Computer Modern Sans Serif, Lucida Grande, Verdana, Geneva, Lucid, Arial, Helvetica, Avant Garde, sans-serif \u5b9a\u4f4d\u8fd9\u4e00\u884c\uff0c\u53bb\u6389\u6ce8\u91ca\u7b26 # \uff0c\u5e76\u628a True \u6539\u4e3a False \uff0c\u4fee\u6539\u540e\u4e3a axes.unicode_minus: False","title":"\u5b89\u88c5matplotlib\u4e2d\u6587\u5b57\u4f53"},{"location":"python/DataAnalysis/ch01/#matplotlib_1","text":"\u5728\u4f7f\u7528matplotlib\u8f93\u51fa\u56fe\u50cf\u65f6\uff0c\u5982\u679c\u9047\u5230\u65e0\u6cd5\u663e\u793a\u56fe\u50cf\u7684\u9519\u8bef UserWarning: Matplotlib is currently using agg, which is a non-GUI backend, so cannot show the figure\u3002 \uff0c\u53ef\u4ee5\u5c1d\u8bd5\u4e0b\u9762\u7684\u6b65\u9aa4\u89e3\u51b3\u3002 \u5b89\u88c5 python3-tk \u5305 james@lizard:~> sudo zypper in python3-tk \u6216\u8005\u901a\u8fc7 pip \u5b89\u88c5 tk \u5305 james@lizard:~> pip3 install tk Defaulting to user installation because normal site-packages is not writeable Collecting tk Downloading tk-0.1.0-py3-none-any.whl (3.9 kB) Installing collected packages: tk Successfully installed tk-0.1.0 \u4e00\u822c\u5b8c\u6210\u4e0a\u9762\u5b89\u88c5\u540e\uff0c\u7a0b\u5e8f\u5c31\u80fd\u81ea\u52a8\u663e\u793a\u56fe\u4e86\uff0c\u5982\u679c\u8fd8\u662f\u4e0d\u80fd\u663e\u793a\uff0c\u518d\u5c1d\u8bd5\u91cd\u65b0\u5b89\u88c5 matplotlib \u3002 pip3 ininstall matplotlib pip3 install matplotlib","title":"\u8bbe\u7f6ematplotlib\u540e\u7aef\u6e32\u67d3\u5668"},{"location":"python/DataAnalysis/ch01/#ndarray-n-","text":"\u4e00\u4e2andarray\u662f\u4e00\u4e2a\u901a\u7528\u7684\u591a\u7ef4\u540c\u7c7b\u6570\u636e\u5bb9\u5668\uff0c\u4e5f\u5c31\u662f\u8bf4\uff0c\u5b83\u5305\u542b\u7684\u6bcf\u4e00\u4e2a\u5143\u7d20\u5747\u4e3a**\u76f8\u540c\u7c7b\u578b**\uff1b \u6bcf\u4e00\u4e2a\u6570\u7ec4\u90fd\u6709\u4e00\u4e2ashape\u5c5e\u6027\uff0c\u7528\u6765\u8868\u5f81\u6570\u7ec4\u6bcf\u4e00\u7ef4\u5ea6\u7684\u6570\u91cf\uff1b \u6bcf\u4e00\u4e2a\u6570\u7ec4\u90fd\u6709\u4e00\u4e2adtype\u5c5e\u6027\uff0c\u7528\u6765\u63cf\u8ff0\u6570\u7ec4\u7684\u6570\u636e\u7c7b\u578b\uff1b \u4e0b\u9762\u662f\u6807\u51c6\u6570\u7ec4\u7684\u751f\u6210\u51fd\u6570 array: \u5c06\u8f93\u5165\u6570\u636e\uff08\u5217\u8868\u3001\u5143\u7ec4\u3001\u6570\u7ec4\uff0c\u5176\u4ed6\u5e8f\u5217\uff09\u8f6c\u6362\u4e3andarray\uff0c\u5982\u679c\u4e0d\u663e\u5f0f\u6307\u660e\u6570\u636e\u7c7b\u578b\uff0c\u5c06\u81ea\u52a8\u63a8\u65ad\uff1b\u9ed8\u8ba4\u590d\u5236\u6240\u6709\u7684\u8f93\u5165\u6570\u636e\u3002 asarray\uff1a\u5c06\u8f93\u5165\u8f6c\u6362\u4e3andarray\uff0c\u4f46\u5982\u679c\u8f93\u5165\u5df2\u7ecf\u662fndarray\u5219\u4e0d\u518d\u590d\u5236\u3002 arange\uff1aPython\u5185\u7f6e\u51fd\u6570range\u7684\u6570\u7ec4\u7248\uff0c\u8fd4\u56de\u4e00\u4e2a\u6570\u7ec4\u3002 \u4e0b\u9762\u662f\u7528 Numpy.random() \u4e00\u4e2a\u751f\u6210\u4e00\u4e2a\u968f\u673a\u6570\u7ec4\u7684\u4f8b\u5b50\uff0c\u6ce8\u610f data01 \u7684\u7c7b\u578b\u662f'numpy.ndarray'\u3002\u53ef\u4ee5\u5728ndarray\u7c7b\u578b\u6570\u7ec4\u4e0a\u53e0\u52a0\u4e00\u4e0b\u6570\u5b66\u64cd\u4f5c\u3002 data01 = np.random.randn(2, 3) print(type(data01)) # print(data01) # [[ 0.12047302 -1.13499045 -0.39311368] # [ 1.54046881 0.01254838 -3.65090952]] print(data01 * 10) # \u7ed9data\u52a0\u4e0a\u4e00\u4e2a\u6570\u5b66\u64cd\u4f5c, \u6240\u6709\u7684\u5143\u7d20\u90fd\u540c\u65f6\u4e58\u4ee5\u4e8610 # [[ 1.20473022 -11.3499045 -3.93113676] # [ 15.40468806 0.12548383 -36.50909515]] print(data01 + data01) # \u7ed9data\u52a0\u4e0a\u4e00\u4e2a\u6570\u5b66\u64cd\u4f5c, \u6570\u7ec4\u4e2d\u7684\u5bf9\u5e94\u5143\u7d20\u8fdb\u884c\u4e86\u76f8\u52a0 # [[ 0.24094604 -2.2699809 -0.78622735] # [ 3.08093761 0.02509677 -7.30181903]] print(data01.shape) # (2, 3) print(data01.dtype) # float64 \u5f53\u8868\u8fbe\u201c\u6570\u7ec4\u201d\u3001\u201cNumPy\u6570\u7ec4\u201d\u6216\u201cndarray\u201d\u65f6\uff0c\u90fd\u8868\u793a\u540c\u4e00\u4e2a\u5bf9\u8c61\uff1andarray\u5bf9\u8c61\u3002 \u770b\u4e0b\u9762\u7684\u4f8b\u5b50\uff1a data01 \u662f\u4e00\u4e2a\u5217\u8868\uff08list\uff09\u7c7b\u578b\uff0c\u901a\u8fc7 Numpy.array \u8f6c\u6362\u6210Numpy\u7684 ndarray \u7c7b\u578b\u3002 \u5728 np.array \u4e2d\uff0c\u9664\u975e\u663e\u5f0f\u5730\u6307\u5b9a\uff0c\u5982 np.array(data01, dtype=np.int8) \uff0c\u5426\u5219np.array\u4f1a\u81ea\u52a8\u63a8\u65ad\u751f\u6210\u6570\u7ec4\u7684\u6570\u636e\u7c7b\u578b array01.dtype \u3002 \u4f7f\u7528 astype() \u65b9\u6cd5\u663e\u5f0f\u5730\u8f6c\u6362\u6570\u7ec4\u7684\u6570\u636e\u7c7b\u578b\u3002\u4f7f\u7528 astype() \u65f6\u603b\u662f\u751f\u6210\u4e00\u4e2a*\u65b0\u7684\u6570\u7ec4*\uff0c\u5373\u4f7f\u4f60\u4f20\u5165\u7684dtype\u4e0e\u4e4b\u524d\u4e00\u6837\u3002 data02 \u662f\u4e00\u4e2a\u5d4c\u5957\u5217\u8868 [[1, 2, 3, 4], [5, 6, 7, 8]] \uff0c\u901a\u8fc7np.array()\u65b9\u6cd5\u8f6c\u6362\u6210\u591a\u7ef4\u6570\u7ec4\uff0c\u524d\u63d0\u662f\u6bcf\u4e2a\u5b50\u5217\u8868\u7684\u957f\u5ea6\u8981\u4e00\u81f4\u3002 data01 = [6, 7.5, 8, 0, 1] print(data01) # [6, 7.5, 8, 0, 1] print(type(data01)) # array01 = np.array(data01) print(\"\u77e9\u9635\u7c7b\u578b\", type(array01)) # \u77e9\u9635\u7c7b\u578b print(\"\u6837\u672c\u77e9\u9635\", array01) # \u6837\u672c\u77e9\u9635 [6. 7.5 8. 0. 1. ] print(\"\u6570\u7ec4\u7ef4\u5ea6\", array01.ndim) # \u6570\u7ec4\u7ef4\u5ea6 1 print(\"\u77e9\u9635\u5f62\u72b6\", array01.shape) # \u77e9\u9635\u5f62\u72b6 (5,) \u4e00\u884c\u4e94\u5217 print(\"\u77e9\u9635\u6570\u636e\u7c7b\u578b\", array01.dtype) # float64 data02 = [[1, 2, 3, 4], [5, 6, 7, 8]] array02 = np.array(data02) print(\"\u6837\u672c\u77e9\u9635\\n\", array02) # \u6837\u672c\u77e9\u9635 # [[1 2 3 4] # [5 6 7 8]] print(\"\u6570\u7ec4\u7ef4\u5ea6\", array02.ndim) # \u6570\u7ec4\u7ef4\u5ea6 2 print(\"\u77e9\u9635\u5f62\u72b6\", array02.shape) # \u77e9\u9635\u5f62\u72b6 (2, 4) print(\"\u77e9\u9635\u6570\u636e\u7c7b\u578b\", array02.dtype) # \u77e9\u9635\u6570\u636e\u7c7b\u578b int64 print(\"\u77e9\u96350\u8f74\u5411\u6c42\u548c\", array02.sum(axis=0)) # \u77e9\u96350\u8f74\u5411\u6c42\u548c [ 6 8 10 12] print(\"\u77e9\u96351\u8f74\u5411\u6c42\u548c\", array02.sum(axis=1)) # \u77e9\u96351\u8f74\u5411\u6c42\u548c [10 26] array03 = array02.astype(np.float64) print(array03.dtype) # float64 print(array03) # [[1. 2. 3. 4.] # [5. 6. 7. 8.]] zeros() \u65b9\u6cd5\u53ef\u4ee5\u4e00\u6b21\u6027\u521b\u9020\u51680\u6570\u7ec4\u3002 print(np.zeros(10)) # [0. 0. 0. 0. 0. 0. 0. 0. 0. 0.] ones() \u65b9\u6cd5\u53ef\u4ee5\u4e00\u6b21\u6027\u521b\u9020\u51681\u6570\u7ec4\u3002\u6ce8\u610f\uff0c\u4f20\u53c2shape\u662f\u4e00\u4e2a\u5143\u7ec4 (3, 5) \u3002 print(np.ones((3, 5))) # [[1. 1. 1. 1. 1.] # [1. 1. 1. 1. 1.] # [1. 1. 1. 1. 1.]] empty() \u65b9\u6cd5\u53ef\u4ee5\u521b\u5efa\u4e00\u4e2a\u6ca1\u6709\u521d\u59cb\u5316\u6570\u503c\u7684\u6570\u7ec4\u3002\u4f46\u662f\uff0c\u4f7f\u7528np.empty\u6765\u751f\u6210\u4e00\u4e2a\u51680\u6570\u7ec4\uff0c\u5e76\u4e0d\u53ef\u9760\uff0c\u6709\u4e9b\u65f6\u5019\u5b83\u53ef\u80fd\u4f1a\u8fd4\u56de\u672a\u521d\u59cb\u5316\u7684\u5783\u573e\u6570\u503c print(np.empty((2, 3, 2))) # [[[2.30116964e-316 0.00000000e+000] # [2.10077583e-312 6.79038654e-313] # [2.22809558e-312 2.14321575e-312]] # # [[2.35541533e-312 6.79038654e-313] # [2.22809558e-312 2.14321575e-312] # [2.46151512e-312 2.41907520e-312]]]","title":"ndarray: N-\u7ef4\u6570\u7ec4\u5bf9\u8c61"},{"location":"python/DataAnalysis/ch01/#numpy_1","text":"\u4e00\u53e5\u8bdd\u603b\u7ed3\uff1a\u5c06NumPy\u8f74\u89c6\u4e3a\u6211\u4eec\u53ef\u4ee5\u6267\u884c\u64cd\u4f5c\u7684\u65b9\u5411\u3002 \u770b\u4e0b\u9762\u7684\u4f8b\u5b50\uff1a arr_1 = np.array([[1, 1, 1], [1, 1, 1]]) arr_2 = np.array([[9, 9, 9], [9, 9, 9]]) print(arr_1) # [[1 1 1] # [1 1 1]] print(arr_2) # [[9 9 9] # [9 9 9]] \u6cbf0\u8f74\u5408\u5e76\u7684\u601d\u8def\u662f\uff0c\u4e24\u4e2a\u6570\u7ec4\u6cbf0\u8f74\u65b9\u5411\uff0c\u54110\u8f74\u201c\u584c\u7f29\u201d\uff08collapse\uff09\u3002 result = np.concatenate([arr_1, arr_2], axis=0) print(result) # [[1 1 1] # [1 1 1] # [9 9 9] # [9 9 9]] \u6cbf1\u8f74\u5408\u5e76\u7684\u601d\u8def\u662f\uff0c\u4e24\u4e2a\u6570\u7ec4\u6cbf1\u8f74\u65b9\u5411\uff0c\u54111\u8f74\u201c\u584c\u7f29\u201d result = np.concatenate([arr_1, arr_2], axis=1) print(result) # [[1 1 1 9 9 9] # [1 1 1 9 9 9]] \u6211\u4eec\u6765\u770bNumPy\u7684\u4e09\u7ef4\u6570\u7ec4\u3002 array1 = np.arange(36).reshape((3, 3, 4)) print(array1) # [[[ 0 1 2 3] # [ 4 5 6 7] # [ 8 9 10 11]] # # [[12 13 14 15] # [16 17 18 19] # [20 21 22 23]] # # [[24 25 26 27] # [28 29 30 31] # [32 33 34 35]]] \u8fd9\u6837\u770b\u4f1a\u5bb9\u6613\u7406\u89e3\u4e00\u4e9b\uff0c0\u8f74\u67093\u884c\uff0c1\u8f74\u67093\u5217\uff0c2\u8f74\u67094\u4e2a\u5143\u7d20\uff1a [[[ 0 1 2 3], [ 4 5 6 7], [ 8 9 10 11]] [[12 13 14 15], [16 17 18 19], [20 21 22 23]] [[24 25 26 27], [28 29 30 31], [32 33 34 35]]] \u8f93\u51fa\uff1a\u8f740\u7d22\u5f15\u53f7\uff1a0\uff1b\u8f741\u7d22\u5f15\u53f7\uff1a0\uff1b\u8f742\u7d22\u5f15\u53f7\uff1a\u5168\u90e8 print(array1[0, 0, :]) # [0 1 2 3] \u8f93\u51fa\uff1a\u8f740\u7d22\u5f15\u53f7\uff1a0\uff1b\u8f741\u7d22\u5f15\u53f7\uff1a0\uff1b\u8f742\u7d22\u5f15\u53f7\uff1a1 print(array1[0, 0, 1]) # 1","title":"NumPy\u8f74"},{"location":"python/DataAnalysis/ch01/#numpy_2","text":"\u4e00\u4e2a**\u6807\u91cf**\u5c31\u662f\u4e00\u4e2a\u5355\u72ec\u7684\u6570\u3002\u4e00\u4e2a\u5411\u91cf\u5c31\u662f\u4e00\u5217\u6570\uff0c\u8fd9\u4e9b\u6570\u662f\u6709\u5e8f\u6392\u5217\u7684\u3002 \u77e9\u9635\u662f\u4e8c\u7ef4\u6570\u7ec4\uff0c\u5176\u4e2d\u7684\u6bcf\u4e00\u4e2a\u5143\u7d20\u88ab\u4e24\u4e2a\u7d22\u5f15\u800c\u975e\u4e00\u4e2a\u6240\u786e\u5b9a\u3002 \u51e0\u4f55\u4ee3\u6570\u4e2d\u5b9a\u4e49\u7684**\u5f20\u91cf**\u662f\u57fa\u4e8e\u5411\u91cf\u548c\u77e9\u9635\u7684\u63a8\u5e7f\uff0c\u6211\u4eec\u53ef\u4ee5**\u5c06\u6807\u91cf\u89c6\u4e3a\u96f6\u9636\u5f20\u91cf**\uff0c \u77e2\u91cf**\u89c6\u4e3a\u4e00\u9636\u5f20\u91cf\uff0c\u90a3\u4e48**\u77e9\u9635\u5c31\u662f\u4e8c\u9636\u5f20\u91cf \u3002 \u5e26\u6709\u6807\u91cf\u8ba1\u7b97\u7684\u7b97\u672f\u64cd\u4f5c\uff0c\u4f1a\u628a\u8ba1\u7b97\u53c2\u6570\u4f20\u9012\u7ed9\u6570\u7ec4\u7684\u6bcf\u4e00\u4e2a\u5143\u7d20\u3002 \u540c\u5c3a\u5bf8\u6570\u7ec4\u4e4b\u95f4\u7684\u6bd4\u8f83 array04 == array04 \uff0c\u4f1a\u4ea7\u751f\u4e00\u4e2a\u5e03\u5c14\u503c\u6570\u7ec4 \u4e0d\u540c\u5c3a\u5bf8\u7684\u6570\u7ec4\u95f4\u7684\u64cd\u4f5c\uff0c\u5c06\u4f1a\u7528\u5230 \u5e7f\u64ad\u7279\u6027\uff08broadcasting\uff09 \u3002 array04 = np.array([ [1, 2, 3, 4, 5], [3, 4, 5, 6, 7], [5, 6, 7, 8, 9] ], dtype=int) print(array04 + array04) # [[ 2 4 6 8 10] # [ 6 8 10 12 14] # [10 12 14 16 18]] print(array04 - array04) # [[0 0 0 0 0] # [0 0 0 0 0] # [0 0 0 0 0]] print(array04 * array04) # [[ 1 4 9 16 25] # [ 9 16 25 36 49] # [25 36 49 64 81]] print(array04 / array04) # [[1. 1. 1. 1. 1.] # [1. 1. 1. 1. 1.] # [1. 1. 1. 1. 1.]] print(1 / array04) # [[1. 0.5 0.33333333 0.25 0.2 ] # [0.33333333 0.25 0.2 0.16666667 0.14285714] # [0.2 0.16666667 0.14285714 0.125 0.11111111]] print(array04 == array04) # [[ True True True True True] # [ True True True True True] # [ True True True True True]]","title":"NumPy\u6570\u7ec4\u7b97\u672f"},{"location":"python/DataAnalysis/ch01/#_2","text":"ndarray\u5bf9\u8c61\u7684\u5185\u5bb9\u53ef\u4ee5\u901a\u8fc7\u7d22\u5f15\uff08indexing\uff09\u6216\u5207\u7247\uff08slicing\uff09\u6765\u8bbf\u95ee\u548c\u4fee\u6539\uff0cndarray\u5bf9\u8c61\u4e2d\u7684\u5143\u7d20\u7d22\u5f15\u4ece\u96f6\u5f00\u59cb\u3002 \u6709\u4e09\u79cd\u53ef\u7528\u7684\u7d22\u5f15\u65b9\u6cd5\uff1a\u5b57\u6bb5\u8bbf\u95ee\uff0c\u57fa\u672c\u5207\u7247\u548c\u9ad8\u7ea7\u7d22\u5f15\u3002 \u7d22\u5f15\uff08indexing\uff09\uff1a\u83b7\u53d6\u6570\u7ec4\u4e2d\u7279\u5b9a\u4f4d\u7f6e\u5143\u7d20\u7684\u8fc7\u7a0b\u3002 \u5207\u7247\uff08slicing\uff09\uff1a\u83b7\u53d6\u6570\u7ec4\u5143\u7d20\u5b50\u96c6\u7684\u8fc7\u7a0b\u3002\u6570\u7ec4\u7684\u5207\u7247\u662f\u539f\u6570\u7ec4\u7684\u89c6\u56fe\u3002\u8fd9\u610f\u5473\u7740\u4efb\u4f55**\u5bf9\u4e8e\u89c6\u56fe\u7684\u4fee\u6539\u90fd\u4f1a\u53cd\u6620\u5230\u539f\u6570\u7ec4\u4e0a**\u3002\u6570\u7ec4\u7684\u5207\u7247, \u8fd4\u56de\u7684\u5bf9\u8c61\u662f\u964d\u4f4e\u4e00\u4e2a\u7ef4\u5ea6\u7684\u6570\u7ec4\u3002 \u4e00\u7ef4\u6570\u7ec4\u7684\u7d22\u5f15\u548c\u5207\u7247\uff1a\u4e0ePython\u7684\u5217\u8868\u7c7b\u4f3c\uff1a a[n] \uff1a\u8fd4\u56de\u7b2c n+1 \u4e2a\u5143\u7d20\u3002\u5982\u679c n \u4e3a\u8d1f\u6570\uff0c\u5219\u8fd4\u56de\u5012\u6570\u7b2c n \u4e2a\u5143\u7d20\u3002 a[n:m:k] \uff1a\u8d77\u59cb\u7f16\u53f7 n \uff0c\u7ec8\u6b62\u7f16\u53f7 m \uff0c\u6b65\u957f k \uff0c\u7528\u5192\u53f7\u5206\u5272\u3002 \u9075\u5faa\u5de6\u95ed\u53f3\u5f00\u7684\u539f\u5219 \uff0c\u5373 [n, m) \u3002\u5982\u679c n \u4e3a\u7a7a\uff0c\u5373 n = 0 \uff1b\u5982\u679c m \u4e3a\u7a7a\uff0c\u5373 m = len(a) \u3002 \u591a\u7ef4\u6570\u7ec4\u7684\u7d22\u5f15\u548c\u5207\u7247\uff1a a[n,m,k,...] \uff1a\u6bcf\u4e2a\u7ef4\u5ea6\u4e00\u4e2a\u7d22\u5f15\u503c\uff0c\u6700\u5916\u5c42\u5217\u8868\uff08list\uff09\u4e2d\u7b2c n \u4e2a\u5143\u7d20\uff0c\u6b21\u5916\u5c42\u5217\u8868\uff08list\uff09\u4e2d\u7b2c m \u4e2a\u5143\u7d20\uff0c\u4ee5\u6b64\u7c7b\u63a8\u3002\u5982\u679c n \u4e3a\u8d1f\u6570\uff0c\u5219\u8fd4\u56de\u5012\u6570\u7b2c n \u4e2a\u5143\u7d20\u3002 a[n1:m1:k1,n2:m2:k2,n3:m3:k3,...] \uff1a\u6bcf\u4e2a\u7ef4\u5ea6\u7684\u5207\u7247\u65b9\u6cd5\u4e0e\u4e00\u7ef4\u6570\u7ec4\u76f8\u540c\u3002\u987a\u5e8f\u4e3a\u4ece\u5916\u5230\u5185\u3002 array05 = np.arange(10) print(array05) # [0 1 2 3 4 5 6 7 8 9] # \u4ece\u7d22\u5f15\u503c5\u5f00\u59cb\u5230\u7d22\u5f15\u503c7\u7684\u4e00\u4e2a\u5207\u7247\u3002 print(array05[5:8]) # [5 6 7] array06 = array05[5:8] # \u4f20\u5165\u4e00\u4e2a\u6570\u503c\u7ed9\u6570\u7ec4\u7684\u5207\u7247\uff0c\u6570\u503c\u88ab\u4f20\u9012\u7ed9\u4e86\u6574\u4e2a\u5207\u7247\u3002\u4e0d\u5199\u5207\u7247\u503c\u7684[:]\u5c06\u4f1a\u5f15\u7528\u6570\u7ec4\u7684\u6240\u6709\u503c array06[:] = 12 print(array06) # [12 12 12] # \u5207\u7247\u7684\u4fee\u6539\u4f1a\u53cd\u6620\u5230\u539f\u6570\u7ec4\u4e0a print(array05) # [ 0 1 2 3 4 12 12 12 8 9] # \u8f93\u51fa3\u7ef4\u77e9\u9635\uff0c3\u884c3\u5217\uff0c\u51719\u4e2a\u5143\u7d20\uff0c\u6bcf\u4e2a\u5143\u7d20\u662f\u4e00\u4e2a\u542b3\u4e2a\u5143\u7d20\u7684\u5217\u8868 array07 = np.array([ [[0, 1, 2], [3, 4, 5], [6, 7, 8]], [[9, 0, 1], [2, 3, 4], [5, 6, 7]], [[8, 9, 0], [1, 2, 3], [4, 5, 6]], ]) # \u8f93\u51fa3\u7ef4\u77e9\u9635\uff0c\u663e\u793a\u539f\u77e9\u9635\u7684\u7b2c1\uff0c2\u884c\u76842\uff0c3\u5217\u5143\u7d20\uff0c\u4e0d\u8981\u628a\u7d22\u5f15\u53f7\u548c\u8fd9\u91cc\u7684\u8868\u8ff0\u884c\u53f7\u6df7\u6dc6\u3002 print(array07[:2, 1:]) # [[[3 4 5] [6 7 8]] # [[2 3 4] [5 6 7]]] print(array07[:2, 1:].shape) # (2, 2, 3) # \u964d\u7ef4\uff0c\u8f93\u51fa\u539f\u77e9\u9635\u7684\u7b2c3\u884c print(array07[2]) # [[8 9 0] [1 2 3] [4 5 6]] print(array07[2].shape) # (3, 3) # \u964d\u7ef4\uff0c\u8f93\u51fa\u539f\u77e9\u9635\u7684\u7b2c3\u884c print(array07[2, :]) # [[8 9 0] [1 2 3] [4 5 6]] print(array07[2, :].shape) # (3, 3) # \u964d\u7ef4\uff0c\u8f93\u51fa\u539f\u77e9\u9635\u7684\u7b2c3\u884c\uff08\u53ea\u6709\u4e09\u884c\uff0c\u6240\u4ee5[2:, :]\u7b49\u540c\u4e8e[2, :]\uff09 print(array07[2:, :]) # [[[8 9 0] [1 2 3] [4 5 6]]] print(array07[2:, :].shape) # (1, 3, 3) # \u8f93\u51fa\u539f\u77e9\u9635\u76841\uff0c2\u5217 print(array07[:, :2]) # [[[0 1 2] [3 4 5]] # [[9 0 1] [2 3 4]] # [[8 9 0] [1 2 3]]] print(array07[:, :2].shape) # (3, 2, 3) # \u964d\u7ef4\uff0c\u8f93\u51fa\u539f\u77e9\u9635\u7684\u7b2c2\u884c\u524d2\u4e2a\u5143\u7d20 print(array07[1, :2]) # [[9 0 1] [2 3 4]] print(array07[1, :2].shape) # (2, 3) # \u8f93\u51fa\u539f\u77e9\u9635\u7684\u7b2c2\u884c\u524d2\u4e2a\u5143\u7d20 print(array07[1:2, :2]) # [[[9 0 1] [2 3 4]]] print(array07[1:2, :2].shape) # (1, 2, 3) # \u5c06\u539f\u77e9\u9635\u7684\u7b2c2\u884c\u8d4b\u503c\u7ed9\u53d8\u91cf old_value = array07[2].copy() print(old_value) # [[8 9 0] [1 2 3] [4 5 6]] # \u4fee\u6539\u539f\u77e9\u9635\u7684\u7b2c2\u884c\u7684\u503c\uff0c\u6807\u91cf\u548c\u6570\u7ec4\u90fd\u53ef\u4ee5\u4f20\u9012\u7ed9 array07[2] array07[2] = 25 print(array07) # [[[ 0 1 2] [ 3 4 5] [ 6 7 8]] # [[ 9 0 1] [ 2 3 4] [ 5 6 7]] # [[25 25 25] [25 25 25] [25 25 25]]] # \u5c06\u53d8\u91cf\u503c\u8d4b\u503c\u7ed9\u539f\u77e9\u9635\u7684\u7b2c2\u884c array07[2] = old_value print(array07) # [[[0 1 2] [3 4 5] [6 7 8]] # [[9 0 1] [2 3 4] [5 6 7]] # [[8 9 0] [1 2 3] [4 5 6]]]","title":"\u57fa\u7840\u7d22\u5f15\u4e0e\u5207\u7247"},{"location":"python/DataAnalysis/ch01/#_3","text":"\u5e03\u5c14\u503c\u7d22\u5f15\uff08Boolean indexing\uff09\u662f\u901a\u8fc7\u4e00\u4e2a\u5e03\u5c14\u6570\u7ec4\u6765\u7d22\u5f15\u76ee\u6807\u6570\u7ec4\uff0c\u4ee5\u6b64\u627e\u51fa\u4e0e\u5e03\u5c14\u6570\u7ec4\u4e2d\u503c\u4e3aTrue\u7684\u5bf9\u5e94\u7684\u76ee\u6807\u6570\u7ec4\u4e2d\u7684\u6570\u636e\u3002\u5e03\u5c14\u6570\u7ec4\u7684\u957f\u5ea6\u5fc5\u987b\u4e0e\u76ee\u6807\u6570\u7ec4\u5bf9\u5e94\u7684\u8f74\u7684\u957f\u5ea6\u4e00\u81f4\u3002 \u4f7f\u7528\u5e03\u5c14\u503c\u7d22\u5f15\uff08Boolean indexing\uff09\u9009\u62e9\u6570\u636e\u65f6\uff0c\u603b\u662f\u751f\u6210\u6570\u636e\u7684\u62f7\u8d1d\uff0c\u5373\u4f7f\u8fd4\u56de\u7684\u6570\u7ec4\u5e76\u6ca1\u6709\u4efb\u4f55\u53d8\u5316\u3002 \u5047\u8bbe\u6211\u4eec\u7684\u6570\u636e\u90fd\u5728\u6570\u7ec4\u4e2d\uff0c\u5e76\u4e14\u6570\u7ec4\u4e2d\u7684\u6570\u636e\u662f\u4e00\u4e9b\u5b58\u5728\u91cd\u590d\u7684\u4eba\u540d\u3002\u7528randn\u51fd\u6570\u751f\u6210\u4e00\u4e9b\u6807\u51c6\u6b63\u6001(standard normal)\u5206\u5e03\u7684\u6570\u636e\u3002\u5047\u8bbe\u6bcf\u4e2a\u4eba\u540d\u90fd\u548cdata\u6570\u7ec4\u4e2d\u7684\u4e00\u884c\u76f8\u5bf9\u5e94\uff0c\u5e76\u4e14\u6211\u4eec\u60f3\u8981\u9009\u4e2d\u6240\u6709\u2019Bob\u2019\u5bf9\u5e94\u7684\u884c\u3002 names = np.array(['Bob', 'Joe', 'Will', 'Bob', 'Will', 'Joe', 'Joe'], dtype=' # \u56fe\u50cf\u6807\u9898 plt.title(\"$\\sqrt{x^2 + y^2}$ \u8ba1\u7b97\u503c\u7684\u7f51\u683c\u56fe\") # \u8f93\u51fa\u56fe\u50cf plt.show() \u8f93\u51fa\u56fe\u50cf\u4e3a\uff1a","title":"\u9762\u5411\u6570\u7ec4\u7f16\u7a0b"},{"location":"python/DataAnalysis/ch01/#_8","text":"numpy.where \u51fd\u6570\u662f\u4e09\u5143\u8868\u8fbe\u5f0f x if condition else y \u7684\u5411\u91cf\u5316\u7248\u672c\u3002 np.where \u7684\u7b2c\u4e8c\u4e2a\u548c\u7b2c\u4e09\u4e2a\u53c2\u6570\u5e76\u4e0d\u9700\u8981\u662f\u6570\u7ec4\uff0c\u5b83\u4eec\u53ef\u4ee5\u662f\u6807\u91cf\u3002 np.where \u5728\u6570\u636e\u5206\u6790\u4e2d\u7684\u4e00\u4e2a\u5178\u578b\u7528\u6cd5\u662f\u6839\u636e\u4e00\u4e2a\u6570\u7ec4\u6765\u751f\u6210\u4e00\u4e2a\u65b0\u7684\u6570\u7ec4\u3002 \u5047\u8bbe\u6211\u4eec\u6709\u4e00\u4e2a\u5e03\u5c14\u503c\u6570\u7ec4\u548c\u4e24\u4e2a\u6570\u503c\u6570\u7ec4\u3002\u5047\u8bbe cond \u4e2d\u7684\u5143\u7d20\u4e3a True \u65f6\uff0c\u6211\u4eec\u53d6 xarr \u4e2d\u7684\u5bf9\u5e94\u5143\u7d20\u503c\uff0c\u5426\u5219\u53d6 yarr \u4e2d\u7684\u5143\u7d20\u3002 xarray = np.array([1.1, 1.2, 1.3, 1.4, 1.5]) yarray = np.array([2.1, 2.2, 2.3, 2.4, 2.5]) cond = np.array([True, False, True, True, False]) \u901a\u8fc7\u5217\u8868\u63a8\u5bfc\u5f0f\u6765\u5b9e\u73b0\u4e0a\u8ff0\u9700\u6c42\u3002 \u7f3a\u70b9: \u9996\u5148\uff0c\u5982\u679c\u6570\u7ec4\u5f88\u5927\u7684\u8bdd\uff0c\u901f\u5ea6\u4f1a\u5f88\u6162\uff08\u56e0\u4e3a\u6240\u6709\u7684\u5de5\u4f5c\u90fd\u662f\u901a\u8fc7\u89e3\u91ca\u5668\u6765\u89e3\u91caPython\u4ee3\u7801\u5b8c\u6210\uff09\u3002 \u5176\u6b21\uff0c\u5f53\u6570\u7ec4\u662f\u591a\u7ef4\u65f6\uff0c\u5c31\u65e0\u6cd5\u51d1\u6548\u4e86\u3002 # \u901a\u8fc7\u5217\u8868\u63a8\u5bfc\u5f0f\u6765\u5b9e\u73b0 result = [(x if c else y) for x, y, c in zip(xarray, yarray, cond)] print(result) # [1.1, 2.2, 1.3, 1.4, 2.5] \u901a\u8fc7 np.where \u6765\u5b9e\u73b0\u4e0a\u8ff0\u9700\u6c42\u3002 result = np.where(cond, xarray, yarray) print(result) # [1.1 2.2 1.3 1.4 2.5] \u5047\u8bbe\u6709\u4e00\u4e2a\u968f\u673a\u751f\u6210\u7684\u77e9\u9635\u6570\u636e\uff0c\u4e0b\u9762\u4f7f\u7528np.where\u5b9e\u73b0\u66ff\u6362\u3002 array = np.random.randn(4, 4) print(\"\u6837\u672c\u77e9\u9635 \\n\", array) print(\"\u77e9\u9635\u5143\u7d20\u662f\u5426\u5927\u4e8e0 \\n\", array > 0) # \u5c06\u5176\u4e2d\u7684\u6b63\u503c\u90fd\u66ff\u6362\u4e3a2\uff0c\u5c06\u6240\u6709\u7684\u8d1f\u503c\u66ff\u6362\u4e3a-2 result03 = np.where(array > 0, 2, -2) print(\"\u5c06\u5176\u4e2d\u7684\u6b63\u503c\u90fd\u66ff\u6362\u4e3a2\uff0c\u5c06\u6240\u6709\u7684\u8d1f\u503c\u66ff\u6362\u4e3a-2 \\n\", result03) # \u4ec5\u5c06\u5176\u4e2d\u7684\u6b63\u503c\u90fd\u66ff\u6362\u4e3a2 result04 = np.where(array > 0, 2, array) print(\"\u4ec5\u5c06\u5176\u4e2d\u7684\u6b63\u503c\u90fd\u66ff\u6362\u4e3a2 \\n\", result04) # \u6837\u672c\u77e9\u9635 # [[-0.57177422 -0.34917512 2.20268075 1.99959296] # [ 0.67966599 2.67915099 -0.40528454 -0.80339907] # [-0.74406888 2.33802717 -0.74582936 0.59347128] # [ 0.68624473 0.65953112 -0.40871415 -0.68698878]] # \u77e9\u9635\u5143\u7d20\u662f\u5426\u5927\u4e8e0 # [[False False True True] # [ True True False False] # [False True False True] # [ True True False False]] # \u5c06\u5176\u4e2d\u7684\u6b63\u503c\u90fd\u66ff\u6362\u4e3a2\uff0c\u5c06\u6240\u6709\u7684\u8d1f\u503c\u66ff\u6362\u4e3a-2 # [[-2 -2 2 2] # [ 2 2 -2 -2] # [-2 2 -2 2] # [ 2 2 -2 -2]] # \u4ec5\u5c06\u5176\u4e2d\u7684\u6b63\u503c\u90fd\u66ff\u6362\u4e3a2 # [[-0.57177422 -0.34917512 2. 2. ] # [ 2. 2. -0.40528454 -0.80339907] # [-0.74406888 2. -0.74582936 2. ] # [ 2. 2. -0.40871415 -0.68698878]]","title":"\u901a\u8fc7\u6761\u4ef6\u903b\u8f91\u64cd\u4f5c\u6570\u7ec4"},{"location":"python/DataAnalysis/ch01/#_9","text":"NumPy\u6709\u4e00\u4e9b\u4e13\u95e8\u7684\u6570\u5b66\u51fd\u6570\uff0c\u7528\u6765\u8ba1\u7b97\u6574\u4e2a\u6570\u7ec4\u7edf\u8ba1\u503c\u6216\u8f74\u5411\u6570\u636e\u7684\u8ba1\u7b97\u3002\u4f8b\u5982\uff0c\u805a\u5408\u51fd\u6570\uff08\u901a\u5e38\u4e5f\u53eb\u7f29\u51cf\u51fd\u6570\uff09\uff0c\u5982sum\u3001mean\u548cstd\uff08\u6807\u51c6\u5dee\uff09\u3002 \u65e2\u53ef\u4ee5\u76f4\u63a5\u8c03\u7528\u6570\u7ec4\u5b9e\u4f8b\u7684\u65b9\u6cd5\uff0c\u4e5f\u53ef\u4ee5\u4f7f\u7528\u9876\u5c42\u7684NumPy\u51fd\u6570\u3002 \u4e3e\u4f8b\uff1a\u751f\u6210\u4e00\u4e9b\u6b63\u6001\u5206\u5e03\u7684\u968f\u673a\u6570\uff0c\u8ba1\u7b97\u90e8\u5206\u805a\u5408\u7edf\u8ba1\u6570\u636e\u3002 \u8fd9\u91cc\u518d\u5bf9\u8f74\u5411\u505a\u4e2a\u89e3\u91ca\uff0c np.random.randn(5, 4) \u4ea7\u751f\u7684\u4e8c\u7ef4\u6570\u7ec4\u662f\uff1a0\u8f74\u54115\u4e2a\u5143\u7d20, 1\u8f74\u54114\u4e2a\u5143\u7d20\u3002 # \u751f\u62102\u8f74\u6570\u7ec4 array = np.random.randn(5, 4) print(\"\u6837\u672c\u77e9\u9635 \\n\", array) print(\"\u77e9\u9635\u5143\u7d20\u5e73\u5747\u503c\", array.mean()) print(\"\u77e9\u9635\u5143\u7d20\u5e73\u5747\u503c\", np.mean(array)) print(\"\u77e9\u9635\u5143\u7d20\u548c\", array.sum()) print(\"\u77e9\u9635\u5143\u7d20\u548c\", np.sum(array)) print(\"0\u8f74\u5411\u7684\u7d2f\u548c\", array.sum(axis=0)) print(\"1\u8f74\u5411\u7684\u7d2f\u548c\", array.sum(axis=1)) print(\"1\u8f74\u5411\u7684\u5e73\u5747\u503c\", array.mean(axis=1)) # \u6837\u672c\u77e9\u9635 shape=(5, 4) 0\u8f74\u54115\u4e2a\u5143\u7d20, 1\u8f74\u54114\u4e2a\u5143\u7d20 # [[ 0.32532911 -0.00177984 -1.59432632 1.58375133] # [ 1.48921763 0.25202456 0.44076148 -1.02277289] # [-0.73490219 0.19197171 -0.22374362 0.52610852] # [-1.03531076 1.0595528 -0.11566501 0.34063544] # [-0.2122241 -0.81348187 1.70989712 -0.00732696]] # \u77e9\u9635\u5143\u7d20\u5e73\u5747\u503c 0.10788580775057008 # \u77e9\u9635\u5143\u7d20\u5e73\u5747\u503c 0.10788580775057008 # \u77e9\u9635\u5143\u7d20\u548c 2.1577161550114017 # \u77e9\u9635\u5143\u7d20\u548c 2.1577161550114017 # 0\u8f74\u5411\u7684\u7d2f\u548c [-0.16789031 0.68828737 0.21692365 1.42039545] # 1\u8f74\u5411\u7684\u7d2f\u548c [ 0.31297429 1.15923078 -0.24056558 0.24921247 0.67686419] # 1\u8f74\u5411\u7684\u5e73\u5747\u503c [ 0.07824357 0.28980769 -0.06014139 0.06230312 0.16921605] \u4e0b\u9762\u5217\u4e3e\u4e86\u5e38\u7528\u7684\u57fa\u7840\u6570\u7ec4\u7edf\u8ba1\u65b9\u6cd5\u3002 array = np.array([ [1, 2, 3, 4, 5], [3, 4, 5, 6, 7], [5, 6, 7, 8, 9] ], dtype=int) print(\"\u6837\u672c\u77e9\u9635 \\n\", array) print(\"\u8f74\u5411\u6c42\u548c\", array.sum()) print(\"\u8f74\u5411\u6c42\u548c\", array.sum(axis=0)) print(\"\u6570\u5b66\u5e73\u5747\", array.mean()) print(\"\u8f74\u5411\u6570\u5b66\u5e73\u5747\", array.mean(axis=0)) print(\"\u6807\u51c6\u5dee\", array.std(), \"\u65b9\u5dee\", array.var()) print(\"\u8f74\u5411\u6807\u51c6\u5dee\", array.std(axis=0), \"\u8f74\u5411\u65b9\u5dee\", array.var(axis=0)) print(\"\u6700\u5c0f\u503c\", array.min(), \"\u6700\u5927\u503c\", array.max()) print(\"\u8f74\u5411\u6700\u5c0f\u503c\", array.min(axis=0), \"\u8f74\u5411\u6700\u5927\u503c\", array.max(axis=0)) print(\"\u6700\u5c0f\u503c\u4f4d\u7f6e\", array.argmin(), \"\u6700\u5927\u503c\u4f4d\u7f6e\", array.argmax()) print(\"\u8f74\u5411\u6700\u5c0f\u503c\u4f4d\u7f6e\", array.argmin(axis=0), \"\u8f74\u5411\u6700\u5927\u503c\u4f4d\u7f6e\", array.argmax(axis=0)) print(\"\u7d2f\u79ef\u548c \\n\", array.cumsum()) print(\"\u8f74\u5411\u7d2f\u79ef\u548c \\n\", array.cumsum(axis=1)) print(\"\u7d2f\u79ef\u4e58\u79ef \\n\", array.cumprod()) print(\"\u8f74\u5411\u7d2f\u79ef\u4e58\u79ef \\n\", array.cumprod(axis=1)) # \u6837\u672c\u77e9\u9635 # [[1 2 3 4 5] # [3 4 5 6 7] # [5 6 7 8 9]] # \u8f74\u5411\u6c42\u548c 75 # \u8f74\u5411\u6c42\u548c [ 9 12 15 18 21] # \u6570\u5b66\u5e73\u5747 5.0 # \u8f74\u5411\u6570\u5b66\u5e73\u5747 [3. 4. 5. 6. 7.] # \u6807\u51c6\u5dee 2.160246899469287 \u65b9\u5dee 4.666666666666667 # \u8f74\u5411\u6807\u51c6\u5dee [1.63299316 1.63299316 1.63299316 1.63299316 1.63299316] \u8f74\u5411\u65b9\u5dee [2.66666667 2.66666667 2.66666667 2.66666667 2.66666667] # \u6700\u5c0f\u503c 1 \u6700\u5927\u503c 9 # \u8f74\u5411\u6700\u5c0f\u503c [1 2 3 4 5] \u8f74\u5411\u6700\u5927\u503c [5 6 7 8 9] # \u6700\u5c0f\u503c\u4f4d\u7f6e 0 \u6700\u5927\u503c\u4f4d\u7f6e 14 # \u8f74\u5411\u6700\u5c0f\u503c\u4f4d\u7f6e [0 0 0 0 0] \u8f74\u5411\u6700\u5927\u503c\u4f4d\u7f6e [2 2 2 2 2] # \u7d2f\u79ef\u548c # [ 1 3 6 10 15 18 22 27 33 40 45 51 58 66 75] # \u8f74\u5411\u7d2f\u79ef\u548c # [[ 1 3 6 10 15] # [ 3 7 12 18 25] # [ 5 11 18 26 35]] # \u7d2f\u79ef\u4e58\u79ef # [ 1 2 6 24 120 360 # 1440 7200 43200 302400 1512000 9072000 # 63504000 508032000 4572288000] # \u8f74\u5411\u7d2f\u79ef\u4e58\u79ef # [[ 1 2 6 24 120] # [ 3 12 60 360 2520] # [ 5 30 210 1680 15120]]","title":"\u6570\u5b66\u548c\u7edf\u8ba1\u65b9\u6cd5"},{"location":"python/DataAnalysis/ch01/#boolean-array","text":"\u5e03\u5c14\u503c\u6570\u7ec4\uff0c\u6709\u4e24\u4e2a\u975e\u5e38\u6709\u7528\u7684\u65b9\u6cd5any\u548call\u3002 * any\u68c0\u67e5\u6570\u7ec4\u4e2d\u662f\u5426\u81f3\u5c11\u6709\u4e00\u4e2aTrue\uff0c * all\u68c0\u67e5\u662f\u5426\u6bcf\u4e2a\u503c\u90fd\u662fTrue bools = np.array([False, False, True, False]) print(bools.any()) # True print(bools.all()) # False \u4e0b\u9762\u662f\u4e00\u4e2a\u8fd0\u7528\u5e03\u5c14\u503c\u6570\u7ec4\uff08Boolean Array\uff09\u8fdb\u884c\u6c42\u548c\u7684\u4e00\u4e2a\u4f8b\u5b50\uff0c\u5176\u4e2d (array > 0) \u672c\u8eab\u662f\u4e00\u4e2a\u5e03\u5c14\u578b\u7684\u6570\u7ec4\u3002 array = np.random.randn(100) result = (array > 0).sum() # \u8ba1\u7b97\u6b63\u503c\u7684\u4e2a\u6570 print(result) # 59 \u4e0b\u9762\u662f\u8fd0\u7528\u5e03\u5c14\u503c\u6570\u7ec4\u7684\u751f\u6210\u65b0\u6570\u7ec4\u7684\u4f8b\u5b50\u3002 arr = [[8, 9, 10, 11], [0, 1, 2, 3], [4, 5, 6, 7]] arr = np.array(arr) print(arr.shape) # (3, 4) print(arr) # [[ 8 9 10 11] # [ 0 1 2 3] # [ 4 5 6 7]] idx = [[1, 0, 0, 0], [0, 1, 0, 0], [0, 0, 1, 0]] idx = np.array(idx) print(idx.shape) # (3, 4) print(idx) # [[1 0 0 0] # [0 1 0 0] # [0 0 1 0]] result = arr[idx] # print(result.shape) # (3, 4, 4) print(result) # [[[ 0 1 2 3] # [ 8 9 10 11] # [ 8 9 10 11] # [ 8 9 10 11]] # [[ 8 9 10 11] # [ 0 1 2 3] # [ 8 9 10 11] # [ 8 9 10 11]] # [[ 8 9 10 11] # [ 8 9 10 11] # [ 0 1 2 3] # [ 8 9 10 11]]] result = arr[idx == 1] print(result.shape) print(result) # [8 1 6]","title":"\u5e03\u5c14\u503c\u6570\u7ec4(Boolean Array)\u7684\u65b9\u6cd5"},{"location":"python/DataAnalysis/ch01/#_10","text":"\u548cPython\u7684\u5185\u5efa\u5217\u8868\u7c7b\u578b\u76f8\u4f3c\uff0cNumPy\u6570\u7ec4\u53ef\u4ee5\u4f7f\u7528sort\u65b9\u6cd5\u6309\u4f4d\u7f6e\u6392\u5e8f\u3002 \u9876\u5c42\u7684np.sort\u65b9\u6cd5\u8fd4\u56de\u7684\u662f\u5df2\u7ecf\u6392\u5e8f\u597d\u7684\u6570\u7ec4*\u62f7\u8d1d*\uff0c\u800c\u4e0d\u662f\u5bf9\u539f\u6570\u7ec4\u6309\u4f4d\u7f6e\u6392\u5e8f\u3002 array = np.random.randn(6) print(\"\u6837\u672c\u77e9\u9635\", array) array.sort() print(\"\u6392\u5e8f\u540e\u77e9\u9635\", array) # \u6837\u672c\u77e9\u9635 [-0.03119521 0.01839556 0.79238537 -2.46622775 0.62522211 0.22430846] # \u6392\u5e8f\u540e\u77e9\u9635 [-2.46622775 -0.03119521 0.01839556 0.22430846 0.62522211 0.79238537] \u591a\u7ef4\u6570\u7ec4\u4e2d\u6839\u636e\u4f20\u9012\u7684axis\u503c\uff0c\u6cbf\u7740\u8f74\u5411\u5bf9\u6bcf\u4e2a\u4e00\u7ef4\u6570\u636e\u6bb5\u8fdb\u884c\u6392\u5e8f\u3002 array = np.random.randn(5, 3) print(\"\u6837\u672c\u77e9\u9635 \\n\", array) array.sort(1) print(\"\u5bf91\u8f74\u6392\u5e8f\u540e\u77e9\u9635 \\n\", array) # \u6837\u672c\u77e9\u9635 # [[-0.88057833 0.30160954 -2.08788148] # [ 0.27969618 0.62923028 -0.58157581] # [-1.87194465 -1.1102104 1.09589605] # [ 0.1467938 -1.01558304 -0.25905165] # [-0.17294279 0.62369511 0.17947059]] # \u5bf91\u8f74\u6392\u5e8f\u540e\u77e9\u9635 # [[-2.08788148 -0.88057833 0.30160954] # [-0.58157581 0.27969618 0.62923028] # [-1.87194465 -1.1102104 1.09589605] # [-1.01558304 -0.25905165 0.1467938 ] # [-0.17294279 0.17947059 0.62369511]]","title":"\u6392\u5e8f"},{"location":"python/DataAnalysis/ch01/#_11","text":"NumPy\u5305\u542b\u4e00\u4e9b\u9488\u5bf9\u4e00\u7ef4 ndarray \u6570\u7ec4\u7684\u57fa\u7840\u96c6\u5408\u64cd\u4f5c\u3002 np.unique(x, y) \u8ba1\u7b97x\u7684\u552f\u4e00\u503c\uff0c\u5e76\u6392\u5e8f\u3002 names = np.array(['Bob', 'Joe', 'Will', 'Bob', 'Will', 'Joe', 'Joe']) result = np.unique(names) # NumPy\u5b9e\u73b0 print(result) # ['Bob' 'Joe' 'Will'] result = sorted(set(names)) # \u7eafPython\u5b9e\u73b0 print(result) # ['Bob' 'Joe' 'Will'] inits = np.array([3, 3, 3, 2, 2, 1, 1, 5, 5]) result = np.unique(inits) print(result) # [1 2 3 5] np.in1d(x, y) \u8ba1\u7b97x\u4e2d\u7684\u5143\u7d20\u662f\u5426\u5305\u542b\u5728y\u4e2d\uff0c\u5e76\u8fd4\u56de\u4e00\u4e2a\u5e03\u5c14\u503c\u6570\u7ec4\u3002 inits = np.array([3, 3, 3, 2, 2, 1, 1, 5, 5]) print(np.in1d(inits, [3, 4, 5])) # [ True True True False False False False True True] np.intersect1d(x, y) \uff0c\u8ba1\u7b97x\u548cy\u7684\u4ea4\u96c6\uff0c\u5e76\u6392\u5e8f\u3002 inits = np.array([3, 3, 3, 2, 2, 1, 1, 5, 5]) print(np.intersect1d(inits, [3, 4, 5])) # [3 5] np.union1d(x, y) \u8ba1\u7b97x\u548cy\u7684\u5e76\u96c6\uff0c\u5e76\u6392\u5e8f\u3002 inits = np.array([3, 3, 3, 2, 2, 1, 1, 5, 5]) print(np.union1d(inits, [3, 4, 5])) # [1 2 3 4 5] np.setdiff1d(x, y) \u5dee\u96c6\uff0c\u5728x\u4e2d\u4f46\u4e0d\u5728y\u4e2d\u7684\u5143\u7d20\u3002 inits = np.array([3, 3, 3, 2, 2, 1, 1, 5, 5]) print(np.setdiff1d(inits, [3, 4, 5])) # [1 2] np.setxor1d(x, y) \u5f02\u6216\u96c6\uff0c\u5728x\u6216\u8005y\u4e2d\uff0c\u4f46\u4e0d\u5c5e\u4e8ex\uff0cy\u4ea4\u96c6\u7684\u5143\u7d20\u3002 inits = np.array([3, 3, 3, 2, 2, 1, 1, 5, 5]) print(np.setxor1d(inits, [3, 4, 5])) # [1 2 4]","title":"\u552f\u4e00\u503c\u4e0e\u5176\u4ed6\u96c6\u5408\u903b\u8f91"},{"location":"python/DataAnalysis/ch01/#_12","text":"NumPy\u53ef\u4ee5\u5728\u786c\u76d8\u4e2d\u5c06\u6570\u636e\u4ee5\u6587\u672c\u6216\u4e8c\u8fdb\u5236\u6587\u4ef6\u7684\u5f62\u5f0f\u8fdb\u884c\u5b58\u5165\u786c\u76d8\u6216\u7531\u786c\u76d8\u8f7d\u5165\u3002 \u5f53\u524d\u53ea\u5173\u6ce8NumPy\u7684\u5185\u5efa\u4e8c\u8fdb\u5236\u683c\u5f0f\uff0c\u56e0\u4e3a\u5927\u90e8\u5206\u7528\u6237\u66f4\u503e\u5411\u4e8e\u4f7f\u7528pandas\u6216\u5176\u4ed6\u5de5\u5177\u6765\u8f7d\u5165\u6587\u672c\u6216\u8868\u683c\u578b\u6570\u636e\u3002 np.save \u548c np.load \u662f\u9ad8\u6548\u5b58\u53d6\u786c\u76d8\u6570\u636e\u7684\u4e24\u5927\u5de5\u5177\u51fd\u6570\u3002\u6570\u7ec4\u5728\u9ed8\u8ba4\u60c5\u51b5\u4e0b\u662f\u4ee5*\u672a\u538b\u7f29*\u7684\u683c\u5f0f\u8fdb\u884c\u5b58\u50a8\u7684\uff0c\u540e\u7f00\u540d\u662f.npy\u3002 import numpy as np array1 = np.arange(10) array2 = np.arange(15).reshape(3, 5) array3 = np.arange(30).reshape(3, 2, 5) print(array1) # [0 1 2 3 4 5 6 7 8 9] print(array2) # [[ 0 1 2 3 4] # [ 5 6 7 8 9] # [10 11 12 13 14]] print(array3) # [[[ 0 1 2 3 4] # [ 5 6 7 8 9]] # [[10 11 12 13 14] # [15 16 17 18 19]] # [[20 21 22 23 24] # [25 26 27 28 29]]] # \u67e5\u770b\u5f53\u524d\u8def\u5f84 os.getcwd() # '/opt/myProject/mySite' # \u66f4\u6539\u9ed8\u8ba4\u8def\u5f84 os.chdir('/opt/myProject/mySite/docs/python/datasets/examples') # \u4fdd\u5b58\u5230\u9ed8\u8ba4\u8def\u5f84\u3002npy\u540e\u7f00\u540d\u4f1a\u88ab\u81ea\u52a8\u52a0\u4e0a np.save('some_array', array1) # \u8bfb\u53d6\u6240\u4fdd\u5b58\u7684\u6587\u4ef6 result = np.load('some_array.npy') # \u5bf9\u6bd4\u7ed3\u679c\u4e00\u81f4\u3002 print(result) # [0 1 2 3 4 5 6 7 8 9] # \u5c06\u591a\u4e2a\u6570\u7ec4\u4fdd\u5b58\u5230\u672a\u538b\u7f29\u7684\u5355\u4e2a\u6587\u4ef6\u4e2d\uff0c.npz\u683c\u5f0f np.savez('some_array_archive.npz', a=array2, b=array3) result = np.load('some_array_archive.npz') # reslt\u662f\u4e00\u4e2a\u5b57\u5178\u578b\u7684\u5bf9\u8c61 print(result['b']) # \u8f7d\u5165\u5355\u4e2a\u6570\u7ec4b # [[[ 0 1 2 3 4] # [ 5 6 7 8 9]] # [[10 11 12 13 14] # [15 16 17 18 19]] # [[20 21 22 23 24] # [25 26 27 28 29]]]","title":"\u4f7f\u7528\u6570\u7ec4\u8fdb\u884c\u6587\u4ef6\u8f93\u5165\u548c\u8f93\u51fa"},{"location":"python/DataAnalysis/ch01/#_13","text":"\u53c2\u8003\u94fe\u63a5\uff1a https://www.numpy.org.cn/reference/routines/linalg.html https://github.com/teadocs/numpy-cn \u5e0c\u814a\u5b57\u6bcd: \u0391 \u03b1 /'\u00e6lf\u0259/ alpha \u0392 \u03b2 /'bi:t\u0259/ beta \u0393 \u03b3 /'g\u00e6m\u0259/ gamma \u0394 \u03b4 /'delt\u0259/ delta \u0395 \u03b5 /'eps\u026al\u0252n/ epsilon \u0396 \u03b6 /'zi:t\u0259/ zeta \u0397 \u03b7 /'i:t\u0259/ eta \u0398 \u03b8 /'\u03b8i:t\u0259/ theta \u0399 \u03b9 /'a\u026a\u0259\u028at\u0259/ iota \u039a \u03ba /'k\u00e6p\u0259/ kappa \u2227 \u03bb /'l\u00e6md\u0259/ lambda \u039c \u03bc /mju:/ mu \u039d \u03bd /nju:/ nu \u039e \u03be /ksi/ xi \u039f \u03bf /\u0259u\u02c8maikr\u0259n/ omicron \u220f \u03c0 /pa\u026a/ pi \u03a1 \u03c1 /r\u0259\u028a/ rho \u2211 \u03c3 /'s\u026a\u0261m\u0259/ sigma \u03a4 \u03c4 /t\u0254:/ tau \u03a5 \u03c5 /\u02c8ips\u026alon/ upsilon \u03a6 \u03c6 /fa\u026a/ phi \u03a7 \u03c7 /ka\u026a/ chi \u03a8 \u03c8 /psa\u026a/ psi \u03a9 \u03c9 /'\u0259\u028am\u026a\u0261\u0259/ omega numpy.linalg \u6a21\u5757\u5305\u542b\u7ebf\u6027\u4ee3\u6570\u7684\u51fd\u6570\u3002\u4f7f\u7528\u8fd9\u4e2a\u6a21\u5757\uff0c\u53ef\u4ee5\u8ba1\u7b97\u9006\u77e9\u9635\u3001\u6c42\u7279\u5f81\u503c\u3001\u89e3\u7ebf\u6027\u65b9\u7a0b\u7ec4\u4ee5\u53ca\u6c42\u89e3\u884c\u5217\u5f0f\u7b49\u3002 import numpy as np from numpy import linalg as LA from numpy import * from numpy.linalg import inv import matplotlib.pyplot as plt","title":"\u7ebf\u6027\u4ee3\u6570"},{"location":"python/DataAnalysis/ch01/#diag","text":"np.diag \u5c06\u4e00\u4e2a\u65b9\u9635\u7684\u5bf9\u89d2\uff08\u6216\u975e\u5bf9\u89d2\uff09\u5143\u7d20\u4f5c\u4e3a\u4e00\u7ef4\u6570\u7ec4\u8fd4\u56de\uff0c\u6216\u8005\u5c06\u4e00\u7ef4\u6570\u7ec4\u8f6c\u6362\u6210\u4e00\u4e2a\u65b9\u9635\uff0c\u5e76\u4e14\u5728\u975e\u5bf9\u89d2\u7ebf\u4e0a\u6709\u96f6\u70b9\u3002 a1 = np.arange(9, dtype=float).reshape((3, 3)) r1 = np.diag(a1) r2 = np.diag(a1, k=1) r3 = np.diag(a1, k=-1) r4 = np.diag(np.diag(a1)) # \u5bf9\u89d2\u77e9\u9635 print(\"\u6837\u672c\u77e9\u9635 \\n\", a1) print(\"\u77e9\u9635\u5bf9\u89d2\u7ebf\", r1) print(\"\u77e9\u9635\u5bf9\u89d2\u7ebf\u5411\u4e0a\u504f\u79fb\", r2) print(\"\u77e9\u9635\u5bf9\u89d2\u7ebf\u5411\u4e0b\u504f\u79fb\", r3) print(\"\u5bf9\u89d2\u77e9\u9635 \\n\", r4) # \u6837\u672c\u77e9\u9635 # [[0. 1. 2.] # [3. 4. 5.] # [6. 7. 8.]] # \u77e9\u9635\u5bf9\u89d2\u7ebf [0. 4. 8.] # \u77e9\u9635\u5bf9\u89d2\u7ebf\u5411\u4e0a\u504f\u79fb [1. 5.] # \u77e9\u9635\u5bf9\u89d2\u7ebf\u5411\u4e0b\u504f\u79fb [3. 7.] # \u5bf9\u89d2\u77e9\u9635 # [[0. 0. 0.] # [0. 4. 0.] # [0. 0. 8.]]","title":"diag"},{"location":"python/DataAnalysis/ch01/#dot","text":"np.dot \u5c06\u5411\u91cf\u4e2d\u5bf9\u5e94\u5143\u7d20\u76f8\u4e58\uff0c\u518d\u76f8\u52a0\u6240\u5f97\u3002\u5373\u666e\u901a\u7684\u5411\u91cf\u4e58\u6cd5\u8fd0\u7b97\uff0c\u6216**\u77e9\u9635\u70b9\u4e58**\u3002 a1 = np.dot(3, 4) print(a1) # 12 a2 = np.arange(9, dtype=float).reshape((3, 3)) r2 = np.dot(a2, a2) print(a2) # [[0. 1. 2.] # [3. 4. 5.] # [6. 7. 8.]] print(r2) # [[ 15. 18. 21.] # [ 42. 54. 66.] # [ 69. 90. 111.]] r3 = np.dot([2j, 3j], [2j, 3j]) print(r3) # (-13+0j)","title":"dot"},{"location":"python/DataAnalysis/ch01/#trace","text":"np.trace \u8ba1\u7b97\u5bf9\u89d2\u5143\u7d20\u548c\u3002 a1 = np.arange(9, dtype=float).reshape((3, 3)) print(\"\u6837\u672c\u77e9\u9635 \\n\", a1) r1 = np.trace(a1) print(\"\u5bf9\u89d2\u7ebf\u5143\u7d20\u6c42\u548c\", r1) a2 = np.arange(24, dtype=float).reshape((2, 3, 4)) r2 = np.trace(a2) print(\"\u6837\u672c\u77e9\u9635 \\n\", a2) print(\"\u5bf9\u89d2\u7ebf\u5143\u7d20\u6c42\u548c\", r2) # \u6837\u672c\u77e9\u9635 # [[0. 1. 2.] # [3. 4. 5.] # [6. 7. 8.]] # \u5bf9\u89d2\u7ebf\u5143\u7d20\u6c42\u548c 12.0 # \u6837\u672c\u77e9\u9635 # [[[ 0. 1. 2. 3.] # [ 4. 5. 6. 7.] # [ 8. 9. 10. 11.]] # # [[12. 13. 14. 15.] # [16. 17. 18. 19.] # [20. 21. 22. 23.]]] # \u5bf9\u89d2\u7ebf\u5143\u7d20\u6c42\u548c [16. 18. 20. 22.]","title":"trace"},{"location":"python/DataAnalysis/ch01/#det","text":"np.det \u8ba1\u7b97\u77e9\u9635\u7684\u884c\u5217\u5f0f\uff08\u65b9\u9635\uff09\u3002 \u4e8c\u9636\u884c\u5217\u5f0f[[a, b], [c, d]]\u7684\u503c\u662fad - bc \u4e09\u9636\u884c\u5217\u5f0f [[a, b, c], [d, e, f], [g, h, i]]\u7684\u503c\u662f aei + bfd + cdh - ceg - bdi - afh \u4e09\u9636\u884c\u5217\u5f0f\u7684\u6027\u8d28 \u6027\u8d281\uff1a\u884c\u5217\u5f0f\u4e0e\u5b83\u7684\u8f6c\u7f6e\u884c\u5217\u5f0f\u76f8\u7b49\u3002 \u6027\u8d282\uff1a\u4e92\u6362\u884c\u5217\u5f0f\u7684\u4e24\u884c(\u5217)\uff0c\u884c\u5217\u5f0f\u53d8\u53f7\u3002 \u63a8\u8bba\uff1a\u5982\u679c\u884c\u5217\u5f0f\u6709\u4e24\u884c(\u5217)\u5b8c\u5168\u76f8\u540c\uff0c\u5219\u6b64\u884c\u5217\u5f0f\u4e3a\u96f6\u3002 \u6027\u8d283\uff1a\u884c\u5217\u5f0f\u7684\u67d0\u4e00\u884c(\u5217)\u4e2d\u6240\u6709\u7684\u5143\u7d20\u90fd\u4e58\u4ee5\u540c\u4e00\u6570k\uff0c\u7b49\u4e8e\u7528\u6570k\u4e58\u6b64\u884c\u5217\u5f0f\u3002 \u63a8\u8bba\uff1a\u884c\u5217\u5f0f\u4e2d\u67d0\u4e00\u884c(\u5217)\u7684\u6240\u6709\u5143\u7d20\u7684\u516c\u56e0\u5b50\u53ef\u4ee5\u63d0\u5230\u884c\u5217\u5f0f\u7b26\u53f7\u7684\u5916\u9762\u3002 \u6027\u8d284\uff1a\u884c\u5217\u5f0f\u4e2d\u5982\u679c\u6709\u4e24\u884c(\u5217)\u5143\u7d20\u6210\u6bd4\u4f8b\uff0c\u5219\u6b64\u884c\u5217\u5f0f\u7b49\u4e8e\u96f6\u3002 \u6027\u8d285\uff1a\u628a\u884c\u5217\u5f0f\u7684\u67d0\u4e00\u5217(\u884c)\u7684\u5404\u5143\u7d20\u4e58\u4ee5\u540c\u4e00\u6570\u7136\u540e\u52a0\u5230\u53e6\u4e00\u5217(\u884c)\u5bf9\u5e94\u7684\u5143\u7d20\u4e0a\u53bb\uff0c\u884c\u5217\u5f0f\u4e0d\u53d8\u3002 a1 = np.array([[1, 2], [3, 4]]) r1 = np.linalg.det(a1) print(\"\u4e8c\u9636\u65b9\u9635 \\n\", a1) print(\"\u4e8c\u9636\u884c\u5217\u5f0f\u7684\u503c\", r1) # \u4e8c\u9636\u65b9\u9635 # [[1 2] # [3 4]] # \u4e8c\u9636\u884c\u5217\u5f0f\u7684\u503c -2.0000000000000004 # \u5e0c\u814a\u5b57\u6bcd # \u03b1, \u03b2, \u03b3,\u03b4, \u03b5, \u03b6, \u03b7, \u03b8, \u03b9, \u03ba, \u03bb, \u03bc, \u03bd, # \u03be, \u03bf, \u03c0, \u03c1, \u03c2, \u03c3, \u03c4, \u03c5, \u03c6, \u03c7, \u03c8, \u03c9, a2 = np.arange(9).reshape(3, 3) r2 = np.linalg.det(a2) print(\"\u4e09\u9636\u65b9\u9635 \\n\", a2) print(\"\u4e09\u9636\u884c\u5217\u5f0f\u7684\u503c\", r2) # \u4e09\u9636\u65b9\u9635 # [[0 1 2] # [3 4 5] # [6 7 8]] # \u4e09\u9636\u884c\u5217\u5f0f\u7684\u503c 0.0 a3 = np.arange(16).reshape(4, 4) r3 = np.linalg.det(a3) print(\"\u56db\u9636\u65b9\u9635 \\n\", a3) print(\"\u56db\u9636\u884c\u5217\u5f0f\u7684\u503c\", r3) # \u56db\u9636\u65b9\u9635 # [[ 0 1 2 3] # [ 4 5 6 7] # [ 8 9 10 11]# \u5e0c\u814a\u5b57\u6bcd # \u03b1, \u03b2, \u03b3,\u03b4, \u03b5, \u03b6, \u03b7, \u03b8, \u03b9, \u03ba, \u03bb, \u03bc, \u03bd, # \u03be, \u03bf, \u03c0, \u03c1, \u03c2, \u03c3, \u03c4, \u03c5, \u03c6, \u03c7, \u03c8, \u03c9, # [12 13 14 15]] # \u56db\u9636\u884c\u5217\u5f0f\u7684\u503c 0.0","title":"det"},{"location":"python/DataAnalysis/ch01/#eig","text":"np.eig \u8ba1\u7b97\u65b9\u9635\u7684\u7279\u5f81\u503c\u548c\u7279\u5f81\u5411\u91cf\u3002 \u7279\u5f81\u503c\u4e0e\u7279\u5f81\u5411\u91cf\u7684\u5b9a\u4e49\uff1a\u8bbeA\u662fn\u9636\u65b9\u9635\uff0c\u82e5\u6570\u03bb\u548cn\u7ef4\u975e\u96f6\u5217\u5411\u91cfx\uff0c\u4f7f\u5f97Ax = \u03bbx\u6210\u7acb\uff0c\u5219\u79f0\u03bb\u662f\u65b9\u9635A\u7684\u4e00\u4e2a\u7279\u5f81\u503c\uff0cx\u4e3a\u65b9\u9635A\u7684\u5bf9\u5e94\u4e8e\u7279\u5f81\u503c\u03bb\u7684\u4e00\u4e2a\u7279\u5f81\u5411\u91cf\u3002 A\u662f\u65b9\u9635\u3002\uff08\u5bf9\u4e8e\u975e\u65b9\u9635\uff0c\u662f\u6ca1\u6709\u7279\u5f81\u503c\u7684\uff0c\u4f46\u4f1a\u6709\u6761\u4ef6\u6570\u3002\uff09\u7279\u5f81\u5411\u91cfx\u4e3a\u975e\u96f6\u5217\u5411\u91cf\u3002 v_eigenvectors, v_eigenvalues = LA.eig(np.diag((1, 2, 3))) print(\"\u7279\u5f81\u5411\u91cf\", v_eigenvectors) print(\"\u7279\u5f81\u503c \\n\", v_eigenvalues) # \u7279\u5f81\u5411\u91cf [1. 2. 3.] # \u7279\u5f81\u503c # [[1. 0. 0.] # [0. 1. 0.] # [0. 0. 1.]] v_eigenvectors, v_eigenvalues = LA.eig(np.array([[1, -1], [1, 1]])) print(\"\u7279\u5f81\u5411\u91cf\", v_eigenvectors) print(\"\u7279\u5f81\u503c \\n\", v_eigenvalues) # \u7279\u5f81\u5411\u91cf [1.+1.j 1.-1.j] # \u7279\u5f81\u503c # [[0.70710678+0.j 0.70710678-0.j ] # [0. -0.70710678j 0. +0.70710678j]]","title":"eig"},{"location":"python/DataAnalysis/ch01/#inv","text":"np.inv \u8ba1\u7b97\u65b9\u9635\u7684\u9006\u77e9\u9635\u3002 a1 = np.array([[1, 2], [3, 4]]) r1 = inv(a1) r2 = inv(np.matrix(a1)) print(\"\u539f\u77e9\u9635 \\n\", a1) print(\"\u9006\u77e9\u9635 \\n\", r1) print(\"\u9006\u77e9\u9635 \\n\", r2) # \u539f\u77e9\u9635 # [[1 2] # [3 4]] # \u9006\u77e9\u9635 # [[-2. 1. ] # [ 1.5 -0.5]] # \u9006\u77e9\u9635 # [[-2. 1. ] # [ 1.5 -0.5]]","title":"inv"},{"location":"python/DataAnalysis/ch01/#pinv","text":"np.pinv \u8ba1\u7b97\u77e9\u9635\u7684Moore-Penrose\u4f2a\u9006(\u6469\u5c14\uff0d\u5f6d\u82e5\u65af\u5e7f\u4e49\u9006)\u3002 \u4e0b\u9762\u7684\u4f8b\u5b50\u68c0\u9a8c a * a+ * a == a \u548c a+ * a * a+ == a+ a = np.random.randn(9, 6) B = np.linalg.pinv(a) r1 = np.allclose(a, np.dot(a, np.dot(B, a))) r2 = np.allclose(B, np.dot(B, np.dot(a, B))) print(a) print(B) print(r1) # True print(r2) # True # a: # [[-2.30316101 -0.63217332 1.24134743 -0.72492307 0.12456801 -0.14192548] # [ 1.37573495 0.07626697 -0.71870843 1.26824984 -0.79485727 -0.24630455] # [ 0.29003175 -1.23931665 -0.50864107 -0.31140718 0.45467649 -2.44973999] # [-0.70748664 -1.2995059 0.85126149 -1.10918804 -2.10042342 0.75942293] # [ 1.91765238 1.23892103 1.58516486 -1.65520154 0.11894439 0.84536298] # [ 1.03220791 0.1715148 0.85595408 0.58569706 1.34066384 -1.5782386 ] # [-0.54432889 -0.0114189 1.55403934 0.89852512 1.15586365 -0.30733805] # [-0.80874673 0.14602121 1.04680044 1.98722514 0.39766383 0.75178788] # [ 0.01664663 0.06243353 -0.50725334 -0.37707204 -1.76701091 -0.33866559]] # B: # [[-0.25055838 0.13963115 0.08990923 0.16280282 0.12997291 0.05088469 -0.01541299 -0.01656133 -0.21731387] # [ 0.22862622 -0.05108109 -0.2639602 -0.47835978 0.11776862 0.09324694 0.00436756 -0.00609393 0.61995597] # [ 0.10422554 0.03985857 0.00198025 0.15139023 0.17165026 0.15697725 0.17360246 0.13150089 0.08378135] # [-0.07021378 0.17665487 -0.04109252 0.0015022 -0.11998477 0.0543575 0.08649033 0.21190785 0.04065729] # [-0.08110336 -0.15274536 0.05601496 -0.07967802 -0.02454705 -0.04152356 0.00071268 -0.05981012 -0.43996066] # [-0.17998537 -0.03160871 -0.12587707 0.16856246 0.00565094 -0.21038026 -0.06060039 0.04322126 -0.42038066]]","title":"pinv"},{"location":"python/DataAnalysis/ch01/#qr","text":"np.qr \u8ba1\u7b97QR\u5206\u89e3\u3002QR\uff08\u6b63\u4ea4\u4e09\u89d2\uff09\u5206\u89e3\u6cd5\u662f\u6c42\u4e00\u822c\u77e9\u9635\u5168\u90e8\u7279\u5f81\u503c\u7684\u6700\u6709\u6548\u5e76\u5e7f\u6cdb\u5e94\u7528\u7684\u65b9\u6cd5\u3002 \u4e00\u822c\u77e9\u9635\u5148\u7ecf\u8fc7\u6b63\u4ea4\u76f8\u4f3c\u53d8\u5316\u6210\u4e3aHessenberg\u77e9\u9635\uff0c\u7136\u540e\u518d\u5e94\u7528QR\u65b9\u6cd5\u6c42\u7279\u5f81\u503c\u548c\u7279\u5f81\u5411\u91cf\u3002QR\u5206\u89e3\u6cd5\u662f\u5c06\u77e9\u9635\u5206\u89e3\u6210\u4e00\u4e2a\u6b63\u89c4\u6b63\u4ea4\u77e9\u9635Q\u4e0e\u4e0a\u4e09\u89d2\u5f62\u77e9\u9635R\uff0c\u6240\u4ee5\u79f0\u4e3aQR\u5206\u89e3\u6cd5\u3002 a = np.arange(9).reshape(3, 3) q, r = np.linalg.qr(a) print(\"\u539f\u77e9\u9635 \\n\", a) print(\"\u6b63\u4ea4\u77e9\u9635 \\n\", q) print(\"\u4e0a\u4e09\u89d2\u77e9\u9635 \\n\", r) # \u539f\u77e9\u9635 # [[0 1 2] # [3 4 5] # [6 7 8]] # \u6b63\u4ea4\u77e9\u9635 # [[ 0. 0.91287093 0.40824829] # [-0.4472136 0.36514837 -0.81649658] # [-0.89442719 -0.18257419 0.40824829]] # \u4e0a\u4e09\u89d2\u77e9\u9635 # [[-6.70820393e+00 -8.04984472e+00 -9.39148551e+00] # [ 0.00000000e+00 1.09544512e+00 2.19089023e+00] # [ 0.00000000e+00 0.00000000e+00 -8.88178420e-16]]","title":"qr"},{"location":"python/DataAnalysis/ch01/#svd","text":"np.svd \u8ba1\u7b97\u5947\u5f02\u503c\u5206\u89e3\uff08SVD\uff09\u3002 \u51e0\u4f55\u610f\u4e49\uff1aSVD\u5206\u89e3\u7684\u51e0\u4f55\u610f\u4e49\u662f\u4efb\u4f55\u4e00\u4e2a\u77e9\u9635A\u5728\u4e00\u7cfb\u5217\u65cb\u8f6c\u548c\u5e73\u79fb\u4e0b\u90fd\u80fd\u8f6c\u5316\u6210\u4e00\u4e2a\u5bf9\u89d2\u77e9\u9635\u2211 , \u5176\u4e2d\u9149\u9635U, V\u7684\u51e0\u4f55\u610f\u4e49\u5c31\u662f\u4e00\u7cfb\u5217\u65cb\u8f6c\u548c\u5e73\u79fb\u7684\u53e0\u52a0\u3002 a = mat([[1, 2, 3],[4, 5, 6]]) U, sigma, V = np.linalg.svd(a) print(\"\u539f\u77e9\u9635 \\n\", a) print(\"\u5de6\u5947\u5f02\u503cU \\n\", U) print(\"\u5947\u5f02\u503cSigma \\n\", sigma) print(\"\u53f3\u5947\u5f02\u503cV \\n\", V) # \u539f\u77e9\u9635 # [[1 2 3] # [4 5 6]] # \u5de6\u5947\u5f02\u503cU # [[-0.3863177 -0.92236578] # [-0.92236578 0.3863177 ]] # \u5947\u5f02\u503cSigma # [9.508032 0.77286964] # \u53f3\u5947\u5f02\u503cV # [[-0.42866713 -0.56630692 -0.7039467 ] # [ 0.80596391 0.11238241 -0.58119908] # [ 0.40824829 -0.81649658 0.40824829]]","title":"svd"},{"location":"python/DataAnalysis/ch01/#solve","text":"np.solve \u6c42\u89e3x\u7684\u7ebf\u6027\u7cfb\u7edfAx = b\uff0c\u5176\u4e2dA\u662f\u65b9\u9635\u3002 \u89e3\u65b9\u7a0b\u7ec4\uff1a x + 2y = 1 3x + 5y = 2 a = np.array([[1, 2], [3, 5]]) b = np.array([1, 2]) x = np.linalg.solve(a, b) print(x) # [-1. 1.]","title":"solve"},{"location":"python/DataAnalysis/ch01/#lstsq","text":"np.lstsq \u8ba1\u7b97Ax = b\u7684\u6700\u5c0f\u4e8c\u4e58\u89e3\u3002 \u7528\u6700\u5c0f\u4e8c\u4e58\u6cd5\u62df\u5408\u6570\u636e\u5f97\u5230\u4e00\u4e2a\u5f62\u5982y = mx + c\u7684\u7ebf\u6027\u65b9\u7a0b\uff08Return the least-squares solution to a linear matrix equation\uff09\u3002 x = np.array([0, 1, 2, 3]) # \u539f\u59cb\u6570\u636e\u70b9\u7684\u6a2a\u5750\u6807 y = np.array([-1, 0.2, 0.9, 2.1]) # \u539f\u59cb\u6570\u636e\u70b9\u7684\u7eb5\u5750\u6807 print(x) # [0 1 2 3] print(y) # [-1. 0.2 0.9 2.1] A = np.vstack([x, np.ones(len(x))]).T # \u6784\u9020\u7cfb\u6570\u77e9\u9635 print(A) # [[0. 1.] # [1. 1.] # [2. 1.] # [3. 1.]] m, c = np.linalg.lstsq(A, y, rcond=None)[0] # \u89e3\u51fa\u659c\u7387a\u548c\u7eb5\u622a\u8dddc plt.plot(x, y, 'o', label='Original data', markersize=10) # \u505a\u51fa\u539f\u59cb\u6570\u636e\u6563\u70b9\u56fe plt.plot(x, m*x + c, 'r', label='Fitted line') # \u7528\u4e0a\u9762\u89e3\u51fa\u7684\u53c2\u6570\u505a\u51fa\u62df\u5408\u66f2\u7ebfy=mx+c plt.legend() plt.show()","title":"lstsq"},{"location":"python/DataAnalysis/ch01/#_14","text":"numpy.random \u6a21\u5757\u586b\u8865\u4e86Python\u5185\u5efa\u7684 random \u6a21\u5757\u7684\u4e0d\u8db3\uff0c\u53ef\u4ee5\u9ad8\u6548\u5730\u751f\u6210\u591a\u79cd\u6982\u7387\u5206\u5e03\u4e0b\u7684\u5b8c\u6574\u6837\u672c\u503c\u6570\u7ec4\u3002 numpy.random \u4e2d\u7684\u6570\u636e\u751f\u6210\u51fd\u6570\u516c\u7528\u4e86\u4e00\u4e2a\u5168\u5c40\u7684\u968f\u673a\u6570\u79cd\u5b50\u3002 \u4f7f\u7528 numpy.random.RandomState \u751f\u6210\u4e00\u4e2a\u968f\u673a\u6570\u751f\u6210\u5668\uff0c\u4f7f\u6570\u636e\u72ec\u7acb\u4e8e\u5176\u4ed6\u7684\u968f\u673a\u6570\u72b6\u6001\u3002 \u901a\u8fc7 np.random.seed \u66f4\u6539NumPy\u7684\u968f\u673a\u6570\u79cd\u5b50\u3002 numpy.random \u4e2d\u7684\u90e8\u5206\u51fd\u6570\u5217\u8868 seed: \u5411\u968f\u673a\u6570\u751f\u6210\u5668\u4f20\u9012\u968f\u673a\u72b6\u6001\u79cd\u5b50 permutation: \u8fd4\u56de\u4e00\u4e2a\u5e8f\u5217\u7684\u968f\u673a\u6392\u5217\uff0c\u6216\u8005\u8fd4\u56de\u4e00\u4e2a\u4e71\u5e8f\u7684\u6574\u6570\u8303\u56f4\u5e8f\u5217 shuffle: \u968f\u673a\u6392\u5217\u4e00\u4e2a\u5e8f\u5217 rand: \u4ece\u5747\u5300\u5206\u5e03\u4e2d\u62bd\u53d6\u6837\u672c randint: \u6839\u636e\u7ed9\u5b9a\u7684\u7531\u4f4e\u5230\u9ad8\u7684\u8303\u56f4\u62bd\u53d6\u968f\u673a\u6574\u6570 randn: \u4ece\u5747\u503c0\u65b9\u5dee1\u7684\u6b63\u6001\u5206\u5e03\u4e2d\u62bd\u53d6\u6837\u672c(MATLAB\u578b\u63a5\u53e3\uff09 binomial: \u4ece\u4e8c\u9879\u5206\u5e03\u4e2d\u62bd\u53d6\u6837\u672c normal: \u4ece\u6b63\u6001\uff08\u9ad8\u65af\uff09\u5206\u5e03\u4e2d\u62bd\u53d6\u6837\u672c beta\u4ecebeta: \u5206\u5e03\u4e2d\u62bd\u53d6\u6837\u672c chisquare: \u4ece\u5361\u65b9\u5206\u5e03\u4e2d\u62bd\u53d6\u6837\u672c \u4f8b\u5982\uff0c\u4f7f\u7528normal\u6765\u83b7\u5f97\u4e00\u4e2a4\u00d74\u7684\u6b63\u6001\u5206\u5e03\u6837\u672c\u6570\u7ec4\uff0c\u79f0\u4e3a\u4f2a\u968f\u673a\u6570\u3002 import numpy as np samples = np.random.normal(size=(4, 4)) print(samples) # [[ 0.78583658 -0.27462104 -0.53027675 -0.62675004] # [ 0.39054781 1.20503691 -0.0057432 0.17243182] # [-0.41516669 -0.93335854 0.01996088 -0.12707275] # [ 0.42952379 2.56998319 0.14848737 -0.42871493]]","title":"\u4f2a\u968f\u673a\u6570\u751f\u6210"},{"location":"python/DataAnalysis/ch01/#_15","text":"import matplotlib.pyplot as plt import numpy as np position = 0 walk = [position] nwalks = 5000 nsteps = 1000 draws = np.random.randint(0, 2, size=(nwalks, nsteps)) steps = np.where(draws > 0, 1, -1) walks = steps.cumsum() plt.plot(walks[:500000000000000000000000000]) plt.show() \u8f93\u51fa\u56fe\u50cf\uff1a","title":"\u793a\u4f8b\uff1a\u968f\u673a\u6f2b\u6b65"},{"location":"python/DataAnalysis/ch02/","text":"Pandas\u5165\u95e8 \u00b6 \u7ea6\u5b9a\uff1a import numpy as np import pandas as pd from pandas import Series, DataFrame import pandas_datareader as web pandas\u6570\u636e\u7ed3\u6784\u4ecb\u7ecd \u00b6 Series \u00b6 Series\u662f\u4e00\u79cd\u4e00\u7ef4\u7684\u6570\u7ec4\u578b\u5bf9\u8c61\uff0c\u5b83\u5305\u542b\u4e86\u4e00\u4e2a\u503c\u5e8f\u5217\uff08\u4e0eNumPy\u4e2d\u7684\u7c7b\u578b\u76f8\u4f3c\uff09\uff0c\u5e76\u4e14\u5305\u542b\u4e86\u6570\u636e\u6807\u7b7e\uff0c\u79f0\u4e3a**\u7d22\u5f15\uff08index\uff09 \u3002 \u4ece\u53e6\u4e00\u4e2a\u89d2\u5ea6\u8003\u8651Series\uff0c\u53ef\u4ee5\u8ba4\u4e3a\u5b83\u662f\u4e00\u4e2a**\u957f\u5ea6\u56fa\u5b9a\u4e14\u6709\u5e8f\u7684\u5b57\u5178 \uff0c\u56e0\u4e3a\u5b83\u5c06\u7d22\u5f15\u503c\u548c\u6570\u636e\u503c\u6309\u4f4d\u7f6e\u914d\u5bf9\u3002\u7d22\u5f15\u5728\u5de6\u8fb9\uff0c\u503c\u5728\u53f3\u8fb9\u3002 obj = pd.Series([4, 7, -5, 3]) print(obj) # 0 4 # 1 7 # 2 -5 # 3 3 # dtype: int64 print(obj.values) # [ 4 7 -5 3 print(obj.index) # RangeIndex(start=0, stop=4, step=1) \u81ea\u5b9a\u4e49index obj = pd.Series([4, 7, -5, 3], index=['d', 'b', 'a', 'c']) print(obj) # d 4 # b 7 # a -5 # c 3 # dtype: int64 print(obj.values) # [ 4 7 -5 3] print(obj.index) # Index(['d', 'b', 'a', 'c'], dtype='object') # \u8f93\u51fa\u7d22\u5f15\u503c\u4e3a'a'\u7684Series\u503c print(obj['a']) # -5 # \u4f7f\u7528\u5e03\u5c14\u503c\u6570\u7ec4\u8fdb\u884c\u8fc7\u6ee4Series\u503c print(obj[obj > 3]) # d 4 # b 7 # dtype: int64 # \u5bf9Series\u503c\u8fdb\u884c\u7b97\u672f\u8fd0\u7b97 print(obj * 2) # d 8 # b 14 # a -10 # c 6 # dtype: int64 # \u5bf9Series\u503c\u8fdb\u884c\u7b97\u672f\u8fd0\u7b97 print(np.exp(obj)) # d 54.598150 # b 1096.633158 # a 0.006738 # c 20.085537 # dtype: float64 # \u66f4\u65b0Series\u6570\u7ec4\u503c obj['a'] = 9 # \u8f93\u51fa\u6307\u5b9a\u7d22\u5f15\u503c\u7684Series\u503c\uff0c\u6ce8\u610f\uff0c\u7d22\u5f15\u6761\u4ef6\u662f\u5217\u8868 print(obj[['a', 'b', 'c']]) # a 9 # b 7 # c 3 # dtype: int64 # \u6ce8\u610f\uff0c\u4e0b\u9762\u7684\u5224\u65ad\u662f\u7d22\u5f15\u503c\uff0c\u975eSeries\u503c print(obj) print(7 in obj) # False print('a' in obj) # True \u901a\u8fc7\u5b57\u5178\u751f\u6210\u4e00\u4e2aSeries\u3002 NaN \uff08not a number\uff09\uff0c\u8fd9\u662fpandas\u4e2d\u6807\u8bb0\u7f3a\u5931\u503c\u6216NA\u503c\u7684\u65b9\u5f0f\u3002 \u5f53\u628a\u5b57\u5178\u4f20\u9012\u7ed9Series\u6784\u9020\u51fd\u6570\u65f6\uff0c\u4ea7\u751f\u7684Series\u7684\u7d22\u5f15\u5c06\u662f\u6392\u5e8f\u597d\u7684\u5b57\u5178\u952e\u3002\u53ef\u4ee5\u5c06\u5b57\u5178\u952e\u6309\u7167\u4f60\u6240\u60f3\u8981\u7684\u987a\u5e8f\u4f20\u9012\u7ed9\u6784\u9020\u51fd\u6570\uff0c\u4ece\u800c\u4f7f\u751f\u6210\u7684Series\u7684\u7d22\u5f15\u987a\u5e8f\u7b26\u5408\u9884\u671f\u3002 \u770b\u4e0b\u4f8b\uff0c\u901a\u8fc7\u5b57\u5178sdata\u751f\u6210Series\u3002 sdata = {'Ohio': 35000, 'Texas': 71000, 'Oregon': 16000, 'Utah': 5000} obj3 = pd.Series(sdata) print(sdata) # {'Ohio': 35000, 'Texas': 71000, 'Oregon': 16000, 'Utah': 5000} print(obj3) # Ohio 35000 # Texas 71000 # Oregon 16000 # Utah 5000 # dtype: int64 \u901a\u8fc7\u6307\u5b9a\u7d22\u5f15states\u53bb\u5339\u914d\u5b57\u5178sdata\u751f\u6210\u57fa\u4e8e\u65b0\u7d22\u5f15states\u7684Series\u3002 states = ['California', 'Ohio', 'Oregon', 'Texas'] obj4 = pd.Series(sdata, index=states) print(obj4) # California NaN # Ohio 35000.0 # Oregon 16000.0 # Texas 71000.0 # dtype: float64 \u5bf9Series\u8fdb\u884c\u5e03\u5c14\u503c\u5224\u65ad\u3002 print(pd.isnull(obj4)) # California True # Ohio False # Oregon False # Texas False # dtype: bool print(pd.notnull(obj4)) # California False # Ohio True # Oregon True # Texas True # dtype: bool \u5bf9Series\u8fdb\u884c\u5e03\u5c14\u503c\u5224\u65ad\u3002 print(obj4.isnull) # print(obj4.notnull) # Series\u7684\u81ea\u52a8\u5bf9\u9f50\u7d22\u5f15\uff0c\u4e0e\u6570\u636e\u5e93\u7684join\u64cd\u4f5c\u662f\u975e\u5e38\u76f8\u4f3c\u3002 print(\"obj3 \\n\", obj3) # obj3 # Ohio 35000 # Texas 71000 # Oregon 16000 # Utah 5000 # dtype: int64 print(\"obj4 \\n\", obj4) # obj4 # California NaN # Ohio 35000.0 # Oregon 16000.0 # Texas 71000.0 # dtype: float64 print(\"obj3+obj4 \\n\", obj3 + obj4) # obj3+obj4 # California NaN # Ohio 70000.0 # Oregon 32000.0 # Texas 142000.0 # Utah NaN # dtype: float64 # \u4e0b\u9762\u662fobj3\u548cobj4\u7684\u503c\uff0c\u5e2e\u52a9\u7406\u89e3\u4e0a\u9762obj3 + obj4\u7684\u64cd\u4f5c\u3002 # obj3 obj4 # Ohio 35000 California NaN # Texas 71000 Ohio 35000.0 # Oregon 16000 Oregon 16000.0 # Utah 5000 Texas 71000.0 # dtype: int64 dtype: float64 Series\u5bf9\u8c61\u81ea\u8eab\u548c\u5176\u7d22\u5f15\u90fd\u6709name\u5c5e\u6027\u3002 obj4.name = 'population' obj4.index.name = 'state' print(obj4) # state # California NaN # Ohio 35000.0 # Oregon 16000.0 # Texas 71000.0 # Name: population, dtype: float64 \u66ff\u6362Series\u7684\u7d22\u5f15\u540d\u3002 obj = pd.Series([4, 7, -5, 3], index=['d', 'b', 'a', 'c']) print(obj) obj.index = ['Bob', 'Steve', 'Jeff', 'Ryan'] print(obj) # Bob 4 # Steve 7 # Jeff -5 # Ryan 3 # dtype: int64 DataFrame \u00b6 DataFrame\u8868\u793a\u7684\u662f\u77e9\u9635\u7684\u6570\u636e\u8868\uff0c\u5b83\u5305\u542b\u5df2\u6392\u5e8f\u7684\u5217\u96c6\u5408\uff0c\u6bcf\u4e00\u5217\u53ef\u4ee5\u662f\u4e0d\u540c\u7684\u503c\u7c7b\u578b\uff08\u6570\u503c\u3001\u5b57\u7b26\u4e32\u3001\u5e03\u5c14\u503c\u7b49\uff09\u3002 DataFrame\u65e2\u6709\u884c\u7d22\u5f15\u4e5f\u6709\u5217\u7d22\u5f15\uff0c\u5b83\u53ef\u4ee5\u88ab\u89c6\u4e3a\u4e00\u4e2a\u5171\u4eab\u76f8\u540c\u7d22\u5f15\u7684Series\u7684\u5b57\u5178\uff0c\u6bd4\u5982\u6240\u6709\u5217\u5171\u4eab\u540c\u4e00\u4e2a\u5217\u7d22\u5f15\u3002 \u5728DataFrame\u4e2d\uff0c\u6570\u636e\u88ab\u5b58\u50a8\u4e3a\u4e00\u4e2a\u4ee5\u4e0a\u7684\u4e8c\u7ef4\u5757\uff0c\u800c\u4e0d\u662f\u5217\u8868\u3001\u5b57\u5178\u6216\u5176\u4ed6\u4e00\u7ef4\u6570\u7ec4\u7684\u96c6\u5408\u3002 DataFrame\u662f\u4e8c\u7ef4\u7684\uff0c\u4f46\u53ef\u4ee5\u5229\u7528**\u5206\u5c42\u7d22\u5f15**\u5728DataFrame\u4e2d\u5c55\u73b0\u66f4\u9ad8\u7ef4\u5ea6\u7684\u6570\u636e\u3002 \u4eceDataFrame\u4e2d\u9009\u53d6\u7684\u5217\u662f\u6570\u636e\u7684\u89c6\u56fe\uff0c\u800c\u4e0d\u662f\u62f7\u8d1d \u3002\u56e0\u6b64\uff0c\u5bf9Series\u7684\u4fee\u6539\u4f1a\u6620\u5c04\u5230DataFrame\u4e2d\u3002\u5982\u679c\u9700\u8981\u590d\u5236\uff0c\u5219\u5e94\u5f53\u663e\u5f0f\u5730\u4f7f\u7528Series\u7684copy\u65b9\u6cd5\u3002 \u7531\u5b57\u5178\u6784\u6210DataFrame \u00b6 \u57fa\u4e8e\u5b57\u5178 data \u4ea7\u751f\u7684DataFrame\u4f1a\u81ea\u52a8\u4e3aSereies\u5206\u914d\u7d22\u5f15\uff0c\u5e76\u4e14\u5217\u4f1a\u6309\u7167\u6392\u5e8f\u7684\u987a\u5e8f\u6392\u5217\u3002 data = { 'state': ['Ohio', 'Ohio', 'Ohio', 'Nevada', 'Nevada', 'Nevada'], 'year': [2000, 2001, 2002, 2001, 2002, 2003], 'pop': [1.5, 1.7, 3.6, 2.4, 2.9, 3.2] } frame = pd.DataFrame(data) print(frame) # state year pop # 0 Ohio 2000 1.5 # 1 Ohio 2001 1.7 # 2 Ohio 2002 3.6 # 3 Nevada 2001 2.4 # 4 Nevada 2002 2.9 # 5 Nevada 2003 3.2 # \u5bf9\u4e8e\u5927\u578bDataFrame, head\u65b9\u6cd5\u5c06\u4f1a\u53ea\u9009\u51fa\u5934\u90e8\u7684\u82e5\u5e72\u884c, \u9ed8\u8ba4\u662f\u524d\u4e94\u884c\u3002 print(frame.head(3)) # state year pop # 0 Ohio 2000 1.5 # 1 Ohio 2001 1.7 # 2 Ohio 2002 3.6 \u5982\u679c\u6307\u5b9a\u4e86\u5217\u7684\u987a\u5e8f\uff0cDataFrame\u7684\u5217\u5c06\u4f1a\u6309\u7167\u6307\u5b9a\u987a\u5e8f\u6392\u5217\u3002 frame = pd.DataFrame(data, columns=['year', 'state', 'pop']) print(frame) # year state pop # 0 2000 Ohio 1.5 # 1 2001 Ohio 1.7 # 2 2002 Ohio 3.6 # 3 2001 Nevada 2.4 # 4 2002 Nevada 2.9 # 5 2003 Nevada 3.2 \u5982\u679c\u4f20\u7684\u5217\uff08 debt \uff09\u4e0d\u5305\u542b\u5728\u5b57\u5178\uff08 data \uff09\u4e2d\uff0c\u5c06\u4f1a\u5728\u7ed3\u679c\u4e2d\u51fa\u73b0\u7f3a\u5931\u503c\u3002 frame2 = pd.DataFrame( data, columns=['year', 'state', 'pop', 'debt'], index=['one', 'two', 'three', 'four', 'five', 'six'] ) print(frame2) # year state pop debt # one 2000 Ohio 1.5 NaN # two 2001 Ohio 1.7 NaN # three 2002 Ohio 3.6 NaN # four 2001 Nevada 2.4 NaN # five 2002 Nevada 2.9 NaN # six 2003 Nevada 3.2 NaN \u9009\u53d6\u884c, \u53ef\u4ee5\u901a\u8fc7\u4f4d\u7f6e\u6216\u884c\u7d22\u5f15\u6807\u7b7e loc \u8fdb\u884c\u9009\u53d6\u3002 print(frame2.loc['three']) # year 2002 # state Ohio # pop 3.6 # debt NaN # Name: three, dtype: object DataFrame\u4e2d\u7684\u4e00\u5217\uff0c\u53ef\u4ee5\u6309\u5b57\u5178\u578b\u6807\u8bb0\u6216\u5c5e\u6027\u90a3\u6837\u68c0\u7d22\u4e3aSeries\u3002 frame2[colunm] \u5bf9\u4e8e\u4efb\u610f\u5217\u540d\u5747\u6709\u6548\uff0c\u4f46\u662f frame2.column \u53ea\u5728\u5217\u540d\u662f\u6709\u6548\u7684Python\u53d8\u91cf\u540d\u65f6\u6709\u6548\u3002 \u8fd4\u56de\u7684Series\u4e0e\u539fDataFrame\u6709\u76f8\u540c\u7684\u7d22\u5f15\uff0c\u4e14Series\u7684 name \u5c5e\u6027\u4e5f\u4f1a\u88ab\u5408\u7406\u5730\u8bbe\u7f6e\u3002 print(frame2['state']) # one Ohio # two Ohio # three Ohio # four Nevada # five Nevada # six Nevada # Name: state, dtype: object print(frame2.state) # \u5c5e\u6027\u578b\u8fde\u63a5 # one Ohio # two Ohio # three Ohio # four Nevada # five Nevada # six Nevada # Name: state, dtype: object \u5217\u7684\u5f15\u7528\u662f\u53ef\u4ee5\u4fee\u6539\u7684\u3002\u503c\u7684\u957f\u5ea6\u5fc5\u987b\u548cDataFrame\u7684\u957f\u5ea6\u76f8\u5339\u914d,\u6bd4\u5982\uff0c\u4e0b\u4f8b\u4e2d np.arange(6.) \u548c frame2['debt'] \u7684\u957f\u5ea6\u90fd\u662f6\u3002 frame2['debt'] = 16.5 print(frame2) # Name: state, dtype: object # year state pop debt # one 2000 Ohio 1.5 16.5 # two 2001 Ohio 1.7 16.5 # three 2002 Ohio 3.6 16.5 # four 2001 Nevada 2.4 16.5 # five 2002 Nevada 2.9 16.5 # six 2003 Nevada 3.2 16.5 frame2['debt'] = np.arange(6.) print(frame2) # year state pop debt # one 2000 Ohio 1.5 0.0 # two 2001 Ohio 1.7 1.0 # three 2002 Ohio 3.6 2.0 # four 2001 Nevada 2.4 3.0 # five 2002 Nevada 2.9 4.0 # six 2003 Nevada 3.2 5.0 \u5982\u679c\u5c06Series\u8d4b\u503c\u7ed9\u4e00\u5217\u65f6\uff0cSeries\u7684\u7d22\u5f15\u5c06\u4f1a\u6309\u7167DataFrame\u7684\u7d22\u5f15\u91cd\u65b0\u6392\u5217\uff0c\u5e76\u5728\u7a7a\u7f3a\u7684\u5730\u65b9\u586b\u5145\u7f3a\u5931\u503c val = pd.Series([-1.2, -1.5, -1.7], index=['two', 'four', 'five']) frame2['debt'] = val print(frame2) # year state pop debt # one 2000 Ohio 1.5 NaN # two 2001 Ohio 1.7 -1.2 # three 2002 Ohio 3.6 NaN # four 2001 Nevada 2.4 -1.5 # five 2002 Nevada 2.9 -1.7 # six 2003 Nevada 3.2 NaN \u5982\u679c\u88ab\u8d4b\u503c\u7684\u5217( eastern \u5217)\u5e76\u4e0d\u5b58\u5728\uff0c\u5219\u4f1a\u751f\u6210\u4e00\u4e2a\u65b0\u7684\u5217\u3002 frame2.state == 'Ohio' \u8fd4\u56de\u7684\u662f\u5e03\u5c14\u503c\uff0c\u8d4b\u503c\u7ed9 eastern \u3002 frame2['eastern'] = frame2.state == 'Ohio' print(frame2) # year state pop debt eastern # one 2000 Ohio 1.5 NaN True # two 2001 Ohio 1.7 -1.2 True # three 2002 Ohio 3.6 NaN True # four 2001 Nevada 2.4 -1.5 False # five 2002 Nevada 2.9 -1.7 False # six 2003 Nevada 3.2 NaN False print(frame2.eastern) # one True # two True # three True # four False # five False # six False # Name: eastern, dtype: bool del \u5173\u952e\u5b57\u53ef\u4ee5\u50cf\u5728\u5b57\u5178\u4e2d\u90a3\u6837\u5bf9DataFrame\u5220\u9664\u5217\u3002 del frame2['eastern'] print(frame2.columns) # Index(['year', 'state', 'pop', 'debt'], dtype='object') \u4f7f\u7528\u5d4c\u5957\u5b57\u5178\u6784\u5efaDataFrame \u00b6 pandas\u4f1a\u5c06\u5b57\u5178\u7684\u952e\u4f5c\u4e3a\u5217('Nevada', etc.)\uff0c\u5c06\u5185\u90e8\u5b57\u5178\u7684\u952e\u4f5c\u4e3a\u884c\u7d22\u5f15(2001, etc.) pop = { 'Nevada': { 2001: 2.4, 2002: 2.9 }, 'Ohio': { 2000: 1.5, 2001: 1.7, 2002: 3.6 } } # \u4e0d\u6307\u5b9a\u7d22\u5f15\uff0c\u9ed8\u8ba4\u4f7f\u7528\u5b57\u5178\u7d22\u5f15 frame3 = pd.DataFrame(pop) print(frame3) # Nevada Ohio # 2001 2.4 1.7 # 2002 2.9 3.6 # 2000 NaN 1.5 # \u6307\u5b9a\u5b57\u5178\u67d0\u5217\u4f5c\u4e3a\u7d22\u5f15 print(pd.DataFrame(pop, index=[2001, 2002, 2003])) # Nevada Ohio # 2001 2.4 1.7 # 2002 2.9 3.6 # 2003 NaN NaN # \u6307\u5b9a\u4e0d\u76f8\u5e72\u7d22\u5f15 print(pd.DataFrame(pop, index=['a', 'b', 'c'])) # Nevada Ohio # a NaN NaN # b NaN NaN # c NaN NaN \u8f6c\u7f6e\u64cd\u4f5c\uff08\u8c03\u6362\u884c\u548c\u5217\uff09 print(frame3.T) # 2001 2002 2000 # Nevada 2.4 2.9 NaN # Ohio 1.7 3.6 1.5 \u4f7f\u7528\u542bSeries\u7684\u5b57\u5178\u6784\u9020DataFrame \u00b6 frame3['Ohio'][:-1] \u662f\u503c\u4e3a Ohio \u7684Series\u76840~\u5012\u6570\u7b2c\u4e00\u4e2a\u5143\u7d20\uff08\u4e0d\u542b\uff09\uff0c\u4e00\u51713\u4e2a\u3002 frame3['Nevada'][:2] \u662f\u503c\u4e3a Nevada \u7684Series\u7684\u524d2\u4e2a\u5143\u7d20\u3002 pdata = { 'Ohio': frame3['Ohio'][:-1], 'Nevada': frame3['Nevada'][:2] } print(pd.DataFrame(pdata)) # Ohio Nevada # 2001 1.7 2.4 # 2002 3.6 2.9 \u6307\u5b9aDataframe frame3 \u7684\u5217\u540d\u3002 frame3.index.name = 'year' frame3.columns.name = 'state' print(frame3) # state Nevada Ohio # year # 2001 2.4 1.7 # 2002 2.9 3.6 # 2000 NaN 1.5 \u53ea\u8f93\u51faDataframe\u7684\u503c frame3.values \uff0c\u662f\u4e00\u4e2a\u4e8c\u7ef4\u6570\u7ec4\u3002 print(frame3.values) # [[2.4 1.7] # [2.9 3.6] # [nan 1.5]] \u53ea\u8f93\u51faDataframe\u7684\u503c frame2.values \uff0c\u662f\u4e00\u4e2a\u4e8c\u7ef4\u6570\u7ec4\u3002 print(frame2) # year state pop debt # one 2000 Ohio 1.5 NaN # two 2001 Ohio 1.7 -1.2 # three 2002 Ohio 3.6 NaN # four 2001 Nevada 2.4 -1.5 # five 2002 Nevada 2.9 -1.7 # six 2003 Nevada 3.2 NaN print(frame2.values) # [[2000 'Ohio' 1.5 nan] # [2001 'Ohio' 1.7 -1.2] # [2002 'Ohio' 3.6 nan] # [2001 'Nevada' 2.4 -1.5] # [2002 'Nevada' 2.9 -1.7] # [2003 'Nevada' 3.2 nan]] \u7d22\u5f15\u5bf9\u8c61 \u00b6 pandas\u4e2d\u7684**\u7d22\u5f15\u5bf9\u8c61**\u662f\u7528\u4e8e\u5b58\u50a8\u8f74\u6807\u7b7e\u548c\u5176\u4ed6\u5143\u6570\u636e\u7684\uff08\u4f8b\u5982\u8f74\u540d\u79f0\u6216\u6807\u7b7e\uff09\u3002 \u5728\u6784\u9020Series\u6216DataFrame\u65f6\uff0c\u4f60\u6240\u4f7f\u7528\u7684\u4efb\u610f\u6570\u7ec4\u6216\u6807\u7b7e\u5e8f\u5217\u90fd\u53ef\u4ee5\u5728\u5185\u90e8\u8f6c\u6362\u4e3a\u7d22\u5f15\u5bf9\u8c61\u3002 \u7d22\u5f15\u5bf9\u8c61\u662f\u4e0d\u53ef\u53d8\u7684\u3002 \u9664\u4e86\u7c7b\u4f3c\u6570\u7ec4\uff0c\u7d22\u5f15\u5bf9\u8c61\u4e5f\u50cf\u4e00\u4e2a\u56fa\u5b9a\u5927\u5c0f\u7684\u96c6\u5408\u3002\u4e0ePython\u96c6\u5408\u4e0d\u540c\uff0c pandas\u7d22\u5f15\u5bf9\u8c61\u53ef\u4ee5\u5305\u542b\u91cd\u590d\u6807\u7b7e \u3002 \u56e0\u4e3a\u4e00\u4e9b\u64cd\u4f5c\u4f1a\u4ea7\u751f\u5305\u542b\u7d22\u5f15\u5316\u6570\u636e\u7684\u7ed3\u679c\uff0c\u7406\u89e3\u7d22\u5f15\u5982\u4f55\u5de5\u4f5c\u8fd8\u662f\u5f88\u91cd\u8981\u7684\u3002 \u4e0b\u4f8b\u6f14\u793a\u4e86\u5982\u4f55\u8bfb\u53d6Dataframe\u7684\u7d22\u5f15\u503c\u3002 obj = pd.Series(range(3), index=['a', 'b', 'c']) index = obj.index print(obj) # a 0 # b 1 # c 2 # dtype: int64 print(index) # Index(['a', 'b', 'c'], dtype='object') print(index[1:]) # Index(['b', 'c'], dtype='object') \u4e0b\u4f8b\u6f14\u793a\u4e86\u901a\u8fc7\u4e00\u4e2a\u6307\u5b9a\u7684Dataframe\u7d22\u5f15 labels \u6765\u751f\u6210Dataframe obj2 \u3002 labels = pd.Index(np.arange(3)) print(labels) # Int64Index([0, 1, 2], dtype='int64') obj2 = pd.Series([1.5, -2.5, 0], index=labels) print(obj2) # 0 1.5 # 1 -2.5 # 2 0.0 # dtype: float64 print(obj2.index is labels) # True \u4e0b\u4f8b\u6f14\u793a\u4e86\u4e0d\u6307\u5b9a\u7d22\u5f15\uff0c\u9ed8\u8ba4\u4f7f\u7528\u5b57\u5178\u7d22\u5f15\u6765\u521b\u5efaDataframe\u3002 pop = { 'Nevada': { 2001: 2.4, 2002: 2.9 }, 'Ohio': { 2000: 1.5, 2001: 1.7, 2002: 3.6 } } frame3 = pd.DataFrame(pop) print(frame3) # Nevada Ohio # 2001 2.4 1.7 # 2002 2.9 3.6 # 2000 NaN 1.5 print(frame3) # state Nevada Ohio # year # 2001 2.4 1.7 # 2002 2.9 3.6 # 2000 NaN 1.5 print(frame3.columns) # Index(['Nevada', 'Ohio'], dtype='object', name='state') print(frame3.index) # Int64Index([2001, 2002, 2000], dtype='int64', name='year') print('Ohio' in frame3.columns) # True print(2003 in frame3.index) # False pandas\u7d22\u5f15\u5bf9\u8c61\u5141\u8bb8\u5305\u542b\u91cd\u590d\u6807\u7b7e\u3002\u6839\u636e\u91cd\u590d\u6807\u7b7e\u8fdb\u884c\u7b5b\u9009\uff0c\u4f1a\u9009\u53d6\u6240\u6709\u91cd\u590d\u6807\u7b7e\u5bf9\u5e94\u7684\u6570\u636e\u3002 dup_labels = pd.Index(['foo', 'foo', 'bar', 'bar']) print(dup_labels) # Index(['foo', 'foo', 'bar', 'bar'], dtype='object') \u4e00\u4e9b\u5e38\u7528\u7d22\u5f15\u5bf9\u8c61\u7684\u65b9\u6cd5\u548c\u5c5e\u6027\u3002 obj1 = pd.Series(range(3), index=['a', 'b', 'c']) index1 = obj1.index obj2 = pd.Series(range(3), index=['c', 'f', 'g']) index2 = obj2.index print(index1) # Index(['a', 'b', 'c'], dtype='object') print(index2) # Index(['c', 'f', 'g'], dtype='object') append \u65b9\u6cd5\uff1a\u5c06\u5916\u90e8\u7684\u7d22\u5f15\u5bf9\u8c61\u7c98\u8d34\u5230\u539f\u7d22\u5f15\u540e\uff0c\u4ea7\u751f\u4e00\u4e2a\u65b0\u7684\u7d22\u5f15\u3002 \u63a5\u4e0a\u4f8b\uff0c\u628a index2 \u5bf9\u8c61\u8ffd\u52a0\u5230 index1 \u5bf9\u8c61\u3002 print(index1.append(index2)) # Index(['a', 'b', 'c', 'c', 'f', 'g'], dtype='object') difference \u65b9\u6cd5: \u8ba1\u7b972\u4e2a\u7d22\u5f15\u7684\u5dee\u96c6\u3002 print(index1.difference(index2)) # Index(['a', 'b'], dtype='object') intersection \u65b9\u6cd5: \u8ba1\u7b972\u4e2a\u7d22\u5f15\u7684\u4ea4\u96c6\u3002 print(index1.intersection(index2)) # Index(['c'], dtype='object') union \u65b9\u6cd5: \u8ba1\u7b972\u4e2a\u7d22\u5f15\u7684\u5e76\u96c6\uff08\u53bb\u91cd\uff09\u3002 print(index1.union(index2)) # Index(['a', 'b', 'c', 'f', 'g'], dtype='object') isin \u65b9\u6cd5: \u8ba1\u7b97\u8868\u793a\u6bcf\u4e00\u4e2a\u503c\u662f\u5426\u5728\u4f20\u503c\u5bb9\u5668\u4e2d\uff0c\u8fd4\u56de\u7684\u662f\u4e00\u4e2a\u5e03\u5c14\u6570\u7ec4\u3002 print(index1.isin(index2)) # [False False True] delete \u65b9\u6cd5: \u5c06\u4f4d\u7f6ei\uff08\u4ece0\u5f00\u59cb\u7f16\u53f7\uff09\u7684\u5143\u7d20\u5220\u9664\uff0c\u5e76\u4ea7\u751f\u65b0\u7684\u7d22\u5f15\u3002 print(index1.delete('b')) # IndexError: arrays used as indices must be of integer (or boolean) type print(index1.delete(1)) # Index(['a', 'c'], dtype='object') print(index1) # Index(['a', 'b', 'c'], dtype='object') drop \u65b9\u6cd5: \u6839\u636e\u4f20\u53c2\u5220\u9664\u6307\u5b9a\u7d22\u5f15\u503c\uff0c\u5e76\u4ea7\u751f\u65b0\u7684\u7d22\u5f15, \u5bf9\u6bd4\u548cdelete\u7684\u533a\u522b\uff0c delete \u65b9\u6cd5\u662f\u8f93\u5165\u4f4d\u7f6e\uff0c drop \u65b9\u6cd5\u662f\u8f93\u5165\u7d22\u5f15\u540d\u79f0\u3002 print(index2.drop(1)) # KeyError: '[1] not found in axis' print(index2.drop('f')) # Index(['c', 'g'], dtype='object') print(index2) # Index(['c', 'f', 'g'], dtype='object') insert \u65b9\u6cd5: \u5728\u4f4d\u7f6e i \u63d2\u5165\u5143\u7d20\uff0c\u5e76\u4ea7\u751f\u65b0\u7684\u7d22\u5f15\u3002 print(index1.insert(1, 'e')) # Index(['a', 'e', 'b', 'c'], dtype='object') print(index1) # Index(['a', 'b', 'c'], dtype='object') is_monotonic \u65b9\u6cd5: \u5982\u679c\u7d22\u5f15\u5e8f\u5217\u9012\u589e\uff0c\u5219\u8fd4\u56de True \u3002 print(index1.is_monotonic) # True print(index1.insert(1, 'e').is_monotonic) # False is_unique \u65b9\u6cd5: \u5982\u679c\u7d22\u5f15\u5e8f\u5217\u552f\u4e00\u5219\u8fd4\u56de True \u3002 print(index1.is_unique) # True print(index1.append(index2).is_unique) # False unique \u65b9\u6cd5: \u8ba1\u7b97\u7d22\u5f15\u7684\u552f\u4e00\u503c\u5e8f\u5217\uff08\u5bf9\u6bd4Union\uff09\u3002 print(index1.unique()) # Index(['a', 'b', 'c'], dtype='object') print(index1.append(index2).unique()) # Index(['a', 'b', 'c', 'f', 'g'], dtype='object') pandas\u57fa\u672c\u529f\u80fd \u00b6 \u91cd\u5efa\u7d22\u5f15 \u00b6 Series\u8c03\u7528 reindex \u65b9\u6cd5\u65f6\uff0c\u4f1a\u5c06\u6570\u636e\u6309\u7167\u65b0\u7684\u7d22\u5f15\u8fdb\u884c\u6392\u5217\uff0c\u5982\u679c\u67d0\u4e2a\u7d22\u5f15\u503c\u4e4b\u524d\u5e76\u4e0d\u5b58\u5728\uff0c\u5219\u4f1a\u5f15\u5165\u7f3a\u5931\u503c\u3002 \u4e0b\u4f8b\u4e2d\uff0c\u5bf9 obj1 \u505a reindex \uff0c reindex \u65b9\u6cd5\u4f1a\u521b\u5efa\u4e00\u4e2a\u65b0\u7d22\u5f15\u5bf9\u8c61 obj2 \uff0c\u7d22\u5f15\u503c e \u4e4b\u524d\u5e76\u4e0d\u5b58\u5728\uff0c\u6240\u4ee5\u586b\u5165\u7f3a\u5931\u503c\u3002 \u5982\u679c\u5bf9obj1\u505a reindex \u65f6\u6307\u5b9a method='ffill' \uff0c\u4f1a\u62a5\u9519 index must be monotonic increasing or decreasing \u3002 obj1 = pd.Series([4.5, 7.2, -5.3, 3.6], index=['d', 'b', 'a', 'c']) print(obj1) # d 4.5 # b 7.2 # a -5.3 # c 3.6 # dtype: float64 obj2 = obj1.reindex(['a', 'b', 'c', 'd', 'e']) print(obj2) # a -5.3 # b 7.2 # c 3.6 # d 4.5 # e NaN # dtype: float64 obj2 = obj1.reindex(['a', 'b', 'c', 'd', 'e'], method='ffill') # ValueError: index must be monotonic increasing or decreasing \u5bf9\u4e8e\u987a\u5e8f\u6570\u636e\uff0c\u6bd4\u5982\u65f6\u95f4\u5e8f\u5217\uff0c\u5728\u91cd\u5efa\u7d22\u5f15\u65f6\u53ef\u80fd\u4f1a\u9700\u8981\u8fdb\u884c\u63d2\u503c\u6216\u586b\u503c\u3002 ffill \u65b9\u6cd5\u5728\u91cd\u5efa\u7d22\u5f15\u65f6\u63d2\u503c\uff0c\u5c06\u503c\u524d\u5411\u586b\u5145\u3002 obj3 = pd.Series(['blue', 'purple', 'yellow'], index=[0, 2, 4]) print(obj3.reindex(range(6), method='ffill')) # 0 blue # 1 blue # 2 purple # 3 purple # 4 yellow # 5 yellow # dtype: object \u5728DataFrame\u4e2d\uff0c reindex \u53ef\u4ee5\u6539\u53d8\u884c\u7d22\u5f15\u3001\u5217\u7d22\u5f15\uff0c\u4e5f\u53ef\u4ee5\u540c\u65f6\u6539\u53d8\u4e8c\u8005\u3002\u5f53\u4ec5\u4f20\u5165\u4e00\u4e2a\u5e8f\u5217\u65f6\uff0c\u4f1a\u91cd\u5efa\u884c\u7d22\u5f15\u3002 \u4e0b\u4f8b\u4e2d\uff0c\u901a\u8fc7 indexes \u521b\u5efaDataframe frame \u3002 \u901a\u8fc7 frame.reindex(['a', 'b', 'c', 'd'])\u91cd\u5efa\u884c\u7d22\u5f15 \u3002 \u901a\u8fc7 frame2.reindex(columns=['Ohio', 'Uta', 'California']) \u91cd\u5efa\u5217\u7d22\u5f15\u3002 \u7f3a\u5931\u7684\u7d22\u5f15\u5217\u586b\u5165\u7f3a\u5931\u503c\u3002 indexes = index = ['a', 'b', 'c'] states = ['Ohio', 'Texas', 'California'] frame = pd.DataFrame( np.arange(9).reshape(3, 3), index=indexes, columns=states ) print(frame) # Ohio Texas California # a 0 1 2 # b 3 4 5 # c 6 7 8 frame2 = frame.reindex(['a', 'b', 'c', 'd']) # \u91cd\u5efa\u884c\u7d22\u5f15 print(frame2) # Ohio Texas California # a 0.0 1.0 2.0 # b 3.0 4.0 5.0 # c 6.0 7.0 8.0 # d NaN NaN NaN frame3 = frame2.reindex(columns=['Ohio', 'Uta', 'California']) # \u91cd\u5efa\u5217\u7d22\u5f15 print(frame3) # Ohio Uta California # a 0.0 NaN 2.0 # b 3.0 NaN 5.0 # c 6.0 NaN 8.0 # d NaN NaN NaN \u4f7f\u7528 loc \u8fdb\u884c\u66f4\u4e3a\u7b80\u6d01\u7684\u884c\u3001\u5217\u6807\u7b7e\u7d22\u5f15\u3002\u4e0b\u4f8b\u901a\u8fc7\u7b5b\u9009\u884c\u7d22\u5f15\u548c\u5217\u7d22\u5f15\u4ea7\u751f\u65b0\u7684Dataframe\u3002 frame4 = frame.loc[['a', 'b'], states] print(frame4) # Ohio Texas California # a 0 1 2 # b 3 4 5 \u8f74\u5411\u7d22\u5f15\u5220\u9664\u6761\u76ee \u00b6 set_index() , dropna() , fillna() , reset_index() , drop() , replace() \u8fd9\u4e9b\u65b9\u6cd5\u7684 inplace \u5c5e\u6027\u8bbe\u4e3a True \u65f6\uff0c\u8fd9\u4e9b\u65b9\u6cd5\u4f1a\u4fee\u6539Series\u6216DataFrame\u7684\u5c3a\u5bf8\u6216\u5f62\u72b6\uff0c*\u76f4\u63a5*\u64cd\u4f5c\u539f\u5bf9\u8c61\u800c\u4e0d\u8fd4\u56de\u65b0\u5bf9\u8c61\u3002 obj = pd.Series(np.arange(5), index=['a', 'b', 'c', 'd', 'e']) print(obj) # a 0 # b 1 # c 2 # d 3 # e 4 # dtype: int64 obj1 = obj.drop('c') print(obj1) # a 0 # b 1 # d 3 # e 4 # dtype: int64 print(obj1.drop(['d', 'e'])) # a 0 # b 1 # dtype: int64 \u5bf9\u6bd4 inplace=True \u548c False \u7684\u533a\u522b\u3002 inplace=False \u65f6\uff0c obj \u7684\u503c\u6ca1\u6709\u53d8\u5316\u3002 obj = pd.Series(np.arange(5), index=['a', 'b', 'c', 'd', 'e']) print(obj.drop('c', inplace=False)) # \u8bf4\u660e\u751f\u6210\u4e86\u65b0\u5bf9\u8c61 # a 0 # b 1 # d 3 # e 4 # dtype: int64 print(obj) # a 0 # b 1 # c 2 # d 3 # e 4 # dtype: int64 obj.drop('c', inplace=True) \u8f93\u51fa\u662f None \uff0c\u8bf4\u660e\u6ca1\u6709\u751f\u6210\u65b0\u5bf9\u8c61\uff0c\u53d8\u5316\u76f4\u63a5\u4f5c\u7528\u5230 obj \u4e0a\u3002 obj = pd.Series(np.arange(5), index=['a', 'b', 'c', 'd', 'e']) print(obj) print(obj.drop('c', inplace=True)) # \u8bf4\u660e\u6ca1\u6709\u751f\u6210\u65b0\u5bf9\u8c61 # None print(obj) # a 0 # b 1 # d 3 # e 4 # dtype: int64 \u4e0b\u4f8b\u6f14\u793a\u4e86\u8f74\u5411\u7684\u6548\u679c\u3002 \u5982\u679c\u4e0d\u6307\u5b9a\u8f74\u5411axis\uff0c drop() \u4f1a\u9ed8\u8ba4\u6cbf axis=0 \u8fdb\u884c\uff0c\u6240\u4ee5\uff0c\u57280\u8f74\u4e0a\u6267\u884c data.drop(['one', 'two']) \u4f1a\u62a5\u9519\u3002 axis='columns \u4e0e\u6307\u5b9a axis=1 \u540c\u6837\u6548\u679c\u3002 data = pd.DataFrame( np.arange(16).reshape(4, 4), index=['Ohio', 'Colorado', 'Utah', 'New York'], columns=['one', 'two', 'three', 'four'] ) print(data) # one two three four # Ohio 0 1 2 3 # Colorado 4 5 6 7 # Utah 8 9 10 11 # New York 12 13 14 15 # \u6cbf0\u8f74\u64cd\u4f5c\uff0c\u5220\u9664\u7b26\u5408\u6761\u4ef6\u7684\u884c\u8bb0\u5f55 print(data.drop(['Ohio', 'Colorado'])) # one two three four # Utah 8 9 10 11 # New York 12 13 14 15 print(data.drop(['one', 'two'])) # KeyError: \"['one' 'two'] not found in axis\" # \u6cbf1\u8f74\u64cd\u4f5c\uff0c\u5220\u9664\u7b26\u5408\u6761\u4ef6\u7684\u5217\u8bb0\u5f55 print(data.drop(['one', 'two'], axis=1)) # three four # Ohio 2 3 # Colorado 6 7 # Utah 10 11 # New York 14 15 print(data.drop(['one', 'two'], axis='columns')) # three four # Ohio 2 3 # Colorado 6 7 # Utah 10 11 # New York 14 15 \u518d\u901a\u8fc7\u4e0b\u4f8b\u4f53\u4f1a\u4e00\u4e0b inplace \u53c2\u6570\u7684\u4e0d\u540c\u6548\u679c\u3002 data = pd.DataFrame( { 'Name': ['Shobhit', 'vaibhav', 'vimal', 'Sourabh'], 'class': [11, 12, 10, 9], 'Age': [18, 20, 21, 17] } ) print(data) # Name class Age # 0 Shobhit 11 18 # 1 vaibhav 12 20 # 2 vimal 10 21 # 3 Sourabh 9 17 print(data.rename(columns={'Name': 'FirstName'}, inplace=False)) # FirstName class Age # 0 Shobhit 11 18 # 1 vaibhav 12 20 # 2 vimal 10 21 # 3 Sourabh 9 17 print(data) # Name class Age # 0 Shobhit 11 18 # 1 vaibhav 12 20 # 2 vimal 10 21 # 3 Sourabh 9 17 print(data.rename(columns={'Name': 'FirstName'}, inplace=True)) # \u6ca1\u6709\u751f\u6210\u65b0\u5bf9\u8c61 # None print(data) # FirstName class Age # 0 Shobhit 11 18 # 1 vaibhav 12 20 # 2 vimal 10 21 # 3 Sourabh 9 17 \u7d22\u5f15\u3001\u9009\u62e9\u4e0e\u8fc7\u6ee4 \u00b6 Series\u7684\u7d22\u5f15 obj[...] \u4e0eNumPy\u6570\u7ec4\u7d22\u5f15\u7684\u529f\u80fd\u7c7b\u4f3c\uff0c\u53ea\u4e0d\u8fc7Series\u7684\u7d22\u5f15\u503c\u53ef\u4ee5\u4e0d\u4ec5\u4ec5\u662f\u6574\u6570\u3002 \u4e0b\u4f8b\u4e2d\uff1a obj[1] \u901a\u8fc7\u7d22\u5f15\u4f4d 1 \u68c0\u7d22\uff0c\u8f93\u51fa\u5bf9\u5e94Series\u7684\u503c\u3002 obj[1] \u901a\u8fc7\u7d22\u5f15\u4f4d [1] \u68c0\u7d22\uff0c\u8f93\u51faSeries\u3002 obj['b'] \u901a\u8fc7\u7d22\u5f15\u503c 'b' \u68c0\u7d22\uff0c\u8f93\u51fa\u5bf9\u5e94Series\u7684\u503c\u3002 obj[['b']] \u901a\u8fc7\u7d22\u5f15\u503c ['b'] \u68c0\u7d22\uff0c\u8f93\u51faSeries\u3002 obj = pd.Series(['Shobhit', 'vaibhav', 'vimal', 'Sourabh'], index=['a', 'b', 'c', 'd']) print(obj) # a Shobhit # b vaibhav # c vimal # d Sourabh # dtype: object print(obj[1]) # \u901a\u8fc7\u7d22\u5f15\u4f4d\u68c0\u7d22\uff0c\u8f93\u51fa\u5bf9\u5e94Series\u7684\u503c # vaibhav print(obj[[1]]) # b vaibhav # dtype: object print(obj['b']) # \u901a\u8fc7\u7d22\u5f15\u503c\u68c0\u7d22\uff0c\u8f93\u51fa\u5bf9\u5e94Series\u7684\u503c # vaibhav print(obj[['b']]) # \u901a\u8fc7\u7d22\u5f15\u503c\u68c0\u7d22\uff0c\u8f93\u51faSeries # b vaibhav # dtype: object \u4e0b\u9762\u4e00\u7ec4\u7684\u8f93\u51fa\u4e2d\uff0c\u6ce8\u610f\u5bf9\u6bd4\u666e\u901aPython\u5207\u7247\u4e0eSeries\u7684\u5207\u7247\u7684\u5dee\u5f02\u3002 obj = pd.Series(['Shobhit', 'vaibhav', 'vimal', 'Sourabh'], index=['a', 'b', 'c', 'd']) print(obj[1]) # vaibhav print(obj[[1]]) # b vaibhav # dtype: object print(obj[1:3]) # b vaibhav # c vimal # dtype: object print(obj['b':'d']) # b vaibhav # c vimal # d Sourabh # dtype: object Series\u7684\u5207\u7247\u7684\u503c\u66f4\u65b0\u3002 obj['b': 'c'] = 5 \u662f\u901a\u8fc7\u7d22\u5f15\u503c\u8fdb\u884c\u66f4\u65b0\uff0c\u76f4\u63a5\u4f5c\u7528\u5728 obj \u3002 obj[1: 3] = 6 \u662f\u901a\u8fc7\u7d22\u5f15\u4f4d\u7f6e\u6765\u66f4\u65b0 obj \u3002 obj = pd.Series(['Shobhit', 'vaibhav', 'vimal', 'Sourabh'], index=['a', 'b', 'c', 'd']) obj['b': 'c'] = 5 print(obj) # a Shobhit # b 5 # c 5 # d Sourabh # dtype: object obj[1: 3] = 6 print(obj) # a Shobhit # b 6 # c 6 # d Sourabh # dtype: object DataFrame\u7684\u7d22\u5f15\u4e0e\u5207\u7247\u3002 data[['Three', 'Two']] \u9009\u53d6\u6307\u5b9a\u5217\uff0c\u6ce8\u610f\u8f93\u5165\u5217\u6761\u4ef6\u662f\u5217\u8868 ['Three', 'Two'] \u3002 data = pd.DataFrame( np.arange(16).reshape(4, 4), index=['Ohio', 'Colorado', 'Utah', 'New York'], columns=['One', 'Two', 'Three', 'Four'] ) print(data) # One Two Three Four # Ohio 0 1 2 3 # Colorado 4 5 6 7 # Utah 8 9 10 11 # New York 12 13 14 15 print(data['Two']) # Ohio 1 # Colorado 5 # Utah 9 # New York 13 # Name: Two, dtype: int64 print(data[['Three', 'Two']]) # Three Two # Ohio 2 1 # Colorado 6 5 # Utah 10 9 # New York 14 13 print(data[:2]) # One Two Three Four # Ohio 0 1 2 3 # Colorado 4 5 6 7 \u5d4c\u5957\uff1a\u6839\u636e\u4e00\u4e2a\u5e03\u5c14\u503c\u6570\u7ec4\u5207\u7247\u6216\u9009\u62e9\u6570\u636e\u3002 data['Three'] > 5 \u662f\u4e00\u4e2a\u5e03\u5c14\u503c\u5e8f\u5217\u3002 data[data['Three'] > 5] \u8f93\u51fa\u6761\u4ef6\u4e3aTrue\u7684\u7ed3\u679c\u96c6\u3002 print(data['Three'] > 5) # Ohio False # Colorado True # Utah True # New York True # Name: Three, dtype: bool print(data[data['Three'] > 5]) # One Two Three Four # Colorado 4 5 6 7 # Utah 8 9 10 11 # New York 12 13 14 15 \u4f7f\u7528\u5e03\u5c14\u503cDataFrame\u8fdb\u884c\u7d22\u5f15\uff0c\u5df2\u7ecf\u66f4\u65b0\u3002 \u5728\u4e0b\u9762\u8fd9\u4e2a\u4f8b\u5b50\u4e2d\uff0c\u8fd9\u79cd\u7d22\u5f15\u65b9\u5f0f\u4f7f\u5f97DataFrame\u5728\u8bed\u6cd5\u4e0a\u66f4\u50cf\u662fNumPy\u4e8c\u7ef4\u6570\u7ec4\u3002 print(data < 5) # One Two Three Four # Ohio True True True True # Colorado True False False False # Utah False False False False # New York False False False False data[data < 5] = 0 print(data) # One Two Three Four # Ohio 0 0 0 0 # Colorado 0 5 6 7 # Utah 8 9 10 11 # New York 12 13 14 15 \u4f7f\u7528loc\u548ciloc\u9009\u62e9\u6570\u636e\u3002 \u4f7f\u7528\u6807\u7b7e\u540d loc \u6216\u6807\u7b7e\u4f4d\u7f6e iloc \u4ee5NumPy\u98ce\u683c\u7684\u8bed\u6cd5\u4eceDataFrame\u4e2d\u9009\u51faDataframe\u7684\u884c\u548c\u5217\u7684\u5b50\u96c6\u3002 data = pd.DataFrame( np.arange(16).reshape(4, 4), index=['Ohio', 'Colorado', 'Utah', 'New York'], columns=['One', 'Two', 'Three', 'Four'] ) print(data) # One Two Three Four # Ohio 0 1 2 3 # Colorado 4 5 6 7 # Utah 8 9 10 11 # New York 12 13 14 15 \u4e0b\u4f8b\u901a\u8fc7loc\u5bf9\u6807\u7b7e\u540d\u7b5b\u9009\u884c\u6216\u5217\u6570\u636e\u3002\u4f8b\u5982\uff0c\u8f93\u51fa Colorado \u884c\u6807\u7b7e\u7684 Two \u548c Three \u8fd9\u4e24\u5217\u7684\u503c\uff0c\u4ee5\u884c\u8bb0\u5f55\u7684\u65b9\u5f0f\u5c55\u73b0\u3002 print(data.loc['Colorado', ['Two', 'Three']]) # \u5207\u7247: # Two 5 # Three 6 # Name: Colorado, dtype: int64 print(data.loc[:'Ohio', :'Two']) # \u5207\u7247: 0\u884c\uff0c0,1\u5217 # One Two # Ohio 0 1 \u4e0b\u4f8b\u901a\u8fc7\u6807\u7b7e\u4f4d\u7f6e iloc \u8fdb\u884c\u7c7b\u4f3c\u7684\u6570\u636e\u9009\u62e9\u3002 data.iloc[:3, :2][data > 4] \u6309\u6307\u5b9a\u6761\u4ef6\u8fdb\u884c\u884c\u3001\u5217\u7b5b\u9009\uff0c\u7b26\u5408\u6761\u4ef6 [data > 4] \u7684\u8f93\u51faDataframe\u503c\uff0c\u4e0d\u7b26\u5408\u6761\u4ef6\u7684\u8f93\u51faNaN\u3002 print(data.iloc[[0]]) # 0\u884c # One Two Three Four # Ohio 0 1 2 3 print(data.iloc[[0], [1]]) # \u5207\u7247: 0\u884c\uff0c1\u5217 # Two # Ohio 1 print(data.iloc[1:2, 1:2]) # \u5207\u7247: 1\u884c\uff0c2\u5217 # Two # Ohio 1 print(data.iloc[2, [3, 0, 1]]) # \u5207\u7247: 2\u884c\uff0c\u4f9d\u6b21\u53d63\uff0c0\uff0c1\u5217 # Four 11 # One 8 # Two 9 # Name: Utah, dtype: int64 print(data.iloc[:3, :2][data > 4]) # One Two # Ohio NaN NaN # Colorado NaN 5.0 # Utah 8.0 9.0 \u6574\u6570\u7d22\u5f15 \u00b6 Pandas\u7684Series\u7684\u7d22\u5f15\u503c\u662f\u6574\u6570\u7d22\u5f15\u3002 data = np.arange(3.) ser = pd.Series(data) print(ser) # 0 0.0 # 1 1.0 # 2 2.0 # dtype: float64 print(ser[:1]) # 0 0.0 # dtype: float64 print(ser.loc[:1]) # loc\u7528\u4e8e\u6807\u7b7e\u540d # 0 0.0 # 1 1.0 # dtype: float64 print(ser.iloc[:1]) # iloc\u7528\u4e8e\u6807\u7b7e\u4f4d\u7f6e # 0 0.0 # dtype: float64 data = ['1', 'b', 'e', 3] ser = pd.Series(data) print(ser) # 0 1 # 1 b # 2 e # 3 3 # dtype: object print(ser[:1]) # 0 1 # dtype: object print(ser.loc[:1]) # 0 1 # 1 b # dtype: object print(ser.iloc[:1]) # 0 1 # dtype: object \u5bf9DataFrame\u7684\u66f4\u65b0\u3002 df1 = pd.DataFrame(np.arange(4).reshape((2, 2)), columns=list('ab')) print(df1) # a b # 0 0 1 # 1 2 3 # \u6309\u6807\u7b7e\u540d\u66f4\u65b0 df1.loc[1, :'b'] = np.nan print(df1) # a b # 0 0.0 1.0 # 1 NaN NaN \u7b97\u672f\u548c\u6570\u636e\u5bf9\u9f50 \u00b6 Pandas\u652f\u6301\u5728Series\u6216\u8005DataFrame\u5bf9\u8c61\u4e4b\u95f4\u8fdb\u884c\u7b97\u672f\u8fd0\u7b97\u3002 \u4f8b\uff1a\u4e24\u4e2aSeries\u505a\u7b97\u672f\u52a0\u6cd5\u3002 \u8fd4\u56de\u7684\u7ed3\u679c\u4e5f\u662f\u4e00\u4e2aSeries\u3002 \u8fd4\u56de\u7ed3\u679c\u7684\u7d22\u5f15\u662f\u6bcf\u4e2aSeries\u7684\u7d22\u5f15\u7684\u5e76\u96c6\u3002 \u51e1\u662f\u6ca1\u6709\u5728\u4e24\u4e2aSeries\u90fd\u51fa\u73b0\u7684\u7d22\u5f15\u4f4d\u7f6e\uff0c\u5185\u90e8\u6570\u636e\u5bf9\u9f50\u4f1a\u586b\u5145\u7f3a\u5931\u503cNaN\u3002\u7f3a\u5931\u503c\u4f1a\u5728\u540e\u7eed\u7684\u5176\u5b83\u7b97\u672f\u64cd\u4f5c\u4e0a\u4ea7\u751f\u5f71\u54cd\u3002 \u540c\u65f6\u51fa\u73b0\u5728\u4e24\u4e2aSeries\u7684\u7d22\u5f15\u4f4d\u7f6e\uff0cSeries\u7684\u503c\u505a\u7b97\u672f\u76f8\u52a0\u3002 s1 = pd.Series( [7.3, -2.5, 3.4, 1.5], index=['a', 'c', 'd', 'e'] ) s2 = pd.Series( [-2.1, 3.6, -1.5, 4, 3.1], index=['a', 'c', 'e', 'f', 'g'] ) print(s1) # a 7.3 # c -2.5 # d 3.4 # e 1.5 # dtype: float64 print(s2) # a -2.1 # c 3.6 # e -1.5 # f 4.0 # g 3.1 # dtype: float64 print(s1 + s2) # a 5.2 # c 1.1 # d NaN # e 0.0 # f NaN # g NaN # dtype: float64 \u4f8b\uff1a\u4e24\u4e2aDataframe\u505a\u7b97\u672f\u52a0\u6cd5 \u8fd4\u56de\u7ed3\u679c\u4e5f\u662f\u4e00\u4e2aDataframe\u3002 \u8fd4\u56de\u7ed3\u679c\u7684\u884c\u5217\u7d22\u5f15\u662f\u6bcf\u4e2aDataFrame\u7684\u884c\u5217\u7d22\u5f15\u7684\u5e76\u96c6\u3002 \u51e1\u662f\u6ca1\u6709\u5728\u4e24\u4e2aDataFrame\u90fd\u51fa\u73b0\u7684\u4f4d\u7f6e\u5c31\u4f1a\u88ab\u7f6e\u4e3aNaN\u3002 \u4e24\u4e2aDataFrame\u90fd\u51fa\u73b0\u7684\u4f4d\u7f6e\uff0c\u5bf9Dataframe\u7684\u503c\u505a\u7b97\u672f\u52a0\u6cd5\u3002 df1 = pd.DataFrame( np.arange(9).reshape((3, 3)), columns=list('bcd'), index=['Ohio', 'Texas', 'Colorado'] ) df2 = pd.DataFrame( np.arange(12).reshape((4, 3)), columns=list('bde'), index=['Utah', 'Ohio', 'Texas', 'Oregon'] ) print(df1) # b c d # Ohio 0 1 2 # Texas 3 4 5 # Colorado 6 7 8 print(df2) # b d e # Utah 0 1 2 # Ohio 3 4 5 # Texas 6 7 8 # Oregon 9 10 11 print(df1 + df2) # b c d e # Colorado NaN NaN NaN NaN # Ohio 3.0 NaN 6.0 NaN # Oregon NaN NaN NaN NaN # Texas 9.0 NaN 12.0 NaN # Utah NaN NaN NaN NaN \u5728Series\u6216\u8005DataFrame\u5bf9\u8c61\u4e4b\u95f4\u8fdb\u884c\u7b97\u672f\u64cd\u4f5c\u65f6\uff0c\u6709\u65f6\u9700\u8981\u5bf9\u7f3a\u5931\u503c\u6307\u5b9a\u586b\u5145\u503c\uff0c\u6bd4\u5982\u5f53\u8f74\u6807\u7b7e\u5728\u4e00\u4e2a\u5bf9\u8c61\u4e2d\u5b58\u5728\uff0c\u5728\u53e6\u4e00\u4e2a\u5bf9\u8c61\u4e2d\u4e0d\u5b58\u5728\u65f6\uff0c\u5c06\u7f3a\u5931\u503c\u586b\u5145\u4e3a0\u3002\u4e5f\u5c31\u662f\u8bf4\uff0c\u5982\u679c\u5728\u4e24\u4e2aDataFrame\u90fd\u7f3a\u5931\uff0c\u90a3\u4e48\u4f9d\u7136\u8fd8\u4f1a\u662fNaN\u3002 \u4e0b\u4f8b\u4e2da2\u662f\u5728 df1 \u548c df2 \u90fd\u7f3a\u5931\u7684\u4f4d\u7f6e\uff0c\u6240\u4ee5\u5373\u4f7f fill_value=0 \uff0ca2\u4ecd\u7136\u662fNaN\u3002 df1 = pd.DataFrame( np.arange(4).reshape((2, 2)), columns=list('ab') ) df2 = pd.DataFrame( np.arange(9).reshape((3, 3)), columns=list('bcd') ) print(df1) # a b # 0 0 1 # 1 2 3 print(df2) # b c d # 0 0 1 2 # 1 3 4 5 # 2 6 7 8 # \u5bf9df1\u548cdf2\u5c31\u7b97\u672f\u548c\uff0c\u5bf9\u5e94\u6ca1\u6709\u884c\u5217\u5171\u540c\u7684\u4ea4\u96c6\u7684\u5730\u65b9\u586b\u5145\u7a7a\u503cNaN\uff0c\u6709\u4ea4\u96c6\u7684\u5730\u65b9\u6c42\u7b97\u672f\u548c\u3002 print(df1.add(df2)) # a b c d # 0 NaN 1.0 NaN NaN # 1 NaN 6.0 NaN NaN # 2 NaN NaN NaN NaN # \u5bf9df1\u548cdf2\u5c31\u7b97\u672f\u548c\uff0c\u5bf9\u5e94\u6ca1\u6709\u884c\u5217\u5171\u540c\u7684\u4ea4\u96c6\u7684\u5730\u65b9\u586b\u5145\u7a7a\u503c0\uff0c\u6709\u4ea4\u96c6\u7684\u5730\u65b9\u6c42\u7b97\u672f\u548c\u3002 print(df1.add(df2, fill_value=0)) # df2.add(df1, fill_value=0) \u8fd4\u56de\u540c\u6837\u7684\u7ed3\u679c # a b c d # 0 0.0 1.0 1.0 2.0 # 1 2.0 6.0 4.0 5.0 # 2 NaN 6.0 7.0 8.0 \u4e0b\u4f8b\u4e2db2\u662f\u5728 df1 \u548c df2 \u90fd\u7f3a\u5931\u7684\u4f4d\u7f6e\uff0c\u6240\u4ee5\u5373\u4f7f fill_value=0 \uff0cb2\u4ecd\u7136\u662fNaN\u3002 df1 = pd.DataFrame( np.arange(4).reshape((2, 2)), columns=list('ab') ) df2 = pd.DataFrame( np.arange(9).reshape((3, 3)), columns=list('acd') ) print(df1) # a b # 0 0 1 # 1 2 3 print(df2) # a c d # 0 0 1 2 # 1 3 4 5 # 2 6 7 8 print(df1.add(df2, fill_value=0)) # a b c d # 0 0.0 1.0 1.0 2.0 # 1 5.0 3.0 4.0 5.0 # 2 6.0 NaN 7.0 8.0 \u4e0b\u4f8b\u4e2d\u6ca1\u6709\u4e24\u4e2aDataFrame\u5171\u540c\u7f3a\u5931\u7684\u60c5\u51b5\u3002 df1 = pd.DataFrame( np.arange(4).reshape((2, 2)), columns=list('ab') ) df2 = pd.DataFrame( np.arange(9).reshape((3, 3)), columns=list('abd') ) print(df1) # a b # 0 0 1 # 1 2 3 print(df2) # a b d # 0 0 1 2 # 1 3 4 5 # 2 6 7 8 print(df1.add(df2, fill_value=0)) # a b d # 0 0.0 2.0 2.0 # 1 5.0 7.0 5.0 # 2 6.0 7.0 8.0 \u4e0b\u9762\u662fSeries\u548cDataFrame\u7684\u7b97\u672f\u65b9\u6cd5\u3002 add\uff0cradd\uff1a\u52a0\u6cd5(+) sub\uff0crsub\uff1a\u51cf\u6cd5(-) div\uff0crdiv\uff1a\u9664\u6cd5(/) floordiv\uff0crfloordiv\uff1a\u6574\u9664(//) mul\uff0crmul\uff1a\u4e58\u6cd5(*) pow\uff0crpow\uff1a\u5e42\u6b21\u65b9(**) \u4e0a\u8ff0\u6bcf\u4e2a\u65b9\u6cd5\u90fd\u6709\u4e00\u4e2a\u4ee5r\u5f00\u5934\u7684\u526f\u672c\uff0c\u8fd9\u4e9b\u526f\u672c\u65b9\u6cd5\u7684\u53c2\u6570\u662f\u7ffb\u8f6c\u7684\u3002\u6bd4\u5982\uff0c\u6c42DataFrame\u5f53\u4e2d\u6240\u6709\u5143\u7d20\u7684\u5012\u6570 1/df \uff0c\u53ef\u4ee5\u5199\u6210df.rdiv(1)\u3002 df1 = pd.DataFrame( np.arange(4).reshape((2, 2)), columns=list('ab') ) df2 = pd.DataFrame( np.arange(9).reshape((3, 3)), columns=list('abd') ) print(df1) # a b # 0 0 1 # 1 2 3 print(df2) # a b d # 0 0 1 2 # 1 3 4 5 # 2 6 7 8 print(df1.radd(df2, fill_value=0)) # a b d # 0 0.0 2.0 2.0 # 1 5.0 7.0 5.0 # 2 6.0 7.0 8.0 print(df1.sub(df2, fill_value=0)) # a b d # 0 0.0 0.0 -2.0 # 1 -1.0 -1.0 -5.0 # 2 -6.0 -7.0 -8.0 print(df1.div(df2, fill_value=0)) # a b d # 0 NaN 1.00 0.0 # 1 0.666667 0.75 0.0 # 2 0.000000 0.00 0.0 print(df1.floordiv(df2, fill_value=0)) # a b d # 0 NaN 1.0 0.0 # 1 0.0 0.0 0.0 # 2 0.0 0.0 0.0 print(df1.mul(df2, fill_value=0)) # a b d # 0 0.0 1.0 0.0 # 1 6.0 12.0 0.0 # 2 0.0 0.0 0.0 print(df1.pow(df2, fill_value=0)) # a b d # 0 1.0 1.0 0.0 # 1 8.0 81.0 0.0 # 2 0.0 0.0 0.0 DataFrame\u548cSeries\u95f4\u7684\u7b97\u672f\u64cd\u4f5c \u00b6 DataFrame\u548cSeries\u95f4\u7684\u7b97\u672f\u64cd\u4f5c\u4e0eNumPy\u4e2d\u4e0d\u540c\u7ef4\u5ea6\u6570\u7ec4\u95f4\u7684\u64cd\u4f5c\u7c7b\u4f3c\u3002 \u4e0d\u540c\u7ef4\u5ea6NumPy\u6570\u7ec4\u95f4\u7684\u7b97\u672f\u64cd\u4f5c \u00b6 \u4ecearr\u4e2d\u51cf\u53bbarr[0]\u65f6\uff0c\u51cf\u6cd5\u6cbf0\u8f74\u5728\u6bcf\u4e00\u884c\u90fd\u8fdb\u884c\u4e86\u64cd\u4f5c\u3002\u8fd9\u5c31\u662f\u6240\u8c13\u7684\u5e7f\u64ad\u673a\u5236\u3002 arr = np.arange(12).reshape((3, 4)) print(arr) # [[ 0 1 2 3] # [ 4 5 6 7] # [ 8 9 10 11]] print(arr[0]) # [0 1 2 3] print(arr - arr[0]) # [[0 0 0 0] # [4 4 4 4] # [8 8 8 8]] DataFrame\u548cSeries\u95f4\u7684\u7b97\u672f\u64cd\u4f5c \u00b6 \u9ed8\u8ba4\u60c5\u51b5\u4e0b\uff0cDataFrame\u548cSeries\u7684\u6570\u5b66\u64cd\u4f5c\u4e2d\u4f1a\u5c06Series\u7684\u7d22\u5f15\u548cDataFrame\u7684*\u5217*\u8fdb\u884c\u5339\u914d\uff0c\u5e76*\u5e7f\u64ad\u5230\u5404\u884c*. \u5982\u679c\u4e00\u4e2a\u7d22\u5f15\u503c\u4e0d\u5728DataFrame\u7684\u5217\u4e2d\uff0c\u4e5f\u4e0d\u5728Series\u7684\u7d22\u5f15\u4e2d\uff0c\u5219\u65b0\u5bf9\u8c61\u4f1a\u6784\u5efa\u5e76\u96c6\u7d22\u5f15\u3002 frame = pd.DataFrame( np.arange(12).reshape((4, 3)), columns=list('bde'), index=['Utah', 'Ohio', 'Texas', 'Oregon'] ) print(frame) # b d e # Utah 0 1 2 # Ohio 3 4 5 # Texas 6 7 8 # Oregon 9 10 11 # \u622a\u53d6frame\u7684\u7b2c0\u884c\uff0c\u5217\u6807\u7b7e\u53d8\u6210\u65b0Serise\u7684\u7d22\u5f15\u3002 series = frame.iloc[0] print(series) # b 0 # d 1 # e 2 # Name: Utah, dtype: int64 series2 = pd.Series( range(3), index=list('bef') ) print(series2) # b 0 # e 1 # f 2 # dtype: int64 # \u622a\u53d6frame\u7684d\u5217\uff0c\u884c\u6807\u7b7e\u53d8\u6210\u65b0Serise\u7684\u7d22\u5f15\u3002 series3 = frame['d'] print(series3) # Utah 1 # Ohio 4 # Texas 7 # Oregon 10 # Name: d, dtype: int64 # \u5c06Series\u7684\u7d22\u5f15\u548cDataFrame\u7684\u5217\u6807\u7b7e\u8fdb\u884c\u5339\u914d\uff0cSeries\u7684\u503c\u6cbfDataFrame\u76840\u8f74\u5e7f\u64ad\u5230\u5404\u4e2a\u884c\u3002 print(frame - series) # frame: series Result: # b d e # b 0 # b d e # Utah 0 1 2 # d 1 # Utah 0 0 0 # Ohio 3 4 5 # e 2 # Ohio 3 3 3 # Texas 6 7 8 # Name: Utah, dtype: int64 # Texas 6 6 6 # Oregon 9 10 11 # Oregon 9 9 9 # \u5c06Series\u7684\u7d22\u5f15\u548cDataFrame\u7684\u5217\u6807\u7b7e\u8fdb\u884c\u5339\u914d\uff0cSeries\u7684\u503c\u6cbfDataFrame\u76840\u8f74\u5e7f\u64ad\u5230\u5404\u4e2a\u884c\uff0c\u7f3a\u5931\u4f4d\u7f6e\u586b\u5145\u7a7a\u503cNaN\u3002 print(frame - series2) # frame: series2 Result: # b d e # b 0 # b d e f # Utah 0 1 2 # e 1 # Utah 0.0 NaN 1.0 NaN # Ohio 3 4 5 # f 2 # Ohio 3.0 NaN 4.0 NaN # Texas 6 7 8 # dtype: int64 # Texas 6.0 NaN 7.0 NaN # Oregon 9 10 11 # Oregon 9.0 NaN 10.0 NaN # \u6539\u4e3a\u5728\u5217\u4e0a\u8fdb\u884c\u5e7f\u64ad\uff0c\u5728\u884c\u4e0a\u5339\u914d\uff0c\u5fc5\u987b\u4f5c\u7528\u5728\u67d0\u79cd\u7b97\u672f\u65b9\u6cd5\u4e0a\u3002\u4e0b\u4f8b\u4e2dSeries\u7684\u503c\u6cbfDataFrame\u76840\u8f74\u5e7f\u64ad\u5230\u5404\u4e2a\u884c\uff08\u6309index\u5339\u914d\u8fdb\u884c\u884c\u64cd\u4f5c\uff09\u3002 print(frame.sub(series3, axis='index')) # \u6216axis=0 # frame: series3 Result: # b d e # Utah 1 # b d e # Utah 0 1 2 # Ohio 4 # Utah -1 0 1 # Ohio 3 4 5 # Texas 7 # Ohio -1 0 1 # Texas 6 7 8 # Oregon 10 # Texas -1 0 1 # Oregon 9 10 11 # Name: d, dtype: int64 # Oregon -1 0 1 \u51fd\u6570\u5e94\u7528\u548c\u6620\u5c04 \u00b6 NumPy\u7684\u901a\u7528\u51fd\u6570\uff08\u9010\u5143\u7d20\u6570\u7ec4\u65b9\u6cd5\uff09\u5bf9pandas\u5bf9\u8c61\uff08DataFrame\u548cSeries\uff09\u4e5f\u6709\u6548\u3002 frame = pd.DataFrame( np.random.randn(4, 3), columns=list('bde'), index=['Utah', 'Ohio', 'Texas', 'Oregon'] ) print(frame) # b d e # Utah 2.737734 -0.379977 0.758933 # Ohio 0.847497 0.839583 -2.192021 # Texas -0.907544 -0.457436 -1.907396 # Oregon 0.389362 0.250170 1.065889 # \u5bf9DataFrame\u5bf9\u8c61\u8ba1\u7b97\u7edd\u5bf9\u503c\u3002 print(np.abs(frame)) # b d e # Utah 2.737734 0.379977 0.758933 # Ohio 0.847497 0.839583 2.192021 # Texas 0.907544 0.457436 1.907396 # Oregon 0.389362 0.250170 1.065889 # f\u8fd4\u56de\u4e00\u4e2a\u6807\u91cf\u503c f = lambda x: x.max() - x.min() # \u6cbf0\u8f74\u5e94\u7528f\uff08\u5bf9\u6bcf\u5217\u7684\u6240\u6709\u884c\u5143\u7d20\u8fdb\u884cf\u8ba1\u7b97\uff09, \u9ed8\u8ba4axis=0 print(frame.apply(f)) # b 3.645278 # d 1.297019 # e 3.257911 # dtype: float64 # \u6cbf1\u8f74\u5e94\u7528f\uff08\u5bf9\u6bcf\u884c\u7684\u6240\u6709\u5217\u5143\u7d20\u8fdb\u884cf\u8ba1\u7b97\uff09 print(frame.apply(f, axis=1)) # Utah 3.117711 # Ohio 3.039518 # Texas 1.449961 # Oregon 0.815720 # dtype: float64 # \u5b9a\u4e49\u51fd\u6570f\uff0c\u8fd4\u56de\u5e26\u6709\u591a\u4e2a\u503c\u7684Series\u3002 def f(x): return pd.Series( [x.min(), x.max()], index=['min', 'max'] ) print(frame.apply(f)) # b d e # min -0.907544 -0.457436 -2.192021 # max 2.737734 0.839583 1.065889 # \u5b9a\u4e49\u51fd\u6570f\uff0c\u4f7f\u7528applymap\u65b9\u6cd5\u683c\u5f0f\u5316\u5b57\u7b26\uff0c\u5c06\u4e00\u4e2a\u9010\u5143\u7d20\u7684\u51fd\u6570\u5e94\u7528\u5230Series\u4e0a\u3002 f = lambda x: '%.2f' % x print(frame.applymap(f)) # # b d e # Utah 2.74 -0.38 0.76 # Ohio 0.85 0.84 -2.19 # Texas -0.91 -0.46 -1.91 # Oregon 0.39 0.25 1.07 print(frame['e'].map(f)) # Utah 0.76 # Ohio -2.19 # Texas -1.91 # Oregon 1.07 # Name: e, dtype: object \u6392\u5e8f\u548c\u6392\u540d \u00b6 \u4f7f\u7528sort_index\u65b9\u6cd5\uff0c\u6309\u884c\u6216\u5217\u7d22\u5f15\u8fdb\u884c\u5b57\u5178\u578b\u6392\u5e8f\uff0c\u8fd4\u56de\u4e00\u4e2a\u65b0\u7684\u6392\u5e8f\u597d\u7684Pandas\u5bf9\u8c61\u3002 Series\u6392\u5e8f \u00b6 \u5bf9Series\u8fdb\u884c\u7d22\u5f15\u6392\u5e8f\u548c\u503c\u6392\u5e8f\u3002 obj = pd.Series( range(4), index=list('dabc') ) print(obj) # d 0 # a 1 # b 2 # c 3 # dtype: int64 print(obj.sort_index()) # a 1 # b 2 # c 3 # d 0 # dtype: int64 # print(obj.sort_values()) # d 0 # a 1 # b 2 # c 3 # dtype: int64 \u9ed8\u8ba4\u60c5\u51b5\u4e0b\uff0c\u6240\u6709\u7684\u7f3a\u5931\u503c\u90fd\u4f1a\u88ab\u6392\u5e8f\u81f3Series\u7684\u5c3e\u90e8\u3002 obj = pd.Series([4, np.nan, 7, np.nan, -3, 2]) print(obj) # 0 4.0 # 1 NaN # 2 7.0 # 3 NaN # 4 -3.0 # 5 2.0 # dtype: float64 print(obj.sort_values()) # 4 -3.0 # 5 2.0 # 0 4.0 # 2 7.0 # 1 NaN # 3 NaN # dtype: float64 DataFrame\u6392\u5e8f \u00b6 frame = pd.DataFrame( [[0, 1, 10, 3], [4, 5, 6, 21], [8, 9, 2, 21]], index=['three', 'one', 'five'], columns=list('dabc') ) print(frame) # d a b c # three 0 1 10 3 # one 4 5 6 21 # five 8 9 2 21 print(frame.index) # Index(['three', 'one', 'five'], dtype='object') # \u9ed8\u8ba40\u8f74\uff0c\u6240\u6709\u884c\u8fdb\u884c\u7d22\u5f15\u9996\u5b57\u6bcd\u5347\u5e8f print(frame.sort_index()) # d a b c # five 8 9 2 21 # one 4 5 6 21 # three 0 1 10 3 # \u6307\u5b9a0\u8f74\uff0c\u6240\u6709\u884c\u8fdb\u884c\u7d22\u5f15\u9996\u5b57\u6bcd\u5347\u5e8f print(frame.sort_index(axis=0)) # d a b c # five 8 9 2 21 # one 4 5 6 21 # three 0 1 10 3 # \u6307\u5b9a0\u8f74\uff0c\u6240\u6709\u884c\u8fdb\u884c\u7d22\u5f15\u9996\u5b57\u6bcd\u964d\u5e8f print(frame.sort_index(axis=0, ascending=False)) # d a b c # three 0 1 10 3 # one 4 5 6 21 # five 8 9 2 21 # \u6307\u5b9a1\u8f74\uff0c\u6240\u6709\u5217\u8fdb\u5217\u7d22\u5f15\u9996\u5b57\u6bcd\u5347\u5e8f print(frame.sort_index(axis=1)) # a b c d # three 1 10 3 0 # one 5 6 21 4 # five 9 2 21 8 # \u6307\u5b9a1\u8f74\uff0c\u6240\u6709\u5217\u8fdb\u5217\u7d22\u5f15\u9996\u5b57\u6bcd\u964d\u5e8f print(frame.sort_index(axis=1, ascending=False)) # d c b a # three 0 3 10 1 # one 4 21 6 5 # five 8 21 2 9 # \u6309\u6307\u5b9a\u5355\u5217\u8fdb\u884c\u503c\u6392\u5e8f\uff08\u964d\u5e8f\uff09 print(frame.sort_values(by=['c'], ascending=False)) # d a b c # one 4 5 6 21 # five 8 9 2 21 # three 0 1 10 3 # \u6309\u6307\u5b9a\u591a\u5217\u8fdb\u884c\u503c\u6392\u5e8f\uff08\u964d\u5e8f\uff09\uff0c\u5148\u5bf9b\u964d\u5e8f\uff0c\u518d\u5bf9d\u964d\u5e8f print(frame.sort_values(by=['c', 'd'], ascending=False)) # d a b c # five 8 9 2 21 # one 4 5 6 21 # three 0 1 10 3 \u6392\u540d \u00b6 **\u6392\u540d**\u662f\u6307\u5bf9\u6570\u7ec4\u4ece1\u5230\u6709\u6548\u6570\u636e\u70b9\u603b\u6570\u5206\u914d\u540d\u6b21\u7684\u64cd\u4f5c\u3002 Series\u548cDataFrame\u7684 rank \u65b9\u6cd5\u662f\u5b9e\u73b0\u6392\u540d\u7684\u65b9\u6cd5\uff0c df.rank(ascending=False, method='max') \u3002 ascending \uff1a\u6392\u540d\u65b9\u5f0f\uff0c\u9ed8\u8ba4\u4ece\u4f4e\u5230\u9ad8\uff0c ascending=False \u8868\u793a\u4ece\u9ad8\u5230\u4f4e\uff1b method \uff1a\u6392\u540d\u65b9\u5f0f\uff0c\u5305\u62ec\uff1a average:\u9ed8\u8ba4\uff0c\u5728\u76f8\u7b49\u5206\u7ec4\u4e2d\uff0c\u4e3a\u5404\u4e2a\u503c\u5206\u914d\u5e73\u5747\u6392\u540d\uff0c\u5373\u76f8\u540c\u503c\u7684\u548c\u9664\u4ee5\u8be5\u503c\u7684\u4e2a\u6570\uff0c\u5373\u4e3a\u8be5\u503c\u7684\u540d\u6b21\u3002 min:\u4f7f\u7528\u6574\u4e2a\u5206\u7ec4\u7684\u6700\u5c0f\u6392\u540d\uff0c\u5373\uff0c\u5bf9\u5e94\u76f8\u540c\u503c\uff0c\u53d6\u5728\u987a\u5e8f\u6392\u540d\u4e2d\u6700\u5c0f\u7684\u90a3\u4e2a\u6392\u540d\u4f5c\u4e3a\u6240\u6709\u8be5\u503c\u7684\u6392\u540d\u3002 max:\u4f7f\u7528\u6574\u4e2a\u5206\u7ec4\u7684\u6700\u5927\u6392\u540d\uff0c\u5373\uff0c\u5bf9\u5e94\u76f8\u540c\u503c\uff0c\u53d6\u5728\u987a\u5e8f\u6392\u540d\u4e2d\u6700\u5927\u7684\u90a3\u4e2a\u6392\u540d\u4f5c\u4e3a\u6240\u6709\u8be5\u503c\u7684\u6392\u540d\u3002 first:\u6309\u503c\u518d\u539f\u59cb\u6570\u636e\u4e2d\u51fa\u73b0\u987a\u5e8f\u5206\u914d\u6392\u540d\uff0c\u8c01\u51fa\u73b0\u7684\u4f4d\u7f6e\u9760\u524d\uff0c\u8c01\u7684\u6392\u540d\u9760\u524d\u3002 dense:\u7c7b\u4f3cmin\u65b9\u6cd5\uff0c\u4f46\u6392\u540d\u603b\u662f\u5728\u7ec4\u95f4\u589e\u52a01\uff0c\u800c\u4e0d\u662f\u7ec4\u4e2d\u76f8\u540c\u7684\u5143\u7d20\u6570\uff0c\u5373\u76f8\u540c\u503c\u7684\u6392\u540d\u76f8\u540c\uff0c\u5176\u4ed6\u4f9d\u6b21\u52a01\u5373\u53ef\u3002 \u9ed8\u8ba4\u60c5\u51b5\u4e0b\uff0crank\u662f\u901a\u8fc7\u201c\u4e3a\u5404\u7ec4\u5206\u914d\u4e00\u4e2a\u5e73\u5747\u6392\u540d\u201d\u7684\u65b9\u5f0f\u7834\u574f\u5e73\u7ea7\u5173\u7cfb # \u6309\u7167\u6bcf\u4e2a\u5143\u7d20\u7684\u5927\u5c0f\u987a\u5e8f\u7ed9\u51fa\u4e00\u4e2a\u5e73\u5747\u6392\u540d obj = pd.Series([7, -5, 7, 4, 2, 0, 4]) print(obj) # 0 7 # 1 -5 # 2 7 # 3 4 # 4 2 # 5 0 # 6 4 # dtype: int64 print(obj.rank()) # 0 6.5 # 1 1.0 # 2 6.5 # 3 4.5 # 4 3.0 # 5 2.0 # 6 4.5 # dtype: float64 # index value rank # 2 -5 1 # 6 0 2 # 5 2 3 # 4 4 4.5 # 7 4 4.5 # 1 7 6.5 # 3 7 6.5 # \u6839\u636e\u5143\u7d20\u7684\u89c2\u5bdf\u987a\u5e8f\u8fdb\u884c\u5206\u914d\u3002\u5143\u7d200\u548c2\u6ca1\u6709\u4f7f\u7528\u5e73\u5747\u6392\u540d6.5\uff0c\u5b83\u4eec\u88ab\u8bbe\u6210\u4e866\u548c7\uff0c\u56e0\u4e3a\u6570\u636e\u4e2d\u6807\u7b7e0\u4f4d\u4e8e\u6807\u7b7e2\u7684\u524d\u9762\u3002 print(obj.rank(method='first')) # 0 6.0 # 1 1.0 # 2 7.0 # 3 4.0 # 4 3.0 # 5 2.0 # 6 5.0 # dtype: float64 # \u6309\u7167max\u8fdb\u884c\u5347\u5e8f\u548c\u964d\u5e8f print(obj.rank(ascending=False, method='max')) print(obj.rank(ascending=True, method='max')) # Original Series Max with inc Max with dec # 0 7 # 0 2.0 (\u6700\u5c0f) # 0 7.0 (\u6700\u5927) # 1 -5 # 1 7.0 (\u6700\u5927) # 1 1.0 (\u6700\u5c0f) # 2 7 # 2 2.0 (\u6700\u5c0f) # 2 7.0 (\u6700\u5927) # 3 4 # 3 4.0 # 3 5.0 # 4 2 # 4 5.0 # 4 3.0 # 5 0 # 5 6.0 # 5 2.0 # 6 4 # 6 4.0 # 6 5.0 # dtype: float64 # dtype: float64 # dtype: float64 frame = pd.DataFrame( {'b': [4.3, 7, -3, 2], 'a': [0, 1, 0, 1], 'c': [-2, 5, 8, -2]} ) print(frame) # b a c # 0 4.3 0 -2 # 1 7.0 1 5 # 2 -3.0 0 8 # 3 2.0 1 -2 # \u6cbf1\u8f74\u5bf9DataFrame\u8fdb\u884crank\u64cd\u4f5c\uff0c\u5373\uff0c\u6bcf\u4e00\u884c\u5404\u5143\u7d20\u8fdb\u884crank\u3002 print(frame.rank(axis='columns')) # axis=1 # b a c # 0 3.0 2.0 1.0 # 1 3.0 1.0 2.0 # 2 1.0 2.0 3.0 # 3 3.0 2.0 1.0 \u542b\u6709\u91cd\u590d\u6807\u7b7e\u7684\u8f74\u7d22\u5f15 \u00b6 \u5c3d\u7ba1\u5f88\u591apandas\u51fd\u6570\uff08\u6bd4\u5982reindex\uff09\u9700\u8981\u6807\u7b7e\u662f\u552f\u4e00\u7684\uff0c\u4f46\u8fd9\u4e2a\u5e76\u4e0d\u662f\u5f3a\u5236\u6027\u7684\u3002 \u7d22\u5f15\u7684is_unique\u5c5e\u6027\u53ef\u4ee5\u68c0\u67e5\u6807\u7b7e\u662f\u5426\u552f\u4e00\u3002 \u5e26\u6709\u91cd\u590d\u7d22\u5f15\u7684\u60c5\u51b5\u4e0b\uff0c\u4e00\u4e2a\u7d22\u5f15\u6807\u7b7e\u4f1a\u4ee5\u5e8f\u5217\u65b9\u5f0f\u8fd4\u56de\u591a\u4e2a\u6761\u76ee\u3002\u4e0d\u91cd\u590d\u7684\u7d22\u5f15\u5219\u4f1a\u4ee5\u6807\u91cf\u503c\u7684\u5f62\u5f0f\u8fd4\u56de\u5355\u4e2a\u6761\u76ee\uff0c\u8fd9\u53ef\u80fd\u4f1a\u4f7f\u4ee3\u7801\u66f4\u590d\u6742\u3002 obj = pd.Series(range(5), index=['a', 'b', 'a', 'c', 'b']) print(obj) # a 0 # b 1 # a 2 # c 3 # b 4 # dtype: int64 print(obj.is_unique) # True print(obj.index.is_unique) # False # \u8fd4\u56de\u91cd\u590d\u7d22\u5f15\u5bf9\u5e94\u503c\u7684\u5e8f\u5217\u3002 print(obj['a']) # a 0 # a 2 # dtype: int64 df = pd.DataFrame(np.random.randn(4, 3), index=['a', 'a', 'b', 'b']) print(df) # 0 1 2 # a -0.726164 0.531540 -0.521611 # a -1.539807 -0.710880 -0.992789 # b -0.975970 -0.470725 0.121958 # b -0.301495 1.072322 -1.542296 print(df.index.is_unique) # False print(df.loc['b']) # 0 1 2 # b -0.520008 0.052574 0.638529 # b -1.928705 -1.099534 -1.605296 \u63cf\u8ff0\u6027\u7edf\u8ba1\u6982\u8ff0\u4e0e\u8ba1\u7b97 \u00b6 pandas\u5305\u542b\u4e86\u4e00\u4e9b\u5e38\u7528\u6570\u5b66\u3001\u7edf\u8ba1\u5b66\u65b9\u6cd5\u3002\u5176\u4e2d\u5927\u90e8\u5206\u5c5e\u4e8e\u5f52\u7ea6\u6216\u6c47\u603b\u7edf\u8ba1\u7684\u7c7b\u522b\uff0c\u8fd9\u4e9b\u65b9\u6cd5\u4eceDataFrame\u7684\u884c\u6216\u5217\u4e2d\u62bd\u53d6\u4e00\u4e2aSeries\u6216\u4e00\u7cfb\u5217\u503c\uff08\u5982\u603b\u548c\u6216\u5e73\u5747\u503c\uff09\u3002 \u4e0eNumPy\u6570\u7ec4\u4e2d\u7684\u7c7b\u4f3c\u65b9\u6cd5\u76f8\u6bd4\uff0cpandas\u5185\u5efa\u4e86\u5904\u7406\u7f3a\u5931\u503c\u7684\u529f\u80fd\u3002 \u5f52\u7ea6\u65b9\u6cd5: sum() \u79ef\u7d2f\u578b\u65b9\u6cd5: cumsun() \u65e2\u4e0d\u662f\u5f52\u7ea6\u578b\u65b9\u6cd5\u4e5f\u4e0d\u662f\u79ef\u7d2f\u578b\u65b9\u6cd5: describe() df = pd.DataFrame( [[1.4, np.nan], [7.1, -4.5], [np.nan, np.nan], [0.75, -1.3]], index=list('abcd'), columns=['one', 'two'] ) print(df) # one two # a 1.40 NaN # b 7.10 -4.5 # c NaN NaN # d 0.75 -1.3 # axis=0, \u8fd4\u56de\u4e00\u4e2a\u6bcf\u5217\u7b97\u672f\u548c\u7684Series print(df.sum()) # one 9.25 # two -5.80 # dtype: float64 # axis=1\u4e14skipna=True, \u8fd4\u56de\u4e00\u4e2a\u6bcf\u884c\u548c\u7684Series, \u5ffd\u7565NA\u503c, \u586b0\u3002 print(df.sum(axis=1)) # a 1.40 # b 2.60 # c 0.00 # d -0.55 # dtype: float64 # \u4e0d\u5ffd\u7565NA\u503c\uff0c\u586bNaN\u3002 print(df.sum(axis=1, skipna=False)) # a NaN # b 2.60 # c NaN # d -0.55 # dtype: float64 # \u53ea\u67091\u7ea7\u7d22\u5f15\uff0c\u6240\u4ee5level=0\u548c\u539f\u7d22\u5f15\u6ca1\u6709\u533a\u522b\uff0cNaN\u586b\u51450\u3002 print(df.groupby(level=0).sum()) # one two # a 1.40 0.0 # b 7.10 -4.5 # c 0.00 0.0 # d 0.75 -1.3 # \u5217one\u7684\u6700\u5927\u503c\u662f\u5728\u7d22\u5f15b, \u5217two\u7684\u6700\u5927\u503c\u662f\u5728\u7d22\u5f15d print(df.idxmax()) # one b # two d # dtype: object print(df.idxmin()) # one d # two b # dtype: object # cumsun\u7684\u610f\u601d\u662f\u7b2cn\u6b21\u7684\u548c\u662fn-1\u6b21\u7684\u548c\u4e0en\u7684\u548c\uff0cone\u5217d\u884c\u7684\u548c\u5c31\u662fone\u5217a\u3001b\u3001c\u3001d\u503c\u7684\u603b\u548c\u3002 print(df.cumsum()) # one two # a 1.40 NaN # b 8.50 -4.5 # c NaN NaN # d 9.25 -5.8 \u901a\u8fc7describe\u4ea7\u751f\u7edf\u8ba1\u4fe1\u606f\uff0c\u6ce8\u610f\uff0c\u6570\u503c\u578b\u548c\u975e\u6570\u503c\u578b\u7684describe\u7684\u4fe1\u606f\u662f\u4e0d\u540c\u7684\u3002 # \u4e00\u6b21\u6027\u4ea7\u751f\u591a\u4e2a\u6c47\u603b\u7edf\u8ba1 print(df.describe()) # one two # count 3.000000 2.000000 # mean 3.083333 -2.900000 # std 3.493685 2.262742 # min 0.750000 -4.500000 # 25% 1.075000 -3.700000 # 50% 1.400000 -2.900000 # 75% 4.250000 -2.100000 # max 7.100000 -1.300000 obj = pd.Series(['a', 'a', 'b', 'c'] * 4) print(obj) # 0 a # 1 a # 2 b # 3 c # 4 a # 5 a # 6 b # 7 c # 8 a # 9 a # 10 b # 11 c # 12 a # 13 a # 14 b # 15 c # dtype: object # \u9488\u5bf9\u975e\u6570\u503c\u578b\u6570\u636e\uff0cdescribe\u4ea7\u751f\u53e6\u4e00\u79cd\u6c47\u603b\u7edf\u8ba1 print(obj.describe()) # count 16 # unique 3 # top a # freq 8 # dtype: object \u76f8\u5173\u6027\u548c\u534f\u65b9\u5dee \u00b6 \u534f\u65b9\u5dee\u4e0e\u76f8\u5173\u7cfb\u6570\u4e5f\u662f\u5728\u65f6\u57df\u5206\u6790\u65f6\u5e38\u89c1\u7684\u4e24\u4e2a\u6982\u5ff5\uff0c\u4ed6\u4eec\u90fd\u662f\u7528\u6765\u63cf\u8ff0\u6570\u636e\u201c\u50cf\u4e0d\u50cf\u201d\u7684\u3002 \u534f\u65b9\u5dee\u7684\u901a\u4fd7\u7406\u89e3\uff1a \u4e24\u4e2a\u53d8\u91cf\u5728\u53d8\u5316\u8fc7\u7a0b\u4e2d\u662f\u540c\u65b9\u5411\u53d8\u5316\u8fd8\u662f\u53cd\u65b9\u5411\u53d8\u5316\uff1f\u76f8\u540c\u6216\u8005\u76f8\u53cd\u7a0b\u5ea6\u5982\u4f55\uff1f \u4f60\u53d8\u5927\uff0c\u540c\u65f6\u6211\u53d8\u5927\uff0c\u8bf4\u660e\u4e24\u4e2a\u53d8\u91cf\u662f\u540c\u5411\u53d8\u5316\uff0c\u8fd9\u65f6\u534f\u65b9\u5dee\u5c31\u662f\u6b63\u7684\u3002 \u4f60\u53d8\u5927\uff0c\u540c\u65f6\u6211\u53d8\u5c0f\uff0c\u8bf4\u660e\u4e24\u4e2a\u53d8\u91cf\u662f\u53cd\u5411\u53d8\u5316\uff0c\u8fd9\u65f6\u534f\u65b9\u5dee\u5c31\u662f\u8d1f\u7684\u3002 \u4ece\u6570\u503c\u770b\uff0c\u534f\u65b9\u5dee\u7684\u6570\u503c\u8d8a\u5927\uff0c\u4e24\u4e2a\u53d8\u91cf\u540c\u5411\u7a0b\u5ea6\u4e5f\u5c31\u8d8a\u5927\u3002\u53cd\u4e4b\u4ea6\u7136\u3002 \u76f8\u5173\u7cfb\u6570\u7684\u901a\u4fd7\u7406\u89e3\uff1a \u7528X\uff0cY\u7684\u534f\u65b9\u5dee\u9664\u4ee5X\u7684\u6807\u51c6\u5dee\u548cY\u7684\u6807\u51c6\u5dee\u3002\u76f8\u5173\u7cfb\u6570\u4e5f\u53ef\u4ee5\u770b\u6210\u534f\u65b9\u5dee\uff0c\u4e00\u79cd\u63d0\u51fa\u4e86\u4e24\u4e2a\u53d8\u91cf\u91cf\u7eb2\u5f71\u54cd\u3001\u6807\u51c6\u5316\u540e\u7684\u7279\u6b8a\u534f\u65b9\u5dee\u3002\u6240\u4ee5\uff1a\u4e5f\u53ef\u4ee5\u53cd\u6620\u4e24\u4e2a\u53d8\u91cf\u53d8\u5316\u65f6\u662f\u540c\u5411\u8fd8\u662f\u53cd\u5411\uff0c\u5982\u679c\u540c\u5411\u53d8\u5316\u5c31\u4e3a\u6b63\uff0c\u53cd\u5411\u53d8\u5316\u5c31\u4e3a\u8d1f\u3002 \u7531\u4e8e\u662f\u6807\u51c6\u7248\u540e\u7684\u534f\u65b9\u5dee\uff0c\u76f8\u5173\u7cfb\u6570\u6d88\u9664\u4e86\u4e24\u4e2a\u53d8\u91cf\u53d8\u5316\u5e45\u5ea6\u7684\u5f71\u54cd\uff0c\u800c\u53ea\u662f\u5355\u7eaf\u53cd\u5e94\u4e24\u4e2a\u53d8\u91cf\u6bcf\u5355\u4f4d\u53d8\u5316\u65f6\u7684\u76f8\u4f3c\u7a0b\u5ea6\u3002 \u603b\u7ed3\uff1a \u5bf9\u4e8e\u4e24\u4e2a\u53d8\u91cfX\u3001Y\uff0c \u5f53\u4ed6\u4eec\u7684\u76f8\u5173\u7cfb\u6570\u4e3a1\u65f6\uff0c\u8bf4\u660e\u4e24\u4e2a\u53d8\u91cf\u53d8\u5316\u65f6\u7684\u6b63\u5411\u76f8\u4f3c\u5ea6\u6700\u5927\u3002 \u5f53\u4ed6\u4eec\u7684\u76f8\u5173\u7cfb\u6570\u4e3a\uff0d1\u65f6\uff0c\u8bf4\u660e\u4e24\u4e2a\u53d8\u91cf\u53d8\u5316\u7684\u53cd\u5411\u76f8\u4f3c\u5ea6\u6700\u5927\u3002 \u968f\u7740\u4ed6\u4eec\u76f8\u5173\u7cfb\u6570\u51cf\u5c0f\uff0c\u4e24\u4e2a\u53d8\u91cf\u53d8\u5316\u65f6\u7684\u76f8\u4f3c\u5ea6\u4e5f\u53d8\u5c0f\uff0c\u5f53\u76f8\u5173\u7cfb\u6570\u4e3a0\u65f6\uff0c\u4e24\u4e2a\u53d8\u91cf\u7684\u53d8\u5316\u8fc7\u7a0b\u6ca1\u6709\u4efb\u4f55\u76f8\u4f3c\u5ea6\uff0c\u4e5f\u5373\u4e24\u4e2a\u53d8\u91cf\u65e0\u5173\u3002 \u5f53\u76f8\u5173\u7cfb\u6570\u7ee7\u7eed\u53d8\u5c0f\uff0c\u5c0f\u4e8e0\u65f6\uff0c\u4e24\u4e2a\u53d8\u91cf\u5f00\u59cb\u51fa\u73b0\u53cd\u5411\u7684\u76f8\u4f3c\u5ea6\uff0c\u968f\u7740\u76f8\u5173\u7cfb\u6570\u7ee7\u7eed\u53d8\u5c0f\uff0c\u53cd\u5411\u76f8\u4f3c\u5ea6\u4f1a\u9010\u6e10\u53d8\u5927\u3002 \u4e0b\u9762\u7684\u4f8b\u5b50\u4f7f\u7528 pandas-datareader\uff1a https://pypi.org/project/pandas-datareader/ https://pydata.github.io/pandas-datareader/) \u5728\u6240\u6709\u4f8b\u5b50\u4e2d\uff0c\u5728\u8ba1\u7b97\u76f8\u5173\u6027\u4e4b\u524d\uff0c\u6570\u636e\u70b9\u5df2\u7ecf\u6309\u6807\u7b7e\u8fdb\u884c\u4e86\u5bf9\u9f50\u3002 \u4e0b\u4f8b\u9700\u8981\u901a\u8fc7pandas-datareader\u5e93\u4eceYahoo! Finance\u4e0a\u83b7\u53d6\u7684\u5305\u542b\u80a1\u4ef7\u548c\u4ea4\u6613\u91cf\u7684DataFrame\u3002 import pandas_datareader.data as web all_data = { ticker: web.get_data_yahoo(ticker) for ticker in ['AAPL', 'IBM', 'MSFT', 'GOOG'] } price = pd.DataFrame( { ticker: data['Adj Close'] for ticker, data in all_data.items() } ) volume = pd.DataFrame( { ticker: data['Volume'] for ticker, data in all_data.items() } ) returns = price.pct_change() print(returns.tail()) # AAPL IBM MSFT GOOG # Date # 2021-08-09 -0.000342 -0.008424 -0.003904 0.007049 # 2021-08-10 -0.003354 0.000920 -0.006555 0.000685 # 2021-08-11 0.001786 0.005305 0.001781 -0.002947 # 2021-08-12 0.020773 0.006614 0.009967 0.005084 # 2021-08-13 0.001410 0.000769 0.010490 0.000119 Series\u7684corr\u65b9\u6cd5\u8ba1\u7b97\u7684\u662f\u4e24\u4e2aSeries\u4e2d\u91cd\u53e0\u7684\u3001\u975eNA\u7684\u3001\u6309\u7d22\u5f15\u5bf9\u9f50\u7684\u503c\u7684\u76f8\u5173\u6027\u3002\u76f8\u5e94\u5730\uff0ccov\u8ba1\u7b97\u7684\u662f\u534f\u65b9\u5dee print(returns['MSFT']) # Date # 2016-08-15 NaN # 2016-08-16 -0.005540 # 2016-08-17 0.002089 # 2016-08-18 0.000695 # 2016-08-19 0.000347 # ... # 2021-08-09 -0.003904 # 2021-08-10 -0.006555 # 2021-08-11 0.001781 # 2021-08-12 0.009967 # 2021-08-13 0.010490 # Name: MSFT, Length: 1259, dtype: float64 # Series\u7684corr\u65b9\u6cd5\u8ba1\u7b97\u7684\u662f\u4e24\u4e2aSeries\u4e2d\u91cd\u53e0\u7684\u3001\u975eNA\u7684\u3001\u6309\u7d22\u5f15\u5bf9\u9f50\u7684\u503c\u7684\u76f8\u5173\u6027\u3002 print(returns['MSFT'].corr(returns['IBM'])) # 0.5175237180581937 # \u7b49\u540c\u5199\u6cd5\uff0cMSFT\u662f\u4e00\u4e2a\u6709\u6548\u7684Python\u5c5e\u6027 print(returns.MSFT.corr(returns.IBM)) # 0.5175237180581937 # Series\u7684cov\u65b9\u6cd5\u8ba1\u7b97\u7684\u662f\u4e24\u4e2aSeries\u4e2d\u503c\u7684\u534f\u65b9\u5dee\u3002 print(returns['MSFT'].cov(returns['IBM'])) # 0.0001452224236764915 DataFrame\u7684corr\u548ccov\u65b9\u6cd5\u4f1a\u5206\u522b\u4ee5DataFrame\u7684\u5f62\u5f0f\u8fd4\u56de\u76f8\u5173\u6027\u548c\u534f\u65b9\u5dee\u77e9\u9635\u3002 print(returns.corr()) # AAPL IBM MSFT GOOG # AAPL 1.000000 0.441111 0.735539 0.661961 # IBM 0.441111 1.000000 0.517524 0.484230 # MSFT 0.735539 0.517524 1.000000 0.775756 # GOOG 0.661961 0.484230 0.775756 1.000000 # \u7ed9corrwith\u65b9\u6cd5\uff0c\u4f20\u5165\u4e00\u4e2aSeries\u65f6\uff0c\u4f1a\u8fd4\u56de\u4e00\u4e2a\u542b\u6709\u4e3a\u6bcf\u5217\u8ba1\u7b97\u76f8\u5173\u6027\u503c\u7684Series print(returns.corrwith(returns['IBM'])) # AAPL 0.441111 # IBM 1.000000 # MSFT 0.517524 # GOOG 0.484230 # dtype: float64 # \u7ed9corrwith\u65b9\u6cd5\uff0c\u4f20\u5165\u4e00\u4e2aDataFrame\u65f6\uff0c\u4f1a\u8ba1\u7b97\u5339\u914d\u5230\u5217\u540d\u7684\u76f8\u5173\u6027\u6570\u503c\u3002\u4e0b\u9762\u662f\u8ba1\u7b97\u4ea4\u6613\u91cf\u767e\u5206\u6bd4\u53d8\u5316\u7684\u76f8\u5173\u6027 print(returns.corrwith(volume)) # AAPL -0.063111 # IBM -0.103721 # MSFT -0.056842 # GOOG -0.119026 # dtype: float64 print(returns.cov()) # AAPL IBM MSFT GOOG # AAPL 0.000361 0.000137 0.000240 0.000211 # IBM 0.000137 0.000268 0.000145 0.000133 # MSFT 0.000240 0.000145 0.000294 0.000224 # GOOG 0.000211 0.000133 0.000224 0.000282 \u552f\u4e00\u503c\u3001\u8ba1\u6570\u548c\u6210\u5458\u5c5e\u6027 \u00b6 obj = pd.Series(['c', 'a', 'd', 'a', 'a', 'a', 'b', 'b', 'c', 'c']) print(obj) # 0 c # 1 a # 2 d # 3 a # 4 a # 5 a # 6 b # 7 b # 8 c # 9 c # dtype: object \u51fd\u6570 unique \u7ed9\u51faSeries\u4e2d\u7684\u552f\u4e00\u503c\u3002 print(obj.unique()) # ['c' 'a' 'd' 'b'] print(obj.sort_values().unique()) # ['a' 'b' 'c' 'd'] # value_counts\u8ba1\u7b97Series\u5305\u542b\u7684\u503c\u7684\u4e2a\u6570 print(obj.value_counts()) # a 4 # c 3 # b 2 # d 1 # dtype: int64 # \u8fd9\u91ccvalue_counts\u4e0d\u662fSeries\u7684\u65b9\u6cd5\uff0c\u662fpandas\u9876\u5c42\u65b9\u6cd5 print(pd.value_counts(obj.values, sort=True)) # a 4 # c 3 # b 2 # d 1 # dtype: int64 print(obj.isin(['b', 'c'])) # 0 True # 1 False # 2 False # 3 False # 4 False # 5 False # 6 True # 7 True # 8 True # 9 True # dtype: bool # \u5c06\u4e0a\u9762\u7684\u7ed3\u679c\u4f5c\u4e3a\u5217\u8868\u8f93\u5165\u7684\u6761\u4ef6\uff0c\u8f93\u51fa\u4e3aTrue\u7684\u7ed3\u679c print(obj[obj.isin(['b', 'c'])]) # 0 c # 6 b # 7 b # 8 c # 9 c # dtype: object \u53c2\u8003: pandas.Index.get_indexer obj1 = pd.Series(['c', 'a', 'd', 'a', 'a', 'a', 'b', 'b', 'c', 'c']) obj2 = pd.Series(['c', 'a', 'b']) print(pd.Index(obj1)) # Index(['c', 'a', 'd', 'a', 'a', 'a', 'b', 'b', 'c', 'c'], dtype='object') print(pd.Index(obj2)) # Index(['c', 'a', 'b'], dtype='object') # \u8fd9\u91cc0\u5bf9\u5e94obj2\u91cc\u9762\u7684c\u5728job1\u7684\u4f4d\u7f6e\uff0c\u4ee5\u6b64\u7c7b\u63a8\uff0c\u751f\u6210\u65b0\u7684\u7d22\u5f15\u5217\u8868 print(pd.Index(obj2).get_indexer(obj1)) # [ 0 1 -1 1 1 1 2 2 0 0] \u8ba1\u7b97DataFrame\u591a\u4e2a\u76f8\u5173\u5217\u7684\u76f4\u65b9\u56fe\u3002 data = pd.DataFrame( { 'Que1': [1, 3, 4, 3, 4], 'Que2': [2, 3, 1, 2, 3], 'Que3': [1, 5, 2, 4, 4], } ) print(data) # Que1 Que2 Que3 # 0 1 2 1 # 1 3 3 5 # 2 4 1 2 # 3 3 2 4 # 4 4 3 4 result = data.apply(pd.value_counts).fillna(0) # \u4e0b\u9762\u7ed3\u679c\u4e2d\u7684\u884c\u6807\u7b7e\u662f\u6240\u6709\u5217\u4e2d\u51fa\u73b0\u7684\u4e0d\u540c\u503c\uff0c\u6570\u503c\u5219\u662f\u8fd9\u4e9b\u4e0d\u540c\u503c\u5728\u6bcf\u4e2a\u5217\u4e2d\u51fa\u73b0\u7684\u6b21\u6570\uff0c\u4f8b\u5982\uff1a\u6570\u5b575\u53ea\u5728Que3\u91cc\u9762\u51fa\u73b0\u4e86\u4e00\u6b21 print(result) # Que1 Que2 Que3 # 1 1.0 1.0 1.0 # 2 0.0 2.0 1.0 # 3 2.0 2.0 0.0 # 4 2.0 0.0 2.0 # 5 0.0 0.0 1.0","title":"Pandas\u5165\u95e8"},{"location":"python/DataAnalysis/ch02/#pandas","text":"\u7ea6\u5b9a\uff1a import numpy as np import pandas as pd from pandas import Series, DataFrame import pandas_datareader as web","title":"Pandas\u5165\u95e8"},{"location":"python/DataAnalysis/ch02/#pandas_1","text":"","title":"pandas\u6570\u636e\u7ed3\u6784\u4ecb\u7ecd"},{"location":"python/DataAnalysis/ch02/#series","text":"Series\u662f\u4e00\u79cd\u4e00\u7ef4\u7684\u6570\u7ec4\u578b\u5bf9\u8c61\uff0c\u5b83\u5305\u542b\u4e86\u4e00\u4e2a\u503c\u5e8f\u5217\uff08\u4e0eNumPy\u4e2d\u7684\u7c7b\u578b\u76f8\u4f3c\uff09\uff0c\u5e76\u4e14\u5305\u542b\u4e86\u6570\u636e\u6807\u7b7e\uff0c\u79f0\u4e3a**\u7d22\u5f15\uff08index\uff09 \u3002 \u4ece\u53e6\u4e00\u4e2a\u89d2\u5ea6\u8003\u8651Series\uff0c\u53ef\u4ee5\u8ba4\u4e3a\u5b83\u662f\u4e00\u4e2a**\u957f\u5ea6\u56fa\u5b9a\u4e14\u6709\u5e8f\u7684\u5b57\u5178 \uff0c\u56e0\u4e3a\u5b83\u5c06\u7d22\u5f15\u503c\u548c\u6570\u636e\u503c\u6309\u4f4d\u7f6e\u914d\u5bf9\u3002\u7d22\u5f15\u5728\u5de6\u8fb9\uff0c\u503c\u5728\u53f3\u8fb9\u3002 obj = pd.Series([4, 7, -5, 3]) print(obj) # 0 4 # 1 7 # 2 -5 # 3 3 # dtype: int64 print(obj.values) # [ 4 7 -5 3 print(obj.index) # RangeIndex(start=0, stop=4, step=1) \u81ea\u5b9a\u4e49index obj = pd.Series([4, 7, -5, 3], index=['d', 'b', 'a', 'c']) print(obj) # d 4 # b 7 # a -5 # c 3 # dtype: int64 print(obj.values) # [ 4 7 -5 3] print(obj.index) # Index(['d', 'b', 'a', 'c'], dtype='object') # \u8f93\u51fa\u7d22\u5f15\u503c\u4e3a'a'\u7684Series\u503c print(obj['a']) # -5 # \u4f7f\u7528\u5e03\u5c14\u503c\u6570\u7ec4\u8fdb\u884c\u8fc7\u6ee4Series\u503c print(obj[obj > 3]) # d 4 # b 7 # dtype: int64 # \u5bf9Series\u503c\u8fdb\u884c\u7b97\u672f\u8fd0\u7b97 print(obj * 2) # d 8 # b 14 # a -10 # c 6 # dtype: int64 # \u5bf9Series\u503c\u8fdb\u884c\u7b97\u672f\u8fd0\u7b97 print(np.exp(obj)) # d 54.598150 # b 1096.633158 # a 0.006738 # c 20.085537 # dtype: float64 # \u66f4\u65b0Series\u6570\u7ec4\u503c obj['a'] = 9 # \u8f93\u51fa\u6307\u5b9a\u7d22\u5f15\u503c\u7684Series\u503c\uff0c\u6ce8\u610f\uff0c\u7d22\u5f15\u6761\u4ef6\u662f\u5217\u8868 print(obj[['a', 'b', 'c']]) # a 9 # b 7 # c 3 # dtype: int64 # \u6ce8\u610f\uff0c\u4e0b\u9762\u7684\u5224\u65ad\u662f\u7d22\u5f15\u503c\uff0c\u975eSeries\u503c print(obj) print(7 in obj) # False print('a' in obj) # True \u901a\u8fc7\u5b57\u5178\u751f\u6210\u4e00\u4e2aSeries\u3002 NaN \uff08not a number\uff09\uff0c\u8fd9\u662fpandas\u4e2d\u6807\u8bb0\u7f3a\u5931\u503c\u6216NA\u503c\u7684\u65b9\u5f0f\u3002 \u5f53\u628a\u5b57\u5178\u4f20\u9012\u7ed9Series\u6784\u9020\u51fd\u6570\u65f6\uff0c\u4ea7\u751f\u7684Series\u7684\u7d22\u5f15\u5c06\u662f\u6392\u5e8f\u597d\u7684\u5b57\u5178\u952e\u3002\u53ef\u4ee5\u5c06\u5b57\u5178\u952e\u6309\u7167\u4f60\u6240\u60f3\u8981\u7684\u987a\u5e8f\u4f20\u9012\u7ed9\u6784\u9020\u51fd\u6570\uff0c\u4ece\u800c\u4f7f\u751f\u6210\u7684Series\u7684\u7d22\u5f15\u987a\u5e8f\u7b26\u5408\u9884\u671f\u3002 \u770b\u4e0b\u4f8b\uff0c\u901a\u8fc7\u5b57\u5178sdata\u751f\u6210Series\u3002 sdata = {'Ohio': 35000, 'Texas': 71000, 'Oregon': 16000, 'Utah': 5000} obj3 = pd.Series(sdata) print(sdata) # {'Ohio': 35000, 'Texas': 71000, 'Oregon': 16000, 'Utah': 5000} print(obj3) # Ohio 35000 # Texas 71000 # Oregon 16000 # Utah 5000 # dtype: int64 \u901a\u8fc7\u6307\u5b9a\u7d22\u5f15states\u53bb\u5339\u914d\u5b57\u5178sdata\u751f\u6210\u57fa\u4e8e\u65b0\u7d22\u5f15states\u7684Series\u3002 states = ['California', 'Ohio', 'Oregon', 'Texas'] obj4 = pd.Series(sdata, index=states) print(obj4) # California NaN # Ohio 35000.0 # Oregon 16000.0 # Texas 71000.0 # dtype: float64 \u5bf9Series\u8fdb\u884c\u5e03\u5c14\u503c\u5224\u65ad\u3002 print(pd.isnull(obj4)) # California True # Ohio False # Oregon False # Texas False # dtype: bool print(pd.notnull(obj4)) # California False # Ohio True # Oregon True # Texas True # dtype: bool \u5bf9Series\u8fdb\u884c\u5e03\u5c14\u503c\u5224\u65ad\u3002 print(obj4.isnull) # print(obj4.notnull) # Series\u7684\u81ea\u52a8\u5bf9\u9f50\u7d22\u5f15\uff0c\u4e0e\u6570\u636e\u5e93\u7684join\u64cd\u4f5c\u662f\u975e\u5e38\u76f8\u4f3c\u3002 print(\"obj3 \\n\", obj3) # obj3 # Ohio 35000 # Texas 71000 # Oregon 16000 # Utah 5000 # dtype: int64 print(\"obj4 \\n\", obj4) # obj4 # California NaN # Ohio 35000.0 # Oregon 16000.0 # Texas 71000.0 # dtype: float64 print(\"obj3+obj4 \\n\", obj3 + obj4) # obj3+obj4 # California NaN # Ohio 70000.0 # Oregon 32000.0 # Texas 142000.0 # Utah NaN # dtype: float64 # \u4e0b\u9762\u662fobj3\u548cobj4\u7684\u503c\uff0c\u5e2e\u52a9\u7406\u89e3\u4e0a\u9762obj3 + obj4\u7684\u64cd\u4f5c\u3002 # obj3 obj4 # Ohio 35000 California NaN # Texas 71000 Ohio 35000.0 # Oregon 16000 Oregon 16000.0 # Utah 5000 Texas 71000.0 # dtype: int64 dtype: float64 Series\u5bf9\u8c61\u81ea\u8eab\u548c\u5176\u7d22\u5f15\u90fd\u6709name\u5c5e\u6027\u3002 obj4.name = 'population' obj4.index.name = 'state' print(obj4) # state # California NaN # Ohio 35000.0 # Oregon 16000.0 # Texas 71000.0 # Name: population, dtype: float64 \u66ff\u6362Series\u7684\u7d22\u5f15\u540d\u3002 obj = pd.Series([4, 7, -5, 3], index=['d', 'b', 'a', 'c']) print(obj) obj.index = ['Bob', 'Steve', 'Jeff', 'Ryan'] print(obj) # Bob 4 # Steve 7 # Jeff -5 # Ryan 3 # dtype: int64","title":"Series"},{"location":"python/DataAnalysis/ch02/#dataframe","text":"DataFrame\u8868\u793a\u7684\u662f\u77e9\u9635\u7684\u6570\u636e\u8868\uff0c\u5b83\u5305\u542b\u5df2\u6392\u5e8f\u7684\u5217\u96c6\u5408\uff0c\u6bcf\u4e00\u5217\u53ef\u4ee5\u662f\u4e0d\u540c\u7684\u503c\u7c7b\u578b\uff08\u6570\u503c\u3001\u5b57\u7b26\u4e32\u3001\u5e03\u5c14\u503c\u7b49\uff09\u3002 DataFrame\u65e2\u6709\u884c\u7d22\u5f15\u4e5f\u6709\u5217\u7d22\u5f15\uff0c\u5b83\u53ef\u4ee5\u88ab\u89c6\u4e3a\u4e00\u4e2a\u5171\u4eab\u76f8\u540c\u7d22\u5f15\u7684Series\u7684\u5b57\u5178\uff0c\u6bd4\u5982\u6240\u6709\u5217\u5171\u4eab\u540c\u4e00\u4e2a\u5217\u7d22\u5f15\u3002 \u5728DataFrame\u4e2d\uff0c\u6570\u636e\u88ab\u5b58\u50a8\u4e3a\u4e00\u4e2a\u4ee5\u4e0a\u7684\u4e8c\u7ef4\u5757\uff0c\u800c\u4e0d\u662f\u5217\u8868\u3001\u5b57\u5178\u6216\u5176\u4ed6\u4e00\u7ef4\u6570\u7ec4\u7684\u96c6\u5408\u3002 DataFrame\u662f\u4e8c\u7ef4\u7684\uff0c\u4f46\u53ef\u4ee5\u5229\u7528**\u5206\u5c42\u7d22\u5f15**\u5728DataFrame\u4e2d\u5c55\u73b0\u66f4\u9ad8\u7ef4\u5ea6\u7684\u6570\u636e\u3002 \u4eceDataFrame\u4e2d\u9009\u53d6\u7684\u5217\u662f\u6570\u636e\u7684\u89c6\u56fe\uff0c\u800c\u4e0d\u662f\u62f7\u8d1d \u3002\u56e0\u6b64\uff0c\u5bf9Series\u7684\u4fee\u6539\u4f1a\u6620\u5c04\u5230DataFrame\u4e2d\u3002\u5982\u679c\u9700\u8981\u590d\u5236\uff0c\u5219\u5e94\u5f53\u663e\u5f0f\u5730\u4f7f\u7528Series\u7684copy\u65b9\u6cd5\u3002","title":"DataFrame"},{"location":"python/DataAnalysis/ch02/#dataframe_1","text":"\u57fa\u4e8e\u5b57\u5178 data \u4ea7\u751f\u7684DataFrame\u4f1a\u81ea\u52a8\u4e3aSereies\u5206\u914d\u7d22\u5f15\uff0c\u5e76\u4e14\u5217\u4f1a\u6309\u7167\u6392\u5e8f\u7684\u987a\u5e8f\u6392\u5217\u3002 data = { 'state': ['Ohio', 'Ohio', 'Ohio', 'Nevada', 'Nevada', 'Nevada'], 'year': [2000, 2001, 2002, 2001, 2002, 2003], 'pop': [1.5, 1.7, 3.6, 2.4, 2.9, 3.2] } frame = pd.DataFrame(data) print(frame) # state year pop # 0 Ohio 2000 1.5 # 1 Ohio 2001 1.7 # 2 Ohio 2002 3.6 # 3 Nevada 2001 2.4 # 4 Nevada 2002 2.9 # 5 Nevada 2003 3.2 # \u5bf9\u4e8e\u5927\u578bDataFrame, head\u65b9\u6cd5\u5c06\u4f1a\u53ea\u9009\u51fa\u5934\u90e8\u7684\u82e5\u5e72\u884c, \u9ed8\u8ba4\u662f\u524d\u4e94\u884c\u3002 print(frame.head(3)) # state year pop # 0 Ohio 2000 1.5 # 1 Ohio 2001 1.7 # 2 Ohio 2002 3.6 \u5982\u679c\u6307\u5b9a\u4e86\u5217\u7684\u987a\u5e8f\uff0cDataFrame\u7684\u5217\u5c06\u4f1a\u6309\u7167\u6307\u5b9a\u987a\u5e8f\u6392\u5217\u3002 frame = pd.DataFrame(data, columns=['year', 'state', 'pop']) print(frame) # year state pop # 0 2000 Ohio 1.5 # 1 2001 Ohio 1.7 # 2 2002 Ohio 3.6 # 3 2001 Nevada 2.4 # 4 2002 Nevada 2.9 # 5 2003 Nevada 3.2 \u5982\u679c\u4f20\u7684\u5217\uff08 debt \uff09\u4e0d\u5305\u542b\u5728\u5b57\u5178\uff08 data \uff09\u4e2d\uff0c\u5c06\u4f1a\u5728\u7ed3\u679c\u4e2d\u51fa\u73b0\u7f3a\u5931\u503c\u3002 frame2 = pd.DataFrame( data, columns=['year', 'state', 'pop', 'debt'], index=['one', 'two', 'three', 'four', 'five', 'six'] ) print(frame2) # year state pop debt # one 2000 Ohio 1.5 NaN # two 2001 Ohio 1.7 NaN # three 2002 Ohio 3.6 NaN # four 2001 Nevada 2.4 NaN # five 2002 Nevada 2.9 NaN # six 2003 Nevada 3.2 NaN \u9009\u53d6\u884c, \u53ef\u4ee5\u901a\u8fc7\u4f4d\u7f6e\u6216\u884c\u7d22\u5f15\u6807\u7b7e loc \u8fdb\u884c\u9009\u53d6\u3002 print(frame2.loc['three']) # year 2002 # state Ohio # pop 3.6 # debt NaN # Name: three, dtype: object DataFrame\u4e2d\u7684\u4e00\u5217\uff0c\u53ef\u4ee5\u6309\u5b57\u5178\u578b\u6807\u8bb0\u6216\u5c5e\u6027\u90a3\u6837\u68c0\u7d22\u4e3aSeries\u3002 frame2[colunm] \u5bf9\u4e8e\u4efb\u610f\u5217\u540d\u5747\u6709\u6548\uff0c\u4f46\u662f frame2.column \u53ea\u5728\u5217\u540d\u662f\u6709\u6548\u7684Python\u53d8\u91cf\u540d\u65f6\u6709\u6548\u3002 \u8fd4\u56de\u7684Series\u4e0e\u539fDataFrame\u6709\u76f8\u540c\u7684\u7d22\u5f15\uff0c\u4e14Series\u7684 name \u5c5e\u6027\u4e5f\u4f1a\u88ab\u5408\u7406\u5730\u8bbe\u7f6e\u3002 print(frame2['state']) # one Ohio # two Ohio # three Ohio # four Nevada # five Nevada # six Nevada # Name: state, dtype: object print(frame2.state) # \u5c5e\u6027\u578b\u8fde\u63a5 # one Ohio # two Ohio # three Ohio # four Nevada # five Nevada # six Nevada # Name: state, dtype: object \u5217\u7684\u5f15\u7528\u662f\u53ef\u4ee5\u4fee\u6539\u7684\u3002\u503c\u7684\u957f\u5ea6\u5fc5\u987b\u548cDataFrame\u7684\u957f\u5ea6\u76f8\u5339\u914d,\u6bd4\u5982\uff0c\u4e0b\u4f8b\u4e2d np.arange(6.) \u548c frame2['debt'] \u7684\u957f\u5ea6\u90fd\u662f6\u3002 frame2['debt'] = 16.5 print(frame2) # Name: state, dtype: object # year state pop debt # one 2000 Ohio 1.5 16.5 # two 2001 Ohio 1.7 16.5 # three 2002 Ohio 3.6 16.5 # four 2001 Nevada 2.4 16.5 # five 2002 Nevada 2.9 16.5 # six 2003 Nevada 3.2 16.5 frame2['debt'] = np.arange(6.) print(frame2) # year state pop debt # one 2000 Ohio 1.5 0.0 # two 2001 Ohio 1.7 1.0 # three 2002 Ohio 3.6 2.0 # four 2001 Nevada 2.4 3.0 # five 2002 Nevada 2.9 4.0 # six 2003 Nevada 3.2 5.0 \u5982\u679c\u5c06Series\u8d4b\u503c\u7ed9\u4e00\u5217\u65f6\uff0cSeries\u7684\u7d22\u5f15\u5c06\u4f1a\u6309\u7167DataFrame\u7684\u7d22\u5f15\u91cd\u65b0\u6392\u5217\uff0c\u5e76\u5728\u7a7a\u7f3a\u7684\u5730\u65b9\u586b\u5145\u7f3a\u5931\u503c val = pd.Series([-1.2, -1.5, -1.7], index=['two', 'four', 'five']) frame2['debt'] = val print(frame2) # year state pop debt # one 2000 Ohio 1.5 NaN # two 2001 Ohio 1.7 -1.2 # three 2002 Ohio 3.6 NaN # four 2001 Nevada 2.4 -1.5 # five 2002 Nevada 2.9 -1.7 # six 2003 Nevada 3.2 NaN \u5982\u679c\u88ab\u8d4b\u503c\u7684\u5217( eastern \u5217)\u5e76\u4e0d\u5b58\u5728\uff0c\u5219\u4f1a\u751f\u6210\u4e00\u4e2a\u65b0\u7684\u5217\u3002 frame2.state == 'Ohio' \u8fd4\u56de\u7684\u662f\u5e03\u5c14\u503c\uff0c\u8d4b\u503c\u7ed9 eastern \u3002 frame2['eastern'] = frame2.state == 'Ohio' print(frame2) # year state pop debt eastern # one 2000 Ohio 1.5 NaN True # two 2001 Ohio 1.7 -1.2 True # three 2002 Ohio 3.6 NaN True # four 2001 Nevada 2.4 -1.5 False # five 2002 Nevada 2.9 -1.7 False # six 2003 Nevada 3.2 NaN False print(frame2.eastern) # one True # two True # three True # four False # five False # six False # Name: eastern, dtype: bool del \u5173\u952e\u5b57\u53ef\u4ee5\u50cf\u5728\u5b57\u5178\u4e2d\u90a3\u6837\u5bf9DataFrame\u5220\u9664\u5217\u3002 del frame2['eastern'] print(frame2.columns) # Index(['year', 'state', 'pop', 'debt'], dtype='object')","title":"\u7531\u5b57\u5178\u6784\u6210DataFrame"},{"location":"python/DataAnalysis/ch02/#dataframe_2","text":"pandas\u4f1a\u5c06\u5b57\u5178\u7684\u952e\u4f5c\u4e3a\u5217('Nevada', etc.)\uff0c\u5c06\u5185\u90e8\u5b57\u5178\u7684\u952e\u4f5c\u4e3a\u884c\u7d22\u5f15(2001, etc.) pop = { 'Nevada': { 2001: 2.4, 2002: 2.9 }, 'Ohio': { 2000: 1.5, 2001: 1.7, 2002: 3.6 } } # \u4e0d\u6307\u5b9a\u7d22\u5f15\uff0c\u9ed8\u8ba4\u4f7f\u7528\u5b57\u5178\u7d22\u5f15 frame3 = pd.DataFrame(pop) print(frame3) # Nevada Ohio # 2001 2.4 1.7 # 2002 2.9 3.6 # 2000 NaN 1.5 # \u6307\u5b9a\u5b57\u5178\u67d0\u5217\u4f5c\u4e3a\u7d22\u5f15 print(pd.DataFrame(pop, index=[2001, 2002, 2003])) # Nevada Ohio # 2001 2.4 1.7 # 2002 2.9 3.6 # 2003 NaN NaN # \u6307\u5b9a\u4e0d\u76f8\u5e72\u7d22\u5f15 print(pd.DataFrame(pop, index=['a', 'b', 'c'])) # Nevada Ohio # a NaN NaN # b NaN NaN # c NaN NaN \u8f6c\u7f6e\u64cd\u4f5c\uff08\u8c03\u6362\u884c\u548c\u5217\uff09 print(frame3.T) # 2001 2002 2000 # Nevada 2.4 2.9 NaN # Ohio 1.7 3.6 1.5","title":"\u4f7f\u7528\u5d4c\u5957\u5b57\u5178\u6784\u5efaDataFrame"},{"location":"python/DataAnalysis/ch02/#seriesdataframe","text":"frame3['Ohio'][:-1] \u662f\u503c\u4e3a Ohio \u7684Series\u76840~\u5012\u6570\u7b2c\u4e00\u4e2a\u5143\u7d20\uff08\u4e0d\u542b\uff09\uff0c\u4e00\u51713\u4e2a\u3002 frame3['Nevada'][:2] \u662f\u503c\u4e3a Nevada \u7684Series\u7684\u524d2\u4e2a\u5143\u7d20\u3002 pdata = { 'Ohio': frame3['Ohio'][:-1], 'Nevada': frame3['Nevada'][:2] } print(pd.DataFrame(pdata)) # Ohio Nevada # 2001 1.7 2.4 # 2002 3.6 2.9 \u6307\u5b9aDataframe frame3 \u7684\u5217\u540d\u3002 frame3.index.name = 'year' frame3.columns.name = 'state' print(frame3) # state Nevada Ohio # year # 2001 2.4 1.7 # 2002 2.9 3.6 # 2000 NaN 1.5 \u53ea\u8f93\u51faDataframe\u7684\u503c frame3.values \uff0c\u662f\u4e00\u4e2a\u4e8c\u7ef4\u6570\u7ec4\u3002 print(frame3.values) # [[2.4 1.7] # [2.9 3.6] # [nan 1.5]] \u53ea\u8f93\u51faDataframe\u7684\u503c frame2.values \uff0c\u662f\u4e00\u4e2a\u4e8c\u7ef4\u6570\u7ec4\u3002 print(frame2) # year state pop debt # one 2000 Ohio 1.5 NaN # two 2001 Ohio 1.7 -1.2 # three 2002 Ohio 3.6 NaN # four 2001 Nevada 2.4 -1.5 # five 2002 Nevada 2.9 -1.7 # six 2003 Nevada 3.2 NaN print(frame2.values) # [[2000 'Ohio' 1.5 nan] # [2001 'Ohio' 1.7 -1.2] # [2002 'Ohio' 3.6 nan] # [2001 'Nevada' 2.4 -1.5] # [2002 'Nevada' 2.9 -1.7] # [2003 'Nevada' 3.2 nan]]","title":"\u4f7f\u7528\u542bSeries\u7684\u5b57\u5178\u6784\u9020DataFrame"},{"location":"python/DataAnalysis/ch02/#_1","text":"pandas\u4e2d\u7684**\u7d22\u5f15\u5bf9\u8c61**\u662f\u7528\u4e8e\u5b58\u50a8\u8f74\u6807\u7b7e\u548c\u5176\u4ed6\u5143\u6570\u636e\u7684\uff08\u4f8b\u5982\u8f74\u540d\u79f0\u6216\u6807\u7b7e\uff09\u3002 \u5728\u6784\u9020Series\u6216DataFrame\u65f6\uff0c\u4f60\u6240\u4f7f\u7528\u7684\u4efb\u610f\u6570\u7ec4\u6216\u6807\u7b7e\u5e8f\u5217\u90fd\u53ef\u4ee5\u5728\u5185\u90e8\u8f6c\u6362\u4e3a\u7d22\u5f15\u5bf9\u8c61\u3002 \u7d22\u5f15\u5bf9\u8c61\u662f\u4e0d\u53ef\u53d8\u7684\u3002 \u9664\u4e86\u7c7b\u4f3c\u6570\u7ec4\uff0c\u7d22\u5f15\u5bf9\u8c61\u4e5f\u50cf\u4e00\u4e2a\u56fa\u5b9a\u5927\u5c0f\u7684\u96c6\u5408\u3002\u4e0ePython\u96c6\u5408\u4e0d\u540c\uff0c pandas\u7d22\u5f15\u5bf9\u8c61\u53ef\u4ee5\u5305\u542b\u91cd\u590d\u6807\u7b7e \u3002 \u56e0\u4e3a\u4e00\u4e9b\u64cd\u4f5c\u4f1a\u4ea7\u751f\u5305\u542b\u7d22\u5f15\u5316\u6570\u636e\u7684\u7ed3\u679c\uff0c\u7406\u89e3\u7d22\u5f15\u5982\u4f55\u5de5\u4f5c\u8fd8\u662f\u5f88\u91cd\u8981\u7684\u3002 \u4e0b\u4f8b\u6f14\u793a\u4e86\u5982\u4f55\u8bfb\u53d6Dataframe\u7684\u7d22\u5f15\u503c\u3002 obj = pd.Series(range(3), index=['a', 'b', 'c']) index = obj.index print(obj) # a 0 # b 1 # c 2 # dtype: int64 print(index) # Index(['a', 'b', 'c'], dtype='object') print(index[1:]) # Index(['b', 'c'], dtype='object') \u4e0b\u4f8b\u6f14\u793a\u4e86\u901a\u8fc7\u4e00\u4e2a\u6307\u5b9a\u7684Dataframe\u7d22\u5f15 labels \u6765\u751f\u6210Dataframe obj2 \u3002 labels = pd.Index(np.arange(3)) print(labels) # Int64Index([0, 1, 2], dtype='int64') obj2 = pd.Series([1.5, -2.5, 0], index=labels) print(obj2) # 0 1.5 # 1 -2.5 # 2 0.0 # dtype: float64 print(obj2.index is labels) # True \u4e0b\u4f8b\u6f14\u793a\u4e86\u4e0d\u6307\u5b9a\u7d22\u5f15\uff0c\u9ed8\u8ba4\u4f7f\u7528\u5b57\u5178\u7d22\u5f15\u6765\u521b\u5efaDataframe\u3002 pop = { 'Nevada': { 2001: 2.4, 2002: 2.9 }, 'Ohio': { 2000: 1.5, 2001: 1.7, 2002: 3.6 } } frame3 = pd.DataFrame(pop) print(frame3) # Nevada Ohio # 2001 2.4 1.7 # 2002 2.9 3.6 # 2000 NaN 1.5 print(frame3) # state Nevada Ohio # year # 2001 2.4 1.7 # 2002 2.9 3.6 # 2000 NaN 1.5 print(frame3.columns) # Index(['Nevada', 'Ohio'], dtype='object', name='state') print(frame3.index) # Int64Index([2001, 2002, 2000], dtype='int64', name='year') print('Ohio' in frame3.columns) # True print(2003 in frame3.index) # False pandas\u7d22\u5f15\u5bf9\u8c61\u5141\u8bb8\u5305\u542b\u91cd\u590d\u6807\u7b7e\u3002\u6839\u636e\u91cd\u590d\u6807\u7b7e\u8fdb\u884c\u7b5b\u9009\uff0c\u4f1a\u9009\u53d6\u6240\u6709\u91cd\u590d\u6807\u7b7e\u5bf9\u5e94\u7684\u6570\u636e\u3002 dup_labels = pd.Index(['foo', 'foo', 'bar', 'bar']) print(dup_labels) # Index(['foo', 'foo', 'bar', 'bar'], dtype='object') \u4e00\u4e9b\u5e38\u7528\u7d22\u5f15\u5bf9\u8c61\u7684\u65b9\u6cd5\u548c\u5c5e\u6027\u3002 obj1 = pd.Series(range(3), index=['a', 'b', 'c']) index1 = obj1.index obj2 = pd.Series(range(3), index=['c', 'f', 'g']) index2 = obj2.index print(index1) # Index(['a', 'b', 'c'], dtype='object') print(index2) # Index(['c', 'f', 'g'], dtype='object') append \u65b9\u6cd5\uff1a\u5c06\u5916\u90e8\u7684\u7d22\u5f15\u5bf9\u8c61\u7c98\u8d34\u5230\u539f\u7d22\u5f15\u540e\uff0c\u4ea7\u751f\u4e00\u4e2a\u65b0\u7684\u7d22\u5f15\u3002 \u63a5\u4e0a\u4f8b\uff0c\u628a index2 \u5bf9\u8c61\u8ffd\u52a0\u5230 index1 \u5bf9\u8c61\u3002 print(index1.append(index2)) # Index(['a', 'b', 'c', 'c', 'f', 'g'], dtype='object') difference \u65b9\u6cd5: \u8ba1\u7b972\u4e2a\u7d22\u5f15\u7684\u5dee\u96c6\u3002 print(index1.difference(index2)) # Index(['a', 'b'], dtype='object') intersection \u65b9\u6cd5: \u8ba1\u7b972\u4e2a\u7d22\u5f15\u7684\u4ea4\u96c6\u3002 print(index1.intersection(index2)) # Index(['c'], dtype='object') union \u65b9\u6cd5: \u8ba1\u7b972\u4e2a\u7d22\u5f15\u7684\u5e76\u96c6\uff08\u53bb\u91cd\uff09\u3002 print(index1.union(index2)) # Index(['a', 'b', 'c', 'f', 'g'], dtype='object') isin \u65b9\u6cd5: \u8ba1\u7b97\u8868\u793a\u6bcf\u4e00\u4e2a\u503c\u662f\u5426\u5728\u4f20\u503c\u5bb9\u5668\u4e2d\uff0c\u8fd4\u56de\u7684\u662f\u4e00\u4e2a\u5e03\u5c14\u6570\u7ec4\u3002 print(index1.isin(index2)) # [False False True] delete \u65b9\u6cd5: \u5c06\u4f4d\u7f6ei\uff08\u4ece0\u5f00\u59cb\u7f16\u53f7\uff09\u7684\u5143\u7d20\u5220\u9664\uff0c\u5e76\u4ea7\u751f\u65b0\u7684\u7d22\u5f15\u3002 print(index1.delete('b')) # IndexError: arrays used as indices must be of integer (or boolean) type print(index1.delete(1)) # Index(['a', 'c'], dtype='object') print(index1) # Index(['a', 'b', 'c'], dtype='object') drop \u65b9\u6cd5: \u6839\u636e\u4f20\u53c2\u5220\u9664\u6307\u5b9a\u7d22\u5f15\u503c\uff0c\u5e76\u4ea7\u751f\u65b0\u7684\u7d22\u5f15, \u5bf9\u6bd4\u548cdelete\u7684\u533a\u522b\uff0c delete \u65b9\u6cd5\u662f\u8f93\u5165\u4f4d\u7f6e\uff0c drop \u65b9\u6cd5\u662f\u8f93\u5165\u7d22\u5f15\u540d\u79f0\u3002 print(index2.drop(1)) # KeyError: '[1] not found in axis' print(index2.drop('f')) # Index(['c', 'g'], dtype='object') print(index2) # Index(['c', 'f', 'g'], dtype='object') insert \u65b9\u6cd5: \u5728\u4f4d\u7f6e i \u63d2\u5165\u5143\u7d20\uff0c\u5e76\u4ea7\u751f\u65b0\u7684\u7d22\u5f15\u3002 print(index1.insert(1, 'e')) # Index(['a', 'e', 'b', 'c'], dtype='object') print(index1) # Index(['a', 'b', 'c'], dtype='object') is_monotonic \u65b9\u6cd5: \u5982\u679c\u7d22\u5f15\u5e8f\u5217\u9012\u589e\uff0c\u5219\u8fd4\u56de True \u3002 print(index1.is_monotonic) # True print(index1.insert(1, 'e').is_monotonic) # False is_unique \u65b9\u6cd5: \u5982\u679c\u7d22\u5f15\u5e8f\u5217\u552f\u4e00\u5219\u8fd4\u56de True \u3002 print(index1.is_unique) # True print(index1.append(index2).is_unique) # False unique \u65b9\u6cd5: \u8ba1\u7b97\u7d22\u5f15\u7684\u552f\u4e00\u503c\u5e8f\u5217\uff08\u5bf9\u6bd4Union\uff09\u3002 print(index1.unique()) # Index(['a', 'b', 'c'], dtype='object') print(index1.append(index2).unique()) # Index(['a', 'b', 'c', 'f', 'g'], dtype='object')","title":"\u7d22\u5f15\u5bf9\u8c61"},{"location":"python/DataAnalysis/ch02/#pandas_2","text":"","title":"pandas\u57fa\u672c\u529f\u80fd"},{"location":"python/DataAnalysis/ch02/#_2","text":"Series\u8c03\u7528 reindex \u65b9\u6cd5\u65f6\uff0c\u4f1a\u5c06\u6570\u636e\u6309\u7167\u65b0\u7684\u7d22\u5f15\u8fdb\u884c\u6392\u5217\uff0c\u5982\u679c\u67d0\u4e2a\u7d22\u5f15\u503c\u4e4b\u524d\u5e76\u4e0d\u5b58\u5728\uff0c\u5219\u4f1a\u5f15\u5165\u7f3a\u5931\u503c\u3002 \u4e0b\u4f8b\u4e2d\uff0c\u5bf9 obj1 \u505a reindex \uff0c reindex \u65b9\u6cd5\u4f1a\u521b\u5efa\u4e00\u4e2a\u65b0\u7d22\u5f15\u5bf9\u8c61 obj2 \uff0c\u7d22\u5f15\u503c e \u4e4b\u524d\u5e76\u4e0d\u5b58\u5728\uff0c\u6240\u4ee5\u586b\u5165\u7f3a\u5931\u503c\u3002 \u5982\u679c\u5bf9obj1\u505a reindex \u65f6\u6307\u5b9a method='ffill' \uff0c\u4f1a\u62a5\u9519 index must be monotonic increasing or decreasing \u3002 obj1 = pd.Series([4.5, 7.2, -5.3, 3.6], index=['d', 'b', 'a', 'c']) print(obj1) # d 4.5 # b 7.2 # a -5.3 # c 3.6 # dtype: float64 obj2 = obj1.reindex(['a', 'b', 'c', 'd', 'e']) print(obj2) # a -5.3 # b 7.2 # c 3.6 # d 4.5 # e NaN # dtype: float64 obj2 = obj1.reindex(['a', 'b', 'c', 'd', 'e'], method='ffill') # ValueError: index must be monotonic increasing or decreasing \u5bf9\u4e8e\u987a\u5e8f\u6570\u636e\uff0c\u6bd4\u5982\u65f6\u95f4\u5e8f\u5217\uff0c\u5728\u91cd\u5efa\u7d22\u5f15\u65f6\u53ef\u80fd\u4f1a\u9700\u8981\u8fdb\u884c\u63d2\u503c\u6216\u586b\u503c\u3002 ffill \u65b9\u6cd5\u5728\u91cd\u5efa\u7d22\u5f15\u65f6\u63d2\u503c\uff0c\u5c06\u503c\u524d\u5411\u586b\u5145\u3002 obj3 = pd.Series(['blue', 'purple', 'yellow'], index=[0, 2, 4]) print(obj3.reindex(range(6), method='ffill')) # 0 blue # 1 blue # 2 purple # 3 purple # 4 yellow # 5 yellow # dtype: object \u5728DataFrame\u4e2d\uff0c reindex \u53ef\u4ee5\u6539\u53d8\u884c\u7d22\u5f15\u3001\u5217\u7d22\u5f15\uff0c\u4e5f\u53ef\u4ee5\u540c\u65f6\u6539\u53d8\u4e8c\u8005\u3002\u5f53\u4ec5\u4f20\u5165\u4e00\u4e2a\u5e8f\u5217\u65f6\uff0c\u4f1a\u91cd\u5efa\u884c\u7d22\u5f15\u3002 \u4e0b\u4f8b\u4e2d\uff0c\u901a\u8fc7 indexes \u521b\u5efaDataframe frame \u3002 \u901a\u8fc7 frame.reindex(['a', 'b', 'c', 'd'])\u91cd\u5efa\u884c\u7d22\u5f15 \u3002 \u901a\u8fc7 frame2.reindex(columns=['Ohio', 'Uta', 'California']) \u91cd\u5efa\u5217\u7d22\u5f15\u3002 \u7f3a\u5931\u7684\u7d22\u5f15\u5217\u586b\u5165\u7f3a\u5931\u503c\u3002 indexes = index = ['a', 'b', 'c'] states = ['Ohio', 'Texas', 'California'] frame = pd.DataFrame( np.arange(9).reshape(3, 3), index=indexes, columns=states ) print(frame) # Ohio Texas California # a 0 1 2 # b 3 4 5 # c 6 7 8 frame2 = frame.reindex(['a', 'b', 'c', 'd']) # \u91cd\u5efa\u884c\u7d22\u5f15 print(frame2) # Ohio Texas California # a 0.0 1.0 2.0 # b 3.0 4.0 5.0 # c 6.0 7.0 8.0 # d NaN NaN NaN frame3 = frame2.reindex(columns=['Ohio', 'Uta', 'California']) # \u91cd\u5efa\u5217\u7d22\u5f15 print(frame3) # Ohio Uta California # a 0.0 NaN 2.0 # b 3.0 NaN 5.0 # c 6.0 NaN 8.0 # d NaN NaN NaN \u4f7f\u7528 loc \u8fdb\u884c\u66f4\u4e3a\u7b80\u6d01\u7684\u884c\u3001\u5217\u6807\u7b7e\u7d22\u5f15\u3002\u4e0b\u4f8b\u901a\u8fc7\u7b5b\u9009\u884c\u7d22\u5f15\u548c\u5217\u7d22\u5f15\u4ea7\u751f\u65b0\u7684Dataframe\u3002 frame4 = frame.loc[['a', 'b'], states] print(frame4) # Ohio Texas California # a 0 1 2 # b 3 4 5","title":"\u91cd\u5efa\u7d22\u5f15"},{"location":"python/DataAnalysis/ch02/#_3","text":"set_index() , dropna() , fillna() , reset_index() , drop() , replace() \u8fd9\u4e9b\u65b9\u6cd5\u7684 inplace \u5c5e\u6027\u8bbe\u4e3a True \u65f6\uff0c\u8fd9\u4e9b\u65b9\u6cd5\u4f1a\u4fee\u6539Series\u6216DataFrame\u7684\u5c3a\u5bf8\u6216\u5f62\u72b6\uff0c*\u76f4\u63a5*\u64cd\u4f5c\u539f\u5bf9\u8c61\u800c\u4e0d\u8fd4\u56de\u65b0\u5bf9\u8c61\u3002 obj = pd.Series(np.arange(5), index=['a', 'b', 'c', 'd', 'e']) print(obj) # a 0 # b 1 # c 2 # d 3 # e 4 # dtype: int64 obj1 = obj.drop('c') print(obj1) # a 0 # b 1 # d 3 # e 4 # dtype: int64 print(obj1.drop(['d', 'e'])) # a 0 # b 1 # dtype: int64 \u5bf9\u6bd4 inplace=True \u548c False \u7684\u533a\u522b\u3002 inplace=False \u65f6\uff0c obj \u7684\u503c\u6ca1\u6709\u53d8\u5316\u3002 obj = pd.Series(np.arange(5), index=['a', 'b', 'c', 'd', 'e']) print(obj.drop('c', inplace=False)) # \u8bf4\u660e\u751f\u6210\u4e86\u65b0\u5bf9\u8c61 # a 0 # b 1 # d 3 # e 4 # dtype: int64 print(obj) # a 0 # b 1 # c 2 # d 3 # e 4 # dtype: int64 obj.drop('c', inplace=True) \u8f93\u51fa\u662f None \uff0c\u8bf4\u660e\u6ca1\u6709\u751f\u6210\u65b0\u5bf9\u8c61\uff0c\u53d8\u5316\u76f4\u63a5\u4f5c\u7528\u5230 obj \u4e0a\u3002 obj = pd.Series(np.arange(5), index=['a', 'b', 'c', 'd', 'e']) print(obj) print(obj.drop('c', inplace=True)) # \u8bf4\u660e\u6ca1\u6709\u751f\u6210\u65b0\u5bf9\u8c61 # None print(obj) # a 0 # b 1 # d 3 # e 4 # dtype: int64 \u4e0b\u4f8b\u6f14\u793a\u4e86\u8f74\u5411\u7684\u6548\u679c\u3002 \u5982\u679c\u4e0d\u6307\u5b9a\u8f74\u5411axis\uff0c drop() \u4f1a\u9ed8\u8ba4\u6cbf axis=0 \u8fdb\u884c\uff0c\u6240\u4ee5\uff0c\u57280\u8f74\u4e0a\u6267\u884c data.drop(['one', 'two']) \u4f1a\u62a5\u9519\u3002 axis='columns \u4e0e\u6307\u5b9a axis=1 \u540c\u6837\u6548\u679c\u3002 data = pd.DataFrame( np.arange(16).reshape(4, 4), index=['Ohio', 'Colorado', 'Utah', 'New York'], columns=['one', 'two', 'three', 'four'] ) print(data) # one two three four # Ohio 0 1 2 3 # Colorado 4 5 6 7 # Utah 8 9 10 11 # New York 12 13 14 15 # \u6cbf0\u8f74\u64cd\u4f5c\uff0c\u5220\u9664\u7b26\u5408\u6761\u4ef6\u7684\u884c\u8bb0\u5f55 print(data.drop(['Ohio', 'Colorado'])) # one two three four # Utah 8 9 10 11 # New York 12 13 14 15 print(data.drop(['one', 'two'])) # KeyError: \"['one' 'two'] not found in axis\" # \u6cbf1\u8f74\u64cd\u4f5c\uff0c\u5220\u9664\u7b26\u5408\u6761\u4ef6\u7684\u5217\u8bb0\u5f55 print(data.drop(['one', 'two'], axis=1)) # three four # Ohio 2 3 # Colorado 6 7 # Utah 10 11 # New York 14 15 print(data.drop(['one', 'two'], axis='columns')) # three four # Ohio 2 3 # Colorado 6 7 # Utah 10 11 # New York 14 15 \u518d\u901a\u8fc7\u4e0b\u4f8b\u4f53\u4f1a\u4e00\u4e0b inplace \u53c2\u6570\u7684\u4e0d\u540c\u6548\u679c\u3002 data = pd.DataFrame( { 'Name': ['Shobhit', 'vaibhav', 'vimal', 'Sourabh'], 'class': [11, 12, 10, 9], 'Age': [18, 20, 21, 17] } ) print(data) # Name class Age # 0 Shobhit 11 18 # 1 vaibhav 12 20 # 2 vimal 10 21 # 3 Sourabh 9 17 print(data.rename(columns={'Name': 'FirstName'}, inplace=False)) # FirstName class Age # 0 Shobhit 11 18 # 1 vaibhav 12 20 # 2 vimal 10 21 # 3 Sourabh 9 17 print(data) # Name class Age # 0 Shobhit 11 18 # 1 vaibhav 12 20 # 2 vimal 10 21 # 3 Sourabh 9 17 print(data.rename(columns={'Name': 'FirstName'}, inplace=True)) # \u6ca1\u6709\u751f\u6210\u65b0\u5bf9\u8c61 # None print(data) # FirstName class Age # 0 Shobhit 11 18 # 1 vaibhav 12 20 # 2 vimal 10 21 # 3 Sourabh 9 17","title":"\u8f74\u5411\u7d22\u5f15\u5220\u9664\u6761\u76ee"},{"location":"python/DataAnalysis/ch02/#_4","text":"Series\u7684\u7d22\u5f15 obj[...] \u4e0eNumPy\u6570\u7ec4\u7d22\u5f15\u7684\u529f\u80fd\u7c7b\u4f3c\uff0c\u53ea\u4e0d\u8fc7Series\u7684\u7d22\u5f15\u503c\u53ef\u4ee5\u4e0d\u4ec5\u4ec5\u662f\u6574\u6570\u3002 \u4e0b\u4f8b\u4e2d\uff1a obj[1] \u901a\u8fc7\u7d22\u5f15\u4f4d 1 \u68c0\u7d22\uff0c\u8f93\u51fa\u5bf9\u5e94Series\u7684\u503c\u3002 obj[1] \u901a\u8fc7\u7d22\u5f15\u4f4d [1] \u68c0\u7d22\uff0c\u8f93\u51faSeries\u3002 obj['b'] \u901a\u8fc7\u7d22\u5f15\u503c 'b' \u68c0\u7d22\uff0c\u8f93\u51fa\u5bf9\u5e94Series\u7684\u503c\u3002 obj[['b']] \u901a\u8fc7\u7d22\u5f15\u503c ['b'] \u68c0\u7d22\uff0c\u8f93\u51faSeries\u3002 obj = pd.Series(['Shobhit', 'vaibhav', 'vimal', 'Sourabh'], index=['a', 'b', 'c', 'd']) print(obj) # a Shobhit # b vaibhav # c vimal # d Sourabh # dtype: object print(obj[1]) # \u901a\u8fc7\u7d22\u5f15\u4f4d\u68c0\u7d22\uff0c\u8f93\u51fa\u5bf9\u5e94Series\u7684\u503c # vaibhav print(obj[[1]]) # b vaibhav # dtype: object print(obj['b']) # \u901a\u8fc7\u7d22\u5f15\u503c\u68c0\u7d22\uff0c\u8f93\u51fa\u5bf9\u5e94Series\u7684\u503c # vaibhav print(obj[['b']]) # \u901a\u8fc7\u7d22\u5f15\u503c\u68c0\u7d22\uff0c\u8f93\u51faSeries # b vaibhav # dtype: object \u4e0b\u9762\u4e00\u7ec4\u7684\u8f93\u51fa\u4e2d\uff0c\u6ce8\u610f\u5bf9\u6bd4\u666e\u901aPython\u5207\u7247\u4e0eSeries\u7684\u5207\u7247\u7684\u5dee\u5f02\u3002 obj = pd.Series(['Shobhit', 'vaibhav', 'vimal', 'Sourabh'], index=['a', 'b', 'c', 'd']) print(obj[1]) # vaibhav print(obj[[1]]) # b vaibhav # dtype: object print(obj[1:3]) # b vaibhav # c vimal # dtype: object print(obj['b':'d']) # b vaibhav # c vimal # d Sourabh # dtype: object Series\u7684\u5207\u7247\u7684\u503c\u66f4\u65b0\u3002 obj['b': 'c'] = 5 \u662f\u901a\u8fc7\u7d22\u5f15\u503c\u8fdb\u884c\u66f4\u65b0\uff0c\u76f4\u63a5\u4f5c\u7528\u5728 obj \u3002 obj[1: 3] = 6 \u662f\u901a\u8fc7\u7d22\u5f15\u4f4d\u7f6e\u6765\u66f4\u65b0 obj \u3002 obj = pd.Series(['Shobhit', 'vaibhav', 'vimal', 'Sourabh'], index=['a', 'b', 'c', 'd']) obj['b': 'c'] = 5 print(obj) # a Shobhit # b 5 # c 5 # d Sourabh # dtype: object obj[1: 3] = 6 print(obj) # a Shobhit # b 6 # c 6 # d Sourabh # dtype: object DataFrame\u7684\u7d22\u5f15\u4e0e\u5207\u7247\u3002 data[['Three', 'Two']] \u9009\u53d6\u6307\u5b9a\u5217\uff0c\u6ce8\u610f\u8f93\u5165\u5217\u6761\u4ef6\u662f\u5217\u8868 ['Three', 'Two'] \u3002 data = pd.DataFrame( np.arange(16).reshape(4, 4), index=['Ohio', 'Colorado', 'Utah', 'New York'], columns=['One', 'Two', 'Three', 'Four'] ) print(data) # One Two Three Four # Ohio 0 1 2 3 # Colorado 4 5 6 7 # Utah 8 9 10 11 # New York 12 13 14 15 print(data['Two']) # Ohio 1 # Colorado 5 # Utah 9 # New York 13 # Name: Two, dtype: int64 print(data[['Three', 'Two']]) # Three Two # Ohio 2 1 # Colorado 6 5 # Utah 10 9 # New York 14 13 print(data[:2]) # One Two Three Four # Ohio 0 1 2 3 # Colorado 4 5 6 7 \u5d4c\u5957\uff1a\u6839\u636e\u4e00\u4e2a\u5e03\u5c14\u503c\u6570\u7ec4\u5207\u7247\u6216\u9009\u62e9\u6570\u636e\u3002 data['Three'] > 5 \u662f\u4e00\u4e2a\u5e03\u5c14\u503c\u5e8f\u5217\u3002 data[data['Three'] > 5] \u8f93\u51fa\u6761\u4ef6\u4e3aTrue\u7684\u7ed3\u679c\u96c6\u3002 print(data['Three'] > 5) # Ohio False # Colorado True # Utah True # New York True # Name: Three, dtype: bool print(data[data['Three'] > 5]) # One Two Three Four # Colorado 4 5 6 7 # Utah 8 9 10 11 # New York 12 13 14 15 \u4f7f\u7528\u5e03\u5c14\u503cDataFrame\u8fdb\u884c\u7d22\u5f15\uff0c\u5df2\u7ecf\u66f4\u65b0\u3002 \u5728\u4e0b\u9762\u8fd9\u4e2a\u4f8b\u5b50\u4e2d\uff0c\u8fd9\u79cd\u7d22\u5f15\u65b9\u5f0f\u4f7f\u5f97DataFrame\u5728\u8bed\u6cd5\u4e0a\u66f4\u50cf\u662fNumPy\u4e8c\u7ef4\u6570\u7ec4\u3002 print(data < 5) # One Two Three Four # Ohio True True True True # Colorado True False False False # Utah False False False False # New York False False False False data[data < 5] = 0 print(data) # One Two Three Four # Ohio 0 0 0 0 # Colorado 0 5 6 7 # Utah 8 9 10 11 # New York 12 13 14 15 \u4f7f\u7528loc\u548ciloc\u9009\u62e9\u6570\u636e\u3002 \u4f7f\u7528\u6807\u7b7e\u540d loc \u6216\u6807\u7b7e\u4f4d\u7f6e iloc \u4ee5NumPy\u98ce\u683c\u7684\u8bed\u6cd5\u4eceDataFrame\u4e2d\u9009\u51faDataframe\u7684\u884c\u548c\u5217\u7684\u5b50\u96c6\u3002 data = pd.DataFrame( np.arange(16).reshape(4, 4), index=['Ohio', 'Colorado', 'Utah', 'New York'], columns=['One', 'Two', 'Three', 'Four'] ) print(data) # One Two Three Four # Ohio 0 1 2 3 # Colorado 4 5 6 7 # Utah 8 9 10 11 # New York 12 13 14 15 \u4e0b\u4f8b\u901a\u8fc7loc\u5bf9\u6807\u7b7e\u540d\u7b5b\u9009\u884c\u6216\u5217\u6570\u636e\u3002\u4f8b\u5982\uff0c\u8f93\u51fa Colorado \u884c\u6807\u7b7e\u7684 Two \u548c Three \u8fd9\u4e24\u5217\u7684\u503c\uff0c\u4ee5\u884c\u8bb0\u5f55\u7684\u65b9\u5f0f\u5c55\u73b0\u3002 print(data.loc['Colorado', ['Two', 'Three']]) # \u5207\u7247: # Two 5 # Three 6 # Name: Colorado, dtype: int64 print(data.loc[:'Ohio', :'Two']) # \u5207\u7247: 0\u884c\uff0c0,1\u5217 # One Two # Ohio 0 1 \u4e0b\u4f8b\u901a\u8fc7\u6807\u7b7e\u4f4d\u7f6e iloc \u8fdb\u884c\u7c7b\u4f3c\u7684\u6570\u636e\u9009\u62e9\u3002 data.iloc[:3, :2][data > 4] \u6309\u6307\u5b9a\u6761\u4ef6\u8fdb\u884c\u884c\u3001\u5217\u7b5b\u9009\uff0c\u7b26\u5408\u6761\u4ef6 [data > 4] \u7684\u8f93\u51faDataframe\u503c\uff0c\u4e0d\u7b26\u5408\u6761\u4ef6\u7684\u8f93\u51faNaN\u3002 print(data.iloc[[0]]) # 0\u884c # One Two Three Four # Ohio 0 1 2 3 print(data.iloc[[0], [1]]) # \u5207\u7247: 0\u884c\uff0c1\u5217 # Two # Ohio 1 print(data.iloc[1:2, 1:2]) # \u5207\u7247: 1\u884c\uff0c2\u5217 # Two # Ohio 1 print(data.iloc[2, [3, 0, 1]]) # \u5207\u7247: 2\u884c\uff0c\u4f9d\u6b21\u53d63\uff0c0\uff0c1\u5217 # Four 11 # One 8 # Two 9 # Name: Utah, dtype: int64 print(data.iloc[:3, :2][data > 4]) # One Two # Ohio NaN NaN # Colorado NaN 5.0 # Utah 8.0 9.0","title":"\u7d22\u5f15\u3001\u9009\u62e9\u4e0e\u8fc7\u6ee4"},{"location":"python/DataAnalysis/ch02/#_5","text":"Pandas\u7684Series\u7684\u7d22\u5f15\u503c\u662f\u6574\u6570\u7d22\u5f15\u3002 data = np.arange(3.) ser = pd.Series(data) print(ser) # 0 0.0 # 1 1.0 # 2 2.0 # dtype: float64 print(ser[:1]) # 0 0.0 # dtype: float64 print(ser.loc[:1]) # loc\u7528\u4e8e\u6807\u7b7e\u540d # 0 0.0 # 1 1.0 # dtype: float64 print(ser.iloc[:1]) # iloc\u7528\u4e8e\u6807\u7b7e\u4f4d\u7f6e # 0 0.0 # dtype: float64 data = ['1', 'b', 'e', 3] ser = pd.Series(data) print(ser) # 0 1 # 1 b # 2 e # 3 3 # dtype: object print(ser[:1]) # 0 1 # dtype: object print(ser.loc[:1]) # 0 1 # 1 b # dtype: object print(ser.iloc[:1]) # 0 1 # dtype: object \u5bf9DataFrame\u7684\u66f4\u65b0\u3002 df1 = pd.DataFrame(np.arange(4).reshape((2, 2)), columns=list('ab')) print(df1) # a b # 0 0 1 # 1 2 3 # \u6309\u6807\u7b7e\u540d\u66f4\u65b0 df1.loc[1, :'b'] = np.nan print(df1) # a b # 0 0.0 1.0 # 1 NaN NaN","title":"\u6574\u6570\u7d22\u5f15"},{"location":"python/DataAnalysis/ch02/#_6","text":"Pandas\u652f\u6301\u5728Series\u6216\u8005DataFrame\u5bf9\u8c61\u4e4b\u95f4\u8fdb\u884c\u7b97\u672f\u8fd0\u7b97\u3002 \u4f8b\uff1a\u4e24\u4e2aSeries\u505a\u7b97\u672f\u52a0\u6cd5\u3002 \u8fd4\u56de\u7684\u7ed3\u679c\u4e5f\u662f\u4e00\u4e2aSeries\u3002 \u8fd4\u56de\u7ed3\u679c\u7684\u7d22\u5f15\u662f\u6bcf\u4e2aSeries\u7684\u7d22\u5f15\u7684\u5e76\u96c6\u3002 \u51e1\u662f\u6ca1\u6709\u5728\u4e24\u4e2aSeries\u90fd\u51fa\u73b0\u7684\u7d22\u5f15\u4f4d\u7f6e\uff0c\u5185\u90e8\u6570\u636e\u5bf9\u9f50\u4f1a\u586b\u5145\u7f3a\u5931\u503cNaN\u3002\u7f3a\u5931\u503c\u4f1a\u5728\u540e\u7eed\u7684\u5176\u5b83\u7b97\u672f\u64cd\u4f5c\u4e0a\u4ea7\u751f\u5f71\u54cd\u3002 \u540c\u65f6\u51fa\u73b0\u5728\u4e24\u4e2aSeries\u7684\u7d22\u5f15\u4f4d\u7f6e\uff0cSeries\u7684\u503c\u505a\u7b97\u672f\u76f8\u52a0\u3002 s1 = pd.Series( [7.3, -2.5, 3.4, 1.5], index=['a', 'c', 'd', 'e'] ) s2 = pd.Series( [-2.1, 3.6, -1.5, 4, 3.1], index=['a', 'c', 'e', 'f', 'g'] ) print(s1) # a 7.3 # c -2.5 # d 3.4 # e 1.5 # dtype: float64 print(s2) # a -2.1 # c 3.6 # e -1.5 # f 4.0 # g 3.1 # dtype: float64 print(s1 + s2) # a 5.2 # c 1.1 # d NaN # e 0.0 # f NaN # g NaN # dtype: float64 \u4f8b\uff1a\u4e24\u4e2aDataframe\u505a\u7b97\u672f\u52a0\u6cd5 \u8fd4\u56de\u7ed3\u679c\u4e5f\u662f\u4e00\u4e2aDataframe\u3002 \u8fd4\u56de\u7ed3\u679c\u7684\u884c\u5217\u7d22\u5f15\u662f\u6bcf\u4e2aDataFrame\u7684\u884c\u5217\u7d22\u5f15\u7684\u5e76\u96c6\u3002 \u51e1\u662f\u6ca1\u6709\u5728\u4e24\u4e2aDataFrame\u90fd\u51fa\u73b0\u7684\u4f4d\u7f6e\u5c31\u4f1a\u88ab\u7f6e\u4e3aNaN\u3002 \u4e24\u4e2aDataFrame\u90fd\u51fa\u73b0\u7684\u4f4d\u7f6e\uff0c\u5bf9Dataframe\u7684\u503c\u505a\u7b97\u672f\u52a0\u6cd5\u3002 df1 = pd.DataFrame( np.arange(9).reshape((3, 3)), columns=list('bcd'), index=['Ohio', 'Texas', 'Colorado'] ) df2 = pd.DataFrame( np.arange(12).reshape((4, 3)), columns=list('bde'), index=['Utah', 'Ohio', 'Texas', 'Oregon'] ) print(df1) # b c d # Ohio 0 1 2 # Texas 3 4 5 # Colorado 6 7 8 print(df2) # b d e # Utah 0 1 2 # Ohio 3 4 5 # Texas 6 7 8 # Oregon 9 10 11 print(df1 + df2) # b c d e # Colorado NaN NaN NaN NaN # Ohio 3.0 NaN 6.0 NaN # Oregon NaN NaN NaN NaN # Texas 9.0 NaN 12.0 NaN # Utah NaN NaN NaN NaN \u5728Series\u6216\u8005DataFrame\u5bf9\u8c61\u4e4b\u95f4\u8fdb\u884c\u7b97\u672f\u64cd\u4f5c\u65f6\uff0c\u6709\u65f6\u9700\u8981\u5bf9\u7f3a\u5931\u503c\u6307\u5b9a\u586b\u5145\u503c\uff0c\u6bd4\u5982\u5f53\u8f74\u6807\u7b7e\u5728\u4e00\u4e2a\u5bf9\u8c61\u4e2d\u5b58\u5728\uff0c\u5728\u53e6\u4e00\u4e2a\u5bf9\u8c61\u4e2d\u4e0d\u5b58\u5728\u65f6\uff0c\u5c06\u7f3a\u5931\u503c\u586b\u5145\u4e3a0\u3002\u4e5f\u5c31\u662f\u8bf4\uff0c\u5982\u679c\u5728\u4e24\u4e2aDataFrame\u90fd\u7f3a\u5931\uff0c\u90a3\u4e48\u4f9d\u7136\u8fd8\u4f1a\u662fNaN\u3002 \u4e0b\u4f8b\u4e2da2\u662f\u5728 df1 \u548c df2 \u90fd\u7f3a\u5931\u7684\u4f4d\u7f6e\uff0c\u6240\u4ee5\u5373\u4f7f fill_value=0 \uff0ca2\u4ecd\u7136\u662fNaN\u3002 df1 = pd.DataFrame( np.arange(4).reshape((2, 2)), columns=list('ab') ) df2 = pd.DataFrame( np.arange(9).reshape((3, 3)), columns=list('bcd') ) print(df1) # a b # 0 0 1 # 1 2 3 print(df2) # b c d # 0 0 1 2 # 1 3 4 5 # 2 6 7 8 # \u5bf9df1\u548cdf2\u5c31\u7b97\u672f\u548c\uff0c\u5bf9\u5e94\u6ca1\u6709\u884c\u5217\u5171\u540c\u7684\u4ea4\u96c6\u7684\u5730\u65b9\u586b\u5145\u7a7a\u503cNaN\uff0c\u6709\u4ea4\u96c6\u7684\u5730\u65b9\u6c42\u7b97\u672f\u548c\u3002 print(df1.add(df2)) # a b c d # 0 NaN 1.0 NaN NaN # 1 NaN 6.0 NaN NaN # 2 NaN NaN NaN NaN # \u5bf9df1\u548cdf2\u5c31\u7b97\u672f\u548c\uff0c\u5bf9\u5e94\u6ca1\u6709\u884c\u5217\u5171\u540c\u7684\u4ea4\u96c6\u7684\u5730\u65b9\u586b\u5145\u7a7a\u503c0\uff0c\u6709\u4ea4\u96c6\u7684\u5730\u65b9\u6c42\u7b97\u672f\u548c\u3002 print(df1.add(df2, fill_value=0)) # df2.add(df1, fill_value=0) \u8fd4\u56de\u540c\u6837\u7684\u7ed3\u679c # a b c d # 0 0.0 1.0 1.0 2.0 # 1 2.0 6.0 4.0 5.0 # 2 NaN 6.0 7.0 8.0 \u4e0b\u4f8b\u4e2db2\u662f\u5728 df1 \u548c df2 \u90fd\u7f3a\u5931\u7684\u4f4d\u7f6e\uff0c\u6240\u4ee5\u5373\u4f7f fill_value=0 \uff0cb2\u4ecd\u7136\u662fNaN\u3002 df1 = pd.DataFrame( np.arange(4).reshape((2, 2)), columns=list('ab') ) df2 = pd.DataFrame( np.arange(9).reshape((3, 3)), columns=list('acd') ) print(df1) # a b # 0 0 1 # 1 2 3 print(df2) # a c d # 0 0 1 2 # 1 3 4 5 # 2 6 7 8 print(df1.add(df2, fill_value=0)) # a b c d # 0 0.0 1.0 1.0 2.0 # 1 5.0 3.0 4.0 5.0 # 2 6.0 NaN 7.0 8.0 \u4e0b\u4f8b\u4e2d\u6ca1\u6709\u4e24\u4e2aDataFrame\u5171\u540c\u7f3a\u5931\u7684\u60c5\u51b5\u3002 df1 = pd.DataFrame( np.arange(4).reshape((2, 2)), columns=list('ab') ) df2 = pd.DataFrame( np.arange(9).reshape((3, 3)), columns=list('abd') ) print(df1) # a b # 0 0 1 # 1 2 3 print(df2) # a b d # 0 0 1 2 # 1 3 4 5 # 2 6 7 8 print(df1.add(df2, fill_value=0)) # a b d # 0 0.0 2.0 2.0 # 1 5.0 7.0 5.0 # 2 6.0 7.0 8.0 \u4e0b\u9762\u662fSeries\u548cDataFrame\u7684\u7b97\u672f\u65b9\u6cd5\u3002 add\uff0cradd\uff1a\u52a0\u6cd5(+) sub\uff0crsub\uff1a\u51cf\u6cd5(-) div\uff0crdiv\uff1a\u9664\u6cd5(/) floordiv\uff0crfloordiv\uff1a\u6574\u9664(//) mul\uff0crmul\uff1a\u4e58\u6cd5(*) pow\uff0crpow\uff1a\u5e42\u6b21\u65b9(**) \u4e0a\u8ff0\u6bcf\u4e2a\u65b9\u6cd5\u90fd\u6709\u4e00\u4e2a\u4ee5r\u5f00\u5934\u7684\u526f\u672c\uff0c\u8fd9\u4e9b\u526f\u672c\u65b9\u6cd5\u7684\u53c2\u6570\u662f\u7ffb\u8f6c\u7684\u3002\u6bd4\u5982\uff0c\u6c42DataFrame\u5f53\u4e2d\u6240\u6709\u5143\u7d20\u7684\u5012\u6570 1/df \uff0c\u53ef\u4ee5\u5199\u6210df.rdiv(1)\u3002 df1 = pd.DataFrame( np.arange(4).reshape((2, 2)), columns=list('ab') ) df2 = pd.DataFrame( np.arange(9).reshape((3, 3)), columns=list('abd') ) print(df1) # a b # 0 0 1 # 1 2 3 print(df2) # a b d # 0 0 1 2 # 1 3 4 5 # 2 6 7 8 print(df1.radd(df2, fill_value=0)) # a b d # 0 0.0 2.0 2.0 # 1 5.0 7.0 5.0 # 2 6.0 7.0 8.0 print(df1.sub(df2, fill_value=0)) # a b d # 0 0.0 0.0 -2.0 # 1 -1.0 -1.0 -5.0 # 2 -6.0 -7.0 -8.0 print(df1.div(df2, fill_value=0)) # a b d # 0 NaN 1.00 0.0 # 1 0.666667 0.75 0.0 # 2 0.000000 0.00 0.0 print(df1.floordiv(df2, fill_value=0)) # a b d # 0 NaN 1.0 0.0 # 1 0.0 0.0 0.0 # 2 0.0 0.0 0.0 print(df1.mul(df2, fill_value=0)) # a b d # 0 0.0 1.0 0.0 # 1 6.0 12.0 0.0 # 2 0.0 0.0 0.0 print(df1.pow(df2, fill_value=0)) # a b d # 0 1.0 1.0 0.0 # 1 8.0 81.0 0.0 # 2 0.0 0.0 0.0","title":"\u7b97\u672f\u548c\u6570\u636e\u5bf9\u9f50"},{"location":"python/DataAnalysis/ch02/#dataframeseries","text":"DataFrame\u548cSeries\u95f4\u7684\u7b97\u672f\u64cd\u4f5c\u4e0eNumPy\u4e2d\u4e0d\u540c\u7ef4\u5ea6\u6570\u7ec4\u95f4\u7684\u64cd\u4f5c\u7c7b\u4f3c\u3002","title":"DataFrame\u548cSeries\u95f4\u7684\u7b97\u672f\u64cd\u4f5c"},{"location":"python/DataAnalysis/ch02/#numpy","text":"\u4ecearr\u4e2d\u51cf\u53bbarr[0]\u65f6\uff0c\u51cf\u6cd5\u6cbf0\u8f74\u5728\u6bcf\u4e00\u884c\u90fd\u8fdb\u884c\u4e86\u64cd\u4f5c\u3002\u8fd9\u5c31\u662f\u6240\u8c13\u7684\u5e7f\u64ad\u673a\u5236\u3002 arr = np.arange(12).reshape((3, 4)) print(arr) # [[ 0 1 2 3] # [ 4 5 6 7] # [ 8 9 10 11]] print(arr[0]) # [0 1 2 3] print(arr - arr[0]) # [[0 0 0 0] # [4 4 4 4] # [8 8 8 8]]","title":"\u4e0d\u540c\u7ef4\u5ea6NumPy\u6570\u7ec4\u95f4\u7684\u7b97\u672f\u64cd\u4f5c"},{"location":"python/DataAnalysis/ch02/#dataframeseries_1","text":"\u9ed8\u8ba4\u60c5\u51b5\u4e0b\uff0cDataFrame\u548cSeries\u7684\u6570\u5b66\u64cd\u4f5c\u4e2d\u4f1a\u5c06Series\u7684\u7d22\u5f15\u548cDataFrame\u7684*\u5217*\u8fdb\u884c\u5339\u914d\uff0c\u5e76*\u5e7f\u64ad\u5230\u5404\u884c*. \u5982\u679c\u4e00\u4e2a\u7d22\u5f15\u503c\u4e0d\u5728DataFrame\u7684\u5217\u4e2d\uff0c\u4e5f\u4e0d\u5728Series\u7684\u7d22\u5f15\u4e2d\uff0c\u5219\u65b0\u5bf9\u8c61\u4f1a\u6784\u5efa\u5e76\u96c6\u7d22\u5f15\u3002 frame = pd.DataFrame( np.arange(12).reshape((4, 3)), columns=list('bde'), index=['Utah', 'Ohio', 'Texas', 'Oregon'] ) print(frame) # b d e # Utah 0 1 2 # Ohio 3 4 5 # Texas 6 7 8 # Oregon 9 10 11 # \u622a\u53d6frame\u7684\u7b2c0\u884c\uff0c\u5217\u6807\u7b7e\u53d8\u6210\u65b0Serise\u7684\u7d22\u5f15\u3002 series = frame.iloc[0] print(series) # b 0 # d 1 # e 2 # Name: Utah, dtype: int64 series2 = pd.Series( range(3), index=list('bef') ) print(series2) # b 0 # e 1 # f 2 # dtype: int64 # \u622a\u53d6frame\u7684d\u5217\uff0c\u884c\u6807\u7b7e\u53d8\u6210\u65b0Serise\u7684\u7d22\u5f15\u3002 series3 = frame['d'] print(series3) # Utah 1 # Ohio 4 # Texas 7 # Oregon 10 # Name: d, dtype: int64 # \u5c06Series\u7684\u7d22\u5f15\u548cDataFrame\u7684\u5217\u6807\u7b7e\u8fdb\u884c\u5339\u914d\uff0cSeries\u7684\u503c\u6cbfDataFrame\u76840\u8f74\u5e7f\u64ad\u5230\u5404\u4e2a\u884c\u3002 print(frame - series) # frame: series Result: # b d e # b 0 # b d e # Utah 0 1 2 # d 1 # Utah 0 0 0 # Ohio 3 4 5 # e 2 # Ohio 3 3 3 # Texas 6 7 8 # Name: Utah, dtype: int64 # Texas 6 6 6 # Oregon 9 10 11 # Oregon 9 9 9 # \u5c06Series\u7684\u7d22\u5f15\u548cDataFrame\u7684\u5217\u6807\u7b7e\u8fdb\u884c\u5339\u914d\uff0cSeries\u7684\u503c\u6cbfDataFrame\u76840\u8f74\u5e7f\u64ad\u5230\u5404\u4e2a\u884c\uff0c\u7f3a\u5931\u4f4d\u7f6e\u586b\u5145\u7a7a\u503cNaN\u3002 print(frame - series2) # frame: series2 Result: # b d e # b 0 # b d e f # Utah 0 1 2 # e 1 # Utah 0.0 NaN 1.0 NaN # Ohio 3 4 5 # f 2 # Ohio 3.0 NaN 4.0 NaN # Texas 6 7 8 # dtype: int64 # Texas 6.0 NaN 7.0 NaN # Oregon 9 10 11 # Oregon 9.0 NaN 10.0 NaN # \u6539\u4e3a\u5728\u5217\u4e0a\u8fdb\u884c\u5e7f\u64ad\uff0c\u5728\u884c\u4e0a\u5339\u914d\uff0c\u5fc5\u987b\u4f5c\u7528\u5728\u67d0\u79cd\u7b97\u672f\u65b9\u6cd5\u4e0a\u3002\u4e0b\u4f8b\u4e2dSeries\u7684\u503c\u6cbfDataFrame\u76840\u8f74\u5e7f\u64ad\u5230\u5404\u4e2a\u884c\uff08\u6309index\u5339\u914d\u8fdb\u884c\u884c\u64cd\u4f5c\uff09\u3002 print(frame.sub(series3, axis='index')) # \u6216axis=0 # frame: series3 Result: # b d e # Utah 1 # b d e # Utah 0 1 2 # Ohio 4 # Utah -1 0 1 # Ohio 3 4 5 # Texas 7 # Ohio -1 0 1 # Texas 6 7 8 # Oregon 10 # Texas -1 0 1 # Oregon 9 10 11 # Name: d, dtype: int64 # Oregon -1 0 1","title":"DataFrame\u548cSeries\u95f4\u7684\u7b97\u672f\u64cd\u4f5c"},{"location":"python/DataAnalysis/ch02/#_7","text":"NumPy\u7684\u901a\u7528\u51fd\u6570\uff08\u9010\u5143\u7d20\u6570\u7ec4\u65b9\u6cd5\uff09\u5bf9pandas\u5bf9\u8c61\uff08DataFrame\u548cSeries\uff09\u4e5f\u6709\u6548\u3002 frame = pd.DataFrame( np.random.randn(4, 3), columns=list('bde'), index=['Utah', 'Ohio', 'Texas', 'Oregon'] ) print(frame) # b d e # Utah 2.737734 -0.379977 0.758933 # Ohio 0.847497 0.839583 -2.192021 # Texas -0.907544 -0.457436 -1.907396 # Oregon 0.389362 0.250170 1.065889 # \u5bf9DataFrame\u5bf9\u8c61\u8ba1\u7b97\u7edd\u5bf9\u503c\u3002 print(np.abs(frame)) # b d e # Utah 2.737734 0.379977 0.758933 # Ohio 0.847497 0.839583 2.192021 # Texas 0.907544 0.457436 1.907396 # Oregon 0.389362 0.250170 1.065889 # f\u8fd4\u56de\u4e00\u4e2a\u6807\u91cf\u503c f = lambda x: x.max() - x.min() # \u6cbf0\u8f74\u5e94\u7528f\uff08\u5bf9\u6bcf\u5217\u7684\u6240\u6709\u884c\u5143\u7d20\u8fdb\u884cf\u8ba1\u7b97\uff09, \u9ed8\u8ba4axis=0 print(frame.apply(f)) # b 3.645278 # d 1.297019 # e 3.257911 # dtype: float64 # \u6cbf1\u8f74\u5e94\u7528f\uff08\u5bf9\u6bcf\u884c\u7684\u6240\u6709\u5217\u5143\u7d20\u8fdb\u884cf\u8ba1\u7b97\uff09 print(frame.apply(f, axis=1)) # Utah 3.117711 # Ohio 3.039518 # Texas 1.449961 # Oregon 0.815720 # dtype: float64 # \u5b9a\u4e49\u51fd\u6570f\uff0c\u8fd4\u56de\u5e26\u6709\u591a\u4e2a\u503c\u7684Series\u3002 def f(x): return pd.Series( [x.min(), x.max()], index=['min', 'max'] ) print(frame.apply(f)) # b d e # min -0.907544 -0.457436 -2.192021 # max 2.737734 0.839583 1.065889 # \u5b9a\u4e49\u51fd\u6570f\uff0c\u4f7f\u7528applymap\u65b9\u6cd5\u683c\u5f0f\u5316\u5b57\u7b26\uff0c\u5c06\u4e00\u4e2a\u9010\u5143\u7d20\u7684\u51fd\u6570\u5e94\u7528\u5230Series\u4e0a\u3002 f = lambda x: '%.2f' % x print(frame.applymap(f)) # # b d e # Utah 2.74 -0.38 0.76 # Ohio 0.85 0.84 -2.19 # Texas -0.91 -0.46 -1.91 # Oregon 0.39 0.25 1.07 print(frame['e'].map(f)) # Utah 0.76 # Ohio -2.19 # Texas -1.91 # Oregon 1.07 # Name: e, dtype: object","title":"\u51fd\u6570\u5e94\u7528\u548c\u6620\u5c04"},{"location":"python/DataAnalysis/ch02/#_8","text":"\u4f7f\u7528sort_index\u65b9\u6cd5\uff0c\u6309\u884c\u6216\u5217\u7d22\u5f15\u8fdb\u884c\u5b57\u5178\u578b\u6392\u5e8f\uff0c\u8fd4\u56de\u4e00\u4e2a\u65b0\u7684\u6392\u5e8f\u597d\u7684Pandas\u5bf9\u8c61\u3002","title":"\u6392\u5e8f\u548c\u6392\u540d"},{"location":"python/DataAnalysis/ch02/#series_1","text":"\u5bf9Series\u8fdb\u884c\u7d22\u5f15\u6392\u5e8f\u548c\u503c\u6392\u5e8f\u3002 obj = pd.Series( range(4), index=list('dabc') ) print(obj) # d 0 # a 1 # b 2 # c 3 # dtype: int64 print(obj.sort_index()) # a 1 # b 2 # c 3 # d 0 # dtype: int64 # print(obj.sort_values()) # d 0 # a 1 # b 2 # c 3 # dtype: int64 \u9ed8\u8ba4\u60c5\u51b5\u4e0b\uff0c\u6240\u6709\u7684\u7f3a\u5931\u503c\u90fd\u4f1a\u88ab\u6392\u5e8f\u81f3Series\u7684\u5c3e\u90e8\u3002 obj = pd.Series([4, np.nan, 7, np.nan, -3, 2]) print(obj) # 0 4.0 # 1 NaN # 2 7.0 # 3 NaN # 4 -3.0 # 5 2.0 # dtype: float64 print(obj.sort_values()) # 4 -3.0 # 5 2.0 # 0 4.0 # 2 7.0 # 1 NaN # 3 NaN # dtype: float64","title":"Series\u6392\u5e8f"},{"location":"python/DataAnalysis/ch02/#dataframe_3","text":"frame = pd.DataFrame( [[0, 1, 10, 3], [4, 5, 6, 21], [8, 9, 2, 21]], index=['three', 'one', 'five'], columns=list('dabc') ) print(frame) # d a b c # three 0 1 10 3 # one 4 5 6 21 # five 8 9 2 21 print(frame.index) # Index(['three', 'one', 'five'], dtype='object') # \u9ed8\u8ba40\u8f74\uff0c\u6240\u6709\u884c\u8fdb\u884c\u7d22\u5f15\u9996\u5b57\u6bcd\u5347\u5e8f print(frame.sort_index()) # d a b c # five 8 9 2 21 # one 4 5 6 21 # three 0 1 10 3 # \u6307\u5b9a0\u8f74\uff0c\u6240\u6709\u884c\u8fdb\u884c\u7d22\u5f15\u9996\u5b57\u6bcd\u5347\u5e8f print(frame.sort_index(axis=0)) # d a b c # five 8 9 2 21 # one 4 5 6 21 # three 0 1 10 3 # \u6307\u5b9a0\u8f74\uff0c\u6240\u6709\u884c\u8fdb\u884c\u7d22\u5f15\u9996\u5b57\u6bcd\u964d\u5e8f print(frame.sort_index(axis=0, ascending=False)) # d a b c # three 0 1 10 3 # one 4 5 6 21 # five 8 9 2 21 # \u6307\u5b9a1\u8f74\uff0c\u6240\u6709\u5217\u8fdb\u5217\u7d22\u5f15\u9996\u5b57\u6bcd\u5347\u5e8f print(frame.sort_index(axis=1)) # a b c d # three 1 10 3 0 # one 5 6 21 4 # five 9 2 21 8 # \u6307\u5b9a1\u8f74\uff0c\u6240\u6709\u5217\u8fdb\u5217\u7d22\u5f15\u9996\u5b57\u6bcd\u964d\u5e8f print(frame.sort_index(axis=1, ascending=False)) # d c b a # three 0 3 10 1 # one 4 21 6 5 # five 8 21 2 9 # \u6309\u6307\u5b9a\u5355\u5217\u8fdb\u884c\u503c\u6392\u5e8f\uff08\u964d\u5e8f\uff09 print(frame.sort_values(by=['c'], ascending=False)) # d a b c # one 4 5 6 21 # five 8 9 2 21 # three 0 1 10 3 # \u6309\u6307\u5b9a\u591a\u5217\u8fdb\u884c\u503c\u6392\u5e8f\uff08\u964d\u5e8f\uff09\uff0c\u5148\u5bf9b\u964d\u5e8f\uff0c\u518d\u5bf9d\u964d\u5e8f print(frame.sort_values(by=['c', 'd'], ascending=False)) # d a b c # five 8 9 2 21 # one 4 5 6 21 # three 0 1 10 3","title":"DataFrame\u6392\u5e8f"},{"location":"python/DataAnalysis/ch02/#_9","text":"**\u6392\u540d**\u662f\u6307\u5bf9\u6570\u7ec4\u4ece1\u5230\u6709\u6548\u6570\u636e\u70b9\u603b\u6570\u5206\u914d\u540d\u6b21\u7684\u64cd\u4f5c\u3002 Series\u548cDataFrame\u7684 rank \u65b9\u6cd5\u662f\u5b9e\u73b0\u6392\u540d\u7684\u65b9\u6cd5\uff0c df.rank(ascending=False, method='max') \u3002 ascending \uff1a\u6392\u540d\u65b9\u5f0f\uff0c\u9ed8\u8ba4\u4ece\u4f4e\u5230\u9ad8\uff0c ascending=False \u8868\u793a\u4ece\u9ad8\u5230\u4f4e\uff1b method \uff1a\u6392\u540d\u65b9\u5f0f\uff0c\u5305\u62ec\uff1a average:\u9ed8\u8ba4\uff0c\u5728\u76f8\u7b49\u5206\u7ec4\u4e2d\uff0c\u4e3a\u5404\u4e2a\u503c\u5206\u914d\u5e73\u5747\u6392\u540d\uff0c\u5373\u76f8\u540c\u503c\u7684\u548c\u9664\u4ee5\u8be5\u503c\u7684\u4e2a\u6570\uff0c\u5373\u4e3a\u8be5\u503c\u7684\u540d\u6b21\u3002 min:\u4f7f\u7528\u6574\u4e2a\u5206\u7ec4\u7684\u6700\u5c0f\u6392\u540d\uff0c\u5373\uff0c\u5bf9\u5e94\u76f8\u540c\u503c\uff0c\u53d6\u5728\u987a\u5e8f\u6392\u540d\u4e2d\u6700\u5c0f\u7684\u90a3\u4e2a\u6392\u540d\u4f5c\u4e3a\u6240\u6709\u8be5\u503c\u7684\u6392\u540d\u3002 max:\u4f7f\u7528\u6574\u4e2a\u5206\u7ec4\u7684\u6700\u5927\u6392\u540d\uff0c\u5373\uff0c\u5bf9\u5e94\u76f8\u540c\u503c\uff0c\u53d6\u5728\u987a\u5e8f\u6392\u540d\u4e2d\u6700\u5927\u7684\u90a3\u4e2a\u6392\u540d\u4f5c\u4e3a\u6240\u6709\u8be5\u503c\u7684\u6392\u540d\u3002 first:\u6309\u503c\u518d\u539f\u59cb\u6570\u636e\u4e2d\u51fa\u73b0\u987a\u5e8f\u5206\u914d\u6392\u540d\uff0c\u8c01\u51fa\u73b0\u7684\u4f4d\u7f6e\u9760\u524d\uff0c\u8c01\u7684\u6392\u540d\u9760\u524d\u3002 dense:\u7c7b\u4f3cmin\u65b9\u6cd5\uff0c\u4f46\u6392\u540d\u603b\u662f\u5728\u7ec4\u95f4\u589e\u52a01\uff0c\u800c\u4e0d\u662f\u7ec4\u4e2d\u76f8\u540c\u7684\u5143\u7d20\u6570\uff0c\u5373\u76f8\u540c\u503c\u7684\u6392\u540d\u76f8\u540c\uff0c\u5176\u4ed6\u4f9d\u6b21\u52a01\u5373\u53ef\u3002 \u9ed8\u8ba4\u60c5\u51b5\u4e0b\uff0crank\u662f\u901a\u8fc7\u201c\u4e3a\u5404\u7ec4\u5206\u914d\u4e00\u4e2a\u5e73\u5747\u6392\u540d\u201d\u7684\u65b9\u5f0f\u7834\u574f\u5e73\u7ea7\u5173\u7cfb # \u6309\u7167\u6bcf\u4e2a\u5143\u7d20\u7684\u5927\u5c0f\u987a\u5e8f\u7ed9\u51fa\u4e00\u4e2a\u5e73\u5747\u6392\u540d obj = pd.Series([7, -5, 7, 4, 2, 0, 4]) print(obj) # 0 7 # 1 -5 # 2 7 # 3 4 # 4 2 # 5 0 # 6 4 # dtype: int64 print(obj.rank()) # 0 6.5 # 1 1.0 # 2 6.5 # 3 4.5 # 4 3.0 # 5 2.0 # 6 4.5 # dtype: float64 # index value rank # 2 -5 1 # 6 0 2 # 5 2 3 # 4 4 4.5 # 7 4 4.5 # 1 7 6.5 # 3 7 6.5 # \u6839\u636e\u5143\u7d20\u7684\u89c2\u5bdf\u987a\u5e8f\u8fdb\u884c\u5206\u914d\u3002\u5143\u7d200\u548c2\u6ca1\u6709\u4f7f\u7528\u5e73\u5747\u6392\u540d6.5\uff0c\u5b83\u4eec\u88ab\u8bbe\u6210\u4e866\u548c7\uff0c\u56e0\u4e3a\u6570\u636e\u4e2d\u6807\u7b7e0\u4f4d\u4e8e\u6807\u7b7e2\u7684\u524d\u9762\u3002 print(obj.rank(method='first')) # 0 6.0 # 1 1.0 # 2 7.0 # 3 4.0 # 4 3.0 # 5 2.0 # 6 5.0 # dtype: float64 # \u6309\u7167max\u8fdb\u884c\u5347\u5e8f\u548c\u964d\u5e8f print(obj.rank(ascending=False, method='max')) print(obj.rank(ascending=True, method='max')) # Original Series Max with inc Max with dec # 0 7 # 0 2.0 (\u6700\u5c0f) # 0 7.0 (\u6700\u5927) # 1 -5 # 1 7.0 (\u6700\u5927) # 1 1.0 (\u6700\u5c0f) # 2 7 # 2 2.0 (\u6700\u5c0f) # 2 7.0 (\u6700\u5927) # 3 4 # 3 4.0 # 3 5.0 # 4 2 # 4 5.0 # 4 3.0 # 5 0 # 5 6.0 # 5 2.0 # 6 4 # 6 4.0 # 6 5.0 # dtype: float64 # dtype: float64 # dtype: float64 frame = pd.DataFrame( {'b': [4.3, 7, -3, 2], 'a': [0, 1, 0, 1], 'c': [-2, 5, 8, -2]} ) print(frame) # b a c # 0 4.3 0 -2 # 1 7.0 1 5 # 2 -3.0 0 8 # 3 2.0 1 -2 # \u6cbf1\u8f74\u5bf9DataFrame\u8fdb\u884crank\u64cd\u4f5c\uff0c\u5373\uff0c\u6bcf\u4e00\u884c\u5404\u5143\u7d20\u8fdb\u884crank\u3002 print(frame.rank(axis='columns')) # axis=1 # b a c # 0 3.0 2.0 1.0 # 1 3.0 1.0 2.0 # 2 1.0 2.0 3.0 # 3 3.0 2.0 1.0","title":"\u6392\u540d"},{"location":"python/DataAnalysis/ch02/#_10","text":"\u5c3d\u7ba1\u5f88\u591apandas\u51fd\u6570\uff08\u6bd4\u5982reindex\uff09\u9700\u8981\u6807\u7b7e\u662f\u552f\u4e00\u7684\uff0c\u4f46\u8fd9\u4e2a\u5e76\u4e0d\u662f\u5f3a\u5236\u6027\u7684\u3002 \u7d22\u5f15\u7684is_unique\u5c5e\u6027\u53ef\u4ee5\u68c0\u67e5\u6807\u7b7e\u662f\u5426\u552f\u4e00\u3002 \u5e26\u6709\u91cd\u590d\u7d22\u5f15\u7684\u60c5\u51b5\u4e0b\uff0c\u4e00\u4e2a\u7d22\u5f15\u6807\u7b7e\u4f1a\u4ee5\u5e8f\u5217\u65b9\u5f0f\u8fd4\u56de\u591a\u4e2a\u6761\u76ee\u3002\u4e0d\u91cd\u590d\u7684\u7d22\u5f15\u5219\u4f1a\u4ee5\u6807\u91cf\u503c\u7684\u5f62\u5f0f\u8fd4\u56de\u5355\u4e2a\u6761\u76ee\uff0c\u8fd9\u53ef\u80fd\u4f1a\u4f7f\u4ee3\u7801\u66f4\u590d\u6742\u3002 obj = pd.Series(range(5), index=['a', 'b', 'a', 'c', 'b']) print(obj) # a 0 # b 1 # a 2 # c 3 # b 4 # dtype: int64 print(obj.is_unique) # True print(obj.index.is_unique) # False # \u8fd4\u56de\u91cd\u590d\u7d22\u5f15\u5bf9\u5e94\u503c\u7684\u5e8f\u5217\u3002 print(obj['a']) # a 0 # a 2 # dtype: int64 df = pd.DataFrame(np.random.randn(4, 3), index=['a', 'a', 'b', 'b']) print(df) # 0 1 2 # a -0.726164 0.531540 -0.521611 # a -1.539807 -0.710880 -0.992789 # b -0.975970 -0.470725 0.121958 # b -0.301495 1.072322 -1.542296 print(df.index.is_unique) # False print(df.loc['b']) # 0 1 2 # b -0.520008 0.052574 0.638529 # b -1.928705 -1.099534 -1.605296","title":"\u542b\u6709\u91cd\u590d\u6807\u7b7e\u7684\u8f74\u7d22\u5f15"},{"location":"python/DataAnalysis/ch02/#_11","text":"pandas\u5305\u542b\u4e86\u4e00\u4e9b\u5e38\u7528\u6570\u5b66\u3001\u7edf\u8ba1\u5b66\u65b9\u6cd5\u3002\u5176\u4e2d\u5927\u90e8\u5206\u5c5e\u4e8e\u5f52\u7ea6\u6216\u6c47\u603b\u7edf\u8ba1\u7684\u7c7b\u522b\uff0c\u8fd9\u4e9b\u65b9\u6cd5\u4eceDataFrame\u7684\u884c\u6216\u5217\u4e2d\u62bd\u53d6\u4e00\u4e2aSeries\u6216\u4e00\u7cfb\u5217\u503c\uff08\u5982\u603b\u548c\u6216\u5e73\u5747\u503c\uff09\u3002 \u4e0eNumPy\u6570\u7ec4\u4e2d\u7684\u7c7b\u4f3c\u65b9\u6cd5\u76f8\u6bd4\uff0cpandas\u5185\u5efa\u4e86\u5904\u7406\u7f3a\u5931\u503c\u7684\u529f\u80fd\u3002 \u5f52\u7ea6\u65b9\u6cd5: sum() \u79ef\u7d2f\u578b\u65b9\u6cd5: cumsun() \u65e2\u4e0d\u662f\u5f52\u7ea6\u578b\u65b9\u6cd5\u4e5f\u4e0d\u662f\u79ef\u7d2f\u578b\u65b9\u6cd5: describe() df = pd.DataFrame( [[1.4, np.nan], [7.1, -4.5], [np.nan, np.nan], [0.75, -1.3]], index=list('abcd'), columns=['one', 'two'] ) print(df) # one two # a 1.40 NaN # b 7.10 -4.5 # c NaN NaN # d 0.75 -1.3 # axis=0, \u8fd4\u56de\u4e00\u4e2a\u6bcf\u5217\u7b97\u672f\u548c\u7684Series print(df.sum()) # one 9.25 # two -5.80 # dtype: float64 # axis=1\u4e14skipna=True, \u8fd4\u56de\u4e00\u4e2a\u6bcf\u884c\u548c\u7684Series, \u5ffd\u7565NA\u503c, \u586b0\u3002 print(df.sum(axis=1)) # a 1.40 # b 2.60 # c 0.00 # d -0.55 # dtype: float64 # \u4e0d\u5ffd\u7565NA\u503c\uff0c\u586bNaN\u3002 print(df.sum(axis=1, skipna=False)) # a NaN # b 2.60 # c NaN # d -0.55 # dtype: float64 # \u53ea\u67091\u7ea7\u7d22\u5f15\uff0c\u6240\u4ee5level=0\u548c\u539f\u7d22\u5f15\u6ca1\u6709\u533a\u522b\uff0cNaN\u586b\u51450\u3002 print(df.groupby(level=0).sum()) # one two # a 1.40 0.0 # b 7.10 -4.5 # c 0.00 0.0 # d 0.75 -1.3 # \u5217one\u7684\u6700\u5927\u503c\u662f\u5728\u7d22\u5f15b, \u5217two\u7684\u6700\u5927\u503c\u662f\u5728\u7d22\u5f15d print(df.idxmax()) # one b # two d # dtype: object print(df.idxmin()) # one d # two b # dtype: object # cumsun\u7684\u610f\u601d\u662f\u7b2cn\u6b21\u7684\u548c\u662fn-1\u6b21\u7684\u548c\u4e0en\u7684\u548c\uff0cone\u5217d\u884c\u7684\u548c\u5c31\u662fone\u5217a\u3001b\u3001c\u3001d\u503c\u7684\u603b\u548c\u3002 print(df.cumsum()) # one two # a 1.40 NaN # b 8.50 -4.5 # c NaN NaN # d 9.25 -5.8 \u901a\u8fc7describe\u4ea7\u751f\u7edf\u8ba1\u4fe1\u606f\uff0c\u6ce8\u610f\uff0c\u6570\u503c\u578b\u548c\u975e\u6570\u503c\u578b\u7684describe\u7684\u4fe1\u606f\u662f\u4e0d\u540c\u7684\u3002 # \u4e00\u6b21\u6027\u4ea7\u751f\u591a\u4e2a\u6c47\u603b\u7edf\u8ba1 print(df.describe()) # one two # count 3.000000 2.000000 # mean 3.083333 -2.900000 # std 3.493685 2.262742 # min 0.750000 -4.500000 # 25% 1.075000 -3.700000 # 50% 1.400000 -2.900000 # 75% 4.250000 -2.100000 # max 7.100000 -1.300000 obj = pd.Series(['a', 'a', 'b', 'c'] * 4) print(obj) # 0 a # 1 a # 2 b # 3 c # 4 a # 5 a # 6 b # 7 c # 8 a # 9 a # 10 b # 11 c # 12 a # 13 a # 14 b # 15 c # dtype: object # \u9488\u5bf9\u975e\u6570\u503c\u578b\u6570\u636e\uff0cdescribe\u4ea7\u751f\u53e6\u4e00\u79cd\u6c47\u603b\u7edf\u8ba1 print(obj.describe()) # count 16 # unique 3 # top a # freq 8 # dtype: object","title":"\u63cf\u8ff0\u6027\u7edf\u8ba1\u6982\u8ff0\u4e0e\u8ba1\u7b97"},{"location":"python/DataAnalysis/ch02/#_12","text":"\u534f\u65b9\u5dee\u4e0e\u76f8\u5173\u7cfb\u6570\u4e5f\u662f\u5728\u65f6\u57df\u5206\u6790\u65f6\u5e38\u89c1\u7684\u4e24\u4e2a\u6982\u5ff5\uff0c\u4ed6\u4eec\u90fd\u662f\u7528\u6765\u63cf\u8ff0\u6570\u636e\u201c\u50cf\u4e0d\u50cf\u201d\u7684\u3002 \u534f\u65b9\u5dee\u7684\u901a\u4fd7\u7406\u89e3\uff1a \u4e24\u4e2a\u53d8\u91cf\u5728\u53d8\u5316\u8fc7\u7a0b\u4e2d\u662f\u540c\u65b9\u5411\u53d8\u5316\u8fd8\u662f\u53cd\u65b9\u5411\u53d8\u5316\uff1f\u76f8\u540c\u6216\u8005\u76f8\u53cd\u7a0b\u5ea6\u5982\u4f55\uff1f \u4f60\u53d8\u5927\uff0c\u540c\u65f6\u6211\u53d8\u5927\uff0c\u8bf4\u660e\u4e24\u4e2a\u53d8\u91cf\u662f\u540c\u5411\u53d8\u5316\uff0c\u8fd9\u65f6\u534f\u65b9\u5dee\u5c31\u662f\u6b63\u7684\u3002 \u4f60\u53d8\u5927\uff0c\u540c\u65f6\u6211\u53d8\u5c0f\uff0c\u8bf4\u660e\u4e24\u4e2a\u53d8\u91cf\u662f\u53cd\u5411\u53d8\u5316\uff0c\u8fd9\u65f6\u534f\u65b9\u5dee\u5c31\u662f\u8d1f\u7684\u3002 \u4ece\u6570\u503c\u770b\uff0c\u534f\u65b9\u5dee\u7684\u6570\u503c\u8d8a\u5927\uff0c\u4e24\u4e2a\u53d8\u91cf\u540c\u5411\u7a0b\u5ea6\u4e5f\u5c31\u8d8a\u5927\u3002\u53cd\u4e4b\u4ea6\u7136\u3002 \u76f8\u5173\u7cfb\u6570\u7684\u901a\u4fd7\u7406\u89e3\uff1a \u7528X\uff0cY\u7684\u534f\u65b9\u5dee\u9664\u4ee5X\u7684\u6807\u51c6\u5dee\u548cY\u7684\u6807\u51c6\u5dee\u3002\u76f8\u5173\u7cfb\u6570\u4e5f\u53ef\u4ee5\u770b\u6210\u534f\u65b9\u5dee\uff0c\u4e00\u79cd\u63d0\u51fa\u4e86\u4e24\u4e2a\u53d8\u91cf\u91cf\u7eb2\u5f71\u54cd\u3001\u6807\u51c6\u5316\u540e\u7684\u7279\u6b8a\u534f\u65b9\u5dee\u3002\u6240\u4ee5\uff1a\u4e5f\u53ef\u4ee5\u53cd\u6620\u4e24\u4e2a\u53d8\u91cf\u53d8\u5316\u65f6\u662f\u540c\u5411\u8fd8\u662f\u53cd\u5411\uff0c\u5982\u679c\u540c\u5411\u53d8\u5316\u5c31\u4e3a\u6b63\uff0c\u53cd\u5411\u53d8\u5316\u5c31\u4e3a\u8d1f\u3002 \u7531\u4e8e\u662f\u6807\u51c6\u7248\u540e\u7684\u534f\u65b9\u5dee\uff0c\u76f8\u5173\u7cfb\u6570\u6d88\u9664\u4e86\u4e24\u4e2a\u53d8\u91cf\u53d8\u5316\u5e45\u5ea6\u7684\u5f71\u54cd\uff0c\u800c\u53ea\u662f\u5355\u7eaf\u53cd\u5e94\u4e24\u4e2a\u53d8\u91cf\u6bcf\u5355\u4f4d\u53d8\u5316\u65f6\u7684\u76f8\u4f3c\u7a0b\u5ea6\u3002 \u603b\u7ed3\uff1a \u5bf9\u4e8e\u4e24\u4e2a\u53d8\u91cfX\u3001Y\uff0c \u5f53\u4ed6\u4eec\u7684\u76f8\u5173\u7cfb\u6570\u4e3a1\u65f6\uff0c\u8bf4\u660e\u4e24\u4e2a\u53d8\u91cf\u53d8\u5316\u65f6\u7684\u6b63\u5411\u76f8\u4f3c\u5ea6\u6700\u5927\u3002 \u5f53\u4ed6\u4eec\u7684\u76f8\u5173\u7cfb\u6570\u4e3a\uff0d1\u65f6\uff0c\u8bf4\u660e\u4e24\u4e2a\u53d8\u91cf\u53d8\u5316\u7684\u53cd\u5411\u76f8\u4f3c\u5ea6\u6700\u5927\u3002 \u968f\u7740\u4ed6\u4eec\u76f8\u5173\u7cfb\u6570\u51cf\u5c0f\uff0c\u4e24\u4e2a\u53d8\u91cf\u53d8\u5316\u65f6\u7684\u76f8\u4f3c\u5ea6\u4e5f\u53d8\u5c0f\uff0c\u5f53\u76f8\u5173\u7cfb\u6570\u4e3a0\u65f6\uff0c\u4e24\u4e2a\u53d8\u91cf\u7684\u53d8\u5316\u8fc7\u7a0b\u6ca1\u6709\u4efb\u4f55\u76f8\u4f3c\u5ea6\uff0c\u4e5f\u5373\u4e24\u4e2a\u53d8\u91cf\u65e0\u5173\u3002 \u5f53\u76f8\u5173\u7cfb\u6570\u7ee7\u7eed\u53d8\u5c0f\uff0c\u5c0f\u4e8e0\u65f6\uff0c\u4e24\u4e2a\u53d8\u91cf\u5f00\u59cb\u51fa\u73b0\u53cd\u5411\u7684\u76f8\u4f3c\u5ea6\uff0c\u968f\u7740\u76f8\u5173\u7cfb\u6570\u7ee7\u7eed\u53d8\u5c0f\uff0c\u53cd\u5411\u76f8\u4f3c\u5ea6\u4f1a\u9010\u6e10\u53d8\u5927\u3002 \u4e0b\u9762\u7684\u4f8b\u5b50\u4f7f\u7528 pandas-datareader\uff1a https://pypi.org/project/pandas-datareader/ https://pydata.github.io/pandas-datareader/) \u5728\u6240\u6709\u4f8b\u5b50\u4e2d\uff0c\u5728\u8ba1\u7b97\u76f8\u5173\u6027\u4e4b\u524d\uff0c\u6570\u636e\u70b9\u5df2\u7ecf\u6309\u6807\u7b7e\u8fdb\u884c\u4e86\u5bf9\u9f50\u3002 \u4e0b\u4f8b\u9700\u8981\u901a\u8fc7pandas-datareader\u5e93\u4eceYahoo! Finance\u4e0a\u83b7\u53d6\u7684\u5305\u542b\u80a1\u4ef7\u548c\u4ea4\u6613\u91cf\u7684DataFrame\u3002 import pandas_datareader.data as web all_data = { ticker: web.get_data_yahoo(ticker) for ticker in ['AAPL', 'IBM', 'MSFT', 'GOOG'] } price = pd.DataFrame( { ticker: data['Adj Close'] for ticker, data in all_data.items() } ) volume = pd.DataFrame( { ticker: data['Volume'] for ticker, data in all_data.items() } ) returns = price.pct_change() print(returns.tail()) # AAPL IBM MSFT GOOG # Date # 2021-08-09 -0.000342 -0.008424 -0.003904 0.007049 # 2021-08-10 -0.003354 0.000920 -0.006555 0.000685 # 2021-08-11 0.001786 0.005305 0.001781 -0.002947 # 2021-08-12 0.020773 0.006614 0.009967 0.005084 # 2021-08-13 0.001410 0.000769 0.010490 0.000119 Series\u7684corr\u65b9\u6cd5\u8ba1\u7b97\u7684\u662f\u4e24\u4e2aSeries\u4e2d\u91cd\u53e0\u7684\u3001\u975eNA\u7684\u3001\u6309\u7d22\u5f15\u5bf9\u9f50\u7684\u503c\u7684\u76f8\u5173\u6027\u3002\u76f8\u5e94\u5730\uff0ccov\u8ba1\u7b97\u7684\u662f\u534f\u65b9\u5dee print(returns['MSFT']) # Date # 2016-08-15 NaN # 2016-08-16 -0.005540 # 2016-08-17 0.002089 # 2016-08-18 0.000695 # 2016-08-19 0.000347 # ... # 2021-08-09 -0.003904 # 2021-08-10 -0.006555 # 2021-08-11 0.001781 # 2021-08-12 0.009967 # 2021-08-13 0.010490 # Name: MSFT, Length: 1259, dtype: float64 # Series\u7684corr\u65b9\u6cd5\u8ba1\u7b97\u7684\u662f\u4e24\u4e2aSeries\u4e2d\u91cd\u53e0\u7684\u3001\u975eNA\u7684\u3001\u6309\u7d22\u5f15\u5bf9\u9f50\u7684\u503c\u7684\u76f8\u5173\u6027\u3002 print(returns['MSFT'].corr(returns['IBM'])) # 0.5175237180581937 # \u7b49\u540c\u5199\u6cd5\uff0cMSFT\u662f\u4e00\u4e2a\u6709\u6548\u7684Python\u5c5e\u6027 print(returns.MSFT.corr(returns.IBM)) # 0.5175237180581937 # Series\u7684cov\u65b9\u6cd5\u8ba1\u7b97\u7684\u662f\u4e24\u4e2aSeries\u4e2d\u503c\u7684\u534f\u65b9\u5dee\u3002 print(returns['MSFT'].cov(returns['IBM'])) # 0.0001452224236764915 DataFrame\u7684corr\u548ccov\u65b9\u6cd5\u4f1a\u5206\u522b\u4ee5DataFrame\u7684\u5f62\u5f0f\u8fd4\u56de\u76f8\u5173\u6027\u548c\u534f\u65b9\u5dee\u77e9\u9635\u3002 print(returns.corr()) # AAPL IBM MSFT GOOG # AAPL 1.000000 0.441111 0.735539 0.661961 # IBM 0.441111 1.000000 0.517524 0.484230 # MSFT 0.735539 0.517524 1.000000 0.775756 # GOOG 0.661961 0.484230 0.775756 1.000000 # \u7ed9corrwith\u65b9\u6cd5\uff0c\u4f20\u5165\u4e00\u4e2aSeries\u65f6\uff0c\u4f1a\u8fd4\u56de\u4e00\u4e2a\u542b\u6709\u4e3a\u6bcf\u5217\u8ba1\u7b97\u76f8\u5173\u6027\u503c\u7684Series print(returns.corrwith(returns['IBM'])) # AAPL 0.441111 # IBM 1.000000 # MSFT 0.517524 # GOOG 0.484230 # dtype: float64 # \u7ed9corrwith\u65b9\u6cd5\uff0c\u4f20\u5165\u4e00\u4e2aDataFrame\u65f6\uff0c\u4f1a\u8ba1\u7b97\u5339\u914d\u5230\u5217\u540d\u7684\u76f8\u5173\u6027\u6570\u503c\u3002\u4e0b\u9762\u662f\u8ba1\u7b97\u4ea4\u6613\u91cf\u767e\u5206\u6bd4\u53d8\u5316\u7684\u76f8\u5173\u6027 print(returns.corrwith(volume)) # AAPL -0.063111 # IBM -0.103721 # MSFT -0.056842 # GOOG -0.119026 # dtype: float64 print(returns.cov()) # AAPL IBM MSFT GOOG # AAPL 0.000361 0.000137 0.000240 0.000211 # IBM 0.000137 0.000268 0.000145 0.000133 # MSFT 0.000240 0.000145 0.000294 0.000224 # GOOG 0.000211 0.000133 0.000224 0.000282","title":"\u76f8\u5173\u6027\u548c\u534f\u65b9\u5dee"},{"location":"python/DataAnalysis/ch02/#_13","text":"obj = pd.Series(['c', 'a', 'd', 'a', 'a', 'a', 'b', 'b', 'c', 'c']) print(obj) # 0 c # 1 a # 2 d # 3 a # 4 a # 5 a # 6 b # 7 b # 8 c # 9 c # dtype: object \u51fd\u6570 unique \u7ed9\u51faSeries\u4e2d\u7684\u552f\u4e00\u503c\u3002 print(obj.unique()) # ['c' 'a' 'd' 'b'] print(obj.sort_values().unique()) # ['a' 'b' 'c' 'd'] # value_counts\u8ba1\u7b97Series\u5305\u542b\u7684\u503c\u7684\u4e2a\u6570 print(obj.value_counts()) # a 4 # c 3 # b 2 # d 1 # dtype: int64 # \u8fd9\u91ccvalue_counts\u4e0d\u662fSeries\u7684\u65b9\u6cd5\uff0c\u662fpandas\u9876\u5c42\u65b9\u6cd5 print(pd.value_counts(obj.values, sort=True)) # a 4 # c 3 # b 2 # d 1 # dtype: int64 print(obj.isin(['b', 'c'])) # 0 True # 1 False # 2 False # 3 False # 4 False # 5 False # 6 True # 7 True # 8 True # 9 True # dtype: bool # \u5c06\u4e0a\u9762\u7684\u7ed3\u679c\u4f5c\u4e3a\u5217\u8868\u8f93\u5165\u7684\u6761\u4ef6\uff0c\u8f93\u51fa\u4e3aTrue\u7684\u7ed3\u679c print(obj[obj.isin(['b', 'c'])]) # 0 c # 6 b # 7 b # 8 c # 9 c # dtype: object \u53c2\u8003: pandas.Index.get_indexer obj1 = pd.Series(['c', 'a', 'd', 'a', 'a', 'a', 'b', 'b', 'c', 'c']) obj2 = pd.Series(['c', 'a', 'b']) print(pd.Index(obj1)) # Index(['c', 'a', 'd', 'a', 'a', 'a', 'b', 'b', 'c', 'c'], dtype='object') print(pd.Index(obj2)) # Index(['c', 'a', 'b'], dtype='object') # \u8fd9\u91cc0\u5bf9\u5e94obj2\u91cc\u9762\u7684c\u5728job1\u7684\u4f4d\u7f6e\uff0c\u4ee5\u6b64\u7c7b\u63a8\uff0c\u751f\u6210\u65b0\u7684\u7d22\u5f15\u5217\u8868 print(pd.Index(obj2).get_indexer(obj1)) # [ 0 1 -1 1 1 1 2 2 0 0] \u8ba1\u7b97DataFrame\u591a\u4e2a\u76f8\u5173\u5217\u7684\u76f4\u65b9\u56fe\u3002 data = pd.DataFrame( { 'Que1': [1, 3, 4, 3, 4], 'Que2': [2, 3, 1, 2, 3], 'Que3': [1, 5, 2, 4, 4], } ) print(data) # Que1 Que2 Que3 # 0 1 2 1 # 1 3 3 5 # 2 4 1 2 # 3 3 2 4 # 4 4 3 4 result = data.apply(pd.value_counts).fillna(0) # \u4e0b\u9762\u7ed3\u679c\u4e2d\u7684\u884c\u6807\u7b7e\u662f\u6240\u6709\u5217\u4e2d\u51fa\u73b0\u7684\u4e0d\u540c\u503c\uff0c\u6570\u503c\u5219\u662f\u8fd9\u4e9b\u4e0d\u540c\u503c\u5728\u6bcf\u4e2a\u5217\u4e2d\u51fa\u73b0\u7684\u6b21\u6570\uff0c\u4f8b\u5982\uff1a\u6570\u5b575\u53ea\u5728Que3\u91cc\u9762\u51fa\u73b0\u4e86\u4e00\u6b21 print(result) # Que1 Que2 Que3 # 1 1.0 1.0 1.0 # 2 0.0 2.0 1.0 # 3 2.0 2.0 0.0 # 4 2.0 0.0 2.0 # 5 0.0 0.0 1.0","title":"\u552f\u4e00\u503c\u3001\u8ba1\u6570\u548c\u6210\u5458\u5c5e\u6027"},{"location":"python/DataAnalysis/ch03/","text":"\u6570\u636e\u8f7d\u5165\u3001\u5b58\u50a8\u53ca\u6587\u4ef6\u683c\u5f0f \u00b6 \u6587\u672c\u683c\u5f0f\u6570\u636e\u7684\u8bfb\u5199 \u00b6 import numpy as np import pandas as pd import sys import csv import json \u5c06\u8868\u683c\u578b\u6570\u636e\u8bfb\u53d6\u4e3aDataFrame\u5bf9\u8c61\u662fpandas\u7684\u91cd\u8981\u7279\u6027\u3002 \u4e0b\u9762\u662f\u90e8\u5206\u5b9e\u73b0\u6587\u4ef6\u8bfb\u53d6\u529f\u80fd\u7684\u51fd\u6570\uff0cread_csv\u548cread_table\u53ef\u80fd\u662f\u540e\u671f\u6211\u4eec\u4f7f\u7528\u6700\u591a\u7684\u51fd\u6570\u3002 \u8fd9\u4e9b\u51fd\u6570\u7684\u53ef\u9009\u53c2\u6570\u4e3b\u8981\u6709\u4ee5\u4e0b\u51e0\u79cd\u7c7b\u578b\uff1a \u7d22\u5f15\uff1a\u53ef\u4ee5\u5c06\u4e00\u5217\u6216\u591a\u4e2a\u5217\u4f5c\u4e3a\u8fd4\u56de\u7684DataFrame\uff0c\u4ece\u6587\u4ef6\u6216\u7528\u6237\u5904\u83b7\u5f97\u5217\u540d\uff0c\u6216\u8005\u6ca1\u6709\u5217\u540d\u3002 \u7c7b\u578b\u63a8\u65ad\u548c\u6570\u636e\u8f6c\u6362\uff1a\u5305\u62ec\u7528\u6237\u81ea\u5b9a\u4e49\u7684\u503c\u8f6c\u6362\u548c\u81ea\u5b9a\u4e49\u7684\u7f3a\u5931\u503c\u7b26\u53f7\u5217\u8868\u3002 \u65e5\u671f\u65f6\u95f4\u89e3\u6790\uff1a\u5305\u62ec\u7ec4\u5408\u529f\u80fd\uff0c\u4e5f\u5305\u62ec\u5c06\u5206\u6563\u5728\u591a\u4e2a\u5217\u4e0a\u7684\u65e5\u671f\u548c\u65f6\u95f4\u4fe1\u606f\u7ec4\u5408\u6210\u7ed3\u679c\u4e2d\u7684\u5355\u4e2a\u5217\u3002 \u8fed\u4ee3\uff1a\u652f\u6301\u5bf9\u5927\u578b\u6587\u4ef6\u7684\u5206\u5757\u8fed\u4ee3\u3002 \u672a\u6e05\u6d17\u6570\u636e\u95ee\u9898\uff1a\u8df3\u8fc7\u884c\u3001\u9875\u811a\u3001\u6ce8\u91ca\u4ee5\u53ca\u5176\u4ed6\u6b21\u8981\u6570\u636e\uff0c\u6bd4\u5982\u4f7f\u7528\u9017\u53f7\u5206\u9694\u5343\u4f4d\u7684\u6570\u5b57\u3002 file01 = '../examples/ex1.csv' # \u4f7f\u7528read_csv\u5c06\u6587\u4ef6\u8bfb\u5165\u4e00\u4e2aDataFrame df = pd.read_csv(file01) print(df) # 1 2 3 4 hello # 0 5 6 7 8 world # 1 9 10 11 12 foo df = pd.read_csv(file01, header=None) # \u4f7f\u7528pandas\u81ea\u52a8\u5206\u914d\u9ed8\u8ba4\u5217\u540d print(df) # 0 1 2 3 4 # 0 1 2 3 4 hello # 1 5 6 7 8 world # 2 9 10 11 12 foo df = pd.read_csv(file01, names=['aa', 'bb', 'cc', 'dd', 'message']) # \u81ea\u5df1\u6307\u5b9a\u5217\u540d print(df) # aa bb cc dd ee # 0 1 2 3 4 hello # 1 5 6 7 8 world # 2 9 10 11 12 foo # \u4f7f\u7528read_table\uff0c\u5e76\u6307\u5b9a\u5206\u9694\u7b26\uff0c\u5c06\u6587\u4ef6\u8bfb\u5165\u4e00\u4e2aDataFrame df = pd.read_table(file01, sep=',') print(df) # a b c d message # 0 1 2 3 4 hello # 1 5 6 7 8 world # 2 9 10 11 12 foo \u4ece\u591a\u4e2a\u5217\u4e2d\u5f62\u6210\u4e00\u4e2a\u5206\u5c42\u7d22\u5f15 parased = pd.read_csv('../examples/csv_mindex.csv', index_col=['key1', 'key2']) print(parased) # value1 value2 # key1 key2 # one a 1 2 # b 3 4 # c 5 6 # d 7 8 # two a 9 10 # b 11 12 # c 13 14 # d 15 16 \u4e0b\u4f8b\u4e2d\uff0c\u7531\u4e8e\u5217\u540d\u7684\u6570\u91cf\u6bd4\u6570\u636e\u7684\u5217\u6570\u5c11\u4e00\u4e2a\uff0c\u56e0\u6b64read_table\u63a8\u65ad\u7b2c\u4e00\u5217\u5e94\u5f53\u4f5c\u4e3aDataFrame\u7684\u7d22\u5f15\u3002 ex3.txt\u539f\u59cb\u6587\u4ef6\u5185\u5bb9 A B C aaa -0.264438 -1.026059 -0.619500 bbb 0.927272 0.302904 -0.032399 ccc -0.264273 -0.386314 -0.217601 ddd -0.871858 -0.348382 1.100491 result = pd.read_table('../examples/ex3.txt') # \u76f4\u63a5\u8bfb\u53d6 print(result) # A B C # aaa -0.264438 -1.026059 -0.619500 # bbb 0.927272 0.302904 -0.032399 NaN # ccc -0.264273 -0.386314 -0.217601 # ddd -0.871858 -0.348382 1.100491 result = pd.read_table('../examples/ex3.txt', sep='\\s+') # \u5411read_table\u6b63\u5219\u8868\u8fbe\u5f0f\u4e3a\\s+\u6765\u683c\u5f0f\u5316\u6587\u4ef6 print(result) # A B C # aaa -0.264438 -1.026059 -0.619500 # bbb 0.927272 0.302904 -0.032399 # ccc -0.264273 -0.386314 -0.217601 # ddd -0.871858 -0.348382 1.100491 \u4e0b\u4f8b\u4e2dex4.csv\u539f\u59cb\u6587\u4ef6\u5185\u5bb9 # hey! a,b,c,d,message # just wanted to make things more difficult for you # who reads CSV files with computers, anyway? 1,2,3,4,hello 5,6,7,8,world 9,10,11,12,foo result = pd.read_csv('../examples/ex4.csv', skiprows=[0, 2, 3]) # \u4f7f\u7528skiprows\u6765\u8df3\u8fc7\u7b2c\u4e00\u884c\u3001\u7b2c\u4e09\u884c\u548c\u7b2c\u56db\u884c print(result) # a b c d message # 0 1 2 3 4 hello # 1 5 6 7 8 world # 2 9 10 11 12 foo \u7f3a\u5931\u503c\u5904\u7406 \u9ed8\u8ba4\u60c5\u51b5\u4e0b\uff0cpandas\u4f7f\u7528\u4e00\u4e9b\u5e38\u89c1\u7684\u6807\u8bc6\uff0c\u4f8b\u5982 NA \u548c NULL \u4e0b\u4f8b\u4e2dex5.csv\u539f\u59cb\u6587\u4ef6\u5185\u5bb9 something,a,b,c,d,message one,1,2,3,4,NA two,5,6,,8,world three,9,10,11,12,foo result = pd.read_csv('../examples/ex5.csv') print(result) # something a b c d message # 0 one 1 2 3.0 4 NaN # 1 two 5 6 NaN 8 world # 2 three 9 10 11.0 12 foo print(pd.isnull(result)) # something a b c d message # 0 False False False False False True # 1 False False False True False False # 2 False False False False False False result = pd.read_csv('../examples/ex5.csv', na_values=['NULL']) print(result) # something a b c d message # 0 one 1 2 3.0 4 NaN # 1 two 5 6 NaN 8 world # 2 three 9 10 11.0 12 foo \u5b9a\u4e49\u66ff\u6362\u89c4\u5219 sentinels = { 'message': ['foo', 'NA'], 'something': ['two'] } result = pd.read_csv('../examples/ex5.csv', na_values=sentinels) \u628amessage\u5217\u6240\u6709\u503c\u4e3afoo\u6216NA\u7684\u66ff\u6362\u4e3aNull \u628asomething\u5217\u6240\u6709\u503c\u4e3atwo\u7684\u66ff\u6362\u4e3aNull print(result) # something a b c d message # 0 one 1 2 3.0 4 NaN # 1 NaN 5 6 NaN 8 world # 2 three 9 10 11.0 12 NaN \u5206\u5757\u8bfb\u5165\u6587\u672c\u6587\u4ef6 \u00b6 pd.options.display.max_rows = 10 result = pd.read_csv('../examples/ex6.csv') # \u8bfb\u53d6\u5168\u90e8\u8bb0\u5f55 print(result) result = pd.read_csv('../examples/ex6.csv', nrows=5) # \u8bfb\u53d6\u524d5\u884c\u8bb0\u5f55 print(result) # [10000 rows x 5 columns] # one two three four key # 0 0.467976 -0.038649 -0.295344 -1.824726 L # 1 -0.358893 1.404453 0.704965 -0.200638 B # 2 -0.501840 0.659254 -0.421691 -0.057688 G # 3 0.204886 1.074134 1.388361 -0.982404 R # 4 0.354628 -0.133116 0.283763 -0.837063 Q result = pd.read_csv('../examples/ex6.csv', chunksize=1000) # \u5206\u5757\u8bfb\u5165\u6587\u4ef6\uff0c\u6bcf\u57571000\u884c print(result) # \u8fd4\u56de\u7684\u662f\u4e00\u4e2aTextParser\u5bf9\u8c61, \u5141\u8bb8\u4f60\u6839\u636echunksize\u904d\u5386\u6587\u4ef6\u3002 # \u53ef\u4ee5\u904d\u5386 ex6.csv \uff0c\u5e76\u5bf9 key \u5217\u805a\u5408\u83b7\u5f97\u8ba1\u6570\u503c tot = pd.Series([], dtype=float) # \u8fd9\u91cc\u9700\u8981\u663e\u5f0f\u6307\u5b9adtype\uff0c\u540e\u7eedPython\u4f1a\u5c06\u9ed8\u8ba4\u503c\u4ecefloat64\u53d8\u6210object\uff0c\u76ee\u524d\u9ed8\u8ba4\u662ffloat64 for piece in result: tot = tot.add(piece['key'].value_counts(), fill_value=0) tot = tot.sort_values(ascending=False) print(tot[:10]) # E 368.0 # X 364.0 # L 346.0 # O 343.0 # Q 340.0 # M 338.0 # J 337.0 # F 335.0 # K 334.0 # H 330.0 # dtype: float64 \u5c06\u6570\u636e\u5199\u5165\u6587\u672c\u683c\u5f0f \u00b6 data = pd.read_csv('../examples/ex5.csv') print(data) # something a b c d message # 0 one 1 2 3.0 4 NaN # 1 two 5 6 NaN 8 world # 2 three 9 10 11.0 12 foo \u4f7f\u7528DataFrame\u7684 to_csv \u65b9\u6cd5\uff0c\u5c06\u6570\u636e\u5bfc\u51fa\u4e3a\u9017\u53f7\u5206\u9694\u7684\u6587\u4ef6 data.to_csv('../examples/out.csv') # \u8f93\u51faout.csv\u7684\u5185\u5bb9 # ,something,a,b,c,d,message # 0,one,1,2,3.0,4, # 1,two,5,6,,8,world # 2,three,9,10,11.0,12,foo \u4f7f\u7528DataFrame\u7684 to_csv \u65b9\u6cd5\uff0c\u5c06\u6570\u636e\u5bfc\u51fa\u4e3a\u5176\u4ed6\u7684\u5206\u9694\u7b26\u7684\u6587\u4ef6 data.to_csv(sys.stdout, sep='|') # |something|a|b|c|d|message # 0|one|1|2|3.0|4| # 1|two|5|6||8|world # 2|three|9|10|11.0|12|foo data.to_csv(sys.stdout, sep=',') # ,something,a,b,c,d,message # 0,one,1,2,3.0,4, # 1,two,5,6,,8,world # 2,three,9,10,11.0,12,foo data.to_csv(sys.stdout, sep=',', na_rep='NULL') # \u8bbe\u5b9a\u7f3a\u5931\u503c\u5728\u8f93\u51fa\u65f6\u4ee5\u7a7a\u5b57\u7b26\u4e32\u51fa\u73b0 # ,something,a,b,c,d,message # 0,one,1,2,3.0,4,NULL # 1,two,5,6,NULL,8,world # 2,three,9,10,11.0,12,foo data.to_csv(sys.stdout, sep=',', na_rep='NULL', index=False, header=False) # \u4e0d\u8f93\u51fa\u884c\u548c\u5217\u7684\u6807\u7b7e\uff08index\uff0cheader\uff09 # one,1,2,3.0,4,NULL # two,5,6,NULL,8,world # three,9,10,11.0,12,foo data.to_csv(sys.stdout, sep=',', na_rep='NULL', index=False, header=False, columns=['a', 'b', 'c']) # \u6309\u7167\u81ea\u5b9a\u7684\u987a\u5e8f\u8f93\u51fa\u5b50\u96c6 # 1,2,3.0 # 5,6,NULL # 9,10,11.0 Series\u4e5f\u6709 to_csv \u65b9\u6cd5 dates = pd.date_range('1/1/2000', periods=7) ts = pd.Series(np.arange(7), index=dates) ts.to_csv('../examples/tseries.csv', header=False) # \u8f93\u51fatseries.csv\u6587\u4ef6\u5185\u5bb9 # 2000-01-01,0 # 2000-01-02,1 # 2000-01-03,2 # 2000-01-04,3 # 2000-01-05,4 # 2000-01-06,5 # 2000-01-07,6 \u4f7f\u7528\u5206\u9694\u683c\u5f0f \u00b6 \u7edd\u5927\u591a\u6570\u7684\u8868\u578b\u6570\u636e\u90fd\u53ef\u4ee5\u4f7f\u7528\u51fd\u6570 pandas.read_table \u4ece\u786c\u76d8\u4e2d\u8bfb\u53d6\u3002 \u7136\u800c\uff0c\u5728\u67d0\u4e9b\u60c5\u51b5\u4e0b\uff0c\u63a5\u6536\u4e00\u4e2a\u5e26\u6709\u4e00\u884c\u6216\u591a\u884c\u9519\u8bef\u7684\u6587\u4ef6\u5e76\u4e0d\u5c11\u89c1\uff0c read_table \u4e5f\u65e0\u6cd5\u89e3\u51b3\u8fd9\u79cd\u60c5\u51b5\u3002 ex7.csv \u6587\u4ef6\u5185\u5bb9 \"a\",\"b\",\"c\" \"1\",\"2\",\"3\" \"1\",\"2\",\"3\" f = open('../examples/ex7.csv') # \u4f7f\u7528Python\u7684\u5185\u5efacsv\u6a21\u5757 reader = csv.reader(f) # \u5c06\u4efb\u4e00\u6253\u5f00\u7684\u6587\u4ef6\u6216\u6587\u4ef6\u578b\u5bf9\u8c61\u4f20\u7ed9csv.reader for line in reader: # # \u904d\u5386reader\uff0c\u4ea7\u751f\u5143\u7ec4\uff0c\u5143\u7ec4\u7684\u503c\u4e3a\u5220\u9664\u4e86\u5f15\u53f7\u7684\u5b57\u7b26 print(line) f.close() # ['a', 'b', 'c'] # ['1', '2', '3'] # ['1', '2', '3'] with open('../examples/ex7.csv') as f: lines = list(csv.reader(f)) # \u9996\u5148\uff0c\u5c06\u6587\u4ef6\u8bfb\u53d6\u4e3a\u884c\u7684\u5217\u8868 header, values = lines[0], lines[1:] # \u5176\u6b21\uff0c\u5c06\u6570\u636e\u62c6\u5206\u4e3a\u5217\u540d\u884c\u548c\u6570\u636e\u884c data_dict = { h: v for h, v in zip(header, zip(*values)) # \u518d\u7136\u540e\uff0c\u4f7f\u7528\u5b57\u5178\u63a8\u5bfc\u5f0f\u548c\u8868\u8fbe\u5f0fzip(*values)\u751f\u6210\u4e00\u4e2a\u5305\u542b\u6570\u636e\u5217\u7684\u5b57\u5178\uff0c\u5b57\u5178\u4e2d\u884c\u8f6c\u7f6e\u6210\u5217 } print(data_dict) # \u8f93\u51fa\u7ed3\u679c # {'a': ('1', '1'), 'b': ('2', '2'), 'c': ('3', '3')} \u5982\u679c\u9700\u6839\u636e\u4e0d\u540c\u7684\u5206\u9694\u7b26\u3001\u5b57\u7b26\u4e32\u5f15\u7528\u7ea6\u5b9a\u6216\u884c\u7ec8\u6b62\u7b26\u5b9a\u4e49\u4e00\u79cd\u65b0\u7684\u683c\u5f0f\u65f6\uff0c\u53ef\u4ee5: \u65b9\u6cd51\uff1a\u4f7f\u7528csv.Dialect\u5b9a\u4e49\u4e00\u4e2a\u7b80\u5355\u7684\u5b50\u7c7b class my_dialect(csv.Dialect): lineterminator = '\\n' delimiter = ';' # \u8fd9\u91cc\u53ea\u80fd\u662f\u4e00\u4e2a\u5b57\u7b26 quotechar = '\"' quoting = csv.QUOTE_MINIMAL f = open('../examples/ex7.csv') reader = csv.reader(f, dialect=my_dialect) for line in reader: # \u904d\u5386reader\uff0c\u4ea7\u751f\u5143\u7ec4\uff0c\u5143\u7ec4\u7684\u503c\u4e3a\u5220\u9664\u4e86\u5f15\u53f7\u7684\u5b57\u7b26 print(line) f.close() # ['a,\"b\",\"c\"'] # ['1,\"2\",\"3\"'] # ['1,\"2\",\"3\"'] \u65b9\u6cd52\uff1a\u76f4\u63a5\u5c06CSV\u65b9\u8a00\u53c2\u6570(dialect)\u4f20\u5165csv.reader\u7684\u5173\u952e\u5b57\u53c2\u6570\u3002 \u6bd4\u8f83\u8be6\u7ec6\u7684 \u4ecb\u7ecd\u65b9\u8a00\u548c\u5206\u9694\u7b26 f = open('../examples/ex7.csv') reader = csv.reader(f, delimiter='|') for line in reader: # \u904d\u5386reader\uff0c\u4ea7\u751f\u5143\u7ec4\uff0c\u5143\u7ec4\u7684\u503c\u4e3a\u5220\u9664\u4e86\u5f15\u53f7\u7684\u5b57\u7b26 print(line) f.close() # ['a,\"b\",\"c\"'] # ['1,\"2\",\"3\"'] # ['1,\"2\",\"3\"'] \u5bf9\u4e8e\u5177\u6709\u66f4\u590d\u6742\u6216\u56fa\u5b9a\u7684\u591a\u5b57\u7b26\u5206\u9694\u7b26\u7684\u6587\u4ef6\uff0c\u5c06\u65e0\u6cd5\u4f7f\u7528csv\u6a21\u5757\u3002 \u5728\u6b64\u7c7b\u60c5\u51b5\u4e0b\uff0c\u5c06\u4f7f\u7528\u5b57\u7b26\u4e32\u7684split\u65b9\u6cd5\u6216\u6b63\u5219\u8868\u8fbe\u5f0f\u65b9\u6cd5re.split\u8fdb\u884c\u884c\u62c6\u5206\u548c\u5176\u4ed6\u6e05\u7406\u5de5\u4f5c\u3002 \u9700\u8981\u624b\u52a8\u5199\u5165\u88ab\u5206\u9694\u7684\u6587\u4ef6\u65f6\uff0c\u4f60\u53ef\u4ee5\u4f7f\u7528csv.writer\u3002 \u8fd9\u4e2a\u51fd\u6570\u63a5\u6536\u4e00\u4e2a\u5df2\u7ecf\u6253\u5f00\u7684\u53ef\u5199\u5165\u6587\u4ef6\u5bf9\u8c61\u4ee5\u53ca\u548ccsv.reader\u76f8\u540c\u7684CSV\u65b9\u8a00\u3001\u683c\u5f0f\u9009\u9879. with open('../examples/mydata.csv', 'w') as f: writer = csv.writer(f, dialect=my_dialect) writer.writerow(('1', '2', '3')) writer.writerow(('4', '5', '6')) writer.writerow(('7', '8', '9')) writer.writerow(('10', '11', '12')) # mydata.csv \u6587\u4ef6\u5185\u5bb9 # 1;2;3 # 4;5;6 # 7;8;9 # 10;11;12 JSON\u6570\u636e \u00b6 obj = \"\"\" { \"name\": \"Wes\", \"places_lived\": [\"United States\", \"Spain\", \"Germany\"], \"pet\": null, \"siblings\": [ { \"name\": \"Scott\", \"age\": 30, \"pets\": [\"Zeus\", \"Zuko\"] }, { \"name\": \"Katie\", \"age\": 38, \"pets\": [\"Sixes\", \"Stache\", \"Cisco\"] } ] } \"\"\" \u5c06JSON\u5b57\u7b26\u4e32\u8f6c\u6362\u4e3aPython\u5f62\u5f0f\u65f6\uff0c\u4f7f\u7528json.loads\u65b9\u6cd5 result = json.loads(obj) print(result) # {'name': 'Wes', 'places_lived': ['United States', 'Spain', 'Germany'], 'pet': None, 'siblings': [{'name': 'Scott', 'age': 30, 'pets': ['Zeus', 'Zuko']}, {'name': 'Katie', 'age': 38, 'pets': ['Sixes', 'Stache', 'Cisco']}]} \u53e6\u4e00\u65b9\u9762\uff0cjson.dumps\u53ef\u4ee5\u5c06Python\u5bf9\u8c61\u8f6c\u6362\u56deJSON asjson = json.dumps(result) print(asjson) # {\"name\": \"Wes\", \"places_lived\": [\"United States\", \"Spain\", \"Germany\"], \"pet\": null, \"siblings\": [{\"name\": \"Scott\", \"age\": 30, \"pets\": [\"Zeus\", \"Zuko\"]}, {\"name\": \"Katie\", \"age\": 38, \"pets\": [\"Sixes\", \"Stache\", \"Cisco\"]}]} \u5c06JSON\u5bf9\u8c61\u6216\u5bf9\u8c61\u5217\u8868\u8f6c\u6362\u4e3aDataFrame\u6216\u5176\u4ed6\u6570\u636e\u7ed3\u6784\u3002 \u6bd4\u8f83\u65b9\u4fbf\u7684\u65b9\u5f0f\u662f\u5c06\u5b57\u5178\u6784\u6210\u7684\u5217\u8868\uff08\u4e4b\u524d\u662fJSON\u5bf9\u8c61\uff09\u4f20\u5165DataFrame\u6784\u9020\u51fd\u6570\uff0c\u5e76\u9009\u51fa\u6570\u636e\u5b57\u6bb5\u7684\u5b50\u96c6\u3002 siblings = pd.DataFrame(result['siblings'], columns=['name', 'age']) print(siblings) # name age # 0 Scott 30 # 1 Katie 38 pandas.read_json\u53ef\u4ee5\u81ea\u52a8\u5c06JSON\u6570\u636e\u96c6\u6309\u7167\u6307\u5b9a\u6b21\u5e8f\u8f6c\u6362\u4e3aSeries\u6216DataFrame\u3002 pandas.read_json\u7684\u9ed8\u8ba4\u9009\u9879\u662f\u5047\u8bbeJSON\u6570\u7ec4\u4e2d\u7684\u6bcf\u4e2a\u5bf9\u8c61\u662f\u8868\u91cc\u7684\u4e00\u884c\u3002 \u4f8b\u5982\u8bfb\u53d6 data = pd.read_json('../examples/example_new.json') data = pd.read_json('../examples/example.json') print(data) # a b c # 0 1 2 3 # 1 4 5 6 # 2 7 8 9 print(data.to_json()) # {\"a\":{\"0\":1,\"1\":4,\"2\":7},\"b\":{\"0\":2,\"1\":5,\"2\":8},\"c\":{\"0\":3,\"1\":6,\"2\":9}} print(data.to_json(orient='records')) # [{\"a\":1,\"b\":2,\"c\":3},{\"a\":4,\"b\":5,\"c\":6},{\"a\":7,\"b\":8,\"c\":9}] XML\u548cHTML\uff1a\u7f51\u7edc\u6293\u53d6 \u00b6 pandas\u7684\u5185\u5efa\u51fd\u6570read_html\u53ef\u4ee5\u4f7f\u7528lxml\u548cBeautiful Soup\u7b49\u5e93\u5c06HTML\u4e2d\u7684\u8868\u81ea\u52a8\u89e3\u6790\u4e3aDataFrame\u5bf9\u8c61\u3002 tables = pd.read_html('../examples/fdic_failed_bank_list.html') print(len(tables)) # 1 failures = tables[0] # //*[@id=\"table\"] print(failures.head()) # \u8bfb\u53d6\u524d5\u884c\u8bb0\u5f55 # Bank Name ... Updated Date # 0 Allied Bank ... November 17, 2016 # 1 The Woodbury Banking Company ... November 17, 2016 # 2 First CornerStone Bank ... September 6, 2016 # 3 Trust Company Bank ... September 6, 2016 # 4 North Milwaukee State Bank ... June 16, 2016 # # [5 rows x 7 columns] close_timestamps = pd.to_datetime(failures['Closing Date']) # \u8ba1\u7b97\u6bcf\u5e74\u94f6\u884c\u5012\u95ed\u7684\u6570\u91cf print(close_timestamps.dt.year.value_counts()) # 2010 157 # 2009 140 # 2011 92 # 2012 51 # 2008 25 # ... # 2004 4 # 2001 4 # 2007 3 # 2003 3 # 2000 2 # Name: Closing Date, Length: 15, dtype: int64 \u4e8c\u8fdb\u5236\u683c\u5f0f \u00b6 \u4e0eWeb API\u4ea4\u4e92 \u00b6 \u4e0e\u6570\u636e\u5e93\u4ea4\u4e92 \u00b6","title":"\u6570\u636e\u8f7d\u5165\u3001\u5b58\u50a8\u53ca\u6587\u4ef6\u683c\u5f0f"},{"location":"python/DataAnalysis/ch03/#_1","text":"","title":"\u6570\u636e\u8f7d\u5165\u3001\u5b58\u50a8\u53ca\u6587\u4ef6\u683c\u5f0f"},{"location":"python/DataAnalysis/ch03/#_2","text":"import numpy as np import pandas as pd import sys import csv import json \u5c06\u8868\u683c\u578b\u6570\u636e\u8bfb\u53d6\u4e3aDataFrame\u5bf9\u8c61\u662fpandas\u7684\u91cd\u8981\u7279\u6027\u3002 \u4e0b\u9762\u662f\u90e8\u5206\u5b9e\u73b0\u6587\u4ef6\u8bfb\u53d6\u529f\u80fd\u7684\u51fd\u6570\uff0cread_csv\u548cread_table\u53ef\u80fd\u662f\u540e\u671f\u6211\u4eec\u4f7f\u7528\u6700\u591a\u7684\u51fd\u6570\u3002 \u8fd9\u4e9b\u51fd\u6570\u7684\u53ef\u9009\u53c2\u6570\u4e3b\u8981\u6709\u4ee5\u4e0b\u51e0\u79cd\u7c7b\u578b\uff1a \u7d22\u5f15\uff1a\u53ef\u4ee5\u5c06\u4e00\u5217\u6216\u591a\u4e2a\u5217\u4f5c\u4e3a\u8fd4\u56de\u7684DataFrame\uff0c\u4ece\u6587\u4ef6\u6216\u7528\u6237\u5904\u83b7\u5f97\u5217\u540d\uff0c\u6216\u8005\u6ca1\u6709\u5217\u540d\u3002 \u7c7b\u578b\u63a8\u65ad\u548c\u6570\u636e\u8f6c\u6362\uff1a\u5305\u62ec\u7528\u6237\u81ea\u5b9a\u4e49\u7684\u503c\u8f6c\u6362\u548c\u81ea\u5b9a\u4e49\u7684\u7f3a\u5931\u503c\u7b26\u53f7\u5217\u8868\u3002 \u65e5\u671f\u65f6\u95f4\u89e3\u6790\uff1a\u5305\u62ec\u7ec4\u5408\u529f\u80fd\uff0c\u4e5f\u5305\u62ec\u5c06\u5206\u6563\u5728\u591a\u4e2a\u5217\u4e0a\u7684\u65e5\u671f\u548c\u65f6\u95f4\u4fe1\u606f\u7ec4\u5408\u6210\u7ed3\u679c\u4e2d\u7684\u5355\u4e2a\u5217\u3002 \u8fed\u4ee3\uff1a\u652f\u6301\u5bf9\u5927\u578b\u6587\u4ef6\u7684\u5206\u5757\u8fed\u4ee3\u3002 \u672a\u6e05\u6d17\u6570\u636e\u95ee\u9898\uff1a\u8df3\u8fc7\u884c\u3001\u9875\u811a\u3001\u6ce8\u91ca\u4ee5\u53ca\u5176\u4ed6\u6b21\u8981\u6570\u636e\uff0c\u6bd4\u5982\u4f7f\u7528\u9017\u53f7\u5206\u9694\u5343\u4f4d\u7684\u6570\u5b57\u3002 file01 = '../examples/ex1.csv' # \u4f7f\u7528read_csv\u5c06\u6587\u4ef6\u8bfb\u5165\u4e00\u4e2aDataFrame df = pd.read_csv(file01) print(df) # 1 2 3 4 hello # 0 5 6 7 8 world # 1 9 10 11 12 foo df = pd.read_csv(file01, header=None) # \u4f7f\u7528pandas\u81ea\u52a8\u5206\u914d\u9ed8\u8ba4\u5217\u540d print(df) # 0 1 2 3 4 # 0 1 2 3 4 hello # 1 5 6 7 8 world # 2 9 10 11 12 foo df = pd.read_csv(file01, names=['aa', 'bb', 'cc', 'dd', 'message']) # \u81ea\u5df1\u6307\u5b9a\u5217\u540d print(df) # aa bb cc dd ee # 0 1 2 3 4 hello # 1 5 6 7 8 world # 2 9 10 11 12 foo # \u4f7f\u7528read_table\uff0c\u5e76\u6307\u5b9a\u5206\u9694\u7b26\uff0c\u5c06\u6587\u4ef6\u8bfb\u5165\u4e00\u4e2aDataFrame df = pd.read_table(file01, sep=',') print(df) # a b c d message # 0 1 2 3 4 hello # 1 5 6 7 8 world # 2 9 10 11 12 foo \u4ece\u591a\u4e2a\u5217\u4e2d\u5f62\u6210\u4e00\u4e2a\u5206\u5c42\u7d22\u5f15 parased = pd.read_csv('../examples/csv_mindex.csv', index_col=['key1', 'key2']) print(parased) # value1 value2 # key1 key2 # one a 1 2 # b 3 4 # c 5 6 # d 7 8 # two a 9 10 # b 11 12 # c 13 14 # d 15 16 \u4e0b\u4f8b\u4e2d\uff0c\u7531\u4e8e\u5217\u540d\u7684\u6570\u91cf\u6bd4\u6570\u636e\u7684\u5217\u6570\u5c11\u4e00\u4e2a\uff0c\u56e0\u6b64read_table\u63a8\u65ad\u7b2c\u4e00\u5217\u5e94\u5f53\u4f5c\u4e3aDataFrame\u7684\u7d22\u5f15\u3002 ex3.txt\u539f\u59cb\u6587\u4ef6\u5185\u5bb9 A B C aaa -0.264438 -1.026059 -0.619500 bbb 0.927272 0.302904 -0.032399 ccc -0.264273 -0.386314 -0.217601 ddd -0.871858 -0.348382 1.100491 result = pd.read_table('../examples/ex3.txt') # \u76f4\u63a5\u8bfb\u53d6 print(result) # A B C # aaa -0.264438 -1.026059 -0.619500 # bbb 0.927272 0.302904 -0.032399 NaN # ccc -0.264273 -0.386314 -0.217601 # ddd -0.871858 -0.348382 1.100491 result = pd.read_table('../examples/ex3.txt', sep='\\s+') # \u5411read_table\u6b63\u5219\u8868\u8fbe\u5f0f\u4e3a\\s+\u6765\u683c\u5f0f\u5316\u6587\u4ef6 print(result) # A B C # aaa -0.264438 -1.026059 -0.619500 # bbb 0.927272 0.302904 -0.032399 # ccc -0.264273 -0.386314 -0.217601 # ddd -0.871858 -0.348382 1.100491 \u4e0b\u4f8b\u4e2dex4.csv\u539f\u59cb\u6587\u4ef6\u5185\u5bb9 # hey! a,b,c,d,message # just wanted to make things more difficult for you # who reads CSV files with computers, anyway? 1,2,3,4,hello 5,6,7,8,world 9,10,11,12,foo result = pd.read_csv('../examples/ex4.csv', skiprows=[0, 2, 3]) # \u4f7f\u7528skiprows\u6765\u8df3\u8fc7\u7b2c\u4e00\u884c\u3001\u7b2c\u4e09\u884c\u548c\u7b2c\u56db\u884c print(result) # a b c d message # 0 1 2 3 4 hello # 1 5 6 7 8 world # 2 9 10 11 12 foo \u7f3a\u5931\u503c\u5904\u7406 \u9ed8\u8ba4\u60c5\u51b5\u4e0b\uff0cpandas\u4f7f\u7528\u4e00\u4e9b\u5e38\u89c1\u7684\u6807\u8bc6\uff0c\u4f8b\u5982 NA \u548c NULL \u4e0b\u4f8b\u4e2dex5.csv\u539f\u59cb\u6587\u4ef6\u5185\u5bb9 something,a,b,c,d,message one,1,2,3,4,NA two,5,6,,8,world three,9,10,11,12,foo result = pd.read_csv('../examples/ex5.csv') print(result) # something a b c d message # 0 one 1 2 3.0 4 NaN # 1 two 5 6 NaN 8 world # 2 three 9 10 11.0 12 foo print(pd.isnull(result)) # something a b c d message # 0 False False False False False True # 1 False False False True False False # 2 False False False False False False result = pd.read_csv('../examples/ex5.csv', na_values=['NULL']) print(result) # something a b c d message # 0 one 1 2 3.0 4 NaN # 1 two 5 6 NaN 8 world # 2 three 9 10 11.0 12 foo \u5b9a\u4e49\u66ff\u6362\u89c4\u5219 sentinels = { 'message': ['foo', 'NA'], 'something': ['two'] } result = pd.read_csv('../examples/ex5.csv', na_values=sentinels) \u628amessage\u5217\u6240\u6709\u503c\u4e3afoo\u6216NA\u7684\u66ff\u6362\u4e3aNull \u628asomething\u5217\u6240\u6709\u503c\u4e3atwo\u7684\u66ff\u6362\u4e3aNull print(result) # something a b c d message # 0 one 1 2 3.0 4 NaN # 1 NaN 5 6 NaN 8 world # 2 three 9 10 11.0 12 NaN","title":"\u6587\u672c\u683c\u5f0f\u6570\u636e\u7684\u8bfb\u5199"},{"location":"python/DataAnalysis/ch03/#_3","text":"pd.options.display.max_rows = 10 result = pd.read_csv('../examples/ex6.csv') # \u8bfb\u53d6\u5168\u90e8\u8bb0\u5f55 print(result) result = pd.read_csv('../examples/ex6.csv', nrows=5) # \u8bfb\u53d6\u524d5\u884c\u8bb0\u5f55 print(result) # [10000 rows x 5 columns] # one two three four key # 0 0.467976 -0.038649 -0.295344 -1.824726 L # 1 -0.358893 1.404453 0.704965 -0.200638 B # 2 -0.501840 0.659254 -0.421691 -0.057688 G # 3 0.204886 1.074134 1.388361 -0.982404 R # 4 0.354628 -0.133116 0.283763 -0.837063 Q result = pd.read_csv('../examples/ex6.csv', chunksize=1000) # \u5206\u5757\u8bfb\u5165\u6587\u4ef6\uff0c\u6bcf\u57571000\u884c print(result) # \u8fd4\u56de\u7684\u662f\u4e00\u4e2aTextParser\u5bf9\u8c61, \u5141\u8bb8\u4f60\u6839\u636echunksize\u904d\u5386\u6587\u4ef6\u3002 # \u53ef\u4ee5\u904d\u5386 ex6.csv \uff0c\u5e76\u5bf9 key \u5217\u805a\u5408\u83b7\u5f97\u8ba1\u6570\u503c tot = pd.Series([], dtype=float) # \u8fd9\u91cc\u9700\u8981\u663e\u5f0f\u6307\u5b9adtype\uff0c\u540e\u7eedPython\u4f1a\u5c06\u9ed8\u8ba4\u503c\u4ecefloat64\u53d8\u6210object\uff0c\u76ee\u524d\u9ed8\u8ba4\u662ffloat64 for piece in result: tot = tot.add(piece['key'].value_counts(), fill_value=0) tot = tot.sort_values(ascending=False) print(tot[:10]) # E 368.0 # X 364.0 # L 346.0 # O 343.0 # Q 340.0 # M 338.0 # J 337.0 # F 335.0 # K 334.0 # H 330.0 # dtype: float64","title":"\u5206\u5757\u8bfb\u5165\u6587\u672c\u6587\u4ef6"},{"location":"python/DataAnalysis/ch03/#_4","text":"data = pd.read_csv('../examples/ex5.csv') print(data) # something a b c d message # 0 one 1 2 3.0 4 NaN # 1 two 5 6 NaN 8 world # 2 three 9 10 11.0 12 foo \u4f7f\u7528DataFrame\u7684 to_csv \u65b9\u6cd5\uff0c\u5c06\u6570\u636e\u5bfc\u51fa\u4e3a\u9017\u53f7\u5206\u9694\u7684\u6587\u4ef6 data.to_csv('../examples/out.csv') # \u8f93\u51faout.csv\u7684\u5185\u5bb9 # ,something,a,b,c,d,message # 0,one,1,2,3.0,4, # 1,two,5,6,,8,world # 2,three,9,10,11.0,12,foo \u4f7f\u7528DataFrame\u7684 to_csv \u65b9\u6cd5\uff0c\u5c06\u6570\u636e\u5bfc\u51fa\u4e3a\u5176\u4ed6\u7684\u5206\u9694\u7b26\u7684\u6587\u4ef6 data.to_csv(sys.stdout, sep='|') # |something|a|b|c|d|message # 0|one|1|2|3.0|4| # 1|two|5|6||8|world # 2|three|9|10|11.0|12|foo data.to_csv(sys.stdout, sep=',') # ,something,a,b,c,d,message # 0,one,1,2,3.0,4, # 1,two,5,6,,8,world # 2,three,9,10,11.0,12,foo data.to_csv(sys.stdout, sep=',', na_rep='NULL') # \u8bbe\u5b9a\u7f3a\u5931\u503c\u5728\u8f93\u51fa\u65f6\u4ee5\u7a7a\u5b57\u7b26\u4e32\u51fa\u73b0 # ,something,a,b,c,d,message # 0,one,1,2,3.0,4,NULL # 1,two,5,6,NULL,8,world # 2,three,9,10,11.0,12,foo data.to_csv(sys.stdout, sep=',', na_rep='NULL', index=False, header=False) # \u4e0d\u8f93\u51fa\u884c\u548c\u5217\u7684\u6807\u7b7e\uff08index\uff0cheader\uff09 # one,1,2,3.0,4,NULL # two,5,6,NULL,8,world # three,9,10,11.0,12,foo data.to_csv(sys.stdout, sep=',', na_rep='NULL', index=False, header=False, columns=['a', 'b', 'c']) # \u6309\u7167\u81ea\u5b9a\u7684\u987a\u5e8f\u8f93\u51fa\u5b50\u96c6 # 1,2,3.0 # 5,6,NULL # 9,10,11.0 Series\u4e5f\u6709 to_csv \u65b9\u6cd5 dates = pd.date_range('1/1/2000', periods=7) ts = pd.Series(np.arange(7), index=dates) ts.to_csv('../examples/tseries.csv', header=False) # \u8f93\u51fatseries.csv\u6587\u4ef6\u5185\u5bb9 # 2000-01-01,0 # 2000-01-02,1 # 2000-01-03,2 # 2000-01-04,3 # 2000-01-05,4 # 2000-01-06,5 # 2000-01-07,6","title":"\u5c06\u6570\u636e\u5199\u5165\u6587\u672c\u683c\u5f0f"},{"location":"python/DataAnalysis/ch03/#_5","text":"\u7edd\u5927\u591a\u6570\u7684\u8868\u578b\u6570\u636e\u90fd\u53ef\u4ee5\u4f7f\u7528\u51fd\u6570 pandas.read_table \u4ece\u786c\u76d8\u4e2d\u8bfb\u53d6\u3002 \u7136\u800c\uff0c\u5728\u67d0\u4e9b\u60c5\u51b5\u4e0b\uff0c\u63a5\u6536\u4e00\u4e2a\u5e26\u6709\u4e00\u884c\u6216\u591a\u884c\u9519\u8bef\u7684\u6587\u4ef6\u5e76\u4e0d\u5c11\u89c1\uff0c read_table \u4e5f\u65e0\u6cd5\u89e3\u51b3\u8fd9\u79cd\u60c5\u51b5\u3002 ex7.csv \u6587\u4ef6\u5185\u5bb9 \"a\",\"b\",\"c\" \"1\",\"2\",\"3\" \"1\",\"2\",\"3\" f = open('../examples/ex7.csv') # \u4f7f\u7528Python\u7684\u5185\u5efacsv\u6a21\u5757 reader = csv.reader(f) # \u5c06\u4efb\u4e00\u6253\u5f00\u7684\u6587\u4ef6\u6216\u6587\u4ef6\u578b\u5bf9\u8c61\u4f20\u7ed9csv.reader for line in reader: # # \u904d\u5386reader\uff0c\u4ea7\u751f\u5143\u7ec4\uff0c\u5143\u7ec4\u7684\u503c\u4e3a\u5220\u9664\u4e86\u5f15\u53f7\u7684\u5b57\u7b26 print(line) f.close() # ['a', 'b', 'c'] # ['1', '2', '3'] # ['1', '2', '3'] with open('../examples/ex7.csv') as f: lines = list(csv.reader(f)) # \u9996\u5148\uff0c\u5c06\u6587\u4ef6\u8bfb\u53d6\u4e3a\u884c\u7684\u5217\u8868 header, values = lines[0], lines[1:] # \u5176\u6b21\uff0c\u5c06\u6570\u636e\u62c6\u5206\u4e3a\u5217\u540d\u884c\u548c\u6570\u636e\u884c data_dict = { h: v for h, v in zip(header, zip(*values)) # \u518d\u7136\u540e\uff0c\u4f7f\u7528\u5b57\u5178\u63a8\u5bfc\u5f0f\u548c\u8868\u8fbe\u5f0fzip(*values)\u751f\u6210\u4e00\u4e2a\u5305\u542b\u6570\u636e\u5217\u7684\u5b57\u5178\uff0c\u5b57\u5178\u4e2d\u884c\u8f6c\u7f6e\u6210\u5217 } print(data_dict) # \u8f93\u51fa\u7ed3\u679c # {'a': ('1', '1'), 'b': ('2', '2'), 'c': ('3', '3')} \u5982\u679c\u9700\u6839\u636e\u4e0d\u540c\u7684\u5206\u9694\u7b26\u3001\u5b57\u7b26\u4e32\u5f15\u7528\u7ea6\u5b9a\u6216\u884c\u7ec8\u6b62\u7b26\u5b9a\u4e49\u4e00\u79cd\u65b0\u7684\u683c\u5f0f\u65f6\uff0c\u53ef\u4ee5: \u65b9\u6cd51\uff1a\u4f7f\u7528csv.Dialect\u5b9a\u4e49\u4e00\u4e2a\u7b80\u5355\u7684\u5b50\u7c7b class my_dialect(csv.Dialect): lineterminator = '\\n' delimiter = ';' # \u8fd9\u91cc\u53ea\u80fd\u662f\u4e00\u4e2a\u5b57\u7b26 quotechar = '\"' quoting = csv.QUOTE_MINIMAL f = open('../examples/ex7.csv') reader = csv.reader(f, dialect=my_dialect) for line in reader: # \u904d\u5386reader\uff0c\u4ea7\u751f\u5143\u7ec4\uff0c\u5143\u7ec4\u7684\u503c\u4e3a\u5220\u9664\u4e86\u5f15\u53f7\u7684\u5b57\u7b26 print(line) f.close() # ['a,\"b\",\"c\"'] # ['1,\"2\",\"3\"'] # ['1,\"2\",\"3\"'] \u65b9\u6cd52\uff1a\u76f4\u63a5\u5c06CSV\u65b9\u8a00\u53c2\u6570(dialect)\u4f20\u5165csv.reader\u7684\u5173\u952e\u5b57\u53c2\u6570\u3002 \u6bd4\u8f83\u8be6\u7ec6\u7684 \u4ecb\u7ecd\u65b9\u8a00\u548c\u5206\u9694\u7b26 f = open('../examples/ex7.csv') reader = csv.reader(f, delimiter='|') for line in reader: # \u904d\u5386reader\uff0c\u4ea7\u751f\u5143\u7ec4\uff0c\u5143\u7ec4\u7684\u503c\u4e3a\u5220\u9664\u4e86\u5f15\u53f7\u7684\u5b57\u7b26 print(line) f.close() # ['a,\"b\",\"c\"'] # ['1,\"2\",\"3\"'] # ['1,\"2\",\"3\"'] \u5bf9\u4e8e\u5177\u6709\u66f4\u590d\u6742\u6216\u56fa\u5b9a\u7684\u591a\u5b57\u7b26\u5206\u9694\u7b26\u7684\u6587\u4ef6\uff0c\u5c06\u65e0\u6cd5\u4f7f\u7528csv\u6a21\u5757\u3002 \u5728\u6b64\u7c7b\u60c5\u51b5\u4e0b\uff0c\u5c06\u4f7f\u7528\u5b57\u7b26\u4e32\u7684split\u65b9\u6cd5\u6216\u6b63\u5219\u8868\u8fbe\u5f0f\u65b9\u6cd5re.split\u8fdb\u884c\u884c\u62c6\u5206\u548c\u5176\u4ed6\u6e05\u7406\u5de5\u4f5c\u3002 \u9700\u8981\u624b\u52a8\u5199\u5165\u88ab\u5206\u9694\u7684\u6587\u4ef6\u65f6\uff0c\u4f60\u53ef\u4ee5\u4f7f\u7528csv.writer\u3002 \u8fd9\u4e2a\u51fd\u6570\u63a5\u6536\u4e00\u4e2a\u5df2\u7ecf\u6253\u5f00\u7684\u53ef\u5199\u5165\u6587\u4ef6\u5bf9\u8c61\u4ee5\u53ca\u548ccsv.reader\u76f8\u540c\u7684CSV\u65b9\u8a00\u3001\u683c\u5f0f\u9009\u9879. with open('../examples/mydata.csv', 'w') as f: writer = csv.writer(f, dialect=my_dialect) writer.writerow(('1', '2', '3')) writer.writerow(('4', '5', '6')) writer.writerow(('7', '8', '9')) writer.writerow(('10', '11', '12')) # mydata.csv \u6587\u4ef6\u5185\u5bb9 # 1;2;3 # 4;5;6 # 7;8;9 # 10;11;12","title":"\u4f7f\u7528\u5206\u9694\u683c\u5f0f"},{"location":"python/DataAnalysis/ch03/#json","text":"obj = \"\"\" { \"name\": \"Wes\", \"places_lived\": [\"United States\", \"Spain\", \"Germany\"], \"pet\": null, \"siblings\": [ { \"name\": \"Scott\", \"age\": 30, \"pets\": [\"Zeus\", \"Zuko\"] }, { \"name\": \"Katie\", \"age\": 38, \"pets\": [\"Sixes\", \"Stache\", \"Cisco\"] } ] } \"\"\" \u5c06JSON\u5b57\u7b26\u4e32\u8f6c\u6362\u4e3aPython\u5f62\u5f0f\u65f6\uff0c\u4f7f\u7528json.loads\u65b9\u6cd5 result = json.loads(obj) print(result) # {'name': 'Wes', 'places_lived': ['United States', 'Spain', 'Germany'], 'pet': None, 'siblings': [{'name': 'Scott', 'age': 30, 'pets': ['Zeus', 'Zuko']}, {'name': 'Katie', 'age': 38, 'pets': ['Sixes', 'Stache', 'Cisco']}]} \u53e6\u4e00\u65b9\u9762\uff0cjson.dumps\u53ef\u4ee5\u5c06Python\u5bf9\u8c61\u8f6c\u6362\u56deJSON asjson = json.dumps(result) print(asjson) # {\"name\": \"Wes\", \"places_lived\": [\"United States\", \"Spain\", \"Germany\"], \"pet\": null, \"siblings\": [{\"name\": \"Scott\", \"age\": 30, \"pets\": [\"Zeus\", \"Zuko\"]}, {\"name\": \"Katie\", \"age\": 38, \"pets\": [\"Sixes\", \"Stache\", \"Cisco\"]}]} \u5c06JSON\u5bf9\u8c61\u6216\u5bf9\u8c61\u5217\u8868\u8f6c\u6362\u4e3aDataFrame\u6216\u5176\u4ed6\u6570\u636e\u7ed3\u6784\u3002 \u6bd4\u8f83\u65b9\u4fbf\u7684\u65b9\u5f0f\u662f\u5c06\u5b57\u5178\u6784\u6210\u7684\u5217\u8868\uff08\u4e4b\u524d\u662fJSON\u5bf9\u8c61\uff09\u4f20\u5165DataFrame\u6784\u9020\u51fd\u6570\uff0c\u5e76\u9009\u51fa\u6570\u636e\u5b57\u6bb5\u7684\u5b50\u96c6\u3002 siblings = pd.DataFrame(result['siblings'], columns=['name', 'age']) print(siblings) # name age # 0 Scott 30 # 1 Katie 38 pandas.read_json\u53ef\u4ee5\u81ea\u52a8\u5c06JSON\u6570\u636e\u96c6\u6309\u7167\u6307\u5b9a\u6b21\u5e8f\u8f6c\u6362\u4e3aSeries\u6216DataFrame\u3002 pandas.read_json\u7684\u9ed8\u8ba4\u9009\u9879\u662f\u5047\u8bbeJSON\u6570\u7ec4\u4e2d\u7684\u6bcf\u4e2a\u5bf9\u8c61\u662f\u8868\u91cc\u7684\u4e00\u884c\u3002 \u4f8b\u5982\u8bfb\u53d6 data = pd.read_json('../examples/example_new.json') data = pd.read_json('../examples/example.json') print(data) # a b c # 0 1 2 3 # 1 4 5 6 # 2 7 8 9 print(data.to_json()) # {\"a\":{\"0\":1,\"1\":4,\"2\":7},\"b\":{\"0\":2,\"1\":5,\"2\":8},\"c\":{\"0\":3,\"1\":6,\"2\":9}} print(data.to_json(orient='records')) # [{\"a\":1,\"b\":2,\"c\":3},{\"a\":4,\"b\":5,\"c\":6},{\"a\":7,\"b\":8,\"c\":9}]","title":"JSON\u6570\u636e"},{"location":"python/DataAnalysis/ch03/#xmlhtml","text":"pandas\u7684\u5185\u5efa\u51fd\u6570read_html\u53ef\u4ee5\u4f7f\u7528lxml\u548cBeautiful Soup\u7b49\u5e93\u5c06HTML\u4e2d\u7684\u8868\u81ea\u52a8\u89e3\u6790\u4e3aDataFrame\u5bf9\u8c61\u3002 tables = pd.read_html('../examples/fdic_failed_bank_list.html') print(len(tables)) # 1 failures = tables[0] # //*[@id=\"table\"] print(failures.head()) # \u8bfb\u53d6\u524d5\u884c\u8bb0\u5f55 # Bank Name ... Updated Date # 0 Allied Bank ... November 17, 2016 # 1 The Woodbury Banking Company ... November 17, 2016 # 2 First CornerStone Bank ... September 6, 2016 # 3 Trust Company Bank ... September 6, 2016 # 4 North Milwaukee State Bank ... June 16, 2016 # # [5 rows x 7 columns] close_timestamps = pd.to_datetime(failures['Closing Date']) # \u8ba1\u7b97\u6bcf\u5e74\u94f6\u884c\u5012\u95ed\u7684\u6570\u91cf print(close_timestamps.dt.year.value_counts()) # 2010 157 # 2009 140 # 2011 92 # 2012 51 # 2008 25 # ... # 2004 4 # 2001 4 # 2007 3 # 2003 3 # 2000 2 # Name: Closing Date, Length: 15, dtype: int64","title":"XML\u548cHTML\uff1a\u7f51\u7edc\u6293\u53d6"},{"location":"python/DataAnalysis/ch03/#_6","text":"","title":"\u4e8c\u8fdb\u5236\u683c\u5f0f"},{"location":"python/DataAnalysis/ch03/#web-api","text":"","title":"\u4e0eWeb API\u4ea4\u4e92"},{"location":"python/DataAnalysis/ch03/#_7","text":"","title":"\u4e0e\u6570\u636e\u5e93\u4ea4\u4e92"},{"location":"python/DataAnalysis/ch04/","text":"\u6570\u636e\u6e05\u6d17\u4e0e\u51c6\u5907 \u00b6 \u5904\u7406\u7f3a\u5931\u503c \u00b6 import pandas as pd import numpy as np from numpy import nan as NA \u5bf9\u4e8e\u6570\u503c\u578b\u6570\u636e\uff0cpandas\u4f7f\u7528\u6d6e\u70b9\u503c NaN \uff08Not a Number\u6765\u8868\u793a\u7f3a\u5931\u503c\uff09\u3002 \u5728pandas\u4e2d\uff0c\u91c7\u7528\u4e86R\u8bed\u8a00\u4e2d\u7684\u7f16\u7a0b\u60ef\u4f8b\uff0c\u5c06\u7f3a\u5931\u503c\u6210\u4e3a NA \uff0c\u610f\u601d\u662fnotavailable\uff08\u4e0d\u53ef\u7528\uff09\u3002 Python\u5185\u5efa\u7684 None \u503c\u5728\u5bf9\u8c61\u6570\u7ec4\u4e2d\u4e5f\u88ab\u5f53\u4f5c NA \u5904\u7406\u3002 NA\u5904\u7406\u65b9\u6cd5\uff1a dropna :\u6839\u636e\u6bcf\u4e2a\u6807\u7b7e\u7684\u503c\u662f\u5426\u662f\u786e\u5b9e\u6570\u636e\u6765\u7b5b\u9009\u8f74\u6807\u7b7e\uff0c\u5e76\u6839\u636e\u5141\u8bb8\u4e22\u5931\u7684\u6570\u636e\u91cf\u6765\u786e\u5b9a\u9608\u503c fillna :\u7528\u67d0\u4e9b\u503c\u586b\u5145\u786e\u5b9e\u7684\u6570\u636e\u6216\u4f7f\u7528\u63d2\u503c\u65b9\u6cd5\uff0c\u5982 ffill \u6216 bfill isnull :\u8fd4\u56de\u8868\u660e\u54ea\u4e9b\u503c\u662f\u7f3a\u5931\u503c\u7684\u5e03\u5c14\u503c notnull :\u662f isnull \u7684\u53cd\u51fd\u6570 string_data = pd.Series(['aardvark', 'artichoke', np.nan, 'avocado']) print(string_data) # 0 aardvark # 1 artichoke # 2 NaN # 3 avocado # dtype: object print(string_data.isnull()) # 0 False # 1 False # 2 True # 3 False # dtype: bool string_data[0] = None print(string_data.isnull()) # 0 True # 1 False # 2 True # 3 False # dtype: bool \u8fc7\u6ee4\u7f3a\u5931\u503c \u00b6 \u5904\u7406Series \u00b6 \u5728Series\u4e0a\u4f7f\u7528 dropna \uff0c\u5b83\u4f1a\u8fd4\u56deSeries\u4e2d\u6240\u6709\u7684\u975e\u7a7a\u6570\u636e\u53ca\u5176\u7d22\u5f15\u503c\u3002 data = pd.Series([1, NA, 3.5, NA, 7]) print(data.dropna()) # 0 1.0 # 2 3.5 # 4 7.0 # dtype: float64 print(data[data.notnull()]) # \u4e0e\u4e0a\u9762\u7b49\u4ef7 # 0 1.0 # 2 3.5 # 4 7.0 # dtype: float64 \u5904\u7406DataFrame \u00b6 data = pd.DataFrame( [[1., 6.5, 3.], [1., NA, NA], [NA, NA, NA], [NA, 6.5, 3.]] ) print(data) # 0 1 2 # 0 1.0 6.5 3.0 # 1 1.0 NaN NaN # 2 NaN NaN NaN # 3 NaN 6.5 3.0 cleaned = data.dropna() # dropna\u9ed8\u8ba4\u60c5\u51b5\u4e0b\u4f1a\u5220\u9664\u5305\u542b\u7f3a\u5931\u503c\u7684\u884c print(cleaned) # 0 1 2 # 0 1.0 6.5 3.0 cleaned = data.dropna(how='all') # \u4f20\u5165how='all\u2019\u65f6\uff0c\u5c06\u5220\u9664\u6240\u6709\u503c\u5747\u4e3aNA\u7684\u884c print(cleaned) # 0 1 2 # 0 1.0 6.5 3.0 # 1 1.0 NaN NaN # 3 NaN 6.5 3.0 data[4] = NA print(data) # 0 1 2 4 # 0 1.0 6.5 3.0 NaN # 1 1.0 NaN NaN NaN # 2 NaN NaN NaN NaN # 3 NaN 6.5 3.0 NaN cleaned = data.dropna(axis=1, how='all') # \u5220\u9664\u5168NA\u7684\u5217 print(cleaned) # 0 1 2 # 0 1.0 6.5 3.0 # 1 1.0 NaN NaN # 2 NaN NaN NaN # 3 NaN 6.5 3.0 df = pd.DataFrame(np.random.randn(7, 3)) print(df) # 0 1 2 # 0 -1.069771 -0.777921 0.181956 # 1 -0.399504 -0.641737 -0.946327 # 2 -1.013920 -0.247588 -0.760146 # 3 1.076946 -1.263203 0.494077 # 4 0.460985 -1.241870 0.283006 # 5 1.168149 1.033752 0.900095 # 6 -1.208514 -1.049546 -0.783680 df.iloc[:4, 1] = NA # \u6807\u7b7e1\uff0c\u524d4\u4e2a\u5143\u7d20 df.iloc[:2, 2] = NA # \u6807\u7b7e2\uff0c\u524d2\u4e2a\u5143\u7d20 print(df) # 0 1 2 # 0 -1.069771 NaN NaN # 1 -0.399504 NaN NaN # 2 -1.013920 NaN -0.760146 # 3 1.076946 NaN 0.494077 # 4 0.460985 -1.241870 0.283006 # 5 1.168149 1.033752 0.900095 # 6 -1.208514 -1.049546 -0.783680 cleaned = df.dropna() print(cleaned) # 0 1 2 # 4 0.033663 0.291886 0.736448 # 5 -0.433380 0.397104 1.252005 # 6 -1.999018 0.303866 1.430109 cleaned = df.dropna(thresh=2) # \u4fdd\u75592\u884c\u542bNA\u7684\u89c2\u5bdf\u503c print(cleaned) # 0 1 2 # 2 -1.413976 NaN 0.222274 # 3 -0.644266 NaN 0.324180 # 4 -0.122160 -2.244880 -0.406562 # 5 -0.140326 0.101133 -0.764048 # 6 -1.809141 0.139091 -0.819175 \u8865\u5168\u7f3a\u5931\u503c \u00b6 fillna \u51fd\u6570\u53c2\u6570\uff1a value\uff1a\u6807\u91cf\u503c\u6216\u5b57\u5178\u578b\u5bf9\u8c61\u7528\u4e8e\u586b\u5145\u7f3a\u5931\u503c method\uff1a\u63d2\u503c\u65b9\u6cd5\uff0c\u5982\u679c\u6ca1\u6709\u5176\u4ed6\u53c2\u6570\uff0c\u9ed8\u8ba4\u662f'ffill' axis\uff1a\u9700\u8981\u586b\u5145\u7684\u8f74\uff0c\u9ed8\u8ba4axis=0 inplace\uff1a\u4fee\u6539\u88ab\u8c03\u7528\u5bf9\u8c61\uff0c\u800c\u4e0d\u662f\u751f\u6210\u4e00\u4e2a\u5907\u4efd limit\uff1a\u7528\u4e8e\u524d\u5411\u6216\u540e\u5411\u586b\u5145\u65f6\u6700\u5927\u7684\u586b\u5145\u8303\u56f4 df = pd.DataFrame(np.random.randn(7, 3)) df.iloc[:4, 1] = NA # \u6807\u7b7e1\uff0c\u524d4\u4e2a\u5143\u7d20 df.iloc[:2, 2] = NA # \u6807\u7b7e2\uff0c\u524d2\u4e2a\u5143\u7d20 print(df) # 0 1 2 # 0 -0.181196 NaN NaN # 1 -1.657668 NaN NaN # 2 -0.053454 NaN 0.391461 # 3 -0.539307 NaN -0.668400 # 4 -0.433439 0.839713 -0.295273 # 5 0.749930 1.661641 -0.495165 # 6 0.591810 1.017372 0.932367 result = df.fillna(0) # \u8c03\u7528fillna\u65f6\uff0c\u53ef\u4ee5\u4f7f\u7528\u4e00\u4e2a\u5e38\u6570\u6765\u66ff\u4ee3\u7f3a\u5931\u503c print(result) # 0 1 2 # 0 -0.430926 0.000000 0.000000 # 1 0.448061 0.000000 0.000000 # 2 -0.059910 0.000000 -1.532646 # 3 -0.315793 0.000000 -0.196546 # 4 -0.546106 0.135108 -0.332309 # 5 1.083075 0.346070 -0.773104 # 6 -0.186511 1.055337 -1.168303 result = df.fillna({1: 0.5, 2: 0}) # \u8c03\u7528fillna\u65f6\u4f7f\u7528\u5b57\u5178\uff0c\u53ef\u4ee5\u4e3a\u4e0d\u540c\u5217\u8bbe\u5b9a\u4e0d\u540c\u7684\u586b\u5145\u503c print(result) # 0 1 2 # 0 -0.794344 0.500000 0.000000 # 1 -0.960917 0.500000 0.000000 # 2 1.494351 0.500000 0.100878 # 3 -0.554765 0.500000 1.118801 # 4 -0.866117 0.523615 1.217478 # 5 -0.706966 -0.681776 0.797690 # 6 -1.456366 1.205518 -0.402432 fillna \u8fd4\u56de\u7684\u662f\u4e00\u4e2a\u65b0\u7684\u5bf9\u8c61\uff0c\u4f46\u4e5f\u53ef\u4ee5\u4fee\u6539\u5df2\u7ecf\u5b58\u5728\u7684\u5bf9\u8c61 _ = df.fillna(0, inplace=True) # inplace=True\u6307\u5b9a\u5728\u5df2\u6709\u5bf9\u8c61\u4e0a\u76f4\u63a5\u4fee\u6539 print(df) # 0 1 2 # 0 -1.176124 0.000000 0.000000 # 1 0.120458 0.000000 0.000000 # 2 -1.206408 0.000000 0.551693 # 3 0.224563 0.000000 1.145156 # 4 -0.557836 0.081135 -0.075282 # 5 2.378837 -0.876145 1.430386 # 6 -0.152662 1.278364 0.479686 df = pd.DataFrame(np.random.randn(6, 3)) df.iloc[2:, 1] = NA # \u6807\u7b7e1\uff0c\u524d4\u4e2a\u5143\u7d20 df.iloc[4:, 2] = NA # \u6807\u7b7e2\uff0c\u524d2\u4e2a\u5143\u7d20 print(df) # 0 1 2 # 0 1.154788 0.033949 -0.122807 # 1 0.258684 -0.580244 1.636514 # 2 1.503756 NaN -1.224203 # 3 0.824049 NaN -0.364345 # 4 -1.247609 NaN NaN # 5 -1.019980 NaN NaN result = df.fillna(method='ffill') # \u5411\u540e\u586b\u5145 print(result) # 0 1 2 # 0 2.082449 0.398874 0.359772 # 1 0.233129 0.385347 1.953533 # 2 0.396555 0.385347 0.592784 # 3 -0.957249 0.385347 0.169815 # 4 0.854452 0.385347 0.169815 # 5 -0.105982 0.385347 0.169815 result = df.fillna(method='ffill', limit=3) # \u6bcf\u5217\u6700\u591a\u586b3\u4e2a print(result) result = df.fillna(df[0].max()) # \u75280\u5217\u7684\u6700\u5927\u503c\u586b\u5145\u6240\u6709\u7684NA print(result) # 0 1 2 # 0 -0.377697 -0.852891 -0.705489 # 1 -0.611759 -0.013237 -0.295764 # 2 -0.389974 1.057881 1.041957 # 3 -0.016845 1.057881 -1.149954 # 4 1.057881 1.057881 1.057881 # 5 -0.463471 1.057881 1.057881 \u6570\u636e\u8f6c\u6362 \u00b6 import pandas as pd import numpy as np from numpy import nan as NA \u5220\u9664\u91cd\u590d\u503c \u00b6 data = pd.DataFrame( { 'k1': ['one', 'two'] * 3 + ['two'], 'k2': [1, 1, 2, 3, 4, 4, 4] } ) print(data) # \u91cd\u590d\u51fa\u73b02\u6b21\u7684\u8bb0\u5f55\uff1atwo 4 # k1 k2 # 0 one 1 # 1 two 1 # 2 one 2 # 3 two 3 # 4 one 4 # 5 two 4 # 6 two 4 DataFrame\u7684 duplicated \u65b9\u6cd5\u8fd4\u56de\u7684\u662f\u4e00\u4e2a\u5e03\u5c14\u503cSeries\uff0c\u8fd9\u4e2aSeries\u53cd\u6620\u7684\u662f\u6bcf\u4e00\u884c\u662f\u5426\u5b58\u5728\u91cd\u590d\uff08\u4e0e\u4e4b\u524d\u51fa\u73b0\u8fc7\u7684\u884c\u76f8\u540c\uff09\u60c5\u51b5\uff0c\u9ed8\u8ba4\u662f\u5bf9\u5217\u8fdb\u884c\u64cd\u4f5c\u3002 print(data.duplicated()) # 0 False # 1 False # 2 False # 3 False # 4 False # 5 False # 6 True # dtype: bool drop_duplicates \u8fd4\u56de\u7684\u662fDataFrame\uff0c\u5185\u5bb9\u662f duplicated \u8fd4\u56de\u6570\u7ec4\u4e2d\u4e3a False \u7684\u90e8\u5206\u3002\u9ed8\u8ba4\u662f\u5bf9\u5217\u8fdb\u884c\u64cd\u4f5c\u3002 print(data.drop_duplicates()) # k1 k2 # 0 one 1 # 1 two 1 # 2 one 2 # 3 two 3 # 4 one 4 # 5 two 4 \u53ef\u4ee5\u6307\u5b9a\u6570\u636e\u7684\u4efb\u4f55\u5b50\u96c6\u6765\u68c0\u6d4b\u662f\u5426\u6709\u91cd\u590d\u3002\u5047\u8bbe\u6211\u4eec\u6709\u4e00\u4e2a\u989d\u5916\u7684\u5217\uff0c\u5e76\u60f3\u57fa\u4e8e\u2019k1\u2019\u5217\u53bb\u9664\u91cd\u590d\u503c\u3002 data['v1'] = range(7) print(data) # k1 k2 v1 # 0 one 1 0 # 1 two 1 1 # 2 one 2 2 # 3 two 3 3 # 4 one 4 4 # 5 two 4 5 # 6 two 4 6 print(data.drop_duplicates(['k1'])) # \u4fdd\u7559\u7b2c\u4e00\u4e2a\u89c2\u6d4b\u5230\u7684one\u548ctwo\uff0c\u5176\u4f59\u4e22\u5f03 # k1 k2 v1 # 0 one 1 0 # 1 two 1 1 duplicated \u548c drop_duplicates \u9ed8\u8ba4\u90fd\u662f\u4fdd\u7559\u7b2c\u4e00\u4e2a\u89c2\u6d4b\u5230\u7684\u503c\u3002\u4f20\u5165\u53c2\u6570keep='last\u2019\u5c06\u4f1a\u8fd4\u56de\u6700\u540e\u4e00\u4e2a\u3002 print(data.drop_duplicates(['k1'], keep='last')) # \u4fdd\u7559\u6700\u540e\u4e00\u4e2a\u89c2\u6d4b\u5230\u7684one\u548ctwo # k1 k2 v1 # 4 one 4 4 # 6 two 4 6 \u4f7f\u7528\u51fd\u6570\u6216\u6620\u5c04\u8fdb\u884c\u6570\u636e\u8f6c\u6362 \u00b6 \u4f7f\u7528 map \u662f\u4e00\u79cd\u53ef\u4ee5\u4fbf\u6377\u6267\u884c\u6309\u5143\u7d20\u8f6c\u6362\u53ca\u5176\u4ed6\u6e05\u6d17\u76f8\u5173\u64cd\u4f5c\u7684\u65b9\u6cd5\u3002 data = pd.DataFrame( { 'food': ['bacon', 'pulled pork', 'bacon', 'Pastrami', 'corned beef', 'Bacon', 'pastrami', 'honey ham', 'nova lox'], 'ounces': [4, 3, 12, 6, 7.5, 8, 3, 5, 6] } ) print(data) # food ounces # 0 bacon 4.0 # 1 pulled pork 3.0 # 2 bacon 12.0 # 3 Pastrami 6.0 # 4 corned beef 7.5 # 5 Bacon 8.0 # 6 pastrami 3.0 # 7 honey ham 5.0 # 8 nova lox 6.0 \u6dfb\u52a0\u4e00\u5217\u7528\u4e8e\u8868\u660e\u6bcf\u79cd\u98df\u7269\u7684\u52a8\u7269\u8089\u7c7b\u578b\u3002 \u5148\u521b\u5efa\u4e00\u4e2a\u98df\u7269\u548c\u8089\u7c7b\u7684\u6620\u5c04\u3002 meat_to_animal = { 'bacon': 'pig', 'pulled pork': 'pig', 'pastrami': 'cow', 'corned beef': 'cow', 'honey ham': 'pig', 'nova lox': 'salmon' } lowercased = data['food'].str.lower() # \u4f7f\u7528Series\u7684str.lower\u65b9\u6cd5\u5c06food\u7684\u6bcf\u4e2a\u503c\u90fd\u8f6c\u6362\u4e3a\u5c0f\u5199 print(lowercased) # 0 bacon # 1 pulled pork # 2 bacon # 3 pastrami # 4 corned beef # 5 bacon # 6 pastrami # 7 honey ham # 8 nova lox # Name: food, dtype: object data['animal'] = lowercased.map(meat_to_animal) print(data) # food ounces animal # 0 bacon 4.0 pig # 1 pulled pork 3.0 pig # 2 bacon 12.0 pig # 3 Pastrami 6.0 cow # 4 corned beef 7.5 cow # 5 Bacon 8.0 pig # 6 pastrami 3.0 cow # 7 honey ham 5.0 pig # 8 nova lox 6.0 salmon \u4e5f\u53ef\u4ee5\u4f20\u5165\u4e00\u4e2a\u51fd\u6570\uff0c\u5b8c\u6210\u4e0a\u9762\u6240\u6709\u529f\u80fd\u3002 data = pd.DataFrame( { 'food': ['bacon', 'pulled pork', 'bacon', 'Pastrami', 'corned beef', 'Bacon', 'pastrami', 'honey ham', 'nova lox'], 'ounces': [4, 3, 12, 6, 7.5, 8, 3, 5, 6] } ) result = data['food'].map(lambda x: meat_to_animal[x.lower()]) print(result) # 0 pig # 1 pig # 2 pig # 3 cow # 4 cow # 5 pig # 6 cow # 7 pig # 8 salmon # Name: food, dtype: object \u66ff\u4ee3\u503c \u00b6 \u4f7f\u7528 fillna \u586b\u5145\u7f3a\u5931\u503c\u662f\u901a\u7528\u503c\u66ff\u6362\u7684\u7279\u6b8a\u6848\u4f8b\u3002 map \u53ef\u4ee5\u7528\u6765\u4fee\u6539\u4e00\u4e2a\u5bf9\u8c61\u4e2d\u7684\u5b50\u96c6\u7684\u503c\uff0c\u4f46\u662f replace \u63d0\u4f9b\u4e86\u66f4\u4e3a\u7b80\u5355\u7075\u6d3b\u7684\u5b9e\u73b0\u3002 data.replace \u65b9\u6cd5\u4e0e data.str.replace \u65b9\u6cd5\u662f\u4e0d\u540c\u7684\uff0c data.str.replace \u662f\u5bf9\u5b57\u7b26\u4e32\u8fdb\u884c\u6309\u5143\u7d20\u66ff\u4ee3\u7684\u3002 \u4e0b\u9762\u7684Series\uff0c -999 \u53ef\u80fd\u662f\u7f3a\u5931\u503c\u7684\u6807\u8bc6\u3002\u5982\u679c\u8981\u4f7f\u7528 NA \u6765\u66ff\u4ee3\u8fd9\u4e9b\u503c\uff0c\u53ef\u4ee5\u4f7f\u7528 replace \u65b9\u6cd5\u751f\u6210\u65b0\u7684Series\uff08\u9664\u975e\u4f20\u5165\u4e86 inplace=True \uff09 data = pd.Series([1., -999., 2., -999., -1000., 3.]) print(data) # 0 1.0 # 1 -999.0 # 2 2.0 # 3 -999.0 # 4 -1000.0 # 5 3.0 # dtype: float64 result = data.replace(-999, np.nan) print(result) # 0 1.0 # 1 NaN # 2 2.0 # 3 NaN # 4 -1000.0 # 5 3.0 # dtype: float64 \u8981\u5c06\u4e0d\u540c\u7684\u503c\u66ff\u6362\u4e3a\u4e0d\u540c\u7684\u503c\uff0c\u53ef\u4ee5\u4f20\u5165\u66ff\u4ee3\u503c\u7684\u5217\u8868 result = data.replace([-999, -1000], [np.nan, 0]) print(result) # 0 1.0 # 1 NaN # 2 2.0 # 3 NaN # 4 0.0 # 5 3.0 # dtype: float64 \u4e5f\u53ef\u4ee5\u4f20\u5165\u66ff\u4ee3\u503c\u7684\u5b57\u5178 result = data.replace({-999: np.nan, -1000: 0}) print(result) # 0 1.0 # 1 NaN # 2 2.0 # 3 NaN # 4 0.0 # 5 3.0 # dtype: float64 \u91cd\u547d\u540d\u8f74\u7d22\u5f15 \u00b6 \u548cSeries\u4e2d\u503c\u66ff\u6362\u7c7b\u4f3c\uff0c\u53ef\u4ee5\u901a\u8fc7\u51fd\u6570\u6216\u6620\u5c04\u5bf9\u8f74\u6807\u7b7e\u8fdb\u884c\u7c7b\u4f3c\u7684\u8f6c\u6362\uff0c\u751f\u6210\u65b0\u7684\u4e14\u5e26\u6709\u4e0d\u540c\u6807\u7b7e\u7684\u5bf9\u8c61\u3002 data = pd.DataFrame( np.arange(12).reshape((3, 4)), index=['Ohio', 'Colorado', 'New York'], columns=['one', 'two', 'three', 'four'] ) print(data) # one two three four # Ohio 0 1 2 3 # Colorado 4 5 6 7 # New York 8 9 10 11 \u4e0eSeries\u7c7b\u4f3c\uff0c\u8f74\u7d22\u5f15\u4e5f\u6709\u4e00\u4e2a map \u65b9\u6cd5\u3002 transform = lambda x: x[:4].upper() # \u622a\u53d6index\u7684\u524d\u56db\u4f4d\u5e76\u8f6c\u5316\u4e3a\u5927\u5199\u683c\u5f0f result = data.index.map(transform) print(result) # Index(['OHIO', 'COLO', 'NEW '], dtype='object') \u8d4b\u503c\u7ed9 index \uff0c\u4fee\u6539DataFrame\u3002 data.index = data.index.map(transform) print(data) # one two three four # OHIO 0 1 2 3 # COLO 4 5 6 7 # NEW 8 9 10 11 \u521b\u5efa\u6570\u636e\u96c6\u8f6c\u6362\u540e\u7684\u7248\u672c\uff0c\u5e76\u4e14\u4e0d\u4fee\u6539\u539f\u6709\u7684\u6570\u636e\u96c6\uff0c\u4e00\u4e2a\u6709\u7528\u7684\u65b9\u6cd5\u662f rename \u3002 result = data.rename(index=str.title, columns=str.upper) print(result) # ONE TWO THREE FOUR # Ohio 0 1 2 3 # Colo 4 5 6 7 # New 8 9 10 11 print(data) # \u539f\u6709\u7684\u6570\u636e\u96c6\u672a\u88ab\u4fee\u6539 # one two three four # OHIO 0 1 2 3 # COLO 4 5 6 7 # NEW 8 9 10 11 rename \u53ef\u4ee5\u7ed3\u5408\u5b57\u5178\u578b\u5bf9\u8c61\u4f7f\u7528\uff0c\u4e3a\u8f74\u6807\u7b7e\u7684\u5b50\u96c6\u63d0\u4f9b\u65b0\u7684\u503c\u3002 result = data.rename(index={'OHIO': 'INDIANA'}, columns={'three': 'peekaboo'}) print(result) # one two peekaboo four # INDIANA 0 1 2 3 # COLO 4 5 6 7 # NEW 8 9 10 11 \u5982\u679c\u8981\u4fee\u6539\u539f\u6709\u7684\u6570\u636e\u96c6\uff0c\u4f20\u5165 inplace=True \u3002 data.rename(index={'OHIO': 'INDIANA'}, columns={'three': 'peekaboo'}, inplace=True) print(data) # one two peekaboo four # INDIANA 0 1 2 3 # COLO 4 5 6 7 # NEW 8 9 10 11 \u79bb\u6563\u5316\u548c\u5206\u7bb1 \u00b6 \u8fde\u7eed\u503c\u7ecf\u5e38\u9700\u8981\u79bb\u6563\u5316\uff0c\u6216\u8005\u5206\u79bb\u6210\u201d\u7bb1\u5b50\u201c\u8fdb\u884c\u5206\u6790\u3002 \u5047\u8bbe\u6709\u4e00\u7ec4\u4eba\u7fa4\u7684\u6570\u636e\uff0c\u60f3\u5c06\u4ed6\u4eec\u8fdb\u884c\u5206\u7ec4\uff0c\u653e\u5165\u79bb\u6563\u7684\u5e74\u9f84\u6846\u4e2d\u3002 ages = [20, 22, 25, 27, 21, 23, 37, 31, 61, 45, 41, 32] \u5c06\u8fd9\u4e9b\u5e74\u9f84\u5206\u4e3a18\uff5e25\u300126\uff5e35\u300136\uff5e60\u4ee5\u53ca61\u53ca\u4ee5\u4e0a\u7b49\u82e5\u5e72\u7ec4\uff0c\u4f7f\u7528pandas\u4e2d\u7684 cut \u3002 bins = [18, 25, 35, 60, 100] cats = pd.cut(ages, bins) print(cats) # [(18, 25], (18, 25], (18, 25], (25, 35], (18, 25], ..., (25, 35], (60, 100], (35, 60], (35, 60], (25, 35]] # Length: 12 # Categories (4, interval[int64, right]): [(18, 25] < (25, 35] < (35, 60] < (60, 100]] pandas\u8fd4\u56de\u7684\u5bf9\u8c61\u662f\u4e00\u4e2a\u7279\u6b8a\u7684 Categorical \u5bf9\u8c61\u3002 \u4f60\u770b\u5230\u7684\u8f93\u51fa\u63cf\u8ff0\u4e86\u7531 pandas.cut \u8ba1\u7b97\u51fa\u7684\u7bb1\u3002 \u4f60\u53ef\u4ee5\u5c06\u5b83\u5f53\u4f5c\u4e00\u4e2a\u8868\u793a\u7bb1\u540d\u7684\u5b57\u7b26\u4e32\u6570\u7ec4\uff1b\u5b83\u5728\u5185\u90e8\u5305\u542b\u4e00\u4e2a categories \uff08\u7c7b\u522b\uff09\u6570\u7ec4\uff0c\u5b83\u6307\u5b9a\u4e86\u4e0d\u540c\u7684\u7c7b\u522b\u540d\u79f0\u4ee5\u53ca codes \u5c5e\u6027\u4e2d\u7684 ages \uff08\u5e74\u9f84\uff09\u6570\u636e\u6807\u7b7e\u3002 print(cats.categories) # \u56db\u4e2a\u533a\u95f4\u7ec4 # IntervalIndex([(18, 25], (25, 35], (35, 60], (60, 100]], dtype='interval[int64, right]') print(cats.codes) # 61\u5c81\u843d\u5728\u7b2c3\u7ec4\uff08\u7ec4\u7f16\u53f7\u4ece0\u5f00\u59cb\uff09 # [0 0 0 1 0 0 2 1 3 2 2 1] \u6ce8\u610f\uff0c pd.value_counts(cats) \u662f\u5bf9 pandas.cut \u7684\u7ed3\u679c\u4e2d\u7684\u7bb1\u6570\u91cf\u7684\u8ba1\u6570\u3002 result = pd.value_counts(cats) print(result) # (18, 25] 5 # (25, 35] 3 # (35, 60] 3 # (60, 100] 1 # dtype: int64 \u4e0e\u533a\u95f4\u7684\u6570\u5b66\u7b26\u53f7\u4e00\u81f4\uff0c\u5c0f\u62ec\u53f7\u8868\u793a\u8fb9\u662f\u5f00\u653e\u7684\uff0c\u4e2d\u62ec\u53f7\u8868\u793a\u5b83\u662f\u5c01\u95ed\u7684\uff08\u5305\u62ec\u8fb9\uff09\u3002\u53ef\u4ee5\u901a\u8fc7\u4f20\u9012 right=False \u6765\u6539\u53d8\u54ea\u4e00\u8fb9\u662f\u5c01\u95ed\u7684\u3002\u9ed8\u8ba4 right=True \u3002 result = pd.cut(ages, [18, 26, 36, 61, 100], right=False) print(result) # [[18, 26), [18, 26), [18, 26), [26, 36), [18, 26), ..., [26, 36), [61, 100), [36, 61), [36, 61), [26, 36)] # Length: 12 # Categories (4, interval[int64, left]): [[18, 26) < [26, 36) < [36, 61) < [61, 100)] \u901a\u8fc7\u5411 labels \u9009\u9879\u4f20\u9012\u4e00\u4e2a\u5217\u8868\u6216\u6570\u7ec4\u6765\u4f20\u5165\u81ea\u5b9a\u4e49\u7684\u7bb1\u540d\u3002 group_name = ['Youth', 'YoungAdult', 'MiddleAged', 'Senior'] result = pd.cut(ages, bins, labels=group_name) print(result) # ['Youth', 'Youth', 'Youth', 'YoungAdult', 'Youth', ..., 'YoungAdult', 'Senior', 'MiddleAged', 'MiddleAged', 'YoungAdult'] # Length: 12 # Categories (4, object): ['Youth' < 'YoungAdult' < 'MiddleAged' < 'Senior'] result = pd.value_counts(pd.cut(ages, bins, labels=group_name)) # \u6807\u7b7e\u8f93\u51fa print(result) # Youth 5 # YoungAdult 3 # MiddleAged 3 # Senior 1 # dtype: int64 result = pd.value_counts(pd.cut(ages, bins)) # \u533a\u95f4\u8f93\u51fa print(result) # (18, 25] 5 # (25, 35] 3 # (35, 60] 3 # (60, 100] 1 # dtype: int64 \u5982\u679c\u4f20\u7ed9 cut \u6574\u6570\u4e2a\u7684\u7bb1\u6765\u4ee3\u66ff\u663e\u5f0f\u7684\u7bb1\u8fb9\uff0cpandas\u5c06\u6839\u636e\u6570\u636e\u4e2d\u7684\u6700\u5c0f\u503c\u548c\u6700\u5927\u503c\u8ba1\u7b97\u51fa\u7b49\u957f\u7684\u7bb1\u3002 \u4e0b\u9762\u7684\u4f8b\u5b50\u662f\u8003\u8651\u4e00\u4e9b\u5747\u5300\u5206\u5e03\u7684\u6570\u636e\u88ab\u5207\u6210\u56db\u4efd\u7684\u60c5\u51b5\u3002 data = np.random.rand(20) result = pd.cut(data, 4, precision=2) # precision=2\u7684\u9009\u9879\u5c06\u5341\u8fdb\u5236\u7cbe\u5ea6\u9650\u5236\u5728\u4e24\u4f4d\u3002 print(result) # [(0.44, 0.66], (0.0063, 0.23], (0.23, 0.44], (0.0063, 0.23], (0.23, 0.44], ..., (0.23, 0.44], (0.0063, 0.23], (0.23, 0.44], (0.66, 0.88], (0.23, 0.44]] # Length: 20 # Categories (4, interval[float64, right]): [(0.0063, 0.23] < (0.23, 0.44] < (0.44, 0.66] < (0.66, 0.88]] qcut \u662f\u4e00\u4e2a\u4e0e\u5206\u7bb1\u5bc6\u5207\u76f8\u5173\u7684\u51fd\u6570\uff0c\u5b83\u57fa\u4e8e\u6837\u672c\u5206\u4f4d\u6570\u8fdb\u884c\u5206\u7bb1\u3002 \u53d6\u51b3\u4e8e\u6570\u636e\u7684\u5206\u5e03\uff0c\u4f7f\u7528 cut \u901a\u5e38\u4e0d\u4f1a\u4f7f\u6bcf\u4e2a\u7bb1\u5177\u6709\u76f8\u540c\u6570\u636e\u91cf\u7684\u6570\u636e\u70b9\u3002 \u7531\u4e8eqcut\u4f7f\u7528\u6837\u672c\u7684\u5206\u4f4d\u6570\uff0c\u4f60\u53ef\u4ee5\u901a\u8fc7qcut\u83b7\u5f97\u7b49\u957f\u7684\u7bb1\u3002 data = np.random.randn(1000) # \u6b63\u6001\u5206\u5e03 cats = pd.qcut(data, 4) # \u5207\u62104\u4efd print(cats) # [(-0.00329, 0.644], (-0.00329, 0.644], (-0.659, -0.00329], (-0.659, -0.00329], (0.644, 3.468], ..., (0.644, 3.468], (-3.9619999999999997, -0.659], (-3.9619999999999997, -0.659], (-0.00329, 0.644], (-0.00329, 0.644]] # Length: 1000 # Categories (4, interval[float64, right]): [(-3.9619999999999997, -0.659] < (-0.659, -0.00329] < (-0.00329, 0.644] < (0.644, 3.468]] result = pd.value_counts(cats) print(result) # (-3.9619999999999997, -0.659] 250 # (-0.659, -0.00329] 250 # (-0.00329, 0.644] 250 # (0.644, 3.468] 250 # dtype: int64 \u4e0e cut \u7c7b\u4f3c\uff0c\u53ef\u4ee5\u4f20\u5165\u81ea\u5b9a\u4e49\u7684\u5206\u4f4d\u6570\uff080\u548c1\u4e4b\u95f4\u7684\u6570\u636e\uff0c\u5305\u62ec\u8fb9\uff09\u3002 result = pd.qcut(data, [0, 0.1, 0.5, 0.9, 1.]) print(result) # [(-0.00329, 1.234], (-0.00329, 1.234], (-1.321, -0.00329], (-1.321, -0.00329], (-0.00329, 1.234], ..., (-0.00329, 1.234], (-1.321, -0.00329], (-1.321, -0.00329], (-0.00329, 1.234], (-0.00329, 1.234]] # Length: 1000 # Categories (4, interval[float64, right]): [(-3.9619999999999997, -1.321] < (-1.321, -0.00329] < (-0.00329, 1.234] < (1.234, 3.468]] \u68c0\u6d4b\u548c\u8fc7\u6ee4\u5f02\u5e38\u503c \u00b6 \u8fc7\u6ee4\u6216\u8f6c\u6362\u5f02\u5e38\u503c\u5728\u5f88\u5927\u7a0b\u5ea6\u4e0a\u662f\u5e94\u7528\u6570\u7ec4\u64cd\u4f5c\u7684\u4e8b\u60c5\u3002 \u8003\u8651\u4e00\u4e2a\u5177\u6709\u6b63\u6001\u5206\u5e03\u6570\u636e\u7684DataFrame\u3002 data = pd.DataFrame(np.random.randn(1000, 4)) print(data.describe()) # 0 1 2 3 # count 1000.000000 1000.000000 1000.000000 1000.000000 # mean 0.008124 -0.008050 -0.013403 -0.008261 # std 0.979236 0.992982 0.998819 1.038760 # min -3.231914 -3.441270 -3.345210 -4.320565 # 25% -0.634801 -0.599852 -0.656481 -0.677611 # 50% -0.033252 0.000060 -0.040634 -0.015463 # 75% 0.649340 0.644312 0.678101 0.683849 # max 3.292099 2.758754 2.911447 3.371729 \u627e\u51fa\u4e00\u5217\u4e2d\u7edd\u5bf9\u503c\u5927\u4e8e\u4e09\u7684\u503c\u3002 col = data[2] result = col[np.abs(col) > 3] print(result) # 519 -3.035355 # 536 -3.345210 # Name: 2, dtype: float64 \u9009\u51fa\u6240\u6709\u503c\u5927\u4e8e3\u6216\u5c0f\u4e8e-3\u7684\u884c\uff0c\u53ef\u4ee5\u5bf9\u5e03\u5c14\u503cDataFrame\u4f7f\u7528 any \u65b9\u6cd5\u3002 result = data[(np.abs(data) > 3).any(1)] print(result) # 0 1 2 3 # 116 -0.080907 -3.441270 -0.163263 0.392800 # 139 -1.294440 1.828397 1.178897 -3.469466 # 241 -0.486292 0.150443 0.264172 -3.013440 # 295 3.292099 -0.339284 0.732829 -0.475202 # 355 0.307577 -3.053322 0.967497 0.896363 # 359 3.264981 -1.172096 0.207622 -0.281803 # 519 -0.448987 1.623843 -3.035355 -0.436833 # 533 -1.022616 -0.212597 1.030969 3.371729 # 536 1.067598 -1.306839 -3.345210 0.620834 # 541 -0.952760 -2.157970 -0.403199 -4.320565 # 690 0.006821 -3.104117 0.484881 -0.132613 # 750 -3.231914 1.017712 0.070430 0.631447 # 771 -3.007622 0.257960 -0.118179 -1.283365 # 976 1.684760 -0.003295 -0.249843 3.169371 \u6839\u636e\u8fd9\u4e9b\u6807\u51c6\u6765\u8bbe\u7f6e\u6765\u9650\u5b9a\u503c\uff0c\u4e0b\u9762\u4ee3\u7801\u9650\u5236\u4e86-3\u52303\u4e4b\u95f4\u7684\u6570\u503c\u3002 \u8bed\u53e5 np.sign(data) \u6839\u636e\u6570\u636e\u4e2d\u7684\u503c\u7684\u6b63\u8d1f\u5206\u522b\u751f\u62101\u548c-1\u7684\u6570\u503c\u3002 result = data[(np.abs(data) > 3)] = np.sign(data) * 3 print(result.describe()) # 0 1 2 3 # count 1000.000000 1000.000000 1000.000000 1000.000000 # mean -0.036000 0.000000 -0.084000 -0.048000 # std 3.001285 3.001501 3.000324 3.001117 # min -3.000000 -3.000000 -3.000000 -3.000000 # 25% -3.000000 -3.000000 -3.000000 -3.000000 # 50% -3.000000 0.000000 -3.000000 -3.000000 # 75% 3.000000 3.000000 3.000000 3.000000 # max 3.000000 3.000000 3.000000 3.000000 print(result.head()) # 0 1 2 3 # 0 -3.0 3.0 -3.0 -3.0 # 1 -3.0 -3.0 -3.0 -3.0 # 2 3.0 3.0 -3.0 3.0 # 3 3.0 -3.0 3.0 -3.0 # 4 3.0 -3.0 -3.0 -3.0 \u7f6e\u6362\u548c\u968f\u673a\u62bd\u6837 \u00b6 \u4f7f\u7528 numpy.random.permutation \u5bf9DataFrame\u4e2d\u7684Series\u6216\u884c\u8fdb\u884c\u7f6e\u6362\uff08\u968f\u673a\u91cd\u6392\u5e8f\uff09\u3002 \u5728\u8c03\u7528 permutation \u65f6\u6839\u636e\u4f60\u60f3\u8981\u7684\u8f74\u957f\u5ea6\u53ef\u4ee5\u4ea7\u751f\u4e00\u4e2a\u8868\u793a\u65b0\u987a\u5e8f\u7684\u6574\u6570\u6570\u7ec4\u3002 df = pd.DataFrame(np.arange(5 * 4).reshape((5, 4))) sampler = np.random.permutation(5) print(sampler) # \u8fd4\u56dearray # [1 4 3 0 2] print(df) # 0 1 2 3 # 0 0 1 2 3 # 1 4 5 6 7 # 2 8 9 10 11 # 3 12 13 14 15 # 4 16 17 18 19 \u4e0a\u9762\u8fd4\u56de\u7684 sampler \u6574\u6570\u6570\u7ec4 [1 4 3 0 2] \u7528\u5728\u57fa\u4e8e iloc \u7684\u7d22\u5f15\u6216\u7b49\u4ef7\u7684 take \u51fd\u6570\u4e2d\uff0c\u91cd\u65b0\u6392\u5217\u884c\u987a\u5e8f\u3002 print(df.take(sampler)) # 0 1 2 3 # 1 4 5 6 7 # 4 16 17 18 19 # 3 12 13 14 15 # 0 0 1 2 3 # 2 8 9 10 11 \u9009\u51fa\u4e00\u4e2a\u4e0d\u542b\u6709\u66ff\u4ee3\u503c\u7684\u968f\u673a\u5b50\u96c6\uff0c\u53ef\u4ee5\u4f7f\u7528Series\u548cDataFrame\u7684 sample \u65b9\u6cd5\u3002 result = df.sample(n=3) print(result) # 0 1 2 3 # 0 0 1 2 3 # 2 8 9 10 11 # 1 4 5 6 7 \u8981\u751f\u6210\u4e00\u4e2a\u5e26\u6709\u66ff\u4ee3\u503c\u7684\u6837\u672c\uff08\u5141\u8bb8\u6709\u91cd\u590d\u9009\u62e9\uff09\uff0c\u5c06 replace=True \u4f20\u5165 sample \u65b9\u6cd5\u3002 choice = pd.Series([5, 7, -1, 6, 4]) draws = choice.sample(n=10, replace=True) print(choice) # 0 5 # 1 7 # 2 -1 # 3 6 # 4 4 # dtype: int64 print(draws) # 4 4 # 0 5 # 0 5 # 3 6 # 4 4 # 0 5 # 1 7 # 3 6 # 2 -1 # 0 5 # dtype: int64 \u8ba1\u7b97\u6307\u6807/\u865a\u62df\u53d8\u91cf \u00b6 \u5c06\u5206\u7c7b\u53d8\u91cf\u8f6c\u6362\u4e3a\u201c\u865a\u62df\u201d\u6216\u201c\u6307\u6807\u201d\u77e9\u9635\u662f\u53e6\u4e00\u79cd\u7528\u4e8e\u7edf\u8ba1\u5efa\u6a21\u6216\u673a\u5668\u5b66\u4e60\u7684\u8f6c\u6362\u64cd\u4f5c\u3002 \u5982\u679cDataFrame\u4e2d\u7684\u4e00\u5217\u6709 k \u4e2a\u4e0d\u540c\u7684\u503c\uff0c\u5219\u53ef\u4ee5\u884d\u751f\u4e00\u4e2a k \u5217\u7684\u503c\u4e3a 1 \u548c 0 \u7684\u77e9\u9635\u6216DataFrame\u3002 pandas\u6709\u4e00\u4e2aget_dummies\u51fd\u6570\u7528\u4e8e\u5b9e\u73b0\u8be5\u529f\u80fd\u3002 df = pd.DataFrame( { 'key': ['b', 'b', 'a', 'c', 'a', 'b'], 'data1': range(6) } ) print(df) # key data1 # 0 b 0 # 1 b 1 # 2 a 2 # 3 c 3 # 4 a 4 # 5 b 5 \u5728\u6307\u6807DataFrame\u7684\u5217\u4e0a\u52a0\u5165\u524d\u7f00\uff0c\u7136\u540e\u4e0e\u5176\u4ed6\u6570\u636e\u5408\u5e76\u3002\u5728 get_dummies \u65b9\u6cd5\u4e2d\u6709\u4e00\u4e2a\u524d\u7f00\u53c2\u6570\u7528\u4e8e\u5b9e\u73b0\u8be5\u529f\u80fd\u3002 \u901a\u8fc7 get_dummies \u65b9\u6cd5\uff0c\u628a\u4e0a\u9762 df \u6570\u636e\u6309\u7167 key \u8fdb\u884c\u4e86\u5206\u7ec4\uff0c\u5e76\u901a\u8fc7\u4e0d\u540c\u5217\u6765\u5c55\u73b0\u5206\u7ec4\u540e\u7684\u5bf9\u5e94\u5173\u7cfb\u3002\u4f8b\u5982\uff0c key \u5217\u7684 a \uff0c\u5bf9\u5e94\u503c 2 \u548c 4 \u3002 dummies = pd.get_dummies(df['key'], prefix='key') print(dummies) # key_a key_b key_c # 0 0 1 0 # 1 0 1 0 # 2 1 0 0 # 3 0 0 1 # 4 1 0 0 # 5 0 1 0 df_with_dummy = df[['data1']].join(dummies) print(df_with_dummy) # data1 key_a key_b key_c # 0 0 0 1 0 # 1 1 0 1 0 # 2 2 1 0 0 # 3 3 0 0 1 # 4 4 1 0 0 # 5 5 0 1 0 \u66f4\u4e3a\u590d\u6742\u7684\u60c5\u51b5\uff0cDataFrame\u4e2d\u7684\u4e00\u884c\u5c5e\u4e8e\u591a\u4e2a\u7c7b\u522b\u3002 \u4ee5MovieLens\u76841M\u6570\u636e\u96c6\u4e3a\u4f8b\u3002\u589e\u52a0\u53c2\u6570 encoding='unicode_escape' \u907f\u514d\u51fa\u73b0\u4e0b\u9762\u7684\u9519\u8bef\uff1a UnicodeDecodeError: 'utf-8' codec can't decode byte 0xe9 in position 3114: invalid continuation byte \u589e\u52a0\u53c2\u6570 engine='python' \u907f\u514d\u51fa\u73b0\u4e0b\u9762\u7684\u9519\u8bef\uff1a ParserWarning: Falling back to the 'python' engine because the 'c' engine does not support regex separators (separators > 1 char and different from '\\s+' are interpreted as regex); you can avoid this warning by specifying engine='python'. mnames = ['movie_id', 'title', 'genres'] movies = pd.read_table( '../datasets/movielens/movies.dat', sep='::', header=None, names=mnames, encoding='unicode_escape', engine='python' ) print(movies[:10]) # movie_id title genres # 0 1 Toy Story (1995) Animation|Children's|Comedy # 1 2 Jumanji (1995) Adventure|Children's|Fantasy # 2 3 Grumpier Old Men (1995) Comedy|Romance # 3 4 Waiting to Exhale (1995) Comedy|Drama # 4 5 Father of the Bride Part II (1995) Comedy # 5 6 Heat (1995) Action|Crime|Thriller # 6 7 Sabrina (1995) Comedy|Romance # 7 8 Tom and Huck (1995) Adventure|Children's # 8 9 Sudden Death (1995) Action # 9 10 GoldenEye (1995) Action|Adventure|Thriller \u4e3a\u6bcf\u4e2a\u7535\u5f71\u6d41\u6d3e\u6dfb\u52a0\u6307\u6807\u53d8\u91cf\u9700\u8981\u8fdb\u884c\u4e00\u4e9b\u6570\u636e\u5904\u7406\u3002 \u9996\u5148\uff0c\u6211\u4eec\u4ece\u6570\u636e\u96c6\u4e2d\u63d0\u53d6\u51fa\u6240\u6709\u4e0d\u540c\u7684\u6d41\u6d3e\u7684\u5217\u8868\u3002 all_genres = [] for x in movies.genres: all_genres.extend(x.split('|')) genres = pd.unique(all_genres) print(genres) # ['Animation' \"Children's\" 'Comedy' 'Adventure' 'Fantasy' 'Romance' 'Drama' # 'Action' 'Crime' 'Thriller' 'Horror' 'Sci-Fi' 'Documentary' 'War' # 'Musical' 'Mystery' 'Film-Noir' 'Western'] \u4f7f\u7528\u51680\u7684DataFrame\u662f\u6784\u5efa\u6307\u6807DataFrame\u7684\u4e00\u79cd\u65b9\u5f0f\u3002 zero_matrix = np.zeros((len(movies), len(genres))) dummies = pd.DataFrame(zero_matrix, columns=genres) print(zero_matrix) # [[0. 0. 0. ... 0. 0. 0.] # [0. 0. 0. ... 0. 0. 0.] # [0. 0. 0. ... 0. 0. 0.] # ... # [0. 0. 0. ... 0. 0. 0.] # [0. 0. 0. ... 0. 0. 0.] # [0. 0. 0. ... 0. 0. 0.]] print(dummies.head(n=10)) # Animation Children's Comedy ... Mystery Film-Noir Western # 0 0.0 0.0 0.0 ... 0.0 0.0 0.0 # 1 0.0 0.0 0.0 ... 0.0 0.0 0.0 # 2 0.0 0.0 0.0 ... 0.0 0.0 0.0 # 3 0.0 0.0 0.0 ... 0.0 0.0 0.0 # 4 0.0 0.0 0.0 ... 0.0 0.0 0.0 # 5 0.0 0.0 0.0 ... 0.0 0.0 0.0 # 6 0.0 0.0 0.0 ... 0.0 0.0 0.0 # 7 0.0 0.0 0.0 ... 0.0 0.0 0.0 # 8 0.0 0.0 0.0 ... 0.0 0.0 0.0 # 9 0.0 0.0 0.0 ... 0.0 0.0 0.0 # # [10 rows x 18 columns] \u904d\u5386\u6bcf\u4e00\u90e8\u7535\u5f71\uff0c\u5c06 dummies \u6bcf\u4e00\u884c\u7684\u6761\u76ee\u8bbe\u7f6e\u4e3a 1 \u3002\u4f7f\u7528 dummies.columns \u6765\u8ba1\u7b97\u6bcf\u4e00\u4e2a\u6d41\u6d3e\u7684\u5217\u6307\u6807\u3002 gen = movies.genres[0] print(gen.split('|')) # ['Animation', \"Children's\", 'Comedy'] result = dummies.columns.get_indexer(gen.split('|')) print(result) # [0 1 2] \u4f7f\u7528 .loc \u6839\u636e\u8fd9\u4e9b\u6307\u6807\u6765\u8bbe\u7f6e\u503c\u3002 for i, gen in enumerate(movies.genres): indices = dummies.columns.get_indexer(gen.split('|')) dummies.iloc[i, indices] = 1 \u5c06\u7ed3\u679c\u4e0e movies \u8fdb\u884c\u5408\u5e76\u3002 movies_windic = movies.join(dummies.add_prefix('Genre_')) print(movies_windic.iloc[0]) # movie_id 1 # title Toy Story (1995) # genres Animation|Children's|Comedy # Genre_Animation 1.0 # Genre_Children's 1.0 # Genre_Comedy 1.0 # Genre_Adventure 0.0 # Genre_Fantasy 0.0 # Genre_Romance 0.0 # Genre_Drama 0.0 # Genre_Action 0.0 # Genre_Crime 0.0 # Genre_Thriller 0.0 # Genre_Horror 0.0 # Genre_Sci-Fi 0.0 # Genre_Documentary 0.0 # Genre_War 0.0 # Genre_Musical 0.0 # Genre_Mystery 0.0 # Genre_Film-Noir 0.0 # Genre_Western 0.0 # Name: 0, dtype: object \u5bf9\u4e8e\u66f4\u5927\u7684\u6570\u636e\uff0c\u4e0a\u9762\u8fd9\u79cd\u4f7f\u7528\u591a\u6210\u5458\u6784\u5efa\u6307\u6807\u53d8\u91cf\u5e76\u4e0d\u662f\u7279\u522b\u5feb\u901f\u3002 \u66f4\u597d\u7684\u65b9\u6cd5\u662f\u5199\u4e00\u4e2a\u76f4\u63a5\u5c06\u6570\u636e\u5199\u4e3aNumPy\u6570\u7ec4\u7684\u5e95\u5c42\u51fd\u6570\uff0c\u7136\u540e\u5c06\u7ed3\u679c\u5c01\u88c5\u8fdbDataFrame\u3002 \u5c06 get_dummies \u4e0e cut \u7b49\u79bb\u6563\u5316\u51fd\u6570\u7ed3\u5408\u4f7f\u7528\u662f\u7edf\u8ba1\u5e94\u7528\u7684\u4e00\u4e2a\u6709\u7528\u65b9\u6cd5\u3002 np.random.seed(12345) # \u4f7f\u7528numpy.random.seed\u6765\u8bbe\u7f6e\u968f\u673a\u79cd\u5b50\u4ee5\u786e\u4fdd\u793a\u4f8b\u7684\u786e\u5b9a\u6027 values = np.random.rand(10) print(values) # [0.92961609 0.31637555 0.18391881 0.20456028 0.56772503 0.5955447 # 0.96451452 0.6531771 0.74890664 0.65356987] bins = [0, 0.2, 0.4, 0.6, 0.8, 1] result = pd.get_dummies(pd.cut(values, bins)) print(result) # (0.0, 0.2] (0.2, 0.4] (0.4, 0.6] (0.6, 0.8] (0.8, 1.0] # 0 0 0 0 0 1 # 1 0 1 0 0 0 # 2 1 0 0 0 0 # 3 0 1 0 0 0 # 4 0 0 1 0 0 # 5 0 0 1 0 0 # 6 0 0 0 0 1 # 7 0 0 0 1 0 # 8 0 0 0 1 0 # 9 0 0 0 1 0 \u5b57\u7b26\u4e32\u64cd\u4f5c \u00b6 import re pandas\u5141\u8bb8\u5c06\u5b57\u7b26\u4e32\u548c\u6b63\u5219\u8868\u8fbe\u5f0f\u7b80\u6d01\u5730\u5e94\u7528\u5230\u6574\u4e2a\u6570\u636e\u6570\u7ec4\u4e0a\uff0c\u6b64\u5916\u8fd8\u80fd\u5904\u7406\u6570\u636e\u7f3a\u5931\u3002 \u5b57\u7b26\u4e32\u5bf9\u8c61\u65b9\u6cd5 \u00b6 \u5b57\u4e32\u62c6\u5206\u5408\u5e76\u65b9\u6cd5\u3002\u5728\u5f88\u591a\u5b57\u7b26\u4e32\u5904\u7406\u548c\u811a\u672c\u5e94\u7528\u4e2d\uff0c\u5185\u5efa\u7684\u5b57\u7b26\u4e32\u65b9\u6cd5\u662f\u8db3\u591f\u7684\u3002 \u4f8b\u5982\uff0c\u4e00\u4e2a\u9017\u53f7\u5206\u9694\u7684\u5b57\u7b26\u4e32\u53ef\u4ee5\u4f7f\u7528split\u65b9\u6cd5\u62c6\u5206\u6210\u591a\u5757\u3002 import numpy as np import pandas as pd val = 'a, b, guido' result = val.split(',') print(result) # ['a', ' b', ' guido'] count \uff1a\u8fd4\u56de\u5b50\u5b57\u7b26\u4e32\u5728\u5b57\u7b26\u4e32\u4e2d\u7684\u975e\u91cd\u53e0\u51fa\u73b0\u6b21\u6570\u3002 result = val.count(',') print(result) # 2 endswith \uff1a\u5982\u679c\u5b57\u7b26\u4e32\u4ee5\u540e\u7f00\u7ed3\u5c3e\u5219\u8fd4\u56de True \u3002 startswith \uff1a\u5982\u679c\u5b57\u7b26\u4e32\u4ee5\u540e\u7f00\u7ed3\u5c3e\u5219\u8fd4\u56de True \u3002 result = val.endswith('b') print(result) # False result = val.endswith('o') print(result) # True result = val.startswith('a') print(result) # True split \u5e38\u548c strip \u4e00\u8d77\u4f7f\u7528\uff0c\u7528\u4e8e\u6e05\u9664\u7a7a\u683c\uff08\u5305\u62ec\u6362\u884c\uff09\u3002 split \uff1a\u4f7f\u7528\u5206\u9694\u7b26\u8bb2\u5b57\u7b26\u4e32\u62c6\u5206\u6210\u5b50\u5b57\u7b26\u4e32\u7684\u5217\u8868\u3002 strip \uff0c rstrip \uff0c lstrip \uff1a\u4fee\u526a\u7a7a\u767d\uff0c\u5305\u62ec\u6362\u884c\u7b26\uff1b\u76f8\u5f53\u4e8e\u5bf9\u6bcf\u4e2a\u5143\u7d20\u8fdb\u884c x.strip() (\u4ee5\u53ca rstrip \uff0c lstrip )\u3002 pieces = [x.strip() for x in val.split(',')] print(pieces) # ['a', 'b', 'guido'] \u8fd9\u4e9b\u5b50\u5b57\u7b26\u4e32\u53ef\u4ee5\u4f7f\u7528\u52a0\u6cd5\u4e0e\u4e24\u4e2a\u5192\u53f7\u5206\u9694\u7b26\u8fde\u63a5\u5728\u4e00\u8d77\u3002 first, second, third = pieces result = first + '::' + second + '::' + third print(result) # a::b::guido \u4f46\u662f\u8fd9\u5e76\u4e0d\u662f\u4e00\u4e2a\u5b9e\u7528\u7684\u901a\u7528\u65b9\u6cd5\u3002 \u5728\u5b57\u7b26\u4e32 ': :' \u7684 join \u65b9\u6cd5\u4e2d\u4f20\u5165\u4e00\u4e2a\u5217\u8868\u6216\u5143\u7ec4\u662f\u4e00\u79cd\u66f4\u5feb\u4e14\u66f4\u52a0Pythonic\uff08Python\u98ce\u683c\u5316\uff09\u7684\u65b9\u6cd5\u3002 join : \u4f7f\u7528\u5b57\u7b26\u4e32\u5ea7\u4f4d\u95f4\u9694\u7b26\uff0c\u7528\u4e8e\u7c98\u5408\u5176\u4ed6\u5b57\u7b26\u4e32\u7684\u5e8f\u5217\u3002 result = '::'.join(pieces) print(result) # a::b::guido \u5b9a\u4f4d\u5b50\u5b57\u7b26\u4e32\u7684\u65b9\u6cd5\u3002 \u4f7f\u7528Python\u7684 in \u5173\u952e\u5b57\u662f\u68c0\u6d4b\u5b50\u5b57\u7b26\u4e32\u7684\u6700\u4f73\u65b9\u6cd5\uff0c\u5c3d\u7ba1 index \u548c find \u4e5f\u80fd\u5b9e\u73b0\u540c\u6837\u7684\u529f\u80fd\u3002 result = 'guido' in val print(result) # True index \uff1a\u5982\u679c\u5728\u5b57\u7b26\u4e32\u4e2d\u627e\u5230\uff0c\u5219\u8fd4\u56de\u5b50\u5b57\u7b26\u4e32\u4e2d\u7b2c\u4e00\u4e2a\u5b57\u7b26\u7684\u4f4d\u7f6e\uff0c\u5982\u679c\u627e\u4e0d\u5230\u5219\u89e6\u53d1\u4e00\u4e2a ValueError \u3002 find \uff1a\u8fd4\u56de\u5b57\u7b26\u4e32\u4e2d\u7b2c\u4e00\u4e2a\u51fa\u73b0\u5b50\u5b57\u7b26\u7684\u7b2c\u4e00\u4e2a\u5b57\u7b26\u7684\u4f4d\u7f6e\uff0c\u7c7b\u4f3c index \uff0c\u5982\u679c\u6ca1\u6709\u627e\u5230\uff0c\u5219\u8fd4\u56de -1 \u3002 rfind \uff1a\u8fd4\u56de\u5b57\u7b26\u4e32\u4e2d\u5b50\u5b57\u7b26\u6700\u540e\u4e00\u6b21\u51fa\u73b0\u65f6\u7b2c\u4e00\u4e2a\u5b57\u7b26\u7684\u4f4d\u7f6e\uff0c\u5982\u679c\u6ca1\u6709\u627e\u5230\uff0c\u5219\u8fd4\u56de -1 \u3002 result = val.index(',') print(result) # 1 result = val.find(',') print(result) # 1 # result = val.index(':') print(result) # ValueError: substring not found result = val.find(':') print(result) # -1 result = val.rfind(',') print(result) # 4 replace \u5c06\u7528\u4e00\u79cd\u6a21\u5f0f\u66ff\u4ee3\u53e6\u4e00\u79cd\u6a21\u5f0f\u3002\u5b83\u4e5f\u7528\u4e8e\u4f20\u5165\u7a7a\u5b57\u7b26\u4e32\u6765\u5220\u9664\u67d0\u4e2a\u6a21\u5f0f\u3002 result = val.replace(',', '::') print(result) # a:: b:: guido result = val.replace(', ', '') print(result) # abguido result = val.replace(',', '') print(result) # a b guido lower \uff1a\u5c06\u5927\u5199\u5b57\u6bcd\u8f6c\u6362\u4e3a\u5c0f\u5199\u5b57\u6bcd\u3002 upper \uff1a\u5c06\u5c0f\u5199\u5b57\u6bcd\u8f6c\u6362\u4e3a\u5927\u5199\u5b57\u6bcd\u3002 uppers = val.upper() print(uppers) # A, B, GUIDO casefold \uff1a\u548c lower \u7c7b\u4f3c\uff0c\u5c06\u5b57\u7b26\u4e32\u4e2d\u7684\u5143\u7d20\u53d8\u6210\u5c0f\u5199\uff0c lower \u51fd\u6570\u53ea\u652f\u6301 ascill \u8868\u4e2d\u7684\u5b57\u7b26\uff0c casefold \u652f\u6301\u5f88\u591a\u4e0d\u540c\u79cd\u7c7b\u7684\u8bed\u8a00\u3002 str1 = \"Jan Wei\u03b2@cN\u4e0a\u6d77\" result = str1.casefold() print(result) # jan wei\u03b2@cn\u4e0a\u6d77 result = str1.lower() print(result) # jan wei\u03b2@cn\u4e0a\u6d77 ljust \uff0c rjust \uff1a\u5de6\u5bf9\u9f50\u6216\u8005\u53f3\u5bf9\u9f50\uff1b\u7528\u7a7a\u683c\u6216\u8005\u5176\u5b83\u4e00\u4e9b\u5b57\u7b26\u586b\u5145\u5b57\u7b26\u4e32\u7684\u76f8\u53cd\u4fa7\uff0c\u4ee5\u8fd4\u56de\u5177\u6709\u6700\u5c0f\u5bbd\u5ea6\u7684\u5b57\u7b26\u4e32 str1 = 'https://docs.python.org/3/' str2 = 'https://packagehub.suse.com/package-categories/python/' print(str1.ljust(60, '*')) print(str2.ljust(60, '*')) # https://docs.python.org/3/********************************** # https://packagehub.suse.com/package-categories/python/****** print(str1.rjust(60, '*')) print(str2.rjust(60, '*')) # **********************************https://docs.python.org/3/ # ******https://packagehub.suse.com/package-categories/python/ print(str1.rjust(60)) print(str2.rjust(60)) \u6b63\u5219\u8868\u8fbe\u5f0f \u00b6 Python\u5185\u5efa\u7684 re \u6a21\u5757\u662f\u7528\u4e8e\u5c06\u6b63\u5219\u8868\u8fbe\u5f0f\u5e94\u7528\u5230\u5b57\u7b26\u4e32\u4e0a\u7684\u5e93\u3002 re \u6a21\u5757\u4e3b\u8981\u6709\u4e09\u4e2a\u4e3b\u9898\uff1a\u6a21\u5f0f\u5339\u914d\u3001\u66ff\u4ee3\u3001\u62c6\u5206\u3002 \u770b\u4e00\u4e2a\u7b80\u5355\u7684\u793a\u4f8b\uff1a\u5047\u8bbe\u6211\u4eec\u60f3\u5c06\u542b\u6709\u591a\u79cd\u7a7a\u767d\u5b57\u7b26\uff08\u5236\u8868\u7b26\u3001\u7a7a\u683c\u3001\u6362\u884c\u7b26\uff09\u7684\u5b57\u7b26\u4e32\u62c6\u5206\u5f00\u3002 \u63cf\u8ff0\u4e00\u4e2a\u6216\u591a\u4e2a\u7a7a\u767d\u5b57\u7b26\u7684\u6b63\u5219\u8868\u8fbe\u5f0f\u662f \\s+ \u3002 \u5f53\u8c03\u7528 re.split('\\s+', text) \uff0c\u6b63\u5219\u8868\u8fbe\u5f0f\u9996\u5148\u4f1a\u88ab\u7f16\u8bd1\uff0c\u7136\u540e\u6b63\u5219\u8868\u8fbe\u5f0f\u7684 split \u65b9\u6cd5\u5728\u4f20\u5165\u6587\u672c\u4e0a\u88ab\u8c03\u7528\u3002 text = \"foo bar\\t baz \\tqux\" result = re.split('\\s+', text) print(result) # ['foo', 'bar', 'baz', 'qux'] \u53ef\u4ee5\u4f7f\u7528 re.compile \u81ea\u884c\u7f16\u8bd1\uff0c\u5f62\u6210\u4e00\u4e2a\u53ef\u590d\u7528\u7684\u6b63\u5219\u8868\u8fbe\u5f0f\u5bf9\u8c61\u3002 regex = re.compile('\\s+') result = regex.split(text) print(result) # ['foo', 'bar', 'baz', 'qux'] \u5982\u679c\u60f3\u83b7\u5f97\u7684\u662f\u4e00\u4e2a\u6240\u6709\u5339\u914d\u6b63\u5219\u8868\u8fbe\u5f0f\u7684\u6a21\u5f0f\u7684\u5217\u8868\uff0c\u4f60\u53ef\u4ee5\u4f7f\u7528 findall \u65b9\u6cd5\u3002 result = regex.findall(text) print(result) # [' ', '\\t ', ' \\t'] \u4e3a\u4e86\u5728\u6b63\u5219\u8868\u8fbe\u5f0f\u4e2d\u907f\u514d\u8f6c\u4e49\u7b26 \\ \u7684\u5f71\u54cd\uff0c\u53ef\u4ee5\u4f7f\u7528\u539f\u751f\u5b57\u7b26\u4e32\u8bed\u6cd5\uff0c\u6bd4\u5982 r'C:\\x' \u6216\u8005\u7528\u7b49\u4ef7\u7684 'C:\\\\x'\\ \u3002 \u5982\u679c\u9700\u8981\u5c06\u76f8\u540c\u7684\u8868\u8fbe\u5f0f\u5e94\u7528\u5230\u591a\u4e2a\u5b57\u7b26\u4e32\u4e0a\uff0c\u63a8\u8350\u4f7f\u7528 re.compile \u521b\u5efa\u4e00\u4e2a\u6b63\u5219\u8868\u8fbe\u5f0f\u5bf9\u8c61\uff0c\u8fd9\u6837\u505a\u6709\u5229\u4e8e\u8282\u7ea6CPU\u5468\u671f\u3002 match \u548c search \u4e0e findall \u76f8\u5173\u6027\u5f88\u5927\u3002 findall \u8fd4\u56de\u7684\u662f\u5b57\u7b26\u4e32\u4e2d\u6240\u6709\u7684\u5339\u914d\u9879\uff0c\u800c search \u8fd4\u56de\u7684\u4ec5\u4ec5\u662f\u7b2c\u4e00\u4e2a\u5339\u914d\u9879\u3002 match \u66f4\u4e3a\u4e25\u683c\uff0c\u5b83\u53ea\u5728\u5b57\u7b26\u4e32\u7684\u8d77\u59cb\u4f4d\u7f6e\u8fdb\u884c\u5339\u914d\u3002 text = \"\"\"Dave dave@google.com Steve steve@gmail.com Rob rob@gmail.com Ryan ryan@yahoo.com \"\"\" pattern = r'[A-Z0-9._%+-]+@[A-Z0-9.-]+\\.[A-Z]{2,4}' regex = re.compile(pattern, flags=re.IGNORECASE) # flags=re.IGNORECASE \u4f7f\u6b63\u5219\u8868\u8fbe\u5f0f\u4e0d\u533a\u5206\u5927\u5c0f\u5199 m = regex.findall(text) # findall\u4f1a\u751f\u6210\u4e00\u4e2a\u7535\u5b50\u90ae\u4ef6\u5730\u5740\u7684\u5217\u8868 print(m) # ['dave@google.com', 'steve@gmail.com', 'rob@gmail.com', 'ryan@yahoo.com'] search \u8fd4\u56de\u7684\u662f\u6587\u672c\u4e2d\u7b2c\u4e00\u4e2a\u5339\u914d\u5230\u7684\u7535\u5b50\u90ae\u4ef6\u5730\u5740\u3002 \u5bf9\u4e8e\u524d\u9762\u63d0\u5230\u7684\u6b63\u5219\u8868\u8fbe\u5f0f\uff0c\u5339\u914d\u5bf9\u8c61\u53ea\u80fd\u544a\u8bc9\u6211\u4eec\u6a21\u5f0f\u5728\u5b57\u7b26\u4e32\u4e2d\u8d77\u59cb\u548c\u7ed3\u675f\u7684\u4f4d\u7f6e\u3002 m = regex.search(text) print(m) # print(text[m.start():m.end()]) # dave@google.com regex.match \u53ea\u5728\u6a21\u5f0f\u51fa\u73b0\u4e8e\u5b57\u7b26\u4e32\u8d77\u59cb\u4f4d\u7f6e\u65f6\u8fdb\u884c\u5339\u914d\uff0c\u5982\u679c\u6ca1\u6709\u5339\u914d\u5230\uff0c\u8fd4\u56de None \u3002 m = regex.match(text) print(m) # None m = regex.match('rob@gmail.com') print(m) # print(m.group()) # rob@gmail.com print(m.groups()) # () regex.sub \u4f1a\u8fd4\u56de\u4e00\u4e2a\u65b0\u7684\u5b57\u7b26\u4e32\uff0c\u539f\u5b57\u7b26\u4e32\u4e2d\u7684\u6a21\u5f0f\u4f1a\u88ab\u4e00\u4e2a\u65b0\u7684\u5b57\u7b26\u4e32\u66ff\u4ee3\u3002 m = regex.sub('REDACTED', text) print(m) # Dave REDACTED # Steve REDACTED # Rob REDACTED # Ryan REDACTED \u67e5\u627e\u7535\u5b50\u90ae\u4ef6\u5730\u5740\uff0c\u5e76\u5c06\u6bcf\u4e2a\u5730\u5740\u5206\u4e3a\u4e09\u4e2a\u90e8\u5206\uff1a\u7528\u6237\u540d\uff0c\u57df\u540d\u548c\u57df\u540d\u540e\u7f00\u3002\u8981\u5b9e\u73b0\u8fd9\u4e00\u70b9\uff0c\u53ef\u4ee5\u7528\u62ec\u53f7\u5c06 pattern \u5305\u8d77\u6765\u3002 \u4fee\u6539\u540e\u7684\u6b63\u5219\u8868\u8fbe\u5f0f\u4ea7\u751f\u7684\u5339\u914d\u5bf9\u8c61\u7684 groups \u65b9\u6cd5\uff0c\u8fd4\u56de\u7684\u662f\u6a21\u5f0f\u7ec4\u4ef6\u7684\u5143\u7ec4\u3002 text = \"\"\"Dave dave@google.com Steve steve@gmail.com Rob rob@gmail.com Ryan ryan@yahoo.com \"\"\" pattern = r'([A-Z0-9._%+-]+)@([A-Z0-9.-]+)\\.([A-Z]{2,4})' regex = re.compile(pattern, flags=re.IGNORECASE) m = regex.findall(text) # \u5f53pattern\u53ef\u4ee5\u5206\u7ec4\u65f6\uff0cfindall\u8fd4\u56de\u7684\u662f\u5305\u542b\u5143\u7ec4\u7684\u5217\u8868 print(m) # [('dave', 'google', 'com'), ('steve', 'gmail', 'com'), ('rob', 'gmail', 'com'), ('ryan', 'yahoo', 'com')] m = regex.search(text) print(m) # print(text[m.start():m.end()]) # dave@google.com m = regex.match('rob@gmail.com') print(m) # print(m.group()) # rob@gmail.com print(m.groups()) # ('rob', 'gmail', 'com') m = regex.sub('REDACTED', text) print(m) # Dave REDACTED # Steve REDACTED # Rob REDACTED # Ryan REDACTED m = regex.sub(r'Username: \\1, Domain: \\2, Suffix: \\3', text) print(m) # Dave Username: dave, Domain: google, Suffix: com # Steve Username: steve, Domain: gmail, Suffix: com # Rob Username: rob, Domain: gmail, Suffix: com # Ryan Username: ryan, Domain: yahoo, Suffix: com pandas\u4e2d\u7684\u5411\u91cf\u5316\u5b57\u7b26\u4e32\u51fd\u6570 \u00b6 \u6e05\u7406\u6742\u4e71\u7684\u6570\u636e\u96c6\u7528\u4e8e\u5206\u6790\u901a\u5e38\u9700\u8981\u5927\u91cf\u7684\u5b57\u7b26\u4e32\u5904\u7406\u548c\u6b63\u5219\u5316\u3002 data = { 'Dave': 'dave@gmail.com', 'Steve': 'steve@gmail.com', 'Rob': 'rob@gmail.com', 'Wes': np.nan } data = pd.Series(data) print(data) # Dave dave@gmail.com # Steve steve@gmail.com # Rob rob@gmail.com # Wes NaN # dtype: object print(data.isnull()) # Dave False # Steve False # Rob False # Wes True # dtype: bool \u53ef\u4ee5\u4f7f\u7528 data.map \u5c06\u5b57\u7b26\u4e32\u548c\u6709\u6548\u7684\u6b63\u5219\u8868\u8fbe\u5f0f\u65b9\u6cd5\uff08\u4ee5 lambda \u6216\u5176\u4ed6\u51fd\u6570\u7684\u65b9\u5f0f\u4f20\u9012\uff09\u5e94\u7528\u5230\u6bcf\u4e2a\u503c\u4e0a\uff0c\u4f46\u662f\u5728 NA \uff08 null \uff09\u503c\u4e0a\u4f1a\u5931\u8d25\u3002 \u4e3a\u4e86\u89e3\u51b3\u8fd9\u4e2a\u95ee\u9898\uff0cSeries\u6709\u9762\u5411\u6570\u7ec4\u7684\u65b9\u6cd5\u7528\u4e8e\u8df3\u8fc7 NA \u503c\u7684\u5b57\u7b26\u4e32\u64cd\u4f5c\u3002\u8fd9\u4e9b\u65b9\u6cd5\u901a\u8fc7Series\u7684 str \u5c5e\u6027\u8fdb\u884c\u8c03\u7528\u3002 \u4f8b\u5982\uff0c\u53ef\u4ee5\u901a\u8fc7 str.contains \u6765\u68c0\u67e5\u6bcf\u4e2a\u7535\u5b50\u90ae\u4ef6\u5730\u5740\u662f\u5426\u542b\u6709 'gmail' \u3002 m = data.str.contains('gmail') print(m) # Dave True # Steve True # Rob True # Wes NaN # dtype: object \u6b63\u5219\u8868\u8fbe\u5f0f\u4e5f\u53ef\u4ee5\u7ed3\u5408\u4efb\u610f\u7684 re \u6a21\u5757\u9009\u9879\u4f7f\u7528\uff0c\u4f8b\u5982 IGNORECASE \u3002 print(pattern) # ([A-Z0-9._%+-]+)@([A-Z0-9.-]+)\\.([A-Z]{2,4}) m = data.str.findall(pattern, flags=re.IGNORECASE) print(m) # Dave [(dave, gmail, com)] # Steve [(steve, gmail, com)] # Rob [(rob, gmail, com)] # Wes NaN # dtype: object \u4f7f\u7528 str.get \u6216\u5728 str \u5c5e\u6027\u5185\u90e8\u7d22\u5f15\uff0c\u8fdb\u884c\u5411\u91cf\u5316\u7684\u5143\u7d20\u68c0\u7d22\u3002 m = data.str.match(pattern, flags=re.IGNORECASE) print(m) # Dave True # Steve True # Rob True # Wes NaN # dtype: object m = data.str.findall(pattern, flags=re.IGNORECASE) print(m.str.get(1)) # Dave NaN # Steve NaN # Rob NaN # Wes NaN # dtype: float64 print(m.str[0]) # Dave (dave, gmail, com) # Steve (steve, gmail, com) # Rob (rob, gmail, com) # Wes NaN # dtype: object \u4f7f\u7528\u5b57\u7b26\u4e32\u5207\u7247\u7684\u7c7b\u4f3c\u8bed\u6cd5\u8fdb\u884c\u5411\u91cf\u5316\u5207\u7247\u3002 print(data.str[:]) # Dave dave@gmail.com # Steve steve@gmail.com # Rob rob@gmail.com # Wes NaN # dtype: object print(data.str[:5]) # Dave dave@ # Steve steve # Rob rob@g # Wes NaN # dtype: object","title":"\u6570\u636e\u6e05\u6d17\u4e0e\u51c6\u5907"},{"location":"python/DataAnalysis/ch04/#_1","text":"","title":"\u6570\u636e\u6e05\u6d17\u4e0e\u51c6\u5907"},{"location":"python/DataAnalysis/ch04/#_2","text":"import pandas as pd import numpy as np from numpy import nan as NA \u5bf9\u4e8e\u6570\u503c\u578b\u6570\u636e\uff0cpandas\u4f7f\u7528\u6d6e\u70b9\u503c NaN \uff08Not a Number\u6765\u8868\u793a\u7f3a\u5931\u503c\uff09\u3002 \u5728pandas\u4e2d\uff0c\u91c7\u7528\u4e86R\u8bed\u8a00\u4e2d\u7684\u7f16\u7a0b\u60ef\u4f8b\uff0c\u5c06\u7f3a\u5931\u503c\u6210\u4e3a NA \uff0c\u610f\u601d\u662fnotavailable\uff08\u4e0d\u53ef\u7528\uff09\u3002 Python\u5185\u5efa\u7684 None \u503c\u5728\u5bf9\u8c61\u6570\u7ec4\u4e2d\u4e5f\u88ab\u5f53\u4f5c NA \u5904\u7406\u3002 NA\u5904\u7406\u65b9\u6cd5\uff1a dropna :\u6839\u636e\u6bcf\u4e2a\u6807\u7b7e\u7684\u503c\u662f\u5426\u662f\u786e\u5b9e\u6570\u636e\u6765\u7b5b\u9009\u8f74\u6807\u7b7e\uff0c\u5e76\u6839\u636e\u5141\u8bb8\u4e22\u5931\u7684\u6570\u636e\u91cf\u6765\u786e\u5b9a\u9608\u503c fillna :\u7528\u67d0\u4e9b\u503c\u586b\u5145\u786e\u5b9e\u7684\u6570\u636e\u6216\u4f7f\u7528\u63d2\u503c\u65b9\u6cd5\uff0c\u5982 ffill \u6216 bfill isnull :\u8fd4\u56de\u8868\u660e\u54ea\u4e9b\u503c\u662f\u7f3a\u5931\u503c\u7684\u5e03\u5c14\u503c notnull :\u662f isnull \u7684\u53cd\u51fd\u6570 string_data = pd.Series(['aardvark', 'artichoke', np.nan, 'avocado']) print(string_data) # 0 aardvark # 1 artichoke # 2 NaN # 3 avocado # dtype: object print(string_data.isnull()) # 0 False # 1 False # 2 True # 3 False # dtype: bool string_data[0] = None print(string_data.isnull()) # 0 True # 1 False # 2 True # 3 False # dtype: bool","title":"\u5904\u7406\u7f3a\u5931\u503c"},{"location":"python/DataAnalysis/ch04/#_3","text":"","title":"\u8fc7\u6ee4\u7f3a\u5931\u503c"},{"location":"python/DataAnalysis/ch04/#series","text":"\u5728Series\u4e0a\u4f7f\u7528 dropna \uff0c\u5b83\u4f1a\u8fd4\u56deSeries\u4e2d\u6240\u6709\u7684\u975e\u7a7a\u6570\u636e\u53ca\u5176\u7d22\u5f15\u503c\u3002 data = pd.Series([1, NA, 3.5, NA, 7]) print(data.dropna()) # 0 1.0 # 2 3.5 # 4 7.0 # dtype: float64 print(data[data.notnull()]) # \u4e0e\u4e0a\u9762\u7b49\u4ef7 # 0 1.0 # 2 3.5 # 4 7.0 # dtype: float64","title":"\u5904\u7406Series"},{"location":"python/DataAnalysis/ch04/#dataframe","text":"data = pd.DataFrame( [[1., 6.5, 3.], [1., NA, NA], [NA, NA, NA], [NA, 6.5, 3.]] ) print(data) # 0 1 2 # 0 1.0 6.5 3.0 # 1 1.0 NaN NaN # 2 NaN NaN NaN # 3 NaN 6.5 3.0 cleaned = data.dropna() # dropna\u9ed8\u8ba4\u60c5\u51b5\u4e0b\u4f1a\u5220\u9664\u5305\u542b\u7f3a\u5931\u503c\u7684\u884c print(cleaned) # 0 1 2 # 0 1.0 6.5 3.0 cleaned = data.dropna(how='all') # \u4f20\u5165how='all\u2019\u65f6\uff0c\u5c06\u5220\u9664\u6240\u6709\u503c\u5747\u4e3aNA\u7684\u884c print(cleaned) # 0 1 2 # 0 1.0 6.5 3.0 # 1 1.0 NaN NaN # 3 NaN 6.5 3.0 data[4] = NA print(data) # 0 1 2 4 # 0 1.0 6.5 3.0 NaN # 1 1.0 NaN NaN NaN # 2 NaN NaN NaN NaN # 3 NaN 6.5 3.0 NaN cleaned = data.dropna(axis=1, how='all') # \u5220\u9664\u5168NA\u7684\u5217 print(cleaned) # 0 1 2 # 0 1.0 6.5 3.0 # 1 1.0 NaN NaN # 2 NaN NaN NaN # 3 NaN 6.5 3.0 df = pd.DataFrame(np.random.randn(7, 3)) print(df) # 0 1 2 # 0 -1.069771 -0.777921 0.181956 # 1 -0.399504 -0.641737 -0.946327 # 2 -1.013920 -0.247588 -0.760146 # 3 1.076946 -1.263203 0.494077 # 4 0.460985 -1.241870 0.283006 # 5 1.168149 1.033752 0.900095 # 6 -1.208514 -1.049546 -0.783680 df.iloc[:4, 1] = NA # \u6807\u7b7e1\uff0c\u524d4\u4e2a\u5143\u7d20 df.iloc[:2, 2] = NA # \u6807\u7b7e2\uff0c\u524d2\u4e2a\u5143\u7d20 print(df) # 0 1 2 # 0 -1.069771 NaN NaN # 1 -0.399504 NaN NaN # 2 -1.013920 NaN -0.760146 # 3 1.076946 NaN 0.494077 # 4 0.460985 -1.241870 0.283006 # 5 1.168149 1.033752 0.900095 # 6 -1.208514 -1.049546 -0.783680 cleaned = df.dropna() print(cleaned) # 0 1 2 # 4 0.033663 0.291886 0.736448 # 5 -0.433380 0.397104 1.252005 # 6 -1.999018 0.303866 1.430109 cleaned = df.dropna(thresh=2) # \u4fdd\u75592\u884c\u542bNA\u7684\u89c2\u5bdf\u503c print(cleaned) # 0 1 2 # 2 -1.413976 NaN 0.222274 # 3 -0.644266 NaN 0.324180 # 4 -0.122160 -2.244880 -0.406562 # 5 -0.140326 0.101133 -0.764048 # 6 -1.809141 0.139091 -0.819175","title":"\u5904\u7406DataFrame"},{"location":"python/DataAnalysis/ch04/#_4","text":"fillna \u51fd\u6570\u53c2\u6570\uff1a value\uff1a\u6807\u91cf\u503c\u6216\u5b57\u5178\u578b\u5bf9\u8c61\u7528\u4e8e\u586b\u5145\u7f3a\u5931\u503c method\uff1a\u63d2\u503c\u65b9\u6cd5\uff0c\u5982\u679c\u6ca1\u6709\u5176\u4ed6\u53c2\u6570\uff0c\u9ed8\u8ba4\u662f'ffill' axis\uff1a\u9700\u8981\u586b\u5145\u7684\u8f74\uff0c\u9ed8\u8ba4axis=0 inplace\uff1a\u4fee\u6539\u88ab\u8c03\u7528\u5bf9\u8c61\uff0c\u800c\u4e0d\u662f\u751f\u6210\u4e00\u4e2a\u5907\u4efd limit\uff1a\u7528\u4e8e\u524d\u5411\u6216\u540e\u5411\u586b\u5145\u65f6\u6700\u5927\u7684\u586b\u5145\u8303\u56f4 df = pd.DataFrame(np.random.randn(7, 3)) df.iloc[:4, 1] = NA # \u6807\u7b7e1\uff0c\u524d4\u4e2a\u5143\u7d20 df.iloc[:2, 2] = NA # \u6807\u7b7e2\uff0c\u524d2\u4e2a\u5143\u7d20 print(df) # 0 1 2 # 0 -0.181196 NaN NaN # 1 -1.657668 NaN NaN # 2 -0.053454 NaN 0.391461 # 3 -0.539307 NaN -0.668400 # 4 -0.433439 0.839713 -0.295273 # 5 0.749930 1.661641 -0.495165 # 6 0.591810 1.017372 0.932367 result = df.fillna(0) # \u8c03\u7528fillna\u65f6\uff0c\u53ef\u4ee5\u4f7f\u7528\u4e00\u4e2a\u5e38\u6570\u6765\u66ff\u4ee3\u7f3a\u5931\u503c print(result) # 0 1 2 # 0 -0.430926 0.000000 0.000000 # 1 0.448061 0.000000 0.000000 # 2 -0.059910 0.000000 -1.532646 # 3 -0.315793 0.000000 -0.196546 # 4 -0.546106 0.135108 -0.332309 # 5 1.083075 0.346070 -0.773104 # 6 -0.186511 1.055337 -1.168303 result = df.fillna({1: 0.5, 2: 0}) # \u8c03\u7528fillna\u65f6\u4f7f\u7528\u5b57\u5178\uff0c\u53ef\u4ee5\u4e3a\u4e0d\u540c\u5217\u8bbe\u5b9a\u4e0d\u540c\u7684\u586b\u5145\u503c print(result) # 0 1 2 # 0 -0.794344 0.500000 0.000000 # 1 -0.960917 0.500000 0.000000 # 2 1.494351 0.500000 0.100878 # 3 -0.554765 0.500000 1.118801 # 4 -0.866117 0.523615 1.217478 # 5 -0.706966 -0.681776 0.797690 # 6 -1.456366 1.205518 -0.402432 fillna \u8fd4\u56de\u7684\u662f\u4e00\u4e2a\u65b0\u7684\u5bf9\u8c61\uff0c\u4f46\u4e5f\u53ef\u4ee5\u4fee\u6539\u5df2\u7ecf\u5b58\u5728\u7684\u5bf9\u8c61 _ = df.fillna(0, inplace=True) # inplace=True\u6307\u5b9a\u5728\u5df2\u6709\u5bf9\u8c61\u4e0a\u76f4\u63a5\u4fee\u6539 print(df) # 0 1 2 # 0 -1.176124 0.000000 0.000000 # 1 0.120458 0.000000 0.000000 # 2 -1.206408 0.000000 0.551693 # 3 0.224563 0.000000 1.145156 # 4 -0.557836 0.081135 -0.075282 # 5 2.378837 -0.876145 1.430386 # 6 -0.152662 1.278364 0.479686 df = pd.DataFrame(np.random.randn(6, 3)) df.iloc[2:, 1] = NA # \u6807\u7b7e1\uff0c\u524d4\u4e2a\u5143\u7d20 df.iloc[4:, 2] = NA # \u6807\u7b7e2\uff0c\u524d2\u4e2a\u5143\u7d20 print(df) # 0 1 2 # 0 1.154788 0.033949 -0.122807 # 1 0.258684 -0.580244 1.636514 # 2 1.503756 NaN -1.224203 # 3 0.824049 NaN -0.364345 # 4 -1.247609 NaN NaN # 5 -1.019980 NaN NaN result = df.fillna(method='ffill') # \u5411\u540e\u586b\u5145 print(result) # 0 1 2 # 0 2.082449 0.398874 0.359772 # 1 0.233129 0.385347 1.953533 # 2 0.396555 0.385347 0.592784 # 3 -0.957249 0.385347 0.169815 # 4 0.854452 0.385347 0.169815 # 5 -0.105982 0.385347 0.169815 result = df.fillna(method='ffill', limit=3) # \u6bcf\u5217\u6700\u591a\u586b3\u4e2a print(result) result = df.fillna(df[0].max()) # \u75280\u5217\u7684\u6700\u5927\u503c\u586b\u5145\u6240\u6709\u7684NA print(result) # 0 1 2 # 0 -0.377697 -0.852891 -0.705489 # 1 -0.611759 -0.013237 -0.295764 # 2 -0.389974 1.057881 1.041957 # 3 -0.016845 1.057881 -1.149954 # 4 1.057881 1.057881 1.057881 # 5 -0.463471 1.057881 1.057881","title":"\u8865\u5168\u7f3a\u5931\u503c"},{"location":"python/DataAnalysis/ch04/#_5","text":"import pandas as pd import numpy as np from numpy import nan as NA","title":"\u6570\u636e\u8f6c\u6362"},{"location":"python/DataAnalysis/ch04/#_6","text":"data = pd.DataFrame( { 'k1': ['one', 'two'] * 3 + ['two'], 'k2': [1, 1, 2, 3, 4, 4, 4] } ) print(data) # \u91cd\u590d\u51fa\u73b02\u6b21\u7684\u8bb0\u5f55\uff1atwo 4 # k1 k2 # 0 one 1 # 1 two 1 # 2 one 2 # 3 two 3 # 4 one 4 # 5 two 4 # 6 two 4 DataFrame\u7684 duplicated \u65b9\u6cd5\u8fd4\u56de\u7684\u662f\u4e00\u4e2a\u5e03\u5c14\u503cSeries\uff0c\u8fd9\u4e2aSeries\u53cd\u6620\u7684\u662f\u6bcf\u4e00\u884c\u662f\u5426\u5b58\u5728\u91cd\u590d\uff08\u4e0e\u4e4b\u524d\u51fa\u73b0\u8fc7\u7684\u884c\u76f8\u540c\uff09\u60c5\u51b5\uff0c\u9ed8\u8ba4\u662f\u5bf9\u5217\u8fdb\u884c\u64cd\u4f5c\u3002 print(data.duplicated()) # 0 False # 1 False # 2 False # 3 False # 4 False # 5 False # 6 True # dtype: bool drop_duplicates \u8fd4\u56de\u7684\u662fDataFrame\uff0c\u5185\u5bb9\u662f duplicated \u8fd4\u56de\u6570\u7ec4\u4e2d\u4e3a False \u7684\u90e8\u5206\u3002\u9ed8\u8ba4\u662f\u5bf9\u5217\u8fdb\u884c\u64cd\u4f5c\u3002 print(data.drop_duplicates()) # k1 k2 # 0 one 1 # 1 two 1 # 2 one 2 # 3 two 3 # 4 one 4 # 5 two 4 \u53ef\u4ee5\u6307\u5b9a\u6570\u636e\u7684\u4efb\u4f55\u5b50\u96c6\u6765\u68c0\u6d4b\u662f\u5426\u6709\u91cd\u590d\u3002\u5047\u8bbe\u6211\u4eec\u6709\u4e00\u4e2a\u989d\u5916\u7684\u5217\uff0c\u5e76\u60f3\u57fa\u4e8e\u2019k1\u2019\u5217\u53bb\u9664\u91cd\u590d\u503c\u3002 data['v1'] = range(7) print(data) # k1 k2 v1 # 0 one 1 0 # 1 two 1 1 # 2 one 2 2 # 3 two 3 3 # 4 one 4 4 # 5 two 4 5 # 6 two 4 6 print(data.drop_duplicates(['k1'])) # \u4fdd\u7559\u7b2c\u4e00\u4e2a\u89c2\u6d4b\u5230\u7684one\u548ctwo\uff0c\u5176\u4f59\u4e22\u5f03 # k1 k2 v1 # 0 one 1 0 # 1 two 1 1 duplicated \u548c drop_duplicates \u9ed8\u8ba4\u90fd\u662f\u4fdd\u7559\u7b2c\u4e00\u4e2a\u89c2\u6d4b\u5230\u7684\u503c\u3002\u4f20\u5165\u53c2\u6570keep='last\u2019\u5c06\u4f1a\u8fd4\u56de\u6700\u540e\u4e00\u4e2a\u3002 print(data.drop_duplicates(['k1'], keep='last')) # \u4fdd\u7559\u6700\u540e\u4e00\u4e2a\u89c2\u6d4b\u5230\u7684one\u548ctwo # k1 k2 v1 # 4 one 4 4 # 6 two 4 6","title":"\u5220\u9664\u91cd\u590d\u503c"},{"location":"python/DataAnalysis/ch04/#_7","text":"\u4f7f\u7528 map \u662f\u4e00\u79cd\u53ef\u4ee5\u4fbf\u6377\u6267\u884c\u6309\u5143\u7d20\u8f6c\u6362\u53ca\u5176\u4ed6\u6e05\u6d17\u76f8\u5173\u64cd\u4f5c\u7684\u65b9\u6cd5\u3002 data = pd.DataFrame( { 'food': ['bacon', 'pulled pork', 'bacon', 'Pastrami', 'corned beef', 'Bacon', 'pastrami', 'honey ham', 'nova lox'], 'ounces': [4, 3, 12, 6, 7.5, 8, 3, 5, 6] } ) print(data) # food ounces # 0 bacon 4.0 # 1 pulled pork 3.0 # 2 bacon 12.0 # 3 Pastrami 6.0 # 4 corned beef 7.5 # 5 Bacon 8.0 # 6 pastrami 3.0 # 7 honey ham 5.0 # 8 nova lox 6.0 \u6dfb\u52a0\u4e00\u5217\u7528\u4e8e\u8868\u660e\u6bcf\u79cd\u98df\u7269\u7684\u52a8\u7269\u8089\u7c7b\u578b\u3002 \u5148\u521b\u5efa\u4e00\u4e2a\u98df\u7269\u548c\u8089\u7c7b\u7684\u6620\u5c04\u3002 meat_to_animal = { 'bacon': 'pig', 'pulled pork': 'pig', 'pastrami': 'cow', 'corned beef': 'cow', 'honey ham': 'pig', 'nova lox': 'salmon' } lowercased = data['food'].str.lower() # \u4f7f\u7528Series\u7684str.lower\u65b9\u6cd5\u5c06food\u7684\u6bcf\u4e2a\u503c\u90fd\u8f6c\u6362\u4e3a\u5c0f\u5199 print(lowercased) # 0 bacon # 1 pulled pork # 2 bacon # 3 pastrami # 4 corned beef # 5 bacon # 6 pastrami # 7 honey ham # 8 nova lox # Name: food, dtype: object data['animal'] = lowercased.map(meat_to_animal) print(data) # food ounces animal # 0 bacon 4.0 pig # 1 pulled pork 3.0 pig # 2 bacon 12.0 pig # 3 Pastrami 6.0 cow # 4 corned beef 7.5 cow # 5 Bacon 8.0 pig # 6 pastrami 3.0 cow # 7 honey ham 5.0 pig # 8 nova lox 6.0 salmon \u4e5f\u53ef\u4ee5\u4f20\u5165\u4e00\u4e2a\u51fd\u6570\uff0c\u5b8c\u6210\u4e0a\u9762\u6240\u6709\u529f\u80fd\u3002 data = pd.DataFrame( { 'food': ['bacon', 'pulled pork', 'bacon', 'Pastrami', 'corned beef', 'Bacon', 'pastrami', 'honey ham', 'nova lox'], 'ounces': [4, 3, 12, 6, 7.5, 8, 3, 5, 6] } ) result = data['food'].map(lambda x: meat_to_animal[x.lower()]) print(result) # 0 pig # 1 pig # 2 pig # 3 cow # 4 cow # 5 pig # 6 cow # 7 pig # 8 salmon # Name: food, dtype: object","title":"\u4f7f\u7528\u51fd\u6570\u6216\u6620\u5c04\u8fdb\u884c\u6570\u636e\u8f6c\u6362"},{"location":"python/DataAnalysis/ch04/#_8","text":"\u4f7f\u7528 fillna \u586b\u5145\u7f3a\u5931\u503c\u662f\u901a\u7528\u503c\u66ff\u6362\u7684\u7279\u6b8a\u6848\u4f8b\u3002 map \u53ef\u4ee5\u7528\u6765\u4fee\u6539\u4e00\u4e2a\u5bf9\u8c61\u4e2d\u7684\u5b50\u96c6\u7684\u503c\uff0c\u4f46\u662f replace \u63d0\u4f9b\u4e86\u66f4\u4e3a\u7b80\u5355\u7075\u6d3b\u7684\u5b9e\u73b0\u3002 data.replace \u65b9\u6cd5\u4e0e data.str.replace \u65b9\u6cd5\u662f\u4e0d\u540c\u7684\uff0c data.str.replace \u662f\u5bf9\u5b57\u7b26\u4e32\u8fdb\u884c\u6309\u5143\u7d20\u66ff\u4ee3\u7684\u3002 \u4e0b\u9762\u7684Series\uff0c -999 \u53ef\u80fd\u662f\u7f3a\u5931\u503c\u7684\u6807\u8bc6\u3002\u5982\u679c\u8981\u4f7f\u7528 NA \u6765\u66ff\u4ee3\u8fd9\u4e9b\u503c\uff0c\u53ef\u4ee5\u4f7f\u7528 replace \u65b9\u6cd5\u751f\u6210\u65b0\u7684Series\uff08\u9664\u975e\u4f20\u5165\u4e86 inplace=True \uff09 data = pd.Series([1., -999., 2., -999., -1000., 3.]) print(data) # 0 1.0 # 1 -999.0 # 2 2.0 # 3 -999.0 # 4 -1000.0 # 5 3.0 # dtype: float64 result = data.replace(-999, np.nan) print(result) # 0 1.0 # 1 NaN # 2 2.0 # 3 NaN # 4 -1000.0 # 5 3.0 # dtype: float64 \u8981\u5c06\u4e0d\u540c\u7684\u503c\u66ff\u6362\u4e3a\u4e0d\u540c\u7684\u503c\uff0c\u53ef\u4ee5\u4f20\u5165\u66ff\u4ee3\u503c\u7684\u5217\u8868 result = data.replace([-999, -1000], [np.nan, 0]) print(result) # 0 1.0 # 1 NaN # 2 2.0 # 3 NaN # 4 0.0 # 5 3.0 # dtype: float64 \u4e5f\u53ef\u4ee5\u4f20\u5165\u66ff\u4ee3\u503c\u7684\u5b57\u5178 result = data.replace({-999: np.nan, -1000: 0}) print(result) # 0 1.0 # 1 NaN # 2 2.0 # 3 NaN # 4 0.0 # 5 3.0 # dtype: float64","title":"\u66ff\u4ee3\u503c"},{"location":"python/DataAnalysis/ch04/#_9","text":"\u548cSeries\u4e2d\u503c\u66ff\u6362\u7c7b\u4f3c\uff0c\u53ef\u4ee5\u901a\u8fc7\u51fd\u6570\u6216\u6620\u5c04\u5bf9\u8f74\u6807\u7b7e\u8fdb\u884c\u7c7b\u4f3c\u7684\u8f6c\u6362\uff0c\u751f\u6210\u65b0\u7684\u4e14\u5e26\u6709\u4e0d\u540c\u6807\u7b7e\u7684\u5bf9\u8c61\u3002 data = pd.DataFrame( np.arange(12).reshape((3, 4)), index=['Ohio', 'Colorado', 'New York'], columns=['one', 'two', 'three', 'four'] ) print(data) # one two three four # Ohio 0 1 2 3 # Colorado 4 5 6 7 # New York 8 9 10 11 \u4e0eSeries\u7c7b\u4f3c\uff0c\u8f74\u7d22\u5f15\u4e5f\u6709\u4e00\u4e2a map \u65b9\u6cd5\u3002 transform = lambda x: x[:4].upper() # \u622a\u53d6index\u7684\u524d\u56db\u4f4d\u5e76\u8f6c\u5316\u4e3a\u5927\u5199\u683c\u5f0f result = data.index.map(transform) print(result) # Index(['OHIO', 'COLO', 'NEW '], dtype='object') \u8d4b\u503c\u7ed9 index \uff0c\u4fee\u6539DataFrame\u3002 data.index = data.index.map(transform) print(data) # one two three four # OHIO 0 1 2 3 # COLO 4 5 6 7 # NEW 8 9 10 11 \u521b\u5efa\u6570\u636e\u96c6\u8f6c\u6362\u540e\u7684\u7248\u672c\uff0c\u5e76\u4e14\u4e0d\u4fee\u6539\u539f\u6709\u7684\u6570\u636e\u96c6\uff0c\u4e00\u4e2a\u6709\u7528\u7684\u65b9\u6cd5\u662f rename \u3002 result = data.rename(index=str.title, columns=str.upper) print(result) # ONE TWO THREE FOUR # Ohio 0 1 2 3 # Colo 4 5 6 7 # New 8 9 10 11 print(data) # \u539f\u6709\u7684\u6570\u636e\u96c6\u672a\u88ab\u4fee\u6539 # one two three four # OHIO 0 1 2 3 # COLO 4 5 6 7 # NEW 8 9 10 11 rename \u53ef\u4ee5\u7ed3\u5408\u5b57\u5178\u578b\u5bf9\u8c61\u4f7f\u7528\uff0c\u4e3a\u8f74\u6807\u7b7e\u7684\u5b50\u96c6\u63d0\u4f9b\u65b0\u7684\u503c\u3002 result = data.rename(index={'OHIO': 'INDIANA'}, columns={'three': 'peekaboo'}) print(result) # one two peekaboo four # INDIANA 0 1 2 3 # COLO 4 5 6 7 # NEW 8 9 10 11 \u5982\u679c\u8981\u4fee\u6539\u539f\u6709\u7684\u6570\u636e\u96c6\uff0c\u4f20\u5165 inplace=True \u3002 data.rename(index={'OHIO': 'INDIANA'}, columns={'three': 'peekaboo'}, inplace=True) print(data) # one two peekaboo four # INDIANA 0 1 2 3 # COLO 4 5 6 7 # NEW 8 9 10 11","title":"\u91cd\u547d\u540d\u8f74\u7d22\u5f15"},{"location":"python/DataAnalysis/ch04/#_10","text":"\u8fde\u7eed\u503c\u7ecf\u5e38\u9700\u8981\u79bb\u6563\u5316\uff0c\u6216\u8005\u5206\u79bb\u6210\u201d\u7bb1\u5b50\u201c\u8fdb\u884c\u5206\u6790\u3002 \u5047\u8bbe\u6709\u4e00\u7ec4\u4eba\u7fa4\u7684\u6570\u636e\uff0c\u60f3\u5c06\u4ed6\u4eec\u8fdb\u884c\u5206\u7ec4\uff0c\u653e\u5165\u79bb\u6563\u7684\u5e74\u9f84\u6846\u4e2d\u3002 ages = [20, 22, 25, 27, 21, 23, 37, 31, 61, 45, 41, 32] \u5c06\u8fd9\u4e9b\u5e74\u9f84\u5206\u4e3a18\uff5e25\u300126\uff5e35\u300136\uff5e60\u4ee5\u53ca61\u53ca\u4ee5\u4e0a\u7b49\u82e5\u5e72\u7ec4\uff0c\u4f7f\u7528pandas\u4e2d\u7684 cut \u3002 bins = [18, 25, 35, 60, 100] cats = pd.cut(ages, bins) print(cats) # [(18, 25], (18, 25], (18, 25], (25, 35], (18, 25], ..., (25, 35], (60, 100], (35, 60], (35, 60], (25, 35]] # Length: 12 # Categories (4, interval[int64, right]): [(18, 25] < (25, 35] < (35, 60] < (60, 100]] pandas\u8fd4\u56de\u7684\u5bf9\u8c61\u662f\u4e00\u4e2a\u7279\u6b8a\u7684 Categorical \u5bf9\u8c61\u3002 \u4f60\u770b\u5230\u7684\u8f93\u51fa\u63cf\u8ff0\u4e86\u7531 pandas.cut \u8ba1\u7b97\u51fa\u7684\u7bb1\u3002 \u4f60\u53ef\u4ee5\u5c06\u5b83\u5f53\u4f5c\u4e00\u4e2a\u8868\u793a\u7bb1\u540d\u7684\u5b57\u7b26\u4e32\u6570\u7ec4\uff1b\u5b83\u5728\u5185\u90e8\u5305\u542b\u4e00\u4e2a categories \uff08\u7c7b\u522b\uff09\u6570\u7ec4\uff0c\u5b83\u6307\u5b9a\u4e86\u4e0d\u540c\u7684\u7c7b\u522b\u540d\u79f0\u4ee5\u53ca codes \u5c5e\u6027\u4e2d\u7684 ages \uff08\u5e74\u9f84\uff09\u6570\u636e\u6807\u7b7e\u3002 print(cats.categories) # \u56db\u4e2a\u533a\u95f4\u7ec4 # IntervalIndex([(18, 25], (25, 35], (35, 60], (60, 100]], dtype='interval[int64, right]') print(cats.codes) # 61\u5c81\u843d\u5728\u7b2c3\u7ec4\uff08\u7ec4\u7f16\u53f7\u4ece0\u5f00\u59cb\uff09 # [0 0 0 1 0 0 2 1 3 2 2 1] \u6ce8\u610f\uff0c pd.value_counts(cats) \u662f\u5bf9 pandas.cut \u7684\u7ed3\u679c\u4e2d\u7684\u7bb1\u6570\u91cf\u7684\u8ba1\u6570\u3002 result = pd.value_counts(cats) print(result) # (18, 25] 5 # (25, 35] 3 # (35, 60] 3 # (60, 100] 1 # dtype: int64 \u4e0e\u533a\u95f4\u7684\u6570\u5b66\u7b26\u53f7\u4e00\u81f4\uff0c\u5c0f\u62ec\u53f7\u8868\u793a\u8fb9\u662f\u5f00\u653e\u7684\uff0c\u4e2d\u62ec\u53f7\u8868\u793a\u5b83\u662f\u5c01\u95ed\u7684\uff08\u5305\u62ec\u8fb9\uff09\u3002\u53ef\u4ee5\u901a\u8fc7\u4f20\u9012 right=False \u6765\u6539\u53d8\u54ea\u4e00\u8fb9\u662f\u5c01\u95ed\u7684\u3002\u9ed8\u8ba4 right=True \u3002 result = pd.cut(ages, [18, 26, 36, 61, 100], right=False) print(result) # [[18, 26), [18, 26), [18, 26), [26, 36), [18, 26), ..., [26, 36), [61, 100), [36, 61), [36, 61), [26, 36)] # Length: 12 # Categories (4, interval[int64, left]): [[18, 26) < [26, 36) < [36, 61) < [61, 100)] \u901a\u8fc7\u5411 labels \u9009\u9879\u4f20\u9012\u4e00\u4e2a\u5217\u8868\u6216\u6570\u7ec4\u6765\u4f20\u5165\u81ea\u5b9a\u4e49\u7684\u7bb1\u540d\u3002 group_name = ['Youth', 'YoungAdult', 'MiddleAged', 'Senior'] result = pd.cut(ages, bins, labels=group_name) print(result) # ['Youth', 'Youth', 'Youth', 'YoungAdult', 'Youth', ..., 'YoungAdult', 'Senior', 'MiddleAged', 'MiddleAged', 'YoungAdult'] # Length: 12 # Categories (4, object): ['Youth' < 'YoungAdult' < 'MiddleAged' < 'Senior'] result = pd.value_counts(pd.cut(ages, bins, labels=group_name)) # \u6807\u7b7e\u8f93\u51fa print(result) # Youth 5 # YoungAdult 3 # MiddleAged 3 # Senior 1 # dtype: int64 result = pd.value_counts(pd.cut(ages, bins)) # \u533a\u95f4\u8f93\u51fa print(result) # (18, 25] 5 # (25, 35] 3 # (35, 60] 3 # (60, 100] 1 # dtype: int64 \u5982\u679c\u4f20\u7ed9 cut \u6574\u6570\u4e2a\u7684\u7bb1\u6765\u4ee3\u66ff\u663e\u5f0f\u7684\u7bb1\u8fb9\uff0cpandas\u5c06\u6839\u636e\u6570\u636e\u4e2d\u7684\u6700\u5c0f\u503c\u548c\u6700\u5927\u503c\u8ba1\u7b97\u51fa\u7b49\u957f\u7684\u7bb1\u3002 \u4e0b\u9762\u7684\u4f8b\u5b50\u662f\u8003\u8651\u4e00\u4e9b\u5747\u5300\u5206\u5e03\u7684\u6570\u636e\u88ab\u5207\u6210\u56db\u4efd\u7684\u60c5\u51b5\u3002 data = np.random.rand(20) result = pd.cut(data, 4, precision=2) # precision=2\u7684\u9009\u9879\u5c06\u5341\u8fdb\u5236\u7cbe\u5ea6\u9650\u5236\u5728\u4e24\u4f4d\u3002 print(result) # [(0.44, 0.66], (0.0063, 0.23], (0.23, 0.44], (0.0063, 0.23], (0.23, 0.44], ..., (0.23, 0.44], (0.0063, 0.23], (0.23, 0.44], (0.66, 0.88], (0.23, 0.44]] # Length: 20 # Categories (4, interval[float64, right]): [(0.0063, 0.23] < (0.23, 0.44] < (0.44, 0.66] < (0.66, 0.88]] qcut \u662f\u4e00\u4e2a\u4e0e\u5206\u7bb1\u5bc6\u5207\u76f8\u5173\u7684\u51fd\u6570\uff0c\u5b83\u57fa\u4e8e\u6837\u672c\u5206\u4f4d\u6570\u8fdb\u884c\u5206\u7bb1\u3002 \u53d6\u51b3\u4e8e\u6570\u636e\u7684\u5206\u5e03\uff0c\u4f7f\u7528 cut \u901a\u5e38\u4e0d\u4f1a\u4f7f\u6bcf\u4e2a\u7bb1\u5177\u6709\u76f8\u540c\u6570\u636e\u91cf\u7684\u6570\u636e\u70b9\u3002 \u7531\u4e8eqcut\u4f7f\u7528\u6837\u672c\u7684\u5206\u4f4d\u6570\uff0c\u4f60\u53ef\u4ee5\u901a\u8fc7qcut\u83b7\u5f97\u7b49\u957f\u7684\u7bb1\u3002 data = np.random.randn(1000) # \u6b63\u6001\u5206\u5e03 cats = pd.qcut(data, 4) # \u5207\u62104\u4efd print(cats) # [(-0.00329, 0.644], (-0.00329, 0.644], (-0.659, -0.00329], (-0.659, -0.00329], (0.644, 3.468], ..., (0.644, 3.468], (-3.9619999999999997, -0.659], (-3.9619999999999997, -0.659], (-0.00329, 0.644], (-0.00329, 0.644]] # Length: 1000 # Categories (4, interval[float64, right]): [(-3.9619999999999997, -0.659] < (-0.659, -0.00329] < (-0.00329, 0.644] < (0.644, 3.468]] result = pd.value_counts(cats) print(result) # (-3.9619999999999997, -0.659] 250 # (-0.659, -0.00329] 250 # (-0.00329, 0.644] 250 # (0.644, 3.468] 250 # dtype: int64 \u4e0e cut \u7c7b\u4f3c\uff0c\u53ef\u4ee5\u4f20\u5165\u81ea\u5b9a\u4e49\u7684\u5206\u4f4d\u6570\uff080\u548c1\u4e4b\u95f4\u7684\u6570\u636e\uff0c\u5305\u62ec\u8fb9\uff09\u3002 result = pd.qcut(data, [0, 0.1, 0.5, 0.9, 1.]) print(result) # [(-0.00329, 1.234], (-0.00329, 1.234], (-1.321, -0.00329], (-1.321, -0.00329], (-0.00329, 1.234], ..., (-0.00329, 1.234], (-1.321, -0.00329], (-1.321, -0.00329], (-0.00329, 1.234], (-0.00329, 1.234]] # Length: 1000 # Categories (4, interval[float64, right]): [(-3.9619999999999997, -1.321] < (-1.321, -0.00329] < (-0.00329, 1.234] < (1.234, 3.468]]","title":"\u79bb\u6563\u5316\u548c\u5206\u7bb1"},{"location":"python/DataAnalysis/ch04/#_11","text":"\u8fc7\u6ee4\u6216\u8f6c\u6362\u5f02\u5e38\u503c\u5728\u5f88\u5927\u7a0b\u5ea6\u4e0a\u662f\u5e94\u7528\u6570\u7ec4\u64cd\u4f5c\u7684\u4e8b\u60c5\u3002 \u8003\u8651\u4e00\u4e2a\u5177\u6709\u6b63\u6001\u5206\u5e03\u6570\u636e\u7684DataFrame\u3002 data = pd.DataFrame(np.random.randn(1000, 4)) print(data.describe()) # 0 1 2 3 # count 1000.000000 1000.000000 1000.000000 1000.000000 # mean 0.008124 -0.008050 -0.013403 -0.008261 # std 0.979236 0.992982 0.998819 1.038760 # min -3.231914 -3.441270 -3.345210 -4.320565 # 25% -0.634801 -0.599852 -0.656481 -0.677611 # 50% -0.033252 0.000060 -0.040634 -0.015463 # 75% 0.649340 0.644312 0.678101 0.683849 # max 3.292099 2.758754 2.911447 3.371729 \u627e\u51fa\u4e00\u5217\u4e2d\u7edd\u5bf9\u503c\u5927\u4e8e\u4e09\u7684\u503c\u3002 col = data[2] result = col[np.abs(col) > 3] print(result) # 519 -3.035355 # 536 -3.345210 # Name: 2, dtype: float64 \u9009\u51fa\u6240\u6709\u503c\u5927\u4e8e3\u6216\u5c0f\u4e8e-3\u7684\u884c\uff0c\u53ef\u4ee5\u5bf9\u5e03\u5c14\u503cDataFrame\u4f7f\u7528 any \u65b9\u6cd5\u3002 result = data[(np.abs(data) > 3).any(1)] print(result) # 0 1 2 3 # 116 -0.080907 -3.441270 -0.163263 0.392800 # 139 -1.294440 1.828397 1.178897 -3.469466 # 241 -0.486292 0.150443 0.264172 -3.013440 # 295 3.292099 -0.339284 0.732829 -0.475202 # 355 0.307577 -3.053322 0.967497 0.896363 # 359 3.264981 -1.172096 0.207622 -0.281803 # 519 -0.448987 1.623843 -3.035355 -0.436833 # 533 -1.022616 -0.212597 1.030969 3.371729 # 536 1.067598 -1.306839 -3.345210 0.620834 # 541 -0.952760 -2.157970 -0.403199 -4.320565 # 690 0.006821 -3.104117 0.484881 -0.132613 # 750 -3.231914 1.017712 0.070430 0.631447 # 771 -3.007622 0.257960 -0.118179 -1.283365 # 976 1.684760 -0.003295 -0.249843 3.169371 \u6839\u636e\u8fd9\u4e9b\u6807\u51c6\u6765\u8bbe\u7f6e\u6765\u9650\u5b9a\u503c\uff0c\u4e0b\u9762\u4ee3\u7801\u9650\u5236\u4e86-3\u52303\u4e4b\u95f4\u7684\u6570\u503c\u3002 \u8bed\u53e5 np.sign(data) \u6839\u636e\u6570\u636e\u4e2d\u7684\u503c\u7684\u6b63\u8d1f\u5206\u522b\u751f\u62101\u548c-1\u7684\u6570\u503c\u3002 result = data[(np.abs(data) > 3)] = np.sign(data) * 3 print(result.describe()) # 0 1 2 3 # count 1000.000000 1000.000000 1000.000000 1000.000000 # mean -0.036000 0.000000 -0.084000 -0.048000 # std 3.001285 3.001501 3.000324 3.001117 # min -3.000000 -3.000000 -3.000000 -3.000000 # 25% -3.000000 -3.000000 -3.000000 -3.000000 # 50% -3.000000 0.000000 -3.000000 -3.000000 # 75% 3.000000 3.000000 3.000000 3.000000 # max 3.000000 3.000000 3.000000 3.000000 print(result.head()) # 0 1 2 3 # 0 -3.0 3.0 -3.0 -3.0 # 1 -3.0 -3.0 -3.0 -3.0 # 2 3.0 3.0 -3.0 3.0 # 3 3.0 -3.0 3.0 -3.0 # 4 3.0 -3.0 -3.0 -3.0","title":"\u68c0\u6d4b\u548c\u8fc7\u6ee4\u5f02\u5e38\u503c"},{"location":"python/DataAnalysis/ch04/#_12","text":"\u4f7f\u7528 numpy.random.permutation \u5bf9DataFrame\u4e2d\u7684Series\u6216\u884c\u8fdb\u884c\u7f6e\u6362\uff08\u968f\u673a\u91cd\u6392\u5e8f\uff09\u3002 \u5728\u8c03\u7528 permutation \u65f6\u6839\u636e\u4f60\u60f3\u8981\u7684\u8f74\u957f\u5ea6\u53ef\u4ee5\u4ea7\u751f\u4e00\u4e2a\u8868\u793a\u65b0\u987a\u5e8f\u7684\u6574\u6570\u6570\u7ec4\u3002 df = pd.DataFrame(np.arange(5 * 4).reshape((5, 4))) sampler = np.random.permutation(5) print(sampler) # \u8fd4\u56dearray # [1 4 3 0 2] print(df) # 0 1 2 3 # 0 0 1 2 3 # 1 4 5 6 7 # 2 8 9 10 11 # 3 12 13 14 15 # 4 16 17 18 19 \u4e0a\u9762\u8fd4\u56de\u7684 sampler \u6574\u6570\u6570\u7ec4 [1 4 3 0 2] \u7528\u5728\u57fa\u4e8e iloc \u7684\u7d22\u5f15\u6216\u7b49\u4ef7\u7684 take \u51fd\u6570\u4e2d\uff0c\u91cd\u65b0\u6392\u5217\u884c\u987a\u5e8f\u3002 print(df.take(sampler)) # 0 1 2 3 # 1 4 5 6 7 # 4 16 17 18 19 # 3 12 13 14 15 # 0 0 1 2 3 # 2 8 9 10 11 \u9009\u51fa\u4e00\u4e2a\u4e0d\u542b\u6709\u66ff\u4ee3\u503c\u7684\u968f\u673a\u5b50\u96c6\uff0c\u53ef\u4ee5\u4f7f\u7528Series\u548cDataFrame\u7684 sample \u65b9\u6cd5\u3002 result = df.sample(n=3) print(result) # 0 1 2 3 # 0 0 1 2 3 # 2 8 9 10 11 # 1 4 5 6 7 \u8981\u751f\u6210\u4e00\u4e2a\u5e26\u6709\u66ff\u4ee3\u503c\u7684\u6837\u672c\uff08\u5141\u8bb8\u6709\u91cd\u590d\u9009\u62e9\uff09\uff0c\u5c06 replace=True \u4f20\u5165 sample \u65b9\u6cd5\u3002 choice = pd.Series([5, 7, -1, 6, 4]) draws = choice.sample(n=10, replace=True) print(choice) # 0 5 # 1 7 # 2 -1 # 3 6 # 4 4 # dtype: int64 print(draws) # 4 4 # 0 5 # 0 5 # 3 6 # 4 4 # 0 5 # 1 7 # 3 6 # 2 -1 # 0 5 # dtype: int64","title":"\u7f6e\u6362\u548c\u968f\u673a\u62bd\u6837"},{"location":"python/DataAnalysis/ch04/#_13","text":"\u5c06\u5206\u7c7b\u53d8\u91cf\u8f6c\u6362\u4e3a\u201c\u865a\u62df\u201d\u6216\u201c\u6307\u6807\u201d\u77e9\u9635\u662f\u53e6\u4e00\u79cd\u7528\u4e8e\u7edf\u8ba1\u5efa\u6a21\u6216\u673a\u5668\u5b66\u4e60\u7684\u8f6c\u6362\u64cd\u4f5c\u3002 \u5982\u679cDataFrame\u4e2d\u7684\u4e00\u5217\u6709 k \u4e2a\u4e0d\u540c\u7684\u503c\uff0c\u5219\u53ef\u4ee5\u884d\u751f\u4e00\u4e2a k \u5217\u7684\u503c\u4e3a 1 \u548c 0 \u7684\u77e9\u9635\u6216DataFrame\u3002 pandas\u6709\u4e00\u4e2aget_dummies\u51fd\u6570\u7528\u4e8e\u5b9e\u73b0\u8be5\u529f\u80fd\u3002 df = pd.DataFrame( { 'key': ['b', 'b', 'a', 'c', 'a', 'b'], 'data1': range(6) } ) print(df) # key data1 # 0 b 0 # 1 b 1 # 2 a 2 # 3 c 3 # 4 a 4 # 5 b 5 \u5728\u6307\u6807DataFrame\u7684\u5217\u4e0a\u52a0\u5165\u524d\u7f00\uff0c\u7136\u540e\u4e0e\u5176\u4ed6\u6570\u636e\u5408\u5e76\u3002\u5728 get_dummies \u65b9\u6cd5\u4e2d\u6709\u4e00\u4e2a\u524d\u7f00\u53c2\u6570\u7528\u4e8e\u5b9e\u73b0\u8be5\u529f\u80fd\u3002 \u901a\u8fc7 get_dummies \u65b9\u6cd5\uff0c\u628a\u4e0a\u9762 df \u6570\u636e\u6309\u7167 key \u8fdb\u884c\u4e86\u5206\u7ec4\uff0c\u5e76\u901a\u8fc7\u4e0d\u540c\u5217\u6765\u5c55\u73b0\u5206\u7ec4\u540e\u7684\u5bf9\u5e94\u5173\u7cfb\u3002\u4f8b\u5982\uff0c key \u5217\u7684 a \uff0c\u5bf9\u5e94\u503c 2 \u548c 4 \u3002 dummies = pd.get_dummies(df['key'], prefix='key') print(dummies) # key_a key_b key_c # 0 0 1 0 # 1 0 1 0 # 2 1 0 0 # 3 0 0 1 # 4 1 0 0 # 5 0 1 0 df_with_dummy = df[['data1']].join(dummies) print(df_with_dummy) # data1 key_a key_b key_c # 0 0 0 1 0 # 1 1 0 1 0 # 2 2 1 0 0 # 3 3 0 0 1 # 4 4 1 0 0 # 5 5 0 1 0 \u66f4\u4e3a\u590d\u6742\u7684\u60c5\u51b5\uff0cDataFrame\u4e2d\u7684\u4e00\u884c\u5c5e\u4e8e\u591a\u4e2a\u7c7b\u522b\u3002 \u4ee5MovieLens\u76841M\u6570\u636e\u96c6\u4e3a\u4f8b\u3002\u589e\u52a0\u53c2\u6570 encoding='unicode_escape' \u907f\u514d\u51fa\u73b0\u4e0b\u9762\u7684\u9519\u8bef\uff1a UnicodeDecodeError: 'utf-8' codec can't decode byte 0xe9 in position 3114: invalid continuation byte \u589e\u52a0\u53c2\u6570 engine='python' \u907f\u514d\u51fa\u73b0\u4e0b\u9762\u7684\u9519\u8bef\uff1a ParserWarning: Falling back to the 'python' engine because the 'c' engine does not support regex separators (separators > 1 char and different from '\\s+' are interpreted as regex); you can avoid this warning by specifying engine='python'. mnames = ['movie_id', 'title', 'genres'] movies = pd.read_table( '../datasets/movielens/movies.dat', sep='::', header=None, names=mnames, encoding='unicode_escape', engine='python' ) print(movies[:10]) # movie_id title genres # 0 1 Toy Story (1995) Animation|Children's|Comedy # 1 2 Jumanji (1995) Adventure|Children's|Fantasy # 2 3 Grumpier Old Men (1995) Comedy|Romance # 3 4 Waiting to Exhale (1995) Comedy|Drama # 4 5 Father of the Bride Part II (1995) Comedy # 5 6 Heat (1995) Action|Crime|Thriller # 6 7 Sabrina (1995) Comedy|Romance # 7 8 Tom and Huck (1995) Adventure|Children's # 8 9 Sudden Death (1995) Action # 9 10 GoldenEye (1995) Action|Adventure|Thriller \u4e3a\u6bcf\u4e2a\u7535\u5f71\u6d41\u6d3e\u6dfb\u52a0\u6307\u6807\u53d8\u91cf\u9700\u8981\u8fdb\u884c\u4e00\u4e9b\u6570\u636e\u5904\u7406\u3002 \u9996\u5148\uff0c\u6211\u4eec\u4ece\u6570\u636e\u96c6\u4e2d\u63d0\u53d6\u51fa\u6240\u6709\u4e0d\u540c\u7684\u6d41\u6d3e\u7684\u5217\u8868\u3002 all_genres = [] for x in movies.genres: all_genres.extend(x.split('|')) genres = pd.unique(all_genres) print(genres) # ['Animation' \"Children's\" 'Comedy' 'Adventure' 'Fantasy' 'Romance' 'Drama' # 'Action' 'Crime' 'Thriller' 'Horror' 'Sci-Fi' 'Documentary' 'War' # 'Musical' 'Mystery' 'Film-Noir' 'Western'] \u4f7f\u7528\u51680\u7684DataFrame\u662f\u6784\u5efa\u6307\u6807DataFrame\u7684\u4e00\u79cd\u65b9\u5f0f\u3002 zero_matrix = np.zeros((len(movies), len(genres))) dummies = pd.DataFrame(zero_matrix, columns=genres) print(zero_matrix) # [[0. 0. 0. ... 0. 0. 0.] # [0. 0. 0. ... 0. 0. 0.] # [0. 0. 0. ... 0. 0. 0.] # ... # [0. 0. 0. ... 0. 0. 0.] # [0. 0. 0. ... 0. 0. 0.] # [0. 0. 0. ... 0. 0. 0.]] print(dummies.head(n=10)) # Animation Children's Comedy ... Mystery Film-Noir Western # 0 0.0 0.0 0.0 ... 0.0 0.0 0.0 # 1 0.0 0.0 0.0 ... 0.0 0.0 0.0 # 2 0.0 0.0 0.0 ... 0.0 0.0 0.0 # 3 0.0 0.0 0.0 ... 0.0 0.0 0.0 # 4 0.0 0.0 0.0 ... 0.0 0.0 0.0 # 5 0.0 0.0 0.0 ... 0.0 0.0 0.0 # 6 0.0 0.0 0.0 ... 0.0 0.0 0.0 # 7 0.0 0.0 0.0 ... 0.0 0.0 0.0 # 8 0.0 0.0 0.0 ... 0.0 0.0 0.0 # 9 0.0 0.0 0.0 ... 0.0 0.0 0.0 # # [10 rows x 18 columns] \u904d\u5386\u6bcf\u4e00\u90e8\u7535\u5f71\uff0c\u5c06 dummies \u6bcf\u4e00\u884c\u7684\u6761\u76ee\u8bbe\u7f6e\u4e3a 1 \u3002\u4f7f\u7528 dummies.columns \u6765\u8ba1\u7b97\u6bcf\u4e00\u4e2a\u6d41\u6d3e\u7684\u5217\u6307\u6807\u3002 gen = movies.genres[0] print(gen.split('|')) # ['Animation', \"Children's\", 'Comedy'] result = dummies.columns.get_indexer(gen.split('|')) print(result) # [0 1 2] \u4f7f\u7528 .loc \u6839\u636e\u8fd9\u4e9b\u6307\u6807\u6765\u8bbe\u7f6e\u503c\u3002 for i, gen in enumerate(movies.genres): indices = dummies.columns.get_indexer(gen.split('|')) dummies.iloc[i, indices] = 1 \u5c06\u7ed3\u679c\u4e0e movies \u8fdb\u884c\u5408\u5e76\u3002 movies_windic = movies.join(dummies.add_prefix('Genre_')) print(movies_windic.iloc[0]) # movie_id 1 # title Toy Story (1995) # genres Animation|Children's|Comedy # Genre_Animation 1.0 # Genre_Children's 1.0 # Genre_Comedy 1.0 # Genre_Adventure 0.0 # Genre_Fantasy 0.0 # Genre_Romance 0.0 # Genre_Drama 0.0 # Genre_Action 0.0 # Genre_Crime 0.0 # Genre_Thriller 0.0 # Genre_Horror 0.0 # Genre_Sci-Fi 0.0 # Genre_Documentary 0.0 # Genre_War 0.0 # Genre_Musical 0.0 # Genre_Mystery 0.0 # Genre_Film-Noir 0.0 # Genre_Western 0.0 # Name: 0, dtype: object \u5bf9\u4e8e\u66f4\u5927\u7684\u6570\u636e\uff0c\u4e0a\u9762\u8fd9\u79cd\u4f7f\u7528\u591a\u6210\u5458\u6784\u5efa\u6307\u6807\u53d8\u91cf\u5e76\u4e0d\u662f\u7279\u522b\u5feb\u901f\u3002 \u66f4\u597d\u7684\u65b9\u6cd5\u662f\u5199\u4e00\u4e2a\u76f4\u63a5\u5c06\u6570\u636e\u5199\u4e3aNumPy\u6570\u7ec4\u7684\u5e95\u5c42\u51fd\u6570\uff0c\u7136\u540e\u5c06\u7ed3\u679c\u5c01\u88c5\u8fdbDataFrame\u3002 \u5c06 get_dummies \u4e0e cut \u7b49\u79bb\u6563\u5316\u51fd\u6570\u7ed3\u5408\u4f7f\u7528\u662f\u7edf\u8ba1\u5e94\u7528\u7684\u4e00\u4e2a\u6709\u7528\u65b9\u6cd5\u3002 np.random.seed(12345) # \u4f7f\u7528numpy.random.seed\u6765\u8bbe\u7f6e\u968f\u673a\u79cd\u5b50\u4ee5\u786e\u4fdd\u793a\u4f8b\u7684\u786e\u5b9a\u6027 values = np.random.rand(10) print(values) # [0.92961609 0.31637555 0.18391881 0.20456028 0.56772503 0.5955447 # 0.96451452 0.6531771 0.74890664 0.65356987] bins = [0, 0.2, 0.4, 0.6, 0.8, 1] result = pd.get_dummies(pd.cut(values, bins)) print(result) # (0.0, 0.2] (0.2, 0.4] (0.4, 0.6] (0.6, 0.8] (0.8, 1.0] # 0 0 0 0 0 1 # 1 0 1 0 0 0 # 2 1 0 0 0 0 # 3 0 1 0 0 0 # 4 0 0 1 0 0 # 5 0 0 1 0 0 # 6 0 0 0 0 1 # 7 0 0 0 1 0 # 8 0 0 0 1 0 # 9 0 0 0 1 0","title":"\u8ba1\u7b97\u6307\u6807/\u865a\u62df\u53d8\u91cf"},{"location":"python/DataAnalysis/ch04/#_14","text":"import re pandas\u5141\u8bb8\u5c06\u5b57\u7b26\u4e32\u548c\u6b63\u5219\u8868\u8fbe\u5f0f\u7b80\u6d01\u5730\u5e94\u7528\u5230\u6574\u4e2a\u6570\u636e\u6570\u7ec4\u4e0a\uff0c\u6b64\u5916\u8fd8\u80fd\u5904\u7406\u6570\u636e\u7f3a\u5931\u3002","title":"\u5b57\u7b26\u4e32\u64cd\u4f5c"},{"location":"python/DataAnalysis/ch04/#_15","text":"\u5b57\u4e32\u62c6\u5206\u5408\u5e76\u65b9\u6cd5\u3002\u5728\u5f88\u591a\u5b57\u7b26\u4e32\u5904\u7406\u548c\u811a\u672c\u5e94\u7528\u4e2d\uff0c\u5185\u5efa\u7684\u5b57\u7b26\u4e32\u65b9\u6cd5\u662f\u8db3\u591f\u7684\u3002 \u4f8b\u5982\uff0c\u4e00\u4e2a\u9017\u53f7\u5206\u9694\u7684\u5b57\u7b26\u4e32\u53ef\u4ee5\u4f7f\u7528split\u65b9\u6cd5\u62c6\u5206\u6210\u591a\u5757\u3002 import numpy as np import pandas as pd val = 'a, b, guido' result = val.split(',') print(result) # ['a', ' b', ' guido'] count \uff1a\u8fd4\u56de\u5b50\u5b57\u7b26\u4e32\u5728\u5b57\u7b26\u4e32\u4e2d\u7684\u975e\u91cd\u53e0\u51fa\u73b0\u6b21\u6570\u3002 result = val.count(',') print(result) # 2 endswith \uff1a\u5982\u679c\u5b57\u7b26\u4e32\u4ee5\u540e\u7f00\u7ed3\u5c3e\u5219\u8fd4\u56de True \u3002 startswith \uff1a\u5982\u679c\u5b57\u7b26\u4e32\u4ee5\u540e\u7f00\u7ed3\u5c3e\u5219\u8fd4\u56de True \u3002 result = val.endswith('b') print(result) # False result = val.endswith('o') print(result) # True result = val.startswith('a') print(result) # True split \u5e38\u548c strip \u4e00\u8d77\u4f7f\u7528\uff0c\u7528\u4e8e\u6e05\u9664\u7a7a\u683c\uff08\u5305\u62ec\u6362\u884c\uff09\u3002 split \uff1a\u4f7f\u7528\u5206\u9694\u7b26\u8bb2\u5b57\u7b26\u4e32\u62c6\u5206\u6210\u5b50\u5b57\u7b26\u4e32\u7684\u5217\u8868\u3002 strip \uff0c rstrip \uff0c lstrip \uff1a\u4fee\u526a\u7a7a\u767d\uff0c\u5305\u62ec\u6362\u884c\u7b26\uff1b\u76f8\u5f53\u4e8e\u5bf9\u6bcf\u4e2a\u5143\u7d20\u8fdb\u884c x.strip() (\u4ee5\u53ca rstrip \uff0c lstrip )\u3002 pieces = [x.strip() for x in val.split(',')] print(pieces) # ['a', 'b', 'guido'] \u8fd9\u4e9b\u5b50\u5b57\u7b26\u4e32\u53ef\u4ee5\u4f7f\u7528\u52a0\u6cd5\u4e0e\u4e24\u4e2a\u5192\u53f7\u5206\u9694\u7b26\u8fde\u63a5\u5728\u4e00\u8d77\u3002 first, second, third = pieces result = first + '::' + second + '::' + third print(result) # a::b::guido \u4f46\u662f\u8fd9\u5e76\u4e0d\u662f\u4e00\u4e2a\u5b9e\u7528\u7684\u901a\u7528\u65b9\u6cd5\u3002 \u5728\u5b57\u7b26\u4e32 ': :' \u7684 join \u65b9\u6cd5\u4e2d\u4f20\u5165\u4e00\u4e2a\u5217\u8868\u6216\u5143\u7ec4\u662f\u4e00\u79cd\u66f4\u5feb\u4e14\u66f4\u52a0Pythonic\uff08Python\u98ce\u683c\u5316\uff09\u7684\u65b9\u6cd5\u3002 join : \u4f7f\u7528\u5b57\u7b26\u4e32\u5ea7\u4f4d\u95f4\u9694\u7b26\uff0c\u7528\u4e8e\u7c98\u5408\u5176\u4ed6\u5b57\u7b26\u4e32\u7684\u5e8f\u5217\u3002 result = '::'.join(pieces) print(result) # a::b::guido \u5b9a\u4f4d\u5b50\u5b57\u7b26\u4e32\u7684\u65b9\u6cd5\u3002 \u4f7f\u7528Python\u7684 in \u5173\u952e\u5b57\u662f\u68c0\u6d4b\u5b50\u5b57\u7b26\u4e32\u7684\u6700\u4f73\u65b9\u6cd5\uff0c\u5c3d\u7ba1 index \u548c find \u4e5f\u80fd\u5b9e\u73b0\u540c\u6837\u7684\u529f\u80fd\u3002 result = 'guido' in val print(result) # True index \uff1a\u5982\u679c\u5728\u5b57\u7b26\u4e32\u4e2d\u627e\u5230\uff0c\u5219\u8fd4\u56de\u5b50\u5b57\u7b26\u4e32\u4e2d\u7b2c\u4e00\u4e2a\u5b57\u7b26\u7684\u4f4d\u7f6e\uff0c\u5982\u679c\u627e\u4e0d\u5230\u5219\u89e6\u53d1\u4e00\u4e2a ValueError \u3002 find \uff1a\u8fd4\u56de\u5b57\u7b26\u4e32\u4e2d\u7b2c\u4e00\u4e2a\u51fa\u73b0\u5b50\u5b57\u7b26\u7684\u7b2c\u4e00\u4e2a\u5b57\u7b26\u7684\u4f4d\u7f6e\uff0c\u7c7b\u4f3c index \uff0c\u5982\u679c\u6ca1\u6709\u627e\u5230\uff0c\u5219\u8fd4\u56de -1 \u3002 rfind \uff1a\u8fd4\u56de\u5b57\u7b26\u4e32\u4e2d\u5b50\u5b57\u7b26\u6700\u540e\u4e00\u6b21\u51fa\u73b0\u65f6\u7b2c\u4e00\u4e2a\u5b57\u7b26\u7684\u4f4d\u7f6e\uff0c\u5982\u679c\u6ca1\u6709\u627e\u5230\uff0c\u5219\u8fd4\u56de -1 \u3002 result = val.index(',') print(result) # 1 result = val.find(',') print(result) # 1 # result = val.index(':') print(result) # ValueError: substring not found result = val.find(':') print(result) # -1 result = val.rfind(',') print(result) # 4 replace \u5c06\u7528\u4e00\u79cd\u6a21\u5f0f\u66ff\u4ee3\u53e6\u4e00\u79cd\u6a21\u5f0f\u3002\u5b83\u4e5f\u7528\u4e8e\u4f20\u5165\u7a7a\u5b57\u7b26\u4e32\u6765\u5220\u9664\u67d0\u4e2a\u6a21\u5f0f\u3002 result = val.replace(',', '::') print(result) # a:: b:: guido result = val.replace(', ', '') print(result) # abguido result = val.replace(',', '') print(result) # a b guido lower \uff1a\u5c06\u5927\u5199\u5b57\u6bcd\u8f6c\u6362\u4e3a\u5c0f\u5199\u5b57\u6bcd\u3002 upper \uff1a\u5c06\u5c0f\u5199\u5b57\u6bcd\u8f6c\u6362\u4e3a\u5927\u5199\u5b57\u6bcd\u3002 uppers = val.upper() print(uppers) # A, B, GUIDO casefold \uff1a\u548c lower \u7c7b\u4f3c\uff0c\u5c06\u5b57\u7b26\u4e32\u4e2d\u7684\u5143\u7d20\u53d8\u6210\u5c0f\u5199\uff0c lower \u51fd\u6570\u53ea\u652f\u6301 ascill \u8868\u4e2d\u7684\u5b57\u7b26\uff0c casefold \u652f\u6301\u5f88\u591a\u4e0d\u540c\u79cd\u7c7b\u7684\u8bed\u8a00\u3002 str1 = \"Jan Wei\u03b2@cN\u4e0a\u6d77\" result = str1.casefold() print(result) # jan wei\u03b2@cn\u4e0a\u6d77 result = str1.lower() print(result) # jan wei\u03b2@cn\u4e0a\u6d77 ljust \uff0c rjust \uff1a\u5de6\u5bf9\u9f50\u6216\u8005\u53f3\u5bf9\u9f50\uff1b\u7528\u7a7a\u683c\u6216\u8005\u5176\u5b83\u4e00\u4e9b\u5b57\u7b26\u586b\u5145\u5b57\u7b26\u4e32\u7684\u76f8\u53cd\u4fa7\uff0c\u4ee5\u8fd4\u56de\u5177\u6709\u6700\u5c0f\u5bbd\u5ea6\u7684\u5b57\u7b26\u4e32 str1 = 'https://docs.python.org/3/' str2 = 'https://packagehub.suse.com/package-categories/python/' print(str1.ljust(60, '*')) print(str2.ljust(60, '*')) # https://docs.python.org/3/********************************** # https://packagehub.suse.com/package-categories/python/****** print(str1.rjust(60, '*')) print(str2.rjust(60, '*')) # **********************************https://docs.python.org/3/ # ******https://packagehub.suse.com/package-categories/python/ print(str1.rjust(60)) print(str2.rjust(60))","title":"\u5b57\u7b26\u4e32\u5bf9\u8c61\u65b9\u6cd5"},{"location":"python/DataAnalysis/ch04/#_16","text":"Python\u5185\u5efa\u7684 re \u6a21\u5757\u662f\u7528\u4e8e\u5c06\u6b63\u5219\u8868\u8fbe\u5f0f\u5e94\u7528\u5230\u5b57\u7b26\u4e32\u4e0a\u7684\u5e93\u3002 re \u6a21\u5757\u4e3b\u8981\u6709\u4e09\u4e2a\u4e3b\u9898\uff1a\u6a21\u5f0f\u5339\u914d\u3001\u66ff\u4ee3\u3001\u62c6\u5206\u3002 \u770b\u4e00\u4e2a\u7b80\u5355\u7684\u793a\u4f8b\uff1a\u5047\u8bbe\u6211\u4eec\u60f3\u5c06\u542b\u6709\u591a\u79cd\u7a7a\u767d\u5b57\u7b26\uff08\u5236\u8868\u7b26\u3001\u7a7a\u683c\u3001\u6362\u884c\u7b26\uff09\u7684\u5b57\u7b26\u4e32\u62c6\u5206\u5f00\u3002 \u63cf\u8ff0\u4e00\u4e2a\u6216\u591a\u4e2a\u7a7a\u767d\u5b57\u7b26\u7684\u6b63\u5219\u8868\u8fbe\u5f0f\u662f \\s+ \u3002 \u5f53\u8c03\u7528 re.split('\\s+', text) \uff0c\u6b63\u5219\u8868\u8fbe\u5f0f\u9996\u5148\u4f1a\u88ab\u7f16\u8bd1\uff0c\u7136\u540e\u6b63\u5219\u8868\u8fbe\u5f0f\u7684 split \u65b9\u6cd5\u5728\u4f20\u5165\u6587\u672c\u4e0a\u88ab\u8c03\u7528\u3002 text = \"foo bar\\t baz \\tqux\" result = re.split('\\s+', text) print(result) # ['foo', 'bar', 'baz', 'qux'] \u53ef\u4ee5\u4f7f\u7528 re.compile \u81ea\u884c\u7f16\u8bd1\uff0c\u5f62\u6210\u4e00\u4e2a\u53ef\u590d\u7528\u7684\u6b63\u5219\u8868\u8fbe\u5f0f\u5bf9\u8c61\u3002 regex = re.compile('\\s+') result = regex.split(text) print(result) # ['foo', 'bar', 'baz', 'qux'] \u5982\u679c\u60f3\u83b7\u5f97\u7684\u662f\u4e00\u4e2a\u6240\u6709\u5339\u914d\u6b63\u5219\u8868\u8fbe\u5f0f\u7684\u6a21\u5f0f\u7684\u5217\u8868\uff0c\u4f60\u53ef\u4ee5\u4f7f\u7528 findall \u65b9\u6cd5\u3002 result = regex.findall(text) print(result) # [' ', '\\t ', ' \\t'] \u4e3a\u4e86\u5728\u6b63\u5219\u8868\u8fbe\u5f0f\u4e2d\u907f\u514d\u8f6c\u4e49\u7b26 \\ \u7684\u5f71\u54cd\uff0c\u53ef\u4ee5\u4f7f\u7528\u539f\u751f\u5b57\u7b26\u4e32\u8bed\u6cd5\uff0c\u6bd4\u5982 r'C:\\x' \u6216\u8005\u7528\u7b49\u4ef7\u7684 'C:\\\\x'\\ \u3002 \u5982\u679c\u9700\u8981\u5c06\u76f8\u540c\u7684\u8868\u8fbe\u5f0f\u5e94\u7528\u5230\u591a\u4e2a\u5b57\u7b26\u4e32\u4e0a\uff0c\u63a8\u8350\u4f7f\u7528 re.compile \u521b\u5efa\u4e00\u4e2a\u6b63\u5219\u8868\u8fbe\u5f0f\u5bf9\u8c61\uff0c\u8fd9\u6837\u505a\u6709\u5229\u4e8e\u8282\u7ea6CPU\u5468\u671f\u3002 match \u548c search \u4e0e findall \u76f8\u5173\u6027\u5f88\u5927\u3002 findall \u8fd4\u56de\u7684\u662f\u5b57\u7b26\u4e32\u4e2d\u6240\u6709\u7684\u5339\u914d\u9879\uff0c\u800c search \u8fd4\u56de\u7684\u4ec5\u4ec5\u662f\u7b2c\u4e00\u4e2a\u5339\u914d\u9879\u3002 match \u66f4\u4e3a\u4e25\u683c\uff0c\u5b83\u53ea\u5728\u5b57\u7b26\u4e32\u7684\u8d77\u59cb\u4f4d\u7f6e\u8fdb\u884c\u5339\u914d\u3002 text = \"\"\"Dave dave@google.com Steve steve@gmail.com Rob rob@gmail.com Ryan ryan@yahoo.com \"\"\" pattern = r'[A-Z0-9._%+-]+@[A-Z0-9.-]+\\.[A-Z]{2,4}' regex = re.compile(pattern, flags=re.IGNORECASE) # flags=re.IGNORECASE \u4f7f\u6b63\u5219\u8868\u8fbe\u5f0f\u4e0d\u533a\u5206\u5927\u5c0f\u5199 m = regex.findall(text) # findall\u4f1a\u751f\u6210\u4e00\u4e2a\u7535\u5b50\u90ae\u4ef6\u5730\u5740\u7684\u5217\u8868 print(m) # ['dave@google.com', 'steve@gmail.com', 'rob@gmail.com', 'ryan@yahoo.com'] search \u8fd4\u56de\u7684\u662f\u6587\u672c\u4e2d\u7b2c\u4e00\u4e2a\u5339\u914d\u5230\u7684\u7535\u5b50\u90ae\u4ef6\u5730\u5740\u3002 \u5bf9\u4e8e\u524d\u9762\u63d0\u5230\u7684\u6b63\u5219\u8868\u8fbe\u5f0f\uff0c\u5339\u914d\u5bf9\u8c61\u53ea\u80fd\u544a\u8bc9\u6211\u4eec\u6a21\u5f0f\u5728\u5b57\u7b26\u4e32\u4e2d\u8d77\u59cb\u548c\u7ed3\u675f\u7684\u4f4d\u7f6e\u3002 m = regex.search(text) print(m) # print(text[m.start():m.end()]) # dave@google.com regex.match \u53ea\u5728\u6a21\u5f0f\u51fa\u73b0\u4e8e\u5b57\u7b26\u4e32\u8d77\u59cb\u4f4d\u7f6e\u65f6\u8fdb\u884c\u5339\u914d\uff0c\u5982\u679c\u6ca1\u6709\u5339\u914d\u5230\uff0c\u8fd4\u56de None \u3002 m = regex.match(text) print(m) # None m = regex.match('rob@gmail.com') print(m) # print(m.group()) # rob@gmail.com print(m.groups()) # () regex.sub \u4f1a\u8fd4\u56de\u4e00\u4e2a\u65b0\u7684\u5b57\u7b26\u4e32\uff0c\u539f\u5b57\u7b26\u4e32\u4e2d\u7684\u6a21\u5f0f\u4f1a\u88ab\u4e00\u4e2a\u65b0\u7684\u5b57\u7b26\u4e32\u66ff\u4ee3\u3002 m = regex.sub('REDACTED', text) print(m) # Dave REDACTED # Steve REDACTED # Rob REDACTED # Ryan REDACTED \u67e5\u627e\u7535\u5b50\u90ae\u4ef6\u5730\u5740\uff0c\u5e76\u5c06\u6bcf\u4e2a\u5730\u5740\u5206\u4e3a\u4e09\u4e2a\u90e8\u5206\uff1a\u7528\u6237\u540d\uff0c\u57df\u540d\u548c\u57df\u540d\u540e\u7f00\u3002\u8981\u5b9e\u73b0\u8fd9\u4e00\u70b9\uff0c\u53ef\u4ee5\u7528\u62ec\u53f7\u5c06 pattern \u5305\u8d77\u6765\u3002 \u4fee\u6539\u540e\u7684\u6b63\u5219\u8868\u8fbe\u5f0f\u4ea7\u751f\u7684\u5339\u914d\u5bf9\u8c61\u7684 groups \u65b9\u6cd5\uff0c\u8fd4\u56de\u7684\u662f\u6a21\u5f0f\u7ec4\u4ef6\u7684\u5143\u7ec4\u3002 text = \"\"\"Dave dave@google.com Steve steve@gmail.com Rob rob@gmail.com Ryan ryan@yahoo.com \"\"\" pattern = r'([A-Z0-9._%+-]+)@([A-Z0-9.-]+)\\.([A-Z]{2,4})' regex = re.compile(pattern, flags=re.IGNORECASE) m = regex.findall(text) # \u5f53pattern\u53ef\u4ee5\u5206\u7ec4\u65f6\uff0cfindall\u8fd4\u56de\u7684\u662f\u5305\u542b\u5143\u7ec4\u7684\u5217\u8868 print(m) # [('dave', 'google', 'com'), ('steve', 'gmail', 'com'), ('rob', 'gmail', 'com'), ('ryan', 'yahoo', 'com')] m = regex.search(text) print(m) # print(text[m.start():m.end()]) # dave@google.com m = regex.match('rob@gmail.com') print(m) # print(m.group()) # rob@gmail.com print(m.groups()) # ('rob', 'gmail', 'com') m = regex.sub('REDACTED', text) print(m) # Dave REDACTED # Steve REDACTED # Rob REDACTED # Ryan REDACTED m = regex.sub(r'Username: \\1, Domain: \\2, Suffix: \\3', text) print(m) # Dave Username: dave, Domain: google, Suffix: com # Steve Username: steve, Domain: gmail, Suffix: com # Rob Username: rob, Domain: gmail, Suffix: com # Ryan Username: ryan, Domain: yahoo, Suffix: com","title":"\u6b63\u5219\u8868\u8fbe\u5f0f"},{"location":"python/DataAnalysis/ch04/#pandas","text":"\u6e05\u7406\u6742\u4e71\u7684\u6570\u636e\u96c6\u7528\u4e8e\u5206\u6790\u901a\u5e38\u9700\u8981\u5927\u91cf\u7684\u5b57\u7b26\u4e32\u5904\u7406\u548c\u6b63\u5219\u5316\u3002 data = { 'Dave': 'dave@gmail.com', 'Steve': 'steve@gmail.com', 'Rob': 'rob@gmail.com', 'Wes': np.nan } data = pd.Series(data) print(data) # Dave dave@gmail.com # Steve steve@gmail.com # Rob rob@gmail.com # Wes NaN # dtype: object print(data.isnull()) # Dave False # Steve False # Rob False # Wes True # dtype: bool \u53ef\u4ee5\u4f7f\u7528 data.map \u5c06\u5b57\u7b26\u4e32\u548c\u6709\u6548\u7684\u6b63\u5219\u8868\u8fbe\u5f0f\u65b9\u6cd5\uff08\u4ee5 lambda \u6216\u5176\u4ed6\u51fd\u6570\u7684\u65b9\u5f0f\u4f20\u9012\uff09\u5e94\u7528\u5230\u6bcf\u4e2a\u503c\u4e0a\uff0c\u4f46\u662f\u5728 NA \uff08 null \uff09\u503c\u4e0a\u4f1a\u5931\u8d25\u3002 \u4e3a\u4e86\u89e3\u51b3\u8fd9\u4e2a\u95ee\u9898\uff0cSeries\u6709\u9762\u5411\u6570\u7ec4\u7684\u65b9\u6cd5\u7528\u4e8e\u8df3\u8fc7 NA \u503c\u7684\u5b57\u7b26\u4e32\u64cd\u4f5c\u3002\u8fd9\u4e9b\u65b9\u6cd5\u901a\u8fc7Series\u7684 str \u5c5e\u6027\u8fdb\u884c\u8c03\u7528\u3002 \u4f8b\u5982\uff0c\u53ef\u4ee5\u901a\u8fc7 str.contains \u6765\u68c0\u67e5\u6bcf\u4e2a\u7535\u5b50\u90ae\u4ef6\u5730\u5740\u662f\u5426\u542b\u6709 'gmail' \u3002 m = data.str.contains('gmail') print(m) # Dave True # Steve True # Rob True # Wes NaN # dtype: object \u6b63\u5219\u8868\u8fbe\u5f0f\u4e5f\u53ef\u4ee5\u7ed3\u5408\u4efb\u610f\u7684 re \u6a21\u5757\u9009\u9879\u4f7f\u7528\uff0c\u4f8b\u5982 IGNORECASE \u3002 print(pattern) # ([A-Z0-9._%+-]+)@([A-Z0-9.-]+)\\.([A-Z]{2,4}) m = data.str.findall(pattern, flags=re.IGNORECASE) print(m) # Dave [(dave, gmail, com)] # Steve [(steve, gmail, com)] # Rob [(rob, gmail, com)] # Wes NaN # dtype: object \u4f7f\u7528 str.get \u6216\u5728 str \u5c5e\u6027\u5185\u90e8\u7d22\u5f15\uff0c\u8fdb\u884c\u5411\u91cf\u5316\u7684\u5143\u7d20\u68c0\u7d22\u3002 m = data.str.match(pattern, flags=re.IGNORECASE) print(m) # Dave True # Steve True # Rob True # Wes NaN # dtype: object m = data.str.findall(pattern, flags=re.IGNORECASE) print(m.str.get(1)) # Dave NaN # Steve NaN # Rob NaN # Wes NaN # dtype: float64 print(m.str[0]) # Dave (dave, gmail, com) # Steve (steve, gmail, com) # Rob (rob, gmail, com) # Wes NaN # dtype: object \u4f7f\u7528\u5b57\u7b26\u4e32\u5207\u7247\u7684\u7c7b\u4f3c\u8bed\u6cd5\u8fdb\u884c\u5411\u91cf\u5316\u5207\u7247\u3002 print(data.str[:]) # Dave dave@gmail.com # Steve steve@gmail.com # Rob rob@gmail.com # Wes NaN # dtype: object print(data.str[:5]) # Dave dave@ # Steve steve # Rob rob@g # Wes NaN # dtype: object","title":"pandas\u4e2d\u7684\u5411\u91cf\u5316\u5b57\u7b26\u4e32\u51fd\u6570"},{"location":"python/DataAnalysis/ch05/","text":"\u6570\u636e\u89c4\u6574\uff1a\u8fde\u63a5\u3001\u8054\u5408\u4e0e\u91cd\u5851 \u00b6 \u5206\u5c42\u7d22\u5f15 \u00b6 import pandas as pd import numpy as np import re \u5206\u5c42\u7d22\u5f15\u662fpandas\u7684\u91cd\u8981\u7279\u6027\uff0c\u5141\u8bb8\u4f60\u5728\u4e00\u4e2a\u8f74\u5411\u4e0a\u62e5\u6709\u591a\u4e2a\uff08\u4e24\u4e2a\u6216\u4e24\u4e2a\u4ee5\u4e0a\uff09\u7d22\u5f15\u5c42\u7ea7\u3002 \u5206\u5c42\u7d22 import re \u5f15\u63d0\u4f9b\u4e86\u4e00\u79cd\u5728\u66f4\u4f4e\u7ef4\u5ea6\u7684\u5f62\u5f0f\u4e2d\u5904\u7406\u66f4\u9ad8\u7ef4\u5ea6\u6570\u636e\u7684\u65b9\u5f0f\u3002 Series\u7d22\u5f15\u5206\u5c42 \u00b6 data = pd.Series( np.random.randn(9), index=[['a', 'a', 'a', 'b', 'b', 'c', 'c', 'd', 'd'], [1, 2, 3, 1, 3, 1, 2, 2, 3]] ) \u8f93\u51fa\u662f\u4e00\u4e2a\u4ee5 MultiIndex \u4f5c\u4e3a\u7d22\u5f15\u7684Series\u7684\u7f8e\u5316\u89c6\u56fe\u3002 \u7d22\u5f15\u4e2d\u7684\"\u95f4\u9699\"\u8868\u793a\"\u76f4\u63a5\u4f7f\u7528\u4e0a\u9762\u7684\u6807\u7b7e\"\u3002 print(data) # a 1 0.163468 # 2 -1.525926 # 3 -0.210247 # b 1 -0.956063 # 3 -1.839111 # c 1 -0.398905 # 2 0.595279 # d 2 0.034305 # 3 -0.896078 # dtype: float64 print(data.index) # MultiIndex([('a', 1), # ('a', 2), # ('a', 3), # ('b', 1), # ('b', 3), # ('c', 1), # ('c', 2), # ('d', 2), # ('d', 3)], # ) \u901a\u8fc7\u5206\u5c42\u7d22\u5f15\u5bf9\u8c61\uff0c\u4e5f\u53ef\u4ee5\u79f0\u4e3a\u90e8\u5206\u7d22\u5f15\uff0c\u53ef\u4ee5\u7b80\u6d01\u5730\u9009\u62e9\u51fa\u6570\u636e\u7684\u5b50\u96c6\u3002 m = data['b'] print(m) # 1 -0.956063 # 3 -1.839111 # dtype: float64 m = data['b': 'c'] print(m) # b 1 -0.956063 # 3 -1.839111 # c 1 -0.398905 # 2 0.595279 # dtype: float64 m = data.loc[['b', 'c']] print(m) # b 1 -0.956063 # 3 -1.839111 # c 1 -0.398905 # 2 0.595279 # dtype: float64 m = data.loc[:, 2] print(m) # a -1.525926 # c 0.595279 # d 0.034305 # dtype: float64 \u5206\u5c42\u7d22\u5f15\u5728\u91cd\u5851\u6570\u636e\u548c\u6570\u7ec4\u900f\u89c6\u8868\u7b49\u5206\u7ec4\u64cd\u4f5c\u4e2d\u626e\u6f14\u4e86\u91cd\u8981\u89d2\u8272\u3002 \u4f8b\u5982\uff0c\u4f60\u53ef\u4ee5\u4f7f\u7528 unstack \u65b9\u6cd5\u5c06\u6570\u636e\u5728DataFrame\u4e2d\u91cd\u65b0\u6392\u5217\u3002 m = data.unstack() print(m) # 1 2 3 # a 0.163468 -1.525926 -0.210247 # b -0.956063 NaN -1.839111 # c -0.398905 0.595279 NaN # d NaN 0.034305 -0.896078 n = m.stack() print(n) # \u6216\u8005 print(data.unstack().stack()) # a 1 0.163468 # 2 -1.525926 # 3 -0.210247 # b 1 -0.956063 # 3 -1.839111 # c 1 -0.398905 # 2 0.595279 # d 2 0.034305 # 3 -0.896078 # dtype: float64 DataFrame\u7d22\u5f15\u5206\u5c42 \u00b6 \u5728DataFrame\u4e2d\uff0c\u6bcf\u4e2a\u8f74\u90fd\u53ef\u4ee5\u62e5\u6709\u5206\u5c42\u7d22\u5f15\u3002 \u53c2\u8003 \u65b9\u6cd51\uff1a\u76f4\u63a5\u521b\u5efa \u00b6 \u76f4\u63a5\u901a\u8fc7\u7ed9 index \uff08columns\uff09\u53c2\u6570\u4f20\u9012\u591a\u7ef4\u6570\u7ec4\uff0c\u8fdb\u800c\u6784\u5efa\u591a\u7ef4\u7d22\u5f15\u3002 \u6570\u7ec4\u4e2d\u6bcf\u4e2a\u7ef4\u5ea6\u5bf9\u5e94\u4f4d\u7f6e\u7684\u5143\u7d20\uff0c\u7ec4\u6210\u6bcf\u4e2a\u7d22\u5f15\u503c\u3002 frame = pd.DataFrame( np.arange(12).reshape((4, 3)), index=[['a', 'a', 'b', 'b'], [1, 2, 1, 2]], columns=[['Ohio', 'Ohio', 'Colorado'], ['Green', 'Red', 'Green']] ) print(frame) # Ohio Colorado # Green Red Green # a 1 0 1 2 # 2 3 4 5 # b 1 6 7 8 # 2 9 10 11 \u4e0a\u9762\u8f93\u51fa\u4e2d\u76842\u4e2a\u5c42\u7ea7\u662f\u6ca1\u6709\u540d\u5b57\u3002 \u5206\u5c42\u7684\u5c42\u7ea7\u53ef\u4ee5\u6709\u540d\u79f0\uff08\u53ef\u4ee5\u662f\u5b57\u7b26\u4e32\u6216Python\u5bf9\u8c61\uff09\u3002 \u5982\u679c\u5c42\u7ea7\u6709\u540d\u79f0\uff0c\u8fd9\u4e9b\u540d\u79f0\u4f1a\u5728\u63a7\u5236\u53f0\u8f93\u51fa\u4e2d\u663e\u793a\u3002 print(frame.index.names) # [None, None] print(frame.columns.names) # [None, None] \u7ed9\u5c42\u7ea7\u8d4b\u4e88\u540d\u79f0\u3002\u6ce8\u610f\u533a\u5206\u884c\u6807\u7b7e\u4e2d\u7684\u7d22\u5f15\u540d\u79f0 state \u548c color \u3002 frame.index.names = ['key1', 'key2'] frame.columns.names = ['state', 'color'] print(frame) # state Ohio Colorado # color Green Red Green # key1 key2 # a 1 0 1 2 # 2 3 4 5 # b 1 6 7 8 # 2 9 10 11 print(frame['Ohio']) # color Green Red # key1 key2 # a 1 0 1 # 2 3 4 # b 1 6 7 # 2 9 10 print(frame.index) # MultiIndex([('a', 1), # ('a', 2), # ('b', 1), # ('b', 2)], # names=['key1', 'key2']) \u901a\u8fc7 MultiIndex \u7c7b\u7684\u76f8\u5173\u65b9\u6cd5\uff0c\u9884\u5148\u521b\u5efa\u4e00\u4e2a MultiIndex \u5bf9\u8c61\uff0c\u7136\u540e\u4f5c\u4e3aSeries\u4e0eDataFrame\u4e2d\u7684 index \uff08\u6216columns\uff09\u53c2\u6570\u503c\u3002\u540c\u65f6\uff0c\u53ef\u4ee5\u901a\u8fc7 names \u53c2\u6570\u6307\u5b9a\u591a\u5c42\u7d22\u5f15\u7684\u540d\u79f0\u3002 \u65b9\u6cd52\uff1afrom_arrays \u00b6 from_arrays \uff1a\u63a5\u6536\u4e00\u4e2a\u591a\u7ef4\u6570\u7ec4\u53c2\u6570\uff0c\u9ad8\u7ef4\u6307\u5b9a\u9ad8\u5c42\u7d22\u5f15\uff0c\u4f4e\u7ef4\u6307\u5b9a\u5e95\u5c42\u7d22\u5f15\u3002 mindex = pd.MultiIndex.from_arrays( [['a', 'a', 'b', 'b'], [1, 2, 1, 2]], names=['key1', 'key2'] ) frame = pd.DataFrame( np.arange(12).reshape((4, 3)), index=mindex, columns=[['Ohio', 'Ohio', 'Colorado'], ['Green', 'Red', 'Green']] ) frame.columns.names = ['state', 'color'] print(frame) # state Ohio Colorado # color Green Red Green # key1 key2 # a 1 0 1 2 # 2 3 4 5 # b 1 6 7 8 # 2 9 10 11 \u65b9\u6cd53\uff1afrom_tuples \u00b6 from_tuples \uff1a\u63a5\u6536\u4e00\u4e2a\u5143\u7ec4\u7684\u5217\u8868\uff0c\u6bcf\u4e2a\u5143\u7ec4\u6307\u5b9a\u6bcf\u4e2a\u7d22\u5f15\uff08\u9ad8\u7ef4\u7d22\u5f15\uff0c\u4f4e\u7ef4\u7d22\u5f15\uff09\u3002 mindex = pd.MultiIndex.from_tuples( [('a', 1), ('a', 2), ('b', 1), ('b', 2)] ) frame = pd.DataFrame( np.arange(12).reshape((4, 3)), index=mindex, columns=[['Ohio', 'Ohio', 'Colorado'], ['Green', 'Red', 'Green']] ) frame.index.names = ['key1', 'key2'] frame.columns.names = ['state', 'color'] print(frame) # state Ohio Colorado # color Green Red Green # key1 key2 # a 1 0 1 2 # 2 3 4 5 # b 1 6 7 8 # 2 9 10 11 \u65b9\u6cd54\uff1afrom_product \u00b6 from_product \uff1a\u63a5\u6536\u4e00\u4e2a\u53ef\u8fed\u4ee3\u5bf9\u8c61\u7684\u5217\u8868\uff0c\u6839\u636e\u591a\u4e2a\u53ef\u8fed\u4ee3\u5bf9\u8c61\u5143\u7d20\u7684\u7b1b\u5361\u5c14\u79ef\u8fdb\u884c\u521b\u5efa\u7d22\u5f15\u3002 \u4f7f\u7528\u7b1b\u5361\u5c14\u79ef\u7684\u65b9\u5f0f\u6765\u521b\u5efa\u591a\u5c42\u7d22\u5f15\u3002\u53c2\u6570\u4e3a\u5d4c\u5957\u7684\u53ef\u8fed\u4ee3\u5bf9\u8c61\u3002\u7ed3\u679c\u4e3a\u4f7f\u7528\u6bcf\u4e2a\u4e00\u7ef4\u6570\u7ec4\u4e2d\u7684\u5143\u7d20\u4e0e\u5176\u4ed6\u4e00\u7ef4\u6570\u7ec4\u4e2d\u7684\u5143\u7d20\u6765\u751f\u6210\u3002 \u7b1b\u5361\u5c14\u79ef\u7684\u65b9\u5f0f\u7684\u5c40\u9650\uff1a\u4e24\u4e24\u7ec4\u5408\u5fc5\u987b\u90fd\u5b58\u5728\uff0c\u5426\u5219\uff0c\u5c31\u4e0d\u80fd\u4f7f\u7528\u8fd9\u79cd\u65b9\u5f0f\u3002 mindex = pd.MultiIndex.from_product( [['a', 'b'], ['1', '2']], names=['key1', 'key2'] ) frame = pd.DataFrame( np.arange(12).reshape((4, 3)), index=mindex, columns=[['Ohio', 'Ohio', 'Colorado'], ['Green', 'Red', 'Green']] ) frame.columns.names = ['state', 'color'] print(frame) # state Ohio Colorado # color Green Red Green # key1 key2 # a 1 0 1 2 # 2 3 4 5 # b 1 6 7 8 # 2 9 10 11 \u91cd\u6392\u5e8f\u548c\u5c42\u7ea7\u6392\u5e8f \u00b6 \u5982\u679c\u9700\u8981\u91cd\u65b0\u6392\u5217\u8f74\u4e0a\u7684\u5c42\u7ea7\u987a\u5e8f\uff0c\u6216\u8005\u6309\u7167\u7279\u5b9a\u5c42\u7ea7\u7684\u503c\u5bf9\u6570\u636e\u8fdb\u884c\u6392\u5e8f\uff0c \u53ef\u4ee5\u901a\u8fc7swaplevel\u63a5\u6536\u4e24\u4e2a\u5c42\u7ea7\u5e8f\u53f7\u6216\u5c42\u7ea7\u540d\u79f0\uff0c\u8fd4\u56de\u4e00\u4e2a\u8fdb\u884c\u4e86\u5c42\u7ea7\u53d8\u66f4\u7684\u65b0\u5bf9\u8c61\uff08\u4f46\u662f\u6570\u636e\u662f\u4e0d\u53d8\u7684\uff09\u3002 print(frame) # state Ohio Colorado # color Green Red Green # key1 key2 # a 1 0 1 2 # 2 3 4 5 # b 1 6 7 8 # 2 9 10 11 m = frame.swaplevel('key1', 'key2') print(m) # state Ohio Colorado # color Green Red Green # key2 key1 # 1 a 0 1 2 # 2 a 3 4 5 # 1 b 6 7 8 # 2 b 9 10 11 sort_index \u53ea\u80fd\u5728\u5355\u4e00\u5c42\u7ea7\u4e0a\u5bf9\u6570\u636e\u8fdb\u884c\u6392\u5e8f\u3002 \u5728\u8fdb\u884c\u5c42\u7ea7\u53d8\u6362\u65f6\uff0c\u4f7f\u7528 sort_index \u4ee5\u4f7f\u5f97\u7ed3\u679c\u6309\u7167\u5c42\u7ea7\u8fdb\u884c\u5b57\u5178\u6392\u5e8f\u3002 m = frame.sort_index(level=1) # \u5bf9key2\u6392\u5e8f\uff0c\u5e95\u5c42\u7d22\u5f15 print(m) # state Ohio Colorado # color Green Red Green # key1 key2 # a 1 0 1 2 # b 1 6 7 8 # a 2 3 4 5 # b 2 9 10 11 m = frame.sort_index(level=0) # \u5bf9key1\u6392\u5e8f\uff0c\u9ad8\u5c42\u7d22\u5f15 print(m) # state Ohio Colorado # color Green Red Green # key1 key2 # a 1 0 1 2 # 2 3 4 5 # b 1 6 7 8 # 2 9 10 11 m = frame.swaplevel(0, 1).sort_index(level=1) # swaplevel(0, 1)\u7b49\u540c\u4e8eswaplevel(key1, key2)\uff0c\u4ea4\u6362\u540ekey1\u53d8\u6210\u4e86\u5e95\u5c42\u7d22\u5f15 print(m) # state Ohio Colorado # color Green Red Green # key2 key1 # 1 a 0 1 2 # 2 a 3 4 5 # 1 b 6 7 8 # 2 b 9 10 11 \u6309\u5c42\u7ea7\u8fdb\u884c\u6c47\u603b\u7edf\u8ba1 \u00b6 DataFrame\u548cSeries\u4e2d\u5f88\u591a\u63cf\u8ff0\u6027\u548c\u6c47\u603b\u6027\u7edf\u8ba1\u6709\u4e00\u4e2a level \u9009\u9879\uff0c\u901a\u8fc7 level \u9009\u9879\u4f60\u53ef\u4ee5\u6307\u5b9a\u4f60\u60f3\u8981\u5728\u67d0\u4e2a\u7279\u5b9a\u7684\u8f74\u4e0a\u8fdb\u884c\u805a\u5408\u3002 print(frame) # state Ohio Colorado # color Green Red Green # key1 key2 # a 1 0 1 2 # 2 3 4 5 # b 1 6 7 8 # 2 9 10 11 m = frame.groupby(level='key2').sum() print(m) # state Ohio Colorado # color Green Red Green # key2 # 1 6 8 10 # 2 12 14 16 m = frame.groupby(level='color', axis=1).sum() print(m) # color Green Red # key1 key2 # a 1 2 1 # 2 8 4 # b 1 14 7 # 2 20 10 \u4f7f\u7528DataFrame\u7684\u5217\u8fdb\u884c\u7d22\u5f15 \u00b6 \u901a\u5e38\u6211\u4eec\u4e0d\u4f1a\u4f7f\u7528DataFrame\u4e2d\u4e00\u4e2a\u6216\u591a\u4e2a\u5217\u4f5c\u4e3a\u884c\u7d22\u5f15\uff1b\u53cd\u800c\u4f60\u53ef\u80fd\u60f3\u8981\u5c06\u884c\u7d22\u5f15\u79fb\u52a8\u5230DataFrame\u7684\u5217\u4e2d\u3002 frame = pd.DataFrame( {'a': range(7), 'b': range(7, 0, -1), 'c': ['one', 'one', 'one', 'two', 'two', 'two', 'two'], 'd': [0, 1, 2, 0, 1, 2, 3] } ) print(frame) # a b c d # 0 0 7 one 0 # 1 1 6 one 1 # 2 2 5 one 2 # 3 3 4 two 0 # 4 4 3 two 1 # 5 5 2 two 2 # 6 6 1 two 3 DataFrame\u7684 set_index \u51fd\u6570\u4f1a\u751f\u6210\u4e00\u4e2a\u65b0\u7684DataFrame\uff0c\u65b0\u7684DataFrame\u4f7f\u7528\u4e00\u4e2a\u6216\u591a\u4e2a\u5217\u4f5c\u4e3a\u7d22\u5f15\u3002 \u9ed8\u8ba4\u60c5\u51b5\u4e0b\u8fd9\u4e9b\u7d22\u5f15\u5217\u4f1a\u4eceDataFrame\u4e2d\u79fb\u9664\uff0c\u4e5f\u53ef\u4ee5\u5c06\u5b83\u4eec\u7559\u5728DataFrame\u4e2d\u3002 frame2 = frame.set_index(['c', 'd'], drop=False) print(frame2) # a b c d # c d # one 0 0 7 one 0 # 1 1 6 one 1 # 2 2 5 one 2 # two 0 3 4 two 0 # 1 4 3 two 1 # 2 5 2 two 2 # 3 6 1 two 3 frame2 = frame.set_index(['c', 'd']) print(frame2) # a b # c d # one 0 0 7 # 1 1 6 # 2 2 5 # two 0 3 4 # 1 4 3 # 2 5 2 # 3 6 1 reset_index \u662f set_index \u7684\u53cd\u64cd\u4f5c\uff0c\u5206\u5c42\u7d22\u5f15\u7684\u7d22\u5f15\u5c42\u7ea7\u4f1a\u88ab\u79fb\u52a8\u5230\u5217\u4e2d\u3002 \u6ce8\u610f\uff1a\u5982\u679c\u5728 set_index \u65f6\u4f7f\u7528\u4e86 drop=False \uff0c\u5728\u4f7f\u7528 reset_index \u4f1a\u62a5\u9519\u3002 m = frame2.reset_index() print(m) # c d a b # 0 one 0 0 7 # 1 one 1 1 6 # 2 one 2 2 5 # 3 two 0 3 4 # 4 two 1 4 3 # 5 two 2 5 2 # 6 two 3 6 1 \u8054\u5408\u4e0e\u5408\u5e76\u6570\u636e\u96c6 \u00b6 \u5305\u542b\u5728pandas\u5bf9\u8c61\u7684\u6570\u636e\u53ef\u4ee5\u901a\u8fc7\u591a\u79cd\u65b9\u5f0f\u8054\u5408\u5728\u4e00\u8d77\uff1a pandas.merge \u6839\u636e\u4e00\u4e2a\u6216\u591a\u4e2a\u952e\u5c06\u884c\u8fdb\u884c\u8fde\u63a5\u3002\u5bf9\u4e8eSQL\u6216\u5176\u4ed6\u5173\u7cfb\u578b\u6570\u636e\u5e93\u7684\u7528\u6237\u6765\u8bf4\uff0c\u8fd9\u79cd\u65b9\u5f0f\u6bd4\u8f83\u719f\u6089\uff0c\u5b83\u5b9e\u73b0\u7684\u662f\u6570\u636e\u5e93\u7684\u8fde\u63a5\u64cd\u4f5c\u3002 pandas.concat \u4f7f\u5bf9\u8c61\u5728\u8f74\u5411\u4e0a\u8fdb\u884c\u9ecf\u5408\u6216\u201c\u5806\u53e0\u201d\u3002 combine_first \u5b9e\u4f8b\u65b9\u6cd5\u5141\u8bb8\u5c06\u91cd\u53e0\u7684\u6570\u636e\u62fc\u63a5\u5728\u4e00\u8d77\uff0c\u4ee5\u4f7f\u7528\u4e00\u4e2a\u5bf9\u8c61\u4e2d\u7684\u503c\u586b\u5145\u53e6\u4e00\u4e2a\u5bf9\u8c61\u4e2d\u7684\u7f3a\u5931\u503c\u3002 \u6570\u636e\u5e93\u98ce\u683c\u7684DataFrame\u8fde\u63a5 \u00b6 \u5408\u5e76\u6216\u8fde\u63a5\u64cd\u4f5c\u901a\u8fc7\u4e00\u4e2a\u6216\u591a\u4e2a\u952e\u8fde\u63a5\u884c\u6765\u8054\u5408\u6570\u636e\u96c6\u3002 \u8fd9\u4e9b\u64cd\u4f5c\u662f\u5173\u7cfb\u578b\u6570\u636e\u5e93\u7684\u6838\u5fc3\u5185\u5bb9\uff08\u4f8b\u5982\u57fa\u4e8eSQL\u7684\u6570\u636e\u5e93\uff09\u3002 pandas\u4e2d\u7684 merge \u51fd\u6570\u4e3b\u8981\u7528\u4e8e\u5c06\u5404\u79cd join \u64cd\u4f5c\u7b97\u6cd5\u8fd0\u7528\u5728\u6570\u636e\u4e0a\u3002 \u5728\u8fdb\u884c\u5217-\u5217\u8fde\u63a5\u65f6\uff0c\u4f20\u9012\u7684DataFrame\u7d22\u5f15\u5bf9\u8c61\u4f1a\u88ab\u4e22\u5f03\u3002 \u5408\u5e76\u64cd\u4f5c\u4e5f\u8981\u8003\u8651\u5982\u4f55\u5904\u7406\u91cd\u53e0\u7684\u5217\u540d( suffixes \u540e\u7f00\u9009\u9879)\u3002 \u4e0b\u9762\u662f\u4e00\u4e2a\u591a\u5bf9\u4e00\u8fde\u63a5\u7684\u4f8b\u5b50\u3002 df1 \u7684\u6570\u636e\u6709\u591a\u4e2a\u884c\u7684\u6807\u7b7e\u4e3a a \u548c b \uff0c\u800c df2 \u5728 key \u5217\u4e2d\u6bcf\u4e2a\u503c\u4ec5\u6709\u4e00\u884c\u3002 df1 = pd.DataFrame( { 'key': ['b', 'b', 'a', 'c', 'a', 'a', 'b'], 'data1': range(7) } ) df2 = pd.DataFrame( { 'key': ['a', 'b', 'd'], 'data1': range(3) } ) print(df1) # key data1 # 0 b 0 # 1 b 1 # 2 a 2 # 3 c 3 # 4 a 4 # 5 a 5 # 6 b 6 print(df2) # key data1 # 0 a 0 # 1 b 1 # 2 d 2 \u8c03\u7528 merge \u5904\u7406\uff0c\u63a8\u8350\u663e\u5f0f\u5730\u6307\u5b9a\u8fde\u63a5\u952e\u3002 result = pd.merge(df1, df2) print(result) # key data1 # 0 b 1 result = pd.merge(df1, df2, on=['key', 'data1']) print(result) # key data1 # 0 b 1 result = pd.merge(df1, df2, on='key') print(result) # key data1_x data1_y # 0 b 0 1 # 1 b 1 1 # 2 b 6 1 # 3 a 2 0 # 4 a 4 0 # 5 a 5 0 \u5982\u679c\u6bcf\u4e2a\u5bf9\u8c61\u7684\u5217\u540d\u662f\u4e0d\u540c\u7684\uff0c\u53ef\u4ee5\u5206\u522b\u4e3a\u5b83\u4eec\u6307\u5b9a\u5217\u540d\u3002 df3 = pd.DataFrame( { 'lkey': ['b', 'b', 'a', 'c', 'a', 'a', 'b'], 'data1': range(7) } ) df4 = pd.DataFrame( { 'rkey': ['a', 'b', 'd'], 'data2': range(3) } ) print(df3) # lkey data1 # 0 b 0 # 1 b 1 # 2 a 2 # 3 c 3 # 4 a 4 # 5 a 5 # 6 b 6 print(df4) # rkey data2 # 0 a 0 # 1 b 1 # 2 d 2 \u9ed8\u8ba4\u60c5\u51b5\u4e0b\uff0c merge \u505a\u7684\u662f\u5185\u8fde\u63a5\uff08'inner' join\uff09\uff0c\u7ed3\u679c\u4e2d\u7684\u952e\u662f\u4e24\u5f20\u8868\u7684\u4ea4\u96c6\u3002 result = pd.merge(df3, df4, left_on='lkey', right_on='rkey') # df4\u7684[a,0]\u5bf9\u5e94df3\u7684\u6240\u6709[a,?]\u8bb0\u5f55\uff08\u901a\u8fc7\u91cd\u590d\u6765\u586b\u5145\u4e0d\u8db3\uff09 print(result) # lkey data1 rkey data2 # 0 b 0 b 1 # 1 b 1 b 1 # 2 b 6 b 1 # 3 a 2 a 0 # 4 a 4 a 0 # 5 a 5 a 0 \u5916\u8fde\u63a5\uff08outer join\uff09\u662f\u952e\u7684\u5e76\u96c6\uff0c\u8054\u5408\u4e86\u5de6\u8fde\u63a5\u548c\u53f3\u8fde\u63a5\u7684\u6548\u679c\u3002 \u591a\u5bf9\u591a\u8fde\u63a5\u662f\u884c\u7684\u7b1b\u5361\u5c14\u79ef\u3002 df1 = pd.DataFrame( { 'key': ['b', 'b', 'a', 'c', 'a', 'b'], 'data1': range(6) } ) df2 = pd.DataFrame( { 'key': ['a', 'b', 'a', 'b', 'd'], 'data2': range(5) } ) print(df1.sort_values(by='key')) # key data1 # 2 a 2 # 4 a 4 # 0 b 0 # 1 b 1 # 5 b 5 # 3 c 3 print(df2.sort_values(by='key')) # key data2 # 0 a 0 # 2 a 2 # 1 b 1 # 3 b 3 # 4 d 4 result = pd.merge(df1, df2, on='key', how='left') print(result.sort_values(by='key')) # key data1 data2 # 4 a 2 0.0 # 5 a 2 2.0 # 7 a 4 0.0 # 8 a 4 2.0 # 0 b 0 1.0 # 1 b 0 3.0 # 2 b 1 1.0 # 3 b 1 3.0 # 9 b 5 1.0 # 10 b 5 3.0 # 6 c 3 NaN result = pd.merge(df1, df2, on='key', how='outer') # \u591a\u5bf9\u591a\u8fde\u63a5 print(result.sort_values(by='key')) # key data1 data2 # 6 a 2.0 0.0 # 7 a 2.0 2.0 # 8 a 4.0 0.0 # 9 a 4.0 2.0 # 0 b 0.0 1.0 # 1 b 0.0 3.0 # 2 b 1.0 1.0 # 3 b 1.0 3.0 # 4 b 5.0 1.0 # 5 b 5.0 3.0 # 10 c 3.0 NaN # 11 d NaN 4.0 \u591a\u952e\u5408\u5e76\u3002 df1 = pd.DataFrame( { 'key1': ['foo', 'foo', 'bar'], 'key2': ['one', 'two', 'one'], 'lval': [1, 2, 3] } ) df2 = pd.DataFrame( { 'key1': ['foo', 'foo', 'bar', 'bar'], 'key2': ['one', 'one', 'one', 'two'], 'rval': [4, 5, 6, 7] } ) print(df1.sort_values(by=['key1', 'key2'])) # key1 key2 lval # 2 bar one 3 # 0 foo one 1 # 1 foo two 2 print(df2.sort_values(by=['key1', 'key2'])) # key1 key2 rval # 2 bar one 6 # 3 bar two 7 # 0 foo one 4 # 1 foo one 5 result = pd.merge(df1, df2, on=['key1', 'key2'], how='outer') print(result.sort_values(by=['key1', 'key2'])) # key1 key2 lval rval # 3 bar one 3.0 6.0 # 4 bar two NaN 7.0 # 0 foo one 1.0 4.0 # \u91cd\u590d\u586b\u5145 # 1 foo one 1.0 5.0 # \u91cd\u590d\u586b\u5145 # 2 foo two 2.0 NaN \u5904\u7406\u91cd\u53e0\u5217\u540d\u3002 result = pd.merge(df1, df2, on='key1') print(result.sort_values(by='key1')) # key1 key2_x lval key2_y rval # 4 bar one 3 one 6 # 5 bar one 3 two 7 # 0 foo one 1 one 4 # 1 foo one 1 one 5 # 2 foo two 2 one 4 # 3 foo two 2 one 5 result = pd.merge(df1, df2, on='key1', suffixes=('_left', '_right')) print(result.sort_values(by='key1')) # key1 key2_left lval key2_right rval # 4 bar one 3 one 6 # 5 bar one 3 two 7 # 0 foo one 1 one 4 # 1 foo one 1 one 5 # 2 foo two 2 one 4 # 3 foo two 2 one 5 \u6839\u636e\u7d22\u5f15\u5408\u5e76 \u00b6 \u5728\u67d0\u4e9b\u60c5\u51b5\u4e0b\uff0cDataFrame\u4e2d\u7528\u4e8e\u5408\u5e76\u7684\u952e\u662f\u5b83\u7684\u7d22\u5f15\u3002\u53ef\u4ee5\u4f20\u9012 left_index=True \u6216 right_index=True \uff08\u6216\u8005\u90fd\u4f20\uff09\u6765\u8868\u793a\u7d22\u5f15\u9700\u8981\u7528\u6765\u4f5c\u4e3a\u5408\u5e76\u7684\u952e\u3002 df1 = pd.DataFrame( { 'key1': ['foo', 'foo', 'bar'], 'key2': ['one', 'two', 'one'], 'lval': [1, 2, 3] } ) df2 = pd.DataFrame( { 'key1': ['foo', 'foo', 'bar', 'bar'], 'key2': ['one', 'one', 'one', 'two'], 'rval': [4, 5, 6, 7] }, index=['foo', 'foo', 'bar', 'bar'] ) print(df1) # key1 key2 lval # 0 foo one 1 # 1 foo two 2 # 2 bar one 3 print(df2) # key1 key2 rval # foo foo one 4 # foo foo one 5 # bar bar one 6 # bar bar two 7 result = pd.merge(df1, df2, left_on='key1', right_index=True, suffixes=('_left', '_right')) print(result.sort_index()) # key1 key1_left key2_left lval key1_right key2_right rval # 0 foo foo one 1 foo one 4 # 0 foo foo one 1 foo one 5 # 1 foo foo two 2 foo one 4 # 1 foo foo two 2 foo one 5 # 2 bar bar one 3 bar one 6 # 2 bar bar one 3 bar two 7 result = pd.merge(df1, df2, left_on='key1', right_index=True, how='outer', suffixes=('_left', '_right')) # \u548c\u4e0a\u8ff0\u7ed3\u679c\u4e00\u6837 print(result.sort_index()) # key1 key1_left key2_left lval key1_right key2_right rval # 0 foo foo one 1 foo one 4 # 0 foo foo one 1 foo one 5 # 1 foo foo two 2 foo one 4 # 1 foo foo two 2 foo one 5 # 2 bar bar one 3 bar one 6 # 2 bar bar one 3 bar two 7 \u5728\u66f4\u590d\u6742\u591a\u5c42\u7d22\u5f15\u6570\u636e\u7684\u591a\u952e\u5408\u5e76\uff0c\u5728\u7d22\u5f15\u4e0a\u8fde\u63a5\u662f\u4e00\u4e2a\u9690\u5f0f\u7684\u591a\u952e\u5408\u5e76\u3002 \u5fc5\u987b\u4ee5\u5217\u8868\u7684\u65b9\u5f0f\u6307\u660e\u5408\u5e76\u6240\u9700\u591a\u4e2a\u5217\uff08\u6ce8\u610f\u4f7f\u7528 how='outer' \u5904\u7406\u91cd\u590d\u7684\u7d22\u5f15\u503c\uff09\u3002 df1 = pd.DataFrame( { 'key1': ['Ohio', 'Ohio', 'Ohio', 'Nevada', 'Nevada'], 'key2': [2000, 2001, 2002, 2001, 2002], 'data': np.arange(5.) } ) df2 = pd.DataFrame( np.arange(12).reshape((6, 2)), index=[ ['Nevada', 'Nevada', 'Ohio', 'Ohio', 'Ohio', 'Ohio'], [2001, 2000, 2000, 2000, 2001, 2002] ], columns=['event1', 'event2'] ) print(df1) # key1 key2 data # 0 Ohio 2000 0.0 # 1 Ohio 2001 1.0 # 2 Ohio 2002 2.0 # 3 Nevada 2001 3.0 # 4 Nevada 2002 4.0 print(df2) # event1 event2 # Nevada 2001 0 1 # 2000 2 3 # Ohio 2000 4 5 # 2000 6 7 # 2001 8 9 # 2002 10 11 result = pd.merge(df1, df2, left_on=['key1', 'key2'], right_index=True) print(result) # key1 key2 data event1 event2 # 0 Ohio 2000 0.0 4 5 # 0 Ohio 2000 0.0 6 7 # 1 Ohio 2001 1.0 8 9 # 2 Ohio 2002 2.0 10 11 # 3 Nevada 2001 3.0 0 1 result = pd.merge(df1, df2, left_on=['key1', 'key2'], right_index=True, how='outer') print(result) # key1 key2 data event1 event2 # 0 Ohio 2000 0.0 4.0 5.0 # 0 Ohio 2000 0.0 6.0 7.0 # 1 Ohio 2001 1.0 8.0 9.0 # 2 Ohio 2002 2.0 10.0 11.0 # 3 Nevada 2001 3.0 0.0 1.0 # 4 Nevada 2002 4.0 NaN NaN # 4 Nevada 2000 NaN 2.0 3.0 \u4f7f\u7528\u4e24\u8fb9\u7684\u7d22\u5f15\u8fdb\u884c\u5408\u5e76\u4e5f\u662f\u53ef\u4ee5\u7684\uff0c\u524d\u63d0\u662f\u7528\u4e24\u8fb9\u7528\u6765\u5408\u5e76\u7684\u7d22\u5f15\u6709\u4ea4\u96c6\uff08\u516c\u5171\u90e8\u5206\uff09\u3002 \u5728\u4f7f\u7528 merge \u65f6\uff0c\u53c2\u6570 on=['key1', 'key2'] \u4e0d\u80fd\u548c left_index=True , right_index=True \u540c\u65f6\u5b58\u5728\u3002 \u5bf9\u4e8e\u91cd\u590d\u7d22\u5f15\uff0c\u5982\u679c\u503c\u4e0d\u540c\uff0c\u5219\u591a\u884c\u663e\u793a\uff0c\u548c\u6570\u636e\u5e93SQL\u7684 full join \u7c7b\u4f3c\u6982\u5ff5\u3002 \u5982\u679c\u51fa\u73b0\u76f8\u540c\u5217\u540d\uff0c\u5219\u4f1a\u81ea\u52a8\u6dfb\u52a0\u540e\u7f00\u5b57\u7b26\u4ee5\u793a\u533a\u522b\u3002 df1 = pd.DataFrame( [[1, 2], [3, 4], [5, 6]], index=['a', 'c', 'e'], columns=['Ohio', 'Nevada'] ) print(df1) # Ohio Nevada # a 1 2 # c 3 4 # e 5 6 df2 = pd.DataFrame( [[7, 8], [9, 10], [11, 12], [13, 14]], index=['b', 'c', 'c', 'e'], columns=['Missouri', 'Alabama'] ) print(df2) # Missouri Alabama # b 7 8 # c 9 10 # c 11 12 # e 13 14 df3 = pd.DataFrame( [[7, 8], [9, 10], [11, 12], [13, 14]], index=['a', 'c', 'e', 'f'], columns=['Nevada', 'Alabama'] ) print(df3) # Nevada Alabama # a 7 8 # c 9 10 # e 11 12 # f 13 14 result = pd.merge(df1, df2, left_index=True, right_index=True, how='outer') print(result) # Ohio Nevada Missouri Alabama # a 1.0 2.0 NaN NaN # b NaN NaN 7.0 8.0 # c 3.0 4.0 9.0 10.0 # c 3.0 4.0 11.0 12.0 # e 5.0 6.0 13.0 14.0 result = pd.merge(df1, df3, left_index=True, right_index=True, how='outer') print(result) # Ohio Nevada_x Nevada_y Alabama # a 1.0 2.0 7 8 # c 3.0 4.0 9 10 # e 5.0 6.0 11 12 # f NaN NaN 13 14 \u53e6\u4e00\u79cd\u5199\u6cd5\uff1a result = df1.join(df2, how='outer') print(result) # Ohio Nevada Missouri Alabama # a 1.0 2.0 NaN NaN # b NaN NaN 7.0 8.0 # c 3.0 4.0 9.0 10.0 # c 3.0 4.0 11.0 12.0 # e 5.0 6.0 13.0 14.0 \u4e5f\u53ef\u4ee5\u5411 join \u65b9\u6cd5\u4f20\u5165\u4e00\u4e2aDataFrame\u5217\u8868\uff0c\u7c7b\u4f3c\u4e8e\u5bf9\u4e09\u4e2a\u6570\u636e\u96c6\u8fdb\u884c join \u64cd\u4f5c\u3002 result = df1.join([df2, df3]) print(result) # Ohio Nevada_x Missouri Alabama_x Nevada_y Alabama_y # a 1 2 NaN NaN 7 8 # c 3 4 9.0 10.0 9 10 # c 3 4 11.0 12.0 9 10 # e 5 6 13.0 14.0 11 12 \u6cbf\u8f74\u5411\u8fde\u63a5 \u00b6 \u53e6\u4e00\u79cd\u6570\u636e\u7ec4\u5408\u64cd\u4f5c\u53ef\u79f0\u4e3a\u62fc\u63a5\u3001\u7ed1\u5b9a\u6216\u5806\u53e0\u3002NumPy\u7684 concatenate \u51fd\u6570\u53ef\u4ee5\u5728NumPy\u6570\u7ec4\u4e0a\u5b9e\u73b0\u8be5\u529f\u80fd\u3002 \u57fa\u4e8eSeries\u7684pandas\u7684 concat \u51fd\u6570\u7684\u5de5\u4f5c\u673a\u5236\u5206\u6790\u3002 \u4e0b\u9762\u4e09\u4e2a\u7d22\u5f15\u4e0d\u91cd\u53e0\u7684Series\u3002 s1 = pd.Series([0, 1], index=['a', 'b']) s2 = pd.Series([2, 3, 4], index=['c', 'd', 'e']) s3 = pd.Series([5, 6], index=['f', 'g']) \u7528\u5217\u8868\u4e2d\u7684\u8fd9\u4e9b\u5bf9\u8c61\u8c03\u7528 concat \u65b9\u6cd5\u4f1a\u5c06\u503c\u548c\u7d22\u5f15\u7c98\u5728\u4e00\u8d77\uff1a \u9ed8\u8ba4\u60c5\u51b5\u4e0b\uff0c concat \u65b9\u6cd5\u662f\u6cbf\u7740 axis=0 \u7684\u8f74\u5411\u751f\u6548\u7684\uff0c\u751f\u6210\u53e6\u4e00\u4e2aSeries\u3002 \u5982\u679c\u4f20\u9012 axis=1 \uff0c\u8fd4\u56de\u7684\u7ed3\u679c\u5219\u662f\u4e00\u4e2aDataFrame\uff08 axis=1 \u65f6\u662f\u5217\uff09\u3002 result = pd.concat([s1, s2, s3]) print(result) # a 0 # b 1 # c 2 # d 3 # e 4 # f 5 # g 6 # dtype: int64 result = pd.concat([s1, s2, s3], keys=['one', 'two', 'three']) # \u901a\u8fc7keys\u53c2\u6570\uff0c\u5728\u8fde\u63a5\u8f74\u5411\u4e0a\u521b\u5efa\u4e00\u4e2a\u591a\u5c42\u7d22\u5f15\uff0c\u4ee5\u4fbf\u5728\u7ed3\u679c\u4e2d\u533a\u5206\u5404\u90e8\u5206 print(result) # one a 0 # b 1 # two c 2 # d 3 # e 4 # three f 5 # g 6 # dtype: int64 print(result.unstack()) # \u628a\u539f\u7d22\u5f15\u4f5c\u4e3a\u5217\u6807\u7b7e\u5c55\u5f00 # a b c d e f g # one 0.0 1.0 NaN NaN NaN NaN NaN # two NaN NaN 2.0 3.0 4.0 NaN NaN # three NaN NaN NaN NaN NaN 5.0 6.0 result = pd.concat([s1, s2, s3], axis=1) # \u5728\u8fd9\u4e2a\u6848\u4f8b\u4e2daxis=1\u8f74\u5411\u4e0a\u5e76\u6ca1\u6709\u91cd\u53e0 print(result) # 0 1 2 # a 0.0 NaN NaN # b 1.0 NaN NaN # c NaN 2.0 NaN # d NaN 3.0 NaN # e NaN 4.0 NaN # f NaN NaN 5.0 # g NaN NaN 6.0 result = pd.concat([s1, s2, s3], axis=1, keys=['one', 'two', 'three']) # \u5728\u8fd9\u4e2a\u6848\u4f8b\u4e2daxis=1\u8f74\u5411\u4e0a\u5e76\u6ca1\u6709\u91cd\u53e0 print(result) # one two three # a 0.0 NaN NaN # b 1.0 NaN NaN # c NaN 2.0 NaN # d NaN 3.0 NaN # e NaN 4.0 NaN # f NaN NaN 5.0 # g NaN NaN 6.0 print(result.unstack()) # \u5bf9\u6bd4axis=0\u7684\u591a\u5c42\u7d22\u5f15\uff0c\u5f53axis=1\u65f6\u5bf9\u8f93\u51fa\u5404index\u7684\u5e76\u96c6\u505a\u4e86\u5206\u7ec4\u3002 # one a 0.0 # b 1.0 # c NaN # d NaN # e NaN # f NaN # g NaN # two a NaN # b NaN # c 2.0 # d 3.0 # e 4.0 # f NaN # g NaN # three a NaN # b NaN # c NaN # d NaN # e NaN # f 5.0 # g 6.0 # dtype: float64 s4 = pd.concat([s1, s3]) print(s4) # a 0 # b 1 # f 5 # g 6 # dtype: int64 result = pd.concat([s1, s4]) print(result) # a 0 # b 1 # a 0 # b 1 # f 5 # g 6 # dtype: int64 result = pd.concat([s1, s4], axis=1) # \u73b0\u5728\u5728\u4e2daxis=1\u8f74\u5411\u4e0a\u6709\u91cd\u53e0 print(result) # 0 1 # a 0.0 0 # b 1.0 1 # f NaN 5 # g NaN 6 result = pd.concat([s1, s4], axis=1, keys=['one', 'two', 'three']) print(result) # one two # a 0.0 0 # b 1.0 1 # f NaN 5 # g NaN 6 result = pd.concat([s1, s4], axis=0, keys=['one', 'two', 'three']) # \u901a\u8fc7keys\u53c2\u6570\uff0c\u5728\u8fde\u63a5\u8f74\u5411\u4e0a\u521b\u5efa\u4e00\u4e2a\u591a\u5c42\u7d22\u5f15 print(result) # one a 0 # b 1 # two a 0 # b 1 # f 5 # g 6 # dtype: int64 result = pd.concat([s1, s4], axis=1, join='inner') # \u5185\u8fde\u63a5\u65b9\u5f0f\u5408\u5e76\u7d22\u5f15\uff08\u7d22\u5f15\u4ea4\u96c6\uff09 print(result) # 0 1 # a 0 0 # b 1 1 result = pd.concat([s1, s4], axis=1).reindex(['a', 'c', 'b', 'e']) # \u4f7f\u7528join_axes(\u5df2\u88ab\u66ff\u6362\u6210reindex)\u6765\u6307\u5b9a\u7528\u4e8e\u8fde\u63a5\u5176\u4ed6\u8f74\u5411\u7684\u8f74 print(result) # 0 1 # a 0.0 0.0 # c NaN NaN # b 1.0 1.0 # e NaN NaN \u57fa\u4e8eDataFrame\u7684pandas\u7684 concat \u51fd\u6570\u7684\u5de5\u4f5c\u673a\u5236\u5206\u6790\u3002 df1 = pd.DataFrame( np.arange(12).reshape((6, 2)), index=[ ['Ohio', 'Ohio', 'Ohio', 'Nevada', 'Nevada', 'Nevada'], [2000, 2001, 2002, 2000, 2001, 2002] ], columns=['event1', 'event2'] ) df2 = pd.DataFrame( np.arange(12).reshape((6, 2)), index=[ ['Ohio', 'Ohio', 'Ohio', 'Nevada', 'Nevada', 'Nevada'], [2000, 2001, 2002, 2000, 2001, 2002] ], columns=['event3', 'event4'] ) print(df1) # event1 event2 # Ohio 2000 0 1 # 2001 2 3 # 2002 4 5 # Nevada 2000 6 7 # 2001 8 9 # 2002 10 11 print(df2) # event3 event4 # Ohio 2000 0 1 # 2001 2 3 # 2002 4 5 # Nevada 2000 6 7 # 2001 8 9 # 2002 10 11 result = np.concatenate([df1, df2], axis=0) # \u6cbf0\u8f74\u62fc\u63a5 print(result) # [[ 0 1] # [ 2 3] # [ 4 5] # [ 6 7] # [ 8 9] # [10 11] # [ 0 1] # [ 2 3] # [ 4 5] # [ 6 7] # [ 8 9] # [10 11]] result = np.concatenate([df1, df2], axis=1) # \u6cbf1\u8f74\u62fc\u63a5 print(result) # [[ 0 1 0 1] # [ 2 3 2 3] # [ 4 5 4 5] # [ 6 7 6 7] # [ 8 9 8 9] # [10 11 10 11]] result = np.concatenate([df1, df2], axis=None) # \u5c06\u6570\u7ec4\u5c55\u5e73 print(result) # [ 0 1 2 3 4 5 6 7 8 9 10 11 0 1 2 3 4 5 6 7 8 9 10 11] \u8054\u5408\u91cd\u53e0\u6570\u636e \u00b6 \u53e6\u4e00\u4e2a\u6570\u636e\u8054\u5408\u573a\u666f\uff0c\u65e2\u4e0d\u662f\u5408\u5e76\u64cd\u4f5c\uff0c\u4e5f\u4e0d\u662f\u8fde\u63a5\u64cd\u4f5c\u3002 \u5047\u5982\u6709\u4e24\u4e2a\u6570\u636e\u96c6\uff0c\u8fd9\u4e24\u4e2a\u6570\u636e\u96c6\u7684\u7d22\u5f15\u5168\u90e8\u6216\u90e8\u5206\u91cd\u53e0\uff0c\u901a\u8fc7NumPy\u7684 where \u51fd\u6570\u53ef\u4ee5\u8fdb\u884c\u9762\u5411\u6570\u7ec4\u7684if-else\u7b49\u4ef7\u64cd\u4f5c\u3002 s1 = pd.Series( [np.nan, 2.5, 0.0, 3.5, 4.5, np.nan], index=['f', 'e', 'd', 'c', 'b', 'a'] ) s2 = pd.Series( [0.0, np.nan, 2.0, np.nan, np.nan, 5.0], index=['a', 'b', 'c', 'd', 'e', 'f'] ) print(s1) # f NaN # e 2.5 # d 0.0 # c 3.5 # b 4.5 # a NaN # dtype: float64 print(s2) # a 0.0 # b NaN # c 2.0 # d NaN # e NaN # f 5.0 # dtype: float64 \u65b9\u6cd51\uff0c\u901a\u8fc7Numpy\u7684 where \u51fd\u6570\u3002 result = np.where(pd.isnull(s1), s2, s1) # An array with elements from 'x'(s2) where 'condition'(isnull(s1)) is True, and elements from 'y'(s1) elsewhere. print(result) # [0. 2.5 0. 3.5 4.5 5. ] # s1 # s2 # result # f NaN # a 0.0 0. \u6761\u4ef6\u4e2ds1\u8be5\u5143\u7d20\u4e3anull\uff0c\u6240\u4ee5where\u51fd\u6570\u53d6\u5bf9\u5e94x(s2)\u7684\u5143\u7d20\uff08\u6ce8\u610f\uff0c\u4e0e\u7d22\u5f15\u987a\u5e8f\u65e0\u5173\uff09 # e 2.5 # b NaN 2.5 \u6761\u4ef6\u4e2ds1\u8be5\u5143\u7d20\u4e0d\u4e3anull\uff0c\u6240\u4ee5where\u51fd\u6570\u53d6\u5bf9\u5e94y(s1)\u7684\u5143\u7d20 # d 0.0 # c 2.0 0. # c 3.5 # d NaN 3.5 # b 4.5 # e NaN 4.5 # a NaN # f 5.0 5.0 \u6761\u4ef6\u4e2ds1\u8be5\u5143\u7d20\u4e3anull\uff0c\u6240\u4ee5where\u51fd\u6570\u53d6\u5bf9\u5e94x(s2)\u7684\u5143\u7d20 result = np.where(pd.isnull(s2), s1, s2) print(result) # [0. 2.5 2. 3.5 4.5 5. ] \u65b9\u6cd52\uff0c\u901a\u8fc7Series\u7684 combine_first \u65b9\u6cd5\u3002 result = s2.combine_first(s1) # \u6ce8\u610f\uff0ccombine_first\u662f\u6309\u7167s2\u7684\u7d22\u5f15\u987a\u5e8f\u68c0\u7d22\u7684\uff0c\u76f8\u540c\u7d22\u5f15\u7684s1\u7684\u503c\u4f1a\u586b\u5145\u5bf9\u5e94s2\u7684null print(result) # a 0.0 # b 4.5 # c 2.0 # d 0.0 # e 2.5 # f 5.0 # dtype: float64 \u65b9\u6cd53\uff1aPandas\u7684 combine_first \u65b9\u6cd5\u3002 df1 = pd.DataFrame( { 'a': [1.0, np.nan, 5.0, np.nan], 'b': [np.nan, 2.0, np.nan, 6.0], 'c': [2.0, 6.0, 10.0, 15.0] } ) df2 = pd.DataFrame( { 'a': [5.0, 4.0, np.nan, 3.0, 7.0], 'b': [np.nan, 3.0, 4.0, 6.0, 8.0] } ) print(df1) # a b c # 0 1.0 NaN 2.0 # 1 NaN 2.0 6.0 # 2 5.0 NaN 10.0 # 3 NaN 6.0 15.0 print(df2) # a b # 0 5.0 NaN # 1 4.0 3.0 # 2 NaN 4.0 # 3 3.0 6.0 # 4 7.0 8.0 result = df2.combine_first(df1) # \u7528df1\u7684\u503c\u53bb\u586b\u5145df2\u5bf9\u5e94\u7d22\u5f15\u4f4d\u7f6e\u7684null\u503c print(result) # a b c # 0 5.0 NaN 2.0 # 1 4.0 3.0 6.0 # 2 5.0 4.0 10.0 # 3 3.0 6.0 15.0 # 4 7.0 8.0 NaN \u91cd\u5851\u548c\u900f\u89c6 \u00b6 \u91cd\u65b0\u6392\u5217\u8868\u683c\u578b\u6570\u636e\u6709\u591a\u79cd\u57fa\u7840\u64cd\u4f5c\u3002\u8fd9\u4e9b\u64cd\u4f5c\u88ab\u79f0\u4e3a\u91cd\u5851\u6216\u900f\u89c6\u3002 import numpy as np import pandas as pd \u4f7f\u7528\u591a\u5c42\u7d22\u5f15\u8fdb\u884c\u91cd\u5851 \u00b6 \u591a\u5c42\u7d22\u5f15\u5728DataFrame\u4e2d\u63d0\u4f9b\u4e86\u4e00\u79cd\u4e00\u81f4\u6027\u65b9\u5f0f\u7528\u4e8e\u91cd\u6392\u5217\u6570\u636e\u3002\u4ee5\u4e0b\u662f\u4e24\u4e2a\u57fa\u7840\u64cd\u4f5c\uff1a statck\uff08\u5806\u53e0\uff09\u8be5\u64cd\u4f5c\u4f1a\u201c\u65cb\u8f6c\u201d\u6216\u5c06\u5217\u4e2d\u7684\u6570\u636e\u900f\u89c6\u5230\u884c\u3002 unstack\uff08\u62c6\u5806\uff09\u8be5\u64cd\u4f5c\u4f1a\u5c06\u884c\u4e2d\u7684\u6570\u636e\u900f\u89c6\u5230\u5217\u3002 df = pd.DataFrame( np.arange(6).reshape((2, 3)), index=pd.Index(['Ohio', 'Colorado'], name='state'), columns=pd.Index(['one', 'two', 'three'], name='number') ) print(df) # number one two three # state # Ohio 0 1 2 # Colorado 3 4 5 \u5728\u8fd9\u4efd\u6570\u636e\u4e0a\u4f7f\u7528stack\u65b9\u6cd5\u4f1a\u5c06\u5217\u900f\u89c6\u5230\u884c\uff0c\u4ea7\u751f\u4e00\u4e2a\u65b0\u7684Series\uff1a result = df.stack() print(result) # state number # Ohio one 0 # two 1 # three 2 # Colorado one 3 # two 4 # three 5 # dtype: int64 \u4ece\u4e00\u4e2a\u591a\u5c42\u7d22\u5f15\u5e8f\u5217\u4e2d\uff0c\u4f60\u53ef\u4ee5\u4f7f\u7528 unstack \u65b9\u6cd5\u5c06\u6570\u636e\u91cd\u6392\u5217\u540e\u653e\u5165\u4e00\u4e2aDataFrame\u4e2d\uff1a print(result.unstack()) # number one two three # state # Ohio 0 1 2 # Colorado 3 4 5 print(result.unstack(0)) # \u53ef\u4ee5\u4f20\u5165\u4e00\u4e2a\u5c42\u7ea7\u5e8f\u53f7\u6216\u540d\u79f0\u6765\u62c6\u5206\u4e00\u4e2a\u4e0d\u540c\u7684\u5c42\u7ea7 # state Ohio Colorado # number # one 0 3 # two 1 4 # three 2 5 print(result.unstack(1)) # number one two three # state # Ohio 0 1 2 # Colorado 3 4 5 print(result.unstack('state')) # \u8f93\u51fa\u7ed3\u679c\u548c\u4f20\u5165\u5c42\u7ea70\u4e00\u6837 # state Ohio Colorado # number # one 0 3 # two 1 4 # three 2 5 print(result.unstack('number')) # \u8f93\u51fa\u7ed3\u679c\u548c\u4f20\u5165\u5c42\u7ea71\u4e00\u6837 # number one two three # state # Ohio 0 1 2 # Colorado 3 4 5 \u5982\u679c\u5c42\u7ea7\u4e2d\u7684\u6240\u6709\u503c\u5e76\u672a\u5305\u542b\u4e8e\u6bcf\u4e2a\u5b50\u5206\u7ec4\u4e2d\u65f6\uff0c\u62c6\u5206\u53ef\u80fd\u4f1a\u5f15\u5165\u7f3a\u5931\u503c\uff1a s1 = pd.Series([0, 1, 2, 3], index=['a', 'b', 'c', 'd']) s2 = pd.Series([4, 5, 6], index=['c', 'd', 'e']) s3 = pd.concat([s1, s2], keys=['one', 'two']) print(s3) # one a 0 # b 1 # c 2 # d 3 # two c 4 # d 5 # e 6 # dtype: int64 print(s3.unstack(0)) # one two # a 0.0 NaN # b 1.0 NaN # c 2.0 4.0 # d 3.0 5.0 # e NaN 6.0 print(s3.unstack(1)) print(s3.unstack()) # a b c d e # one 0.0 1.0 2.0 3.0 NaN # two NaN NaN 4.0 5.0 6.0 \u9ed8\u8ba4\u60c5\u51b5\u4e0b\uff0c\u5806\u53e0\u4f1a\u8fc7\u6ee4\u51fa\u7f3a\u5931\u503c\uff0c\u56e0\u6b64\u5806\u53e0\u62c6\u5806\u7684\u64cd\u4f5c\u662f\u53ef\u9006\u7684\u3002 print(s3.unstack().stack()) # one a 0.0 # b 1.0 # c 2.0 # d 3.0 # two c 4.0 # d 5.0 # e 6.0 # dtype: float64 print(s3.unstack().stack(dropna=False)) # one a 0.0 # b 1.0 # c 2.0 # d 3.0 # e NaN # two a NaN # b NaN # c 4.0 # d 5.0 # e 6.0 # dtype: float64 \u5728DataFrame\u4e2d\u62c6\u5806\u65f6\uff0c\u88ab\u62c6\u5806\u7684\u5c42\u7ea7\u4f1a\u53d8\u4e3a\u7ed3\u679c\u4e2d\u6700\u4f4e\u7684\u5c42\u7ea7\u3002 \u5728\u8c03\u7528 stack \u65b9\u6cd5\u65f6\uff0c\u6211\u4eec\u53ef\u4ee5\u6307\u660e\u9700\u8981\u5806\u53e0\u7684\u8f74\u5411\u540d\u79f0\u3002 df = pd.DataFrame( {'left': result, 'right': result + 5}, columns=pd.Index(['left', 'right'], name='side') ) print(df) # side left right # state number # Ohio one 0 5 # two 1 6 # three 2 7 # Colorado one 3 8 # two 4 9 # three 5 10 print(df.unstack()) # side left right # number one two three one two three # state # Ohio 0 1 2 5 6 7 # Colorado 3 4 5 8 9 10 print(df.unstack('state')) # \u88ab\u62c6\u5806\u7684\u5c42\u7ea7(state)\u4f1a\u53d8\u4e3a\u7ed3\u679c\u4e2d\u6700\u4f4e\u7684\u5c42\u7ea7 # side left right # state Ohio Colorado Ohio Colorado # number # one 0 3 5 8 # two 1 4 6 9 # three 2 5 7 10 \u5728\u8c03\u7528 stack \u65b9\u6cd5\u65f6\uff0c\u53ef\u4ee5\u6307\u660e\u9700\u8981\u5806\u53e0\u7684\u8f74\u5411\u540d\u79f0\uff1a print(df.unstack('state').stack('side')) # state Colorado Ohio # number side # one left 3 0 # right 8 5 # two left 4 1 # right 9 6 # three left 5 2 # right 10 7 \u5c06\u201c\u957f\u201d\u900f\u89c6\u4e3a\u201c\u5bbd\u201d \u00b6 \u5728\u6570\u636e\u5e93\u548cCSV\u4e2d\u5b58\u50a8\u591a\u65f6\u95f4\u5e8f\u5217\u7684\u65b9\u5f0f\u5c31\u662f\u6240\u8c13\u7684\u957f\u683c\u5f0f\u6216\u5806\u53e0\u683c\u5f0f\u3002 data = pd.read_csv('../examples/macrodata.csv') print(data.head(3)) # year quarter realgdp realcons ... unemp pop infl realint # 0 1959.0 1.0 2710.349 1707.4 ... 5.8 177.146 0.00 0.00 # 1 1959.0 2.0 2778.801 1733.7 ... 5.1 177.830 2.34 0.74 # 2 1959.0 3.0 2775.488 1751.8 ... 5.3 178.657 2.74 1.09 # ...... # [3 rows x 14 columns] # PeriodIndex\u5c06year\u548cquarter\u7b49\u5217\u8fdb\u884c\u8054\u5408\u5e76\u751f\u6210\u4e86\u4e00\u79cd\u65f6\u95f4\u95f4\u9694\u7c7b\u578b periods = pd.PeriodIndex( year=data.year, quarter=data.quarter, name='date' ) columns = pd.Index( ['realgdp', 'infl', 'unemp'], name='item' ) data = data.reindex(columns=columns) print(data) # item realgdp infl unemp # 0 2710.349 0.00 5.8 # 1 2778.801 2.34 5.1 # 2 2775.488 2.74 5.3 # ...... # [203 rows x 3 columns] data.index = periods.to_timestamp('D', 'end') print(data.index) # DatetimeIndex(['1959-03-31 23:59:59.999999999', # '1959-06-30 23:59:59.999999999', # ... # '2009-06-30 23:59:59.999999999', # '2009-09-30 23:59:59.999999999'], # dtype='datetime64[ns]', name='date', length=203, freq=None) \u4e0b\u9762\u662fldata\u7684\u6570\u636e\u6837\u672c\u3002 \u8fd9\u79cd\u6570\u636e\u5373\u6240\u8c13\u7684\u591a\u65f6\u95f4\u5e8f\u5217\u7684\u957f\u683c\u5f0f\uff0c\u6216\u79f0\u4e3a\u5177\u6709\u4e24\u4e2a\u6216\u66f4\u591a\u4e2a\u952e\u7684\u5176\u4ed6\u89c2\u6d4b\u6570\u636e\uff08\u8fd9\u91cc\uff0c\u6211\u4eec\u7684\u952e\u662fdate\u548citem\uff09\u3002 \u8868\u4e2d\u7684\u6bcf\u4e00\u884c\u8868\u793a\u4e00\u4e2a\u65f6\u95f4\u70b9\u4e0a\u7684\u5355\u4e2a\u89c2\u6d4b\u503c\u3002 ldata = data.stack().reset_index().rename(columns={0: 'value'}) print(ldata) # date item value # 0 1959-03-31 23:59:59.999999999 realgdp 2710.349 # 1 1959-03-31 23:59:59.999999999 infl 0.000 # 2 1959-03-31 23:59:59.999999999 unemp 5.800 # 3 1959-06-30 23:59:59.999999999 realgdp 2778.801 # 4 1959-06-30 23:59:59.999999999 infl 2.340 # .. ... ... ... # 604 2009-06-30 23:59:59.999999999 infl 3.370 # 605 2009-06-30 23:59:59.999999999 unemp 9.200 # 606 2009-09-30 23:59:59.999999999 realgdp 12990.341 # 607 2009-09-30 23:59:59.999999999 infl 3.560 # 608 2009-09-30 23:59:59.999999999 unemp 9.600 # [609 rows x 3 columns] \u5728\u4e0a\u9762\u7684\u4f8b\u5b50\u4e2d\uff1a \u6570\u636e\u901a\u5e38\u4ee5\u8fd9\u79cd\u65b9\u5f0f\u5b58\u50a8\u5728\u5173\u7cfb\u578b\u6570\u636e\u5e93\u4e2d\uff0c\u6bd4\u5982MySQL\uff0c\u56e0\u4e3a\u56fa\u5b9a\u6a21\u5f0f\uff08\u5217\u540d\u79f0\u548c\u6570\u636e\u7c7b\u578b\uff09\u5141\u8bb8 item \u5217\u4e2d\u4e0d\u540c\u503c\u7684\u6570\u91cf\u968f\u7740\u6570\u636e\u88ab\u6dfb\u52a0\u5230\u8868\u4e2d\u800c\u6539\u53d8\u3002 date \u548c item \u901a\u5e38\u662f\u4e3b\u952e\uff08\u4f7f\u7528\u5173\u7cfb\u578b\u6570\u636e\u5e93\u7684\u8bf4\u6cd5\uff09\uff0c\u63d0\u4f9b\u4e86\u5173\u7cfb\u5b8c\u6574\u6027\u548c\u66f4\u7b80\u5355\u7684\u8fde\u63a5\u3002 \u5728\u67d0\u4e9b\u60c5\u51b5\u4e0b\uff0c\u5904\u7406\u8fd9\u79cd\u683c\u5f0f\u7684\u6570\u636e\u66f4\u4e3a\u56f0\u96be\u3002\u53ef\u80fd\u66f4\u503e\u5411\u4e8e\u83b7\u53d6\u4e00\u4e2a\u6309 date \u5217\u65f6\u95f4\u6233\u7d22\u5f15\u7684\u4e14\u6bcf\u4e2a\u4e0d\u540c\u7684 item \u72ec\u7acb\u4e00\u5217\u7684DataFrame\u3002 DataFrame\u7684pivot\u65b9\u6cd5\u5c31\u662f\u8fdb\u884c\u8fd9\u79cd\u8f6c\u6362\u7684\uff1a \u4e0b\u9762\u4f8b\u5b50\u4e2d\uff0c\u4f20\u9012\u7684\u524d\u4e24\u4e2a\u503c\u662f\u5206\u522b\u7528\u4f5c\u884c\u548c\u5217\u7d22\u5f15\u7684\u5217\uff0c\u7136\u540e\u662f\u53ef\u9009\u7684\u6570\u503c\u5217\u4ee5\u586b\u5145DataFrame\u3002 \u6ce8\u610f\uff0c pivot \u65b9\u6cd5\u7b49\u4ef7\u4e8e\u4f7f\u7528 set_index \u521b\u5efa\u5206\u5c42\u7d22\u5f15\uff0c\u7136\u540e\u8c03\u7528unstack\u3002 pivoted = ldata.pivot('date', 'item', 'value') print(pivoted) # item infl realgdp unemp # date # 1959-03-31 23:59:59.999999999 0.00 2710.349 5.8 # 1959-06-30 23:59:59.999999999 2.34 2778.801 5.1 # ... ... ... ... # 2009-06-30 23:59:59.999999999 3.37 12901.504 9.2 # 2009-09-30 23:59:59.999999999 3.56 12990.341 9.6 # [203 rows x 3 columns] ldata['value2'] = np.random.randn(len(ldata)) print(ldata[:5]) # date item value value2 # 0 1959-03-31 23:59:59.999999999 realgdp 2710.349 -1.268405 # 1 1959-03-31 23:59:59.999999999 infl 0.000 0.377691 # 2 1959-03-31 23:59:59.999999999 unemp 5.800 -0.342492 # 3 1959-06-30 23:59:59.999999999 realgdp 2778.801 0.132797 # 4 1959-06-30 23:59:59.999999999 infl 2.340 0.180290 \u6b64\u65f6 ldata \u5df2\u7ecf\u6dfb\u52a0\u4e86\u4e00\u5217\u3002\u5982\u679c\u9057\u6f0f\u6700\u540e\u4e00\u4e2a\u53c2\u6570\uff0c\u4f1a\u5f97\u5230\u4e00\u4e2a\u542b\u6709\u591a\u5c42\u5217\u7684DataFrame\uff0c\u5982\u4e0b\uff1a pivoted = ldata.pivot('date', 'item') print(pivoted) # value ... value2 # item infl realgdp ... realgdp unemp # date ... # 1959-03-31 23:59:59.999999999 0.00 2710.349 ... 0.157467 -0.222464 # 1959-06-30 23:59:59.999999999 2.34 2778.801 ... 0.861501 0.368855 # ... ... ... ... ... ... # 2009-06-30 23:59:59.999999999 3.37 12901.504 ... 0.279988 0.934972 # 2009-09-30 23:59:59.999999999 3.56 12990.341 ... 0.547914 1.842967 # [203 rows x 6 columns] \u6ce8\u610f\uff0c pivot \u65b9\u6cd5\u7b49\u4ef7\u4e8e\u4f7f\u7528 set_index \u521b\u5efa\u5206\u5c42\u7d22\u5f15\uff0c\u7136\u540e\u8c03\u7528 unstack \u3002 unstacked = ldata.set_index(['date', 'item']).unstack('item') print(unstacked[:5]) # value ... value2 # item infl realgdp ... realgdp unemp # date ... # 1959-03-31 23:59:59.999999999 0.00 2710.349 ... 0.213120 -0.248004 # 1959-06-30 23:59:59.999999999 2.34 2778.801 ... 0.697763 0.112388 # 1959-09-30 23:59:59.999999999 2.74 2775.488 ... 1.291884 -1.046142 # 1959-12-31 23:59:59.999999999 0.27 2785.204 ... 0.363339 -0.307364 # 1960-03-31 23:59:59.999999999 2.31 2847.699 ... 0.377330 2.272980 # [5 rows x 6 columns] \u5c06\u201c\u5bbd\u201d\u900f\u89c6\u4e3a\u201c\u957f\u201d \u00b6 \u5728DataFrame\u4e2d\uff0cpivot\u65b9\u6cd5\u7684\u53cd\u64cd\u4f5c\u662f pandas.melt \u3002 \u4e0e\u5c06\u4e00\u5217\u53d8\u6362\u4e3a\u65b0\u7684DataFrame\u4e2d\u7684\u591a\u5217\u4e0d\u540c\uff0c\u5b83\u5c06\u591a\u5217\u5408\u5e76\u6210\u4e00\u5217\uff0c\u4ea7\u751f\u4e00\u4e2a\u65b0\u7684DataFrame\uff0c\u5176\u957f\u5ea6\u6bd4\u8f93\u5165\u66f4\u957f\u3002 df = pd.DataFrame( { 'key': ['foo', 'bar', 'baz'], 'A': [1, 2, 3], 'B': [4, 5, 6], 'C': [7, 8, 9] } ) print(df) # key A B C # 0 foo 1 4 7 # 1 bar 2 5 8 # 2 baz 3 6 9 key \u5217\u53ef\u4ee5\u4f5c\u4e3a\u5206\u7ec4\u6307\u6807\uff0c\u5176\u4ed6\u5217\u5747\u4e3a\u6570\u636e\u503c\u3002 \u5f53\u4f7f\u7528 pandas.melt \u65f6\uff0c\u6211\u4eec\u5fc5\u987b\u6307\u660e\u54ea\u4e9b\u5217\u662f\u5206\u7ec4\u6307\u6807\uff08\u5982\u679c\u6709\u7684\u8bdd\uff09\u3002 \u6b64\u5904\uff0c\u8ba9\u6211\u4eec\u4f7f\u7528 key \u4f5c\u4e3a\u552f\u4e00\u7684\u5206\u7ec4\u6307\u6807\uff1a melted = pd.melt(df, ['key']) print(melted) # key variable value # 0 foo A 1 # 1 bar A 2 # 2 baz A 3 # 3 foo B 4 # 4 bar B 5 # 5 baz B 6 # 6 foo C 7 # 7 bar C 8 # 8 baz C 9 \u4f7f\u7528 pivot \u65b9\u6cd5\uff0c\u6211\u4eec\u53ef\u4ee5\u5c06\u6570\u636e\u91cd\u5851\u56de\u539f\u5148\u7684\u5e03\u5c40\u3002 reshaped = melted.pivot('key', 'variable', 'value') print(reshaped) # variable A B C # key # bar 2 5 8 # baz 3 6 9 # foo 1 4 7 \u7531\u4e8e pivot \u7684\u7ed3\u679c\u6839\u636e\u4f5c\u4e3a\u884c\u6807\u7b7e\u7684\u5217\u751f\u6210\u4e86\u7d22\u5f15\uff0c\u53ef\u4f7f\u7528 reset_index \u6765\u5c06\u6570\u636e\u56de\u79fb\u4e00\u5217\uff1a print(reshaped.reset_index()) # variable key A B C # 0 bar 2 5 8 # 1 baz 3 6 9 # 2 foo 1 4 7 pandas.melt \u7684\u4f7f\u7528\u4e5f\u53ef\u4ee5\u65e0\u987b\u4efb\u4f55\u5206\u7ec4\u6307\u6807\u3002 result = pd.melt(df, value_vars=['A', 'B', 'C']) print(result) # variable value # 0 A 1 # 1 A 2 # 2 A 3 # 3 B 4 # 4 B 5 # 5 B 6 # 6 C 7 # 7 C 8 # 8 C 9 result = pd.melt(df, value_vars=['key', 'B', 'C']) print(result) # variable value # 0 key foo # 1 key bar # 2 key baz # 3 B 4 # 4 B 5 # 5 B 6 # 6 C 7 # 7 C 8 # 8 C 9","title":"\u6570\u636e\u89c4\u6574\uff1a\u8fde\u63a5\u3001\u8054\u5408\u4e0e\u91cd\u5851"},{"location":"python/DataAnalysis/ch05/#_1","text":"","title":"\u6570\u636e\u89c4\u6574\uff1a\u8fde\u63a5\u3001\u8054\u5408\u4e0e\u91cd\u5851"},{"location":"python/DataAnalysis/ch05/#_2","text":"import pandas as pd import numpy as np import re \u5206\u5c42\u7d22\u5f15\u662fpandas\u7684\u91cd\u8981\u7279\u6027\uff0c\u5141\u8bb8\u4f60\u5728\u4e00\u4e2a\u8f74\u5411\u4e0a\u62e5\u6709\u591a\u4e2a\uff08\u4e24\u4e2a\u6216\u4e24\u4e2a\u4ee5\u4e0a\uff09\u7d22\u5f15\u5c42\u7ea7\u3002 \u5206\u5c42\u7d22 import re \u5f15\u63d0\u4f9b\u4e86\u4e00\u79cd\u5728\u66f4\u4f4e\u7ef4\u5ea6\u7684\u5f62\u5f0f\u4e2d\u5904\u7406\u66f4\u9ad8\u7ef4\u5ea6\u6570\u636e\u7684\u65b9\u5f0f\u3002","title":"\u5206\u5c42\u7d22\u5f15"},{"location":"python/DataAnalysis/ch05/#series","text":"data = pd.Series( np.random.randn(9), index=[['a', 'a', 'a', 'b', 'b', 'c', 'c', 'd', 'd'], [1, 2, 3, 1, 3, 1, 2, 2, 3]] ) \u8f93\u51fa\u662f\u4e00\u4e2a\u4ee5 MultiIndex \u4f5c\u4e3a\u7d22\u5f15\u7684Series\u7684\u7f8e\u5316\u89c6\u56fe\u3002 \u7d22\u5f15\u4e2d\u7684\"\u95f4\u9699\"\u8868\u793a\"\u76f4\u63a5\u4f7f\u7528\u4e0a\u9762\u7684\u6807\u7b7e\"\u3002 print(data) # a 1 0.163468 # 2 -1.525926 # 3 -0.210247 # b 1 -0.956063 # 3 -1.839111 # c 1 -0.398905 # 2 0.595279 # d 2 0.034305 # 3 -0.896078 # dtype: float64 print(data.index) # MultiIndex([('a', 1), # ('a', 2), # ('a', 3), # ('b', 1), # ('b', 3), # ('c', 1), # ('c', 2), # ('d', 2), # ('d', 3)], # ) \u901a\u8fc7\u5206\u5c42\u7d22\u5f15\u5bf9\u8c61\uff0c\u4e5f\u53ef\u4ee5\u79f0\u4e3a\u90e8\u5206\u7d22\u5f15\uff0c\u53ef\u4ee5\u7b80\u6d01\u5730\u9009\u62e9\u51fa\u6570\u636e\u7684\u5b50\u96c6\u3002 m = data['b'] print(m) # 1 -0.956063 # 3 -1.839111 # dtype: float64 m = data['b': 'c'] print(m) # b 1 -0.956063 # 3 -1.839111 # c 1 -0.398905 # 2 0.595279 # dtype: float64 m = data.loc[['b', 'c']] print(m) # b 1 -0.956063 # 3 -1.839111 # c 1 -0.398905 # 2 0.595279 # dtype: float64 m = data.loc[:, 2] print(m) # a -1.525926 # c 0.595279 # d 0.034305 # dtype: float64 \u5206\u5c42\u7d22\u5f15\u5728\u91cd\u5851\u6570\u636e\u548c\u6570\u7ec4\u900f\u89c6\u8868\u7b49\u5206\u7ec4\u64cd\u4f5c\u4e2d\u626e\u6f14\u4e86\u91cd\u8981\u89d2\u8272\u3002 \u4f8b\u5982\uff0c\u4f60\u53ef\u4ee5\u4f7f\u7528 unstack \u65b9\u6cd5\u5c06\u6570\u636e\u5728DataFrame\u4e2d\u91cd\u65b0\u6392\u5217\u3002 m = data.unstack() print(m) # 1 2 3 # a 0.163468 -1.525926 -0.210247 # b -0.956063 NaN -1.839111 # c -0.398905 0.595279 NaN # d NaN 0.034305 -0.896078 n = m.stack() print(n) # \u6216\u8005 print(data.unstack().stack()) # a 1 0.163468 # 2 -1.525926 # 3 -0.210247 # b 1 -0.956063 # 3 -1.839111 # c 1 -0.398905 # 2 0.595279 # d 2 0.034305 # 3 -0.896078 # dtype: float64","title":"Series\u7d22\u5f15\u5206\u5c42"},{"location":"python/DataAnalysis/ch05/#dataframe","text":"\u5728DataFrame\u4e2d\uff0c\u6bcf\u4e2a\u8f74\u90fd\u53ef\u4ee5\u62e5\u6709\u5206\u5c42\u7d22\u5f15\u3002 \u53c2\u8003","title":"DataFrame\u7d22\u5f15\u5206\u5c42"},{"location":"python/DataAnalysis/ch05/#1","text":"\u76f4\u63a5\u901a\u8fc7\u7ed9 index \uff08columns\uff09\u53c2\u6570\u4f20\u9012\u591a\u7ef4\u6570\u7ec4\uff0c\u8fdb\u800c\u6784\u5efa\u591a\u7ef4\u7d22\u5f15\u3002 \u6570\u7ec4\u4e2d\u6bcf\u4e2a\u7ef4\u5ea6\u5bf9\u5e94\u4f4d\u7f6e\u7684\u5143\u7d20\uff0c\u7ec4\u6210\u6bcf\u4e2a\u7d22\u5f15\u503c\u3002 frame = pd.DataFrame( np.arange(12).reshape((4, 3)), index=[['a', 'a', 'b', 'b'], [1, 2, 1, 2]], columns=[['Ohio', 'Ohio', 'Colorado'], ['Green', 'Red', 'Green']] ) print(frame) # Ohio Colorado # Green Red Green # a 1 0 1 2 # 2 3 4 5 # b 1 6 7 8 # 2 9 10 11 \u4e0a\u9762\u8f93\u51fa\u4e2d\u76842\u4e2a\u5c42\u7ea7\u662f\u6ca1\u6709\u540d\u5b57\u3002 \u5206\u5c42\u7684\u5c42\u7ea7\u53ef\u4ee5\u6709\u540d\u79f0\uff08\u53ef\u4ee5\u662f\u5b57\u7b26\u4e32\u6216Python\u5bf9\u8c61\uff09\u3002 \u5982\u679c\u5c42\u7ea7\u6709\u540d\u79f0\uff0c\u8fd9\u4e9b\u540d\u79f0\u4f1a\u5728\u63a7\u5236\u53f0\u8f93\u51fa\u4e2d\u663e\u793a\u3002 print(frame.index.names) # [None, None] print(frame.columns.names) # [None, None] \u7ed9\u5c42\u7ea7\u8d4b\u4e88\u540d\u79f0\u3002\u6ce8\u610f\u533a\u5206\u884c\u6807\u7b7e\u4e2d\u7684\u7d22\u5f15\u540d\u79f0 state \u548c color \u3002 frame.index.names = ['key1', 'key2'] frame.columns.names = ['state', 'color'] print(frame) # state Ohio Colorado # color Green Red Green # key1 key2 # a 1 0 1 2 # 2 3 4 5 # b 1 6 7 8 # 2 9 10 11 print(frame['Ohio']) # color Green Red # key1 key2 # a 1 0 1 # 2 3 4 # b 1 6 7 # 2 9 10 print(frame.index) # MultiIndex([('a', 1), # ('a', 2), # ('b', 1), # ('b', 2)], # names=['key1', 'key2']) \u901a\u8fc7 MultiIndex \u7c7b\u7684\u76f8\u5173\u65b9\u6cd5\uff0c\u9884\u5148\u521b\u5efa\u4e00\u4e2a MultiIndex \u5bf9\u8c61\uff0c\u7136\u540e\u4f5c\u4e3aSeries\u4e0eDataFrame\u4e2d\u7684 index \uff08\u6216columns\uff09\u53c2\u6570\u503c\u3002\u540c\u65f6\uff0c\u53ef\u4ee5\u901a\u8fc7 names \u53c2\u6570\u6307\u5b9a\u591a\u5c42\u7d22\u5f15\u7684\u540d\u79f0\u3002","title":"\u65b9\u6cd51\uff1a\u76f4\u63a5\u521b\u5efa"},{"location":"python/DataAnalysis/ch05/#2from_arrays","text":"from_arrays \uff1a\u63a5\u6536\u4e00\u4e2a\u591a\u7ef4\u6570\u7ec4\u53c2\u6570\uff0c\u9ad8\u7ef4\u6307\u5b9a\u9ad8\u5c42\u7d22\u5f15\uff0c\u4f4e\u7ef4\u6307\u5b9a\u5e95\u5c42\u7d22\u5f15\u3002 mindex = pd.MultiIndex.from_arrays( [['a', 'a', 'b', 'b'], [1, 2, 1, 2]], names=['key1', 'key2'] ) frame = pd.DataFrame( np.arange(12).reshape((4, 3)), index=mindex, columns=[['Ohio', 'Ohio', 'Colorado'], ['Green', 'Red', 'Green']] ) frame.columns.names = ['state', 'color'] print(frame) # state Ohio Colorado # color Green Red Green # key1 key2 # a 1 0 1 2 # 2 3 4 5 # b 1 6 7 8 # 2 9 10 11","title":"\u65b9\u6cd52\uff1afrom_arrays"},{"location":"python/DataAnalysis/ch05/#3from_tuples","text":"from_tuples \uff1a\u63a5\u6536\u4e00\u4e2a\u5143\u7ec4\u7684\u5217\u8868\uff0c\u6bcf\u4e2a\u5143\u7ec4\u6307\u5b9a\u6bcf\u4e2a\u7d22\u5f15\uff08\u9ad8\u7ef4\u7d22\u5f15\uff0c\u4f4e\u7ef4\u7d22\u5f15\uff09\u3002 mindex = pd.MultiIndex.from_tuples( [('a', 1), ('a', 2), ('b', 1), ('b', 2)] ) frame = pd.DataFrame( np.arange(12).reshape((4, 3)), index=mindex, columns=[['Ohio', 'Ohio', 'Colorado'], ['Green', 'Red', 'Green']] ) frame.index.names = ['key1', 'key2'] frame.columns.names = ['state', 'color'] print(frame) # state Ohio Colorado # color Green Red Green # key1 key2 # a 1 0 1 2 # 2 3 4 5 # b 1 6 7 8 # 2 9 10 11","title":"\u65b9\u6cd53\uff1afrom_tuples"},{"location":"python/DataAnalysis/ch05/#4from_product","text":"from_product \uff1a\u63a5\u6536\u4e00\u4e2a\u53ef\u8fed\u4ee3\u5bf9\u8c61\u7684\u5217\u8868\uff0c\u6839\u636e\u591a\u4e2a\u53ef\u8fed\u4ee3\u5bf9\u8c61\u5143\u7d20\u7684\u7b1b\u5361\u5c14\u79ef\u8fdb\u884c\u521b\u5efa\u7d22\u5f15\u3002 \u4f7f\u7528\u7b1b\u5361\u5c14\u79ef\u7684\u65b9\u5f0f\u6765\u521b\u5efa\u591a\u5c42\u7d22\u5f15\u3002\u53c2\u6570\u4e3a\u5d4c\u5957\u7684\u53ef\u8fed\u4ee3\u5bf9\u8c61\u3002\u7ed3\u679c\u4e3a\u4f7f\u7528\u6bcf\u4e2a\u4e00\u7ef4\u6570\u7ec4\u4e2d\u7684\u5143\u7d20\u4e0e\u5176\u4ed6\u4e00\u7ef4\u6570\u7ec4\u4e2d\u7684\u5143\u7d20\u6765\u751f\u6210\u3002 \u7b1b\u5361\u5c14\u79ef\u7684\u65b9\u5f0f\u7684\u5c40\u9650\uff1a\u4e24\u4e24\u7ec4\u5408\u5fc5\u987b\u90fd\u5b58\u5728\uff0c\u5426\u5219\uff0c\u5c31\u4e0d\u80fd\u4f7f\u7528\u8fd9\u79cd\u65b9\u5f0f\u3002 mindex = pd.MultiIndex.from_product( [['a', 'b'], ['1', '2']], names=['key1', 'key2'] ) frame = pd.DataFrame( np.arange(12).reshape((4, 3)), index=mindex, columns=[['Ohio', 'Ohio', 'Colorado'], ['Green', 'Red', 'Green']] ) frame.columns.names = ['state', 'color'] print(frame) # state Ohio Colorado # color Green Red Green # key1 key2 # a 1 0 1 2 # 2 3 4 5 # b 1 6 7 8 # 2 9 10 11","title":"\u65b9\u6cd54\uff1afrom_product"},{"location":"python/DataAnalysis/ch05/#_3","text":"\u5982\u679c\u9700\u8981\u91cd\u65b0\u6392\u5217\u8f74\u4e0a\u7684\u5c42\u7ea7\u987a\u5e8f\uff0c\u6216\u8005\u6309\u7167\u7279\u5b9a\u5c42\u7ea7\u7684\u503c\u5bf9\u6570\u636e\u8fdb\u884c\u6392\u5e8f\uff0c \u53ef\u4ee5\u901a\u8fc7swaplevel\u63a5\u6536\u4e24\u4e2a\u5c42\u7ea7\u5e8f\u53f7\u6216\u5c42\u7ea7\u540d\u79f0\uff0c\u8fd4\u56de\u4e00\u4e2a\u8fdb\u884c\u4e86\u5c42\u7ea7\u53d8\u66f4\u7684\u65b0\u5bf9\u8c61\uff08\u4f46\u662f\u6570\u636e\u662f\u4e0d\u53d8\u7684\uff09\u3002 print(frame) # state Ohio Colorado # color Green Red Green # key1 key2 # a 1 0 1 2 # 2 3 4 5 # b 1 6 7 8 # 2 9 10 11 m = frame.swaplevel('key1', 'key2') print(m) # state Ohio Colorado # color Green Red Green # key2 key1 # 1 a 0 1 2 # 2 a 3 4 5 # 1 b 6 7 8 # 2 b 9 10 11 sort_index \u53ea\u80fd\u5728\u5355\u4e00\u5c42\u7ea7\u4e0a\u5bf9\u6570\u636e\u8fdb\u884c\u6392\u5e8f\u3002 \u5728\u8fdb\u884c\u5c42\u7ea7\u53d8\u6362\u65f6\uff0c\u4f7f\u7528 sort_index \u4ee5\u4f7f\u5f97\u7ed3\u679c\u6309\u7167\u5c42\u7ea7\u8fdb\u884c\u5b57\u5178\u6392\u5e8f\u3002 m = frame.sort_index(level=1) # \u5bf9key2\u6392\u5e8f\uff0c\u5e95\u5c42\u7d22\u5f15 print(m) # state Ohio Colorado # color Green Red Green # key1 key2 # a 1 0 1 2 # b 1 6 7 8 # a 2 3 4 5 # b 2 9 10 11 m = frame.sort_index(level=0) # \u5bf9key1\u6392\u5e8f\uff0c\u9ad8\u5c42\u7d22\u5f15 print(m) # state Ohio Colorado # color Green Red Green # key1 key2 # a 1 0 1 2 # 2 3 4 5 # b 1 6 7 8 # 2 9 10 11 m = frame.swaplevel(0, 1).sort_index(level=1) # swaplevel(0, 1)\u7b49\u540c\u4e8eswaplevel(key1, key2)\uff0c\u4ea4\u6362\u540ekey1\u53d8\u6210\u4e86\u5e95\u5c42\u7d22\u5f15 print(m) # state Ohio Colorado # color Green Red Green # key2 key1 # 1 a 0 1 2 # 2 a 3 4 5 # 1 b 6 7 8 # 2 b 9 10 11","title":"\u91cd\u6392\u5e8f\u548c\u5c42\u7ea7\u6392\u5e8f"},{"location":"python/DataAnalysis/ch05/#_4","text":"DataFrame\u548cSeries\u4e2d\u5f88\u591a\u63cf\u8ff0\u6027\u548c\u6c47\u603b\u6027\u7edf\u8ba1\u6709\u4e00\u4e2a level \u9009\u9879\uff0c\u901a\u8fc7 level \u9009\u9879\u4f60\u53ef\u4ee5\u6307\u5b9a\u4f60\u60f3\u8981\u5728\u67d0\u4e2a\u7279\u5b9a\u7684\u8f74\u4e0a\u8fdb\u884c\u805a\u5408\u3002 print(frame) # state Ohio Colorado # color Green Red Green # key1 key2 # a 1 0 1 2 # 2 3 4 5 # b 1 6 7 8 # 2 9 10 11 m = frame.groupby(level='key2').sum() print(m) # state Ohio Colorado # color Green Red Green # key2 # 1 6 8 10 # 2 12 14 16 m = frame.groupby(level='color', axis=1).sum() print(m) # color Green Red # key1 key2 # a 1 2 1 # 2 8 4 # b 1 14 7 # 2 20 10","title":"\u6309\u5c42\u7ea7\u8fdb\u884c\u6c47\u603b\u7edf\u8ba1"},{"location":"python/DataAnalysis/ch05/#dataframe_1","text":"\u901a\u5e38\u6211\u4eec\u4e0d\u4f1a\u4f7f\u7528DataFrame\u4e2d\u4e00\u4e2a\u6216\u591a\u4e2a\u5217\u4f5c\u4e3a\u884c\u7d22\u5f15\uff1b\u53cd\u800c\u4f60\u53ef\u80fd\u60f3\u8981\u5c06\u884c\u7d22\u5f15\u79fb\u52a8\u5230DataFrame\u7684\u5217\u4e2d\u3002 frame = pd.DataFrame( {'a': range(7), 'b': range(7, 0, -1), 'c': ['one', 'one', 'one', 'two', 'two', 'two', 'two'], 'd': [0, 1, 2, 0, 1, 2, 3] } ) print(frame) # a b c d # 0 0 7 one 0 # 1 1 6 one 1 # 2 2 5 one 2 # 3 3 4 two 0 # 4 4 3 two 1 # 5 5 2 two 2 # 6 6 1 two 3 DataFrame\u7684 set_index \u51fd\u6570\u4f1a\u751f\u6210\u4e00\u4e2a\u65b0\u7684DataFrame\uff0c\u65b0\u7684DataFrame\u4f7f\u7528\u4e00\u4e2a\u6216\u591a\u4e2a\u5217\u4f5c\u4e3a\u7d22\u5f15\u3002 \u9ed8\u8ba4\u60c5\u51b5\u4e0b\u8fd9\u4e9b\u7d22\u5f15\u5217\u4f1a\u4eceDataFrame\u4e2d\u79fb\u9664\uff0c\u4e5f\u53ef\u4ee5\u5c06\u5b83\u4eec\u7559\u5728DataFrame\u4e2d\u3002 frame2 = frame.set_index(['c', 'd'], drop=False) print(frame2) # a b c d # c d # one 0 0 7 one 0 # 1 1 6 one 1 # 2 2 5 one 2 # two 0 3 4 two 0 # 1 4 3 two 1 # 2 5 2 two 2 # 3 6 1 two 3 frame2 = frame.set_index(['c', 'd']) print(frame2) # a b # c d # one 0 0 7 # 1 1 6 # 2 2 5 # two 0 3 4 # 1 4 3 # 2 5 2 # 3 6 1 reset_index \u662f set_index \u7684\u53cd\u64cd\u4f5c\uff0c\u5206\u5c42\u7d22\u5f15\u7684\u7d22\u5f15\u5c42\u7ea7\u4f1a\u88ab\u79fb\u52a8\u5230\u5217\u4e2d\u3002 \u6ce8\u610f\uff1a\u5982\u679c\u5728 set_index \u65f6\u4f7f\u7528\u4e86 drop=False \uff0c\u5728\u4f7f\u7528 reset_index \u4f1a\u62a5\u9519\u3002 m = frame2.reset_index() print(m) # c d a b # 0 one 0 0 7 # 1 one 1 1 6 # 2 one 2 2 5 # 3 two 0 3 4 # 4 two 1 4 3 # 5 two 2 5 2 # 6 two 3 6 1","title":"\u4f7f\u7528DataFrame\u7684\u5217\u8fdb\u884c\u7d22\u5f15"},{"location":"python/DataAnalysis/ch05/#_5","text":"\u5305\u542b\u5728pandas\u5bf9\u8c61\u7684\u6570\u636e\u53ef\u4ee5\u901a\u8fc7\u591a\u79cd\u65b9\u5f0f\u8054\u5408\u5728\u4e00\u8d77\uff1a pandas.merge \u6839\u636e\u4e00\u4e2a\u6216\u591a\u4e2a\u952e\u5c06\u884c\u8fdb\u884c\u8fde\u63a5\u3002\u5bf9\u4e8eSQL\u6216\u5176\u4ed6\u5173\u7cfb\u578b\u6570\u636e\u5e93\u7684\u7528\u6237\u6765\u8bf4\uff0c\u8fd9\u79cd\u65b9\u5f0f\u6bd4\u8f83\u719f\u6089\uff0c\u5b83\u5b9e\u73b0\u7684\u662f\u6570\u636e\u5e93\u7684\u8fde\u63a5\u64cd\u4f5c\u3002 pandas.concat \u4f7f\u5bf9\u8c61\u5728\u8f74\u5411\u4e0a\u8fdb\u884c\u9ecf\u5408\u6216\u201c\u5806\u53e0\u201d\u3002 combine_first \u5b9e\u4f8b\u65b9\u6cd5\u5141\u8bb8\u5c06\u91cd\u53e0\u7684\u6570\u636e\u62fc\u63a5\u5728\u4e00\u8d77\uff0c\u4ee5\u4f7f\u7528\u4e00\u4e2a\u5bf9\u8c61\u4e2d\u7684\u503c\u586b\u5145\u53e6\u4e00\u4e2a\u5bf9\u8c61\u4e2d\u7684\u7f3a\u5931\u503c\u3002","title":"\u8054\u5408\u4e0e\u5408\u5e76\u6570\u636e\u96c6"},{"location":"python/DataAnalysis/ch05/#dataframe_2","text":"\u5408\u5e76\u6216\u8fde\u63a5\u64cd\u4f5c\u901a\u8fc7\u4e00\u4e2a\u6216\u591a\u4e2a\u952e\u8fde\u63a5\u884c\u6765\u8054\u5408\u6570\u636e\u96c6\u3002 \u8fd9\u4e9b\u64cd\u4f5c\u662f\u5173\u7cfb\u578b\u6570\u636e\u5e93\u7684\u6838\u5fc3\u5185\u5bb9\uff08\u4f8b\u5982\u57fa\u4e8eSQL\u7684\u6570\u636e\u5e93\uff09\u3002 pandas\u4e2d\u7684 merge \u51fd\u6570\u4e3b\u8981\u7528\u4e8e\u5c06\u5404\u79cd join \u64cd\u4f5c\u7b97\u6cd5\u8fd0\u7528\u5728\u6570\u636e\u4e0a\u3002 \u5728\u8fdb\u884c\u5217-\u5217\u8fde\u63a5\u65f6\uff0c\u4f20\u9012\u7684DataFrame\u7d22\u5f15\u5bf9\u8c61\u4f1a\u88ab\u4e22\u5f03\u3002 \u5408\u5e76\u64cd\u4f5c\u4e5f\u8981\u8003\u8651\u5982\u4f55\u5904\u7406\u91cd\u53e0\u7684\u5217\u540d( suffixes \u540e\u7f00\u9009\u9879)\u3002 \u4e0b\u9762\u662f\u4e00\u4e2a\u591a\u5bf9\u4e00\u8fde\u63a5\u7684\u4f8b\u5b50\u3002 df1 \u7684\u6570\u636e\u6709\u591a\u4e2a\u884c\u7684\u6807\u7b7e\u4e3a a \u548c b \uff0c\u800c df2 \u5728 key \u5217\u4e2d\u6bcf\u4e2a\u503c\u4ec5\u6709\u4e00\u884c\u3002 df1 = pd.DataFrame( { 'key': ['b', 'b', 'a', 'c', 'a', 'a', 'b'], 'data1': range(7) } ) df2 = pd.DataFrame( { 'key': ['a', 'b', 'd'], 'data1': range(3) } ) print(df1) # key data1 # 0 b 0 # 1 b 1 # 2 a 2 # 3 c 3 # 4 a 4 # 5 a 5 # 6 b 6 print(df2) # key data1 # 0 a 0 # 1 b 1 # 2 d 2 \u8c03\u7528 merge \u5904\u7406\uff0c\u63a8\u8350\u663e\u5f0f\u5730\u6307\u5b9a\u8fde\u63a5\u952e\u3002 result = pd.merge(df1, df2) print(result) # key data1 # 0 b 1 result = pd.merge(df1, df2, on=['key', 'data1']) print(result) # key data1 # 0 b 1 result = pd.merge(df1, df2, on='key') print(result) # key data1_x data1_y # 0 b 0 1 # 1 b 1 1 # 2 b 6 1 # 3 a 2 0 # 4 a 4 0 # 5 a 5 0 \u5982\u679c\u6bcf\u4e2a\u5bf9\u8c61\u7684\u5217\u540d\u662f\u4e0d\u540c\u7684\uff0c\u53ef\u4ee5\u5206\u522b\u4e3a\u5b83\u4eec\u6307\u5b9a\u5217\u540d\u3002 df3 = pd.DataFrame( { 'lkey': ['b', 'b', 'a', 'c', 'a', 'a', 'b'], 'data1': range(7) } ) df4 = pd.DataFrame( { 'rkey': ['a', 'b', 'd'], 'data2': range(3) } ) print(df3) # lkey data1 # 0 b 0 # 1 b 1 # 2 a 2 # 3 c 3 # 4 a 4 # 5 a 5 # 6 b 6 print(df4) # rkey data2 # 0 a 0 # 1 b 1 # 2 d 2 \u9ed8\u8ba4\u60c5\u51b5\u4e0b\uff0c merge \u505a\u7684\u662f\u5185\u8fde\u63a5\uff08'inner' join\uff09\uff0c\u7ed3\u679c\u4e2d\u7684\u952e\u662f\u4e24\u5f20\u8868\u7684\u4ea4\u96c6\u3002 result = pd.merge(df3, df4, left_on='lkey', right_on='rkey') # df4\u7684[a,0]\u5bf9\u5e94df3\u7684\u6240\u6709[a,?]\u8bb0\u5f55\uff08\u901a\u8fc7\u91cd\u590d\u6765\u586b\u5145\u4e0d\u8db3\uff09 print(result) # lkey data1 rkey data2 # 0 b 0 b 1 # 1 b 1 b 1 # 2 b 6 b 1 # 3 a 2 a 0 # 4 a 4 a 0 # 5 a 5 a 0 \u5916\u8fde\u63a5\uff08outer join\uff09\u662f\u952e\u7684\u5e76\u96c6\uff0c\u8054\u5408\u4e86\u5de6\u8fde\u63a5\u548c\u53f3\u8fde\u63a5\u7684\u6548\u679c\u3002 \u591a\u5bf9\u591a\u8fde\u63a5\u662f\u884c\u7684\u7b1b\u5361\u5c14\u79ef\u3002 df1 = pd.DataFrame( { 'key': ['b', 'b', 'a', 'c', 'a', 'b'], 'data1': range(6) } ) df2 = pd.DataFrame( { 'key': ['a', 'b', 'a', 'b', 'd'], 'data2': range(5) } ) print(df1.sort_values(by='key')) # key data1 # 2 a 2 # 4 a 4 # 0 b 0 # 1 b 1 # 5 b 5 # 3 c 3 print(df2.sort_values(by='key')) # key data2 # 0 a 0 # 2 a 2 # 1 b 1 # 3 b 3 # 4 d 4 result = pd.merge(df1, df2, on='key', how='left') print(result.sort_values(by='key')) # key data1 data2 # 4 a 2 0.0 # 5 a 2 2.0 # 7 a 4 0.0 # 8 a 4 2.0 # 0 b 0 1.0 # 1 b 0 3.0 # 2 b 1 1.0 # 3 b 1 3.0 # 9 b 5 1.0 # 10 b 5 3.0 # 6 c 3 NaN result = pd.merge(df1, df2, on='key', how='outer') # \u591a\u5bf9\u591a\u8fde\u63a5 print(result.sort_values(by='key')) # key data1 data2 # 6 a 2.0 0.0 # 7 a 2.0 2.0 # 8 a 4.0 0.0 # 9 a 4.0 2.0 # 0 b 0.0 1.0 # 1 b 0.0 3.0 # 2 b 1.0 1.0 # 3 b 1.0 3.0 # 4 b 5.0 1.0 # 5 b 5.0 3.0 # 10 c 3.0 NaN # 11 d NaN 4.0 \u591a\u952e\u5408\u5e76\u3002 df1 = pd.DataFrame( { 'key1': ['foo', 'foo', 'bar'], 'key2': ['one', 'two', 'one'], 'lval': [1, 2, 3] } ) df2 = pd.DataFrame( { 'key1': ['foo', 'foo', 'bar', 'bar'], 'key2': ['one', 'one', 'one', 'two'], 'rval': [4, 5, 6, 7] } ) print(df1.sort_values(by=['key1', 'key2'])) # key1 key2 lval # 2 bar one 3 # 0 foo one 1 # 1 foo two 2 print(df2.sort_values(by=['key1', 'key2'])) # key1 key2 rval # 2 bar one 6 # 3 bar two 7 # 0 foo one 4 # 1 foo one 5 result = pd.merge(df1, df2, on=['key1', 'key2'], how='outer') print(result.sort_values(by=['key1', 'key2'])) # key1 key2 lval rval # 3 bar one 3.0 6.0 # 4 bar two NaN 7.0 # 0 foo one 1.0 4.0 # \u91cd\u590d\u586b\u5145 # 1 foo one 1.0 5.0 # \u91cd\u590d\u586b\u5145 # 2 foo two 2.0 NaN \u5904\u7406\u91cd\u53e0\u5217\u540d\u3002 result = pd.merge(df1, df2, on='key1') print(result.sort_values(by='key1')) # key1 key2_x lval key2_y rval # 4 bar one 3 one 6 # 5 bar one 3 two 7 # 0 foo one 1 one 4 # 1 foo one 1 one 5 # 2 foo two 2 one 4 # 3 foo two 2 one 5 result = pd.merge(df1, df2, on='key1', suffixes=('_left', '_right')) print(result.sort_values(by='key1')) # key1 key2_left lval key2_right rval # 4 bar one 3 one 6 # 5 bar one 3 two 7 # 0 foo one 1 one 4 # 1 foo one 1 one 5 # 2 foo two 2 one 4 # 3 foo two 2 one 5","title":"\u6570\u636e\u5e93\u98ce\u683c\u7684DataFrame\u8fde\u63a5"},{"location":"python/DataAnalysis/ch05/#_6","text":"\u5728\u67d0\u4e9b\u60c5\u51b5\u4e0b\uff0cDataFrame\u4e2d\u7528\u4e8e\u5408\u5e76\u7684\u952e\u662f\u5b83\u7684\u7d22\u5f15\u3002\u53ef\u4ee5\u4f20\u9012 left_index=True \u6216 right_index=True \uff08\u6216\u8005\u90fd\u4f20\uff09\u6765\u8868\u793a\u7d22\u5f15\u9700\u8981\u7528\u6765\u4f5c\u4e3a\u5408\u5e76\u7684\u952e\u3002 df1 = pd.DataFrame( { 'key1': ['foo', 'foo', 'bar'], 'key2': ['one', 'two', 'one'], 'lval': [1, 2, 3] } ) df2 = pd.DataFrame( { 'key1': ['foo', 'foo', 'bar', 'bar'], 'key2': ['one', 'one', 'one', 'two'], 'rval': [4, 5, 6, 7] }, index=['foo', 'foo', 'bar', 'bar'] ) print(df1) # key1 key2 lval # 0 foo one 1 # 1 foo two 2 # 2 bar one 3 print(df2) # key1 key2 rval # foo foo one 4 # foo foo one 5 # bar bar one 6 # bar bar two 7 result = pd.merge(df1, df2, left_on='key1', right_index=True, suffixes=('_left', '_right')) print(result.sort_index()) # key1 key1_left key2_left lval key1_right key2_right rval # 0 foo foo one 1 foo one 4 # 0 foo foo one 1 foo one 5 # 1 foo foo two 2 foo one 4 # 1 foo foo two 2 foo one 5 # 2 bar bar one 3 bar one 6 # 2 bar bar one 3 bar two 7 result = pd.merge(df1, df2, left_on='key1', right_index=True, how='outer', suffixes=('_left', '_right')) # \u548c\u4e0a\u8ff0\u7ed3\u679c\u4e00\u6837 print(result.sort_index()) # key1 key1_left key2_left lval key1_right key2_right rval # 0 foo foo one 1 foo one 4 # 0 foo foo one 1 foo one 5 # 1 foo foo two 2 foo one 4 # 1 foo foo two 2 foo one 5 # 2 bar bar one 3 bar one 6 # 2 bar bar one 3 bar two 7 \u5728\u66f4\u590d\u6742\u591a\u5c42\u7d22\u5f15\u6570\u636e\u7684\u591a\u952e\u5408\u5e76\uff0c\u5728\u7d22\u5f15\u4e0a\u8fde\u63a5\u662f\u4e00\u4e2a\u9690\u5f0f\u7684\u591a\u952e\u5408\u5e76\u3002 \u5fc5\u987b\u4ee5\u5217\u8868\u7684\u65b9\u5f0f\u6307\u660e\u5408\u5e76\u6240\u9700\u591a\u4e2a\u5217\uff08\u6ce8\u610f\u4f7f\u7528 how='outer' \u5904\u7406\u91cd\u590d\u7684\u7d22\u5f15\u503c\uff09\u3002 df1 = pd.DataFrame( { 'key1': ['Ohio', 'Ohio', 'Ohio', 'Nevada', 'Nevada'], 'key2': [2000, 2001, 2002, 2001, 2002], 'data': np.arange(5.) } ) df2 = pd.DataFrame( np.arange(12).reshape((6, 2)), index=[ ['Nevada', 'Nevada', 'Ohio', 'Ohio', 'Ohio', 'Ohio'], [2001, 2000, 2000, 2000, 2001, 2002] ], columns=['event1', 'event2'] ) print(df1) # key1 key2 data # 0 Ohio 2000 0.0 # 1 Ohio 2001 1.0 # 2 Ohio 2002 2.0 # 3 Nevada 2001 3.0 # 4 Nevada 2002 4.0 print(df2) # event1 event2 # Nevada 2001 0 1 # 2000 2 3 # Ohio 2000 4 5 # 2000 6 7 # 2001 8 9 # 2002 10 11 result = pd.merge(df1, df2, left_on=['key1', 'key2'], right_index=True) print(result) # key1 key2 data event1 event2 # 0 Ohio 2000 0.0 4 5 # 0 Ohio 2000 0.0 6 7 # 1 Ohio 2001 1.0 8 9 # 2 Ohio 2002 2.0 10 11 # 3 Nevada 2001 3.0 0 1 result = pd.merge(df1, df2, left_on=['key1', 'key2'], right_index=True, how='outer') print(result) # key1 key2 data event1 event2 # 0 Ohio 2000 0.0 4.0 5.0 # 0 Ohio 2000 0.0 6.0 7.0 # 1 Ohio 2001 1.0 8.0 9.0 # 2 Ohio 2002 2.0 10.0 11.0 # 3 Nevada 2001 3.0 0.0 1.0 # 4 Nevada 2002 4.0 NaN NaN # 4 Nevada 2000 NaN 2.0 3.0 \u4f7f\u7528\u4e24\u8fb9\u7684\u7d22\u5f15\u8fdb\u884c\u5408\u5e76\u4e5f\u662f\u53ef\u4ee5\u7684\uff0c\u524d\u63d0\u662f\u7528\u4e24\u8fb9\u7528\u6765\u5408\u5e76\u7684\u7d22\u5f15\u6709\u4ea4\u96c6\uff08\u516c\u5171\u90e8\u5206\uff09\u3002 \u5728\u4f7f\u7528 merge \u65f6\uff0c\u53c2\u6570 on=['key1', 'key2'] \u4e0d\u80fd\u548c left_index=True , right_index=True \u540c\u65f6\u5b58\u5728\u3002 \u5bf9\u4e8e\u91cd\u590d\u7d22\u5f15\uff0c\u5982\u679c\u503c\u4e0d\u540c\uff0c\u5219\u591a\u884c\u663e\u793a\uff0c\u548c\u6570\u636e\u5e93SQL\u7684 full join \u7c7b\u4f3c\u6982\u5ff5\u3002 \u5982\u679c\u51fa\u73b0\u76f8\u540c\u5217\u540d\uff0c\u5219\u4f1a\u81ea\u52a8\u6dfb\u52a0\u540e\u7f00\u5b57\u7b26\u4ee5\u793a\u533a\u522b\u3002 df1 = pd.DataFrame( [[1, 2], [3, 4], [5, 6]], index=['a', 'c', 'e'], columns=['Ohio', 'Nevada'] ) print(df1) # Ohio Nevada # a 1 2 # c 3 4 # e 5 6 df2 = pd.DataFrame( [[7, 8], [9, 10], [11, 12], [13, 14]], index=['b', 'c', 'c', 'e'], columns=['Missouri', 'Alabama'] ) print(df2) # Missouri Alabama # b 7 8 # c 9 10 # c 11 12 # e 13 14 df3 = pd.DataFrame( [[7, 8], [9, 10], [11, 12], [13, 14]], index=['a', 'c', 'e', 'f'], columns=['Nevada', 'Alabama'] ) print(df3) # Nevada Alabama # a 7 8 # c 9 10 # e 11 12 # f 13 14 result = pd.merge(df1, df2, left_index=True, right_index=True, how='outer') print(result) # Ohio Nevada Missouri Alabama # a 1.0 2.0 NaN NaN # b NaN NaN 7.0 8.0 # c 3.0 4.0 9.0 10.0 # c 3.0 4.0 11.0 12.0 # e 5.0 6.0 13.0 14.0 result = pd.merge(df1, df3, left_index=True, right_index=True, how='outer') print(result) # Ohio Nevada_x Nevada_y Alabama # a 1.0 2.0 7 8 # c 3.0 4.0 9 10 # e 5.0 6.0 11 12 # f NaN NaN 13 14 \u53e6\u4e00\u79cd\u5199\u6cd5\uff1a result = df1.join(df2, how='outer') print(result) # Ohio Nevada Missouri Alabama # a 1.0 2.0 NaN NaN # b NaN NaN 7.0 8.0 # c 3.0 4.0 9.0 10.0 # c 3.0 4.0 11.0 12.0 # e 5.0 6.0 13.0 14.0 \u4e5f\u53ef\u4ee5\u5411 join \u65b9\u6cd5\u4f20\u5165\u4e00\u4e2aDataFrame\u5217\u8868\uff0c\u7c7b\u4f3c\u4e8e\u5bf9\u4e09\u4e2a\u6570\u636e\u96c6\u8fdb\u884c join \u64cd\u4f5c\u3002 result = df1.join([df2, df3]) print(result) # Ohio Nevada_x Missouri Alabama_x Nevada_y Alabama_y # a 1 2 NaN NaN 7 8 # c 3 4 9.0 10.0 9 10 # c 3 4 11.0 12.0 9 10 # e 5 6 13.0 14.0 11 12","title":"\u6839\u636e\u7d22\u5f15\u5408\u5e76"},{"location":"python/DataAnalysis/ch05/#_7","text":"\u53e6\u4e00\u79cd\u6570\u636e\u7ec4\u5408\u64cd\u4f5c\u53ef\u79f0\u4e3a\u62fc\u63a5\u3001\u7ed1\u5b9a\u6216\u5806\u53e0\u3002NumPy\u7684 concatenate \u51fd\u6570\u53ef\u4ee5\u5728NumPy\u6570\u7ec4\u4e0a\u5b9e\u73b0\u8be5\u529f\u80fd\u3002 \u57fa\u4e8eSeries\u7684pandas\u7684 concat \u51fd\u6570\u7684\u5de5\u4f5c\u673a\u5236\u5206\u6790\u3002 \u4e0b\u9762\u4e09\u4e2a\u7d22\u5f15\u4e0d\u91cd\u53e0\u7684Series\u3002 s1 = pd.Series([0, 1], index=['a', 'b']) s2 = pd.Series([2, 3, 4], index=['c', 'd', 'e']) s3 = pd.Series([5, 6], index=['f', 'g']) \u7528\u5217\u8868\u4e2d\u7684\u8fd9\u4e9b\u5bf9\u8c61\u8c03\u7528 concat \u65b9\u6cd5\u4f1a\u5c06\u503c\u548c\u7d22\u5f15\u7c98\u5728\u4e00\u8d77\uff1a \u9ed8\u8ba4\u60c5\u51b5\u4e0b\uff0c concat \u65b9\u6cd5\u662f\u6cbf\u7740 axis=0 \u7684\u8f74\u5411\u751f\u6548\u7684\uff0c\u751f\u6210\u53e6\u4e00\u4e2aSeries\u3002 \u5982\u679c\u4f20\u9012 axis=1 \uff0c\u8fd4\u56de\u7684\u7ed3\u679c\u5219\u662f\u4e00\u4e2aDataFrame\uff08 axis=1 \u65f6\u662f\u5217\uff09\u3002 result = pd.concat([s1, s2, s3]) print(result) # a 0 # b 1 # c 2 # d 3 # e 4 # f 5 # g 6 # dtype: int64 result = pd.concat([s1, s2, s3], keys=['one', 'two', 'three']) # \u901a\u8fc7keys\u53c2\u6570\uff0c\u5728\u8fde\u63a5\u8f74\u5411\u4e0a\u521b\u5efa\u4e00\u4e2a\u591a\u5c42\u7d22\u5f15\uff0c\u4ee5\u4fbf\u5728\u7ed3\u679c\u4e2d\u533a\u5206\u5404\u90e8\u5206 print(result) # one a 0 # b 1 # two c 2 # d 3 # e 4 # three f 5 # g 6 # dtype: int64 print(result.unstack()) # \u628a\u539f\u7d22\u5f15\u4f5c\u4e3a\u5217\u6807\u7b7e\u5c55\u5f00 # a b c d e f g # one 0.0 1.0 NaN NaN NaN NaN NaN # two NaN NaN 2.0 3.0 4.0 NaN NaN # three NaN NaN NaN NaN NaN 5.0 6.0 result = pd.concat([s1, s2, s3], axis=1) # \u5728\u8fd9\u4e2a\u6848\u4f8b\u4e2daxis=1\u8f74\u5411\u4e0a\u5e76\u6ca1\u6709\u91cd\u53e0 print(result) # 0 1 2 # a 0.0 NaN NaN # b 1.0 NaN NaN # c NaN 2.0 NaN # d NaN 3.0 NaN # e NaN 4.0 NaN # f NaN NaN 5.0 # g NaN NaN 6.0 result = pd.concat([s1, s2, s3], axis=1, keys=['one', 'two', 'three']) # \u5728\u8fd9\u4e2a\u6848\u4f8b\u4e2daxis=1\u8f74\u5411\u4e0a\u5e76\u6ca1\u6709\u91cd\u53e0 print(result) # one two three # a 0.0 NaN NaN # b 1.0 NaN NaN # c NaN 2.0 NaN # d NaN 3.0 NaN # e NaN 4.0 NaN # f NaN NaN 5.0 # g NaN NaN 6.0 print(result.unstack()) # \u5bf9\u6bd4axis=0\u7684\u591a\u5c42\u7d22\u5f15\uff0c\u5f53axis=1\u65f6\u5bf9\u8f93\u51fa\u5404index\u7684\u5e76\u96c6\u505a\u4e86\u5206\u7ec4\u3002 # one a 0.0 # b 1.0 # c NaN # d NaN # e NaN # f NaN # g NaN # two a NaN # b NaN # c 2.0 # d 3.0 # e 4.0 # f NaN # g NaN # three a NaN # b NaN # c NaN # d NaN # e NaN # f 5.0 # g 6.0 # dtype: float64 s4 = pd.concat([s1, s3]) print(s4) # a 0 # b 1 # f 5 # g 6 # dtype: int64 result = pd.concat([s1, s4]) print(result) # a 0 # b 1 # a 0 # b 1 # f 5 # g 6 # dtype: int64 result = pd.concat([s1, s4], axis=1) # \u73b0\u5728\u5728\u4e2daxis=1\u8f74\u5411\u4e0a\u6709\u91cd\u53e0 print(result) # 0 1 # a 0.0 0 # b 1.0 1 # f NaN 5 # g NaN 6 result = pd.concat([s1, s4], axis=1, keys=['one', 'two', 'three']) print(result) # one two # a 0.0 0 # b 1.0 1 # f NaN 5 # g NaN 6 result = pd.concat([s1, s4], axis=0, keys=['one', 'two', 'three']) # \u901a\u8fc7keys\u53c2\u6570\uff0c\u5728\u8fde\u63a5\u8f74\u5411\u4e0a\u521b\u5efa\u4e00\u4e2a\u591a\u5c42\u7d22\u5f15 print(result) # one a 0 # b 1 # two a 0 # b 1 # f 5 # g 6 # dtype: int64 result = pd.concat([s1, s4], axis=1, join='inner') # \u5185\u8fde\u63a5\u65b9\u5f0f\u5408\u5e76\u7d22\u5f15\uff08\u7d22\u5f15\u4ea4\u96c6\uff09 print(result) # 0 1 # a 0 0 # b 1 1 result = pd.concat([s1, s4], axis=1).reindex(['a', 'c', 'b', 'e']) # \u4f7f\u7528join_axes(\u5df2\u88ab\u66ff\u6362\u6210reindex)\u6765\u6307\u5b9a\u7528\u4e8e\u8fde\u63a5\u5176\u4ed6\u8f74\u5411\u7684\u8f74 print(result) # 0 1 # a 0.0 0.0 # c NaN NaN # b 1.0 1.0 # e NaN NaN \u57fa\u4e8eDataFrame\u7684pandas\u7684 concat \u51fd\u6570\u7684\u5de5\u4f5c\u673a\u5236\u5206\u6790\u3002 df1 = pd.DataFrame( np.arange(12).reshape((6, 2)), index=[ ['Ohio', 'Ohio', 'Ohio', 'Nevada', 'Nevada', 'Nevada'], [2000, 2001, 2002, 2000, 2001, 2002] ], columns=['event1', 'event2'] ) df2 = pd.DataFrame( np.arange(12).reshape((6, 2)), index=[ ['Ohio', 'Ohio', 'Ohio', 'Nevada', 'Nevada', 'Nevada'], [2000, 2001, 2002, 2000, 2001, 2002] ], columns=['event3', 'event4'] ) print(df1) # event1 event2 # Ohio 2000 0 1 # 2001 2 3 # 2002 4 5 # Nevada 2000 6 7 # 2001 8 9 # 2002 10 11 print(df2) # event3 event4 # Ohio 2000 0 1 # 2001 2 3 # 2002 4 5 # Nevada 2000 6 7 # 2001 8 9 # 2002 10 11 result = np.concatenate([df1, df2], axis=0) # \u6cbf0\u8f74\u62fc\u63a5 print(result) # [[ 0 1] # [ 2 3] # [ 4 5] # [ 6 7] # [ 8 9] # [10 11] # [ 0 1] # [ 2 3] # [ 4 5] # [ 6 7] # [ 8 9] # [10 11]] result = np.concatenate([df1, df2], axis=1) # \u6cbf1\u8f74\u62fc\u63a5 print(result) # [[ 0 1 0 1] # [ 2 3 2 3] # [ 4 5 4 5] # [ 6 7 6 7] # [ 8 9 8 9] # [10 11 10 11]] result = np.concatenate([df1, df2], axis=None) # \u5c06\u6570\u7ec4\u5c55\u5e73 print(result) # [ 0 1 2 3 4 5 6 7 8 9 10 11 0 1 2 3 4 5 6 7 8 9 10 11]","title":"\u6cbf\u8f74\u5411\u8fde\u63a5"},{"location":"python/DataAnalysis/ch05/#_8","text":"\u53e6\u4e00\u4e2a\u6570\u636e\u8054\u5408\u573a\u666f\uff0c\u65e2\u4e0d\u662f\u5408\u5e76\u64cd\u4f5c\uff0c\u4e5f\u4e0d\u662f\u8fde\u63a5\u64cd\u4f5c\u3002 \u5047\u5982\u6709\u4e24\u4e2a\u6570\u636e\u96c6\uff0c\u8fd9\u4e24\u4e2a\u6570\u636e\u96c6\u7684\u7d22\u5f15\u5168\u90e8\u6216\u90e8\u5206\u91cd\u53e0\uff0c\u901a\u8fc7NumPy\u7684 where \u51fd\u6570\u53ef\u4ee5\u8fdb\u884c\u9762\u5411\u6570\u7ec4\u7684if-else\u7b49\u4ef7\u64cd\u4f5c\u3002 s1 = pd.Series( [np.nan, 2.5, 0.0, 3.5, 4.5, np.nan], index=['f', 'e', 'd', 'c', 'b', 'a'] ) s2 = pd.Series( [0.0, np.nan, 2.0, np.nan, np.nan, 5.0], index=['a', 'b', 'c', 'd', 'e', 'f'] ) print(s1) # f NaN # e 2.5 # d 0.0 # c 3.5 # b 4.5 # a NaN # dtype: float64 print(s2) # a 0.0 # b NaN # c 2.0 # d NaN # e NaN # f 5.0 # dtype: float64 \u65b9\u6cd51\uff0c\u901a\u8fc7Numpy\u7684 where \u51fd\u6570\u3002 result = np.where(pd.isnull(s1), s2, s1) # An array with elements from 'x'(s2) where 'condition'(isnull(s1)) is True, and elements from 'y'(s1) elsewhere. print(result) # [0. 2.5 0. 3.5 4.5 5. ] # s1 # s2 # result # f NaN # a 0.0 0. \u6761\u4ef6\u4e2ds1\u8be5\u5143\u7d20\u4e3anull\uff0c\u6240\u4ee5where\u51fd\u6570\u53d6\u5bf9\u5e94x(s2)\u7684\u5143\u7d20\uff08\u6ce8\u610f\uff0c\u4e0e\u7d22\u5f15\u987a\u5e8f\u65e0\u5173\uff09 # e 2.5 # b NaN 2.5 \u6761\u4ef6\u4e2ds1\u8be5\u5143\u7d20\u4e0d\u4e3anull\uff0c\u6240\u4ee5where\u51fd\u6570\u53d6\u5bf9\u5e94y(s1)\u7684\u5143\u7d20 # d 0.0 # c 2.0 0. # c 3.5 # d NaN 3.5 # b 4.5 # e NaN 4.5 # a NaN # f 5.0 5.0 \u6761\u4ef6\u4e2ds1\u8be5\u5143\u7d20\u4e3anull\uff0c\u6240\u4ee5where\u51fd\u6570\u53d6\u5bf9\u5e94x(s2)\u7684\u5143\u7d20 result = np.where(pd.isnull(s2), s1, s2) print(result) # [0. 2.5 2. 3.5 4.5 5. ] \u65b9\u6cd52\uff0c\u901a\u8fc7Series\u7684 combine_first \u65b9\u6cd5\u3002 result = s2.combine_first(s1) # \u6ce8\u610f\uff0ccombine_first\u662f\u6309\u7167s2\u7684\u7d22\u5f15\u987a\u5e8f\u68c0\u7d22\u7684\uff0c\u76f8\u540c\u7d22\u5f15\u7684s1\u7684\u503c\u4f1a\u586b\u5145\u5bf9\u5e94s2\u7684null print(result) # a 0.0 # b 4.5 # c 2.0 # d 0.0 # e 2.5 # f 5.0 # dtype: float64 \u65b9\u6cd53\uff1aPandas\u7684 combine_first \u65b9\u6cd5\u3002 df1 = pd.DataFrame( { 'a': [1.0, np.nan, 5.0, np.nan], 'b': [np.nan, 2.0, np.nan, 6.0], 'c': [2.0, 6.0, 10.0, 15.0] } ) df2 = pd.DataFrame( { 'a': [5.0, 4.0, np.nan, 3.0, 7.0], 'b': [np.nan, 3.0, 4.0, 6.0, 8.0] } ) print(df1) # a b c # 0 1.0 NaN 2.0 # 1 NaN 2.0 6.0 # 2 5.0 NaN 10.0 # 3 NaN 6.0 15.0 print(df2) # a b # 0 5.0 NaN # 1 4.0 3.0 # 2 NaN 4.0 # 3 3.0 6.0 # 4 7.0 8.0 result = df2.combine_first(df1) # \u7528df1\u7684\u503c\u53bb\u586b\u5145df2\u5bf9\u5e94\u7d22\u5f15\u4f4d\u7f6e\u7684null\u503c print(result) # a b c # 0 5.0 NaN 2.0 # 1 4.0 3.0 6.0 # 2 5.0 4.0 10.0 # 3 3.0 6.0 15.0 # 4 7.0 8.0 NaN","title":"\u8054\u5408\u91cd\u53e0\u6570\u636e"},{"location":"python/DataAnalysis/ch05/#_9","text":"\u91cd\u65b0\u6392\u5217\u8868\u683c\u578b\u6570\u636e\u6709\u591a\u79cd\u57fa\u7840\u64cd\u4f5c\u3002\u8fd9\u4e9b\u64cd\u4f5c\u88ab\u79f0\u4e3a\u91cd\u5851\u6216\u900f\u89c6\u3002 import numpy as np import pandas as pd","title":"\u91cd\u5851\u548c\u900f\u89c6"},{"location":"python/DataAnalysis/ch05/#_10","text":"\u591a\u5c42\u7d22\u5f15\u5728DataFrame\u4e2d\u63d0\u4f9b\u4e86\u4e00\u79cd\u4e00\u81f4\u6027\u65b9\u5f0f\u7528\u4e8e\u91cd\u6392\u5217\u6570\u636e\u3002\u4ee5\u4e0b\u662f\u4e24\u4e2a\u57fa\u7840\u64cd\u4f5c\uff1a statck\uff08\u5806\u53e0\uff09\u8be5\u64cd\u4f5c\u4f1a\u201c\u65cb\u8f6c\u201d\u6216\u5c06\u5217\u4e2d\u7684\u6570\u636e\u900f\u89c6\u5230\u884c\u3002 unstack\uff08\u62c6\u5806\uff09\u8be5\u64cd\u4f5c\u4f1a\u5c06\u884c\u4e2d\u7684\u6570\u636e\u900f\u89c6\u5230\u5217\u3002 df = pd.DataFrame( np.arange(6).reshape((2, 3)), index=pd.Index(['Ohio', 'Colorado'], name='state'), columns=pd.Index(['one', 'two', 'three'], name='number') ) print(df) # number one two three # state # Ohio 0 1 2 # Colorado 3 4 5 \u5728\u8fd9\u4efd\u6570\u636e\u4e0a\u4f7f\u7528stack\u65b9\u6cd5\u4f1a\u5c06\u5217\u900f\u89c6\u5230\u884c\uff0c\u4ea7\u751f\u4e00\u4e2a\u65b0\u7684Series\uff1a result = df.stack() print(result) # state number # Ohio one 0 # two 1 # three 2 # Colorado one 3 # two 4 # three 5 # dtype: int64 \u4ece\u4e00\u4e2a\u591a\u5c42\u7d22\u5f15\u5e8f\u5217\u4e2d\uff0c\u4f60\u53ef\u4ee5\u4f7f\u7528 unstack \u65b9\u6cd5\u5c06\u6570\u636e\u91cd\u6392\u5217\u540e\u653e\u5165\u4e00\u4e2aDataFrame\u4e2d\uff1a print(result.unstack()) # number one two three # state # Ohio 0 1 2 # Colorado 3 4 5 print(result.unstack(0)) # \u53ef\u4ee5\u4f20\u5165\u4e00\u4e2a\u5c42\u7ea7\u5e8f\u53f7\u6216\u540d\u79f0\u6765\u62c6\u5206\u4e00\u4e2a\u4e0d\u540c\u7684\u5c42\u7ea7 # state Ohio Colorado # number # one 0 3 # two 1 4 # three 2 5 print(result.unstack(1)) # number one two three # state # Ohio 0 1 2 # Colorado 3 4 5 print(result.unstack('state')) # \u8f93\u51fa\u7ed3\u679c\u548c\u4f20\u5165\u5c42\u7ea70\u4e00\u6837 # state Ohio Colorado # number # one 0 3 # two 1 4 # three 2 5 print(result.unstack('number')) # \u8f93\u51fa\u7ed3\u679c\u548c\u4f20\u5165\u5c42\u7ea71\u4e00\u6837 # number one two three # state # Ohio 0 1 2 # Colorado 3 4 5 \u5982\u679c\u5c42\u7ea7\u4e2d\u7684\u6240\u6709\u503c\u5e76\u672a\u5305\u542b\u4e8e\u6bcf\u4e2a\u5b50\u5206\u7ec4\u4e2d\u65f6\uff0c\u62c6\u5206\u53ef\u80fd\u4f1a\u5f15\u5165\u7f3a\u5931\u503c\uff1a s1 = pd.Series([0, 1, 2, 3], index=['a', 'b', 'c', 'd']) s2 = pd.Series([4, 5, 6], index=['c', 'd', 'e']) s3 = pd.concat([s1, s2], keys=['one', 'two']) print(s3) # one a 0 # b 1 # c 2 # d 3 # two c 4 # d 5 # e 6 # dtype: int64 print(s3.unstack(0)) # one two # a 0.0 NaN # b 1.0 NaN # c 2.0 4.0 # d 3.0 5.0 # e NaN 6.0 print(s3.unstack(1)) print(s3.unstack()) # a b c d e # one 0.0 1.0 2.0 3.0 NaN # two NaN NaN 4.0 5.0 6.0 \u9ed8\u8ba4\u60c5\u51b5\u4e0b\uff0c\u5806\u53e0\u4f1a\u8fc7\u6ee4\u51fa\u7f3a\u5931\u503c\uff0c\u56e0\u6b64\u5806\u53e0\u62c6\u5806\u7684\u64cd\u4f5c\u662f\u53ef\u9006\u7684\u3002 print(s3.unstack().stack()) # one a 0.0 # b 1.0 # c 2.0 # d 3.0 # two c 4.0 # d 5.0 # e 6.0 # dtype: float64 print(s3.unstack().stack(dropna=False)) # one a 0.0 # b 1.0 # c 2.0 # d 3.0 # e NaN # two a NaN # b NaN # c 4.0 # d 5.0 # e 6.0 # dtype: float64 \u5728DataFrame\u4e2d\u62c6\u5806\u65f6\uff0c\u88ab\u62c6\u5806\u7684\u5c42\u7ea7\u4f1a\u53d8\u4e3a\u7ed3\u679c\u4e2d\u6700\u4f4e\u7684\u5c42\u7ea7\u3002 \u5728\u8c03\u7528 stack \u65b9\u6cd5\u65f6\uff0c\u6211\u4eec\u53ef\u4ee5\u6307\u660e\u9700\u8981\u5806\u53e0\u7684\u8f74\u5411\u540d\u79f0\u3002 df = pd.DataFrame( {'left': result, 'right': result + 5}, columns=pd.Index(['left', 'right'], name='side') ) print(df) # side left right # state number # Ohio one 0 5 # two 1 6 # three 2 7 # Colorado one 3 8 # two 4 9 # three 5 10 print(df.unstack()) # side left right # number one two three one two three # state # Ohio 0 1 2 5 6 7 # Colorado 3 4 5 8 9 10 print(df.unstack('state')) # \u88ab\u62c6\u5806\u7684\u5c42\u7ea7(state)\u4f1a\u53d8\u4e3a\u7ed3\u679c\u4e2d\u6700\u4f4e\u7684\u5c42\u7ea7 # side left right # state Ohio Colorado Ohio Colorado # number # one 0 3 5 8 # two 1 4 6 9 # three 2 5 7 10 \u5728\u8c03\u7528 stack \u65b9\u6cd5\u65f6\uff0c\u53ef\u4ee5\u6307\u660e\u9700\u8981\u5806\u53e0\u7684\u8f74\u5411\u540d\u79f0\uff1a print(df.unstack('state').stack('side')) # state Colorado Ohio # number side # one left 3 0 # right 8 5 # two left 4 1 # right 9 6 # three left 5 2 # right 10 7","title":"\u4f7f\u7528\u591a\u5c42\u7d22\u5f15\u8fdb\u884c\u91cd\u5851"},{"location":"python/DataAnalysis/ch05/#_11","text":"\u5728\u6570\u636e\u5e93\u548cCSV\u4e2d\u5b58\u50a8\u591a\u65f6\u95f4\u5e8f\u5217\u7684\u65b9\u5f0f\u5c31\u662f\u6240\u8c13\u7684\u957f\u683c\u5f0f\u6216\u5806\u53e0\u683c\u5f0f\u3002 data = pd.read_csv('../examples/macrodata.csv') print(data.head(3)) # year quarter realgdp realcons ... unemp pop infl realint # 0 1959.0 1.0 2710.349 1707.4 ... 5.8 177.146 0.00 0.00 # 1 1959.0 2.0 2778.801 1733.7 ... 5.1 177.830 2.34 0.74 # 2 1959.0 3.0 2775.488 1751.8 ... 5.3 178.657 2.74 1.09 # ...... # [3 rows x 14 columns] # PeriodIndex\u5c06year\u548cquarter\u7b49\u5217\u8fdb\u884c\u8054\u5408\u5e76\u751f\u6210\u4e86\u4e00\u79cd\u65f6\u95f4\u95f4\u9694\u7c7b\u578b periods = pd.PeriodIndex( year=data.year, quarter=data.quarter, name='date' ) columns = pd.Index( ['realgdp', 'infl', 'unemp'], name='item' ) data = data.reindex(columns=columns) print(data) # item realgdp infl unemp # 0 2710.349 0.00 5.8 # 1 2778.801 2.34 5.1 # 2 2775.488 2.74 5.3 # ...... # [203 rows x 3 columns] data.index = periods.to_timestamp('D', 'end') print(data.index) # DatetimeIndex(['1959-03-31 23:59:59.999999999', # '1959-06-30 23:59:59.999999999', # ... # '2009-06-30 23:59:59.999999999', # '2009-09-30 23:59:59.999999999'], # dtype='datetime64[ns]', name='date', length=203, freq=None) \u4e0b\u9762\u662fldata\u7684\u6570\u636e\u6837\u672c\u3002 \u8fd9\u79cd\u6570\u636e\u5373\u6240\u8c13\u7684\u591a\u65f6\u95f4\u5e8f\u5217\u7684\u957f\u683c\u5f0f\uff0c\u6216\u79f0\u4e3a\u5177\u6709\u4e24\u4e2a\u6216\u66f4\u591a\u4e2a\u952e\u7684\u5176\u4ed6\u89c2\u6d4b\u6570\u636e\uff08\u8fd9\u91cc\uff0c\u6211\u4eec\u7684\u952e\u662fdate\u548citem\uff09\u3002 \u8868\u4e2d\u7684\u6bcf\u4e00\u884c\u8868\u793a\u4e00\u4e2a\u65f6\u95f4\u70b9\u4e0a\u7684\u5355\u4e2a\u89c2\u6d4b\u503c\u3002 ldata = data.stack().reset_index().rename(columns={0: 'value'}) print(ldata) # date item value # 0 1959-03-31 23:59:59.999999999 realgdp 2710.349 # 1 1959-03-31 23:59:59.999999999 infl 0.000 # 2 1959-03-31 23:59:59.999999999 unemp 5.800 # 3 1959-06-30 23:59:59.999999999 realgdp 2778.801 # 4 1959-06-30 23:59:59.999999999 infl 2.340 # .. ... ... ... # 604 2009-06-30 23:59:59.999999999 infl 3.370 # 605 2009-06-30 23:59:59.999999999 unemp 9.200 # 606 2009-09-30 23:59:59.999999999 realgdp 12990.341 # 607 2009-09-30 23:59:59.999999999 infl 3.560 # 608 2009-09-30 23:59:59.999999999 unemp 9.600 # [609 rows x 3 columns] \u5728\u4e0a\u9762\u7684\u4f8b\u5b50\u4e2d\uff1a \u6570\u636e\u901a\u5e38\u4ee5\u8fd9\u79cd\u65b9\u5f0f\u5b58\u50a8\u5728\u5173\u7cfb\u578b\u6570\u636e\u5e93\u4e2d\uff0c\u6bd4\u5982MySQL\uff0c\u56e0\u4e3a\u56fa\u5b9a\u6a21\u5f0f\uff08\u5217\u540d\u79f0\u548c\u6570\u636e\u7c7b\u578b\uff09\u5141\u8bb8 item \u5217\u4e2d\u4e0d\u540c\u503c\u7684\u6570\u91cf\u968f\u7740\u6570\u636e\u88ab\u6dfb\u52a0\u5230\u8868\u4e2d\u800c\u6539\u53d8\u3002 date \u548c item \u901a\u5e38\u662f\u4e3b\u952e\uff08\u4f7f\u7528\u5173\u7cfb\u578b\u6570\u636e\u5e93\u7684\u8bf4\u6cd5\uff09\uff0c\u63d0\u4f9b\u4e86\u5173\u7cfb\u5b8c\u6574\u6027\u548c\u66f4\u7b80\u5355\u7684\u8fde\u63a5\u3002 \u5728\u67d0\u4e9b\u60c5\u51b5\u4e0b\uff0c\u5904\u7406\u8fd9\u79cd\u683c\u5f0f\u7684\u6570\u636e\u66f4\u4e3a\u56f0\u96be\u3002\u53ef\u80fd\u66f4\u503e\u5411\u4e8e\u83b7\u53d6\u4e00\u4e2a\u6309 date \u5217\u65f6\u95f4\u6233\u7d22\u5f15\u7684\u4e14\u6bcf\u4e2a\u4e0d\u540c\u7684 item \u72ec\u7acb\u4e00\u5217\u7684DataFrame\u3002 DataFrame\u7684pivot\u65b9\u6cd5\u5c31\u662f\u8fdb\u884c\u8fd9\u79cd\u8f6c\u6362\u7684\uff1a \u4e0b\u9762\u4f8b\u5b50\u4e2d\uff0c\u4f20\u9012\u7684\u524d\u4e24\u4e2a\u503c\u662f\u5206\u522b\u7528\u4f5c\u884c\u548c\u5217\u7d22\u5f15\u7684\u5217\uff0c\u7136\u540e\u662f\u53ef\u9009\u7684\u6570\u503c\u5217\u4ee5\u586b\u5145DataFrame\u3002 \u6ce8\u610f\uff0c pivot \u65b9\u6cd5\u7b49\u4ef7\u4e8e\u4f7f\u7528 set_index \u521b\u5efa\u5206\u5c42\u7d22\u5f15\uff0c\u7136\u540e\u8c03\u7528unstack\u3002 pivoted = ldata.pivot('date', 'item', 'value') print(pivoted) # item infl realgdp unemp # date # 1959-03-31 23:59:59.999999999 0.00 2710.349 5.8 # 1959-06-30 23:59:59.999999999 2.34 2778.801 5.1 # ... ... ... ... # 2009-06-30 23:59:59.999999999 3.37 12901.504 9.2 # 2009-09-30 23:59:59.999999999 3.56 12990.341 9.6 # [203 rows x 3 columns] ldata['value2'] = np.random.randn(len(ldata)) print(ldata[:5]) # date item value value2 # 0 1959-03-31 23:59:59.999999999 realgdp 2710.349 -1.268405 # 1 1959-03-31 23:59:59.999999999 infl 0.000 0.377691 # 2 1959-03-31 23:59:59.999999999 unemp 5.800 -0.342492 # 3 1959-06-30 23:59:59.999999999 realgdp 2778.801 0.132797 # 4 1959-06-30 23:59:59.999999999 infl 2.340 0.180290 \u6b64\u65f6 ldata \u5df2\u7ecf\u6dfb\u52a0\u4e86\u4e00\u5217\u3002\u5982\u679c\u9057\u6f0f\u6700\u540e\u4e00\u4e2a\u53c2\u6570\uff0c\u4f1a\u5f97\u5230\u4e00\u4e2a\u542b\u6709\u591a\u5c42\u5217\u7684DataFrame\uff0c\u5982\u4e0b\uff1a pivoted = ldata.pivot('date', 'item') print(pivoted) # value ... value2 # item infl realgdp ... realgdp unemp # date ... # 1959-03-31 23:59:59.999999999 0.00 2710.349 ... 0.157467 -0.222464 # 1959-06-30 23:59:59.999999999 2.34 2778.801 ... 0.861501 0.368855 # ... ... ... ... ... ... # 2009-06-30 23:59:59.999999999 3.37 12901.504 ... 0.279988 0.934972 # 2009-09-30 23:59:59.999999999 3.56 12990.341 ... 0.547914 1.842967 # [203 rows x 6 columns] \u6ce8\u610f\uff0c pivot \u65b9\u6cd5\u7b49\u4ef7\u4e8e\u4f7f\u7528 set_index \u521b\u5efa\u5206\u5c42\u7d22\u5f15\uff0c\u7136\u540e\u8c03\u7528 unstack \u3002 unstacked = ldata.set_index(['date', 'item']).unstack('item') print(unstacked[:5]) # value ... value2 # item infl realgdp ... realgdp unemp # date ... # 1959-03-31 23:59:59.999999999 0.00 2710.349 ... 0.213120 -0.248004 # 1959-06-30 23:59:59.999999999 2.34 2778.801 ... 0.697763 0.112388 # 1959-09-30 23:59:59.999999999 2.74 2775.488 ... 1.291884 -1.046142 # 1959-12-31 23:59:59.999999999 0.27 2785.204 ... 0.363339 -0.307364 # 1960-03-31 23:59:59.999999999 2.31 2847.699 ... 0.377330 2.272980 # [5 rows x 6 columns]","title":"\u5c06\u201c\u957f\u201d\u900f\u89c6\u4e3a\u201c\u5bbd\u201d"},{"location":"python/DataAnalysis/ch05/#_12","text":"\u5728DataFrame\u4e2d\uff0cpivot\u65b9\u6cd5\u7684\u53cd\u64cd\u4f5c\u662f pandas.melt \u3002 \u4e0e\u5c06\u4e00\u5217\u53d8\u6362\u4e3a\u65b0\u7684DataFrame\u4e2d\u7684\u591a\u5217\u4e0d\u540c\uff0c\u5b83\u5c06\u591a\u5217\u5408\u5e76\u6210\u4e00\u5217\uff0c\u4ea7\u751f\u4e00\u4e2a\u65b0\u7684DataFrame\uff0c\u5176\u957f\u5ea6\u6bd4\u8f93\u5165\u66f4\u957f\u3002 df = pd.DataFrame( { 'key': ['foo', 'bar', 'baz'], 'A': [1, 2, 3], 'B': [4, 5, 6], 'C': [7, 8, 9] } ) print(df) # key A B C # 0 foo 1 4 7 # 1 bar 2 5 8 # 2 baz 3 6 9 key \u5217\u53ef\u4ee5\u4f5c\u4e3a\u5206\u7ec4\u6307\u6807\uff0c\u5176\u4ed6\u5217\u5747\u4e3a\u6570\u636e\u503c\u3002 \u5f53\u4f7f\u7528 pandas.melt \u65f6\uff0c\u6211\u4eec\u5fc5\u987b\u6307\u660e\u54ea\u4e9b\u5217\u662f\u5206\u7ec4\u6307\u6807\uff08\u5982\u679c\u6709\u7684\u8bdd\uff09\u3002 \u6b64\u5904\uff0c\u8ba9\u6211\u4eec\u4f7f\u7528 key \u4f5c\u4e3a\u552f\u4e00\u7684\u5206\u7ec4\u6307\u6807\uff1a melted = pd.melt(df, ['key']) print(melted) # key variable value # 0 foo A 1 # 1 bar A 2 # 2 baz A 3 # 3 foo B 4 # 4 bar B 5 # 5 baz B 6 # 6 foo C 7 # 7 bar C 8 # 8 baz C 9 \u4f7f\u7528 pivot \u65b9\u6cd5\uff0c\u6211\u4eec\u53ef\u4ee5\u5c06\u6570\u636e\u91cd\u5851\u56de\u539f\u5148\u7684\u5e03\u5c40\u3002 reshaped = melted.pivot('key', 'variable', 'value') print(reshaped) # variable A B C # key # bar 2 5 8 # baz 3 6 9 # foo 1 4 7 \u7531\u4e8e pivot \u7684\u7ed3\u679c\u6839\u636e\u4f5c\u4e3a\u884c\u6807\u7b7e\u7684\u5217\u751f\u6210\u4e86\u7d22\u5f15\uff0c\u53ef\u4f7f\u7528 reset_index \u6765\u5c06\u6570\u636e\u56de\u79fb\u4e00\u5217\uff1a print(reshaped.reset_index()) # variable key A B C # 0 bar 2 5 8 # 1 baz 3 6 9 # 2 foo 1 4 7 pandas.melt \u7684\u4f7f\u7528\u4e5f\u53ef\u4ee5\u65e0\u987b\u4efb\u4f55\u5206\u7ec4\u6307\u6807\u3002 result = pd.melt(df, value_vars=['A', 'B', 'C']) print(result) # variable value # 0 A 1 # 1 A 2 # 2 A 3 # 3 B 4 # 4 B 5 # 5 B 6 # 6 C 7 # 7 C 8 # 8 C 9 result = pd.melt(df, value_vars=['key', 'B', 'C']) print(result) # variable value # 0 key foo # 1 key bar # 2 key baz # 3 B 4 # 4 B 5 # 5 B 6 # 6 C 7 # 7 C 8 # 8 C 9","title":"\u5c06\u201c\u5bbd\u201d\u900f\u89c6\u4e3a\u201c\u957f\u201d"},{"location":"python/DataAnalysis/ch06/","text":"\u7ed8\u56fe\u4e0e\u53ef\u89c6\u5316 \u00b6 \u7b80\u660ematplotlib API\u5165\u95e8 \u00b6 import matplotlib as mpl import matplotlib.pyplot as plt import numpy as np import pandas as pd from io import BytesIO \u6267\u884c plt.show() \u65f6\u62a5\u9519\uff1a UserWarning: Matplotlib is currently using agg, which is a non-GUI backend, so cannot show the figure. \u6267\u884c\u4e0b\u9762\u547d\u4ee4\uff0c\u5f97\u5230 plt \u7684 backend \u662f\u7528 agg \u3002 plt.get_backend() \u4f8b\u5982\uff1a\u4e0b\u9762\u4e24\u79cd\u8868\u8fbe\u65b9\u5f0f\u6548\u679c\u4e00\u6837\u3002 ax.plot(x, y, 'g--') ax.plot(x, y, linestyle='--', color='g') Out[6]: 'agg' \u5b89\u88c5\u4e0b\u9762\u51e0\u4e2a\u5305\uff1a sudo zypper in python-tk python3-tk sudo zypper in plplot-tcltk-devel plplot-tcltk-libs pip install tk \u6dfb\u52a0\u4e0b\u9762\u5230python\u4ee3\u7801\u4e2d\u3002 import matplotlib.pyplot as plt mpl.use('TkAgg') \u6267\u884c\u540e\u62a5\u4e0b\u9762\u9519\u8bef\uff1a your Python may not be configured for Tk \u8fdb\u5165python\u6e90\u7801\u76ee\u5f55\uff0c\u91cd\u65b0\u7f16\u8bd1\u4f8b\u5982\uff1a\u4e0b\u9762\u4e24\u79cd\u8868\u8fbe\u65b9\u5f0f\u6548\u679c\u4e00\u6837\u3002 ax.plot(x, y, 'g--') ax.plot(x, y, linestyle='--', color='g') james@lizard:/opt/Python-3.9.6> sudo make james@lizard:/opt/Python-3.9.6> sudo make install \u95ee\u9898\u89e3\u51b3\uff0c\u5373\u4f7f\u4e0d\u52a0\u5165 mpl.use('TkAgg') \uff0c\u6267\u884c plt.show() \u4e5f\u662f\u53ef\u4ee5\u8f93\u51fa\u56fe\u50cf\u3002 \u56fe\u7247\u4e0e\u5b50\u56fe \u00b6 matplotlib \u6240\u7ed8\u5236\u7684\u56fe\u4f4d\u4e8e\u56fe\u7247\uff08Figure\uff09\u5bf9\u8c61\u4e2d\u3002\u53ef\u4ee5\u4f7f\u7528 plt.figure \u751f\u6210\u4e00\u4e2a\u65b0\u7684\u56fe\u7247\u3002 \u4f7f\u7528 add_subplot \u521b\u5efa\u4e00\u4e2a\u6216\u591a\u4e2a\u5b50\u56fe\uff08subplot\uff09\u3002 plt \u4e0e ax \u7ed8\u56fe\u3002 fig = plt.figure() # plt: \u5148\u751f\u6210\u4e86\u4e00\u4e2a\u753b\u5e03\uff0c\u7136\u540e\u5728\u8fd9\u4e2a\u753b\u5e03\u4e0a\u9690\u5f0f\u7684\u751f\u6210\u4e00\u4e2a\u753b\u56fe\u533a\u57df\u6765\u8fdb\u884c\u753b\u56fe # plt.plot([1, 2, 3, 4]) # plt.show() # ax: \u5148\u751f\u6210\u4e00\u4e2a\u753b\u5e03\uff082\u00d72\u7684\u533a\u57df\uff0c\u6700\u591a\u653e\u56db\u4e2a\u56fe\u5f62\uff09\uff0c\u7136\u540e\u5728\u6b64\u753b\u5e03\u4e0a\uff0c\u9009\u5b9a\u4e00\u4e2a\u5b50\u533a\u57df\u753b\u4e86\u4e00\u4e2a\u5b50\u56fe\uff08\u5e8f\u53f71\u4ee3\u8868\u7b2c\u4e00\u4e2a\u533a\u57df\uff09 ax1 = fig.add_subplot(2, 2, 1) # \u4e5f\u53ef\u4ee5\u5199\u6210fig.add_subplot(221) ax1.plot([1, 2, 3, 4], [1, 4, 3, 2]) # \u8f93\u51fa\u56fe\u7247\u5230\u7b2c\u4e00\u4e2a\u533a\u57df\u3002 # \u7b2c\u4e00\u4e2a\u53c2\u6570\u662f\u6570\u636e\u96c6\u91cc\u5404\u4e2a\u6570\u636e\u70b9\u7684X\u503c\u7684\u96c6\u5408 # \u7b2c\u4e8c\u4e2a\u53c2\u6570\u6570\u636e\u96c6\u91cc\u5404\u4e2a\u6570\u636e\u70b9\u7684Y\u503c\u7684\u96c6\u5408\u3002 # \u4e0d\u662f\u6570\u5b66\u4e0a\u5e38\u89c1\u7684\u6210\u5bf9\u5750\u6807\u70b9\u5982(x1,y1)\u3001(x2,y2)\u3001...\u3001(xn,yn)\u7684\u683c\u5f0f\uff0c\u800c\u662f (x1,x2,...,xn)\u548c(y1,y2,...,yn) \u3002 plt.show() \u770b\u4e0b\u9762\u4f8b\u5b50\uff0c\u589e\u52a0\u5b50\u56fe\u540e\u7684\u6570\u636e\u53ef\u89c6\u5316\u6548\u679c\u3002 fig = plt.figure() ax1 = fig.add_subplot(2, 2, 1) ax2 = fig.add_subplot(2, 2, 2) ax3 = fig.add_subplot(2, 2, 3) ax1.plot(np.random.randn(50).cumsum(), 'k--') # \u5728\u7b2c\u4e09\u4e2a\u533a\u57df\u8f93\u51fa\u56fe\u50cf\u3002'k--\u2019\u662f\u7528\u4e8e\u7ed8\u5236\u9ed1\u8272\u5206\u6bb5\u7ebf\u7684style\u9009\u9879\u3002 ax2.hist(np.random.randn(100), bins=20, color='k', alpha=0.3) ax3.scatter(np.arange(30), np.arange(30) + 3 * np.random.randn(30)) plt.show() plt.subplots \u901a\u8fc7 matplotlib \u7684 subplots \u65b9\u6cd5\uff0c\u4f7f\u7528\u5b50\u56fe\u7f51\u683c\u521b\u5efa\u56fe\u7247\uff0c\u7136\u540e\u8fd4\u56de\u5305\u542b\u4e86\u5df2\u751f\u6210\u5b50\u56fe\u5bf9\u8c61\u7684NumPy\u6570\u7ec4\u3002 \u6570\u7ec4 axes \u53ef\u4ee5\u50cf\u4e8c\u7ef4\u6570\u7ec4\u90a3\u6837\u65b9\u4fbf\u5730\u8fdb\u884c\u7d22\u5f15\uff0c\u4f8b\u5982\uff0c axes[0, 1] \u3002 plt.subplots \u53c2\u6570\u9009\u9879\uff1a nrows\uff1a\u53ef\u9009\u7684\uff0c\u6574\u578b\uff0c\u9ed8\u8ba4\u4e3a1\u3002\u5b50\u56fe\u7f51\u683c\u7684\u884c\u6570\u3002 ncols\uff1a\u53ef\u9009\u7684\uff0c\u6574\u578b\uff0c\u9ed8\u8ba4\u4e3a1\u3002\u5b50\u56fe\u7f51\u683c\u7684\u5217\u6570\u3002 sharex\uff1a\u53ef\u9009\u7684\uff0c\u9ed8\u8ba4\u4e3aFalse\u3002\u53ef\u9009\u503c\u5982\u4e0b\uff1a True\u6216all\uff0c\u6240\u6709\u5b50\u56fe\u5171\u4eabx\u8f74 False\u6216none\uff0c\u6bcf\u4e2a\u5b50\u56fe\u7684x\u8f74\u90fd\u662f\u72ec\u7acb\u7684 row\uff0c\u6bcf\u884c\u5b50\u56fe\u5171\u4eab\u4e00\u4e2ax\u8f74 col\uff0c\u6bcf\u5217\u5b50\u56fe\u5171\u4eab\u4e00\u4e2ax\u8f74 sharey\uff1a\u7c7b\u4f3c\u4e8esharex\uff0c\u8bbe\u7f6ey\u8f74\u7684\u5171\u4eab\u65b9\u5f0f\u3002\u5f53\u67d0\u5217\u5171\u4eab\u4e00\u4e2ax\u8f74\u65f6\uff0c\u53ea\u6709\u5e95\u90e8\u7684\u5b50\u56fe\u4f1a\u521b\u5efax\u8f74\u6807\u8bb0\u3002\u540c\u6837\u7684\uff0c\u5982\u679c\u67d0\u884c\u5171\u4eab\u4e00\u4e2ay\u8f74\u65f6\uff0c\u53ea\u6709\u884c\u7684\u7b2c\u4e00\u5217\u5b50\u56fe\u4f1a\u521b\u5efay\u8f74\u6807\u8bb0\u3002 squeeze \uff1a\u53ef\u9009\u7684\uff0c\u5e03\u5c14\u578b\uff0c\u9ed8\u8ba4\u4e3aTrue\u3002\u662f\u5426\u538b\u7f29\u8fd4\u56de\u7684Axes\u6570\u7ec4\u3002\u5982\u679c\u4e3aTrue\uff0c\u5f53\u53ea\u6709\u4e00\u4e2a\u5b50\u56fe\uff0c\u5373nrows\u548cncols\u5747\u4e3a1\u65f6\uff0c\u8fd4\u56de\u4e00\u4e2a\u5355\u72ec\u7684Axes\u5bf9\u8c61\uff0c\u5f53\u6709N*1\u548c1*M\u4e2a\u5b50\u56fe\u65f6\uff0c\u8fd4\u56de\u4e00\u4e2a\u4e00\u7ef4Axes\u5bf9\u8c61\u6570\u7ec4\u3002\u5f53\u6709N*M\u4e2a\u5b50\u56fe\uff08N>1\uff0cM>1\uff09\u65f6\uff0c\u8fd4\u56de\u4e8c\u7ef4\u6570\u7ec4\u3002\u5982\u679c\u4e3aFalse\uff0c\u5219\u603b\u662f\u8fd4\u56de\u4e8c\u7ef4\u6570\u7ec4\u3002 num\uff1a\u53ef\u9009\u7684\uff0c\u6574\u578b\u6216\u5b57\u7b26\u4e32\uff0c\u9ed8\u8ba4\u4e3aNone\u3002\u662fmatplotlib.pyplot.figure\u7684\u5173\u952e\u5b57\uff0c\u7528\u4e8e\u8bbe\u7f6e\u56fe\u50cf\u6570\u5b57\u6216\u6807\u7b7e\u3002\u5982\u679c\u672a\u8bbe\u7f6e\u6b64\u53c2\u6570\uff0c\u4f1a\u521b\u5efa\u4e00\u4e2a\u65b0\u7684\u56fe\u50cf\uff0c\u5e76\u9012\u589e\u56fe\u50cf\u7f16\u53f7\uff0cfigure\u5bf9\u8c61\u4f1a\u5c06\u7f16\u53f7\u4fdd\u5b58\u5728number\u5c5e\u6027\u4e2d\u3002\u5982\u679c\u8bbe\u7f6e\u4e86\u6b64\u53c2\u6570\uff0c\u5e76\u4e14\u5b58\u5728\u53c2\u6570\u6307\u5b9a\u7684\u56fe\u50cf\uff0c\u5219\u4f1a\u8fd4\u56de\u6b64\u56fe\u50cf\u7684\u5f15\u7528\uff0c\u5982\u679c\u4e0d\u5b58\u5728\u5219\u4f1a\u521b\u5efa\u65b0\u7684\u56fe\u50cf\u5e76\u8fd4\u56de\u5b83\u7684\u5f15\u7528\u3002\u5982\u679c\u662f\u5b57\u7b26\u4e32\uff0c\u5219\u7a97\u53e3\u6807\u9898\u4f1a\u88ab\u8bbe\u7f6e\u4e3a\u6b64\u5b57\u7b26\u4e32\u7684\u503c\u3002 subplot_kw\uff1a\u53ef\u9009\u7684\uff0c\u5b57\u5178\u7c7b\u578b\u3002\u5305\u542b\u4f20\u9012\u7ed9\u7528\u4e8e\u521b\u5efa\u5b50\u56fe\u7684\u8c03\u7528add_subplot\u7684\u5173\u952e\u5b57\u53c2\u6570\u3002 gridspec_kw\uff1a\u53ef\u9009\u7684\uff0c\u5b57\u5178\u7c7b\u578b\u3002\u5305\u542b\u4f20\u9012\u7ed9\u7528\u4e8e\u521b\u5efa\u5b50\u56fe\u7f51\u683c\u7684GridSpec\u6784\u9020\u51fd\u6570\u7684\u5173\u952e\u5b57\u53c2\u6570\u3002 fig, axes = plt.subplots(2, 3) print(axes) # \u5c06\u751f\u6210\u7684axes\u5bf9\u8c61\u653e\u5165NumPy\u6570\u7ec4\u3002 # [[ ] # [ ]] \u8c03\u6574\u5b50\u56fe\u5468\u56f4\u7684\u95f4\u8ddd\u3002 \u9ed8\u8ba4\u60c5\u51b5\u4e0b\uff0c matplotlib \u4f1a\u5728\u5b50\u56fe\u7684\u5916\u90e8\u548c\u5b50\u56fe\u4e4b\u95f4\u7559\u51fa\u4e00\u5b9a\u7684\u95f4\u8ddd\u3002 \u8fd9\u4e2a\u95f4\u8ddd\u90fd\u662f\u76f8\u5bf9\u4e8e\u56fe\u7684\u9ad8\u5ea6\u548c\u5bbd\u5ea6\u6765\u6307\u5b9a\u7684\uff0c\u624b\u52a8\u8c03\u6574\u56fe\u7684\u5927\u5c0f\uff0c\u90a3\u4e48\u95f4\u8ddd\u4f1a\u81ea\u52a8\u8c03\u6574\u3002 \u4e5f\u53ef\u4ee5\u4f7f\u7528\u56fe\u5bf9\u8c61\u4e0a\u7684 subplots_adjust \u65b9\u6cd5\u66f4\u6539\u95f4\u8ddd\uff0c\u4e5f\u53ef\u4ee5\u7528\u4f5c\u9876\u5c42\u51fd\u6570\u3002 fig, axes = plt.subplots(2, 2, sharex=True, sharey=True) for i in range(2): for j in range(2): axes[i, j].hist(np.random.randn(500), bins=50, color='k', alpha=0.5) plt.subplots_adjust(wspace=0, hspace=0) plt.show() \u4e0a\u9762\u8f93\u51fa\u56fe\u50cf\u7684\u8f74\u6807\u7b7e\u662f\u5b58\u5728\u91cd\u53e0\u7684\u3002 matplotlib \u5e76\u4e0d\u68c0\u67e5\u6807\u7b7e\u662f\u5426\u91cd\u53e0\uff0c\u56e0\u6b64\u5728\u7c7b\u4f3c\u60c5\u51b5\u4e0b\u4f60\u9700\u8981\u901a\u8fc7\u663e\u5f0f\u6307\u5b9a\u523b\u5ea6\u4f4d\u7f6e\u548c\u523b\u5ea6\u6807\u7b7e\u7684\u65b9\u6cd5\u6765\u4fee\u590d\u8f74\u6807\u7b7e\u3002 \u989c\u8272\u3001\u6807\u8bb0\u548c\u7ebf\u7c7b\u578b \u00b6 matplotlib \u7684\u4e3b\u51fd\u6570 plot \u63a5\u6536\u5e26\u6709 x \u548c y \u8f74\u7684\u6570\u7ec4\u4ee5\u53ca\u4e00\u4e9b\u53ef\u9009\u7684\u5b57\u7b26\u4e32\u7f29\u5199\u53c2\u6570\u6765\u6307\u660e\u989c\u8272\u548c\u7ebf\u7c7b\u578b\u3002 \u4f8b\u5982\uff1a\u4e0b\u9762\u4e24\u79cd\u8868\u8fbe\u65b9\u5f0f\u6548\u679c\u4e00\u6837\u3002 ax.plot(x, y, 'g--') ax.plot(x, y, linestyle='--', color='g') data = np.random.randn(30).cumsum() plt.plot(data, 'ko--') plt.show() # \u4e0a\u9762\u7684\u4ee3\u7801\u53ef\u4ee5\u5199\u5f97\u66f4\u4e3a\u663e\u5f0f\uff1a plt.plot(data, color='k', linestyle='dashed', marker='o') plt.show() plt.plot(data, color='k', linestyle='dashed', marker='o', label='Default') plt.show() plt.plot(data, color='k', linestyle='dashed', marker='o', label='steps-post', drawstyle='steps-post') plt.show() \u523b\u5ea6\u3001\u6807\u7b7e\u548c\u56fe\u4f8b \u00b6 \u5bf9\u4e8e\u5927\u591a\u6570\u56fe\u8868\u4fee\u9970\u5de5\u4f5c\uff0c\u6709\u4e24\u79cd\u4e3b\u8981\u7684\u65b9\u5f0f\uff1a\u4f7f\u7528\u7a0b\u5e8f\u6027\u7684pyplot\u63a5\u53e3\uff08\u5373matplotlib.pyplot\uff09\u548c\u66f4\u591a\u9762\u5411\u5bf9\u8c61\u7684\u539f\u751fmatplotlib API\u3002 pyplot \u63a5\u53e3\u8bbe\u8ba1\u4e3a\u4ea4\u4e92\u5f0f\u4f7f\u7528\uff0c\u5305\u542b\u4e86\u50cf xlim \u3001 xticks \u548c xticklabels \u7b49\u65b9\u6cd5\u3002\u8fd9\u4e9b\u65b9\u6cd5\u5206\u522b\u63a7\u5236\u4e86\u7ed8\u56fe\u8303\u56f4\u3001\u523b\u5ea6\u4f4d\u7f6e\u4ee5\u53ca\u523b\u5ea6\u6807\u7b7e\u3002 \u5728\u6ca1\u6709\u51fd\u6570\u53c2\u6570\u7684\u60c5\u51b5\u4e0b\u8c03\u7528\uff0c\u8fd4\u56de\u5f53\u524d\u7684\u53c2\u6570\u503c\uff08\u4f8b\u5982 plt.xlim() \u8fd4\u56de\u5f53\u524d\u7684x\u8f74\u7ed8\u56fe\u8303\u56f4\uff09\u3002 \u4f20\u5165\u53c2\u6570\u7684\u60c5\u51b5\u4e0b\u8c03\u7528\uff0c\u5e76\u8bbe\u7f6e\u53c2\u6570\u503c\uff08\u4f8b\u5982 plt.xlim\uff08[0, 10]\uff09 \u4f1a\u5c06 x \u8f74\u7684\u8303\u56f4\u8bbe\u7f6e\u4e3a0\u523010\uff09\u3002 \u6240\u6709\u7684\u8fd9\u4e9b\u65b9\u6cd5\u90fd\u4f1a\u5728\u5f53\u524d\u6d3b\u52a8\u7684\u6216\u6700\u8fd1\u521b\u5efa\u7684 AxesSubplot \u4e0a\u751f\u6548\u3002 \u8fd9\u4e9b\u65b9\u6cd5\u4e2d\u7684\u6bcf\u4e00\u4e2a\u5bf9\u5e94\u4e8e\u5b50\u56fe\u81ea\u8eab\u7684\u4e24\u4e2a\u65b9\u6cd5\u3002\u6bd4\u5982 xlim \u5bf9\u5e94\u4e8e ax.get_lim \u548c ax.set_lim \u3002 \u63a8\u8350\u4f7f\u7528 subplot \u7684\u5b9e\u4f8b\u65b9\u6cd5\uff0c\u56e0\u4e3a\u8fd9\u6837\u66f4\u4e3a\u663e\u5f0f\uff08\u5c24\u5176\u662f\u5728\u5904\u7406\u591a\u4e2a\u5b50\u56fe\u65f6\uff09\u3002 data = np.random.randn(1000).cumsum() fig = plt.figure() # \u8bbe\u5b9a\u5b50\u56fe ax = fig.add_subplot(1, 1, 1) # \u8bbe\u5b9ax\u8f74\u5bf9\u5e94\u53c2\u6570\uff1a # \u8bbe\u5b9ax\u8f74\u523b\u5ea6 ax.set_xticks([0, 250, 500, 750, 1000]) # \u8bbe\u5b9ax\u8f74\u6807\u7b7e ax.set_xticklabels(['one(0)', 'two(250)', 'three(500)', 'four(750)', 'five(1000)'], rotation=30, fontsize='small') # \u7ed9x\u8f74\u4e00\u4e2a\u540d\u79f0 ax.set_xlabel('Stages') # \u8bbe\u5b9ay\u8f74\u5bf9\u5e94\u53c2\u6570\uff1a # \u672a\u6307\u5b9a\u7684\u53c2\u6570\u7531\u7cfb\u7edf\u9ed8\u8ba4\u4ea7\u751f\u3002 ax.set_ylabel('Steps') # \u7ed9\u5b50\u56fe\u6dfb\u52a0\u4e00\u4e2a\u6807\u9898 ax.set_title('My first matplotlib plot') # \u7ed9\u5b50\u56fe\u6dfb\u52a0\u4e00\u4e2a\u56fe\u4f8b\uff08\u5982\uff1a\u7ed9\u5b50\u56fe\u5185\u4e00\u4e2a\u56fe\u5f62\u66f2\u7ebf\u6dfb\u52a0\u4e00\u4e2alabel\uff09 ax.plot(data, 'k--', label='Label One') # loc\u53c2\u6570\u544a\u8bc9matplotlib\u5728\u54ea\u91cc\u653e\u7f6e\u56fe\u8868\u3002legend\u65b9\u6cd5\u6709\u591a\u4e2a\u5176\u4ed6\u7684\u4f4d\u7f6e\u53c2\u6570loc\u3002 ax.legend(loc='best') # \u6216\u8005plt.legend(loc='best') \u3002 # \u5728\u56fe\u5f62\u5750\u6807\u4e3a(0, 0)\u7684\u4f4d\u7f6e\u6dfb\u52a0\u4e00\u4e2alable ax.text(0, 0, 'Hello World1', family='monospace', fontsize=10) # \u7ed9\u5b50\u56fe\u6dfb\u52a0annotate\u3002\u7528\u4e00\u4e2a\u7bad\u5934\u6307\u5411\u8981\u6ce8\u91ca\u7684\u5730\u65b9\uff0c\u518d\u5199\u4e0a\u4e00\u6bb5\u8bdd\u7684\u884c\u4e3a\uff0c\u53eb\u505aannotate\u3002 # * s: \u6ce8\u91ca\u7684\u5185\u5bb9\uff0c\u4e00\u6bb5\u6587\u5b57\uff1b # * xytext: \u8fd9\u6bb5\u6587\u5b57\u6240\u5904\u7684\u4f4d\u7f6e; # * xy: \u7bad\u5934\u6307\u5411\u7684\u4f4d\u7f6e\uff1b # * arrowprops: \u901a\u8fc7arrowstyle\u8868\u660e\u7bad\u5934\u7684\u98ce\u683c\u6216\u79cd\u7c7b\u3002 ax.annotate('Zero is here!', xytext=(20, 20), xy=(1, 1), arrowprops=dict(arrowstyle='->')) # \u7ed9\u5b50\u56fe\u6dfb\u52a0\u4e00\u4e9b\u56fe\u5f62 # matplotlib\u542b\u6709\u8868\u793a\u591a\u79cd\u5e38\u89c1\u56fe\u5f62\u7684\u5bf9\u8c61\uff0c\u8fd9\u4e9b\u5bf9\u8c61\u7684\u5f15\u7528\u662fpatches\u3002 # \u4e00\u4e9b\u56fe\u5f62\uff0c\u6bd4\u5982Rectangle\uff08\u77e9\u5f62\uff09\u548cCircle\uff08\u5706\u5f62\uff09\uff0c\u53ef\u4ee5\u5728matplotlib.pyplot\u4e2d\u627e\u5230\uff0c\u4f46\u56fe\u5f62\u7684\u5168\u96c6\u4f4d\u4e8ematplotlib.patches\u3002 rect = plt.Rectangle((10, 5), 100, 15, color='k', alpha=0.3) circ = plt.Circle((200, 9), 95, color='b', alpha=0.3) pgon = plt.Polygon([[500, 5], [600, -5], [700, 30]], color='g', alpha=0.5) ax.add_patch(rect) ax.add_patch(circ) ax.add_patch(pgon) # \u5c06\u56fe\u7247\u4fdd\u5b58\u5230\u6587\u4ef6 # \u6587\u4ef6\u7c7b\u578b\u662f\u4ece\u6587\u4ef6\u6269\u5c55\u540d\u4e2d\u63a8\u65ad\u51fa\u6765\u7684\u3002\u6240\u4ee5\u5982\u679c\u4f60\u4f7f\u7528\uff0epdf\uff0c\u5219\u4f1a\u5f97\u5230\u4e00\u4e2aPDF\u3002 # \u51e0\u4e2a\u91cd\u8981\u7684\u9009\u9879\uff1adpi\uff0c\u5b83\u63a7\u5236\u6bcf\u82f1\u5bf8\u70b9\u6570\u7684\u5206\u8fa8\u7387\uff1bbbox_inches\uff0c\u53ef\u4ee5\u4fee\u526a\u5b9e\u9645\u56fe\u5f62\u7684\u7a7a\u767d\u3002 plt.savefig('../examples/figpath.png', dpi=400, bbox_inches='tight') # saveifg\u5e76\u975e\u4e00\u5b9a\u662f\u5199\u5230\u786c\u76d8\u7684\uff0c\u5b83\u53ef\u4ee5\u5c06\u56fe\u7247\u5199\u5165\u5230\u6240\u6709\u7684\u6587\u4ef6\u578b\u5bf9\u8c61\u4e2d\uff0c\u4f8b\u5982BytesIO buffer = BytesIO() plt.savefig(buffer) plot_data = buffer.getvalue() plt.show() matplotlib\u8bbe\u7f6e \u00b6 matplotlib \u914d\u7f6e\u4e86\u914d\u8272\u65b9\u6848\u548c\u9ed8\u8ba4\u8bbe\u7f6e\uff0c\u901a\u8fc7\u5168\u5c40\u53c2\u6570\u6765\u5b9a\u5236\uff0c\u5305\u62ec\u56fe\u5f62\u5927\u5c0f\u3001\u5b50\u56fe\u95f4\u8ddd\u3001\u989c\u8272\u3001\u5b57\u4f53\u5927\u5c0f\u548c\u7f51\u683c\u6837\u5f0f\u7b49\u7b49\u3002 \u4f7f\u7528 rc \u65b9\u6cd5\u662f\u4f7f\u7528Python\u7f16\u7a0b\u4fee\u6539\u914d\u7f6e\u7684\u4e00\u79cd\u65b9\u5f0f\u3002 rc \u7684\u7b2c\u4e00\u4e2a\u53c2\u6570\u662f\u4f60\u60f3\u8981\u81ea\u5b9a\u4e49\u7684\u7ec4\u4ef6\uff0c\u6bd4\u5982 'figure'\u3001'axes'\u3001'xtick'\u3001'ytick'\u3001'grid'\u3001'legend' \u7b49\u7b49\u3002 \u4e4b\u540e\uff0c\u53ef\u4ee5\u6309\u7167\u5173\u952e\u5b57\u53c2\u6570\u7684\u5e8f\u5217\u6307\u5b9a\u65b0\u53c2\u6570\u3002 \u5b57\u5178\u662f\u4e00\u79cd\u5728\u7a0b\u5e8f\u4e2d\u8bbe\u7f6e\u9009\u9879\u7684\u7b80\u5355\u65b9\u5f0f\u3002\u6bd4\u5982\uff1a plt.rc('figure', figsize=(10, 10)) font_options = { 'family': 'monospace', 'weight': 'bold', 'size': 'small' } plt.rc('font', **font_options) \u4f7f\u7528pandas\u548cseaborn\u7ed8\u56fe \u00b6 pandas\u81ea\u8eab\u6709\u5f88\u591a\u5185\u5efa\u65b9\u6cd5\u53ef\u4ee5\u7b80\u5316\u4eceDataFrame\u548cSeries\u5bf9\u8c61\u751f\u6210\u53ef\u89c6\u5316\u7684\u8fc7\u7a0b\u3002 \u53e6\u4e00\u4e2a\u5e93\u662f seaborn \u3002 seaborn \u7b80\u5316\u4e86\u5f88\u591a\u5e38\u7528\u53ef\u89c6\u5316\u7c7b\u578b\u7684\u751f\u6210\u3002 \u5bfc\u5165 seaborn \u4f1a\u4fee\u6539\u9ed8\u8ba4\u7684matplotlib\u914d\u8272\u65b9\u6848\u548c\u7ed8\u56fe\u6837\u5f0f\uff0c\u8fd9\u4f1a\u63d0\u9ad8\u56fe\u8868\u7684\u53ef\u8bfb\u6027\u548c\u7f8e\u89c2\u6027\u3002 \u5373\u4f7f\u4e0d\u4f7f\u7528seaborn\u7684API\uff0c\u4e5f\u53ef\u4ee5\u5bfc\u5165seaborn\u6765\u4e3a\u901a\u7528matplotlib\u56fe\u8868\u63d0\u4f9b\u66f4\u597d\u7684\u89c6\u89c9\u7f8e\u89c2\u5ea6\u3002 import pandas as pd import numpy as np import matplotlib.pyplot as plt import seaborn as sns \u6298\u7ebf\u56fe \u00b6 Series\u548cDataFrame\u90fd\u6709\u4e00\u4e2a plot \u5c5e\u6027\uff0c\u7528\u4e8e\u7ed8\u5236\u57fa\u672c\u7684\u56fe\u5f62\u3002\u9ed8\u8ba4\u60c5\u51b5\u4e0b\uff0c plot() \u7ed8\u5236\u7684\u662f\u6298\u7ebf\u56fe\u3002 Series\u7684 plot \u53c2\u6570\uff1a ax: matplotlib\u5b50\u56fe\u5bf9\u8c61axes\uff0c\u5982\u679c\u6ca1\u6709\u4f20\u503c\uff0c\u5219\u4f7f\u7528\u5f53\u524d\u6d3b\u52a8\u7684\u5b50\u56fe\u9ed8\u8ba4\u4f7f\u7528gca() alpha: \u56fe\u7247\u4e0d\u900f\u660e\u5ea6\uff080\u52301\uff09 data: \u6570\u636e\u5e8f\u5217Series figsize: \u56fe\u50cf\u5c3a\u5bf8\uff0ctuple(\u5bbd\u5ea6\uff0c\u9ad8\u5ea6)\uff0c\u6ce8\u610f\u8fd9\u91cc\u7684\u5355\u4f4d\u662f\u82f1\u5bf8 fontsize: \u8bbe\u7f6e\u523b\u5ea6\u6807\u7b7e\uff08xticks, yticks\uff09\u7684\u5927\u5c0f grid: \u7f51\u683c\u7ebf\uff08\u9ed8\u8ba4\u662f\u6253\u5f00\u7684\uff09 kind: \u56fe\u7c7b\u578b\uff1a\u6298\u7ebf\u56fe\uff0c\u67f1\u5f62\u56fe\uff0c\u6a2a\u5411\u67f1\u5f62\u56fe\uff0c\u76f4\u65b9\u56fe\uff0c\u7bb1\u7ebf\u56fe\uff0c\u5bc6\u5ea6\u56fe\uff0c\u9762\u79ef\u56fe\uff0c\u997c\u56fe label: \u5217\u7684\u522b\u540d\uff0c\u4f5c\u7528\u5728\u56fe\u4f8b\u4e0a legend: \u56fe\u4f8b loglog: x,y\u8f74\u90fd\u4f7f\u7528\u5bf9\u6570\u523b\u5ea6 logx: x\u8f74\u4f7f\u7528\u5bf9\u6570\u523b\u5ea6 logy: y\u8f74\u4f7f\u7528\u5bf9\u6570\u523b\u5ea6 mark_right: \u53cc y \u8f74\u65f6\uff0c\u5728\u56fe\u4f8b\u4e2d\u7684\u5217\u6807\u7b7e\u65c1\u589e\u52a0\u663e\u793a (right) \u6807\u8bc6 position: \u67f1\u5f62\u56fe\u7684\u67f1\u5b50\u7684\u4f4d\u7f6e\u8bbe\u7f6e rot: \u6539\u53d8\u523b\u5ea6\u6807\u7b7e\uff08xticks, yticks\uff09\u7684\u65cb\u8f6c\u5ea6\uff080\u5230360\uff09 secondary_y: \u53cc y \u8f74\uff0c\u5728\u53f3\u8fb9\u7684\u7b2c\u4e8c\u4e2a y \u8f74 style: \u7ebf\u7684\u6837\u5f0f\uff0c\u6bd4\u5982'ko--' table: \u5c06\u6570\u636e\u4ee5\u8868\u683c\u7684\u5f62\u5f0f\u5c55\u793a\u51fa\u6765 title: \u6807\u9898 use_index: \u662f\u5426\u4f7f\u7528\u7d22\u5f15\u4f5c\u4e3ax\u523b\u5ea6\u6807\u7b7e xerr: \u5e26\u8bef\u5dee\u7ebf\u7684\u67f1\u5f62\u56fe xlim: \u6a2a\u8f74\u5750\u6807\u523b\u5ea6\u7684\u53d6\u503c\u8303\u56f4 xticks: x\u8f74\u523b\u5ea6\u6807\u7b7e yerr: \u5e26\u8bef\u5dee\u7ebf\u7684\u67f1\u5f62\u56fe ylim: \u7eb5\u8f74\u5750\u6807\u523b\u5ea6\u7684\u53d6\u503c\u8303\u56f4 yticks: y\u8f74\u523b\u5ea6\u6807\u7b7e **kwds: matplotlib plot\u65b9\u6cd5\u7684\u5176\u4ed6\u53c2\u6570 DataFrame\u7684 plot \u53c2\u6570\uff1a x : \u6307\u6570\u636e\u6846\u5217\u7684\u6807\u7b7e\u6216\u4f4d\u7f6e\u53c2\u6570 y : \u6307\u6570\u636e\u6846\u5217\u7684\u6807\u7b7e\u6216\u4f4d\u7f6e\u53c2\u6570 kind : 'line' : \u6298\u7ebf\u56fe 'bar' : \u6761\u5f62\u56fe 'barh' : \u6a2a\u5411\u6761\u5f62\u56fe 'hist' : \u67f1\u72b6\u56fe 'box' : \u7bb1\u7ebf\u56fe 'kde' : Kernel\u7684\u5bc6\u5ea6\u4f30\u8ba1\u56fe\uff0c\u4e3b\u8981\u5bf9\u67f1\u72b6\u56fe\u6dfb\u52a0Kernel \u6982\u7387\u5bc6\u5ea6\u7ebf 'density' : 'kde' 'area' : area plot 'pie' : \u997c\u56fe 'scatter' : \u6563\u70b9\u56fe \u9700\u8981\u4f20\u5165columns\u65b9\u5411\u7684\u7d22\u5f15 'hexbin' : hexbin plot ax : \u5b50\u56fe(axes, \u4e5f\u53ef\u4ee5\u7406\u89e3\u6210\u5750\u6807\u8f74) \u8981\u5728\u5176\u4e0a\u8fdb\u884c\u7ed8\u5236\u7684matplotlib subplot\u5bf9\u8c61\u3002\u5982\u679c\u6ca1\u6709\u8bbe\u7f6e\uff0c\u5219\u4f7f\u7528\u5f53\u524dmatplotlib subplot\u3002\u5176\u4e2d\uff0c\u53d8\u91cf\u548c\u51fd\u6570\u901a\u8fc7\u6539\u53d8figure\u548caxes\u4e2d\u7684\u5143\u7d20\uff08\u4f8b\u5982\uff1atitle,label,\u70b9\u548c\u7ebf\u7b49\u7b49\uff09\u4e00\u8d77\u63cf\u8ff0figure\u548caxes\uff0c\u4e5f\u5c31\u662f\u5728\u753b\u5e03\u4e0a\u7ed8\u56fe\u3002 subplots : \u5224\u65ad\u56fe\u7247\u4e2d\u662f\u5426\u6709\u5b50\u56fe sharex : \u5982\u679c\u6709\u5b50\u56fe\uff0c\u5b50\u56fe\u5171x\u8f74\u523b\u5ea6\uff0c\u6807\u7b7e sharey : \u5982\u679c\u6709\u5b50\u56fe\uff0c\u5b50\u56fe\u5171y\u8f74\u523b\u5ea6\uff0c\u6807\u7b7e layout : \u5b50\u56fe\u7684\u884c\u5217\u5e03\u5c40 figsize : \u56fe\u7247\u5c3a\u5bf8\u5927\u5c0f use_index : \u9ed8\u8ba4\u7528\u7d22\u5f15\u505ax\u8f74 title : \u56fe\u7247\u7684\u6807\u9898\u7528\u5b57\u7b26\u4e32 grid : \u56fe\u7247\u662f\u5426\u6709\u7f51\u683c legend : \u5b50\u56fe\u7684\u56fe\u4f8b\uff0c\u6dfb\u52a0\u4e00\u4e2asubplot\u56fe\u4f8b(\u9ed8\u8ba4\u4e3aTrue) style : \u5bf9\u6bcf\u5217\u6298\u7ebf\u56fe\u8bbe\u7f6e\u7ebf\u7684\u7c7b\u578b logx : \u8bbe\u7f6ex\u8f74\u523b\u5ea6\u662f\u5426\u53d6\u5bf9\u6570 logy : \u8bbe\u7f6ey\u8f74\u523b\u5ea6\u662f\u5426\u53d6\u5bf9\u6570 loglog : \u540c\u65f6\u8bbe\u7f6ex\uff0cy\u8f74\u523b\u5ea6\u662f\u5426\u53d6\u5bf9\u6570 xticks : \u8bbe\u7f6ex\u8f74\u523b\u5ea6\u503c\uff0c\u5e8f\u5217\u5f62\u5f0f\uff08\u6bd4\u5982\u5217\u8868\uff09 yticks : \u8bbe\u7f6ey\u8f74\u523b\u5ea6\uff0c\u5e8f\u5217\u5f62\u5f0f\uff08\u6bd4\u5982\u5217\u8868\uff09 xlim : \u8bbe\u7f6e\u5750\u6807\u8f74x\u7684\u8303\u56f4\uff0c\u5217\u8868\u6216\u5143\u7ec4\u5f62\u5f0f ylim : \u8bbe\u7f6e\u5750\u6807\u8f74y\u7684\u8303\u56f4\uff0c\u5217\u8868\u6216\u5143\u7ec4\u5f62\u5f0f rot : \u8bbe\u7f6e\u8f74\u6807\u7b7e\uff08\u8f74\u523b\u5ea6\uff09\u7684\u663e\u793a\u65cb\u8f6c\u5ea6\u6570 fontsize : \u8bbe\u7f6e\u8f74\u523b\u5ea6\u7684\u5b57\u4f53\u5927\u5c0f colormap : \u8bbe\u7f6e\u56fe\u7684\u533a\u57df\u989c\u8272 colorbar : \u56fe\u7247\u67f1\u5b50 position : Specify relative alignments for bar plot layout. From 0 (left/bottom-end) to 1 (right/top-end). Default is 0.5 (center) layout : \u5e03\u5c40(rows, columns) for the layout of the plot table : \u5982\u679c\u4e3a\u6b63\uff0c\u5219\u9009\u62e9DataFrame\u7c7b\u578b\u7684\u6570\u636e\u5e76\u4e14\u8f6c\u6362\u5339\u914dmatplotlib\u7684\u5e03\u5c40 yerr : \u5e26\u8bef\u5dee\u7ebf\u7684\u67f1\u5f62\u56fe xerr : \u5e26\u8bef\u5dee\u7ebf\u7684\u67f1\u5f62\u56fe stacked : \u751f\u6210\u5806\u79ef\u67f1\u72b6\u56fe sort_columns : \u4ee5\u5b57\u6bcd\u8868\u987a\u5e8f\u7ed8\u5236\u5404\u5217\uff0c\u9ed8\u8ba4\u4f7f\u7528\u524d\u5217\u987a\u5e8f secondary_y : \u8bbe\u7f6e\u7b2c\u4e8c\u4e2ay\u8f74\uff08\u53f3y\u8f74\uff09 mark_right : When using a secondary_y axis, automatically mark the column labels with \u201c(right)\u201d in the legend kwds : Options to pass to matplotlib plotting method Series data1 = np.random.randn(10).cumsum(0) s1 = pd.Series( data1, index=np.arange(0, 100, 10), ) print(s1) fig, axes = plt.subplots(3, 1) # 3\u4e2a\u5b50\u56fe s1.plot.bar(ax=axes[0], color='k', alpha=0.7) # \u6761\u5f62\u56fe(\u5b50\u56fe0)\uff0ccolor='k\u2019(\u67f1\u5b50\u7684\u989c\u8272\u8bbe\u7f6e\u4e3a\u9ed1\u8272)\uff0calpha=0.7(\u56fe\u50cf\u7684\u586b\u5145\u8272\u8bbe\u7f6e\u4e3a\u90e8\u5206\u900f\u660e) s1.plot.barh(ax=axes[1], color='k', alpha=0.7) # \u6a2a\u5411\u6761\u5f62\u56fe(\u5b50\u56fe1) s1.value_counts().plot.pie(ax=axes[2]) # \u901a\u8fc7value_counts()\u5bf9Series\u503c\u9891\u7387\u8fdb\u884c\u53ef\u89c6\u5316 plt.show() DataFrame data2 = np.random.randn(10, 4).cumsum(0) df1 = pd.DataFrame( data2, columns=pd.Index(['A', 'B', 'C', 'D'], name='Genus'), index=np.arange(0, 100, 10) ) print(df1) fig, axes = plt.subplots(2, 1) # 2\u4e2a\u5b50\u56fe df1.plot.kde(ax=axes[0], alpha=0.7, grid='True', title='KDE Figure', sharex=True) df1.plot.bar(ax=axes[1], grid='True', title='Line Figure', sharex=True, use_index=False, stacked=True) # \u56e0\u4e3a\u5171\u4eabx\u8f74\uff0c\u6240\u4ee5\u5728KDE\u5b50\u56fe\u4e2d\u6307\u5b9ause_index=False\u770b\u4e0d\u51fa\u6548\u679c\u3002 # DataFrame\u7684\u5217\u540d\u79f0\"Genus\"\u88ab\u7528\u4f5c\u4e86\u56fe\u4f8b\u6807\u9898 # stacked=True\u6765\u751f\u6210\u5806\u79ef\u67f1\u72b6\u56fe plt.show() \u5b9e\u4f8b\uff1a\u7ed8\u5236\u4e00\u4e2a\u5806\u79ef\u67f1\u72b6\u56fe\uff0c\u7528\u4e8e\u5c55\u793a\u6bcf\u4e2a\u6d3e\u5bf9\u5728\u6bcf\u5929\u7684\u6570\u636e\u70b9\u5360\u6bd4\u3002 \u4ea4\u53c9\u8868 \u662f\u4e00\u79cd\u5e38\u7528\u7684\u5206\u7c7b\u6c47\u603b\u8868\u683c\uff0c\u7528\u4e8e\u9891\u6570\u5206\u5e03\u7edf\u8ba1\uff0c\u4e3b\u8981\u4ef7\u503c\u5728\u4e8e\u63cf\u8ff0\u4e86\u53d8\u91cf\u95f4\u5173\u7cfb\u7684\u6df1\u523b\u542b\u4e49\u3002 \u867d\u7136\u4e24\u4e2a\uff08\u6216\u4ee5\u4e0a\uff09\u53d8\u91cf\u53ef\u4ee5\u662f\u5206\u7c7b\u7684\u6216\u6570\u91cf\u7684\uff0c\u4f46\u662f\u4ee5\u90fd\u662f\u5206\u7c7b\u7684\u60c5\u5f62\u6700\u4e3a\u5e38\u89c1\u3002 Pandas\u7684 crosstab() \u65b9\u6cd5\u80fd\u591f\u5feb\u901f\u6784\u5efa\u4ea4\u53c9\u8868\uff0c\u5e76\u53ef\u4ee5\u901a\u8fc7\u53c2\u6570\u52a0\u4ee5\u4e2a\u6027\u5316\u7684\u8bbe\u7f6e\u3002\u5176\u4e2d\uff0c\u7b2c\u4e00\u4e2a\u53c2\u6570\u5c06\u6784\u6210\u4ea4\u53c9\u8868\u7684\u884c\uff0c\u7b2c\u4e8c\u4e2a\u53c2\u6570\u5c06\u6784\u6210\u4ea4\u53c9\u8868\u7684\u5217\u3002 tips = pd.read_csv('../examples/tips.csv') print(tips) # total_bill tip smoker day time size # 0 16.99 1.01 No Sun Dinner 2 # 1 10.34 1.66 No Sun Dinner 3 # 2 21.01 3.50 No Sun Dinner 3 # 3 23.68 3.31 No Sun Dinner 2 # 4 24.59 3.61 No Sun Dinner 4 # .. ... ... ... ... ... ... # 239 29.03 5.92 No Sat Dinner 3 # 240 27.18 2.00 Yes Sat Dinner 2 # 241 22.67 2.00 Yes Sat Dinner 2 # 242 17.82 1.75 No Sat Dinner 2 # 243 18.78 3.00 No Thur Dinner 2 # [244 rows x 6 columns] party_counts = pd.crosstab(tips['day'], tips['size']) # \u5bf9\u539f\u59cb\u6570\u636e\u7684day\u548csize\u8fdb\u884c\u805a\u5408\uff0c\u5e76\u6784\u5efa\u4ea4\u53c9\u8868\uff0cday\u4f5c\u4e3a\u884c\uff0csize\u4f5c\u4e3a\u5217\u3002 print(party_counts) # size 1 2 3 4 5 6 # day # Fri 1 16 1 1 0 0 # Sat 2 53 18 13 1 0 # Sun 0 39 15 18 3 1 # Thur 1 48 4 5 1 3 # \u6ca1\u6709\u592a\u591a\u76841\u4eba\u548c6\u4eba\u6d3e\u5bf9\uff0c\u820d\u5f03\u8fd9\u4e9b\u6570\u636e party_counts = party_counts.loc[:, 2:5] print(party_counts) # size 2 3 4 5 # day # Fri 16 1 1 0 # Sat 53 18 13 1 # Sun 39 15 18 3 # Thur 48 4 5 1 # \u6807\u51c6\u5316\u81f3\u548c\u4e3a1\uff1a\u6cbf0\u8f74\uff08\u884c\uff09\u5bf9\u6bcf\u5217\u6c42\u548c\uff0c\u6bcf\u884c\u5404\u503c\u9664\u4ee5\u548c\uff0c\u4ee5\u786e\u4fdd\u6bcf\u4e00\u884c\u7684\u503c\u548c\u4e3a1\uff0c\u7136\u540e\u8fdb\u884c\u7ed8\u56fe party_pcts = party_counts.div(party_counts.sum(1), axis=0) print(party_pcts) # size 2 3 4 5 # day # Fri 0.888889 0.055556 0.055556 0.000000 # Sat 0.623529 0.211765 0.152941 0.011765 # Sun 0.520000 0.200000 0.240000 0.040000 # Thur 0.827586 0.068966 0.086207 0.017241 party_counts.plot.bar() plt.show() \u53ef\u4ee5\u770b\u5230\u672c\u6570\u636e\u96c6\u4e2d\u7684\u6d3e\u5bf9\u6570\u91cf\u5728\u5468\u672b\u4f1a\u589e\u52a0\u3002 \u5b9e\u4f8b\uff1a\u4f7f\u7528seaborn\u8fdb\u884c\u6309\u661f\u671f\u65e5\u671f\u8ba1\u7b97\u5c0f\u8d39\u767e\u5206\u6bd4\u3002 Seaborn\u8981\u6c42\u6570\u636e\u7684\u8f93\u5165\u7c7b\u578b\u4e3apandas\u7684Dataframe\u6216Numpy\u6570\u7ec4\u3002 tips['tip_pct'] = tips['tip'] / (tips['total_bill'] - tips['tip']) print(tips) # total_bill tip smoker day time size tip_pct # 0 16.99 1.01 No Sun Dinner 2 0.063204 # 1 10.34 1.66 No Sun Dinner 3 0.191244 # 2 21.01 3.50 No Sun Dinner 3 0.199886 # 3 23.68 3.31 No Sun Dinner 2 0.162494 # 4 24.59 3.61 No Sun Dinner 4 0.172069 # .. ... ... ... ... ... ... ... # 239 29.03 5.92 No Sat Dinner 3 0.256166 # 240 27.18 2.00 Yes Sat Dinner 2 0.079428 # 241 22.67 2.00 Yes Sat Dinner 2 0.096759 # 242 17.82 1.75 No Sat Dinner 2 0.108899 # 243 18.78 3.00 No Thur Dinner 2 0.190114 # [244 rows x 7 columns] # barplot: \u5c06\u70b9\u4f30\u8ba1\u548c\u7f6e\u4fe1\u533a\u95f4\u663e\u793a\u4e3a\u77e9\u5f62\u6761\u3002\u6761\u5f62\u56fe\u8868\u793a\u5177\u6709\u6bcf\u4e2a\u77e9\u5f62\u7684\u9ad8\u5ea6\u7684\u6570\u503c\u53d8\u91cf\u7684\u96c6\u4e2d\u8d8b\u52bf\u7684\u4f30\u8ba1\uff0c\u5e76\u4e14\u4f7f\u7528\u8bef\u5dee\u6761\u63d0\u4f9b\u56f4\u7ed5\u8be5\u4f30\u8ba1\u7684\u4e0d\u786e\u5b9a\u6027\u7684\u4e00\u4e9b\u6307\u793a # \u67f1\u5b50\u7684\u503c\u662ftip_pct\u7684\u5e73\u5747\u503c # \u67f1\u5b50\u4e0a\u753b\u51fa\u7684\u9ed1\u7ebf\u4ee3\u8868\u7684\u662f95%\u7684\u7f6e\u4fe1\u533a\u95f4\uff08\u7f6e\u4fe1\u533a\u95f4\u53ef\u4ee5\u901a\u8fc7\u53ef\u9009\u53c2\u6570\u8fdb\u884c\u8bbe\u7f6e\uff09 # hue\u9009\u9879\uff0c\u5141\u8bb8\u6211\u4eec\u901a\u8fc7\u4e00\u4e2a\u989d\u5916\u7684\u5206\u7c7b\u503c\u5c06\u6570\u636e\u5206\u79bb # \u5e26\u53c2\u6570hue='time'\u65f6\uff0c\u56db\u4e2a\u4e0d\u540c\u989c\u8272\u7684\u67f1\u5b50\uff0c\u6bcf\u4e2a\u67f1\u5b50\u4e0a\u6709\u7f6e\u4fe1\u533a\u95f4\u7684\u9ed1\u7ebf\uff0c\u523b\u5ea60.00~0.30\uff0c\u6b65\u957f0.05 # \u4e0d\u5e26\u53c2\u6570hue='time'\u65f6\uff0c\u4e24\u4e2a\u4e0d\u540c\u989c\u8272\u7684\u67f1\u5b50\uff0c\u5206\u522b\u4ee3\u8868Dinner\u548cLunch\uff0c\u4e0d\u662f\u6bcf\u4e2a\u67f1\u5b50\u4e0a\u90fd\u6709\u7f6e\u4fe1\u533a\u95f4\u7684\u9ed1\u7ebf\uff0c\u523b\u5ea60.00~0.30\uff0c\u6b65\u957f0.05 sns.barplot(x='tip_pct', y='day', data=tips, hue='time', orient='h') # \u6839\u636e\u661f\u671f\u65e5\u671f\u548c\u65f6\u95f4\u8ba1\u7b97\u7684\u5c0f\u8d39\u767e\u5206\u6bd4 # sns.barplot(x='tip_pct', y='day', data=tips, orient='h') sns.set(style=\"darkgrid\", palette=\"deep\") # style=\"whitegrid\" plt.show() \u76f4\u65b9\u56fe\u548c\u5bc6\u5ea6\u56fe \u00b6 \u76f4\u65b9\u56fe\u662f\u4e00\u79cd\u6761\u5f62\u56fe\uff0c\u7528\u4e8e\u7ed9\u51fa\u503c\u9891\u7387\u7684\u79bb\u6563\u663e\u793a\u3002\u6570\u636e\u70b9\u88ab\u5206\u6210\u79bb\u6563\u7684\uff0c\u5747\u5300\u95f4\u9694\u7684\u7bb1\uff0c\u5e76\u4e14\u7ed8\u5236\u6bcf\u4e2a\u7bb1\u4e2d\u6570\u636e\u70b9\u7684\u6570\u91cf\u3002 tips['tip_pct'].plot.hist(bins=50) # \u5c0f\u8d39\u767e\u5206\u6bd4\u7684\u76f4\u65b9\u56fe plt.show() \u5bc6\u5ea6\u56fe\u662f\u4e00\u79cd\u4e0e\u76f4\u65b9\u56fe\u76f8\u5173\u7684\u56fe\u8868\u7c7b\u578b\uff0c\u5b83\u901a\u8fc7\u8ba1\u7b97\u53ef\u80fd\u4ea7\u751f\u89c2\u6d4b\u6570\u636e\u7684\u8fde\u7eed\u6982\u7387\u5206\u5e03\u4f30\u8ba1\u800c\u4ea7\u751f\u3002 \u901a\u5e38\u7684\u505a\u6cd5\u662f\u5c06\u8fd9\u79cd\u5206\u5e03\u8fd1\u4f3c\u4e3a\u201c\u5185\u6838\u201d\u7684\u6df7\u5408\uff0c\u4e5f\u5c31\u662f\u50cf\u6b63\u6001\u5206\u5e03\u90a3\u6837\u7b80\u5355\u7684\u5206\u5e03\u3002 \u56e0\u6b64\uff0c\u5bc6\u5ea6\u56fe\u4e5f\u88ab\u79f0\u4e3a\u5185\u6838\u5bc6\u5ea6\u4f30\u8ba1\u56fe\uff08KDE\uff09\u3002 tips['tip_pct'].plot.density() # \u5c0f\u8d39\u767e\u5206\u6bd4\u5bc6\u5ea6\u56fe plt.show() \u7ed8\u5236\u76f4\u65b9\u56fe\u548c\u8fde\u7eed\u5bc6\u5ea6\u4f30\u8ba1 sns.displot() \u3002 sns.distplot(tips['tip_pct'], bins=100, color='k') plt.show() # FutureWarning: `distplot` is a deprecated function and will be removed in a future version. # Please adapt your code to use either `displot` (a figure-level function with similar flexibility) # or `histplot` (an axes-level function for histograms). \u6563\u70b9\u56fe\u6216\u70b9\u56fe \u00b6 \u70b9\u56fe\u6216\u6563\u70b9\u56fe\u53ef\u4ee5\u7528\u4e8e\u68c0\u9a8c\u4e24\u4e2a\u4e00\u7ef4\u6570\u636e\u5e8f\u5217\u4e4b\u95f4\u7684\u5173\u7cfb\u3002 \u5b9e\u4f8b\uff1a\u4ece statsmodels \u9879\u76ee\u4e2d\u8f7d\u5165\u4e86macrodata\u6570\u636e\u96c6\uff0c\u5e76\u9009\u62e9\u4e86\u4e00\u4e9b\u53d8\u91cf\uff0c\u4e4b\u540e\u8ba1\u7b97\u5bf9\u6570\u5dee\u3002 macro = pd.read_csv('../examples/macrodata.csv') print(macro.head(5)) # year quarter realgdp realcons ... unemp pop infl realint # 0 1959.0 1.0 2710.349 1707.4 ... 5.8 177.146 0.00 0.00 # 1 1959.0 2.0 2778.801 1733.7 ... 5.1 177.830 2.34 0.74 # 2 1959.0 3.0 2775.488 1751.8 ... 5.3 178.657 2.74 1.09 # 3 1959.0 4.0 2785.204 1753.7 ... 5.6 179.386 0.27 4.06 # 4 1960.0 1.0 2847.699 1770.5 ... 5.2 180.007 2.31 1.19 # [5 rows x 14 columns] data = macro[['cpi', 'm1', 'tbilrate', 'unemp']] print(data.head(5)) # cpi m1 tbilrate unemp # 0 28.98 139.7 2.82 5.8 # 1 29.15 141.7 3.08 5.1 # 2 29.35 140.5 3.82 5.3 # 3 29.37 140.0 4.33 5.6 # 4 29.54 139.6 3.50 5.2 trans_data = np.log(data).diff().dropna() print(trans_data[-5:]) # cpi m1 tbilrate unemp # 198 -0.007904 0.045361 -0.396881 0.105361 # 199 -0.021979 0.066753 -2.277267 0.139762 # 200 0.002340 0.010286 0.606136 0.160343 # 201 0.008419 0.037461 -0.200671 0.127339 # 202 0.008894 0.012202 -0.405465 0.042560 \u7528 seaborn \u7684 regplot \u65b9\u6cd5\u7ed8\u5236\u6563\u70b9\u56fe\uff0c\u5e76\u62df\u5408\u51fa\u4e00\u4e2a\u6761\u7ebf\u6027\u56de\u5f52\u7ebf\u3002( seaborn\u6587\u6863 ) sns.regplot('m1', 'unemp', data=trans_data) plt.title('Changes in log %s versus log %s ' % ('m1', 'unemp')) plt.show() \u5728\u63a2\u7d22\u6027\u6570\u636e\u5206\u6790\u4e2d\uff0c\u80fd\u591f\u67e5\u770b\u4e00\u7ec4\u53d8\u91cf\u4e2d\u7684\u6240\u6709\u6563\u70b9\u56fe\u662f\u6709\u5e2e\u52a9\u7684\uff0c\u8fd9\u88ab\u79f0\u4e3a\u6210\u5bf9\u56fe\u6216\u6563\u70b9\u56fe\u77e9\u9635\u3002 Seaborn\u6709\u4e00\u4e2a\u65b9\u4fbf\u7684 pairplot \u51fd\u6570\uff0c\u5b83\u652f\u6301\u5728\u5bf9\u89d2\u7ebf\u4e0a\u653e\u7f6e\u6bcf\u4e2a\u53d8\u91cf\u7684\u76f4\u65b9\u56fe\u6216\u5bc6\u5ea6\u4f30\u8ba1\u503c\u3002 plot_ksw \u53c2\u6570\u80fd\u591f\u5c06\u914d\u7f6e\u9009\u9879\u4f20\u9012\u7ed9\u975e\u5bf9\u89d2\u5143\u7d20\u4e0a\u7684\u5404\u4e2a\u7ed8\u56fe\u8c03\u7528\u3002 sns.pairplot(trans_data, diag_kind='kde', plot_kws={'alpha': 0.2}) plt.show() \u5206\u9762\u7f51\u683c\u548c\u5206\u7c7b\u6570\u636e \u00b6 \u5982\u679c\u6570\u636e\u96c6\u6709\u989d\u5916\u7684\u5206\u7ec4\u7ef4\u5ea6\u600e\u4e48\u529e\uff1f\u4f7f\u7528\u5206\u9762\u7f51\u683c\u662f\u5229\u7528\u591a\u79cd\u5206\u7ec4\u53d8\u91cf\u5bf9\u6570\u636e\u8fdb\u884c\u53ef\u89c6\u5316\u7684\u65b9\u5f0f\u3002 seaborn\u62e5\u6709\u4e00\u4e2a\u6709\u6548\u7684\u5185\u5efa\u51fd\u6570 factorplot \uff0c\u5b83\u53ef\u4ee5\u7b80\u5316\u591a\u79cd\u5206\u9762\u7ed8\u56fe\u3002 sns.factorplot(x='day', y='tip_pct', hue='time', col='smoker', kind='bar', data=tips[tips.tip_pct < 1]) plt.show() # UserWarning: The `factorplot` function has been renamed to `catplot`. # The original name will be removed in a future release. Please update your code. # Note that the default `kind` in `factorplot` (`'point'`) has changed `'strip'` in `catplot`. sns.catplot(x='day', y='tip_pct', hue='time', col='smoker', kind='box', data=tips[tips.tip_pct < 0.5]) plt.show() \u5176\u4ed6Python\u53ef\u89c6\u5316\u5de5\u5177 \u00b6 \u81ea2010\u5e74\u4ee5\u6765\uff0c\u5f88\u591a\u5f00\u53d1\u5de5\u4f5c\u90fd\u96c6\u4e2d\u5728\u521b\u5efaweb\u4ea4\u4e92\u5f0f\u56fe\u5f62\u4e0a\u3002 \u501f\u52a9\u50cf Bokeh \u548c Plotly \u8fd9\u6837\u7684\u5de5\u5177\uff0c\u5728web\u6d4f\u89c8\u5668\u4e2d\u521b\u5efa\u52a8\u6001\u7684\u3001\u4ea4\u4e92\u5f0f\u56fe\u50cf\u7684\u5de5\u4f5c\u73b0\u5728\u5df2\u7ecf\u53ef\u4ee5\u5b9e\u73b0\u3002 \u53ef\u89c6\u5316\u662f\u4e00\u4e2a\u6d3b\u8dc3\u7684\u7814\u7a76\u9886\u57df\u3002","title":"\u7ed8\u56fe\u4e0e\u53ef\u89c6\u5316"},{"location":"python/DataAnalysis/ch06/#_1","text":"","title":"\u7ed8\u56fe\u4e0e\u53ef\u89c6\u5316"},{"location":"python/DataAnalysis/ch06/#matplotlib-api","text":"import matplotlib as mpl import matplotlib.pyplot as plt import numpy as np import pandas as pd from io import BytesIO \u6267\u884c plt.show() \u65f6\u62a5\u9519\uff1a UserWarning: Matplotlib is currently using agg, which is a non-GUI backend, so cannot show the figure. \u6267\u884c\u4e0b\u9762\u547d\u4ee4\uff0c\u5f97\u5230 plt \u7684 backend \u662f\u7528 agg \u3002 plt.get_backend() \u4f8b\u5982\uff1a\u4e0b\u9762\u4e24\u79cd\u8868\u8fbe\u65b9\u5f0f\u6548\u679c\u4e00\u6837\u3002 ax.plot(x, y, 'g--') ax.plot(x, y, linestyle='--', color='g') Out[6]: 'agg' \u5b89\u88c5\u4e0b\u9762\u51e0\u4e2a\u5305\uff1a sudo zypper in python-tk python3-tk sudo zypper in plplot-tcltk-devel plplot-tcltk-libs pip install tk \u6dfb\u52a0\u4e0b\u9762\u5230python\u4ee3\u7801\u4e2d\u3002 import matplotlib.pyplot as plt mpl.use('TkAgg') \u6267\u884c\u540e\u62a5\u4e0b\u9762\u9519\u8bef\uff1a your Python may not be configured for Tk \u8fdb\u5165python\u6e90\u7801\u76ee\u5f55\uff0c\u91cd\u65b0\u7f16\u8bd1\u4f8b\u5982\uff1a\u4e0b\u9762\u4e24\u79cd\u8868\u8fbe\u65b9\u5f0f\u6548\u679c\u4e00\u6837\u3002 ax.plot(x, y, 'g--') ax.plot(x, y, linestyle='--', color='g') james@lizard:/opt/Python-3.9.6> sudo make james@lizard:/opt/Python-3.9.6> sudo make install \u95ee\u9898\u89e3\u51b3\uff0c\u5373\u4f7f\u4e0d\u52a0\u5165 mpl.use('TkAgg') \uff0c\u6267\u884c plt.show() \u4e5f\u662f\u53ef\u4ee5\u8f93\u51fa\u56fe\u50cf\u3002","title":"\u7b80\u660ematplotlib API\u5165\u95e8"},{"location":"python/DataAnalysis/ch06/#_2","text":"matplotlib \u6240\u7ed8\u5236\u7684\u56fe\u4f4d\u4e8e\u56fe\u7247\uff08Figure\uff09\u5bf9\u8c61\u4e2d\u3002\u53ef\u4ee5\u4f7f\u7528 plt.figure \u751f\u6210\u4e00\u4e2a\u65b0\u7684\u56fe\u7247\u3002 \u4f7f\u7528 add_subplot \u521b\u5efa\u4e00\u4e2a\u6216\u591a\u4e2a\u5b50\u56fe\uff08subplot\uff09\u3002 plt \u4e0e ax \u7ed8\u56fe\u3002 fig = plt.figure() # plt: \u5148\u751f\u6210\u4e86\u4e00\u4e2a\u753b\u5e03\uff0c\u7136\u540e\u5728\u8fd9\u4e2a\u753b\u5e03\u4e0a\u9690\u5f0f\u7684\u751f\u6210\u4e00\u4e2a\u753b\u56fe\u533a\u57df\u6765\u8fdb\u884c\u753b\u56fe # plt.plot([1, 2, 3, 4]) # plt.show() # ax: \u5148\u751f\u6210\u4e00\u4e2a\u753b\u5e03\uff082\u00d72\u7684\u533a\u57df\uff0c\u6700\u591a\u653e\u56db\u4e2a\u56fe\u5f62\uff09\uff0c\u7136\u540e\u5728\u6b64\u753b\u5e03\u4e0a\uff0c\u9009\u5b9a\u4e00\u4e2a\u5b50\u533a\u57df\u753b\u4e86\u4e00\u4e2a\u5b50\u56fe\uff08\u5e8f\u53f71\u4ee3\u8868\u7b2c\u4e00\u4e2a\u533a\u57df\uff09 ax1 = fig.add_subplot(2, 2, 1) # \u4e5f\u53ef\u4ee5\u5199\u6210fig.add_subplot(221) ax1.plot([1, 2, 3, 4], [1, 4, 3, 2]) # \u8f93\u51fa\u56fe\u7247\u5230\u7b2c\u4e00\u4e2a\u533a\u57df\u3002 # \u7b2c\u4e00\u4e2a\u53c2\u6570\u662f\u6570\u636e\u96c6\u91cc\u5404\u4e2a\u6570\u636e\u70b9\u7684X\u503c\u7684\u96c6\u5408 # \u7b2c\u4e8c\u4e2a\u53c2\u6570\u6570\u636e\u96c6\u91cc\u5404\u4e2a\u6570\u636e\u70b9\u7684Y\u503c\u7684\u96c6\u5408\u3002 # \u4e0d\u662f\u6570\u5b66\u4e0a\u5e38\u89c1\u7684\u6210\u5bf9\u5750\u6807\u70b9\u5982(x1,y1)\u3001(x2,y2)\u3001...\u3001(xn,yn)\u7684\u683c\u5f0f\uff0c\u800c\u662f (x1,x2,...,xn)\u548c(y1,y2,...,yn) \u3002 plt.show() \u770b\u4e0b\u9762\u4f8b\u5b50\uff0c\u589e\u52a0\u5b50\u56fe\u540e\u7684\u6570\u636e\u53ef\u89c6\u5316\u6548\u679c\u3002 fig = plt.figure() ax1 = fig.add_subplot(2, 2, 1) ax2 = fig.add_subplot(2, 2, 2) ax3 = fig.add_subplot(2, 2, 3) ax1.plot(np.random.randn(50).cumsum(), 'k--') # \u5728\u7b2c\u4e09\u4e2a\u533a\u57df\u8f93\u51fa\u56fe\u50cf\u3002'k--\u2019\u662f\u7528\u4e8e\u7ed8\u5236\u9ed1\u8272\u5206\u6bb5\u7ebf\u7684style\u9009\u9879\u3002 ax2.hist(np.random.randn(100), bins=20, color='k', alpha=0.3) ax3.scatter(np.arange(30), np.arange(30) + 3 * np.random.randn(30)) plt.show() plt.subplots \u901a\u8fc7 matplotlib \u7684 subplots \u65b9\u6cd5\uff0c\u4f7f\u7528\u5b50\u56fe\u7f51\u683c\u521b\u5efa\u56fe\u7247\uff0c\u7136\u540e\u8fd4\u56de\u5305\u542b\u4e86\u5df2\u751f\u6210\u5b50\u56fe\u5bf9\u8c61\u7684NumPy\u6570\u7ec4\u3002 \u6570\u7ec4 axes \u53ef\u4ee5\u50cf\u4e8c\u7ef4\u6570\u7ec4\u90a3\u6837\u65b9\u4fbf\u5730\u8fdb\u884c\u7d22\u5f15\uff0c\u4f8b\u5982\uff0c axes[0, 1] \u3002 plt.subplots \u53c2\u6570\u9009\u9879\uff1a nrows\uff1a\u53ef\u9009\u7684\uff0c\u6574\u578b\uff0c\u9ed8\u8ba4\u4e3a1\u3002\u5b50\u56fe\u7f51\u683c\u7684\u884c\u6570\u3002 ncols\uff1a\u53ef\u9009\u7684\uff0c\u6574\u578b\uff0c\u9ed8\u8ba4\u4e3a1\u3002\u5b50\u56fe\u7f51\u683c\u7684\u5217\u6570\u3002 sharex\uff1a\u53ef\u9009\u7684\uff0c\u9ed8\u8ba4\u4e3aFalse\u3002\u53ef\u9009\u503c\u5982\u4e0b\uff1a True\u6216all\uff0c\u6240\u6709\u5b50\u56fe\u5171\u4eabx\u8f74 False\u6216none\uff0c\u6bcf\u4e2a\u5b50\u56fe\u7684x\u8f74\u90fd\u662f\u72ec\u7acb\u7684 row\uff0c\u6bcf\u884c\u5b50\u56fe\u5171\u4eab\u4e00\u4e2ax\u8f74 col\uff0c\u6bcf\u5217\u5b50\u56fe\u5171\u4eab\u4e00\u4e2ax\u8f74 sharey\uff1a\u7c7b\u4f3c\u4e8esharex\uff0c\u8bbe\u7f6ey\u8f74\u7684\u5171\u4eab\u65b9\u5f0f\u3002\u5f53\u67d0\u5217\u5171\u4eab\u4e00\u4e2ax\u8f74\u65f6\uff0c\u53ea\u6709\u5e95\u90e8\u7684\u5b50\u56fe\u4f1a\u521b\u5efax\u8f74\u6807\u8bb0\u3002\u540c\u6837\u7684\uff0c\u5982\u679c\u67d0\u884c\u5171\u4eab\u4e00\u4e2ay\u8f74\u65f6\uff0c\u53ea\u6709\u884c\u7684\u7b2c\u4e00\u5217\u5b50\u56fe\u4f1a\u521b\u5efay\u8f74\u6807\u8bb0\u3002 squeeze \uff1a\u53ef\u9009\u7684\uff0c\u5e03\u5c14\u578b\uff0c\u9ed8\u8ba4\u4e3aTrue\u3002\u662f\u5426\u538b\u7f29\u8fd4\u56de\u7684Axes\u6570\u7ec4\u3002\u5982\u679c\u4e3aTrue\uff0c\u5f53\u53ea\u6709\u4e00\u4e2a\u5b50\u56fe\uff0c\u5373nrows\u548cncols\u5747\u4e3a1\u65f6\uff0c\u8fd4\u56de\u4e00\u4e2a\u5355\u72ec\u7684Axes\u5bf9\u8c61\uff0c\u5f53\u6709N*1\u548c1*M\u4e2a\u5b50\u56fe\u65f6\uff0c\u8fd4\u56de\u4e00\u4e2a\u4e00\u7ef4Axes\u5bf9\u8c61\u6570\u7ec4\u3002\u5f53\u6709N*M\u4e2a\u5b50\u56fe\uff08N>1\uff0cM>1\uff09\u65f6\uff0c\u8fd4\u56de\u4e8c\u7ef4\u6570\u7ec4\u3002\u5982\u679c\u4e3aFalse\uff0c\u5219\u603b\u662f\u8fd4\u56de\u4e8c\u7ef4\u6570\u7ec4\u3002 num\uff1a\u53ef\u9009\u7684\uff0c\u6574\u578b\u6216\u5b57\u7b26\u4e32\uff0c\u9ed8\u8ba4\u4e3aNone\u3002\u662fmatplotlib.pyplot.figure\u7684\u5173\u952e\u5b57\uff0c\u7528\u4e8e\u8bbe\u7f6e\u56fe\u50cf\u6570\u5b57\u6216\u6807\u7b7e\u3002\u5982\u679c\u672a\u8bbe\u7f6e\u6b64\u53c2\u6570\uff0c\u4f1a\u521b\u5efa\u4e00\u4e2a\u65b0\u7684\u56fe\u50cf\uff0c\u5e76\u9012\u589e\u56fe\u50cf\u7f16\u53f7\uff0cfigure\u5bf9\u8c61\u4f1a\u5c06\u7f16\u53f7\u4fdd\u5b58\u5728number\u5c5e\u6027\u4e2d\u3002\u5982\u679c\u8bbe\u7f6e\u4e86\u6b64\u53c2\u6570\uff0c\u5e76\u4e14\u5b58\u5728\u53c2\u6570\u6307\u5b9a\u7684\u56fe\u50cf\uff0c\u5219\u4f1a\u8fd4\u56de\u6b64\u56fe\u50cf\u7684\u5f15\u7528\uff0c\u5982\u679c\u4e0d\u5b58\u5728\u5219\u4f1a\u521b\u5efa\u65b0\u7684\u56fe\u50cf\u5e76\u8fd4\u56de\u5b83\u7684\u5f15\u7528\u3002\u5982\u679c\u662f\u5b57\u7b26\u4e32\uff0c\u5219\u7a97\u53e3\u6807\u9898\u4f1a\u88ab\u8bbe\u7f6e\u4e3a\u6b64\u5b57\u7b26\u4e32\u7684\u503c\u3002 subplot_kw\uff1a\u53ef\u9009\u7684\uff0c\u5b57\u5178\u7c7b\u578b\u3002\u5305\u542b\u4f20\u9012\u7ed9\u7528\u4e8e\u521b\u5efa\u5b50\u56fe\u7684\u8c03\u7528add_subplot\u7684\u5173\u952e\u5b57\u53c2\u6570\u3002 gridspec_kw\uff1a\u53ef\u9009\u7684\uff0c\u5b57\u5178\u7c7b\u578b\u3002\u5305\u542b\u4f20\u9012\u7ed9\u7528\u4e8e\u521b\u5efa\u5b50\u56fe\u7f51\u683c\u7684GridSpec\u6784\u9020\u51fd\u6570\u7684\u5173\u952e\u5b57\u53c2\u6570\u3002 fig, axes = plt.subplots(2, 3) print(axes) # \u5c06\u751f\u6210\u7684axes\u5bf9\u8c61\u653e\u5165NumPy\u6570\u7ec4\u3002 # [[ ] # [ ]] \u8c03\u6574\u5b50\u56fe\u5468\u56f4\u7684\u95f4\u8ddd\u3002 \u9ed8\u8ba4\u60c5\u51b5\u4e0b\uff0c matplotlib \u4f1a\u5728\u5b50\u56fe\u7684\u5916\u90e8\u548c\u5b50\u56fe\u4e4b\u95f4\u7559\u51fa\u4e00\u5b9a\u7684\u95f4\u8ddd\u3002 \u8fd9\u4e2a\u95f4\u8ddd\u90fd\u662f\u76f8\u5bf9\u4e8e\u56fe\u7684\u9ad8\u5ea6\u548c\u5bbd\u5ea6\u6765\u6307\u5b9a\u7684\uff0c\u624b\u52a8\u8c03\u6574\u56fe\u7684\u5927\u5c0f\uff0c\u90a3\u4e48\u95f4\u8ddd\u4f1a\u81ea\u52a8\u8c03\u6574\u3002 \u4e5f\u53ef\u4ee5\u4f7f\u7528\u56fe\u5bf9\u8c61\u4e0a\u7684 subplots_adjust \u65b9\u6cd5\u66f4\u6539\u95f4\u8ddd\uff0c\u4e5f\u53ef\u4ee5\u7528\u4f5c\u9876\u5c42\u51fd\u6570\u3002 fig, axes = plt.subplots(2, 2, sharex=True, sharey=True) for i in range(2): for j in range(2): axes[i, j].hist(np.random.randn(500), bins=50, color='k', alpha=0.5) plt.subplots_adjust(wspace=0, hspace=0) plt.show() \u4e0a\u9762\u8f93\u51fa\u56fe\u50cf\u7684\u8f74\u6807\u7b7e\u662f\u5b58\u5728\u91cd\u53e0\u7684\u3002 matplotlib \u5e76\u4e0d\u68c0\u67e5\u6807\u7b7e\u662f\u5426\u91cd\u53e0\uff0c\u56e0\u6b64\u5728\u7c7b\u4f3c\u60c5\u51b5\u4e0b\u4f60\u9700\u8981\u901a\u8fc7\u663e\u5f0f\u6307\u5b9a\u523b\u5ea6\u4f4d\u7f6e\u548c\u523b\u5ea6\u6807\u7b7e\u7684\u65b9\u6cd5\u6765\u4fee\u590d\u8f74\u6807\u7b7e\u3002","title":"\u56fe\u7247\u4e0e\u5b50\u56fe"},{"location":"python/DataAnalysis/ch06/#_3","text":"matplotlib \u7684\u4e3b\u51fd\u6570 plot \u63a5\u6536\u5e26\u6709 x \u548c y \u8f74\u7684\u6570\u7ec4\u4ee5\u53ca\u4e00\u4e9b\u53ef\u9009\u7684\u5b57\u7b26\u4e32\u7f29\u5199\u53c2\u6570\u6765\u6307\u660e\u989c\u8272\u548c\u7ebf\u7c7b\u578b\u3002 \u4f8b\u5982\uff1a\u4e0b\u9762\u4e24\u79cd\u8868\u8fbe\u65b9\u5f0f\u6548\u679c\u4e00\u6837\u3002 ax.plot(x, y, 'g--') ax.plot(x, y, linestyle='--', color='g') data = np.random.randn(30).cumsum() plt.plot(data, 'ko--') plt.show() # \u4e0a\u9762\u7684\u4ee3\u7801\u53ef\u4ee5\u5199\u5f97\u66f4\u4e3a\u663e\u5f0f\uff1a plt.plot(data, color='k', linestyle='dashed', marker='o') plt.show() plt.plot(data, color='k', linestyle='dashed', marker='o', label='Default') plt.show() plt.plot(data, color='k', linestyle='dashed', marker='o', label='steps-post', drawstyle='steps-post') plt.show()","title":"\u989c\u8272\u3001\u6807\u8bb0\u548c\u7ebf\u7c7b\u578b"},{"location":"python/DataAnalysis/ch06/#_4","text":"\u5bf9\u4e8e\u5927\u591a\u6570\u56fe\u8868\u4fee\u9970\u5de5\u4f5c\uff0c\u6709\u4e24\u79cd\u4e3b\u8981\u7684\u65b9\u5f0f\uff1a\u4f7f\u7528\u7a0b\u5e8f\u6027\u7684pyplot\u63a5\u53e3\uff08\u5373matplotlib.pyplot\uff09\u548c\u66f4\u591a\u9762\u5411\u5bf9\u8c61\u7684\u539f\u751fmatplotlib API\u3002 pyplot \u63a5\u53e3\u8bbe\u8ba1\u4e3a\u4ea4\u4e92\u5f0f\u4f7f\u7528\uff0c\u5305\u542b\u4e86\u50cf xlim \u3001 xticks \u548c xticklabels \u7b49\u65b9\u6cd5\u3002\u8fd9\u4e9b\u65b9\u6cd5\u5206\u522b\u63a7\u5236\u4e86\u7ed8\u56fe\u8303\u56f4\u3001\u523b\u5ea6\u4f4d\u7f6e\u4ee5\u53ca\u523b\u5ea6\u6807\u7b7e\u3002 \u5728\u6ca1\u6709\u51fd\u6570\u53c2\u6570\u7684\u60c5\u51b5\u4e0b\u8c03\u7528\uff0c\u8fd4\u56de\u5f53\u524d\u7684\u53c2\u6570\u503c\uff08\u4f8b\u5982 plt.xlim() \u8fd4\u56de\u5f53\u524d\u7684x\u8f74\u7ed8\u56fe\u8303\u56f4\uff09\u3002 \u4f20\u5165\u53c2\u6570\u7684\u60c5\u51b5\u4e0b\u8c03\u7528\uff0c\u5e76\u8bbe\u7f6e\u53c2\u6570\u503c\uff08\u4f8b\u5982 plt.xlim\uff08[0, 10]\uff09 \u4f1a\u5c06 x \u8f74\u7684\u8303\u56f4\u8bbe\u7f6e\u4e3a0\u523010\uff09\u3002 \u6240\u6709\u7684\u8fd9\u4e9b\u65b9\u6cd5\u90fd\u4f1a\u5728\u5f53\u524d\u6d3b\u52a8\u7684\u6216\u6700\u8fd1\u521b\u5efa\u7684 AxesSubplot \u4e0a\u751f\u6548\u3002 \u8fd9\u4e9b\u65b9\u6cd5\u4e2d\u7684\u6bcf\u4e00\u4e2a\u5bf9\u5e94\u4e8e\u5b50\u56fe\u81ea\u8eab\u7684\u4e24\u4e2a\u65b9\u6cd5\u3002\u6bd4\u5982 xlim \u5bf9\u5e94\u4e8e ax.get_lim \u548c ax.set_lim \u3002 \u63a8\u8350\u4f7f\u7528 subplot \u7684\u5b9e\u4f8b\u65b9\u6cd5\uff0c\u56e0\u4e3a\u8fd9\u6837\u66f4\u4e3a\u663e\u5f0f\uff08\u5c24\u5176\u662f\u5728\u5904\u7406\u591a\u4e2a\u5b50\u56fe\u65f6\uff09\u3002 data = np.random.randn(1000).cumsum() fig = plt.figure() # \u8bbe\u5b9a\u5b50\u56fe ax = fig.add_subplot(1, 1, 1) # \u8bbe\u5b9ax\u8f74\u5bf9\u5e94\u53c2\u6570\uff1a # \u8bbe\u5b9ax\u8f74\u523b\u5ea6 ax.set_xticks([0, 250, 500, 750, 1000]) # \u8bbe\u5b9ax\u8f74\u6807\u7b7e ax.set_xticklabels(['one(0)', 'two(250)', 'three(500)', 'four(750)', 'five(1000)'], rotation=30, fontsize='small') # \u7ed9x\u8f74\u4e00\u4e2a\u540d\u79f0 ax.set_xlabel('Stages') # \u8bbe\u5b9ay\u8f74\u5bf9\u5e94\u53c2\u6570\uff1a # \u672a\u6307\u5b9a\u7684\u53c2\u6570\u7531\u7cfb\u7edf\u9ed8\u8ba4\u4ea7\u751f\u3002 ax.set_ylabel('Steps') # \u7ed9\u5b50\u56fe\u6dfb\u52a0\u4e00\u4e2a\u6807\u9898 ax.set_title('My first matplotlib plot') # \u7ed9\u5b50\u56fe\u6dfb\u52a0\u4e00\u4e2a\u56fe\u4f8b\uff08\u5982\uff1a\u7ed9\u5b50\u56fe\u5185\u4e00\u4e2a\u56fe\u5f62\u66f2\u7ebf\u6dfb\u52a0\u4e00\u4e2alabel\uff09 ax.plot(data, 'k--', label='Label One') # loc\u53c2\u6570\u544a\u8bc9matplotlib\u5728\u54ea\u91cc\u653e\u7f6e\u56fe\u8868\u3002legend\u65b9\u6cd5\u6709\u591a\u4e2a\u5176\u4ed6\u7684\u4f4d\u7f6e\u53c2\u6570loc\u3002 ax.legend(loc='best') # \u6216\u8005plt.legend(loc='best') \u3002 # \u5728\u56fe\u5f62\u5750\u6807\u4e3a(0, 0)\u7684\u4f4d\u7f6e\u6dfb\u52a0\u4e00\u4e2alable ax.text(0, 0, 'Hello World1', family='monospace', fontsize=10) # \u7ed9\u5b50\u56fe\u6dfb\u52a0annotate\u3002\u7528\u4e00\u4e2a\u7bad\u5934\u6307\u5411\u8981\u6ce8\u91ca\u7684\u5730\u65b9\uff0c\u518d\u5199\u4e0a\u4e00\u6bb5\u8bdd\u7684\u884c\u4e3a\uff0c\u53eb\u505aannotate\u3002 # * s: \u6ce8\u91ca\u7684\u5185\u5bb9\uff0c\u4e00\u6bb5\u6587\u5b57\uff1b # * xytext: \u8fd9\u6bb5\u6587\u5b57\u6240\u5904\u7684\u4f4d\u7f6e; # * xy: \u7bad\u5934\u6307\u5411\u7684\u4f4d\u7f6e\uff1b # * arrowprops: \u901a\u8fc7arrowstyle\u8868\u660e\u7bad\u5934\u7684\u98ce\u683c\u6216\u79cd\u7c7b\u3002 ax.annotate('Zero is here!', xytext=(20, 20), xy=(1, 1), arrowprops=dict(arrowstyle='->')) # \u7ed9\u5b50\u56fe\u6dfb\u52a0\u4e00\u4e9b\u56fe\u5f62 # matplotlib\u542b\u6709\u8868\u793a\u591a\u79cd\u5e38\u89c1\u56fe\u5f62\u7684\u5bf9\u8c61\uff0c\u8fd9\u4e9b\u5bf9\u8c61\u7684\u5f15\u7528\u662fpatches\u3002 # \u4e00\u4e9b\u56fe\u5f62\uff0c\u6bd4\u5982Rectangle\uff08\u77e9\u5f62\uff09\u548cCircle\uff08\u5706\u5f62\uff09\uff0c\u53ef\u4ee5\u5728matplotlib.pyplot\u4e2d\u627e\u5230\uff0c\u4f46\u56fe\u5f62\u7684\u5168\u96c6\u4f4d\u4e8ematplotlib.patches\u3002 rect = plt.Rectangle((10, 5), 100, 15, color='k', alpha=0.3) circ = plt.Circle((200, 9), 95, color='b', alpha=0.3) pgon = plt.Polygon([[500, 5], [600, -5], [700, 30]], color='g', alpha=0.5) ax.add_patch(rect) ax.add_patch(circ) ax.add_patch(pgon) # \u5c06\u56fe\u7247\u4fdd\u5b58\u5230\u6587\u4ef6 # \u6587\u4ef6\u7c7b\u578b\u662f\u4ece\u6587\u4ef6\u6269\u5c55\u540d\u4e2d\u63a8\u65ad\u51fa\u6765\u7684\u3002\u6240\u4ee5\u5982\u679c\u4f60\u4f7f\u7528\uff0epdf\uff0c\u5219\u4f1a\u5f97\u5230\u4e00\u4e2aPDF\u3002 # \u51e0\u4e2a\u91cd\u8981\u7684\u9009\u9879\uff1adpi\uff0c\u5b83\u63a7\u5236\u6bcf\u82f1\u5bf8\u70b9\u6570\u7684\u5206\u8fa8\u7387\uff1bbbox_inches\uff0c\u53ef\u4ee5\u4fee\u526a\u5b9e\u9645\u56fe\u5f62\u7684\u7a7a\u767d\u3002 plt.savefig('../examples/figpath.png', dpi=400, bbox_inches='tight') # saveifg\u5e76\u975e\u4e00\u5b9a\u662f\u5199\u5230\u786c\u76d8\u7684\uff0c\u5b83\u53ef\u4ee5\u5c06\u56fe\u7247\u5199\u5165\u5230\u6240\u6709\u7684\u6587\u4ef6\u578b\u5bf9\u8c61\u4e2d\uff0c\u4f8b\u5982BytesIO buffer = BytesIO() plt.savefig(buffer) plot_data = buffer.getvalue() plt.show()","title":"\u523b\u5ea6\u3001\u6807\u7b7e\u548c\u56fe\u4f8b"},{"location":"python/DataAnalysis/ch06/#matplotlib","text":"matplotlib \u914d\u7f6e\u4e86\u914d\u8272\u65b9\u6848\u548c\u9ed8\u8ba4\u8bbe\u7f6e\uff0c\u901a\u8fc7\u5168\u5c40\u53c2\u6570\u6765\u5b9a\u5236\uff0c\u5305\u62ec\u56fe\u5f62\u5927\u5c0f\u3001\u5b50\u56fe\u95f4\u8ddd\u3001\u989c\u8272\u3001\u5b57\u4f53\u5927\u5c0f\u548c\u7f51\u683c\u6837\u5f0f\u7b49\u7b49\u3002 \u4f7f\u7528 rc \u65b9\u6cd5\u662f\u4f7f\u7528Python\u7f16\u7a0b\u4fee\u6539\u914d\u7f6e\u7684\u4e00\u79cd\u65b9\u5f0f\u3002 rc \u7684\u7b2c\u4e00\u4e2a\u53c2\u6570\u662f\u4f60\u60f3\u8981\u81ea\u5b9a\u4e49\u7684\u7ec4\u4ef6\uff0c\u6bd4\u5982 'figure'\u3001'axes'\u3001'xtick'\u3001'ytick'\u3001'grid'\u3001'legend' \u7b49\u7b49\u3002 \u4e4b\u540e\uff0c\u53ef\u4ee5\u6309\u7167\u5173\u952e\u5b57\u53c2\u6570\u7684\u5e8f\u5217\u6307\u5b9a\u65b0\u53c2\u6570\u3002 \u5b57\u5178\u662f\u4e00\u79cd\u5728\u7a0b\u5e8f\u4e2d\u8bbe\u7f6e\u9009\u9879\u7684\u7b80\u5355\u65b9\u5f0f\u3002\u6bd4\u5982\uff1a plt.rc('figure', figsize=(10, 10)) font_options = { 'family': 'monospace', 'weight': 'bold', 'size': 'small' } plt.rc('font', **font_options)","title":"matplotlib\u8bbe\u7f6e"},{"location":"python/DataAnalysis/ch06/#pandasseaborn","text":"pandas\u81ea\u8eab\u6709\u5f88\u591a\u5185\u5efa\u65b9\u6cd5\u53ef\u4ee5\u7b80\u5316\u4eceDataFrame\u548cSeries\u5bf9\u8c61\u751f\u6210\u53ef\u89c6\u5316\u7684\u8fc7\u7a0b\u3002 \u53e6\u4e00\u4e2a\u5e93\u662f seaborn \u3002 seaborn \u7b80\u5316\u4e86\u5f88\u591a\u5e38\u7528\u53ef\u89c6\u5316\u7c7b\u578b\u7684\u751f\u6210\u3002 \u5bfc\u5165 seaborn \u4f1a\u4fee\u6539\u9ed8\u8ba4\u7684matplotlib\u914d\u8272\u65b9\u6848\u548c\u7ed8\u56fe\u6837\u5f0f\uff0c\u8fd9\u4f1a\u63d0\u9ad8\u56fe\u8868\u7684\u53ef\u8bfb\u6027\u548c\u7f8e\u89c2\u6027\u3002 \u5373\u4f7f\u4e0d\u4f7f\u7528seaborn\u7684API\uff0c\u4e5f\u53ef\u4ee5\u5bfc\u5165seaborn\u6765\u4e3a\u901a\u7528matplotlib\u56fe\u8868\u63d0\u4f9b\u66f4\u597d\u7684\u89c6\u89c9\u7f8e\u89c2\u5ea6\u3002 import pandas as pd import numpy as np import matplotlib.pyplot as plt import seaborn as sns","title":"\u4f7f\u7528pandas\u548cseaborn\u7ed8\u56fe"},{"location":"python/DataAnalysis/ch06/#_5","text":"Series\u548cDataFrame\u90fd\u6709\u4e00\u4e2a plot \u5c5e\u6027\uff0c\u7528\u4e8e\u7ed8\u5236\u57fa\u672c\u7684\u56fe\u5f62\u3002\u9ed8\u8ba4\u60c5\u51b5\u4e0b\uff0c plot() \u7ed8\u5236\u7684\u662f\u6298\u7ebf\u56fe\u3002 Series\u7684 plot \u53c2\u6570\uff1a ax: matplotlib\u5b50\u56fe\u5bf9\u8c61axes\uff0c\u5982\u679c\u6ca1\u6709\u4f20\u503c\uff0c\u5219\u4f7f\u7528\u5f53\u524d\u6d3b\u52a8\u7684\u5b50\u56fe\u9ed8\u8ba4\u4f7f\u7528gca() alpha: \u56fe\u7247\u4e0d\u900f\u660e\u5ea6\uff080\u52301\uff09 data: \u6570\u636e\u5e8f\u5217Series figsize: \u56fe\u50cf\u5c3a\u5bf8\uff0ctuple(\u5bbd\u5ea6\uff0c\u9ad8\u5ea6)\uff0c\u6ce8\u610f\u8fd9\u91cc\u7684\u5355\u4f4d\u662f\u82f1\u5bf8 fontsize: \u8bbe\u7f6e\u523b\u5ea6\u6807\u7b7e\uff08xticks, yticks\uff09\u7684\u5927\u5c0f grid: \u7f51\u683c\u7ebf\uff08\u9ed8\u8ba4\u662f\u6253\u5f00\u7684\uff09 kind: \u56fe\u7c7b\u578b\uff1a\u6298\u7ebf\u56fe\uff0c\u67f1\u5f62\u56fe\uff0c\u6a2a\u5411\u67f1\u5f62\u56fe\uff0c\u76f4\u65b9\u56fe\uff0c\u7bb1\u7ebf\u56fe\uff0c\u5bc6\u5ea6\u56fe\uff0c\u9762\u79ef\u56fe\uff0c\u997c\u56fe label: \u5217\u7684\u522b\u540d\uff0c\u4f5c\u7528\u5728\u56fe\u4f8b\u4e0a legend: \u56fe\u4f8b loglog: x,y\u8f74\u90fd\u4f7f\u7528\u5bf9\u6570\u523b\u5ea6 logx: x\u8f74\u4f7f\u7528\u5bf9\u6570\u523b\u5ea6 logy: y\u8f74\u4f7f\u7528\u5bf9\u6570\u523b\u5ea6 mark_right: \u53cc y \u8f74\u65f6\uff0c\u5728\u56fe\u4f8b\u4e2d\u7684\u5217\u6807\u7b7e\u65c1\u589e\u52a0\u663e\u793a (right) \u6807\u8bc6 position: \u67f1\u5f62\u56fe\u7684\u67f1\u5b50\u7684\u4f4d\u7f6e\u8bbe\u7f6e rot: \u6539\u53d8\u523b\u5ea6\u6807\u7b7e\uff08xticks, yticks\uff09\u7684\u65cb\u8f6c\u5ea6\uff080\u5230360\uff09 secondary_y: \u53cc y \u8f74\uff0c\u5728\u53f3\u8fb9\u7684\u7b2c\u4e8c\u4e2a y \u8f74 style: \u7ebf\u7684\u6837\u5f0f\uff0c\u6bd4\u5982'ko--' table: \u5c06\u6570\u636e\u4ee5\u8868\u683c\u7684\u5f62\u5f0f\u5c55\u793a\u51fa\u6765 title: \u6807\u9898 use_index: \u662f\u5426\u4f7f\u7528\u7d22\u5f15\u4f5c\u4e3ax\u523b\u5ea6\u6807\u7b7e xerr: \u5e26\u8bef\u5dee\u7ebf\u7684\u67f1\u5f62\u56fe xlim: \u6a2a\u8f74\u5750\u6807\u523b\u5ea6\u7684\u53d6\u503c\u8303\u56f4 xticks: x\u8f74\u523b\u5ea6\u6807\u7b7e yerr: \u5e26\u8bef\u5dee\u7ebf\u7684\u67f1\u5f62\u56fe ylim: \u7eb5\u8f74\u5750\u6807\u523b\u5ea6\u7684\u53d6\u503c\u8303\u56f4 yticks: y\u8f74\u523b\u5ea6\u6807\u7b7e **kwds: matplotlib plot\u65b9\u6cd5\u7684\u5176\u4ed6\u53c2\u6570 DataFrame\u7684 plot \u53c2\u6570\uff1a x : \u6307\u6570\u636e\u6846\u5217\u7684\u6807\u7b7e\u6216\u4f4d\u7f6e\u53c2\u6570 y : \u6307\u6570\u636e\u6846\u5217\u7684\u6807\u7b7e\u6216\u4f4d\u7f6e\u53c2\u6570 kind : 'line' : \u6298\u7ebf\u56fe 'bar' : \u6761\u5f62\u56fe 'barh' : \u6a2a\u5411\u6761\u5f62\u56fe 'hist' : \u67f1\u72b6\u56fe 'box' : \u7bb1\u7ebf\u56fe 'kde' : Kernel\u7684\u5bc6\u5ea6\u4f30\u8ba1\u56fe\uff0c\u4e3b\u8981\u5bf9\u67f1\u72b6\u56fe\u6dfb\u52a0Kernel \u6982\u7387\u5bc6\u5ea6\u7ebf 'density' : 'kde' 'area' : area plot 'pie' : \u997c\u56fe 'scatter' : \u6563\u70b9\u56fe \u9700\u8981\u4f20\u5165columns\u65b9\u5411\u7684\u7d22\u5f15 'hexbin' : hexbin plot ax : \u5b50\u56fe(axes, \u4e5f\u53ef\u4ee5\u7406\u89e3\u6210\u5750\u6807\u8f74) \u8981\u5728\u5176\u4e0a\u8fdb\u884c\u7ed8\u5236\u7684matplotlib subplot\u5bf9\u8c61\u3002\u5982\u679c\u6ca1\u6709\u8bbe\u7f6e\uff0c\u5219\u4f7f\u7528\u5f53\u524dmatplotlib subplot\u3002\u5176\u4e2d\uff0c\u53d8\u91cf\u548c\u51fd\u6570\u901a\u8fc7\u6539\u53d8figure\u548caxes\u4e2d\u7684\u5143\u7d20\uff08\u4f8b\u5982\uff1atitle,label,\u70b9\u548c\u7ebf\u7b49\u7b49\uff09\u4e00\u8d77\u63cf\u8ff0figure\u548caxes\uff0c\u4e5f\u5c31\u662f\u5728\u753b\u5e03\u4e0a\u7ed8\u56fe\u3002 subplots : \u5224\u65ad\u56fe\u7247\u4e2d\u662f\u5426\u6709\u5b50\u56fe sharex : \u5982\u679c\u6709\u5b50\u56fe\uff0c\u5b50\u56fe\u5171x\u8f74\u523b\u5ea6\uff0c\u6807\u7b7e sharey : \u5982\u679c\u6709\u5b50\u56fe\uff0c\u5b50\u56fe\u5171y\u8f74\u523b\u5ea6\uff0c\u6807\u7b7e layout : \u5b50\u56fe\u7684\u884c\u5217\u5e03\u5c40 figsize : \u56fe\u7247\u5c3a\u5bf8\u5927\u5c0f use_index : \u9ed8\u8ba4\u7528\u7d22\u5f15\u505ax\u8f74 title : \u56fe\u7247\u7684\u6807\u9898\u7528\u5b57\u7b26\u4e32 grid : \u56fe\u7247\u662f\u5426\u6709\u7f51\u683c legend : \u5b50\u56fe\u7684\u56fe\u4f8b\uff0c\u6dfb\u52a0\u4e00\u4e2asubplot\u56fe\u4f8b(\u9ed8\u8ba4\u4e3aTrue) style : \u5bf9\u6bcf\u5217\u6298\u7ebf\u56fe\u8bbe\u7f6e\u7ebf\u7684\u7c7b\u578b logx : \u8bbe\u7f6ex\u8f74\u523b\u5ea6\u662f\u5426\u53d6\u5bf9\u6570 logy : \u8bbe\u7f6ey\u8f74\u523b\u5ea6\u662f\u5426\u53d6\u5bf9\u6570 loglog : \u540c\u65f6\u8bbe\u7f6ex\uff0cy\u8f74\u523b\u5ea6\u662f\u5426\u53d6\u5bf9\u6570 xticks : \u8bbe\u7f6ex\u8f74\u523b\u5ea6\u503c\uff0c\u5e8f\u5217\u5f62\u5f0f\uff08\u6bd4\u5982\u5217\u8868\uff09 yticks : \u8bbe\u7f6ey\u8f74\u523b\u5ea6\uff0c\u5e8f\u5217\u5f62\u5f0f\uff08\u6bd4\u5982\u5217\u8868\uff09 xlim : \u8bbe\u7f6e\u5750\u6807\u8f74x\u7684\u8303\u56f4\uff0c\u5217\u8868\u6216\u5143\u7ec4\u5f62\u5f0f ylim : \u8bbe\u7f6e\u5750\u6807\u8f74y\u7684\u8303\u56f4\uff0c\u5217\u8868\u6216\u5143\u7ec4\u5f62\u5f0f rot : \u8bbe\u7f6e\u8f74\u6807\u7b7e\uff08\u8f74\u523b\u5ea6\uff09\u7684\u663e\u793a\u65cb\u8f6c\u5ea6\u6570 fontsize : \u8bbe\u7f6e\u8f74\u523b\u5ea6\u7684\u5b57\u4f53\u5927\u5c0f colormap : \u8bbe\u7f6e\u56fe\u7684\u533a\u57df\u989c\u8272 colorbar : \u56fe\u7247\u67f1\u5b50 position : Specify relative alignments for bar plot layout. From 0 (left/bottom-end) to 1 (right/top-end). Default is 0.5 (center) layout : \u5e03\u5c40(rows, columns) for the layout of the plot table : \u5982\u679c\u4e3a\u6b63\uff0c\u5219\u9009\u62e9DataFrame\u7c7b\u578b\u7684\u6570\u636e\u5e76\u4e14\u8f6c\u6362\u5339\u914dmatplotlib\u7684\u5e03\u5c40 yerr : \u5e26\u8bef\u5dee\u7ebf\u7684\u67f1\u5f62\u56fe xerr : \u5e26\u8bef\u5dee\u7ebf\u7684\u67f1\u5f62\u56fe stacked : \u751f\u6210\u5806\u79ef\u67f1\u72b6\u56fe sort_columns : \u4ee5\u5b57\u6bcd\u8868\u987a\u5e8f\u7ed8\u5236\u5404\u5217\uff0c\u9ed8\u8ba4\u4f7f\u7528\u524d\u5217\u987a\u5e8f secondary_y : \u8bbe\u7f6e\u7b2c\u4e8c\u4e2ay\u8f74\uff08\u53f3y\u8f74\uff09 mark_right : When using a secondary_y axis, automatically mark the column labels with \u201c(right)\u201d in the legend kwds : Options to pass to matplotlib plotting method Series data1 = np.random.randn(10).cumsum(0) s1 = pd.Series( data1, index=np.arange(0, 100, 10), ) print(s1) fig, axes = plt.subplots(3, 1) # 3\u4e2a\u5b50\u56fe s1.plot.bar(ax=axes[0], color='k', alpha=0.7) # \u6761\u5f62\u56fe(\u5b50\u56fe0)\uff0ccolor='k\u2019(\u67f1\u5b50\u7684\u989c\u8272\u8bbe\u7f6e\u4e3a\u9ed1\u8272)\uff0calpha=0.7(\u56fe\u50cf\u7684\u586b\u5145\u8272\u8bbe\u7f6e\u4e3a\u90e8\u5206\u900f\u660e) s1.plot.barh(ax=axes[1], color='k', alpha=0.7) # \u6a2a\u5411\u6761\u5f62\u56fe(\u5b50\u56fe1) s1.value_counts().plot.pie(ax=axes[2]) # \u901a\u8fc7value_counts()\u5bf9Series\u503c\u9891\u7387\u8fdb\u884c\u53ef\u89c6\u5316 plt.show() DataFrame data2 = np.random.randn(10, 4).cumsum(0) df1 = pd.DataFrame( data2, columns=pd.Index(['A', 'B', 'C', 'D'], name='Genus'), index=np.arange(0, 100, 10) ) print(df1) fig, axes = plt.subplots(2, 1) # 2\u4e2a\u5b50\u56fe df1.plot.kde(ax=axes[0], alpha=0.7, grid='True', title='KDE Figure', sharex=True) df1.plot.bar(ax=axes[1], grid='True', title='Line Figure', sharex=True, use_index=False, stacked=True) # \u56e0\u4e3a\u5171\u4eabx\u8f74\uff0c\u6240\u4ee5\u5728KDE\u5b50\u56fe\u4e2d\u6307\u5b9ause_index=False\u770b\u4e0d\u51fa\u6548\u679c\u3002 # DataFrame\u7684\u5217\u540d\u79f0\"Genus\"\u88ab\u7528\u4f5c\u4e86\u56fe\u4f8b\u6807\u9898 # stacked=True\u6765\u751f\u6210\u5806\u79ef\u67f1\u72b6\u56fe plt.show() \u5b9e\u4f8b\uff1a\u7ed8\u5236\u4e00\u4e2a\u5806\u79ef\u67f1\u72b6\u56fe\uff0c\u7528\u4e8e\u5c55\u793a\u6bcf\u4e2a\u6d3e\u5bf9\u5728\u6bcf\u5929\u7684\u6570\u636e\u70b9\u5360\u6bd4\u3002 \u4ea4\u53c9\u8868 \u662f\u4e00\u79cd\u5e38\u7528\u7684\u5206\u7c7b\u6c47\u603b\u8868\u683c\uff0c\u7528\u4e8e\u9891\u6570\u5206\u5e03\u7edf\u8ba1\uff0c\u4e3b\u8981\u4ef7\u503c\u5728\u4e8e\u63cf\u8ff0\u4e86\u53d8\u91cf\u95f4\u5173\u7cfb\u7684\u6df1\u523b\u542b\u4e49\u3002 \u867d\u7136\u4e24\u4e2a\uff08\u6216\u4ee5\u4e0a\uff09\u53d8\u91cf\u53ef\u4ee5\u662f\u5206\u7c7b\u7684\u6216\u6570\u91cf\u7684\uff0c\u4f46\u662f\u4ee5\u90fd\u662f\u5206\u7c7b\u7684\u60c5\u5f62\u6700\u4e3a\u5e38\u89c1\u3002 Pandas\u7684 crosstab() \u65b9\u6cd5\u80fd\u591f\u5feb\u901f\u6784\u5efa\u4ea4\u53c9\u8868\uff0c\u5e76\u53ef\u4ee5\u901a\u8fc7\u53c2\u6570\u52a0\u4ee5\u4e2a\u6027\u5316\u7684\u8bbe\u7f6e\u3002\u5176\u4e2d\uff0c\u7b2c\u4e00\u4e2a\u53c2\u6570\u5c06\u6784\u6210\u4ea4\u53c9\u8868\u7684\u884c\uff0c\u7b2c\u4e8c\u4e2a\u53c2\u6570\u5c06\u6784\u6210\u4ea4\u53c9\u8868\u7684\u5217\u3002 tips = pd.read_csv('../examples/tips.csv') print(tips) # total_bill tip smoker day time size # 0 16.99 1.01 No Sun Dinner 2 # 1 10.34 1.66 No Sun Dinner 3 # 2 21.01 3.50 No Sun Dinner 3 # 3 23.68 3.31 No Sun Dinner 2 # 4 24.59 3.61 No Sun Dinner 4 # .. ... ... ... ... ... ... # 239 29.03 5.92 No Sat Dinner 3 # 240 27.18 2.00 Yes Sat Dinner 2 # 241 22.67 2.00 Yes Sat Dinner 2 # 242 17.82 1.75 No Sat Dinner 2 # 243 18.78 3.00 No Thur Dinner 2 # [244 rows x 6 columns] party_counts = pd.crosstab(tips['day'], tips['size']) # \u5bf9\u539f\u59cb\u6570\u636e\u7684day\u548csize\u8fdb\u884c\u805a\u5408\uff0c\u5e76\u6784\u5efa\u4ea4\u53c9\u8868\uff0cday\u4f5c\u4e3a\u884c\uff0csize\u4f5c\u4e3a\u5217\u3002 print(party_counts) # size 1 2 3 4 5 6 # day # Fri 1 16 1 1 0 0 # Sat 2 53 18 13 1 0 # Sun 0 39 15 18 3 1 # Thur 1 48 4 5 1 3 # \u6ca1\u6709\u592a\u591a\u76841\u4eba\u548c6\u4eba\u6d3e\u5bf9\uff0c\u820d\u5f03\u8fd9\u4e9b\u6570\u636e party_counts = party_counts.loc[:, 2:5] print(party_counts) # size 2 3 4 5 # day # Fri 16 1 1 0 # Sat 53 18 13 1 # Sun 39 15 18 3 # Thur 48 4 5 1 # \u6807\u51c6\u5316\u81f3\u548c\u4e3a1\uff1a\u6cbf0\u8f74\uff08\u884c\uff09\u5bf9\u6bcf\u5217\u6c42\u548c\uff0c\u6bcf\u884c\u5404\u503c\u9664\u4ee5\u548c\uff0c\u4ee5\u786e\u4fdd\u6bcf\u4e00\u884c\u7684\u503c\u548c\u4e3a1\uff0c\u7136\u540e\u8fdb\u884c\u7ed8\u56fe party_pcts = party_counts.div(party_counts.sum(1), axis=0) print(party_pcts) # size 2 3 4 5 # day # Fri 0.888889 0.055556 0.055556 0.000000 # Sat 0.623529 0.211765 0.152941 0.011765 # Sun 0.520000 0.200000 0.240000 0.040000 # Thur 0.827586 0.068966 0.086207 0.017241 party_counts.plot.bar() plt.show() \u53ef\u4ee5\u770b\u5230\u672c\u6570\u636e\u96c6\u4e2d\u7684\u6d3e\u5bf9\u6570\u91cf\u5728\u5468\u672b\u4f1a\u589e\u52a0\u3002 \u5b9e\u4f8b\uff1a\u4f7f\u7528seaborn\u8fdb\u884c\u6309\u661f\u671f\u65e5\u671f\u8ba1\u7b97\u5c0f\u8d39\u767e\u5206\u6bd4\u3002 Seaborn\u8981\u6c42\u6570\u636e\u7684\u8f93\u5165\u7c7b\u578b\u4e3apandas\u7684Dataframe\u6216Numpy\u6570\u7ec4\u3002 tips['tip_pct'] = tips['tip'] / (tips['total_bill'] - tips['tip']) print(tips) # total_bill tip smoker day time size tip_pct # 0 16.99 1.01 No Sun Dinner 2 0.063204 # 1 10.34 1.66 No Sun Dinner 3 0.191244 # 2 21.01 3.50 No Sun Dinner 3 0.199886 # 3 23.68 3.31 No Sun Dinner 2 0.162494 # 4 24.59 3.61 No Sun Dinner 4 0.172069 # .. ... ... ... ... ... ... ... # 239 29.03 5.92 No Sat Dinner 3 0.256166 # 240 27.18 2.00 Yes Sat Dinner 2 0.079428 # 241 22.67 2.00 Yes Sat Dinner 2 0.096759 # 242 17.82 1.75 No Sat Dinner 2 0.108899 # 243 18.78 3.00 No Thur Dinner 2 0.190114 # [244 rows x 7 columns] # barplot: \u5c06\u70b9\u4f30\u8ba1\u548c\u7f6e\u4fe1\u533a\u95f4\u663e\u793a\u4e3a\u77e9\u5f62\u6761\u3002\u6761\u5f62\u56fe\u8868\u793a\u5177\u6709\u6bcf\u4e2a\u77e9\u5f62\u7684\u9ad8\u5ea6\u7684\u6570\u503c\u53d8\u91cf\u7684\u96c6\u4e2d\u8d8b\u52bf\u7684\u4f30\u8ba1\uff0c\u5e76\u4e14\u4f7f\u7528\u8bef\u5dee\u6761\u63d0\u4f9b\u56f4\u7ed5\u8be5\u4f30\u8ba1\u7684\u4e0d\u786e\u5b9a\u6027\u7684\u4e00\u4e9b\u6307\u793a # \u67f1\u5b50\u7684\u503c\u662ftip_pct\u7684\u5e73\u5747\u503c # \u67f1\u5b50\u4e0a\u753b\u51fa\u7684\u9ed1\u7ebf\u4ee3\u8868\u7684\u662f95%\u7684\u7f6e\u4fe1\u533a\u95f4\uff08\u7f6e\u4fe1\u533a\u95f4\u53ef\u4ee5\u901a\u8fc7\u53ef\u9009\u53c2\u6570\u8fdb\u884c\u8bbe\u7f6e\uff09 # hue\u9009\u9879\uff0c\u5141\u8bb8\u6211\u4eec\u901a\u8fc7\u4e00\u4e2a\u989d\u5916\u7684\u5206\u7c7b\u503c\u5c06\u6570\u636e\u5206\u79bb # \u5e26\u53c2\u6570hue='time'\u65f6\uff0c\u56db\u4e2a\u4e0d\u540c\u989c\u8272\u7684\u67f1\u5b50\uff0c\u6bcf\u4e2a\u67f1\u5b50\u4e0a\u6709\u7f6e\u4fe1\u533a\u95f4\u7684\u9ed1\u7ebf\uff0c\u523b\u5ea60.00~0.30\uff0c\u6b65\u957f0.05 # \u4e0d\u5e26\u53c2\u6570hue='time'\u65f6\uff0c\u4e24\u4e2a\u4e0d\u540c\u989c\u8272\u7684\u67f1\u5b50\uff0c\u5206\u522b\u4ee3\u8868Dinner\u548cLunch\uff0c\u4e0d\u662f\u6bcf\u4e2a\u67f1\u5b50\u4e0a\u90fd\u6709\u7f6e\u4fe1\u533a\u95f4\u7684\u9ed1\u7ebf\uff0c\u523b\u5ea60.00~0.30\uff0c\u6b65\u957f0.05 sns.barplot(x='tip_pct', y='day', data=tips, hue='time', orient='h') # \u6839\u636e\u661f\u671f\u65e5\u671f\u548c\u65f6\u95f4\u8ba1\u7b97\u7684\u5c0f\u8d39\u767e\u5206\u6bd4 # sns.barplot(x='tip_pct', y='day', data=tips, orient='h') sns.set(style=\"darkgrid\", palette=\"deep\") # style=\"whitegrid\" plt.show()","title":"\u6298\u7ebf\u56fe"},{"location":"python/DataAnalysis/ch06/#_6","text":"\u76f4\u65b9\u56fe\u662f\u4e00\u79cd\u6761\u5f62\u56fe\uff0c\u7528\u4e8e\u7ed9\u51fa\u503c\u9891\u7387\u7684\u79bb\u6563\u663e\u793a\u3002\u6570\u636e\u70b9\u88ab\u5206\u6210\u79bb\u6563\u7684\uff0c\u5747\u5300\u95f4\u9694\u7684\u7bb1\uff0c\u5e76\u4e14\u7ed8\u5236\u6bcf\u4e2a\u7bb1\u4e2d\u6570\u636e\u70b9\u7684\u6570\u91cf\u3002 tips['tip_pct'].plot.hist(bins=50) # \u5c0f\u8d39\u767e\u5206\u6bd4\u7684\u76f4\u65b9\u56fe plt.show() \u5bc6\u5ea6\u56fe\u662f\u4e00\u79cd\u4e0e\u76f4\u65b9\u56fe\u76f8\u5173\u7684\u56fe\u8868\u7c7b\u578b\uff0c\u5b83\u901a\u8fc7\u8ba1\u7b97\u53ef\u80fd\u4ea7\u751f\u89c2\u6d4b\u6570\u636e\u7684\u8fde\u7eed\u6982\u7387\u5206\u5e03\u4f30\u8ba1\u800c\u4ea7\u751f\u3002 \u901a\u5e38\u7684\u505a\u6cd5\u662f\u5c06\u8fd9\u79cd\u5206\u5e03\u8fd1\u4f3c\u4e3a\u201c\u5185\u6838\u201d\u7684\u6df7\u5408\uff0c\u4e5f\u5c31\u662f\u50cf\u6b63\u6001\u5206\u5e03\u90a3\u6837\u7b80\u5355\u7684\u5206\u5e03\u3002 \u56e0\u6b64\uff0c\u5bc6\u5ea6\u56fe\u4e5f\u88ab\u79f0\u4e3a\u5185\u6838\u5bc6\u5ea6\u4f30\u8ba1\u56fe\uff08KDE\uff09\u3002 tips['tip_pct'].plot.density() # \u5c0f\u8d39\u767e\u5206\u6bd4\u5bc6\u5ea6\u56fe plt.show() \u7ed8\u5236\u76f4\u65b9\u56fe\u548c\u8fde\u7eed\u5bc6\u5ea6\u4f30\u8ba1 sns.displot() \u3002 sns.distplot(tips['tip_pct'], bins=100, color='k') plt.show() # FutureWarning: `distplot` is a deprecated function and will be removed in a future version. # Please adapt your code to use either `displot` (a figure-level function with similar flexibility) # or `histplot` (an axes-level function for histograms).","title":"\u76f4\u65b9\u56fe\u548c\u5bc6\u5ea6\u56fe"},{"location":"python/DataAnalysis/ch06/#_7","text":"\u70b9\u56fe\u6216\u6563\u70b9\u56fe\u53ef\u4ee5\u7528\u4e8e\u68c0\u9a8c\u4e24\u4e2a\u4e00\u7ef4\u6570\u636e\u5e8f\u5217\u4e4b\u95f4\u7684\u5173\u7cfb\u3002 \u5b9e\u4f8b\uff1a\u4ece statsmodels \u9879\u76ee\u4e2d\u8f7d\u5165\u4e86macrodata\u6570\u636e\u96c6\uff0c\u5e76\u9009\u62e9\u4e86\u4e00\u4e9b\u53d8\u91cf\uff0c\u4e4b\u540e\u8ba1\u7b97\u5bf9\u6570\u5dee\u3002 macro = pd.read_csv('../examples/macrodata.csv') print(macro.head(5)) # year quarter realgdp realcons ... unemp pop infl realint # 0 1959.0 1.0 2710.349 1707.4 ... 5.8 177.146 0.00 0.00 # 1 1959.0 2.0 2778.801 1733.7 ... 5.1 177.830 2.34 0.74 # 2 1959.0 3.0 2775.488 1751.8 ... 5.3 178.657 2.74 1.09 # 3 1959.0 4.0 2785.204 1753.7 ... 5.6 179.386 0.27 4.06 # 4 1960.0 1.0 2847.699 1770.5 ... 5.2 180.007 2.31 1.19 # [5 rows x 14 columns] data = macro[['cpi', 'm1', 'tbilrate', 'unemp']] print(data.head(5)) # cpi m1 tbilrate unemp # 0 28.98 139.7 2.82 5.8 # 1 29.15 141.7 3.08 5.1 # 2 29.35 140.5 3.82 5.3 # 3 29.37 140.0 4.33 5.6 # 4 29.54 139.6 3.50 5.2 trans_data = np.log(data).diff().dropna() print(trans_data[-5:]) # cpi m1 tbilrate unemp # 198 -0.007904 0.045361 -0.396881 0.105361 # 199 -0.021979 0.066753 -2.277267 0.139762 # 200 0.002340 0.010286 0.606136 0.160343 # 201 0.008419 0.037461 -0.200671 0.127339 # 202 0.008894 0.012202 -0.405465 0.042560 \u7528 seaborn \u7684 regplot \u65b9\u6cd5\u7ed8\u5236\u6563\u70b9\u56fe\uff0c\u5e76\u62df\u5408\u51fa\u4e00\u4e2a\u6761\u7ebf\u6027\u56de\u5f52\u7ebf\u3002( seaborn\u6587\u6863 ) sns.regplot('m1', 'unemp', data=trans_data) plt.title('Changes in log %s versus log %s ' % ('m1', 'unemp')) plt.show() \u5728\u63a2\u7d22\u6027\u6570\u636e\u5206\u6790\u4e2d\uff0c\u80fd\u591f\u67e5\u770b\u4e00\u7ec4\u53d8\u91cf\u4e2d\u7684\u6240\u6709\u6563\u70b9\u56fe\u662f\u6709\u5e2e\u52a9\u7684\uff0c\u8fd9\u88ab\u79f0\u4e3a\u6210\u5bf9\u56fe\u6216\u6563\u70b9\u56fe\u77e9\u9635\u3002 Seaborn\u6709\u4e00\u4e2a\u65b9\u4fbf\u7684 pairplot \u51fd\u6570\uff0c\u5b83\u652f\u6301\u5728\u5bf9\u89d2\u7ebf\u4e0a\u653e\u7f6e\u6bcf\u4e2a\u53d8\u91cf\u7684\u76f4\u65b9\u56fe\u6216\u5bc6\u5ea6\u4f30\u8ba1\u503c\u3002 plot_ksw \u53c2\u6570\u80fd\u591f\u5c06\u914d\u7f6e\u9009\u9879\u4f20\u9012\u7ed9\u975e\u5bf9\u89d2\u5143\u7d20\u4e0a\u7684\u5404\u4e2a\u7ed8\u56fe\u8c03\u7528\u3002 sns.pairplot(trans_data, diag_kind='kde', plot_kws={'alpha': 0.2}) plt.show()","title":"\u6563\u70b9\u56fe\u6216\u70b9\u56fe"},{"location":"python/DataAnalysis/ch06/#_8","text":"\u5982\u679c\u6570\u636e\u96c6\u6709\u989d\u5916\u7684\u5206\u7ec4\u7ef4\u5ea6\u600e\u4e48\u529e\uff1f\u4f7f\u7528\u5206\u9762\u7f51\u683c\u662f\u5229\u7528\u591a\u79cd\u5206\u7ec4\u53d8\u91cf\u5bf9\u6570\u636e\u8fdb\u884c\u53ef\u89c6\u5316\u7684\u65b9\u5f0f\u3002 seaborn\u62e5\u6709\u4e00\u4e2a\u6709\u6548\u7684\u5185\u5efa\u51fd\u6570 factorplot \uff0c\u5b83\u53ef\u4ee5\u7b80\u5316\u591a\u79cd\u5206\u9762\u7ed8\u56fe\u3002 sns.factorplot(x='day', y='tip_pct', hue='time', col='smoker', kind='bar', data=tips[tips.tip_pct < 1]) plt.show() # UserWarning: The `factorplot` function has been renamed to `catplot`. # The original name will be removed in a future release. Please update your code. # Note that the default `kind` in `factorplot` (`'point'`) has changed `'strip'` in `catplot`. sns.catplot(x='day', y='tip_pct', hue='time', col='smoker', kind='box', data=tips[tips.tip_pct < 0.5]) plt.show()","title":"\u5206\u9762\u7f51\u683c\u548c\u5206\u7c7b\u6570\u636e"},{"location":"python/DataAnalysis/ch06/#python","text":"\u81ea2010\u5e74\u4ee5\u6765\uff0c\u5f88\u591a\u5f00\u53d1\u5de5\u4f5c\u90fd\u96c6\u4e2d\u5728\u521b\u5efaweb\u4ea4\u4e92\u5f0f\u56fe\u5f62\u4e0a\u3002 \u501f\u52a9\u50cf Bokeh \u548c Plotly \u8fd9\u6837\u7684\u5de5\u5177\uff0c\u5728web\u6d4f\u89c8\u5668\u4e2d\u521b\u5efa\u52a8\u6001\u7684\u3001\u4ea4\u4e92\u5f0f\u56fe\u50cf\u7684\u5de5\u4f5c\u73b0\u5728\u5df2\u7ecf\u53ef\u4ee5\u5b9e\u73b0\u3002 \u53ef\u89c6\u5316\u662f\u4e00\u4e2a\u6d3b\u8dc3\u7684\u7814\u7a76\u9886\u57df\u3002","title":"\u5176\u4ed6Python\u53ef\u89c6\u5316\u5de5\u5177"},{"location":"python/DataAnalysis/ch07/","text":"\u6570\u636e\u805a\u5408\u4e0e\u5206\u7ec4\u64cd\u4f5c \u00b6 GroupBy\u673a\u5236 \u00b6 import pandas as pd import numpy as np \u5206\u7ec4\u673a\u5236 \u00b6 \u5206\u7ec4\u64cd\u4f5c\u7b2c\u4e00\u6b65\uff0c\u6570\u636e\u5305\u542b\u5728pandas\u5bf9\u8c61\u4e2d\uff0c\u53ef\u4ee5\u662fSeries\u3001DataFrame\u6216\u5176\u4ed6\u6570\u636e\u7ed3\u6784\u3002\u4e4b\u540e\u6839\u636e\u63d0\u4f9b\u7684\u4e00\u4e2a\u6216\u591a\u4e2a\u952e\u5206\u79bb\u5230\u5404\u4e2a\u7ec4\u4e2d\u3002 \u5206\u7ec4\u952e\u53ef\u662f\u591a\u79cd\u5f62\u5f0f\u7684\uff0c\u5e76\u4e14\u952e\u4e0d\u4e00\u5b9a\u662f\u5b8c\u5168\u76f8\u540c\u7684\u7c7b\u578b(\u6ce8\u610f\u540e\u9762\u4ecb\u7ecd\u7684\u4e09\u4e2a\u65b9\u6cd5\u662f\u53ef\u4ee5\u4ea7\u751f\u7528\u4e8e\u5206\u9694\u5bf9\u8c61\u7684\u503c\u6570\u7ec4\u7684\u5feb\u6377\u65b9\u5f0f)\uff1a \u4e0e\u9700\u8981\u5206\u7ec4\u7684\u8f74\u5411\u957f\u5ea6\u4e00\u81f4\u7684\u503c\u5217\u8868\u6216\u503c\u6570\u7ec4\u3002\u9ed8\u8ba4\u60c5\u51b5\u4e0b\uff0cgroupby\u5728axis=0\u7684\u8f74\u5411\u4e0a\u5206\u7ec4\u3002 DataFrame\u7684\u5217\u540d\u7684\u503c\u3002 \u53ef\u4ee5\u5c06\u5206\u7ec4\u8f74\u5411\u4e0a\u7684\u503c\u548c\u5206\u7ec4\u540d\u79f0\u76f8\u5339\u914d\u7684\u5b57\u5178\u6216Series\u3002 \u53ef\u4ee5\u5728\u8f74\u7d22\u5f15\u6216\u7d22\u5f15\u4e2d\u7684\u5355\u4e2a\u6807\u7b7e\u4e0a\u8c03\u7528\u7684\u51fd\u6570\u3002 \u8bf7\u6ce8\u610f\uff0c\u5206\u7ec4\u952e\u4e2d\u7684\u4efb\u4f55\u7f3a\u5931\u503c\u5c06\u88ab\u6392\u9664\u5728\u7ed3\u679c\u4e4b\u5916\u3002 \u5206\u79bb\u64cd\u4f5c\u662f\u5728\u6570\u636e\u5bf9\u8c61\u7684\u7279\u5b9a\u8f74\u5411\u4e0a\u8fdb\u884c\u7684\u3002\u4f8b\u5982\uff0cDataFrame\u53ef\u4ee5\u5728\u5b83\u7684\u884c\u65b9\u5411\uff08axis=0\uff09\u6216\u5217\u65b9\u5411\uff08axis=1\uff09\u8fdb\u884c\u5206\u7ec4\u3002 \u5206\u7ec4\u64cd\u4f5c\u540e\uff0c\u4e00\u4e2a\u51fd\u6570\u5c31\u53ef\u4ee5\u5e94\u7528\u5230\u5404\u4e2a\u7ec4\u4e2d\uff0c\u4ea7\u751f\u65b0\u7684\u503c\u3002\u6700\u7ec8\uff0c\u6240\u6709\u51fd\u6570\u7684\u5e94\u7528\u7ed3\u679c\u4f1a\u8054\u5408\u4e3a\u4e00\u4e2a\u7ed3\u679c\u5bf9\u8c61\u3002 df = pd.DataFrame( { 'key1': ['a', 'a', 'b', 'b', 'a'], 'key2': ['one', 'two', 'one', 'two', 'one'], 'data1': [1, 3, 5, 7, 9], 'data2': [2, 4, 6, 8, 10] } ) \u6839\u636ekey1\u6807\u7b7e\u8ba1\u7b97data1\u5217\u7684\u5747\u503c\uff0c\u65b9\u6cd5\u4e00\uff0c\u8bbf\u95ee data1 \u5e76\u4f7f\u7528 key1 \u5217\uff08\u5b83\u662f\u4e00\u4e2aSeries\uff09\u8c03\u7528 groupby \u65b9\u6cd5\uff1a grouped = df['data1'].groupby(df['key1']) print(grouped) # grouped \u53d8\u91cf\u73b0\u5728\u662f\u4e00\u4e2a GroupBy \u5bf9\u8c61\uff0c\u5b83\u5b9e\u9645\u4e0a\u8fd8\u6ca1\u6709\u8fdb\u884c\u4efb\u4f55\u8ba1\u7b97\uff0c\u62e5\u6709\u4e00\u4e9b\u5173\u4e8e\u5206\u7ec4\u952edf['key1']\u7684\u4e00\u4e9b\u4e2d\u95f4\u6570\u636e\u7684\u4fe1\u606f\u3002 \u4e0b\u9762\u5bf9 grouped \u5bf9\u8c61\u505a\u4e00\u4e9b\u64cd\u4f5c\uff1a result = grouped.mean() # \u8ba1\u7b97\u5e73\u5747\u503c print(result) # key1 # a 4.333333 # b 6.000000 # Name: data1, dtype: float64 grouped_means = df['data1'].groupby([df['key1'], df['key2']]).mean() print(grouped_means) # key1 key2 # a one 5.0 # two 3.0 # b one 5.0 # two 7.0 # Name: data1, dtype: float64 \u4e0a\u9762\u4f8b\u5b50\u4f7f\u7528\u4e86\u4e24\u4e2a\u952e\u5bf9\u6570\u636e\u8fdb\u884c\u5206\u7ec4\uff0c\u5e76\u4e14\u7ed3\u679cSeries\u73b0\u5728\u62e5\u6709\u4e00\u4e2a\u5305\u542b\u552f\u4e00\u952e\u5bf9\u7684\u591a\u5c42\u7d22\u5f15\u3002 \u4e0b\u9762\u5bf9\u8ba1\u7b97\u7684\u5e73\u5747\u503c\uff08mean\uff09\u8fdb\u884c\u91cd\u5851\uff08unstack\uff09\u3002 print(grouped_means.unstack()) # key2 one two # key1 # a 5.0 3.0 # b 5.0 7.0 \u5206\u7ec4\u4fe1\u606f\u901a\u5e38\u5305\u542b\u5728\u540c\u4e00\u4e2aDataFrame\u4e2d\u3002\u5728\u8fd9\u79cd\u60c5\u51b5\u4e0b\uff0c\u53ef\u4ee5\u4f20\u9012\u5217\u540d\uff08\u65e0\u8bba\u90a3\u4e9b\u5217\u540d\u662f\u5b57\u7b26\u4e32\u3001\u6570\u5b57\u6216\u5176\u4ed6Python\u5bf9\u8c61\uff09\u4f5c\u4e3a\u5206\u7ec4\u952e\uff1a \u4e0b\u9762\u4f8b\u5b50\u4e2d df.groupby('key1').mean() \u7684\u7ed3\u679c\u91cc\u5e76\u6ca1\u6709 key2 \u5217\u3002\u8fd9\u662f\u56e0\u4e3a df['key2'] \u5e76\u4e0d\u662f\u6570\u503c\u6570\u636e\uff0c\u5373 df['key2'] \u662f\u4e00\u4e2a\u5197\u4f59\u5217\uff0c\u56e0\u6b64\u88ab\u6392\u9664\u5728\u7ed3\u679c\u4e4b\u5916\u3002 result = df.groupby('key1').mean() print(result) # data1 data2 # key1 # a 4.333333 5.333333 # b 6.000000 7.000000 result = df.groupby(['key1', 'key2']).mean() print(result) # data1 data2 # key1 key2 # a one 5.0 6.0 # two 3.0 4.0 # b one 5.0 6.0 # two 7.0 8.0 result = df.groupby(['key1', 'key2']).size() print(result) # key1 key # a one 2 # two 1 # b one 1 # two 1 # dtype: int64 \u904d\u5386\u5404\u5206\u7ec4 \u00b6 GroupBy \u5bf9\u8c61\u652f\u6301\u8fed\u4ee3\uff0c\u4f1a\u751f\u6210\u4e00\u4e2a\u5305\u542b\u7ec4\u540d\u548c\u6570\u636e\u5757\u76842\u7ef4\u5143\u7ec4\u5e8f\u5217\u3002 df = pd.DataFrame( { 'key1': ['a', 'a', 'b', 'b', 'a'], 'key2': ['one', 'two', 'one', 'two', 'one'], 'data1': [1, 3, 5, 7, 9], 'data2': [2, 4, 6, 8, 10] } ) \u5355\u4e2a\u5206\u7ec4\u952e\u7684\u60c5\u51b5: for name, group in df.groupby('key1'): print(name) print(group) # a # key1 key2 data1 data2 # 0 a one 1 2 # 1 a two 3 4 # 4 a one 9 10 # b # key1 key2 data1 data2 # 2 b one 5 6 # 3 b two 7 8 \u591a\u4e2a\u5206\u7ec4\u952e\u7684\u60c5\u51b5: \u5143\u7ec4\u4e2d\u7684\u7b2c\u4e00\u4e2a\u5143\u7d20\u662f\u952e\u503c\u7684\u5143\u7ec4\u3002 for (k1, k2), group in df.groupby(['key1', 'key2']): print((k1, k2)) print(group) # ('a', 'one') # key1 key2 data1 data2 # 0 a one 1 2 # 4 a one 9 10 # ('a', 'two') # key1 key2 data1 data2 # 1 a two 3 4 # ('b', 'one') # key1 key2 data1 data2 # 2 b one 5 6 # ('b', 'two') # key1 key2 data1 data2 # 3 b two 7 8 result = dict(list(df.groupby('key1'))) print(result) # df.groupby('key1')\u7684\u7ed3\u679c\u662f\u4e00\u4e2a\u5bf9\u8c61 # # list(df.groupby('key1'))\u7684\u7ed3\u679c\u662f\u5305\u542bFrameData\u7684\u7ed3\u6784\u7684\u5217\u8868list: # [ # ('a', key1 key2 data1 data2 # 0 a one 1 2 # 1 a two 3 4 # 4 a one 9 10), # ('b', key1 key2 data1 data2 # 2 b one 5 6 # 3 b two 7 8) # ] # dict(list(df.groupby('key1')))\u7684\u7ed3\u679c\u662f\u5305\u542bFrameData\u7684\u7ed3\u6784\u7684\u5b57\u5178dict # { # 'a': key1 key2 data1 data2 # 0 a one 1 2 # 1 a two 3 4 # 4 a one 9 10, # 'b': key1 key2 data1 data2 # 2 b one 5 6 # 3 b two 7 8 # } print(result['b']) # key1 key2 data1 data2 # 2 b one 5 6 # 3 b two 7 8 \u9ed8\u8ba4\u60c5\u51b5\u4e0b\uff0c groupby \u5728 axis=0 \u7684\u8f74\u5411\u4e0a\u5206\u7ec4\uff0c\u4e5f\u53ef\u4ee5\u5728\u5176\u4ed6\u4efb\u610f\u8f74\u5411\u4e0a\u8fdb\u884c\u5206\u7ec4\u3002 print(df.dtypes) # key1 object # key2 object # data1 int64 # data2 int64 # dtype: object grouped = df.groupby(df.dtypes, axis=1) print(grouped) # print(list(grouped)) # [ # (dtype('int64'), data1 data2 # 0 1 2 # 1 3 4 # 2 5 6 # 3 7 8 # 4 9 10), # (dtype('O'), key1 key2 # 0 a one # 1 a two # 2 b one # 3 b two # 4 a one) # ] \u6253\u5370\u5404\u5206\u7ec4\u5982\u4e0b\uff1a for dtype, group in grouped: print(dtype) print(group) # int64 # data1 data2 # 0 1 2 # 1 3 4 # 2 5 6 # 3 7 8 # 4 9 10 # object # key1 key2 # 0 a one # 1 a two # 2 b one # 3 b two # 4 a one \u9009\u62e9\u4e00\u5217\u6216\u6240\u6709\u5217\u7684\u5b50\u96c6 \u00b6 \u5bf9\u4e8e\u4eceDataFrame\u521b\u5efa\u7684 GroupBy \u5bf9\u8c61\uff0c\u7528\u5217\u540d\u79f0\u6216\u5217\u540d\u79f0\u6570\u7ec4\u8fdb\u884c\u7d22\u5f15\u65f6\uff0c\u4f1a\u4ea7\u751f\u7528\u4e8e\u805a\u5408\u7684\u5217\u5b50\u96c6\u7684\u6548\u679c\u3002 \u5982\u679c\u4f20\u9012\u7684\u662f\u5217\u8868\u6216\u6570\u7ec4\uff0c\u5219\u6b64\u7d22\u5f15\u64cd\u4f5c\u8fd4\u56de\u7684\u5bf9\u8c61\u662f\u5206\u7ec4\u7684DataFrame\uff1b\u5982\u679c\u53ea\u6709\u5355\u4e2a\u5217\u540d\u4f5c\u4e3a\u6807\u91cf\u4f20\u9012\uff0c\u5219\u4e3a\u5206\u7ec4\u7684Series\uff1b \u5bf9\u6bd4\u4e0b\u97624\u53e5\uff1a result = df.groupby('key1')['data1'] # \u5355\u4e2a\u5217\u540d print(result) # for key, data in result: print(key) print(data) result = df['data1'].groupby(df['key1']) # \u5355\u4e2a\u5217\u540d print(result) # for key, data in result: print(key) print(data) # a # 0 1 # 1 3 # 4 9 # Name: data1, dtype: int64 # b # 2 5 # 3 7 # Name: data1, dtype: int64 result = df.groupby('key1')[['data1']] # \u5217\u8868\u6216\u6570\u7ec4 print(result) # for key, data in result: print(key) print(data) # a # key1 key2 data1 data2 # 0 a one 1 2 # 1 a two 3 4 # 4 a one 9 10 # b # key1 key2 data1 data2 # 2 b one 5 6 # 3 b two 7 8 result = df[['data1']].groupby(df['key1']) # \u5217\u8868\u6216\u6570\u7ec4 print(result) # for key, data in result: print(key) print(data) # a # data1 # 0 1 # 1 3 # 4 9 # b # data1 # 2 5 # 3 7 \u4f7f\u7528\u5b57\u5178\u548cSeries\u5206\u7ec4 \u00b6 \u5206\u7ec4\u4fe1\u606f\u53ef\u80fd\u4f1a\u4ee5\u975e\u6570\u7ec4\u5f62\u5f0f\u5b58\u5728\u3002 \u751f\u6210\u4e00\u4e2a\u793a\u4f8bDataFrame\u3002 people = pd.DataFrame( [[1, 3, 5, 7, 9], [0, 2, 4, 6, 8], [0, 2, 4, 6, 8], [1, 3, 5, 7, 9], [1, 2, 3, 4, 5]], columns=['a', 'b', 'c', 'd', 'e'], index=['Joe', 'Steve', 'Wes', 'Jim', 'Travis'] ) \u6dfb\u52a0\u4e00\u4e9bNA\u503c\u3002 people.iloc[2:3, [1, 2]] = np.nan print(people) # a b c d e # Joe 1 3.0 5.0 7 9 # Steve 0 2.0 4.0 6 8 # Wes 0 NaN NaN 6 8 # Jim 1 3.0 5.0 7 9 # Travis 1 2.0 3.0 4 5 \u5047\u8bbe\u6709\u5982\u4e0b\u5404\u5217\u7684\u5206\u7ec4\u5bf9\u5e94\u5173\u7cfb\uff0c\u5e76\u4e14\u60f3\u628a\u5404\u5217\u6309\u7ec4\u7d2f\u52a0\u3002 mapping = { 'a': 'red', 'b': 'red', 'c': 'blue', 'd': 'blue', 'e': 'red', 'f': 'orange' # \u6ce8\u610f\uff1a\u5065f\u867d\u7136\u6ca1\u6709\u88ab\u7528\u5230\uff0c\u4f46\u4e0d\u5f71\u54cd\u5728\u8fd9\u91cc\u5b9a\u4e49\u3002 } \u628a mapping \u8fd9\u4e2a\u5b57\u5178\u4f20\u7ed9 groupby() \u3002 by_column = people.groupby(mapping, axis=1) print(by_column.sum()) # blue red # Joe 12.0 13.0 # Steve 10.0 10.0 # Wes 6.0 8.0 # Jim 12.0 13.0 # Travis 7.0 8.0 Series\u4e5f\u6709\u76f8\u540c\u7684\u529f\u80fd\uff0c\u53ef\u4ee5\u89c6\u4e3a\u56fa\u5b9a\u5927\u5c0f\u7684\u6620\u5c04\u3002 map_services = pd.Series(mapping) print(map_services) # a red # b red # c blue # d blue # e red # f orange # dtype: object result = people.groupby(map_services, axis=1).count() print(result) # blue red # Joe 2 3 # Steve 2 3 # Wes 1 2 # Jim 2 3 # Travis 2 3 \u4f7f\u7528\u51fd\u6570\u5206\u7ec4 \u00b6 \u4e0e\u4f7f\u7528\u5b57\u5178\u6216Series\u5206\u7ec4\u76f8\u6bd4\uff0c\u4f7f\u7528Python\u51fd\u6570\u662f\u5b9a\u4e49\u5206\u7ec4\u5173\u7cfb\u7684\u4e00\u79cd\u66f4\u4e3a\u901a\u7528\u7684\u65b9\u5f0f\u3002 \u4f5c\u4e3a\u5206\u7ec4\u952e\u4f20\u9012\u7684\u51fd\u6570\u5c06\u4f1a\u6309\u7167\u6bcf\u4e2a\u7d22\u5f15\u503c\u8c03\u7528\u4e00\u6b21\uff0c\u540c\u65f6\u8fd4\u56de\u503c\u4f1a\u88ab\u7528\u4f5c\u5206\u7ec4\u540d\u79f0\u3002\u6ce8\u610f\uff1a\u51fd\u6570\u662f\u4f5c\u7528\u5728\u7d22\u5f15\u4e0a\u3002 result = people.groupby(len).sum() # \u4eba\u7684\u540d\u5b57\u662f\u7d22\u5f15\u503c\uff0c\u6839\u636e\u540d\u5b57\u7684\u957f\u5ea6\u6765\u8fdb\u884c\u5206\u7ec4 print(result) # a b c d e # 3 2 6.0 10.0 20 26 # 5 0 2.0 4.0 6 8 # 6 1 2.0 3.0 4 5 \u53ef\u4ee5\u5c06\u51fd\u6570\u4e0e\u6570\u7ec4\u3001\u5b57\u5178\u6216Series\u8fdb\u884c\u6df7\u5408\uff0c\u6240\u6709\u7684\u5bf9\u8c61\u90fd\u4f1a\u5728\u5185\u90e8\u8f6c\u6362\u4e3a\u6570\u7ec4\u3002 key_list = ['one', 'one', 'one', 'two', 'two'] result = people.groupby([len, key_list]).min() print(result) # a b c d e # 3 one 0 3.0 5.0 6 8 # two 1 3.0 5.0 7 9 # 5 one 0 2.0 4.0 6 8 # 6 two 1 2.0 3.0 4 5 \u6839\u636e\u7d22\u5f15\u5c42\u7ea7\u5206\u7ec4 \u00b6 \u6839\u636e\u5c42\u7ea7\u5206\u7ec4\u65f6\uff0c\u5c06\u5c42\u7ea7\u6570\u503c\u6216\u5c42\u7ea7\u540d\u79f0\u4f20\u9012\u7ed9 level \u5173\u952e\u5b57\u3002 columns = pd.MultiIndex.from_arrays( [['US', 'US', 'US', 'JP', 'JP'], [1, 3, 5, 1, 3]], names=['cty', 'tenor'] ) hier_df = pd.DataFrame( [[1, 3, 5, 7, 9], [0, 2, 4, 6, 8], [1, 3, 5, 7, 9], [1, 2, 3, 4, 5]], columns=columns ) print(hier_df) # cty US JP # tenor 1 3 5 1 3 # 0 1 3 5 7 9 # 1 0 2 4 6 8 # 2 1 3 5 7 9 # 3 1 2 3 4 5 result = hier_df.groupby(level='cty', axis=1).count() print(result) # cty JP US # 0 2 3 # 1 2 3 # 2 2 3 # 3 2 3 \u6570\u636e\u805a\u5408 \u00b6 \u805a\u5408\u662f\u6307\u6240\u6709\u6839\u636e\u6570\u7ec4\u4ea7\u751f\u6807\u91cf\u503c\u7684\u6570\u636e\u8f6c\u6362\u8fc7\u7a0b\uff0c\u6bd4\u5982\uff1a mean \u3001 count \u3001 min \u548c sum \u7b49\u4e00\u4e9b\u805a\u5408\u64cd\u4f5c\u3002 import pandas as pd import numpy as np \u9884\u5907\u77e5\u8bc6\uff1a \u5206\u4f4d\u6570\uff08Quantile\uff09\uff0c\u4e5f\u79f0\u5206\u4f4d\u70b9\uff0c\u662f\u6307\u5c06\u4e00\u4e2a\u968f\u673a\u53d8\u91cf\u7684\u6982\u7387\u5206\u5e03\u8303\u56f4\u5206\u4e3a\u51e0\u4e2a\u7b49\u4efd\u7684\u6570\u503c\u70b9\uff0c\u5206\u6790\u5176\u6570\u636e\u53d8\u91cf\u7684\u8d8b\u52bf\u3002 \u5e38\u7528\u7684\u5206\u4f4d\u6570\u6709 \u4e2d\u4f4d\u6570\u3001\u56db\u5206\u4f4d\u6570\u3001\u767e\u5206\u4f4d\u6570\u7b49\u3002 \u4e2d\u4f4d\u6570\uff08Medians\uff09\u662f\u4e00\u4e2a\u7edf\u8ba1\u5b66\u7684\u4e13\u6709\u540d\u8bcd\uff0c\u4ee3\u8868\u4e00\u4e2a\u6837\u672c\u3001\u79cd\u7fa4\u6216\u6982\u7387\u5206\u5e03\u4e2d\u7684\u4e00\u4e2a\u6570\u503c\uff0c\u53ef\u4ee5\u5c06\u6570\u503c\u96c6\u5408\u5212\u5206\u4e3a\u76f8\u7b49\u7684\u4e24\u90e8\u5206\u3002 \u5229\u7528pandas\u5e93\u8ba1\u7b97 data = [6, 47, 49, 15, 42, 41, 7, 39, 43, 40, 36] \u7684\u5206\u4f4d\u6570\u3002 \u786e\u5b9a p \u5206\u4f4d\u6570\u4f4d\u7f6e\u7684\u4e24\u79cd\u65b9\u6cd5( n \u4e3a\u6570\u636e\u7684\u603b\u4e2a\u6570\uff0c p \u4e3a 0-1 \u4e4b\u95f4\u7684\u503c)\u3002\u5728python\u4e2d\u8ba1\u7b97\u5206\u4f4d\u6570\u4f4d\u7f6e\u7684\u65b9\u6848\u91c7\u7528 position=1+(n-1)*p \uff1a position = (n+1)*p position = 1 + (n-1)*p \u6848\u4f8b1 data = pd.Series(np.array([6, 47, 49, 15, 42, 41, 7, 39, 43, 40, 36])) print(\"\u6570\u636e\u683c\u5f0f\uff1a\") print(np.sort(data)) # \u5fc5\u987b\u8981\u6392\u5e8f print('Q1:', data.quantile(.25)) print('Q2:', data.quantile(.5)) print('Q3:', data.quantile(.75)) # \u6570\u636e\u683c\u5f0f\uff1a # [ 6 7 15 36 39 40 41 42 43 47 49] # Q1: 25.5 # Q2: 40.0 # Q3: 42.5 # \u624b\u7b97\u8ba1\u7b97\u7ed3\u679c\uff1a # Q1\u7684p\u5206\u4f4d\u6570(0.25)\u4f4d\u7f6eposition = 1+(11-1)*0.25 = 3.5(\u53d6\u7b2c3\u4f4d) (p=0.25) Q1=15+(36-15)*0.5=25.5 (\u7b2c3\u30014\u4f4d\u7684\u5dee\u4e58\u4ee5\u4f59\u65700.5) # Q2\u7684p\u5206\u4f4d\u6570(0.5)\u4f4d\u7f6eposition = 1+(11-1)*0.5 = 6 (p=0.5) Q2=40 # Q3\u7684p\u5206\u4f4d\u6570(0.75)\u4f4d\u7f6eposition = 1+(11-1)*0.75 = 9 (p=0.75) Q3=42+(43-42)*0.5=42.5 # IQR = Q3 - Q1 = 17 \u6848\u4f8b2 df = pd.DataFrame(np.array([[1, 1], [2, 10], [3, 100], [4, 100]]), columns=['a', 'b']) print(\"\u6570\u636e\u539f\u59cb\u683c\u5f0f\uff1a\") print(df) print(\"\u8ba1\u7b97p=0.1\u65f6\uff0ca\u5217\u548cb\u5217\u7684\u5206\u4f4d\u6570\") print(df.quantile(.1)) # \u6570\u636e\u539f\u59cb\u683c\u5f0f\uff1a # a b # 0 1 1 # 1 2 10 # 2 3 100 # 3 4 100 # \u8ba1\u7b97p=0.1\u65f6\uff0ca\u5217\u548cb\u5217\u7684\u5206\u4f4d\u6570 # a 1.3 # b 3.7 # Name: 0.1, dtype: float64 # \u624b\u7b97\u8ba1\u7b97\u7ed3\u679c\uff1a # \u8ba1\u7b97a\u5217 # position=1+(4-1)*0.1=1.3 (\u53d6\u7b2c1\u4f4d) # Q1=1+(2-1)*0.3=1.3 (\u7b2c1\u30012\u4f4d\u7684\u5dee\u4e58\u4ee5\u4f59\u65700.3) # \u8ba1\u7b97b\u5217 # position=1+(4-1)*0.1=1.3 (\u53d6\u7b2c1\u4f4d) # Q1=1+(10-1)*0.3=3.7 (\u7b2c1\u30012\u4f4d\u7684\u5dee\u4e58\u4ee5\u4f59\u65700.3) \u4f18\u5316\u7684 groupby \u65b9\u6cd5\uff1a count: \u5206\u7ec4\u4e2d\u975eNA\u503c\u7684\u6570\u91cf sum: \u975eNA\u503c\u7684\u7d2f\u52a0\u548c mean: \u975eNA\u503c\u7684\u5e73\u5747\u503c median: \u975eNA\u503c\u7684\u7b97\u672f\u4e2d\u4f4d\u6570 std, var: \u65e0\u504f\u7684(n-1\u5206\u6bcd)\u6807\u51c6\u5dee\u548c\u65b9\u5dee min, max: \u975eNA\u503c\u7684\u6700\u5c0f\u503c\u3001\u6700\u5927\u503c prod: \u975eNA\u503c\u7684\u4e58\u79ef first, last: \u975eNA\u503c\u7684\u7b2c\u4e00\u4e2a\u3001\u6700\u540e\u4e00\u4e2a\u503c df = pd.DataFrame( { 'key1': ['a', 'a', 'b', 'b', 'a'], 'key2': ['one', 'two', 'one', 'two', 'one'], 'data1': [1, 3, 5, 7, 9], 'data2': [2, 4, 6, 8, 10] } ) print(df) # key1 key2 data1 data2 # 0 a one 1 2 # 1 a two 3 4 # 2 b one 5 6 # 3 b two 7 8 # 4 a one 9 10 grouped = df.groupby('key1') result = grouped['data1'] for i in result: print(i) # ('a', 0 1 # 1 3 # 4 9 # Name: data1, dtype: int64) # ('b', 2 5 # 3 7 # Name: data1, dtype: int64) result = grouped['data1'].quantile(0.9) # quantile\u5206\u4f4d\u6570 print(result) # key1 # a 7.8 # b 6.8 # Name: data1, dtype: float64 # \u624b\u7b97\u8ba1\u7b97\u7ed3\u679c\uff1a # \u8ba1\u7b97a\u5217 # position=1+(3-1)*0.9=2.8 # Q1=3+(9-3)*0.8=7.8 # \u8ba1\u7b97b\u5217 # position=1+(2-1)*0.9=1.9 # Q1=5+(7-5)*0.9=6.8 \u4f7f\u7528\u81ea\u884c\u5236\u5b9a\u7684\u805a\u5408\uff0c\u5e76\u518d\u8c03\u7528\u5df2\u7ecf\u5728\u5206\u7ec4\u5bf9\u8c61\u4e0a\u5b9a\u4e49\u597d\u7684\u65b9\u6cd5\u3002 def peak_to_peak(arr): return arr.max() - arr.min() result = grouped.agg(peak_to_peak) print(result) # data1 data2 # key1 # a 8 8 # b 2 2 result = grouped.describe() print(result) # data1 ... data2 # count mean std min 25% ... min 25% 50% 75% max # key1 ... # a 3.0 4.333333 4.163332 1.0 2.0 ... 2.0 3.0 4.0 7.0 10.0 # b 2.0 6.000000 1.414214 5.0 5.5 ... 6.0 6.5 7.0 7.5 8.0 \u9010\u5217\u53ca\u591a\u51fd\u6570\u5e94\u7528 \u00b6 tips = pd.read_csv('../examples/tips.csv') tips['tip_pct'] = tips['tip'] / (tips['total_bill'] - tips['tip']) print(tips.head(5)) # total_bill tip smoker day time size tip_pct # 0 16.99 1.01 No Sun Dinner 2 0.063204 # 1 10.34 1.66 No Sun Dinner 3 0.191244 # 2 21.01 3.50 No Sun Dinner 3 0.199886 # 3 23.68 3.31 No Sun Dinner 2 0.162494 # 4 24.59 3.61 No Sun Dinner 4 0.172069 \u6839\u636e\u5404\u5217\u540c\u65f6\u4f7f\u7528\u591a\u4e2a\u51fd\u6570\u8fdb\u884c\u805a\u5408 grouped = tips.groupby(['day', 'smoker']) # for i in grouped: # print(i) # (('Fri', 'No'), total_bill tip smoker day time size tip_pct # 91 22.49 3.50 No Fri Dinner 2 0.184308 # ...... # 223 15.98 3.00 No Fri Lunch 3 0.231125) # (('Fri', 'Yes'), total_bill tip smoker day time size tip_pct # 90 28.97 3.00 Yes Fri Dinner 2 0.115518 # ...... # 226 10.09 2.00 Yes Fri Lunch 2 0.247219) # ...... grouped_pct = grouped['tip_pct'] for i in grouped_pct: print(i) # (('Fri', 'No'), 91 0.184308 # 94 0.166667 # ...... # Name: tip_pct, dtype: float64) # (('Fri', 'Yes'), 90 0.115518 # 92 0.210526 # ...... # Name: tip_pct, dtype: float64) # ...... \u5c06\u51fd\u6570\u540d\u4ee5\u5b57\u7b26\u4e32\u5f62\u5f0f\u4f20\u9012\u3002 result = grouped_pct.agg('mean') print(result) # day smoker # Fri No 0.179740 # Yes 0.216293 # Sat No 0.190412 # Yes 0.179833 # Sun No 0.193617 # Yes 0.322021 # Thur No 0.193424 # Yes 0.198508 # Name: tip_pct, dtype: float64 \u5982\u679c\u4f20\u9012\u7684\u662f\u51fd\u6570\u6216\u8005\u51fd\u6570\u540d\u7684\u5217\u8868\uff0c\u4f1a\u5f97\u5230\u4e00\u4e2a\u5217\u540d\u662f\u8fd9\u4e9b\u51fd\u6570\u540d\u7684DataFrame\u3002 \u4e0b\u9762\u4f20\u9012\u4e86\u805a\u5408\u51fd\u6570\u7684\u5217\u8868\u7ed9agg\u65b9\u6cd5\uff0c\u8fd9\u4e9b\u51fd\u6570\u4f1a\u5404\u81ea\u8fd0\u7528\u4e8e\u6570\u636e\u5206\u7ec4\u3002 result = grouped_pct.agg(['mean', 'std', peak_to_peak]) print(result) # mean std peak_to_peak # day smoker # Fri No 0.179740 0.039458 0.094263 # Yes 0.216293 0.077530 0.242219 # Sat No 0.190412 0.058626 0.352192 # Yes 0.179833 0.089496 0.446137 # Sun No 0.193617 0.060302 0.274897 # Yes 0.322021 0.538061 2.382107 # Thur No 0.193424 0.056065 0.284273 # Yes 0.198508 0.057170 0.219047 \u5982\u679c\u4f20\u9012\u7684\u662f (name, function) \u5143\u7ec4\u7684\u5217\u8868\uff0c\u6bcf\u4e2a\u5143\u7ec4\u7684\u7b2c\u4e00\u4e2a\u5143\u7d20\u5c06\u4f5c\u4e3aDataFrame\u7684\u5217\u540d\uff08\u53ef\u4ee5\u8ba4\u4e3a\u4e8c\u5143\u5143\u7ec4\u7684\u5217\u8868\u662f\u4e00\u79cd\u6709\u5e8f\u7684\u5bf9\u5e94\u5173\u7cfb\uff09\uff1a result = grouped_pct.agg([('foo', 'mean'), ('bar', np.std)]) # foo\u662fmean\u503c\u7684\u5217\u540d print(result) # foo bar # day smoker # Fri No 0.179740 0.039458 # Yes 0.216293 0.077530 # Sat No 0.190412 0.058626 # Yes 0.179833 0.089496 # Sun No 0.193617 0.060302 # Yes 0.322021 0.538061 # Thur No 0.193424 0.056065 # Yes 0.198508 0.057170 \u53ef\u4ee5\u6307\u5b9a\u5e94\u7528\u5230\u6240\u6709\u5217\u4e0a\u7684\u51fd\u6570\u5217\u8868\u6216\u6bcf\u4e00\u5217\u4e0a\u8981\u5e94\u7528\u7684\u4e0d\u540c\u51fd\u6570\u3002 \u4e0b\u9762\u4ea7\u751f\u7684DataFrame\u62e5\u6709\u5206\u5c42\u5217\uff0c\u4e0e\u5206\u522b\u805a\u5408\u6bcf\u4e00\u5217\uff0c\u518d\u4ee5\u5217\u540d\u4f5c\u4e3a keys \u53c2\u6570\u4f7f\u7528 concat \u5c06\u7ed3\u679c\u62fc\u63a5\u5728\u4e00\u8d77\u7684\u7ed3\u679c\u76f8\u540c\u3002 functions = ['count', 'mean', 'max'] result = grouped[['tip_pct', 'total_bill']].agg(functions) print(result) # tip_pct total_bill # count mean max count mean max # day smoker # Fri No 4 0.179740 0.231125 4 18.420000 22.75 # Yes 15 0.216293 0.357737 15 16.813333 40.17 # Sat No 45 0.190412 0.412409 45 19.661778 48.33 # Yes 42 0.179833 0.483092 42 21.276667 50.81 # Sun No 57 0.193617 0.338101 57 20.506667 48.17 # Yes 19 0.322021 2.452381 19 24.120000 45.35 # Thur No 45 0.193424 0.362976 45 17.113111 41.19 # Yes 17 0.198508 0.317965 17 19.190588 43.11 # \u628a['tip_pct', 'total_bill']\u6539\u6210[['tip_pct', 'total_bill']]\uff0c\u5c31\u53ef\u4ee5\u907f\u514d\u62a5\u9519 # FutureWarning: Indexing with multiple keys (implicitly converted to a tuple of keys) will be deprecated, use a list instead. # result = grouped['tip_pct', 'total_bill'].agg(functions) print(result['tip_pct']) # count mean max # day smoker # Fri No 4 0.179740 0.231125 # Yes 15 0.216293 0.357737 # Sat No 45 0.190412 0.412409 # Yes 42 0.179833 0.483092 # Sun No 57 0.193617 0.338101 # Yes 19 0.322021 2.452381 # Thur No 45 0.193424 0.362976 # Yes 17 0.198508 0.317965 \u4e5f\u540c\u6837\u53ef\u4ee5\u4f20\u9012\u5177\u6709\u81ea\u5b9a\u4e49\u540d\u79f0\u7684\u5143\u7ec4\u5217\u8868\uff1a ftuples = [('Durchschnitt', 'mean'), ('Abweichung', np.var)] result = grouped[['tip_pct', 'total_bill']].agg(ftuples) print(result) # tip_pct total_bill # Durchschnitt Abweichung Durchschnitt Abweichung # day smoker # Fri No 0.179740 0.001557 18.420000 25.596333 # Yes 0.216293 0.006011 16.813333 82.562438 # Sat No 0.190412 0.003437 19.661778 79.908965 # Yes 0.179833 0.008010 21.276667 101.387535 # Sun No 0.193617 0.003636 20.506667 66.099980 # Yes 0.322021 0.289509 24.120000 109.046044 # Thur No 0.193424 0.003143 17.113111 59.625081 # Yes 0.198508 0.003268 19.190588 69.808518 \u8981\u5c06\u4e0d\u540c\u7684\u51fd\u6570\u5e94\u7528\u5230\u4e00\u4e2a\u6216\u591a\u4e2a\u5217\u4e0a\uff0c\u9700\u8981\u5c06\u542b\u6709\u5217\u540d\u4e0e\u51fd\u6570\u5bf9\u5e94\u5173\u7cfb\u7684\u5b57\u5178\u4f20\u9012\u7ed9 agg \uff1a result = grouped.agg({'tip': np.max, 'size': 'sum'}) print(result) # tip size # day smoker # Fri No 3.50 9 # Yes 4.73 31 # Sat No 9.00 115 # Yes 10.00 104 # Sun No 6.00 167 # Yes 6.50 49 # Thur No 6.70 112 # Yes 5.00 40 result = grouped.agg({'tip_pct': ['min', 'max', 'mean', 'std']}) print(result) # tip_pct # min max mean std # day smoker # Fri No 0.136861 0.231125 0.179740 0.039458 # Yes 0.115518 0.357737 0.216293 0.077530 # Sat No 0.060217 0.412409 0.190412 0.058626 # Yes 0.036955 0.483092 0.179833 0.089496 # Sun No 0.063204 0.338101 0.193617 0.060302 # Yes 0.070274 2.452381 0.322021 0.538061 # Thur No 0.078704 0.362976 0.193424 0.056065 # Yes 0.098918 0.317965 0.198508 0.057170 \u53ea\u6709\u591a\u4e2a\u51fd\u6570\u5e94\u7528\u4e8e\u81f3\u5c11\u4e00\u4e2a\u5217\u65f6\uff0cDataFrame\u624d\u5177\u6709\u5206\u5c42\u5217\u3002 \u8fd4\u56de\u4e0d\u542b\u884c\u7d22\u5f15\u7684\u805a\u5408\u6570\u636e \u00b6 \u5728\u524d\u9762\u6240\u6709\u7684\u4f8b\u5b50\u4e2d\uff0c\u805a\u5408\u6570\u636e\u8fd4\u56de\u65f6\u90fd\u662f\u5e26\u6709\u7d22\u5f15\u7684\uff0c\u6709\u65f6\u7d22\u5f15\u662f\u5206\u5c42\u7684\uff0c\u7531\u552f\u4e00\u7684\u5206\u7ec4\u952e\u8054\u5408\u5f62\u6210\u3002 \u56e0\u4e3a\u4e0d\u662f\u6240\u6709\u7684\u60c5\u51b5\u4e0b\u90fd\u9700\u8981\u7d22\u5f15\uff0c\u6240\u4ee5\u5728\u5927\u591a\u6570\u60c5\u51b5\u4e0b\u53ef\u4ee5\u901a\u8fc7\u5411groupby\u4f20\u9012as_index=False\u6765\u7981\u7528\u5206\u7ec4\u952e\u4f5c\u4e3a\u7d22\u5f15\u7684\u884c\u4e3a\uff1a result = tips.groupby(['day', 'smoker'], as_index=False).mean() print(result) # day smoker total_bill tip size tip_pct # 0 Fri No 18.420000 2.812500 2.250000 0.179740 # 1 Fri Yes 16.813333 2.714000 2.066667 0.216293 # 2 Sat No 19.661778 3.102889 2.555556 0.190412 # 3 Sat Yes 21.276667 2.875476 2.476190 0.179833 # 4 Sun No 20.506667 3.167895 2.929825 0.193617 # 5 Sun Yes 24.120000 3.516842 2.578947 0.322021 # 6 Thur No 17.113111 2.673778 2.488889 0.193424 # 7 Thur Yes 19.190588 3.030000 2.352941 0.198508 \u901a\u8fc7\u5728\u7ed3\u679c\u4e0a\u8c03\u7528reset_index\u4e5f\u53ef\u4ee5\u83b7\u5f97\u540c\u6837\u7684\u7ed3\u679c\u3002\u4f7f\u7528as_index=False\u53ef\u4ee5\u907f\u514d\u4e00\u4e9b\u4e0d\u5fc5\u8981\u7684\u8ba1\u7b97\u3002 result = tips.groupby(['day', 'smoker']).mean() print(result.reset_index()) # day smoker total_bill tip size tip_pct # 0 Fri No 18.420000 2.812500 2.250000 0.179740 # 1 Fri Yes 16.813333 2.714000 2.066667 0.216293 # 2 Sat No 19.661778 3.102889 2.555556 0.190412 # 3 Sat Yes 21.276667 2.875476 2.476190 0.179833 # 4 Sun No 20.506667 3.167895 2.929825 0.193617 # 5 Sun Yes 24.120000 3.516842 2.578947 0.322021 # 6 Thur No 17.113111 2.673778 2.488889 0.193424 # 7 Thur Yes 19.190588 3.030000 2.352941 0.198508 print(result) # total_bill tip size tip_pct # day smoker # Fri No 18.420000 2.812500 2.250000 0.179740 # Yes 16.813333 2.714000 2.066667 0.216293 # Sat No 19.661778 3.102889 2.555556 0.190412 # Yes 21.276667 2.875476 2.476190 0.179833 # Sun No 20.506667 3.167895 2.929825 0.193617 # Yes 24.120000 3.516842 2.578947 0.322021 # Thur No 17.113111 2.673778 2.488889 0.193424 # Yes 19.190588 3.030000 2.352941 0.198508 \u5e94\u7528\uff1a\u901a\u7528\u62c6\u5206-\u5e94\u7528-\u8054\u5408 \u00b6 import pandas as pd import numpy as np import statsmodels.api as sm GroupBy \u65b9\u6cd5\u6700\u5e38\u89c1\u7684\u76ee\u7684\u662f apply \uff08\u5e94\u7528\uff09\u3002 apply \u5c06\u5bf9\u8c61\u62c6\u5206\u6210\u591a\u5757\uff0c\u7136\u540e\u5728\u6bcf\u4e00\u5757\u4e0a\u8c03\u7528\u4f20\u9012\u7684\u51fd\u6570\uff0c\u4e4b\u540e\u5c1d\u8bd5\u5c06\u6bcf\u4e00\u5757\u62fc\u63a5\u5230\u4e00\u8d77\u3002 \u6839\u636e\u4e0b\u9762\u7684\u5c0f\u8d39\u6570\u636e\u96c6\uff0c\u6309\u7ec4\u9009\u51fa\u5c0f\u8d39\u767e\u5206\u6bd4\uff08tip-pct\uff09\u6700\u9ad8\u7684\u4e94\u7ec4\u3002 tips = pd.read_csv('../examples/tips.csv') tips['tip_pct'] = tips['tip'] / (tips['total_bill'] - tips['tip']) \u6837\u672c\u6570\u636e print(tips.head(5)) # total_bill tip smoker day time size tip_pct # 0 16.99 1.01 No Sun Dinner 2 0.063204 # 1 10.34 1.66 No Sun Dinner 3 0.191244 # 2 21.01 3.50 No Sun Dinner 3 0.199886 # 3 23.68 3.31 No Sun Dinner 2 0.162494 # 4 24.59 3.61 No Sun Dinner 4 0.172069 \u9996\u5148\uff0c\u5199\u4e00\u4e2a\u53ef\u4ee5\u5728\u7279\u5b9a\u5217\u4e2d\u9009\u51fa\u6700\u5927\u503c\u6240\u5728\u884c\u7684\u51fd\u6570\uff1a \u6dfb\u52a0\u4e86\u5347\u5e8f\uff0c\u7ed3\u679c\u8f93\u51fa\u6700\u540e5\u884c\uff08\u6700\u540e\u76845\u884c\u4e5f\u662f\u6700\u5927\u76845\u4e2a tip_tcp \u8bb0\u5f55\uff09\u3002 def top(df, n=5, column='tip_pct'): return df.sort_values(by=column, ascending=True)[-n:] result = top(tips, n=6) print(result) # \u7b49\u4ef7\u65b9\u5f0f\uff1a # result = tips.sort_values('tip_pct')[-6:] # print(result) # total_bill tip smoker day time size tip_pct # 109 14.31 4.00 Yes Sat Dinner 2 0.387973 # 183 23.17 6.50 Yes Sun Dinner 4 0.389922 # 232 11.61 3.39 No Sat Dinner 2 0.412409 # 67 3.07 1.00 Yes Sat Dinner 1 0.483092 # 178 9.60 4.00 Yes Sun Dinner 2 0.714286 # 172 7.25 5.15 Yes Sun Dinner 2 2.452381 \u5982\u679c\u6309\u7167 smoker \u8fdb\u884c\u5206\u7ec4\uff0c\u4e4b\u540e\u8c03\u7528 apply \uff0c\u4f1a\u5f97\u5230\u4ee5\u4e0b\u7ed3\u679c\uff1a top \u51fd\u6570\u5728DataFrame\u7684\u6bcf\u4e00\u884c\u5206\u7ec4\u4e0a\u88ab\u8c03\u7528\uff0c\u4e4b\u540e\u4f7f\u7528 pandas.concat \u5c06\u51fd\u6570\u7ed3\u679c\u7c98\u8d34\u5728\u4e00\u8d77\uff0c\u5e76\u4f7f\u7528\u5206\u7ec4\u540d\u4f5c\u4e3a\u5404\u7ec4\u7684\u6807\u7b7e\u3002 \u56e0\u6b64\u7ed3\u679c\u5305\u542b\u4e00\u4e2a\u5206\u5c42\u7d22\u5f15\uff0c\u8be5\u5206\u5c42\u7d22\u5f15\u7684\u5185\u90e8\u5c42\u7ea7\u5305\u542b\u539fDataFrame\u7684\u7d22\u5f15\u503c\u3002 result = tips.groupby('smoker').apply(top) print(result) # total_bill tip smoker day time size tip_pct # smoker # No 88 24.71 5.85 No Thur Lunch 2 0.310180 # 185 20.69 5.00 No Sun Dinner 5 0.318674 # 51 10.29 2.60 No Sun Dinner 2 0.338101 # 149 7.51 2.00 No Thur Lunch 2 0.362976 # 232 11.61 3.39 No Sat Dinner 2 0.412409 # Yes 109 14.31 4.00 Yes Sat Dinner 2 0.387973 # 183 23.17 6.50 Yes Sun Dinner 4 0.389922 # 67 3.07 1.00 Yes Sat Dinner 1 0.483092 # 178 9.60 4.00 Yes Sun Dinner 2 0.714286 # 172 7.25 5.15 Yes Sun Dinner 2 2.452381 \u5982\u679c\u9664\u4e86\u5411 apply \u4f20\u9012\u51fd\u6570\uff0c\u8fd8\u4f20\u9012\u5176\u4ed6\u53c2\u6570\u6216\u5173\u952e\u5b57\u7684\u8bdd\uff0c\u4f60\u53ef\u4ee5\u628a\u8fd9\u4e9b\u653e\u5728\u51fd\u6570\u540e\u8fdb\u884c\u4f20\u9012\u3002 result = tips.groupby('smoker').apply(top, n=1, column='total_bill') print(result) # \u8fd92\u884c\u90fd\u662fsmoker\u662fyes\u548cno\u65f6\u6700\u5927total_bill\u503c\u6240\u5728\u884c\u3002 # total_bill tip smoker day time size tip_pct # smoker # No 212 48.33 9.0 No Sat Dinner 4 0.228833 # Yes 170 50.81 10.0 Yes Sat Dinner 3 0.245038 \u5728 GroupBy \u5bf9\u8c61\u4e0a\u8c03\u7528 describe \u65b9\u6cd5\u3002 result = tips.groupby('smoker')['tip_pct'].describe() print(result) # count mean std ... 50% 75% max # smoker ... # No 151.0 0.192237 0.057665 ... 0.184308 0.227015 0.412409 # Yes 93.0 0.218176 0.254295 ... 0.181818 0.242326 2.452381 # [2 rows x 8 columns] print(result.unstack('smoker')) # \u7c7b\u4f3c\u4e8e\u8f6c\u7f6e # smoker # count No 151.000000 # Yes 93.000000 # mean No 0.192237 # Yes 0.218176 # std No 0.057665 # Yes 0.254295 # min No 0.060217 # Yes 0.036955 # 25% No 0.158622 # Yes 0.119534 # 50% No 0.184308 # Yes 0.181818 # 75% No 0.227015 # Yes 0.242326 # max No 0.412409 # Yes 2.452381 # dtype: float64 \u5728 GroupBy \u5bf9\u8c61\u7684\u5185\u90e8\uff0c\u5f53\u8c03\u7528\u50cf describe \u8fd9\u6837\u7684\u65b9\u6cd5\u65f6\uff0c\u5b9e\u9645\u4e0a\u662f\u4ee5\u4e0b\u4ee3\u7801\u7684\u7b80\u5199\uff1a grouped = tips.groupby(['smoker']) f = lambda x: x.describe() result = grouped.apply(f) print(result) # total_bill tip size tip_pct # smoker # No count 151.000000 151.000000 151.000000 151.000000 # mean 19.188278 2.991854 2.668874 0.192237 # std 8.255582 1.377190 1.017984 0.057665 # min 7.250000 1.000000 1.000000 0.060217 # 25% 13.325000 2.000000 2.000000 0.158622 # 50% 17.590000 2.740000 2.000000 0.184308 # 75% 22.755000 3.505000 3.000000 0.227015 # max 48.330000 9.000000 6.000000 0.412409 # Yes count 93.000000 93.000000 93.000000 93.000000 # mean 20.756344 3.008710 2.408602 0.218176 # std 9.832154 1.401468 0.810751 0.254295 # min 3.070000 1.000000 1.000000 0.036955 # 25% 13.420000 2.000000 2.000000 0.119534 # 50% 17.920000 3.000000 2.000000 0.181818 # 75% 26.860000 3.680000 3.000000 0.242326 # max 50.810000 10.000000 5.000000 2.452381 \u538b\u7f29\u5206\u7ec4\u952e \u00b6 \u5728\u524d\u9762\u7684\u4f8b\u5b50\u4e2d\u6240\u5f97\u5230\u7684\u5bf9\u8c61\uff0c\u90fd\u5177\u6709\u5206\u7ec4\u952e\u6240\u5f62\u6210\u7684\u5206\u5c42\u7d22\u5f15\u4ee5\u53ca\u6bcf\u4e2a\u539f\u59cb\u5bf9\u8c61\u7684\u7d22\u5f15\u3002 \u4e5f\u53ef\u4ee5\u901a\u8fc7\u5411 groupby \u4f20\u9012 group_keys=False \u6765\u7981\u7528\u8fd9\u4e2a\u529f\u80fd\u3002 result = tips.groupby('smoker', group_keys=True).apply(top) print(result) # total_bill tip smoker day time size tip_pct # smoker # No 88 24.71 5.85 No Thur Lunch 2 0.310180 # 185 20.69 5.00 No Sun Dinner 5 0.318674 # 51 10.29 2.60 No Sun Dinner 2 0.338101 # 149 7.51 2.00 No Thur Lunch 2 0.362976 # 232 11.61 3.39 No Sat Dinner 2 0.412409 # Yes 109 14.31 4.00 Yes Sat Dinner 2 0.387973 # 183 23.17 6.50 Yes Sun Dinner 4 0.389922 # 67 3.07 1.00 Yes Sat Dinner 1 0.483092 # 178 9.60 4.00 Yes Sun Dinner 2 0.714286 # 172 7.25 5.15 Yes Sun Dinner 2 2.452381 result = tips.groupby('smoker', group_keys=False).apply(top) print(result) # total_bill tip smoker day time size tip_pct # 88 24.71 5.85 No Thur Lunch 2 0.310180 # 185 20.69 5.00 No Sun Dinner 5 0.318674 # 51 10.29 2.60 No Sun Dinner 2 0.338101 # 149 7.51 2.00 No Thur Lunch 2 0.362976 # 232 11.61 3.39 No Sat Dinner 2 0.412409 # 109 14.31 4.00 Yes Sat Dinner 2 0.387973 # 183 23.17 6.50 Yes Sun Dinner 4 0.389922 # 67 3.07 1.00 Yes Sat Dinner 1 0.483092 # 178 9.60 4.00 Yes Sun Dinner 2 0.714286 # 172 7.25 5.15 Yes Sun Dinner 2 2.452381 \u5206\u4f4d\u6570\u4e0e\u6876\u5206\u6790 \u00b6 \u7b2c8\u7ae0\u4e2d\uff0cpandas\u6709\u4e00\u4e9b\u5de5\u5177\uff0c\u5c24\u5176\u662f cut \u548c qcut \uff0c\u7528\u4e8e\u5c06\u6570\u636e\u6309\u7167\u4f60\u9009\u62e9\u7684\u7bb1\u4f4d\u6216\u6837\u672c\u5206\u4f4d\u6570\u8fdb\u884c\u5206\u6876\u3002 \u4e0e groupby \u65b9\u6cd5\u4e00\u8d77\u4f7f\u7528\u8fd9\u4e9b\u51fd\u6570\u53ef\u4ee5\u5bf9\u6570\u636e\u96c6\u66f4\u65b9\u4fbf\u5730\u8fdb\u884c\u5206\u6876\u6216\u5206\u4f4d\u5206\u6790\u3002 \u590d\u4e60\uff1a\u673a\u68b0\u5b66\u4e60\u4e2d\u7684\u5206\u7bb1\u5904\u7406\u3002 \u5728\u673a\u68b0\u5b66\u4e60\u4e2d\u7ecf\u5e38\u4f1a\u5bf9\u6570\u636e\u8fdb\u884c\u5206\u7bb1\u5904\u7406\u7684\u64cd\u4f5c\uff0c \u4e5f\u5c31\u662f\u628a\u4e00\u6bb5\u8fde\u7eed\u7684\u503c\u5207\u5206\u6210\u82e5\u5e72\u6bb5\uff0c\u6bcf\u4e00\u6bb5\u7684\u503c\u770b\u6210\u4e00\u4e2a\u5206\u7c7b\u3002\u8fd9\u4e2a\u628a\u8fde\u7eed\u503c\u8f6c\u6362\u6210\u79bb\u6563\u503c\u7684\u8fc7\u7a0b\uff0c\u6211\u4eec\u53eb\u505a\u5206\u7bb1\u5904\u7406\u3002 \u6bd4\u5982\uff0c\u628a\u5e74\u9f84\u630915\u5c81\u5212\u5206\u6210\u4e00\u7ec4\uff0c0-15\u5c81\u53eb\u505a\u5c11\u5e74\uff0c16-30\u5c81\u53eb\u505a\u9752\u5e74\uff0c31-45\u5c81\u53eb\u505a\u58ee\u5e74\u3002\u5728\u8fd9\u4e2a\u8fc7\u7a0b\u4e2d\uff0c\u6211\u4eec\u628a\u8fde\u7eed\u7684\u5e74\u9f84\u5206\u6210\u4e86\u4e09\u4e2a\u7c7b\u522b\uff0c\u201c\u5c11\u5e74\u201d\uff0c\u201c\u9752\u5e74\u201d\u548c\u201c\u58ee\u5e74\u201d\u5c31\u662f\u5404\u4e2a\u7c7b\u522b\u7684\u540d\u79f0\uff0c\u6216\u8005\u53eb\u505a\u6807\u7b7e\u3002 \u5728pandas\u4e2d\uff0c cut \u548c qcut \u51fd\u6570\u90fd\u53ef\u4ee5\u8fdb\u884c\u5206\u7bb1\u5904\u7406\u64cd\u4f5c\u3002 cut() \u6309\u7167\u53d8\u91cf\u7684\u503c\u5bf9\u53d8\u91cf\u8fdb\u884c\u5206\u5272\uff0c\u6bcf\u4e2a\u5206\u7ec4\u91cc\u6570\u636e\u7684\u4e2a\u6570\u5e76\u4e0d\u4e00\u6837\u3002 qcut() \u662f\u6309\u53d8\u91cf\u7684\u6570\u91cf\u6765\u5bf9\u53d8\u91cf\u8fdb\u884c\u5206\u5272\uff0c\u5e76\u4e14\u5c3d\u91cf\u4fdd\u8bc1\u6bcf\u4e2a\u5206\u7ec4\u91cc\u53d8\u91cf\u7684\u4e2a\u6570\u76f8\u540c\u3002 \u8003\u8651\u4e0b\u9762\u4e00\u4e2a\u7b80\u5355\u7684\u968f\u673a\u6570\u636e\u96c6\u548c\u4e00\u4e2a\u4f7f\u7528 cut \u7684\u7b49\u957f\u6876\u5206\u7c7b\uff1a df = pd.DataFrame( { 'data1': np.random.randn(1000), 'data2': np.random.randn(1000) } ) quartiles = pd.cut(df.data1, 4) # \u6309\u7167data1\u503c\u7531\u5c0f\u5230\u5927\u7684\u987a\u5e8f\u5c06\u6570\u636e\u5206\u62104\u4efd\uff0c\u5e76\u4e14\u4f7f\u6bcf\u7ec4\u503c\u7684\u8303\u56f4\u5927\u81f4\u76f8\u7b49\u3002 print(quartiles[:10]) # 0 (-0.0743, 1.729] # 1 (-0.0743, 1.729] # 2 (-0.0743, 1.729] # 3 (-0.0743, 1.729] # 4 (-1.877, -0.0743] # 5 (-0.0743, 1.729] # 6 (-0.0743, 1.729] # 7 (-0.0743, 1.729] # 8 (-1.877, -0.0743] # 9 (-0.0743, 1.729] # Name: data1, dtype: category # Categories ( # 4, # interval[float64, right]): [ # (-3.687, -1.877] < (-1.877, -0.0743] < (-0.0743, 1.729] < (1.729, 3.531] # ] \u4e0a\u9762 cut \u8fd4\u56de\u7684 Categorical \u5bf9\u8c61\u53ef\u4ee5\u76f4\u63a5\u4f20\u9012\u7ed9 groupby \u3002\u5229\u7528\u5b83\u8ba1\u7b97\u51fa data2 \u5217\u7684\u4e00\u4e2a\u7edf\u8ba1\u503c\u96c6\u5408\uff0c\u5982\u4e0b\uff1a def get_stats(group): return { 'min': group.min(), 'max': group.max(), 'count': group.count(), 'mean': group.mean() } grouped = df.data2.groupby(quartiles) for i in grouped: print(i) result = grouped.apply(get_stats).unstack() print(result) # min max count mean # data1 # (-3.145, -1.424] -1.759377 2.484321 77.0 -0.127900 # (-1.424, 0.29] -3.142344 2.830654 524.0 -0.081931 # (0.29, 2.005] -3.557136 3.261635 376.0 0.015715 # (2.005, 3.719] -2.829458 1.766352 23.0 -0.198780 \u4f7f\u7528 qcut \uff0c\u6839\u636e\u6837\u672c\u5206\u4f4d\u6570\u8ba1\u7b97\u51fa\u7b49\u5927\u5c0f\u7684\u6876\uff0c\u5c31\u662f\u7b49\u957f\u6876\u3002\u901a\u8fc7\u4f20\u9012 labels=False \u6765\u83b7\u5f97\u5206\u4f4d\u6570\u6570\u503c\u3002 grouping = pd.qcut(df.data1, 10, labels=False) grouped = df.data2.groupby(grouping) result = grouped.apply(get_stats).unstack() print(result) # min max count mean # data1 # 0 -3.678934 3.022862 100.0 0.029658 # 1 -2.319813 2.646502 100.0 0.094035 # 2 -2.873727 2.470840 100.0 0.023866 # 3 -2.196701 2.042251 100.0 0.021232 # 4 -2.154161 2.020809 100.0 0.110834 # 5 -2.723061 2.415626 100.0 0.057365 # 6 -2.291470 2.536159 100.0 0.020866 # 7 -2.064083 1.799356 100.0 -0.081025 # 8 -3.405679 1.792581 100.0 -0.009705 # 9 -2.469285 2.600849 100.0 -0.061721 \u793a\u4f8b\uff1a\u4f7f\u7528\u6307\u5b9a\u5206\u7ec4\u503c\u586b\u5145\u7f3a\u5931\u503c \u00b6 \u5728\u6e05\u9664\u7f3a\u5931\u503c\u65f6\uff0c\u6709\u65f6\u4f1a\u4f7f\u7528 dropna \u6765\u53bb\u9664\u7f3a\u5931\u503c\uff0c\u6709\u65f6\u4f7f\u7528\u4fee\u6b63\u503c\u6216\u6765\u81ea\u4e8e\u5176\u4ed6\u6570\u636e\u7684\u503c\u6765\u8f93\u5165\uff08\u586b\u5145\uff09\u5230 null \u503c\uff08 NA \uff09\u3002 fillna \u662f\u4e00\u4e2a\u53ef\u4ee5\u4f7f\u7528\u7684\u6b63\u786e\u5de5\u5177\u3002 \u4f8b\u5982\u4e0b\u9762\u4f8b\u5b50\u4e2d\u4f7f\u7528\u4f7f\u7528\u5e73\u5747\u503c\u6765\u586b\u5145NA\u503c\uff1a data = (100, 110, 120, 130, 140, 150) s = pd.Series(data) print(s) # 0 100 # 1 110 # 2 120 # 3 130 # 4 140 # 5 150 # dtype: float64 \u5c06\u6570\u636e\u4e2d\u7684\u4e00\u4e9b\u503c\u8bbe\u7f6e\u4e3a\u7f3a\u5931\u503c\uff1a s[::2] = np.nan print(s) # 0 NaN # 1 110.0 # 2 NaN # 3 130.0 # 4 NaN # 5 150.0 # dtype: float64 result = s.fillna(s.mean()) # 110, 130, 150\u7684\u5e73\u5747\u503c\u662f130 print(result) # 0 130.0 # 1 110.0 # 2 130.0 # 3 130.0 # 4 130.0 # 5 150.0 # dtype: float64 \u4e0b\u9762\u7684\u4f8b\u5b50\u662f\u6309\u7ec4\u586b\u5145NA\u503c\uff1a \u65b9\u6cd51,\u5bf9\u6570\u636e\u5206\u7ec4\u540e\u4f7f\u7528 apply \u3002 \u65b9\u6cd52,\u5728\u6bcf\u4e2a\u6570\u636e\u5757\u4e0a\u90fd\u8c03\u7528 fillna \u7684\u51fd\u6570\u3002 data = (100, 110, 120, 130, 140, 150, 160, 170) states = ['Ohio', 'New York', 'Vermont', 'Florida', 'Oregon', 'Nevada', 'California', 'Idaho'] group_key = ['East'] * 4 + ['West'] * 4 # 4\u4e2aEast\u548c4\u4e2aWest\u62fc\u63a5\u7684\u5217\u8868list s = pd.Series(data, index=states) print(s) # Ohio 100 # New York 110 # Vermont 120 # Florida 130 # Oregon 140 # Nevada 150 # California 160 # Idaho 170 # dtype: int64 \u5c06\u6570\u636e\u4e2d\u7684\u4e00\u4e9b\u503c\u8bbe\u7f6e\u4e3a\u7f3a\u5931\u503c\uff1a s[['Vermont', 'Nevada', 'Idaho']] = np.nan print(s) # Ohio 100.0 # New York 110.0 # Vermont NaN # Florida 130.0 # Oregon 140.0 # Nevada NaN # California 160.0 # Idaho NaN # dtype: float64 result = s.groupby(group_key).mean() print(result) # East 113.333333 # West 150.000000 # dtype: float64 \u7528\u4e0a\u9762\u5f97\u51fa\u7684\u5206\u7ec4\u5e73\u5747\u503c\u6765\u586b\u5145NA\u3002 fill_mean = lambda g: g.fillna(g.mean()) result = s.groupby(group_key).apply(fill_mean) print(result) # Ohio 100.000000 # New York 110.000000 # Vermont 113.333333 # Florida 130.000000 # Oregon 140.000000 # Nevada 150.000000 # California 160.000000 # Idaho 150.000000 # dtype: float64 \u5982\u679c\u5df2\u7ecf\u5728\u4ee3\u7801\u4e2d\u4e3a\u6bcf\u4e2a\u5206\u7ec4\u9884\u5b9a\u4e49\u4e86\u586b\u5145\u503c\uff0c\u53ef\u4ee5\u5229\u7528\u6bcf\u4e2a\u5206\u7ec4\u90fd\u6709\u7684\u5185\u7f6e\u7684 name \u5c5e\u6027\uff0c\u5b9e\u73b0\u586b\u5145 NA \u3002 fill_value = {'East': 0.5, 'West': -1} fill_func = lambda g: g.fillna(fill_value[g.name]) result = s.groupby(group_key).apply(fill_func) print(result) # Ohio 100.0 # New York 110.0 # Vermont 0.5 # Florida 130.0 # Oregon 140.0 # Nevada -1.0 # California 160.0 # Idaho -1.0 # dtype: float64 \u793a\u4f8b\uff1a\u968f\u673a\u91c7\u6837\u4e0e\u6392\u5217 \u00b6 \u5047\u8bbe\u60f3\u4ece\u5927\u6570\u636e\u96c6\u4e2d\u62bd\u53d6\u968f\u673a\u6837\u672c\uff08\u6709\u6216\u6ca1\u6709\u66ff\u6362\uff09\u4ee5\u7528\u4e8e\u8499\u7279\u5361\u7f57\u6a21\u62df\u76ee\u7684\u6216\u67d0\u4e9b\u5176\u4ed6\u5e94\u7528\u7a0b\u5e8f\u3002 \u6709\u5f88\u591a\u65b9\u6cd5\u6765\u6267\u884c\u201c\u62bd\u53d6\u201d\uff0c\u8fd9\u91cc\u4f7f\u7528Series\u7684sample\u65b9\u6cd5\u3002 \u4e3a\u4e86\u6f14\u793a\uff0c\u8fd9\u91cc\u4ecb\u7ecd\u4e00\u79cd\u6784\u9020\u4e00\u526f\u82f1\u5f0f\u6251\u514b\u724c\u7684\u65b9\u6cd5\uff1a # \u6885\u82b1clubs\u3001\u65b9\u5757diamonds\u3001\u7ea2\u6843hearts\u3001\u9ed1\u6843spades\u3002 suits = ['H', 'S', 'C', 'D'] card_val = (list(range(1, 11)) + [10] * 3) * 4 # card_val [ # 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 10, 10, 10, # 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 10, 10, 10, # 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 10, 10, 10, # 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 10, 10, 10 # ] base_names = ['A'] + list(range(2, 11)) + ['J', 'K', 'Q'] # base_names\uff1a ['A', 2, 3, 4, 5, 6, 7, 8, 9, 10, 'J', 'K', 'Q'] \u751f\u6210\u4e86\u4e00\u4e2a\u957f\u5ea6\u4e3a 52 \u7684Series, Series\u7684\u7d22\u5f15\u5305\u542b\u4e86\u724c\u540d\uff0cSeries\u7684\u503c\u53ef\u4ee5\u7528\u6e38\u620f\uff08\u4e3a\u4e86\u4fdd\u6301\u7b80\u5355\uff0c\u8ba9\u2019A\u2019\u4e3a1 \uff09\uff1a cards = [] for suit in ['H', 'S', 'C', 'D']: cards.extend(str(num) + suit for num in base_names) deck = pd.Series(card_val, index=cards) print(deck) # AH 1 # 2H 2 # 3H 3 # 4H 4 # 5H 5 # 6H 6 # 7H 7 # 8H 8 # 9H 9 # 10H 10 # JH 10 # KH 10 # QH 10 # AS 1 # 2S 2 # 3S 3 # 4S 4 # 5S 5 # 6S 6 # 7S 7 # 8S 8 # 9S 9 # 10S 10 # JS 10 # KS 10 # QS 10 # AC 1 # 2C 2 # 3C 3 # 4C 4 # 5C 5 # 6C 6 # 7C 7 # 8C 8 # 9C 9 # 10C 10 # JC 10 # KC 10 # QC 10 # AD 1 # 2D 2 # 3D 3 # 4D 4 # 5D 5 # 6D 6 # 7D 7 # 8D 8 # 9D 9 # 10D 10 # JD 10 # KD 10 # QD 10 # dtype: int64 \u4ece\u8fd9\u526f\u724c\u4e2d\u62ff\u51fa\u4e94\u5f20\u724c\u53ef\u4ee5\u5199\u6210\uff1a def draw(_deck, n=5): return _deck.sample(n) print(draw(deck)) # KD 10 # 2S 2 # 5C 5 # 6C 6 # QD 10 # dtype: int64 \u5047\u8bbe\u8981\u4ece\u6bcf\u4e2a\u82b1\u8272\u4e2d\u968f\u673a\u62bd\u53d6\u4e24\u5f20\u724c\u3002\u7531\u4e8e\u82b1\u8272\u662f\u724c\u540d\u7684\u6700\u540e\u4e24\u4e2a\u5b57\u7b26\uff0c\u53ef\u4ee5\u57fa\u4e8e\u8fd9\u70b9\u8fdb\u884c\u5206\u7ec4\uff0c\u5e76\u4f7f\u7528 apply \uff1a get_suit = lambda card: card[-1] # \u6700\u540e\u4e00\u4e2a\u5b57\u6bcd\u662f\u82b1\u8272 result = deck.groupby(get_suit).apply(draw, n=2) print(result) # C 10C 10 # 3C 3 # D KD 10 # AD 1 # H 5H 5 # 7H 7 # S 3S 3 # 5S 5 # dtype: int64 \u6216\u8005\u4e5f\u53ef\u4ee5\u5199\u6210\uff1a result = deck.groupby(get_suit, group_keys=False).apply(draw, n=2) print(result) # JC 10 # 8C 8 # QD 10 # 4D 4 # 10H 10 # 6H 6 # 7S 7 # KS 10 # dtype: int64 \u793a\u4f8b\uff1a\u5206\u7ec4\u52a0\u6743\u5e73\u5747\u548c\u76f8\u5173\u6027 \u00b6 \u5728 groupby \u7684\u62c6\u5206-\u5e94\u7528-\u8054\u5408\u7684\u8303\u5f0f\u4e0b\uff0cDataFrame\u7684\u5217\u95f4\u64cd\u4f5c\u6216\u4e24\u4e2aSeriese\u4e4b\u95f4\u7684\u64cd\u4f5c\uff0c\u4f8b\u5982\u5b9e\u73b0\u5206\u7ec4\u52a0\u6743\u5e73\u5747\u3002 \u4e0b\u9762\u4f8b\u5b50\uff0c\u4f7f\u7528\u4e00\u4e2a\u5305\u542b\u5206\u7ec4\u952e\u548c\u6743\u91cd\u503c\u7684\u6570\u636e\u96c6\uff1a dt = np.random.randn(8) wt = np.random.randn(8) df = pd.DataFrame( { 'category': ['a', 'a', 'a', 'a', 'b', 'b', 'b', 'b'], 'data': dt, 'weight': wt } ) print(df) # category data weight # 0 a -0.250764 -0.085285 # 1 a 0.167155 -1.361254 # 2 a 0.399306 1.755542 # 3 a -0.514477 0.270124 # 4 b -0.005558 0.886514 # 5 b 0.607596 -1.384315 # 6 b -1.029627 -0.845340 # 7 b -0.294204 1.253965 \u901a\u8fc7 category \u8fdb\u884c\u5206\u7ec4\u52a0\u6743\u5e73\u5747\u5982\u4e0b\uff1a grouped = df.groupby('category') get_wavg = lambda g: np.average(g['data'], weights=g['weight']) result = grouped.apply(get_wavg) print(result) # category # a 0.614499 # b 3.863947 # dtype: float64 \u53e6\u4e00\u4e2a\u4f8b\u5b50\uff0c\u4e00\u4e2a\u4ece\u96c5\u864e\u8d22\u7ecf\u4e0a\u83b7\u5f97\u7684\u6570\u636e\u96c6\uff0c\u8be5\u6570\u636e\u96c6\u5305\u542b\u4e00\u4e9b\u6807\u666e500 \uff08SPX\u7b26\u53f7\uff09\u548c\u80a1\u7968\u7684\u6536\u76d8\u4ef7\uff1a close_px = pd.read_csv('../examples/stock_px_2.csv', parse_dates=True, index_col=0) print(close_px.info()) # # DatetimeIndex: 2214 entries, 2003-01-02 to 2011-10-14 # Data columns (total 4 columns): # # Column Non-Null Count Dtype # --- ------ -------------- ----- # 0 AAPL 2214 non-null float64 # 1 MSFT 2214 non-null float64 # 2 XOM 2214 non-null float64 # 3 SPX 2214 non-null float64 # dtypes: float64(4) # memory usage: 86.5 KB # None print(close_px[-4:]) # AAPL MSFT XOM SPX # 2011-10-11 400.29 27.00 76.27 1195.54 # 2011-10-12 402.19 26.96 77.16 1207.25 # 2011-10-13 408.43 27.18 76.37 1203.66 # 2011-10-14 422.00 27.27 78.11 1224.58 \u76ee\u6807\u4efb\u52a1\uff1a\u8ba1\u7b97\u4e00\u4e2aDataFrame\uff0c\u5b83\u5305\u542b\u6807\u666e\u6307\u6570\uff08SPX\uff09\u6bcf\u65e5\u6536\u76ca\u7684\u5e74\u5ea6\u76f8\u5173\u6027\uff08\u901a\u8fc7\u767e\u5206\u6bd4\u53d8\u5316\u8ba1\u7b97\uff09\u3002 \u9996\u5148\u521b\u5efa\u4e00\u4e2a\u8ba1\u7b97\u6bcf\u5217\u4e0e\u2019SPX\u2019\u5217\u6210\u5bf9\u5173\u8054\u7684\u51fd\u6570\uff1a spx_corr = lambda x: x.corrwith(x['SPX']) \u4e4b\u540e\uff0c\u4f7f\u7528 pct_change \u8ba1\u7b97 close-px \u767e\u5206\u6bd4\u7684\u53d8\u5316\uff1a rets = close_px.pct_change().dropna() # Percentage change between the current and a prior element. print(rets) # AAPL MSFT XOM SPX # 2003-01-03 0.006757 0.001421 0.000684 -0.000484 # 2003-01-06 0.000000 0.017975 0.024624 0.022474 # ... ... ... ... ... # 2011-10-14 0.033225 0.003311 0.022784 0.017380 # [2213 rows x 4 columns] \u6700\u540e\uff0c\u6309\u5e74\u5bf9\u767e\u5206\u6bd4\u53d8\u5316\u8fdb\u884c\u5206\u7ec4\uff0c\u53ef\u4ee5\u4f7f\u7528\u5355\u884c\u51fd\u6570\u4ece\u6bcf\u4e2a\u884c\u6807\u7b7e\u4e2d\u63d0\u53d6\u6bcf\u4e2a datetime \u6807\u7b7e\u7684 year \u5c5e\u6027\uff1a get_year = lambda x: x.year by_year = rets.groupby(get_year) result = by_year.apply(spx_corr) print(result) # AAPL MSFT XOM SPX # 2003 0.541124 0.745174 0.661265 1.0 # 2004 0.374283 0.588531 0.557742 1.0 # 2005 0.467540 0.562374 0.631010 1.0 # 2006 0.428267 0.406126 0.518514 1.0 # 2007 0.508118 0.658770 0.786264 1.0 # 2008 0.681434 0.804626 0.828303 1.0 # 2009 0.707103 0.654902 0.797921 1.0 # 2010 0.710105 0.730118 0.839057 1.0 # 2011 0.691931 0.800996 0.859975 1.0 \u53ef\u4ee5\u8ba1\u7b97\u5185\u90e8\u5217\u76f8\u5173\u6027\u3002\u8fd9\u91cc\u8ba1\u7b97\u4e86\u82f9\u679c\u548c\u5fae\u8f6f\u7684\u5e74\u5ea6\u76f8\u5173\u6027\uff1a result = by_year.apply(lambda g: g['AAPL'].corr(g['MSFT'])) print(result) # 2003 0.480868 # 2004 0.259024 # 2005 0.300093 # 2006 0.161735 # 2007 0.417738 # 2008 0.611901 # 2009 0.432738 # 2010 0.571946 # 2011 0.581987 # dtype: float64 \u793a\u4f8b\uff1a\u9010\u7ec4\u7ebf\u6027\u56de\u5f52 \u00b6 \u5b9a\u4e49\u4ee5\u4e0b regress \uff08\u56de\u5f52\uff09\u51fd\u6570\uff08\u4f7f\u7528 statsmodels \u8ba1\u91cf\u7ecf\u6d4e\u5b66\u5e93\uff09\uff0c\u8be5\u51fd\u6570\u5bf9\u6bcf\u4e2a\u6570\u636e\u5757\u6267\u884c\u666e\u901a\u6700\u5c0f\u4e8c\u4e58\uff08OLS\uff09\u56de\u5f52\uff1a def regress(data, yvar, xvars): Y = data[yvar] X = data[xvars] X['intercept'] = 1. result = sm.OLS(Y, X).fit() return result.params \u73b0\u5728\u8981\u8ba1\u7b97AAPL\u5728SPX\u56de\u62a5\u4e0a\u7684\u5e74\u5ea6\u7ebf\u6027\u56de\u5f52\uff1a result = by_year.apply(regress, 'AAPL', ['SPX']) print(result) # SPX intercept # 2003 1.195406 0.000710 # 2004 1.363463 0.004201 # 2005 1.766415 0.003246 # 2006 1.645496 0.000080 # 2007 1.198761 0.003438 # 2008 0.968016 -0.001110 # 2009 0.879103 0.002954 # 2010 1.052608 0.001261 # 2011 0.806605 0.001514 \u6570\u636e\u900f\u89c6\u8868\u4e0e\u4ea4\u53c9\u8868 \u00b6 \u6570\u636e\u900f\u89c6\u8868 \u00b6 \u6570\u636e\u900f\u89c6\u8868\u662f\u7535\u5b50\u8868\u683c\u7a0b\u5e8f\u548c\u5176\u4ed6\u6570\u636e\u5206\u6790\u8f6f\u4ef6\u4e2d\u5e38\u89c1\u7684\u6570\u636e\u6c47\u603b\u5de5\u5177\u3002 \u5b83\u6839\u636e\u4e00\u4e2a\u6216\u591a\u4e2a\u952e\u805a\u5408\u4e00\u5f20\u8868\u7684\u6570\u636e\uff0c\u5c06\u6570\u636e\u5728\u77e9\u5f62\u683c\u5f0f\u4e2d\u6392\u5217\uff0c\u5176\u4e2d\u4e00\u4e9b\u5206\u7ec4\u952e\u662f\u6cbf\u7740\u884c\u7684\uff0c\u53e6\u4e00\u4e9b\u662f\u6cbf\u7740\u5217\u7684\u3002 Python\u4e2d\u7684pandas\u900f\u89c6\u8868\u662f\u901a\u8fc7\u8fd9\u91cc\u6240\u4ecb\u7ecd\u7684groupby\u5de5\u5177\u4ee5\u53ca\u4f7f\u7528\u5206\u5c42\u7d22\u5f15\u7684\u91cd\u5851\u64cd\u4f5c\u5b9e\u73b0\u7684\u3002 DataFrame\u62e5\u6709\u4e00\u4e2a pivot_table \u65b9\u6cd5\uff0c\u5e76\u4e14\u8fd8\u6709\u8fd8\u4e00\u4e2a\u9876\u5c42\u7684 pandas.pivot_table \u51fd\u6570\u3002 \u9664\u4e86\u4e3a groupby \u63d0\u4f9b\u4e00\u4e2a\u65b9\u4fbf\u63a5\u53e3\uff0c pivot_table \u8fd8\u53ef\u4ee5\u6dfb\u52a0\u90e8\u5206\u603b\u8ba1\uff0c\u4e5f\u79f0\u4f5c\u8fb9\u8ddd\u3002 import pandas as pd import numpy as np \u6839\u636e\u4e0b\u9762\u7684\u5c0f\u8d39\u6570\u636e\u96c6\uff0c\u8ba1\u7b97\u4e00\u5f20\u5728\u884c\u65b9\u5411\u4e0a\u6309 day \u548c smoker \u6392\u5217\u7684\u5206\u7ec4\u5e73\u5747\u503c\uff08\u9ed8\u8ba4\u7684 pivot_table \u805a\u5408\u7c7b\u578b\uff09\u7684\u8868\u3002 pivot_table \u9009\u9879\uff1a values: \u9700\u8981\u805a\u5408\u7684\u5217\u540d\uff0c\u9ed8\u8ba4\u60c5\u51b5\u4e0b\u805a\u5408\u6240\u6709\u6570\u503c\u578b\u7684\u5217\u3002 index: \u5728\u7ed3\u679c\u900f\u89c6\u8868\u7684\u884c\u4e0a\u8fdb\u884c\u5206\u7ec4\u7684\u5217\u540d\u6216\u8005\u5176\u4ed6\u5206\u7ec4\u952e\u3002 tips = pd.read_csv('../examples/tips.csv') tips['tip_pct'] = tips['tip'] / (tips['total_bill'] - tips['tip']) \u6837\u672c\u6570\u636e\u3002 print(tips.head(5)) # total_bill tip smoker day time size tip_pct # 0 16.99 1.01 No Sun Dinner 2 0.063204 # 1 10.34 1.66 No Sun Dinner 3 0.191244 # 2 21.01 3.50 No Sun Dinner 3 0.199886 # 3 23.68 3.31 No Sun Dinner 2 0.162494 # 4 24.59 3.61 No Sun Dinner 4 0.172069 \u8ba1\u7b97\u5728\u884c\u65b9\u5411\u4e0a\u6309 day \u548c smoker \u6392\u5217\u7684\u5206\u7ec4\u5e73\u5747\u503c\u3002\u4e5f\u53ef\u4ee5\u76f4\u63a5\u4f7f\u7528 groupby \u5b9e\u73b0\u3002 result = tips.pivot_table(index=['day', 'smoker']) print(result) # size tip tip_pct total_bill # day smoker # Fri No 2.250000 2.812500 0.179740 18.420000 # Yes 2.066667 2.714000 0.216293 16.813333 # Sat No 2.555556 3.102889 0.190412 19.661778 # Yes 2.476190 2.875476 0.179833 21.276667 # Sun No 2.929825 3.167895 0.193617 20.506667 # Yes 2.578947 3.516842 0.322021 24.120000 # Thur No 2.488889 2.673778 0.193424 17.113111 # Yes 2.352941 3.030000 0.198508 19.190588 \u5728 tip_pct \u548c size \u4e0a\u8fdb\u884c\u805a\u5408\uff0c\u5e76\u6839\u636e time \u5206\u7ec4\u3002\u5c06\u628a smoker \u653e\u5165\u8868\u7684\u5217\uff0c\u800c\u5c06 day \u653e\u5165\u8868\u7684\u884c\uff1a result = tips.pivot_table( ['tip_pct', 'size'], index=['time', 'day'], columns='smoker' ) print(result) # size tip_pct # smoker No Yes No Yes # time day # Dinner Fri 2.000000 2.222222 0.162612 0.202545 # Sat 2.555556 2.476190 0.190412 0.179833 # Sun 2.929825 2.578947 0.193617 0.322021 # Thur 2.000000 NaN 0.190114 NaN # Lunch Fri 3.000000 1.833333 0.231125 0.236915 # Thur 2.500000 2.352941 0.193499 0.198508 \u901a\u8fc7\u4f20\u9012 margins=True \u6765\u6269\u5145\u8fd9\u4e2a\u8868\u6765\u5305\u542b\u90e8\u5206\u603b\u8ba1\u3002\u8fd9\u4f1a\u6dfb\u52a0 All \u884c\u548c\u5217\u6807\u7b7e\uff0c\u5176\u4e2d\u76f8\u5e94\u7684\u503c\u662f\u5355\u5c42\u4e2d\u6240\u6709\u6570\u636e\u7684\u5206\u7ec4\u7edf\u8ba1\u503c\u3002 \u8fd9\u91cc All \u7684\u503c\u662f\u5747\u503c\uff0c\u4e14\u8be5\u5747\u503c\u662f\u4e0d\u8003\u8651\u5438\u70df\u8005\u4e0e\u975e\u5438\u70df\u8005\uff08 All \u5217\uff09\u6216\u884c\u5206\u7ec4\u4e2d\u4efb\u4f55\u4e24\u7ea7\u7684\uff08 All \u884c\uff09\u3002 result = tips.pivot_table( ['tip_pct', 'size'], index=['time', 'day'], columns='smoker', margins=True ) print(result) # size tip_pct # smoker No Yes All No Yes All # time day # Dinner Fri 2.000000 2.222222 2.166667 0.162612 0.202545 0.192562 # Sat 2.555556 2.476190 2.517241 0.190412 0.179833 0.185305 # Sun 2.929825 2.578947 2.842105 0.193617 0.322021 0.225718 # Thur 2.000000 NaN 2.000000 0.190114 NaN 0.190114 # Lunch Fri 3.000000 1.833333 2.000000 0.231125 0.236915 0.236088 # Thur 2.500000 2.352941 2.459016 0.193499 0.198508 0.194895 # All 2.668874 2.408602 2.569672 0.192237 0.218176 0.202123 \u8981\u4f7f\u7528\u4e0d\u540c\u7684\u805a\u5408\u51fd\u6570\u65f6\uff0c\u5c06\u51fd\u6570\u4f20\u9012\u7ed9 aggfunc \u3002\u4f8b\u5982\uff0c count \u6216\u8005 len \u5c06\u7ed9\u51fa\u4e00\u5f20\u5206\u7ec4\u5927\u5c0f\u7684\u4ea4\u53c9\u8868\uff08\u8ba1\u6570\u6216\u51fa\u73b0\u9891\u7387\uff09\uff1a result = tips.pivot_table( ['tip_pct', 'size'], index=['time', 'day'], columns='smoker', aggfunc=len, margins=True ) print(result) # size tip_pct # smoker No Yes All No Yes All # time day # Dinner Fri 3.0 9.0 12 3.0 9.0 12 # Sat 45.0 42.0 87 45.0 42.0 87 # Sun 57.0 19.0 76 57.0 19.0 76 # Thur 1.0 NaN 1 1.0 NaN 1 # Lunch Fri 1.0 6.0 7 1.0 6.0 7 # Thur 44.0 17.0 61 44.0 17.0 61 # All 151.0 93.0 244 151.0 93.0 244 \u5bf9\u4e8e\u7a7a\u503c NA \uff0c\u4f20\u9012\u4e00\u4e2a fill_value \u3002 result = tips.pivot_table( ['tip_pct', 'size'], index=['time', 'day'], columns='smoker', aggfunc='mean', fill_value=0, margins=True ) print(result) # size tip_pct # smoker No Yes All No Yes All # time day # Dinner Fri 2.000000 2.222222 2.166667 0.162612 0.202545 0.192562 # Sat 2.555556 2.476190 2.517241 0.190412 0.179833 0.185305 # Sun 2.929825 2.578947 2.842105 0.193617 0.322021 0.225718 # Thur 2.000000 0.000000 2.000000 0.190114 0.000000 0.190114 # Lunch Fri 3.000000 1.833333 2.000000 0.231125 0.236915 0.236088 # Thur 2.500000 2.352941 2.459016 0.193499 0.198508 0.194895 # All 2.668874 2.408602 2.569672 0.192237 0.218176 0.202123 \u4ea4\u53c9\u8868\uff1acrosstab \u00b6 \u4ea4\u53c9\u8868\uff08\u7b80\u5199\u4e3acrosstab\uff09\u662f\u6570\u636e\u900f\u89c6\u8868\u7684\u4e00\u4e2a\u7279\u6b8a\u60c5\u51b5\uff0c\u8ba1\u7b97\u7684\u662f\u5206\u7ec4\u4e2d\u7684\u9891\u7387\u3002 crosstab \u7684\u524d\u4e24\u4e2a\u53c2\u6570\u53ef\u662f\u6570\u7ec4\u3001Series\u6216\u6570\u7ec4\u7684\u5217\u8868\u3002 sample = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10] nationality = ['USA', 'Japan', 'USA', 'Japan', 'Japan', 'Japan', 'USA', 'USA', 'Japan', 'USA'] handedness = ['Right-handed', 'Left-handed', 'Right-handed', 'Right-handed', 'Left-handed', 'Right-handed', 'Right-handed', 'Left-handed', 'Right-handed', 'Right-handed'] df = pd.DataFrame( { 'sample': sample, 'nationality': nationality, 'handedness': handedness } ) print(df) # sample nationality handedness # 0 1 USA Right-handed # 1 2 Japan Left-handed # 2 3 USA Right-handed # 3 4 Japan Right-handed # 4 5 Japan Left-handed # 5 6 Japan Right-handed # 6 7 USA Right-handed # 7 8 USA Left-handed # 8 9 Japan Right-handed # 9 10 USA Right-handed \u6309\u7167\u56fd\u7c4d\u548c\u60ef\u7528\u6027\u6765\u603b\u7ed3\u8fd9\u4e9b\u6570\u636e\uff0c\u53ef\u4ee5\u4f7f\u7528 pivot_table \u6765\u5b9e\u73b0\u8fd9\u4e2a\u529f\u80fd\uff0c\u4f46\u662f pandas.crosstable \u51fd\u6570\u66f4\u4e3a\u65b9\u4fbf\uff1a result = pd.crosstab(df.nationality, df.handedness, margins=True) print(result) # handedness Left-handed Right-handed All # nationality # Japan 2 3 5 # USA 1 4 5 # All 3 7 10 \u5728\u5c0f\u8d39\u6570\u636e\u4e2d\u53ef\u4ee5\u8fd9\u4e48\u505a\uff1a result = pd.crosstab(['tips.time', tips.day], tips.smoker, margins=True) print(result) # smoker No Yes All # row_0 day # tips.time Fri 4 15 19 # Sat 45 42 87 # Sun 57 19 76 # Thur 45 17 62 # All 151 93 244","title":"\u6570\u636e\u805a\u5408\u4e0e\u5206\u7ec4\u64cd\u4f5c"},{"location":"python/DataAnalysis/ch07/#_1","text":"","title":"\u6570\u636e\u805a\u5408\u4e0e\u5206\u7ec4\u64cd\u4f5c"},{"location":"python/DataAnalysis/ch07/#groupby","text":"import pandas as pd import numpy as np","title":"GroupBy\u673a\u5236"},{"location":"python/DataAnalysis/ch07/#_2","text":"\u5206\u7ec4\u64cd\u4f5c\u7b2c\u4e00\u6b65\uff0c\u6570\u636e\u5305\u542b\u5728pandas\u5bf9\u8c61\u4e2d\uff0c\u53ef\u4ee5\u662fSeries\u3001DataFrame\u6216\u5176\u4ed6\u6570\u636e\u7ed3\u6784\u3002\u4e4b\u540e\u6839\u636e\u63d0\u4f9b\u7684\u4e00\u4e2a\u6216\u591a\u4e2a\u952e\u5206\u79bb\u5230\u5404\u4e2a\u7ec4\u4e2d\u3002 \u5206\u7ec4\u952e\u53ef\u662f\u591a\u79cd\u5f62\u5f0f\u7684\uff0c\u5e76\u4e14\u952e\u4e0d\u4e00\u5b9a\u662f\u5b8c\u5168\u76f8\u540c\u7684\u7c7b\u578b(\u6ce8\u610f\u540e\u9762\u4ecb\u7ecd\u7684\u4e09\u4e2a\u65b9\u6cd5\u662f\u53ef\u4ee5\u4ea7\u751f\u7528\u4e8e\u5206\u9694\u5bf9\u8c61\u7684\u503c\u6570\u7ec4\u7684\u5feb\u6377\u65b9\u5f0f)\uff1a \u4e0e\u9700\u8981\u5206\u7ec4\u7684\u8f74\u5411\u957f\u5ea6\u4e00\u81f4\u7684\u503c\u5217\u8868\u6216\u503c\u6570\u7ec4\u3002\u9ed8\u8ba4\u60c5\u51b5\u4e0b\uff0cgroupby\u5728axis=0\u7684\u8f74\u5411\u4e0a\u5206\u7ec4\u3002 DataFrame\u7684\u5217\u540d\u7684\u503c\u3002 \u53ef\u4ee5\u5c06\u5206\u7ec4\u8f74\u5411\u4e0a\u7684\u503c\u548c\u5206\u7ec4\u540d\u79f0\u76f8\u5339\u914d\u7684\u5b57\u5178\u6216Series\u3002 \u53ef\u4ee5\u5728\u8f74\u7d22\u5f15\u6216\u7d22\u5f15\u4e2d\u7684\u5355\u4e2a\u6807\u7b7e\u4e0a\u8c03\u7528\u7684\u51fd\u6570\u3002 \u8bf7\u6ce8\u610f\uff0c\u5206\u7ec4\u952e\u4e2d\u7684\u4efb\u4f55\u7f3a\u5931\u503c\u5c06\u88ab\u6392\u9664\u5728\u7ed3\u679c\u4e4b\u5916\u3002 \u5206\u79bb\u64cd\u4f5c\u662f\u5728\u6570\u636e\u5bf9\u8c61\u7684\u7279\u5b9a\u8f74\u5411\u4e0a\u8fdb\u884c\u7684\u3002\u4f8b\u5982\uff0cDataFrame\u53ef\u4ee5\u5728\u5b83\u7684\u884c\u65b9\u5411\uff08axis=0\uff09\u6216\u5217\u65b9\u5411\uff08axis=1\uff09\u8fdb\u884c\u5206\u7ec4\u3002 \u5206\u7ec4\u64cd\u4f5c\u540e\uff0c\u4e00\u4e2a\u51fd\u6570\u5c31\u53ef\u4ee5\u5e94\u7528\u5230\u5404\u4e2a\u7ec4\u4e2d\uff0c\u4ea7\u751f\u65b0\u7684\u503c\u3002\u6700\u7ec8\uff0c\u6240\u6709\u51fd\u6570\u7684\u5e94\u7528\u7ed3\u679c\u4f1a\u8054\u5408\u4e3a\u4e00\u4e2a\u7ed3\u679c\u5bf9\u8c61\u3002 df = pd.DataFrame( { 'key1': ['a', 'a', 'b', 'b', 'a'], 'key2': ['one', 'two', 'one', 'two', 'one'], 'data1': [1, 3, 5, 7, 9], 'data2': [2, 4, 6, 8, 10] } ) \u6839\u636ekey1\u6807\u7b7e\u8ba1\u7b97data1\u5217\u7684\u5747\u503c\uff0c\u65b9\u6cd5\u4e00\uff0c\u8bbf\u95ee data1 \u5e76\u4f7f\u7528 key1 \u5217\uff08\u5b83\u662f\u4e00\u4e2aSeries\uff09\u8c03\u7528 groupby \u65b9\u6cd5\uff1a grouped = df['data1'].groupby(df['key1']) print(grouped) # grouped \u53d8\u91cf\u73b0\u5728\u662f\u4e00\u4e2a GroupBy \u5bf9\u8c61\uff0c\u5b83\u5b9e\u9645\u4e0a\u8fd8\u6ca1\u6709\u8fdb\u884c\u4efb\u4f55\u8ba1\u7b97\uff0c\u62e5\u6709\u4e00\u4e9b\u5173\u4e8e\u5206\u7ec4\u952edf['key1']\u7684\u4e00\u4e9b\u4e2d\u95f4\u6570\u636e\u7684\u4fe1\u606f\u3002 \u4e0b\u9762\u5bf9 grouped \u5bf9\u8c61\u505a\u4e00\u4e9b\u64cd\u4f5c\uff1a result = grouped.mean() # \u8ba1\u7b97\u5e73\u5747\u503c print(result) # key1 # a 4.333333 # b 6.000000 # Name: data1, dtype: float64 grouped_means = df['data1'].groupby([df['key1'], df['key2']]).mean() print(grouped_means) # key1 key2 # a one 5.0 # two 3.0 # b one 5.0 # two 7.0 # Name: data1, dtype: float64 \u4e0a\u9762\u4f8b\u5b50\u4f7f\u7528\u4e86\u4e24\u4e2a\u952e\u5bf9\u6570\u636e\u8fdb\u884c\u5206\u7ec4\uff0c\u5e76\u4e14\u7ed3\u679cSeries\u73b0\u5728\u62e5\u6709\u4e00\u4e2a\u5305\u542b\u552f\u4e00\u952e\u5bf9\u7684\u591a\u5c42\u7d22\u5f15\u3002 \u4e0b\u9762\u5bf9\u8ba1\u7b97\u7684\u5e73\u5747\u503c\uff08mean\uff09\u8fdb\u884c\u91cd\u5851\uff08unstack\uff09\u3002 print(grouped_means.unstack()) # key2 one two # key1 # a 5.0 3.0 # b 5.0 7.0 \u5206\u7ec4\u4fe1\u606f\u901a\u5e38\u5305\u542b\u5728\u540c\u4e00\u4e2aDataFrame\u4e2d\u3002\u5728\u8fd9\u79cd\u60c5\u51b5\u4e0b\uff0c\u53ef\u4ee5\u4f20\u9012\u5217\u540d\uff08\u65e0\u8bba\u90a3\u4e9b\u5217\u540d\u662f\u5b57\u7b26\u4e32\u3001\u6570\u5b57\u6216\u5176\u4ed6Python\u5bf9\u8c61\uff09\u4f5c\u4e3a\u5206\u7ec4\u952e\uff1a \u4e0b\u9762\u4f8b\u5b50\u4e2d df.groupby('key1').mean() \u7684\u7ed3\u679c\u91cc\u5e76\u6ca1\u6709 key2 \u5217\u3002\u8fd9\u662f\u56e0\u4e3a df['key2'] \u5e76\u4e0d\u662f\u6570\u503c\u6570\u636e\uff0c\u5373 df['key2'] \u662f\u4e00\u4e2a\u5197\u4f59\u5217\uff0c\u56e0\u6b64\u88ab\u6392\u9664\u5728\u7ed3\u679c\u4e4b\u5916\u3002 result = df.groupby('key1').mean() print(result) # data1 data2 # key1 # a 4.333333 5.333333 # b 6.000000 7.000000 result = df.groupby(['key1', 'key2']).mean() print(result) # data1 data2 # key1 key2 # a one 5.0 6.0 # two 3.0 4.0 # b one 5.0 6.0 # two 7.0 8.0 result = df.groupby(['key1', 'key2']).size() print(result) # key1 key # a one 2 # two 1 # b one 1 # two 1 # dtype: int64","title":"\u5206\u7ec4\u673a\u5236"},{"location":"python/DataAnalysis/ch07/#_3","text":"GroupBy \u5bf9\u8c61\u652f\u6301\u8fed\u4ee3\uff0c\u4f1a\u751f\u6210\u4e00\u4e2a\u5305\u542b\u7ec4\u540d\u548c\u6570\u636e\u5757\u76842\u7ef4\u5143\u7ec4\u5e8f\u5217\u3002 df = pd.DataFrame( { 'key1': ['a', 'a', 'b', 'b', 'a'], 'key2': ['one', 'two', 'one', 'two', 'one'], 'data1': [1, 3, 5, 7, 9], 'data2': [2, 4, 6, 8, 10] } ) \u5355\u4e2a\u5206\u7ec4\u952e\u7684\u60c5\u51b5: for name, group in df.groupby('key1'): print(name) print(group) # a # key1 key2 data1 data2 # 0 a one 1 2 # 1 a two 3 4 # 4 a one 9 10 # b # key1 key2 data1 data2 # 2 b one 5 6 # 3 b two 7 8 \u591a\u4e2a\u5206\u7ec4\u952e\u7684\u60c5\u51b5: \u5143\u7ec4\u4e2d\u7684\u7b2c\u4e00\u4e2a\u5143\u7d20\u662f\u952e\u503c\u7684\u5143\u7ec4\u3002 for (k1, k2), group in df.groupby(['key1', 'key2']): print((k1, k2)) print(group) # ('a', 'one') # key1 key2 data1 data2 # 0 a one 1 2 # 4 a one 9 10 # ('a', 'two') # key1 key2 data1 data2 # 1 a two 3 4 # ('b', 'one') # key1 key2 data1 data2 # 2 b one 5 6 # ('b', 'two') # key1 key2 data1 data2 # 3 b two 7 8 result = dict(list(df.groupby('key1'))) print(result) # df.groupby('key1')\u7684\u7ed3\u679c\u662f\u4e00\u4e2a\u5bf9\u8c61 # # list(df.groupby('key1'))\u7684\u7ed3\u679c\u662f\u5305\u542bFrameData\u7684\u7ed3\u6784\u7684\u5217\u8868list: # [ # ('a', key1 key2 data1 data2 # 0 a one 1 2 # 1 a two 3 4 # 4 a one 9 10), # ('b', key1 key2 data1 data2 # 2 b one 5 6 # 3 b two 7 8) # ] # dict(list(df.groupby('key1')))\u7684\u7ed3\u679c\u662f\u5305\u542bFrameData\u7684\u7ed3\u6784\u7684\u5b57\u5178dict # { # 'a': key1 key2 data1 data2 # 0 a one 1 2 # 1 a two 3 4 # 4 a one 9 10, # 'b': key1 key2 data1 data2 # 2 b one 5 6 # 3 b two 7 8 # } print(result['b']) # key1 key2 data1 data2 # 2 b one 5 6 # 3 b two 7 8 \u9ed8\u8ba4\u60c5\u51b5\u4e0b\uff0c groupby \u5728 axis=0 \u7684\u8f74\u5411\u4e0a\u5206\u7ec4\uff0c\u4e5f\u53ef\u4ee5\u5728\u5176\u4ed6\u4efb\u610f\u8f74\u5411\u4e0a\u8fdb\u884c\u5206\u7ec4\u3002 print(df.dtypes) # key1 object # key2 object # data1 int64 # data2 int64 # dtype: object grouped = df.groupby(df.dtypes, axis=1) print(grouped) # print(list(grouped)) # [ # (dtype('int64'), data1 data2 # 0 1 2 # 1 3 4 # 2 5 6 # 3 7 8 # 4 9 10), # (dtype('O'), key1 key2 # 0 a one # 1 a two # 2 b one # 3 b two # 4 a one) # ] \u6253\u5370\u5404\u5206\u7ec4\u5982\u4e0b\uff1a for dtype, group in grouped: print(dtype) print(group) # int64 # data1 data2 # 0 1 2 # 1 3 4 # 2 5 6 # 3 7 8 # 4 9 10 # object # key1 key2 # 0 a one # 1 a two # 2 b one # 3 b two # 4 a one","title":"\u904d\u5386\u5404\u5206\u7ec4"},{"location":"python/DataAnalysis/ch07/#_4","text":"\u5bf9\u4e8e\u4eceDataFrame\u521b\u5efa\u7684 GroupBy \u5bf9\u8c61\uff0c\u7528\u5217\u540d\u79f0\u6216\u5217\u540d\u79f0\u6570\u7ec4\u8fdb\u884c\u7d22\u5f15\u65f6\uff0c\u4f1a\u4ea7\u751f\u7528\u4e8e\u805a\u5408\u7684\u5217\u5b50\u96c6\u7684\u6548\u679c\u3002 \u5982\u679c\u4f20\u9012\u7684\u662f\u5217\u8868\u6216\u6570\u7ec4\uff0c\u5219\u6b64\u7d22\u5f15\u64cd\u4f5c\u8fd4\u56de\u7684\u5bf9\u8c61\u662f\u5206\u7ec4\u7684DataFrame\uff1b\u5982\u679c\u53ea\u6709\u5355\u4e2a\u5217\u540d\u4f5c\u4e3a\u6807\u91cf\u4f20\u9012\uff0c\u5219\u4e3a\u5206\u7ec4\u7684Series\uff1b \u5bf9\u6bd4\u4e0b\u97624\u53e5\uff1a result = df.groupby('key1')['data1'] # \u5355\u4e2a\u5217\u540d print(result) # for key, data in result: print(key) print(data) result = df['data1'].groupby(df['key1']) # \u5355\u4e2a\u5217\u540d print(result) # for key, data in result: print(key) print(data) # a # 0 1 # 1 3 # 4 9 # Name: data1, dtype: int64 # b # 2 5 # 3 7 # Name: data1, dtype: int64 result = df.groupby('key1')[['data1']] # \u5217\u8868\u6216\u6570\u7ec4 print(result) # for key, data in result: print(key) print(data) # a # key1 key2 data1 data2 # 0 a one 1 2 # 1 a two 3 4 # 4 a one 9 10 # b # key1 key2 data1 data2 # 2 b one 5 6 # 3 b two 7 8 result = df[['data1']].groupby(df['key1']) # \u5217\u8868\u6216\u6570\u7ec4 print(result) # for key, data in result: print(key) print(data) # a # data1 # 0 1 # 1 3 # 4 9 # b # data1 # 2 5 # 3 7","title":"\u9009\u62e9\u4e00\u5217\u6216\u6240\u6709\u5217\u7684\u5b50\u96c6"},{"location":"python/DataAnalysis/ch07/#series","text":"\u5206\u7ec4\u4fe1\u606f\u53ef\u80fd\u4f1a\u4ee5\u975e\u6570\u7ec4\u5f62\u5f0f\u5b58\u5728\u3002 \u751f\u6210\u4e00\u4e2a\u793a\u4f8bDataFrame\u3002 people = pd.DataFrame( [[1, 3, 5, 7, 9], [0, 2, 4, 6, 8], [0, 2, 4, 6, 8], [1, 3, 5, 7, 9], [1, 2, 3, 4, 5]], columns=['a', 'b', 'c', 'd', 'e'], index=['Joe', 'Steve', 'Wes', 'Jim', 'Travis'] ) \u6dfb\u52a0\u4e00\u4e9bNA\u503c\u3002 people.iloc[2:3, [1, 2]] = np.nan print(people) # a b c d e # Joe 1 3.0 5.0 7 9 # Steve 0 2.0 4.0 6 8 # Wes 0 NaN NaN 6 8 # Jim 1 3.0 5.0 7 9 # Travis 1 2.0 3.0 4 5 \u5047\u8bbe\u6709\u5982\u4e0b\u5404\u5217\u7684\u5206\u7ec4\u5bf9\u5e94\u5173\u7cfb\uff0c\u5e76\u4e14\u60f3\u628a\u5404\u5217\u6309\u7ec4\u7d2f\u52a0\u3002 mapping = { 'a': 'red', 'b': 'red', 'c': 'blue', 'd': 'blue', 'e': 'red', 'f': 'orange' # \u6ce8\u610f\uff1a\u5065f\u867d\u7136\u6ca1\u6709\u88ab\u7528\u5230\uff0c\u4f46\u4e0d\u5f71\u54cd\u5728\u8fd9\u91cc\u5b9a\u4e49\u3002 } \u628a mapping \u8fd9\u4e2a\u5b57\u5178\u4f20\u7ed9 groupby() \u3002 by_column = people.groupby(mapping, axis=1) print(by_column.sum()) # blue red # Joe 12.0 13.0 # Steve 10.0 10.0 # Wes 6.0 8.0 # Jim 12.0 13.0 # Travis 7.0 8.0 Series\u4e5f\u6709\u76f8\u540c\u7684\u529f\u80fd\uff0c\u53ef\u4ee5\u89c6\u4e3a\u56fa\u5b9a\u5927\u5c0f\u7684\u6620\u5c04\u3002 map_services = pd.Series(mapping) print(map_services) # a red # b red # c blue # d blue # e red # f orange # dtype: object result = people.groupby(map_services, axis=1).count() print(result) # blue red # Joe 2 3 # Steve 2 3 # Wes 1 2 # Jim 2 3 # Travis 2 3","title":"\u4f7f\u7528\u5b57\u5178\u548cSeries\u5206\u7ec4"},{"location":"python/DataAnalysis/ch07/#_5","text":"\u4e0e\u4f7f\u7528\u5b57\u5178\u6216Series\u5206\u7ec4\u76f8\u6bd4\uff0c\u4f7f\u7528Python\u51fd\u6570\u662f\u5b9a\u4e49\u5206\u7ec4\u5173\u7cfb\u7684\u4e00\u79cd\u66f4\u4e3a\u901a\u7528\u7684\u65b9\u5f0f\u3002 \u4f5c\u4e3a\u5206\u7ec4\u952e\u4f20\u9012\u7684\u51fd\u6570\u5c06\u4f1a\u6309\u7167\u6bcf\u4e2a\u7d22\u5f15\u503c\u8c03\u7528\u4e00\u6b21\uff0c\u540c\u65f6\u8fd4\u56de\u503c\u4f1a\u88ab\u7528\u4f5c\u5206\u7ec4\u540d\u79f0\u3002\u6ce8\u610f\uff1a\u51fd\u6570\u662f\u4f5c\u7528\u5728\u7d22\u5f15\u4e0a\u3002 result = people.groupby(len).sum() # \u4eba\u7684\u540d\u5b57\u662f\u7d22\u5f15\u503c\uff0c\u6839\u636e\u540d\u5b57\u7684\u957f\u5ea6\u6765\u8fdb\u884c\u5206\u7ec4 print(result) # a b c d e # 3 2 6.0 10.0 20 26 # 5 0 2.0 4.0 6 8 # 6 1 2.0 3.0 4 5 \u53ef\u4ee5\u5c06\u51fd\u6570\u4e0e\u6570\u7ec4\u3001\u5b57\u5178\u6216Series\u8fdb\u884c\u6df7\u5408\uff0c\u6240\u6709\u7684\u5bf9\u8c61\u90fd\u4f1a\u5728\u5185\u90e8\u8f6c\u6362\u4e3a\u6570\u7ec4\u3002 key_list = ['one', 'one', 'one', 'two', 'two'] result = people.groupby([len, key_list]).min() print(result) # a b c d e # 3 one 0 3.0 5.0 6 8 # two 1 3.0 5.0 7 9 # 5 one 0 2.0 4.0 6 8 # 6 two 1 2.0 3.0 4 5","title":"\u4f7f\u7528\u51fd\u6570\u5206\u7ec4"},{"location":"python/DataAnalysis/ch07/#_6","text":"\u6839\u636e\u5c42\u7ea7\u5206\u7ec4\u65f6\uff0c\u5c06\u5c42\u7ea7\u6570\u503c\u6216\u5c42\u7ea7\u540d\u79f0\u4f20\u9012\u7ed9 level \u5173\u952e\u5b57\u3002 columns = pd.MultiIndex.from_arrays( [['US', 'US', 'US', 'JP', 'JP'], [1, 3, 5, 1, 3]], names=['cty', 'tenor'] ) hier_df = pd.DataFrame( [[1, 3, 5, 7, 9], [0, 2, 4, 6, 8], [1, 3, 5, 7, 9], [1, 2, 3, 4, 5]], columns=columns ) print(hier_df) # cty US JP # tenor 1 3 5 1 3 # 0 1 3 5 7 9 # 1 0 2 4 6 8 # 2 1 3 5 7 9 # 3 1 2 3 4 5 result = hier_df.groupby(level='cty', axis=1).count() print(result) # cty JP US # 0 2 3 # 1 2 3 # 2 2 3 # 3 2 3","title":"\u6839\u636e\u7d22\u5f15\u5c42\u7ea7\u5206\u7ec4"},{"location":"python/DataAnalysis/ch07/#_7","text":"\u805a\u5408\u662f\u6307\u6240\u6709\u6839\u636e\u6570\u7ec4\u4ea7\u751f\u6807\u91cf\u503c\u7684\u6570\u636e\u8f6c\u6362\u8fc7\u7a0b\uff0c\u6bd4\u5982\uff1a mean \u3001 count \u3001 min \u548c sum \u7b49\u4e00\u4e9b\u805a\u5408\u64cd\u4f5c\u3002 import pandas as pd import numpy as np \u9884\u5907\u77e5\u8bc6\uff1a \u5206\u4f4d\u6570\uff08Quantile\uff09\uff0c\u4e5f\u79f0\u5206\u4f4d\u70b9\uff0c\u662f\u6307\u5c06\u4e00\u4e2a\u968f\u673a\u53d8\u91cf\u7684\u6982\u7387\u5206\u5e03\u8303\u56f4\u5206\u4e3a\u51e0\u4e2a\u7b49\u4efd\u7684\u6570\u503c\u70b9\uff0c\u5206\u6790\u5176\u6570\u636e\u53d8\u91cf\u7684\u8d8b\u52bf\u3002 \u5e38\u7528\u7684\u5206\u4f4d\u6570\u6709 \u4e2d\u4f4d\u6570\u3001\u56db\u5206\u4f4d\u6570\u3001\u767e\u5206\u4f4d\u6570\u7b49\u3002 \u4e2d\u4f4d\u6570\uff08Medians\uff09\u662f\u4e00\u4e2a\u7edf\u8ba1\u5b66\u7684\u4e13\u6709\u540d\u8bcd\uff0c\u4ee3\u8868\u4e00\u4e2a\u6837\u672c\u3001\u79cd\u7fa4\u6216\u6982\u7387\u5206\u5e03\u4e2d\u7684\u4e00\u4e2a\u6570\u503c\uff0c\u53ef\u4ee5\u5c06\u6570\u503c\u96c6\u5408\u5212\u5206\u4e3a\u76f8\u7b49\u7684\u4e24\u90e8\u5206\u3002 \u5229\u7528pandas\u5e93\u8ba1\u7b97 data = [6, 47, 49, 15, 42, 41, 7, 39, 43, 40, 36] \u7684\u5206\u4f4d\u6570\u3002 \u786e\u5b9a p \u5206\u4f4d\u6570\u4f4d\u7f6e\u7684\u4e24\u79cd\u65b9\u6cd5( n \u4e3a\u6570\u636e\u7684\u603b\u4e2a\u6570\uff0c p \u4e3a 0-1 \u4e4b\u95f4\u7684\u503c)\u3002\u5728python\u4e2d\u8ba1\u7b97\u5206\u4f4d\u6570\u4f4d\u7f6e\u7684\u65b9\u6848\u91c7\u7528 position=1+(n-1)*p \uff1a position = (n+1)*p position = 1 + (n-1)*p \u6848\u4f8b1 data = pd.Series(np.array([6, 47, 49, 15, 42, 41, 7, 39, 43, 40, 36])) print(\"\u6570\u636e\u683c\u5f0f\uff1a\") print(np.sort(data)) # \u5fc5\u987b\u8981\u6392\u5e8f print('Q1:', data.quantile(.25)) print('Q2:', data.quantile(.5)) print('Q3:', data.quantile(.75)) # \u6570\u636e\u683c\u5f0f\uff1a # [ 6 7 15 36 39 40 41 42 43 47 49] # Q1: 25.5 # Q2: 40.0 # Q3: 42.5 # \u624b\u7b97\u8ba1\u7b97\u7ed3\u679c\uff1a # Q1\u7684p\u5206\u4f4d\u6570(0.25)\u4f4d\u7f6eposition = 1+(11-1)*0.25 = 3.5(\u53d6\u7b2c3\u4f4d) (p=0.25) Q1=15+(36-15)*0.5=25.5 (\u7b2c3\u30014\u4f4d\u7684\u5dee\u4e58\u4ee5\u4f59\u65700.5) # Q2\u7684p\u5206\u4f4d\u6570(0.5)\u4f4d\u7f6eposition = 1+(11-1)*0.5 = 6 (p=0.5) Q2=40 # Q3\u7684p\u5206\u4f4d\u6570(0.75)\u4f4d\u7f6eposition = 1+(11-1)*0.75 = 9 (p=0.75) Q3=42+(43-42)*0.5=42.5 # IQR = Q3 - Q1 = 17 \u6848\u4f8b2 df = pd.DataFrame(np.array([[1, 1], [2, 10], [3, 100], [4, 100]]), columns=['a', 'b']) print(\"\u6570\u636e\u539f\u59cb\u683c\u5f0f\uff1a\") print(df) print(\"\u8ba1\u7b97p=0.1\u65f6\uff0ca\u5217\u548cb\u5217\u7684\u5206\u4f4d\u6570\") print(df.quantile(.1)) # \u6570\u636e\u539f\u59cb\u683c\u5f0f\uff1a # a b # 0 1 1 # 1 2 10 # 2 3 100 # 3 4 100 # \u8ba1\u7b97p=0.1\u65f6\uff0ca\u5217\u548cb\u5217\u7684\u5206\u4f4d\u6570 # a 1.3 # b 3.7 # Name: 0.1, dtype: float64 # \u624b\u7b97\u8ba1\u7b97\u7ed3\u679c\uff1a # \u8ba1\u7b97a\u5217 # position=1+(4-1)*0.1=1.3 (\u53d6\u7b2c1\u4f4d) # Q1=1+(2-1)*0.3=1.3 (\u7b2c1\u30012\u4f4d\u7684\u5dee\u4e58\u4ee5\u4f59\u65700.3) # \u8ba1\u7b97b\u5217 # position=1+(4-1)*0.1=1.3 (\u53d6\u7b2c1\u4f4d) # Q1=1+(10-1)*0.3=3.7 (\u7b2c1\u30012\u4f4d\u7684\u5dee\u4e58\u4ee5\u4f59\u65700.3) \u4f18\u5316\u7684 groupby \u65b9\u6cd5\uff1a count: \u5206\u7ec4\u4e2d\u975eNA\u503c\u7684\u6570\u91cf sum: \u975eNA\u503c\u7684\u7d2f\u52a0\u548c mean: \u975eNA\u503c\u7684\u5e73\u5747\u503c median: \u975eNA\u503c\u7684\u7b97\u672f\u4e2d\u4f4d\u6570 std, var: \u65e0\u504f\u7684(n-1\u5206\u6bcd)\u6807\u51c6\u5dee\u548c\u65b9\u5dee min, max: \u975eNA\u503c\u7684\u6700\u5c0f\u503c\u3001\u6700\u5927\u503c prod: \u975eNA\u503c\u7684\u4e58\u79ef first, last: \u975eNA\u503c\u7684\u7b2c\u4e00\u4e2a\u3001\u6700\u540e\u4e00\u4e2a\u503c df = pd.DataFrame( { 'key1': ['a', 'a', 'b', 'b', 'a'], 'key2': ['one', 'two', 'one', 'two', 'one'], 'data1': [1, 3, 5, 7, 9], 'data2': [2, 4, 6, 8, 10] } ) print(df) # key1 key2 data1 data2 # 0 a one 1 2 # 1 a two 3 4 # 2 b one 5 6 # 3 b two 7 8 # 4 a one 9 10 grouped = df.groupby('key1') result = grouped['data1'] for i in result: print(i) # ('a', 0 1 # 1 3 # 4 9 # Name: data1, dtype: int64) # ('b', 2 5 # 3 7 # Name: data1, dtype: int64) result = grouped['data1'].quantile(0.9) # quantile\u5206\u4f4d\u6570 print(result) # key1 # a 7.8 # b 6.8 # Name: data1, dtype: float64 # \u624b\u7b97\u8ba1\u7b97\u7ed3\u679c\uff1a # \u8ba1\u7b97a\u5217 # position=1+(3-1)*0.9=2.8 # Q1=3+(9-3)*0.8=7.8 # \u8ba1\u7b97b\u5217 # position=1+(2-1)*0.9=1.9 # Q1=5+(7-5)*0.9=6.8 \u4f7f\u7528\u81ea\u884c\u5236\u5b9a\u7684\u805a\u5408\uff0c\u5e76\u518d\u8c03\u7528\u5df2\u7ecf\u5728\u5206\u7ec4\u5bf9\u8c61\u4e0a\u5b9a\u4e49\u597d\u7684\u65b9\u6cd5\u3002 def peak_to_peak(arr): return arr.max() - arr.min() result = grouped.agg(peak_to_peak) print(result) # data1 data2 # key1 # a 8 8 # b 2 2 result = grouped.describe() print(result) # data1 ... data2 # count mean std min 25% ... min 25% 50% 75% max # key1 ... # a 3.0 4.333333 4.163332 1.0 2.0 ... 2.0 3.0 4.0 7.0 10.0 # b 2.0 6.000000 1.414214 5.0 5.5 ... 6.0 6.5 7.0 7.5 8.0","title":"\u6570\u636e\u805a\u5408"},{"location":"python/DataAnalysis/ch07/#_8","text":"tips = pd.read_csv('../examples/tips.csv') tips['tip_pct'] = tips['tip'] / (tips['total_bill'] - tips['tip']) print(tips.head(5)) # total_bill tip smoker day time size tip_pct # 0 16.99 1.01 No Sun Dinner 2 0.063204 # 1 10.34 1.66 No Sun Dinner 3 0.191244 # 2 21.01 3.50 No Sun Dinner 3 0.199886 # 3 23.68 3.31 No Sun Dinner 2 0.162494 # 4 24.59 3.61 No Sun Dinner 4 0.172069 \u6839\u636e\u5404\u5217\u540c\u65f6\u4f7f\u7528\u591a\u4e2a\u51fd\u6570\u8fdb\u884c\u805a\u5408 grouped = tips.groupby(['day', 'smoker']) # for i in grouped: # print(i) # (('Fri', 'No'), total_bill tip smoker day time size tip_pct # 91 22.49 3.50 No Fri Dinner 2 0.184308 # ...... # 223 15.98 3.00 No Fri Lunch 3 0.231125) # (('Fri', 'Yes'), total_bill tip smoker day time size tip_pct # 90 28.97 3.00 Yes Fri Dinner 2 0.115518 # ...... # 226 10.09 2.00 Yes Fri Lunch 2 0.247219) # ...... grouped_pct = grouped['tip_pct'] for i in grouped_pct: print(i) # (('Fri', 'No'), 91 0.184308 # 94 0.166667 # ...... # Name: tip_pct, dtype: float64) # (('Fri', 'Yes'), 90 0.115518 # 92 0.210526 # ...... # Name: tip_pct, dtype: float64) # ...... \u5c06\u51fd\u6570\u540d\u4ee5\u5b57\u7b26\u4e32\u5f62\u5f0f\u4f20\u9012\u3002 result = grouped_pct.agg('mean') print(result) # day smoker # Fri No 0.179740 # Yes 0.216293 # Sat No 0.190412 # Yes 0.179833 # Sun No 0.193617 # Yes 0.322021 # Thur No 0.193424 # Yes 0.198508 # Name: tip_pct, dtype: float64 \u5982\u679c\u4f20\u9012\u7684\u662f\u51fd\u6570\u6216\u8005\u51fd\u6570\u540d\u7684\u5217\u8868\uff0c\u4f1a\u5f97\u5230\u4e00\u4e2a\u5217\u540d\u662f\u8fd9\u4e9b\u51fd\u6570\u540d\u7684DataFrame\u3002 \u4e0b\u9762\u4f20\u9012\u4e86\u805a\u5408\u51fd\u6570\u7684\u5217\u8868\u7ed9agg\u65b9\u6cd5\uff0c\u8fd9\u4e9b\u51fd\u6570\u4f1a\u5404\u81ea\u8fd0\u7528\u4e8e\u6570\u636e\u5206\u7ec4\u3002 result = grouped_pct.agg(['mean', 'std', peak_to_peak]) print(result) # mean std peak_to_peak # day smoker # Fri No 0.179740 0.039458 0.094263 # Yes 0.216293 0.077530 0.242219 # Sat No 0.190412 0.058626 0.352192 # Yes 0.179833 0.089496 0.446137 # Sun No 0.193617 0.060302 0.274897 # Yes 0.322021 0.538061 2.382107 # Thur No 0.193424 0.056065 0.284273 # Yes 0.198508 0.057170 0.219047 \u5982\u679c\u4f20\u9012\u7684\u662f (name, function) \u5143\u7ec4\u7684\u5217\u8868\uff0c\u6bcf\u4e2a\u5143\u7ec4\u7684\u7b2c\u4e00\u4e2a\u5143\u7d20\u5c06\u4f5c\u4e3aDataFrame\u7684\u5217\u540d\uff08\u53ef\u4ee5\u8ba4\u4e3a\u4e8c\u5143\u5143\u7ec4\u7684\u5217\u8868\u662f\u4e00\u79cd\u6709\u5e8f\u7684\u5bf9\u5e94\u5173\u7cfb\uff09\uff1a result = grouped_pct.agg([('foo', 'mean'), ('bar', np.std)]) # foo\u662fmean\u503c\u7684\u5217\u540d print(result) # foo bar # day smoker # Fri No 0.179740 0.039458 # Yes 0.216293 0.077530 # Sat No 0.190412 0.058626 # Yes 0.179833 0.089496 # Sun No 0.193617 0.060302 # Yes 0.322021 0.538061 # Thur No 0.193424 0.056065 # Yes 0.198508 0.057170 \u53ef\u4ee5\u6307\u5b9a\u5e94\u7528\u5230\u6240\u6709\u5217\u4e0a\u7684\u51fd\u6570\u5217\u8868\u6216\u6bcf\u4e00\u5217\u4e0a\u8981\u5e94\u7528\u7684\u4e0d\u540c\u51fd\u6570\u3002 \u4e0b\u9762\u4ea7\u751f\u7684DataFrame\u62e5\u6709\u5206\u5c42\u5217\uff0c\u4e0e\u5206\u522b\u805a\u5408\u6bcf\u4e00\u5217\uff0c\u518d\u4ee5\u5217\u540d\u4f5c\u4e3a keys \u53c2\u6570\u4f7f\u7528 concat \u5c06\u7ed3\u679c\u62fc\u63a5\u5728\u4e00\u8d77\u7684\u7ed3\u679c\u76f8\u540c\u3002 functions = ['count', 'mean', 'max'] result = grouped[['tip_pct', 'total_bill']].agg(functions) print(result) # tip_pct total_bill # count mean max count mean max # day smoker # Fri No 4 0.179740 0.231125 4 18.420000 22.75 # Yes 15 0.216293 0.357737 15 16.813333 40.17 # Sat No 45 0.190412 0.412409 45 19.661778 48.33 # Yes 42 0.179833 0.483092 42 21.276667 50.81 # Sun No 57 0.193617 0.338101 57 20.506667 48.17 # Yes 19 0.322021 2.452381 19 24.120000 45.35 # Thur No 45 0.193424 0.362976 45 17.113111 41.19 # Yes 17 0.198508 0.317965 17 19.190588 43.11 # \u628a['tip_pct', 'total_bill']\u6539\u6210[['tip_pct', 'total_bill']]\uff0c\u5c31\u53ef\u4ee5\u907f\u514d\u62a5\u9519 # FutureWarning: Indexing with multiple keys (implicitly converted to a tuple of keys) will be deprecated, use a list instead. # result = grouped['tip_pct', 'total_bill'].agg(functions) print(result['tip_pct']) # count mean max # day smoker # Fri No 4 0.179740 0.231125 # Yes 15 0.216293 0.357737 # Sat No 45 0.190412 0.412409 # Yes 42 0.179833 0.483092 # Sun No 57 0.193617 0.338101 # Yes 19 0.322021 2.452381 # Thur No 45 0.193424 0.362976 # Yes 17 0.198508 0.317965 \u4e5f\u540c\u6837\u53ef\u4ee5\u4f20\u9012\u5177\u6709\u81ea\u5b9a\u4e49\u540d\u79f0\u7684\u5143\u7ec4\u5217\u8868\uff1a ftuples = [('Durchschnitt', 'mean'), ('Abweichung', np.var)] result = grouped[['tip_pct', 'total_bill']].agg(ftuples) print(result) # tip_pct total_bill # Durchschnitt Abweichung Durchschnitt Abweichung # day smoker # Fri No 0.179740 0.001557 18.420000 25.596333 # Yes 0.216293 0.006011 16.813333 82.562438 # Sat No 0.190412 0.003437 19.661778 79.908965 # Yes 0.179833 0.008010 21.276667 101.387535 # Sun No 0.193617 0.003636 20.506667 66.099980 # Yes 0.322021 0.289509 24.120000 109.046044 # Thur No 0.193424 0.003143 17.113111 59.625081 # Yes 0.198508 0.003268 19.190588 69.808518 \u8981\u5c06\u4e0d\u540c\u7684\u51fd\u6570\u5e94\u7528\u5230\u4e00\u4e2a\u6216\u591a\u4e2a\u5217\u4e0a\uff0c\u9700\u8981\u5c06\u542b\u6709\u5217\u540d\u4e0e\u51fd\u6570\u5bf9\u5e94\u5173\u7cfb\u7684\u5b57\u5178\u4f20\u9012\u7ed9 agg \uff1a result = grouped.agg({'tip': np.max, 'size': 'sum'}) print(result) # tip size # day smoker # Fri No 3.50 9 # Yes 4.73 31 # Sat No 9.00 115 # Yes 10.00 104 # Sun No 6.00 167 # Yes 6.50 49 # Thur No 6.70 112 # Yes 5.00 40 result = grouped.agg({'tip_pct': ['min', 'max', 'mean', 'std']}) print(result) # tip_pct # min max mean std # day smoker # Fri No 0.136861 0.231125 0.179740 0.039458 # Yes 0.115518 0.357737 0.216293 0.077530 # Sat No 0.060217 0.412409 0.190412 0.058626 # Yes 0.036955 0.483092 0.179833 0.089496 # Sun No 0.063204 0.338101 0.193617 0.060302 # Yes 0.070274 2.452381 0.322021 0.538061 # Thur No 0.078704 0.362976 0.193424 0.056065 # Yes 0.098918 0.317965 0.198508 0.057170 \u53ea\u6709\u591a\u4e2a\u51fd\u6570\u5e94\u7528\u4e8e\u81f3\u5c11\u4e00\u4e2a\u5217\u65f6\uff0cDataFrame\u624d\u5177\u6709\u5206\u5c42\u5217\u3002","title":"\u9010\u5217\u53ca\u591a\u51fd\u6570\u5e94\u7528"},{"location":"python/DataAnalysis/ch07/#_9","text":"\u5728\u524d\u9762\u6240\u6709\u7684\u4f8b\u5b50\u4e2d\uff0c\u805a\u5408\u6570\u636e\u8fd4\u56de\u65f6\u90fd\u662f\u5e26\u6709\u7d22\u5f15\u7684\uff0c\u6709\u65f6\u7d22\u5f15\u662f\u5206\u5c42\u7684\uff0c\u7531\u552f\u4e00\u7684\u5206\u7ec4\u952e\u8054\u5408\u5f62\u6210\u3002 \u56e0\u4e3a\u4e0d\u662f\u6240\u6709\u7684\u60c5\u51b5\u4e0b\u90fd\u9700\u8981\u7d22\u5f15\uff0c\u6240\u4ee5\u5728\u5927\u591a\u6570\u60c5\u51b5\u4e0b\u53ef\u4ee5\u901a\u8fc7\u5411groupby\u4f20\u9012as_index=False\u6765\u7981\u7528\u5206\u7ec4\u952e\u4f5c\u4e3a\u7d22\u5f15\u7684\u884c\u4e3a\uff1a result = tips.groupby(['day', 'smoker'], as_index=False).mean() print(result) # day smoker total_bill tip size tip_pct # 0 Fri No 18.420000 2.812500 2.250000 0.179740 # 1 Fri Yes 16.813333 2.714000 2.066667 0.216293 # 2 Sat No 19.661778 3.102889 2.555556 0.190412 # 3 Sat Yes 21.276667 2.875476 2.476190 0.179833 # 4 Sun No 20.506667 3.167895 2.929825 0.193617 # 5 Sun Yes 24.120000 3.516842 2.578947 0.322021 # 6 Thur No 17.113111 2.673778 2.488889 0.193424 # 7 Thur Yes 19.190588 3.030000 2.352941 0.198508 \u901a\u8fc7\u5728\u7ed3\u679c\u4e0a\u8c03\u7528reset_index\u4e5f\u53ef\u4ee5\u83b7\u5f97\u540c\u6837\u7684\u7ed3\u679c\u3002\u4f7f\u7528as_index=False\u53ef\u4ee5\u907f\u514d\u4e00\u4e9b\u4e0d\u5fc5\u8981\u7684\u8ba1\u7b97\u3002 result = tips.groupby(['day', 'smoker']).mean() print(result.reset_index()) # day smoker total_bill tip size tip_pct # 0 Fri No 18.420000 2.812500 2.250000 0.179740 # 1 Fri Yes 16.813333 2.714000 2.066667 0.216293 # 2 Sat No 19.661778 3.102889 2.555556 0.190412 # 3 Sat Yes 21.276667 2.875476 2.476190 0.179833 # 4 Sun No 20.506667 3.167895 2.929825 0.193617 # 5 Sun Yes 24.120000 3.516842 2.578947 0.322021 # 6 Thur No 17.113111 2.673778 2.488889 0.193424 # 7 Thur Yes 19.190588 3.030000 2.352941 0.198508 print(result) # total_bill tip size tip_pct # day smoker # Fri No 18.420000 2.812500 2.250000 0.179740 # Yes 16.813333 2.714000 2.066667 0.216293 # Sat No 19.661778 3.102889 2.555556 0.190412 # Yes 21.276667 2.875476 2.476190 0.179833 # Sun No 20.506667 3.167895 2.929825 0.193617 # Yes 24.120000 3.516842 2.578947 0.322021 # Thur No 17.113111 2.673778 2.488889 0.193424 # Yes 19.190588 3.030000 2.352941 0.198508","title":"\u8fd4\u56de\u4e0d\u542b\u884c\u7d22\u5f15\u7684\u805a\u5408\u6570\u636e"},{"location":"python/DataAnalysis/ch07/#-","text":"import pandas as pd import numpy as np import statsmodels.api as sm GroupBy \u65b9\u6cd5\u6700\u5e38\u89c1\u7684\u76ee\u7684\u662f apply \uff08\u5e94\u7528\uff09\u3002 apply \u5c06\u5bf9\u8c61\u62c6\u5206\u6210\u591a\u5757\uff0c\u7136\u540e\u5728\u6bcf\u4e00\u5757\u4e0a\u8c03\u7528\u4f20\u9012\u7684\u51fd\u6570\uff0c\u4e4b\u540e\u5c1d\u8bd5\u5c06\u6bcf\u4e00\u5757\u62fc\u63a5\u5230\u4e00\u8d77\u3002 \u6839\u636e\u4e0b\u9762\u7684\u5c0f\u8d39\u6570\u636e\u96c6\uff0c\u6309\u7ec4\u9009\u51fa\u5c0f\u8d39\u767e\u5206\u6bd4\uff08tip-pct\uff09\u6700\u9ad8\u7684\u4e94\u7ec4\u3002 tips = pd.read_csv('../examples/tips.csv') tips['tip_pct'] = tips['tip'] / (tips['total_bill'] - tips['tip']) \u6837\u672c\u6570\u636e print(tips.head(5)) # total_bill tip smoker day time size tip_pct # 0 16.99 1.01 No Sun Dinner 2 0.063204 # 1 10.34 1.66 No Sun Dinner 3 0.191244 # 2 21.01 3.50 No Sun Dinner 3 0.199886 # 3 23.68 3.31 No Sun Dinner 2 0.162494 # 4 24.59 3.61 No Sun Dinner 4 0.172069 \u9996\u5148\uff0c\u5199\u4e00\u4e2a\u53ef\u4ee5\u5728\u7279\u5b9a\u5217\u4e2d\u9009\u51fa\u6700\u5927\u503c\u6240\u5728\u884c\u7684\u51fd\u6570\uff1a \u6dfb\u52a0\u4e86\u5347\u5e8f\uff0c\u7ed3\u679c\u8f93\u51fa\u6700\u540e5\u884c\uff08\u6700\u540e\u76845\u884c\u4e5f\u662f\u6700\u5927\u76845\u4e2a tip_tcp \u8bb0\u5f55\uff09\u3002 def top(df, n=5, column='tip_pct'): return df.sort_values(by=column, ascending=True)[-n:] result = top(tips, n=6) print(result) # \u7b49\u4ef7\u65b9\u5f0f\uff1a # result = tips.sort_values('tip_pct')[-6:] # print(result) # total_bill tip smoker day time size tip_pct # 109 14.31 4.00 Yes Sat Dinner 2 0.387973 # 183 23.17 6.50 Yes Sun Dinner 4 0.389922 # 232 11.61 3.39 No Sat Dinner 2 0.412409 # 67 3.07 1.00 Yes Sat Dinner 1 0.483092 # 178 9.60 4.00 Yes Sun Dinner 2 0.714286 # 172 7.25 5.15 Yes Sun Dinner 2 2.452381 \u5982\u679c\u6309\u7167 smoker \u8fdb\u884c\u5206\u7ec4\uff0c\u4e4b\u540e\u8c03\u7528 apply \uff0c\u4f1a\u5f97\u5230\u4ee5\u4e0b\u7ed3\u679c\uff1a top \u51fd\u6570\u5728DataFrame\u7684\u6bcf\u4e00\u884c\u5206\u7ec4\u4e0a\u88ab\u8c03\u7528\uff0c\u4e4b\u540e\u4f7f\u7528 pandas.concat \u5c06\u51fd\u6570\u7ed3\u679c\u7c98\u8d34\u5728\u4e00\u8d77\uff0c\u5e76\u4f7f\u7528\u5206\u7ec4\u540d\u4f5c\u4e3a\u5404\u7ec4\u7684\u6807\u7b7e\u3002 \u56e0\u6b64\u7ed3\u679c\u5305\u542b\u4e00\u4e2a\u5206\u5c42\u7d22\u5f15\uff0c\u8be5\u5206\u5c42\u7d22\u5f15\u7684\u5185\u90e8\u5c42\u7ea7\u5305\u542b\u539fDataFrame\u7684\u7d22\u5f15\u503c\u3002 result = tips.groupby('smoker').apply(top) print(result) # total_bill tip smoker day time size tip_pct # smoker # No 88 24.71 5.85 No Thur Lunch 2 0.310180 # 185 20.69 5.00 No Sun Dinner 5 0.318674 # 51 10.29 2.60 No Sun Dinner 2 0.338101 # 149 7.51 2.00 No Thur Lunch 2 0.362976 # 232 11.61 3.39 No Sat Dinner 2 0.412409 # Yes 109 14.31 4.00 Yes Sat Dinner 2 0.387973 # 183 23.17 6.50 Yes Sun Dinner 4 0.389922 # 67 3.07 1.00 Yes Sat Dinner 1 0.483092 # 178 9.60 4.00 Yes Sun Dinner 2 0.714286 # 172 7.25 5.15 Yes Sun Dinner 2 2.452381 \u5982\u679c\u9664\u4e86\u5411 apply \u4f20\u9012\u51fd\u6570\uff0c\u8fd8\u4f20\u9012\u5176\u4ed6\u53c2\u6570\u6216\u5173\u952e\u5b57\u7684\u8bdd\uff0c\u4f60\u53ef\u4ee5\u628a\u8fd9\u4e9b\u653e\u5728\u51fd\u6570\u540e\u8fdb\u884c\u4f20\u9012\u3002 result = tips.groupby('smoker').apply(top, n=1, column='total_bill') print(result) # \u8fd92\u884c\u90fd\u662fsmoker\u662fyes\u548cno\u65f6\u6700\u5927total_bill\u503c\u6240\u5728\u884c\u3002 # total_bill tip smoker day time size tip_pct # smoker # No 212 48.33 9.0 No Sat Dinner 4 0.228833 # Yes 170 50.81 10.0 Yes Sat Dinner 3 0.245038 \u5728 GroupBy \u5bf9\u8c61\u4e0a\u8c03\u7528 describe \u65b9\u6cd5\u3002 result = tips.groupby('smoker')['tip_pct'].describe() print(result) # count mean std ... 50% 75% max # smoker ... # No 151.0 0.192237 0.057665 ... 0.184308 0.227015 0.412409 # Yes 93.0 0.218176 0.254295 ... 0.181818 0.242326 2.452381 # [2 rows x 8 columns] print(result.unstack('smoker')) # \u7c7b\u4f3c\u4e8e\u8f6c\u7f6e # smoker # count No 151.000000 # Yes 93.000000 # mean No 0.192237 # Yes 0.218176 # std No 0.057665 # Yes 0.254295 # min No 0.060217 # Yes 0.036955 # 25% No 0.158622 # Yes 0.119534 # 50% No 0.184308 # Yes 0.181818 # 75% No 0.227015 # Yes 0.242326 # max No 0.412409 # Yes 2.452381 # dtype: float64 \u5728 GroupBy \u5bf9\u8c61\u7684\u5185\u90e8\uff0c\u5f53\u8c03\u7528\u50cf describe \u8fd9\u6837\u7684\u65b9\u6cd5\u65f6\uff0c\u5b9e\u9645\u4e0a\u662f\u4ee5\u4e0b\u4ee3\u7801\u7684\u7b80\u5199\uff1a grouped = tips.groupby(['smoker']) f = lambda x: x.describe() result = grouped.apply(f) print(result) # total_bill tip size tip_pct # smoker # No count 151.000000 151.000000 151.000000 151.000000 # mean 19.188278 2.991854 2.668874 0.192237 # std 8.255582 1.377190 1.017984 0.057665 # min 7.250000 1.000000 1.000000 0.060217 # 25% 13.325000 2.000000 2.000000 0.158622 # 50% 17.590000 2.740000 2.000000 0.184308 # 75% 22.755000 3.505000 3.000000 0.227015 # max 48.330000 9.000000 6.000000 0.412409 # Yes count 93.000000 93.000000 93.000000 93.000000 # mean 20.756344 3.008710 2.408602 0.218176 # std 9.832154 1.401468 0.810751 0.254295 # min 3.070000 1.000000 1.000000 0.036955 # 25% 13.420000 2.000000 2.000000 0.119534 # 50% 17.920000 3.000000 2.000000 0.181818 # 75% 26.860000 3.680000 3.000000 0.242326 # max 50.810000 10.000000 5.000000 2.452381","title":"\u5e94\u7528\uff1a\u901a\u7528\u62c6\u5206-\u5e94\u7528-\u8054\u5408"},{"location":"python/DataAnalysis/ch07/#_10","text":"\u5728\u524d\u9762\u7684\u4f8b\u5b50\u4e2d\u6240\u5f97\u5230\u7684\u5bf9\u8c61\uff0c\u90fd\u5177\u6709\u5206\u7ec4\u952e\u6240\u5f62\u6210\u7684\u5206\u5c42\u7d22\u5f15\u4ee5\u53ca\u6bcf\u4e2a\u539f\u59cb\u5bf9\u8c61\u7684\u7d22\u5f15\u3002 \u4e5f\u53ef\u4ee5\u901a\u8fc7\u5411 groupby \u4f20\u9012 group_keys=False \u6765\u7981\u7528\u8fd9\u4e2a\u529f\u80fd\u3002 result = tips.groupby('smoker', group_keys=True).apply(top) print(result) # total_bill tip smoker day time size tip_pct # smoker # No 88 24.71 5.85 No Thur Lunch 2 0.310180 # 185 20.69 5.00 No Sun Dinner 5 0.318674 # 51 10.29 2.60 No Sun Dinner 2 0.338101 # 149 7.51 2.00 No Thur Lunch 2 0.362976 # 232 11.61 3.39 No Sat Dinner 2 0.412409 # Yes 109 14.31 4.00 Yes Sat Dinner 2 0.387973 # 183 23.17 6.50 Yes Sun Dinner 4 0.389922 # 67 3.07 1.00 Yes Sat Dinner 1 0.483092 # 178 9.60 4.00 Yes Sun Dinner 2 0.714286 # 172 7.25 5.15 Yes Sun Dinner 2 2.452381 result = tips.groupby('smoker', group_keys=False).apply(top) print(result) # total_bill tip smoker day time size tip_pct # 88 24.71 5.85 No Thur Lunch 2 0.310180 # 185 20.69 5.00 No Sun Dinner 5 0.318674 # 51 10.29 2.60 No Sun Dinner 2 0.338101 # 149 7.51 2.00 No Thur Lunch 2 0.362976 # 232 11.61 3.39 No Sat Dinner 2 0.412409 # 109 14.31 4.00 Yes Sat Dinner 2 0.387973 # 183 23.17 6.50 Yes Sun Dinner 4 0.389922 # 67 3.07 1.00 Yes Sat Dinner 1 0.483092 # 178 9.60 4.00 Yes Sun Dinner 2 0.714286 # 172 7.25 5.15 Yes Sun Dinner 2 2.452381","title":"\u538b\u7f29\u5206\u7ec4\u952e"},{"location":"python/DataAnalysis/ch07/#_11","text":"\u7b2c8\u7ae0\u4e2d\uff0cpandas\u6709\u4e00\u4e9b\u5de5\u5177\uff0c\u5c24\u5176\u662f cut \u548c qcut \uff0c\u7528\u4e8e\u5c06\u6570\u636e\u6309\u7167\u4f60\u9009\u62e9\u7684\u7bb1\u4f4d\u6216\u6837\u672c\u5206\u4f4d\u6570\u8fdb\u884c\u5206\u6876\u3002 \u4e0e groupby \u65b9\u6cd5\u4e00\u8d77\u4f7f\u7528\u8fd9\u4e9b\u51fd\u6570\u53ef\u4ee5\u5bf9\u6570\u636e\u96c6\u66f4\u65b9\u4fbf\u5730\u8fdb\u884c\u5206\u6876\u6216\u5206\u4f4d\u5206\u6790\u3002 \u590d\u4e60\uff1a\u673a\u68b0\u5b66\u4e60\u4e2d\u7684\u5206\u7bb1\u5904\u7406\u3002 \u5728\u673a\u68b0\u5b66\u4e60\u4e2d\u7ecf\u5e38\u4f1a\u5bf9\u6570\u636e\u8fdb\u884c\u5206\u7bb1\u5904\u7406\u7684\u64cd\u4f5c\uff0c \u4e5f\u5c31\u662f\u628a\u4e00\u6bb5\u8fde\u7eed\u7684\u503c\u5207\u5206\u6210\u82e5\u5e72\u6bb5\uff0c\u6bcf\u4e00\u6bb5\u7684\u503c\u770b\u6210\u4e00\u4e2a\u5206\u7c7b\u3002\u8fd9\u4e2a\u628a\u8fde\u7eed\u503c\u8f6c\u6362\u6210\u79bb\u6563\u503c\u7684\u8fc7\u7a0b\uff0c\u6211\u4eec\u53eb\u505a\u5206\u7bb1\u5904\u7406\u3002 \u6bd4\u5982\uff0c\u628a\u5e74\u9f84\u630915\u5c81\u5212\u5206\u6210\u4e00\u7ec4\uff0c0-15\u5c81\u53eb\u505a\u5c11\u5e74\uff0c16-30\u5c81\u53eb\u505a\u9752\u5e74\uff0c31-45\u5c81\u53eb\u505a\u58ee\u5e74\u3002\u5728\u8fd9\u4e2a\u8fc7\u7a0b\u4e2d\uff0c\u6211\u4eec\u628a\u8fde\u7eed\u7684\u5e74\u9f84\u5206\u6210\u4e86\u4e09\u4e2a\u7c7b\u522b\uff0c\u201c\u5c11\u5e74\u201d\uff0c\u201c\u9752\u5e74\u201d\u548c\u201c\u58ee\u5e74\u201d\u5c31\u662f\u5404\u4e2a\u7c7b\u522b\u7684\u540d\u79f0\uff0c\u6216\u8005\u53eb\u505a\u6807\u7b7e\u3002 \u5728pandas\u4e2d\uff0c cut \u548c qcut \u51fd\u6570\u90fd\u53ef\u4ee5\u8fdb\u884c\u5206\u7bb1\u5904\u7406\u64cd\u4f5c\u3002 cut() \u6309\u7167\u53d8\u91cf\u7684\u503c\u5bf9\u53d8\u91cf\u8fdb\u884c\u5206\u5272\uff0c\u6bcf\u4e2a\u5206\u7ec4\u91cc\u6570\u636e\u7684\u4e2a\u6570\u5e76\u4e0d\u4e00\u6837\u3002 qcut() \u662f\u6309\u53d8\u91cf\u7684\u6570\u91cf\u6765\u5bf9\u53d8\u91cf\u8fdb\u884c\u5206\u5272\uff0c\u5e76\u4e14\u5c3d\u91cf\u4fdd\u8bc1\u6bcf\u4e2a\u5206\u7ec4\u91cc\u53d8\u91cf\u7684\u4e2a\u6570\u76f8\u540c\u3002 \u8003\u8651\u4e0b\u9762\u4e00\u4e2a\u7b80\u5355\u7684\u968f\u673a\u6570\u636e\u96c6\u548c\u4e00\u4e2a\u4f7f\u7528 cut \u7684\u7b49\u957f\u6876\u5206\u7c7b\uff1a df = pd.DataFrame( { 'data1': np.random.randn(1000), 'data2': np.random.randn(1000) } ) quartiles = pd.cut(df.data1, 4) # \u6309\u7167data1\u503c\u7531\u5c0f\u5230\u5927\u7684\u987a\u5e8f\u5c06\u6570\u636e\u5206\u62104\u4efd\uff0c\u5e76\u4e14\u4f7f\u6bcf\u7ec4\u503c\u7684\u8303\u56f4\u5927\u81f4\u76f8\u7b49\u3002 print(quartiles[:10]) # 0 (-0.0743, 1.729] # 1 (-0.0743, 1.729] # 2 (-0.0743, 1.729] # 3 (-0.0743, 1.729] # 4 (-1.877, -0.0743] # 5 (-0.0743, 1.729] # 6 (-0.0743, 1.729] # 7 (-0.0743, 1.729] # 8 (-1.877, -0.0743] # 9 (-0.0743, 1.729] # Name: data1, dtype: category # Categories ( # 4, # interval[float64, right]): [ # (-3.687, -1.877] < (-1.877, -0.0743] < (-0.0743, 1.729] < (1.729, 3.531] # ] \u4e0a\u9762 cut \u8fd4\u56de\u7684 Categorical \u5bf9\u8c61\u53ef\u4ee5\u76f4\u63a5\u4f20\u9012\u7ed9 groupby \u3002\u5229\u7528\u5b83\u8ba1\u7b97\u51fa data2 \u5217\u7684\u4e00\u4e2a\u7edf\u8ba1\u503c\u96c6\u5408\uff0c\u5982\u4e0b\uff1a def get_stats(group): return { 'min': group.min(), 'max': group.max(), 'count': group.count(), 'mean': group.mean() } grouped = df.data2.groupby(quartiles) for i in grouped: print(i) result = grouped.apply(get_stats).unstack() print(result) # min max count mean # data1 # (-3.145, -1.424] -1.759377 2.484321 77.0 -0.127900 # (-1.424, 0.29] -3.142344 2.830654 524.0 -0.081931 # (0.29, 2.005] -3.557136 3.261635 376.0 0.015715 # (2.005, 3.719] -2.829458 1.766352 23.0 -0.198780 \u4f7f\u7528 qcut \uff0c\u6839\u636e\u6837\u672c\u5206\u4f4d\u6570\u8ba1\u7b97\u51fa\u7b49\u5927\u5c0f\u7684\u6876\uff0c\u5c31\u662f\u7b49\u957f\u6876\u3002\u901a\u8fc7\u4f20\u9012 labels=False \u6765\u83b7\u5f97\u5206\u4f4d\u6570\u6570\u503c\u3002 grouping = pd.qcut(df.data1, 10, labels=False) grouped = df.data2.groupby(grouping) result = grouped.apply(get_stats).unstack() print(result) # min max count mean # data1 # 0 -3.678934 3.022862 100.0 0.029658 # 1 -2.319813 2.646502 100.0 0.094035 # 2 -2.873727 2.470840 100.0 0.023866 # 3 -2.196701 2.042251 100.0 0.021232 # 4 -2.154161 2.020809 100.0 0.110834 # 5 -2.723061 2.415626 100.0 0.057365 # 6 -2.291470 2.536159 100.0 0.020866 # 7 -2.064083 1.799356 100.0 -0.081025 # 8 -3.405679 1.792581 100.0 -0.009705 # 9 -2.469285 2.600849 100.0 -0.061721","title":"\u5206\u4f4d\u6570\u4e0e\u6876\u5206\u6790"},{"location":"python/DataAnalysis/ch07/#_12","text":"\u5728\u6e05\u9664\u7f3a\u5931\u503c\u65f6\uff0c\u6709\u65f6\u4f1a\u4f7f\u7528 dropna \u6765\u53bb\u9664\u7f3a\u5931\u503c\uff0c\u6709\u65f6\u4f7f\u7528\u4fee\u6b63\u503c\u6216\u6765\u81ea\u4e8e\u5176\u4ed6\u6570\u636e\u7684\u503c\u6765\u8f93\u5165\uff08\u586b\u5145\uff09\u5230 null \u503c\uff08 NA \uff09\u3002 fillna \u662f\u4e00\u4e2a\u53ef\u4ee5\u4f7f\u7528\u7684\u6b63\u786e\u5de5\u5177\u3002 \u4f8b\u5982\u4e0b\u9762\u4f8b\u5b50\u4e2d\u4f7f\u7528\u4f7f\u7528\u5e73\u5747\u503c\u6765\u586b\u5145NA\u503c\uff1a data = (100, 110, 120, 130, 140, 150) s = pd.Series(data) print(s) # 0 100 # 1 110 # 2 120 # 3 130 # 4 140 # 5 150 # dtype: float64 \u5c06\u6570\u636e\u4e2d\u7684\u4e00\u4e9b\u503c\u8bbe\u7f6e\u4e3a\u7f3a\u5931\u503c\uff1a s[::2] = np.nan print(s) # 0 NaN # 1 110.0 # 2 NaN # 3 130.0 # 4 NaN # 5 150.0 # dtype: float64 result = s.fillna(s.mean()) # 110, 130, 150\u7684\u5e73\u5747\u503c\u662f130 print(result) # 0 130.0 # 1 110.0 # 2 130.0 # 3 130.0 # 4 130.0 # 5 150.0 # dtype: float64 \u4e0b\u9762\u7684\u4f8b\u5b50\u662f\u6309\u7ec4\u586b\u5145NA\u503c\uff1a \u65b9\u6cd51,\u5bf9\u6570\u636e\u5206\u7ec4\u540e\u4f7f\u7528 apply \u3002 \u65b9\u6cd52,\u5728\u6bcf\u4e2a\u6570\u636e\u5757\u4e0a\u90fd\u8c03\u7528 fillna \u7684\u51fd\u6570\u3002 data = (100, 110, 120, 130, 140, 150, 160, 170) states = ['Ohio', 'New York', 'Vermont', 'Florida', 'Oregon', 'Nevada', 'California', 'Idaho'] group_key = ['East'] * 4 + ['West'] * 4 # 4\u4e2aEast\u548c4\u4e2aWest\u62fc\u63a5\u7684\u5217\u8868list s = pd.Series(data, index=states) print(s) # Ohio 100 # New York 110 # Vermont 120 # Florida 130 # Oregon 140 # Nevada 150 # California 160 # Idaho 170 # dtype: int64 \u5c06\u6570\u636e\u4e2d\u7684\u4e00\u4e9b\u503c\u8bbe\u7f6e\u4e3a\u7f3a\u5931\u503c\uff1a s[['Vermont', 'Nevada', 'Idaho']] = np.nan print(s) # Ohio 100.0 # New York 110.0 # Vermont NaN # Florida 130.0 # Oregon 140.0 # Nevada NaN # California 160.0 # Idaho NaN # dtype: float64 result = s.groupby(group_key).mean() print(result) # East 113.333333 # West 150.000000 # dtype: float64 \u7528\u4e0a\u9762\u5f97\u51fa\u7684\u5206\u7ec4\u5e73\u5747\u503c\u6765\u586b\u5145NA\u3002 fill_mean = lambda g: g.fillna(g.mean()) result = s.groupby(group_key).apply(fill_mean) print(result) # Ohio 100.000000 # New York 110.000000 # Vermont 113.333333 # Florida 130.000000 # Oregon 140.000000 # Nevada 150.000000 # California 160.000000 # Idaho 150.000000 # dtype: float64 \u5982\u679c\u5df2\u7ecf\u5728\u4ee3\u7801\u4e2d\u4e3a\u6bcf\u4e2a\u5206\u7ec4\u9884\u5b9a\u4e49\u4e86\u586b\u5145\u503c\uff0c\u53ef\u4ee5\u5229\u7528\u6bcf\u4e2a\u5206\u7ec4\u90fd\u6709\u7684\u5185\u7f6e\u7684 name \u5c5e\u6027\uff0c\u5b9e\u73b0\u586b\u5145 NA \u3002 fill_value = {'East': 0.5, 'West': -1} fill_func = lambda g: g.fillna(fill_value[g.name]) result = s.groupby(group_key).apply(fill_func) print(result) # Ohio 100.0 # New York 110.0 # Vermont 0.5 # Florida 130.0 # Oregon 140.0 # Nevada -1.0 # California 160.0 # Idaho -1.0 # dtype: float64","title":"\u793a\u4f8b\uff1a\u4f7f\u7528\u6307\u5b9a\u5206\u7ec4\u503c\u586b\u5145\u7f3a\u5931\u503c"},{"location":"python/DataAnalysis/ch07/#_13","text":"\u5047\u8bbe\u60f3\u4ece\u5927\u6570\u636e\u96c6\u4e2d\u62bd\u53d6\u968f\u673a\u6837\u672c\uff08\u6709\u6216\u6ca1\u6709\u66ff\u6362\uff09\u4ee5\u7528\u4e8e\u8499\u7279\u5361\u7f57\u6a21\u62df\u76ee\u7684\u6216\u67d0\u4e9b\u5176\u4ed6\u5e94\u7528\u7a0b\u5e8f\u3002 \u6709\u5f88\u591a\u65b9\u6cd5\u6765\u6267\u884c\u201c\u62bd\u53d6\u201d\uff0c\u8fd9\u91cc\u4f7f\u7528Series\u7684sample\u65b9\u6cd5\u3002 \u4e3a\u4e86\u6f14\u793a\uff0c\u8fd9\u91cc\u4ecb\u7ecd\u4e00\u79cd\u6784\u9020\u4e00\u526f\u82f1\u5f0f\u6251\u514b\u724c\u7684\u65b9\u6cd5\uff1a # \u6885\u82b1clubs\u3001\u65b9\u5757diamonds\u3001\u7ea2\u6843hearts\u3001\u9ed1\u6843spades\u3002 suits = ['H', 'S', 'C', 'D'] card_val = (list(range(1, 11)) + [10] * 3) * 4 # card_val [ # 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 10, 10, 10, # 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 10, 10, 10, # 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 10, 10, 10, # 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 10, 10, 10 # ] base_names = ['A'] + list(range(2, 11)) + ['J', 'K', 'Q'] # base_names\uff1a ['A', 2, 3, 4, 5, 6, 7, 8, 9, 10, 'J', 'K', 'Q'] \u751f\u6210\u4e86\u4e00\u4e2a\u957f\u5ea6\u4e3a 52 \u7684Series, Series\u7684\u7d22\u5f15\u5305\u542b\u4e86\u724c\u540d\uff0cSeries\u7684\u503c\u53ef\u4ee5\u7528\u6e38\u620f\uff08\u4e3a\u4e86\u4fdd\u6301\u7b80\u5355\uff0c\u8ba9\u2019A\u2019\u4e3a1 \uff09\uff1a cards = [] for suit in ['H', 'S', 'C', 'D']: cards.extend(str(num) + suit for num in base_names) deck = pd.Series(card_val, index=cards) print(deck) # AH 1 # 2H 2 # 3H 3 # 4H 4 # 5H 5 # 6H 6 # 7H 7 # 8H 8 # 9H 9 # 10H 10 # JH 10 # KH 10 # QH 10 # AS 1 # 2S 2 # 3S 3 # 4S 4 # 5S 5 # 6S 6 # 7S 7 # 8S 8 # 9S 9 # 10S 10 # JS 10 # KS 10 # QS 10 # AC 1 # 2C 2 # 3C 3 # 4C 4 # 5C 5 # 6C 6 # 7C 7 # 8C 8 # 9C 9 # 10C 10 # JC 10 # KC 10 # QC 10 # AD 1 # 2D 2 # 3D 3 # 4D 4 # 5D 5 # 6D 6 # 7D 7 # 8D 8 # 9D 9 # 10D 10 # JD 10 # KD 10 # QD 10 # dtype: int64 \u4ece\u8fd9\u526f\u724c\u4e2d\u62ff\u51fa\u4e94\u5f20\u724c\u53ef\u4ee5\u5199\u6210\uff1a def draw(_deck, n=5): return _deck.sample(n) print(draw(deck)) # KD 10 # 2S 2 # 5C 5 # 6C 6 # QD 10 # dtype: int64 \u5047\u8bbe\u8981\u4ece\u6bcf\u4e2a\u82b1\u8272\u4e2d\u968f\u673a\u62bd\u53d6\u4e24\u5f20\u724c\u3002\u7531\u4e8e\u82b1\u8272\u662f\u724c\u540d\u7684\u6700\u540e\u4e24\u4e2a\u5b57\u7b26\uff0c\u53ef\u4ee5\u57fa\u4e8e\u8fd9\u70b9\u8fdb\u884c\u5206\u7ec4\uff0c\u5e76\u4f7f\u7528 apply \uff1a get_suit = lambda card: card[-1] # \u6700\u540e\u4e00\u4e2a\u5b57\u6bcd\u662f\u82b1\u8272 result = deck.groupby(get_suit).apply(draw, n=2) print(result) # C 10C 10 # 3C 3 # D KD 10 # AD 1 # H 5H 5 # 7H 7 # S 3S 3 # 5S 5 # dtype: int64 \u6216\u8005\u4e5f\u53ef\u4ee5\u5199\u6210\uff1a result = deck.groupby(get_suit, group_keys=False).apply(draw, n=2) print(result) # JC 10 # 8C 8 # QD 10 # 4D 4 # 10H 10 # 6H 6 # 7S 7 # KS 10 # dtype: int64","title":"\u793a\u4f8b\uff1a\u968f\u673a\u91c7\u6837\u4e0e\u6392\u5217"},{"location":"python/DataAnalysis/ch07/#_14","text":"\u5728 groupby \u7684\u62c6\u5206-\u5e94\u7528-\u8054\u5408\u7684\u8303\u5f0f\u4e0b\uff0cDataFrame\u7684\u5217\u95f4\u64cd\u4f5c\u6216\u4e24\u4e2aSeriese\u4e4b\u95f4\u7684\u64cd\u4f5c\uff0c\u4f8b\u5982\u5b9e\u73b0\u5206\u7ec4\u52a0\u6743\u5e73\u5747\u3002 \u4e0b\u9762\u4f8b\u5b50\uff0c\u4f7f\u7528\u4e00\u4e2a\u5305\u542b\u5206\u7ec4\u952e\u548c\u6743\u91cd\u503c\u7684\u6570\u636e\u96c6\uff1a dt = np.random.randn(8) wt = np.random.randn(8) df = pd.DataFrame( { 'category': ['a', 'a', 'a', 'a', 'b', 'b', 'b', 'b'], 'data': dt, 'weight': wt } ) print(df) # category data weight # 0 a -0.250764 -0.085285 # 1 a 0.167155 -1.361254 # 2 a 0.399306 1.755542 # 3 a -0.514477 0.270124 # 4 b -0.005558 0.886514 # 5 b 0.607596 -1.384315 # 6 b -1.029627 -0.845340 # 7 b -0.294204 1.253965 \u901a\u8fc7 category \u8fdb\u884c\u5206\u7ec4\u52a0\u6743\u5e73\u5747\u5982\u4e0b\uff1a grouped = df.groupby('category') get_wavg = lambda g: np.average(g['data'], weights=g['weight']) result = grouped.apply(get_wavg) print(result) # category # a 0.614499 # b 3.863947 # dtype: float64 \u53e6\u4e00\u4e2a\u4f8b\u5b50\uff0c\u4e00\u4e2a\u4ece\u96c5\u864e\u8d22\u7ecf\u4e0a\u83b7\u5f97\u7684\u6570\u636e\u96c6\uff0c\u8be5\u6570\u636e\u96c6\u5305\u542b\u4e00\u4e9b\u6807\u666e500 \uff08SPX\u7b26\u53f7\uff09\u548c\u80a1\u7968\u7684\u6536\u76d8\u4ef7\uff1a close_px = pd.read_csv('../examples/stock_px_2.csv', parse_dates=True, index_col=0) print(close_px.info()) # # DatetimeIndex: 2214 entries, 2003-01-02 to 2011-10-14 # Data columns (total 4 columns): # # Column Non-Null Count Dtype # --- ------ -------------- ----- # 0 AAPL 2214 non-null float64 # 1 MSFT 2214 non-null float64 # 2 XOM 2214 non-null float64 # 3 SPX 2214 non-null float64 # dtypes: float64(4) # memory usage: 86.5 KB # None print(close_px[-4:]) # AAPL MSFT XOM SPX # 2011-10-11 400.29 27.00 76.27 1195.54 # 2011-10-12 402.19 26.96 77.16 1207.25 # 2011-10-13 408.43 27.18 76.37 1203.66 # 2011-10-14 422.00 27.27 78.11 1224.58 \u76ee\u6807\u4efb\u52a1\uff1a\u8ba1\u7b97\u4e00\u4e2aDataFrame\uff0c\u5b83\u5305\u542b\u6807\u666e\u6307\u6570\uff08SPX\uff09\u6bcf\u65e5\u6536\u76ca\u7684\u5e74\u5ea6\u76f8\u5173\u6027\uff08\u901a\u8fc7\u767e\u5206\u6bd4\u53d8\u5316\u8ba1\u7b97\uff09\u3002 \u9996\u5148\u521b\u5efa\u4e00\u4e2a\u8ba1\u7b97\u6bcf\u5217\u4e0e\u2019SPX\u2019\u5217\u6210\u5bf9\u5173\u8054\u7684\u51fd\u6570\uff1a spx_corr = lambda x: x.corrwith(x['SPX']) \u4e4b\u540e\uff0c\u4f7f\u7528 pct_change \u8ba1\u7b97 close-px \u767e\u5206\u6bd4\u7684\u53d8\u5316\uff1a rets = close_px.pct_change().dropna() # Percentage change between the current and a prior element. print(rets) # AAPL MSFT XOM SPX # 2003-01-03 0.006757 0.001421 0.000684 -0.000484 # 2003-01-06 0.000000 0.017975 0.024624 0.022474 # ... ... ... ... ... # 2011-10-14 0.033225 0.003311 0.022784 0.017380 # [2213 rows x 4 columns] \u6700\u540e\uff0c\u6309\u5e74\u5bf9\u767e\u5206\u6bd4\u53d8\u5316\u8fdb\u884c\u5206\u7ec4\uff0c\u53ef\u4ee5\u4f7f\u7528\u5355\u884c\u51fd\u6570\u4ece\u6bcf\u4e2a\u884c\u6807\u7b7e\u4e2d\u63d0\u53d6\u6bcf\u4e2a datetime \u6807\u7b7e\u7684 year \u5c5e\u6027\uff1a get_year = lambda x: x.year by_year = rets.groupby(get_year) result = by_year.apply(spx_corr) print(result) # AAPL MSFT XOM SPX # 2003 0.541124 0.745174 0.661265 1.0 # 2004 0.374283 0.588531 0.557742 1.0 # 2005 0.467540 0.562374 0.631010 1.0 # 2006 0.428267 0.406126 0.518514 1.0 # 2007 0.508118 0.658770 0.786264 1.0 # 2008 0.681434 0.804626 0.828303 1.0 # 2009 0.707103 0.654902 0.797921 1.0 # 2010 0.710105 0.730118 0.839057 1.0 # 2011 0.691931 0.800996 0.859975 1.0 \u53ef\u4ee5\u8ba1\u7b97\u5185\u90e8\u5217\u76f8\u5173\u6027\u3002\u8fd9\u91cc\u8ba1\u7b97\u4e86\u82f9\u679c\u548c\u5fae\u8f6f\u7684\u5e74\u5ea6\u76f8\u5173\u6027\uff1a result = by_year.apply(lambda g: g['AAPL'].corr(g['MSFT'])) print(result) # 2003 0.480868 # 2004 0.259024 # 2005 0.300093 # 2006 0.161735 # 2007 0.417738 # 2008 0.611901 # 2009 0.432738 # 2010 0.571946 # 2011 0.581987 # dtype: float64","title":"\u793a\u4f8b\uff1a\u5206\u7ec4\u52a0\u6743\u5e73\u5747\u548c\u76f8\u5173\u6027"},{"location":"python/DataAnalysis/ch07/#_15","text":"\u5b9a\u4e49\u4ee5\u4e0b regress \uff08\u56de\u5f52\uff09\u51fd\u6570\uff08\u4f7f\u7528 statsmodels \u8ba1\u91cf\u7ecf\u6d4e\u5b66\u5e93\uff09\uff0c\u8be5\u51fd\u6570\u5bf9\u6bcf\u4e2a\u6570\u636e\u5757\u6267\u884c\u666e\u901a\u6700\u5c0f\u4e8c\u4e58\uff08OLS\uff09\u56de\u5f52\uff1a def regress(data, yvar, xvars): Y = data[yvar] X = data[xvars] X['intercept'] = 1. result = sm.OLS(Y, X).fit() return result.params \u73b0\u5728\u8981\u8ba1\u7b97AAPL\u5728SPX\u56de\u62a5\u4e0a\u7684\u5e74\u5ea6\u7ebf\u6027\u56de\u5f52\uff1a result = by_year.apply(regress, 'AAPL', ['SPX']) print(result) # SPX intercept # 2003 1.195406 0.000710 # 2004 1.363463 0.004201 # 2005 1.766415 0.003246 # 2006 1.645496 0.000080 # 2007 1.198761 0.003438 # 2008 0.968016 -0.001110 # 2009 0.879103 0.002954 # 2010 1.052608 0.001261 # 2011 0.806605 0.001514","title":"\u793a\u4f8b\uff1a\u9010\u7ec4\u7ebf\u6027\u56de\u5f52"},{"location":"python/DataAnalysis/ch07/#_16","text":"","title":"\u6570\u636e\u900f\u89c6\u8868\u4e0e\u4ea4\u53c9\u8868"},{"location":"python/DataAnalysis/ch07/#_17","text":"\u6570\u636e\u900f\u89c6\u8868\u662f\u7535\u5b50\u8868\u683c\u7a0b\u5e8f\u548c\u5176\u4ed6\u6570\u636e\u5206\u6790\u8f6f\u4ef6\u4e2d\u5e38\u89c1\u7684\u6570\u636e\u6c47\u603b\u5de5\u5177\u3002 \u5b83\u6839\u636e\u4e00\u4e2a\u6216\u591a\u4e2a\u952e\u805a\u5408\u4e00\u5f20\u8868\u7684\u6570\u636e\uff0c\u5c06\u6570\u636e\u5728\u77e9\u5f62\u683c\u5f0f\u4e2d\u6392\u5217\uff0c\u5176\u4e2d\u4e00\u4e9b\u5206\u7ec4\u952e\u662f\u6cbf\u7740\u884c\u7684\uff0c\u53e6\u4e00\u4e9b\u662f\u6cbf\u7740\u5217\u7684\u3002 Python\u4e2d\u7684pandas\u900f\u89c6\u8868\u662f\u901a\u8fc7\u8fd9\u91cc\u6240\u4ecb\u7ecd\u7684groupby\u5de5\u5177\u4ee5\u53ca\u4f7f\u7528\u5206\u5c42\u7d22\u5f15\u7684\u91cd\u5851\u64cd\u4f5c\u5b9e\u73b0\u7684\u3002 DataFrame\u62e5\u6709\u4e00\u4e2a pivot_table \u65b9\u6cd5\uff0c\u5e76\u4e14\u8fd8\u6709\u8fd8\u4e00\u4e2a\u9876\u5c42\u7684 pandas.pivot_table \u51fd\u6570\u3002 \u9664\u4e86\u4e3a groupby \u63d0\u4f9b\u4e00\u4e2a\u65b9\u4fbf\u63a5\u53e3\uff0c pivot_table \u8fd8\u53ef\u4ee5\u6dfb\u52a0\u90e8\u5206\u603b\u8ba1\uff0c\u4e5f\u79f0\u4f5c\u8fb9\u8ddd\u3002 import pandas as pd import numpy as np \u6839\u636e\u4e0b\u9762\u7684\u5c0f\u8d39\u6570\u636e\u96c6\uff0c\u8ba1\u7b97\u4e00\u5f20\u5728\u884c\u65b9\u5411\u4e0a\u6309 day \u548c smoker \u6392\u5217\u7684\u5206\u7ec4\u5e73\u5747\u503c\uff08\u9ed8\u8ba4\u7684 pivot_table \u805a\u5408\u7c7b\u578b\uff09\u7684\u8868\u3002 pivot_table \u9009\u9879\uff1a values: \u9700\u8981\u805a\u5408\u7684\u5217\u540d\uff0c\u9ed8\u8ba4\u60c5\u51b5\u4e0b\u805a\u5408\u6240\u6709\u6570\u503c\u578b\u7684\u5217\u3002 index: \u5728\u7ed3\u679c\u900f\u89c6\u8868\u7684\u884c\u4e0a\u8fdb\u884c\u5206\u7ec4\u7684\u5217\u540d\u6216\u8005\u5176\u4ed6\u5206\u7ec4\u952e\u3002 tips = pd.read_csv('../examples/tips.csv') tips['tip_pct'] = tips['tip'] / (tips['total_bill'] - tips['tip']) \u6837\u672c\u6570\u636e\u3002 print(tips.head(5)) # total_bill tip smoker day time size tip_pct # 0 16.99 1.01 No Sun Dinner 2 0.063204 # 1 10.34 1.66 No Sun Dinner 3 0.191244 # 2 21.01 3.50 No Sun Dinner 3 0.199886 # 3 23.68 3.31 No Sun Dinner 2 0.162494 # 4 24.59 3.61 No Sun Dinner 4 0.172069 \u8ba1\u7b97\u5728\u884c\u65b9\u5411\u4e0a\u6309 day \u548c smoker \u6392\u5217\u7684\u5206\u7ec4\u5e73\u5747\u503c\u3002\u4e5f\u53ef\u4ee5\u76f4\u63a5\u4f7f\u7528 groupby \u5b9e\u73b0\u3002 result = tips.pivot_table(index=['day', 'smoker']) print(result) # size tip tip_pct total_bill # day smoker # Fri No 2.250000 2.812500 0.179740 18.420000 # Yes 2.066667 2.714000 0.216293 16.813333 # Sat No 2.555556 3.102889 0.190412 19.661778 # Yes 2.476190 2.875476 0.179833 21.276667 # Sun No 2.929825 3.167895 0.193617 20.506667 # Yes 2.578947 3.516842 0.322021 24.120000 # Thur No 2.488889 2.673778 0.193424 17.113111 # Yes 2.352941 3.030000 0.198508 19.190588 \u5728 tip_pct \u548c size \u4e0a\u8fdb\u884c\u805a\u5408\uff0c\u5e76\u6839\u636e time \u5206\u7ec4\u3002\u5c06\u628a smoker \u653e\u5165\u8868\u7684\u5217\uff0c\u800c\u5c06 day \u653e\u5165\u8868\u7684\u884c\uff1a result = tips.pivot_table( ['tip_pct', 'size'], index=['time', 'day'], columns='smoker' ) print(result) # size tip_pct # smoker No Yes No Yes # time day # Dinner Fri 2.000000 2.222222 0.162612 0.202545 # Sat 2.555556 2.476190 0.190412 0.179833 # Sun 2.929825 2.578947 0.193617 0.322021 # Thur 2.000000 NaN 0.190114 NaN # Lunch Fri 3.000000 1.833333 0.231125 0.236915 # Thur 2.500000 2.352941 0.193499 0.198508 \u901a\u8fc7\u4f20\u9012 margins=True \u6765\u6269\u5145\u8fd9\u4e2a\u8868\u6765\u5305\u542b\u90e8\u5206\u603b\u8ba1\u3002\u8fd9\u4f1a\u6dfb\u52a0 All \u884c\u548c\u5217\u6807\u7b7e\uff0c\u5176\u4e2d\u76f8\u5e94\u7684\u503c\u662f\u5355\u5c42\u4e2d\u6240\u6709\u6570\u636e\u7684\u5206\u7ec4\u7edf\u8ba1\u503c\u3002 \u8fd9\u91cc All \u7684\u503c\u662f\u5747\u503c\uff0c\u4e14\u8be5\u5747\u503c\u662f\u4e0d\u8003\u8651\u5438\u70df\u8005\u4e0e\u975e\u5438\u70df\u8005\uff08 All \u5217\uff09\u6216\u884c\u5206\u7ec4\u4e2d\u4efb\u4f55\u4e24\u7ea7\u7684\uff08 All \u884c\uff09\u3002 result = tips.pivot_table( ['tip_pct', 'size'], index=['time', 'day'], columns='smoker', margins=True ) print(result) # size tip_pct # smoker No Yes All No Yes All # time day # Dinner Fri 2.000000 2.222222 2.166667 0.162612 0.202545 0.192562 # Sat 2.555556 2.476190 2.517241 0.190412 0.179833 0.185305 # Sun 2.929825 2.578947 2.842105 0.193617 0.322021 0.225718 # Thur 2.000000 NaN 2.000000 0.190114 NaN 0.190114 # Lunch Fri 3.000000 1.833333 2.000000 0.231125 0.236915 0.236088 # Thur 2.500000 2.352941 2.459016 0.193499 0.198508 0.194895 # All 2.668874 2.408602 2.569672 0.192237 0.218176 0.202123 \u8981\u4f7f\u7528\u4e0d\u540c\u7684\u805a\u5408\u51fd\u6570\u65f6\uff0c\u5c06\u51fd\u6570\u4f20\u9012\u7ed9 aggfunc \u3002\u4f8b\u5982\uff0c count \u6216\u8005 len \u5c06\u7ed9\u51fa\u4e00\u5f20\u5206\u7ec4\u5927\u5c0f\u7684\u4ea4\u53c9\u8868\uff08\u8ba1\u6570\u6216\u51fa\u73b0\u9891\u7387\uff09\uff1a result = tips.pivot_table( ['tip_pct', 'size'], index=['time', 'day'], columns='smoker', aggfunc=len, margins=True ) print(result) # size tip_pct # smoker No Yes All No Yes All # time day # Dinner Fri 3.0 9.0 12 3.0 9.0 12 # Sat 45.0 42.0 87 45.0 42.0 87 # Sun 57.0 19.0 76 57.0 19.0 76 # Thur 1.0 NaN 1 1.0 NaN 1 # Lunch Fri 1.0 6.0 7 1.0 6.0 7 # Thur 44.0 17.0 61 44.0 17.0 61 # All 151.0 93.0 244 151.0 93.0 244 \u5bf9\u4e8e\u7a7a\u503c NA \uff0c\u4f20\u9012\u4e00\u4e2a fill_value \u3002 result = tips.pivot_table( ['tip_pct', 'size'], index=['time', 'day'], columns='smoker', aggfunc='mean', fill_value=0, margins=True ) print(result) # size tip_pct # smoker No Yes All No Yes All # time day # Dinner Fri 2.000000 2.222222 2.166667 0.162612 0.202545 0.192562 # Sat 2.555556 2.476190 2.517241 0.190412 0.179833 0.185305 # Sun 2.929825 2.578947 2.842105 0.193617 0.322021 0.225718 # Thur 2.000000 0.000000 2.000000 0.190114 0.000000 0.190114 # Lunch Fri 3.000000 1.833333 2.000000 0.231125 0.236915 0.236088 # Thur 2.500000 2.352941 2.459016 0.193499 0.198508 0.194895 # All 2.668874 2.408602 2.569672 0.192237 0.218176 0.202123","title":"\u6570\u636e\u900f\u89c6\u8868"},{"location":"python/DataAnalysis/ch07/#crosstab","text":"\u4ea4\u53c9\u8868\uff08\u7b80\u5199\u4e3acrosstab\uff09\u662f\u6570\u636e\u900f\u89c6\u8868\u7684\u4e00\u4e2a\u7279\u6b8a\u60c5\u51b5\uff0c\u8ba1\u7b97\u7684\u662f\u5206\u7ec4\u4e2d\u7684\u9891\u7387\u3002 crosstab \u7684\u524d\u4e24\u4e2a\u53c2\u6570\u53ef\u662f\u6570\u7ec4\u3001Series\u6216\u6570\u7ec4\u7684\u5217\u8868\u3002 sample = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10] nationality = ['USA', 'Japan', 'USA', 'Japan', 'Japan', 'Japan', 'USA', 'USA', 'Japan', 'USA'] handedness = ['Right-handed', 'Left-handed', 'Right-handed', 'Right-handed', 'Left-handed', 'Right-handed', 'Right-handed', 'Left-handed', 'Right-handed', 'Right-handed'] df = pd.DataFrame( { 'sample': sample, 'nationality': nationality, 'handedness': handedness } ) print(df) # sample nationality handedness # 0 1 USA Right-handed # 1 2 Japan Left-handed # 2 3 USA Right-handed # 3 4 Japan Right-handed # 4 5 Japan Left-handed # 5 6 Japan Right-handed # 6 7 USA Right-handed # 7 8 USA Left-handed # 8 9 Japan Right-handed # 9 10 USA Right-handed \u6309\u7167\u56fd\u7c4d\u548c\u60ef\u7528\u6027\u6765\u603b\u7ed3\u8fd9\u4e9b\u6570\u636e\uff0c\u53ef\u4ee5\u4f7f\u7528 pivot_table \u6765\u5b9e\u73b0\u8fd9\u4e2a\u529f\u80fd\uff0c\u4f46\u662f pandas.crosstable \u51fd\u6570\u66f4\u4e3a\u65b9\u4fbf\uff1a result = pd.crosstab(df.nationality, df.handedness, margins=True) print(result) # handedness Left-handed Right-handed All # nationality # Japan 2 3 5 # USA 1 4 5 # All 3 7 10 \u5728\u5c0f\u8d39\u6570\u636e\u4e2d\u53ef\u4ee5\u8fd9\u4e48\u505a\uff1a result = pd.crosstab(['tips.time', tips.day], tips.smoker, margins=True) print(result) # smoker No Yes All # row_0 day # tips.time Fri 4 15 19 # Sat 45 42 87 # Sun 57 19 76 # Thur 45 17 62 # All 151 93 244","title":"\u4ea4\u53c9\u8868\uff1acrosstab"},{"location":"python/DataAnalysis/ch08/","text":"\u65f6\u95f4\u5e8f\u5217 \u00b6 \u65e5\u671f\u548c\u65f6\u95f4\u6570\u636e\u7684\u7c7b\u578b\u53ca\u5de5\u5177 \u00b6 \u65f6\u95f4\u5e8f\u5217\u6570\u636e\u5728\u5f88\u591a\u9886\u57df\u90fd\u662f\u91cd\u8981\u7684\u7ed3\u6784\u5316\u6570\u636e\u5f62\u5f0f\u3002\u5728\u591a\u4e2a\u65f6\u95f4\u70b9\u89c2\u6d4b\u6216\u6d4b\u91cf\u7684\u6570\u636e\u5f62\u6210\u4e86\u65f6\u95f4\u5e8f\u5217\u3002 \u8bb8\u591a\u65f6\u95f4\u5e8f\u5217\u662f\u56fa\u5b9a\u9891\u7387\u7684\uff0c\u4e5f\u5c31\u662f\u8bf4\u6570\u636e\u662f\u6839\u636e\u76f8\u540c\u7684\u89c4\u5219\u5b9a\u671f\u51fa\u73b0\u7684\uff0c\u4f8b\u5982\u6bcf15\u79d2\u3001\u6bcf5\u5206\u949f\u6216\u6bcf\u67081\u6b21\u3002 \u65f6\u95f4\u5e8f\u5217\u4e5f\u53ef\u4ee5\u662f\u4e0d\u89c4\u5219\u7684\uff0c\u6ca1\u6709\u56fa\u5b9a\u7684\u65f6\u95f4\u5355\u4f4d\u6216\u5355\u4f4d\u95f4\u7684\u504f\u79fb\u91cf\u3002 \u5982\u4f55\u6807\u8bb0\u548c\u5f15\u7528\u65f6\u95f4\u5e8f\u5217\u6570\u636e\u53d6\u51b3\u4e8e\u5e94\u7528\u7a0b\u5e8f\uff0c\u65f6\u95f4\u5e8f\u5217\u5305\u62ec\uff1a \u65f6\u95f4\u6233\uff0c\u5177\u4f53\u7684\u65f6\u523b\u3002 \u56fa\u5b9a\u7684\u65f6\u95f4\u533a\u95f4\uff0c\u4f8b\u59822007\u76841\u6708\u6216\u6574\u4e2a2010\u5e74\u3002 \u65f6\u95f4\u95f4\u9694\uff0c\u7531\u5f00\u59cb\u548c\u7ed3\u675f\u65f6\u95f4\u6233\u8868\u793a\u3002\u65f6\u95f4\u533a\u95f4\u53ef\u4ee5\u88ab\u8ba4\u4e3a\u662f\u95f4\u9694\u7684\u7279\u6b8a\u60c5\u51b5\u3002 \u5b9e\u9a8c\u65f6\u95f4\u6216\u6d88\u8017\u65f6\u95f4\u3002\u6bcf\u4e2a\u65f6\u95f4\u6233\u662f\u76f8\u5bf9\u4e8e\u7279\u5b9a\u5f00\u59cb\u65f6\u95f4\u7684\u65f6\u95f4\u7684\u91cf\u5ea6\uff08\u4f8b\u5982\uff0c\u81ea\u4ece\u88ab\u653e\u7f6e\u5728\u70e4\u7bb1\u4e2d\u6bcf\u79d2\u70d8\u70e4\u7684\u997c\u5e72\u7684\u76f4\u5f84\uff09\u3002 \u76ee\u524d\u4e3b\u8981\u5173\u6ce8\u524d\u4e09\u7c7b\u4e2d\u7684\u65f6\u95f4\u5e8f\u5217\u3002 from datetime import datetime, timedelta import datetime as dt from dateutil.parser import parse import pandas as pd datetime \u00b6 datetime\u683c\u5f0f\u7b26\uff1a %a \u661f\u671f\u7684\u82f1\u6587\u5355\u8bcd\u7684\u7f29\u5199\uff1a\u5982\u661f\u671f\u4e00\uff0c \u5219\u8fd4\u56de Mon %A \u661f\u671f\u7684\u82f1\u6587\u5355\u8bcd\u7684\u5168\u62fc\uff1a\u5982\u661f\u671f\u4e00\uff0c\u8fd4\u56de Monday %b \u6708\u4efd\u7684\u82f1\u6587\u5355\u8bcd\u7684\u7f29\u5199\uff1a\u5982\u4e00\u6708\uff0c \u5219\u8fd4\u56de Jan %B \u6708\u4efd\u7684\u5f15\u6587\u5355\u8bcd\u7684\u7f29\u5199\uff1a\u5982\u4e00\u6708\uff0c \u5219\u8fd4\u56de January %c \u8fd4\u56dedatetime\u7684\u5b57\u7b26\u4e32\u8868\u793a\uff0c\u598203/08/15 23:01:26 %d \u8fd4\u56de\u7684\u662f\u5f53\u524d\u65f6\u95f4\u662f\u5f53\u524d\u6708\u7684\u7b2c\u51e0\u5929 %f \u5fae\u79d2\u7684\u8868\u793a\uff1a \u8303\u56f4: [0,999999] %H \u4ee524\u5c0f\u65f6\u5236\u8868\u793a\u5f53\u524d\u5c0f\u65f6 %I \u4ee512\u5c0f\u65f6\u5236\u8868\u793a\u5f53\u524d\u5c0f\u65f6 %m \u8fd4\u56de\u6708\u4efd \u8303\u56f4[0,12] %M \u8fd4\u56de\u5206\u949f\u6570 \u8303\u56f4 [0,59] %P \u8fd4\u56de\u662f\u4e0a\u5348\u8fd8\u662f\u4e0b\u5348\u2013AM or PM %S \u8fd4\u56de\u79d2\u6570 \u8303\u56f4 [0,61]\u3002\u3002\u3002\u624b\u518c\u8bf4\u660e\u7684 %U \u8fd4\u56de\u5f53\u5468\u662f\u5f53\u5e74\u7684\u7b2c\u51e0\u5468 \u4ee5\u5468\u65e5\u4e3a\u7b2c\u4e00\u5929 %W \u8fd4\u56de\u5f53\u5468\u662f\u5f53\u5e74\u7684\u7b2c\u51e0\u5468 \u4ee5\u5468\u4e00\u4e3a\u7b2c\u4e00\u5929 %w \u5f53\u5929\u5728\u5f53\u5468\u7684\u5929\u6570\uff0c\u8303\u56f4\u4e3a[0, 6]\uff0c6\u8868\u793a\u661f\u671f\u5929 %x \u65e5\u671f\u7684\u5b57\u7b26\u4e32\u8868\u793a \uff1a03/08/15 %X \u65f6\u95f4\u7684\u5b57\u7b26\u4e32\u8868\u793a \uff1a23:22:08 %y \u4e24\u4e2a\u6570\u5b57\u8868\u793a\u7684\u5e74\u4efd 15 %Y \u56db\u4e2a\u6570\u5b57\u8868\u793a\u7684\u5e74\u4efd 2015 %z \u4e0eutc\u65f6\u95f4\u7684\u95f4\u9694 \uff08\u5982\u679c\u662f\u672c\u5730\u65f6\u95f4\uff0c\u8fd4\u56de\u7a7a\u5b57\u7b26\u4e32\uff09 %Z \u65f6\u533a\u540d\u79f0\uff08\u5982\u679c\u662f\u672c\u5730\u65f6\u95f4\uff0c\u8fd4\u56de\u7a7a\u5b57\u7b26\u4e32\uff09 datestrs = ['2020/5/6', '2021/10/1'] # \u6ce8\u610f\u533a\u5206datetime\u6a21\u5757\u548cdatetime\u7c7b\uff0c\u540d\u5b57\u76f8\u540c\uff0c\u5bb9\u6613\u5f15\u8d77\u9519\u8bef\u3002 # \u6bd4\u5982datetime.datetime\u5c31\u62a5\u9519type object 'datetime.datetime' has no attribute 'datetime' print(datetime) # print(dt) # Python\u6807\u51c6\u5e93\u5305\u542b\u4e86\u65e5\u671f\u548c\u65f6\u95f4\u6570\u636e\u7684\u7c7b\u578b\u3002 datetime \u3001 time \u548c calendar \u6a21\u5757\u662f\u5f00\u59cb\u5904\u7406\u65f6\u95f4\u6570\u636e\u7684\u4e3b\u8981\u5185\u5bb9\u3002 datetime.datetime \u7c7b\u578b\uff0c\u6216\u7b80\u5199\u4e3a datetime \uff0c\u662f\u5e7f\u6cdb\u4f7f\u7528\u7684\u3002 now = datetime.now() print(now) # 2021-10-07 20:24:43.834293 result = dt.datetime(2021, 10, 7, 20, 26, 00, 72973) print(result) # 2021-10-07 20:26:00.072973 datetime \u65e2\u5b58\u50a8\u4e86\u65e5\u671f\uff0c\u4e5f\u5b58\u50a8\u4e86\u7ec6\u5316\u5230\u5fae\u79d2\u7684\u65f6\u95f4\u3002 timedelta \u8868\u793a\u4e24\u4e2a datetime \u5bf9\u8c61\u7684\u65f6\u95f4\u5dee\u3002 delta = datetime(2021, 10, 7) - datetime(2021, 9, 7) print(delta) # 30 days, 0:00:00 print(delta.days) # 30 print(delta.seconds) # 0 result = dt.timedelta(926, 56700) print(result) # 926 days, 15:45:00 \u53ef\u4ee5\u4e3a\u4e00\u4e2a datetime \u5bf9\u8c61\u52a0\u4e0a\uff08\u6216\u51cf\u53bb\uff09\u4e00\u4e2a timedelta \u6216\u5176\u6574\u6570\u500d\u6765\u4ea7\u751f\u4e00\u4e2a\u65b0\u7684 datetime \u5bf9\u8c61\u3002 start = datetime(2021, 10, 7) result = start + timedelta(12) print(result) # 2021-10-19 00:00:00 result = start - 2 * timedelta(5) print(result) # 2021-09-27 00:00:00 \u5b57\u7b26\u4e32\u4e0edatetime\u4e92\u76f8\u8f6c\u6362 \u00b6 \u4f7f\u7528 str \u65b9\u6cd5\u6216\u4f20\u9012\u4e00\u4e2a\u6307\u5b9a\u7684\u683c\u5f0f\u7ed9 strftime \u65b9\u6cd5\u6765\u5bf9 datetime \u5bf9\u8c61\u548cpandas\u7684 Timestamp \u5bf9\u8c61\u8fdb\u884c\u683c\u5f0f\u5316\u3002 stamp = datetime(2021, 10, 7) result = str(stamp) print(result) # 2021-10-07 00:00:00 \u4f7f\u7528 datetime.srtptime \u548c datetime \u683c\u5f0f\u7b26\uff0c\u628a\u5b57\u7b26\u4e32\u8f6c\u6362\u65e5\u671f\u3002 datetime.strptime \u662f\u5728\u5df2\u77e5\u683c\u5f0f\u7684\u60c5\u51b5\u4e0b\u8f6c\u6362\u65e5\u671f\u7684\u597d\u65b9\u5f0f\u3002 value = '2021-10-7' result = datetime.strptime(value, '%Y-%m-%d') print(result) # 2021-10-07 00:00:00 datestrs = ['2020/5/6', '2021/10/1'] result = [datetime.strptime(x, '%Y/%m/%d') for x in datestrs] print(result) # [datetime.datetime(2020, 5, 6, 0, 0), datetime.datetime(2021, 10, 1, 0, 0)] dateutil \u89e3\u6790\u901a\u7528\u65e5\u671f\u683c\u5f0f\uff1a print(parse('2020/5/6')) # 2020-05-06 00:00:00 print(parse('Jan 31, 2021 10:25 AM')) # 2021-01-31 10:25:00 print(parse('5/6/2021', dayfirst=True)) # \u65e5\u671f\u51fa\u73b0\u5728\u6708\u4efd\u4e4b\u524d # 2021-06-05 00:00:00 pandas\u4e3b\u8981\u662f\u9762\u5411\u5904\u7406\u65e5\u671f\u6570\u7ec4\u7684\uff0c\u65e0\u8bba\u662f\u7528\u4f5c\u8f74\u7d22\u5f15\u8fd8\u662f\u7528\u4f5cDataFrame\u4e2d\u7684\u5217\u3002 to_datetime \u65b9\u6cd5\u53ef\u4ee5\u8f6c\u6362\u5f88\u591a\u4e0d\u540c\u7684\u65e5\u671f\u8868\u793a\u683c\u5f0f\u3002 to_datetime \u65b9\u6cd5\u8fd8\u53ef\u4ee5\u5904\u7406\u90a3\u4e9b\u88ab\u8ba4\u4e3a\u662f\u7f3a\u5931\u503c\u7684\u503c\uff08None\u3001\u7a7a\u5b57\u7b26\u4e32\u7b49\uff09\u3002 NaT \uff08Not a time\uff09\u662fpandas\u4e2d\u65f6\u95f4\u6233\u6570\u636e\u7684\u662fnull\u503c\u3002 datestrs = ['2020/5/6 12:00:00', '2021/10/1 09:00:00'] result = pd.to_datetime(datestrs) print(result) # DatetimeIndex(['2020-05-06 12:00:00', '2021-10-01 09:00:00'], dtype='datetime64[ns]', freq=None) idx = pd.to_datetime(datestrs + [None]) print(idx) # DatetimeIndex(['2020-05-06 12:00:00', '2021-10-01 09:00:00', 'NaT'], dtype='datetime64[ns]', freq=None) print(idx[2]) # NaT print(pd.isnull(idx)) # [False False True] \u65f6\u95f4\u5e8f\u5217\u57fa\u7840 \u00b6 from datetime import datetime import pandas as pd import numpy as np DatetimeIndex \u00b6 pandas\u4e2d\u7684\u57fa\u7840\u65f6\u95f4\u5e8f\u5217\u79cd\u7c7b\u662f\u7531\u65f6\u95f4\u6233\u7d22\u5f15\u7684Series\uff0c\u5728pandas\u5916\u90e8\u5219\u901a\u5e38\u8868\u793a\u4e3aPython\u5b57\u7b26\u4e32\u6216 datetime \u5bf9\u8c61\u3002 \u6240\u6709\u4f7f\u7528 datetime \u5bf9\u8c61\u7684\u5730\u65b9\u90fd\u53ef\u4ee5\u7528 Timestamp \u3002 dates = [ datetime(2021, 10, 1), datetime(2021, 10, 3), datetime(2021, 10, 5), datetime(2021, 10, 7), datetime(2021, 10, 9), datetime(2021, 10, 11) ] data = np.random.rand(6) ts = pd.Series(data, index=dates) print(ts) # 2021-10-01 0.678297 # 2021-10-03 0.538631 # 2021-10-05 0.934413 # 2021-10-07 0.018534 # 2021-10-09 0.938441 # 2021-10-11 0.173329 # dtype: float64 \u8fd9\u4e9b datetime \u5bf9\u8c61\u88ab\u653e\u5165 DatetimeIndex \u4e2d\u3002 print(ts.index) # DatetimeIndex(['2021-10-01', '2021-10-03', '2021-10-05', '2021-10-07', # '2021-10-09', '2021-10-11'], # dtype='datetime64[ns]', freq=None) DatetimeIndex \u4e2d\u7684\u6807\u91cf\u503c\u662f pandas \u7684 Timestamp \u5bf9\u8c61\uff1a stamp = ts.index[0] print(stamp) # 2021-10-01 00:00:00 \u548c\u5176\u4ed6Series\u7c7b\u4f3c\uff0c\u4e0d\u540c\u7d22\u5f15\u7684\u65f6\u95f4\u5e8f\u5217\u4e4b\u95f4\u7684\u7b97\u672f\u8fd0\u7b97\u5728\u65e5\u671f\u4e0a\u81ea\u52a8\u5bf9\u9f50\uff1a print(ts + ts[::2]) # ts[::2]\u4f1a\u5c06ts\u4e2d\u6bcf\u9694\u4e00\u4e2a\u7684\u5143\u7d20\u9009\u62e9\u51fa # 2021-10-01 1.356595 # 2021-10-03 NaN # 2021-10-05 1.868825 # 2021-10-07 NaN # 2021-10-09 1.876883 # 2021-10-11 NaN # dtype: float64 pandas\u4f7f\u7528NumPy\u7684 datetime64 \u6570\u636e\u7c7b\u578b\u5728\u7eb3\u79d2\u7ea7\u7684\u5206\u8fa8\u7387\u4e0b\u5b58\u50a8\u65f6\u95f4\u6233 print(ts.index.dtype) # datetime64[ns] \u7d22\u5f15\u3001\u9009\u62e9\u3001\u5b50\u96c6 \u00b6 \u5f53\u57fa\u4e8e\u6807\u7b7e\u8fdb\u884c\u7d22\u5f15\u548c\u9009\u62e9\u65f6\uff0c\u65f6\u95f4\u5e8f\u5217\u7684\u884c\u4e3a\u548c\u5176\u4ed6\u7684pandas.Series\u7c7b\u4f3c\uff1a stamp = ts.index[2] print(ts[stamp]) # 0.9344125159374457 \u5bf9\u5e942021-10-05 \u4e5f\u53ef\u4ee5\u4f20\u9012\u4e00\u4e2a\u80fd\u89e3\u91ca\u4e3a\u65e5\u671f\u7684\u5b57\u7b26\u4e32\uff1a print(ts['10/9/2021']) print(ts['20211003']) \u5bf9\u4e00\u4e2a\u957f\u7684\u65f6\u95f4\u5e8f\u5217\uff0c\u53ef\u4ee5\u4f20\u9012\u4e00\u4e2a\u5e74\u4efd\u6216\u4e00\u4e2a\u5e74\u4efd\u548c\u6708\u4efd\u6765\u9009\u62e9\u6570\u636e\u5207\u7247\uff1a data = np.random.randn(1000) longer_ts = pd.Series( data, index=pd.date_range('1/1/2021', periods=1000) ) print(longer_ts) # 2021-01-01 -0.009192 # 2021-01-02 -1.079068 # 2021-01-03 -1.851176 # 2021-01-04 1.347109 # 2021-01-05 -0.236394 # ... # 2023-09-23 -1.317943 # 2023-09-24 0.201741 # 2023-09-25 0.442282 # 2023-09-26 0.176137 # 2023-09-27 1.146437 # Freq: D, Length: 1000, dtype: float64 \u5b57\u7b26\u4e32\u20192001\u2019\u88ab\u89e3\u91ca\u4e3a\u4e00\u4e2a\u5e74\u4efd\uff0c\u5e76\u9009\u62e9\u4e86\u76f8\u5e94\u7684\u65f6\u95f4\u533a\u95f4\u3002 print(longer_ts['2021']) # 2021-01-01 2.170411 # 2021-01-02 1.186933 # 2021-01-03 0.399262 # 2021-01-04 -1.042606 # 2021-01-05 2.082112 # ... # 2021-12-27 -0.988282 # 2021-12-28 0.598683 # 2021-12-29 2.770580 # 2021-12-30 -1.463262 # 2021-12-31 -1.642846 # Freq: D, Length: 365, dtype: float64 \u6307\u5b9a\u4e86\u5e74\u4efd\u548c\u6708\u4efd\u4e5f\u662f\u6709\u6548\u7684\u3002 print(longer_ts['2021-10']) # 2021-10-01 0.712265 # 2021-10-02 1.195221 # 2021-10-03 -1.930220 # 2021-10-04 -0.720816 # 2021-10-05 0.081777 # 2021-10-06 -0.037466 # 2021-10-07 3.737303 # 2021-10-08 1.620383 # 2021-10-09 0.990797 # 2021-10-10 0.507850 # 2021-10-11 0.846935 # 2021-10-12 0.996947 # 2021-10-13 -1.078558 # 2021-10-14 0.871832 # 2021-10-15 -0.591698 # 2021-10-16 -0.805463 # 2021-10-17 0.160528 # 2021-10-18 -0.028474 # 2021-10-19 2.305579 # 2021-10-20 -1.132288 # 2021-10-21 0.649980 # 2021-10-22 0.615327 # 2021-10-23 0.185108 # 2021-10-24 0.857199 # 2021-10-25 -1.473752 # 2021-10-26 -0.895161 # 2021-10-27 -0.432717 # 2021-10-28 0.734504 # 2021-10-29 1.892493 # 2021-10-30 0.456619 # 2021-10-31 -0.255288 # Freq: D, dtype: float64 \u4f7f\u7528 datetime \u5bf9\u8c61\u8fdb\u884c\u5207\u7247\u4e5f\u662f\u53ef\u4ee5\u7684\uff1a print(longer_ts[datetime(2023, 1, 6):]) # 2023-01-06 0.952591 # 2023-01-07 -0.900259 # 2023-01-08 0.925332 # 2023-01-09 0.173215 # 2023-01-10 -0.507791 # ... # 2023-09-23 -0.319989 # 2023-09-24 -1.105417 # 2023-09-25 -2.118769 # 2023-09-26 0.009420 # 2023-09-27 -0.310281 # Freq: D, Length: 265, dtype: float64 \u56e0\u4e3a\u5927\u90e8\u5206\u7684\u65f6\u95f4\u5e8f\u5217\u6570\u636e\u662f\u6309\u65f6\u95f4\u987a\u5e8f\u6392\u5e8f\u7684\uff0c\u53ef\u4ee5\u4f7f\u7528\u4e0d\u5305\u542b\u5728\u65f6\u95f4\u5e8f\u5217\u4e2d\u7684\u65f6\u95f4\u6233\u8fdb\u884c\u5207\u7247\uff0c\u4ee5\u6267\u884c\u8303\u56f4\u67e5\u8be2\uff1a print(longer_ts['2021/10/1':'2021/10/5']) # 2021-10-01 -0.591853 # 2021-10-02 -1.554564 # 2021-10-03 -0.712585 # 2021-10-04 -0.326657 # 2021-10-05 1.044887 # Freq: D, dtype: float64 \u4f7f\u7528 truncate \u5728\u4e24\u4e2a\u65e5\u671f\u95f4\u5bf9Series\u8fdb\u884c\u5207\u7247\uff1a print(longer_ts.truncate(after='2021/10/1')) # 2021-01-01 -0.906685 # 2021-01-02 -0.470732 # 2021-01-03 -0.041316 # 2021-01-04 -0.287356 # 2021-01-05 0.104268 # ... # 2021-09-27 -0.669198 # 2021-09-28 -2.222169 # 2021-09-29 -0.653814 # 2021-09-30 -0.625868 # 2021-10-01 0.872684 # Freq: D, Length: 274, dtype: float64 \u4e0a\u9762\u8fd9\u4e9b\u64cd\u4f5c\u4e5f\u90fd\u9002\u7528\u4e8eDataFrame\uff0c\u5e76\u5728\u5176\u884c\u4e0a\u8fdb\u884c\u7d22\u5f15\uff1a dates = pd.date_range('10/1/2020', periods=100, freq='W-WED') data = np.random.randn(100, 4) long_df = pd.DataFrame( data, index=dates, columns=['Colorado', 'Texas', 'New York', 'Ohio'] ) print(long_df) # Colorado Texas New York Ohio # 2020-10-07 -1.186789 2.020634 0.300076 -0.955234 # 2020-10-14 1.502838 0.965368 -0.797539 -0.292833 # ... ... ... ... ... # 2022-08-24 -0.253116 -0.263307 0.602425 0.370599 # 2022-08-31 0.907918 0.091939 0.789694 2.781535 # [100 rows x 4 columns] print(long_df.loc['10-2020']) # Colorado Texas New York Ohio # 2020-10-07 1.031616 -1.812038 -0.446577 0.395656 # 2020-10-14 -0.673167 0.198804 -0.439141 0.086004 # 2020-10-21 -1.139786 0.716820 0.006516 -0.284335 # 2020-10-28 -0.637939 1.647810 -0.750786 0.140637 \u542b\u6709\u91cd\u590d\u7d22\u5f15\u7684\u65f6\u95f4\u5e8f\u5217 \u00b6 \u5728\u67d0\u4e9b\u5e94\u7528\u4e2d\uff0c\u53ef\u80fd\u4f1a\u6709\u591a\u4e2a\u6570\u636e\u89c2\u5bdf\u503c\u843d\u5728\u7279\u5b9a\u7684\u65f6\u95f4\u6233\u4e0a\u3002\u4e0b\u9762\u662f\u4e2a\u4f8b\u5b50\uff1a dates = pd.DatetimeIndex( ['2021/1/1', '2021/1/2', '2021/1/2', '2021/1/2', '2021/1/3'] ) dup_ts = pd.Series( np.arange(5), index=dates ) print(dup_ts) # 2021-01-01 0 # 2021-01-02 1 # 2021-01-02 2 # 2021-01-02 3 # 2021-01-03 4 # dtype: int64 \u901a\u8fc7\u68c0\u67e5\u7d22\u5f15\u7684 is_unique \u5c5e\u6027\uff0c\u53ef\u4ee5\u770b\u51fa\u7d22\u5f15\u5e76\u4e0d\u662f\u552f\u4e00\u7684\uff1a print(dup_ts.index.is_unique) # False \u5bf9\u4e0a\u9762\u7684Series\u8fdb\u884c\u7d22\u5f15\uff0c\u7ed3\u679c\u662f\u6807\u91cf\u503c\u8fd8\u662fSeries\u5207\u7247\u53d6\u51b3\u4e8e\u662f\u5426\u6709\u65f6\u95f4\u6233\u662f\u91cd\u590d\u7684\uff1a result = dup_ts['2021/1/3'] print(result) # 4 result = dup_ts['2021/1/2'] print(result) # 2021-01-02 1 # 2021-01-02 2 # 2021-01-02 3 # dtype: int64 \u5047\u8bbe\u60f3\u8981\u805a\u5408\u542b\u6709\u975e\u552f\u4e00\u65f6\u95f4\u6233\u7684\u6570\u636e\u3002\u4e00\u79cd\u65b9\u5f0f\u5c31\u662f\u4f7f\u7528 groupby \u5e76\u4f20\u9012 level=0 \uff1a grouped = dup_ts.groupby(level=0) result = grouped.mean() print(result) # 2021-01-01 0.0 # 2021-01-02 2.0 # 2021-01-03 4.0 # dtype: float64 result = grouped.count() print(result) # 2021-01-01 1 # 2021-01-02 3 # 2021-01-03 1 # dtype: int64 \u65e5\u671f\u8303\u56f4\u3001\u9891\u7387\u548c\u79fb\u4f4d \u00b6 from datetime import datetime, timedelta import pandas as pd import numpy as np from pandas.tseries.offsets import Hour, Minute, Day, MonthEnd pandas\u7684\u901a\u7528\u65f6\u95f4\u5e8f\u5217\u662f\u4e0d\u89c4\u5219\u7684\uff0c\u5373\u65f6\u95f4\u5e8f\u5217\u7684\u9891\u7387\u4e0d\u662f\u56fa\u5b9a\u7684\u3002 \u4f46\u6709\u65f6\u9700\u8981\u5904\u7406\u56fa\u5b9a\u9891\u7387\u7684\u573a\u666f\uff0c\u4f8b\u5982\u6bcf\u65e5\u7684\u3001\u6bcf\u6708\u7684\u6216\u6bcf15\u5206\u949f\u7684\u65f6\u95f4\u5e8f\u5217\u6570\u636e\u3002 \u53ef\u4ee5\u901a\u8fc7\u8c03\u7528resample\u65b9\u6cd5\u5c06\u6837\u672c\u65f6\u95f4\u5e8f\u5217\u8f6c\u6362\u4e3a\u56fa\u5b9a\u7684\u6bcf\u65e5\u9891\u7387\u6570\u636e\u3002 \u5728\u9891\u7387\u95f4\u8f6c\u6362\uff0c\u53c8\u79f0\u4e3a\u91cd\u65b0\u91c7\u6837\u3002 dates = [ datetime(2021, 10, 1), datetime(2021, 10, 3), datetime(2021, 10, 5), datetime(2021, 10, 7), datetime(2021, 10, 9), datetime(2021, 10, 11) ] data = np.random.rand(6) ts = pd.Series(data, index=dates) print(ts) # 2021-10-01 0.956685 # 2021-10-03 0.817168 # 2021-10-05 0.275543 # 2021-10-07 0.614226 # 2021-10-09 0.061377 # 2021-10-11 0.357080 # dtype: float64 resampler = ts.resample('D') # \u5b57\u7b26\u4e32\u2019D\u2019\u88ab\u89e3\u91ca\u4e3a\u6bcf\u65e5\u9891\u7387 print(resampler) # DatetimeIndexResampler [freq=, axis=0, closed=left, label=left, convention=start, origin=start_day] \u751f\u6210\u65e5\u671f\u8303\u56f4 \u00b6 pandas.date_range \u662f\u7528\u4e8e\u6839\u636e\u7279\u5b9a\u9891\u7387\u751f\u6210\u6307\u5b9a\u957f\u5ea6\u7684 DatetimeIndex \u3002 \u9ed8\u8ba4\u60c5\u51b5\u4e0b\uff0c date_range \u751f\u6210\u7684\u662f\u6bcf\u65e5\u7684\u65f6\u95f4\u6233\u3002\u5982\u679c\u53ea\u4f20\u9012\u4e00\u4e2a\u8d77\u59cb\u6216\u7ed3\u5c3e\u65e5\u671f\uff0c\u4f60\u5fc5\u987b\u4f20\u9012\u4e00\u4e2a\u7528\u4e8e\u751f\u6210\u8303\u56f4\u7684\u6570\u5b57\u3002 \u5f00\u59cb\u65e5\u671f\u548c\u7ed3\u675f\u65e5\u671f\u4e25\u683c\u5b9a\u4e49\u4e86\u751f\u6210\u65e5\u671f\u7d22\u5f15\u7684\u8fb9\u754c\u3002 index = pd.date_range('2021/1/1', '2021/1/30') print(index) index = pd.date_range(start='2021/1/1', periods=30) print(index) index = pd.date_range(end='2021/1/30', periods=30) print(index) # DatetimeIndex(['2021-01-01', '2021-01-02', '2021-01-03', '2021-01-04', # '2021-01-05', '2021-01-06', '2021-01-07', '2021-01-08', # '2021-01-09', '2021-01-10', '2021-01-11', '2021-01-12', # '2021-01-13', '2021-01-14', '2021-01-15', '2021-01-16', # '2021-01-17', '2021-01-18', '2021-01-19', '2021-01-20', # '2021-01-21', '2021-01-22', '2021-01-23', '2021-01-24', # '2021-01-25', '2021-01-26', '2021-01-27', '2021-01-28', # '2021-01-29', '2021-01-30'], # dtype='datetime64[ns]', freq='D') \u9ed8\u8ba4\u60c5\u51b5\u4e0b\uff0c date_range \u4fdd\u7559\u5f00\u59cb\u6216\u7ed3\u675f\u65f6\u95f4\u6233\u7684\u65f6\u95f4\uff08\u5982\u679c\u6709\u7684\u8bdd\uff09\u3002 normalize \u9009\u9879\u53ef\u4ee5\u5b9e\u73b0\u751f\u6210\u7684\u662f\u6807\u51c6\u5316\u4e3a\u96f6\u70b9\u7684\u65f6\u95f4\u6233\u3002 index = pd.date_range('2021/1/1 12:56:30', periods=5) print(index) # DatetimeIndex(['2021-01-01 12:56:30', '2021-01-02 12:56:30', # '2021-01-03 12:56:30', '2021-01-04 12:56:30', # '2021-01-05 12:56:30'], # dtype='datetime64[ns]', freq='D') index = pd.date_range('2021/1/1 12:56:30', periods=5, normalize=True) print(index) # DatetimeIndex(['2021-01-01', '2021-01-02', '2021-01-03', '2021-01-04', # '2021-01-05'], # dtype='datetime64[ns]', freq='D') Pandas\u65f6\u95f4\u5e8f\u5217\uff1a\u9891\u7387\u548c\u65e5\u671f\u504f\u79fb\u91cf\u3002 pandas\u4e2d\u7684\u9891\u7387\u662f\u7531\u4e00\u4e2a\u57fa\u7840\u9891\u7387(\u4f8b\u5982\u201c\u65e5\u201d\u3001\u201c\u6708\u201d)\u548c\u4e00\u4e2a\u4e58\u6570\u7ec4\u6210\u3002 \u57fa\u7840\u9891\u7387\u901a\u5e38\u4ee5\u4e00\u4e2a\u5b57\u7b26\u4e32\u522b\u540d\u8868\u793a\uff0c\u6bd4\u5982\u201cD\u201d\u8868\u793a\u65e5\uff0c\u201cM\u201d\u8868\u793a\u6708\u3002 \u5bf9\u4e8e\u6bcf\u4e2a\u57fa\u7840\u9891\u7387\uff0c\u90fd\u6709\u4e00\u4e2a\u88ab\u79f0\u4e3a\u65e5\u671f\u504f\u79fb\u91cf(dateoffset)\u7684\u5bf9\u8c61\u4e0e\u4e4b\u5bf9\u5e94\uff0c\u6bd4\u5982\u65e5\u671f\u504f\u79fb\u91cf Hour \u5bf9\u5e94\u7684\u9891\u7387\u662f H \u3002 \u5e38\u7528\u9891\u7387\u4e0e\u65e5\u671f\u504f\u79fb\u91cf\u3002 \u9891\u7387 \u65e5\u671f\u504f\u79fb\u91cf \u8bf4\u660e D Day \u65e5\u5386\u65e5 B BusinessDay \u5de5\u4f5c\u65e5 H Hour \u5c0f\u65f6 T/min Minute \u5206 S Second \u79d2 L/ms Milli \u6beb\u79d2 U Micro \u5fae\u79d2 M MonthEnd \u6bcf\u6708\u6700\u540e\u4e00\u4e2a\u65e5\u5386\u65e5 BM BusinessMonthEnd \u6bcf\u6708\u6700\u540e\u4e00\u4e2a\u5de5\u4f5c\u65e5 MS MonthBegin \u6bcf\u6708\u7b2c\u4e00\u4e2a\u65e5\u5386\u65e5 BMS BussinessMonthBegin \u6bcf\u6708\u7b2c\u4e00\u4e2a\u5de5\u4f5c\u65e5 W-MON, W-TUE, ... Week \u6307\u5b9a\u661f\u671f\u51e0(MON,TUE,WED,THU,FRI,SAT,SUN) WOM-1MON,WOM-2MON, ... WeekOfMonth \u4ea7\u751f\u6bcf\u6708\u7b2c\u4e00,\u7b2c\u4e8c,\u7b2c\u4e09\u6216\u7b2c\u56db\u5468\u7684\u661f\u671f\u51e0\u3002\u4f8b\u5982WOM-3FRI\u8868\u793a\u6bcf\u6708\u7b2c3\u4e2a\u661f\u671f\u4e94 Q-JAN,Q-FEB, ... QuarterEnd \u4ee5\u6307\u5b9a\u6708\u4efd\u7ed3\u675f\u7684\u5e74\u5ea6\uff0c\u6bcf\u5b63\u5ea6\u6700\u540e\u4e00\u4e2a\u6708\u7684\u6700\u540e\u4e00\u4e2a\u65e5\u5386\u65e5 BQ-JAN,BQ-FEB, ... BusinessQuarterEnd \u4ee5\u6307\u5b9a\u6708\u4efd\u7ed3\u675f\u7684\u5e74\u5ea6\uff0c\u6bcf\u5b63\u5ea6\u6700\u540e\u4e00\u4e2a\u6708\u7684\u6700\u540e\u4e00\u4e2a\u5de5\u4f5c\u65e5 QS-JAN,QS-FEB, ... QuarterBegin \u4ee5\u6307\u5b9a\u6708\u4efd\u7ed3\u675f\u7684\u5e74\u5ea6\uff0c\u6bcf\u5b63\u5ea6\u6700\u540e\u4e00\u4e2a\u6708\u7684\u7b2c\u4e00\u4e2a\u65e5\u5386\u65e5 BQS-JAN,BQS-FEB, ... BusinessQuarterBegin \u4ee5\u6307\u5b9a\u6708\u4efd\u7ed3\u675f\u7684\u5e74\u5ea6\uff0c\u6bcf\u5b63\u5ea6\u6700\u540e\u4e00\u4e2a\u6708\u7684\u7b2c\u4e00\u4e2a\u5de5\u4f5c\u65e5 A-JAN,A-FEB, ... YearEnd \u6bcf\u5e74\u6307\u5b9a\u6708\u4efd\u7684\u6700\u540e\u4e00\u4e2a\u65e5\u5386\u65e5 BA-JAN,BA-FEB, ... BusinessYearEnd \u6bcf\u5e74\u6307\u5b9a\u6708\u4efd\u7684\u6700\u540e\u4e00\u4e2a\u5de5\u4f5c\u65e5 AS-JAN,AS-FEB, ... YearBegin \u6bcf\u5e74\u6307\u5b9a\u6708\u4efd\u7684\u7b2c\u4e00\u4e2a\u65e5\u5386\u65e5 BAS-JAN,BAS-FEB, ... BusinessYearBegin \u6bcf\u5e74\u6307\u5b9a\u6708\u4efd\u7684\u7b2c\u4e00\u4e2a\u5de5\u4f5c\u65e5 \u9891\u7387\u548c\u65e5\u671f\u504f\u7f6e \u00b6 pandas\u4e2d\u7684\u9891\u7387\u662f\u7531\u57fa\u7840\u9891\u7387\u548c\u500d\u6570\u7ec4\u6210\u7684\u3002 \u57fa\u7840\u9891\u7387\u901a\u5e38\u4f1a\u6709\u5b57\u7b26\u4e32\u522b\u540d\uff0c\u4f8b\u5982 M \u4ee3\u8868\u6bcf\u6708\uff0c H \u4ee3\u8868\u6bcf\u5c0f\u65f6\u3002 \u5bf9\u4e8e\u6bcf\u4e2a\u57fa\u7840\u9891\u7387\uff0c\u90fd\u6709\u4e00\u4e2a\u5bf9\u8c61\u53ef\u4ee5\u88ab\u7528\u4e8e\u5b9a\u4e49\u65e5\u671f\u504f\u7f6e\u3002 \u4f8b\u5982\uff0c\u6bcf\u5c0f\u65f6\u7684\u9891\u7387\u53ef\u4ee5\u4f7f\u7528 Hour \u7c7b\u6765\u8868\u793a\uff1a ```hour = Hour() print(hour) \u00b6 \u53ef\u4ee5\u4f20\u9012\u4e00\u4e2a\u6574\u6570\u6765\u5b9a\u4e49\u504f\u7f6e\u91cf\u7684\u500d\u6570\uff1a four_hours = Hour(4) print(four_hours) <4 * Hours> \u00b6 \u5728\u5927\u591a\u6570\u5e94\u7528\u4e2d\uff0c\u4e0d\u9700\u8981\u663e\u5f0f\u5730\u521b\u5efa\u8fd9\u4e9b\u5bf9\u8c61\uff0c\u800c\u662f\u4f7f\u7528\u5b57\u7b26\u4e32\u522b\u540d\uff0c\u5982`H`\u6216`4H`\u3002\u5728\u57fa\u7840\u9891\u7387\u524d\u653e\u4e00\u4e2a\u6574\u6570\u5c31\u53ef\u4ee5\u751f\u6210\u500d\u6570\uff1a ts = pd.date_range('2021/1/1', '2021/\u00bd 23:59', freq='4h') print(ts) DatetimeIndex(['2021-01-01 00:00:00', '2021-01-01 04:00:00', \u00b6 '2021-01-01 08:00:00', '2021-01-01 12:00:00', \u00b6 '2021-01-01 16:00:00', '2021-01-01 20:00:00', \u00b6 '2021-01-02 00:00:00', '2021-01-02 04:00:00', \u00b6 '2021-01-02 08:00:00', '2021-01-02 12:00:00', \u00b6 '2021-01-02 16:00:00', '2021-01-02 20:00:00'], \u00b6 dtype='datetime64[ns]', freq='4H') \u00b6 \u591a\u4e2a\u504f\u7f6e\u53ef\u4ee5\u901a\u8fc7\u52a0\u6cd5\u8fdb\u884c\u8054\u5408\uff1a print(Hour(2) + Minute(30)) <150 * Minutes> \u00b6 \u7c7b\u4f3c\u5730\uff0c\u53ef\u4ee5\u4f20\u9012\u9891\u7387\u5b57\u7b26\u4e32\uff1a ts = pd.date_range('2021/1/1', '2021/1/1 23:59', freq='4h30min') print(ts) DatetimeIndex(['2021-01-01 00:00:00', '2021-01-01 04:30:00', \u00b6 '2021-01-01 09:00:00', '2021-01-01 13:30:00', \u00b6 '2021-01-01 18:00:00', '2021-01-01 22:30:00'], \u00b6 dtype='datetime64[ns]', freq='270T') \u00b6 \u6709\u4e9b\u9891\u7387\u63cf\u8ff0\u70b9\u7684\u65f6\u95f4\u5e76\u4e0d\u662f\u5747\u5300\u5206\u9694\u7684\u3002\u4f8b\u5982\uff0c`M`\uff08\u65e5\u5386\u6708\u672b\uff09\u548c`BM`\uff08\u6708\u5185\u6700\u540e\u5de5\u4f5c\u65e5\uff09\u53d6\u51b3\u4e8e\u5f53\u6708\u5929\u6570\uff0c\u6708\u672b\u662f\u5426\u662f\u5468\u672b\u3002\u6211\u4eec\u5c06\u8fd9\u4e9b\u65e5\u671f\u79f0\u4e3a\u951a\u5b9a\u504f\u7f6e\u91cf\u3002 #### \u6708\u4e2d\u67d0\u661f\u671f\u7684\u65e5\u671f \"\u6708\u4e2d\u67d0\u661f\u671f\"\uff08week of month \uff09\u7684\u65e5\u671f\u662f\u4e00\u4e2a\u6709\u7528\u7684\u9891\u7387\u7c7b\uff0c\u4ee5`WOM`\u5f00\u59cb\u3002 rng = pd.date_range('2021-1-1', '2021-9-1', freq='WOM-3FRI') # \u6bcf\u6708\u7b2c\u4e09\u4e2a\u661f\u671f\u4e94 print(rng) DatetimeIndex(['2021-01-15', '2021-02-19', '2021-03-19', '2021-04-16', \u00b6 '2021-05-21', '2021-06-18', '2021-07-16', '2021-08-20'], \u00b6 dtype='datetime64[ns]', freq='WOM-3FRI') \u00b6 ### \u79fb\u4f4d\uff08\u524d\u5411\u548c\u540e\u5411\uff09\u65e5\u671f \"\u79fb\u4f4d\"\u662f\u6307\u5c06\u65e5\u671f\u6309\u65f6\u95f4\u5411\u524d\u79fb\u52a8\u6216\u5411\u540e\u79fb\u52a8\u3002 Series\u548cDataFrame\u90fd\u6709\u4e00\u4e2a`shift`\u65b9\u6cd5\u7528\u4e8e\u8fdb\u884c\u7b80\u5355\u7684\u524d\u5411\u6216\u540e\u5411\u79fb\u4f4d\uff0c\u800c\u4e0d\u6539\u53d8\u7d22\u5f15\u3002 \u8fdb\u884c\u79fb\u4f4d\u65f6\uff0c\u4f1a\u5728\u65f6\u95f4\u5e8f\u5217\u7684\u8d77\u59cb\u4f4d\u6216\u7ed3\u675f\u4f4d\u5f15\u5165\u7f3a\u5931\u503c\u3002 data = [0.882972, 1.363282, -0.687750, -0.048117] ts = pd.Series(data, index=pd.date_range('2021-1-1', periods=4, freq='M')) print(ts) 2021-01-31 0.882972 \u00b6 2021-02-28 1.363282 \u00b6 2021-03-31 -0.687750 \u00b6 2021-04-30 -0.048117 \u00b6 Freq: M, dtype: float64 \u00b6 print(ts.shift(2)) 2021-01-31 NaN \u00b6 2021-02-28 NaN \u00b6 2021-03-31 0.882972 \u00b6 2021-04-30 1.363282 \u00b6 Freq: M, dtype: float64 \u00b6 print(ts.shift(-2)) 2021-01-31 -0.687750 \u00b6 2021-02-28 -0.048117 \u00b6 2021-03-31 NaN \u00b6 2021-04-30 NaN \u00b6 Freq: M, dtype: float64 \u00b6 `shift`\u5e38\u7528\u4e8e\u8ba1\u7b97\u65f6\u95f4\u5e8f\u5217\u6216DataFrame\u591a\u5217\u65f6\u95f4\u5e8f\u5217\u7684\u767e\u5206\u6bd4\u53d8\u5316\uff1a print(ts/ts.shift(1)) 2021-01-31 NaN \u00b6 2021-02-28 1.543970 \u00b6 2021-03-31 -0.504481 \u00b6 2021-04-30 0.069963 \u00b6 Freq: M, dtype: float64 \u00b6 print(ts/ts.shift(1) - 1) 2021-01-31 NaN \u00b6 2021-02-28 0.543970 \u00b6 2021-03-31 -1.504481 \u00b6 2021-04-30 -0.930037 \u00b6 Freq: M, dtype: float64 \u00b6 \u5982\u679c\u9891\u7387\u662f\u5df2\u77e5\u7684\uff0c\u5219\u53ef\u4ee5\u5c06\u9891\u7387\u4f20\u9012\u7ed9`shift`\u6765\u63a8\u79fb\u65f6\u95f4\u6233\uff1a print(ts.shift(2, freq='M')) # \u539f\u59cb\u6570\u636e\u7684\u201c\u6708\u201c\u589e\u52a0\u4e86\u504f\u79fb\u503c 2021-03-31 0.882972 \u00b6 2022021-10-31 00:00:001-04-30 1.363282 \u00b6 2021-05-31 -0.687750 \u00b6 2021-06-30 -0.048117 \u00b6 Freq: M, dtype: float64 \u00b6 print(ts.shift(2, freq='D')) # \u539f\u59cb\u6570\u636e\u7684\u201c\u65e5\u201c\u589e\u52a0\u4e86\u504f\u79fb\u503c 2021-02-02 0.882972 \u00b6 2021-03-02 1.363282 \u00b6 2021-04-02 -0.687750 \u00b6 2021-05-02 -0.048117 \u00b6 dtype: float64 \u00b6 print(ts.shift(2, freq='90T')) # \u539f\u59cb\u6570\u636e\u7684\u201c\u5c0f\u65f6\u201c\u589e\u52a0\u4e86\u504f\u79fb\u503c 2021-01-31 03:00:00 0.882972 \u00b6 2021-02-28 03:00:00 1.363282 \u00b6 2021-03-31 03:00:00 -0.687750 \u00b6 2021-04-30 03:00:00 -0.048117 \u00b6 dtype: float64 \u00b6 #### \u4f7f\u7528\u504f\u7f6e\u8fdb\u884c\u79fb\u4f4d\u65e5\u671f pandas\u65e5\u671f\u504f\u7f6e\u4e5f\u53ef\u4ee5\u4f7f\u7528`datetime`\u6216`Timestamp`\u5bf9\u8c61\u5b8c\u6210\uff1a now = datetime(2021, 10, 9) print(now) 2021-10-09 00:00:00 \u00b6 print(now + 3 * Day()) 2021-10-12 00:00:00 \u00b6 \u951a\u5b9a\u504f\u7f6e\u53ef\u4ee5\u4f7f\u7528`rollforward`\u548c`rollback`\u5206\u522b\u663e\u5f0f\u5730\u5c06\u65e5\u671f\u5411\u524d\u6216\u5411\u540e\"\u6eda\u52a8\"\u3002 \u5982\u679c\u6dfb\u52a0\u4e86\u4e00\u4e2a\u951a\u5b9a\u504f\u7f6e\u91cf\uff0c\u6bd4\u5982`MonthEnd`\uff0c\u6839\u636e\u9891\u7387\u89c4\u5219\uff0c\u7b2c\u4e00\u4e2a\u589e\u91cf\u4f1a\u5c06\u65e5\u671f\u201c\u524d\u6eda\u201d\u5230\u4e0b\u4e00\u4e2a\u65e5\u671f\uff1a print(now + MonthEnd()) # \u201c\u524d\u6eda\u201d\u5230\u5f53\u524d\u6708\u7684\u6708\u5e95 2021-10-31 00:00:00 \u00b6 print(now + MonthEnd(2)) # \u6ce8\u610f\u8fd9\u91cc\u7684\u5e8f\u5217\u53f7\uff0c\u5f53\u524d\u6708\u662f1,\u4e0b\u4e2a\u6708\u662f2 2021-11-30 00:00:00 \u00b6 offset = MonthEnd() print(offset.rollback(now)) 2021-09-30 00:00:00 \u00b6 print(offset.rollforward(now)) 2021-10-31 00:00:00 \u00b6 \u5c06\u79fb\u4f4d\u65b9\u6cd5\u4e0e`groupby`\u4e00\u8d77\u4f7f\u7528\u662f\u65e5\u671f\u504f\u7f6e\u7684\u4e00\u79cd\u521b\u9020\u6027\u7528\u6cd5\uff1a ts = pd.Series( np.random.randn(20), index=pd.date_range('2021/1/1', periods=20, freq='4d') ) print(ts) 2021-01-01 0.674348 \u00b6 2021-01-05 -1.437803 \u00b6 2021-01-09 -0.079218 \u00b6 2021-01-13 -1.444890 \u00b6 2021-01-17 0.643279 \u00b6 2021-01-21 1.089965 \u00b6 2021-01-25 0.021876 \u00b6 2021-01-29 0.692138 \u00b6 2021-02-02 0.833496 \u00b6 2021-02-06 1.082616 \u00b6 2021-02-10 -0.729415 \u00b6 2021-02-14 0.271186 \u00b6 2021-02-18 -1.416218 \u00b6 2021-02-22 -0.780402 \u00b6 2021-02-26 -0.113773 \u00b6 2021-03-02 2.095338 \u00b6 2021-03-06 -0.302612 \u00b6 2021-03-10 1.113632 \u00b6 2021-03-14 -1.314581 \u00b6 2021-03-18 0.947746 \u00b6 Freq: 4D, dtype: float64 \u00b6 print(ts.groupby(offset.rollforward).mean()) # \u524d\u6eda\u81f3\u5f53\u6708\u6708\u5e95\uff0c\u8ba1\u7b97\u5f53\u6708\u5e73\u5747\u503c 2021-01-31 0.019962 \u00b6 2021-02-28 -0.121787 \u00b6 2021-03-31 0.507905 \u00b6 dtype: float64 \u00b6 \u4f7f\u7528resample\u662f\u66f4\u7b80\u5355\u66f4\u5feb\u6377\u7684\u65b9\u6cd5 \u00b6 print(ts.resample('M').mean()) 2021-01-31 0.019962 \u00b6 2021-02-28 -0.121787 \u00b6 2021-03-31 0.507905 \u00b6 Freq: M, dtype: float64 \u00b6 ## \u65f6\u533a\u5904\u7406 \u65f6\u533a\u901a\u5e38\u88ab\u8868\u793a\u4e3aUTC\u7684\u504f\u7f6e\u3002 \u5728Python\u8bed\u8a00\u4e2d\uff0c\u65f6\u533a\u4fe1\u606f\u6765\u6e90\u4e8e\u7b2c\u4e09\u65b9\u5e93pytz\uff08\u53ef\u4ee5\u4f7f\u7528pip\u6216conda\u5b89\u88c5\uff09\uff0c\u5176\u4e2d\u516c\u5f00\u4e86Olson\u6570\u636e\u5e93\uff0c\u8fd9\u662f\u4e16\u754c\u65f6\u533a\u4fe1\u606f\u7684\u6c47\u7f16\u3002 pandas\u5c01\u88c5\u4e86pytz\u7684\u529f\u80fd\u3002 from datetime import datetime, timedelta import pandas as pd import numpy as np from pandas.tseries.offsets import Hour, Minute, Day, MonthEnd import pytz #### common_timezones tz = pytz.common_timezones[-5:] # \u8bfb\u53d6common_timezones\u8fd9\u4e2a\u5217\u8868\u7684\u6700\u540e5\u4e2a\u5143\u7d20 print(tz) ['US/Eastern', 'US/Hawaii', 'US/Mountain', 'US/Pacific', 'UTC'] \u00b6 \u8981\u83b7\u5f97pytz\u7684\u65f6\u533a\u5bf9\u8c61\uff0c\u53ef\u4f7f\u7528pytz.timezone\uff1a tz = pytz.timezone('Asia/Shanghai') print(tz) #### \u65f6\u533a\u7684\u672c\u5730\u5316\u548c\u8f6c\u6362 \u9ed8\u8ba4\u60c5\u51b5\u4e0b\uff0cpandas\u4e2d\u7684\u65f6\u95f4\u5e8f\u5217\u662f\u65f6\u533a\u7b80\u5355\u578b\u7684\u3002 rng = pd.date_range('2021/1/1 9:30', periods=6, freq='D') ts = pd.Series(np.random.randn(len(rng)), index=rng) print(rng) DatetimeIndex(['2021-01-01 09:30:00', '2021-01-02 09:30:00', \u00b6 '2021-01-03 09:30:00', '2021-01-04 09:30:00', \u00b6 '2021-01-05 09:30:00', '2021-01-06 09:30:00'], \u00b6 dtype='datetime64[ns]', freq='D') \u00b6 print(ts) 2021-01-01 09:30:00 0.339822 \u00b6 2021-01-02 09:30:00 1.356382 \u00b6 2021-01-03 09:30:00 0.475429 \u00b6 2021-01-04 09:30:00 1.826654 \u00b6 2021-01-05 09:30:00 -0.245510 \u00b6 2021-01-06 09:30:00 0.705274 \u00b6 Freq: D, dtype: float64 \u00b6 print(ts.index.tz) # \u7d22\u5f15\u7684tz\u5c5e\u6027\u662fNone None \u00b6 \u65e5\u671f\u8303\u56f4\u53ef\u4ee5\u901a\u8fc7\u65f6\u533a\u96c6\u5408\u6765\u751f\u6210\uff1a rng = pd.date_range('2021/3/1', periods=10, freq='D', tz='UTC') print(rng) DatetimeIndex(['2021-03-01 00:00:00+00:00', '2021-03-02 00:00:00+00:00', \u00b6 '2021-03-03 00:00:00+00:00', '2021-03-04 00:00:00+00:00', \u00b6 '2021-03-05 00:00:00+00:00', '2021-03-06 00:00:00+00:00', \u00b6 '2021-03-07 00:00:00+00:00', '2021-03-08 00:00:00+00:00', \u00b6 '2021-03-09 00:00:00+00:00', '2021-03-10 00:00:00+00:00'], \u00b6 dtype='datetime64[ns, UTC]', freq='D') \u00b6 \u4f7f\u7528`tz_localize`\u65b9\u6cd5\u53ef\u4ee5\u4ece\u7b80\u5355\u65f6\u533a\u8f6c\u6362\u5230\u672c\u5730\u5316\u65f6\u533a\uff1a print(ts) 2021-01-01 09:30:00 0.294647 \u00b6 2021-01-02 09:30:00 0.958414 \u00b6 2021-01-03 09:30:00 0.424235 \u00b6 2021-01-04 09:30:00 -1.714333 \u00b6 2021-01-05 09:30:00 -0.030319 \u00b6 2021-01-06 09:30:00 -0.744940 \u00b6 Freq: D, dtype: float64 \u00b6 print(ts.tz_localize('UTC')) 2021-01-01 09:30:00+00:00 0.294647 \u00b6 2021-01-02 09:30:00+00:00 0.958414 \u00b6 2021-01-03 09:30:00+00:00 0.424235 \u00b6 2021-01-04 09:30:00+00:00 -1.714333 \u00b6 2021-01-05 09:30:00+00:00 -0.030319 \u00b6 2021-01-06 09:30:00+00:00 -0.744940 \u00b6 Freq: D, dtype: float64 \u00b6 print(ts.tz_localize('Asia/Shanghai')) 2021-01-01 09:30:00+08:00 0.052521 \u00b6 2021-01-02 09:30:00+08:00 -0.305417 \u00b6 2021-01-03 09:30:00+08:00 0.150215 \u00b6 2021-01-04 09:30:00+08:00 -0.953715 \u00b6 2021-01-05 09:30:00+08:00 0.543622 \u00b6 2021-01-06 09:30:00+08:00 0.222422 \u00b6 dtype: float64 \u00b6 print(ts.tz_localize('Asia/Shanghai').index) DatetimeIndex(['2021-01-01 09:30:00+08:00', '2021-01-02 09:30:00+08:00', \u00b6 '2021-01-03 09:30:00+08:00', '2021-01-04 09:30:00+08:00', \u00b6 '2021-01-05 09:30:00+08:00', '2021-01-06 09:30:00+08:00'], \u00b6 dtype='datetime64[ns, Asia/Shanghai]', freq=None) \u00b6 \u4e00\u65e6\u65f6\u95f4\u5e8f\u5217\u88ab\u672c\u5730\u5316\u4e3a\u67d0\u4e2a\u7279\u5b9a\u7684\u65f6\u533a\uff0c\u5219\u53ef\u4ee5\u901a\u8fc7`tz_convert`\u5c06\u5176\u8f6c\u6362\u4e3a\u53e6\u4e00\u4e2a\u65f6\u533a\uff1a tz_sha = ts.tz_localize('Asia/Shanghai') tz_utc = tz_sha.tz_convert('UTC') print(tz_sha) 2021-01-01 09:30:00+08:00 0.095689 \u00b6 2021-01-02 09:30:00+08:00 -0.392730 \u00b6 2021-01-03 09:30:00+08:00 0.151468 \u00b6 2021-01-04 09:30:00+08:00 0.027467 \u00b6 2021-01-05 09:30:00+08:00 0.393709 \u00b6 2021-01-06 09:30:00+08:00 0.872914 \u00b6 dtype: float64 \u00b6 print(tz_utc) 2021-01-01 01:30:00+00:00 0.095689 \u00b6 2021-01-02 01:30:00+00:00 -0.392730 \u00b6 2021-01-03 01:30:00+00:00 0.151468 \u00b6 2021-01-04 01:30:00+00:00 0.027467 \u00b6 2021-01-05 01:30:00+00:00 0.393709 \u00b6 2021-01-06 01:30:00+00:00 0.872914 \u00b6 dtype: float64 \u00b6 tz_localize\u548ctz_convert\u4e5f\u662fDatetimeIndex\u7684\u5b9e\u4f8b\u65b9\u6cd5\uff1a \u00b6 print(ts.index.tz_localize('Asia/Shanghai')) DatetimeIndex(['2021-01-01 09:30:00+08:00', '2021-01-02 09:30:00+08:00', \u00b6 '2021-01-03 09:30:00+08:00', '2021-01-04 09:30:00+08:00', \u00b6 '2021-01-05 09:30:00+08:00', '2021-01-06 09:30:00+08:00'], \u00b6 dtype='datetime64[ns, Asia/Shanghai]', freq=None) \u00b6 ### \u65f6\u533a\u611f\u77e5\u65f6\u95f4\u6233\u5bf9\u8c61\u7684\u64cd\u4f5c \u4e0e\u65f6\u95f4\u5e8f\u5217\u548c\u65e5\u671f\u8303\u56f4\u7c7b\u4f3c\uff0c\u5355\u72ec\u7684`Timestamp`\u5bf9\u8c61\u4e5f\u53ef\u4ee5\u4ece\u7b80\u5355\u65f6\u95f4\u6233\u672c\u5730\u5316\u4e3a\u65f6\u533a\u611f\u77e5\u65f6\u95f4\u6233\uff0c\u5e76\u4ece\u4e00\u4e2a\u65f6\u533a\u8f6c\u6362\u4e3a\u53e6\u4e00\u4e2a\u65f6\u533a\uff1a stamp = pd.Timestamp('2021-5-1 05:30') print(stamp) 2021-05-01 05:30:00 \u00b6 stamp_utc = stamp.tz_localize('utc') print(stamp_utc) 2021-05-01 05:30:00+00:00 \u00b6 stamp_sha = stamp_utc.tz_convert('Asia/Shanghai') print(stamp_sha) 2021-05-01 13:30:00+08:00 \u00b6 \u4e5f\u53ef\u4ee5\u5728\u521b\u5efa`Timestamp`\u7684\u65f6\u5019\u4f20\u9012\u4e00\u4e2a\u65f6\u533a\uff1a stamp_sha = pd.Timestamp('2021-5-1 05:30', tz='Asia/Shanghai') print(stamp_sha) 2021-05-01 05:30:00+08:00 \u00b6 `Timestamp`\u5bf9\u8c61\u5185\u90e8\u5b58\u50a8\u4e86\u4e00\u4e2aUnix\u7eaa\u5143(1970\u5e741\u67081\u65e5)\u81f3\u4eca\u7684\u7eb3\u79d2\u6570\u91cfUTC\u65f6\u95f4\u6233\u6570\u503c\uff0c\u8be5\u6570\u503c\u5728\u65f6\u533a\u8f6c\u6362\u4e2d\u662f\u4e0d\u53d8\u7684\uff1a print(stamp_utc.value) 1619847000000000000 \u00b6 print(stamp_utc.tz_convert('Asia/Shanghai').value) 1619847000000000000 \u00b6 \u5728\u4f7f\u7528pandas\u7684`DateOffset`\u8fdb\u884c\u65f6\u95f4\u7b97\u672f\u65f6\uff0cpandas\u5c3d\u53ef\u80fd\u9075\u4ece\u590f\u65f6\u5236\u3002 \u9996\u5148\uff0c\u6784\u9020\u8f6c\u6362\u5230DST\u4e4b\u524d\u768430\u5206\u949f\u7684\u65f6\u95f4\uff1a stamp = pd.Timestamp('2012-3-12 1:30', tz='US/Eastern') print(stamp) 2012-03-12 01:30:00-04:00 \u00b6 print(stamp + Hour()) 2012-03-12 02:30:00-04:00 \u00b6 \u4e4b\u540e\uff0c\u6784\u5efa\u4eceDST\u8fdb\u884c\u8f6c\u6362\u524d\u768490\u5206\u949f\uff1a stamp = pd.Timestamp('2012-11-04 0:30-04:00', tz='US/Eastern') print(stamp) 2012-11-04 00:30:00-04:00 \u00b6 print(stamp + 2 * Hour()) # \u53ea\u589e\u52a0\u4e86\u4e00\u5c0f\u65f6 2012-11-04 01:30:00-05:00 \u00b6 ### \u4e0d\u540c\u65f6\u533a\u95f4\u7684\u64cd\u4f5c \u5982\u679c\u4e24\u4e2a\u65f6\u533a\u4e0d\u540c\u7684\u65f6\u95f4\u5e8f\u5217\u9700\u8981\u8054\u5408\uff0c\u90a3\u4e48\u7ed3\u679c\u5c06\u662fUTC\u65f6\u95f4\u7684\uff0c\u56e0\u4e3a\u65f6\u95f4\u6233\u4ee5UTC\u683c\u5f0f\u5b58\u50a8\u3002 rng = pd.date_range('2021/1/1 9:30', periods=9, freq='B') ts = pd.Series(np.random.randn(len(rng)), index=rng) print(ts) 2021-01-01 09:30:00 0.715681 \u00b6 2021-01-04 09:30:00 0.524563 \u00b6 2021-01-05 09:30:00 -0.482199 \u00b6 2021-01-06 09:30:00 -0.661303 \u00b6 2021-01-07 09:30:00 1.750010 \u00b6 2021-01-08 09:30:00 0.251478 \u00b6 2021-01-11 09:30:00 -1.487268 \u00b6 2021-01-12 09:30:00 -0.224024 \u00b6 2021-01-13 09:30:00 -1.621853 \u00b6 Freq: B, dtype: float64 \u00b6 ts1 = ts[:7].tz_localize('Europe/London') ts2 = ts1[2:].tz_convert('Europe/Moscow') result = ts1 + ts2 print(ts1) 2021-01-01 09:30:00+00:00 -1.393445 \u00b6 2021-01-04 09:30:00+00:00 -1.179614 \u00b6 2021-01-05 09:30:00+00:00 0.716669 \u00b6 2021-01-06 09:30:00+00:00 -0.485656 \u00b6 2021-01-07 09:30:00+00:00 0.433000 \u00b6 2021-01-08 09:30:00+00:00 1.540745 \u00b6 2021-01-11 09:30:00+00:00 0.343751 \u00b6 dtype: float64 \u00b6 print(ts2) 2021-01-05 12:30:00+03:00 0.716669 \u00b6 2021-01-06 12:30:00+03:00 -0.485656 \u00b6 2021-01-07 12:30:00+03:00 0.433000 \u00b6 2021-01-08 12:30:00+03:00 1.540745 \u00b6 2021-01-11 12:30:00+03:00 0.343751 \u00b6 dtype: float64 \u00b6 print(result) 2021-01-01 09:30:00+00:00 NaN \u00b6 2021-01-04 09:30:00+00:00 NaN \u00b6 2021-01-05 09:30:00+00:00 1.433337 \u00b6 2021-01-06 09:30:00+00:00 -0.971312 \u00b6 2021-01-07 09:30:00+00:00 0.866000 \u00b6 2021-01-08 09:30:00+00:00 3.081489 \u00b6 2021-01-11 09:30:00+00:00 0.687502 \u00b6 dtype: float64 \u00b6 ## \u65f6\u95f4\u533a\u95f4\u548c\u533a\u95f4\u7b97\u672f from datetime import datetime, timedelta import pandas as pd import numpy as np from pandas.tseries.offsets import Hour, Minute, Day, MonthEnd import pytz \u65f6\u95f4\u533a\u95f4\u8868\u793a\u7684\u662f\u65f6\u95f4\u8303\u56f4\u901a\u8fc7\u539f\u7d22\u5f151~202\uff0c\u628a`year`\u548c`quarter`\u8054\u5408\u8d77\u6765\uff0c\u751f\u6210\u65b0\u7d22\u5f15\uff0c\u5e76\u66ff\u6362\u539f\u7d22\u5f15\uff0c\u6bd4\u5982\u4e00\u4e9b\u5929\u3001\u4e00\u4e9b\u6708\u3001\u4e00\u4e9b\u5b63\u5ea6\u6216\u8005\u662f\u4e00\u4e9b\u5e74\u3002 `Period`\u7c7b\u8868\u793a\u7684\u6b63\u662f\u8fd9\u79cd\u6570\u636e\u7c7b\u578b\uff0c\u9700\u8981\u4e00\u4e2a\u5b57\u7b26\u4e32\u6216\u6570\u5b57\u4ee5\u53ca\u9891\u7387\u3002 \u5728\u8fd9\u4e2a\u4f8b\u5b50\u4e2d\uff0c`Period`\u5bf9\u8c61\u8868\u793a\u7684\u662f\u4ece2007\u5e741\u67081\u65e5\u52302007\u5e7412\u670831\u65e5\uff08\u5305\u542b\u5728\u5185\uff09\u7684\u65f6\u95f4\u6bb5\u3002 \u5728\u65f6\u95f4\u6bb5\u4e0a\u589e\u52a0\u6216\u51cf\u53bb\u6574\u6570\u53ef\u4ee5\u65b9\u4fbf\u5730\u6839\u636e\u5b83\u4eec\u7684\u9891\u7387\u8fdb\u884c\u79fb\u4f4d\u3002 p = pd.Period(2020, freq='A-DEC') print(p) 2020 \u00b6 print(p + 5) 2025 \u00b6 print(p - 5) 2015 \u00b6 \u5982\u679c\u4e24\u4e2a\u533a\u95f4\u62e5\u6709\u76f8\u540c\u7684\u9891\u7387\uff0c\u5219\u5b83\u4eec\u7684\u5dee\u662f\u5b83\u4eec\u4e4b\u95f4\u7684\u5355\u4f4d\u6570\u3002 p1 = pd.Period(2020, freq='A-DEC') p2 = pd.Period(2010, freq='A-DEC') print(p1 - p2) <10 * YearEnds: month=12> \u00b6 p1 = pd.Period(2020, freq='Q-DEC') p2 = pd.Period(2010, freq='Q-DEC') print(p1 - p2) <40 * QuarterEnds: startingMonth=12> \u00b6 \u4f7f\u7528`period_range`\u51fd\u6570\u53ef\u4ee5\u6784\u9020\u89c4\u5219\u533a\u95f4\u5e8f\u5217\u3002`PeriodIndex`\u7c7b\u5b58\u50a8\u7684\u662f\u533a\u95f4\u7684\u5e8f\u5217\uff0c\u53ef\u4ee5\u4f5c\u4e3a\u4efb\u610fpandas\u6570\u636e\u7ed3\u6784\u7684\u8f74\u7d22\u5f15\u3002 data = np.random.randn(6) strings = ['2021Q1', '2021Q2', '2021Q3', '2021Q4', '2022Q1', '2022Q2'] rng = pd.period_range('2001-1-1', '2001-6-30', freq='M') ts = pd.Series(data, index=rng) print(ts) 2001-01 -0.481408 \u00b6 2001-02 -0.297590 \u00b6 2001-03 -0.860354 \u00b6 2001-04 1.281540 \u00b6 2001-05 1.036551 \u00b6 2001-06 -0.522592 \u00b6 Freq: M, dtype: float64 \u00b6 rng = pd.PeriodIndex(strings, freq='Q-DEC') # \u5b57\u7b26\u4e32\u6570\u7ec4\u4e5f\u53ef\u4ee5\u4f7f\u7528PeriodIndex\u7c7b ts = pd.Series(data, index=rng) print(ts) 2021Q1 -2.077200 \u00b6 2021Q2 -0.948796 \u00b6 2021Q3 -1.104737 \u00b6 2021Q4 0.090281 \u00b6 2022Q1 0.431517 \u00b6 2022Q2 1.537045 \u00b6 Freq: Q-DEC, dtype: float64 \u00b6 ### \u533a\u95f4\u9891\u7387\u8f6c\u6362 \u4f7f\u7528`asfreq`\u53ef\u4ee5\u5c06\u533a\u95f4\u548c`PeriodIndex`\u5bf9\u8c61\u8f6c\u6362\u4e3a\u5176\u4ed6\u7684\u9891\u7387\u3002 \u4f8b\u5982\uff0c\u5047\u8bbe\u6211\u4eec\u6709\u4e00\u4e2a\u5e74\u5ea6\u533a\u95f4\uff0c\u5e76\u4e14\u60f3\u8981\u5728\u4e00\u5e74\u7684\u5f00\u59cb\u6216\u7ed3\u675f\u65f6\u5c06\u5176\u8f6c\u6362\u4e3a\u6708\u5ea6\u533a\u95f4\u3002 \u53ef\u4ee5\u5c06`Period('2020', 'A-DEC')`\u770b\u4f5c\u4e00\u6bb5\u65f6\u95f4\u4e2d\u7684\u4e00\u79cd\u6e38\u6807\uff0c\u5c06\u65f6\u95f4\u6309\u6708\u4efd\u5212\u5206\u3002 p = pd.Period(2020, freq='A-DEC') print(p.asfreq('M', how='start')) 2020-01 \u00b6 print(p.asfreq('M', how='end')) 2020-12 \u00b6 \u5982\u679c\u8d22\u5e74\u7ed3\u675f\u4e0d\u572812\u6708\uff0c\u5219\u6bcf\u6708\u5206\u671f\u4f1a\u81ea\u52a8\u8c03\u6574\u3002 \u6309\u5f53\u5e74\u8d22\u5e74\u7ed3\u675f\u8ba1\u7b97\uff0c\u8d77\u59cb\u5e74\u4efd\u5c31\u662f\u4e0a\u4e00\u5e74\u4e86\u3002 p = pd.Period(2020, freq='A-JUN') print(p.asfreq('M', how='start')) 2019-07 \u00b6 print(p.asfreq('M', how='end')) 2020-06 \u00b6 \u5f53\u4ece\u9ad8\u9891\u7387\u5411\u4f4e\u9891\u7387\u8f6c\u6362\u65f6\uff0cpandas\u6839\u636e\u5b50\u533a\u95f4\u7684\"\u6240\u5c5e\"\u6765\u51b3\u5b9a\u7236\u533a\u95f4\u3002 \u4f8b\u5982\uff0c\u5728A-JUN\u9891\u7387\u4e2d\uff0cAug-2020\u662f2020\u533a\u95f4\u7684\u4e00\u90e8\u5206\uff1a print(p.asfreq('A-JUN')) 2020\u901a\u8fc7\u539f\u7d22\u5f151~202\uff0c\u628a`year`\u548c`quarter`\u8054\u5408\u8d77\u6765\uff0c\u751f\u6210\u65b0\u7d22\u5f15\uff0c\u5e76\u66ff\u6362\u539f\u7d22\u5f15\u3002 \u5b8c\u6574\u7684`PeriodIndex`\u5bf9\u8c61\u6216\u65f6\u95f4\u5e8f\u5217\u53ef\u4ee5\u6309\u7167\u76f8\u540c\u7684\u8bed\u4e49\u8fdb\u884c\u8f6c\u6362\uff1a rng = pd.period_range('2018', '2021', freq='A-DEC') data = np.random.randn(len(rng)) ts = pd.Series(data, index=rng) print(ts) 2018 0.221634 \u00b6 2019 -0.392724 \u00b6 2020 -0.355022 \u00b6 2021 0.114000 \u00b6 Freq: A-DEC, dtype: float64 \u00b6 \u4e0b\u9762\u5e74\u5ea6\u533a\u95f4\u5c06\u901a\u8fc7`asfreq`\u88ab\u66ff\u6362\u4e3a\u5bf9\u5e94\u4e8e\u6bcf\u4e2a\u5e74\u5ea6\u533a\u95f4\u5185\u7684\u7b2c\u4e00\u4e2a\u6708\u7684\u6708\u5ea6\u533a\u95f4\u3002 print(ts.asfreq('M', how='start')) 2018-01 0.681874 \u00b6 2019-01 -1.006585 \u00b6 2020-01 -0.619142 \u00b6 2021-01 1.445820 \u00b6 Freq: M, dtype: float64 \u00b6 \u5982\u679c\u6211\u4eec\u60f3\u8981\u6bcf\u5e74\u6700\u540e\u4e00\u4e2a\u5de5\u4f5c\u65e5\uff0c\u6211\u4eec\u53ef\u4ee5\u4f7f\u7528`B`\u9891\u7387\u6765\u8868\u793a\u6211\u4eec\u60f3\u8981\u7684\u662f\u533a\u95f4\u7684\u672b\u7aef\u3002 print(ts.asfreq('B', how='end')) 2018-12-31 -1.520316 \u00b6 2019-12-31 -0.425544 \u00b6 2020-12-31 -0.658073 \u00b6 2021-12-31 1.206881 \u00b6 Freq: B, dtype: float64 \u00b6 ### \u5b63\u5ea6\u533a\u95f4\u9891\u7387 \u5b63\u5ea6\u6570\u636e\u662f\u4f1a\u8ba1\u3001\u91d1\u878d\u548c\u5176\u4ed6\u9886\u57df\u7684\u6807\u51c6\u3002 \u5f88\u591a\u5b63\u5ea6\u6570\u636e\u662f\u5728\u8d22\u5e74\u7ed3\u5c3e\u62a5\u544a\u7684\uff0c\u901a\u5e38\u662f\u4e00\u5e7412\u4e2a\u6708\u4e2d\u7684\u6700\u540e\u4e00\u4e2a\u65e5\u5386\u65e5\u6216\u5de5\u4f5c\u65e5\u3002 pandas\u652f\u6301\u6240\u6709\u7684\u53ef\u80fd\u768412\u4e2a\u5b63\u5ea6\u9891\u7387\u4eceQ-JAN\u5230Q-DEC\uff1a \u4e0b\u4f8b\u4e2d\uff0c\u8d22\u5e74\u7ed3\u675f\u4e8e1\u6708\uff0c2020Q4\u884c\u65f6\u95f4\u4e3a\u4e0a\u4e00\u5e7411\u6708\u81f3\u5f53\u5e741\u6708\u3002\u53ef\u4ee5\u901a\u8fc7\u8f6c\u6362\u4e3a\u6bcf\u65e5\u9891\u7387\uff08asfreq\uff09\u8fdb\u884c\u68c0\u67e5\u3002 p = pd.Period('2020Q4', freq='Q-JAN') print(p) 2020Q4 \u00b6 print(p.asfreq('D', 'start')) 2019-11-01 \u00b6 print(p.asfreq('D', 'end')) 2020-01-31 \u00b6 \u5047\u5982\u8d22\u5e74\u7ed3\u675f\u4e8e2\u6708\uff0c2020Q4\u884c\u65f6\u95f4\u4e3a\u4e0a\u4e00\u5e7412\u6708\u81f3\u5f53\u5e742\u6708\u3002 p = pd.Period('2020Q4', freq='Q-FEB') print(p) 2020Q4 \u00b6 print(p.asfreq('D', 'start')) 2019-11-01 \u00b6 print(p.asfreq('D', 'end')) 2020-01-31 \u00b6 \u5047\u5982\u8d22\u5e74\u7ed3\u675f\u4e8e4\u6708\uff0c2020Q4\u884c\u65f6\u95f4\u4e3a\u4e0a\u4e00\u5e7412\u6708\u81f3\u5f53\u5e742\u6708\u3002 p = pd.Period('2020Q4', freq='Q-APR') print(p) 2020Q4 \u00b6 print(p.asfreq('D', 'start')) 2020-02-01 \u00b6 print(p.asfreq('D', 'end')) 2020-04-30 \u00b6 \u53ef\u4ee5\u5bf9\u533a\u95f4\u6570\u636e\u505a\u7b97\u672f\u64cd\u4f5c\u3002\u4f8b\u5982\uff0c\u8981\u83b7\u53d6\u5728\u5b63\u5ea6\u5012\u6570\u7b2c\u4e8c\u4e2a\u5de5\u4f5c\u65e5\u4e0b\u53484\u70b9\u7684\u65f6\u95f4\u6233\uff0c\u53ef\u4ee5\u8fd9\u4e48\u505a\uff1a(\u7591\u95ee\uff1a\u8fd9\u91cc\u7684\u53c2\u6570e\u4ee3\u8868\u4ec0\u4e48 ???) p4pm = (p.asfreq('B', 'e') - 1).asfreq('T', 's') + 16 * 60 print(p4pm) 2020-04-29 16:00 \u00b6 print(p4pm.to_timestamp()) 2020-04-29 16:00:00 \u00b6 \u53ef\u4ee5\u4f7f\u7528`peroid_range`\u751f\u6210\u5b63\u5ea6\u5e8f\u5217\u3002\u5b83\u7684\u7b97\u672f\u4e5f\u662f\u4e00\u6837\u7684\uff1a rng = pd.period_range('2000Q3', '2001Q4', freq='Q-JAN') ts = pd.Series(np.arange(len(rng)), index=rng) print(ts) 2000Q3 0 \u00b6 2000Q4 1 \u00b6 2001Q1 2 \u00b6 2001Q2 3 \u00b6 2001Q3 4 \u00b6 2001Q4 5 \u00b6 Freq: Q-JAN, dtype: int64 \u00b6 new_rng = (rng.asfreq('B', 'e') - 1).asfreq('T', 's') + 16 * 60 ts.index = new_rng.to_timestamp() print(ts) 1999-10-28 16:00:00 0 \u00b6 2000-01-28 16:00:00 1 \u00b6 2000-04-27 16:00:00 2 \u00b6 2000-07-28 16:00:00 3 \u00b6 2000-10-30 16:00:00 4 \u00b6 2001-01-30 16:00:00 5 \u00b6 dtype: int64 \u00b6 ### \u5c06\u65f6\u95f4\u6233\u8f6c\u6362\u4e3a\u533a\u95f4\uff08\u4ee5\u53ca\u9006\u8f6c\u6362\uff09 \u901a\u8fc7\u65f6\u95f4\u6233\u7d22\u5f15\u7684Series\u548cDataFrame\u53ef\u4ee5\u88ab`to_period`\u65b9\u6cd5\u8f6c\u6362\u4e3a\u533a\u95f4\uff1a rng = pd.date_range('2020-01-01', periods=3, freq='M') ts = pd.Series(np.random.randn(3), index=rng) print(ts) 2020-01-31 -0.567097 \u00b6 2020-02-29 0.63452\u901a\u8fc7\u539f\u7d22\u5f151~202\uff0c\u628ayear\u548cquarter\u8054\u5408\u8d77\u6765\uff0c\u751f\u6210\u65b0\u7d22\u5f15\uff0c\u5e76\u66ff\u6362\u539f\u7d22\u5f152 \u00b6 2020-03-31 0.297777 \u00b6 Freq: M, dtype: float64 \u00b6 pts = ts.to_period() print(pts) 2020-01 -0.567097 \u00b6 2020-02 0.634522 \u00b6 2020-03 0.297777 \u00b6 Freq: M, dtype: float64 \u00b6 \u7531\u4e8e\u533a\u95f4\u662f\u975e\u91cd\u53e0\u65f6\u95f4\u8303\u56f4\uff0c\u4e00\u4e2a\u65f6\u95f4\u6233\u53ea\u80fd\u5c5e\u4e8e\u7ed9\u5b9a\u9891\u7387\u7684\u5355\u4e2a\u533a\u95f4\u3002 \u5c3d\u7ba1\u9ed8\u8ba4\u60c5\u51b5\u4e0b\u6839\u636e\u65f6\u95f4\u6233\u63a8\u65ad\u51fa\u65b0`PeriodIndex`\u7684\u9891\u7387\uff0c\u4f46\u53ef\u4ee5\u6307\u5b9a\u4efb\u4f55\u60f3\u8981\u7684\u9891\u7387\u3002 \u5728\u7ed3\u679c\u4e2d\u5305\u542b\u91cd\u590d\u7684\u533a\u95f4\u4e5f\u662f\u6ca1\u6709\u95ee\u9898\u7684\u3002 rng = pd.date_range('2020-01-01', periods=6, freq='D') ts = pd.Series(np.random.randn(6), index=rng) print(ts) 2020-01-01 -0.111287 \u00b6 2020-01-02 1.442234 \u00b6 2020-01-03 -0.767553 \u00b6 2020-01-04 -0.265064 \u00b6 2020-01-05 1.200312 \u00b6 2020-01-06 -1.782557 \u00b6 Freq: D, dtype: float64 \u00b6 ts_m = ts.to_period('M') # \u6307\u5b9aperiod\u7684\u9891\u7387\uff08M\uff09,\u8f93\u51fa\u7ed3\u679c\u5305\u542b\u91cd\u590dperiod print(ts_m) 2020-01 -0.111287 \u00b6 2020-01 1.442234 \u00b6 2020-01 -0.767553 \u00b6 2020-01 -0.265064 \u00b6 2020-01 1.200312 \u00b6 2020-01 -1.782557 \u00b6 Freq: M, dtype: float64 \u00b6 \u4f7f\u7528`to_timestamp`\u53ef\u4ee5\u5c06\u533a\u95f4\u518d\u8f6c\u6362\u4e3a\u65f6\u95f4\u6233\uff1a print(ts_m.to_timestamp(how='end')) 2020-01-31 23:59:59.999999999 -0.111287 \u00b6 2020-01-31 23:59:59.999999999 1.442234 \u00b6 2020-01-31 23:59:59.999999999 -0.767553 \u00b6 2020-01-31 23:59:59.999999999 -0.265064 \u00b6 2020-01-31 23:59:59.999999999 1.200312 \u00b6 2020-01-31 23:59:59.999999999 -1.782557 \u00b6 dtype: float64 \u00b6 print(ts_m.to_timestamp(how='start')) 2020-01-01 -0.111287 \u00b6 2020-01-01 1.442234 \u00b6 2020-01-01 -0.767553 \u00b6 2020-01-01 -0.265064 \u00b6 2020-01-01 1.200312 \u00b6 2020-01-01 -1.782557 \u00b6 dtype: float64 \u00b6 ### \u4ece\u6570\u7ec4\u751f\u6210PeriodIndex \u56fa\u5b9a\u9891\u7387\u6570\u636e\u96c6\u6709\u65f6\u5b58\u50a8\u5728\u8de8\u8d8a\u591a\u5217\u7684\u65f6\u95f4\u8303\u56f4\u4fe1\u606f\u4e2d\u3002\u4f8b\u5982\uff0c\u5728\u8fd9\u4e2a\u5b8f\u89c2\u7ecf\u6d4e\u6570\u636e\u96c6\u4e2d\uff0c\u5e74\u4efd\u548c\u5b63\u5ea6\u5728\u4e0d\u540c\u5217\u4e2d\uff1a data = pd.read_csv('../examples/macrodata.csv') print(data.head(5)) year quarter realgdp realcons ... unemp pop infl realint \u00b6 0 1959.0 1.0 2710.349 1707.4 ... 5.8 177.146 0.00 0.00 \u00b6 1 1959.0 2.0 2778.801 1733.7 ... 5.1 177.830 2.34 0.74 \u00b6 2 1959.0 3.0 2775.488 1751.8 ... 5.3 178.657 2.74 1.09 \u00b6 3 1959.0 4.0 2785.204 1753.7 ... 5.6 179.386 0.27 4.06 \u00b6 4 1960.0 1.0 2847.699 1770.5 ... 5.2 180.007 2.31 1.19 \u00b6 print(data.year) 0 1959.0 \u00b6 1 1959.0 \u00b6 2 1959.0 \u00b6 3 1959.0 \u00b6 4 1960.0 \u00b6 ... \u00b6 198 2008.0 \u00b6 199 2008.0 \u00b6 200 2009.0 \u00b6 201 2009.0 \u00b6 202 2009.0 \u00b6 Name: year, Length: 203, dtype: float64 \u00b6 print(data.quarter) 0 1.0 \u00b6 1 2.0 \u00b6 2 3.0 \u00b6 3 4.0 \u00b6 4 1.0 \u00b6 ... \u00b6 198 3.0 \u00b6 199 4.0 \u00b6 200 1.0 \u00b6 201 2.0 \u00b6 202 3.0 \u00b6 Name: quarter, Length: 203, dtype: float64 \u00b6 \u901a\u8fc7\u5c06\u8fd9\u4e9b\u6570\u7ec4\u548c\u9891\u7387\u4f20\u9012\u7ed9`PeriodIndex`\uff0c\u53ef\u4ee5\u8054\u5408\u5f62\u6210DataFrame\u7684\u7d22\u5f15 index = pd.PeriodIndex(year=data.year, quarter=data.quarter, freq='Q-DEC') print(index) PeriodIndex(['1959Q1', '1959Q2', '1959Q3', '1959Q4', '1960Q1', '1960Q2', \u00b6 '1960Q3', '1960Q4', '1961Q1', '1961Q2', \u00b6 ... \u00b6 '2007Q2', '2007Q3', '2007Q4', '2008Q1', '2008Q2', '2008Q3', \u00b6 '2008Q4', '2009Q1', '2009Q2', '2009Q3'], \u00b6 dtype='period[Q-DEC]', length=203) \u00b6 data.index = index # \u901a\u8fc7\u539f\u7d22\u5f151~202\uff0c\u628ayear\u548cquarter\u8054\u5408\u8d77\u6765\uff0c\u751f\u6210\u65b0\u7d22\u5f15\uff0c\u5e76\u66ff\u6362\u539f\u7d22\u5f15 print(data.infl) 1959Q1 0.00 \u00b6 1959Q2 2.34 \u00b6 1959Q3 2.74 \u00b6 1959Q4 0.27 \u00b6 1960Q1 2.31 \u00b6 ... \u00b6 2008Q3 -3.16 \u00b6 2008Q4 -8.79 \u00b6 2009Q1 0.94 \u00b6 2009Q2 3.37 \u00b6 2009Q3 3.56 \u00b6 Freq: Q-DEC, Name: infl, Length: 203, dtype: float64 \u00b6 ## \u91cd\u65b0\u91c7\u6837\u9891\u7387\u8f6c\u6362 import pandas as pd import numpy as np from pandas.tseries.frequencies import to_offset \u91cd\u65b0\u91c7\u6837\u662f\u6307\u5c06\u65f6\u95f4\u5e8f\u5217\u4ece\u4e00\u4e2a\u9891\u7387\u8f6c\u6362\u4e3a\u53e6\u4e00\u4e2a\u9891\u7387\u7684\u8fc7\u7a0b\u3002 \u5c06\u66f4\u9ad8\u9891\u7387\u7684\u6570\u636e\u805a\u5408\u5230\u4f4e\u9891\u7387\u88ab\u79f0\u4e3a\u5411\u4e0b\u91c7\u6837\uff0c\u800c\u4ece\u4f4e\u9891\u7387\u8f6c\u6362\u5230\u9ad8\u9891\u7387\u79f0\u4e3a\u5411\u4e0a\u91c7\u6837\u3002 \u5e76\u4e0d\u662f\u6240\u6709\u7684\u91cd\u65b0\u91c7\u6837\u90fd\u5c5e\u4e8e\u4e0a\u9762\u8bf4\u7684\u4e24\u7c7b\u3002\u4f8b\u5982\uff0c\u5c06W-WED\uff08weekly on Wednesday\uff0c\u6bcf\u5468\u4e09\uff09\u8f6c\u6362\u5230W-FRI\uff08\u6bcf\u5468\u4e94\uff09\u65e2\u4e0d\u662f\u5411\u4e0a\u91c7\u6837\u4e5f\u4e0d\u662f\u5411\u4e0b\u91c7\u6837\u3002 pandas\u5bf9\u8c61\u90fd\u914d\u6709`resample`\u65b9\u6cd5\uff0c\u8be5\u65b9\u6cd5\u662f\u6240\u6709\u9891\u7387\u8f6c\u6362\u7684\u5de5\u5177\u51fd\u6570\u3002`resample`\u62e5\u6709\u7c7b\u4f3c\u4e8e`groupby`\u7684API\uff1b\u8c03\u7528`resample`\u5bf9\u6570\u636e\u5206\u7ec4\uff0c\u4e4b\u540e\u518d\u8c03\u7528\u805a\u5408\u51fd\u6570\uff1a ### resample\u65b9\u6cd5\u53c2\u6570 \u53c2\u6570 * freq: \u8868\u793a\u91cd\u91c7\u6837\u9891\u7387\uff0c\u4f8b\u5982\u2018M'\u3001\u20185min'\uff0cSecond(15) * how='mean': \u7528\u4e8e\u4ea7\u751f\u805a\u5408\u503c\u7684\u51fd\u6570\u540d\u6216\u6570\u7ec4\u51fd\u6570\uff0c\u4f8b\u5982\u2018mean'\u3001\u2018ohlc'\u3001np.max\u7b49\uff0c\u9ed8\u8ba4\u662f\u2018mean'\uff0c\u5176\u4ed6\u5e38\u7528\u7684\u503c\u7531\uff1a\u2018first'\u3001\u2018last'\u3001\u2018median'\u3001\u2018max'\u3001\u2018min' * axis=0: \u9ed8\u8ba4\u662f\u7eb5\u8f74\uff0c\u6a2a\u8f74\u8bbe\u7f6eaxis=1 * fill_method = None: \u5347\u91c7\u6837\u65f6\u5982\u4f55\u63d2\u503c\uff0c\u6bd4\u5982\u2018ffill'\u3001\u2018bfill'\u7b49 * closed = \u2018right': \u5728\u964d\u91c7\u6837\u65f6\uff0c\u5404\u65f6\u95f4\u6bb5\u7684\u54ea\u4e00\u6bb5\u662f\u95ed\u5408\u7684\uff0c\u2018right'\u6216\u2018left'\uff0c\u9ed8\u8ba4\u2018right' * label= \u2018right': \u5728\u964d\u91c7\u6837\u65f6\uff0c\u5982\u4f55\u8bbe\u7f6e\u805a\u5408\u503c\u7684\u6807\u7b7e\uff0c\u4f8b\u5982\uff0c9\uff1a30-9\uff1a35\u4f1a\u88ab\u6807\u8bb0\u62109\uff1a30\u8fd8\u662f9\uff1a35,\u9ed8\u8ba49\uff1a35 * loffset = None: \u9762\u5143\u6807\u7b7e\u7684\u65f6\u95f4\u6821\u6b63\u503c\uff0c\u6bd4\u5982\u2018-1s'\u6216Second(-1)\u7528\u4e8e\u5c06\u805a\u5408\u6807\u7b7e\u8c03\u65e91\u79d2 * limit=None: \u5728\u5411\u524d\u6216\u5411\u540e\u586b\u5145\u65f6\uff0c\u5141\u8bb8\u586b\u5145\u7684\u6700\u5927\u65f6\u671f\u6570 * kind = None: \u805a\u5408\u5230\u65f6\u671f\uff08\u2018period'\uff09\u6216\u65f6\u95f4\u6233\uff08\u2018timestamp'\uff09\uff0c\u9ed8\u8ba4\u805a\u5408\u5230\u65f6\u95f4\u5e8f\u5217\u7684\u7d22\u5f15\u7c7b\u578b * convention = None: \u5f53\u91cd\u91c7\u6837\u65f6\u671f\u65f6\uff0c\u5c06\u4f4e\u9891\u7387\u8f6c\u6362\u5230\u9ad8\u9891\u7387\u6240\u91c7\u7528\u7684\u7ea6\u5b9a\uff08start\u6216end\uff09\u3002\u9ed8\u8ba4\u2018end' rng = pd.date_range('2020-1-1', periods=100, freq='D') ts = pd.Series(np.random.randn(len(rng)), index=rng) print(ts) 2020-01-01 0.802409 \u00b6 2020-01-02 -1.147130 \u00b6 2020-01-03 -1.076115 \u00b6 2020-01-04 -2.097443 \u00b6 2020-01-05 0.577671 \u00b6 ... \u00b6 2020-04-05 -0.110747 \u00b6 2020-04-06 0.132867 \u00b6 2020-04-07 -0.294061 \u00b6 2020-04-08 -0.246155 \u00b6 2020-04-09 0.927194 \u00b6 Freq: D, Length: 100, dtype: float64 \u00b6 print(ts.resample('M')) DatetimeIndexResampler [freq= , axis=0, closed=right, label=right, convention=start, origin=start_day] \u00b6 print(ts.resample('M').mean()) # \u628a100\u5929\u7684\u6570\u636e\u6309\u6708groupby\uff0c\u5e76\u8f93\u51fa\u6708\u672b\u6700\u540e\u4e00\u5929\uff0c\u8ba1\u7b97\u5e73\u5747\u503c 2020-01-31 -0.311714 \u00b6 2020-02-29 0.121526 \u00b6 2020-03-31 -0.051131 \u00b6 2020-04-30 -0.273113 \u00b6 Freq: M, dtype: float64 \u00b6 print(ts.resample('M', kind='period').mean()) # # \u628a100\u5929\u7684\u6570\u636e\u6309\u6708groupby\uff0c\u5e76\u8f93\u51fa\u6708\u4efd\uff08\u53c2\u6570period\uff09\uff0c\u8ba1\u7b97\u5e73\u5747\u503c 2020-01 -0.311714 \u00b6 2020-02 0.121526 \u00b6 2020-03 -0.051131 \u00b6 2020-04 -0.273113 \u00b6 Freq: M, dtype: float64 \u00b6 ### \u5411\u4e0b\u91c7\u6837 \u5c06\u6570\u636e\u805a\u5408\u5230\u4e00\u4e2a\u89c4\u5219\u7684\u4f4e\u9891\u7387\u4e0a\u662f\u4e00\u4e2a\u5e38\u89c1\u7684\u65f6\u95f4\u5e8f\u5217\u4efb\u52a1\u3002 \u8981\u805a\u5408\u7684\u6570\u636e\u4e0d\u5fc5\u662f\u56fa\u5b9a\u9891\u7387\u7684\u3002 \u671f\u671b\u7684\u9891\u7387\u5b9a\u4e49\u4e86\u7528\u4e8e\u5bf9\u65f6\u95f4\u5e8f\u5217\u5207\u7247\u4ee5\u805a\u5408\u7684\u7bb1\u4f53\u8fb9\u754c\u3002\u4f8b\u5982\uff0c\u8981\u5c06\u65f6\u95f4\u8f6c\u6362\u4e3a\u6bcf\u6708\uff0c`M`\u6216`BM`\uff0c\u5219\u9700\u8981\u5c06\u6570\u636e\u5206\u6210\u4e00\u4e2a\u6708\u7684\u65f6\u95f4\u95f4\u9694\u3002 \u6bcf\u4e2a\u95f4\u9694\u662f\u534a\u95ed\u5408\u7684\uff0c\u4e00\u4e2a\u6570\u636e\u70b9\u53ea\u80fd\u5c5e\u4e8e\u4e00\u4e2a\u65f6\u95f4\u95f4\u9694\uff0c\u65f6\u95f4\u95f4\u9694\u7684\u5e76\u96c6\u5fc5\u987b\u662f\u6574\u4e2a\u65f6\u95f4\u5e27\u3002 \u5728\u4f7f\u7528resample\u8fdb\u884c\u5411\u4e0b\u91c7\u6837\u6570\u636e\u65f6\u6709\u4e9b\u4e8b\u60c5\u9700\u8981\u8003\u8651\uff1a * \u6bcf\u6bb5\u95f4\u9694\u7684\u54ea\u4e00\u8fb9\u662f\u95ed\u5408\u7684\u3002 * \u5982\u4f55\u5728\u95f4\u9694\u7684\u8d77\u59cb\u6216\u7ed3\u675f\u4f4d\u7f6e\u6807\u8bb0\u6bcf\u4e2a\u5df2\u805a\u5408\u7684\u7bb1\u4f53\u3002 rng = pd.date_range('2020-1-1', periods=12, freq='T') ts = pd.Series(np.arange(12), index=rng) print(ts) 2020-01-01 00:00:00 0 \u00b6 2020-01-01 00:01:00 1 \u00b6 2020-01-01 00:02:00 2 \u00b6 2020-01-01 00:03:00 3 \u00b6 2020-01-01 00:04:00 4 \u00b6 2020-01-01 00:05:00 5 \u00b6 2020-01-01 00:06:00 6 \u00b6 2020-01-01 00:07:00 7 \u00b6 2020-01-01 00:08:00 8 \u00b6 2020-01-01 00:09:00 9 \u00b6 2020-01-01 00:10:00 10 \u00b6 2020-01-01 00:11:00 11 \u00b6 Freq: T, dtype: int64 \u00b6 \u6309\u4e94\u5206\u949f\u9891\u7387\u805a\u5408\u5206\u7ec4\uff0c\u8ba1\u7b97\u6bcf\u4e00\u7ec4\u7684\u52a0\u548c\u3002\u9891\u7387\u6309\u4e94\u5206\u949f\u7684\u589e\u91cf\u5b9a\u4e49\u4e86\u7bb1\u4f53\u8fb9\u754c\u3002 \u9ed8\u8ba4\u60c5\u51b5\u4e0b\uff0c\u5de6\u7bb1\u4f53\u8fb9\u754c\u662f\u5305\u542b\u7684\uff0c\u56e0\u6b6400:00\u7684\u503c\u662f\u5305\u542b\u572800:00\u523000:05\u95f4\u9694\u5185\u7684\u3002 \u4f20\u9012`closed='right'`\u5c06\u95f4\u9694\u7684\u95ed\u5408\u7aef\u6539\u4e3a\u4e86\u53f3\u8fb9\u3002 \u5206\u7ec4\uff1a * left: [00:00,00:01,00:02,00:03,00:04],[00:05,00:06,00:07,00:08,00:09],[00:10,00:11] * right:[00:00],[00:01,00:02,00:03,00:04,00:05],[00:06,00:07,00:08,00:09,00:10],[00:11] result = ts.resample('5min', closed='right').sum() print(result) 2019-12-31 23:55:00 0 \u00b6 2020-01-01 00:00:00 15 \u00b6 2020-01-01 00:05:00 40 \u00b6 2020-01-01 00:10:00 11 \u00b6 Freq: 5T, dtype: int64 \u00b6 result = ts.resample('5min', closed='left').sum() print(result) 2020-01-01 00:00:00 10 \u00b6 2020-01-01 00:05:00 35 \u00b6 2020-01-01 00:10:00 21 \u00b6 Freq: 5T, dtype: int64 \u00b6 \u6700\u540e\uff0c\u5c06\u7ed3\u679c\u7d22\u5f15\u79fb\u52a8\u4e00\u5b9a\u7684\u6570\u91cf\uff0c\u4f8b\u5982\u4ece\u53f3\u8fb9\u7f18\u51cf\u53bb\u4e00\u79d2\uff0c\u4ee5\u4f7f\u5176\u66f4\u6e05\u695a\u5730\u8868\u660e\u65f6\u95f4\u6233\u6240\u6307\u7684\u95f4\u9694\u3002 \u8981\u5b9e\u73b0\u8fd9\u4e2a\u529f\u80fd\uff0c\u5411`loffset`\u4f20\u9012\u5b57\u7b26\u4e32\u6216\u65e5\u671f\u504f\u7f6e\uff1a result = ts.resample('5min', closed='right', label='right', loffset='-1s').sum() print(result) 2019-12-31 23:59:59 0 \u00b6 2020-01-01 00:04:59 15 \u00b6 2020-01-01 00:09:59 40 \u00b6 2020-01-01 00:14:59 11 \u00b6 Freq: 5T, dtype: int64 \u00b6 FutureWarning: 'loffset' in .resample() and in Grouper() is deprecated. \u00b6 >>> df.resample(freq=\"3s\", loffset=\"8H\") \u00b6 becomes: \u00b6 >>> from pandas.tseries.frequencies import to_offset \u00b6 >>> df = df.resample(freq=\"3s\").mean() \u00b6 >>> df.index = df.index.to_timestamp() + to_offset(\"8H\") \u00b6 #### \u5f00\u7aef-\u5cf0\u503c-\u8c37\u503c-\u7ed3\u675f\uff08OHLC\uff09\u91cd\u65b0\u91c7\u6837 \u5728\u91d1\u878d\u4e2d\uff0c\u4e3a\u6bcf\u4e2a\u6570\u636e\u6876\u8ba1\u7b97\u56db\u4e2a\u503c\u662f\u4e00\u79cd\u6d41\u884c\u7684\u65f6\u95f4\u5e8f\u5217\u805a\u5408\u65b9\u6cd5\uff1a\u7b2c\u4e00\u4e2a\u503c\uff08\u5f00\u7aef\uff09\u3001\u6700\u540e\u4e00\u4e2a\u503c\uff08\u7ed3\u675f\uff09\u3001\u6700\u5927\u503c\uff08\u5cf0\u503c\uff09\u548c\u6700\u5c0f\u503c\uff08\u8c37\u503c\uff09\u3002 \u901a\u8fc7\u4f7f\u7528`ohlc`\u805a\u5408\u51fd\u6570\u53d6\u5f97\u5305\u542b\u56db\u79cd\u805a\u5408\u503c\u5217\u7684DataFrame\uff0c\u8fd9\u4e9b\u503c\u5728\u6570\u636e\u7684\u5355\u6b21\u626b\u63cf\u4e2d\u88ab\u9ad8\u6548\u8ba1\u7b97\uff1a result = ts.resample('5min').ohlc() print(result) open high low close \u00b6 2020-01-01 00:00:00 0 4 0 4 \u00b6 2020-01-01 00:05:00 5 9 5 9 \u00b6 2020-01-01 00:10:00 10 11 10 11 \u00b6 ### \u5411\u4e0a\u91c7\u6837\u4e0e\u63d2\u503c \u5f53\u4ece\u4f4e\u9891\u7387\u8f6c\u6362\u4e3a\u9ad8\u9891\u7387\u65f6\uff0c\u5e76\u4e0d\u9700\u8981\u4efb\u4f55\u805a\u5408\u3002 df = pd.DataFrame( np.random.randn(2, 4), index=pd.date_range('2020/1/1', periods=2, freq='W-WED'), columns=['Colorado', 'Texas', 'New York', 'Ohio'] ) print(df) Colorado Texas New York Ohio \u00b6 2020-01-01 -0.228758 -0.758718 -0.025410 -1.001819 \u00b6 2020-01-08 -0.704541 -0.261414 -0.863335 0.267101 \u00b6 df_daily = df.resample('W-WED').sum() print(df_daily) Colorado Texas New York Ohio \u00b6 2020-01-01 -0.228758 -0.758718 -0.025410 -1.001819 \u00b6 2020-01-08 -0.704541 -0.261414 -0.863335 0.267101 \u00b6 df_daily = df.resample('D').sum() print(df_daily) Colorado Texas New York Ohio \u00b6 2020-01-01 -0.228758 -0.758718 -0.025410 -1.001819 \u00b6 2020-01-02 0.000000 0.000000 0.000000 0.000000 \u00b6 2020-01-03 0.000000 0.000000 0.000000 0.000000 \u00b6 2020-01-04 0.000000 0.000000 0.000000 0.000000 \u00b6 2020-01-05 0.000000 0.000000 0.000000 0.000000 \u00b6 2020-01-06 0.000000 0.000000 0.000000 0.000000 \u00b6 2020-01-07 0.000000 0.000000 0.000000 0.000000 \u00b6 2020-01-08 -0.704541 -0.261414 -0.863335 0.267101 \u00b6 \u5f53\u5bf9\u8fd9\u4e9b\u6570\u636e\u4f7f\u7528\u805a\u5408\u51fd\u6570\u65f6\uff0c\u6bcf\u4e00\u7ec4\u53ea\u6709\u4e00\u4e2a\u503c\uff0c\u5e76\u4e14\u4f1a\u5728\u95f4\u9699\u4e2d\u4ea7\u751f\u7f3a\u5931\u503c\u3002 \u4f7f\u7528`asfreq`\u65b9\u6cd5\u5728\u4e0d\u805a\u5408\u7684\u60c5\u51b5\u4e0b\u8f6c\u6362\u5230\u9ad8\u9891\u7387\uff1a df_daily = df.resample('D').asfreq() print(df_daily) Colorado Texas New York Ohio \u00b6 2020-01-01 -0.228758 -0.758718 -0.025410 -1.001819 \u00b6 2020-01-02 NaN NaN NaN NaN \u00b6 2020-01-03 NaN NaN NaN NaN \u00b6 2020-01-04 NaN NaN NaN NaN \u00b6 2020-01-05 NaN NaN NaN NaN \u00b6 2020-01-06 NaN NaN NaN NaN \u00b6 2020-01-07 NaN NaN NaN NaN \u00b6 2020-01-08 -0.704541 -0.261414 -0.863335 0.267101 \u00b6 \u5728\u975e\u661f\u671f\u4e09\u7684\u65e5\u671f\u4e0a\u5411\u524d\u586b\u5145\u6bcf\u5468\u6570\u503c\u3002`fillna`\u548c`reindex`\u65b9\u6cd5\u4e2d\u53ef\u7528\u7684\u586b\u5145\u6216\u63d2\u503c\u65b9\u6cd5\u53ef\u7528\u4e8e\u91cd\u91c7\u6837\uff1a df_daily = df.resample('D').ffill() print(df_daily) Colorado Texas New York Ohio \u00b6 2020-01-01 -0.228758 -0.758718 -0.025410 -1.001819 \u00b6 2020-01-02 -0.228758 -0.758718 -0.025410 -1.001819 \u00b6 2020-01-03 -0.228758 -0.758718 -0.025410 -1.001819 \u00b6 2020-01-04 -0.228758 -0.758718 -0.025410 -1.001819 \u00b6 2020-01-05 -0.228758 -0.758718 -0.025410 -1.001819 \u00b6 2020-01-06 -0.228758 -0.758718 -0.025410 -1.001819 \u00b6 2020-01-07 -0.228758 -0.758718 -0.025410 -1.001819 \u00b6 2020-01-08 -0.704541 -0.261414 -0.863335 0.267101 \u00b6 \u53ef\u4ee5\u540c\u6837\u9009\u62e9\u4ec5\u5411\u524d\u586b\u5145\u4e00\u5b9a\u6570\u91cf\u7684\u533a\u95f4\uff0c\u4ee5\u9650\u5236\u7ee7\u7eed\u4f7f\u7528\u89c2\u6d4b\u503c\u7684\u65f6\u8ddd\uff1a df_daily = df.resample('D').ffill(limit=2) print(df_daily) Colorado Texas New York Ohio \u00b6 2020-01-01 -0.228758 -0.758718 -0.025410 -1.001819 \u00b6 2020-01-02 -0.228758 -0.758718 -0.025410 -1.001819 \u00b6 2020-01-03 -0.228758 -0.758718 -0.025410 -1.001819 \u00b6 2020-01-04 NaN NaN NaN NaN \u00b6 2020-01-05 NaN NaN NaN NaN \u00b6 2020-01-06 NaN NaN NaN NaN \u00b6 2020-01-07 NaN NaN NaN NaN \u00b6 2020-01-08 -0.704541 -0.261414 -0.863335 0.267101 \u00b6 \u6ce8\u610f\uff0c\u65b0\u7684\u65e5\u671f\u7d22\u5f15\u4e0d\u9700\u8981\u4e0e\u65e7\u7684\u7d22\u5f15\u91cd\u53e0\uff0c\u548c\u539f\u6765`df`\u7684\u503c\u4e00\u6837\uff0c\u53ea\u662f\u65e5\u671f\u7d22\u5f15\u53d8\u4e86\u3002 df_new = df.resample('W-THU').ffill() print(df_new) Colorado Texas New York Ohio \u00b6 2020-01-02 -0.228758 -0.758718 -0.025410 -1.001819 \u00b6 2020-01-09 -0.704541 -0.261414 -0.863335 0.267101 \u00b6 ### \u4f7f\u7528\u533a\u95f4\u8fdb\u884c\u91cd\u65b0\u91c7\u6837 \u5bf9\u4ee5\u533a\u95f4\u4e3a\u7d22\u5f15\u7684\u6570\u636e\u8fdb\u884c\u91c7\u6837\u4e0e\u65f6\u95f4\u6233\u7684\u60c5\u51b5\u7c7b\u4f3c\uff1a df = pd.DataFrame( np.random.randn(24, 4), index=pd.period_range('2020-1', periods=24, freq='M'), columns=['Colorado', 'Texas', 'New York', 'Ohio'] ) print(df) 2020-01 0.721395 -1.492674 0.707410 1.641890 \u00b6 2020-02 -0.894880 0.032823 -0.676158 0.029203 \u00b6 2020-03 2.147365 -0.176796 0.562695 -0.747656 \u00b6 2020-04 1.496037 -0.797119 -0.495601 0.774147 \u00b6 2020-05 -0.309839 0.502563 0.237244 0.910624 \u00b6 2020-06 1.231869 -0.105227 1.315759 0.217701 \u00b6 2020-07 1.447419 0.263876 -0.342045 -0.768907 \u00b6 2020-08 -2.567162 -1.008827 0.391085 1.259560 \u00b6 2020-09 -0.772501 1.183532 0.450374 0.450714 \u00b6 2020-10 0.228974 0.461224 1.393178 0.175243 \u00b6 2020-11 -0.725193 -1.544131 1.372029 -0.659224 \u00b6 2020-12 0.718195 0.862024 -0.166460 -0.940191 \u00b6 2021-01 -0.617054 -0.887312 0.338451 -1.392838 \u00b6 2021-02 -0.081140 0.634730 -0.868051 -1.277167 \u00b6 2021-03 -0.999642 -1.959715 -0.930662 0.748687 \u00b6 2021-04 1.851453 1.561669 -0.688822 -0.371255 \u00b6 2021-05 -0.540777 -0.890403 -1.204188 0.243480 \u00b6 2021-06 1.318905 1.247457 0.518969 0.799793 \u00b6 2021-07 0.223238 0.747177 -0.410889 0.904593 \u00b6 2021-08 -0.652551 -0.254351 -0.464604 -0.676923 \u00b6 2021-09 0.562312 0.182099 0.018617 0.573331 \u00b6 2021-10 0.429490 -0.045959 -0.356292 -0.295776 \u00b6 2021-11 2.552155 0.801299 1.378421 1.232792 \u00b6 2021-12 1.102288 0.850280 -0.767015 -0.519840 \u00b6 df_annual = df.resample('A-DEC').mean() print(df_annual) Colorado Texas New York Ohio \u00b6 2020 0.226807 -0.151561 0.395793 0.195259 \u00b6 2021 0.429056 0.165581 -0.286339 -0.002594 \u00b6 \u5411\u4e0a\u91c7\u6837\u66f4\u4e3a\u7ec6\u81f4\uff0c\u56e0\u4e3a\u5fc5\u987b\u5728\u91cd\u65b0\u91c7\u6837\u524d\u51b3\u5b9a\u65b0\u9891\u7387\u4e2d\u5728\u65f6\u95f4\u6bb5\u7684\u54ea\u4e00\u7aef\u653e\u7f6e\u6570\u503c\uff0c\u5c31\u50cfasfreq\u65b9\u6cd5\u4e00\u6837\u3002 `convention`\u53c2\u6570\u9ed8\u8ba4\u503c\u662f`start`\uff0c\u4f46\u4e5f\u53ef\u4ee5\u662f`end`\uff1a result = df_annual.resample('Q-DEC').ffill() print(result) Colorado Texas New York Ohio \u00b6 2020Q1 0.226807 -0.151561 0.395793 0.195259 \u00b6 2020Q2 0.226807 -0.151561 0.395793 0.195259 \u00b6 2020Q3 0.226807 -0.151561 0.395793 0.195259 \u00b6 2020Q4 0.226807 -0.151561 0.395793 0.195259 \u00b6 2021Q1 0.429056 0.165581 -0.286339 -0.002594 \u00b6 2021Q2 0.429056 0.165581 -0.286339 -0.002594 \u00b6 2021Q3 0.429056 0.165581 -0.286339 -0.002594 \u00b6 2021Q4 0.429056 0.165581 -0.286339 -0.002594 \u00b6 result = df_annual.resample('Q-DEC', convention='end').ffill() print(result) Colorado Texas New York Ohio \u00b6 2020Q4 0.226807 -0.151561 0.395793 0.195259 \u00b6 2021Q1 0.226807 -0.151561 0.395793 0.195259 \u00b6 2021Q2 0.226807 -0.151561 0.395793 0.195259 \u00b6 2021Q3 0.226807 -0.151561 0.395793 0.195259 \u00b6 2021Q4 0.429056 0.165581 -0.286339 -0.002594 \u00b6 \u7531\u4e8e\u533a\u95f4\u6d89\u53ca\u65f6\u95f4\u8303\u56f4\uff0c\u5411\u4e0a\u91c7\u6837\u548c\u5411\u4e0b\u91c7\u6837\u5c31\u66f4\u4e3a\u4e25\u683c\uff1a * \u5728\u5411\u4e0b\u91c7\u6837\u4e2d\uff0c\u76ee\u6807\u9891\u7387\u5fc5\u987b\u662f\u539f\u9891\u7387\u7684\u5b50\u533a\u95f4\u3002 * \u5728\u5411\u4e0a\u91c7\u6837\u4e2d\uff0c\u76ee\u6807\u9891\u7387\u5fc5\u987b\u662f\u539f\u9891\u7387\u7684\u7236\u533a\u95f4\u3002 \u5982\u679c\u4e0d\u6ee1\u8db3\u8fd9\u4e9b\u89c4\u5219\uff0c\u5c06\u4f1a\u5f15\u8d77\u5f02\u5e38\u3002\u8fd9\u4e3b\u8981\u4f1a\u5f71\u54cd\u6bcf\u5b63\u5ea6\u3001\u6bcf\u5e74\u548c\u6bcf\u5468\u7684\u9891\u7387\u3002 \u4f8b\u5982\uff0c\u6839\u636eQ-MAR\u5b9a\u4e49\u7684\u65f6\u95f4\u8303\u56f4\u5c06\u53ea\u548cA-MAR\u3001A-JUN\u3001A-SEP\u548cA-DEC\u4fdd\u6301\u4e00\u81f4\uff1a result = df_annual.resample('Q-MAR').ffill() print(result) Colorado Texas New York Ohio \u00b6 2020Q4 0.226807 -0.151561 0.395793 0.195259 \u00b6 2021Q1 0.226807 -0.151561 0.395793 0.195259 \u00b6 2021Q2 0.226807 -0.151561 0.395793 0.195259 \u00b6 2021Q3 0.226807 -0.151561 0.395793 0.195259 \u00b6 2021Q4 0.429056 0.165581 -0.286339 -0.002594 \u00b6 2022Q1 0.429056 0.165581 -0.286339 -0.002594 \u00b6 2022Q2 0.429056 0.165581 -0.286339 -0.002594 \u00b6 2022Q3 0.429056 0.165581 -0.286339 -0.002594 \u00b6 ## \u79fb\u52a8\u7a97\u53e3\u51fd\u6570 \u7edf\u8ba1\u90a3\u4e9b\u901a\u8fc7\u79fb\u52a8\u7a97\u53e3\u6216\u6307\u6570\u8870\u51cf\u800c\u8fd0\u884c\u7684\u51fd\u6570\uff0c\u662f\u7528\u4e8e\u65f6\u95f4\u5e8f\u5217\u64cd\u4f5c\u7684\u6570\u7ec4\u53d8\u6362\u7684\u4e00\u4e2a\u91cd\u8981\u7c7b\u522b\u3002 \u8fd9\u5bf9\u5e73\u6ed1\u566a\u58f0\u6216\u7c97\u7cd9\u7684\u6570\u636e\u975e\u5e38\u6709\u7528\u3002\u79f0\u8fd9\u4e9b\u51fd\u6570\u4e3a\u79fb\u52a8\u7a97\u53e3\u51fd\u6570\uff0c\u5c3d\u7ba1\u5b83\u4e5f\u5305\u542b\u4e86\u4e00\u4e9b\u6ca1\u6709\u56fa\u5b9a\u957f\u5ea6\u7a97\u53e3\u7684\u51fd\u6570\uff0c\u6bd4\u5982\u6307\u6570\u52a0\u6743\u79fb\u52a8\u5e73\u5747\u3002 \u4e0e\u5176\u4ed6\u7684\u7edf\u8ba1\u51fd\u6570\u7c7b\u4f3c\uff0c\u8fd9\u4e9b\u51fd\u6570\u4f1a\u81ea\u52a8\u6392\u9664\u7f3a\u5931\u6570\u636e\u3002 import matplotlib.pyplot as plt import pandas as pd from scipy.stats import percentileofscore import numpy as np from pandas.tseries.offsets import Hour, Minute, Day, MonthEnd import pytz \u5728\u6df1\u5165\u4e86\u89e3\u4e4b\u524d\uff0c\u6211\u4eec\u53ef\u4ee5\u5148\u8f7d\u5165\u4e00\u4e9b\u65f6\u95f4\u5e8f\u5217\u6570\u636e\u5e76\u6309\u7167\u5de5\u4f5c\u65e5\u9891\u7387\u8fdb\u884c\u91cd\u65b0\u91c7\u6837\uff1a close_px_all = pd.read_csv( '../examples/stock_px_2.csv', parse_dates = True, index_col=0 ) print(close_px_all.head(5)) AAPL MSFT XOM SPX \u00b6 2003-01-02 7.40 21.11 29.22 909.03 \u00b6 2003-01-03 7.45 21.14 29.24 908.59 \u00b6 2003-01-06 7.45 21.52 29.96 929.01 \u00b6 2003-01-07 7.43 21.93 28.95 922.93 \u00b6 2003-01-08 7.28 21.31 28.83 909.93 \u00b6 close_px = close_px_all[ ['AAPL', 'MSFT', 'XOM'] ] close_px = close_px.resample('B').ffill() print(close_px) AAPL MSFT XOM \u00b6 2003-01-02 7.40 21.11 29.22 \u00b6 2003-01-03 7.45 21.14 29.24 \u00b6 ... ... ... ... \u00b6 2011-10-13 408.43 27.18 76.37 \u00b6 2011-10-14 422.00 27.27 78.11 \u00b6 [2292 rows x 3 columns] \u00b6 `rolling`\u7b97\u5b50\uff0c\u5b83\u7684\u884c\u4e3a\u4e0e`resample`\u548c`groupby`\u7c7b\u4f3c\u3002 `rolling`\u53ef\u4ee5\u5728Series\u6216DataFrame\u4e0a\u901a\u8fc7\u4e00\u4e2awindow\uff08\u4ee5\u4e00\u4e2a\u533a\u95f4\u7684\u6570\u5b57\u6765\u8868\u793a\uff09\u8fdb\u884c\u8c03\u7528\u3002 close_px.AAPL.plot() \u8868\u8fbe\u5f0f`rolling(250)`\u4e0e`groupby`\u7684\u884c\u4e3a\u7c7b\u4f3c\uff0c\u4f46\u662f\u5b83\u521b\u5efa\u7684\u5bf9\u8c61\u662f\u6839\u636e250\u65e5\u6ed1\u52a8\u7a97\u53e3\u5206\u7ec4\u7684\u800c\u4e0d\u662f\u76f4\u63a5\u5206\u7ec4\u3002 \u56e0\u6b64\u8fd9\u91cc\u6211\u4eec\u83b7\u5f97\u4e86\u82f9\u679c\u516c\u53f8\u80a1\u7968\u4ef7\u683c\u7684250\u65e5\u79fb\u52a8\u7a97\u53e3\u5e73\u5747\u503c\u3002 close_px.AAPL.rolling(250).mean().plot() plt.show() \u9ed8\u8ba4\u60c5\u51b5\u4e0b\uff0c\u6eda\u52a8\u51fd\u6570\u9700\u8981\u7a97\u53e3\u4e2d\u6240\u6709\u7684\u503c\u5fc5\u987b\u662f\u975e`NA`\u503c\u3002 \u7531\u4e8e\u5b58\u5728\u7f3a\u5931\u503c\u8fd9\u79cd\u884c\u4e3a\u4f1a\u53d1\u751f\u6539\u53d8\uff0c\u5c24\u5176\u662f\u5728\u65f6\u95f4\u5e8f\u5217\u7684\u8d77\u59cb\u4f4d\u7f6e\u4f60\u62e5\u6709\u7684\u6570\u636e\u662f\u5c11\u4e8e\u7a97\u53e3\u533a\u95f4\u7684 apple_std250 = close_px.AAPL.rolling(250, min_periods=10).std() # \u82f9\u679c\u516c\u53f8250\u65e5\u6bcf\u65e5\u8fd4\u56de\u6807\u51c6\u5dee print(apple_std250[5:12]) 2003-01-09 NaN \u00b6 2003-01-10 NaN \u00b6 2003-01-13 NaN \u00b6 2003-01-14 NaN \u00b6 2003-01-15 0.077496 \u00b6 2003-01-16 0.074760 \u00b6 2003-01-17 0.112368 \u00b6 Freq: B, Name: AAPL, dtype: float64 \u00b6 apple_std250.plot() plt.show() expanding_mean = apple_std250.expanding().mean() print(expanding_mean[5:12]) 2003-01-09 NaN \u00b6 2003-01-10 NaN \u00b6 2003-01-13 NaN \u00b6 2003-01-14 NaN \u00b6 2003-01-15 0.077496 \u00b6 2003-01-16 0.076128 \u00b6 2003-01-17 0.088208 \u00b6 Freq: B, Name: AAPL, dtype: float64 \u00b6 expanding_mean.plot() plt.show() \u5728DataFrame\u4e0a\u8c03\u7528\u4e00\u4e2a\u79fb\u52a8\u7a97\u53e3\u51fd\u6570\u4f1a\u5c06\u53d8\u6362\u5e94\u7528\u5230\u6bcf\u4e00\u5217\u4e0a: close_px.rolling(60).mean().plot(logy=True) # \u80a1\u7968\u4ef7\u683c60\u65e5MA\uff08Y\u8f74\u53d6\u5bf9\u6570\uff09 plt.show() `rolling`\u51fd\u6570\u4e5f\u63a5\u6536\u8868\u793a\u56fa\u5b9a\u5927\u5c0f\u7684\u65f6\u95f4\u504f\u7f6e\u5b57\u7b26\u4e32\uff0c\u800c\u4e0d\u53ea\u662f\u4e00\u4e2a\u533a\u95f4\u7684\u96c6\u5408\u6570\u5b57\u3002 \u5bf9\u4e0d\u89c4\u5219\u65f6\u95f4\u5e8f\u5217\u4f7f\u7528\u6ce8\u91ca\u975e\u5e38\u6709\u7528\u3002\u8fd9\u4e9b\u5b57\u7b26\u4e32\u53ef\u4ee5\u4f20\u9012\u7ed9`resample`\u3002 \u4f8b\u5982\uff0c\u6211\u4eec\u53ef\u4ee5\u50cf\u8fd9\u6837\u8ba1\u7b9720\u5929\u7684\u6eda\u52a8\u5e73\u5747\u503c\uff1a result = close_px.rolling('20D').mean() print(result) AAPL MSFT XOM \u00b6 2003-01-02 7.400000 21.110000 29.220000 \u00b6 ... ... ... ... \u00b6 2011-10-14 391.038000 26.048667 74.185333 \u00b6 [2292 rows x 3 columns] \u00b6 result.plot() plt.show() ### \u6307\u6570\u52a0\u6743\u51fd\u6570 \u6307\u5b9a\u4e00\u4e2a\u5e38\u6570\u8870\u51cf\u56e0\u5b50\u4ee5\u5411\u66f4\u591a\u8fd1\u671f\u89c2\u6d4b\u503c\u63d0\u4f9b\u66f4\u591a\u6743\u91cd\uff0c\u53ef\u4ee5\u66ff\u4ee3\u4f7f\u7528\u5177\u6709\u76f8\u7b49\u52a0\u6743\u89c2\u5bdf\u503c\u7684\u9759\u6001\u7a97\u53e3\u5c3a\u5bf8\u7684\u65b9\u6cd5\u3002 \u6709\u591a\u79cd\u65b9\u5f0f\u53ef\u4ee5\u6307\u5b9a\u8870\u51cf\u56e0\u5b50\u3002\u5176\u4e2d\u4e00\u79cd\u6d41\u884c\u7684\u65b9\u5f0f\u662f\u4f7f\u7528\u4e00\u4e2aspan\uff08\u8de8\u5ea6\uff09\uff0c\u8fd9\u4f7f\u5f97\u7ed3\u679c\u4e0e\u7a97\u53e3\u5927\u5c0f\u7b49\u4e8e\u8de8\u5ea6\u7684\u7b80\u5355\u79fb\u52a8\u7a97\u53e3\u51fd\u6570\u3002 \u7531\u4e8e\u6307\u6570\u52a0\u6743\u7edf\u8ba1\u503c\u7ed9\u66f4\u8fd1\u671f\u7684\u89c2\u6d4b\u503c\u4ee5\u66f4\u591a\u7684\u6743\u91cd\uff0c\u4e0e\u7b49\u6743\u91cd\u7684\u7248\u672c\u76f8\u6bd4\uff0c\u5b83\u5bf9\u53d8\u5316\u201c\u9002\u5e94\u201d\u5f97\u66f4\u5feb\u3002 pandas\u62e5\u6709`ewm`\u7b97\u5b50\uff0c\u540c`rolling`\u3001`expanding`\u7b97\u5b50\u4e00\u8d77\u4f7f\u7528\u3002 \u4ee5\u4e0b\u662f\u5c06\u82f9\u679c\u516c\u53f8\u80a1\u7968\u4ef7\u683c\u768460\u65e5\u5747\u7ebf\u4e0e`span=60`\u7684EW\u79fb\u52a8\u5e73\u5747\u7ebf\u8fdb\u884c\u6bd4\u8f83\u7684\u4f8b\u5b50\uff1a aapl_ex = close_px.AAPL['2006':'2007'] ma60 = aapl_ex.rolling(30, min_periods=20).mean() ewma60 = aapl_ex.ewm(span=30).mean() ma60.plot(style='k--', label='Simple MA') ewma60.plot(style='k-', label='EWMA') plt.legend() plt.show() ### \u4e8c\u5143\u79fb\u52a8\u7a97\u53e3\u51fd\u6570 \u4e00\u4e9b\u7edf\u8ba1\u7b97\u5b50\uff0c\u4f8b\u5982\u76f8\u5173\u5ea6\u548c\u534f\u65b9\u5dee\uff0c\u9700\u8981\u64cd\u4f5c\u4e24\u4e2a\u65f6\u95f4\u5e8f\u5217\u3002 \u4f8b\u5982\uff0c\u91d1\u878d\u5206\u6790\u5e08\u7ecf\u5e38\u5bf9\u80a1\u7968\u4e0e\u57fa\u51c6\u6307\u6570\uff08\u5982\u6807\u666e500\uff09\u7684\u5173\u8054\u6027\u611f\u5174\u8da3\u3002 \u6211\u4eec\u9996\u5148\u8ba1\u7b97\u6240\u6709\u6211\u4eec\u611f\u5174\u8da3\u7684\u65f6\u95f4\u5e8f\u5217\u7684\u767e\u5206\u6bd4\u53d8\u5316\uff1a spx_px = close_px_all['SPX'] spx_rets = spx_px.pct_change() returns = close_px.pct_change() \u5728\u8c03\u7528rolling\u540e\uff0ccorr\u805a\u5408\u51fd\u6570\u53ef\u4ee5\u6839\u636espx_rets\u8ba1\u7b97\u6eda\u52a8\u76f8\u5173\u6027\uff1a \u00b6 corr = returns.AAPL.rolling(125, min_periods=100).corr(spx_rets) # \u82f9\u679c\u516c\u53f8\u4e0e\u6807\u666e500\u7684\u516d\u4e2a\u6708\u7684\u6536\u76ca\u76f8\u5173\u6027 corr.plot() plt.show() corr = returns.rolling(125, min_periods=100).corr(spx_rets) # \u591a\u53ea\u80a1\u7968\u4e0e\u6807\u666e500\u7684\u516d\u4e2a\u6708\u6536\u76ca\u76f8\u5173\u6027 corr.plot() plt.show() ### \u7528\u6237\u81ea\u5b9a\u4e49\u7684\u79fb\u52a8\u7a97\u53e3\u51fd\u6570 \u5728`rolling`\u53ca\u5176\u76f8\u5173\u65b9\u6cd5\u4e0a\u4f7f\u7528apply\u65b9\u6cd5\u63d0\u4f9b\u4e86\u4e00\u79cd\u5728\u79fb\u52a8\u7a97\u53e3\u4e2d\u5e94\u7528\u4f60\u81ea\u5df1\u8bbe\u8ba1\u7684\u6570\u7ec4\u51fd\u6570\u7684\u65b9\u6cd5\u3002 \u552f\u4e00\u7684\u8981\u6c42\u662f\u8be5\u51fd\u6570\u4ece\u6bcf\u4e2a\u6570\u7ec4\u4e2d\u4ea7\u751f\u4e00\u4e2a\u5355\u503c\uff08\u7f29\u805a\uff09\u3002 \u4f8b\u5982\uff0c\u5c3d\u7ba1\u6211\u4eec\u53ef\u4ee5\u4f7f\u7528`rolling(...).quantile(q)`\u8ba1\u7b97\u6837\u672c\u7684\u5206\u4f4d\u6570\uff0c\u4f46\u6211\u4eec\u53ef\u80fd\u4f1a\u5bf9\u6837\u672c\u4e2d\u7279\u5b9a\u503c\u7684\u767e\u5206\u4f4d\u6570\u611f\u5174\u8da3\u3002 `scipy.stats.percentileofscore`\u51fd\u6570\u5c31\u662f\u5b9e\u73b0\u8fd9\u4e2a\u529f\u80fd\u7684\uff1a score_at_2percent = lambda x: percentileofscore(x, 0.02) result = returns.AAPL.rolling(250).apply(score_at_2percent) # \u4e00\u5e74\u7a97\u53e3\u4e0b\u82f9\u679c\u516c\u53f8\u80a1\u4ef72%\u6536\u76ca\u7684\u767e\u5206\u4f4d\u7b49\u7ea7 result.plot() plt.show() result = returns.rolling(250).apply(score_at_2percent) # \u4e00\u5e74\u7a97\u53e3\u4e0b\u6240\u6709\u516c\u53f8\u80a1\u4ef72%\u6536\u76ca\u7684\u767e\u5206\u4f4d\u7b49\u7ea7 result.plot() plt.show() ```","title":"\u65f6\u95f4\u5e8f\u5217"},{"location":"python/DataAnalysis/ch08/#_1","text":"","title":"\u65f6\u95f4\u5e8f\u5217"},{"location":"python/DataAnalysis/ch08/#_2","text":"\u65f6\u95f4\u5e8f\u5217\u6570\u636e\u5728\u5f88\u591a\u9886\u57df\u90fd\u662f\u91cd\u8981\u7684\u7ed3\u6784\u5316\u6570\u636e\u5f62\u5f0f\u3002\u5728\u591a\u4e2a\u65f6\u95f4\u70b9\u89c2\u6d4b\u6216\u6d4b\u91cf\u7684\u6570\u636e\u5f62\u6210\u4e86\u65f6\u95f4\u5e8f\u5217\u3002 \u8bb8\u591a\u65f6\u95f4\u5e8f\u5217\u662f\u56fa\u5b9a\u9891\u7387\u7684\uff0c\u4e5f\u5c31\u662f\u8bf4\u6570\u636e\u662f\u6839\u636e\u76f8\u540c\u7684\u89c4\u5219\u5b9a\u671f\u51fa\u73b0\u7684\uff0c\u4f8b\u5982\u6bcf15\u79d2\u3001\u6bcf5\u5206\u949f\u6216\u6bcf\u67081\u6b21\u3002 \u65f6\u95f4\u5e8f\u5217\u4e5f\u53ef\u4ee5\u662f\u4e0d\u89c4\u5219\u7684\uff0c\u6ca1\u6709\u56fa\u5b9a\u7684\u65f6\u95f4\u5355\u4f4d\u6216\u5355\u4f4d\u95f4\u7684\u504f\u79fb\u91cf\u3002 \u5982\u4f55\u6807\u8bb0\u548c\u5f15\u7528\u65f6\u95f4\u5e8f\u5217\u6570\u636e\u53d6\u51b3\u4e8e\u5e94\u7528\u7a0b\u5e8f\uff0c\u65f6\u95f4\u5e8f\u5217\u5305\u62ec\uff1a \u65f6\u95f4\u6233\uff0c\u5177\u4f53\u7684\u65f6\u523b\u3002 \u56fa\u5b9a\u7684\u65f6\u95f4\u533a\u95f4\uff0c\u4f8b\u59822007\u76841\u6708\u6216\u6574\u4e2a2010\u5e74\u3002 \u65f6\u95f4\u95f4\u9694\uff0c\u7531\u5f00\u59cb\u548c\u7ed3\u675f\u65f6\u95f4\u6233\u8868\u793a\u3002\u65f6\u95f4\u533a\u95f4\u53ef\u4ee5\u88ab\u8ba4\u4e3a\u662f\u95f4\u9694\u7684\u7279\u6b8a\u60c5\u51b5\u3002 \u5b9e\u9a8c\u65f6\u95f4\u6216\u6d88\u8017\u65f6\u95f4\u3002\u6bcf\u4e2a\u65f6\u95f4\u6233\u662f\u76f8\u5bf9\u4e8e\u7279\u5b9a\u5f00\u59cb\u65f6\u95f4\u7684\u65f6\u95f4\u7684\u91cf\u5ea6\uff08\u4f8b\u5982\uff0c\u81ea\u4ece\u88ab\u653e\u7f6e\u5728\u70e4\u7bb1\u4e2d\u6bcf\u79d2\u70d8\u70e4\u7684\u997c\u5e72\u7684\u76f4\u5f84\uff09\u3002 \u76ee\u524d\u4e3b\u8981\u5173\u6ce8\u524d\u4e09\u7c7b\u4e2d\u7684\u65f6\u95f4\u5e8f\u5217\u3002 from datetime import datetime, timedelta import datetime as dt from dateutil.parser import parse import pandas as pd","title":"\u65e5\u671f\u548c\u65f6\u95f4\u6570\u636e\u7684\u7c7b\u578b\u53ca\u5de5\u5177"},{"location":"python/DataAnalysis/ch08/#datetime","text":"datetime\u683c\u5f0f\u7b26\uff1a %a \u661f\u671f\u7684\u82f1\u6587\u5355\u8bcd\u7684\u7f29\u5199\uff1a\u5982\u661f\u671f\u4e00\uff0c \u5219\u8fd4\u56de Mon %A \u661f\u671f\u7684\u82f1\u6587\u5355\u8bcd\u7684\u5168\u62fc\uff1a\u5982\u661f\u671f\u4e00\uff0c\u8fd4\u56de Monday %b \u6708\u4efd\u7684\u82f1\u6587\u5355\u8bcd\u7684\u7f29\u5199\uff1a\u5982\u4e00\u6708\uff0c \u5219\u8fd4\u56de Jan %B \u6708\u4efd\u7684\u5f15\u6587\u5355\u8bcd\u7684\u7f29\u5199\uff1a\u5982\u4e00\u6708\uff0c \u5219\u8fd4\u56de January %c \u8fd4\u56dedatetime\u7684\u5b57\u7b26\u4e32\u8868\u793a\uff0c\u598203/08/15 23:01:26 %d \u8fd4\u56de\u7684\u662f\u5f53\u524d\u65f6\u95f4\u662f\u5f53\u524d\u6708\u7684\u7b2c\u51e0\u5929 %f \u5fae\u79d2\u7684\u8868\u793a\uff1a \u8303\u56f4: [0,999999] %H \u4ee524\u5c0f\u65f6\u5236\u8868\u793a\u5f53\u524d\u5c0f\u65f6 %I \u4ee512\u5c0f\u65f6\u5236\u8868\u793a\u5f53\u524d\u5c0f\u65f6 %m \u8fd4\u56de\u6708\u4efd \u8303\u56f4[0,12] %M \u8fd4\u56de\u5206\u949f\u6570 \u8303\u56f4 [0,59] %P \u8fd4\u56de\u662f\u4e0a\u5348\u8fd8\u662f\u4e0b\u5348\u2013AM or PM %S \u8fd4\u56de\u79d2\u6570 \u8303\u56f4 [0,61]\u3002\u3002\u3002\u624b\u518c\u8bf4\u660e\u7684 %U \u8fd4\u56de\u5f53\u5468\u662f\u5f53\u5e74\u7684\u7b2c\u51e0\u5468 \u4ee5\u5468\u65e5\u4e3a\u7b2c\u4e00\u5929 %W \u8fd4\u56de\u5f53\u5468\u662f\u5f53\u5e74\u7684\u7b2c\u51e0\u5468 \u4ee5\u5468\u4e00\u4e3a\u7b2c\u4e00\u5929 %w \u5f53\u5929\u5728\u5f53\u5468\u7684\u5929\u6570\uff0c\u8303\u56f4\u4e3a[0, 6]\uff0c6\u8868\u793a\u661f\u671f\u5929 %x \u65e5\u671f\u7684\u5b57\u7b26\u4e32\u8868\u793a \uff1a03/08/15 %X \u65f6\u95f4\u7684\u5b57\u7b26\u4e32\u8868\u793a \uff1a23:22:08 %y \u4e24\u4e2a\u6570\u5b57\u8868\u793a\u7684\u5e74\u4efd 15 %Y \u56db\u4e2a\u6570\u5b57\u8868\u793a\u7684\u5e74\u4efd 2015 %z \u4e0eutc\u65f6\u95f4\u7684\u95f4\u9694 \uff08\u5982\u679c\u662f\u672c\u5730\u65f6\u95f4\uff0c\u8fd4\u56de\u7a7a\u5b57\u7b26\u4e32\uff09 %Z \u65f6\u533a\u540d\u79f0\uff08\u5982\u679c\u662f\u672c\u5730\u65f6\u95f4\uff0c\u8fd4\u56de\u7a7a\u5b57\u7b26\u4e32\uff09 datestrs = ['2020/5/6', '2021/10/1'] # \u6ce8\u610f\u533a\u5206datetime\u6a21\u5757\u548cdatetime\u7c7b\uff0c\u540d\u5b57\u76f8\u540c\uff0c\u5bb9\u6613\u5f15\u8d77\u9519\u8bef\u3002 # \u6bd4\u5982datetime.datetime\u5c31\u62a5\u9519type object 'datetime.datetime' has no attribute 'datetime' print(datetime) # print(dt) # Python\u6807\u51c6\u5e93\u5305\u542b\u4e86\u65e5\u671f\u548c\u65f6\u95f4\u6570\u636e\u7684\u7c7b\u578b\u3002 datetime \u3001 time \u548c calendar \u6a21\u5757\u662f\u5f00\u59cb\u5904\u7406\u65f6\u95f4\u6570\u636e\u7684\u4e3b\u8981\u5185\u5bb9\u3002 datetime.datetime \u7c7b\u578b\uff0c\u6216\u7b80\u5199\u4e3a datetime \uff0c\u662f\u5e7f\u6cdb\u4f7f\u7528\u7684\u3002 now = datetime.now() print(now) # 2021-10-07 20:24:43.834293 result = dt.datetime(2021, 10, 7, 20, 26, 00, 72973) print(result) # 2021-10-07 20:26:00.072973 datetime \u65e2\u5b58\u50a8\u4e86\u65e5\u671f\uff0c\u4e5f\u5b58\u50a8\u4e86\u7ec6\u5316\u5230\u5fae\u79d2\u7684\u65f6\u95f4\u3002 timedelta \u8868\u793a\u4e24\u4e2a datetime \u5bf9\u8c61\u7684\u65f6\u95f4\u5dee\u3002 delta = datetime(2021, 10, 7) - datetime(2021, 9, 7) print(delta) # 30 days, 0:00:00 print(delta.days) # 30 print(delta.seconds) # 0 result = dt.timedelta(926, 56700) print(result) # 926 days, 15:45:00 \u53ef\u4ee5\u4e3a\u4e00\u4e2a datetime \u5bf9\u8c61\u52a0\u4e0a\uff08\u6216\u51cf\u53bb\uff09\u4e00\u4e2a timedelta \u6216\u5176\u6574\u6570\u500d\u6765\u4ea7\u751f\u4e00\u4e2a\u65b0\u7684 datetime \u5bf9\u8c61\u3002 start = datetime(2021, 10, 7) result = start + timedelta(12) print(result) # 2021-10-19 00:00:00 result = start - 2 * timedelta(5) print(result) # 2021-09-27 00:00:00","title":"datetime"},{"location":"python/DataAnalysis/ch08/#datetime_1","text":"\u4f7f\u7528 str \u65b9\u6cd5\u6216\u4f20\u9012\u4e00\u4e2a\u6307\u5b9a\u7684\u683c\u5f0f\u7ed9 strftime \u65b9\u6cd5\u6765\u5bf9 datetime \u5bf9\u8c61\u548cpandas\u7684 Timestamp \u5bf9\u8c61\u8fdb\u884c\u683c\u5f0f\u5316\u3002 stamp = datetime(2021, 10, 7) result = str(stamp) print(result) # 2021-10-07 00:00:00 \u4f7f\u7528 datetime.srtptime \u548c datetime \u683c\u5f0f\u7b26\uff0c\u628a\u5b57\u7b26\u4e32\u8f6c\u6362\u65e5\u671f\u3002 datetime.strptime \u662f\u5728\u5df2\u77e5\u683c\u5f0f\u7684\u60c5\u51b5\u4e0b\u8f6c\u6362\u65e5\u671f\u7684\u597d\u65b9\u5f0f\u3002 value = '2021-10-7' result = datetime.strptime(value, '%Y-%m-%d') print(result) # 2021-10-07 00:00:00 datestrs = ['2020/5/6', '2021/10/1'] result = [datetime.strptime(x, '%Y/%m/%d') for x in datestrs] print(result) # [datetime.datetime(2020, 5, 6, 0, 0), datetime.datetime(2021, 10, 1, 0, 0)] dateutil \u89e3\u6790\u901a\u7528\u65e5\u671f\u683c\u5f0f\uff1a print(parse('2020/5/6')) # 2020-05-06 00:00:00 print(parse('Jan 31, 2021 10:25 AM')) # 2021-01-31 10:25:00 print(parse('5/6/2021', dayfirst=True)) # \u65e5\u671f\u51fa\u73b0\u5728\u6708\u4efd\u4e4b\u524d # 2021-06-05 00:00:00 pandas\u4e3b\u8981\u662f\u9762\u5411\u5904\u7406\u65e5\u671f\u6570\u7ec4\u7684\uff0c\u65e0\u8bba\u662f\u7528\u4f5c\u8f74\u7d22\u5f15\u8fd8\u662f\u7528\u4f5cDataFrame\u4e2d\u7684\u5217\u3002 to_datetime \u65b9\u6cd5\u53ef\u4ee5\u8f6c\u6362\u5f88\u591a\u4e0d\u540c\u7684\u65e5\u671f\u8868\u793a\u683c\u5f0f\u3002 to_datetime \u65b9\u6cd5\u8fd8\u53ef\u4ee5\u5904\u7406\u90a3\u4e9b\u88ab\u8ba4\u4e3a\u662f\u7f3a\u5931\u503c\u7684\u503c\uff08None\u3001\u7a7a\u5b57\u7b26\u4e32\u7b49\uff09\u3002 NaT \uff08Not a time\uff09\u662fpandas\u4e2d\u65f6\u95f4\u6233\u6570\u636e\u7684\u662fnull\u503c\u3002 datestrs = ['2020/5/6 12:00:00', '2021/10/1 09:00:00'] result = pd.to_datetime(datestrs) print(result) # DatetimeIndex(['2020-05-06 12:00:00', '2021-10-01 09:00:00'], dtype='datetime64[ns]', freq=None) idx = pd.to_datetime(datestrs + [None]) print(idx) # DatetimeIndex(['2020-05-06 12:00:00', '2021-10-01 09:00:00', 'NaT'], dtype='datetime64[ns]', freq=None) print(idx[2]) # NaT print(pd.isnull(idx)) # [False False True]","title":"\u5b57\u7b26\u4e32\u4e0edatetime\u4e92\u76f8\u8f6c\u6362"},{"location":"python/DataAnalysis/ch08/#_3","text":"from datetime import datetime import pandas as pd import numpy as np","title":"\u65f6\u95f4\u5e8f\u5217\u57fa\u7840"},{"location":"python/DataAnalysis/ch08/#datetimeindex","text":"pandas\u4e2d\u7684\u57fa\u7840\u65f6\u95f4\u5e8f\u5217\u79cd\u7c7b\u662f\u7531\u65f6\u95f4\u6233\u7d22\u5f15\u7684Series\uff0c\u5728pandas\u5916\u90e8\u5219\u901a\u5e38\u8868\u793a\u4e3aPython\u5b57\u7b26\u4e32\u6216 datetime \u5bf9\u8c61\u3002 \u6240\u6709\u4f7f\u7528 datetime \u5bf9\u8c61\u7684\u5730\u65b9\u90fd\u53ef\u4ee5\u7528 Timestamp \u3002 dates = [ datetime(2021, 10, 1), datetime(2021, 10, 3), datetime(2021, 10, 5), datetime(2021, 10, 7), datetime(2021, 10, 9), datetime(2021, 10, 11) ] data = np.random.rand(6) ts = pd.Series(data, index=dates) print(ts) # 2021-10-01 0.678297 # 2021-10-03 0.538631 # 2021-10-05 0.934413 # 2021-10-07 0.018534 # 2021-10-09 0.938441 # 2021-10-11 0.173329 # dtype: float64 \u8fd9\u4e9b datetime \u5bf9\u8c61\u88ab\u653e\u5165 DatetimeIndex \u4e2d\u3002 print(ts.index) # DatetimeIndex(['2021-10-01', '2021-10-03', '2021-10-05', '2021-10-07', # '2021-10-09', '2021-10-11'], # dtype='datetime64[ns]', freq=None) DatetimeIndex \u4e2d\u7684\u6807\u91cf\u503c\u662f pandas \u7684 Timestamp \u5bf9\u8c61\uff1a stamp = ts.index[0] print(stamp) # 2021-10-01 00:00:00 \u548c\u5176\u4ed6Series\u7c7b\u4f3c\uff0c\u4e0d\u540c\u7d22\u5f15\u7684\u65f6\u95f4\u5e8f\u5217\u4e4b\u95f4\u7684\u7b97\u672f\u8fd0\u7b97\u5728\u65e5\u671f\u4e0a\u81ea\u52a8\u5bf9\u9f50\uff1a print(ts + ts[::2]) # ts[::2]\u4f1a\u5c06ts\u4e2d\u6bcf\u9694\u4e00\u4e2a\u7684\u5143\u7d20\u9009\u62e9\u51fa # 2021-10-01 1.356595 # 2021-10-03 NaN # 2021-10-05 1.868825 # 2021-10-07 NaN # 2021-10-09 1.876883 # 2021-10-11 NaN # dtype: float64 pandas\u4f7f\u7528NumPy\u7684 datetime64 \u6570\u636e\u7c7b\u578b\u5728\u7eb3\u79d2\u7ea7\u7684\u5206\u8fa8\u7387\u4e0b\u5b58\u50a8\u65f6\u95f4\u6233 print(ts.index.dtype) # datetime64[ns]","title":"DatetimeIndex"},{"location":"python/DataAnalysis/ch08/#_4","text":"\u5f53\u57fa\u4e8e\u6807\u7b7e\u8fdb\u884c\u7d22\u5f15\u548c\u9009\u62e9\u65f6\uff0c\u65f6\u95f4\u5e8f\u5217\u7684\u884c\u4e3a\u548c\u5176\u4ed6\u7684pandas.Series\u7c7b\u4f3c\uff1a stamp = ts.index[2] print(ts[stamp]) # 0.9344125159374457 \u5bf9\u5e942021-10-05 \u4e5f\u53ef\u4ee5\u4f20\u9012\u4e00\u4e2a\u80fd\u89e3\u91ca\u4e3a\u65e5\u671f\u7684\u5b57\u7b26\u4e32\uff1a print(ts['10/9/2021']) print(ts['20211003']) \u5bf9\u4e00\u4e2a\u957f\u7684\u65f6\u95f4\u5e8f\u5217\uff0c\u53ef\u4ee5\u4f20\u9012\u4e00\u4e2a\u5e74\u4efd\u6216\u4e00\u4e2a\u5e74\u4efd\u548c\u6708\u4efd\u6765\u9009\u62e9\u6570\u636e\u5207\u7247\uff1a data = np.random.randn(1000) longer_ts = pd.Series( data, index=pd.date_range('1/1/2021', periods=1000) ) print(longer_ts) # 2021-01-01 -0.009192 # 2021-01-02 -1.079068 # 2021-01-03 -1.851176 # 2021-01-04 1.347109 # 2021-01-05 -0.236394 # ... # 2023-09-23 -1.317943 # 2023-09-24 0.201741 # 2023-09-25 0.442282 # 2023-09-26 0.176137 # 2023-09-27 1.146437 # Freq: D, Length: 1000, dtype: float64 \u5b57\u7b26\u4e32\u20192001\u2019\u88ab\u89e3\u91ca\u4e3a\u4e00\u4e2a\u5e74\u4efd\uff0c\u5e76\u9009\u62e9\u4e86\u76f8\u5e94\u7684\u65f6\u95f4\u533a\u95f4\u3002 print(longer_ts['2021']) # 2021-01-01 2.170411 # 2021-01-02 1.186933 # 2021-01-03 0.399262 # 2021-01-04 -1.042606 # 2021-01-05 2.082112 # ... # 2021-12-27 -0.988282 # 2021-12-28 0.598683 # 2021-12-29 2.770580 # 2021-12-30 -1.463262 # 2021-12-31 -1.642846 # Freq: D, Length: 365, dtype: float64 \u6307\u5b9a\u4e86\u5e74\u4efd\u548c\u6708\u4efd\u4e5f\u662f\u6709\u6548\u7684\u3002 print(longer_ts['2021-10']) # 2021-10-01 0.712265 # 2021-10-02 1.195221 # 2021-10-03 -1.930220 # 2021-10-04 -0.720816 # 2021-10-05 0.081777 # 2021-10-06 -0.037466 # 2021-10-07 3.737303 # 2021-10-08 1.620383 # 2021-10-09 0.990797 # 2021-10-10 0.507850 # 2021-10-11 0.846935 # 2021-10-12 0.996947 # 2021-10-13 -1.078558 # 2021-10-14 0.871832 # 2021-10-15 -0.591698 # 2021-10-16 -0.805463 # 2021-10-17 0.160528 # 2021-10-18 -0.028474 # 2021-10-19 2.305579 # 2021-10-20 -1.132288 # 2021-10-21 0.649980 # 2021-10-22 0.615327 # 2021-10-23 0.185108 # 2021-10-24 0.857199 # 2021-10-25 -1.473752 # 2021-10-26 -0.895161 # 2021-10-27 -0.432717 # 2021-10-28 0.734504 # 2021-10-29 1.892493 # 2021-10-30 0.456619 # 2021-10-31 -0.255288 # Freq: D, dtype: float64 \u4f7f\u7528 datetime \u5bf9\u8c61\u8fdb\u884c\u5207\u7247\u4e5f\u662f\u53ef\u4ee5\u7684\uff1a print(longer_ts[datetime(2023, 1, 6):]) # 2023-01-06 0.952591 # 2023-01-07 -0.900259 # 2023-01-08 0.925332 # 2023-01-09 0.173215 # 2023-01-10 -0.507791 # ... # 2023-09-23 -0.319989 # 2023-09-24 -1.105417 # 2023-09-25 -2.118769 # 2023-09-26 0.009420 # 2023-09-27 -0.310281 # Freq: D, Length: 265, dtype: float64 \u56e0\u4e3a\u5927\u90e8\u5206\u7684\u65f6\u95f4\u5e8f\u5217\u6570\u636e\u662f\u6309\u65f6\u95f4\u987a\u5e8f\u6392\u5e8f\u7684\uff0c\u53ef\u4ee5\u4f7f\u7528\u4e0d\u5305\u542b\u5728\u65f6\u95f4\u5e8f\u5217\u4e2d\u7684\u65f6\u95f4\u6233\u8fdb\u884c\u5207\u7247\uff0c\u4ee5\u6267\u884c\u8303\u56f4\u67e5\u8be2\uff1a print(longer_ts['2021/10/1':'2021/10/5']) # 2021-10-01 -0.591853 # 2021-10-02 -1.554564 # 2021-10-03 -0.712585 # 2021-10-04 -0.326657 # 2021-10-05 1.044887 # Freq: D, dtype: float64 \u4f7f\u7528 truncate \u5728\u4e24\u4e2a\u65e5\u671f\u95f4\u5bf9Series\u8fdb\u884c\u5207\u7247\uff1a print(longer_ts.truncate(after='2021/10/1')) # 2021-01-01 -0.906685 # 2021-01-02 -0.470732 # 2021-01-03 -0.041316 # 2021-01-04 -0.287356 # 2021-01-05 0.104268 # ... # 2021-09-27 -0.669198 # 2021-09-28 -2.222169 # 2021-09-29 -0.653814 # 2021-09-30 -0.625868 # 2021-10-01 0.872684 # Freq: D, Length: 274, dtype: float64 \u4e0a\u9762\u8fd9\u4e9b\u64cd\u4f5c\u4e5f\u90fd\u9002\u7528\u4e8eDataFrame\uff0c\u5e76\u5728\u5176\u884c\u4e0a\u8fdb\u884c\u7d22\u5f15\uff1a dates = pd.date_range('10/1/2020', periods=100, freq='W-WED') data = np.random.randn(100, 4) long_df = pd.DataFrame( data, index=dates, columns=['Colorado', 'Texas', 'New York', 'Ohio'] ) print(long_df) # Colorado Texas New York Ohio # 2020-10-07 -1.186789 2.020634 0.300076 -0.955234 # 2020-10-14 1.502838 0.965368 -0.797539 -0.292833 # ... ... ... ... ... # 2022-08-24 -0.253116 -0.263307 0.602425 0.370599 # 2022-08-31 0.907918 0.091939 0.789694 2.781535 # [100 rows x 4 columns] print(long_df.loc['10-2020']) # Colorado Texas New York Ohio # 2020-10-07 1.031616 -1.812038 -0.446577 0.395656 # 2020-10-14 -0.673167 0.198804 -0.439141 0.086004 # 2020-10-21 -1.139786 0.716820 0.006516 -0.284335 # 2020-10-28 -0.637939 1.647810 -0.750786 0.140637","title":"\u7d22\u5f15\u3001\u9009\u62e9\u3001\u5b50\u96c6"},{"location":"python/DataAnalysis/ch08/#_5","text":"\u5728\u67d0\u4e9b\u5e94\u7528\u4e2d\uff0c\u53ef\u80fd\u4f1a\u6709\u591a\u4e2a\u6570\u636e\u89c2\u5bdf\u503c\u843d\u5728\u7279\u5b9a\u7684\u65f6\u95f4\u6233\u4e0a\u3002\u4e0b\u9762\u662f\u4e2a\u4f8b\u5b50\uff1a dates = pd.DatetimeIndex( ['2021/1/1', '2021/1/2', '2021/1/2', '2021/1/2', '2021/1/3'] ) dup_ts = pd.Series( np.arange(5), index=dates ) print(dup_ts) # 2021-01-01 0 # 2021-01-02 1 # 2021-01-02 2 # 2021-01-02 3 # 2021-01-03 4 # dtype: int64 \u901a\u8fc7\u68c0\u67e5\u7d22\u5f15\u7684 is_unique \u5c5e\u6027\uff0c\u53ef\u4ee5\u770b\u51fa\u7d22\u5f15\u5e76\u4e0d\u662f\u552f\u4e00\u7684\uff1a print(dup_ts.index.is_unique) # False \u5bf9\u4e0a\u9762\u7684Series\u8fdb\u884c\u7d22\u5f15\uff0c\u7ed3\u679c\u662f\u6807\u91cf\u503c\u8fd8\u662fSeries\u5207\u7247\u53d6\u51b3\u4e8e\u662f\u5426\u6709\u65f6\u95f4\u6233\u662f\u91cd\u590d\u7684\uff1a result = dup_ts['2021/1/3'] print(result) # 4 result = dup_ts['2021/1/2'] print(result) # 2021-01-02 1 # 2021-01-02 2 # 2021-01-02 3 # dtype: int64 \u5047\u8bbe\u60f3\u8981\u805a\u5408\u542b\u6709\u975e\u552f\u4e00\u65f6\u95f4\u6233\u7684\u6570\u636e\u3002\u4e00\u79cd\u65b9\u5f0f\u5c31\u662f\u4f7f\u7528 groupby \u5e76\u4f20\u9012 level=0 \uff1a grouped = dup_ts.groupby(level=0) result = grouped.mean() print(result) # 2021-01-01 0.0 # 2021-01-02 2.0 # 2021-01-03 4.0 # dtype: float64 result = grouped.count() print(result) # 2021-01-01 1 # 2021-01-02 3 # 2021-01-03 1 # dtype: int64","title":"\u542b\u6709\u91cd\u590d\u7d22\u5f15\u7684\u65f6\u95f4\u5e8f\u5217"},{"location":"python/DataAnalysis/ch08/#_6","text":"from datetime import datetime, timedelta import pandas as pd import numpy as np from pandas.tseries.offsets import Hour, Minute, Day, MonthEnd pandas\u7684\u901a\u7528\u65f6\u95f4\u5e8f\u5217\u662f\u4e0d\u89c4\u5219\u7684\uff0c\u5373\u65f6\u95f4\u5e8f\u5217\u7684\u9891\u7387\u4e0d\u662f\u56fa\u5b9a\u7684\u3002 \u4f46\u6709\u65f6\u9700\u8981\u5904\u7406\u56fa\u5b9a\u9891\u7387\u7684\u573a\u666f\uff0c\u4f8b\u5982\u6bcf\u65e5\u7684\u3001\u6bcf\u6708\u7684\u6216\u6bcf15\u5206\u949f\u7684\u65f6\u95f4\u5e8f\u5217\u6570\u636e\u3002 \u53ef\u4ee5\u901a\u8fc7\u8c03\u7528resample\u65b9\u6cd5\u5c06\u6837\u672c\u65f6\u95f4\u5e8f\u5217\u8f6c\u6362\u4e3a\u56fa\u5b9a\u7684\u6bcf\u65e5\u9891\u7387\u6570\u636e\u3002 \u5728\u9891\u7387\u95f4\u8f6c\u6362\uff0c\u53c8\u79f0\u4e3a\u91cd\u65b0\u91c7\u6837\u3002 dates = [ datetime(2021, 10, 1), datetime(2021, 10, 3), datetime(2021, 10, 5), datetime(2021, 10, 7), datetime(2021, 10, 9), datetime(2021, 10, 11) ] data = np.random.rand(6) ts = pd.Series(data, index=dates) print(ts) # 2021-10-01 0.956685 # 2021-10-03 0.817168 # 2021-10-05 0.275543 # 2021-10-07 0.614226 # 2021-10-09 0.061377 # 2021-10-11 0.357080 # dtype: float64 resampler = ts.resample('D') # \u5b57\u7b26\u4e32\u2019D\u2019\u88ab\u89e3\u91ca\u4e3a\u6bcf\u65e5\u9891\u7387 print(resampler) # DatetimeIndexResampler [freq=, axis=0, closed=left, label=left, convention=start, origin=start_day]","title":"\u65e5\u671f\u8303\u56f4\u3001\u9891\u7387\u548c\u79fb\u4f4d"},{"location":"python/DataAnalysis/ch08/#_7","text":"pandas.date_range \u662f\u7528\u4e8e\u6839\u636e\u7279\u5b9a\u9891\u7387\u751f\u6210\u6307\u5b9a\u957f\u5ea6\u7684 DatetimeIndex \u3002 \u9ed8\u8ba4\u60c5\u51b5\u4e0b\uff0c date_range \u751f\u6210\u7684\u662f\u6bcf\u65e5\u7684\u65f6\u95f4\u6233\u3002\u5982\u679c\u53ea\u4f20\u9012\u4e00\u4e2a\u8d77\u59cb\u6216\u7ed3\u5c3e\u65e5\u671f\uff0c\u4f60\u5fc5\u987b\u4f20\u9012\u4e00\u4e2a\u7528\u4e8e\u751f\u6210\u8303\u56f4\u7684\u6570\u5b57\u3002 \u5f00\u59cb\u65e5\u671f\u548c\u7ed3\u675f\u65e5\u671f\u4e25\u683c\u5b9a\u4e49\u4e86\u751f\u6210\u65e5\u671f\u7d22\u5f15\u7684\u8fb9\u754c\u3002 index = pd.date_range('2021/1/1', '2021/1/30') print(index) index = pd.date_range(start='2021/1/1', periods=30) print(index) index = pd.date_range(end='2021/1/30', periods=30) print(index) # DatetimeIndex(['2021-01-01', '2021-01-02', '2021-01-03', '2021-01-04', # '2021-01-05', '2021-01-06', '2021-01-07', '2021-01-08', # '2021-01-09', '2021-01-10', '2021-01-11', '2021-01-12', # '2021-01-13', '2021-01-14', '2021-01-15', '2021-01-16', # '2021-01-17', '2021-01-18', '2021-01-19', '2021-01-20', # '2021-01-21', '2021-01-22', '2021-01-23', '2021-01-24', # '2021-01-25', '2021-01-26', '2021-01-27', '2021-01-28', # '2021-01-29', '2021-01-30'], # dtype='datetime64[ns]', freq='D') \u9ed8\u8ba4\u60c5\u51b5\u4e0b\uff0c date_range \u4fdd\u7559\u5f00\u59cb\u6216\u7ed3\u675f\u65f6\u95f4\u6233\u7684\u65f6\u95f4\uff08\u5982\u679c\u6709\u7684\u8bdd\uff09\u3002 normalize \u9009\u9879\u53ef\u4ee5\u5b9e\u73b0\u751f\u6210\u7684\u662f\u6807\u51c6\u5316\u4e3a\u96f6\u70b9\u7684\u65f6\u95f4\u6233\u3002 index = pd.date_range('2021/1/1 12:56:30', periods=5) print(index) # DatetimeIndex(['2021-01-01 12:56:30', '2021-01-02 12:56:30', # '2021-01-03 12:56:30', '2021-01-04 12:56:30', # '2021-01-05 12:56:30'], # dtype='datetime64[ns]', freq='D') index = pd.date_range('2021/1/1 12:56:30', periods=5, normalize=True) print(index) # DatetimeIndex(['2021-01-01', '2021-01-02', '2021-01-03', '2021-01-04', # '2021-01-05'], # dtype='datetime64[ns]', freq='D') Pandas\u65f6\u95f4\u5e8f\u5217\uff1a\u9891\u7387\u548c\u65e5\u671f\u504f\u79fb\u91cf\u3002 pandas\u4e2d\u7684\u9891\u7387\u662f\u7531\u4e00\u4e2a\u57fa\u7840\u9891\u7387(\u4f8b\u5982\u201c\u65e5\u201d\u3001\u201c\u6708\u201d)\u548c\u4e00\u4e2a\u4e58\u6570\u7ec4\u6210\u3002 \u57fa\u7840\u9891\u7387\u901a\u5e38\u4ee5\u4e00\u4e2a\u5b57\u7b26\u4e32\u522b\u540d\u8868\u793a\uff0c\u6bd4\u5982\u201cD\u201d\u8868\u793a\u65e5\uff0c\u201cM\u201d\u8868\u793a\u6708\u3002 \u5bf9\u4e8e\u6bcf\u4e2a\u57fa\u7840\u9891\u7387\uff0c\u90fd\u6709\u4e00\u4e2a\u88ab\u79f0\u4e3a\u65e5\u671f\u504f\u79fb\u91cf(dateoffset)\u7684\u5bf9\u8c61\u4e0e\u4e4b\u5bf9\u5e94\uff0c\u6bd4\u5982\u65e5\u671f\u504f\u79fb\u91cf Hour \u5bf9\u5e94\u7684\u9891\u7387\u662f H \u3002 \u5e38\u7528\u9891\u7387\u4e0e\u65e5\u671f\u504f\u79fb\u91cf\u3002 \u9891\u7387 \u65e5\u671f\u504f\u79fb\u91cf \u8bf4\u660e D Day \u65e5\u5386\u65e5 B BusinessDay \u5de5\u4f5c\u65e5 H Hour \u5c0f\u65f6 T/min Minute \u5206 S Second \u79d2 L/ms Milli \u6beb\u79d2 U Micro \u5fae\u79d2 M MonthEnd \u6bcf\u6708\u6700\u540e\u4e00\u4e2a\u65e5\u5386\u65e5 BM BusinessMonthEnd \u6bcf\u6708\u6700\u540e\u4e00\u4e2a\u5de5\u4f5c\u65e5 MS MonthBegin \u6bcf\u6708\u7b2c\u4e00\u4e2a\u65e5\u5386\u65e5 BMS BussinessMonthBegin \u6bcf\u6708\u7b2c\u4e00\u4e2a\u5de5\u4f5c\u65e5 W-MON, W-TUE, ... Week \u6307\u5b9a\u661f\u671f\u51e0(MON,TUE,WED,THU,FRI,SAT,SUN) WOM-1MON,WOM-2MON, ... WeekOfMonth \u4ea7\u751f\u6bcf\u6708\u7b2c\u4e00,\u7b2c\u4e8c,\u7b2c\u4e09\u6216\u7b2c\u56db\u5468\u7684\u661f\u671f\u51e0\u3002\u4f8b\u5982WOM-3FRI\u8868\u793a\u6bcf\u6708\u7b2c3\u4e2a\u661f\u671f\u4e94 Q-JAN,Q-FEB, ... QuarterEnd \u4ee5\u6307\u5b9a\u6708\u4efd\u7ed3\u675f\u7684\u5e74\u5ea6\uff0c\u6bcf\u5b63\u5ea6\u6700\u540e\u4e00\u4e2a\u6708\u7684\u6700\u540e\u4e00\u4e2a\u65e5\u5386\u65e5 BQ-JAN,BQ-FEB, ... BusinessQuarterEnd \u4ee5\u6307\u5b9a\u6708\u4efd\u7ed3\u675f\u7684\u5e74\u5ea6\uff0c\u6bcf\u5b63\u5ea6\u6700\u540e\u4e00\u4e2a\u6708\u7684\u6700\u540e\u4e00\u4e2a\u5de5\u4f5c\u65e5 QS-JAN,QS-FEB, ... QuarterBegin \u4ee5\u6307\u5b9a\u6708\u4efd\u7ed3\u675f\u7684\u5e74\u5ea6\uff0c\u6bcf\u5b63\u5ea6\u6700\u540e\u4e00\u4e2a\u6708\u7684\u7b2c\u4e00\u4e2a\u65e5\u5386\u65e5 BQS-JAN,BQS-FEB, ... BusinessQuarterBegin \u4ee5\u6307\u5b9a\u6708\u4efd\u7ed3\u675f\u7684\u5e74\u5ea6\uff0c\u6bcf\u5b63\u5ea6\u6700\u540e\u4e00\u4e2a\u6708\u7684\u7b2c\u4e00\u4e2a\u5de5\u4f5c\u65e5 A-JAN,A-FEB, ... YearEnd \u6bcf\u5e74\u6307\u5b9a\u6708\u4efd\u7684\u6700\u540e\u4e00\u4e2a\u65e5\u5386\u65e5 BA-JAN,BA-FEB, ... BusinessYearEnd \u6bcf\u5e74\u6307\u5b9a\u6708\u4efd\u7684\u6700\u540e\u4e00\u4e2a\u5de5\u4f5c\u65e5 AS-JAN,AS-FEB, ... YearBegin \u6bcf\u5e74\u6307\u5b9a\u6708\u4efd\u7684\u7b2c\u4e00\u4e2a\u65e5\u5386\u65e5 BAS-JAN,BAS-FEB, ... BusinessYearBegin \u6bcf\u5e74\u6307\u5b9a\u6708\u4efd\u7684\u7b2c\u4e00\u4e2a\u5de5\u4f5c\u65e5","title":"\u751f\u6210\u65e5\u671f\u8303\u56f4"},{"location":"python/DataAnalysis/ch08/#_8","text":"pandas\u4e2d\u7684\u9891\u7387\u662f\u7531\u57fa\u7840\u9891\u7387\u548c\u500d\u6570\u7ec4\u6210\u7684\u3002 \u57fa\u7840\u9891\u7387\u901a\u5e38\u4f1a\u6709\u5b57\u7b26\u4e32\u522b\u540d\uff0c\u4f8b\u5982 M \u4ee3\u8868\u6bcf\u6708\uff0c H \u4ee3\u8868\u6bcf\u5c0f\u65f6\u3002 \u5bf9\u4e8e\u6bcf\u4e2a\u57fa\u7840\u9891\u7387\uff0c\u90fd\u6709\u4e00\u4e2a\u5bf9\u8c61\u53ef\u4ee5\u88ab\u7528\u4e8e\u5b9a\u4e49\u65e5\u671f\u504f\u7f6e\u3002 \u4f8b\u5982\uff0c\u6bcf\u5c0f\u65f6\u7684\u9891\u7387\u53ef\u4ee5\u4f7f\u7528 Hour \u7c7b\u6765\u8868\u793a\uff1a ```hour = Hour() print(hour)","title":"\u9891\u7387\u548c\u65e5\u671f\u504f\u7f6e"},{"location":"python/DataAnalysis/ch08/#_9","text":"\u53ef\u4ee5\u4f20\u9012\u4e00\u4e2a\u6574\u6570\u6765\u5b9a\u4e49\u504f\u7f6e\u91cf\u7684\u500d\u6570\uff1a four_hours = Hour(4) print(four_hours)","title":""},{"location":"python/DataAnalysis/ch08/#4-hours","text":"\u5728\u5927\u591a\u6570\u5e94\u7528\u4e2d\uff0c\u4e0d\u9700\u8981\u663e\u5f0f\u5730\u521b\u5efa\u8fd9\u4e9b\u5bf9\u8c61\uff0c\u800c\u662f\u4f7f\u7528\u5b57\u7b26\u4e32\u522b\u540d\uff0c\u5982`H`\u6216`4H`\u3002\u5728\u57fa\u7840\u9891\u7387\u524d\u653e\u4e00\u4e2a\u6574\u6570\u5c31\u53ef\u4ee5\u751f\u6210\u500d\u6570\uff1a ts = pd.date_range('2021/1/1', '2021/\u00bd 23:59', freq='4h') print(ts)","title":"<4 * Hours>"},{"location":"python/DataAnalysis/ch08/#datetimeindex2021-01-01-000000-2021-01-01-040000","text":"","title":"DatetimeIndex(['2021-01-01 00:00:00', '2021-01-01 04:00:00',"},{"location":"python/DataAnalysis/ch08/#2021-01-01-080000-2021-01-01-120000","text":"","title":"'2021-01-01 08:00:00', '2021-01-01 12:00:00',"},{"location":"python/DataAnalysis/ch08/#2021-01-01-160000-2021-01-01-200000","text":"","title":"'2021-01-01 16:00:00', '2021-01-01 20:00:00',"},{"location":"python/DataAnalysis/ch08/#2021-01-02-000000-2021-01-02-040000","text":"","title":"'2021-01-02 00:00:00', '2021-01-02 04:00:00',"},{"location":"python/DataAnalysis/ch08/#2021-01-02-080000-2021-01-02-120000","text":"","title":"'2021-01-02 08:00:00', '2021-01-02 12:00:00',"},{"location":"python/DataAnalysis/ch08/#2021-01-02-160000-2021-01-02-200000","text":"","title":"'2021-01-02 16:00:00', '2021-01-02 20:00:00'],"},{"location":"python/DataAnalysis/ch08/#dtypedatetime64ns-freq4h","text":"\u591a\u4e2a\u504f\u7f6e\u53ef\u4ee5\u901a\u8fc7\u52a0\u6cd5\u8fdb\u884c\u8054\u5408\uff1a print(Hour(2) + Minute(30))","title":"dtype='datetime64[ns]', freq='4H')"},{"location":"python/DataAnalysis/ch08/#150-minutes","text":"\u7c7b\u4f3c\u5730\uff0c\u53ef\u4ee5\u4f20\u9012\u9891\u7387\u5b57\u7b26\u4e32\uff1a ts = pd.date_range('2021/1/1', '2021/1/1 23:59', freq='4h30min') print(ts)","title":"<150 * Minutes>"},{"location":"python/DataAnalysis/ch08/#datetimeindex2021-01-01-000000-2021-01-01-043000","text":"","title":"DatetimeIndex(['2021-01-01 00:00:00', '2021-01-01 04:30:00',"},{"location":"python/DataAnalysis/ch08/#2021-01-01-090000-2021-01-01-133000","text":"","title":"'2021-01-01 09:00:00', '2021-01-01 13:30:00',"},{"location":"python/DataAnalysis/ch08/#2021-01-01-180000-2021-01-01-223000","text":"","title":"'2021-01-01 18:00:00', '2021-01-01 22:30:00'],"},{"location":"python/DataAnalysis/ch08/#dtypedatetime64ns-freq270t","text":"\u6709\u4e9b\u9891\u7387\u63cf\u8ff0\u70b9\u7684\u65f6\u95f4\u5e76\u4e0d\u662f\u5747\u5300\u5206\u9694\u7684\u3002\u4f8b\u5982\uff0c`M`\uff08\u65e5\u5386\u6708\u672b\uff09\u548c`BM`\uff08\u6708\u5185\u6700\u540e\u5de5\u4f5c\u65e5\uff09\u53d6\u51b3\u4e8e\u5f53\u6708\u5929\u6570\uff0c\u6708\u672b\u662f\u5426\u662f\u5468\u672b\u3002\u6211\u4eec\u5c06\u8fd9\u4e9b\u65e5\u671f\u79f0\u4e3a\u951a\u5b9a\u504f\u7f6e\u91cf\u3002 #### \u6708\u4e2d\u67d0\u661f\u671f\u7684\u65e5\u671f \"\u6708\u4e2d\u67d0\u661f\u671f\"\uff08week of month \uff09\u7684\u65e5\u671f\u662f\u4e00\u4e2a\u6709\u7528\u7684\u9891\u7387\u7c7b\uff0c\u4ee5`WOM`\u5f00\u59cb\u3002 rng = pd.date_range('2021-1-1', '2021-9-1', freq='WOM-3FRI') # \u6bcf\u6708\u7b2c\u4e09\u4e2a\u661f\u671f\u4e94 print(rng)","title":"dtype='datetime64[ns]', freq='270T')"},{"location":"python/DataAnalysis/ch08/#datetimeindex2021-01-15-2021-02-19-2021-03-19-2021-04-16","text":"","title":"DatetimeIndex(['2021-01-15', '2021-02-19', '2021-03-19', '2021-04-16',"},{"location":"python/DataAnalysis/ch08/#2021-05-21-2021-06-18-2021-07-16-2021-08-20","text":"","title":"'2021-05-21', '2021-06-18', '2021-07-16', '2021-08-20'],"},{"location":"python/DataAnalysis/ch08/#dtypedatetime64ns-freqwom-3fri","text":"### \u79fb\u4f4d\uff08\u524d\u5411\u548c\u540e\u5411\uff09\u65e5\u671f \"\u79fb\u4f4d\"\u662f\u6307\u5c06\u65e5\u671f\u6309\u65f6\u95f4\u5411\u524d\u79fb\u52a8\u6216\u5411\u540e\u79fb\u52a8\u3002 Series\u548cDataFrame\u90fd\u6709\u4e00\u4e2a`shift`\u65b9\u6cd5\u7528\u4e8e\u8fdb\u884c\u7b80\u5355\u7684\u524d\u5411\u6216\u540e\u5411\u79fb\u4f4d\uff0c\u800c\u4e0d\u6539\u53d8\u7d22\u5f15\u3002 \u8fdb\u884c\u79fb\u4f4d\u65f6\uff0c\u4f1a\u5728\u65f6\u95f4\u5e8f\u5217\u7684\u8d77\u59cb\u4f4d\u6216\u7ed3\u675f\u4f4d\u5f15\u5165\u7f3a\u5931\u503c\u3002 data = [0.882972, 1.363282, -0.687750, -0.048117] ts = pd.Series(data, index=pd.date_range('2021-1-1', periods=4, freq='M')) print(ts)","title":"dtype='datetime64[ns]', freq='WOM-3FRI')"},{"location":"python/DataAnalysis/ch08/#2021-01-31-0882972","text":"","title":"2021-01-31 0.882972"},{"location":"python/DataAnalysis/ch08/#2021-02-28-1363282","text":"","title":"2021-02-28 1.363282"},{"location":"python/DataAnalysis/ch08/#2021-03-31-0687750","text":"","title":"2021-03-31 -0.687750"},{"location":"python/DataAnalysis/ch08/#2021-04-30-0048117","text":"","title":"2021-04-30 -0.048117"},{"location":"python/DataAnalysis/ch08/#freq-m-dtype-float64","text":"print(ts.shift(2))","title":"Freq: M, dtype: float64"},{"location":"python/DataAnalysis/ch08/#2021-01-31-nan","text":"","title":"2021-01-31 NaN"},{"location":"python/DataAnalysis/ch08/#2021-02-28-nan","text":"","title":"2021-02-28 NaN"},{"location":"python/DataAnalysis/ch08/#2021-03-31-0882972","text":"","title":"2021-03-31 0.882972"},{"location":"python/DataAnalysis/ch08/#2021-04-30-1363282","text":"","title":"2021-04-30 1.363282"},{"location":"python/DataAnalysis/ch08/#freq-m-dtype-float64_1","text":"print(ts.shift(-2))","title":"Freq: M, dtype: float64"},{"location":"python/DataAnalysis/ch08/#2021-01-31-0687750","text":"","title":"2021-01-31 -0.687750"},{"location":"python/DataAnalysis/ch08/#2021-02-28-0048117","text":"","title":"2021-02-28 -0.048117"},{"location":"python/DataAnalysis/ch08/#2021-03-31-nan","text":"","title":"2021-03-31 NaN"},{"location":"python/DataAnalysis/ch08/#2021-04-30-nan","text":"","title":"2021-04-30 NaN"},{"location":"python/DataAnalysis/ch08/#freq-m-dtype-float64_2","text":"`shift`\u5e38\u7528\u4e8e\u8ba1\u7b97\u65f6\u95f4\u5e8f\u5217\u6216DataFrame\u591a\u5217\u65f6\u95f4\u5e8f\u5217\u7684\u767e\u5206\u6bd4\u53d8\u5316\uff1a print(ts/ts.shift(1))","title":"Freq: M, dtype: float64"},{"location":"python/DataAnalysis/ch08/#2021-01-31-nan_1","text":"","title":"2021-01-31 NaN"},{"location":"python/DataAnalysis/ch08/#2021-02-28-1543970","text":"","title":"2021-02-28 1.543970"},{"location":"python/DataAnalysis/ch08/#2021-03-31-0504481","text":"","title":"2021-03-31 -0.504481"},{"location":"python/DataAnalysis/ch08/#2021-04-30-0069963","text":"","title":"2021-04-30 0.069963"},{"location":"python/DataAnalysis/ch08/#freq-m-dtype-float64_3","text":"print(ts/ts.shift(1) - 1)","title":"Freq: M, dtype: float64"},{"location":"python/DataAnalysis/ch08/#2021-01-31-nan_2","text":"","title":"2021-01-31 NaN"},{"location":"python/DataAnalysis/ch08/#2021-02-28-0543970","text":"","title":"2021-02-28 0.543970"},{"location":"python/DataAnalysis/ch08/#2021-03-31-1504481","text":"","title":"2021-03-31 -1.504481"},{"location":"python/DataAnalysis/ch08/#2021-04-30-0930037","text":"","title":"2021-04-30 -0.930037"},{"location":"python/DataAnalysis/ch08/#freq-m-dtype-float64_4","text":"\u5982\u679c\u9891\u7387\u662f\u5df2\u77e5\u7684\uff0c\u5219\u53ef\u4ee5\u5c06\u9891\u7387\u4f20\u9012\u7ed9`shift`\u6765\u63a8\u79fb\u65f6\u95f4\u6233\uff1a print(ts.shift(2, freq='M')) # \u539f\u59cb\u6570\u636e\u7684\u201c\u6708\u201c\u589e\u52a0\u4e86\u504f\u79fb\u503c","title":"Freq: M, dtype: float64"},{"location":"python/DataAnalysis/ch08/#2021-03-31-0882972_1","text":"","title":"2021-03-31 0.882972"},{"location":"python/DataAnalysis/ch08/#2022021-10-31-0000001-04-30-1363282","text":"","title":"2022021-10-31 00:00:001-04-30 1.363282"},{"location":"python/DataAnalysis/ch08/#2021-05-31-0687750","text":"","title":"2021-05-31 -0.687750"},{"location":"python/DataAnalysis/ch08/#2021-06-30-0048117","text":"","title":"2021-06-30 -0.048117"},{"location":"python/DataAnalysis/ch08/#freq-m-dtype-float64_5","text":"print(ts.shift(2, freq='D')) # \u539f\u59cb\u6570\u636e\u7684\u201c\u65e5\u201c\u589e\u52a0\u4e86\u504f\u79fb\u503c","title":"Freq: M, dtype: float64"},{"location":"python/DataAnalysis/ch08/#2021-02-02-0882972","text":"","title":"2021-02-02 0.882972"},{"location":"python/DataAnalysis/ch08/#2021-03-02-1363282","text":"","title":"2021-03-02 1.363282"},{"location":"python/DataAnalysis/ch08/#2021-04-02-0687750","text":"","title":"2021-04-02 -0.687750"},{"location":"python/DataAnalysis/ch08/#2021-05-02-0048117","text":"","title":"2021-05-02 -0.048117"},{"location":"python/DataAnalysis/ch08/#dtype-float64","text":"print(ts.shift(2, freq='90T')) # \u539f\u59cb\u6570\u636e\u7684\u201c\u5c0f\u65f6\u201c\u589e\u52a0\u4e86\u504f\u79fb\u503c","title":"dtype: float64"},{"location":"python/DataAnalysis/ch08/#2021-01-31-030000-0882972","text":"","title":"2021-01-31 03:00:00 0.882972"},{"location":"python/DataAnalysis/ch08/#2021-02-28-030000-1363282","text":"","title":"2021-02-28 03:00:00 1.363282"},{"location":"python/DataAnalysis/ch08/#2021-03-31-030000-0687750","text":"","title":"2021-03-31 03:00:00 -0.687750"},{"location":"python/DataAnalysis/ch08/#2021-04-30-030000-0048117","text":"","title":"2021-04-30 03:00:00 -0.048117"},{"location":"python/DataAnalysis/ch08/#dtype-float64_1","text":"#### \u4f7f\u7528\u504f\u7f6e\u8fdb\u884c\u79fb\u4f4d\u65e5\u671f pandas\u65e5\u671f\u504f\u7f6e\u4e5f\u53ef\u4ee5\u4f7f\u7528`datetime`\u6216`Timestamp`\u5bf9\u8c61\u5b8c\u6210\uff1a now = datetime(2021, 10, 9) print(now)","title":"dtype: float64"},{"location":"python/DataAnalysis/ch08/#2021-10-09-000000","text":"print(now + 3 * Day())","title":"2021-10-09 00:00:00"},{"location":"python/DataAnalysis/ch08/#2021-10-12-000000","text":"\u951a\u5b9a\u504f\u7f6e\u53ef\u4ee5\u4f7f\u7528`rollforward`\u548c`rollback`\u5206\u522b\u663e\u5f0f\u5730\u5c06\u65e5\u671f\u5411\u524d\u6216\u5411\u540e\"\u6eda\u52a8\"\u3002 \u5982\u679c\u6dfb\u52a0\u4e86\u4e00\u4e2a\u951a\u5b9a\u504f\u7f6e\u91cf\uff0c\u6bd4\u5982`MonthEnd`\uff0c\u6839\u636e\u9891\u7387\u89c4\u5219\uff0c\u7b2c\u4e00\u4e2a\u589e\u91cf\u4f1a\u5c06\u65e5\u671f\u201c\u524d\u6eda\u201d\u5230\u4e0b\u4e00\u4e2a\u65e5\u671f\uff1a print(now + MonthEnd()) # \u201c\u524d\u6eda\u201d\u5230\u5f53\u524d\u6708\u7684\u6708\u5e95","title":"2021-10-12 00:00:00"},{"location":"python/DataAnalysis/ch08/#2021-10-31-000000","text":"print(now + MonthEnd(2)) # \u6ce8\u610f\u8fd9\u91cc\u7684\u5e8f\u5217\u53f7\uff0c\u5f53\u524d\u6708\u662f1,\u4e0b\u4e2a\u6708\u662f2","title":"2021-10-31 00:00:00"},{"location":"python/DataAnalysis/ch08/#2021-11-30-000000","text":"offset = MonthEnd() print(offset.rollback(now))","title":"2021-11-30 00:00:00"},{"location":"python/DataAnalysis/ch08/#2021-09-30-000000","text":"print(offset.rollforward(now))","title":"2021-09-30 00:00:00"},{"location":"python/DataAnalysis/ch08/#2021-10-31-000000_1","text":"\u5c06\u79fb\u4f4d\u65b9\u6cd5\u4e0e`groupby`\u4e00\u8d77\u4f7f\u7528\u662f\u65e5\u671f\u504f\u7f6e\u7684\u4e00\u79cd\u521b\u9020\u6027\u7528\u6cd5\uff1a ts = pd.Series( np.random.randn(20), index=pd.date_range('2021/1/1', periods=20, freq='4d') ) print(ts)","title":"2021-10-31 00:00:00"},{"location":"python/DataAnalysis/ch08/#2021-01-01-0674348","text":"","title":"2021-01-01 0.674348"},{"location":"python/DataAnalysis/ch08/#2021-01-05-1437803","text":"","title":"2021-01-05 -1.437803"},{"location":"python/DataAnalysis/ch08/#2021-01-09-0079218","text":"","title":"2021-01-09 -0.079218"},{"location":"python/DataAnalysis/ch08/#2021-01-13-1444890","text":"","title":"2021-01-13 -1.444890"},{"location":"python/DataAnalysis/ch08/#2021-01-17-0643279","text":"","title":"2021-01-17 0.643279"},{"location":"python/DataAnalysis/ch08/#2021-01-21-1089965","text":"","title":"2021-01-21 1.089965"},{"location":"python/DataAnalysis/ch08/#2021-01-25-0021876","text":"","title":"2021-01-25 0.021876"},{"location":"python/DataAnalysis/ch08/#2021-01-29-0692138","text":"","title":"2021-01-29 0.692138"},{"location":"python/DataAnalysis/ch08/#2021-02-02-0833496","text":"","title":"2021-02-02 0.833496"},{"location":"python/DataAnalysis/ch08/#2021-02-06-1082616","text":"","title":"2021-02-06 1.082616"},{"location":"python/DataAnalysis/ch08/#2021-02-10-0729415","text":"","title":"2021-02-10 -0.729415"},{"location":"python/DataAnalysis/ch08/#2021-02-14-0271186","text":"","title":"2021-02-14 0.271186"},{"location":"python/DataAnalysis/ch08/#2021-02-18-1416218","text":"","title":"2021-02-18 -1.416218"},{"location":"python/DataAnalysis/ch08/#2021-02-22-0780402","text":"","title":"2021-02-22 -0.780402"},{"location":"python/DataAnalysis/ch08/#2021-02-26-0113773","text":"","title":"2021-02-26 -0.113773"},{"location":"python/DataAnalysis/ch08/#2021-03-02-2095338","text":"","title":"2021-03-02 2.095338"},{"location":"python/DataAnalysis/ch08/#2021-03-06-0302612","text":"","title":"2021-03-06 -0.302612"},{"location":"python/DataAnalysis/ch08/#2021-03-10-1113632","text":"","title":"2021-03-10 1.113632"},{"location":"python/DataAnalysis/ch08/#2021-03-14-1314581","text":"","title":"2021-03-14 -1.314581"},{"location":"python/DataAnalysis/ch08/#2021-03-18-0947746","text":"","title":"2021-03-18 0.947746"},{"location":"python/DataAnalysis/ch08/#freq-4d-dtype-float64","text":"print(ts.groupby(offset.rollforward).mean()) # \u524d\u6eda\u81f3\u5f53\u6708\u6708\u5e95\uff0c\u8ba1\u7b97\u5f53\u6708\u5e73\u5747\u503c","title":"Freq: 4D, dtype: float64"},{"location":"python/DataAnalysis/ch08/#2021-01-31-0019962","text":"","title":"2021-01-31 0.019962"},{"location":"python/DataAnalysis/ch08/#2021-02-28-0121787","text":"","title":"2021-02-28 -0.121787"},{"location":"python/DataAnalysis/ch08/#2021-03-31-0507905","text":"","title":"2021-03-31 0.507905"},{"location":"python/DataAnalysis/ch08/#dtype-float64_2","text":"","title":"dtype: float64"},{"location":"python/DataAnalysis/ch08/#resample","text":"print(ts.resample('M').mean())","title":"\u4f7f\u7528resample\u662f\u66f4\u7b80\u5355\u66f4\u5feb\u6377\u7684\u65b9\u6cd5"},{"location":"python/DataAnalysis/ch08/#2021-01-31-0019962_1","text":"","title":"2021-01-31 0.019962"},{"location":"python/DataAnalysis/ch08/#2021-02-28-0121787_1","text":"","title":"2021-02-28 -0.121787"},{"location":"python/DataAnalysis/ch08/#2021-03-31-0507905_1","text":"","title":"2021-03-31 0.507905"},{"location":"python/DataAnalysis/ch08/#freq-m-dtype-float64_6","text":"## \u65f6\u533a\u5904\u7406 \u65f6\u533a\u901a\u5e38\u88ab\u8868\u793a\u4e3aUTC\u7684\u504f\u7f6e\u3002 \u5728Python\u8bed\u8a00\u4e2d\uff0c\u65f6\u533a\u4fe1\u606f\u6765\u6e90\u4e8e\u7b2c\u4e09\u65b9\u5e93pytz\uff08\u53ef\u4ee5\u4f7f\u7528pip\u6216conda\u5b89\u88c5\uff09\uff0c\u5176\u4e2d\u516c\u5f00\u4e86Olson\u6570\u636e\u5e93\uff0c\u8fd9\u662f\u4e16\u754c\u65f6\u533a\u4fe1\u606f\u7684\u6c47\u7f16\u3002 pandas\u5c01\u88c5\u4e86pytz\u7684\u529f\u80fd\u3002 from datetime import datetime, timedelta import pandas as pd import numpy as np from pandas.tseries.offsets import Hour, Minute, Day, MonthEnd import pytz #### common_timezones tz = pytz.common_timezones[-5:] # \u8bfb\u53d6common_timezones\u8fd9\u4e2a\u5217\u8868\u7684\u6700\u540e5\u4e2a\u5143\u7d20 print(tz)","title":"Freq: M, dtype: float64"},{"location":"python/DataAnalysis/ch08/#useastern-ushawaii-usmountain-uspacific-utc","text":"\u8981\u83b7\u5f97pytz\u7684\u65f6\u533a\u5bf9\u8c61\uff0c\u53ef\u4f7f\u7528pytz.timezone\uff1a tz = pytz.timezone('Asia/Shanghai') print(tz) #### \u65f6\u533a\u7684\u672c\u5730\u5316\u548c\u8f6c\u6362 \u9ed8\u8ba4\u60c5\u51b5\u4e0b\uff0cpandas\u4e2d\u7684\u65f6\u95f4\u5e8f\u5217\u662f\u65f6\u533a\u7b80\u5355\u578b\u7684\u3002 rng = pd.date_range('2021/1/1 9:30', periods=6, freq='D') ts = pd.Series(np.random.randn(len(rng)), index=rng) print(rng)","title":"['US/Eastern', 'US/Hawaii', 'US/Mountain', 'US/Pacific', 'UTC']"},{"location":"python/DataAnalysis/ch08/#datetimeindex2021-01-01-093000-2021-01-02-093000","text":"","title":"DatetimeIndex(['2021-01-01 09:30:00', '2021-01-02 09:30:00',"},{"location":"python/DataAnalysis/ch08/#2021-01-03-093000-2021-01-04-093000","text":"","title":"'2021-01-03 09:30:00', '2021-01-04 09:30:00',"},{"location":"python/DataAnalysis/ch08/#2021-01-05-093000-2021-01-06-093000","text":"","title":"'2021-01-05 09:30:00', '2021-01-06 09:30:00'],"},{"location":"python/DataAnalysis/ch08/#dtypedatetime64ns-freqd","text":"print(ts)","title":"dtype='datetime64[ns]', freq='D')"},{"location":"python/DataAnalysis/ch08/#2021-01-01-093000-0339822","text":"","title":"2021-01-01 09:30:00 0.339822"},{"location":"python/DataAnalysis/ch08/#2021-01-02-093000-1356382","text":"","title":"2021-01-02 09:30:00 1.356382"},{"location":"python/DataAnalysis/ch08/#2021-01-03-093000-0475429","text":"","title":"2021-01-03 09:30:00 0.475429"},{"location":"python/DataAnalysis/ch08/#2021-01-04-093000-1826654","text":"","title":"2021-01-04 09:30:00 1.826654"},{"location":"python/DataAnalysis/ch08/#2021-01-05-093000-0245510","text":"","title":"2021-01-05 09:30:00 -0.245510"},{"location":"python/DataAnalysis/ch08/#2021-01-06-093000-0705274","text":"","title":"2021-01-06 09:30:00 0.705274"},{"location":"python/DataAnalysis/ch08/#freq-d-dtype-float64","text":"print(ts.index.tz) # \u7d22\u5f15\u7684tz\u5c5e\u6027\u662fNone","title":"Freq: D, dtype: float64"},{"location":"python/DataAnalysis/ch08/#none","text":"\u65e5\u671f\u8303\u56f4\u53ef\u4ee5\u901a\u8fc7\u65f6\u533a\u96c6\u5408\u6765\u751f\u6210\uff1a rng = pd.date_range('2021/3/1', periods=10, freq='D', tz='UTC') print(rng)","title":"None"},{"location":"python/DataAnalysis/ch08/#datetimeindex2021-03-01-0000000000-2021-03-02-0000000000","text":"","title":"DatetimeIndex(['2021-03-01 00:00:00+00:00', '2021-03-02 00:00:00+00:00',"},{"location":"python/DataAnalysis/ch08/#2021-03-03-0000000000-2021-03-04-0000000000","text":"","title":"'2021-03-03 00:00:00+00:00', '2021-03-04 00:00:00+00:00',"},{"location":"python/DataAnalysis/ch08/#2021-03-05-0000000000-2021-03-06-0000000000","text":"","title":"'2021-03-05 00:00:00+00:00', '2021-03-06 00:00:00+00:00',"},{"location":"python/DataAnalysis/ch08/#2021-03-07-0000000000-2021-03-08-0000000000","text":"","title":"'2021-03-07 00:00:00+00:00', '2021-03-08 00:00:00+00:00',"},{"location":"python/DataAnalysis/ch08/#2021-03-09-0000000000-2021-03-10-0000000000","text":"","title":"'2021-03-09 00:00:00+00:00', '2021-03-10 00:00:00+00:00'],"},{"location":"python/DataAnalysis/ch08/#dtypedatetime64ns-utc-freqd","text":"\u4f7f\u7528`tz_localize`\u65b9\u6cd5\u53ef\u4ee5\u4ece\u7b80\u5355\u65f6\u533a\u8f6c\u6362\u5230\u672c\u5730\u5316\u65f6\u533a\uff1a print(ts)","title":"dtype='datetime64[ns, UTC]', freq='D')"},{"location":"python/DataAnalysis/ch08/#2021-01-01-093000-0294647","text":"","title":"2021-01-01 09:30:00 0.294647"},{"location":"python/DataAnalysis/ch08/#2021-01-02-093000-0958414","text":"","title":"2021-01-02 09:30:00 0.958414"},{"location":"python/DataAnalysis/ch08/#2021-01-03-093000-0424235","text":"","title":"2021-01-03 09:30:00 0.424235"},{"location":"python/DataAnalysis/ch08/#2021-01-04-093000-1714333","text":"","title":"2021-01-04 09:30:00 -1.714333"},{"location":"python/DataAnalysis/ch08/#2021-01-05-093000-0030319","text":"","title":"2021-01-05 09:30:00 -0.030319"},{"location":"python/DataAnalysis/ch08/#2021-01-06-093000-0744940","text":"","title":"2021-01-06 09:30:00 -0.744940"},{"location":"python/DataAnalysis/ch08/#freq-d-dtype-float64_1","text":"print(ts.tz_localize('UTC'))","title":"Freq: D, dtype: float64"},{"location":"python/DataAnalysis/ch08/#2021-01-01-0930000000-0294647","text":"","title":"2021-01-01 09:30:00+00:00 0.294647"},{"location":"python/DataAnalysis/ch08/#2021-01-02-0930000000-0958414","text":"","title":"2021-01-02 09:30:00+00:00 0.958414"},{"location":"python/DataAnalysis/ch08/#2021-01-03-0930000000-0424235","text":"","title":"2021-01-03 09:30:00+00:00 0.424235"},{"location":"python/DataAnalysis/ch08/#2021-01-04-0930000000-1714333","text":"","title":"2021-01-04 09:30:00+00:00 -1.714333"},{"location":"python/DataAnalysis/ch08/#2021-01-05-0930000000-0030319","text":"","title":"2021-01-05 09:30:00+00:00 -0.030319"},{"location":"python/DataAnalysis/ch08/#2021-01-06-0930000000-0744940","text":"","title":"2021-01-06 09:30:00+00:00 -0.744940"},{"location":"python/DataAnalysis/ch08/#freq-d-dtype-float64_2","text":"print(ts.tz_localize('Asia/Shanghai'))","title":"Freq: D, dtype: float64"},{"location":"python/DataAnalysis/ch08/#2021-01-01-0930000800-0052521","text":"","title":"2021-01-01 09:30:00+08:00 0.052521"},{"location":"python/DataAnalysis/ch08/#2021-01-02-0930000800-0305417","text":"","title":"2021-01-02 09:30:00+08:00 -0.305417"},{"location":"python/DataAnalysis/ch08/#2021-01-03-0930000800-0150215","text":"","title":"2021-01-03 09:30:00+08:00 0.150215"},{"location":"python/DataAnalysis/ch08/#2021-01-04-0930000800-0953715","text":"","title":"2021-01-04 09:30:00+08:00 -0.953715"},{"location":"python/DataAnalysis/ch08/#2021-01-05-0930000800-0543622","text":"","title":"2021-01-05 09:30:00+08:00 0.543622"},{"location":"python/DataAnalysis/ch08/#2021-01-06-0930000800-0222422","text":"","title":"2021-01-06 09:30:00+08:00 0.222422"},{"location":"python/DataAnalysis/ch08/#dtype-float64_3","text":"print(ts.tz_localize('Asia/Shanghai').index)","title":"dtype: float64"},{"location":"python/DataAnalysis/ch08/#datetimeindex2021-01-01-0930000800-2021-01-02-0930000800","text":"","title":"DatetimeIndex(['2021-01-01 09:30:00+08:00', '2021-01-02 09:30:00+08:00',"},{"location":"python/DataAnalysis/ch08/#2021-01-03-0930000800-2021-01-04-0930000800","text":"","title":"'2021-01-03 09:30:00+08:00', '2021-01-04 09:30:00+08:00',"},{"location":"python/DataAnalysis/ch08/#2021-01-05-0930000800-2021-01-06-0930000800","text":"","title":"'2021-01-05 09:30:00+08:00', '2021-01-06 09:30:00+08:00'],"},{"location":"python/DataAnalysis/ch08/#dtypedatetime64ns-asiashanghai-freqnone","text":"\u4e00\u65e6\u65f6\u95f4\u5e8f\u5217\u88ab\u672c\u5730\u5316\u4e3a\u67d0\u4e2a\u7279\u5b9a\u7684\u65f6\u533a\uff0c\u5219\u53ef\u4ee5\u901a\u8fc7`tz_convert`\u5c06\u5176\u8f6c\u6362\u4e3a\u53e6\u4e00\u4e2a\u65f6\u533a\uff1a tz_sha = ts.tz_localize('Asia/Shanghai') tz_utc = tz_sha.tz_convert('UTC') print(tz_sha)","title":"dtype='datetime64[ns, Asia/Shanghai]', freq=None)"},{"location":"python/DataAnalysis/ch08/#2021-01-01-0930000800-0095689","text":"","title":"2021-01-01 09:30:00+08:00 0.095689"},{"location":"python/DataAnalysis/ch08/#2021-01-02-0930000800-0392730","text":"","title":"2021-01-02 09:30:00+08:00 -0.392730"},{"location":"python/DataAnalysis/ch08/#2021-01-03-0930000800-0151468","text":"","title":"2021-01-03 09:30:00+08:00 0.151468"},{"location":"python/DataAnalysis/ch08/#2021-01-04-0930000800-0027467","text":"","title":"2021-01-04 09:30:00+08:00 0.027467"},{"location":"python/DataAnalysis/ch08/#2021-01-05-0930000800-0393709","text":"","title":"2021-01-05 09:30:00+08:00 0.393709"},{"location":"python/DataAnalysis/ch08/#2021-01-06-0930000800-0872914","text":"","title":"2021-01-06 09:30:00+08:00 0.872914"},{"location":"python/DataAnalysis/ch08/#dtype-float64_4","text":"print(tz_utc)","title":"dtype: float64"},{"location":"python/DataAnalysis/ch08/#2021-01-01-0130000000-0095689","text":"","title":"2021-01-01 01:30:00+00:00 0.095689"},{"location":"python/DataAnalysis/ch08/#2021-01-02-0130000000-0392730","text":"","title":"2021-01-02 01:30:00+00:00 -0.392730"},{"location":"python/DataAnalysis/ch08/#2021-01-03-0130000000-0151468","text":"","title":"2021-01-03 01:30:00+00:00 0.151468"},{"location":"python/DataAnalysis/ch08/#2021-01-04-0130000000-0027467","text":"","title":"2021-01-04 01:30:00+00:00 0.027467"},{"location":"python/DataAnalysis/ch08/#2021-01-05-0130000000-0393709","text":"","title":"2021-01-05 01:30:00+00:00 0.393709"},{"location":"python/DataAnalysis/ch08/#2021-01-06-0130000000-0872914","text":"","title":"2021-01-06 01:30:00+00:00 0.872914"},{"location":"python/DataAnalysis/ch08/#dtype-float64_5","text":"","title":"dtype: float64"},{"location":"python/DataAnalysis/ch08/#tz_localizetz_convertdatetimeindex","text":"print(ts.index.tz_localize('Asia/Shanghai'))","title":"tz_localize\u548ctz_convert\u4e5f\u662fDatetimeIndex\u7684\u5b9e\u4f8b\u65b9\u6cd5\uff1a"},{"location":"python/DataAnalysis/ch08/#datetimeindex2021-01-01-0930000800-2021-01-02-0930000800_1","text":"","title":"DatetimeIndex(['2021-01-01 09:30:00+08:00', '2021-01-02 09:30:00+08:00',"},{"location":"python/DataAnalysis/ch08/#2021-01-03-0930000800-2021-01-04-0930000800_1","text":"","title":"'2021-01-03 09:30:00+08:00', '2021-01-04 09:30:00+08:00',"},{"location":"python/DataAnalysis/ch08/#2021-01-05-0930000800-2021-01-06-0930000800_1","text":"","title":"'2021-01-05 09:30:00+08:00', '2021-01-06 09:30:00+08:00'],"},{"location":"python/DataAnalysis/ch08/#dtypedatetime64ns-asiashanghai-freqnone_1","text":"### \u65f6\u533a\u611f\u77e5\u65f6\u95f4\u6233\u5bf9\u8c61\u7684\u64cd\u4f5c \u4e0e\u65f6\u95f4\u5e8f\u5217\u548c\u65e5\u671f\u8303\u56f4\u7c7b\u4f3c\uff0c\u5355\u72ec\u7684`Timestamp`\u5bf9\u8c61\u4e5f\u53ef\u4ee5\u4ece\u7b80\u5355\u65f6\u95f4\u6233\u672c\u5730\u5316\u4e3a\u65f6\u533a\u611f\u77e5\u65f6\u95f4\u6233\uff0c\u5e76\u4ece\u4e00\u4e2a\u65f6\u533a\u8f6c\u6362\u4e3a\u53e6\u4e00\u4e2a\u65f6\u533a\uff1a stamp = pd.Timestamp('2021-5-1 05:30') print(stamp)","title":"dtype='datetime64[ns, Asia/Shanghai]', freq=None)"},{"location":"python/DataAnalysis/ch08/#2021-05-01-053000","text":"stamp_utc = stamp.tz_localize('utc') print(stamp_utc)","title":"2021-05-01 05:30:00"},{"location":"python/DataAnalysis/ch08/#2021-05-01-0530000000","text":"stamp_sha = stamp_utc.tz_convert('Asia/Shanghai') print(stamp_sha)","title":"2021-05-01 05:30:00+00:00"},{"location":"python/DataAnalysis/ch08/#2021-05-01-1330000800","text":"\u4e5f\u53ef\u4ee5\u5728\u521b\u5efa`Timestamp`\u7684\u65f6\u5019\u4f20\u9012\u4e00\u4e2a\u65f6\u533a\uff1a stamp_sha = pd.Timestamp('2021-5-1 05:30', tz='Asia/Shanghai') print(stamp_sha)","title":"2021-05-01 13:30:00+08:00"},{"location":"python/DataAnalysis/ch08/#2021-05-01-0530000800","text":"`Timestamp`\u5bf9\u8c61\u5185\u90e8\u5b58\u50a8\u4e86\u4e00\u4e2aUnix\u7eaa\u5143(1970\u5e741\u67081\u65e5)\u81f3\u4eca\u7684\u7eb3\u79d2\u6570\u91cfUTC\u65f6\u95f4\u6233\u6570\u503c\uff0c\u8be5\u6570\u503c\u5728\u65f6\u533a\u8f6c\u6362\u4e2d\u662f\u4e0d\u53d8\u7684\uff1a print(stamp_utc.value)","title":"2021-05-01 05:30:00+08:00"},{"location":"python/DataAnalysis/ch08/#1619847000000000000","text":"print(stamp_utc.tz_convert('Asia/Shanghai').value)","title":"1619847000000000000"},{"location":"python/DataAnalysis/ch08/#1619847000000000000_1","text":"\u5728\u4f7f\u7528pandas\u7684`DateOffset`\u8fdb\u884c\u65f6\u95f4\u7b97\u672f\u65f6\uff0cpandas\u5c3d\u53ef\u80fd\u9075\u4ece\u590f\u65f6\u5236\u3002 \u9996\u5148\uff0c\u6784\u9020\u8f6c\u6362\u5230DST\u4e4b\u524d\u768430\u5206\u949f\u7684\u65f6\u95f4\uff1a stamp = pd.Timestamp('2012-3-12 1:30', tz='US/Eastern') print(stamp)","title":"1619847000000000000"},{"location":"python/DataAnalysis/ch08/#2012-03-12-013000-0400","text":"print(stamp + Hour())","title":"2012-03-12 01:30:00-04:00"},{"location":"python/DataAnalysis/ch08/#2012-03-12-023000-0400","text":"\u4e4b\u540e\uff0c\u6784\u5efa\u4eceDST\u8fdb\u884c\u8f6c\u6362\u524d\u768490\u5206\u949f\uff1a stamp = pd.Timestamp('2012-11-04 0:30-04:00', tz='US/Eastern') print(stamp)","title":"2012-03-12 02:30:00-04:00"},{"location":"python/DataAnalysis/ch08/#2012-11-04-003000-0400","text":"print(stamp + 2 * Hour()) # \u53ea\u589e\u52a0\u4e86\u4e00\u5c0f\u65f6","title":"2012-11-04 00:30:00-04:00"},{"location":"python/DataAnalysis/ch08/#2012-11-04-013000-0500","text":"### \u4e0d\u540c\u65f6\u533a\u95f4\u7684\u64cd\u4f5c \u5982\u679c\u4e24\u4e2a\u65f6\u533a\u4e0d\u540c\u7684\u65f6\u95f4\u5e8f\u5217\u9700\u8981\u8054\u5408\uff0c\u90a3\u4e48\u7ed3\u679c\u5c06\u662fUTC\u65f6\u95f4\u7684\uff0c\u56e0\u4e3a\u65f6\u95f4\u6233\u4ee5UTC\u683c\u5f0f\u5b58\u50a8\u3002 rng = pd.date_range('2021/1/1 9:30', periods=9, freq='B') ts = pd.Series(np.random.randn(len(rng)), index=rng) print(ts)","title":"2012-11-04 01:30:00-05:00"},{"location":"python/DataAnalysis/ch08/#2021-01-01-093000-0715681","text":"","title":"2021-01-01 09:30:00 0.715681"},{"location":"python/DataAnalysis/ch08/#2021-01-04-093000-0524563","text":"","title":"2021-01-04 09:30:00 0.524563"},{"location":"python/DataAnalysis/ch08/#2021-01-05-093000-0482199","text":"","title":"2021-01-05 09:30:00 -0.482199"},{"location":"python/DataAnalysis/ch08/#2021-01-06-093000-0661303","text":"","title":"2021-01-06 09:30:00 -0.661303"},{"location":"python/DataAnalysis/ch08/#2021-01-07-093000-1750010","text":"","title":"2021-01-07 09:30:00 1.750010"},{"location":"python/DataAnalysis/ch08/#2021-01-08-093000-0251478","text":"","title":"2021-01-08 09:30:00 0.251478"},{"location":"python/DataAnalysis/ch08/#2021-01-11-093000-1487268","text":"","title":"2021-01-11 09:30:00 -1.487268"},{"location":"python/DataAnalysis/ch08/#2021-01-12-093000-0224024","text":"","title":"2021-01-12 09:30:00 -0.224024"},{"location":"python/DataAnalysis/ch08/#2021-01-13-093000-1621853","text":"","title":"2021-01-13 09:30:00 -1.621853"},{"location":"python/DataAnalysis/ch08/#freq-b-dtype-float64","text":"ts1 = ts[:7].tz_localize('Europe/London') ts2 = ts1[2:].tz_convert('Europe/Moscow') result = ts1 + ts2 print(ts1)","title":"Freq: B, dtype: float64"},{"location":"python/DataAnalysis/ch08/#2021-01-01-0930000000-1393445","text":"","title":"2021-01-01 09:30:00+00:00 -1.393445"},{"location":"python/DataAnalysis/ch08/#2021-01-04-0930000000-1179614","text":"","title":"2021-01-04 09:30:00+00:00 -1.179614"},{"location":"python/DataAnalysis/ch08/#2021-01-05-0930000000-0716669","text":"","title":"2021-01-05 09:30:00+00:00 0.716669"},{"location":"python/DataAnalysis/ch08/#2021-01-06-0930000000-0485656","text":"","title":"2021-01-06 09:30:00+00:00 -0.485656"},{"location":"python/DataAnalysis/ch08/#2021-01-07-0930000000-0433000","text":"","title":"2021-01-07 09:30:00+00:00 0.433000"},{"location":"python/DataAnalysis/ch08/#2021-01-08-0930000000-1540745","text":"","title":"2021-01-08 09:30:00+00:00 1.540745"},{"location":"python/DataAnalysis/ch08/#2021-01-11-0930000000-0343751","text":"","title":"2021-01-11 09:30:00+00:00 0.343751"},{"location":"python/DataAnalysis/ch08/#dtype-float64_6","text":"print(ts2)","title":"dtype: float64"},{"location":"python/DataAnalysis/ch08/#2021-01-05-1230000300-0716669","text":"","title":"2021-01-05 12:30:00+03:00 0.716669"},{"location":"python/DataAnalysis/ch08/#2021-01-06-1230000300-0485656","text":"","title":"2021-01-06 12:30:00+03:00 -0.485656"},{"location":"python/DataAnalysis/ch08/#2021-01-07-1230000300-0433000","text":"","title":"2021-01-07 12:30:00+03:00 0.433000"},{"location":"python/DataAnalysis/ch08/#2021-01-08-1230000300-1540745","text":"","title":"2021-01-08 12:30:00+03:00 1.540745"},{"location":"python/DataAnalysis/ch08/#2021-01-11-1230000300-0343751","text":"","title":"2021-01-11 12:30:00+03:00 0.343751"},{"location":"python/DataAnalysis/ch08/#dtype-float64_7","text":"print(result)","title":"dtype: float64"},{"location":"python/DataAnalysis/ch08/#2021-01-01-0930000000-nan","text":"","title":"2021-01-01 09:30:00+00:00 NaN"},{"location":"python/DataAnalysis/ch08/#2021-01-04-0930000000-nan","text":"","title":"2021-01-04 09:30:00+00:00 NaN"},{"location":"python/DataAnalysis/ch08/#2021-01-05-0930000000-1433337","text":"","title":"2021-01-05 09:30:00+00:00 1.433337"},{"location":"python/DataAnalysis/ch08/#2021-01-06-0930000000-0971312","text":"","title":"2021-01-06 09:30:00+00:00 -0.971312"},{"location":"python/DataAnalysis/ch08/#2021-01-07-0930000000-0866000","text":"","title":"2021-01-07 09:30:00+00:00 0.866000"},{"location":"python/DataAnalysis/ch08/#2021-01-08-0930000000-3081489","text":"","title":"2021-01-08 09:30:00+00:00 3.081489"},{"location":"python/DataAnalysis/ch08/#2021-01-11-0930000000-0687502","text":"","title":"2021-01-11 09:30:00+00:00 0.687502"},{"location":"python/DataAnalysis/ch08/#dtype-float64_8","text":"## \u65f6\u95f4\u533a\u95f4\u548c\u533a\u95f4\u7b97\u672f from datetime import datetime, timedelta import pandas as pd import numpy as np from pandas.tseries.offsets import Hour, Minute, Day, MonthEnd import pytz \u65f6\u95f4\u533a\u95f4\u8868\u793a\u7684\u662f\u65f6\u95f4\u8303\u56f4\u901a\u8fc7\u539f\u7d22\u5f151~202\uff0c\u628a`year`\u548c`quarter`\u8054\u5408\u8d77\u6765\uff0c\u751f\u6210\u65b0\u7d22\u5f15\uff0c\u5e76\u66ff\u6362\u539f\u7d22\u5f15\uff0c\u6bd4\u5982\u4e00\u4e9b\u5929\u3001\u4e00\u4e9b\u6708\u3001\u4e00\u4e9b\u5b63\u5ea6\u6216\u8005\u662f\u4e00\u4e9b\u5e74\u3002 `Period`\u7c7b\u8868\u793a\u7684\u6b63\u662f\u8fd9\u79cd\u6570\u636e\u7c7b\u578b\uff0c\u9700\u8981\u4e00\u4e2a\u5b57\u7b26\u4e32\u6216\u6570\u5b57\u4ee5\u53ca\u9891\u7387\u3002 \u5728\u8fd9\u4e2a\u4f8b\u5b50\u4e2d\uff0c`Period`\u5bf9\u8c61\u8868\u793a\u7684\u662f\u4ece2007\u5e741\u67081\u65e5\u52302007\u5e7412\u670831\u65e5\uff08\u5305\u542b\u5728\u5185\uff09\u7684\u65f6\u95f4\u6bb5\u3002 \u5728\u65f6\u95f4\u6bb5\u4e0a\u589e\u52a0\u6216\u51cf\u53bb\u6574\u6570\u53ef\u4ee5\u65b9\u4fbf\u5730\u6839\u636e\u5b83\u4eec\u7684\u9891\u7387\u8fdb\u884c\u79fb\u4f4d\u3002 p = pd.Period(2020, freq='A-DEC') print(p)","title":"dtype: float64"},{"location":"python/DataAnalysis/ch08/#2020","text":"print(p + 5)","title":"2020"},{"location":"python/DataAnalysis/ch08/#2025","text":"print(p - 5)","title":"2025"},{"location":"python/DataAnalysis/ch08/#2015","text":"\u5982\u679c\u4e24\u4e2a\u533a\u95f4\u62e5\u6709\u76f8\u540c\u7684\u9891\u7387\uff0c\u5219\u5b83\u4eec\u7684\u5dee\u662f\u5b83\u4eec\u4e4b\u95f4\u7684\u5355\u4f4d\u6570\u3002 p1 = pd.Period(2020, freq='A-DEC') p2 = pd.Period(2010, freq='A-DEC') print(p1 - p2)","title":"2015"},{"location":"python/DataAnalysis/ch08/#10-yearends-month12","text":"p1 = pd.Period(2020, freq='Q-DEC') p2 = pd.Period(2010, freq='Q-DEC') print(p1 - p2)","title":"<10 * YearEnds: month=12>"},{"location":"python/DataAnalysis/ch08/#40-quarterends-startingmonth12","text":"\u4f7f\u7528`period_range`\u51fd\u6570\u53ef\u4ee5\u6784\u9020\u89c4\u5219\u533a\u95f4\u5e8f\u5217\u3002`PeriodIndex`\u7c7b\u5b58\u50a8\u7684\u662f\u533a\u95f4\u7684\u5e8f\u5217\uff0c\u53ef\u4ee5\u4f5c\u4e3a\u4efb\u610fpandas\u6570\u636e\u7ed3\u6784\u7684\u8f74\u7d22\u5f15\u3002 data = np.random.randn(6) strings = ['2021Q1', '2021Q2', '2021Q3', '2021Q4', '2022Q1', '2022Q2'] rng = pd.period_range('2001-1-1', '2001-6-30', freq='M') ts = pd.Series(data, index=rng) print(ts)","title":"<40 * QuarterEnds: startingMonth=12>"},{"location":"python/DataAnalysis/ch08/#2001-01-0481408","text":"","title":"2001-01 -0.481408"},{"location":"python/DataAnalysis/ch08/#2001-02-0297590","text":"","title":"2001-02 -0.297590"},{"location":"python/DataAnalysis/ch08/#2001-03-0860354","text":"","title":"2001-03 -0.860354"},{"location":"python/DataAnalysis/ch08/#2001-04-1281540","text":"","title":"2001-04 1.281540"},{"location":"python/DataAnalysis/ch08/#2001-05-1036551","text":"","title":"2001-05 1.036551"},{"location":"python/DataAnalysis/ch08/#2001-06-0522592","text":"","title":"2001-06 -0.522592"},{"location":"python/DataAnalysis/ch08/#freq-m-dtype-float64_7","text":"rng = pd.PeriodIndex(strings, freq='Q-DEC') # \u5b57\u7b26\u4e32\u6570\u7ec4\u4e5f\u53ef\u4ee5\u4f7f\u7528PeriodIndex\u7c7b ts = pd.Series(data, index=rng) print(ts)","title":"Freq: M, dtype: float64"},{"location":"python/DataAnalysis/ch08/#2021q1-2077200","text":"","title":"2021Q1 -2.077200"},{"location":"python/DataAnalysis/ch08/#2021q2-0948796","text":"","title":"2021Q2 -0.948796"},{"location":"python/DataAnalysis/ch08/#2021q3-1104737","text":"","title":"2021Q3 -1.104737"},{"location":"python/DataAnalysis/ch08/#2021q4-0090281","text":"","title":"2021Q4 0.090281"},{"location":"python/DataAnalysis/ch08/#2022q1-0431517","text":"","title":"2022Q1 0.431517"},{"location":"python/DataAnalysis/ch08/#2022q2-1537045","text":"","title":"2022Q2 1.537045"},{"location":"python/DataAnalysis/ch08/#freq-q-dec-dtype-float64","text":"### \u533a\u95f4\u9891\u7387\u8f6c\u6362 \u4f7f\u7528`asfreq`\u53ef\u4ee5\u5c06\u533a\u95f4\u548c`PeriodIndex`\u5bf9\u8c61\u8f6c\u6362\u4e3a\u5176\u4ed6\u7684\u9891\u7387\u3002 \u4f8b\u5982\uff0c\u5047\u8bbe\u6211\u4eec\u6709\u4e00\u4e2a\u5e74\u5ea6\u533a\u95f4\uff0c\u5e76\u4e14\u60f3\u8981\u5728\u4e00\u5e74\u7684\u5f00\u59cb\u6216\u7ed3\u675f\u65f6\u5c06\u5176\u8f6c\u6362\u4e3a\u6708\u5ea6\u533a\u95f4\u3002 \u53ef\u4ee5\u5c06`Period('2020', 'A-DEC')`\u770b\u4f5c\u4e00\u6bb5\u65f6\u95f4\u4e2d\u7684\u4e00\u79cd\u6e38\u6807\uff0c\u5c06\u65f6\u95f4\u6309\u6708\u4efd\u5212\u5206\u3002 p = pd.Period(2020, freq='A-DEC') print(p.asfreq('M', how='start'))","title":"Freq: Q-DEC, dtype: float64"},{"location":"python/DataAnalysis/ch08/#2020-01","text":"print(p.asfreq('M', how='end'))","title":"2020-01"},{"location":"python/DataAnalysis/ch08/#2020-12","text":"\u5982\u679c\u8d22\u5e74\u7ed3\u675f\u4e0d\u572812\u6708\uff0c\u5219\u6bcf\u6708\u5206\u671f\u4f1a\u81ea\u52a8\u8c03\u6574\u3002 \u6309\u5f53\u5e74\u8d22\u5e74\u7ed3\u675f\u8ba1\u7b97\uff0c\u8d77\u59cb\u5e74\u4efd\u5c31\u662f\u4e0a\u4e00\u5e74\u4e86\u3002 p = pd.Period(2020, freq='A-JUN') print(p.asfreq('M', how='start'))","title":"2020-12"},{"location":"python/DataAnalysis/ch08/#2019-07","text":"print(p.asfreq('M', how='end'))","title":"2019-07"},{"location":"python/DataAnalysis/ch08/#2020-06","text":"\u5f53\u4ece\u9ad8\u9891\u7387\u5411\u4f4e\u9891\u7387\u8f6c\u6362\u65f6\uff0cpandas\u6839\u636e\u5b50\u533a\u95f4\u7684\"\u6240\u5c5e\"\u6765\u51b3\u5b9a\u7236\u533a\u95f4\u3002 \u4f8b\u5982\uff0c\u5728A-JUN\u9891\u7387\u4e2d\uff0cAug-2020\u662f2020\u533a\u95f4\u7684\u4e00\u90e8\u5206\uff1a print(p.asfreq('A-JUN')) 2020\u901a\u8fc7\u539f\u7d22\u5f151~202\uff0c\u628a`year`\u548c`quarter`\u8054\u5408\u8d77\u6765\uff0c\u751f\u6210\u65b0\u7d22\u5f15\uff0c\u5e76\u66ff\u6362\u539f\u7d22\u5f15\u3002 \u5b8c\u6574\u7684`PeriodIndex`\u5bf9\u8c61\u6216\u65f6\u95f4\u5e8f\u5217\u53ef\u4ee5\u6309\u7167\u76f8\u540c\u7684\u8bed\u4e49\u8fdb\u884c\u8f6c\u6362\uff1a rng = pd.period_range('2018', '2021', freq='A-DEC') data = np.random.randn(len(rng)) ts = pd.Series(data, index=rng) print(ts)","title":"2020-06"},{"location":"python/DataAnalysis/ch08/#2018-0221634","text":"","title":"2018 0.221634"},{"location":"python/DataAnalysis/ch08/#2019-0392724","text":"","title":"2019 -0.392724"},{"location":"python/DataAnalysis/ch08/#2020-0355022","text":"","title":"2020 -0.355022"},{"location":"python/DataAnalysis/ch08/#2021-0114000","text":"","title":"2021 0.114000"},{"location":"python/DataAnalysis/ch08/#freq-a-dec-dtype-float64","text":"\u4e0b\u9762\u5e74\u5ea6\u533a\u95f4\u5c06\u901a\u8fc7`asfreq`\u88ab\u66ff\u6362\u4e3a\u5bf9\u5e94\u4e8e\u6bcf\u4e2a\u5e74\u5ea6\u533a\u95f4\u5185\u7684\u7b2c\u4e00\u4e2a\u6708\u7684\u6708\u5ea6\u533a\u95f4\u3002 print(ts.asfreq('M', how='start'))","title":"Freq: A-DEC, dtype: float64"},{"location":"python/DataAnalysis/ch08/#2018-01-0681874","text":"","title":"2018-01 0.681874"},{"location":"python/DataAnalysis/ch08/#2019-01-1006585","text":"","title":"2019-01 -1.006585"},{"location":"python/DataAnalysis/ch08/#2020-01-0619142","text":"","title":"2020-01 -0.619142"},{"location":"python/DataAnalysis/ch08/#2021-01-1445820","text":"","title":"2021-01 1.445820"},{"location":"python/DataAnalysis/ch08/#freq-m-dtype-float64_8","text":"\u5982\u679c\u6211\u4eec\u60f3\u8981\u6bcf\u5e74\u6700\u540e\u4e00\u4e2a\u5de5\u4f5c\u65e5\uff0c\u6211\u4eec\u53ef\u4ee5\u4f7f\u7528`B`\u9891\u7387\u6765\u8868\u793a\u6211\u4eec\u60f3\u8981\u7684\u662f\u533a\u95f4\u7684\u672b\u7aef\u3002 print(ts.asfreq('B', how='end'))","title":"Freq: M, dtype: float64"},{"location":"python/DataAnalysis/ch08/#2018-12-31-1520316","text":"","title":"2018-12-31 -1.520316"},{"location":"python/DataAnalysis/ch08/#2019-12-31-0425544","text":"","title":"2019-12-31 -0.425544"},{"location":"python/DataAnalysis/ch08/#2020-12-31-0658073","text":"","title":"2020-12-31 -0.658073"},{"location":"python/DataAnalysis/ch08/#2021-12-31-1206881","text":"","title":"2021-12-31 1.206881"},{"location":"python/DataAnalysis/ch08/#freq-b-dtype-float64_1","text":"### \u5b63\u5ea6\u533a\u95f4\u9891\u7387 \u5b63\u5ea6\u6570\u636e\u662f\u4f1a\u8ba1\u3001\u91d1\u878d\u548c\u5176\u4ed6\u9886\u57df\u7684\u6807\u51c6\u3002 \u5f88\u591a\u5b63\u5ea6\u6570\u636e\u662f\u5728\u8d22\u5e74\u7ed3\u5c3e\u62a5\u544a\u7684\uff0c\u901a\u5e38\u662f\u4e00\u5e7412\u4e2a\u6708\u4e2d\u7684\u6700\u540e\u4e00\u4e2a\u65e5\u5386\u65e5\u6216\u5de5\u4f5c\u65e5\u3002 pandas\u652f\u6301\u6240\u6709\u7684\u53ef\u80fd\u768412\u4e2a\u5b63\u5ea6\u9891\u7387\u4eceQ-JAN\u5230Q-DEC\uff1a \u4e0b\u4f8b\u4e2d\uff0c\u8d22\u5e74\u7ed3\u675f\u4e8e1\u6708\uff0c2020Q4\u884c\u65f6\u95f4\u4e3a\u4e0a\u4e00\u5e7411\u6708\u81f3\u5f53\u5e741\u6708\u3002\u53ef\u4ee5\u901a\u8fc7\u8f6c\u6362\u4e3a\u6bcf\u65e5\u9891\u7387\uff08asfreq\uff09\u8fdb\u884c\u68c0\u67e5\u3002 p = pd.Period('2020Q4', freq='Q-JAN') print(p)","title":"Freq: B, dtype: float64"},{"location":"python/DataAnalysis/ch08/#2020q4","text":"print(p.asfreq('D', 'start'))","title":"2020Q4"},{"location":"python/DataAnalysis/ch08/#2019-11-01","text":"print(p.asfreq('D', 'end'))","title":"2019-11-01"},{"location":"python/DataAnalysis/ch08/#2020-01-31","text":"\u5047\u5982\u8d22\u5e74\u7ed3\u675f\u4e8e2\u6708\uff0c2020Q4\u884c\u65f6\u95f4\u4e3a\u4e0a\u4e00\u5e7412\u6708\u81f3\u5f53\u5e742\u6708\u3002 p = pd.Period('2020Q4', freq='Q-FEB') print(p)","title":"2020-01-31"},{"location":"python/DataAnalysis/ch08/#2020q4_1","text":"print(p.asfreq('D', 'start'))","title":"2020Q4"},{"location":"python/DataAnalysis/ch08/#2019-11-01_1","text":"print(p.asfreq('D', 'end'))","title":"2019-11-01"},{"location":"python/DataAnalysis/ch08/#2020-01-31_1","text":"\u5047\u5982\u8d22\u5e74\u7ed3\u675f\u4e8e4\u6708\uff0c2020Q4\u884c\u65f6\u95f4\u4e3a\u4e0a\u4e00\u5e7412\u6708\u81f3\u5f53\u5e742\u6708\u3002 p = pd.Period('2020Q4', freq='Q-APR') print(p)","title":"2020-01-31"},{"location":"python/DataAnalysis/ch08/#2020q4_2","text":"print(p.asfreq('D', 'start'))","title":"2020Q4"},{"location":"python/DataAnalysis/ch08/#2020-02-01","text":"print(p.asfreq('D', 'end'))","title":"2020-02-01"},{"location":"python/DataAnalysis/ch08/#2020-04-30","text":"\u53ef\u4ee5\u5bf9\u533a\u95f4\u6570\u636e\u505a\u7b97\u672f\u64cd\u4f5c\u3002\u4f8b\u5982\uff0c\u8981\u83b7\u53d6\u5728\u5b63\u5ea6\u5012\u6570\u7b2c\u4e8c\u4e2a\u5de5\u4f5c\u65e5\u4e0b\u53484\u70b9\u7684\u65f6\u95f4\u6233\uff0c\u53ef\u4ee5\u8fd9\u4e48\u505a\uff1a(\u7591\u95ee\uff1a\u8fd9\u91cc\u7684\u53c2\u6570e\u4ee3\u8868\u4ec0\u4e48 ???) p4pm = (p.asfreq('B', 'e') - 1).asfreq('T', 's') + 16 * 60 print(p4pm)","title":"2020-04-30"},{"location":"python/DataAnalysis/ch08/#2020-04-29-1600","text":"print(p4pm.to_timestamp())","title":"2020-04-29 16:00"},{"location":"python/DataAnalysis/ch08/#2020-04-29-160000","text":"\u53ef\u4ee5\u4f7f\u7528`peroid_range`\u751f\u6210\u5b63\u5ea6\u5e8f\u5217\u3002\u5b83\u7684\u7b97\u672f\u4e5f\u662f\u4e00\u6837\u7684\uff1a rng = pd.period_range('2000Q3', '2001Q4', freq='Q-JAN') ts = pd.Series(np.arange(len(rng)), index=rng) print(ts)","title":"2020-04-29 16:00:00"},{"location":"python/DataAnalysis/ch08/#2000q3-0","text":"","title":"2000Q3 0"},{"location":"python/DataAnalysis/ch08/#2000q4-1","text":"","title":"2000Q4 1"},{"location":"python/DataAnalysis/ch08/#2001q1-2","text":"","title":"2001Q1 2"},{"location":"python/DataAnalysis/ch08/#2001q2-3","text":"","title":"2001Q2 3"},{"location":"python/DataAnalysis/ch08/#2001q3-4","text":"","title":"2001Q3 4"},{"location":"python/DataAnalysis/ch08/#2001q4-5","text":"","title":"2001Q4 5"},{"location":"python/DataAnalysis/ch08/#freq-q-jan-dtype-int64","text":"new_rng = (rng.asfreq('B', 'e') - 1).asfreq('T', 's') + 16 * 60 ts.index = new_rng.to_timestamp() print(ts)","title":"Freq: Q-JAN, dtype: int64"},{"location":"python/DataAnalysis/ch08/#1999-10-28-160000-0","text":"","title":"1999-10-28 16:00:00 0"},{"location":"python/DataAnalysis/ch08/#2000-01-28-160000-1","text":"","title":"2000-01-28 16:00:00 1"},{"location":"python/DataAnalysis/ch08/#2000-04-27-160000-2","text":"","title":"2000-04-27 16:00:00 2"},{"location":"python/DataAnalysis/ch08/#2000-07-28-160000-3","text":"","title":"2000-07-28 16:00:00 3"},{"location":"python/DataAnalysis/ch08/#2000-10-30-160000-4","text":"","title":"2000-10-30 16:00:00 4"},{"location":"python/DataAnalysis/ch08/#2001-01-30-160000-5","text":"","title":"2001-01-30 16:00:00 5"},{"location":"python/DataAnalysis/ch08/#dtype-int64","text":"### \u5c06\u65f6\u95f4\u6233\u8f6c\u6362\u4e3a\u533a\u95f4\uff08\u4ee5\u53ca\u9006\u8f6c\u6362\uff09 \u901a\u8fc7\u65f6\u95f4\u6233\u7d22\u5f15\u7684Series\u548cDataFrame\u53ef\u4ee5\u88ab`to_period`\u65b9\u6cd5\u8f6c\u6362\u4e3a\u533a\u95f4\uff1a rng = pd.date_range('2020-01-01', periods=3, freq='M') ts = pd.Series(np.random.randn(3), index=rng) print(ts)","title":"dtype: int64"},{"location":"python/DataAnalysis/ch08/#2020-01-31-0567097","text":"","title":"2020-01-31 -0.567097"},{"location":"python/DataAnalysis/ch08/#2020-02-29-0634521202yearquarter2","text":"","title":"2020-02-29 0.63452\u901a\u8fc7\u539f\u7d22\u5f151~202\uff0c\u628ayear\u548cquarter\u8054\u5408\u8d77\u6765\uff0c\u751f\u6210\u65b0\u7d22\u5f15\uff0c\u5e76\u66ff\u6362\u539f\u7d22\u5f152"},{"location":"python/DataAnalysis/ch08/#2020-03-31-0297777","text":"","title":"2020-03-31 0.297777"},{"location":"python/DataAnalysis/ch08/#freq-m-dtype-float64_9","text":"pts = ts.to_period() print(pts)","title":"Freq: M, dtype: float64"},{"location":"python/DataAnalysis/ch08/#2020-01-0567097","text":"","title":"2020-01 -0.567097"},{"location":"python/DataAnalysis/ch08/#2020-02-0634522","text":"","title":"2020-02 0.634522"},{"location":"python/DataAnalysis/ch08/#2020-03-0297777","text":"","title":"2020-03 0.297777"},{"location":"python/DataAnalysis/ch08/#freq-m-dtype-float64_10","text":"\u7531\u4e8e\u533a\u95f4\u662f\u975e\u91cd\u53e0\u65f6\u95f4\u8303\u56f4\uff0c\u4e00\u4e2a\u65f6\u95f4\u6233\u53ea\u80fd\u5c5e\u4e8e\u7ed9\u5b9a\u9891\u7387\u7684\u5355\u4e2a\u533a\u95f4\u3002 \u5c3d\u7ba1\u9ed8\u8ba4\u60c5\u51b5\u4e0b\u6839\u636e\u65f6\u95f4\u6233\u63a8\u65ad\u51fa\u65b0`PeriodIndex`\u7684\u9891\u7387\uff0c\u4f46\u53ef\u4ee5\u6307\u5b9a\u4efb\u4f55\u60f3\u8981\u7684\u9891\u7387\u3002 \u5728\u7ed3\u679c\u4e2d\u5305\u542b\u91cd\u590d\u7684\u533a\u95f4\u4e5f\u662f\u6ca1\u6709\u95ee\u9898\u7684\u3002 rng = pd.date_range('2020-01-01', periods=6, freq='D') ts = pd.Series(np.random.randn(6), index=rng) print(ts)","title":"Freq: M, dtype: float64"},{"location":"python/DataAnalysis/ch08/#2020-01-01-0111287","text":"","title":"2020-01-01 -0.111287"},{"location":"python/DataAnalysis/ch08/#2020-01-02-1442234","text":"","title":"2020-01-02 1.442234"},{"location":"python/DataAnalysis/ch08/#2020-01-03-0767553","text":"","title":"2020-01-03 -0.767553"},{"location":"python/DataAnalysis/ch08/#2020-01-04-0265064","text":"","title":"2020-01-04 -0.265064"},{"location":"python/DataAnalysis/ch08/#2020-01-05-1200312","text":"","title":"2020-01-05 1.200312"},{"location":"python/DataAnalysis/ch08/#2020-01-06-1782557","text":"","title":"2020-01-06 -1.782557"},{"location":"python/DataAnalysis/ch08/#freq-d-dtype-float64_3","text":"ts_m = ts.to_period('M') # \u6307\u5b9aperiod\u7684\u9891\u7387\uff08M\uff09,\u8f93\u51fa\u7ed3\u679c\u5305\u542b\u91cd\u590dperiod print(ts_m)","title":"Freq: D, dtype: float64"},{"location":"python/DataAnalysis/ch08/#2020-01-0111287","text":"","title":"2020-01 -0.111287"},{"location":"python/DataAnalysis/ch08/#2020-01-1442234","text":"","title":"2020-01 1.442234"},{"location":"python/DataAnalysis/ch08/#2020-01-0767553","text":"","title":"2020-01 -0.767553"},{"location":"python/DataAnalysis/ch08/#2020-01-0265064","text":"","title":"2020-01 -0.265064"},{"location":"python/DataAnalysis/ch08/#2020-01-1200312","text":"","title":"2020-01 1.200312"},{"location":"python/DataAnalysis/ch08/#2020-01-1782557","text":"","title":"2020-01 -1.782557"},{"location":"python/DataAnalysis/ch08/#freq-m-dtype-float64_11","text":"\u4f7f\u7528`to_timestamp`\u53ef\u4ee5\u5c06\u533a\u95f4\u518d\u8f6c\u6362\u4e3a\u65f6\u95f4\u6233\uff1a print(ts_m.to_timestamp(how='end'))","title":"Freq: M, dtype: float64"},{"location":"python/DataAnalysis/ch08/#2020-01-31-235959999999999-0111287","text":"","title":"2020-01-31 23:59:59.999999999 -0.111287"},{"location":"python/DataAnalysis/ch08/#2020-01-31-235959999999999-1442234","text":"","title":"2020-01-31 23:59:59.999999999 1.442234"},{"location":"python/DataAnalysis/ch08/#2020-01-31-235959999999999-0767553","text":"","title":"2020-01-31 23:59:59.999999999 -0.767553"},{"location":"python/DataAnalysis/ch08/#2020-01-31-235959999999999-0265064","text":"","title":"2020-01-31 23:59:59.999999999 -0.265064"},{"location":"python/DataAnalysis/ch08/#2020-01-31-235959999999999-1200312","text":"","title":"2020-01-31 23:59:59.999999999 1.200312"},{"location":"python/DataAnalysis/ch08/#2020-01-31-235959999999999-1782557","text":"","title":"2020-01-31 23:59:59.999999999 -1.782557"},{"location":"python/DataAnalysis/ch08/#dtype-float64_9","text":"print(ts_m.to_timestamp(how='start'))","title":"dtype: float64"},{"location":"python/DataAnalysis/ch08/#2020-01-01-0111287_1","text":"","title":"2020-01-01 -0.111287"},{"location":"python/DataAnalysis/ch08/#2020-01-01-1442234","text":"","title":"2020-01-01 1.442234"},{"location":"python/DataAnalysis/ch08/#2020-01-01-0767553","text":"","title":"2020-01-01 -0.767553"},{"location":"python/DataAnalysis/ch08/#2020-01-01-0265064","text":"","title":"2020-01-01 -0.265064"},{"location":"python/DataAnalysis/ch08/#2020-01-01-1200312","text":"","title":"2020-01-01 1.200312"},{"location":"python/DataAnalysis/ch08/#2020-01-01-1782557","text":"","title":"2020-01-01 -1.782557"},{"location":"python/DataAnalysis/ch08/#dtype-float64_10","text":"### \u4ece\u6570\u7ec4\u751f\u6210PeriodIndex \u56fa\u5b9a\u9891\u7387\u6570\u636e\u96c6\u6709\u65f6\u5b58\u50a8\u5728\u8de8\u8d8a\u591a\u5217\u7684\u65f6\u95f4\u8303\u56f4\u4fe1\u606f\u4e2d\u3002\u4f8b\u5982\uff0c\u5728\u8fd9\u4e2a\u5b8f\u89c2\u7ecf\u6d4e\u6570\u636e\u96c6\u4e2d\uff0c\u5e74\u4efd\u548c\u5b63\u5ea6\u5728\u4e0d\u540c\u5217\u4e2d\uff1a data = pd.read_csv('../examples/macrodata.csv') print(data.head(5))","title":"dtype: float64"},{"location":"python/DataAnalysis/ch08/#year-quarter-realgdp-realcons-unemp-pop-infl-realint","text":"","title":"year quarter realgdp realcons ... unemp pop infl realint"},{"location":"python/DataAnalysis/ch08/#0-19590-10-2710349-17074-58-177146-000-000","text":"","title":"0 1959.0 1.0 2710.349 1707.4 ... 5.8 177.146 0.00 0.00"},{"location":"python/DataAnalysis/ch08/#1-19590-20-2778801-17337-51-177830-234-074","text":"","title":"1 1959.0 2.0 2778.801 1733.7 ... 5.1 177.830 2.34 0.74"},{"location":"python/DataAnalysis/ch08/#2-19590-30-2775488-17518-53-178657-274-109","text":"","title":"2 1959.0 3.0 2775.488 1751.8 ... 5.3 178.657 2.74 1.09"},{"location":"python/DataAnalysis/ch08/#3-19590-40-2785204-17537-56-179386-027-406","text":"","title":"3 1959.0 4.0 2785.204 1753.7 ... 5.6 179.386 0.27 4.06"},{"location":"python/DataAnalysis/ch08/#4-19600-10-2847699-17705-52-180007-231-119","text":"print(data.year)","title":"4 1960.0 1.0 2847.699 1770.5 ... 5.2 180.007 2.31 1.19"},{"location":"python/DataAnalysis/ch08/#0-19590","text":"","title":"0 1959.0"},{"location":"python/DataAnalysis/ch08/#1-19590","text":"","title":"1 1959.0"},{"location":"python/DataAnalysis/ch08/#2-19590","text":"","title":"2 1959.0"},{"location":"python/DataAnalysis/ch08/#3-19590","text":"","title":"3 1959.0"},{"location":"python/DataAnalysis/ch08/#4-19600","text":"","title":"4 1960.0"},{"location":"python/DataAnalysis/ch08/#_10","text":"","title":"..."},{"location":"python/DataAnalysis/ch08/#198-20080","text":"","title":"198 2008.0"},{"location":"python/DataAnalysis/ch08/#199-20080","text":"","title":"199 2008.0"},{"location":"python/DataAnalysis/ch08/#200-20090","text":"","title":"200 2009.0"},{"location":"python/DataAnalysis/ch08/#201-20090","text":"","title":"201 2009.0"},{"location":"python/DataAnalysis/ch08/#202-20090","text":"","title":"202 2009.0"},{"location":"python/DataAnalysis/ch08/#name-year-length-203-dtype-float64","text":"print(data.quarter)","title":"Name: year, Length: 203, dtype: float64"},{"location":"python/DataAnalysis/ch08/#0-10","text":"","title":"0 1.0"},{"location":"python/DataAnalysis/ch08/#1-20","text":"","title":"1 2.0"},{"location":"python/DataAnalysis/ch08/#2-30","text":"","title":"2 3.0"},{"location":"python/DataAnalysis/ch08/#3-40","text":"","title":"3 4.0"},{"location":"python/DataAnalysis/ch08/#4-10","text":"","title":"4 1.0"},{"location":"python/DataAnalysis/ch08/#_11","text":"","title":"..."},{"location":"python/DataAnalysis/ch08/#198-30","text":"","title":"198 3.0"},{"location":"python/DataAnalysis/ch08/#199-40","text":"","title":"199 4.0"},{"location":"python/DataAnalysis/ch08/#200-10","text":"","title":"200 1.0"},{"location":"python/DataAnalysis/ch08/#201-20","text":"","title":"201 2.0"},{"location":"python/DataAnalysis/ch08/#202-30","text":"","title":"202 3.0"},{"location":"python/DataAnalysis/ch08/#name-quarter-length-203-dtype-float64","text":"\u901a\u8fc7\u5c06\u8fd9\u4e9b\u6570\u7ec4\u548c\u9891\u7387\u4f20\u9012\u7ed9`PeriodIndex`\uff0c\u53ef\u4ee5\u8054\u5408\u5f62\u6210DataFrame\u7684\u7d22\u5f15 index = pd.PeriodIndex(year=data.year, quarter=data.quarter, freq='Q-DEC') print(index)","title":"Name: quarter, Length: 203, dtype: float64"},{"location":"python/DataAnalysis/ch08/#periodindex1959q1-1959q2-1959q3-1959q4-1960q1-1960q2","text":"","title":"PeriodIndex(['1959Q1', '1959Q2', '1959Q3', '1959Q4', '1960Q1', '1960Q2',"},{"location":"python/DataAnalysis/ch08/#1960q3-1960q4-1961q1-1961q2","text":"","title":"'1960Q3', '1960Q4', '1961Q1', '1961Q2',"},{"location":"python/DataAnalysis/ch08/#_12","text":"","title":"..."},{"location":"python/DataAnalysis/ch08/#2007q2-2007q3-2007q4-2008q1-2008q2-2008q3","text":"","title":"'2007Q2', '2007Q3', '2007Q4', '2008Q1', '2008Q2', '2008Q3',"},{"location":"python/DataAnalysis/ch08/#2008q4-2009q1-2009q2-2009q3","text":"","title":"'2008Q4', '2009Q1', '2009Q2', '2009Q3'],"},{"location":"python/DataAnalysis/ch08/#dtypeperiodq-dec-length203","text":"data.index = index # \u901a\u8fc7\u539f\u7d22\u5f151~202\uff0c\u628ayear\u548cquarter\u8054\u5408\u8d77\u6765\uff0c\u751f\u6210\u65b0\u7d22\u5f15\uff0c\u5e76\u66ff\u6362\u539f\u7d22\u5f15 print(data.infl)","title":"dtype='period[Q-DEC]', length=203)"},{"location":"python/DataAnalysis/ch08/#1959q1-000","text":"","title":"1959Q1 0.00"},{"location":"python/DataAnalysis/ch08/#1959q2-234","text":"","title":"1959Q2 2.34"},{"location":"python/DataAnalysis/ch08/#1959q3-274","text":"","title":"1959Q3 2.74"},{"location":"python/DataAnalysis/ch08/#1959q4-027","text":"","title":"1959Q4 0.27"},{"location":"python/DataAnalysis/ch08/#1960q1-231","text":"","title":"1960Q1 2.31"},{"location":"python/DataAnalysis/ch08/#_13","text":"","title":"..."},{"location":"python/DataAnalysis/ch08/#2008q3-316","text":"","title":"2008Q3 -3.16"},{"location":"python/DataAnalysis/ch08/#2008q4-879","text":"","title":"2008Q4 -8.79"},{"location":"python/DataAnalysis/ch08/#2009q1-094","text":"","title":"2009Q1 0.94"},{"location":"python/DataAnalysis/ch08/#2009q2-337","text":"","title":"2009Q2 3.37"},{"location":"python/DataAnalysis/ch08/#2009q3-356","text":"","title":"2009Q3 3.56"},{"location":"python/DataAnalysis/ch08/#freq-q-dec-name-infl-length-203-dtype-float64","text":"## \u91cd\u65b0\u91c7\u6837\u9891\u7387\u8f6c\u6362 import pandas as pd import numpy as np from pandas.tseries.frequencies import to_offset \u91cd\u65b0\u91c7\u6837\u662f\u6307\u5c06\u65f6\u95f4\u5e8f\u5217\u4ece\u4e00\u4e2a\u9891\u7387\u8f6c\u6362\u4e3a\u53e6\u4e00\u4e2a\u9891\u7387\u7684\u8fc7\u7a0b\u3002 \u5c06\u66f4\u9ad8\u9891\u7387\u7684\u6570\u636e\u805a\u5408\u5230\u4f4e\u9891\u7387\u88ab\u79f0\u4e3a\u5411\u4e0b\u91c7\u6837\uff0c\u800c\u4ece\u4f4e\u9891\u7387\u8f6c\u6362\u5230\u9ad8\u9891\u7387\u79f0\u4e3a\u5411\u4e0a\u91c7\u6837\u3002 \u5e76\u4e0d\u662f\u6240\u6709\u7684\u91cd\u65b0\u91c7\u6837\u90fd\u5c5e\u4e8e\u4e0a\u9762\u8bf4\u7684\u4e24\u7c7b\u3002\u4f8b\u5982\uff0c\u5c06W-WED\uff08weekly on Wednesday\uff0c\u6bcf\u5468\u4e09\uff09\u8f6c\u6362\u5230W-FRI\uff08\u6bcf\u5468\u4e94\uff09\u65e2\u4e0d\u662f\u5411\u4e0a\u91c7\u6837\u4e5f\u4e0d\u662f\u5411\u4e0b\u91c7\u6837\u3002 pandas\u5bf9\u8c61\u90fd\u914d\u6709`resample`\u65b9\u6cd5\uff0c\u8be5\u65b9\u6cd5\u662f\u6240\u6709\u9891\u7387\u8f6c\u6362\u7684\u5de5\u5177\u51fd\u6570\u3002`resample`\u62e5\u6709\u7c7b\u4f3c\u4e8e`groupby`\u7684API\uff1b\u8c03\u7528`resample`\u5bf9\u6570\u636e\u5206\u7ec4\uff0c\u4e4b\u540e\u518d\u8c03\u7528\u805a\u5408\u51fd\u6570\uff1a ### resample\u65b9\u6cd5\u53c2\u6570 \u53c2\u6570 * freq: \u8868\u793a\u91cd\u91c7\u6837\u9891\u7387\uff0c\u4f8b\u5982\u2018M'\u3001\u20185min'\uff0cSecond(15) * how='mean': \u7528\u4e8e\u4ea7\u751f\u805a\u5408\u503c\u7684\u51fd\u6570\u540d\u6216\u6570\u7ec4\u51fd\u6570\uff0c\u4f8b\u5982\u2018mean'\u3001\u2018ohlc'\u3001np.max\u7b49\uff0c\u9ed8\u8ba4\u662f\u2018mean'\uff0c\u5176\u4ed6\u5e38\u7528\u7684\u503c\u7531\uff1a\u2018first'\u3001\u2018last'\u3001\u2018median'\u3001\u2018max'\u3001\u2018min' * axis=0: \u9ed8\u8ba4\u662f\u7eb5\u8f74\uff0c\u6a2a\u8f74\u8bbe\u7f6eaxis=1 * fill_method = None: \u5347\u91c7\u6837\u65f6\u5982\u4f55\u63d2\u503c\uff0c\u6bd4\u5982\u2018ffill'\u3001\u2018bfill'\u7b49 * closed = \u2018right': \u5728\u964d\u91c7\u6837\u65f6\uff0c\u5404\u65f6\u95f4\u6bb5\u7684\u54ea\u4e00\u6bb5\u662f\u95ed\u5408\u7684\uff0c\u2018right'\u6216\u2018left'\uff0c\u9ed8\u8ba4\u2018right' * label= \u2018right': \u5728\u964d\u91c7\u6837\u65f6\uff0c\u5982\u4f55\u8bbe\u7f6e\u805a\u5408\u503c\u7684\u6807\u7b7e\uff0c\u4f8b\u5982\uff0c9\uff1a30-9\uff1a35\u4f1a\u88ab\u6807\u8bb0\u62109\uff1a30\u8fd8\u662f9\uff1a35,\u9ed8\u8ba49\uff1a35 * loffset = None: \u9762\u5143\u6807\u7b7e\u7684\u65f6\u95f4\u6821\u6b63\u503c\uff0c\u6bd4\u5982\u2018-1s'\u6216Second(-1)\u7528\u4e8e\u5c06\u805a\u5408\u6807\u7b7e\u8c03\u65e91\u79d2 * limit=None: \u5728\u5411\u524d\u6216\u5411\u540e\u586b\u5145\u65f6\uff0c\u5141\u8bb8\u586b\u5145\u7684\u6700\u5927\u65f6\u671f\u6570 * kind = None: \u805a\u5408\u5230\u65f6\u671f\uff08\u2018period'\uff09\u6216\u65f6\u95f4\u6233\uff08\u2018timestamp'\uff09\uff0c\u9ed8\u8ba4\u805a\u5408\u5230\u65f6\u95f4\u5e8f\u5217\u7684\u7d22\u5f15\u7c7b\u578b * convention = None: \u5f53\u91cd\u91c7\u6837\u65f6\u671f\u65f6\uff0c\u5c06\u4f4e\u9891\u7387\u8f6c\u6362\u5230\u9ad8\u9891\u7387\u6240\u91c7\u7528\u7684\u7ea6\u5b9a\uff08start\u6216end\uff09\u3002\u9ed8\u8ba4\u2018end' rng = pd.date_range('2020-1-1', periods=100, freq='D') ts = pd.Series(np.random.randn(len(rng)), index=rng) print(ts)","title":"Freq: Q-DEC, Name: infl, Length: 203, dtype: float64"},{"location":"python/DataAnalysis/ch08/#2020-01-01-0802409","text":"","title":"2020-01-01 0.802409"},{"location":"python/DataAnalysis/ch08/#2020-01-02-1147130","text":"","title":"2020-01-02 -1.147130"},{"location":"python/DataAnalysis/ch08/#2020-01-03-1076115","text":"","title":"2020-01-03 -1.076115"},{"location":"python/DataAnalysis/ch08/#2020-01-04-2097443","text":"","title":"2020-01-04 -2.097443"},{"location":"python/DataAnalysis/ch08/#2020-01-05-0577671","text":"","title":"2020-01-05 0.577671"},{"location":"python/DataAnalysis/ch08/#_14","text":"","title":"..."},{"location":"python/DataAnalysis/ch08/#2020-04-05-0110747","text":"","title":"2020-04-05 -0.110747"},{"location":"python/DataAnalysis/ch08/#2020-04-06-0132867","text":"","title":"2020-04-06 0.132867"},{"location":"python/DataAnalysis/ch08/#2020-04-07-0294061","text":"","title":"2020-04-07 -0.294061"},{"location":"python/DataAnalysis/ch08/#2020-04-08-0246155","text":"","title":"2020-04-08 -0.246155"},{"location":"python/DataAnalysis/ch08/#2020-04-09-0927194","text":"","title":"2020-04-09 0.927194"},{"location":"python/DataAnalysis/ch08/#freq-d-length-100-dtype-float64","text":"print(ts.resample('M'))","title":"Freq: D, Length: 100, dtype: float64"},{"location":"python/DataAnalysis/ch08/#datetimeindexresampler-freq-axis0-closedright-labelright-conventionstart-originstart_day","text":"print(ts.resample('M').mean()) # \u628a100\u5929\u7684\u6570\u636e\u6309\u6708groupby\uff0c\u5e76\u8f93\u51fa\u6708\u672b\u6700\u540e\u4e00\u5929\uff0c\u8ba1\u7b97\u5e73\u5747\u503c","title":"DatetimeIndexResampler [freq=, axis=0, closed=right, label=right, convention=start, origin=start_day]"},{"location":"python/DataAnalysis/ch08/#2020-01-31-0311714","text":"","title":"2020-01-31 -0.311714"},{"location":"python/DataAnalysis/ch08/#2020-02-29-0121526","text":"","title":"2020-02-29 0.121526"},{"location":"python/DataAnalysis/ch08/#2020-03-31-0051131","text":"","title":"2020-03-31 -0.051131"},{"location":"python/DataAnalysis/ch08/#2020-04-30-0273113","text":"","title":"2020-04-30 -0.273113"},{"location":"python/DataAnalysis/ch08/#freq-m-dtype-float64_12","text":"print(ts.resample('M', kind='period').mean()) # # \u628a100\u5929\u7684\u6570\u636e\u6309\u6708groupby\uff0c\u5e76\u8f93\u51fa\u6708\u4efd\uff08\u53c2\u6570period\uff09\uff0c\u8ba1\u7b97\u5e73\u5747\u503c","title":"Freq: M, dtype: float64"},{"location":"python/DataAnalysis/ch08/#2020-01-0311714","text":"","title":"2020-01 -0.311714"},{"location":"python/DataAnalysis/ch08/#2020-02-0121526","text":"","title":"2020-02 0.121526"},{"location":"python/DataAnalysis/ch08/#2020-03-0051131","text":"","title":"2020-03 -0.051131"},{"location":"python/DataAnalysis/ch08/#2020-04-0273113","text":"","title":"2020-04 -0.273113"},{"location":"python/DataAnalysis/ch08/#freq-m-dtype-float64_13","text":"### \u5411\u4e0b\u91c7\u6837 \u5c06\u6570\u636e\u805a\u5408\u5230\u4e00\u4e2a\u89c4\u5219\u7684\u4f4e\u9891\u7387\u4e0a\u662f\u4e00\u4e2a\u5e38\u89c1\u7684\u65f6\u95f4\u5e8f\u5217\u4efb\u52a1\u3002 \u8981\u805a\u5408\u7684\u6570\u636e\u4e0d\u5fc5\u662f\u56fa\u5b9a\u9891\u7387\u7684\u3002 \u671f\u671b\u7684\u9891\u7387\u5b9a\u4e49\u4e86\u7528\u4e8e\u5bf9\u65f6\u95f4\u5e8f\u5217\u5207\u7247\u4ee5\u805a\u5408\u7684\u7bb1\u4f53\u8fb9\u754c\u3002\u4f8b\u5982\uff0c\u8981\u5c06\u65f6\u95f4\u8f6c\u6362\u4e3a\u6bcf\u6708\uff0c`M`\u6216`BM`\uff0c\u5219\u9700\u8981\u5c06\u6570\u636e\u5206\u6210\u4e00\u4e2a\u6708\u7684\u65f6\u95f4\u95f4\u9694\u3002 \u6bcf\u4e2a\u95f4\u9694\u662f\u534a\u95ed\u5408\u7684\uff0c\u4e00\u4e2a\u6570\u636e\u70b9\u53ea\u80fd\u5c5e\u4e8e\u4e00\u4e2a\u65f6\u95f4\u95f4\u9694\uff0c\u65f6\u95f4\u95f4\u9694\u7684\u5e76\u96c6\u5fc5\u987b\u662f\u6574\u4e2a\u65f6\u95f4\u5e27\u3002 \u5728\u4f7f\u7528resample\u8fdb\u884c\u5411\u4e0b\u91c7\u6837\u6570\u636e\u65f6\u6709\u4e9b\u4e8b\u60c5\u9700\u8981\u8003\u8651\uff1a * \u6bcf\u6bb5\u95f4\u9694\u7684\u54ea\u4e00\u8fb9\u662f\u95ed\u5408\u7684\u3002 * \u5982\u4f55\u5728\u95f4\u9694\u7684\u8d77\u59cb\u6216\u7ed3\u675f\u4f4d\u7f6e\u6807\u8bb0\u6bcf\u4e2a\u5df2\u805a\u5408\u7684\u7bb1\u4f53\u3002 rng = pd.date_range('2020-1-1', periods=12, freq='T') ts = pd.Series(np.arange(12), index=rng) print(ts)","title":"Freq: M, dtype: float64"},{"location":"python/DataAnalysis/ch08/#2020-01-01-000000-0","text":"","title":"2020-01-01 00:00:00 0"},{"location":"python/DataAnalysis/ch08/#2020-01-01-000100-1","text":"","title":"2020-01-01 00:01:00 1"},{"location":"python/DataAnalysis/ch08/#2020-01-01-000200-2","text":"","title":"2020-01-01 00:02:00 2"},{"location":"python/DataAnalysis/ch08/#2020-01-01-000300-3","text":"","title":"2020-01-01 00:03:00 3"},{"location":"python/DataAnalysis/ch08/#2020-01-01-000400-4","text":"","title":"2020-01-01 00:04:00 4"},{"location":"python/DataAnalysis/ch08/#2020-01-01-000500-5","text":"","title":"2020-01-01 00:05:00 5"},{"location":"python/DataAnalysis/ch08/#2020-01-01-000600-6","text":"","title":"2020-01-01 00:06:00 6"},{"location":"python/DataAnalysis/ch08/#2020-01-01-000700-7","text":"","title":"2020-01-01 00:07:00 7"},{"location":"python/DataAnalysis/ch08/#2020-01-01-000800-8","text":"","title":"2020-01-01 00:08:00 8"},{"location":"python/DataAnalysis/ch08/#2020-01-01-000900-9","text":"","title":"2020-01-01 00:09:00 9"},{"location":"python/DataAnalysis/ch08/#2020-01-01-001000-10","text":"","title":"2020-01-01 00:10:00 10"},{"location":"python/DataAnalysis/ch08/#2020-01-01-001100-11","text":"","title":"2020-01-01 00:11:00 11"},{"location":"python/DataAnalysis/ch08/#freq-t-dtype-int64","text":"\u6309\u4e94\u5206\u949f\u9891\u7387\u805a\u5408\u5206\u7ec4\uff0c\u8ba1\u7b97\u6bcf\u4e00\u7ec4\u7684\u52a0\u548c\u3002\u9891\u7387\u6309\u4e94\u5206\u949f\u7684\u589e\u91cf\u5b9a\u4e49\u4e86\u7bb1\u4f53\u8fb9\u754c\u3002 \u9ed8\u8ba4\u60c5\u51b5\u4e0b\uff0c\u5de6\u7bb1\u4f53\u8fb9\u754c\u662f\u5305\u542b\u7684\uff0c\u56e0\u6b6400:00\u7684\u503c\u662f\u5305\u542b\u572800:00\u523000:05\u95f4\u9694\u5185\u7684\u3002 \u4f20\u9012`closed='right'`\u5c06\u95f4\u9694\u7684\u95ed\u5408\u7aef\u6539\u4e3a\u4e86\u53f3\u8fb9\u3002 \u5206\u7ec4\uff1a * left: [00:00,00:01,00:02,00:03,00:04],[00:05,00:06,00:07,00:08,00:09],[00:10,00:11] * right:[00:00],[00:01,00:02,00:03,00:04,00:05],[00:06,00:07,00:08,00:09,00:10],[00:11] result = ts.resample('5min', closed='right').sum() print(result)","title":"Freq: T, dtype: int64"},{"location":"python/DataAnalysis/ch08/#2019-12-31-235500-0","text":"","title":"2019-12-31 23:55:00 0"},{"location":"python/DataAnalysis/ch08/#2020-01-01-000000-15","text":"","title":"2020-01-01 00:00:00 15"},{"location":"python/DataAnalysis/ch08/#2020-01-01-000500-40","text":"","title":"2020-01-01 00:05:00 40"},{"location":"python/DataAnalysis/ch08/#2020-01-01-001000-11","text":"","title":"2020-01-01 00:10:00 11"},{"location":"python/DataAnalysis/ch08/#freq-5t-dtype-int64","text":"result = ts.resample('5min', closed='left').sum() print(result)","title":"Freq: 5T, dtype: int64"},{"location":"python/DataAnalysis/ch08/#2020-01-01-000000-10","text":"","title":"2020-01-01 00:00:00 10"},{"location":"python/DataAnalysis/ch08/#2020-01-01-000500-35","text":"","title":"2020-01-01 00:05:00 35"},{"location":"python/DataAnalysis/ch08/#2020-01-01-001000-21","text":"","title":"2020-01-01 00:10:00 21"},{"location":"python/DataAnalysis/ch08/#freq-5t-dtype-int64_1","text":"\u6700\u540e\uff0c\u5c06\u7ed3\u679c\u7d22\u5f15\u79fb\u52a8\u4e00\u5b9a\u7684\u6570\u91cf\uff0c\u4f8b\u5982\u4ece\u53f3\u8fb9\u7f18\u51cf\u53bb\u4e00\u79d2\uff0c\u4ee5\u4f7f\u5176\u66f4\u6e05\u695a\u5730\u8868\u660e\u65f6\u95f4\u6233\u6240\u6307\u7684\u95f4\u9694\u3002 \u8981\u5b9e\u73b0\u8fd9\u4e2a\u529f\u80fd\uff0c\u5411`loffset`\u4f20\u9012\u5b57\u7b26\u4e32\u6216\u65e5\u671f\u504f\u7f6e\uff1a result = ts.resample('5min', closed='right', label='right', loffset='-1s').sum() print(result)","title":"Freq: 5T, dtype: int64"},{"location":"python/DataAnalysis/ch08/#2019-12-31-235959-0","text":"","title":"2019-12-31 23:59:59 0"},{"location":"python/DataAnalysis/ch08/#2020-01-01-000459-15","text":"","title":"2020-01-01 00:04:59 15"},{"location":"python/DataAnalysis/ch08/#2020-01-01-000959-40","text":"","title":"2020-01-01 00:09:59 40"},{"location":"python/DataAnalysis/ch08/#2020-01-01-001459-11","text":"","title":"2020-01-01 00:14:59 11"},{"location":"python/DataAnalysis/ch08/#freq-5t-dtype-int64_2","text":"","title":"Freq: 5T, dtype: int64"},{"location":"python/DataAnalysis/ch08/#futurewarning-loffset-in-resample-and-in-grouper-is-deprecated","text":"","title":"FutureWarning: 'loffset' in .resample() and in Grouper() is deprecated."},{"location":"python/DataAnalysis/ch08/#dfresamplefreq3s-loffset8h","text":"","title":">>> df.resample(freq=\"3s\", loffset=\"8H\")"},{"location":"python/DataAnalysis/ch08/#becomes","text":"","title":"becomes:"},{"location":"python/DataAnalysis/ch08/#from-pandastseriesfrequencies-import-to_offset","text":"","title":">>> from pandas.tseries.frequencies import to_offset"},{"location":"python/DataAnalysis/ch08/#df-dfresamplefreq3smean","text":"","title":">>> df = df.resample(freq=\"3s\").mean()"},{"location":"python/DataAnalysis/ch08/#dfindex-dfindexto_timestamp-to_offset8h","text":"#### \u5f00\u7aef-\u5cf0\u503c-\u8c37\u503c-\u7ed3\u675f\uff08OHLC\uff09\u91cd\u65b0\u91c7\u6837 \u5728\u91d1\u878d\u4e2d\uff0c\u4e3a\u6bcf\u4e2a\u6570\u636e\u6876\u8ba1\u7b97\u56db\u4e2a\u503c\u662f\u4e00\u79cd\u6d41\u884c\u7684\u65f6\u95f4\u5e8f\u5217\u805a\u5408\u65b9\u6cd5\uff1a\u7b2c\u4e00\u4e2a\u503c\uff08\u5f00\u7aef\uff09\u3001\u6700\u540e\u4e00\u4e2a\u503c\uff08\u7ed3\u675f\uff09\u3001\u6700\u5927\u503c\uff08\u5cf0\u503c\uff09\u548c\u6700\u5c0f\u503c\uff08\u8c37\u503c\uff09\u3002 \u901a\u8fc7\u4f7f\u7528`ohlc`\u805a\u5408\u51fd\u6570\u53d6\u5f97\u5305\u542b\u56db\u79cd\u805a\u5408\u503c\u5217\u7684DataFrame\uff0c\u8fd9\u4e9b\u503c\u5728\u6570\u636e\u7684\u5355\u6b21\u626b\u63cf\u4e2d\u88ab\u9ad8\u6548\u8ba1\u7b97\uff1a result = ts.resample('5min').ohlc() print(result)","title":">>> df.index = df.index.to_timestamp() + to_offset(\"8H\")"},{"location":"python/DataAnalysis/ch08/#open-high-low-close","text":"","title":"open high low close"},{"location":"python/DataAnalysis/ch08/#2020-01-01-000000-0-4-0-4","text":"","title":"2020-01-01 00:00:00 0 4 0 4"},{"location":"python/DataAnalysis/ch08/#2020-01-01-000500-5-9-5-9","text":"","title":"2020-01-01 00:05:00 5 9 5 9"},{"location":"python/DataAnalysis/ch08/#2020-01-01-001000-10-11-10-11","text":"### \u5411\u4e0a\u91c7\u6837\u4e0e\u63d2\u503c \u5f53\u4ece\u4f4e\u9891\u7387\u8f6c\u6362\u4e3a\u9ad8\u9891\u7387\u65f6\uff0c\u5e76\u4e0d\u9700\u8981\u4efb\u4f55\u805a\u5408\u3002 df = pd.DataFrame( np.random.randn(2, 4), index=pd.date_range('2020/1/1', periods=2, freq='W-WED'), columns=['Colorado', 'Texas', 'New York', 'Ohio'] ) print(df)","title":"2020-01-01 00:10:00 10 11 10 11"},{"location":"python/DataAnalysis/ch08/#colorado-texas-new-york-ohio","text":"","title":"Colorado Texas New York Ohio"},{"location":"python/DataAnalysis/ch08/#2020-01-01-0228758-0758718-0025410-1001819","text":"","title":"2020-01-01 -0.228758 -0.758718 -0.025410 -1.001819"},{"location":"python/DataAnalysis/ch08/#2020-01-08-0704541-0261414-0863335-0267101","text":"df_daily = df.resample('W-WED').sum() print(df_daily)","title":"2020-01-08 -0.704541 -0.261414 -0.863335 0.267101"},{"location":"python/DataAnalysis/ch08/#colorado-texas-new-york-ohio_1","text":"","title":"Colorado Texas New York Ohio"},{"location":"python/DataAnalysis/ch08/#2020-01-01-0228758-0758718-0025410-1001819_1","text":"","title":"2020-01-01 -0.228758 -0.758718 -0.025410 -1.001819"},{"location":"python/DataAnalysis/ch08/#2020-01-08-0704541-0261414-0863335-0267101_1","text":"df_daily = df.resample('D').sum() print(df_daily)","title":"2020-01-08 -0.704541 -0.261414 -0.863335 0.267101"},{"location":"python/DataAnalysis/ch08/#colorado-texas-new-york-ohio_2","text":"","title":"Colorado Texas New York Ohio"},{"location":"python/DataAnalysis/ch08/#2020-01-01-0228758-0758718-0025410-1001819_2","text":"","title":"2020-01-01 -0.228758 -0.758718 -0.025410 -1.001819"},{"location":"python/DataAnalysis/ch08/#2020-01-02-0000000-0000000-0000000-0000000","text":"","title":"2020-01-02 0.000000 0.000000 0.000000 0.000000"},{"location":"python/DataAnalysis/ch08/#2020-01-03-0000000-0000000-0000000-0000000","text":"","title":"2020-01-03 0.000000 0.000000 0.000000 0.000000"},{"location":"python/DataAnalysis/ch08/#2020-01-04-0000000-0000000-0000000-0000000","text":"","title":"2020-01-04 0.000000 0.000000 0.000000 0.000000"},{"location":"python/DataAnalysis/ch08/#2020-01-05-0000000-0000000-0000000-0000000","text":"","title":"2020-01-05 0.000000 0.000000 0.000000 0.000000"},{"location":"python/DataAnalysis/ch08/#2020-01-06-0000000-0000000-0000000-0000000","text":"","title":"2020-01-06 0.000000 0.000000 0.000000 0.000000"},{"location":"python/DataAnalysis/ch08/#2020-01-07-0000000-0000000-0000000-0000000","text":"","title":"2020-01-07 0.000000 0.000000 0.000000 0.000000"},{"location":"python/DataAnalysis/ch08/#2020-01-08-0704541-0261414-0863335-0267101_2","text":"\u5f53\u5bf9\u8fd9\u4e9b\u6570\u636e\u4f7f\u7528\u805a\u5408\u51fd\u6570\u65f6\uff0c\u6bcf\u4e00\u7ec4\u53ea\u6709\u4e00\u4e2a\u503c\uff0c\u5e76\u4e14\u4f1a\u5728\u95f4\u9699\u4e2d\u4ea7\u751f\u7f3a\u5931\u503c\u3002 \u4f7f\u7528`asfreq`\u65b9\u6cd5\u5728\u4e0d\u805a\u5408\u7684\u60c5\u51b5\u4e0b\u8f6c\u6362\u5230\u9ad8\u9891\u7387\uff1a df_daily = df.resample('D').asfreq() print(df_daily)","title":"2020-01-08 -0.704541 -0.261414 -0.863335 0.267101"},{"location":"python/DataAnalysis/ch08/#colorado-texas-new-york-ohio_3","text":"","title":"Colorado Texas New York Ohio"},{"location":"python/DataAnalysis/ch08/#2020-01-01-0228758-0758718-0025410-1001819_3","text":"","title":"2020-01-01 -0.228758 -0.758718 -0.025410 -1.001819"},{"location":"python/DataAnalysis/ch08/#2020-01-02-nan-nan-nan-nan","text":"","title":"2020-01-02 NaN NaN NaN NaN"},{"location":"python/DataAnalysis/ch08/#2020-01-03-nan-nan-nan-nan","text":"","title":"2020-01-03 NaN NaN NaN NaN"},{"location":"python/DataAnalysis/ch08/#2020-01-04-nan-nan-nan-nan","text":"","title":"2020-01-04 NaN NaN NaN NaN"},{"location":"python/DataAnalysis/ch08/#2020-01-05-nan-nan-nan-nan","text":"","title":"2020-01-05 NaN NaN NaN NaN"},{"location":"python/DataAnalysis/ch08/#2020-01-06-nan-nan-nan-nan","text":"","title":"2020-01-06 NaN NaN NaN NaN"},{"location":"python/DataAnalysis/ch08/#2020-01-07-nan-nan-nan-nan","text":"","title":"2020-01-07 NaN NaN NaN NaN"},{"location":"python/DataAnalysis/ch08/#2020-01-08-0704541-0261414-0863335-0267101_3","text":"\u5728\u975e\u661f\u671f\u4e09\u7684\u65e5\u671f\u4e0a\u5411\u524d\u586b\u5145\u6bcf\u5468\u6570\u503c\u3002`fillna`\u548c`reindex`\u65b9\u6cd5\u4e2d\u53ef\u7528\u7684\u586b\u5145\u6216\u63d2\u503c\u65b9\u6cd5\u53ef\u7528\u4e8e\u91cd\u91c7\u6837\uff1a df_daily = df.resample('D').ffill() print(df_daily)","title":"2020-01-08 -0.704541 -0.261414 -0.863335 0.267101"},{"location":"python/DataAnalysis/ch08/#colorado-texas-new-york-ohio_4","text":"","title":"Colorado Texas New York Ohio"},{"location":"python/DataAnalysis/ch08/#2020-01-01-0228758-0758718-0025410-1001819_4","text":"","title":"2020-01-01 -0.228758 -0.758718 -0.025410 -1.001819"},{"location":"python/DataAnalysis/ch08/#2020-01-02-0228758-0758718-0025410-1001819","text":"","title":"2020-01-02 -0.228758 -0.758718 -0.025410 -1.001819"},{"location":"python/DataAnalysis/ch08/#2020-01-03-0228758-0758718-0025410-1001819","text":"","title":"2020-01-03 -0.228758 -0.758718 -0.025410 -1.001819"},{"location":"python/DataAnalysis/ch08/#2020-01-04-0228758-0758718-0025410-1001819","text":"","title":"2020-01-04 -0.228758 -0.758718 -0.025410 -1.001819"},{"location":"python/DataAnalysis/ch08/#2020-01-05-0228758-0758718-0025410-1001819","text":"","title":"2020-01-05 -0.228758 -0.758718 -0.025410 -1.001819"},{"location":"python/DataAnalysis/ch08/#2020-01-06-0228758-0758718-0025410-1001819","text":"","title":"2020-01-06 -0.228758 -0.758718 -0.025410 -1.001819"},{"location":"python/DataAnalysis/ch08/#2020-01-07-0228758-0758718-0025410-1001819","text":"","title":"2020-01-07 -0.228758 -0.758718 -0.025410 -1.001819"},{"location":"python/DataAnalysis/ch08/#2020-01-08-0704541-0261414-0863335-0267101_4","text":"\u53ef\u4ee5\u540c\u6837\u9009\u62e9\u4ec5\u5411\u524d\u586b\u5145\u4e00\u5b9a\u6570\u91cf\u7684\u533a\u95f4\uff0c\u4ee5\u9650\u5236\u7ee7\u7eed\u4f7f\u7528\u89c2\u6d4b\u503c\u7684\u65f6\u8ddd\uff1a df_daily = df.resample('D').ffill(limit=2) print(df_daily)","title":"2020-01-08 -0.704541 -0.261414 -0.863335 0.267101"},{"location":"python/DataAnalysis/ch08/#colorado-texas-new-york-ohio_5","text":"","title":"Colorado Texas New York Ohio"},{"location":"python/DataAnalysis/ch08/#2020-01-01-0228758-0758718-0025410-1001819_5","text":"","title":"2020-01-01 -0.228758 -0.758718 -0.025410 -1.001819"},{"location":"python/DataAnalysis/ch08/#2020-01-02-0228758-0758718-0025410-1001819_1","text":"","title":"2020-01-02 -0.228758 -0.758718 -0.025410 -1.001819"},{"location":"python/DataAnalysis/ch08/#2020-01-03-0228758-0758718-0025410-1001819_1","text":"","title":"2020-01-03 -0.228758 -0.758718 -0.025410 -1.001819"},{"location":"python/DataAnalysis/ch08/#2020-01-04-nan-nan-nan-nan_1","text":"","title":"2020-01-04 NaN NaN NaN NaN"},{"location":"python/DataAnalysis/ch08/#2020-01-05-nan-nan-nan-nan_1","text":"","title":"2020-01-05 NaN NaN NaN NaN"},{"location":"python/DataAnalysis/ch08/#2020-01-06-nan-nan-nan-nan_1","text":"","title":"2020-01-06 NaN NaN NaN NaN"},{"location":"python/DataAnalysis/ch08/#2020-01-07-nan-nan-nan-nan_1","text":"","title":"2020-01-07 NaN NaN NaN NaN"},{"location":"python/DataAnalysis/ch08/#2020-01-08-0704541-0261414-0863335-0267101_5","text":"\u6ce8\u610f\uff0c\u65b0\u7684\u65e5\u671f\u7d22\u5f15\u4e0d\u9700\u8981\u4e0e\u65e7\u7684\u7d22\u5f15\u91cd\u53e0\uff0c\u548c\u539f\u6765`df`\u7684\u503c\u4e00\u6837\uff0c\u53ea\u662f\u65e5\u671f\u7d22\u5f15\u53d8\u4e86\u3002 df_new = df.resample('W-THU').ffill() print(df_new)","title":"2020-01-08 -0.704541 -0.261414 -0.863335 0.267101"},{"location":"python/DataAnalysis/ch08/#colorado-texas-new-york-ohio_6","text":"","title":"Colorado Texas New York Ohio"},{"location":"python/DataAnalysis/ch08/#2020-01-02-0228758-0758718-0025410-1001819_2","text":"","title":"2020-01-02 -0.228758 -0.758718 -0.025410 -1.001819"},{"location":"python/DataAnalysis/ch08/#2020-01-09-0704541-0261414-0863335-0267101","text":"### \u4f7f\u7528\u533a\u95f4\u8fdb\u884c\u91cd\u65b0\u91c7\u6837 \u5bf9\u4ee5\u533a\u95f4\u4e3a\u7d22\u5f15\u7684\u6570\u636e\u8fdb\u884c\u91c7\u6837\u4e0e\u65f6\u95f4\u6233\u7684\u60c5\u51b5\u7c7b\u4f3c\uff1a df = pd.DataFrame( np.random.randn(24, 4), index=pd.period_range('2020-1', periods=24, freq='M'), columns=['Colorado', 'Texas', 'New York', 'Ohio'] ) print(df)","title":"2020-01-09 -0.704541 -0.261414 -0.863335 0.267101"},{"location":"python/DataAnalysis/ch08/#2020-01-0721395-1492674-0707410-1641890","text":"","title":"2020-01 0.721395 -1.492674 0.707410 1.641890"},{"location":"python/DataAnalysis/ch08/#2020-02-0894880-0032823-0676158-0029203","text":"","title":"2020-02 -0.894880 0.032823 -0.676158 0.029203"},{"location":"python/DataAnalysis/ch08/#2020-03-2147365-0176796-0562695-0747656","text":"","title":"2020-03 2.147365 -0.176796 0.562695 -0.747656"},{"location":"python/DataAnalysis/ch08/#2020-04-1496037-0797119-0495601-0774147","text":"","title":"2020-04 1.496037 -0.797119 -0.495601 0.774147"},{"location":"python/DataAnalysis/ch08/#2020-05-0309839-0502563-0237244-0910624","text":"","title":"2020-05 -0.309839 0.502563 0.237244 0.910624"},{"location":"python/DataAnalysis/ch08/#2020-06-1231869-0105227-1315759-0217701","text":"","title":"2020-06 1.231869 -0.105227 1.315759 0.217701"},{"location":"python/DataAnalysis/ch08/#2020-07-1447419-0263876-0342045-0768907","text":"","title":"2020-07 1.447419 0.263876 -0.342045 -0.768907"},{"location":"python/DataAnalysis/ch08/#2020-08-2567162-1008827-0391085-1259560","text":"","title":"2020-08 -2.567162 -1.008827 0.391085 1.259560"},{"location":"python/DataAnalysis/ch08/#2020-09-0772501-1183532-0450374-0450714","text":"","title":"2020-09 -0.772501 1.183532 0.450374 0.450714"},{"location":"python/DataAnalysis/ch08/#2020-10-0228974-0461224-1393178-0175243","text":"","title":"2020-10 0.228974 0.461224 1.393178 0.175243"},{"location":"python/DataAnalysis/ch08/#2020-11-0725193-1544131-1372029-0659224","text":"","title":"2020-11 -0.725193 -1.544131 1.372029 -0.659224"},{"location":"python/DataAnalysis/ch08/#2020-12-0718195-0862024-0166460-0940191","text":"","title":"2020-12 0.718195 0.862024 -0.166460 -0.940191"},{"location":"python/DataAnalysis/ch08/#2021-01-0617054-0887312-0338451-1392838","text":"","title":"2021-01 -0.617054 -0.887312 0.338451 -1.392838"},{"location":"python/DataAnalysis/ch08/#2021-02-0081140-0634730-0868051-1277167","text":"","title":"2021-02 -0.081140 0.634730 -0.868051 -1.277167"},{"location":"python/DataAnalysis/ch08/#2021-03-0999642-1959715-0930662-0748687","text":"","title":"2021-03 -0.999642 -1.959715 -0.930662 0.748687"},{"location":"python/DataAnalysis/ch08/#2021-04-1851453-1561669-0688822-0371255","text":"","title":"2021-04 1.851453 1.561669 -0.688822 -0.371255"},{"location":"python/DataAnalysis/ch08/#2021-05-0540777-0890403-1204188-0243480","text":"","title":"2021-05 -0.540777 -0.890403 -1.204188 0.243480"},{"location":"python/DataAnalysis/ch08/#2021-06-1318905-1247457-0518969-0799793","text":"","title":"2021-06 1.318905 1.247457 0.518969 0.799793"},{"location":"python/DataAnalysis/ch08/#2021-07-0223238-0747177-0410889-0904593","text":"","title":"2021-07 0.223238 0.747177 -0.410889 0.904593"},{"location":"python/DataAnalysis/ch08/#2021-08-0652551-0254351-0464604-0676923","text":"","title":"2021-08 -0.652551 -0.254351 -0.464604 -0.676923"},{"location":"python/DataAnalysis/ch08/#2021-09-0562312-0182099-0018617-0573331","text":"","title":"2021-09 0.562312 0.182099 0.018617 0.573331"},{"location":"python/DataAnalysis/ch08/#2021-10-0429490-0045959-0356292-0295776","text":"","title":"2021-10 0.429490 -0.045959 -0.356292 -0.295776"},{"location":"python/DataAnalysis/ch08/#2021-11-2552155-0801299-1378421-1232792","text":"","title":"2021-11 2.552155 0.801299 1.378421 1.232792"},{"location":"python/DataAnalysis/ch08/#2021-12-1102288-0850280-0767015-0519840","text":"df_annual = df.resample('A-DEC').mean() print(df_annual)","title":"2021-12 1.102288 0.850280 -0.767015 -0.519840"},{"location":"python/DataAnalysis/ch08/#colorado-texas-new-york-ohio_7","text":"","title":"Colorado Texas New York Ohio"},{"location":"python/DataAnalysis/ch08/#2020-0226807-0151561-0395793-0195259","text":"","title":"2020 0.226807 -0.151561 0.395793 0.195259"},{"location":"python/DataAnalysis/ch08/#2021-0429056-0165581-0286339-0002594","text":"\u5411\u4e0a\u91c7\u6837\u66f4\u4e3a\u7ec6\u81f4\uff0c\u56e0\u4e3a\u5fc5\u987b\u5728\u91cd\u65b0\u91c7\u6837\u524d\u51b3\u5b9a\u65b0\u9891\u7387\u4e2d\u5728\u65f6\u95f4\u6bb5\u7684\u54ea\u4e00\u7aef\u653e\u7f6e\u6570\u503c\uff0c\u5c31\u50cfasfreq\u65b9\u6cd5\u4e00\u6837\u3002 `convention`\u53c2\u6570\u9ed8\u8ba4\u503c\u662f`start`\uff0c\u4f46\u4e5f\u53ef\u4ee5\u662f`end`\uff1a result = df_annual.resample('Q-DEC').ffill() print(result)","title":"2021 0.429056 0.165581 -0.286339 -0.002594"},{"location":"python/DataAnalysis/ch08/#colorado-texas-new-york-ohio_8","text":"","title":"Colorado Texas New York Ohio"},{"location":"python/DataAnalysis/ch08/#2020q1-0226807-0151561-0395793-0195259","text":"","title":"2020Q1 0.226807 -0.151561 0.395793 0.195259"},{"location":"python/DataAnalysis/ch08/#2020q2-0226807-0151561-0395793-0195259","text":"","title":"2020Q2 0.226807 -0.151561 0.395793 0.195259"},{"location":"python/DataAnalysis/ch08/#2020q3-0226807-0151561-0395793-0195259","text":"","title":"2020Q3 0.226807 -0.151561 0.395793 0.195259"},{"location":"python/DataAnalysis/ch08/#2020q4-0226807-0151561-0395793-0195259","text":"","title":"2020Q4 0.226807 -0.151561 0.395793 0.195259"},{"location":"python/DataAnalysis/ch08/#2021q1-0429056-0165581-0286339-0002594","text":"","title":"2021Q1 0.429056 0.165581 -0.286339 -0.002594"},{"location":"python/DataAnalysis/ch08/#2021q2-0429056-0165581-0286339-0002594","text":"","title":"2021Q2 0.429056 0.165581 -0.286339 -0.002594"},{"location":"python/DataAnalysis/ch08/#2021q3-0429056-0165581-0286339-0002594","text":"","title":"2021Q3 0.429056 0.165581 -0.286339 -0.002594"},{"location":"python/DataAnalysis/ch08/#2021q4-0429056-0165581-0286339-0002594","text":"result = df_annual.resample('Q-DEC', convention='end').ffill() print(result)","title":"2021Q4 0.429056 0.165581 -0.286339 -0.002594"},{"location":"python/DataAnalysis/ch08/#colorado-texas-new-york-ohio_9","text":"","title":"Colorado Texas New York Ohio"},{"location":"python/DataAnalysis/ch08/#2020q4-0226807-0151561-0395793-0195259_1","text":"","title":"2020Q4 0.226807 -0.151561 0.395793 0.195259"},{"location":"python/DataAnalysis/ch08/#2021q1-0226807-0151561-0395793-0195259","text":"","title":"2021Q1 0.226807 -0.151561 0.395793 0.195259"},{"location":"python/DataAnalysis/ch08/#2021q2-0226807-0151561-0395793-0195259","text":"","title":"2021Q2 0.226807 -0.151561 0.395793 0.195259"},{"location":"python/DataAnalysis/ch08/#2021q3-0226807-0151561-0395793-0195259","text":"","title":"2021Q3 0.226807 -0.151561 0.395793 0.195259"},{"location":"python/DataAnalysis/ch08/#2021q4-0429056-0165581-0286339-0002594_1","text":"\u7531\u4e8e\u533a\u95f4\u6d89\u53ca\u65f6\u95f4\u8303\u56f4\uff0c\u5411\u4e0a\u91c7\u6837\u548c\u5411\u4e0b\u91c7\u6837\u5c31\u66f4\u4e3a\u4e25\u683c\uff1a * \u5728\u5411\u4e0b\u91c7\u6837\u4e2d\uff0c\u76ee\u6807\u9891\u7387\u5fc5\u987b\u662f\u539f\u9891\u7387\u7684\u5b50\u533a\u95f4\u3002 * \u5728\u5411\u4e0a\u91c7\u6837\u4e2d\uff0c\u76ee\u6807\u9891\u7387\u5fc5\u987b\u662f\u539f\u9891\u7387\u7684\u7236\u533a\u95f4\u3002 \u5982\u679c\u4e0d\u6ee1\u8db3\u8fd9\u4e9b\u89c4\u5219\uff0c\u5c06\u4f1a\u5f15\u8d77\u5f02\u5e38\u3002\u8fd9\u4e3b\u8981\u4f1a\u5f71\u54cd\u6bcf\u5b63\u5ea6\u3001\u6bcf\u5e74\u548c\u6bcf\u5468\u7684\u9891\u7387\u3002 \u4f8b\u5982\uff0c\u6839\u636eQ-MAR\u5b9a\u4e49\u7684\u65f6\u95f4\u8303\u56f4\u5c06\u53ea\u548cA-MAR\u3001A-JUN\u3001A-SEP\u548cA-DEC\u4fdd\u6301\u4e00\u81f4\uff1a result = df_annual.resample('Q-MAR').ffill() print(result)","title":"2021Q4 0.429056 0.165581 -0.286339 -0.002594"},{"location":"python/DataAnalysis/ch08/#colorado-texas-new-york-ohio_10","text":"","title":"Colorado Texas New York Ohio"},{"location":"python/DataAnalysis/ch08/#2020q4-0226807-0151561-0395793-0195259_2","text":"","title":"2020Q4 0.226807 -0.151561 0.395793 0.195259"},{"location":"python/DataAnalysis/ch08/#2021q1-0226807-0151561-0395793-0195259_1","text":"","title":"2021Q1 0.226807 -0.151561 0.395793 0.195259"},{"location":"python/DataAnalysis/ch08/#2021q2-0226807-0151561-0395793-0195259_1","text":"","title":"2021Q2 0.226807 -0.151561 0.395793 0.195259"},{"location":"python/DataAnalysis/ch08/#2021q3-0226807-0151561-0395793-0195259_1","text":"","title":"2021Q3 0.226807 -0.151561 0.395793 0.195259"},{"location":"python/DataAnalysis/ch08/#2021q4-0429056-0165581-0286339-0002594_2","text":"","title":"2021Q4 0.429056 0.165581 -0.286339 -0.002594"},{"location":"python/DataAnalysis/ch08/#2022q1-0429056-0165581-0286339-0002594","text":"","title":"2022Q1 0.429056 0.165581 -0.286339 -0.002594"},{"location":"python/DataAnalysis/ch08/#2022q2-0429056-0165581-0286339-0002594","text":"","title":"2022Q2 0.429056 0.165581 -0.286339 -0.002594"},{"location":"python/DataAnalysis/ch08/#2022q3-0429056-0165581-0286339-0002594","text":"## \u79fb\u52a8\u7a97\u53e3\u51fd\u6570 \u7edf\u8ba1\u90a3\u4e9b\u901a\u8fc7\u79fb\u52a8\u7a97\u53e3\u6216\u6307\u6570\u8870\u51cf\u800c\u8fd0\u884c\u7684\u51fd\u6570\uff0c\u662f\u7528\u4e8e\u65f6\u95f4\u5e8f\u5217\u64cd\u4f5c\u7684\u6570\u7ec4\u53d8\u6362\u7684\u4e00\u4e2a\u91cd\u8981\u7c7b\u522b\u3002 \u8fd9\u5bf9\u5e73\u6ed1\u566a\u58f0\u6216\u7c97\u7cd9\u7684\u6570\u636e\u975e\u5e38\u6709\u7528\u3002\u79f0\u8fd9\u4e9b\u51fd\u6570\u4e3a\u79fb\u52a8\u7a97\u53e3\u51fd\u6570\uff0c\u5c3d\u7ba1\u5b83\u4e5f\u5305\u542b\u4e86\u4e00\u4e9b\u6ca1\u6709\u56fa\u5b9a\u957f\u5ea6\u7a97\u53e3\u7684\u51fd\u6570\uff0c\u6bd4\u5982\u6307\u6570\u52a0\u6743\u79fb\u52a8\u5e73\u5747\u3002 \u4e0e\u5176\u4ed6\u7684\u7edf\u8ba1\u51fd\u6570\u7c7b\u4f3c\uff0c\u8fd9\u4e9b\u51fd\u6570\u4f1a\u81ea\u52a8\u6392\u9664\u7f3a\u5931\u6570\u636e\u3002 import matplotlib.pyplot as plt import pandas as pd from scipy.stats import percentileofscore import numpy as np from pandas.tseries.offsets import Hour, Minute, Day, MonthEnd import pytz \u5728\u6df1\u5165\u4e86\u89e3\u4e4b\u524d\uff0c\u6211\u4eec\u53ef\u4ee5\u5148\u8f7d\u5165\u4e00\u4e9b\u65f6\u95f4\u5e8f\u5217\u6570\u636e\u5e76\u6309\u7167\u5de5\u4f5c\u65e5\u9891\u7387\u8fdb\u884c\u91cd\u65b0\u91c7\u6837\uff1a close_px_all = pd.read_csv( '../examples/stock_px_2.csv', parse_dates = True, index_col=0 ) print(close_px_all.head(5))","title":"2022Q3 0.429056 0.165581 -0.286339 -0.002594"},{"location":"python/DataAnalysis/ch08/#aapl-msft-xom-spx","text":"","title":"AAPL MSFT XOM SPX"},{"location":"python/DataAnalysis/ch08/#2003-01-02-740-2111-2922-90903","text":"","title":"2003-01-02 7.40 21.11 29.22 909.03"},{"location":"python/DataAnalysis/ch08/#2003-01-03-745-2114-2924-90859","text":"","title":"2003-01-03 7.45 21.14 29.24 908.59"},{"location":"python/DataAnalysis/ch08/#2003-01-06-745-2152-2996-92901","text":"","title":"2003-01-06 7.45 21.52 29.96 929.01"},{"location":"python/DataAnalysis/ch08/#2003-01-07-743-2193-2895-92293","text":"","title":"2003-01-07 7.43 21.93 28.95 922.93"},{"location":"python/DataAnalysis/ch08/#2003-01-08-728-2131-2883-90993","text":"close_px = close_px_all[ ['AAPL', 'MSFT', 'XOM'] ] close_px = close_px.resample('B').ffill() print(close_px)","title":"2003-01-08 7.28 21.31 28.83 909.93"},{"location":"python/DataAnalysis/ch08/#aapl-msft-xom","text":"","title":"AAPL MSFT XOM"},{"location":"python/DataAnalysis/ch08/#2003-01-02-740-2111-2922","text":"","title":"2003-01-02 7.40 21.11 29.22"},{"location":"python/DataAnalysis/ch08/#2003-01-03-745-2114-2924","text":"","title":"2003-01-03 7.45 21.14 29.24"},{"location":"python/DataAnalysis/ch08/#_15","text":"","title":"... ... ... ..."},{"location":"python/DataAnalysis/ch08/#2011-10-13-40843-2718-7637","text":"","title":"2011-10-13 408.43 27.18 76.37"},{"location":"python/DataAnalysis/ch08/#2011-10-14-42200-2727-7811","text":"","title":"2011-10-14 422.00 27.27 78.11"},{"location":"python/DataAnalysis/ch08/#2292-rows-x-3-columns","text":"`rolling`\u7b97\u5b50\uff0c\u5b83\u7684\u884c\u4e3a\u4e0e`resample`\u548c`groupby`\u7c7b\u4f3c\u3002 `rolling`\u53ef\u4ee5\u5728Series\u6216DataFrame\u4e0a\u901a\u8fc7\u4e00\u4e2awindow\uff08\u4ee5\u4e00\u4e2a\u533a\u95f4\u7684\u6570\u5b57\u6765\u8868\u793a\uff09\u8fdb\u884c\u8c03\u7528\u3002 close_px.AAPL.plot() \u8868\u8fbe\u5f0f`rolling(250)`\u4e0e`groupby`\u7684\u884c\u4e3a\u7c7b\u4f3c\uff0c\u4f46\u662f\u5b83\u521b\u5efa\u7684\u5bf9\u8c61\u662f\u6839\u636e250\u65e5\u6ed1\u52a8\u7a97\u53e3\u5206\u7ec4\u7684\u800c\u4e0d\u662f\u76f4\u63a5\u5206\u7ec4\u3002 \u56e0\u6b64\u8fd9\u91cc\u6211\u4eec\u83b7\u5f97\u4e86\u82f9\u679c\u516c\u53f8\u80a1\u7968\u4ef7\u683c\u7684250\u65e5\u79fb\u52a8\u7a97\u53e3\u5e73\u5747\u503c\u3002 close_px.AAPL.rolling(250).mean().plot() plt.show() \u9ed8\u8ba4\u60c5\u51b5\u4e0b\uff0c\u6eda\u52a8\u51fd\u6570\u9700\u8981\u7a97\u53e3\u4e2d\u6240\u6709\u7684\u503c\u5fc5\u987b\u662f\u975e`NA`\u503c\u3002 \u7531\u4e8e\u5b58\u5728\u7f3a\u5931\u503c\u8fd9\u79cd\u884c\u4e3a\u4f1a\u53d1\u751f\u6539\u53d8\uff0c\u5c24\u5176\u662f\u5728\u65f6\u95f4\u5e8f\u5217\u7684\u8d77\u59cb\u4f4d\u7f6e\u4f60\u62e5\u6709\u7684\u6570\u636e\u662f\u5c11\u4e8e\u7a97\u53e3\u533a\u95f4\u7684 apple_std250 = close_px.AAPL.rolling(250, min_periods=10).std() # \u82f9\u679c\u516c\u53f8250\u65e5\u6bcf\u65e5\u8fd4\u56de\u6807\u51c6\u5dee print(apple_std250[5:12])","title":"[2292 rows x 3 columns]"},{"location":"python/DataAnalysis/ch08/#2003-01-09-nan","text":"","title":"2003-01-09 NaN"},{"location":"python/DataAnalysis/ch08/#2003-01-10-nan","text":"","title":"2003-01-10 NaN"},{"location":"python/DataAnalysis/ch08/#2003-01-13-nan","text":"","title":"2003-01-13 NaN"},{"location":"python/DataAnalysis/ch08/#2003-01-14-nan","text":"","title":"2003-01-14 NaN"},{"location":"python/DataAnalysis/ch08/#2003-01-15-0077496","text":"","title":"2003-01-15 0.077496"},{"location":"python/DataAnalysis/ch08/#2003-01-16-0074760","text":"","title":"2003-01-16 0.074760"},{"location":"python/DataAnalysis/ch08/#2003-01-17-0112368","text":"","title":"2003-01-17 0.112368"},{"location":"python/DataAnalysis/ch08/#freq-b-name-aapl-dtype-float64","text":"apple_std250.plot() plt.show() expanding_mean = apple_std250.expanding().mean() print(expanding_mean[5:12])","title":"Freq: B, Name: AAPL, dtype: float64"},{"location":"python/DataAnalysis/ch08/#2003-01-09-nan_1","text":"","title":"2003-01-09 NaN"},{"location":"python/DataAnalysis/ch08/#2003-01-10-nan_1","text":"","title":"2003-01-10 NaN"},{"location":"python/DataAnalysis/ch08/#2003-01-13-nan_1","text":"","title":"2003-01-13 NaN"},{"location":"python/DataAnalysis/ch08/#2003-01-14-nan_1","text":"","title":"2003-01-14 NaN"},{"location":"python/DataAnalysis/ch08/#2003-01-15-0077496_1","text":"","title":"2003-01-15 0.077496"},{"location":"python/DataAnalysis/ch08/#2003-01-16-0076128","text":"","title":"2003-01-16 0.076128"},{"location":"python/DataAnalysis/ch08/#2003-01-17-0088208","text":"","title":"2003-01-17 0.088208"},{"location":"python/DataAnalysis/ch08/#freq-b-name-aapl-dtype-float64_1","text":"expanding_mean.plot() plt.show() \u5728DataFrame\u4e0a\u8c03\u7528\u4e00\u4e2a\u79fb\u52a8\u7a97\u53e3\u51fd\u6570\u4f1a\u5c06\u53d8\u6362\u5e94\u7528\u5230\u6bcf\u4e00\u5217\u4e0a: close_px.rolling(60).mean().plot(logy=True) # \u80a1\u7968\u4ef7\u683c60\u65e5MA\uff08Y\u8f74\u53d6\u5bf9\u6570\uff09 plt.show() `rolling`\u51fd\u6570\u4e5f\u63a5\u6536\u8868\u793a\u56fa\u5b9a\u5927\u5c0f\u7684\u65f6\u95f4\u504f\u7f6e\u5b57\u7b26\u4e32\uff0c\u800c\u4e0d\u53ea\u662f\u4e00\u4e2a\u533a\u95f4\u7684\u96c6\u5408\u6570\u5b57\u3002 \u5bf9\u4e0d\u89c4\u5219\u65f6\u95f4\u5e8f\u5217\u4f7f\u7528\u6ce8\u91ca\u975e\u5e38\u6709\u7528\u3002\u8fd9\u4e9b\u5b57\u7b26\u4e32\u53ef\u4ee5\u4f20\u9012\u7ed9`resample`\u3002 \u4f8b\u5982\uff0c\u6211\u4eec\u53ef\u4ee5\u50cf\u8fd9\u6837\u8ba1\u7b9720\u5929\u7684\u6eda\u52a8\u5e73\u5747\u503c\uff1a result = close_px.rolling('20D').mean() print(result)","title":"Freq: B, Name: AAPL, dtype: float64"},{"location":"python/DataAnalysis/ch08/#aapl-msft-xom_1","text":"","title":"AAPL MSFT XOM"},{"location":"python/DataAnalysis/ch08/#2003-01-02-7400000-21110000-29220000","text":"","title":"2003-01-02 7.400000 21.110000 29.220000"},{"location":"python/DataAnalysis/ch08/#_16","text":"","title":"... ... ... ..."},{"location":"python/DataAnalysis/ch08/#2011-10-14-391038000-26048667-74185333","text":"","title":"2011-10-14 391.038000 26.048667 74.185333"},{"location":"python/DataAnalysis/ch08/#2292-rows-x-3-columns_1","text":"result.plot() plt.show() ### \u6307\u6570\u52a0\u6743\u51fd\u6570 \u6307\u5b9a\u4e00\u4e2a\u5e38\u6570\u8870\u51cf\u56e0\u5b50\u4ee5\u5411\u66f4\u591a\u8fd1\u671f\u89c2\u6d4b\u503c\u63d0\u4f9b\u66f4\u591a\u6743\u91cd\uff0c\u53ef\u4ee5\u66ff\u4ee3\u4f7f\u7528\u5177\u6709\u76f8\u7b49\u52a0\u6743\u89c2\u5bdf\u503c\u7684\u9759\u6001\u7a97\u53e3\u5c3a\u5bf8\u7684\u65b9\u6cd5\u3002 \u6709\u591a\u79cd\u65b9\u5f0f\u53ef\u4ee5\u6307\u5b9a\u8870\u51cf\u56e0\u5b50\u3002\u5176\u4e2d\u4e00\u79cd\u6d41\u884c\u7684\u65b9\u5f0f\u662f\u4f7f\u7528\u4e00\u4e2aspan\uff08\u8de8\u5ea6\uff09\uff0c\u8fd9\u4f7f\u5f97\u7ed3\u679c\u4e0e\u7a97\u53e3\u5927\u5c0f\u7b49\u4e8e\u8de8\u5ea6\u7684\u7b80\u5355\u79fb\u52a8\u7a97\u53e3\u51fd\u6570\u3002 \u7531\u4e8e\u6307\u6570\u52a0\u6743\u7edf\u8ba1\u503c\u7ed9\u66f4\u8fd1\u671f\u7684\u89c2\u6d4b\u503c\u4ee5\u66f4\u591a\u7684\u6743\u91cd\uff0c\u4e0e\u7b49\u6743\u91cd\u7684\u7248\u672c\u76f8\u6bd4\uff0c\u5b83\u5bf9\u53d8\u5316\u201c\u9002\u5e94\u201d\u5f97\u66f4\u5feb\u3002 pandas\u62e5\u6709`ewm`\u7b97\u5b50\uff0c\u540c`rolling`\u3001`expanding`\u7b97\u5b50\u4e00\u8d77\u4f7f\u7528\u3002 \u4ee5\u4e0b\u662f\u5c06\u82f9\u679c\u516c\u53f8\u80a1\u7968\u4ef7\u683c\u768460\u65e5\u5747\u7ebf\u4e0e`span=60`\u7684EW\u79fb\u52a8\u5e73\u5747\u7ebf\u8fdb\u884c\u6bd4\u8f83\u7684\u4f8b\u5b50\uff1a aapl_ex = close_px.AAPL['2006':'2007'] ma60 = aapl_ex.rolling(30, min_periods=20).mean() ewma60 = aapl_ex.ewm(span=30).mean() ma60.plot(style='k--', label='Simple MA') ewma60.plot(style='k-', label='EWMA') plt.legend() plt.show() ### \u4e8c\u5143\u79fb\u52a8\u7a97\u53e3\u51fd\u6570 \u4e00\u4e9b\u7edf\u8ba1\u7b97\u5b50\uff0c\u4f8b\u5982\u76f8\u5173\u5ea6\u548c\u534f\u65b9\u5dee\uff0c\u9700\u8981\u64cd\u4f5c\u4e24\u4e2a\u65f6\u95f4\u5e8f\u5217\u3002 \u4f8b\u5982\uff0c\u91d1\u878d\u5206\u6790\u5e08\u7ecf\u5e38\u5bf9\u80a1\u7968\u4e0e\u57fa\u51c6\u6307\u6570\uff08\u5982\u6807\u666e500\uff09\u7684\u5173\u8054\u6027\u611f\u5174\u8da3\u3002 \u6211\u4eec\u9996\u5148\u8ba1\u7b97\u6240\u6709\u6211\u4eec\u611f\u5174\u8da3\u7684\u65f6\u95f4\u5e8f\u5217\u7684\u767e\u5206\u6bd4\u53d8\u5316\uff1a spx_px = close_px_all['SPX'] spx_rets = spx_px.pct_change() returns = close_px.pct_change()","title":"[2292 rows x 3 columns]"},{"location":"python/DataAnalysis/ch08/#rollingcorrspx_rets","text":"corr = returns.AAPL.rolling(125, min_periods=100).corr(spx_rets) # \u82f9\u679c\u516c\u53f8\u4e0e\u6807\u666e500\u7684\u516d\u4e2a\u6708\u7684\u6536\u76ca\u76f8\u5173\u6027 corr.plot() plt.show() corr = returns.rolling(125, min_periods=100).corr(spx_rets) # \u591a\u53ea\u80a1\u7968\u4e0e\u6807\u666e500\u7684\u516d\u4e2a\u6708\u6536\u76ca\u76f8\u5173\u6027 corr.plot() plt.show() ### \u7528\u6237\u81ea\u5b9a\u4e49\u7684\u79fb\u52a8\u7a97\u53e3\u51fd\u6570 \u5728`rolling`\u53ca\u5176\u76f8\u5173\u65b9\u6cd5\u4e0a\u4f7f\u7528apply\u65b9\u6cd5\u63d0\u4f9b\u4e86\u4e00\u79cd\u5728\u79fb\u52a8\u7a97\u53e3\u4e2d\u5e94\u7528\u4f60\u81ea\u5df1\u8bbe\u8ba1\u7684\u6570\u7ec4\u51fd\u6570\u7684\u65b9\u6cd5\u3002 \u552f\u4e00\u7684\u8981\u6c42\u662f\u8be5\u51fd\u6570\u4ece\u6bcf\u4e2a\u6570\u7ec4\u4e2d\u4ea7\u751f\u4e00\u4e2a\u5355\u503c\uff08\u7f29\u805a\uff09\u3002 \u4f8b\u5982\uff0c\u5c3d\u7ba1\u6211\u4eec\u53ef\u4ee5\u4f7f\u7528`rolling(...).quantile(q)`\u8ba1\u7b97\u6837\u672c\u7684\u5206\u4f4d\u6570\uff0c\u4f46\u6211\u4eec\u53ef\u80fd\u4f1a\u5bf9\u6837\u672c\u4e2d\u7279\u5b9a\u503c\u7684\u767e\u5206\u4f4d\u6570\u611f\u5174\u8da3\u3002 `scipy.stats.percentileofscore`\u51fd\u6570\u5c31\u662f\u5b9e\u73b0\u8fd9\u4e2a\u529f\u80fd\u7684\uff1a score_at_2percent = lambda x: percentileofscore(x, 0.02) result = returns.AAPL.rolling(250).apply(score_at_2percent) # \u4e00\u5e74\u7a97\u53e3\u4e0b\u82f9\u679c\u516c\u53f8\u80a1\u4ef72%\u6536\u76ca\u7684\u767e\u5206\u4f4d\u7b49\u7ea7 result.plot() plt.show() result = returns.rolling(250).apply(score_at_2percent) # \u4e00\u5e74\u7a97\u53e3\u4e0b\u6240\u6709\u516c\u53f8\u80a1\u4ef72%\u6536\u76ca\u7684\u767e\u5206\u4f4d\u7b49\u7ea7 result.plot() plt.show() ```","title":"\u5728\u8c03\u7528rolling\u540e\uff0ccorr\u805a\u5408\u51fd\u6570\u53ef\u4ee5\u6839\u636espx_rets\u8ba1\u7b97\u6eda\u52a8\u76f8\u5173\u6027\uff1a"},{"location":"python/DataAnalysis/ch09/","text":"\u9ad8\u9636pandas \u00b6 \u5206\u7c7b\u6570\u636e \u00b6 import numpy as np import pandas as pd \u80cc\u666f\u548c\u76ee\u6807 \u00b6 \u4e00\u4e2a\u5217\u7ecf\u5e38\u4f1a\u5305\u542b\u91cd\u590d\u503c\uff0c\u8fd9\u4e9b\u91cd\u590d\u503c\u662f\u4e00\u4e2a\u5c0f\u578b\u7684\u4e0d\u540c\u503c\u7684\u96c6\u5408\u3002 unique \u548c value_counts \u8fd9\u6837\u7684\u51fd\u6570\u5141\u8bb8\u6211\u4eec\u4ece\u4e00\u4e2a\u6570\u7ec4\u4e2d\u63d0\u53d6\u4e0d\u540c\u503c\u5e76\u5206\u522b\u8ba1\u7b97\u8fd9\u4e9b\u4e0d\u540c\u503c\u7684\u9891\u7387\uff1a values = pd.Series(['apple', 'orange', 'apple', 'apple'] * 2) print(values) # 0 apple # 1 orange # 2 apple # 3 apple # 4 apple # 5 orange # 6 apple # 7 apple # dtype: object print(pd.unique(values)) # ['apple' 'orange'] print(pd.value_counts(values)) # apple 6 # orange 2 # dtype: int64 \u5728\u6570\u636e\u5165\u5e93\u7684\u64cd\u4f5c\u4e2d\uff0c\u4f7f\u7528\u7ef4\u5ea6\u8868\u662f\u4e00\u79cd\u6700\u4f73\u5b9e\u8df5\uff0c\u7ef4\u5ea6\u8868\u5305\u542b\u4e86\u4e0d\u540c\u503c\uff0c\u5e76\u5c06\u4e3b\u8981\u89c2\u6d4b\u503c\u5b58\u50a8\u4e3a\u5f15\u7528\u7ef4\u5ea6\u8868\u7684\u6574\u6570\u952e\uff1a values = pd.Series([0, 1, 0, 0] * 2) dim = pd.Series(['apple', 'oragne']) \u4f7f\u7528 take \u65b9\u6cd5\u6765\u6062\u590d\u539f\u6765\u7684\u5b57\u7b26\u4e32Series\u3002\uff080\u5bf9\u5e94\u5230apple)\u3002 \u8fd9\u79cd\u6309\u7167\u6574\u6570\u5c55\u73b0\u7684\u65b9\u5f0f\u88ab\u79f0\u4e3a\u5206\u7c7b\u6216\u5b57\u5178\u7f16\u7801\u5c55\u73b0\u3002\u4e0d\u540c\u503c\u7684\u6570\u7ec4\u53ef\u4ee5\u88ab\u79f0\u4e3a\u6570\u636e\u7684\u7c7b\u522b\u3001\u5b57\u5178\u6216\u5c42\u7ea7\u3002 print(dim.take(values)) # 0 apple # 1 oragne # 0 apple # 0 apple # 0 apple # 1 oragne # 0 apple # 0 apple # dtype: object \u5728\u505a\u6570\u636e\u5206\u6790\u65f6\uff0c\u5206\u7c7b\u5c55\u793a\u4f1a\u4ea7\u751f\u663e\u8457\u7684\u6027\u80fd\u63d0\u5347\u3002\u53ef\u4ee5\u5728\u7c7b\u522b\u4e0a\u8fdb\u884c\u8f6c\u6362\u540c\u65f6\u4e0d\u6539\u53d8\u4ee3\u7801\u3002 \u4ee5\u4e0b\u662f\u4e00\u4e9b\u76f8\u5bf9\u4f4e\u5f00\u9500\u7684\u8f6c\u6362\u793a\u4f8b\uff1a \u91cd\u547d\u540d\u7c7b\u522b \u5728\u4e0d\u6539\u53d8\u5df2\u6709\u7684\u7c7b\u522b\u987a\u5e8f\u7684\u60c5\u51b5\u4e0b\u6dfb\u52a0\u4e00\u4e2a\u65b0\u7684\u7c7b\u522b pandas\u4e2d\u7684Categorical\u7c7b\u578b \u00b6 pandas\u62e5\u6709\u7279\u6b8a\u7684 Categorical \u7c7b\u578b\uff0c\u7528\u4e8e\u627f\u8f7d\u57fa\u4e8e\u6574\u6570\u7684\u7c7b\u522b\u5c55\u793a\u6216\u7f16\u7801\u7684\u6570\u636e\u3002 fruits = ['apple', 'orange', 'apple', 'apple'] * 2 N = len(fruits) df = pd.DataFrame( { 'fruit': fruits, 'basket_id': np.arange(N), 'count': np.random.randint(3, 15, size=N), 'weight': np.random.uniform(0, 4, size=N) }, columns=['basket_id', 'fruit', 'count', 'weight'] ) print(df) # basket_id fruit count weight # 0 0 apple 8 1.288867 # 1 1 orange 4 3.414430 # 2 2 apple 7 3.222160 # 3 3 apple 14 2.724804 # 4 4 apple 8 3.548828 # 5 5 orange 10 0.918739 # 6 6 apple 4 0.784816 # 7 7 apple 10 3.140607 df['fruit'] \u662f\u4e00\u4e2aPython\u5b57\u7b26\u4e32\u5bf9\u8c61\u7ec4\u6210\u7684\u6570\u7ec4\u3002\u53ef\u4ee5\u901a\u8fc7\u8c03\u7528\u51fd\u6570\u5c06\u5b83\u8f6c\u6362\u4e3a Categorical \u5bf9\u8c61\uff1a fruit_cat = df['fruit'].astype('category') print(fruit_cat) # 0 apple # 1 orange # 2 apple # 3 apple # 4 apple # 5 orange # 6 apple # 7 apple # Name: fruit, dtype: category # Categories (2, object): ['apple', 'orange'] fruit_cat \u7684\u503c\u5e76\u4e0d\u662fNumPy\u6570\u7ec4\uff0c\u800c\u662f pandas.Categorical \u7684\u5b9e\u4f8b\uff1a c = fruit_cat.values print(type(c)) # print(c) # ['apple', 'orange', 'apple', 'apple', 'apple', 'orange', 'apple', 'apple'] # Categories (2, object): ['apple', 'orange'] Categorical \u5bf9\u8c61\u62e5\u6709 categories \u548c codes \u5c5e\u6027\uff1a print(c.categories) # Index(['apple', 'orange'], dtype='object') print(c.codes) # [0 1 0 0 0 1 0 0] \u901a\u8fc7\u5206\u914d\u5df2\u8f6c\u6362\u7684\u7ed3\u679c\u5c06DataFrame\u7684\u4e00\u5217\u8f6c\u6362\u4e3a Categorical \u5bf9\u8c61\uff1a print(df['fruit']) # 0 apple # 1 orange # 2 apple # 3 apple # 4 apple # 5 orange # 6 apple # 7 apple # Name: fruit, dtype: object df['fruit'] = df['fruit'].astype('category') print(df['fruit']) # 0 apple # 1 orange # 2 apple # 3 apple # 4 apple # 5 orange # 6 apple # 7 apple # Name: fruit, dtype: category # Categories (2, object): ['apple', 'orange'] \u4e5f\u53ef\u4ee5\u4ece\u5176\u4ed6Python\u5e8f\u5217\u7c7b\u578b\u76f4\u63a5\u751f\u6210 pandas.Categorical \uff1a my_categories = pd.Categorical(['foo', 'bar', 'baz', 'foo', 'bar']) print(my_categories) # ['foo', 'bar', 'baz', 'foo', 'bar'] # Categories (3, object): ['bar', 'baz', 'foo'] \u4e5f\u53ef\u4ee5\u4f7f\u7528 from_codes \u6784\u9020\u51fd\u6570\u6765\u8f6c\u6362\u5176\u4ed6\u6570\u636e\u6e90\u7684\u5206\u7c7b\u7f16\u7801\u6570\u636e\uff1a categories = ['foo', 'bar', 'baz'] codes = [0, 1, 2, 0, 0, 1] my_cats_2 = pd.Categorical.from_codes(codes, categories) print(my_cats_2) # ['foo', 'bar', 'baz', 'foo', 'foo', 'bar'] # Categories (3, object): ['foo', 'bar', 'baz'] \u8fd9\u4e2a\u672a\u6392\u5e8f\u7684\u5206\u7c7b\u5b9e\u4f8b\u53ef\u4ee5\u4f7f\u7528 as_ordered \u8fdb\u884c\u6392\u5e8f\uff1a print(my_cats_2.as_ordered()) # ['foo', 'bar', 'baz', 'foo', 'foo', 'bar'] # Categories (3, object): ['foo' < 'bar' < 'baz'] \u9664\u975e\u663e\u5f0f\u5730\u6307\u5b9a\uff0c\u5206\u7c7b\u8f6c\u6362\u662f\u4e0d\u4f1a\u6307\u5b9a\u7c7b\u522b\u7684\u987a\u5e8f\u7684\u3002\u56e0\u6b64 categories \u6570\u7ec4\u53ef\u80fd\u4f1a\u4e0e\u8f93\u5165\u6570\u636e\u7684\u987a\u5e8f\u4e0d\u540c\u3002 \u5f53\u4f7f\u7528 from_codes \u6216\u5176\u4ed6\u4efb\u610f\u6784\u9020\u51fd\u6570\u65f6\uff0c\u53ef\u4ee5\u4e3a\u7c7b\u522b\u6307\u5b9a\u4e00\u4e2a\u6709\u610f\u4e49\u7684\u987a\u5e8f\uff1a\u8f93\u51fa\u7684 [foo df.pipe(len) # \u4f20\u9012\u7684\u662flen\u5b9e\u4f8b # 4 def fun(df): return df * 2 fun(df) # 0 1 2 # 0 2.0 4.0 6.0 # 1 2.0 NaN NaN # 2 NaN NaN NaN # 3 NaN 4.0 6.0 df.pipe(fun) # \u4f20\u9012\u7684\u662ffun\u51fd\u6570 # 0 1 2 # 0 2.0 4.0 6.0 # 1 2.0 NaN NaN # 2 NaN NaN NaN # 3 NaN 4.0 6.0 def fun2(x, df): # \u6570\u636e\u662f\u7b2c\u4e8c\u4e2a\u53c2\u6570 return df * 3 df.pipe((fun2, 'df'), 2) # \u6ce8\u610f\u4f20\u503c # 0 1 2 # 0 3.0 6.0 9.0 # 1 3.0 NaN NaN # 2 NaN NaN NaN # 3 NaN 6.0 9.0 Series \u793a\u4f8b\uff1a \u00b6 s = pd.Series([1, 2, 3, 4, 5]) s.pipe(type) # s.pipe(len) # 5 def fun3(x, ss): return ss * 3 s.pipe((fun3, 'ss'), 2) # 0 3 # 1 6 # 2 9 # 3 12 # 4 15 # dtype: int64 GroupBy \u793a\u4f8b\uff1a \u00b6 df = pd.DataFrame({'A': 'a b a b'.split(), 'B': [1, 2, 3, 4]}) print(df) # A B # 0 a 1 # 1 b 2 # 2 a 3 # 3 b 4 \u6c42\u6bcf\u7ec4\u6700\u5927\u503c\u548c\u6700\u5c0f\u503c\u4e4b\u95f4\u7684\u5dee\u5f02\u3002 df.groupby('A').pipe(lambda x: x.max() - x.min()) # B # A # a 2 # b 2 def mean1(groupby): return groupby.mean() df.groupby(['A']).pipe(mean1) # B # A # a 2.0 # b 3.0","title":"\u9ad8\u9636pandas"},{"location":"python/DataAnalysis/ch09/#pandas","text":"","title":"\u9ad8\u9636pandas"},{"location":"python/DataAnalysis/ch09/#_1","text":"import numpy as np import pandas as pd","title":"\u5206\u7c7b\u6570\u636e"},{"location":"python/DataAnalysis/ch09/#_2","text":"\u4e00\u4e2a\u5217\u7ecf\u5e38\u4f1a\u5305\u542b\u91cd\u590d\u503c\uff0c\u8fd9\u4e9b\u91cd\u590d\u503c\u662f\u4e00\u4e2a\u5c0f\u578b\u7684\u4e0d\u540c\u503c\u7684\u96c6\u5408\u3002 unique \u548c value_counts \u8fd9\u6837\u7684\u51fd\u6570\u5141\u8bb8\u6211\u4eec\u4ece\u4e00\u4e2a\u6570\u7ec4\u4e2d\u63d0\u53d6\u4e0d\u540c\u503c\u5e76\u5206\u522b\u8ba1\u7b97\u8fd9\u4e9b\u4e0d\u540c\u503c\u7684\u9891\u7387\uff1a values = pd.Series(['apple', 'orange', 'apple', 'apple'] * 2) print(values) # 0 apple # 1 orange # 2 apple # 3 apple # 4 apple # 5 orange # 6 apple # 7 apple # dtype: object print(pd.unique(values)) # ['apple' 'orange'] print(pd.value_counts(values)) # apple 6 # orange 2 # dtype: int64 \u5728\u6570\u636e\u5165\u5e93\u7684\u64cd\u4f5c\u4e2d\uff0c\u4f7f\u7528\u7ef4\u5ea6\u8868\u662f\u4e00\u79cd\u6700\u4f73\u5b9e\u8df5\uff0c\u7ef4\u5ea6\u8868\u5305\u542b\u4e86\u4e0d\u540c\u503c\uff0c\u5e76\u5c06\u4e3b\u8981\u89c2\u6d4b\u503c\u5b58\u50a8\u4e3a\u5f15\u7528\u7ef4\u5ea6\u8868\u7684\u6574\u6570\u952e\uff1a values = pd.Series([0, 1, 0, 0] * 2) dim = pd.Series(['apple', 'oragne']) \u4f7f\u7528 take \u65b9\u6cd5\u6765\u6062\u590d\u539f\u6765\u7684\u5b57\u7b26\u4e32Series\u3002\uff080\u5bf9\u5e94\u5230apple)\u3002 \u8fd9\u79cd\u6309\u7167\u6574\u6570\u5c55\u73b0\u7684\u65b9\u5f0f\u88ab\u79f0\u4e3a\u5206\u7c7b\u6216\u5b57\u5178\u7f16\u7801\u5c55\u73b0\u3002\u4e0d\u540c\u503c\u7684\u6570\u7ec4\u53ef\u4ee5\u88ab\u79f0\u4e3a\u6570\u636e\u7684\u7c7b\u522b\u3001\u5b57\u5178\u6216\u5c42\u7ea7\u3002 print(dim.take(values)) # 0 apple # 1 oragne # 0 apple # 0 apple # 0 apple # 1 oragne # 0 apple # 0 apple # dtype: object \u5728\u505a\u6570\u636e\u5206\u6790\u65f6\uff0c\u5206\u7c7b\u5c55\u793a\u4f1a\u4ea7\u751f\u663e\u8457\u7684\u6027\u80fd\u63d0\u5347\u3002\u53ef\u4ee5\u5728\u7c7b\u522b\u4e0a\u8fdb\u884c\u8f6c\u6362\u540c\u65f6\u4e0d\u6539\u53d8\u4ee3\u7801\u3002 \u4ee5\u4e0b\u662f\u4e00\u4e9b\u76f8\u5bf9\u4f4e\u5f00\u9500\u7684\u8f6c\u6362\u793a\u4f8b\uff1a \u91cd\u547d\u540d\u7c7b\u522b \u5728\u4e0d\u6539\u53d8\u5df2\u6709\u7684\u7c7b\u522b\u987a\u5e8f\u7684\u60c5\u51b5\u4e0b\u6dfb\u52a0\u4e00\u4e2a\u65b0\u7684\u7c7b\u522b","title":"\u80cc\u666f\u548c\u76ee\u6807"},{"location":"python/DataAnalysis/ch09/#pandascategorical","text":"pandas\u62e5\u6709\u7279\u6b8a\u7684 Categorical \u7c7b\u578b\uff0c\u7528\u4e8e\u627f\u8f7d\u57fa\u4e8e\u6574\u6570\u7684\u7c7b\u522b\u5c55\u793a\u6216\u7f16\u7801\u7684\u6570\u636e\u3002 fruits = ['apple', 'orange', 'apple', 'apple'] * 2 N = len(fruits) df = pd.DataFrame( { 'fruit': fruits, 'basket_id': np.arange(N), 'count': np.random.randint(3, 15, size=N), 'weight': np.random.uniform(0, 4, size=N) }, columns=['basket_id', 'fruit', 'count', 'weight'] ) print(df) # basket_id fruit count weight # 0 0 apple 8 1.288867 # 1 1 orange 4 3.414430 # 2 2 apple 7 3.222160 # 3 3 apple 14 2.724804 # 4 4 apple 8 3.548828 # 5 5 orange 10 0.918739 # 6 6 apple 4 0.784816 # 7 7 apple 10 3.140607 df['fruit'] \u662f\u4e00\u4e2aPython\u5b57\u7b26\u4e32\u5bf9\u8c61\u7ec4\u6210\u7684\u6570\u7ec4\u3002\u53ef\u4ee5\u901a\u8fc7\u8c03\u7528\u51fd\u6570\u5c06\u5b83\u8f6c\u6362\u4e3a Categorical \u5bf9\u8c61\uff1a fruit_cat = df['fruit'].astype('category') print(fruit_cat) # 0 apple # 1 orange # 2 apple # 3 apple # 4 apple # 5 orange # 6 apple # 7 apple # Name: fruit, dtype: category # Categories (2, object): ['apple', 'orange'] fruit_cat \u7684\u503c\u5e76\u4e0d\u662fNumPy\u6570\u7ec4\uff0c\u800c\u662f pandas.Categorical \u7684\u5b9e\u4f8b\uff1a c = fruit_cat.values print(type(c)) # print(c) # ['apple', 'orange', 'apple', 'apple', 'apple', 'orange', 'apple', 'apple'] # Categories (2, object): ['apple', 'orange'] Categorical \u5bf9\u8c61\u62e5\u6709 categories \u548c codes \u5c5e\u6027\uff1a print(c.categories) # Index(['apple', 'orange'], dtype='object') print(c.codes) # [0 1 0 0 0 1 0 0] \u901a\u8fc7\u5206\u914d\u5df2\u8f6c\u6362\u7684\u7ed3\u679c\u5c06DataFrame\u7684\u4e00\u5217\u8f6c\u6362\u4e3a Categorical \u5bf9\u8c61\uff1a print(df['fruit']) # 0 apple # 1 orange # 2 apple # 3 apple # 4 apple # 5 orange # 6 apple # 7 apple # Name: fruit, dtype: object df['fruit'] = df['fruit'].astype('category') print(df['fruit']) # 0 apple # 1 orange # 2 apple # 3 apple # 4 apple # 5 orange # 6 apple # 7 apple # Name: fruit, dtype: category # Categories (2, object): ['apple', 'orange'] \u4e5f\u53ef\u4ee5\u4ece\u5176\u4ed6Python\u5e8f\u5217\u7c7b\u578b\u76f4\u63a5\u751f\u6210 pandas.Categorical \uff1a my_categories = pd.Categorical(['foo', 'bar', 'baz', 'foo', 'bar']) print(my_categories) # ['foo', 'bar', 'baz', 'foo', 'bar'] # Categories (3, object): ['bar', 'baz', 'foo'] \u4e5f\u53ef\u4ee5\u4f7f\u7528 from_codes \u6784\u9020\u51fd\u6570\u6765\u8f6c\u6362\u5176\u4ed6\u6570\u636e\u6e90\u7684\u5206\u7c7b\u7f16\u7801\u6570\u636e\uff1a categories = ['foo', 'bar', 'baz'] codes = [0, 1, 2, 0, 0, 1] my_cats_2 = pd.Categorical.from_codes(codes, categories) print(my_cats_2) # ['foo', 'bar', 'baz', 'foo', 'foo', 'bar'] # Categories (3, object): ['foo', 'bar', 'baz'] \u8fd9\u4e2a\u672a\u6392\u5e8f\u7684\u5206\u7c7b\u5b9e\u4f8b\u53ef\u4ee5\u4f7f\u7528 as_ordered \u8fdb\u884c\u6392\u5e8f\uff1a print(my_cats_2.as_ordered()) # ['foo', 'bar', 'baz', 'foo', 'foo', 'bar'] # Categories (3, object): ['foo' < 'bar' < 'baz'] \u9664\u975e\u663e\u5f0f\u5730\u6307\u5b9a\uff0c\u5206\u7c7b\u8f6c\u6362\u662f\u4e0d\u4f1a\u6307\u5b9a\u7c7b\u522b\u7684\u987a\u5e8f\u7684\u3002\u56e0\u6b64 categories \u6570\u7ec4\u53ef\u80fd\u4f1a\u4e0e\u8f93\u5165\u6570\u636e\u7684\u987a\u5e8f\u4e0d\u540c\u3002 \u5f53\u4f7f\u7528 from_codes \u6216\u5176\u4ed6\u4efb\u610f\u6784\u9020\u51fd\u6570\u65f6\uff0c\u53ef\u4ee5\u4e3a\u7c7b\u522b\u6307\u5b9a\u4e00\u4e2a\u6709\u610f\u4e49\u7684\u987a\u5e8f\uff1a\u8f93\u51fa\u7684 [foo df.pipe(len) # \u4f20\u9012\u7684\u662flen\u5b9e\u4f8b # 4 def fun(df): return df * 2 fun(df) # 0 1 2 # 0 2.0 4.0 6.0 # 1 2.0 NaN NaN # 2 NaN NaN NaN # 3 NaN 4.0 6.0 df.pipe(fun) # \u4f20\u9012\u7684\u662ffun\u51fd\u6570 # 0 1 2 # 0 2.0 4.0 6.0 # 1 2.0 NaN NaN # 2 NaN NaN NaN # 3 NaN 4.0 6.0 def fun2(x, df): # \u6570\u636e\u662f\u7b2c\u4e8c\u4e2a\u53c2\u6570 return df * 3 df.pipe((fun2, 'df'), 2) # \u6ce8\u610f\u4f20\u503c # 0 1 2 # 0 3.0 6.0 9.0 # 1 3.0 NaN NaN # 2 NaN NaN NaN # 3 NaN 6.0 9.0","title":"DataFrame\u793a\u4f8b\uff1a"},{"location":"python/DataAnalysis/ch09/#series","text":"s = pd.Series([1, 2, 3, 4, 5]) s.pipe(type) # s.pipe(len) # 5 def fun3(x, ss): return ss * 3 s.pipe((fun3, 'ss'), 2) # 0 3 # 1 6 # 2 9 # 3 12 # 4 15 # dtype: int64","title":"Series \u793a\u4f8b\uff1a"},{"location":"python/DataAnalysis/ch09/#groupby_2","text":"df = pd.DataFrame({'A': 'a b a b'.split(), 'B': [1, 2, 3, 4]}) print(df) # A B # 0 a 1 # 1 b 2 # 2 a 3 # 3 b 4 \u6c42\u6bcf\u7ec4\u6700\u5927\u503c\u548c\u6700\u5c0f\u503c\u4e4b\u95f4\u7684\u5dee\u5f02\u3002 df.groupby('A').pipe(lambda x: x.max() - x.min()) # B # A # a 2 # b 2 def mean1(groupby): return groupby.mean() df.groupby(['A']).pipe(mean1) # B # A # a 2.0 # b 3.0","title":"GroupBy \u793a\u4f8b\uff1a"},{"location":"python/DataAnalysis/ch10/","text":"NumPy\u8fdb\u9636 \u00b6 \u5305\u542b\u4ee5\u4e0b\u5185\u5bb9\uff1a ndarray\u5bf9\u8c61\u7684\u5185\u90e8\u673a\u7406 \u9ad8\u7ea7\u6570\u7ec4\u64cd\u4f5c \u91cd\u5851\u6570\u7ec4 C\u987a\u5e8f\u548cF\u987a\u5e8f \u8fde\u63a5\u548c\u5206\u9694\u6570\u7ec4 \u5806\u53e0\u52a9\u624b\uff1ar \u548cc \u91cd\u590d\u5143\u7d20\uff1atile\u548crepeat \u795e\u5947\u7d22\u5f15\u7684\u7b49\u4ef7\u65b9\u6cd5\uff1atake\u548cput \u5e7f\u64ad ufunc\u9ad8\u7ea7\u5e94\u7528 \u7ed3\u6784\u5316\u548c\u8bb0\u5f55\u5f0f\u6570\u7ec4 ndarray\u5bf9\u8c61\u7684\u5185\u90e8\u673a\u7406 \u00b6 NumPy\u7684 ndarray \u63d0\u4f9b\u4e86\u4e00\u79cd\u5c06\u540c\u8d28\u6570\u636e\u5757\uff08\u53ef\u4ee5\u662f\u8fde\u7eed\u6216\u8de8\u8d8a\uff09\u89e3\u91ca\u4e3a\u591a\u7ef4\u6570\u7ec4\u5bf9\u8c61\u7684\u65b9\u5f0f\u3002 ndarray \u7684\u6570\u636e\u7c7b\u578b dtype \u51b3\u5b9a\u4e86\u6570\u636e\u7684\u89e3\u91ca\u65b9\u5f0f\uff0c\u6bd4\u5982\u6d6e\u70b9\u6570\u3001\u6574\u6570\u3001\u5e03\u5c14\u503c\u7b49\u3002 ndarray \u7684\u6240\u6709\u6570\u7ec4\u5bf9\u8c61\u90fd\u662f\u6570\u636e\u5757\u7684\u4e00\u4e2a\u8de8\u5ea6\u89c6\u56fe\uff08strided view\uff09\u3002 \u6570\u7ec4\u89c6\u56fe arr[::2,::-1] \u4e0d\u590d\u5236\u4efb\u4f55\u6570\u636e\u7684\u539f\u56e0\u662f\u4ec0\u4e48\uff1f \u7b80\u5355\u5730\u8bf4\uff0c ndarray \u4e0d\u53ea\u662f\u4e00\u5757\u5185\u5b58\u548c\u4e00\u4e2a dtype \uff0c\u5b83\u8fd8\u6709\u8de8\u5ea6\u4fe1\u606f\uff0c\u8fd9\u4f7f\u5f97\u6570\u7ec4\u80fd\u4ee5\u5404\u79cd\u6b65\u5e45\uff08step size\uff09\u5728\u5185\u5b58\u4e2d\u79fb\u52a8\u3002 \u66f4\u51c6\u786e\u5730\u8bb2\uff0c ndarray \u5185\u90e8\u7531\u4ee5\u4e0b\u5185\u5bb9\u7ec4\u6210\uff1a \u4e00\u4e2a\u6307\u5411\u6570\u636e\uff08\u5185\u5b58\u6216\u5185\u5b58\u6620\u5c04\u6587\u4ef6\u4e2d\u7684\u4e00\u5757\u6570\u636e\uff09\u7684\u6307\u9488\u3002 \u6570\u636e\u7c7b\u578b\u6216 dtype \uff0c\u63cf\u8ff0\u5728\u6570\u7ec4\u4e2d\u7684\u56fa\u5b9a\u5927\u5c0f\u503c\u7684\u683c\u5b50\u3002 \u4e00\u4e2a\u8868\u793a\u6570\u7ec4\u5f62\u72b6\uff08shape\uff09\u7684\u5143\u7ec4\u3002 \u4e00\u4e2a\u8de8\u5ea6\u5143\u7ec4\uff08stride\uff09\uff0c\u5176\u4e2d\u7684\u6574\u6570\u6307\u7684\u662f\u4e3a\u4e86\u524d\u8fdb\u5230\u5f53\u524d\u7ef4\u5ea6\u4e0b\u4e00\u4e2a\u5143\u7d20\u9700\u8981\u201c\u8de8\u8fc7\u201d\u7684\u5b57\u8282\u6570\u3002 \u4f8b\u5982\uff0c\u4e00\u4e2a10\u00d75\u7684\u6570\u7ec4\uff0c\u5176shape\u4e3a(10, 5)\uff1a s = np.ones((10, 5)).shape print(s) # (10, 5) \u4e00\u4e2a\u5178\u578b\u7684\uff08C\u9636\uff093\u00d74\u00d75 float64\u503c\uff088\u5b57\u8282\uff09\u7684\u6570\u7ec4\u5177\u6709\u8de8\u5ea6\uff08160,40,8\uff09\uff08\u901a\u5e38\u7279\u5b9a\u8f74\u4e0a\u7684\u8de8\u5ea6\u8d8a\u5927\uff0c\u6cbf\u7740\u8be5\u8f74\u6267\u884c\u8ba1\u7b97\u7684\u4ee3\u4ef7\u8d8a\u9ad8\uff09\uff1a s = np.ones((3, 4, 5), dtype=np.float64).strides print(s) # (160, 40, 8) \u6570\u7ec4\u8de8\u5ea6\uff08strides\uff09\u662f\u6784\u5efa\u201c\u96f6\u590d\u5236\u201d\u6570\u7ec4\u89c6\u56fe\u7684\u5173\u952e\u56e0\u7d20\u3002 \u6570\u7ec4\u8de8\u5ea6\u751a\u81f3\u53ef\u4ee5\u662f\u8d1f\u7684\uff0c\u8fd9\u4f7f\u5f97\u6570\u7ec4\u80fd\u591f\u7a7f\u8fc7\u5185\u5b58\u201c\u5411\u540e\u201d\u79fb\u52a8\uff08\u4f8b\u5982\uff0c\u5728\u8bf8\u5982obj[::-1]\u6216obj[:, ::-1]\u7684\u5207\u7247\u4e2d\u5c31\u662f\u8fd9\u79cd\u60c5\u51b5\uff09\u3002 NumPy dtype\u5c42\u6b21\u7ed3\u6784 \u00b6 \u6709\u65f6\u5019\u9700\u8981\u901a\u8fc7\u4e00\u4e9b\u4ee3\u7801\u6765\u68c0\u67e5\u6570\u7ec4\u662f\u5426\u5305\u542b\u6574\u6570\u3001\u6d6e\u70b9\u6570\u3001\u5b57\u7b26\u4e32\u6216Python\u5bf9\u8c61\u3002 \u7531\u4e8e\u6d6e\u70b9\u6570\u6709\u591a\u79cd\u7c7b\u578b\uff08float16\u5230float128\uff09\uff0c\u56e0\u6b64\u68c0\u67e5dtype\u662f\u5426\u5728\u7c7b\u578b\u5217\u8868\u4e2d\u4f1a\u975e\u5e38\u9ebb\u70e6\u3002 dtype\u6709\u8d85\u7c7b\uff0c\u5982np.integer\u548cnp.floating\uff0c\u5b83\u4eec\u53ef\u4ee5\u548cnp.issubdtype\u51fd\u6570\u4e00\u8d77\u4f7f\u7528\uff1a ints = np.ones(10, dtype=np.uint16) floats = np.ones(10, dtype=np.float32) \u53ef\u4ee5\u901a\u8fc7\u8c03\u7528\u7c7b\u578b\u7684mro\u65b9\u6cd5\u6765\u67e5\u770b\u7279\u5b9adtype\u7684\u6240\u6709\u7236\u7c7b\uff1a print(np.float64.mro()) # [, # , # , # , # , # , # ] print(np.issubdtype(ints.dtype, np.integer)) # True print(np.issubdtype(floats.dtype, np.floating)) # True print(np.issubdtype(floats.dtype, np.number)) # True print(np.issubdtype(floats.dtype, np.generic)) # True \u9ad8\u7ea7\u6570\u7ec4\u64cd\u4f5c \u00b6 \u91cd\u5851\u6570\u7ec4 \u00b6 \u901a\u5e38\uff0c\u901a\u8fc7 reshape \u5c06\u6570\u7ec4\u4ece\u4e00\u4e2a\u5f62\u72b6\u8f6c\u6362\u4e3a\u53e6\u4e00\u4e2a\u5f62\u72b6\uff0c\u5e76\u4e14\u4e0d\u590d\u5236\u4efb\u4f55\u6570\u636e\u3002 reshape \u91cc\u9762\u6709\u4e24\u79cd\u91cd\u5851\u987a\u5e8f\uff0c\u6309C\u987a\u5e8f\uff08\u884c\u65b9\u5411\uff09\u7684\u91cd\u5851\u548c\u6309Fortran\u987a\u5e8f\uff08\u5217\u65b9\u5411\uff09\u7684\u91cd\u5851\u3002 \u9996\u5148\u662f\u53d6\u6570\uff0c\u7136\u540e\u662f\u653e\u6570\uff0c\u53d6\u6570\u6309\u4ec0\u4e48\u987a\u5e8f\uff0c\u653e\u6570\u5c31\u6309\u4ec0\u4e48\u987a\u5e8f\u3002 \u4e0b\u9762\u662f\u5b98\u7f51\u7684\u89e3\u91ca\uff1a \u2018C\u2019 means to read / write the elements using C-like index order, with the last axis index changing fastest, back to the first axis index changing slowest. \u2018F\u2019 means to read / write the elements using Fortran-like index order, with the first index changing fastest, and the last index changing slowest. Note that the \u2018C\u2019 and \u2018F\u2019 options take no account of the memory layout of the underlying array, and only refer to the order of indexing. \u2018A\u2019 means to read / write the elements in Fortran-like index order if a is Fortran contiguous in memory, C-like order otherwise. \u4e00\u7ef4\u6570\u7ec4\u91cd\u5851\uff1a arr = np.arange(8) print(arr) # [0 1 2 3 4 5 6 7] a = arr.reshape((4, 2), order='C') print(a) # [[0 1] # [2 3] # [4 5] # [6 7]] a = arr.reshape((4, 2), order='F') print(a) # [[0 4] # [1 5] # [2 6] # [3 7]] \u591a\u7ef4\u6570\u7ec4\u91cd\u5851\uff1a\u4f20\u9012\u7684\u5f62\u72b6\u7ef4\u5ea6\u53ef\u4ee5\u6709\u4e00\u4e2a\u503c\u662f-1\uff0c\u8868\u793a\u7ef4\u5ea6\u901a\u8fc7\u6570\u636e\u8fdb\u884c\u63a8\u65ad\uff1a a = arr.reshape((4, 2)).reshape((2, 4)) print(a) # [[0 1 2 3] # [4 5 6 7]] arr = np.arange(15) a = arr.reshape((5, -1)) # 15 / 5 = 3\u5217 print(a) # [[ 0 1 2] # [ 3 4 5] # [ 6 7 8] # [ 9 10 11] # [12 13 14]] print(a.shape) # (5, 3) \u6570\u7ec4\u7684 shape \u5c5e\u6027\u662f\u4e00\u4e2a**\u5143\u7ec4**\uff0c\u5b83\u4e5f\u53ef\u4ee5\u88ab\u4f20\u9012\u7ed9 reshape \uff0c\u63a5\u4e0a\u4f8b\uff1a other_arr = np.ones((3, 5)) print(other_arr.shape) # (3, 5) a = arr.reshape(other_arr.shape) print(a.shape) # (3, 5) reshape \u7684\u53cd\u64cd\u4f5c\u53ef\u4ee5\u5c06\u66f4\u9ad8\u7ef4\u5ea6\u7684\u6570\u7ec4\u8f6c\u6362\u4e3a\u4e00\u7ef4\u6570\u7ec4\uff0c\u8fd9\u79cd\u64cd\u4f5c\u901a\u5e38\u88ab\u6210\u4e3a\u6241\u5e73\u5316\uff08flattening\uff09\u6216\u5206\u6563\u5316\uff08raveling\uff09\u3002 \u5982\u679c\u7ed3\u679c\u4e2d\u7684\u503c\u5728\u539f\u59cb\u6570\u7ec4\u4e2d\u662f\u8fde\u7eed\u7684\uff0c\u5219 ravel \u4e0d\u4f1a\u751f\u6210\u5e95\u5c42\u6570\u503c\u7684\u526f\u672c\u3002 flatten \u65b9\u6cd5\u7684\u884c\u4e3a\u7c7b\u4f3c\u4e8e ravel \uff0c\u4f46\u5b83\u603b\u662f\u751f\u6210\u6570\u636e\u7684\u526f\u672c\u3002 arr = np.arange(15).reshape((5, 3)) print(arr) # [[ 0 1 2] # [ 3 4 5] # [ 6 7 8] # [ 9 10 11] # [12 13 14]] a = arr.ravel() print(a) # [ 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14] a = arr.flatten() print(a) # [ 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14] C\u987a\u5e8f\u548cF\u987a\u5e8f \u00b6 \u6570\u636e\u53ef\u4ee5\u6309\u7167\u4e0d\u540c\u7684\u987a\u5e8f\u8fdb\u884c\u91cd\u5851\u6216\u6241\u5e73\u5316\u3002\u9ed8\u8ba4\u60c5\u51b5\u4e0b\uff0cNumPy\u6570\u7ec4\u662f\u6309\u884c\u65b9\u5411\u987a\u5e8f\u521b\u5efa\u7684\u3002 \u5bf9\u4e8e\u4e00\u4e2a\u4e8c\u7ef4\u7684\u6570\u636e\u6570\u7ec4\uff0c**C\u987a\u5e8f**\u8bf4\u660e\u6570\u7ec4\u6bcf\u884c\u4e2d\u7684\u5143\u7d20\u5b58\u50a8\u5728\u76f8\u90bb\u7684\u5b58\u50a8\u5355\u5143\u4e2d\u3002**F\u987a\u5e8f**\u610f\u5473\u7740\u6bcf\u5217\u6570\u636e\u4e2d\u7684\u503c\u90fd\u5b58\u50a8\u5728\u76f8\u90bb\u7684\u5185\u5b58\u4f4d\u7f6e\u4e2d\u3002 \u53ef\u4ee5\u901a\u8fc7\u8bbe\u7f6e reshape \u548c ravel \u51fd\u6570\u7684 order \u53c2\u6570\u6765\u8868\u793a\u6570\u636e\u5728\u6570\u7ec4\u4e2d\u4f7f\u7528\u54ea\u79cd\u987a\u5e8f\u3002 arr = np.arange(15).reshape((5, 3)) print(arr) # [[ 0 1 2] # [ 3 4 5] # [ 6 7 8] # [ 9 10 11] # [12 13 14]] print(arr.ravel()) # [ 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14] print(arr.ravel('F')) # [ 0 3 6 9 12 1 4 7 10 13 2 5 8 11 14] C\u987a\u5e8f\u548cFortran\u987a\u5e8f\u7684\u6838\u5fc3\u533a\u522b\u5c31\u662f\u5728\u7ef4\u5ea6\u65b9\u5411\u4e0a\u904d\u5386\u7684\u65b9\u5f0f\u3002 C\u987a\u5e8f/\u884c\u65b9\u5411\u987a\u5e8f\u9996\u5148\u904d\u5386\u66f4\u9ad8\u7684\u7ef4\u5ea6\uff08\u4f8b\u5982\uff0c\u5728\u8f740\u4e0a\u884c\u8fdb\u4e4b\u524d\u5148\u5728\u8f741\u4e0a\u884c\u8fdb\uff09\u3002 Fortran\u987a\u5e8f/\u5217\u65b9\u5411\u987a\u5e8f\u6700\u540e\u904d\u5386\u66f4\u9ad8\u7684\u7ef4\u5ea6\uff08\u4f8b\u5982\uff0c\u5728\u8f741\u4e0a\u884c\u8fdb\u4e4b\u524d\u5148\u5728\u8f740\u4e0a\u884c\u8fdb\uff09\u3002 \u6570\u7ec4\u8fde\u63a5\u548c\u5206\u9694 \u00b6 numpy.concatenate \u53ef\u4ee5\u83b7\u53d6\u6570\u7ec4\u7684\u5e8f\u5217\uff08\u5143\u7ec4\u3001\u5217\u8868\u7b49\uff09\uff0c\u5e76\u6cbf\u7740\u8f93\u5165\u8f74\u5c06\u5b83\u4eec\u6309\u987a\u5e8f\u8fde\u63a5\u5728\u4e00\u8d77\uff1a arr1 = np.array( [ [1, 2, 3], [4, 5, 6] ] ) arr2 = np.array( [ [7, 8, 9], [10, 11, 12] ] ) a = np.concatenate([arr1, arr2], axis=0) print(a) # [[ 1 2 3] # [ 4 5 6] # [ 7 8 9] # [10 11 12]] a = np.concatenate([arr1, arr2], axis=1) print(a) # [[ 1 2 3 7 8 9] # [ 4 5 6 10 11 12]] \u5176\u4ed6\u7c7b\u4f3c concatenate \u7684\u51fd\u6570\u3002 vstack \u7c7b\u4f3c concatenate \u6cbf axis=0 \u64cd\u4f5c\uff0c hstack \u7c7b\u4f3c concatenate \u6cbf axis=1 \u64cd\u4f5c\u3002 a = np.vstack((arr1, arr2)) print(a) # [[ 1 2 3] # [ 4 5 6] # [ 7 8 9] # [10 11 12]] a = np.hstack((arr1, arr2)) print(a) # [[ 1 2 3 7 8 9] # [ 4 5 6 10 11 12]] split \u53ef\u4ee5\u5c06\u4e00\u4e2a\u6570\u7ec4\u6cbf\u8f74\u5411\u5207\u7247\u6210\u591a\u4e2a\u6570\u7ec4\u3002\u5148\u770b\u4e00\u7ef4\u6570\u7ec4\u3002 np.split(arr, 3) \u8868\u793a\u5c06\u6570\u7ec4\u62c6\u5206\u65f6\u7684**\u7d22\u5f15\u4f4d\u7f6e** arr = np.array(['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k']) print(arr) # ['a' 'b' 'c' 'd' 'e' 'f' 'g' 'h' 'i' 'j' 'k'] print(np.split(arr, 3)) print(np.split(arr, [3])) # \u4ece\u7d22\u5f15\u4f4d\u7f6e\u4e3a3\u8fdb\u884c\u62c6\u5206 # [array(['a', 'b', 'c'], dtype=', # , # , # , # , # , # ] print(np.issubdtype(ints.dtype, np.integer)) # True print(np.issubdtype(floats.dtype, np.floating)) # True print(np.issubdtype(floats.dtype, np.number)) # True print(np.issubdtype(floats.dtype, np.generic)) # True","title":"NumPy dtype\u5c42\u6b21\u7ed3\u6784"},{"location":"python/DataAnalysis/ch10/#_1","text":"","title":"\u9ad8\u7ea7\u6570\u7ec4\u64cd\u4f5c"},{"location":"python/DataAnalysis/ch10/#_2","text":"\u901a\u5e38\uff0c\u901a\u8fc7 reshape \u5c06\u6570\u7ec4\u4ece\u4e00\u4e2a\u5f62\u72b6\u8f6c\u6362\u4e3a\u53e6\u4e00\u4e2a\u5f62\u72b6\uff0c\u5e76\u4e14\u4e0d\u590d\u5236\u4efb\u4f55\u6570\u636e\u3002 reshape \u91cc\u9762\u6709\u4e24\u79cd\u91cd\u5851\u987a\u5e8f\uff0c\u6309C\u987a\u5e8f\uff08\u884c\u65b9\u5411\uff09\u7684\u91cd\u5851\u548c\u6309Fortran\u987a\u5e8f\uff08\u5217\u65b9\u5411\uff09\u7684\u91cd\u5851\u3002 \u9996\u5148\u662f\u53d6\u6570\uff0c\u7136\u540e\u662f\u653e\u6570\uff0c\u53d6\u6570\u6309\u4ec0\u4e48\u987a\u5e8f\uff0c\u653e\u6570\u5c31\u6309\u4ec0\u4e48\u987a\u5e8f\u3002 \u4e0b\u9762\u662f\u5b98\u7f51\u7684\u89e3\u91ca\uff1a \u2018C\u2019 means to read / write the elements using C-like index order, with the last axis index changing fastest, back to the first axis index changing slowest. \u2018F\u2019 means to read / write the elements using Fortran-like index order, with the first index changing fastest, and the last index changing slowest. Note that the \u2018C\u2019 and \u2018F\u2019 options take no account of the memory layout of the underlying array, and only refer to the order of indexing. \u2018A\u2019 means to read / write the elements in Fortran-like index order if a is Fortran contiguous in memory, C-like order otherwise. \u4e00\u7ef4\u6570\u7ec4\u91cd\u5851\uff1a arr = np.arange(8) print(arr) # [0 1 2 3 4 5 6 7] a = arr.reshape((4, 2), order='C') print(a) # [[0 1] # [2 3] # [4 5] # [6 7]] a = arr.reshape((4, 2), order='F') print(a) # [[0 4] # [1 5] # [2 6] # [3 7]] \u591a\u7ef4\u6570\u7ec4\u91cd\u5851\uff1a\u4f20\u9012\u7684\u5f62\u72b6\u7ef4\u5ea6\u53ef\u4ee5\u6709\u4e00\u4e2a\u503c\u662f-1\uff0c\u8868\u793a\u7ef4\u5ea6\u901a\u8fc7\u6570\u636e\u8fdb\u884c\u63a8\u65ad\uff1a a = arr.reshape((4, 2)).reshape((2, 4)) print(a) # [[0 1 2 3] # [4 5 6 7]] arr = np.arange(15) a = arr.reshape((5, -1)) # 15 / 5 = 3\u5217 print(a) # [[ 0 1 2] # [ 3 4 5] # [ 6 7 8] # [ 9 10 11] # [12 13 14]] print(a.shape) # (5, 3) \u6570\u7ec4\u7684 shape \u5c5e\u6027\u662f\u4e00\u4e2a**\u5143\u7ec4**\uff0c\u5b83\u4e5f\u53ef\u4ee5\u88ab\u4f20\u9012\u7ed9 reshape \uff0c\u63a5\u4e0a\u4f8b\uff1a other_arr = np.ones((3, 5)) print(other_arr.shape) # (3, 5) a = arr.reshape(other_arr.shape) print(a.shape) # (3, 5) reshape \u7684\u53cd\u64cd\u4f5c\u53ef\u4ee5\u5c06\u66f4\u9ad8\u7ef4\u5ea6\u7684\u6570\u7ec4\u8f6c\u6362\u4e3a\u4e00\u7ef4\u6570\u7ec4\uff0c\u8fd9\u79cd\u64cd\u4f5c\u901a\u5e38\u88ab\u6210\u4e3a\u6241\u5e73\u5316\uff08flattening\uff09\u6216\u5206\u6563\u5316\uff08raveling\uff09\u3002 \u5982\u679c\u7ed3\u679c\u4e2d\u7684\u503c\u5728\u539f\u59cb\u6570\u7ec4\u4e2d\u662f\u8fde\u7eed\u7684\uff0c\u5219 ravel \u4e0d\u4f1a\u751f\u6210\u5e95\u5c42\u6570\u503c\u7684\u526f\u672c\u3002 flatten \u65b9\u6cd5\u7684\u884c\u4e3a\u7c7b\u4f3c\u4e8e ravel \uff0c\u4f46\u5b83\u603b\u662f\u751f\u6210\u6570\u636e\u7684\u526f\u672c\u3002 arr = np.arange(15).reshape((5, 3)) print(arr) # [[ 0 1 2] # [ 3 4 5] # [ 6 7 8] # [ 9 10 11] # [12 13 14]] a = arr.ravel() print(a) # [ 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14] a = arr.flatten() print(a) # [ 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14]","title":"\u91cd\u5851\u6570\u7ec4"},{"location":"python/DataAnalysis/ch10/#cf","text":"\u6570\u636e\u53ef\u4ee5\u6309\u7167\u4e0d\u540c\u7684\u987a\u5e8f\u8fdb\u884c\u91cd\u5851\u6216\u6241\u5e73\u5316\u3002\u9ed8\u8ba4\u60c5\u51b5\u4e0b\uff0cNumPy\u6570\u7ec4\u662f\u6309\u884c\u65b9\u5411\u987a\u5e8f\u521b\u5efa\u7684\u3002 \u5bf9\u4e8e\u4e00\u4e2a\u4e8c\u7ef4\u7684\u6570\u636e\u6570\u7ec4\uff0c**C\u987a\u5e8f**\u8bf4\u660e\u6570\u7ec4\u6bcf\u884c\u4e2d\u7684\u5143\u7d20\u5b58\u50a8\u5728\u76f8\u90bb\u7684\u5b58\u50a8\u5355\u5143\u4e2d\u3002**F\u987a\u5e8f**\u610f\u5473\u7740\u6bcf\u5217\u6570\u636e\u4e2d\u7684\u503c\u90fd\u5b58\u50a8\u5728\u76f8\u90bb\u7684\u5185\u5b58\u4f4d\u7f6e\u4e2d\u3002 \u53ef\u4ee5\u901a\u8fc7\u8bbe\u7f6e reshape \u548c ravel \u51fd\u6570\u7684 order \u53c2\u6570\u6765\u8868\u793a\u6570\u636e\u5728\u6570\u7ec4\u4e2d\u4f7f\u7528\u54ea\u79cd\u987a\u5e8f\u3002 arr = np.arange(15).reshape((5, 3)) print(arr) # [[ 0 1 2] # [ 3 4 5] # [ 6 7 8] # [ 9 10 11] # [12 13 14]] print(arr.ravel()) # [ 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14] print(arr.ravel('F')) # [ 0 3 6 9 12 1 4 7 10 13 2 5 8 11 14] C\u987a\u5e8f\u548cFortran\u987a\u5e8f\u7684\u6838\u5fc3\u533a\u522b\u5c31\u662f\u5728\u7ef4\u5ea6\u65b9\u5411\u4e0a\u904d\u5386\u7684\u65b9\u5f0f\u3002 C\u987a\u5e8f/\u884c\u65b9\u5411\u987a\u5e8f\u9996\u5148\u904d\u5386\u66f4\u9ad8\u7684\u7ef4\u5ea6\uff08\u4f8b\u5982\uff0c\u5728\u8f740\u4e0a\u884c\u8fdb\u4e4b\u524d\u5148\u5728\u8f741\u4e0a\u884c\u8fdb\uff09\u3002 Fortran\u987a\u5e8f/\u5217\u65b9\u5411\u987a\u5e8f\u6700\u540e\u904d\u5386\u66f4\u9ad8\u7684\u7ef4\u5ea6\uff08\u4f8b\u5982\uff0c\u5728\u8f741\u4e0a\u884c\u8fdb\u4e4b\u524d\u5148\u5728\u8f740\u4e0a\u884c\u8fdb\uff09\u3002","title":"C\u987a\u5e8f\u548cF\u987a\u5e8f"},{"location":"python/DataAnalysis/ch10/#_3","text":"numpy.concatenate \u53ef\u4ee5\u83b7\u53d6\u6570\u7ec4\u7684\u5e8f\u5217\uff08\u5143\u7ec4\u3001\u5217\u8868\u7b49\uff09\uff0c\u5e76\u6cbf\u7740\u8f93\u5165\u8f74\u5c06\u5b83\u4eec\u6309\u987a\u5e8f\u8fde\u63a5\u5728\u4e00\u8d77\uff1a arr1 = np.array( [ [1, 2, 3], [4, 5, 6] ] ) arr2 = np.array( [ [7, 8, 9], [10, 11, 12] ] ) a = np.concatenate([arr1, arr2], axis=0) print(a) # [[ 1 2 3] # [ 4 5 6] # [ 7 8 9] # [10 11 12]] a = np.concatenate([arr1, arr2], axis=1) print(a) # [[ 1 2 3 7 8 9] # [ 4 5 6 10 11 12]] \u5176\u4ed6\u7c7b\u4f3c concatenate \u7684\u51fd\u6570\u3002 vstack \u7c7b\u4f3c concatenate \u6cbf axis=0 \u64cd\u4f5c\uff0c hstack \u7c7b\u4f3c concatenate \u6cbf axis=1 \u64cd\u4f5c\u3002 a = np.vstack((arr1, arr2)) print(a) # [[ 1 2 3] # [ 4 5 6] # [ 7 8 9] # [10 11 12]] a = np.hstack((arr1, arr2)) print(a) # [[ 1 2 3 7 8 9] # [ 4 5 6 10 11 12]] split \u53ef\u4ee5\u5c06\u4e00\u4e2a\u6570\u7ec4\u6cbf\u8f74\u5411\u5207\u7247\u6210\u591a\u4e2a\u6570\u7ec4\u3002\u5148\u770b\u4e00\u7ef4\u6570\u7ec4\u3002 np.split(arr, 3) \u8868\u793a\u5c06\u6570\u7ec4\u62c6\u5206\u65f6\u7684**\u7d22\u5f15\u4f4d\u7f6e** arr = np.array(['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k']) print(arr) # ['a' 'b' 'c' 'd' 'e' 'f' 'g' 'h' 'i' 'j' 'k'] print(np.split(arr, 3)) print(np.split(arr, [3])) # \u4ece\u7d22\u5f15\u4f4d\u7f6e\u4e3a3\u8fdb\u884c\u62c6\u5206 # [array(['a', 'b', 'c'], dtype='|t| [0.025 0.975] # ------------------------------------------------------------------------------ # x1 0.1783 0.053 3.364 0.001 0.073 0.283 # x2 0.2230 0.046 4.818 0.000 0.131 0.315 # x3 0.5010 0.080 6.237 0.000 0.342 0.660 # ============================================================================== # Omnibus: 4.662 Durbin-Watson: 0 -0.002327 # Prob(Omnibus): 0.097 Jarque-Bera (JB): 4.098 # Skew: 0.481 Prob(JB): 0.129 # Kurtosis: 3.243 Cond. No. 1.74 # ============================================================================== # # Notes: # [1] R\u00b2 is computed without centering (uncentered) since the model does not contain a constant. # [2] Standard Errors assume that the covariance matrix of the errors is correctly specified. \u5047\u8bbe\u6240\u6709\u6a21\u578b\u53c2\u6570\u90fd\u5728DataFrame\u4e2d\uff1a data = pd.DataFrame(X, columns=['col0', 'col1', 'col2']) data['y'] = y print(data[:5]) # col0 col1 col2 y # 0 -0.129468 -1.212753 0.504225 0.427863 # 1 0.302910 -0.435742 -0.254180 -0.673480 # 2 -0.328522 -0.025302 0.138351 -0.090878 # 3 -0.351475 -0.719605 -0.258215 -0.489494 # 4 1.243269 -0.373799 -0.522629 -0.128941 \u73b0\u5728\u53ef\u4ee5\u4f7f\u7528 statsmodels \u516c\u5f0fAPI\u548cPatsy\u516c\u5f0f\u5b57\u7b26\u4e32\u3002\u89c2\u5bdf statsmodels \u5982\u4f55\u5c06\u7ed3\u679c\u4f5c\u4e3a\u5e26\u6709DataFrame\u5217\u540d\u79f0\u7684Series\u8fd4\u56de\u3002 results = smf.ols('y ~ col0 + col1 + col2', data=data).fit() print(results.params) # Intercept 0.033559 # col0 0.176149 # col1 0.224826 # col2 0.514808 # dtype: float64 \u7ed9\u5b9a\u65b0\u7684\u6837\u672c\u5916\u6570\u636e\u540e\uff0c\u53ef\u4ee5\u6839\u636e\u4f30\u8ba1\u7684\u6a21\u578b\u53c2\u6570\u8ba1\u7b97\u9884\u6d4b\u503c\uff1a print(results.predict(data[:5])) # 0 -0.002327 # 1 -0.141904 # 2 0.041226 # 3 -0.323070 # 4 -0.100535 # dtype: float64 \u8bc4\u4f30\u65f6\u95f4\u5e8f\u5217\u5904\u7406 \u00b6 statsmodels\u4e2d\u7684\u53e6\u4e00\u7c7b\u6a21\u578b\u7528\u4e8e\u65f6\u95f4\u5e8f\u5217\u5206\u6790\u3002\u5176\u4e2d\u5305\u62ec\u81ea\u56de\u5f52\u8fc7\u7a0b\uff0c\u5361\u5c14\u66fc\u6ee4\u6ce2\u548c\u5176\u4ed6\u72b6\u6001\u7a7a\u95f4\u6a21\u578b\uff0c\u4ee5\u53ca\u591a\u53d8\u91cf\u81ea\u56de\u5f52\u6a21\u578b\u3002 \u4e0b\u4f8b\u6a21\u62df\u4e00\u4e9b\u5177\u6709\u81ea\u56de\u5f52\u7ed3\u6784\u548c\u566a\u58f0\u7684\u65f6\u95f4\u5e8f\u5217\u6570\u636e\uff0c\u8be5\u6570\u636e\u5177\u6709\u53c2\u6570\u4e3a0.8\u548c-0.4\u7684AR\uff082\uff09\u7ed3\u6784\uff08\u4e24\u4e2a\u6ede\u540e\uff09\u3002 init_x = 4 values = [init_x, init_x] N = 1000 b0 = 0.8 b1 = -0.4 noise = dnorm(0, 0.1, N) for i in range(N): new_x = values[-1] * b0 + values[-2] * b1 + noise[i] values.append(new_x) \u5f53\u62df\u5408\u4e00\u4e2aAR\u6a21\u578b\u65f6\uff0c\u4f60\u53ef\u80fd\u4e0d\u77e5\u9053\u5305\u542b\u7684\u6ede\u540e\u9879\u7684\u6570\u91cf\uff0c\u6240\u4ee5\u53ef\u4ee5\u7528\u66f4\u5927\u7684\u6ede\u540e\u6570\u6765\u62df\u5408\u8be5\u6a21\u578b\uff1a MAXLAGS = 5 model = sm.tsa.AR(values) results = model.fit(MAXLAGS) print(results.params) # NotImplementedError: AR has been removed from statsmodels and replaced with statsmodels.tsa.ar_model.AutoReg. sikit-learn\u4ecb\u7ecd \u00b6 scikit-learn\uff08http://scikit-learn.org\uff09\u662f\u4f7f\u7528\u6700\u5e7f\u6cdb\u4e14\u6700\u53d7\u4fe1\u4efb\u7684\u901a\u7528Python\u673a\u5668\u5b66\u4e60\u5e93\u3002\\ \u5b83\u5305\u542b\u5e7f\u6cdb\u7684\u6807\u51c6\u76d1\u7763\u7684\u548c\u65e0\u76d1\u7763\u7684\u673a\u5668\u5b66\u4e60\u65b9\u6cd5\uff0c\u5305\u62ec\u7528\u4e8e\u6a21\u578b\u9009\u62e9\u548c\u8bc4\u4f30\u3001\u6570\u636e\u8f6c\u6362\u3001\u6570\u636e\u52a0\u8f7d\u548c\u6a21\u578b\u6301\u4e45\u5316\u7684\u5de5\u5177\u3002\\ \u8fd9\u4e9b\u6a21\u578b\u53ef\u7528\u4e8e\u5206\u7c7b\u3001\u805a\u7c7b\u3001\u9884\u6d4b\u548c\u5176\u4ed6\u5e38\u89c1\u4efb\u52a1\u3002\\ pandas\u975e\u5e38\u9002\u5408\u5728\u6a21\u578b\u62df\u5408\u524d\u5904\u7406\u6570\u636e\u96c6\u3002 \u4e3e\u4e2a\u4f8b\u5b50\uff0c\u7528\u4e00\u4e2aKaggle\u7ade\u8d5b\u7684\u7ecf\u5178\u6570\u636e\u96c6\uff0c\u5173\u4e8e\u6cf0\u5766\u5c3c\u514b\u53f7\u4e58\u5ba2\u7684\u751f\u8fd8\u7387\u3002\u6211\u4eec\u7528pandas\u52a0\u8f7d\u6d4b\u8bd5\u548c\u8bad\u7ec3\u6570\u636e\u96c6\uff1a import pandas as pd from sklearn.linear_model import LogisticRegression from sklearn.linear_model import LogisticRegressionCV from sklearn.model_selection import cross_val_score train = pd.read_csv('../datasets/titanic/train.csv') test = pd.read_csv('../datasets/titanic/test.csv') print(train[:4]) # PassengerId Survived Pclass ... Fare Cabin Embarked # 0 1 0 3 ... 7.2500 NaN S # 1 2 1 1 ... 71.2833 C85 C # 2 3 1 3 ... 7.9250 NaN S # 3 4 1 1 ... 53.1000 C123 S \u50cfstatsmodels\u548cscikit-learn\u901a\u5e38\u4e0d\u80fd\u63d0\u4f9b\u7f3a\u5931\u6570\u636e\uff0c\u56e0\u6b64\u6211\u4eec\u8981\u68c0\u67e5\u5404\u5217\uff0c\u770b\u770b\u662f\u5426\u6709\u5305\u542b\u7f3a\u5931\u6570\u636e\uff1a print(train.isnull().sum()) # PassengerId 0 # Survived 0 # Pclass 0 # Name 0 # Sex 0 # Age 177 # SibSp 0 # Parch 0 # Ticket 0 # Fare 0 # Cabin 687 # Embarked 2 # dtype: int64 print(test.isnull().sum()) # PassengerId 0 # Pclass 0 # Name 0 # Sex 0 # Age 86 # SibSp 0 # Parch 0 # Ticket 0 # Fare 1 # Cabin 327 # Embarked 0 # dtype: int64 \u5728\u50cf\u8fd9\u6837\u7684\u7edf\u8ba1\u548c\u673a\u5668\u5b66\u4e60\u7684\u4f8b\u5b50\u4e2d\uff0c\u4e00\u4e2a\u5178\u578b\u7684\u4efb\u52a1\u662f\u6839\u636e\u6570\u636e\u4e2d\u7684\u7279\u5f81\u6765\u9884\u6d4b\u4e58\u5ba2\u662f\u5426\u80fd\u5e78\u5b58\u4e0b\u6765\u3002\\ \u5c06\u6a21\u578b\u62df\u5408\u5230\u8bad\u7ec3\u6570\u636e\u96c6\u4e0a\uff0c\u7136\u540e\u5728\u6837\u672c\u5916\u6d4b\u8bd5\u6570\u636e\u96c6\u4e0a\u8fdb\u884c\u8bc4\u4f30\u3002\\ \u5982\u679c\u7528Age\u4f5c\u4e3a\u9884\u6d4b\uff0c\u4f46\u5b83\u7f3a\u5c11\u6570\u636e\u3002\u9700\u8981\u8fdb\u884c\u7f3a\u5931\u6570\u636e\u63d2\u8865\uff08imputation\uff09\uff0c\u5e76\u4f7f\u7528\u8bad\u7ec3\u6570\u636e\u96c6\u7684\u4e2d\u95f4\u503c\u586b\u5145\u4e24\u4e2a\u8868\u4e2d\u7684\u7a7a\u503c\uff1a impute_value = train['Age'].median() train['Age'] = train['Age'].fillna(impute_value) test['Age'] = test['Age'].fillna(impute_value) \u73b0\u5728\u5efa\u7acb\u6a21\u578b\u3002\\ \u6dfb\u52a0\u4e00\u5217IsFemale\u4f5c\u4e3a\u2019Sex\u2019\u5217\u7684\u7f16\u7801\u7248\u672c\uff1a train['IsFemale'] = (train['Sex'] == 'female').astype(int) test['IsFemale'] = (test['Sex'] == 'female').astype(int) \u786e\u5b9a\u4e00\u4e9b\u6a21\u578b\u53d8\u91cf\u5e76\u521b\u5efaNumPy\u6570\u7ec4\uff1a predictors = ['Pclass', 'IsFemale', 'Age'] X_train = train[predictors].values X_test = test[predictors].values y_train = train['Survived'].values print(X_train[:5]) # [[ 3. 0. 22.] # [ 1. 1. 38.] # [ 3. 1. 26.] # [ 1. 1. 35.] # [ 3. 0. 35.]] print(y_train[:5]) # [0 1 1 1 0] \u4f7f\u7528scikit-learn\u7684LogisticRegression\u6a21\u578b\u521b\u5efa\u4e00\u4e2a\u6a21\u578b\u5b9e\u4f8b\uff1a model = LogisticRegression() \u4e0estatsmodels\u7c7b\u4f3c\uff0c\u4f7f\u7528\u6a21\u578b\u7684fit\u65b9\u6cd5\u5728\u8bad\u7ec3\u6570\u636e\u4e0a\u62df\u5408\u6a21\u578b\uff1a result = model.fit(X_train, y_train) print(result) # LogisticRegression() \u4f7f\u7528model.predict\u4e3a\u6d4b\u8bd5\u6570\u636e\u96c6\u5f62\u6210\u9884\u6d4b\uff1a y_predict = model.predict(X_test) print(y_predict[:10]) # [0 0 0 0 1 0 1 0 1 0] \u5b9e\u9645\u4e0a\uff0c\u6a21\u578b\u8bad\u7ec3\u4e2d\u7ecf\u5e38\u5b58\u5728\u8bb8\u591a\u9644\u52a0\u7684\u590d\u6742\u5c42\u6b21\u3002\\ \u8bb8\u591a\u6a21\u578b\u5177\u6709\u53ef\u4ee5\u8c03\u6574\u7684\u53c2\u6570\uff0c\u5e76\u4e14\u5b58\u5728\u53ef\u7528\u4e8e\u53c2\u6570\u8c03\u6574\u7684\u4ea4\u53c9\u9a8c\u8bc1\u7b49\u6280\u672f\u4ee5\u907f\u514d\u8fc7\u5ea6\u62df\u5408\u8bad\u7ec3\u6570\u636e\u3002\\ \u8fd9\u901a\u5e38\u53ef\u4ee5\u5728\u65b0\u6570\u636e\u4e0a\u4ea7\u751f\u66f4\u597d\u7684\u9884\u6d4b\u6027\u80fd\u6216\u7a33\u5065\u6027\u3002\u4ea4\u53c9\u9a8c\u8bc1\u901a\u8fc7\u5206\u5272\u8bad\u7ec3\u6570\u636e\u6765\u6a21\u62df\u6837\u672c\u5916\u9884\u6d4b\u3002\\ \u57fa\u4e8e\u50cf\u5747\u65b9\u8bef\u5dee\u4e4b\u7c7b\u7684\u6a21\u578b\u51c6\u786e\u5ea6\u5206\u6570\uff0c\u53ef\u4ee5\u5bf9\u6a21\u578b\u53c2\u6570\u6267\u884c\u7f51\u683c\u641c\u7d22\u3002\\ \u4e00\u4e9b\u6a21\u578b\uff0c\u5982\u903b\u8f91\u56de\u5f52\uff0c\u5177\u6709\u5185\u7f6e\u4ea4\u53c9\u9a8c\u8bc1\u7684\u4f30\u8ba1\u7c7b\u3002\\ \u4f8b\u5982\uff0cLogisticRegressionCV\u7c7b\u53ef\u4ee5\u4e0e\u4e00\u4e2a\u53c2\u6570\u4e00\u8d77\u4f7f\u7528\uff0c\u8be5\u53c2\u6570\u8868\u793a\u7f51\u683c\u641c\u7d22\u5728\u6a21\u578b\u6b63\u5219\u5316\u53c2\u6570C\u4e0a\u7684\u7ec6\u81f4\u5ea6\uff1a model_cv = LogisticRegressionCV() result = model_cv.fit(X_train, y_train) print(result) # LogisticRegressionCV() \u8981\u624b\u52a8\u8fdb\u884c\u4ea4\u53c9\u9a8c\u8bc1\uff0c\u53ef\u4ee5\u4f7f\u7528cross_val_score\u51fd\u6570\uff0c\u8be5\u51fd\u6570\u5904\u7406\u6570\u636e\u62c6\u5206\u8fc7\u7a0b\u3002\\ \u4f8b\u5982\uff0c\u4e3a\u4e86\u7528\u6211\u4eec\u7684\u6a21\u578b\u4e0e\u8bad\u7ec3\u6570\u636e\u7684\u56db\u4e2a\u975e\u91cd\u53e0\u5206\u5272\u8fdb\u884c\u4ea4\u53c9\u9a8c\u8bc1\uff0c\u53ef\u4ee5\u8fd9\u6837\u505a\uff1a model = LogisticRegression(C=10) scores = cross_val_score(model, X_train, y_train, cv=4) print(scores) # [0.77578475 0.79820628 0.77578475 0.78828829] \u9ed8\u8ba4\u8bc4\u5206\u6307\u6807\u662f\u4f9d\u8d56\u4e8e\u6a21\u578b\u7684\uff0c\u4f46\u53ef\u4ee5\u9009\u62e9\u660e\u786e\u7684\u8bc4\u5206\u51fd\u6570\u3002\u7ecf\u8fc7\u4ea4\u53c9\u9a8c\u8bc1\u7684\u6a21\u578b\u9700\u8981\u66f4\u957f\u65f6\u95f4\u7684\u8bad\u7ec3\uff0c\u4f46\u901a\u5e38\u53ef\u4ee5\u4ea7\u751f\u66f4\u597d\u7684\u6a21\u578b\u6027\u80fd\u3002","title":"Python\u5efa\u6a21\u5e93\u4ecb\u7ecd"},{"location":"python/DataAnalysis/ch11/#python","text":"","title":"Python\u5efa\u6a21\u5e93\u4ecb\u7ecd"},{"location":"python/DataAnalysis/ch11/#pandas","text":"\u4ecb\u7ecd\u4e24\u4e2a\u6d41\u884c\u7684\u5efa\u6a21\u5de5\u5177\u5305\uff1a [statsmodels]http://statsmodels.org\uff09 [scikit-learn]http://scikit-learn.org\uff09 import pandas as pd import numpy as np \u4f7f\u7528pandas\u7528\u4e8e\u6570\u636e\u8f7d\u5165\u548c\u6570\u636e\u6e05\u6d17\uff0c\u4e4b\u540e\u5207\u6362\u5230\u6a21\u578b\u5e93\u53bb\u5efa\u7acb\u6a21\u578b\u662f\u4e00\u4e2a\u5e38\u89c1\u7684\u6a21\u578b\u5f00\u53d1\u5de5\u4f5c\u6d41\u3002 \u5728\u673a\u5668\u5b66\u4e60\u4e2d\uff0c\u7279\u5f81\u5de5\u7a0b\u662f\u6a21\u578b\u5f00\u53d1\u7684\u91cd\u8981\u90e8\u5206\u4e4b\u4e00\u3002 \u7279\u5f81\u5de5\u7a0b\u662f\u6307\u4ece\u539f\u751f\u6570\u636e\u96c6\u4e2d\u63d0\u53d6\u53ef\u7528\u4e8e\u6a21\u578b\u4e0a\u4e0b\u6587\u7684\u6709\u6548\u4fe1\u606f\u7684\u6570\u636e\u8f6c\u6362\u8fc7\u7a0b\u6216\u5206\u6790\u3002 pandas\u548c\u5176\u4ed6\u5206\u6790\u5e93\u7684\u7ed3\u5408\u70b9\u901a\u5e38\u662fNumPy\u6570\u7ec4\u3002 \u8981\u5c06DataFrame\u8f6c\u6362\u4e3aNumPy\u6570\u7ec4\uff0c\u4f7f\u7528 .values \u5c5e\u6027\uff1a df = pd.DataFrame( { 'x0': [1, 2, 3, 4, 5], 'x1': [0.01, -0.01, 0.25, -4.1, 0.], 'y': [-1.5, 0., 3.6, 1.3, -2.] } ) print(df) # x0 x1 y # 0 1 0.01 -1.5 # 1 2 -0.01 0.0 # 2 3 0.25 3.6 # 3 4 -4.10 1.3 # 4 5 0.00 -2.0 print(df.columns) # Index(['x0', 'x1', 'y'], dtype='object') print(df.values) # [[ 1. 0.01 -1.5 ] # [ 2. -0.01 0. ] # [ 3. 0.25 3.6 ] # [ 4. -4.1 1.3 ] # [ 5. 0. -2. ]] \u5c06\u6570\u7ec4\u518d\u8f6c\u6362\u4e3aDataFrame\uff1a df2 = pd.DataFrame(df.values, columns=['one', 'two', 'three']) # \u9012\u4e00\u4e2a\u542b\u6709\u5217\u540d\u7684\u4e8c\u7ef4ndarray print(df2) # one two three # 0 1.0 0.01 -1.5 # 1 2.0 -0.01 0.0 # 2 3.0 0.25 3.6 # 3 4.0 -4.10 1.3 # 4 5.0 0.00 -2.0 .values \u5c5e\u6027\u4e00\u822c\u5728\u6570\u636e\u662f\u540c\u6784\u5316\u7684\u65f6\u5019\u4f7f\u7528\u2014\u2014\u4f8b\u5982\uff0c\u90fd\u662f\u6570\u5b57\u7c7b\u578b\u7684\u65f6\u5019\u3002\u5982\u679c\u6570\u636e\u662f\u5f02\u6784\u5316\u7684\uff0c\u7ed3\u679c\u5c06\u662fPython\u5bf9\u8c61\u7684 ndarray \uff1a \u6dfb\u52a0\u4e00\u4e2a\u975e\u6570\u5b57\u7c7b\u578b\u7684\u5217\u3002 df3 = df.copy() df3['category'] = pd.Categorical(['a', 'b', 'a', 'a', 'b'], categories=['a', 'b']) print(df3) # x0 x1 y category # 0 1 0.01 -1.5 a # 1 2 -0.01 0.0 b # 2 3 0.25 3.6 a # 3 4 -4.10 1.3 a # 4 5 0.00 -2.0 b print(df3.values) # [[1 0.01 -1.5 'a'] # [2 -0.01 0.0 'b'] # [3 0.25 3.6 'a'] # [4 -4.1 1.3 'a'] # [5 0.0 -2.0 'b']] \u901a\u8fc7 loc \u7d22\u5f15\u548c values \u4f7f\u7528\u4e00\u90e8\u5206\u5217\u6570\u636e\u3002 model_cols = ['x0', 'x1'] result = df.loc[:, model_cols].values print(result) # [[ 1. 0.01] # [ 2. -0.01] # [ 3. 0.25] # [ 4. -4.1 ] # [ 5. 0. ]] \u5982\u679c\u6211\u4f7f\u7528\u865a\u62df\u53d8\u91cf\u66ff\u4ee3 df3 \u7684 category \u5217\uff0c\u5148\u521b\u5efa\u865a\u62df\u53d8\u91cf\uff0c\u4e4b\u540e\u5220\u9664 categroy \u5217\uff0c\u7136\u540e\u8fde\u63a5\u7ed3\u679c\uff1a dummies = pd.get_dummies(df3.category, prefix='category') print(dummies) # category_a category_b # 0 1 0 # 1 0 1 # 2 1 0 # 3 1 0 # 4 0 1 data_with_dummies = df3.drop('category', axis=1).join(dummies) print(data_with_dummies) # x0 x1 y category_a category_b # 0 1 0.01 -1.5 1 0 # 1 2 -0.01 0.0 0 1 # 2 3 0.25 3.6 1 0 # 3 4 -4.10 1.3 1 0 # 4 5 0.00 -2.0 0 1","title":"pandas\u4e0e\u5efa\u6a21\u4ee3\u7801\u7684\u7ed3\u5408"},{"location":"python/DataAnalysis/ch11/#patsy","text":"\u6837\u672c\u7684\u8868\u793a\u5f62\u5f0f\uff1a \u5728\u6570\u636e\u6316\u6398\u8fc7\u7a0b\u4e2d\uff0c\u6837\u672c\u4ee5\u7279\u5f81\u503c\u77e9\u9635X\u548c\u76ee\u6807\u503c\u5411\u91cfY\u7684\u5f62\u5f0f\u8868\u793a\u3002 \u5bb9\u91cf\u4e3a n \uff0c\u6709 m \u4e2a\u7279\u5f81\u7684\u6837\u672c\uff0c\u5176\u7279\u5f81\u503c\u77e9\u9635X\u7531 n \u4e2a\u7ef4\u5ea6\u4e3a m \u7684\u5217\u5411\u91cf\u7ec4\u6210\uff0c\u7b2c j \u4e2a\u5217\u5411\u91cf\u4e3a\u6837\u672c\u4e2d\u7b2c j \u4e2a\u4e2a\u4f53\u7684\u7279\u5f81\u503c\u5411\u91cf\uff1b \u76ee\u6807\u503c\u5411\u91cfY\u7684\u7b2c j \u4e2a\u5206\u91cf\u4e3a\u6837\u672c\u4e2d\u7b2c j \u4e2a\u4e2a\u4f53\u7684\u76ee\u6807\u503c\u3002 \u53c2\u8003\uff1a How formulas work [Patsy](https://patsy.readthedocs.io/\uff09\u662f\u4e00\u4e2a\u7528\u4e8e\u63cf\u8ff0\u7edf\u8ba1\u6a21\u578b\uff08\u5c24\u5176\u662f\u7ebf\u6027\u6a21\u578b\uff09\u7684Python\u5e93\u3002 \u5b83\u4f7f\u7528\u4e00\u79cd\u5c0f\u578b\u57fa\u4e8e\u5b57\u7b26\u4e32\u7684\"\u516c\u5f0f\u8bed\u6cd5\"\u3002 Patsy\u80fd\u591f\u5f88\u597d\u5730\u652f\u6301 statsmodels \u4e2d\u7279\u5b9a\u7684\u7ebf\u6027\u6a21\u578b\u3002 \u50cf y ~ x0 + x1 \u8fd9\u79cd a + b \u7684\u8bed\u6cd5\u5e76\u4e0d\u4ee3\u8868\u5c06 a \u548c b \u76f8\u52a0\uff0c\u800c\u662f\u4ee3\u8868\u4e3a\u6a21\u578b\u521b\u5efa\u7684\u8bbe\u8ba1\u77e9\u9635\u7684\u672f\u8bed\uff08terms in the design matrix\uff09\u3002 patsy.dmatrices \u51fd\u6570\uff0c\u53d6\u4e00\u4e2a\u516c\u5f0f\u5b57\u7b26\u4e32\u548c\u4e00\u4e2a\u6570\u636e\u96c6\uff08\u53ef\u4ee5\u4f7fDataFrame\u6216dict\uff09\uff0c\u7136\u540e\u4e3a\u7ebf\u6027\u6a21\u578b\u4ea7\u751f\u8bbe\u8ba1\u77e9\u9635\uff1a import pandas as pd import numpy as np import patsy from patsy import dmatrices, dmatrix, demo_data df = pd.DataFrame( { 'x0': [1, 2, 3, 4, 5], 'x1': [0.01, -0.01, 0.25, -4.1, 0.], 'y': [-1.5, 0., 3.6, 1.3, -2.] } ) print(df) # x0 x1 y # 0 1 0.01 -1.5 # 1 2 -0.01 0.0 # 2 3 0.25 3.6 # 3 4 -4.10 1.3 # 4 5 0.00 -2.0 y, X = patsy.dmatrices('y ~ x0 + x1', df) print(y) # [[-1.5] # [ 0. ] # [ 3.6] # [ 1.3] # [-2. ]] print(X) # [[ 1. 1. 0.01] # [ 1. 2. -0.01] # [ 1. 3. 0.25] # [ 1. 4. -4.1 ] # [ 1. 5. 0. ]] print(np.asarray(y)) # Patsy\u7684DesignMatrix\u5b9e\u4f8b\uff0c\u542b\u6709\u9644\u52a0\u5143\u6570\u636e\u7684NumPy.ndarray # [[-1.5] # [ 0. ] # [ 3.6] # [ 1.3] # [-2. ]] print(np.asarray(X)) # Patsy\u7684DesignMatrix\u5b9e\u4f8b\uff0c\u542b\u6709\u9644\u52a0\u5143\u6570\u636e\u7684NumPy.ndarray # [[ 1. 1. 0.01] # [ 1. 2. -0.01] # [ 1. 3. 0.25] # [ 1. 4. -4.1 ] # [ 1. 5. 0. ]] \u4e0a\u9762X\u8f93\u51fa\u4e2d\u7684Intercept(\u6700\u5de6\u8fb9\u4e00\u5217)\u662f\u4ece\u54ea\u91cc\u6765\u7684\u3002 \u8fd9\u5176\u5b9e\u662f\u7ebf\u6027\u6a21\u578b\u7684\u4e00\u4e2a\u60ef\u4f8b\uff0c\u6bd4\u5982\u666e\u901a\u6700\u5c0f\u4e8c\u4e58\u56de\u5f52\u6cd5\uff08ordinary least squares regression\uff09\u3002 \u53ef\u4ee5\u53bb\u6389\u8fd9\u4e2a\u622a\u8ddd\uff08intercept\uff09\uff0c\u901a\u8fc7 y ~ x0 + x1 + 0 \u7ed9\u6a21\u578b\u3002 y, X = patsy.dmatrices('y ~ x0 + x1 + 0', df) print(X) # [[ 1. 0.01] # [ 2. -0.01] # [ 3. 0.25] # [ 4. -4.1 ] # [ 5. 0. ]] \u8fd9\u79cdPatsy\u5bf9\u8c61\u53ef\u4ee5\u76f4\u63a5\u4f20\u5165\u4e00\u4e2a\u7b97\u6cd5\uff0c\u6bd4\u5982 numpy.linalg.lstsq \uff0c\u6765\u8fdb\u884c\u666e\u901a\u6700\u5c0f\u4e8c\u4e58\u56de\u5f52\u7684\u8ba1\u7b97 coef, resid, _, _ =np.linalg.lstsq(X, y, rcond=1) # \u6700\u5c0f\u4e8c\u4e58\u6cd5 print(coef) # [[ 0.00925424] # [-0.25485421]] print(resid) # [19.72552896] coef = pd.Series(coef.squeeze(), index=X.design_info.column_names) print(coef) # x0 0.009254 # x1 -0.254854 # dtype: float64","title":"\u4f7f\u7528Patsy\u521b\u5efa\u6a21\u578b\u63cf\u8ff0"},{"location":"python/DataAnalysis/ch11/#patsy_1","text":"\u53ef\u4ee5\u5c06Python\u4ee3\u7801\u6df7\u5408\u5230\u4f60\u7684Patsy\u516c\u5f0f\u4e2d\uff0c\u5728\u6267\u884c\u516c\u5f0f\u65f6\uff0cPatsy\u5e93\u5c06\u5c1d\u8bd5\u5728\u5c01\u95ed\u4f5c\u7528\u57df\u4e2d\u5bfb\u627e\u4f60\u4f7f\u7528\u7684\u51fd\u6570\uff1a y, X = patsy.dmatrices('y ~ x0 + np.log(np.abs(x1) +1)', df) print(X) # [[1. 1. 0.00995033] # [1. 2. 0.00995033] # [1. 3. 0.22314355] # [1. 4. 1.62924054] # [1. 5. 0. ]] \u4e00\u4e9b\u5e38\u7528\u7684\u53d8\u91cf\u53d8\u6362\uff0c\u5305\u62ec\u6807\u51c6\u5316\uff08standardizing (\u5e73\u5747\u503c0\uff0c\u65b9\u5dee1\uff09\u548c\u4e2d\u5fc3\u5316\uff08\u51cf\u53bb\u5e73\u5747\u503c\uff09\u3002Patsy\u6709\u5185\u5efa\u7684\u51fd\u6570\u53ef\u4ee5\u505a\u5230\u8fd9\u4e9b\u3002 y, X = patsy.dmatrices('y ~ standardize(x0) + center(x1)', df) print(X) # [[ 1. -1.41421356 0.78 ] # [ 1. -0.70710678 0.76 ] # [ 1. 0. 1.02 ] # [ 1. 0.70710678 -3.33 ] # [ 1. 1.41421356 0.77 ]] \u4f5c\u4e3a\u5efa\u6a21\u7684\u4e00\u90e8\u5206\uff0c\u6211\u4eec\u53ef\u80fd\u4f1a\u5728\u4e00\u4e2a\u6570\u636e\u53ca\u4e0a\u8bad\u7ec3\u6a21\u578b\uff0c\u7136\u540e\u5728\u53e6\u4e00\u4e2a\u6570\u636e\u53ca\u4e0a\u8bc4\u4ef7\u6a21\u578b\u3002 \u5f53\u4f7f\u7528\u4e2d\u5fc3\u5316\u6216\u6807\u51c6\u5316\u8fd9\u6837\u7684\u8f6c\u6362\u65f6\uff0c\u6211\u4eec\u5fc5\u987b\u6ce8\u610f\uff0c\u5fc5\u987b\u7528\u6a21\u578b\u5728\u65b0\u6570\u636e\u96c6\u4e0a\u505a\u9884\u6d4b\u3002 \u8fd9\u53eb\u505a\u72b6\u6001\u53d8\u6362\uff08stateful transformations\uff09\u3002 \u56e0\u4e3a\u6211\u4eec\u5fc5\u987b\u7528\u539f\u672c\u5728\u8bad\u7ec3\u96c6\u4e0a\u5f97\u5230\u7684\u5e73\u5747\u503c\u548c\u6807\u51c6\u5dee\uff0c\u7528\u5728\u65b0\u7684\u6570\u636e\u96c6\u4e0a\u3002 new_df = pd.DataFrame( { 'x0': [6, 7, 8, 9], 'x1': [3.1, -0.5, 0, 2.3], 'y': [1, 2, 3, 4] } ) new_X = patsy.build_design_matrices([X.design_info], new_df) print(new_X) # [DesignMatrix with shape (4, 3) # Intercept standardize(x0) center(x1) # 1 2.12132 3.87 # 1 2.82843 0.27 # 1 3.53553 0.77 # 1 4.24264 3.07 # Terms: # 'Intercept' (column 0), 'standardize(x0)' (column 1), 'center(x1)' (column 2)] \u56e0\u4e3a\u52a0\u53f7\uff08+\uff09\u5728Patsy\u516c\u5f0f\u7684\u4e0a\u4e0b\u6587\u4e2d\u5e76\u4e0d\u662f\u52a0\u6cd5\u7684\u610f\u601d\uff0c\u5f53\u60f3\u8981\u5bf9\u6570\u636e\u96c6\u4e2d\u4e24\u5217\u6309\u5217\u540d\u76f8\u52a0\u65f6\uff0c\u5fc5\u987b\u5c06\u5217\u540d\u5c01\u88c5\u5230\u7279\u6b8a\u7684I\u51fd\u6570\u4e2d\uff1a y, X = patsy.dmatrices('y ~ I(x0 + x1)', df) print(X) # [[ 1. 1.01] # [ 1. 1.99] # [ 1. 3.25] # [ 1. -0.1 ] # [ 1. 5. ]]","title":"Patsy\u516c\u5f0f\u4e2d\u7684\u6570\u636e\u8f6c\u6362"},{"location":"python/DataAnalysis/ch11/#categoricalpatsy","text":"\u975e\u6570\u503c\u578b\u6570\u636e\u53ef\u4ee5\u901a\u8fc7\u5f88\u591a\u79cd\u65b9\u5f0f\u53d8\u4e3a\u4e00\u4e2a\u6a21\u578b\u8bbe\u8ba1\u77e9\u9635\u3002 \u5f53\u6211\u4eec\u5728Patsy\u516c\u5f0f\u4e2d\u4f7f\u7528\u975e\u6570\u503c\u672f\u8bed\u65f6\uff0c\u8fd9\u4e9b\u7c7b\u578b\u6570\u636e\u9ed8\u8ba4\u4f1a\u88ab\u8f6c\u6362\u4e3a\u54d1\u53d8\u91cf\u3002\u5982\u679c\u6709\u622a\u8ddd\uff0c\u4e00\u4e2a\u5c42\u7ea7\u4e0a\u7684\u622a\u8ddd\u4f1a\u88ab\u820d\u5f03\uff0c\u9632\u6b62\u51fa\u73b0\u5171\u7ebf\u6027\u3002 data = pd.DataFrame( { 'key1': ['a', 'a', 'b', 'b', 'a', 'b', 'a', 'b'], 'key2': [0, 1, 0, 1, 0, 1, 0, 0], 'v1': [1, 2, 3, 4, 5, 6, 7, 8], 'v2': [-1, 0, 2.5, -0.5, 4., -1.2, 0.2, -1.7] } ) y, X = patsy.dmatrices('v2 ~ key1', data) print(y) # [[-1. ] # [ 0. ] # [ 2.5] # [-0.5] # [ 4. ] # [-1.2] # [ 0.2] # [-1.7]] print(X) # [[1. 0.] # [1. 0.] # [1. 1.] # [1. 1.] # [1. 0.] # [1. 1.] # [1. 0.] # [1. 1.]] \u5982\u679c\u4ece\u6a21\u578b\u4e2d\u820d\u5f03\u622a\u8ddd\uff0c\u6bcf\u4e2a\u7c7b\u578b\u7684\u5217\u4f1a\u88ab\u5305\u542b\u5728\u6a21\u578b\u8bbe\u8ba1\u77e9\u9635\u4e2d\u3002 y, X = patsy.dmatrices('v2 ~ key1 + 0', data) print(X) # [[1. 0.] # [1. 0.] # [0. 1.] # [0. 1.] # [1. 0.] # [0. 1.] # [1. 0.] # [0. 1.]] \u6570\u503c\u578b\u5217\u53ef\u4ee5\u901a\u8fc7C\u51fd\u6570\uff0c\u53d8\u4e3a\u7c7b\u578b\u5217\uff1a y, X = patsy.dmatrices('v2 ~ C(key2)', data) print(X) # [[1. 0.] # [1. 1.] # [1. 0.] # [1. 1.] # [1. 0.] # [1. 1.] # [1. 0.] # [1. 0.]] \u5f53\u6211\u4eec\u5728\u4e00\u4e2a\u6a21\u578b\u4e2d\u4f7f\u7528\u591a\u4e2a\u7c7b\u578b\u672f\u8bed\u65f6\uff0c\u4f1a\u53d8\u5f97\u66f4\u590d\u6742\u4e00\u4e9b\uff0c\u4e4b\u524d\u7528key1:key2\u7684\u5f62\u5f0f\u6765\u5305\u542b\u6709\u4ea4\u96c6\u7684\u672f\u8bed\uff0c \u8fd9\u79cd\u65b9\u6cd5\u53ef\u4ee5\u7528\u4e8e\u4f7f\u7528\u591a\u4e2a\u672f\u8bed\uff0c\u4f8b\u5982\uff0c\u4e00\u4e2a\u65b9\u6cd5\u5206\u6790\u6a21\u578b\uff08analysis of variance (ANOVA) models\uff09\uff1a data['key2'] = data['key2'].map({0: 'zero', 1: 'one'}) print(data) # key1 key2 v1 v2 # 0 a zero 1 -1.0 # 1 a one 2 0.0 # 2 b zero 3 2.5 # 3 b one 4 -0.5 # 4 a zero 5 4.0 # 5 b one 6 -1.2 # 6 a zero 7 0.2 # 7 b zero 8 -1.7 y, X = patsy.dmatrices('v2 ~ key1 + key2', data) print(X) # [[1. 0. 1.] # [1. 0. 0.] # [1. 1. 1.] # [1. 1. 0.] # [1. 0. 1.] # [1. 1. 0.] # [1. 0. 1.] # [1. 1. 1.]] y, X = patsy.dmatrices('v2 ~ key1 + key2 + key1:key2', data) print(X) # [[1. 0. 1. 0.] # [1. 0. 0. 0.] # [1. 1. 1. 1.] # [1. 1. 0. 0.] # [1. 0. 1. 0.] # [1. 1. 0. 0.] # [1. 0. 1. 0.] # [1. 1. 1. 1.]]","title":"\u5206\u7c7b\u6570\u636eCategorical\u548cPatsy"},{"location":"python/DataAnalysis/ch11/#statsmodels","text":"statsmodels \u662f\u4e00\u4e2aPython\u5e93\uff0c\u7528\u4e8e\u62df\u5408\u591a\u79cd\u7edf\u8ba1\u6a21\u578b\uff0c\u6267\u884c\u7edf\u8ba1\u6d4b\u8bd5\u4ee5\u53ca\u6570\u636e\u63a2\u7d22\u548c\u53ef\u89c6\u5316\u3002 statsmodels \u5305\u542b\u66f4\u591a\u7684\u201c\u7ecf\u5178\u201d\u9891\u7387\u5b66\u6d3e\u7edf\u8ba1\u65b9\u6cd5\uff0c\u800c\u8d1d\u53f6\u65af\u65b9\u6cd5\u548c\u673a\u5668\u5b66\u4e60\u6a21\u578b\u53ef\u5728\u5176\u4ed6\u5e93\u4e2d\u627e\u5230\u3002 \u5305\u542b\u5728statsmodels\u4e2d\u7684\u4e00\u4e9b\u6a21\u578b\uff1a \u7ebf\u6027\u6a21\u578b\uff0c\u5e7f\u4e49\u7ebf\u6027\u6a21\u578b\u548c\u9c81\u68d2\u7ebf\u6027\u6a21\u578b \u7ebf\u6027\u6df7\u5408\u6548\u5e94\u6a21\u578b \u65b9\u5dee\u5206\u6790\uff08ANOVA\uff09\u65b9\u6cd5 \u65f6\u95f4\u5e8f\u5217\u8fc7\u7a0b\u548c\u72b6\u6001\u7a7a\u95f4\u6a21\u578b \u5e7f\u4e49\u7684\u77e9\u91cf\u6cd5 import pandas as pd import statsmodels.api as sm import statsmodels.formula.api as smf import numpy as np import random","title":"statsmodels\u4ecb\u7ecd"},{"location":"python/DataAnalysis/ch11/#_1","text":"\u7edf\u8ba1\u6a21\u578b\u4e2d\u6709\u51e0\u79cd\u7ebf\u6027\u56de\u5f52\u6a21\u578b\uff0c\u4ece\u8f83\u57fa\u672c\u7684\uff08\u4f8b\u5982\uff0c\u666e\u901a\u6700\u5c0f\u4e8c\u4e58\uff09\u5230\u66f4\u590d\u6742\u7684\uff08\u4f8b\u5982\uff0c\u8fed\u4ee3\u91cd\u65b0\u52a0\u6743\u7684\u6700\u5c0f\u4e8c\u4e58\uff09\u3002 tatsmodels \u4e2d\u7684\u7ebf\u6027\u6a21\u578b\u6709\u4e24\u4e2a\u4e0d\u540c\u7684\u4e3b\u8981\u63a5\u53e3\uff0c\u8fd9\u4e9b\u63a5\u53e3\u901a\u8fc7\u8fd9\u4e9bAPI\u6a21\u5757\u5bfc\u5165\u6765\u8bbf\u95ee\uff1a \u57fa\u4e8e\u6570\u7ec4 \u57fa\u4e8e\u516c\u5f0f \u4e0b\u9762\u7684\u4f8b\u5b50\u662f\u8c03\u7528\u5df2\u77e5\u53c2\u6570beta\u7684\u6a21\u578b\u3002\u5728\u8fd9\u79cd\u60c5\u51b5\u4e0b\uff0c dnorm \u662f\u7528\u4e8e\u751f\u6210\u5177\u6709\u7279\u5b9a\u5747\u503c\u548c\u65b9\u5dee\u7684\u6b63\u6001\u5206\u5e03\u6570\u636e\u7684\u8f85\u52a9\u51fd\u6570\u3002 def dnorm (mean, variance, size=1): if isinstance(size, int): size = size, return mean + np.sqrt(variance) * np.random.randn(*size) np.random.seed(12345) N = 100 X = np.c_[ dnorm(0, 0.4, size=N), dnorm(0, 0.6, size=N), dnorm(0, 0.2, size=N) ] eps = dnorm(0, 0.1, size=N) beta = [0.1, 0.3, 0.5] y = np.dot(X, beta) + eps print(X[:5]) # [[-0.12946849 -1.21275292 0.50422488] # [ 0.30291036 -0.43574176 -0.25417986] # [-0.32852189 -0.02530153 0.13835097] # [-0.35147471 -0.71960511 -0.25821463] # [ 1.2432688 -0.37379916 -0.52262905]] print(y[:5]) # [ 0.42786349 -0.67348041 -0.09087764 -0.48949442 -0.12894109] \u7ebf\u6027\u6a21\u578b\u901a\u5e38\u4e0e\u6211\u4eec\u5728Patsy\u4e2d\u770b\u5230\u7684\u622a\u8ddd\u9879\u76f8\u5339\u914d\u3002 sm.add_constant \u51fd\u6570\u53ef\u4ee5\u5c06\u622a\u8ddd\u5217\u6dfb\u52a0\u5230\u73b0\u6709\u77e9\u9635\uff1a X_model = sm.add_constant(X) print(X_model[:5]) # [[ 1. -0.12946849 -1.21275292 0.50422488] # [ 1. 0.30291036 -0.43574176 -0.25417986] # [ 1. -0.32852189 -0.02530153 0.13835097] # [ 1. -0.35147471 -0.71960511 -0.25821463] # [ 1. 1.2432688 -0.37379916 -0.52262905]] sm.OLS \u7c7b\u53ef\u4ee5\u62df\u5408\u4e00\u4e2a\u6700\u5c0f\u4e8c\u4e58\u7ebf\u6027\u56de\u5f52\uff1a model = sm.OLS(y, X) \u6a21\u578b\u7684 fit \u65b9\u6cd5\u8fd4\u56de\u4e00\u4e2a\u56de\u5f52\u7ed3\u679c\u5bf9\u8c61\uff0c\u8be5\u5bf9\u8c61\u5305\u542b\u4e86\u4f30\u8ba1\u7684\u6a21\u578b\u53c2\u6570\u548c\u5176\u4ed6\u7684\u8bca\u65ad\uff1a results = model.fit() print(results.params) # [0.17826108 0.22303962 0.50095093] \u8c03\u7528 summary \u65b9\u6cd5\u53ef\u4ee5\u6253\u5370\u51fa\u4e00\u4e2a\u6a21\u578b\u7684\u8bca\u65ad\u7ec6\u8282\uff0c\u6b64\u5904\u7684\u53c2\u6570\u540d\u79f0\u5df2\u88ab\u8d4b\u4e88\u901a\u7528\u540d\u79f0 x1 \u3001 x2 \u7b49\uff1a print(results.summary()) # OLS Regression Results # ======================================================================================= # Dep. Variable: y R-squared (uncentered): 0.430 # Model: OLS Adj. R-squared (uncentered): 0.413 # Method: Least Squares F-statistic: 24.42 # Date: Sat, 16 Oct 2021 Prob (F-statistic): 7.44e-12 # Time: 14:21:45 Log-Likelihood: -34.305 # No. Observations: 100 AIC: 74.61 # Df Residuals: 97 BIC: 82.42 # Df Model: 3 # Covariance Type: nonrobust # ============================================================================== # coef std err t P>|t| [0.025 0.975] # ------------------------------------------------------------------------------ # x1 0.1783 0.053 3.364 0.001 0.073 0.283 # x2 0.2230 0.046 4.818 0.000 0.131 0.315 # x3 0.5010 0.080 6.237 0.000 0.342 0.660 # ============================================================================== # Omnibus: 4.662 Durbin-Watson: 0 -0.002327 # Prob(Omnibus): 0.097 Jarque-Bera (JB): 4.098 # Skew: 0.481 Prob(JB): 0.129 # Kurtosis: 3.243 Cond. No. 1.74 # ============================================================================== # # Notes: # [1] R\u00b2 is computed without centering (uncentered) since the model does not contain a constant. # [2] Standard Errors assume that the covariance matrix of the errors is correctly specified. \u5047\u8bbe\u6240\u6709\u6a21\u578b\u53c2\u6570\u90fd\u5728DataFrame\u4e2d\uff1a data = pd.DataFrame(X, columns=['col0', 'col1', 'col2']) data['y'] = y print(data[:5]) # col0 col1 col2 y # 0 -0.129468 -1.212753 0.504225 0.427863 # 1 0.302910 -0.435742 -0.254180 -0.673480 # 2 -0.328522 -0.025302 0.138351 -0.090878 # 3 -0.351475 -0.719605 -0.258215 -0.489494 # 4 1.243269 -0.373799 -0.522629 -0.128941 \u73b0\u5728\u53ef\u4ee5\u4f7f\u7528 statsmodels \u516c\u5f0fAPI\u548cPatsy\u516c\u5f0f\u5b57\u7b26\u4e32\u3002\u89c2\u5bdf statsmodels \u5982\u4f55\u5c06\u7ed3\u679c\u4f5c\u4e3a\u5e26\u6709DataFrame\u5217\u540d\u79f0\u7684Series\u8fd4\u56de\u3002 results = smf.ols('y ~ col0 + col1 + col2', data=data).fit() print(results.params) # Intercept 0.033559 # col0 0.176149 # col1 0.224826 # col2 0.514808 # dtype: float64 \u7ed9\u5b9a\u65b0\u7684\u6837\u672c\u5916\u6570\u636e\u540e\uff0c\u53ef\u4ee5\u6839\u636e\u4f30\u8ba1\u7684\u6a21\u578b\u53c2\u6570\u8ba1\u7b97\u9884\u6d4b\u503c\uff1a print(results.predict(data[:5])) # 0 -0.002327 # 1 -0.141904 # 2 0.041226 # 3 -0.323070 # 4 -0.100535 # dtype: float64","title":"\u8bc4\u4f30\u7ebf\u6027\u6a21\u578b"},{"location":"python/DataAnalysis/ch11/#_2","text":"statsmodels\u4e2d\u7684\u53e6\u4e00\u7c7b\u6a21\u578b\u7528\u4e8e\u65f6\u95f4\u5e8f\u5217\u5206\u6790\u3002\u5176\u4e2d\u5305\u62ec\u81ea\u56de\u5f52\u8fc7\u7a0b\uff0c\u5361\u5c14\u66fc\u6ee4\u6ce2\u548c\u5176\u4ed6\u72b6\u6001\u7a7a\u95f4\u6a21\u578b\uff0c\u4ee5\u53ca\u591a\u53d8\u91cf\u81ea\u56de\u5f52\u6a21\u578b\u3002 \u4e0b\u4f8b\u6a21\u62df\u4e00\u4e9b\u5177\u6709\u81ea\u56de\u5f52\u7ed3\u6784\u548c\u566a\u58f0\u7684\u65f6\u95f4\u5e8f\u5217\u6570\u636e\uff0c\u8be5\u6570\u636e\u5177\u6709\u53c2\u6570\u4e3a0.8\u548c-0.4\u7684AR\uff082\uff09\u7ed3\u6784\uff08\u4e24\u4e2a\u6ede\u540e\uff09\u3002 init_x = 4 values = [init_x, init_x] N = 1000 b0 = 0.8 b1 = -0.4 noise = dnorm(0, 0.1, N) for i in range(N): new_x = values[-1] * b0 + values[-2] * b1 + noise[i] values.append(new_x) \u5f53\u62df\u5408\u4e00\u4e2aAR\u6a21\u578b\u65f6\uff0c\u4f60\u53ef\u80fd\u4e0d\u77e5\u9053\u5305\u542b\u7684\u6ede\u540e\u9879\u7684\u6570\u91cf\uff0c\u6240\u4ee5\u53ef\u4ee5\u7528\u66f4\u5927\u7684\u6ede\u540e\u6570\u6765\u62df\u5408\u8be5\u6a21\u578b\uff1a MAXLAGS = 5 model = sm.tsa.AR(values) results = model.fit(MAXLAGS) print(results.params) # NotImplementedError: AR has been removed from statsmodels and replaced with statsmodels.tsa.ar_model.AutoReg.","title":"\u8bc4\u4f30\u65f6\u95f4\u5e8f\u5217\u5904\u7406"},{"location":"python/DataAnalysis/ch11/#sikit-learn","text":"scikit-learn\uff08http://scikit-learn.org\uff09\u662f\u4f7f\u7528\u6700\u5e7f\u6cdb\u4e14\u6700\u53d7\u4fe1\u4efb\u7684\u901a\u7528Python\u673a\u5668\u5b66\u4e60\u5e93\u3002\\ \u5b83\u5305\u542b\u5e7f\u6cdb\u7684\u6807\u51c6\u76d1\u7763\u7684\u548c\u65e0\u76d1\u7763\u7684\u673a\u5668\u5b66\u4e60\u65b9\u6cd5\uff0c\u5305\u62ec\u7528\u4e8e\u6a21\u578b\u9009\u62e9\u548c\u8bc4\u4f30\u3001\u6570\u636e\u8f6c\u6362\u3001\u6570\u636e\u52a0\u8f7d\u548c\u6a21\u578b\u6301\u4e45\u5316\u7684\u5de5\u5177\u3002\\ \u8fd9\u4e9b\u6a21\u578b\u53ef\u7528\u4e8e\u5206\u7c7b\u3001\u805a\u7c7b\u3001\u9884\u6d4b\u548c\u5176\u4ed6\u5e38\u89c1\u4efb\u52a1\u3002\\ pandas\u975e\u5e38\u9002\u5408\u5728\u6a21\u578b\u62df\u5408\u524d\u5904\u7406\u6570\u636e\u96c6\u3002 \u4e3e\u4e2a\u4f8b\u5b50\uff0c\u7528\u4e00\u4e2aKaggle\u7ade\u8d5b\u7684\u7ecf\u5178\u6570\u636e\u96c6\uff0c\u5173\u4e8e\u6cf0\u5766\u5c3c\u514b\u53f7\u4e58\u5ba2\u7684\u751f\u8fd8\u7387\u3002\u6211\u4eec\u7528pandas\u52a0\u8f7d\u6d4b\u8bd5\u548c\u8bad\u7ec3\u6570\u636e\u96c6\uff1a import pandas as pd from sklearn.linear_model import LogisticRegression from sklearn.linear_model import LogisticRegressionCV from sklearn.model_selection import cross_val_score train = pd.read_csv('../datasets/titanic/train.csv') test = pd.read_csv('../datasets/titanic/test.csv') print(train[:4]) # PassengerId Survived Pclass ... Fare Cabin Embarked # 0 1 0 3 ... 7.2500 NaN S # 1 2 1 1 ... 71.2833 C85 C # 2 3 1 3 ... 7.9250 NaN S # 3 4 1 1 ... 53.1000 C123 S \u50cfstatsmodels\u548cscikit-learn\u901a\u5e38\u4e0d\u80fd\u63d0\u4f9b\u7f3a\u5931\u6570\u636e\uff0c\u56e0\u6b64\u6211\u4eec\u8981\u68c0\u67e5\u5404\u5217\uff0c\u770b\u770b\u662f\u5426\u6709\u5305\u542b\u7f3a\u5931\u6570\u636e\uff1a print(train.isnull().sum()) # PassengerId 0 # Survived 0 # Pclass 0 # Name 0 # Sex 0 # Age 177 # SibSp 0 # Parch 0 # Ticket 0 # Fare 0 # Cabin 687 # Embarked 2 # dtype: int64 print(test.isnull().sum()) # PassengerId 0 # Pclass 0 # Name 0 # Sex 0 # Age 86 # SibSp 0 # Parch 0 # Ticket 0 # Fare 1 # Cabin 327 # Embarked 0 # dtype: int64 \u5728\u50cf\u8fd9\u6837\u7684\u7edf\u8ba1\u548c\u673a\u5668\u5b66\u4e60\u7684\u4f8b\u5b50\u4e2d\uff0c\u4e00\u4e2a\u5178\u578b\u7684\u4efb\u52a1\u662f\u6839\u636e\u6570\u636e\u4e2d\u7684\u7279\u5f81\u6765\u9884\u6d4b\u4e58\u5ba2\u662f\u5426\u80fd\u5e78\u5b58\u4e0b\u6765\u3002\\ \u5c06\u6a21\u578b\u62df\u5408\u5230\u8bad\u7ec3\u6570\u636e\u96c6\u4e0a\uff0c\u7136\u540e\u5728\u6837\u672c\u5916\u6d4b\u8bd5\u6570\u636e\u96c6\u4e0a\u8fdb\u884c\u8bc4\u4f30\u3002\\ \u5982\u679c\u7528Age\u4f5c\u4e3a\u9884\u6d4b\uff0c\u4f46\u5b83\u7f3a\u5c11\u6570\u636e\u3002\u9700\u8981\u8fdb\u884c\u7f3a\u5931\u6570\u636e\u63d2\u8865\uff08imputation\uff09\uff0c\u5e76\u4f7f\u7528\u8bad\u7ec3\u6570\u636e\u96c6\u7684\u4e2d\u95f4\u503c\u586b\u5145\u4e24\u4e2a\u8868\u4e2d\u7684\u7a7a\u503c\uff1a impute_value = train['Age'].median() train['Age'] = train['Age'].fillna(impute_value) test['Age'] = test['Age'].fillna(impute_value) \u73b0\u5728\u5efa\u7acb\u6a21\u578b\u3002\\ \u6dfb\u52a0\u4e00\u5217IsFemale\u4f5c\u4e3a\u2019Sex\u2019\u5217\u7684\u7f16\u7801\u7248\u672c\uff1a train['IsFemale'] = (train['Sex'] == 'female').astype(int) test['IsFemale'] = (test['Sex'] == 'female').astype(int) \u786e\u5b9a\u4e00\u4e9b\u6a21\u578b\u53d8\u91cf\u5e76\u521b\u5efaNumPy\u6570\u7ec4\uff1a predictors = ['Pclass', 'IsFemale', 'Age'] X_train = train[predictors].values X_test = test[predictors].values y_train = train['Survived'].values print(X_train[:5]) # [[ 3. 0. 22.] # [ 1. 1. 38.] # [ 3. 1. 26.] # [ 1. 1. 35.] # [ 3. 0. 35.]] print(y_train[:5]) # [0 1 1 1 0] \u4f7f\u7528scikit-learn\u7684LogisticRegression\u6a21\u578b\u521b\u5efa\u4e00\u4e2a\u6a21\u578b\u5b9e\u4f8b\uff1a model = LogisticRegression() \u4e0estatsmodels\u7c7b\u4f3c\uff0c\u4f7f\u7528\u6a21\u578b\u7684fit\u65b9\u6cd5\u5728\u8bad\u7ec3\u6570\u636e\u4e0a\u62df\u5408\u6a21\u578b\uff1a result = model.fit(X_train, y_train) print(result) # LogisticRegression() \u4f7f\u7528model.predict\u4e3a\u6d4b\u8bd5\u6570\u636e\u96c6\u5f62\u6210\u9884\u6d4b\uff1a y_predict = model.predict(X_test) print(y_predict[:10]) # [0 0 0 0 1 0 1 0 1 0] \u5b9e\u9645\u4e0a\uff0c\u6a21\u578b\u8bad\u7ec3\u4e2d\u7ecf\u5e38\u5b58\u5728\u8bb8\u591a\u9644\u52a0\u7684\u590d\u6742\u5c42\u6b21\u3002\\ \u8bb8\u591a\u6a21\u578b\u5177\u6709\u53ef\u4ee5\u8c03\u6574\u7684\u53c2\u6570\uff0c\u5e76\u4e14\u5b58\u5728\u53ef\u7528\u4e8e\u53c2\u6570\u8c03\u6574\u7684\u4ea4\u53c9\u9a8c\u8bc1\u7b49\u6280\u672f\u4ee5\u907f\u514d\u8fc7\u5ea6\u62df\u5408\u8bad\u7ec3\u6570\u636e\u3002\\ \u8fd9\u901a\u5e38\u53ef\u4ee5\u5728\u65b0\u6570\u636e\u4e0a\u4ea7\u751f\u66f4\u597d\u7684\u9884\u6d4b\u6027\u80fd\u6216\u7a33\u5065\u6027\u3002\u4ea4\u53c9\u9a8c\u8bc1\u901a\u8fc7\u5206\u5272\u8bad\u7ec3\u6570\u636e\u6765\u6a21\u62df\u6837\u672c\u5916\u9884\u6d4b\u3002\\ \u57fa\u4e8e\u50cf\u5747\u65b9\u8bef\u5dee\u4e4b\u7c7b\u7684\u6a21\u578b\u51c6\u786e\u5ea6\u5206\u6570\uff0c\u53ef\u4ee5\u5bf9\u6a21\u578b\u53c2\u6570\u6267\u884c\u7f51\u683c\u641c\u7d22\u3002\\ \u4e00\u4e9b\u6a21\u578b\uff0c\u5982\u903b\u8f91\u56de\u5f52\uff0c\u5177\u6709\u5185\u7f6e\u4ea4\u53c9\u9a8c\u8bc1\u7684\u4f30\u8ba1\u7c7b\u3002\\ \u4f8b\u5982\uff0cLogisticRegressionCV\u7c7b\u53ef\u4ee5\u4e0e\u4e00\u4e2a\u53c2\u6570\u4e00\u8d77\u4f7f\u7528\uff0c\u8be5\u53c2\u6570\u8868\u793a\u7f51\u683c\u641c\u7d22\u5728\u6a21\u578b\u6b63\u5219\u5316\u53c2\u6570C\u4e0a\u7684\u7ec6\u81f4\u5ea6\uff1a model_cv = LogisticRegressionCV() result = model_cv.fit(X_train, y_train) print(result) # LogisticRegressionCV() \u8981\u624b\u52a8\u8fdb\u884c\u4ea4\u53c9\u9a8c\u8bc1\uff0c\u53ef\u4ee5\u4f7f\u7528cross_val_score\u51fd\u6570\uff0c\u8be5\u51fd\u6570\u5904\u7406\u6570\u636e\u62c6\u5206\u8fc7\u7a0b\u3002\\ \u4f8b\u5982\uff0c\u4e3a\u4e86\u7528\u6211\u4eec\u7684\u6a21\u578b\u4e0e\u8bad\u7ec3\u6570\u636e\u7684\u56db\u4e2a\u975e\u91cd\u53e0\u5206\u5272\u8fdb\u884c\u4ea4\u53c9\u9a8c\u8bc1\uff0c\u53ef\u4ee5\u8fd9\u6837\u505a\uff1a model = LogisticRegression(C=10) scores = cross_val_score(model, X_train, y_train, cv=4) print(scores) # [0.77578475 0.79820628 0.77578475 0.78828829] \u9ed8\u8ba4\u8bc4\u5206\u6307\u6807\u662f\u4f9d\u8d56\u4e8e\u6a21\u578b\u7684\uff0c\u4f46\u53ef\u4ee5\u9009\u62e9\u660e\u786e\u7684\u8bc4\u5206\u51fd\u6570\u3002\u7ecf\u8fc7\u4ea4\u53c9\u9a8c\u8bc1\u7684\u6a21\u578b\u9700\u8981\u66f4\u957f\u65f6\u95f4\u7684\u8bad\u7ec3\uff0c\u4f46\u901a\u5e38\u53ef\u4ee5\u4ea7\u751f\u66f4\u597d\u7684\u6a21\u578b\u6027\u80fd\u3002","title":"sikit-learn\u4ecb\u7ecd"},{"location":"python/DataStructure/01_PythonFundmantal/","text":"1.\u57fa\u7840\u77e5\u8bc6\u56de\u987e \u00b6 1.1.\u57fa\u672c\u7a0b\u5e8f\u8981\u7d20 \u00b6 \u793a\u4f8b\u4ee3\u7801 numberguess.py \u3002 import random def main (): smaller = int ( input ( \"\u8f93\u5165\u6700\u5c0f\u503c: \" )) larger = int ( input ( \"\u8f93\u5165\u6700\u5927\u503c: \" )) myNumber = random . randint ( smaller , larger ) count = 0 while True : count += 1 userNumber = int ( input ( \"\u8f93\u5165\u4f60\u731c\u7684\u503c: \" )) if userNumber < myNumber : print ( \"\u4f60\u731c\u7684\u592a\u5c0f\uff01\" ) elif userNumber > myNumber : print ( \"\u4f60\u731c\u7684\u592a\u5927\uff01\" ) else : print ( \"\u606d\u559c\uff0c\u4f60\u5728\u7b2c\" , count , \"\u6b21\u731c\u5bf9\u4e86!\" ) break if __name__ == \"__main__\" : main () \u8fd0\u884c\u4ee3\u7801\uff1a $ python3 numberguess.py Enter the smaller number: 10 Enter the larger number: 60 Enter your guess: 50 Too large Enter your guess: 40 Too large Enter your guess: 30 Too large Enter your guess: 20 Too large Enter your guess: 10 Too small Enter your guess: 15 You\u2019ve got it in 6 tries! 1.1.1.\u62fc\u5199\u548c\u547d\u540d\u60ef\u4f8b \u00b6 \u53d8\u91cf\uff1asalary\uff0choursWorked\uff0cisAbsent \u5e38\u6570\uff1aABSOLUTE_ZERO\uff0cINTEREST_RATE \u51fd\u6570\u6216\u65b9\u6cd5\uff1aprintResults\uff0ccubeRoot\uff0cinput \u7c7b\uff1aBankAccount\uff0cSortedSet \u901a\u5e38\u7ea6\u5b9a\uff1a\u53d8\u91cf\u540d\u662f\u540d\u8bcd\u3001\u5f62\u5bb9\u8bcd\uff08\u5e03\u5c14\u503c\uff09\uff0c\u51fd\u6570\u548c\u65b9\u6cd5\u662f\u52a8\u8bcd\uff08\u8868\u793a\u52a8\u4f5c\uff09\u3001\u540d\u8bcd\u3001\u6216\u5f62\u5bb9\u8bcd\uff08\u8868\u793a\u8fd4\u56de\u7684\u503c\uff09\u3002 \u8bed\u6cd5\u5143\u7d20\uff1a Python\u4f7f\u7528\u7a7a\u767d\u7b26\uff08\u7a7a\u683c\u3001\u5236\u8868\u7b26\u3001\u6216\u6362\u884c\u7b26\uff09\u6765\u8868\u793a\u4e0d\u540c\u7c7b\u578b\u7684\u8bed\u53e5\u7684\u8bed\u6cd5\u3002 \u901a\u5e38\u7ea6\u5b9a\u4f7f\u75284\u4e2a\u7a7a\u683c\u4f5c\u4e3a\u9501\u8fdb\u5bbd\u5ea6\u3002 1.1.2.\u5b57\u7b26\u4e32 \u00b6 \u5355\u5f15\u53f7 \u53cc\u5f15\u53f7 \u6210\u5bf9\u7684\u4e09\u4e2a\u53cc\u5f15\u53f7\uff08\u591a\u884c\u6587\u672c\uff09 \u6210\u5bf9\u7684\u4e09\u4e2a\u5355\u5f15\u53f7\uff08\u591a\u884c\u6587\u672c\uff09 \u8f6c\u4e49\u5b57\u7b26 \\ \uff08\u53cd\u659c\u6760\uff09 1.1.3.\u8fd0\u7b97\u7b26\u548c\u8868\u8fbe\u5f0f \u00b6 \u6807\u51c6\u8fd0\u7b97\u7b26\uff1a + \u3001 - \u3001 * \u3001 / \u3001 % \u7b97\u672f\u8868\u8fbe\u5f0f\u662f\u7528\u6807\u51c6\u8fd0\u7b97\u7b26\u548c\u4e2d\u7f00\u8868\u793a\u6cd5 \u6bd4\u8f83\u8fd0\u7b97\u7b26\uff1a < \u3001 <= \u3001 > \u3001 >= \u3001 == \u3001 != \uff0c\u7528\u4e8e\u6bd4\u8f83\u6570\u5b57\u6216\u5b57\u7b26\u4e32\uff0c\u8fd4\u56deTrue\u6216False \u8fd0\u7b97\u7b26 == \u7528\u4e8e\u6bd4\u8f83\u6570\u636e\u7ed3\u6784\u91cc\u7684\u5185\u5bb9\uff0c\u8fd0\u7b97\u7b26 is \u7528\u4e8e\u6bd4\u8f83\u4e24\u4e2a\u5bf9\u8c61\u7684\u6807\u8bc6\u662f\u5426\u4e00\u81f4 \u903b\u8f91\u8fd0\u7b97\u7b26\uff1a and \u3001 or \u3001 not \u3002\u628a0\u3001None\u3001\u7a7a\u5b57\u7b26\u4e32\u3001\u7a7a\u5217\u8868\u7b49\u89c6\u4e3aFalse\uff0c\u5927\u591a\u6570\u5176\u4ed6\u503c\u662f\u4e3aTrue \u4e0b\u6807\u8fd0\u7b97\u7b26\uff1a [] \uff0c\u4e0e\u591a\u9879\u96c6collection\u5bf9\u8c61\u4e00\u8d77\u4f7f\u7528 \u9009\u62e9\u5668\u8fd0\u7b97\u7b26\uff1a . \uff0c\u7528\u4e8e\u5f15\u7528\u4e00\u4e2a\u6a21\u5757\u3001\u7c7b\u6216\u5bf9\u8c61\u4e2d\u7684\u4e00\u4e2a\u5177\u540d\u7684\u9879 \u8fd0\u7b97\u7b26\u4f18\u5148\u7ea7\uff0c\u4f9d\u6b21\u662f\u9009\u62e9\u8fd0\u7b97\u7b26\u3001\u51fd\u6570\u8c03\u7528\u8fd0\u7b97\u7b26\u3001\u4e0b\u6807\u8fd0\u7b97\u7b26\u3001\u7b97\u672f\u8fd0\u7b97\u7b26\u3001\u6bd4\u8f83\u8fd0\u7b97\u7b26\u3001\u903b\u8f91\u8fd0\u7b97\u7b26\u3001\u8d4b\u503c\u8fd0\u7b97\u7b26\u3002\u62ec\u53f7\u7528\u4e8e\u8ba9\u5b50\u8868\u8fbe\u5f0f\u4f18\u5148\u8fd0\u884c\u3002 1.1.4.\u51fd\u6570\u8c03\u7528 \u00b6 \u51fd\u6570\u540d\u79f0\u540e\u9762\u8ddf\u7740\u7528\u62ec\u53f7\u62ec\u8d77\u6765\u7684\u53c2\u6570\u5217\u8868\uff0c\u4f8b\u5982\uff1a min(5,2) \u6807\u51c6\u51fd\u6570 \u5176\u4ed6\u6a21\u5757\u5bfc\u5165\u51fd\u6570 1.1.5.print\u51fd\u6570 \u00b6 \u81ea\u52a8\u4e3a\u6bcf\u4e2a\u53c2\u6570\u8fd0\u884c str \u51fd\u6570\uff0c\u4ee5\u5f97\u5230\u5176\u5b57\u7b26\u4e32\u8868\u793a \u5728\u8f93\u51fa\u4e4b\u524d\u4f1a\u7528\u7a7a\u683c\u5427\u6bcf\u4e2a\u5b57\u7b26\u4e32\u9694\u5f00 \u9ed8\u8ba4\u4ee5\u6362\u884c\u7b26\u4f5c\u4e3a\u7ed3\u675f 1.1.6.input\u51fd\u6570 \u00b6 \u6807\u51c6\u8f93\u5165\u51fd\u6570input\u4f1a\u4e00\u76f4\u7b49\u5f85\u7528\u6237\u901a\u8fc7\u952e\u76d8\u8f93\u5165\u6587\u672c \u63a5\u53d7\u4e00\u4e2a\u53ef\u9009\u7684\u5b57\u7b26\u4e32\u4f5c\u4e3a\u5176\u53c2\u6570 1.1.7.\u7c7b\u578b\u8f6c\u6362\u51fd\u6570\u548c\u6df7\u5408\u6a21\u5f0f\u64cd\u4f5c \u00b6 Python\u5141\u8bb8\u7b97\u672f\u8868\u8fbe\u5f0f\u4e2d\u7684\u64cd\u4f5c\u6570\u5177\u6709\u4e0d\u540c\u7684\u6570\u503c\u7c7b\u578b\u3002\u4f8b\u5982\uff0c\u628aint\u7c7b\u578b\u7684\u64cd\u4f5c\u6570\u548cfloat\u7c7b\u578b\u7684\u64cd\u4f5c\u6570\u76f8\u52a0\uff0c\u4f1a\u5f97\u5230float\u7c7b\u578b\u7684\u6570\u3002 # \u8f93\u5165\u534a\u5f84\u6c42\u5706\u9762\u79ef radius = float ( input ( \"Radius: \" )) print ( \"The area is\" , 3.14 * radius ** 2 ) 1.1.8.\u53ef\u9009\u548c\u5173\u952e\u5b57\u51fd\u6570\u53c2\u6570 \u00b6 \u5fc5\u9009\u53c2\u6570\u662f\u6ca1\u6709\u9ed8\u8ba4\u503c\u7684\uff1b\u53ef\u9009\u53c2\u6570\u6709\u9ed8\u8ba4\u503c\uff1b \u5728\u8c03\u7528\u51fd\u6570\u65f6\uff0c\u4f20\u9012\u7ed9\u5b83\u7684\u53c2\u6570\u6570\u91cf\u5fc5\u987b\u81f3\u5c11\u548c\u5fc5\u9009\u53c2\u6570\u7684\u6570\u91cf\u76f8\u540c\u3002 \u6807\u51c6\u51fd\u6570\u548cPython\u7684\u5e93\u51fd\u6570\u5728\u8c03\u7528\u65f6\u90fd\u4f1a\u5bf9\u4f20\u5165\u7684\u53c2\u6570\u8fdb\u884c\u7c7b\u578b\u68c0\u67e5 1.1.9.\u53d8\u91cf\u548c\u8d4b\u503c\u8bed\u53e5 \u00b6 \u7b80\u5355\u7684\u8d4b\u503c\u8bed\u53e5 PI = 3.1416 \u591a\u53d8\u91cf\u8d4b\u503c minValue, maxValue = 1, 100 \u53d8\u91cf\u4ea4\u6362 a, b = b, a \u8d4b\u503c\u8bed\u53e5\u5fc5\u987b\u5199\u5728\u4e00\u884c\u4ee3\u7801\u91cc\uff0c\u4f46\u662f\u53ef\u4ee5\u5728\u9017\u53f7\u3001\u5706\u62ec\u53f7\u3001\u82b1\u62ec\u53f7\u6216\u65b9\u62ec\u53f7\u4e4b\u540e\u6362\u884c\uff0c\u6216\u8005\u7528\u8f6c\u4e49\u7b26 \\ \u8fdb\u884c\u6362\u884c\u3002 \u6362\u884c\u793a\u4f8b\uff1a minValue = min ( 100 , 200 ) product = max ( 100 , 200 ) \\ * 30 1.1.10.\u6570\u636e\u7c7b\u578b \u00b6 \u53d8\u91cf\u90fd\u53ef\u4ee5\u88ab\u6307\u5b9a\u4e3a\u4efb\u4f55\u7c7b\u578b\u7684\u503c\u3002\u8fd9\u4e9b\u53d8\u91cf\u5e76\u4e0d\u50cf\u5176\u4ed6\u8bed\u8a00\u90a3\u6837\u88ab\u58f0\u660e\u4e3a\u7279\u5b9a\u7684\u7c7b\u578b\uff0c\u800c\u53ea\u662f\u88ab\u8d4b\u4e86\u4e00\u4e2a\u503c \u503c\u548c\u5bf9\u8c61\u90fd\u662f\u6709\u7c7b\u578b\u7684\uff0c\u4f1a\u5728\u8fd0\u884c\u65f6\u8fdb\u884c\u6570\u636e\u7c7b\u578b\u68c0\u67e5 1.1.11. import \u8bed\u53e5 \u00b6 import \u8bed\u53e5\u4f7f\u5f97\u4e00\u4e2a\u6a21\u5757\u4e2d\u7684\u6807\u8bc6\u7b26\u53ef\u4ee5\u88ab\u53e6\u4e00\u4e2a\u7a0b\u5e8f\u6240\u89c1\u5230\u3002\u6807\u8bc6\u7b26\u53ef\u4ee5\u662f\u5bf9\u8c61\u540d\u3001\u51fd\u6570\u540d\u6216\u7c7b\u540d \u5bfc\u5165\u6a21\u5757\u540d\u79f0\uff0c\u4f8b\u5982 import math \u5bfc\u5165\u6a21\u5757\u4e2d\u7684\u6807\u8bc6\u7b26\uff0c\u4f8b\u5982\uff1a from math import sqrt \uff0c\u6216\u8005 from math import pi, sqrt \u4e5f\u53ef\u4ee5\u4f7f\u7528\u7b26\u53f7 * \u5bfc\u5165\u4e00\u4e2a\u6a21\u5757\u4e2d\u7684\u6240\u6709\u540d\u79f0\uff0c\u4f46\u4e0d\u63a8\u8350 1.2.\u63a7\u5236\u8bed\u53e5 \u00b6 1.2.1.\u6761\u4ef6\u8bed\u53e5 \u00b6 \u5355\u5411if\u8bed\u53e5\u7684\u8bed\u6cd5 if < Boolean expression > : < sequence of statements > \u53cc\u5411if\u8bed\u53e5\u7684\u8bed\u6cd5 if < Boolean expression > : < sequence of statements > else : < sequence of statements > \u591a\u5411if\u8bed\u53e5\u7684\u8bed\u6cd5 if < Boolean expression > : < sequence of statements > elif < Boolean expression > : < sequence of statements > ... else : < sequence of statements > 1.2.2.\u4f7f\u7528if name == \" main \" \u00b6 \u793a\u4f8b\u4ee3\u7801 numberguess.py \u3002 import random def main (): smaller = int ( input ( \"\u8f93\u5165\u6700\u5c0f\u503c: \" )) larger = int ( input ( \"\u8f93\u5165\u6700\u5927\u503c: \" )) myNumber = random . randint ( smaller , larger ) count = 0 while True : count += 1 userNumber = int ( input ( \"\u8f93\u5165\u4f60\u731c\u7684\u503c: \" )) if userNumber < myNumber : print ( \"\u4f60\u731c\u7684\u592a\u5c0f\uff01\" ) elif userNumber > myNumber : print ( \"\u4f60\u731c\u7684\u592a\u5927\uff01\" ) else : print ( \"\u606d\u559c\uff0c\u4f60\u5728\u7b2c\" , count , \"\u6b21\u731c\u5bf9\u4e86!\" ) break if __name__ == \"__main__\" : main () \u4e0a\u9762\u7684if\u8bed\u53e5\u7684\u4f5c\u7528\u662f\uff0c \u8981\u4e48\u5c06\u6a21\u5757\u5f53\u4f5c\u4e00\u4e2a\u72ec\u7acb\u7684\u7a0b\u5e8f\u8fd0\u884c\uff0c\u8be5\u6a21\u5757\u7684 _name_ \u53d8\u91cf\u4f1a\u8bbe\u7f6e\u4e3a\u5b57\u7b26\u4e32 _main_ \uff0c\u624d\u4f1a\u6267\u884c main() \u51fd\u6570 \u8981\u4e48\u4ece\u53e6\u4e00\u4e2a\u6a21\u5757\u4e2d\u5bfc\u5165\uff0c\u8be5\u6a21\u5757\u7684 _name_ \u53d8\u91cf\u4f1a\u8bbe\u7f6e\u8be5\u6a21\u5757\u7684\u540d\u79f0\uff0c\u4e0a\u4f8b\u4e2d\u5373 numberguess 1.2.3.\u5faa\u73af\u8bed\u53e5 \u00b6 \u901a\u5e38\uff1a \u4e00\u822c\u4f1a\u4f7f\u7528for\u5faa\u73af\u6765\u8fed\u4ee3\u786e\u5b9a\u8303\u56f4\u7684\u503c\u6216\u503c\u7684\u5e8f\u5217 \u5982\u679c\u7ee7\u7eed\u5faa\u73af\u7684\u6761\u4ef6\u662f\u67d0\u4e2a\u5e03\u5c14\u8868\u8fbe\u5f0f\uff0c\u4e00\u822c\u4f1a\u4f7f\u7528while\u5faa\u73af while \u8bed\u6cd5\u683c\u5f0f\uff1a while < Boolean expression > : < sequence of statements > \u793a\u4f8b\uff1a # \u8ba1\u7b97\u4ece1\u523010\u7684\u4e58\u79ef\u5e76\u8f93\u51fa\u7ed3\u679c result = 1 value = 1 while value <= 10 : result *= value value += 1 print ( result , value ) # \u8fd0\u884c\u7ed3\u679c # 3628800 11 for \u8bed\u6cd5\u683c\u5f0f\uff1a for < variable > in < iterable object > : < sequence of statements > \u793a\u4f8b\uff1a # \u8ba1\u7b97\u4ece1\u523010\u7684\u4e58\u79ef\u5e76\u8f93\u51fa\u7ed3\u679c result = 1 value = 1 for value in range ( 1 , 11 ): result *= value value += 1 print ( result , value ) # \u8fd0\u884c\u7ed3\u679c # 3628800 11 1.3.\u5b57\u7b26\u4e32\u53ca\u5176\u8fd0\u7b97 \u00b6 Python\u4e2d\u7684\u5b57\u7b26\u4e32\u4e5f\u662f\u4e00\u4e2a\u590d\u5408\u5bf9\u8c61 Python\u7684\u5b57\u7b26\u4e32\u7c7b\u578b\u540d\u4e3a str \u7ea6\u5b9a\uff1a \u628a\u5355\u5b57\u7b26\u7684\u5b57\u7b26\u4e32\u7528\u5355\u5f15\u53f7\u62ec\u8d77\u6765 \u628a\u591a\u5b57\u7b26\u7684\u5b57\u7b26\u4e32\u7528\u53cc\u5f15\u53f7\u62ec\u8d77\u6765 1.3.1.\u8fd0\u7b97\u7b26 \u00b6 \u6bd4\u8f83\u8fd0\u7b97\u7b26\uff0c\u662f\u6309\u7167ASCII\u7801\u7684\u987a\u5e8f\u6bd4\u8f83\u4e24\u4e2a\u5b57\u7b26\u4e32\u4e2d\u6bcf\u4e2a\u4f4d\u7f6e\u7684\u5b57\u7b26\u5bf9 \u793a\u4f8b\uff1a print ( 'A' > 'a' ) # \u8fd0\u884c\u7ed3\u679c False print ( 'A' < 'a' ) # \u8fd0\u884c\u7ed3\u679c True + \u8fd0\u7b97\u7b26\u751f\u6210\u5e76\u8fd4\u56de\u4e00\u4e2a\u5305\u542b\u4e24\u4e2a\u64cd\u4f5c\u6570\u7684\u65b0\u5b57\u7b26\u4e32 \u793a\u4f8b\uff1a print ( \"Hello\" + \"Python\" ) # \u8fd0\u884c\u7ed3\u679c HelloPython \u4e0b\u6807\u8fd0\u7b97\u7b26\uff0c\u8303\u56f4\u662f\u4ece0\u5230\u5b57\u7b26\u4e32\u7684\u957f\u5ea6\u51cf\u53bb1\u7684\u4e00\u4e2a\u6574\u6570\u3002 \u8fd0\u7b97\u7b26\u8fd4\u56de\u5728\u5b57\u7b26\u4e32\u4e2d\u8be5\u4f4d\u7f6e\u7684\u5b57\u7b26\u3002 \u793a\u4f8b\uff1a print ( \"Greater\" [ 1 ]) # \u8fd0\u884c\u7ed3\u679c\uff1ar \u5f53\u7d22\u5f15\u4e3a\u8d1f\u503c\u65f6\uff0cPython\u4f1a\u628a\u8fd9\u4e2a\u503c\u548c\u5b57\u7b26\u4e32\u7684\u957f\u5ea6\u76f8\u52a0\uff0c\u4ee5\u786e\u5b9a\u8981\u8fd4\u56de\u7684\u5b57\u7b26\u7684\u4f4d\u7f6e\u3002\u8d1f\u7d22\u5f15\u503c\u4e0d\u5f97\u5c0f\u4e8e\u5b57\u7b26\u4e32\u957f\u5ea6\u7684\u8d1f\u503c\u3002 print ( \"Greater\" [ - 3 ]) # \u8fd0\u884c\u7ed3\u679c\uff1at print ( \"Greater\" [ - 9 ]) # \u8fd0\u884c\u7ed3\u679c\uff1aIndexError: string index out of range \u5207\u7247\u8fd0\u7b97\u7b26\uff08slice operator\uff09\uff0c\u4e0b\u6807\u8fd0\u7b97\u7b26\u7684\u4e00\u79cd\u53d8\u4f53\u3002 \u8bed\u6cd5\u683c\u5f0f\uff1a [:] \uff1a\u8303\u56f4\u662f\u4ece0\u5230\u5b57\u7b26\u4e32\u7684\u957f\u5ea6\u51cf\u53bb1\u7684\u6574\u6570 \uff1a\u8303\u56f4\u662f\u4ece0\u5230\u5b57\u7b26\u4e32\u7684\u957f\u5ea6\u7684\u6574\u6570 \u5207\u7247\u68c0\u7d22\u89c4\u5219\uff1a \u8fd4\u56de\u8fd9\u6837\u4e00\u4e2a\u5b50\u5b57\u7b26\u4e32\uff1a\u8fd9\u4e2a\u5b50\u5b57\u7b26\u4e32\u4f1a\u4ece \u7d22\u5f15\u5904\u7684\u5b57\u7b26\u5f00\u59cb\uff0c\u5230 \u7d22\u5f15\u51cf1\u7684\u4f4d\u7f6e\u4f5c\u4e3a\u7ed3\u675f\u3002 \u5982\u679c\u7701\u7565 \u7d22\u5f15\uff0c\u90a3\u4e48\u5207\u7247\u8fd0\u7b97\u7b26\u5c06\u8fd4\u56de\u4e00\u4e2a\u4ee5\u5f53\u524d\u5b57\u7b26\u4e32\u7684\u7b2c\u4e00\u4e2a\u5b57\u7b26\u4f5c\u4e3a\u5f00\u5934\u7684\u5b50\u5b57\u7b26\u4e32\u3002 \u5982\u679c\u7701\u7565 \u7d22\u5f15\uff0c\u90a3\u4e48\u5207\u7247\u8fd0\u7b97\u7b26\u5c06\u8fd4\u56de\u4e00\u4e2a\u4ee5\u5f53\u524d\u5b57\u7b26\u4e32\u7684\u6700\u540e\u4e00\u4e2a\u5b57\u7b26\u4f5c\u4e3a\u7ed3\u5c3e\u7684\u5b50\u5b57\u7b26\u4e32\u3002 \u5982\u679c\u7701\u7565\u8fd9\u4e24\u4e2a\u503c\uff0c\u90a3\u4e48\u5207\u7247\u8fd0\u7b97\u7b26\u4f1a\u8fd4\u56de\u6574\u4e2a\u5b57\u7b26\u4e32\u3002 \u793a\u4f8b\uff1a print ( \"Greater\" [:]) # \u8fd4\u56de\u5b57\u4e32 Greater print ( \"Greater\" [ 2 :]) # \u8fd4\u56de\u5b57\u4e32 eater print ( \"Greater\" [: 2 ]) # \u8fd4\u56de\u5b57\u4e32 Gr print ( \"Greater\" [ 2 : 5 ]) # \u8fd4\u56de\u5b57\u4e32 eat 1.3.2.\u5b57\u7b26\u4e32\u683c\u5f0f\u5316 \u00b6 \u683c\u5f0f\u5316\u5b57\u7b26\u4e32\u91cc\u7684\u6570\u636e\u5b57\u7b26\u4ee5\u53ca\u6ee1\u8db3\u7ed9\u5b9a\u57fa\u51c6\u7ebf\u7684\u9644\u52a0\u7a7a\u683c\u7684\u603b\u6570\u79f0\u4e3a\u5b83\u7684\u5b57\u6bb5\u5bbd\u5ea6\uff08field width\uff09\u3002 print \u51fd\u6570\u4f1a\u5728\u9047\u5230\u7b2c\u4e00\u5217\u65f6\u81ea\u52a8\u5f00\u59cb\u6253\u5370\u8f93\u51fa\u57fa\u51c6\u7ebf\u3002 \u793a\u4f8b\uff0c\u901a\u8fc7print\u8bed\u53e5\u8f93\u51fa2\u5217\u3002 for i in range ( 7 , 11 ): print ( i , 10 * i ) # \u8fd0\u884c\u7ed3\u679c # 7 70 # 8 80 # 9 90 # 10 100 Python\u7684\u901a\u7528\u683c\u5f0f\u5316\u673a\u5236 \u8bed\u6cd5\u683c\u5f0f % \u548c % (, \u2026, ) \u3002 \u683c\u5f0f\u5316\u5b57\u7b26\u4e32\u65f6\uff0c \u4f7f\u7528 %s \u8868\u793a\u6cd5\u3002\u5f53\u5b57\u6bb5\u5bbd\u5ea6\u4e3a\u6b63\u65f6\uff0c\u6570\u636e\u662f\u53f3\u5bf9\u9f50\u7684\uff1b\u5f53\u5b57\u6bb5\u5bbd\u5ea6\u4e3a\u8d1f\u65f6\uff0c\u6570\u636e\u662f\u5de6\u5bf9\u9f50\u7684\u3002 \u683c\u5f0f\u6574\u6570\u65f6\uff0c \u4f7f\u7528 %d \u8868\u793a\u6cd5\u3002 \u683c\u5f0f\u6d6e\u70b9\u6570\u65f6\uff0c \u4f7f\u7528 %.f \u8868\u793a\u6cd5\uff0c\u5176\u4e2d . \u8fd9\u4e00\u90e8\u5206\u662f\u53ef\u9009\u7684\u3002 \u793a\u4f8b\uff1a print ( \" %6s \" % \"four\" ) print ( \" %-6s \" % \"four\" ) # four # four for i in range ( 7 , 11 ): print ( \" %-3d%5d \" % ( i , 10 * i )) # 7 70 # 8 80 # 9 90 # 10 100 for i in range ( 7 , 11 ): print ( \" %-3d%5.3f \" % ( i , i / 3 )) # 7 2.333 # 8 2.667 # 9 3.000 # 10 3.333 \u4e0b\u4f8b\u5bf9\u6bd4\u4e86\u6d6e\u70b9\u6570\u5728\u4f7f\u7528\u4e86\u683c\u5f0f\u5b57\u7b26\u4e32\u548c\u6ca1\u6709\u4f7f\u7528\u683c\u5f0f\u5b57\u7b26\u4e32\u8fd9\u4e24\u79cd\u60c5\u51b5\u4e0b\u7684\u8f93\u51fa\u5dee\u5f02\u3002 salary = 100.00 print ( \"Salary: $\" + str ( salary )) # Salary: $100.0 print ( \"Salary: $ %0.2f \" % salary ) # Salary: $100.00 \u6ce8\u610f\uff0c\u4e0b\u4f8b\u4e2dPython\u7ed9\u6570\u5b57\u6dfb\u52a0\u4e86\u4e00\u4e2a\u7cbe\u5ea6\u4f4d\u6570\uff0c\u5e76\u4e14\u5176\u5de6\u4fa7\u586b\u5145\u7a7a\u683c\uff0c\u4ece\u800c\u5b9e\u73b0\u4e86\u5b57\u6bb5\u5bbd\u5ea6\u4e3a6\u3001\u7cbe\u5ea6\u4e3a3\u7684\u8bbe\u7f6e\u3002\u8fd9\u4e2a\u5bbd\u5ea6\u5305\u542b\u5c0f\u6570\u70b9\u540e\u6240\u5360\u636e\u7684\u4f4d\u7f6e\u3002 print ( \" %6.3f \" % 3.14 ) # \u5de6\u4fa7\u586b\u5145\u4e86\u7a7a\u683c # 3.140 print ( \" %-6.3f \" % 3.14 ) # 3.140 1.3.3.\u5bf9\u8c61\u548c\u65b9\u6cd5\u8c03\u7528 \u00b6 \u8bed\u6cd5\u683c\u5f0f\uff1a .() \u793a\u4f8b\uff1a print ( \"greater\" . isupper ()) # \u8fd0\u884c\u7ed3\u679c # False print ( \"greater\" . upper ()) # \u8fd0\u884c\u7ed3\u679c # GREATER print ( \"greater\" . startswith ( \"great\" )) # \u8fd0\u884c\u7ed3\u679c # True print ( len ( \"greater\" )) print ( \"greater\" . __len__ ()) # \u8fd0\u884c\u7ed3\u679c # 7 print ( \"great\" + \"er\" ) print ( \"great\" . __add__ ( \"er\" )) # \u8fd0\u884c\u7ed3\u679c # greater print ( \"e\" in \"great\" ) print ( \"great\" . __contains__ ( \"e\" )) # \u8fd0\u884c\u7ed3\u679c # True \u63d0\u793a\uff1a dir() \u65b9\u6cd5\u4f1a\u8fd4\u56de\u6240\u4f20\u9012\u7684\u5bf9\u8c61\u7684\u6709\u6548\u5c5e\u6027\uff0c\u8bed\u6cd5\u683c\u5f0f\uff1a dir(object) help() \u51fd\u6570\u67e5\u770b\u51fd\u6570\u6216\u6a21\u5757\u7528\u9014\u7684\u8be6\u7ec6\u8bf4\u660e\uff0c\u8bed\u6cd5\u683c\u5f0f\uff1a help(object) dir ( str ) help ( str . __contains__ ) 1.4.\u5185\u7f6e\u591a\u9879\u96c6\u53ca\u5176\u64cd\u4f5c \u00b6 Python\u4e2d\u7684\u591a\u9879\u96c6\uff08collections\uff09\u6307\u80fd\u591f\u5305\u542b\u5143\u7d20\u7684\u6570\u636e\u7ed3\u6784\u3002\u591a\u9879\u96c6\u6a21\u5757\u63d0\u4f9b\u4e86\u4e0d\u540c\u7c7b\u578b\u7684\u5bb9\u5668\u3002\u5bb9\u5668\u662f\u7528\u4e8e\u5b58\u50a8\u4e0d\u540c\u5bf9\u8c61\u5e76\u63d0\u4f9b\u8bbf\u95ee\u6240\u5305\u542b\u5bf9\u8c61\u4ee5\u53ca\u5bf9\u5b83\u4eec\u8fdb\u884c\u8fed\u4ee3\u7684\u65b9\u5f0f\u7684\u5bf9\u8c61\u3002\u4e00\u4e9b\u5185\u7f6e\u7684\u5bb9\u5668\u6709\u5143\u7ec4\uff08Tuple\uff09\u3001\u5217\u8868\uff08List\uff09\u3001\u5b57\u5178\uff08Dictionary\uff09\u7b49\u3002 \u4ee5\u4e0b\u662f\u7531collections\u6a21\u5757\u63d0\u4f9b\u7684\u4e0d\u540c\u5bb9\u5668\u7684\u5217\u8868\uff1a \u8ba1\u6570\u5668\uff08Counters\uff09 \u6709\u5e8f\u5b57\u5178\uff08OrderedDict\uff09 \u9ed8\u8ba4\u5b57\u5178\uff08DefaultDict\uff09 \u94fe\u6620\u5c04\uff08ChainMap\uff09 \u547d\u540d\u5143\u7ec4\uff08NamedTuple\uff09 \u53cc\u5411\u961f\u5217\uff08DeQue\uff09 \u7528\u6237\u5b57\u5178\uff08UserDict\uff09 \u7528\u6237\u5217\u8868\uff08UserList\uff09 \u7528\u6237\u5b57\u7b26\u4e32\uff08UserString\uff09 1.4.1.\u5217\u8868 \u00b6 \u5217\u8868\uff08list\uff09\u662f\u96f6\u4e2a\u6216\u591a\u4e2aPython\u5bf9\u8c61\u7684\u4e00\u4e2a\u5e8f\u5217\uff0c\u8fd9\u4e9b\u5bf9\u8c61\u901a\u5e38\u79f0\u4e3a\u9879\uff08item\uff09\u3002 \u5217\u8868\u7684\u8868\u73b0\u5f62\u5f0f\u662f\uff1a\u7528\u65b9\u62ec\u53f7\u62ec\u8d77\u6574\u4e2a\u5217\u8868\uff0c\u5e76\u7528\u9017\u53f7\u5206\u9694\u5143\u7d20\u3002 \u793a\u4f8b\uff1a [] # \u7a7a\u5217\u8868 [ \"greater\" , \"less\" , 10 ] # \u542b\u4e0d\u540c\u7c7b\u578b\u7684\u5217\u8868 [ \"greater\" , [ \"less\" , 10 ]] # \u542b\u5185\u5d4c\u5217\u8868\u7684\u5217\u8868 \u5217\u8868\u7684\u5207\u7247\u64cd\u4f5c\uff1a \u548c\u5b57\u7b26\u4e32\u7c7b\u4f3c\uff0c\u53ef\u4ee5\u901a\u8fc7\u6807\u51c6\u8fd0\u7b97\u7b26\u6267\u884c\u5207\u7247\u6216\u8fde\u63a5\u64cd\u4f5c\uff0c\u8fd4\u56de\u7ed3\u679c\u4e5f\u662f\u5217\u8868\u3002 \u548c\u5b57\u7b26\u4e32\u4e0d\u540c\uff0c\u5217\u8868\u662f\u53ef\u53d8\u7684\uff0c\u5373\uff0c\u53ef\u4ee5\u66ff\u6362\u3001\u63d2\u5165\u6216\u5220\u9664\u5217\u8868\u4e2d\u6240\u5305\u542b\u7684\u9879\u3002 \u5207\u7247\u548c\u8fde\u63a5\u8fd0\u7b97\u7b26\u6240\u8fd4\u56de\u7684\u5217\u8868\u662f\u65b0\u7684\u5217\u8868\uff0c\u800c\u4e0d\u662f\u6700\u521d\u5217\u8868\u7684\u4e00\u90e8\u5206\uff1b \u5217\u8868\u7c7b\u578b\u5305\u542b\u4e86\u51e0\u4e2a\u53eb\u4f5c\u53d8\u5f02\u5668\uff08mutator\uff09\u7684\u65b9\u6cd5\uff0c\u7528\u4e8e\u4fee\u6539\u5217\u8868\u7684\u7ed3\u6784\u3002 \u53ef\u4ee5\u901a\u8fc7 dir(list) \u6765\u67e5\u770b\u65b9\u6cd5\uff0c\u5305\u62ec\u53d8\u5f02\u5668\uff08mutator\uff09\u7684\u65b9\u6cd5\u3002 dir ( list ) # \u8fd0\u884c\u7ed3\u679c # ['__add__', '__class__', '__contains__', '__delattr__', '__delitem__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__getitem__', '__gt__', '__hash__', '__iadd__', '__imul__', '__init__', '__init_subclass__', '__iter__', '__le__', '__len__', '__lt__', '__mul__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__reversed__', '__rmul__', '__setattr__', '__setitem__', '__sizeof__', '__str__', '__subclasshook__', 'append', 'clear', 'copy', 'count', 'extend', 'index', 'insert', 'pop', 'remove', 'reverse', 'sort'] \u6700\u5e38\u7528\u7684\u5217\u8868\u53d8\u5f02\u5668\u65b9\u6cd5\u662f append \u3001 insert \u3001 pop \u3001 remove \u548c sort \u3002 \u793a\u4f8b\uff1a myList = [] # myList\u5f53\u524d\u4e3a[] myList . append ( 34 ) # myList\u5f53\u524d\u4e3a[34]\uff0c\u9ed8\u8ba4\u5c3e\u90e8\u63d2\u5165 myList . append ( 22 ) # myList\u5f53\u524d\u4e3a[34, 22]\uff0c\u9ed8\u8ba4\u5c3e\u90e8\u63d2\u5165 myList . sort () # myList\u5f53\u524d\u4e3a[22, 34] myList . pop () # \u9ed8\u8ba4\u4ece\u7d22\u5f15\u4f4d[0]\u5220\u9664\uff0c\u8fd4\u56de\u7ed3\u679c22\uff1bmyList\u5f53\u524d\u4e3a[34] myList . insert ( 0 , 22 ) # \u5728\u6307\u5b9a\u7d22\u5f15\u4f4d[0]\u63d2\u5165\uff1bmyList\u5f53\u524d\u4e3a[22, 34] myList . insert ( 1 , 55 ) # \u5728\u6307\u5b9a\u7d22\u5f15\u4f4d[1]\u63d2\u5165\uff1bmyList\u5f53\u524d\u4e3a[22, 55, 34] myList . pop ( 1 ) # \u6307\u5b9a\u7d22\u5f15\u4f4d[1]\u5220\u9664\uff0c\u8fd4\u56de\u7ed3\u679c55\uff1bmyList\u5f53\u524d\u4e3a[22, 34] myList . remove ( 22 ) # \u5220\u9664\u9996\u4e2a\u5339\u914d\u9879\u7684\u5143\u7d20[22]\uff1bmyList\u5f53\u524d\u4e3a[34] myList . remove ( 55 ) # \u62a5ValueError\u9519\uff0clist.remove(x): x not in list \u5bf9\u4e8e\u5b57\u7b26\u4e32\uff0csplit\u65b9\u6cd5\u4f1a\u4ece\u5b57\u7b26\u4e32\u91cc\u5206\u79bb\u51fa\u4e00\u4e2a\u5355\u8bcd\u5217\u8868\uff0c\u800cjoin\u65b9\u6cd5\u4f1a\u628a\u5355\u8bcd\u5217\u8868\u8fde\u5728\u4e00\u8d77\u4ece\u800c\u5f62\u6210\u5b57\u7b26\u4e32\u3002\u4f8b\u5982\uff1a print ( \"Python is cool\" . split ()) # \u8fd0\u884c\u7ed3\u679c\uff1a # ['Python', 'is', 'cool'] print ( \" \" . join ([ \"Python\" , \"is\" , \"cool\" ])) # \u8fd0\u884c\u7ed3\u679c\uff1a # Python is cool \u5bf9\u4e8e\u5217\u8868\u7279\u6027\u548c\u64cd\u4f5c\u7684\u8be6\u7ec6\u7ec3\u4e60\uff0c\u53c2\u8003 Python\u8bed\u8a00\u57fa\u7840@github \u6216\u8005 Python\u8bed\u8a00\u57fa\u7840@web \u4e2d\u201c1.3 \u5217\u8868\uff08list\uff09\u201d\u7684\u5185\u5bb9\u3002 1.4.2.\u5143\u7ec4 \u00b6 \u5143\u7ec4\uff08tuple\uff09\u662f\u4e00\u4e2a\u4e0d\u53ef\u53d8\u7684\u5143\u7d20\u5e8f\u5217\u3002 \u5143\u7ec4\uff08tuple\uff09\u5f62\u5f0f\u662f\u7528\u5706\u62ec\u53f7\u5c06\u5404\u9879\u62ec\u8d77\u6765\uff0c\u5e76\u4e14\u5fc5\u987b\u81f3\u5c11\u5305\u542b\u4e24\u4e2a\u9879\u3002 \u5143\u7ec4\u5b9e\u9645\u4e0a\u5c31\u50cf\u5217\u8868\u4e00\u6837\uff0c\u53ea\u4e0d\u8fc7\u5b83\u6ca1\u6709\u53d8\u5f02\u5668\u65b9\u6cd5\u3002 \u5982\u679c\u8981\u4f7f\u5143\u7ec4\u53ea\u5305\u542b\u4e00\u4e2a\u5143\u7d20\uff0c\u5219\u5fc5\u987b\u5728\u5143\u7ec4\u91cc\u5305\u542b\u9017\u53f7\u3002 \u5bf9\u6bd4\u4e0b\u9762\u7684\u533a\u522b\uff1a print (( 21 )) # (21)\u88ab\u89c6\u4e3a\u6574\u6570 # \u8fd0\u884c\u7ed3\u679c\uff1a # 21 print (( 21 ,)) # (21,)\u88ab\u89c6\u4e3a\u5143\u7ec4 # \u8fd0\u884c\u7ed3\u679c\uff1a # (21,) \u5bf9\u4e8e\u5217\u8868\u7279\u6027\u548c\u64cd\u4f5c\u7684\u8be6\u7ec6\u7ec3\u4e60\uff0c\u53c2\u8003 Python\u8bed\u8a00\u57fa\u7840@github \u6216\u8005 Python\u8bed\u8a00\u57fa\u7840@web \u4e2d\u201c1.6 \u5143\u7ec4\uff08tuple\uff09\u201d\u7684\u5185\u5bb9\u3002 1.4.3.\u5e8f\u5217\u904d\u5386 \u00b6 for \u5faa\u73af\u53ef\u4ee5\u7528\u6765\u904d\u5386\u5e8f\u5217\uff08\u5982\u5b57\u7b26\u4e32\u3001\u5217\u8868\u6216\u5143\u7ec4\uff09\u91cc\u7684\u6240\u6709\u5143\u7d20\u3002 \u904d\u5386\u5217\u8868\uff1a myList = [ 67 , 100 , 'Monday' , \"It's good\" ] for item in myList : print ( item ) myList = [ 67 , 100 , 'Monday' , \"It's good\" ] for idx in range ( len ( myList )): print ( myList [ idx ]) \u904d\u5386\u5143\u7ec4\uff1a myString = \"I love Python\" myList = myString . split () myTuple = tuple ( myList ) for i in myTuple : print ( i ) \u904d\u5386\u5b57\u7b26\u4e32\uff1a(\u6ce8\u610f\uff0c\u662f\u904d\u5386\u5b57\u7b26\uff0c\u4e0d\u662f\u5355\u8bcd) myString = \"I love Python\" for i in myString : print ( i ) myString = \"I love Python\" for i in range ( len ( myString )): print ( myString [ i ]) myString = \"I love Python\" for i in enumerate ( myString ): print ( i ) myString = \"I love Python\" for i , j in enumerate ( myString ): print ( i , j ) myString = \"I love Python\" for i in iter ( myString ): print ( i ) \u5982\u679c\u6309\u7167\u5355\u8bcd\u904d\u5386\u5b57\u7b26\u4e32\uff0c\u5219\u9700\u8981\u5148\u628a\u5b57\u4e32\u6309\u5355\u8bcd\u62c6\u89e3\u4e3a\u5217\u8868\u3002 myString = \"I love Python\" myList = \"I love Python\" . split () for i in myList : print ( i ) \u5bf9\u4e8e\u5217\u8868\u548c\u5143\u7ec4\u904d\u5386\u7684\u66f4\u591a\u4f8b\u5b50\uff0c\u5305\u62ec\u62c6\u5305\u904d\u5386\uff0c\u53c2\u8003 Python\u8bed\u8a00\u57fa\u7840@github \u6216\u8005 Python\u8bed\u8a00\u57fa\u7840@web \u7684\u5185\u5bb9\u3002 1.4.4.\u5b57\u5178 \u00b6 \u5b57\u5178\uff08dictionary\uff09\u5305\u542b\u96f6\u4e2a\u6216\u591a\u4e2a\u6761\u76ee\u3002 \u6bcf\u4e2a\u6761\u76ee\uff08entry\uff09\u90fd\u6709\u552f\u4e00\u7684\u952e\u548c\u5b83\u6240\u5bf9\u5e94\u7684\u503c\u76f8\u5173\u8054\u3002 \u952e\u901a\u5e38\u662f\u5b57\u7b26\u4e32\u6216\u6574\u6570\uff0c\u800c\u503c\u662f\u4efb\u610f\u7684Python\u5bf9\u8c61\u3002 \u4e0b\u6807\u8fd0\u7b97\u7b26\u53ef\u4ee5\u7528\u4e8e\u8bbf\u95ee\u4e00\u4e2a\u7ed9\u5b9a\u952e\u7684\u503c\uff0c\u7ed9\u4e00\u4e2a\u65b0\u952e\u6dfb\u52a0\u4e00\u4e2a\u503c\uff0c\u4ee5\u53ca\u66ff\u6362\u7ed9\u5b9a\u952e\u7684\u503c\u3002 pop \u65b9\u6cd5\u4f1a\u5220\u9664\u4e00\u4e2a\u6761\u76ee\u5e76\u8fd4\u56de\u7ed9\u5b9a\u952e\u6240\u5bf9\u5e94\u7684\u503c\u3002 keys \u65b9\u6cd5\u4f1a\u628a\u6240\u6709\u952e\u8fd4\u56de\u6210\u4e00\u4e2a\u53ef\u8fed\u4ee3\u5bf9\u8c61\u3002 values \u65b9\u6cd5\u4f1a\u628a\u6240\u6709\u503c\u8fd4\u56de\u6210\u4e00\u4e2a\u53ef\u8fed\u4ee3\u5bf9\u8c61\u3002 \u793a\u4f8b\uff1a {} # \u7a7a\u5b57\u5178 { \"name\" : \"Ken\" } # \u542b\u4e00\u4e2a\u6761\u76ee { \"name\" : \"Ken\" , \"age\" : 67 } # \u542b\u4e8c\u4e2a\u6761\u76ee { \"hobbies\" :[ \"reading\" , \"running\" ]} # \u542b\u4e00\u4e2a\u6761\u76ee\uff0c\u5176\u4e2d\u503c\u662f\u4e00\u4e2a\u5217\u8868 \u5b57\u5178\u672c\u8eab\u4e5f\u662f\u4e00\u4e2a\u53ef\u8fed\u4ee3\u5bf9\u8c61\u3002\u53ef\u4ee5\u901a\u8fc7for\u8bed\u53e5\u8fdb\u884c\u904d\u5386\u952e\u6216/\u548c\u503c\u3002 myDict = { 'name' : 'Ming' , 'id' : 1001 , 'age' : 35 } for keys in myDict : print ( keys , myDict [ keys ]) # \u8fd0\u884c\u7ed3\u679c\uff1a # name Ming # id 1001 # age 35 1.4.5.\u503c\u68c0\u7d22 \u00b6 \u53ef\u4ee5\u5728\u5b57\u7b26\u4e32\u5217\u8868\u3001\u5143\u7ec4\u6216\u5b57\u5178\u91cc\u901a\u8fc7 in \u8fd0\u7b97\u7b26\u6765\u5bf9\u503c\u6216\u591a\u9879\u96c6\u8fdb\u884c\u641c\u7d22\uff0c\u8fd4\u56de True \u6216 False \u3002\u5bf9\u4e8e\u5b57\u5178\u6765\u8bf4\uff0c\u641c\u7d22\u7684\u76ee\u6807\u503c\u5e94\u8be5\u662f\u4e00\u4e2a\u952e\u3002 \u5982\u679c\u5df2\u77e5\u7ed9\u5b9a\u503c\u5b58\u5728\u4e8e\u5e8f\u5217\uff08\u5b57\u7b26\u4e32\u3001\u5217\u8868\u6216\u5143\u7ec4\uff09\u91cc\uff0c\u90a3\u4e48 index \u65b9\u6cd5\u5c06\u8fd4\u56de\u8fd9\u4e2a\u503c\u6240\u51fa\u73b0\u7684\u7b2c\u4e00\u4e2a\u4f4d\u7f6e\u3002 \u5217\u8868\u68c0\u7d22\uff1a myString = \"I love Python\" myList = myString . split () print ( myList ) # \u8fd0\u884c\u7ed3\u679c\uff1a # ['I', 'love', 'Python'] print ( myList . index ( 'love' )) # \u8fd0\u884c\u7ed3\u679c\uff1a # 1 \u5143\u7ec4\u68c0\u7d22\uff1a myString = \"I love Python\" myList = myString . split () myTuple = tuple ( myList ) print ( myTuple ) print ( myTuple . index ( 'love' )) \u5b57\u5178\u68c0\u7d22\uff1a myDict = { 'name' : 'Ming' , 'id' : 1001 , 'age' : 35 } print ( myDict ) for keys in myDict : print ( keys , myDict [ keys ]) myDict . pop ( 'city' ) # \u62a5\u9519\uff0cKeyError: 'city' myDict . pop ( 'id' ) print ( myDict ) # \u8fd0\u884c\u7ed3\u679c\uff1a{'name': 'Ming', 'age': 35} 1.4.6.\u6a21\u5f0f\u5339\u914d\u8bbf\u95ee\u591a\u9879\u96c6 \u00b6 \u4e0b\u6807\u8fd0\u7b97\u7b26\u53ef\u4ee5\u7528\u6765\u8bbf\u95ee\u5217\u8868\u3001\u5143\u7ec4\u548c\u5b57\u5178\u91cc\u7684\u5143\u7d20\u3002 \u901a\u8fc7\u6a21\u5f0f\u5339\u914d\u53ef\u4ee5\u4e00\u6b21\u8bbf\u95ee\u591a\u4e2a\u5143\u7d20\u3002 \u793a\u4f8b\uff1a myTuple \u662f\u4e00\u4e2a\u542b\u5185\u5d4c\u5143\u7ec4\u7684\u5143\u7ec4\u3002 myTuple = (( 'r' , 'g' , 'b' ), 'hexString' ) print ( myTuple ) # \u8fd0\u884c\u7ed3\u679c\uff1a # (('r', 'g', 'b'), 'hexString') print ( myTuple [ 0 ]) # \u8fd0\u884c\u7ed3\u679c\uff1a # ('r', 'g', 'b') print ( myTuple [ 0 ][ 0 ]) # \u8fd0\u884c\u7ed3\u679c\uff1a # r print ( myTuple [ 0 ][ 1 ]) # \u8fd0\u884c\u7ed3\u679c\uff1a # g print ( myTuple [ 0 ][ 2 ]) # \u8fd0\u884c\u7ed3\u679c\uff1a # b print ( myTuple [ 1 ]) # \u8fd0\u884c\u7ed3\u679c\uff1a # hexString \u901a\u8fc7\u4e0a\u9762\u7684\u62c6\u89e3\uff0c\u6211\u4eec\u6e05\u695a\u4e86\u5185\u5d4c\u5143\u7ec4\u7684\u7ed3\u6784\u8be6\u7ec6\u60c5\u51b5\u3002 \u4e0b\u9762\uff0c\u6211\u4eec\u901a\u8fc7\u6a21\u5f0f\u5339\u914d\uff0c\u628a\u4e00\u4e2a\u7ed3\u6784\u5206\u914d\u7ed9\u5f62\u5f0f\u5b8c\u5168\u76f8\u540c\u7684\u53e6\u4e00\u4e2a\u7ed3\u6784\u3002\u8fd9\u91cc\u76ee\u6807\u7ed3\u6784 newTuple \u6240\u5305\u542b\u7684\u53d8\u91cf\u4ece\u6e90\u7ed3\u6784 (('r', 'g', 'b'), 'hexString') \u91cc\u7684\u76f8\u5e94\u4f4d\u7f6e\u5904\u83b7\u5f97\u5bf9\u5e94\u7684\u503c\u3002 newTuple = (( 'r' , 'g' , 'b' ), 'hexString' ) print ( newTuple [ 0 ]) # ('r', 'g', 'b') print ( newTuple [ 0 ][ 0 ]) # \u8fd0\u884c\u7ed3\u679c\uff1a # r print ( newTuple [ 0 ][ 1 ]) # \u8fd0\u884c\u7ed3\u679c\uff1a # g print ( newTuple [ 0 ][ 2 ]) # \u8fd0\u884c\u7ed3\u679c\uff1a # b print ( newTuple [ 1 ]) # \u8fd0\u884c\u7ed3\u679c\uff1a # hexString 1.5.\u521b\u5efa\u51fd\u6570 \u00b6 Python\u652f\u6301\u5b8c\u5168\u51fd\u6570\u5f0f\u7f16\u7a0b\u8bbe\u8ba1\u3002 Python\u5305\u542b\u5f88\u591a\u5185\u7f6e\u51fd\u6570\u3002 Python\u4e5f\u8fd0\u884c\u521b\u5efa\u65b0\u51fd\u6570\uff0c\u53ef\u4ee5\u4f7f\u7528\u9012\u5f52\uff0c\u628a\u51fd\u6570\u4f5c\u4e3a\u6570\u636e\u8fdb\u884c\u4f20\u9012\u548c\u8fd4\u56de\u3002 1.5.1.\u51fd\u6570\u5b9a\u4e49 \u00b6 \u51fd\u6570\u5b9a\u4e49\u8bed\u6cd5\uff1a \u547d\u540d\u51fd\u6570\u540d\u79f0\u548c\u53c2\u6570\u540d\u79f0\u7684\u89c4\u5219\u4e0e\u60ef\u4f8b\u4e0e\u547d\u540d\u53d8\u91cf\u7684\u662f\u76f8\u540c\u7684\u3002 \u5fc5\u9009\u53c2\u6570\u7684\u5217\u8868\u53ef\u4ee5\u4e3a\u7a7a\uff0c\u4e5f\u53ef\u4ee5\u5305\u542b\u7528\u9017\u53f7\u9694\u5f00\u7684\u540d\u79f0\u3002 \u4e0e\u5176\u4ed6\u7f16\u7a0b\u8bed\u8a00\u4e0d\u540c\u7684\u662f\uff0c\u53c2\u6570\u540d\u79f0\u6216\u51fd\u6570\u540d\u79f0\u672c\u8eab\u5e76\u4e0d\u4f1a\u548c\u6570\u636e\u7c7b\u578b\u8fdb\u884c\u5173\u8054\u3002 def < function name > ( < list of parameters > ): < sequence of statements > \u793a\u4f8b\uff1a \u5728\u51fd\u6570\u7684\u6807\u9898\u4e0b\u6709\u4e00\u884c\u7528\u4e09\u5f15\u53f7\u62ec\u8d77\u6765\u7684\u5b57\u7b26\u4e32 \u8fd4\u56den\u7684\u5e73\u65b9\u6570 \uff0c\u8fd9\u662f\u4e00\u4e2a\u6587\u6863\u5b57\u7b26\u4e32\uff08docstring\uff09\u3002 \u5728shell\u91cc\u9762\u8f93\u5165help(square)\u65f6\uff0c\u4f1a\u663e\u793a\u8fd9\u4e2a\u5b57\u7b26\u4e32\u3002 \u5b9a\u4e49\u7684\u6bcf\u4e00\u4e2a\u51fd\u6570\u90fd\u5e94\u8be5\u6709\u6587\u6863\u5b57\u7b26\u4e32\uff0c\u6765\u8bf4\u660e\u8be5\u51fd\u6570\u7684\u529f\u80fd\uff0c\u5e76\u63d0\u4f9b\u76f8\u5173\u7684\u6240\u6709\u53c2\u6570\u4ee5\u53ca\u8fd4\u56de\u503c\u7684\u4fe1\u606f\u3002 \u51fd\u6570\u7684\u53c2\u6570\u548c\u4e34\u65f6\u53d8\u91cf\u53ea\u4f1a\u5728\u51fd\u6570\u8c03\u7528\u7684\u751f\u5b58\u5468\u671f\u5185\u5b58\u5728\uff0c\u5e76\u4e14\u5bf9\u5176\u4ed6\u51fd\u6570\u53ca\u5176\u5916\u56f4\u7a0b\u5e8f\u90fd\u662f\u4e0d\u53ef\u89c1\u7684\u3002 n \u662f\u53c2\u6570\u3002 result \u662f\u4e34\u65f6\u53d8\u91cf\u3002 \u5982\u679c\u51fd\u6570\u4e0d\u5305\u542b return \u8bed\u53e5\u65f6\uff0c\u5b83\u5c06\u5728\u6700\u540e\u4e00\u6761\u8bed\u53e5\u6267\u884c\u4e4b\u540e\u81ea\u52a8\u8fd4\u56de None \u503c\u3002 \u7528 = \u628a\u53c2\u6570\u6307\u5b9a\u4e3a\u6709\u9ed8\u8ba4\u503c\u7684\u53ef\u9009\u53c2\u6570\u3002 \u5728\u53c2\u6570\u5217\u8868\u4e2d\uff0c\u5fc5\u9009\u53c2\u6570\uff08\u6ca1\u6709\u9ed8\u8ba4\u503c\u7684\u53c2\u6570\uff09\u5fc5\u987b\u4f4d\u4e8e\u53ef\u9009\u53c2\u6570\u4e4b\u524d\u3002 def square ( n ): \"\"\"\u8fd4\u56den\u7684\u5e73\u65b9\u6570\"\"\" result = n ** 2 return result print ( square ( 5 )) 1.5.2.\u51fd\u6570\u9012\u5f52 \u00b6 \u9012\u5f52\u51fd\u6570\uff08recursive function\uff09\u662f\u6307\u4f1a\u8c03\u7528\u81ea\u8eab\u7684\u51fd\u6570\u3002 \u4e3a\u4e86\u9632\u6b62\u51fd\u6570\u65e0\u9650\u5730\u91cd\u590d\u8c03\u7528\u81ea\u8eab\uff0c\u4ee3\u7801\u4e2d\u5fc5\u987b\u81f3\u5c11\u6709\u4e00\u6761\u7528\u6765\u67e5\u9a8c\u6761\u4ef6\u7684\u9009\u62e9\u8bed\u53e5\uff0c\u7528\u4e8e\u786e\u5b9a\u63a5\u4e0b\u6765\u8981\u7ee7\u7eed\u9012\u5f52\u8fd8\u662f\u505c\u6b62\u9012\u5f52\u3002\u8fd9\u4e2a\u68c0\u67e5\u6761\u4ef6\u8bed\u53e5\u79f0\u4e3a\u57fa\u672c\u60c5\u51b5\uff08base case\uff09\u3002 \u793a\u4f8b\uff1a\u4e0b\u9762\u662f\u901a\u8fc7\u5faa\u73af\u5b9e\u73b0\u8f93\u51fa\u4ece\u7ed9\u5b9a\u7684\u6700\u5c0f\u503c\u5230\u6700\u5927\u503c\u4e4b\u95f4\u7684\u6574\u6570\u548c\u3002 def mySum ( lower , upper ): \"\"\"\u5bf9\u7ed9\u5b9a\u7684\u6700\u5c0f\u503c\u5230\u6700\u5927\u503c\u4e4b\u95f4\u7684\u6574\u6570\u6c42\u548c; lower:\u6700\u5c0f\u503c; upper:\u6700\u5927\u503c;\"\"\" result = 0 while ( lower <= upper ): result = result + lower lower += 1 return result print ( mySum ( 1 , 10 )) # \u8fd0\u884c\u7ed3\u679c\uff1a # 55 \u7528\u9012\u5f52\u51fd\u6570\u6539\u5199\u4e0a\u8ff0\u51fd\u6570\u3002 def mySum ( lower , upper ): \"\"\"\u5bf9\u7ed9\u5b9a\u7684\u6700\u5c0f\u503c\u5230\u6700\u5927\u503c\u4e4b\u95f4\u7684\u6574\u6570\u6c42\u548c; lower:\u6700\u5c0f\u503c; upper:\u6700\u5927\u503c;\"\"\" if lower <= upper : return lower + mySum ( lower + 1 , upper ) else : return 0 print ( mySum ( 1 , 10 )) # \u8fd0\u884c\u7ed3\u679c\uff1a # 55 \u901a\u5e38\u6765\u8bf4\uff0c\u9012\u5f52\u51fd\u6570\u81f3\u5c11\u6709\u4e00\u4e2a\u53c2\u6570\u3002 \u8fd9\u4e2a\u53c2\u6570\u7684\u503c\u4f1a\u88ab\u7528\u6765\u5bf9\u9012\u5f52\u8fc7\u7a0b\u7684\u57fa\u672c\u60c5\u51b5\u8fdb\u884c\u5224\u5b9a\uff0c\u4ece\u800c\u51b3\u5b9a\u662f\u5426\u8981\u7ed3\u675f\u6574\u4e2a\u8c03\u7528\u3002 \u5728\u6bcf\u6b21\u9012\u5f52\u8c03\u7528\u4e4b\u524d\uff0c\u8fd9\u4e2a\u503c\u4e5f\u4f1a\u88ab\u8fdb\u884c\u67d0\u79cd\u65b9\u5f0f\u7684\u4fee\u6539\u3002 \u6bcf\u6b21\u5bf9\u8fd9\u4e2a\u503c\u7684\u4fee\u6539\uff0c\u90fd\u5e94\u8be5\u4ea7\u751f\u4e00\u4e2a\u65b0\u6570\u636e\u503c\uff0c\u53ef\u4ee5\u8ba9\u51fd\u6570\u6700\u7ec8\u8fbe\u5230\u57fa\u672c\u60c5\u51b5\u3002 \u4e3a\u4e86\u5bf9 mySum \u51fd\u6570\u7684\u9012\u5f52\u8fdb\u884c\u8ddf\u8e2a\uff0c\u53ef\u4ee5\u5c1d\u8bd5\u6dfb\u52a0\u4e00\u4e2a\u4ee3\u8868\u7f29\u8fdb\u8fb9\u8ddd\u7684\u53c2\u6570\u5e76\u4e14\u6dfb\u52a0\u4e00\u4e9bprint\u8bed\u53e5\u3002\u8fd9\u6837\u5728\u6bcf\u6b21\u8c03\u7528\u65f6\uff0c\u51fd\u6570\u7684\u7b2c\u4e00\u6761\u8bed\u53e5\u4f1a\u8ba1\u7b97\u7f29\u8fdb\u6570\u91cf\uff0c\u7136\u540e\u518d\u6253\u5370\u4e24\u4e2a\u53c2\u6570\u7684\u503c\uff0c\u6bcf\u6b21\u8fd4\u56de\u8c03\u7528\u4e4b\u524d\u7684\u8fd4\u56de\u503c\u65f6\u90fd\u4f7f\u7528\u76f8\u540c\u7684\u7f29\u8fdb\uff0c\u5c31\u53ef\u4ee5\u5b9e\u73b0\u5bf9\u4e24\u4e2a\u53c2\u6570\u7684\u503c\u4ee5\u53ca\u6bcf\u6b21\u8c03\u7528\u7684\u8fd4\u56de\u503c\u8fdb\u884c\u8ddf\u8e2a\u3002 def mySum ( lower , upper , margin = 0 ): \"\"\"\u5bf9\u7ed9\u5b9a\u7684\u6700\u5c0f\u503c\u5230\u6700\u5927\u503c\u4e4b\u95f4\u7684\u6574\u6570\u6c42\u548c\uff0c\u901a\u8fc7\u9636\u68af\u65b9\u5f0f\u8f93\u51fa; lower:\u6700\u5c0f\u503c; upper:\u6700\u5927\u503c;\"\"\" blanks = \" \" * margin print ( blanks , lower , upper ) if lower <= upper : result = lower + mySum ( lower + 1 , upper , margin + 4 ) print ( blanks , result ) return result else : print ( blanks , 0 ) return 0 print ( mySum ( 1 , 5 )) # \u8fd0\u884c\u7ed3\u679c\uff1a # 1 5 # 2 5 # 3 5 # 4 5 # 5 5 # 6 5 # 0 # 5 # 9 # 12 # 14 # 15 # 15 1.5.3.\u51fd\u6570\u5d4c\u5957 \u00b6 \u5d4c\u5957\u51fd\u6570\u7c7b\u4f3c\u4e8e\u5d4c\u5957\u5faa\u73af\uff0c\u5c31\u662f\u51fd\u6570\u5185\u53c8\u5d4c\u5957\u7740\u51fd\u6570\u3002\u5373\uff0c\u51fd\u6570\u7684\u5b9a\u4e49\u5d4c\u5957\u5728\u4e00\u4e2a\u51fd\u6570\u7684\u8bed\u53e5\u5e8f\u5217\u91cc\u3002 \u5148\u770b\u4e00\u4e2a\u666e\u901a\u4f8b\u5b50\uff1a # \u5b9a\u4e49inner\u51fd\u6570 def inner (): print ( '\u6211\u662finner' ) # \u5b9a\u4e49outer\u51fd\u6570\uff0couter\u51fd\u6570\u8c03\u7528inner\u51fd\u6570 def outer (): print ( '\u6211\u662fouter' ) inner () outer () # \u8fd0\u884c\u7ed3\u679c\uff1a # \u6211\u662fouter # \u6211\u662finner \u6539\u5199\u4e0a\u9762\u7684\u4ee3\u7801\uff0c\u628a inner \u51fd\u6570\u5199\u5728 outer \u51fd\u6570\u91cc\u9762\u3002 # \u5b9a\u4e49outer\u51fd\u6570\uff0couter\u51fd\u6570\u5185\u5d4cinner\u51fd\u6570\uff0c\u5e76\u8c03\u7528inner\u51fd\u6570 def outer (): print ( '\u6211\u662fouter' ) # \u5b9a\u4e49inner\u51fd\u6570 def inner (): print ( '\u6211\u662finner' ) inner () outer () # \u8fd0\u884c\u7ed3\u679c\uff1a # \u6211\u662fouter # \u6211\u662finner \u4e0a\u9762\u7684\u5916\u5c42 outer \u51fd\u6570\u548c\u5185\u5c42 inner \u51fd\u6570\u90fd\u6ca1\u6709\u53d8\u91cf\u548c\u53c2\u6570\u3002 \u73b0\u5728\u4fee\u6539\u4e0a\u9762\u7684\u4ee3\u7801\uff0c\u6211\u4eec\u4f20\u5165\u53c2\u6570\u548c\u53d8\u91cf\uff0c\u7136\u540e\u628a\u5916\u5c42\u51fd\u6570\u8fd4\u56de\u503c\u6307\u5411\u5185\u5c42\u51fd\u6570\u540d\u3002 def outer (): a = 1 print ( '\u6211\u662fouter' ) # \u5b9a\u4e49inner\u51fd\u6570 def inner (): print ( '\u6211\u662finner' ) print ( 'inner\u6253\u5370: ' , a ) # \u8fd4\u56de\u5185\u5c42inner\u51fd\u6570\u540d return inner f = outer () # \u8fd0\u884c\u7ed3\u679c\uff1a # \u6211\u662fouter f () # \u8fd0\u884c\u7ed3\u679c\uff1a # \u6211\u662finner # inner\u6253\u5370: 1 \u5728\u4e0a\u9762\u7684\u4f8b\u5b50\u4e2d\uff1a f = outer() \u8c03\u7528\u5916\u5c42 outer \u51fd\u6570\uff0c\u5e76\u628a\u7ed3\u679c\u8d4b\u503c\u7ed9 f \u3002\u6ce8\u610f\uff0cinner\u51fd\u6570\u5e76\u6ca1\u6709\u88ab\u6267\u884c\u3002 f \u5176\u5b9e\u5c31\u662f inner \uff0c\u6307\u5411 inner \u7684\u5185\u5b58\u7a7a\u95f4\u3002\u901a\u8fc7 f() \u9a8c\u8bc1\u4e86\u8fd9\u4e00\u70b9\uff0c outer \u51fd\u6570\u4e2d\u7684\u53d8\u91cf a \u88ab\u6253\u5370\u51fa\u6765\u4e86\u3002 \u4e0a\u9762\u4f8b\u5b50\u4e2d outer \u5c31\u662f\u95ed\u5305\u51fd\u6570\uff0c\u5916\u5c42\u51fd\u6570\u7684\u53d8\u91cf\u53ef\u4ee5\u88ab\u5185\u5c42\u51fd\u6570\u8c03\u7528\uff0c\u7c7b\u4f3c\u4e8e\u5c01\u88c5\u7684\u6548\u679c\u3002\u5185\u5c42\u51fd\u6570\u4e0d\u4f1a\u7acb\u523b\u88ab\u6267\u884c\uff0c\u5f53\u518d\u6b21\u8c03\u7528\u65f6\uff0c\u5185\u5c42\u51fd\u6570\u624d\u4f1a\u6267\u884c\u3002 \u95ed\u5305\u51fd\u6570\u9700\u8981\u6709\u4e09\u4e2a\u6761\u4ef6\uff1a \u5fc5\u987b\u6709\u4e00\u4e2a\u5185\u5d4c\u51fd\u6570\uff0c\u4f8b\u5982\u51fd\u6570 inner \uff1b \u5185\u90e8\u51fd\u6570\u5f15\u7528\u5916\u90e8\u51fd\u6570\u53d8\u91cf\uff0c\u4f8b\u5982\u53d8\u91cf a \uff1b \u5916\u90e8\u51fd\u6570\u5fc5\u987b\u8fd4\u56de\u5185\u5d4c\u51fd\u6570\uff0c\u4f8b\u5982 outer \u51fd\u6570\u4e2d\u7684 return inner \uff1b \u5bf9\u4e0a\u9762\u7684\u4ee3\u7801\u518d\u8fdb\u884c\u4fee\u6539\uff0c\u5728 inner \u51fd\u6570\u4e2d\u518d\u6dfb\u52a0\u4e00\u4e2a\u540c\u540d\u7684\u53d8\u91cfa\u3002\u4ece\u7ed3\u679c\u53ef\u4ee5\u5f97\u51fa\u7ed3\u8bba\uff0c inner \u51fd\u6570\u4f18\u5148\u5728\u5185\u90e8\u67e5\u627e\u53d8\u91cf a=5 \u3002 def outer (): a = 1 print ( '\u6211\u662fouter' ) # \u5b9a\u4e49inner\u51fd\u6570 def inner (): a = 5 print ( '\u6211\u662finner' ) print ( 'inner\u6253\u5370: ' , a ) return inner f = outer () # \u8fd0\u884c\u7ed3\u679c\uff1a # \u6211\u662fouter f () # \u8fd0\u884c\u7ed3\u679c\uff1a # \u6211\u662finner # inner\u6253\u5370: 5 \u7ed3\u8bba\uff1a\u5185\u5c42\u51fd\u6570\u4e2d\u8c03\u7528\u7684\u53d8\u91cf\uff1a \u9996\u5148\u4f1a\u4ece\u5185\u5c42\u51fd\u6570\u4e2d\u627e\uff0c \u627e\u4e0d\u5230\u5c31\u53bb\u5916\u5c42\u51fd\u6570\u4e2d\u627e\uff0c \u518d\u627e\u4e0d\u5230\u5c31\u5230\u51fd\u6570\u5916\u4e2d\u627e\uff0c \u518d\u627e\u4e0d\u5230\u5c31\u5230\u5185\u7f6e\u7684\u6a21\u5757\u4e2d\u627e\uff0c \u518d\u627e\u4e0d\u5230\uff0c\u5c31\u62a5\u9519\u3002 \u8fd9\u5c31\u662f\u4f5c\u7528\u57df\u7684\u6982\u5ff5\u3002 \u7ee7\u7eed\u4fee\u6539\u4e0a\u9762\u7684\u4ee3\u7801\uff0c\u5728 inner \u51fd\u6570\u4e2d\u4fee\u6539 outer \u51fd\u6570\u4e2d\u53d8\u91cf a \u7684\u503c\uff0c\u8fd0\u884c\u7ed3\u679c\u62a5\u9519\u3002\u7ed3\u8bba\uff1a\u5185\u5c42\u51fd\u6570\u4e0d\u80fd\u4fee\u6539\u5916\u5c42\u51fd\u6570\u7684\u53d8\u91cf\u503c\u3002 def outer (): a = 1 print ( '\u6211\u662fouter' ) # \u5b9a\u4e49inner\u51fd\u6570 def inner (): a += 5 print ( '\u6211\u662finner' ) print ( 'inner\u6253\u5370: ' , a ) return inner f = outer () # \u8fd0\u884c\u7ed3\u679c\uff1a # \u6211\u662fouter f () # \u8fd0\u884c\u7ed3\u679c\uff1a # UnboundLocalError: local variable 'a' referenced before assignment \u4fee\u6b63\u4e0a\u9762\u7684\u4ee3\u7801\u3002\u5728 inner \u51fd\u6570\u4e2d\u5bf9\u53d8\u91cfa\u6dfb\u52a0\u4e00\u4e2a nonlocal \u7684\u58f0\u660e\uff0c\u5c31\u53ef\u4ee5\u5728 inner \u51fd\u6570\u4e2d\u4fee\u6539\u5916\u5c42outer\u51fd\u6570\u7684\u53d8\u91cf a \u7684\u503c\u3002 def outer (): a = 1 print ( '\u6211\u662fouter' ) # \u5b9a\u4e49inner\u51fd\u6570 def inner (): nonlocal a a += 5 print ( '\u6211\u662finner' ) print ( 'inner\u6253\u5370: ' , a ) return inner f = outer () # \u8fd0\u884c\u7ed3\u679c\uff1a # \u6211\u662fouter f () # \u8fd0\u884c\u7ed3\u679c\uff1a # \u6211\u662finner # inner\u6253\u5370: 6 \u4e0b\u9762\u8fd9\u6bb5\u4ee3\u7801\u662f\u9636\u4e58\uff08factorial\uff09\u9012\u5f52\u51fd\u6570\u7684\u4e24\u4e2a\u4e0d\u540c\u7684\u5b9a\u4e49\u3002 \u7b2c\u4e00\u4e2a\u5b9a\u4e49\u4f7f\u7528\u4e86\u5d4c\u5957\u7684\u8f85\u52a9\u51fd\u6570 recurse \u6765\u5bf9\u6240\u9700\u8981\u7684\u53c2\u6570\u8fdb\u884c\u9012\u5f52\uff1b\u8fd9\u91cc\u7684 factorial \u51fd\u6570\u5c31\u662f\u95ed\u5305\u51fd\u6570\u3002 \u7b2c\u4e00\u6b65\uff1a\u7b2c\u4e00\u6b21\u8c03\u7528 factorial() \u51fd\u6570\uff0c\u5373 n=5 \uff1b \u7b2c\u4e8c\u6b65\uff1a\u7b2c\u4e00\u6b21\u8c03\u7528\u5185\u5c42\u51fd\u6570 recurse() \uff0c\u4f46\u4e0d\u4f1a\u7acb\u523b\u88ab\u6267\u884c\uff1b \u7b2c\u4e09\u6b65\uff0c\u6267\u884c return recurse(5, 1) \uff0c\u5bf9\u53c2\u6570 product \u521d\u59cb\u5316\u8d4b\u503c 1 \u7b2c\u56db\u6b65\uff1a\u6267\u884c return recurse(5, 5 * 1) \uff0c\u6b64\u65f6 n=5 \uff0c product=1 \u3002 \u7b2c\u4e94\u6b65\uff1a\u6267\u884c return recurse(4, 4 * 5) \uff0c\u6b64\u65f6 n=4 \uff0c product=5 \u3002 \u7b2c\u516d\u6b65\uff1a\u6267\u884c return recurse(3, 3 * 20) \uff0c\u6b64\u65f6 n=3 \uff0c product=20 \u3002 \u7b2c\u4e03\u6b65\uff1a\u6267\u884c return recurse(2, 2 * 60) \uff0c\u6b64\u65f6 n=2 \uff0c product=60 \u3002 \u7b2c\u516b\u6b65\uff1a\u6267\u884c return recurse(1, 1 * 120) \uff0c\u6b64\u65f6 n=1 \uff0c product=120 \u3002 \u7b2c\u4e5d\u6b65\uff1a\u6b64\u65f6 n=1 \uff0c\u6267\u884c return product \uff0c\u5373 return 120 \uff0c\u7ed3\u675f\u3002 \u7b2c\u4e8c\u4e2a\u5b9a\u4e49\u5219\u662f\u4e3a\u7b2c\u4e8c\u4e2a\u53c2\u6570\u63d0\u4f9b\u4e86\u9ed8\u8ba4\u503c\uff0c\u4ece\u800c\u7b80\u5316\u4e86\u8bbe\u8ba1\u3002 # \u7b2c\u4e00\u4e2a\u5b9a\u4e49 def factorial ( n ): \"\"\"\u8fd4\u56de n \u7684\u9636\u4e58\"\"\" def recurse ( n , product ): \"\"\"\u8ba1\u7b97\u9636\u4e58\u7684\u5e2e\u52a9\u5668\"\"\" print ( n , product ) # \u63d2\u5165\u8fd9\u4e00\u53e5\u662f\u4e3a\u4e86\u80fd\u770b\u6e05\u695a\u6bcf\u4e00\u6b21\u9012\u5f52\u8c03\u7528\u7684n\u548cproduct\u53d8\u5316 if n == 1 : return product else : return recurse ( n - 1 , n * product ) return recurse ( n , 1 ) f = factorial ( 5 ) # \u8fd0\u884c\u7ed3\u679c 5 1 4 5 3 20 2 60 1 120 # \u7b2c\u4e8c\u4e2a\u5b9a\u4e49 def factorial ( n , product = 1 ): \"\"\"\u8fd4\u56de n \u7684\u9636\u4e58\"\"\" if n == 1 : return product else : return factorial ( n - 1 , n * product ) print ( factorial ( 5 )) # \u8fd0\u884c\u7ed3\u679c # 120 1.5.4.\u9ad8\u9636\u51fd\u6570 \u00b6 \u51fd\u6570\u672c\u8eab\u4e5f\u662f\u4e00\u79cd\u72ec\u7279\u7684\u6570\u636e\u5bf9\u8c61\u3002\u53ef\u4ee5\u628a\u5b83\u4eec\u8d4b\u7ed9\u53d8\u91cf\u3001\u5b58\u50a8\u5728\u6570\u636e\u7ed3\u6784\u91cc\u3001\u4f5c\u4e3a\u53c2\u6570\u4f20\u9012\u7ed9\u5176\u4ed6\u51fd\u6570\u4ee5\u53ca\u4f5c\u4e3a\u5176\u4ed6\u51fd\u6570\u7684\u503c\u8fd4\u56de\u3002 \u9ad8\u9636\u51fd\u6570\uff08higher-order function\uff09\uff1a\u5b83\u63a5\u6536\u53e6\u4e00\u4e2a\u51fd\u6570\u4f5c\u4e3a\u53c2\u6570\uff0c\u5e76\u4e14\u4ee5\u67d0\u79cd\u65b9\u5f0f\u5e94\u7528\u8be5\u51fd\u6570\u3002 Python\u6709\u4e24\u4e2a\u5185\u7f6e\u7684\u9ad8\u9636\u51fd\u6570\uff0c\u5206\u522b\u662f map \u548c filter \uff0c\u5b83\u4eec\u53ef\u4ee5\u7528\u4e8e\u5904\u7406\u53ef\u8fed\u4ee3\u5bf9\u8c61\u3002 map \u51fd\u6570\u4f1a\u63a5\u6536\u53e6\u4e00\u4e2a\u51fd\u6570\u548c\u4e00\u4e2a\u53ef\u8fed\u4ee3\u5bf9\u8c61\u4f5c\u4e3a\u53c2\u6570\uff0c\u8fd4\u56de\u53e6\u4e00\u4e2a\u53ef\u8fed\u4ee3\u5bf9\u8c61\u3002\u8fd9\u4e2a\u51fd\u6570\u4f1a\u628a\u4f5c\u4e3a\u53c2\u6570\u4f20\u9012\u7684\u51fd\u6570\u5e94\u7528\u5728\u53ef\u8fed\u4ee3\u5bf9\u8c61\u91cc\u7684\u6bcf\u4e2a\u5143\u7d20\u4e0a\u3002\u7b80\u5355\u6765\u8bf4\uff0c map \u51fd\u6570\u4f1a\u5bf9\u53ef\u8fed\u4ee3\u5bf9\u8c61\u91cc\u7684\u6bcf\u4e2a\u5143\u7d20\u8fdb\u884c\u8f6c\u6362\u3002 filter \u4f1a\u63a5\u53d7\u4e00\u4e2a\u5e03\u5c14\u51fd\u6570\u548c\u4e00\u4e2a\u53ef\u8fed\u4ee3\u5bf9\u8c61\u4f5c\u4e3a\u53c2\u6570\uff0c\u8fd4\u56de\u8fd9\u6837\u4e00\u4e2a\u53ef\u8fed\u4ee3\u5bf9\u8c61\uff0c\u5b83\u7684\u6bcf\u4e00\u4e2a\u5143\u7d20\u90fd\u4f1a\u88ab\u4f20\u9012\u7ed9\u5e03\u5c14\u51fd\u6570\uff0c\u5982\u679c\u8fd9\u4e2a\u51fd\u6570\u8fd4\u56deTrue\uff0c\u90a3\u4e48\u8fd9\u4e2a\u5143\u7d20\u5c06\u88ab\u4fdd\u7559\u5728\u8fd4\u56de\u7684\u53ef\u8fed\u4ee3\u5bf9\u8c61\u91cc\uff1b\u5426\u5219\uff0c\u8fd9\u4e2a\u5143\u7d20\u5c06\u88ab\u5220\u9664\u3002\u7b80\u5355\u8bf4\uff0c filter \u51fd\u6570\u4f1a\u628a\u6240\u6709\u80fd\u591f\u901a\u8fc7\u68c0\u9a8c\u7684\u5143\u7d20\u4fdd\u7559\u5728\u53ef\u8fed\u4ee3\u5bf9\u8c61\u91cc\u3002 functools.reduce \u901a\u8fc7\u628a\u63a5\u6536\u4e24\u4e2a\u53c2\u6570\u7684\u51fd\u6570\u7684\u7ed3\u679c\u4ee5\u53ca\u8fed\u4ee3\u5bf9\u8c61\u7684\u4e0b\u4e00\u4e2a\u5143\u7d20\u518d\u6b21\u5e94\u7528\u4e8e\u8fd9\u4e2a\u63a5\u6536\u4e24\u4e2a\u53c2\u6570\u7684\u51fd\u6570\uff0c\u6765\u628a\u53ef\u8fed\u4ee3\u5bf9\u8c61\u8ba1\u7b97\u6210\u5355\u4e00\u7684\u503c\u3002 \u793a\u4f8b\uff1a\u628a\u4e00\u4e2a\u6574\u6570\u5217\u8868\u8f6c\u6362\u6210\u53e6\u4e00\u4e2a\u5305\u542b\u8fd9\u4e9b\u6574\u6570\u7684\u5b57\u7b26\u4e32\u5f62\u5f0f\u7684\u5217\u8868\u3002 \u4f20\u7edf\u65b9\u6cd5\u5b9e\u73b0\uff1a oldList = [ 0 , 1 , 3 , 5 , 7 , 9 ] newList = [] for i in oldList : newList . append ( str ( i )) print ( newList ) # ['0', '1', '3', '5', '7', '9'] \u7528 map \u5b9e\u73b0\uff1a oldList = [ 0 , 1 , 3 , 5 , 7 , 9 ] newList = [] newList = list ( map ( str , oldList )) print ( newList ) # ['0', '1', '3', '5', '7', '9'] \u62d3\u5c55\uff1a\u628a\u4e00\u4e2a\u6574\u6570\u5217\u8868\u4e2d\u7684\u6b63\u6574\u6570\u8f6c\u6362\u6210\u53e6\u4e00\u4e2a\u5305\u542b\u8fd9\u4e9b\u6574\u6570\u7684\u5b57\u7b26\u4e32\u5f62\u5f0f\u7684\u5217\u8868\u3002 \u4f20\u7edf\u5b9e\u73b0\uff1a oldList = [ 0 , 1 , 3 , 5 , 7 , 9 ] newList = [] for i in oldList : if i > 0 : newList . append (( str ( i ))) print ( newList ) # ['1', '3', '5', '7', '9'] \u4f7f\u7528 filter \u5b9e\u73b0\uff1a oldList = [ 0 , 1 , 3 , 5 , 7 , 9 ] newList = [] def isPositive ( n ): if n > 0 : return True # \u521b\u5efa\u4e00\u4e2a\u4e0d\u5305\u542b\u4efb\u4f55\u96f6\u7684\u53ef\u8fed\u4ee3\u5bf9\u8c61 newList = list ( filter ( isPositive , oldList )) print ( newList ) # [1, 3, 5, 7, 9] \u793a\u4f8b\uff1a\u8ba1\u7b97\u4ece1\u523010\u7684\u4e58\u79ef\u5e76\u8f93\u51fa\u7ed3\u679c\u3002 \u901a\u8fc7 for \u5faa\u73af\u5b9e\u73b0\uff1a result = 1 value = 1 for value in range ( 1 , 11 ): result *= value value += 1 print ( result ) # \u8fd0\u884c\u7ed3\u679c # 3628800 \u901a\u8fc7 functools.reduce \u5faa\u73af\u5b9e\u73b0\uff1a import functools result = functools . reduce ( lambda x , y : x * y , range ( 1 , 11 )) print ( result ) # 3628800 1.5.5.lambda\u4e0e\u533f\u540d\u51fd\u6570 \u00b6 \u8bed\u6cd5\u683c\u5f0f\uff1a lambda < argument list > : < expression > lambda\u8868\u8fbe\u5f0f\u4e0d\u80fd\u50cf\u5176\u4ed6Python\u51fd\u6570\u90a3\u6837\u5305\u542b\u4e00\u6574\u4e2a\u8bed\u53e5\u5e8f\u5217\u3002 \u62d3\u5c55\uff1a\u7528lambda\u5b9e\u73b0\u628a\u4e00\u4e2a\u6574\u6570\u5217\u8868\u4e2d\u7684\u6b63\u6574\u6570\u8f6c\u6362\u6210\u53e6\u4e00\u4e2a\u5305\u542b\u8fd9\u4e9b\u6574\u6570\u7684\u5b57\u7b26\u4e32\u5f62\u5f0f\u7684\u5217\u8868\uff0c\u5b9e\u9645\u5c31\u662f\u901a\u8fc7\u4f7f\u7528\u533f\u540d\u7684\u5e03\u5c14\u51fd\u6570\u6765\u4ece\u6574\u6570\u5217\u8868\u91cc\u5254\u9664\u6240\u6709\u4e3a\u96f6\u7684\u5143\u7d20\u3002 oldList = [ 0 , 1 , 3 , 5 , 7 , 9 ] newList = [] newList = list ( filter ( lambda i : i > 0 , oldList )) print ( newList ) # [1, 3, 5, 7, 9] 1.6.\u6355\u83b7\u5f02\u5e38 \u00b6 \u8003\u8651\u4e24\u79cd\u5f02\u5e38\u60c5\u51b5\uff1a Python\u865a\u62df\u673a\u5728\u7a0b\u5e8f\u6267\u884c\u671f\u95f4\u9047\u5230\u4e86\u8bed\u4e49\u9519\u8bef\uff0c\u5219\u4f1a\u5f97\u5230\u76f8\u5e94\u7684\u9519\u8bef\u6d88\u606f\uff0c\u4ece\u800c\u5f15\u53d1\u4e00\u4e2a\u5f02\u5e38\u5e76\u4e14\u6682\u505c\u7a0b\u5e8f\u3002\u8bed\u4e49\u9519\u8bef\u5305\u62ec\u4f8b\u5982\u672a\u5b9a\u4e49\u7684\u53d8\u91cf\u540d\u3001\u9664\u4ee50\u4ee5\u53ca\u8d85\u51fa\u5217\u8868\u8303\u56f4\u7684\u7d22\u5f15\u7b49\u3002 \u7528\u6237\u5f15\u8d77\u7684\u67d0\u4e9b\u9519\u8bef\uff0c\u4f8b\u5982\uff0c\u671f\u671b\u8f93\u5165\u6570\u5b57\u7684\u65f6\u5019\u8f93\u5165\u4e86\u5176\u4ed6\u5b57\u7b26\u3002\u5bf9\u4e8e\u5728\u8fd9\u4e9b\u60c5\u51b5\u4e0b\u4ea7\u751f\u7684\u5f02\u5e38\uff0c\u7a0b\u5e8f\u4e0d\u5e94\u8be5\u505c\u6b62\u6267\u884c\uff0c\u800c\u5e94\u8be5\u5bf9\u8fd9\u4e9b\u5f02\u5e38\u8fdb\u884c\u6355\u83b7\uff0c\u5e76\u4e14\u5141\u8bb8\u7528\u6237\u4fee\u6b63\u9519\u8bef\u3002 Python\u63d0\u4f9b\u4e86try-except\u8bed\u53e5\uff0c\u53ef\u4ee5\u8ba9\u7a0b\u5e8f\u6355\u83b7\u5f02\u5e38\u5e76\u6267\u884c\u76f8\u5e94\u7684\u6062\u590d\u64cd\u4f5c\u3002 try \u5b50\u53e5\u4e2d\u7684\u8bed\u53e5\u5c06\u5148\u88ab\u6267\u884c\u3002\u5982\u679c\u8fd9\u4e9b\u8bed\u53e5\u4e2d\u7684\u4e00\u6761\u5f15\u53d1\u4e86\u5f02\u5e38\uff0c\u90a3\u4e48\u63a7\u5236\u6743\u4f1a\u7acb\u5373\u8f6c\u79fb\u5230 except \u5b50\u53e5\u53bb\u3002 \u5982\u679c\u5f15\u53d1\u7684\u5f02\u5e38\u7c7b\u578b\u548c\u8fd9\u4e2a\u5b50\u53e5\u91cc\u7684\u7c7b\u578b\u4e00\u81f4\uff0c\u90a3\u4e48\u4f1a\u6267\u884c\u5b83\u91cc\u9762\u7684\u8bed\u53e5\uff1b \u5426\u5219\uff0c\u5c06\u8f6c\u79fb\u5230try-except\u8bed\u53e5\u7684\u8c03\u7528\u8005\uff0c\u5e76\u57fa\u4e8e\u8c03\u7528\u94fe\u5411\u4e0a\u4f20\u9012\uff0c\u76f4\u5230\u8fd9\u4e2a\u5f02\u5e38\u88ab\u6210\u529f\u6355\u83b7\uff0c\u6216\u8005\u662f\u7a0b\u5e8f\u56e0\u9519\u8bef\u6d88\u606f\u800c\u505c\u6b62\u6267\u884c\u3002 \u5982\u679c try \u5b50\u53e5\u91cc\u7684\u8bed\u53e5\u6ca1\u6709\u5f15\u53d1\u4efb\u4f55\u5f02\u5e38\uff0c\u90a3\u4e48\u4f1a\u8df3\u8fc7 except \u5b50\u53e5\u5e76\u7ee7\u7eed\u6267\u884c\uff0c\u76f4\u5230try-except\u8bed\u53e5\u7684\u672b\u5c3e\u3002 try : < statements > except < exception type > : < statements > \u901a\u5e38\u6765\u8bf4\uff0c \u5bf9\u4e8e\u5df2\u77e5\u53ef\u80fd\u4f1a\u53d1\u751f\u7684\u5f02\u5e38\u7c7b\u578b\uff0c\u5e94\u8be5\u5c3d\u53ef\u80fd\u5730\u5305\u62ec\u5728\u5728 except \u8bed\u53e5\u91cc\u3002 \u5982\u679c\u4e0d\u77e5\u9053\u5f02\u5e38\u7684\u7c7b\u578b\uff0c\u53ef\u4ee5\u5728 except \u4e2d\u7528\u66f4\u901a\u7528\u7684Exception\u7c7b\u578b\u5339\u914d\u53ef\u80fd\u4f1a\u5f15\u53d1\u7684\u4efb\u4f55\u5f02\u5e38\u3002 \u793a\u4f8b\uff1a def getYourAge ( prompt ): \"\"\"\u63d0\u793a\u7528\u6237\u8f93\u5165\u4e00\u4e2a\u6574\u6570\uff0c\u5426\u5219\u7ed9\u51fa\u9519\u8bef\u63d0\u793a\uff0c\u5e76\u7ee7\u7eed\u63d0\u793a\u7528\u6237\u8f93\u5165\u3002\"\"\" inputStr = input ( prompt ) try : number = int ( inputStr ) return number except ValueError : print ( \"Error in number format:\" , inputStr ) return getYourAge ( prompt ) if __name__ == \"__main__\" : age = getYourAge ( \"Enter your age: \" ) print ( \"Your age is\" , age ) # \u8fd0\u884c\u7ed3\u679c # Enter your age: 3a # Error in number format: 3a # Enter your age: 3.5 # Error in number format: 3.5 # Enter your age: 20 # Your age is 20 1.7.\u6587\u4ef6\u53ca\u5176\u64cd\u4f5c \u00b6 1.7.1.\u6587\u672c\u6587\u4ef6\u8bfb\u53d6 \u00b6 \u53ef\u4ee5\u628a\u6587\u672c\u6587\u4ef6\u91cc\u7684\u6570\u636e\u770b\u4f5c\u5b57\u7b26\u3001\u5355\u8bcd\u3001\u6570\u5b57\u6216\u8005\u82e5\u5e72\u884c\u6587\u672c\u3002 \u5982\u679c\u628a\u6587\u672c\u6587\u4ef6\u91cc\u7684\u6570\u636e\u5f53\u4f5c\u6574\u6570\u6216\u6d6e\u70b9\u6570\uff0c\u5c31\u5fc5\u987b\u7528\u7a7a\u767d\u5b57\u7b26\uff08\u7a7a\u683c\u3001\u5236\u8868\u7b26\u548c\u6362\u884c\u7b26\uff09\u5c06\u5176\u5206\u9694\u5f00\u3002\u8f93\u51fa\u6216\u8f93\u5165\u5230\u6587\u672c\u6587\u4ef6\u7684\u6240\u6709\u6570\u636e\u5fc5\u987b\u662f\u5b57\u7b26\u4e32\u5f62\u5f0f\u7684\uff0c\u6240\u4ee5\u5728\u8f93\u5165/\u8f93\u51fa\u65f6\u9700\u8981\u505a\u76f8\u5e94\u7684\u7c7b\u578b\u8f6c\u6362\u3002 \u5982\u4e0b\u4f8b\uff1a 34.6 22.33 66.75 77.12 21.44 99.01 Python\u7684open\u51fd\u6570\u63a5\u6536\u4e0b\u9762\u4e24\u4e2a\u4e3b\u8981\u53c2\u6570\uff0c\u6253\u5f00\u4e00\u4e2a\u4e0e\u78c1\u76d8\u6587\u4ef6\u7684\u8fde\u63a5\u5e76\u4e14\u8fd4\u56de\u76f8\u5e94\u7684\u6587\u4ef6\u5bf9\u8c61\u3002 \u6587\u4ef6\u8def\u5f84\uff1b \u6253\u5f00\u6a21\u5f0f\uff1a \u6253\u5f00\u6a21\u5f0f\uff1a r \u8868\u793a\u6587\u4ef6\u53ea\u80fd\u8bfb\u53d6\uff1b w \u8868\u793a\u6587\u4ef6\u53ea\u80fd\u5199\u5165\uff1b a \u8868\u793a\u6253\u5f00\u6587\u4ef6\uff0c\u5728\u539f\u6709\u5185\u5bb9\u7684\u57fa\u7840\u4e0a\u8ffd\u52a0\u5185\u5bb9\uff0c\u5728\u672b\u5c3e\u5199\u5165\uff1b w+ \u8868\u793a\u53ef\u4ee5\u5bf9\u6587\u4ef6\u8fdb\u884c\u8bfb\u5199\u53cc\u91cd\u64cd\u4f5c\uff1b rb \u4ee5\u4e8c\u8fdb\u5236\u683c\u5f0f\u6253\u5f00\u4e00\u4e2a\u6587\u4ef6\uff0c\u7528\u4e8e\u53ea\u8bfb\uff1b wb \u4ee5\u4e8c\u8fdb\u5236\u683c\u5f0f\u6253\u5f00\u4e00\u4e2a\u6587\u4ef6\uff0c\u7528\u4e8e\u53ea\u5199\uff1b ab \u4ee5\u4e8c\u8fdb\u5236\u683c\u5f0f\u6253\u5f00\u4e00\u4e2a\u6587\u4ef6\uff0c\u7528\u4e8e\u8ffd\u52a0\uff1b wb+ \u4ee5\u4e8c\u8fdb\u5236\u683c\u5f0f\u6253\u5f00\u4e00\u4e2a\u6587\u4ef6\uff0c\u7528\u4e8e\u8bfb\u5199\uff1b \u793a\u4f8b\uff1a \u4e3a myfile.txt \u6587\u4ef6\u6253\u5f00\u4e00\u4e2a\u7528\u6765\u8f93\u51fa\u7684\u6587\u4ef6\u5bf9\u8c61\u3002 \u5b57\u7b26\u4e32\u6570\u636e\u901a\u8fc7 write \u65b9\u6cd5\u548c\u6587\u4ef6\u5bf9\u8c61\u5199\u5165\uff08\u6216\u8f93\u51fa\uff09\u5230\u6587\u4ef6\u91cc\u3002 \u8f6c\u4e49\u7b26 \\n \u5b9e\u73b0\u6362\u884c\u3002 \u4f7f\u7528 close \u65b9\u6cd5\u5173\u95ed\u6587\u4ef6\u3002\u5982\u679c\u6ca1\u6709\u5173\u95ed\u8f93\u51fa\u6587\u4ef6\uff0c\u5219\u53ef\u80fd\u5bfc\u81f4\u6570\u636e\u4e22\u5931\u3002 f = open ( \"./docs/python/DataStructure/code/myfile.txt\" , 'w' ) f . write ( \"First line. \\n Second line. \\n \" ) f . close () \u6587\u4ef6myfile.txt\u7684\u5185\u5bb9\uff1a First line. Second line. 1.7.2.\u6587\u672c\u6587\u4ef6\u5199\u5165 \u00b6 \u6587\u4ef6\u7684 write \u65b9\u6cd5\u63a5\u6536\u4e00\u4e2a\u5b57\u7b26\u4e32\u4f5c\u4e3a\u53c2\u6570\u3002\u56e0\u6b64\uff0c\u5176\u4ed6\u7c7b\u578b\u7684\u6570\u636e\uff08\u5982\u6574\u6570\u6216\u6d6e\u70b9\u6570\uff09\u5728\u5199\u5165\u8f93\u51fa\u6587\u4ef6\u4e4b\u524d\uff0c\u90fd\u5fc5\u987b\u5148\u88ab\u8f6c\u6362\u4e3a\u5b57\u7b26\u4e32\u3002 \u5728Python\u91cc\uff0c\u53ef\u4ee5\u4f7f\u7528 str \u51fd\u6570\u628a\u7edd\u5927\u591a\u6570\u7684\u6570\u636e\u7c7b\u578b\u7684\u503c\u8f6c\u6362\u4e3a\u5b57\u7b26\u4e32\uff0c\u4ee5\u7a7a\u683c\u6216\u6362\u884c\u7b26\u4f5c\u4e3a\u5206\u9694\u7b26\uff0c\u5c06\u5176\u5199\u5165\u6587\u4ef6\u91cc\u3002 \u793a\u4f8b\uff1a\u751f\u6210500\u4e2a\u4ecb\u4e8e1\u548c500\u4e4b\u95f4\u7684\u968f\u673a\u6570\uff0c\u5e76\u8f93\u51fa\u5230\u6587\u672c\u6587\u4ef6\u3002 import random f = open ( \"./docs/python/DataStructure/code/myfile.txt\" , 'w' ) for count in range ( 500 ): number = random . randint ( 1 , 500 ) f . write ( str ( number ) + \" \\n \" ) f . close () 1.7.3.\u4ece\u6587\u672c\u6587\u4ef6\u8bfb\u53d6\u6570\u636e \u00b6 \u793a\u4f8b\uff1a\u8bfb\u53d6\u6587\u4ef6\u5185\u5bb9\u3002 import random f = open ( \"./docs/python/DataStructure/code/myfile.txt\" , 'w' ) f . write ( \"First line. \\n Second line. \\n \" ) # \u521d\u59cb\u5316\u6587\u4ef6\u5185\u5bb9 f . close () # \u6253\u5f00\u6587\u4ef6\u8bfb\u53d6\u5185\u5bb9 f = open ( \"./docs/python/DataStructure/code/myfile.txt\" , 'r' ) text1 = f . read () # \u628a\u6587\u4ef6\u7684\u5168\u90e8\u5185\u5bb9\u8f93\u5165\u5355\u4e2a\u5b57\u7b26\u4e32\u4e2d print ( text1 ) # \u8fd0\u884c\u7ed3\u679c\uff1a # First line. # Second line text2 = f . read () # \u518d\u6b21read\uff0c\u5f97\u5230\u4e00\u4e2a\u7a7a\u5b57\u4e32\uff0c\u8868\u8ff0\u5df2\u7ecf\u5230\u8fbe\u6587\u4ef6\u672b\u5c3e\u3002\u8981\u518d\u6b21\u8bfb\u53d6\u9700\u8981\u91cd\u65b0\u6253\u5f00\u6587\u4ef6 print ( \"======\" ) print ( text2 ) # \u8fd0\u884c\u7ed3\u679c\uff1a # ====== # f . close () # \u91cd\u65b0\u6253\u5f00\u6587\u4ef6\u8bfb\u53d6\u5185\u5bb9 f = open ( \"./docs/python/DataStructure/code/myfile.txt\" , 'r' ) for line in f : # \u9010\u884c\u8bfb\u53d6\u6587\u4ef6\u5185\u5bb9 print ( \"======\" ) print ( line ) # \u6bcf\u884c\u90fd\u6709\u4e00\u4e2a\u6362\u884c\u7b26\uff0c\u8fd9\u662fprint\u51fd\u6570\u9ed8\u8ba4\u884c\u4e3a # \u8fd0\u884c\u7ed3\u679c\uff1a # ====== # First line. # ====== # Second line. # f . close () # \u91cd\u65b0\u6253\u5f00\u6587\u4ef6\u8bfb\u53d6\u5185\u5bb9 f = open ( \"./docs/python/DataStructure/code/myfile.txt\" , 'r' ) while True : line = f . readline () # readline\u65b9\u6cd5\u4f1a\u4ece\u8f93\u5165\u7684\u6587\u672c\u91cc\u53ea\u83b7\u53d6\u4e00\u884c\u6570\u636e\uff0c\u5e76\u4e14\u8fd4\u56de\u8fd9\u4e2a\u5305\u542b\u6362\u884c\u7b26\u7684\u5b57\u7b26\u4e32\u3002\u5982\u679creadline\u9047\u5230\u4e86\u6587\u4ef6\u672b\u5c3e\uff0c\u90a3\u4e48\u4f1a\u8fd4\u56de\u7a7a\u5b57\u7b26\u4e32\u3002 if line == \"\" : break print ( \"******\" ) print ( line ) # \u8fd0\u884c\u7ed3\u679c\uff1a # ****** # First line. # ****** # Second line. # f . close () # \u91cd\u65b0\u6253\u5f00\u6587\u4ef6\u8bfb\u53d6\u5185\u5bb9 f = open ( \"./docs/python/DataStructure/code/myfile.txt\" , 'r' ) line = f . readlines () # readlines\u65b9\u6cd5\u5219\u662f\u8bfb\u53d6\u6240\u6709\u884c\uff0c\u8fd4\u56de\u7684\u662f\u6240\u6709\u884c\u7ec4\u6210\u7684\u5217\u8868\u3002 print ( line ) # \u8fd0\u884c\u7ed3\u679c\uff1a # ['First line.\\n', 'Second line.\\n'] f . close () 1.7.4.\u4ece\u5176\u5b83\u6587\u4ef6\u8bfb\u53d6\u6570\u636e \u00b6 \u793a\u4f8b\uff1a\u8bfb\u53d6\u6587\u4ef6\u4e2d\u7684\u6574\u6570\uff0c\u6bcf\u884c\u53ea\u6709\u4e00\u4e2a\u6574\u6570\u3002 import random f = open ( \"./docs/python/DataStructure/code/myfile.txt\" , 'w' ) # \u751f\u62100~9\u6574\u6570\uff0c\u5e76\u5199\u5165\u6587\u4ef6 for count in range ( 10 ): f . write ( str ( count ) + \" \\n \" ) f . close () # \u6253\u5f00\u6587\u4ef6 f = open ( \"./docs/python/DataStructure/code/myfile.txt\" , 'r' ) # \u4f9d\u6b21\u8bfb\u53d6\u6587\u4ef6\u4e2d\u7684\u6570\u5b57\uff0c\u5e76\u6c42\u548c theSum = 0 for line in f : line = line . strip () number = int ( line ) theSum += number print ( \"The sum is : \" , theSum ) # \u8fd0\u884c\u7ed3\u679c\uff1a # The sum is : 45 f . close () \u793a\u4f8b\uff1a\u8bfb\u53d6\u6587\u4ef6\u4e2d\u7684\u6574\u6570\uff0c\u6bcf\u884c\u6709\u591a\u4e2a\u6574\u6570\u3002\u9700\u8981\u4e8b\u5148\u628a\u4e0b\u9762\u7684\u5185\u5bb9\u5199\u5165 myfile.txt \u6587\u4ef6\u4e2d\u3002 \u6587\u4ef6 myfile.txt \u7684\u5185\u5bb9\u3002 1 3 5 7 9 2 4 6 8 10 31 200 3000 50000 import random # \u6253\u5f00\u6587\u4ef6 f = open ( \"./docs/python/DataStructure/code/myfile.txt\" , 'r' ) # \u4f9d\u6b21\u8bfb\u53d6\u6587\u4ef6\u4e2d\u7684\u6570\u5b57\uff0c\u5e76\u6c42\u548c theSum = 0 for line in f : lines = line . split () # split\u65b9\u6cd5\u4f1a\u81ea\u52a8\u5904\u7406\u6362\u884c\u7b26 for word in lines : number = int ( word ) theSum += number print ( \"The sum is : \" , theSum ) # \u8fd0\u884c\u7ed3\u679c\uff1a # The sum is : 53286 f . close () \u7b80\u5199\u4e0a\u9762\u7684\u4ee3\u7801\u3002 import random f = open ( \"./docs/python/DataStructure/code/myfile.txt\" , 'r' ) print ( \"The sum is: \" , sum ( map ( int , f . read () . split ()))) # \u8fd0\u884c\u7ed3\u679c\uff1a # The sum is : 53286 f . close () 1.7.5.\u4f7f\u7528pickle\u8bfb\u5199\u5bf9\u8c61 \u00b6 \u5728\u628a\u4efb\u4f55\u5bf9\u8c61\u4fdd\u5b58\u5230\u6587\u4ef6\u4e4b\u524d\uff0c\u6211\u4eec\u53ef\u4ee5\u5bf9\u5b83\u8fdb\u884c\u201c\u814c\u5236\u201d\uff1b\u5728\u628a\u5bf9\u8c61\u4ece\u6587\u4ef6\u52a0\u8f7d\u5230\u7a0b\u5e8f\u4e2d\u65f6\uff0c\u4e5f\u53ef\u4ee5\u5bf9\u5b83\u8fdb\u884c\u201c\u53cd\u814c\u5236\u201d\u3002 \u793a\u4f8b\uff1a \u4f7f\u7528pickle\u6a21\u5757\u7684 pickle.dump \u628a\u540d\u4e3alyst\u7684\u5217\u8868\u91cc\u7684\u6240\u6709\u5bf9\u8c61\u4fdd\u5b58\u5230\u540d\u4e3aitems.dat\u7684\u6587\u4ef6\u91cc\uff08\u201c\u814c\u5236\u201d\uff09\u3002\u6211\u4eec\u4e0d\u9700\u8981\u77e5\u9053\u5217\u8868\u91cc\u6709\u54ea\u4e9b\u7c7b\u578b\u7684\u5bf9\u8c61\uff0c\u4e5f\u4e0d\u9700\u8981\u77e5\u9053\u6709\u591a\u5c11\u4e2a\u5bf9\u8c61\u3002 import pickle myList = [ 60 , \"A string object\" , 1977 ] fObj = open ( \"./docs/python/DataStructure/code/items.dat\" , \"wb\" ) for item in myList : pickle . dump ( item , fObj ) fObj . close () \u4f7f\u7528pickle\u6a21\u5757\u7684 pickle.load \u628aitems.dat\u7684\u6587\u4ef6\u5185\u5bb9\u52a0\u8f7d\u56de\u7a0b\u5e8f\uff08\u201c\u53cd\u814c\u5236\u201d\uff09\u3002 import pickle lyst = list () fileObj = open ( \"./docs/python/DataStructure/code/items.dat\" , \"rb\" ) while True : try : item = pickle . load ( fileObj ) lyst . append ( item ) except EOFError : # \u68c0\u6d4b\u5df2\u7ecf\u5230\u8fbe\u6587\u4ef6\u672b\u5c3e fileObj . close () break print ( lyst ) # \u8fd0\u884c\u7ed3\u679c\uff1a # [60, 'A string object', 1977] 1.8.\u521b\u5efa\u7c7b \u00b6 \u7c7b\uff08class\uff09\u7528\u6765\u63cf\u8ff0\u4e0e\u4e00\u7ec4\u5bf9\u8c61\u6709\u5173\u7684\u6570\u636e\u548c\u65b9\u6cd5\u3002\u5b83\u63d0\u4f9b\u4e86\u7528\u6765\u521b\u5efa\u5bf9\u8c61\u7684\u84dd\u56fe\uff0c\u4ee5\u53ca\u5728\u5bf9\u8c61\u4e0a\u8c03\u7528\u65b9\u6cd5\u65f6\u6240\u9700\u8981\u6267\u884c\u7684\u4ee3\u7801\u3002 Python\u91cc\u7684\u6570\u636e\u7c7b\u578b\u90fd\u662f\u7c7b\uff1b \u7c7b\u540d\u6309\u7167\u60ef\u4f8b\u9996\u5b57\u6bcd\u5e94\u4e3a\u5927\u5199\u6837\u5f0f\uff1b \u5b9a\u4e49\u7c7b\u7684\u4ee3\u7801\u901a\u5e38\u4f1a\u88ab\u5b58\u653e\u5728\u9996\u5b57\u6bcd\u5c0f\u5199\u7684\u7c7b\u540d\u7684\u6a21\u5757\u6587\u4ef6\u91cc\u3002 \u76f8\u5173\u7684\u7c7b\u4e5f\u53ef\u80fd\u4f1a\u51fa\u73b0\u5728\u540c\u4e00\u4e2a\u6a21\u5757\u91cc\u3002 \u7c7b\u7684\u8bed\u6cd5\uff1a def < class name > ( < parent class name > )[ 2 ]: < class variable assignments > < instance method definitions > \u7236\u7c7b\uff08parent class\uff09\u7684\u540d\u79f0\u662f\u53ef\u9009\u7684\uff0c\u5728\u9ed8\u8ba4\u60c5\u51b5\u4e0b\uff0c\u5b83\u4f1a\u662fobject\u3002 \u6240\u6709Python\u7c7b\u5c5e\u4e8e\u4e00\u4e2a\u4ee5 object \u4f5c\u4e3a\u6839\u8282\u70b9\u7684\u5c42\u6b21\u7ed3\u6784\u3002 \u5728 object \u91cc\uff0cPython\u5b9a\u4e49\u4e86\u51e0\u79cd\u65b9\u6cd5\uff1a __str__ \u548c __eq__ \uff0c\u56e0\u6b64\u6240\u6709\u5b50\u7c7b\u4f1a\u81ea\u52a8\u7ee7\u627f\u8fd9\u4e9b\u65b9\u6cd5\u3002 \u5b9e\u4f8b\u65b9\u6cd5\uff08instance method\uff09\u662f\u5728\u7c7b\u7684\u5bf9\u8c61\u4e0a\u8fd0\u884c\u7684\u3002\u5b83\u4eec\u5305\u542b\u7528\u6765\u8bbf\u95ee\u6216\u4fee\u6539\u5b9e\u4f8b\u53d8\u91cf\u7684\u4ee3\u7801\u3002 \u5b9e\u4f8b\u53d8\u91cf\uff08instance variable\uff09\u662f\u6307\u7531\u5355\u4e2a\u5bf9\u8c61\u6240\u62e5\u6709\u7684\u5b58\u50a8\u4fe1\u606f\u3002 \u7c7b\u53d8\u91cf\uff08class variable\uff09\u662f\u6307\u7531\u7c7b\u7684\u6240\u6709\u5bf9\u8c61\u5b58\u50a8\u6240\u6709\u7684\u4fe1\u606f\u3002 \u793a\u4f8b\uff1a\u89e3\u8bfbCounter\u7c7b\u3002 Counter \u7c7b\u662f object \u7684\u5b50\u7c7b\uff1b instances \u662f\u7c7b\u53d8\u91cf\uff0c\u8ddf\u8e2a\u5df2\u521b\u5efa\u7684\u8ba1\u6570\u5668\u5bf9\u8c61\u7684\u6570\u91cf\uff1b \u5b9e\u4f8b\u65b9\u6cd5 __init__ \u4e5f\u79f0\u4e3a\u6784\u9020\u51fd\u6570\uff1b\u8fd9\u4e2a\u65b9\u6cd5\u7528\u6765\u521d\u59cb\u5316\u5b9e\u4f8b\u53d8\u91cf\uff0c\u5e76\u4e14\u5bf9\u7c7b\u53d8\u91cf\u8fdb\u884c\u66f4\u65b0\uff1b self \u662f\u6307\u5728\u8fd0\u884c\u65f6\u8fd9\u4e2a\u65b9\u6cd5\u7684\u5bf9\u8c61\u672c\u8eab\uff1b \u4f7f\u7528\u5b9e\u4f8b\u53d8\u91cf\u90fd\u4f1a\u52a0\u4e0a\u524d\u7f00 self \uff1b\u548c\u53c2\u6570\u6216\u4e34\u65f6\u53d8\u91cf\u4e0d\u540c\u7684\u5730\u65b9\u662f\uff0c\u5b9e\u4f8b\u53d8\u91cf\u5728\u7c7b\u7684\u4efb\u4f55\u65b9\u6cd5\u91cc\u662f\u53ef\u89c1\u7684\uff1b \u5176\u4ed6\u5b9e\u4f8b\u65b9\u6cd5\u53ef\u4ee5\u5206\u4e3a\u4e24\u79cd\uff1a\u53d8\u5f02\u5668\uff08mutator\uff09\u548c\u8bbf\u95ee\u5668\uff08accessor\uff09\u3002\u53d8\u5f02\u5668\u4f1a\u901a\u8fc7\u4fee\u6539\u5bf9\u8c61\u7684\u5b9e\u4f8b\u53d8\u91cf\u5bf9\u5176\u5185\u90e8\u72b6\u6001\u8fdb\u884c\u4fee\u6539\u6216\u66f4\u6539\u3002\u8bbf\u95ee\u5668\u5219\u53ea\u4f1a\u67e5\u770b\u6216\u4f7f\u7528\u5bf9\u8c61\u7684\u5b9e\u4f8b\u53d8\u91cf\u7684\u503c\uff0c\u800c\u4e0d\u4f1a\u53bb\u4fee\u6539\u5b83\u4eec\uff1b __str__ \u65b9\u6cd5\u5c06\u8986\u76d6object\u7c7b\u91cc\u7684\u8fd9\u4e2a\u65b9\u6cd5\uff1b \u5f53Python\u7684 print \u51fd\u6570\u63a5\u6536\u5230\u4e00\u4e2a\u53c2\u6570\u65f6\uff0c\u8fd9\u4e2a\u53c2\u6570\u7684 __str__ \u65b9\u6cd5\u5c06\u81ea\u52a8\u8fd0\u884c\uff0c\u4ece\u800c\u5f97\u5230\u5b83\u7684\u5b57\u7b26\u4e32\u8868\u8fbe\u5f0f\uff0c\u4ee5\u4fbf\u7528\u6765\u8f93\u51fa\uff1b \u5f53\u770b\u5230 == \u8fd0\u7b97\u7b26\u65f6\uff0cPython\u5c06\u8fd0\u884c __eq__ \u65b9\u6cd5\uff1b\u5728 object \u7c7b\u91cc\uff0c\u8fd9\u4e2a\u65b9\u6cd5\u7684\u9ed8\u8ba4\u5b9a\u4e49\u662f\u8fd0\u884c is \u8fd0\u7b97\u7b26\u3002 class Counter ( object ): # Counter\u7c7b\u662fobject\u7684\u5b50\u7c7b \"\"\"Models a counter.\"\"\" # Class variable \u7c7b\u53d8\u91cf instances = 0 # \u8ddf\u8e2a\u5df2\u521b\u5efa\u7684\u8ba1\u6570\u5668\u5bf9\u8c61\u7684\u6570\u91cf # Constructor \u6784\u9020\u5668 # \u5b9e\u4f8b\u65b9\u6cd5__init__\u4e5f\u79f0\u4e3a\u6784\u9020\u51fd\u6570\uff1b\u8fd9\u4e2a\u65b9\u6cd5\u7528\u6765\u521d\u59cb\u5316\u5b9e\u4f8b\u53d8\u91cf\uff0c\u5e76\u4e14\u5bf9\u7c7b\u53d8\u91cf\u8fdb\u884c\u66f4\u65b0\uff1b def __init__ ( self ): # self\u662f\u6307\u5728\u8fd0\u884c\u65f6\u8fd9\u4e2a\u65b9\u6cd5\u7684\u5bf9\u8c61\u672c\u8eab \"\"\"Sets up the counter.\"\"\" Counter . instances += 1 self . reset () # Mutator methods def reset ( self ): \"\"\"Sets the counter to 0.\"\"\" self . value = 0 def increment ( self , amount = 1 ): \"\"\"Adds amount to the counter.\"\"\" self . value += amount def decrement ( self , amount = 1 ): \"\"\"Subtracts amount from the counter.\"\"\" self . value -= amount # Accessor methods def getValue ( self ): \"\"\"Returns the counter's value.\"\"\" return self . value def __str__ ( self ): \"\"\"Returns the string representation of the counter.\"\"\" return str ( self . value ) def __eq__ ( self , other ): \"\"\"Returns True if self equals other or False otherwise.\"\"\" if self is other : return True if type ( self ) != type ( other ): return False return self . value == other . value c1 = Counter () print ( c1 ) # \u8fd0\u884c\u7ed3\u679c\uff1a # 0 c1 . getValue () str ( c1 ) c1 . increment () print ( c1 ) # \u8fd0\u884c\u7ed3\u679c\uff1a # 1 c1 . increment ( 5 ) print ( c1 ) # \u8fd0\u884c\u7ed3\u679c\uff1a # 6 c1 . reset () print ( c1 ) # \u8fd0\u884c\u7ed3\u679c\uff1a # 0 c2 = Counter () print ( Counter . instances ) # \u8fd0\u884c\u7ed3\u679c\uff1a # 2 print ( c1 == c1 ) # \u8fd0\u884c\u7ed3\u679c\uff1a # True print ( c1 == 0 ) # \u8fd0\u884c\u7ed3\u679c\uff1a # False print ( c1 == c2 ) # \u8fd0\u884c\u7ed3\u679c\uff1a # True c2 . increment () print ( c1 == c2 ) # \u8fd0\u884c\u7ed3\u679c\uff1a # False 1.9.\u7f16\u7a0b\u7ec3\u4e60 \u00b6 1\uff0e\u7f16\u5199\u4e00\u4e2a\u7a0b\u5e8f\uff0c\u4f7f\u4e4b\u80fd\u591f\u63a5\u6536\u7403\u4f53\u7684\u534a\u5f84\uff08\u6d6e\u70b9\u6570\uff09\uff0c\u5e76\u4e14\u53ef\u4ee5\u8f93\u51fa\u7403\u4f53\u7684\u76f4\u5f84\u3001\u5468\u957f\u3001\u8868\u9762\u79ef\u4ee5\u53ca\u4f53\u79ef\u3002 \u89e3\u7b54\uff1a PAI = 3.14 radius = float ( input ( \"\u8f93\u5165\u7403\u534a\u5f84\uff1a\" )) diameter = radius * 2 circumference = 2 * PAI * radius surfaceArea = 4 * PAI * radius ** 2 sphereVolume = 4 * ( PAI * radius ** 3 ) / 3 print ( \"\u7403\u534a\u5f84\uff1a\" , radius , \"\u7403\u76f4\u5f84\uff1a\" , diameter , \"\u7403\u8868\u9762\u79ef\uff1a\" , surfaceArea , \"\u7403\u4f53\u79ef\uff1a\" , sphereVolume ) # \u8fd0\u884c\u7ed3\u679c\uff1a # \u8f93\u5165\u7403\u534a\u5f84\uff1a3.5 # \u7403\u534a\u5f84\uff1a 3.5 \u7403\u76f4\u5f84\uff1a 7.0 \u7403\u8868\u9762\u79ef\uff1a 153.86 \u7403\u4f53\u79ef\uff1a 179.50333333333333 import math def main (): try : radius = float ( input ( \"\u8bf7\u8f93\u5165\u7403\u534a\u5f84\uff1a\" )) if radius <= 0 : print ( \"\u534a\u5f84\u5fc5\u987b\u4e3a\u6b63\u6570\uff01\" ) return diameter = 2 * radius circumference = 2 * math . pi * radius surfaceArea = 4 * math . pi * radius ** 2 volume = ( 4 / 3 ) * math . pi * radius ** 3 print ( f \"\u7403\u4f53\u7684\u76f4\u5f84\uff1a { diameter : .2f } \" ) print ( f \"\u7403\u4f53\u7684\u5468\u957f\uff1a { circumference : .2f } \" ) print ( f \"\u7403\u4f53\u7684\u8868\u9762\u79ef\uff1a { surfaceArea : .2f } \" ) print ( f \"\u7403\u4f53\u7684\u4f53\u79ef\uff1a { volume : .2f } \" ) except ValueError : print ( \"\u8bf7\u8f93\u5165\u6709\u6548\u7684\u6570\u5b57\uff01\" ) if __name__ == \"__main__\" : main () # \u8fd0\u884c\u7ed3\u679c\uff1a # \u8bf7\u8f93\u5165\u7403\u534a\u5f84\uff1a3.5 # \u7403\u4f53\u7684\u76f4\u5f84\uff1a7.00 # \u7403\u4f53\u7684\u5468\u957f\uff1a21.99 # \u7403\u4f53\u7684\u8868\u9762\u79ef\uff1a153.94 # \u7403\u4f53\u7684\u4f53\u79ef\uff1a179.59 import math class Sphere : def __init__ ( self , radius ): self . radius = radius def diameter ( self ): return 2 * self . radius def circumference ( self ): return 2 * math . pi * self . radius def surfaceArea ( self ): return 4 * math . pi * self . radius ** 2 def volume ( self ): return ( 4 / 3 ) * math . pi * self . radius ** 3 def main (): try : radius = float ( input ( \"\u8bf7\u8f93\u5165\u7403\u4f53\u7684\u534a\u5f84\uff1a\" )) if radius <= 0 : print ( \"\u534a\u5f84\u5fc5\u987b\u4e3a\u6b63\u6570\uff01\" ) return sphere = Sphere ( radius ) print ( f \"\u7403\u4f53\u7684\u76f4\u5f84\uff1a { sphere . diameter () : .2f } \" ) print ( f \"\u7403\u4f53\u7684\u5468\u957f\uff1a { sphere . circumference () : .2f } \" ) print ( f \"\u7403\u4f53\u7684\u8868\u9762\u79ef\uff1a { sphere . surfaceArea () : .2f } \" ) print ( f \"\u7403\u4f53\u7684\u4f53\u79ef\uff1a { sphere . volume () : .2f } \" ) except ValueError : print ( \"\u8bf7\u8f93\u5165\u6709\u6548\u7684\u6570\u5b57\uff01\" ) if __name__ == \"__main__\" : main () # \u8fd0\u884c\u7ed3\u679c\uff1a # \u8bf7\u8f93\u5165\u7403\u4f53\u7684\u534a\u5f84\uff1a3.5 # \u7403\u4f53\u7684\u76f4\u5f84\uff1a7.00 # \u7403\u4f53\u7684\u5468\u957f\uff1a21.99 # \u7403\u4f53\u7684\u8868\u9762\u79ef\uff1a153.94 # \u7403\u4f53\u7684\u4f53\u79ef\uff1a179.59 2\uff0e\u5458\u5de5\u7684\u5468\u5de5\u8d44\u7b49\u4e8e\u5c0f\u65f6\u5de5\u8d44\u4e58\u4ee5\u6b63\u5e38\u7684\u603b\u5de5\u4f5c\u65f6\u95f4\u518d\u52a0\u4e0a\u52a0\u73ed\u5de5\u8d44\u3002\u52a0\u73ed\u5de5\u8d44\u7b49\u4e8e\u603b\u52a0\u73ed\u65f6\u95f4\u4e58\u4ee5\u5c0f\u65f6\u5de5\u8d44\u76841.5\u500d\u3002\u7f16\u5199\u4e00\u4e2a\u7a0b\u5e8f\uff0c\u8ba9\u7528\u6237\u53ef\u4ee5\u8f93\u5165\u5c0f\u65f6\u5de5\u8d44\u3001\u6b63\u5e38\u7684\u603b\u5de5\u4f5c\u65f6\u95f4\u4ee5\u53ca\u52a0\u73ed\u603b\u65f6\u95f4\uff0c\u7136\u540e\u663e\u793a\u51fa\u5458\u5de5\u7684\u5468\u5de5\u8d44\u3002 \u89e3\u7b54\uff1a hourSalary = float ( input ( \"\u8f93\u5165\u5c0f\u65f6\u5de5\u8d44\uff08\u5143\uff09\uff1a\" )) totalWorkingHours = float ( input ( \"\u8f93\u5165\u672c\u5468\u6b63\u5e38\u603b\u5de5\u4f5c\u65f6\u95f4\uff08\u5c0f\u65f6\uff09\uff1a\" )) totalOvertimeHours = float ( input ( \"\u8f93\u5165\u672c\u5468\u603b\u52a0\u73ed\u603b\u5de5\u4f5c\u65f6\u95f4\uff08\u5c0f\u65f6\uff09\uff1a\" )) weeklySalary = hourSalary * totalWorkingHours + hourSalary * totalOvertimeHours * 1.5 print ( \"\u5458\u5de5\u7684\u5468\u5de5\u8d44\uff08\u5143\uff09\u662f\uff1a\" , weeklySalary ) # \u8fd0\u884c\u7ed3\u679c\uff1a # \u8f93\u5165\u5c0f\u65f6\u5de5\u8d44\uff08\u5143\uff09\uff1a20 # \u8f93\u5165\u672c\u5468\u6b63\u5e38\u603b\u5de5\u4f5c\u65f6\u95f4\uff08\u5c0f\u65f6\uff09\uff1a40 # \u8f93\u5165\u672c\u5468\u603b\u52a0\u73ed\u603b\u5de5\u4f5c\u65f6\u95f4\uff08\u5c0f\u65f6\uff09\uff1a10 # \u5458\u5de5\u7684\u5468\u5de5\u8d44\uff08\u5143\uff09\u662f\uff1a 1100.0 def calculate_weekly_salary ( hourly_wage , normal_hours , overtime_hours ): overtime_pay = overtime_hours * hourly_wage * 1.5 normal_pay = normal_hours * hourly_wage weekly_salary = normal_pay + overtime_pay return weekly_salary def main (): try : hourly_wage = float ( input ( \"\u8bf7\u8f93\u5165\u5c0f\u65f6\u5de5\u8d44\uff1a\" )) normal_hours = float ( input ( \"\u8bf7\u8f93\u5165\u6b63\u5e38\u7684\u603b\u5de5\u4f5c\u65f6\u95f4\uff08\u5c0f\u65f6\uff09\uff1a\" )) overtime_hours = float ( input ( \"\u8bf7\u8f93\u5165\u52a0\u73ed\u603b\u65f6\u95f4\uff08\u5c0f\u65f6\uff09\uff1a\" )) weekly_salary = calculate_weekly_salary ( hourly_wage , normal_hours , overtime_hours ) print ( f \"\u5458\u5de5\u7684\u5468\u5de5\u8d44\u4e3a\uff1a { weekly_salary : .2f } \" ) except ValueError : print ( \"\u8bf7\u8f93\u5165\u6709\u6548\u7684\u6570\u5b57\uff01\" ) if __name__ == \"__main__\" : main () # \u8fd0\u884c\u7ed3\u679c\uff1a # \u8bf7\u8f93\u5165\u5c0f\u65f6\u5de5\u8d44\uff1a20 # \u8bf7\u8f93\u5165\u6b63\u5e38\u7684\u603b\u5de5\u4f5c\u65f6\u95f4\uff08\u5c0f\u65f6\uff09\uff1a40 # \u8bf7\u8f93\u5165\u52a0\u73ed\u603b\u65f6\u95f4\uff08\u5c0f\u65f6\uff09\uff1a10 # \u5458\u5de5\u7684\u5468\u5de5\u8d44\u4e3a\uff1a1100.00 class Employee : def __init__ ( self , hourly_wage , normal_hours , overtime_hours ): self . hourly_wage = hourly_wage self . normal_hours = normal_hours self . overtime_hours = overtime_hours def calculate_weekly_salary ( self ): overtime_pay = self . overtime_hours * self . hourly_wage * 1.5 normal_pay = self . normal_hours * self . hourly_wage weekly_salary = normal_pay + overtime_pay return weekly_salary def main (): try : hourly_wage = float ( input ( \"\u8bf7\u8f93\u5165\u5c0f\u65f6\u5de5\u8d44\uff1a\" )) normal_hours = float ( input ( \"\u8bf7\u8f93\u5165\u6b63\u5e38\u7684\u603b\u5de5\u4f5c\u65f6\u95f4\uff08\u5c0f\u65f6\uff09\uff1a\" )) overtime_hours = float ( input ( \"\u8bf7\u8f93\u5165\u52a0\u73ed\u603b\u65f6\u95f4\uff08\u5c0f\u65f6\uff09\uff1a\" )) employee = Employee ( hourly_wage , normal_hours , overtime_hours ) weekly_salary = employee . calculate_weekly_salary () print ( f \"\u5458\u5de5\u7684\u5468\u5de5\u8d44\u4e3a\uff1a { weekly_salary : .2f } \" ) except ValueError : print ( \"\u8bf7\u8f93\u5165\u6709\u6548\u7684\u6570\u5b57\uff01\" ) if __name__ == \"__main__\" : main () # \u8fd0\u884c\u7ed3\u679c\uff1a # \u8bf7\u8f93\u5165\u5c0f\u65f6\u5de5\u8d44\uff1a20 # \u8bf7\u8f93\u5165\u6b63\u5e38\u7684\u603b\u5de5\u4f5c\u65f6\u95f4\uff08\u5c0f\u65f6\uff09\uff1a40 # \u8bf7\u8f93\u5165\u52a0\u73ed\u603b\u65f6\u95f4\uff08\u5c0f\u65f6\uff09\uff1a10 # \u5458\u5de5\u7684\u5468\u5de5\u8d44\u4e3a\uff1a1100.00 3\uff0e\u6709\u4e00\u4e2a\u6807\u51c6\u7684\u79d1\u5b66\u5b9e\u9a8c\uff1a\u6254\u4e00\u4e2a\u7403\uff0c\u770b\u770b\u5b83\u80fd\u53cd\u5f39\u591a\u9ad8\u3002\u4e00\u65e6\u786e\u5b9a\u4e86\u7403\u7684\u201c\u53cd\u5f39\u9ad8\u5ea6\u201d\uff0c\u8fd9\u4e2a\u6bd4\u503c\u5c31\u7ed9\u51fa\u4e86\u76f8\u5e94\u7684\u53cd\u5f39\u5ea6\u6307\u6570\u3002\u4f8b\u5982\uff0c\u5982\u679c\u4ece10ft\uff081ft=0.3048m\uff09\u9ad8\u5904\u6389\u843d\u7684\u7403\u53ef\u4ee5\u53cd\u5f39\u52306 ft\u9ad8\uff0c\u90a3\u4e48\u76f8\u5e94\u7684\u53cd\u5f39\u5ea6\u6307\u6570\u5c31\u662f0.6\uff1b\u5728\u4e00\u6b21\u53cd\u5f39\u4e4b\u540e\uff0c\u7403\u7684\u603b\u884c\u8fdb\u8ddd\u79bb\u662f16 ft\u3002\u63a5\u4e0b\u6765\uff0c\u7403\u7ee7\u7eed\u5f39\u8df3\uff0c\u90a3\u4e48\u4e24\u6b21\u5f39\u8df3\u540e\u7684\u603b\u8ddd\u79bb\u5e94\u8be5\u662f\uff1a10 ft + 6 ft + 6 ft + 3.6 ft = 25.6 ft\u3002\u53ef\u4ee5\u770b\u5230\uff0c\u6bcf\u6b21\u8fde\u7eed\u5f39\u8df3\u6240\u7ecf\u8fc7\u7684\u8ddd\u79bb\u662f\uff1a\u7403\u5230\u5730\u9762\u7684\u8ddd\u79bb\uff0c\u52a0\u4e0a\u8fd9\u4e2a\u8ddd\u79bb\u4e58\u4ee5 0.6\uff0c\u8fd9\u65f6\u7403\u53c8\u5f39\u56de\u6765\u4e86\u3002\u7f16\u5199\u4e00\u4e2a\u7a0b\u5e8f\uff0c\u53ef\u4ee5\u8ba9\u7528\u6237\u8f93\u5165\u7403\u7684\u521d\u59cb\u9ad8\u5ea6\u548c\u5141\u8bb8\u7403\u5f39\u8df3\u7684\u6b21\u6570\uff0c\u5e76\u8f93\u51fa\u7403\u6240\u7ecf\u8fc7\u7684\u603b\u8ddd\u79bb\u3002 \u89e3\u7b54\uff1a height = float ( input ( \"\u8f93\u5165\u5c0f\u7403\u521d\u59cb\u9ad8\u5ea6\uff08ft\uff09\uff1a\" )) times = float ( input ( \"\u8f93\u5165\u5141\u8bb8\u5c0f\u7403\u5f39\u8df3\u6b21\u6570\uff1a\" )) distance = 0 traceDistance = 0 while times : distance = height + 0.6 * height traceDistance += distance height = 0.6 * height times -= 1 print ( \"\u5c0f\u7403\u7ecf\u8fc7\u7684\u603b\u8ddd\u79bb\uff08ft\uff09\uff1a\" , traceDistance ) # \u8fd0\u884c\u7ed3\u679c\uff1a # \u8f93\u5165\u5c0f\u7403\u521d\u59cb\u9ad8\u5ea6\uff08ft\uff09\uff1a50 # \u8f93\u5165\u5141\u8bb8\u5c0f\u7403\u5f39\u8df3\u6b21\u6570\uff1a5 # \u5c0f\u7403\u7ecf\u8fc7\u7684\u603b\u8ddd\u79bb\uff08ft\uff09\uff1a 184.448 # \u8f93\u5165\u5c0f\u7403\u521d\u59cb\u9ad8\u5ea6\uff08ft\uff09\uff1a100 # \u8f93\u5165\u5141\u8bb8\u5c0f\u7403\u5f39\u8df3\u6b21\u6570\uff1a10 # \u5c0f\u7403\u7ecf\u8fc7\u7684\u603b\u8ddd\u79bb\uff08ft\uff09\uff1a 397.58135296000006 def calculate_total_distance ( initial_height , num_bounces ): rebound_factor = 0.6 total_distance = 0 height = initial_height for _ in range ( num_bounces + 1 ): total_distance += height height *= rebound_factor return total_distance def main (): try : initial_height = float ( input ( \"\u8bf7\u8f93\u5165\u7403\u7684\u521d\u59cb\u9ad8\u5ea6\uff08\u5355\u4f4d\uff1aft\uff09\uff1a\" )) num_bounces = int ( input ( \"\u8bf7\u8f93\u5165\u5141\u8bb8\u7403\u5f39\u8df3\u7684\u6b21\u6570\uff1a\" )) total_distance = calculate_total_distance ( initial_height , num_bounces ) print ( f \"\u7403\u6240\u7ecf\u8fc7\u7684\u603b\u8ddd\u79bb\u4e3a\uff1a { total_distance : .2f } ft\" ) except ValueError : print ( \"\u8bf7\u8f93\u5165\u6709\u6548\u7684\u6570\u5b57\uff01\" ) if __name__ == \"__main__\" : main () # \u8fd0\u884c\u7ed3\u679c\uff1a # \u8bf7\u8f93\u5165\u7403\u7684\u521d\u59cb\u9ad8\u5ea6\uff08\u5355\u4f4d\uff1aft\uff09\uff1a50 # \u8bf7\u8f93\u5165\u5141\u8bb8\u7403\u5f39\u8df3\u7684\u6b21\u6570\uff1a5 # \u7403\u6240\u7ecf\u8fc7\u7684\u603b\u8ddd\u79bb\u4e3a\uff1a119.17 ft # \u8bf7\u8f93\u5165\u7403\u7684\u521d\u59cb\u9ad8\u5ea6\uff08\u5355\u4f4d\uff1aft\uff09\uff1a100 # \u8bf7\u8f93\u5165\u5141\u8bb8\u7403\u5f39\u8df3\u7684\u6b21\u6570\uff1a10 # \u7403\u6240\u7ecf\u8fc7\u7684\u603b\u8ddd\u79bb\u4e3a\uff1a249.09 ft class BouncingBall : def __init__ ( self , initial_height , num_bounces ): self . initial_height = initial_height self . num_bounces = num_bounces self . rebound_factor = 0.6 def calculate_total_distance ( self ): total_distance = 0 height = self . initial_height for _ in range ( self . num_bounces + 1 ): total_distance += height height *= self . rebound_factor return total_distance def main (): try : initial_height = float ( input ( \"\u8bf7\u8f93\u5165\u7403\u7684\u521d\u59cb\u9ad8\u5ea6\uff08\u5355\u4f4d\uff1aft\uff09\uff1a\" )) num_bounces = int ( input ( \"\u8bf7\u8f93\u5165\u5141\u8bb8\u7403\u5f39\u8df3\u7684\u6b21\u6570\uff1a\" )) bouncing_ball = BouncingBall ( initial_height , num_bounces ) total_distance = bouncing_ball . calculate_total_distance () print ( f \"\u7403\u6240\u7ecf\u8fc7\u7684\u603b\u8ddd\u79bb\u4e3a\uff1a { total_distance : .2f } ft\" ) except ValueError : print ( \"\u8bf7\u8f93\u5165\u6709\u6548\u7684\u6570\u5b57\uff01\" ) if __name__ == \"__main__\" : main () 4\uff0e\u5fb7\u56fd\u6570\u5b66\u5bb6Gottfried Leibniz\u53d1\u660e\u4e86\u4e0b\u9762\u8fd9\u4e2a\u7528\u6765\u6c42\u03c0\u7684\u8fd1\u4f3c\u503c\u7684\u65b9\u6cd5\uff1a \u03c0/4 = 1 - 1/3 + 1/5 - 1/7 + ...... \uff0c\u8bf7\u7f16\u5199\u4e00\u4e2a\u7a0b\u5e8f\uff0c\u8ba9\u7528\u6237\u53ef\u4ee5\u6307\u5b9a\u8fd9\u4e2a\u8fd1\u4f3c\u503c\u6240\u4f7f\u7528\u7684\u8fed\u4ee3\u6b21\u6570\uff0c\u5e76\u4e14\u663e\u793a\u51fa\u7ed3\u679c\u3002 \u89e3\u7b54\uff1a n = int ( input ( \"\u8f93\u5165\u8fed\u4ee3\u6b21\u6570\uff1a\" )) mySum = 0 while n : mySum += 1 / ( 2 * n - 1 ) * (( - 1 ) ** ( n + 1 )) n -= 1 print ( \"\u03c0\u7684\u8fd1\u4f3c\u503c\u662f\uff1a\" , mySum * 4 ) # \u8fd0\u884c\u7ed3\u679c\uff1a # \u8f93\u5165\u8fed\u4ee3\u6b21\u6570\uff1a5 # \u03c0\u7684\u8fd1\u4f3c\u503c\u662f\uff1a 3.33968253968254 # \u8f93\u5165\u8fed\u4ee3\u6b21\u6570\uff1a10 # \u03c0\u7684\u8fd1\u4f3c\u503c\u662f\uff1a 3.0418396189294024 # \u8f93\u5165\u8fed\u4ee3\u6b21\u6570\uff1a20 # \u03c0\u7684\u8fd1\u4f3c\u503c\u662f\uff1a 3.0916238066678385 # \u8f93\u5165\u8fed\u4ee3\u6b21\u6570\uff1a10000000 # \u03c0\u7684\u8fd1\u4f3c\u503c\u662f\uff1a 3.1415925535897933 def calculate_pi_approximation ( iterations ): approximation = 0 sign = 1 for i in range ( 1 , iterations * 2 , 2 ): approximation += sign * ( 1 / i ) sign *= - 1 return approximation * 4 def main (): try : iterations = int ( input ( \"\u8bf7\u8f93\u5165\u8fed\u4ee3\u6b21\u6570\uff1a\" )) if iterations <= 0 : print ( \"\u8fed\u4ee3\u6b21\u6570\u5fc5\u987b\u4e3a\u6b63\u6574\u6570\uff01\" ) return pi_approximation = calculate_pi_approximation ( iterations ) print ( f \"\u03c0 \u7684\u8fd1\u4f3c\u503c\u4e3a\uff1a { pi_approximation : .10f } \" ) except ValueError : print ( \"\u8bf7\u8f93\u5165\u6709\u6548\u7684\u6574\u6570\uff01\" ) if __name__ == \"__main__\" : main () # \u8fd0\u884c\u7ed3\u679c\uff1a # \u8bf7\u8f93\u5165\u8fed\u4ee3\u6b21\u6570\uff1a5 # \u03c0 \u7684\u8fd1\u4f3c\u503c\u4e3a\uff1a3.3396825397 # \u8bf7\u8f93\u5165\u8fed\u4ee3\u6b21\u6570\uff1a10 # \u03c0 \u7684\u8fd1\u4f3c\u503c\u4e3a\uff1a3.0418396189 # \u8bf7\u8f93\u5165\u8fed\u4ee3\u6b21\u6570\uff1a20 # \u03c0 \u7684\u8fd1\u4f3c\u503c\u4e3a\uff1a3.0916238067 # \u8bf7\u8f93\u5165\u8fed\u4ee3\u6b21\u6570\uff1a10000000 # \u03c0 \u7684\u8fd1\u4f3c\u503c\u4e3a\uff1a3.1415925536 class PiApproximation : @classmethod def calculate_pi_approximation ( cls , iterations ): approximation = 0 sign = 1 for i in range ( 1 , iterations * 2 , 2 ): approximation += sign * ( 1 / i ) sign *= - 1 return approximation * 4 def main (): try : iterations = int ( input ( \"\u8bf7\u8f93\u5165\u8fed\u4ee3\u6b21\u6570\uff1a\" )) if iterations <= 0 : print ( \"\u8fed\u4ee3\u6b21\u6570\u5fc5\u987b\u4e3a\u6b63\u6574\u6570\uff01\" ) return pi_approximation = PiApproximation . calculate_pi_approximation ( iterations ) print ( f \"\u03c0 \u7684\u8fd1\u4f3c\u503c\u4e3a\uff1a { pi_approximation : .10f } \" ) except ValueError : print ( \"\u8bf7\u8f93\u5165\u6709\u6548\u7684\u6574\u6570\uff01\" ) if __name__ == \"__main__\" : main () # \u8fd0\u884c\u7ed3\u679c\uff1a # \u8f93\u5165\u8fed\u4ee3\u6b21\u6570\uff1a5 # \u03c0 \u7684\u8fd1\u4f3c\u503c\u4e3a\uff1a3.3396825397 # \u8bf7\u8f93\u5165\u8fed\u4ee3\u6b21\u6570\uff1a10 # \u03c0 \u7684\u8fd1\u4f3c\u503c\u4e3a\uff1a3.0418396189 # \u8bf7\u8f93\u5165\u8fed\u4ee3\u6b21\u6570\uff1a20 # \u03c0 \u7684\u8fd1\u4f3c\u503c\u4e3a\uff1a3.0916238067 # \u8bf7\u8f93\u5165\u8fed\u4ee3\u6b21\u6570\uff1a10000000 # \u03c0 \u7684\u8fd1\u4f3c\u503c\u4e3a\uff1a3.1415925536 5\uff0e\u67d0\u8ba1\u7b97\u673a\u5546\u5e97\u6709\u8d2d\u4e70\u8ba1\u7b97\u673a\u7684\u4fe1\u8d37\u8ba1\u5212\uff1a\u9996\u4ed810%\uff0c\u5e74\u5229\u7387\u4e3a12%\uff0c\u6bcf\u6708\u6240\u4ed8\u6b3e\u4e3a\u8d2d\u4e70\u4ef7\u683c\u51cf\u53bb\u9996\u4ed8\u4e4b\u540e\u76845%\u3002\u7f16\u5199\u4e00\u4e2a\u4ee5\u8d2d\u4e70\u4ef7\u683c\u4e3a\u8f93\u5165\u7684\u7a0b\u5e8f\uff0c\u53ef\u4ee5\u8f93\u51fa\u4e00\u4e2a\u6709\u9002\u5f53\u6807\u9898\u7684\u8868\u683c\uff0c\u663e\u793a\u8d37\u6b3e\u671f\u9650\u5185\u7684\u4ed8\u6b3e\u8ba1\u5212\u3002\u8868\u7684\u6bcf\u4e00\u884c\u90fd\u5e94\u5305\u542b\u4e0b\u9762\u5404\u9879\uff1a \u6708\u6570\uff08\u4ee51\u5f00\u5934\uff09\uff1b \u5f53\u524d\u6240\u6b20\u7684\u4f59\u989d\uff1b \u5f53\u6708\u6240\u6b20\u7684\u5229\u606f\uff1b \u5f53\u6708\u6240\u6b20\u7684\u672c\u91d1\uff1b \u5f53\u6708\u6240\u9700\u4ed8\u6b3e\u91d1\u989d\uff1b \u4ed8\u6b3e\u4e4b\u540e\u6240\u6b20\u7684\u91d1\u989d\u3002 \u4e00\u4e2a\u6708\u7684\u5229\u606f\u7b49\u4e8e\u4f59\u989d \u00d7 \u5229\u7387/12\uff1b\u4e00\u4e2a\u6708\u6240\u6b20\u7684\u672c\u91d1\u7b49\u4e8e\u5f53\u6708\u8fd8\u6b3e\u989d\u51cf\u53bb\u6240\u6b20\u7684\u5229\u606f\u3002 \u89e3\u7b54\uff1a def calculate_payment_schedule ( purchase_price ): down_payment = purchase_price * 0.1 loan_balance = purchase_price - down_payment annual_interest_rate = 0.12 monthly_interest_rate = annual_interest_rate / 12 monthly_payment = ( purchase_price - down_payment ) * 0.05 payment_schedule = [] for month in range ( 1 , 13 ): interest = loan_balance * monthly_interest_rate principal = monthly_payment - interest loan_balance -= principal payment_schedule . append (( month , loan_balance , interest , principal , monthly_payment , loan_balance + monthly_payment )) return payment_schedule def main (): try : purchase_price = float ( input ( \"\u8bf7\u8f93\u5165\u8d2d\u4e70\u4ef7\u683c\uff1a\" )) payment_schedule = calculate_payment_schedule ( purchase_price ) print ( \" {:<10} {:<15} {:<15} {:<15} {:<15} {:<15} \" . format ( \"\u6708\u6570\" , \"\u5f53\u524d\u6240\u6b20\u7684\u4f59\u989d\" , \"\u5f53\u6708\u6240\u6b20\u7684\u5229\u606f\" , \"\u5f53\u6708\u6240\u6b20\u7684\u672c\u91d1\" , \"\u5f53\u6708\u6240\u9700\u4ed8\u6b3e\u91d1\u989d\" , \"\u4ed8\u6b3e\u4e4b\u540e\u6240\u6b20\u7684\u91d1\u989d\" )) for payment in payment_schedule : month , balance , interest , principal , monthly_payment , new_balance = payment print ( \" {:<10} {:<15.2f} {:<15.2f} {:<15.2f} {:<15.2f} {:<15.2f} \" . format ( month , balance , interest , principal , monthly_payment , new_balance )) except ValueError : print ( \"\u8bf7\u8f93\u5165\u6709\u6548\u7684\u6570\u5b57\uff01\" ) if __name__ == \"__main__\" : main () # \u8fd0\u884c\u7ed3\u679c\uff1a # \u8bf7\u8f93\u5165\u8d2d\u4e70\u4ef7\u683c\uff1a5000 # \u6708\u6570 \u5f53\u524d\u6240\u6b20\u7684\u4f59\u989d \u5f53\u6708\u6240\u6b20\u7684\u5229\u606f \u5f53\u6708\u6240\u6b20\u7684\u672c\u91d1 \u5f53\u6708\u6240\u9700\u4ed8\u6b3e\u91d1\u989d \u4ed8\u6b3e\u4e4b\u540e\u6240\u6b20\u7684\u91d1\u989d # 1 4320.00 45.00 180.00 225.00 4545.00 # 2 4138.20 43.20 181.80 225.00 4363.20 # 3 3954.58 41.38 183.62 225.00 4179.58 # 4 3769.13 39.55 185.45 225.00 3994.13 # 5 3581.82 37.69 187.31 225.00 3806.82 # 6 3392.64 35.82 189.18 225.00 3617.64 # 7 3201.56 33.93 191.07 225.00 3426.56 # 8 3008.58 32.02 192.98 225.00 3233.58 # 9 2813.67 30.09 194.91 225.00 3038.67 # 10 2616.80 28.14 196.86 225.00 2841.80 # 11 2417.97 26.17 198.83 225.00 2642.97 # 12 2217.15 24.18 200.82 225.00 2442.15 class PaymentSchedule : def __init__ ( self , purchase_price ): self . purchase_price = purchase_price self . down_payment = purchase_price * 0.1 self . loan_balance = purchase_price - self . down_payment self . annual_interest_rate = 0.12 self . monthly_interest_rate = self . annual_interest_rate / 12 self . monthly_payment = ( purchase_price - self . down_payment ) * 0.05 def calculate_schedule ( self ): payment_schedule = [] for month in range ( 1 , 13 ): interest = self . loan_balance * self . monthly_interest_rate principal = self . monthly_payment - interest self . loan_balance -= principal payment_schedule . append (( month , self . loan_balance , interest , principal , self . monthly_payment , self . loan_balance + self . monthly_payment )) return payment_schedule def print_schedule_table ( self ): payment_schedule = self . calculate_schedule () print ( \" {:<10} {:<15} {:<15} {:<15} {:<15} {:<15} \" . format ( \"\u6708\u6570\" , \"\u5f53\u524d\u6240\u6b20\u7684\u4f59\u989d\" , \"\u5f53\u6708\u6240\u6b20\u7684\u5229\u606f\" , \"\u5f53\u6708\u6240\u6b20\u7684\u672c\u91d1\" , \"\u5f53\u6708\u6240\u9700\u4ed8\u6b3e\u91d1\u989d\" , \"\u4ed8\u6b3e\u4e4b\u540e\u6240\u6b20\u7684\u91d1\u989d\" )) for payment in payment_schedule : month , balance , interest , principal , monthly_payment , new_balance = payment print ( \" {:<10} {:<15.2f} {:<15.2f} {:<15.2f} {:<15.2f} {:<15.2f} \" . format ( month , balance , interest , principal , monthly_payment , new_balance )) def main (): try : purchase_price = float ( input ( \"\u8bf7\u8f93\u5165\u8d2d\u4e70\u4ef7\u683c\uff1a\" )) payment_schedule = PaymentSchedule ( purchase_price ) payment_schedule . print_schedule_table () except ValueError : print ( \"\u8bf7\u8f93\u5165\u6709\u6548\u7684\u6570\u5b57\uff01\" ) if __name__ == \"__main__\" : main () # \u8fd0\u884c\u7ed3\u679c # \u8bf7\u8f93\u5165\u8d2d\u4e70\u4ef7\u683c\uff1a5000 # \u6708\u6570 \u5f53\u524d\u6240\u6b20\u7684\u4f59\u989d \u5f53\u6708\u6240\u6b20\u7684\u5229\u606f \u5f53\u6708\u6240\u6b20\u7684\u672c\u91d1 \u5f53\u6708\u6240\u9700\u4ed8\u6b3e\u91d1\u989d \u4ed8\u6b3e\u4e4b\u540e\u6240\u6b20\u7684\u91d1\u989d # 1 4320.00 45.00 180.00 225.00 4545.00 # 2 4138.20 43.20 181.80 225.00 4363.20 # 3 3954.58 41.38 183.62 225.00 4179.58 # 4 3769.13 39.55 185.45 225.00 3994.13 # 5 3581.82 37.69 187.31 225.00 3806.82 # 6 3392.64 35.82 189.18 225.00 3617.64 # 7 3201.56 33.93 191.07 225.00 3426.56 # 8 3008.58 32.02 192.98 225.00 3233.58 # 9 2813.67 30.09 194.91 225.00 3038.67 # 10 2616.80 28.14 196.86 225.00 2841.80 # 11 2417.97 26.17 198.83 225.00 2642.97 # 12 2217.15 24.18 200.82 225.00 2442.15 6\uff0e\u8d22\u52a1\u90e8\u95e8\u5728\u6587\u672c\u6587\u4ef6\u91cc\u4fdd\u5b58\u4e86\u6240\u6709\u5458\u5de5\u5728\u6bcf\u4e2a\u5de5\u8d44\u5468\u671f\u91cc\u7684\u4fe1\u606f\u5217\u8868\u3002\u6587\u4ef6\u4e2d\u6bcf\u4e00\u884c\u7684\u683c\u5f0f\u4e3a \u3002\u8bf7\u7f16\u5199\u4e00\u4e2a\u7a0b\u5e8f\uff0c\u8ba9\u7528\u6237\u53ef\u4ee5\u8f93\u5165\u6587\u4ef6\u7684\u540d\u79f0\uff0c\u5e76\u5728\u7ec8\u7aef\u4e0a\u6253\u5370\u51fa\u7ed9\u5b9a\u65f6\u95f4\u5185\u652f\u4ed8\u7ed9\u6bcf\u4e2a\u5458\u5de5\u7684\u5de5\u8d44\u62a5\u544a\u3002\u8fd9\u4e2a\u62a5\u544a\u662f\u4e00\u4e2a\u6709\u5408\u9002\u6807\u9898\u7684\u8868\uff0c\u5176\u4e2d\u6bcf\u884c\u90fd\u5e94\u8be5\u5305\u542b\u5458\u5de5\u7684\u59d3\u540d\u3001\u5de5\u4f5c\u65f6\u957f\u4ee5\u53ca\u7ed9\u5b9a\u65f6\u95f4\u5185\u6240\u652f\u4ed8\u7684\u5de5\u8d44\u3002 \u89e3\u7b54\uff1a # \u7a0b\u5e8f\u4f1a\u63d0\u793a\u7528\u6237\u8f93\u5165\u6587\u4ef6\u540d\uff0c\u7136\u540e\u8bfb\u53d6\u6587\u4ef6\u4e2d\u7684\u5458\u5de5\u4fe1\u606f\uff0c\u8ba1\u7b97\u5de5\u8d44\u62a5\u544a\uff0c\u5e76\u6253\u5370\u51fa\u5458\u5de5\u7684\u59d3\u540d\u3001\u5de5\u4f5c\u65f6\u957f\u548c\u652f\u4ed8\u5de5\u8d44\u3002\u6ce8\u610f\uff0c\u7a0b\u5e8f\u4f1a\u68c0\u67e5\u6587\u4ef6\u662f\u5426\u5b58\u5728\uff0c\u5e76\u4f1a\u5bf9\u6587\u4ef6\u4e2d\u7684\u6bcf\u884c\u6570\u636e\u8fdb\u884c\u5904\u7406\u4ee5\u786e\u4fdd\u6b63\u786e\u89e3\u6790\u3002 class Employee : def __init__ ( self , last_name , hourly_wage , hours_worked ): self . last_name = last_name self . hourly_wage = float ( hourly_wage ) self . hours_worked = float ( hours_worked ) def calculate_salary ( self ): return self . hourly_wage * self . hours_worked def main (): try : filename = input ( \"\u8bf7\u8f93\u5165\u6587\u4ef6\u540d\uff1a\" ) with open ( filename , 'r' ) as file : employees = [] for line in file : parts = line . strip () . split () if len ( parts ) == 3 : last_name , hourly_wage , hours_worked = parts employee = Employee ( last_name , hourly_wage , hours_worked ) employees . append ( employee ) print ( \" {:<20} {:<15} {:<15} \" . format ( \"\u5458\u5de5\u59d3\u540d\" , \"\u5de5\u4f5c\u65f6\u957f\" , \"\u652f\u4ed8\u5de5\u8d44\" )) print ( \"=\" * 50 ) total_salary = 0 for employee in employees : salary = employee . calculate_salary () total_salary += salary print ( \" {:<20} {:<15.2f} {:<15.2f} \" . format ( employee . last_name , employee . hours_worked , salary )) print ( \"=\" * 50 ) print ( f \"\u603b\u652f\u4ed8\u5de5\u8d44\uff1a { total_salary : .2f } \" ) except FileNotFoundError : print ( \"\u6587\u4ef6\u4e0d\u5b58\u5728\uff01\" ) if __name__ == \"__main__\" : main () 7\uff0e\u7edf\u8ba1\u5b66\u5bb6\u5e0c\u671b\u4f7f\u7528\u4e00\u7ec4\u51fd\u6570\u8ba1\u7b97\u6570\u5b57\u5217\u8868\u7684\u4e2d\u4f4d\u6570\uff08median\uff09\u548c\u4f17\u6570\uff08mode\uff09\u3002\u4e2d\u4f4d\u6570\u662f\u6307\u5982\u679c\u5bf9\u5217\u8868\u8fdb\u884c\u6392\u5e8f\u5c06\u4f1a\u51fa\u73b0\u5728\u5217\u8868\u4e2d\u70b9\u7684\u6570\u5b57\uff0c\u4f17\u6570\u662f\u6307\u5217\u8868\u4e2d\u6700\u5e38\u51fa\u73b0\u7684\u6570\u5b57\u3002\u628a\u8fd9\u4e9b\u529f\u80fd\u5b9a\u4e49\u5728\u540d\u53ebstats.py\u7684\u6a21\u5757\u4e2d\u3002\u9664\u6b64\u4e4b\u5916\uff0c\u6a21\u5757\u8fd8\u5e94\u8be5\u5305\u542b\u4e00\u4e2a\u540d\u53ebmean\u7684\u51fd\u6570\uff0c\u7528\u6765\u8ba1\u7b97\u4e00\u7ec4\u6570\u5b57\u7684\u5e73\u5747\u503c\u3002\u6bcf\u4e2a\u51fd\u6570\u90fd\u4f1a\u63a5\u6536\u4e00\u4e2a\u6570\u5b57\u5217\u8868\u4f5c\u4e3a\u53c2\u6570\uff0c\u5e76\u8fd4\u56de\u4e00\u4e2a\u6570\u5b57\u3002 \u89e3\u7b54\uff1a def median ( numbers ): sorted_numbers = sorted ( numbers ) length = len ( sorted_numbers ) if length % 2 == 1 : return sorted_numbers [ length // 2 ] else : mid1 = sorted_numbers [ length // 2 - 1 ] mid2 = sorted_numbers [ length // 2 ] return ( mid1 + mid2 ) / 2 def mode ( numbers ): from collections import Counter counter = Counter ( numbers ) mode_list = counter . most_common () max_count = mode_list [ 0 ][ 1 ] modes = [ num for num , count in mode_list if count == max_count ] return modes def mean ( numbers ): total = sum ( numbers ) count = len ( numbers ) return total / count if __name__ == \"__main__\" : test_numbers = [ 4 , 2 , 7 , 2 , 1 , 9 , 4 , 7 ] print ( \"\u4e2d\u4f4d\u6570:\" , median ( test_numbers )) print ( \"\u4f17\u6570:\" , mode ( test_numbers )) print ( \"\u5e73\u5747\u503c:\" , mean ( test_numbers )) class Stats : @staticmethod def median ( numbers ): sorted_numbers = sorted ( numbers ) length = len ( sorted_numbers ) if length % 2 == 1 : return sorted_numbers [ length // 2 ] else : mid1 = sorted_numbers [ length // 2 - 1 ] mid2 = sorted_numbers [ length // 2 ] return ( mid1 + mid2 ) / 2 @staticmethod def mode ( numbers ): from collections import Counter counter = Counter ( numbers ) mode_list = counter . most_common () max_count = mode_list [ 0 ][ 1 ] modes = [ num for num , count in mode_list if count == max_count ] return modes @staticmethod def mean ( numbers ): total = sum ( numbers ) count = len ( numbers ) return total / count if __name__ == \"__main__\" : test_numbers = [ 4 , 2 , 7 , 2 , 1 , 9 , 4 , 7 ] print ( \"\u4e2d\u4f4d\u6570:\" , Stats . median ( test_numbers )) print ( \"\u4f17\u6570:\" , Stats . mode ( test_numbers )) print ( \"\u5e73\u5747\u503c:\" , Stats . mean ( test_numbers )) 8\uff0e\u7f16\u5199\u7a0b\u5e8f\uff0c\u8ba9\u7528\u6237\u53ef\u4ee5\u6d4f\u89c8\u6587\u4ef6\u91cc\u7684\u6587\u672c\u884c\u3002\u8fd9\u4e2a\u7a0b\u5e8f\u4f1a\u63d0\u793a\u7528\u6237\u8f93\u5165\u6587\u4ef6\u540d\uff0c\u7136\u540e\u628a\u6587\u672c\u884c\u90fd\u8f93\u5165\u5217\u8868\u3002\u63a5\u4e0b\u6765\uff0c\u8fd9\u4e2a\u7a0b\u5e8f\u4f1a\u8fdb\u5165\u4e00\u4e2a\u5faa\u73af\uff0c\u5728\u8fd9\u4e2a\u5faa\u73af\u91cc\u6253\u5370\u51fa\u6587\u4ef6\u7684\u603b\u884c\u6570\uff0c\u5e76\u63d0\u793a\u7528\u6237\u8f93\u5165\u884c\u53f7\u3002\u8fd9\u4e2a\u884c\u53f7\u7684\u8303\u56f4\u5e94\u5f53\u662f1\u5230\u6587\u4ef6\u7684\u603b\u884c\u6570\u3002\u5982\u679c\u8f93\u5165\u662f0\uff0c\u90a3\u4e48\u7a0b\u5e8f\u9000\u51fa\uff1b\u5426\u5219\uff0c\u7a0b\u5e8f\u5c06\u6253\u5370\u51fa\u884c\u53f7\u6240\u5bf9\u5e94\u7684\u6587\u672c\u884c\u3002 def read_file_lines ( filename ): try : with open ( filename , 'r' ) as file : lines = file . readlines () return lines except FileNotFoundError : print ( \"\u6587\u4ef6\u4e0d\u5b58\u5728\uff01\" ) return [] def main (): filename = input ( \"\u8bf7\u8f93\u5165\u6587\u4ef6\u540d\uff1a\" ) lines = read_file_lines ( filename ) if not lines : return total_lines = len ( lines ) while True : print ( f \"\u6587\u4ef6\u603b\u884c\u6570\uff1a { total_lines } \" ) try : line_number = int ( input ( \"\u8bf7\u8f93\u5165\u884c\u53f7\uff08\u8f93\u51650\u9000\u51fa\uff09\uff1a\" )) if line_number == 0 : break elif 1 <= line_number <= total_lines : print ( f \"\u884c\u53f7 { line_number } : { lines [ line_number - 1 ] . strip () } \" ) else : print ( \"\u65e0\u6548\u7684\u884c\u53f7\uff0c\u8bf7\u8f93\u5165\u6b63\u786e\u8303\u56f4\u5185\u7684\u884c\u53f7\uff01\" ) except ValueError : print ( \"\u8bf7\u8f93\u5165\u6709\u6548\u7684\u6570\u5b57\uff01\" ) if __name__ == \"__main__\" : main () class TextFileBrowser : @classmethod def read_file_lines ( cls , filename ): try : with open ( filename , 'r' ) as file : lines = file . readlines () return lines except FileNotFoundError : print ( \"\u6587\u4ef6\u4e0d\u5b58\u5728\uff01\" ) return [] @classmethod def browse_file ( cls , filename ): lines = cls . read_file_lines ( filename ) if not lines : return total_lines = len ( lines ) while True : print ( f \"\u6587\u4ef6\u603b\u884c\u6570\uff1a { total_lines } \" ) try : line_number = int ( input ( \"\u8bf7\u8f93\u5165\u884c\u53f7\uff08\u8f93\u51650\u9000\u51fa\uff09\uff1a\" )) if line_number == 0 : break elif 1 <= line_number <= total_lines : print ( f \"\u884c\u53f7 { line_number } : { lines [ line_number - 1 ] . strip () } \" ) else : print ( \"\u65e0\u6548\u7684\u884c\u53f7\uff0c\u8bf7\u8f93\u5165\u6b63\u786e\u8303\u56f4\u5185\u7684\u884c\u53f7\uff01\" ) except ValueError : print ( \"\u8bf7\u8f93\u5165\u6709\u6548\u7684\u6570\u5b57\uff01\" ) def main (): filename = input ( \"\u8bf7\u8f93\u5165\u6587\u4ef6\u540d\uff1a\" ) TextFileBrowser . browse_file ( filename ) if __name__ == \"__main__\" : main () 9\uff0e\u5728\u672c\u7ae0\u8ba8\u8bba\u7684numberguess\u7a0b\u5e8f\u91cc\uff0c\u8ba1\u7b97\u673a\u4f1a\u201c\u6784\u601d\u201d\u4e00\u4e2a\u6570\u5b57\uff0c\u800c\u7528\u6237\u5219\u8f93\u5165\u731c\u6d4b\u7684\u503c\uff0c\u76f4\u5230\u731c\u5bf9\u4e3a\u6b62\u3002\u7f16\u5199\u8fd9\u6837\u4e00\u4e2a\u7a0b\u5e8f\uff0c\u4f7f\u5176\u53ef\u4ee5\u8c03\u6362\u8fd9\u4e24\u4e2a\u89d2\u8272\uff0c\u4e5f\u5c31\u662f\uff1a\u7528\u6237\u53bb\u201c\u6784\u601d\u201d\u4e00\u4e2a\u6570\u5b57\uff0c\u7136\u540e\u8ba1\u7b97\u673a\u53bb\u8ba1\u7b97\u5e76\u8f93\u51fa\u731c\u6d4b\u7684\u503c\u3002\u548c\u524d\u9762\u90a3\u4e2a\u6e38\u620f\u7248\u672c\u4e00\u6837\uff0c\u5f53\u8ba1\u7b97\u673a\u731c\u9519\u65f6\uff0c\u7528\u6237\u5fc5\u987b\u7ed9\u51fa\u76f8\u5e94\u7684\u63d0\u793a\uff0c\u4f8b\u5982\u201c<\u201d\u548c\u201c>\u201d\uff08\u5206\u522b\u4ee3\u8868\u201c\u6211\u7684\u6570\u5b57\u66f4\u5c0f\u201d\u548c\u201c\u6211\u7684\u6570\u5b57\u66f4\u5927\u201d\uff09\u3002\u5f53\u8ba1\u7b97\u673a\u731c\u5bf9\u65f6\uff0c\u7528\u6237\u5e94\u8be5\u8f93\u5165\u201c=\u201d\u3002\u7528\u6237\u9700\u8981\u5728\u7a0b\u5e8f\u542f\u52a8\u7684\u65f6\u5019\u8f93\u5165\u6570\u5b57\u7684\u4e0b\u9650\u548c\u4e0a\u9650\u3002\u8ba1\u7b97\u673a\u5e94\u8be5\u5728\u6700\u591a [log2(high\u2212low)+1] \u6b21\u731c\u6d4b\u91cc\u627e\u5230\u6b63\u786e\u7684\u6570\u5b57\u3002\u7a0b\u5e8f\u5e94\u8be5\u80fd\u591f\u8ddf\u8e2a\u731c\u6d4b\u6b21\u6570\uff0c\u5982\u679c\u731c\u6d4b\u9519\u8bef\u7684\u6b21\u6570\u5230\u4e86\u5141\u8bb8\u731c\u6d4b\u7684\u6700\u5927\u503c\u4f46\u8fd8\u6ca1\u6709\u731c\u5bf9\uff0c\u5c31\u8f93\u51fa\u6d88\u606f\u201cYou're cheating\uff01\u201d\u3002\u4e0b\u9762\u662f\u548c\u8fd9\u4e2a\u7a0b\u5e8f\u8fdb\u884c\u4ea4\u4e92\u7684\u793a\u4f8b\uff1a Enter the smaller number : 1 Enter the larger number : 100 Your number is 50 Enter = , < , or > : > Your number is 75 Enter = , < , or > : < Your number is 62 Enter = , < , or > : < Your number is 56 Enter = , < , or > : = Hooray , I 've got it in 4 tries! import math class ComputerGuesser : def __init__ ( self , lower_limit , upper_limit ): self . lower_limit = lower_limit self . upper_limit = upper_limit self . max_attempts = math . floor ( math . log2 ( upper_limit - lower_limit + 1 )) + 1 self . attempts = 0 def guess ( self ): return ( self . lower_limit + self . upper_limit ) // 2 def play ( self ): print ( f \"\u8bf7\u4f60\u9009\u62e9\u4e00\u4e2a\u5728 { self . lower_limit } \u5230 { self . upper_limit } \u4e4b\u95f4\u7684\u6570\u5b57\u3002\" ) while self . attempts < self . max_attempts : guess = self . guess () print ( f \"\u6211\u7684\u731c\u6d4b\u662f\uff1a { guess } \" ) response = input ( \"\u8bf7\u8f93\u5165 =, <, \u6216 > \u6765\u6307\u793a\u662f\u5426\u731c\u5bf9\uff1a\" ) self . attempts += 1 if response == '=' : print ( f \"\u6211\u5728\u7b2c { self . attempts } \u6b21\u731c\u5bf9\u4e86\uff01\" ) break elif response == '<' : self . upper_limit = guess - 1 elif response == '>' : self . lower_limit = guess + 1 else : print ( \"\u8bf7\u8f93\u5165\u6709\u6548\u7684\u64cd\u4f5c\u7b26\uff1a=, <, \u6216 >\" ) if self . attempts >= self . max_attempts : print ( \"\u4f60\u5728\u6b3a\u9a97\u6211\uff01\" ) def main (): lower_limit = int ( input ( \"\u8bf7\u8f93\u5165\u8f83\u5c0f\u7684\u6570\u5b57\uff1a\" )) upper_limit = int ( input ( \"\u8bf7\u8f93\u5165\u8f83\u5927\u7684\u6570\u5b57\uff1a\" )) guesser = ComputerGuesser ( lower_limit , upper_limit ) guesser . play () if __name__ == \"__main__\" : main () import math class ComputerGuesser : def __init__ ( self , lower_limit , upper_limit ): self . lower_limit = lower_limit self . upper_limit = upper_limit self . max_attempts = math . floor ( math . log2 ( upper_limit - lower_limit + 1 )) + 1 self . attempts = 0 @classmethod def guess ( cls , lower_limit , upper_limit ): return ( lower_limit + upper_limit ) // 2 @classmethod def play ( cls , lower_limit , upper_limit ): print ( f \"\u8bf7\u4f60\u9009\u62e9\u4e00\u4e2a\u5728 { lower_limit } \u5230 { upper_limit } \u4e4b\u95f4\u7684\u6570\u5b57\u3002\" ) attempts = 0 while attempts < cls . max_attempts : guess = cls . guess ( lower_limit , upper_limit ) print ( f \"\u6211\u7684\u731c\u6d4b\u662f\uff1a { guess } \" ) response = input ( \"\u8bf7\u8f93\u5165 =, <, \u6216 > \u6765\u6307\u793a\u662f\u5426\u731c\u5bf9\uff1a\" ) attempts += 1 if response == '=' : print ( f \"\u6211\u5728\u7b2c { attempts } \u6b21\u731c\u5bf9\u4e86\uff01\" ) break elif response == '<' : upper_limit = guess - 1 elif response == '>' : lower_limit = guess + 1 else : print ( \"\u8bf7\u8f93\u5165\u6709\u6548\u7684\u64cd\u4f5c\u7b26\uff1a=, <, \u6216 >\" ) if attempts >= cls . max_attempts : print ( \"\u4f60\u5728\u6b3a\u9a97\u6211\uff01\" ) def main (): lower_limit = int ( input ( \"\u8bf7\u8f93\u5165\u8f83\u5c0f\u7684\u6570\u5b57\uff1a\" )) upper_limit = int ( input ( \"\u8bf7\u8f93\u5165\u8f83\u5927\u7684\u6570\u5b57\uff1a\" )) ComputerGuesser . play ( lower_limit , upper_limit ) if __name__ == \"__main__\" : main () 10\uff0e\u6709\u4e00\u4e2a\u7b80\u5355\u7684\u8bfe\u7a0b\u7ba1\u7406\u7cfb\u7edf\uff0c\u5b83\u901a\u8fc7\u4f7f\u7528\u540d\u5b57\u548c\u4e00\u7ec4\u8003\u8bd5\u5206\u6570\u6765\u6a21\u62df\u5b66\u751f\u7684\u4fe1\u606f\u3002\u8fd9\u4e2a\u7cfb\u7edf\u5e94\u8be5\u80fd\u591f\u521b\u5efa\u4e00\u4e2a\u5177\u6709\u7ed9\u5b9a\u540d\u5b57\u548c\u5206\u6570\uff08\u8d77\u521d\u5747\u4e3a0\uff09\u7684\u5b66\u751f\u5bf9\u8c61\u3002\u7cfb\u7edf\u5e94\u8be5\u80fd\u591f\u8bbf\u95ee\u548c\u66ff\u6362\u6307\u5b9a\u4f4d\u7f6e\u5904\u7684\u5206\u6570\uff08\u4ece0\u5f00\u59cb\u8ba1\u6570\uff09\u3001\u5f97\u5230\u5b66\u751f\u6709\u591a\u5c11\u6b21\u8003\u8bd5\u3001\u5f97\u5230\u7684\u6700\u9ad8\u5206\u3001\u5f97\u5230\u7684\u5e73\u5747\u5206\u4ee5\u53ca\u5b66\u751f\u7684\u59d3\u540d\u3002\u9664\u6b64\u4e4b\u5916\uff0c\u5728\u6253\u5370\u5b66\u751f\u5bf9\u8c61\u7684\u65f6\u5019\uff0c\u5e94\u8be5\u50cf\u4e0b\u9762\u8fd9\u6837\u663e\u793a\u5b66\u751f\u7684\u59d3\u540d\u548c\u5206\u6570\uff1a Name : Ken Lambert Score 1 : 88 Score 2 : 77 Score 3 : 100 \u8bf7\u5b9a\u4e49\u4e00\u4e2a\u652f\u6301\u8fd9\u4e9b\u529f\u80fd\u548c\u884c\u4e3a\u7684Student\u7c7b\uff0c\u5e76\u4e14\u7f16\u5199\u4e00\u4e2a\u521b\u5efaStudent\u5bf9\u8c61\u5e76\u8fd0\u884c\u5176\u65b9\u6cd5\u7684\u7b80\u77ed\u7684\u6d4b\u8bd5\u51fd\u6570\u3002 class Student : def __init__ ( self , name ): self . name = name self . scores = [] def add_score ( self , score ): self . scores . append ( score ) def replace_score ( self , index , score ): if 0 <= index < len ( self . scores ): self . scores [ index ] = score else : print ( \"\u65e0\u6548\u7684\u5206\u6570\u7d22\u5f15\" ) def num_scores ( self ): return len ( self . scores ) def highest_score ( self ): if self . scores : return max ( self . scores ) else : return None def average_score ( self ): if self . scores : return sum ( self . scores ) / len ( self . scores ) else : return None def display ( self ): print ( f \"Name: { self . name } \" ) for i , score in enumerate ( self . scores , start = 1 ): print ( f \"Score { i } : { score } \" ) def test_student_class (): student = Student ( \"Ken Lambert\" ) student . add_score ( 88 ) student . add_score ( 77 ) student . add_score ( 100 ) student . display () print ( f \"Total Scores: { student . num_scores () } \" ) print ( f \"Highest Score: { student . highest_score () } \" ) print ( f \"Average Score: { student . average_score () } \" ) if __name__ == \"__main__\" : test_student_class ()","title":"\u57fa\u7840\u77e5\u8bc6\u56de\u987e"},{"location":"python/DataStructure/01_PythonFundmantal/#1","text":"","title":"1.\u57fa\u7840\u77e5\u8bc6\u56de\u987e"},{"location":"python/DataStructure/01_PythonFundmantal/#11","text":"\u793a\u4f8b\u4ee3\u7801 numberguess.py \u3002 import random def main (): smaller = int ( input ( \"\u8f93\u5165\u6700\u5c0f\u503c: \" )) larger = int ( input ( \"\u8f93\u5165\u6700\u5927\u503c: \" )) myNumber = random . randint ( smaller , larger ) count = 0 while True : count += 1 userNumber = int ( input ( \"\u8f93\u5165\u4f60\u731c\u7684\u503c: \" )) if userNumber < myNumber : print ( \"\u4f60\u731c\u7684\u592a\u5c0f\uff01\" ) elif userNumber > myNumber : print ( \"\u4f60\u731c\u7684\u592a\u5927\uff01\" ) else : print ( \"\u606d\u559c\uff0c\u4f60\u5728\u7b2c\" , count , \"\u6b21\u731c\u5bf9\u4e86!\" ) break if __name__ == \"__main__\" : main () \u8fd0\u884c\u4ee3\u7801\uff1a $ python3 numberguess.py Enter the smaller number: 10 Enter the larger number: 60 Enter your guess: 50 Too large Enter your guess: 40 Too large Enter your guess: 30 Too large Enter your guess: 20 Too large Enter your guess: 10 Too small Enter your guess: 15 You\u2019ve got it in 6 tries!","title":"1.1.\u57fa\u672c\u7a0b\u5e8f\u8981\u7d20"},{"location":"python/DataStructure/01_PythonFundmantal/#111","text":"\u53d8\u91cf\uff1asalary\uff0choursWorked\uff0cisAbsent \u5e38\u6570\uff1aABSOLUTE_ZERO\uff0cINTEREST_RATE \u51fd\u6570\u6216\u65b9\u6cd5\uff1aprintResults\uff0ccubeRoot\uff0cinput \u7c7b\uff1aBankAccount\uff0cSortedSet \u901a\u5e38\u7ea6\u5b9a\uff1a\u53d8\u91cf\u540d\u662f\u540d\u8bcd\u3001\u5f62\u5bb9\u8bcd\uff08\u5e03\u5c14\u503c\uff09\uff0c\u51fd\u6570\u548c\u65b9\u6cd5\u662f\u52a8\u8bcd\uff08\u8868\u793a\u52a8\u4f5c\uff09\u3001\u540d\u8bcd\u3001\u6216\u5f62\u5bb9\u8bcd\uff08\u8868\u793a\u8fd4\u56de\u7684\u503c\uff09\u3002 \u8bed\u6cd5\u5143\u7d20\uff1a Python\u4f7f\u7528\u7a7a\u767d\u7b26\uff08\u7a7a\u683c\u3001\u5236\u8868\u7b26\u3001\u6216\u6362\u884c\u7b26\uff09\u6765\u8868\u793a\u4e0d\u540c\u7c7b\u578b\u7684\u8bed\u53e5\u7684\u8bed\u6cd5\u3002 \u901a\u5e38\u7ea6\u5b9a\u4f7f\u75284\u4e2a\u7a7a\u683c\u4f5c\u4e3a\u9501\u8fdb\u5bbd\u5ea6\u3002","title":"1.1.1.\u62fc\u5199\u548c\u547d\u540d\u60ef\u4f8b"},{"location":"python/DataStructure/01_PythonFundmantal/#112","text":"\u5355\u5f15\u53f7 \u53cc\u5f15\u53f7 \u6210\u5bf9\u7684\u4e09\u4e2a\u53cc\u5f15\u53f7\uff08\u591a\u884c\u6587\u672c\uff09 \u6210\u5bf9\u7684\u4e09\u4e2a\u5355\u5f15\u53f7\uff08\u591a\u884c\u6587\u672c\uff09 \u8f6c\u4e49\u5b57\u7b26 \\ \uff08\u53cd\u659c\u6760\uff09","title":"1.1.2.\u5b57\u7b26\u4e32"},{"location":"python/DataStructure/01_PythonFundmantal/#113","text":"\u6807\u51c6\u8fd0\u7b97\u7b26\uff1a + \u3001 - \u3001 * \u3001 / \u3001 % \u7b97\u672f\u8868\u8fbe\u5f0f\u662f\u7528\u6807\u51c6\u8fd0\u7b97\u7b26\u548c\u4e2d\u7f00\u8868\u793a\u6cd5 \u6bd4\u8f83\u8fd0\u7b97\u7b26\uff1a < \u3001 <= \u3001 > \u3001 >= \u3001 == \u3001 != \uff0c\u7528\u4e8e\u6bd4\u8f83\u6570\u5b57\u6216\u5b57\u7b26\u4e32\uff0c\u8fd4\u56deTrue\u6216False \u8fd0\u7b97\u7b26 == \u7528\u4e8e\u6bd4\u8f83\u6570\u636e\u7ed3\u6784\u91cc\u7684\u5185\u5bb9\uff0c\u8fd0\u7b97\u7b26 is \u7528\u4e8e\u6bd4\u8f83\u4e24\u4e2a\u5bf9\u8c61\u7684\u6807\u8bc6\u662f\u5426\u4e00\u81f4 \u903b\u8f91\u8fd0\u7b97\u7b26\uff1a and \u3001 or \u3001 not \u3002\u628a0\u3001None\u3001\u7a7a\u5b57\u7b26\u4e32\u3001\u7a7a\u5217\u8868\u7b49\u89c6\u4e3aFalse\uff0c\u5927\u591a\u6570\u5176\u4ed6\u503c\u662f\u4e3aTrue \u4e0b\u6807\u8fd0\u7b97\u7b26\uff1a [] \uff0c\u4e0e\u591a\u9879\u96c6collection\u5bf9\u8c61\u4e00\u8d77\u4f7f\u7528 \u9009\u62e9\u5668\u8fd0\u7b97\u7b26\uff1a . \uff0c\u7528\u4e8e\u5f15\u7528\u4e00\u4e2a\u6a21\u5757\u3001\u7c7b\u6216\u5bf9\u8c61\u4e2d\u7684\u4e00\u4e2a\u5177\u540d\u7684\u9879 \u8fd0\u7b97\u7b26\u4f18\u5148\u7ea7\uff0c\u4f9d\u6b21\u662f\u9009\u62e9\u8fd0\u7b97\u7b26\u3001\u51fd\u6570\u8c03\u7528\u8fd0\u7b97\u7b26\u3001\u4e0b\u6807\u8fd0\u7b97\u7b26\u3001\u7b97\u672f\u8fd0\u7b97\u7b26\u3001\u6bd4\u8f83\u8fd0\u7b97\u7b26\u3001\u903b\u8f91\u8fd0\u7b97\u7b26\u3001\u8d4b\u503c\u8fd0\u7b97\u7b26\u3002\u62ec\u53f7\u7528\u4e8e\u8ba9\u5b50\u8868\u8fbe\u5f0f\u4f18\u5148\u8fd0\u884c\u3002","title":"1.1.3.\u8fd0\u7b97\u7b26\u548c\u8868\u8fbe\u5f0f"},{"location":"python/DataStructure/01_PythonFundmantal/#114","text":"\u51fd\u6570\u540d\u79f0\u540e\u9762\u8ddf\u7740\u7528\u62ec\u53f7\u62ec\u8d77\u6765\u7684\u53c2\u6570\u5217\u8868\uff0c\u4f8b\u5982\uff1a min(5,2) \u6807\u51c6\u51fd\u6570 \u5176\u4ed6\u6a21\u5757\u5bfc\u5165\u51fd\u6570","title":"1.1.4.\u51fd\u6570\u8c03\u7528"},{"location":"python/DataStructure/01_PythonFundmantal/#115print","text":"\u81ea\u52a8\u4e3a\u6bcf\u4e2a\u53c2\u6570\u8fd0\u884c str \u51fd\u6570\uff0c\u4ee5\u5f97\u5230\u5176\u5b57\u7b26\u4e32\u8868\u793a \u5728\u8f93\u51fa\u4e4b\u524d\u4f1a\u7528\u7a7a\u683c\u5427\u6bcf\u4e2a\u5b57\u7b26\u4e32\u9694\u5f00 \u9ed8\u8ba4\u4ee5\u6362\u884c\u7b26\u4f5c\u4e3a\u7ed3\u675f","title":"1.1.5.print\u51fd\u6570"},{"location":"python/DataStructure/01_PythonFundmantal/#116input","text":"\u6807\u51c6\u8f93\u5165\u51fd\u6570input\u4f1a\u4e00\u76f4\u7b49\u5f85\u7528\u6237\u901a\u8fc7\u952e\u76d8\u8f93\u5165\u6587\u672c \u63a5\u53d7\u4e00\u4e2a\u53ef\u9009\u7684\u5b57\u7b26\u4e32\u4f5c\u4e3a\u5176\u53c2\u6570","title":"1.1.6.input\u51fd\u6570"},{"location":"python/DataStructure/01_PythonFundmantal/#117","text":"Python\u5141\u8bb8\u7b97\u672f\u8868\u8fbe\u5f0f\u4e2d\u7684\u64cd\u4f5c\u6570\u5177\u6709\u4e0d\u540c\u7684\u6570\u503c\u7c7b\u578b\u3002\u4f8b\u5982\uff0c\u628aint\u7c7b\u578b\u7684\u64cd\u4f5c\u6570\u548cfloat\u7c7b\u578b\u7684\u64cd\u4f5c\u6570\u76f8\u52a0\uff0c\u4f1a\u5f97\u5230float\u7c7b\u578b\u7684\u6570\u3002 # \u8f93\u5165\u534a\u5f84\u6c42\u5706\u9762\u79ef radius = float ( input ( \"Radius: \" )) print ( \"The area is\" , 3.14 * radius ** 2 )","title":"1.1.7.\u7c7b\u578b\u8f6c\u6362\u51fd\u6570\u548c\u6df7\u5408\u6a21\u5f0f\u64cd\u4f5c"},{"location":"python/DataStructure/01_PythonFundmantal/#118","text":"\u5fc5\u9009\u53c2\u6570\u662f\u6ca1\u6709\u9ed8\u8ba4\u503c\u7684\uff1b\u53ef\u9009\u53c2\u6570\u6709\u9ed8\u8ba4\u503c\uff1b \u5728\u8c03\u7528\u51fd\u6570\u65f6\uff0c\u4f20\u9012\u7ed9\u5b83\u7684\u53c2\u6570\u6570\u91cf\u5fc5\u987b\u81f3\u5c11\u548c\u5fc5\u9009\u53c2\u6570\u7684\u6570\u91cf\u76f8\u540c\u3002 \u6807\u51c6\u51fd\u6570\u548cPython\u7684\u5e93\u51fd\u6570\u5728\u8c03\u7528\u65f6\u90fd\u4f1a\u5bf9\u4f20\u5165\u7684\u53c2\u6570\u8fdb\u884c\u7c7b\u578b\u68c0\u67e5","title":"1.1.8.\u53ef\u9009\u548c\u5173\u952e\u5b57\u51fd\u6570\u53c2\u6570"},{"location":"python/DataStructure/01_PythonFundmantal/#119","text":"\u7b80\u5355\u7684\u8d4b\u503c\u8bed\u53e5 PI = 3.1416 \u591a\u53d8\u91cf\u8d4b\u503c minValue, maxValue = 1, 100 \u53d8\u91cf\u4ea4\u6362 a, b = b, a \u8d4b\u503c\u8bed\u53e5\u5fc5\u987b\u5199\u5728\u4e00\u884c\u4ee3\u7801\u91cc\uff0c\u4f46\u662f\u53ef\u4ee5\u5728\u9017\u53f7\u3001\u5706\u62ec\u53f7\u3001\u82b1\u62ec\u53f7\u6216\u65b9\u62ec\u53f7\u4e4b\u540e\u6362\u884c\uff0c\u6216\u8005\u7528\u8f6c\u4e49\u7b26 \\ \u8fdb\u884c\u6362\u884c\u3002 \u6362\u884c\u793a\u4f8b\uff1a minValue = min ( 100 , 200 ) product = max ( 100 , 200 ) \\ * 30","title":"1.1.9.\u53d8\u91cf\u548c\u8d4b\u503c\u8bed\u53e5"},{"location":"python/DataStructure/01_PythonFundmantal/#1110","text":"\u53d8\u91cf\u90fd\u53ef\u4ee5\u88ab\u6307\u5b9a\u4e3a\u4efb\u4f55\u7c7b\u578b\u7684\u503c\u3002\u8fd9\u4e9b\u53d8\u91cf\u5e76\u4e0d\u50cf\u5176\u4ed6\u8bed\u8a00\u90a3\u6837\u88ab\u58f0\u660e\u4e3a\u7279\u5b9a\u7684\u7c7b\u578b\uff0c\u800c\u53ea\u662f\u88ab\u8d4b\u4e86\u4e00\u4e2a\u503c \u503c\u548c\u5bf9\u8c61\u90fd\u662f\u6709\u7c7b\u578b\u7684\uff0c\u4f1a\u5728\u8fd0\u884c\u65f6\u8fdb\u884c\u6570\u636e\u7c7b\u578b\u68c0\u67e5","title":"1.1.10.\u6570\u636e\u7c7b\u578b"},{"location":"python/DataStructure/01_PythonFundmantal/#1111import","text":"import \u8bed\u53e5\u4f7f\u5f97\u4e00\u4e2a\u6a21\u5757\u4e2d\u7684\u6807\u8bc6\u7b26\u53ef\u4ee5\u88ab\u53e6\u4e00\u4e2a\u7a0b\u5e8f\u6240\u89c1\u5230\u3002\u6807\u8bc6\u7b26\u53ef\u4ee5\u662f\u5bf9\u8c61\u540d\u3001\u51fd\u6570\u540d\u6216\u7c7b\u540d \u5bfc\u5165\u6a21\u5757\u540d\u79f0\uff0c\u4f8b\u5982 import math \u5bfc\u5165\u6a21\u5757\u4e2d\u7684\u6807\u8bc6\u7b26\uff0c\u4f8b\u5982\uff1a from math import sqrt \uff0c\u6216\u8005 from math import pi, sqrt \u4e5f\u53ef\u4ee5\u4f7f\u7528\u7b26\u53f7 * \u5bfc\u5165\u4e00\u4e2a\u6a21\u5757\u4e2d\u7684\u6240\u6709\u540d\u79f0\uff0c\u4f46\u4e0d\u63a8\u8350","title":"1.1.11.import\u8bed\u53e5"},{"location":"python/DataStructure/01_PythonFundmantal/#12","text":"","title":"1.2.\u63a7\u5236\u8bed\u53e5"},{"location":"python/DataStructure/01_PythonFundmantal/#121","text":"\u5355\u5411if\u8bed\u53e5\u7684\u8bed\u6cd5 if < Boolean expression > : < sequence of statements > \u53cc\u5411if\u8bed\u53e5\u7684\u8bed\u6cd5 if < Boolean expression > : < sequence of statements > else : < sequence of statements > \u591a\u5411if\u8bed\u53e5\u7684\u8bed\u6cd5 if < Boolean expression > : < sequence of statements > elif < Boolean expression > : < sequence of statements > ... else : < sequence of statements >","title":"1.2.1.\u6761\u4ef6\u8bed\u53e5"},{"location":"python/DataStructure/01_PythonFundmantal/#122if-name-main","text":"\u793a\u4f8b\u4ee3\u7801 numberguess.py \u3002 import random def main (): smaller = int ( input ( \"\u8f93\u5165\u6700\u5c0f\u503c: \" )) larger = int ( input ( \"\u8f93\u5165\u6700\u5927\u503c: \" )) myNumber = random . randint ( smaller , larger ) count = 0 while True : count += 1 userNumber = int ( input ( \"\u8f93\u5165\u4f60\u731c\u7684\u503c: \" )) if userNumber < myNumber : print ( \"\u4f60\u731c\u7684\u592a\u5c0f\uff01\" ) elif userNumber > myNumber : print ( \"\u4f60\u731c\u7684\u592a\u5927\uff01\" ) else : print ( \"\u606d\u559c\uff0c\u4f60\u5728\u7b2c\" , count , \"\u6b21\u731c\u5bf9\u4e86!\" ) break if __name__ == \"__main__\" : main () \u4e0a\u9762\u7684if\u8bed\u53e5\u7684\u4f5c\u7528\u662f\uff0c \u8981\u4e48\u5c06\u6a21\u5757\u5f53\u4f5c\u4e00\u4e2a\u72ec\u7acb\u7684\u7a0b\u5e8f\u8fd0\u884c\uff0c\u8be5\u6a21\u5757\u7684 _name_ \u53d8\u91cf\u4f1a\u8bbe\u7f6e\u4e3a\u5b57\u7b26\u4e32 _main_ \uff0c\u624d\u4f1a\u6267\u884c main() \u51fd\u6570 \u8981\u4e48\u4ece\u53e6\u4e00\u4e2a\u6a21\u5757\u4e2d\u5bfc\u5165\uff0c\u8be5\u6a21\u5757\u7684 _name_ \u53d8\u91cf\u4f1a\u8bbe\u7f6e\u8be5\u6a21\u5757\u7684\u540d\u79f0\uff0c\u4e0a\u4f8b\u4e2d\u5373 numberguess","title":"1.2.2.\u4f7f\u7528if name == \"main\""},{"location":"python/DataStructure/01_PythonFundmantal/#123","text":"\u901a\u5e38\uff1a \u4e00\u822c\u4f1a\u4f7f\u7528for\u5faa\u73af\u6765\u8fed\u4ee3\u786e\u5b9a\u8303\u56f4\u7684\u503c\u6216\u503c\u7684\u5e8f\u5217 \u5982\u679c\u7ee7\u7eed\u5faa\u73af\u7684\u6761\u4ef6\u662f\u67d0\u4e2a\u5e03\u5c14\u8868\u8fbe\u5f0f\uff0c\u4e00\u822c\u4f1a\u4f7f\u7528while\u5faa\u73af while \u8bed\u6cd5\u683c\u5f0f\uff1a while < Boolean expression > : < sequence of statements > \u793a\u4f8b\uff1a # \u8ba1\u7b97\u4ece1\u523010\u7684\u4e58\u79ef\u5e76\u8f93\u51fa\u7ed3\u679c result = 1 value = 1 while value <= 10 : result *= value value += 1 print ( result , value ) # \u8fd0\u884c\u7ed3\u679c # 3628800 11 for \u8bed\u6cd5\u683c\u5f0f\uff1a for < variable > in < iterable object > : < sequence of statements > \u793a\u4f8b\uff1a # \u8ba1\u7b97\u4ece1\u523010\u7684\u4e58\u79ef\u5e76\u8f93\u51fa\u7ed3\u679c result = 1 value = 1 for value in range ( 1 , 11 ): result *= value value += 1 print ( result , value ) # \u8fd0\u884c\u7ed3\u679c # 3628800 11","title":"1.2.3.\u5faa\u73af\u8bed\u53e5"},{"location":"python/DataStructure/01_PythonFundmantal/#13","text":"Python\u4e2d\u7684\u5b57\u7b26\u4e32\u4e5f\u662f\u4e00\u4e2a\u590d\u5408\u5bf9\u8c61 Python\u7684\u5b57\u7b26\u4e32\u7c7b\u578b\u540d\u4e3a str \u7ea6\u5b9a\uff1a \u628a\u5355\u5b57\u7b26\u7684\u5b57\u7b26\u4e32\u7528\u5355\u5f15\u53f7\u62ec\u8d77\u6765 \u628a\u591a\u5b57\u7b26\u7684\u5b57\u7b26\u4e32\u7528\u53cc\u5f15\u53f7\u62ec\u8d77\u6765","title":"1.3.\u5b57\u7b26\u4e32\u53ca\u5176\u8fd0\u7b97"},{"location":"python/DataStructure/01_PythonFundmantal/#131","text":"\u6bd4\u8f83\u8fd0\u7b97\u7b26\uff0c\u662f\u6309\u7167ASCII\u7801\u7684\u987a\u5e8f\u6bd4\u8f83\u4e24\u4e2a\u5b57\u7b26\u4e32\u4e2d\u6bcf\u4e2a\u4f4d\u7f6e\u7684\u5b57\u7b26\u5bf9 \u793a\u4f8b\uff1a print ( 'A' > 'a' ) # \u8fd0\u884c\u7ed3\u679c False print ( 'A' < 'a' ) # \u8fd0\u884c\u7ed3\u679c True + \u8fd0\u7b97\u7b26\u751f\u6210\u5e76\u8fd4\u56de\u4e00\u4e2a\u5305\u542b\u4e24\u4e2a\u64cd\u4f5c\u6570\u7684\u65b0\u5b57\u7b26\u4e32 \u793a\u4f8b\uff1a print ( \"Hello\" + \"Python\" ) # \u8fd0\u884c\u7ed3\u679c HelloPython \u4e0b\u6807\u8fd0\u7b97\u7b26\uff0c\u8303\u56f4\u662f\u4ece0\u5230\u5b57\u7b26\u4e32\u7684\u957f\u5ea6\u51cf\u53bb1\u7684\u4e00\u4e2a\u6574\u6570\u3002 \u8fd0\u7b97\u7b26\u8fd4\u56de\u5728\u5b57\u7b26\u4e32\u4e2d\u8be5\u4f4d\u7f6e\u7684\u5b57\u7b26\u3002 \u793a\u4f8b\uff1a print ( \"Greater\" [ 1 ]) # \u8fd0\u884c\u7ed3\u679c\uff1ar \u5f53\u7d22\u5f15\u4e3a\u8d1f\u503c\u65f6\uff0cPython\u4f1a\u628a\u8fd9\u4e2a\u503c\u548c\u5b57\u7b26\u4e32\u7684\u957f\u5ea6\u76f8\u52a0\uff0c\u4ee5\u786e\u5b9a\u8981\u8fd4\u56de\u7684\u5b57\u7b26\u7684\u4f4d\u7f6e\u3002\u8d1f\u7d22\u5f15\u503c\u4e0d\u5f97\u5c0f\u4e8e\u5b57\u7b26\u4e32\u957f\u5ea6\u7684\u8d1f\u503c\u3002 print ( \"Greater\" [ - 3 ]) # \u8fd0\u884c\u7ed3\u679c\uff1at print ( \"Greater\" [ - 9 ]) # \u8fd0\u884c\u7ed3\u679c\uff1aIndexError: string index out of range \u5207\u7247\u8fd0\u7b97\u7b26\uff08slice operator\uff09\uff0c\u4e0b\u6807\u8fd0\u7b97\u7b26\u7684\u4e00\u79cd\u53d8\u4f53\u3002 \u8bed\u6cd5\u683c\u5f0f\uff1a [:] \uff1a\u8303\u56f4\u662f\u4ece0\u5230\u5b57\u7b26\u4e32\u7684\u957f\u5ea6\u51cf\u53bb1\u7684\u6574\u6570 \uff1a\u8303\u56f4\u662f\u4ece0\u5230\u5b57\u7b26\u4e32\u7684\u957f\u5ea6\u7684\u6574\u6570 \u5207\u7247\u68c0\u7d22\u89c4\u5219\uff1a \u8fd4\u56de\u8fd9\u6837\u4e00\u4e2a\u5b50\u5b57\u7b26\u4e32\uff1a\u8fd9\u4e2a\u5b50\u5b57\u7b26\u4e32\u4f1a\u4ece \u7d22\u5f15\u5904\u7684\u5b57\u7b26\u5f00\u59cb\uff0c\u5230 \u7d22\u5f15\u51cf1\u7684\u4f4d\u7f6e\u4f5c\u4e3a\u7ed3\u675f\u3002 \u5982\u679c\u7701\u7565 \u7d22\u5f15\uff0c\u90a3\u4e48\u5207\u7247\u8fd0\u7b97\u7b26\u5c06\u8fd4\u56de\u4e00\u4e2a\u4ee5\u5f53\u524d\u5b57\u7b26\u4e32\u7684\u7b2c\u4e00\u4e2a\u5b57\u7b26\u4f5c\u4e3a\u5f00\u5934\u7684\u5b50\u5b57\u7b26\u4e32\u3002 \u5982\u679c\u7701\u7565 \u7d22\u5f15\uff0c\u90a3\u4e48\u5207\u7247\u8fd0\u7b97\u7b26\u5c06\u8fd4\u56de\u4e00\u4e2a\u4ee5\u5f53\u524d\u5b57\u7b26\u4e32\u7684\u6700\u540e\u4e00\u4e2a\u5b57\u7b26\u4f5c\u4e3a\u7ed3\u5c3e\u7684\u5b50\u5b57\u7b26\u4e32\u3002 \u5982\u679c\u7701\u7565\u8fd9\u4e24\u4e2a\u503c\uff0c\u90a3\u4e48\u5207\u7247\u8fd0\u7b97\u7b26\u4f1a\u8fd4\u56de\u6574\u4e2a\u5b57\u7b26\u4e32\u3002 \u793a\u4f8b\uff1a print ( \"Greater\" [:]) # \u8fd4\u56de\u5b57\u4e32 Greater print ( \"Greater\" [ 2 :]) # \u8fd4\u56de\u5b57\u4e32 eater print ( \"Greater\" [: 2 ]) # \u8fd4\u56de\u5b57\u4e32 Gr print ( \"Greater\" [ 2 : 5 ]) # \u8fd4\u56de\u5b57\u4e32 eat","title":"1.3.1.\u8fd0\u7b97\u7b26"},{"location":"python/DataStructure/01_PythonFundmantal/#132","text":"\u683c\u5f0f\u5316\u5b57\u7b26\u4e32\u91cc\u7684\u6570\u636e\u5b57\u7b26\u4ee5\u53ca\u6ee1\u8db3\u7ed9\u5b9a\u57fa\u51c6\u7ebf\u7684\u9644\u52a0\u7a7a\u683c\u7684\u603b\u6570\u79f0\u4e3a\u5b83\u7684\u5b57\u6bb5\u5bbd\u5ea6\uff08field width\uff09\u3002 print \u51fd\u6570\u4f1a\u5728\u9047\u5230\u7b2c\u4e00\u5217\u65f6\u81ea\u52a8\u5f00\u59cb\u6253\u5370\u8f93\u51fa\u57fa\u51c6\u7ebf\u3002 \u793a\u4f8b\uff0c\u901a\u8fc7print\u8bed\u53e5\u8f93\u51fa2\u5217\u3002 for i in range ( 7 , 11 ): print ( i , 10 * i ) # \u8fd0\u884c\u7ed3\u679c # 7 70 # 8 80 # 9 90 # 10 100 Python\u7684\u901a\u7528\u683c\u5f0f\u5316\u673a\u5236 \u8bed\u6cd5\u683c\u5f0f % \u548c % (, \u2026, ) \u3002 \u683c\u5f0f\u5316\u5b57\u7b26\u4e32\u65f6\uff0c \u4f7f\u7528 %s \u8868\u793a\u6cd5\u3002\u5f53\u5b57\u6bb5\u5bbd\u5ea6\u4e3a\u6b63\u65f6\uff0c\u6570\u636e\u662f\u53f3\u5bf9\u9f50\u7684\uff1b\u5f53\u5b57\u6bb5\u5bbd\u5ea6\u4e3a\u8d1f\u65f6\uff0c\u6570\u636e\u662f\u5de6\u5bf9\u9f50\u7684\u3002 \u683c\u5f0f\u6574\u6570\u65f6\uff0c \u4f7f\u7528 %d \u8868\u793a\u6cd5\u3002 \u683c\u5f0f\u6d6e\u70b9\u6570\u65f6\uff0c \u4f7f\u7528 %.f \u8868\u793a\u6cd5\uff0c\u5176\u4e2d . \u8fd9\u4e00\u90e8\u5206\u662f\u53ef\u9009\u7684\u3002 \u793a\u4f8b\uff1a print ( \" %6s \" % \"four\" ) print ( \" %-6s \" % \"four\" ) # four # four for i in range ( 7 , 11 ): print ( \" %-3d%5d \" % ( i , 10 * i )) # 7 70 # 8 80 # 9 90 # 10 100 for i in range ( 7 , 11 ): print ( \" %-3d%5.3f \" % ( i , i / 3 )) # 7 2.333 # 8 2.667 # 9 3.000 # 10 3.333 \u4e0b\u4f8b\u5bf9\u6bd4\u4e86\u6d6e\u70b9\u6570\u5728\u4f7f\u7528\u4e86\u683c\u5f0f\u5b57\u7b26\u4e32\u548c\u6ca1\u6709\u4f7f\u7528\u683c\u5f0f\u5b57\u7b26\u4e32\u8fd9\u4e24\u79cd\u60c5\u51b5\u4e0b\u7684\u8f93\u51fa\u5dee\u5f02\u3002 salary = 100.00 print ( \"Salary: $\" + str ( salary )) # Salary: $100.0 print ( \"Salary: $ %0.2f \" % salary ) # Salary: $100.00 \u6ce8\u610f\uff0c\u4e0b\u4f8b\u4e2dPython\u7ed9\u6570\u5b57\u6dfb\u52a0\u4e86\u4e00\u4e2a\u7cbe\u5ea6\u4f4d\u6570\uff0c\u5e76\u4e14\u5176\u5de6\u4fa7\u586b\u5145\u7a7a\u683c\uff0c\u4ece\u800c\u5b9e\u73b0\u4e86\u5b57\u6bb5\u5bbd\u5ea6\u4e3a6\u3001\u7cbe\u5ea6\u4e3a3\u7684\u8bbe\u7f6e\u3002\u8fd9\u4e2a\u5bbd\u5ea6\u5305\u542b\u5c0f\u6570\u70b9\u540e\u6240\u5360\u636e\u7684\u4f4d\u7f6e\u3002 print ( \" %6.3f \" % 3.14 ) # \u5de6\u4fa7\u586b\u5145\u4e86\u7a7a\u683c # 3.140 print ( \" %-6.3f \" % 3.14 ) # 3.140","title":"1.3.2.\u5b57\u7b26\u4e32\u683c\u5f0f\u5316"},{"location":"python/DataStructure/01_PythonFundmantal/#133","text":"\u8bed\u6cd5\u683c\u5f0f\uff1a .() \u793a\u4f8b\uff1a print ( \"greater\" . isupper ()) # \u8fd0\u884c\u7ed3\u679c # False print ( \"greater\" . upper ()) # \u8fd0\u884c\u7ed3\u679c # GREATER print ( \"greater\" . startswith ( \"great\" )) # \u8fd0\u884c\u7ed3\u679c # True print ( len ( \"greater\" )) print ( \"greater\" . __len__ ()) # \u8fd0\u884c\u7ed3\u679c # 7 print ( \"great\" + \"er\" ) print ( \"great\" . __add__ ( \"er\" )) # \u8fd0\u884c\u7ed3\u679c # greater print ( \"e\" in \"great\" ) print ( \"great\" . __contains__ ( \"e\" )) # \u8fd0\u884c\u7ed3\u679c # True \u63d0\u793a\uff1a dir() \u65b9\u6cd5\u4f1a\u8fd4\u56de\u6240\u4f20\u9012\u7684\u5bf9\u8c61\u7684\u6709\u6548\u5c5e\u6027\uff0c\u8bed\u6cd5\u683c\u5f0f\uff1a dir(object) help() \u51fd\u6570\u67e5\u770b\u51fd\u6570\u6216\u6a21\u5757\u7528\u9014\u7684\u8be6\u7ec6\u8bf4\u660e\uff0c\u8bed\u6cd5\u683c\u5f0f\uff1a help(object) dir ( str ) help ( str . __contains__ )","title":"1.3.3.\u5bf9\u8c61\u548c\u65b9\u6cd5\u8c03\u7528"},{"location":"python/DataStructure/01_PythonFundmantal/#14","text":"Python\u4e2d\u7684\u591a\u9879\u96c6\uff08collections\uff09\u6307\u80fd\u591f\u5305\u542b\u5143\u7d20\u7684\u6570\u636e\u7ed3\u6784\u3002\u591a\u9879\u96c6\u6a21\u5757\u63d0\u4f9b\u4e86\u4e0d\u540c\u7c7b\u578b\u7684\u5bb9\u5668\u3002\u5bb9\u5668\u662f\u7528\u4e8e\u5b58\u50a8\u4e0d\u540c\u5bf9\u8c61\u5e76\u63d0\u4f9b\u8bbf\u95ee\u6240\u5305\u542b\u5bf9\u8c61\u4ee5\u53ca\u5bf9\u5b83\u4eec\u8fdb\u884c\u8fed\u4ee3\u7684\u65b9\u5f0f\u7684\u5bf9\u8c61\u3002\u4e00\u4e9b\u5185\u7f6e\u7684\u5bb9\u5668\u6709\u5143\u7ec4\uff08Tuple\uff09\u3001\u5217\u8868\uff08List\uff09\u3001\u5b57\u5178\uff08Dictionary\uff09\u7b49\u3002 \u4ee5\u4e0b\u662f\u7531collections\u6a21\u5757\u63d0\u4f9b\u7684\u4e0d\u540c\u5bb9\u5668\u7684\u5217\u8868\uff1a \u8ba1\u6570\u5668\uff08Counters\uff09 \u6709\u5e8f\u5b57\u5178\uff08OrderedDict\uff09 \u9ed8\u8ba4\u5b57\u5178\uff08DefaultDict\uff09 \u94fe\u6620\u5c04\uff08ChainMap\uff09 \u547d\u540d\u5143\u7ec4\uff08NamedTuple\uff09 \u53cc\u5411\u961f\u5217\uff08DeQue\uff09 \u7528\u6237\u5b57\u5178\uff08UserDict\uff09 \u7528\u6237\u5217\u8868\uff08UserList\uff09 \u7528\u6237\u5b57\u7b26\u4e32\uff08UserString\uff09","title":"1.4.\u5185\u7f6e\u591a\u9879\u96c6\u53ca\u5176\u64cd\u4f5c"},{"location":"python/DataStructure/01_PythonFundmantal/#141","text":"\u5217\u8868\uff08list\uff09\u662f\u96f6\u4e2a\u6216\u591a\u4e2aPython\u5bf9\u8c61\u7684\u4e00\u4e2a\u5e8f\u5217\uff0c\u8fd9\u4e9b\u5bf9\u8c61\u901a\u5e38\u79f0\u4e3a\u9879\uff08item\uff09\u3002 \u5217\u8868\u7684\u8868\u73b0\u5f62\u5f0f\u662f\uff1a\u7528\u65b9\u62ec\u53f7\u62ec\u8d77\u6574\u4e2a\u5217\u8868\uff0c\u5e76\u7528\u9017\u53f7\u5206\u9694\u5143\u7d20\u3002 \u793a\u4f8b\uff1a [] # \u7a7a\u5217\u8868 [ \"greater\" , \"less\" , 10 ] # \u542b\u4e0d\u540c\u7c7b\u578b\u7684\u5217\u8868 [ \"greater\" , [ \"less\" , 10 ]] # \u542b\u5185\u5d4c\u5217\u8868\u7684\u5217\u8868 \u5217\u8868\u7684\u5207\u7247\u64cd\u4f5c\uff1a \u548c\u5b57\u7b26\u4e32\u7c7b\u4f3c\uff0c\u53ef\u4ee5\u901a\u8fc7\u6807\u51c6\u8fd0\u7b97\u7b26\u6267\u884c\u5207\u7247\u6216\u8fde\u63a5\u64cd\u4f5c\uff0c\u8fd4\u56de\u7ed3\u679c\u4e5f\u662f\u5217\u8868\u3002 \u548c\u5b57\u7b26\u4e32\u4e0d\u540c\uff0c\u5217\u8868\u662f\u53ef\u53d8\u7684\uff0c\u5373\uff0c\u53ef\u4ee5\u66ff\u6362\u3001\u63d2\u5165\u6216\u5220\u9664\u5217\u8868\u4e2d\u6240\u5305\u542b\u7684\u9879\u3002 \u5207\u7247\u548c\u8fde\u63a5\u8fd0\u7b97\u7b26\u6240\u8fd4\u56de\u7684\u5217\u8868\u662f\u65b0\u7684\u5217\u8868\uff0c\u800c\u4e0d\u662f\u6700\u521d\u5217\u8868\u7684\u4e00\u90e8\u5206\uff1b \u5217\u8868\u7c7b\u578b\u5305\u542b\u4e86\u51e0\u4e2a\u53eb\u4f5c\u53d8\u5f02\u5668\uff08mutator\uff09\u7684\u65b9\u6cd5\uff0c\u7528\u4e8e\u4fee\u6539\u5217\u8868\u7684\u7ed3\u6784\u3002 \u53ef\u4ee5\u901a\u8fc7 dir(list) \u6765\u67e5\u770b\u65b9\u6cd5\uff0c\u5305\u62ec\u53d8\u5f02\u5668\uff08mutator\uff09\u7684\u65b9\u6cd5\u3002 dir ( list ) # \u8fd0\u884c\u7ed3\u679c # ['__add__', '__class__', '__contains__', '__delattr__', '__delitem__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__getitem__', '__gt__', '__hash__', '__iadd__', '__imul__', '__init__', '__init_subclass__', '__iter__', '__le__', '__len__', '__lt__', '__mul__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__reversed__', '__rmul__', '__setattr__', '__setitem__', '__sizeof__', '__str__', '__subclasshook__', 'append', 'clear', 'copy', 'count', 'extend', 'index', 'insert', 'pop', 'remove', 'reverse', 'sort'] \u6700\u5e38\u7528\u7684\u5217\u8868\u53d8\u5f02\u5668\u65b9\u6cd5\u662f append \u3001 insert \u3001 pop \u3001 remove \u548c sort \u3002 \u793a\u4f8b\uff1a myList = [] # myList\u5f53\u524d\u4e3a[] myList . append ( 34 ) # myList\u5f53\u524d\u4e3a[34]\uff0c\u9ed8\u8ba4\u5c3e\u90e8\u63d2\u5165 myList . append ( 22 ) # myList\u5f53\u524d\u4e3a[34, 22]\uff0c\u9ed8\u8ba4\u5c3e\u90e8\u63d2\u5165 myList . sort () # myList\u5f53\u524d\u4e3a[22, 34] myList . pop () # \u9ed8\u8ba4\u4ece\u7d22\u5f15\u4f4d[0]\u5220\u9664\uff0c\u8fd4\u56de\u7ed3\u679c22\uff1bmyList\u5f53\u524d\u4e3a[34] myList . insert ( 0 , 22 ) # \u5728\u6307\u5b9a\u7d22\u5f15\u4f4d[0]\u63d2\u5165\uff1bmyList\u5f53\u524d\u4e3a[22, 34] myList . insert ( 1 , 55 ) # \u5728\u6307\u5b9a\u7d22\u5f15\u4f4d[1]\u63d2\u5165\uff1bmyList\u5f53\u524d\u4e3a[22, 55, 34] myList . pop ( 1 ) # \u6307\u5b9a\u7d22\u5f15\u4f4d[1]\u5220\u9664\uff0c\u8fd4\u56de\u7ed3\u679c55\uff1bmyList\u5f53\u524d\u4e3a[22, 34] myList . remove ( 22 ) # \u5220\u9664\u9996\u4e2a\u5339\u914d\u9879\u7684\u5143\u7d20[22]\uff1bmyList\u5f53\u524d\u4e3a[34] myList . remove ( 55 ) # \u62a5ValueError\u9519\uff0clist.remove(x): x not in list \u5bf9\u4e8e\u5b57\u7b26\u4e32\uff0csplit\u65b9\u6cd5\u4f1a\u4ece\u5b57\u7b26\u4e32\u91cc\u5206\u79bb\u51fa\u4e00\u4e2a\u5355\u8bcd\u5217\u8868\uff0c\u800cjoin\u65b9\u6cd5\u4f1a\u628a\u5355\u8bcd\u5217\u8868\u8fde\u5728\u4e00\u8d77\u4ece\u800c\u5f62\u6210\u5b57\u7b26\u4e32\u3002\u4f8b\u5982\uff1a print ( \"Python is cool\" . split ()) # \u8fd0\u884c\u7ed3\u679c\uff1a # ['Python', 'is', 'cool'] print ( \" \" . join ([ \"Python\" , \"is\" , \"cool\" ])) # \u8fd0\u884c\u7ed3\u679c\uff1a # Python is cool \u5bf9\u4e8e\u5217\u8868\u7279\u6027\u548c\u64cd\u4f5c\u7684\u8be6\u7ec6\u7ec3\u4e60\uff0c\u53c2\u8003 Python\u8bed\u8a00\u57fa\u7840@github \u6216\u8005 Python\u8bed\u8a00\u57fa\u7840@web \u4e2d\u201c1.3 \u5217\u8868\uff08list\uff09\u201d\u7684\u5185\u5bb9\u3002","title":"1.4.1.\u5217\u8868"},{"location":"python/DataStructure/01_PythonFundmantal/#142","text":"\u5143\u7ec4\uff08tuple\uff09\u662f\u4e00\u4e2a\u4e0d\u53ef\u53d8\u7684\u5143\u7d20\u5e8f\u5217\u3002 \u5143\u7ec4\uff08tuple\uff09\u5f62\u5f0f\u662f\u7528\u5706\u62ec\u53f7\u5c06\u5404\u9879\u62ec\u8d77\u6765\uff0c\u5e76\u4e14\u5fc5\u987b\u81f3\u5c11\u5305\u542b\u4e24\u4e2a\u9879\u3002 \u5143\u7ec4\u5b9e\u9645\u4e0a\u5c31\u50cf\u5217\u8868\u4e00\u6837\uff0c\u53ea\u4e0d\u8fc7\u5b83\u6ca1\u6709\u53d8\u5f02\u5668\u65b9\u6cd5\u3002 \u5982\u679c\u8981\u4f7f\u5143\u7ec4\u53ea\u5305\u542b\u4e00\u4e2a\u5143\u7d20\uff0c\u5219\u5fc5\u987b\u5728\u5143\u7ec4\u91cc\u5305\u542b\u9017\u53f7\u3002 \u5bf9\u6bd4\u4e0b\u9762\u7684\u533a\u522b\uff1a print (( 21 )) # (21)\u88ab\u89c6\u4e3a\u6574\u6570 # \u8fd0\u884c\u7ed3\u679c\uff1a # 21 print (( 21 ,)) # (21,)\u88ab\u89c6\u4e3a\u5143\u7ec4 # \u8fd0\u884c\u7ed3\u679c\uff1a # (21,) \u5bf9\u4e8e\u5217\u8868\u7279\u6027\u548c\u64cd\u4f5c\u7684\u8be6\u7ec6\u7ec3\u4e60\uff0c\u53c2\u8003 Python\u8bed\u8a00\u57fa\u7840@github \u6216\u8005 Python\u8bed\u8a00\u57fa\u7840@web \u4e2d\u201c1.6 \u5143\u7ec4\uff08tuple\uff09\u201d\u7684\u5185\u5bb9\u3002","title":"1.4.2.\u5143\u7ec4"},{"location":"python/DataStructure/01_PythonFundmantal/#143","text":"for \u5faa\u73af\u53ef\u4ee5\u7528\u6765\u904d\u5386\u5e8f\u5217\uff08\u5982\u5b57\u7b26\u4e32\u3001\u5217\u8868\u6216\u5143\u7ec4\uff09\u91cc\u7684\u6240\u6709\u5143\u7d20\u3002 \u904d\u5386\u5217\u8868\uff1a myList = [ 67 , 100 , 'Monday' , \"It's good\" ] for item in myList : print ( item ) myList = [ 67 , 100 , 'Monday' , \"It's good\" ] for idx in range ( len ( myList )): print ( myList [ idx ]) \u904d\u5386\u5143\u7ec4\uff1a myString = \"I love Python\" myList = myString . split () myTuple = tuple ( myList ) for i in myTuple : print ( i ) \u904d\u5386\u5b57\u7b26\u4e32\uff1a(\u6ce8\u610f\uff0c\u662f\u904d\u5386\u5b57\u7b26\uff0c\u4e0d\u662f\u5355\u8bcd) myString = \"I love Python\" for i in myString : print ( i ) myString = \"I love Python\" for i in range ( len ( myString )): print ( myString [ i ]) myString = \"I love Python\" for i in enumerate ( myString ): print ( i ) myString = \"I love Python\" for i , j in enumerate ( myString ): print ( i , j ) myString = \"I love Python\" for i in iter ( myString ): print ( i ) \u5982\u679c\u6309\u7167\u5355\u8bcd\u904d\u5386\u5b57\u7b26\u4e32\uff0c\u5219\u9700\u8981\u5148\u628a\u5b57\u4e32\u6309\u5355\u8bcd\u62c6\u89e3\u4e3a\u5217\u8868\u3002 myString = \"I love Python\" myList = \"I love Python\" . split () for i in myList : print ( i ) \u5bf9\u4e8e\u5217\u8868\u548c\u5143\u7ec4\u904d\u5386\u7684\u66f4\u591a\u4f8b\u5b50\uff0c\u5305\u62ec\u62c6\u5305\u904d\u5386\uff0c\u53c2\u8003 Python\u8bed\u8a00\u57fa\u7840@github \u6216\u8005 Python\u8bed\u8a00\u57fa\u7840@web \u7684\u5185\u5bb9\u3002","title":"1.4.3.\u5e8f\u5217\u904d\u5386"},{"location":"python/DataStructure/01_PythonFundmantal/#144","text":"\u5b57\u5178\uff08dictionary\uff09\u5305\u542b\u96f6\u4e2a\u6216\u591a\u4e2a\u6761\u76ee\u3002 \u6bcf\u4e2a\u6761\u76ee\uff08entry\uff09\u90fd\u6709\u552f\u4e00\u7684\u952e\u548c\u5b83\u6240\u5bf9\u5e94\u7684\u503c\u76f8\u5173\u8054\u3002 \u952e\u901a\u5e38\u662f\u5b57\u7b26\u4e32\u6216\u6574\u6570\uff0c\u800c\u503c\u662f\u4efb\u610f\u7684Python\u5bf9\u8c61\u3002 \u4e0b\u6807\u8fd0\u7b97\u7b26\u53ef\u4ee5\u7528\u4e8e\u8bbf\u95ee\u4e00\u4e2a\u7ed9\u5b9a\u952e\u7684\u503c\uff0c\u7ed9\u4e00\u4e2a\u65b0\u952e\u6dfb\u52a0\u4e00\u4e2a\u503c\uff0c\u4ee5\u53ca\u66ff\u6362\u7ed9\u5b9a\u952e\u7684\u503c\u3002 pop \u65b9\u6cd5\u4f1a\u5220\u9664\u4e00\u4e2a\u6761\u76ee\u5e76\u8fd4\u56de\u7ed9\u5b9a\u952e\u6240\u5bf9\u5e94\u7684\u503c\u3002 keys \u65b9\u6cd5\u4f1a\u628a\u6240\u6709\u952e\u8fd4\u56de\u6210\u4e00\u4e2a\u53ef\u8fed\u4ee3\u5bf9\u8c61\u3002 values \u65b9\u6cd5\u4f1a\u628a\u6240\u6709\u503c\u8fd4\u56de\u6210\u4e00\u4e2a\u53ef\u8fed\u4ee3\u5bf9\u8c61\u3002 \u793a\u4f8b\uff1a {} # \u7a7a\u5b57\u5178 { \"name\" : \"Ken\" } # \u542b\u4e00\u4e2a\u6761\u76ee { \"name\" : \"Ken\" , \"age\" : 67 } # \u542b\u4e8c\u4e2a\u6761\u76ee { \"hobbies\" :[ \"reading\" , \"running\" ]} # \u542b\u4e00\u4e2a\u6761\u76ee\uff0c\u5176\u4e2d\u503c\u662f\u4e00\u4e2a\u5217\u8868 \u5b57\u5178\u672c\u8eab\u4e5f\u662f\u4e00\u4e2a\u53ef\u8fed\u4ee3\u5bf9\u8c61\u3002\u53ef\u4ee5\u901a\u8fc7for\u8bed\u53e5\u8fdb\u884c\u904d\u5386\u952e\u6216/\u548c\u503c\u3002 myDict = { 'name' : 'Ming' , 'id' : 1001 , 'age' : 35 } for keys in myDict : print ( keys , myDict [ keys ]) # \u8fd0\u884c\u7ed3\u679c\uff1a # name Ming # id 1001 # age 35","title":"1.4.4.\u5b57\u5178"},{"location":"python/DataStructure/01_PythonFundmantal/#145","text":"\u53ef\u4ee5\u5728\u5b57\u7b26\u4e32\u5217\u8868\u3001\u5143\u7ec4\u6216\u5b57\u5178\u91cc\u901a\u8fc7 in \u8fd0\u7b97\u7b26\u6765\u5bf9\u503c\u6216\u591a\u9879\u96c6\u8fdb\u884c\u641c\u7d22\uff0c\u8fd4\u56de True \u6216 False \u3002\u5bf9\u4e8e\u5b57\u5178\u6765\u8bf4\uff0c\u641c\u7d22\u7684\u76ee\u6807\u503c\u5e94\u8be5\u662f\u4e00\u4e2a\u952e\u3002 \u5982\u679c\u5df2\u77e5\u7ed9\u5b9a\u503c\u5b58\u5728\u4e8e\u5e8f\u5217\uff08\u5b57\u7b26\u4e32\u3001\u5217\u8868\u6216\u5143\u7ec4\uff09\u91cc\uff0c\u90a3\u4e48 index \u65b9\u6cd5\u5c06\u8fd4\u56de\u8fd9\u4e2a\u503c\u6240\u51fa\u73b0\u7684\u7b2c\u4e00\u4e2a\u4f4d\u7f6e\u3002 \u5217\u8868\u68c0\u7d22\uff1a myString = \"I love Python\" myList = myString . split () print ( myList ) # \u8fd0\u884c\u7ed3\u679c\uff1a # ['I', 'love', 'Python'] print ( myList . index ( 'love' )) # \u8fd0\u884c\u7ed3\u679c\uff1a # 1 \u5143\u7ec4\u68c0\u7d22\uff1a myString = \"I love Python\" myList = myString . split () myTuple = tuple ( myList ) print ( myTuple ) print ( myTuple . index ( 'love' )) \u5b57\u5178\u68c0\u7d22\uff1a myDict = { 'name' : 'Ming' , 'id' : 1001 , 'age' : 35 } print ( myDict ) for keys in myDict : print ( keys , myDict [ keys ]) myDict . pop ( 'city' ) # \u62a5\u9519\uff0cKeyError: 'city' myDict . pop ( 'id' ) print ( myDict ) # \u8fd0\u884c\u7ed3\u679c\uff1a{'name': 'Ming', 'age': 35}","title":"1.4.5.\u503c\u68c0\u7d22"},{"location":"python/DataStructure/01_PythonFundmantal/#146","text":"\u4e0b\u6807\u8fd0\u7b97\u7b26\u53ef\u4ee5\u7528\u6765\u8bbf\u95ee\u5217\u8868\u3001\u5143\u7ec4\u548c\u5b57\u5178\u91cc\u7684\u5143\u7d20\u3002 \u901a\u8fc7\u6a21\u5f0f\u5339\u914d\u53ef\u4ee5\u4e00\u6b21\u8bbf\u95ee\u591a\u4e2a\u5143\u7d20\u3002 \u793a\u4f8b\uff1a myTuple \u662f\u4e00\u4e2a\u542b\u5185\u5d4c\u5143\u7ec4\u7684\u5143\u7ec4\u3002 myTuple = (( 'r' , 'g' , 'b' ), 'hexString' ) print ( myTuple ) # \u8fd0\u884c\u7ed3\u679c\uff1a # (('r', 'g', 'b'), 'hexString') print ( myTuple [ 0 ]) # \u8fd0\u884c\u7ed3\u679c\uff1a # ('r', 'g', 'b') print ( myTuple [ 0 ][ 0 ]) # \u8fd0\u884c\u7ed3\u679c\uff1a # r print ( myTuple [ 0 ][ 1 ]) # \u8fd0\u884c\u7ed3\u679c\uff1a # g print ( myTuple [ 0 ][ 2 ]) # \u8fd0\u884c\u7ed3\u679c\uff1a # b print ( myTuple [ 1 ]) # \u8fd0\u884c\u7ed3\u679c\uff1a # hexString \u901a\u8fc7\u4e0a\u9762\u7684\u62c6\u89e3\uff0c\u6211\u4eec\u6e05\u695a\u4e86\u5185\u5d4c\u5143\u7ec4\u7684\u7ed3\u6784\u8be6\u7ec6\u60c5\u51b5\u3002 \u4e0b\u9762\uff0c\u6211\u4eec\u901a\u8fc7\u6a21\u5f0f\u5339\u914d\uff0c\u628a\u4e00\u4e2a\u7ed3\u6784\u5206\u914d\u7ed9\u5f62\u5f0f\u5b8c\u5168\u76f8\u540c\u7684\u53e6\u4e00\u4e2a\u7ed3\u6784\u3002\u8fd9\u91cc\u76ee\u6807\u7ed3\u6784 newTuple \u6240\u5305\u542b\u7684\u53d8\u91cf\u4ece\u6e90\u7ed3\u6784 (('r', 'g', 'b'), 'hexString') \u91cc\u7684\u76f8\u5e94\u4f4d\u7f6e\u5904\u83b7\u5f97\u5bf9\u5e94\u7684\u503c\u3002 newTuple = (( 'r' , 'g' , 'b' ), 'hexString' ) print ( newTuple [ 0 ]) # ('r', 'g', 'b') print ( newTuple [ 0 ][ 0 ]) # \u8fd0\u884c\u7ed3\u679c\uff1a # r print ( newTuple [ 0 ][ 1 ]) # \u8fd0\u884c\u7ed3\u679c\uff1a # g print ( newTuple [ 0 ][ 2 ]) # \u8fd0\u884c\u7ed3\u679c\uff1a # b print ( newTuple [ 1 ]) # \u8fd0\u884c\u7ed3\u679c\uff1a # hexString","title":"1.4.6.\u6a21\u5f0f\u5339\u914d\u8bbf\u95ee\u591a\u9879\u96c6"},{"location":"python/DataStructure/01_PythonFundmantal/#15","text":"Python\u652f\u6301\u5b8c\u5168\u51fd\u6570\u5f0f\u7f16\u7a0b\u8bbe\u8ba1\u3002 Python\u5305\u542b\u5f88\u591a\u5185\u7f6e\u51fd\u6570\u3002 Python\u4e5f\u8fd0\u884c\u521b\u5efa\u65b0\u51fd\u6570\uff0c\u53ef\u4ee5\u4f7f\u7528\u9012\u5f52\uff0c\u628a\u51fd\u6570\u4f5c\u4e3a\u6570\u636e\u8fdb\u884c\u4f20\u9012\u548c\u8fd4\u56de\u3002","title":"1.5.\u521b\u5efa\u51fd\u6570"},{"location":"python/DataStructure/01_PythonFundmantal/#151","text":"\u51fd\u6570\u5b9a\u4e49\u8bed\u6cd5\uff1a \u547d\u540d\u51fd\u6570\u540d\u79f0\u548c\u53c2\u6570\u540d\u79f0\u7684\u89c4\u5219\u4e0e\u60ef\u4f8b\u4e0e\u547d\u540d\u53d8\u91cf\u7684\u662f\u76f8\u540c\u7684\u3002 \u5fc5\u9009\u53c2\u6570\u7684\u5217\u8868\u53ef\u4ee5\u4e3a\u7a7a\uff0c\u4e5f\u53ef\u4ee5\u5305\u542b\u7528\u9017\u53f7\u9694\u5f00\u7684\u540d\u79f0\u3002 \u4e0e\u5176\u4ed6\u7f16\u7a0b\u8bed\u8a00\u4e0d\u540c\u7684\u662f\uff0c\u53c2\u6570\u540d\u79f0\u6216\u51fd\u6570\u540d\u79f0\u672c\u8eab\u5e76\u4e0d\u4f1a\u548c\u6570\u636e\u7c7b\u578b\u8fdb\u884c\u5173\u8054\u3002 def < function name > ( < list of parameters > ): < sequence of statements > \u793a\u4f8b\uff1a \u5728\u51fd\u6570\u7684\u6807\u9898\u4e0b\u6709\u4e00\u884c\u7528\u4e09\u5f15\u53f7\u62ec\u8d77\u6765\u7684\u5b57\u7b26\u4e32 \u8fd4\u56den\u7684\u5e73\u65b9\u6570 \uff0c\u8fd9\u662f\u4e00\u4e2a\u6587\u6863\u5b57\u7b26\u4e32\uff08docstring\uff09\u3002 \u5728shell\u91cc\u9762\u8f93\u5165help(square)\u65f6\uff0c\u4f1a\u663e\u793a\u8fd9\u4e2a\u5b57\u7b26\u4e32\u3002 \u5b9a\u4e49\u7684\u6bcf\u4e00\u4e2a\u51fd\u6570\u90fd\u5e94\u8be5\u6709\u6587\u6863\u5b57\u7b26\u4e32\uff0c\u6765\u8bf4\u660e\u8be5\u51fd\u6570\u7684\u529f\u80fd\uff0c\u5e76\u63d0\u4f9b\u76f8\u5173\u7684\u6240\u6709\u53c2\u6570\u4ee5\u53ca\u8fd4\u56de\u503c\u7684\u4fe1\u606f\u3002 \u51fd\u6570\u7684\u53c2\u6570\u548c\u4e34\u65f6\u53d8\u91cf\u53ea\u4f1a\u5728\u51fd\u6570\u8c03\u7528\u7684\u751f\u5b58\u5468\u671f\u5185\u5b58\u5728\uff0c\u5e76\u4e14\u5bf9\u5176\u4ed6\u51fd\u6570\u53ca\u5176\u5916\u56f4\u7a0b\u5e8f\u90fd\u662f\u4e0d\u53ef\u89c1\u7684\u3002 n \u662f\u53c2\u6570\u3002 result \u662f\u4e34\u65f6\u53d8\u91cf\u3002 \u5982\u679c\u51fd\u6570\u4e0d\u5305\u542b return \u8bed\u53e5\u65f6\uff0c\u5b83\u5c06\u5728\u6700\u540e\u4e00\u6761\u8bed\u53e5\u6267\u884c\u4e4b\u540e\u81ea\u52a8\u8fd4\u56de None \u503c\u3002 \u7528 = \u628a\u53c2\u6570\u6307\u5b9a\u4e3a\u6709\u9ed8\u8ba4\u503c\u7684\u53ef\u9009\u53c2\u6570\u3002 \u5728\u53c2\u6570\u5217\u8868\u4e2d\uff0c\u5fc5\u9009\u53c2\u6570\uff08\u6ca1\u6709\u9ed8\u8ba4\u503c\u7684\u53c2\u6570\uff09\u5fc5\u987b\u4f4d\u4e8e\u53ef\u9009\u53c2\u6570\u4e4b\u524d\u3002 def square ( n ): \"\"\"\u8fd4\u56den\u7684\u5e73\u65b9\u6570\"\"\" result = n ** 2 return result print ( square ( 5 ))","title":"1.5.1.\u51fd\u6570\u5b9a\u4e49"},{"location":"python/DataStructure/01_PythonFundmantal/#152","text":"\u9012\u5f52\u51fd\u6570\uff08recursive function\uff09\u662f\u6307\u4f1a\u8c03\u7528\u81ea\u8eab\u7684\u51fd\u6570\u3002 \u4e3a\u4e86\u9632\u6b62\u51fd\u6570\u65e0\u9650\u5730\u91cd\u590d\u8c03\u7528\u81ea\u8eab\uff0c\u4ee3\u7801\u4e2d\u5fc5\u987b\u81f3\u5c11\u6709\u4e00\u6761\u7528\u6765\u67e5\u9a8c\u6761\u4ef6\u7684\u9009\u62e9\u8bed\u53e5\uff0c\u7528\u4e8e\u786e\u5b9a\u63a5\u4e0b\u6765\u8981\u7ee7\u7eed\u9012\u5f52\u8fd8\u662f\u505c\u6b62\u9012\u5f52\u3002\u8fd9\u4e2a\u68c0\u67e5\u6761\u4ef6\u8bed\u53e5\u79f0\u4e3a\u57fa\u672c\u60c5\u51b5\uff08base case\uff09\u3002 \u793a\u4f8b\uff1a\u4e0b\u9762\u662f\u901a\u8fc7\u5faa\u73af\u5b9e\u73b0\u8f93\u51fa\u4ece\u7ed9\u5b9a\u7684\u6700\u5c0f\u503c\u5230\u6700\u5927\u503c\u4e4b\u95f4\u7684\u6574\u6570\u548c\u3002 def mySum ( lower , upper ): \"\"\"\u5bf9\u7ed9\u5b9a\u7684\u6700\u5c0f\u503c\u5230\u6700\u5927\u503c\u4e4b\u95f4\u7684\u6574\u6570\u6c42\u548c; lower:\u6700\u5c0f\u503c; upper:\u6700\u5927\u503c;\"\"\" result = 0 while ( lower <= upper ): result = result + lower lower += 1 return result print ( mySum ( 1 , 10 )) # \u8fd0\u884c\u7ed3\u679c\uff1a # 55 \u7528\u9012\u5f52\u51fd\u6570\u6539\u5199\u4e0a\u8ff0\u51fd\u6570\u3002 def mySum ( lower , upper ): \"\"\"\u5bf9\u7ed9\u5b9a\u7684\u6700\u5c0f\u503c\u5230\u6700\u5927\u503c\u4e4b\u95f4\u7684\u6574\u6570\u6c42\u548c; lower:\u6700\u5c0f\u503c; upper:\u6700\u5927\u503c;\"\"\" if lower <= upper : return lower + mySum ( lower + 1 , upper ) else : return 0 print ( mySum ( 1 , 10 )) # \u8fd0\u884c\u7ed3\u679c\uff1a # 55 \u901a\u5e38\u6765\u8bf4\uff0c\u9012\u5f52\u51fd\u6570\u81f3\u5c11\u6709\u4e00\u4e2a\u53c2\u6570\u3002 \u8fd9\u4e2a\u53c2\u6570\u7684\u503c\u4f1a\u88ab\u7528\u6765\u5bf9\u9012\u5f52\u8fc7\u7a0b\u7684\u57fa\u672c\u60c5\u51b5\u8fdb\u884c\u5224\u5b9a\uff0c\u4ece\u800c\u51b3\u5b9a\u662f\u5426\u8981\u7ed3\u675f\u6574\u4e2a\u8c03\u7528\u3002 \u5728\u6bcf\u6b21\u9012\u5f52\u8c03\u7528\u4e4b\u524d\uff0c\u8fd9\u4e2a\u503c\u4e5f\u4f1a\u88ab\u8fdb\u884c\u67d0\u79cd\u65b9\u5f0f\u7684\u4fee\u6539\u3002 \u6bcf\u6b21\u5bf9\u8fd9\u4e2a\u503c\u7684\u4fee\u6539\uff0c\u90fd\u5e94\u8be5\u4ea7\u751f\u4e00\u4e2a\u65b0\u6570\u636e\u503c\uff0c\u53ef\u4ee5\u8ba9\u51fd\u6570\u6700\u7ec8\u8fbe\u5230\u57fa\u672c\u60c5\u51b5\u3002 \u4e3a\u4e86\u5bf9 mySum \u51fd\u6570\u7684\u9012\u5f52\u8fdb\u884c\u8ddf\u8e2a\uff0c\u53ef\u4ee5\u5c1d\u8bd5\u6dfb\u52a0\u4e00\u4e2a\u4ee3\u8868\u7f29\u8fdb\u8fb9\u8ddd\u7684\u53c2\u6570\u5e76\u4e14\u6dfb\u52a0\u4e00\u4e9bprint\u8bed\u53e5\u3002\u8fd9\u6837\u5728\u6bcf\u6b21\u8c03\u7528\u65f6\uff0c\u51fd\u6570\u7684\u7b2c\u4e00\u6761\u8bed\u53e5\u4f1a\u8ba1\u7b97\u7f29\u8fdb\u6570\u91cf\uff0c\u7136\u540e\u518d\u6253\u5370\u4e24\u4e2a\u53c2\u6570\u7684\u503c\uff0c\u6bcf\u6b21\u8fd4\u56de\u8c03\u7528\u4e4b\u524d\u7684\u8fd4\u56de\u503c\u65f6\u90fd\u4f7f\u7528\u76f8\u540c\u7684\u7f29\u8fdb\uff0c\u5c31\u53ef\u4ee5\u5b9e\u73b0\u5bf9\u4e24\u4e2a\u53c2\u6570\u7684\u503c\u4ee5\u53ca\u6bcf\u6b21\u8c03\u7528\u7684\u8fd4\u56de\u503c\u8fdb\u884c\u8ddf\u8e2a\u3002 def mySum ( lower , upper , margin = 0 ): \"\"\"\u5bf9\u7ed9\u5b9a\u7684\u6700\u5c0f\u503c\u5230\u6700\u5927\u503c\u4e4b\u95f4\u7684\u6574\u6570\u6c42\u548c\uff0c\u901a\u8fc7\u9636\u68af\u65b9\u5f0f\u8f93\u51fa; lower:\u6700\u5c0f\u503c; upper:\u6700\u5927\u503c;\"\"\" blanks = \" \" * margin print ( blanks , lower , upper ) if lower <= upper : result = lower + mySum ( lower + 1 , upper , margin + 4 ) print ( blanks , result ) return result else : print ( blanks , 0 ) return 0 print ( mySum ( 1 , 5 )) # \u8fd0\u884c\u7ed3\u679c\uff1a # 1 5 # 2 5 # 3 5 # 4 5 # 5 5 # 6 5 # 0 # 5 # 9 # 12 # 14 # 15 # 15","title":"1.5.2.\u51fd\u6570\u9012\u5f52"},{"location":"python/DataStructure/01_PythonFundmantal/#153","text":"\u5d4c\u5957\u51fd\u6570\u7c7b\u4f3c\u4e8e\u5d4c\u5957\u5faa\u73af\uff0c\u5c31\u662f\u51fd\u6570\u5185\u53c8\u5d4c\u5957\u7740\u51fd\u6570\u3002\u5373\uff0c\u51fd\u6570\u7684\u5b9a\u4e49\u5d4c\u5957\u5728\u4e00\u4e2a\u51fd\u6570\u7684\u8bed\u53e5\u5e8f\u5217\u91cc\u3002 \u5148\u770b\u4e00\u4e2a\u666e\u901a\u4f8b\u5b50\uff1a # \u5b9a\u4e49inner\u51fd\u6570 def inner (): print ( '\u6211\u662finner' ) # \u5b9a\u4e49outer\u51fd\u6570\uff0couter\u51fd\u6570\u8c03\u7528inner\u51fd\u6570 def outer (): print ( '\u6211\u662fouter' ) inner () outer () # \u8fd0\u884c\u7ed3\u679c\uff1a # \u6211\u662fouter # \u6211\u662finner \u6539\u5199\u4e0a\u9762\u7684\u4ee3\u7801\uff0c\u628a inner \u51fd\u6570\u5199\u5728 outer \u51fd\u6570\u91cc\u9762\u3002 # \u5b9a\u4e49outer\u51fd\u6570\uff0couter\u51fd\u6570\u5185\u5d4cinner\u51fd\u6570\uff0c\u5e76\u8c03\u7528inner\u51fd\u6570 def outer (): print ( '\u6211\u662fouter' ) # \u5b9a\u4e49inner\u51fd\u6570 def inner (): print ( '\u6211\u662finner' ) inner () outer () # \u8fd0\u884c\u7ed3\u679c\uff1a # \u6211\u662fouter # \u6211\u662finner \u4e0a\u9762\u7684\u5916\u5c42 outer \u51fd\u6570\u548c\u5185\u5c42 inner \u51fd\u6570\u90fd\u6ca1\u6709\u53d8\u91cf\u548c\u53c2\u6570\u3002 \u73b0\u5728\u4fee\u6539\u4e0a\u9762\u7684\u4ee3\u7801\uff0c\u6211\u4eec\u4f20\u5165\u53c2\u6570\u548c\u53d8\u91cf\uff0c\u7136\u540e\u628a\u5916\u5c42\u51fd\u6570\u8fd4\u56de\u503c\u6307\u5411\u5185\u5c42\u51fd\u6570\u540d\u3002 def outer (): a = 1 print ( '\u6211\u662fouter' ) # \u5b9a\u4e49inner\u51fd\u6570 def inner (): print ( '\u6211\u662finner' ) print ( 'inner\u6253\u5370: ' , a ) # \u8fd4\u56de\u5185\u5c42inner\u51fd\u6570\u540d return inner f = outer () # \u8fd0\u884c\u7ed3\u679c\uff1a # \u6211\u662fouter f () # \u8fd0\u884c\u7ed3\u679c\uff1a # \u6211\u662finner # inner\u6253\u5370: 1 \u5728\u4e0a\u9762\u7684\u4f8b\u5b50\u4e2d\uff1a f = outer() \u8c03\u7528\u5916\u5c42 outer \u51fd\u6570\uff0c\u5e76\u628a\u7ed3\u679c\u8d4b\u503c\u7ed9 f \u3002\u6ce8\u610f\uff0cinner\u51fd\u6570\u5e76\u6ca1\u6709\u88ab\u6267\u884c\u3002 f \u5176\u5b9e\u5c31\u662f inner \uff0c\u6307\u5411 inner \u7684\u5185\u5b58\u7a7a\u95f4\u3002\u901a\u8fc7 f() \u9a8c\u8bc1\u4e86\u8fd9\u4e00\u70b9\uff0c outer \u51fd\u6570\u4e2d\u7684\u53d8\u91cf a \u88ab\u6253\u5370\u51fa\u6765\u4e86\u3002 \u4e0a\u9762\u4f8b\u5b50\u4e2d outer \u5c31\u662f\u95ed\u5305\u51fd\u6570\uff0c\u5916\u5c42\u51fd\u6570\u7684\u53d8\u91cf\u53ef\u4ee5\u88ab\u5185\u5c42\u51fd\u6570\u8c03\u7528\uff0c\u7c7b\u4f3c\u4e8e\u5c01\u88c5\u7684\u6548\u679c\u3002\u5185\u5c42\u51fd\u6570\u4e0d\u4f1a\u7acb\u523b\u88ab\u6267\u884c\uff0c\u5f53\u518d\u6b21\u8c03\u7528\u65f6\uff0c\u5185\u5c42\u51fd\u6570\u624d\u4f1a\u6267\u884c\u3002 \u95ed\u5305\u51fd\u6570\u9700\u8981\u6709\u4e09\u4e2a\u6761\u4ef6\uff1a \u5fc5\u987b\u6709\u4e00\u4e2a\u5185\u5d4c\u51fd\u6570\uff0c\u4f8b\u5982\u51fd\u6570 inner \uff1b \u5185\u90e8\u51fd\u6570\u5f15\u7528\u5916\u90e8\u51fd\u6570\u53d8\u91cf\uff0c\u4f8b\u5982\u53d8\u91cf a \uff1b \u5916\u90e8\u51fd\u6570\u5fc5\u987b\u8fd4\u56de\u5185\u5d4c\u51fd\u6570\uff0c\u4f8b\u5982 outer \u51fd\u6570\u4e2d\u7684 return inner \uff1b \u5bf9\u4e0a\u9762\u7684\u4ee3\u7801\u518d\u8fdb\u884c\u4fee\u6539\uff0c\u5728 inner \u51fd\u6570\u4e2d\u518d\u6dfb\u52a0\u4e00\u4e2a\u540c\u540d\u7684\u53d8\u91cfa\u3002\u4ece\u7ed3\u679c\u53ef\u4ee5\u5f97\u51fa\u7ed3\u8bba\uff0c inner \u51fd\u6570\u4f18\u5148\u5728\u5185\u90e8\u67e5\u627e\u53d8\u91cf a=5 \u3002 def outer (): a = 1 print ( '\u6211\u662fouter' ) # \u5b9a\u4e49inner\u51fd\u6570 def inner (): a = 5 print ( '\u6211\u662finner' ) print ( 'inner\u6253\u5370: ' , a ) return inner f = outer () # \u8fd0\u884c\u7ed3\u679c\uff1a # \u6211\u662fouter f () # \u8fd0\u884c\u7ed3\u679c\uff1a # \u6211\u662finner # inner\u6253\u5370: 5 \u7ed3\u8bba\uff1a\u5185\u5c42\u51fd\u6570\u4e2d\u8c03\u7528\u7684\u53d8\u91cf\uff1a \u9996\u5148\u4f1a\u4ece\u5185\u5c42\u51fd\u6570\u4e2d\u627e\uff0c \u627e\u4e0d\u5230\u5c31\u53bb\u5916\u5c42\u51fd\u6570\u4e2d\u627e\uff0c \u518d\u627e\u4e0d\u5230\u5c31\u5230\u51fd\u6570\u5916\u4e2d\u627e\uff0c \u518d\u627e\u4e0d\u5230\u5c31\u5230\u5185\u7f6e\u7684\u6a21\u5757\u4e2d\u627e\uff0c \u518d\u627e\u4e0d\u5230\uff0c\u5c31\u62a5\u9519\u3002 \u8fd9\u5c31\u662f\u4f5c\u7528\u57df\u7684\u6982\u5ff5\u3002 \u7ee7\u7eed\u4fee\u6539\u4e0a\u9762\u7684\u4ee3\u7801\uff0c\u5728 inner \u51fd\u6570\u4e2d\u4fee\u6539 outer \u51fd\u6570\u4e2d\u53d8\u91cf a \u7684\u503c\uff0c\u8fd0\u884c\u7ed3\u679c\u62a5\u9519\u3002\u7ed3\u8bba\uff1a\u5185\u5c42\u51fd\u6570\u4e0d\u80fd\u4fee\u6539\u5916\u5c42\u51fd\u6570\u7684\u53d8\u91cf\u503c\u3002 def outer (): a = 1 print ( '\u6211\u662fouter' ) # \u5b9a\u4e49inner\u51fd\u6570 def inner (): a += 5 print ( '\u6211\u662finner' ) print ( 'inner\u6253\u5370: ' , a ) return inner f = outer () # \u8fd0\u884c\u7ed3\u679c\uff1a # \u6211\u662fouter f () # \u8fd0\u884c\u7ed3\u679c\uff1a # UnboundLocalError: local variable 'a' referenced before assignment \u4fee\u6b63\u4e0a\u9762\u7684\u4ee3\u7801\u3002\u5728 inner \u51fd\u6570\u4e2d\u5bf9\u53d8\u91cfa\u6dfb\u52a0\u4e00\u4e2a nonlocal \u7684\u58f0\u660e\uff0c\u5c31\u53ef\u4ee5\u5728 inner \u51fd\u6570\u4e2d\u4fee\u6539\u5916\u5c42outer\u51fd\u6570\u7684\u53d8\u91cf a \u7684\u503c\u3002 def outer (): a = 1 print ( '\u6211\u662fouter' ) # \u5b9a\u4e49inner\u51fd\u6570 def inner (): nonlocal a a += 5 print ( '\u6211\u662finner' ) print ( 'inner\u6253\u5370: ' , a ) return inner f = outer () # \u8fd0\u884c\u7ed3\u679c\uff1a # \u6211\u662fouter f () # \u8fd0\u884c\u7ed3\u679c\uff1a # \u6211\u662finner # inner\u6253\u5370: 6 \u4e0b\u9762\u8fd9\u6bb5\u4ee3\u7801\u662f\u9636\u4e58\uff08factorial\uff09\u9012\u5f52\u51fd\u6570\u7684\u4e24\u4e2a\u4e0d\u540c\u7684\u5b9a\u4e49\u3002 \u7b2c\u4e00\u4e2a\u5b9a\u4e49\u4f7f\u7528\u4e86\u5d4c\u5957\u7684\u8f85\u52a9\u51fd\u6570 recurse \u6765\u5bf9\u6240\u9700\u8981\u7684\u53c2\u6570\u8fdb\u884c\u9012\u5f52\uff1b\u8fd9\u91cc\u7684 factorial \u51fd\u6570\u5c31\u662f\u95ed\u5305\u51fd\u6570\u3002 \u7b2c\u4e00\u6b65\uff1a\u7b2c\u4e00\u6b21\u8c03\u7528 factorial() \u51fd\u6570\uff0c\u5373 n=5 \uff1b \u7b2c\u4e8c\u6b65\uff1a\u7b2c\u4e00\u6b21\u8c03\u7528\u5185\u5c42\u51fd\u6570 recurse() \uff0c\u4f46\u4e0d\u4f1a\u7acb\u523b\u88ab\u6267\u884c\uff1b \u7b2c\u4e09\u6b65\uff0c\u6267\u884c return recurse(5, 1) \uff0c\u5bf9\u53c2\u6570 product \u521d\u59cb\u5316\u8d4b\u503c 1 \u7b2c\u56db\u6b65\uff1a\u6267\u884c return recurse(5, 5 * 1) \uff0c\u6b64\u65f6 n=5 \uff0c product=1 \u3002 \u7b2c\u4e94\u6b65\uff1a\u6267\u884c return recurse(4, 4 * 5) \uff0c\u6b64\u65f6 n=4 \uff0c product=5 \u3002 \u7b2c\u516d\u6b65\uff1a\u6267\u884c return recurse(3, 3 * 20) \uff0c\u6b64\u65f6 n=3 \uff0c product=20 \u3002 \u7b2c\u4e03\u6b65\uff1a\u6267\u884c return recurse(2, 2 * 60) \uff0c\u6b64\u65f6 n=2 \uff0c product=60 \u3002 \u7b2c\u516b\u6b65\uff1a\u6267\u884c return recurse(1, 1 * 120) \uff0c\u6b64\u65f6 n=1 \uff0c product=120 \u3002 \u7b2c\u4e5d\u6b65\uff1a\u6b64\u65f6 n=1 \uff0c\u6267\u884c return product \uff0c\u5373 return 120 \uff0c\u7ed3\u675f\u3002 \u7b2c\u4e8c\u4e2a\u5b9a\u4e49\u5219\u662f\u4e3a\u7b2c\u4e8c\u4e2a\u53c2\u6570\u63d0\u4f9b\u4e86\u9ed8\u8ba4\u503c\uff0c\u4ece\u800c\u7b80\u5316\u4e86\u8bbe\u8ba1\u3002 # \u7b2c\u4e00\u4e2a\u5b9a\u4e49 def factorial ( n ): \"\"\"\u8fd4\u56de n \u7684\u9636\u4e58\"\"\" def recurse ( n , product ): \"\"\"\u8ba1\u7b97\u9636\u4e58\u7684\u5e2e\u52a9\u5668\"\"\" print ( n , product ) # \u63d2\u5165\u8fd9\u4e00\u53e5\u662f\u4e3a\u4e86\u80fd\u770b\u6e05\u695a\u6bcf\u4e00\u6b21\u9012\u5f52\u8c03\u7528\u7684n\u548cproduct\u53d8\u5316 if n == 1 : return product else : return recurse ( n - 1 , n * product ) return recurse ( n , 1 ) f = factorial ( 5 ) # \u8fd0\u884c\u7ed3\u679c 5 1 4 5 3 20 2 60 1 120 # \u7b2c\u4e8c\u4e2a\u5b9a\u4e49 def factorial ( n , product = 1 ): \"\"\"\u8fd4\u56de n \u7684\u9636\u4e58\"\"\" if n == 1 : return product else : return factorial ( n - 1 , n * product ) print ( factorial ( 5 )) # \u8fd0\u884c\u7ed3\u679c # 120","title":"1.5.3.\u51fd\u6570\u5d4c\u5957"},{"location":"python/DataStructure/01_PythonFundmantal/#154","text":"\u51fd\u6570\u672c\u8eab\u4e5f\u662f\u4e00\u79cd\u72ec\u7279\u7684\u6570\u636e\u5bf9\u8c61\u3002\u53ef\u4ee5\u628a\u5b83\u4eec\u8d4b\u7ed9\u53d8\u91cf\u3001\u5b58\u50a8\u5728\u6570\u636e\u7ed3\u6784\u91cc\u3001\u4f5c\u4e3a\u53c2\u6570\u4f20\u9012\u7ed9\u5176\u4ed6\u51fd\u6570\u4ee5\u53ca\u4f5c\u4e3a\u5176\u4ed6\u51fd\u6570\u7684\u503c\u8fd4\u56de\u3002 \u9ad8\u9636\u51fd\u6570\uff08higher-order function\uff09\uff1a\u5b83\u63a5\u6536\u53e6\u4e00\u4e2a\u51fd\u6570\u4f5c\u4e3a\u53c2\u6570\uff0c\u5e76\u4e14\u4ee5\u67d0\u79cd\u65b9\u5f0f\u5e94\u7528\u8be5\u51fd\u6570\u3002 Python\u6709\u4e24\u4e2a\u5185\u7f6e\u7684\u9ad8\u9636\u51fd\u6570\uff0c\u5206\u522b\u662f map \u548c filter \uff0c\u5b83\u4eec\u53ef\u4ee5\u7528\u4e8e\u5904\u7406\u53ef\u8fed\u4ee3\u5bf9\u8c61\u3002 map \u51fd\u6570\u4f1a\u63a5\u6536\u53e6\u4e00\u4e2a\u51fd\u6570\u548c\u4e00\u4e2a\u53ef\u8fed\u4ee3\u5bf9\u8c61\u4f5c\u4e3a\u53c2\u6570\uff0c\u8fd4\u56de\u53e6\u4e00\u4e2a\u53ef\u8fed\u4ee3\u5bf9\u8c61\u3002\u8fd9\u4e2a\u51fd\u6570\u4f1a\u628a\u4f5c\u4e3a\u53c2\u6570\u4f20\u9012\u7684\u51fd\u6570\u5e94\u7528\u5728\u53ef\u8fed\u4ee3\u5bf9\u8c61\u91cc\u7684\u6bcf\u4e2a\u5143\u7d20\u4e0a\u3002\u7b80\u5355\u6765\u8bf4\uff0c map \u51fd\u6570\u4f1a\u5bf9\u53ef\u8fed\u4ee3\u5bf9\u8c61\u91cc\u7684\u6bcf\u4e2a\u5143\u7d20\u8fdb\u884c\u8f6c\u6362\u3002 filter \u4f1a\u63a5\u53d7\u4e00\u4e2a\u5e03\u5c14\u51fd\u6570\u548c\u4e00\u4e2a\u53ef\u8fed\u4ee3\u5bf9\u8c61\u4f5c\u4e3a\u53c2\u6570\uff0c\u8fd4\u56de\u8fd9\u6837\u4e00\u4e2a\u53ef\u8fed\u4ee3\u5bf9\u8c61\uff0c\u5b83\u7684\u6bcf\u4e00\u4e2a\u5143\u7d20\u90fd\u4f1a\u88ab\u4f20\u9012\u7ed9\u5e03\u5c14\u51fd\u6570\uff0c\u5982\u679c\u8fd9\u4e2a\u51fd\u6570\u8fd4\u56deTrue\uff0c\u90a3\u4e48\u8fd9\u4e2a\u5143\u7d20\u5c06\u88ab\u4fdd\u7559\u5728\u8fd4\u56de\u7684\u53ef\u8fed\u4ee3\u5bf9\u8c61\u91cc\uff1b\u5426\u5219\uff0c\u8fd9\u4e2a\u5143\u7d20\u5c06\u88ab\u5220\u9664\u3002\u7b80\u5355\u8bf4\uff0c filter \u51fd\u6570\u4f1a\u628a\u6240\u6709\u80fd\u591f\u901a\u8fc7\u68c0\u9a8c\u7684\u5143\u7d20\u4fdd\u7559\u5728\u53ef\u8fed\u4ee3\u5bf9\u8c61\u91cc\u3002 functools.reduce \u901a\u8fc7\u628a\u63a5\u6536\u4e24\u4e2a\u53c2\u6570\u7684\u51fd\u6570\u7684\u7ed3\u679c\u4ee5\u53ca\u8fed\u4ee3\u5bf9\u8c61\u7684\u4e0b\u4e00\u4e2a\u5143\u7d20\u518d\u6b21\u5e94\u7528\u4e8e\u8fd9\u4e2a\u63a5\u6536\u4e24\u4e2a\u53c2\u6570\u7684\u51fd\u6570\uff0c\u6765\u628a\u53ef\u8fed\u4ee3\u5bf9\u8c61\u8ba1\u7b97\u6210\u5355\u4e00\u7684\u503c\u3002 \u793a\u4f8b\uff1a\u628a\u4e00\u4e2a\u6574\u6570\u5217\u8868\u8f6c\u6362\u6210\u53e6\u4e00\u4e2a\u5305\u542b\u8fd9\u4e9b\u6574\u6570\u7684\u5b57\u7b26\u4e32\u5f62\u5f0f\u7684\u5217\u8868\u3002 \u4f20\u7edf\u65b9\u6cd5\u5b9e\u73b0\uff1a oldList = [ 0 , 1 , 3 , 5 , 7 , 9 ] newList = [] for i in oldList : newList . append ( str ( i )) print ( newList ) # ['0', '1', '3', '5', '7', '9'] \u7528 map \u5b9e\u73b0\uff1a oldList = [ 0 , 1 , 3 , 5 , 7 , 9 ] newList = [] newList = list ( map ( str , oldList )) print ( newList ) # ['0', '1', '3', '5', '7', '9'] \u62d3\u5c55\uff1a\u628a\u4e00\u4e2a\u6574\u6570\u5217\u8868\u4e2d\u7684\u6b63\u6574\u6570\u8f6c\u6362\u6210\u53e6\u4e00\u4e2a\u5305\u542b\u8fd9\u4e9b\u6574\u6570\u7684\u5b57\u7b26\u4e32\u5f62\u5f0f\u7684\u5217\u8868\u3002 \u4f20\u7edf\u5b9e\u73b0\uff1a oldList = [ 0 , 1 , 3 , 5 , 7 , 9 ] newList = [] for i in oldList : if i > 0 : newList . append (( str ( i ))) print ( newList ) # ['1', '3', '5', '7', '9'] \u4f7f\u7528 filter \u5b9e\u73b0\uff1a oldList = [ 0 , 1 , 3 , 5 , 7 , 9 ] newList = [] def isPositive ( n ): if n > 0 : return True # \u521b\u5efa\u4e00\u4e2a\u4e0d\u5305\u542b\u4efb\u4f55\u96f6\u7684\u53ef\u8fed\u4ee3\u5bf9\u8c61 newList = list ( filter ( isPositive , oldList )) print ( newList ) # [1, 3, 5, 7, 9] \u793a\u4f8b\uff1a\u8ba1\u7b97\u4ece1\u523010\u7684\u4e58\u79ef\u5e76\u8f93\u51fa\u7ed3\u679c\u3002 \u901a\u8fc7 for \u5faa\u73af\u5b9e\u73b0\uff1a result = 1 value = 1 for value in range ( 1 , 11 ): result *= value value += 1 print ( result ) # \u8fd0\u884c\u7ed3\u679c # 3628800 \u901a\u8fc7 functools.reduce \u5faa\u73af\u5b9e\u73b0\uff1a import functools result = functools . reduce ( lambda x , y : x * y , range ( 1 , 11 )) print ( result ) # 3628800","title":"1.5.4.\u9ad8\u9636\u51fd\u6570"},{"location":"python/DataStructure/01_PythonFundmantal/#155lambda","text":"\u8bed\u6cd5\u683c\u5f0f\uff1a lambda < argument list > : < expression > lambda\u8868\u8fbe\u5f0f\u4e0d\u80fd\u50cf\u5176\u4ed6Python\u51fd\u6570\u90a3\u6837\u5305\u542b\u4e00\u6574\u4e2a\u8bed\u53e5\u5e8f\u5217\u3002 \u62d3\u5c55\uff1a\u7528lambda\u5b9e\u73b0\u628a\u4e00\u4e2a\u6574\u6570\u5217\u8868\u4e2d\u7684\u6b63\u6574\u6570\u8f6c\u6362\u6210\u53e6\u4e00\u4e2a\u5305\u542b\u8fd9\u4e9b\u6574\u6570\u7684\u5b57\u7b26\u4e32\u5f62\u5f0f\u7684\u5217\u8868\uff0c\u5b9e\u9645\u5c31\u662f\u901a\u8fc7\u4f7f\u7528\u533f\u540d\u7684\u5e03\u5c14\u51fd\u6570\u6765\u4ece\u6574\u6570\u5217\u8868\u91cc\u5254\u9664\u6240\u6709\u4e3a\u96f6\u7684\u5143\u7d20\u3002 oldList = [ 0 , 1 , 3 , 5 , 7 , 9 ] newList = [] newList = list ( filter ( lambda i : i > 0 , oldList )) print ( newList ) # [1, 3, 5, 7, 9]","title":"1.5.5.lambda\u4e0e\u533f\u540d\u51fd\u6570"},{"location":"python/DataStructure/01_PythonFundmantal/#16","text":"\u8003\u8651\u4e24\u79cd\u5f02\u5e38\u60c5\u51b5\uff1a Python\u865a\u62df\u673a\u5728\u7a0b\u5e8f\u6267\u884c\u671f\u95f4\u9047\u5230\u4e86\u8bed\u4e49\u9519\u8bef\uff0c\u5219\u4f1a\u5f97\u5230\u76f8\u5e94\u7684\u9519\u8bef\u6d88\u606f\uff0c\u4ece\u800c\u5f15\u53d1\u4e00\u4e2a\u5f02\u5e38\u5e76\u4e14\u6682\u505c\u7a0b\u5e8f\u3002\u8bed\u4e49\u9519\u8bef\u5305\u62ec\u4f8b\u5982\u672a\u5b9a\u4e49\u7684\u53d8\u91cf\u540d\u3001\u9664\u4ee50\u4ee5\u53ca\u8d85\u51fa\u5217\u8868\u8303\u56f4\u7684\u7d22\u5f15\u7b49\u3002 \u7528\u6237\u5f15\u8d77\u7684\u67d0\u4e9b\u9519\u8bef\uff0c\u4f8b\u5982\uff0c\u671f\u671b\u8f93\u5165\u6570\u5b57\u7684\u65f6\u5019\u8f93\u5165\u4e86\u5176\u4ed6\u5b57\u7b26\u3002\u5bf9\u4e8e\u5728\u8fd9\u4e9b\u60c5\u51b5\u4e0b\u4ea7\u751f\u7684\u5f02\u5e38\uff0c\u7a0b\u5e8f\u4e0d\u5e94\u8be5\u505c\u6b62\u6267\u884c\uff0c\u800c\u5e94\u8be5\u5bf9\u8fd9\u4e9b\u5f02\u5e38\u8fdb\u884c\u6355\u83b7\uff0c\u5e76\u4e14\u5141\u8bb8\u7528\u6237\u4fee\u6b63\u9519\u8bef\u3002 Python\u63d0\u4f9b\u4e86try-except\u8bed\u53e5\uff0c\u53ef\u4ee5\u8ba9\u7a0b\u5e8f\u6355\u83b7\u5f02\u5e38\u5e76\u6267\u884c\u76f8\u5e94\u7684\u6062\u590d\u64cd\u4f5c\u3002 try \u5b50\u53e5\u4e2d\u7684\u8bed\u53e5\u5c06\u5148\u88ab\u6267\u884c\u3002\u5982\u679c\u8fd9\u4e9b\u8bed\u53e5\u4e2d\u7684\u4e00\u6761\u5f15\u53d1\u4e86\u5f02\u5e38\uff0c\u90a3\u4e48\u63a7\u5236\u6743\u4f1a\u7acb\u5373\u8f6c\u79fb\u5230 except \u5b50\u53e5\u53bb\u3002 \u5982\u679c\u5f15\u53d1\u7684\u5f02\u5e38\u7c7b\u578b\u548c\u8fd9\u4e2a\u5b50\u53e5\u91cc\u7684\u7c7b\u578b\u4e00\u81f4\uff0c\u90a3\u4e48\u4f1a\u6267\u884c\u5b83\u91cc\u9762\u7684\u8bed\u53e5\uff1b \u5426\u5219\uff0c\u5c06\u8f6c\u79fb\u5230try-except\u8bed\u53e5\u7684\u8c03\u7528\u8005\uff0c\u5e76\u57fa\u4e8e\u8c03\u7528\u94fe\u5411\u4e0a\u4f20\u9012\uff0c\u76f4\u5230\u8fd9\u4e2a\u5f02\u5e38\u88ab\u6210\u529f\u6355\u83b7\uff0c\u6216\u8005\u662f\u7a0b\u5e8f\u56e0\u9519\u8bef\u6d88\u606f\u800c\u505c\u6b62\u6267\u884c\u3002 \u5982\u679c try \u5b50\u53e5\u91cc\u7684\u8bed\u53e5\u6ca1\u6709\u5f15\u53d1\u4efb\u4f55\u5f02\u5e38\uff0c\u90a3\u4e48\u4f1a\u8df3\u8fc7 except \u5b50\u53e5\u5e76\u7ee7\u7eed\u6267\u884c\uff0c\u76f4\u5230try-except\u8bed\u53e5\u7684\u672b\u5c3e\u3002 try : < statements > except < exception type > : < statements > \u901a\u5e38\u6765\u8bf4\uff0c \u5bf9\u4e8e\u5df2\u77e5\u53ef\u80fd\u4f1a\u53d1\u751f\u7684\u5f02\u5e38\u7c7b\u578b\uff0c\u5e94\u8be5\u5c3d\u53ef\u80fd\u5730\u5305\u62ec\u5728\u5728 except \u8bed\u53e5\u91cc\u3002 \u5982\u679c\u4e0d\u77e5\u9053\u5f02\u5e38\u7684\u7c7b\u578b\uff0c\u53ef\u4ee5\u5728 except \u4e2d\u7528\u66f4\u901a\u7528\u7684Exception\u7c7b\u578b\u5339\u914d\u53ef\u80fd\u4f1a\u5f15\u53d1\u7684\u4efb\u4f55\u5f02\u5e38\u3002 \u793a\u4f8b\uff1a def getYourAge ( prompt ): \"\"\"\u63d0\u793a\u7528\u6237\u8f93\u5165\u4e00\u4e2a\u6574\u6570\uff0c\u5426\u5219\u7ed9\u51fa\u9519\u8bef\u63d0\u793a\uff0c\u5e76\u7ee7\u7eed\u63d0\u793a\u7528\u6237\u8f93\u5165\u3002\"\"\" inputStr = input ( prompt ) try : number = int ( inputStr ) return number except ValueError : print ( \"Error in number format:\" , inputStr ) return getYourAge ( prompt ) if __name__ == \"__main__\" : age = getYourAge ( \"Enter your age: \" ) print ( \"Your age is\" , age ) # \u8fd0\u884c\u7ed3\u679c # Enter your age: 3a # Error in number format: 3a # Enter your age: 3.5 # Error in number format: 3.5 # Enter your age: 20 # Your age is 20","title":"1.6.\u6355\u83b7\u5f02\u5e38"},{"location":"python/DataStructure/01_PythonFundmantal/#17","text":"","title":"1.7.\u6587\u4ef6\u53ca\u5176\u64cd\u4f5c"},{"location":"python/DataStructure/01_PythonFundmantal/#171","text":"\u53ef\u4ee5\u628a\u6587\u672c\u6587\u4ef6\u91cc\u7684\u6570\u636e\u770b\u4f5c\u5b57\u7b26\u3001\u5355\u8bcd\u3001\u6570\u5b57\u6216\u8005\u82e5\u5e72\u884c\u6587\u672c\u3002 \u5982\u679c\u628a\u6587\u672c\u6587\u4ef6\u91cc\u7684\u6570\u636e\u5f53\u4f5c\u6574\u6570\u6216\u6d6e\u70b9\u6570\uff0c\u5c31\u5fc5\u987b\u7528\u7a7a\u767d\u5b57\u7b26\uff08\u7a7a\u683c\u3001\u5236\u8868\u7b26\u548c\u6362\u884c\u7b26\uff09\u5c06\u5176\u5206\u9694\u5f00\u3002\u8f93\u51fa\u6216\u8f93\u5165\u5230\u6587\u672c\u6587\u4ef6\u7684\u6240\u6709\u6570\u636e\u5fc5\u987b\u662f\u5b57\u7b26\u4e32\u5f62\u5f0f\u7684\uff0c\u6240\u4ee5\u5728\u8f93\u5165/\u8f93\u51fa\u65f6\u9700\u8981\u505a\u76f8\u5e94\u7684\u7c7b\u578b\u8f6c\u6362\u3002 \u5982\u4e0b\u4f8b\uff1a 34.6 22.33 66.75 77.12 21.44 99.01 Python\u7684open\u51fd\u6570\u63a5\u6536\u4e0b\u9762\u4e24\u4e2a\u4e3b\u8981\u53c2\u6570\uff0c\u6253\u5f00\u4e00\u4e2a\u4e0e\u78c1\u76d8\u6587\u4ef6\u7684\u8fde\u63a5\u5e76\u4e14\u8fd4\u56de\u76f8\u5e94\u7684\u6587\u4ef6\u5bf9\u8c61\u3002 \u6587\u4ef6\u8def\u5f84\uff1b \u6253\u5f00\u6a21\u5f0f\uff1a \u6253\u5f00\u6a21\u5f0f\uff1a r \u8868\u793a\u6587\u4ef6\u53ea\u80fd\u8bfb\u53d6\uff1b w \u8868\u793a\u6587\u4ef6\u53ea\u80fd\u5199\u5165\uff1b a \u8868\u793a\u6253\u5f00\u6587\u4ef6\uff0c\u5728\u539f\u6709\u5185\u5bb9\u7684\u57fa\u7840\u4e0a\u8ffd\u52a0\u5185\u5bb9\uff0c\u5728\u672b\u5c3e\u5199\u5165\uff1b w+ \u8868\u793a\u53ef\u4ee5\u5bf9\u6587\u4ef6\u8fdb\u884c\u8bfb\u5199\u53cc\u91cd\u64cd\u4f5c\uff1b rb \u4ee5\u4e8c\u8fdb\u5236\u683c\u5f0f\u6253\u5f00\u4e00\u4e2a\u6587\u4ef6\uff0c\u7528\u4e8e\u53ea\u8bfb\uff1b wb \u4ee5\u4e8c\u8fdb\u5236\u683c\u5f0f\u6253\u5f00\u4e00\u4e2a\u6587\u4ef6\uff0c\u7528\u4e8e\u53ea\u5199\uff1b ab \u4ee5\u4e8c\u8fdb\u5236\u683c\u5f0f\u6253\u5f00\u4e00\u4e2a\u6587\u4ef6\uff0c\u7528\u4e8e\u8ffd\u52a0\uff1b wb+ \u4ee5\u4e8c\u8fdb\u5236\u683c\u5f0f\u6253\u5f00\u4e00\u4e2a\u6587\u4ef6\uff0c\u7528\u4e8e\u8bfb\u5199\uff1b \u793a\u4f8b\uff1a \u4e3a myfile.txt \u6587\u4ef6\u6253\u5f00\u4e00\u4e2a\u7528\u6765\u8f93\u51fa\u7684\u6587\u4ef6\u5bf9\u8c61\u3002 \u5b57\u7b26\u4e32\u6570\u636e\u901a\u8fc7 write \u65b9\u6cd5\u548c\u6587\u4ef6\u5bf9\u8c61\u5199\u5165\uff08\u6216\u8f93\u51fa\uff09\u5230\u6587\u4ef6\u91cc\u3002 \u8f6c\u4e49\u7b26 \\n \u5b9e\u73b0\u6362\u884c\u3002 \u4f7f\u7528 close \u65b9\u6cd5\u5173\u95ed\u6587\u4ef6\u3002\u5982\u679c\u6ca1\u6709\u5173\u95ed\u8f93\u51fa\u6587\u4ef6\uff0c\u5219\u53ef\u80fd\u5bfc\u81f4\u6570\u636e\u4e22\u5931\u3002 f = open ( \"./docs/python/DataStructure/code/myfile.txt\" , 'w' ) f . write ( \"First line. \\n Second line. \\n \" ) f . close () \u6587\u4ef6myfile.txt\u7684\u5185\u5bb9\uff1a First line. Second line.","title":"1.7.1.\u6587\u672c\u6587\u4ef6\u8bfb\u53d6"},{"location":"python/DataStructure/01_PythonFundmantal/#172","text":"\u6587\u4ef6\u7684 write \u65b9\u6cd5\u63a5\u6536\u4e00\u4e2a\u5b57\u7b26\u4e32\u4f5c\u4e3a\u53c2\u6570\u3002\u56e0\u6b64\uff0c\u5176\u4ed6\u7c7b\u578b\u7684\u6570\u636e\uff08\u5982\u6574\u6570\u6216\u6d6e\u70b9\u6570\uff09\u5728\u5199\u5165\u8f93\u51fa\u6587\u4ef6\u4e4b\u524d\uff0c\u90fd\u5fc5\u987b\u5148\u88ab\u8f6c\u6362\u4e3a\u5b57\u7b26\u4e32\u3002 \u5728Python\u91cc\uff0c\u53ef\u4ee5\u4f7f\u7528 str \u51fd\u6570\u628a\u7edd\u5927\u591a\u6570\u7684\u6570\u636e\u7c7b\u578b\u7684\u503c\u8f6c\u6362\u4e3a\u5b57\u7b26\u4e32\uff0c\u4ee5\u7a7a\u683c\u6216\u6362\u884c\u7b26\u4f5c\u4e3a\u5206\u9694\u7b26\uff0c\u5c06\u5176\u5199\u5165\u6587\u4ef6\u91cc\u3002 \u793a\u4f8b\uff1a\u751f\u6210500\u4e2a\u4ecb\u4e8e1\u548c500\u4e4b\u95f4\u7684\u968f\u673a\u6570\uff0c\u5e76\u8f93\u51fa\u5230\u6587\u672c\u6587\u4ef6\u3002 import random f = open ( \"./docs/python/DataStructure/code/myfile.txt\" , 'w' ) for count in range ( 500 ): number = random . randint ( 1 , 500 ) f . write ( str ( number ) + \" \\n \" ) f . close ()","title":"1.7.2.\u6587\u672c\u6587\u4ef6\u5199\u5165"},{"location":"python/DataStructure/01_PythonFundmantal/#173","text":"\u793a\u4f8b\uff1a\u8bfb\u53d6\u6587\u4ef6\u5185\u5bb9\u3002 import random f = open ( \"./docs/python/DataStructure/code/myfile.txt\" , 'w' ) f . write ( \"First line. \\n Second line. \\n \" ) # \u521d\u59cb\u5316\u6587\u4ef6\u5185\u5bb9 f . close () # \u6253\u5f00\u6587\u4ef6\u8bfb\u53d6\u5185\u5bb9 f = open ( \"./docs/python/DataStructure/code/myfile.txt\" , 'r' ) text1 = f . read () # \u628a\u6587\u4ef6\u7684\u5168\u90e8\u5185\u5bb9\u8f93\u5165\u5355\u4e2a\u5b57\u7b26\u4e32\u4e2d print ( text1 ) # \u8fd0\u884c\u7ed3\u679c\uff1a # First line. # Second line text2 = f . read () # \u518d\u6b21read\uff0c\u5f97\u5230\u4e00\u4e2a\u7a7a\u5b57\u4e32\uff0c\u8868\u8ff0\u5df2\u7ecf\u5230\u8fbe\u6587\u4ef6\u672b\u5c3e\u3002\u8981\u518d\u6b21\u8bfb\u53d6\u9700\u8981\u91cd\u65b0\u6253\u5f00\u6587\u4ef6 print ( \"======\" ) print ( text2 ) # \u8fd0\u884c\u7ed3\u679c\uff1a # ====== # f . close () # \u91cd\u65b0\u6253\u5f00\u6587\u4ef6\u8bfb\u53d6\u5185\u5bb9 f = open ( \"./docs/python/DataStructure/code/myfile.txt\" , 'r' ) for line in f : # \u9010\u884c\u8bfb\u53d6\u6587\u4ef6\u5185\u5bb9 print ( \"======\" ) print ( line ) # \u6bcf\u884c\u90fd\u6709\u4e00\u4e2a\u6362\u884c\u7b26\uff0c\u8fd9\u662fprint\u51fd\u6570\u9ed8\u8ba4\u884c\u4e3a # \u8fd0\u884c\u7ed3\u679c\uff1a # ====== # First line. # ====== # Second line. # f . close () # \u91cd\u65b0\u6253\u5f00\u6587\u4ef6\u8bfb\u53d6\u5185\u5bb9 f = open ( \"./docs/python/DataStructure/code/myfile.txt\" , 'r' ) while True : line = f . readline () # readline\u65b9\u6cd5\u4f1a\u4ece\u8f93\u5165\u7684\u6587\u672c\u91cc\u53ea\u83b7\u53d6\u4e00\u884c\u6570\u636e\uff0c\u5e76\u4e14\u8fd4\u56de\u8fd9\u4e2a\u5305\u542b\u6362\u884c\u7b26\u7684\u5b57\u7b26\u4e32\u3002\u5982\u679creadline\u9047\u5230\u4e86\u6587\u4ef6\u672b\u5c3e\uff0c\u90a3\u4e48\u4f1a\u8fd4\u56de\u7a7a\u5b57\u7b26\u4e32\u3002 if line == \"\" : break print ( \"******\" ) print ( line ) # \u8fd0\u884c\u7ed3\u679c\uff1a # ****** # First line. # ****** # Second line. # f . close () # \u91cd\u65b0\u6253\u5f00\u6587\u4ef6\u8bfb\u53d6\u5185\u5bb9 f = open ( \"./docs/python/DataStructure/code/myfile.txt\" , 'r' ) line = f . readlines () # readlines\u65b9\u6cd5\u5219\u662f\u8bfb\u53d6\u6240\u6709\u884c\uff0c\u8fd4\u56de\u7684\u662f\u6240\u6709\u884c\u7ec4\u6210\u7684\u5217\u8868\u3002 print ( line ) # \u8fd0\u884c\u7ed3\u679c\uff1a # ['First line.\\n', 'Second line.\\n'] f . close ()","title":"1.7.3.\u4ece\u6587\u672c\u6587\u4ef6\u8bfb\u53d6\u6570\u636e"},{"location":"python/DataStructure/01_PythonFundmantal/#174","text":"\u793a\u4f8b\uff1a\u8bfb\u53d6\u6587\u4ef6\u4e2d\u7684\u6574\u6570\uff0c\u6bcf\u884c\u53ea\u6709\u4e00\u4e2a\u6574\u6570\u3002 import random f = open ( \"./docs/python/DataStructure/code/myfile.txt\" , 'w' ) # \u751f\u62100~9\u6574\u6570\uff0c\u5e76\u5199\u5165\u6587\u4ef6 for count in range ( 10 ): f . write ( str ( count ) + \" \\n \" ) f . close () # \u6253\u5f00\u6587\u4ef6 f = open ( \"./docs/python/DataStructure/code/myfile.txt\" , 'r' ) # \u4f9d\u6b21\u8bfb\u53d6\u6587\u4ef6\u4e2d\u7684\u6570\u5b57\uff0c\u5e76\u6c42\u548c theSum = 0 for line in f : line = line . strip () number = int ( line ) theSum += number print ( \"The sum is : \" , theSum ) # \u8fd0\u884c\u7ed3\u679c\uff1a # The sum is : 45 f . close () \u793a\u4f8b\uff1a\u8bfb\u53d6\u6587\u4ef6\u4e2d\u7684\u6574\u6570\uff0c\u6bcf\u884c\u6709\u591a\u4e2a\u6574\u6570\u3002\u9700\u8981\u4e8b\u5148\u628a\u4e0b\u9762\u7684\u5185\u5bb9\u5199\u5165 myfile.txt \u6587\u4ef6\u4e2d\u3002 \u6587\u4ef6 myfile.txt \u7684\u5185\u5bb9\u3002 1 3 5 7 9 2 4 6 8 10 31 200 3000 50000 import random # \u6253\u5f00\u6587\u4ef6 f = open ( \"./docs/python/DataStructure/code/myfile.txt\" , 'r' ) # \u4f9d\u6b21\u8bfb\u53d6\u6587\u4ef6\u4e2d\u7684\u6570\u5b57\uff0c\u5e76\u6c42\u548c theSum = 0 for line in f : lines = line . split () # split\u65b9\u6cd5\u4f1a\u81ea\u52a8\u5904\u7406\u6362\u884c\u7b26 for word in lines : number = int ( word ) theSum += number print ( \"The sum is : \" , theSum ) # \u8fd0\u884c\u7ed3\u679c\uff1a # The sum is : 53286 f . close () \u7b80\u5199\u4e0a\u9762\u7684\u4ee3\u7801\u3002 import random f = open ( \"./docs/python/DataStructure/code/myfile.txt\" , 'r' ) print ( \"The sum is: \" , sum ( map ( int , f . read () . split ()))) # \u8fd0\u884c\u7ed3\u679c\uff1a # The sum is : 53286 f . close ()","title":"1.7.4.\u4ece\u5176\u5b83\u6587\u4ef6\u8bfb\u53d6\u6570\u636e"},{"location":"python/DataStructure/01_PythonFundmantal/#175pickle","text":"\u5728\u628a\u4efb\u4f55\u5bf9\u8c61\u4fdd\u5b58\u5230\u6587\u4ef6\u4e4b\u524d\uff0c\u6211\u4eec\u53ef\u4ee5\u5bf9\u5b83\u8fdb\u884c\u201c\u814c\u5236\u201d\uff1b\u5728\u628a\u5bf9\u8c61\u4ece\u6587\u4ef6\u52a0\u8f7d\u5230\u7a0b\u5e8f\u4e2d\u65f6\uff0c\u4e5f\u53ef\u4ee5\u5bf9\u5b83\u8fdb\u884c\u201c\u53cd\u814c\u5236\u201d\u3002 \u793a\u4f8b\uff1a \u4f7f\u7528pickle\u6a21\u5757\u7684 pickle.dump \u628a\u540d\u4e3alyst\u7684\u5217\u8868\u91cc\u7684\u6240\u6709\u5bf9\u8c61\u4fdd\u5b58\u5230\u540d\u4e3aitems.dat\u7684\u6587\u4ef6\u91cc\uff08\u201c\u814c\u5236\u201d\uff09\u3002\u6211\u4eec\u4e0d\u9700\u8981\u77e5\u9053\u5217\u8868\u91cc\u6709\u54ea\u4e9b\u7c7b\u578b\u7684\u5bf9\u8c61\uff0c\u4e5f\u4e0d\u9700\u8981\u77e5\u9053\u6709\u591a\u5c11\u4e2a\u5bf9\u8c61\u3002 import pickle myList = [ 60 , \"A string object\" , 1977 ] fObj = open ( \"./docs/python/DataStructure/code/items.dat\" , \"wb\" ) for item in myList : pickle . dump ( item , fObj ) fObj . close () \u4f7f\u7528pickle\u6a21\u5757\u7684 pickle.load \u628aitems.dat\u7684\u6587\u4ef6\u5185\u5bb9\u52a0\u8f7d\u56de\u7a0b\u5e8f\uff08\u201c\u53cd\u814c\u5236\u201d\uff09\u3002 import pickle lyst = list () fileObj = open ( \"./docs/python/DataStructure/code/items.dat\" , \"rb\" ) while True : try : item = pickle . load ( fileObj ) lyst . append ( item ) except EOFError : # \u68c0\u6d4b\u5df2\u7ecf\u5230\u8fbe\u6587\u4ef6\u672b\u5c3e fileObj . close () break print ( lyst ) # \u8fd0\u884c\u7ed3\u679c\uff1a # [60, 'A string object', 1977]","title":"1.7.5.\u4f7f\u7528pickle\u8bfb\u5199\u5bf9\u8c61"},{"location":"python/DataStructure/01_PythonFundmantal/#18","text":"\u7c7b\uff08class\uff09\u7528\u6765\u63cf\u8ff0\u4e0e\u4e00\u7ec4\u5bf9\u8c61\u6709\u5173\u7684\u6570\u636e\u548c\u65b9\u6cd5\u3002\u5b83\u63d0\u4f9b\u4e86\u7528\u6765\u521b\u5efa\u5bf9\u8c61\u7684\u84dd\u56fe\uff0c\u4ee5\u53ca\u5728\u5bf9\u8c61\u4e0a\u8c03\u7528\u65b9\u6cd5\u65f6\u6240\u9700\u8981\u6267\u884c\u7684\u4ee3\u7801\u3002 Python\u91cc\u7684\u6570\u636e\u7c7b\u578b\u90fd\u662f\u7c7b\uff1b \u7c7b\u540d\u6309\u7167\u60ef\u4f8b\u9996\u5b57\u6bcd\u5e94\u4e3a\u5927\u5199\u6837\u5f0f\uff1b \u5b9a\u4e49\u7c7b\u7684\u4ee3\u7801\u901a\u5e38\u4f1a\u88ab\u5b58\u653e\u5728\u9996\u5b57\u6bcd\u5c0f\u5199\u7684\u7c7b\u540d\u7684\u6a21\u5757\u6587\u4ef6\u91cc\u3002 \u76f8\u5173\u7684\u7c7b\u4e5f\u53ef\u80fd\u4f1a\u51fa\u73b0\u5728\u540c\u4e00\u4e2a\u6a21\u5757\u91cc\u3002 \u7c7b\u7684\u8bed\u6cd5\uff1a def < class name > ( < parent class name > )[ 2 ]: < class variable assignments > < instance method definitions > \u7236\u7c7b\uff08parent class\uff09\u7684\u540d\u79f0\u662f\u53ef\u9009\u7684\uff0c\u5728\u9ed8\u8ba4\u60c5\u51b5\u4e0b\uff0c\u5b83\u4f1a\u662fobject\u3002 \u6240\u6709Python\u7c7b\u5c5e\u4e8e\u4e00\u4e2a\u4ee5 object \u4f5c\u4e3a\u6839\u8282\u70b9\u7684\u5c42\u6b21\u7ed3\u6784\u3002 \u5728 object \u91cc\uff0cPython\u5b9a\u4e49\u4e86\u51e0\u79cd\u65b9\u6cd5\uff1a __str__ \u548c __eq__ \uff0c\u56e0\u6b64\u6240\u6709\u5b50\u7c7b\u4f1a\u81ea\u52a8\u7ee7\u627f\u8fd9\u4e9b\u65b9\u6cd5\u3002 \u5b9e\u4f8b\u65b9\u6cd5\uff08instance method\uff09\u662f\u5728\u7c7b\u7684\u5bf9\u8c61\u4e0a\u8fd0\u884c\u7684\u3002\u5b83\u4eec\u5305\u542b\u7528\u6765\u8bbf\u95ee\u6216\u4fee\u6539\u5b9e\u4f8b\u53d8\u91cf\u7684\u4ee3\u7801\u3002 \u5b9e\u4f8b\u53d8\u91cf\uff08instance variable\uff09\u662f\u6307\u7531\u5355\u4e2a\u5bf9\u8c61\u6240\u62e5\u6709\u7684\u5b58\u50a8\u4fe1\u606f\u3002 \u7c7b\u53d8\u91cf\uff08class variable\uff09\u662f\u6307\u7531\u7c7b\u7684\u6240\u6709\u5bf9\u8c61\u5b58\u50a8\u6240\u6709\u7684\u4fe1\u606f\u3002 \u793a\u4f8b\uff1a\u89e3\u8bfbCounter\u7c7b\u3002 Counter \u7c7b\u662f object \u7684\u5b50\u7c7b\uff1b instances \u662f\u7c7b\u53d8\u91cf\uff0c\u8ddf\u8e2a\u5df2\u521b\u5efa\u7684\u8ba1\u6570\u5668\u5bf9\u8c61\u7684\u6570\u91cf\uff1b \u5b9e\u4f8b\u65b9\u6cd5 __init__ \u4e5f\u79f0\u4e3a\u6784\u9020\u51fd\u6570\uff1b\u8fd9\u4e2a\u65b9\u6cd5\u7528\u6765\u521d\u59cb\u5316\u5b9e\u4f8b\u53d8\u91cf\uff0c\u5e76\u4e14\u5bf9\u7c7b\u53d8\u91cf\u8fdb\u884c\u66f4\u65b0\uff1b self \u662f\u6307\u5728\u8fd0\u884c\u65f6\u8fd9\u4e2a\u65b9\u6cd5\u7684\u5bf9\u8c61\u672c\u8eab\uff1b \u4f7f\u7528\u5b9e\u4f8b\u53d8\u91cf\u90fd\u4f1a\u52a0\u4e0a\u524d\u7f00 self \uff1b\u548c\u53c2\u6570\u6216\u4e34\u65f6\u53d8\u91cf\u4e0d\u540c\u7684\u5730\u65b9\u662f\uff0c\u5b9e\u4f8b\u53d8\u91cf\u5728\u7c7b\u7684\u4efb\u4f55\u65b9\u6cd5\u91cc\u662f\u53ef\u89c1\u7684\uff1b \u5176\u4ed6\u5b9e\u4f8b\u65b9\u6cd5\u53ef\u4ee5\u5206\u4e3a\u4e24\u79cd\uff1a\u53d8\u5f02\u5668\uff08mutator\uff09\u548c\u8bbf\u95ee\u5668\uff08accessor\uff09\u3002\u53d8\u5f02\u5668\u4f1a\u901a\u8fc7\u4fee\u6539\u5bf9\u8c61\u7684\u5b9e\u4f8b\u53d8\u91cf\u5bf9\u5176\u5185\u90e8\u72b6\u6001\u8fdb\u884c\u4fee\u6539\u6216\u66f4\u6539\u3002\u8bbf\u95ee\u5668\u5219\u53ea\u4f1a\u67e5\u770b\u6216\u4f7f\u7528\u5bf9\u8c61\u7684\u5b9e\u4f8b\u53d8\u91cf\u7684\u503c\uff0c\u800c\u4e0d\u4f1a\u53bb\u4fee\u6539\u5b83\u4eec\uff1b __str__ \u65b9\u6cd5\u5c06\u8986\u76d6object\u7c7b\u91cc\u7684\u8fd9\u4e2a\u65b9\u6cd5\uff1b \u5f53Python\u7684 print \u51fd\u6570\u63a5\u6536\u5230\u4e00\u4e2a\u53c2\u6570\u65f6\uff0c\u8fd9\u4e2a\u53c2\u6570\u7684 __str__ \u65b9\u6cd5\u5c06\u81ea\u52a8\u8fd0\u884c\uff0c\u4ece\u800c\u5f97\u5230\u5b83\u7684\u5b57\u7b26\u4e32\u8868\u8fbe\u5f0f\uff0c\u4ee5\u4fbf\u7528\u6765\u8f93\u51fa\uff1b \u5f53\u770b\u5230 == \u8fd0\u7b97\u7b26\u65f6\uff0cPython\u5c06\u8fd0\u884c __eq__ \u65b9\u6cd5\uff1b\u5728 object \u7c7b\u91cc\uff0c\u8fd9\u4e2a\u65b9\u6cd5\u7684\u9ed8\u8ba4\u5b9a\u4e49\u662f\u8fd0\u884c is \u8fd0\u7b97\u7b26\u3002 class Counter ( object ): # Counter\u7c7b\u662fobject\u7684\u5b50\u7c7b \"\"\"Models a counter.\"\"\" # Class variable \u7c7b\u53d8\u91cf instances = 0 # \u8ddf\u8e2a\u5df2\u521b\u5efa\u7684\u8ba1\u6570\u5668\u5bf9\u8c61\u7684\u6570\u91cf # Constructor \u6784\u9020\u5668 # \u5b9e\u4f8b\u65b9\u6cd5__init__\u4e5f\u79f0\u4e3a\u6784\u9020\u51fd\u6570\uff1b\u8fd9\u4e2a\u65b9\u6cd5\u7528\u6765\u521d\u59cb\u5316\u5b9e\u4f8b\u53d8\u91cf\uff0c\u5e76\u4e14\u5bf9\u7c7b\u53d8\u91cf\u8fdb\u884c\u66f4\u65b0\uff1b def __init__ ( self ): # self\u662f\u6307\u5728\u8fd0\u884c\u65f6\u8fd9\u4e2a\u65b9\u6cd5\u7684\u5bf9\u8c61\u672c\u8eab \"\"\"Sets up the counter.\"\"\" Counter . instances += 1 self . reset () # Mutator methods def reset ( self ): \"\"\"Sets the counter to 0.\"\"\" self . value = 0 def increment ( self , amount = 1 ): \"\"\"Adds amount to the counter.\"\"\" self . value += amount def decrement ( self , amount = 1 ): \"\"\"Subtracts amount from the counter.\"\"\" self . value -= amount # Accessor methods def getValue ( self ): \"\"\"Returns the counter's value.\"\"\" return self . value def __str__ ( self ): \"\"\"Returns the string representation of the counter.\"\"\" return str ( self . value ) def __eq__ ( self , other ): \"\"\"Returns True if self equals other or False otherwise.\"\"\" if self is other : return True if type ( self ) != type ( other ): return False return self . value == other . value c1 = Counter () print ( c1 ) # \u8fd0\u884c\u7ed3\u679c\uff1a # 0 c1 . getValue () str ( c1 ) c1 . increment () print ( c1 ) # \u8fd0\u884c\u7ed3\u679c\uff1a # 1 c1 . increment ( 5 ) print ( c1 ) # \u8fd0\u884c\u7ed3\u679c\uff1a # 6 c1 . reset () print ( c1 ) # \u8fd0\u884c\u7ed3\u679c\uff1a # 0 c2 = Counter () print ( Counter . instances ) # \u8fd0\u884c\u7ed3\u679c\uff1a # 2 print ( c1 == c1 ) # \u8fd0\u884c\u7ed3\u679c\uff1a # True print ( c1 == 0 ) # \u8fd0\u884c\u7ed3\u679c\uff1a # False print ( c1 == c2 ) # \u8fd0\u884c\u7ed3\u679c\uff1a # True c2 . increment () print ( c1 == c2 ) # \u8fd0\u884c\u7ed3\u679c\uff1a # False","title":"1.8.\u521b\u5efa\u7c7b"},{"location":"python/DataStructure/01_PythonFundmantal/#19","text":"1\uff0e\u7f16\u5199\u4e00\u4e2a\u7a0b\u5e8f\uff0c\u4f7f\u4e4b\u80fd\u591f\u63a5\u6536\u7403\u4f53\u7684\u534a\u5f84\uff08\u6d6e\u70b9\u6570\uff09\uff0c\u5e76\u4e14\u53ef\u4ee5\u8f93\u51fa\u7403\u4f53\u7684\u76f4\u5f84\u3001\u5468\u957f\u3001\u8868\u9762\u79ef\u4ee5\u53ca\u4f53\u79ef\u3002 \u89e3\u7b54\uff1a PAI = 3.14 radius = float ( input ( \"\u8f93\u5165\u7403\u534a\u5f84\uff1a\" )) diameter = radius * 2 circumference = 2 * PAI * radius surfaceArea = 4 * PAI * radius ** 2 sphereVolume = 4 * ( PAI * radius ** 3 ) / 3 print ( \"\u7403\u534a\u5f84\uff1a\" , radius , \"\u7403\u76f4\u5f84\uff1a\" , diameter , \"\u7403\u8868\u9762\u79ef\uff1a\" , surfaceArea , \"\u7403\u4f53\u79ef\uff1a\" , sphereVolume ) # \u8fd0\u884c\u7ed3\u679c\uff1a # \u8f93\u5165\u7403\u534a\u5f84\uff1a3.5 # \u7403\u534a\u5f84\uff1a 3.5 \u7403\u76f4\u5f84\uff1a 7.0 \u7403\u8868\u9762\u79ef\uff1a 153.86 \u7403\u4f53\u79ef\uff1a 179.50333333333333 import math def main (): try : radius = float ( input ( \"\u8bf7\u8f93\u5165\u7403\u534a\u5f84\uff1a\" )) if radius <= 0 : print ( \"\u534a\u5f84\u5fc5\u987b\u4e3a\u6b63\u6570\uff01\" ) return diameter = 2 * radius circumference = 2 * math . pi * radius surfaceArea = 4 * math . pi * radius ** 2 volume = ( 4 / 3 ) * math . pi * radius ** 3 print ( f \"\u7403\u4f53\u7684\u76f4\u5f84\uff1a { diameter : .2f } \" ) print ( f \"\u7403\u4f53\u7684\u5468\u957f\uff1a { circumference : .2f } \" ) print ( f \"\u7403\u4f53\u7684\u8868\u9762\u79ef\uff1a { surfaceArea : .2f } \" ) print ( f \"\u7403\u4f53\u7684\u4f53\u79ef\uff1a { volume : .2f } \" ) except ValueError : print ( \"\u8bf7\u8f93\u5165\u6709\u6548\u7684\u6570\u5b57\uff01\" ) if __name__ == \"__main__\" : main () # \u8fd0\u884c\u7ed3\u679c\uff1a # \u8bf7\u8f93\u5165\u7403\u534a\u5f84\uff1a3.5 # \u7403\u4f53\u7684\u76f4\u5f84\uff1a7.00 # \u7403\u4f53\u7684\u5468\u957f\uff1a21.99 # \u7403\u4f53\u7684\u8868\u9762\u79ef\uff1a153.94 # \u7403\u4f53\u7684\u4f53\u79ef\uff1a179.59 import math class Sphere : def __init__ ( self , radius ): self . radius = radius def diameter ( self ): return 2 * self . radius def circumference ( self ): return 2 * math . pi * self . radius def surfaceArea ( self ): return 4 * math . pi * self . radius ** 2 def volume ( self ): return ( 4 / 3 ) * math . pi * self . radius ** 3 def main (): try : radius = float ( input ( \"\u8bf7\u8f93\u5165\u7403\u4f53\u7684\u534a\u5f84\uff1a\" )) if radius <= 0 : print ( \"\u534a\u5f84\u5fc5\u987b\u4e3a\u6b63\u6570\uff01\" ) return sphere = Sphere ( radius ) print ( f \"\u7403\u4f53\u7684\u76f4\u5f84\uff1a { sphere . diameter () : .2f } \" ) print ( f \"\u7403\u4f53\u7684\u5468\u957f\uff1a { sphere . circumference () : .2f } \" ) print ( f \"\u7403\u4f53\u7684\u8868\u9762\u79ef\uff1a { sphere . surfaceArea () : .2f } \" ) print ( f \"\u7403\u4f53\u7684\u4f53\u79ef\uff1a { sphere . volume () : .2f } \" ) except ValueError : print ( \"\u8bf7\u8f93\u5165\u6709\u6548\u7684\u6570\u5b57\uff01\" ) if __name__ == \"__main__\" : main () # \u8fd0\u884c\u7ed3\u679c\uff1a # \u8bf7\u8f93\u5165\u7403\u4f53\u7684\u534a\u5f84\uff1a3.5 # \u7403\u4f53\u7684\u76f4\u5f84\uff1a7.00 # \u7403\u4f53\u7684\u5468\u957f\uff1a21.99 # \u7403\u4f53\u7684\u8868\u9762\u79ef\uff1a153.94 # \u7403\u4f53\u7684\u4f53\u79ef\uff1a179.59 2\uff0e\u5458\u5de5\u7684\u5468\u5de5\u8d44\u7b49\u4e8e\u5c0f\u65f6\u5de5\u8d44\u4e58\u4ee5\u6b63\u5e38\u7684\u603b\u5de5\u4f5c\u65f6\u95f4\u518d\u52a0\u4e0a\u52a0\u73ed\u5de5\u8d44\u3002\u52a0\u73ed\u5de5\u8d44\u7b49\u4e8e\u603b\u52a0\u73ed\u65f6\u95f4\u4e58\u4ee5\u5c0f\u65f6\u5de5\u8d44\u76841.5\u500d\u3002\u7f16\u5199\u4e00\u4e2a\u7a0b\u5e8f\uff0c\u8ba9\u7528\u6237\u53ef\u4ee5\u8f93\u5165\u5c0f\u65f6\u5de5\u8d44\u3001\u6b63\u5e38\u7684\u603b\u5de5\u4f5c\u65f6\u95f4\u4ee5\u53ca\u52a0\u73ed\u603b\u65f6\u95f4\uff0c\u7136\u540e\u663e\u793a\u51fa\u5458\u5de5\u7684\u5468\u5de5\u8d44\u3002 \u89e3\u7b54\uff1a hourSalary = float ( input ( \"\u8f93\u5165\u5c0f\u65f6\u5de5\u8d44\uff08\u5143\uff09\uff1a\" )) totalWorkingHours = float ( input ( \"\u8f93\u5165\u672c\u5468\u6b63\u5e38\u603b\u5de5\u4f5c\u65f6\u95f4\uff08\u5c0f\u65f6\uff09\uff1a\" )) totalOvertimeHours = float ( input ( \"\u8f93\u5165\u672c\u5468\u603b\u52a0\u73ed\u603b\u5de5\u4f5c\u65f6\u95f4\uff08\u5c0f\u65f6\uff09\uff1a\" )) weeklySalary = hourSalary * totalWorkingHours + hourSalary * totalOvertimeHours * 1.5 print ( \"\u5458\u5de5\u7684\u5468\u5de5\u8d44\uff08\u5143\uff09\u662f\uff1a\" , weeklySalary ) # \u8fd0\u884c\u7ed3\u679c\uff1a # \u8f93\u5165\u5c0f\u65f6\u5de5\u8d44\uff08\u5143\uff09\uff1a20 # \u8f93\u5165\u672c\u5468\u6b63\u5e38\u603b\u5de5\u4f5c\u65f6\u95f4\uff08\u5c0f\u65f6\uff09\uff1a40 # \u8f93\u5165\u672c\u5468\u603b\u52a0\u73ed\u603b\u5de5\u4f5c\u65f6\u95f4\uff08\u5c0f\u65f6\uff09\uff1a10 # \u5458\u5de5\u7684\u5468\u5de5\u8d44\uff08\u5143\uff09\u662f\uff1a 1100.0 def calculate_weekly_salary ( hourly_wage , normal_hours , overtime_hours ): overtime_pay = overtime_hours * hourly_wage * 1.5 normal_pay = normal_hours * hourly_wage weekly_salary = normal_pay + overtime_pay return weekly_salary def main (): try : hourly_wage = float ( input ( \"\u8bf7\u8f93\u5165\u5c0f\u65f6\u5de5\u8d44\uff1a\" )) normal_hours = float ( input ( \"\u8bf7\u8f93\u5165\u6b63\u5e38\u7684\u603b\u5de5\u4f5c\u65f6\u95f4\uff08\u5c0f\u65f6\uff09\uff1a\" )) overtime_hours = float ( input ( \"\u8bf7\u8f93\u5165\u52a0\u73ed\u603b\u65f6\u95f4\uff08\u5c0f\u65f6\uff09\uff1a\" )) weekly_salary = calculate_weekly_salary ( hourly_wage , normal_hours , overtime_hours ) print ( f \"\u5458\u5de5\u7684\u5468\u5de5\u8d44\u4e3a\uff1a { weekly_salary : .2f } \" ) except ValueError : print ( \"\u8bf7\u8f93\u5165\u6709\u6548\u7684\u6570\u5b57\uff01\" ) if __name__ == \"__main__\" : main () # \u8fd0\u884c\u7ed3\u679c\uff1a # \u8bf7\u8f93\u5165\u5c0f\u65f6\u5de5\u8d44\uff1a20 # \u8bf7\u8f93\u5165\u6b63\u5e38\u7684\u603b\u5de5\u4f5c\u65f6\u95f4\uff08\u5c0f\u65f6\uff09\uff1a40 # \u8bf7\u8f93\u5165\u52a0\u73ed\u603b\u65f6\u95f4\uff08\u5c0f\u65f6\uff09\uff1a10 # \u5458\u5de5\u7684\u5468\u5de5\u8d44\u4e3a\uff1a1100.00 class Employee : def __init__ ( self , hourly_wage , normal_hours , overtime_hours ): self . hourly_wage = hourly_wage self . normal_hours = normal_hours self . overtime_hours = overtime_hours def calculate_weekly_salary ( self ): overtime_pay = self . overtime_hours * self . hourly_wage * 1.5 normal_pay = self . normal_hours * self . hourly_wage weekly_salary = normal_pay + overtime_pay return weekly_salary def main (): try : hourly_wage = float ( input ( \"\u8bf7\u8f93\u5165\u5c0f\u65f6\u5de5\u8d44\uff1a\" )) normal_hours = float ( input ( \"\u8bf7\u8f93\u5165\u6b63\u5e38\u7684\u603b\u5de5\u4f5c\u65f6\u95f4\uff08\u5c0f\u65f6\uff09\uff1a\" )) overtime_hours = float ( input ( \"\u8bf7\u8f93\u5165\u52a0\u73ed\u603b\u65f6\u95f4\uff08\u5c0f\u65f6\uff09\uff1a\" )) employee = Employee ( hourly_wage , normal_hours , overtime_hours ) weekly_salary = employee . calculate_weekly_salary () print ( f \"\u5458\u5de5\u7684\u5468\u5de5\u8d44\u4e3a\uff1a { weekly_salary : .2f } \" ) except ValueError : print ( \"\u8bf7\u8f93\u5165\u6709\u6548\u7684\u6570\u5b57\uff01\" ) if __name__ == \"__main__\" : main () # \u8fd0\u884c\u7ed3\u679c\uff1a # \u8bf7\u8f93\u5165\u5c0f\u65f6\u5de5\u8d44\uff1a20 # \u8bf7\u8f93\u5165\u6b63\u5e38\u7684\u603b\u5de5\u4f5c\u65f6\u95f4\uff08\u5c0f\u65f6\uff09\uff1a40 # \u8bf7\u8f93\u5165\u52a0\u73ed\u603b\u65f6\u95f4\uff08\u5c0f\u65f6\uff09\uff1a10 # \u5458\u5de5\u7684\u5468\u5de5\u8d44\u4e3a\uff1a1100.00 3\uff0e\u6709\u4e00\u4e2a\u6807\u51c6\u7684\u79d1\u5b66\u5b9e\u9a8c\uff1a\u6254\u4e00\u4e2a\u7403\uff0c\u770b\u770b\u5b83\u80fd\u53cd\u5f39\u591a\u9ad8\u3002\u4e00\u65e6\u786e\u5b9a\u4e86\u7403\u7684\u201c\u53cd\u5f39\u9ad8\u5ea6\u201d\uff0c\u8fd9\u4e2a\u6bd4\u503c\u5c31\u7ed9\u51fa\u4e86\u76f8\u5e94\u7684\u53cd\u5f39\u5ea6\u6307\u6570\u3002\u4f8b\u5982\uff0c\u5982\u679c\u4ece10ft\uff081ft=0.3048m\uff09\u9ad8\u5904\u6389\u843d\u7684\u7403\u53ef\u4ee5\u53cd\u5f39\u52306 ft\u9ad8\uff0c\u90a3\u4e48\u76f8\u5e94\u7684\u53cd\u5f39\u5ea6\u6307\u6570\u5c31\u662f0.6\uff1b\u5728\u4e00\u6b21\u53cd\u5f39\u4e4b\u540e\uff0c\u7403\u7684\u603b\u884c\u8fdb\u8ddd\u79bb\u662f16 ft\u3002\u63a5\u4e0b\u6765\uff0c\u7403\u7ee7\u7eed\u5f39\u8df3\uff0c\u90a3\u4e48\u4e24\u6b21\u5f39\u8df3\u540e\u7684\u603b\u8ddd\u79bb\u5e94\u8be5\u662f\uff1a10 ft + 6 ft + 6 ft + 3.6 ft = 25.6 ft\u3002\u53ef\u4ee5\u770b\u5230\uff0c\u6bcf\u6b21\u8fde\u7eed\u5f39\u8df3\u6240\u7ecf\u8fc7\u7684\u8ddd\u79bb\u662f\uff1a\u7403\u5230\u5730\u9762\u7684\u8ddd\u79bb\uff0c\u52a0\u4e0a\u8fd9\u4e2a\u8ddd\u79bb\u4e58\u4ee5 0.6\uff0c\u8fd9\u65f6\u7403\u53c8\u5f39\u56de\u6765\u4e86\u3002\u7f16\u5199\u4e00\u4e2a\u7a0b\u5e8f\uff0c\u53ef\u4ee5\u8ba9\u7528\u6237\u8f93\u5165\u7403\u7684\u521d\u59cb\u9ad8\u5ea6\u548c\u5141\u8bb8\u7403\u5f39\u8df3\u7684\u6b21\u6570\uff0c\u5e76\u8f93\u51fa\u7403\u6240\u7ecf\u8fc7\u7684\u603b\u8ddd\u79bb\u3002 \u89e3\u7b54\uff1a height = float ( input ( \"\u8f93\u5165\u5c0f\u7403\u521d\u59cb\u9ad8\u5ea6\uff08ft\uff09\uff1a\" )) times = float ( input ( \"\u8f93\u5165\u5141\u8bb8\u5c0f\u7403\u5f39\u8df3\u6b21\u6570\uff1a\" )) distance = 0 traceDistance = 0 while times : distance = height + 0.6 * height traceDistance += distance height = 0.6 * height times -= 1 print ( \"\u5c0f\u7403\u7ecf\u8fc7\u7684\u603b\u8ddd\u79bb\uff08ft\uff09\uff1a\" , traceDistance ) # \u8fd0\u884c\u7ed3\u679c\uff1a # \u8f93\u5165\u5c0f\u7403\u521d\u59cb\u9ad8\u5ea6\uff08ft\uff09\uff1a50 # \u8f93\u5165\u5141\u8bb8\u5c0f\u7403\u5f39\u8df3\u6b21\u6570\uff1a5 # \u5c0f\u7403\u7ecf\u8fc7\u7684\u603b\u8ddd\u79bb\uff08ft\uff09\uff1a 184.448 # \u8f93\u5165\u5c0f\u7403\u521d\u59cb\u9ad8\u5ea6\uff08ft\uff09\uff1a100 # \u8f93\u5165\u5141\u8bb8\u5c0f\u7403\u5f39\u8df3\u6b21\u6570\uff1a10 # \u5c0f\u7403\u7ecf\u8fc7\u7684\u603b\u8ddd\u79bb\uff08ft\uff09\uff1a 397.58135296000006 def calculate_total_distance ( initial_height , num_bounces ): rebound_factor = 0.6 total_distance = 0 height = initial_height for _ in range ( num_bounces + 1 ): total_distance += height height *= rebound_factor return total_distance def main (): try : initial_height = float ( input ( \"\u8bf7\u8f93\u5165\u7403\u7684\u521d\u59cb\u9ad8\u5ea6\uff08\u5355\u4f4d\uff1aft\uff09\uff1a\" )) num_bounces = int ( input ( \"\u8bf7\u8f93\u5165\u5141\u8bb8\u7403\u5f39\u8df3\u7684\u6b21\u6570\uff1a\" )) total_distance = calculate_total_distance ( initial_height , num_bounces ) print ( f \"\u7403\u6240\u7ecf\u8fc7\u7684\u603b\u8ddd\u79bb\u4e3a\uff1a { total_distance : .2f } ft\" ) except ValueError : print ( \"\u8bf7\u8f93\u5165\u6709\u6548\u7684\u6570\u5b57\uff01\" ) if __name__ == \"__main__\" : main () # \u8fd0\u884c\u7ed3\u679c\uff1a # \u8bf7\u8f93\u5165\u7403\u7684\u521d\u59cb\u9ad8\u5ea6\uff08\u5355\u4f4d\uff1aft\uff09\uff1a50 # \u8bf7\u8f93\u5165\u5141\u8bb8\u7403\u5f39\u8df3\u7684\u6b21\u6570\uff1a5 # \u7403\u6240\u7ecf\u8fc7\u7684\u603b\u8ddd\u79bb\u4e3a\uff1a119.17 ft # \u8bf7\u8f93\u5165\u7403\u7684\u521d\u59cb\u9ad8\u5ea6\uff08\u5355\u4f4d\uff1aft\uff09\uff1a100 # \u8bf7\u8f93\u5165\u5141\u8bb8\u7403\u5f39\u8df3\u7684\u6b21\u6570\uff1a10 # \u7403\u6240\u7ecf\u8fc7\u7684\u603b\u8ddd\u79bb\u4e3a\uff1a249.09 ft class BouncingBall : def __init__ ( self , initial_height , num_bounces ): self . initial_height = initial_height self . num_bounces = num_bounces self . rebound_factor = 0.6 def calculate_total_distance ( self ): total_distance = 0 height = self . initial_height for _ in range ( self . num_bounces + 1 ): total_distance += height height *= self . rebound_factor return total_distance def main (): try : initial_height = float ( input ( \"\u8bf7\u8f93\u5165\u7403\u7684\u521d\u59cb\u9ad8\u5ea6\uff08\u5355\u4f4d\uff1aft\uff09\uff1a\" )) num_bounces = int ( input ( \"\u8bf7\u8f93\u5165\u5141\u8bb8\u7403\u5f39\u8df3\u7684\u6b21\u6570\uff1a\" )) bouncing_ball = BouncingBall ( initial_height , num_bounces ) total_distance = bouncing_ball . calculate_total_distance () print ( f \"\u7403\u6240\u7ecf\u8fc7\u7684\u603b\u8ddd\u79bb\u4e3a\uff1a { total_distance : .2f } ft\" ) except ValueError : print ( \"\u8bf7\u8f93\u5165\u6709\u6548\u7684\u6570\u5b57\uff01\" ) if __name__ == \"__main__\" : main () 4\uff0e\u5fb7\u56fd\u6570\u5b66\u5bb6Gottfried Leibniz\u53d1\u660e\u4e86\u4e0b\u9762\u8fd9\u4e2a\u7528\u6765\u6c42\u03c0\u7684\u8fd1\u4f3c\u503c\u7684\u65b9\u6cd5\uff1a \u03c0/4 = 1 - 1/3 + 1/5 - 1/7 + ...... \uff0c\u8bf7\u7f16\u5199\u4e00\u4e2a\u7a0b\u5e8f\uff0c\u8ba9\u7528\u6237\u53ef\u4ee5\u6307\u5b9a\u8fd9\u4e2a\u8fd1\u4f3c\u503c\u6240\u4f7f\u7528\u7684\u8fed\u4ee3\u6b21\u6570\uff0c\u5e76\u4e14\u663e\u793a\u51fa\u7ed3\u679c\u3002 \u89e3\u7b54\uff1a n = int ( input ( \"\u8f93\u5165\u8fed\u4ee3\u6b21\u6570\uff1a\" )) mySum = 0 while n : mySum += 1 / ( 2 * n - 1 ) * (( - 1 ) ** ( n + 1 )) n -= 1 print ( \"\u03c0\u7684\u8fd1\u4f3c\u503c\u662f\uff1a\" , mySum * 4 ) # \u8fd0\u884c\u7ed3\u679c\uff1a # \u8f93\u5165\u8fed\u4ee3\u6b21\u6570\uff1a5 # \u03c0\u7684\u8fd1\u4f3c\u503c\u662f\uff1a 3.33968253968254 # \u8f93\u5165\u8fed\u4ee3\u6b21\u6570\uff1a10 # \u03c0\u7684\u8fd1\u4f3c\u503c\u662f\uff1a 3.0418396189294024 # \u8f93\u5165\u8fed\u4ee3\u6b21\u6570\uff1a20 # \u03c0\u7684\u8fd1\u4f3c\u503c\u662f\uff1a 3.0916238066678385 # \u8f93\u5165\u8fed\u4ee3\u6b21\u6570\uff1a10000000 # \u03c0\u7684\u8fd1\u4f3c\u503c\u662f\uff1a 3.1415925535897933 def calculate_pi_approximation ( iterations ): approximation = 0 sign = 1 for i in range ( 1 , iterations * 2 , 2 ): approximation += sign * ( 1 / i ) sign *= - 1 return approximation * 4 def main (): try : iterations = int ( input ( \"\u8bf7\u8f93\u5165\u8fed\u4ee3\u6b21\u6570\uff1a\" )) if iterations <= 0 : print ( \"\u8fed\u4ee3\u6b21\u6570\u5fc5\u987b\u4e3a\u6b63\u6574\u6570\uff01\" ) return pi_approximation = calculate_pi_approximation ( iterations ) print ( f \"\u03c0 \u7684\u8fd1\u4f3c\u503c\u4e3a\uff1a { pi_approximation : .10f } \" ) except ValueError : print ( \"\u8bf7\u8f93\u5165\u6709\u6548\u7684\u6574\u6570\uff01\" ) if __name__ == \"__main__\" : main () # \u8fd0\u884c\u7ed3\u679c\uff1a # \u8bf7\u8f93\u5165\u8fed\u4ee3\u6b21\u6570\uff1a5 # \u03c0 \u7684\u8fd1\u4f3c\u503c\u4e3a\uff1a3.3396825397 # \u8bf7\u8f93\u5165\u8fed\u4ee3\u6b21\u6570\uff1a10 # \u03c0 \u7684\u8fd1\u4f3c\u503c\u4e3a\uff1a3.0418396189 # \u8bf7\u8f93\u5165\u8fed\u4ee3\u6b21\u6570\uff1a20 # \u03c0 \u7684\u8fd1\u4f3c\u503c\u4e3a\uff1a3.0916238067 # \u8bf7\u8f93\u5165\u8fed\u4ee3\u6b21\u6570\uff1a10000000 # \u03c0 \u7684\u8fd1\u4f3c\u503c\u4e3a\uff1a3.1415925536 class PiApproximation : @classmethod def calculate_pi_approximation ( cls , iterations ): approximation = 0 sign = 1 for i in range ( 1 , iterations * 2 , 2 ): approximation += sign * ( 1 / i ) sign *= - 1 return approximation * 4 def main (): try : iterations = int ( input ( \"\u8bf7\u8f93\u5165\u8fed\u4ee3\u6b21\u6570\uff1a\" )) if iterations <= 0 : print ( \"\u8fed\u4ee3\u6b21\u6570\u5fc5\u987b\u4e3a\u6b63\u6574\u6570\uff01\" ) return pi_approximation = PiApproximation . calculate_pi_approximation ( iterations ) print ( f \"\u03c0 \u7684\u8fd1\u4f3c\u503c\u4e3a\uff1a { pi_approximation : .10f } \" ) except ValueError : print ( \"\u8bf7\u8f93\u5165\u6709\u6548\u7684\u6574\u6570\uff01\" ) if __name__ == \"__main__\" : main () # \u8fd0\u884c\u7ed3\u679c\uff1a # \u8f93\u5165\u8fed\u4ee3\u6b21\u6570\uff1a5 # \u03c0 \u7684\u8fd1\u4f3c\u503c\u4e3a\uff1a3.3396825397 # \u8bf7\u8f93\u5165\u8fed\u4ee3\u6b21\u6570\uff1a10 # \u03c0 \u7684\u8fd1\u4f3c\u503c\u4e3a\uff1a3.0418396189 # \u8bf7\u8f93\u5165\u8fed\u4ee3\u6b21\u6570\uff1a20 # \u03c0 \u7684\u8fd1\u4f3c\u503c\u4e3a\uff1a3.0916238067 # \u8bf7\u8f93\u5165\u8fed\u4ee3\u6b21\u6570\uff1a10000000 # \u03c0 \u7684\u8fd1\u4f3c\u503c\u4e3a\uff1a3.1415925536 5\uff0e\u67d0\u8ba1\u7b97\u673a\u5546\u5e97\u6709\u8d2d\u4e70\u8ba1\u7b97\u673a\u7684\u4fe1\u8d37\u8ba1\u5212\uff1a\u9996\u4ed810%\uff0c\u5e74\u5229\u7387\u4e3a12%\uff0c\u6bcf\u6708\u6240\u4ed8\u6b3e\u4e3a\u8d2d\u4e70\u4ef7\u683c\u51cf\u53bb\u9996\u4ed8\u4e4b\u540e\u76845%\u3002\u7f16\u5199\u4e00\u4e2a\u4ee5\u8d2d\u4e70\u4ef7\u683c\u4e3a\u8f93\u5165\u7684\u7a0b\u5e8f\uff0c\u53ef\u4ee5\u8f93\u51fa\u4e00\u4e2a\u6709\u9002\u5f53\u6807\u9898\u7684\u8868\u683c\uff0c\u663e\u793a\u8d37\u6b3e\u671f\u9650\u5185\u7684\u4ed8\u6b3e\u8ba1\u5212\u3002\u8868\u7684\u6bcf\u4e00\u884c\u90fd\u5e94\u5305\u542b\u4e0b\u9762\u5404\u9879\uff1a \u6708\u6570\uff08\u4ee51\u5f00\u5934\uff09\uff1b \u5f53\u524d\u6240\u6b20\u7684\u4f59\u989d\uff1b \u5f53\u6708\u6240\u6b20\u7684\u5229\u606f\uff1b \u5f53\u6708\u6240\u6b20\u7684\u672c\u91d1\uff1b \u5f53\u6708\u6240\u9700\u4ed8\u6b3e\u91d1\u989d\uff1b \u4ed8\u6b3e\u4e4b\u540e\u6240\u6b20\u7684\u91d1\u989d\u3002 \u4e00\u4e2a\u6708\u7684\u5229\u606f\u7b49\u4e8e\u4f59\u989d \u00d7 \u5229\u7387/12\uff1b\u4e00\u4e2a\u6708\u6240\u6b20\u7684\u672c\u91d1\u7b49\u4e8e\u5f53\u6708\u8fd8\u6b3e\u989d\u51cf\u53bb\u6240\u6b20\u7684\u5229\u606f\u3002 \u89e3\u7b54\uff1a def calculate_payment_schedule ( purchase_price ): down_payment = purchase_price * 0.1 loan_balance = purchase_price - down_payment annual_interest_rate = 0.12 monthly_interest_rate = annual_interest_rate / 12 monthly_payment = ( purchase_price - down_payment ) * 0.05 payment_schedule = [] for month in range ( 1 , 13 ): interest = loan_balance * monthly_interest_rate principal = monthly_payment - interest loan_balance -= principal payment_schedule . append (( month , loan_balance , interest , principal , monthly_payment , loan_balance + monthly_payment )) return payment_schedule def main (): try : purchase_price = float ( input ( \"\u8bf7\u8f93\u5165\u8d2d\u4e70\u4ef7\u683c\uff1a\" )) payment_schedule = calculate_payment_schedule ( purchase_price ) print ( \" {:<10} {:<15} {:<15} {:<15} {:<15} {:<15} \" . format ( \"\u6708\u6570\" , \"\u5f53\u524d\u6240\u6b20\u7684\u4f59\u989d\" , \"\u5f53\u6708\u6240\u6b20\u7684\u5229\u606f\" , \"\u5f53\u6708\u6240\u6b20\u7684\u672c\u91d1\" , \"\u5f53\u6708\u6240\u9700\u4ed8\u6b3e\u91d1\u989d\" , \"\u4ed8\u6b3e\u4e4b\u540e\u6240\u6b20\u7684\u91d1\u989d\" )) for payment in payment_schedule : month , balance , interest , principal , monthly_payment , new_balance = payment print ( \" {:<10} {:<15.2f} {:<15.2f} {:<15.2f} {:<15.2f} {:<15.2f} \" . format ( month , balance , interest , principal , monthly_payment , new_balance )) except ValueError : print ( \"\u8bf7\u8f93\u5165\u6709\u6548\u7684\u6570\u5b57\uff01\" ) if __name__ == \"__main__\" : main () # \u8fd0\u884c\u7ed3\u679c\uff1a # \u8bf7\u8f93\u5165\u8d2d\u4e70\u4ef7\u683c\uff1a5000 # \u6708\u6570 \u5f53\u524d\u6240\u6b20\u7684\u4f59\u989d \u5f53\u6708\u6240\u6b20\u7684\u5229\u606f \u5f53\u6708\u6240\u6b20\u7684\u672c\u91d1 \u5f53\u6708\u6240\u9700\u4ed8\u6b3e\u91d1\u989d \u4ed8\u6b3e\u4e4b\u540e\u6240\u6b20\u7684\u91d1\u989d # 1 4320.00 45.00 180.00 225.00 4545.00 # 2 4138.20 43.20 181.80 225.00 4363.20 # 3 3954.58 41.38 183.62 225.00 4179.58 # 4 3769.13 39.55 185.45 225.00 3994.13 # 5 3581.82 37.69 187.31 225.00 3806.82 # 6 3392.64 35.82 189.18 225.00 3617.64 # 7 3201.56 33.93 191.07 225.00 3426.56 # 8 3008.58 32.02 192.98 225.00 3233.58 # 9 2813.67 30.09 194.91 225.00 3038.67 # 10 2616.80 28.14 196.86 225.00 2841.80 # 11 2417.97 26.17 198.83 225.00 2642.97 # 12 2217.15 24.18 200.82 225.00 2442.15 class PaymentSchedule : def __init__ ( self , purchase_price ): self . purchase_price = purchase_price self . down_payment = purchase_price * 0.1 self . loan_balance = purchase_price - self . down_payment self . annual_interest_rate = 0.12 self . monthly_interest_rate = self . annual_interest_rate / 12 self . monthly_payment = ( purchase_price - self . down_payment ) * 0.05 def calculate_schedule ( self ): payment_schedule = [] for month in range ( 1 , 13 ): interest = self . loan_balance * self . monthly_interest_rate principal = self . monthly_payment - interest self . loan_balance -= principal payment_schedule . append (( month , self . loan_balance , interest , principal , self . monthly_payment , self . loan_balance + self . monthly_payment )) return payment_schedule def print_schedule_table ( self ): payment_schedule = self . calculate_schedule () print ( \" {:<10} {:<15} {:<15} {:<15} {:<15} {:<15} \" . format ( \"\u6708\u6570\" , \"\u5f53\u524d\u6240\u6b20\u7684\u4f59\u989d\" , \"\u5f53\u6708\u6240\u6b20\u7684\u5229\u606f\" , \"\u5f53\u6708\u6240\u6b20\u7684\u672c\u91d1\" , \"\u5f53\u6708\u6240\u9700\u4ed8\u6b3e\u91d1\u989d\" , \"\u4ed8\u6b3e\u4e4b\u540e\u6240\u6b20\u7684\u91d1\u989d\" )) for payment in payment_schedule : month , balance , interest , principal , monthly_payment , new_balance = payment print ( \" {:<10} {:<15.2f} {:<15.2f} {:<15.2f} {:<15.2f} {:<15.2f} \" . format ( month , balance , interest , principal , monthly_payment , new_balance )) def main (): try : purchase_price = float ( input ( \"\u8bf7\u8f93\u5165\u8d2d\u4e70\u4ef7\u683c\uff1a\" )) payment_schedule = PaymentSchedule ( purchase_price ) payment_schedule . print_schedule_table () except ValueError : print ( \"\u8bf7\u8f93\u5165\u6709\u6548\u7684\u6570\u5b57\uff01\" ) if __name__ == \"__main__\" : main () # \u8fd0\u884c\u7ed3\u679c # \u8bf7\u8f93\u5165\u8d2d\u4e70\u4ef7\u683c\uff1a5000 # \u6708\u6570 \u5f53\u524d\u6240\u6b20\u7684\u4f59\u989d \u5f53\u6708\u6240\u6b20\u7684\u5229\u606f \u5f53\u6708\u6240\u6b20\u7684\u672c\u91d1 \u5f53\u6708\u6240\u9700\u4ed8\u6b3e\u91d1\u989d \u4ed8\u6b3e\u4e4b\u540e\u6240\u6b20\u7684\u91d1\u989d # 1 4320.00 45.00 180.00 225.00 4545.00 # 2 4138.20 43.20 181.80 225.00 4363.20 # 3 3954.58 41.38 183.62 225.00 4179.58 # 4 3769.13 39.55 185.45 225.00 3994.13 # 5 3581.82 37.69 187.31 225.00 3806.82 # 6 3392.64 35.82 189.18 225.00 3617.64 # 7 3201.56 33.93 191.07 225.00 3426.56 # 8 3008.58 32.02 192.98 225.00 3233.58 # 9 2813.67 30.09 194.91 225.00 3038.67 # 10 2616.80 28.14 196.86 225.00 2841.80 # 11 2417.97 26.17 198.83 225.00 2642.97 # 12 2217.15 24.18 200.82 225.00 2442.15 6\uff0e\u8d22\u52a1\u90e8\u95e8\u5728\u6587\u672c\u6587\u4ef6\u91cc\u4fdd\u5b58\u4e86\u6240\u6709\u5458\u5de5\u5728\u6bcf\u4e2a\u5de5\u8d44\u5468\u671f\u91cc\u7684\u4fe1\u606f\u5217\u8868\u3002\u6587\u4ef6\u4e2d\u6bcf\u4e00\u884c\u7684\u683c\u5f0f\u4e3a \u3002\u8bf7\u7f16\u5199\u4e00\u4e2a\u7a0b\u5e8f\uff0c\u8ba9\u7528\u6237\u53ef\u4ee5\u8f93\u5165\u6587\u4ef6\u7684\u540d\u79f0\uff0c\u5e76\u5728\u7ec8\u7aef\u4e0a\u6253\u5370\u51fa\u7ed9\u5b9a\u65f6\u95f4\u5185\u652f\u4ed8\u7ed9\u6bcf\u4e2a\u5458\u5de5\u7684\u5de5\u8d44\u62a5\u544a\u3002\u8fd9\u4e2a\u62a5\u544a\u662f\u4e00\u4e2a\u6709\u5408\u9002\u6807\u9898\u7684\u8868\uff0c\u5176\u4e2d\u6bcf\u884c\u90fd\u5e94\u8be5\u5305\u542b\u5458\u5de5\u7684\u59d3\u540d\u3001\u5de5\u4f5c\u65f6\u957f\u4ee5\u53ca\u7ed9\u5b9a\u65f6\u95f4\u5185\u6240\u652f\u4ed8\u7684\u5de5\u8d44\u3002 \u89e3\u7b54\uff1a # \u7a0b\u5e8f\u4f1a\u63d0\u793a\u7528\u6237\u8f93\u5165\u6587\u4ef6\u540d\uff0c\u7136\u540e\u8bfb\u53d6\u6587\u4ef6\u4e2d\u7684\u5458\u5de5\u4fe1\u606f\uff0c\u8ba1\u7b97\u5de5\u8d44\u62a5\u544a\uff0c\u5e76\u6253\u5370\u51fa\u5458\u5de5\u7684\u59d3\u540d\u3001\u5de5\u4f5c\u65f6\u957f\u548c\u652f\u4ed8\u5de5\u8d44\u3002\u6ce8\u610f\uff0c\u7a0b\u5e8f\u4f1a\u68c0\u67e5\u6587\u4ef6\u662f\u5426\u5b58\u5728\uff0c\u5e76\u4f1a\u5bf9\u6587\u4ef6\u4e2d\u7684\u6bcf\u884c\u6570\u636e\u8fdb\u884c\u5904\u7406\u4ee5\u786e\u4fdd\u6b63\u786e\u89e3\u6790\u3002 class Employee : def __init__ ( self , last_name , hourly_wage , hours_worked ): self . last_name = last_name self . hourly_wage = float ( hourly_wage ) self . hours_worked = float ( hours_worked ) def calculate_salary ( self ): return self . hourly_wage * self . hours_worked def main (): try : filename = input ( \"\u8bf7\u8f93\u5165\u6587\u4ef6\u540d\uff1a\" ) with open ( filename , 'r' ) as file : employees = [] for line in file : parts = line . strip () . split () if len ( parts ) == 3 : last_name , hourly_wage , hours_worked = parts employee = Employee ( last_name , hourly_wage , hours_worked ) employees . append ( employee ) print ( \" {:<20} {:<15} {:<15} \" . format ( \"\u5458\u5de5\u59d3\u540d\" , \"\u5de5\u4f5c\u65f6\u957f\" , \"\u652f\u4ed8\u5de5\u8d44\" )) print ( \"=\" * 50 ) total_salary = 0 for employee in employees : salary = employee . calculate_salary () total_salary += salary print ( \" {:<20} {:<15.2f} {:<15.2f} \" . format ( employee . last_name , employee . hours_worked , salary )) print ( \"=\" * 50 ) print ( f \"\u603b\u652f\u4ed8\u5de5\u8d44\uff1a { total_salary : .2f } \" ) except FileNotFoundError : print ( \"\u6587\u4ef6\u4e0d\u5b58\u5728\uff01\" ) if __name__ == \"__main__\" : main () 7\uff0e\u7edf\u8ba1\u5b66\u5bb6\u5e0c\u671b\u4f7f\u7528\u4e00\u7ec4\u51fd\u6570\u8ba1\u7b97\u6570\u5b57\u5217\u8868\u7684\u4e2d\u4f4d\u6570\uff08median\uff09\u548c\u4f17\u6570\uff08mode\uff09\u3002\u4e2d\u4f4d\u6570\u662f\u6307\u5982\u679c\u5bf9\u5217\u8868\u8fdb\u884c\u6392\u5e8f\u5c06\u4f1a\u51fa\u73b0\u5728\u5217\u8868\u4e2d\u70b9\u7684\u6570\u5b57\uff0c\u4f17\u6570\u662f\u6307\u5217\u8868\u4e2d\u6700\u5e38\u51fa\u73b0\u7684\u6570\u5b57\u3002\u628a\u8fd9\u4e9b\u529f\u80fd\u5b9a\u4e49\u5728\u540d\u53ebstats.py\u7684\u6a21\u5757\u4e2d\u3002\u9664\u6b64\u4e4b\u5916\uff0c\u6a21\u5757\u8fd8\u5e94\u8be5\u5305\u542b\u4e00\u4e2a\u540d\u53ebmean\u7684\u51fd\u6570\uff0c\u7528\u6765\u8ba1\u7b97\u4e00\u7ec4\u6570\u5b57\u7684\u5e73\u5747\u503c\u3002\u6bcf\u4e2a\u51fd\u6570\u90fd\u4f1a\u63a5\u6536\u4e00\u4e2a\u6570\u5b57\u5217\u8868\u4f5c\u4e3a\u53c2\u6570\uff0c\u5e76\u8fd4\u56de\u4e00\u4e2a\u6570\u5b57\u3002 \u89e3\u7b54\uff1a def median ( numbers ): sorted_numbers = sorted ( numbers ) length = len ( sorted_numbers ) if length % 2 == 1 : return sorted_numbers [ length // 2 ] else : mid1 = sorted_numbers [ length // 2 - 1 ] mid2 = sorted_numbers [ length // 2 ] return ( mid1 + mid2 ) / 2 def mode ( numbers ): from collections import Counter counter = Counter ( numbers ) mode_list = counter . most_common () max_count = mode_list [ 0 ][ 1 ] modes = [ num for num , count in mode_list if count == max_count ] return modes def mean ( numbers ): total = sum ( numbers ) count = len ( numbers ) return total / count if __name__ == \"__main__\" : test_numbers = [ 4 , 2 , 7 , 2 , 1 , 9 , 4 , 7 ] print ( \"\u4e2d\u4f4d\u6570:\" , median ( test_numbers )) print ( \"\u4f17\u6570:\" , mode ( test_numbers )) print ( \"\u5e73\u5747\u503c:\" , mean ( test_numbers )) class Stats : @staticmethod def median ( numbers ): sorted_numbers = sorted ( numbers ) length = len ( sorted_numbers ) if length % 2 == 1 : return sorted_numbers [ length // 2 ] else : mid1 = sorted_numbers [ length // 2 - 1 ] mid2 = sorted_numbers [ length // 2 ] return ( mid1 + mid2 ) / 2 @staticmethod def mode ( numbers ): from collections import Counter counter = Counter ( numbers ) mode_list = counter . most_common () max_count = mode_list [ 0 ][ 1 ] modes = [ num for num , count in mode_list if count == max_count ] return modes @staticmethod def mean ( numbers ): total = sum ( numbers ) count = len ( numbers ) return total / count if __name__ == \"__main__\" : test_numbers = [ 4 , 2 , 7 , 2 , 1 , 9 , 4 , 7 ] print ( \"\u4e2d\u4f4d\u6570:\" , Stats . median ( test_numbers )) print ( \"\u4f17\u6570:\" , Stats . mode ( test_numbers )) print ( \"\u5e73\u5747\u503c:\" , Stats . mean ( test_numbers )) 8\uff0e\u7f16\u5199\u7a0b\u5e8f\uff0c\u8ba9\u7528\u6237\u53ef\u4ee5\u6d4f\u89c8\u6587\u4ef6\u91cc\u7684\u6587\u672c\u884c\u3002\u8fd9\u4e2a\u7a0b\u5e8f\u4f1a\u63d0\u793a\u7528\u6237\u8f93\u5165\u6587\u4ef6\u540d\uff0c\u7136\u540e\u628a\u6587\u672c\u884c\u90fd\u8f93\u5165\u5217\u8868\u3002\u63a5\u4e0b\u6765\uff0c\u8fd9\u4e2a\u7a0b\u5e8f\u4f1a\u8fdb\u5165\u4e00\u4e2a\u5faa\u73af\uff0c\u5728\u8fd9\u4e2a\u5faa\u73af\u91cc\u6253\u5370\u51fa\u6587\u4ef6\u7684\u603b\u884c\u6570\uff0c\u5e76\u63d0\u793a\u7528\u6237\u8f93\u5165\u884c\u53f7\u3002\u8fd9\u4e2a\u884c\u53f7\u7684\u8303\u56f4\u5e94\u5f53\u662f1\u5230\u6587\u4ef6\u7684\u603b\u884c\u6570\u3002\u5982\u679c\u8f93\u5165\u662f0\uff0c\u90a3\u4e48\u7a0b\u5e8f\u9000\u51fa\uff1b\u5426\u5219\uff0c\u7a0b\u5e8f\u5c06\u6253\u5370\u51fa\u884c\u53f7\u6240\u5bf9\u5e94\u7684\u6587\u672c\u884c\u3002 def read_file_lines ( filename ): try : with open ( filename , 'r' ) as file : lines = file . readlines () return lines except FileNotFoundError : print ( \"\u6587\u4ef6\u4e0d\u5b58\u5728\uff01\" ) return [] def main (): filename = input ( \"\u8bf7\u8f93\u5165\u6587\u4ef6\u540d\uff1a\" ) lines = read_file_lines ( filename ) if not lines : return total_lines = len ( lines ) while True : print ( f \"\u6587\u4ef6\u603b\u884c\u6570\uff1a { total_lines } \" ) try : line_number = int ( input ( \"\u8bf7\u8f93\u5165\u884c\u53f7\uff08\u8f93\u51650\u9000\u51fa\uff09\uff1a\" )) if line_number == 0 : break elif 1 <= line_number <= total_lines : print ( f \"\u884c\u53f7 { line_number } : { lines [ line_number - 1 ] . strip () } \" ) else : print ( \"\u65e0\u6548\u7684\u884c\u53f7\uff0c\u8bf7\u8f93\u5165\u6b63\u786e\u8303\u56f4\u5185\u7684\u884c\u53f7\uff01\" ) except ValueError : print ( \"\u8bf7\u8f93\u5165\u6709\u6548\u7684\u6570\u5b57\uff01\" ) if __name__ == \"__main__\" : main () class TextFileBrowser : @classmethod def read_file_lines ( cls , filename ): try : with open ( filename , 'r' ) as file : lines = file . readlines () return lines except FileNotFoundError : print ( \"\u6587\u4ef6\u4e0d\u5b58\u5728\uff01\" ) return [] @classmethod def browse_file ( cls , filename ): lines = cls . read_file_lines ( filename ) if not lines : return total_lines = len ( lines ) while True : print ( f \"\u6587\u4ef6\u603b\u884c\u6570\uff1a { total_lines } \" ) try : line_number = int ( input ( \"\u8bf7\u8f93\u5165\u884c\u53f7\uff08\u8f93\u51650\u9000\u51fa\uff09\uff1a\" )) if line_number == 0 : break elif 1 <= line_number <= total_lines : print ( f \"\u884c\u53f7 { line_number } : { lines [ line_number - 1 ] . strip () } \" ) else : print ( \"\u65e0\u6548\u7684\u884c\u53f7\uff0c\u8bf7\u8f93\u5165\u6b63\u786e\u8303\u56f4\u5185\u7684\u884c\u53f7\uff01\" ) except ValueError : print ( \"\u8bf7\u8f93\u5165\u6709\u6548\u7684\u6570\u5b57\uff01\" ) def main (): filename = input ( \"\u8bf7\u8f93\u5165\u6587\u4ef6\u540d\uff1a\" ) TextFileBrowser . browse_file ( filename ) if __name__ == \"__main__\" : main () 9\uff0e\u5728\u672c\u7ae0\u8ba8\u8bba\u7684numberguess\u7a0b\u5e8f\u91cc\uff0c\u8ba1\u7b97\u673a\u4f1a\u201c\u6784\u601d\u201d\u4e00\u4e2a\u6570\u5b57\uff0c\u800c\u7528\u6237\u5219\u8f93\u5165\u731c\u6d4b\u7684\u503c\uff0c\u76f4\u5230\u731c\u5bf9\u4e3a\u6b62\u3002\u7f16\u5199\u8fd9\u6837\u4e00\u4e2a\u7a0b\u5e8f\uff0c\u4f7f\u5176\u53ef\u4ee5\u8c03\u6362\u8fd9\u4e24\u4e2a\u89d2\u8272\uff0c\u4e5f\u5c31\u662f\uff1a\u7528\u6237\u53bb\u201c\u6784\u601d\u201d\u4e00\u4e2a\u6570\u5b57\uff0c\u7136\u540e\u8ba1\u7b97\u673a\u53bb\u8ba1\u7b97\u5e76\u8f93\u51fa\u731c\u6d4b\u7684\u503c\u3002\u548c\u524d\u9762\u90a3\u4e2a\u6e38\u620f\u7248\u672c\u4e00\u6837\uff0c\u5f53\u8ba1\u7b97\u673a\u731c\u9519\u65f6\uff0c\u7528\u6237\u5fc5\u987b\u7ed9\u51fa\u76f8\u5e94\u7684\u63d0\u793a\uff0c\u4f8b\u5982\u201c<\u201d\u548c\u201c>\u201d\uff08\u5206\u522b\u4ee3\u8868\u201c\u6211\u7684\u6570\u5b57\u66f4\u5c0f\u201d\u548c\u201c\u6211\u7684\u6570\u5b57\u66f4\u5927\u201d\uff09\u3002\u5f53\u8ba1\u7b97\u673a\u731c\u5bf9\u65f6\uff0c\u7528\u6237\u5e94\u8be5\u8f93\u5165\u201c=\u201d\u3002\u7528\u6237\u9700\u8981\u5728\u7a0b\u5e8f\u542f\u52a8\u7684\u65f6\u5019\u8f93\u5165\u6570\u5b57\u7684\u4e0b\u9650\u548c\u4e0a\u9650\u3002\u8ba1\u7b97\u673a\u5e94\u8be5\u5728\u6700\u591a [log2(high\u2212low)+1] \u6b21\u731c\u6d4b\u91cc\u627e\u5230\u6b63\u786e\u7684\u6570\u5b57\u3002\u7a0b\u5e8f\u5e94\u8be5\u80fd\u591f\u8ddf\u8e2a\u731c\u6d4b\u6b21\u6570\uff0c\u5982\u679c\u731c\u6d4b\u9519\u8bef\u7684\u6b21\u6570\u5230\u4e86\u5141\u8bb8\u731c\u6d4b\u7684\u6700\u5927\u503c\u4f46\u8fd8\u6ca1\u6709\u731c\u5bf9\uff0c\u5c31\u8f93\u51fa\u6d88\u606f\u201cYou're cheating\uff01\u201d\u3002\u4e0b\u9762\u662f\u548c\u8fd9\u4e2a\u7a0b\u5e8f\u8fdb\u884c\u4ea4\u4e92\u7684\u793a\u4f8b\uff1a Enter the smaller number : 1 Enter the larger number : 100 Your number is 50 Enter = , < , or > : > Your number is 75 Enter = , < , or > : < Your number is 62 Enter = , < , or > : < Your number is 56 Enter = , < , or > : = Hooray , I 've got it in 4 tries! import math class ComputerGuesser : def __init__ ( self , lower_limit , upper_limit ): self . lower_limit = lower_limit self . upper_limit = upper_limit self . max_attempts = math . floor ( math . log2 ( upper_limit - lower_limit + 1 )) + 1 self . attempts = 0 def guess ( self ): return ( self . lower_limit + self . upper_limit ) // 2 def play ( self ): print ( f \"\u8bf7\u4f60\u9009\u62e9\u4e00\u4e2a\u5728 { self . lower_limit } \u5230 { self . upper_limit } \u4e4b\u95f4\u7684\u6570\u5b57\u3002\" ) while self . attempts < self . max_attempts : guess = self . guess () print ( f \"\u6211\u7684\u731c\u6d4b\u662f\uff1a { guess } \" ) response = input ( \"\u8bf7\u8f93\u5165 =, <, \u6216 > \u6765\u6307\u793a\u662f\u5426\u731c\u5bf9\uff1a\" ) self . attempts += 1 if response == '=' : print ( f \"\u6211\u5728\u7b2c { self . attempts } \u6b21\u731c\u5bf9\u4e86\uff01\" ) break elif response == '<' : self . upper_limit = guess - 1 elif response == '>' : self . lower_limit = guess + 1 else : print ( \"\u8bf7\u8f93\u5165\u6709\u6548\u7684\u64cd\u4f5c\u7b26\uff1a=, <, \u6216 >\" ) if self . attempts >= self . max_attempts : print ( \"\u4f60\u5728\u6b3a\u9a97\u6211\uff01\" ) def main (): lower_limit = int ( input ( \"\u8bf7\u8f93\u5165\u8f83\u5c0f\u7684\u6570\u5b57\uff1a\" )) upper_limit = int ( input ( \"\u8bf7\u8f93\u5165\u8f83\u5927\u7684\u6570\u5b57\uff1a\" )) guesser = ComputerGuesser ( lower_limit , upper_limit ) guesser . play () if __name__ == \"__main__\" : main () import math class ComputerGuesser : def __init__ ( self , lower_limit , upper_limit ): self . lower_limit = lower_limit self . upper_limit = upper_limit self . max_attempts = math . floor ( math . log2 ( upper_limit - lower_limit + 1 )) + 1 self . attempts = 0 @classmethod def guess ( cls , lower_limit , upper_limit ): return ( lower_limit + upper_limit ) // 2 @classmethod def play ( cls , lower_limit , upper_limit ): print ( f \"\u8bf7\u4f60\u9009\u62e9\u4e00\u4e2a\u5728 { lower_limit } \u5230 { upper_limit } \u4e4b\u95f4\u7684\u6570\u5b57\u3002\" ) attempts = 0 while attempts < cls . max_attempts : guess = cls . guess ( lower_limit , upper_limit ) print ( f \"\u6211\u7684\u731c\u6d4b\u662f\uff1a { guess } \" ) response = input ( \"\u8bf7\u8f93\u5165 =, <, \u6216 > \u6765\u6307\u793a\u662f\u5426\u731c\u5bf9\uff1a\" ) attempts += 1 if response == '=' : print ( f \"\u6211\u5728\u7b2c { attempts } \u6b21\u731c\u5bf9\u4e86\uff01\" ) break elif response == '<' : upper_limit = guess - 1 elif response == '>' : lower_limit = guess + 1 else : print ( \"\u8bf7\u8f93\u5165\u6709\u6548\u7684\u64cd\u4f5c\u7b26\uff1a=, <, \u6216 >\" ) if attempts >= cls . max_attempts : print ( \"\u4f60\u5728\u6b3a\u9a97\u6211\uff01\" ) def main (): lower_limit = int ( input ( \"\u8bf7\u8f93\u5165\u8f83\u5c0f\u7684\u6570\u5b57\uff1a\" )) upper_limit = int ( input ( \"\u8bf7\u8f93\u5165\u8f83\u5927\u7684\u6570\u5b57\uff1a\" )) ComputerGuesser . play ( lower_limit , upper_limit ) if __name__ == \"__main__\" : main () 10\uff0e\u6709\u4e00\u4e2a\u7b80\u5355\u7684\u8bfe\u7a0b\u7ba1\u7406\u7cfb\u7edf\uff0c\u5b83\u901a\u8fc7\u4f7f\u7528\u540d\u5b57\u548c\u4e00\u7ec4\u8003\u8bd5\u5206\u6570\u6765\u6a21\u62df\u5b66\u751f\u7684\u4fe1\u606f\u3002\u8fd9\u4e2a\u7cfb\u7edf\u5e94\u8be5\u80fd\u591f\u521b\u5efa\u4e00\u4e2a\u5177\u6709\u7ed9\u5b9a\u540d\u5b57\u548c\u5206\u6570\uff08\u8d77\u521d\u5747\u4e3a0\uff09\u7684\u5b66\u751f\u5bf9\u8c61\u3002\u7cfb\u7edf\u5e94\u8be5\u80fd\u591f\u8bbf\u95ee\u548c\u66ff\u6362\u6307\u5b9a\u4f4d\u7f6e\u5904\u7684\u5206\u6570\uff08\u4ece0\u5f00\u59cb\u8ba1\u6570\uff09\u3001\u5f97\u5230\u5b66\u751f\u6709\u591a\u5c11\u6b21\u8003\u8bd5\u3001\u5f97\u5230\u7684\u6700\u9ad8\u5206\u3001\u5f97\u5230\u7684\u5e73\u5747\u5206\u4ee5\u53ca\u5b66\u751f\u7684\u59d3\u540d\u3002\u9664\u6b64\u4e4b\u5916\uff0c\u5728\u6253\u5370\u5b66\u751f\u5bf9\u8c61\u7684\u65f6\u5019\uff0c\u5e94\u8be5\u50cf\u4e0b\u9762\u8fd9\u6837\u663e\u793a\u5b66\u751f\u7684\u59d3\u540d\u548c\u5206\u6570\uff1a Name : Ken Lambert Score 1 : 88 Score 2 : 77 Score 3 : 100 \u8bf7\u5b9a\u4e49\u4e00\u4e2a\u652f\u6301\u8fd9\u4e9b\u529f\u80fd\u548c\u884c\u4e3a\u7684Student\u7c7b\uff0c\u5e76\u4e14\u7f16\u5199\u4e00\u4e2a\u521b\u5efaStudent\u5bf9\u8c61\u5e76\u8fd0\u884c\u5176\u65b9\u6cd5\u7684\u7b80\u77ed\u7684\u6d4b\u8bd5\u51fd\u6570\u3002 class Student : def __init__ ( self , name ): self . name = name self . scores = [] def add_score ( self , score ): self . scores . append ( score ) def replace_score ( self , index , score ): if 0 <= index < len ( self . scores ): self . scores [ index ] = score else : print ( \"\u65e0\u6548\u7684\u5206\u6570\u7d22\u5f15\" ) def num_scores ( self ): return len ( self . scores ) def highest_score ( self ): if self . scores : return max ( self . scores ) else : return None def average_score ( self ): if self . scores : return sum ( self . scores ) / len ( self . scores ) else : return None def display ( self ): print ( f \"Name: { self . name } \" ) for i , score in enumerate ( self . scores , start = 1 ): print ( f \"Score { i } : { score } \" ) def test_student_class (): student = Student ( \"Ken Lambert\" ) student . add_score ( 88 ) student . add_score ( 77 ) student . add_score ( 100 ) student . display () print ( f \"Total Scores: { student . num_scores () } \" ) print ( f \"Highest Score: { student . highest_score () } \" ) print ( f \"Average Score: { student . average_score () } \" ) if __name__ == \"__main__\" : test_student_class ()","title":"1.9.\u7f16\u7a0b\u7ec3\u4e60"},{"location":"python/DataStructure/02_CollectionsOverview/","text":"2.\u591a\u9879\u96c6\u7684\u6982\u8ff0 \u00b6 \u591a\u9879\u96c6\uff08collection\uff09\u662f\u6307\u7531 0 \u4e2a\u6216\u8005\u591a\u4e2a\u5143\u7d20\u7ec4\u6210\u7684\u6982\u5ff5\u5355\u5143\u3002 \u4ece\u4e24\u4e2a\u89d2\u5ea6\u770b\u5f85\u591a\u9879\u96c6\uff1a \u591a\u9879\u96c6\u7684\u7528\u6237\u6216\u8005\u5ba2\u6237\u4f1a\u5173\u5fc3\u5b83\u4eec\u5728\u4e0d\u540c\u7684\u5e94\u7528\u7a0b\u5e8f\u91cc\u80fd\u505a\u4e9b\u4ec0\u4e48\u3002 \u591a\u9879\u96c6\u7684\u5f00\u53d1\u8005\u6216\u8005\u5b9e\u73b0\u8005\u5219\u4f1a\u5173\u5fc3\u5982\u4f55\u624d\u80fd\u8ba9\u5b83\u4eec\u6210\u4e3a\u6700\u597d\u7684\u901a\u7528\u8d44\u6e90\u4ee5\u88ab\u4f7f\u7528\u3002 \u76ee\u6807\uff1a \u5b9a\u4e49\u591a\u9879\u96c6\u76844\u4e2a\u901a\u7528\u7c7b\u578b\uff1a \u7ebf\u6027\u591a\u9879\u96c6 \u5206\u5c42\u591a\u9879\u96c6 \u56fe\u591a\u9879\u96c6 \u65e0\u5e8f\u591a\u9879\u96c6 \u4e86\u89e34\u4e2a\u591a\u9879\u96c6\u7c7b\u578b\u4e2d\u7684\u7279\u5b9a\u7c7b\u578b\uff1b \u4e86\u89e3\u8fd9\u4e9b\u591a\u9879\u96c6\u9002\u5408\u7528\u5728\u4ec0\u4e48\u7c7b\u578b\u7684\u5e94\u7528\u7a0b\u5e8f\u91cc\uff1b \u63cf\u8ff0\u6bcf\u79cd\u591a\u9879\u96c6\u7c7b\u578b\u7684\u5e38\u7528\u64cd\u4f5c\uff1b \u63cf\u8ff0\u591a\u9879\u96c6\u7684\u62bd\u8c61\u7c7b\u578b\u548c\u5b9e\u73b0\u4e4b\u95f4\u7684\u533a\u522b\uff1b 2.1.\u591a\u9879\u96c6\u7c7b\u578b \u00b6 \u5185\u7f6e\u591a\u9879\u96c6\u7c7b\u578b\uff1a \u5b57\u7b26\u4e32 str \u5217\u8868 list \u5143\u7ec4 tuple \u96c6\u5408 set \u5b57\u5178 dict \u5176\u4ed6\u591a\u9879\u96c6\u7c7b\u578b\uff1a \u6808 \u961f\u5217 \u4f18\u5148\u961f\u5217 \u4e8c\u53c9\u67e5\u627e\u6811 \u5806 \u56fe \u5305 \u6709\u5e8f\u591a\u9879\u96c6 \u591a\u9879\u96c6\u901a\u5e38\u4e0d\u662f\u9759\u6001\uff08static\uff09\u7684\uff0c\u800c\u662f\u52a8\u6001\uff08dynamic\uff09\u7684\uff0c\u53ef\u4ee5\u6839\u636e\u9700\u8981\u6765\u6269\u5927\u6216\u8005\u7f29\u5c0f\u591a\u9879\u96c6\u3002 \u4e0d\u53ef\u53d8\u591a\u9879\u96c6\uff08immutable collection\uff09\u7684\u5185\u5bb9\u5728\u7a0b\u5e8f\u8fd0\u884c\u8fc7\u7a0b\u4e2d\u662f\u4e0d\u53ef\u6539\u53d8\u7684\uff08\u5143\u7d20\u4e0d\u53ef\u4ee5\u6dfb\u52a0\u3001\u5220\u9664\u6216\u8005\u66ff\u6362\uff09\uff0c\u6bd4\u5982\u5143\u7ec4tuple\u3002 \u53ef\u53d8\u591a\u9879\u96c6\uff08mutable collection\uff09\u91cc\u7684\u5185\u5bb9\u53ef\u4ee5\u5728\u7a0b\u5e8f\u7684\u6574\u4e2a\u8fd0\u884c\u8fc7\u7a0b\u4e2d\u88ab\u6539\u53d8\uff0c\u6bd4\u5982\u5b57\u7b26\u4e32\u3001\u5217\u8868list\u3002 \u591a\u9879\u96c6\u6309\u6784\u6210\u65b9\u5f0f\u5212\u5206\u7684\u7c7b\u578b\uff1a \u7ebf\u6027\u591a\u9879\u96c6 \u5206\u5c42\u591a\u9879\u96c6 \u56fe\u591a\u9879\u96c6 \u65e0\u5e8f\u591a\u9879\u96c6 \u6709\u5e8f\u591a\u9879\u96c6 2.1.1.\u7ebf\u6027\u591a\u9879\u96c6 \u00b6 \u7ebf\u6027\u591a\u9879\u96c6\uff08linear collection\uff09\u91cc\u7684\u5143\u7d20\u6309\u7167\u4f4d\u7f6e\u8fdb\u884c\u6392\u5217\u3002 \u9664\u4e86\u7b2c\u4e00\u4e2a\u5143\u7d20\uff0c\u5176\u4ed6\u6bcf\u4e2a\u5143\u7d20\u90fd\u6709\u4e14\u53ea\u6709\u4e00\u4e2a\u524d\u5e8f\uff1b \u9664\u4e86\u6700\u540e\u4e00\u4e2a\u5143\u7d20\uff0c\u5176\u4ed6\u6bcf\u4e2a\u5143\u7d20\u90fd\u6709\u4e14\u53ea\u6709\u4e00\u4e2a\u540e\u5e8f\uff1b \u5b9e\u4f8b\uff1a\u6392\u961f\u7684\u4eba\uff0c\u8d2d\u7269\u6e05\u5355\uff0c\u5806\u53e0\u5728\u4e00\u8d77\u7684\u9910\u76d8\u7b49\u3002 2.1.2.\u5206\u5c42\u591a\u9879\u96c6 \u00b6 \u5206\u5c42\u591a\u9879\u96c6\uff08hierarchical collection\uff09\u91cc\u7684\u6570\u636e\u5143\u7d20\u4f1a\u4ee5\u7c7b\u4f3c\u4e8e\u5012\u7f6e\u7684\u6811\u7ed3\u6784\u8fdb\u884c\u6392\u5217\u3002\u9664\u4e86\u9876\u90e8\u7684\u6570\u636e\u5143\u7d20\uff0c\u5176\u4ed6\u6bcf\u4e2a\u6570\u636e\u5143\u7d20\u90fd\u6709\u4e14\u53ea\u6709\u4e00\u4e2a\u524d\u5e8f\uff0c\u88ab\u79f0\u4e3a\u7236\u5143\u7d20\uff08parent\uff09\uff0c\u4f46\u5b83\u4eec\u53ef\u4ee5\u6709\u8bb8\u591a\u7684\u540e\u5e8f\uff0c\u88ab\u79f0\u4e3a\u5b50\u5143\u7d20\uff08children\uff09\u3002 \u56fe\u4f8b\u4e2d\uff0c D3 \u7684\u524d\u5e8f\u7236\u5143\u7d20\u662f D1 \uff0c D3 \u7684\u540e\u7eed\u5b50\u5143\u7d20\u662f D4 \u3001 D5 \u3001 D6 \u3002 \u5b9e\u4f8b\uff1a\u6587\u4ef6\u76ee\u5f55\u7cfb\u7edf\u3001\u516c\u53f8\u7684\u7ec4\u7ec7\u67b6\u6784\u3001\u4e66\u7684\u76ee\u5f55\u7b49\u3002 2.1.3.\u56fe\u591a\u9879\u96c6 \u00b6 \u56fe\u591a\u9879\u96c6\uff08graph collection\uff09\u4e5f\u88ab\u79f0\u4e3a\u56fe\uff08graph\uff09\uff0c\u5b83\u662f\u8fd9\u6837\u4e00\u4e2a\u591a\u9879\u96c6\uff1a\u5b83\u7684\u6bcf\u4e00\u4e2a\u6570\u636e\u5143\u7d20\u90fd\u53ef\u4ee5\u6709\u591a\u4e2a\u524d\u5e8f\u548c\u591a\u4e2a\u540e\u5e8f\u3002 \u56fe\u4f8b\u4e2d\uff0c\u8fde\u63a5\u5230 D3 \u7684\u6240\u6709\u5143\u7d20\u4f1a\u88ab\u5f53\u4f5c\u5b83\u7684\u524d\u5e8f\u548c\u540e\u5e8f\uff0c\u5b83\u4eec\u4e5f\u56e0\u6b64\u88ab\u79f0\u4e3a D3 \u7684\u90bb\u5c45\u3002 \u5b9e\u4f8b\uff1a\u57ce\u5e02\u4e4b\u95f4\u7684\u822a\u7ebf\u56fe\u3001\u4e07\u7ef4\u7f51\u7b49\u3002 2.1.4.\u65e0\u5e8f\u591a\u9879\u96c6 \u00b6 \u65e0\u5e8f\u591a\u9879\u96c6\uff08unordered collection\uff09\u91cc\u7684\u5143\u7d20\u6ca1\u6709\u7279\u5b9a\u7684\u987a\u5e8f\uff0c\u5e76\u4e14\u4e0d\u4f1a\u7528\u4efb\u4f55\u660e\u786e\u7684\u65b9\u5f0f\u6765\u6307\u51fa\u5143\u7d20\u7684\u524d\u5e8f\u6216\u8005\u540e\u5e8f\u3002 \u5b9e\u4f8b\uff1a\u4e00\u888b\u5f39\u73e0\u7b49\u3002 2.1.5.\u6709\u5e8f\u591a\u9879\u96c6 \u00b6 \u6709\u5e8f\u591a\u9879\u96c6\uff08sorted collection\uff09\u4f1a\u5bf9\u5b83\u91cc\u9762\u7684\u5143\u7d20\u8fdb\u884c\u81ea\u7136\u6392\u5e8f\uff08natural ordering\uff09\u3002 \u8981\u8fdb\u884c\u81ea\u7136\u6392\u5e8f\uff0c\u5c31\u5fc5\u987b\u8981\u6709\u89c4\u5219\u6765\u5bf9\u6709\u5e8f\u591a\u9879\u96c6\u91cc\u7684\u5143\u7d20\u52a0\u4ee5\u6bd4\u8f83\uff0c\u4f8b\u5982 item(i) <= item(i+1) \u8fd9\u6837\u7684\u2014\u2014\u89c4\u5219\u3002 \u6709\u5e8f\u5217\u8868\u662f\u6700\u5e38\u89c1\u7684\u6709\u5e8f\u591a\u9879\u96c6\u3002\u6709\u5e8f\u591a\u9879\u96c6\u4e0d\u4e00\u5b9a\u662f\u7ebf\u6027\u7684\u6216\u8005\u6309\u7167\u4f4d\u7f6e\u8fdb\u884c\u6392\u5e8f\u7684\u3002 \u5bf9\u4e8e\u96c6\u5408\u3001\u5305\u3001\u5b57\u5178\uff0c\u867d\u7136\u4e0d\u80fd\u6309\u7167\u4f4d\u7f6e\u6765\u8bbf\u95ee\u5b83\u4eec\u7684\u5143\u7d20\uff0c\u4f46\u5b83\u4eec\u90fd\u53ef\u4ee5\u662f\u6709\u5e8f\u7684\u3002 \u7279\u6b8a\u7684\u5206\u5c42\u591a\u9879\u96c6\u7c7b\u578b\uff08\u5982\u4e8c\u53c9\u67e5\u627e\u6811\uff09\u4e5f\u4f1a\u5bf9\u5176\u4e2d\u7684\u5143\u7d20\u8fdb\u884c\u81ea\u7136\u6392\u5e8f\u3002 2.1.6.\u591a\u9879\u96c6\u7c7b\u578b\u7684\u5206\u7c7b \u00b6 \u4e0b\u9762\u5206\u7c7b\u91cc\u7684\u7c7b\u578b\u540d\u79f0\u6307\u7684\u5e76\u4e0d\u662f\u591a\u9879\u96c6\u7684\u7279\u5b9a\u5b9e\u73b0\u3002\u4e00\u79cd\u7279\u5b9a\u7c7b\u578b\u7684\u591a\u9879\u96c6\u53ef\u4ee5\u6709\u591a\u4e2a\u5b9e\u73b0\u3002 \u591a\u9879\u96c6 | ---\u56fe\u591a\u9879\u96c6 | ---\u5206\u5c42\u591a\u9879\u96c6 | | ---\u4e8c\u53c9\u67e5\u627e\u6811 | | ---\u5806 | ---\u7ebf\u6027\u591a\u9879\u96c6 | | ---\u5217\u8868 | | | ---\u6709\u5e8f\u5217\u8868 | | ---\u961f\u5217 | | | ---\u4f18\u5148\u5bf9\u5217 | | ---\u6808 | | ---\u5b57\u7b26\u4e32 | ---\u65e0\u5e8f\u591a\u9879\u96c6 | ---\u5305 | | ---\u6709\u5e8f\u5305 | ---\u5b57\u5178 | | ---\u6709\u5e8f\u5305 | ---\u96c6\u5408 | ---\u6709\u5e8f\u96c6\u5408 2.2.\u591a\u9879\u96c6\u64cd\u4f5c \u00b6 \u591a\u9879\u96c6\u64cd\u4f5c\u7c7b\u522b\uff1a \u786e\u5b9a\u5927\u5c0f\uff1a\u4f7f\u7528 len \u51fd\u6570\u83b7\u53d6\u5f53\u524d\u591a\u9879\u96c6\u91cc\u7684\u5143\u7d20\u6570\u91cf\u3002 \u68c0\u6d4b\u5143\u7d20\u6210\u5458\uff1a\u4f7f\u7528 in \u8fd0\u7b97\u7b26\u5728\u591a\u9879\u96c6\u91cc\u641c\u7d22\u6307\u5b9a\u7684\u76ee\u6807\u5143\u7d20\u3002\u5982\u679c\u627e\u5230\u4e86\u8fd9\u4e2a\u5143\u7d20\uff0c\u5219\u8fd4\u56deTrue\uff0c\u5426\u5219\u8fd4\u56deFalse\u3002 \u904d\u5386\u591a\u9879\u96c6\uff1a\u4f7f\u7528 for \u5faa\u73af\u8bbf\u95ee\u591a\u9879\u96c6\u91cc\u7684\u6b38\u4e00\u4e2a\u5143\u7d20\u3002\u5143\u7d20\u7684\u8bbf\u95ee\u987a\u5e8f\u53d6\u51b3\u4e8e\u591a\u9879\u96c6\u7684\u7c7b\u578b\u3002 \u83b7\u53d6\u591a\u9879\u96c6\u7684\u5b57\u7b26\u4e32\u8868\u793a\uff1a\u4f7f\u7528 str \u51fd\u6570\u83b7\u53d6\u591a\u9879\u96c6\u7684\u5b57\u7b26\u4e32\u8868\u793a\u3002 \u76f8\u7b49\u68c0\u6d4b\uff1a\u4f7f\u7528 == \u8fd0\u7b97\u7b26\u6765\u786e\u5b9a\u4e24\u4e2a\u591a\u9879\u96c6\u662f\u5426\u76f8\u7b49\u3002\u5982\u679c\u4e24\u4e2a\u591a\u9879\u96c6\u80b2\u6709\u76f8\u540c\u7684\u7c7b\u578b\uff0c\u5e76\u4e14\u5305\u542b\u76f8\u540c\u7684\u5143\u7d20\uff0c\u90a3\u4e48\u5b83\u4eec\u5c31\u662f\u76f8\u7b49\u7684\u3002\u6bd4\u8f83\u8fd9\u4e9b\u5143\u7d20\u5bf9\u7684\u987a\u5e8f\u53d6\u51b3\u4e8e\u591a\u9879\u96c6\u7684\u7c7b\u578b\u3002 \u8fde\u63a5\u4e24\u4e2a\u591a\u9879\u96c6\uff1a\u4f7f\u7528 + \u8fd0\u7b97\u7b26\u6765\u5f97\u5230\u4e00\u4e2a\u548c\u64cd\u4f5c\u6570\u76f8\u540c\u7c7b\u578b\u7684\u65b0\u591a\u9879\u96c6\uff0c\u5e76\u4e14\u5305\u542b\u4e24\u4e2a\u64cd\u4f5c\u6570\u91cc\u7684\u6240\u6709\u5143\u7d20\u3002 \u8f6c\u6362\u4e3a\u5176\u4ed6\u7c7b\u578b\u7684\u591a\u9879\u96c6\uff1a\u521b\u5efa\u4e00\u4e2a\u4e0e\u6e90\u591a\u9879\u96c6\u5177\u6709\u76f8\u540c\u5143\u7d20\u7684\u65b0\u591a\u9879\u96c6\u3002\u514b\u9686\u64cd\u4f5c\u65f6\u7c7b\u578b\u8f6c\u6362\u7684\u4e00\u79cd\u7279\u6b8a\u60c5\u51b5\uff0c\u56e0\u4e3a\u8f93\u5165\u8f93\u51fa\u7684\u4e24\u4e2a\u591a\u9879\u96c6\u5177\u6709\u76f8\u540c\u7c7b\u578b\u3002 \u63d2\u5165\u4e00\u4e2a\u5143\u7d20\uff1a\u5982\u679c\u53ef\u4ee5\uff0c\u5219\u5728\u7ed9\u5b9a\u7684\u4f4d\u7f6e\u5c06\u5bf9\u5e94\u7684\u5143\u7d20\u6dfb\u52a0\u5230\u591a\u9879\u96c6\u91cc\u3002 \u5220\u9664\u4e00\u4e2a\u5143\u7d20\uff1a\u5982\u679c\u53ef\u4ee5\uff0c\u5219\u5728\u7ed9\u5b9a\u7684\u4f4d\u7f6e\u5c06\u5bf9\u5e94\u7684\u5143\u7d20\u4ece\u591a\u9879\u96c6\u4e2d\u5220\u9664\u3002 \u66ff\u6362\u4e00\u4e2a\u5143\u7d20\uff1a\u5c06\u5220\u9664\u548c\u63d2\u5165\u5408\u5e76\u4e3a\u4e00\u9879\u64cd\u4f5c\u3002 \u8bbf\u95ee\u6216\u8005\u83b7\u53d6\u5143\u7d20\uff1a\u5982\u679c\u800c\u5df2\uff0c\u5219\u5728\u7ed9\u5b9a\u7684\u4f4d\u7f6e\u83b7\u53d6\u5143\u7d20\u3002 2.2.1.\u6240\u6709\u591a\u9879\u96c6\u7c7b\u578b\u4e2d\u7684\u57fa\u672c\u64cd\u4f5c \u00b6 \u5728Python\u91cc\uff0c\u4e0d\u540c\u591a\u9879\u96c6\u7c7b\u578b\u7684\u63d2\u5165\u3001\u5220\u9664\u3001\u66ff\u6362\u6216\u8005\u8bbf\u95ee\u64cd\u4f5c\u5e76\u6ca1\u6709\u7edf\u4e00\u7684\u540d\u79f0\uff0c\u4f46\u662f\u4f1a\u6709\u4e00\u4e9b\u6807\u51c6\u53d8\u4f53\u3002\u6bd4\u5982\uff0c \u65b9\u6cd5pop\u4f1a\u88ab\u7528\u6765\u4ece\u5217\u8868\u91cc\u79fb\u9664\u6307\u5b9a\u4f4d\u7f6e\u7684\u5143\u7d20\uff1b \u65b9\u6cd5pop\u4f1a\u88ab\u7528\u6765\u4ece\u5b57\u5178\u91cc\u79fb\u9664\u7ed9\u5b9a\u952e\u6240\u5bf9\u5e94\u7684\u503c\uff1b \u65b9\u6cd5remove\u4f1a\u88ab\u7528\u6765\u4ece\u5217\u8868\u6216\u8005\u67d0\u4e9b\u591a\u9879\u96c6\u91cc\u5220\u9664\u6307\u5b9a\u7684\u5143\u7d20\uff1b \u5bf9\u4e8e\u65b0\u5f00\u53d1\u51fa\u7684\u3001Python\u5c1a\u4e0d\u652f\u6301\u7684\u591a\u9879\u96c6\u7c7b\u578b\uff0c\u5c3d\u53ef\u80fd\u5730\u4f7f\u7528\u6807\u51c6\u7684\u8fd0\u7b97\u7b26\u3001\u51fd\u6570\u4ee5\u53ca\u65b9\u6cd5\u540d\u79f0\u5bf9\u5b83\u4eec\u8fdb\u884c\u64cd\u4f5c\u3002 2.2.2.\u7c7b\u578b\u8f6c\u6362 \u00b6 \u7c7b\u578b\u8f6c\u6362\uff0c\u5c06\u4e00\u79cd\u7c7b\u578b\u7684\u591a\u9879\u96c6\u8f6c\u6362\u4e3a\u53e6\u4e00\u79cd\u7c7b\u578b\u7684\u591a\u9879\u96c6\u3002\u4f8b\u5982\uff0c\u901a\u8fc7 list \u6216 tuple \u51fd\u6570\u5c06\u5b57\u7b26\u4e32\u8f6c\u6362\u4e3a\u5217\u8868\u6216\u8005\u5143\u7ec4\u3002 list \u6216 tuple \u51fd\u6570\u7684\u53c2\u6570\u4e0d\u4e00\u5b9a\u662f\u53e6\u4e00\u4e2a\u591a\u9879\u96c6\uff0c\u4e5f\u53ef\u4ee5\u662f\u4efb\u4f55\u7684\u53ef\u8fed\u4ee3\u5bf9\u8c61\uff08iterable object\uff09\u3002 \u53ef\u8fed\u4ee3\u5bf9\u8c61\u662f\u6307\uff0c\u80fd\u591f\u4f7f\u7528for\u5faa\u73af\u6765\u8bbf\u95ee\u7684\u4e00\u7cfb\u5217\u5143\u7d20\u3002\uff08\u591a\u9879\u96c6\u672c\u8eab\u4e5f\u662f\u53ef\u8fed\u4ee3\u5bf9\u8c61\uff09 2.2.3.\u514b\u9686\u548c\u76f8\u7b49\u6027 \u00b6 \u7c7b\u578b\u8f6c\u6362\u7684\u4e00\u79cd\u7279\u6b8a\u60c5\u51b5\u662f\u514b\u9686\uff0c\u5b83\u7684\u529f\u80fd\u662f\u8fd4\u56de\u8f6c\u6362\u51fd\u6570\u4e2d\u53c2\u6570\u7684\u5b8c\u6574\u526f\u672c\u3002 \u4f8b\u5982\uff1a myList1 = [ 2 , 4 , 8 ] myList2 = list ( myList1 ) myList1 is myList2 # False myList1 == myList2 # True \u6ce8\u610f\uff1a \u4e0a\u9762\u4e24\u4e2a\u5217\u8868\u4e0d\u4ec5\u6709\u76f8\u540c\u7684\u7ed3\u6784\uff0c\u5b83\u4eec\u8fd8\u6709\u76f8\u540c\u7684\u5143\u7d20\uff0c\u6bcf\u5bf9\u5143\u7d20\u5728\u4e24\u4e2a\u5217\u8868\u91cc\u7684\u4f4d\u7f6e\u90fd\u76f8\u540c\u3002\u4f46\u662f\uff0c\u4ed6\u4eec\u662f\u4e24\u4e2a\u4e0d\u540c\u7684\u5bf9\u8c61\u3002 \u4e0a\u4f8b\u4e2d list \u51fd\u6570\u5bf9\u5b83\u7684\u53c2\u6570\u5217\u8868\u8fdb\u884c\u6d45\u62f7\u8d1d\uff08shallow copy\uff09\u3002\u8fd9\u4e9b\u5143\u7d20\u7684\u672c\u8eab\u5728\u6dfb\u52a0\u5230\u65b0\u5217\u8868\u4e4b\u524d\u662f\u4e0d\u4f1a\u88ab\u514b\u9686\u7684\uff0c\u5728\u8fd9\u4e2a\u8fc7\u7a0b\u4e2d\u53ea\u4f1a\u590d\u5236\u5bf9\u8fd9\u4e9b\u5bf9\u8c61\u7684\u5f15\u7528\u3002\u5f53\u5143\u7d20\uff08\u6570\u5b57\u3001\u5b57\u7b26\u4e32\u6216\u8005Python\u7684\u5143\u7ec4\uff09\u4e0d\u53ef\u53d8\u65f6\uff0c\u8fd9\u4e2a\u7b56\u7565\u4e0d\u4f1a\u5f15\u8d77\u95ee\u9898\u3002\u4f46\u662f\uff0c\u5982\u679c\u591a\u9879\u96c6\u5305\u542b\u7684\u662f\u53ef\u53d8\u5143\u7d20\uff0c\u5c31\u53ef\u80fd\u4f1a\u4ea7\u751f\u526f\u4f5c\u7528\u3002\u4e3a\u4e86\u907f\u514d\u8fd9\u79cd\u60c5\u51b5\u7684\u53d1\u751f\uff0c\u6211\u4eec\u53ef\u4ee5\u901a\u8fc7\u5bf9\u6e90\u591a\u9879\u96c6\u7f16\u5199 for \u5faa\u73af\u6765\u521b\u5efa\u6df1\u62f7\u8d1d\uff08deep copy\uff09\uff0c\u8fd9\u4f1a\u628a\u5143\u7d20\u663e\u5f0f\u5730\u514b\u9686\u4e4b\u540e\u518d\u6dfb\u52a0\u5230\u65b0\u7684\u591a\u9879\u96c6\u91cc\u3002 2.3.\u8fed\u4ee3\u5668\u548c\u9ad8\u9636\u51fd\u6570 \u00b6 \u6bcf\u79cd\u7c7b\u578b\u7684\u591a\u9879\u96c6\u90fd\u652f\u6301\u4e00\u4e2a\u8fed\u4ee3\u5668\u6216 for \u5faa\u73af\uff0c\u8fd9\u4e2a\u64cd\u4f5c\u80fd\u591f\u8fed\u4ee3\u8fd9\u4e2a\u591a\u9879\u96c6\u7684\u6240\u6709\u5143\u7d20\u3002\u8fed\u4ee3\u5668\u662f\u591a\u9879\u96c6\u63d0\u4f9b\u7684\u6700\u5173\u952e\u7684\u64cd\u4f5c\u3002 for \u5faa\u73af\u670d\u52a1\u7684\u591a\u9879\u96c6\u4e2d\u5143\u7d20\u7684\u987a\u5e8f\u53d6\u51b3\u4e8e\u591a\u9879\u96c6\u7684\u7ec4\u7ec7\u65b9\u5f0f\u3002\u4f8b\u5982\uff1a \u5217\u8868\u91cc\u7684\u5143\u7d20\u4f1a\u4ece\u5934\u5230\u5c3e\u6309\u7167\u4f4d\u7f6e\u8fdb\u884c\u8bbf\u95ee\uff1b \u6709\u5e8f\u591a\u9879\u96c6\u91cc\u7684\u5143\u7d20\u4f1a\u6309\u4ece\u5c0f\u5230\u5927\u7684\u5347\u5e8f\u8fdb\u884c\u8bbf\u95ee\uff1b \u5bf9\u4e8e\u96c6\u5408\u6216\u8005\u5b57\u5178\u91cc\u7684\u5143\u7d20\u6765\u8bf4\uff0c\u4e0d\u4f1a\u6309\u7167\u7279\u5b9a\u7684\u987a\u5e8f\u8fdb\u884c\u8bbf\u95ee\u3002 \u8fed\u4ee3\u5668\uff08\u4f8b\u5982 for \u5faa\u73af\uff09\u8fd8\u652f\u6301\u4f7f\u7528\u9ad8\u9636\u51fd\u6570 map \u3001 filter \u548c reduce \u3002 \u8fd9\u4e9b\u9ad8\u9636\u51fd\u6570\u90fd\u4f7f\u7528\u53e6\u4e00\u4e2a\u51fd\u6570\u548c\u4e00\u4e2a\u591a\u9879\u96c6\u4f5c\u4e3a\u53c2\u6570\u3002 \u591a\u9879\u96c6\u90fd\u652f\u6301 for \u5faa\u73af\uff0c\u6240\u4ee5 map \u3001 filter \u548c reduce \u51fd\u6570\u53ef\u4ee5\u4e0e\u4efb\u4f55\u7c7b\u578b\u7684\u591a\u9879\u96c6\u4e00\u8d77\u4f7f\u7528\u3002 2.4.\u591a\u9879\u96c6\u7684\u5b9e\u73b0 \u00b6 \u4ece\u7528\u6237\uff08\u6bd4\u5982\uff0c\u7a0b\u5e8f\u5458\uff09\u7684\u89d2\u5ea6\u6765\u770b\uff0c\u591a\u9879\u96c6\u662f\u4e00\u79cd\u62bd\u8c61\uff0c\u662f\u4e00\u79cd\u4ee5\u67d0\u79cd\u9884\u5b9a\u884c\u4e3a\u6765\u5b58\u50a8\u548c\u8bbf\u95ee\u6570\u636e\u5143\u7d20\u7684\u65b9\u5f0f\uff0c\u5e76\u4e0d\u9700\u8981\u5173\u5fc3\u591a\u9879\u96c6\u5b9e\u73b0\u7684\u7ec6\u8282\u3002 \u591a\u9879\u96c6\u4e5f\u88ab\u79f0\u4e3a\u62bd\u8c61\u6570\u636e\u7c7b\u578b\uff08Abstract Data Type\uff0cADT\uff09\u3002\u62bd\u8c61\u6570\u636e\u7c7b\u578b\u7684\u7528\u6237\u53ea\u5173\u6ce8\u5b83\u7684\u63a5\u53e3\u4ee5\u53ca\u8fd9\u4e2a\u7c7b\u578b\u5bf9\u8c61\u6240\u63d0\u4f9b\u7684\u4e00\u7ec4\u64cd\u4f5c\u3002 \u5728Python\u91cc\uff0c\u51fd\u6570\u548c\u65b9\u6cd5\u662f\u6700\u5c0f\u7684\u62bd\u8c61\u5355\u5143\uff0c\u7c7b\u7684\u5927\u5c0f\u6b21\u4e4b\uff0c\u6a21\u5757\u662f\u6700\u5927\u7684\u62bd\u8c61\u5355\u5143\u3002 \u8fd9\u91cc\u4f1a\u628a\u62bd\u8c61\u591a\u9879\u96c6\u7c7b\u578b\u7684\u5b9e\u73b0\u5f53\u4f5c\u6a21\u5757\u91cc\u7684\u7c7b\u6216\u8005\u4e00\u7ec4\u76f8\u5173\u7684\u7c7b\u52a0\u4ee5\u63cf\u8ff0\u3002\u6784\u5efa\u8fd9\u4e9b\u7c7b\u5c31\u662f\u9762\u5411\u5bf9\u8c61\u7f16\u7a0b\u3002 2.5.\u5c0f\u7ed3 \u00b6 \u591a\u9879\u96c6\u662f\u5305\u542b0\u4e2a\u6216\u591a\u4e2a\u5176\u4ed6\u5bf9\u8c61\u7684\u5bf9\u8c61\u3002\u591a\u9879\u96c6\u53ef\u4ee5\u8fdb\u884c\u7684\u64cd\u4f5c\u6709\u8bbf\u95ee\u5bf9\u8c61\u3001\u63d2\u5165\u5bf9\u8c61\u3001\u5220\u9664\u5bf9\u8c61\u3001\u786e\u5b9a\u591a\u9879\u96c6\u7684\u5927\u5c0f\uff0c\u4ee5\u53ca\u904d\u5386\u6216\u8bbf\u95ee\u8fd9\u4e2a\u591a\u9879\u96c6\u7684\u5bf9\u8c61\u3002 \u591a\u9879\u96c6\u76845\u4e2a\u4e3b\u8981\u7c7b\u578b\u662f\uff1a\u7ebf\u6027\u591a\u9879\u96c6\u3001\u5206\u5c42\u591a\u9879\u96c6\u3001\u56fe\u591a\u9879\u96c6\u3001\u65e0\u5e8f\u591a\u9879\u96c6\u548c\u6709\u5e8f\u591a\u9879\u96c6\u3002 \u7ebf\u6027\u591a\u9879\u96c6\u4f1a\u6309\u7167\u4f4d\u7f6e\u5bf9\u5143\u7d20\u8fdb\u884c\u6392\u5e8f\uff0c\u5176\u4e2d\u9664\u4e86\u7b2c\u4e00\u4e2a\u5143\u7d20\uff0c\u6bcf\u4e2a\u90fd\u6709\u4e14\u53ea\u6709\u4e00\u4e2a\u524d\u5e8f\uff1b\u9664\u4e86\u6700\u540e\u4e00\u4e2a\u5143\u7d20\uff0c\u6bcf\u4e2a\u90fd\u6709\u4e14\u53ea\u6709\u4e00\u4e2a\u540e\u5e8f\u3002 \u5728\u5206\u5c42\u591a\u9879\u96c6\u91cc\uff0c\u9664\u4e86\u4e00\u4e2a\u5143\u7d20\uff0c\u5176\u4ed6\u6240\u6709\u5143\u7d20\u90fd\u6709\u4e14\u53ea\u6709\u4e00\u4e2a\u524d\u5e8f\u4ee5\u53ca0\u4e2a\u6216\u591a\u4e2a\u540e\u5e8f\u3002\u88ab\u79f0\u4e3a\u6839\u7684\u90a3\u4e2a\u989d\u5916\u5143\u7d20\u6ca1\u6709\u524d\u5e8f\u3002 \u56fe\u591a\u9879\u96c6\u91cc\u7684\u5143\u7d20\u53ef\u4ee5\u67090\u4e2a\u6216\u591a\u4e2a\u524d\u5e8f\u4ee5\u53ca0\u4e2a\u6216\u591a\u4e2a\u540e\u5e8f\u3002 \u65e0\u5e8f\u591a\u9879\u96c6\u91cc\u7684\u5143\u7d20\u6ca1\u6709\u7279\u5b9a\u7684\u987a\u5e8f\u3002 \u591a\u9879\u96c6\u662f\u53ef\u8fed\u4ee3\u7684\uff0c\u4e5f\u5c31\u662f\u8bf4\uff0c\u53ef\u4ee5\u4f7f\u7528for\u5faa\u73af\u8bbf\u95ee\u591a\u9879\u96c6\u91cc\u7684\u6240\u6709\u5143\u7d20\u3002\u7a0b\u5e8f\u5458\u4e5f\u53ef\u4ee5\u4f7f\u7528\u9ad8\u9636\u51fd\u6570map\u3001filter\u548creduce\u7b80\u5316\u591a\u9879\u96c6\u7684\u6570\u636e\u5904\u7406\u3002 \u62bd\u8c61\u6570\u636e\u7c7b\u578b\u662f\u4e00\u7ec4\u5bf9\u8c61\u548c\u5bf9\u8fd9\u4e9b\u5bf9\u8c61\u7684\u64cd\u4f5c\u3002\u56e0\u6b64\uff0c\u591a\u9879\u96c6\u662f\u62bd\u8c61\u6570\u636e\u7c7b\u578b\u3002 \u6570\u636e\u7ed3\u6784\u662f\u4e00\u4e2a\u8868\u793a\u591a\u9879\u96c6\u91cc\u5305\u542b\u7684\u6570\u636e\u7684\u5bf9\u8c61\u3002 2.6.\u590d\u4e60\u9898 \u00b6 \u7ebf\u6027\u591a\u9879\u96c6\u7684\u4e00\u4e2a\u4f8b\u5b50\u662f\uff1a \u96c6\u5408\u548c\u6811 \u5217\u8868\u548c\u6808 \u65e0\u5e8f\u591a\u9879\u96c6\u7684\u4e00\u4e2a\u4f8b\u5b50\u662f\uff1a \u961f\u5217\u548c\u5217\u8868 \u96c6\u5408\u548c\u5b57\u5178 \u5206\u5c42\u591a\u9879\u96c6\u53ef\u4ee5\u7528\u6765\u8868\u793a\uff1a \u94f6\u884c\u6392\u961f\u7684\u5ba2\u6237 \u6587\u4ef6\u76ee\u5f55\u7cfb\u7edf \u56fe\u591a\u9879\u96c6\u6700\u80fd\u4ee3\u8868\uff1a \u4e00\u7ec4\u6570\u5b57 \u57ce\u5e02\u4e4b\u95f4\u7684\u822a\u7ebf\u56fe \u5728Python\u91cc\uff0c\u4e24\u4e2a\u591a\u9879\u96c6\u95f4\u7684\u7c7b\u578b\u8f6c\u6362\u64cd\u4f5c\uff1a \u5728\u6e90\u591a\u9879\u96c6\u91cc\u521b\u5efa\u5bf9\u8c61\u7684\u526f\u672c\uff0c\u5e76\u4e14\u628a\u8fd9\u4e9b\u65b0\u5bf9\u8c61\u6dfb\u52a0\u5230\u76ee\u6807\u591a\u9879\u96c6\u7684\u65b0\u5b9e\u4f8b\u91cc \u628a\u5bf9\u6e90\u591a\u9879\u96c6\u5bf9\u8c61\u7684\u5f15\u7528\u6dfb\u52a0\u5230\u76ee\u6807\u591a\u9879\u96c6\u7684\u65b0\u5b9e\u4f8b\u91cc \u4e24\u4e2a\u5217\u8868\u7684 == \u64cd\u4f5c\u5fc5\u987b\uff1a \u6bd4\u8f83\u6bcf\u4e2a\u4f4d\u7f6e\u7684\u5143\u7d20\u5bf9\u662f\u5426\u76f8\u7b49 \u53ea\u4f1a\u9a8c\u8bc1\u4e00\u4e2a\u5217\u8868\u91cc\u7684\u6bcf\u4e00\u4e2a\u5143\u7d20\u662f\u5426\u4e5f\u5728\u53e6\u4e00\u4e2a\u5217\u8868\u91cc \u4e24\u4e2a\u96c6\u5408\u7684 == \u64cd\u4f5c\u5fc5\u987b\uff1a \u6bd4\u8f83\u6bcf\u4e2a\u4f4d\u7f6e\u7684\u5143\u7d20\u5bf9\u662f\u5426\u76f8\u7b49 \u9a8c\u8bc1\u96c6\u5408\u7684\u5927\u5c0f\u662f\u5426\u76f8\u7b49\uff0c\u5e76\u4e14\u4e00\u4e2a\u96c6\u5408\u91cc\u7684\u6bcf\u4e00\u4e2a\u5143\u7d20\u662f\u5426\u4e5f\u5728\u53e6\u4e00\u4e2a\u96c6\u5408\u91cc \u5bf9\u5217\u8868\u8fdb\u884c for \u5faa\u73af\u65f6\uff0c\u8bbf\u95ee\u5143\u7d20\u7684\u987a\u5e8f\uff1a \u4ece\u5934\u5230\u5c3e\u7684\u6240\u6709\u4f4d\u7f6e \u4e0d\u4f1a\u6309\u7167\u7279\u5b9a\u7684\u987a\u5e8f map \u51fd\u6570\u4f1a\u521b\u5efa\u4e00\u4e2a\u4ec0\u4e48\u6837\u7684\u5e8f\u5217\uff1a \u5728\u7ed9\u5b9a\u7684\u591a\u9879\u96c6\u91cc\uff0c\u901a\u8fc7\u5e03\u5c14\u6d4b\u8bd5\u7684\u5143\u7d20 \u5728\u7ed9\u5b9a\u7684\u591a\u9879\u96c6\u91cc\uff0c\u5bf9\u5143\u7d20\u6267\u884c\u51fd\u6570\u7684\u7ed3\u679c filter \u51fd\u6570\u4f1a\u521b\u5efa\u4e00\u4e2a\u4ec0\u4e48\u6837\u7684\u5e8f\u5217\uff1a \u5728\u7ed9\u5b9a\u7684\u591a\u9879\u96c6\u91cc\uff0c\u901a\u8fc7\u5e03\u5c14\u6d4b\u8bd5\u7684\u5143\u7d20 \u5728\u7ed9\u5b9a\u7684\u591a\u9879\u96c6\u91cc\uff0c\u5bf9\u5143\u7d20\u6267\u884c\u51fd\u6570\u7684\u7ed3\u679c 2.7.\u7f16\u7a0b\u7ec3\u4e60 \u00b6 1\uff0e\u5728Shell\u7a97\u53e3\u7684\u63d0\u793a\u7b26\u4e0b\u4f7f\u7528 dir \u548c help \u51fd\u6570\u6765\u63a2\u7d22Python\u7684\u5185\u7f6e\u591a\u9879\u96c6\u7c7b\u578b str \u3001 list \u3001 tuple \u3001 set \u4ee5\u53ca dict \u7684\u63a5\u53e3\u3002\u5b83\u4eec\u7684\u8bed\u6cd5\u662f dir() \u548c help() \u3002 \u89e3\u7b54\uff1a \u53ef\u4ee5\u901a\u8fc7\u4ee5\u4e0b\u65b9\u5f0f\u6765\u4e86\u89e3\u5b83\u4eec\u7684\u63a5\u53e3\uff1a \u5b57\u7b26\u4e32 ( str ) \u7c7b\u578b\uff1a # \u4f7f\u7528 dir() \u51fd\u6570\u5217\u51fa\u5b57\u7b26\u4e32\u7c7b\u578b\u7684\u6240\u6709\u65b9\u6cd5\u548c\u5c5e\u6027 dir ( str ) # \u4f7f\u7528 help() \u51fd\u6570\u83b7\u53d6\u5173\u4e8e\u5b57\u7b26\u4e32\u7c7b\u578b\u7684\u8be6\u7ec6\u4fe1\u606f help ( str ) \u5217\u8868 ( list ) \u7c7b\u578b\uff1a # \u4f7f\u7528 dir() \u51fd\u6570\u5217\u51fa\u5217\u8868\u7c7b\u578b\u7684\u6240\u6709\u65b9\u6cd5\u548c\u5c5e\u6027 dir ( list ) x # \u4f7f\u7528 help() \u51fd\u6570\u83b7\u53d6\u5173\u4e8e\u5217\u8868\u7c7b\u578b\u7684\u8be6\u7ec6\u4fe1\u606f help ( list ) \u5143\u7ec4 ( tuple ) \u7c7b\u578b\uff1a # \u4f7f\u7528 dir() \u51fd\u6570\u5217\u51fa\u5143\u7ec4\u7c7b\u578b\u7684\u6240\u6709\u65b9\u6cd5\u548c\u5c5e\u6027 dir ( tuple ) # \u4f7f\u7528 help() \u51fd\u6570\u83b7\u53d6\u5173\u4e8e\u5143\u7ec4\u7c7b\u578b\u7684\u8be6\u7ec6\u4fe1\u606f help ( tuple ) \u96c6\u5408 ( set ) \u7c7b\u578b\uff1a # \u4f7f\u7528 dir() \u51fd\u6570\u5217\u51fa\u96c6\u5408\u7c7b\u578b\u7684\u6240\u6709\u65b9\u6cd5\u548c\u5c5e\u6027 dir ( set ) # \u4f7f\u7528 help() \u51fd\u6570\u83b7\u53d6\u5173\u4e8e\u96c6\u5408\u7c7b\u578b\u7684\u8be6\u7ec6\u4fe1\u606f help ( set ) \u5b57\u5178 ( dict ) \u7c7b\u578b\uff1a # \u4f7f\u7528 dir() \u51fd\u6570\u5217\u51fa\u5b57\u5178\u7c7b\u578b\u7684\u6240\u6709\u65b9\u6cd5\u548c\u5c5e\u6027 dir ( dict ) # \u4f7f\u7528 help() \u51fd\u6570\u83b7\u53d6\u5173\u4e8e\u5b57\u5178\u7c7b\u578b\u7684\u8be6\u7ec6\u4fe1\u606f help ( dict ) dir() \u51fd\u6570\u5c06\u8fd4\u56de\u4e00\u4e2a\u5305\u542b\u6240\u6709\u65b9\u6cd5\u548c\u5c5e\u6027\u540d\u79f0\u7684\u5217\u8868\uff0c\u800c help() \u51fd\u6570\u5c06\u663e\u793a\u5173\u4e8e\u8be5\u7c7b\u578b\u7684\u8be6\u7ec6\u5e2e\u52a9\u4fe1\u606f\uff0c\u5305\u62ec\u6bcf\u4e2a\u65b9\u6cd5\u7684\u8bf4\u660e\u548c\u7528\u6cd5\u793a\u4f8b\u3002 2\uff0e\u67e5\u770b java.util \u5305\u91cc\u6240\u63d0\u4f9b\u7684Java\u591a\u9879\u96c6\u7c7b\u578b\uff0c\u5e76\u548cPython\u7684\u591a\u9879\u96c6\u7c7b\u578b\u52a0\u4ee5\u6bd4\u8f83\u3002 java.util \u5305\u4e2d\u63d0\u4f9b\u4e86\u8bb8\u591aJava\u7684\u96c6\u5408\u7c7b\u578b\uff0c\u5305\u62ec\u5217\u8868\u3001\u96c6\u5408\u3001\u6620\u5c04\u7b49\u3002\u4e0b\u9762\u5c06\u5217\u51fa\u5176\u4e2d\u4e00\u4e9b\u5e38\u7528\u7684\u591a\u9879\u96c6\u7c7b\u578b\uff0c\u5e76\u5c06\u5b83\u4eec\u4e0ePython\u4e2d\u7684\u591a\u9879\u96c6\u7c7b\u578b\u8fdb\u884c\u6bd4\u8f83\u3002 Java ArrayList vs Python List: Java ArrayList \u662f\u4e00\u4e2a\u53ef\u53d8\u5927\u5c0f\u7684\u52a8\u6001\u6570\u7ec4\u3002 Python List \u4e5f\u662f\u53ef\u53d8\u5927\u5c0f\u7684\u52a8\u6001\u6570\u7ec4\uff0c\u53ef\u4ee5\u5bb9\u7eb3\u4efb\u610f\u7c7b\u578b\u7684\u6570\u636e\u3002 Java HashSet vs Python Set: Java HashSet \u662f\u4e00\u4e2a\u4e0d\u5141\u8bb8\u91cd\u590d\u5143\u7d20\u7684\u96c6\u5408\u3002 Python Set \u4e5f\u4e0d\u5141\u8bb8\u91cd\u590d\u5143\u7d20\uff0c\u540c\u65f6\u8fd8\u6709\u4e00\u4e2a\u7279\u6b8a\u7c7b\u578b\u7684\u96c6\u5408\u53eb\u505a frozenset \uff0c\u5b83\u662f\u4e0d\u53ef\u53d8\u7684\u3002 Java LinkedHashSet vs Python OrderedDict: Java LinkedHashSet \u662f\u4e00\u4e2a\u4fdd\u6301\u5143\u7d20\u63d2\u5165\u987a\u5e8f\u7684\u96c6\u5408\uff0c\u4e0d\u5141\u8bb8\u91cd\u590d\u5143\u7d20\u3002 Python OrderedDict \u662f\u4e00\u4e2a\u6709\u5e8f\u5b57\u5178\uff0c\u4fdd\u6301\u5143\u7d20\u63d2\u5165\u987a\u5e8f\uff0c\u53ef\u4ee5\u7528\u4e8e\u521b\u5efa\u6709\u5e8f\u7684\u952e-\u503c\u5bf9\u96c6\u5408\u3002 Java TreeSet vs Python SortedSet: Java TreeSet \u662f\u4e00\u4e2a\u81ea\u7136\u6392\u5e8f\u6216\u8005\u901a\u8fc7\u63d0\u4f9b\u7684\u6bd4\u8f83\u5668\u8fdb\u884c\u6392\u5e8f\u7684\u96c6\u5408\uff0c\u4e0d\u5141\u8bb8\u91cd\u590d\u5143\u7d20\u3002 Python \u6ca1\u6709\u4e13\u95e8\u7684 SortedSet \u7c7b\uff0c\u4f46\u4f60\u53ef\u4ee5\u4f7f\u7528 sorted() \u51fd\u6570\u5bf9\u96c6\u5408\u8fdb\u884c\u6392\u5e8f\u3002 Java HashMap vs Python Dictionary: Java HashMap \u662f\u4e00\u4e2a\u65e0\u5e8f\u7684\u952e-\u503c\u5bf9\u6620\u5c04\uff0c\u4e0d\u5141\u8bb8\u91cd\u590d\u952e\u3002 Python Dictionary \u662f\u4e00\u4e2a\u65e0\u5e8f\u7684\u952e-\u503c\u5bf9\u6620\u5c04\uff0c\u952e\u662f\u552f\u4e00\u7684\u3002 Java TreeMap vs Python OrderedDict: Java TreeMap \u662f\u4e00\u4e2a\u57fa\u4e8e\u7ea2\u9ed1\u6811\u7684\u6709\u5e8f\u6620\u5c04\u3002 Python OrderedDict \u5728\u952e\u7684\u63d2\u5165\u987a\u5e8f\u4e0a\u4fdd\u6301\u6709\u5e8f\u3002 Java \u7684\u591a\u9879\u96c6\u7c7b\u578b\u548c Python \u7684\u591a\u9879\u96c6\u7c7b\u578b\u5728\u529f\u80fd\u4e0a\u975e\u5e38\u7c7b\u4f3c\uff0c\u90fd\u63d0\u4f9b\u4e86\u5404\u79cd\u4e0d\u540c\u7684\u96c6\u5408\u7c7b\u578b\u6765\u9002\u5e94\u4e0d\u540c\u7684\u9700\u6c42\u3002\u9700\u8981\u6839\u636e\u5177\u4f53\u7684\u4f7f\u7528\u60c5\u51b5\u6765\u9009\u62e9\u54ea\u79cd\u96c6\u5408\u7c7b\u578b\u66f4\u9002\u5408\u3002\u540c\u65f6\uff0cPython \u8fd8\u63d0\u4f9b\u4e86\u65b9\u4fbf\u7684\u5217\u8868\u63a8\u5bfc\u3001\u96c6\u5408\u63a8\u5bfc\u548c\u5b57\u5178\u63a8\u5bfc\u7b49\u7279\u6027\uff0c\u53ef\u4ee5\u66f4\u52a0\u4fbf\u6377\u5730\u521b\u5efa\u548c\u5904\u7406\u591a\u9879\u96c6\u3002","title":"\u591a\u9879\u96c6\u7684\u6982\u8ff0"},{"location":"python/DataStructure/02_CollectionsOverview/#2","text":"\u591a\u9879\u96c6\uff08collection\uff09\u662f\u6307\u7531 0 \u4e2a\u6216\u8005\u591a\u4e2a\u5143\u7d20\u7ec4\u6210\u7684\u6982\u5ff5\u5355\u5143\u3002 \u4ece\u4e24\u4e2a\u89d2\u5ea6\u770b\u5f85\u591a\u9879\u96c6\uff1a \u591a\u9879\u96c6\u7684\u7528\u6237\u6216\u8005\u5ba2\u6237\u4f1a\u5173\u5fc3\u5b83\u4eec\u5728\u4e0d\u540c\u7684\u5e94\u7528\u7a0b\u5e8f\u91cc\u80fd\u505a\u4e9b\u4ec0\u4e48\u3002 \u591a\u9879\u96c6\u7684\u5f00\u53d1\u8005\u6216\u8005\u5b9e\u73b0\u8005\u5219\u4f1a\u5173\u5fc3\u5982\u4f55\u624d\u80fd\u8ba9\u5b83\u4eec\u6210\u4e3a\u6700\u597d\u7684\u901a\u7528\u8d44\u6e90\u4ee5\u88ab\u4f7f\u7528\u3002 \u76ee\u6807\uff1a \u5b9a\u4e49\u591a\u9879\u96c6\u76844\u4e2a\u901a\u7528\u7c7b\u578b\uff1a \u7ebf\u6027\u591a\u9879\u96c6 \u5206\u5c42\u591a\u9879\u96c6 \u56fe\u591a\u9879\u96c6 \u65e0\u5e8f\u591a\u9879\u96c6 \u4e86\u89e34\u4e2a\u591a\u9879\u96c6\u7c7b\u578b\u4e2d\u7684\u7279\u5b9a\u7c7b\u578b\uff1b \u4e86\u89e3\u8fd9\u4e9b\u591a\u9879\u96c6\u9002\u5408\u7528\u5728\u4ec0\u4e48\u7c7b\u578b\u7684\u5e94\u7528\u7a0b\u5e8f\u91cc\uff1b \u63cf\u8ff0\u6bcf\u79cd\u591a\u9879\u96c6\u7c7b\u578b\u7684\u5e38\u7528\u64cd\u4f5c\uff1b \u63cf\u8ff0\u591a\u9879\u96c6\u7684\u62bd\u8c61\u7c7b\u578b\u548c\u5b9e\u73b0\u4e4b\u95f4\u7684\u533a\u522b\uff1b","title":"2.\u591a\u9879\u96c6\u7684\u6982\u8ff0"},{"location":"python/DataStructure/02_CollectionsOverview/#21","text":"\u5185\u7f6e\u591a\u9879\u96c6\u7c7b\u578b\uff1a \u5b57\u7b26\u4e32 str \u5217\u8868 list \u5143\u7ec4 tuple \u96c6\u5408 set \u5b57\u5178 dict \u5176\u4ed6\u591a\u9879\u96c6\u7c7b\u578b\uff1a \u6808 \u961f\u5217 \u4f18\u5148\u961f\u5217 \u4e8c\u53c9\u67e5\u627e\u6811 \u5806 \u56fe \u5305 \u6709\u5e8f\u591a\u9879\u96c6 \u591a\u9879\u96c6\u901a\u5e38\u4e0d\u662f\u9759\u6001\uff08static\uff09\u7684\uff0c\u800c\u662f\u52a8\u6001\uff08dynamic\uff09\u7684\uff0c\u53ef\u4ee5\u6839\u636e\u9700\u8981\u6765\u6269\u5927\u6216\u8005\u7f29\u5c0f\u591a\u9879\u96c6\u3002 \u4e0d\u53ef\u53d8\u591a\u9879\u96c6\uff08immutable collection\uff09\u7684\u5185\u5bb9\u5728\u7a0b\u5e8f\u8fd0\u884c\u8fc7\u7a0b\u4e2d\u662f\u4e0d\u53ef\u6539\u53d8\u7684\uff08\u5143\u7d20\u4e0d\u53ef\u4ee5\u6dfb\u52a0\u3001\u5220\u9664\u6216\u8005\u66ff\u6362\uff09\uff0c\u6bd4\u5982\u5143\u7ec4tuple\u3002 \u53ef\u53d8\u591a\u9879\u96c6\uff08mutable collection\uff09\u91cc\u7684\u5185\u5bb9\u53ef\u4ee5\u5728\u7a0b\u5e8f\u7684\u6574\u4e2a\u8fd0\u884c\u8fc7\u7a0b\u4e2d\u88ab\u6539\u53d8\uff0c\u6bd4\u5982\u5b57\u7b26\u4e32\u3001\u5217\u8868list\u3002 \u591a\u9879\u96c6\u6309\u6784\u6210\u65b9\u5f0f\u5212\u5206\u7684\u7c7b\u578b\uff1a \u7ebf\u6027\u591a\u9879\u96c6 \u5206\u5c42\u591a\u9879\u96c6 \u56fe\u591a\u9879\u96c6 \u65e0\u5e8f\u591a\u9879\u96c6 \u6709\u5e8f\u591a\u9879\u96c6","title":"2.1.\u591a\u9879\u96c6\u7c7b\u578b"},{"location":"python/DataStructure/02_CollectionsOverview/#211","text":"\u7ebf\u6027\u591a\u9879\u96c6\uff08linear collection\uff09\u91cc\u7684\u5143\u7d20\u6309\u7167\u4f4d\u7f6e\u8fdb\u884c\u6392\u5217\u3002 \u9664\u4e86\u7b2c\u4e00\u4e2a\u5143\u7d20\uff0c\u5176\u4ed6\u6bcf\u4e2a\u5143\u7d20\u90fd\u6709\u4e14\u53ea\u6709\u4e00\u4e2a\u524d\u5e8f\uff1b \u9664\u4e86\u6700\u540e\u4e00\u4e2a\u5143\u7d20\uff0c\u5176\u4ed6\u6bcf\u4e2a\u5143\u7d20\u90fd\u6709\u4e14\u53ea\u6709\u4e00\u4e2a\u540e\u5e8f\uff1b \u5b9e\u4f8b\uff1a\u6392\u961f\u7684\u4eba\uff0c\u8d2d\u7269\u6e05\u5355\uff0c\u5806\u53e0\u5728\u4e00\u8d77\u7684\u9910\u76d8\u7b49\u3002","title":"2.1.1.\u7ebf\u6027\u591a\u9879\u96c6"},{"location":"python/DataStructure/02_CollectionsOverview/#212","text":"\u5206\u5c42\u591a\u9879\u96c6\uff08hierarchical collection\uff09\u91cc\u7684\u6570\u636e\u5143\u7d20\u4f1a\u4ee5\u7c7b\u4f3c\u4e8e\u5012\u7f6e\u7684\u6811\u7ed3\u6784\u8fdb\u884c\u6392\u5217\u3002\u9664\u4e86\u9876\u90e8\u7684\u6570\u636e\u5143\u7d20\uff0c\u5176\u4ed6\u6bcf\u4e2a\u6570\u636e\u5143\u7d20\u90fd\u6709\u4e14\u53ea\u6709\u4e00\u4e2a\u524d\u5e8f\uff0c\u88ab\u79f0\u4e3a\u7236\u5143\u7d20\uff08parent\uff09\uff0c\u4f46\u5b83\u4eec\u53ef\u4ee5\u6709\u8bb8\u591a\u7684\u540e\u5e8f\uff0c\u88ab\u79f0\u4e3a\u5b50\u5143\u7d20\uff08children\uff09\u3002 \u56fe\u4f8b\u4e2d\uff0c D3 \u7684\u524d\u5e8f\u7236\u5143\u7d20\u662f D1 \uff0c D3 \u7684\u540e\u7eed\u5b50\u5143\u7d20\u662f D4 \u3001 D5 \u3001 D6 \u3002 \u5b9e\u4f8b\uff1a\u6587\u4ef6\u76ee\u5f55\u7cfb\u7edf\u3001\u516c\u53f8\u7684\u7ec4\u7ec7\u67b6\u6784\u3001\u4e66\u7684\u76ee\u5f55\u7b49\u3002","title":"2.1.2.\u5206\u5c42\u591a\u9879\u96c6"},{"location":"python/DataStructure/02_CollectionsOverview/#213","text":"\u56fe\u591a\u9879\u96c6\uff08graph collection\uff09\u4e5f\u88ab\u79f0\u4e3a\u56fe\uff08graph\uff09\uff0c\u5b83\u662f\u8fd9\u6837\u4e00\u4e2a\u591a\u9879\u96c6\uff1a\u5b83\u7684\u6bcf\u4e00\u4e2a\u6570\u636e\u5143\u7d20\u90fd\u53ef\u4ee5\u6709\u591a\u4e2a\u524d\u5e8f\u548c\u591a\u4e2a\u540e\u5e8f\u3002 \u56fe\u4f8b\u4e2d\uff0c\u8fde\u63a5\u5230 D3 \u7684\u6240\u6709\u5143\u7d20\u4f1a\u88ab\u5f53\u4f5c\u5b83\u7684\u524d\u5e8f\u548c\u540e\u5e8f\uff0c\u5b83\u4eec\u4e5f\u56e0\u6b64\u88ab\u79f0\u4e3a D3 \u7684\u90bb\u5c45\u3002 \u5b9e\u4f8b\uff1a\u57ce\u5e02\u4e4b\u95f4\u7684\u822a\u7ebf\u56fe\u3001\u4e07\u7ef4\u7f51\u7b49\u3002","title":"2.1.3.\u56fe\u591a\u9879\u96c6"},{"location":"python/DataStructure/02_CollectionsOverview/#214","text":"\u65e0\u5e8f\u591a\u9879\u96c6\uff08unordered collection\uff09\u91cc\u7684\u5143\u7d20\u6ca1\u6709\u7279\u5b9a\u7684\u987a\u5e8f\uff0c\u5e76\u4e14\u4e0d\u4f1a\u7528\u4efb\u4f55\u660e\u786e\u7684\u65b9\u5f0f\u6765\u6307\u51fa\u5143\u7d20\u7684\u524d\u5e8f\u6216\u8005\u540e\u5e8f\u3002 \u5b9e\u4f8b\uff1a\u4e00\u888b\u5f39\u73e0\u7b49\u3002","title":"2.1.4.\u65e0\u5e8f\u591a\u9879\u96c6"},{"location":"python/DataStructure/02_CollectionsOverview/#215","text":"\u6709\u5e8f\u591a\u9879\u96c6\uff08sorted collection\uff09\u4f1a\u5bf9\u5b83\u91cc\u9762\u7684\u5143\u7d20\u8fdb\u884c\u81ea\u7136\u6392\u5e8f\uff08natural ordering\uff09\u3002 \u8981\u8fdb\u884c\u81ea\u7136\u6392\u5e8f\uff0c\u5c31\u5fc5\u987b\u8981\u6709\u89c4\u5219\u6765\u5bf9\u6709\u5e8f\u591a\u9879\u96c6\u91cc\u7684\u5143\u7d20\u52a0\u4ee5\u6bd4\u8f83\uff0c\u4f8b\u5982 item(i) <= item(i+1) \u8fd9\u6837\u7684\u2014\u2014\u89c4\u5219\u3002 \u6709\u5e8f\u5217\u8868\u662f\u6700\u5e38\u89c1\u7684\u6709\u5e8f\u591a\u9879\u96c6\u3002\u6709\u5e8f\u591a\u9879\u96c6\u4e0d\u4e00\u5b9a\u662f\u7ebf\u6027\u7684\u6216\u8005\u6309\u7167\u4f4d\u7f6e\u8fdb\u884c\u6392\u5e8f\u7684\u3002 \u5bf9\u4e8e\u96c6\u5408\u3001\u5305\u3001\u5b57\u5178\uff0c\u867d\u7136\u4e0d\u80fd\u6309\u7167\u4f4d\u7f6e\u6765\u8bbf\u95ee\u5b83\u4eec\u7684\u5143\u7d20\uff0c\u4f46\u5b83\u4eec\u90fd\u53ef\u4ee5\u662f\u6709\u5e8f\u7684\u3002 \u7279\u6b8a\u7684\u5206\u5c42\u591a\u9879\u96c6\u7c7b\u578b\uff08\u5982\u4e8c\u53c9\u67e5\u627e\u6811\uff09\u4e5f\u4f1a\u5bf9\u5176\u4e2d\u7684\u5143\u7d20\u8fdb\u884c\u81ea\u7136\u6392\u5e8f\u3002","title":"2.1.5.\u6709\u5e8f\u591a\u9879\u96c6"},{"location":"python/DataStructure/02_CollectionsOverview/#216","text":"\u4e0b\u9762\u5206\u7c7b\u91cc\u7684\u7c7b\u578b\u540d\u79f0\u6307\u7684\u5e76\u4e0d\u662f\u591a\u9879\u96c6\u7684\u7279\u5b9a\u5b9e\u73b0\u3002\u4e00\u79cd\u7279\u5b9a\u7c7b\u578b\u7684\u591a\u9879\u96c6\u53ef\u4ee5\u6709\u591a\u4e2a\u5b9e\u73b0\u3002 \u591a\u9879\u96c6 | ---\u56fe\u591a\u9879\u96c6 | ---\u5206\u5c42\u591a\u9879\u96c6 | | ---\u4e8c\u53c9\u67e5\u627e\u6811 | | ---\u5806 | ---\u7ebf\u6027\u591a\u9879\u96c6 | | ---\u5217\u8868 | | | ---\u6709\u5e8f\u5217\u8868 | | ---\u961f\u5217 | | | ---\u4f18\u5148\u5bf9\u5217 | | ---\u6808 | | ---\u5b57\u7b26\u4e32 | ---\u65e0\u5e8f\u591a\u9879\u96c6 | ---\u5305 | | ---\u6709\u5e8f\u5305 | ---\u5b57\u5178 | | ---\u6709\u5e8f\u5305 | ---\u96c6\u5408 | ---\u6709\u5e8f\u96c6\u5408","title":"2.1.6.\u591a\u9879\u96c6\u7c7b\u578b\u7684\u5206\u7c7b"},{"location":"python/DataStructure/02_CollectionsOverview/#22","text":"\u591a\u9879\u96c6\u64cd\u4f5c\u7c7b\u522b\uff1a \u786e\u5b9a\u5927\u5c0f\uff1a\u4f7f\u7528 len \u51fd\u6570\u83b7\u53d6\u5f53\u524d\u591a\u9879\u96c6\u91cc\u7684\u5143\u7d20\u6570\u91cf\u3002 \u68c0\u6d4b\u5143\u7d20\u6210\u5458\uff1a\u4f7f\u7528 in \u8fd0\u7b97\u7b26\u5728\u591a\u9879\u96c6\u91cc\u641c\u7d22\u6307\u5b9a\u7684\u76ee\u6807\u5143\u7d20\u3002\u5982\u679c\u627e\u5230\u4e86\u8fd9\u4e2a\u5143\u7d20\uff0c\u5219\u8fd4\u56deTrue\uff0c\u5426\u5219\u8fd4\u56deFalse\u3002 \u904d\u5386\u591a\u9879\u96c6\uff1a\u4f7f\u7528 for \u5faa\u73af\u8bbf\u95ee\u591a\u9879\u96c6\u91cc\u7684\u6b38\u4e00\u4e2a\u5143\u7d20\u3002\u5143\u7d20\u7684\u8bbf\u95ee\u987a\u5e8f\u53d6\u51b3\u4e8e\u591a\u9879\u96c6\u7684\u7c7b\u578b\u3002 \u83b7\u53d6\u591a\u9879\u96c6\u7684\u5b57\u7b26\u4e32\u8868\u793a\uff1a\u4f7f\u7528 str \u51fd\u6570\u83b7\u53d6\u591a\u9879\u96c6\u7684\u5b57\u7b26\u4e32\u8868\u793a\u3002 \u76f8\u7b49\u68c0\u6d4b\uff1a\u4f7f\u7528 == \u8fd0\u7b97\u7b26\u6765\u786e\u5b9a\u4e24\u4e2a\u591a\u9879\u96c6\u662f\u5426\u76f8\u7b49\u3002\u5982\u679c\u4e24\u4e2a\u591a\u9879\u96c6\u80b2\u6709\u76f8\u540c\u7684\u7c7b\u578b\uff0c\u5e76\u4e14\u5305\u542b\u76f8\u540c\u7684\u5143\u7d20\uff0c\u90a3\u4e48\u5b83\u4eec\u5c31\u662f\u76f8\u7b49\u7684\u3002\u6bd4\u8f83\u8fd9\u4e9b\u5143\u7d20\u5bf9\u7684\u987a\u5e8f\u53d6\u51b3\u4e8e\u591a\u9879\u96c6\u7684\u7c7b\u578b\u3002 \u8fde\u63a5\u4e24\u4e2a\u591a\u9879\u96c6\uff1a\u4f7f\u7528 + \u8fd0\u7b97\u7b26\u6765\u5f97\u5230\u4e00\u4e2a\u548c\u64cd\u4f5c\u6570\u76f8\u540c\u7c7b\u578b\u7684\u65b0\u591a\u9879\u96c6\uff0c\u5e76\u4e14\u5305\u542b\u4e24\u4e2a\u64cd\u4f5c\u6570\u91cc\u7684\u6240\u6709\u5143\u7d20\u3002 \u8f6c\u6362\u4e3a\u5176\u4ed6\u7c7b\u578b\u7684\u591a\u9879\u96c6\uff1a\u521b\u5efa\u4e00\u4e2a\u4e0e\u6e90\u591a\u9879\u96c6\u5177\u6709\u76f8\u540c\u5143\u7d20\u7684\u65b0\u591a\u9879\u96c6\u3002\u514b\u9686\u64cd\u4f5c\u65f6\u7c7b\u578b\u8f6c\u6362\u7684\u4e00\u79cd\u7279\u6b8a\u60c5\u51b5\uff0c\u56e0\u4e3a\u8f93\u5165\u8f93\u51fa\u7684\u4e24\u4e2a\u591a\u9879\u96c6\u5177\u6709\u76f8\u540c\u7c7b\u578b\u3002 \u63d2\u5165\u4e00\u4e2a\u5143\u7d20\uff1a\u5982\u679c\u53ef\u4ee5\uff0c\u5219\u5728\u7ed9\u5b9a\u7684\u4f4d\u7f6e\u5c06\u5bf9\u5e94\u7684\u5143\u7d20\u6dfb\u52a0\u5230\u591a\u9879\u96c6\u91cc\u3002 \u5220\u9664\u4e00\u4e2a\u5143\u7d20\uff1a\u5982\u679c\u53ef\u4ee5\uff0c\u5219\u5728\u7ed9\u5b9a\u7684\u4f4d\u7f6e\u5c06\u5bf9\u5e94\u7684\u5143\u7d20\u4ece\u591a\u9879\u96c6\u4e2d\u5220\u9664\u3002 \u66ff\u6362\u4e00\u4e2a\u5143\u7d20\uff1a\u5c06\u5220\u9664\u548c\u63d2\u5165\u5408\u5e76\u4e3a\u4e00\u9879\u64cd\u4f5c\u3002 \u8bbf\u95ee\u6216\u8005\u83b7\u53d6\u5143\u7d20\uff1a\u5982\u679c\u800c\u5df2\uff0c\u5219\u5728\u7ed9\u5b9a\u7684\u4f4d\u7f6e\u83b7\u53d6\u5143\u7d20\u3002","title":"2.2.\u591a\u9879\u96c6\u64cd\u4f5c"},{"location":"python/DataStructure/02_CollectionsOverview/#221","text":"\u5728Python\u91cc\uff0c\u4e0d\u540c\u591a\u9879\u96c6\u7c7b\u578b\u7684\u63d2\u5165\u3001\u5220\u9664\u3001\u66ff\u6362\u6216\u8005\u8bbf\u95ee\u64cd\u4f5c\u5e76\u6ca1\u6709\u7edf\u4e00\u7684\u540d\u79f0\uff0c\u4f46\u662f\u4f1a\u6709\u4e00\u4e9b\u6807\u51c6\u53d8\u4f53\u3002\u6bd4\u5982\uff0c \u65b9\u6cd5pop\u4f1a\u88ab\u7528\u6765\u4ece\u5217\u8868\u91cc\u79fb\u9664\u6307\u5b9a\u4f4d\u7f6e\u7684\u5143\u7d20\uff1b \u65b9\u6cd5pop\u4f1a\u88ab\u7528\u6765\u4ece\u5b57\u5178\u91cc\u79fb\u9664\u7ed9\u5b9a\u952e\u6240\u5bf9\u5e94\u7684\u503c\uff1b \u65b9\u6cd5remove\u4f1a\u88ab\u7528\u6765\u4ece\u5217\u8868\u6216\u8005\u67d0\u4e9b\u591a\u9879\u96c6\u91cc\u5220\u9664\u6307\u5b9a\u7684\u5143\u7d20\uff1b \u5bf9\u4e8e\u65b0\u5f00\u53d1\u51fa\u7684\u3001Python\u5c1a\u4e0d\u652f\u6301\u7684\u591a\u9879\u96c6\u7c7b\u578b\uff0c\u5c3d\u53ef\u80fd\u5730\u4f7f\u7528\u6807\u51c6\u7684\u8fd0\u7b97\u7b26\u3001\u51fd\u6570\u4ee5\u53ca\u65b9\u6cd5\u540d\u79f0\u5bf9\u5b83\u4eec\u8fdb\u884c\u64cd\u4f5c\u3002","title":"2.2.1.\u6240\u6709\u591a\u9879\u96c6\u7c7b\u578b\u4e2d\u7684\u57fa\u672c\u64cd\u4f5c"},{"location":"python/DataStructure/02_CollectionsOverview/#222","text":"\u7c7b\u578b\u8f6c\u6362\uff0c\u5c06\u4e00\u79cd\u7c7b\u578b\u7684\u591a\u9879\u96c6\u8f6c\u6362\u4e3a\u53e6\u4e00\u79cd\u7c7b\u578b\u7684\u591a\u9879\u96c6\u3002\u4f8b\u5982\uff0c\u901a\u8fc7 list \u6216 tuple \u51fd\u6570\u5c06\u5b57\u7b26\u4e32\u8f6c\u6362\u4e3a\u5217\u8868\u6216\u8005\u5143\u7ec4\u3002 list \u6216 tuple \u51fd\u6570\u7684\u53c2\u6570\u4e0d\u4e00\u5b9a\u662f\u53e6\u4e00\u4e2a\u591a\u9879\u96c6\uff0c\u4e5f\u53ef\u4ee5\u662f\u4efb\u4f55\u7684\u53ef\u8fed\u4ee3\u5bf9\u8c61\uff08iterable object\uff09\u3002 \u53ef\u8fed\u4ee3\u5bf9\u8c61\u662f\u6307\uff0c\u80fd\u591f\u4f7f\u7528for\u5faa\u73af\u6765\u8bbf\u95ee\u7684\u4e00\u7cfb\u5217\u5143\u7d20\u3002\uff08\u591a\u9879\u96c6\u672c\u8eab\u4e5f\u662f\u53ef\u8fed\u4ee3\u5bf9\u8c61\uff09","title":"2.2.2.\u7c7b\u578b\u8f6c\u6362"},{"location":"python/DataStructure/02_CollectionsOverview/#223","text":"\u7c7b\u578b\u8f6c\u6362\u7684\u4e00\u79cd\u7279\u6b8a\u60c5\u51b5\u662f\u514b\u9686\uff0c\u5b83\u7684\u529f\u80fd\u662f\u8fd4\u56de\u8f6c\u6362\u51fd\u6570\u4e2d\u53c2\u6570\u7684\u5b8c\u6574\u526f\u672c\u3002 \u4f8b\u5982\uff1a myList1 = [ 2 , 4 , 8 ] myList2 = list ( myList1 ) myList1 is myList2 # False myList1 == myList2 # True \u6ce8\u610f\uff1a \u4e0a\u9762\u4e24\u4e2a\u5217\u8868\u4e0d\u4ec5\u6709\u76f8\u540c\u7684\u7ed3\u6784\uff0c\u5b83\u4eec\u8fd8\u6709\u76f8\u540c\u7684\u5143\u7d20\uff0c\u6bcf\u5bf9\u5143\u7d20\u5728\u4e24\u4e2a\u5217\u8868\u91cc\u7684\u4f4d\u7f6e\u90fd\u76f8\u540c\u3002\u4f46\u662f\uff0c\u4ed6\u4eec\u662f\u4e24\u4e2a\u4e0d\u540c\u7684\u5bf9\u8c61\u3002 \u4e0a\u4f8b\u4e2d list \u51fd\u6570\u5bf9\u5b83\u7684\u53c2\u6570\u5217\u8868\u8fdb\u884c\u6d45\u62f7\u8d1d\uff08shallow copy\uff09\u3002\u8fd9\u4e9b\u5143\u7d20\u7684\u672c\u8eab\u5728\u6dfb\u52a0\u5230\u65b0\u5217\u8868\u4e4b\u524d\u662f\u4e0d\u4f1a\u88ab\u514b\u9686\u7684\uff0c\u5728\u8fd9\u4e2a\u8fc7\u7a0b\u4e2d\u53ea\u4f1a\u590d\u5236\u5bf9\u8fd9\u4e9b\u5bf9\u8c61\u7684\u5f15\u7528\u3002\u5f53\u5143\u7d20\uff08\u6570\u5b57\u3001\u5b57\u7b26\u4e32\u6216\u8005Python\u7684\u5143\u7ec4\uff09\u4e0d\u53ef\u53d8\u65f6\uff0c\u8fd9\u4e2a\u7b56\u7565\u4e0d\u4f1a\u5f15\u8d77\u95ee\u9898\u3002\u4f46\u662f\uff0c\u5982\u679c\u591a\u9879\u96c6\u5305\u542b\u7684\u662f\u53ef\u53d8\u5143\u7d20\uff0c\u5c31\u53ef\u80fd\u4f1a\u4ea7\u751f\u526f\u4f5c\u7528\u3002\u4e3a\u4e86\u907f\u514d\u8fd9\u79cd\u60c5\u51b5\u7684\u53d1\u751f\uff0c\u6211\u4eec\u53ef\u4ee5\u901a\u8fc7\u5bf9\u6e90\u591a\u9879\u96c6\u7f16\u5199 for \u5faa\u73af\u6765\u521b\u5efa\u6df1\u62f7\u8d1d\uff08deep copy\uff09\uff0c\u8fd9\u4f1a\u628a\u5143\u7d20\u663e\u5f0f\u5730\u514b\u9686\u4e4b\u540e\u518d\u6dfb\u52a0\u5230\u65b0\u7684\u591a\u9879\u96c6\u91cc\u3002","title":"2.2.3.\u514b\u9686\u548c\u76f8\u7b49\u6027"},{"location":"python/DataStructure/02_CollectionsOverview/#23","text":"\u6bcf\u79cd\u7c7b\u578b\u7684\u591a\u9879\u96c6\u90fd\u652f\u6301\u4e00\u4e2a\u8fed\u4ee3\u5668\u6216 for \u5faa\u73af\uff0c\u8fd9\u4e2a\u64cd\u4f5c\u80fd\u591f\u8fed\u4ee3\u8fd9\u4e2a\u591a\u9879\u96c6\u7684\u6240\u6709\u5143\u7d20\u3002\u8fed\u4ee3\u5668\u662f\u591a\u9879\u96c6\u63d0\u4f9b\u7684\u6700\u5173\u952e\u7684\u64cd\u4f5c\u3002 for \u5faa\u73af\u670d\u52a1\u7684\u591a\u9879\u96c6\u4e2d\u5143\u7d20\u7684\u987a\u5e8f\u53d6\u51b3\u4e8e\u591a\u9879\u96c6\u7684\u7ec4\u7ec7\u65b9\u5f0f\u3002\u4f8b\u5982\uff1a \u5217\u8868\u91cc\u7684\u5143\u7d20\u4f1a\u4ece\u5934\u5230\u5c3e\u6309\u7167\u4f4d\u7f6e\u8fdb\u884c\u8bbf\u95ee\uff1b \u6709\u5e8f\u591a\u9879\u96c6\u91cc\u7684\u5143\u7d20\u4f1a\u6309\u4ece\u5c0f\u5230\u5927\u7684\u5347\u5e8f\u8fdb\u884c\u8bbf\u95ee\uff1b \u5bf9\u4e8e\u96c6\u5408\u6216\u8005\u5b57\u5178\u91cc\u7684\u5143\u7d20\u6765\u8bf4\uff0c\u4e0d\u4f1a\u6309\u7167\u7279\u5b9a\u7684\u987a\u5e8f\u8fdb\u884c\u8bbf\u95ee\u3002 \u8fed\u4ee3\u5668\uff08\u4f8b\u5982 for \u5faa\u73af\uff09\u8fd8\u652f\u6301\u4f7f\u7528\u9ad8\u9636\u51fd\u6570 map \u3001 filter \u548c reduce \u3002 \u8fd9\u4e9b\u9ad8\u9636\u51fd\u6570\u90fd\u4f7f\u7528\u53e6\u4e00\u4e2a\u51fd\u6570\u548c\u4e00\u4e2a\u591a\u9879\u96c6\u4f5c\u4e3a\u53c2\u6570\u3002 \u591a\u9879\u96c6\u90fd\u652f\u6301 for \u5faa\u73af\uff0c\u6240\u4ee5 map \u3001 filter \u548c reduce \u51fd\u6570\u53ef\u4ee5\u4e0e\u4efb\u4f55\u7c7b\u578b\u7684\u591a\u9879\u96c6\u4e00\u8d77\u4f7f\u7528\u3002","title":"2.3.\u8fed\u4ee3\u5668\u548c\u9ad8\u9636\u51fd\u6570"},{"location":"python/DataStructure/02_CollectionsOverview/#24","text":"\u4ece\u7528\u6237\uff08\u6bd4\u5982\uff0c\u7a0b\u5e8f\u5458\uff09\u7684\u89d2\u5ea6\u6765\u770b\uff0c\u591a\u9879\u96c6\u662f\u4e00\u79cd\u62bd\u8c61\uff0c\u662f\u4e00\u79cd\u4ee5\u67d0\u79cd\u9884\u5b9a\u884c\u4e3a\u6765\u5b58\u50a8\u548c\u8bbf\u95ee\u6570\u636e\u5143\u7d20\u7684\u65b9\u5f0f\uff0c\u5e76\u4e0d\u9700\u8981\u5173\u5fc3\u591a\u9879\u96c6\u5b9e\u73b0\u7684\u7ec6\u8282\u3002 \u591a\u9879\u96c6\u4e5f\u88ab\u79f0\u4e3a\u62bd\u8c61\u6570\u636e\u7c7b\u578b\uff08Abstract Data Type\uff0cADT\uff09\u3002\u62bd\u8c61\u6570\u636e\u7c7b\u578b\u7684\u7528\u6237\u53ea\u5173\u6ce8\u5b83\u7684\u63a5\u53e3\u4ee5\u53ca\u8fd9\u4e2a\u7c7b\u578b\u5bf9\u8c61\u6240\u63d0\u4f9b\u7684\u4e00\u7ec4\u64cd\u4f5c\u3002 \u5728Python\u91cc\uff0c\u51fd\u6570\u548c\u65b9\u6cd5\u662f\u6700\u5c0f\u7684\u62bd\u8c61\u5355\u5143\uff0c\u7c7b\u7684\u5927\u5c0f\u6b21\u4e4b\uff0c\u6a21\u5757\u662f\u6700\u5927\u7684\u62bd\u8c61\u5355\u5143\u3002 \u8fd9\u91cc\u4f1a\u628a\u62bd\u8c61\u591a\u9879\u96c6\u7c7b\u578b\u7684\u5b9e\u73b0\u5f53\u4f5c\u6a21\u5757\u91cc\u7684\u7c7b\u6216\u8005\u4e00\u7ec4\u76f8\u5173\u7684\u7c7b\u52a0\u4ee5\u63cf\u8ff0\u3002\u6784\u5efa\u8fd9\u4e9b\u7c7b\u5c31\u662f\u9762\u5411\u5bf9\u8c61\u7f16\u7a0b\u3002","title":"2.4.\u591a\u9879\u96c6\u7684\u5b9e\u73b0"},{"location":"python/DataStructure/02_CollectionsOverview/#25","text":"\u591a\u9879\u96c6\u662f\u5305\u542b0\u4e2a\u6216\u591a\u4e2a\u5176\u4ed6\u5bf9\u8c61\u7684\u5bf9\u8c61\u3002\u591a\u9879\u96c6\u53ef\u4ee5\u8fdb\u884c\u7684\u64cd\u4f5c\u6709\u8bbf\u95ee\u5bf9\u8c61\u3001\u63d2\u5165\u5bf9\u8c61\u3001\u5220\u9664\u5bf9\u8c61\u3001\u786e\u5b9a\u591a\u9879\u96c6\u7684\u5927\u5c0f\uff0c\u4ee5\u53ca\u904d\u5386\u6216\u8bbf\u95ee\u8fd9\u4e2a\u591a\u9879\u96c6\u7684\u5bf9\u8c61\u3002 \u591a\u9879\u96c6\u76845\u4e2a\u4e3b\u8981\u7c7b\u578b\u662f\uff1a\u7ebf\u6027\u591a\u9879\u96c6\u3001\u5206\u5c42\u591a\u9879\u96c6\u3001\u56fe\u591a\u9879\u96c6\u3001\u65e0\u5e8f\u591a\u9879\u96c6\u548c\u6709\u5e8f\u591a\u9879\u96c6\u3002 \u7ebf\u6027\u591a\u9879\u96c6\u4f1a\u6309\u7167\u4f4d\u7f6e\u5bf9\u5143\u7d20\u8fdb\u884c\u6392\u5e8f\uff0c\u5176\u4e2d\u9664\u4e86\u7b2c\u4e00\u4e2a\u5143\u7d20\uff0c\u6bcf\u4e2a\u90fd\u6709\u4e14\u53ea\u6709\u4e00\u4e2a\u524d\u5e8f\uff1b\u9664\u4e86\u6700\u540e\u4e00\u4e2a\u5143\u7d20\uff0c\u6bcf\u4e2a\u90fd\u6709\u4e14\u53ea\u6709\u4e00\u4e2a\u540e\u5e8f\u3002 \u5728\u5206\u5c42\u591a\u9879\u96c6\u91cc\uff0c\u9664\u4e86\u4e00\u4e2a\u5143\u7d20\uff0c\u5176\u4ed6\u6240\u6709\u5143\u7d20\u90fd\u6709\u4e14\u53ea\u6709\u4e00\u4e2a\u524d\u5e8f\u4ee5\u53ca0\u4e2a\u6216\u591a\u4e2a\u540e\u5e8f\u3002\u88ab\u79f0\u4e3a\u6839\u7684\u90a3\u4e2a\u989d\u5916\u5143\u7d20\u6ca1\u6709\u524d\u5e8f\u3002 \u56fe\u591a\u9879\u96c6\u91cc\u7684\u5143\u7d20\u53ef\u4ee5\u67090\u4e2a\u6216\u591a\u4e2a\u524d\u5e8f\u4ee5\u53ca0\u4e2a\u6216\u591a\u4e2a\u540e\u5e8f\u3002 \u65e0\u5e8f\u591a\u9879\u96c6\u91cc\u7684\u5143\u7d20\u6ca1\u6709\u7279\u5b9a\u7684\u987a\u5e8f\u3002 \u591a\u9879\u96c6\u662f\u53ef\u8fed\u4ee3\u7684\uff0c\u4e5f\u5c31\u662f\u8bf4\uff0c\u53ef\u4ee5\u4f7f\u7528for\u5faa\u73af\u8bbf\u95ee\u591a\u9879\u96c6\u91cc\u7684\u6240\u6709\u5143\u7d20\u3002\u7a0b\u5e8f\u5458\u4e5f\u53ef\u4ee5\u4f7f\u7528\u9ad8\u9636\u51fd\u6570map\u3001filter\u548creduce\u7b80\u5316\u591a\u9879\u96c6\u7684\u6570\u636e\u5904\u7406\u3002 \u62bd\u8c61\u6570\u636e\u7c7b\u578b\u662f\u4e00\u7ec4\u5bf9\u8c61\u548c\u5bf9\u8fd9\u4e9b\u5bf9\u8c61\u7684\u64cd\u4f5c\u3002\u56e0\u6b64\uff0c\u591a\u9879\u96c6\u662f\u62bd\u8c61\u6570\u636e\u7c7b\u578b\u3002 \u6570\u636e\u7ed3\u6784\u662f\u4e00\u4e2a\u8868\u793a\u591a\u9879\u96c6\u91cc\u5305\u542b\u7684\u6570\u636e\u7684\u5bf9\u8c61\u3002","title":"2.5.\u5c0f\u7ed3"},{"location":"python/DataStructure/02_CollectionsOverview/#26","text":"\u7ebf\u6027\u591a\u9879\u96c6\u7684\u4e00\u4e2a\u4f8b\u5b50\u662f\uff1a \u96c6\u5408\u548c\u6811 \u5217\u8868\u548c\u6808 \u65e0\u5e8f\u591a\u9879\u96c6\u7684\u4e00\u4e2a\u4f8b\u5b50\u662f\uff1a \u961f\u5217\u548c\u5217\u8868 \u96c6\u5408\u548c\u5b57\u5178 \u5206\u5c42\u591a\u9879\u96c6\u53ef\u4ee5\u7528\u6765\u8868\u793a\uff1a \u94f6\u884c\u6392\u961f\u7684\u5ba2\u6237 \u6587\u4ef6\u76ee\u5f55\u7cfb\u7edf \u56fe\u591a\u9879\u96c6\u6700\u80fd\u4ee3\u8868\uff1a \u4e00\u7ec4\u6570\u5b57 \u57ce\u5e02\u4e4b\u95f4\u7684\u822a\u7ebf\u56fe \u5728Python\u91cc\uff0c\u4e24\u4e2a\u591a\u9879\u96c6\u95f4\u7684\u7c7b\u578b\u8f6c\u6362\u64cd\u4f5c\uff1a \u5728\u6e90\u591a\u9879\u96c6\u91cc\u521b\u5efa\u5bf9\u8c61\u7684\u526f\u672c\uff0c\u5e76\u4e14\u628a\u8fd9\u4e9b\u65b0\u5bf9\u8c61\u6dfb\u52a0\u5230\u76ee\u6807\u591a\u9879\u96c6\u7684\u65b0\u5b9e\u4f8b\u91cc \u628a\u5bf9\u6e90\u591a\u9879\u96c6\u5bf9\u8c61\u7684\u5f15\u7528\u6dfb\u52a0\u5230\u76ee\u6807\u591a\u9879\u96c6\u7684\u65b0\u5b9e\u4f8b\u91cc \u4e24\u4e2a\u5217\u8868\u7684 == \u64cd\u4f5c\u5fc5\u987b\uff1a \u6bd4\u8f83\u6bcf\u4e2a\u4f4d\u7f6e\u7684\u5143\u7d20\u5bf9\u662f\u5426\u76f8\u7b49 \u53ea\u4f1a\u9a8c\u8bc1\u4e00\u4e2a\u5217\u8868\u91cc\u7684\u6bcf\u4e00\u4e2a\u5143\u7d20\u662f\u5426\u4e5f\u5728\u53e6\u4e00\u4e2a\u5217\u8868\u91cc \u4e24\u4e2a\u96c6\u5408\u7684 == \u64cd\u4f5c\u5fc5\u987b\uff1a \u6bd4\u8f83\u6bcf\u4e2a\u4f4d\u7f6e\u7684\u5143\u7d20\u5bf9\u662f\u5426\u76f8\u7b49 \u9a8c\u8bc1\u96c6\u5408\u7684\u5927\u5c0f\u662f\u5426\u76f8\u7b49\uff0c\u5e76\u4e14\u4e00\u4e2a\u96c6\u5408\u91cc\u7684\u6bcf\u4e00\u4e2a\u5143\u7d20\u662f\u5426\u4e5f\u5728\u53e6\u4e00\u4e2a\u96c6\u5408\u91cc \u5bf9\u5217\u8868\u8fdb\u884c for \u5faa\u73af\u65f6\uff0c\u8bbf\u95ee\u5143\u7d20\u7684\u987a\u5e8f\uff1a \u4ece\u5934\u5230\u5c3e\u7684\u6240\u6709\u4f4d\u7f6e \u4e0d\u4f1a\u6309\u7167\u7279\u5b9a\u7684\u987a\u5e8f map \u51fd\u6570\u4f1a\u521b\u5efa\u4e00\u4e2a\u4ec0\u4e48\u6837\u7684\u5e8f\u5217\uff1a \u5728\u7ed9\u5b9a\u7684\u591a\u9879\u96c6\u91cc\uff0c\u901a\u8fc7\u5e03\u5c14\u6d4b\u8bd5\u7684\u5143\u7d20 \u5728\u7ed9\u5b9a\u7684\u591a\u9879\u96c6\u91cc\uff0c\u5bf9\u5143\u7d20\u6267\u884c\u51fd\u6570\u7684\u7ed3\u679c filter \u51fd\u6570\u4f1a\u521b\u5efa\u4e00\u4e2a\u4ec0\u4e48\u6837\u7684\u5e8f\u5217\uff1a \u5728\u7ed9\u5b9a\u7684\u591a\u9879\u96c6\u91cc\uff0c\u901a\u8fc7\u5e03\u5c14\u6d4b\u8bd5\u7684\u5143\u7d20 \u5728\u7ed9\u5b9a\u7684\u591a\u9879\u96c6\u91cc\uff0c\u5bf9\u5143\u7d20\u6267\u884c\u51fd\u6570\u7684\u7ed3\u679c","title":"2.6.\u590d\u4e60\u9898"},{"location":"python/DataStructure/02_CollectionsOverview/#27","text":"1\uff0e\u5728Shell\u7a97\u53e3\u7684\u63d0\u793a\u7b26\u4e0b\u4f7f\u7528 dir \u548c help \u51fd\u6570\u6765\u63a2\u7d22Python\u7684\u5185\u7f6e\u591a\u9879\u96c6\u7c7b\u578b str \u3001 list \u3001 tuple \u3001 set \u4ee5\u53ca dict \u7684\u63a5\u53e3\u3002\u5b83\u4eec\u7684\u8bed\u6cd5\u662f dir() \u548c help() \u3002 \u89e3\u7b54\uff1a \u53ef\u4ee5\u901a\u8fc7\u4ee5\u4e0b\u65b9\u5f0f\u6765\u4e86\u89e3\u5b83\u4eec\u7684\u63a5\u53e3\uff1a \u5b57\u7b26\u4e32 ( str ) \u7c7b\u578b\uff1a # \u4f7f\u7528 dir() \u51fd\u6570\u5217\u51fa\u5b57\u7b26\u4e32\u7c7b\u578b\u7684\u6240\u6709\u65b9\u6cd5\u548c\u5c5e\u6027 dir ( str ) # \u4f7f\u7528 help() \u51fd\u6570\u83b7\u53d6\u5173\u4e8e\u5b57\u7b26\u4e32\u7c7b\u578b\u7684\u8be6\u7ec6\u4fe1\u606f help ( str ) \u5217\u8868 ( list ) \u7c7b\u578b\uff1a # \u4f7f\u7528 dir() \u51fd\u6570\u5217\u51fa\u5217\u8868\u7c7b\u578b\u7684\u6240\u6709\u65b9\u6cd5\u548c\u5c5e\u6027 dir ( list ) x # \u4f7f\u7528 help() \u51fd\u6570\u83b7\u53d6\u5173\u4e8e\u5217\u8868\u7c7b\u578b\u7684\u8be6\u7ec6\u4fe1\u606f help ( list ) \u5143\u7ec4 ( tuple ) \u7c7b\u578b\uff1a # \u4f7f\u7528 dir() \u51fd\u6570\u5217\u51fa\u5143\u7ec4\u7c7b\u578b\u7684\u6240\u6709\u65b9\u6cd5\u548c\u5c5e\u6027 dir ( tuple ) # \u4f7f\u7528 help() \u51fd\u6570\u83b7\u53d6\u5173\u4e8e\u5143\u7ec4\u7c7b\u578b\u7684\u8be6\u7ec6\u4fe1\u606f help ( tuple ) \u96c6\u5408 ( set ) \u7c7b\u578b\uff1a # \u4f7f\u7528 dir() \u51fd\u6570\u5217\u51fa\u96c6\u5408\u7c7b\u578b\u7684\u6240\u6709\u65b9\u6cd5\u548c\u5c5e\u6027 dir ( set ) # \u4f7f\u7528 help() \u51fd\u6570\u83b7\u53d6\u5173\u4e8e\u96c6\u5408\u7c7b\u578b\u7684\u8be6\u7ec6\u4fe1\u606f help ( set ) \u5b57\u5178 ( dict ) \u7c7b\u578b\uff1a # \u4f7f\u7528 dir() \u51fd\u6570\u5217\u51fa\u5b57\u5178\u7c7b\u578b\u7684\u6240\u6709\u65b9\u6cd5\u548c\u5c5e\u6027 dir ( dict ) # \u4f7f\u7528 help() \u51fd\u6570\u83b7\u53d6\u5173\u4e8e\u5b57\u5178\u7c7b\u578b\u7684\u8be6\u7ec6\u4fe1\u606f help ( dict ) dir() \u51fd\u6570\u5c06\u8fd4\u56de\u4e00\u4e2a\u5305\u542b\u6240\u6709\u65b9\u6cd5\u548c\u5c5e\u6027\u540d\u79f0\u7684\u5217\u8868\uff0c\u800c help() \u51fd\u6570\u5c06\u663e\u793a\u5173\u4e8e\u8be5\u7c7b\u578b\u7684\u8be6\u7ec6\u5e2e\u52a9\u4fe1\u606f\uff0c\u5305\u62ec\u6bcf\u4e2a\u65b9\u6cd5\u7684\u8bf4\u660e\u548c\u7528\u6cd5\u793a\u4f8b\u3002 2\uff0e\u67e5\u770b java.util \u5305\u91cc\u6240\u63d0\u4f9b\u7684Java\u591a\u9879\u96c6\u7c7b\u578b\uff0c\u5e76\u548cPython\u7684\u591a\u9879\u96c6\u7c7b\u578b\u52a0\u4ee5\u6bd4\u8f83\u3002 java.util \u5305\u4e2d\u63d0\u4f9b\u4e86\u8bb8\u591aJava\u7684\u96c6\u5408\u7c7b\u578b\uff0c\u5305\u62ec\u5217\u8868\u3001\u96c6\u5408\u3001\u6620\u5c04\u7b49\u3002\u4e0b\u9762\u5c06\u5217\u51fa\u5176\u4e2d\u4e00\u4e9b\u5e38\u7528\u7684\u591a\u9879\u96c6\u7c7b\u578b\uff0c\u5e76\u5c06\u5b83\u4eec\u4e0ePython\u4e2d\u7684\u591a\u9879\u96c6\u7c7b\u578b\u8fdb\u884c\u6bd4\u8f83\u3002 Java ArrayList vs Python List: Java ArrayList \u662f\u4e00\u4e2a\u53ef\u53d8\u5927\u5c0f\u7684\u52a8\u6001\u6570\u7ec4\u3002 Python List \u4e5f\u662f\u53ef\u53d8\u5927\u5c0f\u7684\u52a8\u6001\u6570\u7ec4\uff0c\u53ef\u4ee5\u5bb9\u7eb3\u4efb\u610f\u7c7b\u578b\u7684\u6570\u636e\u3002 Java HashSet vs Python Set: Java HashSet \u662f\u4e00\u4e2a\u4e0d\u5141\u8bb8\u91cd\u590d\u5143\u7d20\u7684\u96c6\u5408\u3002 Python Set \u4e5f\u4e0d\u5141\u8bb8\u91cd\u590d\u5143\u7d20\uff0c\u540c\u65f6\u8fd8\u6709\u4e00\u4e2a\u7279\u6b8a\u7c7b\u578b\u7684\u96c6\u5408\u53eb\u505a frozenset \uff0c\u5b83\u662f\u4e0d\u53ef\u53d8\u7684\u3002 Java LinkedHashSet vs Python OrderedDict: Java LinkedHashSet \u662f\u4e00\u4e2a\u4fdd\u6301\u5143\u7d20\u63d2\u5165\u987a\u5e8f\u7684\u96c6\u5408\uff0c\u4e0d\u5141\u8bb8\u91cd\u590d\u5143\u7d20\u3002 Python OrderedDict \u662f\u4e00\u4e2a\u6709\u5e8f\u5b57\u5178\uff0c\u4fdd\u6301\u5143\u7d20\u63d2\u5165\u987a\u5e8f\uff0c\u53ef\u4ee5\u7528\u4e8e\u521b\u5efa\u6709\u5e8f\u7684\u952e-\u503c\u5bf9\u96c6\u5408\u3002 Java TreeSet vs Python SortedSet: Java TreeSet \u662f\u4e00\u4e2a\u81ea\u7136\u6392\u5e8f\u6216\u8005\u901a\u8fc7\u63d0\u4f9b\u7684\u6bd4\u8f83\u5668\u8fdb\u884c\u6392\u5e8f\u7684\u96c6\u5408\uff0c\u4e0d\u5141\u8bb8\u91cd\u590d\u5143\u7d20\u3002 Python \u6ca1\u6709\u4e13\u95e8\u7684 SortedSet \u7c7b\uff0c\u4f46\u4f60\u53ef\u4ee5\u4f7f\u7528 sorted() \u51fd\u6570\u5bf9\u96c6\u5408\u8fdb\u884c\u6392\u5e8f\u3002 Java HashMap vs Python Dictionary: Java HashMap \u662f\u4e00\u4e2a\u65e0\u5e8f\u7684\u952e-\u503c\u5bf9\u6620\u5c04\uff0c\u4e0d\u5141\u8bb8\u91cd\u590d\u952e\u3002 Python Dictionary \u662f\u4e00\u4e2a\u65e0\u5e8f\u7684\u952e-\u503c\u5bf9\u6620\u5c04\uff0c\u952e\u662f\u552f\u4e00\u7684\u3002 Java TreeMap vs Python OrderedDict: Java TreeMap \u662f\u4e00\u4e2a\u57fa\u4e8e\u7ea2\u9ed1\u6811\u7684\u6709\u5e8f\u6620\u5c04\u3002 Python OrderedDict \u5728\u952e\u7684\u63d2\u5165\u987a\u5e8f\u4e0a\u4fdd\u6301\u6709\u5e8f\u3002 Java \u7684\u591a\u9879\u96c6\u7c7b\u578b\u548c Python \u7684\u591a\u9879\u96c6\u7c7b\u578b\u5728\u529f\u80fd\u4e0a\u975e\u5e38\u7c7b\u4f3c\uff0c\u90fd\u63d0\u4f9b\u4e86\u5404\u79cd\u4e0d\u540c\u7684\u96c6\u5408\u7c7b\u578b\u6765\u9002\u5e94\u4e0d\u540c\u7684\u9700\u6c42\u3002\u9700\u8981\u6839\u636e\u5177\u4f53\u7684\u4f7f\u7528\u60c5\u51b5\u6765\u9009\u62e9\u54ea\u79cd\u96c6\u5408\u7c7b\u578b\u66f4\u9002\u5408\u3002\u540c\u65f6\uff0cPython \u8fd8\u63d0\u4f9b\u4e86\u65b9\u4fbf\u7684\u5217\u8868\u63a8\u5bfc\u3001\u96c6\u5408\u63a8\u5bfc\u548c\u5b57\u5178\u63a8\u5bfc\u7b49\u7279\u6027\uff0c\u53ef\u4ee5\u66f4\u52a0\u4fbf\u6377\u5730\u521b\u5efa\u548c\u5904\u7406\u591a\u9879\u96c6\u3002","title":"2.7.\u7f16\u7a0b\u7ec3\u4e60"},{"location":"python/DataStructure/03_TimeComplexity/","text":"3.\u641c\u7d22\u3001\u6392\u5e8f\u4ee5\u53ca\u590d\u6742\u5ea6\u5206\u6790 \u00b6 \u7b97\u6cd5\u63cf\u8ff0\u4e86\u4e00\u4e2a\u968f\u7740\u95ee\u9898\u88ab\u89e3\u51b3\u800c\u505c\u6b62\u7684\u8ba1\u7b97\u8fc7\u7a0b\u3002 \u7b97\u6cd5\u662f\u8ba1\u7b97\u673a\u7a0b\u5e8f\u7684\u57fa\u672c\u7ec4\u6210\u90e8\u5206\u4e4b\u4e00\uff0c\u53e6\u4e00\u4e2a\u57fa\u672c\u7ec4\u6210\u90e8\u5206\u662f\u6570\u636e\u7ed3\u6784\u3002 \u5728\u7b97\u6cd5\u6267\u884c\u8fc7\u7a0b\u4e2d\u4f1a\u6d88\u8017\u4e24\u4e2a\u8d44\u6e90\uff1a\u5904\u7406\u5bf9\u8c61\u6240\u9700\u7684\u65f6\u95f4\u548c\u7a7a\u95f4\uff08\u4e5f\u5c31\u662f\u5185\u5b58\uff09\u3002\u5bf9\u4e8e\u7b97\u6cd5\u6765\u8bf4\uff0c\u603b\u4f1a\u8ffd\u6c42\u6d88\u8017\u66f4\u77ed\u7684\u65f6\u95f4\u548c\u5360\u7528\u66f4\u5c11\u7684\u7a7a\u95f4\u3002\u5728\u9009\u62e9\u7b97\u6cd5\u65f6\uff0c\u901a\u5e38\u5728\u7a7a\u95f4/\u65f6\u95f4\u4e4b\u95f4\u8fdb\u884c\u6743\u8861\u3002 \u7b97\u6cd5\u8d28\u91cf\u7684\u4e3b\u8981\u8bc4\u4f30\u6807\u51c6\uff1a \u6b63\u786e\u6027\uff0c\u5373\u7b97\u6cd5\u80fd\u591f\u771f\u6b63\u89e3\u51b3\u6240\u9488\u5bf9\u7684\u95ee\u9898\uff1b \u53ef\u8bfb\u6027\u548c\u6613\u4e8e\u7ef4\u62a4\u6027\uff1b \u8fd0\u884c\u65f6\u6027\u80fd\uff1b \u76ee\u6807\uff1a \u6839\u636e\u95ee\u9898\u7684\u89c4\u6a21\u786e\u5b9a\u7b97\u6cd5\u5de5\u4f5c\u91cf\u7684\u589e\u957f\u7387\uff1b \u4f7f\u7528\u5927O\u8868\u793a\u6cd5\u6765\u63cf\u8ff0\u7b97\u6cd5\u7684\u8fd0\u884c\u65f6\u548c\u5185\u5b58\u4f7f\u7528\u60c5\u51b5\uff1b \u8ba4\u8bc6\u5e38\u89c1\u7684\u5de5\u4f5c\u91cf\u589e\u957f\u7387\u6216\u590d\u6742\u5ea6\u7684\u7c7b\u522b\uff08\u5e38\u6570\u3001\u5bf9\u6570\u3001\u7ebf\u6027\u3001\u5e73\u65b9\u548c\u6307\u6570\uff09\uff1b \u5c06\u7b97\u6cd5\u8f6c\u6362\u4e3a\u590d\u6742\u5ea6\u4f4e\u4e00\u4e2a\u6570\u91cf\u7ea7\u7684\u66f4\u5feb\u7684\u7248\u672c\uff1b \u63cf\u8ff0\u987a\u5e8f\u641c\u7d22\u7b97\u6cd5\u548c\u4e8c\u5206\u641c\u7d22\u7b97\u6cd5\u7684\u5de5\u4f5c\u65b9\u5f0f\uff1b \u63cf\u8ff0\u9009\u62e9\u6392\u5e8f\u7b97\u6cd5\u548c\u5feb\u901f\u6392\u5e8f\u7b97\u6cd5\u7684\u5de5\u4f5c\u65b9\u5f0f\u3002 3.1.\u8861\u91cf\u7b97\u6cd5\u7684\u6548\u7387 \u00b6 \u8861\u91cf\u7b97\u6cd5\u65f6\u95f4\u6210\u672c\u7684\u4e24\u79cd\u65b9\u6cd5\uff1a \u7528\u8ba1\u7b97\u673a\u65f6\u949f\u5f97\u5230\u7b97\u6cd5\u5b9e\u9645\u7684\u8fd0\u884c\u65f6\u3002\u8fd9\u4e2a\u8fc7\u7a0b\u88ab\u79f0\u4e3a\u57fa\u51c6\u6d4b\u8bd5\uff08benchmarking\uff09\u6216\u6027\u80fd\u5206\u6790\uff08profiling\uff09\u3002\u9884\u6d4b\u7b97\u6cd5\u6267\u884c\u7684\u62bd\u8c61\u5de5\u4f5c\u91cf\u4f9d\u8d56\u4e8e\u7279\u5b9a\u7684\u786c\u4ef6\u6216\u8f6f\u4ef6\u5e73\u53f0\u3002 \u5728\u4e0d\u540c\u95ee\u9898\u89c4\u6a21\u4e0b\uff0c\u7edf\u8ba1\u9700\u8981\u6267\u884c\u7684\u6307\u4ee4\u6570\u3002\u9884\u6d4b\u7b97\u6cd5\u6267\u884c\u7684\u62bd\u8c61\u5de5\u4f5c\u91cf\u9002\u7528\u4e8e\u4e0d\u540c\u7684\u786c\u4ef6\u6216\u8f6f\u4ef6\u5e73\u53f0\u3002 3.1.1.\u8861\u91cf\u7b97\u6cd5\u7684\u8fd0\u884c\u65f6 \u00b6 import time problemSize = 10000000 print ( \" %12s%16s \" % ( \"Problem Size\" , \"Seconds\" )) for count in range ( 5 ): \"\"\" \u5728\u4e00\u4e2a\u5faa\u73af\u4e2d\uff0c\u5c06\u95ee\u9898\u89c4\u6a21\u7ffb\u500d5\u6b21\uff0c\u8bb0\u5f55\u7b97\u6cd5\u6bcf\u6b21\u8fd0\u884c\u65f6\u95f4\u3002 \"\"\" start = time . time () # \u7b97\u6cd5\u5f00\u59cb work = 1 for x in range ( problemSize ): work += 1 work -= 1 # \u7b97\u6cd5\u7ed3\u675f elapsed = time . time () - start print ( \" %12d%16.3f \" % ( problemSize , elapsed )) problemSize *= 2 # \u8fd0\u884c\u7ed3\u679c\uff1a # Problem Size Seconds # 10000000 0.689 # 20000000 1.367 # 40000000 2.644 # 80000000 5.296 # 160000000 10.622 \u4e0a\u8ff0\u6d4b\u8bd5\u7a0b\u5e8f\u4f7f\u7528\u4e86 time \u6a21\u5757\u91cc\u7684 time() \u51fd\u6570\u6765\u8bb0\u5f55\u8fd0\u884c\u65f6\uff0c\u5373 time.time() \u3002\u8fd9\u4e2a\u51fd\u6570\u4f1a\u8fd4\u56de\u8ba1\u7b97\u673a\u7684\u5f53\u524d\u65f6\u95f4\u548c1970\u5e741\u67081\u65e5\uff3b\u4e5f\u79f0\u4e3a\u7eaa\u5143\uff08epoch\uff09\uff3d\u76f8\u5dee\u7684\u79d2\u6570\u3002\u4e24\u6b21\u8c03\u7528 time.time() \u7684\u7ed3\u679c\u4e4b\u95f4\u7684\u5dee\u503c\u5c31\u4ee3\u8868\u4e86\u4e2d\u95f4\u7ecf\u5386\u4e86\u591a\u5c11\u79d2\u3002 \u4e0a\u8ff0\u6d4b\u8bd5\u7a0b\u5e8f\u5728\u6bcf\u6b21\u5faa\u73af\u7684\u65f6\u5019\u90fd\u4f1a\u6267\u884c\u4e24\u4e2a\u6269\u5c55\u7684\u8d4b\u503c\u8bed\u53e5\uff0c\u4e5f\u5c31\u662f\u6bcf\u6b21\u90fd\u6267\u884c\u7684\u5de5\u4f5c\u91cf\u662f\u56fa\u5b9a\u7684\uff0c\u4f1a\u6d88\u8017\u4e86\u4e00\u5b9a\u7684\u65f6\u95f4\u3002 \u4fee\u6539\u4e0a\u8ff0\u7b97\u6cd5\uff0c\u6211\u4eec\u53ef\u4ee5\u4ece\u4e0b\u9762\u7684\u8fd0\u884c\u7ed3\u679c\u770b\u51fa\uff0c\u5f53 problemSize \u4e3a 1,000 \u65f6\uff0c\u7b97\u6cd5\u7684\u6d88\u8017\u65f6\u95f4\u5c31\u5df2\u7ecf\u8d85\u8fc7\u4e86\u539f\u5148\u7b97\u6cd5\uff0c\u6211\u4eec\u53ef\u4ee5\u63a8\u65ad\u51fa\u7ee7\u7eed\u6d4b\u8bd5 problemSize \u4e3a 10,000,000 \u7684\u8017\u65f6\u5df2\u7ecf\u53d8\u5f97\u4e0d\u5b9e\u9645\u4e86\u3002 import time problemSize = 1000 print ( \" %12s%16s \" % ( \"Problem Size\" , \"Seconds\" )) for count in range ( 5 ): start = time . time () # \u7b97\u6cd5\u5f00\u59cb work = 1 for x in range ( problemSize ): for y in range ( problemSize ): work += 1 work -= 1 # \u7b97\u6cd5\u7ed3\u675f elapsed = time . time () - start print ( \" %12d%16.3f \" % ( problemSize , elapsed )) problemSize *= 2 # \u8fd0\u884c\u7ed3\u679c\uff1a # Problem Size Seconds # 1000 0.093 # 2000 0.350 # 4000 1.280 # 8000 5.004 # 16000 20.020 \u4e0d\u540c\u7684\u786c\u4ef6\u5e73\u53f0\u4f1a\u6709\u4e0d\u540c\u7684\u5904\u7406\u901f\u5ea6\uff0c\u7b97\u6cd5\u7684\u8fd0\u884c\u65f6\u4f1a\u56e0\u673a\u5668\u7684\u4e0d\u540c\u800c\u5b58\u5728\u5dee\u5f02\u3002 \u7a0b\u5e8f\u7684\u8fd0\u884c\u65f6\u4e5f\u4f1a\u968f\u7740\u5b83\u548c\u786c\u4ef6\u4e4b\u95f4\u7684\u64cd\u4f5c\u7cfb\u7edf\u7c7b\u578b\u7684\u4e0d\u540c\u800c\u53d8\u5316\u3002 \u4e0d\u540c\u7684\u7f16\u7a0b\u8bed\u8a00\u548c\u7f16\u8bd1\u5668\u751f\u6210\u7684\u4ee3\u7801\u7684\u6027\u80fd\u4e5f\u4f1a\u6709\u6240\u4e0d\u540c\uff0c\u56e0\u6b64\uff0c\u5728\u67d0\u4e00\u4e2a\u786c\u4ef6\u6216\u8f6f\u4ef6\u5e73\u53f0\u4e0a\u6d4b\u5f97\u7684\u8fd0\u884c\u65f6\u7ed3\u679c\u901a\u5e38\u4e0d\u80fd\u7528\u6765\u9884\u6d4b\u5728\u5176\u4ed6\u5e73\u53f0\u4e0a\u7684\u6027\u80fd\u3002 \u7528\u975e\u5e38\u5927\u7684\u6570\u636e\u96c6\u786e\u5b9a\u7b97\u6cd5\u7684\u8fd0\u884c\u65f6\u662f\u975e\u5e38\u4e0d\u5207\u5b9e\u9645\u7684\u3002\u5bf9\u4e8e\u67d0\u4e9b\u7b97\u6cd5\u6765\u8bf4\uff0c\u4e0d\u8bba\u662f\u7f16\u8bd1\u7684\u4ee3\u7801\u8fd8\u662f\u786c\u4ef6\u5904\u7406\u5668\u7684\u901f\u5ea6\u6709\u591a\u5feb\uff0c\u90fd\u6ca1\u6709\u4efb\u4f55\u7684\u533a\u522b\uff0c\u56e0\u4e3a\u5b83\u4eec\u5728\u4efb\u4f55\u8ba1\u7b97\u673a\u4e0a\u90fd\u6ca1\u529e\u6cd5\u5904\u7406\u975e\u5e38\u5927\u7684\u6570\u636e\u96c6\u3002 3.1.2.\u7edf\u8ba1\u6307\u4ee4\u6570 \u00b6 \u7edf\u8ba1\u6307\u4ee4\u6570\u65f6\uff0c\u7edf\u8ba1\u7684\u662f\u7f16\u5199\u7b97\u6cd5\u7684\u9ad8\u7ea7\u8bed\u8a00\u91cc\u7684\u6307\u4ee4\u6570\uff0c\u800c\u4e0d\u662f\u53ef\u6267\u884c\u673a\u5668\u8bed\u8a00\u7a0b\u5e8f\u91cc\u7684\u6307\u4ee4\u6570\u3002 \u901a\u8fc7\u8fd9\u79cd\u65b9\u5f0f\u5bf9\u7b97\u6cd5\u8fdb\u884c\u5206\u6790\u65f6\uff0c\u628a\u5b83\u5206\u6210\u4e24\u4e2a\u90e8\u5206\uff1a \u65e0\u8bba\u95ee\u9898\u7684\u89c4\u6a21\u5982\u4f55\u53d8\u5316\uff0c\u6307\u4ee4\u6267\u884c\u7684\u6b21\u6570\u603b\u662f\u76f8\u540c\u7684\uff1b\u6211\u4eec\u5ffd\u7565\u8fd9\u79cd\u7c7b\u578b\uff0c\u56e0\u4e3a\u5206\u6790\u6548\u7387\u65f6\u5b83\u4eec\u7684\u4f5c\u7528\u5e76\u4e0d\u660e\u663e\u3002 \u6267\u884c\u7684\u6307\u4ee4\u6570\u968f\u7740\u95ee\u9898\u89c4\u6a21\u7684\u53d8\u5316\u800c\u53d8\u5316\uff1b\u6211\u4eec\u91cd\u70b9\u5173\u6ce8\u8fd9\u79cd\u7c7b\u578b\uff0c\u8fd9\u79cd\u7c7b\u578b\u7684\u6307\u4ee4\u901a\u5e38\u53ef\u4ee5\u5728\u5faa\u73af\u6216\u8005\u9012\u5f52\u51fd\u6570\u91cc\u627e\u5230\u3002 \u6211\u4eec\u6765\u6539\u5199\u4e0a\u9762\u7684\u4f8b\u5b50\uff0c\u4ece\u7edf\u8ba1\u8fd0\u884c\u65f6\u95f4\u53d8\u4e3a\u7edf\u8ba1\u8fed\u4ee3\u6b21\u6570\u3002 \u4e0b\u9762\u7684\u7b97\u6cd5\u4e2d\uff0c\u8fed\u4ee3\u6b21\u6570\u548c\u95ee\u9898\u89c4\u6a21\u662f\u76f8\u7b49\u7684\u3002 import time problemSize = 10000000 print ( \" %12s%16s \" % ( \"Problem Size\" , \"Seconds\" )) for count in range ( 5 ): number = 0 # \u7b97\u6cd5\u5f00\u59cb work = 1 for x in range ( problemSize ): number += 1 work += 1 work -= 1 # \u7b97\u6cd5\u7ed3\u675f print ( \" %12d%16.3f \" % ( problemSize , Iterations )) problemSize *= 2 # \u8fd0\u884c\u7ed3\u679c\uff1a # Problem Size Iterations # 10000000 10000000.000 # 20000000 20000000.000 # 40000000 40000000.000 # 80000000 80000000.000 # 160000000 160000000.000 \u4e0b\u9762\u7684\u7b97\u6cd5\u4e2d\uff0c\u8fed\u4ee3\u6b21\u6570\u548c\u95ee\u9898\u89c4\u6a21\u7684\u5e73\u65b9\u3002\u8fd9\u5c31\u89e3\u91ca\u4e86\u4e3a\u4ec0\u4e48\u8fd9\u4e2a\u7b97\u6cd5\u7684\u8017\u65f6\u975e\u5e38\u5927\u3002 import time problemSize = 1000 print ( \" %12s%16s \" % ( \"Problem Size\" , \"Seconds\" )) for count in range ( 5 ): number = 0 # \u7b97\u6cd5\u5f00\u59cb work = 1 for x in range ( problemSize ): for y in range ( problemSize ): number += 1 work += 1 work -= 1 # \u7b97\u6cd5\u7ed3\u675f print ( \" %12d%16.3f \" % ( problemSize , number )) problemSize *= 2 # \u8fd0\u884c\u7ed3\u679c\uff1a # Problem Size Iterations # 1000 1000000.000 # 2000 4000000.000 # 4000 16000000.000 # 8000 64000000.000 # 16000 256000000.000 \u5728\u4e0b\u9762\u7684\u6590\u6ce2\u90a3\u5951\u9012\u5f52\u7684\u4f8b\u5b50\u4e2d\uff0c\u51fd\u6570 fib(problemSize, counter) \u4e2d counter \u53c2\u6570\u662f\u4e00\u4e2a\u5bf9\u8c61\uff0c\u6bcf\u6b21\u9012\u5f52\u8c03\u7528\u7684\u65f6\u5019\uff0c\u90fd\u4f1a\u521b\u5efa\u4e00\u4e2a\u65b0\u7684\u8ba1\u6570\u5668\u5bf9\u8c61\u3002 \u4ece\u4e0b\u9762\u7684\u8fd0\u884c\u7ed3\u679c\u53ef\u4ee5\u770b\u51fa\uff0c\u968f\u7740\u95ee\u9898\u89c4\u6a21\uff08Problem Size\uff09\u7684\u7ffb\u500d\uff0c\u6307\u4ee4\u6570\uff08\u9012\u5f52\u8c03\u7528\u7684\u6b21\u6570\uff09\u5728\u4e00\u5f00\u59cb\u7684\u65f6\u5019\u7f13\u6162\u589e\u957f\uff0c\u968f\u540e\u8fc5\u901f\u52a0\u5feb\u3002 \u7edf\u8ba1\u6307\u4ee4\u6570\u662f\u6b63\u786e\u7684\u601d\u8def\uff0c\u4f46\u4ee5\u8fd9\u79cd\u65b9\u5f0f\u8fdb\u884c\u8ddf\u8e2a\u8ba1\u6570\u7684\u95ee\u9898\u5728\u4e8e\uff0c\u5bf9\u4e8e\u67d0\u4e9b\u7b97\u6cd5\u6765\u8bf4\uff0c\u5982\u679c\u95ee\u9898\u89c4\u6a21\u975e\u5e38\u5927\uff0c\u8ba1\u7b97\u673a\u65e0\u6cd5\u4ee5\u8db3\u591f\u5feb\u7684\u901f\u5ea6\u8fd0\u884c\uff0c\u5e76\u5728\u4e00\u5b9a\u65f6\u95f4\u5185\u5f97\u5230\u7ed3\u679c\u3002 class Counter ( object ): \"\"\"Models a counter.\"\"\" # Class variable instances = 0 #Constructor def __init__ ( self ): \"\"\"Sets up the counter.\"\"\" Counter . instances += 1 self . reset () # Mutator methods def reset ( self ): \"\"\"Sets the counter to 0.\"\"\" self . _value = 0 def increment ( self , amount = 1 ): \"\"\"Adds amount to the counter.\"\"\" self . _value += amount def decrement ( self , amount = 1 ): \"\"\"Subtracts amount from the counter.\"\"\" self . _value -= amount # Accessor methods def getValue ( self ): \"\"\"Returns the counter's value.\"\"\" return self . _value def __str__ ( self ): \"\"\"Returns the string representation of the counter.\"\"\" return str ( self . _value ) def __eq__ ( self , other ): \"\"\"Returns True if self equals other or False otherwise.\"\"\" if self is other : return True if type ( self ) != type ( other ): return False return self . _value == other . _value def fib ( n , counter ): \"\"\"\u7edf\u8ba1\u6590\u6ce2\u90a3\u5951\u51fd\u6570\u88ab\u5916\u90e8\u8c03\u7528\u7684\u6b21\u6570\"\"\" counter . increment () if n < 3 : return 1 else : return fib ( n - 1 , counter ) + fib ( n - 2 , counter ) problemSize = 2 print ( \" %12s%15s \" % ( \"Problem Size\" , \"Calls\" )) for count in range ( 5 ): \"\"\"\u968f\u7740\u95ee\u9898\u89c4\u6a21\u589e\u52a0\uff0c\u8f93\u51fa\u6590\u6ce2\u90a3\u5951\u9012\u5f52\u51fd\u6570\u88ab\u5916\u90e8\u8c03\u7528\u7684\u6b21\u6570\"\"\" counter = Counter () # \u7b97\u6cd5\u5f00\u59cb fib ( problemSize , counter ) # \u7b97\u6cd5\u7ed3\u675f print ( \" %12d%15s \" % ( problemSize , counter )) problemSize *= 2 # \u8fd0\u884c\u7ed3\u679c\uff1a # Problem Size Calls # 2 1 # 4 5 # 8 41 # 16 1973 # 32 4356617 3.1.3.\u8861\u91cf\u7b97\u6cd5\u4f7f\u7528\u7684\u5185\u5b58 \u00b6 \u5bf9\u4e8e\u7b97\u6cd5\u6240\u7528\u8d44\u6e90\u7684\u5206\u6790\u4e5f\u9700\u8981\u5305\u542b\u5b83\u6240\u9700\u7684\u5185\u5b58\u91cf\u7684\u5206\u6790\u3002\u548c\u524d\u9762\u7c7b\u4f3c\u7684\u95ee\u9898\u4e5f\u4f1a\u5b58\u5728\uff0c\u4e00\u4e9b\u7b97\u6cd5\u4f1a\u968f\u7740\u95ee\u9898\u89c4\u6a21\u53d8\u5927\u800c\u9700\u8981\u989d\u5916\u66f4\u591a\u7684\u5185\u5b58\u3002 3.1.4.\u7ec3\u4e60\u9898 \u00b6 \u7f16\u5199\u4e00\u4e2a\u6d4b\u8bd5\u7a0b\u5e8f\uff0c\u8fd9\u4e2a\u7a0b\u5e8f\u7edf\u8ba1\u5e76\u663e\u793a\u51fa\u4e0b\u9762\u8fd9\u4e2a\u5faa\u73af\u7684\u8fed\u4ee3\u6b21\u6570\u3002 while problemSize > 0 : problemSize = problemSize // 2 \u89e3\u7b54\uff1a def count_iterations ( problemSize ): iterations = 0 # \u521d\u59cb\u5316\u8ba1\u6570\u5668 while problemSize > 0 : problemSize = problemSize // 2 iterations += 1 # \u6bcf\u6b21\u5faa\u73af\u8fed\u4ee3\uff0c\u8ba1\u6570\u5668\u52a0\u4e00 return iterations problemSize = 1000 # \u8bbe\u7f6e\u95ee\u9898\u89c4\u6a21 iterations = count_iterations ( problemSize ) print ( f \"Problem Size: { problemSize } \" ) print ( f \"Iterations: { iterations } \" ) # \u8fd0\u884c\u7ed3\u679c\uff1a # Problem Size: 1000 # Iterations: 10 \u5728\u95ee\u9898\u89c4\u6a21\u5206\u522b\u4e3a1000\u30012000\u30014000\u300110000\u548c100000\u65f6\uff0c\u8fd0\u884c\u5728\u7ec3\u4e601\u91cc\u6240\u521b\u5efa\u7684\u7a0b\u5e8f\u3002\u5f53\u95ee\u9898\u89c4\u6a21\u7ffb\u500d\u6216\u662f\u4e58\u4ee510\u65f6\uff0c\u8fed\u4ee3\u6b21\u6570\u4f1a\u5982\u4f55\u53d8\u5316\uff1f \u89e3\u7b54\uff1a\u5206\u522b\u4ee5\u4e0d\u540c\u7684\u95ee\u9898\u89c4\u6a21\u8fd0\u884c\u4e0a\u9762\u7684\u4ee3\u7801\uff0c\u7ed3\u679c\u5982\u4e0b\uff1a Problem Size : 1000 Iterations : 10 Problem Size : 4000 Iterations : 12 Problem Size : 8000 Iterations : 13 Problem Size : 10000 Iterations : 14 Problem Size : 100000 Iterations : 17 \u4e24\u6b21\u8c03\u7528\u51fd\u6570 time.time() \u7684\u7ed3\u679c\u4e4b\u5dee\u5c31\u662f\u8fd0\u884c\u65f6\u3002\u7531\u4e8e\u64cd\u4f5c\u7cfb\u7edf\u4e5f\u53ef\u80fd\u4f1a\u5728\u8fd9\u6bb5\u65f6\u95f4\u5185\u4f7f\u7528CPU\uff0c\u56e0\u6b64\u8fd9\u4e2a\u8fd0\u884c\u65f6\u53ef\u80fd\u5e76\u4e0d\u80fd\u53cd\u6620\u51faPython\u4ee3\u7801\u4f7f\u7528CPU\u7684\u5b9e\u9645\u65f6\u95f4\u3002\u6d4f\u89c8Python\u6587\u6863\uff0c\u627e\u51fa\u53e6\u4e00\u79cd\u53ef\u4ee5\u5b8c\u6574\u8bb0\u5f55\u5904\u7406\u65f6\u95f4\u7684\u65b9\u6cd5\uff0c\u5e76\u63cf\u8ff0\u5982\u4f55\u5b9e\u73b0\u5b83\u3002 \u89e3\u7b54\uff1a \u5728Python\u4e2d\uff0c time \u6a21\u5757\u63d0\u4f9b\u4e86\u66f4\u7cbe\u786e\u7684\u8ba1\u65f6\u529f\u80fd\uff0c\u5176\u4e2d\u7684 time.perf_counter() \u51fd\u6570\u53ef\u4ee5\u7528\u6765\u6d4b\u91cf\u65f6\u95f4\u7684\u7cbe\u786e\u95f4\u9694\u3002\u4e0e time.time() \u4e0d\u540c\uff0c time. perf_counter() \u4f1a\u5728\u5927\u591a\u6570\u5e73\u53f0\u4e0a\u63d0\u4f9b\u4e00\u4e2a\u66f4\u9ad8\u5206\u8fa8\u7387\u7684\u8ba1\u65f6\u5668\uff0c\u53ef\u4ee5\u7528\u6765\u6d4b\u91cf\u4ee3\u7801\u5757\u7684\u6267\u884c\u65f6\u95f4\u3002 time.perf_counter() \u8fd4\u56de\u4e00\u4e2a\u6d6e\u70b9\u6570\uff0c\u8868\u793a\u4ece\u67d0\u4e2a\u7279\u5b9a\u65f6\u95f4\u70b9\u5230\u73b0\u5728\u7ecf\u8fc7\u7684\u79d2\u6570\u3002\u4ee5\u4e0b\u662f\u5982\u4f55\u4f7f\u7528 time.perf_counter() \u6765\u8ba1\u7b97\u4ee3\u7801\u5757\u7684\u6267\u884c\u65f6\u95f4\uff1a import time # \u83b7\u53d6\u8d77\u59cb\u65f6\u95f4\uff08\u5305\u62ecCPU\u65f6\u95f4\u548c\u7cfb\u7edf\u65f6\u95f4\uff09 start_cpu_time = time . process_time () start_real_time = time . perf_counter () start_system_time = time . time () # \u6267\u884c\u4ee3\u7801 for i in range ( 100000000 ): _ = i * i # \u83b7\u53d6\u7ed3\u675f\u65f6\u95f4\uff08\u5305\u62ecCPU\u65f6\u95f4\u548c\u7cfb\u7edf\u65f6\u95f4\uff09 end_cpu_time = time . process_time () end_real_time = time . perf_counter () end_system_time = time . time () # \u8ba1\u7b97CPU\u65f6\u95f4\u5dee cpu_execution_time = end_cpu_time - start_cpu_time real_execution_time = end_real_time - start_real_time system_execution_time = end_system_time - start_system_time print ( f \"CPU Execution Time: { cpu_execution_time : .6f } seconds\" ) print ( f \"Real Execution Time: { real_execution_time : .6f } seconds\" ) print ( f \"System Execution Time: { system_execution_time : .6f } seconds\" ) # \u8fd0\u884c\u7ed3\u679c\uff1a # CPU Execution Time: 7.157305 seconds # Real Execution Time: 7.156638 seconds # System Execution Time: 7.156638 seconds \u5728\u4e0a\u9762\u4ee3\u7801\u4e2d\uff0c start_system_time \u548c end_system_time \u5206\u522b\u8bb0\u5f55\u4e86\u4ee3\u7801\u5757\u5f00\u59cb\u548c\u7ed3\u675f\u65f6\u7684\u7cfb\u7edf\u65f6\u95f4\u3002\u7136\u540e\uff0c\u53ef\u4ee5\u901a\u8fc7\u8ba1\u7b97 end_system_time - start_system_time \u6765\u83b7\u53d6\u7cfb\u7edf\u65f6\u95f4\u7684\u6d88\u8017\u3002 \u7cfb\u7edf\u65f6\u95f4\u7684\u8ba1\u7b97\u53ef\u80fd\u53d7\u5230\u7cfb\u7edf\u7684\u5f71\u54cd\uff0c\u53ef\u80fd\u4f1a\u56e0\u4e3a\u7cfb\u7edf\u65f6\u95f4\u7684\u53d8\u5316\u800c\u4ea7\u751f\u4e0d\u51c6\u786e\u7684\u7ed3\u679c\u3002\u5728\u8fdb\u884c\u6027\u80fd\u6d4b\u8bd5\u65f6\uff0c\u5c3d\u91cf\u4ee5CPU\u65f6\u95f4\u548c\u5b9e\u9645\u7ecf\u8fc7\u65f6\u95f4\u4e3a\u4e3b\u8981\u53c2\u8003\u6307\u6807\u3002 \u8865\u5145\uff1a CPU \u65f6\u95f4\u3001\u5b9e\u9645\u7ecf\u8fc7\u65f6\u95f4\u548c\u7cfb\u7edf\u65f6\u95f4\u4ee3\u8868\u4e86\u4e0d\u540c\u7684\u65f6\u95f4\u6307\u6807\uff0c\u5b83\u4eec\u4e4b\u95f4\u6709\u4ee5\u4e0b\u533a\u522b\uff1a CPU \u65f6\u95f4\uff1a - CPU \u65f6\u95f4\u662f\u7a0b\u5e8f\u5728 CPU \u4e0a\u6267\u884c\u7684\u65f6\u95f4\uff0c\u5305\u62ec\u4e86\u5728\u7528\u6237\u6001\uff08\u6267\u884c\u5e94\u7528\u7a0b\u5e8f\u4ee3\u7801\uff09\u548c\u5185\u6838\u6001\uff08\u6267\u884c\u64cd\u4f5c\u7cfb\u7edf\u4ee3\u7801\uff09\u7684\u65f6\u95f4\u3002\u56e0\u6b64\uff0c\u5b83\u8003\u8651\u4e86\u5e94\u7528\u7a0b\u5e8f\u548c\u64cd\u4f5c\u7cfb\u7edf\u7684\u6267\u884c\u65f6\u95f4\u3002 - CPU \u65f6\u95f4\u901a\u5e38\u7528\u4e8e\u6d4b\u91cf\u7a0b\u5e8f\u7684\u8ba1\u7b97\u5bc6\u96c6\u578b\u5de5\u4f5c\u91cf\uff0c\u5373\u5927\u91cf\u8ba1\u7b97\u64cd\u4f5c\uff0c\u6bd4\u5982\u5faa\u73af\u548c\u6570\u5b66\u8ba1\u7b97\u3002 - \u901a\u8fc7 time.process_time() \u51fd\u6570\u53ef\u4ee5\u83b7\u53d6\u5f53\u524d\u8fdb\u7a0b\u7684 CPU \u65f6\u95f4\u3002 \u5b9e\u9645\u7ecf\u8fc7\u65f6\u95f4\uff1a - \u5b9e\u9645\u7ecf\u8fc7\u65f6\u95f4\u662f\u4ece\u67d0\u4e2a\u65f6\u95f4\u70b9\u5230\u73b0\u5728\u7684\u5b9e\u9645\u7ecf\u8fc7\u7684\u65f6\u95f4\uff0c\u8003\u8651\u4e86\u6240\u6709\u56e0\u7d20\uff0c\u5305\u62ec\u4e86 CPU \u65f6\u95f4\u3001\u7b49\u5f85\u65f6\u95f4\u3001\u7cfb\u7edf\u8c03\u5ea6\u7b49\u3002 - \u5b9e\u9645\u7ecf\u8fc7\u65f6\u95f4\u7528\u4e8e\u6d4b\u91cf\u4ee3\u7801\u7684\u603b\u6267\u884c\u65f6\u95f4\uff0c\u5305\u62ec\u4e86\u8ba1\u7b97\u548c\u7b49\u5f85\u7684\u65f6\u95f4\u3002 - \u901a\u8fc7 time.perf_counter() \u51fd\u6570\u53ef\u4ee5\u83b7\u53d6\u5f53\u524d\u65f6\u95f4\u3002 \u7cfb\u7edf\u65f6\u95f4\uff1a - \u7cfb\u7edf\u65f6\u95f4\u662f\u64cd\u4f5c\u7cfb\u7edf\u5185\u90e8\u7ef4\u62a4\u7684\u4e00\u4e2a\u65f6\u95f4\u503c\uff0c\u5b83\u4ee3\u8868\u4e86\u4ece\u67d0\u4e2a\u56fa\u5b9a\u65f6\u95f4\u70b9\u5f00\u59cb\u7684\u79d2\u6570\u3002 - \u7cfb\u7edf\u65f6\u95f4\u901a\u5e38\u7528\u4e8e\u8bb0\u5f55\u4e8b\u4ef6\u548c\u8ba1\u7b97\u65f6\u95f4\u95f4\u9694\uff0c\u4e0d\u53d7\u7a0b\u5e8f\u7684\u6267\u884c\u5f71\u54cd\u3002 - \u901a\u8fc7 time.time() \u51fd\u6570\u53ef\u4ee5\u83b7\u53d6\u5f53\u524d\u7684\u7cfb\u7edf\u65f6\u95f4\u3002 \u603b\u7ed3\uff1aCPU \u65f6\u95f4\u5173\u6ce8\u7684\u662f\u7a0b\u5e8f\u5728 CPU \u4e0a\u7684\u6267\u884c\u65f6\u95f4\uff0c\u5b9e\u9645\u7ecf\u8fc7\u65f6\u95f4\u5173\u6ce8\u7684\u662f\u4ece\u4ee3\u7801\u5f00\u59cb\u5230\u7ed3\u675f\u6240\u7ecf\u8fc7\u7684\u771f\u5b9e\u65f6\u95f4\uff0c\u7cfb\u7edf\u65f6\u95f4\u662f\u7cfb\u7edf\u7ef4\u62a4\u7684\u5168\u5c40\u65f6\u95f4\u3002\u5728\u4e0d\u540c\u7684\u573a\u666f\u4e2d\uff0c\u4f60\u53ef\u4ee5\u6839\u636e\u9700\u8981\u9009\u62e9\u5408\u9002\u7684\u65f6\u95f4\u6307\u6807\u6765\u8fdb\u884c\u6027\u80fd\u6d4b\u91cf\u548c\u5206\u6790\u3002 3.2.\u590d\u6742\u5ea6\u5206\u6790 \u00b6 \u590d\u6742\u5ea6\u5206\u6790\uff08complexity analysis\uff09\u65b9\u6cd5\uff0c\u4e00\u79cd\u8bc4\u4f30\u7b97\u6cd5\u6548\u7387\u7684\u65b9\u6cd5\uff0c\u8fd9\u4e2a\u65b9\u6cd5\u53ef\u4ee5\u4e0d\u7528\u5173\u5fc3\u4e0e\u5e73\u53f0\u76f8\u5173\u7684\u65f6\u95f4\uff0c\u4e5f\u4e0d\u9700\u8981\u4f7f\u7528\u7edf\u8ba1\u6307\u4ee4\u6570\u91cf\u8fd9\u79cd\u65b9\u6cd5\u6765\u5bf9\u7b97\u6cd5\u8fdb\u884c\u8bc4\u4f30\u3002 3.2.1.\u590d\u6742\u5ea6\u7684\u9636 \u00b6 \u5728 3.1.2.\u7edf\u8ba1\u6307\u4ee4\u6570 \u4e2d\u5173\u4e8e\u8fed\u4ee3\u6b21\u6570\u548c\u95ee\u9898\u89c4\u6a21\u7684\u4e24\u4e2a\u7b97\u6cd5\uff0c\u5b83\u4eec\u590d\u6742\u5ea6\u7684\u9636\uff08order of complexity\uff09\u4e0a\u662f\u4e0d\u4e00\u6837\u7684\u3002 \u7b2c\u4e00\u4e2a\u7b97\u6cd5\u4e2d\uff0c\u8fed\u4ee3\u6b21\u6570\u548c\u95ee\u9898\u89c4\u6a21\u4e4b\u95f4\u662f\u7ebf\u6027\u5173\u7cfb\uff0c\u79f0\u5176\u590d\u6742\u5ea6\u4e3a\u7ebf\u6027\uff08linear\uff09\u9636\uff1b \u7b2c\u4e8c\u4e2a\u7b97\u6cd5\u4e2d\uff0c\u8fed\u4ee3\u6b21\u6570\u548c\u95ee\u9898\u89c4\u6a21\u4e4b\u95f4\u662f\u5e73\u65b9\u5173\u7cfb\uff0c\u79f0\u5176\u590d\u6742\u5ea6\u4e3a\u5e73\u65b9\uff08quadratic\uff09\u9636\uff1b \u5982\u679c\u7b97\u6cd5\u9700\u8981\u76f8\u540c\u6570\u91cf\u7684\u8fd0\u7b97\uff0c\u90a3\u4e48\u5b83\u7684\u6027\u80fd\u5c31\u662f\u5e38\u6570\uff08constant\uff09\u9636\u3002\u5217\u8868\u7d22\u5f15\u5c31\u662f\u4e00\u4e2a\u5e38\u6570\u65f6\u95f4\u7b97\u6cd5\u7684\u4f8b\u5b50\u3002 \u6bd4\u7ebf\u6027\u6027\u80fd\u597d\uff0c\u4f46\u6bd4\u5e38\u6570\u6027\u80fd\u5dee\u7684\u53e6\u4e00\u4e2a\u590d\u6742\u5ea6\u7684\u9636\u88ab\u79f0\u4e3a\u5bf9\u6570\uff08logarithmic\uff09\u9636\u3002\u5bf9\u6570\u7b97\u6cd5\u7684\u5de5\u4f5c\u91cf\u4e0e\u95ee\u9898\u89c4\u6a21\u7684\u4ee52\u4e3a\u5e95\u7684\u5bf9\u6570\u6210\u6b63\u6bd4\u3002\u5f53\u95ee\u9898\u89c4\u6a21\u6269\u5927\u4e00\u500d\u65f6\uff0c\u5de5\u4f5c\u91cf\u53ea\u4f1a\u52a01\u3002 \u591a\u9879\u5f0f\u65f6\u95f4\u7b97\u6cd5\uff08polynomial time algorithm\uff09\u7684\u5de5\u4f5c\u91cf\u4f1a\u4ee5 n^k \u7684\u901f\u7387\u589e\u957f\uff0c\u5176\u4e2d k \u662f\u5927\u4e8e 1 \u7684\u5e38\u6570\uff0c\u6bd4\u5982 n^2 \u3001 n^3 \u4ee5\u53ca n^10 \u3002\u4ece\u67d0\u79cd\u610f\u4e49\u4e0a\u8bb2\uff0c n^3 \u7684\u6027\u80fd\u8981\u6bd4 n^2 \u5dee\uff0c\u4f46\u90fd\u5c5e\u4e8e\u591a\u9879\u5f0f\uff08polynomial\uff09\u9636\u3002 \u6bd4\u591a\u9879\u5f0f\u8fd8\u8981\u5dee\u7684\u590d\u6742\u5ea6\u7684\u9636\u88ab\u79f0\u4e3a\u6307\u6570\uff08exponential\uff09\u9636\uff0c\u6bd4\u5982 2^n \u3002\u5bf9\u4e8e\u5927\u7684\u95ee\u9898\u89c4\u6a21\u6765\u8bf4\uff0c\u6307\u6570\u7b97\u6cd5\u662f\u4e0d\u53ef\u884c\u7684\u3002 \u4e0d\u540c\u590d\u6742\u5ea6\u9636\u7684\u7b97\u6cd5\u7684\u5de5\u4f5c\u91cf\u6bd4\u8f83\uff08\u4ece\u5c0f\u5230\u5927\uff09\uff1a\u5bf9\u6570\u9636 < \u7ebf\u6027\u9636 < \u5e73\u65b9\u9636 < \u6307\u6570\u9636\u3002\u968f\u7740\u95ee\u9898\u89c4\u6a21\u7684\u589e\u5927\uff0c\u5177\u6709\u8f83\u9ad8\u590d\u6742\u5ea6\u7684\u9636\u7684\u7b97\u6cd5\u7684\u6027\u80fd\u4f1a\u66f4\u5feb\u5730\u53d8\u5dee\u3002 3.2.2.\u5927O\u8868\u793a\u6cd5 \u00b6 \u5f88\u591a\u60c5\u51b5\u4e0b\uff0c\u7b97\u6cd5\u4e2d\u7684\u5de5\u4f5c\u91cf\u901a\u5e38\u662f\u591a\u9879\u5f0f\u91cc\u591a\u9879\u7684\u603b\u548c\uff0c\u800c\u5f53\u5de5\u4f5c\u91cf\u8868\u793a\u4e3a\u591a\u9879\u5f0f\u65f6\uff0c\u5176\u4e2d\u4e00\u9879\u662f\u4e3b\u5bfc\u9879\uff08dominant\uff09\u3002\u968f\u7740 n \u8d8a\u6765\u8d8a\u5927\uff0c\u4e3b\u5bfc\u9879\u5c06\u53d8\u5f97\u975e\u5e38\u5927\uff0c\u4ee5\u81f3\u4e8e\u53ef\u4ee5\u5ffd\u7565\u5176\u4ed6\u9879\u6240\u4ee3\u8868\u7684\u5de5\u4f5c\u91cf\u3002\u56e0\u6b64\uff0c\u5bf9\u4e8e\u591a\u9879\u5f0f n^2+n \uff0c\u53ea\u9700\u8981\u7740\u91cd\u8003\u8651\u5e73\u65b9\u9879 n^2 \uff0c\u4e5f\u5c31\u662f\u5728\u8003\u8651\u7684\u65f6\u5019\u53ef\u4ee5\u5ffd\u7565\u7ebf\u6027\u9879 n \u3002\u968f\u7740 n^2 \u53d8\u5f97\u975e\u5e38\u5927\uff0c\u591a\u9879\u5f0f\u7684\u503c\u6e10\u8fd1\u5730\u63a5\u8fd1\u6216\u8fd1\u4f3c\u4e8e\u5b83\u7684\u6700\u5927\u9879\u503c\uff0c\u8fd9\u79cd\u5f62\u5f0f\u7684\u5206\u6790\u6709\u65f6\u88ab\u79f0\u4e3a\u6e10\u8fd1\u5206\u6790\uff08asymptotic analysis\uff09\u3002 \u8ba1\u7b97\u4e2d\u7528\u6765\u8868\u793a\u7b97\u6cd5\u7684\u6548\u7387\u6216\u8ba1\u7b97\u590d\u6742\u5ea6\u7684\u4e00\u79cd\u65b9\u6cd5\u88ab\u79f0\u4e3a\u5927O\u8868\u793a\u6cd5\uff08big-O notation\uff09\u3002\u201cO\u201d\u4ee3\u8868\u201c\u5728\u2026\u2026\u9636\u201d\uff0c\u6307\u7684\u662f\u7b97\u6cd5\u5de5\u4f5c\u7684\u590d\u6742\u5ea6\u7684\u9636\u3002\u4f8b\u5982\uff1a \u5e38\u6570\u65f6\u95f4\uff1aO(1) \u7ebf\u6027\u65f6\u95f4\uff1aO(n) \u5e73\u65b9\u65f6\u95f4\uff1aO(n^2) \u7acb\u65b9\u65f6\u95f4\uff1aO(n^3) \u591a\u9879\u5f0f\u65f6\u95f4\uff1aO(n^k) 3.2.3.\u6bd4\u4f8b\u5e38\u6570\u7684\u4f5c\u7528 \u00b6 \u6bd4\u4f8b\u5e38\u6570\uff08constant of proportionality\uff09\u5305\u542b\u5728\u5927O\u5206\u6790\u4e2d\u88ab\u5ffd\u7565\u7684\u9879\u548c\u7cfb\u6570\u3002\u6bd4\u5982\uff0c\u7ebf\u6027\u65f6\u95f4\u7b97\u6cd5\u6240\u6267\u884c\u7684\u5de5\u4f5c\u91cf\u53ef\u4ee5\u8868\u793a\u4e3a\uff1a work = 2 * size \uff0c\u5176\u4e2d\u6bd4\u4f8b\u5e38\u6570\u5c31\u662f work/size \uff0c\u4e5f\u5c31\u662f 2 \u3002\u5728\u5904\u7406\u4e2d\u5c0f\u578b\u6570\u636e\u96c6\u7684\u65f6\u5019\uff0c\u5982\u679c\u8fd9\u4e9b\u5e38\u6570\u5f88\u5927\uff0c\u90a3\u4e48\u5b83\u4eec\u4e5f\u4f1a\u5f71\u54cd\u5230\u7b97\u6cd5\u6548\u7387\u3002 \u56de\u987e\u4e0b\u9762\u7684\u4f8b\u5b50\u3002 import time problemSize = 10000000 print ( \" %12s%16s \" % ( \"Problem Size\" , \"Seconds\" )) for count in range ( 5 ): number = 0 # \u7b97\u6cd5\u5f00\u59cb work = 1 for x in range ( problemSize ): number += 1 work += 1 work -= 1 # \u7b97\u6cd5\u7ed3\u675f print ( \" %12d%16.3f \" % ( problemSize , Iterations )) problemSize *= 2 # \u8fd0\u884c\u7ed3\u679c\uff1a # Problem Size Iterations # 10000000 10000000.000 # 20000000 20000000.000 # 40000000 40000000.000 # 80000000 80000000.000 # 160000000 160000000.000 \u5176\u4e2d\u7684\u7b97\u6cd5\u90e8\u5206\uff0c\u9664\u4e86\u5faa\u73af\u8bed\u53e5\u672c\u8eab\uff0c\u8fd8\u6709\u5176\u4ed63\u884c\u4ee3\u7801\uff0c\u5b83\u4eec\u90fd\u662f\u590d\u5236\u8bed\u53e5\uff0c\u90fd\u4f1a\u4ee5\u5e38\u6570\u65f6\u95f4\u8fd0\u884c\u3002\u5047\u8bbe\u5faa\u73af\u8bed\u53e5\u672c\u8eab\u4f1a\u6d88\u8017\u4e00\u4e2a\u65f6\u95f4\u5e38\u6570\uff0c\u90a3\u4e48\u8fd9\u4e2a\u7b97\u6cd5\u7684\u62bd\u8c61\u5de5\u4f5c\u65f6\u95f4\u5c31\u662f 3n+1 \u3002\u867d\u7136 3n+1 \u7684\u5de5\u4f5c\u91cf\u5927\u4e8e n \uff0c\u4f46\u4e8c\u8005\u5728\u8fd0\u884c\u65f6\u90fd\u662f\u7ebf\u6027\u589e\u52a0\uff0c\u6240\u4ee5\u4ed6\u4eec\u8fd0\u884c\u65f6\u90fd\u662f O(n) \u3002 # \u7b97\u6cd5\u5f00\u59cb work = 1 for x in range ( problemSize ): number += 1 work += 1 work -= 1 # \u7b97\u6cd5\u7ed3\u675f 3.2.4.\u7ec3\u4e60\u9898 \u00b6 \u5047\u8bbe\u4e0b\u9762\u7684\u8868\u8fbe\u5f0f\u90fd\u5206\u522b\u8868\u793a\u5bf9\u95ee\u9898\u89c4\u6a21\u4e3a n \u7684\u7b97\u6cd5\u6240\u9700\u8981\u6267\u884c\u7684\u64cd\u4f5c\u6570\uff0c\u8bf7\u6307\u51fa\u6bcf\u79cd\u7b97\u6cd5\u4e2d\u7684\u4e3b\u5bfc\u9879\uff0c\u5e76\u4f7f\u7528\u5927O\u8868\u793a\u6cd5\u5bf9\u5b83\u8fdb\u884c\u5206\u7c7b\u3002 a. 2^n - 4n + 5n b. 2n^2 + 8 c. n^3 n^2 + n \u89e3\u7b54\uff1a a. 2^n\uff0cO(n) b. n 2\uff0cO(n 2) c. n 3\uff0cO(n 3) \u5bf9\u4e8e\u89c4\u6a21\u4e3a n \u7684\u95ee\u9898\uff0c\u7b97\u6cd5A\u548cB\u5206\u522b\u4f1a\u6267\u884c n^2 \u548c (1/2)*n^2+(1/2)*n \u6761\u6307\u4ee4\u3002\u54ea\u79cd\u7b97\u6cd5\u66f4\u9ad8\u6548\uff1f\u6709\u6ca1\u6709\u4e00\u79cd\u7b97\u6cd5\u6bd4\u53e6\u4e00\u79cd\u7b97\u6cd5\u6027\u80fd\u660e\u663e\u66f4\u597d\u7684\u7279\u5b9a\u7684\u95ee\u9898\u89c4\u6a21\uff1f\u662f\u5426\u6709\u8ba9\u4e24\u79cd\u7b97\u6cd5\u90fd\u6267\u884c\u5927\u81f4\u76f8\u540c\u5de5\u4f5c\u91cf\u7684\u7279\u5b9a\u7684\u95ee\u9898\u89c4\u6a21\uff1f \u89e3\u7b54\uff1a \u5728\u6bd4\u8f83\u4e24\u79cd\u7b97\u6cd5\u7684\u6548\u7387\u65f6\uff0c\u901a\u5e38\u5173\u6ce8\u7b97\u6cd5\u6267\u884c\u65f6\u95f4\u968f\u95ee\u9898\u89c4\u6a21\u589e\u957f\u7684\u8d8b\u52bf\u3002\u9898\u76ee\u4e2d\u7684\u4e24\u79cd\u7b97\u6cd5\u7684\u6267\u884c\u6307\u4ee4\u6570\u5206\u522b\u5982\u4e0b\uff1a \u7b97\u6cd5A\uff1a\u6267\u884c n^2 \u6761\u6307\u4ee4\u3002 \u7b97\u6cd5B\uff1a\u6267\u884c (1/2)*n^2+(1/2)*n \u6761\u6307\u4ee4\u3002 \u7528\u5982\u4e0b\u4ee3\u7801\u6a21\u62df\u7b97\u6cd5A\u548c\u7b97\u6cd5B\uff0c\u53ef\u4ee5\u770b\u51fa\uff0c\u968f\u7740 n \u7684\u589e\u52a0\uff0c\u7b97\u6cd5A\u7684\u589e\u957f\u901f\u7387\u8fdc\u5927\u4e8e\u7b97\u6cd5B\u3002\u6240\u4ee5\u53ef\u4ee5\u8ba4\u4e3a\u5728 n >= 2 \u7684\u60c5\u51b5\u4e0b\uff0c\u7b97\u6cd5A\u4f18\u4e8e\u7b97\u6cd5B\u3002 n = 1 print ( \" %-15s%25s \" % ( \"ProblemSize: n\" , \"A/B\" )) while n < 1000000 : n *= 10 print ( \" %-15d%25d \" % ( n , int (( n ** 2 ) / ( 1 / 2 ) * n ** 2 + ( 1 / 2 ) * n ))) # ProblemSize: n A/B # 10 20005 # 100 200000050 # 1000 2000000000500 # 10000 20000000000005000 # 100000 200000000000000065536 # 1000000 1999999999999999966445568 \u7531\u6b64\u53ef\u5f97\uff0c\u5728\u5927\u95ee\u9898\u89c4\u6a21\u4e0b\uff0c\u7b97\u6cd5B\u7684\u589e\u957f\u901f\u7387\u4f1a\u66f4\u6162\uff0c\u56e0\u4e3a (1/2)*n^2+(1/2)*n \u4e2d\u7684 (1/2)*n \u90e8\u5206\u5bf9\u4e8e\u6574\u4f53\u589e\u957f\u6765\u8bf4\u76f8\u5bf9\u8f83\u5c0f\u3002 \u4e3a\u4e86\u8ba9\u4e24\u79cd\u7b97\u6cd5\u6267\u884c\u76f8\u8fd1\u7684\u5de5\u4f5c\u91cf\uff0c\u6211\u4eec\u53ef\u4ee5\u89e3\u4e0b\u9762\u7684\u65b9\u7a0b\uff1a ( 1 / 2 ) * n ^ 2 + ( 1 / 2 ) * n = k * n ^ 2 \u5176\u4e2d k \u662f\u4e00\u4e2a\u5e38\u6570\uff0c\u8868\u793a\u4e24\u79cd\u7b97\u6cd5\u6267\u884c\u7684\u5de5\u4f5c\u91cf\u76f8\u7b49\u65f6\u7684\u95ee\u9898\u89c4\u6a21\u3002\u901a\u8fc7\u89e3\u8fd9\u4e2a\u65b9\u7a0b\uff0c\u6211\u4eec\u53ef\u4ee5\u627e\u5230\u4e00\u4e2a\u95ee\u9898\u89c4\u6a21 k \uff0c\u5728\u8fd9\u4e2a\u95ee\u9898\u89c4\u6a21\u4e0b\uff0c\u4e24\u79cd\u7b97\u6cd5\u7684\u6267\u884c\u6307\u4ee4\u6570\u76f8\u8fd1\u3002 \u7b97\u6cd5\u7684\u6548\u7387\u5206\u6790\u5e76\u4e0d\u4ec5\u4ec5\u53d6\u51b3\u4e8e\u6307\u4ee4\u6570\uff0c\u8fd8\u53ef\u80fd\u53d7\u5230\u7b97\u6cd5\u4e2d\u5e38\u6570\u56e0\u5b50\u3001\u6570\u636e\u8bbf\u95ee\u6a21\u5f0f\u3001\u5185\u5b58\u5360\u7528\u7b49\u56e0\u7d20\u7684\u5f71\u54cd\u3002\u56e0\u6b64\uff0c\u5728\u5b9e\u9645\u5e94\u7528\u4e2d\uff0c\u901a\u5e38\u9700\u8981\u7efc\u5408\u8003\u8651\u591a\u4e2a\u56e0\u7d20\u6765\u786e\u5b9a\u6700\u4f18\u7684\u7b97\u6cd5\u9009\u62e9\u3002 \u5728\u4ec0\u4e48\u65f6\u5019\u5f00\u59cb n^4 \u7b97\u6cd5\u6bd4 2^n \u7b97\u6cd5\u8868\u73b0\u66f4\u597d\uff1f \u89e3\u7b54\uff1a\u7528\u4e0b\u9762\u7684\u7b97\u6cd5\u6a21\u62df n^4 \u7b97\u6cd5\u6bd4 2^n \u7b97\u6cd5\u6267\u884c\u5de5\u4f5c\u91cf\u3002\u4ece\u8fd0\u884c\u7ed3\u679c\u53ef\u4ee5\u770b\u51fa\uff1a n=16 \u662f\u5206\u754c\u70b9\uff0c n^4 \u7b97\u6cd5\u4e0e 2^n \u7b97\u6cd5\u5de5\u4f5c\u91cf\u76f8\u7b49\uff1b \u5f53 n<16 \u65f6\uff0c n^4 \u7b97\u6cd5\u6bd4 2^n \u7b97\u6cd5\u5de5\u4f5c\u91cf\u8981\u9ad8\uff1b \u5f53 n>16 \u65f6\uff0c n^4 \u7b97\u6cd5\u6bd4 2^n \u7b97\u6cd5\u5de5\u4f5c\u91cf\u8981\u4f4e\uff1b\u800c\u4e14 2^n \u7b97\u6cd5\u5de5\u4f5c\u91cf\u589e\u957f\u901f\u5ea6\u8fdc\u5927\u4e8e n^4 \u7b97\u6cd5\uff1b n = 1 print ( \" %-8s%10s%15s%10s \" % ( \"Size:n\" , \"A:n^4\" , \"B:2^n\" , \"B/A\" )) while n < 30 : n += 1 print ( \" %-8d%10d%15d%10.3f \" % ( n , int ( n ** 4 ), int ( 2 ** n ), ( 2 ** n ) / ( n ** 4 ))) # \u8fd0\u884c\u7ed3\u679c\uff1a # Size:n A:n^4 B:2^n B/A # 2 16 4 0.250 # 3 81 8 0.099 # 4 256 16 0.062 # 5 625 32 0.051 # 6 1296 64 0.049 # 7 2401 128 0.053 # 8 4096 256 0.062 # 9 6561 512 0.078 # 10 10000 1024 0.102 # 11 14641 2048 0.140 # 12 20736 4096 0.198 # 13 28561 8192 0.287 # 14 38416 16384 0.426 # 15 50625 32768 0.647 # 16 65536 65536 1.000 # 17 83521 131072 1.569 # 18 104976 262144 2.497 # 19 130321 524288 4.023 # 20 160000 1048576 6.554 # 21 194481 2097152 10.783 # 22 234256 4194304 17.905 # 23 279841 8388608 29.976 # 24 331776 16777216 50.568 # 25 390625 33554432 85.899 # 26 456976 67108864 146.854 # 27 531441 134217728 252.554 # 28 614656 268435456 436.725 # 29 707281 536870912 759.063 # 30 810000 1073741824 1325.607 3.3.\u641c\u7d22\u7b97\u6cd5 \u00b6 \u7ea6\u5b9a\uff1a \u4ee5\u5217\u8868\u4e3a\u4f8b\uff0c\u4ecb\u7ecd\u641c\u7d22\u548c\u6392\u5e8f\u7684\u7b97\u6cd5\uff1b \u9610\u91ca\u8fd9\u4e9b\u7b97\u6cd5\u7684\u8bbe\u8ba1\uff0c\u5e76\u628a\u5b83\u5b9e\u73b0\u4e3aPython\u51fd\u6570\uff1b \u51fd\u6570\u53ea\u5904\u7406\u5168\u90e8\u662f\u6574\u6570\u7684\u5217\u8868\uff0c\u4e0d\u540c\u5927\u5c0f\u7684\u5217\u8868\u5c06\u4f5c\u4e3a\u53c2\u6570\u4f20\u9012\u7ed9\u51fd\u6570\uff1b \u5bf9\u8fd9\u4e9b\u7b97\u6cd5\u7684\u8ba1\u7b97\u590d\u6742\u5ea6\u8fdb\u884c\u5206\u6790\uff1b 3.3.1.\u6700\u5c0f\u503c\u641c\u7d22 \u00b6 Python\u4e2d\u6709 min \u51fd\u6570\uff0c\u4f1a\u8fd4\u56de\u5217\u8868\u91cc\u7684\u6700\u5c0f\u503c\u6216\u6700\u5c0f\u5143\u7d20\uff0c\u4e0b\u9762\u5199\u4e00\u4e2a\u65b0\u7b97\u6cd5\uff0c\u6765\u5206\u6790 min \u51fd\u6570\u7684\u7b97\u6cd5\u590d\u6742\u5ea6\u3002 \u7b97\u6cd5\u76ee\u6807\uff1a\u5047\u5b9a\u5217\u8868\u4e0d\u4e3a\u7a7a\uff0c\u5e76\u4e14\u5143\u7d20\u662f\u6309\u7167\u4efb\u610f\u987a\u5e8f\u5b58\u653e\u5728\u5217\u8868\u91cc\u7684\uff0c\u7b97\u6cd5\u8fd4\u56de\u6700\u5c0f\u5143\u7d20\u7684\u7d22\u5f15\uff08index\uff09\u3002 \u7b97\u6cd5\u89e3\u6790\uff1a \u9996\u5148\u628a\u7b2c\u4e00\u4e2a\u4f4d\u7f6e\u4f5c\u4e3a\u5b58\u653e\u6700\u5c0f\u5143\u7d20\u7684\u4f4d\u7f6e\uff1b \u7136\u540e\u5411\u53f3\u4fa7\u641c\u7d22\u66f4\u5c0f\u7684\u5143\u7d20\uff1b \u5982\u679c\u627e\u5230\uff0c\u90a3\u4e48\u628a\u6700\u5c0f\u5143\u7d20\u7684\u4f4d\u7f6e\u91cd\u7f6e\u4e3a\u5f53\u524d\u4f4d\u7f6e\uff1b \u5f53\u7b97\u6cd5\u5230\u8fbe\u5217\u8868\u672b\u5c3e\u65f6\uff0c\u5b83\u5c06\u8fd4\u56de\u6700\u5c0f\u5143\u7d20\u7684\u4f4d\u7f6e\u3002 \u7b97\u6cd5\u5b9e\u73b0\uff1a def indexOfMin ( lyst ): \"\"\"\u8fd4\u56de\u6700\u5c0f\u5143\u7d20\u7684\u7d22\u5f15\uff0c\u76f8\u540c\u6700\u5c0f\u5143\u7d20\u8fd4\u56de\u7b2c\u4e00\u4e2a\u7d22\u5f15\"\"\" # \u7b97\u6cd5\u5f00\u59cb minIndex = 0 currentIndex = 1 while currentIndex < len ( lyst ): if lyst [ currentIndex ] < lyst [ minIndex ]: # \u6539\u6210<=\uff0c\u76f8\u540c\u6700\u5c0f\u5143\u7d20\u5219\u8fd4\u56de\u6700\u540e\u4e00\u4e2a\u7d22\u5f15 minIndex = currentIndex currentIndex += 1 return minIndex # \u7b97\u6cd5\u7ed3\u675f def main (): myList = [ 2 , 20 , 5 , 0 , 1 , 0 , 9 ] minIndex = indexOfMin ( myList ) print ( minIndex , myList [ minIndex ]) if __name__ == \"__main__\" : main () # \u8fd0\u7b97\u7ed3\u679c\uff1a # 3 0 # \u5982\u679c\u6539\u6210\u6539\u6210yst[currentIndex] <= lyst[minIndex]\uff0c\u5219\u76f8\u540c\u6700\u5c0f\u5143\u7d20\u5219\u8fd4\u56de\u6700\u540e\u4e00\u4e2a\u7d22\u5f15 # 5 0 \u65e0\u8bba\u5217\u8868\u7684\u5927\u5c0f\u5982\u4f55\uff0c\u5faa\u73af\u5916\u76843\u6761\u6307\u4ee4\uff082\u6761\u8d4b\u503c\u8bed\u53e5\uff0c\u4e00\u6761while\u8bed\u53e5\u672c\u8eab\uff09\u90fd\u4f1a\u6267\u884c\u76f8\u540c\u7684\u6b21\u6570\uff0c\u53ef\u4ee5\u5ffd\u7565\u5b83\u4eec\u90fd\u5f71\u54cd\u3002 \u5faa\u73af\u91cc\u8fd8\u67093\u6761\u6307\u4ee4\uff0c\u5176\u4e2d if \u8bed\u53e5\u5185\u7684\u6bd4\u8f83 lyst[currentIndex] < lyst[minIndex] \u548c currentIndex += 1 \u7684\u81ea\u589e\uff0c\u4f1a\u5728\u6bcf\u6b21\u5faa\u73af\u65f6\u90fd\u6267\u884c\uff0c\u4e14\u6ca1\u6709\u5176\u5b83\u5d4c\u5957\u6216\u9690\u85cf\u7684\u5faa\u73af\u3002 if \u8bed\u53e5\u4e2d\u7684\u6bd4\u8f83\u64cd\u4f5c\u5b9e\u73b0\u4e86\u8bbf\u95ee\u5217\u8868\u91cc\u7684\u6bcf\u4e2a\u5143\u7d20\uff0c\u4ece\u800c\u80fd\u591f\u627e\u5230\u6700\u5c0f\u5143\u7d20\u7684\u4f4d\u7f6e\u3002 \u56e0\u6b64\uff0c\u8fd9\u4e2a\u7b97\u6cd5\u5fc5\u987b\u5bf9\u5927\u5c0f\u4e3a n \u7684\u5217\u8868\u8fdb\u884c n-1 \u6b21\u6bd4\u8f83\uff0c\u5373\uff0c\u5b83\u7684\u590d\u6742\u5ea6\u4e3aO(n)\u3002 3.3.2.\u987a\u5e8f\u641c\u7d22\u5217\u8868 \u00b6 Python\u7684 in \u8fd0\u7b97\u7b26\u5728list\u7c7b\u91cc\u88ab\u5b9e\u73b0\u4e3a\u53eb\u4f5c __contains__ \u7684\u65b9\u6cd5\uff0c\u8fd9\u4e2a\u65b9\u6cd5\u4f1a\u5728\u4efb\u610f\u7684\u5143\u7d20\u5217\u8868\u91cc\u641c\u7d22\u7279\u5b9a\u7684\u5143\u7d20\uff0c\u5373\u76ee\u6807\u5143\u7d20\uff08target item\uff09\u3002 \u5728\u5217\u8868\u91cc\uff0c\u627e\u5230\u76ee\u6807\u5143\u7d20\u7684\u552f\u4e00\u65b9\u6cd5\u662f\u4ece\u4f4d\u4e8e\u7b2c\u4e00\u4e2a\u4f4d\u7f6e\u7684\u5143\u7d20\u5f00\u59cb\uff0c\u5e76\u628a\u5b83\u548c\u76ee\u6807\u5143\u7d20\u8fdb\u884c\u6bd4\u8f83\u3002\u5982\u679c\u4e24\u4e2a\u5143\u7d20\u76f8\u7b49\uff0c\u90a3\u4e48\u8fd9\u4e2a\u65b9\u6cd5\u8fd4\u56de True \uff1b\u5426\u5219\uff0c\u8fd9\u4e2a\u65b9\u6cd5\u5c06\u79fb\u52a8\u5230\u4e0b\u4e00\u4e2a\u4f4d\u7f6e\uff0c\u5e76\u628a\u5b83\u548c\u76ee\u6807\u5143\u7d20\u8fdb\u884c\u6bd4\u8f83\u3002\u5982\u679c\u8fd9\u4e2a\u65b9\u6cd5\u5230\u4e86\u6700\u540e\u4e00\u4e2a\u4f4d\u7f6e\u4ecd\u7136\u627e\u4e0d\u5230\u76ee\u6807\uff0c\u90a3\u4e48\u8fd4\u56de False \u3002\u8fd9\u79cd\u641c\u7d22\u79f0\u4e3a\u987a\u5e8f\u641c\u7d22\uff08sequential search\uff09\u6216\u7ebf\u6027\u641c\u7d22\uff08linear search\uff09\u3002 \u4e0b\u9762\u662f\u987a\u5e8f\u641c\u7d22\u51fd\u6570\u7684\u5b9e\u73b0\u3002\u82e5\u987a\u5e8f\u641c\u7d22\u7b97\u6cd5\u5728\u5217\u8868\u5f00\u5934\u5c31\u627e\u5230\u76ee\u6807\u5143\u7d20\uff0c\u90a3\u4e48\u8fd9\u65f6\u7684\u5de5\u4f5c\u91cf\u660e\u663e\u4f1a\u6bd4\u5728\u5217\u8868\u672b\u5c3e\u627e\u5230\u7684\u5de5\u4f5c\u91cf\u8981\u5c11\u3002 def sequentialSearch ( target , lyst ): \"\"\"\u627e\u5230\u76ee\u6807\u5143\u7d20\u65f6\u8fd4\u56de\u5143\u7d20\u7684\u7d22\u5f15, \u5426\u5219\u8fd4\u56de-1\"\"\" position = 0 while position < len ( lyst ): if target == lyst [ position ]: return position position += 1 return - 1 def main (): myList = [ 2 , 20 , 5 , 0 , 1 , 0 , 9 ] locatedIndex = sequentialSearch ( 9 , myList ) print ( locatedIndex , myList [ locatedIndex ]) if __name__ == \"__main__\" : main () # \u8fd0\u7b97\u7ed3\u679c\uff1a # 6 9 3.3.3.\u6700\u597d\u60c5\u51b5\u3001\u6700\u574f\u60c5\u51b5\u4ee5\u53ca\u5e73\u5747\u60c5\u51b5\u4e0b\u7684\u6027\u80fd \u00b6 \u4e00\u822c\u6765\u8bf4\uff0c\u91cd\u70b9\u5173\u6ce8\u5728\u5e73\u5747\u60c5\u51b5\u548c\u6700\u574f\u60c5\u51b5\u4e0b\u7684\u6027\u80fd\uff0c\u4e0d\u4f1a\u7279\u522b\u5173\u6ce8\u6700\u597d\u60c5\u51b5\u3002 \u5bf9\u987a\u5e8f\u641c\u7d22\u7684\u5206\u6790\u9700\u8981\u8003\u8651\u4e0b\u97623\u79cd\u60c5\u51b5\u3002 \u5728\u6700\u574f\u60c5\u51b5\u4e0b\uff0c\u76ee\u6807\u5143\u7d20\u4f4d\u4e8e\u5217\u8868\u7684\u672b\u5c3e\u6216\u8005\u6839\u672c\u5c31\u4e0d\u5728\u5217\u8868\u91cc\u3002\u8fd9\u65f6\uff0c\u8fd9\u4e2a\u7b97\u6cd5\u5c31\u5fc5\u987b\u8bbf\u95ee\u6bcf\u4e00\u4e2a\u5143\u7d20\uff0c\u5bf9\u5927\u5c0f\u4e3a n \u7684\u5217\u8868\u9700\u8981\u6267\u884c n \u6b21\u8fed\u4ee3\u3002\u56e0\u6b64\uff0c\u987a\u5e8f\u641c\u7d22\u7684\u6700\u574f\u60c5\u51b5\u7684\u590d\u6742\u5ea6\u4e3aO(n)\u3002 \u5728\u6700\u597d\u60c5\u51b5\u4e0b\uff0c\u53ea\u9700\u8981O(1)\u7684\u590d\u6742\u5ea6\uff0c\u56e0\u4e3a\u8fd9\u4e2a\u7b97\u6cd5\u5728\u4e00\u6b21\u8fed\u4ee3\u4e4b\u540e\u5c31\u4f1a\u5728\u7b2c\u4e00\u4e2a\u4f4d\u7f6e\u627e\u5230\u76ee\u6807\u5143\u7d20\u3002 \u8981\u786e\u5b9a\u5e73\u5747\u60c5\u51b5\uff0c\u5c31\u9700\u8981\u628a\u6bcf\u4e2a\u53ef\u80fd\u4f4d\u7f6e\u627e\u5230\u76ee\u6807\u6240\u9700\u8981\u7684\u8fed\u4ee3\u6b21\u6570\u76f8\u52a0\uff0c\u7136\u540e\u518d\u5c06\u5b83\u4eec\u7684\u603b\u548c\u9664\u4ee5 n \u3002\u56e0\u6b64\uff0c\u8fd9\u79cd\u60c5\u51b5\u4e0b\uff0c\u7b97\u6cd5\u4f1a\u6267\u884c (n + n\u22121 + n\u22122+ ... +1)/n \u6216 (n+1)/2 \u6b21\u8fed\u4ee3\u3002\u5bf9\u4e8e\u975e\u5e38\u5927\u7684 n \u6765\u8bf4\uff0c\u5e38\u6570\u7cfb\u65702\u662f\u53ef\u4ee5\u5ffd\u7565\u7684\uff0c\u56e0\u6b64\uff0c\u5e73\u5747\u60c5\u51b5\u7684\u590d\u6742\u5ea6\u4ecd\u7136\u662fO(2)\u3002 \u7ed3\u8bba\uff1a\u6700\u597d\u60c5\u51b5\u4e0b\u987a\u5e8f\u641c\u7d22\u7684\u6027\u80fd\u548c\u5176\u4ed6\u4e24\u79cd\u60c5\u51b5\u6bd4\u8d77\u6765\u5c0f\u5f88\u591a\uff0c\u800c\u5176\u4ed6\u4e24\u79cd\u60c5\u51b5\u4e0b\u7684\u6027\u80fd\u662f\u5dee\u4e0d\u591a\u7684\u3002 3.3.4.\u57fa\u4e8e\u6709\u5e8f\u5217\u8868\u7684\u4e8c\u5206\u641c\u7d22 \u00b6 \u5728\u6570\u636e\u65e0\u5e8f\u7684\u60c5\u51b5\u4e0b\uff0c\u4f7f\u7528\u987a\u5e8f\u641c\u7d22\u6765\u627e\u5230\u76ee\u6807\u5143\u7d20\u3002 \u5728\u6570\u636e\u6709\u5e8f\u7684\u60c5\u51b5\u4e0b\uff0c\u4f7f\u7528\u4e8c\u5206\u641c\u7d22\u6765\u627e\u5230\u76ee\u6807\u5143\u7d20\u3002 Python\u4e2d\u5b9e\u73b0\u4e8c\u5206\u641c\u7d22\u7684\u601d\u8def\uff1a \u5047\u8bbe\u5217\u8868\u91cc\u7684\u5143\u7d20\u90fd\u4ee5\u5347\u5e8f\u6392\u5e8f\u3002 \u641c\u7d22\u7b97\u6cd5\u9996\u5148\u5230\u5217\u8868\u7684\u4e2d\u95f4\u4f4d\u7f6e\uff0c\u5e76\u628a\u8fd9\u4e2a\u4f4d\u7f6e\u7684\u5143\u7d20\u4e0e\u76ee\u6807\u5143\u7d20\u8fdb\u884c\u6bd4\u8f83\uff1b \u5982\u679c\u5339\u914d\uff0c\u90a3\u4e48\u7b97\u6cd5\u5c31\u8fd4\u56de\u5f53\u524d\u4f4d\u7f6e\u3002\u5982\u679c\u76ee\u6807\u5143\u7d20\u5c0f\u4e8e\u5f53\u524d\u5143\u7d20\uff0c\u90a3\u4e48\u7b97\u6cd5\u5c06\u4f1a\u641c\u7d22\u4e2d\u95f4\u4f4d\u7f6e\u4e4b\u524d\u7684\u90e8\u5206\uff1b \u5982\u679c\u76ee\u6807\u5143\u7d20\u5927\u4e8e\u5f53\u524d\u5143\u7d20\uff0c\u5219\u641c\u7d22\u4e2d\u95f4\u4f4d\u7f6e\u4e4b\u540e\u7684\u90e8\u5206\u3002 \u5728\u627e\u5230\u4e86\u76ee\u6807\u5143\u7d20\u6216\u8005\u5f53\u524d\u5f00\u59cb\u4f4d\u7f6e\u5927\u4e8e\u5f53\u524d\u7ed3\u675f\u4f4d\u7f6e\u65f6\uff0c\u505c\u6b62\u641c\u7d22\u8fc7\u7a0b\u3002 \u4e0b\u9762\u662f\u4e8c\u5206\u641c\u7d22\u51fd\u6570\u7684\u4ee3\u7801\u3002\u4ee5\u5217\u8868 [2, 20, 5, 0, 1, 0, 9] \u4e3a\u4f8b\uff1a \u6392\u5e8f\u540e\u7684\u5217\u8868\u4e3a [0, 0, 1, 2, 5, 9, 20] \uff1b \u6392\u5e8f\u540e\u5217\u8868\u957f\u5ea6\u662f7\uff0c\u6240\u4ee5\u521d\u59cbmidpoint=3\uff0c\u5bf9\u5e94\u5217\u8868\u503c\u662f2\uff1b def binarySearch ( target , sortedLyst ): left = 0 right = len ( sortedLyst ) - 1 while left <= right : midpoint = ( left + right ) // 2 if target == sortedLyst [ midpoint ]: return midpoint elif target < sortedLyst [ midpoint ]: right = midpoint - 1 else : left = midpoint + 1 return - 1 def main (): myList = [ 2 , 20 , 5 , 0 , 1 , 0 , 9 ] sortedList = sorted ( myList ) # \u5982\u679c\u4f7f\u7528myList.sort()\uff0c\u5219\u4f1a\u4fee\u6539myList\u672c\u8eab locatedIndex = binarySearch ( 5 , sortedList ) print ( sortedList ) print ( locatedIndex , sortedList [ locatedIndex ]) if __name__ == \"__main__\" : main () # \u8fd0\u7b97\u7ed3\u679c\uff1a # [0, 0, 1, 2, 5, 9, 20] # 4 5 # \u5982\u679c\u6267\u884cbinarySearch(0, sortedList)\uff0c\u5219\u4f1a\u8fd4\u56de\u7b2c\u4e8c\u4e2a0\u7684\u7d22\u5f15 # [0, 0, 1, 2, 5, 9, 20] # 1 0 \u4e0a\u9762\u4e8c\u5206\u6cd5\u7b97\u6cd5\u590d\u6742\u5ea6\u5206\u6790\uff1a \u7b97\u6cd5\u91cc\u53ea\u6709\u4e00\u4e2a\u5faa\u73af\uff0c\u5e76\u4e14\u6ca1\u6709\u5d4c\u5957\u6216\u9690\u85cf\u7684\u5faa\u73af\u3002\u5982\u679c\u76ee\u6807\u4e0d\u5728\u5217\u8868\u91cc\uff0c\u5c31\u4f1a\u5f97\u5230\u6700\u574f\u60c5\u51b5\uff0c\u5373\u904d\u5386\u5217\u8868\u7684\u4e00\u534a\uff0c\u5373\u5faa\u73af\u5217\u8868\u5927\u5c0f\u4e0d\u65ad\u9664\u4ee52\u76f4\u81f3\u5546\u4e3a1\u7684\u6b21\u6570\u3002 \u5bf9\u4e8e\u5927\u5c0f\u4e3a n \u7684\u5217\u8868\u6765\u8bf4\uff0c\u4e5f\u5c31\u662f\u4f60\u9700\u8981\u6267\u884c n/2/2/.../2 \u6b21\uff0c\u76f4\u5230\u7ed3\u679c\u4e3a1\u3002\u5047\u8bbe k \u662f n \u53ef\u4ee5\u9664\u4ee52\u7684\u6b21\u6570\uff0c\u90a3\u4e48\u6c42\u89e3 k \u4f1a\u6709 n/(2^k)=1 \uff0c\u5373 n=2^k \uff0c\u5373 k=log(n,2) \u3002\u56e0\u6b64\uff0c\u4e8c\u5206\u641c\u7d22\u5728\u6700\u574f\u60c5\u51b5\u4e0b\u7684\u590d\u6742\u5ea6\u4e3aO(log(n,2))\u3002 3.3.5.\u6bd4\u8f83\u6570\u636e\u5143\u7d20 \u00b6 \u4e8c\u5206\u641c\u7d22\u548c\u6700\u5c0f\u503c\u641c\u7d22\u90fd\u6709\u4e00\u4e2a\u5047\u8bbe\uff0c\u90a3\u5c31\u662f\u201c\u5217\u8868\u91cc\u7684\u5143\u7d20\u5f7c\u6b64\u4e4b\u95f4\u662f\u53ef\u4ee5\u6bd4\u8f83\u7684\u201d\u3002\u5373\uff0c\u8fd9\u4e9b\u5143\u7d20\u5c5e\u4e8e\u540c\u4e00\u4e2a\u7c7b\u578b\uff0c\u5373\uff0c\u53ef\u4ee5\u4f7f\u7528\u6bd4\u8f83\u8fd0\u7b97\u7b26 == \u3001 < \u548c > \u3002 Python\u5185\u7f6e\u7684\u7c7b\u578b\u5bf9\u8c61\uff0c\u5982\u6570\u5b57\u3001\u5b57\u7b26\u4e32\u548c\u5217\u8868\uff0c\u90fd\u652f\u6301\u6bd4\u8f83\u8fd0\u7b97\u7b26\u3002 \u4e3a\u4e86\u80fd\u591f\u8ba9\u7b97\u6cd5\u5bf9\u65b0\u7684\u7c7b\u5bf9\u8c61\u4f7f\u7528\u6bd4\u8f83\u8fd0\u7b97\u7b26 == \u3001 < \u548c > \uff0c\u5e94\u8be5\u5728\u8fd9\u4e2a\u7c7b\u91cc\u5b9a\u4e49 __eq__ \u3001 __lt__ \u548c __gt__ \u65b9\u6cd5\u3002\u5728\u5b9a\u4e49\u4e86\u8fd9\u4e9b\u65b9\u6cd5\u4e4b\u540e\uff0c\u5176\u4ed6\u6bd4\u8f83\u8fd0\u7b97\u7b26\u7684\u65b9\u6cd5\u5c06\u81ea\u52a8\u751f\u6210\u3002 \u4f8b\u5982\uff0c __lt__ \u7684\u5b9a\u4e49\u5982\u4e0b\uff0c\u5982\u679c self \u5c0f\u4e8e other \uff0c\u90a3\u4e48\u8fd9\u4e2a\u65b9\u6cd5\u5c06\u8fd4\u56de True \uff1b\u5426\u5219\uff0c\u8fd4\u56de False \u3002 __lt__ \u65b9\u6cd5\u4f1a\u4e3a\u4e24\u4e2a\u8d26\u6237\u5bf9\u8c61\u7684 name \u5b57\u6bb5\u8c03\u7528\u8fd0\u7b97\u7b26 < \u3002 \u540d\u79f0\u5b57\u6bb5\u662f\u5b57\u7b26\u4e32\uff0c\u5b57\u7b26\u4e32\u7c7b\u578b\u5df2\u7ecf\u5305\u542b\u5728 __lt__ \u65b9\u6cd5\u91cc\u3002 \u5728\u4f7f\u7528\u8fd0\u7b97\u7b26 < \u65f6\uff0cPython\u4f1a\u81ea\u52a8\u8fd0\u884c\u5b57\u7b26\u4e32\u7684 __lt__ \u65b9\u6cd5\uff0c\u8fd9\u4e0e\u8c03\u7528 str \u51fd\u6570\u65f6\u81ea\u52a8\u8fd0\u884c __str__ \u65b9\u6cd5\u662f\u7c7b\u4f3c\u7684\u3002 def __lt__ ( self , other ): \u793a\u4f8b\uff1a\u8fd4\u56de\u50a8\u84c4\u8d26\u6237\u7684\u6240\u6709\u4eba\u540d\u5b57\u3001PIN\u7801\u3001\u4f59\u989d\u3002 class SavingsAccount ( object ): \"\"\"\u8fd4\u56de\u50a8\u84c4\u8d26\u6237\u7684\u6240\u6709\u4eba\u540d\u5b57\u3001PIN\u7801\u3001\u4f59\u989d\"\"\" def __init__ ( self , name , pin , balance = 0.0 ): self . name = name self . pin = pin self . balance = balance def __lt__ ( self , other ): return self . name < other . name # Other methods, including __eq__ def main (): s1 = SavingsAccount ( \"Ken\" , \"1001\" , 0 ) s2 = SavingsAccount ( \"Bill\" , \"1001\" , 30 ) s3 = SavingsAccount ( \"Ken\" , \"1000\" , 0 ) s4 = s1 print ( \"s1 < s2: \" , s1 < s2 ) print ( \"s2 < s1: \" , s2 < s1 ) print ( \"s2 > s1: \" , s2 > s1 ) print ( \"s2 == s1: \" , s2 == s1 ) print ( \"s1 == s3: \" , s1 == s3 ) print ( \"s1 == s4: \" , s1 == s4 ) if __name__ == \"__main__\" : main () # \u8fd0\u7b97\u7ed3\u679c\uff1a # s1 < s2: False # s2 < s1: True # s2 > s1: False # s2 == s1: False # s1 == s3: False # s1 == s4: True \u63d0\u793a\uff1a\u5728Python\u4e2d\uff0c\u9ed8\u8ba4\u662f\u6309\u7167ASCII\u7684\u5927\u5c0f\u6bd4\u8f83\u5b57\u7b26\u4e32\u7684\uff0c\u5373\u4ece\u5b57\u7b26\u4e32\u7684\u7b2c\u4e00\u4e2a\u5b57\u7b26\u8fdb\u884c\u6bd4\u8f83\uff0c\u5982\u679c\u76f8\u7b49\uff0c\u5219\u7ee7\u7eed\u6bd4\u8f83\u4e0b\u4e00\u4e2a\u5b57\u7b26\uff0c\u76f4\u5230\u5206\u51fa\u5927\u5c0f\uff0c\u6216\u8005\u8fd8\u6ca1\u5206\u51fa\u5927\u5c0f\uff0c\u6709\u4e00\u4e2a\u5b57\u7b26\u4e32\u5df2\u7ecf\u5230\u5934\u4e86\uff0c\u90a3\u4e48\u8f83\u957f\u7684\u90a3\u4e00\u4e2a\u5b57\u7b26\u4e32\u5927\u3002 3.3.6.\u7ec3\u4e60\u9898 \u00b6 \u5047\u8bbe\u4e00\u4e2a\u5217\u8868\u5728\u7d22\u5f150\uff5e9\u7684\u4f4d\u7f6e\u5904\u5305\u542b\u503c20\u300144\u300148\u300155\u300162\u300166\u300174\u300188\u300193\u300199\uff0c\u8bf7\u5728\u7528\u4e8c\u5206\u641c\u7d22\u67e5\u627e\u76ee\u6807\u5143\u7d2090\u7684\u65f6\u5019\uff0c\u5bf9\u53d8\u91cfleft\u3001right\u548cmidpoint\u7684\u503c\u8fdb\u884c\u8ddf\u8e2a\u3002\u6539\u53d8\u76ee\u6807\u5143\u7d20\u4e3a44\uff0c\u5e76\u91cd\u590d\u8fd9\u4e2a\u6b65\u9aa4\u3002 \u89e3\u7b54\uff1a \u4e0b\u9762\u662f\u4ee3\u7801\u548c\u8ddf\u8e2a\u7ed3\u679c\u3002 def binarySearch ( target , sortedLyst ): left = 0 right = len ( sortedLyst ) - 1 print ( \" %5s%10s%10s \" % ( \"left\" , \"midpoint\" , \"right\" )) while left <= right : midpoint = ( left + right ) // 2 print ( \" %5s%10s%10s \" % ( left , midpoint , right )) if target == sortedLyst [ midpoint ]: return midpoint elif target < sortedLyst [ midpoint ]: right = midpoint - 1 else : left = midpoint + 1 return - 1 def main (): myList = [ 20 , 44 , 48 , 55 , 62 , 66 , 74 , 88 , 93 , 99 ] sortedList = sorted ( myList ) locatedIndex = binarySearch ( 44 , sortedList ) if __name__ == \"__main__\" : main () # \u8fd0\u7b97\u7ed3\u679c\uff1a # Target = 90 # left midpoint right # 0 4 9 # 5 7 9 # 8 8 9 # # Target = 44 # left midpoint right # 0 4 9 # 0 1 3 \u901a\u5e38\u6765\u8bf4\uff0c\u67e5\u627e\u7535\u8bdd\u7c3f\u4e2d\u6761\u76ee\u7684\u65b9\u6cd5\u4e0e\u4e8c\u5206\u641c\u7d22\u5e76\u4e0d\u5b8c\u5168\u76f8\u540c\uff0c\u56e0\u4e3a\u4f7f\u7528\u7535\u8bdd\u7c3f\u7684\u65f6\u5019\uff0c\u5e76\u4e0d\u4f1a\u6bcf\u6b21\u90fd\u7ffb\u5230\u88ab\u641c\u7d22\u7684\u5b50\u5217\u8868\u7684\u4e2d\u70b9\u3002\u4e00\u822c\u6765\u8bf4\uff0c\u53ef\u4ee5\u6839\u636e\u8fd9\u4e2a\u4eba\u7684\u59d3\u6c0f\u7684\u7b2c\u4e00\u4e2a\u5b57\u6bcd\u987a\u5e8f\u6765\u4f30\u7b97\u76ee\u6807\u53ef\u80fd\u4f1a\u5728\u7684\u4f4d\u7f6e\u3002\u4f8b\u5982\uff0c\u5f53\u67e5\u627e\u201cSmith\u201d\u7684\u7535\u8bdd\u65f6\uff0c\u4f60\u4f1a\u9996\u5148\u67e5\u770b\u7535\u8bdd\u7c3f\u4e0b\u534a\u90e8\u5206\u7684\u4e2d\u95f4\uff0c\u800c\u4e0d\u662f\u6574\u4e2a\u7535\u8bdd\u7c3f\u7684\u4e2d\u95f4\u3002\u8bf7\u5bf9\u4e8c\u5206\u641c\u7d22\u7b97\u6cd5\u5c1d\u8bd5\u8fdb\u884c\u4fee\u6539\uff0c\u4ece\u800c\u53ef\u4ee5\u5728\u5904\u7406\u540d\u79f0\u5217\u8868\u7684\u65f6\u5019\u6a21\u62df\u8fd9\u4e2a\u7b56\u7565\u3002\u5b83\u7684\u8ba1\u7b97\u590d\u6742\u5ea6\u4e0e\u6807\u51c6\u7684\u4e8c\u5206\u641c\u7d22\u76f8\u6bd4\u8f83\u4f1a\u66f4\u597d\u5417\uff1f \u89e3\u7b54\uff1a\u4e0b\u9762\u662f\u4ee3\u7801\u548c\u8ffd\u8e2a\u7ed3\u679c\u3002\u901a\u8fc7\u5bf9\u6bd4\u4e0d\u540c\u6743\u91cd\u5355\u8bcd\u5230\u7684\u641c\u7d22\uff0c\u53ef\u4ee5\u53d1\u73b0\u6743\u91cd\u4e8c\u5206\u6cd5\u7684\u6548\u7387\u82e5\u8981\u4f18\u4e8e\u4f20\u7edf\u4e8c\u5206\u6cd5\uff0c\u662f\u9700\u8981\u6ee1\u8db3\u4e00\u5b9a\u7684\u6761\u4ef6\u7684\u3002 \u5728\u641c\u7d22\u7684\u7b2c\u4e00\u8f6e\u4e2d\uff0c\u4e2d\u95f4\u4f4d\u7f6e\u5c06\u53d6\u51b3\u4e8e\u5217\u8868\u7684\u5927\u5c0f\u548c\u76ee\u6807\u540d\u5b57\u7684\u7b2c\u4e00\u4e2a\u5b57\u6bcd\u7684\u987a\u5e8f\u503c\u3002\u56e0\u6b64\uff0c\u7b2c\u4e00\u8f6e\u641c\u7d22\u5c06\u6d88\u9664\u6bd4\u4ee5\u524d\u66f4\u591a\u7684\u5143\u7d20\uff0c\u5e76\u4e14\u5982\u679c\u9700\u8981\u5176\u4ed6\u8f6e\u641c\u7d22\uff0c\u5b83\u4eec\u7684\u641c\u7d22\u7a7a\u95f4\u4e5f\u4f1a\u66f4\u5c0f\u3002\u7136\u800c\uff0c\u5728\u6700\u574f\u60c5\u51b5\u4e0b\uff0c\u4fee\u6539\u540e\u7684\u7b97\u6cd5\u4ecd\u7136\u6bd4O(1)\u66f4\u63a5\u8fd1O(log n)\u3002 def binarySearch ( target , sortedLyst ): left = 0 right = len ( sortedLyst ) - 1 print ( \" %5s%10s%10s \" % ( \"left\" , \"midpoint\" , \"right\" )) while left <= right : midpoint = ( left + right ) // 2 print ( \" %5s%10s%10s \" % ( left , midpoint , right )) if target == sortedLyst [ midpoint ]: return midpoint elif target < sortedLyst [ midpoint ]: right = midpoint - 1 else : left = midpoint + 1 return - 1 def letter_position ( myLetter ): letter = myLetter . lower () # \u8f6c\u6210\u5c0f\u5199\u5b57\u6bcd alphabet = \"abcdefghijklmnopqrstuvwxyz\" if letter in alphabet : return alphabet . index ( letter ) + 1 # \u4f4d\u7f6e\u63091\uff5e26\u8ba1\u7b97 else : return None # \u975e\u5b57\u6bcd def dictSearch ( target , sortedLyst ): left = 0 right = len ( sortedLyst ) - 1 # \u9996\u5b57\u6bcd\u5728\u5b57\u6bcd\u8868\u4e2d\u7684\u767e\u5206\u4f4d letter_position_range = letter_position ( target [ 0 ]) * 100 // 26 # \u6309\u7167\u6240\u5f97\u7684\u9996\u5b57\u6bcd\u5728\u5b57\u6bcd\u8868\u4e2d\u7684\u767e\u5206\u4f4d\uff0c\u4f5c\u4e3a\u7ed9\u5b9a\u5b57\u4e32\u4e2d\u8bbe\u5b9a\u641c\u7d22\u8d77\u59cb\u767e\u5206\u4f4d midpoint = letter_position_range * ( len ( sortedLyst ) - 1 ) // 100 print ( \" %5s%10s%10s \" % ( \"left\" , \"midpoint\" , \"right\" )) while left <= right : print ( \" %5s%10s%10s \" % ( left , midpoint , right )) if target == sortedLyst [ midpoint ]: return midpoint elif target < sortedLyst [ midpoint ]: right = midpoint - 1 else : left = midpoint + 1 midpoint = ( left + right ) // 2 return - 1 def main (): myList = [ \"Bob\" , \"Charlie\" , \"Eva\" , \"Alice\" , \"Grace\" , \"David\" , \"Smith\" , \"Frank\" , \"Zoe\" , \"Jack\" ] sortedList = sorted ( myList ) print ( sortedList ) print ( \"=====call binarySearch=====\" ) locatedIndex = binarySearch ( \"Alice\" , sortedList ) print ( \"Found\" , sortedList [ locatedIndex ], \"in position\" , locatedIndex ) print ( \"=====call dictSearch=====\" ) locatedIndex = dictSearch ( \"Alice\" , sortedList ) print ( \"Found\" , sortedList [ locatedIndex ], \"in position\" , locatedIndex ) if __name__ == \"__main__\" : main () # \u8fd0\u7b97\u7ed3\u679c\uff1a # \u641c\u7d22Alice # ['Alice', 'Bob', 'Charlie', 'David', 'Eva', 'Frank', 'Grace', 'Jack', 'Smith', 'Zoe'] # =====call binarySearch===== # left midpoint right # 0 4 9 # 0 1 3 # 0 0 0 # Found Alice in position 0 # =====call dictSearch===== # left midpoint right # 0 0 9 # Found Alice in position 0 # \u641c\u7d22Bob # ['Alice', 'Bob', 'Charlie', 'David', 'Eva', 'Frank', 'Grace', 'Jack', 'Smith', 'Zoe'] # =====call binarySearch===== # left midpoint right # 0 4 9 # 0 1 3 # Found Bob in position 1 # =====call dictSearch===== # left midpoint right # 0 0 9 # 1 5 9 # 1 2 4 # 1 1 1 # Found Bob in position 1 # \u641c\u7d22Smith # ['Alice', 'Bob', 'Charlie', 'David', 'Eva', 'Frank', 'Grace', 'Jack', 'Smith', 'Zoe'] # =====call binarySearch===== # left midpoint right # 0 4 9 # 5 7 9 # 8 8 9 # Found Smith in position 8 # =====call dictSearch===== # left midpoint right # 0 6 9 # 7 8 9 # Found Smith in position 8 # \u641c\u7d22Zoe # ['Alice', 'Bob', 'Charlie', 'David', 'Eva', 'Frank', 'Grace', 'Jack', 'Smith', 'Zoe'] # =====call binarySearch===== # left midpoint right # 0 4 9 # 5 7 9 # 8 8 9 # 9 9 9 # Found Zoe in position 9 # =====call dictSearch===== # left midpoint right # 0 9 9 # Found Zoe in position 9 3.4.\u57fa\u672c\u7684\u6392\u5e8f\u7b97\u6cd5 \u00b6 \u4e0b\u9762\u662fswap\u51fd\u6570\u7684\u4f8b\u5b50\uff0c\u5b9e\u73b0\u4e86\uff1a \u5047\u8bbe\u90fd\u5728\u6574\u6570\u5217\u8868\u4e0a\u8fd0\u884c\uff1b \u4ea4\u6362\u5217\u8868\u4e2d\u4e24\u4e2a\u5143\u7d20\u7684\u4f4d\u7f6e\uff1b def swap ( lyst , i , j ): \"\"\"\u4ea4\u6362\u5143\u7d20\u4f4d\u7f6e\u4e3ai\u548cj\u7684\u5143\u7d20\"\"\" temp = lyst [ i ] lyst [ i ] = lyst [ j ] lyst [ j ] = temp def main (): myList = [ 9 , 4 , 2 , 7 , 6 , 8 , 1 ] print ( myList ) swap ( myList , 3 , 5 ) print ( myList ) if __name__ == \"__main__\" : main () # \u8fd0\u884c\u7ed3\u679c\uff1a # [9, 4, 2, 7, 6, 8, 1] # [9, 4, 2, 8, 6, 7, 1] 3.4.1.\u9009\u62e9\u6392\u5e8f \u00b6 \u9009\u62e9\u6392\u5e8f\uff08selection sort\uff09\uff1a\uff08\u4ee5\u5217\u8868\u4e3a\u4f8b\uff09 \u5728\u4e00\u4e2a\u957f\u5ea6\u4e3a N \u7684\u65e0\u5e8f\u5217\u8868\u4e2d\uff0c\u7b2c\u4e00\u6b21\u904d\u5386 n-1 \u4e2a\u6570\u627e\u5230\u6700\u5c0f\u7684\u548c\u7b2c\u4e00\u4e2a\u6570\u4ea4\u6362\u3002 \u7b2c\u4e8c\u6b21\u4ece\u4e0b\u4e00\u4e2a\u6570\u5f00\u59cb\u904d\u5386 n-2 \u4e2a\u6570\uff0c\u627e\u5230\u6700\u5c0f\u7684\u6570\u548c\u7b2c\u4e8c\u4e2a\u6570\u4ea4\u6362\u3002 \u91cd\u590d\u4ee5\u4e0a\u64cd\u4f5c\u76f4\u5230\u7b2c n-1 \u6b21\u904d\u5386\u6700\u5c0f\u7684\u6570\u548c\u7b2c n-1 \u4e2a\u6570\u4ea4\u6362\uff0c\u6392\u5e8f\u5b8c\u6210\u3002 \u8fd9\u4e2a\u7b97\u6cd5\u5728\u6bcf\u6b21\u901a\u8fc7\u4e3b\u5faa\u73af\u65f6\uff0c\u90fd\u4f1a\u9009\u62e9\u8981\u79fb\u52a8\u7684\u90a3\u4e00\u4e2a\u5143\u7d20\u3002 \u7b97\u6cd5\u590d\u6742\u5ea6\uff1a \u7b2c1\u6b21\u6267\u884c\u5916\u90e8\u5faa\u73af\u65f6\uff0c\u5185\u90e8\u5faa\u73af\u4f1a\u6267\u884cn-1\u6b21\uff1b \u7b2c2\u6b21\u6267\u884c\u5916\u90e8\u5faa\u73af\u65f6\uff0c\u5185\u90e8\u5faa\u73af\u4f1a\u6267\u884cn-2\u6b21\uff1b \u6700\u540e\u4e00\u6b21\u6267\u884c\u5916\u90e8\u5faa\u73af\u65f6\uff0c\u5185\u90e8\u5faa\u73af\u4f1a\u6267\u884c1\u6b21\uff1b \u6240\u4ee5\uff0c\u5927\u5c0f\u4e3a n \u7684\u5217\u8868\uff0c\u4e00\u5171\u9700\u8981\u7684\u6bd4\u8f83\u6b21\u6570\u662f (n-1)+(n-2)+...+1 \uff0c\u5316\u7b80\u4e3a n*(n-1)/2 \uff0c\u5373 (1/2)*n^2+(1/2)*n \u3002\u5f53 n \u6bd4\u8f83\u5927\u65f6\uff0c\u53ef\u4ee5\u9009\u62e9\u6700\u9ad8\u6b21\u7684\u9879\u5e76\u5ffd\u7565\u7cfb\u6570\uff0c\u56e0\u6b64\u5728\u6240\u6709\u60c5\u51b5\u4e0b\uff0c\u9009\u62e9\u6392\u5e8f\u7684\u590d\u6742\u5ea6\u90fd\u662fO(n^2)\u3002 \u5bf9\u4e8e\u5927\u578b\u6570\u636e\u96c6\u6765\u8bf4\uff0c\u4ea4\u6362\u5143\u7d20\u7684\u6210\u672c\u53ef\u80fd\u4f1a\u5f88\u9ad8\u3002\u56e0\u4e3a\u8fd9\u4e2a\u7b97\u6cd5\u53ea\u4f1a\u5728\u5916\u90e8\u5faa\u73af\u91cc\u5bf9\u6570\u636e\u5143\u7d20\u8fdb\u884c\u4ea4\u6362\uff0c\u6240\u4ee5\u5728\u6700\u574f\u60c5\u51b5\u548c\u5e73\u5747\u60c5\u51b5\u4e0b\uff0c\u9009\u62e9\u6392\u5e8f\u7684\u989d\u5916\u6210\u672c\u662f\u7ebf\u6027\u7684\u3002 \u7b97\u6cd5\u4ee3\u7801\uff1a def swap ( lyst , i , j ): \"\"\"\u4ea4\u6362\u5143\u7d20\u4f4d\u7f6e\u4e3ai\u548cj\u7684\u5143\u7d20\"\"\" temp = lyst [ i ] lyst [ i ] = lyst [ j ] lyst [ j ] = temp def selectionSort ( lyst ): \"\"\"\u5b9e\u73b0\u4ea4\u6362\u6392\u5e8f\u7b97\u6cd5\"\"\" i = 0 while i < len ( lyst ) - 1 : # \u5b9e\u73b0n-1\u6b21\u641c\u7d22 minIndex = i # \u6700\u5c0f\u5143\u7d20\u4f4d\u7f6e j = i + 1 while j < len ( lyst ): # \u5411\u540e\u904d\u5386\u641c\u7d22\uff0c\u66f4\u65b0\u6700\u5c0f\u5143\u7d20\u4f4d\u7f6e if lyst [ j ] < lyst [ minIndex ]: minIndex = j j += 1 if minIndex != i : # \u5982\u679c\u9700\u8981\uff0c\u5219\u4ea4\u6362\u5143\u7d20\u4f4d\u7f6e swap ( lyst , minIndex , i ) i += 1 def main (): myList = [ 9 , 4 , 2 , 7 , 6 , 8 , 1 ] print ( \"Before selection sort \" , myList ) selectionSort ( myList ) print ( \"After selection sort \" , myList ) if __name__ == \"__main__\" : main () # \u8fd0\u884c\u7ed3\u679c\uff1a # Before selection sort [9, 4, 2, 7, 6, 8, 1] # After selection sort [1, 2, 4, 6, 7, 8, 9] 3.4.2.\u5192\u6ce1\u6392\u5e8f \u00b6 \u5192\u6ce1\u6392\u5e8f\uff08Bubble Sort\uff09\uff1a \u6bd4\u8f83\u76f8\u90bb\u4e24\u4e2a\u6570\u636e\u5982\u679c\u3002\u7b2c\u4e00\u4e2a\u6bd4\u7b2c\u4e8c\u4e2a\u5927\uff0c\u5c31\u4ea4\u6362\u4e24\u4e2a\u6570\uff1b \u5bf9\u6bcf\u4e00\u4e2a\u76f8\u90bb\u7684\u6570\u505a\u540c\u68371\u7684\u5de5\u4f5c\uff0c\u8fd9\u6837\u4ece\u5f00\u59cb\u4e00\u961f\u5230\u7ed3\u5c3e\u4e00\u961f\u5728\u6700\u540e\u7684\u6570\u5c31\u662f\u6700\u5927\u7684\u6570\u3002 \u9488\u5bf9\u6240\u6709\u5143\u7d20\u4e0a\u9762\u7684\u64cd\u4f5c\uff0c\u9664\u4e86\u6700\u540e\u4e00\u4e2a\u3002 \u91cd\u590d1~3\u6b65\u9aa4\uff0c\u76f4\u81f3\u5b8c\u6210\u3002 \u7b97\u6cd5\u590d\u6742\u5ea6\uff1a \u5192\u6ce1\u6392\u5e8f\u53ea\u4f1a\u6539\u5584\u6700\u597d\u60c5\u51b5\u4e0b\u7684\u590d\u6742\u5ea6\u3002\u5bf9\u4e8e\u5e73\u5747\u60c5\u51b5\u800c\u8a00\uff0c\u7531\u4e8e\u4f9d\u7136\u662f\u53cc\u91cd\u5faa\u73af\u65f6\u95f4\uff0c\u6240\u4ee5\u590d\u6742\u5ea6\u662fO(n^2)\uff1b \u5bf9\u4e8e\u6709\u5e8f\u7684\u5217\u8868\u6765\u8bf4\uff0c\u4fee\u6539\u540e\u7684\u5192\u6ce1\u6392\u5e8f\u4f1a\u6bd4\u9009\u62e9\u6392\u5e8f\u7684\u6267\u884c\u6548\u7387\u66f4\u9ad8\u3002 \u7b97\u6cd5\u4ee3\u7801\uff1a def swap ( lyst , i , j ): \"\"\"\u4ea4\u6362\u5143\u7d20\u4f4d\u7f6e\u4e3ai\u548cj\u7684\u5143\u7d20\"\"\" temp = lyst [ i ] lyst [ i ] = lyst [ j ] lyst [ j ] = temp def selectionSort ( lyst ): \"\"\"\u5b9e\u73b0\u4ea4\u6362\u6392\u5e8f\u7b97\u6cd5\"\"\" i = 0 while i < len ( lyst ) - 1 : # \u5b9e\u73b0n-1\u6b21\u641c\u7d22 minIndex = i # \u6700\u5c0f\u5143\u7d20\u4f4d\u7f6e j = i + 1 while j < len ( lyst ): # \u5411\u540e\u904d\u5386\u641c\u7d22\uff0c\u66f4\u65b0\u6700\u5c0f\u5143\u7d20\u4f4d\u7f6e if lyst [ j ] < lyst [ minIndex ]: minIndex = j j += 1 if minIndex != i : # \u5982\u679c\u9700\u8981\uff0c\u5219\u4ea4\u6362\u5143\u7d20\u4f4d\u7f6e swap ( lyst , minIndex , i ) i += 1 def bubbleSortWithTweak ( lyst ): \"\"\"\u5b9e\u73b0\u5192\u6ce1\u6392\u5e8f\u7b97\u6cd5\"\"\" n = len ( lyst ) while n > 1 : swapped = False # \u7528\u5e03\u5c14\u6807\u5fd7\u6765\u8ffd\u8e2a\u6709\u6ca1\u6709\u53d1\u751f\u4ea4\u6362 i = 1 while i < n : if lyst [ i ] < lyst [ i - 1 ]: # \u5982\u679c\u540e\u9762\u5143\u7d20\u7684\u503c\u6bd4\u524d\u9762\u5143\u7d20\u7684\u5927\uff0c\u5219\u4ea4\u6362\u5143\u7d20\u4f4d\u7f6e\uff0c\u76f4\u81f3\u628a\u5faa\u73af\u4e2d\u7684\u6700\u5927\u5143\u7d20\u79fb\u5230\u6700\u540e swap ( lyst , i , i - 1 ) swapped = True i += 1 if not swapped : # \u5982\u679c\u4e0d\u9700\u8981\u4ea4\u6362\uff0c\u76f4\u63a5return return n -= 1 def main (): myList = [ 9 , 4 , 2 , 7 , 6 , 8 , 1 ] # \u6bd4\u8f83\u6392\u5e8f print ( \"Before selection sort \" , myList ) selectionSort ( myList ) print ( \"After selection sort \" , myList ) # \u5192\u6ce1\u6392\u5e8f myList = [ 9 , 4 , 2 , 7 , 6 , 8 , 1 ] print ( \"Before bubble sort \" , myList ) bubbleSortWithTweak ( myList ) print ( \"After bubble sort \" , myList ) if __name__ == \"__main__\" : main () # \u8fd0\u884c\u7ed3\u679c\uff1a # Before selection sort [9, 4, 2, 7, 6, 8, 1] # After selection sort [1, 2, 4, 6, 7, 8, 9] # Before bubble sort [9, 4, 2, 7, 6, 8, 1] # After bubble sort [1, 2, 4, 6, 7, 8, 9] 3.4.3.\u63d2\u5165\u6392\u5e8f \u00b6 \u63d2\u5165\u6392\u5e8f\uff08Insertion-Sort\uff09\u662f\u901a\u8fc7\u6784\u5efa\u6709\u5e8f\u5e8f\u5217\uff0c\u5bf9\u4e8e\u672a\u6392\u5e8f\u6570\u636e\uff0c\u5728\u5df2\u6392\u5e8f\u5e8f\u5217\u4e2d\u4ece\u540e\u5411\u524d\u626b\u63cf\uff0c\u627e\u5230\u76f8\u5e94\u4f4d\u7f6e\u5e76\u63d2\u5165\u3002\u63d2\u5165\u6392\u5e8f\u90fd\u91c7\u7528 in-place \u5728\u6570\u7ec4\u4e0a\u5b9e\u73b0\uff1a \u4ece\u7b2c\u4e00\u4e2a\u5143\u7d20\u5f00\u59cb\uff0c\u8be5\u5143\u7d20\u53ef\u4ee5\u8ba4\u4e3a\u5df2\u7ecf\u88ab\u6392\u5e8f\uff1b \u53d6\u51fa\u4e0b\u4e00\u4e2a\u5143\u7d20\uff0c\u5728\u5df2\u7ecf\u6392\u5e8f\u7684\u5143\u7d20\u5e8f\u5217\u4ece\u540e\u5411\u524d\u626b\u63cf\uff1b \u5982\u679c\u65b0\u5143\u7d20\u5c0f\u4e8e\u5df2\u6392\u5e8f\u7684\u5143\u7d20\uff0c\u5c06\u65b0\u5143\u7d20\u79fb\u5230\u4e0b\u4e00\u4f4d\u7f6e\uff1b \u91cd\u590d\u6b65\u9aa43\uff0c\u76f4\u5230\u627e\u5230\u5df2\u6392\u5e8f\u7684\u5143\u7d20\u5c0f\u4e8e\u6216\u8005\u7b49\u4e8e\u65b0\u5143\u7d20\u7684\u4f4d\u7f6e\uff1b \u5c06\u65b0\u5143\u7d20\u63d2\u5165\u5230\u8be5\u4f4d\u7f6e\u540e\uff1b \u91cd\u590d\u6b65\u9aa42~5\u3002 \u590d\u6742\u5ea6\uff1a \u548c\u9009\u62e9\u6392\u5e8f\u7c7b\u4f3c\uff0c\u904d\u5386\u6b21\u6570\u4e5f\u662f (1/2)*n^2+(1/2)*n \uff0c\u6240\u4ee5\u590d\u6742\u5ea6\u4e5f\u662fO(n^2)\u3002 \u5217\u8868\u91cc\u6709\u5e8f\u5143\u7d20\u8d8a\u591a\uff0c\u63d2\u5165\u6392\u5e8f\u7684\u6027\u80fd\u5c31\u4f1a\u8d8a\u597d\uff1b \u5728\u6709\u5e8f\u5217\u8868\u7684\u6700\u597d\u60c5\u51b5\u4e0b\uff0c\u6392\u5e8f\u590d\u6742\u5ea6\u662f\u7ebf\u6027\u7684\uff1b def swap ( lyst , i , j ): \"\"\"\u4ea4\u6362\u5143\u7d20\u4f4d\u7f6e\u4e3ai\u548cj\u7684\u5143\u7d20\"\"\" temp = lyst [ i ] lyst [ i ] = lyst [ j ] lyst [ j ] = temp def selectionSort ( lyst ): \"\"\"\u5b9e\u73b0\u4ea4\u6362\u6392\u5e8f\u7b97\u6cd5\"\"\" i = 0 while i < len ( lyst ) - 1 : # \u5b9e\u73b0n-1\u6b21\u641c\u7d22 minIndex = i # \u6700\u5c0f\u5143\u7d20\u4f4d\u7f6e j = i + 1 while j < len ( lyst ): # \u5411\u540e\u904d\u5386\u641c\u7d22\uff0c\u66f4\u65b0\u6700\u5c0f\u5143\u7d20\u4f4d\u7f6e if lyst [ j ] < lyst [ minIndex ]: minIndex = j j += 1 if minIndex != i : # \u5982\u679c\u9700\u8981\uff0c\u5219\u4ea4\u6362\u5143\u7d20\u4f4d\u7f6e swap ( lyst , minIndex , i ) i += 1 def bubbleSortWithTweak ( lyst ): \"\"\"\u5b9e\u73b0\u5192\u6ce1\u6392\u5e8f\u7b97\u6cd5\"\"\" n = len ( lyst ) while n > 1 : swapped = False # \u7528\u5e03\u5c14\u6807\u5fd7\u6765\u8ffd\u8e2a\u6709\u6ca1\u6709\u53d1\u751f\u4ea4\u6362 i = 1 while i < n : if lyst [ i ] < lyst [ i - 1 ]: # \u5982\u679c\u540e\u9762\u5143\u7d20\u7684\u503c\u6bd4\u524d\u9762\u5143\u7d20\u7684\u5927\uff0c\u5219\u4ea4\u6362\u5143\u7d20\u4f4d\u7f6e\uff0c\u76f4\u81f3\u628a\u5faa\u73af\u4e2d\u7684\u6700\u5927\u5143\u7d20\u79fb\u5230\u6700\u540e swap ( lyst , i , i - 1 ) swapped = True i += 1 if not swapped : # \u5982\u679c\u4e0d\u9700\u8981\u4ea4\u6362\uff0c\u76f4\u63a5return return n -= 1 def insertionSort ( lyst ): i = 1 # \u65b0\u5143\u7d20\u7684\u4f4d\u7f6e while i < len ( lyst ): itemToInsert = lyst [ i ] # \u65b0\u5143\u7d20 j = i - 1 # \u5df2\u6392\u5e8f\u7684\u5143\u7d20\u5e8f\u5217\u7684\u6700\u53f3\u4f4d\u7f6e while j >= 0 : if itemToInsert < lyst [ j ]: lyst [ j + 1 ] = lyst [ j ] # \u5982\u679c\u65b0\u5143\u7d20\u5c0f\u4e8e\u5df2\u6392\u5e8f\u5143\u7d20\uff0c\u5219\u5df2\u6392\u5e8f\u5143\u7d20\u5411\u540e\u79fb\u52a8\u4e00\u4e2a\u4f4d\u7f6e j -= 1 else : break # \u65b0\u5143\u7d20\u7b49\u4e8e\u6216\u8005\u5927\u4e8e\u5df2\u6392\u5e8f\u5143\u7d20\uff0c\u8df3\u51fa\u5faa\u73af\uff0c\u6b64\u65f6lyst[j + 1]\u662f\u548clyst[j]\u662f\u540c\u4e00\u4e2a\u5143\u7d20\u503c\uff0clyst[j + 1]\u4f4d\u7f6e\u662f\u7559\u7ed9\u65b0\u5143\u7d20\u7684 lyst [ j + 1 ] = itemToInsert # i += 1 def main (): myList = [ 9 , 4 , 2 , 7 , 6 , 8 , 1 ] # \u6bd4\u8f83\u6392\u5e8f print ( \"Before selection sort \" , myList ) selectionSort ( myList ) print ( \"After selection sort \" , myList ) # \u5192\u6ce1\u6392\u5e8f myList = [ 9 , 4 , 2 , 7 , 6 , 8 , 1 ] print ( \"Before bubble sort \" , myList ) bubbleSortWithTweak ( myList ) print ( \"After bubble sort \" , myList ) # \u63d2\u5165\u6392\u5e8f myList = [ 9 , 4 , 2 , 7 , 6 , 8 , 1 ] print ( \"Before insertion sort \" , myList ) insertionSort ( myList ) print ( \"After insertion sort \" , myList ) if __name__ == \"__main__\" : main () # \u8fd0\u884c\u7ed3\u679c\uff1a # Before selection sort [9, 4, 2, 7, 6, 8, 1] # After selection sort [1, 2, 4, 6, 7, 8, 9] # Before bubble sort [9, 4, 2, 7, 6, 8, 1] # After bubble sort [1, 2, 4, 6, 7, 8, 9] # Before insertion sort [9, 4, 2, 7, 6, 8, 1] # After insertion sort [1, 2, 4, 6, 7, 8, 9] 3.4.4.\u518d\u8bba\u6700\u597d\u60c5\u51b5\u3001\u6700\u574f\u60c5\u51b5\u4ee5\u53ca\u5e73\u5747\u60c5\u51b5\u4e0b\u7684\u6027\u80fd \u00b6 \u5bf9\u4e8e\u8bb8\u591a\u7b97\u6cd5\u6765\u8bf4\uff0c\u4e0d\u80fd\u5bf9\u6240\u6709\u60c5\u51b5\u91c7\u7528\u5355\u4e00\u7684\u590d\u6742\u5ea6\u6765\u8861\u91cf\u3002\u5f53\u9047\u5230\u7279\u5b9a\u987a\u5e8f\u7684\u6570\u636e\u65f6\uff0c\u7b97\u6cd5\u7684\u884c\u4e3a\u53ef\u80fd\u4f1a\u53d8\u5f97\u66f4\u597d\u6216\u66f4\u7cdf\u3002 \u5bf9\u7b97\u6cd5\u590d\u6742\u5ea6\u884c\u4e3a\u5206\u4e3a3\u79cd\u60c5\u51b5\uff1a \u6700\u597d\u60c5\u51b5\uff08best case\uff09\u2014\u2014\u7b97\u6cd5\u5728\u4ec0\u4e48\u60c5\u51b5\u4e0b\u53ef\u4ee5\u4ee5\u6700\u5c11\u7684\u5de5\u4f5c\u91cf\u5b8c\u6210\u5de5\u4f5c\uff1f\u5728\u6700\u597d\u60c5\u51b5\u4e0b\uff0c\u7b97\u6cd5\u7684\u590d\u6742\u5ea6\u662f\u591a\u5c11\uff1f \u6700\u574f\u60c5\u51b5\uff08worst case\uff09\u2014\u2014\u7b97\u6cd5\u5728\u4ec0\u4e48\u60c5\u51b5\u4e0b\u9700\u8981\u5b8c\u6210\u6700\u591a\u7684\u5de5\u4f5c\u91cf\uff1f\u5728\u6700\u574f\u60c5\u51b5\u4e0b\uff0c\u7b97\u6cd5\u7684\u590d\u6742\u5ea6\u662f\u591a\u5c11\uff1f \u5e73\u5747\u60c5\u51b5\uff08average case\uff09\u2014\u2014\u7b97\u6cd5\u5728\u4ec0\u4e48\u60c5\u51b5\u4e0b\u7528\u9002\u91cf\u7684\u5de5\u4f5c\u91cf\u5c31\u80fd\u5b8c\u6210\u5de5\u4f5c\uff1f\u5728\u5e73\u5747\u60c5\u51b5\u4e0b\uff0c\u7b97\u6cd5\u7684\u590d\u6742\u5ea6\u662f\u591a\u5c11\uff1f \u4e0b\u9762\u5206\u522b\u5bf9\u6700\u5c0f\u503c\u641c\u7d22\u3001\u987a\u5e8f\u641c\u7d22\u548c\u5192\u6ce1\u6392\u5e8f\u8fdb\u884c\u6700\u597d\u60c5\u51b5\u3001\u6700\u574f\u60c5\u51b5\u548c\u5e73\u5747\u60c5\u51b5\u4e0b\u7684\u6027\u80fd\u5206\u6790\uff0c\u4e0d\u8003\u8651\u5b9e\u9645\u786c\u4ef6\u548c\u7f16\u7a0b\u8bed\u8a00\u7b49\u7684\u5f71\u54cd\u3002 \u6700\u5c0f\u503c\u641c\u7d22\uff08Minimum Value Search\uff09 \u6700\u597d\u60c5\u51b5\uff1a\u6700\u5c0f\u503c\u521a\u597d\u5728\u7b2c\u4e00\u4e2a\u4f4d\u7f6e\u3002\u8fd9\u65f6\uff0c\u53ea\u9700\u8981\u4e00\u6b21\u6bd4\u8f83\u5c31\u53ef\u4ee5\u627e\u5230\u6700\u5c0f\u503c\uff0c\u65f6\u95f4\u590d\u6742\u5ea6\u4e3aO(1)\u3002 \u6700\u574f\u60c5\u51b5\uff1a\u6700\u5c0f\u503c\u5728\u6700\u540e\u4e00\u4e2a\u4f4d\u7f6e\u6216\u4e0d\u5b58\u5728\u3002\u8fd9\u65f6\uff0c\u9700\u8981\u8fdb\u884cn-1\u6b21\u6bd4\u8f83\u624d\u80fd\u786e\u5b9a\u6700\u5c0f\u503c\uff0c\u65f6\u95f4\u590d\u6742\u5ea6\u4e3aO(n)\u3002 \u5e73\u5747\u60c5\u51b5\uff1a\u5e73\u5747\u60c5\u51b5\u4e0b\uff0c\u6bcf\u4e2a\u5143\u7d20\u6709\u76f8\u7b49\u7684\u6982\u7387\u6210\u4e3a\u6700\u5c0f\u503c\u3002\u56e0\u6b64\uff0c\u5e73\u5747\u6bd4\u8f83\u6b21\u6570\u4e3a(n-1)/2\uff0c\u65f6\u95f4\u590d\u6742\u5ea6\u4e3aO(n)\u3002 \u987a\u5e8f\u641c\u7d22\uff08Sequential Search\uff09 \u6700\u597d\u60c5\u51b5\uff1a\u641c\u7d22\u7684\u5143\u7d20\u521a\u597d\u662f\u5217\u8868\u7684\u7b2c\u4e00\u4e2a\u5143\u7d20\u3002\u8fd9\u65f6\uff0c\u53ea\u9700\u8981\u4e00\u6b21\u6bd4\u8f83\u5c31\u53ef\u4ee5\u627e\u5230\u76ee\u6807\u5143\u7d20\uff0c\u65f6\u95f4\u590d\u6742\u5ea6\u4e3aO(1)\u3002 \u6700\u574f\u60c5\u51b5\uff1a\u641c\u7d22\u7684\u5143\u7d20\u5728\u5217\u8868\u7684\u6700\u540e\u4e00\u4e2a\u4f4d\u7f6e\u6216\u4e0d\u5b58\u5728\u3002\u8fd9\u65f6\uff0c\u9700\u8981\u8fdb\u884cn\u6b21\u6bd4\u8f83\u624d\u80fd\u786e\u5b9a\u76ee\u6807\u5143\u7d20\u4e0d\u5b58\u5728\uff0c\u65f6\u95f4\u590d\u6742\u5ea6\u4e3aO(n)\u3002 \u5e73\u5747\u60c5\u51b5\uff1a\u5e73\u5747\u60c5\u51b5\u4e0b\uff0c\u6bcf\u4e2a\u5143\u7d20\u6709\u76f8\u7b49\u7684\u6982\u7387\u6210\u4e3a\u76ee\u6807\u5143\u7d20\u3002\u56e0\u6b64\uff0c\u5e73\u5747\u6bd4\u8f83\u6b21\u6570\u4e3a (n+1)/2 \uff0c\u65f6\u95f4\u590d\u6742\u5ea6\u4e3aO(n)\u3002 \u5192\u6ce1\u6392\u5e8f\uff08Bubble Sort\uff09 \u6700\u597d\u60c5\u51b5\uff1a\u5982\u679c\u8f93\u5165\u5217\u8868\u5df2\u7ecf\u662f\u6709\u5e8f\u7684\uff0c\u5192\u6ce1\u6392\u5e8f\u53ea\u9700\u8981\u8fdb\u884c\u4e00\u6b21\u904d\u5386\u6765\u68c0\u6d4b\u5217\u8868\u5df2\u7ecf\u6709\u5e8f\uff0c\u65f6\u95f4\u590d\u6742\u5ea6\u4e3aO(n)\u3002\u4f46\u5b9e\u9645\u4e0a\uff0c\u901a\u5e38\u9700\u8981\u8fdb\u884c\u591a\u6b21\u904d\u5386\u6765\u5b8c\u6210\u6392\u5e8f\uff0c\u56e0\u6b64\u6700\u597d\u60c5\u51b5\u4e0b\u7684\u65f6\u95f4\u590d\u6742\u5ea6\u4ecd\u7136\u662fO(n^2)\u3002 \u6700\u574f\u60c5\u51b5\uff1a\u5982\u679c\u8f93\u5165\u5217\u8868\u662f\u9006\u5e8f\u7684\uff0c\u6bcf\u6b21\u904d\u5386\u90fd\u9700\u8981\u8fdb\u884cn-1\u6b21\u4ea4\u6362\uff0c\u603b\u5171\u9700\u8981\u8fdb\u884cn-1\u8f6e\u904d\u5386\uff0c\u65f6\u95f4\u590d\u6742\u5ea6\u4e3aO(n^2)\u3002 \u5e73\u5747\u60c5\u51b5\uff1a\u5e73\u5747\u60c5\u51b5\u4e0b\uff0c\u5192\u6ce1\u6392\u5e8f\u9700\u8981\u8fdb\u884c n(n-1)/2 \u6b21\u6bd4\u8f83\u548c\u4ea4\u6362\u64cd\u4f5c\uff0c\u65f6\u95f4\u590d\u6742\u5ea6\u4e3aO(n^2)\u3002 3.4.5.\u7ec3\u4e60\u9898 \u00b6 \u5217\u8868\u91cc\u5982\u4f55\u6392\u5217\u6570\u636e\u624d\u80fd\u8ba9\u9009\u62e9\u6392\u5e8f\u4e2d\u5143\u7d20\u4ea4\u6362\u7684\u6b21\u6570\u6700\u5c11\uff1f\u5982\u4f55\u6392\u5217\u6570\u636e\u624d\u80fd\u8ba9\u5b83\u6267\u884c\u6700\u591a\u7684\u4ea4\u6362\u6b21\u6570\uff1f \u89e3\u7b54\uff1a \u5728\u9009\u62e9\u6392\u5e8f\u4e2d\uff0c\u5143\u7d20\u7684\u4ea4\u6362\u6b21\u6570\u4e3b\u8981\u53d6\u51b3\u4e8e\u5f85\u6392\u5e8f\u5217\u8868\u7684\u521d\u59cb\u6392\u5217\uff1a \u6700\u5c0f\u5316\u4ea4\u6362\u6b21\u6570\uff1a \u8981\u6700\u5c0f\u5316\u9009\u62e9\u6392\u5e8f\u7684\u5143\u7d20\u4ea4\u6362\u6b21\u6570\uff0c\u53ef\u4ee5\u8ba9\u8f93\u5165\u5217\u8868\u5df2\u7ecf\u6309\u5347\u5e8f\u6392\u5217\u3002\u8fd9\u662f\u56e0\u4e3a\u5728\u5347\u5e8f\u6392\u5217\u7684\u60c5\u51b5\u4e0b\uff0c\u9009\u62e9\u6392\u5e8f\u6bcf\u6b21\u9009\u62e9\u6700\u5c0f\u7684\u5143\u7d20\u5e76\u5c06\u5176\u653e\u7f6e\u5728\u6b63\u786e\u7684\u4f4d\u7f6e\uff0c\u65e0\u9700\u4ea4\u6362\u3002\u56e0\u6b64\uff0c\u5143\u7d20\u4ea4\u6362\u7684\u6b21\u6570\u4e3a 0 \u3002 \u6700\u5927\u5316\u4ea4\u6362\u6b21\u6570\uff1a \u8981\u6700\u5927\u5316\u9009\u62e9\u6392\u5e8f\u7684\u5143\u7d20\u4ea4\u6362\u6b21\u6570\uff0c\u53ef\u4ee5\u8ba9\u8f93\u5165\u5217\u8868\u6309\u964d\u5e8f\u6392\u5217\u3002\u5728\u964d\u5e8f\u6392\u5217\u7684\u60c5\u51b5\u4e0b\uff0c\u9009\u62e9\u6392\u5e8f\u6bcf\u6b21\u9009\u62e9\u6700\u5927\u7684\u5143\u7d20\u5e76\u5c06\u5176\u653e\u7f6e\u5728\u6b63\u786e\u7684\u4f4d\u7f6e\uff0c\u8fd9\u5c06\u5bfc\u81f4\u5927\u91cf\u7684\u4ea4\u6362\u64cd\u4f5c\u3002\u5177\u4f53\u6765\u8bf4\uff0c\u5bf9\u4e8e\u957f\u5ea6\u4e3an\u7684\u5217\u8868\uff0c\u6700\u5927\u5316\u4ea4\u6362\u6b21\u6570\u7684\u60c5\u51b5\u4e0b\uff0c\u5c06\u6267\u884c n-1 \u6b21\u4ea4\u6362\u64cd\u4f5c\u3002 \u603b\u4e4b\uff0c\u8981\u6700\u5c0f\u5316\u9009\u62e9\u6392\u5e8f\u7684\u5143\u7d20\u4ea4\u6362\u6b21\u6570\uff0c\u8f93\u5165\u5217\u8868\u5e94\u8be5\u5df2\u7ecf\u6309\u5347\u5e8f\u6392\u5217\u3002\u8981\u6700\u5927\u5316\u4ea4\u6362\u6b21\u6570\uff0c\u8f93\u5165\u5217\u8868\u5e94\u8be5\u6309\u964d\u5e8f\u6392\u5217\u3002\u5728\u5b9e\u9645\u5e94\u7528\u4e2d\uff0c\u9009\u62e9\u6392\u5e8f\u901a\u5e38\u4e0d\u662f\u9996\u9009\u7684\u6392\u5e8f\u7b97\u6cd5\uff0c\u56e0\u4e3a\u5176\u4ea4\u6362\u6b21\u6570\u8f83\u591a\uff0c\u800c\u5176\u4ed6\u7b97\u6cd5\u5982\u5feb\u901f\u6392\u5e8f\u3001\u5f52\u5e76\u6392\u5e8f\u7b49\u5177\u6709\u66f4\u597d\u7684\u6027\u80fd\u3002 \u8bf7\u8bf4\u660e\u6570\u636e\u4ea4\u6362\u7684\u6b21\u6570\u5728\u5206\u6790\u9009\u62e9\u6392\u5e8f\u548c\u5192\u6ce1\u6392\u5e8f\u65f6\u6240\u8d77\u5230\u7684\u4f5c\u7528\u3002\u6570\u636e\u5bf9\u8c61\u7684\u89c4\u6a21\u5728\u5b83\u4eec\u4e4b\u95f4\u53d1\u6325\u7740\u4ec0\u4e48\u4f5c\u7528\uff08\u5982\u679c\u6709\u4f5c\u7528\uff09\uff1f \u89e3\u7b54\uff1a \u6570\u636e\u4ea4\u6362\u7684\u6b21\u6570\u5728\u5206\u6790\u9009\u62e9\u6392\u5e8f\u548c\u5192\u6ce1\u6392\u5e8f\u65f6\u8d77\u5230\u91cd\u8981\u4f5c\u7528\uff0c\u56e0\u4e3a\u5b83\u4eec\u76f4\u63a5\u5f71\u54cd\u5230\u6392\u5e8f\u7b97\u6cd5\u7684\u6027\u80fd\u548c\u6548\u7387\u3002 \u9009\u62e9\u6392\u5e8f\uff08Selection Sort\uff09\uff1a \u9009\u62e9\u6392\u5e8f\u7684\u6570\u636e\u4ea4\u6362\u6b21\u6570\u4e0e\u6570\u636e\u5bf9\u8c61\u7684\u89c4\u6a21\u76f4\u63a5\u76f8\u5173\u3002\u5728\u9009\u62e9\u6392\u5e8f\u4e2d\uff0c\u6bcf\u4e00\u8f6e\u90fd\u4f1a\u9009\u62e9\u672a\u6392\u5e8f\u90e8\u5206\u7684\u6700\u5c0f\u5143\u7d20\uff0c\u5e76\u5c06\u5176\u653e\u7f6e\u5728\u6b63\u786e\u7684\u4f4d\u7f6e\uff0c\u8fd9\u610f\u5473\u7740\u6bcf\u8f6e\u90fd\u9700\u8981\u4e00\u6b21\u4ea4\u6362\u64cd\u4f5c\u3002 \u9009\u62e9\u6392\u5e8f\u7684\u6570\u636e\u4ea4\u6362\u6b21\u6570\u662f\u4e0e\u8f93\u5165\u6570\u636e\u7684\u521d\u59cb\u6392\u5217\u65e0\u5173\u7684\uff0c\u56e0\u4e3a\u5b83\u603b\u662f\u4f1a\u6267\u884c\u76f8\u540c\u6570\u91cf\u7684\u4ea4\u6362\u64cd\u4f5c\uff0c\u65e0\u8bba\u6570\u636e\u662f\u5426\u6709\u5e8f\u3002 \u5bf9\u4e8e\u9009\u62e9\u6392\u5e8f\uff0c\u6570\u636e\u4ea4\u6362\u6b21\u6570\u4e3b\u8981\u53d7\u5230\u6570\u636e\u5bf9\u8c61\u7684\u89c4\u6a21\u5f71\u54cd\uff0c\u800c\u4e0d\u53d7\u6570\u636e\u7684\u5177\u4f53\u6392\u5217\u65b9\u5f0f\u7684\u5f71\u54cd\u3002\u65e0\u8bba\u6570\u636e\u7684\u6392\u5217\u5982\u4f55\uff0c\u9009\u62e9\u6392\u5e8f\u7684\u5e73\u5747\u548c\u6700\u574f\u60c5\u51b5\u4e0b\u7684\u6570\u636e\u4ea4\u6362\u6b21\u6570\u90fd\u662f\u76f8\u540c\u7684\uff0c\u5373 n-1 \u6b21\u3002 \u5192\u6ce1\u6392\u5e8f\uff08Bubble Sort\uff09\uff1a \u5192\u6ce1\u6392\u5e8f\u7684\u6570\u636e\u4ea4\u6362\u6b21\u6570\u4e5f\u4e0e\u6570\u636e\u5bf9\u8c61\u7684\u89c4\u6a21\u76f8\u5173\u3002\u5728\u5192\u6ce1\u6392\u5e8f\u4e2d\uff0c\u76f8\u90bb\u5143\u7d20\u9010\u4e00\u6bd4\u8f83\uff0c\u5982\u679c\u9006\u5e8f\u5c31\u4ea4\u6362\u4f4d\u7f6e\uff0c\u56e0\u6b64\u5192\u6ce1\u6392\u5e8f\u7684\u6570\u636e\u4ea4\u6362\u6b21\u6570\u4e0e\u9006\u5e8f\u5bf9\u7684\u6570\u91cf\u76f8\u5173\u3002 \u5192\u6ce1\u6392\u5e8f\u7684\u6570\u636e\u4ea4\u6362\u6b21\u6570\u5728\u4e0d\u540c\u7684\u6570\u636e\u6392\u5217\u60c5\u51b5\u4e0b\u53ef\u4ee5\u6709\u5f88\u5927\u5dee\u5f02\u3002\u5728\u6700\u597d\u60c5\u51b5\u4e0b\uff08\u8f93\u5165\u6570\u636e\u5df2\u7ecf\u6709\u5e8f\uff09\uff0c\u5192\u6ce1\u6392\u5e8f\u7684\u6570\u636e\u4ea4\u6362\u6b21\u6570\u4e3a 0 \u3002\u5728\u6700\u574f\u60c5\u51b5\u4e0b\uff08\u8f93\u5165\u6570\u636e\u5b8c\u5168\u9006\u5e8f\uff09\uff0c\u5192\u6ce1\u6392\u5e8f\u7684\u6570\u636e\u4ea4\u6362\u6b21\u6570\u662f\u6700\u5927\u7684\u3002 \u5192\u6ce1\u6392\u5e8f\u7684\u6570\u636e\u4ea4\u6362\u6b21\u6570\u65e2\u53d7\u5230\u6570\u636e\u5bf9\u8c61\u7684\u89c4\u6a21\u5f71\u54cd\uff0c\u53c8\u53d7\u5230\u6570\u636e\u7684\u6392\u5217\u65b9\u5f0f\u7684\u5f71\u54cd\u3002\u6700\u597d\u60c5\u51b5\u4e0b\u7684\u4ea4\u6362\u6b21\u6570\u4e3a 0 \uff0c\u6700\u574f\u60c5\u51b5\u4e0b\u7684\u4ea4\u6362\u6b21\u6570\u4e3a n*(n-1)/2 \uff0c\u5e73\u5747\u60c5\u51b5\u4e0b\u7684\u4ea4\u6362\u6b21\u6570\u53d6\u51b3\u4e8e\u6570\u636e\u6392\u5217\u7684\u968f\u673a\u6027\u3002 \u7efc\u4e0a\u6240\u8ff0\uff0c\u6570\u636e\u4ea4\u6362\u7684\u6b21\u6570\u5728\u9009\u62e9\u6392\u5e8f\u548c\u5192\u6ce1\u6392\u5e8f\u7684\u5206\u6790\u4e2d\u662f\u91cd\u8981\u7684\u6027\u80fd\u6307\u6807\u3002\u9009\u62e9\u6392\u5e8f\u7684\u4ea4\u6362\u6b21\u6570\u4e0e\u6570\u636e\u89c4\u6a21\u76f8\u5173\uff0c\u800c\u5192\u6ce1\u6392\u5e8f\u7684\u4ea4\u6362\u6b21\u6570\u65e2\u4e0e\u6570\u636e\u89c4\u6a21\u76f8\u5173\uff0c\u53c8\u53d7\u5230\u6570\u636e\u6392\u5217\u65b9\u5f0f\u7684\u5f71\u54cd\u3002\u5728\u5927\u89c4\u6a21\u6570\u636e\u96c6\u4e0a\uff0c\u5192\u6ce1\u6392\u5e8f\u901a\u5e38\u6bd4\u9009\u62e9\u6392\u5e8f\u66f4\u6162\uff0c\u56e0\u4e3a\u5b83\u7684\u4ea4\u6362\u64cd\u4f5c\u66f4\u591a\u3002\u56e0\u6b64\uff0c\u5728\u5b9e\u9645\u5e94\u7528\u4e2d\uff0c\u901a\u5e38\u9009\u62e9\u6392\u5e8f\u6bd4\u5192\u6ce1\u6392\u5e8f\u66f4\u6709\u6548\u3002\u4f46\u4e24\u8005\u90fd\u4e0d\u662f\u9996\u9009\u7684\u6392\u5e8f\u7b97\u6cd5\uff0c\u66f4\u9ad8\u6548\u7684\u6392\u5e8f\u7b97\u6cd5\u5982\u5feb\u901f\u6392\u5e8f\u3001\u5f52\u5e76\u6392\u5e8f\u7b49\u901a\u5e38\u88ab\u4f18\u5148\u8003\u8651\u3002 \u8bf7\u8bf4\u660e\u4e3a\u4ec0\u4e48\u4fee\u6539\u540e\u7684\u5192\u6ce1\u6392\u5e8f\u5728\u5e73\u5747\u60c5\u51b5\u4e0b\u6027\u80fd\u4ecd\u7136\u4e3aO(n^2)\u3002 \u89e3\u7b54\uff1a \u4fee\u6539\u540e\u7684\u5192\u6ce1\u6392\u5e8f\u5728\u5e73\u5747\u60c5\u51b5\u4e0b\u6027\u80fd\u4ecd\u7136\u4e3aO(n^2)\uff0c\u539f\u56e0\u5982\u4e0b\uff1a \u5192\u6ce1\u6392\u5e8f\u7684\u57fa\u672c\u64cd\u4f5c\u662f\u6bd4\u8f83\u76f8\u90bb\u5143\u7d20\u5e76\u4ea4\u6362\u5b83\u4eec\uff0c\u76f4\u5230\u6574\u4e2a\u5217\u8868\u6309\u7167\u5347\u5e8f\u6392\u5217\u3002\u5728\u4fee\u6539\u540e\u7684\u5192\u6ce1\u6392\u5e8f\u4e2d\uff0c\u5f53\u4e24\u4e2a\u76f8\u90bb\u5143\u7d20\u9006\u5e8f\u65f6\uff0c\u4f1a\u53d1\u751f\u4ea4\u6362\u3002\u8fd9\u4e2a\u57fa\u672c\u64cd\u4f5c\u7684\u590d\u6742\u5ea6\u662fO(1)\uff0c\u56e0\u4e3a\u5b83\u53ea\u6d89\u53ca\u4e24\u4e2a\u5143\u7d20\u7684\u6bd4\u8f83\u548c\u53ef\u80fd\u7684\u4ea4\u6362\u3002 \u4fee\u6539\u540e\u7684\u5192\u6ce1\u6392\u5e8f\u5728\u6bcf\u4e00\u8f6e\u904d\u5386\u4e2d\uff0c\u4ecd\u7136\u9700\u8981\u68c0\u67e5\u76f8\u90bb\u5143\u7d20\u7684\u6bd4\u8f83\uff0c\u5373\u4f7f\u5728\u6709\u5e8f\u90e8\u5206\uff0c\u5b83\u4ecd\u7136\u9700\u8981\u8fdb\u884c\u6bd4\u8f83\u3002\u5728\u6700\u574f\u60c5\u51b5\u4e0b\uff0c\u5b83\u4f1a\u6267\u884cn-1\u6b21\u904d\u5386\uff0c\u6bcf\u6b21\u90fd\u8981\u6bd4\u8f83\u76f8\u90bb\u5143\u7d20\u3002 \u5192\u6ce1\u6392\u5e8f\u7684\u5e73\u5747\u65f6\u95f4\u590d\u6742\u5ea6\u662fO(n^2)\uff0c\u8fd9\u662f\u56e0\u4e3a\u5b83\u4e0d\u4f1a\u5229\u7528\u8f93\u5165\u6570\u636e\u7684\u4efb\u4f55\u6709\u5e8f\u6027\u3002\u65e0\u8bba\u8f93\u5165\u6570\u636e\u662f\u6709\u5e8f\u7684\u3001\u9006\u5e8f\u7684\uff0c\u8fd8\u662f\u968f\u673a\u6392\u5217\u7684\uff0c\u90fd\u9700\u8981\u6267\u884c\u76f8\u540c\u6570\u91cf\u7684\u6bd4\u8f83\u548c\u4ea4\u6362\u64cd\u4f5c\u3002 \u603b\u4e4b\uff0c\u4fee\u6539\u540e\u7684\u5192\u6ce1\u6392\u5e8f\u867d\u7136\u51cf\u5c11\u4e86\u6570\u636e\u4ea4\u6362\u7684\u6b21\u6570\uff0c\u4f46\u5728\u5e73\u5747\u60c5\u51b5\u4e0b\u4ecd\u7136\u9700\u8981\u6267\u884c\u5927\u7ea6 n(n-1)/2 \u6b21\u6bd4\u8f83\u64cd\u4f5c\uff0c\u56e0\u6b64\u5b83\u7684\u5e73\u5747\u65f6\u95f4\u590d\u6742\u5ea6\u4ecd\u7136\u662fO(n^2)\u3002\u5192\u6ce1\u6392\u5e8f\u7684\u6027\u80fd\u4e3b\u8981\u53d7\u5230\u6570\u636e\u89c4\u6a21\u7684\u5f71\u54cd\uff0c\u800c\u4e0d\u592a\u53d7\u5230\u5177\u4f53\u6570\u636e\u6392\u5217\u65b9\u5f0f\u7684\u5f71\u54cd\u3002\u56e0\u6b64\uff0c\u5b83\u5728\u5e73\u5747\u60c5\u51b5\u4e0b\u4ecd\u7136\u5177\u6709\u4e8c\u6b21\u65f6\u95f4\u590d\u6742\u5ea6\u3002 \u8bf7\u8bf4\u660e\u4e3a\u4ec0\u4e48\u63d2\u5165\u6392\u5e8f\u5728\u90e8\u5206\u6709\u5e8f\u7684\u5217\u8868\u4e0a\u80fd\u591f\u5f88\u597d\u5730\u5de5\u4f5c\u3002 \u89e3\u7b54\uff1a \u63d2\u5165\u6392\u5e8f\u4e4b\u6240\u4ee5\u80fd\u591f\u5728\u90e8\u5206\u6709\u5e8f\u7684\u5217\u8868\u4e0a\u5f88\u597d\u5730\u5de5\u4f5c\uff0c\u662f\u56e0\u4e3a\u5b83\u7684\u6838\u5fc3\u601d\u60f3\u662f\u9010\u6b65\u6784\u5efa\u6709\u5e8f\u7684\u5b50\u5217\u8868\uff0c\u800c\u4e0d\u662f\u50cf\u9009\u62e9\u6392\u5e8f\u6216\u5192\u6ce1\u6392\u5e8f\u4e00\u6837\u603b\u662f\u8003\u8651\u6574\u4e2a\u5217\u8868\u3002\u8fd9\u4f7f\u5f97\u63d2\u5165\u6392\u5e8f\u5728\u5904\u7406\u90e8\u5206\u6709\u5e8f\u7684\u5217\u8868\u65f6\u5177\u6709\u4e00\u4e9b\u4f18\u52bf\uff1a \u5c40\u90e8\u6027\u539f\u7406\uff1a\u63d2\u5165\u6392\u5e8f\u5229\u7528\u4e86\u5c40\u90e8\u6027\u539f\u7406\uff0c\u5373\u5728\u5927\u591a\u6570\u60c5\u51b5\u4e0b\uff0c\u6570\u636e\u9879\u7684\u6b63\u786e\u4f4d\u7f6e\u79bb\u5b83\u4eec\u5f53\u524d\u7684\u4f4d\u7f6e\u5f88\u8fd1\u3002\u5728\u90e8\u5206\u6709\u5e8f\u7684\u5217\u8868\u4e2d\uff0c\u5927\u591a\u6570\u6570\u636e\u9879\u5df2\u7ecf\u63a5\u8fd1\u4e8e\u5b83\u4eec\u7684\u6700\u7ec8\u4f4d\u7f6e\uff0c\u56e0\u6b64\u53ea\u9700\u8981\u8fdb\u884c\u5c11\u91cf\u7684\u79fb\u52a8\u64cd\u4f5c\u3002 \u9002\u5e94\u6027\uff1a\u63d2\u5165\u6392\u5e8f\u662f\u4e00\u79cd\u81ea\u9002\u5e94\u6392\u5e8f\u7b97\u6cd5\uff0c\u5b83\u53ef\u4ee5\u6839\u636e\u8f93\u5165\u6570\u636e\u7684\u6709\u5e8f\u6027\u8fdb\u884c\u81ea\u52a8\u8c03\u6574\u3002\u5728\u5904\u7406\u90e8\u5206\u6709\u5e8f\u7684\u5217\u8868\u65f6\uff0c\u63d2\u5165\u6392\u5e8f\u7684\u6027\u80fd\u4f1a\u66f4\u597d\uff0c\u56e0\u4e3a\u4e0d\u9700\u8981\u6267\u884c\u592a\u591a\u7684\u6bd4\u8f83\u548c\u4ea4\u6362\u64cd\u4f5c\u3002 \u7b80\u5355\u6027\uff1a\u63d2\u5165\u6392\u5e8f\u7684\u5b9e\u73b0\u975e\u5e38\u7b80\u5355\u76f4\u89c2\uff0c\u5b83\u53ea\u6d89\u53ca\u5230\u9010\u4e2a\u63d2\u5165\u5143\u7d20\u5230\u6b63\u786e\u7684\u4f4d\u7f6e\u3002\u8fd9\u79cd\u7b80\u5355\u6027\u4f7f\u5f97\u63d2\u5165\u6392\u5e8f\u5728\u67d0\u4e9b\u60c5\u51b5\u4e0b\u6bd4\u66f4\u590d\u6742\u7684\u6392\u5e8f\u7b97\u6cd5\u66f4\u5177\u7ade\u4e89\u529b\u3002 \u867d\u7136\u63d2\u5165\u6392\u5e8f\u5728\u90e8\u5206\u6709\u5e8f\u7684\u5217\u8868\u4e0a\u8868\u73b0\u826f\u597d\uff0c\u4f46\u5728\u5904\u7406\u5927\u89c4\u6a21\u4e71\u5e8f\u6570\u636e\u96c6\u65f6\uff0c\u5b83\u7684\u6027\u80fd\u4e0d\u5982\u5feb\u901f\u6392\u5e8f\u3001\u5f52\u5e76\u6392\u5e8f\u7b49\u66f4\u9ad8\u7ea7\u7684\u6392\u5e8f\u7b97\u6cd5\u3002\u56e0\u6b64\uff0c\u5728\u5b9e\u9645\u5e94\u7528\u4e2d\uff0c\u6839\u636e\u6570\u636e\u7684\u6027\u8d28\u9009\u62e9\u9002\u5f53\u7684\u6392\u5e8f\u7b97\u6cd5\u662f\u91cd\u8981\u7684\u3002\u63d2\u5165\u6392\u5e8f\u901a\u5e38\u9002\u7528\u4e8e\u5c0f\u89c4\u6a21\u6570\u636e\u6216\u8005\u5df2\u7ecf\u90e8\u5206\u6709\u5e8f\u7684\u6570\u636e\uff0c\u800c\u4e0d\u662f\u5927\u89c4\u6a21\u4e71\u5e8f\u6570\u636e\u7684\u6392\u5e8f\u3002 3.5.\u66f4\u5feb\u7684\u6392\u5e8f \u00b6 \u5206\u6cbb\u6cd5\uff08divide-and-conquer\uff09\u7b56\u7565\uff1a\u628a\u5217\u8868\u5206\u6210\u66f4\u5c0f\u7684\u5b50\u5217\u8868\uff0c\u7136\u540e\u518d\u901a\u8fc7\u9012\u5f52\u628a\u8fd9\u4e9b\u5b50\u5217\u8868\u6392\u5e8f\u3002 \u7406\u60f3\u60c5\u51b5\u4e0b\uff0c\u5982\u679c\u8fd9\u4e9b\u88ab\u62c6\u5206\u7684\u5b50\u5217\u8868\u7684\u6570\u91cf\u662f logn \uff0c\u800c\u628a\u6bcf\u4e2a\u5b50\u5217\u8868\u8fdb\u884c\u5408\u5e76\u6240\u9700\u7684\u5de5\u4f5c\u91cf\u4e3a n \uff0c\u90a3\u4e48\u8fd9\u79cd\u6392\u5e8f\u7b97\u6cd5\u7684\u603b\u590d\u6742\u5ea6\u5c31\u662f O(nlogn) \uff0c\u76f8\u6bd4 O(n^2) \u7684\u5de5\u4f5c\u91cf\u589e\u957f\u8981\u4f4e\u5f88\u591a\u3002 3.5.1.\u5feb\u901f\u6392\u5e8f \u00b6 \u5feb\u901f\u6392\u5e8f\uff08QuickSort\uff09\u662f\u6392\u9664\u7a33\u5b9a\u6027\u56e0\u7d20\u540e\u6700\u5e38\u7528\u7684\u6392\u5e8f\u3002 \u9996\u5148\u4ece\u5217\u8868\u7684\u4e2d\u95f4\u4f4d\u7f6e\u9009\u62e9\u4e00\u4e2a\u5143\u7d20\uff0c\u8fd9\u4e2a\u5143\u7d20\u88ab\u79f0\u4e3a\u57fa\u51c6\uff08pivot\uff09\uff1b \u5bf9\u5217\u8868\u91cc\u7684\u5143\u7d20\u8fdb\u884c\u5206\u5272\uff0c\u628a\u5c0f\u4e8e\u57fa\u51c6\u7684\u6240\u6709\u5143\u7d20\u79fb\u52a8\u5230\u57fa\u51c6\u7684\u5de6\u4fa7\uff0c\u800c\u628a\u5176\u4f59\u5143\u7d20\u90fd\u79fb\u5230\u57fa\u51c6\u7684\u53f3\u4fa7\u3002 \u5982\u679c\u57fa\u51c6\u6b63\u597d\u662f\u6700\u5927\u7684\u5143\u7d20\uff0c\u90a3\u4e48\u5b83\u6700\u7ec8\u4f1a\u5904\u4e8e\u5217\u8868\u7684\u6700\u53f3\u4fa7\uff1b \u5982\u679c\u57fa\u51c6\u6b63\u597d\u662f\u6700\u5c0f\u7684\u5143\u7d20\uff0c\u90a3\u4e48\u5b83\u5c31\u4f1a\u5728\u6700\u5de6\u4fa7\uff1b \u5206\u6cbb\u6cd5\u3002\u5c06\u8fd9\u4e2a\u8fc7\u7a0b\u9012\u5f52\u5730\u5e94\u7528\u5230\u901a\u8fc7\u57fa\u51c6\u800c\u628a\u539f\u5217\u8868\u5206\u5272\u7684\u5b50\u5217\u8868\u4e0a\uff0c\u5176\u4e2d\uff1a \u4e00\u4e2a\u65b0\u7684\u5b50\u5217\u8868\u7531\u57fa\u51c6\u5de6\u4fa7\u7684\u6240\u6709\u5143\u7d20\uff08\u8f83\u5c0f\u7684\u5143\u7d20\uff09\u7ec4\u6210\uff0c \u53e6\u4e00\u4e2a\u65b0\u7684\u5b50\u5217\u8868\u7531\u57fa\u51c6\u53f3\u4fa7\u7684\u6240\u6709\u5143\u7d20\uff08\u8f83\u5927\u7684\u5143\u7d20\uff09\u7ec4\u6210\uff1b \u5f53\u5206\u51fa\u7684\u5b50\u5217\u8868\u5185\u5c11\u4e8e\u4e24\u4e2a\u5143\u7d20\u65f6\uff0c\u8fd9\u4e2a\u8fc7\u7a0b\u7ec8\u6b62\uff1b 3.5.1.1.\u5206\u5272 \u00b6 \u8fd9\u4e2a\u7b97\u6cd5\u91cc\u6700\u590d\u6742\u7684\u90e8\u5206\u662f\u5bf9\u5143\u7d20\u8fdb\u884c\u5206\u5272\u4ece\u800c\u5f97\u5230\u5b50\u5217\u8868\u7684\u64cd\u4f5c\u3002 \u5c06\u57fa\u51c6\u4e0e\u5b50\u5217\u8868\u91cc\u7684\u6700\u540e\u4e00\u4e2a\u5143\u7d20\u8fdb\u884c\u4ea4\u6362\u3002 \u5728\u5df2\u77e5\u5c0f\u4e8e\u57fa\u51c6\u7684\u5143\u7d20\u548c\u5176\u4ed6\u5143\u7d20\u4e4b\u95f4\u6784\u5efa\u4e00\u4e2a\u8fb9\u754c\u3002\u4e00\u5f00\u59cb\uff0c\u8fd9\u4e2a\u8fb9\u754c\u4f1a\u5904\u4e8e\u7b2c\u4e00\u4e2a\u5143\u7d20\u4e4b\u524d\u3002 \u4ece\u5b50\u5217\u8868\u8fb9\u754c\u4e4b\u540e\u7684\u7b2c\u4e00\u4e2a\u5143\u7d20\u5f00\u59cb\u5411\u53f3\u626b\u63cf\u3002\u5f53\u6bcf\u6b21\u9047\u5230\u5c0f\u4e8e\u57fa\u51c6\u7684\u5143\u7d20\u65f6\uff0c\u5c06\u5b83\u548c\u8fb9\u754c\u4e4b\u540e\u7684\u7b2c\u4e00\u4e2a\u5143\u7d20\u8fdb\u884c\u4ea4\u6362\uff0c\u5e76\u4e14\u5c06\u8fb9\u754c\u5411\u53f3\u79fb\u52a8\u3002 \u5728\u7ed3\u675f\u7684\u65f6\u5019\uff0c\u5c06\u57fa\u51c6\u548c\u8fb9\u754c\u4e4b\u540e\u7684\u7b2c\u4e00\u4e2a\u5143\u7d20\u8fdb\u884c\u4ea4\u6362\u3002 \u793a\u4f8b\u5217\u8868\uff1a[12,19,17,18,14,11,15,13,16]\uff0c\u4e0b\u56fe\u5c55\u793a\u4e86\u5206\u5272\u7684\u6bcf\u4e00\u6b65\u8fc7\u7a0b\u3002 3.5.1.2.\u5feb\u901f\u6392\u5e8f\u590d\u6742\u5ea6\u5206\u6790 \u00b6 \u5feb\u901f\u6392\u5e8f\uff08Quick Sort\uff09\u662f\u4e00\u79cd\u9ad8\u6548\u7684\u6392\u5e8f\u7b97\u6cd5\uff0c\u5176\u5e73\u5747\u548c\u6700\u574f\u65f6\u95f4\u590d\u6742\u5ea6\u90fd\u662f O(n log n) \u3002\u4e0b\u9762\u662f\u5feb\u901f\u6392\u5e8f\u7684\u590d\u6742\u5ea6\u5206\u6790\uff1a \u5728\u7b2c\u4e00\u6b21\u8fdb\u884c\u5206\u5272\u64cd\u4f5c\u65f6\uff0c\u6211\u4eec\u5c06\u626b\u63cf\u5217\u8868\u91cc\u4ece\u5f00\u5934\u5230\u7ed3\u5c3e\u7684\u6240\u6709\u5143\u7d20\u3002\u56e0\u6b64\uff0c\u5728\u8fd9\u4e2a\u64cd\u4f5c\u671f\u95f4\u5de5\u4f5c\u91cf\u662f\u548c\u5217\u8868\u7684\u957f\u5ea6 n \u6210\u6b63\u6bd4\u7684\u3002\u8fd9\u6b21\u5206\u5272\u4e4b\u540e\u7684\u5de5\u4f5c\u91cf\u4f1a\u548c\u5de6\u5b50\u5217\u8868\u52a0\u4e0a\u53f3\u5b50\u5217\u8868\u7684\u603b\u957f\u5ea6\u6210\u6b63\u6bd4\uff0c\u4e5f\u5c31\u662f n-1 \u3002 \u518d\u6b21\u5bf9\u8fd9\u4e24\u4e2a\u5b50\u5217\u8868\u8fdb\u884c\u5206\u5272\u4e4b\u540e\uff0c\u5c31\u4f1a\u4ea7\u751f4\u4e2a\u52a0\u8d77\u6765\u603b\u957f\u5ea6\u5927\u7ea6\u4e3a n \u7684\u5217\u8868\u6bb5\u3002\u56e0\u6b64\uff0c\u5bf9\u5b83\u4eec\u8fdb\u884c\u5206\u5272\u7684\u603b\u5de5\u4f5c\u91cf\u8fd8\u662f\u548c n \u6210\u6b63\u6bd4\u7684\u3002\u968f\u7740\u5217\u8868\u88ab\u5206\u5272\u6210\u66f4\u591a\u6bb5\uff0c\u603b\u5de5\u4f5c\u91cf\u4f1a\u4e00\u76f4\u548c n \u6210\u6b63\u6bd4\u3002 \u8981\u5b8c\u6210\u6574\u4e2a\u5206\u6790\uff0c\u8fd8\u9700\u8981\u786e\u5b9a\u5217\u8868\u88ab\u5206\u5272\u4e86\u591a\u5c11\u6b21\u3002\u6309\u7167\u6700\u4e50\u89c2\u7684\u60c5\u51b5\u6765\u8bf4\uff08\u867d\u7136\u5728\u5b9e\u9645\u64cd\u4f5c\u7684\u65f6\u5019\uff0c\u901a\u5e38\u5e76\u4e0d\u4f1a\u51fa\u73b0\u8fd9\u4e48\u597d\u7684\u60c5\u51b5\uff09\uff0c\u5047\u8bbe\u6bcf\u6b21\u65b0\u5b50\u5217\u8868\u4e4b\u95f4\u7684\u5206\u754c\u7ebf\u90fd\u5c3d\u53ef\u80fd\u5730\u9760\u8fd1\u5f53\u524d\u5217\u8868\u7684\u4e2d\u5fc3\uff0c\u901a\u5e38\u8fd9\u79cd\u60c5\u51b5\u5e76\u4e0d\u5e38\u89c1\u3002\u4ece\u4e8c\u5206\u641c\u7d22\u7b97\u6cd5\u7684\u8ba8\u8bba\u91cc\u53ef\u77e5\uff0c\u8981\u628a\u5217\u8868\u4e0d\u65ad\u5730\u5206\u6210\u4e24\u534a\uff0c\u5927\u7ea6\u5728 log n \u6b65\u7684\u65f6\u5019\u5c31\u53ea\u5269\u4e0b\u4e00\u4e2a\u5143\u7d20\u4e86\u3002 \u56e0\u6b64\uff0c\u8fd9\u4e2a\u7b97\u6cd5\u5728\u6700\u597d\u60c5\u51b5\u4e0b\u7684\u6027\u80fd\u4e3a O(n log n) \u3002\u5728\u6700\u574f\u60c5\u51b5\u4e0b\uff0c\u6211\u4eec\u6765\u8003\u8651\u6709\u5e8f\u5217\u8868\u7684\u60c5\u51b5\u3002\u5982\u679c\u9009\u62e9\u7684\u57fa\u51c6\u5143\u7d20\u662f\u7b2c\u4e00\u4e2a\u5143\u7d20\uff0c\u90a3\u4e48\u5728\u7b2c\u4e00\u6b21\u5206\u5272\u4e4b\u540e\u5b83\u7684\u53f3\u8fb9\u4f1a\u6709 n-1 \u4e2a\u5143\u7d20\uff0c\u5728\u7b2c\u4e8c\u6b21\u5206\u5272\u4e4b\u540e\u5b83\u7684\u53f3\u8fb9\u6709 n-2 \u4e2a\u5143\u7d20\uff0c\u4ee5\u6b64\u7c7b\u63a8\uff0c \u5c3d\u7ba1\u6574\u4e2a\u64cd\u4f5c\u91cc\u6ca1\u6709\u4ea4\u6362\u4efb\u4f55\u5143\u7d20\uff0c\u4f46\u5206\u5272\u603b\u5171\u4e5f\u6267\u884c\u4e86 n-1 \u6b21\uff0c\u4e8e\u662f\u6267\u884c\u7684\u6bd4\u8f83\u603b\u6570\u5c31\u662f n^2/2-n/2 \u3002\u8fd9\u4e0e\u9009\u62e9\u6392\u5e8f\u4ee5\u53ca\u5192\u6ce1\u6392\u5e8f\u7684\u60c5\u51b5\u662f\u4e00\u6837\u7684\u3002\u56e0\u6b64\uff0c\u5728\u6700\u574f\u60c5\u51b5\u4e0b\uff0c\u5feb\u901f\u6392\u5e8f\u7b97\u6cd5\u7684\u6027\u80fd\u4e3a O(n^2) \u3002\u5982\u679c\u628a\u5feb\u901f\u6392\u5e8f\u5b9e\u73b0\u6210\u9012\u5f52\u7b97\u6cd5\uff0c\u90a3\u4e48\u5728\u5bf9\u5b83\u8fdb\u884c\u5206\u6790\u65f6\u8fd8\u5fc5\u987b\u8981\u8003\u8651\u8c03\u7528\u6808\u7684\u5185\u5b58\u4f7f\u7528\u60c5\u51b5\u3002\u7531\u4e8e\u5bf9\u4e8e\u6808\u7684\u4e00\u5e27\uff0c\u6bcf\u6b21\u9012\u5f52\u8c03\u7528\u90fd\u9700\u8981\u56fa\u5b9a\u7684\u5185\u5b58\uff0c\u5e76\u4e14\u6bcf\u6b21\u5206\u5272\u4e4b\u540e\u90fd\u4f1a\u6709\u4e24\u6b21\u9012\u5f52\u8c03\u7528\u3002\u56e0\u6b64\uff0c\u5728\u6700\u597d\u60c5\u51b5\u4e0b\u5185\u5b58\u7684\u4f7f\u7528\u91cf\u4f1a\u662f O(log n) \uff0c\u800c\u6700\u574f\u60c5\u51b5\u4e0b\u7684\u5185\u5b58\u4f7f\u7528\u91cf\u662f O(n) \u3002 \u5c3d\u7ba1\u5feb\u901f\u6392\u5e8f\u5904\u4e8e\u6700\u574f\u60c5\u51b5\u4e0b\u7684\u53ef\u80fd\u6027\u5f88\u5c0f\uff0c\u6211\u4eec\u8fd8\u662f\u4f1a\u52aa\u529b\u5730\u53bb\u907f\u514d\u8fd9\u79cd\u60c5\u51b5\uff0c\u56e0\u6b64\uff0c\u5b83\u4eec\u5e76\u4e0d\u4f1a\u5728\u7b2c\u4e00\u4e2a\u6216\u6700\u540e\u4e00\u4e2a\u4f4d\u7f6e\u9009\u62e9\u57fa\u51c6\u5143\u7d20\u3002\u6709\u5176\u4ed6\u4e00\u4e9b\u9009\u62e9\u57fa\u51c6\u7684\u65b9\u6cd5\u53ef\u4ee5\u8ba9\u8fd9\u4e2a\u7b97\u6cd5\u5728\u5e73\u5747\u60c5\u51b5\u4e0b\u6709\u5927\u7ea6 O(n log n) \u7684\u6027\u80fd\uff0c\u6bd4\u5982\uff0c\u53ef\u4ee5\u9009\u62e9\u968f\u673a\u4f4d\u7f6e\u4e0a\u7684\u5143\u7d20\u4f5c\u4e3a\u57fa\u51c6\uff0c\u6216\u8005\u9009\u62e9\u6574\u4e2a\u5217\u8868\u91cc\u7b2c\u4e00\u4e2a\u4f4d\u7f6e\u3001\u4e2d\u95f4\u4f4d\u7f6e\u4ee5\u53ca\u6700\u540e\u4e00\u4e2a\u4f4d\u7f6e\u8fd93\u4e2a\u5143\u7d20\u7684\u4e2d\u4f4d\u6570\u3002 \u603b\u7ed3\uff1a \u6700\u597d\u60c5\u51b5\u65f6\u95f4\u590d\u6742\u5ea6\uff1a\u5728\u6700\u597d\u60c5\u51b5\u4e0b\uff0c\u4e5f\u5c31\u662f\u6bcf\u6b21\u9009\u62e9\u7684\u57fa\u51c6\u5143\u7d20\u90fd\u521a\u597d\u5c06\u8f93\u5165\u6570\u636e\u5206\u6210\u4e24\u4e2a\u7b49\u957f\u7684\u5b50\u6570\u7ec4\uff0c\u5feb\u901f\u6392\u5e8f\u7684\u65f6\u95f4\u590d\u6742\u5ea6\u662f O(n log n) \u3002\u8fd9\u79cd\u60c5\u51b5\u901a\u5e38\u53d1\u751f\u5728\u57fa\u51c6\u5143\u7d20\u7684\u9009\u62e9\u975e\u5e38\u5408\u7406\u7684\u60c5\u51b5\u4e0b\uff0c\u4f8b\u5982\u5728\u6bcf\u6b21\u9009\u62e9\u4e2d\u90fd\u9009\u62e9\u4e2d\u95f4\u5143\u7d20\u3002 \u5e73\u5747\u60c5\u51b5\u65f6\u95f4\u590d\u6742\u5ea6\uff1a\u5728\u5e73\u5747\u60c5\u51b5\u4e0b\uff0c\u5feb\u901f\u6392\u5e8f\u7684\u65f6\u95f4\u590d\u6742\u5ea6\u4e5f\u662f O(n log n) \u3002\u8fd9\u662f\u56e0\u4e3a\u5feb\u901f\u6392\u5e8f\u662f\u4e00\u79cd\u5206\u6cbb\u7b97\u6cd5\uff0c\u6bcf\u6b21\u5c06\u95ee\u9898\u5206\u6210\u4e24\u4e2a\u5b50\u95ee\u9898\uff0c\u7136\u540e\u9012\u5f52\u5730\u89e3\u51b3\u8fd9\u4e9b\u5b50\u95ee\u9898\u3002\u5e73\u5747\u60c5\u51b5\u4e0b\uff0c\u6bcf\u6b21\u5206\u5272\u64cd\u4f5c\u90fd\u80fd\u5c06\u95ee\u9898\u89c4\u6a21\u51cf\u534a\uff0c\u56e0\u6b64\u9700\u8981\u6267\u884c O(n log n) \u6b21\u5206\u5272\u64cd\u4f5c\uff0c\u6bcf\u6b21\u5206\u5272\u64cd\u4f5c\u7684\u65f6\u95f4\u590d\u6742\u5ea6\u662f O(n) \u3002\u56e0\u6b64\uff0c\u5e73\u5747\u65f6\u95f4\u590d\u6742\u5ea6\u662f O(n log n) \u3002 \u6700\u574f\u60c5\u51b5\u65f6\u95f4\u590d\u6742\u5ea6\uff1a\u5728\u6700\u574f\u60c5\u51b5\u4e0b\uff0c\u5feb\u901f\u6392\u5e8f\u7684\u65f6\u95f4\u590d\u6742\u5ea6\u662f O(n^2) \u3002\u6700\u574f\u60c5\u51b5\u53d1\u751f\u5728\u6bcf\u6b21\u9009\u62e9\u7684\u57fa\u51c6\u5143\u7d20\u90fd\u662f\u8f93\u5165\u6570\u636e\u4e2d\u7684\u6700\u5c0f\u6216\u6700\u5927\u5143\u7d20\uff0c\u5bfc\u81f4\u5206\u5272\u64cd\u4f5c\u4e0d\u5747\u8861\uff0c\u6bcf\u6b21\u5206\u5272\u53ea\u80fd\u5c06\u95ee\u9898\u89c4\u6a21\u51cf\u5c111\u3002\u5728\u8fd9\u79cd\u60c5\u51b5\u4e0b\uff0c\u5feb\u901f\u6392\u5e8f\u9000\u5316\u4e3a\u5192\u6ce1\u6392\u5e8f\uff0c\u65f6\u95f4\u590d\u6742\u5ea6\u4e3a O(n^2) \u3002 \u5feb\u901f\u6392\u5e8f\u7684\u5e73\u5747\u548c\u6700\u597d\u60c5\u51b5\u65f6\u95f4\u590d\u6742\u5ea6\u4e3a O(n log n) \uff0c\u5728\u5b9e\u9645\u5e94\u7528\u4e2d\u901a\u5e38\u6027\u80fd\u4f18\u8d8a\u3002\u7136\u800c\uff0c\u9700\u8981\u6ce8\u610f\u7684\u662f\uff0c\u6700\u574f\u60c5\u51b5\u4e0b\u7684\u65f6\u95f4\u590d\u6742\u5ea6\u4e3a O(n^2) \uff0c\u56e0\u6b64\u5728\u5b9e\u73b0\u5feb\u901f\u6392\u5e8f\u65f6\u9700\u8981\u7279\u522b\u6ce8\u610f\u57fa\u51c6\u5143\u7d20\u7684\u9009\u62e9\u4ee5\u907f\u514d\u6700\u574f\u60c5\u51b5\u7684\u53d1\u751f\u3002 3.5.1.3.\u5b9e\u73b0\u5feb\u901f\u6392\u5e8f \u00b6 \u4ee5\u4e0a\u9762\u56fe\u793a\u7684\u5217\u8868 [12,19,17,18,14,11,15,13,16] \u4e3a\u4f8b\uff0c\u4e0b\u9762\u662f\u5b9e\u73b0\u4ee3\u7801\uff1a import random def swap ( lyst , i , j ): \"\"\"\u4ea4\u6362\u5143\u7d20\u4f4d\u7f6e\u4e3ai\u548cj\u7684\u5143\u7d20\"\"\" temp = lyst [ i ] lyst [ i ] = lyst [ j ] lyst [ j ] = temp def quicksort ( lyst ): # left\u7684\u521d\u59cb\u503c\u662f0 # right\u7684\u521d\u59cb\u503c\u662f\u5217\u8868\u957f\u5ea6\u51cf1 quicksortHelper ( lyst , 0 , len ( lyst ) - 1 ) def quicksortHelper ( lyst , left , right ): print ( lyst ) if left < right : pivotLocation = partition ( lyst , left , right ) quicksortHelper ( lyst , left , pivotLocation - 1 ) quicksortHelper ( lyst , pivotLocation + 1 , right ) def partition ( lyst , left , right ): \"\"\"\u5bf9\u5217\u8868\u8fdb\u884c\u5206\u533a\"\"\" # \u627e\u5230\u57fa\u51c6\u5143\u7d20\uff08pivot\uff09\uff0c\u5e76\u548c\u6700\u540e\u4e00\u4e2a\u5143\u7d20\u4e92\u6362 middle = ( left + right ) // 2 pivot = lyst [ middle ] lyst [ middle ] = lyst [ right ] lyst [ right ] = pivot # \u8bbe\u5b9a\u8fb9\u754c\u5143\u7d20\uff08boundary point\uff09\uff0c\u521d\u59cb\u662f\u7b2c\u4e00\u4e2a\u5143\u7d20 boundary = left print ( \"pivot: \" , pivot , \"boundary: \" , lyst [ boundary ]) # \u628a\u6240\u6709\u5c0f\u4e8e\u57fa\u51c6\u7684\u5143\u7d20\u90fd\u79fb\u52a8\u5230\u8fb9\u754c\u7684\u5de6\u8fb9 for index in range ( left , right ): if lyst [ index ] < pivot : swap ( lyst , index , boundary ) boundary += 1 # \u4ea4\u6362\u57fa\u51c6\u5143\u7d20\u548c\u8fb9\u754c\u5143\u7d20 swap ( lyst , right , boundary ) print ( lyst ) return boundary def main ( size = 20 , sort = quicksort ): lyst = [ 12 , 19 , 17 , 18 , 14 , 11 , 15 , 13 , 16 ] sort ( lyst ) if __name__ == \"__main__\" : main () # \u8fd0\u884c\u7ed3\u679c\uff1a # [12, 19, 17, 18, 14, 11, 15, 13, 16] # pivot: 14 boundary: 12 # [12, 11, 13, 14, 16, 19, 15, 17, 18] # [12, 11, 13, 14, 16, 19, 15, 17, 18] # pivot: 11 boundary: 12 # [11, 13, 12, 14, 16, 19, 15, 17, 18] # [11, 13, 12, 14, 16, 19, 15, 17, 18] # [11, 13, 12, 14, 16, 19, 15, 17, 18] # pivot: 13 boundary: 12 # [11, 12, 13, 14, 16, 19, 15, 17, 18] # [11, 12, 13, 14, 16, 19, 15, 17, 18] # [11, 12, 13, 14, 16, 19, 15, 17, 18] # [11, 12, 13, 14, 16, 19, 15, 17, 18] # pivot: 15 boundary: 16 # [11, 12, 13, 14, 15, 19, 18, 17, 16] # [11, 12, 13, 14, 15, 19, 18, 17, 16] # [11, 12, 13, 14, 15, 19, 18, 17, 16] # pivot: 18 boundary: 19 # [11, 12, 13, 14, 15, 16, 17, 18, 19] # [11, 12, 13, 14, 15, 16, 17, 18, 19] # pivot: 16 boundary: 17 # [11, 12, 13, 14, 15, 16, 17, 18, 19] # [11, 12, 13, 14, 15, 16, 17, 18, 19] # [11, 12, 13, 14, 15, 16, 17, 18, 19] # [11, 12, 13, 14, 15, 16, 17, 18, 19] \u628amain()\u6539\u6210\u5982\u4e0b\uff0c\u5219\u53ef\u4ee5\u751f\u6210\u753120\u4e2a\u968f\u673a\u6574\u6570\u7ec4\u6210\u7684\u5217\u8868\uff1a def main ( size = 20 , sort = quicksort ): lyst = [] for count in range ( size ): lyst . append ( random . randint ( 1 , size + 1 )) print ( lyst ) sort ( lyst ) print ( lyst ) # \u8fd0\u884c\u7ed3\u679c\uff1a # \u7b2c\u4e00\u6b21\u8fd0\u884c # [3, 19, 18, 11, 2, 16, 2, 13, 14, 1, 20, 1, 1, 19, 19, 9, 16, 1, 7, 4] # [1, 1, 1, 1, 2, 2, 3, 4, 7, 9, 11, 13, 14, 16, 16, 18, 19, 19, 19, 20] # \u7b2c\u4e8c\u6b21\u8fd0\u884c # [20, 4, 1, 15, 6, 4, 3, 16, 21, 4, 12, 9, 16, 10, 3, 6, 2, 15, 21, 4] # [1, 2, 3, 3, 4, 4, 4, 4, 6, 6, 9, 10, 12, 15, 15, 16, 16, 20, 21, 21] 3.5.2.\u5f52\u5e76\u6392\u5e8f \u00b6 \u5f52\u5e76\u6392\u5e8f\u7684\u7b97\u6cd5\u4e5f\u662f\u91c7\u7528\u5206\u6cbb\u6cd5\uff08Divide and Conquer\uff09\u7684\u4e00\u4e2a\u975e\u5e38\u5178\u578b\u7684\u5e94\u7528\uff0c\u901a\u8fc7\u9012\u5f52\u548c\u5206\u6cbb\u7b56\u7565\u6765\u7a81\u7834 O(n^2) \u6027\u80fd\u74f6\u9888\u7684\u3002 \u4e0b\u9762\u662f\u5bf9\u8fd9\u4e2a\u7b97\u6cd5\u7684\u7b80\u5355\u63cf\u8ff0\u3002 \u5206\u89e3\uff08Divide\uff09\uff1a\u5c06n\u4e2a\u5143\u7d20\u5206\u6210\u4e2a\u542bn/2\u4e2a\u5143\u7d20\u7684\u5b50\u5e8f\u5217\u3002 \u89e3\u51b3\uff08Conquer\uff09\uff1a\u7528\u5408\u5e76\u6392\u5e8f\u6cd5\u5bf9\u4e24\u4e2a\u5b50\u5e8f\u5217\u9012\u5f52\u7684\u6392\u5e8f\u3002 \u5408\u5e76\uff08Combine\uff09\uff1a\u5408\u5e76\u4e24\u4e2a\u5df2\u6392\u5e8f\u7684\u5b50\u5e8f\u5217\u5df2\u5f97\u5230\u6392\u5e8f\u7ed3\u679c\u3002 \u7b97\u6cd5\u601d\u8def\uff1a \u8fed\u4ee3\u6cd5 \u7533\u8bf7\u7a7a\u95f4\uff0c\u4f7f\u5176\u5927\u5c0f\u4e3a\u4e24\u4e2a\u5df2\u7ecf\u6392\u5e8f\u5e8f\u5217\u4e4b\u548c\uff0c\u8be5\u7a7a\u95f4\u7528\u6765\u5b58\u653e\u5408\u5e76\u540e\u7684\u5e8f\u5217\uff1b \u8bbe\u5b9a\u4e24\u4e2a\u6307\u9488\uff0c\u6700\u521d\u4f4d\u7f6e\u5206\u522b\u4e3a\u4e24\u4e2a\u5df2\u7ecf\u6392\u5e8f\u5e8f\u5217\u7684\u8d77\u59cb\u4f4d\u7f6e\uff1b \u6bd4\u8f83\u4e24\u4e2a\u6307\u9488\u6240\u6307\u5411\u7684\u5143\u7d20\uff0c\u9009\u62e9\u76f8\u5bf9\u5c0f\u7684\u5143\u7d20\u653e\u5165\u5230\u5408\u5e76\u7a7a\u95f4\uff0c\u5e76\u79fb\u52a8\u6307\u9488\u5230\u4e0b\u4e00\u4f4d\u7f6e\uff1b \u91cd\u590d\u6b65\u9aa43\u76f4\u5230\u67d0\u4e00\u6307\u9488\u5230\u8fbe\u5e8f\u5217\u5c3e\uff1b \u5c06\u53e6\u4e00\u5e8f\u5217\u5269\u4e0b\u7684\u6240\u6709\u5143\u7d20\u76f4\u63a5\u590d\u5236\u5230\u5408\u5e76\u5e8f\u5217\u5c3e\uff1b \u9012\u5f52\u6cd5 \u5c06\u5e8f\u5217\u6bcf\u76f8\u90bb\u4e24\u4e2a\u6570\u5b57\u8fdb\u884c\u5f52\u5e76\u64cd\u4f5c\uff0c\u5f62\u6210 floor(n/2) \u4e2a\u5e8f\u5217\uff0c\u6392\u5e8f\u540e\u6bcf\u4e2a\u5e8f\u5217\u5305\u542b\u4e24\u4e2a\u5143\u7d20\uff1b \u5c06\u4e0a\u8ff0\u5e8f\u5217\u518d\u6b21\u5f52\u5e76\uff0c\u5f62\u6210 floor(n/4) \u4e2a\u5e8f\u5217\uff0c\u6bcf\u4e2a\u5e8f\u5217\u5305\u542b\u56db\u4e2a\u5143\u7d20\uff1b \u91cd\u590d\u6b65\u9aa42\uff0c\u76f4\u5230\u6240\u6709\u5143\u7d20\u6392\u5e8f\u5b8c\u6bd5\uff1b \u5728\u9876\u5c42\u5b9a\u4e49\u4e863\u4e2aPython\u51fd\u6570\u8fdb\u884c\u534f\u4f5c\u3002 mergeSort \uff1a\u7528\u6237\u8c03\u7528\u7684\u51fd\u6570\uff1b mergeSortHelper \uff1a\u8f85\u52a9\u51fd\u6570\uff0c\u7528\u6765\u9690\u85cf\u9012\u5f52\u8c03\u7528\u6240\u9700\u8981\u7684\u989d\u5916\u53c2\u6570\uff1b merge \uff1a\u5b9e\u73b0\u5408\u5e76\u8fc7\u7a0b\u7684\u51fd\u6570\uff1b 3.5.2.1.\u5408\u5e76\u8fc7\u7a0b\u7684\u5b9e\u73b0 \u00b6 \u5408\u5e76\u8fc7\u7a0b\u7528\u5230\u4e00\u4e2a\u4e0e\u5217\u8868\u5927\u5c0f\u76f8\u540c\u7684\u6570\u7ec4\uff0c\u8fd9\u4e2a\u6570\u7ec4\u53ef\u4ee5\u628a\u5b83\u79f0\u4e3a copyBuffer \u3002\u4e3a\u4e86\u907f\u514d\u6bcf\u6b21\u8c03\u7528 merge \u65f6\u90fd\u8981\u4e3a copyBuffer \u7684\u5206\u914d\u548c\u91ca\u653e\u4ea7\u751f\u5f00\u9500\uff0c\u8fd9\u4e2a\u7f13\u51b2\u533a\u4f1a\u5728 mergeSort \u51fd\u6570\u91cc\u5c31\u5206\u914d\u597d\uff0c\u7136\u540e\u4f5c\u4e3a\u53c2\u6570\u4f20\u9012\u7ed9 mergeSortHelper \u548c merge \u51fd\u6570\u3002\u6bcf\u6b21\u8c03\u7528 mergeSortHelper \u51fd\u6570\u65f6\uff0c\u5b83\u8fd8\u9700\u8981\u77e5\u9053\u5e94\u8be5\u4f7f\u7528\u7684\u5b50\u5217\u8868\u7684\u8303\u56f4\u3002\u8fd9\u4e2a\u8303\u56f4\u53ef\u4ee5\u7531\u53e6\u5916\u4e24\u4e2a\u53c2\u6570 low \u548c high \u6765\u63d0\u4f9b\u3002\u5177\u4f53\u5b9e\u73b0\u53c2\u8003 mergeSort \u51fd\u6570\u7684\u4ee3\u7801\u3002 \u5728\u68c0\u67e5\u4f20\u9012\u7684\u5b50\u5217\u8868\u662f\u4e0d\u662f\u81f3\u5c11\u6709\u4e24\u4e2a\u5143\u7d20\u4e4b\u540e\uff0c mergeSortHelper \u51fd\u6570\u5c06\u4f1a\u8ba1\u7b97\u8fd9\u4e2a\u5b50\u5217\u8868\u7684\u4e2d\u70b9\uff0c\u5e76\u4e14\u5bf9\u4e2d\u70b9\u5de6\u53f3\u4e24\u90e8\u5206\u8fdb\u884c\u9012\u5f52\u6392\u5e8f\uff0c\u6700\u540e\u518d\u8c03\u7528 merge \u51fd\u6570\u6765\u5408\u5e76\u7ed3\u679c\u3002\u5177\u4f53\u5b9e\u73b0\u53c2\u8003 mergeSortHelper \u51fd\u6570\u7684\u4ee3\u7801\u3002 merge \u51fd\u6570\u4f1a\u628a\u4e24\u4e2a\u5df2\u7ecf\u6392\u597d\u5e8f\u7684\u5b50\u5217\u8868\u5408\u5e76\u6210\u4e00\u4e2a\u66f4\u5927\u7684\u6709\u5e8f\u5217\u8868\u3002\u5728\u539f\u5217\u8868\u91cc\uff0c\u7b2c\u4e00\u4e2a\u5b50\u5217\u8868\u4f1a\u5728 low \u5230 middle \u4e4b\u95f4\uff1b\u7b2c\u4e8c\u4e2a\u5b50\u5217\u8868\u5219\u4f4d\u4e8e middle + 1 \u548c high \u4e4b\u95f4\u3002\u8fd9\u4e2a\u8fc7\u7a0b\u5305\u542b\u5982\u4e0b3\u4e2a\u6b65\u9aa4\u3002 \u8bbe\u7f6e\u6307\u5411\u4e24\u4e2a\u5b50\u5217\u8868\u4e2d\u7b2c\u4e00\u4e2a\u5143\u7d20\u7684\u7d22\u5f15\u6307\u9488\u3002\u5b83\u4eec\u5206\u522b\u4f4d\u4e8e low \u548c middle +1 \uff1b \u4ece\u5b50\u5217\u8868\u7684\u7b2c\u4e00\u4e2a\u5143\u7d20\u5f00\u59cb\u91cd\u590d\u6bd4\u8f83\u8fd9\u4e9b\u5143\u7d20\u3002\u628a\u66f4\u5c0f\u7684\u90a3\u4e2a\u5143\u7d20\u4ece\u5b83\u6240\u5728\u7684\u5b50\u5217\u8868\u91cc\u590d\u5236\u5230\u62f7\u8d1d\u7f13\u51b2\u533a\u53bb\uff0c\u7136\u540e\u628a\u8fd9\u4e2a\u5b50\u5217\u8868\u7684\u7d22\u5f15\u79fb\u52a8\u5230\u4e0b\u4e00\u4e2a\u5143\u7d20\uff1b \u4e0d\u65ad\u5730\u6267\u884c\u8fd9\u4e2a\u64cd\u4f5c\uff0c\u76f4\u5230\u5df2\u7ecf\u5b8c\u5168\u590d\u5236\u4e86\u4e24\u4e2a\u5b50\u5217\u8868\u91cc\u7684\u6240\u6709\u5143\u7d20\u3002\u5982\u679c\u5176\u4e2d\u4e00\u4e2a\u5b50\u5217\u8868\u5df2\u7ecf\u5230\u8fbe\u4e86\u672b\u5c3e\uff0c\u90a3\u4e48\u53ef\u4ee5\u628a\u53e6\u4e00\u4e2a\u5b50\u5217\u8868\u91cc\u7684\u5176\u4f59\u5143\u7d20\u76f4\u63a5\u590d\u5236\u8fc7\u53bb\uff1b \u628a copyBuffer \u4e2d low \u5230 high \u4e4b\u95f4\u7684\u90e8\u5206\u590d\u5236\u56de lyst \u4e2d\u7684\u76f8\u5e94\u4f4d\u7f6e\uff1b \u5b9e\u73b0\u4ee3\u7801\uff1a class Array ( object ): \"\"\" \u63cf\u8ff0\u4e00\u4e2a\u6570\u7ec4\u3002 \u6570\u7ec4\u7c7b\u4f3c\u5217\u8868\uff0c\u4f46\u6570\u7ec4\u53ea\u80fd\u4f7f\u7528[], len, iter, \u548c str\u8fd9\u4e9b\u5c5e\u6027\u3002 \u5b9e\u4f8b\u5316\u4e00\u4e2a\u6570\u7ec4\uff0c\u4f7f\u7528 = Array(, ) \u5176\u4e2dfill value\u9ed8\u8ba4\u503c\u662fNone\u3002 \"\"\" def __init__ ( self , capacity , fillValue = None ): \"\"\"Capacity\u662f\u6570\u7ec4\u7684\u5927\u5c0f. fillValue\u4f1a\u586b\u5145\u5728\u6bcf\u4e2a\u5143\u7d20\u4f4d\u7f6e, \u9ed8\u8ba4\u503c\u662fNone\"\"\" self . items = list () for count in range ( capacity ): self . items . append ( fillValue ) def __len__ ( self ): \"\"\"-> \u6570\u7ec4\u7684\u5927\u5c0f\"\"\" return len ( self . items ) def __str__ ( self ): \"\"\"-> \u5c06\u6570\u7ec4\u5b57\u7b26\u4e32\u5316\"\"\" return str ( self . items ) def __iter__ ( self ): \"\"\"\u652f\u6301for\u5faa\u73af\u5bf9\u6570\u7ec4\u8fdb\u884c\u904d\u5386.\"\"\" return iter ( self . items ) def __getitem__ ( self , index ): \"\"\"\u7528\u4e8e\u8bbf\u95ee\u7d22\u5f15\u5904\u7684\u4e0b\u6807\u8fd0\u7b97\u7b26.\"\"\" return self . items [ index ] def __setitem__ ( self , index , newItem ): \"\"\"\u4e0b\u6807\u8fd0\u7b97\u7b26\u7528\u4e8e\u5728\u7d22\u5f15\u5904\u8fdb\u884c\u66ff\u6362.\"\"\" self . items [ index ] = newItem def mergeSort ( lyst ): # lyst : \u7528\u4e8e\u6392\u5e8f\u7684\u5217\u8868 # copyBuffer : \u7528\u4e8e\u5408\u5e76\u7684\u4e34\u65f6\u7a7a\u95f4 copyBuffer = Array ( len ( lyst )) mergeSortHelper ( lyst , copyBuffer , 0 , len ( lyst ) - 1 ) def mergeSortHelper ( lyst , copyBuffer , low , high ): # lyst : \u7528\u4e8e\u6392\u5e8f\u7684\u5217\u8868 # copyBuffer : \u7528\u4e8e\u5408\u5e76\u7684\u4e34\u65f6\u7a7a\u95f4 # low, high : \u5b50\u5217\u8868\u7684\u8fb9\u754c # middle : \u5b50\u5217\u8868\u7684\u4e2d\u70b9 if low < high : middle = ( low + high ) // 2 print ( f 'low: { lyst [ low ] } , middle: { lyst [ middle ] } , high: { lyst [ high ] } , copyBuffer: { copyBuffer } ' ) # \u9012\u5f52\u5904\u7406\u7b2c\u4e00\u4e2a\u6392\u5e8f\u5b50\u5217\u8868\uff0c\u5373\u4e2d\u503c\u7684\u5de6\u6bb5\uff0c\u76f4\u81f3\u4e0d\u6ee1\u8db3low < high\u65f6\u9000\u51fa mergeSortHelper ( lyst , copyBuffer , low , middle ) # \u9012\u5f52\u5904\u7406\u7b2c\u4e8c\u4e2a\u6392\u5e8f\u5b50\u5217\u8868\uff0c\u5373\u4e2d\u503c\u7684\u53f3\u6bb5\uff0c\u76f4\u81f3\u4e0d\u6ee1\u8db3low < high\u65f6\u9000\u51fa mergeSortHelper ( lyst , copyBuffer , middle + 1 , high ) # \u5f53\u524d\u5904\u7406\u7684\u5b50\u8868\u6570\u636e\u9001\u5165copyBuffer\uff0c\u5408\u5e76\u4e14\u6392\u5e8f merge ( lyst , copyBuffer , low , middle , high ) def merge ( lyst , copyBuffer , low , middle , high ): # lyst : \u7528\u4e8e\u6392\u5e8f\u7684\u5217\u8868 # copyBuffer : \u7528\u4e8e\u5408\u5e76\u7684\u4e34\u65f6\u7a7a\u95f4 # low : \u7b2c\u4e00\u4e2a\u6392\u5e8f\u5b50\u5217\u8868\u7684\u5f00\u5934 # middle : \u7b2c\u4e00\u4e2a\u6392\u5e8f\u5b50\u5217\u8868\u7684\u7ed3\u5c3e # middle + 1 : \u7b2c\u4e8c\u4e2a\u6392\u5e8f\u5b50\u5217\u8868\u7684\u5f00\u5934 # high : \u7b2c\u4e8c\u4e2a\u6392\u5e8f\u5b50\u5217\u8868\u7684\u7ed3\u5c3e # \u5c06 i1 \u548c i2 \u521d\u59cb\u5316\u4e3a\u6bcf\u4e2a\u5b50\u5217\u8868\u4e2d\u7684\u7b2c\u4e00\u9879 i1 = low i2 = middle + 1 # \u5c06\u5b50\u5217\u8868\u4e2d\u7684\u5143\u7d20\u4ea4\u9519\u653e\u5165copyBuffer\u4e2d\uff0c\u5e76\u4fdd\u6301\u987a\u5e8f\u3002 for i in range ( low , high + 1 ): if i1 > middle : copyBuffer [ i ] = lyst [ i2 ] # \u7b2c\u4e00\u4e2a\u5b50\u5217\u8868\u5df2\u7528\u5b8c i2 += 1 elif i2 > high : copyBuffer [ i ] = lyst [ i1 ] # \u7b2c\u4e8c\u4e2a\u5b50\u5217\u8868\u5df2\u7528\u5b8c i1 += 1 elif lyst [ i1 ] < lyst [ i2 ]: copyBuffer [ i ] = lyst [ i1 ] # \u7b2c\u4e00\u4e2a\u5b50\u8868\u4e2d\u7684\u5143\u7d20 < i1 += 1 else : copyBuffer [ i ] = lyst [ i2 ] # \u7b2c\u4e8c\u4e2a\u5b50\u8868\u4e2d\u7684\u5143\u7d20 < i2 += 1 print ( \"i=\" , i , \"\" , \"i1=\" , i1 , \"i2=\" , i2 , \"copyBuffer:\" , copyBuffer ) for i in range ( low , high + 1 ): # \u5c06\u5df2\u6392\u5e8f\u7684\u5143\u7d20\u590d\u5236\u56delyst\u4e2d\u7684\u6b63\u786e\u4f4d\u7f6e lyst [ i ] = copyBuffer [ i ] def main (): lyst = [ 12 , 19 , 17 , 18 , 14 , 11 , 15 , 13 , 16 ] print ( \"Original List\" , lyst ) mergeSort ( lyst ) print ( \"Sorted List\" , lyst ) if __name__ == \"__main__\" : main () # \u8fd0\u884c\u7ed3\u679c\uff1a # Original List [12, 19, 17, 18, 14, 11, 15, 13, 16] # low: 12, middle: 14, high: 16, copyBuffer: [None, None, None, None, None, None, None, None, None] # low: 12, middle: 17, high: 14, copyBuffer: [None, None, None, None, None, None, None, None, None] # low: 12, middle: 19, high: 17, copyBuffer: [None, None, None, None, None, None, None, None, None] # low: 12, middle: 12, high: 19, copyBuffer: [None, None, None, None, None, None, None, None, None] # i= 1 i1= 1 i2= 2 copyBuffer: [12, 19, None, None, None, None, None, None, None] # i= 2 i1= 2 i2= 3 copyBuffer: [12, 17, 19, None, None, None, None, None, None] # low: 18, middle: 18, high: 14, copyBuffer: [12, 17, 19, None, None, None, None, None, None] # i= 4 i1= 4 i2= 5 copyBuffer: [12, 17, 19, 14, 18, None, None, None, None] # i= 4 i1= 3 i2= 5 copyBuffer: [12, 14, 17, 18, 19, None, None, None, None] # low: 11, middle: 15, high: 16, copyBuffer: [12, 14, 17, 18, 19, None, None, None, None] # low: 11, middle: 11, high: 15, copyBuffer: [12, 14, 17, 18, 19, None, None, None, None] # i= 6 i1= 6 i2= 7 copyBuffer: [12, 14, 17, 18, 19, 11, 15, None, None] # low: 13, middle: 13, high: 16, copyBuffer: [12, 14, 17, 18, 19, 11, 15, None, None] # i= 8 i1= 8 i2= 9 copyBuffer: [12, 14, 17, 18, 19, 11, 15, 13, 16] # i= 8 i1= 7 i2= 9 copyBuffer: [12, 14, 17, 18, 19, 11, 13, 15, 16] # i= 8 i1= 5 i2= 9 copyBuffer: [11, 12, 13, 14, 15, 16, 17, 18, 19] # Sorted List [11, 12, 13, 14, 15, 16, 17, 18, 19] \u8fd0\u884c\u7ed3\u679c\u56fe\u793a\u5206\u6790\uff1a 3.5.2.2.\u5f52\u5e76\u6392\u5e8f\u7684\u590d\u6742\u5ea6\u5206\u6790 \u00b6 merge \u51fd\u6570\u7684\u8fd0\u884c\u65f6\u7531\u4e24\u4e2a for \u8bed\u53e5\u6765\u51b3\u5b9a\uff0c\u800c\u8fd9\u4e24\u4e2a\u5faa\u73af\u90fd\u4f1a\u88ab\u8fed\u4ee3 (high \u2013 low + 1) \u6b21\uff0c\u56e0\u6b64\uff0c\u8fd9\u4e2a\u51fd\u6570\u7684\u8fd0\u884c\u65f6\u662f O(high\u2212low) \uff0c\u4e8e\u662f\u6bcf\u4e00\u5c42\u4e0a\u7684\u6240\u6709\u5408\u5e76\u603b\u5171\u9700\u8981 O(n) \u7684\u65f6\u95f4\u3002\u56e0\u4e3a mergeSortHelper \u5728\u6bcf\u4e00\u5c42\u90fd\u5c3d\u53ef\u80fd\u5747\u5300\u5730\u62c6\u5206\u5b50\u5217\u8868\uff0c\u6240\u4ee5\u5c42\u6570\u5e94\u8be5\u662f O(log n) \uff0c\u5728\u6240\u6709\u7684\u60c5\u51b5\u4e0b\u8fd9\u4e2a\u51fd\u6570\u7684\u6700\u5927\u8fd0\u884c\u65f6\u90fd\u662f O(n log n) \u3002 \u5f52\u5e76\u6392\u5e8f\u4f1a\u6709\u4e24\u4e2a\u57fa\u4e8e\u5217\u8868\u5927\u5c0f\u7684\u7a7a\u95f4\u9700\u6c42\u3002\u9996\u5148\uff0c\u5728\u8c03\u7528\u6808\u4e0a\u9700\u8981 O(log n) \u7684\u7a7a\u95f4\u6765\u652f\u6301\u9012\u5f52\u8c03\u7528\uff1b\u5176\u6b21\uff0c\u62f7\u8d1d\u7f13\u51b2\u533a\u4f1a\u7528\u5230 O(n) \u7684\u7a7a\u95f4\u3002 3.5.3.\u7ec3\u4e60\u9898 \u00b6 \u63cf\u8ff0\u5feb\u901f\u6392\u5e8f\u7684\u7b56\u7565\uff0c\u5e76\u8bf4\u660e\u4e3a\u4ec0\u4e48\u5b83\u53ef\u4ee5\u628a\u6392\u5e8f\u7684\u65f6\u95f4\u590d\u6742\u5ea6\u4ece O(n^2) \u964d\u4f4e\u5230 O(n log n) \u3002 \u89e3\u7b54\uff1a\u5feb\u901f\u6392\u5e8f\uff08Quick Sort\uff09\u662f\u4e00\u79cd\u9ad8\u6548\u7684\u6392\u5e8f\u7b97\u6cd5\uff0c\u5b83\u91c7\u7528\u5206\u6cbb\u7b56\u7565\u6765\u5c06\u4e00\u4e2a\u5927\u95ee\u9898\u5206\u89e3\u6210\u82e5\u5e72\u4e2a\u5b50\u95ee\u9898\uff0c\u7136\u540e\u9012\u5f52\u5730\u89e3\u51b3\u8fd9\u4e9b\u5b50\u95ee\u9898\u3002\u4ee5\u4e0b\u662f\u5feb\u901f\u6392\u5e8f\u7684\u7b56\u7565\u548c\u539f\u7406\uff0c\u4ee5\u53ca\u4e3a\u4ec0\u4e48\u5b83\u80fd\u591f\u5c06\u6392\u5e8f\u7684\u65f6\u95f4\u590d\u6742\u5ea6\u4ece O(n^2) \u964d\u4f4e\u5230 O(n log n) \uff1a \u5feb\u901f\u6392\u5e8f\u7684\u7b56\u7565\uff1a \u9009\u62e9\u4e3b\u5143\uff08Pivot\uff09\uff1a\u5728\u5feb\u901f\u6392\u5e8f\u4e2d\uff0c\u9996\u5148\u4ece\u5f85\u6392\u5e8f\u7684\u5143\u7d20\u4e2d\u9009\u62e9\u4e00\u4e2a\u4e3b\u5143\uff08\u901a\u5e38\u662f\u7b2c\u4e00\u4e2a\u6216\u6700\u540e\u4e00\u4e2a\u5143\u7d20\uff09\uff0c\u4e5f\u53eb\u57fa\u51c6\u5143\u7d20\u3002 \u5206\u5272\u64cd\u4f5c\uff1a\u5c06\u5143\u7d20\u5206\u4e3a\u4e24\u4e2a\u5b50\u6570\u7ec4\uff0c\u4e00\u4e2a\u5c0f\u4e8e\u4e3b\u5143\u7684\u5b50\u6570\u7ec4\uff0c\u4e00\u4e2a\u5927\u4e8e\u4e3b\u5143\u7684\u5b50\u6570\u7ec4\u3002\u8fd9\u4e2a\u8fc7\u7a0b\u79f0\u4e3a\u5206\u5272\u3002 \u9012\u5f52\u6392\u5e8f\uff1a\u9012\u5f52\u5730\u5bf9\u4e24\u4e2a\u5b50\u6570\u7ec4\u8fdb\u884c\u6392\u5e8f\u3002\u5373\uff0c\u5bf9\u5c0f\u4e8e\u4e3b\u5143\u7684\u5b50\u6570\u7ec4\u548c\u5927\u4e8e\u4e3b\u5143\u7684\u5b50\u6570\u7ec4\u5206\u522b\u8fdb\u884c\u5feb\u901f\u6392\u5e8f\u3002 \u5408\u5e76\uff1a\u5c06\u5df2\u6392\u5e8f\u7684\u5b50\u6570\u7ec4\u5408\u5e76\u6210\u6700\u7ec8\u7684\u6709\u5e8f\u6570\u7ec4\u3002 \u4e3a\u4ec0\u4e48\u5feb\u901f\u6392\u5e8f\u80fd\u591f\u964d\u4f4e\u65f6\u95f4\u590d\u6742\u5ea6\uff1a \u5feb\u901f\u6392\u5e8f\u4e4b\u6240\u4ee5\u80fd\u591f\u5c06\u6392\u5e8f\u7684\u65f6\u95f4\u590d\u6742\u5ea6\u4ece O(n^2) \u964d\u4f4e\u5230 O(n log n) \uff0c\u4e3b\u8981\u6709\u4ee5\u4e0b\u539f\u56e0\uff1a \u5206\u6cbb\u7b56\u7565\uff1a\u5feb\u901f\u6392\u5e8f\u91c7\u7528\u4e86\u5206\u6cbb\u7b56\u7565\uff0c\u5c06\u4e00\u4e2a\u5927\u95ee\u9898\u5206\u89e3\u6210\u4e24\u4e2a\u6216\u591a\u4e2a\u89c4\u6a21\u8f83\u5c0f\u7684\u5b50\u95ee\u9898\u3002\u8fd9\u79cd\u5206\u6cbb\u7b56\u7565\u80fd\u591f\u51cf\u5c0f\u95ee\u9898\u7684\u89c4\u6a21\uff0c\u4ece\u800c\u964d\u4f4e\u4e86\u89e3\u51b3\u95ee\u9898\u7684\u590d\u6742\u5ea6\u3002 \u597d\u7684\u5e73\u5747\u60c5\u51b5\uff1a\u5728\u5e73\u5747\u60c5\u51b5\u4e0b\uff0c\u5feb\u901f\u6392\u5e8f\u5bf9\u5f85\u6392\u5e8f\u7684\u6570\u636e\u8fdb\u884c\u4e86\u826f\u597d\u7684\u5e73\u5747\u5206\u5272\uff0c\u6bcf\u6b21\u5206\u5272\u90fd\u5c06\u95ee\u9898\u89c4\u6a21\u51cf\u534a\u3002\u8fd9\u4f7f\u5f97\u5e73\u5747\u65f6\u95f4\u590d\u6742\u5ea6\u4e3a O(n log n) \u3002 **\u4e0d\u7a33\u5b9a\u6027\uff1a\u5feb\u901f\u6392\u5e8f\u662f\u4e0d\u7a33\u5b9a\u7684\u6392\u5e8f\u7b97\u6cd5\uff0c\u8fd9\u610f\u5473\u7740\u76f8\u540c\u5143\u7d20\u7684\u76f8\u5bf9\u987a\u5e8f\u5728\u6392\u5e8f\u540e\u53ef\u80fd\u4f1a\u6539\u53d8\u3002\u8fd9\u79cd\u4e0d\u7a33\u5b9a\u6027\u4f7f\u5f97\u5feb\u901f\u6392\u5e8f\u53ef\u4ee5\u66f4\u5feb\u5730\u6392\u5e8f\u76f8\u540c\u5143\u7d20\u7684\u5927\u6570\u636e\u96c6\u3002 \u539f\u5730\u6392\u5e8f\uff1a\u5feb\u901f\u6392\u5e8f\u901a\u5e38\u662f\u539f\u5730\u6392\u5e8f\u7684\uff0c\u5b83\u4e0d\u9700\u8981\u989d\u5916\u7684\u5185\u5b58\u6765\u5b58\u50a8\u4e34\u65f6\u6570\u636e\u3002\u8fd9\u5bf9\u4e8e\u5185\u5b58\u5360\u7528\u6709\u9650\u7684\u60c5\u51b5\u5f88\u6709\u5229\u3002 \u6700\u574f\u60c5\u51b5\u4e0b\uff0c\u5feb\u901f\u6392\u5e8f\u7684\u65f6\u95f4\u590d\u6742\u5ea6\u4ecd\u7136\u662f O(n^2) \uff0c\u8fd9\u79cd\u60c5\u51b5\u901a\u5e38\u53d1\u751f\u5728\u4e3b\u5143\u9009\u62e9\u4e0d\u5f53\u6216\u8f93\u5165\u6570\u636e\u5df2\u7ecf\u6709\u5e8f\u7684\u60c5\u51b5\u4e0b\u3002\u5728\u5b9e\u9645\u5e94\u7528\u4e2d\uff0c\u901a\u5e38\u9700\u8981\u9009\u62e9\u4e00\u4e2a\u5408\u9002\u7684\u4e3b\u5143\u9009\u62e9\u7b56\u7565\uff0c\u4ee5\u5c3d\u91cf\u907f\u514d\u6700\u574f\u60c5\u51b5\u7684\u53d1\u751f\u3002 \u4e3a\u4ec0\u4e48\u5feb\u901f\u6392\u5e8f\u5e76\u4e0d\u5728\u6240\u6709\u60c5\u51b5\u4e0b\u90fd\u6709 O(n log n) \u7684\u590d\u6742\u5ea6\uff1f\u5bf9\u5feb\u901f\u6392\u5e8f\u7684\u6700\u574f\u60c5\u51b5\u8fdb\u884c\u63cf\u8ff0\uff0c\u5e76\u7ed9\u51fa\u4e00\u4e2a\u4f1a\u4ea7\u751f\u8fd9\u4e2a\u60c5\u51b5\u7684\u5305\u542b10\u4e2a\u6574\u6570\uff081\uff5e10\uff09\u7684\u5217\u8868\u3002 \u89e3\u7b54\uff1a\u5feb\u901f\u6392\u5e8f\u5e76\u4e0d\u5728\u6240\u6709\u60c5\u51b5\u4e0b\u90fd\u5177\u6709 O(n log n) \u7684\u65f6\u95f4\u590d\u6742\u5ea6\uff0c\u5b83\u7684\u6027\u80fd\u53d6\u51b3\u4e8e\u4e3b\u5143\uff08pivot\uff09\u7684\u9009\u62e9\u548c\u8f93\u5165\u6570\u636e\u7684\u5206\u5e03\u60c5\u51b5\u3002\u6700\u574f\u60c5\u51b5\u53d1\u751f\u5728\u4ee5\u4e0b\u60c5\u51b5\u4e0b\uff1a \u4e3b\u5143\u9009\u62e9\u4e0d\u5f53\uff1a\u5982\u679c\u6bcf\u6b21\u9009\u62e9\u7684\u4e3b\u5143\u90fd\u662f\u8f93\u5165\u6570\u636e\u4e2d\u7684\u6700\u5c0f\u6216\u6700\u5927\u5143\u7d20\uff0c\u5feb\u901f\u6392\u5e8f\u5c06\u4f1a\u4ea7\u751f\u6700\u574f\u60c5\u51b5\u3002\u5728\u8fd9\u79cd\u60c5\u51b5\u4e0b\uff0c\u5206\u5272\u64cd\u4f5c\u5c06\u5bfc\u81f4\u4e00\u4e2a\u5b50\u6570\u7ec4\u4e3a\u7a7a\uff0c\u53e6\u4e00\u4e2a\u5b50\u6570\u7ec4\u7684\u5927\u5c0f\u4e3a\u539f\u59cb\u6570\u7ec4\u5927\u5c0f\u51cf\u4e00\u3002\u8fd9\u4f7f\u5f97\u6bcf\u6b21\u5206\u5272\u64cd\u4f5c\u53ea\u51cf\u5c11\u4e00\u4e2a\u5143\u7d20\uff0c\u5bfc\u81f4\u9012\u5f52\u6df1\u5ea6\u8fbe\u5230\u6700\u5927\uff0c\u65f6\u95f4\u590d\u6742\u5ea6\u4e3a O(n^2) \u3002 \u8f93\u5165\u6570\u636e\u5df2\u7ecf\u6709\u5e8f\uff1a\u5982\u679c\u8f93\u5165\u6570\u636e\u5df2\u7ecf\u662f\u6709\u5e8f\u7684\uff0c\u4e0d\u7ba1\u662f\u5347\u5e8f\u8fd8\u662f\u964d\u5e8f\uff0c\u5feb\u901f\u6392\u5e8f\u4e5f\u4f1a\u4ea7\u751f\u6700\u574f\u60c5\u51b5\u3002\u56e0\u4e3a\u65e0\u8bba\u5982\u4f55\u9009\u62e9\u4e3b\u5143\uff0c\u5206\u5272\u64cd\u4f5c\u90fd\u5c06\u5bfc\u81f4\u4e00\u4e2a\u5b50\u6570\u7ec4\u4e3a\u7a7a\uff0c\u53e6\u4e00\u4e2a\u5b50\u6570\u7ec4\u7684\u5927\u5c0f\u4e3a\u539f\u59cb\u6570\u7ec4\u5927\u5c0f\u51cf\u4e00\u3002 \u4e0b\u9762\u662f\u4e00\u4e2a\u5305\u542b10\u4e2a\u6574\u6570\uff081\uff5e10\uff09\u7684\u5217\u8868\uff0c\u6f14\u793a\u4e86\u5bfc\u81f4\u5feb\u901f\u6392\u5e8f\u6700\u574f\u60c5\u51b5\u7684\u8f93\u5165\u6570\u636e\uff1a [ 10 , 9 , 8 , 7 , 6 , 5 , 4 , 3 , 2 , 1 ] \u5728\u8fd9\u4e2a\u793a\u4f8b\u4e2d\uff0c\u6bcf\u6b21\u9009\u62e9\u7684\u4e3b\u5143\u90fd\u662f\u6700\u5927\u7684\u5143\u7d20\uff0810\uff09\uff0c\u5bfc\u81f4\u5206\u5272\u64cd\u4f5c\u4e0d\u65ad\u51cf\u5c11\u6570\u7ec4\u7684\u5927\u5c0f\uff0c\u9012\u5f52\u6df1\u5ea6\u8fbe\u5230\u6700\u5927\uff0c\u65f6\u95f4\u590d\u6742\u5ea6\u4e3a O(n^2) \u3002 \u8981\u907f\u514d\u6700\u574f\u60c5\u51b5\uff0c\u901a\u5e38\u91c7\u7528\u4ee5\u4e0b\u7b56\u7565\uff1a \u9009\u62e9\u5408\u9002\u7684\u4e3b\u5143\uff0c\u4f8b\u5982\u9009\u62e9\u4e2d\u95f4\u5143\u7d20\uff0c\u4ee5\u786e\u4fdd\u5e73\u5747\u5206\u5272\u3002 \u968f\u673a\u9009\u62e9\u4e3b\u5143\uff0c\u4ee5\u51cf\u5c11\u51fa\u73b0\u6700\u574f\u60c5\u51b5\u7684\u6982\u7387\u3002 \u8fd9\u4e9b\u7b56\u7565\u6709\u52a9\u4e8e\u7ef4\u6301\u5feb\u901f\u6392\u5e8f\u7684\u5e73\u5747\u65f6\u95f4\u590d\u6742\u5ea6\u4e3a O(n log n) \u3002 \u5feb\u901f\u6392\u5e8f\u91cc\u7684\u5206\u5272\u64cd\u4f5c\u4f1a\u9009\u62e9\u4e2d\u70b9\u5143\u7d20\u4f5c\u4e3a\u57fa\u51c6\u3002\u8bf7\u63cf\u8ff0\u53e6\u5916\u4e24\u79cd\u9009\u62e9\u57fa\u51c6\u7684\u7b56\u7565\u3002 \u89e3\u7b54\uff1a\u5feb\u901f\u6392\u5e8f\u4e2d\u7684\u5206\u5272\u64cd\u4f5c\u53ef\u4ee5\u9009\u62e9\u4e2d\u70b9\u5143\u7d20\u4f5c\u4e3a\u57fa\u51c6\uff0c\u4f46\u8fd8\u6709\u5176\u4ed6\u4e24\u79cd\u5e38\u89c1\u7684\u9009\u62e9\u57fa\u51c6\u7684\u7b56\u7565\uff0c\u5b83\u4eec\u5206\u522b\u662f\uff1a \u968f\u673a\u9009\u62e9\u57fa\u51c6\uff08Random Pivot\uff09\uff1a\u8fd9\u79cd\u7b56\u7565\u662f\u5728\u5f85\u6392\u5e8f\u6570\u7ec4\u4e2d\u968f\u673a\u9009\u62e9\u4e00\u4e2a\u5143\u7d20\u4f5c\u4e3a\u57fa\u51c6\u3002\u968f\u673a\u9009\u62e9\u57fa\u51c6\u7684\u597d\u5904\u662f\u53ef\u4ee5\u964d\u4f4e\u51fa\u73b0\u6700\u574f\u60c5\u51b5\u7684\u6982\u7387\uff0c\u56e0\u4e3a\u5728\u5927\u591a\u6570\u60c5\u51b5\u4e0b\uff0c\u968f\u673a\u9009\u62e9\u7684\u57fa\u51c6\u4f1a\u6bd4\u56fa\u5b9a\u4f4d\u7f6e\u7684\u57fa\u51c6\u66f4\u5e73\u5747\u5730\u5212\u5206\u6570\u636e\u3002\u8fd9\u53ef\u4ee5\u63d0\u9ad8\u7b97\u6cd5\u7684\u6027\u80fd\u3002 \u4e09\u6570\u53d6\u4e2d\u6cd5\uff08Median-of-Three Pivot\uff09\uff1a\u8fd9\u79cd\u7b56\u7565\u662f\u5728\u5f85\u6392\u5e8f\u6570\u7ec4\u4e2d\u9009\u62e9\u4e09\u4e2a\u5143\u7d20\uff08\u901a\u5e38\u662f\u7b2c\u4e00\u4e2a\u3001\u4e2d\u95f4\u4e00\u4e2a\u548c\u6700\u540e\u4e00\u4e2a\u5143\u7d20\uff09\uff0c\u7136\u540e\u4ece\u8fd9\u4e09\u4e2a\u5143\u7d20\u4e2d\u9009\u62e9\u4e2d\u95f4\u503c\u4f5c\u4e3a\u57fa\u51c6\u3002\u8fd9\u4e2a\u7b56\u7565\u7684\u76ee\u7684\u662f\u5728\u5c3d\u91cf\u907f\u514d\u6700\u574f\u60c5\u51b5\u7684\u540c\u65f6\uff0c\u4fdd\u6301\u57fa\u51c6\u7684\u76f8\u5bf9\u4e2d\u95f4\u4f4d\u7f6e\u3002\u8fd9\u53ef\u4ee5\u63d0\u9ad8\u7b97\u6cd5\u7684\u5e73\u5747\u6027\u80fd\u3002 \u8fd9\u4e09\u79cd\u9009\u62e9\u57fa\u51c6\u7684\u7b56\u7565\u5404\u6709\u4f18\u52a3\uff0c\u4f46\u5b83\u4eec\u7684\u5171\u540c\u76ee\u6807\u662f\u964d\u4f4e\u6700\u574f\u60c5\u51b5\u7684\u6982\u7387\uff0c\u4ece\u800c\u63d0\u9ad8\u5feb\u901f\u6392\u5e8f\u7684\u6027\u80fd\u3002\u5728\u5b9e\u9645\u5e94\u7528\u4e2d\uff0c\u9009\u62e9\u54ea\u79cd\u7b56\u7565\u53d6\u51b3\u4e8e\u5177\u4f53\u7684\u60c5\u51b5\u548c\u5b9e\u73b0\u3002 \u5f53\u5feb\u901f\u6392\u5e8f\u91cc\u7684\u5b50\u5217\u8868\u7684\u957f\u5ea6\u5c0f\u4e8e\u67d0\u4e2a\u6570\u5b57\uff08\u598230\uff09\u65f6\uff0c\u6267\u884c\u63d2\u5165\u6392\u5e8f\u6765\u5904\u7406\u8fd9\u4e2a\u5b50\u5217\u8868\u3002\u8bf7\u8bf4\u660e\u4e3a\u4ec0\u4e48\u8fd9\u662f\u4e00\u4e2a\u597d\u65b9\u6cd5\u3002 \u89e3\u7b54\uff1a\u5728\u5feb\u901f\u6392\u5e8f\u4e2d\uff0c\u5f53\u5b50\u5217\u8868\u7684\u957f\u5ea6\u53d8\u5f97\u5f88\u5c0f\u65f6\uff08\u901a\u5e38\u5c0f\u4e8e\u67d0\u4e2a\u9884\u5b9a\u7684\u9608\u503c\uff0c\u598230\u6216\u5176\u4ed6\u7ecf\u9a8c\u503c\uff09\uff0c\u6267\u884c\u63d2\u5165\u6392\u5e8f\u6765\u5904\u7406\u8fd9\u4e2a\u5b50\u5217\u8868\u662f\u4e00\u4e2a\u597d\u65b9\u6cd5\uff0c\u4e3b\u8981\u57fa\u4e8e\u4ee5\u4e0b\u8003\u8651\uff1a \u63d2\u5165\u6392\u5e8f\u5bf9\u5c0f\u89c4\u6a21\u6570\u636e\u8868\u73b0\u826f\u597d\uff1a\u63d2\u5165\u6392\u5e8f\u662f\u4e00\u79cd\u7b80\u5355\u4f46\u9ad8\u6548\u7684\u6392\u5e8f\u7b97\u6cd5\uff0c\u7279\u522b\u9002\u7528\u4e8e\u5c0f\u89c4\u6a21\u6570\u636e\u96c6\u3002\u5b83\u7684\u65f6\u95f4\u590d\u6742\u5ea6\u4e3a O(n^2) \uff0c\u4f46\u5728\u5b9e\u9645\u5e94\u7528\u4e2d\uff0c\u5bf9\u4e8e\u5c0f\u89c4\u6a21\u7684\u6570\u636e\uff0c\u5b83\u7684\u6027\u80fd\u901a\u5e38\u5f88\u597d\u3002 \u51cf\u5c11\u9012\u5f52\u6df1\u5ea6\uff1a\u5728\u5feb\u901f\u6392\u5e8f\u4e2d\uff0c\u6bcf\u6b21\u9012\u5f52\u8c03\u7528\u90fd\u4f1a\u589e\u52a0\u9012\u5f52\u6df1\u5ea6\uff0c\u800c\u9012\u5f52\u6df1\u5ea6\u8fc7\u5927\u53ef\u80fd\u4f1a\u5bfc\u81f4\u6808\u6ea2\u51fa\u6216\u6027\u80fd\u4e0b\u964d\u3002\u5f53\u5b50\u5217\u8868\u957f\u5ea6\u5c0f\u4e8e\u67d0\u4e2a\u9608\u503c\u65f6\uff0c\u4f7f\u7528\u63d2\u5165\u6392\u5e8f\u53ef\u4ee5\u907f\u514d\u4e0d\u5fc5\u8981\u7684\u9012\u5f52\u6df1\u5ea6\uff0c\u4ece\u800c\u51cf\u5c11\u9012\u5f52\u8c03\u7528\u7684\u6b21\u6570\u3002 \u9002\u7528\u4e8e\u90e8\u5206\u6709\u5e8f\u7684\u5b50\u5217\u8868\uff1a\u5f53\u5b50\u5217\u8868\u5df2\u7ecf\u90e8\u5206\u6709\u5e8f\u65f6\uff0c\u63d2\u5165\u6392\u5e8f\u7684\u6027\u80fd\u901a\u5e38\u6bd4\u5feb\u901f\u6392\u5e8f\u66f4\u597d\u3002\u56e0\u6b64\uff0c\u5bf9\u4e8e\u53ef\u80fd\u5305\u542b\u5df2\u6392\u5e8f\u90e8\u5206\u7684\u5c0f\u5b50\u5217\u8868\uff0c\u4f7f\u7528\u63d2\u5165\u6392\u5e8f\u53ef\u4ee5\u63d0\u9ad8\u7b97\u6cd5\u7684\u6548\u7387\u3002 \u51cf\u5c11\u9012\u5f52\u5f00\u9500\uff1a\u9012\u5f52\u5f00\u9500\u662f\u5feb\u901f\u6392\u5e8f\u7684\u4e00\u4e2a\u4e0d\u53ef\u5ffd\u89c6\u7684\u56e0\u7d20\uff0c\u7279\u522b\u662f\u5728\u5904\u7406\u5c0f\u89c4\u6a21\u5b50\u5217\u8868\u65f6\u3002\u901a\u8fc7\u4f7f\u7528\u63d2\u5165\u6392\u5e8f\u6765\u5904\u7406\u8fd9\u4e9b\u5c0f\u89c4\u6a21\u5b50\u5217\u8868\uff0c\u53ef\u4ee5\u51cf\u5c11\u9012\u5f52\u5f00\u9500\uff0c\u63d0\u9ad8\u7b97\u6cd5\u7684\u6574\u4f53\u6027\u80fd\u3002 \u5c06\u63d2\u5165\u6392\u5e8f\u4e0e\u5feb\u901f\u6392\u5e8f\u7ed3\u5408\u4f7f\u7528\u662f\u4e00\u79cd\u5e38\u89c1\u7684\u4f18\u5316\u7b56\u7565\uff0c\u5b83\u53ef\u4ee5\u5728\u5904\u7406\u5c0f\u89c4\u6a21\u5b50\u5217\u8868\u65f6\u63d0\u9ad8\u7b97\u6cd5\u7684\u6548\u7387\uff0c\u540c\u65f6\u4fdd\u6301\u5feb\u901f\u6392\u5e8f\u7684\u6574\u4f53\u6027\u80fd\u3002\u8fd9\u79cd\u65b9\u6cd5\u88ab\u79f0\u4e3a\u201c\u5feb\u901f\u6392\u5e8f\u7684\u6539\u8fdb\u201d\u6216\u201c\u5feb\u901f\u6392\u5e8f\u7684\u6df7\u5408\u6392\u5e8f\u201d\u7b56\u7565\uff0c\u7528\u4e8e\u5728\u5b9e\u9645\u5e94\u7528\u4e2d\u63d0\u9ad8\u7b97\u6cd5\u7684\u6548\u7387\u3002 \u4e3a\u4ec0\u4e48\u5f52\u5e76\u6392\u5e8f\u5728\u6700\u574f\u60c5\u51b5\u4e0b\u4e5f\u662f\u4e00\u4e2a O(n log n) \u7b97\u6cd5\uff1f \u89e3\u7b54\uff1a\u5f52\u5e76\u6392\u5e8f\u5728\u6700\u574f\u60c5\u51b5\u4e0b\u4ecd\u7136\u5177\u6709 O(n log n) \u7684\u65f6\u95f4\u590d\u6742\u5ea6\uff0c\u8fd9\u662f\u56e0\u4e3a\u5f52\u5e76\u6392\u5e8f\u7684\u7b97\u6cd5\u8bbe\u8ba1\u4f7f\u5176\u80fd\u591f\u7a33\u5b9a\u5730\u4fdd\u6301\u8fd9\u79cd\u6027\u80fd\uff0c\u4e0d\u53d7\u8f93\u5165\u6570\u636e\u5206\u5e03\u7684\u5f71\u54cd\u3002 \u4ee5\u4e0b\u662f\u5f52\u5e76\u6392\u5e8f\u5728\u6700\u574f\u60c5\u51b5\u4e0b\u4ecd\u7136\u5177\u6709 O(n log n) \u65f6\u95f4\u590d\u6742\u5ea6\u7684\u539f\u56e0\uff1a \u5206\u800c\u6cbb\u4e4b\u7b56\u7565\uff1a\u5f52\u5e76\u6392\u5e8f\u91c7\u7528\u4e86\u5206\u800c\u6cbb\u4e4b\u7684\u7b56\u7565\uff0c\u5c06\u95ee\u9898\u5206\u89e3\u4e3a\u8f83\u5c0f\u7684\u5b50\u95ee\u9898\uff0c\u7136\u540e\u5408\u5e76\u8fd9\u4e9b\u5b50\u95ee\u9898\u7684\u89e3\u3002\u8fd9\u4e2a\u7b56\u7565\u786e\u4fdd\u4e86\u7b97\u6cd5\u7684\u9012\u5f52\u6df1\u5ea6\u5728 log n \u7ea7\u522b\uff0c\u56e0\u4e3a\u6bcf\u6b21\u9012\u5f52\u90fd\u5c06\u6570\u636e\u5212\u5206\u6210\u4e24\u534a\uff0c\u76f4\u5230\u6700\u5c0f\u5b50\u95ee\u9898\u7684\u5927\u5c0f\u4e3a1\u3002 \u5408\u5e76\u64cd\u4f5c\u7684\u7ebf\u6027\u65f6\u95f4\uff1a\u5f52\u5e76\u6392\u5e8f\u7684\u5173\u952e\u64cd\u4f5c\u662f\u5408\u5e76\u5df2\u6392\u5e8f\u7684\u5b50\u6570\u7ec4\u3002\u5408\u5e76\u64cd\u4f5c\u7684\u65f6\u95f4\u590d\u6742\u5ea6\u662f\u7ebf\u6027\u7684\uff0c\u4e0e\u8f93\u5165\u6570\u636e\u7684\u89c4\u6a21 n \u6210\u6b63\u6bd4\u3002\u56e0\u6b64\uff0c\u5373\u4f7f\u5728\u5408\u5e76\u9636\u6bb5\uff0c\u7b97\u6cd5\u7684\u603b\u65f6\u95f4\u590d\u6742\u5ea6\u4ecd\u7136\u53d7\u9650\u4e8e O(n log n) \u3002 \u7a33\u5b9a\u6027\uff1a\u5f52\u5e76\u6392\u5e8f\u662f\u4e00\u79cd\u7a33\u5b9a\u6392\u5e8f\u7b97\u6cd5\uff0c\u610f\u5473\u7740\u5b83\u5728\u6392\u5e8f\u76f8\u7b49\u5143\u7d20\u65f6\u4f1a\u4fdd\u6301\u5b83\u4eec\u7684\u76f8\u5bf9\u987a\u5e8f\u3002\u8fd9\u4e00\u6027\u8d28\u4f7f\u5f97\u7b97\u6cd5\u5728\u5904\u7406\u76f8\u7b49\u5143\u7d20\u6216\u8005\u5177\u6709\u7279\u5b9a\u6570\u636e\u5206\u5e03\u7684\u60c5\u51b5\u4e0b\u4ecd\u7136\u4fdd\u6301 O(n log n) \u7684\u6027\u80fd\uff0c\u800c\u4e0d\u4f1a\u51fa\u73b0\u6700\u574f\u60c5\u51b5\u3002 \u65e0\u8bba\u8f93\u5165\u6570\u636e\u5982\u4f55\u5206\u5e03\uff0c\u5f52\u5e76\u6392\u5e8f\u7684\u5206\u5272\u548c\u5408\u5e76\u64cd\u4f5c\u90fd\u662f\u786e\u5b9a\u6027\u7684\uff1a\u5f52\u5e76\u6392\u5e8f\u7684\u6bcf\u4e00\u6b65\u90fd\u662f\u786e\u5b9a\u6027\u7684\uff0c\u4e0d\u53d7\u8f93\u5165\u6570\u636e\u5206\u5e03\u7684\u5f71\u54cd\u3002\u4e0d\u50cf\u5feb\u901f\u6392\u5e8f\u5728\u6700\u574f\u60c5\u51b5\u4e0b\u53ef\u80fd\u51fa\u73b0\u5206\u5272\u6781\u4e0d\u5e73\u8861\u7684\u60c5\u51b5\uff0c\u5bfc\u81f4\u6027\u80fd\u4e0b\u964d\u3002 \u56e0\u6b64\uff0c\u5f52\u5e76\u6392\u5e8f\u5728\u6700\u574f\u60c5\u51b5\u4e0b\u4ecd\u7136\u80fd\u591f\u4fdd\u6301 O(n log n) \u7684\u65f6\u95f4\u590d\u6742\u5ea6\uff0c\u4f7f\u5176\u6210\u4e3a\u4e00\u79cd\u53ef\u9760\u7684\u6392\u5e8f\u7b97\u6cd5\uff0c\u7279\u522b\u9002\u7528\u4e8e\u5bf9\u7a33\u5b9a\u6027\u548c\u6027\u80fd\u6709\u8981\u6c42\u7684\u60c5\u51b5\u3002 3.6.\u6307\u6570\u590d\u6742\u5ea6\u7684\u7b97\u6cd5 \u00b6 \u6590\u6ce2\u90a3\u5951\u9012\u5f52\u7b97\u6cd5 \u00b6 \u4e0b\u9762\u662f\u6590\u6ce2\u90a3\u5951\u9012\u5f52\u7b97\u6cd5\u7684\u4f8b\u5b50\u3002 def fib ( n , depth = 0 ): \"\"\"\u6590\u6ce2\u90a3\u5951\u9012\u5f52\u6570\u5217\"\"\" if n <= 1 : return 1 else : print ( f 'Depth: { depth } ,fib( { n } ) calls fib( { n - 1 } ) and fib( { n - 2 } )' ) return fib ( n - 1 , depth + 1 ) + fib ( n - 2 , depth + 1 ) def main (): fib ( 6 ) if __name__ == \"__main__\" : main () # \u8fd0\u884c\u7ed3\u679c\uff1a # Depth:0,fib(6) calls fib(5) and fib(4) # Depth:1,fib(5) calls fib(4) and fib(3) # Depth:2,fib(4) calls fib(3) and fib(2) # Depth:3,fib(3) calls fib(2) and fib(1) # Depth:4,fib(2) calls fib(1) and fib(0) # Depth:3,fib(2) calls fib(1) and fib(0) # Depth:2,fib(3) calls fib(2) and fib(1) # Depth:3,fib(2) calls fib(1) and fib(0) # Depth:1,fib(4) calls fib(3) and fib(2) # Depth:2,fib(3) calls fib(2) and fib(1) # Depth:3,fib(2) calls fib(1) and fib(0) # Depth:2,fib(2) calls fib(1) and fib(0) \u4e0a\u4f8b\u53ef\u4ee5\u770b\u51fa\uff0c\u6590\u6ce2\u90a3\u5951\u9012\u5f52\u7b97\u6cd5\u7684\u8c03\u7528\u6b21\u6570\u6bd4\u95ee\u9898\u89c4\u6a21\u7684\u5e73\u65b9\u6570\u589e\u957f\u7684\u8fd8\u8981\u5feb\u5f88\u591a\u3002\u4f8b\u5982\uff0c fib(4) \u53ea\u9700\u89814\u6b21\u9012\u5f52\u8c03\u7528\uff0c\u770b\u8d77\u6765\u5b83\u597d\u50cf\u662f\u7ebf\u6027\u589e\u957f\u7684\uff0c\u4f46\u5728\u603b\u5171\u768414\u6b21\u9012\u5f52\u8c03\u7528\u91cc\uff0c fib(6) \u9700\u8981\u8c03\u75282\u6b21 fib(4) \u3002\u968f\u7740\u95ee\u9898\u89c4\u6a21\u7684\u6269\u5927\uff0c\u5de5\u4f5c\u91cf\u4f1a\u663e\u8457\u589e\u52a0\uff0c\u8fd9\u662f\u56e0\u4e3a\u5728\u8c03\u7528\u6811\uff08call tree\uff09\u91cc\u53ef\u80fd\u6709\u5f88\u591a\u91cd\u590d\u7684\u76f8\u540c\u5b50\u6811\u3002 \u5982\u679c\u8fd9\u68f5\u8c03\u7528\u6811\u662f\u5b8c\u5168\u5e73\u8861\u7684\uff0c\u5e76\u4e14\u5b8c\u5168\u586b\u5145\u4e86\u6700\u4e0b\u9762\u7684\u4e24\u5c42\u8c03\u7528\uff0c\u90a3\u4e48\u5f53\u53c2\u6570\u4e3a6\u65f6\uff0c\u4f1a\u67092 + 4 + 8 + 16 = 30\u6b21\u9012\u5f52\u8c03\u7528\u3002\u6bcf\u4e00\u5c42\u91cc\u7684\u6ee1\u8c03\u7528\u6570\u91cf\u90fd\u662f\u5b83\u4e0a\u4e00\u5c42\u76842\u500d\u3002\u56e0\u6b64\uff0c\u5728\u5b8c\u5168\u5e73\u8861\u7684\u8c03\u7528\u6811\u91cc\uff0c\u9012\u5f52\u8c03\u7528\u7684\u603b\u6570\u91cf\u901a\u5e38\u662f 2^(n+1)-2 \uff0c\u5176\u4e2d n \u662f\u8c03\u7528\u6811\u9876\u90e8\uff08\u6839\uff09\u7684\u53c2\u6570\u3002\u8fd9\u662f\u4e00\u4e2a\u6307\u6570\u7ea7\u7684\u589e\u957f\uff0c\u4e5f\u5c31\u662f O(k^n) \u7b97\u6cd5\u3002 \u5c3d\u7ba1\u5728\u9012\u5f52\u6590\u6ce2\u90a3\u5951\u8c03\u7528\u6811\u7684\u5e95\u90e8\u4e24\u5c42\u5e76\u6ca1\u6709\u88ab\u5b8c\u5168\u586b\u5145\u6ee1\uff0c\u4f46\u5b83\u7684\u8c03\u7528\u6811\u5f62\u72b6\u548c\u5b8c\u5168\u5e73\u8861\u7684\u6811\u5df2\u7ecf\u8db3\u591f\u76f8\u8fd1\u4e86\uff0c\u56e0\u6b64\uff0c\u53ef\u4ee5\u628a\u9012\u5f52\u6590\u6ce2\u90a3\u5951\u5f52\u4e3a\u6307\u6570\u7b97\u6cd5\u3002\u7ecf\u8fc7\u8ba1\u7b97\uff0c\u9012\u5f52\u6590\u6ce2\u90a3\u5951\u7684\u5e38\u6570 k \u5927\u7ea6\u662f1.63\u3002 \u6307\u6570\u7b97\u6cd5\u901a\u5e38\u53ea\u9002\u5408\u7528\u4e8e\u975e\u5e38\u5c0f\u7684\u95ee\u9898\u89c4\u6a21\u3002 \u5c06\u6590\u6ce2\u90a3\u5951\u8f6c\u6362\u4e3a\u7ebf\u6027\u7b97\u6cd5 \u00b6 \u4e0b\u9762\u7684\u4ee3\u7801\u7528\u7ebf\u6027\u7b97\u6cd5\u6539\u5199\u4e86\u4e0a\u9762\u7684\u9012\u5f52\u7b97\u6cd5\u3002\u5b83\u7684\u65f6\u95f4\u590d\u6742\u5ea6\u662fO(n)\u3002 def fibonacci_linear ( n ): if n <= 1 : return 1 prev , current = 0 , 1 for _ in range ( 2 , n + 1 ): next_value = prev + current prev , current = current , next_value return current def main (): n = 6 result = fibonacci_linear ( n ) print ( f \"Fibonacci( { n } ) = { result } \" ) if __name__ == \"__main__\" : main () # \u8fd0\u884c\u7ed3\u679c\uff1a # Fibonacci(6) = 8 3.7.\u6848\u4f8b\u7814\u7a76:\u7b97\u6cd5\u5206\u6790\u5668 \u00b6 \u76ee\u6807\uff1a\u7f16\u5199\u4e00\u4e2a\u53ef\u4ee5\u7528\u6765\u5206\u6790\u4e0d\u540c\u6392\u5e8f\u7b97\u6cd5\u7684\u7a0b\u5e8f\u3002 \u9700\u6c42\uff1a \u5206\u6790\u5668\u53ef\u4ee5\u8fd0\u884c\u6392\u5e8f\u7b97\u6cd5\u4ee5\u5bf9\u6570\u5b57\u5217\u8868\u8fdb\u884c\u6392\u5e8f\uff1b \u5206\u6790\u5668\u53ef\u4ee5\u8ffd\u8e2a\u7b97\u6cd5\u7684\u8fd0\u884c\u65f6\u3001\u6bd4\u8f83\u6b21\u6570\u4ee5\u53ca\u6267\u884c\u4ea4\u6362\u7684\u6b21\u6570\uff1b \u5f53\u7b97\u6cd5\u4ea4\u6362\u4e24\u4e2a\u503c\u7684\u65f6\u5019\uff0c\u5206\u6790\u5668\u53ef\u4ee5\u6253\u5370\u51fa\u5217\u8868\u7684\u53d8\u5316\u8f68\u8ff9\uff1b \u5141\u8bb8\u7ed9\u5206\u6790\u5668\u63d0\u4f9b\u81ea\u5b9a\u4e49\u7684\u6570\u5b57\u5217\u8868\uff0c\u6216\u8005\u751f\u6210\u4e00\u4e2a\u5927\u5c0f\u7ed9\u5b9a\u7684\u968f\u673a\u6570\u5b57\u5217\u8868\uff1b\u5141\u8bb8\u5217\u8868\u53ea\u5305\u542b\u4e00\u4e2a\u6570\u5b57\uff0c\u6216\u8005\u5305\u542b\u91cd\u590d\u6570\u503c\uff1b \u5728\u8fd0\u884c\u7b97\u6cd5\u4e4b\u524d\uff0c\u5141\u8bb8\u7528\u6237\u9009\u62e9\u4e0a\u8ff0\u8fd9\u4e9b\u529f\u80fd\uff1b \u5206\u6790\u5668\u7684\u9ed8\u8ba4\u884c\u4e3a\u662f\u5728\u4e00\u4e2a\u5305\u542b10\u4e2a\u4e0d\u91cd\u590d\u6570\u5b57\u7684\u968f\u673a\u5217\u8868\u4e0a\u8fd0\u884c\u7b97\u6cd5\uff0c\u5e76\u8bb0\u5f55\u7b97\u6cd5\u7684\u8fd0\u884c\u65f6\u3001\u6bd4\u8f83\u6b21\u6570\u4ee5\u53ca\u4ea4\u6362\u6b21\u6570\uff1b \u5b9e\u73b0\uff1a \u5206\u6790\u5668\u662f Profiler \u7c7b\u7684\u4e00\u4e2a\u5b9e\u4f8b\u3002\u6211\u4eec\u53ef\u4ee5\u901a\u8fc7\u8fd0\u884c\u5206\u6790\u5668\u91cc\u7684 test \u65b9\u6cd5\u6765\u5206\u6790\u6392\u5e8f\u51fd\u6570\uff0c\u8fd9\u4e2a\u6392\u5e8f\u51fd\u6570\u4f1a\u4f5c\u4e3a\u65b9\u6cd5\u7684\u7b2c\u4e00\u4e2a\u53c2\u6570\uff0c\u4e0a\u9762\u9700\u6c42\u4e2d\u63d0\u5230\u7684\u90a3\u4e9b\u9009\u9879\u4e5f\u4f1a\u4f5c\u4e3a\u53c2\u6570\u540c\u65f6\u4f20\u9012\u7ed9\u8fd9\u4e2a\u65b9\u6cd5\u3002 \u4e24\u4e2a\u6a21\u5757\uff1a profiler \uff1a\u8fd9\u4e2a\u6a21\u5757\u4f1a\u5b9a\u4e49 Profiler \u7c7b\u3002 algorithms \uff1a\u8fd9\u4e2a\u6a21\u5757\u5b9a\u4e49\u9488\u5bf9\u5206\u6790\u5668\u4fee\u6539\u8fc7\u7684\u6392\u5e8f\u51fd\u6570\u3002 import time import random class Profiler ( object ): \"\"\" \u5b9a\u4e49\u4e00\u4e2aProfiler\u7c7b, \u7528\u6765\u5206\u6790\u6392\u5e8f\u7b97\u6cd5\u3002 Profiler\u5bf9\u8c61\u8ddf\u8e2a\u4e00\u4e2a\u5217\u8868\u7684\u6bd4\u8f83\u6b21\u6570\u3001\u4ea4\u6362\u6b21\u6570\u3001\u548c\u8fd0\u884c\u65f6\u95f4\u3002 Profiler\u5bf9\u8c61\u4e5f\u80fd\u8f93\u51fa\u4e0a\u8ff0\u8ffd\u8e2a\u4fe1\u606f, \u5e76\u521b\u5efa\u4e00\u4e2a\u542b\u6709\u91cd\u590d\u6216\u4e0d\u91cd\u590d\u6570\u5b57\u7684\u5217\u8868\u3002 \u793a\u4f8b\uff1a from profiler import Profiler from algorithms import selectionSort p = Profiler() p.test(selectionSort, size = 15, comp = True, exch = True, trace = True) \"\"\" def test ( self , function , lyst = None , size = 10 , unique = True , comp = True , exch = True , trace = False ): \"\"\" function: \u914d\u7f6e\u7684\u7b97\u6cd5 target: \u914d\u7f6e\u7684\u641c\u7d22\u76ee\u6807 lyst: \u5141\u8bb8\u8c03\u7528\u8005\u4f7f\u7528\u7684\u5217\u8868 size: \u5217\u8868\u7684\u5927\u5c0f, \u9ed8\u8ba4\u503c\u662f10 unique: \u5982\u679c\u662fTrue, \u5219\u5217\u8868\u5305\u542b\u4e0d\u91cd\u590d\u7684\u6574\u6570 comp: \u5982\u679c\u662fTrue, \u5219\u7edf\u8ba1\u6bd4\u8f83\u6b21\u6570 exch: \u5982\u679c\u662fTrue, \u5219\u7edf\u8ba1\u4ea4\u6362\u6b21\u6570 trace: \u5982\u679c\u662fTrue, \u5219\u5728\u6bcf\u6b21\u4ea4\u6362\u540e\u90fd\u8f93\u51fa\u5217\u8868\u5185\u5bb9 \u6b64\u51fd\u6570\u4f9d\u636e\u7ed9\u5b9a\u7684\u4e0a\u8ff0\u5c5e\u6027, \u6253\u5370\u8f93\u51fa\u76f8\u5e94\u7684\u7ed3\u679c \"\"\" self . comp = comp self . exch = exch self . trace = trace if lyst != None : self . lyst = lyst elif unique : self . lyst = list ( range ( 1 , size + 1 )) random . shuffle ( self . lyst ) else : self . lyst = [] for count in range ( size ): self . lyst . append ( random . randint ( 1 , size )) self . exchCount = 0 self . cmpCount = 0 self . startClock () function ( self . lyst , self ) self . stopClock () print ( self ) def exchange ( self ): \"\"\"\u7edf\u8ba1\u4ea4\u6362\u6b21\u6570\"\"\" if self . exch : self . exchCount += 1 if self . trace : print ( self . lyst ) def comparison ( self ): \"\"\"\u7edf\u8ba1\u4ea4\u6362\u6b21\u6570\"\"\" if self . comp : self . cmpCount += 1 def startClock ( self ): \"\"\"\u8bb0\u5f55\u5f00\u59cb\u65f6\u95f4\"\"\" self . start = time . time () def stopClock ( self ): \"\"\"\u505c\u6b62\u8ba1\u65f6\u5e76\u4ee5\u79d2\u4e3a\u5355\u4f4d\u8ba1\u7b97\u6d88\u8017\u65f6\u95f4\"\"\" self . elapsedTime = round ( time . time () - self . start , 3 ) def __str__ ( self ): \"\"\"\u4ee5\u5b57\u7b26\u4e32\u65b9\u5f0f\u8fd4\u56de\u7ed3\u679c\"\"\" result = \"Problem size: \" result += str ( len ( self . lyst )) + \" \\n \" result += \"Elapsed time: \" result += str ( self . elapsedTime ) + \" \\n \" if self . comp : result += \"Comparisons: \" result += str ( self . cmpCount ) + \" \\n \" if self . exch : result += \"Exchanges: \" result += str ( self . exchCount ) + \" \\n \" return result def selectionSort ( lyst , profiler ): i = 0 while i < len ( lyst ) - 1 : minIndex = i j = i + 1 while j < len ( lyst ): profiler . comparison () # Count if lyst [ j ] < lyst [ minIndex ]: minIndex = j j += 1 if minIndex != i : swap ( lyst , minIndex , i , profiler ) i += 1 def swap ( lyst , i , j , profiler ): \"\"\"\u4ea4\u6362\u5904\u4e8e\u4f4d\u7f6ei\u548cj\u7684\u5143\u7d20\"\"\" profiler . exchange () # Count temp = lyst [ i ] lyst [ i ] = lyst [ j ] lyst [ j ] = temp def main (): p = Profiler () # \u9ed8\u8ba4\u884c\u4e3a print ( \"The result of p.test(selectionSort)\" ) p . test ( selectionSort ) print ( \"The result of p.test(selectionSort, size=5, trace=True)\" ) p . test ( selectionSort , size = 5 , trace = True ) print ( \"The result of p.test(selectionSort, size=100)\" ) p . test ( selectionSort , size = 100 ) print ( \"The result of p.test(selectionSort, size=1000)\" ) p . test ( selectionSort , size = 1000 ) print ( \"The result of p.test(selectionSort, size=10000, exch=False, comp=False)\" ) p . test ( selectionSort , size = 10000 , exch = False , comp = False ) if __name__ == \"__main__\" : main () # \u8fd0\u884c\u7ed3\u679c\uff1a # The result of p.test(selectionSort) # Problem size: 20 # Elapsed time: 0.0 # Comparisons: 190 # Exchanges: 12 # The result of p.test(selectionSort, size=5, trace=True) # [5, 1, 4, 3, 2, 1, 1, 2, 4, 4] # [1, 5, 4, 3, 2, 1, 1, 2, 4, 4] # [1, 1, 4, 3, 2, 5, 1, 2, 4, 4] # [1, 1, 1, 3, 2, 5, 4, 2, 4, 4] # [1, 1, 1, 2, 3, 5, 4, 2, 4, 4] # [1, 1, 1, 2, 2, 5, 4, 3, 4, 4] # [1, 1, 1, 2, 2, 3, 4, 5, 4, 4] # [1, 1, 1, 2, 2, 3, 4, 4, 5, 4] # Problem size: 10 # Elapsed time: 0.0 # Comparisons: 45 # Exchanges: 8 # The result of p.test(selectionSort, size=100) # Problem size: 200 # Elapsed time: 0.003 # Comparisons: 19900 # Exchanges: 195 # The result of p.test(selectionSort, size=1000) # Problem size: 2000 # Elapsed time: 0.36 # Comparisons: 1999000 # Exchanges: 1992 # The result of p.test(selectionSort, size=10000, exch=False, comp=False) # Problem size: 20000 # Elapsed time: 26.535 3.8.\u5c0f\u7ed3 \u00b6 \u6839\u636e\u6240\u9700\u8981\u7684\u65f6\u95f4\u548c\u5185\u5b58\u8d44\u6e90\uff0c\u6211\u4eec\u53ef\u4ee5\u5bf9\u89e3\u51b3\u540c\u4e00\u4e2a\u95ee\u9898\u7684\u4e0d\u540c\u7b97\u6cd5\u8fdb\u884c\u6392\u540d\u3002\u4e0e\u9700\u8981\u66f4\u591a\u8d44\u6e90\u7684\u7b97\u6cd5\u76f8\u6bd4\uff0c\u6211\u4eec\u901a\u5e38\u8ba4\u4e3a\u8017\u8d39\u66f4\u5c11\u8fd0\u884c\u65f6\u548c\u5360\u7528\u66f4\u5c11\u5185\u5b58\u7684\u7b97\u6cd5\u66f4\u597d\u3002\u4f46\u662f\uff0c\u8fd9\u4e24\u79cd\u8d44\u6e90\u4e5f\u901a\u5e38\u9700\u8981\u8fdb\u884c\u6743\u8861\u53d6\u820d\uff1a\u6709\u65f6\u4ee5\u66f4\u591a\u5185\u5b58\u4e3a\u4ee3\u4ef7\u6765\u6539\u5584\u8fd0\u884c\u65f6\uff1b\u6709\u65f6\u4ee5\u8f83\u6162\u7684\u8fd0\u884c\u65f6\u4f5c\u4e3a\u4ee3\u4ef7\u6765\u63d0\u9ad8\u5185\u5b58\u7684\u4f7f\u7528\u7387\u3002 \u53ef\u4ee5\u6839\u636e\u8ba1\u7b97\u673a\u7684\u65f6\u949f\u6309\u7167\u8fc7\u5f80\u7ecf\u9a8c\u6d4b\u7b97\u7b97\u6cd5\u7684\u8fd0\u884c\u65f6\u3002\u4f46\u662f\uff0c\u8fd9\u4e2a\u65f6\u95f4\u4f1a\u968f\u7740\u786c\u4ef6\u548c\u6240\u7528\u7f16\u7a0b\u8bed\u8a00\u7684\u4e0d\u540c\u800c\u53d8\u5316\u3002 \u7edf\u8ba1\u6307\u4ee4\u7684\u6570\u91cf\u63d0\u4f9b\u4e86\u53e6\u4e00\u79cd\u5bf9\u7b97\u6cd5\u6240\u9700\u5de5\u4f5c\u91cf\u8fdb\u884c\u7ecf\u9a8c\u6027\u5ea6\u91cf\u7684\u65b9\u5f0f\u3002\u6307\u4ee4\u7684\u8ba1\u6570\u53ef\u4ee5\u663e\u793a\u51fa\u7b97\u6cd5\u5de5\u4f5c\u91cf\u7684\u589e\u957f\u7387\u7684\u53d8\u5316\uff0c\u800c\u4e14\u8fd9\u4e2a\u6570\u636e\u548c\u786c\u4ef6\u4ee5\u53ca\u8f6f\u4ef6\u5e73\u53f0\u90fd\u6ca1\u6709\u5173\u7cfb\u3002 \u7b97\u6cd5\u5de5\u4f5c\u91cf\u7684\u589e\u957f\u7387\u53ef\u4ee5\u7528\u57fa\u4e8e\u95ee\u9898\u89c4\u6a21\u7684\u51fd\u6570\u6765\u8868\u793a\u3002\u590d\u6742\u5ea6\u5206\u6790\u67e5\u770b\u7b97\u6cd5\u91cc\u7684\u4ee3\u7801\u4ee5\u5f97\u5230\u8fd9\u4e9b\u6570\u5b66\u8868\u8fbe\u5f0f\uff0c\u4ece\u800c\u8ba9\u7a0b\u5e8f\u5458\u9884\u6d4b\u5728\u4efb\u4f55\u8ba1\u7b97\u673a\u4e0a\u6267\u884c\u8fd9\u4e2a\u7b97\u6cd5\u7684\u6548\u679c\u3002 \u5927O\u8868\u793a\u6cd5\u662f\u7528\u6765\u8868\u793a\u7b97\u6cd5\u8fd0\u884c\u65f6\u884c\u4e3a\u7684\u5e38\u7528\u65b9\u6cd5\u3002\u5b83\u7528 O(f(n)) \u7684\u5f62\u5f0f\u6765\u8868\u793a\u89e3\u51b3\u8fd9\u4e2a\u95ee\u9898\u6240\u9700\u8981\u7684\u5de5\u4f5c\u91cf\uff0c\u5176\u4e2d n \u662f\u7b97\u6cd5\u95ee\u9898\u7684\u89c4\u6a21\u3001 f(n) \u662f\u6570\u5b66\u51fd\u6570\u3002 \u8fd0\u884c\u65f6\u884c\u4e3a\u7684\u5e38\u89c1\u8868\u8fbe\u5f0f\u6709 O(log(n, 2)) \uff08\u5bf9\u6570\uff09\u3001 O(n) \uff08\u7ebf\u6027\uff09\u3001 O(n^2) \uff08\u5e73\u65b9\uff09\u4ee5\u53ca O(k^n) \uff08\u6307\u6570\uff09\u3002 \u7b97\u6cd5\u5728\u6700\u597d\u60c5\u51b5\u3001\u6700\u574f\u60c5\u51b5\u4ee5\u53ca\u5e73\u5747\u60c5\u51b5\u4e0b\u7684\u6027\u80fd\u53ef\u4ee5\u662f\u4e0d\u540c\u7684\u3002\u6bd4\u5982\uff0c\u5192\u6ce1\u6392\u5e8f\u548c\u63d2\u5165\u6392\u5e8f\u5728\u6700\u597d\u60c5\u51b5\u4e0b\u90fd\u662f\u7ebf\u6027\u590d\u6742\u5ea6\uff0c\u4f46\u662f\u5b83\u4eec\u5728\u5e73\u5747\u60c5\u51b5\u548c\u6700\u574f\u60c5\u51b5\u4e0b\u662f\u5e73\u65b9\u9636\u590d\u6742\u5ea6\u3002 \u901a\u5e38\u6765\u8bf4\uff0c\u8981\u63d0\u9ad8\u7b97\u6cd5\u7684\u6027\u80fd\u6700\u597d\u662f\u5c1d\u8bd5\u964d\u4f4e\u5b83\u7684\u8fd0\u884c\u65f6\u590d\u6742\u5ea6\u7684\u9636\u6570\uff0c\u800c\u4e0d\u662f\u5bf9\u4ee3\u7801\u8fdb\u884c\u5fae\u8c03\u3002 \u4e8c\u5206\u641c\u7d22\u4f1a\u6bd4\u987a\u5e8f\u641c\u7d22\u8981\u5feb\u5f97\u591a\u3002\u4f46\u662f\uff0c\u5728\u7528\u4e8c\u5206\u641c\u7d22\u8fdb\u884c\u641c\u7d22\u65f6\uff0c\u6570\u636e\u5fc5\u987b\u662f\u6709\u5e8f\u7684\u3002 nlogn \u6392\u5e8f\u7b97\u6cd5\u901a\u8fc7\u9012\u5f52\u3001\u5206\u6cbb\u6cd5\u7b56\u7565\u6765\u7a81\u7834 n^2 \u7684\u6027\u80fd\u969c\u788d\u3002\u5feb\u901f\u6392\u5e8f\u4f1a\u5728\u57fa\u51c6\u5143\u7d20\u5de6\u53f3\u5bf9\u5176\u4ed6\u5143\u7d20\u91cd\u65b0\u6392\u5217\uff0c\u7136\u540e\u5bf9\u57fa\u51c6\u4e24\u4fa7\u7684\u5b50\u5217\u8868\u9012\u5f52\u5730\u6392\u5e8f\u3002\u5f52\u5e76\u6392\u5e8f\u5219\u4f1a\u628a\u4e00\u4e2a\u5217\u8868\u8fdb\u884c\u62c6\u5206\uff0c\u9012\u5f52\u5730\u5bf9\u6bcf\u4e2a\u90e8\u5206\u8fdb\u884c\u6392\u5e8f\uff0c\u7136\u540e\u5408\u5e76\u51fa\u6700\u7ec8\u7ed3\u679c\u3002 \u6307\u6570\u590d\u6742\u5ea6\u7684\u7b97\u6cd5\u901a\u5e38\u53ea\u5728\u7406\u8bba\u4e0a\u88ab\u5173\u6ce8\uff0c\u5728\u5904\u7406\u5927\u578b\u95ee\u9898\u7684\u65f6\u5019\uff0c\u5b83\u4eec\u662f\u6ca1\u6709\u4f7f\u7528\u4ef7\u503c\u7684\u3002 3.9.\u590d\u4e60\u9898 \u00b6 \u5728\u4e0d\u540c\u95ee\u9898\u89c4\u6a21\u7684\u60c5\u51b5\u4e0b\u8bb0\u5f55\u7b97\u6cd5\u8fd0\u884c\u65f6\uff1a \u53ef\u4ee5\u8ba9\u4f60\u5927\u81f4\u4e86\u89e3\u7b97\u6cd5\u7684\u8fd0\u884c\u65f6\u884c\u4e3a \u53ef\u4ee5\u8ba9\u4f60\u4e86\u89e3\u7b97\u6cd5\u5728\u7279\u5b9a\u786c\u4ef6\u5e73\u53f0\u548c\u7279\u5b9a\u8f6f\u4ef6\u5e73\u53f0\u4e0a\u7684\u8fd0\u884c\u65f6\u884c\u4e3a \u7edf\u8ba1\u6307\u4ee4\u7684\u6570\u91cf\u4f1a\uff1a \u5728\u4e0d\u540c\u7684\u786c\u4ef6\u548c\u8f6f\u4ef6\u5e73\u53f0\u4e0a\u5f97\u5230\u76f8\u540c\u7684\u6570\u636e \u53ef\u4ee5\u8bc1\u660e\u5728\u95ee\u9898\u89c4\u6a21\u5f88\u5927\u7684\u60c5\u51b5\u4e0b\uff0c\u6307\u6570\u7b97\u6cd5\u662f\u6ca1\u6cd5\u4f7f\u7528\u7684 \u8868\u8fbe\u5f0f O(n) \u3001 O(n^2) \u548c O(k^n) \u5206\u522b\u4ee3\u8868\u7684\u590d\u6742\u5ea6\u662f\uff1a \u6307\u6570\u3001\u7ebf\u6027\u548c\u5e73\u65b9 \u7ebf\u6027\u3001\u5e73\u65b9\u548c\u6307\u6570 \u5bf9\u6570\u3001\u7ebf\u6027\u548c\u5e73\u65b9 \u4e8c\u5206\u641c\u7d22\u9700\u8981\u5047\u5b9a\u6570\u636e\uff1a \u6ca1\u6709\u4efb\u4f55\u7279\u522b\u7684\u987a\u5e8f\u5173\u7cfb \u6709\u5e8f\u7684 \u9009\u62e9\u6392\u5e8f\u6700\u591a\u53ef\u4ee5\u6709\uff1a n^2 \u6b21\u6570\u636e\u5143\u7d20\u7684\u4ea4\u6362 n \u6b21\u6570\u636e\u5143\u7d20\u7684\u4ea4\u6362 \u63d2\u5165\u6392\u5e8f\u548c\u4fee\u6539\u540e\u7684\u5192\u6ce1\u6392\u5e8f\u5728\u6700\u597d\u60c5\u51b5\u4e0b\u662f\uff1a \u7ebf\u6027\u7684 \u5e73\u65b9\u7684 \u6307\u6570\u7684 \u6700\u597d\u60c5\u51b5\u3001\u5e73\u5747\u60c5\u51b5\u4ee5\u53ca\u6700\u574f\u60c5\u51b5\u4e0b\u590d\u6742\u5ea6\u90fd\u76f8\u540c\u7684\u7b97\u6cd5\u662f\uff1a \u987a\u5e8f\u641c\u7d22 \u9009\u62e9\u6392\u5e8f \u5feb\u901f\u6392\u5e8f \u4e00\u822c\u6765\u8bf4\uff0c\u4e0b\u9762\u54ea\u4e2a\u9009\u62e9\u66f4\u597d\uff1a \u8c03\u6574\u7b97\u6cd5\u4ece\u800c\u8282\u7701\u82e5\u5e72\u79d2\u7684\u8fd0\u884c\u65f6 \u9009\u62e9\u8ba1\u7b97\u590d\u6742\u5ea6\u66f4\u4f4e\u7684\u7b97\u6cd5 \u5bf9\u4e8e\u9012\u5f52\u6590\u6ce2\u90a3\u5951\u51fd\u6570\uff1a \u95ee\u9898\u89c4\u6a21\u4e3a n \u7684\u65f6\u5019\uff0c\u6709 n^2 \u6b21\u9012\u5f52\u8c03\u7528 \u95ee\u9898\u89c4\u6a21\u4e3a n \u7684\u65f6\u5019\uff0c\u6709 2n \u6b21\u9012\u5f52\u8c03\u7528 \u5b8c\u5168\u586b\u5145\u7684\u4e8c\u53c9\u8c03\u7528\u6811\u91cc\u6bcf\u4e00\u5c42\uff1a \u8c03\u7528\u6b21\u6570\u662f\u4e0a\u4e00\u5c42\u8c03\u7528\u6b21\u6570\u76842\u500d \u4e0e\u4e0a\u4e00\u5c42\u76f8\u540c\u7684\u8c03\u7528\u6b21\u6570 3.10.\u7f16\u7a0b\u7ec3\u4e60 \u00b6 1\uff0e\u5bf9\u4e00\u4e2a\u6709\u5e8f\u5217\u8868\u8fdb\u884c\u987a\u5e8f\u641c\u7d22\uff0c\u5f53\u76ee\u6807\u5c0f\u4e8e\u6709\u5e8f\u5217\u8868\u91cc\u7684\u67d0\u4e2a\u5143\u7d20\u65f6\uff0c\u987a\u5e8f\u641c\u7d22\u53ef\u4ee5\u63d0\u524d\u505c\u6b62\u3002\u5b9a\u4e49\u8fd9\u4e2a\u7b97\u6cd5\u7684\u4fee\u6539\u7248\u672c\uff0c\u5e76\u4f7f\u7528\u5927O\u8868\u793a\u6cd5\u6765\u63cf\u8ff0\u5b83\u5728\u6700\u597d\u60c5\u51b5\u3001\u6700\u574f\u60c5\u51b5\u4ee5\u53ca\u5e73\u5747\u60c5\u51b5\u4e0b\u7684\u8ba1\u7b97\u590d\u6742\u5ea6\u3002 \u89e3\u7b54\uff1a \u5728\u6700\u597d\u7684\u60c5\u51b5\u4e0b\uff0c\u76ee\u6807\u5143\u7d20\u5728\u6709\u5e8f\u5217\u8868\u7684\u7b2c\u4e00\u4e2a\u4f4d\u7f6e\u3002\u5728\u8fd9\u79cd\u60c5\u51b5\u4e0b\uff0c\u51fd\u6570\u53ea\u9700\u8981\u8fdb\u884c\u4e00\u6b21\u6bd4\u8f83\u3002\u6240\u4ee5\uff0c\u6700\u4f73\u60c5\u51b5\u590d\u6742\u5ea6\u4e3a O(1) \u3002 \u5728\u6700\u574f\u7684\u60c5\u51b5\u4e0b\uff0c\u76ee\u6807\u5143\u7d20\u4e0d\u5728\u5217\u8868\u4e2d\uff0c\u5e76\u4e14\u6240\u6709\u5217\u8868\u5143\u7d20\u90fd\u5c0f\u4e8e\u76ee\u6807\u5143\u7d20\u3002\u8fd9\u5c06\u5bfc\u81f4\u51fd\u6570\u904d\u5386\u6574\u4e2a\u5217\u8868\uff0c\u6240\u4ee5\u6700\u574f\u60c5\u51b5\u590d\u6742\u5ea6\u4e3a O(n) \u3002 \u5bf9\u4e8e\u5e73\u5747\u60c5\u51b5\uff0c\u5047\u8bbe\u6709 n \u4e2a\u9879\u5728\u5217\u8868\u4e2d\uff0c\u641c\u7d22\u76ee\u6807\u4f1a\u5728\u5217\u8868\u524d n/2 \u4e2a\u9879\u6216\u8005\u4e0d\u5728\u6240\u6709\u3002\u5728\u8fd9\u4e2a\u7ea6\u5b9a\u4e0b\uff0c\u5e73\u5747\u6211\u4eec\u9700\u8981\u5bfb\u627e n/2 \u4e2a\u9879\uff0c\u56e0\u6b64\u590d\u6742\u5ea6\u4e3a O(n) \u3002\u4e4b\u6240\u4ee5\u662f n/2 \uff0c\u662f\u56e0\u4e3a\u8fd9\u4e2a\u4efb\u52a1\u53ef\u80fd\u4f1a\u5728\u4efb\u4f55\u5730\u65b9\u88ab\u505c\u6b62\uff0c\u6211\u4eec\u5bf9\u6b64\u505a\u5e73\u5747\u5904\u7406\u3002\u7136\u800c\u5728\u5927O\u6807\u8bb0\u6cd5\u4e2d\uff0c\u5e38\u6570\u5c06\u88ab\u9057\u5fd8\uff0c\u6240\u4ee5\u5b83\u4ecd\u7136\u662f O(n) \u3002 \u4ee3\u7801\u5982\u4e0b\uff1a def ordered_sequential_search ( arr , target ): comparisons = 0 # \u7528\u4e8e\u7edf\u8ba1\u6bd4\u8f83\u6b21\u6570 index = 0 while index < len ( arr ): comparisons += 1 if arr [ index ] == target : return comparisons , index # \u627e\u5230\u76ee\u6807\u5e76\u8fd4\u56de\u6bd4\u8f83\u6b21\u6570\u548c\u7d22\u5f15 elif arr [ index ] > target : break # \u5982\u679c\u76ee\u6807\u5c0f\u4e8e\u5f53\u524d\u5143\u7d20\uff0c\u63d0\u524d\u505c\u6b62\u641c\u7d22 index += 1 return comparisons , - 1 # \u6ca1\u627e\u5230\u76ee\u6807\u8fd4\u56de\u6bd4\u8f83\u6b21\u6570\u548c-1 def main (): # \u6d4b\u8bd5 arr = [ 1 , 2 , 3 , 4 , 5 , 6 , 7 , 8 , 9 , 10 ] for target in [ 5 , 11 ]: comparisons , index = ordered_sequential_search ( arr , target ) if index != - 1 : print ( f \"\u76ee\u6807 { target } \u5728\u7d22\u5f15 { index } \u5904\u627e\u5230\uff0c\u6bd4\u8f83\u6b21\u6570\u4e3a { comparisons } \" ) else : print ( f \"\u76ee\u6807 { target } \u672a\u627e\u5230\uff0c\u6bd4\u8f83\u6b21\u6570\u4e3a { comparisons } \" ) if __name__ == \"__main__\" : main () # \u8fd0\u884c\u7ed3\u679c # \u76ee\u6807 5 \u5728\u7d22\u5f15 4 \u5904\u627e\u5230\uff0c\u6bd4\u8f83\u6b21\u6570\u4e3a 5 # \u76ee\u6807 11 \u672a\u627e\u5230\uff0c\u6bd4\u8f83\u6b21\u6570\u4e3a 10 2\uff0e\u5217\u8868\u7684 reverse \u65b9\u6cd5\u7528\u6765\u53cd\u8f6c\u5217\u8868\u91cc\u7684\u5143\u7d20\u3002\u5b9a\u4e49\u4e00\u4e2a\u53eb\u4f5c reverse \u7684\u51fd\u6570\uff0c\u8fd9\u4e2a\u51fd\u6570\u53ef\u4ee5\u5728\u4e0d\u4f7f\u7528 reverse \u65b9\u6cd5\u7684\u60c5\u51b5\u4e0b\uff0c\u53cd\u8f6c\u5217\u8868\u53c2\u6570\u91cc\u7684\u6240\u6709\u5143\u7d20\u3002\u5c1d\u8bd5\u8ba9\u8fd9\u4e2a\u51fd\u6570\u5c3d\u53ef\u80fd\u5730\u9ad8\u6548\uff0c\u5e76\u4f7f\u7528\u5927O\u8868\u793a\u6cd5\u63cf\u8ff0\u5b83\u7684\u8ba1\u7b97\u590d\u6742\u5ea6\u3002 \u89e3\u7b54\uff1a \u53ea\u9700\u8981\u904d\u5386\u5217\u8868\u7684\u4e00\u534a\uff0c\u6211\u4eec\u5c31\u80fd\u5230\u8fbe\u5217\u8868\u7684\u4e2d\u95f4\u4f4d\u7f6e\u628a\u5217\u8868\u4e24\u8fb9\u7684\u5143\u7d20\u4e92\u6362\uff0c\u8fd9\u6837\u5c31\u5b8c\u6210\u4e86\u5217\u8868\u7684\u53cd\u8f6c\u3002 \u8fd9\u4e2a\u7b97\u6cd5\u7684\u65f6\u95f4\u590d\u6742\u5ea6\u662f O(n/2) \uff0c\u5176\u4e2d n \u662f\u5217\u8868\u7684\u957f\u5ea6\u3002\u4f46\u5728\u5927O\u8868\u793a\u6cd5\u4e2d\uff0c\u5e38\u6570\u88ab\u5ffd\u7565\uff0c\u56e0\u6b64\u8be5\u7b97\u6cd5\u7684\u65f6\u95f4\u590d\u6742\u5ea6\u662f O(n) \u3002\u5728\u8fd9\u4e2a\u7b97\u6cd5\u4e2d\uff0c n \u5c31\u4ee3\u8868\u7740\u5217\u8868\u7684\u957f\u5ea6\u3002\u610f\u5473\u7740\u65f6\u95f4\u590d\u6742\u5ea6\u53d7\u5217\u8868\u957f\u5ea6\u7684\u5f71\u54cd\u3002\u5217\u8868\u957f\u5ea6\u6bcf\u589e\u52a0\u4e00\u6b21\uff0c\u6267\u884c\u53cd\u8f6c\u7684\u65f6\u95f4\u5c31\u589e\u52a0\u4e00\u6b21\u3002\u8fd9\u5c31\u662f O(n) \u7684\u6982\u5ff5\u3002 \u8fd9\u4e2a\u51fd\u6570\u7684\u7a7a\u95f4\u590d\u6742\u5ea6\u662f O(1) \uff0c\u56e0\u4e3a\u5b83\u53ea\u662f\u5728\u539f\u5730\u4fee\u6539\u5217\u8868\uff0c\u4e0d\u9700\u8981\u989d\u5916\u7684\u5b58\u50a8\u7a7a\u95f4\u3002 \u4ee3\u7801\u5982\u4e0b\uff1a def custom_reverse ( arr ): left , right = 0 , len ( arr ) - 1 while left < right : arr [ left ], arr [ right ] = arr [ right ], arr [ left ] left += 1 right -= 1 def main (): # \u6d4b\u8bd5\u5217\u8868reverse\u65b9\u6cd5 my_list = [ 1 , 2 , 3 , 4 , 5 ] my_list . reverse () print ( my_list ) # \u6d4b\u8bd5\u81ea\u5b9a\u4e49\u7684reverse\u65b9\u6cd5 my_list = [ 1 , 2 , 3 , 4 , 5 ] custom_reverse ( my_list ) print ( my_list ) if __name__ == \"__main__\" : main () # \u8fd0\u884c\u7ed3\u679c # [5, 4, 3, 2, 1] # [5, 4, 3, 2, 1] 3\uff0ePython\u7684pow\u51fd\u6570\u4f1a\u8fd4\u56de\u6570\u5b57\u7279\u5b9a\u5e42\u6b21\u7684\u7ed3\u679c\u3002\u5b9a\u4e49\u6267\u884c\u8fd9\u4e2a\u4efb\u52a1\u7684expo\u51fd\u6570\uff0c\u5e76\u4f7f\u7528\u5927O\u8868\u793a\u6cd5\u63cf\u8ff0\u5b83\u7684\u8ba1\u7b97\u590d\u6742\u5ea6\u3002\u8fd9\u4e2a\u51fd\u6570\u7684\u7b2c\u4e00\u4e2a\u53c2\u6570\u662f\u6570\u5b57\uff0c\u7b2c\u4e8c\u4e2a\u53c2\u6570\u662f\u6307\u6570\uff08\u975e\u8d1f\u6570\uff09\u3002\u4f60\u53ef\u4ee5\u901a\u8fc7\u5faa\u73af\u6216\u9012\u5f52\u51fd\u6570\u6765\u5b9e\u73b0\uff0c\u4f46\u4e0d\u8981\u4f7f\u7528Python\u5185\u7f6e\u7684**\u8fd0\u7b97\u7b26\u6216\u662fpow\u51fd\u6570\u3002 \u89e3\u7b54\uff1a \u4e0b\u9762\u5b9e\u73b0\u7684 expo \u51fd\u6570\u4f7f\u7528\u5faa\u73af\u6765\u8fde\u7eed\u4e58\u4ee5 base \uff0c\u5faa\u73af\u7684\u6b21\u6570\u7b49\u4e8e exponent \u7684\u503c\u3002 \u65f6\u95f4\u590d\u6742\u5ea6\u662f O(exponent) \uff0c\u5176\u4e2d exponent \u662f\u6307\u6570\u7684\u503c\u3002 \u6700\u597d\u60c5\u51b5\uff1aO(exponent) \u6700\u574f\u60c5\u51b5\uff1aO(exponent) \u5e73\u5747\u60c5\u51b5\uff1aO(exponent) def expo ( base , exponent ): result = 1 for _ in range ( exponent ): result *= base return result def main (): # \u6d4b\u8bd5 base = 2 for exponent in [ 3 , - 3 ]: result = expo ( base , exponent ) print ( f \" { base } \u7684 { exponent } \u6b21\u65b9\u7b49\u4e8e { result } \" ) if __name__ == \"__main__\" : main () # \u8fd0\u884c\u7ed3\u679c # 2 \u7684 3 \u6b21\u65b9\u7b49\u4e8e 8 # 2 \u7684 -3 \u6b21\u65b9\u7b49\u4e8e 1 4\uff0e\u53e6\u4e00\u4e2a\u5b9e\u73b0 expo \u51fd\u6570\u7684\u7b56\u7565\u4f7f\u7528\u4e0b\u9762\u8fd9\u4e2a\u9012\u5f52\u3002\u8bf7\u5b9a\u4e49\u4f7f\u7528\u8fd9\u4e2a\u7b56\u7565\u7684\u9012\u5f52\u51fd\u6570 expo \uff0c\u5e76\u4f7f\u7528\u5927O\u8868\u793a\u6cd5\u63cf\u8ff0\u5b83\u7684\u8ba1\u7b97\u590d\u6742\u5ea6\u3002 expo ( number \uff0c exponent ) = 1 \uff0c \u5f53 exponent = 0 \u7684\u65f6\u5019 = number * expo ( number , exponent \u2212 1 ) \uff0c \u5f53exponent\u4e3a\u5947\u6570\u7684\u65f6\u5019 = ( expo ( number , exponent / 2 )) 2 \uff0c \u5f53exponent\u4e3a\u5076\u6570\u7684\u65f6\u5019 \u89e3\u7b54\uff1a \u4e0b\u9762\u5b9e\u73b0expo\u51fd\u6570\u662f\u901a\u8fc7\u9012\u5f52\u5b9e\u73b0\uff0c\u5e76\u91c7\u7528\u4e86\u5206\u800c\u6cbb\u4e4b\u7684\u7b56\u7565\u3002 \u5982\u679c\u6307\u6570\u662f\u5947\u6570\uff0c\u5c31\u628a\u95ee\u9898\u5206\u89e3\u4e3a\u4e00\u4e2a\u66f4\u5c0f\u7684\u7248\u672c\uff08\u5373 num * num^(exp - 1) \uff09\uff1b \u5982\u679c\u6307\u6570\u662f\u5076\u6570\uff0c\u5219\u53ef\u4ee5\u5c06\u6307\u6570\u5206\u6210\u4e24\u534a\uff0c\u5e76\u53ea\u8ba1\u7b97\u5176\u4e2d\u7684\u4e00\u534a\uff08\u5373 num^(exp / 2) * num^(exp / 2) \uff09\u3002 \u8fd9\u5c31\u5229\u7528\u4e86\u5e42\u7684\u6027\u8d28 a^(m * n) = (a^m)^n \u3002 \u8be5\u9012\u5f52\u5b9e\u73b0\u7684\u65f6\u95f4\u590d\u6742\u5ea6\u4e3a O(log n) \uff0c\u5176\u4e2dn\u4e3a\u6307\u6570\u3002\u8fd9\u662f\u56e0\u4e3a\u5728\u6307\u6570\u4e3a\u5076\u6570\u7684\u60c5\u51b5\u4e0b\uff0c\u6bcf\u6b21\u9012\u5f52\u8c03\u7528\u90fd\u4f1a\u628a\u95ee\u9898\u89c4\u6a21\u7f29\u5c0f\u4e00\u534a\uff0c\u7c7b\u4f3c\u4e8e\u4e8c\u5206\u67e5\u627e\u7b49\u8bfe\u5206\u5272\u95ee\u9898\u3002 \u7a7a\u95f4\u590d\u6742\u5ea6\u4e5f\u662f O(log n) \uff0c\u8fd9\u4e3b\u8981\u662f\u7531\u4e8e\u51fd\u6570\u8c03\u7528\u6808\u7684\u6df1\u5ea6\u5728\u6307\u6570\u4e3a\u5076\u6570\u7684\u60c5\u51b5\u4e0b\uff0c\u4f1a\u53d8\u4e3a\u539f\u6765\u7684\u4e00\u534a\u3002 def expo ( number , exponent ): if exponent <= 0 : return 1 elif exponent % 2 == 1 : # \u5f53 exponent \u4e3a\u5947\u6570 return number * expo ( number , exponent - 1 ) else : # \u5f53 exponent \u4e3a\u5076\u6570 half_expo = expo ( number , exponent // 2 ) return half_expo * half_expo def main (): # \u6d4b\u8bd5 base = 2 for exponent in [ 3 , - 3 ]: result = expo ( base , exponent ) print ( f \" { base } \u7684 { exponent } \u6b21\u65b9\u7b49\u4e8e { result } \" ) if __name__ == \"__main__\" : main () # \u8fd0\u884c\u7ed3\u679c # 2 \u7684 3 \u6b21\u65b9\u7b49\u4e8e 8 # 2 \u7684 -3 \u6b21\u65b9\u7b49\u4e8e 1 5\uff0ePython\u4e2dlist\u91cc\u7684sort\u65b9\u6cd5\u5305\u542b\u4e00\u4e2a\u7528\u5173\u952e\u5b57\u547d\u540d\u7684\u53c2\u6570reverse\uff0c\u5b83\u7684\u9ed8\u8ba4\u503c\u4e3aFalse\u3002\u7a0b\u5e8f\u5458\u53ef\u4ee5\u901a\u8fc7\u8986\u76d6\u8fd9\u4e2a\u503c\u4ee5\u5bf9\u5217\u8868\u8fdb\u884c\u964d\u5e8f\u6392\u5e8f\u3002\u4fee\u6539\u672c\u7ae0\u8ba8\u8bba\u7684selectionSort\u51fd\u6570\uff0c\u4f7f\u5b83\u53ef\u4ee5\u63d0\u4f9b\u8fd9\u4e2a\u9644\u52a0\u53c2\u6570\u6765\u8ba9\u7a0b\u5e8f\u5458\u51b3\u5b9a\u6392\u5e8f\u7684\u65b9\u5411\u3002 \u89e3\u7b54\uff1a \u901a\u8fc7\u6dfb\u52a0\u4e00\u4e2a\u540d\u4e3a reverse \u7684\u53c2\u6570\u6765\u4fee\u6539 selectionSort \u51fd\u6570\uff0c\u4ee5\u4fbf\u8ba9\u7a0b\u5e8f\u5458\u51b3\u5b9a\u6392\u5e8f\u7684\u65b9\u5411\u3002\u5982\u679c reverse \u4e3a True \uff0c\u6392\u5e8f\u5c06\u662f\u964d\u5e8f\u7684\uff0c\u5982\u679c\u4e3a False \uff08\u9ed8\u8ba4\u503c\uff09\uff0c\u6392\u5e8f\u5c06\u662f\u5347\u5e8f\u7684\u3002 \u4e0b\u9762\u662f\u4fee\u6539\u540e\u7684 selectionSort \u51fd\u6570\uff1a def swap ( lyst , i , j ): \"\"\"\u4ea4\u6362\u5143\u7d20\u4f4d\u7f6e\u4e3ai\u548cj\u7684\u5143\u7d20\"\"\" temp = lyst [ i ] lyst [ i ] = lyst [ j ] lyst [ j ] = temp def selectionSort ( lyst , reverse = False ): \"\"\"\u5b9e\u73b0\u4ea4\u6362\u6392\u5e8f\u7b97\u6cd5\uff0c\u53ef\u4ee5\u9009\u62e9\u5347\u5e8f\u6216\u964d\u5e8f\u6392\u5e8f\"\"\" i = 0 while i < len ( lyst ) - 1 : # \u5b9e\u73b0n-1\u6b21\u641c\u7d22 index = i # \u6700\u5c0f\u6216\u6700\u5927\u5143\u7d20\u4f4d\u7f6e j = i + 1 while j < len ( lyst ): # \u5411\u540e\u904d\u5386\u641c\u7d22\uff0c\u66f4\u65b0\u6700\u5c0f\u6216\u6700\u5927\u5143\u7d20\u4f4d\u7f6e if not reverse : if ( lyst [ j ] < lyst [ index ]): index = j else : if ( lyst [ j ] > lyst [ index ]): index = j j += 1 if index != i : # \u5982\u679c\u9700\u8981\uff0c\u5219\u4ea4\u6362\u5143\u7d20\u4f4d\u7f6e swap ( lyst , index , i ) i += 1 def main (): myList = [ 9 , 4 , 2 , 7 , 6 , 8 , 1 ] print ( \"Before selection sort \" , myList ) selectionSort ( myList ) print ( \"After selection sort \" , myList ) if __name__ == \"__main__\" : main () # \u8fd0\u884c\u7ed3\u679c\uff1a # Before selection sort [9, 4, 2, 7, 6, 8, 1] # After selection sort [1, 2, 4, 6, 7, 8, 9] 6\uff0e\u4fee\u6539\u9012\u5f52\u6590\u6ce2\u90a3\u5951\u51fd\u6570\uff0c\u8ba9\u5b83\u652f\u6301\u672c\u7ae0\u91cc\u8ba8\u8bba\u8fc7\u7684\u8bb0\u5fc6\u5316\u6280\u672f\u3002\u8fd9\u4e2a\u51fd\u6570\u5e94\u6dfb\u52a0\u4e00\u4e2a\u5b57\u5178\u7c7b\u578b\u7684\u53c2\u6570\u3002\u5b83\u7684\u9876\u5c42\u8c03\u7528\u4f1a\u63a5\u6536\u4e00\u4e2a\u7a7a\u5b57\u5178\u4f5c\u4e3a\u53c2\u6570\uff0c\u8fd9\u4e2a\u5b57\u5178\u7684\u952e\u548c\u503c\u5e94\u8be5\u662f\u9012\u5f52\u8c03\u7528\u6240\u4f20\u9012\u7684\u53c2\u6570\u548c\u8ba1\u7b97\u51fa\u7684\u503c\u3002\u4e4b\u540e\uff0c\u7528\u672c\u7ae0\u8ba8\u8bba\u8fc7\u7684\u8ba1\u6570\u5668\u5bf9\u8c61\u5bf9\u9012\u5f52\u8c03\u7528\u7684\u6570\u91cf\u8fdb\u884c\u7edf\u8ba1\u3002 \u89e3\u7b54\uff1a \u4e0b\u9762\u662f\u4e00\u4e2a\u4fee\u6539\u540e\u7684\u7248\u672c\uff0c\u5b83\u4f7f\u7528\u4e00\u4e2a\u5b57\u5178\uff08\u7f13\u5b58\uff09\u6765\u5b58\u50a8\u5df2\u8ba1\u7b97\u7684\u7ed3\u679c\uff0c\u5e76\u4e14\u6dfb\u52a0\u4e86\u4e00\u4e2a\u8ba1\u6570\u5668\u5bf9\u8c61\u6765\u7edf\u8ba1\u9012\u5f52\u8c03\u7528\u6b21\u6570\u3002\u8fd9\u4e2a\u4ee3\u7801\u4f1a\u8f93\u51fa\u6307\u5b9a\u9879\u6570\u7684\u6590\u6ce2\u90a3\u5951\u6570\u4ee5\u53ca\u9012\u5f52\u8c03\u7528\u7684\u603b\u6b21\u6570\u3002\u8bb0\u5fc6\u5316\u6280\u672f\u53ef\u4ee5\u663e\u8457\u63d0\u9ad8\u6590\u6ce2\u90a3\u5951\u51fd\u6570\u7684\u6027\u80fd\uff0c\u907f\u514d\u4e86\u91cd\u590d\u8ba1\u7b97\u3002 class Counter : def __init__ ( self ): self . count = 0 def increment ( self ): self . count += 1 def fib ( n , cache , counter ): \"\"\"\u6590\u6ce2\u90a3\u5951\u9012\u5f52\u6570\u5217\uff0c\u5e26\u6709\u8bb0\u5fc6\u5316\u548c\u8c03\u7528\u8ba1\u6570\u5668\"\"\" if n in cache : return cache [ n ] counter . increment () if n <= 1 : result = 1 else : result = fib ( n - 1 , cache , counter ) + fib ( n - 2 , cache , counter ) cache [ n ] = result return result def main (): n = 10 # \u4f60\u53ef\u4ee5\u8bbe\u7f6e\u4e0d\u540c\u7684\u6590\u6ce2\u90a3\u5951\u6570\u5217\u9879\u6570 cache = {} # \u7528\u4e8e\u7f13\u5b58\u5df2\u8ba1\u7b97\u7ed3\u679c\u7684\u5b57\u5178 counter = Counter () # \u7528\u4e8e\u8ba1\u6570\u9012\u5f52\u8c03\u7528\u6b21\u6570\u7684\u8ba1\u6570\u5668\u5bf9\u8c61 result = fib ( n , cache , counter ) print ( f \"Fibonacci( { n } ) = { result } \" ) print ( f \"Total recursive calls: { counter . count } \" ) if __name__ == \"__main__\" : main () # \u8fd0\u884c\u7ed3\u679c\uff1a # Fibonacci(10) = 89 # Total recursive calls: 11 7\uff0e\u5206\u6790\u4e0a\u9762\u6590\u6ce2\u90a3\u5951\u6570\u5217\u91cc\u5b9a\u4e49\u7684\u8bb0\u5fc6\u5316\u6590\u6ce2\u90a3\u5951\u51fd\u6570\u7684\u6027\u80fd\uff0c\u7edf\u8ba1\u8fd9\u4e2a\u51fd\u6570\u9012\u5f52\u8c03\u7528\u7684\u6b21\u6570\u3002\u4f7f\u7528\u5927O\u8868\u793a\u6cd5\u63cf\u8ff0\u5b83\u7684\u8ba1\u7b97\u590d\u6742\u5ea6\uff0c\u5e76\u8bc1\u660e\u4f60\u7684\u7b54\u6848\u662f\u5408\u7406\u7684\u3002 \u89e3\u7b54\uff1a \u5728\u4e0a\u9762\u7684\u8bb0\u5fc6\u5316\u6590\u6ce2\u90a3\u5951\u51fd\u6570\u4e2d\uff0c\u6211\u4eec\u4f7f\u7528\u4e86\u8bb0\u5fc6\u5316\u6280\u672f\u6765\u907f\u514d\u91cd\u590d\u8ba1\u7b97\u3002\u8fd9\u79cd\u4f18\u5316\u4f1a\u663e\u8457\u51cf\u5c11\u8ba1\u7b97\u65f6\u95f4\uff0c\u56e0\u4e3a\u6bcf\u4e2a\u6590\u6ce2\u90a3\u5951\u6570\u53ea\u4f1a\u88ab\u8ba1\u7b97\u4e00\u6b21\u3002 \u8ba1\u7b97\u590d\u6742\u5ea6\u5206\u6790\uff1a \u8bb0\u5fc6\u5316\u6590\u6ce2\u90a3\u5951\u51fd\u6570\u7684\u8ba1\u7b97\u590d\u6742\u5ea6\u662f O(n) \u3002\u8fd9\u662f\u56e0\u4e3a\u5b83\u9700\u8981\u8ba1\u7b97\u6590\u6ce2\u90a3\u5951\u6570\u5217\u7684\u524d n \u9879\uff0c\u6bcf\u4e00\u9879\u53ea\u9700\u8ba1\u7b97\u4e00\u6b21\uff0c\u7136\u540e\u5b58\u50a8\u5728\u7f13\u5b58\u4e2d\u3002\u56e0\u6b64\uff0c\u603b\u5171\u6267\u884c\u7684\u8ba1\u7b97\u91cf\u4e0e n \u6210\u6b63\u6bd4\uff0c\u5373 O(n) \u3002 \u9012\u5f52\u8c03\u7528\u6b21\u6570\uff1a \u9012\u5f52\u8c03\u7528\u7684\u6b21\u6570\u53d6\u51b3\u4e8e\u8f93\u5165\u53c2\u6570 n \u3002\u5bf9\u4e8e\u6590\u6ce2\u90a3\u5951\u6570\u5217\uff0c\u9012\u5f52\u8c03\u7528\u7684\u6b21\u6570\u5927\u81f4\u7b49\u4e8e n \u3002\u56e0\u4e3a\u6bcf\u4e2a\u9879\u9700\u8981\u8ba1\u7b97\u4e00\u6b21\uff0c\u6240\u4ee5\u9012\u5f52\u8c03\u7528\u7684\u6b21\u6570\u4e0e\u8ba1\u7b97\u7684\u9879\u6570\u662f\u4e00\u81f4\u7684\u3002 \u6240\u4ee5\uff0c\u8fd9\u4e2a\u8bb0\u5fc6\u5316\u6590\u6ce2\u90a3\u5951\u51fd\u6570\u7684\u8ba1\u7b97\u590d\u6742\u5ea6\u662f O(n) \uff0c\u800c\u9012\u5f52\u8c03\u7528\u7684\u6b21\u6570\u4e5f\u5927\u81f4\u7b49\u4e8e n \u3002\u8fd9\u4e2a\u6027\u80fd\u662f\u76f8\u5bf9\u8f83\u597d\u7684\uff0c\u56e0\u4e3a\u5b83\u907f\u514d\u4e86\u6307\u6570\u7ea7\u522b\u7684\u91cd\u590d\u8ba1\u7b97\uff0c\u800c\u662f\u7ebf\u6027\u5730\u8ba1\u7b97\u6590\u6ce2\u90a3\u5951\u6570\u5217\u7684\u5404\u9879\u3002 8\uff0e\u51fd\u6570makeRandomList\u4f1a\u521b\u5efa\u5e76\u8fd4\u56de\u4e00\u4e2a\u7ed9\u5b9a\u5927\u5c0f\uff08\u5b83\u7684\u53c2\u6570\uff09\u7684\u6570\u5b57\u5217\u8868\u3002\u5217\u8868\u91cc\u7684\u6570\u5b57\u6ca1\u6709\u91cd\u590d\uff0c\u5b83\u4eec\u7684\u8303\u56f4\u4e3a1\uff5esize\uff0c\u4f4d\u7f6e\u662f\u968f\u673a\u7684\u3002\u4e0b\u9762\u662f\u8fd9\u4e2a\u51fd\u6570\u7684\u4ee3\u7801\u3002\u53ef\u4ee5\u5047\u5b9arange\u3001randint\u548cappend\u51fd\u6570\u90fd\u662f\u5e38\u6570\u65f6\u95f4\u7684\u590d\u6742\u5ea6\u3002\u8fd8\u53ef\u4ee5\u5047\u8bberandom.randint\u968f\u7740\u53c2\u6570\u4e4b\u95f4\u5dee\u503c\u7684\u589e\u52a0\u800c\u66f4\u5c11\u5730\u8fd4\u56de\u91cd\u590d\u7684\u6570\u5b57\u3002\u4f7f\u7528\u5927O\u8868\u793a\u6cd5\u63cf\u8ff0\u8fd9\u4e2a\u51fd\u6570\u7684\u8ba1\u7b97\u590d\u6742\u5ea6\uff0c\u5e76\u8bc1\u660e\u4f60\u7684\u7b54\u6848\u662f\u5408\u7406\u7684\u3002 def makeRandomList ( size ): lyst = [] for count in range ( size ): while True : number = random . randint ( 1 , size ) if not number in lyst : lyst . append ( number ) break return lyst \u89e3\u7b54\uff1a \u8fd9\u4e2a\u51fd\u6570\u7684\u8ba1\u7b97\u590d\u6742\u5ea6\u53d6\u51b3\u4e8e\u5b83\u7684\u5185\u90e8\u5faa\u73af\uff0c\u8be5\u5faa\u73af\u4f1a\u4e0d\u65ad\u751f\u6210\u968f\u673a\u6570\uff0c\u5e76\u68c0\u67e5\u5b83\u662f\u5426\u5df2\u7ecf\u5728\u5217\u8868 lyst \u4e2d\u3002\u5177\u4f53\u5206\u6790\u5982\u4e0b\uff1a \u521b\u5efa\u4e00\u4e2a\u7a7a\u5217\u8868 lyst \uff0c\u65f6\u95f4\u590d\u6742\u5ea6\u4e3a O(1)\u3002 \u8fdb\u5165 for \u5faa\u73af\uff0c\u5faa\u73af\u6b21\u6570\u4e3a size \uff0c\u65f6\u95f4\u590d\u6742\u5ea6\u4e3a O(size)\u3002 \u5728\u5185\u90e8 while \u5faa\u73af\u4e2d\uff0c\u751f\u6210\u4e00\u4e2a\u968f\u673a\u6570 number \uff0c\u6700\u574f\u60c5\u51b5\u4e0b\u9700\u8981\u751f\u6210 size \u6b21\u968f\u673a\u6570\u624d\u80fd\u627e\u5230\u4e00\u4e2a\u4e0d\u5728 lyst \u4e2d\u7684\u6570\u5b57\u3002\u8fd9\u90e8\u5206\u7684\u65f6\u95f4\u590d\u6742\u5ea6\u4e3a O(size)\u3002 \u7efc\u4e0a\u6240\u8ff0\uff0c\u8fd9\u4e2a\u51fd\u6570\u7684\u603b\u4f53\u65f6\u95f4\u590d\u6742\u5ea6\u4e3a O(size^2)\u3002\u8fd9\u662f\u56e0\u4e3a\u5728\u6700\u574f\u60c5\u51b5\u4e0b\uff0c\u6bcf\u6b21\u751f\u6210\u7684\u968f\u673a\u6570\u90fd\u9700\u8981\u68c0\u67e5\u662f\u5426\u5728 lyst \u4e2d\uff0c\u800c\u968f\u673a\u6570\u7684\u751f\u6210\u53ef\u80fd\u9700\u8981\u591a\u6b21\u624d\u80fd\u751f\u6210\u4e00\u4e2a\u4e0d\u5728\u5217\u8868\u4e2d\u7684\u6570\u5b57\u3002 \u9700\u8981\u6ce8\u610f\u7684\u662f\uff0c\u968f\u7740 size \u7684\u589e\u52a0\uff0c\u5185\u90e8\u5faa\u73af\u7684\u8fed\u4ee3\u6b21\u6570\u4e5f\u4f1a\u589e\u52a0\uff0c\u5bfc\u81f4\u65f6\u95f4\u590d\u6742\u5ea6\u5448\u4e8c\u6b21\u589e\u957f\u3002\u56e0\u6b64\uff0c\u8fd9\u4e2a\u51fd\u6570\u7684\u6027\u80fd\u5728\u5927\u89c4\u6a21\u6570\u636e\u4e0a\u53ef\u80fd\u4f1a\u53d7\u5230\u9650\u5236\u3002\u5982\u679c\u9700\u8981\u66f4\u597d\u7684\u6027\u80fd\uff0c\u53ef\u4ee5\u8003\u8651\u5176\u4ed6\u7b97\u6cd5\uff0c\u4ee5\u907f\u514d\u91cd\u590d\u68c0\u67e5\u548c\u751f\u6210\u968f\u673a\u6570\u3002 import random def makeRandomList ( size ): lyst = [] for count in range ( size ): while True : number = random . randint ( 1 , size ) if not number in lyst : lyst . append ( number ) break print ( \"count=\" , count , \"list=\" , lyst ) return lyst def main (): print ( \"final list=\" , makeRandomList ( 10 )) if __name__ == \"__main__\" : main () # \u8fd0\u884c\u7ed3\u679c\uff1a # count= 0 list= [2] # count= 1 list= [2, 10] # count= 2 list= [2, 10, 9] # count= 3 list= [2, 10, 9, 5] # count= 4 list= [2, 10, 9, 5, 3] # count= 5 list= [2, 10, 9, 5, 3, 4] # count= 6 list= [2, 10, 9, 5, 3, 4, 8] # count= 7 list= [2, 10, 9, 5, 3, 4, 8, 7] # count= 8 list= [2, 10, 9, 5, 3, 4, 8, 7, 6] # count= 9 list= [2, 10, 9, 5, 3, 4, 8, 7, 6, 1] # final list= [2, 10, 9, 5, 3, 4, 8, 7, 6, 1] 9\uff0e\u4fee\u6539quicksort\u51fd\u6570\uff0c\u8ba9\u5b83\u53ef\u4ee5\u5bf9\u4efb\u4f55\u5c3a\u5bf8\u5c0f\u4e8e50\u7684\u5b50\u5217\u8868\u8c03\u7528\u63d2\u5165\u6392\u5e8f\u3002\u4f7f\u7528\u670950\u3001500\u548c5000\u4e2a\u5143\u7d20\u7684\u6570\u636e\u96c6\u6bd4\u8f83\u8fd9\u4e2a\u7248\u672c\u4e0e\u539f\u59cb\u7248\u672c\u7684\u6027\u80fd\u3002\u7136\u540e\u8c03\u6574\u8fd9\u4e2a\u9608\u503c\uff0c\u4ece\u800c\u786e\u5b9a\u4f7f\u7528\u63d2\u5165\u6392\u5e8f\u7684\u6700\u4f73\u8bbe\u7f6e\u3002 \u89e3\u7b54\uff1a \u53ef\u4ee5\u5728 quicksortHelper \u51fd\u6570\u4e2d\u6dfb\u52a0\u4e00\u4e2a\u6761\u4ef6\uff0c\u68c0\u67e5\u5b50\u5217\u8868\u7684\u5927\u5c0f\u3002\u7136\u540e\u518d\u4fee\u6539 quicksort \u51fd\u6570\uff0c\u5b9e\u73b0\u5728\u5c0f\u4e8e50\u7684\u5b50\u5217\u8868\u4e0a\u4f7f\u7528\u63d2\u5165\u6392\u5e8f\u3002 \u5982\u679c\u5b50\u5217\u8868\u7684\u5927\u5c0f\u5c0f\u4e8e50\uff0c\u5c31\u4f7f\u7528\u63d2\u5165\u6392\u5e8f\u7b97\u6cd5\uff0c\u5426\u5219\u4f7f\u7528\u5feb\u901f\u6392\u5e8f\u7b97\u6cd5\u3002\u4e0b\u9762\u662f\u4fee\u6539\u540e\u7684\u4ee3\u7801\uff1a import random def swap ( lyst , i , j ): \"\"\"\u4ea4\u6362\u5143\u7d20\u4f4d\u7f6e\u4e3ai\u548cj\u7684\u5143\u7d20\"\"\" temp = lyst [ i ] lyst [ i ] = lyst [ j ] lyst [ j ] = temp def quicksort ( lyst ): quicksortHelper ( lyst , 0 , len ( lyst ) - 1 ) def quicksortHelper ( lyst , left , right ): if left < right : # \u68c0\u67e5\u5b50\u5217\u8868\u7684\u5927\u5c0f\u662f\u5426\u5c0f\u4e8e50 if right - left < 50 : # \u5982\u679c\u5c0f\u4e8e50\uff0c\u4f7f\u7528\u63d2\u5165\u6392\u5e8f insertionSort ( lyst , left , right ) else : pivotLocation = partition ( lyst , left , right ) quicksortHelper ( lyst , left , pivotLocation - 1 ) quicksortHelper ( lyst , pivotLocation + 1 , right ) def partition ( lyst , left , right ): \"\"\"\u5bf9\u5217\u8868\u8fdb\u884c\u5206\u533a\"\"\" # \u627e\u5230\u57fa\u51c6\u5143\u7d20\uff08pivot\uff09\uff0c\u5e76\u548c\u6700\u540e\u4e00\u4e2a\u5143\u7d20\u4e92\u6362 middle = ( left + right ) // 2 pivot = lyst [ middle ] lyst [ middle ] = lyst [ right ] lyst [ right ] = pivot # \u8bbe\u5b9a\u8fb9\u754c\u5143\u7d20\uff08boundary point\uff09\uff0c\u521d\u59cb\u662f\u7b2c\u4e00\u4e2a\u5143\u7d20 boundary = left print ( \"pivot: \" , pivot , \"boundary: \" , lyst [ boundary ]) # \u628a\u6240\u6709\u5c0f\u4e8e\u57fa\u51c6\u7684\u5143\u7d20\u90fd\u79fb\u52a8\u5230\u8fb9\u754c\u7684\u5de6\u8fb9 for index in range ( left , right ): if lyst [ index ] < pivot : swap ( lyst , index , boundary ) boundary += 1 # \u4ea4\u6362\u57fa\u51c6\u5143\u7d20\u548c\u8fb9\u754c\u5143\u7d20 swap ( lyst , right , boundary ) print ( lyst ) return boundary def insertionSort ( lyst , left , right ): \"\"\"\u63d2\u5165\u6392\u5e8f\u7b97\u6cd5\"\"\" for i in range ( left + 1 , right + 1 ): currentElement = lyst [ i ] j = i while j > left and currentElement < lyst [ j - 1 ]: lyst [ j ] = lyst [ j - 1 ] j -= 1 lyst [ j ] = currentElement def main ( size = 20 , sort = quicksort ): lyst = [ random . randint ( 1 , size ) for _ in range ( size )] print ( \"Before sorted\" , lyst ) sort ( lyst ) print ( \"After sorted\" , lyst ) if __name__ == \"__main__\" : main () # \u8fd0\u884c\u7ed3\u679c\uff1a # Before sorted [1, 3, 6, 14, 9, 6, 14, 15, 17, 13, 4, 3, 1, 13, 11, 16, 2, 4, 6, 2] # After sorted [1, 1, 2, 2, 3, 3, 4, 4, 6, 6, 6, 9, 11, 13, 13, 14, 14, 15, 16, 17] 10\uff0e\u8ba1\u7b97\u673a\u4f7f\u7528\u540d\u4e3a\u8c03\u7528\u6808\u7684\u7ed3\u6784\u6765\u4e3a\u9012\u5f52\u51fd\u6570\u7684\u8c03\u7528\u63d0\u4f9b\u652f\u6301\u3002\u4e00\u822c\u800c\u8a00\uff0c\u8ba1\u7b97\u673a\u4f1a\u4e3a\u51fd\u6570\u7684\u6bcf\u6b21\u8c03\u7528\u90fd\u4fdd\u7559\u4e00\u5b9a\u6570\u91cf\u7684\u5185\u5b58\u3002\u56e0\u6b64\uff0c\u53ef\u4ee5\u5bf9\u9012\u5f52\u51fd\u6570\u4f7f\u7528\u7684\u5185\u5b58\u6570\u91cf\u8fdb\u884c\u590d\u6742\u5ea6\u5206\u6790\u3002\u8bf7\u8bf4\u660e\u9012\u5f52\u9636\u4e58\u51fd\u6570\u548c\u9012\u5f52\u6590\u6ce2\u90a3\u5951\u51fd\u6570\u4f7f\u7528\u7684\u5185\u5b58\u7684\u8ba1\u7b97\u590d\u6742\u5ea6\u3002 \u89e3\u7b54\uff1a \u9012\u5f52\u9636\u4e58\u51fd\u6570\u548c\u9012\u5f52\u6590\u6ce2\u90a3\u5951\u51fd\u6570\u4f7f\u7528\u7684\u5185\u5b58\u7684\u8ba1\u7b97\u590d\u6742\u5ea6\u90fd\u4e0e\u9012\u5f52\u7684\u6df1\u5ea6\uff08\u9012\u5f52\u8c03\u7528\u7684\u5c42\u6570\uff09\u76f8\u5173\u3002\u9012\u5f52\u51fd\u6570\u6bcf\u6b21\u8c03\u7528\u90fd\u4f1a\u5728\u8c03\u7528\u6808\u4e2d\u5206\u914d\u4e00\u5b9a\u6570\u91cf\u7684\u5185\u5b58\uff0c\u5305\u62ec\u51fd\u6570\u7684\u53c2\u6570\u3001\u5c40\u90e8\u53d8\u91cf\u4ee5\u53ca\u8fd4\u56de\u5730\u5740\u7b49\u4fe1\u606f\u3002 \u9012\u5f52\u9636\u4e58\u51fd\u6570\u7684\u5185\u5b58\u590d\u6742\u5ea6\uff1a \u9012\u5f52\u9636\u4e58\u51fd\u6570\u662f\u4e00\u4e2a\u975e\u5e38\u7b80\u5355\u7684\u9012\u5f52\u51fd\u6570\uff0c\u5b83\u53ea\u9700\u8981\u4fdd\u5b58\u4e00\u4e2a\u6574\u6570\u53c2\u6570 n \u548c\u8fd4\u56de\u5730\u5740\u3002\u56e0\u6b64\uff0c\u5b83\u7684\u5185\u5b58\u590d\u6742\u5ea6\u662f O(1)\uff0c\u4e0e\u8f93\u5165\u53c2\u6570 n \u7684\u5927\u5c0f\u65e0\u5173\u3002\u6bcf\u4e2a\u9012\u5f52\u8c03\u7528\u90fd\u53ea\u9700\u8981\u5e38\u6570\u7ea7\u522b\u7684\u5185\u5b58\u7a7a\u95f4\u3002 \u9012\u5f52\u6590\u6ce2\u90a3\u5951\u51fd\u6570\u7684\u5185\u5b58\u590d\u6742\u5ea6\uff1a \u9012\u5f52\u6590\u6ce2\u90a3\u5951\u51fd\u6570\u7684\u5185\u5b58\u590d\u6742\u5ea6\u53d6\u51b3\u4e8e\u9012\u5f52\u7684\u6df1\u5ea6\u3002\u6bcf\u4e2a\u9012\u5f52\u8c03\u7528\u90fd\u9700\u8981\u4fdd\u5b58\u4e24\u4e2a\u6574\u6570\u53c2\u6570 n \u548c depth \uff0c\u4ee5\u53ca\u8fd4\u56de\u5730\u5740\u3002\u56e0\u6b64\uff0c\u6bcf\u6b21\u9012\u5f52\u8c03\u7528\u9700\u8981\u7684\u5185\u5b58\u7a7a\u95f4\u662f\u5e38\u6570\u7ea7\u522b\u7684\u3002 \u9012\u5f52\u6590\u6ce2\u90a3\u5951\u51fd\u6570\u7684\u9012\u5f52\u6df1\u5ea6\u53d6\u51b3\u4e8e\u8f93\u5165\u53c2\u6570 n \u3002\u5177\u4f53\u6765\u8bf4\uff0c\u9012\u5f52\u6df1\u5ea6\u7b49\u4e8e n \u3002\u56e0\u6b64\uff0c\u9012\u5f52\u6590\u6ce2\u90a3\u5951\u51fd\u6570\u7684\u5185\u5b58\u590d\u6742\u5ea6\u662f O(n)\uff0c\u4e0e\u8f93\u5165\u53c2\u6570 n \u6210\u6b63\u6bd4\u3002 \u603b\u7ed3\u6765\u8bf4\uff0c\u9012\u5f52\u9636\u4e58\u51fd\u6570\u7684\u5185\u5b58\u590d\u6742\u5ea6\u662f O(1)\uff0c\u800c\u9012\u5f52\u6590\u6ce2\u90a3\u5951\u51fd\u6570\u7684\u5185\u5b58\u590d\u6742\u5ea6\u662f O(n)\u3002\u5728\u9012\u5f52\u7b97\u6cd5\u4e2d\uff0c\u5185\u5b58\u590d\u6742\u5ea6\u901a\u5e38\u4e0e\u9012\u5f52\u6df1\u5ea6\u6210\u6b63\u6bd4\uff0c\u56e0\u6b64\u9700\u8981\u8c28\u614e\u5904\u7406\u9012\u5f52\u8c03\u7528\uff0c\u4ee5\u907f\u514d\u51fa\u73b0\u6808\u6ea2\u51fa\u7b49\u95ee\u9898\u3002\u53ef\u4ee5\u4f7f\u7528\u8fed\u4ee3\u6216\u52a8\u6001\u89c4\u5212\u7b49\u65b9\u6cd5\u6765\u964d\u4f4e\u5185\u5b58\u6d88\u8017\u3002","title":"\u641c\u7d22\u3001\u6392\u5e8f\u4ee5\u53ca\u590d\u6742\u5ea6\u5206\u6790"},{"location":"python/DataStructure/03_TimeComplexity/#3","text":"\u7b97\u6cd5\u63cf\u8ff0\u4e86\u4e00\u4e2a\u968f\u7740\u95ee\u9898\u88ab\u89e3\u51b3\u800c\u505c\u6b62\u7684\u8ba1\u7b97\u8fc7\u7a0b\u3002 \u7b97\u6cd5\u662f\u8ba1\u7b97\u673a\u7a0b\u5e8f\u7684\u57fa\u672c\u7ec4\u6210\u90e8\u5206\u4e4b\u4e00\uff0c\u53e6\u4e00\u4e2a\u57fa\u672c\u7ec4\u6210\u90e8\u5206\u662f\u6570\u636e\u7ed3\u6784\u3002 \u5728\u7b97\u6cd5\u6267\u884c\u8fc7\u7a0b\u4e2d\u4f1a\u6d88\u8017\u4e24\u4e2a\u8d44\u6e90\uff1a\u5904\u7406\u5bf9\u8c61\u6240\u9700\u7684\u65f6\u95f4\u548c\u7a7a\u95f4\uff08\u4e5f\u5c31\u662f\u5185\u5b58\uff09\u3002\u5bf9\u4e8e\u7b97\u6cd5\u6765\u8bf4\uff0c\u603b\u4f1a\u8ffd\u6c42\u6d88\u8017\u66f4\u77ed\u7684\u65f6\u95f4\u548c\u5360\u7528\u66f4\u5c11\u7684\u7a7a\u95f4\u3002\u5728\u9009\u62e9\u7b97\u6cd5\u65f6\uff0c\u901a\u5e38\u5728\u7a7a\u95f4/\u65f6\u95f4\u4e4b\u95f4\u8fdb\u884c\u6743\u8861\u3002 \u7b97\u6cd5\u8d28\u91cf\u7684\u4e3b\u8981\u8bc4\u4f30\u6807\u51c6\uff1a \u6b63\u786e\u6027\uff0c\u5373\u7b97\u6cd5\u80fd\u591f\u771f\u6b63\u89e3\u51b3\u6240\u9488\u5bf9\u7684\u95ee\u9898\uff1b \u53ef\u8bfb\u6027\u548c\u6613\u4e8e\u7ef4\u62a4\u6027\uff1b \u8fd0\u884c\u65f6\u6027\u80fd\uff1b \u76ee\u6807\uff1a \u6839\u636e\u95ee\u9898\u7684\u89c4\u6a21\u786e\u5b9a\u7b97\u6cd5\u5de5\u4f5c\u91cf\u7684\u589e\u957f\u7387\uff1b \u4f7f\u7528\u5927O\u8868\u793a\u6cd5\u6765\u63cf\u8ff0\u7b97\u6cd5\u7684\u8fd0\u884c\u65f6\u548c\u5185\u5b58\u4f7f\u7528\u60c5\u51b5\uff1b \u8ba4\u8bc6\u5e38\u89c1\u7684\u5de5\u4f5c\u91cf\u589e\u957f\u7387\u6216\u590d\u6742\u5ea6\u7684\u7c7b\u522b\uff08\u5e38\u6570\u3001\u5bf9\u6570\u3001\u7ebf\u6027\u3001\u5e73\u65b9\u548c\u6307\u6570\uff09\uff1b \u5c06\u7b97\u6cd5\u8f6c\u6362\u4e3a\u590d\u6742\u5ea6\u4f4e\u4e00\u4e2a\u6570\u91cf\u7ea7\u7684\u66f4\u5feb\u7684\u7248\u672c\uff1b \u63cf\u8ff0\u987a\u5e8f\u641c\u7d22\u7b97\u6cd5\u548c\u4e8c\u5206\u641c\u7d22\u7b97\u6cd5\u7684\u5de5\u4f5c\u65b9\u5f0f\uff1b \u63cf\u8ff0\u9009\u62e9\u6392\u5e8f\u7b97\u6cd5\u548c\u5feb\u901f\u6392\u5e8f\u7b97\u6cd5\u7684\u5de5\u4f5c\u65b9\u5f0f\u3002","title":"3.\u641c\u7d22\u3001\u6392\u5e8f\u4ee5\u53ca\u590d\u6742\u5ea6\u5206\u6790"},{"location":"python/DataStructure/03_TimeComplexity/#31","text":"\u8861\u91cf\u7b97\u6cd5\u65f6\u95f4\u6210\u672c\u7684\u4e24\u79cd\u65b9\u6cd5\uff1a \u7528\u8ba1\u7b97\u673a\u65f6\u949f\u5f97\u5230\u7b97\u6cd5\u5b9e\u9645\u7684\u8fd0\u884c\u65f6\u3002\u8fd9\u4e2a\u8fc7\u7a0b\u88ab\u79f0\u4e3a\u57fa\u51c6\u6d4b\u8bd5\uff08benchmarking\uff09\u6216\u6027\u80fd\u5206\u6790\uff08profiling\uff09\u3002\u9884\u6d4b\u7b97\u6cd5\u6267\u884c\u7684\u62bd\u8c61\u5de5\u4f5c\u91cf\u4f9d\u8d56\u4e8e\u7279\u5b9a\u7684\u786c\u4ef6\u6216\u8f6f\u4ef6\u5e73\u53f0\u3002 \u5728\u4e0d\u540c\u95ee\u9898\u89c4\u6a21\u4e0b\uff0c\u7edf\u8ba1\u9700\u8981\u6267\u884c\u7684\u6307\u4ee4\u6570\u3002\u9884\u6d4b\u7b97\u6cd5\u6267\u884c\u7684\u62bd\u8c61\u5de5\u4f5c\u91cf\u9002\u7528\u4e8e\u4e0d\u540c\u7684\u786c\u4ef6\u6216\u8f6f\u4ef6\u5e73\u53f0\u3002","title":"3.1.\u8861\u91cf\u7b97\u6cd5\u7684\u6548\u7387"},{"location":"python/DataStructure/03_TimeComplexity/#311","text":"import time problemSize = 10000000 print ( \" %12s%16s \" % ( \"Problem Size\" , \"Seconds\" )) for count in range ( 5 ): \"\"\" \u5728\u4e00\u4e2a\u5faa\u73af\u4e2d\uff0c\u5c06\u95ee\u9898\u89c4\u6a21\u7ffb\u500d5\u6b21\uff0c\u8bb0\u5f55\u7b97\u6cd5\u6bcf\u6b21\u8fd0\u884c\u65f6\u95f4\u3002 \"\"\" start = time . time () # \u7b97\u6cd5\u5f00\u59cb work = 1 for x in range ( problemSize ): work += 1 work -= 1 # \u7b97\u6cd5\u7ed3\u675f elapsed = time . time () - start print ( \" %12d%16.3f \" % ( problemSize , elapsed )) problemSize *= 2 # \u8fd0\u884c\u7ed3\u679c\uff1a # Problem Size Seconds # 10000000 0.689 # 20000000 1.367 # 40000000 2.644 # 80000000 5.296 # 160000000 10.622 \u4e0a\u8ff0\u6d4b\u8bd5\u7a0b\u5e8f\u4f7f\u7528\u4e86 time \u6a21\u5757\u91cc\u7684 time() \u51fd\u6570\u6765\u8bb0\u5f55\u8fd0\u884c\u65f6\uff0c\u5373 time.time() \u3002\u8fd9\u4e2a\u51fd\u6570\u4f1a\u8fd4\u56de\u8ba1\u7b97\u673a\u7684\u5f53\u524d\u65f6\u95f4\u548c1970\u5e741\u67081\u65e5\uff3b\u4e5f\u79f0\u4e3a\u7eaa\u5143\uff08epoch\uff09\uff3d\u76f8\u5dee\u7684\u79d2\u6570\u3002\u4e24\u6b21\u8c03\u7528 time.time() \u7684\u7ed3\u679c\u4e4b\u95f4\u7684\u5dee\u503c\u5c31\u4ee3\u8868\u4e86\u4e2d\u95f4\u7ecf\u5386\u4e86\u591a\u5c11\u79d2\u3002 \u4e0a\u8ff0\u6d4b\u8bd5\u7a0b\u5e8f\u5728\u6bcf\u6b21\u5faa\u73af\u7684\u65f6\u5019\u90fd\u4f1a\u6267\u884c\u4e24\u4e2a\u6269\u5c55\u7684\u8d4b\u503c\u8bed\u53e5\uff0c\u4e5f\u5c31\u662f\u6bcf\u6b21\u90fd\u6267\u884c\u7684\u5de5\u4f5c\u91cf\u662f\u56fa\u5b9a\u7684\uff0c\u4f1a\u6d88\u8017\u4e86\u4e00\u5b9a\u7684\u65f6\u95f4\u3002 \u4fee\u6539\u4e0a\u8ff0\u7b97\u6cd5\uff0c\u6211\u4eec\u53ef\u4ee5\u4ece\u4e0b\u9762\u7684\u8fd0\u884c\u7ed3\u679c\u770b\u51fa\uff0c\u5f53 problemSize \u4e3a 1,000 \u65f6\uff0c\u7b97\u6cd5\u7684\u6d88\u8017\u65f6\u95f4\u5c31\u5df2\u7ecf\u8d85\u8fc7\u4e86\u539f\u5148\u7b97\u6cd5\uff0c\u6211\u4eec\u53ef\u4ee5\u63a8\u65ad\u51fa\u7ee7\u7eed\u6d4b\u8bd5 problemSize \u4e3a 10,000,000 \u7684\u8017\u65f6\u5df2\u7ecf\u53d8\u5f97\u4e0d\u5b9e\u9645\u4e86\u3002 import time problemSize = 1000 print ( \" %12s%16s \" % ( \"Problem Size\" , \"Seconds\" )) for count in range ( 5 ): start = time . time () # \u7b97\u6cd5\u5f00\u59cb work = 1 for x in range ( problemSize ): for y in range ( problemSize ): work += 1 work -= 1 # \u7b97\u6cd5\u7ed3\u675f elapsed = time . time () - start print ( \" %12d%16.3f \" % ( problemSize , elapsed )) problemSize *= 2 # \u8fd0\u884c\u7ed3\u679c\uff1a # Problem Size Seconds # 1000 0.093 # 2000 0.350 # 4000 1.280 # 8000 5.004 # 16000 20.020 \u4e0d\u540c\u7684\u786c\u4ef6\u5e73\u53f0\u4f1a\u6709\u4e0d\u540c\u7684\u5904\u7406\u901f\u5ea6\uff0c\u7b97\u6cd5\u7684\u8fd0\u884c\u65f6\u4f1a\u56e0\u673a\u5668\u7684\u4e0d\u540c\u800c\u5b58\u5728\u5dee\u5f02\u3002 \u7a0b\u5e8f\u7684\u8fd0\u884c\u65f6\u4e5f\u4f1a\u968f\u7740\u5b83\u548c\u786c\u4ef6\u4e4b\u95f4\u7684\u64cd\u4f5c\u7cfb\u7edf\u7c7b\u578b\u7684\u4e0d\u540c\u800c\u53d8\u5316\u3002 \u4e0d\u540c\u7684\u7f16\u7a0b\u8bed\u8a00\u548c\u7f16\u8bd1\u5668\u751f\u6210\u7684\u4ee3\u7801\u7684\u6027\u80fd\u4e5f\u4f1a\u6709\u6240\u4e0d\u540c\uff0c\u56e0\u6b64\uff0c\u5728\u67d0\u4e00\u4e2a\u786c\u4ef6\u6216\u8f6f\u4ef6\u5e73\u53f0\u4e0a\u6d4b\u5f97\u7684\u8fd0\u884c\u65f6\u7ed3\u679c\u901a\u5e38\u4e0d\u80fd\u7528\u6765\u9884\u6d4b\u5728\u5176\u4ed6\u5e73\u53f0\u4e0a\u7684\u6027\u80fd\u3002 \u7528\u975e\u5e38\u5927\u7684\u6570\u636e\u96c6\u786e\u5b9a\u7b97\u6cd5\u7684\u8fd0\u884c\u65f6\u662f\u975e\u5e38\u4e0d\u5207\u5b9e\u9645\u7684\u3002\u5bf9\u4e8e\u67d0\u4e9b\u7b97\u6cd5\u6765\u8bf4\uff0c\u4e0d\u8bba\u662f\u7f16\u8bd1\u7684\u4ee3\u7801\u8fd8\u662f\u786c\u4ef6\u5904\u7406\u5668\u7684\u901f\u5ea6\u6709\u591a\u5feb\uff0c\u90fd\u6ca1\u6709\u4efb\u4f55\u7684\u533a\u522b\uff0c\u56e0\u4e3a\u5b83\u4eec\u5728\u4efb\u4f55\u8ba1\u7b97\u673a\u4e0a\u90fd\u6ca1\u529e\u6cd5\u5904\u7406\u975e\u5e38\u5927\u7684\u6570\u636e\u96c6\u3002","title":"3.1.1.\u8861\u91cf\u7b97\u6cd5\u7684\u8fd0\u884c\u65f6"},{"location":"python/DataStructure/03_TimeComplexity/#312","text":"\u7edf\u8ba1\u6307\u4ee4\u6570\u65f6\uff0c\u7edf\u8ba1\u7684\u662f\u7f16\u5199\u7b97\u6cd5\u7684\u9ad8\u7ea7\u8bed\u8a00\u91cc\u7684\u6307\u4ee4\u6570\uff0c\u800c\u4e0d\u662f\u53ef\u6267\u884c\u673a\u5668\u8bed\u8a00\u7a0b\u5e8f\u91cc\u7684\u6307\u4ee4\u6570\u3002 \u901a\u8fc7\u8fd9\u79cd\u65b9\u5f0f\u5bf9\u7b97\u6cd5\u8fdb\u884c\u5206\u6790\u65f6\uff0c\u628a\u5b83\u5206\u6210\u4e24\u4e2a\u90e8\u5206\uff1a \u65e0\u8bba\u95ee\u9898\u7684\u89c4\u6a21\u5982\u4f55\u53d8\u5316\uff0c\u6307\u4ee4\u6267\u884c\u7684\u6b21\u6570\u603b\u662f\u76f8\u540c\u7684\uff1b\u6211\u4eec\u5ffd\u7565\u8fd9\u79cd\u7c7b\u578b\uff0c\u56e0\u4e3a\u5206\u6790\u6548\u7387\u65f6\u5b83\u4eec\u7684\u4f5c\u7528\u5e76\u4e0d\u660e\u663e\u3002 \u6267\u884c\u7684\u6307\u4ee4\u6570\u968f\u7740\u95ee\u9898\u89c4\u6a21\u7684\u53d8\u5316\u800c\u53d8\u5316\uff1b\u6211\u4eec\u91cd\u70b9\u5173\u6ce8\u8fd9\u79cd\u7c7b\u578b\uff0c\u8fd9\u79cd\u7c7b\u578b\u7684\u6307\u4ee4\u901a\u5e38\u53ef\u4ee5\u5728\u5faa\u73af\u6216\u8005\u9012\u5f52\u51fd\u6570\u91cc\u627e\u5230\u3002 \u6211\u4eec\u6765\u6539\u5199\u4e0a\u9762\u7684\u4f8b\u5b50\uff0c\u4ece\u7edf\u8ba1\u8fd0\u884c\u65f6\u95f4\u53d8\u4e3a\u7edf\u8ba1\u8fed\u4ee3\u6b21\u6570\u3002 \u4e0b\u9762\u7684\u7b97\u6cd5\u4e2d\uff0c\u8fed\u4ee3\u6b21\u6570\u548c\u95ee\u9898\u89c4\u6a21\u662f\u76f8\u7b49\u7684\u3002 import time problemSize = 10000000 print ( \" %12s%16s \" % ( \"Problem Size\" , \"Seconds\" )) for count in range ( 5 ): number = 0 # \u7b97\u6cd5\u5f00\u59cb work = 1 for x in range ( problemSize ): number += 1 work += 1 work -= 1 # \u7b97\u6cd5\u7ed3\u675f print ( \" %12d%16.3f \" % ( problemSize , Iterations )) problemSize *= 2 # \u8fd0\u884c\u7ed3\u679c\uff1a # Problem Size Iterations # 10000000 10000000.000 # 20000000 20000000.000 # 40000000 40000000.000 # 80000000 80000000.000 # 160000000 160000000.000 \u4e0b\u9762\u7684\u7b97\u6cd5\u4e2d\uff0c\u8fed\u4ee3\u6b21\u6570\u548c\u95ee\u9898\u89c4\u6a21\u7684\u5e73\u65b9\u3002\u8fd9\u5c31\u89e3\u91ca\u4e86\u4e3a\u4ec0\u4e48\u8fd9\u4e2a\u7b97\u6cd5\u7684\u8017\u65f6\u975e\u5e38\u5927\u3002 import time problemSize = 1000 print ( \" %12s%16s \" % ( \"Problem Size\" , \"Seconds\" )) for count in range ( 5 ): number = 0 # \u7b97\u6cd5\u5f00\u59cb work = 1 for x in range ( problemSize ): for y in range ( problemSize ): number += 1 work += 1 work -= 1 # \u7b97\u6cd5\u7ed3\u675f print ( \" %12d%16.3f \" % ( problemSize , number )) problemSize *= 2 # \u8fd0\u884c\u7ed3\u679c\uff1a # Problem Size Iterations # 1000 1000000.000 # 2000 4000000.000 # 4000 16000000.000 # 8000 64000000.000 # 16000 256000000.000 \u5728\u4e0b\u9762\u7684\u6590\u6ce2\u90a3\u5951\u9012\u5f52\u7684\u4f8b\u5b50\u4e2d\uff0c\u51fd\u6570 fib(problemSize, counter) \u4e2d counter \u53c2\u6570\u662f\u4e00\u4e2a\u5bf9\u8c61\uff0c\u6bcf\u6b21\u9012\u5f52\u8c03\u7528\u7684\u65f6\u5019\uff0c\u90fd\u4f1a\u521b\u5efa\u4e00\u4e2a\u65b0\u7684\u8ba1\u6570\u5668\u5bf9\u8c61\u3002 \u4ece\u4e0b\u9762\u7684\u8fd0\u884c\u7ed3\u679c\u53ef\u4ee5\u770b\u51fa\uff0c\u968f\u7740\u95ee\u9898\u89c4\u6a21\uff08Problem Size\uff09\u7684\u7ffb\u500d\uff0c\u6307\u4ee4\u6570\uff08\u9012\u5f52\u8c03\u7528\u7684\u6b21\u6570\uff09\u5728\u4e00\u5f00\u59cb\u7684\u65f6\u5019\u7f13\u6162\u589e\u957f\uff0c\u968f\u540e\u8fc5\u901f\u52a0\u5feb\u3002 \u7edf\u8ba1\u6307\u4ee4\u6570\u662f\u6b63\u786e\u7684\u601d\u8def\uff0c\u4f46\u4ee5\u8fd9\u79cd\u65b9\u5f0f\u8fdb\u884c\u8ddf\u8e2a\u8ba1\u6570\u7684\u95ee\u9898\u5728\u4e8e\uff0c\u5bf9\u4e8e\u67d0\u4e9b\u7b97\u6cd5\u6765\u8bf4\uff0c\u5982\u679c\u95ee\u9898\u89c4\u6a21\u975e\u5e38\u5927\uff0c\u8ba1\u7b97\u673a\u65e0\u6cd5\u4ee5\u8db3\u591f\u5feb\u7684\u901f\u5ea6\u8fd0\u884c\uff0c\u5e76\u5728\u4e00\u5b9a\u65f6\u95f4\u5185\u5f97\u5230\u7ed3\u679c\u3002 class Counter ( object ): \"\"\"Models a counter.\"\"\" # Class variable instances = 0 #Constructor def __init__ ( self ): \"\"\"Sets up the counter.\"\"\" Counter . instances += 1 self . reset () # Mutator methods def reset ( self ): \"\"\"Sets the counter to 0.\"\"\" self . _value = 0 def increment ( self , amount = 1 ): \"\"\"Adds amount to the counter.\"\"\" self . _value += amount def decrement ( self , amount = 1 ): \"\"\"Subtracts amount from the counter.\"\"\" self . _value -= amount # Accessor methods def getValue ( self ): \"\"\"Returns the counter's value.\"\"\" return self . _value def __str__ ( self ): \"\"\"Returns the string representation of the counter.\"\"\" return str ( self . _value ) def __eq__ ( self , other ): \"\"\"Returns True if self equals other or False otherwise.\"\"\" if self is other : return True if type ( self ) != type ( other ): return False return self . _value == other . _value def fib ( n , counter ): \"\"\"\u7edf\u8ba1\u6590\u6ce2\u90a3\u5951\u51fd\u6570\u88ab\u5916\u90e8\u8c03\u7528\u7684\u6b21\u6570\"\"\" counter . increment () if n < 3 : return 1 else : return fib ( n - 1 , counter ) + fib ( n - 2 , counter ) problemSize = 2 print ( \" %12s%15s \" % ( \"Problem Size\" , \"Calls\" )) for count in range ( 5 ): \"\"\"\u968f\u7740\u95ee\u9898\u89c4\u6a21\u589e\u52a0\uff0c\u8f93\u51fa\u6590\u6ce2\u90a3\u5951\u9012\u5f52\u51fd\u6570\u88ab\u5916\u90e8\u8c03\u7528\u7684\u6b21\u6570\"\"\" counter = Counter () # \u7b97\u6cd5\u5f00\u59cb fib ( problemSize , counter ) # \u7b97\u6cd5\u7ed3\u675f print ( \" %12d%15s \" % ( problemSize , counter )) problemSize *= 2 # \u8fd0\u884c\u7ed3\u679c\uff1a # Problem Size Calls # 2 1 # 4 5 # 8 41 # 16 1973 # 32 4356617","title":"3.1.2.\u7edf\u8ba1\u6307\u4ee4\u6570"},{"location":"python/DataStructure/03_TimeComplexity/#313","text":"\u5bf9\u4e8e\u7b97\u6cd5\u6240\u7528\u8d44\u6e90\u7684\u5206\u6790\u4e5f\u9700\u8981\u5305\u542b\u5b83\u6240\u9700\u7684\u5185\u5b58\u91cf\u7684\u5206\u6790\u3002\u548c\u524d\u9762\u7c7b\u4f3c\u7684\u95ee\u9898\u4e5f\u4f1a\u5b58\u5728\uff0c\u4e00\u4e9b\u7b97\u6cd5\u4f1a\u968f\u7740\u95ee\u9898\u89c4\u6a21\u53d8\u5927\u800c\u9700\u8981\u989d\u5916\u66f4\u591a\u7684\u5185\u5b58\u3002","title":"3.1.3.\u8861\u91cf\u7b97\u6cd5\u4f7f\u7528\u7684\u5185\u5b58"},{"location":"python/DataStructure/03_TimeComplexity/#314","text":"\u7f16\u5199\u4e00\u4e2a\u6d4b\u8bd5\u7a0b\u5e8f\uff0c\u8fd9\u4e2a\u7a0b\u5e8f\u7edf\u8ba1\u5e76\u663e\u793a\u51fa\u4e0b\u9762\u8fd9\u4e2a\u5faa\u73af\u7684\u8fed\u4ee3\u6b21\u6570\u3002 while problemSize > 0 : problemSize = problemSize // 2 \u89e3\u7b54\uff1a def count_iterations ( problemSize ): iterations = 0 # \u521d\u59cb\u5316\u8ba1\u6570\u5668 while problemSize > 0 : problemSize = problemSize // 2 iterations += 1 # \u6bcf\u6b21\u5faa\u73af\u8fed\u4ee3\uff0c\u8ba1\u6570\u5668\u52a0\u4e00 return iterations problemSize = 1000 # \u8bbe\u7f6e\u95ee\u9898\u89c4\u6a21 iterations = count_iterations ( problemSize ) print ( f \"Problem Size: { problemSize } \" ) print ( f \"Iterations: { iterations } \" ) # \u8fd0\u884c\u7ed3\u679c\uff1a # Problem Size: 1000 # Iterations: 10 \u5728\u95ee\u9898\u89c4\u6a21\u5206\u522b\u4e3a1000\u30012000\u30014000\u300110000\u548c100000\u65f6\uff0c\u8fd0\u884c\u5728\u7ec3\u4e601\u91cc\u6240\u521b\u5efa\u7684\u7a0b\u5e8f\u3002\u5f53\u95ee\u9898\u89c4\u6a21\u7ffb\u500d\u6216\u662f\u4e58\u4ee510\u65f6\uff0c\u8fed\u4ee3\u6b21\u6570\u4f1a\u5982\u4f55\u53d8\u5316\uff1f \u89e3\u7b54\uff1a\u5206\u522b\u4ee5\u4e0d\u540c\u7684\u95ee\u9898\u89c4\u6a21\u8fd0\u884c\u4e0a\u9762\u7684\u4ee3\u7801\uff0c\u7ed3\u679c\u5982\u4e0b\uff1a Problem Size : 1000 Iterations : 10 Problem Size : 4000 Iterations : 12 Problem Size : 8000 Iterations : 13 Problem Size : 10000 Iterations : 14 Problem Size : 100000 Iterations : 17 \u4e24\u6b21\u8c03\u7528\u51fd\u6570 time.time() \u7684\u7ed3\u679c\u4e4b\u5dee\u5c31\u662f\u8fd0\u884c\u65f6\u3002\u7531\u4e8e\u64cd\u4f5c\u7cfb\u7edf\u4e5f\u53ef\u80fd\u4f1a\u5728\u8fd9\u6bb5\u65f6\u95f4\u5185\u4f7f\u7528CPU\uff0c\u56e0\u6b64\u8fd9\u4e2a\u8fd0\u884c\u65f6\u53ef\u80fd\u5e76\u4e0d\u80fd\u53cd\u6620\u51faPython\u4ee3\u7801\u4f7f\u7528CPU\u7684\u5b9e\u9645\u65f6\u95f4\u3002\u6d4f\u89c8Python\u6587\u6863\uff0c\u627e\u51fa\u53e6\u4e00\u79cd\u53ef\u4ee5\u5b8c\u6574\u8bb0\u5f55\u5904\u7406\u65f6\u95f4\u7684\u65b9\u6cd5\uff0c\u5e76\u63cf\u8ff0\u5982\u4f55\u5b9e\u73b0\u5b83\u3002 \u89e3\u7b54\uff1a \u5728Python\u4e2d\uff0c time \u6a21\u5757\u63d0\u4f9b\u4e86\u66f4\u7cbe\u786e\u7684\u8ba1\u65f6\u529f\u80fd\uff0c\u5176\u4e2d\u7684 time.perf_counter() \u51fd\u6570\u53ef\u4ee5\u7528\u6765\u6d4b\u91cf\u65f6\u95f4\u7684\u7cbe\u786e\u95f4\u9694\u3002\u4e0e time.time() \u4e0d\u540c\uff0c time. perf_counter() \u4f1a\u5728\u5927\u591a\u6570\u5e73\u53f0\u4e0a\u63d0\u4f9b\u4e00\u4e2a\u66f4\u9ad8\u5206\u8fa8\u7387\u7684\u8ba1\u65f6\u5668\uff0c\u53ef\u4ee5\u7528\u6765\u6d4b\u91cf\u4ee3\u7801\u5757\u7684\u6267\u884c\u65f6\u95f4\u3002 time.perf_counter() \u8fd4\u56de\u4e00\u4e2a\u6d6e\u70b9\u6570\uff0c\u8868\u793a\u4ece\u67d0\u4e2a\u7279\u5b9a\u65f6\u95f4\u70b9\u5230\u73b0\u5728\u7ecf\u8fc7\u7684\u79d2\u6570\u3002\u4ee5\u4e0b\u662f\u5982\u4f55\u4f7f\u7528 time.perf_counter() \u6765\u8ba1\u7b97\u4ee3\u7801\u5757\u7684\u6267\u884c\u65f6\u95f4\uff1a import time # \u83b7\u53d6\u8d77\u59cb\u65f6\u95f4\uff08\u5305\u62ecCPU\u65f6\u95f4\u548c\u7cfb\u7edf\u65f6\u95f4\uff09 start_cpu_time = time . process_time () start_real_time = time . perf_counter () start_system_time = time . time () # \u6267\u884c\u4ee3\u7801 for i in range ( 100000000 ): _ = i * i # \u83b7\u53d6\u7ed3\u675f\u65f6\u95f4\uff08\u5305\u62ecCPU\u65f6\u95f4\u548c\u7cfb\u7edf\u65f6\u95f4\uff09 end_cpu_time = time . process_time () end_real_time = time . perf_counter () end_system_time = time . time () # \u8ba1\u7b97CPU\u65f6\u95f4\u5dee cpu_execution_time = end_cpu_time - start_cpu_time real_execution_time = end_real_time - start_real_time system_execution_time = end_system_time - start_system_time print ( f \"CPU Execution Time: { cpu_execution_time : .6f } seconds\" ) print ( f \"Real Execution Time: { real_execution_time : .6f } seconds\" ) print ( f \"System Execution Time: { system_execution_time : .6f } seconds\" ) # \u8fd0\u884c\u7ed3\u679c\uff1a # CPU Execution Time: 7.157305 seconds # Real Execution Time: 7.156638 seconds # System Execution Time: 7.156638 seconds \u5728\u4e0a\u9762\u4ee3\u7801\u4e2d\uff0c start_system_time \u548c end_system_time \u5206\u522b\u8bb0\u5f55\u4e86\u4ee3\u7801\u5757\u5f00\u59cb\u548c\u7ed3\u675f\u65f6\u7684\u7cfb\u7edf\u65f6\u95f4\u3002\u7136\u540e\uff0c\u53ef\u4ee5\u901a\u8fc7\u8ba1\u7b97 end_system_time - start_system_time \u6765\u83b7\u53d6\u7cfb\u7edf\u65f6\u95f4\u7684\u6d88\u8017\u3002 \u7cfb\u7edf\u65f6\u95f4\u7684\u8ba1\u7b97\u53ef\u80fd\u53d7\u5230\u7cfb\u7edf\u7684\u5f71\u54cd\uff0c\u53ef\u80fd\u4f1a\u56e0\u4e3a\u7cfb\u7edf\u65f6\u95f4\u7684\u53d8\u5316\u800c\u4ea7\u751f\u4e0d\u51c6\u786e\u7684\u7ed3\u679c\u3002\u5728\u8fdb\u884c\u6027\u80fd\u6d4b\u8bd5\u65f6\uff0c\u5c3d\u91cf\u4ee5CPU\u65f6\u95f4\u548c\u5b9e\u9645\u7ecf\u8fc7\u65f6\u95f4\u4e3a\u4e3b\u8981\u53c2\u8003\u6307\u6807\u3002 \u8865\u5145\uff1a CPU \u65f6\u95f4\u3001\u5b9e\u9645\u7ecf\u8fc7\u65f6\u95f4\u548c\u7cfb\u7edf\u65f6\u95f4\u4ee3\u8868\u4e86\u4e0d\u540c\u7684\u65f6\u95f4\u6307\u6807\uff0c\u5b83\u4eec\u4e4b\u95f4\u6709\u4ee5\u4e0b\u533a\u522b\uff1a CPU \u65f6\u95f4\uff1a - CPU \u65f6\u95f4\u662f\u7a0b\u5e8f\u5728 CPU \u4e0a\u6267\u884c\u7684\u65f6\u95f4\uff0c\u5305\u62ec\u4e86\u5728\u7528\u6237\u6001\uff08\u6267\u884c\u5e94\u7528\u7a0b\u5e8f\u4ee3\u7801\uff09\u548c\u5185\u6838\u6001\uff08\u6267\u884c\u64cd\u4f5c\u7cfb\u7edf\u4ee3\u7801\uff09\u7684\u65f6\u95f4\u3002\u56e0\u6b64\uff0c\u5b83\u8003\u8651\u4e86\u5e94\u7528\u7a0b\u5e8f\u548c\u64cd\u4f5c\u7cfb\u7edf\u7684\u6267\u884c\u65f6\u95f4\u3002 - CPU \u65f6\u95f4\u901a\u5e38\u7528\u4e8e\u6d4b\u91cf\u7a0b\u5e8f\u7684\u8ba1\u7b97\u5bc6\u96c6\u578b\u5de5\u4f5c\u91cf\uff0c\u5373\u5927\u91cf\u8ba1\u7b97\u64cd\u4f5c\uff0c\u6bd4\u5982\u5faa\u73af\u548c\u6570\u5b66\u8ba1\u7b97\u3002 - \u901a\u8fc7 time.process_time() \u51fd\u6570\u53ef\u4ee5\u83b7\u53d6\u5f53\u524d\u8fdb\u7a0b\u7684 CPU \u65f6\u95f4\u3002 \u5b9e\u9645\u7ecf\u8fc7\u65f6\u95f4\uff1a - \u5b9e\u9645\u7ecf\u8fc7\u65f6\u95f4\u662f\u4ece\u67d0\u4e2a\u65f6\u95f4\u70b9\u5230\u73b0\u5728\u7684\u5b9e\u9645\u7ecf\u8fc7\u7684\u65f6\u95f4\uff0c\u8003\u8651\u4e86\u6240\u6709\u56e0\u7d20\uff0c\u5305\u62ec\u4e86 CPU \u65f6\u95f4\u3001\u7b49\u5f85\u65f6\u95f4\u3001\u7cfb\u7edf\u8c03\u5ea6\u7b49\u3002 - \u5b9e\u9645\u7ecf\u8fc7\u65f6\u95f4\u7528\u4e8e\u6d4b\u91cf\u4ee3\u7801\u7684\u603b\u6267\u884c\u65f6\u95f4\uff0c\u5305\u62ec\u4e86\u8ba1\u7b97\u548c\u7b49\u5f85\u7684\u65f6\u95f4\u3002 - \u901a\u8fc7 time.perf_counter() \u51fd\u6570\u53ef\u4ee5\u83b7\u53d6\u5f53\u524d\u65f6\u95f4\u3002 \u7cfb\u7edf\u65f6\u95f4\uff1a - \u7cfb\u7edf\u65f6\u95f4\u662f\u64cd\u4f5c\u7cfb\u7edf\u5185\u90e8\u7ef4\u62a4\u7684\u4e00\u4e2a\u65f6\u95f4\u503c\uff0c\u5b83\u4ee3\u8868\u4e86\u4ece\u67d0\u4e2a\u56fa\u5b9a\u65f6\u95f4\u70b9\u5f00\u59cb\u7684\u79d2\u6570\u3002 - \u7cfb\u7edf\u65f6\u95f4\u901a\u5e38\u7528\u4e8e\u8bb0\u5f55\u4e8b\u4ef6\u548c\u8ba1\u7b97\u65f6\u95f4\u95f4\u9694\uff0c\u4e0d\u53d7\u7a0b\u5e8f\u7684\u6267\u884c\u5f71\u54cd\u3002 - \u901a\u8fc7 time.time() \u51fd\u6570\u53ef\u4ee5\u83b7\u53d6\u5f53\u524d\u7684\u7cfb\u7edf\u65f6\u95f4\u3002 \u603b\u7ed3\uff1aCPU \u65f6\u95f4\u5173\u6ce8\u7684\u662f\u7a0b\u5e8f\u5728 CPU \u4e0a\u7684\u6267\u884c\u65f6\u95f4\uff0c\u5b9e\u9645\u7ecf\u8fc7\u65f6\u95f4\u5173\u6ce8\u7684\u662f\u4ece\u4ee3\u7801\u5f00\u59cb\u5230\u7ed3\u675f\u6240\u7ecf\u8fc7\u7684\u771f\u5b9e\u65f6\u95f4\uff0c\u7cfb\u7edf\u65f6\u95f4\u662f\u7cfb\u7edf\u7ef4\u62a4\u7684\u5168\u5c40\u65f6\u95f4\u3002\u5728\u4e0d\u540c\u7684\u573a\u666f\u4e2d\uff0c\u4f60\u53ef\u4ee5\u6839\u636e\u9700\u8981\u9009\u62e9\u5408\u9002\u7684\u65f6\u95f4\u6307\u6807\u6765\u8fdb\u884c\u6027\u80fd\u6d4b\u91cf\u548c\u5206\u6790\u3002","title":"3.1.4.\u7ec3\u4e60\u9898"},{"location":"python/DataStructure/03_TimeComplexity/#32","text":"\u590d\u6742\u5ea6\u5206\u6790\uff08complexity analysis\uff09\u65b9\u6cd5\uff0c\u4e00\u79cd\u8bc4\u4f30\u7b97\u6cd5\u6548\u7387\u7684\u65b9\u6cd5\uff0c\u8fd9\u4e2a\u65b9\u6cd5\u53ef\u4ee5\u4e0d\u7528\u5173\u5fc3\u4e0e\u5e73\u53f0\u76f8\u5173\u7684\u65f6\u95f4\uff0c\u4e5f\u4e0d\u9700\u8981\u4f7f\u7528\u7edf\u8ba1\u6307\u4ee4\u6570\u91cf\u8fd9\u79cd\u65b9\u6cd5\u6765\u5bf9\u7b97\u6cd5\u8fdb\u884c\u8bc4\u4f30\u3002","title":"3.2.\u590d\u6742\u5ea6\u5206\u6790"},{"location":"python/DataStructure/03_TimeComplexity/#321","text":"\u5728 3.1.2.\u7edf\u8ba1\u6307\u4ee4\u6570 \u4e2d\u5173\u4e8e\u8fed\u4ee3\u6b21\u6570\u548c\u95ee\u9898\u89c4\u6a21\u7684\u4e24\u4e2a\u7b97\u6cd5\uff0c\u5b83\u4eec\u590d\u6742\u5ea6\u7684\u9636\uff08order of complexity\uff09\u4e0a\u662f\u4e0d\u4e00\u6837\u7684\u3002 \u7b2c\u4e00\u4e2a\u7b97\u6cd5\u4e2d\uff0c\u8fed\u4ee3\u6b21\u6570\u548c\u95ee\u9898\u89c4\u6a21\u4e4b\u95f4\u662f\u7ebf\u6027\u5173\u7cfb\uff0c\u79f0\u5176\u590d\u6742\u5ea6\u4e3a\u7ebf\u6027\uff08linear\uff09\u9636\uff1b \u7b2c\u4e8c\u4e2a\u7b97\u6cd5\u4e2d\uff0c\u8fed\u4ee3\u6b21\u6570\u548c\u95ee\u9898\u89c4\u6a21\u4e4b\u95f4\u662f\u5e73\u65b9\u5173\u7cfb\uff0c\u79f0\u5176\u590d\u6742\u5ea6\u4e3a\u5e73\u65b9\uff08quadratic\uff09\u9636\uff1b \u5982\u679c\u7b97\u6cd5\u9700\u8981\u76f8\u540c\u6570\u91cf\u7684\u8fd0\u7b97\uff0c\u90a3\u4e48\u5b83\u7684\u6027\u80fd\u5c31\u662f\u5e38\u6570\uff08constant\uff09\u9636\u3002\u5217\u8868\u7d22\u5f15\u5c31\u662f\u4e00\u4e2a\u5e38\u6570\u65f6\u95f4\u7b97\u6cd5\u7684\u4f8b\u5b50\u3002 \u6bd4\u7ebf\u6027\u6027\u80fd\u597d\uff0c\u4f46\u6bd4\u5e38\u6570\u6027\u80fd\u5dee\u7684\u53e6\u4e00\u4e2a\u590d\u6742\u5ea6\u7684\u9636\u88ab\u79f0\u4e3a\u5bf9\u6570\uff08logarithmic\uff09\u9636\u3002\u5bf9\u6570\u7b97\u6cd5\u7684\u5de5\u4f5c\u91cf\u4e0e\u95ee\u9898\u89c4\u6a21\u7684\u4ee52\u4e3a\u5e95\u7684\u5bf9\u6570\u6210\u6b63\u6bd4\u3002\u5f53\u95ee\u9898\u89c4\u6a21\u6269\u5927\u4e00\u500d\u65f6\uff0c\u5de5\u4f5c\u91cf\u53ea\u4f1a\u52a01\u3002 \u591a\u9879\u5f0f\u65f6\u95f4\u7b97\u6cd5\uff08polynomial time algorithm\uff09\u7684\u5de5\u4f5c\u91cf\u4f1a\u4ee5 n^k \u7684\u901f\u7387\u589e\u957f\uff0c\u5176\u4e2d k \u662f\u5927\u4e8e 1 \u7684\u5e38\u6570\uff0c\u6bd4\u5982 n^2 \u3001 n^3 \u4ee5\u53ca n^10 \u3002\u4ece\u67d0\u79cd\u610f\u4e49\u4e0a\u8bb2\uff0c n^3 \u7684\u6027\u80fd\u8981\u6bd4 n^2 \u5dee\uff0c\u4f46\u90fd\u5c5e\u4e8e\u591a\u9879\u5f0f\uff08polynomial\uff09\u9636\u3002 \u6bd4\u591a\u9879\u5f0f\u8fd8\u8981\u5dee\u7684\u590d\u6742\u5ea6\u7684\u9636\u88ab\u79f0\u4e3a\u6307\u6570\uff08exponential\uff09\u9636\uff0c\u6bd4\u5982 2^n \u3002\u5bf9\u4e8e\u5927\u7684\u95ee\u9898\u89c4\u6a21\u6765\u8bf4\uff0c\u6307\u6570\u7b97\u6cd5\u662f\u4e0d\u53ef\u884c\u7684\u3002 \u4e0d\u540c\u590d\u6742\u5ea6\u9636\u7684\u7b97\u6cd5\u7684\u5de5\u4f5c\u91cf\u6bd4\u8f83\uff08\u4ece\u5c0f\u5230\u5927\uff09\uff1a\u5bf9\u6570\u9636 < \u7ebf\u6027\u9636 < \u5e73\u65b9\u9636 < \u6307\u6570\u9636\u3002\u968f\u7740\u95ee\u9898\u89c4\u6a21\u7684\u589e\u5927\uff0c\u5177\u6709\u8f83\u9ad8\u590d\u6742\u5ea6\u7684\u9636\u7684\u7b97\u6cd5\u7684\u6027\u80fd\u4f1a\u66f4\u5feb\u5730\u53d8\u5dee\u3002","title":"3.2.1.\u590d\u6742\u5ea6\u7684\u9636"},{"location":"python/DataStructure/03_TimeComplexity/#322o","text":"\u5f88\u591a\u60c5\u51b5\u4e0b\uff0c\u7b97\u6cd5\u4e2d\u7684\u5de5\u4f5c\u91cf\u901a\u5e38\u662f\u591a\u9879\u5f0f\u91cc\u591a\u9879\u7684\u603b\u548c\uff0c\u800c\u5f53\u5de5\u4f5c\u91cf\u8868\u793a\u4e3a\u591a\u9879\u5f0f\u65f6\uff0c\u5176\u4e2d\u4e00\u9879\u662f\u4e3b\u5bfc\u9879\uff08dominant\uff09\u3002\u968f\u7740 n \u8d8a\u6765\u8d8a\u5927\uff0c\u4e3b\u5bfc\u9879\u5c06\u53d8\u5f97\u975e\u5e38\u5927\uff0c\u4ee5\u81f3\u4e8e\u53ef\u4ee5\u5ffd\u7565\u5176\u4ed6\u9879\u6240\u4ee3\u8868\u7684\u5de5\u4f5c\u91cf\u3002\u56e0\u6b64\uff0c\u5bf9\u4e8e\u591a\u9879\u5f0f n^2+n \uff0c\u53ea\u9700\u8981\u7740\u91cd\u8003\u8651\u5e73\u65b9\u9879 n^2 \uff0c\u4e5f\u5c31\u662f\u5728\u8003\u8651\u7684\u65f6\u5019\u53ef\u4ee5\u5ffd\u7565\u7ebf\u6027\u9879 n \u3002\u968f\u7740 n^2 \u53d8\u5f97\u975e\u5e38\u5927\uff0c\u591a\u9879\u5f0f\u7684\u503c\u6e10\u8fd1\u5730\u63a5\u8fd1\u6216\u8fd1\u4f3c\u4e8e\u5b83\u7684\u6700\u5927\u9879\u503c\uff0c\u8fd9\u79cd\u5f62\u5f0f\u7684\u5206\u6790\u6709\u65f6\u88ab\u79f0\u4e3a\u6e10\u8fd1\u5206\u6790\uff08asymptotic analysis\uff09\u3002 \u8ba1\u7b97\u4e2d\u7528\u6765\u8868\u793a\u7b97\u6cd5\u7684\u6548\u7387\u6216\u8ba1\u7b97\u590d\u6742\u5ea6\u7684\u4e00\u79cd\u65b9\u6cd5\u88ab\u79f0\u4e3a\u5927O\u8868\u793a\u6cd5\uff08big-O notation\uff09\u3002\u201cO\u201d\u4ee3\u8868\u201c\u5728\u2026\u2026\u9636\u201d\uff0c\u6307\u7684\u662f\u7b97\u6cd5\u5de5\u4f5c\u7684\u590d\u6742\u5ea6\u7684\u9636\u3002\u4f8b\u5982\uff1a \u5e38\u6570\u65f6\u95f4\uff1aO(1) \u7ebf\u6027\u65f6\u95f4\uff1aO(n) \u5e73\u65b9\u65f6\u95f4\uff1aO(n^2) \u7acb\u65b9\u65f6\u95f4\uff1aO(n^3) \u591a\u9879\u5f0f\u65f6\u95f4\uff1aO(n^k)","title":"3.2.2.\u5927O\u8868\u793a\u6cd5"},{"location":"python/DataStructure/03_TimeComplexity/#323","text":"\u6bd4\u4f8b\u5e38\u6570\uff08constant of proportionality\uff09\u5305\u542b\u5728\u5927O\u5206\u6790\u4e2d\u88ab\u5ffd\u7565\u7684\u9879\u548c\u7cfb\u6570\u3002\u6bd4\u5982\uff0c\u7ebf\u6027\u65f6\u95f4\u7b97\u6cd5\u6240\u6267\u884c\u7684\u5de5\u4f5c\u91cf\u53ef\u4ee5\u8868\u793a\u4e3a\uff1a work = 2 * size \uff0c\u5176\u4e2d\u6bd4\u4f8b\u5e38\u6570\u5c31\u662f work/size \uff0c\u4e5f\u5c31\u662f 2 \u3002\u5728\u5904\u7406\u4e2d\u5c0f\u578b\u6570\u636e\u96c6\u7684\u65f6\u5019\uff0c\u5982\u679c\u8fd9\u4e9b\u5e38\u6570\u5f88\u5927\uff0c\u90a3\u4e48\u5b83\u4eec\u4e5f\u4f1a\u5f71\u54cd\u5230\u7b97\u6cd5\u6548\u7387\u3002 \u56de\u987e\u4e0b\u9762\u7684\u4f8b\u5b50\u3002 import time problemSize = 10000000 print ( \" %12s%16s \" % ( \"Problem Size\" , \"Seconds\" )) for count in range ( 5 ): number = 0 # \u7b97\u6cd5\u5f00\u59cb work = 1 for x in range ( problemSize ): number += 1 work += 1 work -= 1 # \u7b97\u6cd5\u7ed3\u675f print ( \" %12d%16.3f \" % ( problemSize , Iterations )) problemSize *= 2 # \u8fd0\u884c\u7ed3\u679c\uff1a # Problem Size Iterations # 10000000 10000000.000 # 20000000 20000000.000 # 40000000 40000000.000 # 80000000 80000000.000 # 160000000 160000000.000 \u5176\u4e2d\u7684\u7b97\u6cd5\u90e8\u5206\uff0c\u9664\u4e86\u5faa\u73af\u8bed\u53e5\u672c\u8eab\uff0c\u8fd8\u6709\u5176\u4ed63\u884c\u4ee3\u7801\uff0c\u5b83\u4eec\u90fd\u662f\u590d\u5236\u8bed\u53e5\uff0c\u90fd\u4f1a\u4ee5\u5e38\u6570\u65f6\u95f4\u8fd0\u884c\u3002\u5047\u8bbe\u5faa\u73af\u8bed\u53e5\u672c\u8eab\u4f1a\u6d88\u8017\u4e00\u4e2a\u65f6\u95f4\u5e38\u6570\uff0c\u90a3\u4e48\u8fd9\u4e2a\u7b97\u6cd5\u7684\u62bd\u8c61\u5de5\u4f5c\u65f6\u95f4\u5c31\u662f 3n+1 \u3002\u867d\u7136 3n+1 \u7684\u5de5\u4f5c\u91cf\u5927\u4e8e n \uff0c\u4f46\u4e8c\u8005\u5728\u8fd0\u884c\u65f6\u90fd\u662f\u7ebf\u6027\u589e\u52a0\uff0c\u6240\u4ee5\u4ed6\u4eec\u8fd0\u884c\u65f6\u90fd\u662f O(n) \u3002 # \u7b97\u6cd5\u5f00\u59cb work = 1 for x in range ( problemSize ): number += 1 work += 1 work -= 1 # \u7b97\u6cd5\u7ed3\u675f","title":"3.2.3.\u6bd4\u4f8b\u5e38\u6570\u7684\u4f5c\u7528"},{"location":"python/DataStructure/03_TimeComplexity/#324","text":"\u5047\u8bbe\u4e0b\u9762\u7684\u8868\u8fbe\u5f0f\u90fd\u5206\u522b\u8868\u793a\u5bf9\u95ee\u9898\u89c4\u6a21\u4e3a n \u7684\u7b97\u6cd5\u6240\u9700\u8981\u6267\u884c\u7684\u64cd\u4f5c\u6570\uff0c\u8bf7\u6307\u51fa\u6bcf\u79cd\u7b97\u6cd5\u4e2d\u7684\u4e3b\u5bfc\u9879\uff0c\u5e76\u4f7f\u7528\u5927O\u8868\u793a\u6cd5\u5bf9\u5b83\u8fdb\u884c\u5206\u7c7b\u3002 a. 2^n - 4n + 5n b. 2n^2 + 8 c. n^3 n^2 + n \u89e3\u7b54\uff1a a. 2^n\uff0cO(n) b. n 2\uff0cO(n 2) c. n 3\uff0cO(n 3) \u5bf9\u4e8e\u89c4\u6a21\u4e3a n \u7684\u95ee\u9898\uff0c\u7b97\u6cd5A\u548cB\u5206\u522b\u4f1a\u6267\u884c n^2 \u548c (1/2)*n^2+(1/2)*n \u6761\u6307\u4ee4\u3002\u54ea\u79cd\u7b97\u6cd5\u66f4\u9ad8\u6548\uff1f\u6709\u6ca1\u6709\u4e00\u79cd\u7b97\u6cd5\u6bd4\u53e6\u4e00\u79cd\u7b97\u6cd5\u6027\u80fd\u660e\u663e\u66f4\u597d\u7684\u7279\u5b9a\u7684\u95ee\u9898\u89c4\u6a21\uff1f\u662f\u5426\u6709\u8ba9\u4e24\u79cd\u7b97\u6cd5\u90fd\u6267\u884c\u5927\u81f4\u76f8\u540c\u5de5\u4f5c\u91cf\u7684\u7279\u5b9a\u7684\u95ee\u9898\u89c4\u6a21\uff1f \u89e3\u7b54\uff1a \u5728\u6bd4\u8f83\u4e24\u79cd\u7b97\u6cd5\u7684\u6548\u7387\u65f6\uff0c\u901a\u5e38\u5173\u6ce8\u7b97\u6cd5\u6267\u884c\u65f6\u95f4\u968f\u95ee\u9898\u89c4\u6a21\u589e\u957f\u7684\u8d8b\u52bf\u3002\u9898\u76ee\u4e2d\u7684\u4e24\u79cd\u7b97\u6cd5\u7684\u6267\u884c\u6307\u4ee4\u6570\u5206\u522b\u5982\u4e0b\uff1a \u7b97\u6cd5A\uff1a\u6267\u884c n^2 \u6761\u6307\u4ee4\u3002 \u7b97\u6cd5B\uff1a\u6267\u884c (1/2)*n^2+(1/2)*n \u6761\u6307\u4ee4\u3002 \u7528\u5982\u4e0b\u4ee3\u7801\u6a21\u62df\u7b97\u6cd5A\u548c\u7b97\u6cd5B\uff0c\u53ef\u4ee5\u770b\u51fa\uff0c\u968f\u7740 n \u7684\u589e\u52a0\uff0c\u7b97\u6cd5A\u7684\u589e\u957f\u901f\u7387\u8fdc\u5927\u4e8e\u7b97\u6cd5B\u3002\u6240\u4ee5\u53ef\u4ee5\u8ba4\u4e3a\u5728 n >= 2 \u7684\u60c5\u51b5\u4e0b\uff0c\u7b97\u6cd5A\u4f18\u4e8e\u7b97\u6cd5B\u3002 n = 1 print ( \" %-15s%25s \" % ( \"ProblemSize: n\" , \"A/B\" )) while n < 1000000 : n *= 10 print ( \" %-15d%25d \" % ( n , int (( n ** 2 ) / ( 1 / 2 ) * n ** 2 + ( 1 / 2 ) * n ))) # ProblemSize: n A/B # 10 20005 # 100 200000050 # 1000 2000000000500 # 10000 20000000000005000 # 100000 200000000000000065536 # 1000000 1999999999999999966445568 \u7531\u6b64\u53ef\u5f97\uff0c\u5728\u5927\u95ee\u9898\u89c4\u6a21\u4e0b\uff0c\u7b97\u6cd5B\u7684\u589e\u957f\u901f\u7387\u4f1a\u66f4\u6162\uff0c\u56e0\u4e3a (1/2)*n^2+(1/2)*n \u4e2d\u7684 (1/2)*n \u90e8\u5206\u5bf9\u4e8e\u6574\u4f53\u589e\u957f\u6765\u8bf4\u76f8\u5bf9\u8f83\u5c0f\u3002 \u4e3a\u4e86\u8ba9\u4e24\u79cd\u7b97\u6cd5\u6267\u884c\u76f8\u8fd1\u7684\u5de5\u4f5c\u91cf\uff0c\u6211\u4eec\u53ef\u4ee5\u89e3\u4e0b\u9762\u7684\u65b9\u7a0b\uff1a ( 1 / 2 ) * n ^ 2 + ( 1 / 2 ) * n = k * n ^ 2 \u5176\u4e2d k \u662f\u4e00\u4e2a\u5e38\u6570\uff0c\u8868\u793a\u4e24\u79cd\u7b97\u6cd5\u6267\u884c\u7684\u5de5\u4f5c\u91cf\u76f8\u7b49\u65f6\u7684\u95ee\u9898\u89c4\u6a21\u3002\u901a\u8fc7\u89e3\u8fd9\u4e2a\u65b9\u7a0b\uff0c\u6211\u4eec\u53ef\u4ee5\u627e\u5230\u4e00\u4e2a\u95ee\u9898\u89c4\u6a21 k \uff0c\u5728\u8fd9\u4e2a\u95ee\u9898\u89c4\u6a21\u4e0b\uff0c\u4e24\u79cd\u7b97\u6cd5\u7684\u6267\u884c\u6307\u4ee4\u6570\u76f8\u8fd1\u3002 \u7b97\u6cd5\u7684\u6548\u7387\u5206\u6790\u5e76\u4e0d\u4ec5\u4ec5\u53d6\u51b3\u4e8e\u6307\u4ee4\u6570\uff0c\u8fd8\u53ef\u80fd\u53d7\u5230\u7b97\u6cd5\u4e2d\u5e38\u6570\u56e0\u5b50\u3001\u6570\u636e\u8bbf\u95ee\u6a21\u5f0f\u3001\u5185\u5b58\u5360\u7528\u7b49\u56e0\u7d20\u7684\u5f71\u54cd\u3002\u56e0\u6b64\uff0c\u5728\u5b9e\u9645\u5e94\u7528\u4e2d\uff0c\u901a\u5e38\u9700\u8981\u7efc\u5408\u8003\u8651\u591a\u4e2a\u56e0\u7d20\u6765\u786e\u5b9a\u6700\u4f18\u7684\u7b97\u6cd5\u9009\u62e9\u3002 \u5728\u4ec0\u4e48\u65f6\u5019\u5f00\u59cb n^4 \u7b97\u6cd5\u6bd4 2^n \u7b97\u6cd5\u8868\u73b0\u66f4\u597d\uff1f \u89e3\u7b54\uff1a\u7528\u4e0b\u9762\u7684\u7b97\u6cd5\u6a21\u62df n^4 \u7b97\u6cd5\u6bd4 2^n \u7b97\u6cd5\u6267\u884c\u5de5\u4f5c\u91cf\u3002\u4ece\u8fd0\u884c\u7ed3\u679c\u53ef\u4ee5\u770b\u51fa\uff1a n=16 \u662f\u5206\u754c\u70b9\uff0c n^4 \u7b97\u6cd5\u4e0e 2^n \u7b97\u6cd5\u5de5\u4f5c\u91cf\u76f8\u7b49\uff1b \u5f53 n<16 \u65f6\uff0c n^4 \u7b97\u6cd5\u6bd4 2^n \u7b97\u6cd5\u5de5\u4f5c\u91cf\u8981\u9ad8\uff1b \u5f53 n>16 \u65f6\uff0c n^4 \u7b97\u6cd5\u6bd4 2^n \u7b97\u6cd5\u5de5\u4f5c\u91cf\u8981\u4f4e\uff1b\u800c\u4e14 2^n \u7b97\u6cd5\u5de5\u4f5c\u91cf\u589e\u957f\u901f\u5ea6\u8fdc\u5927\u4e8e n^4 \u7b97\u6cd5\uff1b n = 1 print ( \" %-8s%10s%15s%10s \" % ( \"Size:n\" , \"A:n^4\" , \"B:2^n\" , \"B/A\" )) while n < 30 : n += 1 print ( \" %-8d%10d%15d%10.3f \" % ( n , int ( n ** 4 ), int ( 2 ** n ), ( 2 ** n ) / ( n ** 4 ))) # \u8fd0\u884c\u7ed3\u679c\uff1a # Size:n A:n^4 B:2^n B/A # 2 16 4 0.250 # 3 81 8 0.099 # 4 256 16 0.062 # 5 625 32 0.051 # 6 1296 64 0.049 # 7 2401 128 0.053 # 8 4096 256 0.062 # 9 6561 512 0.078 # 10 10000 1024 0.102 # 11 14641 2048 0.140 # 12 20736 4096 0.198 # 13 28561 8192 0.287 # 14 38416 16384 0.426 # 15 50625 32768 0.647 # 16 65536 65536 1.000 # 17 83521 131072 1.569 # 18 104976 262144 2.497 # 19 130321 524288 4.023 # 20 160000 1048576 6.554 # 21 194481 2097152 10.783 # 22 234256 4194304 17.905 # 23 279841 8388608 29.976 # 24 331776 16777216 50.568 # 25 390625 33554432 85.899 # 26 456976 67108864 146.854 # 27 531441 134217728 252.554 # 28 614656 268435456 436.725 # 29 707281 536870912 759.063 # 30 810000 1073741824 1325.607","title":"3.2.4.\u7ec3\u4e60\u9898"},{"location":"python/DataStructure/03_TimeComplexity/#33","text":"\u7ea6\u5b9a\uff1a \u4ee5\u5217\u8868\u4e3a\u4f8b\uff0c\u4ecb\u7ecd\u641c\u7d22\u548c\u6392\u5e8f\u7684\u7b97\u6cd5\uff1b \u9610\u91ca\u8fd9\u4e9b\u7b97\u6cd5\u7684\u8bbe\u8ba1\uff0c\u5e76\u628a\u5b83\u5b9e\u73b0\u4e3aPython\u51fd\u6570\uff1b \u51fd\u6570\u53ea\u5904\u7406\u5168\u90e8\u662f\u6574\u6570\u7684\u5217\u8868\uff0c\u4e0d\u540c\u5927\u5c0f\u7684\u5217\u8868\u5c06\u4f5c\u4e3a\u53c2\u6570\u4f20\u9012\u7ed9\u51fd\u6570\uff1b \u5bf9\u8fd9\u4e9b\u7b97\u6cd5\u7684\u8ba1\u7b97\u590d\u6742\u5ea6\u8fdb\u884c\u5206\u6790\uff1b","title":"3.3.\u641c\u7d22\u7b97\u6cd5"},{"location":"python/DataStructure/03_TimeComplexity/#331","text":"Python\u4e2d\u6709 min \u51fd\u6570\uff0c\u4f1a\u8fd4\u56de\u5217\u8868\u91cc\u7684\u6700\u5c0f\u503c\u6216\u6700\u5c0f\u5143\u7d20\uff0c\u4e0b\u9762\u5199\u4e00\u4e2a\u65b0\u7b97\u6cd5\uff0c\u6765\u5206\u6790 min \u51fd\u6570\u7684\u7b97\u6cd5\u590d\u6742\u5ea6\u3002 \u7b97\u6cd5\u76ee\u6807\uff1a\u5047\u5b9a\u5217\u8868\u4e0d\u4e3a\u7a7a\uff0c\u5e76\u4e14\u5143\u7d20\u662f\u6309\u7167\u4efb\u610f\u987a\u5e8f\u5b58\u653e\u5728\u5217\u8868\u91cc\u7684\uff0c\u7b97\u6cd5\u8fd4\u56de\u6700\u5c0f\u5143\u7d20\u7684\u7d22\u5f15\uff08index\uff09\u3002 \u7b97\u6cd5\u89e3\u6790\uff1a \u9996\u5148\u628a\u7b2c\u4e00\u4e2a\u4f4d\u7f6e\u4f5c\u4e3a\u5b58\u653e\u6700\u5c0f\u5143\u7d20\u7684\u4f4d\u7f6e\uff1b \u7136\u540e\u5411\u53f3\u4fa7\u641c\u7d22\u66f4\u5c0f\u7684\u5143\u7d20\uff1b \u5982\u679c\u627e\u5230\uff0c\u90a3\u4e48\u628a\u6700\u5c0f\u5143\u7d20\u7684\u4f4d\u7f6e\u91cd\u7f6e\u4e3a\u5f53\u524d\u4f4d\u7f6e\uff1b \u5f53\u7b97\u6cd5\u5230\u8fbe\u5217\u8868\u672b\u5c3e\u65f6\uff0c\u5b83\u5c06\u8fd4\u56de\u6700\u5c0f\u5143\u7d20\u7684\u4f4d\u7f6e\u3002 \u7b97\u6cd5\u5b9e\u73b0\uff1a def indexOfMin ( lyst ): \"\"\"\u8fd4\u56de\u6700\u5c0f\u5143\u7d20\u7684\u7d22\u5f15\uff0c\u76f8\u540c\u6700\u5c0f\u5143\u7d20\u8fd4\u56de\u7b2c\u4e00\u4e2a\u7d22\u5f15\"\"\" # \u7b97\u6cd5\u5f00\u59cb minIndex = 0 currentIndex = 1 while currentIndex < len ( lyst ): if lyst [ currentIndex ] < lyst [ minIndex ]: # \u6539\u6210<=\uff0c\u76f8\u540c\u6700\u5c0f\u5143\u7d20\u5219\u8fd4\u56de\u6700\u540e\u4e00\u4e2a\u7d22\u5f15 minIndex = currentIndex currentIndex += 1 return minIndex # \u7b97\u6cd5\u7ed3\u675f def main (): myList = [ 2 , 20 , 5 , 0 , 1 , 0 , 9 ] minIndex = indexOfMin ( myList ) print ( minIndex , myList [ minIndex ]) if __name__ == \"__main__\" : main () # \u8fd0\u7b97\u7ed3\u679c\uff1a # 3 0 # \u5982\u679c\u6539\u6210\u6539\u6210yst[currentIndex] <= lyst[minIndex]\uff0c\u5219\u76f8\u540c\u6700\u5c0f\u5143\u7d20\u5219\u8fd4\u56de\u6700\u540e\u4e00\u4e2a\u7d22\u5f15 # 5 0 \u65e0\u8bba\u5217\u8868\u7684\u5927\u5c0f\u5982\u4f55\uff0c\u5faa\u73af\u5916\u76843\u6761\u6307\u4ee4\uff082\u6761\u8d4b\u503c\u8bed\u53e5\uff0c\u4e00\u6761while\u8bed\u53e5\u672c\u8eab\uff09\u90fd\u4f1a\u6267\u884c\u76f8\u540c\u7684\u6b21\u6570\uff0c\u53ef\u4ee5\u5ffd\u7565\u5b83\u4eec\u90fd\u5f71\u54cd\u3002 \u5faa\u73af\u91cc\u8fd8\u67093\u6761\u6307\u4ee4\uff0c\u5176\u4e2d if \u8bed\u53e5\u5185\u7684\u6bd4\u8f83 lyst[currentIndex] < lyst[minIndex] \u548c currentIndex += 1 \u7684\u81ea\u589e\uff0c\u4f1a\u5728\u6bcf\u6b21\u5faa\u73af\u65f6\u90fd\u6267\u884c\uff0c\u4e14\u6ca1\u6709\u5176\u5b83\u5d4c\u5957\u6216\u9690\u85cf\u7684\u5faa\u73af\u3002 if \u8bed\u53e5\u4e2d\u7684\u6bd4\u8f83\u64cd\u4f5c\u5b9e\u73b0\u4e86\u8bbf\u95ee\u5217\u8868\u91cc\u7684\u6bcf\u4e2a\u5143\u7d20\uff0c\u4ece\u800c\u80fd\u591f\u627e\u5230\u6700\u5c0f\u5143\u7d20\u7684\u4f4d\u7f6e\u3002 \u56e0\u6b64\uff0c\u8fd9\u4e2a\u7b97\u6cd5\u5fc5\u987b\u5bf9\u5927\u5c0f\u4e3a n \u7684\u5217\u8868\u8fdb\u884c n-1 \u6b21\u6bd4\u8f83\uff0c\u5373\uff0c\u5b83\u7684\u590d\u6742\u5ea6\u4e3aO(n)\u3002","title":"3.3.1.\u6700\u5c0f\u503c\u641c\u7d22"},{"location":"python/DataStructure/03_TimeComplexity/#332","text":"Python\u7684 in \u8fd0\u7b97\u7b26\u5728list\u7c7b\u91cc\u88ab\u5b9e\u73b0\u4e3a\u53eb\u4f5c __contains__ \u7684\u65b9\u6cd5\uff0c\u8fd9\u4e2a\u65b9\u6cd5\u4f1a\u5728\u4efb\u610f\u7684\u5143\u7d20\u5217\u8868\u91cc\u641c\u7d22\u7279\u5b9a\u7684\u5143\u7d20\uff0c\u5373\u76ee\u6807\u5143\u7d20\uff08target item\uff09\u3002 \u5728\u5217\u8868\u91cc\uff0c\u627e\u5230\u76ee\u6807\u5143\u7d20\u7684\u552f\u4e00\u65b9\u6cd5\u662f\u4ece\u4f4d\u4e8e\u7b2c\u4e00\u4e2a\u4f4d\u7f6e\u7684\u5143\u7d20\u5f00\u59cb\uff0c\u5e76\u628a\u5b83\u548c\u76ee\u6807\u5143\u7d20\u8fdb\u884c\u6bd4\u8f83\u3002\u5982\u679c\u4e24\u4e2a\u5143\u7d20\u76f8\u7b49\uff0c\u90a3\u4e48\u8fd9\u4e2a\u65b9\u6cd5\u8fd4\u56de True \uff1b\u5426\u5219\uff0c\u8fd9\u4e2a\u65b9\u6cd5\u5c06\u79fb\u52a8\u5230\u4e0b\u4e00\u4e2a\u4f4d\u7f6e\uff0c\u5e76\u628a\u5b83\u548c\u76ee\u6807\u5143\u7d20\u8fdb\u884c\u6bd4\u8f83\u3002\u5982\u679c\u8fd9\u4e2a\u65b9\u6cd5\u5230\u4e86\u6700\u540e\u4e00\u4e2a\u4f4d\u7f6e\u4ecd\u7136\u627e\u4e0d\u5230\u76ee\u6807\uff0c\u90a3\u4e48\u8fd4\u56de False \u3002\u8fd9\u79cd\u641c\u7d22\u79f0\u4e3a\u987a\u5e8f\u641c\u7d22\uff08sequential search\uff09\u6216\u7ebf\u6027\u641c\u7d22\uff08linear search\uff09\u3002 \u4e0b\u9762\u662f\u987a\u5e8f\u641c\u7d22\u51fd\u6570\u7684\u5b9e\u73b0\u3002\u82e5\u987a\u5e8f\u641c\u7d22\u7b97\u6cd5\u5728\u5217\u8868\u5f00\u5934\u5c31\u627e\u5230\u76ee\u6807\u5143\u7d20\uff0c\u90a3\u4e48\u8fd9\u65f6\u7684\u5de5\u4f5c\u91cf\u660e\u663e\u4f1a\u6bd4\u5728\u5217\u8868\u672b\u5c3e\u627e\u5230\u7684\u5de5\u4f5c\u91cf\u8981\u5c11\u3002 def sequentialSearch ( target , lyst ): \"\"\"\u627e\u5230\u76ee\u6807\u5143\u7d20\u65f6\u8fd4\u56de\u5143\u7d20\u7684\u7d22\u5f15, \u5426\u5219\u8fd4\u56de-1\"\"\" position = 0 while position < len ( lyst ): if target == lyst [ position ]: return position position += 1 return - 1 def main (): myList = [ 2 , 20 , 5 , 0 , 1 , 0 , 9 ] locatedIndex = sequentialSearch ( 9 , myList ) print ( locatedIndex , myList [ locatedIndex ]) if __name__ == \"__main__\" : main () # \u8fd0\u7b97\u7ed3\u679c\uff1a # 6 9","title":"3.3.2.\u987a\u5e8f\u641c\u7d22\u5217\u8868"},{"location":"python/DataStructure/03_TimeComplexity/#333","text":"\u4e00\u822c\u6765\u8bf4\uff0c\u91cd\u70b9\u5173\u6ce8\u5728\u5e73\u5747\u60c5\u51b5\u548c\u6700\u574f\u60c5\u51b5\u4e0b\u7684\u6027\u80fd\uff0c\u4e0d\u4f1a\u7279\u522b\u5173\u6ce8\u6700\u597d\u60c5\u51b5\u3002 \u5bf9\u987a\u5e8f\u641c\u7d22\u7684\u5206\u6790\u9700\u8981\u8003\u8651\u4e0b\u97623\u79cd\u60c5\u51b5\u3002 \u5728\u6700\u574f\u60c5\u51b5\u4e0b\uff0c\u76ee\u6807\u5143\u7d20\u4f4d\u4e8e\u5217\u8868\u7684\u672b\u5c3e\u6216\u8005\u6839\u672c\u5c31\u4e0d\u5728\u5217\u8868\u91cc\u3002\u8fd9\u65f6\uff0c\u8fd9\u4e2a\u7b97\u6cd5\u5c31\u5fc5\u987b\u8bbf\u95ee\u6bcf\u4e00\u4e2a\u5143\u7d20\uff0c\u5bf9\u5927\u5c0f\u4e3a n \u7684\u5217\u8868\u9700\u8981\u6267\u884c n \u6b21\u8fed\u4ee3\u3002\u56e0\u6b64\uff0c\u987a\u5e8f\u641c\u7d22\u7684\u6700\u574f\u60c5\u51b5\u7684\u590d\u6742\u5ea6\u4e3aO(n)\u3002 \u5728\u6700\u597d\u60c5\u51b5\u4e0b\uff0c\u53ea\u9700\u8981O(1)\u7684\u590d\u6742\u5ea6\uff0c\u56e0\u4e3a\u8fd9\u4e2a\u7b97\u6cd5\u5728\u4e00\u6b21\u8fed\u4ee3\u4e4b\u540e\u5c31\u4f1a\u5728\u7b2c\u4e00\u4e2a\u4f4d\u7f6e\u627e\u5230\u76ee\u6807\u5143\u7d20\u3002 \u8981\u786e\u5b9a\u5e73\u5747\u60c5\u51b5\uff0c\u5c31\u9700\u8981\u628a\u6bcf\u4e2a\u53ef\u80fd\u4f4d\u7f6e\u627e\u5230\u76ee\u6807\u6240\u9700\u8981\u7684\u8fed\u4ee3\u6b21\u6570\u76f8\u52a0\uff0c\u7136\u540e\u518d\u5c06\u5b83\u4eec\u7684\u603b\u548c\u9664\u4ee5 n \u3002\u56e0\u6b64\uff0c\u8fd9\u79cd\u60c5\u51b5\u4e0b\uff0c\u7b97\u6cd5\u4f1a\u6267\u884c (n + n\u22121 + n\u22122+ ... +1)/n \u6216 (n+1)/2 \u6b21\u8fed\u4ee3\u3002\u5bf9\u4e8e\u975e\u5e38\u5927\u7684 n \u6765\u8bf4\uff0c\u5e38\u6570\u7cfb\u65702\u662f\u53ef\u4ee5\u5ffd\u7565\u7684\uff0c\u56e0\u6b64\uff0c\u5e73\u5747\u60c5\u51b5\u7684\u590d\u6742\u5ea6\u4ecd\u7136\u662fO(2)\u3002 \u7ed3\u8bba\uff1a\u6700\u597d\u60c5\u51b5\u4e0b\u987a\u5e8f\u641c\u7d22\u7684\u6027\u80fd\u548c\u5176\u4ed6\u4e24\u79cd\u60c5\u51b5\u6bd4\u8d77\u6765\u5c0f\u5f88\u591a\uff0c\u800c\u5176\u4ed6\u4e24\u79cd\u60c5\u51b5\u4e0b\u7684\u6027\u80fd\u662f\u5dee\u4e0d\u591a\u7684\u3002","title":"3.3.3.\u6700\u597d\u60c5\u51b5\u3001\u6700\u574f\u60c5\u51b5\u4ee5\u53ca\u5e73\u5747\u60c5\u51b5\u4e0b\u7684\u6027\u80fd"},{"location":"python/DataStructure/03_TimeComplexity/#334","text":"\u5728\u6570\u636e\u65e0\u5e8f\u7684\u60c5\u51b5\u4e0b\uff0c\u4f7f\u7528\u987a\u5e8f\u641c\u7d22\u6765\u627e\u5230\u76ee\u6807\u5143\u7d20\u3002 \u5728\u6570\u636e\u6709\u5e8f\u7684\u60c5\u51b5\u4e0b\uff0c\u4f7f\u7528\u4e8c\u5206\u641c\u7d22\u6765\u627e\u5230\u76ee\u6807\u5143\u7d20\u3002 Python\u4e2d\u5b9e\u73b0\u4e8c\u5206\u641c\u7d22\u7684\u601d\u8def\uff1a \u5047\u8bbe\u5217\u8868\u91cc\u7684\u5143\u7d20\u90fd\u4ee5\u5347\u5e8f\u6392\u5e8f\u3002 \u641c\u7d22\u7b97\u6cd5\u9996\u5148\u5230\u5217\u8868\u7684\u4e2d\u95f4\u4f4d\u7f6e\uff0c\u5e76\u628a\u8fd9\u4e2a\u4f4d\u7f6e\u7684\u5143\u7d20\u4e0e\u76ee\u6807\u5143\u7d20\u8fdb\u884c\u6bd4\u8f83\uff1b \u5982\u679c\u5339\u914d\uff0c\u90a3\u4e48\u7b97\u6cd5\u5c31\u8fd4\u56de\u5f53\u524d\u4f4d\u7f6e\u3002\u5982\u679c\u76ee\u6807\u5143\u7d20\u5c0f\u4e8e\u5f53\u524d\u5143\u7d20\uff0c\u90a3\u4e48\u7b97\u6cd5\u5c06\u4f1a\u641c\u7d22\u4e2d\u95f4\u4f4d\u7f6e\u4e4b\u524d\u7684\u90e8\u5206\uff1b \u5982\u679c\u76ee\u6807\u5143\u7d20\u5927\u4e8e\u5f53\u524d\u5143\u7d20\uff0c\u5219\u641c\u7d22\u4e2d\u95f4\u4f4d\u7f6e\u4e4b\u540e\u7684\u90e8\u5206\u3002 \u5728\u627e\u5230\u4e86\u76ee\u6807\u5143\u7d20\u6216\u8005\u5f53\u524d\u5f00\u59cb\u4f4d\u7f6e\u5927\u4e8e\u5f53\u524d\u7ed3\u675f\u4f4d\u7f6e\u65f6\uff0c\u505c\u6b62\u641c\u7d22\u8fc7\u7a0b\u3002 \u4e0b\u9762\u662f\u4e8c\u5206\u641c\u7d22\u51fd\u6570\u7684\u4ee3\u7801\u3002\u4ee5\u5217\u8868 [2, 20, 5, 0, 1, 0, 9] \u4e3a\u4f8b\uff1a \u6392\u5e8f\u540e\u7684\u5217\u8868\u4e3a [0, 0, 1, 2, 5, 9, 20] \uff1b \u6392\u5e8f\u540e\u5217\u8868\u957f\u5ea6\u662f7\uff0c\u6240\u4ee5\u521d\u59cbmidpoint=3\uff0c\u5bf9\u5e94\u5217\u8868\u503c\u662f2\uff1b def binarySearch ( target , sortedLyst ): left = 0 right = len ( sortedLyst ) - 1 while left <= right : midpoint = ( left + right ) // 2 if target == sortedLyst [ midpoint ]: return midpoint elif target < sortedLyst [ midpoint ]: right = midpoint - 1 else : left = midpoint + 1 return - 1 def main (): myList = [ 2 , 20 , 5 , 0 , 1 , 0 , 9 ] sortedList = sorted ( myList ) # \u5982\u679c\u4f7f\u7528myList.sort()\uff0c\u5219\u4f1a\u4fee\u6539myList\u672c\u8eab locatedIndex = binarySearch ( 5 , sortedList ) print ( sortedList ) print ( locatedIndex , sortedList [ locatedIndex ]) if __name__ == \"__main__\" : main () # \u8fd0\u7b97\u7ed3\u679c\uff1a # [0, 0, 1, 2, 5, 9, 20] # 4 5 # \u5982\u679c\u6267\u884cbinarySearch(0, sortedList)\uff0c\u5219\u4f1a\u8fd4\u56de\u7b2c\u4e8c\u4e2a0\u7684\u7d22\u5f15 # [0, 0, 1, 2, 5, 9, 20] # 1 0 \u4e0a\u9762\u4e8c\u5206\u6cd5\u7b97\u6cd5\u590d\u6742\u5ea6\u5206\u6790\uff1a \u7b97\u6cd5\u91cc\u53ea\u6709\u4e00\u4e2a\u5faa\u73af\uff0c\u5e76\u4e14\u6ca1\u6709\u5d4c\u5957\u6216\u9690\u85cf\u7684\u5faa\u73af\u3002\u5982\u679c\u76ee\u6807\u4e0d\u5728\u5217\u8868\u91cc\uff0c\u5c31\u4f1a\u5f97\u5230\u6700\u574f\u60c5\u51b5\uff0c\u5373\u904d\u5386\u5217\u8868\u7684\u4e00\u534a\uff0c\u5373\u5faa\u73af\u5217\u8868\u5927\u5c0f\u4e0d\u65ad\u9664\u4ee52\u76f4\u81f3\u5546\u4e3a1\u7684\u6b21\u6570\u3002 \u5bf9\u4e8e\u5927\u5c0f\u4e3a n \u7684\u5217\u8868\u6765\u8bf4\uff0c\u4e5f\u5c31\u662f\u4f60\u9700\u8981\u6267\u884c n/2/2/.../2 \u6b21\uff0c\u76f4\u5230\u7ed3\u679c\u4e3a1\u3002\u5047\u8bbe k \u662f n \u53ef\u4ee5\u9664\u4ee52\u7684\u6b21\u6570\uff0c\u90a3\u4e48\u6c42\u89e3 k \u4f1a\u6709 n/(2^k)=1 \uff0c\u5373 n=2^k \uff0c\u5373 k=log(n,2) \u3002\u56e0\u6b64\uff0c\u4e8c\u5206\u641c\u7d22\u5728\u6700\u574f\u60c5\u51b5\u4e0b\u7684\u590d\u6742\u5ea6\u4e3aO(log(n,2))\u3002","title":"3.3.4.\u57fa\u4e8e\u6709\u5e8f\u5217\u8868\u7684\u4e8c\u5206\u641c\u7d22"},{"location":"python/DataStructure/03_TimeComplexity/#335","text":"\u4e8c\u5206\u641c\u7d22\u548c\u6700\u5c0f\u503c\u641c\u7d22\u90fd\u6709\u4e00\u4e2a\u5047\u8bbe\uff0c\u90a3\u5c31\u662f\u201c\u5217\u8868\u91cc\u7684\u5143\u7d20\u5f7c\u6b64\u4e4b\u95f4\u662f\u53ef\u4ee5\u6bd4\u8f83\u7684\u201d\u3002\u5373\uff0c\u8fd9\u4e9b\u5143\u7d20\u5c5e\u4e8e\u540c\u4e00\u4e2a\u7c7b\u578b\uff0c\u5373\uff0c\u53ef\u4ee5\u4f7f\u7528\u6bd4\u8f83\u8fd0\u7b97\u7b26 == \u3001 < \u548c > \u3002 Python\u5185\u7f6e\u7684\u7c7b\u578b\u5bf9\u8c61\uff0c\u5982\u6570\u5b57\u3001\u5b57\u7b26\u4e32\u548c\u5217\u8868\uff0c\u90fd\u652f\u6301\u6bd4\u8f83\u8fd0\u7b97\u7b26\u3002 \u4e3a\u4e86\u80fd\u591f\u8ba9\u7b97\u6cd5\u5bf9\u65b0\u7684\u7c7b\u5bf9\u8c61\u4f7f\u7528\u6bd4\u8f83\u8fd0\u7b97\u7b26 == \u3001 < \u548c > \uff0c\u5e94\u8be5\u5728\u8fd9\u4e2a\u7c7b\u91cc\u5b9a\u4e49 __eq__ \u3001 __lt__ \u548c __gt__ \u65b9\u6cd5\u3002\u5728\u5b9a\u4e49\u4e86\u8fd9\u4e9b\u65b9\u6cd5\u4e4b\u540e\uff0c\u5176\u4ed6\u6bd4\u8f83\u8fd0\u7b97\u7b26\u7684\u65b9\u6cd5\u5c06\u81ea\u52a8\u751f\u6210\u3002 \u4f8b\u5982\uff0c __lt__ \u7684\u5b9a\u4e49\u5982\u4e0b\uff0c\u5982\u679c self \u5c0f\u4e8e other \uff0c\u90a3\u4e48\u8fd9\u4e2a\u65b9\u6cd5\u5c06\u8fd4\u56de True \uff1b\u5426\u5219\uff0c\u8fd4\u56de False \u3002 __lt__ \u65b9\u6cd5\u4f1a\u4e3a\u4e24\u4e2a\u8d26\u6237\u5bf9\u8c61\u7684 name \u5b57\u6bb5\u8c03\u7528\u8fd0\u7b97\u7b26 < \u3002 \u540d\u79f0\u5b57\u6bb5\u662f\u5b57\u7b26\u4e32\uff0c\u5b57\u7b26\u4e32\u7c7b\u578b\u5df2\u7ecf\u5305\u542b\u5728 __lt__ \u65b9\u6cd5\u91cc\u3002 \u5728\u4f7f\u7528\u8fd0\u7b97\u7b26 < \u65f6\uff0cPython\u4f1a\u81ea\u52a8\u8fd0\u884c\u5b57\u7b26\u4e32\u7684 __lt__ \u65b9\u6cd5\uff0c\u8fd9\u4e0e\u8c03\u7528 str \u51fd\u6570\u65f6\u81ea\u52a8\u8fd0\u884c __str__ \u65b9\u6cd5\u662f\u7c7b\u4f3c\u7684\u3002 def __lt__ ( self , other ): \u793a\u4f8b\uff1a\u8fd4\u56de\u50a8\u84c4\u8d26\u6237\u7684\u6240\u6709\u4eba\u540d\u5b57\u3001PIN\u7801\u3001\u4f59\u989d\u3002 class SavingsAccount ( object ): \"\"\"\u8fd4\u56de\u50a8\u84c4\u8d26\u6237\u7684\u6240\u6709\u4eba\u540d\u5b57\u3001PIN\u7801\u3001\u4f59\u989d\"\"\" def __init__ ( self , name , pin , balance = 0.0 ): self . name = name self . pin = pin self . balance = balance def __lt__ ( self , other ): return self . name < other . name # Other methods, including __eq__ def main (): s1 = SavingsAccount ( \"Ken\" , \"1001\" , 0 ) s2 = SavingsAccount ( \"Bill\" , \"1001\" , 30 ) s3 = SavingsAccount ( \"Ken\" , \"1000\" , 0 ) s4 = s1 print ( \"s1 < s2: \" , s1 < s2 ) print ( \"s2 < s1: \" , s2 < s1 ) print ( \"s2 > s1: \" , s2 > s1 ) print ( \"s2 == s1: \" , s2 == s1 ) print ( \"s1 == s3: \" , s1 == s3 ) print ( \"s1 == s4: \" , s1 == s4 ) if __name__ == \"__main__\" : main () # \u8fd0\u7b97\u7ed3\u679c\uff1a # s1 < s2: False # s2 < s1: True # s2 > s1: False # s2 == s1: False # s1 == s3: False # s1 == s4: True \u63d0\u793a\uff1a\u5728Python\u4e2d\uff0c\u9ed8\u8ba4\u662f\u6309\u7167ASCII\u7684\u5927\u5c0f\u6bd4\u8f83\u5b57\u7b26\u4e32\u7684\uff0c\u5373\u4ece\u5b57\u7b26\u4e32\u7684\u7b2c\u4e00\u4e2a\u5b57\u7b26\u8fdb\u884c\u6bd4\u8f83\uff0c\u5982\u679c\u76f8\u7b49\uff0c\u5219\u7ee7\u7eed\u6bd4\u8f83\u4e0b\u4e00\u4e2a\u5b57\u7b26\uff0c\u76f4\u5230\u5206\u51fa\u5927\u5c0f\uff0c\u6216\u8005\u8fd8\u6ca1\u5206\u51fa\u5927\u5c0f\uff0c\u6709\u4e00\u4e2a\u5b57\u7b26\u4e32\u5df2\u7ecf\u5230\u5934\u4e86\uff0c\u90a3\u4e48\u8f83\u957f\u7684\u90a3\u4e00\u4e2a\u5b57\u7b26\u4e32\u5927\u3002","title":"3.3.5.\u6bd4\u8f83\u6570\u636e\u5143\u7d20"},{"location":"python/DataStructure/03_TimeComplexity/#336","text":"\u5047\u8bbe\u4e00\u4e2a\u5217\u8868\u5728\u7d22\u5f150\uff5e9\u7684\u4f4d\u7f6e\u5904\u5305\u542b\u503c20\u300144\u300148\u300155\u300162\u300166\u300174\u300188\u300193\u300199\uff0c\u8bf7\u5728\u7528\u4e8c\u5206\u641c\u7d22\u67e5\u627e\u76ee\u6807\u5143\u7d2090\u7684\u65f6\u5019\uff0c\u5bf9\u53d8\u91cfleft\u3001right\u548cmidpoint\u7684\u503c\u8fdb\u884c\u8ddf\u8e2a\u3002\u6539\u53d8\u76ee\u6807\u5143\u7d20\u4e3a44\uff0c\u5e76\u91cd\u590d\u8fd9\u4e2a\u6b65\u9aa4\u3002 \u89e3\u7b54\uff1a \u4e0b\u9762\u662f\u4ee3\u7801\u548c\u8ddf\u8e2a\u7ed3\u679c\u3002 def binarySearch ( target , sortedLyst ): left = 0 right = len ( sortedLyst ) - 1 print ( \" %5s%10s%10s \" % ( \"left\" , \"midpoint\" , \"right\" )) while left <= right : midpoint = ( left + right ) // 2 print ( \" %5s%10s%10s \" % ( left , midpoint , right )) if target == sortedLyst [ midpoint ]: return midpoint elif target < sortedLyst [ midpoint ]: right = midpoint - 1 else : left = midpoint + 1 return - 1 def main (): myList = [ 20 , 44 , 48 , 55 , 62 , 66 , 74 , 88 , 93 , 99 ] sortedList = sorted ( myList ) locatedIndex = binarySearch ( 44 , sortedList ) if __name__ == \"__main__\" : main () # \u8fd0\u7b97\u7ed3\u679c\uff1a # Target = 90 # left midpoint right # 0 4 9 # 5 7 9 # 8 8 9 # # Target = 44 # left midpoint right # 0 4 9 # 0 1 3 \u901a\u5e38\u6765\u8bf4\uff0c\u67e5\u627e\u7535\u8bdd\u7c3f\u4e2d\u6761\u76ee\u7684\u65b9\u6cd5\u4e0e\u4e8c\u5206\u641c\u7d22\u5e76\u4e0d\u5b8c\u5168\u76f8\u540c\uff0c\u56e0\u4e3a\u4f7f\u7528\u7535\u8bdd\u7c3f\u7684\u65f6\u5019\uff0c\u5e76\u4e0d\u4f1a\u6bcf\u6b21\u90fd\u7ffb\u5230\u88ab\u641c\u7d22\u7684\u5b50\u5217\u8868\u7684\u4e2d\u70b9\u3002\u4e00\u822c\u6765\u8bf4\uff0c\u53ef\u4ee5\u6839\u636e\u8fd9\u4e2a\u4eba\u7684\u59d3\u6c0f\u7684\u7b2c\u4e00\u4e2a\u5b57\u6bcd\u987a\u5e8f\u6765\u4f30\u7b97\u76ee\u6807\u53ef\u80fd\u4f1a\u5728\u7684\u4f4d\u7f6e\u3002\u4f8b\u5982\uff0c\u5f53\u67e5\u627e\u201cSmith\u201d\u7684\u7535\u8bdd\u65f6\uff0c\u4f60\u4f1a\u9996\u5148\u67e5\u770b\u7535\u8bdd\u7c3f\u4e0b\u534a\u90e8\u5206\u7684\u4e2d\u95f4\uff0c\u800c\u4e0d\u662f\u6574\u4e2a\u7535\u8bdd\u7c3f\u7684\u4e2d\u95f4\u3002\u8bf7\u5bf9\u4e8c\u5206\u641c\u7d22\u7b97\u6cd5\u5c1d\u8bd5\u8fdb\u884c\u4fee\u6539\uff0c\u4ece\u800c\u53ef\u4ee5\u5728\u5904\u7406\u540d\u79f0\u5217\u8868\u7684\u65f6\u5019\u6a21\u62df\u8fd9\u4e2a\u7b56\u7565\u3002\u5b83\u7684\u8ba1\u7b97\u590d\u6742\u5ea6\u4e0e\u6807\u51c6\u7684\u4e8c\u5206\u641c\u7d22\u76f8\u6bd4\u8f83\u4f1a\u66f4\u597d\u5417\uff1f \u89e3\u7b54\uff1a\u4e0b\u9762\u662f\u4ee3\u7801\u548c\u8ffd\u8e2a\u7ed3\u679c\u3002\u901a\u8fc7\u5bf9\u6bd4\u4e0d\u540c\u6743\u91cd\u5355\u8bcd\u5230\u7684\u641c\u7d22\uff0c\u53ef\u4ee5\u53d1\u73b0\u6743\u91cd\u4e8c\u5206\u6cd5\u7684\u6548\u7387\u82e5\u8981\u4f18\u4e8e\u4f20\u7edf\u4e8c\u5206\u6cd5\uff0c\u662f\u9700\u8981\u6ee1\u8db3\u4e00\u5b9a\u7684\u6761\u4ef6\u7684\u3002 \u5728\u641c\u7d22\u7684\u7b2c\u4e00\u8f6e\u4e2d\uff0c\u4e2d\u95f4\u4f4d\u7f6e\u5c06\u53d6\u51b3\u4e8e\u5217\u8868\u7684\u5927\u5c0f\u548c\u76ee\u6807\u540d\u5b57\u7684\u7b2c\u4e00\u4e2a\u5b57\u6bcd\u7684\u987a\u5e8f\u503c\u3002\u56e0\u6b64\uff0c\u7b2c\u4e00\u8f6e\u641c\u7d22\u5c06\u6d88\u9664\u6bd4\u4ee5\u524d\u66f4\u591a\u7684\u5143\u7d20\uff0c\u5e76\u4e14\u5982\u679c\u9700\u8981\u5176\u4ed6\u8f6e\u641c\u7d22\uff0c\u5b83\u4eec\u7684\u641c\u7d22\u7a7a\u95f4\u4e5f\u4f1a\u66f4\u5c0f\u3002\u7136\u800c\uff0c\u5728\u6700\u574f\u60c5\u51b5\u4e0b\uff0c\u4fee\u6539\u540e\u7684\u7b97\u6cd5\u4ecd\u7136\u6bd4O(1)\u66f4\u63a5\u8fd1O(log n)\u3002 def binarySearch ( target , sortedLyst ): left = 0 right = len ( sortedLyst ) - 1 print ( \" %5s%10s%10s \" % ( \"left\" , \"midpoint\" , \"right\" )) while left <= right : midpoint = ( left + right ) // 2 print ( \" %5s%10s%10s \" % ( left , midpoint , right )) if target == sortedLyst [ midpoint ]: return midpoint elif target < sortedLyst [ midpoint ]: right = midpoint - 1 else : left = midpoint + 1 return - 1 def letter_position ( myLetter ): letter = myLetter . lower () # \u8f6c\u6210\u5c0f\u5199\u5b57\u6bcd alphabet = \"abcdefghijklmnopqrstuvwxyz\" if letter in alphabet : return alphabet . index ( letter ) + 1 # \u4f4d\u7f6e\u63091\uff5e26\u8ba1\u7b97 else : return None # \u975e\u5b57\u6bcd def dictSearch ( target , sortedLyst ): left = 0 right = len ( sortedLyst ) - 1 # \u9996\u5b57\u6bcd\u5728\u5b57\u6bcd\u8868\u4e2d\u7684\u767e\u5206\u4f4d letter_position_range = letter_position ( target [ 0 ]) * 100 // 26 # \u6309\u7167\u6240\u5f97\u7684\u9996\u5b57\u6bcd\u5728\u5b57\u6bcd\u8868\u4e2d\u7684\u767e\u5206\u4f4d\uff0c\u4f5c\u4e3a\u7ed9\u5b9a\u5b57\u4e32\u4e2d\u8bbe\u5b9a\u641c\u7d22\u8d77\u59cb\u767e\u5206\u4f4d midpoint = letter_position_range * ( len ( sortedLyst ) - 1 ) // 100 print ( \" %5s%10s%10s \" % ( \"left\" , \"midpoint\" , \"right\" )) while left <= right : print ( \" %5s%10s%10s \" % ( left , midpoint , right )) if target == sortedLyst [ midpoint ]: return midpoint elif target < sortedLyst [ midpoint ]: right = midpoint - 1 else : left = midpoint + 1 midpoint = ( left + right ) // 2 return - 1 def main (): myList = [ \"Bob\" , \"Charlie\" , \"Eva\" , \"Alice\" , \"Grace\" , \"David\" , \"Smith\" , \"Frank\" , \"Zoe\" , \"Jack\" ] sortedList = sorted ( myList ) print ( sortedList ) print ( \"=====call binarySearch=====\" ) locatedIndex = binarySearch ( \"Alice\" , sortedList ) print ( \"Found\" , sortedList [ locatedIndex ], \"in position\" , locatedIndex ) print ( \"=====call dictSearch=====\" ) locatedIndex = dictSearch ( \"Alice\" , sortedList ) print ( \"Found\" , sortedList [ locatedIndex ], \"in position\" , locatedIndex ) if __name__ == \"__main__\" : main () # \u8fd0\u7b97\u7ed3\u679c\uff1a # \u641c\u7d22Alice # ['Alice', 'Bob', 'Charlie', 'David', 'Eva', 'Frank', 'Grace', 'Jack', 'Smith', 'Zoe'] # =====call binarySearch===== # left midpoint right # 0 4 9 # 0 1 3 # 0 0 0 # Found Alice in position 0 # =====call dictSearch===== # left midpoint right # 0 0 9 # Found Alice in position 0 # \u641c\u7d22Bob # ['Alice', 'Bob', 'Charlie', 'David', 'Eva', 'Frank', 'Grace', 'Jack', 'Smith', 'Zoe'] # =====call binarySearch===== # left midpoint right # 0 4 9 # 0 1 3 # Found Bob in position 1 # =====call dictSearch===== # left midpoint right # 0 0 9 # 1 5 9 # 1 2 4 # 1 1 1 # Found Bob in position 1 # \u641c\u7d22Smith # ['Alice', 'Bob', 'Charlie', 'David', 'Eva', 'Frank', 'Grace', 'Jack', 'Smith', 'Zoe'] # =====call binarySearch===== # left midpoint right # 0 4 9 # 5 7 9 # 8 8 9 # Found Smith in position 8 # =====call dictSearch===== # left midpoint right # 0 6 9 # 7 8 9 # Found Smith in position 8 # \u641c\u7d22Zoe # ['Alice', 'Bob', 'Charlie', 'David', 'Eva', 'Frank', 'Grace', 'Jack', 'Smith', 'Zoe'] # =====call binarySearch===== # left midpoint right # 0 4 9 # 5 7 9 # 8 8 9 # 9 9 9 # Found Zoe in position 9 # =====call dictSearch===== # left midpoint right # 0 9 9 # Found Zoe in position 9","title":"3.3.6.\u7ec3\u4e60\u9898"},{"location":"python/DataStructure/03_TimeComplexity/#34","text":"\u4e0b\u9762\u662fswap\u51fd\u6570\u7684\u4f8b\u5b50\uff0c\u5b9e\u73b0\u4e86\uff1a \u5047\u8bbe\u90fd\u5728\u6574\u6570\u5217\u8868\u4e0a\u8fd0\u884c\uff1b \u4ea4\u6362\u5217\u8868\u4e2d\u4e24\u4e2a\u5143\u7d20\u7684\u4f4d\u7f6e\uff1b def swap ( lyst , i , j ): \"\"\"\u4ea4\u6362\u5143\u7d20\u4f4d\u7f6e\u4e3ai\u548cj\u7684\u5143\u7d20\"\"\" temp = lyst [ i ] lyst [ i ] = lyst [ j ] lyst [ j ] = temp def main (): myList = [ 9 , 4 , 2 , 7 , 6 , 8 , 1 ] print ( myList ) swap ( myList , 3 , 5 ) print ( myList ) if __name__ == \"__main__\" : main () # \u8fd0\u884c\u7ed3\u679c\uff1a # [9, 4, 2, 7, 6, 8, 1] # [9, 4, 2, 8, 6, 7, 1]","title":"3.4.\u57fa\u672c\u7684\u6392\u5e8f\u7b97\u6cd5"},{"location":"python/DataStructure/03_TimeComplexity/#341","text":"\u9009\u62e9\u6392\u5e8f\uff08selection sort\uff09\uff1a\uff08\u4ee5\u5217\u8868\u4e3a\u4f8b\uff09 \u5728\u4e00\u4e2a\u957f\u5ea6\u4e3a N \u7684\u65e0\u5e8f\u5217\u8868\u4e2d\uff0c\u7b2c\u4e00\u6b21\u904d\u5386 n-1 \u4e2a\u6570\u627e\u5230\u6700\u5c0f\u7684\u548c\u7b2c\u4e00\u4e2a\u6570\u4ea4\u6362\u3002 \u7b2c\u4e8c\u6b21\u4ece\u4e0b\u4e00\u4e2a\u6570\u5f00\u59cb\u904d\u5386 n-2 \u4e2a\u6570\uff0c\u627e\u5230\u6700\u5c0f\u7684\u6570\u548c\u7b2c\u4e8c\u4e2a\u6570\u4ea4\u6362\u3002 \u91cd\u590d\u4ee5\u4e0a\u64cd\u4f5c\u76f4\u5230\u7b2c n-1 \u6b21\u904d\u5386\u6700\u5c0f\u7684\u6570\u548c\u7b2c n-1 \u4e2a\u6570\u4ea4\u6362\uff0c\u6392\u5e8f\u5b8c\u6210\u3002 \u8fd9\u4e2a\u7b97\u6cd5\u5728\u6bcf\u6b21\u901a\u8fc7\u4e3b\u5faa\u73af\u65f6\uff0c\u90fd\u4f1a\u9009\u62e9\u8981\u79fb\u52a8\u7684\u90a3\u4e00\u4e2a\u5143\u7d20\u3002 \u7b97\u6cd5\u590d\u6742\u5ea6\uff1a \u7b2c1\u6b21\u6267\u884c\u5916\u90e8\u5faa\u73af\u65f6\uff0c\u5185\u90e8\u5faa\u73af\u4f1a\u6267\u884cn-1\u6b21\uff1b \u7b2c2\u6b21\u6267\u884c\u5916\u90e8\u5faa\u73af\u65f6\uff0c\u5185\u90e8\u5faa\u73af\u4f1a\u6267\u884cn-2\u6b21\uff1b \u6700\u540e\u4e00\u6b21\u6267\u884c\u5916\u90e8\u5faa\u73af\u65f6\uff0c\u5185\u90e8\u5faa\u73af\u4f1a\u6267\u884c1\u6b21\uff1b \u6240\u4ee5\uff0c\u5927\u5c0f\u4e3a n \u7684\u5217\u8868\uff0c\u4e00\u5171\u9700\u8981\u7684\u6bd4\u8f83\u6b21\u6570\u662f (n-1)+(n-2)+...+1 \uff0c\u5316\u7b80\u4e3a n*(n-1)/2 \uff0c\u5373 (1/2)*n^2+(1/2)*n \u3002\u5f53 n \u6bd4\u8f83\u5927\u65f6\uff0c\u53ef\u4ee5\u9009\u62e9\u6700\u9ad8\u6b21\u7684\u9879\u5e76\u5ffd\u7565\u7cfb\u6570\uff0c\u56e0\u6b64\u5728\u6240\u6709\u60c5\u51b5\u4e0b\uff0c\u9009\u62e9\u6392\u5e8f\u7684\u590d\u6742\u5ea6\u90fd\u662fO(n^2)\u3002 \u5bf9\u4e8e\u5927\u578b\u6570\u636e\u96c6\u6765\u8bf4\uff0c\u4ea4\u6362\u5143\u7d20\u7684\u6210\u672c\u53ef\u80fd\u4f1a\u5f88\u9ad8\u3002\u56e0\u4e3a\u8fd9\u4e2a\u7b97\u6cd5\u53ea\u4f1a\u5728\u5916\u90e8\u5faa\u73af\u91cc\u5bf9\u6570\u636e\u5143\u7d20\u8fdb\u884c\u4ea4\u6362\uff0c\u6240\u4ee5\u5728\u6700\u574f\u60c5\u51b5\u548c\u5e73\u5747\u60c5\u51b5\u4e0b\uff0c\u9009\u62e9\u6392\u5e8f\u7684\u989d\u5916\u6210\u672c\u662f\u7ebf\u6027\u7684\u3002 \u7b97\u6cd5\u4ee3\u7801\uff1a def swap ( lyst , i , j ): \"\"\"\u4ea4\u6362\u5143\u7d20\u4f4d\u7f6e\u4e3ai\u548cj\u7684\u5143\u7d20\"\"\" temp = lyst [ i ] lyst [ i ] = lyst [ j ] lyst [ j ] = temp def selectionSort ( lyst ): \"\"\"\u5b9e\u73b0\u4ea4\u6362\u6392\u5e8f\u7b97\u6cd5\"\"\" i = 0 while i < len ( lyst ) - 1 : # \u5b9e\u73b0n-1\u6b21\u641c\u7d22 minIndex = i # \u6700\u5c0f\u5143\u7d20\u4f4d\u7f6e j = i + 1 while j < len ( lyst ): # \u5411\u540e\u904d\u5386\u641c\u7d22\uff0c\u66f4\u65b0\u6700\u5c0f\u5143\u7d20\u4f4d\u7f6e if lyst [ j ] < lyst [ minIndex ]: minIndex = j j += 1 if minIndex != i : # \u5982\u679c\u9700\u8981\uff0c\u5219\u4ea4\u6362\u5143\u7d20\u4f4d\u7f6e swap ( lyst , minIndex , i ) i += 1 def main (): myList = [ 9 , 4 , 2 , 7 , 6 , 8 , 1 ] print ( \"Before selection sort \" , myList ) selectionSort ( myList ) print ( \"After selection sort \" , myList ) if __name__ == \"__main__\" : main () # \u8fd0\u884c\u7ed3\u679c\uff1a # Before selection sort [9, 4, 2, 7, 6, 8, 1] # After selection sort [1, 2, 4, 6, 7, 8, 9]","title":"3.4.1.\u9009\u62e9\u6392\u5e8f"},{"location":"python/DataStructure/03_TimeComplexity/#342","text":"\u5192\u6ce1\u6392\u5e8f\uff08Bubble Sort\uff09\uff1a \u6bd4\u8f83\u76f8\u90bb\u4e24\u4e2a\u6570\u636e\u5982\u679c\u3002\u7b2c\u4e00\u4e2a\u6bd4\u7b2c\u4e8c\u4e2a\u5927\uff0c\u5c31\u4ea4\u6362\u4e24\u4e2a\u6570\uff1b \u5bf9\u6bcf\u4e00\u4e2a\u76f8\u90bb\u7684\u6570\u505a\u540c\u68371\u7684\u5de5\u4f5c\uff0c\u8fd9\u6837\u4ece\u5f00\u59cb\u4e00\u961f\u5230\u7ed3\u5c3e\u4e00\u961f\u5728\u6700\u540e\u7684\u6570\u5c31\u662f\u6700\u5927\u7684\u6570\u3002 \u9488\u5bf9\u6240\u6709\u5143\u7d20\u4e0a\u9762\u7684\u64cd\u4f5c\uff0c\u9664\u4e86\u6700\u540e\u4e00\u4e2a\u3002 \u91cd\u590d1~3\u6b65\u9aa4\uff0c\u76f4\u81f3\u5b8c\u6210\u3002 \u7b97\u6cd5\u590d\u6742\u5ea6\uff1a \u5192\u6ce1\u6392\u5e8f\u53ea\u4f1a\u6539\u5584\u6700\u597d\u60c5\u51b5\u4e0b\u7684\u590d\u6742\u5ea6\u3002\u5bf9\u4e8e\u5e73\u5747\u60c5\u51b5\u800c\u8a00\uff0c\u7531\u4e8e\u4f9d\u7136\u662f\u53cc\u91cd\u5faa\u73af\u65f6\u95f4\uff0c\u6240\u4ee5\u590d\u6742\u5ea6\u662fO(n^2)\uff1b \u5bf9\u4e8e\u6709\u5e8f\u7684\u5217\u8868\u6765\u8bf4\uff0c\u4fee\u6539\u540e\u7684\u5192\u6ce1\u6392\u5e8f\u4f1a\u6bd4\u9009\u62e9\u6392\u5e8f\u7684\u6267\u884c\u6548\u7387\u66f4\u9ad8\u3002 \u7b97\u6cd5\u4ee3\u7801\uff1a def swap ( lyst , i , j ): \"\"\"\u4ea4\u6362\u5143\u7d20\u4f4d\u7f6e\u4e3ai\u548cj\u7684\u5143\u7d20\"\"\" temp = lyst [ i ] lyst [ i ] = lyst [ j ] lyst [ j ] = temp def selectionSort ( lyst ): \"\"\"\u5b9e\u73b0\u4ea4\u6362\u6392\u5e8f\u7b97\u6cd5\"\"\" i = 0 while i < len ( lyst ) - 1 : # \u5b9e\u73b0n-1\u6b21\u641c\u7d22 minIndex = i # \u6700\u5c0f\u5143\u7d20\u4f4d\u7f6e j = i + 1 while j < len ( lyst ): # \u5411\u540e\u904d\u5386\u641c\u7d22\uff0c\u66f4\u65b0\u6700\u5c0f\u5143\u7d20\u4f4d\u7f6e if lyst [ j ] < lyst [ minIndex ]: minIndex = j j += 1 if minIndex != i : # \u5982\u679c\u9700\u8981\uff0c\u5219\u4ea4\u6362\u5143\u7d20\u4f4d\u7f6e swap ( lyst , minIndex , i ) i += 1 def bubbleSortWithTweak ( lyst ): \"\"\"\u5b9e\u73b0\u5192\u6ce1\u6392\u5e8f\u7b97\u6cd5\"\"\" n = len ( lyst ) while n > 1 : swapped = False # \u7528\u5e03\u5c14\u6807\u5fd7\u6765\u8ffd\u8e2a\u6709\u6ca1\u6709\u53d1\u751f\u4ea4\u6362 i = 1 while i < n : if lyst [ i ] < lyst [ i - 1 ]: # \u5982\u679c\u540e\u9762\u5143\u7d20\u7684\u503c\u6bd4\u524d\u9762\u5143\u7d20\u7684\u5927\uff0c\u5219\u4ea4\u6362\u5143\u7d20\u4f4d\u7f6e\uff0c\u76f4\u81f3\u628a\u5faa\u73af\u4e2d\u7684\u6700\u5927\u5143\u7d20\u79fb\u5230\u6700\u540e swap ( lyst , i , i - 1 ) swapped = True i += 1 if not swapped : # \u5982\u679c\u4e0d\u9700\u8981\u4ea4\u6362\uff0c\u76f4\u63a5return return n -= 1 def main (): myList = [ 9 , 4 , 2 , 7 , 6 , 8 , 1 ] # \u6bd4\u8f83\u6392\u5e8f print ( \"Before selection sort \" , myList ) selectionSort ( myList ) print ( \"After selection sort \" , myList ) # \u5192\u6ce1\u6392\u5e8f myList = [ 9 , 4 , 2 , 7 , 6 , 8 , 1 ] print ( \"Before bubble sort \" , myList ) bubbleSortWithTweak ( myList ) print ( \"After bubble sort \" , myList ) if __name__ == \"__main__\" : main () # \u8fd0\u884c\u7ed3\u679c\uff1a # Before selection sort [9, 4, 2, 7, 6, 8, 1] # After selection sort [1, 2, 4, 6, 7, 8, 9] # Before bubble sort [9, 4, 2, 7, 6, 8, 1] # After bubble sort [1, 2, 4, 6, 7, 8, 9]","title":"3.4.2.\u5192\u6ce1\u6392\u5e8f"},{"location":"python/DataStructure/03_TimeComplexity/#343","text":"\u63d2\u5165\u6392\u5e8f\uff08Insertion-Sort\uff09\u662f\u901a\u8fc7\u6784\u5efa\u6709\u5e8f\u5e8f\u5217\uff0c\u5bf9\u4e8e\u672a\u6392\u5e8f\u6570\u636e\uff0c\u5728\u5df2\u6392\u5e8f\u5e8f\u5217\u4e2d\u4ece\u540e\u5411\u524d\u626b\u63cf\uff0c\u627e\u5230\u76f8\u5e94\u4f4d\u7f6e\u5e76\u63d2\u5165\u3002\u63d2\u5165\u6392\u5e8f\u90fd\u91c7\u7528 in-place \u5728\u6570\u7ec4\u4e0a\u5b9e\u73b0\uff1a \u4ece\u7b2c\u4e00\u4e2a\u5143\u7d20\u5f00\u59cb\uff0c\u8be5\u5143\u7d20\u53ef\u4ee5\u8ba4\u4e3a\u5df2\u7ecf\u88ab\u6392\u5e8f\uff1b \u53d6\u51fa\u4e0b\u4e00\u4e2a\u5143\u7d20\uff0c\u5728\u5df2\u7ecf\u6392\u5e8f\u7684\u5143\u7d20\u5e8f\u5217\u4ece\u540e\u5411\u524d\u626b\u63cf\uff1b \u5982\u679c\u65b0\u5143\u7d20\u5c0f\u4e8e\u5df2\u6392\u5e8f\u7684\u5143\u7d20\uff0c\u5c06\u65b0\u5143\u7d20\u79fb\u5230\u4e0b\u4e00\u4f4d\u7f6e\uff1b \u91cd\u590d\u6b65\u9aa43\uff0c\u76f4\u5230\u627e\u5230\u5df2\u6392\u5e8f\u7684\u5143\u7d20\u5c0f\u4e8e\u6216\u8005\u7b49\u4e8e\u65b0\u5143\u7d20\u7684\u4f4d\u7f6e\uff1b \u5c06\u65b0\u5143\u7d20\u63d2\u5165\u5230\u8be5\u4f4d\u7f6e\u540e\uff1b \u91cd\u590d\u6b65\u9aa42~5\u3002 \u590d\u6742\u5ea6\uff1a \u548c\u9009\u62e9\u6392\u5e8f\u7c7b\u4f3c\uff0c\u904d\u5386\u6b21\u6570\u4e5f\u662f (1/2)*n^2+(1/2)*n \uff0c\u6240\u4ee5\u590d\u6742\u5ea6\u4e5f\u662fO(n^2)\u3002 \u5217\u8868\u91cc\u6709\u5e8f\u5143\u7d20\u8d8a\u591a\uff0c\u63d2\u5165\u6392\u5e8f\u7684\u6027\u80fd\u5c31\u4f1a\u8d8a\u597d\uff1b \u5728\u6709\u5e8f\u5217\u8868\u7684\u6700\u597d\u60c5\u51b5\u4e0b\uff0c\u6392\u5e8f\u590d\u6742\u5ea6\u662f\u7ebf\u6027\u7684\uff1b def swap ( lyst , i , j ): \"\"\"\u4ea4\u6362\u5143\u7d20\u4f4d\u7f6e\u4e3ai\u548cj\u7684\u5143\u7d20\"\"\" temp = lyst [ i ] lyst [ i ] = lyst [ j ] lyst [ j ] = temp def selectionSort ( lyst ): \"\"\"\u5b9e\u73b0\u4ea4\u6362\u6392\u5e8f\u7b97\u6cd5\"\"\" i = 0 while i < len ( lyst ) - 1 : # \u5b9e\u73b0n-1\u6b21\u641c\u7d22 minIndex = i # \u6700\u5c0f\u5143\u7d20\u4f4d\u7f6e j = i + 1 while j < len ( lyst ): # \u5411\u540e\u904d\u5386\u641c\u7d22\uff0c\u66f4\u65b0\u6700\u5c0f\u5143\u7d20\u4f4d\u7f6e if lyst [ j ] < lyst [ minIndex ]: minIndex = j j += 1 if minIndex != i : # \u5982\u679c\u9700\u8981\uff0c\u5219\u4ea4\u6362\u5143\u7d20\u4f4d\u7f6e swap ( lyst , minIndex , i ) i += 1 def bubbleSortWithTweak ( lyst ): \"\"\"\u5b9e\u73b0\u5192\u6ce1\u6392\u5e8f\u7b97\u6cd5\"\"\" n = len ( lyst ) while n > 1 : swapped = False # \u7528\u5e03\u5c14\u6807\u5fd7\u6765\u8ffd\u8e2a\u6709\u6ca1\u6709\u53d1\u751f\u4ea4\u6362 i = 1 while i < n : if lyst [ i ] < lyst [ i - 1 ]: # \u5982\u679c\u540e\u9762\u5143\u7d20\u7684\u503c\u6bd4\u524d\u9762\u5143\u7d20\u7684\u5927\uff0c\u5219\u4ea4\u6362\u5143\u7d20\u4f4d\u7f6e\uff0c\u76f4\u81f3\u628a\u5faa\u73af\u4e2d\u7684\u6700\u5927\u5143\u7d20\u79fb\u5230\u6700\u540e swap ( lyst , i , i - 1 ) swapped = True i += 1 if not swapped : # \u5982\u679c\u4e0d\u9700\u8981\u4ea4\u6362\uff0c\u76f4\u63a5return return n -= 1 def insertionSort ( lyst ): i = 1 # \u65b0\u5143\u7d20\u7684\u4f4d\u7f6e while i < len ( lyst ): itemToInsert = lyst [ i ] # \u65b0\u5143\u7d20 j = i - 1 # \u5df2\u6392\u5e8f\u7684\u5143\u7d20\u5e8f\u5217\u7684\u6700\u53f3\u4f4d\u7f6e while j >= 0 : if itemToInsert < lyst [ j ]: lyst [ j + 1 ] = lyst [ j ] # \u5982\u679c\u65b0\u5143\u7d20\u5c0f\u4e8e\u5df2\u6392\u5e8f\u5143\u7d20\uff0c\u5219\u5df2\u6392\u5e8f\u5143\u7d20\u5411\u540e\u79fb\u52a8\u4e00\u4e2a\u4f4d\u7f6e j -= 1 else : break # \u65b0\u5143\u7d20\u7b49\u4e8e\u6216\u8005\u5927\u4e8e\u5df2\u6392\u5e8f\u5143\u7d20\uff0c\u8df3\u51fa\u5faa\u73af\uff0c\u6b64\u65f6lyst[j + 1]\u662f\u548clyst[j]\u662f\u540c\u4e00\u4e2a\u5143\u7d20\u503c\uff0clyst[j + 1]\u4f4d\u7f6e\u662f\u7559\u7ed9\u65b0\u5143\u7d20\u7684 lyst [ j + 1 ] = itemToInsert # i += 1 def main (): myList = [ 9 , 4 , 2 , 7 , 6 , 8 , 1 ] # \u6bd4\u8f83\u6392\u5e8f print ( \"Before selection sort \" , myList ) selectionSort ( myList ) print ( \"After selection sort \" , myList ) # \u5192\u6ce1\u6392\u5e8f myList = [ 9 , 4 , 2 , 7 , 6 , 8 , 1 ] print ( \"Before bubble sort \" , myList ) bubbleSortWithTweak ( myList ) print ( \"After bubble sort \" , myList ) # \u63d2\u5165\u6392\u5e8f myList = [ 9 , 4 , 2 , 7 , 6 , 8 , 1 ] print ( \"Before insertion sort \" , myList ) insertionSort ( myList ) print ( \"After insertion sort \" , myList ) if __name__ == \"__main__\" : main () # \u8fd0\u884c\u7ed3\u679c\uff1a # Before selection sort [9, 4, 2, 7, 6, 8, 1] # After selection sort [1, 2, 4, 6, 7, 8, 9] # Before bubble sort [9, 4, 2, 7, 6, 8, 1] # After bubble sort [1, 2, 4, 6, 7, 8, 9] # Before insertion sort [9, 4, 2, 7, 6, 8, 1] # After insertion sort [1, 2, 4, 6, 7, 8, 9]","title":"3.4.3.\u63d2\u5165\u6392\u5e8f"},{"location":"python/DataStructure/03_TimeComplexity/#344","text":"\u5bf9\u4e8e\u8bb8\u591a\u7b97\u6cd5\u6765\u8bf4\uff0c\u4e0d\u80fd\u5bf9\u6240\u6709\u60c5\u51b5\u91c7\u7528\u5355\u4e00\u7684\u590d\u6742\u5ea6\u6765\u8861\u91cf\u3002\u5f53\u9047\u5230\u7279\u5b9a\u987a\u5e8f\u7684\u6570\u636e\u65f6\uff0c\u7b97\u6cd5\u7684\u884c\u4e3a\u53ef\u80fd\u4f1a\u53d8\u5f97\u66f4\u597d\u6216\u66f4\u7cdf\u3002 \u5bf9\u7b97\u6cd5\u590d\u6742\u5ea6\u884c\u4e3a\u5206\u4e3a3\u79cd\u60c5\u51b5\uff1a \u6700\u597d\u60c5\u51b5\uff08best case\uff09\u2014\u2014\u7b97\u6cd5\u5728\u4ec0\u4e48\u60c5\u51b5\u4e0b\u53ef\u4ee5\u4ee5\u6700\u5c11\u7684\u5de5\u4f5c\u91cf\u5b8c\u6210\u5de5\u4f5c\uff1f\u5728\u6700\u597d\u60c5\u51b5\u4e0b\uff0c\u7b97\u6cd5\u7684\u590d\u6742\u5ea6\u662f\u591a\u5c11\uff1f \u6700\u574f\u60c5\u51b5\uff08worst case\uff09\u2014\u2014\u7b97\u6cd5\u5728\u4ec0\u4e48\u60c5\u51b5\u4e0b\u9700\u8981\u5b8c\u6210\u6700\u591a\u7684\u5de5\u4f5c\u91cf\uff1f\u5728\u6700\u574f\u60c5\u51b5\u4e0b\uff0c\u7b97\u6cd5\u7684\u590d\u6742\u5ea6\u662f\u591a\u5c11\uff1f \u5e73\u5747\u60c5\u51b5\uff08average case\uff09\u2014\u2014\u7b97\u6cd5\u5728\u4ec0\u4e48\u60c5\u51b5\u4e0b\u7528\u9002\u91cf\u7684\u5de5\u4f5c\u91cf\u5c31\u80fd\u5b8c\u6210\u5de5\u4f5c\uff1f\u5728\u5e73\u5747\u60c5\u51b5\u4e0b\uff0c\u7b97\u6cd5\u7684\u590d\u6742\u5ea6\u662f\u591a\u5c11\uff1f \u4e0b\u9762\u5206\u522b\u5bf9\u6700\u5c0f\u503c\u641c\u7d22\u3001\u987a\u5e8f\u641c\u7d22\u548c\u5192\u6ce1\u6392\u5e8f\u8fdb\u884c\u6700\u597d\u60c5\u51b5\u3001\u6700\u574f\u60c5\u51b5\u548c\u5e73\u5747\u60c5\u51b5\u4e0b\u7684\u6027\u80fd\u5206\u6790\uff0c\u4e0d\u8003\u8651\u5b9e\u9645\u786c\u4ef6\u548c\u7f16\u7a0b\u8bed\u8a00\u7b49\u7684\u5f71\u54cd\u3002 \u6700\u5c0f\u503c\u641c\u7d22\uff08Minimum Value Search\uff09 \u6700\u597d\u60c5\u51b5\uff1a\u6700\u5c0f\u503c\u521a\u597d\u5728\u7b2c\u4e00\u4e2a\u4f4d\u7f6e\u3002\u8fd9\u65f6\uff0c\u53ea\u9700\u8981\u4e00\u6b21\u6bd4\u8f83\u5c31\u53ef\u4ee5\u627e\u5230\u6700\u5c0f\u503c\uff0c\u65f6\u95f4\u590d\u6742\u5ea6\u4e3aO(1)\u3002 \u6700\u574f\u60c5\u51b5\uff1a\u6700\u5c0f\u503c\u5728\u6700\u540e\u4e00\u4e2a\u4f4d\u7f6e\u6216\u4e0d\u5b58\u5728\u3002\u8fd9\u65f6\uff0c\u9700\u8981\u8fdb\u884cn-1\u6b21\u6bd4\u8f83\u624d\u80fd\u786e\u5b9a\u6700\u5c0f\u503c\uff0c\u65f6\u95f4\u590d\u6742\u5ea6\u4e3aO(n)\u3002 \u5e73\u5747\u60c5\u51b5\uff1a\u5e73\u5747\u60c5\u51b5\u4e0b\uff0c\u6bcf\u4e2a\u5143\u7d20\u6709\u76f8\u7b49\u7684\u6982\u7387\u6210\u4e3a\u6700\u5c0f\u503c\u3002\u56e0\u6b64\uff0c\u5e73\u5747\u6bd4\u8f83\u6b21\u6570\u4e3a(n-1)/2\uff0c\u65f6\u95f4\u590d\u6742\u5ea6\u4e3aO(n)\u3002 \u987a\u5e8f\u641c\u7d22\uff08Sequential Search\uff09 \u6700\u597d\u60c5\u51b5\uff1a\u641c\u7d22\u7684\u5143\u7d20\u521a\u597d\u662f\u5217\u8868\u7684\u7b2c\u4e00\u4e2a\u5143\u7d20\u3002\u8fd9\u65f6\uff0c\u53ea\u9700\u8981\u4e00\u6b21\u6bd4\u8f83\u5c31\u53ef\u4ee5\u627e\u5230\u76ee\u6807\u5143\u7d20\uff0c\u65f6\u95f4\u590d\u6742\u5ea6\u4e3aO(1)\u3002 \u6700\u574f\u60c5\u51b5\uff1a\u641c\u7d22\u7684\u5143\u7d20\u5728\u5217\u8868\u7684\u6700\u540e\u4e00\u4e2a\u4f4d\u7f6e\u6216\u4e0d\u5b58\u5728\u3002\u8fd9\u65f6\uff0c\u9700\u8981\u8fdb\u884cn\u6b21\u6bd4\u8f83\u624d\u80fd\u786e\u5b9a\u76ee\u6807\u5143\u7d20\u4e0d\u5b58\u5728\uff0c\u65f6\u95f4\u590d\u6742\u5ea6\u4e3aO(n)\u3002 \u5e73\u5747\u60c5\u51b5\uff1a\u5e73\u5747\u60c5\u51b5\u4e0b\uff0c\u6bcf\u4e2a\u5143\u7d20\u6709\u76f8\u7b49\u7684\u6982\u7387\u6210\u4e3a\u76ee\u6807\u5143\u7d20\u3002\u56e0\u6b64\uff0c\u5e73\u5747\u6bd4\u8f83\u6b21\u6570\u4e3a (n+1)/2 \uff0c\u65f6\u95f4\u590d\u6742\u5ea6\u4e3aO(n)\u3002 \u5192\u6ce1\u6392\u5e8f\uff08Bubble Sort\uff09 \u6700\u597d\u60c5\u51b5\uff1a\u5982\u679c\u8f93\u5165\u5217\u8868\u5df2\u7ecf\u662f\u6709\u5e8f\u7684\uff0c\u5192\u6ce1\u6392\u5e8f\u53ea\u9700\u8981\u8fdb\u884c\u4e00\u6b21\u904d\u5386\u6765\u68c0\u6d4b\u5217\u8868\u5df2\u7ecf\u6709\u5e8f\uff0c\u65f6\u95f4\u590d\u6742\u5ea6\u4e3aO(n)\u3002\u4f46\u5b9e\u9645\u4e0a\uff0c\u901a\u5e38\u9700\u8981\u8fdb\u884c\u591a\u6b21\u904d\u5386\u6765\u5b8c\u6210\u6392\u5e8f\uff0c\u56e0\u6b64\u6700\u597d\u60c5\u51b5\u4e0b\u7684\u65f6\u95f4\u590d\u6742\u5ea6\u4ecd\u7136\u662fO(n^2)\u3002 \u6700\u574f\u60c5\u51b5\uff1a\u5982\u679c\u8f93\u5165\u5217\u8868\u662f\u9006\u5e8f\u7684\uff0c\u6bcf\u6b21\u904d\u5386\u90fd\u9700\u8981\u8fdb\u884cn-1\u6b21\u4ea4\u6362\uff0c\u603b\u5171\u9700\u8981\u8fdb\u884cn-1\u8f6e\u904d\u5386\uff0c\u65f6\u95f4\u590d\u6742\u5ea6\u4e3aO(n^2)\u3002 \u5e73\u5747\u60c5\u51b5\uff1a\u5e73\u5747\u60c5\u51b5\u4e0b\uff0c\u5192\u6ce1\u6392\u5e8f\u9700\u8981\u8fdb\u884c n(n-1)/2 \u6b21\u6bd4\u8f83\u548c\u4ea4\u6362\u64cd\u4f5c\uff0c\u65f6\u95f4\u590d\u6742\u5ea6\u4e3aO(n^2)\u3002","title":"3.4.4.\u518d\u8bba\u6700\u597d\u60c5\u51b5\u3001\u6700\u574f\u60c5\u51b5\u4ee5\u53ca\u5e73\u5747\u60c5\u51b5\u4e0b\u7684\u6027\u80fd"},{"location":"python/DataStructure/03_TimeComplexity/#345","text":"\u5217\u8868\u91cc\u5982\u4f55\u6392\u5217\u6570\u636e\u624d\u80fd\u8ba9\u9009\u62e9\u6392\u5e8f\u4e2d\u5143\u7d20\u4ea4\u6362\u7684\u6b21\u6570\u6700\u5c11\uff1f\u5982\u4f55\u6392\u5217\u6570\u636e\u624d\u80fd\u8ba9\u5b83\u6267\u884c\u6700\u591a\u7684\u4ea4\u6362\u6b21\u6570\uff1f \u89e3\u7b54\uff1a \u5728\u9009\u62e9\u6392\u5e8f\u4e2d\uff0c\u5143\u7d20\u7684\u4ea4\u6362\u6b21\u6570\u4e3b\u8981\u53d6\u51b3\u4e8e\u5f85\u6392\u5e8f\u5217\u8868\u7684\u521d\u59cb\u6392\u5217\uff1a \u6700\u5c0f\u5316\u4ea4\u6362\u6b21\u6570\uff1a \u8981\u6700\u5c0f\u5316\u9009\u62e9\u6392\u5e8f\u7684\u5143\u7d20\u4ea4\u6362\u6b21\u6570\uff0c\u53ef\u4ee5\u8ba9\u8f93\u5165\u5217\u8868\u5df2\u7ecf\u6309\u5347\u5e8f\u6392\u5217\u3002\u8fd9\u662f\u56e0\u4e3a\u5728\u5347\u5e8f\u6392\u5217\u7684\u60c5\u51b5\u4e0b\uff0c\u9009\u62e9\u6392\u5e8f\u6bcf\u6b21\u9009\u62e9\u6700\u5c0f\u7684\u5143\u7d20\u5e76\u5c06\u5176\u653e\u7f6e\u5728\u6b63\u786e\u7684\u4f4d\u7f6e\uff0c\u65e0\u9700\u4ea4\u6362\u3002\u56e0\u6b64\uff0c\u5143\u7d20\u4ea4\u6362\u7684\u6b21\u6570\u4e3a 0 \u3002 \u6700\u5927\u5316\u4ea4\u6362\u6b21\u6570\uff1a \u8981\u6700\u5927\u5316\u9009\u62e9\u6392\u5e8f\u7684\u5143\u7d20\u4ea4\u6362\u6b21\u6570\uff0c\u53ef\u4ee5\u8ba9\u8f93\u5165\u5217\u8868\u6309\u964d\u5e8f\u6392\u5217\u3002\u5728\u964d\u5e8f\u6392\u5217\u7684\u60c5\u51b5\u4e0b\uff0c\u9009\u62e9\u6392\u5e8f\u6bcf\u6b21\u9009\u62e9\u6700\u5927\u7684\u5143\u7d20\u5e76\u5c06\u5176\u653e\u7f6e\u5728\u6b63\u786e\u7684\u4f4d\u7f6e\uff0c\u8fd9\u5c06\u5bfc\u81f4\u5927\u91cf\u7684\u4ea4\u6362\u64cd\u4f5c\u3002\u5177\u4f53\u6765\u8bf4\uff0c\u5bf9\u4e8e\u957f\u5ea6\u4e3an\u7684\u5217\u8868\uff0c\u6700\u5927\u5316\u4ea4\u6362\u6b21\u6570\u7684\u60c5\u51b5\u4e0b\uff0c\u5c06\u6267\u884c n-1 \u6b21\u4ea4\u6362\u64cd\u4f5c\u3002 \u603b\u4e4b\uff0c\u8981\u6700\u5c0f\u5316\u9009\u62e9\u6392\u5e8f\u7684\u5143\u7d20\u4ea4\u6362\u6b21\u6570\uff0c\u8f93\u5165\u5217\u8868\u5e94\u8be5\u5df2\u7ecf\u6309\u5347\u5e8f\u6392\u5217\u3002\u8981\u6700\u5927\u5316\u4ea4\u6362\u6b21\u6570\uff0c\u8f93\u5165\u5217\u8868\u5e94\u8be5\u6309\u964d\u5e8f\u6392\u5217\u3002\u5728\u5b9e\u9645\u5e94\u7528\u4e2d\uff0c\u9009\u62e9\u6392\u5e8f\u901a\u5e38\u4e0d\u662f\u9996\u9009\u7684\u6392\u5e8f\u7b97\u6cd5\uff0c\u56e0\u4e3a\u5176\u4ea4\u6362\u6b21\u6570\u8f83\u591a\uff0c\u800c\u5176\u4ed6\u7b97\u6cd5\u5982\u5feb\u901f\u6392\u5e8f\u3001\u5f52\u5e76\u6392\u5e8f\u7b49\u5177\u6709\u66f4\u597d\u7684\u6027\u80fd\u3002 \u8bf7\u8bf4\u660e\u6570\u636e\u4ea4\u6362\u7684\u6b21\u6570\u5728\u5206\u6790\u9009\u62e9\u6392\u5e8f\u548c\u5192\u6ce1\u6392\u5e8f\u65f6\u6240\u8d77\u5230\u7684\u4f5c\u7528\u3002\u6570\u636e\u5bf9\u8c61\u7684\u89c4\u6a21\u5728\u5b83\u4eec\u4e4b\u95f4\u53d1\u6325\u7740\u4ec0\u4e48\u4f5c\u7528\uff08\u5982\u679c\u6709\u4f5c\u7528\uff09\uff1f \u89e3\u7b54\uff1a \u6570\u636e\u4ea4\u6362\u7684\u6b21\u6570\u5728\u5206\u6790\u9009\u62e9\u6392\u5e8f\u548c\u5192\u6ce1\u6392\u5e8f\u65f6\u8d77\u5230\u91cd\u8981\u4f5c\u7528\uff0c\u56e0\u4e3a\u5b83\u4eec\u76f4\u63a5\u5f71\u54cd\u5230\u6392\u5e8f\u7b97\u6cd5\u7684\u6027\u80fd\u548c\u6548\u7387\u3002 \u9009\u62e9\u6392\u5e8f\uff08Selection Sort\uff09\uff1a \u9009\u62e9\u6392\u5e8f\u7684\u6570\u636e\u4ea4\u6362\u6b21\u6570\u4e0e\u6570\u636e\u5bf9\u8c61\u7684\u89c4\u6a21\u76f4\u63a5\u76f8\u5173\u3002\u5728\u9009\u62e9\u6392\u5e8f\u4e2d\uff0c\u6bcf\u4e00\u8f6e\u90fd\u4f1a\u9009\u62e9\u672a\u6392\u5e8f\u90e8\u5206\u7684\u6700\u5c0f\u5143\u7d20\uff0c\u5e76\u5c06\u5176\u653e\u7f6e\u5728\u6b63\u786e\u7684\u4f4d\u7f6e\uff0c\u8fd9\u610f\u5473\u7740\u6bcf\u8f6e\u90fd\u9700\u8981\u4e00\u6b21\u4ea4\u6362\u64cd\u4f5c\u3002 \u9009\u62e9\u6392\u5e8f\u7684\u6570\u636e\u4ea4\u6362\u6b21\u6570\u662f\u4e0e\u8f93\u5165\u6570\u636e\u7684\u521d\u59cb\u6392\u5217\u65e0\u5173\u7684\uff0c\u56e0\u4e3a\u5b83\u603b\u662f\u4f1a\u6267\u884c\u76f8\u540c\u6570\u91cf\u7684\u4ea4\u6362\u64cd\u4f5c\uff0c\u65e0\u8bba\u6570\u636e\u662f\u5426\u6709\u5e8f\u3002 \u5bf9\u4e8e\u9009\u62e9\u6392\u5e8f\uff0c\u6570\u636e\u4ea4\u6362\u6b21\u6570\u4e3b\u8981\u53d7\u5230\u6570\u636e\u5bf9\u8c61\u7684\u89c4\u6a21\u5f71\u54cd\uff0c\u800c\u4e0d\u53d7\u6570\u636e\u7684\u5177\u4f53\u6392\u5217\u65b9\u5f0f\u7684\u5f71\u54cd\u3002\u65e0\u8bba\u6570\u636e\u7684\u6392\u5217\u5982\u4f55\uff0c\u9009\u62e9\u6392\u5e8f\u7684\u5e73\u5747\u548c\u6700\u574f\u60c5\u51b5\u4e0b\u7684\u6570\u636e\u4ea4\u6362\u6b21\u6570\u90fd\u662f\u76f8\u540c\u7684\uff0c\u5373 n-1 \u6b21\u3002 \u5192\u6ce1\u6392\u5e8f\uff08Bubble Sort\uff09\uff1a \u5192\u6ce1\u6392\u5e8f\u7684\u6570\u636e\u4ea4\u6362\u6b21\u6570\u4e5f\u4e0e\u6570\u636e\u5bf9\u8c61\u7684\u89c4\u6a21\u76f8\u5173\u3002\u5728\u5192\u6ce1\u6392\u5e8f\u4e2d\uff0c\u76f8\u90bb\u5143\u7d20\u9010\u4e00\u6bd4\u8f83\uff0c\u5982\u679c\u9006\u5e8f\u5c31\u4ea4\u6362\u4f4d\u7f6e\uff0c\u56e0\u6b64\u5192\u6ce1\u6392\u5e8f\u7684\u6570\u636e\u4ea4\u6362\u6b21\u6570\u4e0e\u9006\u5e8f\u5bf9\u7684\u6570\u91cf\u76f8\u5173\u3002 \u5192\u6ce1\u6392\u5e8f\u7684\u6570\u636e\u4ea4\u6362\u6b21\u6570\u5728\u4e0d\u540c\u7684\u6570\u636e\u6392\u5217\u60c5\u51b5\u4e0b\u53ef\u4ee5\u6709\u5f88\u5927\u5dee\u5f02\u3002\u5728\u6700\u597d\u60c5\u51b5\u4e0b\uff08\u8f93\u5165\u6570\u636e\u5df2\u7ecf\u6709\u5e8f\uff09\uff0c\u5192\u6ce1\u6392\u5e8f\u7684\u6570\u636e\u4ea4\u6362\u6b21\u6570\u4e3a 0 \u3002\u5728\u6700\u574f\u60c5\u51b5\u4e0b\uff08\u8f93\u5165\u6570\u636e\u5b8c\u5168\u9006\u5e8f\uff09\uff0c\u5192\u6ce1\u6392\u5e8f\u7684\u6570\u636e\u4ea4\u6362\u6b21\u6570\u662f\u6700\u5927\u7684\u3002 \u5192\u6ce1\u6392\u5e8f\u7684\u6570\u636e\u4ea4\u6362\u6b21\u6570\u65e2\u53d7\u5230\u6570\u636e\u5bf9\u8c61\u7684\u89c4\u6a21\u5f71\u54cd\uff0c\u53c8\u53d7\u5230\u6570\u636e\u7684\u6392\u5217\u65b9\u5f0f\u7684\u5f71\u54cd\u3002\u6700\u597d\u60c5\u51b5\u4e0b\u7684\u4ea4\u6362\u6b21\u6570\u4e3a 0 \uff0c\u6700\u574f\u60c5\u51b5\u4e0b\u7684\u4ea4\u6362\u6b21\u6570\u4e3a n*(n-1)/2 \uff0c\u5e73\u5747\u60c5\u51b5\u4e0b\u7684\u4ea4\u6362\u6b21\u6570\u53d6\u51b3\u4e8e\u6570\u636e\u6392\u5217\u7684\u968f\u673a\u6027\u3002 \u7efc\u4e0a\u6240\u8ff0\uff0c\u6570\u636e\u4ea4\u6362\u7684\u6b21\u6570\u5728\u9009\u62e9\u6392\u5e8f\u548c\u5192\u6ce1\u6392\u5e8f\u7684\u5206\u6790\u4e2d\u662f\u91cd\u8981\u7684\u6027\u80fd\u6307\u6807\u3002\u9009\u62e9\u6392\u5e8f\u7684\u4ea4\u6362\u6b21\u6570\u4e0e\u6570\u636e\u89c4\u6a21\u76f8\u5173\uff0c\u800c\u5192\u6ce1\u6392\u5e8f\u7684\u4ea4\u6362\u6b21\u6570\u65e2\u4e0e\u6570\u636e\u89c4\u6a21\u76f8\u5173\uff0c\u53c8\u53d7\u5230\u6570\u636e\u6392\u5217\u65b9\u5f0f\u7684\u5f71\u54cd\u3002\u5728\u5927\u89c4\u6a21\u6570\u636e\u96c6\u4e0a\uff0c\u5192\u6ce1\u6392\u5e8f\u901a\u5e38\u6bd4\u9009\u62e9\u6392\u5e8f\u66f4\u6162\uff0c\u56e0\u4e3a\u5b83\u7684\u4ea4\u6362\u64cd\u4f5c\u66f4\u591a\u3002\u56e0\u6b64\uff0c\u5728\u5b9e\u9645\u5e94\u7528\u4e2d\uff0c\u901a\u5e38\u9009\u62e9\u6392\u5e8f\u6bd4\u5192\u6ce1\u6392\u5e8f\u66f4\u6709\u6548\u3002\u4f46\u4e24\u8005\u90fd\u4e0d\u662f\u9996\u9009\u7684\u6392\u5e8f\u7b97\u6cd5\uff0c\u66f4\u9ad8\u6548\u7684\u6392\u5e8f\u7b97\u6cd5\u5982\u5feb\u901f\u6392\u5e8f\u3001\u5f52\u5e76\u6392\u5e8f\u7b49\u901a\u5e38\u88ab\u4f18\u5148\u8003\u8651\u3002 \u8bf7\u8bf4\u660e\u4e3a\u4ec0\u4e48\u4fee\u6539\u540e\u7684\u5192\u6ce1\u6392\u5e8f\u5728\u5e73\u5747\u60c5\u51b5\u4e0b\u6027\u80fd\u4ecd\u7136\u4e3aO(n^2)\u3002 \u89e3\u7b54\uff1a \u4fee\u6539\u540e\u7684\u5192\u6ce1\u6392\u5e8f\u5728\u5e73\u5747\u60c5\u51b5\u4e0b\u6027\u80fd\u4ecd\u7136\u4e3aO(n^2)\uff0c\u539f\u56e0\u5982\u4e0b\uff1a \u5192\u6ce1\u6392\u5e8f\u7684\u57fa\u672c\u64cd\u4f5c\u662f\u6bd4\u8f83\u76f8\u90bb\u5143\u7d20\u5e76\u4ea4\u6362\u5b83\u4eec\uff0c\u76f4\u5230\u6574\u4e2a\u5217\u8868\u6309\u7167\u5347\u5e8f\u6392\u5217\u3002\u5728\u4fee\u6539\u540e\u7684\u5192\u6ce1\u6392\u5e8f\u4e2d\uff0c\u5f53\u4e24\u4e2a\u76f8\u90bb\u5143\u7d20\u9006\u5e8f\u65f6\uff0c\u4f1a\u53d1\u751f\u4ea4\u6362\u3002\u8fd9\u4e2a\u57fa\u672c\u64cd\u4f5c\u7684\u590d\u6742\u5ea6\u662fO(1)\uff0c\u56e0\u4e3a\u5b83\u53ea\u6d89\u53ca\u4e24\u4e2a\u5143\u7d20\u7684\u6bd4\u8f83\u548c\u53ef\u80fd\u7684\u4ea4\u6362\u3002 \u4fee\u6539\u540e\u7684\u5192\u6ce1\u6392\u5e8f\u5728\u6bcf\u4e00\u8f6e\u904d\u5386\u4e2d\uff0c\u4ecd\u7136\u9700\u8981\u68c0\u67e5\u76f8\u90bb\u5143\u7d20\u7684\u6bd4\u8f83\uff0c\u5373\u4f7f\u5728\u6709\u5e8f\u90e8\u5206\uff0c\u5b83\u4ecd\u7136\u9700\u8981\u8fdb\u884c\u6bd4\u8f83\u3002\u5728\u6700\u574f\u60c5\u51b5\u4e0b\uff0c\u5b83\u4f1a\u6267\u884cn-1\u6b21\u904d\u5386\uff0c\u6bcf\u6b21\u90fd\u8981\u6bd4\u8f83\u76f8\u90bb\u5143\u7d20\u3002 \u5192\u6ce1\u6392\u5e8f\u7684\u5e73\u5747\u65f6\u95f4\u590d\u6742\u5ea6\u662fO(n^2)\uff0c\u8fd9\u662f\u56e0\u4e3a\u5b83\u4e0d\u4f1a\u5229\u7528\u8f93\u5165\u6570\u636e\u7684\u4efb\u4f55\u6709\u5e8f\u6027\u3002\u65e0\u8bba\u8f93\u5165\u6570\u636e\u662f\u6709\u5e8f\u7684\u3001\u9006\u5e8f\u7684\uff0c\u8fd8\u662f\u968f\u673a\u6392\u5217\u7684\uff0c\u90fd\u9700\u8981\u6267\u884c\u76f8\u540c\u6570\u91cf\u7684\u6bd4\u8f83\u548c\u4ea4\u6362\u64cd\u4f5c\u3002 \u603b\u4e4b\uff0c\u4fee\u6539\u540e\u7684\u5192\u6ce1\u6392\u5e8f\u867d\u7136\u51cf\u5c11\u4e86\u6570\u636e\u4ea4\u6362\u7684\u6b21\u6570\uff0c\u4f46\u5728\u5e73\u5747\u60c5\u51b5\u4e0b\u4ecd\u7136\u9700\u8981\u6267\u884c\u5927\u7ea6 n(n-1)/2 \u6b21\u6bd4\u8f83\u64cd\u4f5c\uff0c\u56e0\u6b64\u5b83\u7684\u5e73\u5747\u65f6\u95f4\u590d\u6742\u5ea6\u4ecd\u7136\u662fO(n^2)\u3002\u5192\u6ce1\u6392\u5e8f\u7684\u6027\u80fd\u4e3b\u8981\u53d7\u5230\u6570\u636e\u89c4\u6a21\u7684\u5f71\u54cd\uff0c\u800c\u4e0d\u592a\u53d7\u5230\u5177\u4f53\u6570\u636e\u6392\u5217\u65b9\u5f0f\u7684\u5f71\u54cd\u3002\u56e0\u6b64\uff0c\u5b83\u5728\u5e73\u5747\u60c5\u51b5\u4e0b\u4ecd\u7136\u5177\u6709\u4e8c\u6b21\u65f6\u95f4\u590d\u6742\u5ea6\u3002 \u8bf7\u8bf4\u660e\u4e3a\u4ec0\u4e48\u63d2\u5165\u6392\u5e8f\u5728\u90e8\u5206\u6709\u5e8f\u7684\u5217\u8868\u4e0a\u80fd\u591f\u5f88\u597d\u5730\u5de5\u4f5c\u3002 \u89e3\u7b54\uff1a \u63d2\u5165\u6392\u5e8f\u4e4b\u6240\u4ee5\u80fd\u591f\u5728\u90e8\u5206\u6709\u5e8f\u7684\u5217\u8868\u4e0a\u5f88\u597d\u5730\u5de5\u4f5c\uff0c\u662f\u56e0\u4e3a\u5b83\u7684\u6838\u5fc3\u601d\u60f3\u662f\u9010\u6b65\u6784\u5efa\u6709\u5e8f\u7684\u5b50\u5217\u8868\uff0c\u800c\u4e0d\u662f\u50cf\u9009\u62e9\u6392\u5e8f\u6216\u5192\u6ce1\u6392\u5e8f\u4e00\u6837\u603b\u662f\u8003\u8651\u6574\u4e2a\u5217\u8868\u3002\u8fd9\u4f7f\u5f97\u63d2\u5165\u6392\u5e8f\u5728\u5904\u7406\u90e8\u5206\u6709\u5e8f\u7684\u5217\u8868\u65f6\u5177\u6709\u4e00\u4e9b\u4f18\u52bf\uff1a \u5c40\u90e8\u6027\u539f\u7406\uff1a\u63d2\u5165\u6392\u5e8f\u5229\u7528\u4e86\u5c40\u90e8\u6027\u539f\u7406\uff0c\u5373\u5728\u5927\u591a\u6570\u60c5\u51b5\u4e0b\uff0c\u6570\u636e\u9879\u7684\u6b63\u786e\u4f4d\u7f6e\u79bb\u5b83\u4eec\u5f53\u524d\u7684\u4f4d\u7f6e\u5f88\u8fd1\u3002\u5728\u90e8\u5206\u6709\u5e8f\u7684\u5217\u8868\u4e2d\uff0c\u5927\u591a\u6570\u6570\u636e\u9879\u5df2\u7ecf\u63a5\u8fd1\u4e8e\u5b83\u4eec\u7684\u6700\u7ec8\u4f4d\u7f6e\uff0c\u56e0\u6b64\u53ea\u9700\u8981\u8fdb\u884c\u5c11\u91cf\u7684\u79fb\u52a8\u64cd\u4f5c\u3002 \u9002\u5e94\u6027\uff1a\u63d2\u5165\u6392\u5e8f\u662f\u4e00\u79cd\u81ea\u9002\u5e94\u6392\u5e8f\u7b97\u6cd5\uff0c\u5b83\u53ef\u4ee5\u6839\u636e\u8f93\u5165\u6570\u636e\u7684\u6709\u5e8f\u6027\u8fdb\u884c\u81ea\u52a8\u8c03\u6574\u3002\u5728\u5904\u7406\u90e8\u5206\u6709\u5e8f\u7684\u5217\u8868\u65f6\uff0c\u63d2\u5165\u6392\u5e8f\u7684\u6027\u80fd\u4f1a\u66f4\u597d\uff0c\u56e0\u4e3a\u4e0d\u9700\u8981\u6267\u884c\u592a\u591a\u7684\u6bd4\u8f83\u548c\u4ea4\u6362\u64cd\u4f5c\u3002 \u7b80\u5355\u6027\uff1a\u63d2\u5165\u6392\u5e8f\u7684\u5b9e\u73b0\u975e\u5e38\u7b80\u5355\u76f4\u89c2\uff0c\u5b83\u53ea\u6d89\u53ca\u5230\u9010\u4e2a\u63d2\u5165\u5143\u7d20\u5230\u6b63\u786e\u7684\u4f4d\u7f6e\u3002\u8fd9\u79cd\u7b80\u5355\u6027\u4f7f\u5f97\u63d2\u5165\u6392\u5e8f\u5728\u67d0\u4e9b\u60c5\u51b5\u4e0b\u6bd4\u66f4\u590d\u6742\u7684\u6392\u5e8f\u7b97\u6cd5\u66f4\u5177\u7ade\u4e89\u529b\u3002 \u867d\u7136\u63d2\u5165\u6392\u5e8f\u5728\u90e8\u5206\u6709\u5e8f\u7684\u5217\u8868\u4e0a\u8868\u73b0\u826f\u597d\uff0c\u4f46\u5728\u5904\u7406\u5927\u89c4\u6a21\u4e71\u5e8f\u6570\u636e\u96c6\u65f6\uff0c\u5b83\u7684\u6027\u80fd\u4e0d\u5982\u5feb\u901f\u6392\u5e8f\u3001\u5f52\u5e76\u6392\u5e8f\u7b49\u66f4\u9ad8\u7ea7\u7684\u6392\u5e8f\u7b97\u6cd5\u3002\u56e0\u6b64\uff0c\u5728\u5b9e\u9645\u5e94\u7528\u4e2d\uff0c\u6839\u636e\u6570\u636e\u7684\u6027\u8d28\u9009\u62e9\u9002\u5f53\u7684\u6392\u5e8f\u7b97\u6cd5\u662f\u91cd\u8981\u7684\u3002\u63d2\u5165\u6392\u5e8f\u901a\u5e38\u9002\u7528\u4e8e\u5c0f\u89c4\u6a21\u6570\u636e\u6216\u8005\u5df2\u7ecf\u90e8\u5206\u6709\u5e8f\u7684\u6570\u636e\uff0c\u800c\u4e0d\u662f\u5927\u89c4\u6a21\u4e71\u5e8f\u6570\u636e\u7684\u6392\u5e8f\u3002","title":"3.4.5.\u7ec3\u4e60\u9898"},{"location":"python/DataStructure/03_TimeComplexity/#35","text":"\u5206\u6cbb\u6cd5\uff08divide-and-conquer\uff09\u7b56\u7565\uff1a\u628a\u5217\u8868\u5206\u6210\u66f4\u5c0f\u7684\u5b50\u5217\u8868\uff0c\u7136\u540e\u518d\u901a\u8fc7\u9012\u5f52\u628a\u8fd9\u4e9b\u5b50\u5217\u8868\u6392\u5e8f\u3002 \u7406\u60f3\u60c5\u51b5\u4e0b\uff0c\u5982\u679c\u8fd9\u4e9b\u88ab\u62c6\u5206\u7684\u5b50\u5217\u8868\u7684\u6570\u91cf\u662f logn \uff0c\u800c\u628a\u6bcf\u4e2a\u5b50\u5217\u8868\u8fdb\u884c\u5408\u5e76\u6240\u9700\u7684\u5de5\u4f5c\u91cf\u4e3a n \uff0c\u90a3\u4e48\u8fd9\u79cd\u6392\u5e8f\u7b97\u6cd5\u7684\u603b\u590d\u6742\u5ea6\u5c31\u662f O(nlogn) \uff0c\u76f8\u6bd4 O(n^2) \u7684\u5de5\u4f5c\u91cf\u589e\u957f\u8981\u4f4e\u5f88\u591a\u3002","title":"3.5.\u66f4\u5feb\u7684\u6392\u5e8f"},{"location":"python/DataStructure/03_TimeComplexity/#351","text":"\u5feb\u901f\u6392\u5e8f\uff08QuickSort\uff09\u662f\u6392\u9664\u7a33\u5b9a\u6027\u56e0\u7d20\u540e\u6700\u5e38\u7528\u7684\u6392\u5e8f\u3002 \u9996\u5148\u4ece\u5217\u8868\u7684\u4e2d\u95f4\u4f4d\u7f6e\u9009\u62e9\u4e00\u4e2a\u5143\u7d20\uff0c\u8fd9\u4e2a\u5143\u7d20\u88ab\u79f0\u4e3a\u57fa\u51c6\uff08pivot\uff09\uff1b \u5bf9\u5217\u8868\u91cc\u7684\u5143\u7d20\u8fdb\u884c\u5206\u5272\uff0c\u628a\u5c0f\u4e8e\u57fa\u51c6\u7684\u6240\u6709\u5143\u7d20\u79fb\u52a8\u5230\u57fa\u51c6\u7684\u5de6\u4fa7\uff0c\u800c\u628a\u5176\u4f59\u5143\u7d20\u90fd\u79fb\u5230\u57fa\u51c6\u7684\u53f3\u4fa7\u3002 \u5982\u679c\u57fa\u51c6\u6b63\u597d\u662f\u6700\u5927\u7684\u5143\u7d20\uff0c\u90a3\u4e48\u5b83\u6700\u7ec8\u4f1a\u5904\u4e8e\u5217\u8868\u7684\u6700\u53f3\u4fa7\uff1b \u5982\u679c\u57fa\u51c6\u6b63\u597d\u662f\u6700\u5c0f\u7684\u5143\u7d20\uff0c\u90a3\u4e48\u5b83\u5c31\u4f1a\u5728\u6700\u5de6\u4fa7\uff1b \u5206\u6cbb\u6cd5\u3002\u5c06\u8fd9\u4e2a\u8fc7\u7a0b\u9012\u5f52\u5730\u5e94\u7528\u5230\u901a\u8fc7\u57fa\u51c6\u800c\u628a\u539f\u5217\u8868\u5206\u5272\u7684\u5b50\u5217\u8868\u4e0a\uff0c\u5176\u4e2d\uff1a \u4e00\u4e2a\u65b0\u7684\u5b50\u5217\u8868\u7531\u57fa\u51c6\u5de6\u4fa7\u7684\u6240\u6709\u5143\u7d20\uff08\u8f83\u5c0f\u7684\u5143\u7d20\uff09\u7ec4\u6210\uff0c \u53e6\u4e00\u4e2a\u65b0\u7684\u5b50\u5217\u8868\u7531\u57fa\u51c6\u53f3\u4fa7\u7684\u6240\u6709\u5143\u7d20\uff08\u8f83\u5927\u7684\u5143\u7d20\uff09\u7ec4\u6210\uff1b \u5f53\u5206\u51fa\u7684\u5b50\u5217\u8868\u5185\u5c11\u4e8e\u4e24\u4e2a\u5143\u7d20\u65f6\uff0c\u8fd9\u4e2a\u8fc7\u7a0b\u7ec8\u6b62\uff1b","title":"3.5.1.\u5feb\u901f\u6392\u5e8f"},{"location":"python/DataStructure/03_TimeComplexity/#3511","text":"\u8fd9\u4e2a\u7b97\u6cd5\u91cc\u6700\u590d\u6742\u7684\u90e8\u5206\u662f\u5bf9\u5143\u7d20\u8fdb\u884c\u5206\u5272\u4ece\u800c\u5f97\u5230\u5b50\u5217\u8868\u7684\u64cd\u4f5c\u3002 \u5c06\u57fa\u51c6\u4e0e\u5b50\u5217\u8868\u91cc\u7684\u6700\u540e\u4e00\u4e2a\u5143\u7d20\u8fdb\u884c\u4ea4\u6362\u3002 \u5728\u5df2\u77e5\u5c0f\u4e8e\u57fa\u51c6\u7684\u5143\u7d20\u548c\u5176\u4ed6\u5143\u7d20\u4e4b\u95f4\u6784\u5efa\u4e00\u4e2a\u8fb9\u754c\u3002\u4e00\u5f00\u59cb\uff0c\u8fd9\u4e2a\u8fb9\u754c\u4f1a\u5904\u4e8e\u7b2c\u4e00\u4e2a\u5143\u7d20\u4e4b\u524d\u3002 \u4ece\u5b50\u5217\u8868\u8fb9\u754c\u4e4b\u540e\u7684\u7b2c\u4e00\u4e2a\u5143\u7d20\u5f00\u59cb\u5411\u53f3\u626b\u63cf\u3002\u5f53\u6bcf\u6b21\u9047\u5230\u5c0f\u4e8e\u57fa\u51c6\u7684\u5143\u7d20\u65f6\uff0c\u5c06\u5b83\u548c\u8fb9\u754c\u4e4b\u540e\u7684\u7b2c\u4e00\u4e2a\u5143\u7d20\u8fdb\u884c\u4ea4\u6362\uff0c\u5e76\u4e14\u5c06\u8fb9\u754c\u5411\u53f3\u79fb\u52a8\u3002 \u5728\u7ed3\u675f\u7684\u65f6\u5019\uff0c\u5c06\u57fa\u51c6\u548c\u8fb9\u754c\u4e4b\u540e\u7684\u7b2c\u4e00\u4e2a\u5143\u7d20\u8fdb\u884c\u4ea4\u6362\u3002 \u793a\u4f8b\u5217\u8868\uff1a[12,19,17,18,14,11,15,13,16]\uff0c\u4e0b\u56fe\u5c55\u793a\u4e86\u5206\u5272\u7684\u6bcf\u4e00\u6b65\u8fc7\u7a0b\u3002","title":"3.5.1.1.\u5206\u5272"},{"location":"python/DataStructure/03_TimeComplexity/#3512","text":"\u5feb\u901f\u6392\u5e8f\uff08Quick Sort\uff09\u662f\u4e00\u79cd\u9ad8\u6548\u7684\u6392\u5e8f\u7b97\u6cd5\uff0c\u5176\u5e73\u5747\u548c\u6700\u574f\u65f6\u95f4\u590d\u6742\u5ea6\u90fd\u662f O(n log n) \u3002\u4e0b\u9762\u662f\u5feb\u901f\u6392\u5e8f\u7684\u590d\u6742\u5ea6\u5206\u6790\uff1a \u5728\u7b2c\u4e00\u6b21\u8fdb\u884c\u5206\u5272\u64cd\u4f5c\u65f6\uff0c\u6211\u4eec\u5c06\u626b\u63cf\u5217\u8868\u91cc\u4ece\u5f00\u5934\u5230\u7ed3\u5c3e\u7684\u6240\u6709\u5143\u7d20\u3002\u56e0\u6b64\uff0c\u5728\u8fd9\u4e2a\u64cd\u4f5c\u671f\u95f4\u5de5\u4f5c\u91cf\u662f\u548c\u5217\u8868\u7684\u957f\u5ea6 n \u6210\u6b63\u6bd4\u7684\u3002\u8fd9\u6b21\u5206\u5272\u4e4b\u540e\u7684\u5de5\u4f5c\u91cf\u4f1a\u548c\u5de6\u5b50\u5217\u8868\u52a0\u4e0a\u53f3\u5b50\u5217\u8868\u7684\u603b\u957f\u5ea6\u6210\u6b63\u6bd4\uff0c\u4e5f\u5c31\u662f n-1 \u3002 \u518d\u6b21\u5bf9\u8fd9\u4e24\u4e2a\u5b50\u5217\u8868\u8fdb\u884c\u5206\u5272\u4e4b\u540e\uff0c\u5c31\u4f1a\u4ea7\u751f4\u4e2a\u52a0\u8d77\u6765\u603b\u957f\u5ea6\u5927\u7ea6\u4e3a n \u7684\u5217\u8868\u6bb5\u3002\u56e0\u6b64\uff0c\u5bf9\u5b83\u4eec\u8fdb\u884c\u5206\u5272\u7684\u603b\u5de5\u4f5c\u91cf\u8fd8\u662f\u548c n \u6210\u6b63\u6bd4\u7684\u3002\u968f\u7740\u5217\u8868\u88ab\u5206\u5272\u6210\u66f4\u591a\u6bb5\uff0c\u603b\u5de5\u4f5c\u91cf\u4f1a\u4e00\u76f4\u548c n \u6210\u6b63\u6bd4\u3002 \u8981\u5b8c\u6210\u6574\u4e2a\u5206\u6790\uff0c\u8fd8\u9700\u8981\u786e\u5b9a\u5217\u8868\u88ab\u5206\u5272\u4e86\u591a\u5c11\u6b21\u3002\u6309\u7167\u6700\u4e50\u89c2\u7684\u60c5\u51b5\u6765\u8bf4\uff08\u867d\u7136\u5728\u5b9e\u9645\u64cd\u4f5c\u7684\u65f6\u5019\uff0c\u901a\u5e38\u5e76\u4e0d\u4f1a\u51fa\u73b0\u8fd9\u4e48\u597d\u7684\u60c5\u51b5\uff09\uff0c\u5047\u8bbe\u6bcf\u6b21\u65b0\u5b50\u5217\u8868\u4e4b\u95f4\u7684\u5206\u754c\u7ebf\u90fd\u5c3d\u53ef\u80fd\u5730\u9760\u8fd1\u5f53\u524d\u5217\u8868\u7684\u4e2d\u5fc3\uff0c\u901a\u5e38\u8fd9\u79cd\u60c5\u51b5\u5e76\u4e0d\u5e38\u89c1\u3002\u4ece\u4e8c\u5206\u641c\u7d22\u7b97\u6cd5\u7684\u8ba8\u8bba\u91cc\u53ef\u77e5\uff0c\u8981\u628a\u5217\u8868\u4e0d\u65ad\u5730\u5206\u6210\u4e24\u534a\uff0c\u5927\u7ea6\u5728 log n \u6b65\u7684\u65f6\u5019\u5c31\u53ea\u5269\u4e0b\u4e00\u4e2a\u5143\u7d20\u4e86\u3002 \u56e0\u6b64\uff0c\u8fd9\u4e2a\u7b97\u6cd5\u5728\u6700\u597d\u60c5\u51b5\u4e0b\u7684\u6027\u80fd\u4e3a O(n log n) \u3002\u5728\u6700\u574f\u60c5\u51b5\u4e0b\uff0c\u6211\u4eec\u6765\u8003\u8651\u6709\u5e8f\u5217\u8868\u7684\u60c5\u51b5\u3002\u5982\u679c\u9009\u62e9\u7684\u57fa\u51c6\u5143\u7d20\u662f\u7b2c\u4e00\u4e2a\u5143\u7d20\uff0c\u90a3\u4e48\u5728\u7b2c\u4e00\u6b21\u5206\u5272\u4e4b\u540e\u5b83\u7684\u53f3\u8fb9\u4f1a\u6709 n-1 \u4e2a\u5143\u7d20\uff0c\u5728\u7b2c\u4e8c\u6b21\u5206\u5272\u4e4b\u540e\u5b83\u7684\u53f3\u8fb9\u6709 n-2 \u4e2a\u5143\u7d20\uff0c\u4ee5\u6b64\u7c7b\u63a8\uff0c \u5c3d\u7ba1\u6574\u4e2a\u64cd\u4f5c\u91cc\u6ca1\u6709\u4ea4\u6362\u4efb\u4f55\u5143\u7d20\uff0c\u4f46\u5206\u5272\u603b\u5171\u4e5f\u6267\u884c\u4e86 n-1 \u6b21\uff0c\u4e8e\u662f\u6267\u884c\u7684\u6bd4\u8f83\u603b\u6570\u5c31\u662f n^2/2-n/2 \u3002\u8fd9\u4e0e\u9009\u62e9\u6392\u5e8f\u4ee5\u53ca\u5192\u6ce1\u6392\u5e8f\u7684\u60c5\u51b5\u662f\u4e00\u6837\u7684\u3002\u56e0\u6b64\uff0c\u5728\u6700\u574f\u60c5\u51b5\u4e0b\uff0c\u5feb\u901f\u6392\u5e8f\u7b97\u6cd5\u7684\u6027\u80fd\u4e3a O(n^2) \u3002\u5982\u679c\u628a\u5feb\u901f\u6392\u5e8f\u5b9e\u73b0\u6210\u9012\u5f52\u7b97\u6cd5\uff0c\u90a3\u4e48\u5728\u5bf9\u5b83\u8fdb\u884c\u5206\u6790\u65f6\u8fd8\u5fc5\u987b\u8981\u8003\u8651\u8c03\u7528\u6808\u7684\u5185\u5b58\u4f7f\u7528\u60c5\u51b5\u3002\u7531\u4e8e\u5bf9\u4e8e\u6808\u7684\u4e00\u5e27\uff0c\u6bcf\u6b21\u9012\u5f52\u8c03\u7528\u90fd\u9700\u8981\u56fa\u5b9a\u7684\u5185\u5b58\uff0c\u5e76\u4e14\u6bcf\u6b21\u5206\u5272\u4e4b\u540e\u90fd\u4f1a\u6709\u4e24\u6b21\u9012\u5f52\u8c03\u7528\u3002\u56e0\u6b64\uff0c\u5728\u6700\u597d\u60c5\u51b5\u4e0b\u5185\u5b58\u7684\u4f7f\u7528\u91cf\u4f1a\u662f O(log n) \uff0c\u800c\u6700\u574f\u60c5\u51b5\u4e0b\u7684\u5185\u5b58\u4f7f\u7528\u91cf\u662f O(n) \u3002 \u5c3d\u7ba1\u5feb\u901f\u6392\u5e8f\u5904\u4e8e\u6700\u574f\u60c5\u51b5\u4e0b\u7684\u53ef\u80fd\u6027\u5f88\u5c0f\uff0c\u6211\u4eec\u8fd8\u662f\u4f1a\u52aa\u529b\u5730\u53bb\u907f\u514d\u8fd9\u79cd\u60c5\u51b5\uff0c\u56e0\u6b64\uff0c\u5b83\u4eec\u5e76\u4e0d\u4f1a\u5728\u7b2c\u4e00\u4e2a\u6216\u6700\u540e\u4e00\u4e2a\u4f4d\u7f6e\u9009\u62e9\u57fa\u51c6\u5143\u7d20\u3002\u6709\u5176\u4ed6\u4e00\u4e9b\u9009\u62e9\u57fa\u51c6\u7684\u65b9\u6cd5\u53ef\u4ee5\u8ba9\u8fd9\u4e2a\u7b97\u6cd5\u5728\u5e73\u5747\u60c5\u51b5\u4e0b\u6709\u5927\u7ea6 O(n log n) \u7684\u6027\u80fd\uff0c\u6bd4\u5982\uff0c\u53ef\u4ee5\u9009\u62e9\u968f\u673a\u4f4d\u7f6e\u4e0a\u7684\u5143\u7d20\u4f5c\u4e3a\u57fa\u51c6\uff0c\u6216\u8005\u9009\u62e9\u6574\u4e2a\u5217\u8868\u91cc\u7b2c\u4e00\u4e2a\u4f4d\u7f6e\u3001\u4e2d\u95f4\u4f4d\u7f6e\u4ee5\u53ca\u6700\u540e\u4e00\u4e2a\u4f4d\u7f6e\u8fd93\u4e2a\u5143\u7d20\u7684\u4e2d\u4f4d\u6570\u3002 \u603b\u7ed3\uff1a \u6700\u597d\u60c5\u51b5\u65f6\u95f4\u590d\u6742\u5ea6\uff1a\u5728\u6700\u597d\u60c5\u51b5\u4e0b\uff0c\u4e5f\u5c31\u662f\u6bcf\u6b21\u9009\u62e9\u7684\u57fa\u51c6\u5143\u7d20\u90fd\u521a\u597d\u5c06\u8f93\u5165\u6570\u636e\u5206\u6210\u4e24\u4e2a\u7b49\u957f\u7684\u5b50\u6570\u7ec4\uff0c\u5feb\u901f\u6392\u5e8f\u7684\u65f6\u95f4\u590d\u6742\u5ea6\u662f O(n log n) \u3002\u8fd9\u79cd\u60c5\u51b5\u901a\u5e38\u53d1\u751f\u5728\u57fa\u51c6\u5143\u7d20\u7684\u9009\u62e9\u975e\u5e38\u5408\u7406\u7684\u60c5\u51b5\u4e0b\uff0c\u4f8b\u5982\u5728\u6bcf\u6b21\u9009\u62e9\u4e2d\u90fd\u9009\u62e9\u4e2d\u95f4\u5143\u7d20\u3002 \u5e73\u5747\u60c5\u51b5\u65f6\u95f4\u590d\u6742\u5ea6\uff1a\u5728\u5e73\u5747\u60c5\u51b5\u4e0b\uff0c\u5feb\u901f\u6392\u5e8f\u7684\u65f6\u95f4\u590d\u6742\u5ea6\u4e5f\u662f O(n log n) \u3002\u8fd9\u662f\u56e0\u4e3a\u5feb\u901f\u6392\u5e8f\u662f\u4e00\u79cd\u5206\u6cbb\u7b97\u6cd5\uff0c\u6bcf\u6b21\u5c06\u95ee\u9898\u5206\u6210\u4e24\u4e2a\u5b50\u95ee\u9898\uff0c\u7136\u540e\u9012\u5f52\u5730\u89e3\u51b3\u8fd9\u4e9b\u5b50\u95ee\u9898\u3002\u5e73\u5747\u60c5\u51b5\u4e0b\uff0c\u6bcf\u6b21\u5206\u5272\u64cd\u4f5c\u90fd\u80fd\u5c06\u95ee\u9898\u89c4\u6a21\u51cf\u534a\uff0c\u56e0\u6b64\u9700\u8981\u6267\u884c O(n log n) \u6b21\u5206\u5272\u64cd\u4f5c\uff0c\u6bcf\u6b21\u5206\u5272\u64cd\u4f5c\u7684\u65f6\u95f4\u590d\u6742\u5ea6\u662f O(n) \u3002\u56e0\u6b64\uff0c\u5e73\u5747\u65f6\u95f4\u590d\u6742\u5ea6\u662f O(n log n) \u3002 \u6700\u574f\u60c5\u51b5\u65f6\u95f4\u590d\u6742\u5ea6\uff1a\u5728\u6700\u574f\u60c5\u51b5\u4e0b\uff0c\u5feb\u901f\u6392\u5e8f\u7684\u65f6\u95f4\u590d\u6742\u5ea6\u662f O(n^2) \u3002\u6700\u574f\u60c5\u51b5\u53d1\u751f\u5728\u6bcf\u6b21\u9009\u62e9\u7684\u57fa\u51c6\u5143\u7d20\u90fd\u662f\u8f93\u5165\u6570\u636e\u4e2d\u7684\u6700\u5c0f\u6216\u6700\u5927\u5143\u7d20\uff0c\u5bfc\u81f4\u5206\u5272\u64cd\u4f5c\u4e0d\u5747\u8861\uff0c\u6bcf\u6b21\u5206\u5272\u53ea\u80fd\u5c06\u95ee\u9898\u89c4\u6a21\u51cf\u5c111\u3002\u5728\u8fd9\u79cd\u60c5\u51b5\u4e0b\uff0c\u5feb\u901f\u6392\u5e8f\u9000\u5316\u4e3a\u5192\u6ce1\u6392\u5e8f\uff0c\u65f6\u95f4\u590d\u6742\u5ea6\u4e3a O(n^2) \u3002 \u5feb\u901f\u6392\u5e8f\u7684\u5e73\u5747\u548c\u6700\u597d\u60c5\u51b5\u65f6\u95f4\u590d\u6742\u5ea6\u4e3a O(n log n) \uff0c\u5728\u5b9e\u9645\u5e94\u7528\u4e2d\u901a\u5e38\u6027\u80fd\u4f18\u8d8a\u3002\u7136\u800c\uff0c\u9700\u8981\u6ce8\u610f\u7684\u662f\uff0c\u6700\u574f\u60c5\u51b5\u4e0b\u7684\u65f6\u95f4\u590d\u6742\u5ea6\u4e3a O(n^2) \uff0c\u56e0\u6b64\u5728\u5b9e\u73b0\u5feb\u901f\u6392\u5e8f\u65f6\u9700\u8981\u7279\u522b\u6ce8\u610f\u57fa\u51c6\u5143\u7d20\u7684\u9009\u62e9\u4ee5\u907f\u514d\u6700\u574f\u60c5\u51b5\u7684\u53d1\u751f\u3002","title":"3.5.1.2.\u5feb\u901f\u6392\u5e8f\u590d\u6742\u5ea6\u5206\u6790"},{"location":"python/DataStructure/03_TimeComplexity/#3513","text":"\u4ee5\u4e0a\u9762\u56fe\u793a\u7684\u5217\u8868 [12,19,17,18,14,11,15,13,16] \u4e3a\u4f8b\uff0c\u4e0b\u9762\u662f\u5b9e\u73b0\u4ee3\u7801\uff1a import random def swap ( lyst , i , j ): \"\"\"\u4ea4\u6362\u5143\u7d20\u4f4d\u7f6e\u4e3ai\u548cj\u7684\u5143\u7d20\"\"\" temp = lyst [ i ] lyst [ i ] = lyst [ j ] lyst [ j ] = temp def quicksort ( lyst ): # left\u7684\u521d\u59cb\u503c\u662f0 # right\u7684\u521d\u59cb\u503c\u662f\u5217\u8868\u957f\u5ea6\u51cf1 quicksortHelper ( lyst , 0 , len ( lyst ) - 1 ) def quicksortHelper ( lyst , left , right ): print ( lyst ) if left < right : pivotLocation = partition ( lyst , left , right ) quicksortHelper ( lyst , left , pivotLocation - 1 ) quicksortHelper ( lyst , pivotLocation + 1 , right ) def partition ( lyst , left , right ): \"\"\"\u5bf9\u5217\u8868\u8fdb\u884c\u5206\u533a\"\"\" # \u627e\u5230\u57fa\u51c6\u5143\u7d20\uff08pivot\uff09\uff0c\u5e76\u548c\u6700\u540e\u4e00\u4e2a\u5143\u7d20\u4e92\u6362 middle = ( left + right ) // 2 pivot = lyst [ middle ] lyst [ middle ] = lyst [ right ] lyst [ right ] = pivot # \u8bbe\u5b9a\u8fb9\u754c\u5143\u7d20\uff08boundary point\uff09\uff0c\u521d\u59cb\u662f\u7b2c\u4e00\u4e2a\u5143\u7d20 boundary = left print ( \"pivot: \" , pivot , \"boundary: \" , lyst [ boundary ]) # \u628a\u6240\u6709\u5c0f\u4e8e\u57fa\u51c6\u7684\u5143\u7d20\u90fd\u79fb\u52a8\u5230\u8fb9\u754c\u7684\u5de6\u8fb9 for index in range ( left , right ): if lyst [ index ] < pivot : swap ( lyst , index , boundary ) boundary += 1 # \u4ea4\u6362\u57fa\u51c6\u5143\u7d20\u548c\u8fb9\u754c\u5143\u7d20 swap ( lyst , right , boundary ) print ( lyst ) return boundary def main ( size = 20 , sort = quicksort ): lyst = [ 12 , 19 , 17 , 18 , 14 , 11 , 15 , 13 , 16 ] sort ( lyst ) if __name__ == \"__main__\" : main () # \u8fd0\u884c\u7ed3\u679c\uff1a # [12, 19, 17, 18, 14, 11, 15, 13, 16] # pivot: 14 boundary: 12 # [12, 11, 13, 14, 16, 19, 15, 17, 18] # [12, 11, 13, 14, 16, 19, 15, 17, 18] # pivot: 11 boundary: 12 # [11, 13, 12, 14, 16, 19, 15, 17, 18] # [11, 13, 12, 14, 16, 19, 15, 17, 18] # [11, 13, 12, 14, 16, 19, 15, 17, 18] # pivot: 13 boundary: 12 # [11, 12, 13, 14, 16, 19, 15, 17, 18] # [11, 12, 13, 14, 16, 19, 15, 17, 18] # [11, 12, 13, 14, 16, 19, 15, 17, 18] # [11, 12, 13, 14, 16, 19, 15, 17, 18] # pivot: 15 boundary: 16 # [11, 12, 13, 14, 15, 19, 18, 17, 16] # [11, 12, 13, 14, 15, 19, 18, 17, 16] # [11, 12, 13, 14, 15, 19, 18, 17, 16] # pivot: 18 boundary: 19 # [11, 12, 13, 14, 15, 16, 17, 18, 19] # [11, 12, 13, 14, 15, 16, 17, 18, 19] # pivot: 16 boundary: 17 # [11, 12, 13, 14, 15, 16, 17, 18, 19] # [11, 12, 13, 14, 15, 16, 17, 18, 19] # [11, 12, 13, 14, 15, 16, 17, 18, 19] # [11, 12, 13, 14, 15, 16, 17, 18, 19] \u628amain()\u6539\u6210\u5982\u4e0b\uff0c\u5219\u53ef\u4ee5\u751f\u6210\u753120\u4e2a\u968f\u673a\u6574\u6570\u7ec4\u6210\u7684\u5217\u8868\uff1a def main ( size = 20 , sort = quicksort ): lyst = [] for count in range ( size ): lyst . append ( random . randint ( 1 , size + 1 )) print ( lyst ) sort ( lyst ) print ( lyst ) # \u8fd0\u884c\u7ed3\u679c\uff1a # \u7b2c\u4e00\u6b21\u8fd0\u884c # [3, 19, 18, 11, 2, 16, 2, 13, 14, 1, 20, 1, 1, 19, 19, 9, 16, 1, 7, 4] # [1, 1, 1, 1, 2, 2, 3, 4, 7, 9, 11, 13, 14, 16, 16, 18, 19, 19, 19, 20] # \u7b2c\u4e8c\u6b21\u8fd0\u884c # [20, 4, 1, 15, 6, 4, 3, 16, 21, 4, 12, 9, 16, 10, 3, 6, 2, 15, 21, 4] # [1, 2, 3, 3, 4, 4, 4, 4, 6, 6, 9, 10, 12, 15, 15, 16, 16, 20, 21, 21]","title":"3.5.1.3.\u5b9e\u73b0\u5feb\u901f\u6392\u5e8f"},{"location":"python/DataStructure/03_TimeComplexity/#352","text":"\u5f52\u5e76\u6392\u5e8f\u7684\u7b97\u6cd5\u4e5f\u662f\u91c7\u7528\u5206\u6cbb\u6cd5\uff08Divide and Conquer\uff09\u7684\u4e00\u4e2a\u975e\u5e38\u5178\u578b\u7684\u5e94\u7528\uff0c\u901a\u8fc7\u9012\u5f52\u548c\u5206\u6cbb\u7b56\u7565\u6765\u7a81\u7834 O(n^2) \u6027\u80fd\u74f6\u9888\u7684\u3002 \u4e0b\u9762\u662f\u5bf9\u8fd9\u4e2a\u7b97\u6cd5\u7684\u7b80\u5355\u63cf\u8ff0\u3002 \u5206\u89e3\uff08Divide\uff09\uff1a\u5c06n\u4e2a\u5143\u7d20\u5206\u6210\u4e2a\u542bn/2\u4e2a\u5143\u7d20\u7684\u5b50\u5e8f\u5217\u3002 \u89e3\u51b3\uff08Conquer\uff09\uff1a\u7528\u5408\u5e76\u6392\u5e8f\u6cd5\u5bf9\u4e24\u4e2a\u5b50\u5e8f\u5217\u9012\u5f52\u7684\u6392\u5e8f\u3002 \u5408\u5e76\uff08Combine\uff09\uff1a\u5408\u5e76\u4e24\u4e2a\u5df2\u6392\u5e8f\u7684\u5b50\u5e8f\u5217\u5df2\u5f97\u5230\u6392\u5e8f\u7ed3\u679c\u3002 \u7b97\u6cd5\u601d\u8def\uff1a \u8fed\u4ee3\u6cd5 \u7533\u8bf7\u7a7a\u95f4\uff0c\u4f7f\u5176\u5927\u5c0f\u4e3a\u4e24\u4e2a\u5df2\u7ecf\u6392\u5e8f\u5e8f\u5217\u4e4b\u548c\uff0c\u8be5\u7a7a\u95f4\u7528\u6765\u5b58\u653e\u5408\u5e76\u540e\u7684\u5e8f\u5217\uff1b \u8bbe\u5b9a\u4e24\u4e2a\u6307\u9488\uff0c\u6700\u521d\u4f4d\u7f6e\u5206\u522b\u4e3a\u4e24\u4e2a\u5df2\u7ecf\u6392\u5e8f\u5e8f\u5217\u7684\u8d77\u59cb\u4f4d\u7f6e\uff1b \u6bd4\u8f83\u4e24\u4e2a\u6307\u9488\u6240\u6307\u5411\u7684\u5143\u7d20\uff0c\u9009\u62e9\u76f8\u5bf9\u5c0f\u7684\u5143\u7d20\u653e\u5165\u5230\u5408\u5e76\u7a7a\u95f4\uff0c\u5e76\u79fb\u52a8\u6307\u9488\u5230\u4e0b\u4e00\u4f4d\u7f6e\uff1b \u91cd\u590d\u6b65\u9aa43\u76f4\u5230\u67d0\u4e00\u6307\u9488\u5230\u8fbe\u5e8f\u5217\u5c3e\uff1b \u5c06\u53e6\u4e00\u5e8f\u5217\u5269\u4e0b\u7684\u6240\u6709\u5143\u7d20\u76f4\u63a5\u590d\u5236\u5230\u5408\u5e76\u5e8f\u5217\u5c3e\uff1b \u9012\u5f52\u6cd5 \u5c06\u5e8f\u5217\u6bcf\u76f8\u90bb\u4e24\u4e2a\u6570\u5b57\u8fdb\u884c\u5f52\u5e76\u64cd\u4f5c\uff0c\u5f62\u6210 floor(n/2) \u4e2a\u5e8f\u5217\uff0c\u6392\u5e8f\u540e\u6bcf\u4e2a\u5e8f\u5217\u5305\u542b\u4e24\u4e2a\u5143\u7d20\uff1b \u5c06\u4e0a\u8ff0\u5e8f\u5217\u518d\u6b21\u5f52\u5e76\uff0c\u5f62\u6210 floor(n/4) \u4e2a\u5e8f\u5217\uff0c\u6bcf\u4e2a\u5e8f\u5217\u5305\u542b\u56db\u4e2a\u5143\u7d20\uff1b \u91cd\u590d\u6b65\u9aa42\uff0c\u76f4\u5230\u6240\u6709\u5143\u7d20\u6392\u5e8f\u5b8c\u6bd5\uff1b \u5728\u9876\u5c42\u5b9a\u4e49\u4e863\u4e2aPython\u51fd\u6570\u8fdb\u884c\u534f\u4f5c\u3002 mergeSort \uff1a\u7528\u6237\u8c03\u7528\u7684\u51fd\u6570\uff1b mergeSortHelper \uff1a\u8f85\u52a9\u51fd\u6570\uff0c\u7528\u6765\u9690\u85cf\u9012\u5f52\u8c03\u7528\u6240\u9700\u8981\u7684\u989d\u5916\u53c2\u6570\uff1b merge \uff1a\u5b9e\u73b0\u5408\u5e76\u8fc7\u7a0b\u7684\u51fd\u6570\uff1b","title":"3.5.2.\u5f52\u5e76\u6392\u5e8f"},{"location":"python/DataStructure/03_TimeComplexity/#3521","text":"\u5408\u5e76\u8fc7\u7a0b\u7528\u5230\u4e00\u4e2a\u4e0e\u5217\u8868\u5927\u5c0f\u76f8\u540c\u7684\u6570\u7ec4\uff0c\u8fd9\u4e2a\u6570\u7ec4\u53ef\u4ee5\u628a\u5b83\u79f0\u4e3a copyBuffer \u3002\u4e3a\u4e86\u907f\u514d\u6bcf\u6b21\u8c03\u7528 merge \u65f6\u90fd\u8981\u4e3a copyBuffer \u7684\u5206\u914d\u548c\u91ca\u653e\u4ea7\u751f\u5f00\u9500\uff0c\u8fd9\u4e2a\u7f13\u51b2\u533a\u4f1a\u5728 mergeSort \u51fd\u6570\u91cc\u5c31\u5206\u914d\u597d\uff0c\u7136\u540e\u4f5c\u4e3a\u53c2\u6570\u4f20\u9012\u7ed9 mergeSortHelper \u548c merge \u51fd\u6570\u3002\u6bcf\u6b21\u8c03\u7528 mergeSortHelper \u51fd\u6570\u65f6\uff0c\u5b83\u8fd8\u9700\u8981\u77e5\u9053\u5e94\u8be5\u4f7f\u7528\u7684\u5b50\u5217\u8868\u7684\u8303\u56f4\u3002\u8fd9\u4e2a\u8303\u56f4\u53ef\u4ee5\u7531\u53e6\u5916\u4e24\u4e2a\u53c2\u6570 low \u548c high \u6765\u63d0\u4f9b\u3002\u5177\u4f53\u5b9e\u73b0\u53c2\u8003 mergeSort \u51fd\u6570\u7684\u4ee3\u7801\u3002 \u5728\u68c0\u67e5\u4f20\u9012\u7684\u5b50\u5217\u8868\u662f\u4e0d\u662f\u81f3\u5c11\u6709\u4e24\u4e2a\u5143\u7d20\u4e4b\u540e\uff0c mergeSortHelper \u51fd\u6570\u5c06\u4f1a\u8ba1\u7b97\u8fd9\u4e2a\u5b50\u5217\u8868\u7684\u4e2d\u70b9\uff0c\u5e76\u4e14\u5bf9\u4e2d\u70b9\u5de6\u53f3\u4e24\u90e8\u5206\u8fdb\u884c\u9012\u5f52\u6392\u5e8f\uff0c\u6700\u540e\u518d\u8c03\u7528 merge \u51fd\u6570\u6765\u5408\u5e76\u7ed3\u679c\u3002\u5177\u4f53\u5b9e\u73b0\u53c2\u8003 mergeSortHelper \u51fd\u6570\u7684\u4ee3\u7801\u3002 merge \u51fd\u6570\u4f1a\u628a\u4e24\u4e2a\u5df2\u7ecf\u6392\u597d\u5e8f\u7684\u5b50\u5217\u8868\u5408\u5e76\u6210\u4e00\u4e2a\u66f4\u5927\u7684\u6709\u5e8f\u5217\u8868\u3002\u5728\u539f\u5217\u8868\u91cc\uff0c\u7b2c\u4e00\u4e2a\u5b50\u5217\u8868\u4f1a\u5728 low \u5230 middle \u4e4b\u95f4\uff1b\u7b2c\u4e8c\u4e2a\u5b50\u5217\u8868\u5219\u4f4d\u4e8e middle + 1 \u548c high \u4e4b\u95f4\u3002\u8fd9\u4e2a\u8fc7\u7a0b\u5305\u542b\u5982\u4e0b3\u4e2a\u6b65\u9aa4\u3002 \u8bbe\u7f6e\u6307\u5411\u4e24\u4e2a\u5b50\u5217\u8868\u4e2d\u7b2c\u4e00\u4e2a\u5143\u7d20\u7684\u7d22\u5f15\u6307\u9488\u3002\u5b83\u4eec\u5206\u522b\u4f4d\u4e8e low \u548c middle +1 \uff1b \u4ece\u5b50\u5217\u8868\u7684\u7b2c\u4e00\u4e2a\u5143\u7d20\u5f00\u59cb\u91cd\u590d\u6bd4\u8f83\u8fd9\u4e9b\u5143\u7d20\u3002\u628a\u66f4\u5c0f\u7684\u90a3\u4e2a\u5143\u7d20\u4ece\u5b83\u6240\u5728\u7684\u5b50\u5217\u8868\u91cc\u590d\u5236\u5230\u62f7\u8d1d\u7f13\u51b2\u533a\u53bb\uff0c\u7136\u540e\u628a\u8fd9\u4e2a\u5b50\u5217\u8868\u7684\u7d22\u5f15\u79fb\u52a8\u5230\u4e0b\u4e00\u4e2a\u5143\u7d20\uff1b \u4e0d\u65ad\u5730\u6267\u884c\u8fd9\u4e2a\u64cd\u4f5c\uff0c\u76f4\u5230\u5df2\u7ecf\u5b8c\u5168\u590d\u5236\u4e86\u4e24\u4e2a\u5b50\u5217\u8868\u91cc\u7684\u6240\u6709\u5143\u7d20\u3002\u5982\u679c\u5176\u4e2d\u4e00\u4e2a\u5b50\u5217\u8868\u5df2\u7ecf\u5230\u8fbe\u4e86\u672b\u5c3e\uff0c\u90a3\u4e48\u53ef\u4ee5\u628a\u53e6\u4e00\u4e2a\u5b50\u5217\u8868\u91cc\u7684\u5176\u4f59\u5143\u7d20\u76f4\u63a5\u590d\u5236\u8fc7\u53bb\uff1b \u628a copyBuffer \u4e2d low \u5230 high \u4e4b\u95f4\u7684\u90e8\u5206\u590d\u5236\u56de lyst \u4e2d\u7684\u76f8\u5e94\u4f4d\u7f6e\uff1b \u5b9e\u73b0\u4ee3\u7801\uff1a class Array ( object ): \"\"\" \u63cf\u8ff0\u4e00\u4e2a\u6570\u7ec4\u3002 \u6570\u7ec4\u7c7b\u4f3c\u5217\u8868\uff0c\u4f46\u6570\u7ec4\u53ea\u80fd\u4f7f\u7528[], len, iter, \u548c str\u8fd9\u4e9b\u5c5e\u6027\u3002 \u5b9e\u4f8b\u5316\u4e00\u4e2a\u6570\u7ec4\uff0c\u4f7f\u7528 = Array(, ) \u5176\u4e2dfill value\u9ed8\u8ba4\u503c\u662fNone\u3002 \"\"\" def __init__ ( self , capacity , fillValue = None ): \"\"\"Capacity\u662f\u6570\u7ec4\u7684\u5927\u5c0f. fillValue\u4f1a\u586b\u5145\u5728\u6bcf\u4e2a\u5143\u7d20\u4f4d\u7f6e, \u9ed8\u8ba4\u503c\u662fNone\"\"\" self . items = list () for count in range ( capacity ): self . items . append ( fillValue ) def __len__ ( self ): \"\"\"-> \u6570\u7ec4\u7684\u5927\u5c0f\"\"\" return len ( self . items ) def __str__ ( self ): \"\"\"-> \u5c06\u6570\u7ec4\u5b57\u7b26\u4e32\u5316\"\"\" return str ( self . items ) def __iter__ ( self ): \"\"\"\u652f\u6301for\u5faa\u73af\u5bf9\u6570\u7ec4\u8fdb\u884c\u904d\u5386.\"\"\" return iter ( self . items ) def __getitem__ ( self , index ): \"\"\"\u7528\u4e8e\u8bbf\u95ee\u7d22\u5f15\u5904\u7684\u4e0b\u6807\u8fd0\u7b97\u7b26.\"\"\" return self . items [ index ] def __setitem__ ( self , index , newItem ): \"\"\"\u4e0b\u6807\u8fd0\u7b97\u7b26\u7528\u4e8e\u5728\u7d22\u5f15\u5904\u8fdb\u884c\u66ff\u6362.\"\"\" self . items [ index ] = newItem def mergeSort ( lyst ): # lyst : \u7528\u4e8e\u6392\u5e8f\u7684\u5217\u8868 # copyBuffer : \u7528\u4e8e\u5408\u5e76\u7684\u4e34\u65f6\u7a7a\u95f4 copyBuffer = Array ( len ( lyst )) mergeSortHelper ( lyst , copyBuffer , 0 , len ( lyst ) - 1 ) def mergeSortHelper ( lyst , copyBuffer , low , high ): # lyst : \u7528\u4e8e\u6392\u5e8f\u7684\u5217\u8868 # copyBuffer : \u7528\u4e8e\u5408\u5e76\u7684\u4e34\u65f6\u7a7a\u95f4 # low, high : \u5b50\u5217\u8868\u7684\u8fb9\u754c # middle : \u5b50\u5217\u8868\u7684\u4e2d\u70b9 if low < high : middle = ( low + high ) // 2 print ( f 'low: { lyst [ low ] } , middle: { lyst [ middle ] } , high: { lyst [ high ] } , copyBuffer: { copyBuffer } ' ) # \u9012\u5f52\u5904\u7406\u7b2c\u4e00\u4e2a\u6392\u5e8f\u5b50\u5217\u8868\uff0c\u5373\u4e2d\u503c\u7684\u5de6\u6bb5\uff0c\u76f4\u81f3\u4e0d\u6ee1\u8db3low < high\u65f6\u9000\u51fa mergeSortHelper ( lyst , copyBuffer , low , middle ) # \u9012\u5f52\u5904\u7406\u7b2c\u4e8c\u4e2a\u6392\u5e8f\u5b50\u5217\u8868\uff0c\u5373\u4e2d\u503c\u7684\u53f3\u6bb5\uff0c\u76f4\u81f3\u4e0d\u6ee1\u8db3low < high\u65f6\u9000\u51fa mergeSortHelper ( lyst , copyBuffer , middle + 1 , high ) # \u5f53\u524d\u5904\u7406\u7684\u5b50\u8868\u6570\u636e\u9001\u5165copyBuffer\uff0c\u5408\u5e76\u4e14\u6392\u5e8f merge ( lyst , copyBuffer , low , middle , high ) def merge ( lyst , copyBuffer , low , middle , high ): # lyst : \u7528\u4e8e\u6392\u5e8f\u7684\u5217\u8868 # copyBuffer : \u7528\u4e8e\u5408\u5e76\u7684\u4e34\u65f6\u7a7a\u95f4 # low : \u7b2c\u4e00\u4e2a\u6392\u5e8f\u5b50\u5217\u8868\u7684\u5f00\u5934 # middle : \u7b2c\u4e00\u4e2a\u6392\u5e8f\u5b50\u5217\u8868\u7684\u7ed3\u5c3e # middle + 1 : \u7b2c\u4e8c\u4e2a\u6392\u5e8f\u5b50\u5217\u8868\u7684\u5f00\u5934 # high : \u7b2c\u4e8c\u4e2a\u6392\u5e8f\u5b50\u5217\u8868\u7684\u7ed3\u5c3e # \u5c06 i1 \u548c i2 \u521d\u59cb\u5316\u4e3a\u6bcf\u4e2a\u5b50\u5217\u8868\u4e2d\u7684\u7b2c\u4e00\u9879 i1 = low i2 = middle + 1 # \u5c06\u5b50\u5217\u8868\u4e2d\u7684\u5143\u7d20\u4ea4\u9519\u653e\u5165copyBuffer\u4e2d\uff0c\u5e76\u4fdd\u6301\u987a\u5e8f\u3002 for i in range ( low , high + 1 ): if i1 > middle : copyBuffer [ i ] = lyst [ i2 ] # \u7b2c\u4e00\u4e2a\u5b50\u5217\u8868\u5df2\u7528\u5b8c i2 += 1 elif i2 > high : copyBuffer [ i ] = lyst [ i1 ] # \u7b2c\u4e8c\u4e2a\u5b50\u5217\u8868\u5df2\u7528\u5b8c i1 += 1 elif lyst [ i1 ] < lyst [ i2 ]: copyBuffer [ i ] = lyst [ i1 ] # \u7b2c\u4e00\u4e2a\u5b50\u8868\u4e2d\u7684\u5143\u7d20 < i1 += 1 else : copyBuffer [ i ] = lyst [ i2 ] # \u7b2c\u4e8c\u4e2a\u5b50\u8868\u4e2d\u7684\u5143\u7d20 < i2 += 1 print ( \"i=\" , i , \"\" , \"i1=\" , i1 , \"i2=\" , i2 , \"copyBuffer:\" , copyBuffer ) for i in range ( low , high + 1 ): # \u5c06\u5df2\u6392\u5e8f\u7684\u5143\u7d20\u590d\u5236\u56delyst\u4e2d\u7684\u6b63\u786e\u4f4d\u7f6e lyst [ i ] = copyBuffer [ i ] def main (): lyst = [ 12 , 19 , 17 , 18 , 14 , 11 , 15 , 13 , 16 ] print ( \"Original List\" , lyst ) mergeSort ( lyst ) print ( \"Sorted List\" , lyst ) if __name__ == \"__main__\" : main () # \u8fd0\u884c\u7ed3\u679c\uff1a # Original List [12, 19, 17, 18, 14, 11, 15, 13, 16] # low: 12, middle: 14, high: 16, copyBuffer: [None, None, None, None, None, None, None, None, None] # low: 12, middle: 17, high: 14, copyBuffer: [None, None, None, None, None, None, None, None, None] # low: 12, middle: 19, high: 17, copyBuffer: [None, None, None, None, None, None, None, None, None] # low: 12, middle: 12, high: 19, copyBuffer: [None, None, None, None, None, None, None, None, None] # i= 1 i1= 1 i2= 2 copyBuffer: [12, 19, None, None, None, None, None, None, None] # i= 2 i1= 2 i2= 3 copyBuffer: [12, 17, 19, None, None, None, None, None, None] # low: 18, middle: 18, high: 14, copyBuffer: [12, 17, 19, None, None, None, None, None, None] # i= 4 i1= 4 i2= 5 copyBuffer: [12, 17, 19, 14, 18, None, None, None, None] # i= 4 i1= 3 i2= 5 copyBuffer: [12, 14, 17, 18, 19, None, None, None, None] # low: 11, middle: 15, high: 16, copyBuffer: [12, 14, 17, 18, 19, None, None, None, None] # low: 11, middle: 11, high: 15, copyBuffer: [12, 14, 17, 18, 19, None, None, None, None] # i= 6 i1= 6 i2= 7 copyBuffer: [12, 14, 17, 18, 19, 11, 15, None, None] # low: 13, middle: 13, high: 16, copyBuffer: [12, 14, 17, 18, 19, 11, 15, None, None] # i= 8 i1= 8 i2= 9 copyBuffer: [12, 14, 17, 18, 19, 11, 15, 13, 16] # i= 8 i1= 7 i2= 9 copyBuffer: [12, 14, 17, 18, 19, 11, 13, 15, 16] # i= 8 i1= 5 i2= 9 copyBuffer: [11, 12, 13, 14, 15, 16, 17, 18, 19] # Sorted List [11, 12, 13, 14, 15, 16, 17, 18, 19] \u8fd0\u884c\u7ed3\u679c\u56fe\u793a\u5206\u6790\uff1a","title":"3.5.2.1.\u5408\u5e76\u8fc7\u7a0b\u7684\u5b9e\u73b0"},{"location":"python/DataStructure/03_TimeComplexity/#3522","text":"merge \u51fd\u6570\u7684\u8fd0\u884c\u65f6\u7531\u4e24\u4e2a for \u8bed\u53e5\u6765\u51b3\u5b9a\uff0c\u800c\u8fd9\u4e24\u4e2a\u5faa\u73af\u90fd\u4f1a\u88ab\u8fed\u4ee3 (high \u2013 low + 1) \u6b21\uff0c\u56e0\u6b64\uff0c\u8fd9\u4e2a\u51fd\u6570\u7684\u8fd0\u884c\u65f6\u662f O(high\u2212low) \uff0c\u4e8e\u662f\u6bcf\u4e00\u5c42\u4e0a\u7684\u6240\u6709\u5408\u5e76\u603b\u5171\u9700\u8981 O(n) \u7684\u65f6\u95f4\u3002\u56e0\u4e3a mergeSortHelper \u5728\u6bcf\u4e00\u5c42\u90fd\u5c3d\u53ef\u80fd\u5747\u5300\u5730\u62c6\u5206\u5b50\u5217\u8868\uff0c\u6240\u4ee5\u5c42\u6570\u5e94\u8be5\u662f O(log n) \uff0c\u5728\u6240\u6709\u7684\u60c5\u51b5\u4e0b\u8fd9\u4e2a\u51fd\u6570\u7684\u6700\u5927\u8fd0\u884c\u65f6\u90fd\u662f O(n log n) \u3002 \u5f52\u5e76\u6392\u5e8f\u4f1a\u6709\u4e24\u4e2a\u57fa\u4e8e\u5217\u8868\u5927\u5c0f\u7684\u7a7a\u95f4\u9700\u6c42\u3002\u9996\u5148\uff0c\u5728\u8c03\u7528\u6808\u4e0a\u9700\u8981 O(log n) \u7684\u7a7a\u95f4\u6765\u652f\u6301\u9012\u5f52\u8c03\u7528\uff1b\u5176\u6b21\uff0c\u62f7\u8d1d\u7f13\u51b2\u533a\u4f1a\u7528\u5230 O(n) \u7684\u7a7a\u95f4\u3002","title":"3.5.2.2.\u5f52\u5e76\u6392\u5e8f\u7684\u590d\u6742\u5ea6\u5206\u6790"},{"location":"python/DataStructure/03_TimeComplexity/#353","text":"\u63cf\u8ff0\u5feb\u901f\u6392\u5e8f\u7684\u7b56\u7565\uff0c\u5e76\u8bf4\u660e\u4e3a\u4ec0\u4e48\u5b83\u53ef\u4ee5\u628a\u6392\u5e8f\u7684\u65f6\u95f4\u590d\u6742\u5ea6\u4ece O(n^2) \u964d\u4f4e\u5230 O(n log n) \u3002 \u89e3\u7b54\uff1a\u5feb\u901f\u6392\u5e8f\uff08Quick Sort\uff09\u662f\u4e00\u79cd\u9ad8\u6548\u7684\u6392\u5e8f\u7b97\u6cd5\uff0c\u5b83\u91c7\u7528\u5206\u6cbb\u7b56\u7565\u6765\u5c06\u4e00\u4e2a\u5927\u95ee\u9898\u5206\u89e3\u6210\u82e5\u5e72\u4e2a\u5b50\u95ee\u9898\uff0c\u7136\u540e\u9012\u5f52\u5730\u89e3\u51b3\u8fd9\u4e9b\u5b50\u95ee\u9898\u3002\u4ee5\u4e0b\u662f\u5feb\u901f\u6392\u5e8f\u7684\u7b56\u7565\u548c\u539f\u7406\uff0c\u4ee5\u53ca\u4e3a\u4ec0\u4e48\u5b83\u80fd\u591f\u5c06\u6392\u5e8f\u7684\u65f6\u95f4\u590d\u6742\u5ea6\u4ece O(n^2) \u964d\u4f4e\u5230 O(n log n) \uff1a \u5feb\u901f\u6392\u5e8f\u7684\u7b56\u7565\uff1a \u9009\u62e9\u4e3b\u5143\uff08Pivot\uff09\uff1a\u5728\u5feb\u901f\u6392\u5e8f\u4e2d\uff0c\u9996\u5148\u4ece\u5f85\u6392\u5e8f\u7684\u5143\u7d20\u4e2d\u9009\u62e9\u4e00\u4e2a\u4e3b\u5143\uff08\u901a\u5e38\u662f\u7b2c\u4e00\u4e2a\u6216\u6700\u540e\u4e00\u4e2a\u5143\u7d20\uff09\uff0c\u4e5f\u53eb\u57fa\u51c6\u5143\u7d20\u3002 \u5206\u5272\u64cd\u4f5c\uff1a\u5c06\u5143\u7d20\u5206\u4e3a\u4e24\u4e2a\u5b50\u6570\u7ec4\uff0c\u4e00\u4e2a\u5c0f\u4e8e\u4e3b\u5143\u7684\u5b50\u6570\u7ec4\uff0c\u4e00\u4e2a\u5927\u4e8e\u4e3b\u5143\u7684\u5b50\u6570\u7ec4\u3002\u8fd9\u4e2a\u8fc7\u7a0b\u79f0\u4e3a\u5206\u5272\u3002 \u9012\u5f52\u6392\u5e8f\uff1a\u9012\u5f52\u5730\u5bf9\u4e24\u4e2a\u5b50\u6570\u7ec4\u8fdb\u884c\u6392\u5e8f\u3002\u5373\uff0c\u5bf9\u5c0f\u4e8e\u4e3b\u5143\u7684\u5b50\u6570\u7ec4\u548c\u5927\u4e8e\u4e3b\u5143\u7684\u5b50\u6570\u7ec4\u5206\u522b\u8fdb\u884c\u5feb\u901f\u6392\u5e8f\u3002 \u5408\u5e76\uff1a\u5c06\u5df2\u6392\u5e8f\u7684\u5b50\u6570\u7ec4\u5408\u5e76\u6210\u6700\u7ec8\u7684\u6709\u5e8f\u6570\u7ec4\u3002 \u4e3a\u4ec0\u4e48\u5feb\u901f\u6392\u5e8f\u80fd\u591f\u964d\u4f4e\u65f6\u95f4\u590d\u6742\u5ea6\uff1a \u5feb\u901f\u6392\u5e8f\u4e4b\u6240\u4ee5\u80fd\u591f\u5c06\u6392\u5e8f\u7684\u65f6\u95f4\u590d\u6742\u5ea6\u4ece O(n^2) \u964d\u4f4e\u5230 O(n log n) \uff0c\u4e3b\u8981\u6709\u4ee5\u4e0b\u539f\u56e0\uff1a \u5206\u6cbb\u7b56\u7565\uff1a\u5feb\u901f\u6392\u5e8f\u91c7\u7528\u4e86\u5206\u6cbb\u7b56\u7565\uff0c\u5c06\u4e00\u4e2a\u5927\u95ee\u9898\u5206\u89e3\u6210\u4e24\u4e2a\u6216\u591a\u4e2a\u89c4\u6a21\u8f83\u5c0f\u7684\u5b50\u95ee\u9898\u3002\u8fd9\u79cd\u5206\u6cbb\u7b56\u7565\u80fd\u591f\u51cf\u5c0f\u95ee\u9898\u7684\u89c4\u6a21\uff0c\u4ece\u800c\u964d\u4f4e\u4e86\u89e3\u51b3\u95ee\u9898\u7684\u590d\u6742\u5ea6\u3002 \u597d\u7684\u5e73\u5747\u60c5\u51b5\uff1a\u5728\u5e73\u5747\u60c5\u51b5\u4e0b\uff0c\u5feb\u901f\u6392\u5e8f\u5bf9\u5f85\u6392\u5e8f\u7684\u6570\u636e\u8fdb\u884c\u4e86\u826f\u597d\u7684\u5e73\u5747\u5206\u5272\uff0c\u6bcf\u6b21\u5206\u5272\u90fd\u5c06\u95ee\u9898\u89c4\u6a21\u51cf\u534a\u3002\u8fd9\u4f7f\u5f97\u5e73\u5747\u65f6\u95f4\u590d\u6742\u5ea6\u4e3a O(n log n) \u3002 **\u4e0d\u7a33\u5b9a\u6027\uff1a\u5feb\u901f\u6392\u5e8f\u662f\u4e0d\u7a33\u5b9a\u7684\u6392\u5e8f\u7b97\u6cd5\uff0c\u8fd9\u610f\u5473\u7740\u76f8\u540c\u5143\u7d20\u7684\u76f8\u5bf9\u987a\u5e8f\u5728\u6392\u5e8f\u540e\u53ef\u80fd\u4f1a\u6539\u53d8\u3002\u8fd9\u79cd\u4e0d\u7a33\u5b9a\u6027\u4f7f\u5f97\u5feb\u901f\u6392\u5e8f\u53ef\u4ee5\u66f4\u5feb\u5730\u6392\u5e8f\u76f8\u540c\u5143\u7d20\u7684\u5927\u6570\u636e\u96c6\u3002 \u539f\u5730\u6392\u5e8f\uff1a\u5feb\u901f\u6392\u5e8f\u901a\u5e38\u662f\u539f\u5730\u6392\u5e8f\u7684\uff0c\u5b83\u4e0d\u9700\u8981\u989d\u5916\u7684\u5185\u5b58\u6765\u5b58\u50a8\u4e34\u65f6\u6570\u636e\u3002\u8fd9\u5bf9\u4e8e\u5185\u5b58\u5360\u7528\u6709\u9650\u7684\u60c5\u51b5\u5f88\u6709\u5229\u3002 \u6700\u574f\u60c5\u51b5\u4e0b\uff0c\u5feb\u901f\u6392\u5e8f\u7684\u65f6\u95f4\u590d\u6742\u5ea6\u4ecd\u7136\u662f O(n^2) \uff0c\u8fd9\u79cd\u60c5\u51b5\u901a\u5e38\u53d1\u751f\u5728\u4e3b\u5143\u9009\u62e9\u4e0d\u5f53\u6216\u8f93\u5165\u6570\u636e\u5df2\u7ecf\u6709\u5e8f\u7684\u60c5\u51b5\u4e0b\u3002\u5728\u5b9e\u9645\u5e94\u7528\u4e2d\uff0c\u901a\u5e38\u9700\u8981\u9009\u62e9\u4e00\u4e2a\u5408\u9002\u7684\u4e3b\u5143\u9009\u62e9\u7b56\u7565\uff0c\u4ee5\u5c3d\u91cf\u907f\u514d\u6700\u574f\u60c5\u51b5\u7684\u53d1\u751f\u3002 \u4e3a\u4ec0\u4e48\u5feb\u901f\u6392\u5e8f\u5e76\u4e0d\u5728\u6240\u6709\u60c5\u51b5\u4e0b\u90fd\u6709 O(n log n) \u7684\u590d\u6742\u5ea6\uff1f\u5bf9\u5feb\u901f\u6392\u5e8f\u7684\u6700\u574f\u60c5\u51b5\u8fdb\u884c\u63cf\u8ff0\uff0c\u5e76\u7ed9\u51fa\u4e00\u4e2a\u4f1a\u4ea7\u751f\u8fd9\u4e2a\u60c5\u51b5\u7684\u5305\u542b10\u4e2a\u6574\u6570\uff081\uff5e10\uff09\u7684\u5217\u8868\u3002 \u89e3\u7b54\uff1a\u5feb\u901f\u6392\u5e8f\u5e76\u4e0d\u5728\u6240\u6709\u60c5\u51b5\u4e0b\u90fd\u5177\u6709 O(n log n) \u7684\u65f6\u95f4\u590d\u6742\u5ea6\uff0c\u5b83\u7684\u6027\u80fd\u53d6\u51b3\u4e8e\u4e3b\u5143\uff08pivot\uff09\u7684\u9009\u62e9\u548c\u8f93\u5165\u6570\u636e\u7684\u5206\u5e03\u60c5\u51b5\u3002\u6700\u574f\u60c5\u51b5\u53d1\u751f\u5728\u4ee5\u4e0b\u60c5\u51b5\u4e0b\uff1a \u4e3b\u5143\u9009\u62e9\u4e0d\u5f53\uff1a\u5982\u679c\u6bcf\u6b21\u9009\u62e9\u7684\u4e3b\u5143\u90fd\u662f\u8f93\u5165\u6570\u636e\u4e2d\u7684\u6700\u5c0f\u6216\u6700\u5927\u5143\u7d20\uff0c\u5feb\u901f\u6392\u5e8f\u5c06\u4f1a\u4ea7\u751f\u6700\u574f\u60c5\u51b5\u3002\u5728\u8fd9\u79cd\u60c5\u51b5\u4e0b\uff0c\u5206\u5272\u64cd\u4f5c\u5c06\u5bfc\u81f4\u4e00\u4e2a\u5b50\u6570\u7ec4\u4e3a\u7a7a\uff0c\u53e6\u4e00\u4e2a\u5b50\u6570\u7ec4\u7684\u5927\u5c0f\u4e3a\u539f\u59cb\u6570\u7ec4\u5927\u5c0f\u51cf\u4e00\u3002\u8fd9\u4f7f\u5f97\u6bcf\u6b21\u5206\u5272\u64cd\u4f5c\u53ea\u51cf\u5c11\u4e00\u4e2a\u5143\u7d20\uff0c\u5bfc\u81f4\u9012\u5f52\u6df1\u5ea6\u8fbe\u5230\u6700\u5927\uff0c\u65f6\u95f4\u590d\u6742\u5ea6\u4e3a O(n^2) \u3002 \u8f93\u5165\u6570\u636e\u5df2\u7ecf\u6709\u5e8f\uff1a\u5982\u679c\u8f93\u5165\u6570\u636e\u5df2\u7ecf\u662f\u6709\u5e8f\u7684\uff0c\u4e0d\u7ba1\u662f\u5347\u5e8f\u8fd8\u662f\u964d\u5e8f\uff0c\u5feb\u901f\u6392\u5e8f\u4e5f\u4f1a\u4ea7\u751f\u6700\u574f\u60c5\u51b5\u3002\u56e0\u4e3a\u65e0\u8bba\u5982\u4f55\u9009\u62e9\u4e3b\u5143\uff0c\u5206\u5272\u64cd\u4f5c\u90fd\u5c06\u5bfc\u81f4\u4e00\u4e2a\u5b50\u6570\u7ec4\u4e3a\u7a7a\uff0c\u53e6\u4e00\u4e2a\u5b50\u6570\u7ec4\u7684\u5927\u5c0f\u4e3a\u539f\u59cb\u6570\u7ec4\u5927\u5c0f\u51cf\u4e00\u3002 \u4e0b\u9762\u662f\u4e00\u4e2a\u5305\u542b10\u4e2a\u6574\u6570\uff081\uff5e10\uff09\u7684\u5217\u8868\uff0c\u6f14\u793a\u4e86\u5bfc\u81f4\u5feb\u901f\u6392\u5e8f\u6700\u574f\u60c5\u51b5\u7684\u8f93\u5165\u6570\u636e\uff1a [ 10 , 9 , 8 , 7 , 6 , 5 , 4 , 3 , 2 , 1 ] \u5728\u8fd9\u4e2a\u793a\u4f8b\u4e2d\uff0c\u6bcf\u6b21\u9009\u62e9\u7684\u4e3b\u5143\u90fd\u662f\u6700\u5927\u7684\u5143\u7d20\uff0810\uff09\uff0c\u5bfc\u81f4\u5206\u5272\u64cd\u4f5c\u4e0d\u65ad\u51cf\u5c11\u6570\u7ec4\u7684\u5927\u5c0f\uff0c\u9012\u5f52\u6df1\u5ea6\u8fbe\u5230\u6700\u5927\uff0c\u65f6\u95f4\u590d\u6742\u5ea6\u4e3a O(n^2) \u3002 \u8981\u907f\u514d\u6700\u574f\u60c5\u51b5\uff0c\u901a\u5e38\u91c7\u7528\u4ee5\u4e0b\u7b56\u7565\uff1a \u9009\u62e9\u5408\u9002\u7684\u4e3b\u5143\uff0c\u4f8b\u5982\u9009\u62e9\u4e2d\u95f4\u5143\u7d20\uff0c\u4ee5\u786e\u4fdd\u5e73\u5747\u5206\u5272\u3002 \u968f\u673a\u9009\u62e9\u4e3b\u5143\uff0c\u4ee5\u51cf\u5c11\u51fa\u73b0\u6700\u574f\u60c5\u51b5\u7684\u6982\u7387\u3002 \u8fd9\u4e9b\u7b56\u7565\u6709\u52a9\u4e8e\u7ef4\u6301\u5feb\u901f\u6392\u5e8f\u7684\u5e73\u5747\u65f6\u95f4\u590d\u6742\u5ea6\u4e3a O(n log n) \u3002 \u5feb\u901f\u6392\u5e8f\u91cc\u7684\u5206\u5272\u64cd\u4f5c\u4f1a\u9009\u62e9\u4e2d\u70b9\u5143\u7d20\u4f5c\u4e3a\u57fa\u51c6\u3002\u8bf7\u63cf\u8ff0\u53e6\u5916\u4e24\u79cd\u9009\u62e9\u57fa\u51c6\u7684\u7b56\u7565\u3002 \u89e3\u7b54\uff1a\u5feb\u901f\u6392\u5e8f\u4e2d\u7684\u5206\u5272\u64cd\u4f5c\u53ef\u4ee5\u9009\u62e9\u4e2d\u70b9\u5143\u7d20\u4f5c\u4e3a\u57fa\u51c6\uff0c\u4f46\u8fd8\u6709\u5176\u4ed6\u4e24\u79cd\u5e38\u89c1\u7684\u9009\u62e9\u57fa\u51c6\u7684\u7b56\u7565\uff0c\u5b83\u4eec\u5206\u522b\u662f\uff1a \u968f\u673a\u9009\u62e9\u57fa\u51c6\uff08Random Pivot\uff09\uff1a\u8fd9\u79cd\u7b56\u7565\u662f\u5728\u5f85\u6392\u5e8f\u6570\u7ec4\u4e2d\u968f\u673a\u9009\u62e9\u4e00\u4e2a\u5143\u7d20\u4f5c\u4e3a\u57fa\u51c6\u3002\u968f\u673a\u9009\u62e9\u57fa\u51c6\u7684\u597d\u5904\u662f\u53ef\u4ee5\u964d\u4f4e\u51fa\u73b0\u6700\u574f\u60c5\u51b5\u7684\u6982\u7387\uff0c\u56e0\u4e3a\u5728\u5927\u591a\u6570\u60c5\u51b5\u4e0b\uff0c\u968f\u673a\u9009\u62e9\u7684\u57fa\u51c6\u4f1a\u6bd4\u56fa\u5b9a\u4f4d\u7f6e\u7684\u57fa\u51c6\u66f4\u5e73\u5747\u5730\u5212\u5206\u6570\u636e\u3002\u8fd9\u53ef\u4ee5\u63d0\u9ad8\u7b97\u6cd5\u7684\u6027\u80fd\u3002 \u4e09\u6570\u53d6\u4e2d\u6cd5\uff08Median-of-Three Pivot\uff09\uff1a\u8fd9\u79cd\u7b56\u7565\u662f\u5728\u5f85\u6392\u5e8f\u6570\u7ec4\u4e2d\u9009\u62e9\u4e09\u4e2a\u5143\u7d20\uff08\u901a\u5e38\u662f\u7b2c\u4e00\u4e2a\u3001\u4e2d\u95f4\u4e00\u4e2a\u548c\u6700\u540e\u4e00\u4e2a\u5143\u7d20\uff09\uff0c\u7136\u540e\u4ece\u8fd9\u4e09\u4e2a\u5143\u7d20\u4e2d\u9009\u62e9\u4e2d\u95f4\u503c\u4f5c\u4e3a\u57fa\u51c6\u3002\u8fd9\u4e2a\u7b56\u7565\u7684\u76ee\u7684\u662f\u5728\u5c3d\u91cf\u907f\u514d\u6700\u574f\u60c5\u51b5\u7684\u540c\u65f6\uff0c\u4fdd\u6301\u57fa\u51c6\u7684\u76f8\u5bf9\u4e2d\u95f4\u4f4d\u7f6e\u3002\u8fd9\u53ef\u4ee5\u63d0\u9ad8\u7b97\u6cd5\u7684\u5e73\u5747\u6027\u80fd\u3002 \u8fd9\u4e09\u79cd\u9009\u62e9\u57fa\u51c6\u7684\u7b56\u7565\u5404\u6709\u4f18\u52a3\uff0c\u4f46\u5b83\u4eec\u7684\u5171\u540c\u76ee\u6807\u662f\u964d\u4f4e\u6700\u574f\u60c5\u51b5\u7684\u6982\u7387\uff0c\u4ece\u800c\u63d0\u9ad8\u5feb\u901f\u6392\u5e8f\u7684\u6027\u80fd\u3002\u5728\u5b9e\u9645\u5e94\u7528\u4e2d\uff0c\u9009\u62e9\u54ea\u79cd\u7b56\u7565\u53d6\u51b3\u4e8e\u5177\u4f53\u7684\u60c5\u51b5\u548c\u5b9e\u73b0\u3002 \u5f53\u5feb\u901f\u6392\u5e8f\u91cc\u7684\u5b50\u5217\u8868\u7684\u957f\u5ea6\u5c0f\u4e8e\u67d0\u4e2a\u6570\u5b57\uff08\u598230\uff09\u65f6\uff0c\u6267\u884c\u63d2\u5165\u6392\u5e8f\u6765\u5904\u7406\u8fd9\u4e2a\u5b50\u5217\u8868\u3002\u8bf7\u8bf4\u660e\u4e3a\u4ec0\u4e48\u8fd9\u662f\u4e00\u4e2a\u597d\u65b9\u6cd5\u3002 \u89e3\u7b54\uff1a\u5728\u5feb\u901f\u6392\u5e8f\u4e2d\uff0c\u5f53\u5b50\u5217\u8868\u7684\u957f\u5ea6\u53d8\u5f97\u5f88\u5c0f\u65f6\uff08\u901a\u5e38\u5c0f\u4e8e\u67d0\u4e2a\u9884\u5b9a\u7684\u9608\u503c\uff0c\u598230\u6216\u5176\u4ed6\u7ecf\u9a8c\u503c\uff09\uff0c\u6267\u884c\u63d2\u5165\u6392\u5e8f\u6765\u5904\u7406\u8fd9\u4e2a\u5b50\u5217\u8868\u662f\u4e00\u4e2a\u597d\u65b9\u6cd5\uff0c\u4e3b\u8981\u57fa\u4e8e\u4ee5\u4e0b\u8003\u8651\uff1a \u63d2\u5165\u6392\u5e8f\u5bf9\u5c0f\u89c4\u6a21\u6570\u636e\u8868\u73b0\u826f\u597d\uff1a\u63d2\u5165\u6392\u5e8f\u662f\u4e00\u79cd\u7b80\u5355\u4f46\u9ad8\u6548\u7684\u6392\u5e8f\u7b97\u6cd5\uff0c\u7279\u522b\u9002\u7528\u4e8e\u5c0f\u89c4\u6a21\u6570\u636e\u96c6\u3002\u5b83\u7684\u65f6\u95f4\u590d\u6742\u5ea6\u4e3a O(n^2) \uff0c\u4f46\u5728\u5b9e\u9645\u5e94\u7528\u4e2d\uff0c\u5bf9\u4e8e\u5c0f\u89c4\u6a21\u7684\u6570\u636e\uff0c\u5b83\u7684\u6027\u80fd\u901a\u5e38\u5f88\u597d\u3002 \u51cf\u5c11\u9012\u5f52\u6df1\u5ea6\uff1a\u5728\u5feb\u901f\u6392\u5e8f\u4e2d\uff0c\u6bcf\u6b21\u9012\u5f52\u8c03\u7528\u90fd\u4f1a\u589e\u52a0\u9012\u5f52\u6df1\u5ea6\uff0c\u800c\u9012\u5f52\u6df1\u5ea6\u8fc7\u5927\u53ef\u80fd\u4f1a\u5bfc\u81f4\u6808\u6ea2\u51fa\u6216\u6027\u80fd\u4e0b\u964d\u3002\u5f53\u5b50\u5217\u8868\u957f\u5ea6\u5c0f\u4e8e\u67d0\u4e2a\u9608\u503c\u65f6\uff0c\u4f7f\u7528\u63d2\u5165\u6392\u5e8f\u53ef\u4ee5\u907f\u514d\u4e0d\u5fc5\u8981\u7684\u9012\u5f52\u6df1\u5ea6\uff0c\u4ece\u800c\u51cf\u5c11\u9012\u5f52\u8c03\u7528\u7684\u6b21\u6570\u3002 \u9002\u7528\u4e8e\u90e8\u5206\u6709\u5e8f\u7684\u5b50\u5217\u8868\uff1a\u5f53\u5b50\u5217\u8868\u5df2\u7ecf\u90e8\u5206\u6709\u5e8f\u65f6\uff0c\u63d2\u5165\u6392\u5e8f\u7684\u6027\u80fd\u901a\u5e38\u6bd4\u5feb\u901f\u6392\u5e8f\u66f4\u597d\u3002\u56e0\u6b64\uff0c\u5bf9\u4e8e\u53ef\u80fd\u5305\u542b\u5df2\u6392\u5e8f\u90e8\u5206\u7684\u5c0f\u5b50\u5217\u8868\uff0c\u4f7f\u7528\u63d2\u5165\u6392\u5e8f\u53ef\u4ee5\u63d0\u9ad8\u7b97\u6cd5\u7684\u6548\u7387\u3002 \u51cf\u5c11\u9012\u5f52\u5f00\u9500\uff1a\u9012\u5f52\u5f00\u9500\u662f\u5feb\u901f\u6392\u5e8f\u7684\u4e00\u4e2a\u4e0d\u53ef\u5ffd\u89c6\u7684\u56e0\u7d20\uff0c\u7279\u522b\u662f\u5728\u5904\u7406\u5c0f\u89c4\u6a21\u5b50\u5217\u8868\u65f6\u3002\u901a\u8fc7\u4f7f\u7528\u63d2\u5165\u6392\u5e8f\u6765\u5904\u7406\u8fd9\u4e9b\u5c0f\u89c4\u6a21\u5b50\u5217\u8868\uff0c\u53ef\u4ee5\u51cf\u5c11\u9012\u5f52\u5f00\u9500\uff0c\u63d0\u9ad8\u7b97\u6cd5\u7684\u6574\u4f53\u6027\u80fd\u3002 \u5c06\u63d2\u5165\u6392\u5e8f\u4e0e\u5feb\u901f\u6392\u5e8f\u7ed3\u5408\u4f7f\u7528\u662f\u4e00\u79cd\u5e38\u89c1\u7684\u4f18\u5316\u7b56\u7565\uff0c\u5b83\u53ef\u4ee5\u5728\u5904\u7406\u5c0f\u89c4\u6a21\u5b50\u5217\u8868\u65f6\u63d0\u9ad8\u7b97\u6cd5\u7684\u6548\u7387\uff0c\u540c\u65f6\u4fdd\u6301\u5feb\u901f\u6392\u5e8f\u7684\u6574\u4f53\u6027\u80fd\u3002\u8fd9\u79cd\u65b9\u6cd5\u88ab\u79f0\u4e3a\u201c\u5feb\u901f\u6392\u5e8f\u7684\u6539\u8fdb\u201d\u6216\u201c\u5feb\u901f\u6392\u5e8f\u7684\u6df7\u5408\u6392\u5e8f\u201d\u7b56\u7565\uff0c\u7528\u4e8e\u5728\u5b9e\u9645\u5e94\u7528\u4e2d\u63d0\u9ad8\u7b97\u6cd5\u7684\u6548\u7387\u3002 \u4e3a\u4ec0\u4e48\u5f52\u5e76\u6392\u5e8f\u5728\u6700\u574f\u60c5\u51b5\u4e0b\u4e5f\u662f\u4e00\u4e2a O(n log n) \u7b97\u6cd5\uff1f \u89e3\u7b54\uff1a\u5f52\u5e76\u6392\u5e8f\u5728\u6700\u574f\u60c5\u51b5\u4e0b\u4ecd\u7136\u5177\u6709 O(n log n) \u7684\u65f6\u95f4\u590d\u6742\u5ea6\uff0c\u8fd9\u662f\u56e0\u4e3a\u5f52\u5e76\u6392\u5e8f\u7684\u7b97\u6cd5\u8bbe\u8ba1\u4f7f\u5176\u80fd\u591f\u7a33\u5b9a\u5730\u4fdd\u6301\u8fd9\u79cd\u6027\u80fd\uff0c\u4e0d\u53d7\u8f93\u5165\u6570\u636e\u5206\u5e03\u7684\u5f71\u54cd\u3002 \u4ee5\u4e0b\u662f\u5f52\u5e76\u6392\u5e8f\u5728\u6700\u574f\u60c5\u51b5\u4e0b\u4ecd\u7136\u5177\u6709 O(n log n) \u65f6\u95f4\u590d\u6742\u5ea6\u7684\u539f\u56e0\uff1a \u5206\u800c\u6cbb\u4e4b\u7b56\u7565\uff1a\u5f52\u5e76\u6392\u5e8f\u91c7\u7528\u4e86\u5206\u800c\u6cbb\u4e4b\u7684\u7b56\u7565\uff0c\u5c06\u95ee\u9898\u5206\u89e3\u4e3a\u8f83\u5c0f\u7684\u5b50\u95ee\u9898\uff0c\u7136\u540e\u5408\u5e76\u8fd9\u4e9b\u5b50\u95ee\u9898\u7684\u89e3\u3002\u8fd9\u4e2a\u7b56\u7565\u786e\u4fdd\u4e86\u7b97\u6cd5\u7684\u9012\u5f52\u6df1\u5ea6\u5728 log n \u7ea7\u522b\uff0c\u56e0\u4e3a\u6bcf\u6b21\u9012\u5f52\u90fd\u5c06\u6570\u636e\u5212\u5206\u6210\u4e24\u534a\uff0c\u76f4\u5230\u6700\u5c0f\u5b50\u95ee\u9898\u7684\u5927\u5c0f\u4e3a1\u3002 \u5408\u5e76\u64cd\u4f5c\u7684\u7ebf\u6027\u65f6\u95f4\uff1a\u5f52\u5e76\u6392\u5e8f\u7684\u5173\u952e\u64cd\u4f5c\u662f\u5408\u5e76\u5df2\u6392\u5e8f\u7684\u5b50\u6570\u7ec4\u3002\u5408\u5e76\u64cd\u4f5c\u7684\u65f6\u95f4\u590d\u6742\u5ea6\u662f\u7ebf\u6027\u7684\uff0c\u4e0e\u8f93\u5165\u6570\u636e\u7684\u89c4\u6a21 n \u6210\u6b63\u6bd4\u3002\u56e0\u6b64\uff0c\u5373\u4f7f\u5728\u5408\u5e76\u9636\u6bb5\uff0c\u7b97\u6cd5\u7684\u603b\u65f6\u95f4\u590d\u6742\u5ea6\u4ecd\u7136\u53d7\u9650\u4e8e O(n log n) \u3002 \u7a33\u5b9a\u6027\uff1a\u5f52\u5e76\u6392\u5e8f\u662f\u4e00\u79cd\u7a33\u5b9a\u6392\u5e8f\u7b97\u6cd5\uff0c\u610f\u5473\u7740\u5b83\u5728\u6392\u5e8f\u76f8\u7b49\u5143\u7d20\u65f6\u4f1a\u4fdd\u6301\u5b83\u4eec\u7684\u76f8\u5bf9\u987a\u5e8f\u3002\u8fd9\u4e00\u6027\u8d28\u4f7f\u5f97\u7b97\u6cd5\u5728\u5904\u7406\u76f8\u7b49\u5143\u7d20\u6216\u8005\u5177\u6709\u7279\u5b9a\u6570\u636e\u5206\u5e03\u7684\u60c5\u51b5\u4e0b\u4ecd\u7136\u4fdd\u6301 O(n log n) \u7684\u6027\u80fd\uff0c\u800c\u4e0d\u4f1a\u51fa\u73b0\u6700\u574f\u60c5\u51b5\u3002 \u65e0\u8bba\u8f93\u5165\u6570\u636e\u5982\u4f55\u5206\u5e03\uff0c\u5f52\u5e76\u6392\u5e8f\u7684\u5206\u5272\u548c\u5408\u5e76\u64cd\u4f5c\u90fd\u662f\u786e\u5b9a\u6027\u7684\uff1a\u5f52\u5e76\u6392\u5e8f\u7684\u6bcf\u4e00\u6b65\u90fd\u662f\u786e\u5b9a\u6027\u7684\uff0c\u4e0d\u53d7\u8f93\u5165\u6570\u636e\u5206\u5e03\u7684\u5f71\u54cd\u3002\u4e0d\u50cf\u5feb\u901f\u6392\u5e8f\u5728\u6700\u574f\u60c5\u51b5\u4e0b\u53ef\u80fd\u51fa\u73b0\u5206\u5272\u6781\u4e0d\u5e73\u8861\u7684\u60c5\u51b5\uff0c\u5bfc\u81f4\u6027\u80fd\u4e0b\u964d\u3002 \u56e0\u6b64\uff0c\u5f52\u5e76\u6392\u5e8f\u5728\u6700\u574f\u60c5\u51b5\u4e0b\u4ecd\u7136\u80fd\u591f\u4fdd\u6301 O(n log n) \u7684\u65f6\u95f4\u590d\u6742\u5ea6\uff0c\u4f7f\u5176\u6210\u4e3a\u4e00\u79cd\u53ef\u9760\u7684\u6392\u5e8f\u7b97\u6cd5\uff0c\u7279\u522b\u9002\u7528\u4e8e\u5bf9\u7a33\u5b9a\u6027\u548c\u6027\u80fd\u6709\u8981\u6c42\u7684\u60c5\u51b5\u3002","title":"3.5.3.\u7ec3\u4e60\u9898"},{"location":"python/DataStructure/03_TimeComplexity/#36","text":"","title":"3.6.\u6307\u6570\u590d\u6742\u5ea6\u7684\u7b97\u6cd5"},{"location":"python/DataStructure/03_TimeComplexity/#_1","text":"\u4e0b\u9762\u662f\u6590\u6ce2\u90a3\u5951\u9012\u5f52\u7b97\u6cd5\u7684\u4f8b\u5b50\u3002 def fib ( n , depth = 0 ): \"\"\"\u6590\u6ce2\u90a3\u5951\u9012\u5f52\u6570\u5217\"\"\" if n <= 1 : return 1 else : print ( f 'Depth: { depth } ,fib( { n } ) calls fib( { n - 1 } ) and fib( { n - 2 } )' ) return fib ( n - 1 , depth + 1 ) + fib ( n - 2 , depth + 1 ) def main (): fib ( 6 ) if __name__ == \"__main__\" : main () # \u8fd0\u884c\u7ed3\u679c\uff1a # Depth:0,fib(6) calls fib(5) and fib(4) # Depth:1,fib(5) calls fib(4) and fib(3) # Depth:2,fib(4) calls fib(3) and fib(2) # Depth:3,fib(3) calls fib(2) and fib(1) # Depth:4,fib(2) calls fib(1) and fib(0) # Depth:3,fib(2) calls fib(1) and fib(0) # Depth:2,fib(3) calls fib(2) and fib(1) # Depth:3,fib(2) calls fib(1) and fib(0) # Depth:1,fib(4) calls fib(3) and fib(2) # Depth:2,fib(3) calls fib(2) and fib(1) # Depth:3,fib(2) calls fib(1) and fib(0) # Depth:2,fib(2) calls fib(1) and fib(0) \u4e0a\u4f8b\u53ef\u4ee5\u770b\u51fa\uff0c\u6590\u6ce2\u90a3\u5951\u9012\u5f52\u7b97\u6cd5\u7684\u8c03\u7528\u6b21\u6570\u6bd4\u95ee\u9898\u89c4\u6a21\u7684\u5e73\u65b9\u6570\u589e\u957f\u7684\u8fd8\u8981\u5feb\u5f88\u591a\u3002\u4f8b\u5982\uff0c fib(4) \u53ea\u9700\u89814\u6b21\u9012\u5f52\u8c03\u7528\uff0c\u770b\u8d77\u6765\u5b83\u597d\u50cf\u662f\u7ebf\u6027\u589e\u957f\u7684\uff0c\u4f46\u5728\u603b\u5171\u768414\u6b21\u9012\u5f52\u8c03\u7528\u91cc\uff0c fib(6) \u9700\u8981\u8c03\u75282\u6b21 fib(4) \u3002\u968f\u7740\u95ee\u9898\u89c4\u6a21\u7684\u6269\u5927\uff0c\u5de5\u4f5c\u91cf\u4f1a\u663e\u8457\u589e\u52a0\uff0c\u8fd9\u662f\u56e0\u4e3a\u5728\u8c03\u7528\u6811\uff08call tree\uff09\u91cc\u53ef\u80fd\u6709\u5f88\u591a\u91cd\u590d\u7684\u76f8\u540c\u5b50\u6811\u3002 \u5982\u679c\u8fd9\u68f5\u8c03\u7528\u6811\u662f\u5b8c\u5168\u5e73\u8861\u7684\uff0c\u5e76\u4e14\u5b8c\u5168\u586b\u5145\u4e86\u6700\u4e0b\u9762\u7684\u4e24\u5c42\u8c03\u7528\uff0c\u90a3\u4e48\u5f53\u53c2\u6570\u4e3a6\u65f6\uff0c\u4f1a\u67092 + 4 + 8 + 16 = 30\u6b21\u9012\u5f52\u8c03\u7528\u3002\u6bcf\u4e00\u5c42\u91cc\u7684\u6ee1\u8c03\u7528\u6570\u91cf\u90fd\u662f\u5b83\u4e0a\u4e00\u5c42\u76842\u500d\u3002\u56e0\u6b64\uff0c\u5728\u5b8c\u5168\u5e73\u8861\u7684\u8c03\u7528\u6811\u91cc\uff0c\u9012\u5f52\u8c03\u7528\u7684\u603b\u6570\u91cf\u901a\u5e38\u662f 2^(n+1)-2 \uff0c\u5176\u4e2d n \u662f\u8c03\u7528\u6811\u9876\u90e8\uff08\u6839\uff09\u7684\u53c2\u6570\u3002\u8fd9\u662f\u4e00\u4e2a\u6307\u6570\u7ea7\u7684\u589e\u957f\uff0c\u4e5f\u5c31\u662f O(k^n) \u7b97\u6cd5\u3002 \u5c3d\u7ba1\u5728\u9012\u5f52\u6590\u6ce2\u90a3\u5951\u8c03\u7528\u6811\u7684\u5e95\u90e8\u4e24\u5c42\u5e76\u6ca1\u6709\u88ab\u5b8c\u5168\u586b\u5145\u6ee1\uff0c\u4f46\u5b83\u7684\u8c03\u7528\u6811\u5f62\u72b6\u548c\u5b8c\u5168\u5e73\u8861\u7684\u6811\u5df2\u7ecf\u8db3\u591f\u76f8\u8fd1\u4e86\uff0c\u56e0\u6b64\uff0c\u53ef\u4ee5\u628a\u9012\u5f52\u6590\u6ce2\u90a3\u5951\u5f52\u4e3a\u6307\u6570\u7b97\u6cd5\u3002\u7ecf\u8fc7\u8ba1\u7b97\uff0c\u9012\u5f52\u6590\u6ce2\u90a3\u5951\u7684\u5e38\u6570 k \u5927\u7ea6\u662f1.63\u3002 \u6307\u6570\u7b97\u6cd5\u901a\u5e38\u53ea\u9002\u5408\u7528\u4e8e\u975e\u5e38\u5c0f\u7684\u95ee\u9898\u89c4\u6a21\u3002","title":"\u6590\u6ce2\u90a3\u5951\u9012\u5f52\u7b97\u6cd5"},{"location":"python/DataStructure/03_TimeComplexity/#_2","text":"\u4e0b\u9762\u7684\u4ee3\u7801\u7528\u7ebf\u6027\u7b97\u6cd5\u6539\u5199\u4e86\u4e0a\u9762\u7684\u9012\u5f52\u7b97\u6cd5\u3002\u5b83\u7684\u65f6\u95f4\u590d\u6742\u5ea6\u662fO(n)\u3002 def fibonacci_linear ( n ): if n <= 1 : return 1 prev , current = 0 , 1 for _ in range ( 2 , n + 1 ): next_value = prev + current prev , current = current , next_value return current def main (): n = 6 result = fibonacci_linear ( n ) print ( f \"Fibonacci( { n } ) = { result } \" ) if __name__ == \"__main__\" : main () # \u8fd0\u884c\u7ed3\u679c\uff1a # Fibonacci(6) = 8","title":"\u5c06\u6590\u6ce2\u90a3\u5951\u8f6c\u6362\u4e3a\u7ebf\u6027\u7b97\u6cd5"},{"location":"python/DataStructure/03_TimeComplexity/#37","text":"\u76ee\u6807\uff1a\u7f16\u5199\u4e00\u4e2a\u53ef\u4ee5\u7528\u6765\u5206\u6790\u4e0d\u540c\u6392\u5e8f\u7b97\u6cd5\u7684\u7a0b\u5e8f\u3002 \u9700\u6c42\uff1a \u5206\u6790\u5668\u53ef\u4ee5\u8fd0\u884c\u6392\u5e8f\u7b97\u6cd5\u4ee5\u5bf9\u6570\u5b57\u5217\u8868\u8fdb\u884c\u6392\u5e8f\uff1b \u5206\u6790\u5668\u53ef\u4ee5\u8ffd\u8e2a\u7b97\u6cd5\u7684\u8fd0\u884c\u65f6\u3001\u6bd4\u8f83\u6b21\u6570\u4ee5\u53ca\u6267\u884c\u4ea4\u6362\u7684\u6b21\u6570\uff1b \u5f53\u7b97\u6cd5\u4ea4\u6362\u4e24\u4e2a\u503c\u7684\u65f6\u5019\uff0c\u5206\u6790\u5668\u53ef\u4ee5\u6253\u5370\u51fa\u5217\u8868\u7684\u53d8\u5316\u8f68\u8ff9\uff1b \u5141\u8bb8\u7ed9\u5206\u6790\u5668\u63d0\u4f9b\u81ea\u5b9a\u4e49\u7684\u6570\u5b57\u5217\u8868\uff0c\u6216\u8005\u751f\u6210\u4e00\u4e2a\u5927\u5c0f\u7ed9\u5b9a\u7684\u968f\u673a\u6570\u5b57\u5217\u8868\uff1b\u5141\u8bb8\u5217\u8868\u53ea\u5305\u542b\u4e00\u4e2a\u6570\u5b57\uff0c\u6216\u8005\u5305\u542b\u91cd\u590d\u6570\u503c\uff1b \u5728\u8fd0\u884c\u7b97\u6cd5\u4e4b\u524d\uff0c\u5141\u8bb8\u7528\u6237\u9009\u62e9\u4e0a\u8ff0\u8fd9\u4e9b\u529f\u80fd\uff1b \u5206\u6790\u5668\u7684\u9ed8\u8ba4\u884c\u4e3a\u662f\u5728\u4e00\u4e2a\u5305\u542b10\u4e2a\u4e0d\u91cd\u590d\u6570\u5b57\u7684\u968f\u673a\u5217\u8868\u4e0a\u8fd0\u884c\u7b97\u6cd5\uff0c\u5e76\u8bb0\u5f55\u7b97\u6cd5\u7684\u8fd0\u884c\u65f6\u3001\u6bd4\u8f83\u6b21\u6570\u4ee5\u53ca\u4ea4\u6362\u6b21\u6570\uff1b \u5b9e\u73b0\uff1a \u5206\u6790\u5668\u662f Profiler \u7c7b\u7684\u4e00\u4e2a\u5b9e\u4f8b\u3002\u6211\u4eec\u53ef\u4ee5\u901a\u8fc7\u8fd0\u884c\u5206\u6790\u5668\u91cc\u7684 test \u65b9\u6cd5\u6765\u5206\u6790\u6392\u5e8f\u51fd\u6570\uff0c\u8fd9\u4e2a\u6392\u5e8f\u51fd\u6570\u4f1a\u4f5c\u4e3a\u65b9\u6cd5\u7684\u7b2c\u4e00\u4e2a\u53c2\u6570\uff0c\u4e0a\u9762\u9700\u6c42\u4e2d\u63d0\u5230\u7684\u90a3\u4e9b\u9009\u9879\u4e5f\u4f1a\u4f5c\u4e3a\u53c2\u6570\u540c\u65f6\u4f20\u9012\u7ed9\u8fd9\u4e2a\u65b9\u6cd5\u3002 \u4e24\u4e2a\u6a21\u5757\uff1a profiler \uff1a\u8fd9\u4e2a\u6a21\u5757\u4f1a\u5b9a\u4e49 Profiler \u7c7b\u3002 algorithms \uff1a\u8fd9\u4e2a\u6a21\u5757\u5b9a\u4e49\u9488\u5bf9\u5206\u6790\u5668\u4fee\u6539\u8fc7\u7684\u6392\u5e8f\u51fd\u6570\u3002 import time import random class Profiler ( object ): \"\"\" \u5b9a\u4e49\u4e00\u4e2aProfiler\u7c7b, \u7528\u6765\u5206\u6790\u6392\u5e8f\u7b97\u6cd5\u3002 Profiler\u5bf9\u8c61\u8ddf\u8e2a\u4e00\u4e2a\u5217\u8868\u7684\u6bd4\u8f83\u6b21\u6570\u3001\u4ea4\u6362\u6b21\u6570\u3001\u548c\u8fd0\u884c\u65f6\u95f4\u3002 Profiler\u5bf9\u8c61\u4e5f\u80fd\u8f93\u51fa\u4e0a\u8ff0\u8ffd\u8e2a\u4fe1\u606f, \u5e76\u521b\u5efa\u4e00\u4e2a\u542b\u6709\u91cd\u590d\u6216\u4e0d\u91cd\u590d\u6570\u5b57\u7684\u5217\u8868\u3002 \u793a\u4f8b\uff1a from profiler import Profiler from algorithms import selectionSort p = Profiler() p.test(selectionSort, size = 15, comp = True, exch = True, trace = True) \"\"\" def test ( self , function , lyst = None , size = 10 , unique = True , comp = True , exch = True , trace = False ): \"\"\" function: \u914d\u7f6e\u7684\u7b97\u6cd5 target: \u914d\u7f6e\u7684\u641c\u7d22\u76ee\u6807 lyst: \u5141\u8bb8\u8c03\u7528\u8005\u4f7f\u7528\u7684\u5217\u8868 size: \u5217\u8868\u7684\u5927\u5c0f, \u9ed8\u8ba4\u503c\u662f10 unique: \u5982\u679c\u662fTrue, \u5219\u5217\u8868\u5305\u542b\u4e0d\u91cd\u590d\u7684\u6574\u6570 comp: \u5982\u679c\u662fTrue, \u5219\u7edf\u8ba1\u6bd4\u8f83\u6b21\u6570 exch: \u5982\u679c\u662fTrue, \u5219\u7edf\u8ba1\u4ea4\u6362\u6b21\u6570 trace: \u5982\u679c\u662fTrue, \u5219\u5728\u6bcf\u6b21\u4ea4\u6362\u540e\u90fd\u8f93\u51fa\u5217\u8868\u5185\u5bb9 \u6b64\u51fd\u6570\u4f9d\u636e\u7ed9\u5b9a\u7684\u4e0a\u8ff0\u5c5e\u6027, \u6253\u5370\u8f93\u51fa\u76f8\u5e94\u7684\u7ed3\u679c \"\"\" self . comp = comp self . exch = exch self . trace = trace if lyst != None : self . lyst = lyst elif unique : self . lyst = list ( range ( 1 , size + 1 )) random . shuffle ( self . lyst ) else : self . lyst = [] for count in range ( size ): self . lyst . append ( random . randint ( 1 , size )) self . exchCount = 0 self . cmpCount = 0 self . startClock () function ( self . lyst , self ) self . stopClock () print ( self ) def exchange ( self ): \"\"\"\u7edf\u8ba1\u4ea4\u6362\u6b21\u6570\"\"\" if self . exch : self . exchCount += 1 if self . trace : print ( self . lyst ) def comparison ( self ): \"\"\"\u7edf\u8ba1\u4ea4\u6362\u6b21\u6570\"\"\" if self . comp : self . cmpCount += 1 def startClock ( self ): \"\"\"\u8bb0\u5f55\u5f00\u59cb\u65f6\u95f4\"\"\" self . start = time . time () def stopClock ( self ): \"\"\"\u505c\u6b62\u8ba1\u65f6\u5e76\u4ee5\u79d2\u4e3a\u5355\u4f4d\u8ba1\u7b97\u6d88\u8017\u65f6\u95f4\"\"\" self . elapsedTime = round ( time . time () - self . start , 3 ) def __str__ ( self ): \"\"\"\u4ee5\u5b57\u7b26\u4e32\u65b9\u5f0f\u8fd4\u56de\u7ed3\u679c\"\"\" result = \"Problem size: \" result += str ( len ( self . lyst )) + \" \\n \" result += \"Elapsed time: \" result += str ( self . elapsedTime ) + \" \\n \" if self . comp : result += \"Comparisons: \" result += str ( self . cmpCount ) + \" \\n \" if self . exch : result += \"Exchanges: \" result += str ( self . exchCount ) + \" \\n \" return result def selectionSort ( lyst , profiler ): i = 0 while i < len ( lyst ) - 1 : minIndex = i j = i + 1 while j < len ( lyst ): profiler . comparison () # Count if lyst [ j ] < lyst [ minIndex ]: minIndex = j j += 1 if minIndex != i : swap ( lyst , minIndex , i , profiler ) i += 1 def swap ( lyst , i , j , profiler ): \"\"\"\u4ea4\u6362\u5904\u4e8e\u4f4d\u7f6ei\u548cj\u7684\u5143\u7d20\"\"\" profiler . exchange () # Count temp = lyst [ i ] lyst [ i ] = lyst [ j ] lyst [ j ] = temp def main (): p = Profiler () # \u9ed8\u8ba4\u884c\u4e3a print ( \"The result of p.test(selectionSort)\" ) p . test ( selectionSort ) print ( \"The result of p.test(selectionSort, size=5, trace=True)\" ) p . test ( selectionSort , size = 5 , trace = True ) print ( \"The result of p.test(selectionSort, size=100)\" ) p . test ( selectionSort , size = 100 ) print ( \"The result of p.test(selectionSort, size=1000)\" ) p . test ( selectionSort , size = 1000 ) print ( \"The result of p.test(selectionSort, size=10000, exch=False, comp=False)\" ) p . test ( selectionSort , size = 10000 , exch = False , comp = False ) if __name__ == \"__main__\" : main () # \u8fd0\u884c\u7ed3\u679c\uff1a # The result of p.test(selectionSort) # Problem size: 20 # Elapsed time: 0.0 # Comparisons: 190 # Exchanges: 12 # The result of p.test(selectionSort, size=5, trace=True) # [5, 1, 4, 3, 2, 1, 1, 2, 4, 4] # [1, 5, 4, 3, 2, 1, 1, 2, 4, 4] # [1, 1, 4, 3, 2, 5, 1, 2, 4, 4] # [1, 1, 1, 3, 2, 5, 4, 2, 4, 4] # [1, 1, 1, 2, 3, 5, 4, 2, 4, 4] # [1, 1, 1, 2, 2, 5, 4, 3, 4, 4] # [1, 1, 1, 2, 2, 3, 4, 5, 4, 4] # [1, 1, 1, 2, 2, 3, 4, 4, 5, 4] # Problem size: 10 # Elapsed time: 0.0 # Comparisons: 45 # Exchanges: 8 # The result of p.test(selectionSort, size=100) # Problem size: 200 # Elapsed time: 0.003 # Comparisons: 19900 # Exchanges: 195 # The result of p.test(selectionSort, size=1000) # Problem size: 2000 # Elapsed time: 0.36 # Comparisons: 1999000 # Exchanges: 1992 # The result of p.test(selectionSort, size=10000, exch=False, comp=False) # Problem size: 20000 # Elapsed time: 26.535","title":"3.7.\u6848\u4f8b\u7814\u7a76:\u7b97\u6cd5\u5206\u6790\u5668"},{"location":"python/DataStructure/03_TimeComplexity/#38","text":"\u6839\u636e\u6240\u9700\u8981\u7684\u65f6\u95f4\u548c\u5185\u5b58\u8d44\u6e90\uff0c\u6211\u4eec\u53ef\u4ee5\u5bf9\u89e3\u51b3\u540c\u4e00\u4e2a\u95ee\u9898\u7684\u4e0d\u540c\u7b97\u6cd5\u8fdb\u884c\u6392\u540d\u3002\u4e0e\u9700\u8981\u66f4\u591a\u8d44\u6e90\u7684\u7b97\u6cd5\u76f8\u6bd4\uff0c\u6211\u4eec\u901a\u5e38\u8ba4\u4e3a\u8017\u8d39\u66f4\u5c11\u8fd0\u884c\u65f6\u548c\u5360\u7528\u66f4\u5c11\u5185\u5b58\u7684\u7b97\u6cd5\u66f4\u597d\u3002\u4f46\u662f\uff0c\u8fd9\u4e24\u79cd\u8d44\u6e90\u4e5f\u901a\u5e38\u9700\u8981\u8fdb\u884c\u6743\u8861\u53d6\u820d\uff1a\u6709\u65f6\u4ee5\u66f4\u591a\u5185\u5b58\u4e3a\u4ee3\u4ef7\u6765\u6539\u5584\u8fd0\u884c\u65f6\uff1b\u6709\u65f6\u4ee5\u8f83\u6162\u7684\u8fd0\u884c\u65f6\u4f5c\u4e3a\u4ee3\u4ef7\u6765\u63d0\u9ad8\u5185\u5b58\u7684\u4f7f\u7528\u7387\u3002 \u53ef\u4ee5\u6839\u636e\u8ba1\u7b97\u673a\u7684\u65f6\u949f\u6309\u7167\u8fc7\u5f80\u7ecf\u9a8c\u6d4b\u7b97\u7b97\u6cd5\u7684\u8fd0\u884c\u65f6\u3002\u4f46\u662f\uff0c\u8fd9\u4e2a\u65f6\u95f4\u4f1a\u968f\u7740\u786c\u4ef6\u548c\u6240\u7528\u7f16\u7a0b\u8bed\u8a00\u7684\u4e0d\u540c\u800c\u53d8\u5316\u3002 \u7edf\u8ba1\u6307\u4ee4\u7684\u6570\u91cf\u63d0\u4f9b\u4e86\u53e6\u4e00\u79cd\u5bf9\u7b97\u6cd5\u6240\u9700\u5de5\u4f5c\u91cf\u8fdb\u884c\u7ecf\u9a8c\u6027\u5ea6\u91cf\u7684\u65b9\u5f0f\u3002\u6307\u4ee4\u7684\u8ba1\u6570\u53ef\u4ee5\u663e\u793a\u51fa\u7b97\u6cd5\u5de5\u4f5c\u91cf\u7684\u589e\u957f\u7387\u7684\u53d8\u5316\uff0c\u800c\u4e14\u8fd9\u4e2a\u6570\u636e\u548c\u786c\u4ef6\u4ee5\u53ca\u8f6f\u4ef6\u5e73\u53f0\u90fd\u6ca1\u6709\u5173\u7cfb\u3002 \u7b97\u6cd5\u5de5\u4f5c\u91cf\u7684\u589e\u957f\u7387\u53ef\u4ee5\u7528\u57fa\u4e8e\u95ee\u9898\u89c4\u6a21\u7684\u51fd\u6570\u6765\u8868\u793a\u3002\u590d\u6742\u5ea6\u5206\u6790\u67e5\u770b\u7b97\u6cd5\u91cc\u7684\u4ee3\u7801\u4ee5\u5f97\u5230\u8fd9\u4e9b\u6570\u5b66\u8868\u8fbe\u5f0f\uff0c\u4ece\u800c\u8ba9\u7a0b\u5e8f\u5458\u9884\u6d4b\u5728\u4efb\u4f55\u8ba1\u7b97\u673a\u4e0a\u6267\u884c\u8fd9\u4e2a\u7b97\u6cd5\u7684\u6548\u679c\u3002 \u5927O\u8868\u793a\u6cd5\u662f\u7528\u6765\u8868\u793a\u7b97\u6cd5\u8fd0\u884c\u65f6\u884c\u4e3a\u7684\u5e38\u7528\u65b9\u6cd5\u3002\u5b83\u7528 O(f(n)) \u7684\u5f62\u5f0f\u6765\u8868\u793a\u89e3\u51b3\u8fd9\u4e2a\u95ee\u9898\u6240\u9700\u8981\u7684\u5de5\u4f5c\u91cf\uff0c\u5176\u4e2d n \u662f\u7b97\u6cd5\u95ee\u9898\u7684\u89c4\u6a21\u3001 f(n) \u662f\u6570\u5b66\u51fd\u6570\u3002 \u8fd0\u884c\u65f6\u884c\u4e3a\u7684\u5e38\u89c1\u8868\u8fbe\u5f0f\u6709 O(log(n, 2)) \uff08\u5bf9\u6570\uff09\u3001 O(n) \uff08\u7ebf\u6027\uff09\u3001 O(n^2) \uff08\u5e73\u65b9\uff09\u4ee5\u53ca O(k^n) \uff08\u6307\u6570\uff09\u3002 \u7b97\u6cd5\u5728\u6700\u597d\u60c5\u51b5\u3001\u6700\u574f\u60c5\u51b5\u4ee5\u53ca\u5e73\u5747\u60c5\u51b5\u4e0b\u7684\u6027\u80fd\u53ef\u4ee5\u662f\u4e0d\u540c\u7684\u3002\u6bd4\u5982\uff0c\u5192\u6ce1\u6392\u5e8f\u548c\u63d2\u5165\u6392\u5e8f\u5728\u6700\u597d\u60c5\u51b5\u4e0b\u90fd\u662f\u7ebf\u6027\u590d\u6742\u5ea6\uff0c\u4f46\u662f\u5b83\u4eec\u5728\u5e73\u5747\u60c5\u51b5\u548c\u6700\u574f\u60c5\u51b5\u4e0b\u662f\u5e73\u65b9\u9636\u590d\u6742\u5ea6\u3002 \u901a\u5e38\u6765\u8bf4\uff0c\u8981\u63d0\u9ad8\u7b97\u6cd5\u7684\u6027\u80fd\u6700\u597d\u662f\u5c1d\u8bd5\u964d\u4f4e\u5b83\u7684\u8fd0\u884c\u65f6\u590d\u6742\u5ea6\u7684\u9636\u6570\uff0c\u800c\u4e0d\u662f\u5bf9\u4ee3\u7801\u8fdb\u884c\u5fae\u8c03\u3002 \u4e8c\u5206\u641c\u7d22\u4f1a\u6bd4\u987a\u5e8f\u641c\u7d22\u8981\u5feb\u5f97\u591a\u3002\u4f46\u662f\uff0c\u5728\u7528\u4e8c\u5206\u641c\u7d22\u8fdb\u884c\u641c\u7d22\u65f6\uff0c\u6570\u636e\u5fc5\u987b\u662f\u6709\u5e8f\u7684\u3002 nlogn \u6392\u5e8f\u7b97\u6cd5\u901a\u8fc7\u9012\u5f52\u3001\u5206\u6cbb\u6cd5\u7b56\u7565\u6765\u7a81\u7834 n^2 \u7684\u6027\u80fd\u969c\u788d\u3002\u5feb\u901f\u6392\u5e8f\u4f1a\u5728\u57fa\u51c6\u5143\u7d20\u5de6\u53f3\u5bf9\u5176\u4ed6\u5143\u7d20\u91cd\u65b0\u6392\u5217\uff0c\u7136\u540e\u5bf9\u57fa\u51c6\u4e24\u4fa7\u7684\u5b50\u5217\u8868\u9012\u5f52\u5730\u6392\u5e8f\u3002\u5f52\u5e76\u6392\u5e8f\u5219\u4f1a\u628a\u4e00\u4e2a\u5217\u8868\u8fdb\u884c\u62c6\u5206\uff0c\u9012\u5f52\u5730\u5bf9\u6bcf\u4e2a\u90e8\u5206\u8fdb\u884c\u6392\u5e8f\uff0c\u7136\u540e\u5408\u5e76\u51fa\u6700\u7ec8\u7ed3\u679c\u3002 \u6307\u6570\u590d\u6742\u5ea6\u7684\u7b97\u6cd5\u901a\u5e38\u53ea\u5728\u7406\u8bba\u4e0a\u88ab\u5173\u6ce8\uff0c\u5728\u5904\u7406\u5927\u578b\u95ee\u9898\u7684\u65f6\u5019\uff0c\u5b83\u4eec\u662f\u6ca1\u6709\u4f7f\u7528\u4ef7\u503c\u7684\u3002","title":"3.8.\u5c0f\u7ed3"},{"location":"python/DataStructure/03_TimeComplexity/#39","text":"\u5728\u4e0d\u540c\u95ee\u9898\u89c4\u6a21\u7684\u60c5\u51b5\u4e0b\u8bb0\u5f55\u7b97\u6cd5\u8fd0\u884c\u65f6\uff1a \u53ef\u4ee5\u8ba9\u4f60\u5927\u81f4\u4e86\u89e3\u7b97\u6cd5\u7684\u8fd0\u884c\u65f6\u884c\u4e3a \u53ef\u4ee5\u8ba9\u4f60\u4e86\u89e3\u7b97\u6cd5\u5728\u7279\u5b9a\u786c\u4ef6\u5e73\u53f0\u548c\u7279\u5b9a\u8f6f\u4ef6\u5e73\u53f0\u4e0a\u7684\u8fd0\u884c\u65f6\u884c\u4e3a \u7edf\u8ba1\u6307\u4ee4\u7684\u6570\u91cf\u4f1a\uff1a \u5728\u4e0d\u540c\u7684\u786c\u4ef6\u548c\u8f6f\u4ef6\u5e73\u53f0\u4e0a\u5f97\u5230\u76f8\u540c\u7684\u6570\u636e \u53ef\u4ee5\u8bc1\u660e\u5728\u95ee\u9898\u89c4\u6a21\u5f88\u5927\u7684\u60c5\u51b5\u4e0b\uff0c\u6307\u6570\u7b97\u6cd5\u662f\u6ca1\u6cd5\u4f7f\u7528\u7684 \u8868\u8fbe\u5f0f O(n) \u3001 O(n^2) \u548c O(k^n) \u5206\u522b\u4ee3\u8868\u7684\u590d\u6742\u5ea6\u662f\uff1a \u6307\u6570\u3001\u7ebf\u6027\u548c\u5e73\u65b9 \u7ebf\u6027\u3001\u5e73\u65b9\u548c\u6307\u6570 \u5bf9\u6570\u3001\u7ebf\u6027\u548c\u5e73\u65b9 \u4e8c\u5206\u641c\u7d22\u9700\u8981\u5047\u5b9a\u6570\u636e\uff1a \u6ca1\u6709\u4efb\u4f55\u7279\u522b\u7684\u987a\u5e8f\u5173\u7cfb \u6709\u5e8f\u7684 \u9009\u62e9\u6392\u5e8f\u6700\u591a\u53ef\u4ee5\u6709\uff1a n^2 \u6b21\u6570\u636e\u5143\u7d20\u7684\u4ea4\u6362 n \u6b21\u6570\u636e\u5143\u7d20\u7684\u4ea4\u6362 \u63d2\u5165\u6392\u5e8f\u548c\u4fee\u6539\u540e\u7684\u5192\u6ce1\u6392\u5e8f\u5728\u6700\u597d\u60c5\u51b5\u4e0b\u662f\uff1a \u7ebf\u6027\u7684 \u5e73\u65b9\u7684 \u6307\u6570\u7684 \u6700\u597d\u60c5\u51b5\u3001\u5e73\u5747\u60c5\u51b5\u4ee5\u53ca\u6700\u574f\u60c5\u51b5\u4e0b\u590d\u6742\u5ea6\u90fd\u76f8\u540c\u7684\u7b97\u6cd5\u662f\uff1a \u987a\u5e8f\u641c\u7d22 \u9009\u62e9\u6392\u5e8f \u5feb\u901f\u6392\u5e8f \u4e00\u822c\u6765\u8bf4\uff0c\u4e0b\u9762\u54ea\u4e2a\u9009\u62e9\u66f4\u597d\uff1a \u8c03\u6574\u7b97\u6cd5\u4ece\u800c\u8282\u7701\u82e5\u5e72\u79d2\u7684\u8fd0\u884c\u65f6 \u9009\u62e9\u8ba1\u7b97\u590d\u6742\u5ea6\u66f4\u4f4e\u7684\u7b97\u6cd5 \u5bf9\u4e8e\u9012\u5f52\u6590\u6ce2\u90a3\u5951\u51fd\u6570\uff1a \u95ee\u9898\u89c4\u6a21\u4e3a n \u7684\u65f6\u5019\uff0c\u6709 n^2 \u6b21\u9012\u5f52\u8c03\u7528 \u95ee\u9898\u89c4\u6a21\u4e3a n \u7684\u65f6\u5019\uff0c\u6709 2n \u6b21\u9012\u5f52\u8c03\u7528 \u5b8c\u5168\u586b\u5145\u7684\u4e8c\u53c9\u8c03\u7528\u6811\u91cc\u6bcf\u4e00\u5c42\uff1a \u8c03\u7528\u6b21\u6570\u662f\u4e0a\u4e00\u5c42\u8c03\u7528\u6b21\u6570\u76842\u500d \u4e0e\u4e0a\u4e00\u5c42\u76f8\u540c\u7684\u8c03\u7528\u6b21\u6570","title":"3.9.\u590d\u4e60\u9898"},{"location":"python/DataStructure/03_TimeComplexity/#310","text":"1\uff0e\u5bf9\u4e00\u4e2a\u6709\u5e8f\u5217\u8868\u8fdb\u884c\u987a\u5e8f\u641c\u7d22\uff0c\u5f53\u76ee\u6807\u5c0f\u4e8e\u6709\u5e8f\u5217\u8868\u91cc\u7684\u67d0\u4e2a\u5143\u7d20\u65f6\uff0c\u987a\u5e8f\u641c\u7d22\u53ef\u4ee5\u63d0\u524d\u505c\u6b62\u3002\u5b9a\u4e49\u8fd9\u4e2a\u7b97\u6cd5\u7684\u4fee\u6539\u7248\u672c\uff0c\u5e76\u4f7f\u7528\u5927O\u8868\u793a\u6cd5\u6765\u63cf\u8ff0\u5b83\u5728\u6700\u597d\u60c5\u51b5\u3001\u6700\u574f\u60c5\u51b5\u4ee5\u53ca\u5e73\u5747\u60c5\u51b5\u4e0b\u7684\u8ba1\u7b97\u590d\u6742\u5ea6\u3002 \u89e3\u7b54\uff1a \u5728\u6700\u597d\u7684\u60c5\u51b5\u4e0b\uff0c\u76ee\u6807\u5143\u7d20\u5728\u6709\u5e8f\u5217\u8868\u7684\u7b2c\u4e00\u4e2a\u4f4d\u7f6e\u3002\u5728\u8fd9\u79cd\u60c5\u51b5\u4e0b\uff0c\u51fd\u6570\u53ea\u9700\u8981\u8fdb\u884c\u4e00\u6b21\u6bd4\u8f83\u3002\u6240\u4ee5\uff0c\u6700\u4f73\u60c5\u51b5\u590d\u6742\u5ea6\u4e3a O(1) \u3002 \u5728\u6700\u574f\u7684\u60c5\u51b5\u4e0b\uff0c\u76ee\u6807\u5143\u7d20\u4e0d\u5728\u5217\u8868\u4e2d\uff0c\u5e76\u4e14\u6240\u6709\u5217\u8868\u5143\u7d20\u90fd\u5c0f\u4e8e\u76ee\u6807\u5143\u7d20\u3002\u8fd9\u5c06\u5bfc\u81f4\u51fd\u6570\u904d\u5386\u6574\u4e2a\u5217\u8868\uff0c\u6240\u4ee5\u6700\u574f\u60c5\u51b5\u590d\u6742\u5ea6\u4e3a O(n) \u3002 \u5bf9\u4e8e\u5e73\u5747\u60c5\u51b5\uff0c\u5047\u8bbe\u6709 n \u4e2a\u9879\u5728\u5217\u8868\u4e2d\uff0c\u641c\u7d22\u76ee\u6807\u4f1a\u5728\u5217\u8868\u524d n/2 \u4e2a\u9879\u6216\u8005\u4e0d\u5728\u6240\u6709\u3002\u5728\u8fd9\u4e2a\u7ea6\u5b9a\u4e0b\uff0c\u5e73\u5747\u6211\u4eec\u9700\u8981\u5bfb\u627e n/2 \u4e2a\u9879\uff0c\u56e0\u6b64\u590d\u6742\u5ea6\u4e3a O(n) \u3002\u4e4b\u6240\u4ee5\u662f n/2 \uff0c\u662f\u56e0\u4e3a\u8fd9\u4e2a\u4efb\u52a1\u53ef\u80fd\u4f1a\u5728\u4efb\u4f55\u5730\u65b9\u88ab\u505c\u6b62\uff0c\u6211\u4eec\u5bf9\u6b64\u505a\u5e73\u5747\u5904\u7406\u3002\u7136\u800c\u5728\u5927O\u6807\u8bb0\u6cd5\u4e2d\uff0c\u5e38\u6570\u5c06\u88ab\u9057\u5fd8\uff0c\u6240\u4ee5\u5b83\u4ecd\u7136\u662f O(n) \u3002 \u4ee3\u7801\u5982\u4e0b\uff1a def ordered_sequential_search ( arr , target ): comparisons = 0 # \u7528\u4e8e\u7edf\u8ba1\u6bd4\u8f83\u6b21\u6570 index = 0 while index < len ( arr ): comparisons += 1 if arr [ index ] == target : return comparisons , index # \u627e\u5230\u76ee\u6807\u5e76\u8fd4\u56de\u6bd4\u8f83\u6b21\u6570\u548c\u7d22\u5f15 elif arr [ index ] > target : break # \u5982\u679c\u76ee\u6807\u5c0f\u4e8e\u5f53\u524d\u5143\u7d20\uff0c\u63d0\u524d\u505c\u6b62\u641c\u7d22 index += 1 return comparisons , - 1 # \u6ca1\u627e\u5230\u76ee\u6807\u8fd4\u56de\u6bd4\u8f83\u6b21\u6570\u548c-1 def main (): # \u6d4b\u8bd5 arr = [ 1 , 2 , 3 , 4 , 5 , 6 , 7 , 8 , 9 , 10 ] for target in [ 5 , 11 ]: comparisons , index = ordered_sequential_search ( arr , target ) if index != - 1 : print ( f \"\u76ee\u6807 { target } \u5728\u7d22\u5f15 { index } \u5904\u627e\u5230\uff0c\u6bd4\u8f83\u6b21\u6570\u4e3a { comparisons } \" ) else : print ( f \"\u76ee\u6807 { target } \u672a\u627e\u5230\uff0c\u6bd4\u8f83\u6b21\u6570\u4e3a { comparisons } \" ) if __name__ == \"__main__\" : main () # \u8fd0\u884c\u7ed3\u679c # \u76ee\u6807 5 \u5728\u7d22\u5f15 4 \u5904\u627e\u5230\uff0c\u6bd4\u8f83\u6b21\u6570\u4e3a 5 # \u76ee\u6807 11 \u672a\u627e\u5230\uff0c\u6bd4\u8f83\u6b21\u6570\u4e3a 10 2\uff0e\u5217\u8868\u7684 reverse \u65b9\u6cd5\u7528\u6765\u53cd\u8f6c\u5217\u8868\u91cc\u7684\u5143\u7d20\u3002\u5b9a\u4e49\u4e00\u4e2a\u53eb\u4f5c reverse \u7684\u51fd\u6570\uff0c\u8fd9\u4e2a\u51fd\u6570\u53ef\u4ee5\u5728\u4e0d\u4f7f\u7528 reverse \u65b9\u6cd5\u7684\u60c5\u51b5\u4e0b\uff0c\u53cd\u8f6c\u5217\u8868\u53c2\u6570\u91cc\u7684\u6240\u6709\u5143\u7d20\u3002\u5c1d\u8bd5\u8ba9\u8fd9\u4e2a\u51fd\u6570\u5c3d\u53ef\u80fd\u5730\u9ad8\u6548\uff0c\u5e76\u4f7f\u7528\u5927O\u8868\u793a\u6cd5\u63cf\u8ff0\u5b83\u7684\u8ba1\u7b97\u590d\u6742\u5ea6\u3002 \u89e3\u7b54\uff1a \u53ea\u9700\u8981\u904d\u5386\u5217\u8868\u7684\u4e00\u534a\uff0c\u6211\u4eec\u5c31\u80fd\u5230\u8fbe\u5217\u8868\u7684\u4e2d\u95f4\u4f4d\u7f6e\u628a\u5217\u8868\u4e24\u8fb9\u7684\u5143\u7d20\u4e92\u6362\uff0c\u8fd9\u6837\u5c31\u5b8c\u6210\u4e86\u5217\u8868\u7684\u53cd\u8f6c\u3002 \u8fd9\u4e2a\u7b97\u6cd5\u7684\u65f6\u95f4\u590d\u6742\u5ea6\u662f O(n/2) \uff0c\u5176\u4e2d n \u662f\u5217\u8868\u7684\u957f\u5ea6\u3002\u4f46\u5728\u5927O\u8868\u793a\u6cd5\u4e2d\uff0c\u5e38\u6570\u88ab\u5ffd\u7565\uff0c\u56e0\u6b64\u8be5\u7b97\u6cd5\u7684\u65f6\u95f4\u590d\u6742\u5ea6\u662f O(n) \u3002\u5728\u8fd9\u4e2a\u7b97\u6cd5\u4e2d\uff0c n \u5c31\u4ee3\u8868\u7740\u5217\u8868\u7684\u957f\u5ea6\u3002\u610f\u5473\u7740\u65f6\u95f4\u590d\u6742\u5ea6\u53d7\u5217\u8868\u957f\u5ea6\u7684\u5f71\u54cd\u3002\u5217\u8868\u957f\u5ea6\u6bcf\u589e\u52a0\u4e00\u6b21\uff0c\u6267\u884c\u53cd\u8f6c\u7684\u65f6\u95f4\u5c31\u589e\u52a0\u4e00\u6b21\u3002\u8fd9\u5c31\u662f O(n) \u7684\u6982\u5ff5\u3002 \u8fd9\u4e2a\u51fd\u6570\u7684\u7a7a\u95f4\u590d\u6742\u5ea6\u662f O(1) \uff0c\u56e0\u4e3a\u5b83\u53ea\u662f\u5728\u539f\u5730\u4fee\u6539\u5217\u8868\uff0c\u4e0d\u9700\u8981\u989d\u5916\u7684\u5b58\u50a8\u7a7a\u95f4\u3002 \u4ee3\u7801\u5982\u4e0b\uff1a def custom_reverse ( arr ): left , right = 0 , len ( arr ) - 1 while left < right : arr [ left ], arr [ right ] = arr [ right ], arr [ left ] left += 1 right -= 1 def main (): # \u6d4b\u8bd5\u5217\u8868reverse\u65b9\u6cd5 my_list = [ 1 , 2 , 3 , 4 , 5 ] my_list . reverse () print ( my_list ) # \u6d4b\u8bd5\u81ea\u5b9a\u4e49\u7684reverse\u65b9\u6cd5 my_list = [ 1 , 2 , 3 , 4 , 5 ] custom_reverse ( my_list ) print ( my_list ) if __name__ == \"__main__\" : main () # \u8fd0\u884c\u7ed3\u679c # [5, 4, 3, 2, 1] # [5, 4, 3, 2, 1] 3\uff0ePython\u7684pow\u51fd\u6570\u4f1a\u8fd4\u56de\u6570\u5b57\u7279\u5b9a\u5e42\u6b21\u7684\u7ed3\u679c\u3002\u5b9a\u4e49\u6267\u884c\u8fd9\u4e2a\u4efb\u52a1\u7684expo\u51fd\u6570\uff0c\u5e76\u4f7f\u7528\u5927O\u8868\u793a\u6cd5\u63cf\u8ff0\u5b83\u7684\u8ba1\u7b97\u590d\u6742\u5ea6\u3002\u8fd9\u4e2a\u51fd\u6570\u7684\u7b2c\u4e00\u4e2a\u53c2\u6570\u662f\u6570\u5b57\uff0c\u7b2c\u4e8c\u4e2a\u53c2\u6570\u662f\u6307\u6570\uff08\u975e\u8d1f\u6570\uff09\u3002\u4f60\u53ef\u4ee5\u901a\u8fc7\u5faa\u73af\u6216\u9012\u5f52\u51fd\u6570\u6765\u5b9e\u73b0\uff0c\u4f46\u4e0d\u8981\u4f7f\u7528Python\u5185\u7f6e\u7684**\u8fd0\u7b97\u7b26\u6216\u662fpow\u51fd\u6570\u3002 \u89e3\u7b54\uff1a \u4e0b\u9762\u5b9e\u73b0\u7684 expo \u51fd\u6570\u4f7f\u7528\u5faa\u73af\u6765\u8fde\u7eed\u4e58\u4ee5 base \uff0c\u5faa\u73af\u7684\u6b21\u6570\u7b49\u4e8e exponent \u7684\u503c\u3002 \u65f6\u95f4\u590d\u6742\u5ea6\u662f O(exponent) \uff0c\u5176\u4e2d exponent \u662f\u6307\u6570\u7684\u503c\u3002 \u6700\u597d\u60c5\u51b5\uff1aO(exponent) \u6700\u574f\u60c5\u51b5\uff1aO(exponent) \u5e73\u5747\u60c5\u51b5\uff1aO(exponent) def expo ( base , exponent ): result = 1 for _ in range ( exponent ): result *= base return result def main (): # \u6d4b\u8bd5 base = 2 for exponent in [ 3 , - 3 ]: result = expo ( base , exponent ) print ( f \" { base } \u7684 { exponent } \u6b21\u65b9\u7b49\u4e8e { result } \" ) if __name__ == \"__main__\" : main () # \u8fd0\u884c\u7ed3\u679c # 2 \u7684 3 \u6b21\u65b9\u7b49\u4e8e 8 # 2 \u7684 -3 \u6b21\u65b9\u7b49\u4e8e 1 4\uff0e\u53e6\u4e00\u4e2a\u5b9e\u73b0 expo \u51fd\u6570\u7684\u7b56\u7565\u4f7f\u7528\u4e0b\u9762\u8fd9\u4e2a\u9012\u5f52\u3002\u8bf7\u5b9a\u4e49\u4f7f\u7528\u8fd9\u4e2a\u7b56\u7565\u7684\u9012\u5f52\u51fd\u6570 expo \uff0c\u5e76\u4f7f\u7528\u5927O\u8868\u793a\u6cd5\u63cf\u8ff0\u5b83\u7684\u8ba1\u7b97\u590d\u6742\u5ea6\u3002 expo ( number \uff0c exponent ) = 1 \uff0c \u5f53 exponent = 0 \u7684\u65f6\u5019 = number * expo ( number , exponent \u2212 1 ) \uff0c \u5f53exponent\u4e3a\u5947\u6570\u7684\u65f6\u5019 = ( expo ( number , exponent / 2 )) 2 \uff0c \u5f53exponent\u4e3a\u5076\u6570\u7684\u65f6\u5019 \u89e3\u7b54\uff1a \u4e0b\u9762\u5b9e\u73b0expo\u51fd\u6570\u662f\u901a\u8fc7\u9012\u5f52\u5b9e\u73b0\uff0c\u5e76\u91c7\u7528\u4e86\u5206\u800c\u6cbb\u4e4b\u7684\u7b56\u7565\u3002 \u5982\u679c\u6307\u6570\u662f\u5947\u6570\uff0c\u5c31\u628a\u95ee\u9898\u5206\u89e3\u4e3a\u4e00\u4e2a\u66f4\u5c0f\u7684\u7248\u672c\uff08\u5373 num * num^(exp - 1) \uff09\uff1b \u5982\u679c\u6307\u6570\u662f\u5076\u6570\uff0c\u5219\u53ef\u4ee5\u5c06\u6307\u6570\u5206\u6210\u4e24\u534a\uff0c\u5e76\u53ea\u8ba1\u7b97\u5176\u4e2d\u7684\u4e00\u534a\uff08\u5373 num^(exp / 2) * num^(exp / 2) \uff09\u3002 \u8fd9\u5c31\u5229\u7528\u4e86\u5e42\u7684\u6027\u8d28 a^(m * n) = (a^m)^n \u3002 \u8be5\u9012\u5f52\u5b9e\u73b0\u7684\u65f6\u95f4\u590d\u6742\u5ea6\u4e3a O(log n) \uff0c\u5176\u4e2dn\u4e3a\u6307\u6570\u3002\u8fd9\u662f\u56e0\u4e3a\u5728\u6307\u6570\u4e3a\u5076\u6570\u7684\u60c5\u51b5\u4e0b\uff0c\u6bcf\u6b21\u9012\u5f52\u8c03\u7528\u90fd\u4f1a\u628a\u95ee\u9898\u89c4\u6a21\u7f29\u5c0f\u4e00\u534a\uff0c\u7c7b\u4f3c\u4e8e\u4e8c\u5206\u67e5\u627e\u7b49\u8bfe\u5206\u5272\u95ee\u9898\u3002 \u7a7a\u95f4\u590d\u6742\u5ea6\u4e5f\u662f O(log n) \uff0c\u8fd9\u4e3b\u8981\u662f\u7531\u4e8e\u51fd\u6570\u8c03\u7528\u6808\u7684\u6df1\u5ea6\u5728\u6307\u6570\u4e3a\u5076\u6570\u7684\u60c5\u51b5\u4e0b\uff0c\u4f1a\u53d8\u4e3a\u539f\u6765\u7684\u4e00\u534a\u3002 def expo ( number , exponent ): if exponent <= 0 : return 1 elif exponent % 2 == 1 : # \u5f53 exponent \u4e3a\u5947\u6570 return number * expo ( number , exponent - 1 ) else : # \u5f53 exponent \u4e3a\u5076\u6570 half_expo = expo ( number , exponent // 2 ) return half_expo * half_expo def main (): # \u6d4b\u8bd5 base = 2 for exponent in [ 3 , - 3 ]: result = expo ( base , exponent ) print ( f \" { base } \u7684 { exponent } \u6b21\u65b9\u7b49\u4e8e { result } \" ) if __name__ == \"__main__\" : main () # \u8fd0\u884c\u7ed3\u679c # 2 \u7684 3 \u6b21\u65b9\u7b49\u4e8e 8 # 2 \u7684 -3 \u6b21\u65b9\u7b49\u4e8e 1 5\uff0ePython\u4e2dlist\u91cc\u7684sort\u65b9\u6cd5\u5305\u542b\u4e00\u4e2a\u7528\u5173\u952e\u5b57\u547d\u540d\u7684\u53c2\u6570reverse\uff0c\u5b83\u7684\u9ed8\u8ba4\u503c\u4e3aFalse\u3002\u7a0b\u5e8f\u5458\u53ef\u4ee5\u901a\u8fc7\u8986\u76d6\u8fd9\u4e2a\u503c\u4ee5\u5bf9\u5217\u8868\u8fdb\u884c\u964d\u5e8f\u6392\u5e8f\u3002\u4fee\u6539\u672c\u7ae0\u8ba8\u8bba\u7684selectionSort\u51fd\u6570\uff0c\u4f7f\u5b83\u53ef\u4ee5\u63d0\u4f9b\u8fd9\u4e2a\u9644\u52a0\u53c2\u6570\u6765\u8ba9\u7a0b\u5e8f\u5458\u51b3\u5b9a\u6392\u5e8f\u7684\u65b9\u5411\u3002 \u89e3\u7b54\uff1a \u901a\u8fc7\u6dfb\u52a0\u4e00\u4e2a\u540d\u4e3a reverse \u7684\u53c2\u6570\u6765\u4fee\u6539 selectionSort \u51fd\u6570\uff0c\u4ee5\u4fbf\u8ba9\u7a0b\u5e8f\u5458\u51b3\u5b9a\u6392\u5e8f\u7684\u65b9\u5411\u3002\u5982\u679c reverse \u4e3a True \uff0c\u6392\u5e8f\u5c06\u662f\u964d\u5e8f\u7684\uff0c\u5982\u679c\u4e3a False \uff08\u9ed8\u8ba4\u503c\uff09\uff0c\u6392\u5e8f\u5c06\u662f\u5347\u5e8f\u7684\u3002 \u4e0b\u9762\u662f\u4fee\u6539\u540e\u7684 selectionSort \u51fd\u6570\uff1a def swap ( lyst , i , j ): \"\"\"\u4ea4\u6362\u5143\u7d20\u4f4d\u7f6e\u4e3ai\u548cj\u7684\u5143\u7d20\"\"\" temp = lyst [ i ] lyst [ i ] = lyst [ j ] lyst [ j ] = temp def selectionSort ( lyst , reverse = False ): \"\"\"\u5b9e\u73b0\u4ea4\u6362\u6392\u5e8f\u7b97\u6cd5\uff0c\u53ef\u4ee5\u9009\u62e9\u5347\u5e8f\u6216\u964d\u5e8f\u6392\u5e8f\"\"\" i = 0 while i < len ( lyst ) - 1 : # \u5b9e\u73b0n-1\u6b21\u641c\u7d22 index = i # \u6700\u5c0f\u6216\u6700\u5927\u5143\u7d20\u4f4d\u7f6e j = i + 1 while j < len ( lyst ): # \u5411\u540e\u904d\u5386\u641c\u7d22\uff0c\u66f4\u65b0\u6700\u5c0f\u6216\u6700\u5927\u5143\u7d20\u4f4d\u7f6e if not reverse : if ( lyst [ j ] < lyst [ index ]): index = j else : if ( lyst [ j ] > lyst [ index ]): index = j j += 1 if index != i : # \u5982\u679c\u9700\u8981\uff0c\u5219\u4ea4\u6362\u5143\u7d20\u4f4d\u7f6e swap ( lyst , index , i ) i += 1 def main (): myList = [ 9 , 4 , 2 , 7 , 6 , 8 , 1 ] print ( \"Before selection sort \" , myList ) selectionSort ( myList ) print ( \"After selection sort \" , myList ) if __name__ == \"__main__\" : main () # \u8fd0\u884c\u7ed3\u679c\uff1a # Before selection sort [9, 4, 2, 7, 6, 8, 1] # After selection sort [1, 2, 4, 6, 7, 8, 9] 6\uff0e\u4fee\u6539\u9012\u5f52\u6590\u6ce2\u90a3\u5951\u51fd\u6570\uff0c\u8ba9\u5b83\u652f\u6301\u672c\u7ae0\u91cc\u8ba8\u8bba\u8fc7\u7684\u8bb0\u5fc6\u5316\u6280\u672f\u3002\u8fd9\u4e2a\u51fd\u6570\u5e94\u6dfb\u52a0\u4e00\u4e2a\u5b57\u5178\u7c7b\u578b\u7684\u53c2\u6570\u3002\u5b83\u7684\u9876\u5c42\u8c03\u7528\u4f1a\u63a5\u6536\u4e00\u4e2a\u7a7a\u5b57\u5178\u4f5c\u4e3a\u53c2\u6570\uff0c\u8fd9\u4e2a\u5b57\u5178\u7684\u952e\u548c\u503c\u5e94\u8be5\u662f\u9012\u5f52\u8c03\u7528\u6240\u4f20\u9012\u7684\u53c2\u6570\u548c\u8ba1\u7b97\u51fa\u7684\u503c\u3002\u4e4b\u540e\uff0c\u7528\u672c\u7ae0\u8ba8\u8bba\u8fc7\u7684\u8ba1\u6570\u5668\u5bf9\u8c61\u5bf9\u9012\u5f52\u8c03\u7528\u7684\u6570\u91cf\u8fdb\u884c\u7edf\u8ba1\u3002 \u89e3\u7b54\uff1a \u4e0b\u9762\u662f\u4e00\u4e2a\u4fee\u6539\u540e\u7684\u7248\u672c\uff0c\u5b83\u4f7f\u7528\u4e00\u4e2a\u5b57\u5178\uff08\u7f13\u5b58\uff09\u6765\u5b58\u50a8\u5df2\u8ba1\u7b97\u7684\u7ed3\u679c\uff0c\u5e76\u4e14\u6dfb\u52a0\u4e86\u4e00\u4e2a\u8ba1\u6570\u5668\u5bf9\u8c61\u6765\u7edf\u8ba1\u9012\u5f52\u8c03\u7528\u6b21\u6570\u3002\u8fd9\u4e2a\u4ee3\u7801\u4f1a\u8f93\u51fa\u6307\u5b9a\u9879\u6570\u7684\u6590\u6ce2\u90a3\u5951\u6570\u4ee5\u53ca\u9012\u5f52\u8c03\u7528\u7684\u603b\u6b21\u6570\u3002\u8bb0\u5fc6\u5316\u6280\u672f\u53ef\u4ee5\u663e\u8457\u63d0\u9ad8\u6590\u6ce2\u90a3\u5951\u51fd\u6570\u7684\u6027\u80fd\uff0c\u907f\u514d\u4e86\u91cd\u590d\u8ba1\u7b97\u3002 class Counter : def __init__ ( self ): self . count = 0 def increment ( self ): self . count += 1 def fib ( n , cache , counter ): \"\"\"\u6590\u6ce2\u90a3\u5951\u9012\u5f52\u6570\u5217\uff0c\u5e26\u6709\u8bb0\u5fc6\u5316\u548c\u8c03\u7528\u8ba1\u6570\u5668\"\"\" if n in cache : return cache [ n ] counter . increment () if n <= 1 : result = 1 else : result = fib ( n - 1 , cache , counter ) + fib ( n - 2 , cache , counter ) cache [ n ] = result return result def main (): n = 10 # \u4f60\u53ef\u4ee5\u8bbe\u7f6e\u4e0d\u540c\u7684\u6590\u6ce2\u90a3\u5951\u6570\u5217\u9879\u6570 cache = {} # \u7528\u4e8e\u7f13\u5b58\u5df2\u8ba1\u7b97\u7ed3\u679c\u7684\u5b57\u5178 counter = Counter () # \u7528\u4e8e\u8ba1\u6570\u9012\u5f52\u8c03\u7528\u6b21\u6570\u7684\u8ba1\u6570\u5668\u5bf9\u8c61 result = fib ( n , cache , counter ) print ( f \"Fibonacci( { n } ) = { result } \" ) print ( f \"Total recursive calls: { counter . count } \" ) if __name__ == \"__main__\" : main () # \u8fd0\u884c\u7ed3\u679c\uff1a # Fibonacci(10) = 89 # Total recursive calls: 11 7\uff0e\u5206\u6790\u4e0a\u9762\u6590\u6ce2\u90a3\u5951\u6570\u5217\u91cc\u5b9a\u4e49\u7684\u8bb0\u5fc6\u5316\u6590\u6ce2\u90a3\u5951\u51fd\u6570\u7684\u6027\u80fd\uff0c\u7edf\u8ba1\u8fd9\u4e2a\u51fd\u6570\u9012\u5f52\u8c03\u7528\u7684\u6b21\u6570\u3002\u4f7f\u7528\u5927O\u8868\u793a\u6cd5\u63cf\u8ff0\u5b83\u7684\u8ba1\u7b97\u590d\u6742\u5ea6\uff0c\u5e76\u8bc1\u660e\u4f60\u7684\u7b54\u6848\u662f\u5408\u7406\u7684\u3002 \u89e3\u7b54\uff1a \u5728\u4e0a\u9762\u7684\u8bb0\u5fc6\u5316\u6590\u6ce2\u90a3\u5951\u51fd\u6570\u4e2d\uff0c\u6211\u4eec\u4f7f\u7528\u4e86\u8bb0\u5fc6\u5316\u6280\u672f\u6765\u907f\u514d\u91cd\u590d\u8ba1\u7b97\u3002\u8fd9\u79cd\u4f18\u5316\u4f1a\u663e\u8457\u51cf\u5c11\u8ba1\u7b97\u65f6\u95f4\uff0c\u56e0\u4e3a\u6bcf\u4e2a\u6590\u6ce2\u90a3\u5951\u6570\u53ea\u4f1a\u88ab\u8ba1\u7b97\u4e00\u6b21\u3002 \u8ba1\u7b97\u590d\u6742\u5ea6\u5206\u6790\uff1a \u8bb0\u5fc6\u5316\u6590\u6ce2\u90a3\u5951\u51fd\u6570\u7684\u8ba1\u7b97\u590d\u6742\u5ea6\u662f O(n) \u3002\u8fd9\u662f\u56e0\u4e3a\u5b83\u9700\u8981\u8ba1\u7b97\u6590\u6ce2\u90a3\u5951\u6570\u5217\u7684\u524d n \u9879\uff0c\u6bcf\u4e00\u9879\u53ea\u9700\u8ba1\u7b97\u4e00\u6b21\uff0c\u7136\u540e\u5b58\u50a8\u5728\u7f13\u5b58\u4e2d\u3002\u56e0\u6b64\uff0c\u603b\u5171\u6267\u884c\u7684\u8ba1\u7b97\u91cf\u4e0e n \u6210\u6b63\u6bd4\uff0c\u5373 O(n) \u3002 \u9012\u5f52\u8c03\u7528\u6b21\u6570\uff1a \u9012\u5f52\u8c03\u7528\u7684\u6b21\u6570\u53d6\u51b3\u4e8e\u8f93\u5165\u53c2\u6570 n \u3002\u5bf9\u4e8e\u6590\u6ce2\u90a3\u5951\u6570\u5217\uff0c\u9012\u5f52\u8c03\u7528\u7684\u6b21\u6570\u5927\u81f4\u7b49\u4e8e n \u3002\u56e0\u4e3a\u6bcf\u4e2a\u9879\u9700\u8981\u8ba1\u7b97\u4e00\u6b21\uff0c\u6240\u4ee5\u9012\u5f52\u8c03\u7528\u7684\u6b21\u6570\u4e0e\u8ba1\u7b97\u7684\u9879\u6570\u662f\u4e00\u81f4\u7684\u3002 \u6240\u4ee5\uff0c\u8fd9\u4e2a\u8bb0\u5fc6\u5316\u6590\u6ce2\u90a3\u5951\u51fd\u6570\u7684\u8ba1\u7b97\u590d\u6742\u5ea6\u662f O(n) \uff0c\u800c\u9012\u5f52\u8c03\u7528\u7684\u6b21\u6570\u4e5f\u5927\u81f4\u7b49\u4e8e n \u3002\u8fd9\u4e2a\u6027\u80fd\u662f\u76f8\u5bf9\u8f83\u597d\u7684\uff0c\u56e0\u4e3a\u5b83\u907f\u514d\u4e86\u6307\u6570\u7ea7\u522b\u7684\u91cd\u590d\u8ba1\u7b97\uff0c\u800c\u662f\u7ebf\u6027\u5730\u8ba1\u7b97\u6590\u6ce2\u90a3\u5951\u6570\u5217\u7684\u5404\u9879\u3002 8\uff0e\u51fd\u6570makeRandomList\u4f1a\u521b\u5efa\u5e76\u8fd4\u56de\u4e00\u4e2a\u7ed9\u5b9a\u5927\u5c0f\uff08\u5b83\u7684\u53c2\u6570\uff09\u7684\u6570\u5b57\u5217\u8868\u3002\u5217\u8868\u91cc\u7684\u6570\u5b57\u6ca1\u6709\u91cd\u590d\uff0c\u5b83\u4eec\u7684\u8303\u56f4\u4e3a1\uff5esize\uff0c\u4f4d\u7f6e\u662f\u968f\u673a\u7684\u3002\u4e0b\u9762\u662f\u8fd9\u4e2a\u51fd\u6570\u7684\u4ee3\u7801\u3002\u53ef\u4ee5\u5047\u5b9arange\u3001randint\u548cappend\u51fd\u6570\u90fd\u662f\u5e38\u6570\u65f6\u95f4\u7684\u590d\u6742\u5ea6\u3002\u8fd8\u53ef\u4ee5\u5047\u8bberandom.randint\u968f\u7740\u53c2\u6570\u4e4b\u95f4\u5dee\u503c\u7684\u589e\u52a0\u800c\u66f4\u5c11\u5730\u8fd4\u56de\u91cd\u590d\u7684\u6570\u5b57\u3002\u4f7f\u7528\u5927O\u8868\u793a\u6cd5\u63cf\u8ff0\u8fd9\u4e2a\u51fd\u6570\u7684\u8ba1\u7b97\u590d\u6742\u5ea6\uff0c\u5e76\u8bc1\u660e\u4f60\u7684\u7b54\u6848\u662f\u5408\u7406\u7684\u3002 def makeRandomList ( size ): lyst = [] for count in range ( size ): while True : number = random . randint ( 1 , size ) if not number in lyst : lyst . append ( number ) break return lyst \u89e3\u7b54\uff1a \u8fd9\u4e2a\u51fd\u6570\u7684\u8ba1\u7b97\u590d\u6742\u5ea6\u53d6\u51b3\u4e8e\u5b83\u7684\u5185\u90e8\u5faa\u73af\uff0c\u8be5\u5faa\u73af\u4f1a\u4e0d\u65ad\u751f\u6210\u968f\u673a\u6570\uff0c\u5e76\u68c0\u67e5\u5b83\u662f\u5426\u5df2\u7ecf\u5728\u5217\u8868 lyst \u4e2d\u3002\u5177\u4f53\u5206\u6790\u5982\u4e0b\uff1a \u521b\u5efa\u4e00\u4e2a\u7a7a\u5217\u8868 lyst \uff0c\u65f6\u95f4\u590d\u6742\u5ea6\u4e3a O(1)\u3002 \u8fdb\u5165 for \u5faa\u73af\uff0c\u5faa\u73af\u6b21\u6570\u4e3a size \uff0c\u65f6\u95f4\u590d\u6742\u5ea6\u4e3a O(size)\u3002 \u5728\u5185\u90e8 while \u5faa\u73af\u4e2d\uff0c\u751f\u6210\u4e00\u4e2a\u968f\u673a\u6570 number \uff0c\u6700\u574f\u60c5\u51b5\u4e0b\u9700\u8981\u751f\u6210 size \u6b21\u968f\u673a\u6570\u624d\u80fd\u627e\u5230\u4e00\u4e2a\u4e0d\u5728 lyst \u4e2d\u7684\u6570\u5b57\u3002\u8fd9\u90e8\u5206\u7684\u65f6\u95f4\u590d\u6742\u5ea6\u4e3a O(size)\u3002 \u7efc\u4e0a\u6240\u8ff0\uff0c\u8fd9\u4e2a\u51fd\u6570\u7684\u603b\u4f53\u65f6\u95f4\u590d\u6742\u5ea6\u4e3a O(size^2)\u3002\u8fd9\u662f\u56e0\u4e3a\u5728\u6700\u574f\u60c5\u51b5\u4e0b\uff0c\u6bcf\u6b21\u751f\u6210\u7684\u968f\u673a\u6570\u90fd\u9700\u8981\u68c0\u67e5\u662f\u5426\u5728 lyst \u4e2d\uff0c\u800c\u968f\u673a\u6570\u7684\u751f\u6210\u53ef\u80fd\u9700\u8981\u591a\u6b21\u624d\u80fd\u751f\u6210\u4e00\u4e2a\u4e0d\u5728\u5217\u8868\u4e2d\u7684\u6570\u5b57\u3002 \u9700\u8981\u6ce8\u610f\u7684\u662f\uff0c\u968f\u7740 size \u7684\u589e\u52a0\uff0c\u5185\u90e8\u5faa\u73af\u7684\u8fed\u4ee3\u6b21\u6570\u4e5f\u4f1a\u589e\u52a0\uff0c\u5bfc\u81f4\u65f6\u95f4\u590d\u6742\u5ea6\u5448\u4e8c\u6b21\u589e\u957f\u3002\u56e0\u6b64\uff0c\u8fd9\u4e2a\u51fd\u6570\u7684\u6027\u80fd\u5728\u5927\u89c4\u6a21\u6570\u636e\u4e0a\u53ef\u80fd\u4f1a\u53d7\u5230\u9650\u5236\u3002\u5982\u679c\u9700\u8981\u66f4\u597d\u7684\u6027\u80fd\uff0c\u53ef\u4ee5\u8003\u8651\u5176\u4ed6\u7b97\u6cd5\uff0c\u4ee5\u907f\u514d\u91cd\u590d\u68c0\u67e5\u548c\u751f\u6210\u968f\u673a\u6570\u3002 import random def makeRandomList ( size ): lyst = [] for count in range ( size ): while True : number = random . randint ( 1 , size ) if not number in lyst : lyst . append ( number ) break print ( \"count=\" , count , \"list=\" , lyst ) return lyst def main (): print ( \"final list=\" , makeRandomList ( 10 )) if __name__ == \"__main__\" : main () # \u8fd0\u884c\u7ed3\u679c\uff1a # count= 0 list= [2] # count= 1 list= [2, 10] # count= 2 list= [2, 10, 9] # count= 3 list= [2, 10, 9, 5] # count= 4 list= [2, 10, 9, 5, 3] # count= 5 list= [2, 10, 9, 5, 3, 4] # count= 6 list= [2, 10, 9, 5, 3, 4, 8] # count= 7 list= [2, 10, 9, 5, 3, 4, 8, 7] # count= 8 list= [2, 10, 9, 5, 3, 4, 8, 7, 6] # count= 9 list= [2, 10, 9, 5, 3, 4, 8, 7, 6, 1] # final list= [2, 10, 9, 5, 3, 4, 8, 7, 6, 1] 9\uff0e\u4fee\u6539quicksort\u51fd\u6570\uff0c\u8ba9\u5b83\u53ef\u4ee5\u5bf9\u4efb\u4f55\u5c3a\u5bf8\u5c0f\u4e8e50\u7684\u5b50\u5217\u8868\u8c03\u7528\u63d2\u5165\u6392\u5e8f\u3002\u4f7f\u7528\u670950\u3001500\u548c5000\u4e2a\u5143\u7d20\u7684\u6570\u636e\u96c6\u6bd4\u8f83\u8fd9\u4e2a\u7248\u672c\u4e0e\u539f\u59cb\u7248\u672c\u7684\u6027\u80fd\u3002\u7136\u540e\u8c03\u6574\u8fd9\u4e2a\u9608\u503c\uff0c\u4ece\u800c\u786e\u5b9a\u4f7f\u7528\u63d2\u5165\u6392\u5e8f\u7684\u6700\u4f73\u8bbe\u7f6e\u3002 \u89e3\u7b54\uff1a \u53ef\u4ee5\u5728 quicksortHelper \u51fd\u6570\u4e2d\u6dfb\u52a0\u4e00\u4e2a\u6761\u4ef6\uff0c\u68c0\u67e5\u5b50\u5217\u8868\u7684\u5927\u5c0f\u3002\u7136\u540e\u518d\u4fee\u6539 quicksort \u51fd\u6570\uff0c\u5b9e\u73b0\u5728\u5c0f\u4e8e50\u7684\u5b50\u5217\u8868\u4e0a\u4f7f\u7528\u63d2\u5165\u6392\u5e8f\u3002 \u5982\u679c\u5b50\u5217\u8868\u7684\u5927\u5c0f\u5c0f\u4e8e50\uff0c\u5c31\u4f7f\u7528\u63d2\u5165\u6392\u5e8f\u7b97\u6cd5\uff0c\u5426\u5219\u4f7f\u7528\u5feb\u901f\u6392\u5e8f\u7b97\u6cd5\u3002\u4e0b\u9762\u662f\u4fee\u6539\u540e\u7684\u4ee3\u7801\uff1a import random def swap ( lyst , i , j ): \"\"\"\u4ea4\u6362\u5143\u7d20\u4f4d\u7f6e\u4e3ai\u548cj\u7684\u5143\u7d20\"\"\" temp = lyst [ i ] lyst [ i ] = lyst [ j ] lyst [ j ] = temp def quicksort ( lyst ): quicksortHelper ( lyst , 0 , len ( lyst ) - 1 ) def quicksortHelper ( lyst , left , right ): if left < right : # \u68c0\u67e5\u5b50\u5217\u8868\u7684\u5927\u5c0f\u662f\u5426\u5c0f\u4e8e50 if right - left < 50 : # \u5982\u679c\u5c0f\u4e8e50\uff0c\u4f7f\u7528\u63d2\u5165\u6392\u5e8f insertionSort ( lyst , left , right ) else : pivotLocation = partition ( lyst , left , right ) quicksortHelper ( lyst , left , pivotLocation - 1 ) quicksortHelper ( lyst , pivotLocation + 1 , right ) def partition ( lyst , left , right ): \"\"\"\u5bf9\u5217\u8868\u8fdb\u884c\u5206\u533a\"\"\" # \u627e\u5230\u57fa\u51c6\u5143\u7d20\uff08pivot\uff09\uff0c\u5e76\u548c\u6700\u540e\u4e00\u4e2a\u5143\u7d20\u4e92\u6362 middle = ( left + right ) // 2 pivot = lyst [ middle ] lyst [ middle ] = lyst [ right ] lyst [ right ] = pivot # \u8bbe\u5b9a\u8fb9\u754c\u5143\u7d20\uff08boundary point\uff09\uff0c\u521d\u59cb\u662f\u7b2c\u4e00\u4e2a\u5143\u7d20 boundary = left print ( \"pivot: \" , pivot , \"boundary: \" , lyst [ boundary ]) # \u628a\u6240\u6709\u5c0f\u4e8e\u57fa\u51c6\u7684\u5143\u7d20\u90fd\u79fb\u52a8\u5230\u8fb9\u754c\u7684\u5de6\u8fb9 for index in range ( left , right ): if lyst [ index ] < pivot : swap ( lyst , index , boundary ) boundary += 1 # \u4ea4\u6362\u57fa\u51c6\u5143\u7d20\u548c\u8fb9\u754c\u5143\u7d20 swap ( lyst , right , boundary ) print ( lyst ) return boundary def insertionSort ( lyst , left , right ): \"\"\"\u63d2\u5165\u6392\u5e8f\u7b97\u6cd5\"\"\" for i in range ( left + 1 , right + 1 ): currentElement = lyst [ i ] j = i while j > left and currentElement < lyst [ j - 1 ]: lyst [ j ] = lyst [ j - 1 ] j -= 1 lyst [ j ] = currentElement def main ( size = 20 , sort = quicksort ): lyst = [ random . randint ( 1 , size ) for _ in range ( size )] print ( \"Before sorted\" , lyst ) sort ( lyst ) print ( \"After sorted\" , lyst ) if __name__ == \"__main__\" : main () # \u8fd0\u884c\u7ed3\u679c\uff1a # Before sorted [1, 3, 6, 14, 9, 6, 14, 15, 17, 13, 4, 3, 1, 13, 11, 16, 2, 4, 6, 2] # After sorted [1, 1, 2, 2, 3, 3, 4, 4, 6, 6, 6, 9, 11, 13, 13, 14, 14, 15, 16, 17] 10\uff0e\u8ba1\u7b97\u673a\u4f7f\u7528\u540d\u4e3a\u8c03\u7528\u6808\u7684\u7ed3\u6784\u6765\u4e3a\u9012\u5f52\u51fd\u6570\u7684\u8c03\u7528\u63d0\u4f9b\u652f\u6301\u3002\u4e00\u822c\u800c\u8a00\uff0c\u8ba1\u7b97\u673a\u4f1a\u4e3a\u51fd\u6570\u7684\u6bcf\u6b21\u8c03\u7528\u90fd\u4fdd\u7559\u4e00\u5b9a\u6570\u91cf\u7684\u5185\u5b58\u3002\u56e0\u6b64\uff0c\u53ef\u4ee5\u5bf9\u9012\u5f52\u51fd\u6570\u4f7f\u7528\u7684\u5185\u5b58\u6570\u91cf\u8fdb\u884c\u590d\u6742\u5ea6\u5206\u6790\u3002\u8bf7\u8bf4\u660e\u9012\u5f52\u9636\u4e58\u51fd\u6570\u548c\u9012\u5f52\u6590\u6ce2\u90a3\u5951\u51fd\u6570\u4f7f\u7528\u7684\u5185\u5b58\u7684\u8ba1\u7b97\u590d\u6742\u5ea6\u3002 \u89e3\u7b54\uff1a \u9012\u5f52\u9636\u4e58\u51fd\u6570\u548c\u9012\u5f52\u6590\u6ce2\u90a3\u5951\u51fd\u6570\u4f7f\u7528\u7684\u5185\u5b58\u7684\u8ba1\u7b97\u590d\u6742\u5ea6\u90fd\u4e0e\u9012\u5f52\u7684\u6df1\u5ea6\uff08\u9012\u5f52\u8c03\u7528\u7684\u5c42\u6570\uff09\u76f8\u5173\u3002\u9012\u5f52\u51fd\u6570\u6bcf\u6b21\u8c03\u7528\u90fd\u4f1a\u5728\u8c03\u7528\u6808\u4e2d\u5206\u914d\u4e00\u5b9a\u6570\u91cf\u7684\u5185\u5b58\uff0c\u5305\u62ec\u51fd\u6570\u7684\u53c2\u6570\u3001\u5c40\u90e8\u53d8\u91cf\u4ee5\u53ca\u8fd4\u56de\u5730\u5740\u7b49\u4fe1\u606f\u3002 \u9012\u5f52\u9636\u4e58\u51fd\u6570\u7684\u5185\u5b58\u590d\u6742\u5ea6\uff1a \u9012\u5f52\u9636\u4e58\u51fd\u6570\u662f\u4e00\u4e2a\u975e\u5e38\u7b80\u5355\u7684\u9012\u5f52\u51fd\u6570\uff0c\u5b83\u53ea\u9700\u8981\u4fdd\u5b58\u4e00\u4e2a\u6574\u6570\u53c2\u6570 n \u548c\u8fd4\u56de\u5730\u5740\u3002\u56e0\u6b64\uff0c\u5b83\u7684\u5185\u5b58\u590d\u6742\u5ea6\u662f O(1)\uff0c\u4e0e\u8f93\u5165\u53c2\u6570 n \u7684\u5927\u5c0f\u65e0\u5173\u3002\u6bcf\u4e2a\u9012\u5f52\u8c03\u7528\u90fd\u53ea\u9700\u8981\u5e38\u6570\u7ea7\u522b\u7684\u5185\u5b58\u7a7a\u95f4\u3002 \u9012\u5f52\u6590\u6ce2\u90a3\u5951\u51fd\u6570\u7684\u5185\u5b58\u590d\u6742\u5ea6\uff1a \u9012\u5f52\u6590\u6ce2\u90a3\u5951\u51fd\u6570\u7684\u5185\u5b58\u590d\u6742\u5ea6\u53d6\u51b3\u4e8e\u9012\u5f52\u7684\u6df1\u5ea6\u3002\u6bcf\u4e2a\u9012\u5f52\u8c03\u7528\u90fd\u9700\u8981\u4fdd\u5b58\u4e24\u4e2a\u6574\u6570\u53c2\u6570 n \u548c depth \uff0c\u4ee5\u53ca\u8fd4\u56de\u5730\u5740\u3002\u56e0\u6b64\uff0c\u6bcf\u6b21\u9012\u5f52\u8c03\u7528\u9700\u8981\u7684\u5185\u5b58\u7a7a\u95f4\u662f\u5e38\u6570\u7ea7\u522b\u7684\u3002 \u9012\u5f52\u6590\u6ce2\u90a3\u5951\u51fd\u6570\u7684\u9012\u5f52\u6df1\u5ea6\u53d6\u51b3\u4e8e\u8f93\u5165\u53c2\u6570 n \u3002\u5177\u4f53\u6765\u8bf4\uff0c\u9012\u5f52\u6df1\u5ea6\u7b49\u4e8e n \u3002\u56e0\u6b64\uff0c\u9012\u5f52\u6590\u6ce2\u90a3\u5951\u51fd\u6570\u7684\u5185\u5b58\u590d\u6742\u5ea6\u662f O(n)\uff0c\u4e0e\u8f93\u5165\u53c2\u6570 n \u6210\u6b63\u6bd4\u3002 \u603b\u7ed3\u6765\u8bf4\uff0c\u9012\u5f52\u9636\u4e58\u51fd\u6570\u7684\u5185\u5b58\u590d\u6742\u5ea6\u662f O(1)\uff0c\u800c\u9012\u5f52\u6590\u6ce2\u90a3\u5951\u51fd\u6570\u7684\u5185\u5b58\u590d\u6742\u5ea6\u662f O(n)\u3002\u5728\u9012\u5f52\u7b97\u6cd5\u4e2d\uff0c\u5185\u5b58\u590d\u6742\u5ea6\u901a\u5e38\u4e0e\u9012\u5f52\u6df1\u5ea6\u6210\u6b63\u6bd4\uff0c\u56e0\u6b64\u9700\u8981\u8c28\u614e\u5904\u7406\u9012\u5f52\u8c03\u7528\uff0c\u4ee5\u907f\u514d\u51fa\u73b0\u6808\u6ea2\u51fa\u7b49\u95ee\u9898\u3002\u53ef\u4ee5\u4f7f\u7528\u8fed\u4ee3\u6216\u52a8\u6001\u89c4\u5212\u7b49\u65b9\u6cd5\u6765\u964d\u4f4e\u5185\u5b58\u6d88\u8017\u3002","title":"3.10.\u7f16\u7a0b\u7ec3\u4e60"},{"location":"python/DataStructure/04_ArrayChain/","text":"4.\u6570\u7ec4\u548c\u94fe\u63a5\u7ed3\u6784 \u00b6 \u6570\u636e\u7ed3\u6784\uff08data structure\uff09\u6216\u5177\u4f53\u6570\u636e\u7c7b\u578b\uff08concrete data type\uff09\u662f\u6307\u4e00\u7ec4\u6570\u636e\u7684\u5185\u90e8\u5b58\u50a8\u65b9\u5f0f\u3002 \u6570\u7ec4\uff08array\uff09\u548c\u94fe\u63a5\u7ed3\u6784\uff08linked structure\uff09\u8fd9\u4e24\u79cd\u6570\u636e\u7ed3\u6784\u662f\u7f16\u7a0b\u8bed\u8a00\u91cc\u591a\u9879\u96c6\u6700\u5e38\u7528\u7684\u5b9e\u73b0\u3002 \u76ee\u6807\uff1a \u521b\u5efa\u6570\u7ec4\uff1b \u5bf9\u6570\u7ec4\u6267\u884c\u5404\u79cd\u64cd\u4f5c\uff1b \u786e\u5b9a\u6570\u7ec4\u76f8\u5173\u64cd\u4f5c\u7684\u8fd0\u884c\u65f6\u548c\u5185\u5b58\u7684\u4f7f\u7528\u60c5\u51b5\uff1b \u57fa\u4e8e\u6570\u7ec4\u5728\u8ba1\u7b97\u673a\u5185\u5b58\u91cc\u7684\u4e0d\u540c\u5b58\u50a8\u65b9\u5f0f\uff0c\u63cf\u8ff0\u6570\u7ec4\u76f8\u5173\u64cd\u4f5c\u7684\u6210\u672c\u548c\u6536\u76ca\uff1b \u4f7f\u7528\u5355\u5411\u94fe\u63a5\u8282\u70b9\u521b\u5efa\u94fe\u63a5\u7ed3\u6784\uff1b \u5bf9\u7531\u5355\u5411\u94fe\u63a5\u8282\u70b9\u6784\u6210\u7684\u94fe\u63a5\u7ed3\u6784\u6267\u884c\u5404\u79cd\u64cd\u4f5c\uff1b \u57fa\u4e8e\u94fe\u63a5\u7ed3\u6784\u5728\u8ba1\u7b97\u673a\u5185\u5b58\u91cc\u7684\u4e0d\u540c\u5b58\u50a8\u65b9\u5f0f\uff0c\u63cf\u8ff0\u5728\u94fe\u63a5\u7ed3\u6784\u4e0a\u6267\u884c\u76f8\u5173\u64cd\u4f5c\u7684\u6210\u672c\u548c\u6536\u76ca\uff1b \u6bd4\u8f83\u6570\u7ec4\u548c\u94fe\u63a5\u7ed3\u6784\u5728\u8fd0\u884c\u65f6\u548c\u5185\u5b58\u4f7f\u7528\u4e0a\u7684\u6743\u8861\uff1b 4.1.\u6570\u7ec4\u6570\u636e\u7ed3\u6784 \u00b6 \u5173\u4e8e\u6570\u7ec4\uff08array\uff09\uff1a \u6570\u7ec4\u662f\u6307\u5728\u7ed9\u5b9a\u7d22\u5f15\u4f4d\u7f6e\u53ef\u4ee5\u8bbf\u95ee\u548c\u66ff\u6362\u7684\u5143\u7d20\u5e8f\u5217\u3002 Python\u5217\u8868\u7684\u5e95\u5c42\u6570\u636e\u7ed3\u6784\u6b63\u662f\u4e00\u4e2a\u6570\u7ec4\u3002 Python\u4e2d\u6570\u7ec4\u7684\u9650\u5236\u8981\u6bd4\u5217\u8868\u66f4\u591a\u3002\u53ea\u80fd\u5728\u6307\u5b9a\u4f4d\u7f6e\u8bbf\u95ee\u548c\u66ff\u6362\u6570\u7ec4\u4e2d\u7684\u5143\u7d20\u3001\u68c0\u67e5\u6570\u7ec4\u7684\u957f\u5ea6\u3001\u83b7\u53d6\u5b83\u7684\u5b57\u7b26\u4e32\u8868\u8fbe\u5f0f\uff1b\u4e0d\u80fd\u57fa\u4e8e\u4f4d\u7f6e\u6dfb\u52a0\u6216\u5220\u9664\u5143\u7d20\uff1b\u6570\u7ec4\u7684\u957f\u5ea6\u4e5f\u5c31\u662f\u5b83\u7684\u5bb9\u91cf\uff0c\u5728\u521b\u5efa\u4e4b\u540e\u5c31\u662f\u56fa\u5b9a\u7684\u3002 4.1.1.\u968f\u673a\u8bbf\u95ee\u548c\u8fde\u7eed\u5185\u5b58 \u00b6 \u901a\u8fc7\u4e0b\u6807\u64cd\u4f5c\u6216\u7d22\u5f15\u64cd\u4f5c\u5b9e\u73b0\u5bf9\u6570\u7ec4\u5728\u6307\u5b9a\u4f4d\u7f6e\u5bf9\u5143\u7d20\u8fdb\u884c\u5b58\u50a8\u6216\u68c0\u7d22\u3002 \u6570\u7ec4\u7d22\u5f15\u662f\u968f\u673a\u8bbf\u95ee\uff08random access\uff09\u64cd\u4f5c\uff0c\u800c\u5728\u968f\u673a\u8bbf\u95ee\u65f6\uff0c\u8ba1\u7b97\u673a\u603b\u4f1a\u6267\u884c\u56fa\u5b9a\u7684\u6b65\u9aa4\u6765\u83b7\u53d6\u7b2c i \u4e2a\u5143\u7d20\u7684\u4f4d\u7f6e\u3002\u56e0\u6b64\uff0c\u4e0d\u8bba\u6570\u7ec4\u6709\u591a\u5927\uff0c\u8bbf\u95ee\u7b2c\u4e00\u4e2a\u5143\u7d20\u6240\u9700\u7684\u65f6\u95f4\u548c\u8bbf\u95ee\u6700\u540e\u4e00\u4e2a\u5143\u7d20\u6240\u9700\u8981\u7684\u65f6\u95f4\u90fd\u662f\u76f8\u540c\u7684\u3002 \u8ba1\u7b97\u673a\u901a\u8fc7\u5206\u914d\u4e00\u5757\u8fde\u7eed\u5185\u5b58\uff08contiguous memory\uff09\u5355\u5143\u6765\u5b58\u50a8\u6570\u7ec4\u91cc\u7684\u5143\u7d20\uff0c\u4ece\u800c\u652f\u6301\u5bf9\u6570\u7ec4\u7684\u968f\u673a\u8bbf\u95ee\u3002 \u7531\u4e8e\u6570\u7ec4\u91cc\u7684\u5143\u7d20\u5730\u5740\u90fd\u662f\u6309\u7167\u6570\u5b57\u987a\u5e8f\u8fdb\u884c\u6392\u5217\u7684\uff0c\u56e0\u6b64\u53ef\u4ee5\u901a\u8fc7\u6dfb\u52a0\u4e24\u4e2a\u503c\u6765\u8ba1\u7b97\u51fa\u6570\u7ec4\u5143\u7d20\u7684\u673a\u5668\u5730\u5740\uff0c\u5b83\u4eec\u662f\u6570\u7ec4\u7684\u57fa\u5730\u5740\uff08base address\uff09\u4ee5\u53ca\u5143\u7d20\u7684\u504f\u79fb\u91cf\uff08offset\uff09\u3002\u5176\u4e2d\uff0c\u6570\u7ec4\u7684\u57fa\u5730\u5740\u5c31\u662f\u7b2c\u4e00\u4e2a\u5143\u7d20\u7684\u673a\u5668\u5730\u5740\uff0c\u800c\u5143\u7d20\u7684\u504f\u79fb\u91cf\u5c31\u662f\u5b83\u7684\u7d22\u5f15\u503c\u518d\u4e58\u4ee5\u4e00\u4e2a\u4ee3\u8868\u6570\u7ec4\u5143\u7d20\u6240\u9700\u5185\u5b58\u5355\u5143\u6570\u7684\u5e38\u91cf\uff08\u5728Python\u91cc\uff0c\u8fd9\u4e2a\u503c\u59cb\u7ec8\u662f1\uff09\u3002 \u7b80\u800c\u8a00\u4e4b\uff0cPython\u6570\u7ec4\u91cc\u7684\u7d22\u5f15\u64cd\u4f5c\u5305\u62ec\u4e0b\u9762\u4e24\u4e2a\u6b65\u9aa4\uff1a \u5f97\u5230\u6570\u7ec4\u5185\u5b58\u5757\u7684\u57fa\u5730\u5740\u3002 \u5c06\u7d22\u5f15\u503c\u6dfb\u52a0\u5230\u8fd9\u4e2a\u5730\u5740\u5e76\u8fd4\u56de\u3002 4.1.2.\u9759\u6001\u5185\u5b58\u548c\u52a8\u6001\u5185\u5b58 \u00b6 \u5728\u6bd4\u8f83\u8001\u7684\u7f16\u7a0b\u8bed\u8a00\uff08\u5982FORTRAN\u6216Pascal\uff09\u91cc\uff0c\u6570\u7ec4\u662f\u9759\u6001\u6570\u636e\u7ed3\u6784\u3002\u5728\u8fd9\u79cd\u60c5\u51b5\u4e0b\uff0c\u6570\u7ec4\u7684\u957f\u5ea6\u6216\u5bb9\u91cf\u5728\u7f16\u8bd1\u65f6\u5c31\u786e\u5b9a\u4e86\uff0c\u7a0b\u5e8f\u5458\u9700\u8981\u7533\u8bf7\u8db3\u591f\u591a\u7684\u5185\u5b58\u6765\u6ee1\u8db3\u5728\u6570\u7ec4\u91cc\u5b58\u50a8\u53ef\u80fd\u6709\u6700\u5927\u6570\u91cf\u5143\u7d20\u7684\u60c5\u51b5\uff0c\u8fd9\u6837\u505a\u4f1a\u6d6a\u8d39\u5927\u91cf\u7684\u5185\u5b58\u3002 \u50cfJava\u548cC++\u8fd9\u7c7b\u7684\u73b0\u4ee3\u7f16\u7a0b\u8bed\u8a00\u4f1a\u5141\u8bb8\u7a0b\u5e8f\u5458\u521b\u5efa\u52a8\u6001\u6570\u7ec4\uff08dynamic array\uff09\uff0c\u4ece\u800c\u4e3a\u8fd9\u4e2a\u95ee\u9898\u63d0\u4f9b\u4e86\u4e00\u79cd\u8865\u6551\u65b9\u6cd5\u3002\u548c\u9759\u6001\u6570\u7ec4\u76f8\u4f3c\u7684\u662f\uff0c\u52a8\u6001\u6570\u7ec4\u4e5f\u4f1a\u5360\u7528\u4e00\u5757\u8fde\u7eed\u5185\u5b58\uff0c\u5e76\u652f\u6301\u968f\u673a\u8bbf\u95ee\u3002\u52a8\u6001\u6570\u7ec4\u7684\u957f\u5ea6\u53ea\u5728\u8fd0\u884c\u65f6\u624d\u77e5\u9053\uff0c\u5728\u52a8\u6001\u6570\u7ec4\u5b9e\u4f8b\u5316\u7684\u65f6\u5019\u6307\u5b9a\u5b83\u7684\u957f\u5ea6\u3002\u5728Python\u91cc\u5b9e\u73b0\u7684Array\u7c7b\u7684\u884c\u4e3a\u4e5f\u662f\u8fd9\u6837\u7684\u3002 \u6211\u4eec\u53ef\u4ee5\u901a\u8fc7\u53e6\u4e00\u79cd\u65b9\u6cd5\u5728\u8fd0\u884c\u65f6\u6839\u636e\u5e94\u7528\u7a0b\u5e8f\u7684\u6570\u636e\u8981\u6c42\u6765\u8c03\u6574\u6570\u7ec4\u7684\u957f\u5ea6\uff0c\u8fd9\u4e9b\u8c03\u6574\u4f1a\u7531Python\u5217\u8868\u81ea\u52a8\u8fdb\u884c\u3002\u8fd9\u65f6\uff0c\u6570\u7ec4\u6709\u4ee5\u4e0b3\u79cd\u4e0d\u540c\u5f62\u5f0f\u3002 \u5728\u7a0b\u5e8f\u542f\u52a8\u65f6\u521b\u5efa\u4e00\u4e2a\u5177\u6709\u5408\u7406\u9ed8\u8ba4\u5927\u5c0f\u7684\u6570\u7ec4\u3002 \u5f53\u6570\u7ec4\u65e0\u6cd5\u5bb9\u7eb3\u66f4\u591a\u6570\u636e\u65f6\uff0c\u521b\u5efa\u4e00\u4e2a\u66f4\u5927\u7684\u65b0\u6570\u7ec4\uff0c\u5e76\u628a\u65e7\u6570\u7ec4\u91cc\u7684\u6570\u636e\u5143\u7d20\u4f20\u8f93\u7ed9\u5b83\u3002 \u5982\u679c\u6570\u7ec4\u5728\u6d6a\u8d39\u5185\u5b58\uff08\u5e94\u7528\u7a0b\u5e8f\u5220\u9664\u4e86\u4e00\u4e9b\u6570\u636e\uff09\uff0c\u90a3\u4e48\u7528\u7c7b\u4f3c\u7684\u65b9\u5f0f\u51cf\u5c0f\u6570\u7ec4\u7684\u957f\u5ea6\u3002 4.1.3.\u7269\u7406\u5c3a\u5bf8\u548c\u903b\u8f91\u5c3a\u5bf8 \u00b6 \u6570\u7ec4\u7684\u7269\u7406\u5c3a\u5bf8\uff08physical size\uff09\u662f\u6307\u6570\u7ec4\u5355\u5143\u7684\u603b\u6570\uff0c\u6216\u8005\u521b\u5efa\u6570\u7ec4\u65f6\u6307\u5b9a\u5176\u5bb9\u91cf\u7684\u90a3\u4e2a\u6570\u5b57\uff1b \u6570\u7ec4\u7684\u903b\u8f91\u5c3a\u5bf8\uff08logical size\uff09\u662f\u6307\u5f53\u524d\u5e94\u7528\u7a0b\u5e8f\u4f7f\u7528\u7684\u5143\u7d20\u6570\u91cf\u3002 \u5f53\u6570\u7ec4\u88ab\u586b\u6ee1\u7684\u65f6\u5019\uff0c\u6211\u4eec\u4e0d\u9700\u8981\u62c5\u5fc3\u5b83\u4eec\u7684\u4e0d\u540c\u3002\u5f53\u6570\u7ec4\u88ab\u90e8\u5206\u586b\u6ee1\u7684\u65f6\u5019\uff0c\u672a\u88ab\u586b\u5145\u7684\u5185\u5b58\u5355\u5143\u91cc\u7684\u6570\u636e\u5bf9\u5f53\u524d\u5e94\u7528\u7a0b\u5e8f\u662f\u6ca1\u6709\u7528\u7684\uff0c\u6211\u4eec\u79f0\u4e4b\u5783\u573e\u5185\u5bb9\uff08garbage\uff09\u3002\u5728\u5927\u591a\u6570\u5e94\u7528\u7a0b\u5e8f\u91cc\uff0c\u6211\u4eec\u662f\u8981\u6ce8\u610f\u5bf9\u6570\u7ec4\u7684\u7269\u7406\u5c3a\u5bf8\u548c\u903b\u8f91\u5c3a\u5bf8\u8fdb\u884c\u8ffd\u8e2a\u3002\u901a\u5e38\u6765\u8bf4\uff0c\u903b\u8f91\u5c3a\u5bf8\u548c\u7269\u7406\u5c3a\u5bf8\u4f1a\u53cd\u6620\u51fa\u6709\u5173\u6570\u7ec4\u72b6\u6001\u7684\u51e0\u4e2a\u91cd\u70b9\u3002 \u5982\u679c\u903b\u8f91\u5c3a\u5bf8\u4e3a0\uff0c\u90a3\u4e48\u6570\u7ec4\u5c31\u4e3a\u7a7a\u3002\u4e5f\u5c31\u662f\u8bf4\uff0c\u8fd9\u4e2a\u6570\u7ec4\u4e0d\u5305\u542b\u4efb\u4f55\u6570\u636e\u5143\u7d20\u3002 \u5982\u679c\u5e76\u975e\u4e0a\u8ff0\u60c5\u51b5\uff0c\u5728\u4efb\u4f55\u60c5\u51b5\u4e0b\uff0c\u6570\u7ec4\u4e2d\u6700\u540e\u4e00\u4e2a\u5143\u7d20\u7684\u7d22\u5f15\u90fd\u662f\u5b83\u7684\u903b\u8f91\u5c3a\u5bf8\u51cf1\u3002 \u5982\u679c\u903b\u8f91\u5c3a\u5bf8\u7b49\u4e8e\u7269\u7406\u5c3a\u5bf8\uff0c\u90a3\u4e48\u8868\u793a\u6570\u7ec4\u5df2\u88ab\u586b\u6ee1\u4e86\u3002 4.1.4.\u7ec3\u4e60\u9898 \u00b6 1\uff0e\u8bf7\u8bf4\u660e\u968f\u673a\u8bbf\u95ee\u7684\u5de5\u4f5c\u539f\u7406\uff0c\u4ee5\u53ca\u8fd9\u4e2a\u64cd\u4f5c\u8fd9\u4e48\u5feb\u7684\u539f\u56e0\u3002 \u89e3\u7b54\uff1a\u968f\u673a\u8bbf\u95ee\u662f\u4e00\u79cd\u8ba1\u7b97\u673a\u5b58\u50a8\u7cfb\u7edf\u4e2d\u7684\u8bfb\u53d6\u6216\u5199\u5165\u6570\u636e\u7684\u64cd\u4f5c\uff0c\u5176\u4e2d\u6570\u636e\u53ef\u4ee5\u901a\u8fc7\u76f4\u63a5\u8df3\u8f6c\u5230\u5176\u5b58\u50a8\u4f4d\u7f6e\u800c\u4e0d\u9700\u8981\u987a\u5e8f\u626b\u63cf\u6765\u8bbf\u95ee\u3002\u8fd9\u4e0e\u987a\u5e8f\u8bbf\u95ee\u4e0d\u540c\uff0c\u540e\u8005\u9700\u8981\u6309\u987a\u5e8f\u904d\u5386\u6570\u636e\u4ee5\u627e\u5230\u6240\u9700\u7684\u4fe1\u606f\u3002\u968f\u673a\u8bbf\u95ee\u7684\u5de5\u4f5c\u539f\u7406\u5982\u4e0b\uff1a \u5b58\u50a8\u4ecb\u8d28\uff1a\u8ba1\u7b97\u673a\u5185\u5b58\u548c\u786c\u76d8\u7b49\u5b58\u50a8\u8bbe\u5907\u90fd\u652f\u6301\u968f\u673a\u8bbf\u95ee\u3002\u8fd9\u4e9b\u5b58\u50a8\u4ecb\u8d28\u4e2d\u7684\u6570\u636e\u901a\u5e38\u88ab\u5212\u5206\u4e3a\u5757\u6216\u6247\u533a\uff0c\u5e76\u4e14\u6bcf\u4e2a\u5757\u6216\u6247\u533a\u90fd\u6709\u4e00\u4e2a\u552f\u4e00\u7684\u5730\u5740\u6216\u7d22\u5f15\u3002 \u8bbf\u95ee\u5730\u5740\uff1a\u4e3a\u4e86\u8fdb\u884c\u968f\u673a\u8bbf\u95ee\uff0c\u8ba1\u7b97\u673a\u9700\u8981\u77e5\u9053\u8981\u8bbf\u95ee\u7684\u6570\u636e\u7684\u5730\u5740\u3002\u8fd9\u4e2a\u5730\u5740\u53ef\u4ee5\u662f\u5185\u5b58\u4e2d\u7684\u7279\u5b9a\u4f4d\u7f6e\uff0c\u4e5f\u53ef\u4ee5\u662f\u786c\u76d8\u4e0a\u7684\u67d0\u4e2a\u6247\u533a\u7684\u5730\u5740\u3002 \u5bfb\u5740\u548c\u4f20\u8f93\uff1a\u8ba1\u7b97\u673a\u4f7f\u7528\u5b58\u50a8\u8bbe\u5907\u7684\u63a7\u5236\u5668\u6216\u5b58\u50a8\u5668\u7ba1\u7406\u5355\u5143\u6765\u67e5\u627e\u6570\u636e\u7684\u5730\u5740\u3002\u4e00\u65e6\u627e\u5230\u4e86\u6b63\u786e\u7684\u5730\u5740\uff0c\u5b58\u50a8\u8bbe\u5907\u4f1a\u5c06\u6570\u636e\u4f20\u8f93\u5230\u8ba1\u7b97\u673a\u7684\u5185\u5b58\u4e2d\u4f9b\u5904\u7406\u5668\u4f7f\u7528\u3002 \u8bbf\u95ee\u901f\u5ea6\uff1a\u968f\u673a\u8bbf\u95ee\u4e4b\u6240\u4ee5\u5982\u6b64\u5feb\u901f\uff0c\u662f\u56e0\u4e3a\u8ba1\u7b97\u673a\u5185\u5b58\u548c\u73b0\u4ee3\u786c\u76d8\u9a71\u52a8\u5668\u7b49\u5b58\u50a8\u8bbe\u5907\u90fd\u7ecf\u8fc7\u4e86\u4f18\u5316\uff0c\u53ef\u4ee5\u5feb\u901f\u54cd\u5e94\u8bbf\u95ee\u8bf7\u6c42\u3002\u8fd9\u4e9b\u8bbe\u5907\u4f7f\u7528\u4e86\u9ad8\u901f\u7f13\u5b58\u3001\u8bfb\u5199\u5934\u3001\u5bfb\u9053\u673a\u6784\u7b49\u6280\u672f\u6765\u6700\u5c0f\u5316\u6570\u636e\u8bbf\u95ee\u7684\u5ef6\u8fdf\u3002 \u539f\u56e0\uff1a \u5b58\u50a8\u8bbe\u5907\u7684\u7269\u7406\u7ed3\u6784\uff1a\u8ba1\u7b97\u673a\u5185\u5b58\u548c\u786c\u76d8\u7b49\u5b58\u50a8\u8bbe\u5907\u7684\u7269\u7406\u7ed3\u6784\u88ab\u8bbe\u8ba1\u6210\u53ef\u4ee5\u968f\u673a\u8bbf\u95ee\u7684\u3002\u5185\u5b58\u4e2d\u7684\u6bcf\u4e2a\u5730\u5740\u90fd\u53ef\u4ee5\u77ac\u95f4\u8bbf\u95ee\uff0c\u800c\u786c\u76d8\u4e0a\u7684\u6247\u533a\u4e5f\u53ef\u4ee5\u901a\u8fc7\u78c1\u5934\u5bfb\u9053\u548c\u65cb\u8f6c\u78c1\u76d8\u7b49\u673a\u5236\u8fc5\u901f\u8bbf\u95ee\u3002 \u9ad8\u901f\u7f13\u5b58\uff1a\u73b0\u4ee3\u8ba1\u7b97\u673a\u5185\u5b58\u548c\u5904\u7406\u5668\u90fd\u914d\u5907\u4e86\u9ad8\u901f\u7f13\u5b58\uff08\u4f8b\u5982\uff0cCPU\u7f13\u5b58\uff09\u3002\u8fd9\u4e9b\u9ad8\u901f\u7f13\u5b58\u5b58\u50a8\u4e86\u6700\u8fd1\u8bbf\u95ee\u7684\u6570\u636e\uff0c\u53ef\u4ee5\u5feb\u901f\u63d0\u4f9b\u7ed9\u5904\u7406\u5668\uff0c\u4ece\u800c\u964d\u4f4e\u4e86\u8bbf\u95ee\u5ef6\u8fdf\u3002 \u5b58\u50a8\u5668\u7ba1\u7406\uff1a\u64cd\u4f5c\u7cfb\u7edf\u548c\u5b58\u50a8\u8bbe\u5907\u7684\u63a7\u5236\u5668\u4f1a\u7ba1\u7406\u5b58\u50a8\u5668\u7684\u8bbf\u95ee\uff0c\u4ee5\u786e\u4fdd\u6570\u636e\u53ef\u4ee5\u9ad8\u6548\u5730\u88ab\u8bbf\u95ee\u548c\u4f20\u8f93\u3002\u8fd9\u5305\u62ec\u4e86\u78c1\u76d8\u8c03\u5ea6\u7b97\u6cd5\u3001\u5185\u5b58\u5206\u9875\u7b49\u7b56\u7565\u3002 \u6280\u672f\u8fdb\u6b65\uff1a\u786c\u4ef6\u5236\u9020\u6280\u672f\u7684\u8fdb\u6b65\u548c\u5b58\u50a8\u8bbe\u5907\u7684\u4f18\u5316\u4f7f\u5f97\u968f\u673a\u8bbf\u95ee\u901f\u5ea6\u66f4\u5feb\u3002\u4f8b\u5982\uff0c\u56fa\u6001\u786c\u76d8\uff08SSD\uff09\u7684\u51fa\u73b0\u663e\u8457\u63d0\u9ad8\u4e86\u6570\u636e\u7684\u968f\u673a\u8bbf\u95ee\u901f\u5ea6\u3002 \u603b\u4e4b\uff0c\u968f\u673a\u8bbf\u95ee\u4e4b\u6240\u4ee5\u5982\u6b64\u5feb\u901f\uff0c\u662f\u56e0\u4e3a\u8ba1\u7b97\u673a\u5185\u5b58\u548c\u5b58\u50a8\u8bbe\u5907\u7684\u7269\u7406\u548c\u6280\u672f\u7279\u6027\u4f7f\u5176\u80fd\u591f\u4ee5\u9ad8\u6548\u3001\u8fc5\u901f\u7684\u65b9\u5f0f\u8bbf\u95ee\u6570\u636e\u3002\u8fd9\u79cd\u8bbf\u95ee\u901f\u5ea6\u5bf9\u4e8e\u8ba1\u7b97\u673a\u7684\u6027\u80fd\u548c\u54cd\u5e94\u65f6\u95f4\u81f3\u5173\u91cd\u8981\u3002 2\uff0e\u6570\u7ec4\u548cPython\u5217\u8868\u4e4b\u95f4\u6709\u4ec0\u4e48\u533a\u522b\uff1f \u89e3\u7b54\uff1a\u6570\u7ec4\u548cPython\u5217\u8868\u4e4b\u95f4\u6709\u51e0\u4e2a\u5173\u952e\u533a\u522b\uff0c\u8fd9\u4e9b\u533a\u522b\u5728\u6570\u636e\u7ed3\u6784\u3001\u529f\u80fd\u548c\u7528\u9014\u4e0a\u5b58\u5728\u5dee\u5f02\uff1a \u6570\u636e\u7c7b\u578b\uff1a \u6570\u7ec4\uff1a\u901a\u5e38\u8981\u6c42\u6240\u6709\u5143\u7d20\u5177\u6709\u76f8\u540c\u7684\u6570\u636e\u7c7b\u578b\u3002\u8fd9\u662f\u56e0\u4e3a\u6570\u7ec4\u5728\u5185\u5b58\u4e2d\u4ee5\u7d27\u51d1\u7684\u65b9\u5f0f\u5b58\u50a8\u6570\u636e\uff0c\u9700\u8981\u77e5\u9053\u6bcf\u4e2a\u5143\u7d20\u7684\u5927\u5c0f\u4ee5\u4fbf\u8fdb\u884c\u968f\u673a\u8bbf\u95ee\u3002 Python\u5217\u8868\uff1aPython\u7684\u5217\u8868\u53ef\u4ee5\u5bb9\u7eb3\u4e0d\u540c\u6570\u636e\u7c7b\u578b\u7684\u5143\u7d20\uff0c\u56e0\u4e3a\u5b83\u4eec\u662f\u52a8\u6001\u7c7b\u578b\u7684\u3002 \u5185\u5b58\u7ba1\u7406\uff1a \u6570\u7ec4\uff1a\u901a\u5e38\u5728\u521b\u5efa\u65f6\u9700\u8981\u6307\u5b9a\u56fa\u5b9a\u5927\u5c0f\uff0c\u56e0\u6b64\u5728\u5185\u5b58\u4e2d\u4f1a\u5206\u914d\u4e00\u5757\u8fde\u7eed\u7684\u7a7a\u95f4\uff0c\u8fd9\u4f7f\u5f97\u6570\u7ec4\u5bf9\u4e8e\u9ad8\u6548\u7684\u968f\u673a\u8bbf\u95ee\u975e\u5e38\u9002\u7528\u3002 Python\u5217\u8868\uff1aPython\u7684\u5217\u8868\u662f\u52a8\u6001\u7684\uff0c\u5b83\u4eec\u53ef\u4ee5\u6839\u636e\u9700\u8981\u81ea\u52a8\u6269\u5c55\u6216\u7f29\u5c0f\u3002\u8fd9\u5bfc\u81f4\u4e86\u4e00\u4e9b\u989d\u5916\u7684\u5185\u5b58\u5f00\u9500\uff0c\u56e0\u4e3a\u5217\u8868\u9700\u8981\u66f4\u591a\u7684\u7a7a\u95f4\u6765\u7ba1\u7406\u5143\u7d20\u7684\u6dfb\u52a0\u548c\u5220\u9664\u3002 \u6027\u80fd\uff1a \u6570\u7ec4\uff1a\u7531\u4e8e\u5185\u5b58\u5e03\u5c40\u8fde\u7eed\uff0c\u56e0\u6b64\u6570\u7ec4\u901a\u5e38\u5728\u8bbf\u95ee\u5143\u7d20\u65f6\u66f4\u5feb\u3002\u6570\u7ec4\u8fd8\u652f\u6301\u66f4\u591a\u7684\u5e95\u5c42\u64cd\u4f5c\uff0c\u5982\u4f4d\u64cd\u4f5c\u3002 Python\u5217\u8868\uff1aPython\u5217\u8868\u66f4\u52a0\u7075\u6d3b\uff0c\u4f46\u5728\u67d0\u4e9b\u60c5\u51b5\u4e0b\u53ef\u80fd\u4f1a\u5bfc\u81f4\u6027\u80fd\u4e0b\u964d\uff0c\u7279\u522b\u662f\u5f53\u6d89\u53ca\u5927\u91cf\u5143\u7d20\u7684\u63d2\u5165\u548c\u5220\u9664\u64cd\u4f5c\u65f6\u3002 \u64cd\u4f5c\u548c\u65b9\u6cd5\uff1a \u6570\u7ec4\uff1a\u901a\u5e38\u63d0\u4f9b\u4e00\u7ec4\u57fa\u672c\u64cd\u4f5c\uff0c\u5982\u8bfb\u53d6\u548c\u5199\u5165\u5143\u7d20\uff0c\u4ee5\u53ca\u4e00\u4e9b\u6570\u5b66\u8fd0\u7b97\uff0c\u5982\u5411\u91cf\u5316\u64cd\u4f5c\u3002 Python\u5217\u8868\uff1aPython\u5217\u8868\u63d0\u4f9b\u4e86\u66f4\u4e30\u5bcc\u7684\u65b9\u6cd5\u548c\u64cd\u4f5c\uff0c\u5305\u62ec\u5143\u7d20\u7684\u63d2\u5165\u3001\u5220\u9664\u3001\u8ffd\u52a0\u3001\u5207\u7247\u3001\u8fde\u63a5\u7b49\u3002 \u8bed\u8a00\u4f9d\u8d56\u6027\uff1a \u6570\u7ec4\uff1a\u6570\u7ec4\u901a\u5e38\u662f\u7f16\u7a0b\u8bed\u8a00\u7684\u4e00\u90e8\u5206\uff0c\u5177\u6709\u56fa\u5b9a\u7684\u8bed\u6cd5\u548c\u8bed\u4e49\u3002 Python\u5217\u8868\uff1aPython\u7684\u5217\u8868\u662fPython\u6807\u51c6\u5e93\u7684\u4e00\u90e8\u5206\uff0c\u4e0ePython\u7684\u52a8\u6001\u7279\u6027\u76f8\u9002\u5e94\u3002 \u9002\u7528\u573a\u666f\uff1a \u6570\u7ec4\uff1a\u9002\u7528\u4e8e\u9700\u8981\u9ad8\u6548\u968f\u673a\u8bbf\u95ee\u7684\u60c5\u51b5\uff0c\u5982\u6570\u503c\u8ba1\u7b97\u3001\u56fe\u50cf\u5904\u7406\u7b49\u3002 Python\u5217\u8868\uff1a\u9002\u7528\u4e8e\u66f4\u5e7f\u6cdb\u7684\u5e94\u7528\uff0c\u7279\u522b\u662f\u5728\u7f16\u5199Python\u4ee3\u7801\u65f6\uff0c\u56e0\u4e3a\u5b83\u4eec\u66f4\u7075\u6d3b\u4e14\u6613\u4e8e\u4f7f\u7528\u3002 \u603b\u4e4b\uff0c\u6570\u7ec4\u548cPython\u5217\u8868\u90fd\u6709\u81ea\u5df1\u7684\u4f18\u52bf\u548c\u9002\u7528\u573a\u666f\u3002\u9009\u62e9\u4f7f\u7528\u54ea\u79cd\u6570\u636e\u7ed3\u6784\u53d6\u51b3\u4e8e\u5177\u4f53\u7684\u9700\u6c42\u548c\u7f16\u7a0b\u8bed\u8a00\u3002\u5728Python\u4e2d\uff0c\u901a\u5e38\u4f1a\u4f18\u5148\u9009\u62e9\u4f7f\u7528\u5217\u8868\uff0c\u56e0\u4e3a\u5b83\u4eec\u66f4\u65b9\u4fbf\uff0c\u800c\u5728\u5176\u4ed6\u7f16\u7a0b\u8bed\u8a00\u4e2d\uff0c\u5982C\u6216Java\uff0c\u6570\u7ec4\u53ef\u80fd\u66f4\u4e3a\u5e38\u89c1\u3002 \u5728\u8fd9\u91cc\u9700\u8981\u8bf4\u660e\u4e00\u4e2a\u6982\u5ff5\u3002\u5728Python\u4e2d\uff0c\u672f\u8bed\"\u6570\u7ec4\"\u901a\u5e38\u6307\u7684\u662fNumPy\u5e93\u4e2d\u7684\u6570\u7ec4\u5bf9\u8c61\uff0c\u800c\"\u5217\u8868\"\u6307\u7684\u662fPython\u7684\u5185\u7f6e\u5217\u8868\uff08list\uff09\u6570\u636e\u7ed3\u6784\u3002\u8fd9\u4e24\u8005\u4e4b\u95f4\u6709\u4ee5\u4e0b\u533a\u522b\uff1a \u6570\u636e\u7c7b\u578b\uff1a \u6570\u7ec4\uff08NumPy\u6570\u7ec4\uff09\uff1aNumPy\u5e93\u63d0\u4f9b\u4e86\u4e00\u4e2a\u591a\u7ef4\u6570\u7ec4\u5bf9\u8c61\uff0c\u5b83\u53ef\u4ee5\u5305\u542b\u76f8\u540c\u6570\u636e\u7c7b\u578b\u7684\u5143\u7d20\uff0c\u5e76\u652f\u6301\u9ad8\u7ea7\u6570\u5b66\u3001\u79d1\u5b66\u548c\u5de5\u7a0b\u8ba1\u7b97\u3002NumPy\u6570\u7ec4\u7684\u5143\u7d20\u7c7b\u578b\u901a\u5e38\u662f\u56fa\u5b9a\u7684\uff0c\u4f8b\u5982\uff0c\u53ef\u4ee5\u662f\u6574\u6570\u3001\u6d6e\u70b9\u6570\u3001\u590d\u6570\u7b49\u3002\u8fd9\u4e9b\u6570\u7ec4\u662f\u9ad8\u6027\u80fd\u7684\uff0c\u652f\u6301\u5411\u91cf\u5316\u64cd\u4f5c\u3002 \u5217\u8868\uff08Python\u5217\u8868\uff09\uff1aPython\u7684\u5185\u7f6e\u5217\u8868\u662f\u4e00\u79cd\u901a\u7528\u7684\u3001\u52a8\u6001\u7c7b\u578b\u7684\u6570\u636e\u7ed3\u6784\uff0c\u53ef\u4ee5\u5305\u542b\u4e0d\u540c\u6570\u636e\u7c7b\u578b\u7684\u5143\u7d20\uff0c\u4f8b\u5982\u6574\u6570\u3001\u6d6e\u70b9\u6570\u3001\u5b57\u7b26\u4e32\u3001\u5bf9\u8c61\u7b49\u3002\u5217\u8868\u53ef\u4ee5\u52a8\u6001\u6269\u5c55\u548c\u7f29\u5c0f\uff0c\u5e76\u63d0\u4f9b\u4e86\u4e30\u5bcc\u7684\u5185\u7f6e\u65b9\u6cd5\u548c\u64cd\u4f5c\u3002 \u6027\u80fd\uff1a \u6570\u7ec4\uff08NumPy\u6570\u7ec4\uff09\uff1aNumPy\u6570\u7ec4\u901a\u5e38\u6bd4Python\u5217\u8868\u66f4\u9ad8\u6548\uff0c\u7279\u522b\u662f\u5728\u8fdb\u884c\u6570\u503c\u8ba1\u7b97\u548c\u79d1\u5b66\u8ba1\u7b97\u65f6\u3002\u5b83\u4eec\u5185\u90e8\u4f7f\u7528\u4e86C\u8bed\u8a00\u5b9e\u73b0\uff0c\u652f\u6301\u5411\u91cf\u5316\u64cd\u4f5c\uff0c\u56e0\u6b64\u5728\u5927\u89c4\u6a21\u6570\u636e\u5904\u7406\u4e2d\u901a\u5e38\u66f4\u5feb\u3002 \u5217\u8868\uff08Python\u5217\u8868\uff09\uff1aPython\u5217\u8868\u867d\u7136\u7075\u6d3b\uff0c\u4f46\u6027\u80fd\u76f8\u5bf9\u8f83\u4f4e\uff0c\u4e0d\u9002\u5408\u5927\u89c4\u6a21\u7684\u6570\u503c\u8ba1\u7b97\u3002\u5b83\u4eec\u7684\u5143\u7d20\u7c7b\u578b\u53ef\u4ee5\u4e0d\u540c\uff0c\u8fd9\u610f\u5473\u7740\u9700\u8981\u66f4\u591a\u7684\u5185\u5b58\u548c\u5904\u7406\u65f6\u95f4\u6765\u7ba1\u7406\u5143\u7d20\u3002 \u5e93\u4f9d\u8d56\uff1a \u6570\u7ec4\uff08NumPy\u6570\u7ec4\uff09\uff1a\u4f7f\u7528NumPy\u5e93\u9700\u8981\u5b89\u88c5NumPy\u6a21\u5757\u3002NumPy\u662fPython\u4e2d\u7528\u4e8e\u6570\u503c\u8ba1\u7b97\u7684\u6838\u5fc3\u5e93\uff0c\u5e7f\u6cdb\u5e94\u7528\u4e8e\u79d1\u5b66\u8ba1\u7b97\u3001\u673a\u5668\u5b66\u4e60\u7b49\u9886\u57df\u3002 \u5217\u8868\uff08Python\u5217\u8868\uff09\uff1aPython\u7684\u5185\u7f6e\u5217\u8868\u662fPython\u6807\u51c6\u5e93\u7684\u4e00\u90e8\u5206\uff0c\u65e0\u9700\u989d\u5916\u5b89\u88c5\u3002 \u529f\u80fd\uff1a \u6570\u7ec4\uff08NumPy\u6570\u7ec4\uff09\uff1aNumPy\u6570\u7ec4\u63d0\u4f9b\u4e86\u8bb8\u591a\u6570\u5b66\u548c\u79d1\u5b66\u8ba1\u7b97\u51fd\u6570\uff0c\u5982\u7ebf\u6027\u4ee3\u6570\u3001\u5085\u7acb\u53f6\u53d8\u6362\u3001\u7edf\u8ba1\u5206\u6790\u7b49\u3002\u5b83\u4eec\u9002\u7528\u4e8e\u5904\u7406\u5927\u91cf\u6570\u503c\u6570\u636e\u3002 \u5217\u8868\uff08Python\u5217\u8868\uff09\uff1aPython\u5217\u8868\u63d0\u4f9b\u4e86\u901a\u7528\u7684\u6570\u636e\u5bb9\u5668\uff0c\u7528\u4e8e\u5b58\u50a8\u548c\u7ba1\u7406\u5404\u79cd\u7c7b\u578b\u7684\u6570\u636e\uff0c\u4f46\u4e0d\u63d0\u4f9b\u4e13\u95e8\u7684\u6570\u5b66\u548c\u79d1\u5b66\u8ba1\u7b97\u529f\u80fd\u3002 \u5982\u679c\u9700\u8981\u8fdb\u884c\u6570\u503c\u8ba1\u7b97\u3001\u79d1\u5b66\u8ba1\u7b97\u6216\u6570\u636e\u5206\u6790\uff0c\u901a\u5e38\u4f1a\u4f7f\u7528NumPy\u6570\u7ec4\u3002\u5982\u679c\u53ea\u662f\u9700\u8981\u4e00\u4e2a\u901a\u7528\u7684\u6570\u636e\u5bb9\u5668\uff0c\u7528\u4e8e\u5b58\u50a8\u548c\u7ba1\u7406\u6570\u636e\uff0c\u90a3\u4e48Python\u5217\u8868\u901a\u5e38\u8db3\u591f\u4e86\u3002 3\uff0e\u8bf7\u8bf4\u660e\u6570\u7ec4\u7684\u7269\u7406\u5c3a\u5bf8\u548c\u903b\u8f91\u5c3a\u5bf8\u4e4b\u95f4\u7684\u533a\u522b\u3002 \u89e3\u7b54\uff1a\"\u7269\u7406\u5c3a\u5bf8\"\u548c\"\u903b\u8f91\u5c3a\u5bf8\"\u901a\u5e38\u7528\u4e8e\u63cf\u8ff0\u6570\u636e\u7ed3\u6784\u4e2d\u7684\u4e24\u4e2a\u4e0d\u540c\u65b9\u9762\uff1a \u7269\u7406\u5c3a\u5bf8\uff08Physical Size\uff09\uff1a \u7269\u7406\u5c3a\u5bf8\u662f\u6307\u6570\u636e\u7ed3\u6784\u5b9e\u9645\u5360\u7528\u7684\u5185\u5b58\u7a7a\u95f4\u6216\u5b58\u50a8\u4ecb\u8d28\u4e2d\u7684\u7a7a\u95f4\u5927\u5c0f\u3002 \u5b83\u8868\u793a\u6570\u636e\u7ed3\u6784\u5728\u8ba1\u7b97\u673a\u5185\u5b58\u6216\u78c1\u76d8\u4e2d\u6240\u5360\u636e\u7684\u5b9e\u9645\u5b57\u8282\u6570\u3002 \u7269\u7406\u5c3a\u5bf8\u4e0e\u6570\u636e\u7ed3\u6784\u7684\u5b58\u50a8\u65b9\u5f0f\u3001\u6570\u636e\u7c7b\u578b\u4ee5\u53ca\u8ba1\u7b97\u673a\u67b6\u6784\u6709\u5173\u3002 \u903b\u8f91\u5c3a\u5bf8\uff08Logical Size\uff09\uff1a \u903b\u8f91\u5c3a\u5bf8\u662f\u6307\u6570\u636e\u7ed3\u6784\u4e2d\u5305\u542b\u7684\u5143\u7d20\u6570\u91cf\u6216\u6570\u636e\u9879\u7684\u6570\u91cf\u3002 \u5b83\u8868\u793a\u6570\u636e\u7ed3\u6784\u5185\u90e8\u7684\u5143\u7d20\u6570\u91cf\u6216\u6570\u636e\u9879\u7684\u4e2a\u6570\uff0c\u4e0d\u6d89\u53ca\u5b9e\u9645\u7684\u5b58\u50a8\u5927\u5c0f\u3002 \u903b\u8f91\u5c3a\u5bf8\u901a\u5e38\u7528\u4e8e\u63cf\u8ff0\u6570\u636e\u7ed3\u6784\u7684\u5bb9\u91cf\u3001\u89c4\u6a21\u6216\u7ef4\u5ea6\u3002 \u8fd9\u4e24\u4e2a\u6982\u5ff5\u4e4b\u95f4\u7684\u5173\u7cfb\u5982\u4e0b\uff1a \u4e00\u4e2a\u6570\u636e\u7ed3\u6784\u53ef\u4ee5\u5177\u6709\u56fa\u5b9a\u7684\u7269\u7406\u5c3a\u5bf8\uff08\u5360\u636e\u56fa\u5b9a\u6570\u91cf\u7684\u5b57\u8282\uff09\uff0c\u4f46\u5176\u903b\u8f91\u5c3a\u5bf8\u53ef\u4ee5\u6839\u636e\u5b9e\u9645\u5b58\u50a8\u7684\u5143\u7d20\u6570\u91cf\u800c\u53d8\u5316\u3002 \u7269\u7406\u5c3a\u5bf8\u901a\u5e38\u662f\u7531\u8ba1\u7b97\u673a\u786c\u4ef6\u548c\u64cd\u4f5c\u7cfb\u7edf\u7ba1\u7406\u7684\uff0c\u800c\u903b\u8f91\u5c3a\u5bf8\u5219\u662f\u7a0b\u5e8f\u5458\u6839\u636e\u6570\u636e\u7ed3\u6784\u7684\u8bbe\u8ba1\u6765\u7ba1\u7406\u7684\u3002 \u4e3e\u4f8b\u6765\u8bf4\uff0c\u4e00\u4e2a\u6574\u6570\u6570\u7ec4\u53ef\u4ee5\u5177\u6709\u56fa\u5b9a\u7684\u7269\u7406\u5c3a\u5bf8\uff0c\u4f8b\u59824\u5b57\u8282/\u6574\u6570\uff0c\u4f46\u5b83\u7684\u903b\u8f91\u5c3a\u5bf8\u53ef\u4ee5\u662f\u6570\u7ec4\u4e2d\u6574\u6570\u7684\u6570\u91cf\uff0c\u53ef\u4ee5\u662f0\u4e2a\u300110\u4e2a\u3001100\u4e2a\u7b49\u7b49\u3002\u56e0\u6b64\uff0c\u903b\u8f91\u5c3a\u5bf8\u63cf\u8ff0\u4e86\u6570\u7ec4\u53ef\u4ee5\u5bb9\u7eb3\u7684\u5143\u7d20\u6570\u91cf\uff0c\u800c\u7269\u7406\u5c3a\u5bf8\u63cf\u8ff0\u4e86\u5b9e\u9645\u5360\u7528\u7684\u5185\u5b58\u7a7a\u95f4\u3002 \u5728\u6570\u636e\u7ed3\u6784\u7684\u8bbe\u8ba1\u548c\u4f7f\u7528\u4e2d\uff0c\u4e86\u89e3\u548c\u7ba1\u7406\u7269\u7406\u5c3a\u5bf8\u548c\u903b\u8f91\u5c3a\u5bf8\u5bf9\u4e8e\u6709\u6548\u5730\u5229\u7528\u8ba1\u7b97\u673a\u8d44\u6e90\u975e\u5e38\u91cd\u8981\u3002 4.2.\u6570\u7ec4\u7684\u64cd\u4f5c \u00b6 Python\u7684 array \u6a21\u5757\u5305\u542b\u4e00\u4e2a\u53eb\u4f5c array \u7684\u7c7b\uff0c\u5b83\u975e\u5e38\u7c7b\u4f3c\u4e8e\u5217\u8868\uff0c\u4f46\u662f\u53ea\u80fd\u5b58\u50a8\u6570\u5b57\u3002\u6211\u4eec\u4f1a\u5b9a\u4e49\u4e00\u4e2a\u53eb\u4f5c Array \u7684\u65b0\u7c7b\uff0c\u4f7f\u7528\u5217\u8868\u4fdd\u5b58\u5143\u7d20\uff0c\u5b58\u50a8\u4efb\u4f55\u7c7b\u578b\u7684\u5143\u7d20\u3002 \u4e0b\u9762\u7684\u793a\u4f8b\u5b9a\u4e49\u4e86\u4e00\u4e2a\u6570\u7ec4\u7c7b Array \uff0c\u4e0b\u9762\u5bf9\u6570\u7ec4\u7684\u4e00\u4e9b\u64cd\u4f5c\u7684\u4ee3\u7801\u5b9e\u73b0\u4e5f\u5df2\u7ecf\u5305\u542b\u5728\u4e0b\u9762\u7684\u4ee3\u7801\u4e2d\u3002\u5176\u4e2d\uff1a \u6570\u7ec4\u9ed8\u8ba4\u7684\u7269\u7406\u5c3a\u5bf8\uff08\u4e5f\u5c31\u662f\u5bb9\u91cf\uff09\u662f5 \u6570\u7ec4\u7684\u521d\u59cb\u903b\u8f91\u5c3a\u5bf8\u662f0 class Array ( object ): \"\"\"\u63cf\u8ff0\u4e00\u4e2a\u6570\u7ec4\u3002\"\"\" def __init__ ( self , capacity , fillValue = None ): \"\"\"Capacity\u662f\u6570\u7ec4\u7684\u5927\u5c0f. fillValue\u4f1a\u586b\u5145\u5728\u6bcf\u4e2a\u5143\u7d20\u4f4d\u7f6e, \u9ed8\u8ba4\u503c\u662fNone\"\"\" # \u521d\u59cb\u5316\u6570\u7ec4\u7684\u903b\u8f91\u5c3a\u5bf8\u548c\u7269\u7406\u5c3a\u5bf8 self . logicalSize = 0 self . capacity = capacity self . fillValue = fillValue #\u521d\u59cb\u5316\u5185\u90e8\u6570\u7ec4\uff0c\u5e76\u586b\u5145\u5143\u7d20\u503c self . items = list () for count in range ( capacity ): self . items . append ( fillValue ) self . logicalSize += 1 # \u521d\u59cb\u5316\u6570\u7ec4\u7269\u7406\u5927\u5c0f\u65f6\uff0c\u4e5f\u540c\u65f6\u521d\u59cb\u5316\u5176\u903b\u8f91\u5927\u5c0f def __len__ ( self ): \"\"\"\u8fd4\u56de\u6570\u7ec4\u7684\u5927\u5c0f\"\"\" return len ( self . items ) def __str__ ( self ): \"\"\"\u5c06\u6570\u7ec4\u5b57\u7b26\u4e32\u5316\u5e76\u8fd4\u56de\"\"\" result = \"\" for index in range ( self . size ()): result += str ( self . items [ index ]) + \" \" return result def size ( self ): \"\"\"\u8fd4\u56de\u6570\u7ec4\u7684\u903b\u8f91\u5c3a\u5bf8\"\"\" return self . logicalSize def __iter__ ( self ): \"\"\"\u652f\u6301for\u5faa\u73af\u5bf9\u6570\u7ec4\u8fdb\u884c\u904d\u5386.\"\"\" print ( \"__iter__ called\" ) # \u4ec5\u7528\u6765\u6d4b\u8bd5\u4f55\u65f6__iter__\u4f1a\u88ab\u8c03\u7528 return iter ( self . items ) def __getitem__ ( self , index ): \"\"\" \u7528\u4e8e\u8bbf\u95ee\u7d22\u5f15\u5904\u7684\u4e0b\u6807\u8fd0\u7b97\u7b26. \u5148\u51b3\u6761\u4ef6: 0 <= index < size() \"\"\" if index < 0 or index >= self . size (): raise IndexError ( \"\u8bfb\u53d6\u64cd\u4f5c\u51fa\u9519, \u6570\u7ec4\u7d22\u5f15\u8d8a\u754c(\u4e0d\u5728\u6570\u7ec4\u903b\u8f91\u8fb9\u754c\u8303\u56f4\u5185)\" ) return self . items [ index ] def __setitem__ ( self , index , newItem ): \"\"\" \u4e0b\u6807\u8fd0\u7b97\u7b26\u7528\u4e8e\u5728\u7d22\u5f15\u5904\u8fdb\u884c\u66ff\u6362. \u5148\u51b3\u6761\u4ef6: 0 <= index < size() \"\"\" if index < 0 or index >= self . size (): raise IndexError ( \"\u66f4\u65b0\u64cd\u4f5c\u51fa\u9519, \u6570\u7ec4\u7d22\u5f15\u8d8a\u754c(\u4e0d\u5728\u6570\u7ec4\u903b\u8f91\u8fb9\u754c\u8303\u56f4\u5185)\" ) self . items [ index ] = newItem def __eq__ ( self , other ): \"\"\" \u4e24\u4e2a\u6570\u7ec4\u76f8\u7b49\u5219\u8fd4\u56deTrue\uff0c\u5426\u5219\u8fd4\u56deFalse \"\"\" # \u5224\u65ad\u4e24\u4e2a\u6570\u7ec4\u662f\u5426\u662f\u540c\u4e00\u4e2a\u5bf9\u8c61\uff0c\u6ce8\u610f\uff0c\u4e0d\u662f\u5b83\u4eec\u7684\u503c\u662f\u5426\u76f8\u7b49 if self is other : return True # \u5224\u65ad\u4e24\u4e2a\u5bf9\u8c61\u7c7b\u578b\u662f\u5426\u4e00\u6837 if type ( self ) != type ( other ): return False # \u5224\u65ad\u4e24\u4e2a\u6570\u7ec4\u5927\u5c0f\u662f\u5426\u4e00\u6837 if self . size () != other . size (): return False # \u6bd4\u8f83\u4e24\u4e2a\u6570\u7ec4\u7684\u503c\u662f\u5426\u4e00\u6837 for index in range ( self . size ()): if self [ index ] != other [ index ]: return False return True def grow ( self ): \"\"\"\u589e\u5927\u6570\u7ec4\u7269\u7406\u5c3a\u5bf8\"\"\" # \u57fa\u4e8e\u5f53\u524d\u7269\u7406\u5c3a\u5bf8\u52a0\u500d\uff0c\u5e76\u5c06fillValue\u8d4b\u503c\u5e95\u5c42\u5217\u8868\u7684\u65b0\u5143\u7d20 for count in range ( len ( self )): self . items . append ( self . fillValue ) def insert ( self , index , newItem ): \"\"\"\u5728\u6570\u7ec4\u6307\u5b9a\u7d22\u5f15\u5904\u63d2\u5165\u65b0\u5143\u7d20\"\"\" # \u5f53\u6570\u7ec4\u7684\u7269\u7406\u5c3a\u5bf8\u548c\u903b\u8f91\u5c3a\u5bf8\u4e00\u6837\u65f6\uff0c\u5219\u589e\u52a0\u7269\u7406\u5c3a\u5bf8 if self . size () == len ( self ): self . grow () # \u63d2\u5165\u65b0\u5143\u7d20 # \u5f53\u63d2\u5165\u4f4d\u7f6e\u5927\u4e8e\u6216\u7b49\u4e8e\u6700\u5927\u903b\u8f91\u4f4d\u7f6e\uff0c\u5219\u5728\u6570\u7ec4\u672b\u7aef\u63d2\u5165\u65b0\u5143\u7d20 # \u5f53\u63d2\u5165\u4f4d\u7f6e\u4ecb\u4e8e\u6570\u7ec4\u903b\u8f91\u4f4d\u7f6e\u7684\u4e2d\u95f4\uff0c\u5219\u4ece\u63d2\u5165\u4f4d\u7f6e\u8d77\u5c06\u5269\u4f59\u6570\u7ec4\u5143\u7d20\u5411\u5c3e\u90e8\u5e73\u79fb\u4e00\u4e2a\u4f4d\u7f6e if index >= self . size (): self . items [ self . size ()] = newItem else : index = max ( index , 0 ) # \u5c06\u6570\u7ec4\u5143\u7d20\u5411\u5c3e\u90e8\u5e73\u79fb\u4e00\u4e2a\u4f4d\u7f6e for i in range ( self . size (), index , - 1 ): self . items [ i ] = self . items [ i - 1 ] # \u63d2\u5165\u65b0\u5143\u7d20 self . items [ index ] = newItem # \u589e\u52a0\u6570\u7ec4\u7684\u903b\u8f91\u5c3a\u5bf8 self . logicalSize += 1 def shrink ( self ): \"\"\" \u51cf\u5c11\u6570\u7ec4\u7684\u7269\u7406\u5c3a\u5bf8 \u5f53: - \u6570\u7ec4\u7684\u903b\u8f91\u5c3a\u5bf8\u5c0f\u4e8e\u6216\u7b49\u4e8e\u5176\u7269\u7406\u5c3a\u5bf8\u76841/4 - \u5e76\u4e14\u5b83\u7684\u7269\u7406\u5c3a\u5bf8\u81f3\u5c11\u662f\u8fd9\u4e2a\u6570\u7ec4\u5efa\u7acb\u65f6\u9ed8\u8ba4\u5bb9\u91cf\u76842\u500d\u65f6 \u5219\u628a\u6570\u7ec4\u7684\u7269\u7406\u5c3a\u5bf8\u51cf\u5c0f\u5230\u539f\u6765\u7684\u4e00\u534a\uff0c\u5e76\u4e14\u4e5f\u4e0d\u4f1a\u5c0f\u4e8e\u5176\u9ed8\u8ba4\u5bb9\u91cf \"\"\" # \u5728\u903b\u8f91\u5c3a\u5bf8\u548c\u7269\u7406\u5c3a\u5bf8\u7684\u4e00\u534a\u4e4b\u95f4\u9009\u62e9\u6700\u5927\u503c\u4f5c\u4e3a\u6570\u7ec4\u6536\u7f29\u540e\u7684\u7269\u7406\u5c3a\u5bf8 newSize = max ( self . capacity , len ( self ) // 2 ) # \u91ca\u653e\u591a\u4f59\u7684\u6570\u7ec4\u7a7a\u95f4 for count in range ( len ( self ) - newSize ): self . items . pop () def pop ( self , index ): \"\"\" \u5220\u9664\u6307\u5b9a\u7d22\u5f15\u503c\u7684\u6570\u7ec4\u5143\u7d20,\u5e76\u8fd4\u56de\u5220\u9664\u7684\u6570\u7ec4\u5143\u7d20\u503c \u5148\u51b3\u6761\u4ef6: 0 <= index < size() \"\"\" if index < 0 or index >= self . size (): raise IndexError ( \"\u5220\u9664\u64cd\u4f5c\u51fa\u9519, \u6570\u7ec4\u7d22\u5f15\u8d8a\u754c(\u4e0d\u5728\u6570\u7ec4\u903b\u8f91\u8fb9\u754c\u8303\u56f4\u5185)\" ) # \u4fdd\u5b58\u5373\u5c06\u88ab\u5220\u9664\u7684\u6570\u7ec4\u5143\u7d20\u503c itemToReturn = self . items [ index ] # \u5c06\u6570\u7ec4\u5143\u7d20\u5411\u5934\u90e8\u5e73\u79fb\u4e00\u4e2a\u4f4d\u7f6e for i in range ( index , self . size () - 1 ): self . items [ i ] = self . items [ i + 1 ] # \u5c06\u6570\u7ec4\u5c3e\u90e8\u7684\u7a7a\u4f59\u4f4d\u8d4b\u503cfillValue\uff0c\u9ed8\u8ba4\u662fNone self . items [ self . size () - 1 ] = self . fillValue # \u51cf\u5c11\u6570\u7ec4\u903b\u8f91\u5c3a\u5bf8 self . logicalSize -= 1 # \u51cf\u5c11\u6570\u7ec4\u7269\u7406\u5c3a\u5bf8 # \u5f53: # - \u6570\u7ec4\u7684\u903b\u8f91\u5c3a\u5bf8\u5c0f\u4e8e\u6216\u7b49\u4e8e\u5176\u7269\u7406\u5c3a\u5bf8\u76841/4 # - \u5e76\u4e14\u5b83\u7684\u7269\u7406\u5c3a\u5bf8\u81f3\u5c11\u662f\u8fd9\u4e2a\u6570\u7ec4\u5efa\u7acb\u65f6\u9ed8\u8ba4\u5bb9\u91cf\u76842\u500d\u65f6 # \u5219\u628a\u6570\u7ec4\u7684\u7269\u7406\u5c3a\u5bf8\u51cf\u5c0f\u5230\u539f\u6765\u7684\u4e00\u534a\uff0c\u5e76\u4e14\u4e5f\u4e0d\u4f1a\u5c0f\u4e8e\u5176\u9ed8\u8ba4\u5bb9\u91cf if self . size () <= len ( self ) // 4 and len ( self ) > self . capacity : self . shrink () # \u8fd4\u56de\u88ab\u5220\u9664\u5143\u7d20\u7684\u503c print ( f 'Item { itemToReturn } was deleted' ) return itemToReturn def main (): # \u521d\u59cb\u5316\u7a7a\u6570\u7ec4 DEFAULT_CAPACITY = 5 my_arr = Array ( DEFAULT_CAPACITY ) # \u6253\u5370\u8f93\u51fa\u6570\u7ec4\u521d\u59cb\u4fe1\u606f print ( \"Physical size:\" , len ( my_arr )) print ( \"Logical size:\" , my_arr . size ()) print ( \"Initial items:\" , my_arr . items ) # \u521d\u59cb\u5316\u6570\u7ec4\u5143\u7d20 print ( '------' ) for item in range ( 4 ): my_arr . insert ( 0 , item ) # \u5728\u6570\u7ec4\u5934\u90e8\u63d2\u5165\uff0c\u6bcf\u63d2\u5165\u4e00\u6b21\u90fd\u9700\u8981\u5411\u540e\u79fb\u52a8\u5df2\u6709\u6570\u7ec4\u5143\u7d20 print ( \"Items(logical):\" , my_arr ) print ( \"Items(physical):\" , my_arr . items ) # \u5728\u6570\u7ec4\u4e2d\u95f4\u63d2\u5165\u65b0\u5143\u7d20 print ( '------' ) my_arr . insert ( 3 , 99 ) print ( \"Items(logical):\" , my_arr ) print ( \"Items(physical):\" , my_arr . items ) # \u5728\u6570\u7ec4\u903b\u8f91\u5c3a\u5bf8\u5916\u63d2\u5165\u65b0\u5143\u7d20 print ( '------' ) my_arr . insert ( 20 , 88 ) print ( \"Items(logical):\" , my_arr ) print ( \"Items(physical):\" , my_arr . items ) # \u5220\u9664\u6570\u7ec4\u5143\u7d20 print ( '------' ) my_arr . pop ( 3 ) my_arr . pop ( 3 ) print ( \"Items(logical):\" , my_arr ) print ( \"Items(physical):\" , my_arr . items ) # \u6e05\u7a7a\u6570\u7ec4\u5143\u7d20 print ( '------' ) for count in range ( my_arr . size ()): my_arr . pop ( 0 ) print ( \"Items(logical):\" , my_arr ) print ( \"Items(physical):\" , my_arr . items ) # \u6570\u7ec4\u5143\u7d20\u5df2\u7ecf\u5168\u90e8\u5220\u9664\uff0c\u903b\u8f91\u5c3a\u5bf8\u4e3a\u96f6\uff0c\u4e0b\u9762\u547d\u4ee4\u8fd4\u56de\u9519\u8bef # print('------') # print(my_arr.pop(0)) # \u6570\u7ec4\u6bd4\u8f83 # \u521d\u59cb\u5316\u6570\u7ec4 print ( '------' ) arr_a = Array ( 5 ) for item in range ( 4 ): arr_a . insert ( 0 , item ) arr_b = arr_a arr_c = Array ( 5 ) for item in range ( 4 ): arr_c . insert ( 0 , item ) arr_d = [] print ( \"arr_a(physical):\" , arr_a . items ) print ( \"arr_b(physical):\" , arr_b . items ) print ( \"arr_c(physical):\" , arr_c . items ) print ( \"arr_d(physical):\" , arr_d ) print ( \"arr_a == arr_b:\" , arr_a == arr_b ) print ( \"arr_a is arr_b:\" , arr_a is arr_b ) print ( \"arr_a == arr_c:\" , arr_a == arr_c ) print ( \"arr_a is arr_c:\" , arr_a is arr_c ) arr_c . insert ( 10 , 10 ) print ( \"arr_a == arr_c:\" , arr_a == arr_c ) arr_c . pop ( arr_c . size () - 1 ) arr_c [ 2 ] = 6 print ( \"arr_a == arr_c:\" , arr_a == arr_c ) print ( \"arr_a == arr_d:\" , arr_a == arr_d ) if __name__ == \"__main__\" : main () # \u8fd0\u884c\u7ed3\u679c # Physical size: 5 # Logical size: 0 # Initial items: [None, None, None, None, None] # ------ # Items(logical): 3 2 1 0 # Items(physical): [3, 2, 1, 0, None] # ------ # Items(logical): 3 2 1 99 0 # Items(physical): [3, 2, 1, 99, 0] # ------ # Items(logical): 3 2 1 99 0 88 # Items(physical): [3, 2, 1, 99, 0, 88, None, None, None, None] # ------ # Item 99 was deleted # Item 0 was deleted # Items(logical): 3 2 1 88 # Items(physical): [3, 2, 1, 88, None, None, None, None, None, None] # ------ # Item 3 was deleted # Item 2 was deleted # Item 1 was deleted # Item 88 was deleted # Items(logical): # Items(physical): [None, None, None, None, None] # ------ # IndexError: \u5220\u9664\u64cd\u4f5c\u51fa\u9519, \u6570\u7ec4\u7d22\u5f15\u8d8a\u754c(\u4e0d\u5728\u6570\u7ec4\u903b\u8f91\u8fb9\u754c\u8303\u56f4\u5185) # ------ # arr_a(physical): [3, 2, 1, 0, None] # arr_b(physical): [3, 2, 1, 0, None] # arr_c(physical): [3, 2, 1, 0, None] # arr_d(physical): [] # arr_a == arr_b: True # arr_a is arr_b: True # arr_a == arr_c: True # arr_a is arr_c: False # arr_a == arr_c: False # Item 10 was deleted # arr_a == arr_c: False # arr_a == arr_d: False 4.2.1.\u589e\u5927\u6570\u7ec4\u7684\u5c3a\u5bf8 \u00b6 \u5f53\u6570\u7ec4\u7684\u903b\u8f91\u5c3a\u5bf8\u7b49\u4e8e\u5b83\u7684\u7269\u7406\u5c3a\u5bf8\u65f6\uff0c\u5982\u679c\u8981\u63d2\u5165\u65b0\u7684\u5143\u7d20\uff0c\u5c31\u9700\u8981\u589e\u5927\u6570\u7ec4\u7684\u7269\u7406\u5c3a\u5bf8\u3002 \u5982\u679c\u9700\u8981\u4e3a\u6570\u7ec4\u63d0\u4f9b\u66f4\u591a\u5185\u5b58\uff0cPython\u7684list\u7c7b\u578b\u4f1a\u5728\u8c03\u7528insert\u6216append\u65b9\u6cd5\u65f6\u6267\u884c\u8fd9\u4e2a\u64cd\u4f5c\u3002 \u8c03\u6574\u6570\u7ec4\u7269\u7406\u5c3a\u5bf8\u7684\u8fc7\u7a0b\u5305\u542b\u5982\u4e0b3\u4e2a\u6b65\u9aa4\u3002 \u521b\u5efa\u4e00\u4e2a\u66f4\u5927\u7684\u65b0\u6570\u7ec4\u3002 \u5c06\u6570\u636e\u4ece\u65e7\u6570\u7ec4\u4e2d\u590d\u5236\u5230\u65b0\u6570\u7ec4\u3002 \u5c06\u6307\u5411\u65e7\u6570\u7ec4\u7684\u53d8\u91cf\u6307\u5411\u65b0\u6570\u7ec4\u5bf9\u8c61\u3002 \u4e0b\u9762\u4ee3\u7801\u5b9e\u73b0\u3002 # \u589e\u5927\u6570\u7ec4\u7269\u7406\u5c3a\u5bf8 if logicalSize == len ( my_array ): temp = Array ( len ( my_array ) + 1 ) # \u521b\u5efa\u4e00\u4e2a\u65b0\u6570\u7ec4 for i in range ( logicalSize ): temp [ i ] = my_array [ i ] # \u4ece\u539f\u6570\u7ec4\u590d\u5236\u5185\u5bb9\u5230\u65b0\u6570\u7ec4 my_array = temp # \u628a\u65b0\u6570\u7ec4\u8d4b\u503c\u7ed9\u539f\u6570\u7ec4 \u5728\u4e0a\u9762\u4ee3\u7801\u4e2d\uff0c\u901a\u8fc7 temp[i] = my_array[i] \u6765\u8c03\u6574\u6570\u7ec4\u5c3a\u5bf8\uff0c\u8fd9\u4e2a\u590d\u5236\u64cd\u4f5c\u7684\u6570\u91cf\u662f\u7ebf\u6027\u589e\u957f\u7684\u3002\u56e0\u6b64\uff0c\u5c06 n \u4e2a\u5143\u7d20\u6dfb\u52a0\u5230\u6570\u7ec4\u91cc\u7684\u603b\u65f6\u95f4\u590d\u6742\u5ea6\u662f 1+2+3...+n \uff0c\u4e5f\u5c31\u662f n(n+1)/2 \uff0c\u56e0\u6b64\u662f O(n^2) \u3002 \u5728\u4e0a\u9762\u7684\u4ee3\u7801\u4e2d\uff0c\u901a\u8fc7 temp = Array(len(my_array) + 1) \u5bf9\u6570\u7ec4\u8fdb\u884c\u52a8\u6001\u6269\u5c55\uff0c\u5bf9\u6027\u80fd\u4f1a\u4ea7\u751f\u4e00\u4e9b\u53ef\u80fd\u7684\u5f71\u54cd\uff1a \u65f6\u95f4\u590d\u6742\u5ea6\uff1a\u52a8\u6001\u6269\u5c55\u6570\u7ec4\u901a\u5e38\u9700\u8981\u590d\u5236\u73b0\u6709\u6570\u636e\u5230\u65b0\u7684\u5185\u5b58\u4f4d\u7f6e\uff0c\u8fd9\u5c06\u6d89\u53ca\u5230\u5143\u7d20\u7684\u590d\u5236\u64cd\u4f5c\u3002\u8fd9\u4e9b\u64cd\u4f5c\u7684\u65f6\u95f4\u590d\u6742\u5ea6\u53d6\u51b3\u4e8e\u6570\u7ec4\u7684\u957f\u5ea6\uff0c\u901a\u5e38\u662f O(n) \uff0c\u5176\u4e2d n \u662f\u6570\u7ec4\u7684\u957f\u5ea6\u3002\u56e0\u6b64\uff0c\u5f53\u6570\u7ec4\u9700\u8981\u6269\u5c55\u65f6\uff0c\u53ef\u80fd\u4f1a\u4ea7\u751f\u4e00\u4e9b\u989d\u5916\u7684\u65f6\u95f4\u5f00\u9500\u3002 \u7a7a\u95f4\u590d\u6742\u5ea6\uff1a\u52a8\u6001\u6269\u5c55\u6570\u7ec4\u4f1a\u5360\u7528\u989d\u5916\u7684\u5185\u5b58\u7a7a\u95f4\uff0c\u56e0\u4e3a\u9700\u8981\u5206\u914d\u65b0\u7684\u5185\u5b58\u5757\u6765\u5bb9\u7eb3\u6269\u5c55\u540e\u7684\u6570\u7ec4\u3002\u8fd9\u53ef\u80fd\u4f1a\u5bfc\u81f4\u5185\u5b58\u788e\u7247\u5316\uff0c\u7279\u522b\u662f\u5728\u9891\u7e41\u6269\u5c55\u548c\u7f29\u5c0f\u6570\u7ec4\u65f6\u3002 \u6269\u5c55\u9891\u7387\uff1a\u6269\u5c55\u6570\u7ec4\u7684\u9891\u7387\u4f1a\u5f71\u54cd\u6027\u80fd\u3002\u5982\u679c\u6570\u7ec4\u9700\u8981\u9891\u7e41\u6269\u5c55\uff0c\u90a3\u4e48\u590d\u5236\u548c\u5185\u5b58\u5206\u914d\u7684\u5f00\u9500\u4f1a\u66f4\u52a0\u663e\u8457\uff0c\u4ece\u800c\u964d\u4f4e\u6027\u80fd\u3002\u56e0\u6b64\uff0c\u5728\u8bbe\u8ba1\u6570\u636e\u7ed3\u6784\u65f6\uff0c\u901a\u5e38\u4f1a\u8003\u8651\u521d\u59cb\u5bb9\u91cf\u548c\u6269\u5c55\u7b56\u7565\uff0c\u4ee5\u51cf\u5c11\u4e0d\u5fc5\u8981\u7684\u6269\u5c55\u6b21\u6570\u3002 Amortized Analysis\uff1a\u4e00\u4e9b\u6570\u636e\u7ed3\u6784\uff0c\u4f8b\u5982Python\u7684\u5217\u8868\uff08list\uff09\uff0c\u91c7\u7528\u644a\u8fd8\u5206\u6790\u6765\u5e73\u644a\u52a8\u6001\u6269\u5c55\u7684\u5f00\u9500\u3002\u8fd9\u610f\u5473\u7740\u867d\u7136\u67d0\u4e9b\u64cd\u4f5c\u53ef\u80fd\u4f1a\u82b1\u8d39 O(n) \u7684\u65f6\u95f4\uff0c\u4f46\u8fd9\u4e9b\u5f00\u9500\u5728\u4e00\u7cfb\u5217\u64cd\u4f5c\u4e2d\u88ab\u5206\u644a\uff0c\u5e73\u5747\u4e0b\u6765\u4ecd\u7136\u4fdd\u6301\u8f83\u4f4e\u7684\u590d\u6742\u5ea6\u3002\u8fd9\u53ef\u4ee5\u5728\u4e00\u5b9a\u7a0b\u5ea6\u4e0a\u7f13\u89e3\u6027\u80fd\u95ee\u9898\u3002 \u52a8\u6001\u6269\u5c55\u6570\u7ec4\u4f1a\u5f15\u5165\u4e00\u4e9b\u6027\u80fd\u5f00\u9500\uff0c\u4f46\u5728\u5b9e\u9645\u5e94\u7528\u4e2d\uff0c\u8fd9\u79cd\u5f00\u9500\u901a\u5e38\u662f\u53ef\u4ee5\u63a5\u53d7\u7684\u3002\u4e3a\u4e86\u4f18\u5316\u6027\u80fd\uff0c\u53ef\u4ee5\u8003\u8651\u4ee5\u4e0b\u51e0\u70b9\u7b56\u7565\uff0c\u9700\u8981\u6839\u636e\u5177\u4f53\u5e94\u7528\u7684\u9700\u6c42\u548c\u6027\u80fd\u8981\u6c42\u6765\u6743\u8861\u8fd9\u4e9b\u56e0\u7d20\uff1a \u9884\u5148\u5206\u914d\u8db3\u591f\u7684\u521d\u59cb\u5bb9\u91cf\uff0c\u4ee5\u51cf\u5c11\u6269\u5c55\u7684\u9891\u7387\u3002 \u4f7f\u7528\u644a\u8fd8\u5206\u6790\u6765\u5e73\u644a\u5f00\u9500\u3002 \u8003\u8651\u4f7f\u7528\u5176\u4ed6\u6570\u636e\u7ed3\u6784\uff0c\u5982\u94fe\u8868\uff0c\u5bf9\u63d2\u5165\u548c\u5220\u9664\u64cd\u4f5c\u7684\u6027\u80fd\u66f4\u52a0\u53cb\u597d\u3002 \u4e0b\u9762\uff0c\u5c1d\u8bd5\u5728\u6bcf\u6b21\u589e\u5927\u6570\u7ec4\u5c3a\u5bf8\u65f6\u628a\u6570\u7ec4\u5c3a\u5bf8\u7ffb\u500d\uff0c\u4ee3\u7801\u5b9e\u73b0\u5982\u4e0b\uff1a # \u589e\u5927\u6570\u7ec4\u7269\u7406\u5c3a\u5bf8 while logicalSize < DEFAULT_CAPACITY * 2 : logicalSize += 1 if logicalSize == len ( my_array ): # \u89e6\u53d1\u6761\u4ef6 temp = Array ( len ( my_array ) + 1 ) # \u521b\u5efa\u4e00\u4e2a\u65b0\u6570\u7ec4 for i in range ( logicalSize ): temp [ i ] = my_array [ i ] # \u4ece\u539f\u6570\u7ec4\u590d\u5236\u5185\u5bb9\u5230\u65b0\u6570\u7ec4 my_array = temp # \u628a\u65b0\u6570\u7ec4\u8d4b\u503c\u7ed9\u539f\u6570\u7ec4 \u5c06\u6570\u7ec4\u5c3a\u5bf8\u7ffb\u500d\u6765\u6269\u5c55\u6570\u7ec4\u7684\u65b9\u5f0f\u662f\u4e00\u79cd\u5e38\u89c1\u7684\u7b56\u7565\uff0c\u901a\u5e38\u7528\u4e8e\u51cf\u5c11\u52a8\u6001\u6570\u7ec4\u7684\u9891\u7e41\u6269\u5c55\u6b21\u6570\uff0c\u4ee5\u63d0\u9ad8\u6027\u80fd\u3002\u8fd9\u79cd\u65b9\u5f0f\u7684\u64cd\u4f5c\u65f6\u95f4\u590d\u6742\u5ea6\u4e3b\u8981\u53d6\u51b3\u4e8e\u6269\u5c55\u64cd\u4f5c\u7684\u9891\u7387\u548c\u5143\u7d20\u7684\u590d\u5236\u6210\u672c\u3002 \u644a\u8fd8\u5206\u6790\uff1a\u5bf9\u4e8e\u5c06\u6570\u7ec4\u5c3a\u5bf8\u7ffb\u500d\u7684\u7b56\u7565\uff0c\u644a\u8fd8\u5206\u6790\u8868\u660e\uff0c\u6bcf\u6b21\u6269\u5c55\u64cd\u4f5c\u7684\u644a\u8fd8\u65f6\u95f4\u590d\u6742\u5ea6\u4ecd\u7136\u662f\u5e38\u6570\u65f6\u95f4\u7684\uff08\u901a\u5e38\u662fO(1)\uff09\uff0c\u8fd9\u610f\u5473\u7740\u5e73\u5747\u4e0b\u6765\uff0c\u6bcf\u6b21\u6269\u5c55\u7684\u5f00\u9500\u662f\u56fa\u5b9a\u7684\uff0c\u800c\u4e0d\u4f1a\u968f\u6570\u7ec4\u7684\u5927\u5c0f\u7ebf\u6027\u589e\u52a0\u3002 \u64cd\u4f5c\u65f6\u95f4\uff1a\u5047\u8bbe\u6570\u7ec4\u9700\u8981\u6269\u5c55\uff0c\u90a3\u4e48\u5c06\u6570\u7ec4\u5c3a\u5bf8\u7ffb\u500d\u9700\u8981\u5206\u914d\u65b0\u7684\u5185\u5b58\u5757\u5e76\u590d\u5236\u73b0\u6709\u5143\u7d20\uff0c\u8fd9\u4e2a\u64cd\u4f5c\u7684\u65f6\u95f4\u590d\u6742\u5ea6\u662fO(n)\uff0c\u5176\u4e2dn\u662f\u6570\u7ec4\u7684\u5f53\u524d\u5927\u5c0f\u3002\u7136\u800c\uff0c\u7531\u4e8e\u6269\u5c55\u64cd\u4f5c\u4e0d\u662f\u6bcf\u6b21\u90fd\u6267\u884c\u7684\uff0c\u800c\u662f\u5f53\u6570\u7ec4\u5df2\u6ee1\u65f6\u624d\u6267\u884c\uff0c\u56e0\u6b64\u53ef\u4ee5\u8ba4\u4e3a\u8fd9\u4e2a\u64cd\u4f5c\u7684\u644a\u8fd8\u65f6\u95f4\u662f\u5e38\u6570\u65f6\u95f4\uff0c\u5373O(1)\u3002 \u7a7a\u95f4\u590d\u6742\u5ea6\uff1a\u5c06\u6570\u7ec4\u5c3a\u5bf8\u7ffb\u500d\u4f1a\u5360\u7528\u989d\u5916\u7684\u5185\u5b58\u7a7a\u95f4\uff0c\u4f46\u968f\u7740\u6570\u7ec4\u7684\u589e\u957f\uff0c\u989d\u5916\u5185\u5b58\u7684\u5360\u7528\u76f8\u5bf9\u4e8e\u6570\u7ec4\u672c\u8eab\u7684\u5927\u5c0f\u6765\u8bf4\u662f\u6709\u9650\u7684\u3002\u901a\u5e38\u60c5\u51b5\u4e0b\uff0c\u8fd9\u79cd\u5360\u7528\u53ef\u4ee5\u63a5\u53d7\u3002 \u603b\u7ed3\uff0c\u5c06\u6570\u7ec4\u5c3a\u5bf8\u7ffb\u500d\u7684\u7b56\u7565\u53ef\u4ee5\u663e\u8457\u51cf\u5c11\u52a8\u6001\u6570\u7ec4\u7684\u6269\u5c55\u6b21\u6570\uff0c\u4ece\u800c\u63d0\u9ad8\u6027\u80fd\u3002\u867d\u7136\u6bcf\u6b21\u6269\u5c55\u64cd\u4f5c\u53ef\u80fd\u4f1a\u82b1\u8d39\u4e00\u4e9b\u65f6\u95f4\u548c\u989d\u5916\u5185\u5b58\uff0c\u4f46\u8fd9\u4e9b\u5f00\u9500\u5728\u4e00\u7cfb\u5217\u64cd\u4f5c\u4e2d\u88ab\u5e73\u644a\uff0c\u5e73\u5747\u4e0b\u6765\u662f\u5e38\u6570\u65f6\u95f4\u3002\u8fd9\u662f\u4e00\u79cd\u9ad8\u6548\u7684\u52a8\u6001\u6570\u7ec4\u5b9e\u73b0\u65b9\u5f0f\uff0c\u5e38\u89c1\u4e8e\u8bb8\u591a\u7f16\u7a0b\u8bed\u8a00\u7684\u6807\u51c6\u5e93\u4e2d\uff0c\u5305\u62ecPython\u7684\u5217\u8868\uff08list\uff09\u3002 \u5728\u589e\u52a0\u6570\u7ec4\u7684\u957f\u5ea6\u65f6\uff0c\u6bcf\u6b21\u589e\u52a0\u4e00\u4e2a\u5185\u5b58\u5355\u5143\uff0c\u4e0e\u6bcf\u6b21\u589e\u5927\u6570\u7ec4\u5c3a\u5bf8\u65f6\u628a\u6570\u7ec4\u5c3a\u5bf8\u7ffb\u500d\u76f8\u6bd4\uff0c\u540e\u8005\u7684\u65b9\u6cd5\u901a\u5e38\u66f4\u9ad8\u6548\u3002 \u6bcf\u6b21\u589e\u52a0\u4e00\u4e2a\u5185\u5b58\u5355\u5143\uff1a\u8fd9\u79cd\u65b9\u5f0f\u5728\u6bcf\u6b21\u6dfb\u52a0\u65b0\u5143\u7d20\u65f6\u90fd\u9700\u8981\u5206\u914d\u989d\u5916\u7684\u5185\u5b58\uff0c\u5bfc\u81f4\u6570\u7ec4\u5c3a\u5bf8\u7684\u589e\u957f\u662f\u7ebf\u6027\u7684\u3002\u5982\u679c\u9891\u7e41\u6dfb\u52a0\u5143\u7d20\uff0c\u8fd9\u5c06\u5bfc\u81f4\u5927\u91cf\u7684\u5185\u5b58\u5206\u914d\u548c\u6570\u636e\u590d\u5236\u64cd\u4f5c\uff0c\u56e0\u6b64\u65f6\u95f4\u590d\u6742\u5ea6\u4f1a\u53d8\u5f97\u76f8\u5bf9\u8f83\u9ad8\u3002 \u6bcf\u6b21\u589e\u5927\u6570\u7ec4\u5c3a\u5bf8\u65f6\u628a\u6570\u7ec4\u5c3a\u5bf8\u7ffb\u500d\uff1a\u8fd9\u662f\u4e00\u79cd\u66f4\u9ad8\u6548\u7684\u7b56\u7565\u3002\u5728\u8fd9\u79cd\u65b9\u5f0f\u4e0b\uff0c\u6bcf\u6b21\u6269\u5c55\u64cd\u4f5c\u90fd\u4f1a\u589e\u52a0\u6570\u7ec4\u7684\u5c3a\u5bf8\uff0c\u4f46\u589e\u5e45\u662f\u6307\u6570\u7ea7\u7684\uff0c\u800c\u4e0d\u662f\u7ebf\u6027\u7684\u3002\u8fd9\u610f\u5473\u7740\u968f\u7740\u6570\u7ec4\u7684\u589e\u957f\uff0c\u6269\u5c55\u64cd\u4f5c\u7684\u9891\u7387\u4f1a\u51cf\u5c11\uff0c\u56e0\u4e3a\u6570\u7ec4\u80fd\u591f\u5bb9\u7eb3\u66f4\u591a\u5143\u7d20\u3002\u8fd9\u6837\uff0c\u867d\u7136\u6bcf\u6b21\u6269\u5c55\u64cd\u4f5c\u9700\u8981\u590d\u5236\u66f4\u591a\u7684\u5143\u7d20\uff0c\u4f46\u5b83\u4eec\u7684\u644a\u8fd8\u65f6\u95f4\u590d\u6742\u5ea6\u4ecd\u7136\u662f\u5e38\u6570\u65f6\u95f4\uff0c\u56e0\u4e3a\u5b83\u4eec\u4e0d\u662f\u6bcf\u6b21\u90fd\u6267\u884c\u7684\u3002 \u603b\u7ed3\uff0c\u5c06\u6570\u7ec4\u5c3a\u5bf8\u7ffb\u500d\u7684\u7b56\u7565\u901a\u5e38\u66f4\u9ad8\u6548\uff0c\u56e0\u4e3a\u5b83\u53ef\u4ee5\u51cf\u5c11\u9891\u7e41\u7684\u5185\u5b58\u5206\u914d\u548c\u590d\u5236\u64cd\u4f5c\uff0c\u964d\u4f4e\u4e86\u65f6\u95f4\u590d\u6742\u5ea6\u3002\u8fd9\u662f\u8bb8\u591a\u52a8\u6001\u6570\u7ec4\u5b9e\u73b0\u7684\u5e38\u89c1\u505a\u6cd5\uff0c\u5305\u62ecPython\u7684\u5217\u8868\uff08list\uff09\u3002 \u5728 Array \u7c7b\u5b9e\u73b0\u4e2d\uff0c\u662f\u901a\u8fc7\u4e0b\u9762\u4ee3\u7801\u6bb5\u5b9e\u73b0\u7684\u6570\u7ec4\u7269\u7406\u5c3a\u5bf8\u589e\u52a0\u7684\uff0c\u5373\u5c06\u6570\u7ec4\u5c3a\u5bf8\u7ffb\u500d\u3002 def grow ( self ): \"\"\"\u589e\u5927\u6570\u7ec4\u7269\u7406\u5c3a\u5bf8\"\"\" # \u57fa\u4e8e\u5f53\u524d\u7269\u7406\u5c3a\u5bf8\u52a0\u500d\uff0c\u5e76\u5c06fillValue\u8d4b\u503c\u5e95\u5c42\u5217\u8868\u7684\u65b0\u5143\u7d20 for count in range ( len ( self )): self . items . append ( self . fillValue ) 4.2.2.\u51cf\u5c0f\u6570\u7ec4\u7684\u5c3a\u5bf8 \u00b6 \u5982\u679c\u51cf\u5c0f\u6570\u7ec4\u7684\u903b\u8f91\u5c3a\u5bf8\uff0c\u5c31\u4f1a\u6d6a\u8d39\u76f8\u5e94\u7684\u5185\u5b58\u5355\u5143\u3002\u56e0\u6b64\uff0c\u5f53\u5220\u9664\u67d0\u4e00\u4e2a\u5143\u7d20\uff0c\u5982\u679c\u672a\u4f7f\u7528\u7684\u5185\u5b58\u5355\u5143\u6570\u8fbe\u5230\u6216\u8d85\u8fc7\u4e86\u67d0\u4e2a\u9608\u503c\uff08\u5982\u6570\u7ec4\u7269\u7406\u5c3a\u5bf8\u7684\u00be\uff09\u65f6\uff0c\u5219\u5e94\u8be5\u51cf\u5c0f\u7269\u7406\u5c3a\u5bf8\u4e86\u3002\u5982\u679c\u6d6a\u8d39\u7684\u5185\u5b58\u8d85\u8fc7\u7279\u5b9a\u9608\u503c\uff0c\u90a3\u4e48Python\u7684list\u7c7b\u578b\u4f1a\u5728\u8c03\u7528 pop \u65b9\u6cd5\u65f6\u6267\u884c\u51cf\u5c0f\u6570\u7ec4\u7269\u7406\u5c3a\u5bf8\u7684\u64cd\u4f5c\u3002 \u51cf\u5c0f\u6570\u7ec4\u5c3a\u5bf8\u7684\u8fc7\u7a0b\u4e0e\u589e\u5927\u6570\u7ec4\u5c3a\u5bf8\u7684\u8fc7\u7a0b\u76f8\u53cd\uff0c\u6b65\u9aa4\u5982\u4e0b\uff1a \u521b\u5efa\u4e00\u4e2a\u66f4\u5c0f\u7684\u65b0\u6570\u7ec4\u3002 \u5c06\u6570\u636e\u4ece\u65e7\u6570\u7ec4\u4e2d\u590d\u5236\u5230\u65b0\u6570\u7ec4\u3002 \u5c06\u6307\u5411\u65e7\u6570\u7ec4\u7684\u53d8\u91cf\u6307\u5411\u65b0\u6570\u7ec4\u5bf9\u8c61\u3002 \u4e0b\u9762\u7684\u4ee3\u7801\u5b9e\u73b0\u4e86\u51cf\u5c0f\u6570\u7ec4\u5c3a\u5bf8\u3002 \u5f53\u6570\u7ec4\u7684\u903b\u8f91\u5c3a\u5bf8\u5c0f\u4e8e\u6216\u7b49\u4e8e\u5176\u7269\u7406\u5c3a\u5bf8\u7684\u00bc\uff0c\u5e76\u4e14\u5b83\u7684\u7269\u7406\u5c3a\u5bf8\u81f3\u5c11\u662f\u8fd9\u4e2a\u6570\u7ec4\u5efa\u7acb\u65f6\u9ed8\u8ba4\u5bb9\u91cf\u76842\u500d\u65f6\uff0c\u5219\u4e0b\u9762\u7684\u7b97\u6cd5\u628a\u6570\u7ec4\u7684\u7269\u7406\u5c3a\u5bf8\u51cf\u5c0f\u5230\u539f\u6765\u7684\u4e00\u534a\uff0c\u5e76\u4e14\u4e5f\u4e0d\u4f1a\u5c0f\u4e8e\u5176\u9ed8\u8ba4\u5bb9\u91cf\u3002 # \u51cf\u5c0f\u6570\u7ec4\u7269\u7406\u5c3a\u5bf8 while logicalSize > len ( my_array ) // 4 : logicalSize -= 1 if logicalSize <= len ( my_array ) // 4 and len ( my_array ) >= DEFAULT_CAPACITY * 2 : # \u89e6\u53d1\u6761\u4ef6 temp = Array ( len ( my_array ) // 2 ) # \u521b\u5efa\u4e00\u4e2a\u65b0\u6570\u7ec4 for i in range ( logicalSize ): temp [ i ] = my_array [ i ] # \u4ece\u539f\u6570\u7ec4\u590d\u5236\u5185\u5bb9\u5230\u65b0\u6570\u7ec4 my_array = temp # \u628a\u65b0\u6570\u7ec4\u8d4b\u503c\u7ed9\u539f\u6570\u7ec4 \u6309\u7167\u4e0a\u9762\u7b97\u6cd5\u51cf\u5c11\u6570\u7ec4\u7684\u5c3a\u5bf8\uff0c\u6211\u4eec\u53ef\u4ee5\u5206\u6790\u5176\u65f6\u95f4\u548c\u7a7a\u95f4\u590d\u6742\u5ea6\u5982\u4e0b\uff1a \u65f6\u95f4\u590d\u6742\u5ea6\uff1a\u4e3b\u8981\u6d89\u53ca\u4e24\u4e2a\u64cd\u4f5c\uff1a \u521b\u5efa\u65b0\u6570\u7ec4\u5e76\u5c06\u5143\u7d20\u4ece\u65e7\u6570\u7ec4\u590d\u5236\u5230\u65b0\u6570\u7ec4\uff1b \u5c06\u65e7\u6570\u7ec4\u5f15\u7528\u66f4\u6539\u4e3a\u65b0\u6570\u7ec4\u3002 \u590d\u5236\u64cd\u4f5c\u7684\u65f6\u95f4\u590d\u6742\u5ea6\u53d6\u51b3\u4e8e\u6570\u7ec4\u7684\u7269\u7406\u5c3a\u5bf8\uff0c\u53ef\u4ee5\u8868\u793a\u4e3a O(n) \uff0c\u5176\u4e2d n \u662f\u6570\u7ec4\u7684\u5f53\u524d\u7269\u7406\u5c3a\u5bf8\u3002\u5f15\u7528\u66f4\u6539\u662f\u4e00\u4e2a\u5e38\u6570\u65f6\u95f4\u64cd\u4f5c\uff0c\u4e0d\u5f71\u54cd\u65f6\u95f4\u590d\u6742\u5ea6\u3002\u6240\u4ee5\uff0c\u6574\u4f53\u7684\u65f6\u95f4\u590d\u6742\u5ea6\u662f O(n) \u3002 \u7a7a\u95f4\u590d\u6742\u5ea6\uff1a\u7a7a\u95f4\u590d\u6742\u5ea6\u4e5f\u6d89\u53ca\u4e24\u4e2a\u65b9\u9762\uff1a \u521b\u5efa\u65b0\u6570\u7ec4\u7684\u5185\u5b58\u6d88\u8017\uff0c\u5176\u7a7a\u95f4\u590d\u6742\u5ea6\u662fO(N)\uff1b \u5f15\u7528\u66f4\u6539\u6240\u9700\u7684\u5e38\u6570\u989d\u5916\u7a7a\u95f4\uff0c\u901a\u5e38\u5ffd\u7565\u4e0d\u8ba1\u3002 \u6240\u4ee5\uff0c\u603b\u7684\u7a7a\u95f4\u590d\u6742\u5ea6\u662f O(n) \u3002 \u8fd9\u4e2a\u7b97\u6cd5\u7b56\u7565\u4f1a\u5728\u9002\u5f53\u7684\u65f6\u5019\u51cf\u5c0f\u6570\u7ec4\u7684\u7269\u7406\u5c3a\u5bf8\uff0c\u4ee5\u51cf\u5c11\u5185\u5b58\u5360\u7528\uff0c\u4f46\u4ecd\u7136\u4fdd\u6301\u7740\u6570\u7ec4\u7684\u52a8\u6001\u6027\u3002\u65f6\u95f4\u590d\u6742\u5ea6\u548c\u7a7a\u95f4\u590d\u6742\u5ea6\u90fd\u4e0e\u5f53\u524d\u6570\u7ec4\u7684\u7269\u7406\u5c3a\u5bf8\u6210\u7ebf\u6027\u5173\u7cfb\uff0c\u56e0\u6b64\u662f\u7ebf\u6027\u7684\uff0c\u8fd9\u662f\u4e00\u79cd\u6709\u6548\u7684\u7b56\u7565\u6765\u4f18\u5316\u5185\u5b58\u4f7f\u7528\u3002\u540c\u65f6\uff0c\u4fdd\u7559\u4e86\u4e00\u5b9a\u7684\u5197\u4f59\u7a7a\u95f4\uff0c\u4ee5\u907f\u514d\u9891\u7e41\u5730\u6269\u5c55\u548c\u7f29\u5c0f\u6570\u7ec4\uff0c\u4ece\u800c\u63d0\u9ad8\u4e86\u6027\u80fd\u3002 \u4e0b\u9762\u662f\u5728 Array \u7c7b\u4e2d\u5b9e\u73b0\u51cf\u5c0f\u6570\u7ec4\u7684\u7269\u7406\u5c3a\u5bf8\u7684\u4ee3\u7801\u3002 def shrink ( self ): \"\"\" \u51cf\u5c11\u6570\u7ec4\u7684\u7269\u7406\u5c3a\u5bf8 \u5f53: - \u6570\u7ec4\u7684\u903b\u8f91\u5c3a\u5bf8\u5c0f\u4e8e\u6216\u7b49\u4e8e\u5176\u7269\u7406\u5c3a\u5bf8\u76841/4 - \u5e76\u4e14\u5b83\u7684\u7269\u7406\u5c3a\u5bf8\u81f3\u5c11\u662f\u8fd9\u4e2a\u6570\u7ec4\u5efa\u7acb\u65f6\u9ed8\u8ba4\u5bb9\u91cf\u76842\u500d\u65f6 \u5219\u628a\u6570\u7ec4\u7684\u7269\u7406\u5c3a\u5bf8\u51cf\u5c0f\u5230\u539f\u6765\u7684\u4e00\u534a\uff0c\u5e76\u4e14\u4e5f\u4e0d\u4f1a\u5c0f\u4e8e\u5176\u9ed8\u8ba4\u5bb9\u91cf \"\"\" # \u5728\u903b\u8f91\u5c3a\u5bf8\u548c\u7269\u7406\u5c3a\u5bf8\u7684\u4e00\u534a\u4e4b\u95f4\u9009\u62e9\u6700\u5927\u503c\u4f5c\u4e3a\u6570\u7ec4\u6536\u7f29\u540e\u7684\u7269\u7406\u5c3a\u5bf8 newSize = max ( self . capacity , len ( self ) // 2 ) # \u91ca\u653e\u591a\u4f59\u7684\u6570\u7ec4\u7a7a\u95f4 for count in range ( len ( self ) - newSize ): self . items . pop () 4.2.3.\u5c06\u5143\u7d20\u63d2\u5165\u589e\u5927\u7684\u6570\u7ec4 \u00b6 \u628a\u5143\u7d20\u63d2\u5165\u6570\u7ec4\u4e2d\u548c\u66ff\u6362\u6570\u7ec4\u91cc\u7684\u5143\u7d20\u662f\u4e0d\u4e00\u6837\u7684\u3002 \u66ff\u6362\u6570\u7ec4\u5143\u7d20\u65f6\uff0c\u5143\u7d20\u5df2\u5728\u4e00\u4e2a\u7ed9\u5b9a\u7684\u7d22\u5f15\u4f4d\u7f6e\uff0c\u5bf9\u8fd9\u4e2a\u4f4d\u7f6e\u8fdb\u884c\u7b80\u5355\u590d\u5236\u5373\u53ef\uff0c\u6570\u7ec4\u7684\u903b\u8f91\u5c3a\u5bf8\u5e76\u4e0d\u4f1a\u6539\u53d8\u3002 \u63d2\u5165\u6570\u7ec4\u5143\u7d20\u65f6\uff0c\u9700\u8981\u5b8c\u6210\u4e0b\u97624\u4e2a\u6b65\u9aa4\uff1a \u5728\u63d2\u5165\u5143\u7d20\u4e4b\u524d\u5148\u68c0\u67e5\u53ef\u4ee5\u4f7f\u7528\u7684\u7a7a\u95f4\uff0c\u6839\u636e\u9700\u8981\u6765\u589e\u5927\u6570\u7ec4\u7684\u7269\u7406\u5c3a\u5bf8\u3002 \u5c06\u6570\u7ec4\u91cc\u4ece\u903b\u8f91\u7ed3\u5c3e\u5230\u76ee\u6807\u7d22\u5f15\u7684\u6240\u6709\u5143\u7d20\u5411\u540e\u79fb\u52a8\u3002\u8fd9\u4e2a\u8fc7\u7a0b\u4f1a\u5728\u76ee\u6807\u7d22\u5f15\u4f4d\u7f6e\u5904\u4e3a\u65b0\u5143\u7d20\u7559\u4e0b\u4e00\u4e2a\u7a7a\u683c\u3002 \u5c06\u65b0\u5143\u7d20\u5206\u914d\u5230\u76ee\u6807\u7d22\u5f15\u4f4d\u7f6e\u3002 \u5c06\u903b\u8f91\u5c3a\u5bf8\u52a01\u3002 \u5b9e\u73b0\u7b97\u6cd5\uff1a # \u5f53\u6570\u7ec4\u7684\u7269\u7406\u5c3a\u5bf8\u548c\u903b\u8f91\u5c3a\u5bf8\u4e00\u6837\u65f6\uff0c\u5219\u589e\u52a0\u7269\u7406\u5c3a\u5bf8 # \u5c06\u6570\u7ec4\u5143\u7d20\u5411\u5c3e\u90e8\u5e73\u79fb\u4e00\u4e2a\u4f4d\u7f6e for i in range ( logicalSize , targetIndex , - 1 ): my_array [ i ] = my_array [ i - 1 ] # \u63d2\u5165\u65b0\u5143\u7d20\uff0c\u589e\u52a0\u6570\u7ec4\u7684\u903b\u8f91\u5c3a\u5bf8 my_array [ targetIndex ] = newItem logicalSize += 1 \u4e0b\u9762\u662f Array \u7c7b\u4e2d\u5b9e\u73b0\u63d2\u5165\u5143\u7d20\u7684\u65b9\u6cd5\u3002 def insert ( self , index , newItem ): \"\"\"\u5728\u6570\u7ec4\u6307\u5b9a\u7d22\u5f15\u5904\u63d2\u5165\u65b0\u5143\u7d20\"\"\" # \u5f53\u6570\u7ec4\u7684\u7269\u7406\u5c3a\u5bf8\u548c\u903b\u8f91\u5c3a\u5bf8\u4e00\u6837\u65f6\uff0c\u5219\u589e\u52a0\u7269\u7406\u5c3a\u5bf8 if self . size () == len ( self ): self . grow () # \u63d2\u5165\u65b0\u5143\u7d20 # \u5f53\u63d2\u5165\u4f4d\u7f6e\u5927\u4e8e\u6216\u7b49\u4e8e\u6700\u5927\u903b\u8f91\u4f4d\u7f6e\uff0c\u5219\u5728\u6570\u7ec4\u672b\u7aef\u63d2\u5165\u65b0\u5143\u7d20 # \u5f53\u63d2\u5165\u4f4d\u7f6e\u4ecb\u4e8e\u6570\u7ec4\u903b\u8f91\u4f4d\u7f6e\u7684\u4e2d\u95f4\uff0c\u5219\u4ece\u63d2\u5165\u4f4d\u7f6e\u8d77\u5c06\u5269\u4f59\u6570\u7ec4\u5143\u7d20\u5411\u5c3e\u90e8\u5e73\u79fb\u4e00\u4e2a\u4f4d\u7f6e if index >= self . size (): self . items [ self . size ()] = newItem else : index = max ( index , 0 ) # \u5c06\u6570\u7ec4\u5143\u7d20\u5411\u5c3e\u90e8\u5e73\u79fb\u4e00\u4e2a\u4f4d\u7f6e for i in range ( self . size (), index , - 1 ): self . items [ i ] = self . items [ i - 1 ] # \u63d2\u5165\u65b0\u5143\u7d20 self . items [ index ] = newItem # \u589e\u52a0\u6570\u7ec4\u7684\u903b\u8f91\u5c3a\u5bf8 self . logicalSize += 1 4.2.4.\u4ece\u6570\u7ec4\u91cc\u5220\u9664\u5143\u7d20 \u00b6 \u4ece\u6570\u7ec4\u91cc\u5220\u9664\u5143\u7d20\u7684\u6b65\u9aa4\u5982\u4e0b\uff0c\u548c\u63d2\u5165\u64cd\u4f5c\u4e00\u6837\uff0c\u5143\u7d20\u7684\u79fb\u52a8\u987a\u5e8f\u975e\u5e38\u91cd\u8981\u3002 \u5c06\u6570\u7ec4\u91cc\u4ece\u76ee\u6807\u7d22\u5f15\u5230\u903b\u8f91\u7ed3\u5c3e\u7684\u6240\u6709\u5143\u7d20\u5411\u524d\u79fb\u52a8\uff0c\u628a\u6bcf\u4e2a\u5143\u7d20\u90fd\u590d\u5236\u5230\u5b83\u524d\u9762\u7684\u90a3\u4e2a\u5185\u5b58\u5355\u5143\u91cc\u3002\u8fd9\u4e2a\u8fc7\u7a0b\u4f1a\u5173\u95ed\u5220\u9664\u76ee\u6807\u7d22\u5f15\u4f4d\u7f6e\u4e2d\u7684\u5143\u7d20\u6240\u7559\u4e0b\u7684\u7a7a\u683c\u3002 \u5c06\u903b\u8f91\u5c3a\u5bf8\u51cf1\u3002 \u68c0\u67e5\u662f\u5426\u5b58\u5728\u5185\u5b58\u7a7a\u95f4\u7684\u6d6a\u8d39\uff0c\u5e76\u6839\u636e\u9700\u8981\u51cf\u5c0f\u6570\u7ec4\u7684\u7269\u7406\u5c3a\u5bf8\u3002 \u5728\u5e73\u5747\u60c5\u51b5\u4e0b\uff0c\u79fb\u52a8\u5143\u7d20\u7684\u65f6\u95f4\u590d\u6742\u5ea6\u662f\u7ebf\u6027\u7684\uff0c\u56e0\u6b64\u5220\u9664\u64cd\u4f5c\u7684\u65f6\u95f4\u590d\u6742\u5ea6\u4e5f\u662f\u7ebf\u6027\u7684\u3002 \u4e0b\u9762\u662f\u5b9e\u73b0\u5220\u9664\u64cd\u4f5c\u7684\u4ee3\u7801\u3002 # \u5c06\u6570\u7ec4\u5143\u7d20\u5411\u5934\u90e8\u5e73\u79fb\u4e00\u4e2a\u4f4d\u7f6e for i in range ( targetIndex , logicalSize - 1 ): my_array [ i ] = my_arraya [ i + 1 ] # \u51cf\u5c11\u6570\u7ec4\u903b\u8f91\u5c3a\u5bf8 logicalSize -= 1 # \u5982\u679c\u9700\u8981\uff0c\u5219\u51cf\u5c11\u6570\u7ec4\u7269\u7406\u5c3a\u5bf8 \u4e0b\u9762\u662f Array \u7c7b\u4e2d\u5b9e\u73b0\u5220\u9664\u5143\u7d20\u7684\u65b9\u6cd5\u3002 def pop ( self , index ): \"\"\" \u5220\u9664\u6307\u5b9a\u7d22\u5f15\u503c\u7684\u6570\u7ec4\u5143\u7d20,\u5e76\u8fd4\u56de\u5220\u9664\u7684\u6570\u7ec4\u5143\u7d20\u503c \u5148\u51b3\u6761\u4ef6: 0 <= index < size() \"\"\" if index < 0 or index >= self . size (): raise IndexError ( \"\u5220\u9664\u64cd\u4f5c\u51fa\u9519, \u6570\u7ec4\u7d22\u5f15\u8d8a\u754c(\u4e0d\u5728\u6570\u7ec4\u903b\u8f91\u8fb9\u754c\u8303\u56f4\u5185)\" ) # \u4fdd\u5b58\u5373\u5c06\u88ab\u5220\u9664\u7684\u6570\u7ec4\u5143\u7d20\u503c itemToReturn = self . items [ index ] # \u5c06\u6570\u7ec4\u5143\u7d20\u5411\u5934\u90e8\u5e73\u79fb\u4e00\u4e2a\u4f4d\u7f6e for i in range ( index , self . size () - 1 ): self . items [ i ] = self . items [ i + 1 ] # \u5c06\u6570\u7ec4\u5c3e\u90e8\u7684\u7a7a\u4f59\u4f4d\u8d4b\u503cfillValue\uff0c\u9ed8\u8ba4\u662fNone self . items [ self . size () - 1 ] = self . fillValue # \u51cf\u5c11\u6570\u7ec4\u903b\u8f91\u5c3a\u5bf8 self . logicalSize -= 1 # \u51cf\u5c11\u6570\u7ec4\u7269\u7406\u5c3a\u5bf8 # \u5f53: # - \u6570\u7ec4\u7684\u903b\u8f91\u5c3a\u5bf8\u5c0f\u4e8e\u6216\u7b49\u4e8e\u5176\u7269\u7406\u5c3a\u5bf8\u76841/4 # - \u5e76\u4e14\u5b83\u7684\u7269\u7406\u5c3a\u5bf8\u81f3\u5c11\u662f\u8fd9\u4e2a\u6570\u7ec4\u5efa\u7acb\u65f6\u9ed8\u8ba4\u5bb9\u91cf\u76842\u500d\u65f6 # \u5219\u628a\u6570\u7ec4\u7684\u7269\u7406\u5c3a\u5bf8\u51cf\u5c0f\u5230\u539f\u6765\u7684\u4e00\u534a\uff0c\u5e76\u4e14\u4e5f\u4e0d\u4f1a\u5c0f\u4e8e\u5176\u9ed8\u8ba4\u5bb9\u91cf if self . size () <= len ( self ) // 4 and len ( self ) > self . capacity : self . shrink () # \u8fd4\u56de\u88ab\u5220\u9664\u5143\u7d20\u7684\u503c print ( f 'Item { itemToReturn } was deleted' ) return itemToReturn 4.2.5.\u590d\u6742\u5ea6\u7684\u6743\u8861\uff1a\u65f6\u95f4\u3001\u7a7a\u95f4\u548c\u6570\u7ec4 \u00b6 \u4e0b\u8868\u5217\u51fa\u4e86\u6240\u6709\u6570\u7ec4\u64cd\u4f5c\u7684\u8fd0\u884c\u65f6\u590d\u6742\u5ea6\uff0c\u5305\u62ec\u5728\u6570\u7ec4\u7684\u903b\u8f91\u7ed3\u5c3e\u5904\u63d2\u5165\u548c\u5220\u9664\u5143\u7d20\u3002 \u6570\u7ec4\u63d0\u4f9b\u4e86\u5bf9\u5df2\u7ecf\u5b58\u5728\u7684\u5143\u7d20\u8fdb\u884c\u5feb\u901f\u8bbf\u95ee\u7684\u529f\u80fd\uff0c\u4ee5\u53ca\u5728\u903b\u8f91\u7ed3\u5c3e\u5904\u5feb\u901f\u63d2\u5165\u548c\u5220\u9664\u7684\u529f\u80fd\u3002 \u5728\u4efb\u610f\u4f4d\u7f6e\u5904\u8fdb\u884c\u63d2\u5165\u548c\u5220\u9664\u64cd\u4f5c\u7684\u901f\u5ea6\u5219\u4f1a\u6162\u4e0a\u4e00\u4e2a\u6570\u91cf\u7ea7\u3002 \u8c03\u6574\u6570\u7ec4\u7684\u5c3a\u5bf8\u4e5f\u9700\u8981\u7ebf\u6027\u65f6\u95f4\uff0c\u4f46\u662f\u56e0\u4e3a\u8fd9\u4e2a\u64cd\u4f5c\u4f1a\u628a\u6570\u7ec4\u5c3a\u5bf8\u52a0\u500d\u6216\u51cf\u534a\uff0c\u6240\u4ee5\u53ef\u4ee5\u6700\u5927\u9650\u5ea6\u5730\u51cf\u5c11\u9700\u8981\u6267\u884c\u7684\u6b21\u6570\u3002 \u7531\u4e8e\u53ef\u80fd\u4f1a\u8c03\u6574\u6570\u7ec4\u7684\u5c3a\u5bf8\uff0c\u56e0\u6b64\u63d2\u5165\u548c\u5220\u9664\u64cd\u4f5c\u5728\u4f7f\u7528\u5185\u5b58\u7684\u65f6\u5019\u4f1a\u6709 O(n) \u7684\u590d\u6742\u5ea6\uff0c\u90a3\u4e48\u8fd9\u5c31\u662f\u6700\u574f\u60c5\u51b5\u4e0b\u7684\u6027\u80fd\uff1b\u800c\u5728\u5e73\u5747\u60c5\u51b5\u4e0b\uff0c\u8fd9\u4e9b\u64cd\u4f5c\u7684\u5185\u5b58\u4f7f\u7528\u60c5\u51b5\u4ecd\u7136\u4e3a O(1) \u3002 \u64cd\u4f5c \u8fd0\u884c\u65f6\u590d\u6742\u5ea6 \u5728\u4f4d\u7f6ei\u5904\u8bbf\u95ee O(1)\uff0c\u6700\u597d\u548c\u6700\u574f\u60c5\u51b5\u4e0b \u5728\u4f4d\u7f6ei\u5904\u66ff\u6362 O(1)\uff0c\u6700\u597d\u548c\u6700\u574f\u60c5\u51b5\u4e0b \u5728\u903b\u8f91\u7ed3\u5c3e\u5904\u63d2\u5165 O(1)\uff0c\u5e73\u5747\u60c5\u51b5\u4e0b \u5728\u4f4d\u7f6ei\u5904\u63d2\u5165 O(n)\uff0c\u5e73\u5747\u60c5\u51b5\u4e0b \u5728\u4f4d\u7f6ei\u5904\u5220\u9664 O(n)\uff0c\u5e73\u5747\u60c5\u51b5\u4e0b \u589e\u5927\u5bb9\u91cf O(n)\uff0c\u6700\u597d\u548c\u6700\u574f\u60c5\u51b5\u4e0b \u51cf\u5c0f\u5bb9\u91cf O(n)\uff0c\u6700\u597d\u548c\u6700\u574f\u60c5\u51b5\u4e0b \u5728\u903b\u8f91\u7ed3\u5c3e\u5904\u5220\u9664 O(1)\uff0c\u5e73\u5747\u60c5\u51b5\u4e0b \u4f7f\u7528\u6570\u7ec4\u7684\u65f6\u5019\uff0c\u5185\u5b58\u91cc\u552f\u4e00\u771f\u6b63\u88ab\u6d6a\u8d39\u7684\u662f\u90a3\u4e9b\u5c1a\u672a\u586b\u5145\u6ee1\u7684\u6570\u7ec4\u5355\u5143\u3002 \u8bc4\u4f30\u6570\u7ec4\u5185\u5b58\u4f7f\u7528\u7387\u7684\u4e00\u4e2a\u975e\u5e38\u6709\u7528\u7684\u6982\u5ff5\u662f\u8d1f\u8f7d\u56e0\u5b50\uff08load factor\uff09\u3002\u6570\u7ec4\u7684\u8d1f\u8f7d\u56e0\u5b50\u7b49\u540c\u4e8e\u5b83\u6240\u5b58\u50a8\u7684\u5143\u7d20\u6570\u9664\u4ee5\u6570\u7ec4\u7684\u5bb9\u91cf\u3002 \u5f53\u6570\u7ec4\u5df2\u6ee1\u7684\u65f6\u5019\uff0c\u8d1f\u8f7d\u56e0\u5b50\u5c31\u662f1\uff1b \u5f53\u6570\u7ec4\u4e3a\u7a7a\u65f6\uff0c\u8d1f\u8f7d\u56e0\u5b50\u5c31\u662f0\uff1b \u5f53\u5185\u5b58\u5355\u5143\u7684\u5bb9\u91cf\u4e3a10\u4e14\u5360\u7528\u4e863\u4e2a\u5355\u5143\u65f6\uff0c\u8d1f\u8f7d\u56e0\u5b50\u5c31\u662f0.3\uff1b \u5f53\u6570\u7ec4\u7684\u8d1f\u8f7d\u56e0\u5b50\u964d\u5230\u67d0\u4e2a\u9608\u503c\uff08\u59820.25\uff09\u4ee5\u4e0b\u65f6\uff0c\u53ef\u4ee5\u901a\u8fc7\u8c03\u6574\u6570\u7ec4\u5c3a\u5bf8\u5c06\u6d6a\u8d39\u7684\u5185\u5b58\u5355\u5143\u6570\u4fdd\u6301\u5728\u5c3d\u53ef\u80fd\u4f4e\u7684\u6c34\u5e73\uff1b 4.2.6.\u7ec3\u4e60\u9898 \u00b6 1\uff0e\u8bf7\u8bf4\u660e\u4e3a\u4ec0\u4e48\u63d2\u5165\u6216\u5220\u9664\u7ed9\u5b9a\u5143\u7d20\u65f6\u5fc5\u987b\u8981\u79fb\u52a8\u6570\u7ec4\u91cc\u7684\u67d0\u4e9b\u5143\u7d20\u3002 \u89e3\u7b54\uff1a\u5728 Python \u4e2d\uff0c\u5217\u8868\uff08list\uff09\u662f\u57fa\u4e8e\u6570\u7ec4\u5b9e\u73b0\u7684\u6570\u636e\u7ed3\u6784\u3002\u6240\u8c13\u7684\u201c\u6570\u7ec4\u201d\uff0c\u5176\u672c\u8d28\u4e0a\u662f\u4e00\u5757\u8fde\u7eed\u7684\u5185\u5b58\u7a7a\u95f4\uff0c\u7531\u4e8e\u5176\u5185\u5b58\u8fde\u7eed\u7684\u7279\u6027\uff0c\u6570\u7ec4\u5728\u8fdb\u884c\u63d2\u5165\u6216\u8005\u5220\u9664\u4e00\u4e2a\u5143\u7d20\u65f6\uff0c\u4e3a\u4e86\u4fdd\u6301\u5185\u5b58\u7684\u8fde\u7eed\u6027\uff0c\u5f80\u5f80\u9700\u8981\u79fb\u52a8\u6570\u7ec4\u91cc\u7684\u5176\u5b83\u5143\u7d20\u3002 \u5f53\u5728\u6570\u7ec4\u7684\u4e2d\u95f4\u4f4d\u7f6e\u63d2\u5165\u4e00\u4e2a\u65b0\u7684\u5143\u7d20\u65f6\uff0c\u4e3a\u4e86\u7ed9\u65b0\u5143\u7d20\u817e\u51fa\u7a7a\u95f4\uff0c\u5b83\u540e\u9762\u7684\u6240\u6709\u5143\u7d20\u90fd\u9700\u8981\u5411\u540e\u79fb\u52a8\u4e00\u4f4d\u3002\u540c\u6837\u7684\uff0c\u5982\u679c\u6211\u4eec\u5220\u9664\u4e86\u6570\u7ec4\u7684\u4e00\u4e2a\u5143\u7d20\uff0c\u4e3a\u4e86\u907f\u514d\u5728\u6570\u7ec4\u4e2d\u51fa\u73b0\u4e00\u4e2a\u7a7a\u6d1e\uff0c\u88ab\u5220\u9664\u5143\u7d20\u540e\u9762\u7684\u6240\u6709\u5143\u7d20\u90fd\u9700\u8981\u5411\u524d\u79fb\u52a8\u4e00\u4f4d\u3002 \u7136\u800c\uff0cPython\u7684 list \u6570\u636e\u7ed3\u6784\u662f\u52a8\u6001\u7684\uff0c\u4e5f\u5c31\u662f\u8bf4\uff0c\u5f53\u63d2\u5165\u6216\u5220\u9664\u5143\u7d20\u65f6\uff0cPython\u4f1a\u81ea\u52a8\u5206\u914d\u6216\u56de\u6536\u5185\u5b58\u3002\u5f53\u5728 list \u7684\u672b\u5c3e\u6dfb\u52a0\u6216\u79fb\u9664\u5143\u7d20\u65f6\uff0c\u4e0d\u9700\u8981\u79fb\u52a8\u5176\u4ed6\u5143\u7d20\uff0c\u56e0\u6b64\u64cd\u4f5c\u6548\u7387\u8f83\u9ad8\uff1b\u4f46\u662f\u5728 list \u7684\u4e2d\u95f4\u6216\u8d77\u59cb\u90e8\u5206\u63d2\u5165\u6216\u5220\u9664\u5143\u7d20\u65f6\uff0c\u5c31\u9700\u8981\u79fb\u52a8\u5176\u5b83\u5143\u7d20\uff0c\u76f8\u5bf9\u800c\u8a00\uff0c\u5176\u64cd\u4f5c\u6548\u7387\u5c31\u8f83\u4f4e\u4e86\u3002 2\uff0e\u5728\u63d2\u5165\u8fc7\u7a0b\u4e2d\uff0c\u79fb\u52a8\u6570\u7ec4\u5143\u7d20\u65f6\uff0c\u8981\u5148\u79fb\u52a8\u54ea\u4e2a\u5143\u7d20\uff1f\u5148\u79fb\u52a8\u63d2\u5165\u4f4d\u7f6e\u7684\u5143\u7d20\uff0c\u8fd8\u662f\u6700\u540e\u4e00\u4e2a\u5143\u7d20\uff1f\u4e3a\u4ec0\u4e48\uff1f \u89e3\u7b54\uff1a\u5728 Python \u4e2d\u5b9e\u73b0\u6570\u7ec4\u7684\u63d2\u5165\u8fc7\u7a0b\u65f6\uff0c\u5e94\u5f53\u5148\u79fb\u52a8\u63d2\u5165\u4f4d\u7f6e\u4e4b\u540e\u7684\u6700\u540e\u4e00\u4e2a\u5143\u7d20\u3002 \u8003\u8651\u4ee5\u4e0b\u7684\u60c5\u51b5\uff1a\u503c\u63d2\u5165\u4e8e\u6570\u7ec4\u7684\u4e2d\u95f4\u4f4d\u7f6e\uff0c\u4f60\u8bd5\u56fe\u4ece\u63d2\u5165\u4f4d\u7f6e\u5f00\u59cb\uff0c\u5c06\u6bcf\u4e2a\u5143\u7d20\u540e\u79fb\u4e00\u4f4d\u3002\u4f46\u662f\uff0c\u5f53\u4f60\u628a\u7b2c\u4e00\u4e2a\u5143\u7d20\u79fb\u5230\u7b2c\u4e8c\u4e2a\u4f4d\u7f6e\u65f6\uff0c\u4f60\u4f1a\u8986\u76d6\u6389\u539f\u6709\u7684\u7b2c\u4e8c\u4e2a\u5143\u7d20\uff0c\u7531\u4e8e\u4f60\u8fd8\u6ca1\u6709\u4fdd\u5b58\u6216\u590d\u5236\u8fd9\u4e2a\u88ab\u8986\u76d6\u7684\u5143\u7d20\uff0c\u5b83\u5c31\u4f1a\u4e22\u5931\u3002 \u5982\u679c\u4ece\u6700\u540e\u4e00\u4e2a\u5143\u7d20\u5f00\u59cb\uff0c\u5c06\u6bcf\u4e2a\u5143\u7d20\u5411\u540e\u79fb\u4e00\u4f4d\uff0c\u90a3\u4e48\u6bcf\u4e2a\u5143\u7d20\u90fd\u4f1a\u88ab\u590d\u5236\u5230\u5b83\u7684\u4e0b\u4e00\u4f4d\uff0c\u7136\u540e\u624d\u4f1a\u88ab\u5b83\u524d\u9762\u7684\u5143\u7d20\u8986\u76d6\u3002\u8fd9\u6837\u5c31\u786e\u4fdd\u4e86\u6bcf\u4e2a\u5143\u7d20\u90fd\u80fd\u6b63\u786e\u5730\u79fb\u52a8\u5230\u5b83\u5e94\u8be5\u5230\u8fbe\u7684\u4f4d\u7f6e\uff0c\u4e0d\u4f1a\u6709\u4efb\u4f55\u5143\u7d20\u4e22\u5931\u3002 \u6240\u4ee5\uff0c\u5728\u63d2\u5165\u8fc7\u7a0b\u4e2d\uff0c\u6211\u4eec\u5e94\u8be5\u4ece\u6700\u540e\u4e00\u4e2a\u5143\u7d20\u5f00\u59cb\uff0c\u9010\u4e2a\u5c06\u5143\u7d20\u540e\u79fb\u4e00\u4f4d\uff0c\u76f4\u5230\u5c06\u63d2\u5165\u4f4d\u7f6e\u7684\u5143\u7d20\u4e5f\u540e\u79fb\u4e00\u4f4d\uff0c\u7136\u540e\u5728\u63d2\u5165\u4f4d\u7f6e\u653e\u5165\u65b0\u7684\u5143\u7d20\u3002 3\uff0e\u5982\u679c\u63d2\u5165\u4f4d\u7f6e\u662f\u6570\u7ec4\u7684\u903b\u8f91\u672b\u5c3e\uff0c\u8bf7\u8bf4\u660e\u8fd9\u4e2a\u63d2\u5165\u64cd\u4f5c\u7684\u8fd0\u884c\u65f6\u590d\u6742\u5ea6\u3002 \u89e3\u7b54\uff1a\u5982\u679c\u5728\u6570\u7ec4\uff08\u5728 Python \u4e2d\u5c31\u662f list\uff09\u7684\u903b\u8f91\u672b\u5c3e\u63d2\u5165\u5143\u7d20\uff0c\u8fd9\u79cd\u64cd\u4f5c\u901a\u5e38\u53ef\u4ee5\u5728\u5e38\u6570\u65f6\u95f4\u5185\u5b8c\u6210\uff0c\u4e5f\u5c31\u662f\u8bf4\uff0c\u8fd9\u79cd\u64cd\u4f5c\u7684\u65f6\u95f4\u590d\u6742\u5ea6\u662f O(1)\u3002 \u56e0\u4e3a\u6570\u7ec4\u662f\u8fde\u7eed\u7684\u5185\u5b58\u7a7a\u95f4\uff0c\u4f4d\u4e8e\u672b\u5c3e\u7684\u63d2\u5165\u64cd\u4f5c\u4e0d\u9700\u8981\u79fb\u52a8\u4efb\u4f55\u5143\u7d20\uff0c\u4ec5\u4ec5\u6d89\u53ca\u5728\u672b\u5c3e\u6dfb\u52a0\u65b0\u5143\u7d20\uff0c\u5e76\u53ef\u80fd\u6d89\u53ca\u4e00\u4e9b\u989d\u5916\u7684\u5185\u5b58\u5206\u914d\uff08\u5982\u679c\u6570\u7ec4\u5df2\u6ee1\uff0c\u9700\u8981\u5206\u914d\u66f4\u5927\u7684\u6570\u7ec4\u6765\u5bb9\u7eb3\u65b0\u7684\u5143\u7d20\uff09\u3002 \u9700\u8981\u6ce8\u610f\u7684\u662f\uff0c\u5185\u5b58\u5206\u914d\u548c\u590d\u5236\u5143\u7d20\u5728\u5b9e\u9645\u64cd\u4f5c\u4e2d\u53ef\u80fd\u8fd8\u662f\u9700\u8981\u4e00\u4e9b\u65f6\u95f4\u7684\uff0c\u5c24\u5176\u662f\u5728\u6570\u7ec4\u5df2\u6ee1\u65f6\uff0c\u9700\u8981\u91cd\u65b0\u5206\u914d\u5e76\u590d\u5236\u6574\u4e2a\u6570\u7ec4\u5230\u65b0\u7684\u5185\u5b58\u5730\u5740\u3002\u4f46\u662f\u5728\u7406\u8bba\u5206\u6790\u65f6\uff0c\u6211\u4eec\u901a\u5e38\u5ffd\u7565\u8fd9\u79cd\u60c5\u51b5\uff0c\u56e0\u4e3a\u5b83\u662f\u4e00\u79cd\u88ab\u79f0\u4e3a\u644a\u8fd8\uff08amortized\uff09\u64cd\u4f5c\u7684\u7279\u4f8b\uff0c\u4ece\u957f\u671f\u7684\u5e73\u5747\u8fd0\u884c\u65f6\u95f4\u6765\u770b\uff0c\u8fd9\u79cd\u63d2\u5165\u64cd\u4f5c\u7684\u65f6\u95f4\u590d\u6742\u5ea6\u4ecd\u7136\u662f O(1) \u7684\u3002 4\uff0e\u5047\u8bbe\u6570\u7ec4\u5f53\u524d\u5305\u542b14\u4e2a\u5143\u7d20\uff0c\u5b83\u7684\u8d1f\u8f7d\u56e0\u5b50\u4e3a0.70\uff0c\u90a3\u4e48\u5b83\u7684\u7269\u7406\u5bb9\u91cf\u662f\u591a\u5c11\uff1f \u89e3\u7b54\uff1a\u8d1f\u8f7d\u56e0\u5b50\u901a\u5e38\u662f\u6307\u4e00\u4e2a\u54c8\u5e0c\u8868\u4e2d\u5df2\u5b58\u5143\u7d20\u6570\u91cf\u5bf9\u5e94\u4e8e\u5176\u5e95\u5c42\u6570\u7ec4\u5bb9\u91cf\u7684\u6bd4\u4f8b\u3002\u5bf9\u4e8e\u4e00\u822c\u7684\u6570\u7ec4\u548c Python \u7684 list\uff0c\u6211\u4eec\u901a\u5e38\u4e0d\u4f1a\u8c08\u8bba\u8d1f\u8f7d\u56e0\u5b50\uff0c\u56e0\u4e3a\u8fd9\u4e9b\u6570\u636e\u7ed3\u6784\u7684\u5927\u5c0f\u76f4\u63a5\u5bf9\u5e94\u4e8e\u5176\u4e2d\u5305\u542b\u7684\u5143\u7d20\u6570\u91cf\u3002 \u7136\u800c\uff0c\u5982\u679c\u4f60\u8981\u8ba1\u7b97\u4e00\u4e2a\u8d1f\u8f7d\u56e0\u5b50\u4e3a 0.70 \u7684\u5bb9\u5668\uff0c\u5e76\u4e14\u5b83\u5305\u542b\u4e8614\u4e2a\u5143\u7d20\uff0c\u90a3\u4e48\u5b83\u7684\u7269\u7406\u5bb9\u91cf\u53ef\u4ee5\u8ba1\u7b97\u4e3a\uff1a \u5143\u7d20\u6570\u91cf / \u8d1f\u8f7d\u56e0\u5b50 = \u5bb9\u91cf \u5728\u8fd9\u79cd\u60c5\u51b5\u4e0b\uff0c\u7269\u7406\u5bb9\u91cf\u5e94\u8be5\u662f 14 / 0.70 = 20\u3002\u6240\u4ee5\u7269\u7406\u5bb9\u91cf\u5e94\u8be5\u662f 20\u3002 4.3.\u4e8c\u7ef4\u6570\u7ec4\uff08\u7f51\u683c\uff09 \u00b6 \u4e00\u7ef4\u6570\u7ec4\uff08one-dimensional array\uff09 \u4e8c\u7ef4\u6570\u7ec4\uff08two-dimensional array\uff09\uff0c\u6216\u7f51\u683c\uff08grid\uff09 \u8981\u8bbf\u95eegrid\u91cc\u7684\u5143\u7d20\uff0c\u53ef\u4ee5\u901a\u8fc7\u4e24\u4e2a\u4e0b\u6807\u6765\u6307\u5b9a\u5176\u884c\u548c\u5217\u7684\u76f8\u5e94\u4f4d\u7f6e\uff0c\u5e76\u4e14\u8fd9\u4e24\u4e2a\u7d22\u5f15\u90fd\u662f\u4ece0\u5f00\u59cb\u7684\u3002 x = grid [ 2 ][ 3 ] # \u5c06\u4e8c\u7ef4\u6570\u7ec4\u7b2c\u4e8c\u884c\u7b2c\u4e09\u5217\u7684\u503c\u8d4b\u7ed9\u53d8\u91cfx 4.3.1.\u4f7f\u7528\u7f51\u683c \u00b6 \u9664\u4e86\u7528\u53cc\u4e0b\u6807\uff0c\u7f51\u683c\u8fd8\u5fc5\u987b\u8981\u6709\u4e24\u4e2a\u65b9\u6cd5\uff0c\u7528\u6765\u8fd4\u56de\u884c\u6570\u548c\u5217\u6570\u3002\u6211\u4eec\u628a\u8fd9\u4e24\u4e2a\u65b9\u6cd5\u5206\u522b\u547d\u540d\u4e3a getHeight \u548c getWidth \u3002 \u57fa\u4e8e4.3.3\u4e2d\u5b9a\u4e49\u7684Grid\u7c7b\uff0c\u4e0b\u9762\u8fd9\u6bb5\u4ee3\u7801\u4f1a\u5b9e\u4f8b\u5316\u4e00\u4e2a\u4e8c\u7ef4\u6570\u7ec4\uff0c\u5e76\u8ba1\u7b97\u53d8\u91cf my_grid \u91cc\u6240\u6709\u6570\u5b57\u7684\u603b\u548c\u3002\u5916\u90e8\u5faa\u73af\u4f1a\u8fed\u4ee35\u6b21\u5e76\u5411\u4e0b\u9010\u884c\u79fb\u52a8\uff0c\u5728\u6bcf\u6b21\u8fdb\u5165\u5916\u90e8\u5faa\u73af\u7684\u65f6\u5019\uff0c\u5185\u90e8\u5faa\u73af\u90fd\u4f1a\u8fed\u4ee35\u6b21\uff0c\u4ece\u800c\u5728\u4e0d\u540c\u884c\u7684\u5217\u4e4b\u95f4\u79fb\u52a8\u3002 my_grid = Grid ( 5 , 5 , 1 ) sum = 0 for row in range ( my_grid . getHeight ()): # Go through rows for column in range ( my_grid . getWidth ()): # Go through columns sum += my_grid [ row ][ column ] 4.3.2.\u521b\u5efa\u5e76\u521d\u59cb\u5316\u7f51\u683c \u00b6 \u57fa\u4e8e4.3.3\u4e2d\u5b9a\u4e49\u7684Grid\u7c7b\uff0c\u4e0b\u9762\u4ee3\u7801\u5b9e\u4f8b\u5316\u4e86\u4e00\u4e2a\u4e8c\u7ef4\u6570\u7ec4\uff0c\u904d\u5386\u8be5\u6570\u7ec4\u7684\u6bcf\u4e2a\u5143\u7d20\u5e76\u8d4b\u503c\u3002 my_grid = Grid ( 5 , 5 , 1 ) print ( my_grid ) # \u884c\u904d\u5386 for row in range ( my_grid . getHeight ()): # \u5217\u904d\u5386 for column in range ( my_grid . getWidth ()): my_grid [ row ][ column ] = int ( str ( row ) + str ( column )) 4.3.3.\u5b9a\u4e49Grid\u7c7b \u00b6 \u4e0b\u9762\u5b9e\u73b0\u4e86\u4e00\u4e2a Grid \u5bf9\u8c61\uff0c\u5305\u542b3\u4e2a\u53c2\u6570\uff08\u9ad8\u5ea6\u3001\u5bbd\u5ea6\u4ee5\u53ca\u521d\u59cb\u7684\u586b\u5145\u503c\uff09\u7684 Grid \u6784\u9020\u51fd\u6570\u3002 \u9ad8\u5ea6\uff0c\u5373\u884c\u6570\uff1b\u5bbd\u5ea6\uff0c\u5373\u5217\u6570\uff1b \u5b9e\u4f8b\u5316\u4e86\u4e00\u4e2a5\u884c5\u5217\u7684\u4e8c\u7ef4\u6570\u7ec4\uff1b class Array ( object ): \"\"\"\u63cf\u8ff0\u4e00\u4e2a\u6570\u7ec4\u3002\"\"\" def __init__ ( self , capacity , fillValue = None ): \"\"\"Capacity\u662f\u6570\u7ec4\u7684\u5927\u5c0f. fillValue\u4f1a\u586b\u5145\u5728\u6bcf\u4e2a\u5143\u7d20\u4f4d\u7f6e, \u9ed8\u8ba4\u503c\u662fNone\"\"\" # \u521d\u59cb\u5316\u6570\u7ec4\u7684\u903b\u8f91\u5c3a\u5bf8\u548c\u7269\u7406\u5c3a\u5bf8 self . logicalSize = 0 self . capacity = capacity self . fillValue = fillValue #\u521d\u59cb\u5316\u5185\u90e8\u6570\u7ec4\uff0c\u5e76\u586b\u5145\u5143\u7d20\u503c self . items = list () for count in range ( capacity ): self . items . append ( fillValue ) self . logicalSize += 1 # \u521d\u59cb\u5316\u6570\u7ec4\u7269\u7406\u5927\u5c0f\u65f6\uff0c\u4e5f\u540c\u65f6\u521d\u59cb\u5316\u5176\u903b\u8f91\u5927\u5c0f def __len__ ( self ): \"\"\"\u8fd4\u56de\u6570\u7ec4\u7684\u5927\u5c0f\"\"\" return len ( self . items ) def __str__ ( self ): \"\"\"\u5c06\u6570\u7ec4\u5b57\u7b26\u4e32\u5316\u5e76\u8fd4\u56de\"\"\" result = \"\" for index in range ( self . size ()): result += str ( self . items [ index ]) + \" \" return result def size ( self ): \"\"\"\u8fd4\u56de\u6570\u7ec4\u7684\u903b\u8f91\u5c3a\u5bf8\"\"\" return self . logicalSize def __iter__ ( self ): \"\"\"\u652f\u6301for\u5faa\u73af\u5bf9\u6570\u7ec4\u8fdb\u884c\u904d\u5386.\"\"\" print ( \"__iter__ called\" ) # \u4ec5\u7528\u6765\u6d4b\u8bd5\u4f55\u65f6__iter__\u4f1a\u88ab\u8c03\u7528 return iter ( self . items ) def __getitem__ ( self , index ): \"\"\" \u7528\u4e8e\u8bbf\u95ee\u7d22\u5f15\u5904\u7684\u4e0b\u6807\u8fd0\u7b97\u7b26. \u5148\u51b3\u6761\u4ef6: 0 <= index < size() \"\"\" if index < 0 or index >= self . size (): raise IndexError ( \"\u8bfb\u53d6\u64cd\u4f5c\u51fa\u9519, \u6570\u7ec4\u7d22\u5f15\u8d8a\u754c(\u4e0d\u5728\u6570\u7ec4\u903b\u8f91\u8fb9\u754c\u8303\u56f4\u5185)\" ) return self . items [ index ] def __setitem__ ( self , index , newItem ): \"\"\" \u4e0b\u6807\u8fd0\u7b97\u7b26\u7528\u4e8e\u5728\u7d22\u5f15\u5904\u8fdb\u884c\u66ff\u6362. \u5148\u51b3\u6761\u4ef6: 0 <= index < size() \"\"\" if index < 0 or index >= self . size (): raise IndexError ( \"\u66f4\u65b0\u64cd\u4f5c\u51fa\u9519, \u6570\u7ec4\u7d22\u5f15\u8d8a\u754c(\u4e0d\u5728\u6570\u7ec4\u903b\u8f91\u8fb9\u754c\u8303\u56f4\u5185)\" ) self . items [ index ] = newItem def __eq__ ( self , other ): \"\"\" \u4e24\u4e2a\u6570\u7ec4\u76f8\u7b49\u5219\u8fd4\u56deTrue, \u5426\u5219\u8fd4\u56deFalse \"\"\" # \u5224\u65ad\u4e24\u4e2a\u6570\u7ec4\u662f\u5426\u662f\u540c\u4e00\u4e2a\u5bf9\u8c61\uff0c\u6ce8\u610f\uff0c\u4e0d\u662f\u5b83\u4eec\u7684\u503c\u662f\u5426\u76f8\u7b49 if self is other : return True # \u5224\u65ad\u4e24\u4e2a\u5bf9\u8c61\u7c7b\u578b\u662f\u5426\u4e00\u6837 if type ( self ) != type ( other ): return False # \u5224\u65ad\u4e24\u4e2a\u6570\u7ec4\u5927\u5c0f\u662f\u5426\u4e00\u6837 if self . size () != other . size (): return False # \u6bd4\u8f83\u4e24\u4e2a\u6570\u7ec4\u7684\u503c\u662f\u5426\u4e00\u6837 for index in range ( self . size ()): if self [ index ] != other [ index ]: return False return True def grow ( self ): \"\"\"\u589e\u5927\u6570\u7ec4\u7269\u7406\u5c3a\u5bf8\"\"\" # \u57fa\u4e8e\u5f53\u524d\u7269\u7406\u5c3a\u5bf8\u52a0\u500d\uff0c\u5e76\u5c06fillValue\u8d4b\u503c\u5e95\u5c42\u5217\u8868\u7684\u65b0\u5143\u7d20 for count in range ( len ( self )): self . items . append ( self . fillValue ) def insert ( self , index , newItem ): \"\"\"\u5728\u6570\u7ec4\u6307\u5b9a\u7d22\u5f15\u5904\u63d2\u5165\u65b0\u5143\u7d20\"\"\" # \u5f53\u6570\u7ec4\u7684\u7269\u7406\u5c3a\u5bf8\u548c\u903b\u8f91\u5c3a\u5bf8\u4e00\u6837\u65f6\uff0c\u5219\u589e\u52a0\u7269\u7406\u5c3a\u5bf8 if self . size () == len ( self ): self . grow () # \u63d2\u5165\u65b0\u5143\u7d20 # \u5f53\u63d2\u5165\u4f4d\u7f6e\u5927\u4e8e\u6216\u7b49\u4e8e\u6700\u5927\u903b\u8f91\u4f4d\u7f6e\uff0c\u5219\u5728\u6570\u7ec4\u672b\u7aef\u63d2\u5165\u65b0\u5143\u7d20 # \u5f53\u63d2\u5165\u4f4d\u7f6e\u4ecb\u4e8e\u6570\u7ec4\u903b\u8f91\u4f4d\u7f6e\u7684\u4e2d\u95f4\uff0c\u5219\u4ece\u63d2\u5165\u4f4d\u7f6e\u8d77\u5c06\u5269\u4f59\u6570\u7ec4\u5143\u7d20\u5411\u5c3e\u90e8\u5e73\u79fb\u4e00\u4e2a\u4f4d\u7f6e if index >= self . size (): self . items [ self . size ()] = newItem else : index = max ( index , 0 ) # \u5c06\u6570\u7ec4\u5143\u7d20\u5411\u5c3e\u90e8\u5e73\u79fb\u4e00\u4e2a\u4f4d\u7f6e for i in range ( self . size (), index , - 1 ): self . items [ i ] = self . items [ i - 1 ] # \u63d2\u5165\u65b0\u5143\u7d20 self . items [ index ] = newItem # \u589e\u52a0\u6570\u7ec4\u7684\u903b\u8f91\u5c3a\u5bf8 self . logicalSize += 1 def shrink ( self ): \"\"\" \u51cf\u5c11\u6570\u7ec4\u7684\u7269\u7406\u5c3a\u5bf8 \u5f53: - \u6570\u7ec4\u7684\u903b\u8f91\u5c3a\u5bf8\u5c0f\u4e8e\u6216\u7b49\u4e8e\u5176\u7269\u7406\u5c3a\u5bf8\u76841/4 - \u5e76\u4e14\u5b83\u7684\u7269\u7406\u5c3a\u5bf8\u81f3\u5c11\u662f\u8fd9\u4e2a\u6570\u7ec4\u5efa\u7acb\u65f6\u9ed8\u8ba4\u5bb9\u91cf\u76842\u500d\u65f6 \u5219\u628a\u6570\u7ec4\u7684\u7269\u7406\u5c3a\u5bf8\u51cf\u5c0f\u5230\u539f\u6765\u7684\u4e00\u534a\uff0c\u5e76\u4e14\u4e5f\u4e0d\u4f1a\u5c0f\u4e8e\u5176\u9ed8\u8ba4\u5bb9\u91cf \"\"\" # \u5728\u903b\u8f91\u5c3a\u5bf8\u548c\u7269\u7406\u5c3a\u5bf8\u7684\u4e00\u534a\u4e4b\u95f4\u9009\u62e9\u6700\u5927\u503c\u4f5c\u4e3a\u6570\u7ec4\u6536\u7f29\u540e\u7684\u7269\u7406\u5c3a\u5bf8 newSize = max ( self . capacity , len ( self ) // 2 ) # \u91ca\u653e\u591a\u4f59\u7684\u6570\u7ec4\u7a7a\u95f4 for count in range ( len ( self ) - newSize ): self . items . pop () def pop ( self , index ): \"\"\" \u5220\u9664\u6307\u5b9a\u7d22\u5f15\u503c\u7684\u6570\u7ec4\u5143\u7d20,\u5e76\u8fd4\u56de\u5220\u9664\u7684\u6570\u7ec4\u5143\u7d20\u503c \u5148\u51b3\u6761\u4ef6: 0 <= index < size() \"\"\" if index < 0 or index >= self . size (): raise IndexError ( \"\u5220\u9664\u64cd\u4f5c\u51fa\u9519, \u6570\u7ec4\u7d22\u5f15\u8d8a\u754c(\u4e0d\u5728\u6570\u7ec4\u903b\u8f91\u8fb9\u754c\u8303\u56f4\u5185)\" ) # \u4fdd\u5b58\u5373\u5c06\u88ab\u5220\u9664\u7684\u6570\u7ec4\u5143\u7d20\u503c itemToReturn = self . items [ index ] # \u5c06\u6570\u7ec4\u5143\u7d20\u5411\u5934\u90e8\u5e73\u79fb\u4e00\u4e2a\u4f4d\u7f6e for i in range ( index , self . size () - 1 ): self . items [ i ] = self . items [ i + 1 ] # \u5c06\u6570\u7ec4\u5c3e\u90e8\u7684\u7a7a\u4f59\u4f4d\u8d4b\u503cfillValue\uff0c\u9ed8\u8ba4\u662fNone self . items [ self . size () - 1 ] = self . fillValue # \u51cf\u5c11\u6570\u7ec4\u903b\u8f91\u5c3a\u5bf8 self . logicalSize -= 1 # \u51cf\u5c11\u6570\u7ec4\u7269\u7406\u5c3a\u5bf8 # \u5f53: # - \u6570\u7ec4\u7684\u903b\u8f91\u5c3a\u5bf8\u5c0f\u4e8e\u6216\u7b49\u4e8e\u5176\u7269\u7406\u5c3a\u5bf8\u76841/4 # - \u5e76\u4e14\u5b83\u7684\u7269\u7406\u5c3a\u5bf8\u81f3\u5c11\u662f\u8fd9\u4e2a\u6570\u7ec4\u5efa\u7acb\u65f6\u9ed8\u8ba4\u5bb9\u91cf\u76842\u500d\u65f6 # \u5219\u628a\u6570\u7ec4\u7684\u7269\u7406\u5c3a\u5bf8\u51cf\u5c0f\u5230\u539f\u6765\u7684\u4e00\u534a\uff0c\u5e76\u4e14\u4e5f\u4e0d\u4f1a\u5c0f\u4e8e\u5176\u9ed8\u8ba4\u5bb9\u91cf if self . size () <= len ( self ) // 4 and len ( self ) > self . capacity : self . shrink () # \u8fd4\u56de\u88ab\u5220\u9664\u5143\u7d20\u7684\u503c print ( f 'Item { itemToReturn } was deleted' ) return itemToReturn class Grid ( object ): \"\"\"\u63cf\u8ff0\u4e00\u4e2a\u4e8c\u7ef4\u6570\u7ec4\u3002\"\"\" def __init__ ( self , rows , columns , fillValue = None ): self . rows = rows self . columns = columns self . fillValue = fillValue # \u6309\u884c\u6570\u521d\u59cb\u5316\u6570\u7ec4y\u8f74\u7269\u7406\u5c3a\u5bf8 self . data = Array ( rows , fillValue ) # \u6309\u5217\u6570\u521d\u59cb\u5316\u6570\u7ec4x\u8f74\u7269\u7406\u5c3a\u5bf8\uff0c\u5e76\u8d4b\u503c\u5230y\u8f74\u6570\u7ec4\uff0c\u586b\u5145None\u503c for row in range ( rows ): self . data [ row ] = Array ( columns , fillValue ) def getHeight ( self ): \"\"\"\u8fd4\u56de\u4e8c\u7ef4\u6570\u7ec4\u7684y\u8f74\u7684\u5927\u5c0f(\u7269\u7406\u5c3a\u5bf8), \u5373\u6570\u7ec4\u7684\u884c\u6570\"\"\" return len ( self . data ) def getWidth ( self ): \"\"\"\u8fd4\u56de\u4e8c\u7ef4\u6570\u7ec4\u7684x\u8f74\u7684\u5927\u5c0f(\u7269\u7406\u5c3a\u5bf8), \u5373\u6570\u7ec4\u7684\u5217\u6570\"\"\" return len ( self . data [ 0 ]) def __getitem__ ( self , index ): \"\"\"\u8fd4\u56de\u4e8c\u7ef4\u6570\u7ec4\u6307\u5b9a\u884c\u548c\u5217\u7d22\u5f15\u5bf9\u5e94\u7684\u5143\u7d20\u503c\"\"\" return self . data [ index ] def __str__ ( self ): \"\"\"\u8fd4\u56de\u4e8c\u7ef4\u6570\u7ec4\u7684\u5b57\u7b26\u4e32\u5f62\u5f0f\"\"\" result = \"\" for row in range ( self . getHeight ()): for col in range ( self . getWidth ()): result += str ( self . data [ row ][ col ]) + \" \" result += \" \\n \" return result def main (): my_grid = Grid ( 5 , 5 , 1 ) print ( my_grid ) if __name__ == \"__main__\" : main () # \u8fd0\u884c\u7ed3\u679c # 1 1 1 1 1 # 1 1 1 1 1 # 1 1 1 1 1 # 1 1 1 1 1 # 1 1 1 1 1 4.3.4.\u53c2\u5dee\u4e0d\u9f50\u7684\u7f51\u683c\u548c\u591a\u7ef4\u6570\u7ec4 \u00b6 \u5230\u76ee\u524d\u4e3a\u6b62\uff0c\u6211\u4eec\u6240\u8ba8\u8bba\u7684\u7f51\u683c\u90fd\u662f\u4e8c\u7ef4\u5e76\u4e14\u662f\u77e9\u5f62\u7684\u3002\u6211\u4eec\u4e5f\u53ef\u4ee5\u628a\u7f51\u683c\u521b\u5efa\u6210\u53c2\u5dee\u4e0d\u9f50\u7684\u6837\u5b50\uff0c\u4e5f\u53ef\u4ee5\u521b\u5efa\u9ad8\u4e8e\u4e24\u4e2a\u7ef4\u5ea6\u7684\u7f51\u683c\u3002 \u53c2\u5dee\u4e0d\u9f50\u7684\u7f51\u683c\u6709\u56fa\u5b9a\u7684\u884c\u6570\uff0c\u4f46\u662f\u6bcf\u4e00\u884c\u91cc\u7684\u6570\u636e\u5217\u6570\u5404\u6709\u4e0d\u540c\u3002\u5217\u8868\u6570\u7ec4\u6216\u6570\u7ec4\u662f\u53ef\u4ee5\u5b9e\u73b0\u8fd9\u79cd\u7f51\u683c\u7684\u5408\u9002\u7ed3\u6784\u3002 \u6bd4\u5982\uff0c\u53ef\u4ee5\u521b\u5efa\u4e00\u4e2a\u4e09\u7ef4\u6570\u7ec4\u7684\u65f6\u5019\u9700\u8981\u6307\u5b9a\u5b83\u7684\u6df1\u5ea6\u3001\u9ad8\u5ea6\u4ee5\u53ca\u5bbd\u5ea6\u3002\u56e0\u6b64\u53ef\u4ee5\u7ed9\u6570\u7ec4\u7c7b\u578b\u6dfb\u52a0\u4e00\u4e2a\u53eb\u4f5c getDepth \u7684\u65b9\u6cd5\uff0c\u4ece\u800c\u50cf getWidth \u548c getHeight \u65b9\u6cd5\u4e00\u6837\u518d\u5f97\u5230\u8fd9\u4e2a\u7ef4\u5ea6\u7684\u76f8\u5173\u6570\u636e\u3002\u5728\u8fd9\u4e2a\u5b9e\u73b0\u91cc\uff0c\u6bcf\u4e2a\u5143\u7d20\u90fd\u53ef\u4ee5\u901a\u8fc73\u4e2a\u4f5c\u4e3a\u7d22\u5f15\u7684\u6574\u6570\u8fdb\u884c\u8bbf\u95ee\uff0c\u4e5f\u53ef\u4ee5\u901a\u8fc7\u67093\u5c42\u5faa\u73af\u7684\u63a7\u5236\u8bed\u53e5\u7ed3\u6784\u6765\u4f7f\u7528\u5b83\u3002 4.3.5.\u7ec3\u4e60\u9898 \u00b6 1\uff0e\u4ec0\u4e48\u662f\u4e8c\u7ef4\u6570\u7ec4\uff08\u7f51\u683c\uff09\uff1f \u89e3\u7b54\uff1a\u4e8c\u7ef4\u6570\u7ec4\uff0c\u6709\u65f6\u88ab\u79f0\u4e3a\u7f51\u683c\uff0c\u662f\u4e00\u4e2a\u6570\u636e\u7ed3\u6784\uff0c\u5b83\u5141\u8bb8\u6211\u4eec\u5c06\u6570\u636e\u4ee5\u8868\u683c\u5f62\u5f0f\u7ec4\u7ec7\u8d77\u6765\uff0c\u5373\u6570\u636e\u5728\u4e24\u4e2a\u7ef4\u5ea6\u4e0a\u8fdb\u884c\u7ec4\u7ec7\u3002\u53ef\u4ee5\u628a\u4e8c\u7ef4\u6570\u7ec4\u770b\u4f5c\u662f\u4e00\u4e2a\u6570\u7ec4\u7684\u6570\u7ec4\u3002\u4f8b\u5982\uff0c\u5728 Python \u4e2d\uff0c\u4e00\u4e2a\u4e8c\u7ef4\u6570\u7ec4\u53ef\u4ee5\u662f\u4e00\u4e2a\u5217\u8868\u7684\u5217\u8868\u3002 \u5728\u4e8c\u7ef4\u6570\u7ec4\u4e2d\uff0c\u6bcf\u4e2a\u5143\u7d20\u90fd\u7531\u4e24\u4e2a\u7d22\u5f15\u786e\u5b9a\uff0c\u901a\u5e38\u79f0\u4e3a\u884c\u7d22\u5f15\u548c\u5217\u7d22\u5f15\u3002\u53ef\u4ee5\u8fd9\u6837\u7406\u89e3\uff1a\u9996\u5148\u9009\u5b9a\u4e00\u4e2a\u884c\uff0c\u7136\u540e\u518d\u5728\u8be5\u884c\u4e2d\u9009\u62e9\u4e00\u4e2a\u5143\u7d20\u3002\u7528\u4efb\u4f55\u4e00\u79cd\u7f16\u7a0b\u8bed\u8a00\u521b\u5efa\u548c\u64cd\u4f5c\u4e8c\u7ef4\u6570\u7ec4\u7684\u5177\u4f53\u8bed\u6cd5\u90fd\u4e0d\u5c3d\u76f8\u540c\uff0c\u4f46\u662f\u539f\u7406\u662f\u4e00\u6837\u7684\u3002 \u5728 Python \u4e2d\uff0c\u521b\u5efa\u4e8c\u7ef4\u6570\u7ec4\u7684\u4f8b\u5b50\u5982\u4e0b\uff1a # \u521b\u5efa\u4e00\u4e2a 3x3 \u7684\u4e8c\u7ef4\u6570\u7ec4 grid = [[ 1 , 2 , 3 ], [ 4 , 5 , 6 ], [ 7 , 8 , 9 ]] # \u8bbf\u95ee\u4e8c\u7ef4\u6570\u7ec4\u4e2d\u7279\u5b9a\u7684\u5143\u7d20 print ( grid [ 1 ][ 2 ]) # \u8f93\u51fa\uff1a6 2\uff0e\u8bf7\u63cf\u8ff0\u4e00\u4e2a\u53ef\u80fd\u4f1a\u7528\u5230\u4e8c\u7ef4\u6570\u7ec4\u7684\u5e94\u7528\u7a0b\u5e8f\u3002 \u89e3\u7b54\uff1a\u4e8c\u7ef4\u6570\u7ec4\u5728\u5404\u79cd\u7c7b\u578b\u7684\u5e94\u7528\u7a0b\u5e8f\u4e2d\u90fd\u88ab\u5e7f\u6cdb\u4f7f\u7528\u3002\u4e00\u4e2a\u5e38\u89c1\u7684\u4f8b\u5b50\u662f\u5728\u5904\u7406\u56fe\u50cf\u6216\u50cf\u7d20\u7684\u5e94\u7528\u4e2d\u3002 \u56fe\u50cf\u53ef\u4ee5\u88ab\u770b\u4f5c\u4e00\u4e2a\u4e8c\u7ef4\u6570\u7ec4\uff08\u6216\u8005\u5728\u5f69\u8272\u56fe\u50cf\u4e2d\uff0c\u662f\u4e00\u4e2a\u4e09\u7ef4\u6570\u7ec4\uff0c\u4e09\u4e2a\u901a\u9053\u5206\u522b\u662f\u7ea2\u3001\u7eff\u3001\u84dd\uff09\uff0c\u5176\u4e2d\u6bcf\u4e2a\u5143\u7d20\u8868\u793a\u4e00\u4e2a\u50cf\u7d20\u3002\u4e8c\u7ef4\u6570\u7ec4\u4e2d\u7684\u884c\u548c\u5217\u5bf9\u5e94\u4e8e\u56fe\u50cf\u7684\u5bbd\u5ea6\u548c\u9ad8\u5ea6\uff0c\u5143\u7d20\u503c\u901a\u5e38\u4ee3\u8868\u50cf\u7d20\u7684\u989c\u8272\u6df1\u5ea6\u3002 \u4f8b\u5982\uff0c\u4ee5\u4e0b Python \u4ee3\u7801\u521b\u5efa\u4e86\u4e00\u4e2a\u7b80\u5355\u7684\u7070\u5ea6\u56fe\u50cf\uff0c\u5e76\u4f7f\u7528 matplotlib \u5e93\u663e\u793a\u5b83\uff1a import numpy as np import matplotlib.pyplot as plt # \u521b\u5efa\u4e00\u4e2a 10x10 \u7684\u4e8c\u7ef4\u6570\u7ec4\uff0c\u6bcf\u4e2a\u5143\u7d20\u503c\u4e3a 0-255 \u4e4b\u95f4\u7684\u968f\u673a\u6574\u6570 image = np . random . randint ( 0 , 256 , ( 10 , 10 )) # \u663e\u793a\u8fd9\u4e2a\u56fe\u50cf plt . imshow ( image , cmap = 'gray' ) plt . show () \u5728\u8fd9\u4e2a\u4f8b\u5b50\u4e2d\uff0c\u6211\u4eec\u4f7f\u7528\u4e86 NumPy \u5e93\u6765\u521b\u5efa\u548c\u64cd\u4f5c\u4e8c\u7ef4\u6570\u7ec4\uff08\u5728 NumPy \u4e2d\uff0c\u8fd9\u79cd\u7ed3\u6784\u88ab\u79f0\u4e3a ndarray\uff09\u3002\u8fd9\u662f\u5904\u7406\u5927\u89c4\u6a21\u6570\u503c\u6570\u636e\u7684\u4e00\u4e2a\u975e\u5e38\u597d\u7684\u5de5\u5177\uff0c\u5c24\u5176\u662f\u5bf9\u4e8e\u6d89\u53ca\u5230\u79d1\u5b66\u8ba1\u7b97\u548c\u6570\u636e\u5206\u6790\u7684\u5e94\u7528\u7a0b\u5e8f\u3002 \u6b64\u5916\uff0c\u4e8c\u7ef4\u6570\u7ec4\u4e5f\u5e7f\u6cdb\u5e94\u7528\u4e8e\u6e38\u620f\u5f00\u53d1\uff08\u5982\u68cb\u76d8\u6e38\u620f\uff0c\u5982\u56fd\u9645\u8c61\u68cb\u6216\u4e95\u5b57\u6e38\u620f\u7684\u68cb\u76d8\u53ef\u4ee5\u7528\u4e8c\u7ef4\u6570\u7ec4\u6765\u8868\u793a\uff09\u3001\u7269\u7406\u6a21\u62df\u3001\u7cfb\u7edf\u52a8\u529b\u5b66\u6a21\u4eff\u3001\u5730\u7406\u4fe1\u606f\u7cfb\u7edf\uff08\u5730\u56fe\u53ef\u4ee5\u8868\u793a\u4e3a\u4e8c\u7ef4\u6570\u7ec4\u7684\u9ad8\u7a0b\u6570\u636e\uff09\u7b49\u8bb8\u591a\u9886\u57df\u3002 3\uff0e\u7f16\u5199\u4e00\u4e2a\u7a0b\u5e8f\uff0c\u4f7f\u4e4b\u53ef\u4ee5\u5728Grid\u5bf9\u8c61\u91cc\u641c\u7d22\u4e00\u4e2a\u8d1f\u6574\u6570\u3002\u5faa\u73af\u5e94\u8be5\u5728\u9047\u5230\u7f51\u683c\u91cc\u7684\u7b2c\u4e00\u4e2a\u8d1f\u6574\u6570\u7684\u5730\u65b9\u7ec8\u6b62\uff0c\u8fd9\u65f6\u53d8\u91cfrow\u548ccolumn\u5e94\u8be5\u88ab\u8bbe\u7f6e\u4e3a\u8fd9\u4e2a\u8d1f\u6570\u7684\u4f4d\u7f6e\u3002\u5982\u679c\u5728\u7f51\u683c\u91cc\u627e\u4e0d\u5230\u8d1f\u6570\uff0c\u90a3\u4e48\u53d8\u91cfrow\u548ccolumn\u5e94\u8be5\u7b49\u4e8e\u7f51\u683c\u7684\u884c\u6570\u548c\u5217\u6570\u3002 \u89e3\u7b54\uff1a\u5728Grid\u7c7b\u4e2d\u6dfb\u52a0\u4e0b\u9762\u7684\u65b9\u6cd5\uff0c\u53ef\u4ee5\u5b9e\u73b0\u63d0\u540d\u4e2d\u7684\u8981\u6c42 def find_negative ( self ): \"\"\"\u8fd4\u56de\u7b2c\u4e00\u4e2a\u8d1f\u6574\u6570\u7684\u7d22\u5f15\u503c\"\"\" target_row = 0 target_col = 0 for row in range ( self . getHeight ()): for col in range ( self . getWidth ()): # \u5982\u679c\u5f53\u524d\u5143\u7d20\u662f\u8d1f\u6570 if self . data [ row ][ col ] < 0 : # \u66f4\u65b0 row \u548c column \u4e3a\u8be5\u5143\u7d20\u7684\u4f4d\u7f6e target_row = row target_col = col # \u7ec8\u6b62\u5faa\u73af break # \u5982\u679c\u5df2\u627e\u5230\u8d1f\u6570\uff0c\u7ec8\u6b62\u5916\u5c42\u5faa\u73af if self . data [ row ][ col ] < 0 : break # \u8fd4\u56de\u8d1f\u6570\u7684\u4f4d\u7f6e\uff0c\u6216\u8005\u5982\u679c\u6ca1\u6709\u627e\u5230\u8d1f\u6570\uff0c\u8fd4\u56de\u884c\u6570\u548c\u5217\u6570 return row , col import random def main (): my_grid = Grid ( 5 , 5 , random . randint ( - 10 , 10 )) print ( my_grid ) print ( my_grid . find_negative ()) 4\uff0e\u8bf4\u8bf4\u8fd0\u884c\u4e0b\u9762\u8fd9\u6bb5\u4ee3\u7801\u540e\u7f51\u683c\u91cc\u7684\u5185\u5bb9\u662f\u4ec0\u4e48\u3002 matrix = Grid ( 3 , 3 ) for row in range ( matrix . getHeight ()): for column in range ( matrix . getWidth ()): matrix [ row ][ column ] = row * column \u89e3\u7b54\uff1a\u8fd9\u6bb5\u4ee3\u7801\u9996\u5148\u521b\u5efa\u4e86\u4e00\u4e2a3x3\u7684\u7f51\u683c\uff08\u6216\u4e8c\u7ef4\u6570\u7ec4\uff09\uff0c\u7136\u540e\u4f7f\u7528\u4e24\u4e2a\u5d4c\u5957\u7684for\u5faa\u73af\u6765\u904d\u5386\u8fd9\u4e2a\u7f51\u683c\u7684\u6bcf\u4e00\u4e2a\u5143\u7d20\u3002\u5bf9\u4e8e\u7f51\u683c\u4e2d\u7684\u6bcf\u4e00\u4e2a\u5143\u7d20\uff0c\u5b83\u7684\u503c\u88ab\u8bbe\u7f6e\u4e3a\u5176\u884c\u7d22\u5f15\u4e58\u4ee5\u5217\u7d22\u5f15\u3002\u7531\u4e8e\u7b2c\u4e00\u884c\u548c\u7b2c\u4e00\u5217\u7684\u7d22\u5f15\u90fd\u662f0\uff0c\u6240\u4ee5\u7b2c\u4e00\u884c\u548c\u7b2c\u4e00\u5217\u7684\u5143\u7d20\u503c\u90fd\u662f0\uff08\u56e0\u4e3a\u4efb\u4f55\u6570\u4e58\u4ee50\u90fd\u7b49\u4e8e0\uff09\u3002\u5176\u5b83\u5143\u7d20\u7684\u503c\u7b49\u4e8e\u5b83\u4eec\u7684\u884c\u7d22\u5f15\u4e58\u4ee5\u5217\u7d22\u5f15\u3002 0 0 0 0 1 2 0 2 4 5\uff0e\u7f16\u5199\u4e00\u6bb5\u4ee3\u7801\u4ee5\u521b\u5efa\u4e00\u4e2a\u53c2\u5dee\u4e0d\u9f50\u7684\u7f51\u683c\uff0c\u5b83\u7684\u884c\u5206\u522b\u7528\u6765\u5b58\u50a83\u4e2a\u30016\u4e2a\u548c9\u4e2a\u5143\u7d20\u3002 \u89e3\u7b54\uff1a\u4f7f\u7528\u5217\u8868\u7684\u5217\u8868\uff08\u5373\u5217\u8868\u7684\u5d4c\u5957\uff09\u6765\u521b\u5efa\u53c2\u5dee\u4e0d\u9f50\u7684\u7f51\u683c\u3002\u4e0b\u9762\u662fPython\u5b9e\u73b0\u4ee3\u7801\uff1a # \u521b\u5efa\u7a7a\u7f51\u683c grid = [] # \u4e3a\u7f51\u683c\u6dfb\u52a0\u884c grid . append ([ \"\" ] * 3 ) # \u7b2c\u4e00\u884c3\u4e2a\u5143\u7d20 grid . append ([ \"\" ] * 6 ) # \u7b2c\u4e8c\u884c6\u4e2a\u5143\u7d20 grid . append ([ \"\" ] * 9 ) # \u7b2c\u4e09\u884c9\u4e2a\u5143\u7d20 # \u6253\u5370\u7f51\u683c for row in grid : print ( row ) \u4e0a\u9762\u4ee3\u7801\u521b\u5efa\u4e00\u4e2a\u5177\u6709\u4e09\u884c\u7684\u7f51\u683c\uff0c\u5176\u4e2d\u7b2c\u4e00\u884c\u6709\u4e09\u4e2a\u5143\u7d20\uff0c\u7b2c\u4e8c\u884c\u6709\u516d\u4e2a\u5143\u7d20\uff0c\u7b2c\u4e09\u884c\u6709\u4e5d\u4e2a\u5143\u7d20\u3002\u6bcf\u4e2a\u5143\u7d20\u6700\u521d\u90fd\u88ab\u8bbe\u7f6e\u4e3a\u4e00\u4e2a\u7a7a\u5b57\u7b26\u4e32\uff0c\u8fd9\u4e2a\u7f51\u683c\u7684\u5f62\u72b6\u5c06\u7c7b\u4f3c\u4e8e\uff1a [ '' , '' , '' ] [ '' , '' , '' , '' , '' , '' ] [ '' , '' , '' , '' , '' , '' , '' , '' , '' ] 6\uff0e\u63d0\u4f9b\u4e00\u4e2a\u628aGrid\u7c7b\u7528\u4f5c\u6570\u636e\u7ed3\u6784\u6765\u5b9e\u73b0\u4e09\u7ef4array\u7c7b\u7684\u7b56\u7565\u3002 \u89e3\u7b54\uff1a\u4ee3\u7801\u5b9e\u73b0\u5982\u4e0b\uff1a class ThreeDArray ( object ): \"\"\"\u63cf\u8ff0\u4e00\u4e2a\u4e09\u7ef4\u6570\u7ec4\u3002\"\"\" def __init__ ( self , depth , rows , columns , fillValue = None ): self . depth = depth self . rows = rows self . columns = columns self . fillValue = fillValue # \u521d\u59cb\u5316\u4e09\u7ef4\u6570\u7ec4\uff0c\u6309\u7167\u6df1\u5ea6\u521d\u59cb\u5316\u6bcf\u4e00\u5c42\u4e3a\u4e00\u4e2a\u4e8c\u7ef4\u6570\u7ec4 self . data = Array ( depth , fillValue ) for d in range ( depth ): self . data [ d ] = Grid ( rows , columns , fillValue ) def getDepth ( self ): \"\"\"\u8fd4\u56de\u4e09\u7ef4\u6570\u7ec4\u7684z\u8f74\u5927\u5c0f, \u5373\u6570\u7ec4\u7684\u6df1\u5ea6\"\"\" return len ( self . data ) def get_element ( self , depth , row , column ): \"\"\"\u83b7\u53d6\u6307\u5b9a\u6df1\u5ea6\u3001\u884c\u548c\u5217\u7684\u5143\u7d20\"\"\" return self . data [ depth ][ row ][ column ] def set_element ( self , depth , row , column , new_value ): \"\"\"\u8bbe\u7f6e\u6307\u5b9a\u6df1\u5ea6\u3001\u884c\u548c\u5217\u7684\u5143\u7d20\"\"\" self . data [ depth ][ row ][ column ] = new_value def add_element ( self , depth , row , column , value ): \"\"\"\u5728\u6307\u5b9a\u6df1\u5ea6\u3001\u884c\u548c\u5217\u6dfb\u52a0\u5143\u7d20 \"\"\" if self . data [ depth ][ row ][ column ] == self . fillValue : self . data [ depth ][ row ][ column ] = value else : raise Exception ( \"\u5143\u7d20\u6dfb\u52a0\u5931\u8d25\" ) def remove_element ( self , depth , row , column ): \"\"\"\u5728\u6307\u5b9a\u6df1\u5ea6\u3001\u884c\u548c\u5217\u5220\u9664\u5143\u7d20 \"\"\" if self . data [ depth ][ row ][ column ] != self . fillValue : self . data [ depth ][ row ][ column ] = self . fillValue else : raise Exception ( \"\u5143\u7d20\u5220\u9664\u5931\u8d25\" ) def __str__ ( self ): result = \"\" for depth in range ( self . getDepth ()): result += f \"Depth { depth } : \\n \" for row in range ( self . rows ): for column in range ( self . columns ): result += str ( self . data [ depth ][ row ][ column ]) + \" \\t \" result += \" \\n \" return result def main (): print ( \"---Initial 3D Array---\" ) my_3d = ThreeDArray ( 3 , 2 , 2 , 9 ) print ( my_3d ) print ( \"---Add element into 3D Array---\" ) my_3d . add_element ( 0 , 1 , 1 , 0 ) my_3d . add_element ( 1 , 1 , 1 , 1 ) my_3d . add_element ( 2 , 1 , 1 , 2 ) print ( my_3d ) print ( \"---Remove element from 3D Array---\" ) my_3d . remove_element ( 1 , 1 , 1 ) print ( my_3d ) if __name__ == \"__main__\" : main () # \u8fd0\u884c\u7ed3\u679c # ---Initial 3D Array--- # Depth 0: # 9 9 # 9 9 # Depth 1: # 9 9 # 9 9 # Depth 2: # 9 9 # 9 9 # ---Add element into 3D Array--- # Depth 0: # 9 9 # 9 0 # Depth 1: # 9 9 # 9 1 # Depth 2: # 9 9 # 9 2 # ---Remove element from 3D Array--- # Depth 0: # 9 9 # 9 0 # Depth 1: # 9 9 # 9 9 # Depth 2: # 9 9 # 9 2 7\uff0e\u7f16\u5199\u4e00\u6bb5\u4ee3\u7801\uff1a\u8fd9\u6bb5\u4ee3\u7801\u4f1a\u628a\u4e09\u7ef4\u6570\u7ec4\u91cc\u6bcf\u4e2a\u5355\u5143\u7684\u503c\u90fd\u521d\u59cb\u5316\u4e3a\u5b83\u76843\u4e2a\u7d22\u5f15\u4f4d\u7f6e\u3002\u4f8b\u5982\uff0c\u5982\u679c\u4f4d\u7f6e\u662f\uff08\u6df1\u5ea6\u3001\u884c\u3001\u5217\uff09\uff0c\u5219\u5bf9\u4e8e\u4f4d\u7f6e\uff082\u30013\u30013\uff09\u6765\u8bf4\uff0c\u5b83\u7684\u503c\u5c31\u662f233\u3002 \u89e3\u7b54\uff1a\u4fee\u6539\u4e0a\u9762\u7684\u4ee3\u7801\u4e2d\u7684 __init__ \u548c __str__ \u65b9\u6cd5\uff0c\u4ee3\u7801\u5b9e\u73b0\u5982\u4e0b\u3002 class ThreeDArray ( object ): \"\"\"\u63cf\u8ff0\u4e00\u4e2a\u4e09\u7ef4\u6570\u7ec4\u3002\"\"\" # def __init__(self, depth, rows, columns, fillValue=None): # self.depth = depth # self.rows = rows # self.columns = columns # self.fillValue = fillValue # # \u521d\u59cb\u5316\u4e09\u7ef4\u6570\u7ec4\uff0c\u6309\u7167\u6df1\u5ea6\u521d\u59cb\u5316\u6bcf\u4e00\u5c42\u4e3a\u4e00\u4e2a\u4e8c\u7ef4\u6570\u7ec4 # self.data = Array(depth, fillValue) # for d in range(depth): # self.data[d] = Grid(rows, columns, fillValue) def __init__ ( self , depth , rows , columns ): self . depth = depth self . rows = rows self . columns = columns # \u521d\u59cb\u5316\u4e09\u7ef4\u6570\u7ec4\uff0c\u6309\u7167\u6df1\u5ea6\u521d\u59cb\u5316\u6bcf\u4e00\u5c42\u4e3a\u4e00\u4e2a\u4e8c\u7ef4\u6570\u7ec4 self . data = Array ( depth ) for d in range ( depth ): self . data [ d ] = Grid ( rows , columns ) for r in range ( rows ): for c in range ( columns ): # \u5c06\u6bcf\u4e2a\u4f4d\u7f6e\u7684\u7d22\u5f15\u62fc\u63a5\u6210\u5b57\u7b26\u4e32\u4f5c\u4e3a\u5143\u7d20\u503c self . data [ d ][ r ][ c ] = str ( d ) + str ( r ) + str ( c ) def getDepth ( self ): \"\"\"\u8fd4\u56de\u4e09\u7ef4\u6570\u7ec4\u7684z\u8f74\u5927\u5c0f, \u5373\u6570\u7ec4\u7684\u6df1\u5ea6\"\"\" return len ( self . data ) def get_element ( self , depth , row , column ): \"\"\"\u83b7\u53d6\u6307\u5b9a\u6df1\u5ea6\u3001\u884c\u548c\u5217\u7684\u5143\u7d20\"\"\" return self . data [ depth ][ row ][ column ] def set_element ( self , depth , row , column , new_value ): \"\"\"\u8bbe\u7f6e\u6307\u5b9a\u6df1\u5ea6\u3001\u884c\u548c\u5217\u7684\u5143\u7d20\"\"\" self . data [ depth ][ row ][ column ] = new_value def add_element ( self , depth , row , column , value ): \"\"\"\u5728\u6307\u5b9a\u6df1\u5ea6\u3001\u884c\u548c\u5217\u6dfb\u52a0\u5143\u7d20 \"\"\" if self . data [ depth ][ row ][ column ] == self . fillValue : self . data [ depth ][ row ][ column ] = value else : raise Exception ( \"\u5143\u7d20\u6dfb\u52a0\u5931\u8d25\" ) def remove_element ( self , depth , row , column ): \"\"\"\u5728\u6307\u5b9a\u6df1\u5ea6\u3001\u884c\u548c\u5217\u5220\u9664\u5143\u7d20 \"\"\" if self . data [ depth ][ row ][ column ] != self . fillValue : self . data [ depth ][ row ][ column ] = self . fillValue else : raise Exception ( \"\u5143\u7d20\u5220\u9664\u5931\u8d25\" ) # def __str__(self): # result = \"\" # for depth in range(self.getDepth()): # result += f\"Depth {depth}:\\n\" # for row in range(self.rows): # for column in range(self.columns): # result += str(self.data[depth][row][column]) + \"\\t\" # result += \"\\n\" # return result def __str__ ( self ): result = \"\" for depth in range ( self . getDepth ()): result += f \"Depth { depth } : \\n \" for row in range ( self . rows ): for column in range ( self . columns ): result += str ( self . data [ depth ][ row ][ column ]) + \" \\t \" result += \" \\n \" return result def main (): my_3d = ThreeDArray ( 3 , 4 , 4 ) print ( my_3d ) # \u6253\u5370\u521d\u59cb\u72b6\u6001 if __name__ == \"__main__\" : main () # \u8fd0\u884c\u7ed3\u679c # Depth 0: # 000 001 002 003 # 010 011 012 013 # 020 021 022 023 # 030 031 032 033 # Depth 1: # 100 101 102 103 # 110 111 112 113 # 120 121 122 123 # 130 131 132 133 # Depth 2: # 200 201 202 203 # 210 211 212 213 # 220 221 222 223 # 230 231 232 233 8\uff0e\u7f16\u5199\u4e00\u6bb5\u4ee3\u7801\uff1a\u8fd9\u6bb5\u4ee3\u7801\u53ef\u4ee5\u663e\u793a\u51fa\u4e09\u7ef4\u6570\u7ec4\u91cc\u7684\u6240\u6709\u5143\u7d20\u3002\u6253\u5370\u51fa\u7684\u6bcf\u4e00\u884c\u6570\u636e\u90fd\u5e94\u8be5\u4ee3\u8868\u7ed9\u5b9a\u884c\u548c\u5217\u91cc\u7684\u6240\u6709\u5143\u7d20\uff0c\u800c\u6df1\u5ea6\u5c06\u4ece\u7b2c\u4e00\u4e2a\u4f4d\u7f6e\u5411\u540e\u9012\u5f52\u5230\u6700\u540e\u4e00\u4e2a\u4f4d\u7f6e\u3002\u904d\u5386\u5e94\u8be5\u4ece\u7b2c1\u884c\u3001\u7b2c1\u5217\u4ee5\u53ca\u7b2c\u4e00\u4e2a\u6df1\u5ea6\u4f4d\u7f6e\u5f00\u59cb\uff0c\u4f9d\u6b21\u904d\u5386\u6240\u6709\u7684\u6df1\u5ea6\u3001\u5217\u548c\u884c\u3002 \u89e3\u7b54\uff1a\u6dfb\u52a0\u4e86\u4e00\u4e2a\u65b9\u6cd5 printAllElements \uff0c\u4ee3\u7801\u5b9e\u73b0\u5982\u4e0b\uff1a class ThreeDArray ( object ): \"\"\"\u63cf\u8ff0\u4e00\u4e2a\u4e09\u7ef4\u6570\u7ec4\u3002\"\"\" # def __init__(self, depth, rows, columns, fillValue=None): # self.depth = depth # self.rows = rows # self.columns = columns # self.fillValue = fillValue # # \u521d\u59cb\u5316\u4e09\u7ef4\u6570\u7ec4\uff0c\u6309\u7167\u6df1\u5ea6\u521d\u59cb\u5316\u6bcf\u4e00\u5c42\u4e3a\u4e00\u4e2a\u4e8c\u7ef4\u6570\u7ec4 # self.data = Array(depth, fillValue) # for d in range(depth): # self.data[d] = Grid(rows, columns, fillValue) def __init__ ( self , depth , rows , columns ): self . depth = depth self . rows = rows self . columns = columns # \u521d\u59cb\u5316\u4e09\u7ef4\u6570\u7ec4\uff0c\u6309\u7167\u6df1\u5ea6\u521d\u59cb\u5316\u6bcf\u4e00\u5c42\u4e3a\u4e00\u4e2a\u4e8c\u7ef4\u6570\u7ec4 self . data = Array ( depth ) for d in range ( depth ): self . data [ d ] = Grid ( rows , columns ) for r in range ( rows ): for c in range ( columns ): # \u5c06\u6bcf\u4e2a\u4f4d\u7f6e\u7684\u7d22\u5f15\u62fc\u63a5\u6210\u5b57\u7b26\u4e32\u4f5c\u4e3a\u5143\u7d20\u503c self . data [ d ][ r ][ c ] = str ( d ) + str ( r ) + str ( c ) def getDepth ( self ): \"\"\"\u8fd4\u56de\u4e09\u7ef4\u6570\u7ec4\u7684z\u8f74\u5927\u5c0f, \u5373\u6570\u7ec4\u7684\u6df1\u5ea6\"\"\" return len ( self . data ) def get_element ( self , depth , row , column ): \"\"\"\u83b7\u53d6\u6307\u5b9a\u6df1\u5ea6\u3001\u884c\u548c\u5217\u7684\u5143\u7d20\"\"\" return self . data [ depth ][ row ][ column ] def set_element ( self , depth , row , column , new_value ): \"\"\"\u8bbe\u7f6e\u6307\u5b9a\u6df1\u5ea6\u3001\u884c\u548c\u5217\u7684\u5143\u7d20\"\"\" self . data [ depth ][ row ][ column ] = new_value def add_element ( self , depth , row , column , value ): \"\"\"\u5728\u6307\u5b9a\u6df1\u5ea6\u3001\u884c\u548c\u5217\u6dfb\u52a0\u5143\u7d20 \"\"\" if self . data [ depth ][ row ][ column ] == self . fillValue : self . data [ depth ][ row ][ column ] = value else : raise Exception ( \"\u5143\u7d20\u6dfb\u52a0\u5931\u8d25\" ) def remove_element ( self , depth , row , column ): \"\"\"\u5728\u6307\u5b9a\u6df1\u5ea6\u3001\u884c\u548c\u5217\u5220\u9664\u5143\u7d20 \"\"\" if self . data [ depth ][ row ][ column ] != self . fillValue : self . data [ depth ][ row ][ column ] = self . fillValue else : raise Exception ( \"\u5143\u7d20\u5220\u9664\u5931\u8d25\" ) def printAllElements ( self ): \"\"\"\u6253\u5370\u4e09\u7ef4\u6570\u7ec4\u4e2d\u7684\u6240\u6709\u5143\u7d20\u3002\"\"\" for row in range ( self . rows ): for col in range ( self . columns ): for depth in range ( self . depth ): print ( f \"Element at position ( { row } , { col } , { depth } ): { self . data [ depth ][ row ][ col ] } \" ) # def __str__(self): # result = \"\" # for depth in range(self.getDepth()): # result += f\"Depth {depth}:\\n\" # for row in range(self.rows): # for column in range(self.columns): # result += str(self.data[depth][row][column]) + \"\\t\" # result += \"\\n\" # return result def __str__ ( self ): result = \"\" for depth in range ( self . getDepth ()): result += f \"Depth { depth } : \\n \" for row in range ( self . rows ): for column in range ( self . columns ): result += str ( self . data [ depth ][ row ][ column ]) + \" \\t \" result += \" \\n \" return result def main (): my_3d = ThreeDArray ( 3 , 4 , 4 ) print ( my_3d ) # \u6253\u5370\u521d\u59cb\u72b6\u6001 my_3d . printAllElements () if __name__ == \"__main__\" : main () # \u8fd0\u884c\u7ed3\u679c # Depth 0: # 000 001 002 003 # 010 011 012 013 # 020 021 022 023 # 030 031 032 033 # Depth 1: # 100 101 102 103 # 110 111 112 113 # 120 121 122 123 # 130 131 132 133 # Depth 2: # 200 201 202 203 # 210 211 212 213 # 220 221 222 223 # 230 231 232 233 # Element at position (0, 0, 0): 000 # Element at position (0, 0, 1): 100 # Element at position (0, 0, 2): 200 # Element at position (0, 1, 0): 001 # Element at position (0, 1, 1): 101 # Element at position (0, 1, 2): 201 # Element at position (0, 2, 0): 002 # Element at position (0, 2, 1): 102 # Element at position (0, 2, 2): 202 # Element at position (0, 3, 0): 003 # Element at position (0, 3, 1): 103 # Element at position (0, 3, 2): 203 # Element at position (1, 0, 0): 010 # Element at position (1, 0, 1): 110 # Element at position (1, 0, 2): 210 # Element at position (1, 1, 0): 011 # Element at position (1, 1, 1): 111 # Element at position (1, 1, 2): 211 # Element at position (1, 2, 0): 012 # Element at position (1, 2, 1): 112 # Element at position (1, 2, 2): 212 # Element at position (1, 3, 0): 013 # Element at position (1, 3, 1): 113 # Element at position (1, 3, 2): 213 # Element at position (2, 0, 0): 020 # Element at position (2, 0, 1): 120 # Element at position (2, 0, 2): 220 # Element at position (2, 1, 0): 021 # Element at position (2, 1, 1): 121 # Element at position (2, 1, 2): 221 # Element at position (2, 2, 0): 022 # Element at position (2, 2, 1): 122 # Element at position (2, 2, 2): 222 # Element at position (2, 3, 0): 023 # Element at position (2, 3, 1): 123 # Element at position (2, 3, 2): 223 # Element at position (3, 0, 0): 030 # Element at position (3, 0, 1): 130 # Element at position (3, 0, 2): 230 # Element at position (3, 1, 0): 031 # Element at position (3, 1, 1): 131 # Element at position (3, 1, 2): 231 # Element at position (3, 2, 0): 032 # Element at position (3, 2, 1): 132 # Element at position (3, 2, 2): 232 # Element at position (3, 3, 0): 033 # Element at position (3, 3, 1): 133 # Element at position (3, 3, 2): 233 4.4.\u94fe\u63a5\u7ed3\u6784 \u00b6 \u94fe\u63a5\u7ed3\u6784\u4f5c\u4e3a\u4e00\u79cd\u6570\u636e\u7c7b\u578b\uff0c\u53ef\u4ee5\u7528\u6765\u5b9e\u73b0\u82e5\u5e72\u7c7b\u578b\u7684\u591a\u9879\u96c6\uff08\u5305\u62ec\u5217\u8868\uff09\u3002 \u76ee\u6807\uff1a\u5728\u4f7f\u7528\u94fe\u63a5\u7ed3\u6784\u5b9e\u73b0\u4efb\u4f55\u7c7b\u578b\u7684\u591a\u9879\u96c6\u65f6\u6240\u5fc5\u987b\u8981\u77e5\u9053\u7684\u51e0\u4e2a\u7279\u5f81\uff0c\u4ee5\u53ca\u5982\u4f55\u5728\u591a\u9879\u96c6\uff08\u5982\u5217\u8868\u548c\u4e8c\u53c9\u6811\uff09\u91cc\u4f7f\u7528\u94fe\u63a5\u7ed3\u6784\u3002 4.4.1.\u5355\u5411\u94fe\u63a5\u7ed3\u6784\u548c\u53cc\u5411\u94fe\u63a5\u7ed3\u6784 \u00b6 \u94fe\u63a5\u7ed3\u6784\u7531\u53ef\u4ee5\u94fe\u63a5\u5230\u5176\u4ed6\u8282\u70b9\u7684\u8282\u70b9\u7ec4\u6210\u3002 \u8282\u70b9\u4e4b\u95f4\u6700\u7b80\u5355\u7684\u94fe\u63a5\u7ed3\u6784\u662f\uff1a \u5355\u5411\u94fe\u63a5\u7ed3\u6784\uff08singly linked structure\uff09 \u53cc\u5411\u94fe\u63a5\u7ed3\u6784\uff08doubly linked structure\uff09 \u4e0b\u9762\u56fe\u4f8b\u662f\u7528\u6846\u548c\u6307\u9488\u7b26\u53f7\u7ed8\u51fa\u5355\u5411\u548c\u53cc\u5411\u94fe\u63a5\u7ed3\u6784\u3002 \u901a\u8fc7\u4e00\u4e2a\u989d\u5916\u7684\u5934\u90e8\u94fe\u63a5\uff08head link\uff09\uff0c\u53ef\u4ee5\u4f7f\u7528\u5355\u5411\u94fe\u63a5\u7ed3\u6784\u8bbf\u95ee\u7b2c\u4e00\u4e2a\u8282\u70b9\u3002\u63a5\u4e0b\u6765\uff0c\u6211\u4eec\u5c31\u53ef\u4ee5\u901a\u8fc7\u8fd9\u4e2a\u8282\u70b9\u91cc\u53d1\u51fa\u7684\u94fe\u63a5\uff08\u4e0a\u56fe\u4e2d\u7684\u7bad\u5934\uff09\u6765\u8bbf\u95ee\u5176\u4ed6\u8282\u70b9\u4e86\u3002\u56e0\u6b64\uff0c\u5728\u5355\u5411\u94fe\u63a5\u7ed3\u6784\u91cc\uff0c\u6211\u4eec\u53ef\u4ee5\u5f88\u5bb9\u6613\u5730\u83b7\u5f97\u8282\u70b9\u7684\u540e\u7ee7\u8282\u70b9\uff0c\u4f46\u4e0d\u90a3\u4e48\u5bb9\u6613\u83b7\u5f97\u8282\u70b9\u7684\u524d\u5e8f\u8282\u70b9\u3002 \u53cc\u5411\u94fe\u63a5\u7ed3\u6784\u4f1a\u5305\u542b\u53cc\u5411\u7684\u94fe\u63a5\uff0c\u6211\u4eec\u53ef\u4ee5\u5f88\u5bb9\u6613\u5730\u79fb\u52a8\u5230\u8282\u70b9\u7684\u524d\u5e8f\u6216\u8005\u540e\u7ee7\u8282\u70b9\uff0c\u8fd9\u4e2a\u65f6\u5019\u4f1a\u7528\u5230\u7b2c\u4e8c\u4e2a\u989d\u5916\u7684\u94fe\u63a5\uff08\u5c3e\u90e8\u94fe\u63a5tail link\uff09\u3002\u5c3e\u90e8\u94fe\u63a5\u80fd\u591f\u8ba9\u53cc\u5411\u94fe\u63a5\u7ed3\u6784\u7684\u7528\u6237\u76f4\u63a5\u8bbf\u95ee\u6700\u540e\u4e00\u4e2a\u8282\u70b9\u3002 \u5728\u4e24\u79cd\u94fe\u63a5\u7ed3\u6784\u91cc\uff0c\u6700\u540e\u4e00\u4e2a\u8282\u70b9\u90fd\u6ca1\u6709\u6307\u5411\u540e\u7eed\u8282\u70b9\u7684\u94fe\u63a5\u3002\u5728\u4e0a\u56fe\u4e2d\uff0c\u7528\u659c\u6760\u4ee3\u66ff\u7bad\u5934\u4ee5\u8868\u793a\u6ca1\u6709\u94fe\u63a5\uff0c\u8fd9\u79f0\u4e3a\u7a7a\u94fe\u63a5\uff08empty link\uff09\u3002 \u5728\u53cc\u5411\u94fe\u63a5\u7ed3\u6784\u91cc\uff0c\u7b2c\u4e00\u4e2a\u8282\u70b9\u4e5f\u6ca1\u6709\u6307\u5411\u524d\u5e8f\u8282\u70b9\u7684\u94fe\u63a5\u3002 \u548c\u6570\u7ec4\u4e00\u6837\uff0c\u94fe\u63a5\u7ed3\u6784\u4e5f\u53ef\u4ee5\u7528\u6765\u5b58\u50a8\u5143\u7d20\u7684\u7ebf\u6027\u5e8f\u5217\uff0c\u4f46\u65e0\u6cd5\u901a\u8fc7\u6307\u5b9a\u7684\u7d22\u5f15\u4f4d\u7f6e\u76f4\u63a5\u8bbf\u95ee\u8fd9\u4e2a\u5143\u7d20\uff0c\u5fc5\u987b\u4ece\u6570\u636e\u7ed3\u6784\u7684\u4e00\u4e2a\u9876\u7aef\u5f00\u59cb\uff0c\u7136\u540e\u6309\u7167\u94fe\u63a5\u8fdb\u884c\u8bbf\u95ee\uff0c\u76f4\u81f3\u5230\u8fbe\u6240\u9700\u7684\u4f4d\u7f6e\uff08\u6216\u627e\u5230\u671f\u671b\u7684\u5143\u7d20\uff09\u4e3a\u6b62\u3002\u94fe\u63a5\u7ed3\u6784\u7684\u8fd9\u79cd\u6027\u8d28\u5bf9\u4e8e\u5f88\u591a\u64cd\u4f5c\u90fd\u6709\u663e\u8457\u7684\u5f71\u54cd\u3002 \u4e3a\u94fe\u63a5\u7ed3\u6784\u5206\u914d\u5185\u5b58\u7684\u65b9\u5f0f\u548c\u4e3a\u6570\u7ec4\u5206\u914d\u5185\u5b58\u7684\u65b9\u5f0f\u662f\u5b8c\u5168\u4e0d\u540c\u7684\uff0c\u800c\u4e14\u5bf9\u4e8e\u63d2\u5165\u548c\u5220\u9664\u64cd\u4f5c\u6765\u8bf4\uff0c\u6709\u4e24\u4e2a\u663e\u8457\u5f71\u54cd\u3002 \u5728\u627e\u5230\u63d2\u5165\u6216\u5220\u9664\u70b9\u4e4b\u540e\uff0c\u53ef\u4ee5\u5728\u4e0d\u79fb\u52a8\u5185\u5b58\u91cc\u7684\u6570\u636e\u5143\u7d20\u7684\u60c5\u51b5\u4e0b\u6267\u884c\u63d2\u5165\u6216\u5220\u9664\u64cd\u4f5c\u3002 \u53ef\u4ee5\u5728\u6bcf\u6b21\u63d2\u5165\u6216\u5220\u9664\u671f\u95f4\u81ea\u52a8\u8c03\u6574\u94fe\u63a5\u7ed3\u6784\u7684\u5927\u5c0f\uff0c\u4e0d\u9700\u8981\u82b1\u8d39\u989d\u5916\u7684\u5185\u5b58\u7a7a\u95f4\uff0c\u4e5f\u4e0d\u9700\u8981\u590d\u5236\u6570\u636e\u5143\u7d20\u3002 4.4.2.\u975e\u8fde\u7eed\u5185\u5b58\u548c\u8282\u70b9 \u00b6 \u6570\u7ec4\u91cc\u7684\u5143\u7d20\u5fc5\u987b\u5b58\u50a8\u5728\u4e00\u6bb5\u8fde\u7eed\u7684\u5185\u5b58\u4e2d\uff0c\u8fd9\u5c31\u610f\u5473\u7740\u6570\u7ec4\u91cc\u5404\u4e2a\u5143\u7d20\u7684\u903b\u8f91\u987a\u5e8f\u548c\u5b83\u4eec\u5728\u5185\u5b58\u5355\u5143\u91cc\u7684\u7269\u7406\u987a\u5e8f\u662f\u7d27\u5bc6\u8026\u5408\u7684\u3002 \u76f8\u6bd4\u800c\u8a00\uff0c\u94fe\u63a5\u7ed3\u6784\u4f1a\u628a\u7ed3\u6784\u91cc\u5404\u4e2a\u5143\u7d20\u7684\u903b\u8f91\u987a\u5e8f\u548c\u5b83\u4eec\u5728\u5185\u5b58\u91cc\u7684\u987a\u5e8f\u89e3\u8026\u3002\u8981\u5728\u5185\u5b58\u7684\u67d0\u4e2a\u4f4d\u7f6e\u4e0a\u627e\u5230\u94fe\u63a5\u7ed3\u6784\u91cc\u7279\u5b9a\u5143\u7d20\u7684\u5185\u5b58\u5355\u5143\uff0c\u53ea\u9700\u8981\u8ba9\u8ba1\u7b97\u673a\u8ddf\u968f\u6307\u5411\u8fd9\u4e2a\u5143\u7d20\u7684\u5730\u5740\u6216\u4f4d\u7f6e\u94fe\u63a5\u5c31\u884c\u4e86\u3002\u8fd9\u79f0\u4e3a\u975e\u8fde\u7eed\u5185\u5b58\uff08noncontiguous memory\uff09\u3002 \u94fe\u63a5\u7ed3\u6784\u91cc\u7528\u6765\u5b58\u50a8\u7684\u57fa\u672c\u5355\u4f4d\u662f\u8282\u70b9\uff08node\uff09\u3002 \u5355\u5411\u94fe\u63a5\u8282\u70b9\uff08singly linked node\uff09\u5305\u542b\u4e0b\u9762\u8fd9\u4e9b\u7ec4\u4ef6\u6216\u5b57\u6bb5\uff1a \u6570\u636e\u5143\u7d20\uff1b \u6307\u5411\u7ed3\u6784\u91cc\u540e\u7ee7\u8282\u70b9\u7684\u94fe\u63a5\uff1b \u5bf9\u4e8e\u53cc\u5411\u94fe\u63a5\u8282\u70b9\uff08doubly linked node\uff09\u5305\u542b\u4e0b\u9762\u8fd9\u4e9b\u7ec4\u4ef6\u6216\u5b57\u6bb5\uff1a \u6570\u636e\u5143\u7d20\uff1b \u6307\u5411\u7ed3\u6784\u91cc\u540e\u7ee7\u8282\u70b9\u7684\u94fe\u63a5\uff1b \u6307\u5411\u7ed3\u6784\u91cc\u524d\u5e8f\u8282\u70b9\u7684\u94fe\u63a5\uff1b \u4e0d\u540c\u7684\u7f16\u7a0b\u8bed\u8a00\uff0c\u901a\u8fc7\u4e0d\u540c\u7684\u65b9\u6cd5\u6765\u8ba9\u8282\u70b9\u5229\u7528\u975e\u8fde\u7eed\u5185\u5b58\u3002 FORTRAN\u8bed\u8a00\u4e2d\uff0c\u901a\u8fc7\u4e24\u4e2a\u5e76\u6392\u7684\u6570\u7ec4\u4e3a\u5355\u5411\u94fe\u63a5\u7ed3\u6784\u5b9e\u73b0\u975e\u8fde\u7eed\u5185\u5b58\u548c\u8282\u70b9\u3002\u8fd9\u6837\u505a\u53ef\u4ee5\u6709\u6548\u5730\u5c06\u94fe\u63a5\u7ed3\u6784\u91cc\u6570\u636e\u5143\u7d20\u7684\u903b\u8f91\u4f4d\u7f6e\u548c\u5b83\u5728\u6570\u7ec4\u91cc\u7684\u7269\u7406\u4f4d\u7f6e\u5206\u79bb\u3002 \u7b2c\u4e00\u4e2a\u6570\u7ec4\u5305\u542b\u6570\u636e\u5143\u7d20\uff1b\u7b2c\u4e8c\u4e2a\u6570\u7ec4\u5219\u5305\u542b\u6570\u636e\u6570\u7ec4\u91cc\u5f53\u524d\u8282\u70b9\u6240\u5bf9\u5e94\u7684\u540e\u7eed\u8282\u70b9\u7684\u7d22\u5f15\u4f4d\u7f6e\u3002 \u7528\u7b2c\u4e00\u4e2a\u6570\u7ec4\u91cc\u7684\u6570\u636e\u5143\u7d20\u7d22\u5f15\u6765\u8bbf\u95ee\u7b2c\u4e8c\u4e2a\u6570\u7ec4\u91cc\u7684\u503c\uff0c\u7136\u540e\u518d\u628a\u8fd9\u4e2a\u503c\u4f5c\u4e3a\u7b2c\u4e00\u4e2a\u6570\u7ec4\u91cc\u4e0b\u4e00\u4e2a\u6570\u636e\u5143\u7d20\u7684\u7d22\u5f15\u3002\u7a7a\u94fe\u63a5\u4f1a\u7528\u503c\u22121\u6765\u8868\u793a\u3002 Pascal\u548cC++\u8bed\u8a00\u4e2d\uff0c\u901a\u8fc7\u8bbf\u95ee\u6307\u9488\uff08pointer\uff09\u76f4\u63a5\u5f97\u5230\u6240\u9700\u7684\u6570\u636e\u5730\u5740\u3002 \u5355\u5411\u94fe\u63a5\u7ed3\u6784\u91cc\u7684\u8282\u70b9\u5305\u542b\u4e00\u4e2a\u6570\u636e\u5143\u7d20\u548c\u4e00\u4e2a\u6307\u9488\u503c\u3002\u5bf9\u4e8e\u7a7a\u94fe\u63a5\u6765\u8bf4\uff0c\u5b83\u7684\u6307\u9488\u503c\u7528\u7279\u6b8a\u503cnull\uff08\u6216nil\uff09\u6765\u8868\u793a\u3002 \u8bf7\u6c42\u4e00\u4e2a\u5bf9\u8c61\u5806\uff08object heap\uff09\u7684\u65b0\u8282\u70b9\u7684\u6307\u9488\uff0c\u8fd9\u4e2a\u8282\u70b9\u6765\u81ea\u975e\u8fde\u7eed\u5185\u5b58\u7684\u5185\u7f6e\u533a\u57df\uff0c\u5e76\u628a\u8fd9\u4e2a\u8282\u70b9\u91cc\u7684\u6307\u9488\u8bbe\u7f6e\u4e3a\u6307\u5411\u53e6\u4e00\u4e2a\u8282\u70b9\uff0c\u4ece\u800c\u5efa\u7acb\u5230\u8fd9\u4e2a\u94fe\u63a5\u7ed3\u6784\u91cc\u5176\u4ed6\u6570\u636e\u7684\u94fe\u63a5\u3002 \u901a\u8fc7\u663e\u5f0f\u5730\u4f7f\u7528\u6307\u9488\u548c\u5185\u7f6e\u5806\uff0c\u53ef\u4ee5\u4e0d\u518d\u9700\u8981\u7ba1\u7406\u975e\u8fde\u7eed\u5185\u5b58\u7684\u5e95\u5c42\u6570\u7ec4\u5b58\u50a8\u65b9\u5f0f\u4e86\uff0c\u4f46\u8fd8\u662f\u9700\u8981\u4eba\u4e3a\u7ba1\u7406\u5806\uff0c\u901a\u8fc7\u7279\u6b8a\u7684dispose\u6216delete\u64cd\u4f5c\u628a\u4e0d\u4f7f\u7528\u7684\u8282\u70b9\u8fd4\u56de\u7ed9\u5806\u3002 Python\u8bed\u8a00\u4e2d\uff0c\u901a\u8fc7\u4f7f\u7528\u5bf9\u5bf9\u8c61\u7684\u5f15\u7528\uff08reference\uff09\u8bbe\u7f6e\u8282\u70b9\u548c\u94fe\u63a5\u7ed3\u6784\u3002 Python\u4e2d\uff0c\u4efb\u4f55\u53d8\u91cf\u90fd\u53ef\u4ee5\u7528\u6765\u5f15\u7528\u4efb\u4f55\u6570\u636e\uff0c\u8fd9\u4e5f\u5305\u62ec\u503c None \uff0c\u5b83\u53ef\u4ee5\u7528\u6765\u4ee3\u8868\u7a7a\u94fe\u63a5\u3002 Python\u4e2d\uff0c\u5b9a\u4e49\u5305\u542b\u4e24\u4e2a\u5b57\u6bb5\u7684\u5bf9\u8c61\u6765\u5b9a\u4e49\u5355\u5411\u94fe\u63a5\u8282\u70b9\uff0c\u8fd9\u4e24\u4e2a\u5b57\u6bb5\u662f\u5bf9\u6570\u636e\u5143\u7d20\u7684\u5f15\u7528\u548c\u5bf9\u53e6\u4e00\u4e2a\u8282\u70b9\u7684\u5f15\u7528\u3002 Python\u4e2d\uff0c\u4e3a\u6bcf\u4e2a\u65b0\u7684\u8282\u70b9\u5bf9\u8c61\u63d0\u4f9b\u975e\u8fde\u7eed\u5185\u5b58\u7684\u52a8\u6001\u5206\u914d\uff0c\u5e76\u4e14\u5f53\u5e94\u7528\u7a0b\u5e8f\u4e0d\u518d\u5f15\u7528\u8fd9\u4e2a\u5bf9\u8c61\u7684\u65f6\u5019\uff0c\u5b83\u4f1a\u81ea\u52a8\u628a\u8fd9\u90e8\u5206\u5185\u5b58\u8fd4\u56de\u7ed9\u7cfb\u7edf\uff08\u5783\u573e\u56de\u6536\uff09\u3002 4.4.3.\u5b9a\u4e49\u5355\u5411\u94fe\u63a5\u8282\u70b9\u7c7b \u00b6 \u5355\u5411\u94fe\u63a5\u8282\u70b9\u53ea\u5305\u542b\u6570\u636e\u5143\u7d20\u548c\u5bf9\u4e0b\u4e00\u4e2a\u8282\u70b9\u7684\u5f15\u7528\u3002\u56e0\u4e3a\u8282\u70b9\u5bf9\u8c61\u7684\u7075\u6d3b\u6027\u548c\u6613\u7528\u6027\u975e\u5e38\u91cd\u8981\uff0c\u6240\u4ee5\u901a\u5e38\u4f1a\u5f15\u7528\u8282\u70b9\u5bf9\u8c61\u7684\u5b9e\u4f8b\u53d8\u91cf\u800c\u4e0d\u662f\u65b9\u6cd5\u8c03\u7528\uff0c\u5e76\u4e14\u6784\u9020\u51fd\u6570\u4e5f\u9700\u8981\u7528\u6237\u5728\u521b\u5efa\u8282\u70b9\u65f6\u53ef\u4ee5\u8bbe\u7f6e\u8282\u70b9\u7684\u94fe\u63a5\u3002 \u4e0b\u9762\u662f\u7528\u6765\u5b9e\u73b0\u5355\u5411\u94fe\u63a5\u8282\u70b9\u7c7b\u7684\u4ee3\u7801\u3002 class Node ( object ): \"\"\"\u5355\u5411\u94fe\u63a5\u8282\u70b9\u7c7b\"\"\" def __init__ ( self , data , next = None ): \"\"\"\u5b9e\u4f8b\u5316\u4e00\u4e2a\u8282\u70b9, \u9ed8\u8ba4\u540e\u7ee7\u8282\u70b9\u4e3aNone\"\"\" self . data = data self . next = next def main (): # \u521b\u5efa\u4e00\u4e2a\u7a7a\u94fe node1 = None # \u521b\u5efa\u4e00\u4e2a\u5355\u5411\u94fe\u63a5\u8282\u70b9\uff0c\u542b\u6570\u636e\u5143\u7d20\u548c\u7a7a\u94fe node2 = Node ( \"A\" , None ) # \u521b\u5efa\u4e00\u4e2a\u5355\u5411\u94fe\u63a5\u8282\u70b9\uff0c\u542b\u6570\u636e\u5143\u7d20\u548c\u6307\u5411\u4e0b\u4e00\u4e2a\u8282\u70b9\u7684\u94fe\u63a5 node3 = Node ( \"B\" , node2 ) if __name__ == \"__main__\" : main () 4.4.4.\u4f7f\u7528\u5355\u5411\u94fe\u63a5\u8282\u70b9\u7c7b \u00b6 \u4e0b\u9762\u8fd9\u6bb5\u4ee3\u7801\u6f14\u793a\u4e86\u8282\u70b9\u53d8\u91cf\u88ab\u521d\u59cb\u5316\u4e3a None \u6216\u4e00\u4e2a\u65b0\u7684 Node \u5bf9\u8c61\u3002 node1 \u6ca1\u6709\u6307\u5411\u4efb\u4f55\u8282\u70b9\u5bf9\u8c61\uff08\u662f None \uff09\u3002 node2 \u548c node3 \u90fd\u6307\u5411\u4e86\u94fe\u63a5\u7684\u5bf9\u8c61\u3002 node2 \u6307\u5411\u4e86\u4e0b\u4e00\u4e2a\u6307\u9488\u662f None \u7684\u5bf9\u8c61\u3002 def main (): # \u521b\u5efa\u4e00\u4e2a\u7a7a\u94fe node1 = None # \u521b\u5efa\u4e00\u4e2a\u5355\u5411\u94fe\u63a5\u8282\u70b9\uff0c\u542b\u6570\u636e\u5143\u7d20\u548c\u7a7a\u94fe node2 = Node ( \"A\" , None ) # \u521b\u5efa\u4e00\u4e2a\u5355\u5411\u94fe\u63a5\u8282\u70b9\uff0c\u542b\u6570\u636e\u5143\u7d20\u548c\u6307\u5411\u4e0b\u4e00\u4e2a\u8282\u70b9\u7684\u94fe\u63a5 node3 = Node ( \"B\" , node2 ) \u6267\u884c node1.next = node3 \u4f1a\u6536\u5230\u9519\u8bef AttributeError: 'NoneType' object has no attribute 'next' \uff0c\u56e0\u4e3a\u53d8\u91cf node1 \u7684\u503c\u662f None \uff0c\u6240\u4ee5\u5b83\u5e76\u4e0d\u5305\u542b\u7528\u6765\u5f15\u7528\u8282\u70b9\u5bf9\u8c61\u7684 next \u5b57\u6bb5\u3002 \u5e94\u8be5\u5148\u6b63\u786e\u5b9e\u4f8b\u5316 node1 \uff0c\u518d\u5c06 node3 \u4f5c\u4e3a\u5176\u540e\u7ee7\u3002\u4e0b\u9762\u662f\u793a\u4f8b\u4ee3\u7801\u3002 def main (): # \u521b\u5efa\u4e00\u4e2a\u7a7a\u94fe node1 = None # \u521b\u5efa\u4e00\u4e2a\u5355\u5411\u94fe\u63a5\u8282\u70b9\uff0c\u542b\u6570\u636e\u5143\u7d20\u548c\u7a7a\u94fe node2 = Node ( \"A\" , None ) # \u521b\u5efa\u4e00\u4e2a\u5355\u5411\u94fe\u63a5\u8282\u70b9\uff0c\u542b\u6570\u636e\u5143\u7d20\u548c\u6307\u5411\u4e0b\u4e00\u4e2a\u8282\u70b9\u7684\u94fe\u63a5 node3 = Node ( \"B\" , node2 ) if node1 != None : node1 . next = node3 else : node1 = Node ( \"C\" , None ) node1 . next = node3 \u4e0b\u9762\u7684\u4ee3\u7801\u7684\u529f\u80fd\u662f\uff1a\u521b\u5efa\u4e00\u4e2a\u5355\u5411\u94fe\u63a5\u7ed3\u6784\uff0c\u5e76\u6253\u5370\u51fa\u5b83\u7684\u5185\u5bb9\u3002 \u4ee3\u7801\u4e2d head \u662f\u4e00\u4e2a\u6307\u9488\uff0c\u7528\u4e8e\u751f\u6210\u6574\u4e2a\u94fe\u63a5\u7ed3\u6784\u3002\u8fd9\u4e2a\u6307\u9488\u7684\u7528\u6cd5\u662f\u8ba9\u6240\u6709\u65b0\u63d2\u5165\u7684\u5143\u7d20\u59cb\u7ec8\u4f4d\u4e8e\u94fe\u63a5\u7ed3\u6784\u7684\u5f00\u5934\u3002 \u5728\u663e\u793a\u6570\u636e\u65f6\uff0c\u5b83\u4eec\u4f1a\u4ee5\u548c\u63d2\u5165\u65f6\u76f8\u53cd\u7684\u987a\u5e8f\u51fa\u73b0\u3002\u6b64\u5916\uff0c\u5f53\u663e\u793a\u6570\u636e\u65f6\uff0c\u5934\u90e8\u6307\u9488 head \u4f1a\u88ab\u91cd\u7f6e\u5230\u4e0b\u4e00\u4e2a\u8282\u70b9\uff0c\u76f4\u5230\u5934\u90e8\u6307\u9488\u53d8\u4e3a None \u4e3a\u6b62\u3002 \u4ee3\u7801\u6267\u884c\u7ed3\u675f\u4e4b\u540e\uff0c\u8fd9\u4e9b\u8282\u70b9\u5728\u7a0b\u5e8f\u91cc\u4e0d\u518d\u53ef\u7528\uff0c\u5e76\u4e14\u4f1a\u5728\u4e0b\u4e00\u6b21\u5783\u573e\u56de\u6536\u671f\u95f4\u88ab\u56de\u6536\u3002 def main (): # \u521b\u5efa\u4e00\u4e2a\u5355\u5411\u94fe\u63a5\u7ed3\u6784\uff0c\u5e76\u6253\u5370\u51fa\u5b83\u7684\u5185\u5bb9 head = None # \u5728\u94fe\u63a5\u7ed3\u6784\u7684\u5f00\u5934\u4f9d\u6b21\u63d2\u5165\u4e94\u4e2a\u8282\u70b9 for count in range ( 1 , 6 ): head = Node ( count , head ) # \u6253\u5370\u8f93\u51fa\u8fd9\u4e2a\u5355\u5411\u94fe\u63a5\u7684\u4e94\u4e2a\u8282\u70b9\u7684\u5185\u5bb9 while head != None : print ( head . data ) head = head . next if __name__ == \"__main__\" : main () # \u8fd0\u884c\u7ed3\u679c # 5 # 4 # 3 # 2 # 1 4.4.5.\u7ec3\u4e60\u9898 \u00b6 1\uff0e\u7528\u6846\u548c\u6307\u9488\u7ed8\u5236\u6d4b\u8bd5\u7a0b\u5e8f\u91cc\u7b2c\u4e00\u4e2a\u5faa\u73af\u6240\u521b\u5efa\u7684\u8282\u70b9\u7684\u793a\u610f\u56fe\u3002 \u89e3\u7b54\uff1a\u5728\u4e0b\u9762\u7684\u4ee3\u7801\u4e2d\uff0c\u6211\u4eec\u9996\u5148\u521b\u5efa\u4e86\u4e00\u4e2a\u7a7a\u7684\u5355\u94fe\u8868 head \u3002\u7136\u540e\u6211\u4eec\u5728\u94fe\u8868\u7684\u5f00\u5934\u4f9d\u6b21\u63d2\u5165\u4e94\u4e2a\u8282\u70b9\uff0c\u8282\u70b9\u7684\u6570\u636e\u4f9d\u6b21\u4e3a 1 , 2 , 3 , 4 , 5 \u3002\u5728\u63d2\u5165\u8fc7\u7a0b\u4e2d\uff0c\u6bcf\u6b21\u90fd\u628a\u65b0\u7684\u8282\u70b9\u63d2\u5165\u5230\u94fe\u8868\u7684\u5934\u90e8\uff0c\u6240\u4ee5\u6700\u540e\u7684\u94fe\u8868\u987a\u5e8f\u4f1a\u662f 5 , 4 , 3 , 2 , 1 \u3002 def main (): # \u521b\u5efa\u4e00\u4e2a\u5355\u5411\u94fe\u63a5\u7ed3\u6784\uff0c\u5e76\u6253\u5370\u51fa\u5b83\u7684\u5185\u5bb9 head = None # \u5728\u94fe\u63a5\u7ed3\u6784\u7684\u5f00\u5934\u4f9d\u6b21\u63d2\u5165\u4e94\u4e2a\u8282\u70b9 for count in range ( 1 , 6 ): head = Node ( count , head ) # \u6253\u5370\u8f93\u51fa\u8fd9\u4e2a\u5355\u5411\u94fe\u63a5\u7684\u4e94\u4e2a\u8282\u70b9\u7684\u5185\u5bb9 while head != None : print ( head . data ) head = head . next \u4ee5\u4e0b\u662f\u56fe\u793a\uff0c\u6bcf\u4e2a [] \u4ee3\u8868\u4e00\u4e2a\u8282\u70b9\uff0c\u8282\u70b9\u4e2d\u7684\u6570\u5b57\u4ee3\u8868\u8282\u70b9\u7684\u6570\u636e\uff0c\u7bad\u5934\u4ee3\u8868\u6307\u9488\uff0c\u6307\u5411\u4e86\u4e0b\u4e00\u4e2a\u8282\u70b9\u3002 NULL \u8868\u793a\u94fe\u8868\u7684\u7ed3\u675f\u3002 [5]---> [4] ---> [3] ---> [2] ---> [1] ---> NULL 2\uff0e\u5f53\u8282\u70b9\u53d8\u91cf\u5f15\u7528\u7684\u662f None \u65f6\uff0c\u5982\u679c\u7a0b\u5e8f\u5458\u5c1d\u8bd5\u8bbf\u95ee\u8282\u70b9\u7684\u6570\u636e\u5b57\u6bb5\uff0c\u5219\u4f1a\u53d1\u751f\u4ec0\u4e48\uff1f\u5982\u4f55\u9632\u6b62\u8fd9\u79cd\u60c5\u51b5\u7684\u53d1\u751f\uff1f \u89e3\u7b54\uff1a\u5f53\u8282\u70b9\u53d8\u91cf\u5f15\u7528\u7684\u662f None \u65f6\uff0c\u4f8b\u5982\uff0c\u6267\u884c node1.next = node3 \u4f1a\u6536\u5230\u9519\u8bef AttributeError: 'NoneType' object has no attribute 'next' \uff0c\u56e0\u4e3a\u53d8\u91cf node1 \u7684\u503c\u662f None \uff0c\u6240\u4ee5\u5b83\u5e76\u4e0d\u5305\u542b\u7528\u6765\u5f15\u7528\u8282\u70b9\u5bf9\u8c61\u7684 next \u5b57\u6bb5\u3002 \u5e94\u8be5\u5148\u6b63\u786e\u5b9e\u4f8b\u5316 node1 \uff0c\u518d\u5c06 node3 \u4f5c\u4e3a\u5176\u540e\u7ee7\u3002\u4e0b\u9762\u662f\u793a\u4f8b\u4ee3\u7801\u3002 if node1 != None : node1 . next = node3 else : node1 = Node ( \"C\" , None ) node1 . next = node3 3\uff0e\u7f16\u5199\u4e00\u6bb5\u4ee3\u7801\uff1a\u8fd9\u6bb5\u4ee3\u7801\u4f1a\u628a\u4e00\u4e2a\u88ab\u586b\u6ee1\u7684\u6570\u7ec4\u91cc\u7684\u5143\u7d20\u90fd\u8f6c\u79fb\u4e3a\u5355\u5411\u94fe\u63a5\u7ed3\u6784\u91cc\u7684\u6570\u636e\u3002\u8fd9\u4e2a\u64cd\u4f5c\u5e94\u4fdd\u7559\u5143\u7d20\u7684\u987a\u5e8f\u4e0d\u53d8\u3002 \u89e3\u7b54\uff1a\u4e0b\u9762\u662f\u4ee3\u7801\u5b9e\u73b0\u3002 LinkedList \u7c7b\u6709\u4e24\u4e2a\u65b9\u6cd5\uff0c insert_from_list \u7528\u4e8e\u4ece\u5217\u8868\u4e2d\u63d2\u5165\u6570\u636e\uff0c print_list \u7528\u4e8e\u6253\u5370\u94fe\u8868\u7684\u6240\u6709\u5143\u7d20\u3002 \u5728 insert_from_list \u65b9\u6cd5\u4e2d\uff0c\u6211\u4eec\u9996\u5148\u521b\u5efa\u7b2c\u4e00\u4e2a\u8282\u70b9\uff0c\u7136\u540e\u5bf9\u5217\u8868\u7684\u5269\u4f59\u5143\u7d20\uff0c\u4f9d\u6b21\u521b\u5efa\u65b0\u7684\u8282\u70b9\u5e76\u6dfb\u52a0\u5230\u94fe\u8868\u5c3e\u90e8\u3002 \u7531\u4e8e\u6211\u4eec\u662f\u9010\u4e2a\u5c06\u5143\u7d20\u6dfb\u52a0\u5230\u94fe\u8868\u7684\u672b\u5c3e\uff0c\u6240\u4ee5\u5728\u521b\u5efaNode\u65f6\u5e76\u4e0d\u9700\u8981\u6307\u5b9anext\u8282\u70b9\u3002 class Node ( object ): \"\"\"\u5355\u5411\u94fe\u63a5\u8282\u70b9\u7c7b\"\"\" def __init__ ( self , data , next = None ): \"\"\"\u5b9e\u4f8b\u5316\u4e00\u4e2a\u8282\u70b9, \u9ed8\u8ba4\u540e\u7ee7\u8282\u70b9\u4e3aNone\"\"\" self . data = data self . next = next class LinkedList : \"\"\"\u5c06\u5217\u8868\u5143\u7d20\u8f6c\u79fb\u4e3a\u5355\u5411\u94fe\u63a5\u7ed3\u6784\u91cc\u7684\u6570\u636e\uff0c\u5e76\u4fdd\u7559\u5143\u7d20\u7684\u987a\u5e8f\u4e0d\u53d8\"\"\" def __init__ ( self ): self . head = None # \u521d\u59cb\u5316head def insert_from_list ( self , data_list ): # \u521b\u5efa\u4e86\u94fe\u8868\u7684\u5934\u8282\u70b9 self . head = Node ( data_list [ 0 ]) # \u8bfb\u53d6\u5217\u8868\u7d22\u5f150\u7684\u5143\u7d20\u503c\uff0c\u5e76\u5c06\u5730\u5740\u8d4b\u503c\u7ed9head current = self . head # \u5c06head\u5f15\u7528\u8d4b\u503c\u7ed9current # \u5728\u94fe\u8868\u7684\u5c3e\u90e8\u4f9d\u6b21\u6dfb\u52a0\u65b0\u7684\u8282\u70b9 # \u5728\u6bcf\u6b21\u5faa\u73af\u540e\uff0c\u94fe\u8868\u7684\u5c3e\u90e8\u90fd\u4f1a\u6dfb\u52a0\u65b0\u7684\u8282\u70b9\uff0c\u5e76\u4e14current\u8282\u70b9\u4e5f\u4f1a\u968f\u4e4b\u66f4\u65b0\u3002 for data in data_list [ 1 :]: current . next = Node ( data ) # \u521b\u5efa\u4e00\u4e2a\u65b0\u7684\u8282\u70b9\uff0c\u5e76\u4e14\u5c06current\u8282\u70b9\u7684next\u5c5e\u6027\u8bbe\u7f6e\u4e3a\u8fd9\u4e2a\u65b0\u7684\u8282\u70b9\u3002\u8fd9\u6837\uff0ccurrent\u8282\u70b9\uff08\u4e5f\u5c31\u662f\u4e4b\u524d\u7684\u5c3e\u8282\u70b9\uff09\u5c31\u548c\u65b0\u7684\u8282\u70b9\u5efa\u7acb\u4e86\u94fe\u63a5\u5173\u7cfb\u3002 current = current . next # \u5c06current\u66f4\u65b0\u4e3a\u65b0\u521b\u5efa\u7684\u8282\u70b9\u3002\u4e5f\u5c31\u662f\u8bf4\uff0ccurrent\u59cb\u7ec8\u4ee3\u8868\u5f53\u524d\u94fe\u8868\u7684\u5c3e\u8282\u70b9\u3002 def print_list ( self ): current = self . head while current : print ( current . data , end = ' ' ) current = current . next print () def main (): # \u5c06\u5217\u8868data_list\u4e2d\u7684\u5143\u7d20\u63d2\u5165\u5230LinkedList\u5b9e\u4f8b\u4e2d\uff0c\u518d\u4f7f\u7528print_list\u65b9\u6cd5\u6253\u5370\u51fa\u94fe\u8868\u4e2d\u6240\u6709\u5143\u7d20\u3002 data_list = [ 1 , 2 , 3 , 4 , 5 ] linked_list = LinkedList () linked_list . insert_from_list ( data_list ) linked_list . print_list () # \u8f93\u51fa: 1 2 3 4 5 if __name__ == \"__main__\" : main () # \u8fd0\u884c\u7ed3\u679c # 1 2 3 4 5 \u5982\u679c\u5728\u521b\u5efaNode\u7684\u65f6\u5019\u6307\u5b9a next \u8282\u70b9\uff0c\u5219\u53ef\u4ee5\u4fee\u6539\u4e3a\u4e0b\u9762\u7684\u4ee3\u7801\u3002 insert_from_list \u51fd\u6570\u9996\u5148\u53cd\u8f6c\u4e86\u8f93\u5165\u7684\u5217\u8868\uff0c\u7136\u540e\u904d\u5386\u53cd\u8f6c\u540e\u7684\u5217\u8868\uff0c\u6bcf\u6b21\u90fd\u5728\u94fe\u8868\u5934\u90e8\u63d2\u5165\u4e00\u4e2a\u65b0\u7684\u8282\u70b9\u3002\u8fd9\u6837\u53ef\u4ee5\u786e\u4fdd\u63d2\u5165\u94fe\u8868\u7684\u5143\u7d20\u987a\u5e8f\u548c\u5b83\u4eec\u5728\u8f93\u5165\u5217\u8868\u4e2d\u7684\u987a\u5e8f\u662f\u4e00\u6837\u7684\u3002 class Node ( object ): \"\"\"\u5355\u5411\u94fe\u63a5\u8282\u70b9\u7c7b\"\"\" def __init__ ( self , data , next = None ): \"\"\"\u5b9e\u4f8b\u5316\u4e00\u4e2a\u8282\u70b9, \u9ed8\u8ba4\u540e\u7ee7\u8282\u70b9\u4e3aNone\"\"\" self . data = data self . next = next class LinkedList : \"\"\"\u5c06\u6570\u7ec4\u5143\u7d20\u8f6c\u79fb\u4e3a\u5355\u5411\u94fe\u63a5\u7ed3\u6784\u91cc\u7684\u6570\u636e\uff0c\u5e76\u4fdd\u7559\u5143\u7d20\u7684\u987a\u5e8f\u4e0d\u53d8\"\"\" def __init__ ( self ): self . head = None # \u521d\u59cb\u5316head def insert_from_list ( self , data_list ): for data in reversed ( data_list ): self . head = Node ( data , self . head ) def print_list ( self ): current = self . head while current : print ( current . data , end = ' ' ) current = current . next print () def main (): data_list = [ 1 , 2 , 3 , 4 , 5 ] linked_list = LinkedList () linked_list . insert_from_list ( data_list ) linked_list . print_list () # \u8f93\u51fa: 1 2 3 4 5 if __name__ == \"__main__\" : main () # \u8fd0\u884c\u7ed3\u679c # 1 2 3 4 5 4.5.\u5355\u5411\u94fe\u63a5\u7ed3\u6784\u4e0a\u7684\u64cd\u4f5c \u00b6 \u6570\u7ec4\u4e0a\u7684\u64cd\u4f5c\u51e0\u4e4e\u90fd\u662f\u57fa\u4e8e\u7d22\u5f15\u7684\u3002\u94fe\u63a5\u7ed3\u6784\u4e0a\u7684\u64cd\u4f5c\u662f\u901a\u8fc7\u64cd\u63a7\u7ed3\u6784\u91cc\u7684\u94fe\u63a5\u6765\u6a21\u62df\u8fd9\u4e9b\u57fa\u4e8e\u7d22\u5f15\u7684\u64cd\u4f5c\u3002 \u4e0b\u9762\u662f\u5b8c\u6574\u4ee3\u7801\uff0c\u5305\u542b\u4e86\u540e\u9762\u5173\u4e8e\u8fde\u63a5\u7ed3\u6784\u7684\u64cd\u4f5c\u793a\u4f8b\u3002 # class Node(object): # \"\"\"\u5355\u5411\u94fe\u63a5\u8282\u70b9\u7c7b\"\"\" # def __init__(self, data, next=None): # \"\"\"\u5b9e\u4f8b\u5316\u4e00\u4e2a\u8282\u70b9, \u9ed8\u8ba4\u540e\u7ee7\u8282\u70b9\u4e3aNone\"\"\" # self.data = data # self.next = next # class TwoWayNode(Node): # \"\"\"\u53cc\u5411\u94fe\u63a5\u8282\u70b9\u7c7b\"\"\" # def __init__(self, data, previous=None, next=None): # \"\"\"\u5b9e\u4f8b\u5316\u4e00\u4e2a\u8282\u70b9, \u9ed8\u8ba4\u524d\u5e8f\u8282\u70b9\u5c3eNone, \u9ed8\u8ba4\u540e\u7ee7\u8282\u70b9\u4e3aNone\"\"\" # Node.__init__(self, data, next) # self.previous = previous # class LinkedList: # \"\"\"\u5355\u5411\u548c\u53cc\u5411\u94fe\u63a5\u7ed3\u6784\"\"\" # def __init__(self, node): # # \u521d\u59cb\u5316\u5934\u8282\u70b9 # self.head = node # # \u5c5e\u6027size\u4fdd\u5b58\u94fe\u63a5\u7ed3\u6784\u7684\u903b\u8f91\u5927\u5c0f\uff0c\u901a\u5e38\u6307\u7684\u662f\u94fe\u8868\u6240\u5305\u542b\u7684\u5143\u7d20\u7684\u6570\u91cf\uff0c\u521d\u59cb\u5316\u94fe\u63a5\u7ed3\u6784\u5927\u5c0f\u4e3a0 # self.size = 0 # def insert_from_list(self, data_list, twoway=False): # \"\"\" # \u628a\u4e00\u4e2a\u5217\u8868\uff08\u5df2\u6709\u7684\u6570\u636e\u7ed3\u6784\uff09\u8f6c\u6362\u4e3a\u94fe\u63a5\u7ed3\u6784\u662f\u4e00\u79cd\u6bd4\u8f83\u5e38\u89c1\u5b9e\u7528\u7684\u65b9\u5f0f\u3002\u8fd9\u79cd\u505a\u6cd5\u53ef\u4ee5\u901a\u8fc7\u63a7\u5236\u4ee3\u7801\uff0c\u65b9\u4fbf\u5730\u4ece\u5df2\u6709\u7684\u96c6\u5408\u7c7b\uff08\u5982\u5217\u8868\uff0c\u6570\u7ec4\u7b49\uff09\u4e2d\u5bfc\u5165\u5143\u7d20\uff0c\u5e76\u6784\u5efa\u9700\u8981\u7684\u7684\u94fe\u63a5\u7ed3\u6784\u3002 # \u5728\u4e00\u4e9b\u7b80\u5355\u573a\u666f\u4e0b\uff0c\u6bd4\u5982\u5df2\u77e5\u5f85\u6dfb\u52a0\u7684\u5143\u7d20\u6570\u91cf\u5f88\u5c11\uff0c\u6216\u8005\u6709\u5176\u4ed6\u7ea6\u675f\u4f7f\u5f97\u7528\u5217\u8868\u4e0d\u65b9\u4fbf\u65f6\uff0c\u53ef\u4ee5\u901a\u8fc7\u624b\u52a8\u65b9\u5f0f\u5411\u94fe\u63a5\u7ed3\u6784\u6dfb\u52a0\u5143\u7d20\u3002\u4f46\u5982\u679c\u5143\u7d20\u5f88\u591a\uff0c\u6216\u8005\u6709\u672a\u77e5\u6570\u91cf\u7684\u5143\u7d20\u9700\u8981\u6dfb\u52a0\uff0c\u7528\u5217\u8868\u53ef\u4ee5\u65b9\u4fbf\u5730\u4e00\u6b21\u6027\u5bfc\u5165\u6240\u6709\u5143\u7d20\u3002 # \"\"\" # if twoway: # \u68c0\u67e5\u662f\u5426\u8981\u521b\u5efa\u53cc\u5411\u94fe\u8868 # for data in data_list: # \u5bf9\u4e8e\u6570\u636e\u5217\u8868\u4e2d\u7684\u6bcf\u4e2a\u6570\u636e\u521b\u5efa\u4e00\u4e2a\u65b0\u7684\u53cc\u5411\u94fe\u63a5\u8282\u70b9 # node = TwoWayNode(data) # if self.head is None: # \u5982\u679c\u94fe\u8868\u4e3a\u7a7a\u628a\u65b0\u8282\u70b9\u8bbe\u7f6e\u4e3a\u5934\u8282\u70b9 # self.head = node # else: # \u5982\u679c\u94fe\u8868\u4e0d\u4e3a\u7a7a # tail = self.head # \u4ece\u5934\u8282\u70b9\u5f00\u59cb # while tail.next is not None: # \u901a\u8fc7\u904d\u5386\u94fe\u8868\u67e5\u627e\u5c3e\u8282\u70b9 # tail = tail.next # tail.next = node # \u628a\u65b0\u8282\u70b9\u63d2\u5165\u5230\u5c3e\u8282\u70b9 # node.previous = tail # \u8bbe\u7f6e\u65b0\u8282\u70b9\u7684\u524d\u4e00\u4e2a\u8282\u70b9\u6307\u5411\u5c3e\u8282\u70b9 # else: # \u521b\u5efa\u5355\u5411\u94fe\u8868 # for data in reversed(data_list): # \u5bf9\u4e8e\u5217\u8868\u4e2d\u7684\u6bcf\u4e2a\u5143\u7d20\uff0c\u53cd\u5411\u8fed\u4ee3\u4f7f\u5f97\u63d2\u5165\u7684\u8282\u70b9\u4e0e\u539f\u6570\u636e\u987a\u5e8f\u76f8\u540c # self.head = Node(data, self.head) # \u521b\u5efa\u4e00\u4e2a\u65b0\u7684\u5355\u5411\u94fe\u63a5\u8282\u70b9\u5e76\u63d2\u5165\u5230\u5934\u8282\u70b9 # self.size += len(data_list) # \u66f4\u65b0\u94fe\u8868\u5927\u5c0f # def get_size(self): # \"\"\"\u83b7\u53d6\u94fe\u8868\u5927\u5c0f\uff08\u8282\u70b9\u6570\u91cf\uff09\"\"\" # return self.size # def search(self, target): # \"\"\"\u5728\u94fe\u63a5\u7ed3\u6784\u4e2d\u641c\u7d22\u6307\u5b9a\u5143\u7d20\"\"\" # current = self.head # \u4ece\u5934\u8282\u70b9\u5f00\u59cb # while current: # \u5f53\u5f53\u524d\u8282\u70b9\u975eNone\u65f6\u7ee7\u7eed\u904d\u5386 # if current.data == target: # \u5982\u679c\u5f53\u524d\u8282\u70b9\u7684\u6570\u636e\u7b49\u4e8e\u76ee\u6807\u6570\u636e # return True # \u8fd4\u56de\u771f\u503c # current = current.next # \u79fb\u52a8\u5230\u4e0b\u4e00\u8282\u70b9 # return False # \u5982\u679c\u6574\u4e2a\u94fe\u8868\u904d\u5386\u5b8c\u6bd5\u8fd8\u627e\u4e0d\u5230\u76ee\u6807\u6570\u636e\uff0c\u8fd4\u56de\u5047\u503c # def locate(self, index): # \"\"\"\u8fd4\u56de\u94fe\u63a5\u7ed3\u6784\u4e2d\u7b2cindex\u4e2a\u5143\u7d20, 0 <= index < n\"\"\" # if index >= self.get_size() or index < 0: # \u5982\u679c\u7d22\u5f15\u8d85\u51fa\u8303\u56f4\uff0c\u7acb\u5373\u629b\u51fa\u9519\u8bef # raise IndexError(\"\u94fe\u8868\u7d22\u5f15\u8d85\u51fa\u8303\u56f4\") # probe = self.head # \u786e\u5b9a\u8d77\u59cb\u70b9\u4e3a\u5934\u8282\u70b9 # while index > 0: # \u5f53\u7d22\u5f15\u5927\u4e8e0\u65f6\uff0c\u8fdb\u5165\u5faa\u73af # probe = probe.next # \u5c06\u63a2\u9488\uff08probe\uff09\u79fb\u52a8\u5230\u4e0b\u4e00\u4e2a\u8282\u70b9 # index -= 1 # \u5c06\u7d22\u5f15\u503c\u51cf1 # return probe.data # \u8fd4\u56de\u5f53\u524d\u4f4d\u7f6e\uff08index\u5bf9\u5e94\u4f4d\u7f6e\uff09\u7684\u8282\u70b9\u6570\u636e # def replace(self, old, new): # \"\"\"\u66ff\u6362\u94fe\u8868\u4e2d\u6240\u6709\u7b49\u4e8eold\u7684\u5143\u7d20\u4e3anew\"\"\" # current = self.head # \u4ece\u94fe\u8868\u7684\u5934\u8282\u70b9\u5f00\u59cb\u904d\u5386 # while current: # \u53ea\u8981\u8fd8\u6709\u8282\u70b9\uff0c\u5c31\u7ee7\u7eed\u904d\u5386 # if current.data == old: # \u68c0\u67e5\u5f53\u524d\u8282\u70b9\u7684\u6570\u636e\u662f\u5426\u7b49\u4e8eold # current.data = new # \u5982\u679c\u7b49\u4e8eold\uff0c\u5c06\u5f53\u524d\u8282\u70b9\u7684\u6570\u636e\u66ff\u6362\u4e3anew # current = current.next # \u7ee7\u7eed\u68c0\u67e5\u4e0b\u4e00\u4e2a\u8282\u70b9 # def print_list(self): # \"\"\"\u6253\u5370\u8f93\u51fa\u94fe\u63a5\u7ed3\u6784\u5185\u5bb9\"\"\" # current = self.head # while current: # print(current.data, end=' ') # current = current.next # print() # def main(): # # \u521b\u5efa\u6d4b\u8bd5\u6570\u636e # test_data = [1, 2, 3, 4, 5] # # \u5355\u5411\u94fe\u8868\u6d4b\u8bd5 # print(\"\u5355\u5411\u94fe\u8868\u6d4b\u8bd5:\") # single_linked_list = LinkedList(None) # print(\"\u63d2\u5165\u6570\u636e\") # single_linked_list.insert_from_list(test_data) # \u63d2\u5165\u6d4b\u8bd5\u6570\u636e # single_linked_list.print_list() # \u6253\u5370\u94fe\u63a5\u7ed3\u6784\u5185\u5bb9 # print(\"\u94fe\u8868\u5927\u5c0f\uff1a\", single_linked_list.get_size()) # \u663e\u793a\u94fe\u63a5\u7ed3\u6784\u5927\u5c0f # print(\"\u641c\u7d22\u5143\u7d203: \", single_linked_list.search(3)) # \u641c\u7d22\u94fe\u63a5\u7ed3\u6784\u4e2d\u662f\u5426\u5b58\u5728\u5143\u7d203 # print(\"\u67e5\u627e\u7b2c2\u4e2a\u5143\u7d20: \", single_linked_list.locate(2)) # \u67e5\u627e\u94fe\u63a5\u7ed3\u6784\u4e2d\u7b2c2\u4e2a\u5143\u7d20 # print(\"\u628a\u5143\u7d201\u66ff\u6362\u4e3a10\") # single_linked_list.replace(1, 10) # \u66ff\u6362\u5143\u7d201\u4e3a10 # single_linked_list.print_list() # print() # # \u53cc\u5411\u94fe\u8868\u6d4b\u8bd5 # print(\"\u53cc\u5411\u94fe\u8868\u6d4b\u8bd5:\") # double_linked_list = LinkedList(None) # print(\"\u63d2\u5165\u6570\u636e\") # double_linked_list.insert_from_list(test_data, twoway=True) # double_linked_list.print_list() # print(\"\u94fe\u8868\u5927\u5c0f\uff1a\", double_linked_list.get_size()) # print(\"\u641c\u7d22\u5143\u7d203\uff1a\", double_linked_list.search(3)) # print(\"\u67e5\u627e\u7b2c2\u4e2a\u5143\u7d20\uff1a\", double_linked_list.locate(2)) # print(\"\u66ff\u6362\u5143\u7d201\u4e3a10\") # double_linked_list.replace(1, 10) # double_linked_list.print_list() # if __name__ == \"__main__\": # main() # # \u8fd0\u884c\u7ed3\u679c # # \u5355\u5411\u94fe\u8868\u6d4b\u8bd5: # # \u63d2\u5165\u6570\u636e # # 1 2 3 4 5 # # \u94fe\u8868\u5927\u5c0f\uff1a 5 # # \u641c\u7d22\u5143\u7d203\uff1a True # # \u67e5\u627e\u7b2c2\u4e2a\u5143\u7d20\uff1a 3 # # \u66ff\u6362\u5143\u7d201\u4e3a10 # # 10 2 3 4 5 # # \u53cc\u5411\u94fe\u8868\u6d4b\u8bd5: # # \u63d2\u5165\u6570\u636e # # 1 2 3 4 5 # # \u94fe\u8868\u5927\u5c0f\uff1a 5 # # \u641c\u7d22\u5143\u7d203\uff1a True # # \u67e5\u627e\u7b2c2\u4e2a\u5143\u7d20\uff1a 3 # # \u66ff\u6362\u5143\u7d201\u4e3a10 # # 10 2 3 4 5 4.5.1.\u904d\u5386 \u00b6 \u57284.4\u4e2d\u7684\u793a\u4f8b\u4ee3\u7801\u4e2d\uff08\u5982\u4e0b\uff09\uff0c\u8282\u70b9\u4f1a\u5728\u88ab\u6253\u5370\u4e4b\u540e\u4ece\u94fe\u63a5\u7ed3\u6784\u91cc\u5220\u9664\u3002 def main (): # \u521b\u5efa\u4e00\u4e2a\u5355\u5411\u94fe\u63a5\u7ed3\u6784\uff0c\u5e76\u6253\u5370\u51fa\u5b83\u7684\u5185\u5bb9 head = None # \u5728\u94fe\u63a5\u7ed3\u6784\u7684\u5f00\u5934\u4f9d\u6b21\u63d2\u5165\u4e94\u4e2a\u8282\u70b9 for count in range ( 1 , 6 ): head = Node ( count , head ) # \u6253\u5370\u8f93\u51fa\u8fd9\u4e2a\u5355\u5411\u94fe\u63a5\u7684\u4e94\u4e2a\u8282\u70b9\u7684\u5185\u5bb9 while head != None : print ( head . data ) head = head . next if __name__ == \"__main__\" : main () # \u8fd0\u884c\u7ed3\u679c # 5 # 4 # 3 # 2 # 1 \u5bf9\u4e8e\u8bb8\u591a\u5e94\u7528\u7a0b\u5e8f\u6765\u8bf4\uff0c\u53ea\u9700\u8981\u8bbf\u95ee\u6bcf\u4e2a\u8282\u70b9\u800c\u4e0d\u7528\u5220\u9664\u5b83\u4eec\u3002\u8fd9\u4e2a\u64cd\u4f5c\u79f0\u4e3a\u904d\u5386\uff08traversal\uff09\u3002 \u5728\u904d\u5386\u4e2d\uff0c\u4f1a\u7528\u5230\u4e00\u4e2a\u53eb\u4f5c probe \u7684\u4e34\u65f6\u6307\u9488\u53d8\u91cf\u3002\u4e00\u5f00\u59cb\uff0c\u8fd9\u4e2a\u53d8\u91cf\u88ab\u521d\u59cb\u5316\u4e3a\u94fe\u63a5\u7ed3\u6784\u7684head\u6307\u9488\uff0c\u7136\u540e\u901a\u8fc7\u5faa\u73af\u6765\u5b8c\u6210\uff0c\u5728\u6574\u4e2a\u8fc7\u7a0b\u7ed3\u675f\u4e4b\u540e\uff0cprobe\u6307\u9488\u662fNone\uff0c\u4f46head\u6307\u9488\u4ecd\u7136\u5f15\u7528\u7b2c\u4e00\u4e2a\u8282\u70b9\u3002 \u4e0b\u9762\u662f\u4fee\u6539\u540e\u7684\u4ee3\u7801\uff1a def main (): print ( \"------\" ) # \u521b\u5efa\u4e00\u4e2a\u5355\u5411\u94fe\u63a5\u7ed3\u6784\uff0c\u5e76\u6253\u5370\u51fa\u5b83\u7684\u5185\u5bb9 head = None # \u5728\u94fe\u63a5\u7ed3\u6784\u7684\u5f00\u5934\u4f9d\u6b21\u63d2\u5165\u4e94\u4e2a\u8282\u70b9 for count in range ( 1 , 6 ): head = Node ( count , head ) # \u6253\u5370\u8f93\u51fa\u8fd9\u4e2a\u5355\u5411\u94fe\u63a5\u7684\u4e94\u4e2a\u8282\u70b9\u7684\u5185\u5bb9 probe = head while probe != None : print ( probe . data ) probe = probe . next \u901a\u5e38\u6765\u8bf4\uff0c\u5355\u5411\u94fe\u63a5\u7ed3\u6784\u7684\u904d\u5386\u4f1a\u8bbf\u95ee\u6240\u6709\u8282\u70b9\uff0c\u5e76\u4e14\u5728\u5230\u8fbe\u7a7a\u94fe\u63a5\u65f6\u7ec8\u6b62\u904d\u5386\u3002\u56e0\u6b64\uff0c\u503c None \u76f8\u5f53\u4e8e\u505c\u6b62\u8fdb\u7a0b\u7684\u54e8\u5175\uff08sentinel\uff09\u3002 \u904d\u5386\u7684\u65f6\u95f4\u590d\u6742\u5ea6\u662f\u7ebf\u6027\u7684\uff0c\u4e5f\u4e0d\u9700\u8981\u989d\u5916\u7684\u5185\u5b58\u3002 4.5.2.\u641c\u7d22 \u00b6 \u5bf9\u94fe\u63a5\u7ed3\u6784\u8fdb\u884c\u987a\u5e8f\u641c\u7d22\u6709\u70b9\u7c7b\u4f3c\u4e8e\u904d\u5386\u64cd\u4f5c\uff0c\u56e0\u4e3a\u5fc5\u987b\u8981\u4ece\u7b2c\u4e00\u4e2a\u8282\u70b9\u5f00\u59cb\u5e76\u4f9d\u7167\u94fe\u63a5\u987a\u5e8f\u79fb\u52a8\uff0c\u76f4\u81f3\u627e\u5230\u5bf9\u5e94\u7684\u6807\u8bb0\u3002\u5728\u8fd9\u79cd\u60c5\u51b5\u4e0b\uff0c\u8fd9\u4e2a\u6807\u8bb0\u6709\u4e24\u79cd\u53ef\u80fd\u6027\u3002 \u7a7a\u94fe\u63a5\uff0c\u8bf4\u660e\u6ca1\u6709\u66f4\u591a\u9700\u8981\u88ab\u68c0\u67e5\u7684\u6570\u636e\u5143\u7d20\u3002 \u7b49\u540c\u4e8e\u76ee\u6807\u5143\u7d20\u7684\u6570\u636e\u5143\u7d20\uff0c\u4ee3\u8868\u641c\u7d22\u6210\u529f\u3002 \u4e0b\u9762\u662f\u641c\u7d22\u7ed9\u5b9a\u5143\u7d20\u7684\u4ee3\u7801\u3002 search(self, target) \u65b9\u6cd5\u5b9e\u73b0\u4e86\u5728\u5355\u5411\u6216\u53cc\u5411\u94fe\u8868\u4e2d\u641c\u7d22\u6307\u5b9a\u5143\u7d20\u3002 def search ( self , target ): \"\"\"\u5728\u94fe\u63a5\u7ed3\u6784\u4e2d\u641c\u7d22\u6307\u5b9a\u5143\u7d20\"\"\" current = self . head # \u4ece\u5934\u8282\u70b9\u5f00\u59cb while current : # \u5f53\u5f53\u524d\u8282\u70b9\u975eNone\u65f6\u7ee7\u7eed\u904d\u5386 if current . data == target : # \u5982\u679c\u5f53\u524d\u8282\u70b9\u7684\u6570\u636e\u7b49\u4e8e\u76ee\u6807\u6570\u636e return True # \u8fd4\u56de\u771f\u503c current = current . next # \u79fb\u52a8\u5230\u4e0b\u4e00\u8282\u70b9 return False # \u5982\u679c\u6574\u4e2a\u94fe\u8868\u904d\u5386\u5b8c\u6bd5\u8fd8\u627e\u4e0d\u5230\u76ee\u6807\u6570\u636e\uff0c\u8fd4\u56de\u5047\u503c \u5e73\u5747\u60c5\u51b5\u4e0b\uff0c\u987a\u5e8f\u641c\u7d22\u5728\u5355\u5411\u94fe\u63a5\u7ed3\u6784\u4e0a\u662f\u7ebf\u6027\u7684\u3002 \u8bbf\u95ee\u94fe\u63a5\u7ed3\u6784\u7684\u7b2c i \u4e2a\u5143\u7d20\u65f6\u6267\u884c\u7684\u4e5f\u662f\u987a\u5e8f\u641c\u7d22\u3002\u8fd9\u662f\u56e0\u4e3a\u5fc5\u987b\u4ece\u7b2c\u4e00\u4e2a\u8282\u70b9\u5f00\u59cb\u7edf\u8ba1\u94fe\u63a5\u7684\u6570\u91cf\uff0c\u76f4\u81f3\u5230\u8fbe\u7b2c i \u4e2a\u8282\u70b9\u4e3a\u6b62\u3002\u5047\u8bbe\u6709 0<=i= self . get_size () or index < 0 : # \u5982\u679c\u7d22\u5f15\u8d85\u51fa\u8303\u56f4\uff0c\u7acb\u5373\u629b\u51fa\u9519\u8bef raise IndexError ( \"\u94fe\u8868\u7d22\u5f15\u8d85\u51fa\u8303\u56f4\" ) probe = self . head # \u786e\u5b9a\u8d77\u59cb\u70b9\u4e3a\u5934\u8282\u70b9 while index > 0 : # \u5f53\u7d22\u5f15\u5927\u4e8e0\u65f6\uff0c\u8fdb\u5165\u5faa\u73af probe = probe . next # \u5c06\u63a2\u9488\uff08probe\uff09\u79fb\u52a8\u5230\u4e0b\u4e00\u4e2a\u8282\u70b9 index -= 1 # \u5c06\u7d22\u5f15\u503c\u51cf1 return probe . data # \u8fd4\u56de\u5f53\u524d\u4f4d\u7f6e\uff08index\u5bf9\u5e94\u4f4d\u7f6e\uff09\u7684\u8282\u70b9\u6570\u636e \u548c\u6570\u7ec4\u4e0d\u540c\u7684\u662f\uff0c\u94fe\u63a5\u7ed3\u6784\u5e76\u4e0d\u652f\u6301\u968f\u673a\u8bbf\u95ee\u3002\u56e0\u6b64\uff0c\u4e0d\u80fd\u50cf\u5728\u6709\u5e8f\u6570\u7ec4\u91cc\u90a3\u6837\u5bf9\u6709\u5e8f\u7684\u5355\u5411\u94fe\u63a5\u7ed3\u6784\u8fdb\u884c\u9ad8\u6548\u641c\u7d22\u3002 4.5.3.\u66ff\u6362 \u00b6 \u5355\u5411\u94fe\u63a5\u7ed3\u6784\u91cc\u7684\u66ff\u6362\u64cd\u4f5c\u4e5f\u4f1a\u91c7\u7528\u904d\u5386\u7684\u6a21\u5f0f\u3002\u5728\u8fd9\u79cd\u60c5\u51b5\u4e0b\uff0c\u6211\u4eec\u4f1a\u5728\u94fe\u63a5\u7ed3\u6784\u91cc\u641c\u7d22\u7ed9\u5b9a\u7684\u5143\u7d20\u6216\u7ed9\u5b9a\u7684\u4f4d\u7f6e\uff0c\u7136\u540e\u7528\u4e00\u4e2a\u65b0\u7684\u5143\u7d20\u66ff\u6362\u8fd9\u4e2a\u5143\u7d20\u3002 \u5728\u66ff\u6362\u7ed9\u5b9a\u5143\u7d20\u65f6\uff0c\u5e76\u4e0d\u9700\u8981\u5047\u5b9a\u76ee\u6807\u5143\u7d20\u5df2\u7ecf\u5b58\u5728\u4e8e\u94fe\u63a5\u7ed3\u6784\u91cc\u3002 \u5982\u679c\u76ee\u6807\u5143\u7d20\u4e0d\u5b58\u5728\uff0c\u5c31\u4e0d\u4f1a\u53d1\u751f\u4efb\u4f55\u66ff\u6362\u64cd\u4f5c\uff0c\u5e76\u4e14\u4f1a\u8fd4\u56de False \uff1b \u5982\u679c\u76ee\u6807\u5143\u7d20\u5b58\u5728\uff0c\u65b0\u7684\u5143\u7d20\u5c31\u4f1a\u66ff\u6362\u5b83\uff0c\u5e76\u4e14\u8fd4\u56de True \uff1b \u4e0b\u9762\u662f\u8fd9\u4e2a\u64cd\u4f5c\u7684\u4ee3\u7801\u3002 def replace ( self , old , new ): \"\"\"\u66ff\u6362\u94fe\u8868\u4e2d\u6240\u6709\u7b49\u4e8eold\u7684\u5143\u7d20\u4e3anew\"\"\" current = self . head # \u4ece\u94fe\u8868\u7684\u5934\u8282\u70b9\u5f00\u59cb\u904d\u5386 while current : # \u53ea\u8981\u8fd8\u6709\u8282\u70b9\uff0c\u5c31\u7ee7\u7eed\u904d\u5386 if current . data == old : # \u68c0\u67e5\u5f53\u524d\u8282\u70b9\u7684\u6570\u636e\u662f\u5426\u7b49\u4e8eold current . data = new # \u5982\u679c\u7b49\u4e8eold\uff0c\u5c06\u5f53\u524d\u8282\u70b9\u7684\u6570\u636e\u66ff\u6362\u4e3anew current = current . next # \u7ee7\u7eed\u68c0\u67e5\u4e0b\u4e00\u4e2a\u8282\u70b9 4.5.4.\u5728\u5f00\u59cb\u5904\u63d2\u5165 \u00b6 \u5728\u94fe\u63a5\u7ed3\u6784\u5934\u90e8\u63d2\u5165\u52062\u79cd\u60c5\u51b5\uff1a \u7b2c\u4e00\u79cd\u60c5\u51b5\uff1a head \u6307\u9488\u662f None \uff0c\u63d2\u5165\u64cd\u4f5c\u4f1a\u628a\u7b2c\u4e00\u4e2a\u5143\u7d20\u63d2\u5165\u7ed3\u6784\u91cc\uff1b \u7b2c\u4e8c\u79cd\u60c5\u51b5\uff1a head \u6307\u9488\u4e0d\u662f None \uff0c\uff0c\u7b2c\u4e8c\u4e2a\u5143\u7d20\u4f1a\u88ab\u63d2\u5165\u8fd9\u4e2a\u7ed3\u6784\u7684\u5f00\u5934\uff1b \u4ece\u4e0a\u97622\u79cd\u60c5\u51b5\u5f97\u51fa\uff0c\u5728\u5df2\u7ecf\u6709\u6570\u636e\u7684\u60c5\u51b5\u4e0b\uff0c\u5e76\u4e0d\u9700\u8981\u901a\u8fc7\u590d\u5236\u6570\u636e\u6765\u8ba9\u5b83\u4eec\u5411\u540e\u79fb\u52a8\uff0c\u4e5f\u4e0d\u9700\u8981\u989d\u5916\u7684\u5185\u5b58\u3002\u8fd9\u4e5f\u5c31\u610f\u5473\u7740\u5728\u94fe\u63a5\u7ed3\u6784\u7684\u5f00\u5934\u5904\u63d2\u5165\u6570\u636e\u53ea\u4f1a\u7528\u5230\u5e38\u6570\u7684\u65f6\u95f4\u548c\u5185\u5b58\uff0c\u8fd9\u548c\u5bf9\u6570\u7ec4\u7684\u76f8\u540c\u64cd\u4f5c\u662f\u4e0d\u4e00\u6837\u7684\u3002 \u4e0b\u9762\u662f\u5b8c\u6574\u7684\u4ee3\u7801\u3002 \"\"\" \u5b9e\u73b0\u4e86\u5bf9\u5355\u5411\u94fe\u63a5\u8fdb\u884c\u5982\u4e0b\u64cd\u4f5c\uff1a 1. \u5728\u5f00\u59cb\u5904\u63d2\u5165 2. \u5728\u7ed3\u5c3e\u5904\u63d2\u5165 3. \u5728\u5f00\u59cb\u5904\u5220\u9664 4. \u5728\u7ed3\u5c3e\u5904\u5220\u9664 5. \u5728\u4efb\u610f\u5904\u63d2\u5165 6. \u5728\u4efb\u610f\u5904\u5220\u9664 \"\"\" class Node ( object ): \"\"\"\u5355\u5411\u94fe\u63a5\u8282\u70b9\u7c7b\"\"\" def __init__ ( self , data , next = None ): \"\"\" \u5b9e\u4f8b\u5316\u4e00\u4e2a\u8282\u70b9, \u9ed8\u8ba4\u540e\u7ee7\u8282\u70b9\u4e3aNone Args: data: \u8282\u70b9\u5b58\u50a8\u7684\u6570\u636e next: \u6307\u5411\u4e0b\u4e00\u4e2a\u8282\u70b9\u7684\u6307\u9488\uff0c\u9ed8\u8ba4\u4e3aNone \"\"\" self . data = data # \u5b9a\u4e49\u8282\u70b9\u7684\u6570\u636e\u90e8\u5206 self . next = next # \u5b9a\u4e49\u8282\u70b9\u7684\u6307\u9488\u90e8\u5206\uff0c\u521d\u59cb\u503c\u4e3aNone\u8868\u793a\u6ca1\u6709\u4e0b\u4e00\u4e2a\u8282\u70b9 def insert_at_beginning ( head , data ): \"\"\" \u5728\u94fe\u8868\u5f00\u59cb\u5904\u63d2\u5165\u65b0\u8282\u70b9 Args: head: \u5f53\u524d\u94fe\u8868\u7684\u5934\u8282\u70b9 data: \u65b0\u8282\u70b9\u7684\u6570\u636e Returns: Node: \u65b0\u7684\u5934\u8282\u70b9 \"\"\" new_node = Node ( data ) # \u521b\u5efa\u65b0\u7684\u8282\u70b9\u5bf9\u8c61 new_node . next = head # \u5c06\u65b0\u8282\u70b9\u7684next\u6307\u9488\u6307\u5411\u5f53\u524d\u5934\u8282\u70b9 return new_node # \u8fd4\u56de\u65b0\u7684\u5934\u8282\u70b9 def insert_at_end ( head , data ): \"\"\" \u5728\u94fe\u8868\u672b\u5c3e\u63d2\u5165\u65b0\u8282\u70b9 Args: head: \u5f53\u524d\u94fe\u8868\u7684\u5934\u8282\u70b9 data: \u65b0\u8282\u70b9\u7684\u6570\u636e Returns: Node: \u5934\u8282\u70b9 \"\"\" new_node = Node ( data ) # \u521b\u5efa\u65b0\u7684\u8282\u70b9\u5bf9\u8c61 if head is None : # \u5982\u679c\u94fe\u8868\u4e3a\u7a7a\uff0c\u5c06\u65b0\u8282\u70b9\u8bbe\u7f6e\u4e3a\u5934\u8282\u70b9 head = new_node else : probe = head # \u521b\u5efa\u4e00\u4e2a\u6307\u9488\uff0c\u4ece\u5934\u8282\u70b9\u5f00\u59cb\u904d\u5386\u94fe\u8868 while probe . next is not None : # \u5f53\u6307\u9488\u6240\u6307\u8282\u70b9\u6709\u4e0b\u4e00\u4e2a\u8282\u70b9\u65f6 probe = probe . next # \u79fb\u52a8\u6307\u9488\u5230\u4e0b\u4e00\u4e2a\u8282\u70b9 probe . next = new_node # \u5c06\u65b0\u8282\u70b9\u8fde\u63a5\u5230\u5f53\u524d\u6307\u9488\u6240\u6307\u8282\u70b9\u7684\u4e0b\u4e00\u4e2a\u4f4d\u7f6e\uff0c\u5b8c\u6210\u8282\u70b9\u7684\u63d2\u5165 return head # \u8fd4\u56de\u5934\u8282\u70b9 def delete_at_beginning ( head ): \"\"\" \u4ece\u94fe\u8868\u5f00\u59cb\u5904\u5220\u9664\u8282\u70b9 Args: head: \u5f53\u524d\u94fe\u8868\u7684\u5934\u8282\u70b9 Returns: Node: \u65b0\u7684\u5934\u8282\u70b9 \"\"\" if head is None : # \u5982\u679c\u94fe\u8868\u4e3a\u7a7a\uff0c\u6253\u5370\u6d88\u606f\u5e76\u8fd4\u56de\u7a7a\u94fe\u8868 print ( \"Linked list is empty.\" ) else : head = head . next # \u5c06\u5934\u8282\u70b9\u6307\u5411\u4e0b\u4e00\u4e2a\u8282\u70b9\uff0c\u5373\u5220\u9664\u7b2c\u4e00\u4e2a\u8282\u70b9 return head # \u8fd4\u56de\u65b0\u7684\u5934\u8282\u70b9 def delete_at_end ( head ): \"\"\" \u4ece\u94fe\u8868\u672b\u5c3e\u5220\u9664\u8282\u70b9 Args: head: \u5f53\u524d\u94fe\u8868\u7684\u5934\u8282\u70b9 Returns: Node: \u5934\u8282\u70b9 \"\"\" if head is None : # \u5982\u679c\u94fe\u8868\u4e3a\u7a7a\uff0c\u8fd4\u56deNone return None if head . next is None : # \u5982\u679c\u94fe\u8868\u53ea\u6709\u4e00\u4e2a\u8282\u70b9\uff0c\u5c06\u5934\u8282\u70b9\u7f6e\u4e3aNone return None current = head while current . next . next : # \u79fb\u52a8\u5230\u5012\u6570\u7b2c\u4e8c\u4e2a\u8282\u70b9 current = current . next current . next = None # \u5c06\u5012\u6570\u7b2c\u4e8c\u4e2a\u8282\u70b9\u7684next\u7f6e\u4e3aNone\uff0c\u5373\u5220\u9664\u4e86\u6700\u540e\u4e00\u4e2a\u8282\u70b9 return head # \u8fd4\u56de\u5934\u8282\u70b9 def insert_at_position ( head , data , position ): \"\"\" \u5728\u94fe\u8868\u7684\u4efb\u610f\u4f4d\u7f6e\u63d2\u5165\u65b0\u8282\u70b9 Args: head: \u5f53\u524d\u94fe\u8868\u7684\u5934\u8282\u70b9 data: \u65b0\u8282\u70b9\u7684\u6570\u636e position: \u63d2\u5165\u7684\u4f4d\u7f6e Returns: Node: \u5934\u8282\u70b9 \"\"\" new_node = Node ( data ) # \u521b\u5efa\u65b0\u7684\u8282\u70b9\u5bf9\u8c61 if position == 0 : # \u5982\u679c\u63d2\u5165\u4f4d\u7f6e\u4e3a0\uff0c\u5373\u5728\u5934\u90e8\u63d2\u5165 new_node . next = head # \u65b0\u8282\u70b9\u7684next\u6307\u5411\u5f53\u524d\u5934\u8282\u70b9 return new_node # \u8fd4\u56de\u65b0\u7684\u5934\u8282\u70b9 probe = head # \u521b\u5efa\u4e00\u4e2a\u6307\u9488\uff0c\u4ece\u5934\u8282\u70b9\u5f00\u59cb\u904d\u5386\u94fe\u8868 count = 0 while probe . next is not None and count < position - 1 : # \u627e\u5230\u63d2\u5165\u4f4d\u7f6e\u7684\u524d\u4e00\u4e2a\u8282\u70b9 probe = probe . next count += 1 new_node . next = probe . next # \u65b0\u8282\u70b9\u7684next\u6307\u5411\u63d2\u5165\u4f4d\u7f6e\u7684\u8282\u70b9 probe . next = new_node # \u63d2\u5165\u4f4d\u7f6e\u7684\u524d\u4e00\u4e2a\u8282\u70b9\u7684next\u6307\u5411\u65b0\u8282\u70b9 return head # \u8fd4\u56de\u5934\u8282\u70b9 def delete_at_position ( head , position ): \"\"\" \u4ece\u94fe\u8868\u7684\u4efb\u610f\u4f4d\u7f6e\u5220\u9664\u8282\u70b9 Args: head: \u5f53\u524d\u94fe\u8868\u7684\u5934\u8282\u70b9 position: \u5220\u9664\u7684\u4f4d\u7f6e Returns: Node: \u5934\u8282\u70b9 \"\"\" if head is None : # \u5982\u679c\u94fe\u8868\u4e3a\u7a7a\uff0c\u8fd4\u56deNone return None if position == 0 : # \u5982\u679c\u5220\u9664\u4f4d\u7f6e\u4e3a0\uff0c\u5373\u5220\u9664\u5934\u90e8\u8282\u70b9 return head . next # \u8fd4\u56de\u5934\u8282\u70b9\u7684\u4e0b\u4e00\u4e2a\u8282\u70b9 probe = head # \u521b\u5efa\u4e00\u4e2a\u6307\u9488\uff0c\u4ece\u5934\u8282\u70b9\u5f00\u59cb\u904d\u5386\u94fe\u8868 count = 0 while probe . next is not None and count < position - 1 : # \u627e\u5230\u5220\u9664\u4f4d\u7f6e\u7684\u524d\u4e00\u4e2a\u8282\u70b9 probe = probe . next count += 1 if probe . next is None : # \u5982\u679c\u5220\u9664\u4f4d\u7f6e\u8d85\u8fc7\u94fe\u8868\u957f\u5ea6\uff0c\u4e0d\u505a\u64cd\u4f5c return head probe . next = probe . next . next # \u5220\u9664\u4f4d\u7f6e\u7684\u524d\u4e00\u4e2a\u8282\u70b9\u7684next\u6307\u5411\u5220\u9664\u4f4d\u7f6e\u7684\u540e\u4e00\u4e2a\u8282\u70b9 return head # \u8fd4\u56de\u5934\u8282\u70b9 def print_linked_list ( head ): \"\"\" \u6253\u5370\u94fe\u8868\u4e2d\u7684\u6240\u6709\u8282\u70b9 Args: head: \u5f53\u524d\u94fe\u8868\u7684\u5934\u8282\u70b9 \"\"\" probe = head while probe is not None : print ( probe . data , end = \" -> \" ) # \u6253\u5370\u5f53\u524d\u8282\u70b9\u7684\u6570\u636e probe = probe . next # \u79fb\u52a8\u5230\u4e0b\u4e00\u4e2a\u8282\u70b9 print ( \"None\" ) # \u6253\u5370\u94fe\u8868\u7ed3\u675f\u7684\u6807\u5fd7 def main (): head = None # \u521b\u5efa\u4e00\u4e2a\u7a7a\u94fe\u8868\uff0c\u521d\u59cb\u65f6\u5934\u8282\u70b9\u4e3aNone # \u4ece\u5c3e\u90e8\u63d2\u5165\u8282\u70b9 for count in range ( 1 , 6 ): # \u4ece1\u52305\u904d\u5386 head = insert_at_end ( head , count ) # \u5728\u5c3e\u90e8\u63d2\u5165\u8282\u70b9 print ( \"\u521d\u59cb\u94fe\u8868:\" ) print_linked_list ( head ) # \u6253\u5370\u539f\u59cb\u94fe\u8868 # \u9a8c\u8bc1\u4ece\u5934\u90e8\u5904\u63d2\u5165\u8282\u70b9 new_data_at_beginning = 0 head = insert_at_beginning ( head , new_data_at_beginning ) # \u5728\u94fe\u8868\u5934\u90e8\u63d2\u5165\u65b0\u8282\u70b9 print ( f \" \\n \u5728\u5934\u90e8\u63d2\u5165 { new_data_at_beginning } \u540e\u7684\u94fe\u8868:\" ) print_linked_list ( head ) # \u6253\u5370\u63d2\u5165\u65b0\u8282\u70b9\u540e\u7684\u94fe\u8868\u72b6\u6001 # \u9a8c\u8bc1\u4ece\u672b\u5c3e\u5904\u63d2\u5165\u8282\u70b9 new_data = 10 head = insert_at_end ( head , new_data ) # \u5728\u94fe\u8868\u672b\u5c3e\u63d2\u5165\u65b0\u8282\u70b9 print ( f \" \\n \u5728\u5c3e\u90e8\u63d2\u5165 { new_data } \u540e\u7684\u94fe\u8868:\" ) print_linked_list ( head ) # \u6253\u5370\u63d2\u5165\u65b0\u8282\u70b9\u540e\u7684\u94fe\u8868\u72b6\u6001 # \u9a8c\u8bc1\u4ece\u5934\u90e8\u5220\u9664\u8282\u70b9 head = delete_at_beginning ( head ) # \u5220\u9664\u7b2c\u4e00\u4e2a\u8282\u70b9 print ( \" \\n \u4ece\u5934\u90e8\u5220\u9664\u8282\u70b9\u540e\u7684\u94fe\u8868:\" ) print_linked_list ( head ) # \u6253\u5370\u5220\u9664\u8282\u70b9\u540e\u7684\u94fe\u8868\u72b6\u6001 # \u9a8c\u8bc1\u4ece\u5c3e\u90e8\u5220\u9664\u8282\u70b9 head = delete_at_end ( head ) # \u4ece\u94fe\u8868\u672b\u5c3e\u5220\u9664\u8282\u70b9 print ( \" \\n \u4ece\u5c3e\u90e8\u5220\u9664\u8282\u70b9\u540e\u7684\u94fe\u8868:\" ) print_linked_list ( head ) # \u6253\u5370\u5220\u9664\u8282\u70b9\u540e\u7684\u94fe\u8868\u72b6\u6001 # \u9a8c\u8bc1\u4ece\u4efb\u610f\u4f4d\u7f6e\u63d2\u5165\u8282\u70b9 position = 3 new_data = 99 head = insert_at_position ( head , new_data , position ) # \u5728\u7b2c3\u4e2a\u4f4d\u7f6e\u63d2\u5165\u8282\u70b9 print ( f \" \\n \u5728\u4f4d\u7f6e { position } \u63d2\u5165 { new_data } \u540e\u7684\u94fe\u8868:\" ) print_linked_list ( head ) # \u9a8c\u8bc1\u4ece\u4efb\u610f\u4f4d\u7f6e\u5220\u9664\u8282\u70b9 position = 2 head = delete_at_position ( head , position ) # \u5220\u9664\u7b2c2\u4e2a\u4f4d\u7f6e\u7684\u8282\u70b9 print ( f \" \\n \u5728\u4f4d\u7f6e { position } \u63d2\u5165 { new_data } \u540e\u7684\u94fe\u8868:\" ) print_linked_list ( head ) if __name__ == \"__main__\" : main () # \u8fd0\u884c\u7ed3\u679c # \u521d\u59cb\u94fe\u8868: # 1 -> 2 -> 3 -> 4 -> 5 -> None # \u5728\u5934\u90e8\u63d2\u5165 0 \u540e\u7684\u94fe\u8868: # 0 -> 1 -> 2 -> 3 -> 4 -> 5 -> None # \u5728\u5c3e\u90e8\u63d2\u5165 10 \u540e\u7684\u94fe\u8868: # 0 -> 1 -> 2 -> 3 -> 4 -> 5 -> 10 -> None # \u4ece\u5934\u90e8\u5220\u9664\u8282\u70b9\u540e\u7684\u94fe\u8868: # 1 -> 2 -> 3 -> 4 -> 5 -> 10 -> None # \u4ece\u5c3e\u90e8\u5220\u9664\u8282\u70b9\u540e\u7684\u94fe\u8868: # 1 -> 2 -> 3 -> 4 -> 5 -> None # \u5728\u4f4d\u7f6e 3 \u63d2\u5165 99 \u540e\u7684\u94fe\u8868: # 1 -> 2 -> 3 -> 99 -> 4 -> 5 -> None # \u5728\u4f4d\u7f6e 2 \u63d2\u5165 99 \u540e\u7684\u94fe\u8868: # 1 -> 2 -> 99 -> 4 -> 5 -> None 4.5.5.\u5728\u7ed3\u5c3e\u5904\u63d2\u5165 \u00b6 \u5bf9\u4e8e\u5355\u5411\u94fe\u63a5\u7ed3\u6784\uff0c\u5728\u7ed3\u5c3e\u5904\u63d2\u5165\u65f6\u9700\u8981\u8003\u8651\u4e24\u79cd\u60c5\u51b5\uff1a \u5f53 head \u6307\u9488\u662f None \u65f6\uff0c\u5b83\u4f1a\u88ab\u8bbe\u7f6e\u4e3a\u65b0\u8282\u70b9\u3002 \u5f53 head \u6307\u9488\u4e0d\u662f None \u65f6\uff0c\u4ee3\u7801\u4f1a\u627e\u5230\u6700\u540e\u4e00\u4e2a\u8282\u70b9\uff0c\u5e76\u628a\u5b83\u7684\u4e0b\u4e00\u4e2a\u6307\u9488\u6307\u5411\u65b0\u8282\u70b9\u3002 \u56e0\u6b64\u5728\u6709\u6570\u636e\u7684\u60c5\u51b5\u4e0b\uff0c\u4f1a\u7528\u5230\u904d\u5386\u6a21\u5f0f\u3002 4.5.6.\u5728\u5f00\u59cb\u5904\u5220\u9664 \u00b6 \u5728\u6267\u884c\u4ece\u94fe\u63a5\u7ed3\u6784\u7684\u5f00\u5934\u5220\u9664\u5143\u7d20\u7684\u64cd\u4f5c\u65f6\uff0c\u901a\u5e38\u90fd\u4f1a\u5047\u5b9a\u7ed3\u6784\u91cc\u81f3\u5c11\u5b58\u5728\u4e00\u4e2a\u8282\u70b9\uff0c\u8fd9\u4e2a\u64cd\u4f5c\u5c06\u8fd4\u56de\u88ab\u5220\u9664\u7684\u5143\u7d20\u3002 \u8fd9\u4e2a\u64cd\u4f5c\u4f1a\u7528\u5230\u5e38\u6570\u7684\u65f6\u95f4\u548c\u5185\u5b58\uff0c\u8fd9\u4e0e\u5728\u6570\u7ec4\u4e0a\u6267\u884c\u76f8\u540c\u7684\u64cd\u4f5c\u662f\u6709\u6240\u4e0d\u540c\u7684\u3002 4.5.7.\u5728\u7ed3\u5c3e\u5904\u5220\u9664 \u00b6 \u5355\u5411\u94fe\u63a5\u7ed3\u6784\u4e2d\u7684\u8fd9\u4e2a\u64cd\u4f5c\u5047\u5b9a\u5728\u7ed3\u6784\u91cc\u81f3\u5c11\u6709\u4e00\u4e2a\u8282\u70b9\uff0c\u8fd9\u6837\u5c31\u6709\u4e24\u79cd\u60c5\u51b5\u9700\u8981\u8003\u8651\u3002 \u53ea\u6709\u4e00\u4e2a\u8282\u70b9\uff0c\u8fd9\u65f6\u53ea\u9700\u8981\u628ahead\u6307\u9488\u8bbe\u7f6e\u4e3a None \u3002 \u6700\u540e\u4e00\u4e2a\u8282\u70b9\u4e4b\u524d\u8fd8\u6709\u4e00\u4e2a\u8282\u70b9\u3002\u8fd9\u65f6\u76f8\u5e94\u7684\u4ee3\u7801\u4f1a\u627e\u5230\u5012\u6570\u7b2c\u4e8c\u4e2a\u8282\u70b9\uff0c\u5e76\u628a\u4e0b\u4e00\u4e2a\u6307\u9488\u8bbe\u7f6e\u4e3a None \u3002 \u65e0\u8bba\u662f\u54ea\u79cd\u60c5\u51b5\uff0c\u4ee3\u7801\u90fd\u4f1a\u8fd4\u56de\u8fd9\u4e2a\u88ab\u5220\u9664\u8282\u70b9\u91cc\u5305\u542b\u7684\u6570\u636e\u5143\u7d20\u3002 \u8fd9\u4e2a\u64cd\u4f5c\u4f1a\u7528\u5230\u5e38\u6570\u7684\u65f6\u95f4\u548c\u5185\u5b58\u3002 4.5.8.\u5728\u4efb\u610f\u4f4d\u7f6e\u5904\u63d2\u5165 \u00b6 \u5728\u94fe\u63a5\u7ed3\u6784\u7684\u4efb\u610f\u4f4d\u7f6e\u63d2\u5165\u5143\u7d20\u65f6\u9700\u8981\u8003\u86512\u79cd\u60c5\u51b5\uff1a \u5728\u5f00\u5934\u63d2\u5165\uff0c\u53ef\u4ee5\u7528\u524d\u9762\u63d0\u5230\u7684\u4ee3\u7801\u3002 \u5728\u5176\u4ed6\u4f4d\u7f6e i \u5904\u8981\u8fdb\u884c\u63d2\u5165\uff0c\u63d2\u5165\u64cd\u4f5c\u5fc5\u987b\u8981\u5148\u627e\u5230\u4f4d\u7f6e i-1 \uff08\u5982\u679c i=n \uff09\u5904\u7684\u8282\u70b9\u3002\u8fd9\u6837\uff0c\u5c31\u6709\u4e24\u79cd\u60c5\u51b5\u9700\u8981\u8003\u8651\u3002 \u8fd9\u4e2a\u8282\u70b9\u540e\u9762\u7684\u6307\u9488\u662f None \u3002\u8fd9\u610f\u5473\u7740 i>=n \uff0c\u56e0\u6b64\u5e94\u8be5\u628a\u65b0\u7684\u5143\u7d20\u653e\u5728\u94fe\u63a5\u7ed3\u6784\u7684\u672b\u5c3e\u3002 \u8fd9\u4e2a\u8282\u70b9\u540e\u9762\u7684\u6307\u9488\u4e0d\u662fNone\u3002\u8fd9\u610f\u5473\u7740 0=n \u2014\u2014\u5220\u9664\u6700\u540e\u4e00\u4e2a\u8282\u70b9\u3002 \u5047\u8bbe\u5728\u94fe\u63a5\u7ed3\u6784\u91cc\u81f3\u5c11\u6709\u4e00\u4e2a\u8282\u70b9\u3002\u8fd9\u4e2a\u64cd\u4f5c\u7684\u6a21\u5f0f\u548c\u63d2\u5165\u64cd\u4f5c\u7684\u6a21\u5f0f\u662f\u7c7b\u4f3c\u7684\uff0c\u56e0\u6b64\u4e5f\u8981\u907f\u514d\u5728\u641c\u7d22\u8fc7\u7a0b\u4e2d\u8d85\u51fa\u94fe\u63a5\u7ed3\u6784\u7684\u672b\u5c3e\u3002\u4f46\u662f\u5728\u8fd9\u4e2a\u8fc7\u7a0b\u4e2d\uff0c\u4f60\u5fc5\u987b\u5141\u8bb8probe\u6307\u9488\u53ef\u4ee5\u8bbf\u95ee\u5230\u94fe\u63a5\u7ed3\u6784\u7684\u5012\u6570\u7b2c\u4e8c\u4e2a\u8282\u70b9\u3002 4.5.10.\u590d\u6742\u5ea6\u7684\u6743\u8861\uff1a\u65f6\u95f4\u3001\u7a7a\u95f4\u548c\u5355\u5411\u94fe\u63a5\u7ed3\u6784 \u00b6 \u5355\u5411\u94fe\u63a5\u7ed3\u6784\u5404\u9879\u64cd\u4f5c\u7684\u8fd0\u884c\u65f6\u590d\u6742\u5ea6 \u64cd\u4f5c \u8fd0\u884c\u65f6\u590d\u6742\u5ea6 \u5728\u4f4d\u7f6ei\u5904\u8bbf\u95ee O(n)\uff0c\uff0c\u5e73\u5747\u60c5\u51b5\u4e0b \u5728\u4f4d\u7f6ei\u5904\u66ff\u6362 O(n)\uff0c\u6700\u597d\u548c\u6700\u574f\u60c5\u51b5\u4e0b \u5728\u5f00\u59cb\u5904\u63d2\u5165 O(1)\uff0c\u6700\u597d\u548c\u6700\u574f\u60c5\u51b5\u4e0b \u5728\u5f00\u59cb\u5904\u5220\u9664 O(1)\uff0c\u6700\u597d\u548c\u6700\u574f\u60c5\u51b5\u4e0b \u5728\u4f4d\u7f6ei\u5904\u63d2\u5165 O(n)\uff0c\u5e73\u5747\u60c5\u51b5\u4e0b \u5728\u4f4d\u7f6ei\u5904\u5220\u9664 O(n)\uff0c\u5e73\u5747\u60c5\u51b5\u4e0b \u4e0e\u6570\u7ec4\u76f8\u6bd4\uff0c\u5355\u5411\u94fe\u63a5\u7ed3\u6784\u7684\u4e3b\u8981\u4f18\u52bf\u5e76\u4e0d\u5728\u4e8e\u65f6\u95f4\u590d\u6742\u5ea6\u800c\u5728\u4e8e\u5185\u5b58\u6027\u80fd\u3002 \u8c03\u6574\u6570\u7ec4\u5c3a\u5bf8\uff08\u5728\u9700\u8981\u7684\u65f6\u5019\u6267\u884c\uff09\uff0c\u4f7f\u5176\u5728\u65f6\u95f4\u548c\u5185\u5b58\u4e0a\u90fd\u662f\u7ebf\u6027\u7684\uff1b\u8c03\u6574\u94fe\u63a5\u7ed3\u6784\u7684\u5927\u5c0f\uff08\u4f1a\u5728\u63d2\u5165\u6216\u5220\u9664\u65f6\u53d1\u751f\uff09\u5728\u65f6\u95f4\u548c\u5185\u5b58\u4e0a\u90fd\u662f\u5e38\u6570\u590d\u6742\u5ea6\u3002 \u5728\u94fe\u63a5\u7ed3\u6784\u91cc\uff0c\u4e0d\u4f1a\u6709\u5185\u5b58\u7684\u6d6a\u8d39\uff0c\u56e0\u4e3a\u8fd9\u4e2a\u7ed3\u6784\u7684\u7269\u7406\u5c3a\u5bf8\u6c38\u8fdc\u90fd\u4e0d\u4f1a\u8d85\u8fc7\u903b\u8f91\u5c3a\u5bf8\u3002 \u94fe\u63a5\u7ed3\u6784\u7684\u786e\u4f1a\u4ea7\u751f\u4e00\u4e9b\u989d\u5916\u7684\u5185\u5b58\u5f00\u9500\uff0c\u8fd9\u662f\u56e0\u4e3a\u5355\u5411\u94fe\u63a5\u7ed3\u6784\u5fc5\u987b\u8981\u6709\u989d\u5916\u7684 n \u4e2a\u5185\u5b58\u5355\u5143\u6765\u5b58\u50a8\u6307\u9488\u3002 \u5bf9\u4e8e\u53cc\u5411\u94fe\u63a5\u7ed3\u6784\u6765\u8bf4\uff0c\u5b83\u7684\u8282\u70b9\u91cc\u5305\u542b\u4e24\u4e2a\u94fe\u63a5\uff0c\u56e0\u6b64\u5185\u5b58\u7684\u6210\u672c\u4f1a\u66f4\u9ad8\u4e00\u4e9b\u3002 4.5.11.\u7ec3\u4e60\u9898 \u00b6 1\uff0e\u5047\u8bbe\u5df2\u7ecf\u627e\u5230\u4e86\u4ece\u5355\u5411\u94fe\u63a5\u7ed3\u6784\u91cc\u5220\u9664\u5143\u7d20\u7684\u4f4d\u7f6e\uff0c\u8bf7\u8bf4\u660e\u4ece\u8fd9\u4e2a\u65f6\u5019\u5f00\u59cb\u5b8c\u6210\u5220\u9664\u64cd\u4f5c\u7684\u8fd0\u884c\u65f6\u590d\u6742\u5ea6\u3002 \u89e3\u7b54\uff1a\u5982\u679c\u5df2\u7ecf\u627e\u5230\u4e86\u5355\u5411\u94fe\u8868\u4e2d\u8981\u5220\u9664\u5143\u7d20\u7684\u4f4d\u7f6e\uff0c\u5220\u9664\u64cd\u4f5c\u7684\u8fd0\u884c\u65f6\u590d\u6742\u5ea6\u53d6\u51b3\u4e8e\u5220\u9664\u64cd\u4f5c\u7684\u5177\u4f53\u5b9e\u73b0\u3002\u5728\u5355\u5411\u94fe\u8868\u4e2d\uff0c\u5220\u9664\u4e00\u4e2a\u8282\u70b9\u901a\u5e38\u9700\u8981\u627e\u5230\u5f85\u5220\u9664\u8282\u70b9\u7684\u524d\u9a71\u8282\u70b9\uff0c\u7136\u540e\u5c06\u524d\u9a71\u8282\u70b9\u7684 next \u6307\u9488\u6307\u5411\u5f85\u5220\u9664\u8282\u70b9\u7684\u4e0b\u4e00\u4e2a\u8282\u70b9\uff0c\u4ece\u800c\u5c06\u5f85\u5220\u9664\u8282\u70b9\u4ece\u94fe\u8868\u4e2d\u79fb\u9664\u3002 \u67e5\u627e\u5f85\u5220\u9664\u8282\u70b9\u7684\u65f6\u95f4\u590d\u6742\u5ea6\uff1a\u5728\u6700\u574f\u60c5\u51b5\u4e0b\uff0c\u5982\u679c\u8981\u5220\u9664\u7684\u8282\u70b9\u4f4d\u4e8e\u94fe\u8868\u7684\u672b\u5c3e\uff0c\u6216\u8005\u9700\u8981\u904d\u5386\u6574\u4e2a\u94fe\u8868\u624d\u80fd\u627e\u5230\u5f85\u5220\u9664\u8282\u70b9\uff0c\u67e5\u627e\u64cd\u4f5c\u7684\u65f6\u95f4\u590d\u6742\u5ea6\u4e3aO(n)\uff0c\u5176\u4e2dn\u662f\u94fe\u8868\u7684\u957f\u5ea6\u3002 \u5220\u9664\u8282\u70b9\u7684\u65f6\u95f4\u590d\u6742\u5ea6\uff1a\u5220\u9664\u8282\u70b9\u7684\u64cd\u4f5c\u662f\u5e38\u6570\u65f6\u95f4O(1)\uff0c\u56e0\u4e3a\u5b83\u6d89\u53ca\u7684\u64cd\u4f5c\u90fd\u662f\u57fa\u672c\u7684\u8d4b\u503c\u548c\u6307\u9488\u8c03\u6574\u3002 \u6240\u4ee5\uff0c\u5982\u679c\u5df2\u7ecf\u627e\u5230\u4e86\u5f85\u5220\u9664\u8282\u70b9\u7684\u4f4d\u7f6e\uff0c\u5220\u9664\u64cd\u4f5c\u7684\u8fd0\u884c\u65f6\u590d\u6742\u5ea6\u662fO(n)\u3002 2\uff0e\u53ef\u4ee5\u5bf9\u5355\u5411\u94fe\u63a5\u7ed3\u6784\u91cc\u6309\u987a\u5e8f\u6392\u5217\u7684\u5143\u7d20\u6267\u884c\u4e8c\u5206\u641c\u7d22\u5417\uff1f\u5982\u679c\u4e0d\u53ef\u4ee5\uff0c\u4e3a\u4ec0\u4e48\uff1f \u89e3\u7b54\uff1a\u5728\u666e\u901a\u7684\u5355\u5411\u94fe\u8868\u4e2d\uff0c\u65e0\u6cd5\u76f4\u63a5\u6267\u884c\u4e8c\u5206\u641c\u7d22\u3002\u4e8c\u5206\u641c\u7d22\u901a\u5e38\u57fa\u4e8e\u6570\u7ec4\u8fd9\u79cd\u8fde\u7eed\u5b58\u50a8\u7ed3\u6784\uff0c\u53ef\u4ee5\u76f4\u63a5\u901a\u8fc7\u7d22\u5f15\u8fdb\u884c\u5feb\u901f\u8bbf\u95ee\u3002\u4f46\u5728\u5355\u5411\u94fe\u8868\u4e2d\uff0c\u8981\u67e5\u627e\u4e2d\u95f4\u5143\u7d20\uff0c\u9700\u8981\u904d\u5386\u94fe\u8868\u4ee5\u627e\u5230\u4e2d\u95f4\u4f4d\u7f6e\u3002\u56e0\u4e3a\u94fe\u8868\u7684\u5143\u7d20\u4e0d\u662f\u6309\u7167\u7d22\u5f15\u6392\u5217\u7684\uff0c\u6240\u4ee5\u4e0d\u80fd\u76f4\u63a5\u8fdb\u884c\u4e8c\u5206\u641c\u7d22\u3002 \u5982\u679c\u5e0c\u671b\u5728\u6709\u5e8f\u94fe\u8868\u4e2d\u6267\u884c\u4e8c\u5206\u641c\u7d22\uff0c\u53ef\u4ee5\u8003\u8651\u4f7f\u7528\u53e6\u4e00\u79cd\u6570\u636e\u7ed3\u6784\u2014\u2014\u4e8c\u53c9\u641c\u7d22\u6811\uff08Binary Search Tree\uff09\u3002\u5728\u4e8c\u53c9\u641c\u7d22\u6811\u4e2d\uff0c\u6bcf\u4e2a\u8282\u70b9\u7684\u5de6\u5b50\u6811\u7684\u503c\u5c0f\u4e8e\u8be5\u8282\u70b9\u7684\u503c\uff0c\u53f3\u5b50\u6811\u7684\u503c\u5927\u4e8e\u8be5\u8282\u70b9\u7684\u503c\uff0c\u56e0\u6b64\u53ef\u4ee5\u5229\u7528\u8fd9\u79cd\u6709\u5e8f\u6027\u8fdb\u884c\u5feb\u901f\u641c\u7d22\u3002 3\uff0e\u8bf7\u8bf4\u660e\u4e3a\u4ec0\u4e48Python\u5217\u8868\u4f1a\u4f7f\u7528\u6570\u7ec4\u800c\u4e0d\u662f\u94fe\u63a5\u7ed3\u6784\u6765\u4fdd\u5b58\u5b83\u7684\u5143\u7d20\u3002 \u89e3\u7b54\uff1aPython\u7684\u5217\u8868\u4f7f\u7528\u6570\u7ec4\u800c\u4e0d\u662f\u94fe\u63a5\u7ed3\u6784\u6765\u4fdd\u5b58\u5143\u7d20\uff0c\u4e3b\u8981\u662f\u56e0\u4e3a\u6570\u7ec4\u5728\u968f\u673a\u8bbf\u95ee\uff08\u6839\u636e\u7d22\u5f15\u76f4\u63a5\u8bbf\u95ee\u5143\u7d20\uff09\u548c\u5207\u7247\uff08\u901a\u8fc7[start:stop:step]\u65b9\u5f0f\u622a\u53d6\u5b50\u5217\u8868\uff09\u64cd\u4f5c\u4e0a\u5177\u6709\u66f4\u597d\u7684\u6027\u80fd\u3002\u6570\u7ec4\u7684\u5185\u5b58\u7a7a\u95f4\u662f\u8fde\u7eed\u7684\uff0c\u56e0\u6b64\u53ef\u4ee5\u901a\u8fc7\u7d22\u5f15\u8fc5\u901f\u8ba1\u7b97\u51fa\u5143\u7d20\u7684\u5185\u5b58\u5730\u5740\u3002\u8fd9\u4f7f\u5f97\u968f\u673a\u8bbf\u95ee\u548c\u5207\u7247\u7684\u65f6\u95f4\u590d\u6742\u5ea6\u662fO(1)\uff0c\u5373\u5e38\u6570\u65f6\u95f4\u3002\u800c\u94fe\u63a5\u7ed3\u6784\u5728\u968f\u673a\u8bbf\u95ee\u4e0a\u7684\u65f6\u95f4\u590d\u6742\u5ea6\u901a\u5e38\u662fO(n)\uff0c\u5176\u4e2dn\u662f\u94fe\u8868\u7684\u957f\u5ea6\uff0c\u56e0\u4e3a\u9700\u8981\u4ece\u5934\u8282\u70b9\u5f00\u59cb\u9010\u4e2a\u904d\u5386\u627e\u5230\u76ee\u6807\u8282\u70b9\u3002 \u5728Python\u7684\u5217\u8868\u4e2d\uff0c\u652f\u6301\u901a\u8fc7\u7d22\u5f15\u968f\u673a\u8bbf\u95ee\u5143\u7d20\uff0c\u8fd9\u662f\u56e0\u4e3a\u5217\u8868\u7684\u5143\u7d20\u662f\u4fdd\u5b58\u5728\u4e00\u4e2a\u8fde\u7eed\u7684\u5185\u5b58\u5757\u4e2d\u7684\u3002\u8fd9\u79cd\u8bbe\u8ba1\u4f7f\u5f97Python\u7684\u5217\u8868\u5728\u5927\u591a\u6570\u5e38\u89c1\u64cd\u4f5c\uff08\u4f8b\u5982\u67e5\u627e\u3001\u63d2\u5165\u3001\u5220\u9664\uff09\u4e0a\u90fd\u80fd\u63d0\u4f9b\u8f83\u597d\u7684\u6027\u80fd\uff0c\u7279\u522b\u662f\u5f53\u9700\u8981\u901a\u8fc7\u7d22\u5f15\u6216\u5207\u7247\u5feb\u901f\u8bbf\u95ee\u6216\u4fee\u6539\u5143\u7d20\u65f6\u3002\u7136\u800c\uff0c\u5bf9\u4e8e\u5728\u4e2d\u95f4\u63d2\u5165\u6216\u5220\u9664\u5143\u7d20\u8fd9\u6837\u7684\u64cd\u4f5c\uff0c\u5217\u8868\u7684\u6027\u80fd\u53ef\u80fd\u76f8\u5bf9\u8f83\u4f4e\uff0c\u56e0\u4e3a\u5728\u6570\u7ec4\u4e2d\u95f4\u63d2\u5165\u6216\u5220\u9664\u5143\u7d20\u901a\u5e38\u9700\u8981\u79fb\u52a8\u5176\u4ed6\u5143\u7d20\uff0c\u5bfc\u81f4\u65f6\u95f4\u590d\u6742\u5ea6\u4e3aO(n)\u3002 \u603b\u7684\u6765\u8bf4\uff0cPython\u7684\u5217\u8868\u91c7\u7528\u6570\u7ec4\u5b58\u50a8\u5143\u7d20\uff0c\u662f\u4e3a\u4e86\u5728\u5927\u591a\u6570\u5e38\u89c1\u64cd\u4f5c\u4e2d\u63d0\u4f9b\u8f83\u597d\u7684\u6027\u80fd\u3002\u5982\u679c\u9700\u8981\u5728\u4e2d\u95f4\u63d2\u5165\u6216\u5220\u9664\u5143\u7d20\u7684\u64cd\u4f5c\u6bd4\u8f83\u9891\u7e41\uff0c\u53ef\u80fd\u9700\u8981\u8003\u8651\u4f7f\u7528\u94fe\u8868\u7b49\u6570\u636e\u7ed3\u6784\u3002Python\u4e2d\u7684 collections \u6a21\u5757\u63d0\u4f9b\u4e86 deque \uff08\u53cc\u7aef\u961f\u5217\uff09\u7b49\u6570\u636e\u7ed3\u6784\uff0c\u53ef\u4ee5\u7528\u4e8e\u5728\u4e24\u7aef\u9ad8\u6548\u5730\u8fdb\u884c\u63d2\u5165\u548c\u5220\u9664\u64cd\u4f5c\u3002 \u8865\u5145\uff1a \u67e5\u770b\u6e90\u4ee3\u7801\u7684\u65b9\u6cd5\u3002 import array import inspect # \u83b7\u53d6array\u6a21\u5757\u7684\u6e90\u4ee3\u7801 source_code = inspect . getsource ( array ) # \u6253\u5370\u6e90\u4ee3\u7801 print ( source_code ) \u5bf9\u4e8e\u5185\u7f6e\u7684\u6a21\u5757\uff0c\u4e0d\u80fd\u76f4\u63a5\u901a\u8fc7inspect\u6a21\u5757\u67e5\u770b\u6e90\u4ee3\u7801\u3002\u53ef\u4ee5\u901a\u8fc7\u5728\u7ebf\u67e5\u770bPython\u7684\u6e90\u4ee3\u7801\u3002Python\u7684\u6e90\u4ee3\u7801\u6258\u7ba1\u5728GitHub\u4e0a\uff0c\u4f60\u53ef\u4ee5\u5728\u4ee5\u4e0b\u94fe\u63a5\u4e2d\u627e\u5230Python\u7684\u6e90\u4ee3\u7801\uff1a Python GitHub Repository \uff0c\u5305\u62ec array\u7684\u6e90\u4ee3\u7801 \u3002 4.6.\u94fe\u63a5\u4e0a\u7684\u53d8\u5316 \u00b6 4.6.1.\u5305\u542b\u865a\u62df\u5934\u8282\u70b9\u7684\u73af\u72b6\u94fe\u63a5\u7ed3\u6784 \u00b6 \u5728\u7b2c\u4e00\u4e2a\u8282\u70b9\u4f4d\u7f6e\u5904\u6267\u884c\u63d2\u5165\u548c\u5220\u9664\u64cd\u4f5c\u662f\u5355\u5411\u94fe\u63a5\u7ed3\u6784\u91cc\u5728\u4efb\u610f\u4f4d\u7f6e\u8fdb\u884c\u63d2\u5165\u548c\u5220\u9664\u64cd\u4f5c\u7684\u7279\u6b8a\u60c5\u51b5\uff0c\u662f\u56e0\u4e3a\u8fd9\u4e2a\u65f6\u5019\u5fc5\u987b\u91cd\u7f6ehead\u6307\u9488\u3002 \u53ef\u4ee5\u901a\u8fc7\u5305\u542b\u865a\u62df\u5934\u8282\u70b9\uff08dummy header node\uff09\u7684\u73af\u72b6\u94fe\u63a5\u7ed3\u6784\uff08circular linked structure\uff09\u7b80\u5316\u8fd9\u4e24\u4e2a\u64cd\u4f5c\u3002 \u73af\u72b6\u94fe\u63a5\u7ed3\u6784\u5305\u542b\u4e86\u4ece\u6700\u540e\u4e00\u4e2a\u8282\u70b9\u5230\u7b2c\u4e00\u4e2a\u8282\u70b9\u7684\u94fe\u63a5\uff0c\u5e76\u4e14\u5b83\u7684\u5b9e\u73b0\u91cc\u81f3\u5c11\u4f1a\u5305\u542b\u4e00\u4e2a\u8282\u70b9\u3002\u8fd9\u4e2a\u8282\u70b9\uff08\u865a\u62df\u5934\u8282\u70b9\uff09\u4e0d\u5305\u542b\u4efb\u4f55\u6570\u636e\uff0c\u4f46\u4f1a\u88ab\u7528\u6765\u4f5c\u4e3a\u94fe\u63a5\u7ed3\u6784\u7684\u5f00\u59cb\u548c\u7ed3\u675f\u7684\u6807\u8bb0\u3002\u5728\u6700\u521d\u7684\u7a7a\u94fe\u63a5\u7ed3\u6784\u91cc\uff0chead\u53d8\u91cf\u4f1a\u6307\u5411\u865a\u62df\u5934\u8282\u70b9\uff0c\u800c\u865a\u62df\u5934\u8282\u70b9\u7684\u4e0b\u4e00\u4e2a\u6307\u9488\u4f1a\u6307\u5411\u865a\u62df\u5934\u8282\u70b9\u672c\u8eab\u3002\u5982\u4e0b\u56fe\u6240\u793a\u3002 4.6.2.\u53cc\u5411\u94fe\u63a5\u7ed3\u6784 \u00b6 4.6.3.\u7ec3\u4e60\u9898 \u00b6 1\uff0e\u5305\u542b\u865a\u62df\u5934\u8282\u70b9\u7684\u73af\u72b6\u94fe\u63a5\u7ed3\u6784\u7ed9\u7a0b\u5e8f\u5458\u5e26\u6765\u4e86\u4ec0\u4e48\u597d\u5904\uff1f 2\uff0e\u548c\u5355\u5411\u94fe\u63a5\u7ed3\u6784\u76f8\u6bd4\uff0c\u8bf7\u63cf\u8ff0\u53cc\u5411\u94fe\u63a5\u7ed3\u6784\u7684\u4e00\u4e2a\u597d\u5904\u548c\u4e00\u4e2a\u989d\u5916\u5f00\u9500\u3002 4.7.\u5c0f\u7ed3 \u00b6 \u6570\u636e\u7ed3\u6784\u662f\u4e00\u4e2a\u8868\u793a\u591a\u9879\u96c6\u91cc\u6240\u5305\u542b\u6570\u636e\u7684\u5bf9\u8c61\u3002 \u6570\u7ec4\u662f\u4e00\u79cd\u5728\u5e38\u6570\u65f6\u95f4\u5185\u652f\u6301\u5bf9\u4f4d\u7f6e\u9010\u9879\u968f\u673a\u8bbf\u95ee\u7684\u6570\u636e\u7ed3\u6784\u3002\u5728\u521b\u5efa\u6570\u7ec4\u65f6\uff0c\u4f1a\u4e3a\u5b83\u5206\u914d\u82e5\u5e72\u4e2a\u7528\u6765\u5b58\u653e\u6570\u636e\u7684\u5185\u5b58\u7a7a\u95f4\uff0c\u5e76\u4e14\u6570\u7ec4\u7684\u957f\u5ea6\u4f1a\u4fdd\u6301\u4e0d\u53d8\u3002\u63d2\u5165\u548c\u5220\u9664\u64cd\u4f5c\u9700\u8981\u79fb\u52a8\u6570\u636e\u5143\u7d20\uff0c\u5e76\u4e14\u53ef\u80fd\u9700\u8981\u521b\u5efa\u4e00\u4e2a\u65b0\u7684\u3001\u66f4\u5927\u6216\u66f4\u5c0f\u7684\u6570\u7ec4\u3002 \u4e8c\u7ef4\u6570\u7ec4\u91cc\u7684\u6bcf\u4e2a\u6570\u636e\u503c\u90fd\u4f4d\u4e8e\u77e9\u5f62\u7f51\u683c\u7684\u884c\u548c\u5217\u4e0a\u3002 \u94fe\u63a5\u7ed3\u6784\u662f\u75310\u4e2a\u6216\u591a\u4e2a\u8282\u70b9\u7ec4\u6210\u7684\u6570\u636e\u7ed3\u6784\u3002\u6bcf\u4e2a\u8282\u70b9\u90fd\u5305\u542b\u4e00\u4e2a\u6570\u636e\u5143\u7d20\u548c\u4e00\u4e2a\u6216\u591a\u4e2a\u6307\u5411\u5176\u4ed6\u8282\u70b9\u7684\u94fe\u63a5\u3002 \u5355\u5411\u94fe\u63a5\u7ed3\u6784\u7684\u8282\u70b9\u5305\u542b\u6570\u636e\u5143\u7d20\u548c\u5230\u4e0b\u4e00\u4e2a\u8282\u70b9\u7684\u94fe\u63a5\u3002\u53cc\u5411\u94fe\u63a5\u7ed3\u6784\u91cc\u7684\u8282\u70b9\u8fd8\u5305\u542b\u5230\u524d\u4e00\u4e2a\u8282\u70b9\u7684\u94fe\u63a5\u3002 \u5728\u94fe\u63a5\u7ed3\u6784\u91cc\u8fdb\u884c\u63d2\u5165\u6216\u5220\u9664\u64cd\u4f5c\u4e0d\u9700\u8981\u79fb\u52a8\u6570\u636e\u5143\u7d20\uff0c\u6bcf\u6b21\u6700\u591a\u53ea\u4f1a\u521b\u5efa\u4e00\u4e2a\u8282\u70b9\u3002\u4f46\u662f\uff0c\u5728\u94fe\u63a5\u7ed3\u6784\u91cc\u6267\u884c\u63d2\u5165\u3001\u5220\u9664\u548c\u8bbf\u95ee\u64cd\u4f5c\u9700\u8981\u7684\u65f6\u95f4\u590d\u6742\u5ea6\u90fd\u662f\u7ebf\u6027\u7684\u3002 \u5728\u94fe\u63a5\u7ed3\u6784\u91cc\u4f7f\u7528\u5934\u8282\u70b9\u53ef\u4ee5\u7b80\u5316\u67d0\u4e9b\u64cd\u4f5c\uff0c\u5982\u6dfb\u52a0\u6216\u5220\u9664\u5143\u7d20\u3002 4.8.\u590d\u4e60\u9898 \u00b6 1\uff0e\u6570\u7ec4\u548c\u94fe\u63a5\u7ed3\u6784\u90fd\u662f\uff1a \u62bd\u8c61\u6570\u636e\u7c7b\u578b\uff08ADT\uff09 \u6570\u636e\u7ed3\u6784 2\uff0e\u6570\u7ec4\u7684\u957f\u5ea6\uff1a \u5728\u521b\u5efa\u4e4b\u540e\u5927\u5c0f\u662f\u56fa\u5b9a\u7684 \u5728\u521b\u5efa\u4e4b\u540e\u5927\u5c0f\u53ef\u4ee5\u589e\u52a0\u6216\u51cf\u5c11 3\uff0e\u5728\u6570\u7ec4\u91cc\u8fdb\u884c\u968f\u673a\u8bbf\u95ee\u652f\u6301\u5728\uff1a \u5e38\u6570\u65f6\u95f4\u91cc\u8bbf\u95ee\u6570\u636e \u7ebf\u6027\u65f6\u95f4\u91cc\u8bbf\u95ee\u6570\u636e 4\uff0e\u5355\u5411\u94fe\u63a5\u7ed3\u6784\u91cc\u7684\u6570\u636e\u5305\u542b\u5728\uff1a \u5355\u5143\u91cc \u8282\u70b9\u91cc 5\uff0e\u5bf9\u5355\u5411\u94fe\u63a5\u7ed3\u6784\u6267\u884c\u7684\u5927\u591a\u6570\u64cd\u4f5c\u90fd\u9700\u8981\uff1a \u5e38\u6570\u65f6\u95f4 \u7ebf\u6027\u65f6\u95f4 6\uff0e\u4ece\u4ee5\u4e0b\u54ea\u79cd\u7c7b\u578b\u91cc\u5220\u9664\u7b2c\u4e00\u4e2a\u5143\u7d20\u9700\u8981\u5e38\u6570\u65f6\u95f4\uff1a \u6570\u7ec4 \u5355\u5411\u94fe\u63a5\u7ed3\u6784 7\uff0e\u5728\u4e0b\u9762\u54ea\u79cd\u60c5\u51b5\u4e0b\uff0c\u6570\u7ec4\u91cc\u4f7f\u7528\u7684\u5185\u5b58\u4f1a\u5c11\u4e8e\u5355\u5411\u94fe\u63a5\u7ed3\u6784\u7684\uff1a \u4e0d\u5230\u4e00\u534a\u7684\u4f4d\u7f6e\u653e\u7f6e\u4e86\u6570\u636e \u4e00\u534a\u4ee5\u4e0a\u7684\u4f4d\u7f6e\u653e\u7f6e\u4e86\u6570\u636e 8\uff0e\u5f53\u6570\u7ec4\u7684\u5185\u5b58\u4e0d\u8db3\u4ee5\u4fdd\u5b58\u6570\u636e\u65f6\uff0c\u6700\u597d\u521b\u5efa\u4e00\u4e2a\u65b0\u7684\u6570\u7ec4\uff0c\u8fd9\u4e2a\u65b0\u6570\u7ec4\u5e94\u8be5\uff1a \u5927\u5c0f\u6bd4\u65e7\u6570\u7ec4\u591a1\u4e2a\u4f4d\u7f6e \u5927\u5c0f\u662f\u65e7\u6570\u7ec4\u76842\u500d 9\uff0e\u5bf9\u4e8e\u5355\u5411\u94fe\u63a5\u7ed3\u6784\uff0c\u5f53\u4f60\u5728\u4ec0\u4e48\u5730\u65b9\u6267\u884c\u63d2\u5165\u64cd\u4f5c\u4f1a\u5f97\u5230\u6700\u574f\u60c5\u51b5\u4e0b\u7684\u8fd0\u884c\u65f6\uff1a \u5728\u7ed3\u6784\u7684\u5f00\u5934 \u5728\u7ed3\u6784\u7684\u672b\u5c3e 10\uff0e\u53cc\u5411\u94fe\u63a5\u7ed3\u6784\u8ba9\u7a0b\u5e8f\u5458\u53ef\u4ee5\u79fb\u52a8\u5230\uff1a \u7ed9\u5b9a\u8282\u70b9\u7684\u540e\u4e00\u4e2a\u8282\u70b9\u6216\u524d\u4e00\u4e2a\u8282\u70b9 \u7ed9\u5b9a\u8282\u70b9\u7684\u540e\u4e00\u4e2a\u8282\u70b9 4.9.\u7f16\u7a0b\u7ec3\u4e60 \u00b6 \u5728\u524d6\u4e2a\u9879\u76ee\u91cc\uff0c\u4f60\u5c06\u4fee\u6539\u5728\u672c\u7ae0\u5b9a\u4e49\u7684Array\u7c7b\uff0c\u4ece\u800c\u8ba9\u5b83\u66f4\u50cfPython\u7684list\u7c7b\u3002\u5bf9\u4e8e\u8fd9\u4e9b\u9879\u76ee\u7684\u7b54\u6848\uff0c\u8bf7\u5305\u542b\u4f60\u5bf9Array\u7c7b\u6240\u505a\u4fee\u6539\u7684\u4ee3\u7801\u6d4b\u8bd5\u3002 1\uff0e\u4e3aArray\u7c7b\u6dfb\u52a0\u4e00\u4e2a\u5b9e\u4f8b\u53d8\u91cf logicalSize \u3002\u8fd9\u4e2a\u53d8\u91cf\u7684\u521d\u59cb\u503c\u4e3a 0 \uff0c\u7528\u6765\u8bb0\u5f55\u6570\u7ec4\u91cc\u5f53\u524d\u5df2\u7ecf\u5305\u542b\u7684\u5143\u7d20\u6570\u91cf\u3002\u7136\u540e\u4e3aArray\u7c7b\u6dfb\u52a0 size() \u65b9\u6cd5\uff0c\u8fd9\u4e2a\u65b9\u6cd5\u7528\u6765\u8fd4\u56de\u6570\u7ec4\u7684\u903b\u8f91\u5c3a\u5bf8\u3002 __len__ \u65b9\u6cd5\u4f9d\u7136\u4f1a\u8fd4\u56de\u6570\u7ec4\u7684\u5bb9\u91cf\uff0c\u4e5f\u5c31\u662f\u5b83\u7684\u7269\u7406\u5c3a\u5bf8\u3002 2\uff0e\u4e3aArray\u7c7b\u7684 __getitem__ \u548c_ _setitem__ \u65b9\u6cd5\u6dfb\u52a0\u5148\u9a8c\u6761\u4ef6\u3002\u5b83\u4eec\u7684\u5148\u9a8c\u6761\u4ef6\u662f 0<=index < size() \u3002\u5982\u679c\u4e0d\u6ee1\u8db3\u5148\u9a8c\u6761\u4ef6\uff0c\u5c31\u5f15\u53d1\u5f02\u5e38\u3002 3\uff0e\u5c06 grow \u548c shrink \u65b9\u6cd5\u6dfb\u52a0\u5230Array\u7c7b\u3002\u5b83\u4eec\u80fd\u591f\u57fa\u4e8e\u672c\u7ae0\u6240\u8ba8\u8bba\u7684\u7b56\u7565\u6765\u589e\u52a0\u6216\u51cf\u5c11\u6570\u7ec4\u91cc\u6240\u5305\u542b\u7684\u5217\u8868\u957f\u5ea6\u3002\u5728\u5b9e\u73b0\u65f6\uff0c\u8981\u4fdd\u8bc1\u6570\u7ec4\u7684\u7269\u7406\u5c3a\u5bf8\u4e0d\u4f1a\u7f29\u5c0f\u5230\u7528\u6237\u6307\u5b9a\u7684\u5bb9\u91cf\u4e4b\u4e0b\uff0c\u5e76\u4e14\u5728\u589e\u52a0\u6570\u7ec4\u5c3a\u5bf8\u65f6\uff0c\u6570\u7ec4\u7684\u5185\u5b58\u5355\u5143\u5c06\u4f1a\u7528\u9ed8\u8ba4\u503c\u6765\u586b\u5145\u3002 4\uff0e\u5c06\u65b9\u6cd5 insert \u548c pop \u6dfb\u52a0\u5230Array\u7c7b\u4e2d\u3002\u5b83\u4eec\u57fa\u4e8e\u672c\u7ae0\u5df2\u7ecf\u8ba8\u8bba\u8fc7\u7684\u7b56\u7565\uff0c\u5728\u9700\u8981\u7684\u65f6\u5019\u5bf9\u6570\u7ec4\u7684\u957f\u5ea6\u8fdb\u884c\u8c03\u6574\u3002 insert \u65b9\u6cd5\u4f1a\u63a5\u6536\u4e00\u4e2a\u4f4d\u7f6e\u548c\u4e00\u4e2a\u5143\u7d20\u503c\u4f5c\u4e3a\u53c2\u6570\uff0c\u7136\u540e\u628a\u8fd9\u4e2a\u5143\u7d20\u63d2\u5165\u6307\u5b9a\u7684\u4f4d\u7f6e\u3002\u5982\u679c\u4f4d\u7f6e\u5927\u4e8e\u6216\u7b49\u4e8e\u6570\u7ec4\u7684\u903b\u8f91\u5c3a\u5bf8\uff0c\u90a3\u4e48\u8fd9\u4e2a\u65b9\u6cd5\u4f1a\u628a\u5143\u7d20\u63d2\u5165\u6570\u7ec4\u91cc\u5f53\u524d\u53ef\u83b7\u5f97\u7684\u6700\u540e\u4e00\u4e2a\u5143\u7d20\u4e4b\u540e\u3002 pop \u65b9\u6cd5\u4f1a\u63a5\u6536\u4e00\u4e2a\u4f4d\u7f6e\u4f5c\u4e3a\u53c2\u6570\uff0c\u7136\u540e\u5220\u9664\u5e76\u8fd4\u56de\u8fd9\u4e2a\u4f4d\u7f6e\u7684\u5143\u7d20\u3002 pop \u65b9\u6cd5\u7684\u5148\u9a8c\u6761\u4ef6\u662f 0<=index < size() \u3002 pop \u65b9\u6cd5\u8fd8\u5e94\u8be5\u628a\u817e\u51fa\u6765\u7684\u6570\u7ec4\u5185\u5b58\u5355\u5143\u91cd\u7f6e\u4e3a\u586b\u5145\u503c\u3002 5\uff0e\u5c06\u65b9\u6cd5 __eq__ \u6dfb\u52a0\u5230Array\u7c7b\u4e2d\u3002\u5f53Array\u5bf9\u8c61\u4f5c\u4e3a == \u8fd0\u7b97\u7b26\u7684\u5de6\u64cd\u4f5c\u6570\u65f6\uff0cPython\u4f1a\u8fd0\u884c\u8fd9\u4e2a\u65b9\u6cd5\u3002\u5982\u679c\u8fd9\u4e2a\u65b9\u6cd5\u7684\u53c2\u6570\u4e5f\u662f\u4e00\u4e2aArray\u5bf9\u8c61\uff0c\u5e76\u4e14\u5b83\u7684\u903b\u8f91\u5c3a\u5bf8\u548c\u5de6\u64cd\u4f5c\u6570\u76f8\u540c\uff0c\u4e14\u5728\u4e24\u4e2a\u6570\u7ec4\u91cc\u6bcf\u4e2a\u903b\u8f91\u4f4d\u7f6e\u4e0a\u7684\u5143\u7d20\u90fd\u76f8\u7b49\uff0c\u90a3\u4e48\u8fd9\u4e2a\u65b9\u6cd5\u4f1a\u8fd4\u56de True \uff1b\u5426\u5219\uff0c\u8fd9\u4e2a\u65b9\u6cd5\u8fd4\u56de False \u3002 6\uff0e\u4e3a\u4e86\u8ba9Array\u7c7b\u548c\u5217\u8868\u4e00\u6837\uff0c\u5e94\u8be5\u5220\u9664 __iter__ \u65b9\u6cd5\u7684\u5f53\u524d\u5b9e\u73b0\u3002\u8bf7\u89e3\u91ca\u8fd9\u4e3a\u4ec0\u4e48\u662f\u4e00\u4e2a\u597d\u5efa\u8bae\uff0c\u5e76\u8bf4\u660e\u5728\u8fd9\u4e2a\u60c5\u51b5\u4e0b\u5e94\u8be5\u5982\u4f55\u5bf9 __str__ \u65b9\u6cd5\u8fdb\u884c\u4fee\u6539\u3002 7\uff0e Matrix \u7c7b\u53ef\u4ee5\u6267\u884c\u7ebf\u6027\u4ee3\u6570\u91cc\u7684\u67d0\u4e9b\u8fd0\u7b97\uff0c\u6bd4\u5982\u77e9\u9635\u8fd0\u7b97\u3002\u5f00\u53d1\u4e00\u4e2a\u4f7f\u7528\u5185\u7f6e\u8fd0\u7b97\u7b26\u8fdb\u884c\u7b97\u672f\u8fd0\u7b97\u7684 Matrix \u7c7b\uff0c\u8fd9\u4e2a Matrix \u7c7b\u5e94\u6269\u5c55\u81ea Grid \u7c7b\u3002\u5728\u63a5\u4e0b\u6765\u76844\u4e2a\u9879\u76ee\u91cc\uff0c\u4f60\u5e94\u5b9a\u4e49\u4e00\u4e9b\u7528\u6765\u64cd\u4f5c\u94fe\u63a5\u7ed3\u6784\u7684\u51fd\u6570\u3002\u5728\u89e3\u7b54\u7684\u8fc7\u7a0b\u4e2d\uff0c\u4f60\u5e94\u8be5\u7ee7\u7eed\u4f7f\u7528\u672c\u7ae0\u5b9a\u4e49\u7684 Node \u548c TwoWayNode \u7c7b\u3002\u521b\u5efa\u4e00\u4e2a\u6d4b\u8bd5\u6a21\u5757\u4ee5\u5305\u542b\u4f60\u7684\u51fd\u6570\u5b9a\u4e49\u548c\u7528\u6765\u6d4b\u8bd5\u5b83\u4eec\u7684\u4ee3\u7801\u3002 8\uff0e\u5b9a\u4e49\u4e00\u4e2a\u53eb\u4f5c length \u7684\u51fd\u6570\uff08\u4e0d\u662f len \uff09\uff0c\u8fd9\u4e2a\u51fd\u6570\u4f1a\u63a5\u53d7\u4e00\u4e2a\u5355\u5411\u94fe\u63a5\u7ed3\u6784\u4f5c\u4e3a\u53c2\u6570\uff0c\u5e76\u80fd\u591f\u8fd4\u56de\u7ed3\u6784\u91cc\u7684\u5143\u7d20\u6570\u91cf\u3002 9\uff0e\u5b9a\u4e49\u4e00\u4e2a\u53eb\u4f5c insert \u7684\u51fd\u6570\uff0c\u8fd9\u4e2a\u51fd\u6570\u5177\u6709\u628a\u5143\u7d20\u63d2\u5165\u5355\u5411\u94fe\u63a5\u7ed3\u6784\u4e2d\u6307\u5b9a\u4f4d\u7f6e\u7684\u529f\u80fd\u3002\u8fd9\u4e2a\u51fd\u6570\u67093\u4e2a\u53c2\u6570\uff1a\u5143\u7d20\u3001\u4f4d\u7f6e\u4ee5\u53ca\u4e00\u4e2a\u94fe\u63a5\u7ed3\u6784\uff08\u8fd9\u4e2a\u94fe\u63a5\u7ed3\u6784\u53ef\u80fd\u4e3a\u7a7a\uff09\u3002\u8fd9\u4e2a\u51fd\u6570\u80fd\u591f\u8fd4\u56de\u4fee\u6539\u4e4b\u540e\u7684\u94fe\u63a5\u7ed3\u6784\u3002\u5982\u679c\u4f20\u9012\u7684\u4f4d\u7f6e\u5927\u4e8e\u6216\u7b49\u4e8e\u94fe\u63a5\u7ed3\u6784\u7684\u957f\u5ea6\uff0c\u90a3\u4e48\u8fd9\u4e2a\u51fd\u6570\u4f1a\u628a\u5143\u7d20\u63d2\u5165\u5b83\u7684\u672b\u5c3e\u3002\u8fd9\u4e2a\u51fd\u6570\u7684\u8c03\u7528\u793a\u4f8b\u662f head =insert(1,data,head) \uff0c\u5176\u4e2d head \u662f\u4e00\u4e2a\u53d8\u91cf\uff0c\u8fd9\u4e2a\u53d8\u91cf\u8981\u4e48\u4e3a\u7a7a\u94fe\u63a5\uff0c\u8981\u4e48\u6307\u5411\u94fe\u63a5\u7ed3\u6784\u7684\u7b2c\u4e00\u4e2a\u8282\u70b9\u3002 10\uff0e\u5b9a\u4e49\u4e00\u4e2a\u53eb\u4f5c pop \u7684\u51fd\u6570\uff0c\u8fd9\u4e2a\u51fd\u6570\u80fd\u591f\u5728\u5355\u5411\u94fe\u63a5\u7ed3\u6784\u7684\u6307\u5b9a\u4f4d\u7f6e\u4e0a\u5220\u9664\u5143\u7d20\u3002\u8fd9\u4e2a\u51fd\u6570\u7684\u7b2c\u4e00\u4e2a\u53c2\u6570\u662f\u4f4d\u7f6e\uff0c\u5b83\u7684\u5148\u9a8c\u6761\u4ef6\u662f 0<=position<\u7ed3\u6784\u7684\u957f\u5ea6 \u3002\u5b83\u7684\u7b2c\u4e8c\u4e2a\u53c2\u6570\u662f\u4e00\u4e2a\u94fe\u63a5\u7ed3\u6784\uff0c\u5f88\u660e\u663e\u5b83\u4e0d\u5e94\u8be5\u4e3a\u7a7a\u3002\u8fd9\u4e2a\u51fd\u6570\u5c06\u4f1a\u8fd4\u56de\u4e00\u4e2a\u5143\u7ec4\uff0c\u5305\u542b\u4fee\u6539\u540e\u7684\u94fe\u63a5\u7ed3\u6784\u548c\u5220\u9664\u7684\u5143\u7d20\u3002\u5b83\u7684\u8c03\u7528\u793a\u4f8b\u662f (head, item) = pop(1,head) \u3002 11\uff0e\u5b9a\u4e49\u4e00\u4e2a\u51fd\u6570 makeTwoWay \uff0c\u8fd9\u4e2a\u51fd\u6570\u4f1a\u63a5\u53d7\u4e00\u4e2a\u5355\u5411\u94fe\u63a5\u7ed3\u6784\u4f5c\u4e3a\u53c2\u6570\uff0c\u7136\u540e\u751f\u6210\u5e76\u8fd4\u56de\u4e00\u4e2a\u5305\u542b\u5355\u5411\u94fe\u63a5\u7ed3\u6784\u91cc\u7684\u5143\u7d20\u7684\u53cc\u5411\u94fe\u63a5\u7ed3\u6784\u3002\uff08\u6ce8\u610f\uff1a\u8fd9\u4e2a\u51fd\u6570\u4e0d\u5e94\u8be5\u5bf9\u4f5c\u4e3a\u53c2\u6570\u7684\u94fe\u63a5\u7ed3\u6784\u8fdb\u884c\u4efb\u4f55\u4fee\u6539\u3002\uff09","title":"\u6570\u7ec4\u548c\u94fe\u63a5\u7ed3\u6784"},{"location":"python/DataStructure/04_ArrayChain/#4","text":"\u6570\u636e\u7ed3\u6784\uff08data structure\uff09\u6216\u5177\u4f53\u6570\u636e\u7c7b\u578b\uff08concrete data type\uff09\u662f\u6307\u4e00\u7ec4\u6570\u636e\u7684\u5185\u90e8\u5b58\u50a8\u65b9\u5f0f\u3002 \u6570\u7ec4\uff08array\uff09\u548c\u94fe\u63a5\u7ed3\u6784\uff08linked structure\uff09\u8fd9\u4e24\u79cd\u6570\u636e\u7ed3\u6784\u662f\u7f16\u7a0b\u8bed\u8a00\u91cc\u591a\u9879\u96c6\u6700\u5e38\u7528\u7684\u5b9e\u73b0\u3002 \u76ee\u6807\uff1a \u521b\u5efa\u6570\u7ec4\uff1b \u5bf9\u6570\u7ec4\u6267\u884c\u5404\u79cd\u64cd\u4f5c\uff1b \u786e\u5b9a\u6570\u7ec4\u76f8\u5173\u64cd\u4f5c\u7684\u8fd0\u884c\u65f6\u548c\u5185\u5b58\u7684\u4f7f\u7528\u60c5\u51b5\uff1b \u57fa\u4e8e\u6570\u7ec4\u5728\u8ba1\u7b97\u673a\u5185\u5b58\u91cc\u7684\u4e0d\u540c\u5b58\u50a8\u65b9\u5f0f\uff0c\u63cf\u8ff0\u6570\u7ec4\u76f8\u5173\u64cd\u4f5c\u7684\u6210\u672c\u548c\u6536\u76ca\uff1b \u4f7f\u7528\u5355\u5411\u94fe\u63a5\u8282\u70b9\u521b\u5efa\u94fe\u63a5\u7ed3\u6784\uff1b \u5bf9\u7531\u5355\u5411\u94fe\u63a5\u8282\u70b9\u6784\u6210\u7684\u94fe\u63a5\u7ed3\u6784\u6267\u884c\u5404\u79cd\u64cd\u4f5c\uff1b \u57fa\u4e8e\u94fe\u63a5\u7ed3\u6784\u5728\u8ba1\u7b97\u673a\u5185\u5b58\u91cc\u7684\u4e0d\u540c\u5b58\u50a8\u65b9\u5f0f\uff0c\u63cf\u8ff0\u5728\u94fe\u63a5\u7ed3\u6784\u4e0a\u6267\u884c\u76f8\u5173\u64cd\u4f5c\u7684\u6210\u672c\u548c\u6536\u76ca\uff1b \u6bd4\u8f83\u6570\u7ec4\u548c\u94fe\u63a5\u7ed3\u6784\u5728\u8fd0\u884c\u65f6\u548c\u5185\u5b58\u4f7f\u7528\u4e0a\u7684\u6743\u8861\uff1b","title":"4.\u6570\u7ec4\u548c\u94fe\u63a5\u7ed3\u6784"},{"location":"python/DataStructure/04_ArrayChain/#41","text":"\u5173\u4e8e\u6570\u7ec4\uff08array\uff09\uff1a \u6570\u7ec4\u662f\u6307\u5728\u7ed9\u5b9a\u7d22\u5f15\u4f4d\u7f6e\u53ef\u4ee5\u8bbf\u95ee\u548c\u66ff\u6362\u7684\u5143\u7d20\u5e8f\u5217\u3002 Python\u5217\u8868\u7684\u5e95\u5c42\u6570\u636e\u7ed3\u6784\u6b63\u662f\u4e00\u4e2a\u6570\u7ec4\u3002 Python\u4e2d\u6570\u7ec4\u7684\u9650\u5236\u8981\u6bd4\u5217\u8868\u66f4\u591a\u3002\u53ea\u80fd\u5728\u6307\u5b9a\u4f4d\u7f6e\u8bbf\u95ee\u548c\u66ff\u6362\u6570\u7ec4\u4e2d\u7684\u5143\u7d20\u3001\u68c0\u67e5\u6570\u7ec4\u7684\u957f\u5ea6\u3001\u83b7\u53d6\u5b83\u7684\u5b57\u7b26\u4e32\u8868\u8fbe\u5f0f\uff1b\u4e0d\u80fd\u57fa\u4e8e\u4f4d\u7f6e\u6dfb\u52a0\u6216\u5220\u9664\u5143\u7d20\uff1b\u6570\u7ec4\u7684\u957f\u5ea6\u4e5f\u5c31\u662f\u5b83\u7684\u5bb9\u91cf\uff0c\u5728\u521b\u5efa\u4e4b\u540e\u5c31\u662f\u56fa\u5b9a\u7684\u3002","title":"4.1.\u6570\u7ec4\u6570\u636e\u7ed3\u6784"},{"location":"python/DataStructure/04_ArrayChain/#411","text":"\u901a\u8fc7\u4e0b\u6807\u64cd\u4f5c\u6216\u7d22\u5f15\u64cd\u4f5c\u5b9e\u73b0\u5bf9\u6570\u7ec4\u5728\u6307\u5b9a\u4f4d\u7f6e\u5bf9\u5143\u7d20\u8fdb\u884c\u5b58\u50a8\u6216\u68c0\u7d22\u3002 \u6570\u7ec4\u7d22\u5f15\u662f\u968f\u673a\u8bbf\u95ee\uff08random access\uff09\u64cd\u4f5c\uff0c\u800c\u5728\u968f\u673a\u8bbf\u95ee\u65f6\uff0c\u8ba1\u7b97\u673a\u603b\u4f1a\u6267\u884c\u56fa\u5b9a\u7684\u6b65\u9aa4\u6765\u83b7\u53d6\u7b2c i \u4e2a\u5143\u7d20\u7684\u4f4d\u7f6e\u3002\u56e0\u6b64\uff0c\u4e0d\u8bba\u6570\u7ec4\u6709\u591a\u5927\uff0c\u8bbf\u95ee\u7b2c\u4e00\u4e2a\u5143\u7d20\u6240\u9700\u7684\u65f6\u95f4\u548c\u8bbf\u95ee\u6700\u540e\u4e00\u4e2a\u5143\u7d20\u6240\u9700\u8981\u7684\u65f6\u95f4\u90fd\u662f\u76f8\u540c\u7684\u3002 \u8ba1\u7b97\u673a\u901a\u8fc7\u5206\u914d\u4e00\u5757\u8fde\u7eed\u5185\u5b58\uff08contiguous memory\uff09\u5355\u5143\u6765\u5b58\u50a8\u6570\u7ec4\u91cc\u7684\u5143\u7d20\uff0c\u4ece\u800c\u652f\u6301\u5bf9\u6570\u7ec4\u7684\u968f\u673a\u8bbf\u95ee\u3002 \u7531\u4e8e\u6570\u7ec4\u91cc\u7684\u5143\u7d20\u5730\u5740\u90fd\u662f\u6309\u7167\u6570\u5b57\u987a\u5e8f\u8fdb\u884c\u6392\u5217\u7684\uff0c\u56e0\u6b64\u53ef\u4ee5\u901a\u8fc7\u6dfb\u52a0\u4e24\u4e2a\u503c\u6765\u8ba1\u7b97\u51fa\u6570\u7ec4\u5143\u7d20\u7684\u673a\u5668\u5730\u5740\uff0c\u5b83\u4eec\u662f\u6570\u7ec4\u7684\u57fa\u5730\u5740\uff08base address\uff09\u4ee5\u53ca\u5143\u7d20\u7684\u504f\u79fb\u91cf\uff08offset\uff09\u3002\u5176\u4e2d\uff0c\u6570\u7ec4\u7684\u57fa\u5730\u5740\u5c31\u662f\u7b2c\u4e00\u4e2a\u5143\u7d20\u7684\u673a\u5668\u5730\u5740\uff0c\u800c\u5143\u7d20\u7684\u504f\u79fb\u91cf\u5c31\u662f\u5b83\u7684\u7d22\u5f15\u503c\u518d\u4e58\u4ee5\u4e00\u4e2a\u4ee3\u8868\u6570\u7ec4\u5143\u7d20\u6240\u9700\u5185\u5b58\u5355\u5143\u6570\u7684\u5e38\u91cf\uff08\u5728Python\u91cc\uff0c\u8fd9\u4e2a\u503c\u59cb\u7ec8\u662f1\uff09\u3002 \u7b80\u800c\u8a00\u4e4b\uff0cPython\u6570\u7ec4\u91cc\u7684\u7d22\u5f15\u64cd\u4f5c\u5305\u62ec\u4e0b\u9762\u4e24\u4e2a\u6b65\u9aa4\uff1a \u5f97\u5230\u6570\u7ec4\u5185\u5b58\u5757\u7684\u57fa\u5730\u5740\u3002 \u5c06\u7d22\u5f15\u503c\u6dfb\u52a0\u5230\u8fd9\u4e2a\u5730\u5740\u5e76\u8fd4\u56de\u3002","title":"4.1.1.\u968f\u673a\u8bbf\u95ee\u548c\u8fde\u7eed\u5185\u5b58"},{"location":"python/DataStructure/04_ArrayChain/#412","text":"\u5728\u6bd4\u8f83\u8001\u7684\u7f16\u7a0b\u8bed\u8a00\uff08\u5982FORTRAN\u6216Pascal\uff09\u91cc\uff0c\u6570\u7ec4\u662f\u9759\u6001\u6570\u636e\u7ed3\u6784\u3002\u5728\u8fd9\u79cd\u60c5\u51b5\u4e0b\uff0c\u6570\u7ec4\u7684\u957f\u5ea6\u6216\u5bb9\u91cf\u5728\u7f16\u8bd1\u65f6\u5c31\u786e\u5b9a\u4e86\uff0c\u7a0b\u5e8f\u5458\u9700\u8981\u7533\u8bf7\u8db3\u591f\u591a\u7684\u5185\u5b58\u6765\u6ee1\u8db3\u5728\u6570\u7ec4\u91cc\u5b58\u50a8\u53ef\u80fd\u6709\u6700\u5927\u6570\u91cf\u5143\u7d20\u7684\u60c5\u51b5\uff0c\u8fd9\u6837\u505a\u4f1a\u6d6a\u8d39\u5927\u91cf\u7684\u5185\u5b58\u3002 \u50cfJava\u548cC++\u8fd9\u7c7b\u7684\u73b0\u4ee3\u7f16\u7a0b\u8bed\u8a00\u4f1a\u5141\u8bb8\u7a0b\u5e8f\u5458\u521b\u5efa\u52a8\u6001\u6570\u7ec4\uff08dynamic array\uff09\uff0c\u4ece\u800c\u4e3a\u8fd9\u4e2a\u95ee\u9898\u63d0\u4f9b\u4e86\u4e00\u79cd\u8865\u6551\u65b9\u6cd5\u3002\u548c\u9759\u6001\u6570\u7ec4\u76f8\u4f3c\u7684\u662f\uff0c\u52a8\u6001\u6570\u7ec4\u4e5f\u4f1a\u5360\u7528\u4e00\u5757\u8fde\u7eed\u5185\u5b58\uff0c\u5e76\u652f\u6301\u968f\u673a\u8bbf\u95ee\u3002\u52a8\u6001\u6570\u7ec4\u7684\u957f\u5ea6\u53ea\u5728\u8fd0\u884c\u65f6\u624d\u77e5\u9053\uff0c\u5728\u52a8\u6001\u6570\u7ec4\u5b9e\u4f8b\u5316\u7684\u65f6\u5019\u6307\u5b9a\u5b83\u7684\u957f\u5ea6\u3002\u5728Python\u91cc\u5b9e\u73b0\u7684Array\u7c7b\u7684\u884c\u4e3a\u4e5f\u662f\u8fd9\u6837\u7684\u3002 \u6211\u4eec\u53ef\u4ee5\u901a\u8fc7\u53e6\u4e00\u79cd\u65b9\u6cd5\u5728\u8fd0\u884c\u65f6\u6839\u636e\u5e94\u7528\u7a0b\u5e8f\u7684\u6570\u636e\u8981\u6c42\u6765\u8c03\u6574\u6570\u7ec4\u7684\u957f\u5ea6\uff0c\u8fd9\u4e9b\u8c03\u6574\u4f1a\u7531Python\u5217\u8868\u81ea\u52a8\u8fdb\u884c\u3002\u8fd9\u65f6\uff0c\u6570\u7ec4\u6709\u4ee5\u4e0b3\u79cd\u4e0d\u540c\u5f62\u5f0f\u3002 \u5728\u7a0b\u5e8f\u542f\u52a8\u65f6\u521b\u5efa\u4e00\u4e2a\u5177\u6709\u5408\u7406\u9ed8\u8ba4\u5927\u5c0f\u7684\u6570\u7ec4\u3002 \u5f53\u6570\u7ec4\u65e0\u6cd5\u5bb9\u7eb3\u66f4\u591a\u6570\u636e\u65f6\uff0c\u521b\u5efa\u4e00\u4e2a\u66f4\u5927\u7684\u65b0\u6570\u7ec4\uff0c\u5e76\u628a\u65e7\u6570\u7ec4\u91cc\u7684\u6570\u636e\u5143\u7d20\u4f20\u8f93\u7ed9\u5b83\u3002 \u5982\u679c\u6570\u7ec4\u5728\u6d6a\u8d39\u5185\u5b58\uff08\u5e94\u7528\u7a0b\u5e8f\u5220\u9664\u4e86\u4e00\u4e9b\u6570\u636e\uff09\uff0c\u90a3\u4e48\u7528\u7c7b\u4f3c\u7684\u65b9\u5f0f\u51cf\u5c0f\u6570\u7ec4\u7684\u957f\u5ea6\u3002","title":"4.1.2.\u9759\u6001\u5185\u5b58\u548c\u52a8\u6001\u5185\u5b58"},{"location":"python/DataStructure/04_ArrayChain/#413","text":"\u6570\u7ec4\u7684\u7269\u7406\u5c3a\u5bf8\uff08physical size\uff09\u662f\u6307\u6570\u7ec4\u5355\u5143\u7684\u603b\u6570\uff0c\u6216\u8005\u521b\u5efa\u6570\u7ec4\u65f6\u6307\u5b9a\u5176\u5bb9\u91cf\u7684\u90a3\u4e2a\u6570\u5b57\uff1b \u6570\u7ec4\u7684\u903b\u8f91\u5c3a\u5bf8\uff08logical size\uff09\u662f\u6307\u5f53\u524d\u5e94\u7528\u7a0b\u5e8f\u4f7f\u7528\u7684\u5143\u7d20\u6570\u91cf\u3002 \u5f53\u6570\u7ec4\u88ab\u586b\u6ee1\u7684\u65f6\u5019\uff0c\u6211\u4eec\u4e0d\u9700\u8981\u62c5\u5fc3\u5b83\u4eec\u7684\u4e0d\u540c\u3002\u5f53\u6570\u7ec4\u88ab\u90e8\u5206\u586b\u6ee1\u7684\u65f6\u5019\uff0c\u672a\u88ab\u586b\u5145\u7684\u5185\u5b58\u5355\u5143\u91cc\u7684\u6570\u636e\u5bf9\u5f53\u524d\u5e94\u7528\u7a0b\u5e8f\u662f\u6ca1\u6709\u7528\u7684\uff0c\u6211\u4eec\u79f0\u4e4b\u5783\u573e\u5185\u5bb9\uff08garbage\uff09\u3002\u5728\u5927\u591a\u6570\u5e94\u7528\u7a0b\u5e8f\u91cc\uff0c\u6211\u4eec\u662f\u8981\u6ce8\u610f\u5bf9\u6570\u7ec4\u7684\u7269\u7406\u5c3a\u5bf8\u548c\u903b\u8f91\u5c3a\u5bf8\u8fdb\u884c\u8ffd\u8e2a\u3002\u901a\u5e38\u6765\u8bf4\uff0c\u903b\u8f91\u5c3a\u5bf8\u548c\u7269\u7406\u5c3a\u5bf8\u4f1a\u53cd\u6620\u51fa\u6709\u5173\u6570\u7ec4\u72b6\u6001\u7684\u51e0\u4e2a\u91cd\u70b9\u3002 \u5982\u679c\u903b\u8f91\u5c3a\u5bf8\u4e3a0\uff0c\u90a3\u4e48\u6570\u7ec4\u5c31\u4e3a\u7a7a\u3002\u4e5f\u5c31\u662f\u8bf4\uff0c\u8fd9\u4e2a\u6570\u7ec4\u4e0d\u5305\u542b\u4efb\u4f55\u6570\u636e\u5143\u7d20\u3002 \u5982\u679c\u5e76\u975e\u4e0a\u8ff0\u60c5\u51b5\uff0c\u5728\u4efb\u4f55\u60c5\u51b5\u4e0b\uff0c\u6570\u7ec4\u4e2d\u6700\u540e\u4e00\u4e2a\u5143\u7d20\u7684\u7d22\u5f15\u90fd\u662f\u5b83\u7684\u903b\u8f91\u5c3a\u5bf8\u51cf1\u3002 \u5982\u679c\u903b\u8f91\u5c3a\u5bf8\u7b49\u4e8e\u7269\u7406\u5c3a\u5bf8\uff0c\u90a3\u4e48\u8868\u793a\u6570\u7ec4\u5df2\u88ab\u586b\u6ee1\u4e86\u3002","title":"4.1.3.\u7269\u7406\u5c3a\u5bf8\u548c\u903b\u8f91\u5c3a\u5bf8"},{"location":"python/DataStructure/04_ArrayChain/#414","text":"1\uff0e\u8bf7\u8bf4\u660e\u968f\u673a\u8bbf\u95ee\u7684\u5de5\u4f5c\u539f\u7406\uff0c\u4ee5\u53ca\u8fd9\u4e2a\u64cd\u4f5c\u8fd9\u4e48\u5feb\u7684\u539f\u56e0\u3002 \u89e3\u7b54\uff1a\u968f\u673a\u8bbf\u95ee\u662f\u4e00\u79cd\u8ba1\u7b97\u673a\u5b58\u50a8\u7cfb\u7edf\u4e2d\u7684\u8bfb\u53d6\u6216\u5199\u5165\u6570\u636e\u7684\u64cd\u4f5c\uff0c\u5176\u4e2d\u6570\u636e\u53ef\u4ee5\u901a\u8fc7\u76f4\u63a5\u8df3\u8f6c\u5230\u5176\u5b58\u50a8\u4f4d\u7f6e\u800c\u4e0d\u9700\u8981\u987a\u5e8f\u626b\u63cf\u6765\u8bbf\u95ee\u3002\u8fd9\u4e0e\u987a\u5e8f\u8bbf\u95ee\u4e0d\u540c\uff0c\u540e\u8005\u9700\u8981\u6309\u987a\u5e8f\u904d\u5386\u6570\u636e\u4ee5\u627e\u5230\u6240\u9700\u7684\u4fe1\u606f\u3002\u968f\u673a\u8bbf\u95ee\u7684\u5de5\u4f5c\u539f\u7406\u5982\u4e0b\uff1a \u5b58\u50a8\u4ecb\u8d28\uff1a\u8ba1\u7b97\u673a\u5185\u5b58\u548c\u786c\u76d8\u7b49\u5b58\u50a8\u8bbe\u5907\u90fd\u652f\u6301\u968f\u673a\u8bbf\u95ee\u3002\u8fd9\u4e9b\u5b58\u50a8\u4ecb\u8d28\u4e2d\u7684\u6570\u636e\u901a\u5e38\u88ab\u5212\u5206\u4e3a\u5757\u6216\u6247\u533a\uff0c\u5e76\u4e14\u6bcf\u4e2a\u5757\u6216\u6247\u533a\u90fd\u6709\u4e00\u4e2a\u552f\u4e00\u7684\u5730\u5740\u6216\u7d22\u5f15\u3002 \u8bbf\u95ee\u5730\u5740\uff1a\u4e3a\u4e86\u8fdb\u884c\u968f\u673a\u8bbf\u95ee\uff0c\u8ba1\u7b97\u673a\u9700\u8981\u77e5\u9053\u8981\u8bbf\u95ee\u7684\u6570\u636e\u7684\u5730\u5740\u3002\u8fd9\u4e2a\u5730\u5740\u53ef\u4ee5\u662f\u5185\u5b58\u4e2d\u7684\u7279\u5b9a\u4f4d\u7f6e\uff0c\u4e5f\u53ef\u4ee5\u662f\u786c\u76d8\u4e0a\u7684\u67d0\u4e2a\u6247\u533a\u7684\u5730\u5740\u3002 \u5bfb\u5740\u548c\u4f20\u8f93\uff1a\u8ba1\u7b97\u673a\u4f7f\u7528\u5b58\u50a8\u8bbe\u5907\u7684\u63a7\u5236\u5668\u6216\u5b58\u50a8\u5668\u7ba1\u7406\u5355\u5143\u6765\u67e5\u627e\u6570\u636e\u7684\u5730\u5740\u3002\u4e00\u65e6\u627e\u5230\u4e86\u6b63\u786e\u7684\u5730\u5740\uff0c\u5b58\u50a8\u8bbe\u5907\u4f1a\u5c06\u6570\u636e\u4f20\u8f93\u5230\u8ba1\u7b97\u673a\u7684\u5185\u5b58\u4e2d\u4f9b\u5904\u7406\u5668\u4f7f\u7528\u3002 \u8bbf\u95ee\u901f\u5ea6\uff1a\u968f\u673a\u8bbf\u95ee\u4e4b\u6240\u4ee5\u5982\u6b64\u5feb\u901f\uff0c\u662f\u56e0\u4e3a\u8ba1\u7b97\u673a\u5185\u5b58\u548c\u73b0\u4ee3\u786c\u76d8\u9a71\u52a8\u5668\u7b49\u5b58\u50a8\u8bbe\u5907\u90fd\u7ecf\u8fc7\u4e86\u4f18\u5316\uff0c\u53ef\u4ee5\u5feb\u901f\u54cd\u5e94\u8bbf\u95ee\u8bf7\u6c42\u3002\u8fd9\u4e9b\u8bbe\u5907\u4f7f\u7528\u4e86\u9ad8\u901f\u7f13\u5b58\u3001\u8bfb\u5199\u5934\u3001\u5bfb\u9053\u673a\u6784\u7b49\u6280\u672f\u6765\u6700\u5c0f\u5316\u6570\u636e\u8bbf\u95ee\u7684\u5ef6\u8fdf\u3002 \u539f\u56e0\uff1a \u5b58\u50a8\u8bbe\u5907\u7684\u7269\u7406\u7ed3\u6784\uff1a\u8ba1\u7b97\u673a\u5185\u5b58\u548c\u786c\u76d8\u7b49\u5b58\u50a8\u8bbe\u5907\u7684\u7269\u7406\u7ed3\u6784\u88ab\u8bbe\u8ba1\u6210\u53ef\u4ee5\u968f\u673a\u8bbf\u95ee\u7684\u3002\u5185\u5b58\u4e2d\u7684\u6bcf\u4e2a\u5730\u5740\u90fd\u53ef\u4ee5\u77ac\u95f4\u8bbf\u95ee\uff0c\u800c\u786c\u76d8\u4e0a\u7684\u6247\u533a\u4e5f\u53ef\u4ee5\u901a\u8fc7\u78c1\u5934\u5bfb\u9053\u548c\u65cb\u8f6c\u78c1\u76d8\u7b49\u673a\u5236\u8fc5\u901f\u8bbf\u95ee\u3002 \u9ad8\u901f\u7f13\u5b58\uff1a\u73b0\u4ee3\u8ba1\u7b97\u673a\u5185\u5b58\u548c\u5904\u7406\u5668\u90fd\u914d\u5907\u4e86\u9ad8\u901f\u7f13\u5b58\uff08\u4f8b\u5982\uff0cCPU\u7f13\u5b58\uff09\u3002\u8fd9\u4e9b\u9ad8\u901f\u7f13\u5b58\u5b58\u50a8\u4e86\u6700\u8fd1\u8bbf\u95ee\u7684\u6570\u636e\uff0c\u53ef\u4ee5\u5feb\u901f\u63d0\u4f9b\u7ed9\u5904\u7406\u5668\uff0c\u4ece\u800c\u964d\u4f4e\u4e86\u8bbf\u95ee\u5ef6\u8fdf\u3002 \u5b58\u50a8\u5668\u7ba1\u7406\uff1a\u64cd\u4f5c\u7cfb\u7edf\u548c\u5b58\u50a8\u8bbe\u5907\u7684\u63a7\u5236\u5668\u4f1a\u7ba1\u7406\u5b58\u50a8\u5668\u7684\u8bbf\u95ee\uff0c\u4ee5\u786e\u4fdd\u6570\u636e\u53ef\u4ee5\u9ad8\u6548\u5730\u88ab\u8bbf\u95ee\u548c\u4f20\u8f93\u3002\u8fd9\u5305\u62ec\u4e86\u78c1\u76d8\u8c03\u5ea6\u7b97\u6cd5\u3001\u5185\u5b58\u5206\u9875\u7b49\u7b56\u7565\u3002 \u6280\u672f\u8fdb\u6b65\uff1a\u786c\u4ef6\u5236\u9020\u6280\u672f\u7684\u8fdb\u6b65\u548c\u5b58\u50a8\u8bbe\u5907\u7684\u4f18\u5316\u4f7f\u5f97\u968f\u673a\u8bbf\u95ee\u901f\u5ea6\u66f4\u5feb\u3002\u4f8b\u5982\uff0c\u56fa\u6001\u786c\u76d8\uff08SSD\uff09\u7684\u51fa\u73b0\u663e\u8457\u63d0\u9ad8\u4e86\u6570\u636e\u7684\u968f\u673a\u8bbf\u95ee\u901f\u5ea6\u3002 \u603b\u4e4b\uff0c\u968f\u673a\u8bbf\u95ee\u4e4b\u6240\u4ee5\u5982\u6b64\u5feb\u901f\uff0c\u662f\u56e0\u4e3a\u8ba1\u7b97\u673a\u5185\u5b58\u548c\u5b58\u50a8\u8bbe\u5907\u7684\u7269\u7406\u548c\u6280\u672f\u7279\u6027\u4f7f\u5176\u80fd\u591f\u4ee5\u9ad8\u6548\u3001\u8fc5\u901f\u7684\u65b9\u5f0f\u8bbf\u95ee\u6570\u636e\u3002\u8fd9\u79cd\u8bbf\u95ee\u901f\u5ea6\u5bf9\u4e8e\u8ba1\u7b97\u673a\u7684\u6027\u80fd\u548c\u54cd\u5e94\u65f6\u95f4\u81f3\u5173\u91cd\u8981\u3002 2\uff0e\u6570\u7ec4\u548cPython\u5217\u8868\u4e4b\u95f4\u6709\u4ec0\u4e48\u533a\u522b\uff1f \u89e3\u7b54\uff1a\u6570\u7ec4\u548cPython\u5217\u8868\u4e4b\u95f4\u6709\u51e0\u4e2a\u5173\u952e\u533a\u522b\uff0c\u8fd9\u4e9b\u533a\u522b\u5728\u6570\u636e\u7ed3\u6784\u3001\u529f\u80fd\u548c\u7528\u9014\u4e0a\u5b58\u5728\u5dee\u5f02\uff1a \u6570\u636e\u7c7b\u578b\uff1a \u6570\u7ec4\uff1a\u901a\u5e38\u8981\u6c42\u6240\u6709\u5143\u7d20\u5177\u6709\u76f8\u540c\u7684\u6570\u636e\u7c7b\u578b\u3002\u8fd9\u662f\u56e0\u4e3a\u6570\u7ec4\u5728\u5185\u5b58\u4e2d\u4ee5\u7d27\u51d1\u7684\u65b9\u5f0f\u5b58\u50a8\u6570\u636e\uff0c\u9700\u8981\u77e5\u9053\u6bcf\u4e2a\u5143\u7d20\u7684\u5927\u5c0f\u4ee5\u4fbf\u8fdb\u884c\u968f\u673a\u8bbf\u95ee\u3002 Python\u5217\u8868\uff1aPython\u7684\u5217\u8868\u53ef\u4ee5\u5bb9\u7eb3\u4e0d\u540c\u6570\u636e\u7c7b\u578b\u7684\u5143\u7d20\uff0c\u56e0\u4e3a\u5b83\u4eec\u662f\u52a8\u6001\u7c7b\u578b\u7684\u3002 \u5185\u5b58\u7ba1\u7406\uff1a \u6570\u7ec4\uff1a\u901a\u5e38\u5728\u521b\u5efa\u65f6\u9700\u8981\u6307\u5b9a\u56fa\u5b9a\u5927\u5c0f\uff0c\u56e0\u6b64\u5728\u5185\u5b58\u4e2d\u4f1a\u5206\u914d\u4e00\u5757\u8fde\u7eed\u7684\u7a7a\u95f4\uff0c\u8fd9\u4f7f\u5f97\u6570\u7ec4\u5bf9\u4e8e\u9ad8\u6548\u7684\u968f\u673a\u8bbf\u95ee\u975e\u5e38\u9002\u7528\u3002 Python\u5217\u8868\uff1aPython\u7684\u5217\u8868\u662f\u52a8\u6001\u7684\uff0c\u5b83\u4eec\u53ef\u4ee5\u6839\u636e\u9700\u8981\u81ea\u52a8\u6269\u5c55\u6216\u7f29\u5c0f\u3002\u8fd9\u5bfc\u81f4\u4e86\u4e00\u4e9b\u989d\u5916\u7684\u5185\u5b58\u5f00\u9500\uff0c\u56e0\u4e3a\u5217\u8868\u9700\u8981\u66f4\u591a\u7684\u7a7a\u95f4\u6765\u7ba1\u7406\u5143\u7d20\u7684\u6dfb\u52a0\u548c\u5220\u9664\u3002 \u6027\u80fd\uff1a \u6570\u7ec4\uff1a\u7531\u4e8e\u5185\u5b58\u5e03\u5c40\u8fde\u7eed\uff0c\u56e0\u6b64\u6570\u7ec4\u901a\u5e38\u5728\u8bbf\u95ee\u5143\u7d20\u65f6\u66f4\u5feb\u3002\u6570\u7ec4\u8fd8\u652f\u6301\u66f4\u591a\u7684\u5e95\u5c42\u64cd\u4f5c\uff0c\u5982\u4f4d\u64cd\u4f5c\u3002 Python\u5217\u8868\uff1aPython\u5217\u8868\u66f4\u52a0\u7075\u6d3b\uff0c\u4f46\u5728\u67d0\u4e9b\u60c5\u51b5\u4e0b\u53ef\u80fd\u4f1a\u5bfc\u81f4\u6027\u80fd\u4e0b\u964d\uff0c\u7279\u522b\u662f\u5f53\u6d89\u53ca\u5927\u91cf\u5143\u7d20\u7684\u63d2\u5165\u548c\u5220\u9664\u64cd\u4f5c\u65f6\u3002 \u64cd\u4f5c\u548c\u65b9\u6cd5\uff1a \u6570\u7ec4\uff1a\u901a\u5e38\u63d0\u4f9b\u4e00\u7ec4\u57fa\u672c\u64cd\u4f5c\uff0c\u5982\u8bfb\u53d6\u548c\u5199\u5165\u5143\u7d20\uff0c\u4ee5\u53ca\u4e00\u4e9b\u6570\u5b66\u8fd0\u7b97\uff0c\u5982\u5411\u91cf\u5316\u64cd\u4f5c\u3002 Python\u5217\u8868\uff1aPython\u5217\u8868\u63d0\u4f9b\u4e86\u66f4\u4e30\u5bcc\u7684\u65b9\u6cd5\u548c\u64cd\u4f5c\uff0c\u5305\u62ec\u5143\u7d20\u7684\u63d2\u5165\u3001\u5220\u9664\u3001\u8ffd\u52a0\u3001\u5207\u7247\u3001\u8fde\u63a5\u7b49\u3002 \u8bed\u8a00\u4f9d\u8d56\u6027\uff1a \u6570\u7ec4\uff1a\u6570\u7ec4\u901a\u5e38\u662f\u7f16\u7a0b\u8bed\u8a00\u7684\u4e00\u90e8\u5206\uff0c\u5177\u6709\u56fa\u5b9a\u7684\u8bed\u6cd5\u548c\u8bed\u4e49\u3002 Python\u5217\u8868\uff1aPython\u7684\u5217\u8868\u662fPython\u6807\u51c6\u5e93\u7684\u4e00\u90e8\u5206\uff0c\u4e0ePython\u7684\u52a8\u6001\u7279\u6027\u76f8\u9002\u5e94\u3002 \u9002\u7528\u573a\u666f\uff1a \u6570\u7ec4\uff1a\u9002\u7528\u4e8e\u9700\u8981\u9ad8\u6548\u968f\u673a\u8bbf\u95ee\u7684\u60c5\u51b5\uff0c\u5982\u6570\u503c\u8ba1\u7b97\u3001\u56fe\u50cf\u5904\u7406\u7b49\u3002 Python\u5217\u8868\uff1a\u9002\u7528\u4e8e\u66f4\u5e7f\u6cdb\u7684\u5e94\u7528\uff0c\u7279\u522b\u662f\u5728\u7f16\u5199Python\u4ee3\u7801\u65f6\uff0c\u56e0\u4e3a\u5b83\u4eec\u66f4\u7075\u6d3b\u4e14\u6613\u4e8e\u4f7f\u7528\u3002 \u603b\u4e4b\uff0c\u6570\u7ec4\u548cPython\u5217\u8868\u90fd\u6709\u81ea\u5df1\u7684\u4f18\u52bf\u548c\u9002\u7528\u573a\u666f\u3002\u9009\u62e9\u4f7f\u7528\u54ea\u79cd\u6570\u636e\u7ed3\u6784\u53d6\u51b3\u4e8e\u5177\u4f53\u7684\u9700\u6c42\u548c\u7f16\u7a0b\u8bed\u8a00\u3002\u5728Python\u4e2d\uff0c\u901a\u5e38\u4f1a\u4f18\u5148\u9009\u62e9\u4f7f\u7528\u5217\u8868\uff0c\u56e0\u4e3a\u5b83\u4eec\u66f4\u65b9\u4fbf\uff0c\u800c\u5728\u5176\u4ed6\u7f16\u7a0b\u8bed\u8a00\u4e2d\uff0c\u5982C\u6216Java\uff0c\u6570\u7ec4\u53ef\u80fd\u66f4\u4e3a\u5e38\u89c1\u3002 \u5728\u8fd9\u91cc\u9700\u8981\u8bf4\u660e\u4e00\u4e2a\u6982\u5ff5\u3002\u5728Python\u4e2d\uff0c\u672f\u8bed\"\u6570\u7ec4\"\u901a\u5e38\u6307\u7684\u662fNumPy\u5e93\u4e2d\u7684\u6570\u7ec4\u5bf9\u8c61\uff0c\u800c\"\u5217\u8868\"\u6307\u7684\u662fPython\u7684\u5185\u7f6e\u5217\u8868\uff08list\uff09\u6570\u636e\u7ed3\u6784\u3002\u8fd9\u4e24\u8005\u4e4b\u95f4\u6709\u4ee5\u4e0b\u533a\u522b\uff1a \u6570\u636e\u7c7b\u578b\uff1a \u6570\u7ec4\uff08NumPy\u6570\u7ec4\uff09\uff1aNumPy\u5e93\u63d0\u4f9b\u4e86\u4e00\u4e2a\u591a\u7ef4\u6570\u7ec4\u5bf9\u8c61\uff0c\u5b83\u53ef\u4ee5\u5305\u542b\u76f8\u540c\u6570\u636e\u7c7b\u578b\u7684\u5143\u7d20\uff0c\u5e76\u652f\u6301\u9ad8\u7ea7\u6570\u5b66\u3001\u79d1\u5b66\u548c\u5de5\u7a0b\u8ba1\u7b97\u3002NumPy\u6570\u7ec4\u7684\u5143\u7d20\u7c7b\u578b\u901a\u5e38\u662f\u56fa\u5b9a\u7684\uff0c\u4f8b\u5982\uff0c\u53ef\u4ee5\u662f\u6574\u6570\u3001\u6d6e\u70b9\u6570\u3001\u590d\u6570\u7b49\u3002\u8fd9\u4e9b\u6570\u7ec4\u662f\u9ad8\u6027\u80fd\u7684\uff0c\u652f\u6301\u5411\u91cf\u5316\u64cd\u4f5c\u3002 \u5217\u8868\uff08Python\u5217\u8868\uff09\uff1aPython\u7684\u5185\u7f6e\u5217\u8868\u662f\u4e00\u79cd\u901a\u7528\u7684\u3001\u52a8\u6001\u7c7b\u578b\u7684\u6570\u636e\u7ed3\u6784\uff0c\u53ef\u4ee5\u5305\u542b\u4e0d\u540c\u6570\u636e\u7c7b\u578b\u7684\u5143\u7d20\uff0c\u4f8b\u5982\u6574\u6570\u3001\u6d6e\u70b9\u6570\u3001\u5b57\u7b26\u4e32\u3001\u5bf9\u8c61\u7b49\u3002\u5217\u8868\u53ef\u4ee5\u52a8\u6001\u6269\u5c55\u548c\u7f29\u5c0f\uff0c\u5e76\u63d0\u4f9b\u4e86\u4e30\u5bcc\u7684\u5185\u7f6e\u65b9\u6cd5\u548c\u64cd\u4f5c\u3002 \u6027\u80fd\uff1a \u6570\u7ec4\uff08NumPy\u6570\u7ec4\uff09\uff1aNumPy\u6570\u7ec4\u901a\u5e38\u6bd4Python\u5217\u8868\u66f4\u9ad8\u6548\uff0c\u7279\u522b\u662f\u5728\u8fdb\u884c\u6570\u503c\u8ba1\u7b97\u548c\u79d1\u5b66\u8ba1\u7b97\u65f6\u3002\u5b83\u4eec\u5185\u90e8\u4f7f\u7528\u4e86C\u8bed\u8a00\u5b9e\u73b0\uff0c\u652f\u6301\u5411\u91cf\u5316\u64cd\u4f5c\uff0c\u56e0\u6b64\u5728\u5927\u89c4\u6a21\u6570\u636e\u5904\u7406\u4e2d\u901a\u5e38\u66f4\u5feb\u3002 \u5217\u8868\uff08Python\u5217\u8868\uff09\uff1aPython\u5217\u8868\u867d\u7136\u7075\u6d3b\uff0c\u4f46\u6027\u80fd\u76f8\u5bf9\u8f83\u4f4e\uff0c\u4e0d\u9002\u5408\u5927\u89c4\u6a21\u7684\u6570\u503c\u8ba1\u7b97\u3002\u5b83\u4eec\u7684\u5143\u7d20\u7c7b\u578b\u53ef\u4ee5\u4e0d\u540c\uff0c\u8fd9\u610f\u5473\u7740\u9700\u8981\u66f4\u591a\u7684\u5185\u5b58\u548c\u5904\u7406\u65f6\u95f4\u6765\u7ba1\u7406\u5143\u7d20\u3002 \u5e93\u4f9d\u8d56\uff1a \u6570\u7ec4\uff08NumPy\u6570\u7ec4\uff09\uff1a\u4f7f\u7528NumPy\u5e93\u9700\u8981\u5b89\u88c5NumPy\u6a21\u5757\u3002NumPy\u662fPython\u4e2d\u7528\u4e8e\u6570\u503c\u8ba1\u7b97\u7684\u6838\u5fc3\u5e93\uff0c\u5e7f\u6cdb\u5e94\u7528\u4e8e\u79d1\u5b66\u8ba1\u7b97\u3001\u673a\u5668\u5b66\u4e60\u7b49\u9886\u57df\u3002 \u5217\u8868\uff08Python\u5217\u8868\uff09\uff1aPython\u7684\u5185\u7f6e\u5217\u8868\u662fPython\u6807\u51c6\u5e93\u7684\u4e00\u90e8\u5206\uff0c\u65e0\u9700\u989d\u5916\u5b89\u88c5\u3002 \u529f\u80fd\uff1a \u6570\u7ec4\uff08NumPy\u6570\u7ec4\uff09\uff1aNumPy\u6570\u7ec4\u63d0\u4f9b\u4e86\u8bb8\u591a\u6570\u5b66\u548c\u79d1\u5b66\u8ba1\u7b97\u51fd\u6570\uff0c\u5982\u7ebf\u6027\u4ee3\u6570\u3001\u5085\u7acb\u53f6\u53d8\u6362\u3001\u7edf\u8ba1\u5206\u6790\u7b49\u3002\u5b83\u4eec\u9002\u7528\u4e8e\u5904\u7406\u5927\u91cf\u6570\u503c\u6570\u636e\u3002 \u5217\u8868\uff08Python\u5217\u8868\uff09\uff1aPython\u5217\u8868\u63d0\u4f9b\u4e86\u901a\u7528\u7684\u6570\u636e\u5bb9\u5668\uff0c\u7528\u4e8e\u5b58\u50a8\u548c\u7ba1\u7406\u5404\u79cd\u7c7b\u578b\u7684\u6570\u636e\uff0c\u4f46\u4e0d\u63d0\u4f9b\u4e13\u95e8\u7684\u6570\u5b66\u548c\u79d1\u5b66\u8ba1\u7b97\u529f\u80fd\u3002 \u5982\u679c\u9700\u8981\u8fdb\u884c\u6570\u503c\u8ba1\u7b97\u3001\u79d1\u5b66\u8ba1\u7b97\u6216\u6570\u636e\u5206\u6790\uff0c\u901a\u5e38\u4f1a\u4f7f\u7528NumPy\u6570\u7ec4\u3002\u5982\u679c\u53ea\u662f\u9700\u8981\u4e00\u4e2a\u901a\u7528\u7684\u6570\u636e\u5bb9\u5668\uff0c\u7528\u4e8e\u5b58\u50a8\u548c\u7ba1\u7406\u6570\u636e\uff0c\u90a3\u4e48Python\u5217\u8868\u901a\u5e38\u8db3\u591f\u4e86\u3002 3\uff0e\u8bf7\u8bf4\u660e\u6570\u7ec4\u7684\u7269\u7406\u5c3a\u5bf8\u548c\u903b\u8f91\u5c3a\u5bf8\u4e4b\u95f4\u7684\u533a\u522b\u3002 \u89e3\u7b54\uff1a\"\u7269\u7406\u5c3a\u5bf8\"\u548c\"\u903b\u8f91\u5c3a\u5bf8\"\u901a\u5e38\u7528\u4e8e\u63cf\u8ff0\u6570\u636e\u7ed3\u6784\u4e2d\u7684\u4e24\u4e2a\u4e0d\u540c\u65b9\u9762\uff1a \u7269\u7406\u5c3a\u5bf8\uff08Physical Size\uff09\uff1a \u7269\u7406\u5c3a\u5bf8\u662f\u6307\u6570\u636e\u7ed3\u6784\u5b9e\u9645\u5360\u7528\u7684\u5185\u5b58\u7a7a\u95f4\u6216\u5b58\u50a8\u4ecb\u8d28\u4e2d\u7684\u7a7a\u95f4\u5927\u5c0f\u3002 \u5b83\u8868\u793a\u6570\u636e\u7ed3\u6784\u5728\u8ba1\u7b97\u673a\u5185\u5b58\u6216\u78c1\u76d8\u4e2d\u6240\u5360\u636e\u7684\u5b9e\u9645\u5b57\u8282\u6570\u3002 \u7269\u7406\u5c3a\u5bf8\u4e0e\u6570\u636e\u7ed3\u6784\u7684\u5b58\u50a8\u65b9\u5f0f\u3001\u6570\u636e\u7c7b\u578b\u4ee5\u53ca\u8ba1\u7b97\u673a\u67b6\u6784\u6709\u5173\u3002 \u903b\u8f91\u5c3a\u5bf8\uff08Logical Size\uff09\uff1a \u903b\u8f91\u5c3a\u5bf8\u662f\u6307\u6570\u636e\u7ed3\u6784\u4e2d\u5305\u542b\u7684\u5143\u7d20\u6570\u91cf\u6216\u6570\u636e\u9879\u7684\u6570\u91cf\u3002 \u5b83\u8868\u793a\u6570\u636e\u7ed3\u6784\u5185\u90e8\u7684\u5143\u7d20\u6570\u91cf\u6216\u6570\u636e\u9879\u7684\u4e2a\u6570\uff0c\u4e0d\u6d89\u53ca\u5b9e\u9645\u7684\u5b58\u50a8\u5927\u5c0f\u3002 \u903b\u8f91\u5c3a\u5bf8\u901a\u5e38\u7528\u4e8e\u63cf\u8ff0\u6570\u636e\u7ed3\u6784\u7684\u5bb9\u91cf\u3001\u89c4\u6a21\u6216\u7ef4\u5ea6\u3002 \u8fd9\u4e24\u4e2a\u6982\u5ff5\u4e4b\u95f4\u7684\u5173\u7cfb\u5982\u4e0b\uff1a \u4e00\u4e2a\u6570\u636e\u7ed3\u6784\u53ef\u4ee5\u5177\u6709\u56fa\u5b9a\u7684\u7269\u7406\u5c3a\u5bf8\uff08\u5360\u636e\u56fa\u5b9a\u6570\u91cf\u7684\u5b57\u8282\uff09\uff0c\u4f46\u5176\u903b\u8f91\u5c3a\u5bf8\u53ef\u4ee5\u6839\u636e\u5b9e\u9645\u5b58\u50a8\u7684\u5143\u7d20\u6570\u91cf\u800c\u53d8\u5316\u3002 \u7269\u7406\u5c3a\u5bf8\u901a\u5e38\u662f\u7531\u8ba1\u7b97\u673a\u786c\u4ef6\u548c\u64cd\u4f5c\u7cfb\u7edf\u7ba1\u7406\u7684\uff0c\u800c\u903b\u8f91\u5c3a\u5bf8\u5219\u662f\u7a0b\u5e8f\u5458\u6839\u636e\u6570\u636e\u7ed3\u6784\u7684\u8bbe\u8ba1\u6765\u7ba1\u7406\u7684\u3002 \u4e3e\u4f8b\u6765\u8bf4\uff0c\u4e00\u4e2a\u6574\u6570\u6570\u7ec4\u53ef\u4ee5\u5177\u6709\u56fa\u5b9a\u7684\u7269\u7406\u5c3a\u5bf8\uff0c\u4f8b\u59824\u5b57\u8282/\u6574\u6570\uff0c\u4f46\u5b83\u7684\u903b\u8f91\u5c3a\u5bf8\u53ef\u4ee5\u662f\u6570\u7ec4\u4e2d\u6574\u6570\u7684\u6570\u91cf\uff0c\u53ef\u4ee5\u662f0\u4e2a\u300110\u4e2a\u3001100\u4e2a\u7b49\u7b49\u3002\u56e0\u6b64\uff0c\u903b\u8f91\u5c3a\u5bf8\u63cf\u8ff0\u4e86\u6570\u7ec4\u53ef\u4ee5\u5bb9\u7eb3\u7684\u5143\u7d20\u6570\u91cf\uff0c\u800c\u7269\u7406\u5c3a\u5bf8\u63cf\u8ff0\u4e86\u5b9e\u9645\u5360\u7528\u7684\u5185\u5b58\u7a7a\u95f4\u3002 \u5728\u6570\u636e\u7ed3\u6784\u7684\u8bbe\u8ba1\u548c\u4f7f\u7528\u4e2d\uff0c\u4e86\u89e3\u548c\u7ba1\u7406\u7269\u7406\u5c3a\u5bf8\u548c\u903b\u8f91\u5c3a\u5bf8\u5bf9\u4e8e\u6709\u6548\u5730\u5229\u7528\u8ba1\u7b97\u673a\u8d44\u6e90\u975e\u5e38\u91cd\u8981\u3002","title":"4.1.4.\u7ec3\u4e60\u9898"},{"location":"python/DataStructure/04_ArrayChain/#42","text":"Python\u7684 array \u6a21\u5757\u5305\u542b\u4e00\u4e2a\u53eb\u4f5c array \u7684\u7c7b\uff0c\u5b83\u975e\u5e38\u7c7b\u4f3c\u4e8e\u5217\u8868\uff0c\u4f46\u662f\u53ea\u80fd\u5b58\u50a8\u6570\u5b57\u3002\u6211\u4eec\u4f1a\u5b9a\u4e49\u4e00\u4e2a\u53eb\u4f5c Array \u7684\u65b0\u7c7b\uff0c\u4f7f\u7528\u5217\u8868\u4fdd\u5b58\u5143\u7d20\uff0c\u5b58\u50a8\u4efb\u4f55\u7c7b\u578b\u7684\u5143\u7d20\u3002 \u4e0b\u9762\u7684\u793a\u4f8b\u5b9a\u4e49\u4e86\u4e00\u4e2a\u6570\u7ec4\u7c7b Array \uff0c\u4e0b\u9762\u5bf9\u6570\u7ec4\u7684\u4e00\u4e9b\u64cd\u4f5c\u7684\u4ee3\u7801\u5b9e\u73b0\u4e5f\u5df2\u7ecf\u5305\u542b\u5728\u4e0b\u9762\u7684\u4ee3\u7801\u4e2d\u3002\u5176\u4e2d\uff1a \u6570\u7ec4\u9ed8\u8ba4\u7684\u7269\u7406\u5c3a\u5bf8\uff08\u4e5f\u5c31\u662f\u5bb9\u91cf\uff09\u662f5 \u6570\u7ec4\u7684\u521d\u59cb\u903b\u8f91\u5c3a\u5bf8\u662f0 class Array ( object ): \"\"\"\u63cf\u8ff0\u4e00\u4e2a\u6570\u7ec4\u3002\"\"\" def __init__ ( self , capacity , fillValue = None ): \"\"\"Capacity\u662f\u6570\u7ec4\u7684\u5927\u5c0f. fillValue\u4f1a\u586b\u5145\u5728\u6bcf\u4e2a\u5143\u7d20\u4f4d\u7f6e, \u9ed8\u8ba4\u503c\u662fNone\"\"\" # \u521d\u59cb\u5316\u6570\u7ec4\u7684\u903b\u8f91\u5c3a\u5bf8\u548c\u7269\u7406\u5c3a\u5bf8 self . logicalSize = 0 self . capacity = capacity self . fillValue = fillValue #\u521d\u59cb\u5316\u5185\u90e8\u6570\u7ec4\uff0c\u5e76\u586b\u5145\u5143\u7d20\u503c self . items = list () for count in range ( capacity ): self . items . append ( fillValue ) self . logicalSize += 1 # \u521d\u59cb\u5316\u6570\u7ec4\u7269\u7406\u5927\u5c0f\u65f6\uff0c\u4e5f\u540c\u65f6\u521d\u59cb\u5316\u5176\u903b\u8f91\u5927\u5c0f def __len__ ( self ): \"\"\"\u8fd4\u56de\u6570\u7ec4\u7684\u5927\u5c0f\"\"\" return len ( self . items ) def __str__ ( self ): \"\"\"\u5c06\u6570\u7ec4\u5b57\u7b26\u4e32\u5316\u5e76\u8fd4\u56de\"\"\" result = \"\" for index in range ( self . size ()): result += str ( self . items [ index ]) + \" \" return result def size ( self ): \"\"\"\u8fd4\u56de\u6570\u7ec4\u7684\u903b\u8f91\u5c3a\u5bf8\"\"\" return self . logicalSize def __iter__ ( self ): \"\"\"\u652f\u6301for\u5faa\u73af\u5bf9\u6570\u7ec4\u8fdb\u884c\u904d\u5386.\"\"\" print ( \"__iter__ called\" ) # \u4ec5\u7528\u6765\u6d4b\u8bd5\u4f55\u65f6__iter__\u4f1a\u88ab\u8c03\u7528 return iter ( self . items ) def __getitem__ ( self , index ): \"\"\" \u7528\u4e8e\u8bbf\u95ee\u7d22\u5f15\u5904\u7684\u4e0b\u6807\u8fd0\u7b97\u7b26. \u5148\u51b3\u6761\u4ef6: 0 <= index < size() \"\"\" if index < 0 or index >= self . size (): raise IndexError ( \"\u8bfb\u53d6\u64cd\u4f5c\u51fa\u9519, \u6570\u7ec4\u7d22\u5f15\u8d8a\u754c(\u4e0d\u5728\u6570\u7ec4\u903b\u8f91\u8fb9\u754c\u8303\u56f4\u5185)\" ) return self . items [ index ] def __setitem__ ( self , index , newItem ): \"\"\" \u4e0b\u6807\u8fd0\u7b97\u7b26\u7528\u4e8e\u5728\u7d22\u5f15\u5904\u8fdb\u884c\u66ff\u6362. \u5148\u51b3\u6761\u4ef6: 0 <= index < size() \"\"\" if index < 0 or index >= self . size (): raise IndexError ( \"\u66f4\u65b0\u64cd\u4f5c\u51fa\u9519, \u6570\u7ec4\u7d22\u5f15\u8d8a\u754c(\u4e0d\u5728\u6570\u7ec4\u903b\u8f91\u8fb9\u754c\u8303\u56f4\u5185)\" ) self . items [ index ] = newItem def __eq__ ( self , other ): \"\"\" \u4e24\u4e2a\u6570\u7ec4\u76f8\u7b49\u5219\u8fd4\u56deTrue\uff0c\u5426\u5219\u8fd4\u56deFalse \"\"\" # \u5224\u65ad\u4e24\u4e2a\u6570\u7ec4\u662f\u5426\u662f\u540c\u4e00\u4e2a\u5bf9\u8c61\uff0c\u6ce8\u610f\uff0c\u4e0d\u662f\u5b83\u4eec\u7684\u503c\u662f\u5426\u76f8\u7b49 if self is other : return True # \u5224\u65ad\u4e24\u4e2a\u5bf9\u8c61\u7c7b\u578b\u662f\u5426\u4e00\u6837 if type ( self ) != type ( other ): return False # \u5224\u65ad\u4e24\u4e2a\u6570\u7ec4\u5927\u5c0f\u662f\u5426\u4e00\u6837 if self . size () != other . size (): return False # \u6bd4\u8f83\u4e24\u4e2a\u6570\u7ec4\u7684\u503c\u662f\u5426\u4e00\u6837 for index in range ( self . size ()): if self [ index ] != other [ index ]: return False return True def grow ( self ): \"\"\"\u589e\u5927\u6570\u7ec4\u7269\u7406\u5c3a\u5bf8\"\"\" # \u57fa\u4e8e\u5f53\u524d\u7269\u7406\u5c3a\u5bf8\u52a0\u500d\uff0c\u5e76\u5c06fillValue\u8d4b\u503c\u5e95\u5c42\u5217\u8868\u7684\u65b0\u5143\u7d20 for count in range ( len ( self )): self . items . append ( self . fillValue ) def insert ( self , index , newItem ): \"\"\"\u5728\u6570\u7ec4\u6307\u5b9a\u7d22\u5f15\u5904\u63d2\u5165\u65b0\u5143\u7d20\"\"\" # \u5f53\u6570\u7ec4\u7684\u7269\u7406\u5c3a\u5bf8\u548c\u903b\u8f91\u5c3a\u5bf8\u4e00\u6837\u65f6\uff0c\u5219\u589e\u52a0\u7269\u7406\u5c3a\u5bf8 if self . size () == len ( self ): self . grow () # \u63d2\u5165\u65b0\u5143\u7d20 # \u5f53\u63d2\u5165\u4f4d\u7f6e\u5927\u4e8e\u6216\u7b49\u4e8e\u6700\u5927\u903b\u8f91\u4f4d\u7f6e\uff0c\u5219\u5728\u6570\u7ec4\u672b\u7aef\u63d2\u5165\u65b0\u5143\u7d20 # \u5f53\u63d2\u5165\u4f4d\u7f6e\u4ecb\u4e8e\u6570\u7ec4\u903b\u8f91\u4f4d\u7f6e\u7684\u4e2d\u95f4\uff0c\u5219\u4ece\u63d2\u5165\u4f4d\u7f6e\u8d77\u5c06\u5269\u4f59\u6570\u7ec4\u5143\u7d20\u5411\u5c3e\u90e8\u5e73\u79fb\u4e00\u4e2a\u4f4d\u7f6e if index >= self . size (): self . items [ self . size ()] = newItem else : index = max ( index , 0 ) # \u5c06\u6570\u7ec4\u5143\u7d20\u5411\u5c3e\u90e8\u5e73\u79fb\u4e00\u4e2a\u4f4d\u7f6e for i in range ( self . size (), index , - 1 ): self . items [ i ] = self . items [ i - 1 ] # \u63d2\u5165\u65b0\u5143\u7d20 self . items [ index ] = newItem # \u589e\u52a0\u6570\u7ec4\u7684\u903b\u8f91\u5c3a\u5bf8 self . logicalSize += 1 def shrink ( self ): \"\"\" \u51cf\u5c11\u6570\u7ec4\u7684\u7269\u7406\u5c3a\u5bf8 \u5f53: - \u6570\u7ec4\u7684\u903b\u8f91\u5c3a\u5bf8\u5c0f\u4e8e\u6216\u7b49\u4e8e\u5176\u7269\u7406\u5c3a\u5bf8\u76841/4 - \u5e76\u4e14\u5b83\u7684\u7269\u7406\u5c3a\u5bf8\u81f3\u5c11\u662f\u8fd9\u4e2a\u6570\u7ec4\u5efa\u7acb\u65f6\u9ed8\u8ba4\u5bb9\u91cf\u76842\u500d\u65f6 \u5219\u628a\u6570\u7ec4\u7684\u7269\u7406\u5c3a\u5bf8\u51cf\u5c0f\u5230\u539f\u6765\u7684\u4e00\u534a\uff0c\u5e76\u4e14\u4e5f\u4e0d\u4f1a\u5c0f\u4e8e\u5176\u9ed8\u8ba4\u5bb9\u91cf \"\"\" # \u5728\u903b\u8f91\u5c3a\u5bf8\u548c\u7269\u7406\u5c3a\u5bf8\u7684\u4e00\u534a\u4e4b\u95f4\u9009\u62e9\u6700\u5927\u503c\u4f5c\u4e3a\u6570\u7ec4\u6536\u7f29\u540e\u7684\u7269\u7406\u5c3a\u5bf8 newSize = max ( self . capacity , len ( self ) // 2 ) # \u91ca\u653e\u591a\u4f59\u7684\u6570\u7ec4\u7a7a\u95f4 for count in range ( len ( self ) - newSize ): self . items . pop () def pop ( self , index ): \"\"\" \u5220\u9664\u6307\u5b9a\u7d22\u5f15\u503c\u7684\u6570\u7ec4\u5143\u7d20,\u5e76\u8fd4\u56de\u5220\u9664\u7684\u6570\u7ec4\u5143\u7d20\u503c \u5148\u51b3\u6761\u4ef6: 0 <= index < size() \"\"\" if index < 0 or index >= self . size (): raise IndexError ( \"\u5220\u9664\u64cd\u4f5c\u51fa\u9519, \u6570\u7ec4\u7d22\u5f15\u8d8a\u754c(\u4e0d\u5728\u6570\u7ec4\u903b\u8f91\u8fb9\u754c\u8303\u56f4\u5185)\" ) # \u4fdd\u5b58\u5373\u5c06\u88ab\u5220\u9664\u7684\u6570\u7ec4\u5143\u7d20\u503c itemToReturn = self . items [ index ] # \u5c06\u6570\u7ec4\u5143\u7d20\u5411\u5934\u90e8\u5e73\u79fb\u4e00\u4e2a\u4f4d\u7f6e for i in range ( index , self . size () - 1 ): self . items [ i ] = self . items [ i + 1 ] # \u5c06\u6570\u7ec4\u5c3e\u90e8\u7684\u7a7a\u4f59\u4f4d\u8d4b\u503cfillValue\uff0c\u9ed8\u8ba4\u662fNone self . items [ self . size () - 1 ] = self . fillValue # \u51cf\u5c11\u6570\u7ec4\u903b\u8f91\u5c3a\u5bf8 self . logicalSize -= 1 # \u51cf\u5c11\u6570\u7ec4\u7269\u7406\u5c3a\u5bf8 # \u5f53: # - \u6570\u7ec4\u7684\u903b\u8f91\u5c3a\u5bf8\u5c0f\u4e8e\u6216\u7b49\u4e8e\u5176\u7269\u7406\u5c3a\u5bf8\u76841/4 # - \u5e76\u4e14\u5b83\u7684\u7269\u7406\u5c3a\u5bf8\u81f3\u5c11\u662f\u8fd9\u4e2a\u6570\u7ec4\u5efa\u7acb\u65f6\u9ed8\u8ba4\u5bb9\u91cf\u76842\u500d\u65f6 # \u5219\u628a\u6570\u7ec4\u7684\u7269\u7406\u5c3a\u5bf8\u51cf\u5c0f\u5230\u539f\u6765\u7684\u4e00\u534a\uff0c\u5e76\u4e14\u4e5f\u4e0d\u4f1a\u5c0f\u4e8e\u5176\u9ed8\u8ba4\u5bb9\u91cf if self . size () <= len ( self ) // 4 and len ( self ) > self . capacity : self . shrink () # \u8fd4\u56de\u88ab\u5220\u9664\u5143\u7d20\u7684\u503c print ( f 'Item { itemToReturn } was deleted' ) return itemToReturn def main (): # \u521d\u59cb\u5316\u7a7a\u6570\u7ec4 DEFAULT_CAPACITY = 5 my_arr = Array ( DEFAULT_CAPACITY ) # \u6253\u5370\u8f93\u51fa\u6570\u7ec4\u521d\u59cb\u4fe1\u606f print ( \"Physical size:\" , len ( my_arr )) print ( \"Logical size:\" , my_arr . size ()) print ( \"Initial items:\" , my_arr . items ) # \u521d\u59cb\u5316\u6570\u7ec4\u5143\u7d20 print ( '------' ) for item in range ( 4 ): my_arr . insert ( 0 , item ) # \u5728\u6570\u7ec4\u5934\u90e8\u63d2\u5165\uff0c\u6bcf\u63d2\u5165\u4e00\u6b21\u90fd\u9700\u8981\u5411\u540e\u79fb\u52a8\u5df2\u6709\u6570\u7ec4\u5143\u7d20 print ( \"Items(logical):\" , my_arr ) print ( \"Items(physical):\" , my_arr . items ) # \u5728\u6570\u7ec4\u4e2d\u95f4\u63d2\u5165\u65b0\u5143\u7d20 print ( '------' ) my_arr . insert ( 3 , 99 ) print ( \"Items(logical):\" , my_arr ) print ( \"Items(physical):\" , my_arr . items ) # \u5728\u6570\u7ec4\u903b\u8f91\u5c3a\u5bf8\u5916\u63d2\u5165\u65b0\u5143\u7d20 print ( '------' ) my_arr . insert ( 20 , 88 ) print ( \"Items(logical):\" , my_arr ) print ( \"Items(physical):\" , my_arr . items ) # \u5220\u9664\u6570\u7ec4\u5143\u7d20 print ( '------' ) my_arr . pop ( 3 ) my_arr . pop ( 3 ) print ( \"Items(logical):\" , my_arr ) print ( \"Items(physical):\" , my_arr . items ) # \u6e05\u7a7a\u6570\u7ec4\u5143\u7d20 print ( '------' ) for count in range ( my_arr . size ()): my_arr . pop ( 0 ) print ( \"Items(logical):\" , my_arr ) print ( \"Items(physical):\" , my_arr . items ) # \u6570\u7ec4\u5143\u7d20\u5df2\u7ecf\u5168\u90e8\u5220\u9664\uff0c\u903b\u8f91\u5c3a\u5bf8\u4e3a\u96f6\uff0c\u4e0b\u9762\u547d\u4ee4\u8fd4\u56de\u9519\u8bef # print('------') # print(my_arr.pop(0)) # \u6570\u7ec4\u6bd4\u8f83 # \u521d\u59cb\u5316\u6570\u7ec4 print ( '------' ) arr_a = Array ( 5 ) for item in range ( 4 ): arr_a . insert ( 0 , item ) arr_b = arr_a arr_c = Array ( 5 ) for item in range ( 4 ): arr_c . insert ( 0 , item ) arr_d = [] print ( \"arr_a(physical):\" , arr_a . items ) print ( \"arr_b(physical):\" , arr_b . items ) print ( \"arr_c(physical):\" , arr_c . items ) print ( \"arr_d(physical):\" , arr_d ) print ( \"arr_a == arr_b:\" , arr_a == arr_b ) print ( \"arr_a is arr_b:\" , arr_a is arr_b ) print ( \"arr_a == arr_c:\" , arr_a == arr_c ) print ( \"arr_a is arr_c:\" , arr_a is arr_c ) arr_c . insert ( 10 , 10 ) print ( \"arr_a == arr_c:\" , arr_a == arr_c ) arr_c . pop ( arr_c . size () - 1 ) arr_c [ 2 ] = 6 print ( \"arr_a == arr_c:\" , arr_a == arr_c ) print ( \"arr_a == arr_d:\" , arr_a == arr_d ) if __name__ == \"__main__\" : main () # \u8fd0\u884c\u7ed3\u679c # Physical size: 5 # Logical size: 0 # Initial items: [None, None, None, None, None] # ------ # Items(logical): 3 2 1 0 # Items(physical): [3, 2, 1, 0, None] # ------ # Items(logical): 3 2 1 99 0 # Items(physical): [3, 2, 1, 99, 0] # ------ # Items(logical): 3 2 1 99 0 88 # Items(physical): [3, 2, 1, 99, 0, 88, None, None, None, None] # ------ # Item 99 was deleted # Item 0 was deleted # Items(logical): 3 2 1 88 # Items(physical): [3, 2, 1, 88, None, None, None, None, None, None] # ------ # Item 3 was deleted # Item 2 was deleted # Item 1 was deleted # Item 88 was deleted # Items(logical): # Items(physical): [None, None, None, None, None] # ------ # IndexError: \u5220\u9664\u64cd\u4f5c\u51fa\u9519, \u6570\u7ec4\u7d22\u5f15\u8d8a\u754c(\u4e0d\u5728\u6570\u7ec4\u903b\u8f91\u8fb9\u754c\u8303\u56f4\u5185) # ------ # arr_a(physical): [3, 2, 1, 0, None] # arr_b(physical): [3, 2, 1, 0, None] # arr_c(physical): [3, 2, 1, 0, None] # arr_d(physical): [] # arr_a == arr_b: True # arr_a is arr_b: True # arr_a == arr_c: True # arr_a is arr_c: False # arr_a == arr_c: False # Item 10 was deleted # arr_a == arr_c: False # arr_a == arr_d: False","title":"4.2.\u6570\u7ec4\u7684\u64cd\u4f5c"},{"location":"python/DataStructure/04_ArrayChain/#421","text":"\u5f53\u6570\u7ec4\u7684\u903b\u8f91\u5c3a\u5bf8\u7b49\u4e8e\u5b83\u7684\u7269\u7406\u5c3a\u5bf8\u65f6\uff0c\u5982\u679c\u8981\u63d2\u5165\u65b0\u7684\u5143\u7d20\uff0c\u5c31\u9700\u8981\u589e\u5927\u6570\u7ec4\u7684\u7269\u7406\u5c3a\u5bf8\u3002 \u5982\u679c\u9700\u8981\u4e3a\u6570\u7ec4\u63d0\u4f9b\u66f4\u591a\u5185\u5b58\uff0cPython\u7684list\u7c7b\u578b\u4f1a\u5728\u8c03\u7528insert\u6216append\u65b9\u6cd5\u65f6\u6267\u884c\u8fd9\u4e2a\u64cd\u4f5c\u3002 \u8c03\u6574\u6570\u7ec4\u7269\u7406\u5c3a\u5bf8\u7684\u8fc7\u7a0b\u5305\u542b\u5982\u4e0b3\u4e2a\u6b65\u9aa4\u3002 \u521b\u5efa\u4e00\u4e2a\u66f4\u5927\u7684\u65b0\u6570\u7ec4\u3002 \u5c06\u6570\u636e\u4ece\u65e7\u6570\u7ec4\u4e2d\u590d\u5236\u5230\u65b0\u6570\u7ec4\u3002 \u5c06\u6307\u5411\u65e7\u6570\u7ec4\u7684\u53d8\u91cf\u6307\u5411\u65b0\u6570\u7ec4\u5bf9\u8c61\u3002 \u4e0b\u9762\u4ee3\u7801\u5b9e\u73b0\u3002 # \u589e\u5927\u6570\u7ec4\u7269\u7406\u5c3a\u5bf8 if logicalSize == len ( my_array ): temp = Array ( len ( my_array ) + 1 ) # \u521b\u5efa\u4e00\u4e2a\u65b0\u6570\u7ec4 for i in range ( logicalSize ): temp [ i ] = my_array [ i ] # \u4ece\u539f\u6570\u7ec4\u590d\u5236\u5185\u5bb9\u5230\u65b0\u6570\u7ec4 my_array = temp # \u628a\u65b0\u6570\u7ec4\u8d4b\u503c\u7ed9\u539f\u6570\u7ec4 \u5728\u4e0a\u9762\u4ee3\u7801\u4e2d\uff0c\u901a\u8fc7 temp[i] = my_array[i] \u6765\u8c03\u6574\u6570\u7ec4\u5c3a\u5bf8\uff0c\u8fd9\u4e2a\u590d\u5236\u64cd\u4f5c\u7684\u6570\u91cf\u662f\u7ebf\u6027\u589e\u957f\u7684\u3002\u56e0\u6b64\uff0c\u5c06 n \u4e2a\u5143\u7d20\u6dfb\u52a0\u5230\u6570\u7ec4\u91cc\u7684\u603b\u65f6\u95f4\u590d\u6742\u5ea6\u662f 1+2+3...+n \uff0c\u4e5f\u5c31\u662f n(n+1)/2 \uff0c\u56e0\u6b64\u662f O(n^2) \u3002 \u5728\u4e0a\u9762\u7684\u4ee3\u7801\u4e2d\uff0c\u901a\u8fc7 temp = Array(len(my_array) + 1) \u5bf9\u6570\u7ec4\u8fdb\u884c\u52a8\u6001\u6269\u5c55\uff0c\u5bf9\u6027\u80fd\u4f1a\u4ea7\u751f\u4e00\u4e9b\u53ef\u80fd\u7684\u5f71\u54cd\uff1a \u65f6\u95f4\u590d\u6742\u5ea6\uff1a\u52a8\u6001\u6269\u5c55\u6570\u7ec4\u901a\u5e38\u9700\u8981\u590d\u5236\u73b0\u6709\u6570\u636e\u5230\u65b0\u7684\u5185\u5b58\u4f4d\u7f6e\uff0c\u8fd9\u5c06\u6d89\u53ca\u5230\u5143\u7d20\u7684\u590d\u5236\u64cd\u4f5c\u3002\u8fd9\u4e9b\u64cd\u4f5c\u7684\u65f6\u95f4\u590d\u6742\u5ea6\u53d6\u51b3\u4e8e\u6570\u7ec4\u7684\u957f\u5ea6\uff0c\u901a\u5e38\u662f O(n) \uff0c\u5176\u4e2d n \u662f\u6570\u7ec4\u7684\u957f\u5ea6\u3002\u56e0\u6b64\uff0c\u5f53\u6570\u7ec4\u9700\u8981\u6269\u5c55\u65f6\uff0c\u53ef\u80fd\u4f1a\u4ea7\u751f\u4e00\u4e9b\u989d\u5916\u7684\u65f6\u95f4\u5f00\u9500\u3002 \u7a7a\u95f4\u590d\u6742\u5ea6\uff1a\u52a8\u6001\u6269\u5c55\u6570\u7ec4\u4f1a\u5360\u7528\u989d\u5916\u7684\u5185\u5b58\u7a7a\u95f4\uff0c\u56e0\u4e3a\u9700\u8981\u5206\u914d\u65b0\u7684\u5185\u5b58\u5757\u6765\u5bb9\u7eb3\u6269\u5c55\u540e\u7684\u6570\u7ec4\u3002\u8fd9\u53ef\u80fd\u4f1a\u5bfc\u81f4\u5185\u5b58\u788e\u7247\u5316\uff0c\u7279\u522b\u662f\u5728\u9891\u7e41\u6269\u5c55\u548c\u7f29\u5c0f\u6570\u7ec4\u65f6\u3002 \u6269\u5c55\u9891\u7387\uff1a\u6269\u5c55\u6570\u7ec4\u7684\u9891\u7387\u4f1a\u5f71\u54cd\u6027\u80fd\u3002\u5982\u679c\u6570\u7ec4\u9700\u8981\u9891\u7e41\u6269\u5c55\uff0c\u90a3\u4e48\u590d\u5236\u548c\u5185\u5b58\u5206\u914d\u7684\u5f00\u9500\u4f1a\u66f4\u52a0\u663e\u8457\uff0c\u4ece\u800c\u964d\u4f4e\u6027\u80fd\u3002\u56e0\u6b64\uff0c\u5728\u8bbe\u8ba1\u6570\u636e\u7ed3\u6784\u65f6\uff0c\u901a\u5e38\u4f1a\u8003\u8651\u521d\u59cb\u5bb9\u91cf\u548c\u6269\u5c55\u7b56\u7565\uff0c\u4ee5\u51cf\u5c11\u4e0d\u5fc5\u8981\u7684\u6269\u5c55\u6b21\u6570\u3002 Amortized Analysis\uff1a\u4e00\u4e9b\u6570\u636e\u7ed3\u6784\uff0c\u4f8b\u5982Python\u7684\u5217\u8868\uff08list\uff09\uff0c\u91c7\u7528\u644a\u8fd8\u5206\u6790\u6765\u5e73\u644a\u52a8\u6001\u6269\u5c55\u7684\u5f00\u9500\u3002\u8fd9\u610f\u5473\u7740\u867d\u7136\u67d0\u4e9b\u64cd\u4f5c\u53ef\u80fd\u4f1a\u82b1\u8d39 O(n) \u7684\u65f6\u95f4\uff0c\u4f46\u8fd9\u4e9b\u5f00\u9500\u5728\u4e00\u7cfb\u5217\u64cd\u4f5c\u4e2d\u88ab\u5206\u644a\uff0c\u5e73\u5747\u4e0b\u6765\u4ecd\u7136\u4fdd\u6301\u8f83\u4f4e\u7684\u590d\u6742\u5ea6\u3002\u8fd9\u53ef\u4ee5\u5728\u4e00\u5b9a\u7a0b\u5ea6\u4e0a\u7f13\u89e3\u6027\u80fd\u95ee\u9898\u3002 \u52a8\u6001\u6269\u5c55\u6570\u7ec4\u4f1a\u5f15\u5165\u4e00\u4e9b\u6027\u80fd\u5f00\u9500\uff0c\u4f46\u5728\u5b9e\u9645\u5e94\u7528\u4e2d\uff0c\u8fd9\u79cd\u5f00\u9500\u901a\u5e38\u662f\u53ef\u4ee5\u63a5\u53d7\u7684\u3002\u4e3a\u4e86\u4f18\u5316\u6027\u80fd\uff0c\u53ef\u4ee5\u8003\u8651\u4ee5\u4e0b\u51e0\u70b9\u7b56\u7565\uff0c\u9700\u8981\u6839\u636e\u5177\u4f53\u5e94\u7528\u7684\u9700\u6c42\u548c\u6027\u80fd\u8981\u6c42\u6765\u6743\u8861\u8fd9\u4e9b\u56e0\u7d20\uff1a \u9884\u5148\u5206\u914d\u8db3\u591f\u7684\u521d\u59cb\u5bb9\u91cf\uff0c\u4ee5\u51cf\u5c11\u6269\u5c55\u7684\u9891\u7387\u3002 \u4f7f\u7528\u644a\u8fd8\u5206\u6790\u6765\u5e73\u644a\u5f00\u9500\u3002 \u8003\u8651\u4f7f\u7528\u5176\u4ed6\u6570\u636e\u7ed3\u6784\uff0c\u5982\u94fe\u8868\uff0c\u5bf9\u63d2\u5165\u548c\u5220\u9664\u64cd\u4f5c\u7684\u6027\u80fd\u66f4\u52a0\u53cb\u597d\u3002 \u4e0b\u9762\uff0c\u5c1d\u8bd5\u5728\u6bcf\u6b21\u589e\u5927\u6570\u7ec4\u5c3a\u5bf8\u65f6\u628a\u6570\u7ec4\u5c3a\u5bf8\u7ffb\u500d\uff0c\u4ee3\u7801\u5b9e\u73b0\u5982\u4e0b\uff1a # \u589e\u5927\u6570\u7ec4\u7269\u7406\u5c3a\u5bf8 while logicalSize < DEFAULT_CAPACITY * 2 : logicalSize += 1 if logicalSize == len ( my_array ): # \u89e6\u53d1\u6761\u4ef6 temp = Array ( len ( my_array ) + 1 ) # \u521b\u5efa\u4e00\u4e2a\u65b0\u6570\u7ec4 for i in range ( logicalSize ): temp [ i ] = my_array [ i ] # \u4ece\u539f\u6570\u7ec4\u590d\u5236\u5185\u5bb9\u5230\u65b0\u6570\u7ec4 my_array = temp # \u628a\u65b0\u6570\u7ec4\u8d4b\u503c\u7ed9\u539f\u6570\u7ec4 \u5c06\u6570\u7ec4\u5c3a\u5bf8\u7ffb\u500d\u6765\u6269\u5c55\u6570\u7ec4\u7684\u65b9\u5f0f\u662f\u4e00\u79cd\u5e38\u89c1\u7684\u7b56\u7565\uff0c\u901a\u5e38\u7528\u4e8e\u51cf\u5c11\u52a8\u6001\u6570\u7ec4\u7684\u9891\u7e41\u6269\u5c55\u6b21\u6570\uff0c\u4ee5\u63d0\u9ad8\u6027\u80fd\u3002\u8fd9\u79cd\u65b9\u5f0f\u7684\u64cd\u4f5c\u65f6\u95f4\u590d\u6742\u5ea6\u4e3b\u8981\u53d6\u51b3\u4e8e\u6269\u5c55\u64cd\u4f5c\u7684\u9891\u7387\u548c\u5143\u7d20\u7684\u590d\u5236\u6210\u672c\u3002 \u644a\u8fd8\u5206\u6790\uff1a\u5bf9\u4e8e\u5c06\u6570\u7ec4\u5c3a\u5bf8\u7ffb\u500d\u7684\u7b56\u7565\uff0c\u644a\u8fd8\u5206\u6790\u8868\u660e\uff0c\u6bcf\u6b21\u6269\u5c55\u64cd\u4f5c\u7684\u644a\u8fd8\u65f6\u95f4\u590d\u6742\u5ea6\u4ecd\u7136\u662f\u5e38\u6570\u65f6\u95f4\u7684\uff08\u901a\u5e38\u662fO(1)\uff09\uff0c\u8fd9\u610f\u5473\u7740\u5e73\u5747\u4e0b\u6765\uff0c\u6bcf\u6b21\u6269\u5c55\u7684\u5f00\u9500\u662f\u56fa\u5b9a\u7684\uff0c\u800c\u4e0d\u4f1a\u968f\u6570\u7ec4\u7684\u5927\u5c0f\u7ebf\u6027\u589e\u52a0\u3002 \u64cd\u4f5c\u65f6\u95f4\uff1a\u5047\u8bbe\u6570\u7ec4\u9700\u8981\u6269\u5c55\uff0c\u90a3\u4e48\u5c06\u6570\u7ec4\u5c3a\u5bf8\u7ffb\u500d\u9700\u8981\u5206\u914d\u65b0\u7684\u5185\u5b58\u5757\u5e76\u590d\u5236\u73b0\u6709\u5143\u7d20\uff0c\u8fd9\u4e2a\u64cd\u4f5c\u7684\u65f6\u95f4\u590d\u6742\u5ea6\u662fO(n)\uff0c\u5176\u4e2dn\u662f\u6570\u7ec4\u7684\u5f53\u524d\u5927\u5c0f\u3002\u7136\u800c\uff0c\u7531\u4e8e\u6269\u5c55\u64cd\u4f5c\u4e0d\u662f\u6bcf\u6b21\u90fd\u6267\u884c\u7684\uff0c\u800c\u662f\u5f53\u6570\u7ec4\u5df2\u6ee1\u65f6\u624d\u6267\u884c\uff0c\u56e0\u6b64\u53ef\u4ee5\u8ba4\u4e3a\u8fd9\u4e2a\u64cd\u4f5c\u7684\u644a\u8fd8\u65f6\u95f4\u662f\u5e38\u6570\u65f6\u95f4\uff0c\u5373O(1)\u3002 \u7a7a\u95f4\u590d\u6742\u5ea6\uff1a\u5c06\u6570\u7ec4\u5c3a\u5bf8\u7ffb\u500d\u4f1a\u5360\u7528\u989d\u5916\u7684\u5185\u5b58\u7a7a\u95f4\uff0c\u4f46\u968f\u7740\u6570\u7ec4\u7684\u589e\u957f\uff0c\u989d\u5916\u5185\u5b58\u7684\u5360\u7528\u76f8\u5bf9\u4e8e\u6570\u7ec4\u672c\u8eab\u7684\u5927\u5c0f\u6765\u8bf4\u662f\u6709\u9650\u7684\u3002\u901a\u5e38\u60c5\u51b5\u4e0b\uff0c\u8fd9\u79cd\u5360\u7528\u53ef\u4ee5\u63a5\u53d7\u3002 \u603b\u7ed3\uff0c\u5c06\u6570\u7ec4\u5c3a\u5bf8\u7ffb\u500d\u7684\u7b56\u7565\u53ef\u4ee5\u663e\u8457\u51cf\u5c11\u52a8\u6001\u6570\u7ec4\u7684\u6269\u5c55\u6b21\u6570\uff0c\u4ece\u800c\u63d0\u9ad8\u6027\u80fd\u3002\u867d\u7136\u6bcf\u6b21\u6269\u5c55\u64cd\u4f5c\u53ef\u80fd\u4f1a\u82b1\u8d39\u4e00\u4e9b\u65f6\u95f4\u548c\u989d\u5916\u5185\u5b58\uff0c\u4f46\u8fd9\u4e9b\u5f00\u9500\u5728\u4e00\u7cfb\u5217\u64cd\u4f5c\u4e2d\u88ab\u5e73\u644a\uff0c\u5e73\u5747\u4e0b\u6765\u662f\u5e38\u6570\u65f6\u95f4\u3002\u8fd9\u662f\u4e00\u79cd\u9ad8\u6548\u7684\u52a8\u6001\u6570\u7ec4\u5b9e\u73b0\u65b9\u5f0f\uff0c\u5e38\u89c1\u4e8e\u8bb8\u591a\u7f16\u7a0b\u8bed\u8a00\u7684\u6807\u51c6\u5e93\u4e2d\uff0c\u5305\u62ecPython\u7684\u5217\u8868\uff08list\uff09\u3002 \u5728\u589e\u52a0\u6570\u7ec4\u7684\u957f\u5ea6\u65f6\uff0c\u6bcf\u6b21\u589e\u52a0\u4e00\u4e2a\u5185\u5b58\u5355\u5143\uff0c\u4e0e\u6bcf\u6b21\u589e\u5927\u6570\u7ec4\u5c3a\u5bf8\u65f6\u628a\u6570\u7ec4\u5c3a\u5bf8\u7ffb\u500d\u76f8\u6bd4\uff0c\u540e\u8005\u7684\u65b9\u6cd5\u901a\u5e38\u66f4\u9ad8\u6548\u3002 \u6bcf\u6b21\u589e\u52a0\u4e00\u4e2a\u5185\u5b58\u5355\u5143\uff1a\u8fd9\u79cd\u65b9\u5f0f\u5728\u6bcf\u6b21\u6dfb\u52a0\u65b0\u5143\u7d20\u65f6\u90fd\u9700\u8981\u5206\u914d\u989d\u5916\u7684\u5185\u5b58\uff0c\u5bfc\u81f4\u6570\u7ec4\u5c3a\u5bf8\u7684\u589e\u957f\u662f\u7ebf\u6027\u7684\u3002\u5982\u679c\u9891\u7e41\u6dfb\u52a0\u5143\u7d20\uff0c\u8fd9\u5c06\u5bfc\u81f4\u5927\u91cf\u7684\u5185\u5b58\u5206\u914d\u548c\u6570\u636e\u590d\u5236\u64cd\u4f5c\uff0c\u56e0\u6b64\u65f6\u95f4\u590d\u6742\u5ea6\u4f1a\u53d8\u5f97\u76f8\u5bf9\u8f83\u9ad8\u3002 \u6bcf\u6b21\u589e\u5927\u6570\u7ec4\u5c3a\u5bf8\u65f6\u628a\u6570\u7ec4\u5c3a\u5bf8\u7ffb\u500d\uff1a\u8fd9\u662f\u4e00\u79cd\u66f4\u9ad8\u6548\u7684\u7b56\u7565\u3002\u5728\u8fd9\u79cd\u65b9\u5f0f\u4e0b\uff0c\u6bcf\u6b21\u6269\u5c55\u64cd\u4f5c\u90fd\u4f1a\u589e\u52a0\u6570\u7ec4\u7684\u5c3a\u5bf8\uff0c\u4f46\u589e\u5e45\u662f\u6307\u6570\u7ea7\u7684\uff0c\u800c\u4e0d\u662f\u7ebf\u6027\u7684\u3002\u8fd9\u610f\u5473\u7740\u968f\u7740\u6570\u7ec4\u7684\u589e\u957f\uff0c\u6269\u5c55\u64cd\u4f5c\u7684\u9891\u7387\u4f1a\u51cf\u5c11\uff0c\u56e0\u4e3a\u6570\u7ec4\u80fd\u591f\u5bb9\u7eb3\u66f4\u591a\u5143\u7d20\u3002\u8fd9\u6837\uff0c\u867d\u7136\u6bcf\u6b21\u6269\u5c55\u64cd\u4f5c\u9700\u8981\u590d\u5236\u66f4\u591a\u7684\u5143\u7d20\uff0c\u4f46\u5b83\u4eec\u7684\u644a\u8fd8\u65f6\u95f4\u590d\u6742\u5ea6\u4ecd\u7136\u662f\u5e38\u6570\u65f6\u95f4\uff0c\u56e0\u4e3a\u5b83\u4eec\u4e0d\u662f\u6bcf\u6b21\u90fd\u6267\u884c\u7684\u3002 \u603b\u7ed3\uff0c\u5c06\u6570\u7ec4\u5c3a\u5bf8\u7ffb\u500d\u7684\u7b56\u7565\u901a\u5e38\u66f4\u9ad8\u6548\uff0c\u56e0\u4e3a\u5b83\u53ef\u4ee5\u51cf\u5c11\u9891\u7e41\u7684\u5185\u5b58\u5206\u914d\u548c\u590d\u5236\u64cd\u4f5c\uff0c\u964d\u4f4e\u4e86\u65f6\u95f4\u590d\u6742\u5ea6\u3002\u8fd9\u662f\u8bb8\u591a\u52a8\u6001\u6570\u7ec4\u5b9e\u73b0\u7684\u5e38\u89c1\u505a\u6cd5\uff0c\u5305\u62ecPython\u7684\u5217\u8868\uff08list\uff09\u3002 \u5728 Array \u7c7b\u5b9e\u73b0\u4e2d\uff0c\u662f\u901a\u8fc7\u4e0b\u9762\u4ee3\u7801\u6bb5\u5b9e\u73b0\u7684\u6570\u7ec4\u7269\u7406\u5c3a\u5bf8\u589e\u52a0\u7684\uff0c\u5373\u5c06\u6570\u7ec4\u5c3a\u5bf8\u7ffb\u500d\u3002 def grow ( self ): \"\"\"\u589e\u5927\u6570\u7ec4\u7269\u7406\u5c3a\u5bf8\"\"\" # \u57fa\u4e8e\u5f53\u524d\u7269\u7406\u5c3a\u5bf8\u52a0\u500d\uff0c\u5e76\u5c06fillValue\u8d4b\u503c\u5e95\u5c42\u5217\u8868\u7684\u65b0\u5143\u7d20 for count in range ( len ( self )): self . items . append ( self . fillValue )","title":"4.2.1.\u589e\u5927\u6570\u7ec4\u7684\u5c3a\u5bf8"},{"location":"python/DataStructure/04_ArrayChain/#422","text":"\u5982\u679c\u51cf\u5c0f\u6570\u7ec4\u7684\u903b\u8f91\u5c3a\u5bf8\uff0c\u5c31\u4f1a\u6d6a\u8d39\u76f8\u5e94\u7684\u5185\u5b58\u5355\u5143\u3002\u56e0\u6b64\uff0c\u5f53\u5220\u9664\u67d0\u4e00\u4e2a\u5143\u7d20\uff0c\u5982\u679c\u672a\u4f7f\u7528\u7684\u5185\u5b58\u5355\u5143\u6570\u8fbe\u5230\u6216\u8d85\u8fc7\u4e86\u67d0\u4e2a\u9608\u503c\uff08\u5982\u6570\u7ec4\u7269\u7406\u5c3a\u5bf8\u7684\u00be\uff09\u65f6\uff0c\u5219\u5e94\u8be5\u51cf\u5c0f\u7269\u7406\u5c3a\u5bf8\u4e86\u3002\u5982\u679c\u6d6a\u8d39\u7684\u5185\u5b58\u8d85\u8fc7\u7279\u5b9a\u9608\u503c\uff0c\u90a3\u4e48Python\u7684list\u7c7b\u578b\u4f1a\u5728\u8c03\u7528 pop \u65b9\u6cd5\u65f6\u6267\u884c\u51cf\u5c0f\u6570\u7ec4\u7269\u7406\u5c3a\u5bf8\u7684\u64cd\u4f5c\u3002 \u51cf\u5c0f\u6570\u7ec4\u5c3a\u5bf8\u7684\u8fc7\u7a0b\u4e0e\u589e\u5927\u6570\u7ec4\u5c3a\u5bf8\u7684\u8fc7\u7a0b\u76f8\u53cd\uff0c\u6b65\u9aa4\u5982\u4e0b\uff1a \u521b\u5efa\u4e00\u4e2a\u66f4\u5c0f\u7684\u65b0\u6570\u7ec4\u3002 \u5c06\u6570\u636e\u4ece\u65e7\u6570\u7ec4\u4e2d\u590d\u5236\u5230\u65b0\u6570\u7ec4\u3002 \u5c06\u6307\u5411\u65e7\u6570\u7ec4\u7684\u53d8\u91cf\u6307\u5411\u65b0\u6570\u7ec4\u5bf9\u8c61\u3002 \u4e0b\u9762\u7684\u4ee3\u7801\u5b9e\u73b0\u4e86\u51cf\u5c0f\u6570\u7ec4\u5c3a\u5bf8\u3002 \u5f53\u6570\u7ec4\u7684\u903b\u8f91\u5c3a\u5bf8\u5c0f\u4e8e\u6216\u7b49\u4e8e\u5176\u7269\u7406\u5c3a\u5bf8\u7684\u00bc\uff0c\u5e76\u4e14\u5b83\u7684\u7269\u7406\u5c3a\u5bf8\u81f3\u5c11\u662f\u8fd9\u4e2a\u6570\u7ec4\u5efa\u7acb\u65f6\u9ed8\u8ba4\u5bb9\u91cf\u76842\u500d\u65f6\uff0c\u5219\u4e0b\u9762\u7684\u7b97\u6cd5\u628a\u6570\u7ec4\u7684\u7269\u7406\u5c3a\u5bf8\u51cf\u5c0f\u5230\u539f\u6765\u7684\u4e00\u534a\uff0c\u5e76\u4e14\u4e5f\u4e0d\u4f1a\u5c0f\u4e8e\u5176\u9ed8\u8ba4\u5bb9\u91cf\u3002 # \u51cf\u5c0f\u6570\u7ec4\u7269\u7406\u5c3a\u5bf8 while logicalSize > len ( my_array ) // 4 : logicalSize -= 1 if logicalSize <= len ( my_array ) // 4 and len ( my_array ) >= DEFAULT_CAPACITY * 2 : # \u89e6\u53d1\u6761\u4ef6 temp = Array ( len ( my_array ) // 2 ) # \u521b\u5efa\u4e00\u4e2a\u65b0\u6570\u7ec4 for i in range ( logicalSize ): temp [ i ] = my_array [ i ] # \u4ece\u539f\u6570\u7ec4\u590d\u5236\u5185\u5bb9\u5230\u65b0\u6570\u7ec4 my_array = temp # \u628a\u65b0\u6570\u7ec4\u8d4b\u503c\u7ed9\u539f\u6570\u7ec4 \u6309\u7167\u4e0a\u9762\u7b97\u6cd5\u51cf\u5c11\u6570\u7ec4\u7684\u5c3a\u5bf8\uff0c\u6211\u4eec\u53ef\u4ee5\u5206\u6790\u5176\u65f6\u95f4\u548c\u7a7a\u95f4\u590d\u6742\u5ea6\u5982\u4e0b\uff1a \u65f6\u95f4\u590d\u6742\u5ea6\uff1a\u4e3b\u8981\u6d89\u53ca\u4e24\u4e2a\u64cd\u4f5c\uff1a \u521b\u5efa\u65b0\u6570\u7ec4\u5e76\u5c06\u5143\u7d20\u4ece\u65e7\u6570\u7ec4\u590d\u5236\u5230\u65b0\u6570\u7ec4\uff1b \u5c06\u65e7\u6570\u7ec4\u5f15\u7528\u66f4\u6539\u4e3a\u65b0\u6570\u7ec4\u3002 \u590d\u5236\u64cd\u4f5c\u7684\u65f6\u95f4\u590d\u6742\u5ea6\u53d6\u51b3\u4e8e\u6570\u7ec4\u7684\u7269\u7406\u5c3a\u5bf8\uff0c\u53ef\u4ee5\u8868\u793a\u4e3a O(n) \uff0c\u5176\u4e2d n \u662f\u6570\u7ec4\u7684\u5f53\u524d\u7269\u7406\u5c3a\u5bf8\u3002\u5f15\u7528\u66f4\u6539\u662f\u4e00\u4e2a\u5e38\u6570\u65f6\u95f4\u64cd\u4f5c\uff0c\u4e0d\u5f71\u54cd\u65f6\u95f4\u590d\u6742\u5ea6\u3002\u6240\u4ee5\uff0c\u6574\u4f53\u7684\u65f6\u95f4\u590d\u6742\u5ea6\u662f O(n) \u3002 \u7a7a\u95f4\u590d\u6742\u5ea6\uff1a\u7a7a\u95f4\u590d\u6742\u5ea6\u4e5f\u6d89\u53ca\u4e24\u4e2a\u65b9\u9762\uff1a \u521b\u5efa\u65b0\u6570\u7ec4\u7684\u5185\u5b58\u6d88\u8017\uff0c\u5176\u7a7a\u95f4\u590d\u6742\u5ea6\u662fO(N)\uff1b \u5f15\u7528\u66f4\u6539\u6240\u9700\u7684\u5e38\u6570\u989d\u5916\u7a7a\u95f4\uff0c\u901a\u5e38\u5ffd\u7565\u4e0d\u8ba1\u3002 \u6240\u4ee5\uff0c\u603b\u7684\u7a7a\u95f4\u590d\u6742\u5ea6\u662f O(n) \u3002 \u8fd9\u4e2a\u7b97\u6cd5\u7b56\u7565\u4f1a\u5728\u9002\u5f53\u7684\u65f6\u5019\u51cf\u5c0f\u6570\u7ec4\u7684\u7269\u7406\u5c3a\u5bf8\uff0c\u4ee5\u51cf\u5c11\u5185\u5b58\u5360\u7528\uff0c\u4f46\u4ecd\u7136\u4fdd\u6301\u7740\u6570\u7ec4\u7684\u52a8\u6001\u6027\u3002\u65f6\u95f4\u590d\u6742\u5ea6\u548c\u7a7a\u95f4\u590d\u6742\u5ea6\u90fd\u4e0e\u5f53\u524d\u6570\u7ec4\u7684\u7269\u7406\u5c3a\u5bf8\u6210\u7ebf\u6027\u5173\u7cfb\uff0c\u56e0\u6b64\u662f\u7ebf\u6027\u7684\uff0c\u8fd9\u662f\u4e00\u79cd\u6709\u6548\u7684\u7b56\u7565\u6765\u4f18\u5316\u5185\u5b58\u4f7f\u7528\u3002\u540c\u65f6\uff0c\u4fdd\u7559\u4e86\u4e00\u5b9a\u7684\u5197\u4f59\u7a7a\u95f4\uff0c\u4ee5\u907f\u514d\u9891\u7e41\u5730\u6269\u5c55\u548c\u7f29\u5c0f\u6570\u7ec4\uff0c\u4ece\u800c\u63d0\u9ad8\u4e86\u6027\u80fd\u3002 \u4e0b\u9762\u662f\u5728 Array \u7c7b\u4e2d\u5b9e\u73b0\u51cf\u5c0f\u6570\u7ec4\u7684\u7269\u7406\u5c3a\u5bf8\u7684\u4ee3\u7801\u3002 def shrink ( self ): \"\"\" \u51cf\u5c11\u6570\u7ec4\u7684\u7269\u7406\u5c3a\u5bf8 \u5f53: - \u6570\u7ec4\u7684\u903b\u8f91\u5c3a\u5bf8\u5c0f\u4e8e\u6216\u7b49\u4e8e\u5176\u7269\u7406\u5c3a\u5bf8\u76841/4 - \u5e76\u4e14\u5b83\u7684\u7269\u7406\u5c3a\u5bf8\u81f3\u5c11\u662f\u8fd9\u4e2a\u6570\u7ec4\u5efa\u7acb\u65f6\u9ed8\u8ba4\u5bb9\u91cf\u76842\u500d\u65f6 \u5219\u628a\u6570\u7ec4\u7684\u7269\u7406\u5c3a\u5bf8\u51cf\u5c0f\u5230\u539f\u6765\u7684\u4e00\u534a\uff0c\u5e76\u4e14\u4e5f\u4e0d\u4f1a\u5c0f\u4e8e\u5176\u9ed8\u8ba4\u5bb9\u91cf \"\"\" # \u5728\u903b\u8f91\u5c3a\u5bf8\u548c\u7269\u7406\u5c3a\u5bf8\u7684\u4e00\u534a\u4e4b\u95f4\u9009\u62e9\u6700\u5927\u503c\u4f5c\u4e3a\u6570\u7ec4\u6536\u7f29\u540e\u7684\u7269\u7406\u5c3a\u5bf8 newSize = max ( self . capacity , len ( self ) // 2 ) # \u91ca\u653e\u591a\u4f59\u7684\u6570\u7ec4\u7a7a\u95f4 for count in range ( len ( self ) - newSize ): self . items . pop ()","title":"4.2.2.\u51cf\u5c0f\u6570\u7ec4\u7684\u5c3a\u5bf8"},{"location":"python/DataStructure/04_ArrayChain/#423","text":"\u628a\u5143\u7d20\u63d2\u5165\u6570\u7ec4\u4e2d\u548c\u66ff\u6362\u6570\u7ec4\u91cc\u7684\u5143\u7d20\u662f\u4e0d\u4e00\u6837\u7684\u3002 \u66ff\u6362\u6570\u7ec4\u5143\u7d20\u65f6\uff0c\u5143\u7d20\u5df2\u5728\u4e00\u4e2a\u7ed9\u5b9a\u7684\u7d22\u5f15\u4f4d\u7f6e\uff0c\u5bf9\u8fd9\u4e2a\u4f4d\u7f6e\u8fdb\u884c\u7b80\u5355\u590d\u5236\u5373\u53ef\uff0c\u6570\u7ec4\u7684\u903b\u8f91\u5c3a\u5bf8\u5e76\u4e0d\u4f1a\u6539\u53d8\u3002 \u63d2\u5165\u6570\u7ec4\u5143\u7d20\u65f6\uff0c\u9700\u8981\u5b8c\u6210\u4e0b\u97624\u4e2a\u6b65\u9aa4\uff1a \u5728\u63d2\u5165\u5143\u7d20\u4e4b\u524d\u5148\u68c0\u67e5\u53ef\u4ee5\u4f7f\u7528\u7684\u7a7a\u95f4\uff0c\u6839\u636e\u9700\u8981\u6765\u589e\u5927\u6570\u7ec4\u7684\u7269\u7406\u5c3a\u5bf8\u3002 \u5c06\u6570\u7ec4\u91cc\u4ece\u903b\u8f91\u7ed3\u5c3e\u5230\u76ee\u6807\u7d22\u5f15\u7684\u6240\u6709\u5143\u7d20\u5411\u540e\u79fb\u52a8\u3002\u8fd9\u4e2a\u8fc7\u7a0b\u4f1a\u5728\u76ee\u6807\u7d22\u5f15\u4f4d\u7f6e\u5904\u4e3a\u65b0\u5143\u7d20\u7559\u4e0b\u4e00\u4e2a\u7a7a\u683c\u3002 \u5c06\u65b0\u5143\u7d20\u5206\u914d\u5230\u76ee\u6807\u7d22\u5f15\u4f4d\u7f6e\u3002 \u5c06\u903b\u8f91\u5c3a\u5bf8\u52a01\u3002 \u5b9e\u73b0\u7b97\u6cd5\uff1a # \u5f53\u6570\u7ec4\u7684\u7269\u7406\u5c3a\u5bf8\u548c\u903b\u8f91\u5c3a\u5bf8\u4e00\u6837\u65f6\uff0c\u5219\u589e\u52a0\u7269\u7406\u5c3a\u5bf8 # \u5c06\u6570\u7ec4\u5143\u7d20\u5411\u5c3e\u90e8\u5e73\u79fb\u4e00\u4e2a\u4f4d\u7f6e for i in range ( logicalSize , targetIndex , - 1 ): my_array [ i ] = my_array [ i - 1 ] # \u63d2\u5165\u65b0\u5143\u7d20\uff0c\u589e\u52a0\u6570\u7ec4\u7684\u903b\u8f91\u5c3a\u5bf8 my_array [ targetIndex ] = newItem logicalSize += 1 \u4e0b\u9762\u662f Array \u7c7b\u4e2d\u5b9e\u73b0\u63d2\u5165\u5143\u7d20\u7684\u65b9\u6cd5\u3002 def insert ( self , index , newItem ): \"\"\"\u5728\u6570\u7ec4\u6307\u5b9a\u7d22\u5f15\u5904\u63d2\u5165\u65b0\u5143\u7d20\"\"\" # \u5f53\u6570\u7ec4\u7684\u7269\u7406\u5c3a\u5bf8\u548c\u903b\u8f91\u5c3a\u5bf8\u4e00\u6837\u65f6\uff0c\u5219\u589e\u52a0\u7269\u7406\u5c3a\u5bf8 if self . size () == len ( self ): self . grow () # \u63d2\u5165\u65b0\u5143\u7d20 # \u5f53\u63d2\u5165\u4f4d\u7f6e\u5927\u4e8e\u6216\u7b49\u4e8e\u6700\u5927\u903b\u8f91\u4f4d\u7f6e\uff0c\u5219\u5728\u6570\u7ec4\u672b\u7aef\u63d2\u5165\u65b0\u5143\u7d20 # \u5f53\u63d2\u5165\u4f4d\u7f6e\u4ecb\u4e8e\u6570\u7ec4\u903b\u8f91\u4f4d\u7f6e\u7684\u4e2d\u95f4\uff0c\u5219\u4ece\u63d2\u5165\u4f4d\u7f6e\u8d77\u5c06\u5269\u4f59\u6570\u7ec4\u5143\u7d20\u5411\u5c3e\u90e8\u5e73\u79fb\u4e00\u4e2a\u4f4d\u7f6e if index >= self . size (): self . items [ self . size ()] = newItem else : index = max ( index , 0 ) # \u5c06\u6570\u7ec4\u5143\u7d20\u5411\u5c3e\u90e8\u5e73\u79fb\u4e00\u4e2a\u4f4d\u7f6e for i in range ( self . size (), index , - 1 ): self . items [ i ] = self . items [ i - 1 ] # \u63d2\u5165\u65b0\u5143\u7d20 self . items [ index ] = newItem # \u589e\u52a0\u6570\u7ec4\u7684\u903b\u8f91\u5c3a\u5bf8 self . logicalSize += 1","title":"4.2.3.\u5c06\u5143\u7d20\u63d2\u5165\u589e\u5927\u7684\u6570\u7ec4"},{"location":"python/DataStructure/04_ArrayChain/#424","text":"\u4ece\u6570\u7ec4\u91cc\u5220\u9664\u5143\u7d20\u7684\u6b65\u9aa4\u5982\u4e0b\uff0c\u548c\u63d2\u5165\u64cd\u4f5c\u4e00\u6837\uff0c\u5143\u7d20\u7684\u79fb\u52a8\u987a\u5e8f\u975e\u5e38\u91cd\u8981\u3002 \u5c06\u6570\u7ec4\u91cc\u4ece\u76ee\u6807\u7d22\u5f15\u5230\u903b\u8f91\u7ed3\u5c3e\u7684\u6240\u6709\u5143\u7d20\u5411\u524d\u79fb\u52a8\uff0c\u628a\u6bcf\u4e2a\u5143\u7d20\u90fd\u590d\u5236\u5230\u5b83\u524d\u9762\u7684\u90a3\u4e2a\u5185\u5b58\u5355\u5143\u91cc\u3002\u8fd9\u4e2a\u8fc7\u7a0b\u4f1a\u5173\u95ed\u5220\u9664\u76ee\u6807\u7d22\u5f15\u4f4d\u7f6e\u4e2d\u7684\u5143\u7d20\u6240\u7559\u4e0b\u7684\u7a7a\u683c\u3002 \u5c06\u903b\u8f91\u5c3a\u5bf8\u51cf1\u3002 \u68c0\u67e5\u662f\u5426\u5b58\u5728\u5185\u5b58\u7a7a\u95f4\u7684\u6d6a\u8d39\uff0c\u5e76\u6839\u636e\u9700\u8981\u51cf\u5c0f\u6570\u7ec4\u7684\u7269\u7406\u5c3a\u5bf8\u3002 \u5728\u5e73\u5747\u60c5\u51b5\u4e0b\uff0c\u79fb\u52a8\u5143\u7d20\u7684\u65f6\u95f4\u590d\u6742\u5ea6\u662f\u7ebf\u6027\u7684\uff0c\u56e0\u6b64\u5220\u9664\u64cd\u4f5c\u7684\u65f6\u95f4\u590d\u6742\u5ea6\u4e5f\u662f\u7ebf\u6027\u7684\u3002 \u4e0b\u9762\u662f\u5b9e\u73b0\u5220\u9664\u64cd\u4f5c\u7684\u4ee3\u7801\u3002 # \u5c06\u6570\u7ec4\u5143\u7d20\u5411\u5934\u90e8\u5e73\u79fb\u4e00\u4e2a\u4f4d\u7f6e for i in range ( targetIndex , logicalSize - 1 ): my_array [ i ] = my_arraya [ i + 1 ] # \u51cf\u5c11\u6570\u7ec4\u903b\u8f91\u5c3a\u5bf8 logicalSize -= 1 # \u5982\u679c\u9700\u8981\uff0c\u5219\u51cf\u5c11\u6570\u7ec4\u7269\u7406\u5c3a\u5bf8 \u4e0b\u9762\u662f Array \u7c7b\u4e2d\u5b9e\u73b0\u5220\u9664\u5143\u7d20\u7684\u65b9\u6cd5\u3002 def pop ( self , index ): \"\"\" \u5220\u9664\u6307\u5b9a\u7d22\u5f15\u503c\u7684\u6570\u7ec4\u5143\u7d20,\u5e76\u8fd4\u56de\u5220\u9664\u7684\u6570\u7ec4\u5143\u7d20\u503c \u5148\u51b3\u6761\u4ef6: 0 <= index < size() \"\"\" if index < 0 or index >= self . size (): raise IndexError ( \"\u5220\u9664\u64cd\u4f5c\u51fa\u9519, \u6570\u7ec4\u7d22\u5f15\u8d8a\u754c(\u4e0d\u5728\u6570\u7ec4\u903b\u8f91\u8fb9\u754c\u8303\u56f4\u5185)\" ) # \u4fdd\u5b58\u5373\u5c06\u88ab\u5220\u9664\u7684\u6570\u7ec4\u5143\u7d20\u503c itemToReturn = self . items [ index ] # \u5c06\u6570\u7ec4\u5143\u7d20\u5411\u5934\u90e8\u5e73\u79fb\u4e00\u4e2a\u4f4d\u7f6e for i in range ( index , self . size () - 1 ): self . items [ i ] = self . items [ i + 1 ] # \u5c06\u6570\u7ec4\u5c3e\u90e8\u7684\u7a7a\u4f59\u4f4d\u8d4b\u503cfillValue\uff0c\u9ed8\u8ba4\u662fNone self . items [ self . size () - 1 ] = self . fillValue # \u51cf\u5c11\u6570\u7ec4\u903b\u8f91\u5c3a\u5bf8 self . logicalSize -= 1 # \u51cf\u5c11\u6570\u7ec4\u7269\u7406\u5c3a\u5bf8 # \u5f53: # - \u6570\u7ec4\u7684\u903b\u8f91\u5c3a\u5bf8\u5c0f\u4e8e\u6216\u7b49\u4e8e\u5176\u7269\u7406\u5c3a\u5bf8\u76841/4 # - \u5e76\u4e14\u5b83\u7684\u7269\u7406\u5c3a\u5bf8\u81f3\u5c11\u662f\u8fd9\u4e2a\u6570\u7ec4\u5efa\u7acb\u65f6\u9ed8\u8ba4\u5bb9\u91cf\u76842\u500d\u65f6 # \u5219\u628a\u6570\u7ec4\u7684\u7269\u7406\u5c3a\u5bf8\u51cf\u5c0f\u5230\u539f\u6765\u7684\u4e00\u534a\uff0c\u5e76\u4e14\u4e5f\u4e0d\u4f1a\u5c0f\u4e8e\u5176\u9ed8\u8ba4\u5bb9\u91cf if self . size () <= len ( self ) // 4 and len ( self ) > self . capacity : self . shrink () # \u8fd4\u56de\u88ab\u5220\u9664\u5143\u7d20\u7684\u503c print ( f 'Item { itemToReturn } was deleted' ) return itemToReturn","title":"4.2.4.\u4ece\u6570\u7ec4\u91cc\u5220\u9664\u5143\u7d20"},{"location":"python/DataStructure/04_ArrayChain/#425","text":"\u4e0b\u8868\u5217\u51fa\u4e86\u6240\u6709\u6570\u7ec4\u64cd\u4f5c\u7684\u8fd0\u884c\u65f6\u590d\u6742\u5ea6\uff0c\u5305\u62ec\u5728\u6570\u7ec4\u7684\u903b\u8f91\u7ed3\u5c3e\u5904\u63d2\u5165\u548c\u5220\u9664\u5143\u7d20\u3002 \u6570\u7ec4\u63d0\u4f9b\u4e86\u5bf9\u5df2\u7ecf\u5b58\u5728\u7684\u5143\u7d20\u8fdb\u884c\u5feb\u901f\u8bbf\u95ee\u7684\u529f\u80fd\uff0c\u4ee5\u53ca\u5728\u903b\u8f91\u7ed3\u5c3e\u5904\u5feb\u901f\u63d2\u5165\u548c\u5220\u9664\u7684\u529f\u80fd\u3002 \u5728\u4efb\u610f\u4f4d\u7f6e\u5904\u8fdb\u884c\u63d2\u5165\u548c\u5220\u9664\u64cd\u4f5c\u7684\u901f\u5ea6\u5219\u4f1a\u6162\u4e0a\u4e00\u4e2a\u6570\u91cf\u7ea7\u3002 \u8c03\u6574\u6570\u7ec4\u7684\u5c3a\u5bf8\u4e5f\u9700\u8981\u7ebf\u6027\u65f6\u95f4\uff0c\u4f46\u662f\u56e0\u4e3a\u8fd9\u4e2a\u64cd\u4f5c\u4f1a\u628a\u6570\u7ec4\u5c3a\u5bf8\u52a0\u500d\u6216\u51cf\u534a\uff0c\u6240\u4ee5\u53ef\u4ee5\u6700\u5927\u9650\u5ea6\u5730\u51cf\u5c11\u9700\u8981\u6267\u884c\u7684\u6b21\u6570\u3002 \u7531\u4e8e\u53ef\u80fd\u4f1a\u8c03\u6574\u6570\u7ec4\u7684\u5c3a\u5bf8\uff0c\u56e0\u6b64\u63d2\u5165\u548c\u5220\u9664\u64cd\u4f5c\u5728\u4f7f\u7528\u5185\u5b58\u7684\u65f6\u5019\u4f1a\u6709 O(n) \u7684\u590d\u6742\u5ea6\uff0c\u90a3\u4e48\u8fd9\u5c31\u662f\u6700\u574f\u60c5\u51b5\u4e0b\u7684\u6027\u80fd\uff1b\u800c\u5728\u5e73\u5747\u60c5\u51b5\u4e0b\uff0c\u8fd9\u4e9b\u64cd\u4f5c\u7684\u5185\u5b58\u4f7f\u7528\u60c5\u51b5\u4ecd\u7136\u4e3a O(1) \u3002 \u64cd\u4f5c \u8fd0\u884c\u65f6\u590d\u6742\u5ea6 \u5728\u4f4d\u7f6ei\u5904\u8bbf\u95ee O(1)\uff0c\u6700\u597d\u548c\u6700\u574f\u60c5\u51b5\u4e0b \u5728\u4f4d\u7f6ei\u5904\u66ff\u6362 O(1)\uff0c\u6700\u597d\u548c\u6700\u574f\u60c5\u51b5\u4e0b \u5728\u903b\u8f91\u7ed3\u5c3e\u5904\u63d2\u5165 O(1)\uff0c\u5e73\u5747\u60c5\u51b5\u4e0b \u5728\u4f4d\u7f6ei\u5904\u63d2\u5165 O(n)\uff0c\u5e73\u5747\u60c5\u51b5\u4e0b \u5728\u4f4d\u7f6ei\u5904\u5220\u9664 O(n)\uff0c\u5e73\u5747\u60c5\u51b5\u4e0b \u589e\u5927\u5bb9\u91cf O(n)\uff0c\u6700\u597d\u548c\u6700\u574f\u60c5\u51b5\u4e0b \u51cf\u5c0f\u5bb9\u91cf O(n)\uff0c\u6700\u597d\u548c\u6700\u574f\u60c5\u51b5\u4e0b \u5728\u903b\u8f91\u7ed3\u5c3e\u5904\u5220\u9664 O(1)\uff0c\u5e73\u5747\u60c5\u51b5\u4e0b \u4f7f\u7528\u6570\u7ec4\u7684\u65f6\u5019\uff0c\u5185\u5b58\u91cc\u552f\u4e00\u771f\u6b63\u88ab\u6d6a\u8d39\u7684\u662f\u90a3\u4e9b\u5c1a\u672a\u586b\u5145\u6ee1\u7684\u6570\u7ec4\u5355\u5143\u3002 \u8bc4\u4f30\u6570\u7ec4\u5185\u5b58\u4f7f\u7528\u7387\u7684\u4e00\u4e2a\u975e\u5e38\u6709\u7528\u7684\u6982\u5ff5\u662f\u8d1f\u8f7d\u56e0\u5b50\uff08load factor\uff09\u3002\u6570\u7ec4\u7684\u8d1f\u8f7d\u56e0\u5b50\u7b49\u540c\u4e8e\u5b83\u6240\u5b58\u50a8\u7684\u5143\u7d20\u6570\u9664\u4ee5\u6570\u7ec4\u7684\u5bb9\u91cf\u3002 \u5f53\u6570\u7ec4\u5df2\u6ee1\u7684\u65f6\u5019\uff0c\u8d1f\u8f7d\u56e0\u5b50\u5c31\u662f1\uff1b \u5f53\u6570\u7ec4\u4e3a\u7a7a\u65f6\uff0c\u8d1f\u8f7d\u56e0\u5b50\u5c31\u662f0\uff1b \u5f53\u5185\u5b58\u5355\u5143\u7684\u5bb9\u91cf\u4e3a10\u4e14\u5360\u7528\u4e863\u4e2a\u5355\u5143\u65f6\uff0c\u8d1f\u8f7d\u56e0\u5b50\u5c31\u662f0.3\uff1b \u5f53\u6570\u7ec4\u7684\u8d1f\u8f7d\u56e0\u5b50\u964d\u5230\u67d0\u4e2a\u9608\u503c\uff08\u59820.25\uff09\u4ee5\u4e0b\u65f6\uff0c\u53ef\u4ee5\u901a\u8fc7\u8c03\u6574\u6570\u7ec4\u5c3a\u5bf8\u5c06\u6d6a\u8d39\u7684\u5185\u5b58\u5355\u5143\u6570\u4fdd\u6301\u5728\u5c3d\u53ef\u80fd\u4f4e\u7684\u6c34\u5e73\uff1b","title":"4.2.5.\u590d\u6742\u5ea6\u7684\u6743\u8861\uff1a\u65f6\u95f4\u3001\u7a7a\u95f4\u548c\u6570\u7ec4"},{"location":"python/DataStructure/04_ArrayChain/#426","text":"1\uff0e\u8bf7\u8bf4\u660e\u4e3a\u4ec0\u4e48\u63d2\u5165\u6216\u5220\u9664\u7ed9\u5b9a\u5143\u7d20\u65f6\u5fc5\u987b\u8981\u79fb\u52a8\u6570\u7ec4\u91cc\u7684\u67d0\u4e9b\u5143\u7d20\u3002 \u89e3\u7b54\uff1a\u5728 Python \u4e2d\uff0c\u5217\u8868\uff08list\uff09\u662f\u57fa\u4e8e\u6570\u7ec4\u5b9e\u73b0\u7684\u6570\u636e\u7ed3\u6784\u3002\u6240\u8c13\u7684\u201c\u6570\u7ec4\u201d\uff0c\u5176\u672c\u8d28\u4e0a\u662f\u4e00\u5757\u8fde\u7eed\u7684\u5185\u5b58\u7a7a\u95f4\uff0c\u7531\u4e8e\u5176\u5185\u5b58\u8fde\u7eed\u7684\u7279\u6027\uff0c\u6570\u7ec4\u5728\u8fdb\u884c\u63d2\u5165\u6216\u8005\u5220\u9664\u4e00\u4e2a\u5143\u7d20\u65f6\uff0c\u4e3a\u4e86\u4fdd\u6301\u5185\u5b58\u7684\u8fde\u7eed\u6027\uff0c\u5f80\u5f80\u9700\u8981\u79fb\u52a8\u6570\u7ec4\u91cc\u7684\u5176\u5b83\u5143\u7d20\u3002 \u5f53\u5728\u6570\u7ec4\u7684\u4e2d\u95f4\u4f4d\u7f6e\u63d2\u5165\u4e00\u4e2a\u65b0\u7684\u5143\u7d20\u65f6\uff0c\u4e3a\u4e86\u7ed9\u65b0\u5143\u7d20\u817e\u51fa\u7a7a\u95f4\uff0c\u5b83\u540e\u9762\u7684\u6240\u6709\u5143\u7d20\u90fd\u9700\u8981\u5411\u540e\u79fb\u52a8\u4e00\u4f4d\u3002\u540c\u6837\u7684\uff0c\u5982\u679c\u6211\u4eec\u5220\u9664\u4e86\u6570\u7ec4\u7684\u4e00\u4e2a\u5143\u7d20\uff0c\u4e3a\u4e86\u907f\u514d\u5728\u6570\u7ec4\u4e2d\u51fa\u73b0\u4e00\u4e2a\u7a7a\u6d1e\uff0c\u88ab\u5220\u9664\u5143\u7d20\u540e\u9762\u7684\u6240\u6709\u5143\u7d20\u90fd\u9700\u8981\u5411\u524d\u79fb\u52a8\u4e00\u4f4d\u3002 \u7136\u800c\uff0cPython\u7684 list \u6570\u636e\u7ed3\u6784\u662f\u52a8\u6001\u7684\uff0c\u4e5f\u5c31\u662f\u8bf4\uff0c\u5f53\u63d2\u5165\u6216\u5220\u9664\u5143\u7d20\u65f6\uff0cPython\u4f1a\u81ea\u52a8\u5206\u914d\u6216\u56de\u6536\u5185\u5b58\u3002\u5f53\u5728 list \u7684\u672b\u5c3e\u6dfb\u52a0\u6216\u79fb\u9664\u5143\u7d20\u65f6\uff0c\u4e0d\u9700\u8981\u79fb\u52a8\u5176\u4ed6\u5143\u7d20\uff0c\u56e0\u6b64\u64cd\u4f5c\u6548\u7387\u8f83\u9ad8\uff1b\u4f46\u662f\u5728 list \u7684\u4e2d\u95f4\u6216\u8d77\u59cb\u90e8\u5206\u63d2\u5165\u6216\u5220\u9664\u5143\u7d20\u65f6\uff0c\u5c31\u9700\u8981\u79fb\u52a8\u5176\u5b83\u5143\u7d20\uff0c\u76f8\u5bf9\u800c\u8a00\uff0c\u5176\u64cd\u4f5c\u6548\u7387\u5c31\u8f83\u4f4e\u4e86\u3002 2\uff0e\u5728\u63d2\u5165\u8fc7\u7a0b\u4e2d\uff0c\u79fb\u52a8\u6570\u7ec4\u5143\u7d20\u65f6\uff0c\u8981\u5148\u79fb\u52a8\u54ea\u4e2a\u5143\u7d20\uff1f\u5148\u79fb\u52a8\u63d2\u5165\u4f4d\u7f6e\u7684\u5143\u7d20\uff0c\u8fd8\u662f\u6700\u540e\u4e00\u4e2a\u5143\u7d20\uff1f\u4e3a\u4ec0\u4e48\uff1f \u89e3\u7b54\uff1a\u5728 Python \u4e2d\u5b9e\u73b0\u6570\u7ec4\u7684\u63d2\u5165\u8fc7\u7a0b\u65f6\uff0c\u5e94\u5f53\u5148\u79fb\u52a8\u63d2\u5165\u4f4d\u7f6e\u4e4b\u540e\u7684\u6700\u540e\u4e00\u4e2a\u5143\u7d20\u3002 \u8003\u8651\u4ee5\u4e0b\u7684\u60c5\u51b5\uff1a\u503c\u63d2\u5165\u4e8e\u6570\u7ec4\u7684\u4e2d\u95f4\u4f4d\u7f6e\uff0c\u4f60\u8bd5\u56fe\u4ece\u63d2\u5165\u4f4d\u7f6e\u5f00\u59cb\uff0c\u5c06\u6bcf\u4e2a\u5143\u7d20\u540e\u79fb\u4e00\u4f4d\u3002\u4f46\u662f\uff0c\u5f53\u4f60\u628a\u7b2c\u4e00\u4e2a\u5143\u7d20\u79fb\u5230\u7b2c\u4e8c\u4e2a\u4f4d\u7f6e\u65f6\uff0c\u4f60\u4f1a\u8986\u76d6\u6389\u539f\u6709\u7684\u7b2c\u4e8c\u4e2a\u5143\u7d20\uff0c\u7531\u4e8e\u4f60\u8fd8\u6ca1\u6709\u4fdd\u5b58\u6216\u590d\u5236\u8fd9\u4e2a\u88ab\u8986\u76d6\u7684\u5143\u7d20\uff0c\u5b83\u5c31\u4f1a\u4e22\u5931\u3002 \u5982\u679c\u4ece\u6700\u540e\u4e00\u4e2a\u5143\u7d20\u5f00\u59cb\uff0c\u5c06\u6bcf\u4e2a\u5143\u7d20\u5411\u540e\u79fb\u4e00\u4f4d\uff0c\u90a3\u4e48\u6bcf\u4e2a\u5143\u7d20\u90fd\u4f1a\u88ab\u590d\u5236\u5230\u5b83\u7684\u4e0b\u4e00\u4f4d\uff0c\u7136\u540e\u624d\u4f1a\u88ab\u5b83\u524d\u9762\u7684\u5143\u7d20\u8986\u76d6\u3002\u8fd9\u6837\u5c31\u786e\u4fdd\u4e86\u6bcf\u4e2a\u5143\u7d20\u90fd\u80fd\u6b63\u786e\u5730\u79fb\u52a8\u5230\u5b83\u5e94\u8be5\u5230\u8fbe\u7684\u4f4d\u7f6e\uff0c\u4e0d\u4f1a\u6709\u4efb\u4f55\u5143\u7d20\u4e22\u5931\u3002 \u6240\u4ee5\uff0c\u5728\u63d2\u5165\u8fc7\u7a0b\u4e2d\uff0c\u6211\u4eec\u5e94\u8be5\u4ece\u6700\u540e\u4e00\u4e2a\u5143\u7d20\u5f00\u59cb\uff0c\u9010\u4e2a\u5c06\u5143\u7d20\u540e\u79fb\u4e00\u4f4d\uff0c\u76f4\u5230\u5c06\u63d2\u5165\u4f4d\u7f6e\u7684\u5143\u7d20\u4e5f\u540e\u79fb\u4e00\u4f4d\uff0c\u7136\u540e\u5728\u63d2\u5165\u4f4d\u7f6e\u653e\u5165\u65b0\u7684\u5143\u7d20\u3002 3\uff0e\u5982\u679c\u63d2\u5165\u4f4d\u7f6e\u662f\u6570\u7ec4\u7684\u903b\u8f91\u672b\u5c3e\uff0c\u8bf7\u8bf4\u660e\u8fd9\u4e2a\u63d2\u5165\u64cd\u4f5c\u7684\u8fd0\u884c\u65f6\u590d\u6742\u5ea6\u3002 \u89e3\u7b54\uff1a\u5982\u679c\u5728\u6570\u7ec4\uff08\u5728 Python \u4e2d\u5c31\u662f list\uff09\u7684\u903b\u8f91\u672b\u5c3e\u63d2\u5165\u5143\u7d20\uff0c\u8fd9\u79cd\u64cd\u4f5c\u901a\u5e38\u53ef\u4ee5\u5728\u5e38\u6570\u65f6\u95f4\u5185\u5b8c\u6210\uff0c\u4e5f\u5c31\u662f\u8bf4\uff0c\u8fd9\u79cd\u64cd\u4f5c\u7684\u65f6\u95f4\u590d\u6742\u5ea6\u662f O(1)\u3002 \u56e0\u4e3a\u6570\u7ec4\u662f\u8fde\u7eed\u7684\u5185\u5b58\u7a7a\u95f4\uff0c\u4f4d\u4e8e\u672b\u5c3e\u7684\u63d2\u5165\u64cd\u4f5c\u4e0d\u9700\u8981\u79fb\u52a8\u4efb\u4f55\u5143\u7d20\uff0c\u4ec5\u4ec5\u6d89\u53ca\u5728\u672b\u5c3e\u6dfb\u52a0\u65b0\u5143\u7d20\uff0c\u5e76\u53ef\u80fd\u6d89\u53ca\u4e00\u4e9b\u989d\u5916\u7684\u5185\u5b58\u5206\u914d\uff08\u5982\u679c\u6570\u7ec4\u5df2\u6ee1\uff0c\u9700\u8981\u5206\u914d\u66f4\u5927\u7684\u6570\u7ec4\u6765\u5bb9\u7eb3\u65b0\u7684\u5143\u7d20\uff09\u3002 \u9700\u8981\u6ce8\u610f\u7684\u662f\uff0c\u5185\u5b58\u5206\u914d\u548c\u590d\u5236\u5143\u7d20\u5728\u5b9e\u9645\u64cd\u4f5c\u4e2d\u53ef\u80fd\u8fd8\u662f\u9700\u8981\u4e00\u4e9b\u65f6\u95f4\u7684\uff0c\u5c24\u5176\u662f\u5728\u6570\u7ec4\u5df2\u6ee1\u65f6\uff0c\u9700\u8981\u91cd\u65b0\u5206\u914d\u5e76\u590d\u5236\u6574\u4e2a\u6570\u7ec4\u5230\u65b0\u7684\u5185\u5b58\u5730\u5740\u3002\u4f46\u662f\u5728\u7406\u8bba\u5206\u6790\u65f6\uff0c\u6211\u4eec\u901a\u5e38\u5ffd\u7565\u8fd9\u79cd\u60c5\u51b5\uff0c\u56e0\u4e3a\u5b83\u662f\u4e00\u79cd\u88ab\u79f0\u4e3a\u644a\u8fd8\uff08amortized\uff09\u64cd\u4f5c\u7684\u7279\u4f8b\uff0c\u4ece\u957f\u671f\u7684\u5e73\u5747\u8fd0\u884c\u65f6\u95f4\u6765\u770b\uff0c\u8fd9\u79cd\u63d2\u5165\u64cd\u4f5c\u7684\u65f6\u95f4\u590d\u6742\u5ea6\u4ecd\u7136\u662f O(1) \u7684\u3002 4\uff0e\u5047\u8bbe\u6570\u7ec4\u5f53\u524d\u5305\u542b14\u4e2a\u5143\u7d20\uff0c\u5b83\u7684\u8d1f\u8f7d\u56e0\u5b50\u4e3a0.70\uff0c\u90a3\u4e48\u5b83\u7684\u7269\u7406\u5bb9\u91cf\u662f\u591a\u5c11\uff1f \u89e3\u7b54\uff1a\u8d1f\u8f7d\u56e0\u5b50\u901a\u5e38\u662f\u6307\u4e00\u4e2a\u54c8\u5e0c\u8868\u4e2d\u5df2\u5b58\u5143\u7d20\u6570\u91cf\u5bf9\u5e94\u4e8e\u5176\u5e95\u5c42\u6570\u7ec4\u5bb9\u91cf\u7684\u6bd4\u4f8b\u3002\u5bf9\u4e8e\u4e00\u822c\u7684\u6570\u7ec4\u548c Python \u7684 list\uff0c\u6211\u4eec\u901a\u5e38\u4e0d\u4f1a\u8c08\u8bba\u8d1f\u8f7d\u56e0\u5b50\uff0c\u56e0\u4e3a\u8fd9\u4e9b\u6570\u636e\u7ed3\u6784\u7684\u5927\u5c0f\u76f4\u63a5\u5bf9\u5e94\u4e8e\u5176\u4e2d\u5305\u542b\u7684\u5143\u7d20\u6570\u91cf\u3002 \u7136\u800c\uff0c\u5982\u679c\u4f60\u8981\u8ba1\u7b97\u4e00\u4e2a\u8d1f\u8f7d\u56e0\u5b50\u4e3a 0.70 \u7684\u5bb9\u5668\uff0c\u5e76\u4e14\u5b83\u5305\u542b\u4e8614\u4e2a\u5143\u7d20\uff0c\u90a3\u4e48\u5b83\u7684\u7269\u7406\u5bb9\u91cf\u53ef\u4ee5\u8ba1\u7b97\u4e3a\uff1a \u5143\u7d20\u6570\u91cf / \u8d1f\u8f7d\u56e0\u5b50 = \u5bb9\u91cf \u5728\u8fd9\u79cd\u60c5\u51b5\u4e0b\uff0c\u7269\u7406\u5bb9\u91cf\u5e94\u8be5\u662f 14 / 0.70 = 20\u3002\u6240\u4ee5\u7269\u7406\u5bb9\u91cf\u5e94\u8be5\u662f 20\u3002","title":"4.2.6.\u7ec3\u4e60\u9898"},{"location":"python/DataStructure/04_ArrayChain/#43","text":"\u4e00\u7ef4\u6570\u7ec4\uff08one-dimensional array\uff09 \u4e8c\u7ef4\u6570\u7ec4\uff08two-dimensional array\uff09\uff0c\u6216\u7f51\u683c\uff08grid\uff09 \u8981\u8bbf\u95eegrid\u91cc\u7684\u5143\u7d20\uff0c\u53ef\u4ee5\u901a\u8fc7\u4e24\u4e2a\u4e0b\u6807\u6765\u6307\u5b9a\u5176\u884c\u548c\u5217\u7684\u76f8\u5e94\u4f4d\u7f6e\uff0c\u5e76\u4e14\u8fd9\u4e24\u4e2a\u7d22\u5f15\u90fd\u662f\u4ece0\u5f00\u59cb\u7684\u3002 x = grid [ 2 ][ 3 ] # \u5c06\u4e8c\u7ef4\u6570\u7ec4\u7b2c\u4e8c\u884c\u7b2c\u4e09\u5217\u7684\u503c\u8d4b\u7ed9\u53d8\u91cfx","title":"4.3.\u4e8c\u7ef4\u6570\u7ec4\uff08\u7f51\u683c\uff09"},{"location":"python/DataStructure/04_ArrayChain/#431","text":"\u9664\u4e86\u7528\u53cc\u4e0b\u6807\uff0c\u7f51\u683c\u8fd8\u5fc5\u987b\u8981\u6709\u4e24\u4e2a\u65b9\u6cd5\uff0c\u7528\u6765\u8fd4\u56de\u884c\u6570\u548c\u5217\u6570\u3002\u6211\u4eec\u628a\u8fd9\u4e24\u4e2a\u65b9\u6cd5\u5206\u522b\u547d\u540d\u4e3a getHeight \u548c getWidth \u3002 \u57fa\u4e8e4.3.3\u4e2d\u5b9a\u4e49\u7684Grid\u7c7b\uff0c\u4e0b\u9762\u8fd9\u6bb5\u4ee3\u7801\u4f1a\u5b9e\u4f8b\u5316\u4e00\u4e2a\u4e8c\u7ef4\u6570\u7ec4\uff0c\u5e76\u8ba1\u7b97\u53d8\u91cf my_grid \u91cc\u6240\u6709\u6570\u5b57\u7684\u603b\u548c\u3002\u5916\u90e8\u5faa\u73af\u4f1a\u8fed\u4ee35\u6b21\u5e76\u5411\u4e0b\u9010\u884c\u79fb\u52a8\uff0c\u5728\u6bcf\u6b21\u8fdb\u5165\u5916\u90e8\u5faa\u73af\u7684\u65f6\u5019\uff0c\u5185\u90e8\u5faa\u73af\u90fd\u4f1a\u8fed\u4ee35\u6b21\uff0c\u4ece\u800c\u5728\u4e0d\u540c\u884c\u7684\u5217\u4e4b\u95f4\u79fb\u52a8\u3002 my_grid = Grid ( 5 , 5 , 1 ) sum = 0 for row in range ( my_grid . getHeight ()): # Go through rows for column in range ( my_grid . getWidth ()): # Go through columns sum += my_grid [ row ][ column ]","title":"4.3.1.\u4f7f\u7528\u7f51\u683c"},{"location":"python/DataStructure/04_ArrayChain/#432","text":"\u57fa\u4e8e4.3.3\u4e2d\u5b9a\u4e49\u7684Grid\u7c7b\uff0c\u4e0b\u9762\u4ee3\u7801\u5b9e\u4f8b\u5316\u4e86\u4e00\u4e2a\u4e8c\u7ef4\u6570\u7ec4\uff0c\u904d\u5386\u8be5\u6570\u7ec4\u7684\u6bcf\u4e2a\u5143\u7d20\u5e76\u8d4b\u503c\u3002 my_grid = Grid ( 5 , 5 , 1 ) print ( my_grid ) # \u884c\u904d\u5386 for row in range ( my_grid . getHeight ()): # \u5217\u904d\u5386 for column in range ( my_grid . getWidth ()): my_grid [ row ][ column ] = int ( str ( row ) + str ( column ))","title":"4.3.2.\u521b\u5efa\u5e76\u521d\u59cb\u5316\u7f51\u683c"},{"location":"python/DataStructure/04_ArrayChain/#433grid","text":"\u4e0b\u9762\u5b9e\u73b0\u4e86\u4e00\u4e2a Grid \u5bf9\u8c61\uff0c\u5305\u542b3\u4e2a\u53c2\u6570\uff08\u9ad8\u5ea6\u3001\u5bbd\u5ea6\u4ee5\u53ca\u521d\u59cb\u7684\u586b\u5145\u503c\uff09\u7684 Grid \u6784\u9020\u51fd\u6570\u3002 \u9ad8\u5ea6\uff0c\u5373\u884c\u6570\uff1b\u5bbd\u5ea6\uff0c\u5373\u5217\u6570\uff1b \u5b9e\u4f8b\u5316\u4e86\u4e00\u4e2a5\u884c5\u5217\u7684\u4e8c\u7ef4\u6570\u7ec4\uff1b class Array ( object ): \"\"\"\u63cf\u8ff0\u4e00\u4e2a\u6570\u7ec4\u3002\"\"\" def __init__ ( self , capacity , fillValue = None ): \"\"\"Capacity\u662f\u6570\u7ec4\u7684\u5927\u5c0f. fillValue\u4f1a\u586b\u5145\u5728\u6bcf\u4e2a\u5143\u7d20\u4f4d\u7f6e, \u9ed8\u8ba4\u503c\u662fNone\"\"\" # \u521d\u59cb\u5316\u6570\u7ec4\u7684\u903b\u8f91\u5c3a\u5bf8\u548c\u7269\u7406\u5c3a\u5bf8 self . logicalSize = 0 self . capacity = capacity self . fillValue = fillValue #\u521d\u59cb\u5316\u5185\u90e8\u6570\u7ec4\uff0c\u5e76\u586b\u5145\u5143\u7d20\u503c self . items = list () for count in range ( capacity ): self . items . append ( fillValue ) self . logicalSize += 1 # \u521d\u59cb\u5316\u6570\u7ec4\u7269\u7406\u5927\u5c0f\u65f6\uff0c\u4e5f\u540c\u65f6\u521d\u59cb\u5316\u5176\u903b\u8f91\u5927\u5c0f def __len__ ( self ): \"\"\"\u8fd4\u56de\u6570\u7ec4\u7684\u5927\u5c0f\"\"\" return len ( self . items ) def __str__ ( self ): \"\"\"\u5c06\u6570\u7ec4\u5b57\u7b26\u4e32\u5316\u5e76\u8fd4\u56de\"\"\" result = \"\" for index in range ( self . size ()): result += str ( self . items [ index ]) + \" \" return result def size ( self ): \"\"\"\u8fd4\u56de\u6570\u7ec4\u7684\u903b\u8f91\u5c3a\u5bf8\"\"\" return self . logicalSize def __iter__ ( self ): \"\"\"\u652f\u6301for\u5faa\u73af\u5bf9\u6570\u7ec4\u8fdb\u884c\u904d\u5386.\"\"\" print ( \"__iter__ called\" ) # \u4ec5\u7528\u6765\u6d4b\u8bd5\u4f55\u65f6__iter__\u4f1a\u88ab\u8c03\u7528 return iter ( self . items ) def __getitem__ ( self , index ): \"\"\" \u7528\u4e8e\u8bbf\u95ee\u7d22\u5f15\u5904\u7684\u4e0b\u6807\u8fd0\u7b97\u7b26. \u5148\u51b3\u6761\u4ef6: 0 <= index < size() \"\"\" if index < 0 or index >= self . size (): raise IndexError ( \"\u8bfb\u53d6\u64cd\u4f5c\u51fa\u9519, \u6570\u7ec4\u7d22\u5f15\u8d8a\u754c(\u4e0d\u5728\u6570\u7ec4\u903b\u8f91\u8fb9\u754c\u8303\u56f4\u5185)\" ) return self . items [ index ] def __setitem__ ( self , index , newItem ): \"\"\" \u4e0b\u6807\u8fd0\u7b97\u7b26\u7528\u4e8e\u5728\u7d22\u5f15\u5904\u8fdb\u884c\u66ff\u6362. \u5148\u51b3\u6761\u4ef6: 0 <= index < size() \"\"\" if index < 0 or index >= self . size (): raise IndexError ( \"\u66f4\u65b0\u64cd\u4f5c\u51fa\u9519, \u6570\u7ec4\u7d22\u5f15\u8d8a\u754c(\u4e0d\u5728\u6570\u7ec4\u903b\u8f91\u8fb9\u754c\u8303\u56f4\u5185)\" ) self . items [ index ] = newItem def __eq__ ( self , other ): \"\"\" \u4e24\u4e2a\u6570\u7ec4\u76f8\u7b49\u5219\u8fd4\u56deTrue, \u5426\u5219\u8fd4\u56deFalse \"\"\" # \u5224\u65ad\u4e24\u4e2a\u6570\u7ec4\u662f\u5426\u662f\u540c\u4e00\u4e2a\u5bf9\u8c61\uff0c\u6ce8\u610f\uff0c\u4e0d\u662f\u5b83\u4eec\u7684\u503c\u662f\u5426\u76f8\u7b49 if self is other : return True # \u5224\u65ad\u4e24\u4e2a\u5bf9\u8c61\u7c7b\u578b\u662f\u5426\u4e00\u6837 if type ( self ) != type ( other ): return False # \u5224\u65ad\u4e24\u4e2a\u6570\u7ec4\u5927\u5c0f\u662f\u5426\u4e00\u6837 if self . size () != other . size (): return False # \u6bd4\u8f83\u4e24\u4e2a\u6570\u7ec4\u7684\u503c\u662f\u5426\u4e00\u6837 for index in range ( self . size ()): if self [ index ] != other [ index ]: return False return True def grow ( self ): \"\"\"\u589e\u5927\u6570\u7ec4\u7269\u7406\u5c3a\u5bf8\"\"\" # \u57fa\u4e8e\u5f53\u524d\u7269\u7406\u5c3a\u5bf8\u52a0\u500d\uff0c\u5e76\u5c06fillValue\u8d4b\u503c\u5e95\u5c42\u5217\u8868\u7684\u65b0\u5143\u7d20 for count in range ( len ( self )): self . items . append ( self . fillValue ) def insert ( self , index , newItem ): \"\"\"\u5728\u6570\u7ec4\u6307\u5b9a\u7d22\u5f15\u5904\u63d2\u5165\u65b0\u5143\u7d20\"\"\" # \u5f53\u6570\u7ec4\u7684\u7269\u7406\u5c3a\u5bf8\u548c\u903b\u8f91\u5c3a\u5bf8\u4e00\u6837\u65f6\uff0c\u5219\u589e\u52a0\u7269\u7406\u5c3a\u5bf8 if self . size () == len ( self ): self . grow () # \u63d2\u5165\u65b0\u5143\u7d20 # \u5f53\u63d2\u5165\u4f4d\u7f6e\u5927\u4e8e\u6216\u7b49\u4e8e\u6700\u5927\u903b\u8f91\u4f4d\u7f6e\uff0c\u5219\u5728\u6570\u7ec4\u672b\u7aef\u63d2\u5165\u65b0\u5143\u7d20 # \u5f53\u63d2\u5165\u4f4d\u7f6e\u4ecb\u4e8e\u6570\u7ec4\u903b\u8f91\u4f4d\u7f6e\u7684\u4e2d\u95f4\uff0c\u5219\u4ece\u63d2\u5165\u4f4d\u7f6e\u8d77\u5c06\u5269\u4f59\u6570\u7ec4\u5143\u7d20\u5411\u5c3e\u90e8\u5e73\u79fb\u4e00\u4e2a\u4f4d\u7f6e if index >= self . size (): self . items [ self . size ()] = newItem else : index = max ( index , 0 ) # \u5c06\u6570\u7ec4\u5143\u7d20\u5411\u5c3e\u90e8\u5e73\u79fb\u4e00\u4e2a\u4f4d\u7f6e for i in range ( self . size (), index , - 1 ): self . items [ i ] = self . items [ i - 1 ] # \u63d2\u5165\u65b0\u5143\u7d20 self . items [ index ] = newItem # \u589e\u52a0\u6570\u7ec4\u7684\u903b\u8f91\u5c3a\u5bf8 self . logicalSize += 1 def shrink ( self ): \"\"\" \u51cf\u5c11\u6570\u7ec4\u7684\u7269\u7406\u5c3a\u5bf8 \u5f53: - \u6570\u7ec4\u7684\u903b\u8f91\u5c3a\u5bf8\u5c0f\u4e8e\u6216\u7b49\u4e8e\u5176\u7269\u7406\u5c3a\u5bf8\u76841/4 - \u5e76\u4e14\u5b83\u7684\u7269\u7406\u5c3a\u5bf8\u81f3\u5c11\u662f\u8fd9\u4e2a\u6570\u7ec4\u5efa\u7acb\u65f6\u9ed8\u8ba4\u5bb9\u91cf\u76842\u500d\u65f6 \u5219\u628a\u6570\u7ec4\u7684\u7269\u7406\u5c3a\u5bf8\u51cf\u5c0f\u5230\u539f\u6765\u7684\u4e00\u534a\uff0c\u5e76\u4e14\u4e5f\u4e0d\u4f1a\u5c0f\u4e8e\u5176\u9ed8\u8ba4\u5bb9\u91cf \"\"\" # \u5728\u903b\u8f91\u5c3a\u5bf8\u548c\u7269\u7406\u5c3a\u5bf8\u7684\u4e00\u534a\u4e4b\u95f4\u9009\u62e9\u6700\u5927\u503c\u4f5c\u4e3a\u6570\u7ec4\u6536\u7f29\u540e\u7684\u7269\u7406\u5c3a\u5bf8 newSize = max ( self . capacity , len ( self ) // 2 ) # \u91ca\u653e\u591a\u4f59\u7684\u6570\u7ec4\u7a7a\u95f4 for count in range ( len ( self ) - newSize ): self . items . pop () def pop ( self , index ): \"\"\" \u5220\u9664\u6307\u5b9a\u7d22\u5f15\u503c\u7684\u6570\u7ec4\u5143\u7d20,\u5e76\u8fd4\u56de\u5220\u9664\u7684\u6570\u7ec4\u5143\u7d20\u503c \u5148\u51b3\u6761\u4ef6: 0 <= index < size() \"\"\" if index < 0 or index >= self . size (): raise IndexError ( \"\u5220\u9664\u64cd\u4f5c\u51fa\u9519, \u6570\u7ec4\u7d22\u5f15\u8d8a\u754c(\u4e0d\u5728\u6570\u7ec4\u903b\u8f91\u8fb9\u754c\u8303\u56f4\u5185)\" ) # \u4fdd\u5b58\u5373\u5c06\u88ab\u5220\u9664\u7684\u6570\u7ec4\u5143\u7d20\u503c itemToReturn = self . items [ index ] # \u5c06\u6570\u7ec4\u5143\u7d20\u5411\u5934\u90e8\u5e73\u79fb\u4e00\u4e2a\u4f4d\u7f6e for i in range ( index , self . size () - 1 ): self . items [ i ] = self . items [ i + 1 ] # \u5c06\u6570\u7ec4\u5c3e\u90e8\u7684\u7a7a\u4f59\u4f4d\u8d4b\u503cfillValue\uff0c\u9ed8\u8ba4\u662fNone self . items [ self . size () - 1 ] = self . fillValue # \u51cf\u5c11\u6570\u7ec4\u903b\u8f91\u5c3a\u5bf8 self . logicalSize -= 1 # \u51cf\u5c11\u6570\u7ec4\u7269\u7406\u5c3a\u5bf8 # \u5f53: # - \u6570\u7ec4\u7684\u903b\u8f91\u5c3a\u5bf8\u5c0f\u4e8e\u6216\u7b49\u4e8e\u5176\u7269\u7406\u5c3a\u5bf8\u76841/4 # - \u5e76\u4e14\u5b83\u7684\u7269\u7406\u5c3a\u5bf8\u81f3\u5c11\u662f\u8fd9\u4e2a\u6570\u7ec4\u5efa\u7acb\u65f6\u9ed8\u8ba4\u5bb9\u91cf\u76842\u500d\u65f6 # \u5219\u628a\u6570\u7ec4\u7684\u7269\u7406\u5c3a\u5bf8\u51cf\u5c0f\u5230\u539f\u6765\u7684\u4e00\u534a\uff0c\u5e76\u4e14\u4e5f\u4e0d\u4f1a\u5c0f\u4e8e\u5176\u9ed8\u8ba4\u5bb9\u91cf if self . size () <= len ( self ) // 4 and len ( self ) > self . capacity : self . shrink () # \u8fd4\u56de\u88ab\u5220\u9664\u5143\u7d20\u7684\u503c print ( f 'Item { itemToReturn } was deleted' ) return itemToReturn class Grid ( object ): \"\"\"\u63cf\u8ff0\u4e00\u4e2a\u4e8c\u7ef4\u6570\u7ec4\u3002\"\"\" def __init__ ( self , rows , columns , fillValue = None ): self . rows = rows self . columns = columns self . fillValue = fillValue # \u6309\u884c\u6570\u521d\u59cb\u5316\u6570\u7ec4y\u8f74\u7269\u7406\u5c3a\u5bf8 self . data = Array ( rows , fillValue ) # \u6309\u5217\u6570\u521d\u59cb\u5316\u6570\u7ec4x\u8f74\u7269\u7406\u5c3a\u5bf8\uff0c\u5e76\u8d4b\u503c\u5230y\u8f74\u6570\u7ec4\uff0c\u586b\u5145None\u503c for row in range ( rows ): self . data [ row ] = Array ( columns , fillValue ) def getHeight ( self ): \"\"\"\u8fd4\u56de\u4e8c\u7ef4\u6570\u7ec4\u7684y\u8f74\u7684\u5927\u5c0f(\u7269\u7406\u5c3a\u5bf8), \u5373\u6570\u7ec4\u7684\u884c\u6570\"\"\" return len ( self . data ) def getWidth ( self ): \"\"\"\u8fd4\u56de\u4e8c\u7ef4\u6570\u7ec4\u7684x\u8f74\u7684\u5927\u5c0f(\u7269\u7406\u5c3a\u5bf8), \u5373\u6570\u7ec4\u7684\u5217\u6570\"\"\" return len ( self . data [ 0 ]) def __getitem__ ( self , index ): \"\"\"\u8fd4\u56de\u4e8c\u7ef4\u6570\u7ec4\u6307\u5b9a\u884c\u548c\u5217\u7d22\u5f15\u5bf9\u5e94\u7684\u5143\u7d20\u503c\"\"\" return self . data [ index ] def __str__ ( self ): \"\"\"\u8fd4\u56de\u4e8c\u7ef4\u6570\u7ec4\u7684\u5b57\u7b26\u4e32\u5f62\u5f0f\"\"\" result = \"\" for row in range ( self . getHeight ()): for col in range ( self . getWidth ()): result += str ( self . data [ row ][ col ]) + \" \" result += \" \\n \" return result def main (): my_grid = Grid ( 5 , 5 , 1 ) print ( my_grid ) if __name__ == \"__main__\" : main () # \u8fd0\u884c\u7ed3\u679c # 1 1 1 1 1 # 1 1 1 1 1 # 1 1 1 1 1 # 1 1 1 1 1 # 1 1 1 1 1","title":"4.3.3.\u5b9a\u4e49Grid\u7c7b"},{"location":"python/DataStructure/04_ArrayChain/#434","text":"\u5230\u76ee\u524d\u4e3a\u6b62\uff0c\u6211\u4eec\u6240\u8ba8\u8bba\u7684\u7f51\u683c\u90fd\u662f\u4e8c\u7ef4\u5e76\u4e14\u662f\u77e9\u5f62\u7684\u3002\u6211\u4eec\u4e5f\u53ef\u4ee5\u628a\u7f51\u683c\u521b\u5efa\u6210\u53c2\u5dee\u4e0d\u9f50\u7684\u6837\u5b50\uff0c\u4e5f\u53ef\u4ee5\u521b\u5efa\u9ad8\u4e8e\u4e24\u4e2a\u7ef4\u5ea6\u7684\u7f51\u683c\u3002 \u53c2\u5dee\u4e0d\u9f50\u7684\u7f51\u683c\u6709\u56fa\u5b9a\u7684\u884c\u6570\uff0c\u4f46\u662f\u6bcf\u4e00\u884c\u91cc\u7684\u6570\u636e\u5217\u6570\u5404\u6709\u4e0d\u540c\u3002\u5217\u8868\u6570\u7ec4\u6216\u6570\u7ec4\u662f\u53ef\u4ee5\u5b9e\u73b0\u8fd9\u79cd\u7f51\u683c\u7684\u5408\u9002\u7ed3\u6784\u3002 \u6bd4\u5982\uff0c\u53ef\u4ee5\u521b\u5efa\u4e00\u4e2a\u4e09\u7ef4\u6570\u7ec4\u7684\u65f6\u5019\u9700\u8981\u6307\u5b9a\u5b83\u7684\u6df1\u5ea6\u3001\u9ad8\u5ea6\u4ee5\u53ca\u5bbd\u5ea6\u3002\u56e0\u6b64\u53ef\u4ee5\u7ed9\u6570\u7ec4\u7c7b\u578b\u6dfb\u52a0\u4e00\u4e2a\u53eb\u4f5c getDepth \u7684\u65b9\u6cd5\uff0c\u4ece\u800c\u50cf getWidth \u548c getHeight \u65b9\u6cd5\u4e00\u6837\u518d\u5f97\u5230\u8fd9\u4e2a\u7ef4\u5ea6\u7684\u76f8\u5173\u6570\u636e\u3002\u5728\u8fd9\u4e2a\u5b9e\u73b0\u91cc\uff0c\u6bcf\u4e2a\u5143\u7d20\u90fd\u53ef\u4ee5\u901a\u8fc73\u4e2a\u4f5c\u4e3a\u7d22\u5f15\u7684\u6574\u6570\u8fdb\u884c\u8bbf\u95ee\uff0c\u4e5f\u53ef\u4ee5\u901a\u8fc7\u67093\u5c42\u5faa\u73af\u7684\u63a7\u5236\u8bed\u53e5\u7ed3\u6784\u6765\u4f7f\u7528\u5b83\u3002","title":"4.3.4.\u53c2\u5dee\u4e0d\u9f50\u7684\u7f51\u683c\u548c\u591a\u7ef4\u6570\u7ec4"},{"location":"python/DataStructure/04_ArrayChain/#435","text":"1\uff0e\u4ec0\u4e48\u662f\u4e8c\u7ef4\u6570\u7ec4\uff08\u7f51\u683c\uff09\uff1f \u89e3\u7b54\uff1a\u4e8c\u7ef4\u6570\u7ec4\uff0c\u6709\u65f6\u88ab\u79f0\u4e3a\u7f51\u683c\uff0c\u662f\u4e00\u4e2a\u6570\u636e\u7ed3\u6784\uff0c\u5b83\u5141\u8bb8\u6211\u4eec\u5c06\u6570\u636e\u4ee5\u8868\u683c\u5f62\u5f0f\u7ec4\u7ec7\u8d77\u6765\uff0c\u5373\u6570\u636e\u5728\u4e24\u4e2a\u7ef4\u5ea6\u4e0a\u8fdb\u884c\u7ec4\u7ec7\u3002\u53ef\u4ee5\u628a\u4e8c\u7ef4\u6570\u7ec4\u770b\u4f5c\u662f\u4e00\u4e2a\u6570\u7ec4\u7684\u6570\u7ec4\u3002\u4f8b\u5982\uff0c\u5728 Python \u4e2d\uff0c\u4e00\u4e2a\u4e8c\u7ef4\u6570\u7ec4\u53ef\u4ee5\u662f\u4e00\u4e2a\u5217\u8868\u7684\u5217\u8868\u3002 \u5728\u4e8c\u7ef4\u6570\u7ec4\u4e2d\uff0c\u6bcf\u4e2a\u5143\u7d20\u90fd\u7531\u4e24\u4e2a\u7d22\u5f15\u786e\u5b9a\uff0c\u901a\u5e38\u79f0\u4e3a\u884c\u7d22\u5f15\u548c\u5217\u7d22\u5f15\u3002\u53ef\u4ee5\u8fd9\u6837\u7406\u89e3\uff1a\u9996\u5148\u9009\u5b9a\u4e00\u4e2a\u884c\uff0c\u7136\u540e\u518d\u5728\u8be5\u884c\u4e2d\u9009\u62e9\u4e00\u4e2a\u5143\u7d20\u3002\u7528\u4efb\u4f55\u4e00\u79cd\u7f16\u7a0b\u8bed\u8a00\u521b\u5efa\u548c\u64cd\u4f5c\u4e8c\u7ef4\u6570\u7ec4\u7684\u5177\u4f53\u8bed\u6cd5\u90fd\u4e0d\u5c3d\u76f8\u540c\uff0c\u4f46\u662f\u539f\u7406\u662f\u4e00\u6837\u7684\u3002 \u5728 Python \u4e2d\uff0c\u521b\u5efa\u4e8c\u7ef4\u6570\u7ec4\u7684\u4f8b\u5b50\u5982\u4e0b\uff1a # \u521b\u5efa\u4e00\u4e2a 3x3 \u7684\u4e8c\u7ef4\u6570\u7ec4 grid = [[ 1 , 2 , 3 ], [ 4 , 5 , 6 ], [ 7 , 8 , 9 ]] # \u8bbf\u95ee\u4e8c\u7ef4\u6570\u7ec4\u4e2d\u7279\u5b9a\u7684\u5143\u7d20 print ( grid [ 1 ][ 2 ]) # \u8f93\u51fa\uff1a6 2\uff0e\u8bf7\u63cf\u8ff0\u4e00\u4e2a\u53ef\u80fd\u4f1a\u7528\u5230\u4e8c\u7ef4\u6570\u7ec4\u7684\u5e94\u7528\u7a0b\u5e8f\u3002 \u89e3\u7b54\uff1a\u4e8c\u7ef4\u6570\u7ec4\u5728\u5404\u79cd\u7c7b\u578b\u7684\u5e94\u7528\u7a0b\u5e8f\u4e2d\u90fd\u88ab\u5e7f\u6cdb\u4f7f\u7528\u3002\u4e00\u4e2a\u5e38\u89c1\u7684\u4f8b\u5b50\u662f\u5728\u5904\u7406\u56fe\u50cf\u6216\u50cf\u7d20\u7684\u5e94\u7528\u4e2d\u3002 \u56fe\u50cf\u53ef\u4ee5\u88ab\u770b\u4f5c\u4e00\u4e2a\u4e8c\u7ef4\u6570\u7ec4\uff08\u6216\u8005\u5728\u5f69\u8272\u56fe\u50cf\u4e2d\uff0c\u662f\u4e00\u4e2a\u4e09\u7ef4\u6570\u7ec4\uff0c\u4e09\u4e2a\u901a\u9053\u5206\u522b\u662f\u7ea2\u3001\u7eff\u3001\u84dd\uff09\uff0c\u5176\u4e2d\u6bcf\u4e2a\u5143\u7d20\u8868\u793a\u4e00\u4e2a\u50cf\u7d20\u3002\u4e8c\u7ef4\u6570\u7ec4\u4e2d\u7684\u884c\u548c\u5217\u5bf9\u5e94\u4e8e\u56fe\u50cf\u7684\u5bbd\u5ea6\u548c\u9ad8\u5ea6\uff0c\u5143\u7d20\u503c\u901a\u5e38\u4ee3\u8868\u50cf\u7d20\u7684\u989c\u8272\u6df1\u5ea6\u3002 \u4f8b\u5982\uff0c\u4ee5\u4e0b Python \u4ee3\u7801\u521b\u5efa\u4e86\u4e00\u4e2a\u7b80\u5355\u7684\u7070\u5ea6\u56fe\u50cf\uff0c\u5e76\u4f7f\u7528 matplotlib \u5e93\u663e\u793a\u5b83\uff1a import numpy as np import matplotlib.pyplot as plt # \u521b\u5efa\u4e00\u4e2a 10x10 \u7684\u4e8c\u7ef4\u6570\u7ec4\uff0c\u6bcf\u4e2a\u5143\u7d20\u503c\u4e3a 0-255 \u4e4b\u95f4\u7684\u968f\u673a\u6574\u6570 image = np . random . randint ( 0 , 256 , ( 10 , 10 )) # \u663e\u793a\u8fd9\u4e2a\u56fe\u50cf plt . imshow ( image , cmap = 'gray' ) plt . show () \u5728\u8fd9\u4e2a\u4f8b\u5b50\u4e2d\uff0c\u6211\u4eec\u4f7f\u7528\u4e86 NumPy \u5e93\u6765\u521b\u5efa\u548c\u64cd\u4f5c\u4e8c\u7ef4\u6570\u7ec4\uff08\u5728 NumPy \u4e2d\uff0c\u8fd9\u79cd\u7ed3\u6784\u88ab\u79f0\u4e3a ndarray\uff09\u3002\u8fd9\u662f\u5904\u7406\u5927\u89c4\u6a21\u6570\u503c\u6570\u636e\u7684\u4e00\u4e2a\u975e\u5e38\u597d\u7684\u5de5\u5177\uff0c\u5c24\u5176\u662f\u5bf9\u4e8e\u6d89\u53ca\u5230\u79d1\u5b66\u8ba1\u7b97\u548c\u6570\u636e\u5206\u6790\u7684\u5e94\u7528\u7a0b\u5e8f\u3002 \u6b64\u5916\uff0c\u4e8c\u7ef4\u6570\u7ec4\u4e5f\u5e7f\u6cdb\u5e94\u7528\u4e8e\u6e38\u620f\u5f00\u53d1\uff08\u5982\u68cb\u76d8\u6e38\u620f\uff0c\u5982\u56fd\u9645\u8c61\u68cb\u6216\u4e95\u5b57\u6e38\u620f\u7684\u68cb\u76d8\u53ef\u4ee5\u7528\u4e8c\u7ef4\u6570\u7ec4\u6765\u8868\u793a\uff09\u3001\u7269\u7406\u6a21\u62df\u3001\u7cfb\u7edf\u52a8\u529b\u5b66\u6a21\u4eff\u3001\u5730\u7406\u4fe1\u606f\u7cfb\u7edf\uff08\u5730\u56fe\u53ef\u4ee5\u8868\u793a\u4e3a\u4e8c\u7ef4\u6570\u7ec4\u7684\u9ad8\u7a0b\u6570\u636e\uff09\u7b49\u8bb8\u591a\u9886\u57df\u3002 3\uff0e\u7f16\u5199\u4e00\u4e2a\u7a0b\u5e8f\uff0c\u4f7f\u4e4b\u53ef\u4ee5\u5728Grid\u5bf9\u8c61\u91cc\u641c\u7d22\u4e00\u4e2a\u8d1f\u6574\u6570\u3002\u5faa\u73af\u5e94\u8be5\u5728\u9047\u5230\u7f51\u683c\u91cc\u7684\u7b2c\u4e00\u4e2a\u8d1f\u6574\u6570\u7684\u5730\u65b9\u7ec8\u6b62\uff0c\u8fd9\u65f6\u53d8\u91cfrow\u548ccolumn\u5e94\u8be5\u88ab\u8bbe\u7f6e\u4e3a\u8fd9\u4e2a\u8d1f\u6570\u7684\u4f4d\u7f6e\u3002\u5982\u679c\u5728\u7f51\u683c\u91cc\u627e\u4e0d\u5230\u8d1f\u6570\uff0c\u90a3\u4e48\u53d8\u91cfrow\u548ccolumn\u5e94\u8be5\u7b49\u4e8e\u7f51\u683c\u7684\u884c\u6570\u548c\u5217\u6570\u3002 \u89e3\u7b54\uff1a\u5728Grid\u7c7b\u4e2d\u6dfb\u52a0\u4e0b\u9762\u7684\u65b9\u6cd5\uff0c\u53ef\u4ee5\u5b9e\u73b0\u63d0\u540d\u4e2d\u7684\u8981\u6c42 def find_negative ( self ): \"\"\"\u8fd4\u56de\u7b2c\u4e00\u4e2a\u8d1f\u6574\u6570\u7684\u7d22\u5f15\u503c\"\"\" target_row = 0 target_col = 0 for row in range ( self . getHeight ()): for col in range ( self . getWidth ()): # \u5982\u679c\u5f53\u524d\u5143\u7d20\u662f\u8d1f\u6570 if self . data [ row ][ col ] < 0 : # \u66f4\u65b0 row \u548c column \u4e3a\u8be5\u5143\u7d20\u7684\u4f4d\u7f6e target_row = row target_col = col # \u7ec8\u6b62\u5faa\u73af break # \u5982\u679c\u5df2\u627e\u5230\u8d1f\u6570\uff0c\u7ec8\u6b62\u5916\u5c42\u5faa\u73af if self . data [ row ][ col ] < 0 : break # \u8fd4\u56de\u8d1f\u6570\u7684\u4f4d\u7f6e\uff0c\u6216\u8005\u5982\u679c\u6ca1\u6709\u627e\u5230\u8d1f\u6570\uff0c\u8fd4\u56de\u884c\u6570\u548c\u5217\u6570 return row , col import random def main (): my_grid = Grid ( 5 , 5 , random . randint ( - 10 , 10 )) print ( my_grid ) print ( my_grid . find_negative ()) 4\uff0e\u8bf4\u8bf4\u8fd0\u884c\u4e0b\u9762\u8fd9\u6bb5\u4ee3\u7801\u540e\u7f51\u683c\u91cc\u7684\u5185\u5bb9\u662f\u4ec0\u4e48\u3002 matrix = Grid ( 3 , 3 ) for row in range ( matrix . getHeight ()): for column in range ( matrix . getWidth ()): matrix [ row ][ column ] = row * column \u89e3\u7b54\uff1a\u8fd9\u6bb5\u4ee3\u7801\u9996\u5148\u521b\u5efa\u4e86\u4e00\u4e2a3x3\u7684\u7f51\u683c\uff08\u6216\u4e8c\u7ef4\u6570\u7ec4\uff09\uff0c\u7136\u540e\u4f7f\u7528\u4e24\u4e2a\u5d4c\u5957\u7684for\u5faa\u73af\u6765\u904d\u5386\u8fd9\u4e2a\u7f51\u683c\u7684\u6bcf\u4e00\u4e2a\u5143\u7d20\u3002\u5bf9\u4e8e\u7f51\u683c\u4e2d\u7684\u6bcf\u4e00\u4e2a\u5143\u7d20\uff0c\u5b83\u7684\u503c\u88ab\u8bbe\u7f6e\u4e3a\u5176\u884c\u7d22\u5f15\u4e58\u4ee5\u5217\u7d22\u5f15\u3002\u7531\u4e8e\u7b2c\u4e00\u884c\u548c\u7b2c\u4e00\u5217\u7684\u7d22\u5f15\u90fd\u662f0\uff0c\u6240\u4ee5\u7b2c\u4e00\u884c\u548c\u7b2c\u4e00\u5217\u7684\u5143\u7d20\u503c\u90fd\u662f0\uff08\u56e0\u4e3a\u4efb\u4f55\u6570\u4e58\u4ee50\u90fd\u7b49\u4e8e0\uff09\u3002\u5176\u5b83\u5143\u7d20\u7684\u503c\u7b49\u4e8e\u5b83\u4eec\u7684\u884c\u7d22\u5f15\u4e58\u4ee5\u5217\u7d22\u5f15\u3002 0 0 0 0 1 2 0 2 4 5\uff0e\u7f16\u5199\u4e00\u6bb5\u4ee3\u7801\u4ee5\u521b\u5efa\u4e00\u4e2a\u53c2\u5dee\u4e0d\u9f50\u7684\u7f51\u683c\uff0c\u5b83\u7684\u884c\u5206\u522b\u7528\u6765\u5b58\u50a83\u4e2a\u30016\u4e2a\u548c9\u4e2a\u5143\u7d20\u3002 \u89e3\u7b54\uff1a\u4f7f\u7528\u5217\u8868\u7684\u5217\u8868\uff08\u5373\u5217\u8868\u7684\u5d4c\u5957\uff09\u6765\u521b\u5efa\u53c2\u5dee\u4e0d\u9f50\u7684\u7f51\u683c\u3002\u4e0b\u9762\u662fPython\u5b9e\u73b0\u4ee3\u7801\uff1a # \u521b\u5efa\u7a7a\u7f51\u683c grid = [] # \u4e3a\u7f51\u683c\u6dfb\u52a0\u884c grid . append ([ \"\" ] * 3 ) # \u7b2c\u4e00\u884c3\u4e2a\u5143\u7d20 grid . append ([ \"\" ] * 6 ) # \u7b2c\u4e8c\u884c6\u4e2a\u5143\u7d20 grid . append ([ \"\" ] * 9 ) # \u7b2c\u4e09\u884c9\u4e2a\u5143\u7d20 # \u6253\u5370\u7f51\u683c for row in grid : print ( row ) \u4e0a\u9762\u4ee3\u7801\u521b\u5efa\u4e00\u4e2a\u5177\u6709\u4e09\u884c\u7684\u7f51\u683c\uff0c\u5176\u4e2d\u7b2c\u4e00\u884c\u6709\u4e09\u4e2a\u5143\u7d20\uff0c\u7b2c\u4e8c\u884c\u6709\u516d\u4e2a\u5143\u7d20\uff0c\u7b2c\u4e09\u884c\u6709\u4e5d\u4e2a\u5143\u7d20\u3002\u6bcf\u4e2a\u5143\u7d20\u6700\u521d\u90fd\u88ab\u8bbe\u7f6e\u4e3a\u4e00\u4e2a\u7a7a\u5b57\u7b26\u4e32\uff0c\u8fd9\u4e2a\u7f51\u683c\u7684\u5f62\u72b6\u5c06\u7c7b\u4f3c\u4e8e\uff1a [ '' , '' , '' ] [ '' , '' , '' , '' , '' , '' ] [ '' , '' , '' , '' , '' , '' , '' , '' , '' ] 6\uff0e\u63d0\u4f9b\u4e00\u4e2a\u628aGrid\u7c7b\u7528\u4f5c\u6570\u636e\u7ed3\u6784\u6765\u5b9e\u73b0\u4e09\u7ef4array\u7c7b\u7684\u7b56\u7565\u3002 \u89e3\u7b54\uff1a\u4ee3\u7801\u5b9e\u73b0\u5982\u4e0b\uff1a class ThreeDArray ( object ): \"\"\"\u63cf\u8ff0\u4e00\u4e2a\u4e09\u7ef4\u6570\u7ec4\u3002\"\"\" def __init__ ( self , depth , rows , columns , fillValue = None ): self . depth = depth self . rows = rows self . columns = columns self . fillValue = fillValue # \u521d\u59cb\u5316\u4e09\u7ef4\u6570\u7ec4\uff0c\u6309\u7167\u6df1\u5ea6\u521d\u59cb\u5316\u6bcf\u4e00\u5c42\u4e3a\u4e00\u4e2a\u4e8c\u7ef4\u6570\u7ec4 self . data = Array ( depth , fillValue ) for d in range ( depth ): self . data [ d ] = Grid ( rows , columns , fillValue ) def getDepth ( self ): \"\"\"\u8fd4\u56de\u4e09\u7ef4\u6570\u7ec4\u7684z\u8f74\u5927\u5c0f, \u5373\u6570\u7ec4\u7684\u6df1\u5ea6\"\"\" return len ( self . data ) def get_element ( self , depth , row , column ): \"\"\"\u83b7\u53d6\u6307\u5b9a\u6df1\u5ea6\u3001\u884c\u548c\u5217\u7684\u5143\u7d20\"\"\" return self . data [ depth ][ row ][ column ] def set_element ( self , depth , row , column , new_value ): \"\"\"\u8bbe\u7f6e\u6307\u5b9a\u6df1\u5ea6\u3001\u884c\u548c\u5217\u7684\u5143\u7d20\"\"\" self . data [ depth ][ row ][ column ] = new_value def add_element ( self , depth , row , column , value ): \"\"\"\u5728\u6307\u5b9a\u6df1\u5ea6\u3001\u884c\u548c\u5217\u6dfb\u52a0\u5143\u7d20 \"\"\" if self . data [ depth ][ row ][ column ] == self . fillValue : self . data [ depth ][ row ][ column ] = value else : raise Exception ( \"\u5143\u7d20\u6dfb\u52a0\u5931\u8d25\" ) def remove_element ( self , depth , row , column ): \"\"\"\u5728\u6307\u5b9a\u6df1\u5ea6\u3001\u884c\u548c\u5217\u5220\u9664\u5143\u7d20 \"\"\" if self . data [ depth ][ row ][ column ] != self . fillValue : self . data [ depth ][ row ][ column ] = self . fillValue else : raise Exception ( \"\u5143\u7d20\u5220\u9664\u5931\u8d25\" ) def __str__ ( self ): result = \"\" for depth in range ( self . getDepth ()): result += f \"Depth { depth } : \\n \" for row in range ( self . rows ): for column in range ( self . columns ): result += str ( self . data [ depth ][ row ][ column ]) + \" \\t \" result += \" \\n \" return result def main (): print ( \"---Initial 3D Array---\" ) my_3d = ThreeDArray ( 3 , 2 , 2 , 9 ) print ( my_3d ) print ( \"---Add element into 3D Array---\" ) my_3d . add_element ( 0 , 1 , 1 , 0 ) my_3d . add_element ( 1 , 1 , 1 , 1 ) my_3d . add_element ( 2 , 1 , 1 , 2 ) print ( my_3d ) print ( \"---Remove element from 3D Array---\" ) my_3d . remove_element ( 1 , 1 , 1 ) print ( my_3d ) if __name__ == \"__main__\" : main () # \u8fd0\u884c\u7ed3\u679c # ---Initial 3D Array--- # Depth 0: # 9 9 # 9 9 # Depth 1: # 9 9 # 9 9 # Depth 2: # 9 9 # 9 9 # ---Add element into 3D Array--- # Depth 0: # 9 9 # 9 0 # Depth 1: # 9 9 # 9 1 # Depth 2: # 9 9 # 9 2 # ---Remove element from 3D Array--- # Depth 0: # 9 9 # 9 0 # Depth 1: # 9 9 # 9 9 # Depth 2: # 9 9 # 9 2 7\uff0e\u7f16\u5199\u4e00\u6bb5\u4ee3\u7801\uff1a\u8fd9\u6bb5\u4ee3\u7801\u4f1a\u628a\u4e09\u7ef4\u6570\u7ec4\u91cc\u6bcf\u4e2a\u5355\u5143\u7684\u503c\u90fd\u521d\u59cb\u5316\u4e3a\u5b83\u76843\u4e2a\u7d22\u5f15\u4f4d\u7f6e\u3002\u4f8b\u5982\uff0c\u5982\u679c\u4f4d\u7f6e\u662f\uff08\u6df1\u5ea6\u3001\u884c\u3001\u5217\uff09\uff0c\u5219\u5bf9\u4e8e\u4f4d\u7f6e\uff082\u30013\u30013\uff09\u6765\u8bf4\uff0c\u5b83\u7684\u503c\u5c31\u662f233\u3002 \u89e3\u7b54\uff1a\u4fee\u6539\u4e0a\u9762\u7684\u4ee3\u7801\u4e2d\u7684 __init__ \u548c __str__ \u65b9\u6cd5\uff0c\u4ee3\u7801\u5b9e\u73b0\u5982\u4e0b\u3002 class ThreeDArray ( object ): \"\"\"\u63cf\u8ff0\u4e00\u4e2a\u4e09\u7ef4\u6570\u7ec4\u3002\"\"\" # def __init__(self, depth, rows, columns, fillValue=None): # self.depth = depth # self.rows = rows # self.columns = columns # self.fillValue = fillValue # # \u521d\u59cb\u5316\u4e09\u7ef4\u6570\u7ec4\uff0c\u6309\u7167\u6df1\u5ea6\u521d\u59cb\u5316\u6bcf\u4e00\u5c42\u4e3a\u4e00\u4e2a\u4e8c\u7ef4\u6570\u7ec4 # self.data = Array(depth, fillValue) # for d in range(depth): # self.data[d] = Grid(rows, columns, fillValue) def __init__ ( self , depth , rows , columns ): self . depth = depth self . rows = rows self . columns = columns # \u521d\u59cb\u5316\u4e09\u7ef4\u6570\u7ec4\uff0c\u6309\u7167\u6df1\u5ea6\u521d\u59cb\u5316\u6bcf\u4e00\u5c42\u4e3a\u4e00\u4e2a\u4e8c\u7ef4\u6570\u7ec4 self . data = Array ( depth ) for d in range ( depth ): self . data [ d ] = Grid ( rows , columns ) for r in range ( rows ): for c in range ( columns ): # \u5c06\u6bcf\u4e2a\u4f4d\u7f6e\u7684\u7d22\u5f15\u62fc\u63a5\u6210\u5b57\u7b26\u4e32\u4f5c\u4e3a\u5143\u7d20\u503c self . data [ d ][ r ][ c ] = str ( d ) + str ( r ) + str ( c ) def getDepth ( self ): \"\"\"\u8fd4\u56de\u4e09\u7ef4\u6570\u7ec4\u7684z\u8f74\u5927\u5c0f, \u5373\u6570\u7ec4\u7684\u6df1\u5ea6\"\"\" return len ( self . data ) def get_element ( self , depth , row , column ): \"\"\"\u83b7\u53d6\u6307\u5b9a\u6df1\u5ea6\u3001\u884c\u548c\u5217\u7684\u5143\u7d20\"\"\" return self . data [ depth ][ row ][ column ] def set_element ( self , depth , row , column , new_value ): \"\"\"\u8bbe\u7f6e\u6307\u5b9a\u6df1\u5ea6\u3001\u884c\u548c\u5217\u7684\u5143\u7d20\"\"\" self . data [ depth ][ row ][ column ] = new_value def add_element ( self , depth , row , column , value ): \"\"\"\u5728\u6307\u5b9a\u6df1\u5ea6\u3001\u884c\u548c\u5217\u6dfb\u52a0\u5143\u7d20 \"\"\" if self . data [ depth ][ row ][ column ] == self . fillValue : self . data [ depth ][ row ][ column ] = value else : raise Exception ( \"\u5143\u7d20\u6dfb\u52a0\u5931\u8d25\" ) def remove_element ( self , depth , row , column ): \"\"\"\u5728\u6307\u5b9a\u6df1\u5ea6\u3001\u884c\u548c\u5217\u5220\u9664\u5143\u7d20 \"\"\" if self . data [ depth ][ row ][ column ] != self . fillValue : self . data [ depth ][ row ][ column ] = self . fillValue else : raise Exception ( \"\u5143\u7d20\u5220\u9664\u5931\u8d25\" ) # def __str__(self): # result = \"\" # for depth in range(self.getDepth()): # result += f\"Depth {depth}:\\n\" # for row in range(self.rows): # for column in range(self.columns): # result += str(self.data[depth][row][column]) + \"\\t\" # result += \"\\n\" # return result def __str__ ( self ): result = \"\" for depth in range ( self . getDepth ()): result += f \"Depth { depth } : \\n \" for row in range ( self . rows ): for column in range ( self . columns ): result += str ( self . data [ depth ][ row ][ column ]) + \" \\t \" result += \" \\n \" return result def main (): my_3d = ThreeDArray ( 3 , 4 , 4 ) print ( my_3d ) # \u6253\u5370\u521d\u59cb\u72b6\u6001 if __name__ == \"__main__\" : main () # \u8fd0\u884c\u7ed3\u679c # Depth 0: # 000 001 002 003 # 010 011 012 013 # 020 021 022 023 # 030 031 032 033 # Depth 1: # 100 101 102 103 # 110 111 112 113 # 120 121 122 123 # 130 131 132 133 # Depth 2: # 200 201 202 203 # 210 211 212 213 # 220 221 222 223 # 230 231 232 233 8\uff0e\u7f16\u5199\u4e00\u6bb5\u4ee3\u7801\uff1a\u8fd9\u6bb5\u4ee3\u7801\u53ef\u4ee5\u663e\u793a\u51fa\u4e09\u7ef4\u6570\u7ec4\u91cc\u7684\u6240\u6709\u5143\u7d20\u3002\u6253\u5370\u51fa\u7684\u6bcf\u4e00\u884c\u6570\u636e\u90fd\u5e94\u8be5\u4ee3\u8868\u7ed9\u5b9a\u884c\u548c\u5217\u91cc\u7684\u6240\u6709\u5143\u7d20\uff0c\u800c\u6df1\u5ea6\u5c06\u4ece\u7b2c\u4e00\u4e2a\u4f4d\u7f6e\u5411\u540e\u9012\u5f52\u5230\u6700\u540e\u4e00\u4e2a\u4f4d\u7f6e\u3002\u904d\u5386\u5e94\u8be5\u4ece\u7b2c1\u884c\u3001\u7b2c1\u5217\u4ee5\u53ca\u7b2c\u4e00\u4e2a\u6df1\u5ea6\u4f4d\u7f6e\u5f00\u59cb\uff0c\u4f9d\u6b21\u904d\u5386\u6240\u6709\u7684\u6df1\u5ea6\u3001\u5217\u548c\u884c\u3002 \u89e3\u7b54\uff1a\u6dfb\u52a0\u4e86\u4e00\u4e2a\u65b9\u6cd5 printAllElements \uff0c\u4ee3\u7801\u5b9e\u73b0\u5982\u4e0b\uff1a class ThreeDArray ( object ): \"\"\"\u63cf\u8ff0\u4e00\u4e2a\u4e09\u7ef4\u6570\u7ec4\u3002\"\"\" # def __init__(self, depth, rows, columns, fillValue=None): # self.depth = depth # self.rows = rows # self.columns = columns # self.fillValue = fillValue # # \u521d\u59cb\u5316\u4e09\u7ef4\u6570\u7ec4\uff0c\u6309\u7167\u6df1\u5ea6\u521d\u59cb\u5316\u6bcf\u4e00\u5c42\u4e3a\u4e00\u4e2a\u4e8c\u7ef4\u6570\u7ec4 # self.data = Array(depth, fillValue) # for d in range(depth): # self.data[d] = Grid(rows, columns, fillValue) def __init__ ( self , depth , rows , columns ): self . depth = depth self . rows = rows self . columns = columns # \u521d\u59cb\u5316\u4e09\u7ef4\u6570\u7ec4\uff0c\u6309\u7167\u6df1\u5ea6\u521d\u59cb\u5316\u6bcf\u4e00\u5c42\u4e3a\u4e00\u4e2a\u4e8c\u7ef4\u6570\u7ec4 self . data = Array ( depth ) for d in range ( depth ): self . data [ d ] = Grid ( rows , columns ) for r in range ( rows ): for c in range ( columns ): # \u5c06\u6bcf\u4e2a\u4f4d\u7f6e\u7684\u7d22\u5f15\u62fc\u63a5\u6210\u5b57\u7b26\u4e32\u4f5c\u4e3a\u5143\u7d20\u503c self . data [ d ][ r ][ c ] = str ( d ) + str ( r ) + str ( c ) def getDepth ( self ): \"\"\"\u8fd4\u56de\u4e09\u7ef4\u6570\u7ec4\u7684z\u8f74\u5927\u5c0f, \u5373\u6570\u7ec4\u7684\u6df1\u5ea6\"\"\" return len ( self . data ) def get_element ( self , depth , row , column ): \"\"\"\u83b7\u53d6\u6307\u5b9a\u6df1\u5ea6\u3001\u884c\u548c\u5217\u7684\u5143\u7d20\"\"\" return self . data [ depth ][ row ][ column ] def set_element ( self , depth , row , column , new_value ): \"\"\"\u8bbe\u7f6e\u6307\u5b9a\u6df1\u5ea6\u3001\u884c\u548c\u5217\u7684\u5143\u7d20\"\"\" self . data [ depth ][ row ][ column ] = new_value def add_element ( self , depth , row , column , value ): \"\"\"\u5728\u6307\u5b9a\u6df1\u5ea6\u3001\u884c\u548c\u5217\u6dfb\u52a0\u5143\u7d20 \"\"\" if self . data [ depth ][ row ][ column ] == self . fillValue : self . data [ depth ][ row ][ column ] = value else : raise Exception ( \"\u5143\u7d20\u6dfb\u52a0\u5931\u8d25\" ) def remove_element ( self , depth , row , column ): \"\"\"\u5728\u6307\u5b9a\u6df1\u5ea6\u3001\u884c\u548c\u5217\u5220\u9664\u5143\u7d20 \"\"\" if self . data [ depth ][ row ][ column ] != self . fillValue : self . data [ depth ][ row ][ column ] = self . fillValue else : raise Exception ( \"\u5143\u7d20\u5220\u9664\u5931\u8d25\" ) def printAllElements ( self ): \"\"\"\u6253\u5370\u4e09\u7ef4\u6570\u7ec4\u4e2d\u7684\u6240\u6709\u5143\u7d20\u3002\"\"\" for row in range ( self . rows ): for col in range ( self . columns ): for depth in range ( self . depth ): print ( f \"Element at position ( { row } , { col } , { depth } ): { self . data [ depth ][ row ][ col ] } \" ) # def __str__(self): # result = \"\" # for depth in range(self.getDepth()): # result += f\"Depth {depth}:\\n\" # for row in range(self.rows): # for column in range(self.columns): # result += str(self.data[depth][row][column]) + \"\\t\" # result += \"\\n\" # return result def __str__ ( self ): result = \"\" for depth in range ( self . getDepth ()): result += f \"Depth { depth } : \\n \" for row in range ( self . rows ): for column in range ( self . columns ): result += str ( self . data [ depth ][ row ][ column ]) + \" \\t \" result += \" \\n \" return result def main (): my_3d = ThreeDArray ( 3 , 4 , 4 ) print ( my_3d ) # \u6253\u5370\u521d\u59cb\u72b6\u6001 my_3d . printAllElements () if __name__ == \"__main__\" : main () # \u8fd0\u884c\u7ed3\u679c # Depth 0: # 000 001 002 003 # 010 011 012 013 # 020 021 022 023 # 030 031 032 033 # Depth 1: # 100 101 102 103 # 110 111 112 113 # 120 121 122 123 # 130 131 132 133 # Depth 2: # 200 201 202 203 # 210 211 212 213 # 220 221 222 223 # 230 231 232 233 # Element at position (0, 0, 0): 000 # Element at position (0, 0, 1): 100 # Element at position (0, 0, 2): 200 # Element at position (0, 1, 0): 001 # Element at position (0, 1, 1): 101 # Element at position (0, 1, 2): 201 # Element at position (0, 2, 0): 002 # Element at position (0, 2, 1): 102 # Element at position (0, 2, 2): 202 # Element at position (0, 3, 0): 003 # Element at position (0, 3, 1): 103 # Element at position (0, 3, 2): 203 # Element at position (1, 0, 0): 010 # Element at position (1, 0, 1): 110 # Element at position (1, 0, 2): 210 # Element at position (1, 1, 0): 011 # Element at position (1, 1, 1): 111 # Element at position (1, 1, 2): 211 # Element at position (1, 2, 0): 012 # Element at position (1, 2, 1): 112 # Element at position (1, 2, 2): 212 # Element at position (1, 3, 0): 013 # Element at position (1, 3, 1): 113 # Element at position (1, 3, 2): 213 # Element at position (2, 0, 0): 020 # Element at position (2, 0, 1): 120 # Element at position (2, 0, 2): 220 # Element at position (2, 1, 0): 021 # Element at position (2, 1, 1): 121 # Element at position (2, 1, 2): 221 # Element at position (2, 2, 0): 022 # Element at position (2, 2, 1): 122 # Element at position (2, 2, 2): 222 # Element at position (2, 3, 0): 023 # Element at position (2, 3, 1): 123 # Element at position (2, 3, 2): 223 # Element at position (3, 0, 0): 030 # Element at position (3, 0, 1): 130 # Element at position (3, 0, 2): 230 # Element at position (3, 1, 0): 031 # Element at position (3, 1, 1): 131 # Element at position (3, 1, 2): 231 # Element at position (3, 2, 0): 032 # Element at position (3, 2, 1): 132 # Element at position (3, 2, 2): 232 # Element at position (3, 3, 0): 033 # Element at position (3, 3, 1): 133 # Element at position (3, 3, 2): 233","title":"4.3.5.\u7ec3\u4e60\u9898"},{"location":"python/DataStructure/04_ArrayChain/#44","text":"\u94fe\u63a5\u7ed3\u6784\u4f5c\u4e3a\u4e00\u79cd\u6570\u636e\u7c7b\u578b\uff0c\u53ef\u4ee5\u7528\u6765\u5b9e\u73b0\u82e5\u5e72\u7c7b\u578b\u7684\u591a\u9879\u96c6\uff08\u5305\u62ec\u5217\u8868\uff09\u3002 \u76ee\u6807\uff1a\u5728\u4f7f\u7528\u94fe\u63a5\u7ed3\u6784\u5b9e\u73b0\u4efb\u4f55\u7c7b\u578b\u7684\u591a\u9879\u96c6\u65f6\u6240\u5fc5\u987b\u8981\u77e5\u9053\u7684\u51e0\u4e2a\u7279\u5f81\uff0c\u4ee5\u53ca\u5982\u4f55\u5728\u591a\u9879\u96c6\uff08\u5982\u5217\u8868\u548c\u4e8c\u53c9\u6811\uff09\u91cc\u4f7f\u7528\u94fe\u63a5\u7ed3\u6784\u3002","title":"4.4.\u94fe\u63a5\u7ed3\u6784"},{"location":"python/DataStructure/04_ArrayChain/#441","text":"\u94fe\u63a5\u7ed3\u6784\u7531\u53ef\u4ee5\u94fe\u63a5\u5230\u5176\u4ed6\u8282\u70b9\u7684\u8282\u70b9\u7ec4\u6210\u3002 \u8282\u70b9\u4e4b\u95f4\u6700\u7b80\u5355\u7684\u94fe\u63a5\u7ed3\u6784\u662f\uff1a \u5355\u5411\u94fe\u63a5\u7ed3\u6784\uff08singly linked structure\uff09 \u53cc\u5411\u94fe\u63a5\u7ed3\u6784\uff08doubly linked structure\uff09 \u4e0b\u9762\u56fe\u4f8b\u662f\u7528\u6846\u548c\u6307\u9488\u7b26\u53f7\u7ed8\u51fa\u5355\u5411\u548c\u53cc\u5411\u94fe\u63a5\u7ed3\u6784\u3002 \u901a\u8fc7\u4e00\u4e2a\u989d\u5916\u7684\u5934\u90e8\u94fe\u63a5\uff08head link\uff09\uff0c\u53ef\u4ee5\u4f7f\u7528\u5355\u5411\u94fe\u63a5\u7ed3\u6784\u8bbf\u95ee\u7b2c\u4e00\u4e2a\u8282\u70b9\u3002\u63a5\u4e0b\u6765\uff0c\u6211\u4eec\u5c31\u53ef\u4ee5\u901a\u8fc7\u8fd9\u4e2a\u8282\u70b9\u91cc\u53d1\u51fa\u7684\u94fe\u63a5\uff08\u4e0a\u56fe\u4e2d\u7684\u7bad\u5934\uff09\u6765\u8bbf\u95ee\u5176\u4ed6\u8282\u70b9\u4e86\u3002\u56e0\u6b64\uff0c\u5728\u5355\u5411\u94fe\u63a5\u7ed3\u6784\u91cc\uff0c\u6211\u4eec\u53ef\u4ee5\u5f88\u5bb9\u6613\u5730\u83b7\u5f97\u8282\u70b9\u7684\u540e\u7ee7\u8282\u70b9\uff0c\u4f46\u4e0d\u90a3\u4e48\u5bb9\u6613\u83b7\u5f97\u8282\u70b9\u7684\u524d\u5e8f\u8282\u70b9\u3002 \u53cc\u5411\u94fe\u63a5\u7ed3\u6784\u4f1a\u5305\u542b\u53cc\u5411\u7684\u94fe\u63a5\uff0c\u6211\u4eec\u53ef\u4ee5\u5f88\u5bb9\u6613\u5730\u79fb\u52a8\u5230\u8282\u70b9\u7684\u524d\u5e8f\u6216\u8005\u540e\u7ee7\u8282\u70b9\uff0c\u8fd9\u4e2a\u65f6\u5019\u4f1a\u7528\u5230\u7b2c\u4e8c\u4e2a\u989d\u5916\u7684\u94fe\u63a5\uff08\u5c3e\u90e8\u94fe\u63a5tail link\uff09\u3002\u5c3e\u90e8\u94fe\u63a5\u80fd\u591f\u8ba9\u53cc\u5411\u94fe\u63a5\u7ed3\u6784\u7684\u7528\u6237\u76f4\u63a5\u8bbf\u95ee\u6700\u540e\u4e00\u4e2a\u8282\u70b9\u3002 \u5728\u4e24\u79cd\u94fe\u63a5\u7ed3\u6784\u91cc\uff0c\u6700\u540e\u4e00\u4e2a\u8282\u70b9\u90fd\u6ca1\u6709\u6307\u5411\u540e\u7eed\u8282\u70b9\u7684\u94fe\u63a5\u3002\u5728\u4e0a\u56fe\u4e2d\uff0c\u7528\u659c\u6760\u4ee3\u66ff\u7bad\u5934\u4ee5\u8868\u793a\u6ca1\u6709\u94fe\u63a5\uff0c\u8fd9\u79f0\u4e3a\u7a7a\u94fe\u63a5\uff08empty link\uff09\u3002 \u5728\u53cc\u5411\u94fe\u63a5\u7ed3\u6784\u91cc\uff0c\u7b2c\u4e00\u4e2a\u8282\u70b9\u4e5f\u6ca1\u6709\u6307\u5411\u524d\u5e8f\u8282\u70b9\u7684\u94fe\u63a5\u3002 \u548c\u6570\u7ec4\u4e00\u6837\uff0c\u94fe\u63a5\u7ed3\u6784\u4e5f\u53ef\u4ee5\u7528\u6765\u5b58\u50a8\u5143\u7d20\u7684\u7ebf\u6027\u5e8f\u5217\uff0c\u4f46\u65e0\u6cd5\u901a\u8fc7\u6307\u5b9a\u7684\u7d22\u5f15\u4f4d\u7f6e\u76f4\u63a5\u8bbf\u95ee\u8fd9\u4e2a\u5143\u7d20\uff0c\u5fc5\u987b\u4ece\u6570\u636e\u7ed3\u6784\u7684\u4e00\u4e2a\u9876\u7aef\u5f00\u59cb\uff0c\u7136\u540e\u6309\u7167\u94fe\u63a5\u8fdb\u884c\u8bbf\u95ee\uff0c\u76f4\u81f3\u5230\u8fbe\u6240\u9700\u7684\u4f4d\u7f6e\uff08\u6216\u627e\u5230\u671f\u671b\u7684\u5143\u7d20\uff09\u4e3a\u6b62\u3002\u94fe\u63a5\u7ed3\u6784\u7684\u8fd9\u79cd\u6027\u8d28\u5bf9\u4e8e\u5f88\u591a\u64cd\u4f5c\u90fd\u6709\u663e\u8457\u7684\u5f71\u54cd\u3002 \u4e3a\u94fe\u63a5\u7ed3\u6784\u5206\u914d\u5185\u5b58\u7684\u65b9\u5f0f\u548c\u4e3a\u6570\u7ec4\u5206\u914d\u5185\u5b58\u7684\u65b9\u5f0f\u662f\u5b8c\u5168\u4e0d\u540c\u7684\uff0c\u800c\u4e14\u5bf9\u4e8e\u63d2\u5165\u548c\u5220\u9664\u64cd\u4f5c\u6765\u8bf4\uff0c\u6709\u4e24\u4e2a\u663e\u8457\u5f71\u54cd\u3002 \u5728\u627e\u5230\u63d2\u5165\u6216\u5220\u9664\u70b9\u4e4b\u540e\uff0c\u53ef\u4ee5\u5728\u4e0d\u79fb\u52a8\u5185\u5b58\u91cc\u7684\u6570\u636e\u5143\u7d20\u7684\u60c5\u51b5\u4e0b\u6267\u884c\u63d2\u5165\u6216\u5220\u9664\u64cd\u4f5c\u3002 \u53ef\u4ee5\u5728\u6bcf\u6b21\u63d2\u5165\u6216\u5220\u9664\u671f\u95f4\u81ea\u52a8\u8c03\u6574\u94fe\u63a5\u7ed3\u6784\u7684\u5927\u5c0f\uff0c\u4e0d\u9700\u8981\u82b1\u8d39\u989d\u5916\u7684\u5185\u5b58\u7a7a\u95f4\uff0c\u4e5f\u4e0d\u9700\u8981\u590d\u5236\u6570\u636e\u5143\u7d20\u3002","title":"4.4.1.\u5355\u5411\u94fe\u63a5\u7ed3\u6784\u548c\u53cc\u5411\u94fe\u63a5\u7ed3\u6784"},{"location":"python/DataStructure/04_ArrayChain/#442","text":"\u6570\u7ec4\u91cc\u7684\u5143\u7d20\u5fc5\u987b\u5b58\u50a8\u5728\u4e00\u6bb5\u8fde\u7eed\u7684\u5185\u5b58\u4e2d\uff0c\u8fd9\u5c31\u610f\u5473\u7740\u6570\u7ec4\u91cc\u5404\u4e2a\u5143\u7d20\u7684\u903b\u8f91\u987a\u5e8f\u548c\u5b83\u4eec\u5728\u5185\u5b58\u5355\u5143\u91cc\u7684\u7269\u7406\u987a\u5e8f\u662f\u7d27\u5bc6\u8026\u5408\u7684\u3002 \u76f8\u6bd4\u800c\u8a00\uff0c\u94fe\u63a5\u7ed3\u6784\u4f1a\u628a\u7ed3\u6784\u91cc\u5404\u4e2a\u5143\u7d20\u7684\u903b\u8f91\u987a\u5e8f\u548c\u5b83\u4eec\u5728\u5185\u5b58\u91cc\u7684\u987a\u5e8f\u89e3\u8026\u3002\u8981\u5728\u5185\u5b58\u7684\u67d0\u4e2a\u4f4d\u7f6e\u4e0a\u627e\u5230\u94fe\u63a5\u7ed3\u6784\u91cc\u7279\u5b9a\u5143\u7d20\u7684\u5185\u5b58\u5355\u5143\uff0c\u53ea\u9700\u8981\u8ba9\u8ba1\u7b97\u673a\u8ddf\u968f\u6307\u5411\u8fd9\u4e2a\u5143\u7d20\u7684\u5730\u5740\u6216\u4f4d\u7f6e\u94fe\u63a5\u5c31\u884c\u4e86\u3002\u8fd9\u79f0\u4e3a\u975e\u8fde\u7eed\u5185\u5b58\uff08noncontiguous memory\uff09\u3002 \u94fe\u63a5\u7ed3\u6784\u91cc\u7528\u6765\u5b58\u50a8\u7684\u57fa\u672c\u5355\u4f4d\u662f\u8282\u70b9\uff08node\uff09\u3002 \u5355\u5411\u94fe\u63a5\u8282\u70b9\uff08singly linked node\uff09\u5305\u542b\u4e0b\u9762\u8fd9\u4e9b\u7ec4\u4ef6\u6216\u5b57\u6bb5\uff1a \u6570\u636e\u5143\u7d20\uff1b \u6307\u5411\u7ed3\u6784\u91cc\u540e\u7ee7\u8282\u70b9\u7684\u94fe\u63a5\uff1b \u5bf9\u4e8e\u53cc\u5411\u94fe\u63a5\u8282\u70b9\uff08doubly linked node\uff09\u5305\u542b\u4e0b\u9762\u8fd9\u4e9b\u7ec4\u4ef6\u6216\u5b57\u6bb5\uff1a \u6570\u636e\u5143\u7d20\uff1b \u6307\u5411\u7ed3\u6784\u91cc\u540e\u7ee7\u8282\u70b9\u7684\u94fe\u63a5\uff1b \u6307\u5411\u7ed3\u6784\u91cc\u524d\u5e8f\u8282\u70b9\u7684\u94fe\u63a5\uff1b \u4e0d\u540c\u7684\u7f16\u7a0b\u8bed\u8a00\uff0c\u901a\u8fc7\u4e0d\u540c\u7684\u65b9\u6cd5\u6765\u8ba9\u8282\u70b9\u5229\u7528\u975e\u8fde\u7eed\u5185\u5b58\u3002 FORTRAN\u8bed\u8a00\u4e2d\uff0c\u901a\u8fc7\u4e24\u4e2a\u5e76\u6392\u7684\u6570\u7ec4\u4e3a\u5355\u5411\u94fe\u63a5\u7ed3\u6784\u5b9e\u73b0\u975e\u8fde\u7eed\u5185\u5b58\u548c\u8282\u70b9\u3002\u8fd9\u6837\u505a\u53ef\u4ee5\u6709\u6548\u5730\u5c06\u94fe\u63a5\u7ed3\u6784\u91cc\u6570\u636e\u5143\u7d20\u7684\u903b\u8f91\u4f4d\u7f6e\u548c\u5b83\u5728\u6570\u7ec4\u91cc\u7684\u7269\u7406\u4f4d\u7f6e\u5206\u79bb\u3002 \u7b2c\u4e00\u4e2a\u6570\u7ec4\u5305\u542b\u6570\u636e\u5143\u7d20\uff1b\u7b2c\u4e8c\u4e2a\u6570\u7ec4\u5219\u5305\u542b\u6570\u636e\u6570\u7ec4\u91cc\u5f53\u524d\u8282\u70b9\u6240\u5bf9\u5e94\u7684\u540e\u7eed\u8282\u70b9\u7684\u7d22\u5f15\u4f4d\u7f6e\u3002 \u7528\u7b2c\u4e00\u4e2a\u6570\u7ec4\u91cc\u7684\u6570\u636e\u5143\u7d20\u7d22\u5f15\u6765\u8bbf\u95ee\u7b2c\u4e8c\u4e2a\u6570\u7ec4\u91cc\u7684\u503c\uff0c\u7136\u540e\u518d\u628a\u8fd9\u4e2a\u503c\u4f5c\u4e3a\u7b2c\u4e00\u4e2a\u6570\u7ec4\u91cc\u4e0b\u4e00\u4e2a\u6570\u636e\u5143\u7d20\u7684\u7d22\u5f15\u3002\u7a7a\u94fe\u63a5\u4f1a\u7528\u503c\u22121\u6765\u8868\u793a\u3002 Pascal\u548cC++\u8bed\u8a00\u4e2d\uff0c\u901a\u8fc7\u8bbf\u95ee\u6307\u9488\uff08pointer\uff09\u76f4\u63a5\u5f97\u5230\u6240\u9700\u7684\u6570\u636e\u5730\u5740\u3002 \u5355\u5411\u94fe\u63a5\u7ed3\u6784\u91cc\u7684\u8282\u70b9\u5305\u542b\u4e00\u4e2a\u6570\u636e\u5143\u7d20\u548c\u4e00\u4e2a\u6307\u9488\u503c\u3002\u5bf9\u4e8e\u7a7a\u94fe\u63a5\u6765\u8bf4\uff0c\u5b83\u7684\u6307\u9488\u503c\u7528\u7279\u6b8a\u503cnull\uff08\u6216nil\uff09\u6765\u8868\u793a\u3002 \u8bf7\u6c42\u4e00\u4e2a\u5bf9\u8c61\u5806\uff08object heap\uff09\u7684\u65b0\u8282\u70b9\u7684\u6307\u9488\uff0c\u8fd9\u4e2a\u8282\u70b9\u6765\u81ea\u975e\u8fde\u7eed\u5185\u5b58\u7684\u5185\u7f6e\u533a\u57df\uff0c\u5e76\u628a\u8fd9\u4e2a\u8282\u70b9\u91cc\u7684\u6307\u9488\u8bbe\u7f6e\u4e3a\u6307\u5411\u53e6\u4e00\u4e2a\u8282\u70b9\uff0c\u4ece\u800c\u5efa\u7acb\u5230\u8fd9\u4e2a\u94fe\u63a5\u7ed3\u6784\u91cc\u5176\u4ed6\u6570\u636e\u7684\u94fe\u63a5\u3002 \u901a\u8fc7\u663e\u5f0f\u5730\u4f7f\u7528\u6307\u9488\u548c\u5185\u7f6e\u5806\uff0c\u53ef\u4ee5\u4e0d\u518d\u9700\u8981\u7ba1\u7406\u975e\u8fde\u7eed\u5185\u5b58\u7684\u5e95\u5c42\u6570\u7ec4\u5b58\u50a8\u65b9\u5f0f\u4e86\uff0c\u4f46\u8fd8\u662f\u9700\u8981\u4eba\u4e3a\u7ba1\u7406\u5806\uff0c\u901a\u8fc7\u7279\u6b8a\u7684dispose\u6216delete\u64cd\u4f5c\u628a\u4e0d\u4f7f\u7528\u7684\u8282\u70b9\u8fd4\u56de\u7ed9\u5806\u3002 Python\u8bed\u8a00\u4e2d\uff0c\u901a\u8fc7\u4f7f\u7528\u5bf9\u5bf9\u8c61\u7684\u5f15\u7528\uff08reference\uff09\u8bbe\u7f6e\u8282\u70b9\u548c\u94fe\u63a5\u7ed3\u6784\u3002 Python\u4e2d\uff0c\u4efb\u4f55\u53d8\u91cf\u90fd\u53ef\u4ee5\u7528\u6765\u5f15\u7528\u4efb\u4f55\u6570\u636e\uff0c\u8fd9\u4e5f\u5305\u62ec\u503c None \uff0c\u5b83\u53ef\u4ee5\u7528\u6765\u4ee3\u8868\u7a7a\u94fe\u63a5\u3002 Python\u4e2d\uff0c\u5b9a\u4e49\u5305\u542b\u4e24\u4e2a\u5b57\u6bb5\u7684\u5bf9\u8c61\u6765\u5b9a\u4e49\u5355\u5411\u94fe\u63a5\u8282\u70b9\uff0c\u8fd9\u4e24\u4e2a\u5b57\u6bb5\u662f\u5bf9\u6570\u636e\u5143\u7d20\u7684\u5f15\u7528\u548c\u5bf9\u53e6\u4e00\u4e2a\u8282\u70b9\u7684\u5f15\u7528\u3002 Python\u4e2d\uff0c\u4e3a\u6bcf\u4e2a\u65b0\u7684\u8282\u70b9\u5bf9\u8c61\u63d0\u4f9b\u975e\u8fde\u7eed\u5185\u5b58\u7684\u52a8\u6001\u5206\u914d\uff0c\u5e76\u4e14\u5f53\u5e94\u7528\u7a0b\u5e8f\u4e0d\u518d\u5f15\u7528\u8fd9\u4e2a\u5bf9\u8c61\u7684\u65f6\u5019\uff0c\u5b83\u4f1a\u81ea\u52a8\u628a\u8fd9\u90e8\u5206\u5185\u5b58\u8fd4\u56de\u7ed9\u7cfb\u7edf\uff08\u5783\u573e\u56de\u6536\uff09\u3002","title":"4.4.2.\u975e\u8fde\u7eed\u5185\u5b58\u548c\u8282\u70b9"},{"location":"python/DataStructure/04_ArrayChain/#443","text":"\u5355\u5411\u94fe\u63a5\u8282\u70b9\u53ea\u5305\u542b\u6570\u636e\u5143\u7d20\u548c\u5bf9\u4e0b\u4e00\u4e2a\u8282\u70b9\u7684\u5f15\u7528\u3002\u56e0\u4e3a\u8282\u70b9\u5bf9\u8c61\u7684\u7075\u6d3b\u6027\u548c\u6613\u7528\u6027\u975e\u5e38\u91cd\u8981\uff0c\u6240\u4ee5\u901a\u5e38\u4f1a\u5f15\u7528\u8282\u70b9\u5bf9\u8c61\u7684\u5b9e\u4f8b\u53d8\u91cf\u800c\u4e0d\u662f\u65b9\u6cd5\u8c03\u7528\uff0c\u5e76\u4e14\u6784\u9020\u51fd\u6570\u4e5f\u9700\u8981\u7528\u6237\u5728\u521b\u5efa\u8282\u70b9\u65f6\u53ef\u4ee5\u8bbe\u7f6e\u8282\u70b9\u7684\u94fe\u63a5\u3002 \u4e0b\u9762\u662f\u7528\u6765\u5b9e\u73b0\u5355\u5411\u94fe\u63a5\u8282\u70b9\u7c7b\u7684\u4ee3\u7801\u3002 class Node ( object ): \"\"\"\u5355\u5411\u94fe\u63a5\u8282\u70b9\u7c7b\"\"\" def __init__ ( self , data , next = None ): \"\"\"\u5b9e\u4f8b\u5316\u4e00\u4e2a\u8282\u70b9, \u9ed8\u8ba4\u540e\u7ee7\u8282\u70b9\u4e3aNone\"\"\" self . data = data self . next = next def main (): # \u521b\u5efa\u4e00\u4e2a\u7a7a\u94fe node1 = None # \u521b\u5efa\u4e00\u4e2a\u5355\u5411\u94fe\u63a5\u8282\u70b9\uff0c\u542b\u6570\u636e\u5143\u7d20\u548c\u7a7a\u94fe node2 = Node ( \"A\" , None ) # \u521b\u5efa\u4e00\u4e2a\u5355\u5411\u94fe\u63a5\u8282\u70b9\uff0c\u542b\u6570\u636e\u5143\u7d20\u548c\u6307\u5411\u4e0b\u4e00\u4e2a\u8282\u70b9\u7684\u94fe\u63a5 node3 = Node ( \"B\" , node2 ) if __name__ == \"__main__\" : main ()","title":"4.4.3.\u5b9a\u4e49\u5355\u5411\u94fe\u63a5\u8282\u70b9\u7c7b"},{"location":"python/DataStructure/04_ArrayChain/#444","text":"\u4e0b\u9762\u8fd9\u6bb5\u4ee3\u7801\u6f14\u793a\u4e86\u8282\u70b9\u53d8\u91cf\u88ab\u521d\u59cb\u5316\u4e3a None \u6216\u4e00\u4e2a\u65b0\u7684 Node \u5bf9\u8c61\u3002 node1 \u6ca1\u6709\u6307\u5411\u4efb\u4f55\u8282\u70b9\u5bf9\u8c61\uff08\u662f None \uff09\u3002 node2 \u548c node3 \u90fd\u6307\u5411\u4e86\u94fe\u63a5\u7684\u5bf9\u8c61\u3002 node2 \u6307\u5411\u4e86\u4e0b\u4e00\u4e2a\u6307\u9488\u662f None \u7684\u5bf9\u8c61\u3002 def main (): # \u521b\u5efa\u4e00\u4e2a\u7a7a\u94fe node1 = None # \u521b\u5efa\u4e00\u4e2a\u5355\u5411\u94fe\u63a5\u8282\u70b9\uff0c\u542b\u6570\u636e\u5143\u7d20\u548c\u7a7a\u94fe node2 = Node ( \"A\" , None ) # \u521b\u5efa\u4e00\u4e2a\u5355\u5411\u94fe\u63a5\u8282\u70b9\uff0c\u542b\u6570\u636e\u5143\u7d20\u548c\u6307\u5411\u4e0b\u4e00\u4e2a\u8282\u70b9\u7684\u94fe\u63a5 node3 = Node ( \"B\" , node2 ) \u6267\u884c node1.next = node3 \u4f1a\u6536\u5230\u9519\u8bef AttributeError: 'NoneType' object has no attribute 'next' \uff0c\u56e0\u4e3a\u53d8\u91cf node1 \u7684\u503c\u662f None \uff0c\u6240\u4ee5\u5b83\u5e76\u4e0d\u5305\u542b\u7528\u6765\u5f15\u7528\u8282\u70b9\u5bf9\u8c61\u7684 next \u5b57\u6bb5\u3002 \u5e94\u8be5\u5148\u6b63\u786e\u5b9e\u4f8b\u5316 node1 \uff0c\u518d\u5c06 node3 \u4f5c\u4e3a\u5176\u540e\u7ee7\u3002\u4e0b\u9762\u662f\u793a\u4f8b\u4ee3\u7801\u3002 def main (): # \u521b\u5efa\u4e00\u4e2a\u7a7a\u94fe node1 = None # \u521b\u5efa\u4e00\u4e2a\u5355\u5411\u94fe\u63a5\u8282\u70b9\uff0c\u542b\u6570\u636e\u5143\u7d20\u548c\u7a7a\u94fe node2 = Node ( \"A\" , None ) # \u521b\u5efa\u4e00\u4e2a\u5355\u5411\u94fe\u63a5\u8282\u70b9\uff0c\u542b\u6570\u636e\u5143\u7d20\u548c\u6307\u5411\u4e0b\u4e00\u4e2a\u8282\u70b9\u7684\u94fe\u63a5 node3 = Node ( \"B\" , node2 ) if node1 != None : node1 . next = node3 else : node1 = Node ( \"C\" , None ) node1 . next = node3 \u4e0b\u9762\u7684\u4ee3\u7801\u7684\u529f\u80fd\u662f\uff1a\u521b\u5efa\u4e00\u4e2a\u5355\u5411\u94fe\u63a5\u7ed3\u6784\uff0c\u5e76\u6253\u5370\u51fa\u5b83\u7684\u5185\u5bb9\u3002 \u4ee3\u7801\u4e2d head \u662f\u4e00\u4e2a\u6307\u9488\uff0c\u7528\u4e8e\u751f\u6210\u6574\u4e2a\u94fe\u63a5\u7ed3\u6784\u3002\u8fd9\u4e2a\u6307\u9488\u7684\u7528\u6cd5\u662f\u8ba9\u6240\u6709\u65b0\u63d2\u5165\u7684\u5143\u7d20\u59cb\u7ec8\u4f4d\u4e8e\u94fe\u63a5\u7ed3\u6784\u7684\u5f00\u5934\u3002 \u5728\u663e\u793a\u6570\u636e\u65f6\uff0c\u5b83\u4eec\u4f1a\u4ee5\u548c\u63d2\u5165\u65f6\u76f8\u53cd\u7684\u987a\u5e8f\u51fa\u73b0\u3002\u6b64\u5916\uff0c\u5f53\u663e\u793a\u6570\u636e\u65f6\uff0c\u5934\u90e8\u6307\u9488 head \u4f1a\u88ab\u91cd\u7f6e\u5230\u4e0b\u4e00\u4e2a\u8282\u70b9\uff0c\u76f4\u5230\u5934\u90e8\u6307\u9488\u53d8\u4e3a None \u4e3a\u6b62\u3002 \u4ee3\u7801\u6267\u884c\u7ed3\u675f\u4e4b\u540e\uff0c\u8fd9\u4e9b\u8282\u70b9\u5728\u7a0b\u5e8f\u91cc\u4e0d\u518d\u53ef\u7528\uff0c\u5e76\u4e14\u4f1a\u5728\u4e0b\u4e00\u6b21\u5783\u573e\u56de\u6536\u671f\u95f4\u88ab\u56de\u6536\u3002 def main (): # \u521b\u5efa\u4e00\u4e2a\u5355\u5411\u94fe\u63a5\u7ed3\u6784\uff0c\u5e76\u6253\u5370\u51fa\u5b83\u7684\u5185\u5bb9 head = None # \u5728\u94fe\u63a5\u7ed3\u6784\u7684\u5f00\u5934\u4f9d\u6b21\u63d2\u5165\u4e94\u4e2a\u8282\u70b9 for count in range ( 1 , 6 ): head = Node ( count , head ) # \u6253\u5370\u8f93\u51fa\u8fd9\u4e2a\u5355\u5411\u94fe\u63a5\u7684\u4e94\u4e2a\u8282\u70b9\u7684\u5185\u5bb9 while head != None : print ( head . data ) head = head . next if __name__ == \"__main__\" : main () # \u8fd0\u884c\u7ed3\u679c # 5 # 4 # 3 # 2 # 1","title":"4.4.4.\u4f7f\u7528\u5355\u5411\u94fe\u63a5\u8282\u70b9\u7c7b"},{"location":"python/DataStructure/04_ArrayChain/#445","text":"1\uff0e\u7528\u6846\u548c\u6307\u9488\u7ed8\u5236\u6d4b\u8bd5\u7a0b\u5e8f\u91cc\u7b2c\u4e00\u4e2a\u5faa\u73af\u6240\u521b\u5efa\u7684\u8282\u70b9\u7684\u793a\u610f\u56fe\u3002 \u89e3\u7b54\uff1a\u5728\u4e0b\u9762\u7684\u4ee3\u7801\u4e2d\uff0c\u6211\u4eec\u9996\u5148\u521b\u5efa\u4e86\u4e00\u4e2a\u7a7a\u7684\u5355\u94fe\u8868 head \u3002\u7136\u540e\u6211\u4eec\u5728\u94fe\u8868\u7684\u5f00\u5934\u4f9d\u6b21\u63d2\u5165\u4e94\u4e2a\u8282\u70b9\uff0c\u8282\u70b9\u7684\u6570\u636e\u4f9d\u6b21\u4e3a 1 , 2 , 3 , 4 , 5 \u3002\u5728\u63d2\u5165\u8fc7\u7a0b\u4e2d\uff0c\u6bcf\u6b21\u90fd\u628a\u65b0\u7684\u8282\u70b9\u63d2\u5165\u5230\u94fe\u8868\u7684\u5934\u90e8\uff0c\u6240\u4ee5\u6700\u540e\u7684\u94fe\u8868\u987a\u5e8f\u4f1a\u662f 5 , 4 , 3 , 2 , 1 \u3002 def main (): # \u521b\u5efa\u4e00\u4e2a\u5355\u5411\u94fe\u63a5\u7ed3\u6784\uff0c\u5e76\u6253\u5370\u51fa\u5b83\u7684\u5185\u5bb9 head = None # \u5728\u94fe\u63a5\u7ed3\u6784\u7684\u5f00\u5934\u4f9d\u6b21\u63d2\u5165\u4e94\u4e2a\u8282\u70b9 for count in range ( 1 , 6 ): head = Node ( count , head ) # \u6253\u5370\u8f93\u51fa\u8fd9\u4e2a\u5355\u5411\u94fe\u63a5\u7684\u4e94\u4e2a\u8282\u70b9\u7684\u5185\u5bb9 while head != None : print ( head . data ) head = head . next \u4ee5\u4e0b\u662f\u56fe\u793a\uff0c\u6bcf\u4e2a [] \u4ee3\u8868\u4e00\u4e2a\u8282\u70b9\uff0c\u8282\u70b9\u4e2d\u7684\u6570\u5b57\u4ee3\u8868\u8282\u70b9\u7684\u6570\u636e\uff0c\u7bad\u5934\u4ee3\u8868\u6307\u9488\uff0c\u6307\u5411\u4e86\u4e0b\u4e00\u4e2a\u8282\u70b9\u3002 NULL \u8868\u793a\u94fe\u8868\u7684\u7ed3\u675f\u3002 [5]---> [4] ---> [3] ---> [2] ---> [1] ---> NULL 2\uff0e\u5f53\u8282\u70b9\u53d8\u91cf\u5f15\u7528\u7684\u662f None \u65f6\uff0c\u5982\u679c\u7a0b\u5e8f\u5458\u5c1d\u8bd5\u8bbf\u95ee\u8282\u70b9\u7684\u6570\u636e\u5b57\u6bb5\uff0c\u5219\u4f1a\u53d1\u751f\u4ec0\u4e48\uff1f\u5982\u4f55\u9632\u6b62\u8fd9\u79cd\u60c5\u51b5\u7684\u53d1\u751f\uff1f \u89e3\u7b54\uff1a\u5f53\u8282\u70b9\u53d8\u91cf\u5f15\u7528\u7684\u662f None \u65f6\uff0c\u4f8b\u5982\uff0c\u6267\u884c node1.next = node3 \u4f1a\u6536\u5230\u9519\u8bef AttributeError: 'NoneType' object has no attribute 'next' \uff0c\u56e0\u4e3a\u53d8\u91cf node1 \u7684\u503c\u662f None \uff0c\u6240\u4ee5\u5b83\u5e76\u4e0d\u5305\u542b\u7528\u6765\u5f15\u7528\u8282\u70b9\u5bf9\u8c61\u7684 next \u5b57\u6bb5\u3002 \u5e94\u8be5\u5148\u6b63\u786e\u5b9e\u4f8b\u5316 node1 \uff0c\u518d\u5c06 node3 \u4f5c\u4e3a\u5176\u540e\u7ee7\u3002\u4e0b\u9762\u662f\u793a\u4f8b\u4ee3\u7801\u3002 if node1 != None : node1 . next = node3 else : node1 = Node ( \"C\" , None ) node1 . next = node3 3\uff0e\u7f16\u5199\u4e00\u6bb5\u4ee3\u7801\uff1a\u8fd9\u6bb5\u4ee3\u7801\u4f1a\u628a\u4e00\u4e2a\u88ab\u586b\u6ee1\u7684\u6570\u7ec4\u91cc\u7684\u5143\u7d20\u90fd\u8f6c\u79fb\u4e3a\u5355\u5411\u94fe\u63a5\u7ed3\u6784\u91cc\u7684\u6570\u636e\u3002\u8fd9\u4e2a\u64cd\u4f5c\u5e94\u4fdd\u7559\u5143\u7d20\u7684\u987a\u5e8f\u4e0d\u53d8\u3002 \u89e3\u7b54\uff1a\u4e0b\u9762\u662f\u4ee3\u7801\u5b9e\u73b0\u3002 LinkedList \u7c7b\u6709\u4e24\u4e2a\u65b9\u6cd5\uff0c insert_from_list \u7528\u4e8e\u4ece\u5217\u8868\u4e2d\u63d2\u5165\u6570\u636e\uff0c print_list \u7528\u4e8e\u6253\u5370\u94fe\u8868\u7684\u6240\u6709\u5143\u7d20\u3002 \u5728 insert_from_list \u65b9\u6cd5\u4e2d\uff0c\u6211\u4eec\u9996\u5148\u521b\u5efa\u7b2c\u4e00\u4e2a\u8282\u70b9\uff0c\u7136\u540e\u5bf9\u5217\u8868\u7684\u5269\u4f59\u5143\u7d20\uff0c\u4f9d\u6b21\u521b\u5efa\u65b0\u7684\u8282\u70b9\u5e76\u6dfb\u52a0\u5230\u94fe\u8868\u5c3e\u90e8\u3002 \u7531\u4e8e\u6211\u4eec\u662f\u9010\u4e2a\u5c06\u5143\u7d20\u6dfb\u52a0\u5230\u94fe\u8868\u7684\u672b\u5c3e\uff0c\u6240\u4ee5\u5728\u521b\u5efaNode\u65f6\u5e76\u4e0d\u9700\u8981\u6307\u5b9anext\u8282\u70b9\u3002 class Node ( object ): \"\"\"\u5355\u5411\u94fe\u63a5\u8282\u70b9\u7c7b\"\"\" def __init__ ( self , data , next = None ): \"\"\"\u5b9e\u4f8b\u5316\u4e00\u4e2a\u8282\u70b9, \u9ed8\u8ba4\u540e\u7ee7\u8282\u70b9\u4e3aNone\"\"\" self . data = data self . next = next class LinkedList : \"\"\"\u5c06\u5217\u8868\u5143\u7d20\u8f6c\u79fb\u4e3a\u5355\u5411\u94fe\u63a5\u7ed3\u6784\u91cc\u7684\u6570\u636e\uff0c\u5e76\u4fdd\u7559\u5143\u7d20\u7684\u987a\u5e8f\u4e0d\u53d8\"\"\" def __init__ ( self ): self . head = None # \u521d\u59cb\u5316head def insert_from_list ( self , data_list ): # \u521b\u5efa\u4e86\u94fe\u8868\u7684\u5934\u8282\u70b9 self . head = Node ( data_list [ 0 ]) # \u8bfb\u53d6\u5217\u8868\u7d22\u5f150\u7684\u5143\u7d20\u503c\uff0c\u5e76\u5c06\u5730\u5740\u8d4b\u503c\u7ed9head current = self . head # \u5c06head\u5f15\u7528\u8d4b\u503c\u7ed9current # \u5728\u94fe\u8868\u7684\u5c3e\u90e8\u4f9d\u6b21\u6dfb\u52a0\u65b0\u7684\u8282\u70b9 # \u5728\u6bcf\u6b21\u5faa\u73af\u540e\uff0c\u94fe\u8868\u7684\u5c3e\u90e8\u90fd\u4f1a\u6dfb\u52a0\u65b0\u7684\u8282\u70b9\uff0c\u5e76\u4e14current\u8282\u70b9\u4e5f\u4f1a\u968f\u4e4b\u66f4\u65b0\u3002 for data in data_list [ 1 :]: current . next = Node ( data ) # \u521b\u5efa\u4e00\u4e2a\u65b0\u7684\u8282\u70b9\uff0c\u5e76\u4e14\u5c06current\u8282\u70b9\u7684next\u5c5e\u6027\u8bbe\u7f6e\u4e3a\u8fd9\u4e2a\u65b0\u7684\u8282\u70b9\u3002\u8fd9\u6837\uff0ccurrent\u8282\u70b9\uff08\u4e5f\u5c31\u662f\u4e4b\u524d\u7684\u5c3e\u8282\u70b9\uff09\u5c31\u548c\u65b0\u7684\u8282\u70b9\u5efa\u7acb\u4e86\u94fe\u63a5\u5173\u7cfb\u3002 current = current . next # \u5c06current\u66f4\u65b0\u4e3a\u65b0\u521b\u5efa\u7684\u8282\u70b9\u3002\u4e5f\u5c31\u662f\u8bf4\uff0ccurrent\u59cb\u7ec8\u4ee3\u8868\u5f53\u524d\u94fe\u8868\u7684\u5c3e\u8282\u70b9\u3002 def print_list ( self ): current = self . head while current : print ( current . data , end = ' ' ) current = current . next print () def main (): # \u5c06\u5217\u8868data_list\u4e2d\u7684\u5143\u7d20\u63d2\u5165\u5230LinkedList\u5b9e\u4f8b\u4e2d\uff0c\u518d\u4f7f\u7528print_list\u65b9\u6cd5\u6253\u5370\u51fa\u94fe\u8868\u4e2d\u6240\u6709\u5143\u7d20\u3002 data_list = [ 1 , 2 , 3 , 4 , 5 ] linked_list = LinkedList () linked_list . insert_from_list ( data_list ) linked_list . print_list () # \u8f93\u51fa: 1 2 3 4 5 if __name__ == \"__main__\" : main () # \u8fd0\u884c\u7ed3\u679c # 1 2 3 4 5 \u5982\u679c\u5728\u521b\u5efaNode\u7684\u65f6\u5019\u6307\u5b9a next \u8282\u70b9\uff0c\u5219\u53ef\u4ee5\u4fee\u6539\u4e3a\u4e0b\u9762\u7684\u4ee3\u7801\u3002 insert_from_list \u51fd\u6570\u9996\u5148\u53cd\u8f6c\u4e86\u8f93\u5165\u7684\u5217\u8868\uff0c\u7136\u540e\u904d\u5386\u53cd\u8f6c\u540e\u7684\u5217\u8868\uff0c\u6bcf\u6b21\u90fd\u5728\u94fe\u8868\u5934\u90e8\u63d2\u5165\u4e00\u4e2a\u65b0\u7684\u8282\u70b9\u3002\u8fd9\u6837\u53ef\u4ee5\u786e\u4fdd\u63d2\u5165\u94fe\u8868\u7684\u5143\u7d20\u987a\u5e8f\u548c\u5b83\u4eec\u5728\u8f93\u5165\u5217\u8868\u4e2d\u7684\u987a\u5e8f\u662f\u4e00\u6837\u7684\u3002 class Node ( object ): \"\"\"\u5355\u5411\u94fe\u63a5\u8282\u70b9\u7c7b\"\"\" def __init__ ( self , data , next = None ): \"\"\"\u5b9e\u4f8b\u5316\u4e00\u4e2a\u8282\u70b9, \u9ed8\u8ba4\u540e\u7ee7\u8282\u70b9\u4e3aNone\"\"\" self . data = data self . next = next class LinkedList : \"\"\"\u5c06\u6570\u7ec4\u5143\u7d20\u8f6c\u79fb\u4e3a\u5355\u5411\u94fe\u63a5\u7ed3\u6784\u91cc\u7684\u6570\u636e\uff0c\u5e76\u4fdd\u7559\u5143\u7d20\u7684\u987a\u5e8f\u4e0d\u53d8\"\"\" def __init__ ( self ): self . head = None # \u521d\u59cb\u5316head def insert_from_list ( self , data_list ): for data in reversed ( data_list ): self . head = Node ( data , self . head ) def print_list ( self ): current = self . head while current : print ( current . data , end = ' ' ) current = current . next print () def main (): data_list = [ 1 , 2 , 3 , 4 , 5 ] linked_list = LinkedList () linked_list . insert_from_list ( data_list ) linked_list . print_list () # \u8f93\u51fa: 1 2 3 4 5 if __name__ == \"__main__\" : main () # \u8fd0\u884c\u7ed3\u679c # 1 2 3 4 5","title":"4.4.5.\u7ec3\u4e60\u9898"},{"location":"python/DataStructure/04_ArrayChain/#45","text":"\u6570\u7ec4\u4e0a\u7684\u64cd\u4f5c\u51e0\u4e4e\u90fd\u662f\u57fa\u4e8e\u7d22\u5f15\u7684\u3002\u94fe\u63a5\u7ed3\u6784\u4e0a\u7684\u64cd\u4f5c\u662f\u901a\u8fc7\u64cd\u63a7\u7ed3\u6784\u91cc\u7684\u94fe\u63a5\u6765\u6a21\u62df\u8fd9\u4e9b\u57fa\u4e8e\u7d22\u5f15\u7684\u64cd\u4f5c\u3002 \u4e0b\u9762\u662f\u5b8c\u6574\u4ee3\u7801\uff0c\u5305\u542b\u4e86\u540e\u9762\u5173\u4e8e\u8fde\u63a5\u7ed3\u6784\u7684\u64cd\u4f5c\u793a\u4f8b\u3002 # class Node(object): # \"\"\"\u5355\u5411\u94fe\u63a5\u8282\u70b9\u7c7b\"\"\" # def __init__(self, data, next=None): # \"\"\"\u5b9e\u4f8b\u5316\u4e00\u4e2a\u8282\u70b9, \u9ed8\u8ba4\u540e\u7ee7\u8282\u70b9\u4e3aNone\"\"\" # self.data = data # self.next = next # class TwoWayNode(Node): # \"\"\"\u53cc\u5411\u94fe\u63a5\u8282\u70b9\u7c7b\"\"\" # def __init__(self, data, previous=None, next=None): # \"\"\"\u5b9e\u4f8b\u5316\u4e00\u4e2a\u8282\u70b9, \u9ed8\u8ba4\u524d\u5e8f\u8282\u70b9\u5c3eNone, \u9ed8\u8ba4\u540e\u7ee7\u8282\u70b9\u4e3aNone\"\"\" # Node.__init__(self, data, next) # self.previous = previous # class LinkedList: # \"\"\"\u5355\u5411\u548c\u53cc\u5411\u94fe\u63a5\u7ed3\u6784\"\"\" # def __init__(self, node): # # \u521d\u59cb\u5316\u5934\u8282\u70b9 # self.head = node # # \u5c5e\u6027size\u4fdd\u5b58\u94fe\u63a5\u7ed3\u6784\u7684\u903b\u8f91\u5927\u5c0f\uff0c\u901a\u5e38\u6307\u7684\u662f\u94fe\u8868\u6240\u5305\u542b\u7684\u5143\u7d20\u7684\u6570\u91cf\uff0c\u521d\u59cb\u5316\u94fe\u63a5\u7ed3\u6784\u5927\u5c0f\u4e3a0 # self.size = 0 # def insert_from_list(self, data_list, twoway=False): # \"\"\" # \u628a\u4e00\u4e2a\u5217\u8868\uff08\u5df2\u6709\u7684\u6570\u636e\u7ed3\u6784\uff09\u8f6c\u6362\u4e3a\u94fe\u63a5\u7ed3\u6784\u662f\u4e00\u79cd\u6bd4\u8f83\u5e38\u89c1\u5b9e\u7528\u7684\u65b9\u5f0f\u3002\u8fd9\u79cd\u505a\u6cd5\u53ef\u4ee5\u901a\u8fc7\u63a7\u5236\u4ee3\u7801\uff0c\u65b9\u4fbf\u5730\u4ece\u5df2\u6709\u7684\u96c6\u5408\u7c7b\uff08\u5982\u5217\u8868\uff0c\u6570\u7ec4\u7b49\uff09\u4e2d\u5bfc\u5165\u5143\u7d20\uff0c\u5e76\u6784\u5efa\u9700\u8981\u7684\u7684\u94fe\u63a5\u7ed3\u6784\u3002 # \u5728\u4e00\u4e9b\u7b80\u5355\u573a\u666f\u4e0b\uff0c\u6bd4\u5982\u5df2\u77e5\u5f85\u6dfb\u52a0\u7684\u5143\u7d20\u6570\u91cf\u5f88\u5c11\uff0c\u6216\u8005\u6709\u5176\u4ed6\u7ea6\u675f\u4f7f\u5f97\u7528\u5217\u8868\u4e0d\u65b9\u4fbf\u65f6\uff0c\u53ef\u4ee5\u901a\u8fc7\u624b\u52a8\u65b9\u5f0f\u5411\u94fe\u63a5\u7ed3\u6784\u6dfb\u52a0\u5143\u7d20\u3002\u4f46\u5982\u679c\u5143\u7d20\u5f88\u591a\uff0c\u6216\u8005\u6709\u672a\u77e5\u6570\u91cf\u7684\u5143\u7d20\u9700\u8981\u6dfb\u52a0\uff0c\u7528\u5217\u8868\u53ef\u4ee5\u65b9\u4fbf\u5730\u4e00\u6b21\u6027\u5bfc\u5165\u6240\u6709\u5143\u7d20\u3002 # \"\"\" # if twoway: # \u68c0\u67e5\u662f\u5426\u8981\u521b\u5efa\u53cc\u5411\u94fe\u8868 # for data in data_list: # \u5bf9\u4e8e\u6570\u636e\u5217\u8868\u4e2d\u7684\u6bcf\u4e2a\u6570\u636e\u521b\u5efa\u4e00\u4e2a\u65b0\u7684\u53cc\u5411\u94fe\u63a5\u8282\u70b9 # node = TwoWayNode(data) # if self.head is None: # \u5982\u679c\u94fe\u8868\u4e3a\u7a7a\u628a\u65b0\u8282\u70b9\u8bbe\u7f6e\u4e3a\u5934\u8282\u70b9 # self.head = node # else: # \u5982\u679c\u94fe\u8868\u4e0d\u4e3a\u7a7a # tail = self.head # \u4ece\u5934\u8282\u70b9\u5f00\u59cb # while tail.next is not None: # \u901a\u8fc7\u904d\u5386\u94fe\u8868\u67e5\u627e\u5c3e\u8282\u70b9 # tail = tail.next # tail.next = node # \u628a\u65b0\u8282\u70b9\u63d2\u5165\u5230\u5c3e\u8282\u70b9 # node.previous = tail # \u8bbe\u7f6e\u65b0\u8282\u70b9\u7684\u524d\u4e00\u4e2a\u8282\u70b9\u6307\u5411\u5c3e\u8282\u70b9 # else: # \u521b\u5efa\u5355\u5411\u94fe\u8868 # for data in reversed(data_list): # \u5bf9\u4e8e\u5217\u8868\u4e2d\u7684\u6bcf\u4e2a\u5143\u7d20\uff0c\u53cd\u5411\u8fed\u4ee3\u4f7f\u5f97\u63d2\u5165\u7684\u8282\u70b9\u4e0e\u539f\u6570\u636e\u987a\u5e8f\u76f8\u540c # self.head = Node(data, self.head) # \u521b\u5efa\u4e00\u4e2a\u65b0\u7684\u5355\u5411\u94fe\u63a5\u8282\u70b9\u5e76\u63d2\u5165\u5230\u5934\u8282\u70b9 # self.size += len(data_list) # \u66f4\u65b0\u94fe\u8868\u5927\u5c0f # def get_size(self): # \"\"\"\u83b7\u53d6\u94fe\u8868\u5927\u5c0f\uff08\u8282\u70b9\u6570\u91cf\uff09\"\"\" # return self.size # def search(self, target): # \"\"\"\u5728\u94fe\u63a5\u7ed3\u6784\u4e2d\u641c\u7d22\u6307\u5b9a\u5143\u7d20\"\"\" # current = self.head # \u4ece\u5934\u8282\u70b9\u5f00\u59cb # while current: # \u5f53\u5f53\u524d\u8282\u70b9\u975eNone\u65f6\u7ee7\u7eed\u904d\u5386 # if current.data == target: # \u5982\u679c\u5f53\u524d\u8282\u70b9\u7684\u6570\u636e\u7b49\u4e8e\u76ee\u6807\u6570\u636e # return True # \u8fd4\u56de\u771f\u503c # current = current.next # \u79fb\u52a8\u5230\u4e0b\u4e00\u8282\u70b9 # return False # \u5982\u679c\u6574\u4e2a\u94fe\u8868\u904d\u5386\u5b8c\u6bd5\u8fd8\u627e\u4e0d\u5230\u76ee\u6807\u6570\u636e\uff0c\u8fd4\u56de\u5047\u503c # def locate(self, index): # \"\"\"\u8fd4\u56de\u94fe\u63a5\u7ed3\u6784\u4e2d\u7b2cindex\u4e2a\u5143\u7d20, 0 <= index < n\"\"\" # if index >= self.get_size() or index < 0: # \u5982\u679c\u7d22\u5f15\u8d85\u51fa\u8303\u56f4\uff0c\u7acb\u5373\u629b\u51fa\u9519\u8bef # raise IndexError(\"\u94fe\u8868\u7d22\u5f15\u8d85\u51fa\u8303\u56f4\") # probe = self.head # \u786e\u5b9a\u8d77\u59cb\u70b9\u4e3a\u5934\u8282\u70b9 # while index > 0: # \u5f53\u7d22\u5f15\u5927\u4e8e0\u65f6\uff0c\u8fdb\u5165\u5faa\u73af # probe = probe.next # \u5c06\u63a2\u9488\uff08probe\uff09\u79fb\u52a8\u5230\u4e0b\u4e00\u4e2a\u8282\u70b9 # index -= 1 # \u5c06\u7d22\u5f15\u503c\u51cf1 # return probe.data # \u8fd4\u56de\u5f53\u524d\u4f4d\u7f6e\uff08index\u5bf9\u5e94\u4f4d\u7f6e\uff09\u7684\u8282\u70b9\u6570\u636e # def replace(self, old, new): # \"\"\"\u66ff\u6362\u94fe\u8868\u4e2d\u6240\u6709\u7b49\u4e8eold\u7684\u5143\u7d20\u4e3anew\"\"\" # current = self.head # \u4ece\u94fe\u8868\u7684\u5934\u8282\u70b9\u5f00\u59cb\u904d\u5386 # while current: # \u53ea\u8981\u8fd8\u6709\u8282\u70b9\uff0c\u5c31\u7ee7\u7eed\u904d\u5386 # if current.data == old: # \u68c0\u67e5\u5f53\u524d\u8282\u70b9\u7684\u6570\u636e\u662f\u5426\u7b49\u4e8eold # current.data = new # \u5982\u679c\u7b49\u4e8eold\uff0c\u5c06\u5f53\u524d\u8282\u70b9\u7684\u6570\u636e\u66ff\u6362\u4e3anew # current = current.next # \u7ee7\u7eed\u68c0\u67e5\u4e0b\u4e00\u4e2a\u8282\u70b9 # def print_list(self): # \"\"\"\u6253\u5370\u8f93\u51fa\u94fe\u63a5\u7ed3\u6784\u5185\u5bb9\"\"\" # current = self.head # while current: # print(current.data, end=' ') # current = current.next # print() # def main(): # # \u521b\u5efa\u6d4b\u8bd5\u6570\u636e # test_data = [1, 2, 3, 4, 5] # # \u5355\u5411\u94fe\u8868\u6d4b\u8bd5 # print(\"\u5355\u5411\u94fe\u8868\u6d4b\u8bd5:\") # single_linked_list = LinkedList(None) # print(\"\u63d2\u5165\u6570\u636e\") # single_linked_list.insert_from_list(test_data) # \u63d2\u5165\u6d4b\u8bd5\u6570\u636e # single_linked_list.print_list() # \u6253\u5370\u94fe\u63a5\u7ed3\u6784\u5185\u5bb9 # print(\"\u94fe\u8868\u5927\u5c0f\uff1a\", single_linked_list.get_size()) # \u663e\u793a\u94fe\u63a5\u7ed3\u6784\u5927\u5c0f # print(\"\u641c\u7d22\u5143\u7d203: \", single_linked_list.search(3)) # \u641c\u7d22\u94fe\u63a5\u7ed3\u6784\u4e2d\u662f\u5426\u5b58\u5728\u5143\u7d203 # print(\"\u67e5\u627e\u7b2c2\u4e2a\u5143\u7d20: \", single_linked_list.locate(2)) # \u67e5\u627e\u94fe\u63a5\u7ed3\u6784\u4e2d\u7b2c2\u4e2a\u5143\u7d20 # print(\"\u628a\u5143\u7d201\u66ff\u6362\u4e3a10\") # single_linked_list.replace(1, 10) # \u66ff\u6362\u5143\u7d201\u4e3a10 # single_linked_list.print_list() # print() # # \u53cc\u5411\u94fe\u8868\u6d4b\u8bd5 # print(\"\u53cc\u5411\u94fe\u8868\u6d4b\u8bd5:\") # double_linked_list = LinkedList(None) # print(\"\u63d2\u5165\u6570\u636e\") # double_linked_list.insert_from_list(test_data, twoway=True) # double_linked_list.print_list() # print(\"\u94fe\u8868\u5927\u5c0f\uff1a\", double_linked_list.get_size()) # print(\"\u641c\u7d22\u5143\u7d203\uff1a\", double_linked_list.search(3)) # print(\"\u67e5\u627e\u7b2c2\u4e2a\u5143\u7d20\uff1a\", double_linked_list.locate(2)) # print(\"\u66ff\u6362\u5143\u7d201\u4e3a10\") # double_linked_list.replace(1, 10) # double_linked_list.print_list() # if __name__ == \"__main__\": # main() # # \u8fd0\u884c\u7ed3\u679c # # \u5355\u5411\u94fe\u8868\u6d4b\u8bd5: # # \u63d2\u5165\u6570\u636e # # 1 2 3 4 5 # # \u94fe\u8868\u5927\u5c0f\uff1a 5 # # \u641c\u7d22\u5143\u7d203\uff1a True # # \u67e5\u627e\u7b2c2\u4e2a\u5143\u7d20\uff1a 3 # # \u66ff\u6362\u5143\u7d201\u4e3a10 # # 10 2 3 4 5 # # \u53cc\u5411\u94fe\u8868\u6d4b\u8bd5: # # \u63d2\u5165\u6570\u636e # # 1 2 3 4 5 # # \u94fe\u8868\u5927\u5c0f\uff1a 5 # # \u641c\u7d22\u5143\u7d203\uff1a True # # \u67e5\u627e\u7b2c2\u4e2a\u5143\u7d20\uff1a 3 # # \u66ff\u6362\u5143\u7d201\u4e3a10 # # 10 2 3 4 5","title":"4.5.\u5355\u5411\u94fe\u63a5\u7ed3\u6784\u4e0a\u7684\u64cd\u4f5c"},{"location":"python/DataStructure/04_ArrayChain/#451","text":"\u57284.4\u4e2d\u7684\u793a\u4f8b\u4ee3\u7801\u4e2d\uff08\u5982\u4e0b\uff09\uff0c\u8282\u70b9\u4f1a\u5728\u88ab\u6253\u5370\u4e4b\u540e\u4ece\u94fe\u63a5\u7ed3\u6784\u91cc\u5220\u9664\u3002 def main (): # \u521b\u5efa\u4e00\u4e2a\u5355\u5411\u94fe\u63a5\u7ed3\u6784\uff0c\u5e76\u6253\u5370\u51fa\u5b83\u7684\u5185\u5bb9 head = None # \u5728\u94fe\u63a5\u7ed3\u6784\u7684\u5f00\u5934\u4f9d\u6b21\u63d2\u5165\u4e94\u4e2a\u8282\u70b9 for count in range ( 1 , 6 ): head = Node ( count , head ) # \u6253\u5370\u8f93\u51fa\u8fd9\u4e2a\u5355\u5411\u94fe\u63a5\u7684\u4e94\u4e2a\u8282\u70b9\u7684\u5185\u5bb9 while head != None : print ( head . data ) head = head . next if __name__ == \"__main__\" : main () # \u8fd0\u884c\u7ed3\u679c # 5 # 4 # 3 # 2 # 1 \u5bf9\u4e8e\u8bb8\u591a\u5e94\u7528\u7a0b\u5e8f\u6765\u8bf4\uff0c\u53ea\u9700\u8981\u8bbf\u95ee\u6bcf\u4e2a\u8282\u70b9\u800c\u4e0d\u7528\u5220\u9664\u5b83\u4eec\u3002\u8fd9\u4e2a\u64cd\u4f5c\u79f0\u4e3a\u904d\u5386\uff08traversal\uff09\u3002 \u5728\u904d\u5386\u4e2d\uff0c\u4f1a\u7528\u5230\u4e00\u4e2a\u53eb\u4f5c probe \u7684\u4e34\u65f6\u6307\u9488\u53d8\u91cf\u3002\u4e00\u5f00\u59cb\uff0c\u8fd9\u4e2a\u53d8\u91cf\u88ab\u521d\u59cb\u5316\u4e3a\u94fe\u63a5\u7ed3\u6784\u7684head\u6307\u9488\uff0c\u7136\u540e\u901a\u8fc7\u5faa\u73af\u6765\u5b8c\u6210\uff0c\u5728\u6574\u4e2a\u8fc7\u7a0b\u7ed3\u675f\u4e4b\u540e\uff0cprobe\u6307\u9488\u662fNone\uff0c\u4f46head\u6307\u9488\u4ecd\u7136\u5f15\u7528\u7b2c\u4e00\u4e2a\u8282\u70b9\u3002 \u4e0b\u9762\u662f\u4fee\u6539\u540e\u7684\u4ee3\u7801\uff1a def main (): print ( \"------\" ) # \u521b\u5efa\u4e00\u4e2a\u5355\u5411\u94fe\u63a5\u7ed3\u6784\uff0c\u5e76\u6253\u5370\u51fa\u5b83\u7684\u5185\u5bb9 head = None # \u5728\u94fe\u63a5\u7ed3\u6784\u7684\u5f00\u5934\u4f9d\u6b21\u63d2\u5165\u4e94\u4e2a\u8282\u70b9 for count in range ( 1 , 6 ): head = Node ( count , head ) # \u6253\u5370\u8f93\u51fa\u8fd9\u4e2a\u5355\u5411\u94fe\u63a5\u7684\u4e94\u4e2a\u8282\u70b9\u7684\u5185\u5bb9 probe = head while probe != None : print ( probe . data ) probe = probe . next \u901a\u5e38\u6765\u8bf4\uff0c\u5355\u5411\u94fe\u63a5\u7ed3\u6784\u7684\u904d\u5386\u4f1a\u8bbf\u95ee\u6240\u6709\u8282\u70b9\uff0c\u5e76\u4e14\u5728\u5230\u8fbe\u7a7a\u94fe\u63a5\u65f6\u7ec8\u6b62\u904d\u5386\u3002\u56e0\u6b64\uff0c\u503c None \u76f8\u5f53\u4e8e\u505c\u6b62\u8fdb\u7a0b\u7684\u54e8\u5175\uff08sentinel\uff09\u3002 \u904d\u5386\u7684\u65f6\u95f4\u590d\u6742\u5ea6\u662f\u7ebf\u6027\u7684\uff0c\u4e5f\u4e0d\u9700\u8981\u989d\u5916\u7684\u5185\u5b58\u3002","title":"4.5.1.\u904d\u5386"},{"location":"python/DataStructure/04_ArrayChain/#452","text":"\u5bf9\u94fe\u63a5\u7ed3\u6784\u8fdb\u884c\u987a\u5e8f\u641c\u7d22\u6709\u70b9\u7c7b\u4f3c\u4e8e\u904d\u5386\u64cd\u4f5c\uff0c\u56e0\u4e3a\u5fc5\u987b\u8981\u4ece\u7b2c\u4e00\u4e2a\u8282\u70b9\u5f00\u59cb\u5e76\u4f9d\u7167\u94fe\u63a5\u987a\u5e8f\u79fb\u52a8\uff0c\u76f4\u81f3\u627e\u5230\u5bf9\u5e94\u7684\u6807\u8bb0\u3002\u5728\u8fd9\u79cd\u60c5\u51b5\u4e0b\uff0c\u8fd9\u4e2a\u6807\u8bb0\u6709\u4e24\u79cd\u53ef\u80fd\u6027\u3002 \u7a7a\u94fe\u63a5\uff0c\u8bf4\u660e\u6ca1\u6709\u66f4\u591a\u9700\u8981\u88ab\u68c0\u67e5\u7684\u6570\u636e\u5143\u7d20\u3002 \u7b49\u540c\u4e8e\u76ee\u6807\u5143\u7d20\u7684\u6570\u636e\u5143\u7d20\uff0c\u4ee3\u8868\u641c\u7d22\u6210\u529f\u3002 \u4e0b\u9762\u662f\u641c\u7d22\u7ed9\u5b9a\u5143\u7d20\u7684\u4ee3\u7801\u3002 search(self, target) \u65b9\u6cd5\u5b9e\u73b0\u4e86\u5728\u5355\u5411\u6216\u53cc\u5411\u94fe\u8868\u4e2d\u641c\u7d22\u6307\u5b9a\u5143\u7d20\u3002 def search ( self , target ): \"\"\"\u5728\u94fe\u63a5\u7ed3\u6784\u4e2d\u641c\u7d22\u6307\u5b9a\u5143\u7d20\"\"\" current = self . head # \u4ece\u5934\u8282\u70b9\u5f00\u59cb while current : # \u5f53\u5f53\u524d\u8282\u70b9\u975eNone\u65f6\u7ee7\u7eed\u904d\u5386 if current . data == target : # \u5982\u679c\u5f53\u524d\u8282\u70b9\u7684\u6570\u636e\u7b49\u4e8e\u76ee\u6807\u6570\u636e return True # \u8fd4\u56de\u771f\u503c current = current . next # \u79fb\u52a8\u5230\u4e0b\u4e00\u8282\u70b9 return False # \u5982\u679c\u6574\u4e2a\u94fe\u8868\u904d\u5386\u5b8c\u6bd5\u8fd8\u627e\u4e0d\u5230\u76ee\u6807\u6570\u636e\uff0c\u8fd4\u56de\u5047\u503c \u5e73\u5747\u60c5\u51b5\u4e0b\uff0c\u987a\u5e8f\u641c\u7d22\u5728\u5355\u5411\u94fe\u63a5\u7ed3\u6784\u4e0a\u662f\u7ebf\u6027\u7684\u3002 \u8bbf\u95ee\u94fe\u63a5\u7ed3\u6784\u7684\u7b2c i \u4e2a\u5143\u7d20\u65f6\u6267\u884c\u7684\u4e5f\u662f\u987a\u5e8f\u641c\u7d22\u3002\u8fd9\u662f\u56e0\u4e3a\u5fc5\u987b\u4ece\u7b2c\u4e00\u4e2a\u8282\u70b9\u5f00\u59cb\u7edf\u8ba1\u94fe\u63a5\u7684\u6570\u91cf\uff0c\u76f4\u81f3\u5230\u8fbe\u7b2c i \u4e2a\u8282\u70b9\u4e3a\u6b62\u3002\u5047\u8bbe\u6709 0<=i= self . get_size () or index < 0 : # \u5982\u679c\u7d22\u5f15\u8d85\u51fa\u8303\u56f4\uff0c\u7acb\u5373\u629b\u51fa\u9519\u8bef raise IndexError ( \"\u94fe\u8868\u7d22\u5f15\u8d85\u51fa\u8303\u56f4\" ) probe = self . head # \u786e\u5b9a\u8d77\u59cb\u70b9\u4e3a\u5934\u8282\u70b9 while index > 0 : # \u5f53\u7d22\u5f15\u5927\u4e8e0\u65f6\uff0c\u8fdb\u5165\u5faa\u73af probe = probe . next # \u5c06\u63a2\u9488\uff08probe\uff09\u79fb\u52a8\u5230\u4e0b\u4e00\u4e2a\u8282\u70b9 index -= 1 # \u5c06\u7d22\u5f15\u503c\u51cf1 return probe . data # \u8fd4\u56de\u5f53\u524d\u4f4d\u7f6e\uff08index\u5bf9\u5e94\u4f4d\u7f6e\uff09\u7684\u8282\u70b9\u6570\u636e \u548c\u6570\u7ec4\u4e0d\u540c\u7684\u662f\uff0c\u94fe\u63a5\u7ed3\u6784\u5e76\u4e0d\u652f\u6301\u968f\u673a\u8bbf\u95ee\u3002\u56e0\u6b64\uff0c\u4e0d\u80fd\u50cf\u5728\u6709\u5e8f\u6570\u7ec4\u91cc\u90a3\u6837\u5bf9\u6709\u5e8f\u7684\u5355\u5411\u94fe\u63a5\u7ed3\u6784\u8fdb\u884c\u9ad8\u6548\u641c\u7d22\u3002","title":"4.5.2.\u641c\u7d22"},{"location":"python/DataStructure/04_ArrayChain/#453","text":"\u5355\u5411\u94fe\u63a5\u7ed3\u6784\u91cc\u7684\u66ff\u6362\u64cd\u4f5c\u4e5f\u4f1a\u91c7\u7528\u904d\u5386\u7684\u6a21\u5f0f\u3002\u5728\u8fd9\u79cd\u60c5\u51b5\u4e0b\uff0c\u6211\u4eec\u4f1a\u5728\u94fe\u63a5\u7ed3\u6784\u91cc\u641c\u7d22\u7ed9\u5b9a\u7684\u5143\u7d20\u6216\u7ed9\u5b9a\u7684\u4f4d\u7f6e\uff0c\u7136\u540e\u7528\u4e00\u4e2a\u65b0\u7684\u5143\u7d20\u66ff\u6362\u8fd9\u4e2a\u5143\u7d20\u3002 \u5728\u66ff\u6362\u7ed9\u5b9a\u5143\u7d20\u65f6\uff0c\u5e76\u4e0d\u9700\u8981\u5047\u5b9a\u76ee\u6807\u5143\u7d20\u5df2\u7ecf\u5b58\u5728\u4e8e\u94fe\u63a5\u7ed3\u6784\u91cc\u3002 \u5982\u679c\u76ee\u6807\u5143\u7d20\u4e0d\u5b58\u5728\uff0c\u5c31\u4e0d\u4f1a\u53d1\u751f\u4efb\u4f55\u66ff\u6362\u64cd\u4f5c\uff0c\u5e76\u4e14\u4f1a\u8fd4\u56de False \uff1b \u5982\u679c\u76ee\u6807\u5143\u7d20\u5b58\u5728\uff0c\u65b0\u7684\u5143\u7d20\u5c31\u4f1a\u66ff\u6362\u5b83\uff0c\u5e76\u4e14\u8fd4\u56de True \uff1b \u4e0b\u9762\u662f\u8fd9\u4e2a\u64cd\u4f5c\u7684\u4ee3\u7801\u3002 def replace ( self , old , new ): \"\"\"\u66ff\u6362\u94fe\u8868\u4e2d\u6240\u6709\u7b49\u4e8eold\u7684\u5143\u7d20\u4e3anew\"\"\" current = self . head # \u4ece\u94fe\u8868\u7684\u5934\u8282\u70b9\u5f00\u59cb\u904d\u5386 while current : # \u53ea\u8981\u8fd8\u6709\u8282\u70b9\uff0c\u5c31\u7ee7\u7eed\u904d\u5386 if current . data == old : # \u68c0\u67e5\u5f53\u524d\u8282\u70b9\u7684\u6570\u636e\u662f\u5426\u7b49\u4e8eold current . data = new # \u5982\u679c\u7b49\u4e8eold\uff0c\u5c06\u5f53\u524d\u8282\u70b9\u7684\u6570\u636e\u66ff\u6362\u4e3anew current = current . next # \u7ee7\u7eed\u68c0\u67e5\u4e0b\u4e00\u4e2a\u8282\u70b9","title":"4.5.3.\u66ff\u6362"},{"location":"python/DataStructure/04_ArrayChain/#454","text":"\u5728\u94fe\u63a5\u7ed3\u6784\u5934\u90e8\u63d2\u5165\u52062\u79cd\u60c5\u51b5\uff1a \u7b2c\u4e00\u79cd\u60c5\u51b5\uff1a head \u6307\u9488\u662f None \uff0c\u63d2\u5165\u64cd\u4f5c\u4f1a\u628a\u7b2c\u4e00\u4e2a\u5143\u7d20\u63d2\u5165\u7ed3\u6784\u91cc\uff1b \u7b2c\u4e8c\u79cd\u60c5\u51b5\uff1a head \u6307\u9488\u4e0d\u662f None \uff0c\uff0c\u7b2c\u4e8c\u4e2a\u5143\u7d20\u4f1a\u88ab\u63d2\u5165\u8fd9\u4e2a\u7ed3\u6784\u7684\u5f00\u5934\uff1b \u4ece\u4e0a\u97622\u79cd\u60c5\u51b5\u5f97\u51fa\uff0c\u5728\u5df2\u7ecf\u6709\u6570\u636e\u7684\u60c5\u51b5\u4e0b\uff0c\u5e76\u4e0d\u9700\u8981\u901a\u8fc7\u590d\u5236\u6570\u636e\u6765\u8ba9\u5b83\u4eec\u5411\u540e\u79fb\u52a8\uff0c\u4e5f\u4e0d\u9700\u8981\u989d\u5916\u7684\u5185\u5b58\u3002\u8fd9\u4e5f\u5c31\u610f\u5473\u7740\u5728\u94fe\u63a5\u7ed3\u6784\u7684\u5f00\u5934\u5904\u63d2\u5165\u6570\u636e\u53ea\u4f1a\u7528\u5230\u5e38\u6570\u7684\u65f6\u95f4\u548c\u5185\u5b58\uff0c\u8fd9\u548c\u5bf9\u6570\u7ec4\u7684\u76f8\u540c\u64cd\u4f5c\u662f\u4e0d\u4e00\u6837\u7684\u3002 \u4e0b\u9762\u662f\u5b8c\u6574\u7684\u4ee3\u7801\u3002 \"\"\" \u5b9e\u73b0\u4e86\u5bf9\u5355\u5411\u94fe\u63a5\u8fdb\u884c\u5982\u4e0b\u64cd\u4f5c\uff1a 1. \u5728\u5f00\u59cb\u5904\u63d2\u5165 2. \u5728\u7ed3\u5c3e\u5904\u63d2\u5165 3. \u5728\u5f00\u59cb\u5904\u5220\u9664 4. \u5728\u7ed3\u5c3e\u5904\u5220\u9664 5. \u5728\u4efb\u610f\u5904\u63d2\u5165 6. \u5728\u4efb\u610f\u5904\u5220\u9664 \"\"\" class Node ( object ): \"\"\"\u5355\u5411\u94fe\u63a5\u8282\u70b9\u7c7b\"\"\" def __init__ ( self , data , next = None ): \"\"\" \u5b9e\u4f8b\u5316\u4e00\u4e2a\u8282\u70b9, \u9ed8\u8ba4\u540e\u7ee7\u8282\u70b9\u4e3aNone Args: data: \u8282\u70b9\u5b58\u50a8\u7684\u6570\u636e next: \u6307\u5411\u4e0b\u4e00\u4e2a\u8282\u70b9\u7684\u6307\u9488\uff0c\u9ed8\u8ba4\u4e3aNone \"\"\" self . data = data # \u5b9a\u4e49\u8282\u70b9\u7684\u6570\u636e\u90e8\u5206 self . next = next # \u5b9a\u4e49\u8282\u70b9\u7684\u6307\u9488\u90e8\u5206\uff0c\u521d\u59cb\u503c\u4e3aNone\u8868\u793a\u6ca1\u6709\u4e0b\u4e00\u4e2a\u8282\u70b9 def insert_at_beginning ( head , data ): \"\"\" \u5728\u94fe\u8868\u5f00\u59cb\u5904\u63d2\u5165\u65b0\u8282\u70b9 Args: head: \u5f53\u524d\u94fe\u8868\u7684\u5934\u8282\u70b9 data: \u65b0\u8282\u70b9\u7684\u6570\u636e Returns: Node: \u65b0\u7684\u5934\u8282\u70b9 \"\"\" new_node = Node ( data ) # \u521b\u5efa\u65b0\u7684\u8282\u70b9\u5bf9\u8c61 new_node . next = head # \u5c06\u65b0\u8282\u70b9\u7684next\u6307\u9488\u6307\u5411\u5f53\u524d\u5934\u8282\u70b9 return new_node # \u8fd4\u56de\u65b0\u7684\u5934\u8282\u70b9 def insert_at_end ( head , data ): \"\"\" \u5728\u94fe\u8868\u672b\u5c3e\u63d2\u5165\u65b0\u8282\u70b9 Args: head: \u5f53\u524d\u94fe\u8868\u7684\u5934\u8282\u70b9 data: \u65b0\u8282\u70b9\u7684\u6570\u636e Returns: Node: \u5934\u8282\u70b9 \"\"\" new_node = Node ( data ) # \u521b\u5efa\u65b0\u7684\u8282\u70b9\u5bf9\u8c61 if head is None : # \u5982\u679c\u94fe\u8868\u4e3a\u7a7a\uff0c\u5c06\u65b0\u8282\u70b9\u8bbe\u7f6e\u4e3a\u5934\u8282\u70b9 head = new_node else : probe = head # \u521b\u5efa\u4e00\u4e2a\u6307\u9488\uff0c\u4ece\u5934\u8282\u70b9\u5f00\u59cb\u904d\u5386\u94fe\u8868 while probe . next is not None : # \u5f53\u6307\u9488\u6240\u6307\u8282\u70b9\u6709\u4e0b\u4e00\u4e2a\u8282\u70b9\u65f6 probe = probe . next # \u79fb\u52a8\u6307\u9488\u5230\u4e0b\u4e00\u4e2a\u8282\u70b9 probe . next = new_node # \u5c06\u65b0\u8282\u70b9\u8fde\u63a5\u5230\u5f53\u524d\u6307\u9488\u6240\u6307\u8282\u70b9\u7684\u4e0b\u4e00\u4e2a\u4f4d\u7f6e\uff0c\u5b8c\u6210\u8282\u70b9\u7684\u63d2\u5165 return head # \u8fd4\u56de\u5934\u8282\u70b9 def delete_at_beginning ( head ): \"\"\" \u4ece\u94fe\u8868\u5f00\u59cb\u5904\u5220\u9664\u8282\u70b9 Args: head: \u5f53\u524d\u94fe\u8868\u7684\u5934\u8282\u70b9 Returns: Node: \u65b0\u7684\u5934\u8282\u70b9 \"\"\" if head is None : # \u5982\u679c\u94fe\u8868\u4e3a\u7a7a\uff0c\u6253\u5370\u6d88\u606f\u5e76\u8fd4\u56de\u7a7a\u94fe\u8868 print ( \"Linked list is empty.\" ) else : head = head . next # \u5c06\u5934\u8282\u70b9\u6307\u5411\u4e0b\u4e00\u4e2a\u8282\u70b9\uff0c\u5373\u5220\u9664\u7b2c\u4e00\u4e2a\u8282\u70b9 return head # \u8fd4\u56de\u65b0\u7684\u5934\u8282\u70b9 def delete_at_end ( head ): \"\"\" \u4ece\u94fe\u8868\u672b\u5c3e\u5220\u9664\u8282\u70b9 Args: head: \u5f53\u524d\u94fe\u8868\u7684\u5934\u8282\u70b9 Returns: Node: \u5934\u8282\u70b9 \"\"\" if head is None : # \u5982\u679c\u94fe\u8868\u4e3a\u7a7a\uff0c\u8fd4\u56deNone return None if head . next is None : # \u5982\u679c\u94fe\u8868\u53ea\u6709\u4e00\u4e2a\u8282\u70b9\uff0c\u5c06\u5934\u8282\u70b9\u7f6e\u4e3aNone return None current = head while current . next . next : # \u79fb\u52a8\u5230\u5012\u6570\u7b2c\u4e8c\u4e2a\u8282\u70b9 current = current . next current . next = None # \u5c06\u5012\u6570\u7b2c\u4e8c\u4e2a\u8282\u70b9\u7684next\u7f6e\u4e3aNone\uff0c\u5373\u5220\u9664\u4e86\u6700\u540e\u4e00\u4e2a\u8282\u70b9 return head # \u8fd4\u56de\u5934\u8282\u70b9 def insert_at_position ( head , data , position ): \"\"\" \u5728\u94fe\u8868\u7684\u4efb\u610f\u4f4d\u7f6e\u63d2\u5165\u65b0\u8282\u70b9 Args: head: \u5f53\u524d\u94fe\u8868\u7684\u5934\u8282\u70b9 data: \u65b0\u8282\u70b9\u7684\u6570\u636e position: \u63d2\u5165\u7684\u4f4d\u7f6e Returns: Node: \u5934\u8282\u70b9 \"\"\" new_node = Node ( data ) # \u521b\u5efa\u65b0\u7684\u8282\u70b9\u5bf9\u8c61 if position == 0 : # \u5982\u679c\u63d2\u5165\u4f4d\u7f6e\u4e3a0\uff0c\u5373\u5728\u5934\u90e8\u63d2\u5165 new_node . next = head # \u65b0\u8282\u70b9\u7684next\u6307\u5411\u5f53\u524d\u5934\u8282\u70b9 return new_node # \u8fd4\u56de\u65b0\u7684\u5934\u8282\u70b9 probe = head # \u521b\u5efa\u4e00\u4e2a\u6307\u9488\uff0c\u4ece\u5934\u8282\u70b9\u5f00\u59cb\u904d\u5386\u94fe\u8868 count = 0 while probe . next is not None and count < position - 1 : # \u627e\u5230\u63d2\u5165\u4f4d\u7f6e\u7684\u524d\u4e00\u4e2a\u8282\u70b9 probe = probe . next count += 1 new_node . next = probe . next # \u65b0\u8282\u70b9\u7684next\u6307\u5411\u63d2\u5165\u4f4d\u7f6e\u7684\u8282\u70b9 probe . next = new_node # \u63d2\u5165\u4f4d\u7f6e\u7684\u524d\u4e00\u4e2a\u8282\u70b9\u7684next\u6307\u5411\u65b0\u8282\u70b9 return head # \u8fd4\u56de\u5934\u8282\u70b9 def delete_at_position ( head , position ): \"\"\" \u4ece\u94fe\u8868\u7684\u4efb\u610f\u4f4d\u7f6e\u5220\u9664\u8282\u70b9 Args: head: \u5f53\u524d\u94fe\u8868\u7684\u5934\u8282\u70b9 position: \u5220\u9664\u7684\u4f4d\u7f6e Returns: Node: \u5934\u8282\u70b9 \"\"\" if head is None : # \u5982\u679c\u94fe\u8868\u4e3a\u7a7a\uff0c\u8fd4\u56deNone return None if position == 0 : # \u5982\u679c\u5220\u9664\u4f4d\u7f6e\u4e3a0\uff0c\u5373\u5220\u9664\u5934\u90e8\u8282\u70b9 return head . next # \u8fd4\u56de\u5934\u8282\u70b9\u7684\u4e0b\u4e00\u4e2a\u8282\u70b9 probe = head # \u521b\u5efa\u4e00\u4e2a\u6307\u9488\uff0c\u4ece\u5934\u8282\u70b9\u5f00\u59cb\u904d\u5386\u94fe\u8868 count = 0 while probe . next is not None and count < position - 1 : # \u627e\u5230\u5220\u9664\u4f4d\u7f6e\u7684\u524d\u4e00\u4e2a\u8282\u70b9 probe = probe . next count += 1 if probe . next is None : # \u5982\u679c\u5220\u9664\u4f4d\u7f6e\u8d85\u8fc7\u94fe\u8868\u957f\u5ea6\uff0c\u4e0d\u505a\u64cd\u4f5c return head probe . next = probe . next . next # \u5220\u9664\u4f4d\u7f6e\u7684\u524d\u4e00\u4e2a\u8282\u70b9\u7684next\u6307\u5411\u5220\u9664\u4f4d\u7f6e\u7684\u540e\u4e00\u4e2a\u8282\u70b9 return head # \u8fd4\u56de\u5934\u8282\u70b9 def print_linked_list ( head ): \"\"\" \u6253\u5370\u94fe\u8868\u4e2d\u7684\u6240\u6709\u8282\u70b9 Args: head: \u5f53\u524d\u94fe\u8868\u7684\u5934\u8282\u70b9 \"\"\" probe = head while probe is not None : print ( probe . data , end = \" -> \" ) # \u6253\u5370\u5f53\u524d\u8282\u70b9\u7684\u6570\u636e probe = probe . next # \u79fb\u52a8\u5230\u4e0b\u4e00\u4e2a\u8282\u70b9 print ( \"None\" ) # \u6253\u5370\u94fe\u8868\u7ed3\u675f\u7684\u6807\u5fd7 def main (): head = None # \u521b\u5efa\u4e00\u4e2a\u7a7a\u94fe\u8868\uff0c\u521d\u59cb\u65f6\u5934\u8282\u70b9\u4e3aNone # \u4ece\u5c3e\u90e8\u63d2\u5165\u8282\u70b9 for count in range ( 1 , 6 ): # \u4ece1\u52305\u904d\u5386 head = insert_at_end ( head , count ) # \u5728\u5c3e\u90e8\u63d2\u5165\u8282\u70b9 print ( \"\u521d\u59cb\u94fe\u8868:\" ) print_linked_list ( head ) # \u6253\u5370\u539f\u59cb\u94fe\u8868 # \u9a8c\u8bc1\u4ece\u5934\u90e8\u5904\u63d2\u5165\u8282\u70b9 new_data_at_beginning = 0 head = insert_at_beginning ( head , new_data_at_beginning ) # \u5728\u94fe\u8868\u5934\u90e8\u63d2\u5165\u65b0\u8282\u70b9 print ( f \" \\n \u5728\u5934\u90e8\u63d2\u5165 { new_data_at_beginning } \u540e\u7684\u94fe\u8868:\" ) print_linked_list ( head ) # \u6253\u5370\u63d2\u5165\u65b0\u8282\u70b9\u540e\u7684\u94fe\u8868\u72b6\u6001 # \u9a8c\u8bc1\u4ece\u672b\u5c3e\u5904\u63d2\u5165\u8282\u70b9 new_data = 10 head = insert_at_end ( head , new_data ) # \u5728\u94fe\u8868\u672b\u5c3e\u63d2\u5165\u65b0\u8282\u70b9 print ( f \" \\n \u5728\u5c3e\u90e8\u63d2\u5165 { new_data } \u540e\u7684\u94fe\u8868:\" ) print_linked_list ( head ) # \u6253\u5370\u63d2\u5165\u65b0\u8282\u70b9\u540e\u7684\u94fe\u8868\u72b6\u6001 # \u9a8c\u8bc1\u4ece\u5934\u90e8\u5220\u9664\u8282\u70b9 head = delete_at_beginning ( head ) # \u5220\u9664\u7b2c\u4e00\u4e2a\u8282\u70b9 print ( \" \\n \u4ece\u5934\u90e8\u5220\u9664\u8282\u70b9\u540e\u7684\u94fe\u8868:\" ) print_linked_list ( head ) # \u6253\u5370\u5220\u9664\u8282\u70b9\u540e\u7684\u94fe\u8868\u72b6\u6001 # \u9a8c\u8bc1\u4ece\u5c3e\u90e8\u5220\u9664\u8282\u70b9 head = delete_at_end ( head ) # \u4ece\u94fe\u8868\u672b\u5c3e\u5220\u9664\u8282\u70b9 print ( \" \\n \u4ece\u5c3e\u90e8\u5220\u9664\u8282\u70b9\u540e\u7684\u94fe\u8868:\" ) print_linked_list ( head ) # \u6253\u5370\u5220\u9664\u8282\u70b9\u540e\u7684\u94fe\u8868\u72b6\u6001 # \u9a8c\u8bc1\u4ece\u4efb\u610f\u4f4d\u7f6e\u63d2\u5165\u8282\u70b9 position = 3 new_data = 99 head = insert_at_position ( head , new_data , position ) # \u5728\u7b2c3\u4e2a\u4f4d\u7f6e\u63d2\u5165\u8282\u70b9 print ( f \" \\n \u5728\u4f4d\u7f6e { position } \u63d2\u5165 { new_data } \u540e\u7684\u94fe\u8868:\" ) print_linked_list ( head ) # \u9a8c\u8bc1\u4ece\u4efb\u610f\u4f4d\u7f6e\u5220\u9664\u8282\u70b9 position = 2 head = delete_at_position ( head , position ) # \u5220\u9664\u7b2c2\u4e2a\u4f4d\u7f6e\u7684\u8282\u70b9 print ( f \" \\n \u5728\u4f4d\u7f6e { position } \u63d2\u5165 { new_data } \u540e\u7684\u94fe\u8868:\" ) print_linked_list ( head ) if __name__ == \"__main__\" : main () # \u8fd0\u884c\u7ed3\u679c # \u521d\u59cb\u94fe\u8868: # 1 -> 2 -> 3 -> 4 -> 5 -> None # \u5728\u5934\u90e8\u63d2\u5165 0 \u540e\u7684\u94fe\u8868: # 0 -> 1 -> 2 -> 3 -> 4 -> 5 -> None # \u5728\u5c3e\u90e8\u63d2\u5165 10 \u540e\u7684\u94fe\u8868: # 0 -> 1 -> 2 -> 3 -> 4 -> 5 -> 10 -> None # \u4ece\u5934\u90e8\u5220\u9664\u8282\u70b9\u540e\u7684\u94fe\u8868: # 1 -> 2 -> 3 -> 4 -> 5 -> 10 -> None # \u4ece\u5c3e\u90e8\u5220\u9664\u8282\u70b9\u540e\u7684\u94fe\u8868: # 1 -> 2 -> 3 -> 4 -> 5 -> None # \u5728\u4f4d\u7f6e 3 \u63d2\u5165 99 \u540e\u7684\u94fe\u8868: # 1 -> 2 -> 3 -> 99 -> 4 -> 5 -> None # \u5728\u4f4d\u7f6e 2 \u63d2\u5165 99 \u540e\u7684\u94fe\u8868: # 1 -> 2 -> 99 -> 4 -> 5 -> None","title":"4.5.4.\u5728\u5f00\u59cb\u5904\u63d2\u5165"},{"location":"python/DataStructure/04_ArrayChain/#455","text":"\u5bf9\u4e8e\u5355\u5411\u94fe\u63a5\u7ed3\u6784\uff0c\u5728\u7ed3\u5c3e\u5904\u63d2\u5165\u65f6\u9700\u8981\u8003\u8651\u4e24\u79cd\u60c5\u51b5\uff1a \u5f53 head \u6307\u9488\u662f None \u65f6\uff0c\u5b83\u4f1a\u88ab\u8bbe\u7f6e\u4e3a\u65b0\u8282\u70b9\u3002 \u5f53 head \u6307\u9488\u4e0d\u662f None \u65f6\uff0c\u4ee3\u7801\u4f1a\u627e\u5230\u6700\u540e\u4e00\u4e2a\u8282\u70b9\uff0c\u5e76\u628a\u5b83\u7684\u4e0b\u4e00\u4e2a\u6307\u9488\u6307\u5411\u65b0\u8282\u70b9\u3002 \u56e0\u6b64\u5728\u6709\u6570\u636e\u7684\u60c5\u51b5\u4e0b\uff0c\u4f1a\u7528\u5230\u904d\u5386\u6a21\u5f0f\u3002","title":"4.5.5.\u5728\u7ed3\u5c3e\u5904\u63d2\u5165"},{"location":"python/DataStructure/04_ArrayChain/#456","text":"\u5728\u6267\u884c\u4ece\u94fe\u63a5\u7ed3\u6784\u7684\u5f00\u5934\u5220\u9664\u5143\u7d20\u7684\u64cd\u4f5c\u65f6\uff0c\u901a\u5e38\u90fd\u4f1a\u5047\u5b9a\u7ed3\u6784\u91cc\u81f3\u5c11\u5b58\u5728\u4e00\u4e2a\u8282\u70b9\uff0c\u8fd9\u4e2a\u64cd\u4f5c\u5c06\u8fd4\u56de\u88ab\u5220\u9664\u7684\u5143\u7d20\u3002 \u8fd9\u4e2a\u64cd\u4f5c\u4f1a\u7528\u5230\u5e38\u6570\u7684\u65f6\u95f4\u548c\u5185\u5b58\uff0c\u8fd9\u4e0e\u5728\u6570\u7ec4\u4e0a\u6267\u884c\u76f8\u540c\u7684\u64cd\u4f5c\u662f\u6709\u6240\u4e0d\u540c\u7684\u3002","title":"4.5.6.\u5728\u5f00\u59cb\u5904\u5220\u9664"},{"location":"python/DataStructure/04_ArrayChain/#457","text":"\u5355\u5411\u94fe\u63a5\u7ed3\u6784\u4e2d\u7684\u8fd9\u4e2a\u64cd\u4f5c\u5047\u5b9a\u5728\u7ed3\u6784\u91cc\u81f3\u5c11\u6709\u4e00\u4e2a\u8282\u70b9\uff0c\u8fd9\u6837\u5c31\u6709\u4e24\u79cd\u60c5\u51b5\u9700\u8981\u8003\u8651\u3002 \u53ea\u6709\u4e00\u4e2a\u8282\u70b9\uff0c\u8fd9\u65f6\u53ea\u9700\u8981\u628ahead\u6307\u9488\u8bbe\u7f6e\u4e3a None \u3002 \u6700\u540e\u4e00\u4e2a\u8282\u70b9\u4e4b\u524d\u8fd8\u6709\u4e00\u4e2a\u8282\u70b9\u3002\u8fd9\u65f6\u76f8\u5e94\u7684\u4ee3\u7801\u4f1a\u627e\u5230\u5012\u6570\u7b2c\u4e8c\u4e2a\u8282\u70b9\uff0c\u5e76\u628a\u4e0b\u4e00\u4e2a\u6307\u9488\u8bbe\u7f6e\u4e3a None \u3002 \u65e0\u8bba\u662f\u54ea\u79cd\u60c5\u51b5\uff0c\u4ee3\u7801\u90fd\u4f1a\u8fd4\u56de\u8fd9\u4e2a\u88ab\u5220\u9664\u8282\u70b9\u91cc\u5305\u542b\u7684\u6570\u636e\u5143\u7d20\u3002 \u8fd9\u4e2a\u64cd\u4f5c\u4f1a\u7528\u5230\u5e38\u6570\u7684\u65f6\u95f4\u548c\u5185\u5b58\u3002","title":"4.5.7.\u5728\u7ed3\u5c3e\u5904\u5220\u9664"},{"location":"python/DataStructure/04_ArrayChain/#458","text":"\u5728\u94fe\u63a5\u7ed3\u6784\u7684\u4efb\u610f\u4f4d\u7f6e\u63d2\u5165\u5143\u7d20\u65f6\u9700\u8981\u8003\u86512\u79cd\u60c5\u51b5\uff1a \u5728\u5f00\u5934\u63d2\u5165\uff0c\u53ef\u4ee5\u7528\u524d\u9762\u63d0\u5230\u7684\u4ee3\u7801\u3002 \u5728\u5176\u4ed6\u4f4d\u7f6e i \u5904\u8981\u8fdb\u884c\u63d2\u5165\uff0c\u63d2\u5165\u64cd\u4f5c\u5fc5\u987b\u8981\u5148\u627e\u5230\u4f4d\u7f6e i-1 \uff08\u5982\u679c i=n \uff09\u5904\u7684\u8282\u70b9\u3002\u8fd9\u6837\uff0c\u5c31\u6709\u4e24\u79cd\u60c5\u51b5\u9700\u8981\u8003\u8651\u3002 \u8fd9\u4e2a\u8282\u70b9\u540e\u9762\u7684\u6307\u9488\u662f None \u3002\u8fd9\u610f\u5473\u7740 i>=n \uff0c\u56e0\u6b64\u5e94\u8be5\u628a\u65b0\u7684\u5143\u7d20\u653e\u5728\u94fe\u63a5\u7ed3\u6784\u7684\u672b\u5c3e\u3002 \u8fd9\u4e2a\u8282\u70b9\u540e\u9762\u7684\u6307\u9488\u4e0d\u662fNone\u3002\u8fd9\u610f\u5473\u7740 0=n \u2014\u2014\u5220\u9664\u6700\u540e\u4e00\u4e2a\u8282\u70b9\u3002 \u5047\u8bbe\u5728\u94fe\u63a5\u7ed3\u6784\u91cc\u81f3\u5c11\u6709\u4e00\u4e2a\u8282\u70b9\u3002\u8fd9\u4e2a\u64cd\u4f5c\u7684\u6a21\u5f0f\u548c\u63d2\u5165\u64cd\u4f5c\u7684\u6a21\u5f0f\u662f\u7c7b\u4f3c\u7684\uff0c\u56e0\u6b64\u4e5f\u8981\u907f\u514d\u5728\u641c\u7d22\u8fc7\u7a0b\u4e2d\u8d85\u51fa\u94fe\u63a5\u7ed3\u6784\u7684\u672b\u5c3e\u3002\u4f46\u662f\u5728\u8fd9\u4e2a\u8fc7\u7a0b\u4e2d\uff0c\u4f60\u5fc5\u987b\u5141\u8bb8probe\u6307\u9488\u53ef\u4ee5\u8bbf\u95ee\u5230\u94fe\u63a5\u7ed3\u6784\u7684\u5012\u6570\u7b2c\u4e8c\u4e2a\u8282\u70b9\u3002","title":"4.5.9.\u5728\u4efb\u610f\u4f4d\u7f6e\u5904\u5220\u9664"},{"location":"python/DataStructure/04_ArrayChain/#4510","text":"\u5355\u5411\u94fe\u63a5\u7ed3\u6784\u5404\u9879\u64cd\u4f5c\u7684\u8fd0\u884c\u65f6\u590d\u6742\u5ea6 \u64cd\u4f5c \u8fd0\u884c\u65f6\u590d\u6742\u5ea6 \u5728\u4f4d\u7f6ei\u5904\u8bbf\u95ee O(n)\uff0c\uff0c\u5e73\u5747\u60c5\u51b5\u4e0b \u5728\u4f4d\u7f6ei\u5904\u66ff\u6362 O(n)\uff0c\u6700\u597d\u548c\u6700\u574f\u60c5\u51b5\u4e0b \u5728\u5f00\u59cb\u5904\u63d2\u5165 O(1)\uff0c\u6700\u597d\u548c\u6700\u574f\u60c5\u51b5\u4e0b \u5728\u5f00\u59cb\u5904\u5220\u9664 O(1)\uff0c\u6700\u597d\u548c\u6700\u574f\u60c5\u51b5\u4e0b \u5728\u4f4d\u7f6ei\u5904\u63d2\u5165 O(n)\uff0c\u5e73\u5747\u60c5\u51b5\u4e0b \u5728\u4f4d\u7f6ei\u5904\u5220\u9664 O(n)\uff0c\u5e73\u5747\u60c5\u51b5\u4e0b \u4e0e\u6570\u7ec4\u76f8\u6bd4\uff0c\u5355\u5411\u94fe\u63a5\u7ed3\u6784\u7684\u4e3b\u8981\u4f18\u52bf\u5e76\u4e0d\u5728\u4e8e\u65f6\u95f4\u590d\u6742\u5ea6\u800c\u5728\u4e8e\u5185\u5b58\u6027\u80fd\u3002 \u8c03\u6574\u6570\u7ec4\u5c3a\u5bf8\uff08\u5728\u9700\u8981\u7684\u65f6\u5019\u6267\u884c\uff09\uff0c\u4f7f\u5176\u5728\u65f6\u95f4\u548c\u5185\u5b58\u4e0a\u90fd\u662f\u7ebf\u6027\u7684\uff1b\u8c03\u6574\u94fe\u63a5\u7ed3\u6784\u7684\u5927\u5c0f\uff08\u4f1a\u5728\u63d2\u5165\u6216\u5220\u9664\u65f6\u53d1\u751f\uff09\u5728\u65f6\u95f4\u548c\u5185\u5b58\u4e0a\u90fd\u662f\u5e38\u6570\u590d\u6742\u5ea6\u3002 \u5728\u94fe\u63a5\u7ed3\u6784\u91cc\uff0c\u4e0d\u4f1a\u6709\u5185\u5b58\u7684\u6d6a\u8d39\uff0c\u56e0\u4e3a\u8fd9\u4e2a\u7ed3\u6784\u7684\u7269\u7406\u5c3a\u5bf8\u6c38\u8fdc\u90fd\u4e0d\u4f1a\u8d85\u8fc7\u903b\u8f91\u5c3a\u5bf8\u3002 \u94fe\u63a5\u7ed3\u6784\u7684\u786e\u4f1a\u4ea7\u751f\u4e00\u4e9b\u989d\u5916\u7684\u5185\u5b58\u5f00\u9500\uff0c\u8fd9\u662f\u56e0\u4e3a\u5355\u5411\u94fe\u63a5\u7ed3\u6784\u5fc5\u987b\u8981\u6709\u989d\u5916\u7684 n \u4e2a\u5185\u5b58\u5355\u5143\u6765\u5b58\u50a8\u6307\u9488\u3002 \u5bf9\u4e8e\u53cc\u5411\u94fe\u63a5\u7ed3\u6784\u6765\u8bf4\uff0c\u5b83\u7684\u8282\u70b9\u91cc\u5305\u542b\u4e24\u4e2a\u94fe\u63a5\uff0c\u56e0\u6b64\u5185\u5b58\u7684\u6210\u672c\u4f1a\u66f4\u9ad8\u4e00\u4e9b\u3002","title":"4.5.10.\u590d\u6742\u5ea6\u7684\u6743\u8861\uff1a\u65f6\u95f4\u3001\u7a7a\u95f4\u548c\u5355\u5411\u94fe\u63a5\u7ed3\u6784"},{"location":"python/DataStructure/04_ArrayChain/#4511","text":"1\uff0e\u5047\u8bbe\u5df2\u7ecf\u627e\u5230\u4e86\u4ece\u5355\u5411\u94fe\u63a5\u7ed3\u6784\u91cc\u5220\u9664\u5143\u7d20\u7684\u4f4d\u7f6e\uff0c\u8bf7\u8bf4\u660e\u4ece\u8fd9\u4e2a\u65f6\u5019\u5f00\u59cb\u5b8c\u6210\u5220\u9664\u64cd\u4f5c\u7684\u8fd0\u884c\u65f6\u590d\u6742\u5ea6\u3002 \u89e3\u7b54\uff1a\u5982\u679c\u5df2\u7ecf\u627e\u5230\u4e86\u5355\u5411\u94fe\u8868\u4e2d\u8981\u5220\u9664\u5143\u7d20\u7684\u4f4d\u7f6e\uff0c\u5220\u9664\u64cd\u4f5c\u7684\u8fd0\u884c\u65f6\u590d\u6742\u5ea6\u53d6\u51b3\u4e8e\u5220\u9664\u64cd\u4f5c\u7684\u5177\u4f53\u5b9e\u73b0\u3002\u5728\u5355\u5411\u94fe\u8868\u4e2d\uff0c\u5220\u9664\u4e00\u4e2a\u8282\u70b9\u901a\u5e38\u9700\u8981\u627e\u5230\u5f85\u5220\u9664\u8282\u70b9\u7684\u524d\u9a71\u8282\u70b9\uff0c\u7136\u540e\u5c06\u524d\u9a71\u8282\u70b9\u7684 next \u6307\u9488\u6307\u5411\u5f85\u5220\u9664\u8282\u70b9\u7684\u4e0b\u4e00\u4e2a\u8282\u70b9\uff0c\u4ece\u800c\u5c06\u5f85\u5220\u9664\u8282\u70b9\u4ece\u94fe\u8868\u4e2d\u79fb\u9664\u3002 \u67e5\u627e\u5f85\u5220\u9664\u8282\u70b9\u7684\u65f6\u95f4\u590d\u6742\u5ea6\uff1a\u5728\u6700\u574f\u60c5\u51b5\u4e0b\uff0c\u5982\u679c\u8981\u5220\u9664\u7684\u8282\u70b9\u4f4d\u4e8e\u94fe\u8868\u7684\u672b\u5c3e\uff0c\u6216\u8005\u9700\u8981\u904d\u5386\u6574\u4e2a\u94fe\u8868\u624d\u80fd\u627e\u5230\u5f85\u5220\u9664\u8282\u70b9\uff0c\u67e5\u627e\u64cd\u4f5c\u7684\u65f6\u95f4\u590d\u6742\u5ea6\u4e3aO(n)\uff0c\u5176\u4e2dn\u662f\u94fe\u8868\u7684\u957f\u5ea6\u3002 \u5220\u9664\u8282\u70b9\u7684\u65f6\u95f4\u590d\u6742\u5ea6\uff1a\u5220\u9664\u8282\u70b9\u7684\u64cd\u4f5c\u662f\u5e38\u6570\u65f6\u95f4O(1)\uff0c\u56e0\u4e3a\u5b83\u6d89\u53ca\u7684\u64cd\u4f5c\u90fd\u662f\u57fa\u672c\u7684\u8d4b\u503c\u548c\u6307\u9488\u8c03\u6574\u3002 \u6240\u4ee5\uff0c\u5982\u679c\u5df2\u7ecf\u627e\u5230\u4e86\u5f85\u5220\u9664\u8282\u70b9\u7684\u4f4d\u7f6e\uff0c\u5220\u9664\u64cd\u4f5c\u7684\u8fd0\u884c\u65f6\u590d\u6742\u5ea6\u662fO(n)\u3002 2\uff0e\u53ef\u4ee5\u5bf9\u5355\u5411\u94fe\u63a5\u7ed3\u6784\u91cc\u6309\u987a\u5e8f\u6392\u5217\u7684\u5143\u7d20\u6267\u884c\u4e8c\u5206\u641c\u7d22\u5417\uff1f\u5982\u679c\u4e0d\u53ef\u4ee5\uff0c\u4e3a\u4ec0\u4e48\uff1f \u89e3\u7b54\uff1a\u5728\u666e\u901a\u7684\u5355\u5411\u94fe\u8868\u4e2d\uff0c\u65e0\u6cd5\u76f4\u63a5\u6267\u884c\u4e8c\u5206\u641c\u7d22\u3002\u4e8c\u5206\u641c\u7d22\u901a\u5e38\u57fa\u4e8e\u6570\u7ec4\u8fd9\u79cd\u8fde\u7eed\u5b58\u50a8\u7ed3\u6784\uff0c\u53ef\u4ee5\u76f4\u63a5\u901a\u8fc7\u7d22\u5f15\u8fdb\u884c\u5feb\u901f\u8bbf\u95ee\u3002\u4f46\u5728\u5355\u5411\u94fe\u8868\u4e2d\uff0c\u8981\u67e5\u627e\u4e2d\u95f4\u5143\u7d20\uff0c\u9700\u8981\u904d\u5386\u94fe\u8868\u4ee5\u627e\u5230\u4e2d\u95f4\u4f4d\u7f6e\u3002\u56e0\u4e3a\u94fe\u8868\u7684\u5143\u7d20\u4e0d\u662f\u6309\u7167\u7d22\u5f15\u6392\u5217\u7684\uff0c\u6240\u4ee5\u4e0d\u80fd\u76f4\u63a5\u8fdb\u884c\u4e8c\u5206\u641c\u7d22\u3002 \u5982\u679c\u5e0c\u671b\u5728\u6709\u5e8f\u94fe\u8868\u4e2d\u6267\u884c\u4e8c\u5206\u641c\u7d22\uff0c\u53ef\u4ee5\u8003\u8651\u4f7f\u7528\u53e6\u4e00\u79cd\u6570\u636e\u7ed3\u6784\u2014\u2014\u4e8c\u53c9\u641c\u7d22\u6811\uff08Binary Search Tree\uff09\u3002\u5728\u4e8c\u53c9\u641c\u7d22\u6811\u4e2d\uff0c\u6bcf\u4e2a\u8282\u70b9\u7684\u5de6\u5b50\u6811\u7684\u503c\u5c0f\u4e8e\u8be5\u8282\u70b9\u7684\u503c\uff0c\u53f3\u5b50\u6811\u7684\u503c\u5927\u4e8e\u8be5\u8282\u70b9\u7684\u503c\uff0c\u56e0\u6b64\u53ef\u4ee5\u5229\u7528\u8fd9\u79cd\u6709\u5e8f\u6027\u8fdb\u884c\u5feb\u901f\u641c\u7d22\u3002 3\uff0e\u8bf7\u8bf4\u660e\u4e3a\u4ec0\u4e48Python\u5217\u8868\u4f1a\u4f7f\u7528\u6570\u7ec4\u800c\u4e0d\u662f\u94fe\u63a5\u7ed3\u6784\u6765\u4fdd\u5b58\u5b83\u7684\u5143\u7d20\u3002 \u89e3\u7b54\uff1aPython\u7684\u5217\u8868\u4f7f\u7528\u6570\u7ec4\u800c\u4e0d\u662f\u94fe\u63a5\u7ed3\u6784\u6765\u4fdd\u5b58\u5143\u7d20\uff0c\u4e3b\u8981\u662f\u56e0\u4e3a\u6570\u7ec4\u5728\u968f\u673a\u8bbf\u95ee\uff08\u6839\u636e\u7d22\u5f15\u76f4\u63a5\u8bbf\u95ee\u5143\u7d20\uff09\u548c\u5207\u7247\uff08\u901a\u8fc7[start:stop:step]\u65b9\u5f0f\u622a\u53d6\u5b50\u5217\u8868\uff09\u64cd\u4f5c\u4e0a\u5177\u6709\u66f4\u597d\u7684\u6027\u80fd\u3002\u6570\u7ec4\u7684\u5185\u5b58\u7a7a\u95f4\u662f\u8fde\u7eed\u7684\uff0c\u56e0\u6b64\u53ef\u4ee5\u901a\u8fc7\u7d22\u5f15\u8fc5\u901f\u8ba1\u7b97\u51fa\u5143\u7d20\u7684\u5185\u5b58\u5730\u5740\u3002\u8fd9\u4f7f\u5f97\u968f\u673a\u8bbf\u95ee\u548c\u5207\u7247\u7684\u65f6\u95f4\u590d\u6742\u5ea6\u662fO(1)\uff0c\u5373\u5e38\u6570\u65f6\u95f4\u3002\u800c\u94fe\u63a5\u7ed3\u6784\u5728\u968f\u673a\u8bbf\u95ee\u4e0a\u7684\u65f6\u95f4\u590d\u6742\u5ea6\u901a\u5e38\u662fO(n)\uff0c\u5176\u4e2dn\u662f\u94fe\u8868\u7684\u957f\u5ea6\uff0c\u56e0\u4e3a\u9700\u8981\u4ece\u5934\u8282\u70b9\u5f00\u59cb\u9010\u4e2a\u904d\u5386\u627e\u5230\u76ee\u6807\u8282\u70b9\u3002 \u5728Python\u7684\u5217\u8868\u4e2d\uff0c\u652f\u6301\u901a\u8fc7\u7d22\u5f15\u968f\u673a\u8bbf\u95ee\u5143\u7d20\uff0c\u8fd9\u662f\u56e0\u4e3a\u5217\u8868\u7684\u5143\u7d20\u662f\u4fdd\u5b58\u5728\u4e00\u4e2a\u8fde\u7eed\u7684\u5185\u5b58\u5757\u4e2d\u7684\u3002\u8fd9\u79cd\u8bbe\u8ba1\u4f7f\u5f97Python\u7684\u5217\u8868\u5728\u5927\u591a\u6570\u5e38\u89c1\u64cd\u4f5c\uff08\u4f8b\u5982\u67e5\u627e\u3001\u63d2\u5165\u3001\u5220\u9664\uff09\u4e0a\u90fd\u80fd\u63d0\u4f9b\u8f83\u597d\u7684\u6027\u80fd\uff0c\u7279\u522b\u662f\u5f53\u9700\u8981\u901a\u8fc7\u7d22\u5f15\u6216\u5207\u7247\u5feb\u901f\u8bbf\u95ee\u6216\u4fee\u6539\u5143\u7d20\u65f6\u3002\u7136\u800c\uff0c\u5bf9\u4e8e\u5728\u4e2d\u95f4\u63d2\u5165\u6216\u5220\u9664\u5143\u7d20\u8fd9\u6837\u7684\u64cd\u4f5c\uff0c\u5217\u8868\u7684\u6027\u80fd\u53ef\u80fd\u76f8\u5bf9\u8f83\u4f4e\uff0c\u56e0\u4e3a\u5728\u6570\u7ec4\u4e2d\u95f4\u63d2\u5165\u6216\u5220\u9664\u5143\u7d20\u901a\u5e38\u9700\u8981\u79fb\u52a8\u5176\u4ed6\u5143\u7d20\uff0c\u5bfc\u81f4\u65f6\u95f4\u590d\u6742\u5ea6\u4e3aO(n)\u3002 \u603b\u7684\u6765\u8bf4\uff0cPython\u7684\u5217\u8868\u91c7\u7528\u6570\u7ec4\u5b58\u50a8\u5143\u7d20\uff0c\u662f\u4e3a\u4e86\u5728\u5927\u591a\u6570\u5e38\u89c1\u64cd\u4f5c\u4e2d\u63d0\u4f9b\u8f83\u597d\u7684\u6027\u80fd\u3002\u5982\u679c\u9700\u8981\u5728\u4e2d\u95f4\u63d2\u5165\u6216\u5220\u9664\u5143\u7d20\u7684\u64cd\u4f5c\u6bd4\u8f83\u9891\u7e41\uff0c\u53ef\u80fd\u9700\u8981\u8003\u8651\u4f7f\u7528\u94fe\u8868\u7b49\u6570\u636e\u7ed3\u6784\u3002Python\u4e2d\u7684 collections \u6a21\u5757\u63d0\u4f9b\u4e86 deque \uff08\u53cc\u7aef\u961f\u5217\uff09\u7b49\u6570\u636e\u7ed3\u6784\uff0c\u53ef\u4ee5\u7528\u4e8e\u5728\u4e24\u7aef\u9ad8\u6548\u5730\u8fdb\u884c\u63d2\u5165\u548c\u5220\u9664\u64cd\u4f5c\u3002 \u8865\u5145\uff1a \u67e5\u770b\u6e90\u4ee3\u7801\u7684\u65b9\u6cd5\u3002 import array import inspect # \u83b7\u53d6array\u6a21\u5757\u7684\u6e90\u4ee3\u7801 source_code = inspect . getsource ( array ) # \u6253\u5370\u6e90\u4ee3\u7801 print ( source_code ) \u5bf9\u4e8e\u5185\u7f6e\u7684\u6a21\u5757\uff0c\u4e0d\u80fd\u76f4\u63a5\u901a\u8fc7inspect\u6a21\u5757\u67e5\u770b\u6e90\u4ee3\u7801\u3002\u53ef\u4ee5\u901a\u8fc7\u5728\u7ebf\u67e5\u770bPython\u7684\u6e90\u4ee3\u7801\u3002Python\u7684\u6e90\u4ee3\u7801\u6258\u7ba1\u5728GitHub\u4e0a\uff0c\u4f60\u53ef\u4ee5\u5728\u4ee5\u4e0b\u94fe\u63a5\u4e2d\u627e\u5230Python\u7684\u6e90\u4ee3\u7801\uff1a Python GitHub Repository \uff0c\u5305\u62ec array\u7684\u6e90\u4ee3\u7801 \u3002","title":"4.5.11.\u7ec3\u4e60\u9898"},{"location":"python/DataStructure/04_ArrayChain/#46","text":"","title":"4.6.\u94fe\u63a5\u4e0a\u7684\u53d8\u5316"},{"location":"python/DataStructure/04_ArrayChain/#461","text":"\u5728\u7b2c\u4e00\u4e2a\u8282\u70b9\u4f4d\u7f6e\u5904\u6267\u884c\u63d2\u5165\u548c\u5220\u9664\u64cd\u4f5c\u662f\u5355\u5411\u94fe\u63a5\u7ed3\u6784\u91cc\u5728\u4efb\u610f\u4f4d\u7f6e\u8fdb\u884c\u63d2\u5165\u548c\u5220\u9664\u64cd\u4f5c\u7684\u7279\u6b8a\u60c5\u51b5\uff0c\u662f\u56e0\u4e3a\u8fd9\u4e2a\u65f6\u5019\u5fc5\u987b\u91cd\u7f6ehead\u6307\u9488\u3002 \u53ef\u4ee5\u901a\u8fc7\u5305\u542b\u865a\u62df\u5934\u8282\u70b9\uff08dummy header node\uff09\u7684\u73af\u72b6\u94fe\u63a5\u7ed3\u6784\uff08circular linked structure\uff09\u7b80\u5316\u8fd9\u4e24\u4e2a\u64cd\u4f5c\u3002 \u73af\u72b6\u94fe\u63a5\u7ed3\u6784\u5305\u542b\u4e86\u4ece\u6700\u540e\u4e00\u4e2a\u8282\u70b9\u5230\u7b2c\u4e00\u4e2a\u8282\u70b9\u7684\u94fe\u63a5\uff0c\u5e76\u4e14\u5b83\u7684\u5b9e\u73b0\u91cc\u81f3\u5c11\u4f1a\u5305\u542b\u4e00\u4e2a\u8282\u70b9\u3002\u8fd9\u4e2a\u8282\u70b9\uff08\u865a\u62df\u5934\u8282\u70b9\uff09\u4e0d\u5305\u542b\u4efb\u4f55\u6570\u636e\uff0c\u4f46\u4f1a\u88ab\u7528\u6765\u4f5c\u4e3a\u94fe\u63a5\u7ed3\u6784\u7684\u5f00\u59cb\u548c\u7ed3\u675f\u7684\u6807\u8bb0\u3002\u5728\u6700\u521d\u7684\u7a7a\u94fe\u63a5\u7ed3\u6784\u91cc\uff0chead\u53d8\u91cf\u4f1a\u6307\u5411\u865a\u62df\u5934\u8282\u70b9\uff0c\u800c\u865a\u62df\u5934\u8282\u70b9\u7684\u4e0b\u4e00\u4e2a\u6307\u9488\u4f1a\u6307\u5411\u865a\u62df\u5934\u8282\u70b9\u672c\u8eab\u3002\u5982\u4e0b\u56fe\u6240\u793a\u3002","title":"4.6.1.\u5305\u542b\u865a\u62df\u5934\u8282\u70b9\u7684\u73af\u72b6\u94fe\u63a5\u7ed3\u6784"},{"location":"python/DataStructure/04_ArrayChain/#462","text":"","title":"4.6.2.\u53cc\u5411\u94fe\u63a5\u7ed3\u6784"},{"location":"python/DataStructure/04_ArrayChain/#463","text":"1\uff0e\u5305\u542b\u865a\u62df\u5934\u8282\u70b9\u7684\u73af\u72b6\u94fe\u63a5\u7ed3\u6784\u7ed9\u7a0b\u5e8f\u5458\u5e26\u6765\u4e86\u4ec0\u4e48\u597d\u5904\uff1f 2\uff0e\u548c\u5355\u5411\u94fe\u63a5\u7ed3\u6784\u76f8\u6bd4\uff0c\u8bf7\u63cf\u8ff0\u53cc\u5411\u94fe\u63a5\u7ed3\u6784\u7684\u4e00\u4e2a\u597d\u5904\u548c\u4e00\u4e2a\u989d\u5916\u5f00\u9500\u3002","title":"4.6.3.\u7ec3\u4e60\u9898"},{"location":"python/DataStructure/04_ArrayChain/#47","text":"\u6570\u636e\u7ed3\u6784\u662f\u4e00\u4e2a\u8868\u793a\u591a\u9879\u96c6\u91cc\u6240\u5305\u542b\u6570\u636e\u7684\u5bf9\u8c61\u3002 \u6570\u7ec4\u662f\u4e00\u79cd\u5728\u5e38\u6570\u65f6\u95f4\u5185\u652f\u6301\u5bf9\u4f4d\u7f6e\u9010\u9879\u968f\u673a\u8bbf\u95ee\u7684\u6570\u636e\u7ed3\u6784\u3002\u5728\u521b\u5efa\u6570\u7ec4\u65f6\uff0c\u4f1a\u4e3a\u5b83\u5206\u914d\u82e5\u5e72\u4e2a\u7528\u6765\u5b58\u653e\u6570\u636e\u7684\u5185\u5b58\u7a7a\u95f4\uff0c\u5e76\u4e14\u6570\u7ec4\u7684\u957f\u5ea6\u4f1a\u4fdd\u6301\u4e0d\u53d8\u3002\u63d2\u5165\u548c\u5220\u9664\u64cd\u4f5c\u9700\u8981\u79fb\u52a8\u6570\u636e\u5143\u7d20\uff0c\u5e76\u4e14\u53ef\u80fd\u9700\u8981\u521b\u5efa\u4e00\u4e2a\u65b0\u7684\u3001\u66f4\u5927\u6216\u66f4\u5c0f\u7684\u6570\u7ec4\u3002 \u4e8c\u7ef4\u6570\u7ec4\u91cc\u7684\u6bcf\u4e2a\u6570\u636e\u503c\u90fd\u4f4d\u4e8e\u77e9\u5f62\u7f51\u683c\u7684\u884c\u548c\u5217\u4e0a\u3002 \u94fe\u63a5\u7ed3\u6784\u662f\u75310\u4e2a\u6216\u591a\u4e2a\u8282\u70b9\u7ec4\u6210\u7684\u6570\u636e\u7ed3\u6784\u3002\u6bcf\u4e2a\u8282\u70b9\u90fd\u5305\u542b\u4e00\u4e2a\u6570\u636e\u5143\u7d20\u548c\u4e00\u4e2a\u6216\u591a\u4e2a\u6307\u5411\u5176\u4ed6\u8282\u70b9\u7684\u94fe\u63a5\u3002 \u5355\u5411\u94fe\u63a5\u7ed3\u6784\u7684\u8282\u70b9\u5305\u542b\u6570\u636e\u5143\u7d20\u548c\u5230\u4e0b\u4e00\u4e2a\u8282\u70b9\u7684\u94fe\u63a5\u3002\u53cc\u5411\u94fe\u63a5\u7ed3\u6784\u91cc\u7684\u8282\u70b9\u8fd8\u5305\u542b\u5230\u524d\u4e00\u4e2a\u8282\u70b9\u7684\u94fe\u63a5\u3002 \u5728\u94fe\u63a5\u7ed3\u6784\u91cc\u8fdb\u884c\u63d2\u5165\u6216\u5220\u9664\u64cd\u4f5c\u4e0d\u9700\u8981\u79fb\u52a8\u6570\u636e\u5143\u7d20\uff0c\u6bcf\u6b21\u6700\u591a\u53ea\u4f1a\u521b\u5efa\u4e00\u4e2a\u8282\u70b9\u3002\u4f46\u662f\uff0c\u5728\u94fe\u63a5\u7ed3\u6784\u91cc\u6267\u884c\u63d2\u5165\u3001\u5220\u9664\u548c\u8bbf\u95ee\u64cd\u4f5c\u9700\u8981\u7684\u65f6\u95f4\u590d\u6742\u5ea6\u90fd\u662f\u7ebf\u6027\u7684\u3002 \u5728\u94fe\u63a5\u7ed3\u6784\u91cc\u4f7f\u7528\u5934\u8282\u70b9\u53ef\u4ee5\u7b80\u5316\u67d0\u4e9b\u64cd\u4f5c\uff0c\u5982\u6dfb\u52a0\u6216\u5220\u9664\u5143\u7d20\u3002","title":"4.7.\u5c0f\u7ed3"},{"location":"python/DataStructure/04_ArrayChain/#48","text":"1\uff0e\u6570\u7ec4\u548c\u94fe\u63a5\u7ed3\u6784\u90fd\u662f\uff1a \u62bd\u8c61\u6570\u636e\u7c7b\u578b\uff08ADT\uff09 \u6570\u636e\u7ed3\u6784 2\uff0e\u6570\u7ec4\u7684\u957f\u5ea6\uff1a \u5728\u521b\u5efa\u4e4b\u540e\u5927\u5c0f\u662f\u56fa\u5b9a\u7684 \u5728\u521b\u5efa\u4e4b\u540e\u5927\u5c0f\u53ef\u4ee5\u589e\u52a0\u6216\u51cf\u5c11 3\uff0e\u5728\u6570\u7ec4\u91cc\u8fdb\u884c\u968f\u673a\u8bbf\u95ee\u652f\u6301\u5728\uff1a \u5e38\u6570\u65f6\u95f4\u91cc\u8bbf\u95ee\u6570\u636e \u7ebf\u6027\u65f6\u95f4\u91cc\u8bbf\u95ee\u6570\u636e 4\uff0e\u5355\u5411\u94fe\u63a5\u7ed3\u6784\u91cc\u7684\u6570\u636e\u5305\u542b\u5728\uff1a \u5355\u5143\u91cc \u8282\u70b9\u91cc 5\uff0e\u5bf9\u5355\u5411\u94fe\u63a5\u7ed3\u6784\u6267\u884c\u7684\u5927\u591a\u6570\u64cd\u4f5c\u90fd\u9700\u8981\uff1a \u5e38\u6570\u65f6\u95f4 \u7ebf\u6027\u65f6\u95f4 6\uff0e\u4ece\u4ee5\u4e0b\u54ea\u79cd\u7c7b\u578b\u91cc\u5220\u9664\u7b2c\u4e00\u4e2a\u5143\u7d20\u9700\u8981\u5e38\u6570\u65f6\u95f4\uff1a \u6570\u7ec4 \u5355\u5411\u94fe\u63a5\u7ed3\u6784 7\uff0e\u5728\u4e0b\u9762\u54ea\u79cd\u60c5\u51b5\u4e0b\uff0c\u6570\u7ec4\u91cc\u4f7f\u7528\u7684\u5185\u5b58\u4f1a\u5c11\u4e8e\u5355\u5411\u94fe\u63a5\u7ed3\u6784\u7684\uff1a \u4e0d\u5230\u4e00\u534a\u7684\u4f4d\u7f6e\u653e\u7f6e\u4e86\u6570\u636e \u4e00\u534a\u4ee5\u4e0a\u7684\u4f4d\u7f6e\u653e\u7f6e\u4e86\u6570\u636e 8\uff0e\u5f53\u6570\u7ec4\u7684\u5185\u5b58\u4e0d\u8db3\u4ee5\u4fdd\u5b58\u6570\u636e\u65f6\uff0c\u6700\u597d\u521b\u5efa\u4e00\u4e2a\u65b0\u7684\u6570\u7ec4\uff0c\u8fd9\u4e2a\u65b0\u6570\u7ec4\u5e94\u8be5\uff1a \u5927\u5c0f\u6bd4\u65e7\u6570\u7ec4\u591a1\u4e2a\u4f4d\u7f6e \u5927\u5c0f\u662f\u65e7\u6570\u7ec4\u76842\u500d 9\uff0e\u5bf9\u4e8e\u5355\u5411\u94fe\u63a5\u7ed3\u6784\uff0c\u5f53\u4f60\u5728\u4ec0\u4e48\u5730\u65b9\u6267\u884c\u63d2\u5165\u64cd\u4f5c\u4f1a\u5f97\u5230\u6700\u574f\u60c5\u51b5\u4e0b\u7684\u8fd0\u884c\u65f6\uff1a \u5728\u7ed3\u6784\u7684\u5f00\u5934 \u5728\u7ed3\u6784\u7684\u672b\u5c3e 10\uff0e\u53cc\u5411\u94fe\u63a5\u7ed3\u6784\u8ba9\u7a0b\u5e8f\u5458\u53ef\u4ee5\u79fb\u52a8\u5230\uff1a \u7ed9\u5b9a\u8282\u70b9\u7684\u540e\u4e00\u4e2a\u8282\u70b9\u6216\u524d\u4e00\u4e2a\u8282\u70b9 \u7ed9\u5b9a\u8282\u70b9\u7684\u540e\u4e00\u4e2a\u8282\u70b9","title":"4.8.\u590d\u4e60\u9898"},{"location":"python/DataStructure/04_ArrayChain/#49","text":"\u5728\u524d6\u4e2a\u9879\u76ee\u91cc\uff0c\u4f60\u5c06\u4fee\u6539\u5728\u672c\u7ae0\u5b9a\u4e49\u7684Array\u7c7b\uff0c\u4ece\u800c\u8ba9\u5b83\u66f4\u50cfPython\u7684list\u7c7b\u3002\u5bf9\u4e8e\u8fd9\u4e9b\u9879\u76ee\u7684\u7b54\u6848\uff0c\u8bf7\u5305\u542b\u4f60\u5bf9Array\u7c7b\u6240\u505a\u4fee\u6539\u7684\u4ee3\u7801\u6d4b\u8bd5\u3002 1\uff0e\u4e3aArray\u7c7b\u6dfb\u52a0\u4e00\u4e2a\u5b9e\u4f8b\u53d8\u91cf logicalSize \u3002\u8fd9\u4e2a\u53d8\u91cf\u7684\u521d\u59cb\u503c\u4e3a 0 \uff0c\u7528\u6765\u8bb0\u5f55\u6570\u7ec4\u91cc\u5f53\u524d\u5df2\u7ecf\u5305\u542b\u7684\u5143\u7d20\u6570\u91cf\u3002\u7136\u540e\u4e3aArray\u7c7b\u6dfb\u52a0 size() \u65b9\u6cd5\uff0c\u8fd9\u4e2a\u65b9\u6cd5\u7528\u6765\u8fd4\u56de\u6570\u7ec4\u7684\u903b\u8f91\u5c3a\u5bf8\u3002 __len__ \u65b9\u6cd5\u4f9d\u7136\u4f1a\u8fd4\u56de\u6570\u7ec4\u7684\u5bb9\u91cf\uff0c\u4e5f\u5c31\u662f\u5b83\u7684\u7269\u7406\u5c3a\u5bf8\u3002 2\uff0e\u4e3aArray\u7c7b\u7684 __getitem__ \u548c_ _setitem__ \u65b9\u6cd5\u6dfb\u52a0\u5148\u9a8c\u6761\u4ef6\u3002\u5b83\u4eec\u7684\u5148\u9a8c\u6761\u4ef6\u662f 0<=index < size() \u3002\u5982\u679c\u4e0d\u6ee1\u8db3\u5148\u9a8c\u6761\u4ef6\uff0c\u5c31\u5f15\u53d1\u5f02\u5e38\u3002 3\uff0e\u5c06 grow \u548c shrink \u65b9\u6cd5\u6dfb\u52a0\u5230Array\u7c7b\u3002\u5b83\u4eec\u80fd\u591f\u57fa\u4e8e\u672c\u7ae0\u6240\u8ba8\u8bba\u7684\u7b56\u7565\u6765\u589e\u52a0\u6216\u51cf\u5c11\u6570\u7ec4\u91cc\u6240\u5305\u542b\u7684\u5217\u8868\u957f\u5ea6\u3002\u5728\u5b9e\u73b0\u65f6\uff0c\u8981\u4fdd\u8bc1\u6570\u7ec4\u7684\u7269\u7406\u5c3a\u5bf8\u4e0d\u4f1a\u7f29\u5c0f\u5230\u7528\u6237\u6307\u5b9a\u7684\u5bb9\u91cf\u4e4b\u4e0b\uff0c\u5e76\u4e14\u5728\u589e\u52a0\u6570\u7ec4\u5c3a\u5bf8\u65f6\uff0c\u6570\u7ec4\u7684\u5185\u5b58\u5355\u5143\u5c06\u4f1a\u7528\u9ed8\u8ba4\u503c\u6765\u586b\u5145\u3002 4\uff0e\u5c06\u65b9\u6cd5 insert \u548c pop \u6dfb\u52a0\u5230Array\u7c7b\u4e2d\u3002\u5b83\u4eec\u57fa\u4e8e\u672c\u7ae0\u5df2\u7ecf\u8ba8\u8bba\u8fc7\u7684\u7b56\u7565\uff0c\u5728\u9700\u8981\u7684\u65f6\u5019\u5bf9\u6570\u7ec4\u7684\u957f\u5ea6\u8fdb\u884c\u8c03\u6574\u3002 insert \u65b9\u6cd5\u4f1a\u63a5\u6536\u4e00\u4e2a\u4f4d\u7f6e\u548c\u4e00\u4e2a\u5143\u7d20\u503c\u4f5c\u4e3a\u53c2\u6570\uff0c\u7136\u540e\u628a\u8fd9\u4e2a\u5143\u7d20\u63d2\u5165\u6307\u5b9a\u7684\u4f4d\u7f6e\u3002\u5982\u679c\u4f4d\u7f6e\u5927\u4e8e\u6216\u7b49\u4e8e\u6570\u7ec4\u7684\u903b\u8f91\u5c3a\u5bf8\uff0c\u90a3\u4e48\u8fd9\u4e2a\u65b9\u6cd5\u4f1a\u628a\u5143\u7d20\u63d2\u5165\u6570\u7ec4\u91cc\u5f53\u524d\u53ef\u83b7\u5f97\u7684\u6700\u540e\u4e00\u4e2a\u5143\u7d20\u4e4b\u540e\u3002 pop \u65b9\u6cd5\u4f1a\u63a5\u6536\u4e00\u4e2a\u4f4d\u7f6e\u4f5c\u4e3a\u53c2\u6570\uff0c\u7136\u540e\u5220\u9664\u5e76\u8fd4\u56de\u8fd9\u4e2a\u4f4d\u7f6e\u7684\u5143\u7d20\u3002 pop \u65b9\u6cd5\u7684\u5148\u9a8c\u6761\u4ef6\u662f 0<=index < size() \u3002 pop \u65b9\u6cd5\u8fd8\u5e94\u8be5\u628a\u817e\u51fa\u6765\u7684\u6570\u7ec4\u5185\u5b58\u5355\u5143\u91cd\u7f6e\u4e3a\u586b\u5145\u503c\u3002 5\uff0e\u5c06\u65b9\u6cd5 __eq__ \u6dfb\u52a0\u5230Array\u7c7b\u4e2d\u3002\u5f53Array\u5bf9\u8c61\u4f5c\u4e3a == \u8fd0\u7b97\u7b26\u7684\u5de6\u64cd\u4f5c\u6570\u65f6\uff0cPython\u4f1a\u8fd0\u884c\u8fd9\u4e2a\u65b9\u6cd5\u3002\u5982\u679c\u8fd9\u4e2a\u65b9\u6cd5\u7684\u53c2\u6570\u4e5f\u662f\u4e00\u4e2aArray\u5bf9\u8c61\uff0c\u5e76\u4e14\u5b83\u7684\u903b\u8f91\u5c3a\u5bf8\u548c\u5de6\u64cd\u4f5c\u6570\u76f8\u540c\uff0c\u4e14\u5728\u4e24\u4e2a\u6570\u7ec4\u91cc\u6bcf\u4e2a\u903b\u8f91\u4f4d\u7f6e\u4e0a\u7684\u5143\u7d20\u90fd\u76f8\u7b49\uff0c\u90a3\u4e48\u8fd9\u4e2a\u65b9\u6cd5\u4f1a\u8fd4\u56de True \uff1b\u5426\u5219\uff0c\u8fd9\u4e2a\u65b9\u6cd5\u8fd4\u56de False \u3002 6\uff0e\u4e3a\u4e86\u8ba9Array\u7c7b\u548c\u5217\u8868\u4e00\u6837\uff0c\u5e94\u8be5\u5220\u9664 __iter__ \u65b9\u6cd5\u7684\u5f53\u524d\u5b9e\u73b0\u3002\u8bf7\u89e3\u91ca\u8fd9\u4e3a\u4ec0\u4e48\u662f\u4e00\u4e2a\u597d\u5efa\u8bae\uff0c\u5e76\u8bf4\u660e\u5728\u8fd9\u4e2a\u60c5\u51b5\u4e0b\u5e94\u8be5\u5982\u4f55\u5bf9 __str__ \u65b9\u6cd5\u8fdb\u884c\u4fee\u6539\u3002 7\uff0e Matrix \u7c7b\u53ef\u4ee5\u6267\u884c\u7ebf\u6027\u4ee3\u6570\u91cc\u7684\u67d0\u4e9b\u8fd0\u7b97\uff0c\u6bd4\u5982\u77e9\u9635\u8fd0\u7b97\u3002\u5f00\u53d1\u4e00\u4e2a\u4f7f\u7528\u5185\u7f6e\u8fd0\u7b97\u7b26\u8fdb\u884c\u7b97\u672f\u8fd0\u7b97\u7684 Matrix \u7c7b\uff0c\u8fd9\u4e2a Matrix \u7c7b\u5e94\u6269\u5c55\u81ea Grid \u7c7b\u3002\u5728\u63a5\u4e0b\u6765\u76844\u4e2a\u9879\u76ee\u91cc\uff0c\u4f60\u5e94\u5b9a\u4e49\u4e00\u4e9b\u7528\u6765\u64cd\u4f5c\u94fe\u63a5\u7ed3\u6784\u7684\u51fd\u6570\u3002\u5728\u89e3\u7b54\u7684\u8fc7\u7a0b\u4e2d\uff0c\u4f60\u5e94\u8be5\u7ee7\u7eed\u4f7f\u7528\u672c\u7ae0\u5b9a\u4e49\u7684 Node \u548c TwoWayNode \u7c7b\u3002\u521b\u5efa\u4e00\u4e2a\u6d4b\u8bd5\u6a21\u5757\u4ee5\u5305\u542b\u4f60\u7684\u51fd\u6570\u5b9a\u4e49\u548c\u7528\u6765\u6d4b\u8bd5\u5b83\u4eec\u7684\u4ee3\u7801\u3002 8\uff0e\u5b9a\u4e49\u4e00\u4e2a\u53eb\u4f5c length \u7684\u51fd\u6570\uff08\u4e0d\u662f len \uff09\uff0c\u8fd9\u4e2a\u51fd\u6570\u4f1a\u63a5\u53d7\u4e00\u4e2a\u5355\u5411\u94fe\u63a5\u7ed3\u6784\u4f5c\u4e3a\u53c2\u6570\uff0c\u5e76\u80fd\u591f\u8fd4\u56de\u7ed3\u6784\u91cc\u7684\u5143\u7d20\u6570\u91cf\u3002 9\uff0e\u5b9a\u4e49\u4e00\u4e2a\u53eb\u4f5c insert \u7684\u51fd\u6570\uff0c\u8fd9\u4e2a\u51fd\u6570\u5177\u6709\u628a\u5143\u7d20\u63d2\u5165\u5355\u5411\u94fe\u63a5\u7ed3\u6784\u4e2d\u6307\u5b9a\u4f4d\u7f6e\u7684\u529f\u80fd\u3002\u8fd9\u4e2a\u51fd\u6570\u67093\u4e2a\u53c2\u6570\uff1a\u5143\u7d20\u3001\u4f4d\u7f6e\u4ee5\u53ca\u4e00\u4e2a\u94fe\u63a5\u7ed3\u6784\uff08\u8fd9\u4e2a\u94fe\u63a5\u7ed3\u6784\u53ef\u80fd\u4e3a\u7a7a\uff09\u3002\u8fd9\u4e2a\u51fd\u6570\u80fd\u591f\u8fd4\u56de\u4fee\u6539\u4e4b\u540e\u7684\u94fe\u63a5\u7ed3\u6784\u3002\u5982\u679c\u4f20\u9012\u7684\u4f4d\u7f6e\u5927\u4e8e\u6216\u7b49\u4e8e\u94fe\u63a5\u7ed3\u6784\u7684\u957f\u5ea6\uff0c\u90a3\u4e48\u8fd9\u4e2a\u51fd\u6570\u4f1a\u628a\u5143\u7d20\u63d2\u5165\u5b83\u7684\u672b\u5c3e\u3002\u8fd9\u4e2a\u51fd\u6570\u7684\u8c03\u7528\u793a\u4f8b\u662f head =insert(1,data,head) \uff0c\u5176\u4e2d head \u662f\u4e00\u4e2a\u53d8\u91cf\uff0c\u8fd9\u4e2a\u53d8\u91cf\u8981\u4e48\u4e3a\u7a7a\u94fe\u63a5\uff0c\u8981\u4e48\u6307\u5411\u94fe\u63a5\u7ed3\u6784\u7684\u7b2c\u4e00\u4e2a\u8282\u70b9\u3002 10\uff0e\u5b9a\u4e49\u4e00\u4e2a\u53eb\u4f5c pop \u7684\u51fd\u6570\uff0c\u8fd9\u4e2a\u51fd\u6570\u80fd\u591f\u5728\u5355\u5411\u94fe\u63a5\u7ed3\u6784\u7684\u6307\u5b9a\u4f4d\u7f6e\u4e0a\u5220\u9664\u5143\u7d20\u3002\u8fd9\u4e2a\u51fd\u6570\u7684\u7b2c\u4e00\u4e2a\u53c2\u6570\u662f\u4f4d\u7f6e\uff0c\u5b83\u7684\u5148\u9a8c\u6761\u4ef6\u662f 0<=position<\u7ed3\u6784\u7684\u957f\u5ea6 \u3002\u5b83\u7684\u7b2c\u4e8c\u4e2a\u53c2\u6570\u662f\u4e00\u4e2a\u94fe\u63a5\u7ed3\u6784\uff0c\u5f88\u660e\u663e\u5b83\u4e0d\u5e94\u8be5\u4e3a\u7a7a\u3002\u8fd9\u4e2a\u51fd\u6570\u5c06\u4f1a\u8fd4\u56de\u4e00\u4e2a\u5143\u7ec4\uff0c\u5305\u542b\u4fee\u6539\u540e\u7684\u94fe\u63a5\u7ed3\u6784\u548c\u5220\u9664\u7684\u5143\u7d20\u3002\u5b83\u7684\u8c03\u7528\u793a\u4f8b\u662f (head, item) = pop(1,head) \u3002 11\uff0e\u5b9a\u4e49\u4e00\u4e2a\u51fd\u6570 makeTwoWay \uff0c\u8fd9\u4e2a\u51fd\u6570\u4f1a\u63a5\u53d7\u4e00\u4e2a\u5355\u5411\u94fe\u63a5\u7ed3\u6784\u4f5c\u4e3a\u53c2\u6570\uff0c\u7136\u540e\u751f\u6210\u5e76\u8fd4\u56de\u4e00\u4e2a\u5305\u542b\u5355\u5411\u94fe\u63a5\u7ed3\u6784\u91cc\u7684\u5143\u7d20\u7684\u53cc\u5411\u94fe\u63a5\u7ed3\u6784\u3002\uff08\u6ce8\u610f\uff1a\u8fd9\u4e2a\u51fd\u6570\u4e0d\u5e94\u8be5\u5bf9\u4f5c\u4e3a\u53c2\u6570\u7684\u94fe\u63a5\u7ed3\u6784\u8fdb\u884c\u4efb\u4f55\u4fee\u6539\u3002\uff09","title":"4.9.\u7f16\u7a0b\u7ec3\u4e60"},{"location":"python/DataStructure/05_InterfacePolymorphism/","text":"5.\u63a5\u53e3\u3001\u5b9e\u73b0\u548c\u591a\u6001 \u00b6 \u76ee\u6807\uff1a \u4e3a\u7ed9\u5b9a\u7684\u591a\u9879\u96c6\u7c7b\u578b\u5f00\u53d1\u63a5\u53e3\uff1b \u6309\u7167\u591a\u9879\u96c6\u7c7b\u578b\u7684\u63a5\u53e3\u5b9e\u73b0\u591a\u4e2a\u7c7b\uff1b \u5bf9\u7ed9\u5b9a\u591a\u9879\u96c6\u7c7b\u578b\u7684\u4e0d\u540c\u5b9e\u73b0\u8bc4\u4f30\u8fd0\u884c\u65f6\u548c\u5185\u5b58\u4f7f\u7528\u60c5\u51b5\u7684\u6743\u8861\uff1b \u5b9e\u73b0\u4e00\u4e2a\u7b80\u5355\u7684\u8fed\u4ee3\u5668\uff1b \u4f7f\u7528\u65b9\u6cd5\u5bf9\u5305\u548c\u96c6\u5408\u8fdb\u884c\u64cd\u4f5c\uff1b \u5224\u65ad\u5305\u6216\u96c6\u5408\u662f\u5426\u9002\u5408\u5728\u7ed9\u5b9a\u7684\u5e94\u7528\u7a0b\u5e8f\u91cc\u4f7f\u7528\uff1b \u5c06\u5305\u7684\u5b9e\u73b0\u8f6c\u6362\u6210\u6709\u5e8f\u5305\u7684\u5b9e\u73b0\u3002 5.1.\u5f00\u53d1\u63a5\u53e3 \u00b6 5.1.1.\u8bbe\u8ba1\u5305\u63a5\u53e3 \u00b6 5.1.2.\u6307\u5b9a\u53c2\u6570\u548c\u8fd4\u56de\u503c \u00b6 5.2.\u6784\u9020\u51fd\u6570\u548c\u7c7b\u7684\u5b9e\u73b0 \u00b6 5.2.1.\u524d\u7f6e\u6761\u4ef6\u3001\u540e\u7f6e\u6761\u4ef6\u3001\u5f02\u5e38\u548c\u6587\u6863 \u00b6 5.2.2.\u5728Python\u91cc\u7f16\u5199\u63a5\u53e3 \u00b6 \u7ec3\u4e60\u9898 1\uff0e\u5305\u91cc\u7684\u5143\u7d20\u662f\u6709\u5e8f\u7684\uff0c\u8fd8\u662f\u65e0\u5e8f\u7684\uff1f 2\uff0e\u54ea\u4e9b\u64cd\u4f5c\u4f1a\u51fa\u73b0\u5728\u6240\u6709\u591a\u9879\u96c6\u7684\u63a5\u53e3\u91cc\uff1f 3\uff0e\u54ea\u4e2a\u65b9\u6cd5\u8d1f\u8d23\u521b\u5efa\u591a\u9879\u96c6\u5bf9\u8c61\uff1f 4\uff0e\u8bf7\u8bf4\u51fa\u63a5\u53e3\u4e0e\u5b9e\u73b0\u5206\u79bb\u76843\u4e2a\u539f\u56e0\u3002 5.3.\u5f00\u53d1\u57fa\u4e8e\u6570\u7ec4\u7684\u5b9e\u73b0 \u00b6 5.3.1.\u9009\u62e9\u5e76\u521d\u59cb\u5316\u6570\u636e\u7ed3\u6784 \u00b6 5.3.2.\u5148\u5b8c\u6210\u7b80\u5355\u7684\u65b9\u6cd5 \u00b6 5.3.3.\u5b8c\u6210\u8fed\u4ee3\u5668 \u00b6 5.3.4.\u5b8c\u6210\u4f7f\u7528\u8fed\u4ee3\u5668\u7684\u65b9\u6cd5 \u00b6 5.3.5.in\u8fd0\u7b97\u7b26\u548c__contains__\u65b9\u6cd5 \u00b6 5.3.6.\u5b8c\u6210remove\u65b9\u6cd5 \u00b6 5.3.7.\u7ec3\u4e60\u9898 \u00b6 1\uff0e\u89e3\u91ca\u591a\u9879\u96c6\u7c7b\u7684__init__\u65b9\u6cd5\u7684\u4f5c\u7528\u3002 2\uff0e\u4e3a\u4ec0\u4e48\u8c03\u7528\u65b9\u6cd5\u6bd4\u76f4\u63a5\u5728\u7c7b\u91cc\u5f15\u7528\u5b9e\u4f8b\u53d8\u91cf\u66f4\u597d\uff1f 3\uff0e\u5bf9\u4e8eArrayBag\u7684__init__\u65b9\u6cd5\uff0c\u5c55\u793a\u5982\u4f55\u901a\u8fc7\u8c03\u7528clear\u65b9\u6cd5\u6765\u7b80\u5316\u4ee3\u7801\u3002 4\uff0e\u89e3\u91ca\u4e3a\u4ec0\u4e48__iter__\u65b9\u6cd5\u53ef\u80fd\u4f1a\u662f\u591a\u9879\u96c6\u7c7b\u91cc\u6700\u6709\u7528\u7684\u65b9\u6cd5\u3002 5\uff0e\u89e3\u91ca\u4e3a\u4ec0\u4e48\u5728ArrayBag\u7c7b\u4e2d\u4e0d\u7528\u5305\u542b__contains__\u65b9\u6cd5\u3002 5.4.\u5f00\u53d1\u57fa\u4e8e\u94fe\u63a5\u7684\u5b9e\u73b0 \u00b6 5.4.1.\u521d\u59cb\u5316\u6570\u636e\u7ed3\u6784 \u00b6 5.4.2.\u5b8c\u6210\u8fed\u4ee3\u5668 \u00b6 5.4.3.\u5b8c\u6210clear\u548cadd\u65b9\u6cd5 \u00b6 5.4.4.\u5b8c\u6210remove\u65b9\u6cd5 \u00b6 5.4.5.\u7ec3\u4e60\u9898 \u00b6 1\uff0e\u5047\u8bbea\u662f\u4e00\u4e2a\u6570\u7ec4\u5305\uff0cb\u662f\u4e00\u4e2a\u94fe\u63a5\u5305\uff0c\u5b83\u4eec\u90fd\u4e0d\u5305\u542b\u4efb\u4f55\u5143\u7d20\u3002\u8bf7\u63cf\u8ff0\u5728\u8fd9\u79cd\u60c5\u51b5\u4e0b\u5b83\u4eec\u5728\u5185\u5b58\u4f7f\u7528\u4e0a\u7684\u5dee\u5f02\u3002 2\uff0e\u4e3a\u4ec0\u4e48\u94fe\u63a5\u5305\u4ecd\u7136\u9700\u8981\u4e00\u4e2a\u5355\u72ec\u7684\u5b9e\u4f8b\u53d8\u91cf\u6765\u8bb0\u5f55\u5b83\u7684\u903b\u8f91\u5c3a\u5bf8\uff1f 3\uff0e\u4e3a\u4ec0\u4e48\u4ece\u94fe\u63a5\u5305\u91cc\u5220\u9664\u5143\u7d20\u4e4b\u540e\uff0c\u7a0b\u5e8f\u5458\u4e0d\u7528\u62c5\u5fc3\u51fa\u73b0\u5185\u5b58\u6d6a\u8d39\u7684\u60c5\u51b5\uff1f 5.5.\u4e24\u79cd\u5305\u5b9e\u73b0\u7684\u8fd0\u884c\u65f6\u6027\u80fd \u00b6 5.6.\u6d4b\u8bd5\u5305\u7684\u4e24\u79cd\u5b9e\u73b0 \u00b6 5.7.\u4f7f\u7528UML\u7ed8\u5236\u5305\u8d44\u6e90 \u00b6 5.8.\u5c0f\u7ed3 \u00b6 \u63a5\u53e3\u662f\u7528\u6237\u7684\u8f6f\u4ef6\u8d44\u6e90\u53ef\u4ee5\u4f7f\u7528\u7684\u4e00\u7ec4\u64cd\u4f5c\u3002 \u63a5\u53e3\u91cc\u7684\u5143\u7d20\u662f\u51fd\u6570\u548c\u65b9\u6cd5\u7684\u5b9a\u4e49\u4ee5\u53ca\u5b83\u4eec\u7684\u6587\u6863\u3002 \u524d\u7f6e\u6761\u4ef6\u662f\u6307\u5728\u51fd\u6570\u6216\u65b9\u6cd5\u53ef\u4ee5\u6b63\u786e\u5b8c\u6210\u4efb\u52a1\u4e4b\u524d\u5fc5\u987b\u8981\u6ee1\u8db3\u7684\u6761\u4ef6\u3002 \u540e\u7f6e\u6761\u4ef6\u662f\u6307\u5728\u51fd\u6570\u6216\u65b9\u6cd5\u6b63\u786e\u5b8c\u6210\u4efb\u52a1\u4e4b\u540e\u5fc5\u987b\u4e3a\u771f\u7684\u6761\u4ef6\u3002 \u8bbe\u8ba1\u826f\u597d\u7684\u8f6f\u4ef6\u7cfb\u7edf\u4f1a\u628a\u63a5\u53e3\u548c\u5b83\u7684\u5b9e\u73b0\u5206\u5f00\u3002 \u5b9e\u73b0\u662f\u6307\u6ee1\u8db3\u63a5\u53e3\u7684\u51fd\u6570\u3001\u65b9\u6cd5\u6216\u7c7b\u3002 \u591a\u9879\u96c6\u7c7b\u578b\u53ef\u4ee5\u901a\u8fc7\u63a5\u53e3\u8fdb\u884c\u6307\u5b9a\u3002 \u591a\u9879\u96c6\u7c7b\u578b\u53ef\u4ee5\u6709\u51e0\u4e2a\u4e0d\u540c\u7684\u5b9e\u73b0\u7c7b\u3002 \u591a\u6001\u662f\u6307\u5728\u4e24\u4e2a\u6216\u591a\u4e2a\u5b9e\u73b0\u91cc\u4f7f\u7528\u76f8\u540c\u7684\u8fd0\u7b97\u7b26\u3001\u51fd\u6570\u540d\u79f0\u6216\u65b9\u6cd5\u540d\u79f0\u3002\u591a\u6001\u51fd\u6570\u7684\u793a\u4f8b\u662f str \u548c len \uff1b\u591a\u6001\u8fd0\u7b97\u7b26\u7684\u793a\u4f8b\u662f + \u548c == \uff1b\u591a\u6001\u65b9\u6cd5\u7684\u793a\u4f8b\u5305\u62ecadd\u548c isEmpty \u3002 \u5305\u591a\u9879\u96c6\u7c7b\u578b\u662f\u65e0\u5e8f\u7684\uff0c\u5e76\u4e14\u652f\u6301\u6dfb\u52a0\u3001\u5220\u9664\u548c\u8bbf\u95ee\u5176\u5143\u7d20\u7b49\u64cd\u4f5c\u3002 \u7c7b\u56fe\u662f\u4e00\u79cd\u63cf\u8ff0\u7c7b\u4e0e\u7c7b\u4e4b\u95f4\u5173\u7cfb\u7684\u53ef\u89c6\u5316\u8868\u793a\u65b9\u6cd5\u3002 \u7ec4\u5408\u8868\u793a\u4e24\u4e2a\u7c7b\u4e4b\u95f4\u6574\u4f53\u4e0e\u5c40\u90e8\u7684\u5173\u7cfb\u3002 \u805a\u5408\u8868\u793a\u4e24\u4e2a\u7c7b\u4e4b\u95f4\u4e00\u5bf9\u591a\u7684\u5173\u7cfb\u3002 UML\u662f\u4e00\u79cd\u63cf\u8ff0\u8f6f\u4ef6\u8d44\u6e90\u4e4b\u95f4\u5173\u7cfb\u7684\u53ef\u89c6\u5316\u8868\u793a\u65b9\u6cd5\u3002 5.9.\u590d\u4e60\u9898 \u00b6 1\uff0e\u5305\u662f\uff1a \u7ebf\u6027\u591a\u9879\u96c6 \u65e0\u5e8f\u591a\u9879\u96c6 2\uff0e\u7528\u6765\u8bbe\u7f6e\u5bf9\u8c61\u5b9e\u4f8b\u53d8\u91cf\u7684\u521d\u59cb\u72b6\u6001\u7684\u65b9\u6cd5\u662f\uff1a __init__ \u65b9\u6cd5 __str__ \u65b9\u6cd5 3\uff0e\u8ba9\u7a0b\u5e8f\u5458\u53ef\u4ee5\u8bbf\u95ee\u591a\u9879\u96c6\u91cc\u6240\u6709\u5143\u7d20\u7684\u65b9\u6cd5\u662f\uff1a __init__ \u65b9\u6cd5 __iter__ \u65b9\u6cd5 4\uff0e\u6539\u53d8\u5bf9\u8c61\u5185\u90e8\u72b6\u6001\u7684\u65b9\u6cd5\u662f\uff1a \u8bbf\u95ee\u5668\u65b9\u6cd5 \u53d8\u5f02\u5668\u65b9\u6cd5 5\uff0e\u4e00\u7ec4\u53ef\u4ee5\u88ab\u7c7b\u7684\u5ba2\u6237\u7aef\u4f7f\u7528\u7684\u65b9\u6cd5\u96c6\u79f0\u4e3a\uff1a \u5b9e\u73b0 \u63a5\u53e3 6\uff0e\u591a\u6001\u7528\u6765\u4ee3\u8868\u7684\u672f\u8bed\u662f\uff1a \u591a\u4e2a\u7c7b\u91cc\u76f8\u540c\u7684\u65b9\u6cd5\u540d\u79f0 \u7528\u6765\u5b58\u50a8\u53e6\u4e00\u4e2a\u7c7b\u91cc\u6240\u5305\u542b\u6570\u636e\u7684\u7c7b 7\uff0e\u7ec4\u5408\u662f\u6307\uff1a \u4e24\u4e2a\u7c7b\u4e4b\u95f4\u90e8\u5206\u4e0e\u6574\u4f53\u5173\u7cfb \u4e24\u4e2a\u7c7b\u4e4b\u95f4\u591a\u5bf9\u4e00\u5173\u7cfb 8\uff0e\u5305\u4e2dadd\u65b9\u6cd5\u7684\u5e73\u5747\u8fd0\u884c\u65f6\u4e3a\uff1a O(n) O(k) 9\uff0e\u5305\u4e2dremove\u65b9\u6cd5\u7684\u5e73\u5747\u8fd0\u884c\u65f6\u4e3a\uff1a O(n) O(k) 10\uff0e\u5728\u4ec0\u4e48\u60c5\u51b5\u4e0b\uff0c\u6570\u7ec4\u5305\u5b9e\u73b0\u4f1a\u6bd4\u94fe\u63a5\u5305\u5b9e\u73b0\u4f7f\u7528\u66f4\u5c11\u7684\u5185\u5b58\uff1a \u542b\u6709\u5c11\u4e8e\u4e00\u534a\u7684\u6570\u636e \u542b\u6709\u4e00\u534a\u4ee5\u4e0a\u7684\u6570\u636e 5.10.\u7f16\u7a0b\u7ec3\u4e60 \u00b6 1\uff0e\u5bf9\u4e8e\u4e24\u4e2a\u5305\u5b9e\u73b0\uff0c\u786e\u5b9a == \u64cd\u4f5c\u7684\u8fd0\u884c\u65f6\u3002\u53ef\u4ee5\u9884\u89c1\u5230\uff0c\u8fd9\u91cc\u6709\u51e0\u79cd\u60c5\u51b5\u9700\u8981\u5206\u6790\u3002 2\uff0e\u5bf9\u4e8e\u5305\u7684\u4e24\u4e2a\u5b9e\u73b0\uff0c\u786e\u5b9a + \u8fd0\u7b97\u7b26\u7684\u8fd0\u884c\u65f6\u3002 3\uff0e\u7f16\u7801 ArrayBag \u91cc add \u65b9\u6cd5\u7684\u4ee3\u7801\uff0c\u4ece\u800c\u53ef\u4ee5\u5728\u9700\u8981\u7684\u65f6\u5019\u5bf9\u6570\u7ec4\u5c3a\u5bf8\u8fdb\u884c\u8c03\u6574\u3002 4\uff0e\u7f16\u7801 ArrayBag \u91cc remove \u65b9\u6cd5\u7684\u4ee3\u7801\uff0c\u4ece\u800c\u53ef\u4ee5\u5728\u9700\u8981\u7684\u65f6\u5019\u5bf9\u6570\u7ec4\u5c3a\u5bf8\u8fdb\u884c\u8c03\u6574\u3002 5\uff0e\u5728 ArrayBag \u548c LinkedBag \u7c7b\u91cc\u6dfb\u52a0 clone \u65b9\u6cd5\u3002\u8fd9\u4e2a\u65b9\u6cd5\u5728\u8c03\u7528\u7684\u65f6\u5019\uff0c\u4e0d\u4f1a\u63a5\u6536\u4efb\u4f55\u53c2\u6570\uff0c\u5e76\u4e14\u4f1a\u8fd4\u56de\u5f53\u524d\u5305\u7c7b\u578b\u7684\u4e00\u4e2a\u5b8c\u6574\u526f\u672c\u3002\u5728\u4e0b\u9762\u8fd9\u6bb5\u4ee3\u7801\u7684\u6700\u540e\uff0c\u53d8\u91cf bag2 \u5c06\u5305\u542b\u6570\u5b57 2 \u3001 3 \u548c 4 \u3002 bag1 = ArrayBag ([ 2 , 3 , 4 ]) bag2 = bag1 . clone () bag1 == bag2 # Returns True bag1 is bag2 # Returns False 6\uff0e\u96c6\u5408\u662f\u4e00\u4e2a\u65e0\u5e8f\u591a\u9879\u96c6\uff0c\u5e76\u4e14\u548c\u5305\u5177\u6709\u76f8\u540c\u7684\u63a5\u53e3\u3002\u4f46\u662f\u5728\u96c6\u5408\u91cc\uff0c\u5143\u7d20\u662f\u552f\u4e00\u7684\uff0c\u800c\u5305\u91cc\u53ef\u4ee5\u5305\u542b\u91cd\u590d\u7684\u7269\u54c1\u3002\u5b9a\u4e49\u4e00\u4e2a\u57fa\u4e8e\u6570\u7ec4\u7684\u53eb\u4f5c ArraySet \u7684\u591a\u9879\u96c6\u65b0\u7c7b\u3002\u5982\u679c\u96c6\u5408\u91cc\u7684\u5143\u7d20\u5df2\u7ecf\u5b58\u5728\u4e86\uff0c\u90a3\u4e48 add \u65b9\u6cd5\u5c06\u4f1a\u5ffd\u7565\u8fd9\u4e2a\u5143\u7d20\u3002 7\uff0e\u4f7f\u7528\u94fe\u63a5\u8282\u70b9\u5b9a\u4e49\u4e00\u4e2a\u53eb\u4f5c LinkedSet \u7684\u591a\u9879\u96c6\u65b0\u7c7b\u6765\u5b9e\u73b0\u96c6\u5408\u7c7b\u578b\u3002\u5982\u679c\u96c6\u5408\u91cc\u7684\u5143\u7d20\u5df2\u7ecf\u5b58\u5728\u4e86\uff0c\u90a3\u4e48 add \u65b9\u6cd5\u5c06\u4f1a\u5ffd\u7565\u8fd9\u4e2a\u5143\u7d20\u3002 8\uff0e\u6709\u5e8f\u5305\u7684\u884c\u4e3a\u548c\u666e\u901a\u5305\u7684\u662f\u4e00\u6837\u7684\uff0c\u4f46\u662f\u5b83\u80fd\u591f\u8ba9\u7528\u6237\u5728\u4f7f\u7528 for \u5faa\u73af\u65f6\u6309\u7167\u5347\u5e8f\u8bbf\u95ee\u91cc\u9762\u7684\u5143\u7d20\u3002\u56e0\u6b64\uff0c\u6dfb\u52a0\u5230\u8fd9\u4e2a\u5305\u7c7b\u578b\u91cc\u7684\u5143\u7d20\uff0c\u90fd\u5fc5\u987b\u5177\u6709\u4e00\u5b9a\u7684\u987a\u5e8f\u5e76\u4e14\u652f\u6301\u6bd4\u8f83\u8fd0\u7b97\u7b26\u3002\u8fd9\u79cd\u7c7b\u578b\u5143\u7d20\u7684\u7b80\u5355\u4f8b\u5b50\u662f\uff1a\u5b57\u7b26\u4e32\u548c\u6574\u6570\u3002\u5b9a\u4e49\u4e00\u4e2a\u652f\u6301\u8fd9\u4e2a\u529f\u80fd\u7684\u53eb\u4f5c ArraySortedBag \u7684\u65b0\u7c7b\u3002\u548c ArrayBag \u4e00\u6837\uff0c\u8fd9\u4e2a\u65b0\u7c7b\u4f1a\u57fa\u4e8e\u6570\u7ec4\uff0c\u4f46\u662f\u5b83\u7684 in \u64cd\u4f5c\u73b0\u5728\u53ef\u4ee5\u5728\u5bf9\u6570\u65f6\u95f4\u91cc\u8fd0\u884c\u3002\u8981\u5b8c\u6210\u8fd9\u4e00\u70b9\uff0c ArraySortedBag \u5fc5\u987b\u5c06\u65b0\u6dfb\u52a0\u7684\u5143\u7d20\u6309\u7167\u987a\u5e8f\u653e\u5230\u6570\u7ec4\u91cc\u3002\u6700\u7b80\u5355\u7684\u529e\u6cd5\u662f\u4fee\u6539 add \u65b9\u6cd5\uff0c\u4ece\u800c\u8ba9\u65b0\u5143\u7d20\u63d2\u5165\u9002\u5f53\u7684\u4f4d\u7f6e\uff1b\u7136\u540e\uff0c\u6dfb\u52a0_ _contains__ \u65b9\u6cd5\u6765\u63d0\u4f9b\u65b0\u7684\u4e14\u66f4\u6709\u6548\u7684\u641c\u7d22\uff1b\u6700\u540e\uff0c\u8981\u628a\u5bf9 ArrayBag \u7684\u6240\u6709\u5f15\u7528\u90fd\u66ff\u6362\u4e3a ArraySortedBag \u3002\uff08\u63d0\u793a\uff1a\u628a\u4ee3\u7801\u4ece ArrayBag \u7c7b\u4e2d\u590d\u5236\u5230\u4e00\u4e2a\u65b0\u6587\u4ef6\u91cc\uff0c\u7136\u540e\u5728\u8fd9\u4e2a\u65b0\u6587\u4ef6\u91cc\u5f00\u59cb\u4fee\u6539\u3002\uff09 9\uff0e\u786e\u5b9a ArraySortedBag \u91cc add \u65b9\u6cd5\u7684\u8fd0\u884c\u65f6\u3002 10\uff0ePython\u7684 for \u5faa\u73af\u53ef\u4ee5\u8ba9\u7a0b\u5e8f\u5458\u5728\u5faa\u73af\u8fed\u4ee3\u591a\u9879\u96c6\u7684\u65f6\u5019\u5bf9\u5b83\u6267\u884c\u6dfb\u52a0\u6216\u5220\u9664\u5143\u7d20\u7684\u64cd\u4f5c\u3002\u4e00\u4e9b\u8bbe\u8ba1\u4eba\u5458\u62c5\u5fc3\u5728\u8fed\u4ee3\u8fc7\u7a0b\u4e2d\u5bf9\u591a\u9879\u96c6\u7684\u7ed3\u6784\u8fdb\u884c\u4fee\u6539\u53ef\u80fd\u4f1a\u5bfc\u81f4\u7a0b\u5e8f\u5d29\u6e83\u3002\u6709\u4e00\u79cd\u4fee\u6539\u7b56\u7565\u662f\u901a\u8fc7\u7981\u6b62\u5728\u8fed\u4ee3\u671f\u95f4\u5bf9\u591a\u9879\u96c6\u8fdb\u884c\u53d8\u5f02\u6765\u8ba9 for \u5faa\u73af\u6210\u4e3a\u53ea\u8bfb\u3002\u4f60\u53ef\u4ee5\u901a\u8fc7\u5bf9\u53d8\u5f02\u64cd\u4f5c\u8fdb\u884c\u8ba1\u6570\uff0c\u5e76\u4e14\u5224\u65ad\u8fd9\u4e2a\u8ba1\u6570\u6709\u6ca1\u6709\u5728\u591a\u9879\u96c6\u7684 __iter__ \u65b9\u6cd5\u7684\u4efb\u610f\u8282\u62cd\u4e2d\u88ab\u589e\u52a0\u6765\u68c0\u6d4b\u8fd9\u79cd\u7c7b\u578b\u7684\u53d8\u5f02\u3002\u5f53\u53d1\u751f\u8fd9\u79cd\u60c5\u51b5\u65f6\uff0c\u5c31\u53ef\u4ee5\u5f15\u53d1\u5f02\u5e38\u4ece\u800c\u907f\u514d\u8ba1\u7b97\u7684\u7ee7\u7eed\u8fdb\u884c\u3002\u628a\u8fd9\u4e2a\u673a\u5236\u6dfb\u52a0\u5230 ArrayBag \u7c7b\u91cc\u3002\u53ef\u4ee5\u6dfb\u52a0\u4e00\u4e2a\u53eb\u4f5c modCount \u7684\u65b0\u5b9e\u4f8b\u53d8\u91cf\uff0c\u8fd9\u4e2a\u5b9e\u4f8b\u53d8\u91cf\u4f1a\u5728 __init__ \u65b9\u6cd5\u91cc\u8bbe\u7f6e\u4e3a 0 \uff1b\u7136\u540e\uff0c\u6bcf\u4e2a\u53d8\u5f02\u5668\u65b9\u6cd5\u90fd\u4f1a\u9012\u589e\u8fd9\u4e2a\u53d8\u91cf\uff1b\u6700\u540e\uff0c __iter__ \u65b9\u6cd5\u6709\u4e00\u4e2a\u53eb\u4f5c modCount \u7684\u4e34\u65f6\u53d8\u91cf\uff0c\u8fd9\u4e2a\u4e34\u65f6\u53d8\u91cf\u7684\u521d\u59cb\u503c\u662f\u5b9e\u4f8b\u53d8\u91cf self.modCount \u7684\u503c\u3002\u5728 __iter__ \u65b9\u6cd5\u91cc\u8fd4\u56de\u4e00\u4e2a\u5143\u7d20\u540e\uff0c\u5982\u679c\u8fd9\u4e24\u4e2a\u4fee\u6539\u8fc7\u7684\u8ba1\u6570\u5668\u503c\u4e0d\u76f8\u7b49\uff0c\u5c31\u7acb\u5373\u5f15\u53d1\u5f02\u5e38\u3002\u7528\u4e00\u4e2a\u7a0b\u5e8f\u6765\u6d4b\u8bd5\u4f60\u7684\u4fee\u6539\uff0c\u4ece\u800c\u4fdd\u8bc1\u6ee1\u8db3\u76f8\u5e94\u7684\u9700\u6c42\u3002","title":"\u63a5\u53e3\u3001\u5b9e\u73b0\u548c\u591a\u6001"},{"location":"python/DataStructure/05_InterfacePolymorphism/#5","text":"\u76ee\u6807\uff1a \u4e3a\u7ed9\u5b9a\u7684\u591a\u9879\u96c6\u7c7b\u578b\u5f00\u53d1\u63a5\u53e3\uff1b \u6309\u7167\u591a\u9879\u96c6\u7c7b\u578b\u7684\u63a5\u53e3\u5b9e\u73b0\u591a\u4e2a\u7c7b\uff1b \u5bf9\u7ed9\u5b9a\u591a\u9879\u96c6\u7c7b\u578b\u7684\u4e0d\u540c\u5b9e\u73b0\u8bc4\u4f30\u8fd0\u884c\u65f6\u548c\u5185\u5b58\u4f7f\u7528\u60c5\u51b5\u7684\u6743\u8861\uff1b \u5b9e\u73b0\u4e00\u4e2a\u7b80\u5355\u7684\u8fed\u4ee3\u5668\uff1b \u4f7f\u7528\u65b9\u6cd5\u5bf9\u5305\u548c\u96c6\u5408\u8fdb\u884c\u64cd\u4f5c\uff1b \u5224\u65ad\u5305\u6216\u96c6\u5408\u662f\u5426\u9002\u5408\u5728\u7ed9\u5b9a\u7684\u5e94\u7528\u7a0b\u5e8f\u91cc\u4f7f\u7528\uff1b \u5c06\u5305\u7684\u5b9e\u73b0\u8f6c\u6362\u6210\u6709\u5e8f\u5305\u7684\u5b9e\u73b0\u3002","title":"5.\u63a5\u53e3\u3001\u5b9e\u73b0\u548c\u591a\u6001"},{"location":"python/DataStructure/05_InterfacePolymorphism/#51","text":"","title":"5.1.\u5f00\u53d1\u63a5\u53e3"},{"location":"python/DataStructure/05_InterfacePolymorphism/#511","text":"","title":"5.1.1.\u8bbe\u8ba1\u5305\u63a5\u53e3"},{"location":"python/DataStructure/05_InterfacePolymorphism/#512","text":"","title":"5.1.2.\u6307\u5b9a\u53c2\u6570\u548c\u8fd4\u56de\u503c"},{"location":"python/DataStructure/05_InterfacePolymorphism/#52","text":"","title":"5.2.\u6784\u9020\u51fd\u6570\u548c\u7c7b\u7684\u5b9e\u73b0"},{"location":"python/DataStructure/05_InterfacePolymorphism/#521","text":"","title":"5.2.1.\u524d\u7f6e\u6761\u4ef6\u3001\u540e\u7f6e\u6761\u4ef6\u3001\u5f02\u5e38\u548c\u6587\u6863"},{"location":"python/DataStructure/05_InterfacePolymorphism/#522python","text":"\u7ec3\u4e60\u9898 1\uff0e\u5305\u91cc\u7684\u5143\u7d20\u662f\u6709\u5e8f\u7684\uff0c\u8fd8\u662f\u65e0\u5e8f\u7684\uff1f 2\uff0e\u54ea\u4e9b\u64cd\u4f5c\u4f1a\u51fa\u73b0\u5728\u6240\u6709\u591a\u9879\u96c6\u7684\u63a5\u53e3\u91cc\uff1f 3\uff0e\u54ea\u4e2a\u65b9\u6cd5\u8d1f\u8d23\u521b\u5efa\u591a\u9879\u96c6\u5bf9\u8c61\uff1f 4\uff0e\u8bf7\u8bf4\u51fa\u63a5\u53e3\u4e0e\u5b9e\u73b0\u5206\u79bb\u76843\u4e2a\u539f\u56e0\u3002","title":"5.2.2.\u5728Python\u91cc\u7f16\u5199\u63a5\u53e3"},{"location":"python/DataStructure/05_InterfacePolymorphism/#53","text":"","title":"5.3.\u5f00\u53d1\u57fa\u4e8e\u6570\u7ec4\u7684\u5b9e\u73b0"},{"location":"python/DataStructure/05_InterfacePolymorphism/#531","text":"","title":"5.3.1.\u9009\u62e9\u5e76\u521d\u59cb\u5316\u6570\u636e\u7ed3\u6784"},{"location":"python/DataStructure/05_InterfacePolymorphism/#532","text":"","title":"5.3.2.\u5148\u5b8c\u6210\u7b80\u5355\u7684\u65b9\u6cd5"},{"location":"python/DataStructure/05_InterfacePolymorphism/#533","text":"","title":"5.3.3.\u5b8c\u6210\u8fed\u4ee3\u5668"},{"location":"python/DataStructure/05_InterfacePolymorphism/#534","text":"","title":"5.3.4.\u5b8c\u6210\u4f7f\u7528\u8fed\u4ee3\u5668\u7684\u65b9\u6cd5"},{"location":"python/DataStructure/05_InterfacePolymorphism/#535in__contains__","text":"","title":"5.3.5.in\u8fd0\u7b97\u7b26\u548c__contains__\u65b9\u6cd5"},{"location":"python/DataStructure/05_InterfacePolymorphism/#536remove","text":"","title":"5.3.6.\u5b8c\u6210remove\u65b9\u6cd5"},{"location":"python/DataStructure/05_InterfacePolymorphism/#537","text":"1\uff0e\u89e3\u91ca\u591a\u9879\u96c6\u7c7b\u7684__init__\u65b9\u6cd5\u7684\u4f5c\u7528\u3002 2\uff0e\u4e3a\u4ec0\u4e48\u8c03\u7528\u65b9\u6cd5\u6bd4\u76f4\u63a5\u5728\u7c7b\u91cc\u5f15\u7528\u5b9e\u4f8b\u53d8\u91cf\u66f4\u597d\uff1f 3\uff0e\u5bf9\u4e8eArrayBag\u7684__init__\u65b9\u6cd5\uff0c\u5c55\u793a\u5982\u4f55\u901a\u8fc7\u8c03\u7528clear\u65b9\u6cd5\u6765\u7b80\u5316\u4ee3\u7801\u3002 4\uff0e\u89e3\u91ca\u4e3a\u4ec0\u4e48__iter__\u65b9\u6cd5\u53ef\u80fd\u4f1a\u662f\u591a\u9879\u96c6\u7c7b\u91cc\u6700\u6709\u7528\u7684\u65b9\u6cd5\u3002 5\uff0e\u89e3\u91ca\u4e3a\u4ec0\u4e48\u5728ArrayBag\u7c7b\u4e2d\u4e0d\u7528\u5305\u542b__contains__\u65b9\u6cd5\u3002","title":"5.3.7.\u7ec3\u4e60\u9898"},{"location":"python/DataStructure/05_InterfacePolymorphism/#54","text":"","title":"5.4.\u5f00\u53d1\u57fa\u4e8e\u94fe\u63a5\u7684\u5b9e\u73b0"},{"location":"python/DataStructure/05_InterfacePolymorphism/#541","text":"","title":"5.4.1.\u521d\u59cb\u5316\u6570\u636e\u7ed3\u6784"},{"location":"python/DataStructure/05_InterfacePolymorphism/#542","text":"","title":"5.4.2.\u5b8c\u6210\u8fed\u4ee3\u5668"},{"location":"python/DataStructure/05_InterfacePolymorphism/#543clearadd","text":"","title":"5.4.3.\u5b8c\u6210clear\u548cadd\u65b9\u6cd5"},{"location":"python/DataStructure/05_InterfacePolymorphism/#544remove","text":"","title":"5.4.4.\u5b8c\u6210remove\u65b9\u6cd5"},{"location":"python/DataStructure/05_InterfacePolymorphism/#545","text":"1\uff0e\u5047\u8bbea\u662f\u4e00\u4e2a\u6570\u7ec4\u5305\uff0cb\u662f\u4e00\u4e2a\u94fe\u63a5\u5305\uff0c\u5b83\u4eec\u90fd\u4e0d\u5305\u542b\u4efb\u4f55\u5143\u7d20\u3002\u8bf7\u63cf\u8ff0\u5728\u8fd9\u79cd\u60c5\u51b5\u4e0b\u5b83\u4eec\u5728\u5185\u5b58\u4f7f\u7528\u4e0a\u7684\u5dee\u5f02\u3002 2\uff0e\u4e3a\u4ec0\u4e48\u94fe\u63a5\u5305\u4ecd\u7136\u9700\u8981\u4e00\u4e2a\u5355\u72ec\u7684\u5b9e\u4f8b\u53d8\u91cf\u6765\u8bb0\u5f55\u5b83\u7684\u903b\u8f91\u5c3a\u5bf8\uff1f 3\uff0e\u4e3a\u4ec0\u4e48\u4ece\u94fe\u63a5\u5305\u91cc\u5220\u9664\u5143\u7d20\u4e4b\u540e\uff0c\u7a0b\u5e8f\u5458\u4e0d\u7528\u62c5\u5fc3\u51fa\u73b0\u5185\u5b58\u6d6a\u8d39\u7684\u60c5\u51b5\uff1f","title":"5.4.5.\u7ec3\u4e60\u9898"},{"location":"python/DataStructure/05_InterfacePolymorphism/#55","text":"","title":"5.5.\u4e24\u79cd\u5305\u5b9e\u73b0\u7684\u8fd0\u884c\u65f6\u6027\u80fd"},{"location":"python/DataStructure/05_InterfacePolymorphism/#56","text":"","title":"5.6.\u6d4b\u8bd5\u5305\u7684\u4e24\u79cd\u5b9e\u73b0"},{"location":"python/DataStructure/05_InterfacePolymorphism/#57uml","text":"","title":"5.7.\u4f7f\u7528UML\u7ed8\u5236\u5305\u8d44\u6e90"},{"location":"python/DataStructure/05_InterfacePolymorphism/#58","text":"\u63a5\u53e3\u662f\u7528\u6237\u7684\u8f6f\u4ef6\u8d44\u6e90\u53ef\u4ee5\u4f7f\u7528\u7684\u4e00\u7ec4\u64cd\u4f5c\u3002 \u63a5\u53e3\u91cc\u7684\u5143\u7d20\u662f\u51fd\u6570\u548c\u65b9\u6cd5\u7684\u5b9a\u4e49\u4ee5\u53ca\u5b83\u4eec\u7684\u6587\u6863\u3002 \u524d\u7f6e\u6761\u4ef6\u662f\u6307\u5728\u51fd\u6570\u6216\u65b9\u6cd5\u53ef\u4ee5\u6b63\u786e\u5b8c\u6210\u4efb\u52a1\u4e4b\u524d\u5fc5\u987b\u8981\u6ee1\u8db3\u7684\u6761\u4ef6\u3002 \u540e\u7f6e\u6761\u4ef6\u662f\u6307\u5728\u51fd\u6570\u6216\u65b9\u6cd5\u6b63\u786e\u5b8c\u6210\u4efb\u52a1\u4e4b\u540e\u5fc5\u987b\u4e3a\u771f\u7684\u6761\u4ef6\u3002 \u8bbe\u8ba1\u826f\u597d\u7684\u8f6f\u4ef6\u7cfb\u7edf\u4f1a\u628a\u63a5\u53e3\u548c\u5b83\u7684\u5b9e\u73b0\u5206\u5f00\u3002 \u5b9e\u73b0\u662f\u6307\u6ee1\u8db3\u63a5\u53e3\u7684\u51fd\u6570\u3001\u65b9\u6cd5\u6216\u7c7b\u3002 \u591a\u9879\u96c6\u7c7b\u578b\u53ef\u4ee5\u901a\u8fc7\u63a5\u53e3\u8fdb\u884c\u6307\u5b9a\u3002 \u591a\u9879\u96c6\u7c7b\u578b\u53ef\u4ee5\u6709\u51e0\u4e2a\u4e0d\u540c\u7684\u5b9e\u73b0\u7c7b\u3002 \u591a\u6001\u662f\u6307\u5728\u4e24\u4e2a\u6216\u591a\u4e2a\u5b9e\u73b0\u91cc\u4f7f\u7528\u76f8\u540c\u7684\u8fd0\u7b97\u7b26\u3001\u51fd\u6570\u540d\u79f0\u6216\u65b9\u6cd5\u540d\u79f0\u3002\u591a\u6001\u51fd\u6570\u7684\u793a\u4f8b\u662f str \u548c len \uff1b\u591a\u6001\u8fd0\u7b97\u7b26\u7684\u793a\u4f8b\u662f + \u548c == \uff1b\u591a\u6001\u65b9\u6cd5\u7684\u793a\u4f8b\u5305\u62ecadd\u548c isEmpty \u3002 \u5305\u591a\u9879\u96c6\u7c7b\u578b\u662f\u65e0\u5e8f\u7684\uff0c\u5e76\u4e14\u652f\u6301\u6dfb\u52a0\u3001\u5220\u9664\u548c\u8bbf\u95ee\u5176\u5143\u7d20\u7b49\u64cd\u4f5c\u3002 \u7c7b\u56fe\u662f\u4e00\u79cd\u63cf\u8ff0\u7c7b\u4e0e\u7c7b\u4e4b\u95f4\u5173\u7cfb\u7684\u53ef\u89c6\u5316\u8868\u793a\u65b9\u6cd5\u3002 \u7ec4\u5408\u8868\u793a\u4e24\u4e2a\u7c7b\u4e4b\u95f4\u6574\u4f53\u4e0e\u5c40\u90e8\u7684\u5173\u7cfb\u3002 \u805a\u5408\u8868\u793a\u4e24\u4e2a\u7c7b\u4e4b\u95f4\u4e00\u5bf9\u591a\u7684\u5173\u7cfb\u3002 UML\u662f\u4e00\u79cd\u63cf\u8ff0\u8f6f\u4ef6\u8d44\u6e90\u4e4b\u95f4\u5173\u7cfb\u7684\u53ef\u89c6\u5316\u8868\u793a\u65b9\u6cd5\u3002","title":"5.8.\u5c0f\u7ed3"},{"location":"python/DataStructure/05_InterfacePolymorphism/#59","text":"1\uff0e\u5305\u662f\uff1a \u7ebf\u6027\u591a\u9879\u96c6 \u65e0\u5e8f\u591a\u9879\u96c6 2\uff0e\u7528\u6765\u8bbe\u7f6e\u5bf9\u8c61\u5b9e\u4f8b\u53d8\u91cf\u7684\u521d\u59cb\u72b6\u6001\u7684\u65b9\u6cd5\u662f\uff1a __init__ \u65b9\u6cd5 __str__ \u65b9\u6cd5 3\uff0e\u8ba9\u7a0b\u5e8f\u5458\u53ef\u4ee5\u8bbf\u95ee\u591a\u9879\u96c6\u91cc\u6240\u6709\u5143\u7d20\u7684\u65b9\u6cd5\u662f\uff1a __init__ \u65b9\u6cd5 __iter__ \u65b9\u6cd5 4\uff0e\u6539\u53d8\u5bf9\u8c61\u5185\u90e8\u72b6\u6001\u7684\u65b9\u6cd5\u662f\uff1a \u8bbf\u95ee\u5668\u65b9\u6cd5 \u53d8\u5f02\u5668\u65b9\u6cd5 5\uff0e\u4e00\u7ec4\u53ef\u4ee5\u88ab\u7c7b\u7684\u5ba2\u6237\u7aef\u4f7f\u7528\u7684\u65b9\u6cd5\u96c6\u79f0\u4e3a\uff1a \u5b9e\u73b0 \u63a5\u53e3 6\uff0e\u591a\u6001\u7528\u6765\u4ee3\u8868\u7684\u672f\u8bed\u662f\uff1a \u591a\u4e2a\u7c7b\u91cc\u76f8\u540c\u7684\u65b9\u6cd5\u540d\u79f0 \u7528\u6765\u5b58\u50a8\u53e6\u4e00\u4e2a\u7c7b\u91cc\u6240\u5305\u542b\u6570\u636e\u7684\u7c7b 7\uff0e\u7ec4\u5408\u662f\u6307\uff1a \u4e24\u4e2a\u7c7b\u4e4b\u95f4\u90e8\u5206\u4e0e\u6574\u4f53\u5173\u7cfb \u4e24\u4e2a\u7c7b\u4e4b\u95f4\u591a\u5bf9\u4e00\u5173\u7cfb 8\uff0e\u5305\u4e2dadd\u65b9\u6cd5\u7684\u5e73\u5747\u8fd0\u884c\u65f6\u4e3a\uff1a O(n) O(k) 9\uff0e\u5305\u4e2dremove\u65b9\u6cd5\u7684\u5e73\u5747\u8fd0\u884c\u65f6\u4e3a\uff1a O(n) O(k) 10\uff0e\u5728\u4ec0\u4e48\u60c5\u51b5\u4e0b\uff0c\u6570\u7ec4\u5305\u5b9e\u73b0\u4f1a\u6bd4\u94fe\u63a5\u5305\u5b9e\u73b0\u4f7f\u7528\u66f4\u5c11\u7684\u5185\u5b58\uff1a \u542b\u6709\u5c11\u4e8e\u4e00\u534a\u7684\u6570\u636e \u542b\u6709\u4e00\u534a\u4ee5\u4e0a\u7684\u6570\u636e","title":"5.9.\u590d\u4e60\u9898"},{"location":"python/DataStructure/05_InterfacePolymorphism/#510","text":"1\uff0e\u5bf9\u4e8e\u4e24\u4e2a\u5305\u5b9e\u73b0\uff0c\u786e\u5b9a == \u64cd\u4f5c\u7684\u8fd0\u884c\u65f6\u3002\u53ef\u4ee5\u9884\u89c1\u5230\uff0c\u8fd9\u91cc\u6709\u51e0\u79cd\u60c5\u51b5\u9700\u8981\u5206\u6790\u3002 2\uff0e\u5bf9\u4e8e\u5305\u7684\u4e24\u4e2a\u5b9e\u73b0\uff0c\u786e\u5b9a + \u8fd0\u7b97\u7b26\u7684\u8fd0\u884c\u65f6\u3002 3\uff0e\u7f16\u7801 ArrayBag \u91cc add \u65b9\u6cd5\u7684\u4ee3\u7801\uff0c\u4ece\u800c\u53ef\u4ee5\u5728\u9700\u8981\u7684\u65f6\u5019\u5bf9\u6570\u7ec4\u5c3a\u5bf8\u8fdb\u884c\u8c03\u6574\u3002 4\uff0e\u7f16\u7801 ArrayBag \u91cc remove \u65b9\u6cd5\u7684\u4ee3\u7801\uff0c\u4ece\u800c\u53ef\u4ee5\u5728\u9700\u8981\u7684\u65f6\u5019\u5bf9\u6570\u7ec4\u5c3a\u5bf8\u8fdb\u884c\u8c03\u6574\u3002 5\uff0e\u5728 ArrayBag \u548c LinkedBag \u7c7b\u91cc\u6dfb\u52a0 clone \u65b9\u6cd5\u3002\u8fd9\u4e2a\u65b9\u6cd5\u5728\u8c03\u7528\u7684\u65f6\u5019\uff0c\u4e0d\u4f1a\u63a5\u6536\u4efb\u4f55\u53c2\u6570\uff0c\u5e76\u4e14\u4f1a\u8fd4\u56de\u5f53\u524d\u5305\u7c7b\u578b\u7684\u4e00\u4e2a\u5b8c\u6574\u526f\u672c\u3002\u5728\u4e0b\u9762\u8fd9\u6bb5\u4ee3\u7801\u7684\u6700\u540e\uff0c\u53d8\u91cf bag2 \u5c06\u5305\u542b\u6570\u5b57 2 \u3001 3 \u548c 4 \u3002 bag1 = ArrayBag ([ 2 , 3 , 4 ]) bag2 = bag1 . clone () bag1 == bag2 # Returns True bag1 is bag2 # Returns False 6\uff0e\u96c6\u5408\u662f\u4e00\u4e2a\u65e0\u5e8f\u591a\u9879\u96c6\uff0c\u5e76\u4e14\u548c\u5305\u5177\u6709\u76f8\u540c\u7684\u63a5\u53e3\u3002\u4f46\u662f\u5728\u96c6\u5408\u91cc\uff0c\u5143\u7d20\u662f\u552f\u4e00\u7684\uff0c\u800c\u5305\u91cc\u53ef\u4ee5\u5305\u542b\u91cd\u590d\u7684\u7269\u54c1\u3002\u5b9a\u4e49\u4e00\u4e2a\u57fa\u4e8e\u6570\u7ec4\u7684\u53eb\u4f5c ArraySet \u7684\u591a\u9879\u96c6\u65b0\u7c7b\u3002\u5982\u679c\u96c6\u5408\u91cc\u7684\u5143\u7d20\u5df2\u7ecf\u5b58\u5728\u4e86\uff0c\u90a3\u4e48 add \u65b9\u6cd5\u5c06\u4f1a\u5ffd\u7565\u8fd9\u4e2a\u5143\u7d20\u3002 7\uff0e\u4f7f\u7528\u94fe\u63a5\u8282\u70b9\u5b9a\u4e49\u4e00\u4e2a\u53eb\u4f5c LinkedSet \u7684\u591a\u9879\u96c6\u65b0\u7c7b\u6765\u5b9e\u73b0\u96c6\u5408\u7c7b\u578b\u3002\u5982\u679c\u96c6\u5408\u91cc\u7684\u5143\u7d20\u5df2\u7ecf\u5b58\u5728\u4e86\uff0c\u90a3\u4e48 add \u65b9\u6cd5\u5c06\u4f1a\u5ffd\u7565\u8fd9\u4e2a\u5143\u7d20\u3002 8\uff0e\u6709\u5e8f\u5305\u7684\u884c\u4e3a\u548c\u666e\u901a\u5305\u7684\u662f\u4e00\u6837\u7684\uff0c\u4f46\u662f\u5b83\u80fd\u591f\u8ba9\u7528\u6237\u5728\u4f7f\u7528 for \u5faa\u73af\u65f6\u6309\u7167\u5347\u5e8f\u8bbf\u95ee\u91cc\u9762\u7684\u5143\u7d20\u3002\u56e0\u6b64\uff0c\u6dfb\u52a0\u5230\u8fd9\u4e2a\u5305\u7c7b\u578b\u91cc\u7684\u5143\u7d20\uff0c\u90fd\u5fc5\u987b\u5177\u6709\u4e00\u5b9a\u7684\u987a\u5e8f\u5e76\u4e14\u652f\u6301\u6bd4\u8f83\u8fd0\u7b97\u7b26\u3002\u8fd9\u79cd\u7c7b\u578b\u5143\u7d20\u7684\u7b80\u5355\u4f8b\u5b50\u662f\uff1a\u5b57\u7b26\u4e32\u548c\u6574\u6570\u3002\u5b9a\u4e49\u4e00\u4e2a\u652f\u6301\u8fd9\u4e2a\u529f\u80fd\u7684\u53eb\u4f5c ArraySortedBag \u7684\u65b0\u7c7b\u3002\u548c ArrayBag \u4e00\u6837\uff0c\u8fd9\u4e2a\u65b0\u7c7b\u4f1a\u57fa\u4e8e\u6570\u7ec4\uff0c\u4f46\u662f\u5b83\u7684 in \u64cd\u4f5c\u73b0\u5728\u53ef\u4ee5\u5728\u5bf9\u6570\u65f6\u95f4\u91cc\u8fd0\u884c\u3002\u8981\u5b8c\u6210\u8fd9\u4e00\u70b9\uff0c ArraySortedBag \u5fc5\u987b\u5c06\u65b0\u6dfb\u52a0\u7684\u5143\u7d20\u6309\u7167\u987a\u5e8f\u653e\u5230\u6570\u7ec4\u91cc\u3002\u6700\u7b80\u5355\u7684\u529e\u6cd5\u662f\u4fee\u6539 add \u65b9\u6cd5\uff0c\u4ece\u800c\u8ba9\u65b0\u5143\u7d20\u63d2\u5165\u9002\u5f53\u7684\u4f4d\u7f6e\uff1b\u7136\u540e\uff0c\u6dfb\u52a0_ _contains__ \u65b9\u6cd5\u6765\u63d0\u4f9b\u65b0\u7684\u4e14\u66f4\u6709\u6548\u7684\u641c\u7d22\uff1b\u6700\u540e\uff0c\u8981\u628a\u5bf9 ArrayBag \u7684\u6240\u6709\u5f15\u7528\u90fd\u66ff\u6362\u4e3a ArraySortedBag \u3002\uff08\u63d0\u793a\uff1a\u628a\u4ee3\u7801\u4ece ArrayBag \u7c7b\u4e2d\u590d\u5236\u5230\u4e00\u4e2a\u65b0\u6587\u4ef6\u91cc\uff0c\u7136\u540e\u5728\u8fd9\u4e2a\u65b0\u6587\u4ef6\u91cc\u5f00\u59cb\u4fee\u6539\u3002\uff09 9\uff0e\u786e\u5b9a ArraySortedBag \u91cc add \u65b9\u6cd5\u7684\u8fd0\u884c\u65f6\u3002 10\uff0ePython\u7684 for \u5faa\u73af\u53ef\u4ee5\u8ba9\u7a0b\u5e8f\u5458\u5728\u5faa\u73af\u8fed\u4ee3\u591a\u9879\u96c6\u7684\u65f6\u5019\u5bf9\u5b83\u6267\u884c\u6dfb\u52a0\u6216\u5220\u9664\u5143\u7d20\u7684\u64cd\u4f5c\u3002\u4e00\u4e9b\u8bbe\u8ba1\u4eba\u5458\u62c5\u5fc3\u5728\u8fed\u4ee3\u8fc7\u7a0b\u4e2d\u5bf9\u591a\u9879\u96c6\u7684\u7ed3\u6784\u8fdb\u884c\u4fee\u6539\u53ef\u80fd\u4f1a\u5bfc\u81f4\u7a0b\u5e8f\u5d29\u6e83\u3002\u6709\u4e00\u79cd\u4fee\u6539\u7b56\u7565\u662f\u901a\u8fc7\u7981\u6b62\u5728\u8fed\u4ee3\u671f\u95f4\u5bf9\u591a\u9879\u96c6\u8fdb\u884c\u53d8\u5f02\u6765\u8ba9 for \u5faa\u73af\u6210\u4e3a\u53ea\u8bfb\u3002\u4f60\u53ef\u4ee5\u901a\u8fc7\u5bf9\u53d8\u5f02\u64cd\u4f5c\u8fdb\u884c\u8ba1\u6570\uff0c\u5e76\u4e14\u5224\u65ad\u8fd9\u4e2a\u8ba1\u6570\u6709\u6ca1\u6709\u5728\u591a\u9879\u96c6\u7684 __iter__ \u65b9\u6cd5\u7684\u4efb\u610f\u8282\u62cd\u4e2d\u88ab\u589e\u52a0\u6765\u68c0\u6d4b\u8fd9\u79cd\u7c7b\u578b\u7684\u53d8\u5f02\u3002\u5f53\u53d1\u751f\u8fd9\u79cd\u60c5\u51b5\u65f6\uff0c\u5c31\u53ef\u4ee5\u5f15\u53d1\u5f02\u5e38\u4ece\u800c\u907f\u514d\u8ba1\u7b97\u7684\u7ee7\u7eed\u8fdb\u884c\u3002\u628a\u8fd9\u4e2a\u673a\u5236\u6dfb\u52a0\u5230 ArrayBag \u7c7b\u91cc\u3002\u53ef\u4ee5\u6dfb\u52a0\u4e00\u4e2a\u53eb\u4f5c modCount \u7684\u65b0\u5b9e\u4f8b\u53d8\u91cf\uff0c\u8fd9\u4e2a\u5b9e\u4f8b\u53d8\u91cf\u4f1a\u5728 __init__ \u65b9\u6cd5\u91cc\u8bbe\u7f6e\u4e3a 0 \uff1b\u7136\u540e\uff0c\u6bcf\u4e2a\u53d8\u5f02\u5668\u65b9\u6cd5\u90fd\u4f1a\u9012\u589e\u8fd9\u4e2a\u53d8\u91cf\uff1b\u6700\u540e\uff0c __iter__ \u65b9\u6cd5\u6709\u4e00\u4e2a\u53eb\u4f5c modCount \u7684\u4e34\u65f6\u53d8\u91cf\uff0c\u8fd9\u4e2a\u4e34\u65f6\u53d8\u91cf\u7684\u521d\u59cb\u503c\u662f\u5b9e\u4f8b\u53d8\u91cf self.modCount \u7684\u503c\u3002\u5728 __iter__ \u65b9\u6cd5\u91cc\u8fd4\u56de\u4e00\u4e2a\u5143\u7d20\u540e\uff0c\u5982\u679c\u8fd9\u4e24\u4e2a\u4fee\u6539\u8fc7\u7684\u8ba1\u6570\u5668\u503c\u4e0d\u76f8\u7b49\uff0c\u5c31\u7acb\u5373\u5f15\u53d1\u5f02\u5e38\u3002\u7528\u4e00\u4e2a\u7a0b\u5e8f\u6765\u6d4b\u8bd5\u4f60\u7684\u4fee\u6539\uff0c\u4ece\u800c\u4fdd\u8bc1\u6ee1\u8db3\u76f8\u5e94\u7684\u9700\u6c42\u3002","title":"5.10.\u7f16\u7a0b\u7ec3\u4e60"},{"location":"python/DataStructure/06_InheritanceAbstractClass/","text":"\u7ee7\u627f\u4e0e\u62bd\u8c61\u7c7b \u00b6","title":"\u7ee7\u627f\u4e0e\u62bd\u8c61\u7c7b"},{"location":"python/DataStructure/06_InheritanceAbstractClass/#_1","text":"","title":"\u7ee7\u627f\u4e0e\u62bd\u8c61\u7c7b"},{"location":"python/Demo/CourseSystem/","text":"\u9009\u8bfe\u7cfb\u7edf \u00b6 \u4efb\u52a1\u9700\u6c42 \u00b6 \u89d2\u8272\uff1a\u5b66\u6821\u3001\u5b66\u5458\u3001\u8bfe\u7a0b\u3001\u8bb2\u5e08 \u8981\u6c42\uff1a \u521b\u5efa\u5317\u4eac\u3001\u4e0a\u6d772\u6240\u5b66\u6821\u3002 \u521b\u5efaLinux\u3001Python\u3001go\u4e09\u4e2a\u8bfe\u7a0b\uff0cLinux\u548cPython\u5728\u5317\u4eac\u5f00\uff0cgo\u5728\u4e0a\u6d77\u5f00\u3002 \u8bfe\u7a0b\u5305\u542b\u5468\u671f\u3001\u4ef7\u683c\uff0c\u901a\u8fc7\u5b66\u6821\u521b\u5efa\u8bfe\u7a0b\u3002 \u901a\u8fc7\u5b66\u6821\u521b\u5efa\u73ed\u7ea7\uff0c\u73ed\u7ea7\u5173\u8054\u8bfe\u7a0b\u3001\u8bb2\u5e08\u3002 \u521b\u5efa\u8bb2\u5e08\u3002 \u521b\u5efa\u5b66\u5458\u65f6\uff0c\u9009\u62e9\u5b66\u6821\uff0c\u5173\u8054\u73ed\u7ea7\u3002 \u521b\u5efa\u8bb2\u5e08\u89d2\u8272\uff08\u4e0d\u9700\u8981\u5173\u8054\u5b66\u6821\uff09\u3002 \u63d0\u4f9b\u4e24\u4e2a\u89d2\u8272\u63a5\u53e3\u3002 \u5b66\u5458\u89c6\u56fe\uff1a\u53ef\u4ee5\u6ce8\u518c\uff0c\u4ea4\u5b66\u8d39\uff0c\u9009\u62e9\u73ed\u7ea7\u3002 \u8bb2\u5e08\u89c6\u56fe\uff1a\u8bb2\u5e08\u53ef\u4ee5\u7ba1\u7406\u81ea\u5df1\u7684\u73ed\u7ea7\uff0c\u4e0a\u8bfe\u65f6\u9009\u62e9\u73ed\u7ea7\uff0c\u67e5\u770b\u73ed\u7ea7\u5b66\u5458\u5217\u8868\uff0c\u4fee\u6539\u6240\u7ba1\u7406\u7684\u5b66\u5458\u7684\u6210\u7ee9\u3002 \u7ba1\u7406\u89c6\u56fe\uff1a\u521b\u5efa\u8bb2\u5e08\uff0c\u521b\u5efa\u73ed\u7ea7\uff0c\u521b\u5efa\u8bfe\u7a0b\u3002 \u4e0a\u8ff0\u64cd\u4f5c\u6240\u4ea7\u751f\u7684\u6570\u636e\u901a\u8fc7pickle\u4fdd\u5b58\u5230\u6587\u4ef6\u3002 \u9700\u6c42\u5206\u6790 \u00b6 \u7ba1\u7406\u89c6\u56fe \u6ce8\u518c \u767b\u5f55 \u521b\u5efa\u5b66\u6821 \u521b\u5efa\u8bfe\u7a0b\uff08\u5148\u9009\u62e9\u5b66\u6821\uff09 \u521b\u5efa\u8bb2\u5e08 \u5b66\u5458\u89c6\u56fe \u6ce8\u518c \u767b\u5f55\u529f\u80fd \u9009\u62e9\u6821\u533a \u9009\u62e9\u8bfe\u7a0b\uff08\u5148\u9009\u62e9\u6821\u533a\uff0c\u5728\u9009\u62e9\u6821\u533a\u4e2d\u7684\u67d0\u4e00\u95e8\u8bfe\u7a0b\uff0c\u9009\u62e9\u8bfe\u7a0b\u5373\u9009\u62e9\u73ed\u7ea7\uff09 \u5b66\u751f\u9009\u62e9\u8bfe\u7a0b\uff0c\u8bfe\u7a0b\u4e5f\u9009\u62e9\u5b66\u751f \u67e5\u770b\u5206\u6570 \u4ea4\u5b66\u8d39 \u8bb2\u5e08\u89c6\u56fe \u767b\u5f55 \u67e5\u770b\u6559\u6388\u8bfe\u7a0b \u9009\u62e9\u6559\u6388\u8bfe\u7a0b \u67e5\u770b\u8bfe\u7a0b\u4e0b\u7684\u5b66\u751f \u4fee\u6539\u5b66\u751f\u5206\u6570 \u67b6\u6784\u8bbe\u8ba1\uff08\u4e09\u5c42\u67b6\u6784\uff09 \u00b6 \u7528\u6237\u89c6\u56fe\u5c42 \u7528\u4e8e\u4e0e\u7528\u6237\u8fdb\u884c\u4ea4\u4e92\u3002 \u5b9e\u73b0\u7b80\u5355\u7684\u903b\u8f91\u5224\u65ad\uff0c\u6bd4\u5982\u6ce8\u518c\u529f\u80fd\u4e2d\u4e24\u6b21\u5bc6\u7801\u662f\u5426\u4e00\u81f4\u7684\u6821\u9a8c\u3002 core src.py \u4e3b\u89c6\u56fe admin.py: \u7ba1\u7406\u89c6\u56fe student.py: \u5b66\u5458\u89c6\u56fe teacher.py: \u8bb2\u5e08\u89c6\u56fe \u903b\u8f91\u63a5\u53e3\u5c42 \u6838\u5fc3\u4e1a\u52a1\u903b\u8f91\u7684\u5904\u7406 interface admin_interface.py studeng_interface.py teacher_interface.py \u6570\u636e\u5904\u7406\u5c42 \u6570\u636e\u5904\u7406\uff0c\u6bd4\u5982\u589e\u5220\u6539\u67e5\u3002 db models.py db_handler.py pickle\u4fdd\u5b58\u5bf9\u8c61 object \u2192 pickle \u6587\u4ef6\u7ed3\u6784 \u00b6 /--conf/ | |--settings.py | |--core/ | |--src.py | |--admin.py | |--student.py | |--teacher.py | |--db/ | |--models.py | |--db_handler.py | |--pickle | |--interface/ | |--admin_interface.py | |--student_interface.py | |--teacher_interface.py | |--common_interface.py | |--lib/ | |--common.py | |--start.py \u9009\u8bfe\u7cfb\u7edf\u603b\u7ed3 \u00b6 1.\u7ba1\u7406\u5458 \u00b6 1.1.\u6ce8\u518c \u00b6 \u7528\u6237\u518d\u89c6\u56fe\u5c42\u8f93\u5165\u7528\u6237\u540d\u548c\u5bc6\u7801\uff0c\u4ea4\u7ed9\u63a5\u53e3\u5c42\u3002 \u63a5\u53e3\u5c42\u8c03\u7528\u6570\u636e\u5c42\u4e2d\u7684models.get()\u8fdb\u884c\u6821\u9a8c\u3002 \u82e5\u4e0d\u5b58\u5728\u5219\u521b\u5efa\uff0c\u5e76\u8bb2\u6ce8\u518c\u6210\u529f\u8fd4\u56de\u7ed9\u89c6\u56fe\u5c42\u3002 1.2.\u767b\u5f55 \u00b6 \u7528\u6237\u5728\u89c6\u56fe\u5c42\u8f93\u5165\u7528\u6237\u540d\u548c\u5bc6\u7801\uff0c\u4ea4\u7ed9\u63a5\u53e3\u5c42\u3002 \u63a5\u53e3\u5c42\u8c03\u7528\u6570\u636e\u5c42\u4e2d\u7684models.get()\u8fdb\u884c\u6821\u9a8c\u3002 \u82e5\u4e0d\u5b58\u5728\u5219\u521b\u5efa\uff0c\u5e76\u8bb2\u6ce8\u518c\u6210\u529f\u8fd4\u56de\u7ed9\u89c6\u56fe\u5c42\u3002 1.3.\u521b\u5efa\u5b66\u6821 \u00b6 \u8ba9\u7528\u6237\u8f93\u5165\u5b66\u6821\u540d\u548c\u5b66\u6821\u5730\u5740\u3002 \u8c03\u7528\u7ba1\u7406\u5458\u63a5\u53e3\u521b\u5efa\u5b66\u6821\u3002 \u5224\u65ad\u5b66\u6821\u662f\u5426\u5b58\u5728\uff0c\u82e5\u5b58\u5728\uff0c\u4e0d\u521b\u5efa\u3002 \u82e5\u4e0d\u5b58\u5728\uff0c\u5219\u8c03\u7528\u63a5\u53e3\u5c42\u521b\u5efa\u5b66\u6821\uff0c\u83b7\u53d6\u7ba1\u7406\u5458\u5bf9\u8c61\u7684\u521b\u5efa\u5b66\u6821\u65b9\u6cd5\u4fdd\u6301\u5b66\u6821\u5bf9\u8c61\u3002 \u5c06\u7ed3\u679c\u8fd4\u56de\u7ed9\u89c6\u56fe\u5c42\u3002 1.4.\u521b\u5efa\u8bfe\u7a0b \u00b6 \u83b7\u53d6\u6240\u6709\u5b66\u6821\uff0c\u5e76\u6253\u5370\uff0c\u8ba9\u7528\u6237\u9009\u62e9\u3002 \u83b7\u53d6\u7528\u6237\u9009\u62e9\u7684\u5b66\u6821\u4e0e\u521b\u5efa\u7684\u8bfe\u7a0b\uff0c\u4ea4\u7ed9\u63a5\u53e3\u5c42\u3002 \u63a5\u53e3\u5c42\u8c03\u7528\u7ba1\u7406\u5458\u5bf9\u8c61\u4e2d\u7684\u521b\u5efa\u8bfe\u7a0b\u65b9\u6cd5\uff0c\u4fdd\u5b58\u8bfe\u7a0b\u5bf9\u8c61\u3002 \u8bfe\u7a0b\u9700\u8981\u7ed1\u5b9a\u7ed9\u5b66\u6821\u5bf9\u8c61\uff0c\u6700\u7ec8\u5c06\u521b\u5efa\u6210\u529f\u7684\u7ed3\u679c\u8fd4\u56de\u7ed9\u89c6\u56fe\u5c42\u3002 1.5.\u521b\u5efa\u8001\u5e08 \u00b6 \u7528\u6237\u8f93\u5165\u8001\u5e08\u540d\u79f0\u3002 \u8c03\u7528\u63a5\u53e3\u5c42\uff0c\u63a5\u53e3\u5c42\u4e2d\u8bbe\u7f6e\u9ed8\u8ba4\u5bc6\u7801123\uff0c\u8c03\u7528\u6570\u636e\u5c42\u3002 \u5224\u65ad\u8001\u5e08\u662f\u5426\u5b58\u5728\uff0c\u4e0d\u5b58\u5728\u5219\u8c03\u7528\u7ba1\u7406\u5458\u5bf9\u8c61\u4e2d\u7684\u521b\u5efa\u8001\u5e08\u65b9\u6cd5\u3002 \u4fdd\u5b58\u8001\u5e08\u5bf9\u8c61\uff0c\u5e76\u5c06\u7ed3\u679c\u8fd4\u56de\u7ed9\u89c6\u56fe\u5c42\u3002 2.\u5b66\u751f \u00b6 2.1.\u6ce8\u518c \u00b6 \u540c\u4e0a 2.2.\u767b\u5f55 \u00b6 \u540c\u4e0a 2.3.\u9009\u62e9\u5b66\u6821 \u00b6 \u83b7\u53d6\u6240\u6709\u5b66\u6821\uff0c\u8ba9\u5b66\u751f\u9009\u62e9\uff0c\u5e76\u5c06\u9009\u62e9\u7684\u5b66\u6821\u4f20\u7ed9\u63a5\u53e3\u5c42\u3002 \u63a5\u53e3\u5c42\u5224\u65ad\u5f53\u524d\u5b66\u751f\u662f\u5426\u9009\u62e9\u5b66\u6821\u3002 \u82e5\u6ca1\u6709\u9009\u62e9\uff0c\u5219\u8c03\u7528\u5b66\u751f\u5bf9\u8c61\u4e2d\u7684\u6dfb\u52a0\u5b66\u6821\u65b9\u6cd5\u3002 \u5c06\u6dfb\u52a0\u540e\u6d88\u606f\u8fd4\u56de\u7ed9\u89c6\u56fe\u5c42\u3002 2.4.\u9009\u62e9\u8bfe\u7a0b \u00b6 \u5148\u83b7\u53d6\u5f53\u524d\u5b66\u751f\u6240\u5728\u5b66\u6821\u7684\u6240\u6709\u8bfe\u7a0b\uff0c\u5e76\u9009\u62e9\u3002 \u63a5\u53e3\u5c42\u5c06\u9009\u62e9\u540e\u7684\u8bfe\u7a0b\uff0c\u8c03\u7528\u6570\u636e\u5c42\u7684\u6dfb\u52a0\u8bfe\u7a0b\u65b9\u6cd5\u4fdd\u5b58\u3002 \u5b66\u751f\u5bf9\u8c61\u4e2d\u8bfe\u7a0b\u5217\u8868\u6dfb\u52a0\u8bfe\u7a0b\uff0c\u8bbe\u7f6e\u8bfe\u7a0b\u5206\u6570\uff0c\u9ed8\u8ba4\u4e3a0. \u6700\u7ec8\u5c06\u7ed3\u679c\u8fd4\u56de\u7ed9\u89c6\u56fe\u5c42\u3002 2.5.\u67e5\u770b\u6210\u7ee9 \u00b6 \u76f4\u63a5\u8c03\u7528\u63a5\u53e3\u5c42\u3002 \u63a5\u53e3\u5c42\u8c03\u7528\u6570\u636e\u5c42\u4e2d\u7684\u67e5\u770b\u6210\u7ee9\u65b9\u6cd5\u3002 \u8fd4\u56de\u6210\u7ee9\u7ed9\u89c6\u56fe\u5c42\u5e76\u6253\u5370\u3002 3.\u8001\u5e08 \u00b6 3.1.\u767b\u5f55 \u00b6 \u540c\u4e0a 3.2.\u67e5\u770b\u6559\u6388\u8bfe\u7a0b \u00b6 \u76f4\u63a5\u8c03\u7528\u63a5\u53e3\u5c42\uff0c\u83b7\u53d6\u8001\u5e08\u5bf9\u8c61\u4e0b\u8bfe\u7a0b\u5217\u8868\u6570\u636e\u3002 \u82e5\u6709\u5219\u6253\u5370\uff0c\u6ca1\u6709\u5219\u9000\u51fa\u3002 3.3.\u9009\u62e9\u6559\u6388\u8bfe\u7a0b \u00b6 \u8c03\u7528\u63a5\u53e3\u5c42\u4e2d\u7684\u9009\u62e9\u6559\u6388\u8bfe\u7a0b\u63a5\u53e3\uff0c\u8c03\u7528\u6570\u636e\u5c42\u4e2d\u6539\u8bfe\u7a0b\u4e0b\u6240\u6709\u7684\u5b66\u751f\uff0c\u8fd4\u56de\u7ed9\u89c6\u56fe\u5c42\u3002 \u6253\u5370\u6240\u6709\u7684\u8bfe\u7a0b\uff0c\u8ba9\u8001\u5e08\u9009\u62e9\uff0c\u82e5\u8001\u5e08\u8bfe\u7a0b\u4e2d\u6709\u8be5\u8bfe\u7a0b\u5219\u4e0d\u6dfb\u52a0\u3002 \u6ca1\u6709\uff0c\u5219\u55f2\u7528\u8001\u5e08\u5bf9\u8c61\u4e2d\u7684\u6dfb\u52a0\u8bfe\u7a0b\u65b9\u6cd5\u8fdb\u884c\u6dfb\u52a0\u3002 3.4.\u67e5\u770b\u8bfe\u7a0b\u4e0b\u7684\u5b66\u751f \u00b6 \u76f4\u63a5\u83b7\u53d6\u8001\u5e08\u5bf9\u8c61\u4e0b\u6240\u6709\u7684\u8bfe\u7a0b\uff0c\u9009\u62e9\u8bfe\u7a0b\u3002 \u4ece\u8001\u5e08\u5bf9\u8c61\u4e2d\uff0c\u8c03\u7528\u67e5\u770b\u8bfe\u7a0b\u4e0b\u5b66\u751f\u7684\u65b9\u6cd5\uff0c\u83b7\u53d6\u8bfe\u7a0b\u5bf9\u8c61\u4e0b\u7684\u6240\u6709\u5b66\u751f\uff0c\u8fd4\u56de\u7ed9\u89c6\u56fe\u5c42\u3002 \u89c6\u56fe\u5c42\u6253\u5370\u8be5\u8bfe\u7a0b\u4e0b\u6240\u6709\u7684\u5b66\u751f\u3002 3.5.\u4fee\u6539\u5b66\u751f\u5206\u6570 \u00b6 \u76f4\u63a5\u83b7\u53d6\u8001\u5e08\u5bf9\u8c61\u4e0b\u6240\u6709\u7684\u8bfe\u7a0b\u3002 \u4ece\u8001\u5e08\u5bf9\u8c61\u4e2d\uff0c\u8c03\u7528\u67e5\u770b\u8bfe\u7a0b\u4e0b\u5b66\u751f\u65b9\u6cd5\uff0c\u83b7\u53d6\u8bfe\u7a0b\u5bf9\u8c61\u4e0b\u6240\u6709\u7684\u5b66\u751f\uff0c\u8fd4\u56de\u7ed9\u89c6\u56fe\u5c42\u3002 \u89c6\u56fe\u5c42\u6253\u5370\u6539\u8bfe\u7a0b\u4e0b\u6240\u6709\u7684\u5b66\u751f\uff0c\u5e76\u8ba9\u7528\u6237\u9009\u62e9\u9700\u8981\u5206\u6570\u7684\u5b66\u751f\u3002 \u55f2\u7528\u8001\u5e08\u4fee\u6539\u5206\u6570\u63a5\u53e3\uff0c\u83b7\u53d6\u8001\u5e08\u5bf9\u8c61\uff0c\u8c03\u7528\u5bf9\u8c61\u4e2d\u4fee\u6539\u5206\u6570\u65b9\u6cd5\u3002 \u83b7\u53d6\u5b66\u751f\u5bf9\u8c61\u4e2d\u7684\u5206\u6570\u5b57\u5178\uff0c\u8fdb\u884c\u4fee\u6539\u3002 3.4.\u67e5\u770b\u6210\u7ee9 \u00b6 \u793a\u610f\u56fe \u00b6 \u53c2\u8003\u4ee3\u7801 \u00b6 \u4ee3\u7801","title":"\u9009\u8bfe\u7cfb\u7edf"},{"location":"python/Demo/CourseSystem/#_1","text":"","title":"\u9009\u8bfe\u7cfb\u7edf"},{"location":"python/Demo/CourseSystem/#_2","text":"\u89d2\u8272\uff1a\u5b66\u6821\u3001\u5b66\u5458\u3001\u8bfe\u7a0b\u3001\u8bb2\u5e08 \u8981\u6c42\uff1a \u521b\u5efa\u5317\u4eac\u3001\u4e0a\u6d772\u6240\u5b66\u6821\u3002 \u521b\u5efaLinux\u3001Python\u3001go\u4e09\u4e2a\u8bfe\u7a0b\uff0cLinux\u548cPython\u5728\u5317\u4eac\u5f00\uff0cgo\u5728\u4e0a\u6d77\u5f00\u3002 \u8bfe\u7a0b\u5305\u542b\u5468\u671f\u3001\u4ef7\u683c\uff0c\u901a\u8fc7\u5b66\u6821\u521b\u5efa\u8bfe\u7a0b\u3002 \u901a\u8fc7\u5b66\u6821\u521b\u5efa\u73ed\u7ea7\uff0c\u73ed\u7ea7\u5173\u8054\u8bfe\u7a0b\u3001\u8bb2\u5e08\u3002 \u521b\u5efa\u8bb2\u5e08\u3002 \u521b\u5efa\u5b66\u5458\u65f6\uff0c\u9009\u62e9\u5b66\u6821\uff0c\u5173\u8054\u73ed\u7ea7\u3002 \u521b\u5efa\u8bb2\u5e08\u89d2\u8272\uff08\u4e0d\u9700\u8981\u5173\u8054\u5b66\u6821\uff09\u3002 \u63d0\u4f9b\u4e24\u4e2a\u89d2\u8272\u63a5\u53e3\u3002 \u5b66\u5458\u89c6\u56fe\uff1a\u53ef\u4ee5\u6ce8\u518c\uff0c\u4ea4\u5b66\u8d39\uff0c\u9009\u62e9\u73ed\u7ea7\u3002 \u8bb2\u5e08\u89c6\u56fe\uff1a\u8bb2\u5e08\u53ef\u4ee5\u7ba1\u7406\u81ea\u5df1\u7684\u73ed\u7ea7\uff0c\u4e0a\u8bfe\u65f6\u9009\u62e9\u73ed\u7ea7\uff0c\u67e5\u770b\u73ed\u7ea7\u5b66\u5458\u5217\u8868\uff0c\u4fee\u6539\u6240\u7ba1\u7406\u7684\u5b66\u5458\u7684\u6210\u7ee9\u3002 \u7ba1\u7406\u89c6\u56fe\uff1a\u521b\u5efa\u8bb2\u5e08\uff0c\u521b\u5efa\u73ed\u7ea7\uff0c\u521b\u5efa\u8bfe\u7a0b\u3002 \u4e0a\u8ff0\u64cd\u4f5c\u6240\u4ea7\u751f\u7684\u6570\u636e\u901a\u8fc7pickle\u4fdd\u5b58\u5230\u6587\u4ef6\u3002","title":"\u4efb\u52a1\u9700\u6c42"},{"location":"python/Demo/CourseSystem/#_3","text":"\u7ba1\u7406\u89c6\u56fe \u6ce8\u518c \u767b\u5f55 \u521b\u5efa\u5b66\u6821 \u521b\u5efa\u8bfe\u7a0b\uff08\u5148\u9009\u62e9\u5b66\u6821\uff09 \u521b\u5efa\u8bb2\u5e08 \u5b66\u5458\u89c6\u56fe \u6ce8\u518c \u767b\u5f55\u529f\u80fd \u9009\u62e9\u6821\u533a \u9009\u62e9\u8bfe\u7a0b\uff08\u5148\u9009\u62e9\u6821\u533a\uff0c\u5728\u9009\u62e9\u6821\u533a\u4e2d\u7684\u67d0\u4e00\u95e8\u8bfe\u7a0b\uff0c\u9009\u62e9\u8bfe\u7a0b\u5373\u9009\u62e9\u73ed\u7ea7\uff09 \u5b66\u751f\u9009\u62e9\u8bfe\u7a0b\uff0c\u8bfe\u7a0b\u4e5f\u9009\u62e9\u5b66\u751f \u67e5\u770b\u5206\u6570 \u4ea4\u5b66\u8d39 \u8bb2\u5e08\u89c6\u56fe \u767b\u5f55 \u67e5\u770b\u6559\u6388\u8bfe\u7a0b \u9009\u62e9\u6559\u6388\u8bfe\u7a0b \u67e5\u770b\u8bfe\u7a0b\u4e0b\u7684\u5b66\u751f \u4fee\u6539\u5b66\u751f\u5206\u6570","title":"\u9700\u6c42\u5206\u6790"},{"location":"python/Demo/CourseSystem/#_4","text":"\u7528\u6237\u89c6\u56fe\u5c42 \u7528\u4e8e\u4e0e\u7528\u6237\u8fdb\u884c\u4ea4\u4e92\u3002 \u5b9e\u73b0\u7b80\u5355\u7684\u903b\u8f91\u5224\u65ad\uff0c\u6bd4\u5982\u6ce8\u518c\u529f\u80fd\u4e2d\u4e24\u6b21\u5bc6\u7801\u662f\u5426\u4e00\u81f4\u7684\u6821\u9a8c\u3002 core src.py \u4e3b\u89c6\u56fe admin.py: \u7ba1\u7406\u89c6\u56fe student.py: \u5b66\u5458\u89c6\u56fe teacher.py: \u8bb2\u5e08\u89c6\u56fe \u903b\u8f91\u63a5\u53e3\u5c42 \u6838\u5fc3\u4e1a\u52a1\u903b\u8f91\u7684\u5904\u7406 interface admin_interface.py studeng_interface.py teacher_interface.py \u6570\u636e\u5904\u7406\u5c42 \u6570\u636e\u5904\u7406\uff0c\u6bd4\u5982\u589e\u5220\u6539\u67e5\u3002 db models.py db_handler.py pickle\u4fdd\u5b58\u5bf9\u8c61 object \u2192 pickle","title":"\u67b6\u6784\u8bbe\u8ba1\uff08\u4e09\u5c42\u67b6\u6784\uff09"},{"location":"python/Demo/CourseSystem/#_5","text":"/--conf/ | |--settings.py | |--core/ | |--src.py | |--admin.py | |--student.py | |--teacher.py | |--db/ | |--models.py | |--db_handler.py | |--pickle | |--interface/ | |--admin_interface.py | |--student_interface.py | |--teacher_interface.py | |--common_interface.py | |--lib/ | |--common.py | |--start.py","title":"\u6587\u4ef6\u7ed3\u6784"},{"location":"python/Demo/CourseSystem/#_6","text":"","title":"\u9009\u8bfe\u7cfb\u7edf\u603b\u7ed3"},{"location":"python/Demo/CourseSystem/#1","text":"","title":"1.\u7ba1\u7406\u5458"},{"location":"python/Demo/CourseSystem/#11","text":"\u7528\u6237\u518d\u89c6\u56fe\u5c42\u8f93\u5165\u7528\u6237\u540d\u548c\u5bc6\u7801\uff0c\u4ea4\u7ed9\u63a5\u53e3\u5c42\u3002 \u63a5\u53e3\u5c42\u8c03\u7528\u6570\u636e\u5c42\u4e2d\u7684models.get()\u8fdb\u884c\u6821\u9a8c\u3002 \u82e5\u4e0d\u5b58\u5728\u5219\u521b\u5efa\uff0c\u5e76\u8bb2\u6ce8\u518c\u6210\u529f\u8fd4\u56de\u7ed9\u89c6\u56fe\u5c42\u3002","title":"1.1.\u6ce8\u518c"},{"location":"python/Demo/CourseSystem/#12","text":"\u7528\u6237\u5728\u89c6\u56fe\u5c42\u8f93\u5165\u7528\u6237\u540d\u548c\u5bc6\u7801\uff0c\u4ea4\u7ed9\u63a5\u53e3\u5c42\u3002 \u63a5\u53e3\u5c42\u8c03\u7528\u6570\u636e\u5c42\u4e2d\u7684models.get()\u8fdb\u884c\u6821\u9a8c\u3002 \u82e5\u4e0d\u5b58\u5728\u5219\u521b\u5efa\uff0c\u5e76\u8bb2\u6ce8\u518c\u6210\u529f\u8fd4\u56de\u7ed9\u89c6\u56fe\u5c42\u3002","title":"1.2.\u767b\u5f55"},{"location":"python/Demo/CourseSystem/#13","text":"\u8ba9\u7528\u6237\u8f93\u5165\u5b66\u6821\u540d\u548c\u5b66\u6821\u5730\u5740\u3002 \u8c03\u7528\u7ba1\u7406\u5458\u63a5\u53e3\u521b\u5efa\u5b66\u6821\u3002 \u5224\u65ad\u5b66\u6821\u662f\u5426\u5b58\u5728\uff0c\u82e5\u5b58\u5728\uff0c\u4e0d\u521b\u5efa\u3002 \u82e5\u4e0d\u5b58\u5728\uff0c\u5219\u8c03\u7528\u63a5\u53e3\u5c42\u521b\u5efa\u5b66\u6821\uff0c\u83b7\u53d6\u7ba1\u7406\u5458\u5bf9\u8c61\u7684\u521b\u5efa\u5b66\u6821\u65b9\u6cd5\u4fdd\u6301\u5b66\u6821\u5bf9\u8c61\u3002 \u5c06\u7ed3\u679c\u8fd4\u56de\u7ed9\u89c6\u56fe\u5c42\u3002","title":"1.3.\u521b\u5efa\u5b66\u6821"},{"location":"python/Demo/CourseSystem/#14","text":"\u83b7\u53d6\u6240\u6709\u5b66\u6821\uff0c\u5e76\u6253\u5370\uff0c\u8ba9\u7528\u6237\u9009\u62e9\u3002 \u83b7\u53d6\u7528\u6237\u9009\u62e9\u7684\u5b66\u6821\u4e0e\u521b\u5efa\u7684\u8bfe\u7a0b\uff0c\u4ea4\u7ed9\u63a5\u53e3\u5c42\u3002 \u63a5\u53e3\u5c42\u8c03\u7528\u7ba1\u7406\u5458\u5bf9\u8c61\u4e2d\u7684\u521b\u5efa\u8bfe\u7a0b\u65b9\u6cd5\uff0c\u4fdd\u5b58\u8bfe\u7a0b\u5bf9\u8c61\u3002 \u8bfe\u7a0b\u9700\u8981\u7ed1\u5b9a\u7ed9\u5b66\u6821\u5bf9\u8c61\uff0c\u6700\u7ec8\u5c06\u521b\u5efa\u6210\u529f\u7684\u7ed3\u679c\u8fd4\u56de\u7ed9\u89c6\u56fe\u5c42\u3002","title":"1.4.\u521b\u5efa\u8bfe\u7a0b"},{"location":"python/Demo/CourseSystem/#15","text":"\u7528\u6237\u8f93\u5165\u8001\u5e08\u540d\u79f0\u3002 \u8c03\u7528\u63a5\u53e3\u5c42\uff0c\u63a5\u53e3\u5c42\u4e2d\u8bbe\u7f6e\u9ed8\u8ba4\u5bc6\u7801123\uff0c\u8c03\u7528\u6570\u636e\u5c42\u3002 \u5224\u65ad\u8001\u5e08\u662f\u5426\u5b58\u5728\uff0c\u4e0d\u5b58\u5728\u5219\u8c03\u7528\u7ba1\u7406\u5458\u5bf9\u8c61\u4e2d\u7684\u521b\u5efa\u8001\u5e08\u65b9\u6cd5\u3002 \u4fdd\u5b58\u8001\u5e08\u5bf9\u8c61\uff0c\u5e76\u5c06\u7ed3\u679c\u8fd4\u56de\u7ed9\u89c6\u56fe\u5c42\u3002","title":"1.5.\u521b\u5efa\u8001\u5e08"},{"location":"python/Demo/CourseSystem/#2","text":"","title":"2.\u5b66\u751f"},{"location":"python/Demo/CourseSystem/#21","text":"\u540c\u4e0a","title":"2.1.\u6ce8\u518c"},{"location":"python/Demo/CourseSystem/#22","text":"\u540c\u4e0a","title":"2.2.\u767b\u5f55"},{"location":"python/Demo/CourseSystem/#23","text":"\u83b7\u53d6\u6240\u6709\u5b66\u6821\uff0c\u8ba9\u5b66\u751f\u9009\u62e9\uff0c\u5e76\u5c06\u9009\u62e9\u7684\u5b66\u6821\u4f20\u7ed9\u63a5\u53e3\u5c42\u3002 \u63a5\u53e3\u5c42\u5224\u65ad\u5f53\u524d\u5b66\u751f\u662f\u5426\u9009\u62e9\u5b66\u6821\u3002 \u82e5\u6ca1\u6709\u9009\u62e9\uff0c\u5219\u8c03\u7528\u5b66\u751f\u5bf9\u8c61\u4e2d\u7684\u6dfb\u52a0\u5b66\u6821\u65b9\u6cd5\u3002 \u5c06\u6dfb\u52a0\u540e\u6d88\u606f\u8fd4\u56de\u7ed9\u89c6\u56fe\u5c42\u3002","title":"2.3.\u9009\u62e9\u5b66\u6821"},{"location":"python/Demo/CourseSystem/#24","text":"\u5148\u83b7\u53d6\u5f53\u524d\u5b66\u751f\u6240\u5728\u5b66\u6821\u7684\u6240\u6709\u8bfe\u7a0b\uff0c\u5e76\u9009\u62e9\u3002 \u63a5\u53e3\u5c42\u5c06\u9009\u62e9\u540e\u7684\u8bfe\u7a0b\uff0c\u8c03\u7528\u6570\u636e\u5c42\u7684\u6dfb\u52a0\u8bfe\u7a0b\u65b9\u6cd5\u4fdd\u5b58\u3002 \u5b66\u751f\u5bf9\u8c61\u4e2d\u8bfe\u7a0b\u5217\u8868\u6dfb\u52a0\u8bfe\u7a0b\uff0c\u8bbe\u7f6e\u8bfe\u7a0b\u5206\u6570\uff0c\u9ed8\u8ba4\u4e3a0. \u6700\u7ec8\u5c06\u7ed3\u679c\u8fd4\u56de\u7ed9\u89c6\u56fe\u5c42\u3002","title":"2.4.\u9009\u62e9\u8bfe\u7a0b"},{"location":"python/Demo/CourseSystem/#25","text":"\u76f4\u63a5\u8c03\u7528\u63a5\u53e3\u5c42\u3002 \u63a5\u53e3\u5c42\u8c03\u7528\u6570\u636e\u5c42\u4e2d\u7684\u67e5\u770b\u6210\u7ee9\u65b9\u6cd5\u3002 \u8fd4\u56de\u6210\u7ee9\u7ed9\u89c6\u56fe\u5c42\u5e76\u6253\u5370\u3002","title":"2.5.\u67e5\u770b\u6210\u7ee9"},{"location":"python/Demo/CourseSystem/#3","text":"","title":"3.\u8001\u5e08"},{"location":"python/Demo/CourseSystem/#31","text":"\u540c\u4e0a","title":"3.1.\u767b\u5f55"},{"location":"python/Demo/CourseSystem/#32","text":"\u76f4\u63a5\u8c03\u7528\u63a5\u53e3\u5c42\uff0c\u83b7\u53d6\u8001\u5e08\u5bf9\u8c61\u4e0b\u8bfe\u7a0b\u5217\u8868\u6570\u636e\u3002 \u82e5\u6709\u5219\u6253\u5370\uff0c\u6ca1\u6709\u5219\u9000\u51fa\u3002","title":"3.2.\u67e5\u770b\u6559\u6388\u8bfe\u7a0b"},{"location":"python/Demo/CourseSystem/#33","text":"\u8c03\u7528\u63a5\u53e3\u5c42\u4e2d\u7684\u9009\u62e9\u6559\u6388\u8bfe\u7a0b\u63a5\u53e3\uff0c\u8c03\u7528\u6570\u636e\u5c42\u4e2d\u6539\u8bfe\u7a0b\u4e0b\u6240\u6709\u7684\u5b66\u751f\uff0c\u8fd4\u56de\u7ed9\u89c6\u56fe\u5c42\u3002 \u6253\u5370\u6240\u6709\u7684\u8bfe\u7a0b\uff0c\u8ba9\u8001\u5e08\u9009\u62e9\uff0c\u82e5\u8001\u5e08\u8bfe\u7a0b\u4e2d\u6709\u8be5\u8bfe\u7a0b\u5219\u4e0d\u6dfb\u52a0\u3002 \u6ca1\u6709\uff0c\u5219\u55f2\u7528\u8001\u5e08\u5bf9\u8c61\u4e2d\u7684\u6dfb\u52a0\u8bfe\u7a0b\u65b9\u6cd5\u8fdb\u884c\u6dfb\u52a0\u3002","title":"3.3.\u9009\u62e9\u6559\u6388\u8bfe\u7a0b"},{"location":"python/Demo/CourseSystem/#34","text":"\u76f4\u63a5\u83b7\u53d6\u8001\u5e08\u5bf9\u8c61\u4e0b\u6240\u6709\u7684\u8bfe\u7a0b\uff0c\u9009\u62e9\u8bfe\u7a0b\u3002 \u4ece\u8001\u5e08\u5bf9\u8c61\u4e2d\uff0c\u8c03\u7528\u67e5\u770b\u8bfe\u7a0b\u4e0b\u5b66\u751f\u7684\u65b9\u6cd5\uff0c\u83b7\u53d6\u8bfe\u7a0b\u5bf9\u8c61\u4e0b\u7684\u6240\u6709\u5b66\u751f\uff0c\u8fd4\u56de\u7ed9\u89c6\u56fe\u5c42\u3002 \u89c6\u56fe\u5c42\u6253\u5370\u8be5\u8bfe\u7a0b\u4e0b\u6240\u6709\u7684\u5b66\u751f\u3002","title":"3.4.\u67e5\u770b\u8bfe\u7a0b\u4e0b\u7684\u5b66\u751f"},{"location":"python/Demo/CourseSystem/#35","text":"\u76f4\u63a5\u83b7\u53d6\u8001\u5e08\u5bf9\u8c61\u4e0b\u6240\u6709\u7684\u8bfe\u7a0b\u3002 \u4ece\u8001\u5e08\u5bf9\u8c61\u4e2d\uff0c\u8c03\u7528\u67e5\u770b\u8bfe\u7a0b\u4e0b\u5b66\u751f\u65b9\u6cd5\uff0c\u83b7\u53d6\u8bfe\u7a0b\u5bf9\u8c61\u4e0b\u6240\u6709\u7684\u5b66\u751f\uff0c\u8fd4\u56de\u7ed9\u89c6\u56fe\u5c42\u3002 \u89c6\u56fe\u5c42\u6253\u5370\u6539\u8bfe\u7a0b\u4e0b\u6240\u6709\u7684\u5b66\u751f\uff0c\u5e76\u8ba9\u7528\u6237\u9009\u62e9\u9700\u8981\u5206\u6570\u7684\u5b66\u751f\u3002 \u55f2\u7528\u8001\u5e08\u4fee\u6539\u5206\u6570\u63a5\u53e3\uff0c\u83b7\u53d6\u8001\u5e08\u5bf9\u8c61\uff0c\u8c03\u7528\u5bf9\u8c61\u4e2d\u4fee\u6539\u5206\u6570\u65b9\u6cd5\u3002 \u83b7\u53d6\u5b66\u751f\u5bf9\u8c61\u4e2d\u7684\u5206\u6570\u5b57\u5178\uff0c\u8fdb\u884c\u4fee\u6539\u3002","title":"3.5.\u4fee\u6539\u5b66\u751f\u5206\u6570"},{"location":"python/Demo/CourseSystem/#34_1","text":"","title":"3.4.\u67e5\u770b\u6210\u7ee9"},{"location":"python/Demo/CourseSystem/#_7","text":"","title":"\u793a\u610f\u56fe"},{"location":"python/Demo/CourseSystem/#_8","text":"\u4ee3\u7801","title":"\u53c2\u8003\u4ee3\u7801"},{"location":"python/Foundation/ch00/","text":"Python\u5b89\u88c5 \u00b6 Python\u73af\u5883 \u00b6 \u8fd9\u91cc\u4f7f\u7528\u7cfb\u7edf\u81ea\u5e26\u7684Python\u73af\u5883\uff1a \u4e3b\u673a\uff1aVMWare\u865a\u62df\u673a \u64cd\u4f5c\u7cfb\u7edf(Guest)\uff1aopenSUSE 15.3 Python\u7248\u672c\uff1a3.6.15(openSUSE\u81ea\u5e26) \u68c0\u67e5Python\u7248\u672c \u00b6 $ python --version Python 2 .7.18 $ python3 --version Python 3 .6.15 \u5347\u7ea7pip \u00b6 $ pip3 install --upgrade pip $ pip --version pip 21 .3.1 from /home/james/.local/lib/python3.6/site-packages/pip ( python 3 .6 ) $ pip3 --version pip 21 .3.1 from /home/james/.local/lib/python3.6/site-packages/pip ( python 3 .6 ) pip\u56fd\u5185\u6e90 \u00b6 https://mirrors.aliyun.com/pypi/simple/ https://pypi.tuna.tsinghua.edu.cn/simple/ http://pypi.doubanio.com/simple/ https://mirrors.cloud.tencent.com/pypi/simple/ \u5b89\u88c5Python\u5305(\u6307\u5b9a\u6e90) \u00b6 pip3 install jinja2 -i https://mirrors.aliyun.com/pypi/simple/ pip3 install Django -i https://mirrors.aliyun.com/pypi/simple/ pip3 install sqlite_utils -i https://mirrors.aliyun.com/pypi/simple/ pip3 install pymongo -i https://mirrors.aliyun.com/pypi/simple/ pip3 install numpy -i https://mirrors.aliyun.com/pypi/simple/ pip3 install matplotlib -i https://mirrors.aliyun.com/pypi/simple/ pip3 install scikit-learn -i https://mirrors.aliyun.com/pypi/simple/ pip3 install xlrd -i https://mirrors.aliyun.com/pypi/simple/ pip3 install pandas -i https://mirrors.aliyun.com/pypi/simple/ pip3 install pydotplus -i https://mirrors.aliyun.com/pypi/simple/ pip3 install seaborn -i https://mirrors.aliyun.com/pypi/simple/ pip3 install selenium -i https://mirrors.aliyun.com/pypi/simple/ pip3 install mlxtend -i https://mirrors.aliyun.com/pypi/simple/ pip3 install pandas-datareader -i https://mirrors.aliyun.com/pypi/simple/ pip3 install lxml -i https://mirrors.aliyun.com/pypi/simple/ pip3 install beautifulsoup4 -i https://mirrors.aliyun.com/pypi/simple/ pip3 install html5lib -i https://mirrors.aliyun.com/pypi/simple/ pip3 install tables -i https://mirrors.aliyun.com/pypi/simple/ pip3 install openpyxl -i https://mirrors.aliyun.com/pypi/simple/ pip3 install sqlalchemy -i https://mirrors.aliyun.com/pypi/simple/ pip3 install statsmodels -i https://mirrors.aliyun.com/pypi/simple/ pip3 install patsy -i https://mirrors.aliyun.com/pypi/simple/ pip3 install numba -i https://mirrors.aliyun.com/pypi/simple/ pip3 install jason -i https://mirrors.aliyun.com/pypi/simple/ pip3 install openpyxl -i https://mirrors.aliyun.com/pypi/simple/ \u6e90\u7801\u7f16\u8bd1\u65b9\u6cd5 \u00b6 \u4e0b\u9762\u662f\u6e90\u7801\u7f16\u8bd1\u65b9\u5f0f\u81ea\u884c\u5b89\u88c5Python\u7684\u65b9\u6cd5\uff0c\u4ee53.9.6\u7248\u672c\u4e3a\u4f8b\u3002 \u5b98\u7f51\u4e0b\u8f7dpython3.9.6 \uff08 \u8fde\u63a5 \uff09 \u89e3\u538b\u5b89\u88c5\u5305 tar xvf Python-3.9.6.tgz \u5b89\u88c5\u8def\u5f84\u4e3a /opt/Python-3.9.6/ \uff0c\u9700\u8981\u628a\u5b89\u88c5\u8def\u5f84\u7684owner\u6539\u4e3a\u5f53\u524d\u7528\u6237\uff0c\u5426\u5219\u540e\u671fpython\u7f16\u8bd1\u4ee5\u53ca\u4f7f\u7528pip\u5b89\u88c5python\u5305\u4f1a\u62a5\u9519\u3002 chown -R james.wheel /opt/Python-3.9.6 \u5728\u5b89\u88c5\u524d\u7684\u4e00\u4e9b\u5efa\u8bae \u5728openSUSE\u4e2d\u628a\u5f00\u53d1\u5305\u90fd\u5b89\u88c5\u4e00\u4e0b\uff0c\u7279\u522b\u662fc\u548cc++\u7684\u5f00\u53d1\u5305\u3002\u8fd9\u4e9b\u90fd\u662fPython\u7f16\u8bd1\u7684\u4f9d\u8d56\u5305\u3002 \u5728openSUSE\u4e2d\u5b89\u88c5sqlite3. \u4f7f\u7528openSUSE\u81ea\u5e26\u7684openSSL\uff0c\u5982\u679c\u81ea\u884c\u7f16\u8bd1openSSL\uff0c\u5728\u7f16\u8bd1Python\u65f6\u4f1a\u9047\u5230\u4e00\u4e9b\u672a\u77e5\u95ee\u9898\u3002 \u7f16\u8bd1\u548c\u5b89\u88c5\uff1a cd /opt/Python-3.9.6 sudo ./configure --enable-optimizations --with-ensurepip = install sudo make sudo make test sudo make install \u4fee\u6539\u7cfb\u7edf\u9ed8\u8ba4Python\u7684\u914d\u7f6e\uff0c\u5c06python3\u6307\u5411\u65b0\u5b89\u88c5\u7684Python\u3002\u9700\u8981\u4fee\u6539\u7684\u8def\u5f84\u67092\u4e2a\uff0c /usr/bin/python3 \u548c /usr/local/bin/ \u5c06 /usr/bin/python3 \u91cd\u65b0\u6307\u5411\u65b0\u5b89\u88c5\u7684Python\u3002 sudo rm /usr/bin/python3 sudo ln -s /opt/Python-3.9.6/python /usr/bin/python3 \u68c0\u67e5 /usr/local/bin/ \u76ee\u5f55\u4e0b\u7684python\u6587\u4ef6\u662f\u5426\u6307\u5411\u65b0\u5b89\u88c5\u7684Pyton\u3002\u9ed8\u8ba4\u662f\u7f16\u8bd1\u5b89\u88c5\u5b8c\u6210\u540e\u5df2\u7ecf\u88ab\u4fee\u6539\u4e86\u3002 $ ls -l /usr/local/bin/python* lrwxrwxrwx 1 root root 9 Jul 25 02 :15 python3 -> python3.9 -rwxr-xr-x 1 root root 17645928 Jul 25 02 :14 python3.9 -rwxr-xr-x 1 root root 3087 Jul 25 02 :15 python3.9-config lrwxrwxrwx 1 root root 16 Jul 25 02 :15 python3-config -> python3.9-config \u9a8c\u8bc1python\u7684\u7248\u672c\u3002 $ python Python 2 .7.18 ( default, Mar 04 2021 , 23 :25:57 ) [ GCC ] on linux2 $ python3 Python 3 .9.6 ( default, Jul 25 2021 , 02 :13:27 ) [ GCC 7 .5.0 ] on linux \u6dfb\u52a0\u4e0b\u9762\u7684\u73af\u5883\u53d8\u91cf\u5230\u914d\u7f6e\u6587\u4ef6 /etc/profile.local \u3002 export PATH = /usr/local/bin:/home/ $USER /.local/bin: $PATH \u5e76\u6267\u884c\u4e0b\u9762\u7684\u547d\u4ee4\u4f7f\u4e4b\u751f\u6548\u3002 source /etc/profile.local \u4e0b\u9762\u4fee\u6539pip\u7684\u914d\u7f6e\u3002 $ whereis pip pip: /usr/bin/pip /usr/bin/pip3.6 /usr/local/bin/pip3.9 \u901a\u8fc7\u4e0b\u9762\u53ef\u4ee5\u770b\u5230pip\u5b9e\u9645\u6307\u5411\u7684\u662f\u7cfb\u7edf\u9ed8\u8ba4\u76843.6\u7248\u672c\u3002 $ l /usr/bin/pip* lrwxrwxrwx 1 root root 21 Dec 4 2020 /usr/bin/pip -> /etc/alternatives/pip* -rwxr-xr-x 1 root root 367 Dec 4 2020 /usr/bin/pip3* -rwxr-xr-x 1 root root 371 Dec 4 2020 /usr/bin/pip3.6* -rwxr-xr-x 1 root root 10608 Jun 10 06 :15 /usr/bin/pipewire* -rwxr-xr-x 1 root root 720208 Jun 10 06 :15 /usr/bin/pipewire-media-session* james@lizard:/opt> l /etc/alternatives/pip* lrwxrwxrwx 1 root root 15 Jul 24 20 :24 /etc/alternatives/pip -> /usr/bin/pip3.6* \u68c0\u67e5\u4e00\u4e0b\u5f53\u524dpip\u5728alternative\u91cc\u9762\u7684\u8bbe\u7f6e\u3002 $ sudo update-alternatives --display pip pip - auto mode link best version is /usr/bin/pip3.6 link currently points to /usr/bin/pip3.6 link pip is /usr/bin/pip /usr/bin/pip3.6 - priority 36 \u5220\u9664\u8001\u7248\u672c\uff0c\u6dfb\u52a0\u65b0\u7248\u672c\u3002 $ sudo update-alternatives --remove pip /usr/bin/pip3.6 $ sudo update-alternatives --install /usr/bin/pip pip /usr/bin/pip3.9 100 update-alternatives: using /usr/bin/pip3.9 to provide /usr/bin/pip ( pip ) in auto mode","title":"Python\u5b89\u88c5"},{"location":"python/Foundation/ch00/#python","text":"","title":"Python\u5b89\u88c5"},{"location":"python/Foundation/ch00/#python_1","text":"\u8fd9\u91cc\u4f7f\u7528\u7cfb\u7edf\u81ea\u5e26\u7684Python\u73af\u5883\uff1a \u4e3b\u673a\uff1aVMWare\u865a\u62df\u673a \u64cd\u4f5c\u7cfb\u7edf(Guest)\uff1aopenSUSE 15.3 Python\u7248\u672c\uff1a3.6.15(openSUSE\u81ea\u5e26)","title":"Python\u73af\u5883"},{"location":"python/Foundation/ch00/#python_2","text":"$ python --version Python 2 .7.18 $ python3 --version Python 3 .6.15","title":"\u68c0\u67e5Python\u7248\u672c"},{"location":"python/Foundation/ch00/#pip","text":"$ pip3 install --upgrade pip $ pip --version pip 21 .3.1 from /home/james/.local/lib/python3.6/site-packages/pip ( python 3 .6 ) $ pip3 --version pip 21 .3.1 from /home/james/.local/lib/python3.6/site-packages/pip ( python 3 .6 )","title":"\u5347\u7ea7pip"},{"location":"python/Foundation/ch00/#pip_1","text":"https://mirrors.aliyun.com/pypi/simple/ https://pypi.tuna.tsinghua.edu.cn/simple/ http://pypi.doubanio.com/simple/ https://mirrors.cloud.tencent.com/pypi/simple/","title":"pip\u56fd\u5185\u6e90"},{"location":"python/Foundation/ch00/#python_3","text":"pip3 install jinja2 -i https://mirrors.aliyun.com/pypi/simple/ pip3 install Django -i https://mirrors.aliyun.com/pypi/simple/ pip3 install sqlite_utils -i https://mirrors.aliyun.com/pypi/simple/ pip3 install pymongo -i https://mirrors.aliyun.com/pypi/simple/ pip3 install numpy -i https://mirrors.aliyun.com/pypi/simple/ pip3 install matplotlib -i https://mirrors.aliyun.com/pypi/simple/ pip3 install scikit-learn -i https://mirrors.aliyun.com/pypi/simple/ pip3 install xlrd -i https://mirrors.aliyun.com/pypi/simple/ pip3 install pandas -i https://mirrors.aliyun.com/pypi/simple/ pip3 install pydotplus -i https://mirrors.aliyun.com/pypi/simple/ pip3 install seaborn -i https://mirrors.aliyun.com/pypi/simple/ pip3 install selenium -i https://mirrors.aliyun.com/pypi/simple/ pip3 install mlxtend -i https://mirrors.aliyun.com/pypi/simple/ pip3 install pandas-datareader -i https://mirrors.aliyun.com/pypi/simple/ pip3 install lxml -i https://mirrors.aliyun.com/pypi/simple/ pip3 install beautifulsoup4 -i https://mirrors.aliyun.com/pypi/simple/ pip3 install html5lib -i https://mirrors.aliyun.com/pypi/simple/ pip3 install tables -i https://mirrors.aliyun.com/pypi/simple/ pip3 install openpyxl -i https://mirrors.aliyun.com/pypi/simple/ pip3 install sqlalchemy -i https://mirrors.aliyun.com/pypi/simple/ pip3 install statsmodels -i https://mirrors.aliyun.com/pypi/simple/ pip3 install patsy -i https://mirrors.aliyun.com/pypi/simple/ pip3 install numba -i https://mirrors.aliyun.com/pypi/simple/ pip3 install jason -i https://mirrors.aliyun.com/pypi/simple/ pip3 install openpyxl -i https://mirrors.aliyun.com/pypi/simple/","title":"\u5b89\u88c5Python\u5305(\u6307\u5b9a\u6e90)"},{"location":"python/Foundation/ch00/#_1","text":"\u4e0b\u9762\u662f\u6e90\u7801\u7f16\u8bd1\u65b9\u5f0f\u81ea\u884c\u5b89\u88c5Python\u7684\u65b9\u6cd5\uff0c\u4ee53.9.6\u7248\u672c\u4e3a\u4f8b\u3002 \u5b98\u7f51\u4e0b\u8f7dpython3.9.6 \uff08 \u8fde\u63a5 \uff09 \u89e3\u538b\u5b89\u88c5\u5305 tar xvf Python-3.9.6.tgz \u5b89\u88c5\u8def\u5f84\u4e3a /opt/Python-3.9.6/ \uff0c\u9700\u8981\u628a\u5b89\u88c5\u8def\u5f84\u7684owner\u6539\u4e3a\u5f53\u524d\u7528\u6237\uff0c\u5426\u5219\u540e\u671fpython\u7f16\u8bd1\u4ee5\u53ca\u4f7f\u7528pip\u5b89\u88c5python\u5305\u4f1a\u62a5\u9519\u3002 chown -R james.wheel /opt/Python-3.9.6 \u5728\u5b89\u88c5\u524d\u7684\u4e00\u4e9b\u5efa\u8bae \u5728openSUSE\u4e2d\u628a\u5f00\u53d1\u5305\u90fd\u5b89\u88c5\u4e00\u4e0b\uff0c\u7279\u522b\u662fc\u548cc++\u7684\u5f00\u53d1\u5305\u3002\u8fd9\u4e9b\u90fd\u662fPython\u7f16\u8bd1\u7684\u4f9d\u8d56\u5305\u3002 \u5728openSUSE\u4e2d\u5b89\u88c5sqlite3. \u4f7f\u7528openSUSE\u81ea\u5e26\u7684openSSL\uff0c\u5982\u679c\u81ea\u884c\u7f16\u8bd1openSSL\uff0c\u5728\u7f16\u8bd1Python\u65f6\u4f1a\u9047\u5230\u4e00\u4e9b\u672a\u77e5\u95ee\u9898\u3002 \u7f16\u8bd1\u548c\u5b89\u88c5\uff1a cd /opt/Python-3.9.6 sudo ./configure --enable-optimizations --with-ensurepip = install sudo make sudo make test sudo make install \u4fee\u6539\u7cfb\u7edf\u9ed8\u8ba4Python\u7684\u914d\u7f6e\uff0c\u5c06python3\u6307\u5411\u65b0\u5b89\u88c5\u7684Python\u3002\u9700\u8981\u4fee\u6539\u7684\u8def\u5f84\u67092\u4e2a\uff0c /usr/bin/python3 \u548c /usr/local/bin/ \u5c06 /usr/bin/python3 \u91cd\u65b0\u6307\u5411\u65b0\u5b89\u88c5\u7684Python\u3002 sudo rm /usr/bin/python3 sudo ln -s /opt/Python-3.9.6/python /usr/bin/python3 \u68c0\u67e5 /usr/local/bin/ \u76ee\u5f55\u4e0b\u7684python\u6587\u4ef6\u662f\u5426\u6307\u5411\u65b0\u5b89\u88c5\u7684Pyton\u3002\u9ed8\u8ba4\u662f\u7f16\u8bd1\u5b89\u88c5\u5b8c\u6210\u540e\u5df2\u7ecf\u88ab\u4fee\u6539\u4e86\u3002 $ ls -l /usr/local/bin/python* lrwxrwxrwx 1 root root 9 Jul 25 02 :15 python3 -> python3.9 -rwxr-xr-x 1 root root 17645928 Jul 25 02 :14 python3.9 -rwxr-xr-x 1 root root 3087 Jul 25 02 :15 python3.9-config lrwxrwxrwx 1 root root 16 Jul 25 02 :15 python3-config -> python3.9-config \u9a8c\u8bc1python\u7684\u7248\u672c\u3002 $ python Python 2 .7.18 ( default, Mar 04 2021 , 23 :25:57 ) [ GCC ] on linux2 $ python3 Python 3 .9.6 ( default, Jul 25 2021 , 02 :13:27 ) [ GCC 7 .5.0 ] on linux \u6dfb\u52a0\u4e0b\u9762\u7684\u73af\u5883\u53d8\u91cf\u5230\u914d\u7f6e\u6587\u4ef6 /etc/profile.local \u3002 export PATH = /usr/local/bin:/home/ $USER /.local/bin: $PATH \u5e76\u6267\u884c\u4e0b\u9762\u7684\u547d\u4ee4\u4f7f\u4e4b\u751f\u6548\u3002 source /etc/profile.local \u4e0b\u9762\u4fee\u6539pip\u7684\u914d\u7f6e\u3002 $ whereis pip pip: /usr/bin/pip /usr/bin/pip3.6 /usr/local/bin/pip3.9 \u901a\u8fc7\u4e0b\u9762\u53ef\u4ee5\u770b\u5230pip\u5b9e\u9645\u6307\u5411\u7684\u662f\u7cfb\u7edf\u9ed8\u8ba4\u76843.6\u7248\u672c\u3002 $ l /usr/bin/pip* lrwxrwxrwx 1 root root 21 Dec 4 2020 /usr/bin/pip -> /etc/alternatives/pip* -rwxr-xr-x 1 root root 367 Dec 4 2020 /usr/bin/pip3* -rwxr-xr-x 1 root root 371 Dec 4 2020 /usr/bin/pip3.6* -rwxr-xr-x 1 root root 10608 Jun 10 06 :15 /usr/bin/pipewire* -rwxr-xr-x 1 root root 720208 Jun 10 06 :15 /usr/bin/pipewire-media-session* james@lizard:/opt> l /etc/alternatives/pip* lrwxrwxrwx 1 root root 15 Jul 24 20 :24 /etc/alternatives/pip -> /usr/bin/pip3.6* \u68c0\u67e5\u4e00\u4e0b\u5f53\u524dpip\u5728alternative\u91cc\u9762\u7684\u8bbe\u7f6e\u3002 $ sudo update-alternatives --display pip pip - auto mode link best version is /usr/bin/pip3.6 link currently points to /usr/bin/pip3.6 link pip is /usr/bin/pip /usr/bin/pip3.6 - priority 36 \u5220\u9664\u8001\u7248\u672c\uff0c\u6dfb\u52a0\u65b0\u7248\u672c\u3002 $ sudo update-alternatives --remove pip /usr/bin/pip3.6 $ sudo update-alternatives --install /usr/bin/pip pip /usr/bin/pip3.9 100 update-alternatives: using /usr/bin/pip3.9 to provide /usr/bin/pip ( pip ) in auto mode","title":"\u6e90\u7801\u7f16\u8bd1\u65b9\u6cd5"},{"location":"python/Foundation/ch01/","text":"Python\u8bed\u8a00\u57fa\u7840 \u00b6 1. Python\u6570\u636e\u7c7b\u578b\uff086\u4e2a\uff09 \u00b6 6\u4e2aPython\u6570\u636e\u7c7b\u578b\uff1a \u6570\u503c\u578b\uff08number\uff09\uff1a\u8868\u793a\u6570\u636e\u7ec4\u6210\u4e3a\u6570\u5b57 \u6574\u578b\uff08int\uff09 \u5341\u8fdb\u5236 \u516b\u8fdb\u5236 \u5341\u516d\u8fdb\u5236 \u6d6e\u70b9\u578b\uff08float\uff09 \u5e03\u5c14\u578b\uff08bool\uff09 \u590d\u6570\u6027\uff08complex\uff09 \u5b57\u7b26\u578b\uff08string\uff09\uff1a\u8868\u793a\u6570\u636e\u7ec4\u6210\u662f\u5b57\u7b26 \u5217\u8868\uff08list\uff09\uff1a\u7528\u6765\u8868\u793a\u4e00\u7ec4\u6709\u5e8f\u5143\u7d20\uff0c\u540e\u671f\u6570\u636e\u53ef\u4ee5\u4fee\u6539 ['A','B','C'] \u5143\u7ec4\uff08tuple\uff09\uff1a\u7528\u6765\u8868\u793a\u4e00\u7ec4\u6709\u5e8f\u5143\u7d20\uff0c\u540e\u671f\u6570\u636e\u4e0d\u53ef\u4fee\u6539 ('A','B','C','1') \u96c6\u5408\uff08set\uff09\uff1a\u4e00\u7ec4\u6570\u636e\u65e0\u5e8f\u4e0d\u91cd\u590d\u5143\u7d20 set([1,2,3,4]) \u5b57\u5178\uff08dictionary\uff09\uff1a\u7528\u952e\u503c\u5bf9\u7684\u5f62\u5f0f\u4fdd\u5b58\u4e00\u7ec4\u5143\u7d20 {'A':7,'B':1,'C':9} \u53ef\u8fed\u4ee3\u5bf9\u8c61\uff08Iterable\uff09\uff1a An object capable of returning its members one at a time. Examples of iterables include all sequence types (such as list, str, and tuple) and some non-sequence types like dict, file objects, and objects of any classes you define with an iter() method or with a getitem() method that implements Sequence semantics. \u5e8f\u5217\uff08Sequence\uff09\uff1a An iterable which supports efficient element access using integer indices via the getitem() special method and defines a len() method that returns the length of the sequence. Some built-in sequence types are list, str, tuple, and bytes. Note that dict also supports getitem() and len(), but is considered a mapping rather than a sequence because the lookups use arbitrary immutable keys rather than integers. \u8fed\u4ee3\u5668\uff08Iterator\uff09\uff1a An object representing a stream of data. Repeated calls to the iterator\u2019s next() method (or passing it to the built-in function next()) return successive items in the stream. When no more data are available a StopIteration exception is raised instead. At this point, the iterator object is exhausted and any further calls to its next() method just raise StopIteration again. Iterators are required to have an iter() method that returns the iterator object itself so every iterator is also iterable and may be used in most places where other iterables are accepted. One notable exception is code which attempts multiple iteration passes. A container object (such as a list) produces a fresh new iterator each time you pass it to the iter() function or use it in a for loop. Attempting this with an iterator will just return the same exhausted iterator object used in the previous iteration pass, making it appear like an empty container. \u53ef\u53d8\u6570\u636e\uff08immutable\uff09 \u5217\u8868\uff08list\uff09 \u5b57\u5178\uff08dictionary\uff09 \u96c6\u5408\uff08set\uff09\u3002 \u4e0d\u53ef\u53d8\u6570\u636e\uff08immutable\uff09 \u6570\u5b57\uff08number\uff09 \u5b57\u7b26\uff08string\uff09 \u5143\u7ec4\uff08tuple\uff09 \u53ef\u8fed\u4ee3\uff08iterable\uff09 \u5b57\u7b26\uff08string\uff09 \u5143\u7ec4\uff08tuple\uff09 \u5217\u8868\uff08list\uff09 \u5b57\u5178\uff08dictionary\uff09 \u96c6\u5408\uff08set\uff09 \u5e8f\u5217 \u6709\u5e8f\u5e8f\u5217\uff1a\u5b57\u7b26\uff08string\uff09\uff0c\u5143\u7ec4\uff08tuple\uff09\uff0c\u5217\u8868\uff08list\uff09 \u65e0\u5e8f\u5e8f\u5217\uff1a\u5b57\u5178\uff08dictionary\uff09\uff0c\u96c6\u5408\uff08set\uff09 Python\u5e8f\u5217\u7c7b\u578b\u6700\u5e38\u89c1\u7684\u5206\u7c7b\u5c31\u662f\u53ef\u53d8\u548c\u4e0d\u53ef\u53d8\u5e8f\u5217\u3002\u4f46\u53e6\u5916\u4e00\u79cd\u5206\u7c7b\u65b9\u5f0f\u4e5f\u5f88\u6709\u7528\uff0c\u90a3\u5c31\u662f\u628a\u5b83\u4eec\u5206\u4e3a**\u6241\u5e73\u5e8f\u5217**\u548c**\u5bb9\u5668\u5e8f\u5217**\u3002\u524d\u8005\u7684\u4f53\u79ef\u66f4\u5c0f\u3001\u901f\u5ea6\u66f4\u5feb\u800c\u4e14\u7528\u8d77\u6765\u66f4\u7b80\u5355\uff0c\u4f46\u662f\u5b83\u53ea\u80fd\u4fdd\u5b58\u4e00\u4e9b\u539f\u5b50\u6027\u7684\u6570\u636e\uff0c\u6bd4\u5982\u6570\u5b57\u3001\u5b57\u7b26\u548c\u5b57\u8282\u3002\u5bb9\u5668\u5e8f\u5217\u5219\u6bd4\u8f83\u7075\u6d3b\uff0c\u4f46\u662f\u5f53\u5bb9\u5668\u5e8f\u5217\u9047\u5230\u53ef\u53d8\u5bf9\u8c61\u65f6\uff0c\u5c31\u9700\u8981\u683c\u5916\u5c0f\u5fc3\uff0c\u56e0\u4e3a\u8fd9\u79cd\u7ec4\u5408\u65f6\u5e38\u4f1a\u51fa\u73b0\u4e00\u4e9b\u201c\u610f\u5916\u201d\uff0c\u7279\u522b\u662f\u5e26\u5d4c\u5957\u7684\u6570\u636e\u7ed3\u6784\u51fa\u73b0\u65f6\uff0c\u66f4\u9700\u8981\u9a8c\u8bc1\u4ee3\u7801\u7684\u6b63\u786e\u6027\u3002 Python\u4e2d\u7684\u53d8\u91cf\u3001\u5e38\u91cf\u548c\u5b57\u9762\u91cf \u53d8\u91cf \u53d8\u91cf\u662f\u7528\u4e8e\u5728\u5185\u5b58\u4e2d\u5b58\u50a8\u6570\u636e\u7684\u547d\u540d\u4f4d\u7f6e\u3002\u53ef\u4ee5\u5c06\u53d8\u91cf\u89c6\u4e3a\u4fdd\u5b58\u6570\u636e\u7684\u5bb9\u5668\uff0c\u8fd9\u4e9b\u6570\u636e\u53ef\u4ee5\u5728\u540e\u9762\u7a0b\u5e8f\u4e2d\u8fdb\u884c\u66f4\u6539\u3002\u4f8b\u5982\uff1a number = 10 \u3002\u4ece\u4f8b\u5b50\u4e2d\u53ef\u4ee5\u770b\u5230\uff0cPython\u4f7f\u7528\u8d4b\u503c\u8fd0\u7b97\u7b26 = \u4e3a\u53d8\u91cf\u8d4b\u503c\u3002 \u5e38\u91cf \u5e38\u91cf\u4e5f\u662f\u4e00\u79cd\u53d8\u91cf\uff0c\u53ea\u662f\u5176\u503c\u4e00\u65e6\u8d4b\u4e88\u540e\u65e0\u6cd5\u66f4\u6539\u3002\u53ef\u4ee5\u5c06\u5e38\u91cf\u89c6\u4e3a\u4fdd\u5b58\u4e86\u4ee5\u540e\u65e0\u6cd5\u66f4\u6539\u7684\u4fe1\u606f\u7684\u5bb9\u5668\u3002 \u5728Python\u4e2d\uff0c\u5e38\u91cf\u901a\u5e38\u662f\u5728\u6a21\u5757\u4e2d\u58f0\u660e\u548c\u5206\u914d\u7684\u3002\u5728\u8fd9\u91cc\uff0c\u6a21\u5757\u662f\u4e00\u4e2a\u5305\u542b\u53d8\u91cf\uff0c\u51fd\u6570\u7b49\u7684\u65b0\u6587\u4ef6\uff0c\u8be5\u6587\u4ef6\u88ab\u5bfc\u5165\u5230\u4e3b\u6587\u4ef6\u4e2d\u3002\u5728\u6a21\u5757\u5185\u90e8\uff0c\u7528\u6240\u6709\u5927\u5199\u5b57\u6bcd\u5199\u7684\u5e38\u91cf\u548c\u4e0b\u5212\u7ebf\u5c06\u5355\u8bcd\u5206\u5f00\u3002\u5b9e\u9645\u4e0a\uff0c\u6211\u4eec\u4e0d\u5728Python\u4e2d\u4f7f\u7528\u5e38\u91cf\u3002\u7528\u5927\u5199\u5b57\u6bcd\u547d\u540d\u5b83\u4eec\u662f\u4e00\u79cd\u5c06\u5176\u4e0e\u666e\u901a\u53d8\u91cf\u5206\u5f00\u7684\u4e00\u79cd\u7ea6\u5b9a\uff0c\u4f46\u662f\uff0c\u5b9e\u9645\u4e0a\u5e76\u4e0d\u80fd\u963b\u6b62\u91cd\u65b0\u5206\u914d\u3002 \u5b57\u9762\u91cf\uff08literal\uff09 \u5b57\u9762\u91cf\u662f\u4ee5\u53d8\u91cf\u6216\u5e38\u91cf\u7ed9\u51fa\u7684\u539f\u59cb\u6570\u636e\uff08\u5176\u5b9e\u5c31\u662f\u6307\u53d8\u91cf\u7684\u5e38\u6570\u503c\uff0c\u5b57\u9762\u4e0a\u6240\u770b\u5230\u7684\u503c\uff09\u3002\u5728Python\u4e2d\u5b57\u9762\u91cf\u7c7b\u578b\u5982\u4e0b\uff1a \u6570\u5b57\u5b57\u9762\u91cf\u3002\u6570\u5b57\u5b57\u9762\u91cf\u662f\u4e0d\u53ef\u53d8\u7684\uff08\u4e0d\u53ef\u66f4\u6539\uff09\u3002\u6570\u5b57\u5b57\u9762\u91cf\u53ef\u4ee5\u5c5e\u4e8e3\u79cd\u4e0d\u540c\u7684\u6570\u503c\u7c7b\u578b\uff1aInteger\uff0cFloat \u548c Complex\u3002\u4f8b\u5982\uff1a float_1 = 10.5 \u662f\u5c5e\u4e8eFloat\u5b57\u9762\u91cf\u3002 \u5b57\u7b26\u4e32\u5b57\u9762\u91cf\u662f\u7531\u5f15\u53f7\u62ec\u8d77\u6765\u7684\u4e00\u7cfb\u5217\u5b57\u7b26\u3002\u6211\u4eec\u53ef\u4ee5\u5bf9\u5b57\u7b26\u4e32\u4f7f\u7528\u5355\u5f15\u53f7\uff0c\u53cc\u5f15\u53f7 \u6216 \u4e09\u5f15\u53f7\u3002\u5e76\u4e14\uff0c\u5b57\u7b26\u5b57\u9762\u91cf\u662f\u7528\u5355\u5f15\u53f7\u6216\u53cc\u5f15\u53f7\u5f15\u8d77\u6765\u7684\u5355\u4e2a\u5b57\u7b26\u3002\u4f8b\u5982\uff1a strings = \"This is Python\" \u3002 \u5e03\u5c14\u5b57\u9762\u91cf\u3002\u5e03\u5c14\u5b57\u9762\u91cf\u53ef\u4ee5\u5177\u6709\u4e24\u4e2a\u503c\u4e2d\u7684\u4efb\u4f55\u4e00\u4e2a\uff1a True \u6216 False \u3002\u4f8b\u5982\uff1a a = True + 4 \u3002 \u7279\u6b8a\u5b57\u9762\u91cf\u3002Python\u5305\u542b\u4e00\u4e2a\u7279\u6b8a\u5b57\u9762\u91cf\uff0c\u5373 None \u3002 \u5b57\u9762\u91cf\u96c6\u3002\u6709\u56db\u79cd\u4e0d\u540c\u7684\u5b57\u9762\u91cf\u96c6\u5408\uff1a\u5217\u8868\u5b57\u9762\u91cf\uff0c\u5143\u7ec4\u5b57\u9762\u91cf\uff0c\u5b57\u5178\u5b57\u9762\u91cf \u548c \u96c6\u5408\u5b57\u9762\u91cf\u3002 1.1 \u6570\u503c\u578b\uff08number\uff09 \u00b6 \u4f8b\u5b50\uff1a a , b , c , d = 20 , 5.5 , True , 4 + 3 j print ( a , b , c , d ) # 20 5.5 True (4+3j) print ( type ( a ), type ( b ), type ( c ), type ( d )) # Python\u4e5f\u53ef\u4ee5\u8fd9\u6837\u8d4b\u503c\uff1a a = b = c = d = 1 print ( a , b , c , d ) # 1 1 1 1 \u8fdb\u5236\u8f6c\u6362\uff1a a = - 15 print ( f ' { a } \u5bf9\u5e94\u7684\u5341\u8fdb\u5236\u662f { a } , \u4e8c\u8fdb\u5236\u662f { a : b } , \u516b\u8fdb\u5236\u662f { a : o } , \u5341\u516d\u8fdb\u5236\u662f { a : x } ' ) 1.2 \u5b57\u7b26\u578b\uff08string\uff09 \u00b6 \u5355\u5f15\u53f7\uff1a\u5185\u5bb9\u4e2d\u5305\u542b\u5927\u91cf\u53cc\u5f15\u53f7 \u53cc\u5f15\u53f7\uff1a\u5185\u5bb9\u4e2d\u5305\u542b\u5927\u91cf\u5355\u5f15\u53f7 \u4e09\u5f15\u53f7\uff1a\u5185\u5bb9\u4e2d\u540c\u65f6\u5305\u542b\u5355\u53cc\u5f15\u53f7\uff0c\u4e09\u4e2a\u5355\u5f15\u53f7\u6bd4\u8f83\u597d\u3002 a = 'string is \"special\"' b = \"string's value\" c = '''string's value is \"special\"''' d = \"\"\"string's context \"\"\" \u5b57\u7b26\u4e32\u5e38\u7528\u65b9\u6cd5 \u00b6 \u5b57\u7b26\u4e32\u5207\u7247 s = 'Python is very good' print ( s [ 2 : 4 ]) # th print ( s [ 5 ]) # n print ( s [ - 1 ]) # d print ( s [ - 3 : - 1 ]) # oo # \u975e\u8fed\u4ee3\u578b\uff0c\u4e0d\u53ef\u4fee\u6539 s [ 3 ] = 'b' # Traceback (most recent call last): # File \"\", line 1, in # TypeError: 'str' object does not support item assignment \u5b57\u7b26\u4e32\u5408\u5e76 print ( s + '!!!' ) # Python is very good!!! replace( a,b \u5c06\u5b57\u7b26\u4e32\u4e2d\u7684 a \u66ff\u6362\u6210 b print ( s . replace ( 'is' , 'we' )) # Python we very good find(str) : \u8fd4\u56de str \u51fa\u73b0\u7684\u7d22\u5f15\u4f4d\u7f6e\uff0c\u5982\u679c\u627e\u4e0d\u5230\u8be5\u503c\uff0c\u5219 find() \u65b9\u6cd5\u5c06\u8fd4\u56de -1\u3002 print ( s . find ( 'a' )) # -1 print ( s . find ( 's' )) # 8 str.index(a): \u67e5\u627e\u6307\u5b9a\u503c\u7684\u9996\u6b21\u51fa\u73b0\u3002\u5982\u679c\u627e\u4e0d\u5230\u8be5\u503c\uff0cindex() \u65b9\u6cd5\u5c06\u5f15\u53d1\u5f02\u5e38\u3002 print ( s . index ( 's' )) # 8 print ( s . index ( 'a' )) # Traceback (most recent call last): # File \"\", line 1, in # ValueError: substring not found str.count(a): \u7edf\u8ba1\u5b57\u7b26\u4e32\u4e2d a \u51fa\u73b0\u7684\u6b21\u6570 print ( s . count ( 'a' )) # 0 print ( s . count ( 'o' )) # 3 split: \u5bf9\u5b57\u7b26\u4e32\u8fdb\u884c\u5206\u5272\u3002\u5982\u679c\u53c2\u6570 num \u6709\u6307\u5b9a\u503c\uff0c\u5219\u5206\u9694 num+1 \u4e2a\u5b50\u5b57\u7b26\u4e32\u3002 # \u6309\u7a7a\u683c\u5206\u5272 print ( s . split ( ' ' )) # ['Python', 'is', 'very', 'good'] # \u6309\u7a7a\u683c\u5206\u5272\u62102\u4e2a\u5b50\u5b57\u7b26\u4e32 print ( s . split ( ' ' , 1 )) # ['Python', 'is very good'] strip: \u79fb\u9664\u5b57\u7b26\u4e32\u9996\u5c3e\u6307\u5b9a\u7684\u5b57\u7b26 \u9ed8\u8ba4\u4e3a\u7a7a\u683c\u3002\u8be5\u65b9\u6cd5\u53ea\u80fd\u5220\u9664\u5f00\u5934\u6216\u662f\u7ed3\u5c3e\u7684\u5b57\u7b26\uff0c\u4e0d\u80fd\u5220\u9664\u4e2d\u95f4\u90e8\u5206\u7684\u5b57\u7b26\u3002 print ( s ) # Python is very good # \u79fb\u9664\u672b\u5c3e\u5b57\u7b26d print ( s . strip ( 'd' )) # Python is very goo endswith (str): \u5224\u65ad\u5b57\u7b26\u4e32\u662f\u5426\u4ee5 str \u7ed3\u5c3e print ( s . endswith ( 'd' )) # True print ( s . endswith ( 'a' )) # False startswith (str): \u5224\u65ad\u5b57\u7b26\u4e32\u662f\u5426\u4ee5 str \u5f00\u5934 print ( s . startswith ( 'p' )) # False print ( s . startswith ( 'P' )) # True isdigit \uff1a\u5224\u65ad\u5b57\u7b26\u4e32\u662f\u5426\u5168\u4e3a\u6570\u5b57 d = '+86-123' print ( d . isdigit ()) # False d = '86123' print ( d . isdigit ()) # True isalpha \uff1a\u5224\u65ad\u5b57\u7b26\u4e32\u662f\u5426\u5168\u4e3a\u5b57\u6bcd b = 'Ab?' print ( b . isalpha ()) # False c = 'Ab' print () c . isalpha () # True \u8f6c\u4e49\u5b57\u7b26 \u00b6 \u4f7f\u7528\u53cd\u659c\u6760\\\u8868\u793a\u8f6c\u4e49\u5b57\u7b26\u3002\u53cd\u659c\u6760\u524d\u9762\u52a0r\u4ee3\u8868\u539f\u59cb\u5b57\u7b26\u3002 a = 'str \\n ing' print ( a ) # str # ing a = r 'str\\ning' print ( a ) # str\\ning \u8f6c\u4e49\u7b26 \u63cf\u8ff0 \\\u5728\u884c\u5c3e \u7eed\u884c\u7b26 \\\\ \u53cd\u659c\u6760\u7b26\u53f7\\ \\' \u5355\u5f15\u53f7 \\b \u9000\u683c(Backspace) \\000 \u7a7a \\n \u6362\u884c \\v \u7eb5\u5411\u5236\u8868\u7b26 \\t \u6a2a\u5411\u5236\u8868\u7b26 \\r \u56de\u8f66\uff0c\u5c06 \\r \u540e\u9762\u7684\u5185\u5bb9\u79fb\u5230\u5b57\u7b26\u4e32\u5f00\u5934\uff0c\u5e76\u9010\u4e00\u66ff\u6362\u5f00\u5934\u90e8\u5206\u7684\u5b57\u7b26\uff0c\u76f4\u81f3\u5c06 \\r \u540e\u9762\u7684\u5185\u5bb9\u5b8c\u5168\u66ff\u6362\u5b8c\u6210\u3002 \\yyy \u516b\u8fdb\u5236\u6570\uff0cy \u4ee3\u8868 0~7 \u7684\u5b57\u7b26 \\xyy \u5341\u516d\u8fdb\u5236\u6570\uff0c\u4ee5 \\x \u5f00\u5934\uff0cy \u4ee3\u8868\u7684\u5b57\u7b26 \u53ef\u8fed\u4ee3\u6027 \u00b6 \u5b57\u7b26\u4e32\u662f\u53ef\u8fed\u4ee3\u7684\u3002\u7d22\u5f15\u503c\u4ece0\u5f00\u59cb\uff0c-1\u4ee3\u8868\u4ece\u672b\u5c3e\u5f00\u59cb\u3002\u7d22\u5f15\u533a\u95f4\u662f\u5de6\u95ed\u53f3\u5f00\u3002 a = 'string is \"special\"' print ( a [ 2 : 4 ]) 'ri' print ( a [ - 4 : - 1 ]) # ial f-string \u00b6 f-string\u662fPython3.6\u63a8\u51fa\u7684\u65b0\u529f\u80fd\u3002\u770b\u4e0b\u9762\u7684\u4f8b\u5b50\uff0c\u5bf9\u6bd4\u4f20\u7edf\u8868\u793a\u65b9\u6cd5\u548cf-string\u7684\u65b9\u6cd5\u3002 age = 32 name = 'Tom' fstring = f 'My name is { name } and I am { age } years old.' print ( fstring ) # My name is Tom and I am 32 years old. \u5728f-string\u4e2d\u4f7f\u7528\u8868\u8fbe\u5f0f\u3002 height = 2 base = 3 fstring = f 'The area of the triangle is { base * height / 2 } .' print ( fstring ) # The area of the triangle is 3.0. \u901a\u8fc7f-string\u5bf9\u5b57\u5178\u8fdb\u884c\u64cd\u4f5c\u3002 person1 = { 'name' : 'Tom' , 'age' : 20 , 'gender' : 'male' } person2 = { 'name' : 'Jerry' , 'age' : 20 , 'gender' : 'female' } # \u8bfb\u53d6\u5b57\u5178 fstring = f ' { person1 . get ( \"name\" ) } is { person1 . get ( \"age\" ) } and is { person1 . get ( \"ender\" ) } ' print ( fstring ) # Tom is 20 and is None # \u904d\u5386\u5b57\u5178 people = [ person1 , person2 ] for person in people : fstring = f ' { person . get ( \"name\" ) } is { person . get ( \"age\" ) } and is { person . get ( \"ender\" ) } ' print ( fstring ) # Tom is 20 and is None # Jerry is 20 and is None \u5728f-string\u4e2d\u4f7f\u7528\u6761\u4ef6\u3002 person1 = { 'name' : 'Tom' , 'age' : 20 , 'gender' : 'male' } person2 = { 'name' : 'Jerry' , 'age' : 20 , 'gender' : 'female' } people = [ person1 , person2 ] for person in people : fstring = f ' { \"She\" if person . get ( \"gender\" ) == \"female\" else \"He\" } is watching TV.' print ( fstring ) # He is watching TV. # She is watching TV. \u4f7f\u7528f-string\u683c\u5f0f\u5316\u8f93\u51fa\u3002 \u5de6\u5bf9\u9f50\uff1a< \u53f3\u5bf9\u9f50\uff1a> \u5c45\u4e2d\u5bf9\u9f50\uff1a^ print ( f ' { \"apple\" : >30 } ' ) print ( f ' { \"apple\" : ^30 } ' ) print ( f ' { \"apple\" : <30 } ' ) # apple # apple # apple \u4f7f\u7528f-string\u683c\u5f0f\u5316\u6570\u5b57\u3002 number = 0.9124325345 # \u767e\u5206\u6bd4 fstring = f 'Percentage format for number with two decimal places: { number : .2% } ' print ( fstring ) # Percentage format for number with two decimal places: 91.24% # \u4fdd\u7559\u5c0f\u6570\u70b9\u540e3\u4f4d fstring = f 'Fixed point format for number with three decimal places: { number : .3f } ' print ( fstring ) # Fixed point format for number with three decimal places: 0.912 # \u79d1\u5b66\u8ba1\u6570\u6cd5\u8868\u793a fstring = f 'Exponent format for number: { number : e } ' print ( fstring ) # Exponent format for number: 9.124325e-01 # \u5e26\u8d27\u5e01\u7b26\u53f7 number = 123456.78921 fstring = f 'Currency format for number with two decimal places: $ { number : .2f } ' print ( fstring ) # Currency format for number with two decimal places: $123456.79 # \u5e26\u8d27\u5e01\u7b26\u53f7\u548c\u5343\u5206\u4f4d number = 123456.78921 fstring = f 'Currency format for number with two decimal places and comma seperators: $ { number : ,.2f } ' print ( fstring ) # Currency format for number with two decimal places and comma seperators: $123,456.79 # \u8f93\u51fa\u6570\u503c\u5e26\u6b63\u8d1f\u7b26\u5408 numbers = [ 1 , - 3 , 5 ] for number in numbers : fstring = f 'The number is { number : + } ' print ( fstring ) # The number is +1 # The number is -3 # The number is +5 # Debug\u8c03\u8bd5 number = 2 print ( f ' { number = } ' ) # number = 2 1.3 \u5217\u8868\uff08list\uff09 \u00b6 \u5217\u8868\u662f Python \u5185\u7f6e\u7684\u4e00\u79cd\u6570\u636e\u7ed3\u6784\uff0c\u662f\u4e00\u79cd\u6709\u5e8f\u7684\u96c6\u5408\uff0c\u7528\u6765\u5b58\u50a8\u4e00\u8fde\u4e32\u5143\u7d20\u7684\u5bb9\u5668\u3002\u5217\u8868\u4e2d\u5143\u7d20\u7c7b\u578b\u53ef\u4ee5\u4e0d\u76f8\u540c\uff0c\u5b83\u652f\u6301\u6570\u5b57\u3001\u5b57\u7b26\u4e32\u7b49\u3002 \u5217\u8868\u7684\u6bcf\u4e2a\u503c\u90fd\u6709\u5bf9\u5e94\u7684\u7d22\u5f15\u503c\uff0c\u7d22\u5f15\u503c\u4ece0\u5f00\u59cb\u3002 \u5217\u8868\u5207\u7247\uff1a \u4f7f\u7528\u5207\u7247\u7b26\u53f7\u53ef\u4ee5\u5bf9\u5927\u591a\u6570\u5e8f\u5217\u7c7b\u578b\u9009\u53d6\u5176\u5b50\u96c6\u3002 \u8d77\u59cb\u4f4d\u7f6estart\u7684\u7d22\u5f15\u662f\u5305\u542b\u7684\uff0c\u800c\u7ed3\u675f\u4f4d\u7f6estop\u7684\u7d22\u5f15\u5e76\u4e0d\u5305\u542b\uff08\u5de6\u95ed\u53f3\u5f00\uff09\u3002 \u6b65\u8fdb\u503cstep\u53ef\u4ee5\u5728\u7b2c\u4e8c\u4e2a\u5192\u53f7\u540e\u9762\u4f7f\u7528\uff0c\u610f\u601d\u662f\u6bcf\u9694\u591a\u5c11\u4e2a\u6570\u53d6\u4e00\u4e2a\u503c \u3002 color = [ 'red' , 'green' , 'blue' , 'yellow' , 'white' , 'black' ] # \u4ece0\u5f00\u59cb\u7edf\u8ba1\uff0c\u8bfb\u53d6\u7b2c1\uff0c2\u4f4d print ( color [ 1 : 3 ]) # ['green', 'blue'] # \u4ece0\u5f00\u59cb\u7edf\u8ba1\uff0c\u8bfb\u53d6\u4ece\u7b2c1\u4f4d\u5230\u5012\u6570\u7b2c3\u4f4d print ( color [ 1 : - 2 ]) # ['green', 'blue', 'yellow'] # \u4ece0\u5f00\u59cb\u7edf\u8ba1\uff0c\u8bfb\u53d6\u4ece\u5012\u6570\u7b2c4\u4f4d\u5230\u5012\u6570\u7b2c3\u4f4d print ( color [ - 4 : - 2 ]) # ['blue', 'yellow'] # \u5982\u679c\u5199\u6210\u4e0b\u9762\u8fd9\u6837\uff0c\u5219\u65e0\u8f93\u51fa\u3002 print ( color [ - 2 : - 4 ]) # [] print ( color [:: 2 ]) # ['red', 'blue', 'white'] \u5bf9\u4e8e\u7c7b\u4f3c\u4e0b\u9762 invoice \u683c\u5f0f\u7684\u7eaf\u6587\u672c\u89e3\u6790\uff0c\u4f7f\u7528\u6709\u540d\u5b57\u7684\u5207\u7247\u6bd4\u7528\u4e0a\u9762\u6240\u5217\u4e3e\u7684\u786c\u7f16\u7801\u7684\u6570\u5b57\u533a\u95f4\u8981\u65b9\u4fbf\u5f97\u591a\u3002 invoice = \"\"\" 0 6 40 52 55 1909 Primoroni PiBrella $17.50 3 $52.50 1489 6mm Tactile Switch x20 $4.19 2 $9.90 1510 Panavise JR.-PV-201 $28.00 1 $28.00 1601 PiTFT Mini Kit 320x240 $34.95 1 $34.95 \"\"\" SKU = slice ( 0 , 6 ) DESCRIPTION = slice ( 6 , 40 ) UNIT_PRICE = slice ( 40 , 52 ) QUANTITY = slice ( 52 , 55 ) ITEM_TOTAL = slice ( 55 , None ) line_items = invoice . split ( ' \\n ' )[ 2 :] # \u6309\u4e0a\u9762invoice\u7684\u683c\u5f0f\uff0c\u7b2c0\u548c1\u884c\u820d\u5f03 for item in line_items : print ( item [ UNIT_PRICE ], item [ DESCRIPTION ]) # $17.50 Primoroni PiBrella # $4.19 6mm Tactile Switch x20 # $28.00 Panavise JR.-PV-201 # $34.95 PiTFT Mini Kit 320x240 Python\u5185\u7f6e\u7684\u5e8f\u5217\u7c7b\u578b\u90fd\u662f\u4e00\u7ef4\u7684\uff0c\u56e0\u6b64\u5b83\u4eec\u53ea\u652f\u6301\u5355\u4e00\u7684\u7d22\u5f15\uff0c\u6210\u5bf9\u51fa\u73b0\u7684\u7d22\u5f15\u662f\u6ca1\u6709\u7528\u7684\u3002 **\u7701\u7565\uff08ellipsis\uff09**\u7684\u6b63\u786e\u4e66\u5199\u65b9\u6cd5\u662f\u4e09\u4e2a\u82f1\u8bed\u53e5\u53f7\uff08...\uff09\uff0c\u800c\u4e0d\u662fUnicdoe\u7801\u4f4dU+2026\u8868\u793a\u7684\u534a\u4e2a\u7701\u7565\u53f7\uff08...\uff09\u3002 \u7701\u7565\u5728Python\u89e3\u6790\u5668\u773c\u91cc\u662f\u4e00\u4e2a\u7b26\u53f7\uff0c\u800c\u5b9e\u9645\u4e0a\u5b83\u662f Ellipsis \u5bf9\u8c61\u7684\u522b\u540d\uff0c\u800c Ellipsis \u5bf9\u8c61\u53c8\u662f ellipsis \u7c7b\u7684\u5355\u4e00\u5b9e\u4f8b\u3002 \u5b83\u53ef\u4ee5\u5f53\u4f5c\u5207\u7247\u89c4\u8303\u7684\u4e00\u90e8\u5206\uff0c\u4e5f\u53ef\u4ee5\u7528\u5728\u51fd\u6570\u7684\u53c2\u6570\u6e05\u5355\u4e2d\uff0c\u6bd4\u5982 f(a, ..., z) \uff0c\u6216 a[i:...] \u3002 \u5728NumPy\u4e2d\uff0c ... \u7528\u4f5c\u591a\u7ef4\u6570\u7ec4\u5207\u7247\u7684\u5feb\u6377\u65b9\u5f0f\u3002\u5982\u679c `x\u662f\u56db\u7ef4\u6570\u7ec4\uff0c\u90a3\u4e48 x[i, ...] \u5c31\u662f x[i, :, :, :]`\u7684\u7f29\u5199\u3002\u5982\u679c\u60f3\u4e86\u89e3\u66f4\u591a\uff0c\u8bf7\u53c2\u89c1\u201cTentative NumPy Tutorial\u201d\u3002 \u5217\u8868\u5e38\u7528\u65b9\u6cd5 \u65b9\u6cd5\u540d\u79f0 \u4f5c\u7528 a.index() \u8fd4\u56dea\u4e2d\u9996\u4e2a\u5339\u914d\u9879\u7684\u4f4d\u7f6e a.pop() \u5220\u9664\u6307\u5b9a\u4f4d\u7f6e\u7684\u5143\u7d20 a.insert() \u5411\u6307\u5b9a\u4f4d\u7f6e\u63d2\u5165\u5143\u7d20 a.reverse() \u53cd\u5411\u6392\u5e8f a.append() \u5411\u672b\u5c3e\u6dfb\u52a0\u5143\u7d20 a.sort() \u5bf9\u5217\u8868\u8fdb\u884c\u6392\u5e8f a.remove() \u5220\u9664\u9996\u4e2a\u5339\u914d\u9879\u7684\u5143\u7d20 a.extend() \u5c06\u4e00\u4e2a\u5217\u8868\u6269\u5c55\u81f3\u53e6\u4e00\u4e2a\u5217\u8868 a.count() \u7edf\u8ba1\u67d0\u4e2a\u5143\u7d20\u51fa\u73b0\u7684\u6b21\u6570 \u521b\u5efa\u5217\u8868list a = [ 1 , 2 , 3 , 4 , 5 ] print ( a ) # [1, 2, 3, 4, 5] b = list ( '12345' ) print ( b ) # ['1', '2', '3', '4', '5'] c = list ( 12345 ) # Traceback (most recent call last): # File \"\", line 1, in # TypeError: 'int' object is not iterable \u5217\u8868\u5207\u7247\uff08\u4ece0\u5f00\u59cb\uff0c\u5de6\u95ed\u53f3\u5f00\uff09\uff1a print ( a [ 2 : 3 ]) # [3] print ( a [: 3 ]) # [1, 2, 3] print ( a [:: - 1 ]) # \u5012\u5e8f # [5, 4, 3, 2, 1] print ( a [::]) # [1, 2, 3, 4, 5] print ( a [:: 1 ]) [ 1 , 2 , 3 , 4 , 5 ] \u5217\u8868\u662f\u53ef\u4fee\u6539\u7684\uff1a print ( a [ 1 ]) # 2 a [ 1 ] = 'one' print ( a ) @ [ 1 , 'one' , 3 , 4 , 5 ] \u5217\u8868\u8ffd\u52a0\u548c\u63d2\u5165\u3002insert\u4e0eappend\u76f8\u6bd4\uff0c\u8ba1\u7b97\u4ee3\u4ef7\u66f4\u9ad8\u3002\u56e0\u4e3a\u5b50\u5e8f\u5217\u5143\u7d20\u9700\u8981\u5728\u5185\u90e8\u79fb\u52a8\u4e3a\u65b0\u5143\u7d20\u63d0\u4f9b\u7a7a\u95f4\u3002 a . append ( 6 ) # \u6ce8\u610f\uff0c\u76f4\u63a5\u4fee\u6539\u539f\u5217\u8868\uff0c\u4e0d\u662f\u521b\u5efa\u526f\u672c\u3002 print ( a ) # [1, 'one', 3, 4, 5, 6] a . extend ([ 7 , 8 , 9 ]) print ( a ) # [1, 'one', 3, 4, 5, 6, 7, 8, 9] a . insert ( 0 , 'Italy' ) print ( a ) # ['Italy', 1, 3, 5, 6, 7, 8] \u5217\u8868\u5220\u9664\u5143\u7d20\uff0c\u9ed8\u8ba4\u5220\u9664\u6700\u540e\u4e00\u4e2a\u3002insert\u7684\u53cd\u64cd\u4f5c\u662fpop\u3002 a . pop () # 9 print ( a ) # [1, 'one', 3, 4, 5, 6, 7, 8] a . pop ( 3 ) # 4 print ( a ) # [1, 'one', 3, 5, 6, 7, 8] \u5220\u9664\u5217\u8868\u4e2d\u67d0\u4e2a\u5143\u7d20\u3002 print ( a [ 1 ]) # one del a [ 1 ] print ( a ) [ 1 , 3 , 5 , 6 , 7 , 8 ] \u5220\u9664\u5217\u8868\u4e2d\u67d0\u4e2a\u5143\u7d20\u3002remove\u65b9\u6cd5\u4f1a\u5b9a\u4f4d\u7b2c\u4e00\u4e2a\u7b26\u5408\u8981\u6c42\u7684\u503c\u5e76\u79fb\u9664 a . remove ( 'Italy' ) print ( a ) # [1, 3, 5, 6, 7, 8] \u7edf\u8ba1\u67d0\u4e2a\u5143\u7d20\u51fa\u73b0\u7684\u6b21\u6570\u3002 print ( a . count ( 1 )) # 1 \u8fd4\u56de\u5217\u8868\u4e2d\u5339\u914d\u9879\u7684\u7d22\u5f15\u4f4d\u7f6e\u3002\u5339\u914d\u4e0d\u5230\u629b\u51fa\u5f02\u5e38\u3002 print ( a . index ( 2 )) # Traceback (most recent call last): # File \"\", line 1, in # ValueError: 2 is not in list print ( a . index ( 3 )) # 1 \u5224\u65ad\u5143\u7d20\u662f\u5426\u5b58\u5728\u4e8e\u5217\u8868\u3002 print ( 3 in a ) # True print ( '3' in a ) # False \u53cd\u5411\u8f93\u51fa\u5217\u8868\u3002 a . reverse () print ( a ) # [8, 7, 6, 5, 3, 1] \u53d6\u5217\u8868\u4e2d\u6700\u5927\u503c\u3001\u6700\u5c0f\u503c\u3002 print ( min ( a )) # 1 print ( max ( a )) # 78 \u8ba1\u7b97\u5217\u8868\u957f\u5ea6\u3002 print ( len ( a )) # 6 \u5217\u8868\u6269\u5c55\uff1a a = [ 1 , 2 , 3 ] b = [ 4 , 5 , 6 ] print ( a + b ) # [1, 2, 3, 4, 5, 6] a . extend ( b ) # a\u5217\u8868\u88ab\u4fee\u6539 print ( a ) # [1, 2, 3, 4, 5, 6] print ( b ) # [4, 5, 6] \u4f7f\u7528extend\u6dfb\u52a0\u5143\u7d20\u6bd4\u4f7f\u7528\u52a0\u53f7\uff08+\uff09\u8fde\u63a5\u6548\u7387\u66f4\u9ad8\u3002\u56e0\u4e3a\u4f7f\u7528\u52a0\u53f7\uff08+\uff09\u8fde\u63a5\u8fc7\u7a0b\u4e2d\u521b\u5efa\u4e86\u65b0\u5217\u8868\uff0c\u5e76\u4e14\u8fd8\u8981\u590d\u5236\u5bf9\u8c61\u3002 a_list = [ 4 , None , 'foo' ] b_list = [ 7 , 8 , ( 2 , 3 )] print ( a_list + b_list ) # [4, None, 'foo', 7, 8, (2, 3)] \u4f7f\u7528+\u53f7\u8fde\u63a5 a_list . extend ( b_list ) print ( a_list ) # [4, None, 'foo', 7, 8, (2, 3)] Python\u7684\u4e00\u4e2a\u60ef\u4f8b\uff1a\u5982\u679c\u4e00\u4e2a\u51fd\u6570\u6216\u8005\u65b9\u6cd5\u5bf9\u5bf9\u8c61\u8fdb\u884c\u7684\u662f\u5c31\u5730\u6539\u52a8\uff0c\u90a3\u5b83\u5c31\u5e94\u8be5\u8fd4\u56deNone\uff0c\u597d\u8ba9\u8c03\u7528\u8005\u77e5\u9053\u4f20\u5165\u7684\u53c2\u6570\u53d1\u751f\u4e86\u53d8\u52a8\uff0c\u800c\u4e14\u5e76\u672a\u4ea7\u751f\u65b0\u7684\u5bf9\u8c61\u3002 \u4e0b\u9762\u662f\u6392\u5e8f\u7684\u4f8b\u5b50 list.sort() \u548c sorted(list) \u7684\u533a\u522b\u3002 list1 = [ '1' , 'one' , '3' , 'Four' , '5' , 'two' , 'apple' , '8' , '9' ] print ( list1 ) # ['1', 'one', '3', 'Four', '5', 'two', 'apple', '8', '9'] # \u4e0b\u9762\u7684\u64cd\u4f5c\u4e0d\u6539\u53d8\u539f\u5217\u8868 print ( sorted ( list1 )) # ['1', '3', '5', '8', '9', 'Four', 'apple', 'one', 'two'] print ( sorted ( list1 , reverse = True )) # ['two', 'one', 'apple', 'Four', '9', '8', '5', '3', '1'] print ( sorted ( list1 , key = len )) # ['1', '3', '5', '8', '9', 'one', 'two', 'Four', 'apple'] print ( list1 ) # ['1', 'one', '3', 'Four', '5', 'two', 'apple', '8', '9'] # \u4e0b\u9762\u7684\u64cd\u4f5c\u76f4\u63a5\u4fee\u6539\u539f\u5217\u8868\uff0c\u8fd4\u56de\u503c\u662fNone print ( list1 . sort ()) # None print ( list1 ) # ['1', '3', '5', '8', '9', 'Four', 'apple', 'one', 'two'] \u5217\u8868\u590d\u5236\uff0c + \u548c * \u7684\u64cd\u4f5c\u90fd\u662f\u4e0d\u4fee\u6539\u539f\u6709\u7684\u64cd\u4f5c\u5bf9\u8c61\uff0c\u800c\u662f\u6784\u5efa\u4e00\u4e2a\u5168\u65b0\u7684\u5217\u8868\u3002 c = list ( 'Python' ) print ( a + c ) # [1, 2, 3, 4, 5, 6, 'P', 'y', 't', 'h', 'o', 'n'] print ( a * 3 ) # [1, 2, 3, 4, 5, 6, 1, 2, 3, 4, 5, 6, 1, 2, 3, 4, 5, 6] \u5982\u679c\u5728 a * n \u8fd9\u4e2a\u8bed\u53e5\u4e2d\uff0c\u5e8f\u5217 a \u91cc\u7684\u5143\u7d20\u662f\u5bf9\u5176\u4ed6\u53ef\u53d8\u5bf9\u8c61\u7684\u5f15\u7528\u7684\u8bdd\uff0c\u5c31\u9700\u8981\u683c\u5916\u6ce8\u610f\u4e86\uff0c\u56e0\u4e3a\u8fd9\u4e2a\u5f0f\u5b50\u7684\u7ed3\u679c\u53ef\u80fd\u4f1a\u51fa\u4e4e\u610f\u6599\u3002 \u6bd4\u5982\uff0c\u6211\u4eec\u60f3\u7528 my_list=[[]] * 3 \u6765\u521d\u59cb\u5316\u4e00\u4e2a\u7531\u5217\u8868\u7ec4\u6210\u7684\u5217\u8868\uff0c\u4f46\u662f\u6211\u4eec\u5b9e\u9645\u5f97\u5230\u7684\u5217\u8868\u91cc\u5305\u542b\u76843\u4e2a\u5143\u7d20\u5176\u5b9e\u662f3\u4e2a\u5f15\u7528\uff0c\u800c\u4e14\u8fd93\u4e2a\u5f15\u7528\u6307\u5411\u7684\u90fd\u662f*\u540c\u4e00\u4e2a*\u5217\u8868\u3002\u770b\u4e0b\u9762\u4f8b\u5b50\u3002 # \u505a\u6cd51 board = [[ '_' ] * 3 for i in range ( 3 )] print ( board ) # [['_', '_', '_'], ['_', '_', '_'], ['_', '_', '_']] board [ 1 ][ 2 ] = 'X' print ( board ) # [['_', '_', '_'], ['_', '_', 'X'], ['_', '_', '_']] # \u505a\u6cd52 board = [[ '_' ] * 3 ] * 3 print ( board ) # [['_', '_', '_'], ['_', '_', '_'], ['_', '_', '_']] board [ 1 ][ 2 ] = 'X' print ( board ) # [['_', '_', 'X'], ['_', '_', 'X'], ['_', '_', 'X']] \u4e0b\u9762\u4e5f\u662f\u540c\u6837\u7684\u95ee\u9898\u3002 # \u65b9\u6cd51 row = [ '_' ] * 3 board = [] for i in range ( 3 ): board . append ( row ) print ( board ) # [['_', '_', '_'], ['_', '_', '_'], ['_', '_', '_']] board [ 2 ][ 0 ] = 'X' print ( board ) # [['X', '_', '_'], ['X', '_', '_'], ['X', '_', '_']] # \u65b9\u6cd52 row = [] board = [] for i in range ( 3 ): row = [ '_' ] * 3 board . append ( row ) print ( board ) # [['_', '_', '_'], ['_', '_', '_'], ['_', '_', '_']] board [ 2 ][ 0 ] = 'X' print ( board ) # [['_', '_', '_'], ['_', '_', '_'], ['X', '_', '_']] \u53cc\u7aef\u961f\u5217collections.deque \uff0c\u53ef\u4ee5\u6ee1\u8db3\u5217\u8868\u5934\u5c3e\u90e8\u90fd\u589e\u52a0\u7684\u8981\u6c42\u3002 deque() \u4e2d maxlen \u662f\u4e00\u4e2a\u53ef\u9009\u53c2\u6570\uff0c\u4ee3\u8868\u8fd9\u4e2a\u961f\u5217\u53ef\u4ee5\u5bb9\u7eb3\u7684\u5143\u7d20\u7684\u6570\u91cf\uff0c\u800c\u4e14\u4e00\u65e6\u8bbe\u5b9a\uff0c\u8fd9\u4e2a\u5c5e\u6027\u5c31\u4e0d\u80fd\u4fee\u6539\u4e86\u3002 \u5f53\u8bd5\u56fe\u5bf9\u4e00\u4e2a\u5df2\u6ee1 len(d)==d.maxlen \u7684\u961f\u5217\u505a\u5934\u90e8\u6dfb\u52a0\u64cd\u4f5c\u7684\u65f6\u5019\uff0c\u5b83\u5c3e\u90e8\u7684\u5143\u7d20\u4f1a\u88ab\u5220\u9664\u6389\u3002 extendleft(iter) \u65b9\u6cd5\u4f1a\u628a\u8fed\u4ee3\u5668\u91cc\u7684\u5143\u7d20\u9010\u4e2a\u6dfb\u52a0\u5230\u53cc\u5411\u961f\u5217\u7684\u5de6\u8fb9\uff0c\u56e0\u6b64\u8fed\u4ee3\u5668\u91cc\u7684\u5143\u7d20\u4f1a\u9006\u5e8f\u51fa\u73b0\u5728\u961f\u5217\u91cc\u3002 \u961f\u5217\u7684\u65cb\u8f6c\u64cd\u4f5c rotate \u63a5\u53d7\u4e00\u4e2a\u53c2\u6570n\uff0c\u5f53n > 0\u65f6\uff0c\u961f\u5217\u7684\u6700\u53f3\u8fb9\u7684n\u4e2a\u5143\u7d20\u4f1a\u88ab\u79fb\u52a8\u5230\u961f\u5217\u7684\u5de6\u8fb9\u3002\u5f53n < 0\u65f6\uff0c\u6700\u5de6\u8fb9\u7684n\u4e2a\u5143\u7d20\u4f1a\u88ab\u79fb\u52a8\u5230\u53f3\u8fb9\u3002 from collections import deque d = deque ([ 1 , 2 , 3 ]) print ( d ) # deque([1, 2, 3]) # \u6ce8\u610f\u63d2\u5165\u987a\u5e8f d . extendleft ([ 'a' , 'b' , 'c' ]) print ( d ) # deque(['c', 'b', 'a', 1, 2, 3]) print ( len ( d )) # 6 print ( d [ - 2 ]) # 2 # \u7edf\u8ba1\u5b57\u7b26a\u51fa\u73b0\u7684\u6b21\u6570 print ( d . count ( 'a' )) # 1 # \u8fd4\u56de\u5b57\u7b26a\u7684\u7d22\u5f15\u503c print ( d . index ( 'a' )) # 2 # \u7b2c0\u4f4d\u63d2\u5165\u6570\u5b571\uff0c\u5176\u4f59\u987a\u79fb d . insert ( 0 , 1 ) print ( d ) # deque([1, 'c', 'b', 'a', 1, 2, 3]) # \u628a\u53f3\u8fb92\u4e2a\u5143\u7d20\u653e\u5230\u5de6\u8fb9\uff0c\u6ce8\u610f\u987a\u5e8f\uff0c\u548cextendleft\u4e0d\u4e00\u6837 d . rotate ( 2 ) print ( d ) # deque([2, 3, 1, 'c', 'b', 'a', 1]) d . rotate ( - 2 ) print ( d ) # deque([1, 'c', 'b', 'a', 1, 2, 3]) \u4e0b\u8868\u603b\u7ed3\u4e86\u5217\u8868\u548c\u53cc\u5411\u961f\u5217\u7684\u65b9\u6cd5\uff08\u4e0d\u5305\u62ec\u7531\u5bf9\u8c61\u5b9e\u73b0\u7684\u65b9\u6cd5\uff09\u3002 \u5217\u8868\u6392\u5e8f\u3002\u6392\u5e8f\u5bf9\u5217\u8868\u5143\u7d20\u7684\u6570\u636e\u7c7b\u578b\u662f\u6709\u8981\u6c42\u7684\u3002 a_list = [ 4 , None , 'foo' , 7 , 8 , ( 2 , 3 )] a_list . sort () # Traceback (most recent call last): # File \"\", line 1, in # TypeError: '<' not supported between instances of 'NoneType' and 'int' b_list = [ 7 , 8 , ( 2 , 3 )] b_list . sort () # Traceback (most recent call last): # File \"\", line 1, in # TypeError: '<' not supported between instances of 'tuple' and 'int' a_list = [ 7 , 2 , 5 , 1 , 3 ] a_list . sort () # \u6309\u6570\u503c\u5927\u5c0f\u6392\u5e8f print ( a_list ) # [1, 2, 3, 5, 7] b_list = [ 'saw' , 'small' , 'He' , 'foxes' , 'six' ] b_list . sort ( key = len ) # \u901a\u8fc7\u5b57\u7b26\u4e32\u7684\u957f\u5ea6\u8fdb\u884c\u6392\u5e8f print ( b_list ) # ['He', 'saw', 'six', 'small', 'foxes'] \u5217\u8868\u4e8c\u5206\u641c\u7d22\u548c\u5df2\u6392\u5e8f\u5217\u8868\u7684\u7ef4\u62a4 bisect \u8fd4\u56de\u8981\u63d2\u5165\u5143\u7d20\u5728\u5217\u8868\u4e2d\u7684\u4e0b\u6807\u3002\u5047\u5b9a\u5217\u8868\u662f\u6709\u5e8f\u7684\u3002 bisect_left \u4e0e bisect \u7c7b\u4f3c\uff0c\u53ea\u4e0d\u8fc7\u5176\u9ed8\u8ba4\u5c06\u5143\u7d20\u63d2\u5230\u5de6\u8fb9\uff0c\u6240\u4ee5\u8fd4\u56de\u7684\u662f\u63d2\u5165\u5230\u5de6\u8fb9\u7684\u4e0b\u6807 bisect_right\u4e0e bisect_left \u76f8\u53cd\u3002 \u4ee5\u4e0a\u65b9\u6cd5\u82e5\u5217\u8868\u65e0\u5e8f\uff0c\u90a3\u4e48\u4f1a\u8fd4\u56de\u63d2\u5165\u5230\u5217\u8868\u6700\u540e\u4e00\u4e2a\u5408\u9002\u7684\u4f4d\u7f6e\u3002 insort \u4f1a\u5728\u5217\u8868\u4e2d\u63d2\u5165\u5143\u7d20\u5230\u6b63\u786e\u4f4d\u7f6e\uff0c\u5047\u5b9a\u5217\u8868\u6709\u5e8f\u3002\u5982\u679c\u5217\u8868\u65e0\u5e8f\uff0c\u90a3\u4e48\u4f1a\u8fd4\u56de\u7a7a\u3002\u9ed8\u8ba4\u63d2\u5165\u5230\u53f3\u8fb9\u3002 insort_left \u548cinsort_right \u7c7b\u4f3c\u3002 import bisect c = [ 1 , 2 , 3 , 4 , 7 ] print ( bisect . bisect ( c , 2 )) # 2 bisect\u4f1a\u627e\u5230\u7b2c\u4e00\u4e2a2,\u5e76\u628a\u65b0\u76842\u63d2\u5165\u5b83\u540e\u9762 bisect . insort ( c , 2 ) # [1, 2, 2, 3, 4, 7] print ( bisect . bisect ( c , 5 )) # 5 bisect\u4f1a\u627e\u5230\u7b2c\u4e00\u4e2a4,\u5e76\u628a\u65b0\u76845\u63d2\u5165\u5b83\u540e\u9762 bisect . insort ( c , 5 ) print ( bisect . bisect ( c , 6 )) # 6 bisect\u4f1a\u627e\u5230\u7b2c\u4e00\u4e2a5,\u5e76\u628a\u65b0\u76846\u63d2\u5165\u5b83\u540e\u9762 bisect . insort ( c , 6 ) print ( c ) # [1, 2, 2, 3, 4, 5, 6, 7] bisect\u53ef\u4ee5\u7528\u6765\u5efa\u7acb\u4e00\u4e2a\u7528\u6570\u5b57\u4f5c\u4e3a\u7d22\u5f15\u7684\u67e5\u8be2\u8868\u683c\uff0c\u5982\u4e0b\u4f8b\uff0c\u628a\u5206\u6570\u548c\u6210\u7ee9\u5bf9\u5e94\u8d77\u6765\uff0c\u6839\u636e\u4e00\u4e2a\u5206\u6570\uff0c\u627e\u5230\u5b83\u6240\u5bf9\u5e94\u7684\u6210\u7ee9\u3002 import bisect def grade ( score , breakpoints = [ 60 , 70 , 80 , 90 ], grades = 'FDCBA' ): i = bisect . bisect ( breakpoints , score ) return grades [ i ] [ grade ( score ) for score in [ 15 , 26 , 31 , 62 , 79 , 85 ]] # ['F', 'F', 'F', 'D', 'C', 'B'] \u7528bisect.insort\u63d2\u5165\u65b0\u5143\u7d20\uff0c\u5e76\u80fd\u4fdd\u6301seq\u7684\u5347\u5e8f\u987a\u5e8f\u3002 import bisect import random size = 7 random . seed ( 1729 ) my_list = [] for i in range ( size ): new_item = random . randrange ( size * 2 ) bisect . insort ( my_list , new_item ) print ( f ' { new_item : 2d } :--> { my_list } ' ) # 10 :--> [10] # 0 :--> [0, 10] # 6 :--> [0, 6, 10] # 8 :--> [0, 6, 8, 10] # 7 :--> [0, 6, 7, 8, 10] # 2 :--> [0, 2, 6, 7, 8, 10] # 10 :--> [0, 2, 6, 7, 8, 10, 10] 1.4 \u5b57\u5178\uff08dictionary\uff09 \u00b6 \u5b57\u5178(dict)\u662f\u4f7f\u7528\u952e-\u503c\uff08key-value\uff09\u5b58\u50a8\uff0c\u952e\u662f\u4e0d\u53ef\u53d8\u5bf9\u8c61\uff0c\u4e14\u4e0d\u5141\u8bb8\u91cd\u590d\u3002 dict\uff08\u5b57\u5178\uff09\u66f4\u4e3a\u5e38\u7528\u7684\u540d\u5b57\u662f\u54c8\u5e0c\u8868\u6216\u8005\u662f\u5173\u8054\u6570\u7ec4\u3002 \u5b57\u5178\u662f\u62e5\u6709\u7075\u6d3b\u5c3a\u5bf8\u7684\u952e\u503c\u5bf9\u96c6\u5408\uff0c\u4e0d\u662f\u901a\u8fc7\u4f4d\u7f6e\u8fdb\u884c\u7d22\u5f15\uff0c\u5176\u4e2d\u952e\u548c\u503c\u90fd\u662fPython\u5bf9\u8c61\u3002\u7528\u5927\u62ec\u53f7{}\u662f\u521b\u5efa\u5b57\u5178\u7684\u4e00\u79cd\u65b9\u5f0f\uff0c\u5728\u5b57\u5178\u4e2d\u7528\u9017\u53f7\u5c06\u952e\u503c\u5bf9\u5206\u9694\u3002 \u521b\u5efa\u5b57\u5178\u7684\u51e0\u79cd\u65b9\u6cd5\uff1a a = dict ( one = 1 , two = 2 , three = 3 ) b = { 'one' : 1 , 'two' : 2 , 'three' : 3 } c = dict ( zip ([ 'one' , 'two' , 'three' ], [ 1 , 2 , 3 ])) d = dict ([( 'two' , 2 ), ( 'three' , 3 ), ( 'one' , 1 )]) e = dict ({ 'three' : 3 , 'one' : 1 , 'two' : 2 }) print ( a == b == c == d == e ) # True \u5b57\u5178\u5e38\u7528\u65b9\u6cd5 \u65b9\u6cd5\u540d\u79f0 \u4f5c\u7528 a.items() \u8fd4\u56dea\u4e2d\u6240\u6709\u952e\u503c\u5bf9 a.values() \u8fd4\u56dea\u4e2d\u6240\u6709\u503c a.keys() \u8fd4\u56dea\u4e2d\u6240\u6709\u952e a.get() \u901a\u8fc7\u952e\u6765\u67e5\u503c\uff0c\u8fd4\u56de\u5bf9\u5e94\u7684\u503c a.clear() \u6e05\u7a7a\u5b57\u5178a\u7684\u503c a.setdefault \u901a\u8fc7\u952e\u503c\u6765\u67e5\u627e\u503c\uff0c\u627e\u4e0d\u5230\u5219\u63d2\u5165 a.update() \u952e\u548c\u503c\u66f4\u65b0\u5230\u65b0\u7684\u5b57\u5178 a.pop() \u5220\u9664\u6307\u5b9a\u4f4d\u7f6e\u7684\u5143\u7d20 \u751f\u6210\u4e00\u4e2a\u5b57\u5178\u3002 dict_a = { 'name' : 'Ming' , 'id' : 1001 , 'age' : 35 } print ( type ( dict_a )) # dict_b = dict ( city = 'Shanghai' , strict = 'Xuhui' , zip = '200000' ) print ( type ( dict_b )) # \u901a\u8fc7\u952e\u67e5\u8be2\u503c\uff0c\u67e5\u8be2\u4e0d\u5230\u629b\u51fa\u5f02\u5e38\u3002 print ( dict_a [ 'name' ]) # Ming print ( dict_a [ 'Name' ]) # Traceback (most recent call last): # File \"\", line 1, in # KeyError: 'Name' \u63d2\u5165\u65b0\u7684\u952e\u503c\u5bf9\u3002 dict_a [ 'city' ] = 'Chengdu' print ( dict_a ) # {'name': 'Ming', 'id': 1001, 'city': 'Chengdu'} \u5220\u9664\u67d0\u4e2a\u952e\u503c\u5bf9\u3002pop\u65b9\u6cd5\u4f1a\u5728\u5220\u9664\u7684\u540c\u65f6\u8fd4\u56de\u88ab\u5220\u7684\u503c\uff0c\u5e76\u5220\u9664\u952e\u3002 dict_a . pop ( 'city' ) # Chengdu print ( dict_a ) # {'name': 'Ming', 'id': 1001} \u53e6\u4e00\u79cd\u65b9\u5f0f\u5220\u9664\u67d0\u4e2a\u952e\u503c\u5bf9\u3002 del dict_a [ 'age' ] # Traceback (most recent call last): # File \"\", line 1, in # KeyError: 'age' del dict_a [ 'id' ] print ( dict_a ) # {'name': 'Ming'} \u5224\u65ad\u952e\u662f\u5426\u5b58\u5728\u3002 dict_a [ 23 ] = 'Hello World' print ( dict_a ) # {'name': 'Ming', 23: 'Hello World'} print ( 23 in dict_a ) # True print ( 35 in dict_a ) # False \u901a\u8fc7\u952e\u67e5\u8be2\u503c\u7684\u53e6\u4e00\u79cd\u65b9\u5f0f\uff0c\u67e5\u8be2\u4e0d\u5230\u4e0d\u629b\u5f02\u5e38\u3002 dict_a . get ( 'hai' ) dict_a . get ( 'hai' , 1 ) # 1 dict_a . get ( 'name' , 1 ) # Ming dict_a [ 'hai' ] # Traceback (most recent call last): # File \"\", line 1, in # KeyError: 'hai' \u901a\u8fc7\u952e\u67e5\u8be2\u503c\u7684\u53e6\u4e00\u79cd\u65b9\u5f0f\uff0c\u67e5\u8be2\u4e0d\u5230\u5219\u6dfb\u52a0\u3002 dict_a . setdefault ( 'name' ) # Ming dict_a . setdefault ( 'hai' , 1 ) # 1 print ( dict_a ) # {'name': 'Ming', 23: 'Hello World', 'hai': 1} dict_a . setdefault ( 'go' ) print ( dict_a ) # {'name': 'Ming', 23: 'Hello World', 'hai': 1, 'go': None} \u8bfb\u53d6\u5b57\u5178\u6240\u6709\u952e\u503c\u5bf9\uff0c\u8fd4\u56de\u7684\u662f\u5217\u8868\u5f62\u5f0f\u3002 print ( dict_a . items ()) # dict_items([('name', 'Ming'), (23, 'Hello World'), ('hai', 1), ('go', None)]) \u8bfb\u53d6\u5b57\u5178\u7684\u952e\u3002 print ( dict_a . keys ()) # dict_keys(['name', 23, 'hai', 'go']) \u8bfb\u53d6\u5b57\u5178\u7684\u503c\u3002 print ( dict_a . values ()) # dict_values(['Ming', 'Hello World', 1, None]) \u5c06\u5b57\u5178\u503c\u8f6c\u5316\u6210\u5217\u8868\u3002 print ( list ( dict_a . values ())) # ['Ming', 'Hello World', 1, None] for key in dict_a . keys (): print ( dict_a [ key ]) # Ming # Hello World # 1 # None \u6e05\u7a7a\u5b57\u5178\u3002 dict_a . clear () print ( dict_a ) # {} print ( len ( dict_a )) # 0 \u5bf9\u4e8e\u4efb\u4f55\u539f\u5b57\u5178\u4e2d\u5df2\u7ecf\u5b58\u5728\u7684\u952e\uff0c\u5982\u679c\u4f20\u7ed9update\u65b9\u6cd5\u7684\u6570\u636e\u4e5f\u542b\u6709\u76f8\u540c\u7684\u952e\uff0c\u5219\u5b83\u7684\u503c\u5c06\u4f1a\u88ab\u8986\u76d6\u3002 dict_a = { 'name' : 'Ming' , 'id' : 1001 , 'age' : 35 } dict_b = dict ( city = 'Shanghai' , id = 2001 , zip = '200000' ) dict_a . update ( dict_b ) print ( dict_a ) # {'name': 'Ming', 'id': 2001, 'age': 35, 'city': 'Shanghai', 'zip': '200000'} \u4ece\u5217\u8868\u751f\u6210\u5b57\u5178\u3002 \u5b57\u5178\u672c\u8d28\u4e0a\u662f2-\u5143\u7ec4\uff08\u542b\u67092\u4e2a\u5143\u7d20\u7684\u5143\u7ec4\uff09\u7684\u96c6\u5408\uff0c\u5b57\u5178\u662f\u53ef\u4ee5\u63a5\u53d7\u4e00\u4e2a2-\u5143\u7ec4\u7684\u5217\u8868\u4f5c\u4e3a\u53c2\u6570\u7684\u3002 # \u65b9\u6cd51 mapping = {} key_list = list ( range ( 5 )) value_list = list ( reversed ( range ( 5 ))) for key , value in zip ( key_list , value_list ): mapping [ key ] = value print ( mapping ) # {0: 4, 1: 3, 2: 2, 3: 1, 4: 0} # \u65b9\u6cd52\u3002 mapping = {} key_list = list ( range ( 5 )) value_list = list ( reversed ( range ( 5 ))) mapping = dict ( zip ( key_list , value_list )) print ( mapping ) # {0: 4, 1: 3, 2: 2, 3: 1, 4: 0} \u6709\u6548\u7684\u5b57\u5178\u952e\u7c7b\u578b\u3002 \u5c3d\u7ba1\u5b57\u5178\u7684\u503c\u53ef\u4ee5\u662f\u4efb\u4f55Python\u5bf9\u8c61\uff0c\u4f46\u952e\u5fc5\u987b\u662f\u4e0d\u53ef\u53d8\u7684\u5bf9\u8c61\uff0c\u6bd4\u5982\u6807\u91cf\u7c7b\u578b\uff08\u6574\u6570\u3001\u6d6e\u70b9\u6570\u3001\u5b57\u7b26\u4e32\uff09\u6216\u5143\u7ec4\uff08\u4e14\u5143\u7ec4\u5185\u5bf9\u8c61\u4e5f\u5fc5\u987b\u662f\u4e0d\u53ef\u53d8\u5bf9\u8c61\uff09\u3002 \u901a\u8fc7hash\u51fd\u6570\u53ef\u4ee5\u68c0\u67e5\u4e00\u4e2a\u5bf9\u8c61\u662f\u5426\u53ef\u4ee5\u54c8\u5e0c\u5316\uff08\u5373\u662f\u5426\u53ef\u4ee5\u7528\u4f5c\u5b57\u5178\u7684\u952e\uff09\uff0c\u672f\u8bed\u53eb\u4f5c\u54c8\u5e0c\u5316\u3002 print ( hash ( 'string' )) # -4368784820203065343 print ( hash (( 1 , 2 , ( 2 , 3 )))) # -9209053662355515447 print ( hash (( 1 , 2 , [ 2 , 3 ]))) # TypeError: unhashable type: 'list' print ( hash (( 1 , 2 , tuple ([ 2 , 3 ])))) # -9209053662355515447 \u4e3a\u4e86\u5c06\u5217\u8868\u4f5c\u4e3a\u952e\uff0c\u4e00\u79cd\u65b9\u5f0f\u5c31\u662f\u5c06\u5176\u8f6c\u6362\u4e3a\u5143\u7ec4 \u5b57\u5178\u9ed8\u8ba4\u503c\u3002 \u4e0b\u9762\u7684\u4f8b\u5b50\uff0c\u5b9e\u73b0\u4e86\u5c06\u4e00\u4e2a\u5355\u8bcd\u7ec4\u6210\u7684\u5217\u8868\uff0c\u8f6c\u6362\u6210\u5355\u8bcd\u9996\u5b57\u6bcd\u548c\u5355\u8bcd\u4e3a\u952e\u503c\u5bf9\u7684\u5b57\u5178\u3002\u5148\u7528\u4f20\u7edf\u65b9\u6cd5\u5b9e\u73b0\uff0c\u518d\u7528\u5b57\u5178\u7684setdefault\u65b9\u6cd5\u8fdb\u884c\u6539\u5199\u3002 \u5148\u770b\u4f20\u7edf\u65b9\u6cd5\u3002 words = [ 'apple' , 'bat' , 'bar' , 'atom' , 'book' ] by_letter = {} for word in words : letter = word [ 0 ] # word[0]\u628a\u5217\u8868words\u7684\u6bcf\u4e2a\u5143\u7d20\u5217\u8868\u5316\uff0c\u5e76\u53d6\u9996\u5b57\u6bcd\u3002\u8f93\u51fa\u7684\u662fa, b, b, a, b\u8fd95\u4e2a\u5217\u8868\u5143\u7d20\u7684\u9996\u5b57\u6bcd if letter not in by_letter : # \u751f\u6210\u7b2c\u4e00\u4e2a\u952e\u503c\u5bf9 print ( letter ) by_letter [ letter ] = [ word ] # \u5bf9\u6bd4[word]\u548cword[]\u7684\u7528\u6cd5 print ( by_letter ) # a # {'a': ['apple']} # b # {'a': ['apple'], 'b': ['bat']} else : # append\u5176\u4ed6\u952e\u503c\u5bf9 print ( letter ) by_letter [ letter ] . append ( word ) print ( by_letter ) # b # {'a': ['apple'], 'b': ['bat', 'bar']} # a # {'a': ['apple', 'atom'], 'b': ['bat', 'bar']} # b # {'a': ['apple', 'atom'], 'b': ['bat', 'bar', 'book']} print ( by_letter ) # {'a': ['apple', 'atom'], 'b': ['bat', 'bar', 'book']} \u7528\u5b57\u5178\u7684setdefault\u65b9\u6cd5\uff0c\u4e0a\u8ff0\u7684for\u5faa\u73af\u8bed\u53e5\u53ef\u4ee5\u88ab\u5199\u4e3a\u5982\u4e0b\u3002 words = [ 'apple' , 'bat' , 'bar' , 'atom' , 'book' ] by_letter = {} for word in words : letter = word [ 0 ] # word[0]\u7684\u8f93\u51fa\u4f9d\u7136\u662f5\u4e2a\u5217\u8868\u5143\u7d20\u7684\u9996\u5b57\u6bcda, b, b, a, b by_letter . setdefault ( letter , []) . append ( word ) # \u5982\u679cletter\u4e0d\u5728[]\u5219\u901a\u8fc7append\u6dfb\u52a0word print ( by_letter ) # {'a': ['apple', 'atom'], 'b': ['bat', 'bar', 'book']} \u5982\u679c\u6539\u5199\u4e3a by_letter.setdefault(letter, ['a']).append(word) \uff0c\u5219\u8f93\u51fa by_letter \u662f {'a': ['a', 'apple', 'atom'], 'b': ['a', 'bat', 'bar', 'book']} \u3002 words = [ 'apple' , 'bat' , 'bar' , 'atom' , 'book' ] by_letter = {} for word in words : letter = word [ 0 ] # word[0]\u7684\u8f93\u51fa\u4f9d\u7136\u662f5\u4e2a\u5217\u8868\u5143\u7d20\u7684\u9996\u5b57\u6bcda, b, b, a, b by_letter . setdefault ( letter , [ 'a' ]) . append ( word ) print ( by_letter ) # {'a': ['a', 'apple', 'atom'], 'b': ['a', 'bat', 'bar', 'book']} \u4f53\u4f1asetdefault()\u7684\u6ce8\u91ca\u201cInsert key with a value of default if key is not in the dictionary. Return the value for key if key is in the dictionary, else default.\u201d \u901a\u8fc7defaultdict\u7c7b\u4f7f\u5f97\u4e0a\u8ff0\u76ee\u7684\u5b9e\u73b0\u66f4\u4e3a\u7b80\u5355\u3002 from collections import defaultdict by_letter = defaultdict ( list ) # list\u662f\u5185\u7f6e\u7684\u53ef\u53d8\u5e8f\u5217(Built-in mutable sequence) print ( dict ( by_letter )) # {} for word in words : by_letter [ word [ 0 ]] . append ( word ) print ( by_letter ) # defaultdict(, {'a': ['apple', 'atom'], 'b': ['bat', 'bar', 'book']}) print ( dict ( by_letter )) # {'a': ['apple', 'atom'], 'b': ['bat', 'bar', 'book']} \u4e0b\u8868\u5c55\u793a\u4e86 dict \u3001 defaultdict \u548c OrderedDict \u7684\u5e38\u89c1\u65b9\u6cd5\uff0c\u540e\u9762\u4e24\u4e2a\u6570\u636e\u7c7b\u578b\u662f dict \u7684\u53d8\u79cd\uff0c\u4f4d\u4e8e collections \u6a21\u5757\u5185\u3002 default_factory \u5e76\u4e0d\u662f\u4e00\u4e2a\u65b9\u6cd5\uff0c\u800c\u662f\u4e00\u4e2a\u53ef\u8c03\u7528\u5bf9\u8c61\uff08callable\uff09\uff0c\u5b83\u7684\u503c\u5728 defaultdict \u521d\u59cb\u5316\u7684\u65f6\u5019\u7531\u7528\u6237\u8bbe\u5b9a\u3002 OrderedDict.popitem() \u4f1a\u79fb\u9664\u5b57\u5178\u91cc\u6700\u5148\u63d2\u5165\u7684\u5143\u7d20\uff08\u5148\u8fdb\u5148\u51fa\uff09\uff1b\u540c\u65f6\u8fd9\u4e2a\u65b9\u6cd5\u8fd8\u6709\u4e00\u4e2a\u53ef\u9009\u7684last\u53c2\u6570\uff0c\u82e5\u4e3a\u771f\uff0c\u5219\u4f1a\u79fb\u9664\u6700\u540e\u63d2\u5165\u7684\u5143\u7d20\uff08\u540e\u8fdb\u5148\u51fa\uff09\u3002 \u4e0a\u9762\u7684\u8868\u683c\u4e2d\uff0cupdate\u65b9\u6cd5\u5904\u7406\u53c2\u6570m\u7684\u65b9\u5f0f\uff0c\u662f\u5178\u578b\u7684\u201c\u9e2d\u5b50\u7c7b\u578b\u201d\u3002\u51fd\u6570\u9996\u5148\u68c0\u67e5m\u662f\u5426\u6709keys\u65b9\u6cd5\uff0c\u5982\u679c\u6709\uff0c\u90a3\u4e48update\u51fd\u6570\u5c31\u628a\u5b83\u5f53\u4f5c\u6620\u5c04\u5bf9\u8c61\u6765\u5904\u7406\u3002\u5426\u5219\uff0c\u51fd\u6570\u4f1a\u9000\u4e00\u6b65\uff0c\u8f6c\u800c\u628am\u5f53\u4f5c\u5305\u542b\u4e86\u952e\u503c\u5bf9(key, value)\u5143\u7d20\u7684\u8fed\u4ee3\u5668\u3002Python\u91cc\u5927\u591a\u6570\u6620\u5c04\u7c7b\u578b\u7684\u6784\u9020\u65b9\u6cd5\u90fd\u91c7\u7528\u4e86\u7c7b\u4f3c\u7684\u903b\u8f91\uff0c\u56e0\u6b64\u4f60\u65e2\u53ef\u4ee5\u7528\u4e00\u4e2a\u6620\u5c04\u5bf9\u8c61\u6765\u65b0\u5efa\u4e00\u4e2a\u6620\u5c04\u5bf9\u8c61\uff0c\u4e5f\u53ef\u4ee5\u7528\u5305\u542b(key, value)\u5143\u7d20\u7684\u53ef\u8fed\u4ee3\u5bf9\u8c61\u6765\u521d\u59cb\u5316\u4e00\u4e2a\u6620\u5c04\u5bf9\u8c61\u3002 \u5b57\u5178\u7684\u53d8\u79cd\uff1a collections.OrderedDict \u8fd9\u4e2a\u7c7b\u578b\u5728\u6dfb\u52a0\u952e\u7684\u65f6\u5019\u4f1a\u4fdd\u6301\u987a\u5e8f\uff0c\u56e0\u6b64\u952e\u7684\u8fed\u4ee3\u6b21\u5e8f\u603b\u662f\u4e00\u81f4\u7684\u3002OrderedDict\u7684popitem\u65b9\u6cd5\u9ed8\u8ba4\u5220\u9664\u5e76\u8fd4\u56de\u7684\u662f\u5b57\u5178\u91cc\u7684\u6700\u540e\u4e00\u4e2a\u5143\u7d20\uff0c\u4f46\u662f\u5982\u679c\u50cfmy_odict.popitem(last=False)\u8fd9\u6837\u8c03\u7528\u5b83\uff0c\u90a3\u4e48\u5b83\u5220\u9664\u5e76\u8fd4\u56de\u7b2c\u4e00\u4e2a\u88ab\u6dfb\u52a0\u8fdb\u53bb\u7684\u5143\u7d20\u3002 collections.ChainMap \u8be5\u7c7b\u578b\u53ef\u4ee5\u5bb9\u7eb3\u6570\u4e2a\u4e0d\u540c\u7684\u6620\u5c04\u5bf9\u8c61\uff0c\u7136\u540e\u5728\u8fdb\u884c\u952e\u67e5\u627e\u64cd\u4f5c\u7684\u65f6\u5019\uff0c\u8fd9\u4e9b\u5bf9\u8c61\u4f1a\u88ab\u5f53\u4f5c\u4e00\u4e2a\u6574\u4f53\u88ab\u9010\u4e2a\u67e5\u627e\uff0c\u76f4\u5230\u952e\u88ab\u627e\u5230\u4e3a\u6b62\u3002\u8fd9\u4e2a\u529f\u80fd\u5728\u7ed9\u6709\u5d4c\u5957\u4f5c\u7528\u57df\u7684\u8bed\u8a00\u505a\u89e3\u91ca\u5668\u7684\u65f6\u5019\u5f88\u6709\u7528\uff0c\u53ef\u4ee5\u7528\u4e00\u4e2a\u6620\u5c04\u5bf9\u8c61\u6765\u4ee3\u8868\u4e00\u4e2a\u4f5c\u7528\u57df\u7684\u4e0a\u4e0b\u6587\u3002 collections.Counter \u8fd9\u4e2a\u6620\u5c04\u7c7b\u578b\u4f1a\u7ed9\u952e\u51c6\u5907\u4e00\u4e2a\u6574\u6570\u8ba1\u6570\u5668\u3002\u6bcf\u6b21\u66f4\u65b0\u4e00\u4e2a\u952e\u7684\u65f6\u5019\u90fd\u4f1a\u589e\u52a0\u8fd9\u4e2a\u8ba1\u6570\u5668\u3002\u6240\u4ee5\u8fd9\u4e2a\u7c7b\u578b\u53ef\u4ee5\u7528\u6765\u7ed9\u53ef\u6563\u5217\u8868\u5bf9\u8c61\u8ba1\u6570\uff0c\u6216\u8005\u662f\u5f53\u6210\u591a\u91cd\u96c6\u6765\u7528\u2014\u2014\u591a\u91cd\u96c6\u5408\u5c31\u662f\u96c6\u5408\u91cc\u7684\u5143\u7d20\u53ef\u4ee5\u51fa\u73b0\u4e0d\u6b62\u4e00\u6b21\u3002Counter\u5b9e\u73b0\u4e86+\u548c-\u8fd0\u7b97\u7b26\u7528\u6765\u5408\u5e76\u8bb0\u5f55\uff0c\u8fd8\u6709\u50cfmost_common([n])\u8fd9\u7c7b\u5f88\u6709\u7528\u7684\u65b9\u6cd5\u3002most_common([n])\u4f1a\u6309\u7167\u6b21\u5e8f\u8fd4\u56de\u6620\u5c04\u91cc\u6700\u5e38\u89c1\u7684n\u4e2a\u952e\u548c\u5b83\u4eec\u7684\u8ba1\u6570 collections.UserDict \u8fd9\u4e2a\u7c7b\u5176\u5b9e\u5c31\u662f\u628a\u6807\u51c6dict\u7528\u7eafPython\u53c8\u5b9e\u73b0\u4e86\u4e00\u904d\u3002\u8ddfOrderedDict\u3001ChainMap\u548cCounter\u8fd9\u4e9b\u5f00\u7bb1\u5373\u7528\u7684\u7c7b\u578b\u4e0d\u540c\uff0cUserDict\u662f\u8ba9\u7528\u6237\u7ee7\u627f\u5199\u5b50\u7c7b\u7684\u3002 \u4e0b\u9762\u7684\u4f8b\u5b50\u5229\u7528Counter\u6765\u8ba1\u7b97\u5355\u8bcd\u4e2d\u5404\u4e2a\u5b57\u6bcd\u51fa\u73b0\u7684\u6b21\u6570\uff1a str = 'abracadabra' ct = collections . Counter ( str ) print ( ct ) # Counter({'a': 5, 'b': 2, 'r': 2, 'c': 1, 'd': 1}) \u4e0d\u53ef\u53d8\u6620\u5c04\u7c7b\u578b\u3002 \u6807\u51c6\u5e93\u91cc\u6240\u6709\u7684\u6620\u5c04\u7c7b\u578b\u90fd\u662f\u53ef\u53d8\u7684\uff0c\u4f46\u6709\u65f6\u5019\u4f60\u4f1a\u6709\u8fd9\u6837\u7684\u9700\u6c42\uff0c\u6bd4\u5982\u4e0d\u80fd\u8ba9\u7528\u6237\u9519\u8bef\u5730\u4fee\u6539\u67d0\u4e2a\u6620\u5c04\u3002 \u4ecePython 3.3\u5f00\u59cb\uff0c types \u6a21\u5757\u4e2d\u5f15\u5165\u4e86\u4e00\u4e2a\u5c01\u88c5\u7c7b\u540d\u53eb MappingProxyType \u3002\u5982\u679c\u7ed9\u8fd9\u4e2a\u7c7b\u4e00\u4e2a\u6620\u5c04\uff0c\u5b83\u4f1a\u8fd4\u56de\u4e00\u4e2a\u53ea\u8bfb\u7684\u6620\u5c04\u89c6\u56fe\u3002\u867d\u7136\u662f\u4e2a\u53ea\u8bfb\u89c6\u56fe\uff0c\u4f46\u662f\u5b83\u662f\u52a8\u6001\u7684\u3002\u8fd9\u610f\u5473\u7740\u5982\u679c\u5bf9\u539f\u6620\u5c04\u505a\u51fa\u4e86\u6539\u52a8\uff0c\u6211\u4eec\u901a\u8fc7\u8fd9\u4e2a\u89c6\u56fe\u53ef\u4ee5\u89c2\u5bdf\u5230\uff0c\u4f46\u662f\u65e0\u6cd5\u901a\u8fc7\u8fd9\u4e2a\u89c6\u56fe\u5bf9\u539f\u6620\u5c04\u505a\u51fa\u4fee\u6539\u3002 \u901a\u8fc7\u4e0b\u4f8b\u53ef\u4ee5\u770b\u51fa\uff0c d \u4e2d\u7684\u5185\u5bb9\u53ef\u4ee5\u901a\u8fc7 d_proxy \u770b\u5230\u3002\u4f46\u662f\u901a\u8fc7 d_proxy \u5e76\u4e0d\u80fd\u505a\u4efb\u4f55\u4fee\u6539\u3002 d_proxy \u662f\u52a8\u6001\u7684\uff0c\u4e5f\u5c31\u662f\u8bf4\u5bf9 d \u6240\u505a\u7684\u4efb\u4f55\u6539\u52a8\u90fd\u4f1a\u53cd\u9988\u5230\u5b83\u4e0a\u9762\u3002 from types import MappingProxyType d = { 1 : 'A' } d_proxy = MappingProxyType ( d ) print ( d ) # {1: 'A'} print ( d_proxy ) # {1: 'A'} print ( d [ 1 ]) # A print ( d_proxy [ 1 ]) # A d [ 2 ] = 'W' print ( d ) # {1: 'A', 2: 'W'} d_proxy [ 2 ] = 'W' # TypeError: 'mappingproxy' object does not support item assignment print ( d_proxy ) # {1: 'A', 2: 'W'} 1.5 \u96c6\u5408\uff08set\uff09 \u00b6 \u201c\u96c6\u201d\u8fd9\u4e2a\u6982\u5ff5\u5728Python\u4e2d\u7b97\u662f\u6bd4\u8f83\u5e74\u8f7b\u7684\uff0c\u540c\u65f6\u5b83\u7684\u4f7f\u7528\u7387\u4e5f\u6bd4\u8f83\u4f4e\u3002set\u548c\u5b83\u7684\u4e0d\u53ef\u53d8\u7684\u59ca\u59b9\u7c7b\u578bfrozenset\u76f4\u5230Python 2.3\u624d\u9996\u6b21\u4ee5\u6a21\u5757\u7684\u5f62\u5f0f\u51fa\u73b0\uff0c\u7136\u540e\u5728Python 2.6\u4e2d\u5b83\u4eec\u5347\u7ea7\u6210\u4e3a\u5185\u7f6e\u7c7b\u578b\u3002 \u96c6\u5408(set) \uff0c\u5305\u542b\u4e0d\u53ef\u53d8\u7684\u96c6\u5408\uff08frozenset\uff09\uff0c\u662f\u4e00\u79cd\u65e0\u5e8f\u4e14\u5143\u7d20\u552f\u4e00\u7684\u5e8f\u5217\uff0c\u6240\u4ee5\u96c6\u5408\u7684\u672c\u8d28\u662f\u8bb8\u591a\u552f\u4e00\u5bf9\u8c61\u7684\u805a\u96c6\u3002 \u548c\u5b57\u5178\u7c7b\u4f3c\uff0c\u96c6\u5408\u7684\u5143\u7d20\u662f\u4e0d\u53ef\u53d8\u7684\u3002\u53ef\u4ee5\u8ba4\u4e3a\u96c6\u5408\u4e5f\u50cf\u5b57\u5178\uff0c\u4f46\u662f\u53ea\u6709\u952e\u6ca1\u6709\u503c\u3002\u57fa\u672c\u529f\u80fd\u662f\u8fdb\u884c\u6210\u5458\u5173\u7cfb\u6d4b\u8bd5\u548c\u5220\u9664\u91cd\u590d\u5143\u7d20\u3002\u6240\u4ee5\u96c6\u5408\u53e6\u4e00\u4e2a\u7528\u9014\u662f\u53bb\u91cd\u590d\u3002 \u96c6\u5408\u4e2d\u7684\u5143\u7d20\u5fc5\u987b\u662f\u53ef\u6563\u5217\u7684\uff0cset\u7c7b\u578b\u672c\u8eab\u662f\u4e0d\u53ef\u6563\u5217\u7684\uff0c\u4f46\u662ffrozenset\u53ef\u4ee5\u3002\u56e0\u6b64\u53ef\u4ee5\u521b\u5efa\u4e00\u4e2a\u5305\u542b\u4e0d\u540cfrozenset\u7684set\u3002 \u96c6\u5408\u53ef\u4ee5\u6709\u4e24\u79cd\u521b\u5efa\u65b9\u5f0f\uff1a\u901a\u8fc7set()\u51fd\u6570\u6216\u8005{}\u6765\u521b\u5efa\uff08\u7528\u5927\u62ec\u53f7\u62ec\u4f4f\u7684\u5185\u5bb9\uff0cPython3\u81ea\u52a8\u5b9a\u4e49\u4e3a\u96c6\u5408\uff09\u3002 \u96c6\u5408\u4e0d\u5c5e\u4e8e\u5e8f\u5217\u7c7b\u6570\u636e\uff0c \u96c6\u5408\u4e0d\u652f\u6301\u901a\u8fc7\u7d22\u5f15\u8bbf\u95ee\u6307\u5b9a\u5143\u7d20\uff0c\u4f46\u53ef\u4ee5\u589e\u52a0\u548c\u5220\u9664\u5143\u7d20\u3002 \u9762\u7684\u4f8b\u5b50\u662f\u6c42 haystacke \u548c needles \u4e24\u4e2a\u96c6\u5408\u7684\u4ea4\u96c6\u5143\u7d20\u4e2a\u6570\u3002 haystacke = { 'a' , 'b' , 'c' , 'd' , 'e' , 'f' , 'g' , 'h' , 'f' , 'g' , 'h' , 'c' , 'd' , 'e' , 'c' , 'd' , 'e' , 'f' , 'g' , 'h' } needles = { 'c' , 'h' , 'w' } type ( haystacke ) # type ( needles ) # # \u4f20\u7edf\u65b9\u6cd5 found = 0 for i in needles : if i in haystacke : found += 1 print ( found ) # 2 # \u96c6\u5408\u65b9\u6cd5\u4e00 found = len ( needles & haystacke ) print ( found ) # 2 # \u96c6\u5408\u65b9\u6cd5\u4e8c found = len ( needles . intersection ( haystacke )) print ( found ) # 2 \u96c6\u5408\u5b9e\u73b0\u4e86\u5f88\u591a\u57fa\u7840\u7684\u4e2d\u7f00\u8fd0\u7b97\u7b26\uff0c\u6bd4\u5982\uff0c\u96c6\u5408\u652f\u6301\u6570\u5b66\u4e0a\u7684\u96c6\u5408\u64cd\u4f5c\uff1a\u5e76\u96c6\u3001\u4ea4\u96c6\u3001\u5dee\u96c6\u3001\u5bf9\u79f0\u5dee\u96c6\u3002 \u65b9\u6cd5\u540d\u79f0 \u8bf4\u660e add() \u4e3a\u96c6\u5408\u6dfb\u52a0\u5143\u7d20 update() \u7ed9\u96c6\u5408\u6dfb\u52a0\u5143\u7d20 clear() \u79fb\u9664\u96c6\u5408\u4e2d\u7684\u6240\u6709\u5143\u7d20 copy() \u62f7\u8d1d\u4e00\u4e2a\u96c6\u5408 remove() \u79fb\u9664\u6307\u5b9a\u5143\u7d20 pop() \u968f\u673a\u79fb\u9664\u5143\u7d20 discard() \u5220\u9664\u96c6\u5408\u4e2d\u6307\u5b9a\u7684\u5143\u7d20 < \u6216\u8005issubset() \u5224\u65ad\u6307\u5b9a\u96c6\u5408\u662f\u5426\u4e3a\u8be5\u65b9\u6cd5\u53c2\u6570\u96c6\u5408\u7684\u5b50\u96c6 | \u6216\u8005union() \u8fd4\u56de\u4e24\u4e2a\u96c6\u5408\u7684\u5e76\u96c6 & \u6216\u8005intersection() \u8fd4\u56de\u96c6\u5408\u7684\u4ea4\u96c6 intersection_update() \u8fd4\u56de\u96c6\u5408\u7684\u4ea4\u96c6 - \u6216\u8005difference() \u8fd4\u56de\u591a\u4e2a\u96c6\u5408\u7684\u5dee\u96c6 difference_update() \u79fb\u9664\u96c6\u5408\u4e2d\u7684\u5143\u7d20\uff0c\u8be5\u5143\u7d20\u5728\u6307\u5b9a\u7684\u96c6\u5408\u4e5f\u5b58\u5728 ^ \u6216\u8005symmetric_difference() \u8fd4\u56de\u4e24\u4e2a\u96c6\u5408\u4e2d\u4e0d\u91cd\u590d\u7684\u5143\u7d20\u96c6\u5408(\u4e24\u96c6\u5408\u9664\u53bb\u4ea4\u96c6\u90e8\u5206\u7684\u5143\u7d20) symmetric_difference_update() \u79fb\u9664\u5f53\u524d\u96c6\u5408\u4e2d\u5728\u53e6\u5916\u4e00\u4e2a\u6307\u5b9a\u96c6\u5408\u76f8\u540c\u7684\u5143\u7d20\uff0c\u5e76\u5c06\u53e6\u5916\u4e00\u4e2a\u6307\u5b9a\u96c6\u5408\u4e2d\u4e0d\u540c\u7684\u5143\u7d20\u63d2\u5165\u5230\u5f53\u524d\u96c6\u5408\u4e2d isdisjoint() \u5224\u65ad\u4e24\u4e2a\u96c6\u5408\u662f\u5426\u5305\u542b\u76f8\u540c\u7684\u5143\u7d20\uff0c\u5982\u679c\u6ca1\u6709\u8fd4\u56de True\uff0c\u5426\u5219\u8fd4\u56de False issuperset() \u5224\u65ad\u8be5\u65b9\u6cd5\u7684\u53c2\u6570\u96c6\u5408\u662f\u5426\u4e3a\u6307\u5b9a\u96c6\u5408\u7684\u5b50\u96c6 \u4e3e\u4f8b\uff1a a = { 'a' , 'b' , 'c' , 1 , 2 } b = { 1 , 'c' , 'd' } \u5e76\u96c6(a\u548cb\u4e2d\u7684\u6240\u6709\u4e0d\u540c\u5143\u7d20)\u3002 print ( a . union ( b )) # {'c', 1, 2, 'd', 'a', 'b'} print ( a | b ) # {'c', 1, 2, 'd', 'a', 'b'} \u4ea4\u96c6(a\u3001b\u4e2d\u540c\u65f6\u5305\u542b\u7684\u5143\u7d20)\u3002 print ( a . intersection ( b )) # {'c', 1} print ( a & b ) # {'c', 1} \u5c06a\u7684\u5185\u5bb9\u8bbe\u7f6e\u4e3aa\u548cb\u7684\u4ea4\u96c6\u3002 a = { 'a' , 'b' , 'c' , 1 , 2 } b = { 1 , 'c' , 'd' } a . intersection_update ( b ) print ( a ) # {1, 'c'} \u5728a\u4e0d\u5728b\u7684\u5143\u7d20\u3002 print ( a . difference ( b )) # {'a', 2, 'b'} print ( a - b ) # {2, 'a', 'b'} \u5c06a\u7684\u5185\u5bb9\u8bbe\u4e3a\u5728a\u4e0d\u5728b\u7684\u5143\u7d20\u3002 a = { 'a' , 'b' , 'c' , 1 , 2 } b = { 1 , 'c' , 'd' } a . difference_update ( b ) print ( a ) # {2, 'b', 'a'} a = { 'a' , 'b' , 'c' , 1 , 2 } b = { 1 , 'c' , 'd' } a -= b print ( a ) # {2, 'a', 'b'} \u5c06\u5143\u7d20\u52a0\u5165\u96c6\u5408a\u3002 a . add ( 7 ) print ( a ) # {1, 2, 'c', 7, 'a', 'b'} \u6bcf\u6b21\u8f93\u51fa\u7684\u987a\u5e8f\u662f\u4e0d\u4e00\u6837\u7684 \u4ece\u96c6\u5408a\u79fb\u9664\u67d0\u4e2a\u5143\u7d20\u3002 a . remove ( 7 ) print ( a ) # {1, 2, 'c', 'a', 'b'} \u5982\u679ca\u88ab\u6e05\u7a7a\uff0c\u5219\u62a5\u9519 KeyError: 7 \u6240\u6709\u5728a\u6216b\u4e2d\uff0c\u4f46\u4e0d\u662f\u540c\u65f6\u5728a\u3001b\u4e2d\u7684\u5143\u7d20\u3002 print ( a . symmetric_difference ( b )) # {2, 'd', 'b', 'a'} print ( a ^ b ) # {2, 'd', 'b', 'a'} \u5c06a\u7684\u5185\u5bb9\u8bbe\u4e3a\u6240\u6709\u5728a\u6216b\u4e2d\uff0c\u4f46\u4e0d\u662f\u540c\u65f6\u5728a\u3001b\u4e2d\u7684\u5143\u7d20\u3002 a = { 'a' , 'b' , 'c' , 1 , 2 } b = { 1 , 'c' , 'd' } a . symmetric_difference_update ( b ) print ( a ) # {'a', 2, 'd', 'b'} a = { 'a' , 'b' , 'c' , 1 , 2 } b = { 1 , 'c' , 'd' } a ^= b print ( a ) # {2, 'd', 'a', 'b'} \u5982\u679ca\u5305\u542b\u4e8eb\uff0c\u8fd4\u56deTure\u3002 print ( a . issubset ( b )) # False \u5c06a\u7684\u5185\u5bb9\u8bbe\u7f6e\u4e3aa\u548cb\u7684\u5e76\u96c6\u3002 print ( a ) # {'a', 2, 'd', 'b'} a = { 'a' , 'b' , 'c' , 1 , 2 } a . update ( b ) print ( a ) # {1, 2, 'a', 'b', 'd', 'c'} \u79fb\u9664\u4efb\u610f\u5143\u7d20\uff0c\u5982\u679c\u96c6\u5408\u662f\u7a7a\u7684\uff0c\u629b\u51fakeyError\u3002 a . pop () # \u968f\u673a\u79fb\u9664\u67d0\u4e2a\u5143\u7d20\uff0c\u6ca1\u6709\u8f93\u5165\u53d8\u91cf\uff0c\u5982\u679c\u96c6\u5408\u662f\u7a7a\u7684\uff0c\u629b\u51faKeyError: 'pop from an empty set' print ( a ) # {2, 1, 'd', 'b', 'a'} \u5c06\u96c6\u5408\u91cd\u7f6e\u4e3a\u7a7a\uff0c\u6e05\u7a7a\u6240\u6709\u5143\u7d20\u3002 a . clear () print ( a ) # set() \u96c6\u5408\u7684\u5143\u7d20\u5fc5\u987b\u662f\u4e0d\u53ef\u53d8\u7684\uff0c\u5982\u679c\u60f3\u8981\u5305\u542b\u5217\u8868\u578b\u7684\u5143\u7d20\uff0c\u5fc5\u987b\u5148\u8f6c\u6362\u4e3a\u5143\u7ec4\u3002 my_data1 = [ 1 , 2 , 3 , 4 ] my_data2 = [ 3 , 4 , 5 , 6 ] my_set = { tuple ( my_data1 ), tuple ( my_data2 )} print ( my_set ) # {(1, 2, 3, 4), (3, 4, 5, 6)} 1.6 \u5143\u7ec4\uff08tuple\uff09 \u00b6 Python \u7684\u5143\u7ec4\u4e0e\u5217\u8868\u7c7b\u4f3c\uff0c\u4e0d\u540c\u4e4b\u5904\u5728\u4e8e\u5143\u7ec4\u7684\u5143\u7d20\u4e0d\u80fd\u4fee\u6539\u3002 \u5143\u7ec4\u4f7f\u7528\u5c0f\u62ec\u53f7( )\uff0c\u5217\u8868\u4f7f\u7528\u65b9\u62ec\u53f7[ ]\u3002 \u5143\u7ec4\u4e2d\u53ea\u5305\u542b\u4e00\u4e2a\u5143\u7d20\u65f6\uff0c\u9700\u8981\u5728\u5143\u7d20\u540e\u9762\u6dfb\u52a0\u9017\u53f7 \uff0c\u5426\u5219\u62ec\u53f7\u4f1a\u88ab\u5f53\u4f5c\u8fd0\u7b97\u7b26\u4f7f\u7528\u3002 \u5143\u7ec4\u53ef\u4ee5\u4f7f\u7528\u4e0b\u6807\u7d22\u5f15\u6765\u8bbf\u95ee\u5143\u7ec4\u4e2d\u7684\u503c\u3002 \u5143\u7ec4\u4e2d\u7684\u5143\u7d20\u503c\u662f\u4e0d\u5141\u8bb8\u4fee\u6539\u7684\uff0c\u4f46\u6211\u4eec\u53ef\u4ee5\u5bf9\u5143\u7ec4\u8fdb\u884c\u8fde\u63a5\u7ec4\u5408\u3002 \u5143\u7ec4\u4e2d\u7684\u5143\u7d20\u503c\u662f\u4e0d\u5141\u8bb8\u5220\u9664\u7684\uff0c\u4f46\u6211\u4eec\u53ef\u4ee5\u4f7f\u7528del\u8bed\u53e5\u6765\u5220\u9664\u6574\u4e2a\u5143\u7ec4\u3002 # \u6b64\u5904\u62ec\u53f7\u88ab\u89e3\u6790\u4e3a\u8fd0\u7b97\u7b26\uff0c\u9700\u8981\u5728\u540e\u9762\u52a0\u4e0a\u9017\u53f7\u624d\u4f1a\u88ab\u89e3\u91ca\u4e3a\u5143\u7ec4 tup1 = ( 10 ) print ( type ( tup1 )) # tup1 = ( 10 ,) print ( type ( tup1 )) # \u521b\u5efa\u5143\u7ec4\u6700\u7b80\u5355\u7684\u529e\u6cd5\u5c31\u662f\u7528\u9017\u53f7\u5206\u9694\u5e8f\u5217\u503c\u3002\u5143\u7ec4\u5bf9\u6570\u636e\u7c7b\u578b\u6ca1\u6709\u4e00\u81f4\u6027\u8981\u6c42\u3002 tup = 4 , 5 , 6 print ( tup ) # (4, 5, 6) nested_tup = ( 4 , 5 , 6 ), ( 7 , 8 ) print ( nested_tup ) # # ((4, 5, 6), (7, 8)) tup = ( 'a' , 'b' , { 'one' : 1 }) print ( type ( tup )) # \u4f7f\u7528\u52a0\u53f7\uff08+\uff09\u8fdb\u884c\u5143\u7ec4\u8fde\u63a5\u5408\u5e76\u3002 tup = tuple (( 4 , None , 'fool' ) + ( 6 , 0 ) + ( 'bar' ,)) print ( tup ) # (4, None, 'fool', 6, 0, 'bar') \u5143\u7ec4\u7684\u4e0d\u53ef\u53d8\u6307\u7684\u662f**\u5143\u7ec4\u6240\u6307\u5411\u7684\u5185\u5b58\u4e2d\u7684\u5185\u5bb9\u4e0d\u53ef\u53d8**\u3002 tup = ( 'h' , 'e' , 'l' , 'l' , 'o' ) print ( id ( tup )) # 139820353350208 tup = ( 1 , 2 , 3 , 4 , 5 ) print ( id ( tup )) # 139820353298896 tup [ 0 ] = 'x' # Traceback (most recent call last): # File \"\", line 1, in # TypeError: 'tuple' object does not support item assignment \u5c06\u5143\u7ec4\u4e58\u4ee5\u6574\u6570\uff0c\u5219\u4f1a\u548c\u5217\u8868\u4e00\u6837\uff0c\u751f\u6210\u542b\u6709\u591a\u4efd\u62f7\u8d1d\u7684\u5143\u7ec4\u3002\u5bf9\u8c61\u81ea\u8eab\u5e76\u6ca1\u6709\u590d\u5236\uff0c\u53ea\u662f\u6307\u5411\u5b83\u4eec\u7684\u5f15\u7528\u8fdb\u884c\u4e86\u590d\u5236\u3002 tup = tuple (( 'fool' , 'bar' ) * 4 ) print ( tup ) # ('fool', 'bar', 'fool', 'bar', 'fool', 'bar', 'fool', 'bar') \u5982\u679c\u5143\u7ec4\u4e2d\u7684\u4e00\u4e2a\u5bf9\u8c61\u662f\u53ef\u53d8\u7684\uff0c\u4f8b\u5982\u5217\u8868\uff0c\u4f60\u53ef\u4ee5\u5728\u5b83\u5185\u90e8\u8fdb\u884c\u4fee\u6539\u3002 tup = tuple ([ 'foo' , [ 4 , 5 , 6 ], True ]) tup [ 1 ] . append ( 0 ) print ( tup ) # ('foo', [4, 5, 6, 0], True) tup [ 1 ] . append ([ 9 ]) print ( tup ) # ('foo', [4, 5, 6, 0, [9]], True) \u4f7f\u7528tuple\u51fd\u6570\u5c06\u4efb\u610f\u5e8f\u5217\u6216\u8fed\u4ee3\u5668\u8f6c\u6362\u4e3a\u5143\u7ec4\u3002 tup = tuple ([ 4 , 5 , 6 ]) print ( tup ) # (4, 5, 6) tup = tuple ( 'string' ) print ( tup ) # ('s', 't', 'r', 'i', 'n', 'g') print ( tup [ 2 ]) # r # \u5143\u7ec4\u7684\u5143\u7d20\u53ef\u4ee5\u901a\u8fc7\u4e2d\u62ec\u53f7[]\u6765\u83b7\u53d6 \u5982\u679c\u8981\u5c06\u5143\u7ec4\u578b\u7684\u8868\u8fbe\u5f0f\u8d4b\u503c\u7ed9\u53d8\u91cf\uff0cPython\u4f1a\u5bf9\u7b49\u53f7\u53f3\u8fb9\u7684\u503c\u8fdb\u884c \u62c6\u5305 \u3002 tup = ( 9 , 5 , ( 8 , 7 )) a , b , c = tup print ( a ) # 9 print ( b ) # 5 print ( c ) # (8, 7) a , b , ( c , d ) = tup print ( a ) # 9 print ( b ) # 5 print ( c ) # 8 print ( d ) # 7 tup = ( 9 , 5 , ( 8 , 7 )) a , b , c = tup c , a = a , c # \u5229\u7528\u62c6\u5305\u5b9e\u73b0\u4ea4\u6362 print ( a ) # (8, 7) print ( b ) # 5 print ( c ) # 9 \u5229\u7528\u62c6\u5305\u5b9e\u73b0\u904d\u5386\u5143\u7ec4\u6216\u5217\u8868\u7ec4\u6210\u7684\u5e8f\u5217\u3002 seq = [( 1 , 2 , 3 ), ( 4 , 5 , 6 ), ( 7 , 8 , 9 )] for a , b , c in seq : print ( 'a= {0} , b= {0} , c= {0} ' . format ( a , b , c )) # \u5217\u8868\u6bcf\u4e2a\u5143\u7d20\u7684\u53d6\u503c\u987a\u5e8f # a=1, b=1, c=1 # a=4, b=4, c=4 # a=7, b=7, c=7 print ( 'a= {0} , b= {1} , c= {2} ' . format ( a , b , c )) # a=1, b=2, c=3 # a=4, b=5, c=6 # a=7, b=8, c=9 print ( 'a= {2} , b= {0} , c= {1} ' . format ( a , b , c )) # a=3, b=1, c=2 # a=6, b=4, c=5 # a=9, b=7, c=8 \u5143\u7ec4\u62c6\u5305\u529f\u80fd\u8fd8\u5305\u62ec\u7279\u6b8a\u7684\u8bed\u6cd5*rest\u3002\u5f88\u591aPython\u7f16\u7a0b\u8005\u4f1a\u4f7f\u7528\u4e0b\u5212\u7ebf\uff08_\uff09\u6765\u8868\u793a\u4e0d\u60f3\u8981\u7684\u53d8\u91cf\u3002 values = 1 , 2 , 3 , 4 , 5 a , b , * rest = values print ( a ) # 1 print ( b ) # 2 print ( * rest ) # 3 4 5 a , b , * _ = values print ( * _ ) # 3 4 5 \u5177\u540d\u5143\u7ec4\u3002 collections.namedtuple \u662f\u4e00\u4e2a\u5de5\u5382\u51fd\u6570\uff0c\u5b83\u53ef\u4ee5\u7528\u6765\u6784\u5efa\u4e00\u4e2a\u5e26\u5b57\u6bb5\u540d\u7684\u5143\u7ec4\u548c\u4e00\u4e2a\u6709\u540d\u5b57\u7684\u7c7b\u3002 \u7528namedtuple\u6784\u5efa\u7684\u7c7b\u7684\u5b9e\u4f8b\u6240\u6d88\u8017\u7684\u5185\u5b58\u8ddf\u5143\u7ec4\u662f\u4e00\u6837\u7684\uff0c\u56e0\u4e3a\u5b57\u6bb5\u540d\u90fd\u88ab\u5b58\u5728\u5bf9\u5e94\u7684\u7c7b\u91cc\u9762\u3002 \u521b\u5efa\u4e00\u4e2a\u5177\u540d\u5143\u7ec4\u9700\u8981\u4e24\u4e2a\u53c2\u6570\uff0c\u4e00\u4e2a\u662f\u7c7b\u540d( City )\uff0c\u53e6\u4e00\u4e2a\u662f\u7c7b\u7684\u5404\u4e2a\u5b57\u6bb5\u7684\u540d\u5b57( 'name country population coordinates' )\u3002\u540e\u8005\u53ef\u4ee5\u662f\u7531\u6570\u4e2a\u5b57\u7b26\u4e32\u7ec4\u6210\u7684\u53ef\u8fed\u4ee3\u5bf9\u8c61\uff0c\u6216\u8005\u662f\u7531\u7a7a\u683c\u5206\u9694\u5f00\u7684\u5b57\u6bb5\u540d\u7ec4\u6210\u7684\u5b57\u7b26\u4e32\u3002 \u5b58\u653e\u5728\u5bf9\u5e94\u5b57\u6bb5\u91cc\u7684\u6570\u636e\u8981\u4ee5\u4e00\u4e32\u53c2\u6570\u7684\u5f62\u5f0f\u4f20\u5165\u5230\u6784\u9020\u51fd\u6570\u4e2d\uff08\u6ce8\u610f\uff0c\u5143\u7ec4\u7684\u6784\u9020\u51fd\u6570\u5374\u53ea\u63a5\u53d7\u5355\u4e00\u7684\u53ef\u8fed\u4ee3\u5bf9\u8c61\uff09\u3002 \u5177\u540d\u5143\u7ec4\u8fd8\u6709\u4e00\u4e9b\u81ea\u5df1\u4e13\u6709\u7684\u5c5e\u6027\u3002\u4e0b\u9762\u5c55\u793a\u4e86\u51e0\u4e2a\u6700\u6709\u7528\u7684\uff1a _fields \u7c7b\u5c5e\u6027\u3001\u7c7b\u65b9\u6cd5 _make(iterable) \u548c\u5b9e\u4f8b\u65b9\u6cd5 _asdict() \u3002 _fields \u5c5e\u6027\u662f\u4e00\u4e2a\u5305\u542b\u8fd9\u4e2a\u7c7b\u6240\u6709\u5b57\u6bb5\u540d\u79f0\u7684\u5143\u7ec4\u3002 \u7528 _make() \u901a\u8fc7\u63a5\u53d7\u4e00\u4e2a\u53ef\u8fed\u4ee3\u5bf9\u8c61\u6765\u751f\u6210\u8fd9\u4e2a\u7c7b\u7684\u4e00\u4e2a\u5b9e\u4f8b\uff0c\u5b83\u7684\u4f5c\u7528\u8ddf City(*delhi_data) \u662f\u4e00\u6837\u7684\u3002 _asdict() \u628a\u5177\u540d\u5143\u7ec4\u4ee5 collections.OrderedDict \u7684\u5f62\u5f0f\u8fd4\u56de\uff0c\u6211\u4eec\u53ef\u4ee5\u5229\u7528\u5b83\u6765\u628a\u5143\u7ec4\u91cc\u7684\u4fe1\u606f\u53cb\u597d\u5730\u5448\u73b0\u51fa\u6765\u3002 from collections import namedtuple City = namedtuple ( 'City' , 'name country population coordinates' ) tokyo = City ( 'Tokyo' , 'JP' , 36.933 , ( 35.689722 , 139691667 )) print ( tokyo ) # City(name='Tokyo', country='JP', population=36.933, coordinates=(35.689722, 139691667)) print ( tokyo . population ) # 36.933 print ( tokyo [ 3 ]) # (35.689722, 139691667) print ( City . _fields ) # ('name', 'country', 'population', 'coordinates') LatLong = namedtuple ( 'LatLong' , 'lat long' ) delhi_data = ( 'Delhi NCR' , 'IN' , 21.935 , LatLong ( 28.613899 , 77.208889 )) delhi = City . _make ( delhi_data ) print ( delhi ) # City(name='Delhi NCR', country='IN', population=21.935, coordinates=LatLong(lat=28.613899, long=77.208889)) print ( delhi . _asdict ()) # OrderedDict([('name', 'Delhi NCR'), ('country', 'IN'), ('population', 21.935), ('coordinates', LatLong(lat=28.613899, long=77.208889))]) for key , value in delhi . _asdict () . items (): print ( key + ':' , value ) # name: Delhi NCR # country: IN # population: 21.935 # coordinates: LatLong(lat=28.613899, long=77.208889) \u5143\u7ec4\u8fd8\u6709\u7b2c\u4e8c\u91cd\u529f\u80fd\uff1a\u4f5c\u4e3a\u4e0d\u53ef\u53d8\u5217\u8868\u7684\u5143\u7ec4\u3002 \u4e0b\u9762\u662f\u5217\u8868\u6216\u5143\u7ec4\u7684\u65b9\u6cd5\u548c\u5c5e\u6027\u5bf9\u6bd4\u3002\u9664\u4e86\u8ddf\u589e\u51cf\u5143\u7d20\u76f8\u5173\u7684\u65b9\u6cd5\u4e4b\u5916\uff0c\u5143\u7ec4\u652f\u6301\u5217\u8868\u7684\u5176\u4ed6\u6240\u6709\u65b9\u6cd5\u3002\u8fd8\u6709\u4e00\u4e2a\u4f8b\u5916\uff0c\u5143\u7ec4\u6ca1\u6709__reversed__\u65b9\u6cd5\u3002 \u4e00\u4e2a\u5173\u4e8e+=\u548c*=\u7684\u8c1c\u9898\u3002 \u4e0b\u9762\u7684\u4f8b\u5b50\u5c55\u793a\u4e86 *= \u5728\u53ef\u53d8\u548c\u4e0d\u53ef\u53d8\u5e8f\u5217\u4e0a\u7684\u4f5c\u7528\u3002\u5217\u8868\u7684ID\u6ca1\u53d8\uff0c\u65b0\u5143\u7d20\u8ffd\u52a0\u5230\u5217\u8868\u4e0a\uff0c\u4f46\u6267\u884c\u589e\u91cf\u4e58\u6cd5\u540e\uff0c\u65b0\u7684\u5143\u7ec4\u88ab\u521b\u5efa\u3002 list1 = [ 1 , 2 , 3 , 4 ] id ( list1 ) # 140409777308808 list1 *= 2 print ( list1 ) # [1, 2, 3, 4, 1, 2, 3, 4] id ( list1 ) # 140409777308808 tuple1 = ( 1 , 2 , 3 , 4 ) id ( tuple1 ) # 140409777230536 tuple1 *= 2 print ( tuple1 ) # (1, 2, 3, 4, 1, 2, 3, 4) id ( tuple1 ) # 140409780104888 \u4f46\u5bf9\u4e8e\u4e0b\u9762\u7684\u4f8b\u5b50\uff0c\u867d\u7136 tuple1[2] += [50, 60] \u6267\u884c\u65f6\u6709\u5f02\u5e38\u629b\u51fa\uff0c\u4f46 tuple1 \u5374\u88ab\u4fee\u6539\u4e86\u3002 t = ( 1 , 2 , [ 10 , 20 ]) t [ 2 ] += [ 50 , 60 ] # TypeError: 'tuple' object does not support item assignment print ( t ) # (1, 2, [10, 20, 50, 60]) \u4e0b\u56fe\u5927\u81f4\u63cf\u8ff0\u4e86\u4e0a\u8ff0\u6267\u884c\u8fc7\u7a0b\u3002 \u4e3a\u4e86\u907f\u514d\u4e0a\u9762\u60c5\u51b5\u7684\u53d1\u751f\uff0c\u6211\u4eec**\u4e0d\u8981\u628a\u53ef\u53d8\u5bf9\u8c61\u653e\u5728\u5143\u7ec4\u91cc\u9762**\u3002\u589e\u91cf\u8d4b\u503c\u4e0d\u662f\u4e00\u4e2a\u539f\u5b50\u64cd\u4f5c\uff0c\u5b83\u867d\u7136\u629b\u51fa\u4e86\u5f02\u5e38\uff0c\u4f46\u8fd8\u662f\u5b8c\u6210\u4e86\u64cd\u4f5c\u3002 1.7 \u5185\u5b58\u89c6\u56feMemoryview \u00b6 memoryview \u662f\u4e00\u4e2a\u5185\u7f6e\u7c7b\uff0c\u5b83\u80fd\u8ba9\u7528\u6237\u5728\u4e0d\u590d\u5236\u5185\u5bb9\u7684\u60c5\u51b5\u4e0b\u64cd\u4f5c\u540c\u4e00\u4e2a\u6570\u7ec4\u7684\u4e0d\u540c\u5207\u7247\u3002 \u5185\u5b58\u89c6\u56fe\u5176\u5b9e\u662f\u6cdb\u5316\u548c\u53bb\u6570\u5b66\u5316\u7684NumPy\u6570\u7ec4\u3002\u5b83\u8ba9\u4f60\u5728\u4e0d\u9700\u8981\u590d\u5236\u5185\u5bb9\u7684\u524d\u63d0\u4e0b\uff0c\u5728\u6570\u636e\u7ed3\u6784\u4e4b\u95f4\u5171\u4eab\u5185\u5b58\u3002 \u5176\u4e2d\u6570\u636e\u7ed3\u6784\u53ef\u4ee5\u662f\u4efb\u4f55\u5f62\u5f0f\uff0c\u6bd4\u5982PIL\u56fe\u7247\u3001SQLite\u6570\u636e\u5e93\u548cNumPy\u7684\u6570\u7ec4\uff0c\u7b49\u7b49\u3002\u8fd9\u4e2a\u529f\u80fd\u5728\u5904\u7406\u5927\u578b\u6570\u636e\u96c6\u5408\u7684\u65f6\u5019\u975e\u5e38\u91cd\u8981\u3002 memoryview.cast \u7684\u6982\u5ff5\u8ddf\u6570\u7ec4\u6a21\u5757\u7c7b\u4f3c\uff0c\u80fd\u7528\u4e0d\u540c\u7684\u65b9\u5f0f\u8bfb\u5199\u540c\u4e00\u5757\u5185\u5b58\u6570\u636e\uff0c\u800c\u4e14\u5185\u5bb9\u5b57\u8282\u4e0d\u4f1a\u968f\u610f\u79fb\u52a8\u3002\u8fd9\u8ddfC\u8bed\u8a00\u4e2d\u7c7b\u578b\u8f6c\u6362\u7684\u6982\u5ff5\u5dee\u4e0d\u591a\u3002 memoryview.cast \u4f1a\u628a\u540c\u4e00\u5757\u5185\u5b58\u91cc\u7684\u5185\u5bb9\u6253\u5305\u6210\u4e00\u4e2a\u5168\u65b0\u7684memoryview\u5bf9\u8c61\u7ed9\u4f60\u3002 array \u91cc\u9762\u7684Type code\uff1a 'b' signed integer 1 'B' unsigned integer 1 'u' Unicode character 2 (see note) 'h' signed integer 2 'H' unsigned integer 2 'i' signed integer 2 'I' unsigned integer 2 'l' signed integer 4 'L' unsigned integer 4 'q' signed integer 8 (see note) 'Q' unsigned integer 8 (see note) 'f' floating point 4 'd' floating point 8 numbers = array ( 'h' , [ - 2 , - 1 , 0 , 1 , 2 ]) # array('h', [-2, -1, 0, 1, 2]) # \u75285\u4e2a\u77ed\u6574\u578b\u6709\u7b26\u53f7\u6574\u6570\u7684\u6570\u7ec4\uff08\u7c7b\u578b\u7801\u662f'h'\uff09\u521b\u5efa\u4e00\u4e2amemoryview\u3002 memv = memoryview ( numbers ) # memv\u91cc\u76845\u4e2a\u5143\u7d20\u8ddf\u6570\u7ec4\u91cc\u7684\u6ca1\u6709\u533a\u522b\u3002 print ( len ( memv )) # 5 print ( memv [ 0 ]) # -2 print ( memv . tolist ()) # [-2, -1, 0, 1, 2] # \u521b\u5efa\u4e00\u4e2amemv_oct\uff0c\u8fd9\u4e00\u6b21\u662f\u628amemv\u91cc\u7684\u5185\u5bb9\u8f6c\u6362\u6210'B'\u7c7b\u578b\uff0c\u4e5f\u5c31\u662f\u65e0\u7b26\u53f7\u5b57\u7b26\u3002 memv_oct = memv . cast ( 'B' ) print ( memv_oct . tolist ()) # [254, 255, 255, 255, 0, 0, 1, 0, 2, 0] # \u628a\u4f4d\u4e8e\u4f4d\u7f6e5\u7684\u5b57\u8282\u8d4b\u503c\u62104\u3002\u56e0\u4e3a\u6211\u4eec\u628a\u53602\u4e2a\u5b57\u8282\u7684\u6574\u6570\u7684\u9ad8\u4f4d\u5b57\u8282\u6539\u6210\u4e864\uff0c\u6240\u4ee5\u8fd9\u4e2a\u6709\u7b26\u53f7\u6574\u6570\u7684\u503c\u5c31\u53d8\u6210\u4e861024\u3002 memv_oct [ 5 ] = 4 print ( numbers ) # array('h', [-2, -1, 1024, 1, 2]) 2. \u52a8\u6001\u5f15\u7528\u3001\u5f3a\u7c7b\u578b \u00b6 \u661f\u53f7 * \u7684\u53c2\u6570\u4f1a\u4ee5\u5143\u7ec4(tuple)\u7684\u5f62\u5f0f\u5bfc\u5165\uff0c\u5b58\u653e\u6240\u6709\u672a\u547d\u540d\u7684\u53d8\u91cf\u53c2\u6570 def printinfo ( arg1 , * vartuple ): print ( \"\u8f93\u51fa\u4efb\u4f55\u4f20\u5165\u7684\u53c2\u6570: \" ) print ( arg1 ) print ( vartuple ) for var in vartuple : print ( var ) return printinfo ( 10 ) # 10 # () printinfo ( 70 , 60 , 50 ) # 70 # (60, 50) # 60 # 50 \u4e24\u4e2a\u661f\u53f7 ** \u7684\u53c2\u6570\u4f1a\u4ee5\u5b57\u5178\u7684\u5f62\u5f0f\u5bfc\u5165\u3002 def printinfo ( arg1 , ** vardict ): print ( \"\u8f93\u51fa\u4efb\u4f55\u4f20\u5165\u7684\u53c2\u6570: \" ) print ( arg1 ) print ( vardict ) printinfo ( 1 , a = 2 , b = 3 ) # 1 # {'a': 2, 'b': 3} \u5b57\u5178\u683c\u5f0f\u8f93\u51fa Python\u4e2d\u7684\u5bf9\u8c61\u5f15\u7528\u5e76\u4e0d\u6d89\u53ca\u7c7b\u578b\u3002\u53d8\u91cf\u5bf9\u4e8e\u5bf9\u8c61\u6765\u8bf4\u53ea\u662f\u7279\u5b9a\u547d\u540d\u7a7a\u95f4\u4e2d\u7684\u540d\u79f0\uff1b\u7c7b\u578b\u4fe1\u606f\u662f\u5b58\u50a8\u5728\u5bf9\u8c61\u81ea\u8eab\u4e4b\u4e2d\u3002 a = 5 print ( type ( a )) # a = 'foo' print ( type ( a )) # Python\u662f\u5f3a\u7c7b\u578b\u8bed\u8a00\uff0c\u6240\u6709\u7684\u5bf9\u8c61\u90fd\u62e5\u6709\u4e00\u4e2a\u6307\u5b9a\u7684\u7c7b\u578b\uff08\u6216\u7c7b\uff09\uff0c\u9690\u5f0f\u7684\u8f6c\u6362\u53ea\u5728\u67d0\u4e9b\u7279\u5b9a\u3001\u660e\u663e\u7684\u60c5\u51b5\u4e0b\u53d1\u751f\u3002 a = 4.5 b = 2 print ( 'a is {0} , b is {1} ' . format ( type ( a ), type ( b ))) # a is , b is \u5b57\u4e32\u683c\u5f0f\u5316\uff0c\u7528\u4e8e\u540e\u7eed\u8bbf\u95ee print ( a / b ) # 2.25 \u4f7f\u7528isinstance\u51fd\u6570\u6765\u68c0\u67e5\u4e00\u4e2a\u5bf9\u8c61\u662f\u5426\u662f\u7279\u5b9a\u7c7b\u578b\u7684\u5b9e\u4f8b\u3002isinstance\u63a5\u53d7\u4e00\u4e2a\u5305\u542b\u7c7b\u578b\u7684\u5143\u7ec4\uff0c\u53ef\u4ee5\u68c0\u67e5\u5bf9\u8c61\u7684\u7c7b\u578b\u662f\u5426\u5728\u5143\u7ec4\u4e2d\u7684\u7c7b\u578b\u4e2d\u3002 a = 5 b = 4.5 c = 'foo' print ( isinstance ( a , int )) # True print ( isinstance ( b , str )) # False print ( isinstance ( c , ( str , int ))) # True print ( isinstance ( c , ( float , int ))) # False \u5c5e\u6027\u548c\u65b9\u6cd5\u4e5f\u53ef\u4ee5\u901a\u8fc7getattr\u51fd\u6570\u83b7\u5f97\u3002\u5728\u5176\u4ed6\u7684\u8bed\u8a00\u4e2d\uff0c\u901a\u8fc7\u53d8\u91cf\u540d\u8bbf\u95ee\u5bf9\u8c61\u901a\u5e38\u88ab\u79f0\u4e3a\u201c\u53cd\u5c04\u201d\u3002 b = 'foo' print ( getattr ( b , 'split' )) # 3. \u4e8c\u5143\u8fd0\u7b97\u7b26\u548c\u6bd4\u8f83\u8fd0\u7b97 \u00b6 \u68c0\u67e5\u4e24\u4e2a\u5f15\u7528\u662f\u5426\u6307\u5411\u540c\u4e00\u4e2a\u5bf9\u8c61\uff0c\u53ef\u4ee5\u4f7f\u7528is\u5173\u952e\u5b57\u3002 is\u548cis not\u7684\u5e38\u7528\u4e4b\u5904\u662f\u68c0\u67e5\u4e00\u4e2a\u53d8\u91cf\u662f\u5426\u4e3aNone\uff0c\u56e0\u4e3aNone\u53ea\u6709\u4e00\u4e2a\u5b9e\u4f8b\u3002 a = [ 1 , 2 , 3 ] b = a c = list ( a ) # list\u51fd\u6570\u603b\u662f\u521b\u5efa\u4e00\u4e2a\u65b0\u7684Python\u5217\u8868\uff08\u5373\u4e00\u4efd\u62f7\u8d1d\uff09 print ( a is b ) # True print ( a is not c ) # True print ( a == c ) # True d = None print ( d is None ) # True Python\u4e2d\u7684\u5927\u90e8\u5206\u5bf9\u8c61\uff0c\u4f8b\u5982\u5217\u8868\u3001\u5b57\u5178\u3001NumPy\u6570\u7ec4\u90fd\u662f\u53ef\u53d8\u5bf9\u8c61\uff0c\u5927\u591a\u6570\u7528\u6237\u5b9a\u4e49\u7684\u7c7b\u578b\uff08\u7c7b\uff09\u4e5f\u662f\u53ef\u53d8\u7684\u3002 \u53ef\u53d8\u5bf9\u8c61\u4e2d\u5305\u542b\u7684\u5bf9\u8c61\u548c\u503c\u662f\u53ef\u4ee5\u88ab\u4fee\u6539\u7684\u3002\u8fd8\u6709\u5176\u4ed6\u4e00\u4e9b\u5bf9\u8c61\u662f\u4e0d\u53ef\u53d8\u7684\uff0c\u6bd4\u5982\u5b57\u7b26\u4e32\u3001\u5143\u7ec4\u3002 a_list = [ 'foo' , 2 , [ 4 , 5 ]] # \u5217\u8868 a_list [ 2 ] = ( 3 , 4 ) print ( a_list ) # ['foo', 2, (3, 4)] a_tuple = ( 3 , 5 , ( 4 , 5 )) # \u5143\u7ec4 a_tuple [ 1 ] = 'four' # TypeError: 'tuple' object does not support item assignment \u4e0d\u53ef\u88ab\u4fee\u6539 print ( a_tuple ) # (3, 5, (4, 5)) 4. \u6807\u91cf\u7c7b\u578b \u00b6 Python\u6807\u91cf\u7c7b\u578b\uff1aNone, str, bytes, float, bool, int\u3002 \u6570\u503c\u7c7b\u578b\u3002 \u57fa\u7840\u7684Python\u6570\u5b57\u7c7b\u578b\u5c31\u662fint\u548cfloat\u3002int\u53ef\u4ee5\u5b58\u50a8\u4efb\u610f\u5927\u5c0f\u6570\u5b57\u3002\u6d6e\u70b9\u6570\u5728Python\u4e2d\u7528float\u8868\u793a\uff0c\u6bcf\u4e00\u4e2a\u6d6e\u70b9\u6570\u90fd\u662f\u53cc\u7cbe\u5ea664\u4f4d\u6570\u503c\u3002 ival = 17338971 print ( ival ** 6 ) # 27173145946003847721495630081806010734757321 fval = 17338971.0 print ( fval ** 6 ) # 2.7173145946003847e+43 print ( 3 / 2 ) # 1.5 print ( 3 // 2 ) # 1 \u5b57\u7b26\u4e32\u3002 Python\u7684\u5b57\u7b26\u4e32\u662f\u4e0d\u53ef\u53d8\u7684\u3002 a = 5.6 s = str ( a ) print ( s ) # 5.6 b = 'python' print ( list ( b )) # ['p', 'y', 't', 'h', 'o', 'n'] print ( b [ 2 ]) # t b [ 2 ] = 'f' # TypeError: 'str' object does not support item assignment \u5b57\u7b26\u4e32\u662f\u4e0d\u53ef\u53d8\u7684 \u53cd\u659c\u6760\u7b26\u53f7\\\u662f\u4e00\u79cd\u8f6c\u4e49\u7b26\u53f7\uff0c\u5b83\u7528\u6765\u6307\u660e\u7279\u6b8a\u7b26\u53f7\u3002 \u5982\u679c\u4f60\u6709\u4e00\u4e2a\u4e0d\u542b\u7279\u6b8a\u7b26\u53f7\u4f46\u542b\u6709\u5927\u91cf\u53cd\u659c\u6760\u7684\u5b57\u7b26\u4e32\u65f6\uff0c\u53ef\u4ee5\u5728\u5b57\u7b26\u4e32\u524d\u9762\u52a0\u4e00\u4e2a\u524d\u7f00\u7b26\u53f7r\uff0c\u8868\u660e\u8fd9\u4e9b\u5b57\u7b26\u662f\u539f\u751f\u5b57\u7b26\uff0cr\u662fraw\u7684\u7b80\u5199\uff0c\u8868\u793a\u539f\u751f\u7684\u3002 x = '12 \\\\ 34' y = r 'this\\has\\no\\special\\characters' print ( x ) # 12\\34 print ( y ) # this\\has\\no\\special\\characters \u5b57\u7b26\u4e32\u683c\u5f0f\u5316 {0:.2f}\u8868\u793a\u5c06\u7b2c\u4e00\u4e2a\u53c2\u6570\u683c\u5f0f\u5316\u4e3a2\u4f4d\u5c0f\u6570\u7684\u6d6e\u70b9\u6570 {1:s}\u8868\u793a\u5c06\u7b2c\u4e8c\u4e2a\u53c2\u6570\u683c\u5f0f\u5316\u4e3a\u5b57\u7b26\u4e32 {2:d}\u8868\u793a\u5c06\u7b2c\u4e09\u4e2a\u53c2\u6570\u683c\u5f0f\u5316\u6574\u6570 \u53c2\u8003Python\u5b98\u65b9\u6587\u6863 https://docs.python.org/3.6/library/string.html template = ' {0:.2f} {1:s} are worth US$ {2:d} ' print ( template . format ( 4.5560 , 'Argentine Pesos' , 1 )) # 4.56 Argentine Pesos are worth US$1 \u65e5\u671f\u548c\u65f6\u95f4 from datetime import datetime , date , time dt = datetime ( 2011 , 10 , 29 , 20 , 30 , 21 ) print ( dt . day ) # 29 print ( dt . minute ) # 30 print ( dt . date ()) # 2011-10-29 print ( dt . time ()) # 20:30:21 print ( dt . replace ( minute = 0 , second = 0 )) # 2011-10-29 20:00:00 \u5c06\u5206\u949f\u3001\u79d2\u66ff\u6362\u4e3a0 print ( datetime . strptime ( '20091021' , '%Y%m %d ' )) # 2009-10-21 00:00:00 \u5b57\u7b26\u4e32\u53ef\u4ee5\u901a\u8fc7 strptime \u51fd\u6570\u8f6c\u6362\u4e3adatetime\u5bf9\u8c61 dt2 = datetime ( 2011 , 11 , 15 , 22 , 30 ) delta = dt2 - dt print ( delta ) # 17 days, 1:59:39 print ( dt + delta ) # 2011-11-15 22:30:00 range\u51fd\u6570\u8fd4\u56de\u4e00\u4e2a\u8fed\u4ee3\u5668\uff0c\u8be5\u8fed\u4ee3\u5668\u751f\u6210\u4e00\u4e2a\u7b49\u5dee\u6574\u6570\u5e8f\u5217\u3002 print ( range ( 10 )) # range(0, 10) print ( list ( range ( 10 ))) # [0, 1, 2, 3, 4, 5, 6, 7, 8, 9] print ( list ( range ( 0 , 20 , 2 ))) # [0, 2, 4, 6, 8, 10, 12, 14, 16, 18] 5. \u4e09\u5143\u8868\u8fbe\u5f0f \u00b6 value = true-expr if condition else false-expr x = 5 print ( 'non-negative' if x >= 0 else 'negative' ) # non-negative","title":"Python\u8bed\u8a00\u57fa\u7840"},{"location":"python/Foundation/ch01/#python","text":"","title":"Python\u8bed\u8a00\u57fa\u7840"},{"location":"python/Foundation/ch01/#1-python6","text":"6\u4e2aPython\u6570\u636e\u7c7b\u578b\uff1a \u6570\u503c\u578b\uff08number\uff09\uff1a\u8868\u793a\u6570\u636e\u7ec4\u6210\u4e3a\u6570\u5b57 \u6574\u578b\uff08int\uff09 \u5341\u8fdb\u5236 \u516b\u8fdb\u5236 \u5341\u516d\u8fdb\u5236 \u6d6e\u70b9\u578b\uff08float\uff09 \u5e03\u5c14\u578b\uff08bool\uff09 \u590d\u6570\u6027\uff08complex\uff09 \u5b57\u7b26\u578b\uff08string\uff09\uff1a\u8868\u793a\u6570\u636e\u7ec4\u6210\u662f\u5b57\u7b26 \u5217\u8868\uff08list\uff09\uff1a\u7528\u6765\u8868\u793a\u4e00\u7ec4\u6709\u5e8f\u5143\u7d20\uff0c\u540e\u671f\u6570\u636e\u53ef\u4ee5\u4fee\u6539 ['A','B','C'] \u5143\u7ec4\uff08tuple\uff09\uff1a\u7528\u6765\u8868\u793a\u4e00\u7ec4\u6709\u5e8f\u5143\u7d20\uff0c\u540e\u671f\u6570\u636e\u4e0d\u53ef\u4fee\u6539 ('A','B','C','1') \u96c6\u5408\uff08set\uff09\uff1a\u4e00\u7ec4\u6570\u636e\u65e0\u5e8f\u4e0d\u91cd\u590d\u5143\u7d20 set([1,2,3,4]) \u5b57\u5178\uff08dictionary\uff09\uff1a\u7528\u952e\u503c\u5bf9\u7684\u5f62\u5f0f\u4fdd\u5b58\u4e00\u7ec4\u5143\u7d20 {'A':7,'B':1,'C':9} \u53ef\u8fed\u4ee3\u5bf9\u8c61\uff08Iterable\uff09\uff1a An object capable of returning its members one at a time. Examples of iterables include all sequence types (such as list, str, and tuple) and some non-sequence types like dict, file objects, and objects of any classes you define with an iter() method or with a getitem() method that implements Sequence semantics. \u5e8f\u5217\uff08Sequence\uff09\uff1a An iterable which supports efficient element access using integer indices via the getitem() special method and defines a len() method that returns the length of the sequence. Some built-in sequence types are list, str, tuple, and bytes. Note that dict also supports getitem() and len(), but is considered a mapping rather than a sequence because the lookups use arbitrary immutable keys rather than integers. \u8fed\u4ee3\u5668\uff08Iterator\uff09\uff1a An object representing a stream of data. Repeated calls to the iterator\u2019s next() method (or passing it to the built-in function next()) return successive items in the stream. When no more data are available a StopIteration exception is raised instead. At this point, the iterator object is exhausted and any further calls to its next() method just raise StopIteration again. Iterators are required to have an iter() method that returns the iterator object itself so every iterator is also iterable and may be used in most places where other iterables are accepted. One notable exception is code which attempts multiple iteration passes. A container object (such as a list) produces a fresh new iterator each time you pass it to the iter() function or use it in a for loop. Attempting this with an iterator will just return the same exhausted iterator object used in the previous iteration pass, making it appear like an empty container. \u53ef\u53d8\u6570\u636e\uff08immutable\uff09 \u5217\u8868\uff08list\uff09 \u5b57\u5178\uff08dictionary\uff09 \u96c6\u5408\uff08set\uff09\u3002 \u4e0d\u53ef\u53d8\u6570\u636e\uff08immutable\uff09 \u6570\u5b57\uff08number\uff09 \u5b57\u7b26\uff08string\uff09 \u5143\u7ec4\uff08tuple\uff09 \u53ef\u8fed\u4ee3\uff08iterable\uff09 \u5b57\u7b26\uff08string\uff09 \u5143\u7ec4\uff08tuple\uff09 \u5217\u8868\uff08list\uff09 \u5b57\u5178\uff08dictionary\uff09 \u96c6\u5408\uff08set\uff09 \u5e8f\u5217 \u6709\u5e8f\u5e8f\u5217\uff1a\u5b57\u7b26\uff08string\uff09\uff0c\u5143\u7ec4\uff08tuple\uff09\uff0c\u5217\u8868\uff08list\uff09 \u65e0\u5e8f\u5e8f\u5217\uff1a\u5b57\u5178\uff08dictionary\uff09\uff0c\u96c6\u5408\uff08set\uff09 Python\u5e8f\u5217\u7c7b\u578b\u6700\u5e38\u89c1\u7684\u5206\u7c7b\u5c31\u662f\u53ef\u53d8\u548c\u4e0d\u53ef\u53d8\u5e8f\u5217\u3002\u4f46\u53e6\u5916\u4e00\u79cd\u5206\u7c7b\u65b9\u5f0f\u4e5f\u5f88\u6709\u7528\uff0c\u90a3\u5c31\u662f\u628a\u5b83\u4eec\u5206\u4e3a**\u6241\u5e73\u5e8f\u5217**\u548c**\u5bb9\u5668\u5e8f\u5217**\u3002\u524d\u8005\u7684\u4f53\u79ef\u66f4\u5c0f\u3001\u901f\u5ea6\u66f4\u5feb\u800c\u4e14\u7528\u8d77\u6765\u66f4\u7b80\u5355\uff0c\u4f46\u662f\u5b83\u53ea\u80fd\u4fdd\u5b58\u4e00\u4e9b\u539f\u5b50\u6027\u7684\u6570\u636e\uff0c\u6bd4\u5982\u6570\u5b57\u3001\u5b57\u7b26\u548c\u5b57\u8282\u3002\u5bb9\u5668\u5e8f\u5217\u5219\u6bd4\u8f83\u7075\u6d3b\uff0c\u4f46\u662f\u5f53\u5bb9\u5668\u5e8f\u5217\u9047\u5230\u53ef\u53d8\u5bf9\u8c61\u65f6\uff0c\u5c31\u9700\u8981\u683c\u5916\u5c0f\u5fc3\uff0c\u56e0\u4e3a\u8fd9\u79cd\u7ec4\u5408\u65f6\u5e38\u4f1a\u51fa\u73b0\u4e00\u4e9b\u201c\u610f\u5916\u201d\uff0c\u7279\u522b\u662f\u5e26\u5d4c\u5957\u7684\u6570\u636e\u7ed3\u6784\u51fa\u73b0\u65f6\uff0c\u66f4\u9700\u8981\u9a8c\u8bc1\u4ee3\u7801\u7684\u6b63\u786e\u6027\u3002 Python\u4e2d\u7684\u53d8\u91cf\u3001\u5e38\u91cf\u548c\u5b57\u9762\u91cf \u53d8\u91cf \u53d8\u91cf\u662f\u7528\u4e8e\u5728\u5185\u5b58\u4e2d\u5b58\u50a8\u6570\u636e\u7684\u547d\u540d\u4f4d\u7f6e\u3002\u53ef\u4ee5\u5c06\u53d8\u91cf\u89c6\u4e3a\u4fdd\u5b58\u6570\u636e\u7684\u5bb9\u5668\uff0c\u8fd9\u4e9b\u6570\u636e\u53ef\u4ee5\u5728\u540e\u9762\u7a0b\u5e8f\u4e2d\u8fdb\u884c\u66f4\u6539\u3002\u4f8b\u5982\uff1a number = 10 \u3002\u4ece\u4f8b\u5b50\u4e2d\u53ef\u4ee5\u770b\u5230\uff0cPython\u4f7f\u7528\u8d4b\u503c\u8fd0\u7b97\u7b26 = \u4e3a\u53d8\u91cf\u8d4b\u503c\u3002 \u5e38\u91cf \u5e38\u91cf\u4e5f\u662f\u4e00\u79cd\u53d8\u91cf\uff0c\u53ea\u662f\u5176\u503c\u4e00\u65e6\u8d4b\u4e88\u540e\u65e0\u6cd5\u66f4\u6539\u3002\u53ef\u4ee5\u5c06\u5e38\u91cf\u89c6\u4e3a\u4fdd\u5b58\u4e86\u4ee5\u540e\u65e0\u6cd5\u66f4\u6539\u7684\u4fe1\u606f\u7684\u5bb9\u5668\u3002 \u5728Python\u4e2d\uff0c\u5e38\u91cf\u901a\u5e38\u662f\u5728\u6a21\u5757\u4e2d\u58f0\u660e\u548c\u5206\u914d\u7684\u3002\u5728\u8fd9\u91cc\uff0c\u6a21\u5757\u662f\u4e00\u4e2a\u5305\u542b\u53d8\u91cf\uff0c\u51fd\u6570\u7b49\u7684\u65b0\u6587\u4ef6\uff0c\u8be5\u6587\u4ef6\u88ab\u5bfc\u5165\u5230\u4e3b\u6587\u4ef6\u4e2d\u3002\u5728\u6a21\u5757\u5185\u90e8\uff0c\u7528\u6240\u6709\u5927\u5199\u5b57\u6bcd\u5199\u7684\u5e38\u91cf\u548c\u4e0b\u5212\u7ebf\u5c06\u5355\u8bcd\u5206\u5f00\u3002\u5b9e\u9645\u4e0a\uff0c\u6211\u4eec\u4e0d\u5728Python\u4e2d\u4f7f\u7528\u5e38\u91cf\u3002\u7528\u5927\u5199\u5b57\u6bcd\u547d\u540d\u5b83\u4eec\u662f\u4e00\u79cd\u5c06\u5176\u4e0e\u666e\u901a\u53d8\u91cf\u5206\u5f00\u7684\u4e00\u79cd\u7ea6\u5b9a\uff0c\u4f46\u662f\uff0c\u5b9e\u9645\u4e0a\u5e76\u4e0d\u80fd\u963b\u6b62\u91cd\u65b0\u5206\u914d\u3002 \u5b57\u9762\u91cf\uff08literal\uff09 \u5b57\u9762\u91cf\u662f\u4ee5\u53d8\u91cf\u6216\u5e38\u91cf\u7ed9\u51fa\u7684\u539f\u59cb\u6570\u636e\uff08\u5176\u5b9e\u5c31\u662f\u6307\u53d8\u91cf\u7684\u5e38\u6570\u503c\uff0c\u5b57\u9762\u4e0a\u6240\u770b\u5230\u7684\u503c\uff09\u3002\u5728Python\u4e2d\u5b57\u9762\u91cf\u7c7b\u578b\u5982\u4e0b\uff1a \u6570\u5b57\u5b57\u9762\u91cf\u3002\u6570\u5b57\u5b57\u9762\u91cf\u662f\u4e0d\u53ef\u53d8\u7684\uff08\u4e0d\u53ef\u66f4\u6539\uff09\u3002\u6570\u5b57\u5b57\u9762\u91cf\u53ef\u4ee5\u5c5e\u4e8e3\u79cd\u4e0d\u540c\u7684\u6570\u503c\u7c7b\u578b\uff1aInteger\uff0cFloat \u548c Complex\u3002\u4f8b\u5982\uff1a float_1 = 10.5 \u662f\u5c5e\u4e8eFloat\u5b57\u9762\u91cf\u3002 \u5b57\u7b26\u4e32\u5b57\u9762\u91cf\u662f\u7531\u5f15\u53f7\u62ec\u8d77\u6765\u7684\u4e00\u7cfb\u5217\u5b57\u7b26\u3002\u6211\u4eec\u53ef\u4ee5\u5bf9\u5b57\u7b26\u4e32\u4f7f\u7528\u5355\u5f15\u53f7\uff0c\u53cc\u5f15\u53f7 \u6216 \u4e09\u5f15\u53f7\u3002\u5e76\u4e14\uff0c\u5b57\u7b26\u5b57\u9762\u91cf\u662f\u7528\u5355\u5f15\u53f7\u6216\u53cc\u5f15\u53f7\u5f15\u8d77\u6765\u7684\u5355\u4e2a\u5b57\u7b26\u3002\u4f8b\u5982\uff1a strings = \"This is Python\" \u3002 \u5e03\u5c14\u5b57\u9762\u91cf\u3002\u5e03\u5c14\u5b57\u9762\u91cf\u53ef\u4ee5\u5177\u6709\u4e24\u4e2a\u503c\u4e2d\u7684\u4efb\u4f55\u4e00\u4e2a\uff1a True \u6216 False \u3002\u4f8b\u5982\uff1a a = True + 4 \u3002 \u7279\u6b8a\u5b57\u9762\u91cf\u3002Python\u5305\u542b\u4e00\u4e2a\u7279\u6b8a\u5b57\u9762\u91cf\uff0c\u5373 None \u3002 \u5b57\u9762\u91cf\u96c6\u3002\u6709\u56db\u79cd\u4e0d\u540c\u7684\u5b57\u9762\u91cf\u96c6\u5408\uff1a\u5217\u8868\u5b57\u9762\u91cf\uff0c\u5143\u7ec4\u5b57\u9762\u91cf\uff0c\u5b57\u5178\u5b57\u9762\u91cf \u548c \u96c6\u5408\u5b57\u9762\u91cf\u3002","title":"1. Python\u6570\u636e\u7c7b\u578b\uff086\u4e2a\uff09"},{"location":"python/Foundation/ch01/#11-number","text":"\u4f8b\u5b50\uff1a a , b , c , d = 20 , 5.5 , True , 4 + 3 j print ( a , b , c , d ) # 20 5.5 True (4+3j) print ( type ( a ), type ( b ), type ( c ), type ( d )) # Python\u4e5f\u53ef\u4ee5\u8fd9\u6837\u8d4b\u503c\uff1a a = b = c = d = 1 print ( a , b , c , d ) # 1 1 1 1 \u8fdb\u5236\u8f6c\u6362\uff1a a = - 15 print ( f ' { a } \u5bf9\u5e94\u7684\u5341\u8fdb\u5236\u662f { a } , \u4e8c\u8fdb\u5236\u662f { a : b } , \u516b\u8fdb\u5236\u662f { a : o } , \u5341\u516d\u8fdb\u5236\u662f { a : x } ' )","title":"1.1 \u6570\u503c\u578b\uff08number\uff09"},{"location":"python/Foundation/ch01/#12-string","text":"\u5355\u5f15\u53f7\uff1a\u5185\u5bb9\u4e2d\u5305\u542b\u5927\u91cf\u53cc\u5f15\u53f7 \u53cc\u5f15\u53f7\uff1a\u5185\u5bb9\u4e2d\u5305\u542b\u5927\u91cf\u5355\u5f15\u53f7 \u4e09\u5f15\u53f7\uff1a\u5185\u5bb9\u4e2d\u540c\u65f6\u5305\u542b\u5355\u53cc\u5f15\u53f7\uff0c\u4e09\u4e2a\u5355\u5f15\u53f7\u6bd4\u8f83\u597d\u3002 a = 'string is \"special\"' b = \"string's value\" c = '''string's value is \"special\"''' d = \"\"\"string's context \"\"\"","title":"1.2 \u5b57\u7b26\u578b\uff08string\uff09"},{"location":"python/Foundation/ch01/#_1","text":"\u5b57\u7b26\u4e32\u5207\u7247 s = 'Python is very good' print ( s [ 2 : 4 ]) # th print ( s [ 5 ]) # n print ( s [ - 1 ]) # d print ( s [ - 3 : - 1 ]) # oo # \u975e\u8fed\u4ee3\u578b\uff0c\u4e0d\u53ef\u4fee\u6539 s [ 3 ] = 'b' # Traceback (most recent call last): # File \"\", line 1, in # TypeError: 'str' object does not support item assignment \u5b57\u7b26\u4e32\u5408\u5e76 print ( s + '!!!' ) # Python is very good!!! replace( a,b \u5c06\u5b57\u7b26\u4e32\u4e2d\u7684 a \u66ff\u6362\u6210 b print ( s . replace ( 'is' , 'we' )) # Python we very good find(str) : \u8fd4\u56de str \u51fa\u73b0\u7684\u7d22\u5f15\u4f4d\u7f6e\uff0c\u5982\u679c\u627e\u4e0d\u5230\u8be5\u503c\uff0c\u5219 find() \u65b9\u6cd5\u5c06\u8fd4\u56de -1\u3002 print ( s . find ( 'a' )) # -1 print ( s . find ( 's' )) # 8 str.index(a): \u67e5\u627e\u6307\u5b9a\u503c\u7684\u9996\u6b21\u51fa\u73b0\u3002\u5982\u679c\u627e\u4e0d\u5230\u8be5\u503c\uff0cindex() \u65b9\u6cd5\u5c06\u5f15\u53d1\u5f02\u5e38\u3002 print ( s . index ( 's' )) # 8 print ( s . index ( 'a' )) # Traceback (most recent call last): # File \"\", line 1, in # ValueError: substring not found str.count(a): \u7edf\u8ba1\u5b57\u7b26\u4e32\u4e2d a \u51fa\u73b0\u7684\u6b21\u6570 print ( s . count ( 'a' )) # 0 print ( s . count ( 'o' )) # 3 split: \u5bf9\u5b57\u7b26\u4e32\u8fdb\u884c\u5206\u5272\u3002\u5982\u679c\u53c2\u6570 num \u6709\u6307\u5b9a\u503c\uff0c\u5219\u5206\u9694 num+1 \u4e2a\u5b50\u5b57\u7b26\u4e32\u3002 # \u6309\u7a7a\u683c\u5206\u5272 print ( s . split ( ' ' )) # ['Python', 'is', 'very', 'good'] # \u6309\u7a7a\u683c\u5206\u5272\u62102\u4e2a\u5b50\u5b57\u7b26\u4e32 print ( s . split ( ' ' , 1 )) # ['Python', 'is very good'] strip: \u79fb\u9664\u5b57\u7b26\u4e32\u9996\u5c3e\u6307\u5b9a\u7684\u5b57\u7b26 \u9ed8\u8ba4\u4e3a\u7a7a\u683c\u3002\u8be5\u65b9\u6cd5\u53ea\u80fd\u5220\u9664\u5f00\u5934\u6216\u662f\u7ed3\u5c3e\u7684\u5b57\u7b26\uff0c\u4e0d\u80fd\u5220\u9664\u4e2d\u95f4\u90e8\u5206\u7684\u5b57\u7b26\u3002 print ( s ) # Python is very good # \u79fb\u9664\u672b\u5c3e\u5b57\u7b26d print ( s . strip ( 'd' )) # Python is very goo endswith (str): \u5224\u65ad\u5b57\u7b26\u4e32\u662f\u5426\u4ee5 str \u7ed3\u5c3e print ( s . endswith ( 'd' )) # True print ( s . endswith ( 'a' )) # False startswith (str): \u5224\u65ad\u5b57\u7b26\u4e32\u662f\u5426\u4ee5 str \u5f00\u5934 print ( s . startswith ( 'p' )) # False print ( s . startswith ( 'P' )) # True isdigit \uff1a\u5224\u65ad\u5b57\u7b26\u4e32\u662f\u5426\u5168\u4e3a\u6570\u5b57 d = '+86-123' print ( d . isdigit ()) # False d = '86123' print ( d . isdigit ()) # True isalpha \uff1a\u5224\u65ad\u5b57\u7b26\u4e32\u662f\u5426\u5168\u4e3a\u5b57\u6bcd b = 'Ab?' print ( b . isalpha ()) # False c = 'Ab' print () c . isalpha () # True","title":"\u5b57\u7b26\u4e32\u5e38\u7528\u65b9\u6cd5"},{"location":"python/Foundation/ch01/#_2","text":"\u4f7f\u7528\u53cd\u659c\u6760\\\u8868\u793a\u8f6c\u4e49\u5b57\u7b26\u3002\u53cd\u659c\u6760\u524d\u9762\u52a0r\u4ee3\u8868\u539f\u59cb\u5b57\u7b26\u3002 a = 'str \\n ing' print ( a ) # str # ing a = r 'str\\ning' print ( a ) # str\\ning \u8f6c\u4e49\u7b26 \u63cf\u8ff0 \\\u5728\u884c\u5c3e \u7eed\u884c\u7b26 \\\\ \u53cd\u659c\u6760\u7b26\u53f7\\ \\' \u5355\u5f15\u53f7 \\b \u9000\u683c(Backspace) \\000 \u7a7a \\n \u6362\u884c \\v \u7eb5\u5411\u5236\u8868\u7b26 \\t \u6a2a\u5411\u5236\u8868\u7b26 \\r \u56de\u8f66\uff0c\u5c06 \\r \u540e\u9762\u7684\u5185\u5bb9\u79fb\u5230\u5b57\u7b26\u4e32\u5f00\u5934\uff0c\u5e76\u9010\u4e00\u66ff\u6362\u5f00\u5934\u90e8\u5206\u7684\u5b57\u7b26\uff0c\u76f4\u81f3\u5c06 \\r \u540e\u9762\u7684\u5185\u5bb9\u5b8c\u5168\u66ff\u6362\u5b8c\u6210\u3002 \\yyy \u516b\u8fdb\u5236\u6570\uff0cy \u4ee3\u8868 0~7 \u7684\u5b57\u7b26 \\xyy \u5341\u516d\u8fdb\u5236\u6570\uff0c\u4ee5 \\x \u5f00\u5934\uff0cy \u4ee3\u8868\u7684\u5b57\u7b26","title":"\u8f6c\u4e49\u5b57\u7b26"},{"location":"python/Foundation/ch01/#_3","text":"\u5b57\u7b26\u4e32\u662f\u53ef\u8fed\u4ee3\u7684\u3002\u7d22\u5f15\u503c\u4ece0\u5f00\u59cb\uff0c-1\u4ee3\u8868\u4ece\u672b\u5c3e\u5f00\u59cb\u3002\u7d22\u5f15\u533a\u95f4\u662f\u5de6\u95ed\u53f3\u5f00\u3002 a = 'string is \"special\"' print ( a [ 2 : 4 ]) 'ri' print ( a [ - 4 : - 1 ]) # ial","title":"\u53ef\u8fed\u4ee3\u6027"},{"location":"python/Foundation/ch01/#f-string","text":"f-string\u662fPython3.6\u63a8\u51fa\u7684\u65b0\u529f\u80fd\u3002\u770b\u4e0b\u9762\u7684\u4f8b\u5b50\uff0c\u5bf9\u6bd4\u4f20\u7edf\u8868\u793a\u65b9\u6cd5\u548cf-string\u7684\u65b9\u6cd5\u3002 age = 32 name = 'Tom' fstring = f 'My name is { name } and I am { age } years old.' print ( fstring ) # My name is Tom and I am 32 years old. \u5728f-string\u4e2d\u4f7f\u7528\u8868\u8fbe\u5f0f\u3002 height = 2 base = 3 fstring = f 'The area of the triangle is { base * height / 2 } .' print ( fstring ) # The area of the triangle is 3.0. \u901a\u8fc7f-string\u5bf9\u5b57\u5178\u8fdb\u884c\u64cd\u4f5c\u3002 person1 = { 'name' : 'Tom' , 'age' : 20 , 'gender' : 'male' } person2 = { 'name' : 'Jerry' , 'age' : 20 , 'gender' : 'female' } # \u8bfb\u53d6\u5b57\u5178 fstring = f ' { person1 . get ( \"name\" ) } is { person1 . get ( \"age\" ) } and is { person1 . get ( \"ender\" ) } ' print ( fstring ) # Tom is 20 and is None # \u904d\u5386\u5b57\u5178 people = [ person1 , person2 ] for person in people : fstring = f ' { person . get ( \"name\" ) } is { person . get ( \"age\" ) } and is { person . get ( \"ender\" ) } ' print ( fstring ) # Tom is 20 and is None # Jerry is 20 and is None \u5728f-string\u4e2d\u4f7f\u7528\u6761\u4ef6\u3002 person1 = { 'name' : 'Tom' , 'age' : 20 , 'gender' : 'male' } person2 = { 'name' : 'Jerry' , 'age' : 20 , 'gender' : 'female' } people = [ person1 , person2 ] for person in people : fstring = f ' { \"She\" if person . get ( \"gender\" ) == \"female\" else \"He\" } is watching TV.' print ( fstring ) # He is watching TV. # She is watching TV. \u4f7f\u7528f-string\u683c\u5f0f\u5316\u8f93\u51fa\u3002 \u5de6\u5bf9\u9f50\uff1a< \u53f3\u5bf9\u9f50\uff1a> \u5c45\u4e2d\u5bf9\u9f50\uff1a^ print ( f ' { \"apple\" : >30 } ' ) print ( f ' { \"apple\" : ^30 } ' ) print ( f ' { \"apple\" : <30 } ' ) # apple # apple # apple \u4f7f\u7528f-string\u683c\u5f0f\u5316\u6570\u5b57\u3002 number = 0.9124325345 # \u767e\u5206\u6bd4 fstring = f 'Percentage format for number with two decimal places: { number : .2% } ' print ( fstring ) # Percentage format for number with two decimal places: 91.24% # \u4fdd\u7559\u5c0f\u6570\u70b9\u540e3\u4f4d fstring = f 'Fixed point format for number with three decimal places: { number : .3f } ' print ( fstring ) # Fixed point format for number with three decimal places: 0.912 # \u79d1\u5b66\u8ba1\u6570\u6cd5\u8868\u793a fstring = f 'Exponent format for number: { number : e } ' print ( fstring ) # Exponent format for number: 9.124325e-01 # \u5e26\u8d27\u5e01\u7b26\u53f7 number = 123456.78921 fstring = f 'Currency format for number with two decimal places: $ { number : .2f } ' print ( fstring ) # Currency format for number with two decimal places: $123456.79 # \u5e26\u8d27\u5e01\u7b26\u53f7\u548c\u5343\u5206\u4f4d number = 123456.78921 fstring = f 'Currency format for number with two decimal places and comma seperators: $ { number : ,.2f } ' print ( fstring ) # Currency format for number with two decimal places and comma seperators: $123,456.79 # \u8f93\u51fa\u6570\u503c\u5e26\u6b63\u8d1f\u7b26\u5408 numbers = [ 1 , - 3 , 5 ] for number in numbers : fstring = f 'The number is { number : + } ' print ( fstring ) # The number is +1 # The number is -3 # The number is +5 # Debug\u8c03\u8bd5 number = 2 print ( f ' { number = } ' ) # number = 2","title":"f-string"},{"location":"python/Foundation/ch01/#13-list","text":"\u5217\u8868\u662f Python \u5185\u7f6e\u7684\u4e00\u79cd\u6570\u636e\u7ed3\u6784\uff0c\u662f\u4e00\u79cd\u6709\u5e8f\u7684\u96c6\u5408\uff0c\u7528\u6765\u5b58\u50a8\u4e00\u8fde\u4e32\u5143\u7d20\u7684\u5bb9\u5668\u3002\u5217\u8868\u4e2d\u5143\u7d20\u7c7b\u578b\u53ef\u4ee5\u4e0d\u76f8\u540c\uff0c\u5b83\u652f\u6301\u6570\u5b57\u3001\u5b57\u7b26\u4e32\u7b49\u3002 \u5217\u8868\u7684\u6bcf\u4e2a\u503c\u90fd\u6709\u5bf9\u5e94\u7684\u7d22\u5f15\u503c\uff0c\u7d22\u5f15\u503c\u4ece0\u5f00\u59cb\u3002 \u5217\u8868\u5207\u7247\uff1a \u4f7f\u7528\u5207\u7247\u7b26\u53f7\u53ef\u4ee5\u5bf9\u5927\u591a\u6570\u5e8f\u5217\u7c7b\u578b\u9009\u53d6\u5176\u5b50\u96c6\u3002 \u8d77\u59cb\u4f4d\u7f6estart\u7684\u7d22\u5f15\u662f\u5305\u542b\u7684\uff0c\u800c\u7ed3\u675f\u4f4d\u7f6estop\u7684\u7d22\u5f15\u5e76\u4e0d\u5305\u542b\uff08\u5de6\u95ed\u53f3\u5f00\uff09\u3002 \u6b65\u8fdb\u503cstep\u53ef\u4ee5\u5728\u7b2c\u4e8c\u4e2a\u5192\u53f7\u540e\u9762\u4f7f\u7528\uff0c\u610f\u601d\u662f\u6bcf\u9694\u591a\u5c11\u4e2a\u6570\u53d6\u4e00\u4e2a\u503c \u3002 color = [ 'red' , 'green' , 'blue' , 'yellow' , 'white' , 'black' ] # \u4ece0\u5f00\u59cb\u7edf\u8ba1\uff0c\u8bfb\u53d6\u7b2c1\uff0c2\u4f4d print ( color [ 1 : 3 ]) # ['green', 'blue'] # \u4ece0\u5f00\u59cb\u7edf\u8ba1\uff0c\u8bfb\u53d6\u4ece\u7b2c1\u4f4d\u5230\u5012\u6570\u7b2c3\u4f4d print ( color [ 1 : - 2 ]) # ['green', 'blue', 'yellow'] # \u4ece0\u5f00\u59cb\u7edf\u8ba1\uff0c\u8bfb\u53d6\u4ece\u5012\u6570\u7b2c4\u4f4d\u5230\u5012\u6570\u7b2c3\u4f4d print ( color [ - 4 : - 2 ]) # ['blue', 'yellow'] # \u5982\u679c\u5199\u6210\u4e0b\u9762\u8fd9\u6837\uff0c\u5219\u65e0\u8f93\u51fa\u3002 print ( color [ - 2 : - 4 ]) # [] print ( color [:: 2 ]) # ['red', 'blue', 'white'] \u5bf9\u4e8e\u7c7b\u4f3c\u4e0b\u9762 invoice \u683c\u5f0f\u7684\u7eaf\u6587\u672c\u89e3\u6790\uff0c\u4f7f\u7528\u6709\u540d\u5b57\u7684\u5207\u7247\u6bd4\u7528\u4e0a\u9762\u6240\u5217\u4e3e\u7684\u786c\u7f16\u7801\u7684\u6570\u5b57\u533a\u95f4\u8981\u65b9\u4fbf\u5f97\u591a\u3002 invoice = \"\"\" 0 6 40 52 55 1909 Primoroni PiBrella $17.50 3 $52.50 1489 6mm Tactile Switch x20 $4.19 2 $9.90 1510 Panavise JR.-PV-201 $28.00 1 $28.00 1601 PiTFT Mini Kit 320x240 $34.95 1 $34.95 \"\"\" SKU = slice ( 0 , 6 ) DESCRIPTION = slice ( 6 , 40 ) UNIT_PRICE = slice ( 40 , 52 ) QUANTITY = slice ( 52 , 55 ) ITEM_TOTAL = slice ( 55 , None ) line_items = invoice . split ( ' \\n ' )[ 2 :] # \u6309\u4e0a\u9762invoice\u7684\u683c\u5f0f\uff0c\u7b2c0\u548c1\u884c\u820d\u5f03 for item in line_items : print ( item [ UNIT_PRICE ], item [ DESCRIPTION ]) # $17.50 Primoroni PiBrella # $4.19 6mm Tactile Switch x20 # $28.00 Panavise JR.-PV-201 # $34.95 PiTFT Mini Kit 320x240 Python\u5185\u7f6e\u7684\u5e8f\u5217\u7c7b\u578b\u90fd\u662f\u4e00\u7ef4\u7684\uff0c\u56e0\u6b64\u5b83\u4eec\u53ea\u652f\u6301\u5355\u4e00\u7684\u7d22\u5f15\uff0c\u6210\u5bf9\u51fa\u73b0\u7684\u7d22\u5f15\u662f\u6ca1\u6709\u7528\u7684\u3002 **\u7701\u7565\uff08ellipsis\uff09**\u7684\u6b63\u786e\u4e66\u5199\u65b9\u6cd5\u662f\u4e09\u4e2a\u82f1\u8bed\u53e5\u53f7\uff08...\uff09\uff0c\u800c\u4e0d\u662fUnicdoe\u7801\u4f4dU+2026\u8868\u793a\u7684\u534a\u4e2a\u7701\u7565\u53f7\uff08...\uff09\u3002 \u7701\u7565\u5728Python\u89e3\u6790\u5668\u773c\u91cc\u662f\u4e00\u4e2a\u7b26\u53f7\uff0c\u800c\u5b9e\u9645\u4e0a\u5b83\u662f Ellipsis \u5bf9\u8c61\u7684\u522b\u540d\uff0c\u800c Ellipsis \u5bf9\u8c61\u53c8\u662f ellipsis \u7c7b\u7684\u5355\u4e00\u5b9e\u4f8b\u3002 \u5b83\u53ef\u4ee5\u5f53\u4f5c\u5207\u7247\u89c4\u8303\u7684\u4e00\u90e8\u5206\uff0c\u4e5f\u53ef\u4ee5\u7528\u5728\u51fd\u6570\u7684\u53c2\u6570\u6e05\u5355\u4e2d\uff0c\u6bd4\u5982 f(a, ..., z) \uff0c\u6216 a[i:...] \u3002 \u5728NumPy\u4e2d\uff0c ... \u7528\u4f5c\u591a\u7ef4\u6570\u7ec4\u5207\u7247\u7684\u5feb\u6377\u65b9\u5f0f\u3002\u5982\u679c `x\u662f\u56db\u7ef4\u6570\u7ec4\uff0c\u90a3\u4e48 x[i, ...] \u5c31\u662f x[i, :, :, :]`\u7684\u7f29\u5199\u3002\u5982\u679c\u60f3\u4e86\u89e3\u66f4\u591a\uff0c\u8bf7\u53c2\u89c1\u201cTentative NumPy Tutorial\u201d\u3002 \u5217\u8868\u5e38\u7528\u65b9\u6cd5 \u65b9\u6cd5\u540d\u79f0 \u4f5c\u7528 a.index() \u8fd4\u56dea\u4e2d\u9996\u4e2a\u5339\u914d\u9879\u7684\u4f4d\u7f6e a.pop() \u5220\u9664\u6307\u5b9a\u4f4d\u7f6e\u7684\u5143\u7d20 a.insert() \u5411\u6307\u5b9a\u4f4d\u7f6e\u63d2\u5165\u5143\u7d20 a.reverse() \u53cd\u5411\u6392\u5e8f a.append() \u5411\u672b\u5c3e\u6dfb\u52a0\u5143\u7d20 a.sort() \u5bf9\u5217\u8868\u8fdb\u884c\u6392\u5e8f a.remove() \u5220\u9664\u9996\u4e2a\u5339\u914d\u9879\u7684\u5143\u7d20 a.extend() \u5c06\u4e00\u4e2a\u5217\u8868\u6269\u5c55\u81f3\u53e6\u4e00\u4e2a\u5217\u8868 a.count() \u7edf\u8ba1\u67d0\u4e2a\u5143\u7d20\u51fa\u73b0\u7684\u6b21\u6570 \u521b\u5efa\u5217\u8868list a = [ 1 , 2 , 3 , 4 , 5 ] print ( a ) # [1, 2, 3, 4, 5] b = list ( '12345' ) print ( b ) # ['1', '2', '3', '4', '5'] c = list ( 12345 ) # Traceback (most recent call last): # File \"\", line 1, in # TypeError: 'int' object is not iterable \u5217\u8868\u5207\u7247\uff08\u4ece0\u5f00\u59cb\uff0c\u5de6\u95ed\u53f3\u5f00\uff09\uff1a print ( a [ 2 : 3 ]) # [3] print ( a [: 3 ]) # [1, 2, 3] print ( a [:: - 1 ]) # \u5012\u5e8f # [5, 4, 3, 2, 1] print ( a [::]) # [1, 2, 3, 4, 5] print ( a [:: 1 ]) [ 1 , 2 , 3 , 4 , 5 ] \u5217\u8868\u662f\u53ef\u4fee\u6539\u7684\uff1a print ( a [ 1 ]) # 2 a [ 1 ] = 'one' print ( a ) @ [ 1 , 'one' , 3 , 4 , 5 ] \u5217\u8868\u8ffd\u52a0\u548c\u63d2\u5165\u3002insert\u4e0eappend\u76f8\u6bd4\uff0c\u8ba1\u7b97\u4ee3\u4ef7\u66f4\u9ad8\u3002\u56e0\u4e3a\u5b50\u5e8f\u5217\u5143\u7d20\u9700\u8981\u5728\u5185\u90e8\u79fb\u52a8\u4e3a\u65b0\u5143\u7d20\u63d0\u4f9b\u7a7a\u95f4\u3002 a . append ( 6 ) # \u6ce8\u610f\uff0c\u76f4\u63a5\u4fee\u6539\u539f\u5217\u8868\uff0c\u4e0d\u662f\u521b\u5efa\u526f\u672c\u3002 print ( a ) # [1, 'one', 3, 4, 5, 6] a . extend ([ 7 , 8 , 9 ]) print ( a ) # [1, 'one', 3, 4, 5, 6, 7, 8, 9] a . insert ( 0 , 'Italy' ) print ( a ) # ['Italy', 1, 3, 5, 6, 7, 8] \u5217\u8868\u5220\u9664\u5143\u7d20\uff0c\u9ed8\u8ba4\u5220\u9664\u6700\u540e\u4e00\u4e2a\u3002insert\u7684\u53cd\u64cd\u4f5c\u662fpop\u3002 a . pop () # 9 print ( a ) # [1, 'one', 3, 4, 5, 6, 7, 8] a . pop ( 3 ) # 4 print ( a ) # [1, 'one', 3, 5, 6, 7, 8] \u5220\u9664\u5217\u8868\u4e2d\u67d0\u4e2a\u5143\u7d20\u3002 print ( a [ 1 ]) # one del a [ 1 ] print ( a ) [ 1 , 3 , 5 , 6 , 7 , 8 ] \u5220\u9664\u5217\u8868\u4e2d\u67d0\u4e2a\u5143\u7d20\u3002remove\u65b9\u6cd5\u4f1a\u5b9a\u4f4d\u7b2c\u4e00\u4e2a\u7b26\u5408\u8981\u6c42\u7684\u503c\u5e76\u79fb\u9664 a . remove ( 'Italy' ) print ( a ) # [1, 3, 5, 6, 7, 8] \u7edf\u8ba1\u67d0\u4e2a\u5143\u7d20\u51fa\u73b0\u7684\u6b21\u6570\u3002 print ( a . count ( 1 )) # 1 \u8fd4\u56de\u5217\u8868\u4e2d\u5339\u914d\u9879\u7684\u7d22\u5f15\u4f4d\u7f6e\u3002\u5339\u914d\u4e0d\u5230\u629b\u51fa\u5f02\u5e38\u3002 print ( a . index ( 2 )) # Traceback (most recent call last): # File \"\", line 1, in # ValueError: 2 is not in list print ( a . index ( 3 )) # 1 \u5224\u65ad\u5143\u7d20\u662f\u5426\u5b58\u5728\u4e8e\u5217\u8868\u3002 print ( 3 in a ) # True print ( '3' in a ) # False \u53cd\u5411\u8f93\u51fa\u5217\u8868\u3002 a . reverse () print ( a ) # [8, 7, 6, 5, 3, 1] \u53d6\u5217\u8868\u4e2d\u6700\u5927\u503c\u3001\u6700\u5c0f\u503c\u3002 print ( min ( a )) # 1 print ( max ( a )) # 78 \u8ba1\u7b97\u5217\u8868\u957f\u5ea6\u3002 print ( len ( a )) # 6 \u5217\u8868\u6269\u5c55\uff1a a = [ 1 , 2 , 3 ] b = [ 4 , 5 , 6 ] print ( a + b ) # [1, 2, 3, 4, 5, 6] a . extend ( b ) # a\u5217\u8868\u88ab\u4fee\u6539 print ( a ) # [1, 2, 3, 4, 5, 6] print ( b ) # [4, 5, 6] \u4f7f\u7528extend\u6dfb\u52a0\u5143\u7d20\u6bd4\u4f7f\u7528\u52a0\u53f7\uff08+\uff09\u8fde\u63a5\u6548\u7387\u66f4\u9ad8\u3002\u56e0\u4e3a\u4f7f\u7528\u52a0\u53f7\uff08+\uff09\u8fde\u63a5\u8fc7\u7a0b\u4e2d\u521b\u5efa\u4e86\u65b0\u5217\u8868\uff0c\u5e76\u4e14\u8fd8\u8981\u590d\u5236\u5bf9\u8c61\u3002 a_list = [ 4 , None , 'foo' ] b_list = [ 7 , 8 , ( 2 , 3 )] print ( a_list + b_list ) # [4, None, 'foo', 7, 8, (2, 3)] \u4f7f\u7528+\u53f7\u8fde\u63a5 a_list . extend ( b_list ) print ( a_list ) # [4, None, 'foo', 7, 8, (2, 3)] Python\u7684\u4e00\u4e2a\u60ef\u4f8b\uff1a\u5982\u679c\u4e00\u4e2a\u51fd\u6570\u6216\u8005\u65b9\u6cd5\u5bf9\u5bf9\u8c61\u8fdb\u884c\u7684\u662f\u5c31\u5730\u6539\u52a8\uff0c\u90a3\u5b83\u5c31\u5e94\u8be5\u8fd4\u56deNone\uff0c\u597d\u8ba9\u8c03\u7528\u8005\u77e5\u9053\u4f20\u5165\u7684\u53c2\u6570\u53d1\u751f\u4e86\u53d8\u52a8\uff0c\u800c\u4e14\u5e76\u672a\u4ea7\u751f\u65b0\u7684\u5bf9\u8c61\u3002 \u4e0b\u9762\u662f\u6392\u5e8f\u7684\u4f8b\u5b50 list.sort() \u548c sorted(list) \u7684\u533a\u522b\u3002 list1 = [ '1' , 'one' , '3' , 'Four' , '5' , 'two' , 'apple' , '8' , '9' ] print ( list1 ) # ['1', 'one', '3', 'Four', '5', 'two', 'apple', '8', '9'] # \u4e0b\u9762\u7684\u64cd\u4f5c\u4e0d\u6539\u53d8\u539f\u5217\u8868 print ( sorted ( list1 )) # ['1', '3', '5', '8', '9', 'Four', 'apple', 'one', 'two'] print ( sorted ( list1 , reverse = True )) # ['two', 'one', 'apple', 'Four', '9', '8', '5', '3', '1'] print ( sorted ( list1 , key = len )) # ['1', '3', '5', '8', '9', 'one', 'two', 'Four', 'apple'] print ( list1 ) # ['1', 'one', '3', 'Four', '5', 'two', 'apple', '8', '9'] # \u4e0b\u9762\u7684\u64cd\u4f5c\u76f4\u63a5\u4fee\u6539\u539f\u5217\u8868\uff0c\u8fd4\u56de\u503c\u662fNone print ( list1 . sort ()) # None print ( list1 ) # ['1', '3', '5', '8', '9', 'Four', 'apple', 'one', 'two'] \u5217\u8868\u590d\u5236\uff0c + \u548c * \u7684\u64cd\u4f5c\u90fd\u662f\u4e0d\u4fee\u6539\u539f\u6709\u7684\u64cd\u4f5c\u5bf9\u8c61\uff0c\u800c\u662f\u6784\u5efa\u4e00\u4e2a\u5168\u65b0\u7684\u5217\u8868\u3002 c = list ( 'Python' ) print ( a + c ) # [1, 2, 3, 4, 5, 6, 'P', 'y', 't', 'h', 'o', 'n'] print ( a * 3 ) # [1, 2, 3, 4, 5, 6, 1, 2, 3, 4, 5, 6, 1, 2, 3, 4, 5, 6] \u5982\u679c\u5728 a * n \u8fd9\u4e2a\u8bed\u53e5\u4e2d\uff0c\u5e8f\u5217 a \u91cc\u7684\u5143\u7d20\u662f\u5bf9\u5176\u4ed6\u53ef\u53d8\u5bf9\u8c61\u7684\u5f15\u7528\u7684\u8bdd\uff0c\u5c31\u9700\u8981\u683c\u5916\u6ce8\u610f\u4e86\uff0c\u56e0\u4e3a\u8fd9\u4e2a\u5f0f\u5b50\u7684\u7ed3\u679c\u53ef\u80fd\u4f1a\u51fa\u4e4e\u610f\u6599\u3002 \u6bd4\u5982\uff0c\u6211\u4eec\u60f3\u7528 my_list=[[]] * 3 \u6765\u521d\u59cb\u5316\u4e00\u4e2a\u7531\u5217\u8868\u7ec4\u6210\u7684\u5217\u8868\uff0c\u4f46\u662f\u6211\u4eec\u5b9e\u9645\u5f97\u5230\u7684\u5217\u8868\u91cc\u5305\u542b\u76843\u4e2a\u5143\u7d20\u5176\u5b9e\u662f3\u4e2a\u5f15\u7528\uff0c\u800c\u4e14\u8fd93\u4e2a\u5f15\u7528\u6307\u5411\u7684\u90fd\u662f*\u540c\u4e00\u4e2a*\u5217\u8868\u3002\u770b\u4e0b\u9762\u4f8b\u5b50\u3002 # \u505a\u6cd51 board = [[ '_' ] * 3 for i in range ( 3 )] print ( board ) # [['_', '_', '_'], ['_', '_', '_'], ['_', '_', '_']] board [ 1 ][ 2 ] = 'X' print ( board ) # [['_', '_', '_'], ['_', '_', 'X'], ['_', '_', '_']] # \u505a\u6cd52 board = [[ '_' ] * 3 ] * 3 print ( board ) # [['_', '_', '_'], ['_', '_', '_'], ['_', '_', '_']] board [ 1 ][ 2 ] = 'X' print ( board ) # [['_', '_', 'X'], ['_', '_', 'X'], ['_', '_', 'X']] \u4e0b\u9762\u4e5f\u662f\u540c\u6837\u7684\u95ee\u9898\u3002 # \u65b9\u6cd51 row = [ '_' ] * 3 board = [] for i in range ( 3 ): board . append ( row ) print ( board ) # [['_', '_', '_'], ['_', '_', '_'], ['_', '_', '_']] board [ 2 ][ 0 ] = 'X' print ( board ) # [['X', '_', '_'], ['X', '_', '_'], ['X', '_', '_']] # \u65b9\u6cd52 row = [] board = [] for i in range ( 3 ): row = [ '_' ] * 3 board . append ( row ) print ( board ) # [['_', '_', '_'], ['_', '_', '_'], ['_', '_', '_']] board [ 2 ][ 0 ] = 'X' print ( board ) # [['_', '_', '_'], ['_', '_', '_'], ['X', '_', '_']] \u53cc\u7aef\u961f\u5217collections.deque \uff0c\u53ef\u4ee5\u6ee1\u8db3\u5217\u8868\u5934\u5c3e\u90e8\u90fd\u589e\u52a0\u7684\u8981\u6c42\u3002 deque() \u4e2d maxlen \u662f\u4e00\u4e2a\u53ef\u9009\u53c2\u6570\uff0c\u4ee3\u8868\u8fd9\u4e2a\u961f\u5217\u53ef\u4ee5\u5bb9\u7eb3\u7684\u5143\u7d20\u7684\u6570\u91cf\uff0c\u800c\u4e14\u4e00\u65e6\u8bbe\u5b9a\uff0c\u8fd9\u4e2a\u5c5e\u6027\u5c31\u4e0d\u80fd\u4fee\u6539\u4e86\u3002 \u5f53\u8bd5\u56fe\u5bf9\u4e00\u4e2a\u5df2\u6ee1 len(d)==d.maxlen \u7684\u961f\u5217\u505a\u5934\u90e8\u6dfb\u52a0\u64cd\u4f5c\u7684\u65f6\u5019\uff0c\u5b83\u5c3e\u90e8\u7684\u5143\u7d20\u4f1a\u88ab\u5220\u9664\u6389\u3002 extendleft(iter) \u65b9\u6cd5\u4f1a\u628a\u8fed\u4ee3\u5668\u91cc\u7684\u5143\u7d20\u9010\u4e2a\u6dfb\u52a0\u5230\u53cc\u5411\u961f\u5217\u7684\u5de6\u8fb9\uff0c\u56e0\u6b64\u8fed\u4ee3\u5668\u91cc\u7684\u5143\u7d20\u4f1a\u9006\u5e8f\u51fa\u73b0\u5728\u961f\u5217\u91cc\u3002 \u961f\u5217\u7684\u65cb\u8f6c\u64cd\u4f5c rotate \u63a5\u53d7\u4e00\u4e2a\u53c2\u6570n\uff0c\u5f53n > 0\u65f6\uff0c\u961f\u5217\u7684\u6700\u53f3\u8fb9\u7684n\u4e2a\u5143\u7d20\u4f1a\u88ab\u79fb\u52a8\u5230\u961f\u5217\u7684\u5de6\u8fb9\u3002\u5f53n < 0\u65f6\uff0c\u6700\u5de6\u8fb9\u7684n\u4e2a\u5143\u7d20\u4f1a\u88ab\u79fb\u52a8\u5230\u53f3\u8fb9\u3002 from collections import deque d = deque ([ 1 , 2 , 3 ]) print ( d ) # deque([1, 2, 3]) # \u6ce8\u610f\u63d2\u5165\u987a\u5e8f d . extendleft ([ 'a' , 'b' , 'c' ]) print ( d ) # deque(['c', 'b', 'a', 1, 2, 3]) print ( len ( d )) # 6 print ( d [ - 2 ]) # 2 # \u7edf\u8ba1\u5b57\u7b26a\u51fa\u73b0\u7684\u6b21\u6570 print ( d . count ( 'a' )) # 1 # \u8fd4\u56de\u5b57\u7b26a\u7684\u7d22\u5f15\u503c print ( d . index ( 'a' )) # 2 # \u7b2c0\u4f4d\u63d2\u5165\u6570\u5b571\uff0c\u5176\u4f59\u987a\u79fb d . insert ( 0 , 1 ) print ( d ) # deque([1, 'c', 'b', 'a', 1, 2, 3]) # \u628a\u53f3\u8fb92\u4e2a\u5143\u7d20\u653e\u5230\u5de6\u8fb9\uff0c\u6ce8\u610f\u987a\u5e8f\uff0c\u548cextendleft\u4e0d\u4e00\u6837 d . rotate ( 2 ) print ( d ) # deque([2, 3, 1, 'c', 'b', 'a', 1]) d . rotate ( - 2 ) print ( d ) # deque([1, 'c', 'b', 'a', 1, 2, 3]) \u4e0b\u8868\u603b\u7ed3\u4e86\u5217\u8868\u548c\u53cc\u5411\u961f\u5217\u7684\u65b9\u6cd5\uff08\u4e0d\u5305\u62ec\u7531\u5bf9\u8c61\u5b9e\u73b0\u7684\u65b9\u6cd5\uff09\u3002 \u5217\u8868\u6392\u5e8f\u3002\u6392\u5e8f\u5bf9\u5217\u8868\u5143\u7d20\u7684\u6570\u636e\u7c7b\u578b\u662f\u6709\u8981\u6c42\u7684\u3002 a_list = [ 4 , None , 'foo' , 7 , 8 , ( 2 , 3 )] a_list . sort () # Traceback (most recent call last): # File \"\", line 1, in # TypeError: '<' not supported between instances of 'NoneType' and 'int' b_list = [ 7 , 8 , ( 2 , 3 )] b_list . sort () # Traceback (most recent call last): # File \"\", line 1, in # TypeError: '<' not supported between instances of 'tuple' and 'int' a_list = [ 7 , 2 , 5 , 1 , 3 ] a_list . sort () # \u6309\u6570\u503c\u5927\u5c0f\u6392\u5e8f print ( a_list ) # [1, 2, 3, 5, 7] b_list = [ 'saw' , 'small' , 'He' , 'foxes' , 'six' ] b_list . sort ( key = len ) # \u901a\u8fc7\u5b57\u7b26\u4e32\u7684\u957f\u5ea6\u8fdb\u884c\u6392\u5e8f print ( b_list ) # ['He', 'saw', 'six', 'small', 'foxes'] \u5217\u8868\u4e8c\u5206\u641c\u7d22\u548c\u5df2\u6392\u5e8f\u5217\u8868\u7684\u7ef4\u62a4 bisect \u8fd4\u56de\u8981\u63d2\u5165\u5143\u7d20\u5728\u5217\u8868\u4e2d\u7684\u4e0b\u6807\u3002\u5047\u5b9a\u5217\u8868\u662f\u6709\u5e8f\u7684\u3002 bisect_left \u4e0e bisect \u7c7b\u4f3c\uff0c\u53ea\u4e0d\u8fc7\u5176\u9ed8\u8ba4\u5c06\u5143\u7d20\u63d2\u5230\u5de6\u8fb9\uff0c\u6240\u4ee5\u8fd4\u56de\u7684\u662f\u63d2\u5165\u5230\u5de6\u8fb9\u7684\u4e0b\u6807 bisect_right\u4e0e bisect_left \u76f8\u53cd\u3002 \u4ee5\u4e0a\u65b9\u6cd5\u82e5\u5217\u8868\u65e0\u5e8f\uff0c\u90a3\u4e48\u4f1a\u8fd4\u56de\u63d2\u5165\u5230\u5217\u8868\u6700\u540e\u4e00\u4e2a\u5408\u9002\u7684\u4f4d\u7f6e\u3002 insort \u4f1a\u5728\u5217\u8868\u4e2d\u63d2\u5165\u5143\u7d20\u5230\u6b63\u786e\u4f4d\u7f6e\uff0c\u5047\u5b9a\u5217\u8868\u6709\u5e8f\u3002\u5982\u679c\u5217\u8868\u65e0\u5e8f\uff0c\u90a3\u4e48\u4f1a\u8fd4\u56de\u7a7a\u3002\u9ed8\u8ba4\u63d2\u5165\u5230\u53f3\u8fb9\u3002 insort_left \u548cinsort_right \u7c7b\u4f3c\u3002 import bisect c = [ 1 , 2 , 3 , 4 , 7 ] print ( bisect . bisect ( c , 2 )) # 2 bisect\u4f1a\u627e\u5230\u7b2c\u4e00\u4e2a2,\u5e76\u628a\u65b0\u76842\u63d2\u5165\u5b83\u540e\u9762 bisect . insort ( c , 2 ) # [1, 2, 2, 3, 4, 7] print ( bisect . bisect ( c , 5 )) # 5 bisect\u4f1a\u627e\u5230\u7b2c\u4e00\u4e2a4,\u5e76\u628a\u65b0\u76845\u63d2\u5165\u5b83\u540e\u9762 bisect . insort ( c , 5 ) print ( bisect . bisect ( c , 6 )) # 6 bisect\u4f1a\u627e\u5230\u7b2c\u4e00\u4e2a5,\u5e76\u628a\u65b0\u76846\u63d2\u5165\u5b83\u540e\u9762 bisect . insort ( c , 6 ) print ( c ) # [1, 2, 2, 3, 4, 5, 6, 7] bisect\u53ef\u4ee5\u7528\u6765\u5efa\u7acb\u4e00\u4e2a\u7528\u6570\u5b57\u4f5c\u4e3a\u7d22\u5f15\u7684\u67e5\u8be2\u8868\u683c\uff0c\u5982\u4e0b\u4f8b\uff0c\u628a\u5206\u6570\u548c\u6210\u7ee9\u5bf9\u5e94\u8d77\u6765\uff0c\u6839\u636e\u4e00\u4e2a\u5206\u6570\uff0c\u627e\u5230\u5b83\u6240\u5bf9\u5e94\u7684\u6210\u7ee9\u3002 import bisect def grade ( score , breakpoints = [ 60 , 70 , 80 , 90 ], grades = 'FDCBA' ): i = bisect . bisect ( breakpoints , score ) return grades [ i ] [ grade ( score ) for score in [ 15 , 26 , 31 , 62 , 79 , 85 ]] # ['F', 'F', 'F', 'D', 'C', 'B'] \u7528bisect.insort\u63d2\u5165\u65b0\u5143\u7d20\uff0c\u5e76\u80fd\u4fdd\u6301seq\u7684\u5347\u5e8f\u987a\u5e8f\u3002 import bisect import random size = 7 random . seed ( 1729 ) my_list = [] for i in range ( size ): new_item = random . randrange ( size * 2 ) bisect . insort ( my_list , new_item ) print ( f ' { new_item : 2d } :--> { my_list } ' ) # 10 :--> [10] # 0 :--> [0, 10] # 6 :--> [0, 6, 10] # 8 :--> [0, 6, 8, 10] # 7 :--> [0, 6, 7, 8, 10] # 2 :--> [0, 2, 6, 7, 8, 10] # 10 :--> [0, 2, 6, 7, 8, 10, 10]","title":"1.3 \u5217\u8868\uff08list\uff09"},{"location":"python/Foundation/ch01/#14-dictionary","text":"\u5b57\u5178(dict)\u662f\u4f7f\u7528\u952e-\u503c\uff08key-value\uff09\u5b58\u50a8\uff0c\u952e\u662f\u4e0d\u53ef\u53d8\u5bf9\u8c61\uff0c\u4e14\u4e0d\u5141\u8bb8\u91cd\u590d\u3002 dict\uff08\u5b57\u5178\uff09\u66f4\u4e3a\u5e38\u7528\u7684\u540d\u5b57\u662f\u54c8\u5e0c\u8868\u6216\u8005\u662f\u5173\u8054\u6570\u7ec4\u3002 \u5b57\u5178\u662f\u62e5\u6709\u7075\u6d3b\u5c3a\u5bf8\u7684\u952e\u503c\u5bf9\u96c6\u5408\uff0c\u4e0d\u662f\u901a\u8fc7\u4f4d\u7f6e\u8fdb\u884c\u7d22\u5f15\uff0c\u5176\u4e2d\u952e\u548c\u503c\u90fd\u662fPython\u5bf9\u8c61\u3002\u7528\u5927\u62ec\u53f7{}\u662f\u521b\u5efa\u5b57\u5178\u7684\u4e00\u79cd\u65b9\u5f0f\uff0c\u5728\u5b57\u5178\u4e2d\u7528\u9017\u53f7\u5c06\u952e\u503c\u5bf9\u5206\u9694\u3002 \u521b\u5efa\u5b57\u5178\u7684\u51e0\u79cd\u65b9\u6cd5\uff1a a = dict ( one = 1 , two = 2 , three = 3 ) b = { 'one' : 1 , 'two' : 2 , 'three' : 3 } c = dict ( zip ([ 'one' , 'two' , 'three' ], [ 1 , 2 , 3 ])) d = dict ([( 'two' , 2 ), ( 'three' , 3 ), ( 'one' , 1 )]) e = dict ({ 'three' : 3 , 'one' : 1 , 'two' : 2 }) print ( a == b == c == d == e ) # True \u5b57\u5178\u5e38\u7528\u65b9\u6cd5 \u65b9\u6cd5\u540d\u79f0 \u4f5c\u7528 a.items() \u8fd4\u56dea\u4e2d\u6240\u6709\u952e\u503c\u5bf9 a.values() \u8fd4\u56dea\u4e2d\u6240\u6709\u503c a.keys() \u8fd4\u56dea\u4e2d\u6240\u6709\u952e a.get() \u901a\u8fc7\u952e\u6765\u67e5\u503c\uff0c\u8fd4\u56de\u5bf9\u5e94\u7684\u503c a.clear() \u6e05\u7a7a\u5b57\u5178a\u7684\u503c a.setdefault \u901a\u8fc7\u952e\u503c\u6765\u67e5\u627e\u503c\uff0c\u627e\u4e0d\u5230\u5219\u63d2\u5165 a.update() \u952e\u548c\u503c\u66f4\u65b0\u5230\u65b0\u7684\u5b57\u5178 a.pop() \u5220\u9664\u6307\u5b9a\u4f4d\u7f6e\u7684\u5143\u7d20 \u751f\u6210\u4e00\u4e2a\u5b57\u5178\u3002 dict_a = { 'name' : 'Ming' , 'id' : 1001 , 'age' : 35 } print ( type ( dict_a )) # dict_b = dict ( city = 'Shanghai' , strict = 'Xuhui' , zip = '200000' ) print ( type ( dict_b )) # \u901a\u8fc7\u952e\u67e5\u8be2\u503c\uff0c\u67e5\u8be2\u4e0d\u5230\u629b\u51fa\u5f02\u5e38\u3002 print ( dict_a [ 'name' ]) # Ming print ( dict_a [ 'Name' ]) # Traceback (most recent call last): # File \"\", line 1, in # KeyError: 'Name' \u63d2\u5165\u65b0\u7684\u952e\u503c\u5bf9\u3002 dict_a [ 'city' ] = 'Chengdu' print ( dict_a ) # {'name': 'Ming', 'id': 1001, 'city': 'Chengdu'} \u5220\u9664\u67d0\u4e2a\u952e\u503c\u5bf9\u3002pop\u65b9\u6cd5\u4f1a\u5728\u5220\u9664\u7684\u540c\u65f6\u8fd4\u56de\u88ab\u5220\u7684\u503c\uff0c\u5e76\u5220\u9664\u952e\u3002 dict_a . pop ( 'city' ) # Chengdu print ( dict_a ) # {'name': 'Ming', 'id': 1001} \u53e6\u4e00\u79cd\u65b9\u5f0f\u5220\u9664\u67d0\u4e2a\u952e\u503c\u5bf9\u3002 del dict_a [ 'age' ] # Traceback (most recent call last): # File \"\", line 1, in # KeyError: 'age' del dict_a [ 'id' ] print ( dict_a ) # {'name': 'Ming'} \u5224\u65ad\u952e\u662f\u5426\u5b58\u5728\u3002 dict_a [ 23 ] = 'Hello World' print ( dict_a ) # {'name': 'Ming', 23: 'Hello World'} print ( 23 in dict_a ) # True print ( 35 in dict_a ) # False \u901a\u8fc7\u952e\u67e5\u8be2\u503c\u7684\u53e6\u4e00\u79cd\u65b9\u5f0f\uff0c\u67e5\u8be2\u4e0d\u5230\u4e0d\u629b\u5f02\u5e38\u3002 dict_a . get ( 'hai' ) dict_a . get ( 'hai' , 1 ) # 1 dict_a . get ( 'name' , 1 ) # Ming dict_a [ 'hai' ] # Traceback (most recent call last): # File \"\", line 1, in # KeyError: 'hai' \u901a\u8fc7\u952e\u67e5\u8be2\u503c\u7684\u53e6\u4e00\u79cd\u65b9\u5f0f\uff0c\u67e5\u8be2\u4e0d\u5230\u5219\u6dfb\u52a0\u3002 dict_a . setdefault ( 'name' ) # Ming dict_a . setdefault ( 'hai' , 1 ) # 1 print ( dict_a ) # {'name': 'Ming', 23: 'Hello World', 'hai': 1} dict_a . setdefault ( 'go' ) print ( dict_a ) # {'name': 'Ming', 23: 'Hello World', 'hai': 1, 'go': None} \u8bfb\u53d6\u5b57\u5178\u6240\u6709\u952e\u503c\u5bf9\uff0c\u8fd4\u56de\u7684\u662f\u5217\u8868\u5f62\u5f0f\u3002 print ( dict_a . items ()) # dict_items([('name', 'Ming'), (23, 'Hello World'), ('hai', 1), ('go', None)]) \u8bfb\u53d6\u5b57\u5178\u7684\u952e\u3002 print ( dict_a . keys ()) # dict_keys(['name', 23, 'hai', 'go']) \u8bfb\u53d6\u5b57\u5178\u7684\u503c\u3002 print ( dict_a . values ()) # dict_values(['Ming', 'Hello World', 1, None]) \u5c06\u5b57\u5178\u503c\u8f6c\u5316\u6210\u5217\u8868\u3002 print ( list ( dict_a . values ())) # ['Ming', 'Hello World', 1, None] for key in dict_a . keys (): print ( dict_a [ key ]) # Ming # Hello World # 1 # None \u6e05\u7a7a\u5b57\u5178\u3002 dict_a . clear () print ( dict_a ) # {} print ( len ( dict_a )) # 0 \u5bf9\u4e8e\u4efb\u4f55\u539f\u5b57\u5178\u4e2d\u5df2\u7ecf\u5b58\u5728\u7684\u952e\uff0c\u5982\u679c\u4f20\u7ed9update\u65b9\u6cd5\u7684\u6570\u636e\u4e5f\u542b\u6709\u76f8\u540c\u7684\u952e\uff0c\u5219\u5b83\u7684\u503c\u5c06\u4f1a\u88ab\u8986\u76d6\u3002 dict_a = { 'name' : 'Ming' , 'id' : 1001 , 'age' : 35 } dict_b = dict ( city = 'Shanghai' , id = 2001 , zip = '200000' ) dict_a . update ( dict_b ) print ( dict_a ) # {'name': 'Ming', 'id': 2001, 'age': 35, 'city': 'Shanghai', 'zip': '200000'} \u4ece\u5217\u8868\u751f\u6210\u5b57\u5178\u3002 \u5b57\u5178\u672c\u8d28\u4e0a\u662f2-\u5143\u7ec4\uff08\u542b\u67092\u4e2a\u5143\u7d20\u7684\u5143\u7ec4\uff09\u7684\u96c6\u5408\uff0c\u5b57\u5178\u662f\u53ef\u4ee5\u63a5\u53d7\u4e00\u4e2a2-\u5143\u7ec4\u7684\u5217\u8868\u4f5c\u4e3a\u53c2\u6570\u7684\u3002 # \u65b9\u6cd51 mapping = {} key_list = list ( range ( 5 )) value_list = list ( reversed ( range ( 5 ))) for key , value in zip ( key_list , value_list ): mapping [ key ] = value print ( mapping ) # {0: 4, 1: 3, 2: 2, 3: 1, 4: 0} # \u65b9\u6cd52\u3002 mapping = {} key_list = list ( range ( 5 )) value_list = list ( reversed ( range ( 5 ))) mapping = dict ( zip ( key_list , value_list )) print ( mapping ) # {0: 4, 1: 3, 2: 2, 3: 1, 4: 0} \u6709\u6548\u7684\u5b57\u5178\u952e\u7c7b\u578b\u3002 \u5c3d\u7ba1\u5b57\u5178\u7684\u503c\u53ef\u4ee5\u662f\u4efb\u4f55Python\u5bf9\u8c61\uff0c\u4f46\u952e\u5fc5\u987b\u662f\u4e0d\u53ef\u53d8\u7684\u5bf9\u8c61\uff0c\u6bd4\u5982\u6807\u91cf\u7c7b\u578b\uff08\u6574\u6570\u3001\u6d6e\u70b9\u6570\u3001\u5b57\u7b26\u4e32\uff09\u6216\u5143\u7ec4\uff08\u4e14\u5143\u7ec4\u5185\u5bf9\u8c61\u4e5f\u5fc5\u987b\u662f\u4e0d\u53ef\u53d8\u5bf9\u8c61\uff09\u3002 \u901a\u8fc7hash\u51fd\u6570\u53ef\u4ee5\u68c0\u67e5\u4e00\u4e2a\u5bf9\u8c61\u662f\u5426\u53ef\u4ee5\u54c8\u5e0c\u5316\uff08\u5373\u662f\u5426\u53ef\u4ee5\u7528\u4f5c\u5b57\u5178\u7684\u952e\uff09\uff0c\u672f\u8bed\u53eb\u4f5c\u54c8\u5e0c\u5316\u3002 print ( hash ( 'string' )) # -4368784820203065343 print ( hash (( 1 , 2 , ( 2 , 3 )))) # -9209053662355515447 print ( hash (( 1 , 2 , [ 2 , 3 ]))) # TypeError: unhashable type: 'list' print ( hash (( 1 , 2 , tuple ([ 2 , 3 ])))) # -9209053662355515447 \u4e3a\u4e86\u5c06\u5217\u8868\u4f5c\u4e3a\u952e\uff0c\u4e00\u79cd\u65b9\u5f0f\u5c31\u662f\u5c06\u5176\u8f6c\u6362\u4e3a\u5143\u7ec4 \u5b57\u5178\u9ed8\u8ba4\u503c\u3002 \u4e0b\u9762\u7684\u4f8b\u5b50\uff0c\u5b9e\u73b0\u4e86\u5c06\u4e00\u4e2a\u5355\u8bcd\u7ec4\u6210\u7684\u5217\u8868\uff0c\u8f6c\u6362\u6210\u5355\u8bcd\u9996\u5b57\u6bcd\u548c\u5355\u8bcd\u4e3a\u952e\u503c\u5bf9\u7684\u5b57\u5178\u3002\u5148\u7528\u4f20\u7edf\u65b9\u6cd5\u5b9e\u73b0\uff0c\u518d\u7528\u5b57\u5178\u7684setdefault\u65b9\u6cd5\u8fdb\u884c\u6539\u5199\u3002 \u5148\u770b\u4f20\u7edf\u65b9\u6cd5\u3002 words = [ 'apple' , 'bat' , 'bar' , 'atom' , 'book' ] by_letter = {} for word in words : letter = word [ 0 ] # word[0]\u628a\u5217\u8868words\u7684\u6bcf\u4e2a\u5143\u7d20\u5217\u8868\u5316\uff0c\u5e76\u53d6\u9996\u5b57\u6bcd\u3002\u8f93\u51fa\u7684\u662fa, b, b, a, b\u8fd95\u4e2a\u5217\u8868\u5143\u7d20\u7684\u9996\u5b57\u6bcd if letter not in by_letter : # \u751f\u6210\u7b2c\u4e00\u4e2a\u952e\u503c\u5bf9 print ( letter ) by_letter [ letter ] = [ word ] # \u5bf9\u6bd4[word]\u548cword[]\u7684\u7528\u6cd5 print ( by_letter ) # a # {'a': ['apple']} # b # {'a': ['apple'], 'b': ['bat']} else : # append\u5176\u4ed6\u952e\u503c\u5bf9 print ( letter ) by_letter [ letter ] . append ( word ) print ( by_letter ) # b # {'a': ['apple'], 'b': ['bat', 'bar']} # a # {'a': ['apple', 'atom'], 'b': ['bat', 'bar']} # b # {'a': ['apple', 'atom'], 'b': ['bat', 'bar', 'book']} print ( by_letter ) # {'a': ['apple', 'atom'], 'b': ['bat', 'bar', 'book']} \u7528\u5b57\u5178\u7684setdefault\u65b9\u6cd5\uff0c\u4e0a\u8ff0\u7684for\u5faa\u73af\u8bed\u53e5\u53ef\u4ee5\u88ab\u5199\u4e3a\u5982\u4e0b\u3002 words = [ 'apple' , 'bat' , 'bar' , 'atom' , 'book' ] by_letter = {} for word in words : letter = word [ 0 ] # word[0]\u7684\u8f93\u51fa\u4f9d\u7136\u662f5\u4e2a\u5217\u8868\u5143\u7d20\u7684\u9996\u5b57\u6bcda, b, b, a, b by_letter . setdefault ( letter , []) . append ( word ) # \u5982\u679cletter\u4e0d\u5728[]\u5219\u901a\u8fc7append\u6dfb\u52a0word print ( by_letter ) # {'a': ['apple', 'atom'], 'b': ['bat', 'bar', 'book']} \u5982\u679c\u6539\u5199\u4e3a by_letter.setdefault(letter, ['a']).append(word) \uff0c\u5219\u8f93\u51fa by_letter \u662f {'a': ['a', 'apple', 'atom'], 'b': ['a', 'bat', 'bar', 'book']} \u3002 words = [ 'apple' , 'bat' , 'bar' , 'atom' , 'book' ] by_letter = {} for word in words : letter = word [ 0 ] # word[0]\u7684\u8f93\u51fa\u4f9d\u7136\u662f5\u4e2a\u5217\u8868\u5143\u7d20\u7684\u9996\u5b57\u6bcda, b, b, a, b by_letter . setdefault ( letter , [ 'a' ]) . append ( word ) print ( by_letter ) # {'a': ['a', 'apple', 'atom'], 'b': ['a', 'bat', 'bar', 'book']} \u4f53\u4f1asetdefault()\u7684\u6ce8\u91ca\u201cInsert key with a value of default if key is not in the dictionary. Return the value for key if key is in the dictionary, else default.\u201d \u901a\u8fc7defaultdict\u7c7b\u4f7f\u5f97\u4e0a\u8ff0\u76ee\u7684\u5b9e\u73b0\u66f4\u4e3a\u7b80\u5355\u3002 from collections import defaultdict by_letter = defaultdict ( list ) # list\u662f\u5185\u7f6e\u7684\u53ef\u53d8\u5e8f\u5217(Built-in mutable sequence) print ( dict ( by_letter )) # {} for word in words : by_letter [ word [ 0 ]] . append ( word ) print ( by_letter ) # defaultdict(, {'a': ['apple', 'atom'], 'b': ['bat', 'bar', 'book']}) print ( dict ( by_letter )) # {'a': ['apple', 'atom'], 'b': ['bat', 'bar', 'book']} \u4e0b\u8868\u5c55\u793a\u4e86 dict \u3001 defaultdict \u548c OrderedDict \u7684\u5e38\u89c1\u65b9\u6cd5\uff0c\u540e\u9762\u4e24\u4e2a\u6570\u636e\u7c7b\u578b\u662f dict \u7684\u53d8\u79cd\uff0c\u4f4d\u4e8e collections \u6a21\u5757\u5185\u3002 default_factory \u5e76\u4e0d\u662f\u4e00\u4e2a\u65b9\u6cd5\uff0c\u800c\u662f\u4e00\u4e2a\u53ef\u8c03\u7528\u5bf9\u8c61\uff08callable\uff09\uff0c\u5b83\u7684\u503c\u5728 defaultdict \u521d\u59cb\u5316\u7684\u65f6\u5019\u7531\u7528\u6237\u8bbe\u5b9a\u3002 OrderedDict.popitem() \u4f1a\u79fb\u9664\u5b57\u5178\u91cc\u6700\u5148\u63d2\u5165\u7684\u5143\u7d20\uff08\u5148\u8fdb\u5148\u51fa\uff09\uff1b\u540c\u65f6\u8fd9\u4e2a\u65b9\u6cd5\u8fd8\u6709\u4e00\u4e2a\u53ef\u9009\u7684last\u53c2\u6570\uff0c\u82e5\u4e3a\u771f\uff0c\u5219\u4f1a\u79fb\u9664\u6700\u540e\u63d2\u5165\u7684\u5143\u7d20\uff08\u540e\u8fdb\u5148\u51fa\uff09\u3002 \u4e0a\u9762\u7684\u8868\u683c\u4e2d\uff0cupdate\u65b9\u6cd5\u5904\u7406\u53c2\u6570m\u7684\u65b9\u5f0f\uff0c\u662f\u5178\u578b\u7684\u201c\u9e2d\u5b50\u7c7b\u578b\u201d\u3002\u51fd\u6570\u9996\u5148\u68c0\u67e5m\u662f\u5426\u6709keys\u65b9\u6cd5\uff0c\u5982\u679c\u6709\uff0c\u90a3\u4e48update\u51fd\u6570\u5c31\u628a\u5b83\u5f53\u4f5c\u6620\u5c04\u5bf9\u8c61\u6765\u5904\u7406\u3002\u5426\u5219\uff0c\u51fd\u6570\u4f1a\u9000\u4e00\u6b65\uff0c\u8f6c\u800c\u628am\u5f53\u4f5c\u5305\u542b\u4e86\u952e\u503c\u5bf9(key, value)\u5143\u7d20\u7684\u8fed\u4ee3\u5668\u3002Python\u91cc\u5927\u591a\u6570\u6620\u5c04\u7c7b\u578b\u7684\u6784\u9020\u65b9\u6cd5\u90fd\u91c7\u7528\u4e86\u7c7b\u4f3c\u7684\u903b\u8f91\uff0c\u56e0\u6b64\u4f60\u65e2\u53ef\u4ee5\u7528\u4e00\u4e2a\u6620\u5c04\u5bf9\u8c61\u6765\u65b0\u5efa\u4e00\u4e2a\u6620\u5c04\u5bf9\u8c61\uff0c\u4e5f\u53ef\u4ee5\u7528\u5305\u542b(key, value)\u5143\u7d20\u7684\u53ef\u8fed\u4ee3\u5bf9\u8c61\u6765\u521d\u59cb\u5316\u4e00\u4e2a\u6620\u5c04\u5bf9\u8c61\u3002 \u5b57\u5178\u7684\u53d8\u79cd\uff1a collections.OrderedDict \u8fd9\u4e2a\u7c7b\u578b\u5728\u6dfb\u52a0\u952e\u7684\u65f6\u5019\u4f1a\u4fdd\u6301\u987a\u5e8f\uff0c\u56e0\u6b64\u952e\u7684\u8fed\u4ee3\u6b21\u5e8f\u603b\u662f\u4e00\u81f4\u7684\u3002OrderedDict\u7684popitem\u65b9\u6cd5\u9ed8\u8ba4\u5220\u9664\u5e76\u8fd4\u56de\u7684\u662f\u5b57\u5178\u91cc\u7684\u6700\u540e\u4e00\u4e2a\u5143\u7d20\uff0c\u4f46\u662f\u5982\u679c\u50cfmy_odict.popitem(last=False)\u8fd9\u6837\u8c03\u7528\u5b83\uff0c\u90a3\u4e48\u5b83\u5220\u9664\u5e76\u8fd4\u56de\u7b2c\u4e00\u4e2a\u88ab\u6dfb\u52a0\u8fdb\u53bb\u7684\u5143\u7d20\u3002 collections.ChainMap \u8be5\u7c7b\u578b\u53ef\u4ee5\u5bb9\u7eb3\u6570\u4e2a\u4e0d\u540c\u7684\u6620\u5c04\u5bf9\u8c61\uff0c\u7136\u540e\u5728\u8fdb\u884c\u952e\u67e5\u627e\u64cd\u4f5c\u7684\u65f6\u5019\uff0c\u8fd9\u4e9b\u5bf9\u8c61\u4f1a\u88ab\u5f53\u4f5c\u4e00\u4e2a\u6574\u4f53\u88ab\u9010\u4e2a\u67e5\u627e\uff0c\u76f4\u5230\u952e\u88ab\u627e\u5230\u4e3a\u6b62\u3002\u8fd9\u4e2a\u529f\u80fd\u5728\u7ed9\u6709\u5d4c\u5957\u4f5c\u7528\u57df\u7684\u8bed\u8a00\u505a\u89e3\u91ca\u5668\u7684\u65f6\u5019\u5f88\u6709\u7528\uff0c\u53ef\u4ee5\u7528\u4e00\u4e2a\u6620\u5c04\u5bf9\u8c61\u6765\u4ee3\u8868\u4e00\u4e2a\u4f5c\u7528\u57df\u7684\u4e0a\u4e0b\u6587\u3002 collections.Counter \u8fd9\u4e2a\u6620\u5c04\u7c7b\u578b\u4f1a\u7ed9\u952e\u51c6\u5907\u4e00\u4e2a\u6574\u6570\u8ba1\u6570\u5668\u3002\u6bcf\u6b21\u66f4\u65b0\u4e00\u4e2a\u952e\u7684\u65f6\u5019\u90fd\u4f1a\u589e\u52a0\u8fd9\u4e2a\u8ba1\u6570\u5668\u3002\u6240\u4ee5\u8fd9\u4e2a\u7c7b\u578b\u53ef\u4ee5\u7528\u6765\u7ed9\u53ef\u6563\u5217\u8868\u5bf9\u8c61\u8ba1\u6570\uff0c\u6216\u8005\u662f\u5f53\u6210\u591a\u91cd\u96c6\u6765\u7528\u2014\u2014\u591a\u91cd\u96c6\u5408\u5c31\u662f\u96c6\u5408\u91cc\u7684\u5143\u7d20\u53ef\u4ee5\u51fa\u73b0\u4e0d\u6b62\u4e00\u6b21\u3002Counter\u5b9e\u73b0\u4e86+\u548c-\u8fd0\u7b97\u7b26\u7528\u6765\u5408\u5e76\u8bb0\u5f55\uff0c\u8fd8\u6709\u50cfmost_common([n])\u8fd9\u7c7b\u5f88\u6709\u7528\u7684\u65b9\u6cd5\u3002most_common([n])\u4f1a\u6309\u7167\u6b21\u5e8f\u8fd4\u56de\u6620\u5c04\u91cc\u6700\u5e38\u89c1\u7684n\u4e2a\u952e\u548c\u5b83\u4eec\u7684\u8ba1\u6570 collections.UserDict \u8fd9\u4e2a\u7c7b\u5176\u5b9e\u5c31\u662f\u628a\u6807\u51c6dict\u7528\u7eafPython\u53c8\u5b9e\u73b0\u4e86\u4e00\u904d\u3002\u8ddfOrderedDict\u3001ChainMap\u548cCounter\u8fd9\u4e9b\u5f00\u7bb1\u5373\u7528\u7684\u7c7b\u578b\u4e0d\u540c\uff0cUserDict\u662f\u8ba9\u7528\u6237\u7ee7\u627f\u5199\u5b50\u7c7b\u7684\u3002 \u4e0b\u9762\u7684\u4f8b\u5b50\u5229\u7528Counter\u6765\u8ba1\u7b97\u5355\u8bcd\u4e2d\u5404\u4e2a\u5b57\u6bcd\u51fa\u73b0\u7684\u6b21\u6570\uff1a str = 'abracadabra' ct = collections . Counter ( str ) print ( ct ) # Counter({'a': 5, 'b': 2, 'r': 2, 'c': 1, 'd': 1}) \u4e0d\u53ef\u53d8\u6620\u5c04\u7c7b\u578b\u3002 \u6807\u51c6\u5e93\u91cc\u6240\u6709\u7684\u6620\u5c04\u7c7b\u578b\u90fd\u662f\u53ef\u53d8\u7684\uff0c\u4f46\u6709\u65f6\u5019\u4f60\u4f1a\u6709\u8fd9\u6837\u7684\u9700\u6c42\uff0c\u6bd4\u5982\u4e0d\u80fd\u8ba9\u7528\u6237\u9519\u8bef\u5730\u4fee\u6539\u67d0\u4e2a\u6620\u5c04\u3002 \u4ecePython 3.3\u5f00\u59cb\uff0c types \u6a21\u5757\u4e2d\u5f15\u5165\u4e86\u4e00\u4e2a\u5c01\u88c5\u7c7b\u540d\u53eb MappingProxyType \u3002\u5982\u679c\u7ed9\u8fd9\u4e2a\u7c7b\u4e00\u4e2a\u6620\u5c04\uff0c\u5b83\u4f1a\u8fd4\u56de\u4e00\u4e2a\u53ea\u8bfb\u7684\u6620\u5c04\u89c6\u56fe\u3002\u867d\u7136\u662f\u4e2a\u53ea\u8bfb\u89c6\u56fe\uff0c\u4f46\u662f\u5b83\u662f\u52a8\u6001\u7684\u3002\u8fd9\u610f\u5473\u7740\u5982\u679c\u5bf9\u539f\u6620\u5c04\u505a\u51fa\u4e86\u6539\u52a8\uff0c\u6211\u4eec\u901a\u8fc7\u8fd9\u4e2a\u89c6\u56fe\u53ef\u4ee5\u89c2\u5bdf\u5230\uff0c\u4f46\u662f\u65e0\u6cd5\u901a\u8fc7\u8fd9\u4e2a\u89c6\u56fe\u5bf9\u539f\u6620\u5c04\u505a\u51fa\u4fee\u6539\u3002 \u901a\u8fc7\u4e0b\u4f8b\u53ef\u4ee5\u770b\u51fa\uff0c d \u4e2d\u7684\u5185\u5bb9\u53ef\u4ee5\u901a\u8fc7 d_proxy \u770b\u5230\u3002\u4f46\u662f\u901a\u8fc7 d_proxy \u5e76\u4e0d\u80fd\u505a\u4efb\u4f55\u4fee\u6539\u3002 d_proxy \u662f\u52a8\u6001\u7684\uff0c\u4e5f\u5c31\u662f\u8bf4\u5bf9 d \u6240\u505a\u7684\u4efb\u4f55\u6539\u52a8\u90fd\u4f1a\u53cd\u9988\u5230\u5b83\u4e0a\u9762\u3002 from types import MappingProxyType d = { 1 : 'A' } d_proxy = MappingProxyType ( d ) print ( d ) # {1: 'A'} print ( d_proxy ) # {1: 'A'} print ( d [ 1 ]) # A print ( d_proxy [ 1 ]) # A d [ 2 ] = 'W' print ( d ) # {1: 'A', 2: 'W'} d_proxy [ 2 ] = 'W' # TypeError: 'mappingproxy' object does not support item assignment print ( d_proxy ) # {1: 'A', 2: 'W'}","title":"1.4 \u5b57\u5178\uff08dictionary\uff09"},{"location":"python/Foundation/ch01/#15-set","text":"\u201c\u96c6\u201d\u8fd9\u4e2a\u6982\u5ff5\u5728Python\u4e2d\u7b97\u662f\u6bd4\u8f83\u5e74\u8f7b\u7684\uff0c\u540c\u65f6\u5b83\u7684\u4f7f\u7528\u7387\u4e5f\u6bd4\u8f83\u4f4e\u3002set\u548c\u5b83\u7684\u4e0d\u53ef\u53d8\u7684\u59ca\u59b9\u7c7b\u578bfrozenset\u76f4\u5230Python 2.3\u624d\u9996\u6b21\u4ee5\u6a21\u5757\u7684\u5f62\u5f0f\u51fa\u73b0\uff0c\u7136\u540e\u5728Python 2.6\u4e2d\u5b83\u4eec\u5347\u7ea7\u6210\u4e3a\u5185\u7f6e\u7c7b\u578b\u3002 \u96c6\u5408(set) \uff0c\u5305\u542b\u4e0d\u53ef\u53d8\u7684\u96c6\u5408\uff08frozenset\uff09\uff0c\u662f\u4e00\u79cd\u65e0\u5e8f\u4e14\u5143\u7d20\u552f\u4e00\u7684\u5e8f\u5217\uff0c\u6240\u4ee5\u96c6\u5408\u7684\u672c\u8d28\u662f\u8bb8\u591a\u552f\u4e00\u5bf9\u8c61\u7684\u805a\u96c6\u3002 \u548c\u5b57\u5178\u7c7b\u4f3c\uff0c\u96c6\u5408\u7684\u5143\u7d20\u662f\u4e0d\u53ef\u53d8\u7684\u3002\u53ef\u4ee5\u8ba4\u4e3a\u96c6\u5408\u4e5f\u50cf\u5b57\u5178\uff0c\u4f46\u662f\u53ea\u6709\u952e\u6ca1\u6709\u503c\u3002\u57fa\u672c\u529f\u80fd\u662f\u8fdb\u884c\u6210\u5458\u5173\u7cfb\u6d4b\u8bd5\u548c\u5220\u9664\u91cd\u590d\u5143\u7d20\u3002\u6240\u4ee5\u96c6\u5408\u53e6\u4e00\u4e2a\u7528\u9014\u662f\u53bb\u91cd\u590d\u3002 \u96c6\u5408\u4e2d\u7684\u5143\u7d20\u5fc5\u987b\u662f\u53ef\u6563\u5217\u7684\uff0cset\u7c7b\u578b\u672c\u8eab\u662f\u4e0d\u53ef\u6563\u5217\u7684\uff0c\u4f46\u662ffrozenset\u53ef\u4ee5\u3002\u56e0\u6b64\u53ef\u4ee5\u521b\u5efa\u4e00\u4e2a\u5305\u542b\u4e0d\u540cfrozenset\u7684set\u3002 \u96c6\u5408\u53ef\u4ee5\u6709\u4e24\u79cd\u521b\u5efa\u65b9\u5f0f\uff1a\u901a\u8fc7set()\u51fd\u6570\u6216\u8005{}\u6765\u521b\u5efa\uff08\u7528\u5927\u62ec\u53f7\u62ec\u4f4f\u7684\u5185\u5bb9\uff0cPython3\u81ea\u52a8\u5b9a\u4e49\u4e3a\u96c6\u5408\uff09\u3002 \u96c6\u5408\u4e0d\u5c5e\u4e8e\u5e8f\u5217\u7c7b\u6570\u636e\uff0c \u96c6\u5408\u4e0d\u652f\u6301\u901a\u8fc7\u7d22\u5f15\u8bbf\u95ee\u6307\u5b9a\u5143\u7d20\uff0c\u4f46\u53ef\u4ee5\u589e\u52a0\u548c\u5220\u9664\u5143\u7d20\u3002 \u9762\u7684\u4f8b\u5b50\u662f\u6c42 haystacke \u548c needles \u4e24\u4e2a\u96c6\u5408\u7684\u4ea4\u96c6\u5143\u7d20\u4e2a\u6570\u3002 haystacke = { 'a' , 'b' , 'c' , 'd' , 'e' , 'f' , 'g' , 'h' , 'f' , 'g' , 'h' , 'c' , 'd' , 'e' , 'c' , 'd' , 'e' , 'f' , 'g' , 'h' } needles = { 'c' , 'h' , 'w' } type ( haystacke ) # type ( needles ) # # \u4f20\u7edf\u65b9\u6cd5 found = 0 for i in needles : if i in haystacke : found += 1 print ( found ) # 2 # \u96c6\u5408\u65b9\u6cd5\u4e00 found = len ( needles & haystacke ) print ( found ) # 2 # \u96c6\u5408\u65b9\u6cd5\u4e8c found = len ( needles . intersection ( haystacke )) print ( found ) # 2 \u96c6\u5408\u5b9e\u73b0\u4e86\u5f88\u591a\u57fa\u7840\u7684\u4e2d\u7f00\u8fd0\u7b97\u7b26\uff0c\u6bd4\u5982\uff0c\u96c6\u5408\u652f\u6301\u6570\u5b66\u4e0a\u7684\u96c6\u5408\u64cd\u4f5c\uff1a\u5e76\u96c6\u3001\u4ea4\u96c6\u3001\u5dee\u96c6\u3001\u5bf9\u79f0\u5dee\u96c6\u3002 \u65b9\u6cd5\u540d\u79f0 \u8bf4\u660e add() \u4e3a\u96c6\u5408\u6dfb\u52a0\u5143\u7d20 update() \u7ed9\u96c6\u5408\u6dfb\u52a0\u5143\u7d20 clear() \u79fb\u9664\u96c6\u5408\u4e2d\u7684\u6240\u6709\u5143\u7d20 copy() \u62f7\u8d1d\u4e00\u4e2a\u96c6\u5408 remove() \u79fb\u9664\u6307\u5b9a\u5143\u7d20 pop() \u968f\u673a\u79fb\u9664\u5143\u7d20 discard() \u5220\u9664\u96c6\u5408\u4e2d\u6307\u5b9a\u7684\u5143\u7d20 < \u6216\u8005issubset() \u5224\u65ad\u6307\u5b9a\u96c6\u5408\u662f\u5426\u4e3a\u8be5\u65b9\u6cd5\u53c2\u6570\u96c6\u5408\u7684\u5b50\u96c6 | \u6216\u8005union() \u8fd4\u56de\u4e24\u4e2a\u96c6\u5408\u7684\u5e76\u96c6 & \u6216\u8005intersection() \u8fd4\u56de\u96c6\u5408\u7684\u4ea4\u96c6 intersection_update() \u8fd4\u56de\u96c6\u5408\u7684\u4ea4\u96c6 - \u6216\u8005difference() \u8fd4\u56de\u591a\u4e2a\u96c6\u5408\u7684\u5dee\u96c6 difference_update() \u79fb\u9664\u96c6\u5408\u4e2d\u7684\u5143\u7d20\uff0c\u8be5\u5143\u7d20\u5728\u6307\u5b9a\u7684\u96c6\u5408\u4e5f\u5b58\u5728 ^ \u6216\u8005symmetric_difference() \u8fd4\u56de\u4e24\u4e2a\u96c6\u5408\u4e2d\u4e0d\u91cd\u590d\u7684\u5143\u7d20\u96c6\u5408(\u4e24\u96c6\u5408\u9664\u53bb\u4ea4\u96c6\u90e8\u5206\u7684\u5143\u7d20) symmetric_difference_update() \u79fb\u9664\u5f53\u524d\u96c6\u5408\u4e2d\u5728\u53e6\u5916\u4e00\u4e2a\u6307\u5b9a\u96c6\u5408\u76f8\u540c\u7684\u5143\u7d20\uff0c\u5e76\u5c06\u53e6\u5916\u4e00\u4e2a\u6307\u5b9a\u96c6\u5408\u4e2d\u4e0d\u540c\u7684\u5143\u7d20\u63d2\u5165\u5230\u5f53\u524d\u96c6\u5408\u4e2d isdisjoint() \u5224\u65ad\u4e24\u4e2a\u96c6\u5408\u662f\u5426\u5305\u542b\u76f8\u540c\u7684\u5143\u7d20\uff0c\u5982\u679c\u6ca1\u6709\u8fd4\u56de True\uff0c\u5426\u5219\u8fd4\u56de False issuperset() \u5224\u65ad\u8be5\u65b9\u6cd5\u7684\u53c2\u6570\u96c6\u5408\u662f\u5426\u4e3a\u6307\u5b9a\u96c6\u5408\u7684\u5b50\u96c6 \u4e3e\u4f8b\uff1a a = { 'a' , 'b' , 'c' , 1 , 2 } b = { 1 , 'c' , 'd' } \u5e76\u96c6(a\u548cb\u4e2d\u7684\u6240\u6709\u4e0d\u540c\u5143\u7d20)\u3002 print ( a . union ( b )) # {'c', 1, 2, 'd', 'a', 'b'} print ( a | b ) # {'c', 1, 2, 'd', 'a', 'b'} \u4ea4\u96c6(a\u3001b\u4e2d\u540c\u65f6\u5305\u542b\u7684\u5143\u7d20)\u3002 print ( a . intersection ( b )) # {'c', 1} print ( a & b ) # {'c', 1} \u5c06a\u7684\u5185\u5bb9\u8bbe\u7f6e\u4e3aa\u548cb\u7684\u4ea4\u96c6\u3002 a = { 'a' , 'b' , 'c' , 1 , 2 } b = { 1 , 'c' , 'd' } a . intersection_update ( b ) print ( a ) # {1, 'c'} \u5728a\u4e0d\u5728b\u7684\u5143\u7d20\u3002 print ( a . difference ( b )) # {'a', 2, 'b'} print ( a - b ) # {2, 'a', 'b'} \u5c06a\u7684\u5185\u5bb9\u8bbe\u4e3a\u5728a\u4e0d\u5728b\u7684\u5143\u7d20\u3002 a = { 'a' , 'b' , 'c' , 1 , 2 } b = { 1 , 'c' , 'd' } a . difference_update ( b ) print ( a ) # {2, 'b', 'a'} a = { 'a' , 'b' , 'c' , 1 , 2 } b = { 1 , 'c' , 'd' } a -= b print ( a ) # {2, 'a', 'b'} \u5c06\u5143\u7d20\u52a0\u5165\u96c6\u5408a\u3002 a . add ( 7 ) print ( a ) # {1, 2, 'c', 7, 'a', 'b'} \u6bcf\u6b21\u8f93\u51fa\u7684\u987a\u5e8f\u662f\u4e0d\u4e00\u6837\u7684 \u4ece\u96c6\u5408a\u79fb\u9664\u67d0\u4e2a\u5143\u7d20\u3002 a . remove ( 7 ) print ( a ) # {1, 2, 'c', 'a', 'b'} \u5982\u679ca\u88ab\u6e05\u7a7a\uff0c\u5219\u62a5\u9519 KeyError: 7 \u6240\u6709\u5728a\u6216b\u4e2d\uff0c\u4f46\u4e0d\u662f\u540c\u65f6\u5728a\u3001b\u4e2d\u7684\u5143\u7d20\u3002 print ( a . symmetric_difference ( b )) # {2, 'd', 'b', 'a'} print ( a ^ b ) # {2, 'd', 'b', 'a'} \u5c06a\u7684\u5185\u5bb9\u8bbe\u4e3a\u6240\u6709\u5728a\u6216b\u4e2d\uff0c\u4f46\u4e0d\u662f\u540c\u65f6\u5728a\u3001b\u4e2d\u7684\u5143\u7d20\u3002 a = { 'a' , 'b' , 'c' , 1 , 2 } b = { 1 , 'c' , 'd' } a . symmetric_difference_update ( b ) print ( a ) # {'a', 2, 'd', 'b'} a = { 'a' , 'b' , 'c' , 1 , 2 } b = { 1 , 'c' , 'd' } a ^= b print ( a ) # {2, 'd', 'a', 'b'} \u5982\u679ca\u5305\u542b\u4e8eb\uff0c\u8fd4\u56deTure\u3002 print ( a . issubset ( b )) # False \u5c06a\u7684\u5185\u5bb9\u8bbe\u7f6e\u4e3aa\u548cb\u7684\u5e76\u96c6\u3002 print ( a ) # {'a', 2, 'd', 'b'} a = { 'a' , 'b' , 'c' , 1 , 2 } a . update ( b ) print ( a ) # {1, 2, 'a', 'b', 'd', 'c'} \u79fb\u9664\u4efb\u610f\u5143\u7d20\uff0c\u5982\u679c\u96c6\u5408\u662f\u7a7a\u7684\uff0c\u629b\u51fakeyError\u3002 a . pop () # \u968f\u673a\u79fb\u9664\u67d0\u4e2a\u5143\u7d20\uff0c\u6ca1\u6709\u8f93\u5165\u53d8\u91cf\uff0c\u5982\u679c\u96c6\u5408\u662f\u7a7a\u7684\uff0c\u629b\u51faKeyError: 'pop from an empty set' print ( a ) # {2, 1, 'd', 'b', 'a'} \u5c06\u96c6\u5408\u91cd\u7f6e\u4e3a\u7a7a\uff0c\u6e05\u7a7a\u6240\u6709\u5143\u7d20\u3002 a . clear () print ( a ) # set() \u96c6\u5408\u7684\u5143\u7d20\u5fc5\u987b\u662f\u4e0d\u53ef\u53d8\u7684\uff0c\u5982\u679c\u60f3\u8981\u5305\u542b\u5217\u8868\u578b\u7684\u5143\u7d20\uff0c\u5fc5\u987b\u5148\u8f6c\u6362\u4e3a\u5143\u7ec4\u3002 my_data1 = [ 1 , 2 , 3 , 4 ] my_data2 = [ 3 , 4 , 5 , 6 ] my_set = { tuple ( my_data1 ), tuple ( my_data2 )} print ( my_set ) # {(1, 2, 3, 4), (3, 4, 5, 6)}","title":"1.5 \u96c6\u5408\uff08set\uff09"},{"location":"python/Foundation/ch01/#16-tuple","text":"Python \u7684\u5143\u7ec4\u4e0e\u5217\u8868\u7c7b\u4f3c\uff0c\u4e0d\u540c\u4e4b\u5904\u5728\u4e8e\u5143\u7ec4\u7684\u5143\u7d20\u4e0d\u80fd\u4fee\u6539\u3002 \u5143\u7ec4\u4f7f\u7528\u5c0f\u62ec\u53f7( )\uff0c\u5217\u8868\u4f7f\u7528\u65b9\u62ec\u53f7[ ]\u3002 \u5143\u7ec4\u4e2d\u53ea\u5305\u542b\u4e00\u4e2a\u5143\u7d20\u65f6\uff0c\u9700\u8981\u5728\u5143\u7d20\u540e\u9762\u6dfb\u52a0\u9017\u53f7 \uff0c\u5426\u5219\u62ec\u53f7\u4f1a\u88ab\u5f53\u4f5c\u8fd0\u7b97\u7b26\u4f7f\u7528\u3002 \u5143\u7ec4\u53ef\u4ee5\u4f7f\u7528\u4e0b\u6807\u7d22\u5f15\u6765\u8bbf\u95ee\u5143\u7ec4\u4e2d\u7684\u503c\u3002 \u5143\u7ec4\u4e2d\u7684\u5143\u7d20\u503c\u662f\u4e0d\u5141\u8bb8\u4fee\u6539\u7684\uff0c\u4f46\u6211\u4eec\u53ef\u4ee5\u5bf9\u5143\u7ec4\u8fdb\u884c\u8fde\u63a5\u7ec4\u5408\u3002 \u5143\u7ec4\u4e2d\u7684\u5143\u7d20\u503c\u662f\u4e0d\u5141\u8bb8\u5220\u9664\u7684\uff0c\u4f46\u6211\u4eec\u53ef\u4ee5\u4f7f\u7528del\u8bed\u53e5\u6765\u5220\u9664\u6574\u4e2a\u5143\u7ec4\u3002 # \u6b64\u5904\u62ec\u53f7\u88ab\u89e3\u6790\u4e3a\u8fd0\u7b97\u7b26\uff0c\u9700\u8981\u5728\u540e\u9762\u52a0\u4e0a\u9017\u53f7\u624d\u4f1a\u88ab\u89e3\u91ca\u4e3a\u5143\u7ec4 tup1 = ( 10 ) print ( type ( tup1 )) # tup1 = ( 10 ,) print ( type ( tup1 )) # \u521b\u5efa\u5143\u7ec4\u6700\u7b80\u5355\u7684\u529e\u6cd5\u5c31\u662f\u7528\u9017\u53f7\u5206\u9694\u5e8f\u5217\u503c\u3002\u5143\u7ec4\u5bf9\u6570\u636e\u7c7b\u578b\u6ca1\u6709\u4e00\u81f4\u6027\u8981\u6c42\u3002 tup = 4 , 5 , 6 print ( tup ) # (4, 5, 6) nested_tup = ( 4 , 5 , 6 ), ( 7 , 8 ) print ( nested_tup ) # # ((4, 5, 6), (7, 8)) tup = ( 'a' , 'b' , { 'one' : 1 }) print ( type ( tup )) # \u4f7f\u7528\u52a0\u53f7\uff08+\uff09\u8fdb\u884c\u5143\u7ec4\u8fde\u63a5\u5408\u5e76\u3002 tup = tuple (( 4 , None , 'fool' ) + ( 6 , 0 ) + ( 'bar' ,)) print ( tup ) # (4, None, 'fool', 6, 0, 'bar') \u5143\u7ec4\u7684\u4e0d\u53ef\u53d8\u6307\u7684\u662f**\u5143\u7ec4\u6240\u6307\u5411\u7684\u5185\u5b58\u4e2d\u7684\u5185\u5bb9\u4e0d\u53ef\u53d8**\u3002 tup = ( 'h' , 'e' , 'l' , 'l' , 'o' ) print ( id ( tup )) # 139820353350208 tup = ( 1 , 2 , 3 , 4 , 5 ) print ( id ( tup )) # 139820353298896 tup [ 0 ] = 'x' # Traceback (most recent call last): # File \"\", line 1, in # TypeError: 'tuple' object does not support item assignment \u5c06\u5143\u7ec4\u4e58\u4ee5\u6574\u6570\uff0c\u5219\u4f1a\u548c\u5217\u8868\u4e00\u6837\uff0c\u751f\u6210\u542b\u6709\u591a\u4efd\u62f7\u8d1d\u7684\u5143\u7ec4\u3002\u5bf9\u8c61\u81ea\u8eab\u5e76\u6ca1\u6709\u590d\u5236\uff0c\u53ea\u662f\u6307\u5411\u5b83\u4eec\u7684\u5f15\u7528\u8fdb\u884c\u4e86\u590d\u5236\u3002 tup = tuple (( 'fool' , 'bar' ) * 4 ) print ( tup ) # ('fool', 'bar', 'fool', 'bar', 'fool', 'bar', 'fool', 'bar') \u5982\u679c\u5143\u7ec4\u4e2d\u7684\u4e00\u4e2a\u5bf9\u8c61\u662f\u53ef\u53d8\u7684\uff0c\u4f8b\u5982\u5217\u8868\uff0c\u4f60\u53ef\u4ee5\u5728\u5b83\u5185\u90e8\u8fdb\u884c\u4fee\u6539\u3002 tup = tuple ([ 'foo' , [ 4 , 5 , 6 ], True ]) tup [ 1 ] . append ( 0 ) print ( tup ) # ('foo', [4, 5, 6, 0], True) tup [ 1 ] . append ([ 9 ]) print ( tup ) # ('foo', [4, 5, 6, 0, [9]], True) \u4f7f\u7528tuple\u51fd\u6570\u5c06\u4efb\u610f\u5e8f\u5217\u6216\u8fed\u4ee3\u5668\u8f6c\u6362\u4e3a\u5143\u7ec4\u3002 tup = tuple ([ 4 , 5 , 6 ]) print ( tup ) # (4, 5, 6) tup = tuple ( 'string' ) print ( tup ) # ('s', 't', 'r', 'i', 'n', 'g') print ( tup [ 2 ]) # r # \u5143\u7ec4\u7684\u5143\u7d20\u53ef\u4ee5\u901a\u8fc7\u4e2d\u62ec\u53f7[]\u6765\u83b7\u53d6 \u5982\u679c\u8981\u5c06\u5143\u7ec4\u578b\u7684\u8868\u8fbe\u5f0f\u8d4b\u503c\u7ed9\u53d8\u91cf\uff0cPython\u4f1a\u5bf9\u7b49\u53f7\u53f3\u8fb9\u7684\u503c\u8fdb\u884c \u62c6\u5305 \u3002 tup = ( 9 , 5 , ( 8 , 7 )) a , b , c = tup print ( a ) # 9 print ( b ) # 5 print ( c ) # (8, 7) a , b , ( c , d ) = tup print ( a ) # 9 print ( b ) # 5 print ( c ) # 8 print ( d ) # 7 tup = ( 9 , 5 , ( 8 , 7 )) a , b , c = tup c , a = a , c # \u5229\u7528\u62c6\u5305\u5b9e\u73b0\u4ea4\u6362 print ( a ) # (8, 7) print ( b ) # 5 print ( c ) # 9 \u5229\u7528\u62c6\u5305\u5b9e\u73b0\u904d\u5386\u5143\u7ec4\u6216\u5217\u8868\u7ec4\u6210\u7684\u5e8f\u5217\u3002 seq = [( 1 , 2 , 3 ), ( 4 , 5 , 6 ), ( 7 , 8 , 9 )] for a , b , c in seq : print ( 'a= {0} , b= {0} , c= {0} ' . format ( a , b , c )) # \u5217\u8868\u6bcf\u4e2a\u5143\u7d20\u7684\u53d6\u503c\u987a\u5e8f # a=1, b=1, c=1 # a=4, b=4, c=4 # a=7, b=7, c=7 print ( 'a= {0} , b= {1} , c= {2} ' . format ( a , b , c )) # a=1, b=2, c=3 # a=4, b=5, c=6 # a=7, b=8, c=9 print ( 'a= {2} , b= {0} , c= {1} ' . format ( a , b , c )) # a=3, b=1, c=2 # a=6, b=4, c=5 # a=9, b=7, c=8 \u5143\u7ec4\u62c6\u5305\u529f\u80fd\u8fd8\u5305\u62ec\u7279\u6b8a\u7684\u8bed\u6cd5*rest\u3002\u5f88\u591aPython\u7f16\u7a0b\u8005\u4f1a\u4f7f\u7528\u4e0b\u5212\u7ebf\uff08_\uff09\u6765\u8868\u793a\u4e0d\u60f3\u8981\u7684\u53d8\u91cf\u3002 values = 1 , 2 , 3 , 4 , 5 a , b , * rest = values print ( a ) # 1 print ( b ) # 2 print ( * rest ) # 3 4 5 a , b , * _ = values print ( * _ ) # 3 4 5 \u5177\u540d\u5143\u7ec4\u3002 collections.namedtuple \u662f\u4e00\u4e2a\u5de5\u5382\u51fd\u6570\uff0c\u5b83\u53ef\u4ee5\u7528\u6765\u6784\u5efa\u4e00\u4e2a\u5e26\u5b57\u6bb5\u540d\u7684\u5143\u7ec4\u548c\u4e00\u4e2a\u6709\u540d\u5b57\u7684\u7c7b\u3002 \u7528namedtuple\u6784\u5efa\u7684\u7c7b\u7684\u5b9e\u4f8b\u6240\u6d88\u8017\u7684\u5185\u5b58\u8ddf\u5143\u7ec4\u662f\u4e00\u6837\u7684\uff0c\u56e0\u4e3a\u5b57\u6bb5\u540d\u90fd\u88ab\u5b58\u5728\u5bf9\u5e94\u7684\u7c7b\u91cc\u9762\u3002 \u521b\u5efa\u4e00\u4e2a\u5177\u540d\u5143\u7ec4\u9700\u8981\u4e24\u4e2a\u53c2\u6570\uff0c\u4e00\u4e2a\u662f\u7c7b\u540d( City )\uff0c\u53e6\u4e00\u4e2a\u662f\u7c7b\u7684\u5404\u4e2a\u5b57\u6bb5\u7684\u540d\u5b57( 'name country population coordinates' )\u3002\u540e\u8005\u53ef\u4ee5\u662f\u7531\u6570\u4e2a\u5b57\u7b26\u4e32\u7ec4\u6210\u7684\u53ef\u8fed\u4ee3\u5bf9\u8c61\uff0c\u6216\u8005\u662f\u7531\u7a7a\u683c\u5206\u9694\u5f00\u7684\u5b57\u6bb5\u540d\u7ec4\u6210\u7684\u5b57\u7b26\u4e32\u3002 \u5b58\u653e\u5728\u5bf9\u5e94\u5b57\u6bb5\u91cc\u7684\u6570\u636e\u8981\u4ee5\u4e00\u4e32\u53c2\u6570\u7684\u5f62\u5f0f\u4f20\u5165\u5230\u6784\u9020\u51fd\u6570\u4e2d\uff08\u6ce8\u610f\uff0c\u5143\u7ec4\u7684\u6784\u9020\u51fd\u6570\u5374\u53ea\u63a5\u53d7\u5355\u4e00\u7684\u53ef\u8fed\u4ee3\u5bf9\u8c61\uff09\u3002 \u5177\u540d\u5143\u7ec4\u8fd8\u6709\u4e00\u4e9b\u81ea\u5df1\u4e13\u6709\u7684\u5c5e\u6027\u3002\u4e0b\u9762\u5c55\u793a\u4e86\u51e0\u4e2a\u6700\u6709\u7528\u7684\uff1a _fields \u7c7b\u5c5e\u6027\u3001\u7c7b\u65b9\u6cd5 _make(iterable) \u548c\u5b9e\u4f8b\u65b9\u6cd5 _asdict() \u3002 _fields \u5c5e\u6027\u662f\u4e00\u4e2a\u5305\u542b\u8fd9\u4e2a\u7c7b\u6240\u6709\u5b57\u6bb5\u540d\u79f0\u7684\u5143\u7ec4\u3002 \u7528 _make() \u901a\u8fc7\u63a5\u53d7\u4e00\u4e2a\u53ef\u8fed\u4ee3\u5bf9\u8c61\u6765\u751f\u6210\u8fd9\u4e2a\u7c7b\u7684\u4e00\u4e2a\u5b9e\u4f8b\uff0c\u5b83\u7684\u4f5c\u7528\u8ddf City(*delhi_data) \u662f\u4e00\u6837\u7684\u3002 _asdict() \u628a\u5177\u540d\u5143\u7ec4\u4ee5 collections.OrderedDict \u7684\u5f62\u5f0f\u8fd4\u56de\uff0c\u6211\u4eec\u53ef\u4ee5\u5229\u7528\u5b83\u6765\u628a\u5143\u7ec4\u91cc\u7684\u4fe1\u606f\u53cb\u597d\u5730\u5448\u73b0\u51fa\u6765\u3002 from collections import namedtuple City = namedtuple ( 'City' , 'name country population coordinates' ) tokyo = City ( 'Tokyo' , 'JP' , 36.933 , ( 35.689722 , 139691667 )) print ( tokyo ) # City(name='Tokyo', country='JP', population=36.933, coordinates=(35.689722, 139691667)) print ( tokyo . population ) # 36.933 print ( tokyo [ 3 ]) # (35.689722, 139691667) print ( City . _fields ) # ('name', 'country', 'population', 'coordinates') LatLong = namedtuple ( 'LatLong' , 'lat long' ) delhi_data = ( 'Delhi NCR' , 'IN' , 21.935 , LatLong ( 28.613899 , 77.208889 )) delhi = City . _make ( delhi_data ) print ( delhi ) # City(name='Delhi NCR', country='IN', population=21.935, coordinates=LatLong(lat=28.613899, long=77.208889)) print ( delhi . _asdict ()) # OrderedDict([('name', 'Delhi NCR'), ('country', 'IN'), ('population', 21.935), ('coordinates', LatLong(lat=28.613899, long=77.208889))]) for key , value in delhi . _asdict () . items (): print ( key + ':' , value ) # name: Delhi NCR # country: IN # population: 21.935 # coordinates: LatLong(lat=28.613899, long=77.208889) \u5143\u7ec4\u8fd8\u6709\u7b2c\u4e8c\u91cd\u529f\u80fd\uff1a\u4f5c\u4e3a\u4e0d\u53ef\u53d8\u5217\u8868\u7684\u5143\u7ec4\u3002 \u4e0b\u9762\u662f\u5217\u8868\u6216\u5143\u7ec4\u7684\u65b9\u6cd5\u548c\u5c5e\u6027\u5bf9\u6bd4\u3002\u9664\u4e86\u8ddf\u589e\u51cf\u5143\u7d20\u76f8\u5173\u7684\u65b9\u6cd5\u4e4b\u5916\uff0c\u5143\u7ec4\u652f\u6301\u5217\u8868\u7684\u5176\u4ed6\u6240\u6709\u65b9\u6cd5\u3002\u8fd8\u6709\u4e00\u4e2a\u4f8b\u5916\uff0c\u5143\u7ec4\u6ca1\u6709__reversed__\u65b9\u6cd5\u3002 \u4e00\u4e2a\u5173\u4e8e+=\u548c*=\u7684\u8c1c\u9898\u3002 \u4e0b\u9762\u7684\u4f8b\u5b50\u5c55\u793a\u4e86 *= \u5728\u53ef\u53d8\u548c\u4e0d\u53ef\u53d8\u5e8f\u5217\u4e0a\u7684\u4f5c\u7528\u3002\u5217\u8868\u7684ID\u6ca1\u53d8\uff0c\u65b0\u5143\u7d20\u8ffd\u52a0\u5230\u5217\u8868\u4e0a\uff0c\u4f46\u6267\u884c\u589e\u91cf\u4e58\u6cd5\u540e\uff0c\u65b0\u7684\u5143\u7ec4\u88ab\u521b\u5efa\u3002 list1 = [ 1 , 2 , 3 , 4 ] id ( list1 ) # 140409777308808 list1 *= 2 print ( list1 ) # [1, 2, 3, 4, 1, 2, 3, 4] id ( list1 ) # 140409777308808 tuple1 = ( 1 , 2 , 3 , 4 ) id ( tuple1 ) # 140409777230536 tuple1 *= 2 print ( tuple1 ) # (1, 2, 3, 4, 1, 2, 3, 4) id ( tuple1 ) # 140409780104888 \u4f46\u5bf9\u4e8e\u4e0b\u9762\u7684\u4f8b\u5b50\uff0c\u867d\u7136 tuple1[2] += [50, 60] \u6267\u884c\u65f6\u6709\u5f02\u5e38\u629b\u51fa\uff0c\u4f46 tuple1 \u5374\u88ab\u4fee\u6539\u4e86\u3002 t = ( 1 , 2 , [ 10 , 20 ]) t [ 2 ] += [ 50 , 60 ] # TypeError: 'tuple' object does not support item assignment print ( t ) # (1, 2, [10, 20, 50, 60]) \u4e0b\u56fe\u5927\u81f4\u63cf\u8ff0\u4e86\u4e0a\u8ff0\u6267\u884c\u8fc7\u7a0b\u3002 \u4e3a\u4e86\u907f\u514d\u4e0a\u9762\u60c5\u51b5\u7684\u53d1\u751f\uff0c\u6211\u4eec**\u4e0d\u8981\u628a\u53ef\u53d8\u5bf9\u8c61\u653e\u5728\u5143\u7ec4\u91cc\u9762**\u3002\u589e\u91cf\u8d4b\u503c\u4e0d\u662f\u4e00\u4e2a\u539f\u5b50\u64cd\u4f5c\uff0c\u5b83\u867d\u7136\u629b\u51fa\u4e86\u5f02\u5e38\uff0c\u4f46\u8fd8\u662f\u5b8c\u6210\u4e86\u64cd\u4f5c\u3002","title":"1.6 \u5143\u7ec4\uff08tuple\uff09"},{"location":"python/Foundation/ch01/#17-memoryview","text":"memoryview \u662f\u4e00\u4e2a\u5185\u7f6e\u7c7b\uff0c\u5b83\u80fd\u8ba9\u7528\u6237\u5728\u4e0d\u590d\u5236\u5185\u5bb9\u7684\u60c5\u51b5\u4e0b\u64cd\u4f5c\u540c\u4e00\u4e2a\u6570\u7ec4\u7684\u4e0d\u540c\u5207\u7247\u3002 \u5185\u5b58\u89c6\u56fe\u5176\u5b9e\u662f\u6cdb\u5316\u548c\u53bb\u6570\u5b66\u5316\u7684NumPy\u6570\u7ec4\u3002\u5b83\u8ba9\u4f60\u5728\u4e0d\u9700\u8981\u590d\u5236\u5185\u5bb9\u7684\u524d\u63d0\u4e0b\uff0c\u5728\u6570\u636e\u7ed3\u6784\u4e4b\u95f4\u5171\u4eab\u5185\u5b58\u3002 \u5176\u4e2d\u6570\u636e\u7ed3\u6784\u53ef\u4ee5\u662f\u4efb\u4f55\u5f62\u5f0f\uff0c\u6bd4\u5982PIL\u56fe\u7247\u3001SQLite\u6570\u636e\u5e93\u548cNumPy\u7684\u6570\u7ec4\uff0c\u7b49\u7b49\u3002\u8fd9\u4e2a\u529f\u80fd\u5728\u5904\u7406\u5927\u578b\u6570\u636e\u96c6\u5408\u7684\u65f6\u5019\u975e\u5e38\u91cd\u8981\u3002 memoryview.cast \u7684\u6982\u5ff5\u8ddf\u6570\u7ec4\u6a21\u5757\u7c7b\u4f3c\uff0c\u80fd\u7528\u4e0d\u540c\u7684\u65b9\u5f0f\u8bfb\u5199\u540c\u4e00\u5757\u5185\u5b58\u6570\u636e\uff0c\u800c\u4e14\u5185\u5bb9\u5b57\u8282\u4e0d\u4f1a\u968f\u610f\u79fb\u52a8\u3002\u8fd9\u8ddfC\u8bed\u8a00\u4e2d\u7c7b\u578b\u8f6c\u6362\u7684\u6982\u5ff5\u5dee\u4e0d\u591a\u3002 memoryview.cast \u4f1a\u628a\u540c\u4e00\u5757\u5185\u5b58\u91cc\u7684\u5185\u5bb9\u6253\u5305\u6210\u4e00\u4e2a\u5168\u65b0\u7684memoryview\u5bf9\u8c61\u7ed9\u4f60\u3002 array \u91cc\u9762\u7684Type code\uff1a 'b' signed integer 1 'B' unsigned integer 1 'u' Unicode character 2 (see note) 'h' signed integer 2 'H' unsigned integer 2 'i' signed integer 2 'I' unsigned integer 2 'l' signed integer 4 'L' unsigned integer 4 'q' signed integer 8 (see note) 'Q' unsigned integer 8 (see note) 'f' floating point 4 'd' floating point 8 numbers = array ( 'h' , [ - 2 , - 1 , 0 , 1 , 2 ]) # array('h', [-2, -1, 0, 1, 2]) # \u75285\u4e2a\u77ed\u6574\u578b\u6709\u7b26\u53f7\u6574\u6570\u7684\u6570\u7ec4\uff08\u7c7b\u578b\u7801\u662f'h'\uff09\u521b\u5efa\u4e00\u4e2amemoryview\u3002 memv = memoryview ( numbers ) # memv\u91cc\u76845\u4e2a\u5143\u7d20\u8ddf\u6570\u7ec4\u91cc\u7684\u6ca1\u6709\u533a\u522b\u3002 print ( len ( memv )) # 5 print ( memv [ 0 ]) # -2 print ( memv . tolist ()) # [-2, -1, 0, 1, 2] # \u521b\u5efa\u4e00\u4e2amemv_oct\uff0c\u8fd9\u4e00\u6b21\u662f\u628amemv\u91cc\u7684\u5185\u5bb9\u8f6c\u6362\u6210'B'\u7c7b\u578b\uff0c\u4e5f\u5c31\u662f\u65e0\u7b26\u53f7\u5b57\u7b26\u3002 memv_oct = memv . cast ( 'B' ) print ( memv_oct . tolist ()) # [254, 255, 255, 255, 0, 0, 1, 0, 2, 0] # \u628a\u4f4d\u4e8e\u4f4d\u7f6e5\u7684\u5b57\u8282\u8d4b\u503c\u62104\u3002\u56e0\u4e3a\u6211\u4eec\u628a\u53602\u4e2a\u5b57\u8282\u7684\u6574\u6570\u7684\u9ad8\u4f4d\u5b57\u8282\u6539\u6210\u4e864\uff0c\u6240\u4ee5\u8fd9\u4e2a\u6709\u7b26\u53f7\u6574\u6570\u7684\u503c\u5c31\u53d8\u6210\u4e861024\u3002 memv_oct [ 5 ] = 4 print ( numbers ) # array('h', [-2, -1, 1024, 1, 2])","title":"1.7 \u5185\u5b58\u89c6\u56feMemoryview"},{"location":"python/Foundation/ch01/#2","text":"\u661f\u53f7 * \u7684\u53c2\u6570\u4f1a\u4ee5\u5143\u7ec4(tuple)\u7684\u5f62\u5f0f\u5bfc\u5165\uff0c\u5b58\u653e\u6240\u6709\u672a\u547d\u540d\u7684\u53d8\u91cf\u53c2\u6570 def printinfo ( arg1 , * vartuple ): print ( \"\u8f93\u51fa\u4efb\u4f55\u4f20\u5165\u7684\u53c2\u6570: \" ) print ( arg1 ) print ( vartuple ) for var in vartuple : print ( var ) return printinfo ( 10 ) # 10 # () printinfo ( 70 , 60 , 50 ) # 70 # (60, 50) # 60 # 50 \u4e24\u4e2a\u661f\u53f7 ** \u7684\u53c2\u6570\u4f1a\u4ee5\u5b57\u5178\u7684\u5f62\u5f0f\u5bfc\u5165\u3002 def printinfo ( arg1 , ** vardict ): print ( \"\u8f93\u51fa\u4efb\u4f55\u4f20\u5165\u7684\u53c2\u6570: \" ) print ( arg1 ) print ( vardict ) printinfo ( 1 , a = 2 , b = 3 ) # 1 # {'a': 2, 'b': 3} \u5b57\u5178\u683c\u5f0f\u8f93\u51fa Python\u4e2d\u7684\u5bf9\u8c61\u5f15\u7528\u5e76\u4e0d\u6d89\u53ca\u7c7b\u578b\u3002\u53d8\u91cf\u5bf9\u4e8e\u5bf9\u8c61\u6765\u8bf4\u53ea\u662f\u7279\u5b9a\u547d\u540d\u7a7a\u95f4\u4e2d\u7684\u540d\u79f0\uff1b\u7c7b\u578b\u4fe1\u606f\u662f\u5b58\u50a8\u5728\u5bf9\u8c61\u81ea\u8eab\u4e4b\u4e2d\u3002 a = 5 print ( type ( a )) # a = 'foo' print ( type ( a )) # Python\u662f\u5f3a\u7c7b\u578b\u8bed\u8a00\uff0c\u6240\u6709\u7684\u5bf9\u8c61\u90fd\u62e5\u6709\u4e00\u4e2a\u6307\u5b9a\u7684\u7c7b\u578b\uff08\u6216\u7c7b\uff09\uff0c\u9690\u5f0f\u7684\u8f6c\u6362\u53ea\u5728\u67d0\u4e9b\u7279\u5b9a\u3001\u660e\u663e\u7684\u60c5\u51b5\u4e0b\u53d1\u751f\u3002 a = 4.5 b = 2 print ( 'a is {0} , b is {1} ' . format ( type ( a ), type ( b ))) # a is , b is \u5b57\u4e32\u683c\u5f0f\u5316\uff0c\u7528\u4e8e\u540e\u7eed\u8bbf\u95ee print ( a / b ) # 2.25 \u4f7f\u7528isinstance\u51fd\u6570\u6765\u68c0\u67e5\u4e00\u4e2a\u5bf9\u8c61\u662f\u5426\u662f\u7279\u5b9a\u7c7b\u578b\u7684\u5b9e\u4f8b\u3002isinstance\u63a5\u53d7\u4e00\u4e2a\u5305\u542b\u7c7b\u578b\u7684\u5143\u7ec4\uff0c\u53ef\u4ee5\u68c0\u67e5\u5bf9\u8c61\u7684\u7c7b\u578b\u662f\u5426\u5728\u5143\u7ec4\u4e2d\u7684\u7c7b\u578b\u4e2d\u3002 a = 5 b = 4.5 c = 'foo' print ( isinstance ( a , int )) # True print ( isinstance ( b , str )) # False print ( isinstance ( c , ( str , int ))) # True print ( isinstance ( c , ( float , int ))) # False \u5c5e\u6027\u548c\u65b9\u6cd5\u4e5f\u53ef\u4ee5\u901a\u8fc7getattr\u51fd\u6570\u83b7\u5f97\u3002\u5728\u5176\u4ed6\u7684\u8bed\u8a00\u4e2d\uff0c\u901a\u8fc7\u53d8\u91cf\u540d\u8bbf\u95ee\u5bf9\u8c61\u901a\u5e38\u88ab\u79f0\u4e3a\u201c\u53cd\u5c04\u201d\u3002 b = 'foo' print ( getattr ( b , 'split' )) # ","title":"2. \u52a8\u6001\u5f15\u7528\u3001\u5f3a\u7c7b\u578b"},{"location":"python/Foundation/ch01/#3","text":"\u68c0\u67e5\u4e24\u4e2a\u5f15\u7528\u662f\u5426\u6307\u5411\u540c\u4e00\u4e2a\u5bf9\u8c61\uff0c\u53ef\u4ee5\u4f7f\u7528is\u5173\u952e\u5b57\u3002 is\u548cis not\u7684\u5e38\u7528\u4e4b\u5904\u662f\u68c0\u67e5\u4e00\u4e2a\u53d8\u91cf\u662f\u5426\u4e3aNone\uff0c\u56e0\u4e3aNone\u53ea\u6709\u4e00\u4e2a\u5b9e\u4f8b\u3002 a = [ 1 , 2 , 3 ] b = a c = list ( a ) # list\u51fd\u6570\u603b\u662f\u521b\u5efa\u4e00\u4e2a\u65b0\u7684Python\u5217\u8868\uff08\u5373\u4e00\u4efd\u62f7\u8d1d\uff09 print ( a is b ) # True print ( a is not c ) # True print ( a == c ) # True d = None print ( d is None ) # True Python\u4e2d\u7684\u5927\u90e8\u5206\u5bf9\u8c61\uff0c\u4f8b\u5982\u5217\u8868\u3001\u5b57\u5178\u3001NumPy\u6570\u7ec4\u90fd\u662f\u53ef\u53d8\u5bf9\u8c61\uff0c\u5927\u591a\u6570\u7528\u6237\u5b9a\u4e49\u7684\u7c7b\u578b\uff08\u7c7b\uff09\u4e5f\u662f\u53ef\u53d8\u7684\u3002 \u53ef\u53d8\u5bf9\u8c61\u4e2d\u5305\u542b\u7684\u5bf9\u8c61\u548c\u503c\u662f\u53ef\u4ee5\u88ab\u4fee\u6539\u7684\u3002\u8fd8\u6709\u5176\u4ed6\u4e00\u4e9b\u5bf9\u8c61\u662f\u4e0d\u53ef\u53d8\u7684\uff0c\u6bd4\u5982\u5b57\u7b26\u4e32\u3001\u5143\u7ec4\u3002 a_list = [ 'foo' , 2 , [ 4 , 5 ]] # \u5217\u8868 a_list [ 2 ] = ( 3 , 4 ) print ( a_list ) # ['foo', 2, (3, 4)] a_tuple = ( 3 , 5 , ( 4 , 5 )) # \u5143\u7ec4 a_tuple [ 1 ] = 'four' # TypeError: 'tuple' object does not support item assignment \u4e0d\u53ef\u88ab\u4fee\u6539 print ( a_tuple ) # (3, 5, (4, 5))","title":"3. \u4e8c\u5143\u8fd0\u7b97\u7b26\u548c\u6bd4\u8f83\u8fd0\u7b97"},{"location":"python/Foundation/ch01/#4","text":"Python\u6807\u91cf\u7c7b\u578b\uff1aNone, str, bytes, float, bool, int\u3002 \u6570\u503c\u7c7b\u578b\u3002 \u57fa\u7840\u7684Python\u6570\u5b57\u7c7b\u578b\u5c31\u662fint\u548cfloat\u3002int\u53ef\u4ee5\u5b58\u50a8\u4efb\u610f\u5927\u5c0f\u6570\u5b57\u3002\u6d6e\u70b9\u6570\u5728Python\u4e2d\u7528float\u8868\u793a\uff0c\u6bcf\u4e00\u4e2a\u6d6e\u70b9\u6570\u90fd\u662f\u53cc\u7cbe\u5ea664\u4f4d\u6570\u503c\u3002 ival = 17338971 print ( ival ** 6 ) # 27173145946003847721495630081806010734757321 fval = 17338971.0 print ( fval ** 6 ) # 2.7173145946003847e+43 print ( 3 / 2 ) # 1.5 print ( 3 // 2 ) # 1 \u5b57\u7b26\u4e32\u3002 Python\u7684\u5b57\u7b26\u4e32\u662f\u4e0d\u53ef\u53d8\u7684\u3002 a = 5.6 s = str ( a ) print ( s ) # 5.6 b = 'python' print ( list ( b )) # ['p', 'y', 't', 'h', 'o', 'n'] print ( b [ 2 ]) # t b [ 2 ] = 'f' # TypeError: 'str' object does not support item assignment \u5b57\u7b26\u4e32\u662f\u4e0d\u53ef\u53d8\u7684 \u53cd\u659c\u6760\u7b26\u53f7\\\u662f\u4e00\u79cd\u8f6c\u4e49\u7b26\u53f7\uff0c\u5b83\u7528\u6765\u6307\u660e\u7279\u6b8a\u7b26\u53f7\u3002 \u5982\u679c\u4f60\u6709\u4e00\u4e2a\u4e0d\u542b\u7279\u6b8a\u7b26\u53f7\u4f46\u542b\u6709\u5927\u91cf\u53cd\u659c\u6760\u7684\u5b57\u7b26\u4e32\u65f6\uff0c\u53ef\u4ee5\u5728\u5b57\u7b26\u4e32\u524d\u9762\u52a0\u4e00\u4e2a\u524d\u7f00\u7b26\u53f7r\uff0c\u8868\u660e\u8fd9\u4e9b\u5b57\u7b26\u662f\u539f\u751f\u5b57\u7b26\uff0cr\u662fraw\u7684\u7b80\u5199\uff0c\u8868\u793a\u539f\u751f\u7684\u3002 x = '12 \\\\ 34' y = r 'this\\has\\no\\special\\characters' print ( x ) # 12\\34 print ( y ) # this\\has\\no\\special\\characters \u5b57\u7b26\u4e32\u683c\u5f0f\u5316 {0:.2f}\u8868\u793a\u5c06\u7b2c\u4e00\u4e2a\u53c2\u6570\u683c\u5f0f\u5316\u4e3a2\u4f4d\u5c0f\u6570\u7684\u6d6e\u70b9\u6570 {1:s}\u8868\u793a\u5c06\u7b2c\u4e8c\u4e2a\u53c2\u6570\u683c\u5f0f\u5316\u4e3a\u5b57\u7b26\u4e32 {2:d}\u8868\u793a\u5c06\u7b2c\u4e09\u4e2a\u53c2\u6570\u683c\u5f0f\u5316\u6574\u6570 \u53c2\u8003Python\u5b98\u65b9\u6587\u6863 https://docs.python.org/3.6/library/string.html template = ' {0:.2f} {1:s} are worth US$ {2:d} ' print ( template . format ( 4.5560 , 'Argentine Pesos' , 1 )) # 4.56 Argentine Pesos are worth US$1 \u65e5\u671f\u548c\u65f6\u95f4 from datetime import datetime , date , time dt = datetime ( 2011 , 10 , 29 , 20 , 30 , 21 ) print ( dt . day ) # 29 print ( dt . minute ) # 30 print ( dt . date ()) # 2011-10-29 print ( dt . time ()) # 20:30:21 print ( dt . replace ( minute = 0 , second = 0 )) # 2011-10-29 20:00:00 \u5c06\u5206\u949f\u3001\u79d2\u66ff\u6362\u4e3a0 print ( datetime . strptime ( '20091021' , '%Y%m %d ' )) # 2009-10-21 00:00:00 \u5b57\u7b26\u4e32\u53ef\u4ee5\u901a\u8fc7 strptime \u51fd\u6570\u8f6c\u6362\u4e3adatetime\u5bf9\u8c61 dt2 = datetime ( 2011 , 11 , 15 , 22 , 30 ) delta = dt2 - dt print ( delta ) # 17 days, 1:59:39 print ( dt + delta ) # 2011-11-15 22:30:00 range\u51fd\u6570\u8fd4\u56de\u4e00\u4e2a\u8fed\u4ee3\u5668\uff0c\u8be5\u8fed\u4ee3\u5668\u751f\u6210\u4e00\u4e2a\u7b49\u5dee\u6574\u6570\u5e8f\u5217\u3002 print ( range ( 10 )) # range(0, 10) print ( list ( range ( 10 ))) # [0, 1, 2, 3, 4, 5, 6, 7, 8, 9] print ( list ( range ( 0 , 20 , 2 ))) # [0, 2, 4, 6, 8, 10, 12, 14, 16, 18]","title":"4. \u6807\u91cf\u7c7b\u578b"},{"location":"python/Foundation/ch01/#5","text":"value = true-expr if condition else false-expr x = 5 print ( 'non-negative' if x >= 0 else 'negative' ) # non-negative","title":"5. \u4e09\u5143\u8868\u8fbe\u5f0f"},{"location":"python/Foundation/ch02/","text":"Python\u6253\u5305\u548c\u89e3\u5305 \u00b6 \u89e3\u5305Unpacking \u00b6 Python \u5141\u8bb8\u53d8\u91cf\u7684\u5143\u7ec4\uff08\u6216\u5217\u8868\uff09\u51fa\u73b0\u5728\u8d4b\u503c\u64cd\u4f5c\u7684\u5de6\u4fa7\u3002 \u5143\u7ec4\u4e2d\u7684\u6bcf\u4e2a\u53d8\u91cf\u90fd\u53ef\u4ee5\u4ece\u8d4b\u503c\u53f3\u4fa7\u7684\u53ef\u8fed\u4ee3\u5bf9\u8c61\uff08iterable\uff09\u4e2d\u63a5\u6536\u4e00\u4e2a\u503c\uff08\u6216\u8005\u66f4\u591a\uff0c\u5982\u679c\u6211\u4eec\u4f7f\u7528 * \u8fd0\u7b97\u7b26\uff09\u3002 Python \u4e2d\u7684\u89e3\u5305\u662f\u6307\u4e00\u79cd\u64cd\u4f5c\uff0c\u8be5\u64cd\u4f5c\u5305\u62ec\u5728\u5355\u4e2a\u8d4b\u503c\u8bed\u53e5\u4e2d\u5c06\u53ef\u8fed\u4ee3\u7684\u503c\u5206\u914d\u7ed9\u53d8\u91cf\u7684\u5143\u7ec4\uff08\u6216\u5217\u8868\uff09\u3002 \u5728 Python \u4e2d\uff0c\u53ef\u4ee5\u5728\u8d4b\u503c\u8fd0\u7b97\u7b26 = \u7684\u5de6\u4fa7\u653e\u7f6e\u4e00\u4e2a\u53d8\u91cf\u5143\u7ec4\uff0c\u5728\u53f3\u4fa7\u653e\u7f6e\u4e00\u4e2a\u503c\u5143\u7ec4\u3002 \u53f3\u8fb9\u7684\u503c\u5c06\u6839\u636e\u5b83\u4eec\u5728\u5143\u7ec4\u4e2d\u7684\u4f4d\u7f6e\u81ea\u52a8\u5206\u914d\u7ed9\u5de6\u8fb9\u7684\u53d8\u91cf\u3002 \u8fd9\u5728 Python \u4e2d\u901a\u5e38\u79f0\u4e3a\u5143\u7ec4\u89e3\u5305\u3002 \u5982\u4e0b\u793a\u4f8b\uff1a >>> ( a , b , c ) = ( 1 , 2 , 3 ) >>> a 1 >>> b 2 >>> c 3 >>> birthday = ( 'April' , 5 , 2001 ) >>> month , day , year = birthday >>> month 'April' >>> day 5 >>> year 2001 \u5143\u7ec4\u89e3\u5305\u529f\u80fd\u5728 Python \u4e2d\u53ef\u4ee5\u6269\u5c55\u4e3a\u9002\u7528\u4e8e\u4efb\u4f55\u53ef\u8fed\u4ee3\u5bf9\u8c61\u3002 \u552f\u4e00\u7684\u8981\u6c42\u662f\u53ef\u8fed\u4ee3\u7684\u63a5\u6536\u5143\u7ec4\uff08\u6216\u5217\u8868\uff09\u4e2d\u7684\u6bcf\u4e2a\u53d8\u91cf\u6070\u597d\u5bf9\u5e94\u53ef\u8fed\u4ee3\u5bf9\u8c61\u7684\u4e00\u4e2a\u5143\u7d20\uff08item\uff09\u3002 \u4e0b\u9762\u7684\u793a\u4f8b\u4ecb\u7ecd\u4e86 Python \u4e2d\u53ef\u8fed\u4ee3\u89e3\u5305\u7684\u5de5\u4f5c\u539f\u7406\uff1a >>> # Unpackage strings >>> a , b , c = '123' >>> a '1' >>> b '2' >>> c '3' >>> # Unpacking lists >>> a , b , c = [ 1 , 2 , 3 ] >>> a 1 >>> b 2 >>> c 3 >>> # Unpacking generators >>> gen = ( i ** 2 for i in range ( 3 )) >>> a , b , c = gen >>> a 0 >>> b 1 >>> c 4 >>> # Upacking dictionaries (keys, values, and items) >>> my_dict = { 'one' : 1 , 'two' : 2 , 'three' : 3 } >>> a , b , c = my_dict >>> a 'one' >>> b 'two' >>> c 'three' >>> a , b , c = my_dict . values () >>> a 1 >>> b 2 >>> c 3 >>> a , b , c = my_dict . items () >>> a ( 'one' , 1 ) >>> b ( 'two' , 2 ) >>> c ( 'three' , 3 ) >>> # Use a tuple on the right side of assignment statement >>> [ a , b , c ] = 1 , 2 , 3 >>> a 1 >>> b 2 >>> c 3 >>> # Use range() iterator >>> x , y , z = range ( 3 ) >>> x 0 >>> y 1 >>> z 2 \u6253\u5305Packing \u00b6 \u6253\u5305\u53ef\u4ee5\u7406\u89e3\u4e3a\u4f7f\u7528\u53ef\u8fed\u4ee3\u89e3\u5305\u8fd0\u7b97\u7b26\u5728\u5355\u4e2a\u53d8\u91cf\u4e2d\u6536\u96c6\u591a\u4e2a\u503c\u3002\u5728\u8fd9\u79cd\u60c5\u51b5\u4e0b\uff0c * \u8fd0\u7b97\u7b26\u88ab\u79f0\u4e3a\u5143\u7ec4\uff08\u6216\u53ef\u8fed\u4ee3\uff09\u89e3\u5305\u8fd0\u7b97\u7b26\u3002 \u5b83\u6269\u5c55\u4e86\u89e3\u5305\u529f\u80fd\uff0c\u5141\u8bb8\u5728\u5355\u4e2a\u53d8\u91cf\u4e2d\u6536\u96c6\u6216\u6253\u5305\u591a\u4e2a\u503c\u3002 \u5728\u4ee5\u4e0b\u793a\u4f8b\u4e2d\u53ef\u4ee5\u770b\u5230 * \u8fd0\u7b97\u7b26\u5c06\u5143\u7ec4\u503c\u6253\u5305\u5230\u5355\u4e2a\u53d8\u91cf\u4e2d\uff1a >>> # The right side is a tuple, the left side is a list >>> * a , = 1 , 2 >>> a [ 1 , 2 ] >>> type ( a ) < class ' list '> \u5728\u4e0a\u9762\u7684\u4ee3\u7801\u4e2d\uff0c\u8d4b\u503c\u7684\u5de6\u4fa7\u5fc5\u987b\u662f\u5143\u7ec4\uff08\u6216\u5217\u8868\uff09\uff0c\u8fd9\u5c31\u662f\u4f7f\u7528\u5c3e\u968f\u9017\u53f7\u7684\u539f\u56e0\u3002\u8fd9\u4e2a\u5143\u7ec4\u53ef\u4ee5\u5305\u542b\u6240\u9700\u8981\u7684\u5c3d\u53ef\u80fd\u591a\u7684\u53d8\u91cf\uff0c\u4f46\u662f\uff0c\u5b83\u53ea\u80fd\u5305\u542b\u4e00\u4e2a\u661f\u53f7\u8868\u8fbe\u5f0f(starred expression)\u3002 >>> # Packing trailing values >>> a , * b = 1 , 2 , 3 >>> a 1 >>> b [ 2 , 3 ] >>> type ( a ) < class ' int '> >>> type ( b ) < class ' list '> >>> >>> * a , b , c = 1 , 2 , 3 >>> a [ 1 ] >>> b 2 >>> c 3 >>> * a , b , c , d , e = 1 , 2 , 3 Traceback ( most recent call last ): File \"\" , line 1 , in < module > ValueError : not enough values to unpack ( expected at least 4 , got 3 ) >>> * a , b , c , d = 1 , 2 , 3 >>> a [] >>> b 1 >>> c 2 >>> d 3 >>> >>> seq = [ 1 , 2 , 3 , 4 ] >>> first , * body , last = seq >>> first , body , last ( 1 , [ 2 , 3 ], 4 ) >>> first , body , * last = seq >>> first , body , last ( 1 , 2 , [ 3 , 4 ]) >>> >>> ran = range ( 10 ) >>> * r , = ran >>> r [ 0 , 1 , 2 , 3 , 4 , 5 , 6 , 7 , 8 , 9 ] \u4e0b\u9762\u662f\u4e00\u4e9b\u6253\u5305\u548c\u89e3\u5305\u7684\u4f8b\u5b50\u3002 >>> employee = [ 'John Doe' , '40' , 'Software Engineer' ] >>> name = employee [ 0 ] >>> age = employee [ 1 ] >>> job = employee [ 2 ] >>> name 'John Doe' >>> age '40' >>> job 'Software Engineer' >>> >>> name , age , job = [ 'John Doe' , '40' , 'Software Engineer' ] >>> name 'John Doe' >>> age '40' >>> job 'Software Engineer' >>> >>> a = 100 >>> b = 200 >>> a , b = b , a >>> a 200 >>> b 100 \u4f7f\u7528 * \u5220\u9664\u4e0d\u9700\u8981\u7684\u503c\u3002 >>> a , b , * _ = 1 , 2 , 0 , 0 , 0 , 0 >>> a 1 >>> b 2 >>> _ [ 0 , 0 , 0 , 0 ] \u5728\u4e0a\u4f8b\u4e2d\uff0c\u4e0d\u9700\u8981\u7684\u4fe1\u606f\u5b58\u50a8\u5728\u865a\u62df\u53d8\u91cf _ \u4e2d\uff0c\u5728\u540e\u7eed\u7684\u4f7f\u7528\u4e2d\u53ef\u4ee5\u5ffd\u7565\u5b83\u3002 \u9ed8\u8ba4\u60c5\u51b5\u4e0b\uff0cPython \u89e3\u91ca\u5668\u4f7f\u7528\u4e0b\u5212\u7ebf\u5b57\u7b26 _ \u6765\u5b58\u50a8\u5728\u4ea4\u4e92\u5f0f\u4f1a\u8bdd\u4e2d\u8fd0\u884c\u7684\u8bed\u53e5\u7684\u7ed3\u679c\u503c\u3002 \u56e0\u6b64\uff0c\u5728\u8fd9\u79cd\u60c5\u51b5\u4e0b\uff0c\u4f7f\u7528\u8fd9\u4e2a\u5b57\u7b26\u6765\u8bc6\u522b\u865a\u62df\u53d8\u91cf\u53ef\u80fd\u662f\u6a21\u68f1\u4e24\u53ef\u7684\u3002 \u5728\u51fd\u6570\u4e2d\u8fd4\u56de\u5143\u7ec4\u3002 >>> def powers ( num ): ... return num , num ** 2 , num ** 3 ... >>> # Packaging returned values in a tuple >>> result = powers ( 3 ) >>> result ( 3 , 9 , 27 ) >>> # Unpacking returned values to multiple variables >>> number , square , cube = powers ( 3 ) >>> number 3 >>> square 9 >>> cube 27 >>> * _ , cube = powers ( 3 ) >>> cube 27 \u4f7f\u7528 * \u548c ** \u8fd0\u7b97\u7b26 \u00b6 \u4f7f\u7528 * \u8fd0\u7b97\u7b26\u5408\u5e76\u8fed\u4ee3\u53d8\u91cf\uff08iterables\uff09\u3002\u4e0a\u9762\u4e24\u4e2a\u4f8b\u5b50\u8bf4\u660e\uff0c\u8fd9\u4e2d\u65b9\u6cd5\u4e5f\u662f\u8fde\u63a5\u8fed\u4ee3\u53d8\u91cf\uff08iterables\uff09\u7684\u4e00\u79cd\u66f4\u6613\u8bfb\u548c\u66f4\u6709\u6548\u7684\u65b9\u6cd5\u3002 \u8fd9\u4e2a\u65b9\u6cd5 (my_set) + my_list + list(my_tuple) + list(range(1, 4)) + list(my_str) \u53ef\u4ee5\u751f\u6210\u4e00\u4e2a\u5217\u8868 \uff0c\u4e5f\u53ef\u4ee5\u4f7f\u7528\u66f4\u7b80\u6d01\u7684\u65b9\u6cd5 [*my_set, *my_list, *my_tuple, *range(1, 4), *my_str] \u3002 >>> my_tuple = ( 1 , 2 , 3 ) >>> ( 0 , * my_tuple , 4 ) ( 0 , 1 , 2 , 3 , 4 ) >>> my_list = [ 1 , 2 , 3 ] >>> [ 0 , * my_list , 4 ] [ 0 , 1 , 2 , 3 , 4 ] >>> my_set = { 1 , 2 , 3 } >>> { 0 , * my_set , 4 } { 0 , 1 , 2 , 3 , 4 } >>> [ * my_set , * my_list , * my_tuple , * range ( 1 , 4 )] [ 1 , 2 , 3 , 1 , 2 , 3 , 1 , 2 , 3 , 1 , 2 , 3 ] >>> my_str = \"123\" >>> [ * my_set , * my_list , * my_tuple , * range ( 1 , 4 ), * my_str ] [ 1 , 2 , 3 , 1 , 2 , 3 , 1 , 2 , 3 , 1 , 2 , 3 , '1' , '2' , '3' ] \u4f7f\u7528 ** \u8fd0\u7b97\u7b26\u89e3\u5305\u5b57\u5178\u3002 >>> numbers = { 'one' : 1 , 'two' : 2 , 'three' : 3 } >>> letters = { 'a' : 'A' , 'b' : 'B' , 'c' : 'C' } >>> combination = { ** numbers , ** letters } >>> combination { 'one' : 1 , 'two' : 2 , 'three' : 3 , 'a' : 'A' , 'b' : 'B' , 'c' : 'C' } \u9700\u8981\u6ce8\u610f\u7684\u91cd\u8981\u4e00\u70b9\u662f\uff0c\u5982\u679c\u6211\u4eec\u5408\u5e76\u7684\u5b57\u5178\u5177\u6709\u91cd\u590d\u952e\u6216\u516c\u5171\u952e\uff0c\u5219\u6700\u53f3\u4fa7\u5b57\u5178\u7684\u503c\u5c06\u8986\u76d6\u6700\u5de6\u4fa7\u5b57\u5178\u7684\u503c\u3002\u4f8b\u5982: >>> letters = { 'a' : 'A' , 'b' : 'B' , 'c' : 'C' } >>> vowels = { 'a' : 'a' , 'e' : 'e' , 'i' : 'i' , 'o' : 'o' , 'u' : 'u' } >>> { ** letters , ** vowels } { 'a' : 'a' , 'b' : 'B' , 'c' : 'C' , 'e' : 'e' , 'i' : 'i' , 'o' : 'o' , 'u' : 'u' } >>> { ** vowels , ** letters } { 'a' : 'A' , 'e' : 'e' , 'i' : 'i' , 'o' : 'o' , 'u' : 'u' , 'b' : 'B' , 'c' : 'C' } \u901a\u8fc7 For-Loops \u89e3\u5305 \u00b6 \u6211\u4eec\u8fd8\u53ef\u4ee5\u5728 for \u5faa\u73af\u7684\u4e0a\u4e0b\u6587\u4e2d\u4f7f\u7528\u53ef\u8fed\u4ee3\u89e3\u5305\u3002 \u5f53\u6211\u4eec\u8fd0\u884c for \u5faa\u73af\u65f6\uff0c\u5728\u6bcf\u6b21\u5faa\u73af\u8fed\u4ee3\u4e2d\u5c06\u5176\u53ef\u8fed\u4ee3\u5bf9\u8c61\u4e2d\u7684\u4e00\u9879(item)\u5206\u914d\u7ed9\u76ee\u6807\u53d8\u91cf\u3002 \u5982\u679c\u8981\u5206\u914d\u7684\u9879(item)\u662f\u53ef\u8fed\u4ee3\u7684\uff0c\u90a3\u4e48\u6211\u4eec\u53ef\u4ee5\u4f7f\u7528\u5143\u7ec4\u4f5c\u4e3a\u76ee\u6807\u53d8\u91cf\uff0c\u901a\u8fc7\u5faa\u73af\u5c06\u53ef\u8fed\u4ee3\u5bf9\u8c61\u89e3\u5305\u5230\u76ee\u6807\u53d8\u91cf\u7684\u5143\u7ec4\u4e2d\u3002 \u4f8b\u5982\uff0c\u6211\u4eec\u53ef\u4ee5\u6784\u5efa\u4e00\u4e2a\u5305\u542b\u4e24\u4e2a\u5143\u7d20\u7684\u5143\u7ec4\u7684\u5217\u8868\u3002 \u6bcf\u4e2a\u5143\u7ec4\u5c06\u5305\u542b\u4ea7\u54c1\u540d\u79f0\u3001\u4ef7\u683c\u548c\u9500\u552e\u5355\u4f4d\uff0c\u6211\u4eec\u901a\u8fc7 for \u5faa\u73af\u904d\u5386\u6bcf\u4e2a\u5143\u7ec4\u5143\u7d20\u6765\u8ba1\u7b97\u6bcf\u4e2a\u4ea7\u54c1\u7684\u6536\u5165\u3002 >>> sales = [( 'Pencle' , 0.22 , 1500 ), ( 'Notebook' , 1.30 , 550 ), ( 'Eraser' , 0.75 , 1000 )] >>> for items in sales : ... print ( f \"Income for { items [ 0 ] } is: { items [ 1 ] * items [ 2 ] } \" ) ... Income for Pencle is : 330.0 Income for Notebook is : 715.0 Income for Eraser is : 750.0 \u6211\u4eec\u53ef\u4ee5\u4f7f\u7528\u7d22\u5f15\u6765\u8bbf\u95ee\u6bcf\u4e2a\u5143\u7ec4\u7684\u5404\u4e2a\u5143\u7d20\u3002\u4e0b\u9762\u7684\u793a\u4f8b\u4ee3\u7801\u4e2d\uff0c\u5728 for \u5faa\u73af\u4f7f\u7528\u89e3\u5305\uff0c\u8fd9\u4e5f\u662f Python \u4e2d\u89e3\u5305\u7684\u4e00\u79cd\u5b9e\u73b0\u3002 >>> sales = [( 'Pencle' , 0.22 , 1500 ), ( 'Notebook' , 1.30 , 550 ), ( 'Eraser' , 0.75 , 1000 )] >>> for product , price , sold_units in sales : ... print ( f \"Income for { product } is: { price * sold_units } \" ) ... Income for Pencle is : 330.0 Income for Notebook is : 715.0 Income for Eraser is : 750.0 \u4e5f\u53ef\u4ee5\u5728 for \u5faa\u73af\u4e2d\u4f7f\u7528 * \u8fd0\u7b97\u7b26\u5c06\u591a\u4e2a\u9879\u6253\u5305\u5230\u5355\u4e2a\u76ee\u6807\u53d8\u91cf\u4e2d\u3002 \u5728\u4e0b\u9762\u8fd9\u4e2a\u4f8b\u5b50\u4e2d\uff0c\u6211\u4eec\u9996\u5148\u53d6\u5f97\u6bcf\u4e2a\u5e8f\u5217\u7684\u7b2c\u4e00\u4e2a\u5143\u7d20\u3002 \u5176\u4f59\u503c\u901a\u8fc7 * \u8fd0\u7b97\u7b26\u8d4b\u7ed9\u76ee\u6807\u53d8\u91cf rest \u3002 >>> for first , * rest in [( 1 , 2 , 3 ),( 4 , 5 , 6 )]: ... print ( 'First: ' , first ) ... print ( 'Rest: ' , rest ) ... First : 1 Rest : [ 2 , 3 ] First : 4 Rest : [ 5 , 6 ] >>> \u76ee\u6807\u53d8\u91cf\u7684\u7ed3\u6784\u5fc5\u987b\u4e0e\u53ef\u8fed\u4ee3\u5bf9\u8c61\u7684\u7ed3\u6784\u4e00\u81f4\uff0c\u5426\u5219\u4f1a\u62a5\u9519\u3002\u770b\u4e0b\u9762\u7684\u4f8b\u5b50\u3002 >>> data = [(( 1 , 2 ), 3 ), (( 2 , 3 ), 3 )] >>> for ( a , b ), c in data : ... print ( a , b , c ) ... 1 2 3 2 3 3 >>> for a , b , c in data : ... print ( a , b , c ) ... Traceback ( most recent call last ): File \"\" , line 1 , in < module > ValueError : not enough values to unpack ( expected 3 , got 2 ) \u7528 * \u548c ** \u5b9a\u4e49\u51fd\u6570 \u00b6 \u4e0b\u9762\u4f8b\u5b50\u4e2d\u7684\u51fd\u6570func\u81f3\u5c11\u9700\u8981\u4e00\u4e2a\u540d\u4e3a required \u7684\u53c2\u6570\u3002 \u5b83\u4e5f\u53ef\u4ee5\u63a5\u53d7\u4e00\u4e2a\u6216\u591a\u4e2a\u4f4d\u7f6e\u53c2\u6570\u6216\u5173\u952e\u5b57\u53c2\u6570\u3002 \u5728\u8fd9\u79cd\u60c5\u51b5\u4e0b\uff0c * \u8fd0\u7b97\u7b26\u5728\u4e00\u4e2a\u53eb args \u7684\u5143\u7ec4\u4e2d\u6536\u96c6\u6216\u6253\u5305\u989d\u5916\u7684\u4f4d\u7f6e\u53c2\u6570\uff0c\u800c ** \u8fd0\u7b97\u7b26\u5728\u4e00\u4e2a\u53eb kwargs \u7684\u5b57\u5178\u4e2d\u6536\u96c6\u6216\u6253\u5305\u989d\u5916\u7684\u5173\u952e\u5b57\u53c2\u6570\u3002 args \u548c kwargs \u90fd\u662f\u53ef\u9009\u7684\uff0c\u5e76\u4e14\u5206\u522b\u81ea\u52a8\u9ed8\u8ba4\u4e3a\u5143\u7ec4 () \u548c\u5b57\u5178 {} \u3002 \u8fd9\u91cc args \u548c kwargs \u7684\u547d\u540d\u5e76\u4e0d\u662f\u5fc5\u987b\u7684\uff0c\u8bed\u6cd5\u4e0a\u53ea\u9700\u8981 * \u6216 ** \u540e\u8ddf\u6709\u6548\u6807\u8bc6\u7b26\u5373\u53ef\uff0c\u5efa\u8bae\u7ed9\u53d8\u91cf\u8d77\u4e2a\u6709\u610f\u4e49\u7684\u540d\u5b57\uff0c\u63d0\u9ad8\u4ee3\u7801\u7684\u53ef\u8bfb\u6027\u3002 >>> def func ( required , * args , ** kwargs ): ... print ( required ) ... print ( args ) ... print ( kwargs ) ... >>> func ( 'Welcome to ...' , 1 , 2 , 3 , site = 'CloudAcademy.com' ) Welcome to ... ( 1 , 2 , 3 ) { 'site' : 'CloudAcademy.com' } >>> func ( 'Welcome to ...' , 1 , 2 , 3 , 4 ) Welcome to ... ( 1 , 2 , 3 , 4 ) {} >>> func ( 'Welcome to ...' , 1 , 2 , 3 , ( 1 , 2 )) Welcome to ... ( 1 , 2 , 3 , ( 1 , 2 )) {} >>> func ( 'Welcome to ...' , 1 , 2 , 3 , [ 1 , 2 ]) Welcome to ... ( 1 , 2 , 3 , [ 1 , 2 ]) {} >>> func ( 'Welcome to ...' , 1 , 2 , 3 , ([ 2 , 3 ], [ 1 , 2 ])) Welcome to ... ( 1 , 2 , 3 , ([ 2 , 3 ], [ 1 , 2 ])) {} \u4f7f\u7528 * \u548c ** \u8c03\u7528\u51fd\u6570 \u00b6 \u8c03\u7528\u51fd\u6570\u65f6\uff0c\u6211\u4eec\u8fd8\u53ef\u4ee5\u53d7\u76ca\u4e8e\u4f7f\u7528 * \u548c ** \u8fd0\u7b97\u7b26\u5c06\u53c2\u6570\u96c6\u5408\u5206\u522b\u89e3\u538b\u7f29\u4e3a\u5355\u72ec\u7684\u4f4d\u7f6e\u53c2\u6570\u6216\u5173\u952e\u5b57\u53c2\u6570\u3002 \u8fd9\u4e0e\u5728\u51fd\u6570\u7b7e\u540d(signature of a function)\u4e2d\u4f7f\u7528 * \u548c ** \u662f\u76f8\u53cd\u7684\u3002 \u5728\u51fd\u6570\u7b7e\u540d\u4e2d\uff0c\u8fd0\u7b97\u7b26\u7684\u610f\u601d\u662f\u5728\u4e00\u4e2a\u6807\u8bc6\u7b26\u4e2d\u6536\u96c6\u6216\u6253\u5305\u53ef\u53d8\u6570\u91cf\u7684\u53c2\u6570\u3002 \u5728\u8c03\u7528(calling)\u4e2d\uff0c\u5b83\u4eec\u7684\u610f\u601d\u662f\u89e3\u5305(unpack)\u4e00\u4e2a\u53ef\u8fed\u4ee3\u5bf9\u8c61\u5230\u591a\u4e2a\u53c2\u6570\u4e2d\u3002 \u7eed\u4e0a\u4f8b\uff0c * \u8fd0\u7b97\u7b26\u5c06\u50cf [\"Welcome\", \"to\"] \u8fd9\u6837\u7684\u5e8f\u5217\u89e3\u5305\u5230\u4f4d\u7f6e\u53c2\u6570\u4e2d\u3002 \u7c7b\u4f3c\u5730\uff0c ** \u8fd0\u7b97\u7b26\u5c06\u5b57\u5178\u89e3\u5305\u4e3a\u4e0e\u5b57\u5178\u7684\u952e\u503c\u5339\u914d\u7684\u53c2\u6570\u540d\u3002 >>> def func ( welcome , to , site ): ... print ( welcome , to , site ) ... >>> func ( * [ 'Welcome' , 'to' ], ** { 'site' : 'CloudAcademy.com' }) Welcome to CloudAcademy . com \u7efc\u5408\u8fd0\u7528\u524d\u9762\u7684\u65b9\u6cd5\u6765\u7f16\u5199\u975e\u5e38\u7075\u6d3b\u7684\u51fd\u6570\uff0c\u6bd4\u5982\uff0c\u5728\u5b9a\u4e49\u548c\u8c03\u7528 Python \u51fd\u6570\u65f6\uff0c\u66f4\u7075\u6d3b\u7684\u4f7f\u7528 * \u548c ** \u8fd0\u7b97\u7b26\u3002 \u4f8b\u5982\uff1a >>> def func ( required , * args , ** kwargs ): ... print ( required ) ... print ( args ) ... print ( kwargs ) ... >>> func ( 'Welcome to...' , * ( 1 , 2 , 3 ), ** { 'Site' : 'CloudAcademy.com' }) Welcome to ... ( 1 , 2 , 3 ) { 'Site' : 'CloudAcademy.com' } \u603b\u7ed3 \u00b6 \u53ef\u8fed\u4ee3\u89e3\u5305\uff08iterable unpacking\uff09\u8fd9\u4e2a\u7279\u6027\u5141\u8bb8\u6211\u4eec\u5c06\u4e00\u4e2a\u53ef\u8fed\u4ee3\u5bf9\u8c61\u89e3\u5305\u6210\u51e0\u4e2a\u53d8\u91cf\u3002 \u53e6\u4e00\u65b9\u9762\uff0c\u6253\u5305\u5305\u62ec\u4f7f\u7528\u89e3\u5305\u8fd0\u7b97\u7b26 * \u5c06\u591a\u4e2a\u503c\u8d4b\u5230\u4e00\u4e2a\u53d8\u91cf\u4e2d\u3002 \u53ef\u8fed\u4ee3\u89e3\u5305\uff08iterable unpacking\uff09\u4e5f\u53ef\u4ee5\u7528\u6765\u8fdb\u884c\u5e76\u884c\u8d4b\u503c\u548c\u53d8\u91cf\u4e4b\u95f4\u7684\u503c\u4ea4\u6362\uff0c\u4e5f\u53ef\u4ee5\u7528\u5728 for \u5faa\u73af\u3001\u51fd\u6570\u8c03\u7528\u548c\u51fd\u6570\u5b9a\u4e49\u4e2d\u3002","title":"Python\u6253\u5305\u548c\u89e3\u5305"},{"location":"python/Foundation/ch02/#python","text":"","title":"Python\u6253\u5305\u548c\u89e3\u5305"},{"location":"python/Foundation/ch02/#unpacking","text":"Python \u5141\u8bb8\u53d8\u91cf\u7684\u5143\u7ec4\uff08\u6216\u5217\u8868\uff09\u51fa\u73b0\u5728\u8d4b\u503c\u64cd\u4f5c\u7684\u5de6\u4fa7\u3002 \u5143\u7ec4\u4e2d\u7684\u6bcf\u4e2a\u53d8\u91cf\u90fd\u53ef\u4ee5\u4ece\u8d4b\u503c\u53f3\u4fa7\u7684\u53ef\u8fed\u4ee3\u5bf9\u8c61\uff08iterable\uff09\u4e2d\u63a5\u6536\u4e00\u4e2a\u503c\uff08\u6216\u8005\u66f4\u591a\uff0c\u5982\u679c\u6211\u4eec\u4f7f\u7528 * \u8fd0\u7b97\u7b26\uff09\u3002 Python \u4e2d\u7684\u89e3\u5305\u662f\u6307\u4e00\u79cd\u64cd\u4f5c\uff0c\u8be5\u64cd\u4f5c\u5305\u62ec\u5728\u5355\u4e2a\u8d4b\u503c\u8bed\u53e5\u4e2d\u5c06\u53ef\u8fed\u4ee3\u7684\u503c\u5206\u914d\u7ed9\u53d8\u91cf\u7684\u5143\u7ec4\uff08\u6216\u5217\u8868\uff09\u3002 \u5728 Python \u4e2d\uff0c\u53ef\u4ee5\u5728\u8d4b\u503c\u8fd0\u7b97\u7b26 = \u7684\u5de6\u4fa7\u653e\u7f6e\u4e00\u4e2a\u53d8\u91cf\u5143\u7ec4\uff0c\u5728\u53f3\u4fa7\u653e\u7f6e\u4e00\u4e2a\u503c\u5143\u7ec4\u3002 \u53f3\u8fb9\u7684\u503c\u5c06\u6839\u636e\u5b83\u4eec\u5728\u5143\u7ec4\u4e2d\u7684\u4f4d\u7f6e\u81ea\u52a8\u5206\u914d\u7ed9\u5de6\u8fb9\u7684\u53d8\u91cf\u3002 \u8fd9\u5728 Python \u4e2d\u901a\u5e38\u79f0\u4e3a\u5143\u7ec4\u89e3\u5305\u3002 \u5982\u4e0b\u793a\u4f8b\uff1a >>> ( a , b , c ) = ( 1 , 2 , 3 ) >>> a 1 >>> b 2 >>> c 3 >>> birthday = ( 'April' , 5 , 2001 ) >>> month , day , year = birthday >>> month 'April' >>> day 5 >>> year 2001 \u5143\u7ec4\u89e3\u5305\u529f\u80fd\u5728 Python \u4e2d\u53ef\u4ee5\u6269\u5c55\u4e3a\u9002\u7528\u4e8e\u4efb\u4f55\u53ef\u8fed\u4ee3\u5bf9\u8c61\u3002 \u552f\u4e00\u7684\u8981\u6c42\u662f\u53ef\u8fed\u4ee3\u7684\u63a5\u6536\u5143\u7ec4\uff08\u6216\u5217\u8868\uff09\u4e2d\u7684\u6bcf\u4e2a\u53d8\u91cf\u6070\u597d\u5bf9\u5e94\u53ef\u8fed\u4ee3\u5bf9\u8c61\u7684\u4e00\u4e2a\u5143\u7d20\uff08item\uff09\u3002 \u4e0b\u9762\u7684\u793a\u4f8b\u4ecb\u7ecd\u4e86 Python \u4e2d\u53ef\u8fed\u4ee3\u89e3\u5305\u7684\u5de5\u4f5c\u539f\u7406\uff1a >>> # Unpackage strings >>> a , b , c = '123' >>> a '1' >>> b '2' >>> c '3' >>> # Unpacking lists >>> a , b , c = [ 1 , 2 , 3 ] >>> a 1 >>> b 2 >>> c 3 >>> # Unpacking generators >>> gen = ( i ** 2 for i in range ( 3 )) >>> a , b , c = gen >>> a 0 >>> b 1 >>> c 4 >>> # Upacking dictionaries (keys, values, and items) >>> my_dict = { 'one' : 1 , 'two' : 2 , 'three' : 3 } >>> a , b , c = my_dict >>> a 'one' >>> b 'two' >>> c 'three' >>> a , b , c = my_dict . values () >>> a 1 >>> b 2 >>> c 3 >>> a , b , c = my_dict . items () >>> a ( 'one' , 1 ) >>> b ( 'two' , 2 ) >>> c ( 'three' , 3 ) >>> # Use a tuple on the right side of assignment statement >>> [ a , b , c ] = 1 , 2 , 3 >>> a 1 >>> b 2 >>> c 3 >>> # Use range() iterator >>> x , y , z = range ( 3 ) >>> x 0 >>> y 1 >>> z 2","title":"\u89e3\u5305Unpacking"},{"location":"python/Foundation/ch02/#packing","text":"\u6253\u5305\u53ef\u4ee5\u7406\u89e3\u4e3a\u4f7f\u7528\u53ef\u8fed\u4ee3\u89e3\u5305\u8fd0\u7b97\u7b26\u5728\u5355\u4e2a\u53d8\u91cf\u4e2d\u6536\u96c6\u591a\u4e2a\u503c\u3002\u5728\u8fd9\u79cd\u60c5\u51b5\u4e0b\uff0c * \u8fd0\u7b97\u7b26\u88ab\u79f0\u4e3a\u5143\u7ec4\uff08\u6216\u53ef\u8fed\u4ee3\uff09\u89e3\u5305\u8fd0\u7b97\u7b26\u3002 \u5b83\u6269\u5c55\u4e86\u89e3\u5305\u529f\u80fd\uff0c\u5141\u8bb8\u5728\u5355\u4e2a\u53d8\u91cf\u4e2d\u6536\u96c6\u6216\u6253\u5305\u591a\u4e2a\u503c\u3002 \u5728\u4ee5\u4e0b\u793a\u4f8b\u4e2d\u53ef\u4ee5\u770b\u5230 * \u8fd0\u7b97\u7b26\u5c06\u5143\u7ec4\u503c\u6253\u5305\u5230\u5355\u4e2a\u53d8\u91cf\u4e2d\uff1a >>> # The right side is a tuple, the left side is a list >>> * a , = 1 , 2 >>> a [ 1 , 2 ] >>> type ( a ) < class ' list '> \u5728\u4e0a\u9762\u7684\u4ee3\u7801\u4e2d\uff0c\u8d4b\u503c\u7684\u5de6\u4fa7\u5fc5\u987b\u662f\u5143\u7ec4\uff08\u6216\u5217\u8868\uff09\uff0c\u8fd9\u5c31\u662f\u4f7f\u7528\u5c3e\u968f\u9017\u53f7\u7684\u539f\u56e0\u3002\u8fd9\u4e2a\u5143\u7ec4\u53ef\u4ee5\u5305\u542b\u6240\u9700\u8981\u7684\u5c3d\u53ef\u80fd\u591a\u7684\u53d8\u91cf\uff0c\u4f46\u662f\uff0c\u5b83\u53ea\u80fd\u5305\u542b\u4e00\u4e2a\u661f\u53f7\u8868\u8fbe\u5f0f(starred expression)\u3002 >>> # Packing trailing values >>> a , * b = 1 , 2 , 3 >>> a 1 >>> b [ 2 , 3 ] >>> type ( a ) < class ' int '> >>> type ( b ) < class ' list '> >>> >>> * a , b , c = 1 , 2 , 3 >>> a [ 1 ] >>> b 2 >>> c 3 >>> * a , b , c , d , e = 1 , 2 , 3 Traceback ( most recent call last ): File \"\" , line 1 , in < module > ValueError : not enough values to unpack ( expected at least 4 , got 3 ) >>> * a , b , c , d = 1 , 2 , 3 >>> a [] >>> b 1 >>> c 2 >>> d 3 >>> >>> seq = [ 1 , 2 , 3 , 4 ] >>> first , * body , last = seq >>> first , body , last ( 1 , [ 2 , 3 ], 4 ) >>> first , body , * last = seq >>> first , body , last ( 1 , 2 , [ 3 , 4 ]) >>> >>> ran = range ( 10 ) >>> * r , = ran >>> r [ 0 , 1 , 2 , 3 , 4 , 5 , 6 , 7 , 8 , 9 ] \u4e0b\u9762\u662f\u4e00\u4e9b\u6253\u5305\u548c\u89e3\u5305\u7684\u4f8b\u5b50\u3002 >>> employee = [ 'John Doe' , '40' , 'Software Engineer' ] >>> name = employee [ 0 ] >>> age = employee [ 1 ] >>> job = employee [ 2 ] >>> name 'John Doe' >>> age '40' >>> job 'Software Engineer' >>> >>> name , age , job = [ 'John Doe' , '40' , 'Software Engineer' ] >>> name 'John Doe' >>> age '40' >>> job 'Software Engineer' >>> >>> a = 100 >>> b = 200 >>> a , b = b , a >>> a 200 >>> b 100 \u4f7f\u7528 * \u5220\u9664\u4e0d\u9700\u8981\u7684\u503c\u3002 >>> a , b , * _ = 1 , 2 , 0 , 0 , 0 , 0 >>> a 1 >>> b 2 >>> _ [ 0 , 0 , 0 , 0 ] \u5728\u4e0a\u4f8b\u4e2d\uff0c\u4e0d\u9700\u8981\u7684\u4fe1\u606f\u5b58\u50a8\u5728\u865a\u62df\u53d8\u91cf _ \u4e2d\uff0c\u5728\u540e\u7eed\u7684\u4f7f\u7528\u4e2d\u53ef\u4ee5\u5ffd\u7565\u5b83\u3002 \u9ed8\u8ba4\u60c5\u51b5\u4e0b\uff0cPython \u89e3\u91ca\u5668\u4f7f\u7528\u4e0b\u5212\u7ebf\u5b57\u7b26 _ \u6765\u5b58\u50a8\u5728\u4ea4\u4e92\u5f0f\u4f1a\u8bdd\u4e2d\u8fd0\u884c\u7684\u8bed\u53e5\u7684\u7ed3\u679c\u503c\u3002 \u56e0\u6b64\uff0c\u5728\u8fd9\u79cd\u60c5\u51b5\u4e0b\uff0c\u4f7f\u7528\u8fd9\u4e2a\u5b57\u7b26\u6765\u8bc6\u522b\u865a\u62df\u53d8\u91cf\u53ef\u80fd\u662f\u6a21\u68f1\u4e24\u53ef\u7684\u3002 \u5728\u51fd\u6570\u4e2d\u8fd4\u56de\u5143\u7ec4\u3002 >>> def powers ( num ): ... return num , num ** 2 , num ** 3 ... >>> # Packaging returned values in a tuple >>> result = powers ( 3 ) >>> result ( 3 , 9 , 27 ) >>> # Unpacking returned values to multiple variables >>> number , square , cube = powers ( 3 ) >>> number 3 >>> square 9 >>> cube 27 >>> * _ , cube = powers ( 3 ) >>> cube 27","title":"\u6253\u5305Packing"},{"location":"python/Foundation/ch02/#_1","text":"\u4f7f\u7528 * \u8fd0\u7b97\u7b26\u5408\u5e76\u8fed\u4ee3\u53d8\u91cf\uff08iterables\uff09\u3002\u4e0a\u9762\u4e24\u4e2a\u4f8b\u5b50\u8bf4\u660e\uff0c\u8fd9\u4e2d\u65b9\u6cd5\u4e5f\u662f\u8fde\u63a5\u8fed\u4ee3\u53d8\u91cf\uff08iterables\uff09\u7684\u4e00\u79cd\u66f4\u6613\u8bfb\u548c\u66f4\u6709\u6548\u7684\u65b9\u6cd5\u3002 \u8fd9\u4e2a\u65b9\u6cd5 (my_set) + my_list + list(my_tuple) + list(range(1, 4)) + list(my_str) \u53ef\u4ee5\u751f\u6210\u4e00\u4e2a\u5217\u8868 \uff0c\u4e5f\u53ef\u4ee5\u4f7f\u7528\u66f4\u7b80\u6d01\u7684\u65b9\u6cd5 [*my_set, *my_list, *my_tuple, *range(1, 4), *my_str] \u3002 >>> my_tuple = ( 1 , 2 , 3 ) >>> ( 0 , * my_tuple , 4 ) ( 0 , 1 , 2 , 3 , 4 ) >>> my_list = [ 1 , 2 , 3 ] >>> [ 0 , * my_list , 4 ] [ 0 , 1 , 2 , 3 , 4 ] >>> my_set = { 1 , 2 , 3 } >>> { 0 , * my_set , 4 } { 0 , 1 , 2 , 3 , 4 } >>> [ * my_set , * my_list , * my_tuple , * range ( 1 , 4 )] [ 1 , 2 , 3 , 1 , 2 , 3 , 1 , 2 , 3 , 1 , 2 , 3 ] >>> my_str = \"123\" >>> [ * my_set , * my_list , * my_tuple , * range ( 1 , 4 ), * my_str ] [ 1 , 2 , 3 , 1 , 2 , 3 , 1 , 2 , 3 , 1 , 2 , 3 , '1' , '2' , '3' ] \u4f7f\u7528 ** \u8fd0\u7b97\u7b26\u89e3\u5305\u5b57\u5178\u3002 >>> numbers = { 'one' : 1 , 'two' : 2 , 'three' : 3 } >>> letters = { 'a' : 'A' , 'b' : 'B' , 'c' : 'C' } >>> combination = { ** numbers , ** letters } >>> combination { 'one' : 1 , 'two' : 2 , 'three' : 3 , 'a' : 'A' , 'b' : 'B' , 'c' : 'C' } \u9700\u8981\u6ce8\u610f\u7684\u91cd\u8981\u4e00\u70b9\u662f\uff0c\u5982\u679c\u6211\u4eec\u5408\u5e76\u7684\u5b57\u5178\u5177\u6709\u91cd\u590d\u952e\u6216\u516c\u5171\u952e\uff0c\u5219\u6700\u53f3\u4fa7\u5b57\u5178\u7684\u503c\u5c06\u8986\u76d6\u6700\u5de6\u4fa7\u5b57\u5178\u7684\u503c\u3002\u4f8b\u5982: >>> letters = { 'a' : 'A' , 'b' : 'B' , 'c' : 'C' } >>> vowels = { 'a' : 'a' , 'e' : 'e' , 'i' : 'i' , 'o' : 'o' , 'u' : 'u' } >>> { ** letters , ** vowels } { 'a' : 'a' , 'b' : 'B' , 'c' : 'C' , 'e' : 'e' , 'i' : 'i' , 'o' : 'o' , 'u' : 'u' } >>> { ** vowels , ** letters } { 'a' : 'A' , 'e' : 'e' , 'i' : 'i' , 'o' : 'o' , 'u' : 'u' , 'b' : 'B' , 'c' : 'C' }","title":"\u4f7f\u7528*\u548c**\u8fd0\u7b97\u7b26"},{"location":"python/Foundation/ch02/#for-loops","text":"\u6211\u4eec\u8fd8\u53ef\u4ee5\u5728 for \u5faa\u73af\u7684\u4e0a\u4e0b\u6587\u4e2d\u4f7f\u7528\u53ef\u8fed\u4ee3\u89e3\u5305\u3002 \u5f53\u6211\u4eec\u8fd0\u884c for \u5faa\u73af\u65f6\uff0c\u5728\u6bcf\u6b21\u5faa\u73af\u8fed\u4ee3\u4e2d\u5c06\u5176\u53ef\u8fed\u4ee3\u5bf9\u8c61\u4e2d\u7684\u4e00\u9879(item)\u5206\u914d\u7ed9\u76ee\u6807\u53d8\u91cf\u3002 \u5982\u679c\u8981\u5206\u914d\u7684\u9879(item)\u662f\u53ef\u8fed\u4ee3\u7684\uff0c\u90a3\u4e48\u6211\u4eec\u53ef\u4ee5\u4f7f\u7528\u5143\u7ec4\u4f5c\u4e3a\u76ee\u6807\u53d8\u91cf\uff0c\u901a\u8fc7\u5faa\u73af\u5c06\u53ef\u8fed\u4ee3\u5bf9\u8c61\u89e3\u5305\u5230\u76ee\u6807\u53d8\u91cf\u7684\u5143\u7ec4\u4e2d\u3002 \u4f8b\u5982\uff0c\u6211\u4eec\u53ef\u4ee5\u6784\u5efa\u4e00\u4e2a\u5305\u542b\u4e24\u4e2a\u5143\u7d20\u7684\u5143\u7ec4\u7684\u5217\u8868\u3002 \u6bcf\u4e2a\u5143\u7ec4\u5c06\u5305\u542b\u4ea7\u54c1\u540d\u79f0\u3001\u4ef7\u683c\u548c\u9500\u552e\u5355\u4f4d\uff0c\u6211\u4eec\u901a\u8fc7 for \u5faa\u73af\u904d\u5386\u6bcf\u4e2a\u5143\u7ec4\u5143\u7d20\u6765\u8ba1\u7b97\u6bcf\u4e2a\u4ea7\u54c1\u7684\u6536\u5165\u3002 >>> sales = [( 'Pencle' , 0.22 , 1500 ), ( 'Notebook' , 1.30 , 550 ), ( 'Eraser' , 0.75 , 1000 )] >>> for items in sales : ... print ( f \"Income for { items [ 0 ] } is: { items [ 1 ] * items [ 2 ] } \" ) ... Income for Pencle is : 330.0 Income for Notebook is : 715.0 Income for Eraser is : 750.0 \u6211\u4eec\u53ef\u4ee5\u4f7f\u7528\u7d22\u5f15\u6765\u8bbf\u95ee\u6bcf\u4e2a\u5143\u7ec4\u7684\u5404\u4e2a\u5143\u7d20\u3002\u4e0b\u9762\u7684\u793a\u4f8b\u4ee3\u7801\u4e2d\uff0c\u5728 for \u5faa\u73af\u4f7f\u7528\u89e3\u5305\uff0c\u8fd9\u4e5f\u662f Python \u4e2d\u89e3\u5305\u7684\u4e00\u79cd\u5b9e\u73b0\u3002 >>> sales = [( 'Pencle' , 0.22 , 1500 ), ( 'Notebook' , 1.30 , 550 ), ( 'Eraser' , 0.75 , 1000 )] >>> for product , price , sold_units in sales : ... print ( f \"Income for { product } is: { price * sold_units } \" ) ... Income for Pencle is : 330.0 Income for Notebook is : 715.0 Income for Eraser is : 750.0 \u4e5f\u53ef\u4ee5\u5728 for \u5faa\u73af\u4e2d\u4f7f\u7528 * \u8fd0\u7b97\u7b26\u5c06\u591a\u4e2a\u9879\u6253\u5305\u5230\u5355\u4e2a\u76ee\u6807\u53d8\u91cf\u4e2d\u3002 \u5728\u4e0b\u9762\u8fd9\u4e2a\u4f8b\u5b50\u4e2d\uff0c\u6211\u4eec\u9996\u5148\u53d6\u5f97\u6bcf\u4e2a\u5e8f\u5217\u7684\u7b2c\u4e00\u4e2a\u5143\u7d20\u3002 \u5176\u4f59\u503c\u901a\u8fc7 * \u8fd0\u7b97\u7b26\u8d4b\u7ed9\u76ee\u6807\u53d8\u91cf rest \u3002 >>> for first , * rest in [( 1 , 2 , 3 ),( 4 , 5 , 6 )]: ... print ( 'First: ' , first ) ... print ( 'Rest: ' , rest ) ... First : 1 Rest : [ 2 , 3 ] First : 4 Rest : [ 5 , 6 ] >>> \u76ee\u6807\u53d8\u91cf\u7684\u7ed3\u6784\u5fc5\u987b\u4e0e\u53ef\u8fed\u4ee3\u5bf9\u8c61\u7684\u7ed3\u6784\u4e00\u81f4\uff0c\u5426\u5219\u4f1a\u62a5\u9519\u3002\u770b\u4e0b\u9762\u7684\u4f8b\u5b50\u3002 >>> data = [(( 1 , 2 ), 3 ), (( 2 , 3 ), 3 )] >>> for ( a , b ), c in data : ... print ( a , b , c ) ... 1 2 3 2 3 3 >>> for a , b , c in data : ... print ( a , b , c ) ... Traceback ( most recent call last ): File \"\" , line 1 , in < module > ValueError : not enough values to unpack ( expected 3 , got 2 )","title":"\u901a\u8fc7 For-Loops \u89e3\u5305"},{"location":"python/Foundation/ch02/#_2","text":"\u4e0b\u9762\u4f8b\u5b50\u4e2d\u7684\u51fd\u6570func\u81f3\u5c11\u9700\u8981\u4e00\u4e2a\u540d\u4e3a required \u7684\u53c2\u6570\u3002 \u5b83\u4e5f\u53ef\u4ee5\u63a5\u53d7\u4e00\u4e2a\u6216\u591a\u4e2a\u4f4d\u7f6e\u53c2\u6570\u6216\u5173\u952e\u5b57\u53c2\u6570\u3002 \u5728\u8fd9\u79cd\u60c5\u51b5\u4e0b\uff0c * \u8fd0\u7b97\u7b26\u5728\u4e00\u4e2a\u53eb args \u7684\u5143\u7ec4\u4e2d\u6536\u96c6\u6216\u6253\u5305\u989d\u5916\u7684\u4f4d\u7f6e\u53c2\u6570\uff0c\u800c ** \u8fd0\u7b97\u7b26\u5728\u4e00\u4e2a\u53eb kwargs \u7684\u5b57\u5178\u4e2d\u6536\u96c6\u6216\u6253\u5305\u989d\u5916\u7684\u5173\u952e\u5b57\u53c2\u6570\u3002 args \u548c kwargs \u90fd\u662f\u53ef\u9009\u7684\uff0c\u5e76\u4e14\u5206\u522b\u81ea\u52a8\u9ed8\u8ba4\u4e3a\u5143\u7ec4 () \u548c\u5b57\u5178 {} \u3002 \u8fd9\u91cc args \u548c kwargs \u7684\u547d\u540d\u5e76\u4e0d\u662f\u5fc5\u987b\u7684\uff0c\u8bed\u6cd5\u4e0a\u53ea\u9700\u8981 * \u6216 ** \u540e\u8ddf\u6709\u6548\u6807\u8bc6\u7b26\u5373\u53ef\uff0c\u5efa\u8bae\u7ed9\u53d8\u91cf\u8d77\u4e2a\u6709\u610f\u4e49\u7684\u540d\u5b57\uff0c\u63d0\u9ad8\u4ee3\u7801\u7684\u53ef\u8bfb\u6027\u3002 >>> def func ( required , * args , ** kwargs ): ... print ( required ) ... print ( args ) ... print ( kwargs ) ... >>> func ( 'Welcome to ...' , 1 , 2 , 3 , site = 'CloudAcademy.com' ) Welcome to ... ( 1 , 2 , 3 ) { 'site' : 'CloudAcademy.com' } >>> func ( 'Welcome to ...' , 1 , 2 , 3 , 4 ) Welcome to ... ( 1 , 2 , 3 , 4 ) {} >>> func ( 'Welcome to ...' , 1 , 2 , 3 , ( 1 , 2 )) Welcome to ... ( 1 , 2 , 3 , ( 1 , 2 )) {} >>> func ( 'Welcome to ...' , 1 , 2 , 3 , [ 1 , 2 ]) Welcome to ... ( 1 , 2 , 3 , [ 1 , 2 ]) {} >>> func ( 'Welcome to ...' , 1 , 2 , 3 , ([ 2 , 3 ], [ 1 , 2 ])) Welcome to ... ( 1 , 2 , 3 , ([ 2 , 3 ], [ 1 , 2 ])) {}","title":"\u7528*\u548c**\u5b9a\u4e49\u51fd\u6570"},{"location":"python/Foundation/ch02/#_3","text":"\u8c03\u7528\u51fd\u6570\u65f6\uff0c\u6211\u4eec\u8fd8\u53ef\u4ee5\u53d7\u76ca\u4e8e\u4f7f\u7528 * \u548c ** \u8fd0\u7b97\u7b26\u5c06\u53c2\u6570\u96c6\u5408\u5206\u522b\u89e3\u538b\u7f29\u4e3a\u5355\u72ec\u7684\u4f4d\u7f6e\u53c2\u6570\u6216\u5173\u952e\u5b57\u53c2\u6570\u3002 \u8fd9\u4e0e\u5728\u51fd\u6570\u7b7e\u540d(signature of a function)\u4e2d\u4f7f\u7528 * \u548c ** \u662f\u76f8\u53cd\u7684\u3002 \u5728\u51fd\u6570\u7b7e\u540d\u4e2d\uff0c\u8fd0\u7b97\u7b26\u7684\u610f\u601d\u662f\u5728\u4e00\u4e2a\u6807\u8bc6\u7b26\u4e2d\u6536\u96c6\u6216\u6253\u5305\u53ef\u53d8\u6570\u91cf\u7684\u53c2\u6570\u3002 \u5728\u8c03\u7528(calling)\u4e2d\uff0c\u5b83\u4eec\u7684\u610f\u601d\u662f\u89e3\u5305(unpack)\u4e00\u4e2a\u53ef\u8fed\u4ee3\u5bf9\u8c61\u5230\u591a\u4e2a\u53c2\u6570\u4e2d\u3002 \u7eed\u4e0a\u4f8b\uff0c * \u8fd0\u7b97\u7b26\u5c06\u50cf [\"Welcome\", \"to\"] \u8fd9\u6837\u7684\u5e8f\u5217\u89e3\u5305\u5230\u4f4d\u7f6e\u53c2\u6570\u4e2d\u3002 \u7c7b\u4f3c\u5730\uff0c ** \u8fd0\u7b97\u7b26\u5c06\u5b57\u5178\u89e3\u5305\u4e3a\u4e0e\u5b57\u5178\u7684\u952e\u503c\u5339\u914d\u7684\u53c2\u6570\u540d\u3002 >>> def func ( welcome , to , site ): ... print ( welcome , to , site ) ... >>> func ( * [ 'Welcome' , 'to' ], ** { 'site' : 'CloudAcademy.com' }) Welcome to CloudAcademy . com \u7efc\u5408\u8fd0\u7528\u524d\u9762\u7684\u65b9\u6cd5\u6765\u7f16\u5199\u975e\u5e38\u7075\u6d3b\u7684\u51fd\u6570\uff0c\u6bd4\u5982\uff0c\u5728\u5b9a\u4e49\u548c\u8c03\u7528 Python \u51fd\u6570\u65f6\uff0c\u66f4\u7075\u6d3b\u7684\u4f7f\u7528 * \u548c ** \u8fd0\u7b97\u7b26\u3002 \u4f8b\u5982\uff1a >>> def func ( required , * args , ** kwargs ): ... print ( required ) ... print ( args ) ... print ( kwargs ) ... >>> func ( 'Welcome to...' , * ( 1 , 2 , 3 ), ** { 'Site' : 'CloudAcademy.com' }) Welcome to ... ( 1 , 2 , 3 ) { 'Site' : 'CloudAcademy.com' }","title":"\u4f7f\u7528*\u548c**\u8c03\u7528\u51fd\u6570"},{"location":"python/Foundation/ch02/#_4","text":"\u53ef\u8fed\u4ee3\u89e3\u5305\uff08iterable unpacking\uff09\u8fd9\u4e2a\u7279\u6027\u5141\u8bb8\u6211\u4eec\u5c06\u4e00\u4e2a\u53ef\u8fed\u4ee3\u5bf9\u8c61\u89e3\u5305\u6210\u51e0\u4e2a\u53d8\u91cf\u3002 \u53e6\u4e00\u65b9\u9762\uff0c\u6253\u5305\u5305\u62ec\u4f7f\u7528\u89e3\u5305\u8fd0\u7b97\u7b26 * \u5c06\u591a\u4e2a\u503c\u8d4b\u5230\u4e00\u4e2a\u53d8\u91cf\u4e2d\u3002 \u53ef\u8fed\u4ee3\u89e3\u5305\uff08iterable unpacking\uff09\u4e5f\u53ef\u4ee5\u7528\u6765\u8fdb\u884c\u5e76\u884c\u8d4b\u503c\u548c\u53d8\u91cf\u4e4b\u95f4\u7684\u503c\u4ea4\u6362\uff0c\u4e5f\u53ef\u4ee5\u7528\u5728 for \u5faa\u73af\u3001\u51fd\u6570\u8c03\u7528\u548c\u51fd\u6570\u5b9a\u4e49\u4e2d\u3002","title":"\u603b\u7ed3"},{"location":"python/Foundation/ch03/","text":"Python\u5185\u7f6e\u51fd\u6570\u53ca\u6587\u4ef6 \u00b6 1. \u533f\u540d\uff08Lambda\uff09\u51fd\u6570 \u00b6 \u533f\u540d\u51fd\u6570\u662f\u4e00\u79cd\u901a\u8fc7\u5355\u4e2a\u8bed\u53e5\u751f\u6210\u51fd\u6570\u7684\u65b9\u5f0f\uff0c\u5176\u7ed3\u679c\u662f\u8fd4\u56de\u503c\u3002\u533f\u540d\u51fd\u6570\u4f7f\u7528lambda\u5173\u952e\u5b57\u5b9a\u4e49\uff0c\u8be5\u5173\u952e\u5b57\u4ec5\u8868\u8fbe\u201c\u6211\u4eec\u58f0\u660e\u4e00\u4e2a\u533f\u540d\u51fd\u6570\u201d\u7684\u610f\u601d\u3002 lambda \u51fd\u6570\u53ef\u4ee5\u63a5\u6536\u4efb\u610f\u591a\u4e2a\u53c2\u6570 (\u5305\u62ec\u53ef\u9009\u53c2\u6570) \u5e76\u4e14\u8fd4\u56de\u5355\u4e2a\u8868\u8fbe\u5f0f\u7684\u503c\u3002 \u8bed\u6cd5\u683c\u5f0f\uff1a lambda arg1,arg2,arg3\u2026 :<\u8868\u8fbe\u5f0f> f = lambda x , y : x * y print ( f ( 2 , 3 )) # 6 f = [ lambda a : a * 2 , lambda b : b * 3 ] print ( f [ 0 ]( 5 )) # \u6267\u884cf\u5217\u8868\u7b2c\u4e00\u4e2a\u5143\u7d20 # 10 print ( f [ 1 ]( 5 )) # \u6267\u884cf\u5143\u7d20\u7b2c\u4e8c\u4e2a\u5143\u7d20 # 15 print ( f [ 0 , 1 ]( 5 , 5 )) # TypeError: list indices must be integers or slices, not tuple \u793a\u4f8b1\uff1a def short_func1 ( x ): return x * 2 short_func2 = lambda x : x * 2 print ( short_func1 ( 5 )) # 10 print ( short_func2 ( 5 )) # 10 \u793a\u4f8b2\uff1a def apply_to_list ( some_list , f ): return [ f ( x ) for x in some_list ] ints = [ 4 , 0 , 1 , 5 , 6 ] result5 = apply_to_list ( ints , lambda x : x * 2 ) print ( result5 ) # [8, 0, 2, 10, 12] lambda: None \u51fd\u6570\u6ca1\u6709\u8f93\u5165\u53c2\u6570\uff0c\u8f93\u51fa\u662fNone\u3002 print ( lambda : None ) # at 0x7fa5c4097670> lambda **kwargs: 1 \u8f93\u5165\u662f\u4efb\u610f\u952e\u503c\u5bf9\u53c2\u6570\uff0c\u8f93\u51fa\u662f1\u3002 print ( lambda ** kwargs : 1 ) # at 0x7fa5c4097670> 2. \u5185\u7f6e\u5e8f\u5217\u51fd\u6570enumerate \u00b6 \u5f53\u9700\u8981\u5bf9\u6570\u636e\u5efa\u7acb\u7d22\u5f15\u65f6\uff0c\u4e00\u79cd\u6709\u6548\u7684\u6a21\u5f0f\u5c31\u662f\u4f7f\u7528enumerate\u6784\u9020\u4e00\u4e2a\u5b57\u5178\uff0c\u5c06\u5e8f\u5217\u503c\uff08\u5047\u8bbe\u662f\u552f\u4e00\u7684\uff09\u6620\u5c04\u5230\u7d22\u5f15\u4f4d\u7f6e\u4e0a\u3002 seasons = [ 'Spring' , 'Summer' , 'Fall' , 'Winter' ] print ( list ( enumerate ( seasons ))) # [(0, 'Spring'), (1, 'Summer'), (2, 'Fall'), (3, 'Winter')] \u5bf9\u6bd4\u4e0b\u97622\u4e2a\u5faa\u73af a_list = [ 'foo' , 'bar' , 'baz' ] mapping = {} for i , v in enumerate ( a_list ): # enumerate\u751f\u6210\u7d22\u5f15\u503ci\u548c\u5e8f\u5217\u503cv mapping [ v ] = i print ( mapping ) # {'foo': 0, 'bar': 1, 'baz': 2} i = 0 mapping = {} for v in a_list : print ( i , a_list [ i ]) mapping [ v ] = i # \u53ef\u4ee5\u628ai\u548cv\u4e92\u6362 i += 1 print ( mapping ) # {'foo': 0, 'bar': 1, 'baz': 2} \u5229\u7528 enumerate() \u6279\u91cf\u4fee\u6539\u5217\u8868\u5185\u7684\u5143\u7d20 a_list = [ '01' , '02' , '03' ] unit_element = '1' for i , element in enumerate ( a_list ): a_list [ i ] = unit_element + element print ( a_list ) # ['101', '102', '103'] sorted\u51fd\u6570\u8fd4\u56de\u4e00\u4e2a\u6839\u636e\u4efb\u610f\u5e8f\u5217\u4e2d\u7684\u5143\u7d20\u65b0\u5efa\u7684\u5df2\u6392\u5e8f\u5217\u8868\u3002sorted\u51fd\u6570\u63a5\u53d7\u7684\u53c2\u6570\u4e0e\u5217\u8868\u7684sort\u65b9\u6cd5\u4e00\u81f4\u3002 y = sorted ([ 7 , 1 , 2 , 6 , 0 , 3 , 2 ]) print ( y ) # [0, 1, 2, 2, 3, 6, 7] \u7ed3\u679c\u5df2\u6392\u5e8f z = sorted ( 'Hello World' ) print ( z ) # [' ', 'H', 'W', 'd', 'e', 'l', 'l', 'l', 'o', 'o', 'r'] zip\u5c06\u5217\u8868\u3001\u5143\u7ec4\u6216\u5176\u4ed6\u5e8f\u5217\u7684\u5143\u7d20\u914d\u5bf9\uff0c\u65b0\u5efa\u4e00\u4e2a\u5143\u7ec4\u6784\u6210\u7684\u5217\u8868\u3002 seq1 = [ 'foo' , 'bar' , 'baz' ] seq2 = [ 'one' , 'two' , 'three' ] seq3 = [ False , True ] zipped = zip ( seq1 , seq2 ) print ( list ( zipped )) # [('foo', 'one'), ('bar', 'two'), ('baz', 'three')] zipped = zip ( seq1 , seq2 , seq3 ) print ( list ( zipped )) # [('foo', 'one', False), ('bar', 'two', True)] for i , ( a , b ) in enumerate ( zip ( seq1 , seq2 )): print ( ' {0} : {1} , {2} ' . format ( i , a , b )) # \u65b9\u6cd51 {0}\u5217\u8868\u5143\u7d20\u7684\u7d22\u5f15, {1}\u5143\u7ec4\u4e2d\u7b2c\u4e00\u4e2a\u503c, {2}\u5143\u7ec4\u4e2d\u7b2c\u4e8c\u4e2a\u503c print ( f ' { i } : { a } , { b } ' ) # \u65b9\u6cd52 # 0: foo, one # 1: bar, two # 2: baz, three \u7ed9\u5b9a\u4e00\u4e2a\u5df2\u201c\u914d\u5bf9\u201d\u7684\u5e8f\u5217\u65f6\uff0czip\u51fd\u6570\u53ef\u4ee5\u53bb\u201c\u62c6\u5206\u201d\u5e8f\u5217\u3002\u8fd9\u79cd\u65b9\u5f0f\u7684\u53e6\u4e00\u79cd\u601d\u8def\u5c31\u662f\u5c06\u884c\u7684\u5217\u8868\u8f6c\u6362\u4e3a\u5217\u7684\u5217\u8868\u3002\u53c2\u8003Python\u7684 Unpacking pitchers = [( 'Jack' , 'Ma' ), ( 'Tom' , 'Li' ), ( 'Jimmy' , 'Zhang' )] first_names , last_names = zip ( * pitchers ) print ( first_names ) # ('Jack', 'Tom', 'Jimmy') print ( last_names ) # ('Ma', 'Li', 'Zhang') reversed\u51fd\u6570\u5c06\u5e8f\u5217\u7684\u5143\u7d20\u5012\u5e8f\u6392\u5217 print ( list ( reversed ( range ( 10 )))) # [9, 8, 7, 6, 5, 4, 3, 2, 1, 0] 3. \u5217\u8868\u3001\u96c6\u5408\u548c\u5b57\u5178\u7684\u63a8\u5bfc\u5f0f \u00b6 \u63a8\u5bfc\u5f0fcomprehensions\uff08\u53c8\u79f0\u89e3\u6790\u5f0f\uff09\uff0c\u662fPython\u7684\u4e00\u79cd\u7279\u6027\u3002\u4f7f\u7528\u63a8\u5bfc\u5f0f\u53ef\u4ee5\u5feb\u901f\u751f\u6210\u5217\u8868\u3001\u5143\u7ec4\u3001\u96c6\u5408\u3001\u5b57\u5178\u7c7b\u578b\u7684\u6570\u636e\u3002\u63a8\u5bfc\u5f0f\u53c8\u5206\u4e3a\u5217\u8868\u63a8\u5bfc\u5f0f\u3001\u5143\u7ec4\u63a8\u5bfc\u5f0f\u3001\u96c6\u5408\u63a8\u5bfc\u5f0f\u3001\u5b57\u5178\u63a8\u5bfc\u5f0f\u3002 \u5217\u8868\u63a8\u5bfc\u5f0f(list comprehension) \u00b6 \u5217\u8868\u63a8\u5bfc\u5f0f(list comprehension)\u5141\u8bb8\u4f60\u8fc7\u6ee4\u4e00\u4e2a\u5bb9\u5668\u7684\u5143\u7d20\uff0c\u7528\u4e00\u79cd\u7b80\u660e\u7684\u8868\u8fbe\u5f0f\u8f6c\u6362\u4f20\u9012\u7ed9\u8fc7\u6ee4\u5668\u7684\u5143\u7d20\uff0c\u4ece\u800c\u751f\u6210\u4e00\u4e2a\u65b0\u7684\u5217\u8868\u3002 \u5217\u8868\u63a8\u5bfc\u5f0f\u7684\u57fa\u672c\u5f62\u5f0f\u4e3a\uff1a[expr for val in collection if condition]\uff0c\u6761\u4ef6if-condition\u4e0d\u662f\u5fc5\u987b\u7684\uff0c\u53ef\u4ee5\u53ea\u4fdd\u7559\u8868\u8fbe\u5f0f\u3002\u5217\u8868\u63a8\u5bfc\u5f0f\u4e0e\u4e0b\u9762\u7684for\u5faa\u73af\u662f\u7b49\u4ef7\u7684\uff1a result = [] for val in collection : if condition : result . append ( expr ) \u770b\u4e0b\u9762\u7684\u4f8b\u5b50\uff1a data = [] for i in range ( - 5 , 5 ): if i >= - 1 : data . append ( i ** 2 ) print ( data ) # [1, 0, 1, 4, 9, 16] data = [ i ** 2 for i in range ( - 5 , 5 ) if i >= - 1 ] print ( data ) # [1, 0, 1, 4, 9, 16] \u4e0b\u9762\u7684\u4f8b\u5b50\u662f\u4f7f\u7528for\u53bb\u904d\u5386\u4e00\u4e2a\u53ef\u8fed\u4ee3\u7684\u5217\u8868\u3002 data = [] fruit = [ 'pomegranate' , 'cherry' , 'apricot' , 'date' , 'Apple' , 'lemon' , 'kiwi' , 'ORANGE' , 'lime' , 'Watermelon' , 'guava' , 'papaya' , 'FIG' , 'pear' , 'banana' , 'Tamarind' , 'persimmon' , 'elderberry' , 'peach' , 'BLUEberry' , 'lychee' , 'grape' ] data = [ x . upper () if x . startswith ( 'p' ) else x . title () for x in fruit ] print ( data ) # ['POMEGRANATE', 'Cherry', 'Apricot', 'Date', 'Apple', 'Lemon', 'Kiwi', 'Orange', 'Lime', 'Watermelon', 'Guava', 'PAPAYA', 'Fig', 'PEAR', 'Banana', 'Tamarind', 'PERSIMMON', 'Elderberry', 'PEACH', 'Blueberry', 'Lychee', 'Grape'] \u5957\u5217\u8868\u63a8\u5bfc\u5f0f \u00b6 \u4e0b\u9762\u7684\u4f8b\u5b50\u662f\u7528\u5d4c\u5957\u5217\u8868\u63a8\u5bfc\u5f0f\u4ee3\u66ff2\u5c42for\u5faa\u73af\u3002 data = [] for i in range ( 1 , 3 ): if i >= 0 : for j in range ( 1 , 3 ): data . append (( i , j )) print ( data ) # [(1, 1), (1, 2), (2, 1), (2, 2)] data = [( i , j ) for i in range ( 1 , 3 ) if i >= - 1 for j in range ( 1 , 3 )] print ( data ) # [(1, 1), (1, 2), (2, 1), (2, 2)] \u518d\u4e3e\u4e00\u4e2a\u5d4c\u5957\u5217\u8868\u63a8\u5bfc\u5f0f\u7684\u4f8b\u5b50\u3002 all_data = [ [ 'John' , 'Emily' , 'Michael' , 'Lee' , 'Steven' ], [ 'Maria' , 'Juan' , 'Javier' , 'Natalia' , 'Pilar' ], ] names_of_interest = [] for names in all_data : enough_es = [ name for name in names if name . count ( 'e' ) >= 2 ] names_of_interest . extend ( enough_es ) print ( names_of_interest ) # ['Lee', 'Steven'] result = [ name for names in all_data for name in names if name . count ( 'e' ) >= 2 ] print ( result ) # ['Lee', 'Steven'] \u7528\u5d4c\u5957\u5217\u8868\u63a8\u5bfc\u5f0f\u5c06\u77e9\u9635\u6241\u5e73\u5316\u3002 \u8003\u8651\u4e0b\u9762\u8fd9\u4e2a3x4\u7684\u77e9\u9635\uff0c\u5b83\u75313\u4e2a\u957f\u5ea6\u4e3a4\u7684\u5217\u8868\u7ec4\u6210\u3002\u4e0b\u9762\u4f8b\u5b50\u5bf9\u6bd4\u4e86\u7528\u4f20\u7edffor\u5faa\u73af\u5c06\u77e9\u9635\u6241\u5e73\u5316\uff0c\u548c\u7528\u5d4c\u5957\u5217\u8868\u63a8\u5bfc\u5f0f\u5c06\u77e9\u9635\u6241\u5e73\u5316\u3002\u5e76\u4e14\u901a\u8fc7\u5217\u8868\u63a8\u5bfc\u5f0f\u4e2d\u7684\u5217\u8868\u63a8\u5bfc\u5f0f\u5c06\u6241\u5e73\u77e9\u9635\u8fd8\u539f\u4e3a3x4\u77e9\u9635\u3002 matrix = [ [ 1 , 2 , 3 , 4 ], [ 5 , 6 , 7 , 8 ], [ 9 , 10 , 11 , 12 ], ] flattened = [] # \u4f20\u7edffor\u5faa\u73af\u5d4c\u5957 for m in matrix : for x in m : flattened . append ( x ) print ( flattened ) # [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12] # \u5d4c\u5957\u5217\u8868\u63a8\u5bfc\u5f0f flattened = [ x for m in matrix for x in m ] print ( flattened ) # [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12] # \u5217\u8868\u63a8\u5bfc\u5f0f\u4e2d\u7684\u5217\u8868\u63a8\u5bfc\u5f0f z = [[ x for x in m ] for m in matrix ] print ( z ) # [[1, 2, 3, 4], [5, 6, 7, 8], [9, 10, 11, 12]] \u5143\u7ec4\u63a8\u5bfc\u5f0f \u00b6 \u4e0b\u9762\u7684\u4f8b\u5b50\u751f\u6210\u4e00\u4e2a\u5305\u542b\u6570\u5b571~5\u7684\u5143\u7ec4\u3002\u4ece\u7ed3\u679c\u53ef\u4ee5\u770b\u5230\uff0c\u5143\u7ec4\u63a8\u5bfc\u5f0f\u751f\u6210\u7684\u7ed3\u679c\u5e76\u4e0d\u662f\u4e00\u4e2a\u5143\u7ec4\uff0c\u800c\u662f\u4e00\u4e2a\u751f\u6210\u5668\u5bf9\u8c61\uff0c\u9700\u8981\u901a\u8fc7tuple()\u51fd\u6570\uff0c\u5c06\u751f\u6210\u5668\u5bf9\u8c61\u8f6c\u6362\u6210\u5143\u7ec4\u3002 data = ( x for x in range ( 5 )) print ( data ) # at 0x7f87217a8e40> print ( type ( data )) # print ( tuple ( data )) # (0, 1, 2, 3, 4) \u96c6\u5408\u63a8\u5bfc\u5f0f \u00b6 \u4e0b\u9762\u662f\u4e00\u4e2a\u7b80\u5355\u7684\u96c6\u5408\u63a8\u5bfc\u5f0f\u4f8b\u5b50\u3002 data = { x ** 2 for x in range ( 5 )} print ( data ) # {0, 1, 4, 9, 16} print ( type ( data )) # \u96c6\u5408\u8981\u4fdd\u8bc1\u5143\u7d20\u5fc5\u987b\u662f\u552f\u4e00\u7684\u3002 data = ( 1 , 1 , 2 , 2 , 3 , 3 , 4 , 5 , 6 ) newset = { x ** 2 for x in data } print ( newset ) # {1, 4, 36, 9, 16, 25} print ( type ( newset ) # \u5b57\u5178\u63a8\u5bfc\u5f0f \u00b6 \u5b57\u5178\u63a8\u5bfc\u5f0f: dict_comp = {key-expr : value-expr for value in collection if condition} \u5b57\u5178\u63a8\u5bfc\u5f0f\u7684\u7b80\u5355\u793a\u4f8b\uff1a strings = [ 'a' , 'as' , 'bat' , 'car' , 'dove' , 'python' ] loc_mapping = { index : val for index , val in enumerate ( strings )} print ( loc_mapping ) # {0: 'a', 1: 'as', 2: 'bat', 3: 'car', 4: 'dove', 5: 'python'} # \u4ea4\u6362\u952e\u548c\u503c loc_mapping = { index : val for val , index in enumerate ( strings )} print ( loc_mapping ) # {'a': 0, 'as': 1, 'bat': 2, 'car': 3, 'dove': 4, 'python': 5} 4. \u51fd\u6570\u58f0\u660e \u00b6 \u5982\u679cPython\u8fbe\u5230\u51fd\u6570\u7684\u5c3e\u90e8\u65f6\u4ecd\u7136\u6ca1\u6709\u9047\u5230return\u8bed\u53e5\uff0c\u5c31\u4f1a\u81ea\u52a8\u8fd4\u56deNone\u3002 \u6bcf\u4e2a\u51fd\u6570\u90fd\u53ef\u4ee5\u6709\u4f4d\u7f6e\u53c2\u6570\u548c\u5173\u952e\u5b57\u53c2\u6570\u3002\u5173\u952e\u5b57\u53c2\u6570\u6700\u5e38\u7528\u4e8e\u6307\u5b9a\u9ed8\u8ba4\u503c\u6216\u53ef\u9009\u53c2\u6570\u3002\u5173\u952e\u5b57\u53c2\u6570\u5fc5\u987b\u8ddf\u5728\u4f4d\u7f6e\u53c2\u6570\u540e\uff0c\u53ef\u4ee5\u4f7f\u7528\u5173\u952e\u5b57\u53c2\u6570\u5411\u4f4d\u7f6e\u53c2\u6570\u4f20\u53c2\u3002 import sys def my_function1 ( x , y , z = 1.5 ): if z > 1 : return z * ( x + y ) else : return z / ( x + y ) result1 = my_function1 ( 5 , 6 , z = 0.7 ) print ( result1 ) # 0.06363636363636363 result1 = my_function1 ( x = 5 , y = 6 , z = 0.7 ) print ( result1 ) # 0.06363636363636363 result1 = my_function1 ( 3.14 , 7 , 3.5 ) print ( result1 ) # 35.49 result1 = my_function1 ( 10 , 20 ) print ( result1 ) # 45.0 5. \u547d\u540d\u7a7a\u95f4\u3001\u4f5c\u7528\u57df\u548c\u672c\u5730\u51fd\u6570 \u00b6 \u51fd\u6570\u6709\u4e24\u79cd\u8fde\u63a5\u53d8\u91cf\u7684\u65b9\u5f0f\uff1a\u5168\u5c40\u3001\u672c\u5730\u3002 def func1 (): list1 = [] # \u672c\u5730\u53d8\u91cf for i in range ( 5 ): list1 . append ( i ) print ( list1 ) func1 () # [0, 1, 2, 3, 4] list2 = [] # \u5168\u5c40\u53d8\u91cf def func2 (): global list2 # \u5168\u5c40\u53d8\u91cf for i in range ( 5 ): list2 . append ( i ) print ( list2 ) func2 () # [0, 1, 2, 3, 4] \u6570\u636e\u6e05\u6d17\u793a\u4f8b states = [ ' Alabama' , 'Georgia!' , 'georgia' , 'Georgia' , 'FlOrIda' , 'south carolina##' , 'West virginia? ' ] # \u65b9\u6cd51 import re def clean_string1 ( strings ): result2 = [] for value in strings : value = value . strip () value = re . sub ( '[! #? ]' , '' , value ) value = value . title () result2 . append ( value ) return result2 print ( clean_string1 (( states ))) # ['Alabama', 'Georgia', 'Georgia', 'Georgia', 'Florida', 'Southcarolina', 'Westvirginia'] # \u65b9\u6cd52 def remove_punctuaion ( value ): return re . sub ( '[! #? ]' , '' , value ) clean_ops = [ str . strip , remove_punctuaion , str . title ] def clean_string2 ( strings , ops ): result3 = [] for value in strings : for function in ops : value = function ( value ) result3 . append ( value ) return result3 result4 = clean_string2 ( states , clean_ops ) print ( result4 ) # ['Alabama', 'Georgia', 'Georgia', 'Georgia', 'Florida', 'Southcarolina', 'Westvirginia'] # \u53ef\u4ee5\u5c06\u51fd\u6570\u4f5c\u4e3a\u4e00\u4e2a\u53c2\u6570\u4f20\u7ed9\u5176\u4ed6\u7684\u51fd\u6570\u3002 for x in map ( remove_punctuaion , states ): print ( x ) # Alabama # Georgia # georgia # Georgia # FlOrIda # southcarolina # Westvirginia 6. \u67ef\u91cc\u5316\uff1a\u90e8\u5206\u53c2\u6570\u5e94\u7528 \u00b6 \u67ef\u91cc\u5316\u662f\u8ba1\u7b97\u673a\u79d1\u5b66\u672f\u8bed\uff08\u4ee5\u6570\u5b66\u5bb6Haskell Curry\u547d\u540d\uff09\uff0c\u5b83\u8868\u793a\u901a\u8fc7\u90e8\u5206\u53c2\u6570\u5e94\u7528\u7684\u65b9\u5f0f\u4ece\u5df2\u6709\u7684\u51fd\u6570\u4e2d\u884d\u751f\u51fa\u65b0\u7684\u51fd\u6570\u3002\u67ef\u91cc\u5316\u662f\u4e00\u79cd\u5c06\u591a\u53c2\u6570\u51fd\u6570\u8f6c\u5316\u4e3a\u5355\u53c2\u6570\u9ad8\u9636\u51fd\u6570\u7684\u6280\u672f\uff0c\u5982\u679c\u4f60\u56fa\u5b9a\u67d0\u4e9b\u53c2\u6570\uff0c\u4f60\u5c06\u5f97\u5230\u63a5\u53d7\u4f59\u4e0b\u53c2\u6570\u7684\u4e00\u4e2a\u51fd\u6570\u3002 \u5b9a\u4e49\u4e00\uff1a \u67ef\u91cc\u5316\uff1a\u4e00\u4e2a\u51fd\u6570\u4e2d\u6709\u4e2a\u591a\u4e2a\u53c2\u6570\uff0c\u60f3\u56fa\u5b9a\u5176\u4e2d\u67d0\u4e2a\u6216\u8005\u51e0\u4e2a\u53c2\u6570\u7684\u503c\uff0c\u800c\u53ea\u63a5\u53d7\u53e6\u5916\u51e0\u4e2a\u8fd8\u672a\u56fa\u5b9a\u7684\u53c2\u6570\uff0c\u8fd9\u6837\u51fd\u6570\u6f14\u53d8\u6210\u65b0\u7684\u51fd\u6570\u3002 \u5b9a\u4e49\u4e8c\uff1a \u51fd\u6570\u67ef\u91cc\u5316\uff08currying\uff09\u53c8\u79f0\u90e8\u5206\u6c42\u503c\u3002\u4e00\u4e2a currying \u7684\u51fd\u6570\u9996\u5148\u4f1a\u63a5\u53d7\u4e00\u4e9b\u53c2\u6570\uff0c\u63a5\u53d7\u4e86\u8fd9\u4e9b\u53c2\u6570\u4e4b\u540e\uff0c\u8be5\u51fd\u6570\u5e76\u4e0d\u4f1a\u7acb\u5373\u6c42\u503c\uff0c\u800c\u662f\u7ee7\u7eed\u8fd4\u56de\u53e6\u5916\u4e00\u4e2a\u51fd\u6570\uff0c\u521a\u624d\u4f20\u5165\u7684\u53c2\u6570\u5728\u51fd\u6570\u5f62\u6210\u7684\u95ed\u5305\u4e2d\u88ab\u4fdd\u5b58\u8d77\u6765\u3002\u5f85\u5230\u51fd\u6570\u88ab\u771f\u6b63\u9700\u8981\u6c42\u503c\u7684\u65f6\u5019\uff0c\u4e4b\u524d\u4f20\u5165\u7684\u6240\u6709\u53c2\u6570\u90fd\u4f1a\u88ab\u4e00\u6b21\u6027\u7528\u4e8e\u6c42\u503c\u3002 \u5b9a\u4e49\u4e09\uff1a \u4e00\u4e9b\u51fd\u6570\u5f0f\u8bed\u8a00\u7684\u5de5\u4f5c\u539f\u7406\u662f\u5c06\u591a\u53c2\u6570\u51fd\u6570\u8bed\u6cd5\u8f6c\u5316\u4e3a\u5355\u53c2\u6570\u51fd\u6570\u96c6\u5408\uff0c\u8fd9\u4e00\u8fc7\u7a0b\u79f0\u4e3a\u67ef\u91cc\u5316\uff0c\u5b83\u662f\u4ee5\u903b\u8f91\u5b66\u5bb6Haskell Curry\u7684\u540d\u5b57\u547d\u540d\u7684\u3002Haskell Curry\u4ece\u65e9\u671f\u6982\u5ff5\u4e2d\u53d1\u5c55\u51fa\u4e86\u8be5\u7406\u8bba\u3002\u5176\u5f62\u5f0f\u76f8\u5f53\u4e8e\u5c06z=f(x, y)\u8f6c\u6362\u6210z=f(x)(y)\u7684\u5f62\u5f0f\uff0c\u539f\u51fd\u6570\u7531\u4e24\u4e2a\u53c2\u6570\uff0c\u73b0\u5728\u53d8\u4e3a\u4e24\u4e2a\u63a5\u53d7\u5355\u53c2\u6570\u7684\u51fd\u6570\uff0c \u793a\u4f8b1\uff1a\u67ef\u91cc\u5316\u7684\u8fc7\u7a0b\u5c31\u662f\u628a\u539f\u6765\u5e26\u4e24\u4e2a\u53c2\u6570\u7684\u51fd\u6570add(x, y)\uff0c\u53d8\u6210\u4e86\u4e00\u4e2a\u5d4c\u5957\u51fd\u6570\uff0c\u5728add_currying\u51fd\u6570\u5185\uff0c\u53c8\u5b9a\u4e49\u4e86\u4e00\u4e2a_add\u51fd\u6570\uff0c\u5e76\u4e14_add\u51fd\u6570\u53c8\u5f15\u7528\u4e86\u5916\u90e8\u51fd\u6570add_currying\u7684\u53d8\u91cfx\uff0c\u8fd9\u5c31\u662f\u4e00\u4e2a\u95ed\u5305\u3002 \u95ed\u5305\uff0c\u4e00\u53e5\u8bdd\u8bf4\u5c31\u662f\u5728\u51fd\u6570\u4e2d\u518d\u5d4c\u5957\u4e00\u4e2a\u51fd\u6570\uff0c\u5e76\u4e14\u5f15\u7528\u5916\u90e8\u51fd\u6570\u7684\u53d8\u91cf\u3002 # \u666e\u901a\u5199\u6cd5 def add ( x , y ): return x + y print ( add ( 1 , 2 )) # 3 # \u67ef\u91cc\u5316\u5199\u6cd5 def add_currying ( x ): def _add ( y ): return x + y return _add print ( add_currying ( 1 )( 2 )) # 3 \u793a\u4f8b2\uff0c\u901a\u8fc7\u56fa\u5b9a\u5176\u4e2d\u7684\u7b2c\u4e8c\u4e2a\u53c2\u6570\u4e0d\u53d8\u6765\u5b9e\u73b0\u67ef\u91cc\u5316\u3002 def add2 ( a , b ): def add1 ( a , b , c ): return a + b + c return add1 ( a , 666 , b ) result6 = add2 ( 12 , 13 ) print ( result6 ) # 691 result6 = add2 ( 12 , 555 , 13 ) # TypeError: add2() takes 2 positional arguments but 3 were given \u793a\u4f8b3\uff0c\u901a\u8fc7functools\u63d0\u4f9b\u7684\u504f\u51fd\u6570\u6765\u5b9e\u73b0\u67ef\u91cc\u5316\u3002 from functools import partial def add1 ( a , b , c ): return a + b + c add3 = partial ( add1 , b = 666 ) result7 = add3 ( a = 12 , c = 13 ) print ( result7 ) # 691 \u793a\u4f8b4\uff0c\u901a\u8fc7lambda\u8868\u8fbe\u5f0f\u6765\u5b9e\u73b0\u67ef\u91cc\u5316\u3002 def add1 ( a , b , c ): return a + b + c add4 = lambda x , y : add1 ( x , 666 , y ) result8 = add4 ( 12 , 13 ) print ( result8 ) # 691 \u793a\u4f8b5\uff0c\u901a\u8fc7python\u7684\u88c5\u9970\u5668\u6765\u5b9e\u73b0\u67ef\u91cc\u5316 def add1 ( a , b , c ): return a + b + c def currying_add ( func ): def wrapper ( a , c , b = 666 ): return func ( a , b , c ) return wrapper result9 = currying_add ( add1 )( 12 , 13 ) print ( result9 ) # 691 \u793a\u4f8b6\uff0c\u901a\u8fc7python\u7684\u88c5\u9970\u5668\u7b26\u53f7@\u6765\u5b9e\u73b0\u67ef\u91cc\u5316 def currying_add ( func ): def wrapper ( a , c , b = 666 ): return func ( a , b , c ) return wrapper @currying_add def add5 ( a , b , c ): return a + b + c result10 = add5 ( 12 , 13 ) print ( result10 ) # 691 7. \u8fed\u4ee3\u5668\u4e0e\u751f\u6210\u5668 \u00b6 \u8fed\u4ee3\u5668 \u00b6 \u8fed\u4ee3\u662fPython\u6700\u5f3a\u5927\u7684\u529f\u80fd\u4e4b\u4e00\uff0c\u662f\u8bbf\u95ee\u96c6\u5408\u5143\u7d20\u7684\u4e00\u79cd\u65b9\u5f0f\u3002\u8fed\u4ee3\u5668\u662f\u4e00\u4e2a\u53ef\u4ee5\u8bb0\u4f4f\u904d\u5386\u7684\u4f4d\u7f6e\u7684\u5bf9\u8c61\u3002 \u8fed\u4ee3\u5668\u5bf9\u8c61\u4ece\u96c6\u5408\u7684\u7b2c\u4e00\u4e2a\u5143\u7d20\u5f00\u59cb\u8bbf\u95ee\uff0c\u76f4\u5230\u6240\u6709\u7684\u5143\u7d20\u88ab\u8bbf\u95ee\u5b8c\u7ed3\u675f\u3002\u8fed\u4ee3\u5668\u53ea\u80fd\u5f80\u524d\u4e0d\u4f1a\u540e\u9000\u3002 \u8fed\u4ee3\u5668\u6709\u4e24\u4e2a\u57fa\u672c\u7684\u65b9\u6cd5\uff1aiter() \u548c next()\u3002 \u8fed\u4ee3\u5668\u793a\u4f8b\uff1a list_a = [ 1 , 2 , 3 , 4 ] it = iter ( list_a ) # \u521b\u5efa\u8fed\u4ee3\u5668\u5bf9\u8c61 print ( next ( it )) # \u8f93\u51fa\u8fed\u4ee3\u5668\u7684\u4e0b\u4e00\u4e2a\u5143\u7d20 # 1 print ( next ( it )) # \u8f93\u51fa\u8fed\u4ee3\u5668\u7684\u4e0b\u4e00\u4e2a\u5143\u7d20 # 2 \u8fed\u4ee3\u5668\u5bf9\u8c61\u53ef\u4ee5\u4f7f\u7528\u5e38\u89c4for\u8bed\u53e5\u8fdb\u884c\u904d\u5386\u3002 list_a = [ 1 , 2 , 3 , 4 ] it = iter ( list_a ) # \u521b\u5efa\u8fed\u4ee3\u5668\u5bf9\u8c61 for x in it : print ( x , end = \" \" ) print ( end = \" \\n \" ) # 1 2 3 4 \u751f\u6210\u5668 \u00b6 \u5728 Python \u4e2d\uff0c\u4f7f\u7528\u4e86 yield \u7684\u51fd\u6570\u88ab\u79f0\u4e3a\u751f\u6210\u5668\uff08generator\uff09\u3002\u8ddf\u666e\u901a\u51fd\u6570\u4e0d\u540c\u7684\u662f\uff0c\u751f\u6210\u5668\u662f\u4e00\u4e2a\u8fd4\u56de\u8fed\u4ee3\u5668\u7684\u51fd\u6570\uff0c\u53ea\u80fd\u7528\u4e8e\u8fed\u4ee3\u64cd\u4f5c\uff0c\u751f\u6210\u5668\u5c31\u662f\u4e00\u4e2a\u8fed\u4ee3\u5668\u3002 \u5728\u8c03\u7528\u751f\u6210\u5668\u8fd0\u884c\u7684\u8fc7\u7a0b\u4e2d\uff0c\u6bcf\u6b21\u9047\u5230 yield \u65f6\u51fd\u6570\u4f1a\u6682\u505c\u5e76\u4fdd\u5b58\u5f53\u524d\u6240\u6709\u7684\u8fd0\u884c\u4fe1\u606f\uff0c\u8fd4\u56de yield \u7684\u503c, \u5e76\u5728\u4e0b\u4e00\u6b21\u6267\u884c next() \u65b9\u6cd5\u65f6\u4ece\u5f53\u524d\u4f4d\u7f6e\u7ee7\u7eed\u8fd0\u884c\u3002 \u8c03\u7528\u4e00\u4e2a\u751f\u6210\u5668\u51fd\u6570\uff0c\u8fd4\u56de\u7684\u662f\u4e00\u4e2a\u8fed\u4ee3\u5668\u5bf9\u8c61\u3002 \u793a\u4f8b, \u6590\u6ce2\u90a3\u5951\u6570\u5217\uff1a def fibonacci ( n ): a , b , counter = 0 , 1 , 0 while True : if ( counter > n ): return yield a a , b = b , a + b counter += 1 f = fibonacci ( 10 ) # f \u662f\u4e00\u4e2a\u8fed\u4ee3\u5668\uff0c\u7531\u751f\u6210\u5668\u8fd4\u56de\u751f\u6210 print ( f ) # \u5b9e\u9645\u8c03\u7528\u751f\u6210\u5668\u65f6\uff0c\u4ee3\u7801\u5e76\u4e0d\u4f1a\u7acb\u5373\u6267\u884c for x in f : # \u8bf7\u6c42\u751f\u6210\u5668\u4e2d\u7684\u5143\u7d20\u65f6\uff0c\u5b83\u624d\u4f1a\u6267\u884c\u5b83\u7684\u4ee3\u7801 print ( x , end = \" \" ) print ( end = \" \\n \" ) # 0 1 1 2 3 5 8 13 21 34 55 \u751f\u6210\u5668\u8868\u8fbe\u5f0f\uff1a \u7528\u751f\u6210\u5668\u8868\u8fbe\u5f0f\u6765\u521b\u5efa\u751f\u6210\u5668\u66f4\u4e3a\u7b80\u5355\u3002\u751f\u6210\u5668\u8868\u8fbe\u5f0f\u4e0e\u5217\u8868\u3001\u5b57\u5178\u3001\u96c6\u5408\u7684\u63a8\u5bfc\u5f0f\u5f88\u7c7b\u4f3c\uff0c\u521b\u5efa\u4e00\u4e2a\u751f\u6210\u5668\u8868\u8fbe\u5f0f\uff0c\u53ea\u9700\u8981\u5c06\u5217\u8868\u63a8\u5bfc\u5f0f\u7684\u4e2d\u62ec\u53f7\u66ff\u6362\u4e3a\u5c0f\u62ec\u53f7\u5373\u53ef\u3002 gen1 = ( x ** 2 for x in range ( 100 )) print ( gen1 ) # at 0x7fd3f30c9580> \u4e0a\u9762\u7684\u4ee3\u7801\u4e0e\u4e0b\u9762\u7684\u751f\u6210\u5668\u662f\u7b49\u4ef7\u7684 def _make_gen (): for x in range ( 100 ): yield x ** 2 gen2 = _make_gen () print ( gen2 ) # \u751f\u6210\u5668\u8868\u8fbe\u5f0f\u53ef\u4ee5\u4f5c\u4e3a\u51fd\u6570\u53c2\u6570\u7528\u4e8e\u66ff\u4ee3\u5217\u8868\u63a8\u5bfc\u5f0f\u3002\u5bf9\u6bd4\u4e0b\u97622\u4e2a\u4f8b\u5b50\u3002 # \u793a\u4f8b1 result11 = sum ( x ** 2 for x in range ( 100 )) print ( result11 ) # 328350 gen1 = ( x ** 2 for x in range ( 100 )) result11 = sum ( gen1 ) print ( result11 ) # 328350 # \u793a\u4f8b2 result12 = dict (( i , i ** 2 ) for i in range ( 5 )) print ( result12 ) # {0: 0, 1: 1, 2: 4, 3: 9, 4: 16} gen2 = (( i , i ** 2 ) for i in range ( 5 )) result12 = dict ( gen2 ) print ( result12 ) # {0: 0, 1: 1, 2: 4, 3: 9, 4: 16} \u751f\u6210\u5668\uff1aitertools\u6a21\u5757 \u00b6 \u6807\u51c6\u5e93\u4e2d\u7684itertools\u6a21\u5757\u662f\u9002\u7528\u4e8e\u5927\u591a\u6570\u6570\u636e\u7b97\u6cd5\u7684\u751f\u6210\u5668\u96c6\u5408\u3002 import itertools first_letter = lambda x : x [ 0 ] names = [ 'Alan' , 'Adam' , 'Wes' , 'Will' , 'Albert' , 'Steven' ] for letter , names in itertools . groupby ( names , first_letter ): print ( letter ) print ( first_letter ) print ( letter , list ( names )) # names is generator # A # at 0x7fa598a7a0d0> # A ['Alan', 'Adam'] # W # at 0x7fa598a7a0d0> # W ['Wes', 'Will'] # A # at 0x7fa598a7a0d0> # A ['Albert'] # S # at 0x7fa598a7a0d0> # S ['Steven'] 8. \u9519\u8bef\u548c\u5f02\u5e38\u5904\u7406 \u00b6 Python\u7528\u5f02\u5e38\u5bf9\u8c61(exception object)\u6765\u8868\u793a\u5f02\u5e38\u60c5\u51b5\u3002\u9047\u5230\u9519\u8bef\u540e\uff0c\u4f1a\u5f15\u53d1\u5f02\u5e38\u3002\u5982\u679c\u5f02\u5e38\u5bf9\u8c61\u5e76\u672a\u88ab\u5904\u7406\u6216\u6355\u6349\uff0c\u7a0b\u5e8f\u5c31\u4f1a\u7528\u6240\u8c13\u7684\u56de\u6eaf(traceback\uff0c \u4e00\u79cd\u9519\u8bef\u4fe1\u606f)\u7ec8\u6b62\u6267\u884c\u3002 \u5f02\u5e38\u548c\u8bed\u6cd5\u9519\u8bef\u662f\u6709\u533a\u522b\u7684\u3002 \u9519\u8bef\uff1a\u662f\u6307\u4ee3\u7801\u4e0d\u7b26\u5408\u89e3\u91ca\u5668\u6216\u8005\u7f16\u8bd1\u5668\u8bed\u6cd5\u3002 \u5f02\u5e38\uff1a\u662f\u6307\u4e0d\u5b8c\u6574\u3001\u4e0d\u5408\u6cd5\u8f93\u5165\uff0c\u6216\u8005\u8ba1\u7b97\u51fa\u73b0\u9519\u8bef\u3002 python\u91cc\u7528try...except...\u8bed\u53e5\u6765\u5904\u7406\u5f02\u5e38\u60c5\u51b5\u3002 def attempt_float ( x ): try : return float ( x ) except ( TypeError , ValueError ): return \"Type error, not numbers\" r1 = attempt_float ( '1.2256' ) print ( r1 ) # 1.2256 r1 = attempt_float ( 'friends' ) print ( r1 ) # Type error, not numbers 9. \u6587\u4ef6\u4e0e\u64cd\u4f5c\u7cfb\u7edf \u00b6 f=open(path, 'w')\uff0c\u4e00\u4e2a\u65b0\u7684\u6587\u4ef6\u4f1a\u5728path\u6307\u5b9a\u7684\u8def\u5f84\u88ab\u521b\u5efa\uff0c\u5e76\u5728\u540c\u4e00\u8def\u5f84\u4e0b\u8986\u76d6\u540c\u540d\u6587\u4ef6\u3002\uff08\u8bf7\u5c0f\u5fc3\uff01\uff09 f=open(path, 'x')\uff0c\u4e00\u4e2a\u65b0\u7684\u6587\u4ef6\u4f1a\u5728path\u6307\u5b9a\u7684\u8def\u5f84\u88ab\u521b\u5efa\uff0c\u5982\u679c\u7ed9\u5b9a\u8def\u5f84\u4e0b\u5df2\u7ecf\u5b58\u5728\u540c\u540d\u6587\u4ef6\u5c31\u4f1a\u521b\u5efa\u5931\u8d25\u3002 import os # \u67e5\u770b\u5f53\u524d\u8def\u5f84 os . getcwd () # '/opt/myMemo' # \u66f4\u6539\u6587\u4ef6\u8bfb\u53d6\u9ed8\u8ba4\u8def\u5f84 os . chdir ( '/opt/myMemo/python/datasets/examples' ) # \u6307\u5b9a\u6587\u4ef6\u540d path = 'file01.txt' # \u6253\u5f00\u6587\u4ef6 f = open ( path ) # \u8bfb\u53d6\u6587\u4ef6\u6bcf\u4e00\u884c\uff0c\u6587\u4ef6\u6bcf\u4e00\u884c\u4f5c\u4e3a\u5217\u8868\u4e00\u4e2a\u5143\u7d20 lines = [ x . rstrip () for x in open ( path )] # \u8f93\u51fa\u5217\u8868 print ( lines ) # \u5173\u95ed\u6587\u4ef6\u4f1a\u5c06\u8d44\u6e90\u91ca\u653e\u56de\u64cd\u4f5c\u7cfb\u7edf f . close () \u53e6\u4e00\u79cd\u66f4\u7b80\u5355\u7684\u5173\u95ed\u6587\u4ef6\u7684\u65b9\u5f0f import os # \u67e5\u770b\u5f53\u524d\u8def\u5f84 os . getcwd () # '/opt/myMemo' # \u66f4\u6539\u6587\u4ef6\u8bfb\u53d6\u9ed8\u8ba4\u8def\u5f84 os . chdir ( '/opt/myMemo/python/datasets/examples' ) # \u6307\u5b9a\u6587\u4ef6\u540d path = 'file01.txt' # \u6253\u5f00\u6587\u4ef6 f = open ( path ) # \u4f7f\u7528with\u8bed\u53e5\u8bfb\u53d6\u6587\u4ef6\uff0c\u6587\u4ef6\u4f1a\u5728with\u4ee3\u7801\u5757\u7ed3\u675f\u540e\u81ea\u52a8\u5173\u95ed\u3002 with open ( path ) as f : lines = [ x . rstrip () for x in open ( path )] # \u8f93\u51fa\uff1a\u6587\u4ef6\u6bcf\u4e00\u884c\u4f5c\u4e3a\u5217\u8868\u4e00\u4e2a\u5143\u7d20 print ( lines ) \u5728\u6253\u5f00\u6587\u4ef6\u65f6\u4f7f\u7528seek\u8bfb\u53d6\u6587\u4ef6\u5185\u5bb9\u8981\u5f53\u5fc3\u3002\u5982\u679c\u6587\u4ef6\u7684\u53e5\u67c4\u4f4d\u7f6e\u6070\u597d\u5728\u4e00\u4e2aUnicode\u7b26\u53f7\u7684\u5b57\u8282\u4e2d\u95f4\u65f6\uff0c\u540e\u7eed\u7684\u8bfb\u53d6\u4f1a\u5bfc\u81f4\u9519\u8bef\u3002 import os # \u67e5\u770b\u5f53\u524d\u8def\u5f84 os . getcwd () # '/opt/myMemo' # \u66f4\u6539\u6587\u4ef6\u8bfb\u53d6\u9ed8\u8ba4\u8def\u5f84 os . chdir ( '/opt/myMemo/python/datasets/examples' ) # \u6307\u5b9a\u6587\u4ef6\u540d path = 'file01.txt' # \u6253\u5f00\u6587\u4ef6 f = open ( path ) # \u8bfb\u53d6\u6587\u4ef6\u3002 print ( f . read ( 5 )) # \u8f93\u51fa\u524d5\u4e2a\u5b57\u7b26\u3002 read\u65b9\u6cd5\u901a\u8fc7\u8bfb\u53d6\u7684\u5b57\u8282\u6570\u6765\u63a8\u8fdb\u6587\u4ef6\u53e5\u67c4\u7684\u4f4d\u7f6e\u3002 # I Thi print ( f . tell ()) # tell\u65b9\u6cd5\u53ef\u4ee5\u7ed9\u51fa\u53e5\u67c4\u5f53\u524d\u7684\u4f4d\u7f6e # 5 print ( f . seek ( 6 )) # seek\u65b9\u6cd5\u53ef\u4ee5\u5c06\u53e5\u67c4\u4f4d\u7f6e\u6539\u53d8\u5230\u6587\u4ef6\u4e2d\u7279\u5b9a\u7684\u5b57\u8282 # 6 print ( f . read ( 1 )) # \u4ece\u7b2c7\u4e2a\u5b57\u8282\u5f00\u59cb\uff0c\u8f93\u51fa1\u4e2a\u5b57\u8282 # k # \u5173\u95ed\u6587\u4ef6\u4f1a\u5c06\u8d44\u6e90\u91ca\u653e\u56de\u64cd\u4f5c\u7cfb\u7edf f . close () \u5982\u679c\u4f7f\u7528\u4e8c\u8fdb\u5236\u65b9\u5f0f\u6253\u5f00\u6587\u4ef6\uff0c\u5219\uff1a import os # \u67e5\u770b\u5f53\u524d\u8def\u5f84 os . getcwd () # '/opt/myMemo' # \u66f4\u6539\u6587\u4ef6\u8bfb\u53d6\u9ed8\u8ba4\u8def\u5f84 os . chdir ( '/opt/myMemo/python/datasets/examples' ) # \u6307\u5b9a\u6587\u4ef6\u540d path = 'file01.txt' # \u6253\u5f00\u6587\u4ef6 f2 = open ( path , 'rb' ) # \u4e8c\u8fdb\u5236\u6a21\u5f0f # \u8bfb\u53d6\u6587\u4ef6 print ( f2 . read ( 5 )) # \u7b2c\u4e00\u4e2ab\u4ee3\u8868\u4e8c\u8fdb\u5236\u683c\u5f0f # b'I Thi' print ( f2 . tell ()) # 5 print ( f2 . seek ( 6 )) # 6 print ( f2 . read ( 2 )) # \u4ece\u7b2c7\u4e2a\u5b57\u8282\u5f00\u59cb\uff0c\u8f93\u51fa2\u4e2a\u5b57\u8282 # b'k ' # \u5173\u95ed\u6587\u4ef6\u4f1a\u5c06\u8d44\u6e90\u91ca\u653e\u56de\u64cd\u4f5c\u7cfb\u7edf f2 . close () \u5c06\u672c\u6587\u5199\u5165\u6587\u4ef6\uff0c\u53ef\u4ee5\u4f7f\u7528\u6587\u4ef6\u5bf9\u8c61\u7684write\u6216wirtelines\u65b9\u6cd5\u3002 import os # \u67e5\u770b\u5f53\u524d\u8def\u5f84 os . getcwd () # '/opt/myMemo' # \u66f4\u6539\u6587\u4ef6\u8bfb\u53d6\u9ed8\u8ba4\u8def\u5f84 os . chdir ( '/opt/myMemo/python/datasets/examples' ) # \u6307\u5b9a\u6587\u4ef6\u540d path1 = 'file01.txt' path2 = 'file02.txt' # file02.txt\u662f\u4e00\u4e2a\u7a7a\u6587\u4ef6 with open ( path2 , 'r+' , encoding = 'utf-8' ) as f : f . writelines ( x for x in open ( path1 , 'r' , encoding = 'utf-8' ) if len ( x ) > 1 ) # \u628afile01.txt\u7684\u5185\u5bb9\u5199\u5165file02.txt lines = f . readlines () print ( lines ) 10. \u88c5\u9970\u5668 \u00b6 \u95ed\u5305 \u00b6 \u7ef4\u57fa\u767e\u79d1\u4e2d\u7684\u89e3\u91ca\uff1a \u95ed\u5305\uff08Closure\uff09 \uff0c\u53c8\u79f0\u8bcd\u6cd5\u95ed\u5305\uff08Lexical Closure\uff09\u6216\u51fd\u6570\u95ed\u5305\uff08function closures\uff09\uff0c\u662f\u5f15\u7528\u4e86\u81ea\u7531\u53d8\u91cf\u7684\u51fd\u6570\u3002\u8fd9\u4e2a\u88ab\u5f15\u7528\u7684\u81ea\u7531\u53d8\u91cf\u5c06\u548c\u8fd9\u4e2a\u51fd\u6570\u4e00\u540c\u5b58\u5728\uff0c\u5373\u4f7f\u5df2\u7ecf\u79bb\u5f00\u4e86\u521b\u9020\u5b83\u7684\u73af\u5883\u4e5f\u4e0d\u4f8b\u5916\u3002 \u95ed\u5305\u5ef6\u4f38\u4e86\u4f5c\u7528\u57df\u7684\u51fd\u6570\uff0c\u5176\u4e2d\u5305\u542b\u51fd\u6570\u5b9a\u4e49\u4f53\u4e2d\u5f15\u7528\u3001\u4f46\u662f\u4e0d\u5728\u5b9a\u4e49\u4f53\u4e2d\u5b9a\u4e49\u7684\u975e\u5168\u5c40\u53d8\u91cf\u3002\u51fd\u6570\u662f\u4e0d\u662f\u533f\u540d\u7684\u6ca1\u6709\u5173\u7cfb\uff0c\u5173\u952e\u662f\u5b83\u80fd\u8bbf\u95ee\u5b9a\u4e49\u4f53\u4e4b\u5916\u5b9a\u4e49\u7684\u975e\u5168\u5c40\u53d8\u91cf\u3002 \u4f8b\u4e00\uff0c\u8ba1\u7b97\u79fb\u52a8\u5e73\u5747\u503c\u3002 \u4e0b\u9762\u662f\u662f\u4f20\u7edf\u7c7b\u5b9e\u73b0\u65b9\u5f0f\uff0cAvg\u7684\u5b9e\u4f8b\u662f\u53ef\u8c03\u7528\u7684\u5bf9\u8c61\u3002 class Avg (): def __init__ ( self ): self . mylist = [] def __call__ ( self , newValue ): self . mylist . append ( newValue ) total = sum ( self . mylist ) return total / len ( self . mylist ) avg = Avg () avg ( 10 ) # 10.0 avg ( 20 ) # 15.0 avg ( 30 ) # 20.0 \u4e0b\u9762\u662f\u9ad8\u9636\u51fd\u6570\u5b9e\u73b0\u65b9\u5f0f\u3002\u8c03\u7528 make_avg \u65f6\uff0c\u8fd4\u56de\u4e00\u4e2a my_avg \u51fd\u6570\u5bf9\u8c61\u3002\u6bcf\u6b21\u8c03\u7528 my_avg \u65f6\uff0c\u5b83\u4f1a\u628a\u53c2\u6570\u6dfb\u52a0\u5230\u7cfb\u5217\u503c\u4e2d\uff0c\u7136\u540e\u8ba1\u7b97\u5f53\u524d\u5e73\u5747\u503c\u3002 def make_avg (): my_list = [] def avg ( newValue ): my_list . append ( newValue ) total = sum ( my_list ) return total / len ( my_list ) return avg my_avg = make_avg () my_avg ( 10 ) # 10.0 my_avg ( 20 ) # 15.0 my_avg ( 30 ) # 20.0 my_avg . __code__ . co_varnames # ('newValue', 'total') my_avg . __code__ . co_freevars # ('my_list',) my_avg . __closure__ # (,) my_avg . __closure__ [ 0 ] . cell_contents # [10, 20, 30] \u8fd9\u4e24\u4e2a\u793a\u4f8b\u6709\u5171\u901a\u4e4b\u5904\uff1a\u8c03\u7528 Avg() \u6216 make_avg() \u5f97\u5230\u4e00\u4e2a\u53ef\u8c03\u7528\u5bf9\u8c61 avg \uff0c\u5b83\u4f1a\u66f4\u65b0\u5386\u53f2\u503c\uff0c\u7136\u540e\u8ba1\u7b97\u5f53\u524d\u5747\u503c\u3002 \u5728\u7c7b\u5b9e\u73b0\u4e2d\uff0c avg \u662f Avg \u7684\u5b9e\u4f8b\uff1b\u5728\u9ad8\u9636\u51fd\u6570\u5b9e\u73b0\u4e2d\u662f\u5185\u90e8\u51fd\u6570 avg \u3002 \u4e24\u79cd\u5b9e\u73b0\u65b9\u5f0f\u4e2d\uff0c\u6211\u4eec\u90fd\u53ea\u9700\u8c03\u7528 avg(n) \uff0c\u628a n \u653e\u5165\u7cfb\u5217\u503c\u4e2d\uff0c\u7136\u540e\u91cd\u65b0\u8ba1\u7b97\u5747\u503c\u3002 \u7b2c\u4e00\u4e2a\u4f8b\u5b50\u4e2d\uff0c Avg \u7c7b\u7684\u5b9e\u4f8b avg \u5728 self.series \u5b9e\u4f8b\u5c5e\u6027\u4e2d\u5b58\u50a8\u5386\u53f2\u503c\u3002 \u7b2c\u4e8c\u4e2a\u4f8b\u5b50\u4e2d\u7684 my_list \u662f\u51fd\u6570 make_avg() \u7684\u5c40\u90e8\u53d8\u91cf\uff0c\u4e5f\u79f0\u4e3a\u8be5\u51fd\u6570\u7684**\u81ea\u7531\u53d8\u91cf\uff08free variable\uff09**\uff0c\u6307\u672a\u5728\u672c\u5730\u4f5c\u7528\u57df\u4e2d\u7ed1\u5b9a\u7684\u53d8\u91cf\u3002 avg() \u51fd\u6570\u7684\u95ed\u5305\u5ef6\u4f38\u5230\u51fd\u6570\u7684\u4f5c\u7528\u57df\u4e4b\u5916\uff0c\u5305\u542b\u4e86 make_avg() \u7684\u81ea\u7531\u53d8\u91cf my_list \u7684\u7ed1\u5b9a\u3002 \u5bf9\u4e8e\u8fd4\u56de\u7684 my_avg \u5bf9\u8c61\uff0c\u5176 __code__ \u5c5e\u6027\uff08\u8868\u793a\u7f16\u8bd1\u540e\u7684\u51fd\u6570\u5b9a\u4e49\u4f53\uff09\u4e2d\u4fdd\u5b58\u4e86\u5c40\u90e8\u53d8\u91cf\u548c\u81ea\u7531\u53d8\u91cf\u7684\u540d\u79f0\uff0c\u5373 my_avg.__code__.co_varnames \u8fd4\u56de\u4e86\u5c40\u90e8\u53d8\u91cf ('newValue', 'total') \u548c my_avg.__code__.co_freevars \u8fd4\u56de\u4e86\u81ea\u7531\u53d8\u91cf ('my_list',) \u3002 \u81ea\u7531\u53d8\u91cf my_list \u7ed1\u5b9a\u5728\u8fd4\u56de\u7684 my_avg \u7684 __closure__ \u7684\u5c5e\u6027\u4e2d\uff0c my_avg.__closure__ \u4e2d\u7684\u5404\u4e2a\u5143\u7d20\u5bf9\u5e94\u4e86 my_avg.__code__.co_freevars \u4e2d\u7684\u4e00\u4e2a\u540d\u79f0\u3002\u8fd9\u4e9b\u5143\u7d20\u662f cell \u5bf9\u8c61\uff0c\u6709\u4e2a cell_contents \u5c5e\u6027\uff0c\u5982\uff1a my_avg.__closure__ \u8fd4\u56de (,) \uff0c\u91cc\u9762\u4fdd\u5b58\u7740\u771f\u6b63\u7684\u503c\uff0c\u5982 my_avg.__closure__[0].cell_contents \u91cc\u9762\u4fdd\u5b58\u6bcf\u6b21\u8c03\u7528\u7684\u771f\u5b9e\u503c [10, 20, 30] \u3002 \u4e0a\u9762 my_list \u662f\u4e00\u4e2a\u53ef\u53d8\u7c7b\u578b\uff0c\u5982\u679c\u7528\u4e0d\u53ef\u53d8\u7c7b\u578b\u6539\u5199\uff0c\u5e76\u5b9e\u73b0\u95ed\u5305\uff0c\u53ef\u4ee5\u4f7f\u7528 nolocal \u8fdb\u884c\u58f0\u660e\u3002\u5b83\u7684\u4f5c\u7528\u662f\u628a\u53d8\u91cf\u6807\u8bb0\u4e3a\u81ea\u7531\u53d8\u91cf\uff0c\u5373\u4f7f\u5728\u51fd\u6570\u4e2d\u4e3a\u53d8\u91cf\u8d4b\u4e88\u65b0\u503c\u4e86\uff0c\u4e5f\u4f1a\u53d8\u6210\u81ea\u7531\u53d8\u91cf\u3002\u5982\u679c\u4e3anonlocal\u58f0\u660e\u7684\u53d8\u91cf\u8d4b\u4e88\u65b0\u503c\uff0c\u95ed\u5305\u4e2d\u4fdd\u5b58\u7684\u7ed1\u5b9a\u4f1a\u66f4\u65b0\u3002 my_avg.__code__.co_freevars \u8fd4\u56de\u4e862\u4e2a\u81ea\u7531\u53d8\u91cf ('count', 'total') \uff0c\u5e76\u5728 my_avg.__closure__[0].cell_contents \u548c my_avg.__closure__[1].cell_contents \u91cc\u9762\u4fdd\u5b58\u4e86\u6700\u540e\u4e00\u6b21\u6267\u884c\u7684\u771f\u5b9e\u503c\u3002 def make_avg (): count = 0 total = 0 def avg ( newValue ): nonlocal count , total count += 1 total += newValue return total / count return avg my_avg = make_avg () my_avg ( 10 ) # 10.0 my_avg ( 20 ) # 15.0 my_avg ( 30 ) # 20.0 my_avg . __code__ . co_varnames # ('newValue',) my_avg . __code__ . co_freevars # ('count', 'total') my_avg . __closure__ # (, ) my_avg . __closure__ [ 0 ] . cell_contents # 3 my_avg . __closure__ [ 1 ] . cell_contents # 60 \u4f8b\u4e8c\uff1a money \u662f\u4e00\u4e2a\u5c40\u90e8\u53d8\u91cf\uff0c\u5728 get_money \u662f\u5916\u56f4\u51fd\u6570\uff0c\u51fd\u6570\u6267\u884c\u4e4b\u540e\u5e94\u8be5\u5c31\u4e0d\u4f1a\u5b58\u5728\u4e86\u3002 \u4f46\u662f\u5d4c\u5957\u51fd\u6570 work \u5f15\u7528\u4e86 money \u8fd9\u4e2a\u81ea\u7531\u53d8\u91cf\uff0c\u5c06\u8fd9\u4e2a\u5c40\u90e8\u53d8\u91cf\u5c01\u95ed\u5728\u4e86\u5d4c\u5957\u51fd\u6570 work \u4e2d\uff0c\u8fd9\u6837\u5c31\u5f62\u6210\u4e86\u4e00\u4e2a\u95ed\u5305\u3002 closure = get_money() \u83b7\u5f97\u7684\u5c31\u662f\u4e00\u4e2a\u95ed\u5305\u3002 closure() \u8f93\u51fa\u95ed\u5305\uff0c\u5373\uff0c\u6267\u884c\u4e86 work() \uff0c\u6253\u5370\u8f93\u51fa money \u7684\u503c\u3002 \u672c\u5730\u51fd\u6570\u901a\u8fc7global\u58f0\u660e\u5bf9\u5168\u5c40\u53d8\u91cf\u8fdb\u884c\u5f15\u7528\u4fee\u6539\uff0c\u90a3\u4e48\u5bf9\u4e8e\u5185\u5d4c\u51fd\u6570 work() \u4f5c\u7528\u57df\u4e2d\u7684\u53d8\u91cf\u8fdb\u884c\u4fee\u6539\uff0c\u5c31\u8981\u4f7f\u7528 nonlocal \u8fdb\u884c\u58f0\u660e\u3002 def get_money (): money = 0 def work (): nonlocal money money += 100 print ( money ) return work closure = get_money () closure () # 100 closure () # 200 closure () # 300 \u4f8b\u4e09\uff1a \u51fd\u6570 maker \u4e2d\u5b9a\u4e49\u4e86\u51fd\u6570 action \uff0c action \u5f15\u7528\u4e86 maker \u5d4c\u5957\u4f5c\u7528\u57df\u5185\u7684\u53d8\u91cf k \uff0c\u5e76\u4e14\uff0c maker \u5c06\u51fd\u6570 action \u4f5c\u4e3a\u8fd4\u56de\u5bf9\u8c61\u8fdb\u884c\u8fd4\u56de\u3002 \u8fd9\u6837\uff0c\u6211\u4eec\u901a\u8fc7\u6267\u884c f = maker(2) \uff0c f \u83b7\u53d6\u4e86\u8fd4\u56de\u5bf9\u8c61 action \uff0c\u867d\u7136\u6b64\u65f6 maker \u51fd\u6570\u4ee5\u53ca\u7ed3\u675f\u9000\u51fa\u4e86\uff0c\u4f46\u5bf9\u8c61 f \u4ecd\u7136\u8bb0\u4f4f\u4e86\u51fd\u6570 maker \u5d4c\u5957\u4f5c\u7528\u57df\u5185\u7684\u53d8\u91cf k \u548c n \uff0c\u5e76\u5728\u6267\u884c f(3) \u65f6\uff0c\u5c06 x=3 \u4ee5\u53ca\u4e4b\u524d\u8bb0\u4f4f\u7684 k \u548c n \uff0c\u4e00\u5e76\u4f20\u5165 action() \uff0c\u8ba1\u7b97\u5e76\u8fd4\u56de x + n + k \u503c\u3002 make \u4e5f\u79f0\u4e3a**\u5de5\u5382\u51fd\u6570**\u3002 def maker ( n ): k = 8 def action ( x ): return x + n + k return action f = maker ( 2 ) print ( f ( 3 )) # 13 print ( f ( 4 )) # 14 print ( f ( 5 )) # 15 \u7ed3\u5408\u524d\u97622\u4e2a\u4f8b\u5b50\u518d\u770b\u4e0a\u9762\u7684\u89e3\u91ca\uff0c\u95ed\u5305\u5c31\u662f\u5f15\u7528\u4e86\u81ea\u7531\u53d8\u91cf\u7684\u51fd\u6570\uff0c\u8fd9\u4e2a\u51fd\u6570\u4fdd\u5b58\u4e86\u6267\u884c\u7684\u4e0a\u4e0b\u6587\uff0c\u53ef\u4ee5\u8131\u79bb\u539f\u672c\u7684\u4f5c\u7528\u57df\u72ec\u7acb\u5b58\u5728\u3002 \u88c5\u9970\u5668 \u00b6 \u770b\u4e0b\u9762\u4f8b\u5b50\uff0c\u5c06\u51fd\u6570\u4f5c\u4e3a\u53c2\u6570\u4f20\u7ed9\u53e6\u4e00\u4e2a\u51fd\u6570\uff0c\u51fd\u6570 my_decorator \u7684\u4f20\u5165\u53c2\u6570\u6b63\u597d\u662f\u5176\u5d4c\u5957\u51fd\u6570 myFunc \u3002 def my_decorator ( nestedFunc ): def myFunc (): print ( \"Before executing nestedFunc()\" ) nestedFunc () print ( \"After executing nestedFunc()\" ) return myFunc def nestedFunc (): print ( \"Decoration - executing nestedFunc()\" ) nestedFunc () # Decoration - executing nestedFunc() nestedFunc = my_decorator ( nestedFunc ) nestedFunc () # Before executing nestedFunc() # Decoration - executing nestedFunc() # After executing nestedFunc() \u88c5\u9970\u5668\u53ea\u662f\u4e2a\u65b9\u6cd5\uff0c\u4f7f\u7528\u65f6\u7528\u4e86 @ \u8bed\u6cd5\u3002 @ \u8bed\u6cd5\u53ea\u662f\u5c06\u51fd\u6570 nestedFunc \u4f20\u5165\u88c5\u9970\u5668\u51fd\u6570 my_decorator \u3002 @my_decorator \u662f nestedFunc = my_decorator(nestedFunc) \u7684\u5feb\u6377\u8868\u8fbe\u65b9\u5f0f\uff0c @my_decorator def nestedFunc (): print ( \"New added to decoration - executing nestedFunc()\" ) nestedFunc () # Before executing nestedFunc() # New added to decoration - executing nestedFunc() # After executing nestedFunc() print ( nestedFunc . __name__ ) # myFunc \u4f46\u4e0a\u4f8b\u6700\u540e\u7684\u8f93\u51fa\u4e0d\u662f\u6211\u4eec\u60f3\u8981\u7684\uff0c\u6211\u4eec\u5e0c\u671b\u8f93\u51fa nestedFunc \uff0c\u4f46\u5374\u88ab myFunc \u66ff\u4ee3\u4e86\uff0c\u5b83\u91cd\u5199\u4e86\u6211\u4eec\u51fd\u6570\u7684\u540d\u5b57\u548c\u6ce8\u91ca\u6587\u6863(docstring)\u3002 \u4e0b\u9762\u4f7f\u7528 functools.wraps \u6765\u4fee\u6b63\u4e0a\u9762\u7684\u95ee\u9898\u3002 from functools import wraps def my_decorator ( nestedFunc ): @wraps ( nestedFunc ) def myFunc (): print ( \"Before executing nestedFunc()\" ) nestedFunc () print ( \"After executing nestedFunc()\" ) return myFunc def nestedFunc (): print ( \"Decoration - executing nestedFunc()\" ) @my_decorator def nestedFunc (): print ( \"New added to decoration - executing nestedFunc()\" ) nestedFunc () # Before executing nestedFunc() # New added to decoration - executing nestedFunc() # After executing nestedFunc() print ( nestedFunc . __name__ ) # nestedFunc \u4e0b\u9762\u662f\u88c5\u9970\u5668\u7684\u84dd\u672c\u89c4\u8303\u3002 from functools import wraps def decorator_name ( f ): @wraps ( f ) def decorated ( * args , ** kwargs ): if not can_run : return \"Function will not run\" return f ( * args , ** kwargs ) return decorated @decorator_name def func (): return ( \"Function is running\" ) can_run = True print ( func ()) # Output: Function is running can_run = False print ( func ()) # Output: Function will not run \u4e0b\u9762\u8fd8\u662f\u4e00\u4e2a\u88c5\u9970\u5668\u7684\u4f8b\u5b50\u3002\u628a\u4e0b\u9762\u7684\u4ee3\u7801\u6bb5\u4fdd\u5b58\u5230\u6587\u4ef6 test.py \u3002 registry = [] def register ( func ): print ( f 'running register { func } ' ) registry . append ( func ) return func @register def f1 (): print ( 'running f1()' ) @register def f2 (): print ( 'running f2()' ) def f3 (): print ( 'running f3()' ) def main (): print ( 'runnning main()' ) print ( f 'registry--> { registry } ' ) f1 () f2 () f3 () if __name__ == '__main__' : main () \u6267\u884c\u4e0a\u8ff0\u4ee3\u7801\u6bb5 python3 test.py \uff0c\u5f97\u5230\u4e0b\u9762\u7684\u7ed3\u679c\u3002 running register < function f1 at 0x7f70847bec80 > running register < function f2 at 0x7f70705aa9d8 > runnning main () registry --> [ < function f1 at 0x7f70847bec80 > , < function f2 at 0x7f70705aa9d8 > ] running f1 () running f2 () running f3 () register \u5728\u6a21\u5757\u4e2d\u5176\u4ed6\u51fd\u6570\u4e4b\u524d\u8fd0\u884c\uff08\u4e24\u6b21\uff09\u3002\u8c03\u7528 register \u65f6\uff0c\u4f20\u7ed9\u5b83\u7684\u53c2\u6570\u662f\u88ab\u88c5\u9970\u7684\u51fd\u6570\uff0c\u4f8b\u5982 function f1 at 0x7f70847bec80> \u3002\u52a0\u8f7d\u6a21\u5757\u540e\uff0c registry \u4e2d\u6709\u4e24\u4e2a\u88ab\u88c5\u9970\u51fd\u6570\u7684\u5f15\u7528\uff1a f1 \u548c f2 \u3002\u8fd9\u4e24\u4e2a\u51fd\u6570\uff0c\u4ee5\u53ca f3 \uff0c\u53ea\u5728 main \u660e\u786e\u8c03\u7528\u5b83\u4eec\u65f6\u624d\u6267\u884c\u3002 \u7531\u6b64\u5f97\uff0c\u51fd\u6570\u88c5\u9970\u5668\u5728\u5bfc\u5165\u6a21\u5757\u65f6\u7acb\u5373\u6267\u884c\uff0c\u800c\u88ab\u88c5\u9970\u7684\u51fd\u6570\u53ea\u5728\u660e\u786e\u8c03\u7528\u65f6\u8fd0\u884c\uff0c\u5373Python\u4e2d\u63d0\u5230\u7684**\u5bfc\u5165\u65f6**\u548c**\u8fd0\u884c\u65f6**\u4e4b\u95f4\u7684\u533a\u522b\u3002 \u4e0a\u9762\u4f8b\u5b50\u4e2d\u88c5\u9970\u5668\u51fd\u6570\u4e0e\u88ab\u88c5\u9970\u7684\u51fd\u6570\u5728\u540c\u4e00\u4e2a\u6a21\u5757\u4e2d\u5b9a\u4e49\u3002\u5b9e\u9645\u5e94\u7528\u4e2d\uff0c\u88c5\u9970\u5668\u901a\u5e38\u5728\u4e00\u4e2a\u6a21\u5757\u4e2d\u5b9a\u4e49\uff0c\u7136\u540e\u5e94\u7528\u5230\u5176\u4ed6\u6a21\u5757\u4e2d\u7684\u51fd\u6570\u4e0a\u3002 \u4e0a\u9762\u4f8b\u5b50\u4e2d register \u88c5\u9970\u5668\u8fd4\u56de\u7684\u51fd\u6570\u4e0e\u901a\u8fc7\u53c2\u6570\u4f20\u5165\u7684\u76f8\u540c\u3002\u5b9e\u9645\u5e94\u7528\u4e2d\uff0c\u5927\u591a\u6570\u88c5\u9970\u5668\u4f1a\u5728\u5185\u90e8\u5b9a\u4e49\u4e00\u4e2a\u51fd\u6570\uff0c\u7136\u540e\u5c06\u5176\u8fd4\u56de\u3002","title":"Python\u5185\u7f6e\u51fd\u6570\u53ca\u6587\u4ef6"},{"location":"python/Foundation/ch03/#python","text":"","title":"Python\u5185\u7f6e\u51fd\u6570\u53ca\u6587\u4ef6"},{"location":"python/Foundation/ch03/#1-lambda","text":"\u533f\u540d\u51fd\u6570\u662f\u4e00\u79cd\u901a\u8fc7\u5355\u4e2a\u8bed\u53e5\u751f\u6210\u51fd\u6570\u7684\u65b9\u5f0f\uff0c\u5176\u7ed3\u679c\u662f\u8fd4\u56de\u503c\u3002\u533f\u540d\u51fd\u6570\u4f7f\u7528lambda\u5173\u952e\u5b57\u5b9a\u4e49\uff0c\u8be5\u5173\u952e\u5b57\u4ec5\u8868\u8fbe\u201c\u6211\u4eec\u58f0\u660e\u4e00\u4e2a\u533f\u540d\u51fd\u6570\u201d\u7684\u610f\u601d\u3002 lambda \u51fd\u6570\u53ef\u4ee5\u63a5\u6536\u4efb\u610f\u591a\u4e2a\u53c2\u6570 (\u5305\u62ec\u53ef\u9009\u53c2\u6570) \u5e76\u4e14\u8fd4\u56de\u5355\u4e2a\u8868\u8fbe\u5f0f\u7684\u503c\u3002 \u8bed\u6cd5\u683c\u5f0f\uff1a lambda arg1,arg2,arg3\u2026 :<\u8868\u8fbe\u5f0f> f = lambda x , y : x * y print ( f ( 2 , 3 )) # 6 f = [ lambda a : a * 2 , lambda b : b * 3 ] print ( f [ 0 ]( 5 )) # \u6267\u884cf\u5217\u8868\u7b2c\u4e00\u4e2a\u5143\u7d20 # 10 print ( f [ 1 ]( 5 )) # \u6267\u884cf\u5143\u7d20\u7b2c\u4e8c\u4e2a\u5143\u7d20 # 15 print ( f [ 0 , 1 ]( 5 , 5 )) # TypeError: list indices must be integers or slices, not tuple \u793a\u4f8b1\uff1a def short_func1 ( x ): return x * 2 short_func2 = lambda x : x * 2 print ( short_func1 ( 5 )) # 10 print ( short_func2 ( 5 )) # 10 \u793a\u4f8b2\uff1a def apply_to_list ( some_list , f ): return [ f ( x ) for x in some_list ] ints = [ 4 , 0 , 1 , 5 , 6 ] result5 = apply_to_list ( ints , lambda x : x * 2 ) print ( result5 ) # [8, 0, 2, 10, 12] lambda: None \u51fd\u6570\u6ca1\u6709\u8f93\u5165\u53c2\u6570\uff0c\u8f93\u51fa\u662fNone\u3002 print ( lambda : None ) # at 0x7fa5c4097670> lambda **kwargs: 1 \u8f93\u5165\u662f\u4efb\u610f\u952e\u503c\u5bf9\u53c2\u6570\uff0c\u8f93\u51fa\u662f1\u3002 print ( lambda ** kwargs : 1 ) # at 0x7fa5c4097670>","title":"1. \u533f\u540d\uff08Lambda\uff09\u51fd\u6570"},{"location":"python/Foundation/ch03/#2-enumerate","text":"\u5f53\u9700\u8981\u5bf9\u6570\u636e\u5efa\u7acb\u7d22\u5f15\u65f6\uff0c\u4e00\u79cd\u6709\u6548\u7684\u6a21\u5f0f\u5c31\u662f\u4f7f\u7528enumerate\u6784\u9020\u4e00\u4e2a\u5b57\u5178\uff0c\u5c06\u5e8f\u5217\u503c\uff08\u5047\u8bbe\u662f\u552f\u4e00\u7684\uff09\u6620\u5c04\u5230\u7d22\u5f15\u4f4d\u7f6e\u4e0a\u3002 seasons = [ 'Spring' , 'Summer' , 'Fall' , 'Winter' ] print ( list ( enumerate ( seasons ))) # [(0, 'Spring'), (1, 'Summer'), (2, 'Fall'), (3, 'Winter')] \u5bf9\u6bd4\u4e0b\u97622\u4e2a\u5faa\u73af a_list = [ 'foo' , 'bar' , 'baz' ] mapping = {} for i , v in enumerate ( a_list ): # enumerate\u751f\u6210\u7d22\u5f15\u503ci\u548c\u5e8f\u5217\u503cv mapping [ v ] = i print ( mapping ) # {'foo': 0, 'bar': 1, 'baz': 2} i = 0 mapping = {} for v in a_list : print ( i , a_list [ i ]) mapping [ v ] = i # \u53ef\u4ee5\u628ai\u548cv\u4e92\u6362 i += 1 print ( mapping ) # {'foo': 0, 'bar': 1, 'baz': 2} \u5229\u7528 enumerate() \u6279\u91cf\u4fee\u6539\u5217\u8868\u5185\u7684\u5143\u7d20 a_list = [ '01' , '02' , '03' ] unit_element = '1' for i , element in enumerate ( a_list ): a_list [ i ] = unit_element + element print ( a_list ) # ['101', '102', '103'] sorted\u51fd\u6570\u8fd4\u56de\u4e00\u4e2a\u6839\u636e\u4efb\u610f\u5e8f\u5217\u4e2d\u7684\u5143\u7d20\u65b0\u5efa\u7684\u5df2\u6392\u5e8f\u5217\u8868\u3002sorted\u51fd\u6570\u63a5\u53d7\u7684\u53c2\u6570\u4e0e\u5217\u8868\u7684sort\u65b9\u6cd5\u4e00\u81f4\u3002 y = sorted ([ 7 , 1 , 2 , 6 , 0 , 3 , 2 ]) print ( y ) # [0, 1, 2, 2, 3, 6, 7] \u7ed3\u679c\u5df2\u6392\u5e8f z = sorted ( 'Hello World' ) print ( z ) # [' ', 'H', 'W', 'd', 'e', 'l', 'l', 'l', 'o', 'o', 'r'] zip\u5c06\u5217\u8868\u3001\u5143\u7ec4\u6216\u5176\u4ed6\u5e8f\u5217\u7684\u5143\u7d20\u914d\u5bf9\uff0c\u65b0\u5efa\u4e00\u4e2a\u5143\u7ec4\u6784\u6210\u7684\u5217\u8868\u3002 seq1 = [ 'foo' , 'bar' , 'baz' ] seq2 = [ 'one' , 'two' , 'three' ] seq3 = [ False , True ] zipped = zip ( seq1 , seq2 ) print ( list ( zipped )) # [('foo', 'one'), ('bar', 'two'), ('baz', 'three')] zipped = zip ( seq1 , seq2 , seq3 ) print ( list ( zipped )) # [('foo', 'one', False), ('bar', 'two', True)] for i , ( a , b ) in enumerate ( zip ( seq1 , seq2 )): print ( ' {0} : {1} , {2} ' . format ( i , a , b )) # \u65b9\u6cd51 {0}\u5217\u8868\u5143\u7d20\u7684\u7d22\u5f15, {1}\u5143\u7ec4\u4e2d\u7b2c\u4e00\u4e2a\u503c, {2}\u5143\u7ec4\u4e2d\u7b2c\u4e8c\u4e2a\u503c print ( f ' { i } : { a } , { b } ' ) # \u65b9\u6cd52 # 0: foo, one # 1: bar, two # 2: baz, three \u7ed9\u5b9a\u4e00\u4e2a\u5df2\u201c\u914d\u5bf9\u201d\u7684\u5e8f\u5217\u65f6\uff0czip\u51fd\u6570\u53ef\u4ee5\u53bb\u201c\u62c6\u5206\u201d\u5e8f\u5217\u3002\u8fd9\u79cd\u65b9\u5f0f\u7684\u53e6\u4e00\u79cd\u601d\u8def\u5c31\u662f\u5c06\u884c\u7684\u5217\u8868\u8f6c\u6362\u4e3a\u5217\u7684\u5217\u8868\u3002\u53c2\u8003Python\u7684 Unpacking pitchers = [( 'Jack' , 'Ma' ), ( 'Tom' , 'Li' ), ( 'Jimmy' , 'Zhang' )] first_names , last_names = zip ( * pitchers ) print ( first_names ) # ('Jack', 'Tom', 'Jimmy') print ( last_names ) # ('Ma', 'Li', 'Zhang') reversed\u51fd\u6570\u5c06\u5e8f\u5217\u7684\u5143\u7d20\u5012\u5e8f\u6392\u5217 print ( list ( reversed ( range ( 10 )))) # [9, 8, 7, 6, 5, 4, 3, 2, 1, 0]","title":"2. \u5185\u7f6e\u5e8f\u5217\u51fd\u6570enumerate"},{"location":"python/Foundation/ch03/#3","text":"\u63a8\u5bfc\u5f0fcomprehensions\uff08\u53c8\u79f0\u89e3\u6790\u5f0f\uff09\uff0c\u662fPython\u7684\u4e00\u79cd\u7279\u6027\u3002\u4f7f\u7528\u63a8\u5bfc\u5f0f\u53ef\u4ee5\u5feb\u901f\u751f\u6210\u5217\u8868\u3001\u5143\u7ec4\u3001\u96c6\u5408\u3001\u5b57\u5178\u7c7b\u578b\u7684\u6570\u636e\u3002\u63a8\u5bfc\u5f0f\u53c8\u5206\u4e3a\u5217\u8868\u63a8\u5bfc\u5f0f\u3001\u5143\u7ec4\u63a8\u5bfc\u5f0f\u3001\u96c6\u5408\u63a8\u5bfc\u5f0f\u3001\u5b57\u5178\u63a8\u5bfc\u5f0f\u3002","title":"3. \u5217\u8868\u3001\u96c6\u5408\u548c\u5b57\u5178\u7684\u63a8\u5bfc\u5f0f"},{"location":"python/Foundation/ch03/#list-comprehension","text":"\u5217\u8868\u63a8\u5bfc\u5f0f(list comprehension)\u5141\u8bb8\u4f60\u8fc7\u6ee4\u4e00\u4e2a\u5bb9\u5668\u7684\u5143\u7d20\uff0c\u7528\u4e00\u79cd\u7b80\u660e\u7684\u8868\u8fbe\u5f0f\u8f6c\u6362\u4f20\u9012\u7ed9\u8fc7\u6ee4\u5668\u7684\u5143\u7d20\uff0c\u4ece\u800c\u751f\u6210\u4e00\u4e2a\u65b0\u7684\u5217\u8868\u3002 \u5217\u8868\u63a8\u5bfc\u5f0f\u7684\u57fa\u672c\u5f62\u5f0f\u4e3a\uff1a[expr for val in collection if condition]\uff0c\u6761\u4ef6if-condition\u4e0d\u662f\u5fc5\u987b\u7684\uff0c\u53ef\u4ee5\u53ea\u4fdd\u7559\u8868\u8fbe\u5f0f\u3002\u5217\u8868\u63a8\u5bfc\u5f0f\u4e0e\u4e0b\u9762\u7684for\u5faa\u73af\u662f\u7b49\u4ef7\u7684\uff1a result = [] for val in collection : if condition : result . append ( expr ) \u770b\u4e0b\u9762\u7684\u4f8b\u5b50\uff1a data = [] for i in range ( - 5 , 5 ): if i >= - 1 : data . append ( i ** 2 ) print ( data ) # [1, 0, 1, 4, 9, 16] data = [ i ** 2 for i in range ( - 5 , 5 ) if i >= - 1 ] print ( data ) # [1, 0, 1, 4, 9, 16] \u4e0b\u9762\u7684\u4f8b\u5b50\u662f\u4f7f\u7528for\u53bb\u904d\u5386\u4e00\u4e2a\u53ef\u8fed\u4ee3\u7684\u5217\u8868\u3002 data = [] fruit = [ 'pomegranate' , 'cherry' , 'apricot' , 'date' , 'Apple' , 'lemon' , 'kiwi' , 'ORANGE' , 'lime' , 'Watermelon' , 'guava' , 'papaya' , 'FIG' , 'pear' , 'banana' , 'Tamarind' , 'persimmon' , 'elderberry' , 'peach' , 'BLUEberry' , 'lychee' , 'grape' ] data = [ x . upper () if x . startswith ( 'p' ) else x . title () for x in fruit ] print ( data ) # ['POMEGRANATE', 'Cherry', 'Apricot', 'Date', 'Apple', 'Lemon', 'Kiwi', 'Orange', 'Lime', 'Watermelon', 'Guava', 'PAPAYA', 'Fig', 'PEAR', 'Banana', 'Tamarind', 'PERSIMMON', 'Elderberry', 'PEACH', 'Blueberry', 'Lychee', 'Grape']","title":"\u5217\u8868\u63a8\u5bfc\u5f0f(list comprehension)"},{"location":"python/Foundation/ch03/#_1","text":"\u4e0b\u9762\u7684\u4f8b\u5b50\u662f\u7528\u5d4c\u5957\u5217\u8868\u63a8\u5bfc\u5f0f\u4ee3\u66ff2\u5c42for\u5faa\u73af\u3002 data = [] for i in range ( 1 , 3 ): if i >= 0 : for j in range ( 1 , 3 ): data . append (( i , j )) print ( data ) # [(1, 1), (1, 2), (2, 1), (2, 2)] data = [( i , j ) for i in range ( 1 , 3 ) if i >= - 1 for j in range ( 1 , 3 )] print ( data ) # [(1, 1), (1, 2), (2, 1), (2, 2)] \u518d\u4e3e\u4e00\u4e2a\u5d4c\u5957\u5217\u8868\u63a8\u5bfc\u5f0f\u7684\u4f8b\u5b50\u3002 all_data = [ [ 'John' , 'Emily' , 'Michael' , 'Lee' , 'Steven' ], [ 'Maria' , 'Juan' , 'Javier' , 'Natalia' , 'Pilar' ], ] names_of_interest = [] for names in all_data : enough_es = [ name for name in names if name . count ( 'e' ) >= 2 ] names_of_interest . extend ( enough_es ) print ( names_of_interest ) # ['Lee', 'Steven'] result = [ name for names in all_data for name in names if name . count ( 'e' ) >= 2 ] print ( result ) # ['Lee', 'Steven'] \u7528\u5d4c\u5957\u5217\u8868\u63a8\u5bfc\u5f0f\u5c06\u77e9\u9635\u6241\u5e73\u5316\u3002 \u8003\u8651\u4e0b\u9762\u8fd9\u4e2a3x4\u7684\u77e9\u9635\uff0c\u5b83\u75313\u4e2a\u957f\u5ea6\u4e3a4\u7684\u5217\u8868\u7ec4\u6210\u3002\u4e0b\u9762\u4f8b\u5b50\u5bf9\u6bd4\u4e86\u7528\u4f20\u7edffor\u5faa\u73af\u5c06\u77e9\u9635\u6241\u5e73\u5316\uff0c\u548c\u7528\u5d4c\u5957\u5217\u8868\u63a8\u5bfc\u5f0f\u5c06\u77e9\u9635\u6241\u5e73\u5316\u3002\u5e76\u4e14\u901a\u8fc7\u5217\u8868\u63a8\u5bfc\u5f0f\u4e2d\u7684\u5217\u8868\u63a8\u5bfc\u5f0f\u5c06\u6241\u5e73\u77e9\u9635\u8fd8\u539f\u4e3a3x4\u77e9\u9635\u3002 matrix = [ [ 1 , 2 , 3 , 4 ], [ 5 , 6 , 7 , 8 ], [ 9 , 10 , 11 , 12 ], ] flattened = [] # \u4f20\u7edffor\u5faa\u73af\u5d4c\u5957 for m in matrix : for x in m : flattened . append ( x ) print ( flattened ) # [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12] # \u5d4c\u5957\u5217\u8868\u63a8\u5bfc\u5f0f flattened = [ x for m in matrix for x in m ] print ( flattened ) # [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12] # \u5217\u8868\u63a8\u5bfc\u5f0f\u4e2d\u7684\u5217\u8868\u63a8\u5bfc\u5f0f z = [[ x for x in m ] for m in matrix ] print ( z ) # [[1, 2, 3, 4], [5, 6, 7, 8], [9, 10, 11, 12]]","title":"\u5957\u5217\u8868\u63a8\u5bfc\u5f0f"},{"location":"python/Foundation/ch03/#_2","text":"\u4e0b\u9762\u7684\u4f8b\u5b50\u751f\u6210\u4e00\u4e2a\u5305\u542b\u6570\u5b571~5\u7684\u5143\u7ec4\u3002\u4ece\u7ed3\u679c\u53ef\u4ee5\u770b\u5230\uff0c\u5143\u7ec4\u63a8\u5bfc\u5f0f\u751f\u6210\u7684\u7ed3\u679c\u5e76\u4e0d\u662f\u4e00\u4e2a\u5143\u7ec4\uff0c\u800c\u662f\u4e00\u4e2a\u751f\u6210\u5668\u5bf9\u8c61\uff0c\u9700\u8981\u901a\u8fc7tuple()\u51fd\u6570\uff0c\u5c06\u751f\u6210\u5668\u5bf9\u8c61\u8f6c\u6362\u6210\u5143\u7ec4\u3002 data = ( x for x in range ( 5 )) print ( data ) # at 0x7f87217a8e40> print ( type ( data )) # print ( tuple ( data )) # (0, 1, 2, 3, 4)","title":"\u5143\u7ec4\u63a8\u5bfc\u5f0f"},{"location":"python/Foundation/ch03/#_3","text":"\u4e0b\u9762\u662f\u4e00\u4e2a\u7b80\u5355\u7684\u96c6\u5408\u63a8\u5bfc\u5f0f\u4f8b\u5b50\u3002 data = { x ** 2 for x in range ( 5 )} print ( data ) # {0, 1, 4, 9, 16} print ( type ( data )) # \u96c6\u5408\u8981\u4fdd\u8bc1\u5143\u7d20\u5fc5\u987b\u662f\u552f\u4e00\u7684\u3002 data = ( 1 , 1 , 2 , 2 , 3 , 3 , 4 , 5 , 6 ) newset = { x ** 2 for x in data } print ( newset ) # {1, 4, 36, 9, 16, 25} print ( type ( newset ) # ","title":"\u96c6\u5408\u63a8\u5bfc\u5f0f"},{"location":"python/Foundation/ch03/#_4","text":"\u5b57\u5178\u63a8\u5bfc\u5f0f: dict_comp = {key-expr : value-expr for value in collection if condition} \u5b57\u5178\u63a8\u5bfc\u5f0f\u7684\u7b80\u5355\u793a\u4f8b\uff1a strings = [ 'a' , 'as' , 'bat' , 'car' , 'dove' , 'python' ] loc_mapping = { index : val for index , val in enumerate ( strings )} print ( loc_mapping ) # {0: 'a', 1: 'as', 2: 'bat', 3: 'car', 4: 'dove', 5: 'python'} # \u4ea4\u6362\u952e\u548c\u503c loc_mapping = { index : val for val , index in enumerate ( strings )} print ( loc_mapping ) # {'a': 0, 'as': 1, 'bat': 2, 'car': 3, 'dove': 4, 'python': 5}","title":"\u5b57\u5178\u63a8\u5bfc\u5f0f"},{"location":"python/Foundation/ch03/#4","text":"\u5982\u679cPython\u8fbe\u5230\u51fd\u6570\u7684\u5c3e\u90e8\u65f6\u4ecd\u7136\u6ca1\u6709\u9047\u5230return\u8bed\u53e5\uff0c\u5c31\u4f1a\u81ea\u52a8\u8fd4\u56deNone\u3002 \u6bcf\u4e2a\u51fd\u6570\u90fd\u53ef\u4ee5\u6709\u4f4d\u7f6e\u53c2\u6570\u548c\u5173\u952e\u5b57\u53c2\u6570\u3002\u5173\u952e\u5b57\u53c2\u6570\u6700\u5e38\u7528\u4e8e\u6307\u5b9a\u9ed8\u8ba4\u503c\u6216\u53ef\u9009\u53c2\u6570\u3002\u5173\u952e\u5b57\u53c2\u6570\u5fc5\u987b\u8ddf\u5728\u4f4d\u7f6e\u53c2\u6570\u540e\uff0c\u53ef\u4ee5\u4f7f\u7528\u5173\u952e\u5b57\u53c2\u6570\u5411\u4f4d\u7f6e\u53c2\u6570\u4f20\u53c2\u3002 import sys def my_function1 ( x , y , z = 1.5 ): if z > 1 : return z * ( x + y ) else : return z / ( x + y ) result1 = my_function1 ( 5 , 6 , z = 0.7 ) print ( result1 ) # 0.06363636363636363 result1 = my_function1 ( x = 5 , y = 6 , z = 0.7 ) print ( result1 ) # 0.06363636363636363 result1 = my_function1 ( 3.14 , 7 , 3.5 ) print ( result1 ) # 35.49 result1 = my_function1 ( 10 , 20 ) print ( result1 ) # 45.0","title":"4. \u51fd\u6570\u58f0\u660e"},{"location":"python/Foundation/ch03/#5","text":"\u51fd\u6570\u6709\u4e24\u79cd\u8fde\u63a5\u53d8\u91cf\u7684\u65b9\u5f0f\uff1a\u5168\u5c40\u3001\u672c\u5730\u3002 def func1 (): list1 = [] # \u672c\u5730\u53d8\u91cf for i in range ( 5 ): list1 . append ( i ) print ( list1 ) func1 () # [0, 1, 2, 3, 4] list2 = [] # \u5168\u5c40\u53d8\u91cf def func2 (): global list2 # \u5168\u5c40\u53d8\u91cf for i in range ( 5 ): list2 . append ( i ) print ( list2 ) func2 () # [0, 1, 2, 3, 4] \u6570\u636e\u6e05\u6d17\u793a\u4f8b states = [ ' Alabama' , 'Georgia!' , 'georgia' , 'Georgia' , 'FlOrIda' , 'south carolina##' , 'West virginia? ' ] # \u65b9\u6cd51 import re def clean_string1 ( strings ): result2 = [] for value in strings : value = value . strip () value = re . sub ( '[! #? ]' , '' , value ) value = value . title () result2 . append ( value ) return result2 print ( clean_string1 (( states ))) # ['Alabama', 'Georgia', 'Georgia', 'Georgia', 'Florida', 'Southcarolina', 'Westvirginia'] # \u65b9\u6cd52 def remove_punctuaion ( value ): return re . sub ( '[! #? ]' , '' , value ) clean_ops = [ str . strip , remove_punctuaion , str . title ] def clean_string2 ( strings , ops ): result3 = [] for value in strings : for function in ops : value = function ( value ) result3 . append ( value ) return result3 result4 = clean_string2 ( states , clean_ops ) print ( result4 ) # ['Alabama', 'Georgia', 'Georgia', 'Georgia', 'Florida', 'Southcarolina', 'Westvirginia'] # \u53ef\u4ee5\u5c06\u51fd\u6570\u4f5c\u4e3a\u4e00\u4e2a\u53c2\u6570\u4f20\u7ed9\u5176\u4ed6\u7684\u51fd\u6570\u3002 for x in map ( remove_punctuaion , states ): print ( x ) # Alabama # Georgia # georgia # Georgia # FlOrIda # southcarolina # Westvirginia","title":"5. \u547d\u540d\u7a7a\u95f4\u3001\u4f5c\u7528\u57df\u548c\u672c\u5730\u51fd\u6570"},{"location":"python/Foundation/ch03/#6","text":"\u67ef\u91cc\u5316\u662f\u8ba1\u7b97\u673a\u79d1\u5b66\u672f\u8bed\uff08\u4ee5\u6570\u5b66\u5bb6Haskell Curry\u547d\u540d\uff09\uff0c\u5b83\u8868\u793a\u901a\u8fc7\u90e8\u5206\u53c2\u6570\u5e94\u7528\u7684\u65b9\u5f0f\u4ece\u5df2\u6709\u7684\u51fd\u6570\u4e2d\u884d\u751f\u51fa\u65b0\u7684\u51fd\u6570\u3002\u67ef\u91cc\u5316\u662f\u4e00\u79cd\u5c06\u591a\u53c2\u6570\u51fd\u6570\u8f6c\u5316\u4e3a\u5355\u53c2\u6570\u9ad8\u9636\u51fd\u6570\u7684\u6280\u672f\uff0c\u5982\u679c\u4f60\u56fa\u5b9a\u67d0\u4e9b\u53c2\u6570\uff0c\u4f60\u5c06\u5f97\u5230\u63a5\u53d7\u4f59\u4e0b\u53c2\u6570\u7684\u4e00\u4e2a\u51fd\u6570\u3002 \u5b9a\u4e49\u4e00\uff1a \u67ef\u91cc\u5316\uff1a\u4e00\u4e2a\u51fd\u6570\u4e2d\u6709\u4e2a\u591a\u4e2a\u53c2\u6570\uff0c\u60f3\u56fa\u5b9a\u5176\u4e2d\u67d0\u4e2a\u6216\u8005\u51e0\u4e2a\u53c2\u6570\u7684\u503c\uff0c\u800c\u53ea\u63a5\u53d7\u53e6\u5916\u51e0\u4e2a\u8fd8\u672a\u56fa\u5b9a\u7684\u53c2\u6570\uff0c\u8fd9\u6837\u51fd\u6570\u6f14\u53d8\u6210\u65b0\u7684\u51fd\u6570\u3002 \u5b9a\u4e49\u4e8c\uff1a \u51fd\u6570\u67ef\u91cc\u5316\uff08currying\uff09\u53c8\u79f0\u90e8\u5206\u6c42\u503c\u3002\u4e00\u4e2a currying \u7684\u51fd\u6570\u9996\u5148\u4f1a\u63a5\u53d7\u4e00\u4e9b\u53c2\u6570\uff0c\u63a5\u53d7\u4e86\u8fd9\u4e9b\u53c2\u6570\u4e4b\u540e\uff0c\u8be5\u51fd\u6570\u5e76\u4e0d\u4f1a\u7acb\u5373\u6c42\u503c\uff0c\u800c\u662f\u7ee7\u7eed\u8fd4\u56de\u53e6\u5916\u4e00\u4e2a\u51fd\u6570\uff0c\u521a\u624d\u4f20\u5165\u7684\u53c2\u6570\u5728\u51fd\u6570\u5f62\u6210\u7684\u95ed\u5305\u4e2d\u88ab\u4fdd\u5b58\u8d77\u6765\u3002\u5f85\u5230\u51fd\u6570\u88ab\u771f\u6b63\u9700\u8981\u6c42\u503c\u7684\u65f6\u5019\uff0c\u4e4b\u524d\u4f20\u5165\u7684\u6240\u6709\u53c2\u6570\u90fd\u4f1a\u88ab\u4e00\u6b21\u6027\u7528\u4e8e\u6c42\u503c\u3002 \u5b9a\u4e49\u4e09\uff1a \u4e00\u4e9b\u51fd\u6570\u5f0f\u8bed\u8a00\u7684\u5de5\u4f5c\u539f\u7406\u662f\u5c06\u591a\u53c2\u6570\u51fd\u6570\u8bed\u6cd5\u8f6c\u5316\u4e3a\u5355\u53c2\u6570\u51fd\u6570\u96c6\u5408\uff0c\u8fd9\u4e00\u8fc7\u7a0b\u79f0\u4e3a\u67ef\u91cc\u5316\uff0c\u5b83\u662f\u4ee5\u903b\u8f91\u5b66\u5bb6Haskell Curry\u7684\u540d\u5b57\u547d\u540d\u7684\u3002Haskell Curry\u4ece\u65e9\u671f\u6982\u5ff5\u4e2d\u53d1\u5c55\u51fa\u4e86\u8be5\u7406\u8bba\u3002\u5176\u5f62\u5f0f\u76f8\u5f53\u4e8e\u5c06z=f(x, y)\u8f6c\u6362\u6210z=f(x)(y)\u7684\u5f62\u5f0f\uff0c\u539f\u51fd\u6570\u7531\u4e24\u4e2a\u53c2\u6570\uff0c\u73b0\u5728\u53d8\u4e3a\u4e24\u4e2a\u63a5\u53d7\u5355\u53c2\u6570\u7684\u51fd\u6570\uff0c \u793a\u4f8b1\uff1a\u67ef\u91cc\u5316\u7684\u8fc7\u7a0b\u5c31\u662f\u628a\u539f\u6765\u5e26\u4e24\u4e2a\u53c2\u6570\u7684\u51fd\u6570add(x, y)\uff0c\u53d8\u6210\u4e86\u4e00\u4e2a\u5d4c\u5957\u51fd\u6570\uff0c\u5728add_currying\u51fd\u6570\u5185\uff0c\u53c8\u5b9a\u4e49\u4e86\u4e00\u4e2a_add\u51fd\u6570\uff0c\u5e76\u4e14_add\u51fd\u6570\u53c8\u5f15\u7528\u4e86\u5916\u90e8\u51fd\u6570add_currying\u7684\u53d8\u91cfx\uff0c\u8fd9\u5c31\u662f\u4e00\u4e2a\u95ed\u5305\u3002 \u95ed\u5305\uff0c\u4e00\u53e5\u8bdd\u8bf4\u5c31\u662f\u5728\u51fd\u6570\u4e2d\u518d\u5d4c\u5957\u4e00\u4e2a\u51fd\u6570\uff0c\u5e76\u4e14\u5f15\u7528\u5916\u90e8\u51fd\u6570\u7684\u53d8\u91cf\u3002 # \u666e\u901a\u5199\u6cd5 def add ( x , y ): return x + y print ( add ( 1 , 2 )) # 3 # \u67ef\u91cc\u5316\u5199\u6cd5 def add_currying ( x ): def _add ( y ): return x + y return _add print ( add_currying ( 1 )( 2 )) # 3 \u793a\u4f8b2\uff0c\u901a\u8fc7\u56fa\u5b9a\u5176\u4e2d\u7684\u7b2c\u4e8c\u4e2a\u53c2\u6570\u4e0d\u53d8\u6765\u5b9e\u73b0\u67ef\u91cc\u5316\u3002 def add2 ( a , b ): def add1 ( a , b , c ): return a + b + c return add1 ( a , 666 , b ) result6 = add2 ( 12 , 13 ) print ( result6 ) # 691 result6 = add2 ( 12 , 555 , 13 ) # TypeError: add2() takes 2 positional arguments but 3 were given \u793a\u4f8b3\uff0c\u901a\u8fc7functools\u63d0\u4f9b\u7684\u504f\u51fd\u6570\u6765\u5b9e\u73b0\u67ef\u91cc\u5316\u3002 from functools import partial def add1 ( a , b , c ): return a + b + c add3 = partial ( add1 , b = 666 ) result7 = add3 ( a = 12 , c = 13 ) print ( result7 ) # 691 \u793a\u4f8b4\uff0c\u901a\u8fc7lambda\u8868\u8fbe\u5f0f\u6765\u5b9e\u73b0\u67ef\u91cc\u5316\u3002 def add1 ( a , b , c ): return a + b + c add4 = lambda x , y : add1 ( x , 666 , y ) result8 = add4 ( 12 , 13 ) print ( result8 ) # 691 \u793a\u4f8b5\uff0c\u901a\u8fc7python\u7684\u88c5\u9970\u5668\u6765\u5b9e\u73b0\u67ef\u91cc\u5316 def add1 ( a , b , c ): return a + b + c def currying_add ( func ): def wrapper ( a , c , b = 666 ): return func ( a , b , c ) return wrapper result9 = currying_add ( add1 )( 12 , 13 ) print ( result9 ) # 691 \u793a\u4f8b6\uff0c\u901a\u8fc7python\u7684\u88c5\u9970\u5668\u7b26\u53f7@\u6765\u5b9e\u73b0\u67ef\u91cc\u5316 def currying_add ( func ): def wrapper ( a , c , b = 666 ): return func ( a , b , c ) return wrapper @currying_add def add5 ( a , b , c ): return a + b + c result10 = add5 ( 12 , 13 ) print ( result10 ) # 691","title":"6. \u67ef\u91cc\u5316\uff1a\u90e8\u5206\u53c2\u6570\u5e94\u7528"},{"location":"python/Foundation/ch03/#7","text":"","title":"7. \u8fed\u4ee3\u5668\u4e0e\u751f\u6210\u5668"},{"location":"python/Foundation/ch03/#_5","text":"\u8fed\u4ee3\u662fPython\u6700\u5f3a\u5927\u7684\u529f\u80fd\u4e4b\u4e00\uff0c\u662f\u8bbf\u95ee\u96c6\u5408\u5143\u7d20\u7684\u4e00\u79cd\u65b9\u5f0f\u3002\u8fed\u4ee3\u5668\u662f\u4e00\u4e2a\u53ef\u4ee5\u8bb0\u4f4f\u904d\u5386\u7684\u4f4d\u7f6e\u7684\u5bf9\u8c61\u3002 \u8fed\u4ee3\u5668\u5bf9\u8c61\u4ece\u96c6\u5408\u7684\u7b2c\u4e00\u4e2a\u5143\u7d20\u5f00\u59cb\u8bbf\u95ee\uff0c\u76f4\u5230\u6240\u6709\u7684\u5143\u7d20\u88ab\u8bbf\u95ee\u5b8c\u7ed3\u675f\u3002\u8fed\u4ee3\u5668\u53ea\u80fd\u5f80\u524d\u4e0d\u4f1a\u540e\u9000\u3002 \u8fed\u4ee3\u5668\u6709\u4e24\u4e2a\u57fa\u672c\u7684\u65b9\u6cd5\uff1aiter() \u548c next()\u3002 \u8fed\u4ee3\u5668\u793a\u4f8b\uff1a list_a = [ 1 , 2 , 3 , 4 ] it = iter ( list_a ) # \u521b\u5efa\u8fed\u4ee3\u5668\u5bf9\u8c61 print ( next ( it )) # \u8f93\u51fa\u8fed\u4ee3\u5668\u7684\u4e0b\u4e00\u4e2a\u5143\u7d20 # 1 print ( next ( it )) # \u8f93\u51fa\u8fed\u4ee3\u5668\u7684\u4e0b\u4e00\u4e2a\u5143\u7d20 # 2 \u8fed\u4ee3\u5668\u5bf9\u8c61\u53ef\u4ee5\u4f7f\u7528\u5e38\u89c4for\u8bed\u53e5\u8fdb\u884c\u904d\u5386\u3002 list_a = [ 1 , 2 , 3 , 4 ] it = iter ( list_a ) # \u521b\u5efa\u8fed\u4ee3\u5668\u5bf9\u8c61 for x in it : print ( x , end = \" \" ) print ( end = \" \\n \" ) # 1 2 3 4","title":"\u8fed\u4ee3\u5668"},{"location":"python/Foundation/ch03/#_6","text":"\u5728 Python \u4e2d\uff0c\u4f7f\u7528\u4e86 yield \u7684\u51fd\u6570\u88ab\u79f0\u4e3a\u751f\u6210\u5668\uff08generator\uff09\u3002\u8ddf\u666e\u901a\u51fd\u6570\u4e0d\u540c\u7684\u662f\uff0c\u751f\u6210\u5668\u662f\u4e00\u4e2a\u8fd4\u56de\u8fed\u4ee3\u5668\u7684\u51fd\u6570\uff0c\u53ea\u80fd\u7528\u4e8e\u8fed\u4ee3\u64cd\u4f5c\uff0c\u751f\u6210\u5668\u5c31\u662f\u4e00\u4e2a\u8fed\u4ee3\u5668\u3002 \u5728\u8c03\u7528\u751f\u6210\u5668\u8fd0\u884c\u7684\u8fc7\u7a0b\u4e2d\uff0c\u6bcf\u6b21\u9047\u5230 yield \u65f6\u51fd\u6570\u4f1a\u6682\u505c\u5e76\u4fdd\u5b58\u5f53\u524d\u6240\u6709\u7684\u8fd0\u884c\u4fe1\u606f\uff0c\u8fd4\u56de yield \u7684\u503c, \u5e76\u5728\u4e0b\u4e00\u6b21\u6267\u884c next() \u65b9\u6cd5\u65f6\u4ece\u5f53\u524d\u4f4d\u7f6e\u7ee7\u7eed\u8fd0\u884c\u3002 \u8c03\u7528\u4e00\u4e2a\u751f\u6210\u5668\u51fd\u6570\uff0c\u8fd4\u56de\u7684\u662f\u4e00\u4e2a\u8fed\u4ee3\u5668\u5bf9\u8c61\u3002 \u793a\u4f8b, \u6590\u6ce2\u90a3\u5951\u6570\u5217\uff1a def fibonacci ( n ): a , b , counter = 0 , 1 , 0 while True : if ( counter > n ): return yield a a , b = b , a + b counter += 1 f = fibonacci ( 10 ) # f \u662f\u4e00\u4e2a\u8fed\u4ee3\u5668\uff0c\u7531\u751f\u6210\u5668\u8fd4\u56de\u751f\u6210 print ( f ) # \u5b9e\u9645\u8c03\u7528\u751f\u6210\u5668\u65f6\uff0c\u4ee3\u7801\u5e76\u4e0d\u4f1a\u7acb\u5373\u6267\u884c for x in f : # \u8bf7\u6c42\u751f\u6210\u5668\u4e2d\u7684\u5143\u7d20\u65f6\uff0c\u5b83\u624d\u4f1a\u6267\u884c\u5b83\u7684\u4ee3\u7801 print ( x , end = \" \" ) print ( end = \" \\n \" ) # 0 1 1 2 3 5 8 13 21 34 55 \u751f\u6210\u5668\u8868\u8fbe\u5f0f\uff1a \u7528\u751f\u6210\u5668\u8868\u8fbe\u5f0f\u6765\u521b\u5efa\u751f\u6210\u5668\u66f4\u4e3a\u7b80\u5355\u3002\u751f\u6210\u5668\u8868\u8fbe\u5f0f\u4e0e\u5217\u8868\u3001\u5b57\u5178\u3001\u96c6\u5408\u7684\u63a8\u5bfc\u5f0f\u5f88\u7c7b\u4f3c\uff0c\u521b\u5efa\u4e00\u4e2a\u751f\u6210\u5668\u8868\u8fbe\u5f0f\uff0c\u53ea\u9700\u8981\u5c06\u5217\u8868\u63a8\u5bfc\u5f0f\u7684\u4e2d\u62ec\u53f7\u66ff\u6362\u4e3a\u5c0f\u62ec\u53f7\u5373\u53ef\u3002 gen1 = ( x ** 2 for x in range ( 100 )) print ( gen1 ) # at 0x7fd3f30c9580> \u4e0a\u9762\u7684\u4ee3\u7801\u4e0e\u4e0b\u9762\u7684\u751f\u6210\u5668\u662f\u7b49\u4ef7\u7684 def _make_gen (): for x in range ( 100 ): yield x ** 2 gen2 = _make_gen () print ( gen2 ) # \u751f\u6210\u5668\u8868\u8fbe\u5f0f\u53ef\u4ee5\u4f5c\u4e3a\u51fd\u6570\u53c2\u6570\u7528\u4e8e\u66ff\u4ee3\u5217\u8868\u63a8\u5bfc\u5f0f\u3002\u5bf9\u6bd4\u4e0b\u97622\u4e2a\u4f8b\u5b50\u3002 # \u793a\u4f8b1 result11 = sum ( x ** 2 for x in range ( 100 )) print ( result11 ) # 328350 gen1 = ( x ** 2 for x in range ( 100 )) result11 = sum ( gen1 ) print ( result11 ) # 328350 # \u793a\u4f8b2 result12 = dict (( i , i ** 2 ) for i in range ( 5 )) print ( result12 ) # {0: 0, 1: 1, 2: 4, 3: 9, 4: 16} gen2 = (( i , i ** 2 ) for i in range ( 5 )) result12 = dict ( gen2 ) print ( result12 ) # {0: 0, 1: 1, 2: 4, 3: 9, 4: 16}","title":"\u751f\u6210\u5668"},{"location":"python/Foundation/ch03/#itertools","text":"\u6807\u51c6\u5e93\u4e2d\u7684itertools\u6a21\u5757\u662f\u9002\u7528\u4e8e\u5927\u591a\u6570\u6570\u636e\u7b97\u6cd5\u7684\u751f\u6210\u5668\u96c6\u5408\u3002 import itertools first_letter = lambda x : x [ 0 ] names = [ 'Alan' , 'Adam' , 'Wes' , 'Will' , 'Albert' , 'Steven' ] for letter , names in itertools . groupby ( names , first_letter ): print ( letter ) print ( first_letter ) print ( letter , list ( names )) # names is generator # A # at 0x7fa598a7a0d0> # A ['Alan', 'Adam'] # W # at 0x7fa598a7a0d0> # W ['Wes', 'Will'] # A # at 0x7fa598a7a0d0> # A ['Albert'] # S # at 0x7fa598a7a0d0> # S ['Steven']","title":"\u751f\u6210\u5668\uff1aitertools\u6a21\u5757"},{"location":"python/Foundation/ch03/#8","text":"Python\u7528\u5f02\u5e38\u5bf9\u8c61(exception object)\u6765\u8868\u793a\u5f02\u5e38\u60c5\u51b5\u3002\u9047\u5230\u9519\u8bef\u540e\uff0c\u4f1a\u5f15\u53d1\u5f02\u5e38\u3002\u5982\u679c\u5f02\u5e38\u5bf9\u8c61\u5e76\u672a\u88ab\u5904\u7406\u6216\u6355\u6349\uff0c\u7a0b\u5e8f\u5c31\u4f1a\u7528\u6240\u8c13\u7684\u56de\u6eaf(traceback\uff0c \u4e00\u79cd\u9519\u8bef\u4fe1\u606f)\u7ec8\u6b62\u6267\u884c\u3002 \u5f02\u5e38\u548c\u8bed\u6cd5\u9519\u8bef\u662f\u6709\u533a\u522b\u7684\u3002 \u9519\u8bef\uff1a\u662f\u6307\u4ee3\u7801\u4e0d\u7b26\u5408\u89e3\u91ca\u5668\u6216\u8005\u7f16\u8bd1\u5668\u8bed\u6cd5\u3002 \u5f02\u5e38\uff1a\u662f\u6307\u4e0d\u5b8c\u6574\u3001\u4e0d\u5408\u6cd5\u8f93\u5165\uff0c\u6216\u8005\u8ba1\u7b97\u51fa\u73b0\u9519\u8bef\u3002 python\u91cc\u7528try...except...\u8bed\u53e5\u6765\u5904\u7406\u5f02\u5e38\u60c5\u51b5\u3002 def attempt_float ( x ): try : return float ( x ) except ( TypeError , ValueError ): return \"Type error, not numbers\" r1 = attempt_float ( '1.2256' ) print ( r1 ) # 1.2256 r1 = attempt_float ( 'friends' ) print ( r1 ) # Type error, not numbers","title":"8. \u9519\u8bef\u548c\u5f02\u5e38\u5904\u7406"},{"location":"python/Foundation/ch03/#9","text":"f=open(path, 'w')\uff0c\u4e00\u4e2a\u65b0\u7684\u6587\u4ef6\u4f1a\u5728path\u6307\u5b9a\u7684\u8def\u5f84\u88ab\u521b\u5efa\uff0c\u5e76\u5728\u540c\u4e00\u8def\u5f84\u4e0b\u8986\u76d6\u540c\u540d\u6587\u4ef6\u3002\uff08\u8bf7\u5c0f\u5fc3\uff01\uff09 f=open(path, 'x')\uff0c\u4e00\u4e2a\u65b0\u7684\u6587\u4ef6\u4f1a\u5728path\u6307\u5b9a\u7684\u8def\u5f84\u88ab\u521b\u5efa\uff0c\u5982\u679c\u7ed9\u5b9a\u8def\u5f84\u4e0b\u5df2\u7ecf\u5b58\u5728\u540c\u540d\u6587\u4ef6\u5c31\u4f1a\u521b\u5efa\u5931\u8d25\u3002 import os # \u67e5\u770b\u5f53\u524d\u8def\u5f84 os . getcwd () # '/opt/myMemo' # \u66f4\u6539\u6587\u4ef6\u8bfb\u53d6\u9ed8\u8ba4\u8def\u5f84 os . chdir ( '/opt/myMemo/python/datasets/examples' ) # \u6307\u5b9a\u6587\u4ef6\u540d path = 'file01.txt' # \u6253\u5f00\u6587\u4ef6 f = open ( path ) # \u8bfb\u53d6\u6587\u4ef6\u6bcf\u4e00\u884c\uff0c\u6587\u4ef6\u6bcf\u4e00\u884c\u4f5c\u4e3a\u5217\u8868\u4e00\u4e2a\u5143\u7d20 lines = [ x . rstrip () for x in open ( path )] # \u8f93\u51fa\u5217\u8868 print ( lines ) # \u5173\u95ed\u6587\u4ef6\u4f1a\u5c06\u8d44\u6e90\u91ca\u653e\u56de\u64cd\u4f5c\u7cfb\u7edf f . close () \u53e6\u4e00\u79cd\u66f4\u7b80\u5355\u7684\u5173\u95ed\u6587\u4ef6\u7684\u65b9\u5f0f import os # \u67e5\u770b\u5f53\u524d\u8def\u5f84 os . getcwd () # '/opt/myMemo' # \u66f4\u6539\u6587\u4ef6\u8bfb\u53d6\u9ed8\u8ba4\u8def\u5f84 os . chdir ( '/opt/myMemo/python/datasets/examples' ) # \u6307\u5b9a\u6587\u4ef6\u540d path = 'file01.txt' # \u6253\u5f00\u6587\u4ef6 f = open ( path ) # \u4f7f\u7528with\u8bed\u53e5\u8bfb\u53d6\u6587\u4ef6\uff0c\u6587\u4ef6\u4f1a\u5728with\u4ee3\u7801\u5757\u7ed3\u675f\u540e\u81ea\u52a8\u5173\u95ed\u3002 with open ( path ) as f : lines = [ x . rstrip () for x in open ( path )] # \u8f93\u51fa\uff1a\u6587\u4ef6\u6bcf\u4e00\u884c\u4f5c\u4e3a\u5217\u8868\u4e00\u4e2a\u5143\u7d20 print ( lines ) \u5728\u6253\u5f00\u6587\u4ef6\u65f6\u4f7f\u7528seek\u8bfb\u53d6\u6587\u4ef6\u5185\u5bb9\u8981\u5f53\u5fc3\u3002\u5982\u679c\u6587\u4ef6\u7684\u53e5\u67c4\u4f4d\u7f6e\u6070\u597d\u5728\u4e00\u4e2aUnicode\u7b26\u53f7\u7684\u5b57\u8282\u4e2d\u95f4\u65f6\uff0c\u540e\u7eed\u7684\u8bfb\u53d6\u4f1a\u5bfc\u81f4\u9519\u8bef\u3002 import os # \u67e5\u770b\u5f53\u524d\u8def\u5f84 os . getcwd () # '/opt/myMemo' # \u66f4\u6539\u6587\u4ef6\u8bfb\u53d6\u9ed8\u8ba4\u8def\u5f84 os . chdir ( '/opt/myMemo/python/datasets/examples' ) # \u6307\u5b9a\u6587\u4ef6\u540d path = 'file01.txt' # \u6253\u5f00\u6587\u4ef6 f = open ( path ) # \u8bfb\u53d6\u6587\u4ef6\u3002 print ( f . read ( 5 )) # \u8f93\u51fa\u524d5\u4e2a\u5b57\u7b26\u3002 read\u65b9\u6cd5\u901a\u8fc7\u8bfb\u53d6\u7684\u5b57\u8282\u6570\u6765\u63a8\u8fdb\u6587\u4ef6\u53e5\u67c4\u7684\u4f4d\u7f6e\u3002 # I Thi print ( f . tell ()) # tell\u65b9\u6cd5\u53ef\u4ee5\u7ed9\u51fa\u53e5\u67c4\u5f53\u524d\u7684\u4f4d\u7f6e # 5 print ( f . seek ( 6 )) # seek\u65b9\u6cd5\u53ef\u4ee5\u5c06\u53e5\u67c4\u4f4d\u7f6e\u6539\u53d8\u5230\u6587\u4ef6\u4e2d\u7279\u5b9a\u7684\u5b57\u8282 # 6 print ( f . read ( 1 )) # \u4ece\u7b2c7\u4e2a\u5b57\u8282\u5f00\u59cb\uff0c\u8f93\u51fa1\u4e2a\u5b57\u8282 # k # \u5173\u95ed\u6587\u4ef6\u4f1a\u5c06\u8d44\u6e90\u91ca\u653e\u56de\u64cd\u4f5c\u7cfb\u7edf f . close () \u5982\u679c\u4f7f\u7528\u4e8c\u8fdb\u5236\u65b9\u5f0f\u6253\u5f00\u6587\u4ef6\uff0c\u5219\uff1a import os # \u67e5\u770b\u5f53\u524d\u8def\u5f84 os . getcwd () # '/opt/myMemo' # \u66f4\u6539\u6587\u4ef6\u8bfb\u53d6\u9ed8\u8ba4\u8def\u5f84 os . chdir ( '/opt/myMemo/python/datasets/examples' ) # \u6307\u5b9a\u6587\u4ef6\u540d path = 'file01.txt' # \u6253\u5f00\u6587\u4ef6 f2 = open ( path , 'rb' ) # \u4e8c\u8fdb\u5236\u6a21\u5f0f # \u8bfb\u53d6\u6587\u4ef6 print ( f2 . read ( 5 )) # \u7b2c\u4e00\u4e2ab\u4ee3\u8868\u4e8c\u8fdb\u5236\u683c\u5f0f # b'I Thi' print ( f2 . tell ()) # 5 print ( f2 . seek ( 6 )) # 6 print ( f2 . read ( 2 )) # \u4ece\u7b2c7\u4e2a\u5b57\u8282\u5f00\u59cb\uff0c\u8f93\u51fa2\u4e2a\u5b57\u8282 # b'k ' # \u5173\u95ed\u6587\u4ef6\u4f1a\u5c06\u8d44\u6e90\u91ca\u653e\u56de\u64cd\u4f5c\u7cfb\u7edf f2 . close () \u5c06\u672c\u6587\u5199\u5165\u6587\u4ef6\uff0c\u53ef\u4ee5\u4f7f\u7528\u6587\u4ef6\u5bf9\u8c61\u7684write\u6216wirtelines\u65b9\u6cd5\u3002 import os # \u67e5\u770b\u5f53\u524d\u8def\u5f84 os . getcwd () # '/opt/myMemo' # \u66f4\u6539\u6587\u4ef6\u8bfb\u53d6\u9ed8\u8ba4\u8def\u5f84 os . chdir ( '/opt/myMemo/python/datasets/examples' ) # \u6307\u5b9a\u6587\u4ef6\u540d path1 = 'file01.txt' path2 = 'file02.txt' # file02.txt\u662f\u4e00\u4e2a\u7a7a\u6587\u4ef6 with open ( path2 , 'r+' , encoding = 'utf-8' ) as f : f . writelines ( x for x in open ( path1 , 'r' , encoding = 'utf-8' ) if len ( x ) > 1 ) # \u628afile01.txt\u7684\u5185\u5bb9\u5199\u5165file02.txt lines = f . readlines () print ( lines )","title":"9. \u6587\u4ef6\u4e0e\u64cd\u4f5c\u7cfb\u7edf"},{"location":"python/Foundation/ch03/#10","text":"","title":"10. \u88c5\u9970\u5668"},{"location":"python/Foundation/ch03/#_7","text":"\u7ef4\u57fa\u767e\u79d1\u4e2d\u7684\u89e3\u91ca\uff1a \u95ed\u5305\uff08Closure\uff09 \uff0c\u53c8\u79f0\u8bcd\u6cd5\u95ed\u5305\uff08Lexical Closure\uff09\u6216\u51fd\u6570\u95ed\u5305\uff08function closures\uff09\uff0c\u662f\u5f15\u7528\u4e86\u81ea\u7531\u53d8\u91cf\u7684\u51fd\u6570\u3002\u8fd9\u4e2a\u88ab\u5f15\u7528\u7684\u81ea\u7531\u53d8\u91cf\u5c06\u548c\u8fd9\u4e2a\u51fd\u6570\u4e00\u540c\u5b58\u5728\uff0c\u5373\u4f7f\u5df2\u7ecf\u79bb\u5f00\u4e86\u521b\u9020\u5b83\u7684\u73af\u5883\u4e5f\u4e0d\u4f8b\u5916\u3002 \u95ed\u5305\u5ef6\u4f38\u4e86\u4f5c\u7528\u57df\u7684\u51fd\u6570\uff0c\u5176\u4e2d\u5305\u542b\u51fd\u6570\u5b9a\u4e49\u4f53\u4e2d\u5f15\u7528\u3001\u4f46\u662f\u4e0d\u5728\u5b9a\u4e49\u4f53\u4e2d\u5b9a\u4e49\u7684\u975e\u5168\u5c40\u53d8\u91cf\u3002\u51fd\u6570\u662f\u4e0d\u662f\u533f\u540d\u7684\u6ca1\u6709\u5173\u7cfb\uff0c\u5173\u952e\u662f\u5b83\u80fd\u8bbf\u95ee\u5b9a\u4e49\u4f53\u4e4b\u5916\u5b9a\u4e49\u7684\u975e\u5168\u5c40\u53d8\u91cf\u3002 \u4f8b\u4e00\uff0c\u8ba1\u7b97\u79fb\u52a8\u5e73\u5747\u503c\u3002 \u4e0b\u9762\u662f\u662f\u4f20\u7edf\u7c7b\u5b9e\u73b0\u65b9\u5f0f\uff0cAvg\u7684\u5b9e\u4f8b\u662f\u53ef\u8c03\u7528\u7684\u5bf9\u8c61\u3002 class Avg (): def __init__ ( self ): self . mylist = [] def __call__ ( self , newValue ): self . mylist . append ( newValue ) total = sum ( self . mylist ) return total / len ( self . mylist ) avg = Avg () avg ( 10 ) # 10.0 avg ( 20 ) # 15.0 avg ( 30 ) # 20.0 \u4e0b\u9762\u662f\u9ad8\u9636\u51fd\u6570\u5b9e\u73b0\u65b9\u5f0f\u3002\u8c03\u7528 make_avg \u65f6\uff0c\u8fd4\u56de\u4e00\u4e2a my_avg \u51fd\u6570\u5bf9\u8c61\u3002\u6bcf\u6b21\u8c03\u7528 my_avg \u65f6\uff0c\u5b83\u4f1a\u628a\u53c2\u6570\u6dfb\u52a0\u5230\u7cfb\u5217\u503c\u4e2d\uff0c\u7136\u540e\u8ba1\u7b97\u5f53\u524d\u5e73\u5747\u503c\u3002 def make_avg (): my_list = [] def avg ( newValue ): my_list . append ( newValue ) total = sum ( my_list ) return total / len ( my_list ) return avg my_avg = make_avg () my_avg ( 10 ) # 10.0 my_avg ( 20 ) # 15.0 my_avg ( 30 ) # 20.0 my_avg . __code__ . co_varnames # ('newValue', 'total') my_avg . __code__ . co_freevars # ('my_list',) my_avg . __closure__ # (,) my_avg . __closure__ [ 0 ] . cell_contents # [10, 20, 30] \u8fd9\u4e24\u4e2a\u793a\u4f8b\u6709\u5171\u901a\u4e4b\u5904\uff1a\u8c03\u7528 Avg() \u6216 make_avg() \u5f97\u5230\u4e00\u4e2a\u53ef\u8c03\u7528\u5bf9\u8c61 avg \uff0c\u5b83\u4f1a\u66f4\u65b0\u5386\u53f2\u503c\uff0c\u7136\u540e\u8ba1\u7b97\u5f53\u524d\u5747\u503c\u3002 \u5728\u7c7b\u5b9e\u73b0\u4e2d\uff0c avg \u662f Avg \u7684\u5b9e\u4f8b\uff1b\u5728\u9ad8\u9636\u51fd\u6570\u5b9e\u73b0\u4e2d\u662f\u5185\u90e8\u51fd\u6570 avg \u3002 \u4e24\u79cd\u5b9e\u73b0\u65b9\u5f0f\u4e2d\uff0c\u6211\u4eec\u90fd\u53ea\u9700\u8c03\u7528 avg(n) \uff0c\u628a n \u653e\u5165\u7cfb\u5217\u503c\u4e2d\uff0c\u7136\u540e\u91cd\u65b0\u8ba1\u7b97\u5747\u503c\u3002 \u7b2c\u4e00\u4e2a\u4f8b\u5b50\u4e2d\uff0c Avg \u7c7b\u7684\u5b9e\u4f8b avg \u5728 self.series \u5b9e\u4f8b\u5c5e\u6027\u4e2d\u5b58\u50a8\u5386\u53f2\u503c\u3002 \u7b2c\u4e8c\u4e2a\u4f8b\u5b50\u4e2d\u7684 my_list \u662f\u51fd\u6570 make_avg() \u7684\u5c40\u90e8\u53d8\u91cf\uff0c\u4e5f\u79f0\u4e3a\u8be5\u51fd\u6570\u7684**\u81ea\u7531\u53d8\u91cf\uff08free variable\uff09**\uff0c\u6307\u672a\u5728\u672c\u5730\u4f5c\u7528\u57df\u4e2d\u7ed1\u5b9a\u7684\u53d8\u91cf\u3002 avg() \u51fd\u6570\u7684\u95ed\u5305\u5ef6\u4f38\u5230\u51fd\u6570\u7684\u4f5c\u7528\u57df\u4e4b\u5916\uff0c\u5305\u542b\u4e86 make_avg() \u7684\u81ea\u7531\u53d8\u91cf my_list \u7684\u7ed1\u5b9a\u3002 \u5bf9\u4e8e\u8fd4\u56de\u7684 my_avg \u5bf9\u8c61\uff0c\u5176 __code__ \u5c5e\u6027\uff08\u8868\u793a\u7f16\u8bd1\u540e\u7684\u51fd\u6570\u5b9a\u4e49\u4f53\uff09\u4e2d\u4fdd\u5b58\u4e86\u5c40\u90e8\u53d8\u91cf\u548c\u81ea\u7531\u53d8\u91cf\u7684\u540d\u79f0\uff0c\u5373 my_avg.__code__.co_varnames \u8fd4\u56de\u4e86\u5c40\u90e8\u53d8\u91cf ('newValue', 'total') \u548c my_avg.__code__.co_freevars \u8fd4\u56de\u4e86\u81ea\u7531\u53d8\u91cf ('my_list',) \u3002 \u81ea\u7531\u53d8\u91cf my_list \u7ed1\u5b9a\u5728\u8fd4\u56de\u7684 my_avg \u7684 __closure__ \u7684\u5c5e\u6027\u4e2d\uff0c my_avg.__closure__ \u4e2d\u7684\u5404\u4e2a\u5143\u7d20\u5bf9\u5e94\u4e86 my_avg.__code__.co_freevars \u4e2d\u7684\u4e00\u4e2a\u540d\u79f0\u3002\u8fd9\u4e9b\u5143\u7d20\u662f cell \u5bf9\u8c61\uff0c\u6709\u4e2a cell_contents \u5c5e\u6027\uff0c\u5982\uff1a my_avg.__closure__ \u8fd4\u56de (,) \uff0c\u91cc\u9762\u4fdd\u5b58\u7740\u771f\u6b63\u7684\u503c\uff0c\u5982 my_avg.__closure__[0].cell_contents \u91cc\u9762\u4fdd\u5b58\u6bcf\u6b21\u8c03\u7528\u7684\u771f\u5b9e\u503c [10, 20, 30] \u3002 \u4e0a\u9762 my_list \u662f\u4e00\u4e2a\u53ef\u53d8\u7c7b\u578b\uff0c\u5982\u679c\u7528\u4e0d\u53ef\u53d8\u7c7b\u578b\u6539\u5199\uff0c\u5e76\u5b9e\u73b0\u95ed\u5305\uff0c\u53ef\u4ee5\u4f7f\u7528 nolocal \u8fdb\u884c\u58f0\u660e\u3002\u5b83\u7684\u4f5c\u7528\u662f\u628a\u53d8\u91cf\u6807\u8bb0\u4e3a\u81ea\u7531\u53d8\u91cf\uff0c\u5373\u4f7f\u5728\u51fd\u6570\u4e2d\u4e3a\u53d8\u91cf\u8d4b\u4e88\u65b0\u503c\u4e86\uff0c\u4e5f\u4f1a\u53d8\u6210\u81ea\u7531\u53d8\u91cf\u3002\u5982\u679c\u4e3anonlocal\u58f0\u660e\u7684\u53d8\u91cf\u8d4b\u4e88\u65b0\u503c\uff0c\u95ed\u5305\u4e2d\u4fdd\u5b58\u7684\u7ed1\u5b9a\u4f1a\u66f4\u65b0\u3002 my_avg.__code__.co_freevars \u8fd4\u56de\u4e862\u4e2a\u81ea\u7531\u53d8\u91cf ('count', 'total') \uff0c\u5e76\u5728 my_avg.__closure__[0].cell_contents \u548c my_avg.__closure__[1].cell_contents \u91cc\u9762\u4fdd\u5b58\u4e86\u6700\u540e\u4e00\u6b21\u6267\u884c\u7684\u771f\u5b9e\u503c\u3002 def make_avg (): count = 0 total = 0 def avg ( newValue ): nonlocal count , total count += 1 total += newValue return total / count return avg my_avg = make_avg () my_avg ( 10 ) # 10.0 my_avg ( 20 ) # 15.0 my_avg ( 30 ) # 20.0 my_avg . __code__ . co_varnames # ('newValue',) my_avg . __code__ . co_freevars # ('count', 'total') my_avg . __closure__ # (, ) my_avg . __closure__ [ 0 ] . cell_contents # 3 my_avg . __closure__ [ 1 ] . cell_contents # 60 \u4f8b\u4e8c\uff1a money \u662f\u4e00\u4e2a\u5c40\u90e8\u53d8\u91cf\uff0c\u5728 get_money \u662f\u5916\u56f4\u51fd\u6570\uff0c\u51fd\u6570\u6267\u884c\u4e4b\u540e\u5e94\u8be5\u5c31\u4e0d\u4f1a\u5b58\u5728\u4e86\u3002 \u4f46\u662f\u5d4c\u5957\u51fd\u6570 work \u5f15\u7528\u4e86 money \u8fd9\u4e2a\u81ea\u7531\u53d8\u91cf\uff0c\u5c06\u8fd9\u4e2a\u5c40\u90e8\u53d8\u91cf\u5c01\u95ed\u5728\u4e86\u5d4c\u5957\u51fd\u6570 work \u4e2d\uff0c\u8fd9\u6837\u5c31\u5f62\u6210\u4e86\u4e00\u4e2a\u95ed\u5305\u3002 closure = get_money() \u83b7\u5f97\u7684\u5c31\u662f\u4e00\u4e2a\u95ed\u5305\u3002 closure() \u8f93\u51fa\u95ed\u5305\uff0c\u5373\uff0c\u6267\u884c\u4e86 work() \uff0c\u6253\u5370\u8f93\u51fa money \u7684\u503c\u3002 \u672c\u5730\u51fd\u6570\u901a\u8fc7global\u58f0\u660e\u5bf9\u5168\u5c40\u53d8\u91cf\u8fdb\u884c\u5f15\u7528\u4fee\u6539\uff0c\u90a3\u4e48\u5bf9\u4e8e\u5185\u5d4c\u51fd\u6570 work() \u4f5c\u7528\u57df\u4e2d\u7684\u53d8\u91cf\u8fdb\u884c\u4fee\u6539\uff0c\u5c31\u8981\u4f7f\u7528 nonlocal \u8fdb\u884c\u58f0\u660e\u3002 def get_money (): money = 0 def work (): nonlocal money money += 100 print ( money ) return work closure = get_money () closure () # 100 closure () # 200 closure () # 300 \u4f8b\u4e09\uff1a \u51fd\u6570 maker \u4e2d\u5b9a\u4e49\u4e86\u51fd\u6570 action \uff0c action \u5f15\u7528\u4e86 maker \u5d4c\u5957\u4f5c\u7528\u57df\u5185\u7684\u53d8\u91cf k \uff0c\u5e76\u4e14\uff0c maker \u5c06\u51fd\u6570 action \u4f5c\u4e3a\u8fd4\u56de\u5bf9\u8c61\u8fdb\u884c\u8fd4\u56de\u3002 \u8fd9\u6837\uff0c\u6211\u4eec\u901a\u8fc7\u6267\u884c f = maker(2) \uff0c f \u83b7\u53d6\u4e86\u8fd4\u56de\u5bf9\u8c61 action \uff0c\u867d\u7136\u6b64\u65f6 maker \u51fd\u6570\u4ee5\u53ca\u7ed3\u675f\u9000\u51fa\u4e86\uff0c\u4f46\u5bf9\u8c61 f \u4ecd\u7136\u8bb0\u4f4f\u4e86\u51fd\u6570 maker \u5d4c\u5957\u4f5c\u7528\u57df\u5185\u7684\u53d8\u91cf k \u548c n \uff0c\u5e76\u5728\u6267\u884c f(3) \u65f6\uff0c\u5c06 x=3 \u4ee5\u53ca\u4e4b\u524d\u8bb0\u4f4f\u7684 k \u548c n \uff0c\u4e00\u5e76\u4f20\u5165 action() \uff0c\u8ba1\u7b97\u5e76\u8fd4\u56de x + n + k \u503c\u3002 make \u4e5f\u79f0\u4e3a**\u5de5\u5382\u51fd\u6570**\u3002 def maker ( n ): k = 8 def action ( x ): return x + n + k return action f = maker ( 2 ) print ( f ( 3 )) # 13 print ( f ( 4 )) # 14 print ( f ( 5 )) # 15 \u7ed3\u5408\u524d\u97622\u4e2a\u4f8b\u5b50\u518d\u770b\u4e0a\u9762\u7684\u89e3\u91ca\uff0c\u95ed\u5305\u5c31\u662f\u5f15\u7528\u4e86\u81ea\u7531\u53d8\u91cf\u7684\u51fd\u6570\uff0c\u8fd9\u4e2a\u51fd\u6570\u4fdd\u5b58\u4e86\u6267\u884c\u7684\u4e0a\u4e0b\u6587\uff0c\u53ef\u4ee5\u8131\u79bb\u539f\u672c\u7684\u4f5c\u7528\u57df\u72ec\u7acb\u5b58\u5728\u3002","title":"\u95ed\u5305"},{"location":"python/Foundation/ch03/#_8","text":"\u770b\u4e0b\u9762\u4f8b\u5b50\uff0c\u5c06\u51fd\u6570\u4f5c\u4e3a\u53c2\u6570\u4f20\u7ed9\u53e6\u4e00\u4e2a\u51fd\u6570\uff0c\u51fd\u6570 my_decorator \u7684\u4f20\u5165\u53c2\u6570\u6b63\u597d\u662f\u5176\u5d4c\u5957\u51fd\u6570 myFunc \u3002 def my_decorator ( nestedFunc ): def myFunc (): print ( \"Before executing nestedFunc()\" ) nestedFunc () print ( \"After executing nestedFunc()\" ) return myFunc def nestedFunc (): print ( \"Decoration - executing nestedFunc()\" ) nestedFunc () # Decoration - executing nestedFunc() nestedFunc = my_decorator ( nestedFunc ) nestedFunc () # Before executing nestedFunc() # Decoration - executing nestedFunc() # After executing nestedFunc() \u88c5\u9970\u5668\u53ea\u662f\u4e2a\u65b9\u6cd5\uff0c\u4f7f\u7528\u65f6\u7528\u4e86 @ \u8bed\u6cd5\u3002 @ \u8bed\u6cd5\u53ea\u662f\u5c06\u51fd\u6570 nestedFunc \u4f20\u5165\u88c5\u9970\u5668\u51fd\u6570 my_decorator \u3002 @my_decorator \u662f nestedFunc = my_decorator(nestedFunc) \u7684\u5feb\u6377\u8868\u8fbe\u65b9\u5f0f\uff0c @my_decorator def nestedFunc (): print ( \"New added to decoration - executing nestedFunc()\" ) nestedFunc () # Before executing nestedFunc() # New added to decoration - executing nestedFunc() # After executing nestedFunc() print ( nestedFunc . __name__ ) # myFunc \u4f46\u4e0a\u4f8b\u6700\u540e\u7684\u8f93\u51fa\u4e0d\u662f\u6211\u4eec\u60f3\u8981\u7684\uff0c\u6211\u4eec\u5e0c\u671b\u8f93\u51fa nestedFunc \uff0c\u4f46\u5374\u88ab myFunc \u66ff\u4ee3\u4e86\uff0c\u5b83\u91cd\u5199\u4e86\u6211\u4eec\u51fd\u6570\u7684\u540d\u5b57\u548c\u6ce8\u91ca\u6587\u6863(docstring)\u3002 \u4e0b\u9762\u4f7f\u7528 functools.wraps \u6765\u4fee\u6b63\u4e0a\u9762\u7684\u95ee\u9898\u3002 from functools import wraps def my_decorator ( nestedFunc ): @wraps ( nestedFunc ) def myFunc (): print ( \"Before executing nestedFunc()\" ) nestedFunc () print ( \"After executing nestedFunc()\" ) return myFunc def nestedFunc (): print ( \"Decoration - executing nestedFunc()\" ) @my_decorator def nestedFunc (): print ( \"New added to decoration - executing nestedFunc()\" ) nestedFunc () # Before executing nestedFunc() # New added to decoration - executing nestedFunc() # After executing nestedFunc() print ( nestedFunc . __name__ ) # nestedFunc \u4e0b\u9762\u662f\u88c5\u9970\u5668\u7684\u84dd\u672c\u89c4\u8303\u3002 from functools import wraps def decorator_name ( f ): @wraps ( f ) def decorated ( * args , ** kwargs ): if not can_run : return \"Function will not run\" return f ( * args , ** kwargs ) return decorated @decorator_name def func (): return ( \"Function is running\" ) can_run = True print ( func ()) # Output: Function is running can_run = False print ( func ()) # Output: Function will not run \u4e0b\u9762\u8fd8\u662f\u4e00\u4e2a\u88c5\u9970\u5668\u7684\u4f8b\u5b50\u3002\u628a\u4e0b\u9762\u7684\u4ee3\u7801\u6bb5\u4fdd\u5b58\u5230\u6587\u4ef6 test.py \u3002 registry = [] def register ( func ): print ( f 'running register { func } ' ) registry . append ( func ) return func @register def f1 (): print ( 'running f1()' ) @register def f2 (): print ( 'running f2()' ) def f3 (): print ( 'running f3()' ) def main (): print ( 'runnning main()' ) print ( f 'registry--> { registry } ' ) f1 () f2 () f3 () if __name__ == '__main__' : main () \u6267\u884c\u4e0a\u8ff0\u4ee3\u7801\u6bb5 python3 test.py \uff0c\u5f97\u5230\u4e0b\u9762\u7684\u7ed3\u679c\u3002 running register < function f1 at 0x7f70847bec80 > running register < function f2 at 0x7f70705aa9d8 > runnning main () registry --> [ < function f1 at 0x7f70847bec80 > , < function f2 at 0x7f70705aa9d8 > ] running f1 () running f2 () running f3 () register \u5728\u6a21\u5757\u4e2d\u5176\u4ed6\u51fd\u6570\u4e4b\u524d\u8fd0\u884c\uff08\u4e24\u6b21\uff09\u3002\u8c03\u7528 register \u65f6\uff0c\u4f20\u7ed9\u5b83\u7684\u53c2\u6570\u662f\u88ab\u88c5\u9970\u7684\u51fd\u6570\uff0c\u4f8b\u5982 function f1 at 0x7f70847bec80> \u3002\u52a0\u8f7d\u6a21\u5757\u540e\uff0c registry \u4e2d\u6709\u4e24\u4e2a\u88ab\u88c5\u9970\u51fd\u6570\u7684\u5f15\u7528\uff1a f1 \u548c f2 \u3002\u8fd9\u4e24\u4e2a\u51fd\u6570\uff0c\u4ee5\u53ca f3 \uff0c\u53ea\u5728 main \u660e\u786e\u8c03\u7528\u5b83\u4eec\u65f6\u624d\u6267\u884c\u3002 \u7531\u6b64\u5f97\uff0c\u51fd\u6570\u88c5\u9970\u5668\u5728\u5bfc\u5165\u6a21\u5757\u65f6\u7acb\u5373\u6267\u884c\uff0c\u800c\u88ab\u88c5\u9970\u7684\u51fd\u6570\u53ea\u5728\u660e\u786e\u8c03\u7528\u65f6\u8fd0\u884c\uff0c\u5373Python\u4e2d\u63d0\u5230\u7684**\u5bfc\u5165\u65f6**\u548c**\u8fd0\u884c\u65f6**\u4e4b\u95f4\u7684\u533a\u522b\u3002 \u4e0a\u9762\u4f8b\u5b50\u4e2d\u88c5\u9970\u5668\u51fd\u6570\u4e0e\u88ab\u88c5\u9970\u7684\u51fd\u6570\u5728\u540c\u4e00\u4e2a\u6a21\u5757\u4e2d\u5b9a\u4e49\u3002\u5b9e\u9645\u5e94\u7528\u4e2d\uff0c\u88c5\u9970\u5668\u901a\u5e38\u5728\u4e00\u4e2a\u6a21\u5757\u4e2d\u5b9a\u4e49\uff0c\u7136\u540e\u5e94\u7528\u5230\u5176\u4ed6\u6a21\u5757\u4e2d\u7684\u51fd\u6570\u4e0a\u3002 \u4e0a\u9762\u4f8b\u5b50\u4e2d register \u88c5\u9970\u5668\u8fd4\u56de\u7684\u51fd\u6570\u4e0e\u901a\u8fc7\u53c2\u6570\u4f20\u5165\u7684\u76f8\u540c\u3002\u5b9e\u9645\u5e94\u7528\u4e2d\uff0c\u5927\u591a\u6570\u88c5\u9970\u5668\u4f1a\u5728\u5185\u90e8\u5b9a\u4e49\u4e00\u4e2a\u51fd\u6570\uff0c\u7136\u540e\u5c06\u5176\u8fd4\u56de\u3002","title":"\u88c5\u9970\u5668"},{"location":"python/Foundation/ch04/","text":"Python\u9762\u5411\u5bf9\u8c61\u6982\u5ff5 \u00b6 \u7c7b(class)\u628a\u6570\u636e\u4e0e\u529f\u80fd\u7ed1\u5b9a\u5728\u4e00\u8d77\u3002\u521b\u5efa\u65b0\u7c7b\u5c31\u662f\u521b\u5efa\u65b0\u7684\u5bf9\u8c61\u7c7b\u578b\uff08type of object\uff09\uff0c\u4ece\u800c\u521b\u5efa\u8be5\u7c7b\u578b\u7684\u65b0\u5b9e\u4f8b\uff08instances\uff09\u3002 \u7c7b\u5b9e\u4f8b\u5177\u6709\u591a\u79cd\u4fdd\u6301\u81ea\u8eab\u72b6\u6001\u7684\u5c5e\u6027\uff08attributes\uff09\u3002 \u7c7b\u5b9e\u4f8b\u8fd8\u652f\u6301\uff08\u7531\u7c7b\u5b9a\u4e49\u7684\uff09\u4fee\u6539\u81ea\u8eab\u72b6\u6001\u7684\u65b9\u6cd5\uff08methods\uff09\u3002 Python\u7684\u7c7b\u652f\u6301\u6240\u6709\u9762\u5411\u5bf9\u8c61\u7f16\u7a0b\uff08OOP\uff09\u7684\u6807\u51c6\u7279\u6027\uff1a \u7c7b\u7ee7\u627f\uff08class inheritance\uff09\u673a\u5236\u652f\u6301\u591a\u4e2a\u57fa\u7c7b\uff08base classes\uff09\uff1b \u6d3e\u751f\u7c7b\uff08derived class\uff09\u53ef\u4ee5\u8986\u76d6\u57fa\u7c7b\u7684\u4efb\u4f55\u65b9\u6cd5\uff08methods\uff09\uff1b \u7c7b\u7684\u65b9\u6cd5\u53ef\u4ee5\u8c03\u7528\u57fa\u7c7b\u4e2d\u76f8\u540c\u540d\u79f0\u7684\u65b9\u6cd5 \u5bf9\u8c61\u53ef\u4ee5\u5305\u542b\u4efb\u610f\u6570\u91cf\u548c\u7c7b\u578b\u7684\u6570\u636e\u3002 \u7c7b\uff08class\uff09\u548c\u6a21\u5757\uff08module\uff09\u90fd\u62e5\u6709\u52a8\u6001\u7279\u6027\uff08dynamic nature\uff09\uff1a\u5728\u8fd0\u884c\u65f6\u521b\u5efa\uff0c\u521b\u5efa\u540e\u4e5f\u53ef\u4ee5\u4fee\u6539\u3002 \u540d\u79f0Names\u548c\u5bf9\u8c61Objects \u00b6 \u5bf9\u8c61\u4e4b\u95f4\u76f8\u4e92\u72ec\u7acb\uff0c\u591a\u4e2a\u540d\u79f0\uff08names\uff09\uff08\u5728\u591a\u4e2a\u4f5c\u7528\u57df\u5185\uff09\u53ef\u4ee5\u7ed1\u5b9a\u5230\u540c\u4e00\u4e2a\u5bf9\u8c61\u3002 \u5176\u4ed6\u8bed\u8a00\u79f0\u4e4b\u4e3a\u522b\u540d\uff08alias\uff09\u3002 \u522b\u540d\u5728\u67d0\u4e9b\u65b9\u9762\u5c31\u50cf\u6307\u9488\u3002\u4f8b\u5982\uff0c\u4f20\u9012\u5bf9\u8c61\u7684\u4ee3\u4ef7\u5f88\u5c0f\uff0c\u56e0\u4e3a\u5b9e\u73b0\u53ea\u4f20\u9012\u4e00\u4e2a\u6307\u9488\uff1b\u5982\u679c\u51fd\u6570\u4fee\u6539\u4e86\u4f5c\u4e3a\u53c2\u6570\u4f20\u9012\u7684\u5bf9\u8c61\uff0c\u8c03\u7528\u8005\u5c31\u53ef\u4ee5\u770b\u5230\u66f4\u6539\u3002 \u4f5c\u7528\u57dfScopes\u548c\u547d\u540d\u7a7a\u95f4Namespaces \u00b6 **\u547d\u540d\u7a7a\u95f4\uff08namespace\uff09**\u662f\u4e00\u4e2a\u4ece\u540d\u5b57\u5230\u5bf9\u8c61\u7684\u6620\u5c04\u3002 \u5f53\u524d\u5927\u90e8\u5206\u547d\u540d\u7a7a\u95f4\u90fd\u7531 Python \u5b57\u5178\u5b9e\u73b0\u3002 \u4e0b\u9762\u662f\u51e0\u4e2a\u547d\u540d\u7a7a\u95f4\u7684\u4f8b\u5b50\uff1a \u5b58\u653e\u5185\u7f6e\u51fd\u6570\u7684\u96c6\u5408\uff08\u5305\u542b abs() \u8fd9\u6837\u7684\u51fd\u6570\uff0c\u548c\u5185\u5efa\u7684\u5f02\u5e38\u7b49\uff09\uff1b \u6a21\u5757\u4e2d\u7684\u5168\u5c40\u540d\u79f0\uff1b \u51fd\u6570\u8c03\u7528\u4e2d\u7684\u5c40\u90e8\u540d\u79f0\uff1b \u4ece\u67d0\u79cd\u610f\u4e49\u4e0a\u8bf4\uff0c \u5bf9\u8c61\u7684\u5c5e\u6027\u96c6\u5408\uff08the set of attributes of an object\uff09\u4e5f\u662f\u4e00\u79cd\u547d\u540d\u7a7a\u95f4\u7684\u5f62\u5f0f \u3002 \u5173\u4e8e\u547d\u540d\u7a7a\u95f4\u7684\u91cd\u8981\u4e00\u70b9\u662f\uff0c\u4e0d\u540c\u547d\u540d\u7a7a\u95f4\u4e2d\u7684\u540d\u79f0\u4e4b\u95f4\u7edd\u5bf9\u6ca1\u6709\u5173\u7cfb\uff1b \u4f8b\u5982\uff0c\u5728\u4e24\u4e2a\u4e0d\u540c\u7684\u6a21\u5757\u4e2d\u90fd\u53ef\u4ee5\u5b9a\u4e49\u4e00\u4e2a maximize \u51fd\u6570\u800c\u4e0d\u4f1a\u4ea7\u751f\u6df7\u6dc6\uff0c\u4f46\u5728\u8c03\u7528 maximize \u51fd\u6570\u65f6\u5fc5\u987b\u5fc5\u987b\u5728\u5176\u524d\u9762\u52a0\u4e0a\u6a21\u5757\u540d\u79f0\u3002 \u4efb\u4f55\u8ddf\u5728\u4e00\u4e2a\u70b9\u53f7\u4e4b\u540e\u7684\u540d\u79f0\u90fd\u79f0\u4e3a**\u5c5e\u6027\uff08attribute\uff09**\u3002\u4f8b\u5982\uff0c\u5728\u8868\u8fbe\u5f0f z.real \u4e2d\uff0c real \u662f\u5bf9\u8c61 z \u7684\u4e00\u4e2a\u5c5e\u6027\u3002 \u6309\u4e25\u683c\u7684\u8bf4\u6cd5\uff0c \u5bf9\u6a21\u5757\uff08module\uff09\u4e2d\u7684\u540d\u79f0\u7684\u5f15\u7528\uff08reference\uff09\u90fd\u5c5e\u4e8e\u5c5e\u6027\u5f15\u7528\uff08attribute reference\uff09 \uff1a \u5728\u8868\u8fbe\u5f0f modname.funcname \u4e2d\uff0c modname \u662f\u4e00\u4e2a\u6a21\u5757\u5bf9\u8c61\uff08module object\uff09\u800c funcname \u662f\u5b83\u7684\u4e00\u4e2a\u5c5e\u6027\u3002 \u5728\u6b64\u60c5\u51b5\u4e0b\u5728\u6a21\u5757\u7684\u5c5e\u6027\uff08module\u2019s attribute\uff09\u548c\u6a21\u5757\u4e2d\u5b9a\u4e49\u7684\u5168\u5c40\u540d\u79f0\u4e4b\u95f4\u6b63\u597d\u5b58\u5728\u4e00\u4e2a\u76f4\u89c2\u7684\u6620\u5c04\uff1a\u5b83\u4eec\u5171\u4eab\u76f8\u540c\u7684\u547d\u540d\u7a7a\u95f4\u3002 \u4f46\u5b58\u5728\u4e00\u4e2a\u4f8b\u5916\u3002 \u6a21\u5757\u5bf9\u8c61\u6709\u4e00\u4e2a\u53ea\u8bfb\u5c5e\u6027 __dict__ \uff0c\u5b83\u8fd4\u56de\u7528\u4e8e\u5b9e\u73b0\u6a21\u5757\u547d\u540d\u7a7a\u95f4\u7684\u5b57\u5178\uff1b __dict__ \u662f\u5c5e\u6027\u4f46\u4e0d\u662f\u5168\u5c40\u540d\u79f0\u3002 \u4f7f\u7528\u8fd9\u4e2a\u5c06\u8fdd\u53cd\u547d\u540d\u7a7a\u95f4\u5b9e\u73b0\u7684\u62bd\u8c61\uff0c\u5e94\u5f53\u4ec5\u88ab\u7528\u4e8e\u4e8b\u540e\u8c03\u8bd5\u5668\u4e4b\u7c7b\u7684\u573a\u5408\u3002 **\u5c5e\u6027\uff08attribute\uff09**\u53ef\u4ee5\u662f\u53ea\u8bfb\u6216\u8005\u53ef\u5199\u7684\uff0c\u6240\u4ee5\u53ef\u4ee5\u5bf9\u5c5e\u6027\u8fdb\u884c\u8d4b\u503c\uff0c\u4f8b\u5982 modname.the_answer = 42 \u3002 \u5220\u9664\u5c5e\u6027\u53ef\u4ee5\u7528del\u8bed\u53e5\uff0c\u4f8b\u5982\uff0c del modname.the_answer \u5c06\u4f1a\u4ece\u540d\u4e3a modname \u7684\u5bf9\u8c61\u4e2d\u79fb\u9664 the_answer \u5c5e\u6027\u3002 \u547d\u540d\u7a7a\u95f4\u5728\u4e0d\u540c\u65f6\u523b\u88ab\u521b\u5efa\uff0c\u62e5\u6709\u4e0d\u540c\u7684\u751f\u5b58\u671f\uff08lifetimes\uff09\u3002\u5305\u542b\u5185\u7f6e\u540d\u79f0\uff08built-in names\uff09\u7684\u547d\u540d\u7a7a\u95f4\u662f\u5728Python\u89e3\u91ca\u5668\u542f\u52a8\u65f6\u521b\u5efa\u7684\uff0c\u6c38\u8fdc\u4e0d\u4f1a\u88ab\u5220\u9664\u3002 \u6a21\u5757\u7684\u5168\u5c40\u547d\u540d\u7a7a\u95f4\uff08global namespace\uff09\u5728\u6a21\u5757\u5b9a\u4e49\u88ab\u8bfb\u5165\u65f6\u521b\u5efa\uff1b\u901a\u5e38\uff0c\u6a21\u5757\u547d\u540d\u7a7a\u95f4\u4e5f\u4f1a\u6301\u7eed\u5230\u89e3\u91ca\u5668\u9000\u51fa\u3002 \u88ab\u89e3\u91ca\u5668\u7684\u9876\u5c42\u8c03\u7528\uff08top-level invocation\uff09\u6267\u884c\u7684\u8bed\u53e5\uff0c\u4ece\u4e00\u4e2a\u811a\u672c\u6587\u4ef6\u8bfb\u53d6\u6216\u4ea4\u4e92\u5f0f\u5730\u8bfb\u53d6\uff0c\u88ab\u8ba4\u4e3a\u662f __main__ \u6a21\u5757\u8c03\u7528\u7684\u4e00\u90e8\u5206\uff0c\u56e0\u6b64\u5b83\u4eec\u62e5\u6709\u81ea\u5df1\u7684\u5168\u5c40\u547d\u540d\u7a7a\u95f4\u3002 \u5185\u7f6e\u540d\u79f0\uff08built-in names\uff09\u5b9e\u9645\u4e0a\u4e5f\u5b58\u5728\u4e8e\u4e00\u4e2a\u6a21\u5757\u4e2d\uff0c\u8fd9\u4e2a\u6a21\u5757\u88ab\u79f0\u4f5c builtins \u3002 \u4e00\u4e2a\u51fd\u6570\u7684\u672c\u5730\u547d\u540d\u7a7a\u95f4\uff08local namespace\uff09\u5728\u8fd9\u4e2a\u51fd\u6570\u88ab\u8c03\u7528\u65f6\u521b\u5efa\uff0c\u5e76\u5728\u51fd\u6570\u8fd4\u56de\u6216\u629b\u51fa\u4e00\u4e2a\u65e0\u6cd5\u5728\u8be5\u51fd\u6570\u5185\u90e8\u5904\u7406\u7684\u9519\u8bef\u65f6\u88ab\u5220\u9664\u3002 \u6bcf\u6b21\u9012\u5f52\u8c03\u7528\uff08recursive invocations\uff09\u90fd\u4f1a\u6709\u5b83\u81ea\u5df1\u7684\u672c\u5730\u547d\u540d\u7a7a\u95f4\u3002 \u4e00\u4e2a**\u4f5c\u7528\u57df\uff08scope\uff09**\u662f\u4e00\u4e2a\u547d\u540d\u7a7a\u95f4\u53ef\u76f4\u63a5\u8bbf\u95ee\uff08directly accessible\uff09\u7684Python\u7a0b\u5e8f\u7684\u4ee3\u7801\u533a\u57df\u3002 \u8fd9\u91cc\u7684 \u201c\u53ef\u76f4\u63a5\u8bbf\u95ee\u201d \u610f\u5473\u7740\u4e0d\u52a0\u4efb\u4f55\u9650\u5b9a\u7684\u540d\u79f0\u5f15\u7528\u4f1a\u5728\u547d\u540d\u7a7a\u95f4\u4e2d\u8fdb\u884c\u67e5\u627e\u3002 \u867d\u7136\u4f5c\u7528\u57df\u662f\u9759\u6001\u5730\u786e\u5b9a\u7684\uff0c\u4f46\u5b83\u4eec\u4f1a\u88ab\u52a8\u6001\u5730\u4f7f\u7528\u3002 \u5728\u4ee3\u7801\u6267\u884c\u671f\u95f4\u7684\u4efb\u4f55\u65f6\u523b\uff0c\u4f1a\u67093\u62164\u4e2a\u7684\u5d4c\u5957\u4f5c\u7528\u57df\u4f9b\u547d\u540d\u7a7a\u95f4\u76f4\u63a5\u8bbf\u95ee: \u6700\u5148\u641c\u7d22\u7684\u6700\u5185\u90e8\u4f5c\u7528\u57df\u5305\u542b\u5c40\u90e8\u540d\u79f0 \u4ece\u6700\u8fd1\u7684\u5c01\u95ed\u4f5c\u7528\u57df\u5f00\u59cb\u641c\u7d22\u7684\u4efb\u4f55\u5c01\u95ed\u51fd\u6570\u7684\u4f5c\u7528\u57df\u5305\u542b\u975e\u5c40\u90e8\u540d\u79f0\uff0c\u4e5f\u5305\u62ec\u975e\u5168\u5c40\u540d\u79f0 \u5012\u6570\u7b2c\u4e8c\u4e2a\u4f5c\u7528\u57df\u5305\u542b\u5f53\u524d\u6a21\u5757\u7684\u5168\u5c40\u540d\u79f0 \u6700\u5916\u9762\u7684\u4f5c\u7528\u57df\uff08\u6700\u540e\u641c\u7d22\uff09\u662f\u5305\u542b\u5185\u7f6e\u540d\u79f0\u7684\u547d\u540d\u7a7a\u95f4 \u5982\u679c\u4e00\u4e2a\u540d\u79f0\u88ab\u58f0\u660e\u4e3a\u5168\u5c40\u53d8\u91cf\uff0c\u5219\u6240\u6709\u5f15\u7528\u548c\u8d4b\u503c\u5c06\u76f4\u63a5\u6307\u5411\u8be5\u6a21\u5757\u5168\u5c40\u540d\u79f0\u6240\u5728\u7684\u4e2d\u95f4\u4f5c\u7528\u57df\u3002 \u5982\u679c\u8981\u91cd\u65b0\u7ed1\u5b9a\u5728\u6700\u5185\u5c42\u4f5c\u7528\u57df\u4ee5\u5916\u7684\u53d8\u91cf\uff0c\u53ef\u4ee5\u4f7f\u7528 nonlocal \u8bed\u53e5\u58f0\u660e\u4e3a\u975e\u672c\u5730\u53d8\u91cf\u3002 \u5982\u679c\u6ca1\u6709\u88ab\u58f0\u660e\u4e3a\u975e\u672c\u5730\u53d8\u91cf\uff0c\u8fd9\u4e9b\u53d8\u91cf\u5c06\u662f\u53ea\u8bfb\u7684\u3002\u7ed9\u8fd9\u6837\u7684\u53d8\u91cf\u8d4b\u65b0\u503c\u53ea\u4f1a\u5728\u6700\u5185\u5c42\u4f5c\u7528\u57df\u4e2d\u521b\u5efa\u4e00\u4e2a*\u65b0\u7684*\u5c40\u90e8\u53d8\u91cf\uff0c\u800c\u540c\u540d\u7684\u5916\u90e8\u5168\u5c40\u53d8\u91cf\u5c06\u4fdd\u6301\u4e0d\u53d8\u3002 \u901a\u5e38\uff0c\u5f53\u524d\u5c40\u90e8\u4f5c\u7528\u57df\uff08local scope\uff09\u5c06\u5f15\u7528\u5f53\u524d\u51fd\u6570\u4f5c\u7528\u57df\u7684\u540d\u79f0\uff08local name\uff09\u3002 \u5728\u51fd\u6570\u4f5c\u7528\u57df\u4ee5\u5916\uff0c\u5f53\u524d\u5c40\u90e8\u4f5c\u7528\u57df\u5c06\u5f15\u7528\u4e0e\u5168\u5c40\u4f5c\u7528\u57df\u76f8\u4e00\u81f4\u7684\u547d\u540d\u7a7a\u95f4\uff1a\u6a21\u5757\u7684\u547d\u540d\u7a7a\u95f4\uff08the module\u2019s namespace\uff09\u3002 \u5b9a\u4e49\u4e00\u4e2a\u7c7b\uff0c\u662f\u5728\u672c\u5730\u5c40\u90e8\u547d\u540d\u7a7a\u95f4\u5185\u5efa\u4e00\u4e2a\u65b0\u7684\u547d\u540d\u7a7a\u95f4\u3002 \u5728\u4e00\u4e2a\u6a21\u5757\uff08module \uff09\u5185\u5b9a\u4e49\u7684\u51fd\u6570\u7684\u4f5c\u7528\u57df\u5c31\u662f\u8be5\u6a21\u5757\u7684\u547d\u540d\u7a7a\u95f4\uff0c\u65e0\u8bba\u8be5\u51fd\u6570\u4ece\u4ec0\u4e48\u5730\u65b9\u6216\u4ee5\u4ec0\u4e48\u522b\u540d\u88ab\u8c03\u7528\u3002 \u53e6\u4e00\u65b9\u9762\uff0c\u5b9e\u9645\u7684\u540d\u79f0\u641c\u7d22\u662f\u5728\u8fd0\u884c\u65f6\u52a8\u6001\u5b8c\u6210\u7684\u3002 \u4f46\u662f\uff0cPython\u6b63\u5728\u671d\u7740\u201c\u7f16\u8bd1\u65f6\u9759\u6001\u540d\u79f0\u89e3\u6790\u201d\u7684\u65b9\u5411\u53d1\u5c55\uff0c\u56e0\u6b64\u4e0d\u8981\u8fc7\u4e8e\u4f9d\u8d56\u52a8\u6001\u540d\u79f0\u89e3\u6790\uff01\u4e8b\u5b9e\u4e0a\uff0c\u5c40\u90e8\u53d8\u91cf\u5df2\u7ecf\u662f\u88ab\u9759\u6001\u786e\u5b9a\u4e86\u3002 \u5982\u679c\u4e0d\u5b58\u5728\u751f\u6548\u7684 global \u6216 nonlocal \u8bed\u53e5\uff0c\u5219\u5bf9\u540d\u79f0\u7684\u8d4b\u503c\u603b\u662f\u4f1a\u8fdb\u5165\u6700\u5185\u5c42\u4f5c\u7528\u57df\u3002\u8d4b\u503c\u4e0d\u4f1a\u590d\u5236\u6570\u636e\uff0c\u662f\u5c06\u540d\u79f0\u7ed1\u5b9a\u5230\u5bf9\u8c61\u3002 \u5220\u9664\u4e5f\u662f\u5982\u6b64\uff1a\u8bed\u53e5 del x \u4f1a\u4ece\u5c40\u90e8\u4f5c\u7528\u57df\u6240\u5f15\u7528\u7684\u547d\u540d\u7a7a\u95f4\u4e2d\u79fb\u9664\u5bf9 x \u7684\u7ed1\u5b9a\u3002\u4e8b\u5b9e\u4e0a\uff0c\u6240\u6709\u5f15\u5165\u65b0\u540d\u79f0\u7684\u64cd\u4f5c\u90fd\u662f\u4f7f\u7528\u5c40\u90e8\u4f5c\u7528\u57df\u3002\u7279\u522b\u5730\uff0c import \u8bed\u53e5\u548c\u51fd\u6570\u5b9a\u4e49\u4f1a\u5728\u5c40\u90e8\u4f5c\u7528\u57df\u4e2d\u7ed1\u5b9a\u6a21\u5757\u6216\u51fd\u6570\u540d\u79f0\u3002 global \u8bed\u53e5\u53ef\u88ab\u7528\u6765\u8868\u660e\u7279\u5b9a\u53d8\u91cf\u5b58\u5728\u4e8e\u5168\u5c40\u4f5c\u7528\u57df\uff0c\u5e76\u4e14\u5e94\u5f53\u5728\u5168\u5c40\u4f5c\u7528\u57df\u4e2d\u88ab**\u91cd\u65b0**\u7ed1\u5b9a\uff1b nonlocal \u8bed\u53e5\u8868\u660e\u7279\u5b9a\u53d8\u91cf\u751f\u5b58\u4e8e\u5916\u5c42\u4f5c\u7528\u57df\u4e2d\uff0c\u5e76\u4e14\u5e94\u5f53\u5728\u5176\u6240\u5904\u7684\u5916\u5c42\u4f5c\u7528\u57df\u4e2d\u88ab**\u91cd\u65b0**\u7ed1\u5b9a\u3002 \u770b\u4e0b\u9762\u7684\u4f8b\u5b50\uff1a \u5c40\u90e8\u8d4b\u503c\uff08local assignment\uff0c\u8fd9\u662f\u9ed8\u8ba4\u72b6\u6001\uff09\u4e0d\u4f1a\u6539\u53d8 scope_test \u5bf9 spam \u7684\u7ed1\u5b9a\u3002 nonlocal \u8d4b\u503c\u4f1a\u6539\u53d8 scope_test \u5bf9 spam \u7684\u7ed1\u5b9a\u3002 global \u8d4b\u503c\u4f1a\u6539\u53d8\u6a21\u5757\u5c42\u7ea7\u7684\u7ed1\u5b9a\uff0c\u5373\uff0c global spam \u91cd\u65b0\u7ed1\u5b9a\u4e86spam\u7684\u5168\u5c40\u5b9a\u4e49\uff0c\u4ece spam = \"spam out of func\" \u53d8\u6210\u4e86 spam = \"global spam\" \u3002\u5982\u679c\u6ce8\u91ca\u6389def do_global()\u8fd9\u4e00\u6bb5\u4ee3\u7801\uff0c\u5219 spam = \"spam out of func\" \u8d77\u4f5c\u7528\u3002 spam = \"spam out of func\" def scope_test (): def do_local (): spam = \"local spam\" def do_nonlocal (): nonlocal spam spam = \"nonlocal spam\" def do_global (): global spam spam = \"global spam\" spam = \"test spam\" do_local () print ( \"After local assignment:\" , spam ) do_nonlocal () print ( \"After nonlocal assignment:\" , spam ) do_global () print ( \"After global assignment:\" , spam ) scope_test () print ( \"In global scope:\" , spam ) # \u8fd0\u884c\u7ed3\u679c # scope_test() After local assignment : test spam After nonlocal assignment : nonlocal spam After global assignment : nonlocal spam # print(\"In global scope:\", spam) In global scope : global spam \u7c7bClass \u00b6 \u7c7b\u5b9a\u4e49 Class Definition \u00b6 \u7c7b\u5b9a\u4e49\u4e0e\u51fd\u6570\u5b9a\u4e49 (def \u8bed\u53e5) \u4e00\u6837\u5fc5\u987b\u88ab\u6267\u884c\u624d\u4f1a\u8d77\u4f5c\u7528\u3002 class ClassName : < statement - 1 > ... < statement - N > \u5728\u5b9e\u8df5\u4e2d\uff0c\u7c7b\u5b9a\u4e49\u5185\u7684\u8bed\u53e5\u901a\u5e38\u90fd\u662f\u51fd\u6570\u5b9a\u4e49\uff0c\u4f46\u4e5f\u5141\u8bb8\u6709\u5176\u4ed6\u8bed\u53e5\u3002\u5728\u7c7b\u5185\u90e8\u7684\u51fd\u6570\u5b9a\u4e49\u901a\u5e38\u5177\u6709\u4e00\u79cd\u7279\u6709\u5f62\u5f0f\u7684\u53c2\u6570\u5217\u8868\uff0c\u8fd9\u662f\u7ea6\u5b9a\u7684\u65b9\u6cd5\u89c4\u8303\uff08conventions for methods\uff09\u3002 \u7f16\u8bd1\u8fc7\u7a0b\u4e2d\uff0c\u8fdb\u5165\u4e00\u4e2a\u7c7b\u7684\u5185\u90e8\uff0c\u5c06\u521b\u5efa\u4e00\u4e2a\u65b0\u7684\u547d\u540d\u7a7a\u95f4\uff0c\u4e00\u4e2a\u5c40\u90e8\u4f5c\u7528\u57df\u3002\u56e0\u6b64\uff0c\u6240\u6709\u5bf9\u7c7b\u5185\u90e8\u5c40\u90e8\u53d8\u91cf\u7684\u8d4b\u503c\u90fd\u662f\u5728\u8fd9\u4e2a\u65b0\u7684\u547d\u540d\u7a7a\u95f4\u4e4b\u5185\uff0c\u5305\u62ec\u65b0\u5b9a\u4e49\u7684\u51fd\u6570\u540d\u79f0\u3002 \u5f53\u6b63\u5e38\u79bb\u5f00\u4e00\u4e2a\u7c7b\u65f6\uff0c\u7f16\u8bd1\u8fc7\u7a0b\u5c06\u521b\u5efa\u4e00\u4e2a\u7c7b\u5bf9\u8c61\uff08class object\uff09\uff0c\u5c01\u88c5\u4e86\u7c7b\u5b9a\u4e49\u6240\u521b\u5efa\u7684\u547d\u540d\u7a7a\u95f4\u91cc\u7684\u5185\u5bb9\u3002 \u6700\u521d\u7684\uff08\u5728\u8fdb\u5165\u7c7b\u5b9a\u4e49\u4e4b\u524d\u8d77\u4f5c\u7528\u7684\uff09\u5c40\u90e8\u4f5c\u7528\u57df\u5c06\u91cd\u65b0\u751f\u6548\uff0c\u7c7b\u5bf9\u8c61\uff08class object\uff09\u5c06\u5728\u8fd9\u91cc\u88ab\u7ed1\u5b9a\u5230\u7c7b\u5b9a\u4e49\u5934\u90e8\u6240\u58f0\u660e\u7684\u7c7b\u540d\u79f0 (\u5728\u4e0a\u9762\u7684\u793a\u4f8b\u4e2d\u662f ClassName )\u3002 \u7c7b\u5bf9\u8c61 Class Objects \u00b6 \u7c7b\u5bf9\u8c61\u652f\u6301\u4e24\u79cd\u64cd\u4f5c\uff1a\u5c5e\u6027\u5f15\u7528\uff08attribute references\uff09\u548c\u5b9e\u4f8b\u5316\uff08instantiation\uff09\u3002 \u5c5e\u6027\u5f15\u7528\uff08attribute references\uff09 \u4f7f\u7528Python\u4e2d\u5c5e\u6027\u5f15\u7528\u7684\u6807\u51c6\u8bed\u6cd5: obj.name \u3002 \u5b58\u5728\u4e8e\u7c7b\u547d\u540d\u7a7a\u95f4\u4e2d\u7684\u6240\u6709\u540d\u79f0\uff0c\u7c7b\u5bf9\u8c61\u88ab\u521b\u5efa\u65f6\u540c\u65f6\u88ab\u521b\u5efa\u4e86\uff0c\u8fd9\u4e9b\u5c31\u662f\u6709\u6548\u7684\u5c5e\u6027\u540d\u79f0\u3002\u56e0\u6b64\uff0c\u5982\u679c\u7c7b\u5b9a\u4e49\u662f\u5982\u4e0b\u6240\u793a\uff0c\u90a3\u4e48 MyClass.i \u548c MyClass.f \u5c31\u662f\u6709\u6548\u7684\u5c5e\u6027\u5f15\u7528\uff0c\u5c06\u5206\u522b\u8fd4\u56de\u4e00\u4e2a\u6574\u6570\u548c\u4e00\u4e2a\u51fd\u6570\u5bf9\u8c61\u3002 \u7c7b\u5c5e\u6027\u4e5f\u53ef\u4ee5\u88ab\u8d4b\u503c\uff0c\u56e0\u6b64\u53ef\u4ee5\u901a\u8fc7\u8d4b\u503c\u6765\u66f4\u6539 MyClass.i \u7684\u503c\u3002 __doc__ \u4e5f\u662f\u4e00\u4e2a\u6709\u6548\u7684\u5c5e\u6027\uff0c\u5c06\u8fd4\u56de\u6240\u5c5e\u7c7b\u7684\u6587\u6863\u5b57\u7b26\u4e32: \"A simple example class\"\u3002 class MyClass : \"\"\"A simple example class\"\"\" i = 12345 def f ( self ): return 'hello world' print ( MyClass . i ) # 12345 print ( MyClass . __doc__ ) # A simple example class MyClass . i = 10 print ( MyClass . i ) # 10 \u7c7b\u7684**\u5b9e\u4f8b\u5316\uff08instantiation\uff09**\u4f7f\u7528\u51fd\u6570\u8868\u793a\u6cd5\u3002 \u53ef\u4ee5\u628a\u7c7b\u5bf9\u8c61\uff08class object\uff09\u770b\u4f5c\u662f\u4e00\u4e2a\u4e0d\u5e26\u53c2\u6570\u7684\u51fd\u6570\uff0c\u8fd9\u4e2a\u51fd\u6570\u8fd4\u56de\u4e86\u8be5\u7c7b\u7684\u4e00\u4e2a\u65b0\u5b9e\u4f8b\u3002 \u5728\u4e0b\u9762\u7684\u4f8b\u5b50\u4e2d\uff0c x = MyClass() \u521b\u5efa\u4e86 MyClass() \u8fd9\u4e2a\u7c7b\u7684\u4e00\u4e2a\u5b9e\u4f8b\uff0c\u5e76\u8d4b\u503c\u7ed9\u5c40\u90e8\u53d8\u91cf x \u3002 \u5b9e\u4f8b\u5316\u64cd\u4f5c\uff08\u8c03\u7528\u7c7b\u5bf9\u8c61\uff09\u4f1a\u521b\u5efa\u4e00\u4e2a\u7a7a\u5bf9\u8c61\u3002\u8bb8\u591a\u7c7b\u4f1a\u521b\u5efa\u5e26\u6709\u7279\u5b9a\u521d\u59cb\u72b6\u6001\u7684\u81ea\u5b9a\u4e49\u5b9e\u4f8b\u3002\u4e3a\u6b64\u7c7b\u5b9a\u4e49\u4e2d\u9700\u8981\u5305\u542b\u4e00\u4e2a\u540d\u4e3a __init__() \u7684\u7279\u6b8a\u65b9\u6cd5\u3002 \u5f53\u4e00\u4e2a\u7c7b\u5b9a\u4e49\u4e86 __init__() \u65b9\u6cd5\u65f6\uff0c\u7c7b\u7684\u5b9e\u4f8b\u5316\u64cd\u4f5c\u4f1a\u81ea\u52a8\u4e3a\u65b0\u521b\u5efa\u7684\u7c7b\u5b9e\u4f8b\u8c03\u7528 __init__() \u3002 \u66f4\u65b0\u4e0a\u9762\u7684\u4f8b\u5b50\uff0c\u6ce8\u610f __dict__ \u4e24\u6b21\u8fd4\u56de\u7684\u4e0d\u540c\u7684\u5b57\u5178\u3002\u590d\u4e60\u4e00\u4e0b\uff0c\u5728\u547d\u540d\u7a7a\u95f4\u4e2d\u63d0\u5230\uff0c __dict__ \u662f\u5c5e\u6027\u4f46\u4e0d\u662f\u5168\u5c40\u540d\u79f0\uff0c\u8fd4\u56de\u7528\u4e8e\u5b9e\u73b0\u6a21\u5757\u547d\u540d\u7a7a\u95f4\u7684\u5b57\u5178\u3002 class MyClass : \"\"\"A simple example class\"\"\" i = 12345 def f ( self ): return 'hello world' def __init__ ( self ): self . data = [] x = MyClass () print ( x . __dict__ ) # {'data': []} x . i = 10 print ( x . __dict__ ) # {'data': [], 'i': 10} __init__() \u65b9\u6cd5\u53ef\u4ee5\u6709\u989d\u5916\u7684\u53c2\u6570\u8f93\u5165\uff0c\u5728\u8fd9\u79cd\u60c5\u51b5\u4e0b\uff0c\u7c7b\u5b9e\u4f8b\u5316\u7684\u53c2\u6570\u5c06\u88ab\u4f20\u9012\u7ed9 __init__() \u3002 \u5982\u4e0b\u4f8b: class Complex : def __init__ ( self , realpart , imagpart ): self . r = realpart self . i = imagpart x = Complex ( 3.0 , - 4.5 ) print ( x . r , x . i ) # 3.0 -4.5 \u5b9e\u4f8b\u5bf9\u8c61 Instance Objects \u00b6 \u5bf9\u5b9e\u4f8b\u5bf9\u8c61\u552f\u4e00\u7684\u64cd\u4f5c\u662f\u5c5e\u6027\u5f15\u7528\u3002\u6709\u4e24\u79cd\u6709\u6548\u7684\u5c5e\u6027\u540d\u79f0\uff1a\u6570\u636e\u5c5e\u6027\uff08data attributes\uff09\u548c\u65b9\u6cd5\uff08methods\uff09\u3002 **\u6570\u636e\u5c5e\u6027\uff08data attributes\uff09**\u7c7b\u4f3c\u4e8e\u5b9e\u4f8b\u53d8\u91cf\uff0c\u6570\u636e\u5c5e\u6027\u4e0d\u9700\u8981\u58f0\u660e\u3002\u50cf\u5c40\u90e8\u53d8\u91cf\u4e00\u6837\uff0c\u6570\u636e\u5c5e\u6027\u5c06\u5728\u7b2c\u4e00\u6b21\u88ab\u8d4b\u503c\u65f6\u4ea7\u751f\u3002 \u4f8b\u5982\uff0c\u5982\u679c x \u662f\u4e0a\u9762\u521b\u5efa\u7684 MyClass \u7684\u5b9e\u4f8b\uff0c\u5219\u4ee5\u4e0b\u4ee3\u7801\u6bb5\u5c06\u6253\u5370\u6570\u503c 16 \uff0c\u4e14\u6ca1\u6709\u7559\u4e0b\u5173\u4e8e x.counter \u7684\u75d5\u8ff9\u3002 class MyClass : \"\"\"A simple example class\"\"\" i = 12345 def f ( self ): return 'hello world' def __init__ ( self ): self . data = [] x = MyClass () x . counter = 1 while x . counter < 10 : x . counter = x . counter * 2 print ( x . counter ) # 16 print ( x . __dict__ ) # {'data': [], 'counter': 16} del x . counter print ( x . __dict__ ) # {'data': []} \u53e6\u4e00\u7c7b\u5b9e\u4f8b\u5c5e\u6027\u5f15\u7528\u79f0\u4e3a**\u65b9\u6cd5\uff08methods\uff09 \u3002 \u65b9\u6cd5\u662f\u96b6\u5c5e\u4e8e\u5bf9\u8c61\u7684**\u51fd\u6570 \u3002 \u5728Python\u4e2d\uff0c\u65b9\u6cd5\u8fd9\u4e2a\u672f\u8bed\u5e76\u4e0d\u662f\u7c7b\u5b9e\u4f8b\u6240\u7279\u6709\u7684\uff0c\u5176\u4ed6\u5bf9\u8c61\u4e5f\u53ef\u4ee5\u6709\u65b9\u6cd5\u3002 \u4f8b\u5982\uff0c\u5217\u8868\u5bf9\u8c61\uff08list objects\uff09\u5177\u6709append, insert, remove, sort\u7b49\u65b9\u6cd5\u3002 \u5728\u4ee5\u4e0b\u8ba8\u8bba\u4e2d\uff0c\u6211\u4eec\u4f7f\u7528\u65b9\u6cd5\u4e00\u8bcd\u5c06\u4e13\u6307\u7c7b\u5b9e\u4f8b\u5bf9\u8c61\u7684\u65b9\u6cd5\uff0c\u9664\u975e\u53e6\u5916\u660e\u786e\u8bf4\u660e\u3002 \u5b9e\u4f8b\u5bf9\u8c61\u7684\u6709\u6548\u65b9\u6cd5\u540d\u79f0\u4f9d\u8d56\u4e8e\u5176\u6240\u5c5e\u7684\u7c7b\u3002 \u6839\u636e\u5b9a\u4e49\uff0c\u4e00\u4e2a\u7c7b\u5b9a\u4e49\u4e2d\u6240\u5305\u542b\u7684\u6240\u6709\u51fd\u6570\u5bf9\u8c61\uff08function objects\uff09\u90fd\u79f0\u4e3a\u5c5e\u6027\u3002 \u56e0\u6b64\u5728\u4e0a\u9762\u7684\u793a\u4f8b\u4e2d\uff0c x.f \u662f\u6709\u6548\u7684\u65b9\u6cd5\u5f15\u7528\uff0c\u56e0\u4e3a MyClass.f \u662f\u4e00\u4e2a\u51fd\u6570\uff0c\u800c x.i \u4e0d\u662f\u65b9\u6cd5\uff0c\u56e0\u4e3a MyClass.i \u4e0d\u662f\u51fd\u6570\u3002\u4f46\u662f x.f \u4e0e MyClass.f \u5e76\u4e0d\u662f\u4e00\u56de\u4e8b\uff0c x.f \u662f\u4e00\u4e2a**\u65b9\u6cd5\u5bf9\u8c61**\uff0c\u800c MyClass.f \u662f\u4e00\u4e2a**\u51fd\u6570\u5bf9\u8c61**\u3002\u5dee\u522b\u5728\u4e8e f() \u662f\u5426\u4e0e\u5b9e\u4f8b\u7ed1\u5b9a\uff0c\u672a\u7ed1\u5b9a\uff0c\u5c31\u662f\u51fd\u6570\uff0c\u7ed1\u5b9a\uff0c\u5c31\u662f\u65b9\u6cd5\u3002 class MyClass : \"\"\"A simple example class\"\"\" i = 12345 def f ( self ): return 'hello world' def __init__ ( self ): self . data = [] x = MyClass () print ( MyClass . f ( 0 )) # hello world print ( x . f ()) # hello world print ( MyClass . f ) # print ( x . f ) # > print ( type ( MyClass . f )) # print ( type ( x . f )) # \u8fd9\u91cc\u505a\u4e2a\u5c0f\u7ed3\uff1a \u51fd\u6570(function)\u662fPython\u4e2d\u4e00\u4e2a\u53ef\u8c03\u7528\u5bf9\u8c61(callable), \u65b9\u6cd5(method)\u662f\u4e00\u79cd\u7279\u6b8a\u7684\u51fd\u6570\u3002 \u4e00\u4e2a\u53ef\u8c03\u7528\u5bf9\u8c61\u662f\u65b9\u6cd5\u548c\u51fd\u6570\uff0c\u548c\u8fd9\u4e2a\u5bf9\u8c61\u65e0\u5173\uff0c\u4ec5\u548c\u8fd9\u4e2a\u5bf9\u8c61\u662f\u5426\u4e0e\u7c7b\u6216\u5b9e\u4f8b\u7ed1\u5b9a\u6709\u5173\uff08bound method\uff09\u3002 \u9759\u6001\u65b9\u6cd5\u6ca1\u6709\u548c\u4efb\u4f55\u7c7b\u6216\u5b9e\u4f8b\u7ed1\u5b9a\uff0c\u6240\u4ee5**\u9759\u6001\u65b9\u6cd5\u662f\u4e2a\u51fd\u6570**\u3002 \u65b9\u6cd5\u5bf9\u8c61 Method Objects \u00b6 \u5728 MyClass \u793a\u4f8b\u4e2d\uff0c x.f() \u662f\u4e00\u4e2a\u65b9\u6cd5\u5bf9\u8c61\uff0c\u88ab\u8c03\u7528\u540e\uff0c\u5c06\u8fd4\u56de\u5b57\u7b26\u4e32 'hello world' \u3002\u53ef\u4ee5\u7acb\u5373\u8c03\u7528\uff0c\u4e5f\u53ef\u4ee5\u4fdd\u5b58\u8d77\u6765\u4ee5\u540e\u518d\u8c03\u7528 xf = x.f \u3002 \u867d\u7136 f() \u7684\u51fd\u6570\u5b9a\u4e49\u6307\u5b9a\u4e86\u4e00\u4e2a\u53c2\u6570\uff0c\u4f46\u4e0a\u9762\u4f8b\u5b50\u4e2d\u8c03\u7528 x.f() \u65f6\u5e76\u6ca1\u6709\u5e26\u53c2\u6570\uff0c\u4e5f\u6ca1\u6709\u5f15\u53d1\u5f02\u5e38\u62a5\u9519\u3002\u539f\u56e0\u5728\u4e8e\uff0c \u65b9\u6cd5(method)\u7684\u7279\u6b8a\u4e4b\u5904\u5c31\u5728\u4e8e\u5b9e\u4f8b\u5bf9\u8c61\u4f1a\u4f5c\u4e3a\u51fd\u6570\u7684\u7b2c\u4e00\u4e2a\u53c2\u6570\u88ab\u4f20\u5165\u3002 \u8c03\u7528 x.f() \u5176\u5b9e\u5c31\u76f8\u5f53\u4e8e MyClass.f(x) \u3002 \u603b\u4e4b\uff0c\u8c03\u7528\u4e00\u4e2a\u5177\u6709 n \u4e2a\u53c2\u6570\u7684\u65b9\u6cd5(method)\u5c31\u76f8\u5f53\u4e8e\u8c03\u7528\u518d\u591a\u4e00\u4e2a\u53c2\u6570\u7684\u5bf9\u5e94\u51fd\u6570\uff0c\u8fd9\u4e2a\u53c2\u6570\u503c\u4e3a\u65b9\u6cd5\u6240\u5c5e\u5b9e\u4f8b\u5bf9\u8c61\uff0c \u4f4d\u7f6e\u5728\u5176\u4ed6\u53c2\u6570\u4e4b\u524d \u3002 \u5f53\u4e00\u4e2a\u5b9e\u4f8b\u7684\u975e\u6570\u636e\u5c5e\u6027\u88ab\u5f15\u7528\u65f6\uff0c\u5c06\u641c\u7d22\u5b9e\u4f8b\u6240\u5c5e\u7684\u7c7b\u3002 \u5982\u679c\u88ab\u5f15\u7528\u7684\u5c5e\u6027\u540d\u79f0\u662f\u7c7b\u4e2d\u4e00\u4e2a\u6709\u6548\u7684\u51fd\u6570\u5bf9\u8c61\uff0c\u5219\u4f1a\u521b\u5efa\u4e00\u4e2a\u62bd\u8c61\u7684\u5bf9\u8c61\uff0c\u901a\u8fc7\u6253\u5305\uff08parking\uff0c\u5373\u6307\u5411\uff09\u5339\u914d\u5230\u7684\u5b9e\u4f8b\u5bf9\u8c61\u548c\u51fd\u6570\u5bf9\u8c61\uff0c\u8fd9\u4e2a\u62bd\u8c61\u5bf9\u8c61\u5c31\u662f\u65b9\u6cd5\u5bf9\u8c61\u3002 \u5f53\u5e26\u53c2\u6570\u8c03\u7528\u65b9\u6cd5\u5bf9\u8c61\u65f6\uff0c\u5c06\u57fa\u4e8e\u5b9e\u4f8b\u5bf9\u8c61\u548c\u53c2\u6570\u5217\u8868\u6784\u5efa\u4e00\u4e2a\u65b0\u7684\u53c2\u6570\u5217\u8868\uff0c\u5e76\u4f7f\u7528\u8fd9\u4e2a\u65b0\u53c2\u6570\u5217\u8868\u8c03\u7528\u76f8\u5e94\u7684\u51fd\u6570\u5bf9\u8c61\u3002 \u7c7b\u548c\u5b9e\u4f8b\u53d8\u91cf Class and Instance Variables \u00b6 \u4e00\u822c\u6765\u8bf4\uff0c**\u5b9e\u4f8b\u53d8\u91cf**\u7528\u4e8e\u6bcf\u4e2a\u5b9e\u4f8b\u7684\u552f\u4e00\u6570\u636e\uff0c\u800c**\u7c7b\u53d8\u91cf**\u7528\u4e8e\u7c7b\u7684\u6240\u6709\u5b9e\u4f8b\u5171\u4eab\u7684\u5c5e\u6027\u548c\u65b9\u6cd5: class Dog : kind = 'canine' # class variable shared by all instances def __init__ ( self , name ): self . name = name # instance variable unique to each instance d = Dog ( 'Fido' ) e = Dog ( 'Buddy' ) print ( d . kind ) # shared by all dogs # 'canine' print ( e . kind ) # shared by all dogs # 'canine' print ( d . name ) # unique to d instance # 'Fido' print ( e . name ) # unique to e instance # 'Buddy' \u4e0b\u4ee3\u7801\u4e2d\u7684 tricks \u5217\u8868\u4e0d\u5e94\u8be5\u88ab\u7528\u4f5c\u7c7b\u53d8\u91cf\uff0c\u56e0\u4e3a\u6240\u6709\u7684 Dog \u5b9e\u4f8b\u5c06\u53ea\u5171\u4eab\u4e00\u4e2a\u5355\u72ec\u7684\u5217\u8868: class Dog : kind = 'canine' # class variable shared by all instances tricks = [] # mistaken use of a class variable def __init__ ( self , name ): self . name = name # instance variable unique to each instance def add_trick ( self , trick ): self . tricks . append ( trick ) d = Dog ( 'Fido' ) e = Dog ( 'Buddy' ) d . add_trick ( 'roll over' ) e . add_trick ( 'play dead' ) print ( d . tricks ) # ['roll over', 'play dead'] \u6b63\u786e\u7684\u7c7b\u8bbe\u8ba1\u5e94\u8be5\u4f7f\u7528\u5b9e\u4f8b\u53d8\u91cf: class Dog : kind = 'canine' # class variable shared by all instances def __init__ ( self , name ): self . name = name # instance variable unique to each instance self . tricks = [] # creates a new empty list for each dog def add_trick ( self , trick ): self . tricks . append ( trick ) d = Dog ( 'Fido' ) e = Dog ( 'Buddy' ) d . add_trick ( 'roll over' ) e . add_trick ( 'play dead' ) print ( d . tricks ) # ['roll over'] print ( e . tricks ) # ['play dead'] \u5982\u679c\u540c\u6837\u7684\u5c5e\u6027\u540d\u79f0\u540c\u65f6\u51fa\u73b0\u5728\u5b9e\u4f8b\u548c\u7c7b\u4e2d\uff0c\u5219\u5c5e\u6027\u67e5\u627e\u4f1a**\u4f18\u5148\u9009\u62e9\u5b9e\u4f8b**: class Warehouse : purpose = 'storage' region = 'west' w1 = Warehouse () print ( w1 . purpose , w1 . region ) # storage west w2 = Warehouse () w2 . region = 'east' # Instance W2 has higher priority than class print ( w2 . purpose , w2 . region ) # storage east \u6570\u636e\u5c5e\u6027\uff08Data attributes\uff09\u53ef\u4ee5\u88ab\u65b9\u6cd5\uff08method\uff09\u4ee5\u53ca\u4e00\u4e2a\u5bf9\u8c61\u7684\u666e\u901a\u7528\u6237\uff08ordinary users\uff09\uff08\u201c\u5ba2\u6237\u7aefClient\u201d\uff09\u6240\u5f15\u7528\u3002 \u6362\u53e5\u8bdd\u8bf4\uff0c\u7c7b\u4e0d\u80fd\u7528\u4e8e\u5b9e\u73b0\u7eaf\u62bd\u8c61\u6570\u636e\u7c7b\u578b\u3002 \u65b9\u6cd5\u7684\u7b2c\u4e00\u4e2a\u53c2\u6570\u5e38\u5e38\u88ab\u547d\u540d\u4e3a self \uff0c\u8fd9\u53ea\u662f\u4e00\u4e2a\u7ea6\u5b9a: self \u8fd9\u4e00\u540d\u79f0\u5728Python\u4e2d\u6ca1\u6709\u7279\u6b8a\u542b\u4e49\u3002 \u4f46\u662f\u9075\u5faa\u6b64\u7ea6\u5b9a\u4f1a\u4f7f\u5f97\u4ee3\u7801\u5177\u6709\u5f88\u597d\u7684\u53ef\u8bfb\u6027\u3002 \u4efb\u4f55\u4e00\u4e2a\u4f5c\u4e3a\u7c7b\u5c5e\u6027\uff08class attribute\uff09\u7684\u51fd\u6570\u5bf9\u8c61\uff08function object\uff09\u90fd\u4e3a\u8be5\u7c7b\u7684\u5b9e\u4f8b\u5b9a\u4e49\u4e86\u4e00\u4e2a\u76f8\u5e94\u65b9\u6cd5\u3002 \u51fd\u6570\u5b9a\u4e49\u7684\u6587\u672c\u5e76\u975e\u5fc5\u987b\u5305\u542b\u4e8e\u7c7b\u5b9a\u4e49\u4e4b\u5185\uff1a\u5c06\u4e00\u4e2a\u51fd\u6570\u5bf9\u8c61\u8d4b\u503c\u7ed9\u4e00\u4e2a\u5c40\u90e8\u53d8\u91cf\u4e5f\u662f\u53ef\u4ee5\u7684\u3002\u5982\u4e0b\u4f8b\u3002\u73b0\u5728 f , g \u548c h \u90fd\u662f\u7c7b C \u7684\u5f15\u7528\u51fd\u6570\u5bf9\u8c61\u7684\u5c5e\u6027\uff0c\u56e0\u800c\u5b83\u4eec\u5c31\u90fd\u662f\u7c7b C \u7684\u5b9e\u4f8b\u7684\u65b9\u6cd5\uff0c\u5176\u4e2d h \u5b8c\u5168\u7b49\u540c\u4e8e g \u3002\u4f46\u8bf7\u6ce8\u610f\uff0c\u4e0b\u9762\u8fd9\u4e2a\u4f8b\u5b50\u7684\u53ef\u8bfb\u6027\u975e\u5e38\u4e0d\u597d\u3002 # Function defined outside the class def f1 ( self , x , y ): return min ( x , x + y ) class C : f = f1 # Assign a function object to a local variable in the class def g ( self ): return 'hello world' h = g \u65b9\u6cd5\uff08methods\uff09\u53ef\u4ee5\u901a\u8fc7\u4f7f\u7528 self \u53c2\u6570\u7684\u65b9\u6cd5\u5c5e\u6027\uff08method attributes\uff09\u8c03\u7528\u5176\u4ed6\u65b9\u6cd5\uff08method\uff09: class Bag : def __init__ ( self ): self . data = [] def add ( self , x ): self . data . append ( x ) def addtwice ( self , x ): self . add ( x ) self . add ( x ) \u65b9\u6cd5\u53ef\u4ee5\u901a\u8fc7\u4e0e\u666e\u901a\u51fd\u6570\u76f8\u540c\u7684\u65b9\u5f0f\u5f15\u7528\u5168\u5c40\u540d\u79f0\u3002 \u4e0e\u65b9\u6cd5\u76f8\u5173\u8054\u7684\u5168\u5c40\u4f5c\u7528\u57df\u5c31\u662f\u5305\u542b\u5176\u5b9a\u4e49\u7684\u6a21\u5757\u3002 \uff08\u7c7b\u6c38\u8fdc\u4e0d\u4f1a\u88ab\u4f5c\u4e3a\u5168\u5c40\u4f5c\u7528\u57df\u3002\uff09 \u867d\u7136\u6211\u4eec\u5f88\u5c11\u4f1a\u6709\u5145\u5206\u7684\u7406\u7531\u5728\u65b9\u6cd5\u4e2d\u4f7f\u7528\u5168\u5c40\u4f5c\u7528\u57df\uff0c\u4f46\u5168\u5c40\u4f5c\u7528\u57df\u5b58\u5728\u8bb8\u591a\u5408\u7406\u7684\u4f7f\u7528\u573a\u666f\uff1a\u4e3e\u4e2a\u4f8b\u5b50\uff0c\u5bfc\u5165\u5230\u5168\u5c40\u4f5c\u7528\u57df\u7684\u51fd\u6570\u548c\u6a21\u5757\u53ef\u4ee5\u88ab\u65b9\u6cd5\u6240\u4f7f\u7528\uff0c\u5728\u5176\u4e2d\u5b9a\u4e49\u7684\u51fd\u6570\u548c\u7c7b\u4e5f\u4e00\u6837\u3002 \u901a\u5e38\uff0c\u5305\u542b\u8be5\u65b9\u6cd5\u7684\u7c7b\u672c\u8eab\u662f\u5728\u5168\u5c40\u4f5c\u7528\u57df\u4e2d\u5b9a\u4e49\u7684\u3002 \u603b\u7ed3 \u00b6 \u7c7b\u5b9a\u4e49\u5c0f\u7ed3 \u00b6 \u4e00\u4e2a\u7c7b\u5b9a\u4e49\u7c7b\u6210\u5458\u5c5e\u6027\u548c\u6210\u5458\u65b9\u6cd5\u3002 \u4e00\u4e2a\u7c7b\u53ef\u4ee5\u5b9e\u4f8b\u5316\u591a\u4e2a\u5bf9\u8c61\uff0c\u6bcf\u4e2a\u5b9e\u4f8b\u5316\u5bf9\u8c61\u90fd\u662f\u72ec\u7acb\u7684\u3002 \u521b\u5efa\u7684\u7c7b\u5b9e\u4f8b\u5316\u5bf9\u8c61\uff0c\u4f1a\u5f15\u7528\u7236\u7c7b\u4e2d\u7684\u5c5e\u6027\u548c\u65b9\u6cd5\uff0c\u5e76\u4e0d\u4f1a\u628a\u7c7b\u7684\u5c5e\u6027\u548c\u65b9\u6cd5\u590d\u5236\u7ed9\u5bf9\u8c61\uff0c\u56e0\u6b64\uff1a \u5728\u8bbf\u95ee\u5b9e\u4f8b\u5316\u5bf9\u8c61\u7684\u5c5e\u6027\u548c\u65b9\u6cd5\u65f6\uff0c\u4f1a\u5148\u53bb\u627e\u5bf9\u8c61\u81ea\u5df1\u7684\u5c5e\u6027\u548c\u65b9\u6cd5\uff0c\u7136\u540e\u518d\u53bb\u5b9e\u4f8b\u5316\u8fd9\u4e2a\u5bf9\u8c61\u7684\u7c7b\u4e2d\u67e5\u627e\uff08\u5f15\u7528\uff09\u3002 \u5bf9\u8c61\u6210\u5458\u7684\u6dfb\u52a0\u548c\u4fee\u6539\uff0c\u90fd\u53ea\u4f1a\u5f71\u54cd\u5f53\u524d\u5bf9\u8c61\u81ea\u5df1\uff0c\u4e0d\u4f1a\u5f71\u54cd\u7c7b\u548c\u5176\u5b83\u5bf9\u8c61\u3002 \u5220\u9664\u5bf9\u8c61\u6210\u5458\u7684\u65f6\u5019\uff0c\u5fc5\u987b\u662f\u8be5\u5bf9\u8c61\u81ea\u5df1\u5177\u5907\u7684\u6210\u5458\u624d\u53ef\u4ee5\uff0c\u4e0d\u80fd\u5220\u9664\u7c7b\u4e2d\u5f15\u7528\u7684\u6210\u5458\u3002 \u5bf9\u7c7b\u6210\u5458\u7684\u64cd\u4f5c\uff0c\u4f1a\u5f71\u54cd\u8fd9\u4e2a\u7c7b\u521b\u5efa\u7684\u5bf9\u8c61\uff0c\u5305\u62ec\u4e4b\u524d\u521b\u5efa\u7684\u5bf9\u8c61\uff08\u5f15\u7528\uff09\u3002 \u7c7b\u6210\u5458\u64cd\u4f5c\uff08\u4e0d\u63a8\u8350\uff09 \u00b6 \u6210\u5458\u5c5e\u6027\uff1a \u8bbf\u95ee\uff1a ClassName.AttributeName \u4fee\u6539\uff1a ClassName.AttributeName = NewValue \uff0c\u7b49\u4e8e\u7ed9\u8fd9\u4e2a\u7c7b\u5bf9\u8c61\u521b\u5efa\u4e86\u4e00\u4e2a\u81ea\u5df1\u7684\u5c5e\u6027\uff0c\u901a\u8fc7\u8fd9\u4e2a\u7c7b\u521b\u5efa\u7684\u5bf9\u8c61\u90fd\u5177\u6709\u8fd9\u4e2a\u5c5e\u6027\u3002 \u6dfb\u52a0\uff1a ClassName.NewAttributeName = Value \uff0c\u7b49\u4e8e\u7ed9\u8fd9\u4e2a\u7c7b\u5bf9\u8c61\u521b\u5efa\u4e86\u4e00\u4e2a\u81ea\u5df1\u7684\u5c5e\u6027\uff0c\u901a\u8fc7\u8fd9\u4e2a\u7c7b\u521b\u5efa\u7684\u5bf9\u8c61\u90fd\u5177\u6709\u8fd9\u4e2a\u5c5e\u6027\u3002 \u5220\u9664\uff1a del ClassName.AttributeName \uff0c\u6ce8\u610f\uff0c\u53ea\u80fd\u5220\u9664\u7c7b\u5bf9\u8c61\u81ea\u5df1\u7684\u5c5e\u6027\uff0c\u901a\u8fc7\u8fd9\u4e2a\u7c7b\u521b\u5efa\u7684\u5bf9\u8c61\u90fd\u4e0d\u518d\u5177\u6709\u8fd9\u4e2a\u5c5e\u6027\u3002 \u6210\u5458\u65b9\u6cd5\uff1a \u8bbf\u95ee\uff1a ClassName.MethodName() \u4fee\u6539\uff1a ClassName.MethodName = NewFunction \uff0c\u7b49\u4e8e\u7ed9\u8fd9\u4e2a\u7c7b\u5bf9\u8c61\u521b\u5efa\u4e86\u4e00\u4e2a\u81ea\u5df1\u7684\u65b9\u6cd5\uff0c\u901a\u8fc7\u8fd9\u4e2a\u7c7b\u521b\u5efa\u7684\u5bf9\u8c61\u90fd\u5177\u6709\u8fd9\u4e2a\u65b9\u6cd5\u3002 \u6dfb\u52a0\uff1a ClassName.MethodName = Function \uff0c\u7b49\u4e8e\u7ed9\u8fd9\u4e2a\u7c7b\u5bf9\u8c61\u521b\u5efa\u4e86\u4e00\u4e2a\u81ea\u5df1\u7684\u65b9\u6cd5\uff0c\u901a\u8fc7\u8fd9\u4e2a\u7c7b\u521b\u5efa\u7684\u5bf9\u8c61\u90fd\u5177\u6709\u8fd9\u4e2a\u65b9\u6cd5\u3002 \u5220\u9664\uff1a del ClassName.MethodName \uff0c\u6ce8\u610f\uff0c\u53ea\u80fd\u5220\u9664\u7c7b\u5bf9\u8c61\u81ea\u5df1\u7684\u65b9\u6cd5\uff0c\u901a\u8fc7\u8fd9\u4e2a\u7c7b\u521b\u5efa\u7684\u5bf9\u8c61\u90fd\u4e0d\u518d\u5177\u6709\u8fd9\u4e2a\u65b9\u6cd5\u3002 \u6210\u5458\u65b9\u6cd5\u4e2d\u7684self \u00b6 self \u53ea\u662f\u4e00\u4e2a\u5f62\u53c2\uff0c\u4e0d\u662f\u5173\u952e\u5b57\u3002 self \u5728\u65b9\u6cd5\uff08method\uff09\u4ee3\u8868\u5f53\u524d\u5bf9\u8c61\u81ea\u5df1\u3002\u524d\u9762\u63d0\u5230\u8fc7\uff0c\u65b9\u6cd5\u7684\u7b2c\u4e00\u4e2a\u53c2\u6570\u5e38\u5e38\u88ab\u547d\u540d\u4e3a self \uff0c\u8fd9\u53ea\u662f\u4e00\u4e2a\u7ea6\u5b9a\u3002 \u53ef\u4ee5\u4f7f\u7528 self \u5728\u7c7b\u5185\u90e8\u64cd\u4f5c\u6210\u5458\uff08\u6dfb\u52a0\u3001\u4fee\u6539\u3001\u5220\u9664\u7b49\uff09\u3002 \u65b9\u6cd5\u7684\u5206\u7c7b\uff1a \u542b\u6709self\u6216\u8005\u53ef\u4ee5\u63a5\u53d7\u5bf9\u8c61\u4f5c\u4e3a\u53c2\u6570\u7684\u65b9\u6cd5\uff0c\u79f0\u4e3a**\u975e\u7ed1\u5b9a\u7c7b\u65b9\u6cd5**\uff0c\u975e\u7ed1\u5b9a\u7c7b\u7684\u65b9\u6cd5\u53ef\u4ee5\u4f7f\u7528\u5bf9\u8c61\u53bb\u8bbf\u95ee\u3002 \u4e0d\u542b\u6709self\u6216\u8005\u4e0d\u80fd\u63a5\u53d7\u5bf9\u8c61\u4f5c\u4e3a\u53c2\u6570\u7684\u65b9\u6cd5\uff0c\u79f0\u4e3a**\u7ed1\u5b9a\u7c7b\u65b9\u6cd5**\uff0c\u7ed1\u5b9a\u65b9\u6cd5\u53ea\u80fd\u4f7f\u7528\u7c7b\u53bb\u8bbf\u95ee\u3002 \u9b54\u672f\u65b9\u6cd5 \u00b6 \u9b54\u672f\u65b9\u6cd5\uff08Magic Method\uff09\u548c\u666e\u901a\u65b9\u6cd5\u4e00\u6837\uff0c\u90fd\u662f\u7c7b\u4e2d\u5b9a\u4e49\u7684\u6210\u5458\u65b9\u6cd5\u3002 \u9b54\u672f\u65b9\u6cd5\u540d\u79f0\u524d\u540e\u5404\u67092\u4e2a\u4e0b\u5212\u7ebf\uff0c\u6bd4\u5982 __init__ \u9b54\u672f\u65b9\u6cd5\u662f\u4e0d\u9700\u8981\u624b\u52a8\u8c03\u7528\u7684\uff0c\u4f1a\u5728\u67d0\u79cd\u60c5\u51b5\u4e0b\u81ea\u52a8\u89e6\u53d1\uff08\u81ea\u52a8\u6267\u884c\uff09\u3002 \u9b54\u672f\u65b9\u6cd5\u662f\u7cfb\u7edf\u5b9a\u4e49\u597d\u7684\uff0c\u4e0d\u662f\u7528\u6237\u5b9a\u4e49\u7684\u3002 __init__ \u521d\u59cb\u5316\u65b9\u6cd5\uff0c\u4e5f\u79f0\u4f5c**\u6784\u9020\u65b9\u6cd5** \u00b6 \u7c7b\u5b9e\u4f8b\u5316\u5bf9\u8c61\u521b\u5efa\u540e\u81ea\u52a8\u89e6\u53d1\u3002 __init__ \u521d\u59cb\u5316\u65b9\u6cd5\u53ef\u4ee5\u7528\u6765\u5728\u5bf9\u8c61\u5b9e\u4f8b\u5316\u540e\u5b8c\u6210\u5bf9\u8c61\u7684\u521d\u59cb\u5316\uff0c\u6bd4\u5982\u5c5e\u6027\u8d4b\u503c\uff0c\u65b9\u6cd5\u8c03\u7528\u7b49\u3002 __del__ \u6790\u6784\u65b9\u6cd5 \u00b6 \u7c7b\u5b9e\u4f8b\u5316\u5bf9\u8c61\u88ab\u9500\u6bc1\u65f6\u81ea\u52a8\u89e6\u53d1\u3002 __del__ \u6790\u6784\u65b9\u6cd5\u53ef\u4ee5\u5728\u9500\u6bc1\u5bf9\u8c61\u65f6\u5b8c\u6210\u4e00\u4e9b\u7279\u6b8a\u4efb\u52a1\uff0c\u5173\u95ed\u5bf9\u8c61\u6253\u5f00\u7684\u4e00\u4e9b\u8d44\u6e90\uff0c\u5982\u6587\u4ef6\u7b49\u3002 \u6ce8\u610f\uff0c\u662f\u5bf9\u8c61\u88ab\u9500\u6bc1\u65f6\u89e6\u53d1\u4e86\u6790\u6784\u65b9\u6cd5\uff0c\u800c\u4e0d\u662f\u8fd9\u4e2a\u6790\u6784\u65b9\u6cd5\u9500\u6bc1\u4e86\u5bf9\u8c61\u3002 \u5bf9\u8c61\u9500\u6bc1\u7684\u60c5\u51b5\uff1a \u5f53\u7a0b\u5e8f\u6267\u884c\u5b8c\u6bd5\uff0c\u9500\u6bc1\u548c\u91ca\u653e\u5185\u5b58\u4e2d\u7684\u8d44\u6e90\u3002 \u4f7f\u7528 del \u5220\u9664\u65f6\u3002 \u5bf9\u8c61\u4e0d\u518d\u88ab\u4efb\u4f55\u5bf9\u8c61\u5f15\u7528\u65f6\uff0c\u4f1a\u81ea\u52a8\u9500\u6bc1\u3002 \u770b\u4e0b\u9762\u7684\u4f8b\u5b50\uff0c\u5bf9\u6bd4 bmw = Car('BMW') \u548c Car('BMW') \u6765\u7406\u89e3 init \u548c del \u7684\u89e6\u53d1\u673a\u5236\u3002 \u7f16\u8f91\u6587\u4ef6 file1.py class Car (): brand = \"\" def __init__ ( self , car_brand ): self . brand = car_brand print ( f \"initial method called, create { self . brand } car\" ) def __del__ ( self ): print ( f \"delete method called, destroy { self . brand } car\" ) bmw = Car ( 'BMW' ) vw = Car ( 'VW' ) \u6267\u884c\u4e0a\u9762\u7684\u4ee3\u7801 python3 file1.py \u5f97\u5230\u5982\u4e0b\u8f93\u51fa\uff0c\u5728\u7a0b\u5e8f\u6267\u884c\u5b8c\u6bd5\u65f6\uff0c\u4f9d\u6b21\u6267\u884c __del__ \u3002 initial method called , create BMW car initial method called , create VW car delete method called , destroy BMW car delete method called , destroy VW car \u7f16\u8f91\u6587\u4ef6 file2.py class Car (): brand = \"\" def __init__ ( self , car_brand ): self . brand = car_brand print ( f \"initial method called, create { self . brand } car\" ) def __del__ ( self ): print ( f \"delete method called, destroy { self . brand } car\" ) Car ( 'BMW' ) Car ( 'VW' ) \u6267\u884c\u4e0a\u9762\u7684\u4ee3\u7801 python3 file2.py \u5f97\u5230\u5982\u4e0b\u8f93\u51fa\uff1a initial method called , create BMW car delete method called , destroy BMW car initial method called , create VW car delete method called , destroy VW car Python\u51fd\u6570\u5185\u7701\u5185\u7701 \u00b6 \u4ece\u9b54\u672f\u65b9\u6cd5\u53ef\u4ee5\u5ef6\u7533\u5230Python\u7684**\u51fd\u6570\u5185\u7701**\uff0c\u51fd\u6570\u5185\u7701\u7684\u610f\u601d\u662f\u8bf4\uff0c\u5f53\u4f60\u62ff\u5230\u4e00\u4e2a\u201c\u51fd\u6570\u5bf9\u8c61\u201d\u7684\u65f6\u5019\uff0c\u4f60\u53ef\u4ee5\u7ee7\u7eed\u77e5\u9053\uff0c\u5b83\u7684\u540d\u5b57\uff0c\u53c2\u6570\u5b9a\u4e49\u7b49\u4fe1\u606f\u3002\u8fd9\u4e9b\u4fe1\u606f\u53ef\u4ee5\u901a\u8fc7\u51fd\u6570\u5bf9\u8c61\u7684\u5c5e\u6027\uff08\u4e00\u4e9b\u53cc\u4e0b\u5212\u7ebf\u7684\u9b54\u6cd5\u65b9\u6cd5\uff09\u5f97\u5230\u3002\u7b80\u8a00\u4e4b\uff0c\u5185\u7701\u662f\u5728\u8fd0\u884c\u65f6\u786e\u5b9a\u5bf9\u8c61\u7c7b\u578b\u7684\u80fd\u529b\u3002 \u4e0b\u9762\u7684\u4f8b\u5b50\u5217\u51fa\u4e86\u5e38\u89c4\u5bf9\u8c61\u6ca1\u6709\u800c\u51fd\u6570\u6709\u7684\u5c5e\u6027\u3002 class C : pass obj = C () def func (): pass sorted ( set ( dir ( obj )) - set ( dir ( func ))) # ['__weakref__'] sorted ( set ( dir ( func )) - set ( dir ( obj ))) # ['__annotations__', '__call__', '__closure__', '__code__', '__defaults__', '__get__', '__globals__', '__kwdefaults__', '__name__', '__qualname__'] \u4e0b\u8868\u603b\u7ed3\u4e86\u7528\u6237\u5b9a\u4e49\u7684\u51fd\u6570\u7684\u5c5e\u6027\u3002 \u4e0b\u9762\u7684\u4f8b\u5b50\u662f\u6f14\u793a\u4e86\u5728\u6307\u5b9a\u957f\u5ea6\u9644\u8fd1\u622a\u65ad\u5b57\u7b26\u4e32\u7684\u51fd\u6570\uff0c\u4ee5\u53ca\u63d0\u53d6\u5173\u4e8e\u51fd\u6570\u53c2\u6570\u7684\u4fe1\u606f\u7684\u65b9\u6cd5\u3002 \u53c2\u6570\u540d\u79f0\u5728 __code__.co_varnames \u4e2d\uff0c\u4f46\u8fd9\u91cc\u9762\u4e5f\u5305\u542b\u51fd\u6570\u5b9a\u4e49\u4f53\u4e2d\u521b\u5efa\u7684\u5c40\u90e8\u53d8\u91cf\u3002\u56e0\u6b64\uff0c\u53c2\u6570\u540d\u79f0\u662f\u524d N \u4e2a\u5b57\u7b26\u4e32\uff0c N \u7684\u503c\u7531 __code__.co_argcount \u786e\u5b9a\uff0c\u4f8b\u5b50\u91cc\u9762N\u662f2\uff0c\u5373\u53c2\u6570\u540d\u79f0\u662f text \u548c max_len \uff0c\u5c40\u90e8\u53d8\u91cf\u662f end \u3001 space_before \u3001 space_after \u3002 def clip ( text , max_len = 80 ): \"\"\" Get sub-string by the first blank before or after specified position. rfind() \u8fd4\u56de\u5b57\u7b26\u4e32\u6700\u540e\u4e00\u6b21\u51fa\u73b0\u7684\u4f4d\u7f6e\uff0c\u5982\u679c\u6ca1\u6709\u5339\u914d\u9879\u5219\u8fd4\u56de -1. \"\"\" end = None if len ( text ) > max_len : space_before = text . rfind ( ' ' , 0 , max_len ) if space_before >= 0 : end = space_before else : space_after = text . rfind ( ' ' , max_len ) if space_after >= 0 : end = space_after if end is None : end = len ( text ) return text [: end ] . rstrip () clip ( 'This is the string' , max_len = 10 ) # 'This is' clip . __defaults__ # (80,) clip . __code__ # \", line 1> clip . __code__ . co_varnames # ('text', 'max_len', 'end', 'space_before', 'space_after') clip . __code__ . co_argcount # 2 clip . __doc__ # '\\n Get sub-string by the first blank before or after specified position.\\n rfind() \u8fd4\u56de\u5b57\u7b26\u4e32\u6700\u540e\u4e00\u6b21\u51fa\u73b0\u7684\u4f4d\u7f6e\uff0c\u5982\u679c\u6ca1\u6709\u5339\u914d\u9879\u5219\u8fd4\u56de -1.\\n ' \u4e0a\u4f8b\u4e2d\uff0c\u53c2\u6570\u7684\u9ed8\u8ba4\u503c\u53ea\u80fd\u901a\u8fc7\u5b83\u4eec\u5728 __defaults__ \u5143\u7ec4\u4e2d\u7684\u4f4d\u7f6e\u786e\u5b9a\uff0c\u56e0\u6b64\u8981\u4ece\u540e\u5411\u524d\u626b\u63cf\u624d\u80fd\u628a\u53c2\u6570\u548c\u9ed8\u8ba4\u503c\u5bf9\u5e94\u8d77\u6765\uff0c\u6709\u4e9b\u4e0d\u5408\u7406\u3002\u5f15\u5165 inspect \u6a21\u5757\u540e\uff0c\u4e0a\u9762\u7684\u64cd\u4f5c\u5c31\u66f4\u5bb9\u6613\u4e86\u3002 inspect.signature \u51fd\u6570\u8fd4\u56de\u4e00\u4e2a inspect.Signature \u5bf9\u8c61\uff0c\u5b83\u6709\u4e00\u4e2a parameters \u5c5e\u6027\uff0c\u8fd9\u662f\u4e00\u4e2a\u6709\u5e8f\u6620\u5c04\uff0c\u628a\u53c2\u6570\u540d\u548c inspect.Parameter \u5bf9\u8c61\u5bf9\u5e94\u8d77\u6765\u3002\u5404\u4e2a Parameter \u5c5e\u6027\u4e5f\u6709\u81ea\u5df1\u7684\u5c5e\u6027\uff0c\u4f8b\u5982 name \u3001 default \u548c kind \u3002 from inspect import signature sig = signature ( clip ) type ( sig ) # print ( sig ) # (text, max_len=80) print ( str ( sig )) # (text, max_len=80) for name , param in sig . parameters . items (): print ( f ' { param . kind } : { name } = { param . default } ' ) # 1 : text = # 1 : max_len = 80 \u51fd\u6570\u6ce8\u89e3\u3002 Python 3 \u63d0\u4f9b\u4e86\u4e00\u79cd\u53e5\u6cd5\uff0c\u7528\u4e8e\u4e3a\u51fd\u6570\u58f0\u660e\u4e2d\u7684\u53c2\u6570\u548c\u8fd4\u56de\u503c\u9644\u52a0\u5143\u6570\u636e\u3002\u5bf9\u4e0a\u4f8b\u6dfb\u52a0\u6ce8\u89e3\u540e\u5982\u4e0b\u6240\u793a\uff0c\u4e8c\u8005\u552f\u4e00\u7684\u533a\u522b\u5728\u7b2c\u4e00\u884c\u3002 \u51fd\u6570\u58f0\u660e\u4e2d\u7684\u5404\u4e2a\u53c2\u6570\u53ef\u4ee5\u5728:\u4e4b\u540e\u589e\u52a0\u6ce8\u89e3\u8868\u8fbe\u5f0f\u3002 \u5982\u679c\u53c2\u6570\u6709\u9ed8\u8ba4\u503c\uff0c\u6ce8\u89e3\u653e\u5728\u53c2\u6570\u540d\u548c = \u53f7\u4e4b\u95f4\u3002 \u5982\u679c\u60f3\u6ce8\u89e3\u8fd4\u56de\u503c\uff0c\u5728)\u548c\u51fd\u6570\u58f0\u660e\u672b\u5c3e\u7684 : \u4e4b\u95f4\u6dfb\u52a0 -> \u548c\u4e00\u4e2a\u8868\u8fbe\u5f0f\u3002\u90a3\u4e2a\u8868\u8fbe\u5f0f\u53ef\u4ee5\u662f\u4efb\u4f55\u7c7b\u578b\u3002 \u6ce8\u89e3\u4e2d\u6700\u5e38\u7528\u7684\u7c7b\u578b\u662f\u7c7b\uff08\u5982 str \u6216 int \uff09\u548c\u5b57\u7b26\u4e32\uff08\u5982'int > 0'\uff09\u3002\u5728\u4e0b\u4f8b\u4e2d\uff0cmax_len\u53c2\u6570\u7684\u6ce8\u89e3\u7528\u7684\u662f\u5b57\u7b26\u4e32\u3002 \u6ce8\u89e3\u4e0d\u4f1a\u505a\u4efb\u4f55\u5904\u7406\uff0c\u53ea\u662f\u5b58\u50a8\u5728\u51fd\u6570\u7684 __annotations__ \u5c5e\u6027\uff08\u4e00\u4e2a\u5b57\u5178\uff09\u4e2d\u3002\u6362\u53e5\u8bdd\u8bf4\uff0c\u6ce8\u89e3\u5bf9Python\u89e3\u91ca\u5668\u6ca1\u6709\u4efb\u4f55\u610f\u4e49\u3002 \u6ce8\u89e3\u53ea\u662f\u5143\u6570\u636e \uff0c\u53ef\u4ee5\u4f9bIDE\u3001\u6846\u67b6\u548c\u88c5\u9970\u5668\u7b49\u5de5\u5177\u4f7f\u7528\u3002 return \u952e\u4fdd\u5b58\u7684\u662f\u8fd4\u56de\u503c\u6ce8\u89e3\uff0c\u5373\u4e0b\u4f8b\u4e2d\u51fd\u6570\u58f0\u660e\u91cc\u4ee5 -> \u6807\u8bb0\u7684\u90e8\u5206\u3002 def clip ( text : str , max_len : 'int > 0' = 80 ) -> str : \"\"\" Get sub-string by the first blank before or after specified position. rfind() \u8fd4\u56de\u5b57\u7b26\u4e32\u6700\u540e\u4e00\u6b21\u51fa\u73b0\u7684\u4f4d\u7f6e\uff0c\u5982\u679c\u6ca1\u6709\u5339\u914d\u9879\u5219\u8fd4\u56de -1. \"\"\" end = None if len ( text ) > max_len : space_before = text . rfind ( ' ' , 0 , max_len ) if space_before >= 0 : end = space_before else : space_after = text . rfind ( ' ' , max_len ) if space_after >= 0 : end = space_after if end is None : end = len ( text ) return text [: end ] . rstrip () clip ( 'This is the string' , max_len = 10 ) # 'This is' clip . __annotations__ # {'text': , 'max_len': 'int > 0', 'return': } signature \u51fd\u6570\u8fd4\u56de\u4e00\u4e2a Signature \u5bf9\u8c61\uff0c\u5b83\u6709\u4e00\u4e2a return_annotation \u5c5e\u6027\u548c\u4e00\u4e2a parameters \u5c5e\u6027\uff0c\u540e\u8005\u662f\u4e00\u4e2a\u5b57\u5178\uff0c\u628a\u53c2\u6570\u540d\u6620\u5c04\u5230 Parameter \u5bf9\u8c61\u4e0a\u3002\u6bcf\u4e2a Parameter \u5bf9\u8c61\u81ea\u5df1\u4e5f\u6709 annotation \u5c5e\u6027\u3002 from inspect import signature sig = signature ( clip ) print ( sig . return_annotation ) # for param in sig . parameters . values (): note = repr ( param . annotation ) . ljust ( 13 ) print ( f ' { note } : { param . name } = { param . default } ' ) # : text = # 'int > 0' : max_len = 80","title":"Python\u9762\u5411\u5bf9\u8c61\u6982\u5ff5"},{"location":"python/Foundation/ch04/#python","text":"\u7c7b(class)\u628a\u6570\u636e\u4e0e\u529f\u80fd\u7ed1\u5b9a\u5728\u4e00\u8d77\u3002\u521b\u5efa\u65b0\u7c7b\u5c31\u662f\u521b\u5efa\u65b0\u7684\u5bf9\u8c61\u7c7b\u578b\uff08type of object\uff09\uff0c\u4ece\u800c\u521b\u5efa\u8be5\u7c7b\u578b\u7684\u65b0\u5b9e\u4f8b\uff08instances\uff09\u3002 \u7c7b\u5b9e\u4f8b\u5177\u6709\u591a\u79cd\u4fdd\u6301\u81ea\u8eab\u72b6\u6001\u7684\u5c5e\u6027\uff08attributes\uff09\u3002 \u7c7b\u5b9e\u4f8b\u8fd8\u652f\u6301\uff08\u7531\u7c7b\u5b9a\u4e49\u7684\uff09\u4fee\u6539\u81ea\u8eab\u72b6\u6001\u7684\u65b9\u6cd5\uff08methods\uff09\u3002 Python\u7684\u7c7b\u652f\u6301\u6240\u6709\u9762\u5411\u5bf9\u8c61\u7f16\u7a0b\uff08OOP\uff09\u7684\u6807\u51c6\u7279\u6027\uff1a \u7c7b\u7ee7\u627f\uff08class inheritance\uff09\u673a\u5236\u652f\u6301\u591a\u4e2a\u57fa\u7c7b\uff08base classes\uff09\uff1b \u6d3e\u751f\u7c7b\uff08derived class\uff09\u53ef\u4ee5\u8986\u76d6\u57fa\u7c7b\u7684\u4efb\u4f55\u65b9\u6cd5\uff08methods\uff09\uff1b \u7c7b\u7684\u65b9\u6cd5\u53ef\u4ee5\u8c03\u7528\u57fa\u7c7b\u4e2d\u76f8\u540c\u540d\u79f0\u7684\u65b9\u6cd5 \u5bf9\u8c61\u53ef\u4ee5\u5305\u542b\u4efb\u610f\u6570\u91cf\u548c\u7c7b\u578b\u7684\u6570\u636e\u3002 \u7c7b\uff08class\uff09\u548c\u6a21\u5757\uff08module\uff09\u90fd\u62e5\u6709\u52a8\u6001\u7279\u6027\uff08dynamic nature\uff09\uff1a\u5728\u8fd0\u884c\u65f6\u521b\u5efa\uff0c\u521b\u5efa\u540e\u4e5f\u53ef\u4ee5\u4fee\u6539\u3002","title":"Python\u9762\u5411\u5bf9\u8c61\u6982\u5ff5"},{"location":"python/Foundation/ch04/#namesobjects","text":"\u5bf9\u8c61\u4e4b\u95f4\u76f8\u4e92\u72ec\u7acb\uff0c\u591a\u4e2a\u540d\u79f0\uff08names\uff09\uff08\u5728\u591a\u4e2a\u4f5c\u7528\u57df\u5185\uff09\u53ef\u4ee5\u7ed1\u5b9a\u5230\u540c\u4e00\u4e2a\u5bf9\u8c61\u3002 \u5176\u4ed6\u8bed\u8a00\u79f0\u4e4b\u4e3a\u522b\u540d\uff08alias\uff09\u3002 \u522b\u540d\u5728\u67d0\u4e9b\u65b9\u9762\u5c31\u50cf\u6307\u9488\u3002\u4f8b\u5982\uff0c\u4f20\u9012\u5bf9\u8c61\u7684\u4ee3\u4ef7\u5f88\u5c0f\uff0c\u56e0\u4e3a\u5b9e\u73b0\u53ea\u4f20\u9012\u4e00\u4e2a\u6307\u9488\uff1b\u5982\u679c\u51fd\u6570\u4fee\u6539\u4e86\u4f5c\u4e3a\u53c2\u6570\u4f20\u9012\u7684\u5bf9\u8c61\uff0c\u8c03\u7528\u8005\u5c31\u53ef\u4ee5\u770b\u5230\u66f4\u6539\u3002","title":"\u540d\u79f0Names\u548c\u5bf9\u8c61Objects"},{"location":"python/Foundation/ch04/#scopesnamespaces","text":"**\u547d\u540d\u7a7a\u95f4\uff08namespace\uff09**\u662f\u4e00\u4e2a\u4ece\u540d\u5b57\u5230\u5bf9\u8c61\u7684\u6620\u5c04\u3002 \u5f53\u524d\u5927\u90e8\u5206\u547d\u540d\u7a7a\u95f4\u90fd\u7531 Python \u5b57\u5178\u5b9e\u73b0\u3002 \u4e0b\u9762\u662f\u51e0\u4e2a\u547d\u540d\u7a7a\u95f4\u7684\u4f8b\u5b50\uff1a \u5b58\u653e\u5185\u7f6e\u51fd\u6570\u7684\u96c6\u5408\uff08\u5305\u542b abs() \u8fd9\u6837\u7684\u51fd\u6570\uff0c\u548c\u5185\u5efa\u7684\u5f02\u5e38\u7b49\uff09\uff1b \u6a21\u5757\u4e2d\u7684\u5168\u5c40\u540d\u79f0\uff1b \u51fd\u6570\u8c03\u7528\u4e2d\u7684\u5c40\u90e8\u540d\u79f0\uff1b \u4ece\u67d0\u79cd\u610f\u4e49\u4e0a\u8bf4\uff0c \u5bf9\u8c61\u7684\u5c5e\u6027\u96c6\u5408\uff08the set of attributes of an object\uff09\u4e5f\u662f\u4e00\u79cd\u547d\u540d\u7a7a\u95f4\u7684\u5f62\u5f0f \u3002 \u5173\u4e8e\u547d\u540d\u7a7a\u95f4\u7684\u91cd\u8981\u4e00\u70b9\u662f\uff0c\u4e0d\u540c\u547d\u540d\u7a7a\u95f4\u4e2d\u7684\u540d\u79f0\u4e4b\u95f4\u7edd\u5bf9\u6ca1\u6709\u5173\u7cfb\uff1b \u4f8b\u5982\uff0c\u5728\u4e24\u4e2a\u4e0d\u540c\u7684\u6a21\u5757\u4e2d\u90fd\u53ef\u4ee5\u5b9a\u4e49\u4e00\u4e2a maximize \u51fd\u6570\u800c\u4e0d\u4f1a\u4ea7\u751f\u6df7\u6dc6\uff0c\u4f46\u5728\u8c03\u7528 maximize \u51fd\u6570\u65f6\u5fc5\u987b\u5fc5\u987b\u5728\u5176\u524d\u9762\u52a0\u4e0a\u6a21\u5757\u540d\u79f0\u3002 \u4efb\u4f55\u8ddf\u5728\u4e00\u4e2a\u70b9\u53f7\u4e4b\u540e\u7684\u540d\u79f0\u90fd\u79f0\u4e3a**\u5c5e\u6027\uff08attribute\uff09**\u3002\u4f8b\u5982\uff0c\u5728\u8868\u8fbe\u5f0f z.real \u4e2d\uff0c real \u662f\u5bf9\u8c61 z \u7684\u4e00\u4e2a\u5c5e\u6027\u3002 \u6309\u4e25\u683c\u7684\u8bf4\u6cd5\uff0c \u5bf9\u6a21\u5757\uff08module\uff09\u4e2d\u7684\u540d\u79f0\u7684\u5f15\u7528\uff08reference\uff09\u90fd\u5c5e\u4e8e\u5c5e\u6027\u5f15\u7528\uff08attribute reference\uff09 \uff1a \u5728\u8868\u8fbe\u5f0f modname.funcname \u4e2d\uff0c modname \u662f\u4e00\u4e2a\u6a21\u5757\u5bf9\u8c61\uff08module object\uff09\u800c funcname \u662f\u5b83\u7684\u4e00\u4e2a\u5c5e\u6027\u3002 \u5728\u6b64\u60c5\u51b5\u4e0b\u5728\u6a21\u5757\u7684\u5c5e\u6027\uff08module\u2019s attribute\uff09\u548c\u6a21\u5757\u4e2d\u5b9a\u4e49\u7684\u5168\u5c40\u540d\u79f0\u4e4b\u95f4\u6b63\u597d\u5b58\u5728\u4e00\u4e2a\u76f4\u89c2\u7684\u6620\u5c04\uff1a\u5b83\u4eec\u5171\u4eab\u76f8\u540c\u7684\u547d\u540d\u7a7a\u95f4\u3002 \u4f46\u5b58\u5728\u4e00\u4e2a\u4f8b\u5916\u3002 \u6a21\u5757\u5bf9\u8c61\u6709\u4e00\u4e2a\u53ea\u8bfb\u5c5e\u6027 __dict__ \uff0c\u5b83\u8fd4\u56de\u7528\u4e8e\u5b9e\u73b0\u6a21\u5757\u547d\u540d\u7a7a\u95f4\u7684\u5b57\u5178\uff1b __dict__ \u662f\u5c5e\u6027\u4f46\u4e0d\u662f\u5168\u5c40\u540d\u79f0\u3002 \u4f7f\u7528\u8fd9\u4e2a\u5c06\u8fdd\u53cd\u547d\u540d\u7a7a\u95f4\u5b9e\u73b0\u7684\u62bd\u8c61\uff0c\u5e94\u5f53\u4ec5\u88ab\u7528\u4e8e\u4e8b\u540e\u8c03\u8bd5\u5668\u4e4b\u7c7b\u7684\u573a\u5408\u3002 **\u5c5e\u6027\uff08attribute\uff09**\u53ef\u4ee5\u662f\u53ea\u8bfb\u6216\u8005\u53ef\u5199\u7684\uff0c\u6240\u4ee5\u53ef\u4ee5\u5bf9\u5c5e\u6027\u8fdb\u884c\u8d4b\u503c\uff0c\u4f8b\u5982 modname.the_answer = 42 \u3002 \u5220\u9664\u5c5e\u6027\u53ef\u4ee5\u7528del\u8bed\u53e5\uff0c\u4f8b\u5982\uff0c del modname.the_answer \u5c06\u4f1a\u4ece\u540d\u4e3a modname \u7684\u5bf9\u8c61\u4e2d\u79fb\u9664 the_answer \u5c5e\u6027\u3002 \u547d\u540d\u7a7a\u95f4\u5728\u4e0d\u540c\u65f6\u523b\u88ab\u521b\u5efa\uff0c\u62e5\u6709\u4e0d\u540c\u7684\u751f\u5b58\u671f\uff08lifetimes\uff09\u3002\u5305\u542b\u5185\u7f6e\u540d\u79f0\uff08built-in names\uff09\u7684\u547d\u540d\u7a7a\u95f4\u662f\u5728Python\u89e3\u91ca\u5668\u542f\u52a8\u65f6\u521b\u5efa\u7684\uff0c\u6c38\u8fdc\u4e0d\u4f1a\u88ab\u5220\u9664\u3002 \u6a21\u5757\u7684\u5168\u5c40\u547d\u540d\u7a7a\u95f4\uff08global namespace\uff09\u5728\u6a21\u5757\u5b9a\u4e49\u88ab\u8bfb\u5165\u65f6\u521b\u5efa\uff1b\u901a\u5e38\uff0c\u6a21\u5757\u547d\u540d\u7a7a\u95f4\u4e5f\u4f1a\u6301\u7eed\u5230\u89e3\u91ca\u5668\u9000\u51fa\u3002 \u88ab\u89e3\u91ca\u5668\u7684\u9876\u5c42\u8c03\u7528\uff08top-level invocation\uff09\u6267\u884c\u7684\u8bed\u53e5\uff0c\u4ece\u4e00\u4e2a\u811a\u672c\u6587\u4ef6\u8bfb\u53d6\u6216\u4ea4\u4e92\u5f0f\u5730\u8bfb\u53d6\uff0c\u88ab\u8ba4\u4e3a\u662f __main__ \u6a21\u5757\u8c03\u7528\u7684\u4e00\u90e8\u5206\uff0c\u56e0\u6b64\u5b83\u4eec\u62e5\u6709\u81ea\u5df1\u7684\u5168\u5c40\u547d\u540d\u7a7a\u95f4\u3002 \u5185\u7f6e\u540d\u79f0\uff08built-in names\uff09\u5b9e\u9645\u4e0a\u4e5f\u5b58\u5728\u4e8e\u4e00\u4e2a\u6a21\u5757\u4e2d\uff0c\u8fd9\u4e2a\u6a21\u5757\u88ab\u79f0\u4f5c builtins \u3002 \u4e00\u4e2a\u51fd\u6570\u7684\u672c\u5730\u547d\u540d\u7a7a\u95f4\uff08local namespace\uff09\u5728\u8fd9\u4e2a\u51fd\u6570\u88ab\u8c03\u7528\u65f6\u521b\u5efa\uff0c\u5e76\u5728\u51fd\u6570\u8fd4\u56de\u6216\u629b\u51fa\u4e00\u4e2a\u65e0\u6cd5\u5728\u8be5\u51fd\u6570\u5185\u90e8\u5904\u7406\u7684\u9519\u8bef\u65f6\u88ab\u5220\u9664\u3002 \u6bcf\u6b21\u9012\u5f52\u8c03\u7528\uff08recursive invocations\uff09\u90fd\u4f1a\u6709\u5b83\u81ea\u5df1\u7684\u672c\u5730\u547d\u540d\u7a7a\u95f4\u3002 \u4e00\u4e2a**\u4f5c\u7528\u57df\uff08scope\uff09**\u662f\u4e00\u4e2a\u547d\u540d\u7a7a\u95f4\u53ef\u76f4\u63a5\u8bbf\u95ee\uff08directly accessible\uff09\u7684Python\u7a0b\u5e8f\u7684\u4ee3\u7801\u533a\u57df\u3002 \u8fd9\u91cc\u7684 \u201c\u53ef\u76f4\u63a5\u8bbf\u95ee\u201d \u610f\u5473\u7740\u4e0d\u52a0\u4efb\u4f55\u9650\u5b9a\u7684\u540d\u79f0\u5f15\u7528\u4f1a\u5728\u547d\u540d\u7a7a\u95f4\u4e2d\u8fdb\u884c\u67e5\u627e\u3002 \u867d\u7136\u4f5c\u7528\u57df\u662f\u9759\u6001\u5730\u786e\u5b9a\u7684\uff0c\u4f46\u5b83\u4eec\u4f1a\u88ab\u52a8\u6001\u5730\u4f7f\u7528\u3002 \u5728\u4ee3\u7801\u6267\u884c\u671f\u95f4\u7684\u4efb\u4f55\u65f6\u523b\uff0c\u4f1a\u67093\u62164\u4e2a\u7684\u5d4c\u5957\u4f5c\u7528\u57df\u4f9b\u547d\u540d\u7a7a\u95f4\u76f4\u63a5\u8bbf\u95ee: \u6700\u5148\u641c\u7d22\u7684\u6700\u5185\u90e8\u4f5c\u7528\u57df\u5305\u542b\u5c40\u90e8\u540d\u79f0 \u4ece\u6700\u8fd1\u7684\u5c01\u95ed\u4f5c\u7528\u57df\u5f00\u59cb\u641c\u7d22\u7684\u4efb\u4f55\u5c01\u95ed\u51fd\u6570\u7684\u4f5c\u7528\u57df\u5305\u542b\u975e\u5c40\u90e8\u540d\u79f0\uff0c\u4e5f\u5305\u62ec\u975e\u5168\u5c40\u540d\u79f0 \u5012\u6570\u7b2c\u4e8c\u4e2a\u4f5c\u7528\u57df\u5305\u542b\u5f53\u524d\u6a21\u5757\u7684\u5168\u5c40\u540d\u79f0 \u6700\u5916\u9762\u7684\u4f5c\u7528\u57df\uff08\u6700\u540e\u641c\u7d22\uff09\u662f\u5305\u542b\u5185\u7f6e\u540d\u79f0\u7684\u547d\u540d\u7a7a\u95f4 \u5982\u679c\u4e00\u4e2a\u540d\u79f0\u88ab\u58f0\u660e\u4e3a\u5168\u5c40\u53d8\u91cf\uff0c\u5219\u6240\u6709\u5f15\u7528\u548c\u8d4b\u503c\u5c06\u76f4\u63a5\u6307\u5411\u8be5\u6a21\u5757\u5168\u5c40\u540d\u79f0\u6240\u5728\u7684\u4e2d\u95f4\u4f5c\u7528\u57df\u3002 \u5982\u679c\u8981\u91cd\u65b0\u7ed1\u5b9a\u5728\u6700\u5185\u5c42\u4f5c\u7528\u57df\u4ee5\u5916\u7684\u53d8\u91cf\uff0c\u53ef\u4ee5\u4f7f\u7528 nonlocal \u8bed\u53e5\u58f0\u660e\u4e3a\u975e\u672c\u5730\u53d8\u91cf\u3002 \u5982\u679c\u6ca1\u6709\u88ab\u58f0\u660e\u4e3a\u975e\u672c\u5730\u53d8\u91cf\uff0c\u8fd9\u4e9b\u53d8\u91cf\u5c06\u662f\u53ea\u8bfb\u7684\u3002\u7ed9\u8fd9\u6837\u7684\u53d8\u91cf\u8d4b\u65b0\u503c\u53ea\u4f1a\u5728\u6700\u5185\u5c42\u4f5c\u7528\u57df\u4e2d\u521b\u5efa\u4e00\u4e2a*\u65b0\u7684*\u5c40\u90e8\u53d8\u91cf\uff0c\u800c\u540c\u540d\u7684\u5916\u90e8\u5168\u5c40\u53d8\u91cf\u5c06\u4fdd\u6301\u4e0d\u53d8\u3002 \u901a\u5e38\uff0c\u5f53\u524d\u5c40\u90e8\u4f5c\u7528\u57df\uff08local scope\uff09\u5c06\u5f15\u7528\u5f53\u524d\u51fd\u6570\u4f5c\u7528\u57df\u7684\u540d\u79f0\uff08local name\uff09\u3002 \u5728\u51fd\u6570\u4f5c\u7528\u57df\u4ee5\u5916\uff0c\u5f53\u524d\u5c40\u90e8\u4f5c\u7528\u57df\u5c06\u5f15\u7528\u4e0e\u5168\u5c40\u4f5c\u7528\u57df\u76f8\u4e00\u81f4\u7684\u547d\u540d\u7a7a\u95f4\uff1a\u6a21\u5757\u7684\u547d\u540d\u7a7a\u95f4\uff08the module\u2019s namespace\uff09\u3002 \u5b9a\u4e49\u4e00\u4e2a\u7c7b\uff0c\u662f\u5728\u672c\u5730\u5c40\u90e8\u547d\u540d\u7a7a\u95f4\u5185\u5efa\u4e00\u4e2a\u65b0\u7684\u547d\u540d\u7a7a\u95f4\u3002 \u5728\u4e00\u4e2a\u6a21\u5757\uff08module \uff09\u5185\u5b9a\u4e49\u7684\u51fd\u6570\u7684\u4f5c\u7528\u57df\u5c31\u662f\u8be5\u6a21\u5757\u7684\u547d\u540d\u7a7a\u95f4\uff0c\u65e0\u8bba\u8be5\u51fd\u6570\u4ece\u4ec0\u4e48\u5730\u65b9\u6216\u4ee5\u4ec0\u4e48\u522b\u540d\u88ab\u8c03\u7528\u3002 \u53e6\u4e00\u65b9\u9762\uff0c\u5b9e\u9645\u7684\u540d\u79f0\u641c\u7d22\u662f\u5728\u8fd0\u884c\u65f6\u52a8\u6001\u5b8c\u6210\u7684\u3002 \u4f46\u662f\uff0cPython\u6b63\u5728\u671d\u7740\u201c\u7f16\u8bd1\u65f6\u9759\u6001\u540d\u79f0\u89e3\u6790\u201d\u7684\u65b9\u5411\u53d1\u5c55\uff0c\u56e0\u6b64\u4e0d\u8981\u8fc7\u4e8e\u4f9d\u8d56\u52a8\u6001\u540d\u79f0\u89e3\u6790\uff01\u4e8b\u5b9e\u4e0a\uff0c\u5c40\u90e8\u53d8\u91cf\u5df2\u7ecf\u662f\u88ab\u9759\u6001\u786e\u5b9a\u4e86\u3002 \u5982\u679c\u4e0d\u5b58\u5728\u751f\u6548\u7684 global \u6216 nonlocal \u8bed\u53e5\uff0c\u5219\u5bf9\u540d\u79f0\u7684\u8d4b\u503c\u603b\u662f\u4f1a\u8fdb\u5165\u6700\u5185\u5c42\u4f5c\u7528\u57df\u3002\u8d4b\u503c\u4e0d\u4f1a\u590d\u5236\u6570\u636e\uff0c\u662f\u5c06\u540d\u79f0\u7ed1\u5b9a\u5230\u5bf9\u8c61\u3002 \u5220\u9664\u4e5f\u662f\u5982\u6b64\uff1a\u8bed\u53e5 del x \u4f1a\u4ece\u5c40\u90e8\u4f5c\u7528\u57df\u6240\u5f15\u7528\u7684\u547d\u540d\u7a7a\u95f4\u4e2d\u79fb\u9664\u5bf9 x \u7684\u7ed1\u5b9a\u3002\u4e8b\u5b9e\u4e0a\uff0c\u6240\u6709\u5f15\u5165\u65b0\u540d\u79f0\u7684\u64cd\u4f5c\u90fd\u662f\u4f7f\u7528\u5c40\u90e8\u4f5c\u7528\u57df\u3002\u7279\u522b\u5730\uff0c import \u8bed\u53e5\u548c\u51fd\u6570\u5b9a\u4e49\u4f1a\u5728\u5c40\u90e8\u4f5c\u7528\u57df\u4e2d\u7ed1\u5b9a\u6a21\u5757\u6216\u51fd\u6570\u540d\u79f0\u3002 global \u8bed\u53e5\u53ef\u88ab\u7528\u6765\u8868\u660e\u7279\u5b9a\u53d8\u91cf\u5b58\u5728\u4e8e\u5168\u5c40\u4f5c\u7528\u57df\uff0c\u5e76\u4e14\u5e94\u5f53\u5728\u5168\u5c40\u4f5c\u7528\u57df\u4e2d\u88ab**\u91cd\u65b0**\u7ed1\u5b9a\uff1b nonlocal \u8bed\u53e5\u8868\u660e\u7279\u5b9a\u53d8\u91cf\u751f\u5b58\u4e8e\u5916\u5c42\u4f5c\u7528\u57df\u4e2d\uff0c\u5e76\u4e14\u5e94\u5f53\u5728\u5176\u6240\u5904\u7684\u5916\u5c42\u4f5c\u7528\u57df\u4e2d\u88ab**\u91cd\u65b0**\u7ed1\u5b9a\u3002 \u770b\u4e0b\u9762\u7684\u4f8b\u5b50\uff1a \u5c40\u90e8\u8d4b\u503c\uff08local assignment\uff0c\u8fd9\u662f\u9ed8\u8ba4\u72b6\u6001\uff09\u4e0d\u4f1a\u6539\u53d8 scope_test \u5bf9 spam \u7684\u7ed1\u5b9a\u3002 nonlocal \u8d4b\u503c\u4f1a\u6539\u53d8 scope_test \u5bf9 spam \u7684\u7ed1\u5b9a\u3002 global \u8d4b\u503c\u4f1a\u6539\u53d8\u6a21\u5757\u5c42\u7ea7\u7684\u7ed1\u5b9a\uff0c\u5373\uff0c global spam \u91cd\u65b0\u7ed1\u5b9a\u4e86spam\u7684\u5168\u5c40\u5b9a\u4e49\uff0c\u4ece spam = \"spam out of func\" \u53d8\u6210\u4e86 spam = \"global spam\" \u3002\u5982\u679c\u6ce8\u91ca\u6389def do_global()\u8fd9\u4e00\u6bb5\u4ee3\u7801\uff0c\u5219 spam = \"spam out of func\" \u8d77\u4f5c\u7528\u3002 spam = \"spam out of func\" def scope_test (): def do_local (): spam = \"local spam\" def do_nonlocal (): nonlocal spam spam = \"nonlocal spam\" def do_global (): global spam spam = \"global spam\" spam = \"test spam\" do_local () print ( \"After local assignment:\" , spam ) do_nonlocal () print ( \"After nonlocal assignment:\" , spam ) do_global () print ( \"After global assignment:\" , spam ) scope_test () print ( \"In global scope:\" , spam ) # \u8fd0\u884c\u7ed3\u679c # scope_test() After local assignment : test spam After nonlocal assignment : nonlocal spam After global assignment : nonlocal spam # print(\"In global scope:\", spam) In global scope : global spam","title":"\u4f5c\u7528\u57dfScopes\u548c\u547d\u540d\u7a7a\u95f4Namespaces"},{"location":"python/Foundation/ch04/#class","text":"","title":"\u7c7bClass"},{"location":"python/Foundation/ch04/#class-definition","text":"\u7c7b\u5b9a\u4e49\u4e0e\u51fd\u6570\u5b9a\u4e49 (def \u8bed\u53e5) \u4e00\u6837\u5fc5\u987b\u88ab\u6267\u884c\u624d\u4f1a\u8d77\u4f5c\u7528\u3002 class ClassName : < statement - 1 > ... < statement - N > \u5728\u5b9e\u8df5\u4e2d\uff0c\u7c7b\u5b9a\u4e49\u5185\u7684\u8bed\u53e5\u901a\u5e38\u90fd\u662f\u51fd\u6570\u5b9a\u4e49\uff0c\u4f46\u4e5f\u5141\u8bb8\u6709\u5176\u4ed6\u8bed\u53e5\u3002\u5728\u7c7b\u5185\u90e8\u7684\u51fd\u6570\u5b9a\u4e49\u901a\u5e38\u5177\u6709\u4e00\u79cd\u7279\u6709\u5f62\u5f0f\u7684\u53c2\u6570\u5217\u8868\uff0c\u8fd9\u662f\u7ea6\u5b9a\u7684\u65b9\u6cd5\u89c4\u8303\uff08conventions for methods\uff09\u3002 \u7f16\u8bd1\u8fc7\u7a0b\u4e2d\uff0c\u8fdb\u5165\u4e00\u4e2a\u7c7b\u7684\u5185\u90e8\uff0c\u5c06\u521b\u5efa\u4e00\u4e2a\u65b0\u7684\u547d\u540d\u7a7a\u95f4\uff0c\u4e00\u4e2a\u5c40\u90e8\u4f5c\u7528\u57df\u3002\u56e0\u6b64\uff0c\u6240\u6709\u5bf9\u7c7b\u5185\u90e8\u5c40\u90e8\u53d8\u91cf\u7684\u8d4b\u503c\u90fd\u662f\u5728\u8fd9\u4e2a\u65b0\u7684\u547d\u540d\u7a7a\u95f4\u4e4b\u5185\uff0c\u5305\u62ec\u65b0\u5b9a\u4e49\u7684\u51fd\u6570\u540d\u79f0\u3002 \u5f53\u6b63\u5e38\u79bb\u5f00\u4e00\u4e2a\u7c7b\u65f6\uff0c\u7f16\u8bd1\u8fc7\u7a0b\u5c06\u521b\u5efa\u4e00\u4e2a\u7c7b\u5bf9\u8c61\uff08class object\uff09\uff0c\u5c01\u88c5\u4e86\u7c7b\u5b9a\u4e49\u6240\u521b\u5efa\u7684\u547d\u540d\u7a7a\u95f4\u91cc\u7684\u5185\u5bb9\u3002 \u6700\u521d\u7684\uff08\u5728\u8fdb\u5165\u7c7b\u5b9a\u4e49\u4e4b\u524d\u8d77\u4f5c\u7528\u7684\uff09\u5c40\u90e8\u4f5c\u7528\u57df\u5c06\u91cd\u65b0\u751f\u6548\uff0c\u7c7b\u5bf9\u8c61\uff08class object\uff09\u5c06\u5728\u8fd9\u91cc\u88ab\u7ed1\u5b9a\u5230\u7c7b\u5b9a\u4e49\u5934\u90e8\u6240\u58f0\u660e\u7684\u7c7b\u540d\u79f0 (\u5728\u4e0a\u9762\u7684\u793a\u4f8b\u4e2d\u662f ClassName )\u3002","title":"\u7c7b\u5b9a\u4e49 Class Definition"},{"location":"python/Foundation/ch04/#class-objects","text":"\u7c7b\u5bf9\u8c61\u652f\u6301\u4e24\u79cd\u64cd\u4f5c\uff1a\u5c5e\u6027\u5f15\u7528\uff08attribute references\uff09\u548c\u5b9e\u4f8b\u5316\uff08instantiation\uff09\u3002 \u5c5e\u6027\u5f15\u7528\uff08attribute references\uff09 \u4f7f\u7528Python\u4e2d\u5c5e\u6027\u5f15\u7528\u7684\u6807\u51c6\u8bed\u6cd5: obj.name \u3002 \u5b58\u5728\u4e8e\u7c7b\u547d\u540d\u7a7a\u95f4\u4e2d\u7684\u6240\u6709\u540d\u79f0\uff0c\u7c7b\u5bf9\u8c61\u88ab\u521b\u5efa\u65f6\u540c\u65f6\u88ab\u521b\u5efa\u4e86\uff0c\u8fd9\u4e9b\u5c31\u662f\u6709\u6548\u7684\u5c5e\u6027\u540d\u79f0\u3002\u56e0\u6b64\uff0c\u5982\u679c\u7c7b\u5b9a\u4e49\u662f\u5982\u4e0b\u6240\u793a\uff0c\u90a3\u4e48 MyClass.i \u548c MyClass.f \u5c31\u662f\u6709\u6548\u7684\u5c5e\u6027\u5f15\u7528\uff0c\u5c06\u5206\u522b\u8fd4\u56de\u4e00\u4e2a\u6574\u6570\u548c\u4e00\u4e2a\u51fd\u6570\u5bf9\u8c61\u3002 \u7c7b\u5c5e\u6027\u4e5f\u53ef\u4ee5\u88ab\u8d4b\u503c\uff0c\u56e0\u6b64\u53ef\u4ee5\u901a\u8fc7\u8d4b\u503c\u6765\u66f4\u6539 MyClass.i \u7684\u503c\u3002 __doc__ \u4e5f\u662f\u4e00\u4e2a\u6709\u6548\u7684\u5c5e\u6027\uff0c\u5c06\u8fd4\u56de\u6240\u5c5e\u7c7b\u7684\u6587\u6863\u5b57\u7b26\u4e32: \"A simple example class\"\u3002 class MyClass : \"\"\"A simple example class\"\"\" i = 12345 def f ( self ): return 'hello world' print ( MyClass . i ) # 12345 print ( MyClass . __doc__ ) # A simple example class MyClass . i = 10 print ( MyClass . i ) # 10 \u7c7b\u7684**\u5b9e\u4f8b\u5316\uff08instantiation\uff09**\u4f7f\u7528\u51fd\u6570\u8868\u793a\u6cd5\u3002 \u53ef\u4ee5\u628a\u7c7b\u5bf9\u8c61\uff08class object\uff09\u770b\u4f5c\u662f\u4e00\u4e2a\u4e0d\u5e26\u53c2\u6570\u7684\u51fd\u6570\uff0c\u8fd9\u4e2a\u51fd\u6570\u8fd4\u56de\u4e86\u8be5\u7c7b\u7684\u4e00\u4e2a\u65b0\u5b9e\u4f8b\u3002 \u5728\u4e0b\u9762\u7684\u4f8b\u5b50\u4e2d\uff0c x = MyClass() \u521b\u5efa\u4e86 MyClass() \u8fd9\u4e2a\u7c7b\u7684\u4e00\u4e2a\u5b9e\u4f8b\uff0c\u5e76\u8d4b\u503c\u7ed9\u5c40\u90e8\u53d8\u91cf x \u3002 \u5b9e\u4f8b\u5316\u64cd\u4f5c\uff08\u8c03\u7528\u7c7b\u5bf9\u8c61\uff09\u4f1a\u521b\u5efa\u4e00\u4e2a\u7a7a\u5bf9\u8c61\u3002\u8bb8\u591a\u7c7b\u4f1a\u521b\u5efa\u5e26\u6709\u7279\u5b9a\u521d\u59cb\u72b6\u6001\u7684\u81ea\u5b9a\u4e49\u5b9e\u4f8b\u3002\u4e3a\u6b64\u7c7b\u5b9a\u4e49\u4e2d\u9700\u8981\u5305\u542b\u4e00\u4e2a\u540d\u4e3a __init__() \u7684\u7279\u6b8a\u65b9\u6cd5\u3002 \u5f53\u4e00\u4e2a\u7c7b\u5b9a\u4e49\u4e86 __init__() \u65b9\u6cd5\u65f6\uff0c\u7c7b\u7684\u5b9e\u4f8b\u5316\u64cd\u4f5c\u4f1a\u81ea\u52a8\u4e3a\u65b0\u521b\u5efa\u7684\u7c7b\u5b9e\u4f8b\u8c03\u7528 __init__() \u3002 \u66f4\u65b0\u4e0a\u9762\u7684\u4f8b\u5b50\uff0c\u6ce8\u610f __dict__ \u4e24\u6b21\u8fd4\u56de\u7684\u4e0d\u540c\u7684\u5b57\u5178\u3002\u590d\u4e60\u4e00\u4e0b\uff0c\u5728\u547d\u540d\u7a7a\u95f4\u4e2d\u63d0\u5230\uff0c __dict__ \u662f\u5c5e\u6027\u4f46\u4e0d\u662f\u5168\u5c40\u540d\u79f0\uff0c\u8fd4\u56de\u7528\u4e8e\u5b9e\u73b0\u6a21\u5757\u547d\u540d\u7a7a\u95f4\u7684\u5b57\u5178\u3002 class MyClass : \"\"\"A simple example class\"\"\" i = 12345 def f ( self ): return 'hello world' def __init__ ( self ): self . data = [] x = MyClass () print ( x . __dict__ ) # {'data': []} x . i = 10 print ( x . __dict__ ) # {'data': [], 'i': 10} __init__() \u65b9\u6cd5\u53ef\u4ee5\u6709\u989d\u5916\u7684\u53c2\u6570\u8f93\u5165\uff0c\u5728\u8fd9\u79cd\u60c5\u51b5\u4e0b\uff0c\u7c7b\u5b9e\u4f8b\u5316\u7684\u53c2\u6570\u5c06\u88ab\u4f20\u9012\u7ed9 __init__() \u3002 \u5982\u4e0b\u4f8b: class Complex : def __init__ ( self , realpart , imagpart ): self . r = realpart self . i = imagpart x = Complex ( 3.0 , - 4.5 ) print ( x . r , x . i ) # 3.0 -4.5","title":"\u7c7b\u5bf9\u8c61 Class Objects"},{"location":"python/Foundation/ch04/#instance-objects","text":"\u5bf9\u5b9e\u4f8b\u5bf9\u8c61\u552f\u4e00\u7684\u64cd\u4f5c\u662f\u5c5e\u6027\u5f15\u7528\u3002\u6709\u4e24\u79cd\u6709\u6548\u7684\u5c5e\u6027\u540d\u79f0\uff1a\u6570\u636e\u5c5e\u6027\uff08data attributes\uff09\u548c\u65b9\u6cd5\uff08methods\uff09\u3002 **\u6570\u636e\u5c5e\u6027\uff08data attributes\uff09**\u7c7b\u4f3c\u4e8e\u5b9e\u4f8b\u53d8\u91cf\uff0c\u6570\u636e\u5c5e\u6027\u4e0d\u9700\u8981\u58f0\u660e\u3002\u50cf\u5c40\u90e8\u53d8\u91cf\u4e00\u6837\uff0c\u6570\u636e\u5c5e\u6027\u5c06\u5728\u7b2c\u4e00\u6b21\u88ab\u8d4b\u503c\u65f6\u4ea7\u751f\u3002 \u4f8b\u5982\uff0c\u5982\u679c x \u662f\u4e0a\u9762\u521b\u5efa\u7684 MyClass \u7684\u5b9e\u4f8b\uff0c\u5219\u4ee5\u4e0b\u4ee3\u7801\u6bb5\u5c06\u6253\u5370\u6570\u503c 16 \uff0c\u4e14\u6ca1\u6709\u7559\u4e0b\u5173\u4e8e x.counter \u7684\u75d5\u8ff9\u3002 class MyClass : \"\"\"A simple example class\"\"\" i = 12345 def f ( self ): return 'hello world' def __init__ ( self ): self . data = [] x = MyClass () x . counter = 1 while x . counter < 10 : x . counter = x . counter * 2 print ( x . counter ) # 16 print ( x . __dict__ ) # {'data': [], 'counter': 16} del x . counter print ( x . __dict__ ) # {'data': []} \u53e6\u4e00\u7c7b\u5b9e\u4f8b\u5c5e\u6027\u5f15\u7528\u79f0\u4e3a**\u65b9\u6cd5\uff08methods\uff09 \u3002 \u65b9\u6cd5\u662f\u96b6\u5c5e\u4e8e\u5bf9\u8c61\u7684**\u51fd\u6570 \u3002 \u5728Python\u4e2d\uff0c\u65b9\u6cd5\u8fd9\u4e2a\u672f\u8bed\u5e76\u4e0d\u662f\u7c7b\u5b9e\u4f8b\u6240\u7279\u6709\u7684\uff0c\u5176\u4ed6\u5bf9\u8c61\u4e5f\u53ef\u4ee5\u6709\u65b9\u6cd5\u3002 \u4f8b\u5982\uff0c\u5217\u8868\u5bf9\u8c61\uff08list objects\uff09\u5177\u6709append, insert, remove, sort\u7b49\u65b9\u6cd5\u3002 \u5728\u4ee5\u4e0b\u8ba8\u8bba\u4e2d\uff0c\u6211\u4eec\u4f7f\u7528\u65b9\u6cd5\u4e00\u8bcd\u5c06\u4e13\u6307\u7c7b\u5b9e\u4f8b\u5bf9\u8c61\u7684\u65b9\u6cd5\uff0c\u9664\u975e\u53e6\u5916\u660e\u786e\u8bf4\u660e\u3002 \u5b9e\u4f8b\u5bf9\u8c61\u7684\u6709\u6548\u65b9\u6cd5\u540d\u79f0\u4f9d\u8d56\u4e8e\u5176\u6240\u5c5e\u7684\u7c7b\u3002 \u6839\u636e\u5b9a\u4e49\uff0c\u4e00\u4e2a\u7c7b\u5b9a\u4e49\u4e2d\u6240\u5305\u542b\u7684\u6240\u6709\u51fd\u6570\u5bf9\u8c61\uff08function objects\uff09\u90fd\u79f0\u4e3a\u5c5e\u6027\u3002 \u56e0\u6b64\u5728\u4e0a\u9762\u7684\u793a\u4f8b\u4e2d\uff0c x.f \u662f\u6709\u6548\u7684\u65b9\u6cd5\u5f15\u7528\uff0c\u56e0\u4e3a MyClass.f \u662f\u4e00\u4e2a\u51fd\u6570\uff0c\u800c x.i \u4e0d\u662f\u65b9\u6cd5\uff0c\u56e0\u4e3a MyClass.i \u4e0d\u662f\u51fd\u6570\u3002\u4f46\u662f x.f \u4e0e MyClass.f \u5e76\u4e0d\u662f\u4e00\u56de\u4e8b\uff0c x.f \u662f\u4e00\u4e2a**\u65b9\u6cd5\u5bf9\u8c61**\uff0c\u800c MyClass.f \u662f\u4e00\u4e2a**\u51fd\u6570\u5bf9\u8c61**\u3002\u5dee\u522b\u5728\u4e8e f() \u662f\u5426\u4e0e\u5b9e\u4f8b\u7ed1\u5b9a\uff0c\u672a\u7ed1\u5b9a\uff0c\u5c31\u662f\u51fd\u6570\uff0c\u7ed1\u5b9a\uff0c\u5c31\u662f\u65b9\u6cd5\u3002 class MyClass : \"\"\"A simple example class\"\"\" i = 12345 def f ( self ): return 'hello world' def __init__ ( self ): self . data = [] x = MyClass () print ( MyClass . f ( 0 )) # hello world print ( x . f ()) # hello world print ( MyClass . f ) # print ( x . f ) # > print ( type ( MyClass . f )) # print ( type ( x . f )) # \u8fd9\u91cc\u505a\u4e2a\u5c0f\u7ed3\uff1a \u51fd\u6570(function)\u662fPython\u4e2d\u4e00\u4e2a\u53ef\u8c03\u7528\u5bf9\u8c61(callable), \u65b9\u6cd5(method)\u662f\u4e00\u79cd\u7279\u6b8a\u7684\u51fd\u6570\u3002 \u4e00\u4e2a\u53ef\u8c03\u7528\u5bf9\u8c61\u662f\u65b9\u6cd5\u548c\u51fd\u6570\uff0c\u548c\u8fd9\u4e2a\u5bf9\u8c61\u65e0\u5173\uff0c\u4ec5\u548c\u8fd9\u4e2a\u5bf9\u8c61\u662f\u5426\u4e0e\u7c7b\u6216\u5b9e\u4f8b\u7ed1\u5b9a\u6709\u5173\uff08bound method\uff09\u3002 \u9759\u6001\u65b9\u6cd5\u6ca1\u6709\u548c\u4efb\u4f55\u7c7b\u6216\u5b9e\u4f8b\u7ed1\u5b9a\uff0c\u6240\u4ee5**\u9759\u6001\u65b9\u6cd5\u662f\u4e2a\u51fd\u6570**\u3002","title":"\u5b9e\u4f8b\u5bf9\u8c61 Instance Objects"},{"location":"python/Foundation/ch04/#method-objects","text":"\u5728 MyClass \u793a\u4f8b\u4e2d\uff0c x.f() \u662f\u4e00\u4e2a\u65b9\u6cd5\u5bf9\u8c61\uff0c\u88ab\u8c03\u7528\u540e\uff0c\u5c06\u8fd4\u56de\u5b57\u7b26\u4e32 'hello world' \u3002\u53ef\u4ee5\u7acb\u5373\u8c03\u7528\uff0c\u4e5f\u53ef\u4ee5\u4fdd\u5b58\u8d77\u6765\u4ee5\u540e\u518d\u8c03\u7528 xf = x.f \u3002 \u867d\u7136 f() \u7684\u51fd\u6570\u5b9a\u4e49\u6307\u5b9a\u4e86\u4e00\u4e2a\u53c2\u6570\uff0c\u4f46\u4e0a\u9762\u4f8b\u5b50\u4e2d\u8c03\u7528 x.f() \u65f6\u5e76\u6ca1\u6709\u5e26\u53c2\u6570\uff0c\u4e5f\u6ca1\u6709\u5f15\u53d1\u5f02\u5e38\u62a5\u9519\u3002\u539f\u56e0\u5728\u4e8e\uff0c \u65b9\u6cd5(method)\u7684\u7279\u6b8a\u4e4b\u5904\u5c31\u5728\u4e8e\u5b9e\u4f8b\u5bf9\u8c61\u4f1a\u4f5c\u4e3a\u51fd\u6570\u7684\u7b2c\u4e00\u4e2a\u53c2\u6570\u88ab\u4f20\u5165\u3002 \u8c03\u7528 x.f() \u5176\u5b9e\u5c31\u76f8\u5f53\u4e8e MyClass.f(x) \u3002 \u603b\u4e4b\uff0c\u8c03\u7528\u4e00\u4e2a\u5177\u6709 n \u4e2a\u53c2\u6570\u7684\u65b9\u6cd5(method)\u5c31\u76f8\u5f53\u4e8e\u8c03\u7528\u518d\u591a\u4e00\u4e2a\u53c2\u6570\u7684\u5bf9\u5e94\u51fd\u6570\uff0c\u8fd9\u4e2a\u53c2\u6570\u503c\u4e3a\u65b9\u6cd5\u6240\u5c5e\u5b9e\u4f8b\u5bf9\u8c61\uff0c \u4f4d\u7f6e\u5728\u5176\u4ed6\u53c2\u6570\u4e4b\u524d \u3002 \u5f53\u4e00\u4e2a\u5b9e\u4f8b\u7684\u975e\u6570\u636e\u5c5e\u6027\u88ab\u5f15\u7528\u65f6\uff0c\u5c06\u641c\u7d22\u5b9e\u4f8b\u6240\u5c5e\u7684\u7c7b\u3002 \u5982\u679c\u88ab\u5f15\u7528\u7684\u5c5e\u6027\u540d\u79f0\u662f\u7c7b\u4e2d\u4e00\u4e2a\u6709\u6548\u7684\u51fd\u6570\u5bf9\u8c61\uff0c\u5219\u4f1a\u521b\u5efa\u4e00\u4e2a\u62bd\u8c61\u7684\u5bf9\u8c61\uff0c\u901a\u8fc7\u6253\u5305\uff08parking\uff0c\u5373\u6307\u5411\uff09\u5339\u914d\u5230\u7684\u5b9e\u4f8b\u5bf9\u8c61\u548c\u51fd\u6570\u5bf9\u8c61\uff0c\u8fd9\u4e2a\u62bd\u8c61\u5bf9\u8c61\u5c31\u662f\u65b9\u6cd5\u5bf9\u8c61\u3002 \u5f53\u5e26\u53c2\u6570\u8c03\u7528\u65b9\u6cd5\u5bf9\u8c61\u65f6\uff0c\u5c06\u57fa\u4e8e\u5b9e\u4f8b\u5bf9\u8c61\u548c\u53c2\u6570\u5217\u8868\u6784\u5efa\u4e00\u4e2a\u65b0\u7684\u53c2\u6570\u5217\u8868\uff0c\u5e76\u4f7f\u7528\u8fd9\u4e2a\u65b0\u53c2\u6570\u5217\u8868\u8c03\u7528\u76f8\u5e94\u7684\u51fd\u6570\u5bf9\u8c61\u3002","title":"\u65b9\u6cd5\u5bf9\u8c61 Method Objects"},{"location":"python/Foundation/ch04/#class-and-instance-variables","text":"\u4e00\u822c\u6765\u8bf4\uff0c**\u5b9e\u4f8b\u53d8\u91cf**\u7528\u4e8e\u6bcf\u4e2a\u5b9e\u4f8b\u7684\u552f\u4e00\u6570\u636e\uff0c\u800c**\u7c7b\u53d8\u91cf**\u7528\u4e8e\u7c7b\u7684\u6240\u6709\u5b9e\u4f8b\u5171\u4eab\u7684\u5c5e\u6027\u548c\u65b9\u6cd5: class Dog : kind = 'canine' # class variable shared by all instances def __init__ ( self , name ): self . name = name # instance variable unique to each instance d = Dog ( 'Fido' ) e = Dog ( 'Buddy' ) print ( d . kind ) # shared by all dogs # 'canine' print ( e . kind ) # shared by all dogs # 'canine' print ( d . name ) # unique to d instance # 'Fido' print ( e . name ) # unique to e instance # 'Buddy' \u4e0b\u4ee3\u7801\u4e2d\u7684 tricks \u5217\u8868\u4e0d\u5e94\u8be5\u88ab\u7528\u4f5c\u7c7b\u53d8\u91cf\uff0c\u56e0\u4e3a\u6240\u6709\u7684 Dog \u5b9e\u4f8b\u5c06\u53ea\u5171\u4eab\u4e00\u4e2a\u5355\u72ec\u7684\u5217\u8868: class Dog : kind = 'canine' # class variable shared by all instances tricks = [] # mistaken use of a class variable def __init__ ( self , name ): self . name = name # instance variable unique to each instance def add_trick ( self , trick ): self . tricks . append ( trick ) d = Dog ( 'Fido' ) e = Dog ( 'Buddy' ) d . add_trick ( 'roll over' ) e . add_trick ( 'play dead' ) print ( d . tricks ) # ['roll over', 'play dead'] \u6b63\u786e\u7684\u7c7b\u8bbe\u8ba1\u5e94\u8be5\u4f7f\u7528\u5b9e\u4f8b\u53d8\u91cf: class Dog : kind = 'canine' # class variable shared by all instances def __init__ ( self , name ): self . name = name # instance variable unique to each instance self . tricks = [] # creates a new empty list for each dog def add_trick ( self , trick ): self . tricks . append ( trick ) d = Dog ( 'Fido' ) e = Dog ( 'Buddy' ) d . add_trick ( 'roll over' ) e . add_trick ( 'play dead' ) print ( d . tricks ) # ['roll over'] print ( e . tricks ) # ['play dead'] \u5982\u679c\u540c\u6837\u7684\u5c5e\u6027\u540d\u79f0\u540c\u65f6\u51fa\u73b0\u5728\u5b9e\u4f8b\u548c\u7c7b\u4e2d\uff0c\u5219\u5c5e\u6027\u67e5\u627e\u4f1a**\u4f18\u5148\u9009\u62e9\u5b9e\u4f8b**: class Warehouse : purpose = 'storage' region = 'west' w1 = Warehouse () print ( w1 . purpose , w1 . region ) # storage west w2 = Warehouse () w2 . region = 'east' # Instance W2 has higher priority than class print ( w2 . purpose , w2 . region ) # storage east \u6570\u636e\u5c5e\u6027\uff08Data attributes\uff09\u53ef\u4ee5\u88ab\u65b9\u6cd5\uff08method\uff09\u4ee5\u53ca\u4e00\u4e2a\u5bf9\u8c61\u7684\u666e\u901a\u7528\u6237\uff08ordinary users\uff09\uff08\u201c\u5ba2\u6237\u7aefClient\u201d\uff09\u6240\u5f15\u7528\u3002 \u6362\u53e5\u8bdd\u8bf4\uff0c\u7c7b\u4e0d\u80fd\u7528\u4e8e\u5b9e\u73b0\u7eaf\u62bd\u8c61\u6570\u636e\u7c7b\u578b\u3002 \u65b9\u6cd5\u7684\u7b2c\u4e00\u4e2a\u53c2\u6570\u5e38\u5e38\u88ab\u547d\u540d\u4e3a self \uff0c\u8fd9\u53ea\u662f\u4e00\u4e2a\u7ea6\u5b9a: self \u8fd9\u4e00\u540d\u79f0\u5728Python\u4e2d\u6ca1\u6709\u7279\u6b8a\u542b\u4e49\u3002 \u4f46\u662f\u9075\u5faa\u6b64\u7ea6\u5b9a\u4f1a\u4f7f\u5f97\u4ee3\u7801\u5177\u6709\u5f88\u597d\u7684\u53ef\u8bfb\u6027\u3002 \u4efb\u4f55\u4e00\u4e2a\u4f5c\u4e3a\u7c7b\u5c5e\u6027\uff08class attribute\uff09\u7684\u51fd\u6570\u5bf9\u8c61\uff08function object\uff09\u90fd\u4e3a\u8be5\u7c7b\u7684\u5b9e\u4f8b\u5b9a\u4e49\u4e86\u4e00\u4e2a\u76f8\u5e94\u65b9\u6cd5\u3002 \u51fd\u6570\u5b9a\u4e49\u7684\u6587\u672c\u5e76\u975e\u5fc5\u987b\u5305\u542b\u4e8e\u7c7b\u5b9a\u4e49\u4e4b\u5185\uff1a\u5c06\u4e00\u4e2a\u51fd\u6570\u5bf9\u8c61\u8d4b\u503c\u7ed9\u4e00\u4e2a\u5c40\u90e8\u53d8\u91cf\u4e5f\u662f\u53ef\u4ee5\u7684\u3002\u5982\u4e0b\u4f8b\u3002\u73b0\u5728 f , g \u548c h \u90fd\u662f\u7c7b C \u7684\u5f15\u7528\u51fd\u6570\u5bf9\u8c61\u7684\u5c5e\u6027\uff0c\u56e0\u800c\u5b83\u4eec\u5c31\u90fd\u662f\u7c7b C \u7684\u5b9e\u4f8b\u7684\u65b9\u6cd5\uff0c\u5176\u4e2d h \u5b8c\u5168\u7b49\u540c\u4e8e g \u3002\u4f46\u8bf7\u6ce8\u610f\uff0c\u4e0b\u9762\u8fd9\u4e2a\u4f8b\u5b50\u7684\u53ef\u8bfb\u6027\u975e\u5e38\u4e0d\u597d\u3002 # Function defined outside the class def f1 ( self , x , y ): return min ( x , x + y ) class C : f = f1 # Assign a function object to a local variable in the class def g ( self ): return 'hello world' h = g \u65b9\u6cd5\uff08methods\uff09\u53ef\u4ee5\u901a\u8fc7\u4f7f\u7528 self \u53c2\u6570\u7684\u65b9\u6cd5\u5c5e\u6027\uff08method attributes\uff09\u8c03\u7528\u5176\u4ed6\u65b9\u6cd5\uff08method\uff09: class Bag : def __init__ ( self ): self . data = [] def add ( self , x ): self . data . append ( x ) def addtwice ( self , x ): self . add ( x ) self . add ( x ) \u65b9\u6cd5\u53ef\u4ee5\u901a\u8fc7\u4e0e\u666e\u901a\u51fd\u6570\u76f8\u540c\u7684\u65b9\u5f0f\u5f15\u7528\u5168\u5c40\u540d\u79f0\u3002 \u4e0e\u65b9\u6cd5\u76f8\u5173\u8054\u7684\u5168\u5c40\u4f5c\u7528\u57df\u5c31\u662f\u5305\u542b\u5176\u5b9a\u4e49\u7684\u6a21\u5757\u3002 \uff08\u7c7b\u6c38\u8fdc\u4e0d\u4f1a\u88ab\u4f5c\u4e3a\u5168\u5c40\u4f5c\u7528\u57df\u3002\uff09 \u867d\u7136\u6211\u4eec\u5f88\u5c11\u4f1a\u6709\u5145\u5206\u7684\u7406\u7531\u5728\u65b9\u6cd5\u4e2d\u4f7f\u7528\u5168\u5c40\u4f5c\u7528\u57df\uff0c\u4f46\u5168\u5c40\u4f5c\u7528\u57df\u5b58\u5728\u8bb8\u591a\u5408\u7406\u7684\u4f7f\u7528\u573a\u666f\uff1a\u4e3e\u4e2a\u4f8b\u5b50\uff0c\u5bfc\u5165\u5230\u5168\u5c40\u4f5c\u7528\u57df\u7684\u51fd\u6570\u548c\u6a21\u5757\u53ef\u4ee5\u88ab\u65b9\u6cd5\u6240\u4f7f\u7528\uff0c\u5728\u5176\u4e2d\u5b9a\u4e49\u7684\u51fd\u6570\u548c\u7c7b\u4e5f\u4e00\u6837\u3002 \u901a\u5e38\uff0c\u5305\u542b\u8be5\u65b9\u6cd5\u7684\u7c7b\u672c\u8eab\u662f\u5728\u5168\u5c40\u4f5c\u7528\u57df\u4e2d\u5b9a\u4e49\u7684\u3002","title":"\u7c7b\u548c\u5b9e\u4f8b\u53d8\u91cf Class and Instance Variables"},{"location":"python/Foundation/ch04/#_1","text":"","title":"\u603b\u7ed3"},{"location":"python/Foundation/ch04/#_2","text":"\u4e00\u4e2a\u7c7b\u5b9a\u4e49\u7c7b\u6210\u5458\u5c5e\u6027\u548c\u6210\u5458\u65b9\u6cd5\u3002 \u4e00\u4e2a\u7c7b\u53ef\u4ee5\u5b9e\u4f8b\u5316\u591a\u4e2a\u5bf9\u8c61\uff0c\u6bcf\u4e2a\u5b9e\u4f8b\u5316\u5bf9\u8c61\u90fd\u662f\u72ec\u7acb\u7684\u3002 \u521b\u5efa\u7684\u7c7b\u5b9e\u4f8b\u5316\u5bf9\u8c61\uff0c\u4f1a\u5f15\u7528\u7236\u7c7b\u4e2d\u7684\u5c5e\u6027\u548c\u65b9\u6cd5\uff0c\u5e76\u4e0d\u4f1a\u628a\u7c7b\u7684\u5c5e\u6027\u548c\u65b9\u6cd5\u590d\u5236\u7ed9\u5bf9\u8c61\uff0c\u56e0\u6b64\uff1a \u5728\u8bbf\u95ee\u5b9e\u4f8b\u5316\u5bf9\u8c61\u7684\u5c5e\u6027\u548c\u65b9\u6cd5\u65f6\uff0c\u4f1a\u5148\u53bb\u627e\u5bf9\u8c61\u81ea\u5df1\u7684\u5c5e\u6027\u548c\u65b9\u6cd5\uff0c\u7136\u540e\u518d\u53bb\u5b9e\u4f8b\u5316\u8fd9\u4e2a\u5bf9\u8c61\u7684\u7c7b\u4e2d\u67e5\u627e\uff08\u5f15\u7528\uff09\u3002 \u5bf9\u8c61\u6210\u5458\u7684\u6dfb\u52a0\u548c\u4fee\u6539\uff0c\u90fd\u53ea\u4f1a\u5f71\u54cd\u5f53\u524d\u5bf9\u8c61\u81ea\u5df1\uff0c\u4e0d\u4f1a\u5f71\u54cd\u7c7b\u548c\u5176\u5b83\u5bf9\u8c61\u3002 \u5220\u9664\u5bf9\u8c61\u6210\u5458\u7684\u65f6\u5019\uff0c\u5fc5\u987b\u662f\u8be5\u5bf9\u8c61\u81ea\u5df1\u5177\u5907\u7684\u6210\u5458\u624d\u53ef\u4ee5\uff0c\u4e0d\u80fd\u5220\u9664\u7c7b\u4e2d\u5f15\u7528\u7684\u6210\u5458\u3002 \u5bf9\u7c7b\u6210\u5458\u7684\u64cd\u4f5c\uff0c\u4f1a\u5f71\u54cd\u8fd9\u4e2a\u7c7b\u521b\u5efa\u7684\u5bf9\u8c61\uff0c\u5305\u62ec\u4e4b\u524d\u521b\u5efa\u7684\u5bf9\u8c61\uff08\u5f15\u7528\uff09\u3002","title":"\u7c7b\u5b9a\u4e49\u5c0f\u7ed3"},{"location":"python/Foundation/ch04/#_3","text":"\u6210\u5458\u5c5e\u6027\uff1a \u8bbf\u95ee\uff1a ClassName.AttributeName \u4fee\u6539\uff1a ClassName.AttributeName = NewValue \uff0c\u7b49\u4e8e\u7ed9\u8fd9\u4e2a\u7c7b\u5bf9\u8c61\u521b\u5efa\u4e86\u4e00\u4e2a\u81ea\u5df1\u7684\u5c5e\u6027\uff0c\u901a\u8fc7\u8fd9\u4e2a\u7c7b\u521b\u5efa\u7684\u5bf9\u8c61\u90fd\u5177\u6709\u8fd9\u4e2a\u5c5e\u6027\u3002 \u6dfb\u52a0\uff1a ClassName.NewAttributeName = Value \uff0c\u7b49\u4e8e\u7ed9\u8fd9\u4e2a\u7c7b\u5bf9\u8c61\u521b\u5efa\u4e86\u4e00\u4e2a\u81ea\u5df1\u7684\u5c5e\u6027\uff0c\u901a\u8fc7\u8fd9\u4e2a\u7c7b\u521b\u5efa\u7684\u5bf9\u8c61\u90fd\u5177\u6709\u8fd9\u4e2a\u5c5e\u6027\u3002 \u5220\u9664\uff1a del ClassName.AttributeName \uff0c\u6ce8\u610f\uff0c\u53ea\u80fd\u5220\u9664\u7c7b\u5bf9\u8c61\u81ea\u5df1\u7684\u5c5e\u6027\uff0c\u901a\u8fc7\u8fd9\u4e2a\u7c7b\u521b\u5efa\u7684\u5bf9\u8c61\u90fd\u4e0d\u518d\u5177\u6709\u8fd9\u4e2a\u5c5e\u6027\u3002 \u6210\u5458\u65b9\u6cd5\uff1a \u8bbf\u95ee\uff1a ClassName.MethodName() \u4fee\u6539\uff1a ClassName.MethodName = NewFunction \uff0c\u7b49\u4e8e\u7ed9\u8fd9\u4e2a\u7c7b\u5bf9\u8c61\u521b\u5efa\u4e86\u4e00\u4e2a\u81ea\u5df1\u7684\u65b9\u6cd5\uff0c\u901a\u8fc7\u8fd9\u4e2a\u7c7b\u521b\u5efa\u7684\u5bf9\u8c61\u90fd\u5177\u6709\u8fd9\u4e2a\u65b9\u6cd5\u3002 \u6dfb\u52a0\uff1a ClassName.MethodName = Function \uff0c\u7b49\u4e8e\u7ed9\u8fd9\u4e2a\u7c7b\u5bf9\u8c61\u521b\u5efa\u4e86\u4e00\u4e2a\u81ea\u5df1\u7684\u65b9\u6cd5\uff0c\u901a\u8fc7\u8fd9\u4e2a\u7c7b\u521b\u5efa\u7684\u5bf9\u8c61\u90fd\u5177\u6709\u8fd9\u4e2a\u65b9\u6cd5\u3002 \u5220\u9664\uff1a del ClassName.MethodName \uff0c\u6ce8\u610f\uff0c\u53ea\u80fd\u5220\u9664\u7c7b\u5bf9\u8c61\u81ea\u5df1\u7684\u65b9\u6cd5\uff0c\u901a\u8fc7\u8fd9\u4e2a\u7c7b\u521b\u5efa\u7684\u5bf9\u8c61\u90fd\u4e0d\u518d\u5177\u6709\u8fd9\u4e2a\u65b9\u6cd5\u3002","title":"\u7c7b\u6210\u5458\u64cd\u4f5c\uff08\u4e0d\u63a8\u8350\uff09"},{"location":"python/Foundation/ch04/#self","text":"self \u53ea\u662f\u4e00\u4e2a\u5f62\u53c2\uff0c\u4e0d\u662f\u5173\u952e\u5b57\u3002 self \u5728\u65b9\u6cd5\uff08method\uff09\u4ee3\u8868\u5f53\u524d\u5bf9\u8c61\u81ea\u5df1\u3002\u524d\u9762\u63d0\u5230\u8fc7\uff0c\u65b9\u6cd5\u7684\u7b2c\u4e00\u4e2a\u53c2\u6570\u5e38\u5e38\u88ab\u547d\u540d\u4e3a self \uff0c\u8fd9\u53ea\u662f\u4e00\u4e2a\u7ea6\u5b9a\u3002 \u53ef\u4ee5\u4f7f\u7528 self \u5728\u7c7b\u5185\u90e8\u64cd\u4f5c\u6210\u5458\uff08\u6dfb\u52a0\u3001\u4fee\u6539\u3001\u5220\u9664\u7b49\uff09\u3002 \u65b9\u6cd5\u7684\u5206\u7c7b\uff1a \u542b\u6709self\u6216\u8005\u53ef\u4ee5\u63a5\u53d7\u5bf9\u8c61\u4f5c\u4e3a\u53c2\u6570\u7684\u65b9\u6cd5\uff0c\u79f0\u4e3a**\u975e\u7ed1\u5b9a\u7c7b\u65b9\u6cd5**\uff0c\u975e\u7ed1\u5b9a\u7c7b\u7684\u65b9\u6cd5\u53ef\u4ee5\u4f7f\u7528\u5bf9\u8c61\u53bb\u8bbf\u95ee\u3002 \u4e0d\u542b\u6709self\u6216\u8005\u4e0d\u80fd\u63a5\u53d7\u5bf9\u8c61\u4f5c\u4e3a\u53c2\u6570\u7684\u65b9\u6cd5\uff0c\u79f0\u4e3a**\u7ed1\u5b9a\u7c7b\u65b9\u6cd5**\uff0c\u7ed1\u5b9a\u65b9\u6cd5\u53ea\u80fd\u4f7f\u7528\u7c7b\u53bb\u8bbf\u95ee\u3002","title":"\u6210\u5458\u65b9\u6cd5\u4e2d\u7684self"},{"location":"python/Foundation/ch04/#_4","text":"\u9b54\u672f\u65b9\u6cd5\uff08Magic Method\uff09\u548c\u666e\u901a\u65b9\u6cd5\u4e00\u6837\uff0c\u90fd\u662f\u7c7b\u4e2d\u5b9a\u4e49\u7684\u6210\u5458\u65b9\u6cd5\u3002 \u9b54\u672f\u65b9\u6cd5\u540d\u79f0\u524d\u540e\u5404\u67092\u4e2a\u4e0b\u5212\u7ebf\uff0c\u6bd4\u5982 __init__ \u9b54\u672f\u65b9\u6cd5\u662f\u4e0d\u9700\u8981\u624b\u52a8\u8c03\u7528\u7684\uff0c\u4f1a\u5728\u67d0\u79cd\u60c5\u51b5\u4e0b\u81ea\u52a8\u89e6\u53d1\uff08\u81ea\u52a8\u6267\u884c\uff09\u3002 \u9b54\u672f\u65b9\u6cd5\u662f\u7cfb\u7edf\u5b9a\u4e49\u597d\u7684\uff0c\u4e0d\u662f\u7528\u6237\u5b9a\u4e49\u7684\u3002","title":"\u9b54\u672f\u65b9\u6cd5"},{"location":"python/Foundation/ch04/#__init__","text":"\u7c7b\u5b9e\u4f8b\u5316\u5bf9\u8c61\u521b\u5efa\u540e\u81ea\u52a8\u89e6\u53d1\u3002 __init__ \u521d\u59cb\u5316\u65b9\u6cd5\u53ef\u4ee5\u7528\u6765\u5728\u5bf9\u8c61\u5b9e\u4f8b\u5316\u540e\u5b8c\u6210\u5bf9\u8c61\u7684\u521d\u59cb\u5316\uff0c\u6bd4\u5982\u5c5e\u6027\u8d4b\u503c\uff0c\u65b9\u6cd5\u8c03\u7528\u7b49\u3002","title":"__init__\u521d\u59cb\u5316\u65b9\u6cd5\uff0c\u4e5f\u79f0\u4f5c**\u6784\u9020\u65b9\u6cd5**"},{"location":"python/Foundation/ch04/#__del__","text":"\u7c7b\u5b9e\u4f8b\u5316\u5bf9\u8c61\u88ab\u9500\u6bc1\u65f6\u81ea\u52a8\u89e6\u53d1\u3002 __del__ \u6790\u6784\u65b9\u6cd5\u53ef\u4ee5\u5728\u9500\u6bc1\u5bf9\u8c61\u65f6\u5b8c\u6210\u4e00\u4e9b\u7279\u6b8a\u4efb\u52a1\uff0c\u5173\u95ed\u5bf9\u8c61\u6253\u5f00\u7684\u4e00\u4e9b\u8d44\u6e90\uff0c\u5982\u6587\u4ef6\u7b49\u3002 \u6ce8\u610f\uff0c\u662f\u5bf9\u8c61\u88ab\u9500\u6bc1\u65f6\u89e6\u53d1\u4e86\u6790\u6784\u65b9\u6cd5\uff0c\u800c\u4e0d\u662f\u8fd9\u4e2a\u6790\u6784\u65b9\u6cd5\u9500\u6bc1\u4e86\u5bf9\u8c61\u3002 \u5bf9\u8c61\u9500\u6bc1\u7684\u60c5\u51b5\uff1a \u5f53\u7a0b\u5e8f\u6267\u884c\u5b8c\u6bd5\uff0c\u9500\u6bc1\u548c\u91ca\u653e\u5185\u5b58\u4e2d\u7684\u8d44\u6e90\u3002 \u4f7f\u7528 del \u5220\u9664\u65f6\u3002 \u5bf9\u8c61\u4e0d\u518d\u88ab\u4efb\u4f55\u5bf9\u8c61\u5f15\u7528\u65f6\uff0c\u4f1a\u81ea\u52a8\u9500\u6bc1\u3002 \u770b\u4e0b\u9762\u7684\u4f8b\u5b50\uff0c\u5bf9\u6bd4 bmw = Car('BMW') \u548c Car('BMW') \u6765\u7406\u89e3 init \u548c del \u7684\u89e6\u53d1\u673a\u5236\u3002 \u7f16\u8f91\u6587\u4ef6 file1.py class Car (): brand = \"\" def __init__ ( self , car_brand ): self . brand = car_brand print ( f \"initial method called, create { self . brand } car\" ) def __del__ ( self ): print ( f \"delete method called, destroy { self . brand } car\" ) bmw = Car ( 'BMW' ) vw = Car ( 'VW' ) \u6267\u884c\u4e0a\u9762\u7684\u4ee3\u7801 python3 file1.py \u5f97\u5230\u5982\u4e0b\u8f93\u51fa\uff0c\u5728\u7a0b\u5e8f\u6267\u884c\u5b8c\u6bd5\u65f6\uff0c\u4f9d\u6b21\u6267\u884c __del__ \u3002 initial method called , create BMW car initial method called , create VW car delete method called , destroy BMW car delete method called , destroy VW car \u7f16\u8f91\u6587\u4ef6 file2.py class Car (): brand = \"\" def __init__ ( self , car_brand ): self . brand = car_brand print ( f \"initial method called, create { self . brand } car\" ) def __del__ ( self ): print ( f \"delete method called, destroy { self . brand } car\" ) Car ( 'BMW' ) Car ( 'VW' ) \u6267\u884c\u4e0a\u9762\u7684\u4ee3\u7801 python3 file2.py \u5f97\u5230\u5982\u4e0b\u8f93\u51fa\uff1a initial method called , create BMW car delete method called , destroy BMW car initial method called , create VW car delete method called , destroy VW car","title":"__del__\u6790\u6784\u65b9\u6cd5"},{"location":"python/Foundation/ch04/#python_1","text":"\u4ece\u9b54\u672f\u65b9\u6cd5\u53ef\u4ee5\u5ef6\u7533\u5230Python\u7684**\u51fd\u6570\u5185\u7701**\uff0c\u51fd\u6570\u5185\u7701\u7684\u610f\u601d\u662f\u8bf4\uff0c\u5f53\u4f60\u62ff\u5230\u4e00\u4e2a\u201c\u51fd\u6570\u5bf9\u8c61\u201d\u7684\u65f6\u5019\uff0c\u4f60\u53ef\u4ee5\u7ee7\u7eed\u77e5\u9053\uff0c\u5b83\u7684\u540d\u5b57\uff0c\u53c2\u6570\u5b9a\u4e49\u7b49\u4fe1\u606f\u3002\u8fd9\u4e9b\u4fe1\u606f\u53ef\u4ee5\u901a\u8fc7\u51fd\u6570\u5bf9\u8c61\u7684\u5c5e\u6027\uff08\u4e00\u4e9b\u53cc\u4e0b\u5212\u7ebf\u7684\u9b54\u6cd5\u65b9\u6cd5\uff09\u5f97\u5230\u3002\u7b80\u8a00\u4e4b\uff0c\u5185\u7701\u662f\u5728\u8fd0\u884c\u65f6\u786e\u5b9a\u5bf9\u8c61\u7c7b\u578b\u7684\u80fd\u529b\u3002 \u4e0b\u9762\u7684\u4f8b\u5b50\u5217\u51fa\u4e86\u5e38\u89c4\u5bf9\u8c61\u6ca1\u6709\u800c\u51fd\u6570\u6709\u7684\u5c5e\u6027\u3002 class C : pass obj = C () def func (): pass sorted ( set ( dir ( obj )) - set ( dir ( func ))) # ['__weakref__'] sorted ( set ( dir ( func )) - set ( dir ( obj ))) # ['__annotations__', '__call__', '__closure__', '__code__', '__defaults__', '__get__', '__globals__', '__kwdefaults__', '__name__', '__qualname__'] \u4e0b\u8868\u603b\u7ed3\u4e86\u7528\u6237\u5b9a\u4e49\u7684\u51fd\u6570\u7684\u5c5e\u6027\u3002 \u4e0b\u9762\u7684\u4f8b\u5b50\u662f\u6f14\u793a\u4e86\u5728\u6307\u5b9a\u957f\u5ea6\u9644\u8fd1\u622a\u65ad\u5b57\u7b26\u4e32\u7684\u51fd\u6570\uff0c\u4ee5\u53ca\u63d0\u53d6\u5173\u4e8e\u51fd\u6570\u53c2\u6570\u7684\u4fe1\u606f\u7684\u65b9\u6cd5\u3002 \u53c2\u6570\u540d\u79f0\u5728 __code__.co_varnames \u4e2d\uff0c\u4f46\u8fd9\u91cc\u9762\u4e5f\u5305\u542b\u51fd\u6570\u5b9a\u4e49\u4f53\u4e2d\u521b\u5efa\u7684\u5c40\u90e8\u53d8\u91cf\u3002\u56e0\u6b64\uff0c\u53c2\u6570\u540d\u79f0\u662f\u524d N \u4e2a\u5b57\u7b26\u4e32\uff0c N \u7684\u503c\u7531 __code__.co_argcount \u786e\u5b9a\uff0c\u4f8b\u5b50\u91cc\u9762N\u662f2\uff0c\u5373\u53c2\u6570\u540d\u79f0\u662f text \u548c max_len \uff0c\u5c40\u90e8\u53d8\u91cf\u662f end \u3001 space_before \u3001 space_after \u3002 def clip ( text , max_len = 80 ): \"\"\" Get sub-string by the first blank before or after specified position. rfind() \u8fd4\u56de\u5b57\u7b26\u4e32\u6700\u540e\u4e00\u6b21\u51fa\u73b0\u7684\u4f4d\u7f6e\uff0c\u5982\u679c\u6ca1\u6709\u5339\u914d\u9879\u5219\u8fd4\u56de -1. \"\"\" end = None if len ( text ) > max_len : space_before = text . rfind ( ' ' , 0 , max_len ) if space_before >= 0 : end = space_before else : space_after = text . rfind ( ' ' , max_len ) if space_after >= 0 : end = space_after if end is None : end = len ( text ) return text [: end ] . rstrip () clip ( 'This is the string' , max_len = 10 ) # 'This is' clip . __defaults__ # (80,) clip . __code__ # \", line 1> clip . __code__ . co_varnames # ('text', 'max_len', 'end', 'space_before', 'space_after') clip . __code__ . co_argcount # 2 clip . __doc__ # '\\n Get sub-string by the first blank before or after specified position.\\n rfind() \u8fd4\u56de\u5b57\u7b26\u4e32\u6700\u540e\u4e00\u6b21\u51fa\u73b0\u7684\u4f4d\u7f6e\uff0c\u5982\u679c\u6ca1\u6709\u5339\u914d\u9879\u5219\u8fd4\u56de -1.\\n ' \u4e0a\u4f8b\u4e2d\uff0c\u53c2\u6570\u7684\u9ed8\u8ba4\u503c\u53ea\u80fd\u901a\u8fc7\u5b83\u4eec\u5728 __defaults__ \u5143\u7ec4\u4e2d\u7684\u4f4d\u7f6e\u786e\u5b9a\uff0c\u56e0\u6b64\u8981\u4ece\u540e\u5411\u524d\u626b\u63cf\u624d\u80fd\u628a\u53c2\u6570\u548c\u9ed8\u8ba4\u503c\u5bf9\u5e94\u8d77\u6765\uff0c\u6709\u4e9b\u4e0d\u5408\u7406\u3002\u5f15\u5165 inspect \u6a21\u5757\u540e\uff0c\u4e0a\u9762\u7684\u64cd\u4f5c\u5c31\u66f4\u5bb9\u6613\u4e86\u3002 inspect.signature \u51fd\u6570\u8fd4\u56de\u4e00\u4e2a inspect.Signature \u5bf9\u8c61\uff0c\u5b83\u6709\u4e00\u4e2a parameters \u5c5e\u6027\uff0c\u8fd9\u662f\u4e00\u4e2a\u6709\u5e8f\u6620\u5c04\uff0c\u628a\u53c2\u6570\u540d\u548c inspect.Parameter \u5bf9\u8c61\u5bf9\u5e94\u8d77\u6765\u3002\u5404\u4e2a Parameter \u5c5e\u6027\u4e5f\u6709\u81ea\u5df1\u7684\u5c5e\u6027\uff0c\u4f8b\u5982 name \u3001 default \u548c kind \u3002 from inspect import signature sig = signature ( clip ) type ( sig ) # print ( sig ) # (text, max_len=80) print ( str ( sig )) # (text, max_len=80) for name , param in sig . parameters . items (): print ( f ' { param . kind } : { name } = { param . default } ' ) # 1 : text = # 1 : max_len = 80 \u51fd\u6570\u6ce8\u89e3\u3002 Python 3 \u63d0\u4f9b\u4e86\u4e00\u79cd\u53e5\u6cd5\uff0c\u7528\u4e8e\u4e3a\u51fd\u6570\u58f0\u660e\u4e2d\u7684\u53c2\u6570\u548c\u8fd4\u56de\u503c\u9644\u52a0\u5143\u6570\u636e\u3002\u5bf9\u4e0a\u4f8b\u6dfb\u52a0\u6ce8\u89e3\u540e\u5982\u4e0b\u6240\u793a\uff0c\u4e8c\u8005\u552f\u4e00\u7684\u533a\u522b\u5728\u7b2c\u4e00\u884c\u3002 \u51fd\u6570\u58f0\u660e\u4e2d\u7684\u5404\u4e2a\u53c2\u6570\u53ef\u4ee5\u5728:\u4e4b\u540e\u589e\u52a0\u6ce8\u89e3\u8868\u8fbe\u5f0f\u3002 \u5982\u679c\u53c2\u6570\u6709\u9ed8\u8ba4\u503c\uff0c\u6ce8\u89e3\u653e\u5728\u53c2\u6570\u540d\u548c = \u53f7\u4e4b\u95f4\u3002 \u5982\u679c\u60f3\u6ce8\u89e3\u8fd4\u56de\u503c\uff0c\u5728)\u548c\u51fd\u6570\u58f0\u660e\u672b\u5c3e\u7684 : \u4e4b\u95f4\u6dfb\u52a0 -> \u548c\u4e00\u4e2a\u8868\u8fbe\u5f0f\u3002\u90a3\u4e2a\u8868\u8fbe\u5f0f\u53ef\u4ee5\u662f\u4efb\u4f55\u7c7b\u578b\u3002 \u6ce8\u89e3\u4e2d\u6700\u5e38\u7528\u7684\u7c7b\u578b\u662f\u7c7b\uff08\u5982 str \u6216 int \uff09\u548c\u5b57\u7b26\u4e32\uff08\u5982'int > 0'\uff09\u3002\u5728\u4e0b\u4f8b\u4e2d\uff0cmax_len\u53c2\u6570\u7684\u6ce8\u89e3\u7528\u7684\u662f\u5b57\u7b26\u4e32\u3002 \u6ce8\u89e3\u4e0d\u4f1a\u505a\u4efb\u4f55\u5904\u7406\uff0c\u53ea\u662f\u5b58\u50a8\u5728\u51fd\u6570\u7684 __annotations__ \u5c5e\u6027\uff08\u4e00\u4e2a\u5b57\u5178\uff09\u4e2d\u3002\u6362\u53e5\u8bdd\u8bf4\uff0c\u6ce8\u89e3\u5bf9Python\u89e3\u91ca\u5668\u6ca1\u6709\u4efb\u4f55\u610f\u4e49\u3002 \u6ce8\u89e3\u53ea\u662f\u5143\u6570\u636e \uff0c\u53ef\u4ee5\u4f9bIDE\u3001\u6846\u67b6\u548c\u88c5\u9970\u5668\u7b49\u5de5\u5177\u4f7f\u7528\u3002 return \u952e\u4fdd\u5b58\u7684\u662f\u8fd4\u56de\u503c\u6ce8\u89e3\uff0c\u5373\u4e0b\u4f8b\u4e2d\u51fd\u6570\u58f0\u660e\u91cc\u4ee5 -> \u6807\u8bb0\u7684\u90e8\u5206\u3002 def clip ( text : str , max_len : 'int > 0' = 80 ) -> str : \"\"\" Get sub-string by the first blank before or after specified position. rfind() \u8fd4\u56de\u5b57\u7b26\u4e32\u6700\u540e\u4e00\u6b21\u51fa\u73b0\u7684\u4f4d\u7f6e\uff0c\u5982\u679c\u6ca1\u6709\u5339\u914d\u9879\u5219\u8fd4\u56de -1. \"\"\" end = None if len ( text ) > max_len : space_before = text . rfind ( ' ' , 0 , max_len ) if space_before >= 0 : end = space_before else : space_after = text . rfind ( ' ' , max_len ) if space_after >= 0 : end = space_after if end is None : end = len ( text ) return text [: end ] . rstrip () clip ( 'This is the string' , max_len = 10 ) # 'This is' clip . __annotations__ # {'text': , 'max_len': 'int > 0', 'return': } signature \u51fd\u6570\u8fd4\u56de\u4e00\u4e2a Signature \u5bf9\u8c61\uff0c\u5b83\u6709\u4e00\u4e2a return_annotation \u5c5e\u6027\u548c\u4e00\u4e2a parameters \u5c5e\u6027\uff0c\u540e\u8005\u662f\u4e00\u4e2a\u5b57\u5178\uff0c\u628a\u53c2\u6570\u540d\u6620\u5c04\u5230 Parameter \u5bf9\u8c61\u4e0a\u3002\u6bcf\u4e2a Parameter \u5bf9\u8c61\u81ea\u5df1\u4e5f\u6709 annotation \u5c5e\u6027\u3002 from inspect import signature sig = signature ( clip ) print ( sig . return_annotation ) # for param in sig . parameters . values (): note = repr ( param . annotation ) . ljust ( 13 ) print ( f ' { note } : { param . name } = { param . default } ' ) # : text = # 'int > 0' : max_len = 80","title":"Python\u51fd\u6570\u5185\u7701\u5185\u7701"},{"location":"python/Foundation/ch05/","text":"Python\u9762\u5411\u5bf9\u8c61\u4e09\u5927\u7279\u6027 \u00b6 Python\u9762\u5411\u5bf9\u8c61\u4e09\u5927\u7279\u6027\uff1a \u5c01\u88c5 \u7ee7\u627f \u591a\u6001 \u5c01\u88c5 Encapsulation \u00b6 \u5c01\u88c5\u662f\u4f7f\u7528\u7279\u6b8a\u7684\u8bed\u6cd5\uff0c\u5bf9\u6210\u5458\u5c5e\u6027\u548c\u6210\u5458\u65b9\u6cd5\u8fdb\u884c\u5305\u88c5\uff0c\u9650\u5236\u4e00\u4e9b\u8bbf\u95ee\u548c\u64cd\u4f5c\uff0c\u8fbe\u5230\u4fdd\u62a4\u548c\u9690\u85cf\u7684\u76ee\u7684\u3002 \u5c01\u88c5\u673a\u5236\u4fdd\u8bc1\u4e86\u7c7b\u5185\u90e8\u6570\u636e\u7ed3\u6784\u7684\u5b8c\u6574\u6027\uff0c\u56e0\u4e3a\u4f7f\u7528\u7c7b\u7684\u7528\u6237\u65e0\u6cd5\u76f4\u63a5\u770b\u5230\u7c7b\u4e2d\u7684\u6570\u636e\u7ed3\u6784\uff0c\u53ea\u80fd\u4f7f\u7528\u7c7b\u5141\u8bb8\u516c\u5f00\u7684\u6570\u636e\uff0c\u5f88\u597d\u5730\u907f\u514d\u4e86\u5916\u90e8\u5bf9\u5185\u90e8\u6570\u636e\u7684\u5f71\u54cd\uff0c\u63d0\u9ad8\u4e86\u7a0b\u5e8f\u7684\u53ef\u7ef4\u62a4\u6027\u3002 \u5bf9\u4e00\u4e2a\u7c7b\u5b9e\u73b0\u826f\u597d\u7684\u5c01\u88c5\uff0c\u7528\u6237\u53ea\u80fd\u501f\u52a9\u66b4\u9732\u51fa\u6765\u7684\u7c7b\u65b9\u6cd5\u6765\u8bbf\u95ee\u6570\u636e\uff0c\u53ef\u4ee5\u5728\u8fd9\u4e9b\u66b4\u9732\u7684\u65b9\u6cd5\u4e2d\u52a0\u5165\u9002\u5f53\u7684\u63a7\u5236\u903b\u8f91\uff0c\u5373\u53ef\u63a7\u5236\u7528\u6237\u5bf9\u7c7b\u4e2d\u5c5e\u6027\u6216\u65b9\u6cd5\u7684\u64cd\u4f5c\u3002 \u5bf9\u7c7b\u8fdb\u884c\u826f\u597d\u7684\u5c01\u88c5\uff0c\u4e3b\u8981\u662f\u5185\u90e8\u4f7f\u7528\u5c01\u88c5\u7684\u6210\u5458\uff0c\u4e5f\u63d0\u9ad8\u4e86\u4ee3\u7801\u7684\u590d\u7528\u6027\u3002 \u7c7b\u6210\u5458\u5c01\u88c5\u7684\u7ea7\u522b\uff1a \u516c\u6709\u7684\uff08public\uff09 \u4fdd\u62a4\u7684\uff08protected\uff09\uff0c\u5728Python\u4e2d\u5e76\u6ca1\u6709\u5b9e\u73b0protected\u5c01\u88c5\uff0c\u5c5e\u4e8e\u5f00\u53d1\u8005\u7684\u7ea6\u5b9a\u4fd7\u6210\u3002 \u79c1\u6709\u7684\uff08private\uff09\uff0c\u5728Python\u4e2dprivate\u5c01\u88c5\u662f\u901a\u8fc7\u6539\u540d\u7b56\u7565\u6765\u5b9e\u73b0\u7684\uff0c\u5e76\u4e0d\u662f\u771f\u6b63\u7684\u79c1\u6709\u5316\u3002 \u8bbf\u95ee\u9650\u5236 \u5171\u6709\u7684public \u53d7\u4fdd\u62a4\u7684protected \u79c1\u6709\u7684private \u5728\u7c7b\u7684\u5185\u90e8 OK OK OK \u5728\u7c7b\u7684\u5916\u90e8 OK No (Python\u4e2d\u53ef\u4ee5) No \u770b\u4e0b\u9762\u7684\u4f8b\u5b50\u3002(\u53c2\u8003 \u79c1\u6709\u53d8\u91cfPrivate Variables ) name \u662f\u5171\u6709\u5c5e\u6027\uff0c\u53ef\u4ee5\u5728\u5916\u90e8\u8c03\u7528tom.name\u3002 _age \u662f\u53d7\u4fdd\u62a4\u7684\u5c5e\u6027\uff0c\u7406\u8bba\u4e0a\u5728\u5916\u90e8\u662f\u4e0d\u53ef\u8c03\u7528\u7684\uff0c\u4f46\u5728Python\u4e2d\u662f\u53ef\u4ee5\u8c03\u7528\u7684 tom._age \u3002 __phone \u662f\u79c1\u6709\u5c5e\u6027\uff0c\u5728\u5916\u90e8\u662f\u4e0d\u53ef\u8c03\u7528\u7684\uff0c tom.__get_phone() \u62a5\u9519\u201c\u5c5e\u6027\u4e0d\u5b58\u5728\u201d\u3002 \u5bf9\u5e94\u65b9\u6cd5\u4e5f\u662f\u7c7b\u4f3c\u3002 \u5728\u7c7b\u7684\u5185\u90e8\u5bf9\u53d7\u4fdd\u62a4\u5bf9\u8c61\u548c\u79c1\u6709\u5bf9\u8c61\u6ca1\u6709\u8bbf\u95ee\u9650\u5236\u3002 _get_age \u53ef\u4ee5\u8c03\u7528\u79c1\u6709\u5c5e\u6027 __phone \u3002 class Person (): name = 'name' # public _age = 0 # protected __phone = 'phone' # private def __init__ ( self , n , a , p ): self . name = n self . _age = a self . __phone = p def get_name ( self ): print ( f 'My name is { self . name } ' ) def _get_age ( self ): print ( f 'My age is { self . _age } ' ) print ( f 'My age is { self . __phone } ' ) def __get_phone ( self ): print ( f 'My phone is { self . __phone } ' ) tom = Person ( 'Tom' , 18 , 12345678 ) tom . name # 'Tom' tom . _age # 18 tom . __phone # AttributeError: 'Person' object has no attribute '__phone' tom . get_name () # My name is Tom tom . _get_age () # My age is 18 # My age is 12345678 tom . __get_phone () # AttributeError: 'Person' object has no attribute '__get_phone' \u7ee7\u627f Inheritance \u00b6 \u5728\u4e0d\u6307\u5b9a\u7ee7\u627f\u7684\u7236\u7c7b\u65f6\uff0c\u6240\u6709\u7c7b\u90fd\u7ee7\u627fobject\u7c7b\uff08\u7cfb\u7edf\u63d0\u4f9b\uff09\u3002 \u88ab\u5176\u5b83\u7c7b\u7ee7\u627f\u7684\u7c7b\uff0c\u79f0\u4e3a\u7236\u7c7b\uff0c\u6216\u8005\u57fa\u7c7b\uff0c\u6216\u8005\u8d85\u7c7b\u3002 \u7ee7\u627f\u5176\u5b83\u7c7b\u7684\u7c7b\uff0c\u79f0\u4e3a\u5b50\u7c7b\uff0c\u6216\u8005\u6d3e\u751f\u7c7b\uff08derived class\uff09\u3002 \u5b50\u7c7b\u7ee7\u627f\u7236\u7c7b\u540e\uff0c\u5c31\u62e5\u6709\u4e86\u7236\u7c7b\u4e2d\u7684\u6240\u6709\u6210\u5458\uff08\u9664\u4e86\u79c1\u6709\u6210\u5458\uff09\u3002 \u5b50\u7c7b\u7ee7\u627f\u7236\u7c7b\u540e\uff0c\u5e76\u4e0d\u4f1a\u628a\u7236\u7c7b\u7684\u6210\u5458\u590d\u5236\u7ed9\u5b50\u7c7b\uff0c\u800c\u662f\u5f15\u7528\u3002 \u5b50\u7c7b\u53ef\u4ee5\u76f4\u63a5\u8c03\u7528\u7236\u7c7b\u7684\u65b9\u6cd5 super().BaseClassName \u3002\u5982\u679c\u7236\u7c7b\u65b9\u6cd5\u6709\u53c2\u6570\u8981\u6c42\uff0c\u5b50\u7c7b\u8c03\u7528\u65f6\u4e5f\u6709\u53c2\u6570\u8981\u6c42\u3002 \u5b50\u7c7b\u7ee7\u627f\u7236\u7c7b\u540e\uff0c\u53ef\u4ee5\u91cd\u65b0\u5b9a\u4e49\u7236\u7c7b\u4e2d\u7684\u65b9\u6cd5\uff0c\u79f0\u4e3a**\u91cd\u5199\uff08Override\uff09**\u3002 \u5b50\u7c7b\u7ee7\u627f\u7236\u7c7b\u540e\uff0c\u5b9a\u4e49\u7236\u7c7b\u4e2d\u6ca1\u6709\u7684\u65b9\u6cd5\uff0c\u88ab\u79f0\u4e3a\u5bf9\u7236\u7c7b\u7684\u6269\u5c55\u3002 \u4e00\u4e2a\u7236\u7c7b\u53ef\u4ee5\u88ab\u591a\u4e2a\u5b50\u7c7b\u7ee7\u627f\u3002 **\u6d3e\u751f\u7c7b\uff08derived class\uff09**\u5b9a\u4e49\u7684\u8bed\u6cd5\u5982\u4e0b\u6240\u793a: class BaseClassName (): < statement - 1 > . . . < statement - N > class DerivedClassName ( BaseClassName ): < statement - 1 > . . . < statement - N > \u540d\u79f0 BaseClassName \u5fc5\u987b\u5b9a\u4e49\u4e8e\u5305\u542b\u6d3e\u751f\u7c7b\u5b9a\u4e49\u7684\u4f5c\u7528\u57df\u4e2d\u3002 \u4e5f\u5141\u8bb8\u7528\u5176\u4ed6\u4efb\u610f\u8868\u8fbe\u5f0f\u4ee3\u66ff\u57fa\u7c7b\u540d\u79f0\u6240\u5728\u7684\u4f4d\u7f6e\uff0c\u4f8b\u5982\uff0c\u5f53\u57fa\u7c7b\u5b9a\u4e49\u5728\u53e6\u4e00\u4e2a\u6a21\u5757\u4e2d\u7684\u65f6\u5019: class DerivedClassName ( modname . BaseClassName ): \u6d3e\u751f\u7c7b\u5b9a\u4e49\u7684\u6267\u884c\u8fc7\u7a0b\u4e0e\u57fa\u7c7b\u76f8\u540c\u3002 \u5f53\u6784\u9020\u7c7b\u5bf9\u8c61\u65f6\uff0c\u57fa\u7c7b\u4f1a\u88ab\u8bb0\u4f4f\u3002 \u6b64\u4fe1\u606f\u5c06\u88ab\u7528\u6765\u89e3\u6790\u5c5e\u6027\u5f15\u7528\uff1a\u5982\u679c\u8bf7\u6c42\u7684\u5c5e\u6027\u5728\u7c7b\u4e2d\u627e\u4e0d\u5230\uff0c\u641c\u7d22\u5c06\u8f6c\u5f80\u57fa\u7c7b\u4e2d\u8fdb\u884c\u67e5\u627e\u3002 \u5982\u679c\u57fa\u7c7b\u672c\u8eab\u4e5f\u6d3e\u751f\u81ea\u5176\u4ed6\u67d0\u4e2a\u7c7b\uff0c\u5219\u6b64\u89c4\u5219\u5c06\u88ab\u9012\u5f52\u5730\uff08recursively\uff09\u5e94\u7528\u3002 \u6d3e\u751f\u7c7b\u7684\u5b9e\u4f8b\u5316\u6ca1\u6709\u4efb\u4f55\u7279\u6b8a\u4e4b\u5904: DerivedClassName() \u4f1a\u521b\u5efa\u8be5\u7c7b\u7684\u4e00\u4e2a*\u65b0\u5b9e\u4f8b*\u3002 \u65b9\u6cd5\u5f15\u7528\u5c06\u6309\u4ee5\u4e0b\u65b9\u5f0f\u89e3\u6790\uff1a\u641c\u7d22\u76f8\u5e94\u7684\u7c7b\u5c5e\u6027\uff0c\u5982\u6709\u5fc5\u8981\u5c06\u6309\u57fa\u7c7b\u7ee7\u627f\u94fe\u9010\u6b65\u5411\u4e0b\u67e5\u627e\uff0c\u5982\u679c\u4ea7\u751f\u4e86\u4e00\u4e2a\u51fd\u6570\u5bf9\u8c61\u5219\u65b9\u6cd5\u5f15\u7528\u5c31\u751f\u6548\u3002 \u6d3e\u751f\u7c7b\u53ef\u80fd\u4f1a\u91cd\u5199\uff08override\uff09\u5176\u57fa\u7c7b\u7684\u65b9\u6cd5\u3002 \u56e0\u4e3a\u65b9\u6cd5\u5728\u8c03\u7528\u540c\u4e00\u5bf9\u8c61\u7684\u5176\u4ed6\u65b9\u6cd5\u65f6\u6ca1\u6709\u7279\u6b8a\u6743\u9650\uff0c\u6240\u4ee5\u8c03\u7528\u540c\u4e00\u57fa\u7c7b\u4e2d\u5b9a\u4e49\u7684\u53e6\u4e00\u65b9\u6cd5\u7684\u57fa\u7c7b\u65b9\u6cd5\u6700\u7ec8\u53ef\u80fd\u4f1a\u8c03\u7528\u8986\u76d6\u5b83\u7684\u6d3e\u751f\u7c7b\u7684\u65b9\u6cd5\u3002 \u5728\u6d3e\u751f\u7c7b\u4e2d\u7684\u91cd\u8f7d\u65b9\u6cd5\uff08overriding method\uff09\u5b9e\u9645\u4e0a\u53ef\u80fd\u60f3\u8981\u6269\u5c55\u800c\u975e\u7b80\u5355\u5730\u66ff\u6362\u540c\u540d\u7684\u57fa\u7c7b\u65b9\u6cd5\u3002 \u6709\u4e00\u79cd\u65b9\u5f0f\u53ef\u4ee5\u7b80\u5355\u5730\u76f4\u63a5\u8c03\u7528\u57fa\u7c7b\u65b9\u6cd5\uff1a\u5373\u8c03\u7528 BaseClassName.methodname(self, arguments) \u3002 \u8bf7\u6ce8\u610f\uff0c\u4ec5\u5f53\u6b64\u57fa\u7c7b\u53ef\u5728\u5168\u5c40\u4f5c\u7528\u57df\u4e2d\u4ee5 BaseClassName \u7684\u540d\u79f0\u88ab\u8bbf\u95ee\u65f6\u65b9\u53ef\u4f7f\u7528\u6b64\u65b9\u5f0f\u3002 Python\u6709\u4e24\u4e2a\u5185\u7f6e\u51fd\u6570\u53ef\u88ab\u7528\u4e8e\u7ee7\u627f\u673a\u5236\uff1a \u4f7f\u7528 isinstance() \u6765\u68c0\u67e5\u4e00\u4e2a\u5b9e\u4f8b\u7684\u7c7b\u578b: isinstance(obj, int) \u4ec5\u4f1a\u5728 obj.__class__ \u4e3a int \u6216\u67d0\u4e2a\u6d3e\u751f\u81ea int \u7684\u7c7b\u65f6\u4e3a True \u3002 \u4f7f\u7528 issubclass() \u6765\u68c0\u67e5\u7c7b\u7684\u7ee7\u627f\u5173\u7cfb: issubclass(bool, int) \u4e3a True \uff0c\u56e0\u4e3a bool \u662f int \u7684\u5b50\u7c7b\u3002 \u4f46\u662f\uff0c issubclass(float, int) \u4e3a False \uff0c\u56e0\u4e3a float \u4e0d\u662f int \u7684\u5b50\u7c7b\u3002 \u591a\u91cd\u7ee7\u627f Multiple Inheritance \u00b6 \u5355\u7ee7\u627f\uff08single-inheritance\uff09\uff1a\u4e00\u4e2a\u7c7b\u53ea\u80fd\u7ee7\u627f\u4e00\u4e2a\u7236\u7c7b\u65b9\u5f0f\u3002 class DerivedClassName ( BaseClassName ): < statement - 1 > . . . < statement - N > \u591a\u7ee7\u627f\uff08Multiple Inheritance\uff09\uff1a\u4e00\u4e2a\u7c7b\u53bb\u7ee7\u627f\u591a\u4e2a\u7c7b\u7684\u65b9\u5f0f\u3002\u5b9a\u4e49\u8bed\u53e5\u5982\u4e0b\u6240\u793a class DerivedClassName ( Base1 , Base2 , Base3 ): < statement - 1 > . . . < statement - N > \u5728\u6700\u7b80\u5355\u7684\u60c5\u51b5\u4e0b\uff0c\u641c\u7d22\u4ece\u7236\u7c7b\u6240\u7ee7\u627f\u5c5e\u6027\u7684\u64cd\u4f5c\u662f\u6df1\u5ea6\u4f18\u5148\uff08depth-first\uff09\u3001\u4ece\u5de6\u81f3\u53f3\uff08left-to-right\uff09\u7684\uff0c\u5f53\u5c42\u6b21\u7ed3\u6784\u4e2d\u5b58\u5728\u91cd\u53e0\u65f6\u4e0d\u4f1a\u5728\u540c\u4e00\u4e2a\u7c7b\u4e2d\u641c\u7d22\u4e24\u6b21\u3002 \u56e0\u6b64\uff0c\u5982\u679c\u67d0\u4e00\u5c5e\u6027\u5728 DerivedClassName \u4e2d\u672a\u627e\u5230\uff0c\u5219\u4f1a\u5230 Base1 \u4e2d\u641c\u7d22\u5b83\uff0c\u7136\u540e\uff08\u9012\u5f52\u5730\uff09\u5230 Base1 \u7684\u57fa\u7c7b\u4e2d\u641c\u7d22\uff0c\u5982\u679c\u5728\u90a3\u91cc\u672a\u627e\u5230\uff0c\u518d\u5230 Base2 \u4e2d\u641c\u7d22\uff0c\u4f9d\u6b64\u7c7b\u63a8\u3002 \u771f\u5b9e\u60c5\u51b5\u66f4\u590d\u6742\uff1b\u65b9\u6cd5\u89e3\u6790\u987a\u5e8f\u4f1a\u52a8\u6001\u6539\u53d8\u4ee5\u652f\u6301\u5bf9 super() \u7684\u534f\u540c\u8c03\u7528\u3002 \u8fd9\u79cd\u65b9\u5f0f\u5728\u67d0\u4e9b\u5176\u4ed6\u591a\u91cd\u7ee7\u627f\u578b\u8bed\u8a00\u4e2d\u88ab\u79f0\u4e3a**\u540e\u7eed\u65b9\u6cd5\u8c03\u7528\uff08call-next-method\uff09**\uff0c\u5b83\u6bd4**\u5355\u7ee7\u627f\uff08single-inheritance\uff09**\u8bed\u8a00\u4e2d\u7684 uper \u8c03\u7528\u66f4\u5f3a\u5927\u3002 \u52a8\u6001\u6539\u53d8\u987a\u5e8f\u662f\u6709\u5fc5\u8981\u7684\uff0c\u56e0\u4e3a\u6240\u6709\u591a\u91cd\u7ee7\u627f\u7684\u60c5\u51b5\u90fd\u4f1a\u663e\u793a\u51fa\u4e00\u4e2a\u6216\u66f4\u591a\u7684\u83f1\u5f62\u5173\u8054\uff08diamond relationships\uff09\uff08\u5373\u81f3\u5c11\u6709\u4e00\u4e2a\u7236\u7c7b\u53ef\u901a\u8fc7\u591a\u6761\u8def\u5f84\u88ab\u6700\u5e95\u5c42\u7c7b\u6240\u8bbf\u95ee\uff09\u3002 \u4f8b\u5982\uff0c\u6240\u6709\u7c7b\u90fd\u662f\u7ee7\u627f\u81ea object \uff0c\u56e0\u6b64\u4efb\u4f55\u591a\u91cd\u7ee7\u627f\u7684\u60c5\u51b5\u90fd\u63d0\u4f9b\u4e86\u4e00\u6761\u4ee5\u4e0a\u7684\u8def\u5f84\u53ef\u4ee5\u901a\u5411 object \u3002 \u4e3a\u4e86\u786e\u4fdd\u57fa\u7c7b\u4e0d\u4f1a\u88ab\u8bbf\u95ee\u4e00\u6b21\u4ee5\u4e0a\uff0c\u52a8\u6001\u7b97\u6cd5\u4f1a\u7528\u4e00\u79cd\u7279\u6b8a\u65b9\u5f0f\u5c06\u641c\u7d22\u987a\u5e8f\u7ebf\u6027\u5316\uff0c \u4fdd\u7559\u6bcf\u4e2a\u7c7b\u6240\u6307\u5b9a\u7684\u4ece\u5de6\u81f3\u53f3\u7684\u987a\u5e8f\uff0c\u53ea\u8c03\u7528\u6bcf\u4e2a\u7236\u7c7b\u4e00\u6b21\uff0c\u5e76\u4e14\u4fdd\u6301\u5355\u8c03\uff08monotonic\uff09\uff08\u5373\u4e00\u4e2a\u7c7b\u53ef\u4ee5\u88ab\u5b50\u7c7b\u5316\u800c\u4e0d\u5f71\u54cd\u5176\u7236\u7c7b\u7684\u4f18\u5148\u987a\u5e8f\uff09\u3002 \u603b\u800c\u8a00\u4e4b\uff0c\u8fd9\u4e9b\u7279\u6027\u4f7f\u5f97\u8bbe\u8ba1\u5177\u6709\u591a\u91cd\u7ee7\u627f\u7684\u53ef\u9760\u4e14\u53ef\u6269\u5c55\u7684\u7c7b\u6210\u4e3a\u53ef\u80fd\u3002 \u770b\u4e0b\u9762\u4f8b\u5b50\uff0c\u5b9a\u4e49\u4e863\u4e2a\u7c7b\u548c\u7ee7\u627f\u5173\u7cfb\u3002 class F (): def drink ( self ): print ( \"Drink Beer\" ) class M (): def drink ( self ): print ( \"Drink Red Wine\" ) class C ( F , M ): def drink ( self ): print ( \"Drink Water\" ) \u6267\u884c\u7ed3\u679c\u662f c = C () c . drink () # Drink Water \u65b9\u6cd51\uff1a\u6309\u7167mro\u8fdb\u884c\u7ee7\u627f\u67e5\u627e\u3002 \u5982\u679c\u628a C \u7c7b\u6539\u5199\u4e3a\u5982\u4e0b\uff0c\u53ef\u4ee5\u8c03\u7528\u7236\u7c7b\uff0c\u53c2\u7167 C \u7c7b\u7684mro\u8fdb\u884c\uff0c mro \u91cc\u9762\u7c7b F \u7684\u4e0a\u4e00\u7ea7\u662f\u7c7b M \uff0c\u6240\u4ee5\u7c7b F \u4e2d\u7684 super() \u5c31\u662f\u6307\u7c7b M \u3002 class C ( F , M ): def drink ( self ): super () . drink () print ( \"Drink Water\" ) c = C () c . drink () # Drink Beer # Drink Water C . mro () # [, , , ] \u65b9\u6cd52\uff1a\u201c\u6307\u540d\u9053\u59d3\u201d\u8c03\u7528\u3002\u5982\u679c\u628a C \u7c7b\u6539\u5199\u4e3a\u5982\u4e0b\uff0c\u53ef\u4ee5\u8c03\u7528 M \u7c7b\u3002 class C ( F , M ): def drink ( self ): M . drink ( self ) print ( \"Drink Water\" ) c = C () c . drink () # Drink Red Wine # Drink Water \u83f1\u5f62\u7ee7\u627f\u548c\u7ee7\u627f\u5173\u7cfb\u68c0\u6d4b \u00b6 \u83f1\u5f62\u7ee7\u627f\u7684\u63cf\u8ff0\u662f\uff0c\u7c7b A \u4f5c\u4e3a\u57fa\u7c7b\uff08\u8fd9\u91cc\u57fa\u7c7b\u662f\u6307\u975e object \u7c7b\uff09\uff0c\u7c7b B \u548c\u7c7b C \u540c\u65f6\u7ee7\u627f\u7c7b A \uff0c\u7136\u540e\u7c7b D \u53c8\u7ee7\u627f\u7c7b B \u548c\u7c7b C \uff0c\u5982\u4e0b\u56fe\uff0c\u770b\u8d77\u6765\u50cf\u4e2a\u94bb\u77f3\u7684\u5f62\u72b6\u3002 A / \\ B C \\ / D \u5728\u8fd9\u79cd\u7ed3\u6784\u4e2d\uff0c\u5728\u8c03\u7528\u987a\u5e8f\u4e0a\u5c31\u4f1a\u51fa\u73b0\u7591\u60d1\uff0c\u8c03\u7528\u987a\u5e8f\u7a76\u7adf\u662f\u4ee5\u4e0b\u54ea\u4e00\u79cd\u987a\u5e8f\u5462\uff1f D->B->A->C\uff08\u6df1\u5ea6\u4f18\u5148\uff09 D->B->C->A\uff08\u5e7f\u5ea6\u4f18\u5148\uff09 \u770b\u4e0b\u9762\u4ee3\u7801\uff0c\u5728Python3\u4e2d\uff0c**\u83f1\u5f62**\u7684\u591a\u7ee7\u627f\u5173\u7cfb\u662f\u6309\u7167D->B->C->A**\u5e7f\u5ea6\u4f18\u5148**\u7684\u641c\u7d22\u65b9\u5f0f\u3002 class A (): pass class B ( A ): def test ( self ): print ( \"init B.test()\" ) class C ( A ): def test ( self ): print ( \"init C.test()\" ) class D ( B , C ): pass d = D () d . test () # init B.test() D . mro () # [, , , , ] \u5bf9\u4e8e\u4e0b\u9762\u8fd9\u79cd**\u975e\u83f1\u5f62**\u7684\u591a\u7ee7\u627f\u5173\u7cfb\uff0c\u67e5\u627e\u987a\u5e8f\u662fA->B->E->C->F->D**\u6df1\u5ea6\u4f18\u5148**\u7684\u641c\u7d22\u65b9\u5f0f\u3002 E F | | B ( E ) C ( F ) D | | | \\ | / \\ | / A ( B , C , D ) \u4ee3\u7801\u5b9e\u73b0\uff1a class D (): def test ( self ): print ( \"init D.test()\" ) class F (): def test ( self ): print ( \"init F.test()\" ) class C ( F ): pass class E (): pass class B ( E ): pass class A ( B , C , D ): pass a = A () a . test () # init F.test() A . mro () # [, , , , , , ] \u603b\u7ed3\uff1a \u7ee7\u627f\u7ed3\u6784\u8981\u5c3d\u91cf\u7b80\u5355\uff0c\u4e0d\u8981\u8fc7\u4e8e\u590d\u6742\u3002 \u63a8\u8350\u4f7f\u7528minxins\u673a\u5236\uff0c\u5728\u591a\u7ee7\u627f\u80cc\u666f\u4e0b\uff0c\u6ee1\u8db3\u7ee7\u627f\u7684\u4ec0\u4e48\u662f\u4ec0\u4e48\u7684\u5173\u7cfb\uff08is-a\uff09 \u591a\u7ee7\u627f\u5173\u7cfb\u7684minxins\u673a\u5236 \u00b6 \u770b\u4e0b\u9762\u4f8b\u5b50\uff0c\u5982\u679c\u5728 Vehicle \u7c7b\u4e2d\u5b9a\u4e49\u4e86 fly \u7684\u65b9\u6cd5\uff0c\u4f1a\u5bfc\u81f4 Car(Vehicle) \u7684\u7ee7\u627f\u5173\u7cfb\u51fa\u73b0\u77db\u76fe\uff0c\u6c7d\u8f66\u5e76\u4e0d\u4f1a\u98de\uff0c\u4f46\u6309\u7167\u4e0a\u8ff0\u7ee7\u627f\u5173\u7cfb\uff0c\u6c7d\u8f66\u4e5f\u80fd\u98de\u4e86\u3002 \u4f46\u662f\u5982\u679c\u6c11\u822a\u98de\u673a\u548c\u76f4\u5347\u673a\u90fd\u5404\u81ea\u5199\u81ea\u5df1\u7684\u98de\u884cfly\u65b9\u6cd5\uff0c\u53c8\u8fdd\u80cc\u4e86\u4ee3\u7801\u5c3d\u53ef\u80fd\u91cd\u7528\u7684\u539f\u5219\u3002 class Vehicle : # \u4ea4\u901a\u5de5\u5177 def fly ( self ): ''' \u98de\u884c\u529f\u80fd\u76f8\u5e94\u7684\u4ee3\u7801 ''' print ( \"I am flying\" ) # \u6c11\u822a\u98de\u673a class CivilAircraft ( Vehicle ): pass # \u76f4\u5347\u98de\u673a class Helicopter ( Vehicle ): pass # \u6c7d\u8f66 class Car ( Vehicle ): pass Python\u4e2d\u6ca1\u6709\u7c7b\u4f3cJava\u63a5\u53e3interface\u7684\u529f\u80fd\uff0c\u4f46\u63d0\u4f9b\u4e86Mixins\u673a\u5236\u3002 Python\u5bf9\u4e8e Mixin \u7c7b\u7684\u547d\u540d\u65b9\u5f0f\u4e00\u822c\u4ee5 Mixin , able , ible \u4e3a\u540e\u7f00\u3002 Mixin \u7c7b\u5fc5\u987b\u529f\u80fd\u5355\u4e00\uff0c\u5982\u679c\u6709\u591a\u4e2a\u529f\u80fd\uff0c\u90a3\u5c31\u5199\u591a\u4e2aMixin\u7c7b\u3002 \u4e00\u4e2a\u7c7b\u53ef\u4ee5\u7ee7\u627f\u591a\u4e2a Mixin \u7c7b\uff0c\u4e3a\u4e86\u4fdd\u8bc1\u9075\u5faa\u7ee7\u627f\u7684\u201cis-a\u201d\u539f\u5219\uff0c\u53ea\u80fd\u7ee7\u627f\u4e00\u4e2a\u6807\u8bc6\u5176\u5f52\u5c5e\u542b\u4e49\u7684\u7236\u7c7b Mixin \u7c7b\u4e0d\u4f9d\u8d56\u4e8e\u5b50\u7c7b\u7684\u5b9e\u73b0\u3002 \u5b50\u7c7b\u5373\u4fbf\u6ca1\u6709\u7ee7\u627f\u8fd9\u4e2a Mixin \u7c7b\u7c7b\uff0c\u4e5f\u7167\u6837\u53ef\u4ee5\u5de5\u4f5c\uff0c\u5c31\u662f\u7f3a\u5c11\u4e86\u67d0\u4e2a\u529f\u80fd\u3002 \u6211\u4eec\u5b9a\u4e49\u7684 Mixin \u7c7b\u8d8a\u591a\uff0c\u5b50\u7c7b\u7684\u4ee3\u7801\u53ef\u8bfb\u6027\u5c31\u4f1a\u8d8a\u5dee\u3002 # \u4ea4\u901a\u5de5\u5177 class Vehicle : pass # \u4e3a\u5f53\u524d\u7c7b\u6df7\u5165\u4e00\u4e9b\u529f\u80fd\uff0c\u4e0d\u662f\u4e00\u4e2a\u5355\u7eaf\u7684\u7c7b class FlyableMixin : def fly ( self ): ''' \u98de\u884c\u529f\u80fd\u76f8\u5e94\u7684\u4ee3\u7801 ''' print ( \"I am flying\" ) # \u6c11\u822a\u98de\u673a class CivilAircraft ( FlyableMixin , Vehicle ): pass # \u76f4\u5347\u98de\u673a class Helicopter ( FlyableMixin , Vehicle ): pass # \u6c7d\u8f66 class Car ( Vehicle ): pass \u7ec4\u5408\uff08Class Combination\uff09 \u00b6 \u5728\u4e00\u4e2a\u7c7b\u4e2d\u4ee5\u53e6\u4e00\u4e2a\u7c7b\u7684\u5bf9\u8c61\u4f5c\u4e3a\u6570\u636e\u5c5e\u6027\uff0c\u79f0\u4e3a\u7c7b\u7684**\u7ec4\u5408**\u3002\u7ec4\u5408\u4e0e\u7ee7\u627f\u90fd\u662f\u7528\u6765\u89e3\u51b3\u4ee3\u7801\u7684\u91cd\u7528\u6027\u95ee\u9898\u3002 \u7ee7\u627f\u4f53\u73b0\u201c\u662f\u201d\u7684\u5173\u7cfb\uff0c\u5f53\u7c7b\u4e4b\u95f4\u6709\u5f88\u591a\u76f8\u540c\u4e4b\u5904\uff0c\u7528\u7ee7\u627f\u3002 \u7ec4\u5408\u4f53\u73b0\u201c\u6709\u201d\u7684\u5173\u7cfb\uff0c\u5f53\u7c7b\u4e4b\u95f4\u6709\u663e\u8457\u4e0d\u540c\uff0c\u4e00\u4e2a\u7c7b\u662f\u53e6\u4e00\u4e2a\u7c7b\u7684\u5c5e\u6027\u662f\uff0c\u7528\u7ec4\u5408\u3002 \u4e0b\u4f8b\u662f\u8ba1\u7b97\u5706\u73af\u7684\u9762\u79ef\u548c\u5468\u957f\uff0c\u5706\u73af\u662f\u7531\u4e24\u4e2a\u5706\u7ec4\u6210\u7684\uff0c\u5706\u73af\u7684\u9762\u79ef\u662f\u5916\u9762\u5706\u7684\u9762\u79ef\u51cf\u53bb\u5185\u90e8\u5706\u7684\u9762\u79ef\u3002\u5706\u73af\u7684\u5468\u957f\u662f\u5185\u90e8\u5706\u7684\u5468\u957f\u52a0\u4e0a\u5916\u90e8\u5706\u7684\u5468\u957f\u3002 \u8fd9\u4e2a\u4f8b\u5b50\u6f14\u793a\u4e86\u7c7b ring \u91cc\u9762\u7684\u5c5e\u6027 circle1 \u548c circle2 \u6b63\u662f\u53e6\u4e00\u4e2a\u7c7b Circle \u3002 from math import pi class Circle (): def __init__ ( self , r ): self . r = r def area ( self ): return pi * self . r * self . r def perimeter ( self ): return 2 * pi * self . r class Ring (): def __init__ ( self , r1 , r2 ): self . circle1 = Circle ( r1 ) self . circle2 = Circle ( r2 ) def area ( self ): return abs ( self . circle1 . area () - self . circle2 . area ()) def permiter ( self ): return self . circle1 . perimeter () + self . circle2 . perimeter () ring = Ring ( 5 , 8 ) print ( ring . area ()) # 122.52211349000193 print ( ring . permiter ()) # 81.68140899333463 \u4e0b\u9762\u7684\u4f8b\u5b50\u6f14\u793a\u4e86\u5982\u4f55\u901a\u8fc7\u4f20\u53c2\u7684\u65b9\u5f0f\u8fdb\u884c\u7c7b\u7684\u7ec4\u5408\u3002 class Birthday (): def __init__ ( self , year , month , day ): self . year = year self . month = month self . day = day class Course (): def __init__ ( self , course_name , course_period ): self . course_name = course_name self . course_period = course_period class Professor (): def __init__ ( self , name , gender , birth , course ): self . name = name self . gender = gender self . birth = birth self . course = course def teach ( self ): print ( f \"Professor name: { self . name } ; Gender: { self . gender } ; Birthday: { self . birth . year } - { self . birth . month }{ self . birth . day } , Course name: { self . course . course_name } and period: { self . course . course_period } \" ) prof = Professor ( 'Tom' , 'Male' , Birthday ( 1985 , 5 , 5 ), Course ( 'Chinese' , '2022/3/1 ~ 2022/6/30' )) prof . teach () # Professor name: Tom; Gender: Male; Birthday: 1985-55, Course name: Chinese and period: 2022/3/1 ~ 2022/6/30 \u591a\u6001 Polymorphism \u00b6 \u591a\u6001\u610f\u5473\u7740\u76f8\u540c\u7684\u51fd\u6570\u540d\u7528\u4e8e\u4e0d\u540c\u7684\u60c5\u5f62\u3002 \u5982\u4e0b\u4f8b\uff0c len() \u88ab\u7528\u4e8e\u4e0d\u540c\u7684\u60c5\u5f62\u3002 # len() being used for a string print ( len ( \"geeks\" )) # 5 # len() being used for a list print ( len ([ 10 , 20 , 30 ])) # 3 \u7c7b\u65b9\u6cd5\u7684\u591a\u6001\u6027 \u00b6 \u4e0b\u9762\u7684\u4ee3\u7801\u5c55\u793a\u4e86 Python \u5982\u4f55\u4ee5\u76f8\u540c\u7684\u65b9\u5f0f\u4f7f\u7528\u4e24\u79cd\u4e0d\u540c\u7684\u7c7b\u7c7b\u578b\u3002 \u6211\u4eec\u521b\u5efa\u4e86\u4e00\u4e2a\u904d\u5386\u5bf9\u8c61\u5143\u7ec4\u7684 for \u5faa\u73af\u3002 \u7136\u540e\u8c03\u7528\u65b9\u6cd5\u800c\u4e0d\u7528\u5173\u5fc3\u6bcf\u4e2a\u5bf9\u8c61\u662f\u54ea\u4e2a\u7c7b\u7c7b\u578b\u3002 \u6211\u4eec\u5047\u8bbe\u8fd9\u4e9b\u65b9\u6cd5\u5b9e\u9645\u4e0a\u5b58\u5728\u4e8e\u6bcf\u4e2a\u7c7b\u4e2d\u3002 class India (): def capital ( self ): print ( \"New Delhi is the capital of India.\" ) def language ( self ): print ( \"Hindi is the most widely spoken language of India.\" ) def type ( self ): print ( \"India is a developing country.\" ) class USA (): def capital ( self ): print ( \"Washington, D.C. is the capital of USA.\" ) def language ( self ): print ( \"English is the primary language of USA.\" ) def type ( self ): print ( \"USA is a developed country.\" ) obj_ind = India () obj_usa = USA () for country in ( obj_ind , obj_usa ): country . capital () country . language () country . type () # New Delhi is the capital of India. # Hindi is the most widely spoken language of India. # India is a developing country. # Washington, D.C. is the capital of USA. # English is the primary language of USA. # USA is a developed country. \u7ee7\u627f\u7684\u591a\u6001\u6027 \u00b6 \u5728 Python \u4e2d\uff0c\u591a\u6001\u5141\u8bb8\u6211\u4eec\u5728\u5b50\u7c7b\u4e2d\u5b9a\u4e49\u4e0e\u7236\u7c7b\u4e2d\u7684\u65b9\u6cd5\u540c\u540d\u7684\u65b9\u6cd5\u3002 \u5728\u7ee7\u627f\u4e2d\uff0c\u5b50\u7c7b\u7ee7\u627f\u7236\u7c7b\u7684\u65b9\u6cd5\u3002 \u4f46\u662f\uff0c\u53ef\u4ee5\u4fee\u6539\u4ece\u7236\u7c7b\u7ee7\u627f\u7684\u5b50\u7c7b\u4e2d\u7684\u65b9\u6cd5\u3002 \u8fd9\u5728\u4ece\u7236\u7c7b\u7ee7\u627f\u7684\u65b9\u6cd5\u4e0d\u592a\u9002\u5408\u5b50\u7c7b\u7684\u60c5\u51b5\u4e0b\u7279\u522b\u6709\u7528\u3002 \u5728\u8fd9\u79cd\u60c5\u51b5\u4e0b\uff0c\u6211\u4eec\u5728\u5b50\u7c7b\u4e2d\u91cd\u65b0\u5b9e\u73b0\u8be5\u65b9\u6cd5\u3002 \u8fd9\u79cd\u5728\u5b50\u7c7b\u4e2d\u91cd\u65b0\u5b9e\u73b0\u65b9\u6cd5\u7684\u8fc7\u7a0b\u79f0\u4e3a**\u65b9\u6cd5\u8986\u76d6\uff08Method Overriding\uff09**\u3002 class Bird : def intro ( self ): print ( \"There are many types of birds.\" ) def flight ( self ): print ( \"Most of the birds can fly but some cannot.\" ) class sparrow ( Bird ): def flight ( self ): print ( \"Sparrows can fly.\" ) class ostrich ( Bird ): def flight ( self ): print ( \"Ostriches cannot fly.\" ) obj_bird = Bird () obj_spr = sparrow () obj_ost = ostrich () obj_bird . intro () # There are many types of birds. obj_bird . flight () # Most of the birds can fly but some cannot. obj_spr . intro () # There are many types of birds. obj_spr . flight () # Sparrows can fly. obj_ost . intro () # There are many types of birds. obj_ost . flight () # Ostriches cannot fly. \u51fd\u6570\u548c\u5bf9\u8c61\u7684\u591a\u6001\u6027 \u00b6 \u6211\u4eec\u4e5f\u53ef\u4ee5\u521b\u5efa\u4e00\u4e2a\u53ef\u4ee5\u63a5\u53d7\u4efb\u4f55\u5bf9\u8c61\u7684\u51fd\u6570\uff0c\u5141\u8bb8\u591a\u6001\u6027\u3002 \u5728\u4e0b\u9762\u4f8b\u5b50\u4e2d\uff0c\u6211\u4eec\u521b\u5efa\u4e00\u4e2a\u540d\u4e3a func() \u7684\u51fd\u6570\uff0c\u4f20\u5165\u53c2\u6570\u662f obj \u7684\u5bf9\u8c61\u3002 \u5728\u8fd9\u79cd\u60c5\u51b5\u4e0b\uff0c\u6211\u4eec\u8c03\u7528\u4e09\u4e2a\u65b9\u6cd5\uff0c\u5373 capital() \u3001 language() \u548c type() \uff0c\u6bcf\u4e2a\u65b9\u6cd5\u90fd\u5b9a\u4e49\u5728 India \u548c USA \u4e24\u4e2a\u7c7b\u4e2d\u3002 \u6211\u4eec\u53ef\u4ee5\u4f7f\u7528\u76f8\u540c\u7684 func() \u51fd\u6570\u8c03\u7528\u5b83\u4eec\u7684\u52a8\u4f5c\uff1a class India (): def capital ( self ): print ( \"New Delhi is the capital of India.\" ) def language ( self ): print ( \"Hindi is the most widely spoken language of India.\" ) def type ( self ): print ( \"India is a developing country.\" ) class USA (): def capital ( self ): print ( \"Washington, D.C. is the capital of USA.\" ) def language ( self ): print ( \"English is the primary language of USA.\" ) def type ( self ): print ( \"USA is a developed country.\" ) def func ( obj ): obj . capital () obj . language () obj . type () obj_ind = India () obj_usa = USA () func ( obj_ind ) # New Delhi is the capital of India. # Hindi is the most widely spoken language of India. # India is a developing country. func ( obj_usa ) # Washington, D.C. is the capital of USA. # English is the primary language of USA. # USA is a developed country. \u9e2d\u5b50\u7c7b\u578b\uff08Ducking Typing\uff09\u548c\u767d\u9e45\u7c7b\u578b\uff08Goose Typing\uff09 \u00b6 \u5728Python\u4e2d\u5b9e\u73b0\u591a\u6001\u4e3b\u8981\u6709\u4e24\u79cd\u673a\u5236\uff1a\u767d\u9e45\u7c7b\u578b\u548c\u9e2d\u5b50\u7c7b\u578b\u3002\u767d\u9e45\u7c7b\u578b\u548c\u9e2d\u5b50\u7c7b\u578b\u4e0d\u4ec5\u662f\u4e24\u79cd\u673a\u5236\uff0c\u4e5f\u662f\u4e24\u79cd\u4e0d\u540c\u7684\u7f16\u7a0b\u98ce\u683c\u3002 \u4e0b\u9762\u662f\u4e00\u4e2a\u6253\u5370\u5546\u54c1\u4ef7\u683c\u7684\u4f8b\u5b50\uff0c\u5206\u522b\u7528\u9e2d\u5b50\u7c7b\u578b\u548c\u767d\u9e45\u7c7b\u578b\u5b9e\u73b0\u3002 \u9e2d\u5b50\u7c7b\u578b\u3002 \u5728\u9e2d\u5b50\u7c7b\u578b\u7684\u5b9e\u73b0\u4e2d\uff0c\u6211\u4eec\u53ea\u9700\u8981\u4fdd\u8bc1\u8c03\u7528 price \u65b9\u6cd5\u7684\u6bcf\u4e2a\u5bf9\u8c61\u90fd\u6709 price \u65b9\u6cd5\u5373\u53ef\u3002 class Food : def price ( self ): print ( \" {} price:$4\" . format ( __class__ . __name__ )) class Clothes : def price ( self ): print ( \" {} price:$5\" . format ( __class__ . __name__ )) class Coffee : def price ( self ): print ( \" {} price:$6\" . format ( __class__ . __name__ )) if __name__ == '__main__' : goods = [ Food (), Clothes (), Coffee ()] for good in goods : good . price () # Food price:$4 # Clothes price:$5 # Coffee price:$6 \u767d\u9e45\u7c7b\u578b\u3002 \u5728\u767d\u9e45\u7c7b\u578b\u4e2d\uff0c\u76f4\u63a5\u8ba9\u6240\u6709\u5bf9\u8c61\u7684\u7c7b\u7ee7\u627f\u7236\u7c7b Good \u4e2d\u7684\u62bd\u8c61\u65b9\u6cd5 price \u3002Python\u4e2d\u7684\u767d\u9e45\u7c7b\u578b\u673a\u5236\u5c31\u662f\u5f3a\u7c7b\u578b\u8bed\u8a00\u4e2d\u5b9e\u73b0\u591a\u6001\u7684\u6807\u51c6\u6a21\u5f0f\uff0c\u5373\u901a\u8fc7\u8c03\u53d6\u7236\u7c7b\u7684\u865a\u51fd\u6570\u6216\u8005\u7ee7\u627f\u7684\u51fd\u6570\u6765\u5b8c\u6210\u4e0d\u540c\u7684\u884c\u4e3a\u3002 import abc class Good ( abc . ABC ): @abc . abstractmethod def price ( self ): pass class Food ( Good ): def price ( self ): print ( \" {} price:$4\" . format ( __class__ . __name__ )) class Clothes ( Good ): def price ( self ): print ( \" {} price:$5\" . format ( __class__ . __name__ )) if __name__ == '__main__' : goods = [ Food (), Clothes (), Coffee ()] for good in goods : good . price () # Food price:$4 # Clothes price:$5 # Coffee price:$6 \u7c7b\u65b9\u6cd5\uff08Class method\uff09\u548c\u9759\u6001\u65b9\u6cd5\uff08Static Method\uff09 \u00b6 \u7c7b\u65b9\u6cd5\uff08Class method\uff09\u4e5f\u53eb\u7ed1\u5b9a\u65b9\u6cd5\uff0c\u5fc5\u987b\u628a\u7c7b\u4f5c\u4e3a\u4f20\u5165\u53c2\u6570\uff0c\u4f7f\u7528 cls \u4f5c\u4e3a\u7b2c\u4e00\u4e2a\u4f20\u5165\u53c2\u6570\uff0c\u800c\u9759\u6001\u65b9\u6cd5\uff08Static Method\uff09\uff0c\u4e5f\u53eb\u975e\u7ed1\u5b9a\u65b9\u6cd5\uff0c\u4e0d\u9700\u8981\u7279\u5b9a\u7684\u53c2\u6570\u3002 \u7c7b\u65b9\u6cd5\u662f\u7ed1\u5b9a\u5230\u7c7b\u7684\uff0c\u4e0d\u662f\u7ed1\u5b9a\u5230\u7c7b\u5bf9\u8c61\uff0c\u6240\u4ee5\u7c7b\u65b9\u6cd5\u53ef\u4ee5\u8bbf\u95ee\u6216\u4fee\u6539\u7c7b\uff0c\u5e76\u5bf9\u6240\u6709\u7c7b\u5b9e\u4f8b\u751f\u6548\u3002 \u9759\u6001\u65b9\u6cd5\u65e0\u6cd5\u76f4\u63a5\u8bbf\u95ee\u6216\u4fee\u6539\u7c7b\uff0c\u56e0\u4e3a\u9759\u6001\u65b9\u6cd5\u662f\u4e0d\u77e5\u9053\u7c7b\u672c\u8eab\u7684\uff0c\u9759\u6001\u65b9\u6cd5\u662f\u5c5e\u4e8e\u5de5\u5177\u7c7b\u65b9\u6cd5\uff0c\u57fa\u4e8e\u4f20\u5165\u7684\u53c2\u6570\u5b8c\u6210\u7279\u5b9a\u7684\u529f\u80fd\uff0c\u5176\u5b9e\u5c31\u662f\u4e00\u4e2a\u666e\u901a\u51fd\u6570\u800c\u5df2\u3002 Python\u4e2d\u4f7f\u7528 @classmethod \u88c5\u9970\u5668\uff08decorator\uff09\u6765\u521b\u5efa\u4e00\u4e2a\u7c7b\u65b9\u6cd5\uff0c\u7528@staticmethod\u88c5\u9970\u5668\u6765\u521b\u5efa\u4e00\u4e2a\u9759\u6001\u65b9\u6cd5\u3002 \u8bed\u6cd5\u683c\u5f0f\uff1a @classmethod def fun ( cls , arg1 , arg2 , ... ): \u5176\u4e2d\uff1a fun : \u9700\u8981\u8f6c\u6362\u6210\u7c7b\u65b9\u6cd5\u7684\u51fd\u6570 returns : \u51fd\u6570\u7684\u7c7b\u65b9\u6cd5 classmethod() \u65b9\u6cd5\u7ed1\u5b9a\u5230\u7c7b\u800c\u4e0d\u662f\u5bf9\u8c61\u3002\u7c7b\u65b9\u6cd5\u53ef\u4ee5\u88ab\u7c7b\u548c\u5bf9\u8c61\u8c03\u7528\u3002\u8fd9\u4e9b\u65b9\u6cd5\u53ef\u4ee5\u901a\u8fc7\u7c7b\u6216\u5bf9\u8c61\u8fdb\u884c\u8c03\u7528\u3002 \u4f8b1\uff1a\u521b\u5efa\u4e00\u4e2a\u7b80\u5355\u7684 classmethod \u3002 \u521b\u5efa\u4e00\u4e2a\u7c7b Training \uff0c\u6709\u7c7b\u53d8\u91cf course \u548c\u65b9\u6cd5 purchase \u3002 \u6211\u4eec\u901a\u8fc7\u628a\u51fd\u6570 Training.purchase \u4f20\u7ed9 classmethod() \uff0c\u628a\u8be5\u65b9\u6cd5\u8f6c\u6210\u7c7b\u65b9\u6cd5\uff0c\u7136\u540e\u76f4\u63a5\u8c03\u7528\u5b83\uff0c\u800c\u65e0\u9700\u5148\u521b\u5efa\u5bf9\u8c61\u3002 \u53ef\u4ee5\u770b\u51fa\u8f6c\u6362\u524d\u540e Training.purchase \u7684\u7c7b\u578b\u53d8\u5316\u3002 class Training : course = 'Python for Data Analysis' def purchase ( obj ): print ( \"Puchase course : \" , obj . course ) type ( Training . purchase ) # Training . purchase = classmethod ( Training . purchase ) Training . purchase () # Puchase course : Python for Data Analysis type ( Training . purchase ) # \u4f8b2\uff1a\u4f7f\u7528\u88c5\u9970\u5668 @classmethod \u521b\u5efa\u5de5\u5382\u7c7b\u3002 class Training : def __init__ ( self , course ): self . course = course @classmethod def purchase ( cls , course ): return cls ( course ) def display ( self ): print ( 'Purchase course: ' , self . course ) training = Training ( \"Python for Data Analysis\" ) training . display () # Purchase course: Python for Data Analysis \u4f8b3\uff1a\u901a\u8fc7 staticmethod() \u548c classmethod() \u6765\u68c0\u67e5\u4e00\u4e2aperson\u662f\u5426\u662fadult\u3002 person1\u662f\u901a\u8fc7\u59d3\u540d\u548c\u5e74\u9f84\u521b\u5efa\u7684\u5b9e\u4f8b\u3002person2\u662f\u901a\u8fc7\u59d3\u540d\u548c\u5e74\u4efd\u521b\u5efa\u7684\u5b9e\u4f8b\u3002 from datetime import date class Person : def __init__ ( self , name , age ): self . name = name self . age = age @classmethod def fromBirthYear ( cls , name , year ): return cls ( name , date . today () . year - year ) @staticmethod def isAdult ( age ): return age > 18 person1 = Person ( 'mayank' , 21 ) person2 = Person . fromBirthYear ( 'mayank' , 1996 ) print ( person1 . age ) # 21 print ( person2 . age ) # 26 print ( Person . isAdult ( 22 )) # True \u5c0f\u7ed3\uff1a \u82e5\u7c7b\u4e2d\u9700\u8981\u4e00\u4e2a\u529f\u80fd\uff0c\u8be5\u529f\u80fd\u7684\u5b9e\u73b0\u4ee3\u7801\u4e2d\u9700\u8981\u5f15\u7528\u5bf9\u8c61\uff0c\u5219\u5c06\u5176\u5b9a\u4e49\u6210\u5bf9\u8c61\u65b9\u6cd5\uff1b\u9700\u8981\u5f15\u7528\u7c7b\uff0c\u5219\u5c06\u5176\u5b9a\u4e49\u6210\u7c7b\u65b9\u6cd5\uff1b\u65e0\u9700\u5f15\u7528\u7c7b\u6216\u5bf9\u8c61\uff0c\u5219\u5c06\u5176\u5b9a\u4e49\u6210\u9759\u6001\u65b9\u6cd5\u3002 \u7334\u5b50\u8865\u4e01\uff08monkey patch\uff09 \u00b6 \u7334\u5b50\u8865\u4e01\u662f\u52a8\u6001\u4e3a\u5df2\u7ecf\u521b\u5efa\u51fa\u7684\u5bf9\u8c61\u589e\u52a0\u65b0\u7684\u65b9\u6cd5\u548c\u5c5e\u6027\u6210\u5458\u7684\u4e00\u79cd\u673a\u5236\uff0c\u4e5f\u5c31\u662f\u52a8\u6001\u6253\u8865\u4e01\u3002 \u5b9e\u4f8b\u5316\u5bf9\u8c61\u7684\u7334\u5b50\u8865\u4e01\u3002 class Test : def __init__ ( self ): self . a = 1 def func1 ( self , x , y ): print ( x + y ) # \u6b63\u5e38\u5b9e\u4f8b\u5316 test = Test () test . func1 ( 1 , 1 ) # 2 # \u4fee\u6539\u5b9e\u4f8b test . func1 = lambda x , y : print ( x + 2 * y ) test . func1 ( 1 , 1 ) # 3 # \u901a\u8fc7\u4fee\u6539\u5b9e\u4f8b\uff0c\u8bbf\u95ee\u5185\u90e8\u6210\u5458\u53d8\u91cf\u3002 test . func1 = lambda x , y : print ( x + 2 * y + self . a ) test . func1 ( 1 , 1 ) # NameError: name 'self' is not defined test . func1 = lambda self , x , y : print ( x + 2 * y + self . a ) test . func1 ( test , 1 , 1 ) # 4 \u7c7b\u5bf9\u8c61\u7684\u7334\u5b50\u8865\u4e01\u3002 class Test : def __init__ ( self ): self . a = 1 def func1 ( self , x , y ): print ( x + y ) # \u4fee\u6539\u7c7b\u6210\u5458\uff0c\u5b9e\u4f8b\u5316\u540e\u7684\u7ed3\u679c\u5df2\u4fee\u6539\u3002 Test . func1 = lambda self , x , y : print ( x + 2 * y ) test = Test () test . func1 ( 1 , 1 ) # 3 # \u4fee\u6539\u7c7b\u6210\u5458\uff0c\u5e76\u8bbf\u95ee\u6210\u5458\u53d8\u91cf\uff0c\u5b9e\u4f8b\u5316\u540e\u7684\u7ed3\u679c\u5df2\u4fee\u6539\u3002 Test . func1 = lambda self , x , y : print ( x + 2 * y + self . a ) test = Test () test . func1 ( 1 , 1 ) # 4 # \u589e\u52a0\u7c7b\u6210\u5458\u3002 Test . func2 = lambda self , p , q : print ( p + 3 * q + self . a ) test = Test () test . func1 ( 1 , 1 ) # 4 test . func2 ( 1 , 3 ) # 11 \u79c1\u6709\u53d8\u91cf Private Variables \u00b6 \u90a3\u79cd\u4ec5\u9650\u4ece\u4e00\u4e2a\u5bf9\u8c61\u5185\u90e8\u8bbf\u95ee\u7684\u201c\u79c1\u6709\u201d\u5b9e\u4f8b\u53d8\u91cf\uff08\u201cPrivate\u201d instance variables\uff09\u5728 Python \u4e2d\u5e76\u4e0d\u5b58\u5728\u3002 \u4f46\u662f\uff0c\u5927\u591a\u6570 Python \u4ee3\u7801\u90fd\u9075\u5faa\u8fd9\u6837\u4e00\u4e2a\u7ea6\u5b9a\uff1a\u5e26\u6709*\u4e00\u4e2a\u524d\u7f00\u4e0b\u5212\u7ebf*\u7684\u540d\u79f0 (\u4f8b\u5982 _spam ) \u5e94\u8be5\u88ab\u5f53\u4f5c\u662f API \u7684\u975e\u516c\u6709\uff08non-public\uff09\u90e8\u5206 (\u65e0\u8bba\u5b83\u662f\u51fd\u6570\u3001\u65b9\u6cd5\u6216\u662f\u6570\u636e\u6210\u5458)\u3002 \u8fd9\u5e94\u5f53\u88ab\u89c6\u4e3a\u4e00\u4e2a\u5b9e\u73b0\u7ec6\u8282\uff0c\u53ef\u80fd\u4e0d\u7ecf\u901a\u77e5\u5373\u52a0\u4ee5\u6539\u53d8\u3002 \u7531\u4e8e\u5b58\u5728\u5bf9\u4e8e\u7c7b\u79c1\u6709\u6210\u5458\uff08class-private members\uff09\u7684\u6709\u6548\u4f7f\u7528\u573a\u666f\uff08\u4f8b\u5982\u907f\u514d\u540d\u79f0\u4e0e\u5b50\u7c7b\u6240\u5b9a\u4e49\u7684\u540d\u79f0\u76f8\u51b2\u7a81\uff09\uff0c\u56e0\u6b64\u5b58\u5728\u5bf9\u6b64\u79cd\u673a\u5236\u7684\u6709\u9650\u652f\u6301\uff0c\u79f0\u4e3a**\u540d\u79f0\u6539\u5199\uff08name mangling\uff09**\u3002 \u4efb\u4f55\u5f62\u5f0f\u4e3a __spam \u7684\u6807\u8bc6\u7b26\uff08\u81f3\u5c11\u5e26\u6709*\u4e24\u4e2a\u524d\u7f00\u4e0b\u5212\u7ebf*\uff0c\u81f3\u591a\u4e00\u4e2a\u540e\u7f00\u4e0b\u5212\u7ebf\uff09\u7684\u6587\u672c\u5c06\u88ab\u66ff\u6362\u4e3a _classname__spam \uff0c\u5176\u4e2d classname \u4e3a\u53bb\u9664\u4e86\u524d\u7f00\u4e0b\u5212\u7ebf\u7684\u5f53\u524d\u7c7b\u540d\u79f0\u3002 \u8fd9\u79cd\u6539\u5199\u4e0d\u8003\u8651\u6807\u8bc6\u7b26\u7684\u53e5\u6cd5\u4f4d\u7f6e\uff0c\u53ea\u8981\u5b83\u51fa\u73b0\u5728\u7c7b\u5b9a\u4e49\u5185\u90e8\u5c31\u4f1a\u8fdb\u884c\u3002 \u540d\u79f0\u6539\u5199\uff08Name mangling\uff09\u6709\u52a9\u4e8e\u8ba9\u5b50\u7c7b\u91cd\u8f7d\u65b9\u6cd5\uff08\uff09override methods\u800c\u4e0d\u7834\u574f\u7c7b\u5185\u65b9\u6cd5\uff08intraclass method\uff09\u8c03\u7528\u3002\u4f8b\u5982: class Mapping : def __init__ ( self , iterable ): self . items_list = [] self . __update ( iterable ) def update ( self , iterable ): for item in iterable : self . items_list . append ( item ) __update = update # private copy of original update() method class MappingSubclass ( Mapping ): def update ( self , keys , values ): # provides new signature for update() # but does not break __init__() for item in zip ( keys , values ): self . items_list . append ( item ) \u4e0a\u9762\u7684\u793a\u4f8b\u5373\u4f7f\u5728 MappingSubclass \u5f15\u5165\u4e86\u4e00\u4e2a __update \u6807\u8bc6\u7b26\u7684\u60c5\u51b5\u4e0b\u4e5f\u4e0d\u4f1a\u51fa\u9519\uff0c\u56e0\u4e3a\u5b83\u4f1a\u5728 Mapping \u7c7b\u4e2d\u88ab\u66ff\u6362\u4e3a _Mapping__update \u800c\u5728 MappingSubclass \u7c7b\u4e2d\u88ab\u66ff\u6362\u4e3a _MappingSubclass__update \u3002 \u8bf7\u6ce8\u610f\uff0c\u6539\u5199\u89c4\u5219\uff08mangling rules\uff09\u7684\u8bbe\u8ba1\u4e3b\u8981\u662f\u4e3a\u4e86\u907f\u514d\u610f\u5916\u51b2\u7a81\uff1b\u8bbf\u95ee\u6216\u4fee\u6539\u79c1\u6709\u53d8\u91cf\u4ecd\u7136\u662f\u53ef\u80fd\u7684\u3002\u8fd9\u5728\u7279\u6b8a\u60c5\u51b5\u4e0b\u751a\u81f3\u4f1a\u5f88\u6709\u7528\uff0c\u4f8b\u5982\u5728\u8c03\u8bd5\u5668\uff08debugger\uff09\u4e2d\u3002 \u8bf7\u6ce8\u610f\u4f20\u9012\u7ed9 exec() \u6216 eval() \u7684\u4ee3\u7801\u4e0d\u4f1a\u628a\u53d1\u8d77\u8c03\u7528\u7c7b\u7684\u7c7b\u540d\u89c6\u4f5c\u5f53\u524d\u7c7b\uff1b\u8fd9\u7c7b\u4f3c\u4e8e global \u8bed\u53e5\u7684\u6548\u679c\uff0c\u56e0\u6b64\u8fd9\u79cd\u6548\u679c\u4ec5\u9650\u4e8e\u540c\u65f6\u7ecf\u8fc7\u5b57\u8282\u7801\u7f16\u8bd1\u7684\u4ee3\u7801\u3002 \u540c\u6837\u7684\u9650\u5236\u4e5f\u9002\u7528\u4e8e getattr() , setattr() \u548c delattr() \uff0c\u4ee5\u53ca\u5bf9\u4e8e __dict__ \u7684\u76f4\u63a5\u5f15\u7528\u3002 \u53cd\u5c04(reflection) \u00b6 \u53cd\u5c04(reflection)\u662f\u52a8\u6001\u8bed\u8a00\u7684\u4e00\u4e2a\u7279\u6027\u3002**\u53cd\u5c04\u673a\u5236**\u6307\u7684\u662f\u5728\u7a0b\u5e8f\u7684\u8fd0\u884c\u72b6\u6001\u4e2d\uff0c\u5bf9\u4e8e\u4efb\u610f\u4e00\u4e2a\u7c7b\uff0c\u90fd\u53ef\u4ee5\u77e5\u9053\u8fd9\u4e2a\u7c7b\u7684\u6240\u6709\u5c5e\u6027\u548c\u65b9\u6cd5\uff1b\u5bf9\u4e8e\u4efb\u610f\u4e00\u4e2a\u5bf9\u8c61\uff0c\u90fd\u80fd\u591f\u8c03\u7528\u4ed6\u7684\u4efb\u610f\u65b9\u6cd5\u548c\u5c5e\u6027\u3002\u8fd9\u79cd\u52a8\u6001\u83b7\u53d6\u7a0b\u5e8f\u4fe1\u606f\u4ee5\u53ca\u52a8\u6001\u8c03\u7528\u5bf9\u8c61\u7684\u529f\u80fd\u79f0\u4e3a\u53cd\u5c04\u673a\u5236\u3002 \u901a\u8fc7\u4e0b\u9762\u4f8b\u5b50\u53ef\u77e5\uff0c\u901a\u8fc7 dir(person) \u83b7\u53d6\u4efb\u610f\u4e00\u4e2a\u7c7b\u6216\u8005\u5bf9\u8c61\u7684\u5c5e\u6027\u5217\u8868\u3002\u901a\u8fc7\u5185\u7f6e\u51fd\u6570 hasattr \u3001 getattr \u3001 setattr \u3001 delattr \u64cd\u4f5c\u7c7b\u548c\u5bf9\u8c61\u3002 class Person : def __init__ ( self , name , age , gender ): self . name = name self . age = age self . gender = gender person = Person ( 'Tom' , 21 , 'Male' ) print ( dir ( person )) # ['__class__', '__delattr__', '__dict__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__gt__', '__hash__', '__init__', '__init_subclass__', '__le__', '__lt__', '__module__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', '__weakref__', 'age', 'gender', 'name'] # hasattr(object,'name') # \u6309\u5b57\u7b26\u4e32'name'\u5224\u65ad\u6709\u65e0\u5c5e\u6027person.name hasattr ( person , 'name' ) # True # getattr(object, 'name', default=None) # \u7b49\u540c\u4e8eperson.name,\u4e0d\u5b58\u5728\u8be5\u5c5e\u6027\u5219\u8fd4\u56de\u9ed8\u8ba4\u503cNone getattr ( person , 'name' , None ) # 'Tom' # setattr(x, 'y', v) # \u7b49\u540c\u4e8eperson.age = 18 setattr ( person , 'age' , 18 ) print ( person . age ) # 18 # delattr(x, 'y') # \u7b49\u540c\u4e8edel person.age delattr ( person , 'age' ) print ( person . age ) # AttributeError: 'Person' object has no attribute 'age' \u4e0b\u9762\u662f\u4e00\u4e2a\u5b9e\u9645\u5e94\u7528\u7684\u4f8b\u5b50\u3002 class FtpServer (): def server_run ( self ): while True : inp = input ( 'Input your command >>:' ) . strip () cmd , file = inp . split () if hasattr ( self , cmd ): func = getattr ( self , cmd ) func ( file ) def get ( self , file ): print ( f 'Downloading { file } ...' ) def put ( self , file ): print ( f 'Uploading { file } ...' ) ftp_server = FtpServer () ftp_server . server_run () # Input your command >>:get a.ext # Downloading a.ext... # Input your command >>:put a.txt # Uploading a.txt... \u8fed\u4ee3\u5668 Iterators \u00b6 \u5728Python\u4e2d\uff0c\u5927\u591a\u6570\u5bb9\u5668\u5bf9\u8c61\uff08container object\uff09\u90fd\u53ef\u4ee5\u4f7f\u7528 for \u8bed\u53e5: for element in [ 1 , 2 , 3 ]: print ( element ) for element in ( 1 , 2 , 3 ): print ( element ) for key in { 'one' : 1 , 'two' : 2 }: print ( key ) for char in \"123\" : print ( char ) for line in open ( \"myfile.txt\" ): print ( line , end = '' ) for \u8bed\u53e5\u4f1a\u5728\u5bb9\u5668\u5bf9\u8c61\u4e0a\u8c03\u7528 iter()\u3002 \u8be5\u51fd\u6570\u8fd4\u56de\u4e00\u4e2a\u5b9a\u4e49\u4e86 __next__() \u65b9\u6cd5\u7684\u8fed\u4ee3\u5668\u5bf9\u8c61\uff0c\u6b64\u65b9\u6cd5\u5c06\u9010\u4e00\u8bbf\u95ee\u5bb9\u5668\u4e2d\u7684\u5143\u7d20\u3002 \u5f53\u5143\u7d20\u7528\u5c3d\u65f6\uff0c __next__() \u5c06\u5f15\u53d1 StopIteration \u5f02\u5e38\u6765\u901a\u77e5\u7ec8\u6b62 for \u5faa\u73af\u3002 \u53ef\u4ee5\u4f7f\u7528 next() \u5185\u7f6e\u51fd\u6570\u6765\u8c03\u7528 __next__() \u65b9\u6cd5\uff1b\u4e0b\u9762\u8fd9\u4e2a\u4f8b\u5b50\u5c55\u793a\u4e86\u521a\u521a\u63cf\u8ff0\u7684\u5177\u4f53\u8fd0\u884c\u65b9\u5f0f: >>> s = 'abc' >>> it = iter ( s ) >>> it < str_iterator object at 0x10c90e650 > >>> next ( it ) 'a' >>> next ( it ) 'b' >>> next ( it ) 'c' >>> next ( it ) Traceback ( most recent call last ): File \"\" , line 1 , in < module > next ( it ) StopIteration \u5728\u4e86\u89e3\u4e86\u8fed\u4ee3\u5668\u534f\u8bae\uff08iterator protocol\uff09\u7684\u673a\u5236\u540e\uff0c\u7ed9\u7c7b\u6dfb\u52a0\u8fed\u4ee3\u5668\u5c31\u5f88\u5bb9\u6613\u4e86\u3002 \u5b9a\u4e49\u4e00\u4e2a __iter__() \u65b9\u6cd5\u6765\u8fd4\u56de\u4e00\u4e2a\u5e26\u6709 __next__() \u65b9\u6cd5\u7684\u5bf9\u8c61\u3002 \u5982\u679c\u7c7b\u5df2\u5b9a\u4e49\u4e86 __next__() \uff0c\u5219 __iter__() \u53ef\u4ee5\u7b80\u5355\u5730\u8fd4\u56de self : class Reverse : \"\"\"Iterator for looping over a sequence backwards.\"\"\" def __init__ ( self , data ): self . data = data self . index = len ( data ) def __iter__ ( self ): return self def __next__ ( self ): if self . index == 0 : raise StopIteration self . index = self . index - 1 return self . data [ self . index ] rev = Reverse ( 'spam' ) print ( iter ( rev )) for char in rev : print ( char ) # m # a # p # s \u751f\u6210\u5668 Generators \u00b6 **\u751f\u6210\u5668\uff08Generators\uff09**\u662f\u4e00\u4e2a\u7528\u4e8e\u521b\u5efa\u8fed\u4ee3\u5668\u7684\u7b80\u5355\u800c\u5f3a\u5927\u7684\u5de5\u5177\u3002 \u5b83\u4eec\u7684\u5199\u6cd5\u7c7b\u4f3c\u4e8e\u6807\u51c6\u7684\u51fd\u6570\uff0c\u4f46\u5f53\u5b83\u4eec\u8981\u8fd4\u56de\u6570\u636e\u65f6\u4f1a\u4f7f\u7528 yield \u8bed\u53e5\u3002 \u6bcf\u6b21\u5728\u751f\u6210\u5668\u4e0a\u8c03\u7528 next() \u65f6\uff0c\u5b83\u4f1a\u4ece\u4e0a\u6b21\u79bb\u5f00\u7684\u4f4d\u7f6e\u6062\u590d\u6267\u884c\uff08\u5b83\u4f1a\u8bb0\u4f4f\u4e0a\u6b21\u6267\u884c\u8bed\u53e5\u65f6\u7684\u6240\u6709\u6570\u636e\u503c\uff09\u3002 \u4e00\u4e2a\u521b\u5efa\u751f\u6210\u5668\u7684\u793a\u4f8b\u5982\u4e0b\uff08\u6539\u5199\u4e0a\u9762\u8fed\u4ee3\u5668\u4e2d\u6240\u4e3e\u7684\u4f8b\u5b50\uff09: def reverse ( data ): for index in range ( len ( data ) - 1 , - 1 , - 1 ): yield data [ index ] for char in reverse ( 'golf' ): print ( char ) # f # l # o # g \u53ef\u4ee5\u7528\u751f\u6210\u5668\u6765\u5b8c\u6210\u7684\u64cd\u4f5c\u540c\u6837\u53ef\u4ee5\u7528\u524d\u9762\u6240\u63cf\u8ff0\u7684\u57fa\u4e8e\u7c7b\u7684\u8fed\u4ee3\u5668\u6765\u5b8c\u6210\u3002\u4f46\u751f\u6210\u5668\u7684\u5199\u6cd5\u66f4\u4e3a\u7d27\u51d1\uff0c\u56e0\u4e3a\u5b83\u4f1a\u81ea\u52a8\u521b\u5efa __iter__() \u548c __next__() \u65b9\u6cd5\u3002 \u53e6\u4e00\u4e2a\u5173\u952e\u7279\u6027\u5728\u4e8e\u5c40\u90e8\u53d8\u91cf\u548c\u6267\u884c\u72b6\u6001\u4f1a\u5728\u6bcf\u6b21\u8c03\u7528\u4e4b\u95f4\u81ea\u52a8\u4fdd\u5b58\u3002 \u8fd9\u4f7f\u5f97\u8be5\u51fd\u6570\u76f8\u6bd4\u4f7f\u7528 self.index \u548c self.data \u8fd9\u79cd\u5b9e\u4f8b\u53d8\u91cf\u7684\u65b9\u5f0f\u66f4\u6613\u7f16\u5199\u4e14\u66f4\u4e3a\u6e05\u6670\u3002 \u9664\u4e86\u4f1a\u81ea\u52a8\u521b\u5efa\u65b9\u6cd5\u548c\u4fdd\u5b58\u7a0b\u5e8f\u72b6\u6001\uff0c\u5f53\u751f\u6210\u5668\u7ec8\u7ed3\u65f6\uff0c\u5b83\u4eec\u8fd8\u4f1a\u81ea\u52a8\u5f15\u53d1 StopIteration \u3002 \u751f\u6210\u5668\u8868\u8fbe\u5f0f Generator Expressions \u00b6 \u67d0\u4e9b\u7b80\u5355\u7684\u751f\u6210\u5668\u53ef\u4ee5\u5199\u6210\u7b80\u6d01\u7684\u8868\u8fbe\u5f0f\u4ee3\u7801\uff0c\u6240\u7528\u8bed\u6cd5\u7c7b\u4f3c\u5217\u8868\u63a8\u5bfc\u5f0f\uff0c\u4f46\u5916\u5c42\u4e3a\u5706\u62ec\u53f7\u800c\u975e\u65b9\u62ec\u53f7\u3002 \u8fd9\u79cd\u8868\u8fbe\u5f0f\u88ab\u8bbe\u8ba1\u7528\u4e8e\u751f\u6210\u5668\u5c06\u7acb\u5373\u88ab\u5916\u5c42\u51fd\u6570\u6240\u4f7f\u7528\u7684\u60c5\u51b5\u3002 \u751f\u6210\u5668\u8868\u8fbe\u5f0f\u76f8\u6bd4\u5b8c\u6574\u7684\u751f\u6210\u5668\u66f4\u7d27\u51d1\u4f46\u8f83\u4e0d\u7075\u6d3b\uff0c\u76f8\u6bd4\u7b49\u6548\u7684\u5217\u8868\u63a8\u5bfc\u5f0f\u5219\u66f4\u4e3a\u8282\u7701\u5185\u5b58\u3002 \u793a\u4f8b: >>> sum ( i * i for i in range ( 10 )) # sum of squares 285 >>> xvec = [ 10 , 20 , 30 ] >>> yvec = [ 7 , 5 , 3 ] >>> sum ( x * y for x , y in zip ( xvec , yvec )) # dot product 260 >>> unique_words = set ( word for line in page for word in line . split ()) >>> valedictorian = max (( student . gpa , student . name ) for student in graduates ) >>> data = 'golf' >>> list ( data [ i ] for i in range ( len ( data ) - 1 , - 1 , - 1 )) [ 'f' , 'l' , 'o' , 'g' ] \u5143\u7c7b\uff08metaclass\uff09 \u00b6 \u6240\u6709\u7684\u5bf9\u8c61\u90fd\u662f\u5b9e\u4f8b\u5316\u6216\u8005\u8bf4\u8c03\u7528\u7c7b\u800c\u5f97\u5230\u7684\uff08\u8c03\u7528\u7c7b\u7684\u8fc7\u7a0b\u79f0\u4e3a\u7c7b\u7684\u5b9e\u4f8b\u5316\u3002 class StandfordProfessor ( object ): university = 'Standford' def __init__ ( self , name , gender ): self . name = name self . gender = gender def display ( self ): print ( f 'Professor { self . name } says welcome to { self . university } !' ) professor = StandfordProfessor ( 'Tom' , 'Male' ) \u4e0a\u4f8b\u4e2d\uff0c\u5bf9\u8c61 professor \u662f\u8c03\u7528\u7c7b StandfordProfessor \u5f97\u5230\u7684\u3002\u7c7b StandfordProfessor \u672c\u8d28\u4e5f\u662f\u4e00\u4e2a\u5bf9\u8c61\uff0c \u4e0b\u9762\u53ef\u4ee5\u9a8c\u8bc1\uff0c StandfordProfessor \u662f\u8c03\u7528\u4e86\u5185\u7f6e\u7684\u7c7b type \u5f97\u5230\u7684\u3002\u8fd9\u4e2a type \u79f0\u4e3a\u5143\u7c7b\u3002 print ( type ( StandfordProfessor )) # \u5982\u679c\u4e00\u4e2a\u7c7b\u6ca1\u6709\u58f0\u660e\u81ea\u5df1\u7684\u5143\u7c7b\uff0c\u9ed8\u8ba4\u5b83\u7684\u5143\u7c7b\u5c31\u662f type \uff0c\u9664\u4e86\u4f7f\u7528\u5185\u7f6e\u5143\u7c7b type \uff0c\u6211\u4eec\u4e5f\u53ef\u4ee5\u901a\u8fc7\u7ee7\u627f type \u6765\u81ea\u5b9a\u4e49\u5143\u7c7b\uff0c\u7136\u540e\u4f7f\u7528 metaclass \u5173\u952e\u5b57\u53c2\u6570\u4e3a\u4e00\u4e2a\u7c7b\u7684\u6307\u5b9a\u5143\u7c7b\u3002 \u53ea\u6709\u7ee7\u627f\u4e86type\u7c7b\u624d\u80fd\u79f0\u4e4b\u4e3a\u4e00\u4e2a\u5143\u7c7b\uff0c\u5426\u5219\u5c31\u662f\u4e00\u4e2a\u666e\u901a\u7684\u81ea\u5b9a\u4e49\u7c7b\u3002 class Mymeta ( type ): pass class StandfordProfessor ( object , metaclass = Mymeta ): university = 'Standford' def __init__ ( self , name , gender ): self . name = name self . gender = gender def display ( self ): print ( f 'Professor { self . name } says welcome to { self . university } !' ) professor = StandfordProfessor ( 'Tom' , 'Male' ) \u4e0b\u9762\u8fdb\u884c\u81ea\u5b9a\u4e49\u5143\u7c7b\uff0c\u63a7\u5236\u7c7b StandfordProfessor \u7684\u8c03\u7528\u3002 \u8981\u60f3\u8ba9 professor \u8fd9\u4e2a\u5bf9\u8c61\u53d8\u6210\u4e00\u4e2a\u53ef\u8c03\u7528\u7684\u5bf9\u8c61\uff0c\u9700\u8981\u5728\u8be5\u5bf9\u8c61\u7684\u7c7b\u4e2d\u5b9a\u4e49\u4e00\u4e2a\u65b9\u6cd5 __call__ \uff0c\u8be5\u65b9\u6cd5\u4f1a\u5728\u8c03\u7528\u5bf9\u8c61\u65f6\u81ea\u52a8\u89e6\u53d1\u3002\u8c03\u7528 professor \u7684\u8fd4\u56de\u503c\u5c31\u662f __call__ \u65b9\u6cd5\u7684\u8fd4\u56de\u503c\u3002 class Mymeta ( type ): def __call__ ( self , * args , ** kwargs ): print ( self ) # \u7c7b\u540d print ( args ) # \u8f93\u5165\u53c2\u6570 print ( kwargs ) # \u8f93\u5165\u53c2\u6570 return 10086 class StandfordProfessor ( object , metaclass = Mymeta ): university = 'Standford' def __init__ ( self , name , gender ): self . name = name self . gender = gender def display ( self ): print ( f 'Professor { self . name } says welcome to { self . university } !' ) professor = StandfordProfessor ( 'Tom' , 'Male' ) # # ('Tom', 'Male') # {} \u7c7b\u7684\u4ea7\u751f\u8fc7\u7a0b\u5176\u5b9e\u5c31\u662f\u5143\u7c7b\u7684\u8c03\u7528\u8fc7\u7a0b,\u5373 StandfordProfessor = Mymeta('StandfordProfessor', (object), {...}) \uff0c\u8c03\u7528 Mymeta \u4f1a\u5148\u4ea7\u751f\u4e00\u4e2a\u7a7a\u5bf9\u8c61 StandfordProfessor \uff0c\u7136\u540e\u8fde\u540c\u8c03\u7528 Mymeta \u62ec\u53f7\u5185\u7684\u53c2\u6570\u4e00\u540c\u4f20\u7ed9 Mymeta \u4e0b\u7684 __init__ \u65b9\u6cd5\uff0c\u5b8c\u6210\u521d\u59cb\u5316\u3002\u6211\u4eec\u53ef\u4ee5\u57fa\u4e8e\u4e0a\u4f8b\u505a\u5982\u4e0b\u6539\u5199\u3002 class Mymeta ( type ): def __init__ ( self , class_name , class_bases , class_dic ): super ( Mymeta , self ) . __init__ ( class_name , class_bases , class_dic ) if class_name . islower (): raise TypeError ( f 'Please follow Camel-Case to change class name { class_name } ' ) if '__doc__' not in class_dic or len ( class_dic [ '__doc__' ] . strip ( ' \\n ' )) == 0 : raise TypeError ( 'Please add documentation in class {class_name} , which is mandatory.' ) class StandfordProfessor ( object , metaclass = Mymeta ): \"\"\" Documentation of class StanfordTeacher \"\"\" university = 'Standford' def __init__ ( self , name , gender ): self . name = name self . gender = gender def display ( self ): print ( f 'Professor { self . name } says welcome to { self . university } !' ) professor = StandfordProfessor ( 'Tom' , 'Male' ) professor . display () # Professor Tom says welcome to Standford! print ( professor . __dict__ ) # {'name': 'Tom', 'gender': 'Male'} StandfordProfessor . mro () # [, ]","title":"Python\u9762\u5411\u5bf9\u8c61\u4e09\u5927\u7279\u6027"},{"location":"python/Foundation/ch05/#python","text":"Python\u9762\u5411\u5bf9\u8c61\u4e09\u5927\u7279\u6027\uff1a \u5c01\u88c5 \u7ee7\u627f \u591a\u6001","title":"Python\u9762\u5411\u5bf9\u8c61\u4e09\u5927\u7279\u6027"},{"location":"python/Foundation/ch05/#encapsulation","text":"\u5c01\u88c5\u662f\u4f7f\u7528\u7279\u6b8a\u7684\u8bed\u6cd5\uff0c\u5bf9\u6210\u5458\u5c5e\u6027\u548c\u6210\u5458\u65b9\u6cd5\u8fdb\u884c\u5305\u88c5\uff0c\u9650\u5236\u4e00\u4e9b\u8bbf\u95ee\u548c\u64cd\u4f5c\uff0c\u8fbe\u5230\u4fdd\u62a4\u548c\u9690\u85cf\u7684\u76ee\u7684\u3002 \u5c01\u88c5\u673a\u5236\u4fdd\u8bc1\u4e86\u7c7b\u5185\u90e8\u6570\u636e\u7ed3\u6784\u7684\u5b8c\u6574\u6027\uff0c\u56e0\u4e3a\u4f7f\u7528\u7c7b\u7684\u7528\u6237\u65e0\u6cd5\u76f4\u63a5\u770b\u5230\u7c7b\u4e2d\u7684\u6570\u636e\u7ed3\u6784\uff0c\u53ea\u80fd\u4f7f\u7528\u7c7b\u5141\u8bb8\u516c\u5f00\u7684\u6570\u636e\uff0c\u5f88\u597d\u5730\u907f\u514d\u4e86\u5916\u90e8\u5bf9\u5185\u90e8\u6570\u636e\u7684\u5f71\u54cd\uff0c\u63d0\u9ad8\u4e86\u7a0b\u5e8f\u7684\u53ef\u7ef4\u62a4\u6027\u3002 \u5bf9\u4e00\u4e2a\u7c7b\u5b9e\u73b0\u826f\u597d\u7684\u5c01\u88c5\uff0c\u7528\u6237\u53ea\u80fd\u501f\u52a9\u66b4\u9732\u51fa\u6765\u7684\u7c7b\u65b9\u6cd5\u6765\u8bbf\u95ee\u6570\u636e\uff0c\u53ef\u4ee5\u5728\u8fd9\u4e9b\u66b4\u9732\u7684\u65b9\u6cd5\u4e2d\u52a0\u5165\u9002\u5f53\u7684\u63a7\u5236\u903b\u8f91\uff0c\u5373\u53ef\u63a7\u5236\u7528\u6237\u5bf9\u7c7b\u4e2d\u5c5e\u6027\u6216\u65b9\u6cd5\u7684\u64cd\u4f5c\u3002 \u5bf9\u7c7b\u8fdb\u884c\u826f\u597d\u7684\u5c01\u88c5\uff0c\u4e3b\u8981\u662f\u5185\u90e8\u4f7f\u7528\u5c01\u88c5\u7684\u6210\u5458\uff0c\u4e5f\u63d0\u9ad8\u4e86\u4ee3\u7801\u7684\u590d\u7528\u6027\u3002 \u7c7b\u6210\u5458\u5c01\u88c5\u7684\u7ea7\u522b\uff1a \u516c\u6709\u7684\uff08public\uff09 \u4fdd\u62a4\u7684\uff08protected\uff09\uff0c\u5728Python\u4e2d\u5e76\u6ca1\u6709\u5b9e\u73b0protected\u5c01\u88c5\uff0c\u5c5e\u4e8e\u5f00\u53d1\u8005\u7684\u7ea6\u5b9a\u4fd7\u6210\u3002 \u79c1\u6709\u7684\uff08private\uff09\uff0c\u5728Python\u4e2dprivate\u5c01\u88c5\u662f\u901a\u8fc7\u6539\u540d\u7b56\u7565\u6765\u5b9e\u73b0\u7684\uff0c\u5e76\u4e0d\u662f\u771f\u6b63\u7684\u79c1\u6709\u5316\u3002 \u8bbf\u95ee\u9650\u5236 \u5171\u6709\u7684public \u53d7\u4fdd\u62a4\u7684protected \u79c1\u6709\u7684private \u5728\u7c7b\u7684\u5185\u90e8 OK OK OK \u5728\u7c7b\u7684\u5916\u90e8 OK No (Python\u4e2d\u53ef\u4ee5) No \u770b\u4e0b\u9762\u7684\u4f8b\u5b50\u3002(\u53c2\u8003 \u79c1\u6709\u53d8\u91cfPrivate Variables ) name \u662f\u5171\u6709\u5c5e\u6027\uff0c\u53ef\u4ee5\u5728\u5916\u90e8\u8c03\u7528tom.name\u3002 _age \u662f\u53d7\u4fdd\u62a4\u7684\u5c5e\u6027\uff0c\u7406\u8bba\u4e0a\u5728\u5916\u90e8\u662f\u4e0d\u53ef\u8c03\u7528\u7684\uff0c\u4f46\u5728Python\u4e2d\u662f\u53ef\u4ee5\u8c03\u7528\u7684 tom._age \u3002 __phone \u662f\u79c1\u6709\u5c5e\u6027\uff0c\u5728\u5916\u90e8\u662f\u4e0d\u53ef\u8c03\u7528\u7684\uff0c tom.__get_phone() \u62a5\u9519\u201c\u5c5e\u6027\u4e0d\u5b58\u5728\u201d\u3002 \u5bf9\u5e94\u65b9\u6cd5\u4e5f\u662f\u7c7b\u4f3c\u3002 \u5728\u7c7b\u7684\u5185\u90e8\u5bf9\u53d7\u4fdd\u62a4\u5bf9\u8c61\u548c\u79c1\u6709\u5bf9\u8c61\u6ca1\u6709\u8bbf\u95ee\u9650\u5236\u3002 _get_age \u53ef\u4ee5\u8c03\u7528\u79c1\u6709\u5c5e\u6027 __phone \u3002 class Person (): name = 'name' # public _age = 0 # protected __phone = 'phone' # private def __init__ ( self , n , a , p ): self . name = n self . _age = a self . __phone = p def get_name ( self ): print ( f 'My name is { self . name } ' ) def _get_age ( self ): print ( f 'My age is { self . _age } ' ) print ( f 'My age is { self . __phone } ' ) def __get_phone ( self ): print ( f 'My phone is { self . __phone } ' ) tom = Person ( 'Tom' , 18 , 12345678 ) tom . name # 'Tom' tom . _age # 18 tom . __phone # AttributeError: 'Person' object has no attribute '__phone' tom . get_name () # My name is Tom tom . _get_age () # My age is 18 # My age is 12345678 tom . __get_phone () # AttributeError: 'Person' object has no attribute '__get_phone'","title":"\u5c01\u88c5 Encapsulation"},{"location":"python/Foundation/ch05/#inheritance","text":"\u5728\u4e0d\u6307\u5b9a\u7ee7\u627f\u7684\u7236\u7c7b\u65f6\uff0c\u6240\u6709\u7c7b\u90fd\u7ee7\u627fobject\u7c7b\uff08\u7cfb\u7edf\u63d0\u4f9b\uff09\u3002 \u88ab\u5176\u5b83\u7c7b\u7ee7\u627f\u7684\u7c7b\uff0c\u79f0\u4e3a\u7236\u7c7b\uff0c\u6216\u8005\u57fa\u7c7b\uff0c\u6216\u8005\u8d85\u7c7b\u3002 \u7ee7\u627f\u5176\u5b83\u7c7b\u7684\u7c7b\uff0c\u79f0\u4e3a\u5b50\u7c7b\uff0c\u6216\u8005\u6d3e\u751f\u7c7b\uff08derived class\uff09\u3002 \u5b50\u7c7b\u7ee7\u627f\u7236\u7c7b\u540e\uff0c\u5c31\u62e5\u6709\u4e86\u7236\u7c7b\u4e2d\u7684\u6240\u6709\u6210\u5458\uff08\u9664\u4e86\u79c1\u6709\u6210\u5458\uff09\u3002 \u5b50\u7c7b\u7ee7\u627f\u7236\u7c7b\u540e\uff0c\u5e76\u4e0d\u4f1a\u628a\u7236\u7c7b\u7684\u6210\u5458\u590d\u5236\u7ed9\u5b50\u7c7b\uff0c\u800c\u662f\u5f15\u7528\u3002 \u5b50\u7c7b\u53ef\u4ee5\u76f4\u63a5\u8c03\u7528\u7236\u7c7b\u7684\u65b9\u6cd5 super().BaseClassName \u3002\u5982\u679c\u7236\u7c7b\u65b9\u6cd5\u6709\u53c2\u6570\u8981\u6c42\uff0c\u5b50\u7c7b\u8c03\u7528\u65f6\u4e5f\u6709\u53c2\u6570\u8981\u6c42\u3002 \u5b50\u7c7b\u7ee7\u627f\u7236\u7c7b\u540e\uff0c\u53ef\u4ee5\u91cd\u65b0\u5b9a\u4e49\u7236\u7c7b\u4e2d\u7684\u65b9\u6cd5\uff0c\u79f0\u4e3a**\u91cd\u5199\uff08Override\uff09**\u3002 \u5b50\u7c7b\u7ee7\u627f\u7236\u7c7b\u540e\uff0c\u5b9a\u4e49\u7236\u7c7b\u4e2d\u6ca1\u6709\u7684\u65b9\u6cd5\uff0c\u88ab\u79f0\u4e3a\u5bf9\u7236\u7c7b\u7684\u6269\u5c55\u3002 \u4e00\u4e2a\u7236\u7c7b\u53ef\u4ee5\u88ab\u591a\u4e2a\u5b50\u7c7b\u7ee7\u627f\u3002 **\u6d3e\u751f\u7c7b\uff08derived class\uff09**\u5b9a\u4e49\u7684\u8bed\u6cd5\u5982\u4e0b\u6240\u793a: class BaseClassName (): < statement - 1 > . . . < statement - N > class DerivedClassName ( BaseClassName ): < statement - 1 > . . . < statement - N > \u540d\u79f0 BaseClassName \u5fc5\u987b\u5b9a\u4e49\u4e8e\u5305\u542b\u6d3e\u751f\u7c7b\u5b9a\u4e49\u7684\u4f5c\u7528\u57df\u4e2d\u3002 \u4e5f\u5141\u8bb8\u7528\u5176\u4ed6\u4efb\u610f\u8868\u8fbe\u5f0f\u4ee3\u66ff\u57fa\u7c7b\u540d\u79f0\u6240\u5728\u7684\u4f4d\u7f6e\uff0c\u4f8b\u5982\uff0c\u5f53\u57fa\u7c7b\u5b9a\u4e49\u5728\u53e6\u4e00\u4e2a\u6a21\u5757\u4e2d\u7684\u65f6\u5019: class DerivedClassName ( modname . BaseClassName ): \u6d3e\u751f\u7c7b\u5b9a\u4e49\u7684\u6267\u884c\u8fc7\u7a0b\u4e0e\u57fa\u7c7b\u76f8\u540c\u3002 \u5f53\u6784\u9020\u7c7b\u5bf9\u8c61\u65f6\uff0c\u57fa\u7c7b\u4f1a\u88ab\u8bb0\u4f4f\u3002 \u6b64\u4fe1\u606f\u5c06\u88ab\u7528\u6765\u89e3\u6790\u5c5e\u6027\u5f15\u7528\uff1a\u5982\u679c\u8bf7\u6c42\u7684\u5c5e\u6027\u5728\u7c7b\u4e2d\u627e\u4e0d\u5230\uff0c\u641c\u7d22\u5c06\u8f6c\u5f80\u57fa\u7c7b\u4e2d\u8fdb\u884c\u67e5\u627e\u3002 \u5982\u679c\u57fa\u7c7b\u672c\u8eab\u4e5f\u6d3e\u751f\u81ea\u5176\u4ed6\u67d0\u4e2a\u7c7b\uff0c\u5219\u6b64\u89c4\u5219\u5c06\u88ab\u9012\u5f52\u5730\uff08recursively\uff09\u5e94\u7528\u3002 \u6d3e\u751f\u7c7b\u7684\u5b9e\u4f8b\u5316\u6ca1\u6709\u4efb\u4f55\u7279\u6b8a\u4e4b\u5904: DerivedClassName() \u4f1a\u521b\u5efa\u8be5\u7c7b\u7684\u4e00\u4e2a*\u65b0\u5b9e\u4f8b*\u3002 \u65b9\u6cd5\u5f15\u7528\u5c06\u6309\u4ee5\u4e0b\u65b9\u5f0f\u89e3\u6790\uff1a\u641c\u7d22\u76f8\u5e94\u7684\u7c7b\u5c5e\u6027\uff0c\u5982\u6709\u5fc5\u8981\u5c06\u6309\u57fa\u7c7b\u7ee7\u627f\u94fe\u9010\u6b65\u5411\u4e0b\u67e5\u627e\uff0c\u5982\u679c\u4ea7\u751f\u4e86\u4e00\u4e2a\u51fd\u6570\u5bf9\u8c61\u5219\u65b9\u6cd5\u5f15\u7528\u5c31\u751f\u6548\u3002 \u6d3e\u751f\u7c7b\u53ef\u80fd\u4f1a\u91cd\u5199\uff08override\uff09\u5176\u57fa\u7c7b\u7684\u65b9\u6cd5\u3002 \u56e0\u4e3a\u65b9\u6cd5\u5728\u8c03\u7528\u540c\u4e00\u5bf9\u8c61\u7684\u5176\u4ed6\u65b9\u6cd5\u65f6\u6ca1\u6709\u7279\u6b8a\u6743\u9650\uff0c\u6240\u4ee5\u8c03\u7528\u540c\u4e00\u57fa\u7c7b\u4e2d\u5b9a\u4e49\u7684\u53e6\u4e00\u65b9\u6cd5\u7684\u57fa\u7c7b\u65b9\u6cd5\u6700\u7ec8\u53ef\u80fd\u4f1a\u8c03\u7528\u8986\u76d6\u5b83\u7684\u6d3e\u751f\u7c7b\u7684\u65b9\u6cd5\u3002 \u5728\u6d3e\u751f\u7c7b\u4e2d\u7684\u91cd\u8f7d\u65b9\u6cd5\uff08overriding method\uff09\u5b9e\u9645\u4e0a\u53ef\u80fd\u60f3\u8981\u6269\u5c55\u800c\u975e\u7b80\u5355\u5730\u66ff\u6362\u540c\u540d\u7684\u57fa\u7c7b\u65b9\u6cd5\u3002 \u6709\u4e00\u79cd\u65b9\u5f0f\u53ef\u4ee5\u7b80\u5355\u5730\u76f4\u63a5\u8c03\u7528\u57fa\u7c7b\u65b9\u6cd5\uff1a\u5373\u8c03\u7528 BaseClassName.methodname(self, arguments) \u3002 \u8bf7\u6ce8\u610f\uff0c\u4ec5\u5f53\u6b64\u57fa\u7c7b\u53ef\u5728\u5168\u5c40\u4f5c\u7528\u57df\u4e2d\u4ee5 BaseClassName \u7684\u540d\u79f0\u88ab\u8bbf\u95ee\u65f6\u65b9\u53ef\u4f7f\u7528\u6b64\u65b9\u5f0f\u3002 Python\u6709\u4e24\u4e2a\u5185\u7f6e\u51fd\u6570\u53ef\u88ab\u7528\u4e8e\u7ee7\u627f\u673a\u5236\uff1a \u4f7f\u7528 isinstance() \u6765\u68c0\u67e5\u4e00\u4e2a\u5b9e\u4f8b\u7684\u7c7b\u578b: isinstance(obj, int) \u4ec5\u4f1a\u5728 obj.__class__ \u4e3a int \u6216\u67d0\u4e2a\u6d3e\u751f\u81ea int \u7684\u7c7b\u65f6\u4e3a True \u3002 \u4f7f\u7528 issubclass() \u6765\u68c0\u67e5\u7c7b\u7684\u7ee7\u627f\u5173\u7cfb: issubclass(bool, int) \u4e3a True \uff0c\u56e0\u4e3a bool \u662f int \u7684\u5b50\u7c7b\u3002 \u4f46\u662f\uff0c issubclass(float, int) \u4e3a False \uff0c\u56e0\u4e3a float \u4e0d\u662f int \u7684\u5b50\u7c7b\u3002","title":"\u7ee7\u627f Inheritance"},{"location":"python/Foundation/ch05/#multiple-inheritance","text":"\u5355\u7ee7\u627f\uff08single-inheritance\uff09\uff1a\u4e00\u4e2a\u7c7b\u53ea\u80fd\u7ee7\u627f\u4e00\u4e2a\u7236\u7c7b\u65b9\u5f0f\u3002 class DerivedClassName ( BaseClassName ): < statement - 1 > . . . < statement - N > \u591a\u7ee7\u627f\uff08Multiple Inheritance\uff09\uff1a\u4e00\u4e2a\u7c7b\u53bb\u7ee7\u627f\u591a\u4e2a\u7c7b\u7684\u65b9\u5f0f\u3002\u5b9a\u4e49\u8bed\u53e5\u5982\u4e0b\u6240\u793a class DerivedClassName ( Base1 , Base2 , Base3 ): < statement - 1 > . . . < statement - N > \u5728\u6700\u7b80\u5355\u7684\u60c5\u51b5\u4e0b\uff0c\u641c\u7d22\u4ece\u7236\u7c7b\u6240\u7ee7\u627f\u5c5e\u6027\u7684\u64cd\u4f5c\u662f\u6df1\u5ea6\u4f18\u5148\uff08depth-first\uff09\u3001\u4ece\u5de6\u81f3\u53f3\uff08left-to-right\uff09\u7684\uff0c\u5f53\u5c42\u6b21\u7ed3\u6784\u4e2d\u5b58\u5728\u91cd\u53e0\u65f6\u4e0d\u4f1a\u5728\u540c\u4e00\u4e2a\u7c7b\u4e2d\u641c\u7d22\u4e24\u6b21\u3002 \u56e0\u6b64\uff0c\u5982\u679c\u67d0\u4e00\u5c5e\u6027\u5728 DerivedClassName \u4e2d\u672a\u627e\u5230\uff0c\u5219\u4f1a\u5230 Base1 \u4e2d\u641c\u7d22\u5b83\uff0c\u7136\u540e\uff08\u9012\u5f52\u5730\uff09\u5230 Base1 \u7684\u57fa\u7c7b\u4e2d\u641c\u7d22\uff0c\u5982\u679c\u5728\u90a3\u91cc\u672a\u627e\u5230\uff0c\u518d\u5230 Base2 \u4e2d\u641c\u7d22\uff0c\u4f9d\u6b64\u7c7b\u63a8\u3002 \u771f\u5b9e\u60c5\u51b5\u66f4\u590d\u6742\uff1b\u65b9\u6cd5\u89e3\u6790\u987a\u5e8f\u4f1a\u52a8\u6001\u6539\u53d8\u4ee5\u652f\u6301\u5bf9 super() \u7684\u534f\u540c\u8c03\u7528\u3002 \u8fd9\u79cd\u65b9\u5f0f\u5728\u67d0\u4e9b\u5176\u4ed6\u591a\u91cd\u7ee7\u627f\u578b\u8bed\u8a00\u4e2d\u88ab\u79f0\u4e3a**\u540e\u7eed\u65b9\u6cd5\u8c03\u7528\uff08call-next-method\uff09**\uff0c\u5b83\u6bd4**\u5355\u7ee7\u627f\uff08single-inheritance\uff09**\u8bed\u8a00\u4e2d\u7684 uper \u8c03\u7528\u66f4\u5f3a\u5927\u3002 \u52a8\u6001\u6539\u53d8\u987a\u5e8f\u662f\u6709\u5fc5\u8981\u7684\uff0c\u56e0\u4e3a\u6240\u6709\u591a\u91cd\u7ee7\u627f\u7684\u60c5\u51b5\u90fd\u4f1a\u663e\u793a\u51fa\u4e00\u4e2a\u6216\u66f4\u591a\u7684\u83f1\u5f62\u5173\u8054\uff08diamond relationships\uff09\uff08\u5373\u81f3\u5c11\u6709\u4e00\u4e2a\u7236\u7c7b\u53ef\u901a\u8fc7\u591a\u6761\u8def\u5f84\u88ab\u6700\u5e95\u5c42\u7c7b\u6240\u8bbf\u95ee\uff09\u3002 \u4f8b\u5982\uff0c\u6240\u6709\u7c7b\u90fd\u662f\u7ee7\u627f\u81ea object \uff0c\u56e0\u6b64\u4efb\u4f55\u591a\u91cd\u7ee7\u627f\u7684\u60c5\u51b5\u90fd\u63d0\u4f9b\u4e86\u4e00\u6761\u4ee5\u4e0a\u7684\u8def\u5f84\u53ef\u4ee5\u901a\u5411 object \u3002 \u4e3a\u4e86\u786e\u4fdd\u57fa\u7c7b\u4e0d\u4f1a\u88ab\u8bbf\u95ee\u4e00\u6b21\u4ee5\u4e0a\uff0c\u52a8\u6001\u7b97\u6cd5\u4f1a\u7528\u4e00\u79cd\u7279\u6b8a\u65b9\u5f0f\u5c06\u641c\u7d22\u987a\u5e8f\u7ebf\u6027\u5316\uff0c \u4fdd\u7559\u6bcf\u4e2a\u7c7b\u6240\u6307\u5b9a\u7684\u4ece\u5de6\u81f3\u53f3\u7684\u987a\u5e8f\uff0c\u53ea\u8c03\u7528\u6bcf\u4e2a\u7236\u7c7b\u4e00\u6b21\uff0c\u5e76\u4e14\u4fdd\u6301\u5355\u8c03\uff08monotonic\uff09\uff08\u5373\u4e00\u4e2a\u7c7b\u53ef\u4ee5\u88ab\u5b50\u7c7b\u5316\u800c\u4e0d\u5f71\u54cd\u5176\u7236\u7c7b\u7684\u4f18\u5148\u987a\u5e8f\uff09\u3002 \u603b\u800c\u8a00\u4e4b\uff0c\u8fd9\u4e9b\u7279\u6027\u4f7f\u5f97\u8bbe\u8ba1\u5177\u6709\u591a\u91cd\u7ee7\u627f\u7684\u53ef\u9760\u4e14\u53ef\u6269\u5c55\u7684\u7c7b\u6210\u4e3a\u53ef\u80fd\u3002 \u770b\u4e0b\u9762\u4f8b\u5b50\uff0c\u5b9a\u4e49\u4e863\u4e2a\u7c7b\u548c\u7ee7\u627f\u5173\u7cfb\u3002 class F (): def drink ( self ): print ( \"Drink Beer\" ) class M (): def drink ( self ): print ( \"Drink Red Wine\" ) class C ( F , M ): def drink ( self ): print ( \"Drink Water\" ) \u6267\u884c\u7ed3\u679c\u662f c = C () c . drink () # Drink Water \u65b9\u6cd51\uff1a\u6309\u7167mro\u8fdb\u884c\u7ee7\u627f\u67e5\u627e\u3002 \u5982\u679c\u628a C \u7c7b\u6539\u5199\u4e3a\u5982\u4e0b\uff0c\u53ef\u4ee5\u8c03\u7528\u7236\u7c7b\uff0c\u53c2\u7167 C \u7c7b\u7684mro\u8fdb\u884c\uff0c mro \u91cc\u9762\u7c7b F \u7684\u4e0a\u4e00\u7ea7\u662f\u7c7b M \uff0c\u6240\u4ee5\u7c7b F \u4e2d\u7684 super() \u5c31\u662f\u6307\u7c7b M \u3002 class C ( F , M ): def drink ( self ): super () . drink () print ( \"Drink Water\" ) c = C () c . drink () # Drink Beer # Drink Water C . mro () # [, , , ] \u65b9\u6cd52\uff1a\u201c\u6307\u540d\u9053\u59d3\u201d\u8c03\u7528\u3002\u5982\u679c\u628a C \u7c7b\u6539\u5199\u4e3a\u5982\u4e0b\uff0c\u53ef\u4ee5\u8c03\u7528 M \u7c7b\u3002 class C ( F , M ): def drink ( self ): M . drink ( self ) print ( \"Drink Water\" ) c = C () c . drink () # Drink Red Wine # Drink Water","title":"\u591a\u91cd\u7ee7\u627f Multiple Inheritance"},{"location":"python/Foundation/ch05/#_1","text":"\u83f1\u5f62\u7ee7\u627f\u7684\u63cf\u8ff0\u662f\uff0c\u7c7b A \u4f5c\u4e3a\u57fa\u7c7b\uff08\u8fd9\u91cc\u57fa\u7c7b\u662f\u6307\u975e object \u7c7b\uff09\uff0c\u7c7b B \u548c\u7c7b C \u540c\u65f6\u7ee7\u627f\u7c7b A \uff0c\u7136\u540e\u7c7b D \u53c8\u7ee7\u627f\u7c7b B \u548c\u7c7b C \uff0c\u5982\u4e0b\u56fe\uff0c\u770b\u8d77\u6765\u50cf\u4e2a\u94bb\u77f3\u7684\u5f62\u72b6\u3002 A / \\ B C \\ / D \u5728\u8fd9\u79cd\u7ed3\u6784\u4e2d\uff0c\u5728\u8c03\u7528\u987a\u5e8f\u4e0a\u5c31\u4f1a\u51fa\u73b0\u7591\u60d1\uff0c\u8c03\u7528\u987a\u5e8f\u7a76\u7adf\u662f\u4ee5\u4e0b\u54ea\u4e00\u79cd\u987a\u5e8f\u5462\uff1f D->B->A->C\uff08\u6df1\u5ea6\u4f18\u5148\uff09 D->B->C->A\uff08\u5e7f\u5ea6\u4f18\u5148\uff09 \u770b\u4e0b\u9762\u4ee3\u7801\uff0c\u5728Python3\u4e2d\uff0c**\u83f1\u5f62**\u7684\u591a\u7ee7\u627f\u5173\u7cfb\u662f\u6309\u7167D->B->C->A**\u5e7f\u5ea6\u4f18\u5148**\u7684\u641c\u7d22\u65b9\u5f0f\u3002 class A (): pass class B ( A ): def test ( self ): print ( \"init B.test()\" ) class C ( A ): def test ( self ): print ( \"init C.test()\" ) class D ( B , C ): pass d = D () d . test () # init B.test() D . mro () # [, , , , ] \u5bf9\u4e8e\u4e0b\u9762\u8fd9\u79cd**\u975e\u83f1\u5f62**\u7684\u591a\u7ee7\u627f\u5173\u7cfb\uff0c\u67e5\u627e\u987a\u5e8f\u662fA->B->E->C->F->D**\u6df1\u5ea6\u4f18\u5148**\u7684\u641c\u7d22\u65b9\u5f0f\u3002 E F | | B ( E ) C ( F ) D | | | \\ | / \\ | / A ( B , C , D ) \u4ee3\u7801\u5b9e\u73b0\uff1a class D (): def test ( self ): print ( \"init D.test()\" ) class F (): def test ( self ): print ( \"init F.test()\" ) class C ( F ): pass class E (): pass class B ( E ): pass class A ( B , C , D ): pass a = A () a . test () # init F.test() A . mro () # [, , , , , , ] \u603b\u7ed3\uff1a \u7ee7\u627f\u7ed3\u6784\u8981\u5c3d\u91cf\u7b80\u5355\uff0c\u4e0d\u8981\u8fc7\u4e8e\u590d\u6742\u3002 \u63a8\u8350\u4f7f\u7528minxins\u673a\u5236\uff0c\u5728\u591a\u7ee7\u627f\u80cc\u666f\u4e0b\uff0c\u6ee1\u8db3\u7ee7\u627f\u7684\u4ec0\u4e48\u662f\u4ec0\u4e48\u7684\u5173\u7cfb\uff08is-a\uff09","title":"\u83f1\u5f62\u7ee7\u627f\u548c\u7ee7\u627f\u5173\u7cfb\u68c0\u6d4b"},{"location":"python/Foundation/ch05/#minxins","text":"\u770b\u4e0b\u9762\u4f8b\u5b50\uff0c\u5982\u679c\u5728 Vehicle \u7c7b\u4e2d\u5b9a\u4e49\u4e86 fly \u7684\u65b9\u6cd5\uff0c\u4f1a\u5bfc\u81f4 Car(Vehicle) \u7684\u7ee7\u627f\u5173\u7cfb\u51fa\u73b0\u77db\u76fe\uff0c\u6c7d\u8f66\u5e76\u4e0d\u4f1a\u98de\uff0c\u4f46\u6309\u7167\u4e0a\u8ff0\u7ee7\u627f\u5173\u7cfb\uff0c\u6c7d\u8f66\u4e5f\u80fd\u98de\u4e86\u3002 \u4f46\u662f\u5982\u679c\u6c11\u822a\u98de\u673a\u548c\u76f4\u5347\u673a\u90fd\u5404\u81ea\u5199\u81ea\u5df1\u7684\u98de\u884cfly\u65b9\u6cd5\uff0c\u53c8\u8fdd\u80cc\u4e86\u4ee3\u7801\u5c3d\u53ef\u80fd\u91cd\u7528\u7684\u539f\u5219\u3002 class Vehicle : # \u4ea4\u901a\u5de5\u5177 def fly ( self ): ''' \u98de\u884c\u529f\u80fd\u76f8\u5e94\u7684\u4ee3\u7801 ''' print ( \"I am flying\" ) # \u6c11\u822a\u98de\u673a class CivilAircraft ( Vehicle ): pass # \u76f4\u5347\u98de\u673a class Helicopter ( Vehicle ): pass # \u6c7d\u8f66 class Car ( Vehicle ): pass Python\u4e2d\u6ca1\u6709\u7c7b\u4f3cJava\u63a5\u53e3interface\u7684\u529f\u80fd\uff0c\u4f46\u63d0\u4f9b\u4e86Mixins\u673a\u5236\u3002 Python\u5bf9\u4e8e Mixin \u7c7b\u7684\u547d\u540d\u65b9\u5f0f\u4e00\u822c\u4ee5 Mixin , able , ible \u4e3a\u540e\u7f00\u3002 Mixin \u7c7b\u5fc5\u987b\u529f\u80fd\u5355\u4e00\uff0c\u5982\u679c\u6709\u591a\u4e2a\u529f\u80fd\uff0c\u90a3\u5c31\u5199\u591a\u4e2aMixin\u7c7b\u3002 \u4e00\u4e2a\u7c7b\u53ef\u4ee5\u7ee7\u627f\u591a\u4e2a Mixin \u7c7b\uff0c\u4e3a\u4e86\u4fdd\u8bc1\u9075\u5faa\u7ee7\u627f\u7684\u201cis-a\u201d\u539f\u5219\uff0c\u53ea\u80fd\u7ee7\u627f\u4e00\u4e2a\u6807\u8bc6\u5176\u5f52\u5c5e\u542b\u4e49\u7684\u7236\u7c7b Mixin \u7c7b\u4e0d\u4f9d\u8d56\u4e8e\u5b50\u7c7b\u7684\u5b9e\u73b0\u3002 \u5b50\u7c7b\u5373\u4fbf\u6ca1\u6709\u7ee7\u627f\u8fd9\u4e2a Mixin \u7c7b\u7c7b\uff0c\u4e5f\u7167\u6837\u53ef\u4ee5\u5de5\u4f5c\uff0c\u5c31\u662f\u7f3a\u5c11\u4e86\u67d0\u4e2a\u529f\u80fd\u3002 \u6211\u4eec\u5b9a\u4e49\u7684 Mixin \u7c7b\u8d8a\u591a\uff0c\u5b50\u7c7b\u7684\u4ee3\u7801\u53ef\u8bfb\u6027\u5c31\u4f1a\u8d8a\u5dee\u3002 # \u4ea4\u901a\u5de5\u5177 class Vehicle : pass # \u4e3a\u5f53\u524d\u7c7b\u6df7\u5165\u4e00\u4e9b\u529f\u80fd\uff0c\u4e0d\u662f\u4e00\u4e2a\u5355\u7eaf\u7684\u7c7b class FlyableMixin : def fly ( self ): ''' \u98de\u884c\u529f\u80fd\u76f8\u5e94\u7684\u4ee3\u7801 ''' print ( \"I am flying\" ) # \u6c11\u822a\u98de\u673a class CivilAircraft ( FlyableMixin , Vehicle ): pass # \u76f4\u5347\u98de\u673a class Helicopter ( FlyableMixin , Vehicle ): pass # \u6c7d\u8f66 class Car ( Vehicle ): pass","title":"\u591a\u7ee7\u627f\u5173\u7cfb\u7684minxins\u673a\u5236"},{"location":"python/Foundation/ch05/#class-combination","text":"\u5728\u4e00\u4e2a\u7c7b\u4e2d\u4ee5\u53e6\u4e00\u4e2a\u7c7b\u7684\u5bf9\u8c61\u4f5c\u4e3a\u6570\u636e\u5c5e\u6027\uff0c\u79f0\u4e3a\u7c7b\u7684**\u7ec4\u5408**\u3002\u7ec4\u5408\u4e0e\u7ee7\u627f\u90fd\u662f\u7528\u6765\u89e3\u51b3\u4ee3\u7801\u7684\u91cd\u7528\u6027\u95ee\u9898\u3002 \u7ee7\u627f\u4f53\u73b0\u201c\u662f\u201d\u7684\u5173\u7cfb\uff0c\u5f53\u7c7b\u4e4b\u95f4\u6709\u5f88\u591a\u76f8\u540c\u4e4b\u5904\uff0c\u7528\u7ee7\u627f\u3002 \u7ec4\u5408\u4f53\u73b0\u201c\u6709\u201d\u7684\u5173\u7cfb\uff0c\u5f53\u7c7b\u4e4b\u95f4\u6709\u663e\u8457\u4e0d\u540c\uff0c\u4e00\u4e2a\u7c7b\u662f\u53e6\u4e00\u4e2a\u7c7b\u7684\u5c5e\u6027\u662f\uff0c\u7528\u7ec4\u5408\u3002 \u4e0b\u4f8b\u662f\u8ba1\u7b97\u5706\u73af\u7684\u9762\u79ef\u548c\u5468\u957f\uff0c\u5706\u73af\u662f\u7531\u4e24\u4e2a\u5706\u7ec4\u6210\u7684\uff0c\u5706\u73af\u7684\u9762\u79ef\u662f\u5916\u9762\u5706\u7684\u9762\u79ef\u51cf\u53bb\u5185\u90e8\u5706\u7684\u9762\u79ef\u3002\u5706\u73af\u7684\u5468\u957f\u662f\u5185\u90e8\u5706\u7684\u5468\u957f\u52a0\u4e0a\u5916\u90e8\u5706\u7684\u5468\u957f\u3002 \u8fd9\u4e2a\u4f8b\u5b50\u6f14\u793a\u4e86\u7c7b ring \u91cc\u9762\u7684\u5c5e\u6027 circle1 \u548c circle2 \u6b63\u662f\u53e6\u4e00\u4e2a\u7c7b Circle \u3002 from math import pi class Circle (): def __init__ ( self , r ): self . r = r def area ( self ): return pi * self . r * self . r def perimeter ( self ): return 2 * pi * self . r class Ring (): def __init__ ( self , r1 , r2 ): self . circle1 = Circle ( r1 ) self . circle2 = Circle ( r2 ) def area ( self ): return abs ( self . circle1 . area () - self . circle2 . area ()) def permiter ( self ): return self . circle1 . perimeter () + self . circle2 . perimeter () ring = Ring ( 5 , 8 ) print ( ring . area ()) # 122.52211349000193 print ( ring . permiter ()) # 81.68140899333463 \u4e0b\u9762\u7684\u4f8b\u5b50\u6f14\u793a\u4e86\u5982\u4f55\u901a\u8fc7\u4f20\u53c2\u7684\u65b9\u5f0f\u8fdb\u884c\u7c7b\u7684\u7ec4\u5408\u3002 class Birthday (): def __init__ ( self , year , month , day ): self . year = year self . month = month self . day = day class Course (): def __init__ ( self , course_name , course_period ): self . course_name = course_name self . course_period = course_period class Professor (): def __init__ ( self , name , gender , birth , course ): self . name = name self . gender = gender self . birth = birth self . course = course def teach ( self ): print ( f \"Professor name: { self . name } ; Gender: { self . gender } ; Birthday: { self . birth . year } - { self . birth . month }{ self . birth . day } , Course name: { self . course . course_name } and period: { self . course . course_period } \" ) prof = Professor ( 'Tom' , 'Male' , Birthday ( 1985 , 5 , 5 ), Course ( 'Chinese' , '2022/3/1 ~ 2022/6/30' )) prof . teach () # Professor name: Tom; Gender: Male; Birthday: 1985-55, Course name: Chinese and period: 2022/3/1 ~ 2022/6/30","title":"\u7ec4\u5408\uff08Class Combination\uff09"},{"location":"python/Foundation/ch05/#polymorphism","text":"\u591a\u6001\u610f\u5473\u7740\u76f8\u540c\u7684\u51fd\u6570\u540d\u7528\u4e8e\u4e0d\u540c\u7684\u60c5\u5f62\u3002 \u5982\u4e0b\u4f8b\uff0c len() \u88ab\u7528\u4e8e\u4e0d\u540c\u7684\u60c5\u5f62\u3002 # len() being used for a string print ( len ( \"geeks\" )) # 5 # len() being used for a list print ( len ([ 10 , 20 , 30 ])) # 3","title":"\u591a\u6001 Polymorphism"},{"location":"python/Foundation/ch05/#_2","text":"\u4e0b\u9762\u7684\u4ee3\u7801\u5c55\u793a\u4e86 Python \u5982\u4f55\u4ee5\u76f8\u540c\u7684\u65b9\u5f0f\u4f7f\u7528\u4e24\u79cd\u4e0d\u540c\u7684\u7c7b\u7c7b\u578b\u3002 \u6211\u4eec\u521b\u5efa\u4e86\u4e00\u4e2a\u904d\u5386\u5bf9\u8c61\u5143\u7ec4\u7684 for \u5faa\u73af\u3002 \u7136\u540e\u8c03\u7528\u65b9\u6cd5\u800c\u4e0d\u7528\u5173\u5fc3\u6bcf\u4e2a\u5bf9\u8c61\u662f\u54ea\u4e2a\u7c7b\u7c7b\u578b\u3002 \u6211\u4eec\u5047\u8bbe\u8fd9\u4e9b\u65b9\u6cd5\u5b9e\u9645\u4e0a\u5b58\u5728\u4e8e\u6bcf\u4e2a\u7c7b\u4e2d\u3002 class India (): def capital ( self ): print ( \"New Delhi is the capital of India.\" ) def language ( self ): print ( \"Hindi is the most widely spoken language of India.\" ) def type ( self ): print ( \"India is a developing country.\" ) class USA (): def capital ( self ): print ( \"Washington, D.C. is the capital of USA.\" ) def language ( self ): print ( \"English is the primary language of USA.\" ) def type ( self ): print ( \"USA is a developed country.\" ) obj_ind = India () obj_usa = USA () for country in ( obj_ind , obj_usa ): country . capital () country . language () country . type () # New Delhi is the capital of India. # Hindi is the most widely spoken language of India. # India is a developing country. # Washington, D.C. is the capital of USA. # English is the primary language of USA. # USA is a developed country.","title":"\u7c7b\u65b9\u6cd5\u7684\u591a\u6001\u6027"},{"location":"python/Foundation/ch05/#_3","text":"\u5728 Python \u4e2d\uff0c\u591a\u6001\u5141\u8bb8\u6211\u4eec\u5728\u5b50\u7c7b\u4e2d\u5b9a\u4e49\u4e0e\u7236\u7c7b\u4e2d\u7684\u65b9\u6cd5\u540c\u540d\u7684\u65b9\u6cd5\u3002 \u5728\u7ee7\u627f\u4e2d\uff0c\u5b50\u7c7b\u7ee7\u627f\u7236\u7c7b\u7684\u65b9\u6cd5\u3002 \u4f46\u662f\uff0c\u53ef\u4ee5\u4fee\u6539\u4ece\u7236\u7c7b\u7ee7\u627f\u7684\u5b50\u7c7b\u4e2d\u7684\u65b9\u6cd5\u3002 \u8fd9\u5728\u4ece\u7236\u7c7b\u7ee7\u627f\u7684\u65b9\u6cd5\u4e0d\u592a\u9002\u5408\u5b50\u7c7b\u7684\u60c5\u51b5\u4e0b\u7279\u522b\u6709\u7528\u3002 \u5728\u8fd9\u79cd\u60c5\u51b5\u4e0b\uff0c\u6211\u4eec\u5728\u5b50\u7c7b\u4e2d\u91cd\u65b0\u5b9e\u73b0\u8be5\u65b9\u6cd5\u3002 \u8fd9\u79cd\u5728\u5b50\u7c7b\u4e2d\u91cd\u65b0\u5b9e\u73b0\u65b9\u6cd5\u7684\u8fc7\u7a0b\u79f0\u4e3a**\u65b9\u6cd5\u8986\u76d6\uff08Method Overriding\uff09**\u3002 class Bird : def intro ( self ): print ( \"There are many types of birds.\" ) def flight ( self ): print ( \"Most of the birds can fly but some cannot.\" ) class sparrow ( Bird ): def flight ( self ): print ( \"Sparrows can fly.\" ) class ostrich ( Bird ): def flight ( self ): print ( \"Ostriches cannot fly.\" ) obj_bird = Bird () obj_spr = sparrow () obj_ost = ostrich () obj_bird . intro () # There are many types of birds. obj_bird . flight () # Most of the birds can fly but some cannot. obj_spr . intro () # There are many types of birds. obj_spr . flight () # Sparrows can fly. obj_ost . intro () # There are many types of birds. obj_ost . flight () # Ostriches cannot fly.","title":"\u7ee7\u627f\u7684\u591a\u6001\u6027"},{"location":"python/Foundation/ch05/#_4","text":"\u6211\u4eec\u4e5f\u53ef\u4ee5\u521b\u5efa\u4e00\u4e2a\u53ef\u4ee5\u63a5\u53d7\u4efb\u4f55\u5bf9\u8c61\u7684\u51fd\u6570\uff0c\u5141\u8bb8\u591a\u6001\u6027\u3002 \u5728\u4e0b\u9762\u4f8b\u5b50\u4e2d\uff0c\u6211\u4eec\u521b\u5efa\u4e00\u4e2a\u540d\u4e3a func() \u7684\u51fd\u6570\uff0c\u4f20\u5165\u53c2\u6570\u662f obj \u7684\u5bf9\u8c61\u3002 \u5728\u8fd9\u79cd\u60c5\u51b5\u4e0b\uff0c\u6211\u4eec\u8c03\u7528\u4e09\u4e2a\u65b9\u6cd5\uff0c\u5373 capital() \u3001 language() \u548c type() \uff0c\u6bcf\u4e2a\u65b9\u6cd5\u90fd\u5b9a\u4e49\u5728 India \u548c USA \u4e24\u4e2a\u7c7b\u4e2d\u3002 \u6211\u4eec\u53ef\u4ee5\u4f7f\u7528\u76f8\u540c\u7684 func() \u51fd\u6570\u8c03\u7528\u5b83\u4eec\u7684\u52a8\u4f5c\uff1a class India (): def capital ( self ): print ( \"New Delhi is the capital of India.\" ) def language ( self ): print ( \"Hindi is the most widely spoken language of India.\" ) def type ( self ): print ( \"India is a developing country.\" ) class USA (): def capital ( self ): print ( \"Washington, D.C. is the capital of USA.\" ) def language ( self ): print ( \"English is the primary language of USA.\" ) def type ( self ): print ( \"USA is a developed country.\" ) def func ( obj ): obj . capital () obj . language () obj . type () obj_ind = India () obj_usa = USA () func ( obj_ind ) # New Delhi is the capital of India. # Hindi is the most widely spoken language of India. # India is a developing country. func ( obj_usa ) # Washington, D.C. is the capital of USA. # English is the primary language of USA. # USA is a developed country.","title":"\u51fd\u6570\u548c\u5bf9\u8c61\u7684\u591a\u6001\u6027"},{"location":"python/Foundation/ch05/#ducking-typinggoose-typing","text":"\u5728Python\u4e2d\u5b9e\u73b0\u591a\u6001\u4e3b\u8981\u6709\u4e24\u79cd\u673a\u5236\uff1a\u767d\u9e45\u7c7b\u578b\u548c\u9e2d\u5b50\u7c7b\u578b\u3002\u767d\u9e45\u7c7b\u578b\u548c\u9e2d\u5b50\u7c7b\u578b\u4e0d\u4ec5\u662f\u4e24\u79cd\u673a\u5236\uff0c\u4e5f\u662f\u4e24\u79cd\u4e0d\u540c\u7684\u7f16\u7a0b\u98ce\u683c\u3002 \u4e0b\u9762\u662f\u4e00\u4e2a\u6253\u5370\u5546\u54c1\u4ef7\u683c\u7684\u4f8b\u5b50\uff0c\u5206\u522b\u7528\u9e2d\u5b50\u7c7b\u578b\u548c\u767d\u9e45\u7c7b\u578b\u5b9e\u73b0\u3002 \u9e2d\u5b50\u7c7b\u578b\u3002 \u5728\u9e2d\u5b50\u7c7b\u578b\u7684\u5b9e\u73b0\u4e2d\uff0c\u6211\u4eec\u53ea\u9700\u8981\u4fdd\u8bc1\u8c03\u7528 price \u65b9\u6cd5\u7684\u6bcf\u4e2a\u5bf9\u8c61\u90fd\u6709 price \u65b9\u6cd5\u5373\u53ef\u3002 class Food : def price ( self ): print ( \" {} price:$4\" . format ( __class__ . __name__ )) class Clothes : def price ( self ): print ( \" {} price:$5\" . format ( __class__ . __name__ )) class Coffee : def price ( self ): print ( \" {} price:$6\" . format ( __class__ . __name__ )) if __name__ == '__main__' : goods = [ Food (), Clothes (), Coffee ()] for good in goods : good . price () # Food price:$4 # Clothes price:$5 # Coffee price:$6 \u767d\u9e45\u7c7b\u578b\u3002 \u5728\u767d\u9e45\u7c7b\u578b\u4e2d\uff0c\u76f4\u63a5\u8ba9\u6240\u6709\u5bf9\u8c61\u7684\u7c7b\u7ee7\u627f\u7236\u7c7b Good \u4e2d\u7684\u62bd\u8c61\u65b9\u6cd5 price \u3002Python\u4e2d\u7684\u767d\u9e45\u7c7b\u578b\u673a\u5236\u5c31\u662f\u5f3a\u7c7b\u578b\u8bed\u8a00\u4e2d\u5b9e\u73b0\u591a\u6001\u7684\u6807\u51c6\u6a21\u5f0f\uff0c\u5373\u901a\u8fc7\u8c03\u53d6\u7236\u7c7b\u7684\u865a\u51fd\u6570\u6216\u8005\u7ee7\u627f\u7684\u51fd\u6570\u6765\u5b8c\u6210\u4e0d\u540c\u7684\u884c\u4e3a\u3002 import abc class Good ( abc . ABC ): @abc . abstractmethod def price ( self ): pass class Food ( Good ): def price ( self ): print ( \" {} price:$4\" . format ( __class__ . __name__ )) class Clothes ( Good ): def price ( self ): print ( \" {} price:$5\" . format ( __class__ . __name__ )) if __name__ == '__main__' : goods = [ Food (), Clothes (), Coffee ()] for good in goods : good . price () # Food price:$4 # Clothes price:$5 # Coffee price:$6","title":"\u9e2d\u5b50\u7c7b\u578b\uff08Ducking Typing\uff09\u548c\u767d\u9e45\u7c7b\u578b\uff08Goose Typing\uff09"},{"location":"python/Foundation/ch05/#class-methodstatic-method","text":"\u7c7b\u65b9\u6cd5\uff08Class method\uff09\u4e5f\u53eb\u7ed1\u5b9a\u65b9\u6cd5\uff0c\u5fc5\u987b\u628a\u7c7b\u4f5c\u4e3a\u4f20\u5165\u53c2\u6570\uff0c\u4f7f\u7528 cls \u4f5c\u4e3a\u7b2c\u4e00\u4e2a\u4f20\u5165\u53c2\u6570\uff0c\u800c\u9759\u6001\u65b9\u6cd5\uff08Static Method\uff09\uff0c\u4e5f\u53eb\u975e\u7ed1\u5b9a\u65b9\u6cd5\uff0c\u4e0d\u9700\u8981\u7279\u5b9a\u7684\u53c2\u6570\u3002 \u7c7b\u65b9\u6cd5\u662f\u7ed1\u5b9a\u5230\u7c7b\u7684\uff0c\u4e0d\u662f\u7ed1\u5b9a\u5230\u7c7b\u5bf9\u8c61\uff0c\u6240\u4ee5\u7c7b\u65b9\u6cd5\u53ef\u4ee5\u8bbf\u95ee\u6216\u4fee\u6539\u7c7b\uff0c\u5e76\u5bf9\u6240\u6709\u7c7b\u5b9e\u4f8b\u751f\u6548\u3002 \u9759\u6001\u65b9\u6cd5\u65e0\u6cd5\u76f4\u63a5\u8bbf\u95ee\u6216\u4fee\u6539\u7c7b\uff0c\u56e0\u4e3a\u9759\u6001\u65b9\u6cd5\u662f\u4e0d\u77e5\u9053\u7c7b\u672c\u8eab\u7684\uff0c\u9759\u6001\u65b9\u6cd5\u662f\u5c5e\u4e8e\u5de5\u5177\u7c7b\u65b9\u6cd5\uff0c\u57fa\u4e8e\u4f20\u5165\u7684\u53c2\u6570\u5b8c\u6210\u7279\u5b9a\u7684\u529f\u80fd\uff0c\u5176\u5b9e\u5c31\u662f\u4e00\u4e2a\u666e\u901a\u51fd\u6570\u800c\u5df2\u3002 Python\u4e2d\u4f7f\u7528 @classmethod \u88c5\u9970\u5668\uff08decorator\uff09\u6765\u521b\u5efa\u4e00\u4e2a\u7c7b\u65b9\u6cd5\uff0c\u7528@staticmethod\u88c5\u9970\u5668\u6765\u521b\u5efa\u4e00\u4e2a\u9759\u6001\u65b9\u6cd5\u3002 \u8bed\u6cd5\u683c\u5f0f\uff1a @classmethod def fun ( cls , arg1 , arg2 , ... ): \u5176\u4e2d\uff1a fun : \u9700\u8981\u8f6c\u6362\u6210\u7c7b\u65b9\u6cd5\u7684\u51fd\u6570 returns : \u51fd\u6570\u7684\u7c7b\u65b9\u6cd5 classmethod() \u65b9\u6cd5\u7ed1\u5b9a\u5230\u7c7b\u800c\u4e0d\u662f\u5bf9\u8c61\u3002\u7c7b\u65b9\u6cd5\u53ef\u4ee5\u88ab\u7c7b\u548c\u5bf9\u8c61\u8c03\u7528\u3002\u8fd9\u4e9b\u65b9\u6cd5\u53ef\u4ee5\u901a\u8fc7\u7c7b\u6216\u5bf9\u8c61\u8fdb\u884c\u8c03\u7528\u3002 \u4f8b1\uff1a\u521b\u5efa\u4e00\u4e2a\u7b80\u5355\u7684 classmethod \u3002 \u521b\u5efa\u4e00\u4e2a\u7c7b Training \uff0c\u6709\u7c7b\u53d8\u91cf course \u548c\u65b9\u6cd5 purchase \u3002 \u6211\u4eec\u901a\u8fc7\u628a\u51fd\u6570 Training.purchase \u4f20\u7ed9 classmethod() \uff0c\u628a\u8be5\u65b9\u6cd5\u8f6c\u6210\u7c7b\u65b9\u6cd5\uff0c\u7136\u540e\u76f4\u63a5\u8c03\u7528\u5b83\uff0c\u800c\u65e0\u9700\u5148\u521b\u5efa\u5bf9\u8c61\u3002 \u53ef\u4ee5\u770b\u51fa\u8f6c\u6362\u524d\u540e Training.purchase \u7684\u7c7b\u578b\u53d8\u5316\u3002 class Training : course = 'Python for Data Analysis' def purchase ( obj ): print ( \"Puchase course : \" , obj . course ) type ( Training . purchase ) # Training . purchase = classmethod ( Training . purchase ) Training . purchase () # Puchase course : Python for Data Analysis type ( Training . purchase ) # \u4f8b2\uff1a\u4f7f\u7528\u88c5\u9970\u5668 @classmethod \u521b\u5efa\u5de5\u5382\u7c7b\u3002 class Training : def __init__ ( self , course ): self . course = course @classmethod def purchase ( cls , course ): return cls ( course ) def display ( self ): print ( 'Purchase course: ' , self . course ) training = Training ( \"Python for Data Analysis\" ) training . display () # Purchase course: Python for Data Analysis \u4f8b3\uff1a\u901a\u8fc7 staticmethod() \u548c classmethod() \u6765\u68c0\u67e5\u4e00\u4e2aperson\u662f\u5426\u662fadult\u3002 person1\u662f\u901a\u8fc7\u59d3\u540d\u548c\u5e74\u9f84\u521b\u5efa\u7684\u5b9e\u4f8b\u3002person2\u662f\u901a\u8fc7\u59d3\u540d\u548c\u5e74\u4efd\u521b\u5efa\u7684\u5b9e\u4f8b\u3002 from datetime import date class Person : def __init__ ( self , name , age ): self . name = name self . age = age @classmethod def fromBirthYear ( cls , name , year ): return cls ( name , date . today () . year - year ) @staticmethod def isAdult ( age ): return age > 18 person1 = Person ( 'mayank' , 21 ) person2 = Person . fromBirthYear ( 'mayank' , 1996 ) print ( person1 . age ) # 21 print ( person2 . age ) # 26 print ( Person . isAdult ( 22 )) # True \u5c0f\u7ed3\uff1a \u82e5\u7c7b\u4e2d\u9700\u8981\u4e00\u4e2a\u529f\u80fd\uff0c\u8be5\u529f\u80fd\u7684\u5b9e\u73b0\u4ee3\u7801\u4e2d\u9700\u8981\u5f15\u7528\u5bf9\u8c61\uff0c\u5219\u5c06\u5176\u5b9a\u4e49\u6210\u5bf9\u8c61\u65b9\u6cd5\uff1b\u9700\u8981\u5f15\u7528\u7c7b\uff0c\u5219\u5c06\u5176\u5b9a\u4e49\u6210\u7c7b\u65b9\u6cd5\uff1b\u65e0\u9700\u5f15\u7528\u7c7b\u6216\u5bf9\u8c61\uff0c\u5219\u5c06\u5176\u5b9a\u4e49\u6210\u9759\u6001\u65b9\u6cd5\u3002","title":"\u7c7b\u65b9\u6cd5\uff08Class method\uff09\u548c\u9759\u6001\u65b9\u6cd5\uff08Static Method\uff09"},{"location":"python/Foundation/ch05/#monkey-patch","text":"\u7334\u5b50\u8865\u4e01\u662f\u52a8\u6001\u4e3a\u5df2\u7ecf\u521b\u5efa\u51fa\u7684\u5bf9\u8c61\u589e\u52a0\u65b0\u7684\u65b9\u6cd5\u548c\u5c5e\u6027\u6210\u5458\u7684\u4e00\u79cd\u673a\u5236\uff0c\u4e5f\u5c31\u662f\u52a8\u6001\u6253\u8865\u4e01\u3002 \u5b9e\u4f8b\u5316\u5bf9\u8c61\u7684\u7334\u5b50\u8865\u4e01\u3002 class Test : def __init__ ( self ): self . a = 1 def func1 ( self , x , y ): print ( x + y ) # \u6b63\u5e38\u5b9e\u4f8b\u5316 test = Test () test . func1 ( 1 , 1 ) # 2 # \u4fee\u6539\u5b9e\u4f8b test . func1 = lambda x , y : print ( x + 2 * y ) test . func1 ( 1 , 1 ) # 3 # \u901a\u8fc7\u4fee\u6539\u5b9e\u4f8b\uff0c\u8bbf\u95ee\u5185\u90e8\u6210\u5458\u53d8\u91cf\u3002 test . func1 = lambda x , y : print ( x + 2 * y + self . a ) test . func1 ( 1 , 1 ) # NameError: name 'self' is not defined test . func1 = lambda self , x , y : print ( x + 2 * y + self . a ) test . func1 ( test , 1 , 1 ) # 4 \u7c7b\u5bf9\u8c61\u7684\u7334\u5b50\u8865\u4e01\u3002 class Test : def __init__ ( self ): self . a = 1 def func1 ( self , x , y ): print ( x + y ) # \u4fee\u6539\u7c7b\u6210\u5458\uff0c\u5b9e\u4f8b\u5316\u540e\u7684\u7ed3\u679c\u5df2\u4fee\u6539\u3002 Test . func1 = lambda self , x , y : print ( x + 2 * y ) test = Test () test . func1 ( 1 , 1 ) # 3 # \u4fee\u6539\u7c7b\u6210\u5458\uff0c\u5e76\u8bbf\u95ee\u6210\u5458\u53d8\u91cf\uff0c\u5b9e\u4f8b\u5316\u540e\u7684\u7ed3\u679c\u5df2\u4fee\u6539\u3002 Test . func1 = lambda self , x , y : print ( x + 2 * y + self . a ) test = Test () test . func1 ( 1 , 1 ) # 4 # \u589e\u52a0\u7c7b\u6210\u5458\u3002 Test . func2 = lambda self , p , q : print ( p + 3 * q + self . a ) test = Test () test . func1 ( 1 , 1 ) # 4 test . func2 ( 1 , 3 ) # 11","title":"\u7334\u5b50\u8865\u4e01\uff08monkey patch\uff09"},{"location":"python/Foundation/ch05/#private-variables","text":"\u90a3\u79cd\u4ec5\u9650\u4ece\u4e00\u4e2a\u5bf9\u8c61\u5185\u90e8\u8bbf\u95ee\u7684\u201c\u79c1\u6709\u201d\u5b9e\u4f8b\u53d8\u91cf\uff08\u201cPrivate\u201d instance variables\uff09\u5728 Python \u4e2d\u5e76\u4e0d\u5b58\u5728\u3002 \u4f46\u662f\uff0c\u5927\u591a\u6570 Python \u4ee3\u7801\u90fd\u9075\u5faa\u8fd9\u6837\u4e00\u4e2a\u7ea6\u5b9a\uff1a\u5e26\u6709*\u4e00\u4e2a\u524d\u7f00\u4e0b\u5212\u7ebf*\u7684\u540d\u79f0 (\u4f8b\u5982 _spam ) \u5e94\u8be5\u88ab\u5f53\u4f5c\u662f API \u7684\u975e\u516c\u6709\uff08non-public\uff09\u90e8\u5206 (\u65e0\u8bba\u5b83\u662f\u51fd\u6570\u3001\u65b9\u6cd5\u6216\u662f\u6570\u636e\u6210\u5458)\u3002 \u8fd9\u5e94\u5f53\u88ab\u89c6\u4e3a\u4e00\u4e2a\u5b9e\u73b0\u7ec6\u8282\uff0c\u53ef\u80fd\u4e0d\u7ecf\u901a\u77e5\u5373\u52a0\u4ee5\u6539\u53d8\u3002 \u7531\u4e8e\u5b58\u5728\u5bf9\u4e8e\u7c7b\u79c1\u6709\u6210\u5458\uff08class-private members\uff09\u7684\u6709\u6548\u4f7f\u7528\u573a\u666f\uff08\u4f8b\u5982\u907f\u514d\u540d\u79f0\u4e0e\u5b50\u7c7b\u6240\u5b9a\u4e49\u7684\u540d\u79f0\u76f8\u51b2\u7a81\uff09\uff0c\u56e0\u6b64\u5b58\u5728\u5bf9\u6b64\u79cd\u673a\u5236\u7684\u6709\u9650\u652f\u6301\uff0c\u79f0\u4e3a**\u540d\u79f0\u6539\u5199\uff08name mangling\uff09**\u3002 \u4efb\u4f55\u5f62\u5f0f\u4e3a __spam \u7684\u6807\u8bc6\u7b26\uff08\u81f3\u5c11\u5e26\u6709*\u4e24\u4e2a\u524d\u7f00\u4e0b\u5212\u7ebf*\uff0c\u81f3\u591a\u4e00\u4e2a\u540e\u7f00\u4e0b\u5212\u7ebf\uff09\u7684\u6587\u672c\u5c06\u88ab\u66ff\u6362\u4e3a _classname__spam \uff0c\u5176\u4e2d classname \u4e3a\u53bb\u9664\u4e86\u524d\u7f00\u4e0b\u5212\u7ebf\u7684\u5f53\u524d\u7c7b\u540d\u79f0\u3002 \u8fd9\u79cd\u6539\u5199\u4e0d\u8003\u8651\u6807\u8bc6\u7b26\u7684\u53e5\u6cd5\u4f4d\u7f6e\uff0c\u53ea\u8981\u5b83\u51fa\u73b0\u5728\u7c7b\u5b9a\u4e49\u5185\u90e8\u5c31\u4f1a\u8fdb\u884c\u3002 \u540d\u79f0\u6539\u5199\uff08Name mangling\uff09\u6709\u52a9\u4e8e\u8ba9\u5b50\u7c7b\u91cd\u8f7d\u65b9\u6cd5\uff08\uff09override methods\u800c\u4e0d\u7834\u574f\u7c7b\u5185\u65b9\u6cd5\uff08intraclass method\uff09\u8c03\u7528\u3002\u4f8b\u5982: class Mapping : def __init__ ( self , iterable ): self . items_list = [] self . __update ( iterable ) def update ( self , iterable ): for item in iterable : self . items_list . append ( item ) __update = update # private copy of original update() method class MappingSubclass ( Mapping ): def update ( self , keys , values ): # provides new signature for update() # but does not break __init__() for item in zip ( keys , values ): self . items_list . append ( item ) \u4e0a\u9762\u7684\u793a\u4f8b\u5373\u4f7f\u5728 MappingSubclass \u5f15\u5165\u4e86\u4e00\u4e2a __update \u6807\u8bc6\u7b26\u7684\u60c5\u51b5\u4e0b\u4e5f\u4e0d\u4f1a\u51fa\u9519\uff0c\u56e0\u4e3a\u5b83\u4f1a\u5728 Mapping \u7c7b\u4e2d\u88ab\u66ff\u6362\u4e3a _Mapping__update \u800c\u5728 MappingSubclass \u7c7b\u4e2d\u88ab\u66ff\u6362\u4e3a _MappingSubclass__update \u3002 \u8bf7\u6ce8\u610f\uff0c\u6539\u5199\u89c4\u5219\uff08mangling rules\uff09\u7684\u8bbe\u8ba1\u4e3b\u8981\u662f\u4e3a\u4e86\u907f\u514d\u610f\u5916\u51b2\u7a81\uff1b\u8bbf\u95ee\u6216\u4fee\u6539\u79c1\u6709\u53d8\u91cf\u4ecd\u7136\u662f\u53ef\u80fd\u7684\u3002\u8fd9\u5728\u7279\u6b8a\u60c5\u51b5\u4e0b\u751a\u81f3\u4f1a\u5f88\u6709\u7528\uff0c\u4f8b\u5982\u5728\u8c03\u8bd5\u5668\uff08debugger\uff09\u4e2d\u3002 \u8bf7\u6ce8\u610f\u4f20\u9012\u7ed9 exec() \u6216 eval() \u7684\u4ee3\u7801\u4e0d\u4f1a\u628a\u53d1\u8d77\u8c03\u7528\u7c7b\u7684\u7c7b\u540d\u89c6\u4f5c\u5f53\u524d\u7c7b\uff1b\u8fd9\u7c7b\u4f3c\u4e8e global \u8bed\u53e5\u7684\u6548\u679c\uff0c\u56e0\u6b64\u8fd9\u79cd\u6548\u679c\u4ec5\u9650\u4e8e\u540c\u65f6\u7ecf\u8fc7\u5b57\u8282\u7801\u7f16\u8bd1\u7684\u4ee3\u7801\u3002 \u540c\u6837\u7684\u9650\u5236\u4e5f\u9002\u7528\u4e8e getattr() , setattr() \u548c delattr() \uff0c\u4ee5\u53ca\u5bf9\u4e8e __dict__ \u7684\u76f4\u63a5\u5f15\u7528\u3002","title":"\u79c1\u6709\u53d8\u91cf Private Variables"},{"location":"python/Foundation/ch05/#reflection","text":"\u53cd\u5c04(reflection)\u662f\u52a8\u6001\u8bed\u8a00\u7684\u4e00\u4e2a\u7279\u6027\u3002**\u53cd\u5c04\u673a\u5236**\u6307\u7684\u662f\u5728\u7a0b\u5e8f\u7684\u8fd0\u884c\u72b6\u6001\u4e2d\uff0c\u5bf9\u4e8e\u4efb\u610f\u4e00\u4e2a\u7c7b\uff0c\u90fd\u53ef\u4ee5\u77e5\u9053\u8fd9\u4e2a\u7c7b\u7684\u6240\u6709\u5c5e\u6027\u548c\u65b9\u6cd5\uff1b\u5bf9\u4e8e\u4efb\u610f\u4e00\u4e2a\u5bf9\u8c61\uff0c\u90fd\u80fd\u591f\u8c03\u7528\u4ed6\u7684\u4efb\u610f\u65b9\u6cd5\u548c\u5c5e\u6027\u3002\u8fd9\u79cd\u52a8\u6001\u83b7\u53d6\u7a0b\u5e8f\u4fe1\u606f\u4ee5\u53ca\u52a8\u6001\u8c03\u7528\u5bf9\u8c61\u7684\u529f\u80fd\u79f0\u4e3a\u53cd\u5c04\u673a\u5236\u3002 \u901a\u8fc7\u4e0b\u9762\u4f8b\u5b50\u53ef\u77e5\uff0c\u901a\u8fc7 dir(person) \u83b7\u53d6\u4efb\u610f\u4e00\u4e2a\u7c7b\u6216\u8005\u5bf9\u8c61\u7684\u5c5e\u6027\u5217\u8868\u3002\u901a\u8fc7\u5185\u7f6e\u51fd\u6570 hasattr \u3001 getattr \u3001 setattr \u3001 delattr \u64cd\u4f5c\u7c7b\u548c\u5bf9\u8c61\u3002 class Person : def __init__ ( self , name , age , gender ): self . name = name self . age = age self . gender = gender person = Person ( 'Tom' , 21 , 'Male' ) print ( dir ( person )) # ['__class__', '__delattr__', '__dict__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__gt__', '__hash__', '__init__', '__init_subclass__', '__le__', '__lt__', '__module__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', '__weakref__', 'age', 'gender', 'name'] # hasattr(object,'name') # \u6309\u5b57\u7b26\u4e32'name'\u5224\u65ad\u6709\u65e0\u5c5e\u6027person.name hasattr ( person , 'name' ) # True # getattr(object, 'name', default=None) # \u7b49\u540c\u4e8eperson.name,\u4e0d\u5b58\u5728\u8be5\u5c5e\u6027\u5219\u8fd4\u56de\u9ed8\u8ba4\u503cNone getattr ( person , 'name' , None ) # 'Tom' # setattr(x, 'y', v) # \u7b49\u540c\u4e8eperson.age = 18 setattr ( person , 'age' , 18 ) print ( person . age ) # 18 # delattr(x, 'y') # \u7b49\u540c\u4e8edel person.age delattr ( person , 'age' ) print ( person . age ) # AttributeError: 'Person' object has no attribute 'age' \u4e0b\u9762\u662f\u4e00\u4e2a\u5b9e\u9645\u5e94\u7528\u7684\u4f8b\u5b50\u3002 class FtpServer (): def server_run ( self ): while True : inp = input ( 'Input your command >>:' ) . strip () cmd , file = inp . split () if hasattr ( self , cmd ): func = getattr ( self , cmd ) func ( file ) def get ( self , file ): print ( f 'Downloading { file } ...' ) def put ( self , file ): print ( f 'Uploading { file } ...' ) ftp_server = FtpServer () ftp_server . server_run () # Input your command >>:get a.ext # Downloading a.ext... # Input your command >>:put a.txt # Uploading a.txt...","title":"\u53cd\u5c04(reflection)"},{"location":"python/Foundation/ch05/#iterators","text":"\u5728Python\u4e2d\uff0c\u5927\u591a\u6570\u5bb9\u5668\u5bf9\u8c61\uff08container object\uff09\u90fd\u53ef\u4ee5\u4f7f\u7528 for \u8bed\u53e5: for element in [ 1 , 2 , 3 ]: print ( element ) for element in ( 1 , 2 , 3 ): print ( element ) for key in { 'one' : 1 , 'two' : 2 }: print ( key ) for char in \"123\" : print ( char ) for line in open ( \"myfile.txt\" ): print ( line , end = '' ) for \u8bed\u53e5\u4f1a\u5728\u5bb9\u5668\u5bf9\u8c61\u4e0a\u8c03\u7528 iter()\u3002 \u8be5\u51fd\u6570\u8fd4\u56de\u4e00\u4e2a\u5b9a\u4e49\u4e86 __next__() \u65b9\u6cd5\u7684\u8fed\u4ee3\u5668\u5bf9\u8c61\uff0c\u6b64\u65b9\u6cd5\u5c06\u9010\u4e00\u8bbf\u95ee\u5bb9\u5668\u4e2d\u7684\u5143\u7d20\u3002 \u5f53\u5143\u7d20\u7528\u5c3d\u65f6\uff0c __next__() \u5c06\u5f15\u53d1 StopIteration \u5f02\u5e38\u6765\u901a\u77e5\u7ec8\u6b62 for \u5faa\u73af\u3002 \u53ef\u4ee5\u4f7f\u7528 next() \u5185\u7f6e\u51fd\u6570\u6765\u8c03\u7528 __next__() \u65b9\u6cd5\uff1b\u4e0b\u9762\u8fd9\u4e2a\u4f8b\u5b50\u5c55\u793a\u4e86\u521a\u521a\u63cf\u8ff0\u7684\u5177\u4f53\u8fd0\u884c\u65b9\u5f0f: >>> s = 'abc' >>> it = iter ( s ) >>> it < str_iterator object at 0x10c90e650 > >>> next ( it ) 'a' >>> next ( it ) 'b' >>> next ( it ) 'c' >>> next ( it ) Traceback ( most recent call last ): File \"\" , line 1 , in < module > next ( it ) StopIteration \u5728\u4e86\u89e3\u4e86\u8fed\u4ee3\u5668\u534f\u8bae\uff08iterator protocol\uff09\u7684\u673a\u5236\u540e\uff0c\u7ed9\u7c7b\u6dfb\u52a0\u8fed\u4ee3\u5668\u5c31\u5f88\u5bb9\u6613\u4e86\u3002 \u5b9a\u4e49\u4e00\u4e2a __iter__() \u65b9\u6cd5\u6765\u8fd4\u56de\u4e00\u4e2a\u5e26\u6709 __next__() \u65b9\u6cd5\u7684\u5bf9\u8c61\u3002 \u5982\u679c\u7c7b\u5df2\u5b9a\u4e49\u4e86 __next__() \uff0c\u5219 __iter__() \u53ef\u4ee5\u7b80\u5355\u5730\u8fd4\u56de self : class Reverse : \"\"\"Iterator for looping over a sequence backwards.\"\"\" def __init__ ( self , data ): self . data = data self . index = len ( data ) def __iter__ ( self ): return self def __next__ ( self ): if self . index == 0 : raise StopIteration self . index = self . index - 1 return self . data [ self . index ] rev = Reverse ( 'spam' ) print ( iter ( rev )) for char in rev : print ( char ) # m # a # p # s","title":"\u8fed\u4ee3\u5668 Iterators"},{"location":"python/Foundation/ch05/#generators","text":"**\u751f\u6210\u5668\uff08Generators\uff09**\u662f\u4e00\u4e2a\u7528\u4e8e\u521b\u5efa\u8fed\u4ee3\u5668\u7684\u7b80\u5355\u800c\u5f3a\u5927\u7684\u5de5\u5177\u3002 \u5b83\u4eec\u7684\u5199\u6cd5\u7c7b\u4f3c\u4e8e\u6807\u51c6\u7684\u51fd\u6570\uff0c\u4f46\u5f53\u5b83\u4eec\u8981\u8fd4\u56de\u6570\u636e\u65f6\u4f1a\u4f7f\u7528 yield \u8bed\u53e5\u3002 \u6bcf\u6b21\u5728\u751f\u6210\u5668\u4e0a\u8c03\u7528 next() \u65f6\uff0c\u5b83\u4f1a\u4ece\u4e0a\u6b21\u79bb\u5f00\u7684\u4f4d\u7f6e\u6062\u590d\u6267\u884c\uff08\u5b83\u4f1a\u8bb0\u4f4f\u4e0a\u6b21\u6267\u884c\u8bed\u53e5\u65f6\u7684\u6240\u6709\u6570\u636e\u503c\uff09\u3002 \u4e00\u4e2a\u521b\u5efa\u751f\u6210\u5668\u7684\u793a\u4f8b\u5982\u4e0b\uff08\u6539\u5199\u4e0a\u9762\u8fed\u4ee3\u5668\u4e2d\u6240\u4e3e\u7684\u4f8b\u5b50\uff09: def reverse ( data ): for index in range ( len ( data ) - 1 , - 1 , - 1 ): yield data [ index ] for char in reverse ( 'golf' ): print ( char ) # f # l # o # g \u53ef\u4ee5\u7528\u751f\u6210\u5668\u6765\u5b8c\u6210\u7684\u64cd\u4f5c\u540c\u6837\u53ef\u4ee5\u7528\u524d\u9762\u6240\u63cf\u8ff0\u7684\u57fa\u4e8e\u7c7b\u7684\u8fed\u4ee3\u5668\u6765\u5b8c\u6210\u3002\u4f46\u751f\u6210\u5668\u7684\u5199\u6cd5\u66f4\u4e3a\u7d27\u51d1\uff0c\u56e0\u4e3a\u5b83\u4f1a\u81ea\u52a8\u521b\u5efa __iter__() \u548c __next__() \u65b9\u6cd5\u3002 \u53e6\u4e00\u4e2a\u5173\u952e\u7279\u6027\u5728\u4e8e\u5c40\u90e8\u53d8\u91cf\u548c\u6267\u884c\u72b6\u6001\u4f1a\u5728\u6bcf\u6b21\u8c03\u7528\u4e4b\u95f4\u81ea\u52a8\u4fdd\u5b58\u3002 \u8fd9\u4f7f\u5f97\u8be5\u51fd\u6570\u76f8\u6bd4\u4f7f\u7528 self.index \u548c self.data \u8fd9\u79cd\u5b9e\u4f8b\u53d8\u91cf\u7684\u65b9\u5f0f\u66f4\u6613\u7f16\u5199\u4e14\u66f4\u4e3a\u6e05\u6670\u3002 \u9664\u4e86\u4f1a\u81ea\u52a8\u521b\u5efa\u65b9\u6cd5\u548c\u4fdd\u5b58\u7a0b\u5e8f\u72b6\u6001\uff0c\u5f53\u751f\u6210\u5668\u7ec8\u7ed3\u65f6\uff0c\u5b83\u4eec\u8fd8\u4f1a\u81ea\u52a8\u5f15\u53d1 StopIteration \u3002","title":"\u751f\u6210\u5668 Generators"},{"location":"python/Foundation/ch05/#generator-expressions","text":"\u67d0\u4e9b\u7b80\u5355\u7684\u751f\u6210\u5668\u53ef\u4ee5\u5199\u6210\u7b80\u6d01\u7684\u8868\u8fbe\u5f0f\u4ee3\u7801\uff0c\u6240\u7528\u8bed\u6cd5\u7c7b\u4f3c\u5217\u8868\u63a8\u5bfc\u5f0f\uff0c\u4f46\u5916\u5c42\u4e3a\u5706\u62ec\u53f7\u800c\u975e\u65b9\u62ec\u53f7\u3002 \u8fd9\u79cd\u8868\u8fbe\u5f0f\u88ab\u8bbe\u8ba1\u7528\u4e8e\u751f\u6210\u5668\u5c06\u7acb\u5373\u88ab\u5916\u5c42\u51fd\u6570\u6240\u4f7f\u7528\u7684\u60c5\u51b5\u3002 \u751f\u6210\u5668\u8868\u8fbe\u5f0f\u76f8\u6bd4\u5b8c\u6574\u7684\u751f\u6210\u5668\u66f4\u7d27\u51d1\u4f46\u8f83\u4e0d\u7075\u6d3b\uff0c\u76f8\u6bd4\u7b49\u6548\u7684\u5217\u8868\u63a8\u5bfc\u5f0f\u5219\u66f4\u4e3a\u8282\u7701\u5185\u5b58\u3002 \u793a\u4f8b: >>> sum ( i * i for i in range ( 10 )) # sum of squares 285 >>> xvec = [ 10 , 20 , 30 ] >>> yvec = [ 7 , 5 , 3 ] >>> sum ( x * y for x , y in zip ( xvec , yvec )) # dot product 260 >>> unique_words = set ( word for line in page for word in line . split ()) >>> valedictorian = max (( student . gpa , student . name ) for student in graduates ) >>> data = 'golf' >>> list ( data [ i ] for i in range ( len ( data ) - 1 , - 1 , - 1 )) [ 'f' , 'l' , 'o' , 'g' ]","title":"\u751f\u6210\u5668\u8868\u8fbe\u5f0f Generator Expressions"},{"location":"python/Foundation/ch05/#metaclass","text":"\u6240\u6709\u7684\u5bf9\u8c61\u90fd\u662f\u5b9e\u4f8b\u5316\u6216\u8005\u8bf4\u8c03\u7528\u7c7b\u800c\u5f97\u5230\u7684\uff08\u8c03\u7528\u7c7b\u7684\u8fc7\u7a0b\u79f0\u4e3a\u7c7b\u7684\u5b9e\u4f8b\u5316\u3002 class StandfordProfessor ( object ): university = 'Standford' def __init__ ( self , name , gender ): self . name = name self . gender = gender def display ( self ): print ( f 'Professor { self . name } says welcome to { self . university } !' ) professor = StandfordProfessor ( 'Tom' , 'Male' ) \u4e0a\u4f8b\u4e2d\uff0c\u5bf9\u8c61 professor \u662f\u8c03\u7528\u7c7b StandfordProfessor \u5f97\u5230\u7684\u3002\u7c7b StandfordProfessor \u672c\u8d28\u4e5f\u662f\u4e00\u4e2a\u5bf9\u8c61\uff0c \u4e0b\u9762\u53ef\u4ee5\u9a8c\u8bc1\uff0c StandfordProfessor \u662f\u8c03\u7528\u4e86\u5185\u7f6e\u7684\u7c7b type \u5f97\u5230\u7684\u3002\u8fd9\u4e2a type \u79f0\u4e3a\u5143\u7c7b\u3002 print ( type ( StandfordProfessor )) # \u5982\u679c\u4e00\u4e2a\u7c7b\u6ca1\u6709\u58f0\u660e\u81ea\u5df1\u7684\u5143\u7c7b\uff0c\u9ed8\u8ba4\u5b83\u7684\u5143\u7c7b\u5c31\u662f type \uff0c\u9664\u4e86\u4f7f\u7528\u5185\u7f6e\u5143\u7c7b type \uff0c\u6211\u4eec\u4e5f\u53ef\u4ee5\u901a\u8fc7\u7ee7\u627f type \u6765\u81ea\u5b9a\u4e49\u5143\u7c7b\uff0c\u7136\u540e\u4f7f\u7528 metaclass \u5173\u952e\u5b57\u53c2\u6570\u4e3a\u4e00\u4e2a\u7c7b\u7684\u6307\u5b9a\u5143\u7c7b\u3002 \u53ea\u6709\u7ee7\u627f\u4e86type\u7c7b\u624d\u80fd\u79f0\u4e4b\u4e3a\u4e00\u4e2a\u5143\u7c7b\uff0c\u5426\u5219\u5c31\u662f\u4e00\u4e2a\u666e\u901a\u7684\u81ea\u5b9a\u4e49\u7c7b\u3002 class Mymeta ( type ): pass class StandfordProfessor ( object , metaclass = Mymeta ): university = 'Standford' def __init__ ( self , name , gender ): self . name = name self . gender = gender def display ( self ): print ( f 'Professor { self . name } says welcome to { self . university } !' ) professor = StandfordProfessor ( 'Tom' , 'Male' ) \u4e0b\u9762\u8fdb\u884c\u81ea\u5b9a\u4e49\u5143\u7c7b\uff0c\u63a7\u5236\u7c7b StandfordProfessor \u7684\u8c03\u7528\u3002 \u8981\u60f3\u8ba9 professor \u8fd9\u4e2a\u5bf9\u8c61\u53d8\u6210\u4e00\u4e2a\u53ef\u8c03\u7528\u7684\u5bf9\u8c61\uff0c\u9700\u8981\u5728\u8be5\u5bf9\u8c61\u7684\u7c7b\u4e2d\u5b9a\u4e49\u4e00\u4e2a\u65b9\u6cd5 __call__ \uff0c\u8be5\u65b9\u6cd5\u4f1a\u5728\u8c03\u7528\u5bf9\u8c61\u65f6\u81ea\u52a8\u89e6\u53d1\u3002\u8c03\u7528 professor \u7684\u8fd4\u56de\u503c\u5c31\u662f __call__ \u65b9\u6cd5\u7684\u8fd4\u56de\u503c\u3002 class Mymeta ( type ): def __call__ ( self , * args , ** kwargs ): print ( self ) # \u7c7b\u540d print ( args ) # \u8f93\u5165\u53c2\u6570 print ( kwargs ) # \u8f93\u5165\u53c2\u6570 return 10086 class StandfordProfessor ( object , metaclass = Mymeta ): university = 'Standford' def __init__ ( self , name , gender ): self . name = name self . gender = gender def display ( self ): print ( f 'Professor { self . name } says welcome to { self . university } !' ) professor = StandfordProfessor ( 'Tom' , 'Male' ) # # ('Tom', 'Male') # {} \u7c7b\u7684\u4ea7\u751f\u8fc7\u7a0b\u5176\u5b9e\u5c31\u662f\u5143\u7c7b\u7684\u8c03\u7528\u8fc7\u7a0b,\u5373 StandfordProfessor = Mymeta('StandfordProfessor', (object), {...}) \uff0c\u8c03\u7528 Mymeta \u4f1a\u5148\u4ea7\u751f\u4e00\u4e2a\u7a7a\u5bf9\u8c61 StandfordProfessor \uff0c\u7136\u540e\u8fde\u540c\u8c03\u7528 Mymeta \u62ec\u53f7\u5185\u7684\u53c2\u6570\u4e00\u540c\u4f20\u7ed9 Mymeta \u4e0b\u7684 __init__ \u65b9\u6cd5\uff0c\u5b8c\u6210\u521d\u59cb\u5316\u3002\u6211\u4eec\u53ef\u4ee5\u57fa\u4e8e\u4e0a\u4f8b\u505a\u5982\u4e0b\u6539\u5199\u3002 class Mymeta ( type ): def __init__ ( self , class_name , class_bases , class_dic ): super ( Mymeta , self ) . __init__ ( class_name , class_bases , class_dic ) if class_name . islower (): raise TypeError ( f 'Please follow Camel-Case to change class name { class_name } ' ) if '__doc__' not in class_dic or len ( class_dic [ '__doc__' ] . strip ( ' \\n ' )) == 0 : raise TypeError ( 'Please add documentation in class {class_name} , which is mandatory.' ) class StandfordProfessor ( object , metaclass = Mymeta ): \"\"\" Documentation of class StanfordTeacher \"\"\" university = 'Standford' def __init__ ( self , name , gender ): self . name = name self . gender = gender def display ( self ): print ( f 'Professor { self . name } says welcome to { self . university } !' ) professor = StandfordProfessor ( 'Tom' , 'Male' ) professor . display () # Professor Tom says welcome to Standford! print ( professor . __dict__ ) # {'name': 'Tom', 'gender': 'Male'} StandfordProfessor . mro () # [, ]","title":"\u5143\u7c7b\uff08metaclass\uff09"},{"location":"python/Pythonic90Rules/Rule01/","text":"\u7b2c1\u6761\u3000\u67e5\u8be2\u81ea\u5df1\u4f7f\u7528\u7684Python\u7248\u672c \u00b6 >>> import sys >>> print(sys.version) 3.9.6 (default, Aug 5 2021, 17:13:26) [GCC 7.5.0] >>> print(sys.path) ['', '/usr/local/lib/python39.zip', '/usr/local/lib/python3.9', '/usr/local/lib/python3.9/lib-dynload', '/home/james/.local/lib/python3.9/site-packages', '/usr/local/lib/python3.9/site-packages'] >>> print(sys.version_info) sys.version_info(major=3, minor=9, micro=6, releaselevel='final', serial=0)","title":"\u7b2c01\u6761 \u67e5\u8be2\u81ea\u5df1\u4f7f\u7528\u7684Python\u7248\u672c"},{"location":"python/Pythonic90Rules/Rule01/#1-python","text":">>> import sys >>> print(sys.version) 3.9.6 (default, Aug 5 2021, 17:13:26) [GCC 7.5.0] >>> print(sys.path) ['', '/usr/local/lib/python39.zip', '/usr/local/lib/python3.9', '/usr/local/lib/python3.9/lib-dynload', '/home/james/.local/lib/python3.9/site-packages', '/usr/local/lib/python3.9/site-packages'] >>> print(sys.version_info) sys.version_info(major=3, minor=9, micro=6, releaselevel='final', serial=0)","title":"\u7b2c1\u6761\u3000\u67e5\u8be2\u81ea\u5df1\u4f7f\u7528\u7684Python\u7248\u672c"},{"location":"python/Pythonic90Rules/Rule02/","text":"\u7b2c2\u6761\u3000\u9075\u5faaPEP 8\u98ce\u683c\u6307\u5357 \u00b6 Python Enhancement Proposal #8\u53eb\u4f5cPEP 8\uff0c\u5b83\u662f\u4e00\u4efd\u9488\u5bf9Python\u4ee3\u7801\u683c\u5f0f\u800c\u7f16\u8ba2\u7684\u98ce\u683c\u6307\u5357\u3002 \u5b8c\u6574\u6307\u5357\uff1ahttps://www.python.org/dev/peps/pep-0008 \u4e0e\u7a7a\u767d\u6709\u5173\u7684\u5efa\u8bae \u00b6 \u5728Python\u4e2d\uff0c\u7a7a\u767d\uff08whitespace\uff09\u7684\u4f7f\u7528\u9075\u5faa\u4ee5\u4e0b\u51e0\u6761\u5efa\u8bae\u3002 \u7528\u7a7a\u683c\uff08space\uff09\u8868\u793a\u7f29\u8fdb\uff0c\u800c\u4e0d\u8981\u7528\u5236\u8868\u7b26\uff08tab\uff09\u3002 \u548c\u8bed\u6cd5\u76f8\u5173\u7684\u6bcf\u4e00\u5c42\u7f29\u8fdb\u90fd\u75284\u4e2a\u7a7a\u683c\u8868\u793a\u3002 \u6bcf\u884c\u4e0d\u8d85\u8fc779\u4e2a\u5b57\u7b26\u3002 \u5bf9\u4e8e\u5360\u636e\u591a\u884c\u7684\u957f\u8868\u8fbe\u5f0f\u6765\u8bf4\uff0c\u9664\u4e86\u9996\u884c\u4e4b\u5916\u7684\u5176\u4f59\u5404\u884c\u90fd\u5e94\u8be5\u5728\u901a\u5e38\u7684\u7f29\u8fdb\u7ea7\u522b\u4e4b\u4e0a\u518d\u52a04\u4e2a\u7a7a\u683c\u3002 \u5728\u540c\u4e00\u4efd\u6587\u4ef6\u4e2d\uff0c\u51fd\u6570\u4e0e\u7c7b\u4e4b\u95f4\u7528\u4e24\u4e2a\u7a7a\u884c\u9694\u5f00\u3002 \u5728\u540c\u4e00\u4e2a\u7c7b\u4e2d\uff0c\u65b9\u6cd5\u4e0e\u65b9\u6cd5\u4e4b\u95f4\u7528\u4e00\u4e2a\u7a7a\u884c\u9694\u5f00\u3002 \u4f7f\u7528\u5b57\u5178\u65f6\uff0c\u952e\u4e0e\u5192\u53f7\u4e4b\u95f4\u4e0d\u52a0\u7a7a\u683c\uff0c\u5199\u5728\u540c\u4e00\u884c\u7684\u5192\u53f7\u548c\u503c\u4e4b\u95f4\u5e94\u8be5\u52a0\u4e00\u4e2a\u7a7a\u683c\u3002 \u7ed9\u53d8\u91cf\u8d4b\u503c\u65f6\uff0c\u8d4b\u503c\u7b26\u53f7\u7684\u5de6\u8fb9\u548c\u53f3\u8fb9\u5404\u52a0\u4e00\u4e2a\u7a7a\u683c\uff0c\u5e76\u4e14\u53ea\u52a0\u4e00\u4e2a\u7a7a\u683c\u5c31\u597d\u3002 \u7ed9\u53d8\u91cf\u7684\u7c7b\u578b\u505a\u6ce8\u89e3\uff08annotation\uff09\u65f6\uff0c\u4e0d\u8981\u628a\u53d8\u91cf\u540d\u548c\u5192\u53f7\u9694\u5f00\uff0c\u4f46\u5728\u7c7b\u578b\u4fe1\u606f\u524d\u5e94\u8be5\u6709\u4e00\u4e2a\u7a7a\u683c\u3002 \u4e0e\u547d\u540d\u6709\u5173\u7684\u5efa\u8bae \u00b6 PEP 8\u5efa\u8bae\u91c7\u7528\u4e0d\u540c\u7684\u65b9\u5f0f\u6765\u7ed9Python\u4ee3\u7801\u4e2d\u7684\u5404\u4e2a\u90e8\u5206\u547d\u540d\uff0c\u9075\u5faa\u4ee5\u4e0b\u4e0e\u547d\u540d\u76f8\u5173\u7684\u5efa\u8bae\u3002 \u51fd\u6570\u3001\u53d8\u91cf\u53ca\u5c5e\u6027\u7528\u5c0f\u5199\u5b57\u6bcd\u6765\u62fc\u5199\uff0c\u5404\u5355\u8bcd\u4e4b\u95f4\u7528\u4e0b\u5212\u7ebf\u76f8\u8fde\uff0c\u4f8b\u5982\uff1alowercase_underscore\u3002 \u53d7\u4fdd\u62a4\u7684\u5b9e\u4f8b\u5c5e\u6027\uff0c\u7528\u4e00\u4e2a\u4e0b\u5212\u7ebf\u5f00\u5934\uff0c\u4f8b\u5982\uff1a_leading_underscore\u3002 \u79c1\u6709\u7684\u5b9e\u4f8b\u5c5e\u6027\uff0c\u7528\u4e24\u4e2a\u4e0b\u5212\u7ebf\u5f00\u5934\uff0c\u4f8b\u5982\uff1a__double_leading_underscore\u3002 \u7c7b\uff08\u5305\u62ec\u5f02\u5e38\uff09\u547d\u540d\u65f6\uff0c\u6bcf\u4e2a\u5355\u8bcd\u7684\u9996\u5b57\u6bcd\u5747\u5927\u5199\uff0c\u4f8b\u5982\uff1aCapitalizedWord\u3002 \u6a21\u5757\u7ea7\u522b\u7684\u5e38\u91cf\uff0c\u6240\u6709\u5b57\u6bcd\u90fd\u5927\u5199\uff0c\u5404\u5355\u8bcd\u4e4b\u95f4\u7528\u4e0b\u5212\u7ebf\u76f8\u8fde\uff0c\u4f8b\u5982\uff1aALL_CAPS\u3002 \u7c7b\u4e2d\u7684\u5b9e\u4f8b\u65b9\u6cd5\uff0c\u5e94\u8be5\u628a\u7b2c\u4e00\u4e2a\u53c2\u6570\u547d\u540d\u4e3aself\uff0c\u7528\u6765\u8868\u793a\u8be5\u5bf9\u8c61\u672c\u8eab\u3002 \u7c7b\u65b9\u6cd5\u7684\u7b2c\u4e00\u4e2a\u53c2\u6570\uff0c\u5e94\u8be5\u547d\u540d\u4e3acls\uff0c\u7528\u6765\u8868\u793a\u8fd9\u4e2a\u7c7b\u672c\u8eab\u3002 \u4e0e\u8868\u8fbe\u5f0f\u548c\u8bed\u53e5\u6709\u5173\u7684\u5efa\u8bae \u00b6 The Zen of Python\u4e2d\u63d0\u5230\uff1a\u201c\u6bcf\u4ef6\u4e8b\u90fd\u5e94\u8be5\u6709\u7b80\u5355\u7684\u505a\u6cd5\uff0c\u800c\u4e14\u6700\u597d\u53ea\u6709\u4e00\u79cd\u3002\u201dPEP 8\u5c31\u8bd5\u7740\u8fd0\u7528\u8fd9\u4e2a\u7406\u5ff5\uff0c\u6765\u89c4\u8303\u8868\u8fbe\u5f0f\u548c\u8bed\u53e5\u7684\u5199\u6cd5\u3002 \u91c7\u7528\u884c\u5185\u5426\u5b9a\uff0c\u5373\u628a\u5426\u5b9a\u8bcd\u76f4\u63a5\u5199\u5728\u8981\u5426\u5b9a\u7684\u5185\u5bb9\u524d\u9762\uff0c\u800c\u4e0d\u8981\u653e\u5728\u6574\u4e2a\u8868\u8fbe\u5f0f\u7684\u524d\u9762\uff0c\u4f8b\u5982\u5e94\u8be5\u5199if a is not b\uff0c\u800c\u4e0d\u662fif not a is b\u3002 \u4e0d\u8981\u901a\u8fc7\u957f\u5ea6\u5224\u65ad\u5bb9\u5668\u6216\u5e8f\u5217\u662f\u4e0d\u662f\u7a7a\u7684\uff0c\u4f8b\u5982\u4e0d\u8981\u901a\u8fc7if len(somelist) == 0\u5224\u65adsomelist\u662f\u5426\u4e3a[]\u6216''\u7b49\u7a7a\u503c\uff0c\u800c\u662f\u5e94\u8be5\u91c7\u7528if not somelist\u8fd9\u6837\u7684\u5199\u6cd5\u6765\u5224\u65ad\uff0c\u56e0\u4e3aPython\u4f1a\u628a\u7a7a\u503c\u81ea\u52a8\u8bc4\u4f30\u4e3aFalse\u3002 \u5982\u679c\u8981\u5224\u65ad\u5bb9\u5668\u6216\u5e8f\u5217\u91cc\u9762\u6709\u6ca1\u6709\u5185\u5bb9\uff08\u6bd4\u5982\u8981\u5224\u65ad somelist \u662f\u5426\u4e3a[1]\u6216'hi'\u8fd9\u6837\u975e\u7a7a\u7684\u503c\uff09\uff0c\u4e5f\u4e0d\u5e94\u8be5\u901a\u8fc7\u957f\u5ea6\u6765\u5224\u65ad\uff0c\u800c\u662f\u5e94\u8be5\u91c7\u7528if somelist \u8bed\u53e5\uff0c\u56e0\u4e3aPython\u4f1a\u628a\u975e\u7a7a\u7684\u503c\u81ea\u52a8\u5224\u5b9a\u4e3aTrue\u3002 \u4e0d\u8981\u628aif\u8bed\u53e5\u3001for\u5faa\u73af\u3001while\u5faa\u73af\u53caexcept\u590d\u5408\u8bed\u53e5\u6324\u5728\u4e00\u884c\u3002\u5e94\u8be5\u628a\u8fd9\u4e9b\u8bed\u53e5\u5206\u6210\u591a\u884c\u6765\u5199\uff0c\u8fd9\u6837\u66f4\u52a0\u6e05\u6670\u3002 \u5982\u679c\u8868\u8fbe\u5f0f\u4e00\u884c\u5199\u4e0d\u4e0b\uff0c\u53ef\u4ee5\u7528\u62ec\u53f7\u5c06\u5176\u62ec\u8d77\u6765\uff0c\u800c\u4e14\u8981\u9002\u5f53\u5730\u6dfb\u52a0\u6362\u884c\u4e0e\u7f29\u8fdb\u4ee5\u4fbf\u4e8e\u9605\u8bfb\u3002\u591a\u884c\u7684\u8868\u8fbe\u5f0f\uff0c\u5e94\u8be5\u7528\u62ec\u53f7\u62ec\u8d77\u6765\uff0c\u800c\u4e0d\u8981\u7528 \u4e0e\u5f15\u5165\u6709\u5173\u7684\u5efa\u8bae \u00b6 PEP 8\u5bf9\u4e8e\u600e\u6837\u5728\u4ee3\u7801\u4e2d\u5f15\u5165\u5e76\u4f7f\u7528\u6a21\u5757\uff0c\u7ed9\u51fa\u4e86\u4e0b\u9762\u51e0\u6761\u5efa\u8bae\u3002 import\u8bed\u53e5\uff08\u542bfrom x import y\uff09\u603b\u662f\u5e94\u8be5\u653e\u5728\u6587\u4ef6\u5f00\u5934\u3002 \u5f15\u5165\u6a21\u5757\u65f6\uff0c\u603b\u662f\u5e94\u8be5\u4f7f\u7528\u7edd\u5bf9\u540d\u79f0\uff0c\u800c\u4e0d\u5e94\u8be5\u6839\u636e\u5f53\u524d\u6a21\u5757\u8def\u5f84\u6765\u4f7f\u7528\u76f8\u5bf9\u540d\u79f0\u3002\u4f8b\u5982\uff0c\u8981\u5f15\u5165bar\u5305\u4e2d\u7684foo\u6a21\u5757\uff0c\u5e94\u8be5\u5b8c\u6574\u5730\u5199\u51fafrom bar import foo\uff0c\u5373\u4fbf\u5f53\u524d\u8def\u5f84\u4e3abar\u5305\u91cc\uff0c\u4e5f\u4e0d\u5e94\u8be5\u7b80\u5199\u4e3aimport foo\u3002 \u5982\u679c\u4e00\u5b9a\u8981\u7528\u76f8\u5bf9\u540d\u79f0\u6765\u7f16\u5199import\u8bed\u53e5\uff0c\u90a3\u5c31\u5e94\u8be5\u660e\u786e\u5730\u5199\u6210\uff1afrom . import foo\u3002 \u6587\u4ef6\u4e2d\u7684import\u8bed\u53e5\u5e94\u8be5\u6309\u987a\u5e8f\u5212\u5206\u6210\u4e09\u4e2a\u90e8\u5206\uff1a\u9996\u5148\u5f15\u5165\u6807\u51c6\u5e93\u91cc\u7684\u6a21\u5757\uff0c\u7136\u540e\u5f15\u5165\u7b2c\u4e09\u65b9\u6a21\u5757\uff0c\u6700\u540e\u5f15\u5165\u81ea\u5df1\u7684\u6a21\u5757\u3002\u5c5e\u4e8e\u540c\u4e00\u4e2a\u90e8\u5206\u7684import\u8bed\u53e5\u6309\u5b57\u6bcd\u987a\u5e8f\u6392\u5217\u3002 \u63d0\u793a \u00b6 Pylint\uff08https://www.pylint.org/\uff09\u662f\u4e00\u6b3e\u6d41\u884c\u7684Python\u6e90\u7801\u9759\u6001\u5206\u6790\u5de5\u5177\u3002","title":"\u7b2c02\u6761 \u9075\u5faaPEP 8\u98ce\u683c\u6307\u5357"},{"location":"python/Pythonic90Rules/Rule02/#2-pep-8","text":"Python Enhancement Proposal #8\u53eb\u4f5cPEP 8\uff0c\u5b83\u662f\u4e00\u4efd\u9488\u5bf9Python\u4ee3\u7801\u683c\u5f0f\u800c\u7f16\u8ba2\u7684\u98ce\u683c\u6307\u5357\u3002 \u5b8c\u6574\u6307\u5357\uff1ahttps://www.python.org/dev/peps/pep-0008","title":"\u7b2c2\u6761\u3000\u9075\u5faaPEP 8\u98ce\u683c\u6307\u5357"},{"location":"python/Pythonic90Rules/Rule02/#_1","text":"\u5728Python\u4e2d\uff0c\u7a7a\u767d\uff08whitespace\uff09\u7684\u4f7f\u7528\u9075\u5faa\u4ee5\u4e0b\u51e0\u6761\u5efa\u8bae\u3002 \u7528\u7a7a\u683c\uff08space\uff09\u8868\u793a\u7f29\u8fdb\uff0c\u800c\u4e0d\u8981\u7528\u5236\u8868\u7b26\uff08tab\uff09\u3002 \u548c\u8bed\u6cd5\u76f8\u5173\u7684\u6bcf\u4e00\u5c42\u7f29\u8fdb\u90fd\u75284\u4e2a\u7a7a\u683c\u8868\u793a\u3002 \u6bcf\u884c\u4e0d\u8d85\u8fc779\u4e2a\u5b57\u7b26\u3002 \u5bf9\u4e8e\u5360\u636e\u591a\u884c\u7684\u957f\u8868\u8fbe\u5f0f\u6765\u8bf4\uff0c\u9664\u4e86\u9996\u884c\u4e4b\u5916\u7684\u5176\u4f59\u5404\u884c\u90fd\u5e94\u8be5\u5728\u901a\u5e38\u7684\u7f29\u8fdb\u7ea7\u522b\u4e4b\u4e0a\u518d\u52a04\u4e2a\u7a7a\u683c\u3002 \u5728\u540c\u4e00\u4efd\u6587\u4ef6\u4e2d\uff0c\u51fd\u6570\u4e0e\u7c7b\u4e4b\u95f4\u7528\u4e24\u4e2a\u7a7a\u884c\u9694\u5f00\u3002 \u5728\u540c\u4e00\u4e2a\u7c7b\u4e2d\uff0c\u65b9\u6cd5\u4e0e\u65b9\u6cd5\u4e4b\u95f4\u7528\u4e00\u4e2a\u7a7a\u884c\u9694\u5f00\u3002 \u4f7f\u7528\u5b57\u5178\u65f6\uff0c\u952e\u4e0e\u5192\u53f7\u4e4b\u95f4\u4e0d\u52a0\u7a7a\u683c\uff0c\u5199\u5728\u540c\u4e00\u884c\u7684\u5192\u53f7\u548c\u503c\u4e4b\u95f4\u5e94\u8be5\u52a0\u4e00\u4e2a\u7a7a\u683c\u3002 \u7ed9\u53d8\u91cf\u8d4b\u503c\u65f6\uff0c\u8d4b\u503c\u7b26\u53f7\u7684\u5de6\u8fb9\u548c\u53f3\u8fb9\u5404\u52a0\u4e00\u4e2a\u7a7a\u683c\uff0c\u5e76\u4e14\u53ea\u52a0\u4e00\u4e2a\u7a7a\u683c\u5c31\u597d\u3002 \u7ed9\u53d8\u91cf\u7684\u7c7b\u578b\u505a\u6ce8\u89e3\uff08annotation\uff09\u65f6\uff0c\u4e0d\u8981\u628a\u53d8\u91cf\u540d\u548c\u5192\u53f7\u9694\u5f00\uff0c\u4f46\u5728\u7c7b\u578b\u4fe1\u606f\u524d\u5e94\u8be5\u6709\u4e00\u4e2a\u7a7a\u683c\u3002","title":"\u4e0e\u7a7a\u767d\u6709\u5173\u7684\u5efa\u8bae"},{"location":"python/Pythonic90Rules/Rule02/#_2","text":"PEP 8\u5efa\u8bae\u91c7\u7528\u4e0d\u540c\u7684\u65b9\u5f0f\u6765\u7ed9Python\u4ee3\u7801\u4e2d\u7684\u5404\u4e2a\u90e8\u5206\u547d\u540d\uff0c\u9075\u5faa\u4ee5\u4e0b\u4e0e\u547d\u540d\u76f8\u5173\u7684\u5efa\u8bae\u3002 \u51fd\u6570\u3001\u53d8\u91cf\u53ca\u5c5e\u6027\u7528\u5c0f\u5199\u5b57\u6bcd\u6765\u62fc\u5199\uff0c\u5404\u5355\u8bcd\u4e4b\u95f4\u7528\u4e0b\u5212\u7ebf\u76f8\u8fde\uff0c\u4f8b\u5982\uff1alowercase_underscore\u3002 \u53d7\u4fdd\u62a4\u7684\u5b9e\u4f8b\u5c5e\u6027\uff0c\u7528\u4e00\u4e2a\u4e0b\u5212\u7ebf\u5f00\u5934\uff0c\u4f8b\u5982\uff1a_leading_underscore\u3002 \u79c1\u6709\u7684\u5b9e\u4f8b\u5c5e\u6027\uff0c\u7528\u4e24\u4e2a\u4e0b\u5212\u7ebf\u5f00\u5934\uff0c\u4f8b\u5982\uff1a__double_leading_underscore\u3002 \u7c7b\uff08\u5305\u62ec\u5f02\u5e38\uff09\u547d\u540d\u65f6\uff0c\u6bcf\u4e2a\u5355\u8bcd\u7684\u9996\u5b57\u6bcd\u5747\u5927\u5199\uff0c\u4f8b\u5982\uff1aCapitalizedWord\u3002 \u6a21\u5757\u7ea7\u522b\u7684\u5e38\u91cf\uff0c\u6240\u6709\u5b57\u6bcd\u90fd\u5927\u5199\uff0c\u5404\u5355\u8bcd\u4e4b\u95f4\u7528\u4e0b\u5212\u7ebf\u76f8\u8fde\uff0c\u4f8b\u5982\uff1aALL_CAPS\u3002 \u7c7b\u4e2d\u7684\u5b9e\u4f8b\u65b9\u6cd5\uff0c\u5e94\u8be5\u628a\u7b2c\u4e00\u4e2a\u53c2\u6570\u547d\u540d\u4e3aself\uff0c\u7528\u6765\u8868\u793a\u8be5\u5bf9\u8c61\u672c\u8eab\u3002 \u7c7b\u65b9\u6cd5\u7684\u7b2c\u4e00\u4e2a\u53c2\u6570\uff0c\u5e94\u8be5\u547d\u540d\u4e3acls\uff0c\u7528\u6765\u8868\u793a\u8fd9\u4e2a\u7c7b\u672c\u8eab\u3002","title":"\u4e0e\u547d\u540d\u6709\u5173\u7684\u5efa\u8bae"},{"location":"python/Pythonic90Rules/Rule02/#_3","text":"The Zen of Python\u4e2d\u63d0\u5230\uff1a\u201c\u6bcf\u4ef6\u4e8b\u90fd\u5e94\u8be5\u6709\u7b80\u5355\u7684\u505a\u6cd5\uff0c\u800c\u4e14\u6700\u597d\u53ea\u6709\u4e00\u79cd\u3002\u201dPEP 8\u5c31\u8bd5\u7740\u8fd0\u7528\u8fd9\u4e2a\u7406\u5ff5\uff0c\u6765\u89c4\u8303\u8868\u8fbe\u5f0f\u548c\u8bed\u53e5\u7684\u5199\u6cd5\u3002 \u91c7\u7528\u884c\u5185\u5426\u5b9a\uff0c\u5373\u628a\u5426\u5b9a\u8bcd\u76f4\u63a5\u5199\u5728\u8981\u5426\u5b9a\u7684\u5185\u5bb9\u524d\u9762\uff0c\u800c\u4e0d\u8981\u653e\u5728\u6574\u4e2a\u8868\u8fbe\u5f0f\u7684\u524d\u9762\uff0c\u4f8b\u5982\u5e94\u8be5\u5199if a is not b\uff0c\u800c\u4e0d\u662fif not a is b\u3002 \u4e0d\u8981\u901a\u8fc7\u957f\u5ea6\u5224\u65ad\u5bb9\u5668\u6216\u5e8f\u5217\u662f\u4e0d\u662f\u7a7a\u7684\uff0c\u4f8b\u5982\u4e0d\u8981\u901a\u8fc7if len(somelist) == 0\u5224\u65adsomelist\u662f\u5426\u4e3a[]\u6216''\u7b49\u7a7a\u503c\uff0c\u800c\u662f\u5e94\u8be5\u91c7\u7528if not somelist\u8fd9\u6837\u7684\u5199\u6cd5\u6765\u5224\u65ad\uff0c\u56e0\u4e3aPython\u4f1a\u628a\u7a7a\u503c\u81ea\u52a8\u8bc4\u4f30\u4e3aFalse\u3002 \u5982\u679c\u8981\u5224\u65ad\u5bb9\u5668\u6216\u5e8f\u5217\u91cc\u9762\u6709\u6ca1\u6709\u5185\u5bb9\uff08\u6bd4\u5982\u8981\u5224\u65ad somelist \u662f\u5426\u4e3a[1]\u6216'hi'\u8fd9\u6837\u975e\u7a7a\u7684\u503c\uff09\uff0c\u4e5f\u4e0d\u5e94\u8be5\u901a\u8fc7\u957f\u5ea6\u6765\u5224\u65ad\uff0c\u800c\u662f\u5e94\u8be5\u91c7\u7528if somelist \u8bed\u53e5\uff0c\u56e0\u4e3aPython\u4f1a\u628a\u975e\u7a7a\u7684\u503c\u81ea\u52a8\u5224\u5b9a\u4e3aTrue\u3002 \u4e0d\u8981\u628aif\u8bed\u53e5\u3001for\u5faa\u73af\u3001while\u5faa\u73af\u53caexcept\u590d\u5408\u8bed\u53e5\u6324\u5728\u4e00\u884c\u3002\u5e94\u8be5\u628a\u8fd9\u4e9b\u8bed\u53e5\u5206\u6210\u591a\u884c\u6765\u5199\uff0c\u8fd9\u6837\u66f4\u52a0\u6e05\u6670\u3002 \u5982\u679c\u8868\u8fbe\u5f0f\u4e00\u884c\u5199\u4e0d\u4e0b\uff0c\u53ef\u4ee5\u7528\u62ec\u53f7\u5c06\u5176\u62ec\u8d77\u6765\uff0c\u800c\u4e14\u8981\u9002\u5f53\u5730\u6dfb\u52a0\u6362\u884c\u4e0e\u7f29\u8fdb\u4ee5\u4fbf\u4e8e\u9605\u8bfb\u3002\u591a\u884c\u7684\u8868\u8fbe\u5f0f\uff0c\u5e94\u8be5\u7528\u62ec\u53f7\u62ec\u8d77\u6765\uff0c\u800c\u4e0d\u8981\u7528","title":"\u4e0e\u8868\u8fbe\u5f0f\u548c\u8bed\u53e5\u6709\u5173\u7684\u5efa\u8bae"},{"location":"python/Pythonic90Rules/Rule02/#_4","text":"PEP 8\u5bf9\u4e8e\u600e\u6837\u5728\u4ee3\u7801\u4e2d\u5f15\u5165\u5e76\u4f7f\u7528\u6a21\u5757\uff0c\u7ed9\u51fa\u4e86\u4e0b\u9762\u51e0\u6761\u5efa\u8bae\u3002 import\u8bed\u53e5\uff08\u542bfrom x import y\uff09\u603b\u662f\u5e94\u8be5\u653e\u5728\u6587\u4ef6\u5f00\u5934\u3002 \u5f15\u5165\u6a21\u5757\u65f6\uff0c\u603b\u662f\u5e94\u8be5\u4f7f\u7528\u7edd\u5bf9\u540d\u79f0\uff0c\u800c\u4e0d\u5e94\u8be5\u6839\u636e\u5f53\u524d\u6a21\u5757\u8def\u5f84\u6765\u4f7f\u7528\u76f8\u5bf9\u540d\u79f0\u3002\u4f8b\u5982\uff0c\u8981\u5f15\u5165bar\u5305\u4e2d\u7684foo\u6a21\u5757\uff0c\u5e94\u8be5\u5b8c\u6574\u5730\u5199\u51fafrom bar import foo\uff0c\u5373\u4fbf\u5f53\u524d\u8def\u5f84\u4e3abar\u5305\u91cc\uff0c\u4e5f\u4e0d\u5e94\u8be5\u7b80\u5199\u4e3aimport foo\u3002 \u5982\u679c\u4e00\u5b9a\u8981\u7528\u76f8\u5bf9\u540d\u79f0\u6765\u7f16\u5199import\u8bed\u53e5\uff0c\u90a3\u5c31\u5e94\u8be5\u660e\u786e\u5730\u5199\u6210\uff1afrom . import foo\u3002 \u6587\u4ef6\u4e2d\u7684import\u8bed\u53e5\u5e94\u8be5\u6309\u987a\u5e8f\u5212\u5206\u6210\u4e09\u4e2a\u90e8\u5206\uff1a\u9996\u5148\u5f15\u5165\u6807\u51c6\u5e93\u91cc\u7684\u6a21\u5757\uff0c\u7136\u540e\u5f15\u5165\u7b2c\u4e09\u65b9\u6a21\u5757\uff0c\u6700\u540e\u5f15\u5165\u81ea\u5df1\u7684\u6a21\u5757\u3002\u5c5e\u4e8e\u540c\u4e00\u4e2a\u90e8\u5206\u7684import\u8bed\u53e5\u6309\u5b57\u6bcd\u987a\u5e8f\u6392\u5217\u3002","title":"\u4e0e\u5f15\u5165\u6709\u5173\u7684\u5efa\u8bae"},{"location":"python/Pythonic90Rules/Rule02/#_5","text":"Pylint\uff08https://www.pylint.org/\uff09\u662f\u4e00\u6b3e\u6d41\u884c\u7684Python\u6e90\u7801\u9759\u6001\u5206\u6790\u5de5\u5177\u3002","title":"\u63d0\u793a"},{"location":"python/Pythonic90Rules/Rule03/","text":"\u7b2c3\u6761\u3000\u4e86\u89e3bytes\u4e0estr\u7684\u533a\u522b \u00b6 UNICODE\u7f16\u7801\u7b80\u4ecb \u00b6 ASCII\u7f16\u7801\u89c4\u5b9a1\u4e2a\u5b57\u8282\u7b49\u4e8e8\u4e2a\u6bd4\u7279\u4f4d\uff0c\u4ee3\u88681\u4e2a\u5b57\u7b26\u7684\u7f16\u7801\uff0c\u9664\u4e86\u7b2c\u4e00\u4f4d\u662f0\uff0c \u5176\u4ed67\u4f4d\u90fd\u53ef\u4ee5\u67090 \u6216\u8005 1 \u4e24\u4e2a\u9009\u62e9\uff0c\u6240\u4ee5ASCII \u4e00\u5171\u53ef\u4ee5\u8868\u793a 2^7 \uff0c\u4e5f\u5c31\u662f128\u4e2a\u5b57\u7b26\u3002\u5305\u62eca-z \u5927\u5c0f\u5199\uff0c0-9 \u6570\u5b57 \u548c\u4e00\u4e9b\u6807\u70b9\u7b26\u53f7\u7b49\u3002\u5176\u4e2d\u771f\u6b63\u53ef\u8bfb\u7684\u53ea\u670995 \u4e2a\u5b57\u7b26\uff0c\u5176\u4ed6\u7684\u90fd\u662f\u4e00\u4e9b\u63a7\u5236\u7b26\uff0c\u6bd4\u5982NUL\uff0c\u4ee3\u8868NULL\u3002 \u591a\u5b57\u8282\u7f16\u7801\uff0c\u6bd4\u5982\u53cc\u5b57\u8282\u7f16\u7801\u65b9\u5f0f\uff0cBIG-5\u548cGB18030\u5305\u542b\u4e86\u5927\u591a\u6570\u4e2d\u6587\u7b80\u4f53\u548c\u7e41\u4f53\u3002\u8fd9\u4e2a\u7f16\u7801\u4e0d\u517c\u5bb9ASCII\uff0c\u540c\u65f6\u8fd8\u5360\u7528\u8f83\u591a\u7684\u7a7a\u95f4\u548c\u5185\u5b58\u3002 UNICODE\u4e0d\u662f\u4e00\u79cd\u7f16\u7801\uff0c \u800c\u662f\u5b9a\u4e49\u4e86\u4e00\u4e2a\u8868\uff0c \u8868\u4e2d\u4e3a\u4e16\u754c\u4e0a\u6bcf\u79cd\u8bed\u8a00\u4e2d\u7684\u6bcf\u4e2a\u5b57\u7b26\u8bbe\u5b9a\u4e86\u7edf\u4e00\u5e76\u4e14\u552f\u4e00\u7684\u7801\u4f4d \uff08code point\uff09\uff0c\u4ee5\u6ee1\u8db3\u8de8\u8bed\u8a00\u3001\u8de8\u5e73\u53f0\u8fdb\u884c\u6587\u672c\u8f6c\u6362\u7684\u8981\u6c42\u3002 UTF-8\u7f16\u7801\u89c4\u5b9a\u82f1\u6587\u5b57\u6bcd\u7cfb\u5217\u75281\u4e2a\u5b57\u8282\u8868\u793a\uff0c\u6c49\u5b57\u75283\u4e2a\u5b57\u8282\u8868\u793a\u7b49\u7b49\u3002UTF-8\u7684\u7279\u70b9\u662f\u5bf9\u4e0d\u540c\u8303\u56f4\u7684\u5b57\u7b26\u4f7f\u7528\u4e0d\u540c\u957f\u5ea6\u7684\u7f16\u7801\u3002 \u4e0b\u8868\u8868\u793a\u5982\u4f55\u4ece\u4e00\u4e2a\u4eceUnicode \u8f6c\u5316\u5230UTF-8 , \u5bf9\u4e8e\u524d0x7F\u7684\u5b57\u7b26\uff0cUTF-8\u7f16\u7801\u548cASCII\u7801\u662f\u4e00\u4e00\u5bf9\u5e94\u7684\u3002 \u5982\u679c\u4e00\u4e2a\u5b57\u7b26\u5728000800-00FFFF \u4e4b\u95f4\uff0c\u90a3\u8f6c\u5316\u5230UTF-8 \u9700\u8981\u7528\u4e09\u5b57\u8282\u6a21\u677f\uff0c\u4f7f\u752816\u4e2a\u7801\u4f4d\uff0c\u6bcf\u4e2ax\u5c31\u662f\u4e00\u4e2a\u7801\u4f4d\u3002 Unicode\u7f16\u7801\uff08\u5341\u516d\u8fdb\u5236\uff09 UTF-8\u5b57\u8282\u6d41\uff08\u4e8c\u8fdb\u5236\uff09 000000 - 00007F 0xxxxxxx 000080 - 0007FF 110xxxx 10xxxxxx 000800 - 00FFFF 1110xxxx 10xxxxxx 10xxxxxx 010000 - 10FFFF 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx Python\u6709\u4e24\u79cd\u7c7b\u578b\u53ef\u4ee5\u8868\u793a\u5b57\u7b26\u5e8f\u5217(sequence)\uff1a\u4e00\u79cd\u662fbytes\uff0c\u53e6\u4e00\u79cd\u662fstr\u3002 bytes\u5b9e\u4f8b\u5305\u542b\u7684\u662f\u539f\u59cb\u6570\u636e\uff0c\u53738\u4f4d\u7684\u65e0\u7b26\u53f7\u503c\uff08\u901a\u5e38\u6309\u7167ASCII\u7f16\u7801\u6807\u51c6\u6765\u663e\u793a\uff09\u3002 str\u5b9e\u4f8b\u5305\u542b\u7684\u662fUnicode\u7801\u70b9\uff08code point\uff0c\u4e5f\u53eb\u4f5c\u4ee3\u7801\u70b9\uff09\uff0c\u8fd9\u4e9b\u7801\u70b9\u4e0e\u4eba\u7c7b\u8bed\u8a00\u4e4b\u4e2d\u7684\u6587\u672c\u5b57\u7b26\u76f8\u5bf9\u5e94\u3002 >>> a = b'h\\x65llo' >>> a b'hello' >>> list(a) [104, 101, 108, 108, 111] >>> b = 'a\\u0300 hello' >>> b 'a\u0300 hello' >>> list(b) ['a', '\u0300', ' ', 'h', 'e', 'l', 'l', 'o'] \u5185\u5b58\u662funicode\u7f16\u7801\u683c\u5f0f\uff0c\u786c\u76d8\u662futf-8\u3002 \u5728\u505a\u7f16\u7801\u8f6c\u6362\u65f6\u5019\uff0c\u901a\u5e38\u7528unicode\u4f5c\u4e3a\u4e2d\u95f4\u7f16\u7801\u3002 \u5148\u5c06\u5176\u4ed6\u7f16\u7801\u7684\u5b57\u7b26\u4e32\u89e3\u7801(decode)\u6210unicode,\u518d\u4eceunicode\u7f16\u7801(encode)\u6210\u53e6\u4e00\u79cd\u7f16\u7801\u683c\u5f0f\u3002 decode\u7684\u4f5c\u7528\u662f\u5c06\u4e8c\u8fdb\u5236\u6570\u636e\u89e3\u7801\u6210unicode\u7f16\u7801\u3002 encode\u7684\u4f5c\u7528\u662f\u5c06unicode\u7f16\u7801\u7684\u5b57\u7b26\u4e32\u7f16\u7801\u6210\u4e8c\u8fdb\u5236\u6570\u636e\u3002 \u8981\u628aUnicode\u6570\u636e\u8f6c\u6362\u6210\u4e8c\u8fdb\u5236\u6570\u636e\uff0c\u5fc5\u987b\u8c03\u7528str\u7684encode\u65b9\u6cd5\u3002 \u8981\u628a\u4e8c\u8fdb\u5236\u6570\u636e\u8f6c\u6362\u6210Unicode\u6570\u636e\uff0c\u5fc5\u987b\u8c03\u7528bytes\u7684decode\u65b9\u6cd5\u3002 \u8c03\u7528\u8fd9\u4e9b\u65b9\u6cd5\u7684\u65f6\u5019\uff0c\u53ef\u4ee5\u660e\u786e\u6307\u51fa\u81ea\u5df1\u8981\u4f7f\u7528\u7684\u7f16\u7801\u65b9\u6848\uff0c\u4e5f\u53ef\u4ee5\u91c7\u7528\u7cfb\u7edf\u9ed8\u8ba4\u7684\u65b9\u6848\uff0c\u901a\u5e38\u662f\u6307UTF-8\u3002 \u5728bytes\u548cstr\u7684\u4e92\u76f8\u8f6c\u6362\u8fc7\u7a0b\u4e2d\uff0c\u5b9e\u9645\u5c31\u662f\u7f16\u7801\u89e3\u7801\u7684\u8fc7\u7a0b\uff0c\u5fc5\u987b\u663e\u5f0f\u5730\u6307\u5b9a\u7f16\u7801\u683c\u5f0f\u3002 >>> s = '\u4e2d\u6587' >>> s '\u4e2d\u6587' >>> type(s) >>> b = bytes(s, encoding='utf-8') >>> b b'\\xe4\\xb8\\xad\\xe6\\x96\\x87' >>> type(b) >>> s.encode('utf-8') b'\\xe4\\xb8\\xad\\xe6\\x96\\x87' >>> b.decode('utf-8') '\u4e2d\u6587' >>> >>> str(b, encoding='utf-8') '\u4e2d\u6587' \u7f16\u5199Python\u7a0b\u5e8f\u7684\u65f6\u5019\uff0c\u4e00\u5b9a\u8981\u628a\u89e3\u7801\u548c\u7f16\u7801\u64cd\u4f5c\u653e\u5728\u754c\u9762\u6700\u5916\u5c42\u6765\u505a\uff0c\u8ba9\u7a0b\u5e8f\u7684\u6838\u5fc3\u90e8\u5206\u53ef\u4ee5\u4f7f\u7528Unicode\u6570\u636e\u6765\u8fd0\u4f5c\uff0c\u8fd9\u79cd\u529e\u6cd5\u901a\u5e38\u53eb\u4f5cUnicode\u4e09\u660e\u6cbb\uff08Unicode sandwich\uff09\u3002 \u6211\u4eec\u53ef\u4ee5\u7f16\u5199\u8f85\u52a9\u51fd\u6570\u6765\u786e\u4fdd\u7a0b\u5e8f\u6536\u5230\u7684\u5b57\u7b26\u5e8f\u5217\u786e\u5b9e\u662f\u671f\u671b\u8981\u64cd\u4f5c\u7684\u7c7b\u578b\uff08\u8981\u77e5\u9053\u81ea\u5df1\u60f3\u64cd\u4f5c\u7684\u5230\u5e95\u662fUnicode\u7801\u70b9\uff0c\u8fd8\u662f\u539f\u59cb\u76848\u4f4d\u503c\u3002\u7528UTF-8\u6807\u51c6\u7ed9\u5b57\u7b26\u4e32\u7f16\u7801\uff0c\u5f97\u5230\u7684\u5c31\u662f\u8fd9\u6837\u7684\u4e00\u7cfb\u52178\u4f4d\u503c\uff09\u3002 \u8f85\u52a9\u51fd\u6570to_str\u63a5\u53d7bytes\u6216str\u5b9e\u4f8b\uff0c\u5e76\u8fd4\u56destr\uff1a >>> def to_str(bytes_or_str): ... if isinstance(bytes_or_str, bytes): ... value = bytes_or_str.decode('utf-8') ... else: ... value = bytes_or_str ... return value ... >>> repr(to_str(b'foo')) \"'foo'\" >>> repr(to_str('foo')) \"'foo'\" >>> to_str('foo') 'foo' >>> to_str(b'foo') 'foo' \u8f85\u52a9\u51fd\u6570to_bytes\u63a5\u53d7bytes\u6216str\u5b9e\u4f8b\uff0c\u5e76\u8fd4\u56debytes\uff1a >>> def to_bytes(bytes_or_str): ... if isinstance(bytes_or_str, str): ... value = bytes_or_str.encode('utf-8') ... else: ... value = bytes_or_str ... return value ... >>> repr(to_bytes(b'foo')) \"b'foo'\" >>> repr(to_bytes('foo')) \"b'foo'\" >>> to_bytes(b'foo') b'foo' >>> to_bytes('foo') bytes\u4e0estr\u8fd9\u4e24\u79cd\u5b9e\u4f8b\u4e0d\u80fd\u5728\u67d0\u4e9b\u64cd\u4f5c\u7b26\uff08\u4f8b\u5982>\u3001==\u3001+\u3001%\u64cd\u4f5c\u7b26\uff09\u4e0a\u9762\u6df7\u7528\u3002 >>> b'one' + b'two' b'onetwo' >>> 'one'+'two' 'onetwo' \u4e0d\u80fd\u5c06str\u5b9e\u4f8b\u6dfb\u52a0\u5230bytes\u5b9e\u4f8b\uff1a >>> b'one' + 'two' Traceback (most recent call last): File \"\", line 1, in TypeError: can't concat str to bytes \u4e0d\u80fd\u5c06byte\u5b9e\u4f8b\u6dfb\u52a0\u5230str\u5b9e\u4f8b\uff1a > > > 'one' + b'two' Traceback (most recent call last): File \"\", line 1, in TypeError: can only concatenate str (not \"bytes\") to str str\u5b9e\u4f8b\u4e0d\u80fd\u4e0ebytes\u5b9e\u4f8b\u6bd4\u8f83\uff0c\u5373\u4fbf\u8fd9\u4e24\u4e2a\u5b9e\u4f8b\u8868\u793a\u7684\u5b57\u7b26\u5b8c\u5168\u76f8\u540c\uff0c\u5b83\u4eec\u4e5f\u4e0d\u76f8\u7b49\uff1a >>> assert 'red' >= b'red' Traceback (most recent call last): File \"\", line 1, in TypeError: '>=' not supported between instances of 'str' and 'bytes' >>> assert b'red' >= 'red' Traceback (most recent call last): File \"\", line 1, in TypeError: '>=' not supported between instances of 'bytes' and 'str' \u4e24\u79cd\u7c7b\u578b\u7684\u5b9e\u4f8b\u90fd\u53ef\u4ee5\u51fa\u73b0\u5728%\u64cd\u4f5c\u7b26\u7684\u53f3\u4fa7\uff0c\u7528\u6765\u66ff\u6362\u5de6\u4fa7\u90a3\u4e2a\u683c\u5f0f\u5b57\u7b26\u4e32\uff08format string\uff09\u91cc\u9762\u7684%s\u3002 >>> print(b'red %s' % b'blue') b'red blue' >>> print('red %s' % 'blue') red blue \u5982\u679c\u683c\u5f0f\u5b57\u7b26\u4e32\u662fbytes\u7c7b\u578b\uff0c\u90a3\u4e48\u4e0d\u80fd\u7528str\u5b9e\u4f8b\u6765\u66ff\u6362\u5176\u4e2d\u7684%s\u3002 \u5982\u679c\u683c\u5f0f\u5b57\u7b26\u4e32\u662fstr\u7c7b\u578b\uff0c\u5219\u53ef\u4ee5\u7528bytes\u5b9e\u4f8b\u6765\u66ff\u6362\u5176\u4e2d\u7684%s\u3002(\u7cfb\u7edf\u5728bytes\u5b9e\u4f8b\u4e0a\u9762\u8c03\u7528__repr__ \u65b9\u6cd5\uff08Rule75\uff09\uff0c\u7136\u540e\u7528\u8fd9\u6b21\u8c03\u7528\u6240\u5f97\u5230\u7684\u7ed3\u679c\u66ff\u6362\u683c\u5f0f\u5b57\u7b26\u4e32\u91cc\u7684%s\uff0c\u56e0\u6b64\u7a0b\u5e8f\u4f1a\u76f4\u63a5\u8f93\u51fab'blue'\uff0c\u800c\u4e0d\u662f\u8f93\u51fablue\u672c\u8eab\u3002) >>> print(b'red %s' % 'blue') Traceback (most recent call last): File \"\", line 1, in TypeError: %b requires a bytes-like object, or an object that implements __bytes__, not 'str' >>> print('red %s' % b'blue') red b'blue' \u5728\u64cd\u4f5c\u6587\u4ef6\u53e5\u67c4\u7684\u65f6\u5019\uff0c\u8fd9\u91cc\u7684\u53e5\u67c4\u6307\u7531\u5185\u7f6e\u7684open\u51fd\u6570\u8fd4\u56de\u7684\u53e5\u67c4\u3002\u8fd9\u6837\u7684\u53e5\u67c4\u9ed8\u8ba4\u9700\u8981\u4f7f\u7528Unicode\u5b57\u7b26\u4e32\u64cd\u4f5c\uff0c\u800c\u4e0d\u80fd\u91c7\u7528\u539f\u59cb\u7684bytes\u3002 \u4ece\u6587\u4ef6\u4e2d\u8bfb\u53d6\u4e8c\u8fdb\u5236\u6570\u636e\uff08\u6216\u8005\u628a\u4e8c\u8fdb\u5236\u6570\u636e\u5199\u5165\u6587\u4ef6\uff09\u65f6\uff0c\u5e94\u8be5\u7528'rb'\uff08'wb'\uff09\u8fd9\u6837\u7684\u4e8c\u8fdb\u5236\u6a21\u5f0f\u6253\u5f00\u6587\u4ef6\u3002 >>> with open('./temp/data.bin', 'w') as f: ... f.write(b'\\xf1\\xf2\\xf3\\xf4\\xf5') ... Traceback (most recent call last): File \"\", line 2, in TypeError: write() argument must be str, not bytes >>> >>> with open('./temp/data.bin', 'wb') as f: ... f.write(b'\\xf1\\xf2\\xf3\\xf4\\xf5') ... 5 >>> >>> with open('./temp/data.bin', 'r') as f: ... data = f.read() ... Traceback (most recent call last): File \"\", line 2, in File \"/usr/local/lib/python3.9/codecs.py\", line 322, in decode (result, consumed) = self._buffer_decode(data, self.errors, final) UnicodeDecodeError: 'utf-8' codec can't decode byte 0xf1 in position 0: invalid continuation byte >>> >>> >>> with open('./temp/data.bin', 'rb') as f: ... data = f.read() ... >>> assert data == b'\\xf1\\xf2\\xf3\\xf4\\xf5' >>> \u5982\u679c\u8981\u4ece\u6587\u4ef6\u4e2d\u8bfb\u53d6\uff08\u6216\u8005\u8981\u5199\u5165\u6587\u4ef6\u4e4b\u4e2d\uff09\u7684\u662fUnicode\u6570\u636e\uff0c\u90a3\u4e48\u5fc5\u987b\u6ce8\u610f\u7cfb\u7edf\u9ed8\u8ba4\u7684\u6587\u672c\u7f16\u7801\u65b9\u6848\u3002\u82e5\u65e0\u6cd5\u80af\u5b9a\uff0c\u53ef\u901a\u8fc7encoding\u53c2\u6570\u660e\u786e\u6307\u5b9a\u3002 >>> with open('./temp/data.bin', 'r', encoding='cp1252') as f: ... data = f.read() ... >>> assert data == b'\\xf1\\xf2\\xf3\\xf4\\xf5' Traceback (most recent call last): File \"\", line 1, in AssertionError \u67e5\u770b\u5f53\u524d\u64cd\u4f5c\u7cfb\u7edf\u9ed8\u8ba4\u7684\u7f16\u7801\u6807\u51c6 >>> import locale >>> locale.getpreferredencoding() 'UTF-8' >>>","title":"\u7b2c03\u6761 \u4e86\u89e3bytes\u4e0estr\u7684\u533a\u522b"},{"location":"python/Pythonic90Rules/Rule03/#3-bytesstr","text":"","title":"\u7b2c3\u6761\u3000\u4e86\u89e3bytes\u4e0estr\u7684\u533a\u522b"},{"location":"python/Pythonic90Rules/Rule03/#unicode","text":"ASCII\u7f16\u7801\u89c4\u5b9a1\u4e2a\u5b57\u8282\u7b49\u4e8e8\u4e2a\u6bd4\u7279\u4f4d\uff0c\u4ee3\u88681\u4e2a\u5b57\u7b26\u7684\u7f16\u7801\uff0c\u9664\u4e86\u7b2c\u4e00\u4f4d\u662f0\uff0c \u5176\u4ed67\u4f4d\u90fd\u53ef\u4ee5\u67090 \u6216\u8005 1 \u4e24\u4e2a\u9009\u62e9\uff0c\u6240\u4ee5ASCII \u4e00\u5171\u53ef\u4ee5\u8868\u793a 2^7 \uff0c\u4e5f\u5c31\u662f128\u4e2a\u5b57\u7b26\u3002\u5305\u62eca-z \u5927\u5c0f\u5199\uff0c0-9 \u6570\u5b57 \u548c\u4e00\u4e9b\u6807\u70b9\u7b26\u53f7\u7b49\u3002\u5176\u4e2d\u771f\u6b63\u53ef\u8bfb\u7684\u53ea\u670995 \u4e2a\u5b57\u7b26\uff0c\u5176\u4ed6\u7684\u90fd\u662f\u4e00\u4e9b\u63a7\u5236\u7b26\uff0c\u6bd4\u5982NUL\uff0c\u4ee3\u8868NULL\u3002 \u591a\u5b57\u8282\u7f16\u7801\uff0c\u6bd4\u5982\u53cc\u5b57\u8282\u7f16\u7801\u65b9\u5f0f\uff0cBIG-5\u548cGB18030\u5305\u542b\u4e86\u5927\u591a\u6570\u4e2d\u6587\u7b80\u4f53\u548c\u7e41\u4f53\u3002\u8fd9\u4e2a\u7f16\u7801\u4e0d\u517c\u5bb9ASCII\uff0c\u540c\u65f6\u8fd8\u5360\u7528\u8f83\u591a\u7684\u7a7a\u95f4\u548c\u5185\u5b58\u3002 UNICODE\u4e0d\u662f\u4e00\u79cd\u7f16\u7801\uff0c \u800c\u662f\u5b9a\u4e49\u4e86\u4e00\u4e2a\u8868\uff0c \u8868\u4e2d\u4e3a\u4e16\u754c\u4e0a\u6bcf\u79cd\u8bed\u8a00\u4e2d\u7684\u6bcf\u4e2a\u5b57\u7b26\u8bbe\u5b9a\u4e86\u7edf\u4e00\u5e76\u4e14\u552f\u4e00\u7684\u7801\u4f4d \uff08code point\uff09\uff0c\u4ee5\u6ee1\u8db3\u8de8\u8bed\u8a00\u3001\u8de8\u5e73\u53f0\u8fdb\u884c\u6587\u672c\u8f6c\u6362\u7684\u8981\u6c42\u3002 UTF-8\u7f16\u7801\u89c4\u5b9a\u82f1\u6587\u5b57\u6bcd\u7cfb\u5217\u75281\u4e2a\u5b57\u8282\u8868\u793a\uff0c\u6c49\u5b57\u75283\u4e2a\u5b57\u8282\u8868\u793a\u7b49\u7b49\u3002UTF-8\u7684\u7279\u70b9\u662f\u5bf9\u4e0d\u540c\u8303\u56f4\u7684\u5b57\u7b26\u4f7f\u7528\u4e0d\u540c\u957f\u5ea6\u7684\u7f16\u7801\u3002 \u4e0b\u8868\u8868\u793a\u5982\u4f55\u4ece\u4e00\u4e2a\u4eceUnicode \u8f6c\u5316\u5230UTF-8 , \u5bf9\u4e8e\u524d0x7F\u7684\u5b57\u7b26\uff0cUTF-8\u7f16\u7801\u548cASCII\u7801\u662f\u4e00\u4e00\u5bf9\u5e94\u7684\u3002 \u5982\u679c\u4e00\u4e2a\u5b57\u7b26\u5728000800-00FFFF \u4e4b\u95f4\uff0c\u90a3\u8f6c\u5316\u5230UTF-8 \u9700\u8981\u7528\u4e09\u5b57\u8282\u6a21\u677f\uff0c\u4f7f\u752816\u4e2a\u7801\u4f4d\uff0c\u6bcf\u4e2ax\u5c31\u662f\u4e00\u4e2a\u7801\u4f4d\u3002 Unicode\u7f16\u7801\uff08\u5341\u516d\u8fdb\u5236\uff09 UTF-8\u5b57\u8282\u6d41\uff08\u4e8c\u8fdb\u5236\uff09 000000 - 00007F 0xxxxxxx 000080 - 0007FF 110xxxx 10xxxxxx 000800 - 00FFFF 1110xxxx 10xxxxxx 10xxxxxx 010000 - 10FFFF 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx Python\u6709\u4e24\u79cd\u7c7b\u578b\u53ef\u4ee5\u8868\u793a\u5b57\u7b26\u5e8f\u5217(sequence)\uff1a\u4e00\u79cd\u662fbytes\uff0c\u53e6\u4e00\u79cd\u662fstr\u3002 bytes\u5b9e\u4f8b\u5305\u542b\u7684\u662f\u539f\u59cb\u6570\u636e\uff0c\u53738\u4f4d\u7684\u65e0\u7b26\u53f7\u503c\uff08\u901a\u5e38\u6309\u7167ASCII\u7f16\u7801\u6807\u51c6\u6765\u663e\u793a\uff09\u3002 str\u5b9e\u4f8b\u5305\u542b\u7684\u662fUnicode\u7801\u70b9\uff08code point\uff0c\u4e5f\u53eb\u4f5c\u4ee3\u7801\u70b9\uff09\uff0c\u8fd9\u4e9b\u7801\u70b9\u4e0e\u4eba\u7c7b\u8bed\u8a00\u4e4b\u4e2d\u7684\u6587\u672c\u5b57\u7b26\u76f8\u5bf9\u5e94\u3002 >>> a = b'h\\x65llo' >>> a b'hello' >>> list(a) [104, 101, 108, 108, 111] >>> b = 'a\\u0300 hello' >>> b 'a\u0300 hello' >>> list(b) ['a', '\u0300', ' ', 'h', 'e', 'l', 'l', 'o'] \u5185\u5b58\u662funicode\u7f16\u7801\u683c\u5f0f\uff0c\u786c\u76d8\u662futf-8\u3002 \u5728\u505a\u7f16\u7801\u8f6c\u6362\u65f6\u5019\uff0c\u901a\u5e38\u7528unicode\u4f5c\u4e3a\u4e2d\u95f4\u7f16\u7801\u3002 \u5148\u5c06\u5176\u4ed6\u7f16\u7801\u7684\u5b57\u7b26\u4e32\u89e3\u7801(decode)\u6210unicode,\u518d\u4eceunicode\u7f16\u7801(encode)\u6210\u53e6\u4e00\u79cd\u7f16\u7801\u683c\u5f0f\u3002 decode\u7684\u4f5c\u7528\u662f\u5c06\u4e8c\u8fdb\u5236\u6570\u636e\u89e3\u7801\u6210unicode\u7f16\u7801\u3002 encode\u7684\u4f5c\u7528\u662f\u5c06unicode\u7f16\u7801\u7684\u5b57\u7b26\u4e32\u7f16\u7801\u6210\u4e8c\u8fdb\u5236\u6570\u636e\u3002 \u8981\u628aUnicode\u6570\u636e\u8f6c\u6362\u6210\u4e8c\u8fdb\u5236\u6570\u636e\uff0c\u5fc5\u987b\u8c03\u7528str\u7684encode\u65b9\u6cd5\u3002 \u8981\u628a\u4e8c\u8fdb\u5236\u6570\u636e\u8f6c\u6362\u6210Unicode\u6570\u636e\uff0c\u5fc5\u987b\u8c03\u7528bytes\u7684decode\u65b9\u6cd5\u3002 \u8c03\u7528\u8fd9\u4e9b\u65b9\u6cd5\u7684\u65f6\u5019\uff0c\u53ef\u4ee5\u660e\u786e\u6307\u51fa\u81ea\u5df1\u8981\u4f7f\u7528\u7684\u7f16\u7801\u65b9\u6848\uff0c\u4e5f\u53ef\u4ee5\u91c7\u7528\u7cfb\u7edf\u9ed8\u8ba4\u7684\u65b9\u6848\uff0c\u901a\u5e38\u662f\u6307UTF-8\u3002 \u5728bytes\u548cstr\u7684\u4e92\u76f8\u8f6c\u6362\u8fc7\u7a0b\u4e2d\uff0c\u5b9e\u9645\u5c31\u662f\u7f16\u7801\u89e3\u7801\u7684\u8fc7\u7a0b\uff0c\u5fc5\u987b\u663e\u5f0f\u5730\u6307\u5b9a\u7f16\u7801\u683c\u5f0f\u3002 >>> s = '\u4e2d\u6587' >>> s '\u4e2d\u6587' >>> type(s) >>> b = bytes(s, encoding='utf-8') >>> b b'\\xe4\\xb8\\xad\\xe6\\x96\\x87' >>> type(b) >>> s.encode('utf-8') b'\\xe4\\xb8\\xad\\xe6\\x96\\x87' >>> b.decode('utf-8') '\u4e2d\u6587' >>> >>> str(b, encoding='utf-8') '\u4e2d\u6587' \u7f16\u5199Python\u7a0b\u5e8f\u7684\u65f6\u5019\uff0c\u4e00\u5b9a\u8981\u628a\u89e3\u7801\u548c\u7f16\u7801\u64cd\u4f5c\u653e\u5728\u754c\u9762\u6700\u5916\u5c42\u6765\u505a\uff0c\u8ba9\u7a0b\u5e8f\u7684\u6838\u5fc3\u90e8\u5206\u53ef\u4ee5\u4f7f\u7528Unicode\u6570\u636e\u6765\u8fd0\u4f5c\uff0c\u8fd9\u79cd\u529e\u6cd5\u901a\u5e38\u53eb\u4f5cUnicode\u4e09\u660e\u6cbb\uff08Unicode sandwich\uff09\u3002 \u6211\u4eec\u53ef\u4ee5\u7f16\u5199\u8f85\u52a9\u51fd\u6570\u6765\u786e\u4fdd\u7a0b\u5e8f\u6536\u5230\u7684\u5b57\u7b26\u5e8f\u5217\u786e\u5b9e\u662f\u671f\u671b\u8981\u64cd\u4f5c\u7684\u7c7b\u578b\uff08\u8981\u77e5\u9053\u81ea\u5df1\u60f3\u64cd\u4f5c\u7684\u5230\u5e95\u662fUnicode\u7801\u70b9\uff0c\u8fd8\u662f\u539f\u59cb\u76848\u4f4d\u503c\u3002\u7528UTF-8\u6807\u51c6\u7ed9\u5b57\u7b26\u4e32\u7f16\u7801\uff0c\u5f97\u5230\u7684\u5c31\u662f\u8fd9\u6837\u7684\u4e00\u7cfb\u52178\u4f4d\u503c\uff09\u3002 \u8f85\u52a9\u51fd\u6570to_str\u63a5\u53d7bytes\u6216str\u5b9e\u4f8b\uff0c\u5e76\u8fd4\u56destr\uff1a >>> def to_str(bytes_or_str): ... if isinstance(bytes_or_str, bytes): ... value = bytes_or_str.decode('utf-8') ... else: ... value = bytes_or_str ... return value ... >>> repr(to_str(b'foo')) \"'foo'\" >>> repr(to_str('foo')) \"'foo'\" >>> to_str('foo') 'foo' >>> to_str(b'foo') 'foo' \u8f85\u52a9\u51fd\u6570to_bytes\u63a5\u53d7bytes\u6216str\u5b9e\u4f8b\uff0c\u5e76\u8fd4\u56debytes\uff1a >>> def to_bytes(bytes_or_str): ... if isinstance(bytes_or_str, str): ... value = bytes_or_str.encode('utf-8') ... else: ... value = bytes_or_str ... return value ... >>> repr(to_bytes(b'foo')) \"b'foo'\" >>> repr(to_bytes('foo')) \"b'foo'\" >>> to_bytes(b'foo') b'foo' >>> to_bytes('foo') bytes\u4e0estr\u8fd9\u4e24\u79cd\u5b9e\u4f8b\u4e0d\u80fd\u5728\u67d0\u4e9b\u64cd\u4f5c\u7b26\uff08\u4f8b\u5982>\u3001==\u3001+\u3001%\u64cd\u4f5c\u7b26\uff09\u4e0a\u9762\u6df7\u7528\u3002 >>> b'one' + b'two' b'onetwo' >>> 'one'+'two' 'onetwo' \u4e0d\u80fd\u5c06str\u5b9e\u4f8b\u6dfb\u52a0\u5230bytes\u5b9e\u4f8b\uff1a >>> b'one' + 'two' Traceback (most recent call last): File \"\", line 1, in TypeError: can't concat str to bytes \u4e0d\u80fd\u5c06byte\u5b9e\u4f8b\u6dfb\u52a0\u5230str\u5b9e\u4f8b\uff1a > > > 'one' + b'two' Traceback (most recent call last): File \"\", line 1, in TypeError: can only concatenate str (not \"bytes\") to str str\u5b9e\u4f8b\u4e0d\u80fd\u4e0ebytes\u5b9e\u4f8b\u6bd4\u8f83\uff0c\u5373\u4fbf\u8fd9\u4e24\u4e2a\u5b9e\u4f8b\u8868\u793a\u7684\u5b57\u7b26\u5b8c\u5168\u76f8\u540c\uff0c\u5b83\u4eec\u4e5f\u4e0d\u76f8\u7b49\uff1a >>> assert 'red' >= b'red' Traceback (most recent call last): File \"\", line 1, in TypeError: '>=' not supported between instances of 'str' and 'bytes' >>> assert b'red' >= 'red' Traceback (most recent call last): File \"\", line 1, in TypeError: '>=' not supported between instances of 'bytes' and 'str' \u4e24\u79cd\u7c7b\u578b\u7684\u5b9e\u4f8b\u90fd\u53ef\u4ee5\u51fa\u73b0\u5728%\u64cd\u4f5c\u7b26\u7684\u53f3\u4fa7\uff0c\u7528\u6765\u66ff\u6362\u5de6\u4fa7\u90a3\u4e2a\u683c\u5f0f\u5b57\u7b26\u4e32\uff08format string\uff09\u91cc\u9762\u7684%s\u3002 >>> print(b'red %s' % b'blue') b'red blue' >>> print('red %s' % 'blue') red blue \u5982\u679c\u683c\u5f0f\u5b57\u7b26\u4e32\u662fbytes\u7c7b\u578b\uff0c\u90a3\u4e48\u4e0d\u80fd\u7528str\u5b9e\u4f8b\u6765\u66ff\u6362\u5176\u4e2d\u7684%s\u3002 \u5982\u679c\u683c\u5f0f\u5b57\u7b26\u4e32\u662fstr\u7c7b\u578b\uff0c\u5219\u53ef\u4ee5\u7528bytes\u5b9e\u4f8b\u6765\u66ff\u6362\u5176\u4e2d\u7684%s\u3002(\u7cfb\u7edf\u5728bytes\u5b9e\u4f8b\u4e0a\u9762\u8c03\u7528__repr__ \u65b9\u6cd5\uff08Rule75\uff09\uff0c\u7136\u540e\u7528\u8fd9\u6b21\u8c03\u7528\u6240\u5f97\u5230\u7684\u7ed3\u679c\u66ff\u6362\u683c\u5f0f\u5b57\u7b26\u4e32\u91cc\u7684%s\uff0c\u56e0\u6b64\u7a0b\u5e8f\u4f1a\u76f4\u63a5\u8f93\u51fab'blue'\uff0c\u800c\u4e0d\u662f\u8f93\u51fablue\u672c\u8eab\u3002) >>> print(b'red %s' % 'blue') Traceback (most recent call last): File \"\", line 1, in TypeError: %b requires a bytes-like object, or an object that implements __bytes__, not 'str' >>> print('red %s' % b'blue') red b'blue' \u5728\u64cd\u4f5c\u6587\u4ef6\u53e5\u67c4\u7684\u65f6\u5019\uff0c\u8fd9\u91cc\u7684\u53e5\u67c4\u6307\u7531\u5185\u7f6e\u7684open\u51fd\u6570\u8fd4\u56de\u7684\u53e5\u67c4\u3002\u8fd9\u6837\u7684\u53e5\u67c4\u9ed8\u8ba4\u9700\u8981\u4f7f\u7528Unicode\u5b57\u7b26\u4e32\u64cd\u4f5c\uff0c\u800c\u4e0d\u80fd\u91c7\u7528\u539f\u59cb\u7684bytes\u3002 \u4ece\u6587\u4ef6\u4e2d\u8bfb\u53d6\u4e8c\u8fdb\u5236\u6570\u636e\uff08\u6216\u8005\u628a\u4e8c\u8fdb\u5236\u6570\u636e\u5199\u5165\u6587\u4ef6\uff09\u65f6\uff0c\u5e94\u8be5\u7528'rb'\uff08'wb'\uff09\u8fd9\u6837\u7684\u4e8c\u8fdb\u5236\u6a21\u5f0f\u6253\u5f00\u6587\u4ef6\u3002 >>> with open('./temp/data.bin', 'w') as f: ... f.write(b'\\xf1\\xf2\\xf3\\xf4\\xf5') ... Traceback (most recent call last): File \"\", line 2, in TypeError: write() argument must be str, not bytes >>> >>> with open('./temp/data.bin', 'wb') as f: ... f.write(b'\\xf1\\xf2\\xf3\\xf4\\xf5') ... 5 >>> >>> with open('./temp/data.bin', 'r') as f: ... data = f.read() ... Traceback (most recent call last): File \"\", line 2, in File \"/usr/local/lib/python3.9/codecs.py\", line 322, in decode (result, consumed) = self._buffer_decode(data, self.errors, final) UnicodeDecodeError: 'utf-8' codec can't decode byte 0xf1 in position 0: invalid continuation byte >>> >>> >>> with open('./temp/data.bin', 'rb') as f: ... data = f.read() ... >>> assert data == b'\\xf1\\xf2\\xf3\\xf4\\xf5' >>> \u5982\u679c\u8981\u4ece\u6587\u4ef6\u4e2d\u8bfb\u53d6\uff08\u6216\u8005\u8981\u5199\u5165\u6587\u4ef6\u4e4b\u4e2d\uff09\u7684\u662fUnicode\u6570\u636e\uff0c\u90a3\u4e48\u5fc5\u987b\u6ce8\u610f\u7cfb\u7edf\u9ed8\u8ba4\u7684\u6587\u672c\u7f16\u7801\u65b9\u6848\u3002\u82e5\u65e0\u6cd5\u80af\u5b9a\uff0c\u53ef\u901a\u8fc7encoding\u53c2\u6570\u660e\u786e\u6307\u5b9a\u3002 >>> with open('./temp/data.bin', 'r', encoding='cp1252') as f: ... data = f.read() ... >>> assert data == b'\\xf1\\xf2\\xf3\\xf4\\xf5' Traceback (most recent call last): File \"\", line 1, in AssertionError \u67e5\u770b\u5f53\u524d\u64cd\u4f5c\u7cfb\u7edf\u9ed8\u8ba4\u7684\u7f16\u7801\u6807\u51c6 >>> import locale >>> locale.getpreferredencoding() 'UTF-8' >>>","title":"UNICODE\u7f16\u7801\u7b80\u4ecb"},{"location":"python/Pythonic90Rules/Rule04/","text":"\u7b2c4\u6761\u3000\u7528\u652f\u6301\u63d2\u503c\u7684f-string\u53d6\u4ee3C\u98ce\u683c\u7684\u683c\u5f0f\u5b57\u7b26\u4e32\u4e0estr.format\u65b9\u6cd5 \u00b6 \u683c\u5f0f\u5316\uff08formatting\uff09\u662f\u6307\u628a\u6570\u636e\u586b\u5199\u5230\u9884\u5148\u5b9a\u4e49\u7684\u6587\u672c\u6a21\u677f\u91cc\u9762\uff0c\u5f62\u6210\u4e00\u6761\u7528\u6237\u53ef\u8bfb\u7684\u6d88\u606f\uff0c\u5e76\u628a\u8fd9\u6761\u6d88\u606f\u4fdd\u5b58\u6210\u5b57\u7b26\u4e32\u7684\u8fc7\u7a0b\u3002 \u7528Python\u5bf9\u5b57\u7b26\u4e32\u505a\u683c\u5f0f\u5316\u5904\u7406\u6709\u56db\u79cd\u529e\u6cd5\u53ef\u4ee5\u8003\u8651\uff0c\u8fd9\u4e9b\u529e\u6cd5\u90fd\u5185\u7f6e\u5728\u8bed\u8a00\u548c\u6807\u51c6\u5e93\u91cc\u9762\u3002 \u4f46\u5176\u4e2d\u4e09\u79cd\u529e\u6cd5\u6709\u4e25\u91cd\u7684\u7f3a\u9677\uff0c\u73b0\u5728\u5148\u89e3\u91ca\u4e3a\u4ec0\u4e48\u4e0d\u8981\u4f7f\u7528\u8fd9\u4e09\u79cd\u529e\u6cd5\uff0c\u6700\u540e\u518d\u7ed9\u51fa\u5269\u4e0b\u7684\u90a3\u4e00\u79cd\u3002 Python\u91cc\u9762\u6700\u5e38\u7528\u7684\u5b57\u7b26\u4e32\u683c\u5f0f\u5316\u65b9\u5f0f\u662f\u91c7\u7528%\u683c\u5f0f\u5316\u64cd\u4f5c\u7b26(C\u98ce\u683c\u7684\u683c\u5f0f\u5b57\u7b26\u4e32)\u3002 \u8fd9\u4e2a\u64cd\u4f5c\u7b26\u5de6\u8fb9\u7684\u6587\u672c\u6a21\u677f\u53eb\u4f5c\u683c\u5f0f\u5b57\u7b26\u4e32\uff08format string\uff09\uff0c\u6211\u4eec\u53ef\u4ee5\u5728\u64cd\u4f5c\u7b26\u53f3\u8fb9\u5199\u4e0a\u67d0\u4e2a\u503c\u6216\u8005\u7531\u591a\u4e2a\u503c\u6240\u6784\u6210\u7684\u5143\u7ec4\uff08tuple\uff09\uff0c\u7528\u6765\u66ff\u6362\u683c\u5f0f\u5b57\u7b26\u4e32\u91cc\u7684\u76f8\u5173\u7b26\u53f7\u3002 python\u5b57\u7b26\u4e32\u683c\u5f0f\u5316\u7b26\u53f7\uff1a %c\uff1a\u5b57\u7b26\u53ca\u5176ASCII\u7801 %s\uff1a\u5b57\u7b26\u4e32 %d\uff1a\u6574\u6570 %u\uff1a\u65e0\u7b26\u53f7\u6574\u578b %o\uff1a\u65e0\u7b26\u53f7\u516b\u8fdb\u5236\u6570 %x\uff1a\u65e0\u7b26\u53f7\u5341\u516d\u8fdb\u5236\u6570 %X\uff1a\u65e0\u7b26\u53f7\u5341\u516d\u8fdb\u5236\u6570\uff08\u5927\u5199\uff09 %f\uff1a\u6d6e\u70b9\u6570\u5b57\uff0c\u53ef\u6307\u5b9a\u5c0f\u6570\u70b9\u540e\u7684\u7cbe\u5ea6 %e\uff1a\u7528\u79d1\u5b66\u8ba1\u6570\u6cd5\u683c\u5f0f\u5316\u6d6e\u70b9\u6570 %E\uff1a\u4f5c\u7528\u540c%e\uff0c\u7528\u79d1\u5b66\u8ba1\u6570\u6cd5\u683c\u5f0f\u5316\u6d6e\u70b9\u6570 %g\uff1a%f\u548c%e\u7684\u7b80\u5199 %G\uff1a%f \u548c %E \u7684\u7b80\u5199 %p\uff1a\u7528\u5341\u516d\u8fdb\u5236\u6570\u683c\u5f0f\u5316\u53d8\u91cf\u7684\u5730\u5740 a = 128 b = 3.1415926 print('Binary is %d, Hex is %X, Oct is %o, Float is %e' % (a, a, a, b)) >>> Binary is 128, Hex is 80, Oct is 200, Float is 3.141593e+00 C\u98ce\u683c\u7684\u683c\u5f0f\u5b57\u7b26\u4e32\uff0c\u5728Python\u91cc\u6709\u56db\u4e2a\u7f3a\u70b9\u3002 \u7b2c\u4e00\u4e2a\u7f3a\u70b9\u662f\uff0c\u5982\u679c%\u53f3\u4fa7\u90a3\u4e2a\u5143\u7ec4\u91cc\u9762\u7684\u503c\u5728\u7c7b\u578b\u6216\u987a\u5e8f\u4e0a\u6709\u53d8\u5316\uff0c\u90a3\u4e48\u7a0b\u5e8f\u53ef\u80fd\u4f1a\u56e0\u4e3a\u8f6c\u6362\u7c7b\u578b\u65f6\u53d1\u751f\u4e0d\u517c\u5bb9\u95ee\u9898\u800c\u51fa\u73b0\u9519\u8bef\u3002 >>> key = 'my_var' >>> value = 1.234 >>> formatted = '%-10s = %.2f' % (key, value) # %-10s\u4ee3\u8868=\u5de6\u8fb9\u5b57\u4e32\u603b\u957f\u5ea610,\u4e0d\u8db3\u90e8\u5206\u5728\u5c3e\u90e8\u6dfb\u52a0\u7a7a\u683c >>> formatted 'my_var = 1.23' >>> \u5982\u679c\u628akey\u8ddfvalue\u4e92\u6362\u4f4d\u7f6e\uff0c\u6216\u8005\u5de6\u4fa7\u90a3\u4e2a\u683c\u5f0f\u5b57\u7b26\u4e32\u91cc\u9762\u7684\u4e24\u4e2a\u8bf4\u660e\u7b26\u5bf9\u8c03\u4e86\u987a\u5e8f\uff0c\u90a3\u4e48\u7a0b\u5e8f\u5c31\u4f1a\u5728\u8fd0\u884c\u65f6\u51fa\u73b0\u5f02\u5e38\u3002 >>> key = 'my_var' >>> value = 1.234 >>> formatted = '%-10s = %.2f' % (value, key) Traceback (most recent call last): File \"\", line 1, in TypeError: must be real number, not str >>> key = 'my_var' >>> value = 1.234 >>> formatted = '%.2f = %-10s' % (key, value) Traceback (most recent call last): File \"\", line 1, in TypeError: must be real number, not str \u7b2c\u4e8c\u4e2a\u7f3a\u70b9\u662f\uff0c\u5728\u586b\u5145\u6a21\u677f\u4e4b\u524d\uff0c\u7ecf\u5e38\u8981\u5148\u5bf9\u51c6\u5907\u586b\u5199\u8fdb\u53bb\u7684\u8fd9\u4e2a\u503c\u7a0d\u5fae\u505a\u4e00\u4e9b\u5904\u7406\uff0c\u4f46\u8fd9\u6837\u4e00\u6765\uff0c\u6574\u4e2a\u8868\u8fbe\u5f0f\u53ef\u80fd\u5c31\u4f1a\u5199\u5f97\u5f88\u957f\uff0c\u5f71\u54cd\u7a0b\u5e8f\u7684\u53ef\u8bfb\u6027\u3002 >>> pantry = [ ... ('avocados', 1.25), ... ('bananas', 2.5), ... ('cherries', 15) ... ] >>> for i, (item, count) in enumerate(pantry): ... print( ... '#%d: %-10s = %.2f' % ( ... i + 1, ... item.title(), ... round(count) ... ) ... ) ... #1: Avocados = 1.00 #2: Bananas = 2.00 #3: Cherries = 15.00 \u7b2c\u4e09\u4e2a\u7f3a\u70b9\u662f\uff0c\u5982\u679c\u60f3\u7528\u540c\u4e00\u4e2a\u503c\u6765\u586b\u5145\u683c\u5f0f\u5b57\u7b26\u4e32\u91cc\u7684\u591a\u4e2a\u4f4d\u7f6e\uff0c\u90a3\u4e48\u5fc5\u987b\u5728%\u64cd\u4f5c\u7b26\u53f3\u4fa7\u7684\u5143\u7ec4\u4e2d\u76f8\u5e94\u5730\u591a\u6b21\u91cd\u590d\u8be5\u503c\u3002 >>> template = '%s loves food. See %s cook.' >>> name = 'Max' >>> formatted = template % (name, name) >>> formatted 'Max loves food. See Max cook.' \u4e3a\u4e86\u89e3\u51b3\u4e0a\u9762\u63d0\u5230\u7684\u4e00\u4e9b\u95ee\u9898\uff0cPython\u7684%\u64cd\u4f5c\u7b26\u5141\u8bb8\u6211\u4eec\u7528dict\u53d6\u4ee3tuple\uff0c\u89e3\u51b3\u4e86%\u64cd\u4f5c\u7b26\u4e24\u4fa7\u7684\u987a\u5e8f\u4e0d\u5339\u914d\u95ee\u9898\u3002 >>> key = 'my_var' >>> value = 1.234 >>> old_way = '%-10s = %.2f' % (key, value) >>> new_way = '%(key)-10s = %(value).2f' % {'key': key, 'value': value} # \u5bf9\u5e94 >>> reordered = '%(key)-10s = %(value).2f' % {'value': value, 'key': key} # \u4e92\u6362 >>> assert old_way == new_way == reordered >>> old_way 'my_var = 1.23' >>> new_way 'my_var = 1.23' >>> reordered 'my_var = 1.23' \u7528dict\u53d6\u4ee3tuple\uff0c\u4e5f\u89e3\u51b3\u7528\u540c\u4e00\u4e2a\u503c\u66ff\u6362\u591a\u4e2a\u683c\u5f0f\u8bf4\u660e\u7b26\u7684\u95ee\u9898\uff0c\u6211\u4eec\u5c31\u4e0d\u7528\u5728%\u64cd\u4f5c\u7b26\u53f3\u4fa7\u91cd\u590d\u8fd9\u4e2a\u503c\u4e86\u3002 >>> name = 'Max' >>> template = '%s loves food. See %s cook.' >>> before = template % (name, name) >>> template = '%(name)s loves food. See %(name)s cook.' >>> after = template % {'name': name} >>> assert before == after >>> before 'Max loves food. See Max cook.' >>> after 'Max loves food. See Max cook.' \u4f46\u662f\uff0c\u8fd9\u79cd\u5199\u6cd5\u4f1a\u8ba9\u7b2c\u4e8c\u4e2a\u7f3a\u70b9\u53d8\u5f97\u66f4\u52a0\u4e25\u91cd\uff0c\u683c\u5f0f\u5316\u8868\u8fbe\u5f0f\u53d8\u5f97\u66f4\u52a0\u5197\u957f\uff0c\u770b\u8d77\u6765\u4e5f\u66f4\u52a0\u6df7\u4e71\u3002\u5982\u4e0b\u4f8b\uff1a >>> pantry = [ ... ('avocados', 1.25), ... ('bananas', 2.5), ... ('cherries', 15) ... ] >>> for i, (item, count) in enumerate(pantry): ... before = '#%d: %-10s = %.2f' % ( ... i + 1, ... item.title(), ... round(count) ... ) ... after = '#%(loop)d: %(item)-10s = %(count).2f' % { ... 'loop': i + 1, ... 'item': item.title(), ... 'count': round(count) ... } ... assert before == after ... print(before) ... print(after) ... #1: Avocados = 1.00 #1: Avocados = 1.00 #2: Bananas = 2.00 #2: Bananas = 2.00 #3: Cherries = 15.00 #3: Cherries = 15.00 \u6240\u4ee5\uff0c\u7b2c\u56db\u4e2a\u7f3a\u70b9\u662f\uff0c\u628adict\u5199\u5230\u683c\u5f0f\u5316\u8868\u8fbe\u5f0f\u91cc\u9762\u4f1a\u8ba9\u4ee3\u7801\u53d8\u591a\uff0c\u6bcf\u4e2a\u952e\u90fd\u81f3\u5c11\u8981\u5199\u4e24\u6b21\u3002\u4e3a\u4e86\u67e5\u770b\u683c\u5f0f\u5b57\u7b26\u4e32\u4e2d\u7684\u8bf4\u660e\u7b26\u7a76\u7adf\u5bf9\u5e94\u4e8e\u5b57\u5178\u91cc\u7684\u54ea\u4e2a\u952e\uff0c\u5fc5\u987b\u5728\u8fd9\u4e24\u6bb5\u4ee3\u7801\u4e4b\u95f4\u6765\u56de\u8df3\u8dc3\u3002\u5982\u679c\u8981\u5bf9\u952e\u540d\u7a0d\u505a\u4fee\u6539\uff0c\u90a3\u4e48\u5fc5\u987b\u540c\u6b65\u4fee\u6539\u683c\u5f0f\u5b57\u7b26\u4e32\u91cc\u7684\u8bf4\u660e\u7b26\uff0c\u8fd9\u66f4\u8ba9\u4ee3\u7801\u53d8\u5f97\u76f8\u5f53\u70e6\u7410\uff0c\u53ef\u8bfb\u6027\u66f4\u5dee\u3002 \u5185\u7f6e\u7684format\u51fd\u6570\u4e0estr\u7c7b\u7684format\u65b9\u6cd5 \u00b6 Python 3\u6dfb\u52a0\u4e86\u9ad8\u7ea7\u5b57\u7b26\u4e32\u683c\u5f0f\u5316\uff08advanced stringformatting\uff09\u673a\u5236\uff0c\u5b83\u7684\u8868\u8fbe\u80fd\u529b\u6bd4\u8001\u5f0fC\u98ce\u683c\u7684\u683c\u5f0f\u5b57\u7b26\u4e32\u8981\u5f3a\uff0c\u4e14\u4e0d\u518d\u4f7f\u7528%\u64cd\u4f5c\u7b26\u3002 \u4e0b\u9762\u8fd9\u6bb5\u4ee3\u7801\uff0c\u6f14\u793a\u4e86\u8fd9\u79cd\u65b0\u7684\u683c\u5f0f\u5316\u65b9\u5f0f\u3002\u5728\u4f20\u7ed9format\u51fd\u6570\u7684\u683c\u5f0f\u91cc\u9762\uff0c\u9017\u53f7\u8868\u793a\u663e\u793a\u5343\u4f4d\u5206\u9694\u7b26\uff0c^\u8868\u793a\u5c45\u4e2d\u5bf9\u9f50\u3002 >>> a = 1234.5678 >>> formatted = format(a, ',.2f') >>> formatted '1,234.57' >>> b = 'my string' >>> formatted = format(b, '^20s') >>> formatted ' my string ' \u5982\u679cstr\u7c7b\u578b\u7684\u5b57\u7b26\u4e32\u91cc\u9762\u6709\u8bb8\u591a\u503c\u90fd\u9700\u8981\u8c03\u6574\u683c\u5f0f\uff0c\u5219\u53ef\u4ee5\u628a\u683c\u5f0f\u6709\u5f85\u8c03\u6574\u7684\u90a3\u4e9b\u4f4d\u7f6e\u5728\u5b57\u7b26\u4e32\u91cc\u9762\u5148\u7528{}\u4ee3\u66ff\uff0c\u7136\u540e\u6309\u4ece\u5de6\u5230\u53f3\u7684\u987a\u5e8f\uff0c\u628a\u9700\u8981\u586b\u5199\u5230\u90a3\u4e9b\u4f4d\u7f6e\u7684\u503c\u4f20\u7ed9format\u65b9\u6cd5\uff0c\u4f7f\u8fd9\u4e9b\u503c\u4f9d\u6b21\u51fa\u73b0\u5728\u5b57\u7b26\u4e32\u4e2d\u7684\u76f8\u5e94\u4f4d\u7f6e\u3002 >>> key = 'my_var' >>> value = 1.234 >>> formatted = '{} = {}'.format(key, value) >>> formatted 'my_var = 1.234' >>> formatted = '{} = {}'.format(value, key) >>> formatted '1.234 = my_var' \u901a\u8fc7\u5728{}\u91cc\u5199\u4e2a\u5192\u53f7\uff0c\u7136\u540e\u628a\u683c\u5f0f\u8bf4\u660e\u7b26\u5199\u5728\u5192\u53f7\u7684\u53f3\u8fb9\uff0c\u6765\u6dfb\u52a0\u683c\u5f0f\u3002\uff08\u6dfb\u52a0\u683c\u5f0f\u540e\uff0c\u4e92\u6362\u4f1a\u62a5\u9519\uff09 >>> formatted = '{:<10} = {:.2f}'.format(key, value) >>> formatted 'my_var = 1.23' >>> formatted = '{:<10} = {:.2f}'.format(value, key) Traceback (most recent call last): File \"\", line 1, in ValueError: Unknown format code 'f' for object of type 'str' \u4e5f\u53ef\u4ee5\u7ed9str\u7684{}\u91cc\u9762\u5199\u4e0a\u6570\u5b57\uff0c\u7528\u6765\u6307\u4ee3format\u65b9\u6cd5\u5728\u8fd9\u4e2a\u4f4d\u7f6e\u6240\u63a5\u6536\u5230\u7684\u53c2\u6570\u503c\u4f4d\u7f6e\u7d22\u5f15\u3002 \u4ee5\u540e\u5373\u4f7f\u8fd9\u4e9b{}\u5728\u683c\u5f0f\u5b57\u7b26\u4e32\u4e2d\u7684\u6b21\u5e8f\u6709\u6240\u53d8\u52a8\uff0c\u4e5f\u4e0d\u7528\u8c03\u6362\u4f20\u7ed9format\u65b9\u6cd5\u7684\u90a3\u4e9b\u53c2\u6570\u3002\u4e8e\u662f\uff0c\u8fd9\u5c31\u907f\u514d\u4e86\u524d\u9762\u8bb2\u7684\u7b2c\u4e00\u4e2a\u7f3a\u70b9\u6240\u63d0\u5230\u7684\u90a3\u4e2a\u987a\u5e8f\u95ee\u9898\u3002 >>> key = 'my_var' >>> value = 1.234 >>> formatted = '{} = {}'.format(key, value) >>> formatted 'my_var = 1.234' >>> formatted = '{1} = {0}'.format(key, value) >>> formatted '1.234 = my_var' >>> formatted = '{2} = {1}'.format(key, value) Traceback (most recent call last): File \"\", line 1, in IndexError: Replacement index 2 out of range for positional args tuple \u540c\u4e00\u4e2a\u4f4d\u7f6e\u7d22\u5f15\u53ef\u4ee5\u51fa\u73b0\u5728str\u7684\u591a\u4e2a{}\u91cc\u9762\uff0c\u8fd9\u5c31\u4e0d\u9700\u8981\u628a\u8fd9\u4e2a\u503c\u91cd\u590d\u5730\u4f20\u7ed9format\u65b9\u6cd5\uff0c\u4e8e\u662f\u5c31\u89e3\u51b3\u4e86\u524d\u9762\u63d0\u5230\u7684\u7b2c\u4e09\u4e2a\u7f3a\u70b9\u3002 >>> name = 'Max' >>> formatted = '%s loves food. See %s cook.' % (name, name) >>> formatted 'Max loves food. See Max cook.' >>> formatted = '%(name)s loves food. See %(name)s cook.' % {'name': name} >>> formatted 'Max loves food. See Max cook.' >>> formatted = '{0} loves food. See {0} cook.'.format(name) >>> formatted 'Max loves food. See Max cook.' \u4e0a\u8ff0\u529f\u80fd\u5206\u6790\uff1a \u7cfb\u7edf\u5148\u628astr.format\u65b9\u6cd5\u63a5\u6536\u5230\u7684\u6bcf\u4e2a\u503c\u4f20\u7ed9\u5185\u7f6e\u7684format\u51fd\u6570\uff0c\u5e76\u627e\u5230\u8fd9\u4e2a\u503c\u5728\u5b57\u7b26\u4e32\u91cc\u5bf9\u5e94\u7684{}\uff0c\u540c\u65f6\u5c06{}\u91cc\u9762\u5199\u7684\u683c\u5f0f\u4e5f\u4f20\u7ed9format\u51fd\u6570\uff0c\u4f8b\u5982\u7cfb\u7edf\u5728\u5904\u7406value\u7684\u65f6\u5019\uff0c\u4f20\u7684\u5c31\u662fformat(value,'.2f')\u3002 \u7136\u540e\uff0c\u7cfb\u7edf\u4f1a\u628aformat\u51fd\u6570\u6240\u8fd4\u56de\u7684\u7ed3\u679c\u5199\u5728\u6574\u4e2a\u683c\u5f0f\u5316\u5b57\u7b26\u4e32{}\u6240\u5728\u7684\u4f4d\u7f6e\u3002 \u53e6\u5916\uff0c\u6bcf\u4e2a\u7c7b\u90fd\u53ef\u4ee5\u901a\u8fc7__format__\u8fd9\u4e2a\u7279\u6b8a\u7684\u65b9\u6cd5\u5b9a\u5236\u76f8\u5e94\u7684\u903b\u8f91\uff0c\u8fd9\u6837\u7684\u8bdd\uff0cformat\u51fd\u6570\u5728\u628a\u8be5\u7c7b\u5b9e\u4f8b\u8f6c\u6362\u6210\u5b57\u7b26\u4e32\u65f6\uff0c\u5c31\u4f1a\u6309\u7167\u8fd9\u79cd\u903b\u8f91\u6765\u8f6c\u6362\u3002 \u8f6c\u4e49\u5904\u7406\uff1a >>> formatted = '%.2f%%' % 12.5 >>> formatted '12.50%' >>> formatted = '{} replace {{}}'.format(1.23) >>> formatted '1.23 replace {}' \u7136\u800c\uff0cstr.format\u65b9\u6cd5\u5e76\u6ca1\u6709\u89e3\u51b3\u4e0a\u9762\u8bb2\u7684\u7b2c\u4e8c\u4e2a\u7f3a\u70b9\u3002\u5982\u679c\u5728\u5bf9\u503c\u505a\u586b\u5145\u4e4b\u524d\u8981\u5148\u5bf9\u8fd9\u4e2a\u503c\u505a\u51fa\u8c03\u6574\uff0c\u90a3\u4e48\u7528\u8fd9\u79cd\u65b9\u6cd5\u5199\u51fa\u6765\u7684\u4ee3\u7801\u8fd8\u662f\u8ddf\u539f\u6765\u4e00\u6837\u4e71\uff0c\u9605\u8bfb\u6027\u5dee\u3002\u5bf9\u6bd4\u4e00\u4e0b\uff1a >>> pantry = [ ... ('avocados', 1.25), ... ('bananas', 2.5), ... ('cherries', 15) ... ] >>> for i, (item, count) in enumerate(pantry): ... before = '#%d: %-10s = %.2f' % ( ... i + 1, ... item.title(), ... round(count) ... ) ... after = '#%(loop)d: %(item)-10s = %(count).2f' % { ... 'loop': i + 1, ... 'item': item.title(), ... 'count': round(count) ... } ... new_style = '#{}: {:<10s} = {:.2f}'.format( ... i + 1, ... item.title(), ... round(count) ... ) ... assert before == after == new_style ... print(before) ... print(after) ... print(new_style) ... #1: Avocados = 1.00 #1: Avocados = 1.00 #1: Avocados = 1.00 #2: Bananas = 2.00 #2: Bananas = 2.00 #2: Bananas = 2.00 #3: Cherries = 15.00 #3: Cherries = 15.00 #3: Cherries = 15.00 \u63d2\u503c\u683c\u5f0f\u5b57\u7b26\u4e32f-string \u00b6 Python 3.6\u6dfb\u52a0\u4e86\u4e00\u79cd\u65b0\u7684\u7279\u6027\uff0c\u53eb\u4f5c\u63d2\u503c\u683c\u5f0f\u5b57\u7b26\u4e32\uff08interpolated format string\uff0c\u7b80\u79f0f-string\uff09\uff0c\u53ef\u4ee5\u89e3\u51b3\u4e0a\u9762\u63d0\u5230\u7684\u6240\u6709\u95ee\u9898\u3002 \u4e0b\u9762\u6309\u7167\u4ece\u77ed\u5230\u957f\u7684\u987a\u5e8f\u628a\u8fd9\u51e0\u79cd\u5199\u6cd5\u6240\u5360\u7684\u7bc7\u5e45\u5bf9\u6bd4\u4e00\u4e0b\uff0c\u8fd9\u6837\u5f88\u5bb9\u6613\u770b\u51fa\u7b26\u53f7\u53f3\u8fb9\u7684\u4ee3\u7801\u5230\u5e95\u6709\u591a\u5c11\u3002C\u98ce\u683c\u7684\u5199\u6cd5\u4e0e\u91c7\u7528str.format\u65b9\u6cd5\u7684\u5199\u6cd5\u53ef\u80fd\u4f1a\u8ba9\u8868\u8fbe\u5f0f\u53d8\u5f97\u5f88\u957f\uff0c\u4f46\u5982\u679c\u6539\u7528f-string\uff0c\u6216\u8bb8\u4e00\u884c\u5c31\u80fd\u5199\u5b8c\u3002 >>> key = 'my_var' >>> value = 1.234 >>> f_string = f'{key:<10} = {value:.2f}' >>> c_tuple = '%-10s = %.2f' % (key, value) >>> str_args = '{:<10} = {:.2f}'.format(key, value) >>> str_kw = '{key:<10} = {value:.2f}'.format(key=key, value=value) >>> c_dict = '%(key)-10s = %(value).2f' % {'key': key, 'value': value} >>> assert c_tuple == c_dict == f_string >>> assert str_args == str_kw == f_string >>> f_string 'my_var = 1.23' >>> c_tuple 'my_var = 1.23' >>> str_args 'my_var = 1.23' >>> str_kw 'my_var = 1.23' >>> c_dict 'my_var = 1.23' \u5bf9\u6bd4\u4e0b\u9762\uff0c\u628astr.format\u65b9\u6cd5\u7684\u5199\u6cd5\u6539\u7528f-string\uff0c\u4e00\u884c\u5c31\u80fd\u5199\u5b8c\u3002 >>> pantry = [ ... ('avocados', 1.25), ... ('bananas', 2.5), ... ('cherries', 15) ... ] >>> for i, (item, count) in enumerate(pantry): ... before = '#%d: %-10s = %.2f' % ( ... i + 1, ... item.title(), ... round(count) ... ) ... after = '#%(loop)d: %(item)-10s = %(count).2f' % { ... 'loop': i + 1, ... 'item': item.title(), ... 'count': round(count) ... } ... new_style = '#{}: {:<10s} = {:.2f}'.format( ... i + 1, ... item.title(), ... round(count) ... ) ... f_string = f'#{i+1}: {item.title():<10s} = {round(count):.2f}' ... assert before == after == new_style == f_string ... print(before) ... print(after) ... print(new_style) ... print(f_string) ... #1: Avocados = 1.00 #1: Avocados = 1.00 #1: Avocados = 1.00 #1: Avocados = 1.00 #2: Bananas = 2.00 #2: Bananas = 2.00 #2: Bananas = 2.00 #2: Bananas = 2.00 #3: Cherries = 15.00 #3: Cherries = 15.00 #3: Cherries = 15.00 #3: Cherries = 15.00 \u8981\u70b9\u603b\u7ed3\uff1a \u91c7\u7528%\u64cd\u4f5c\u7b26\u628a\u503c\u586b\u5145\u5230C\u98ce\u683c\u7684\u683c\u5f0f\u5b57\u7b26\u4e32\u65f6\u4f1a\u9047\u5230\u8bb8\u591a\u95ee\u9898\uff0c\u800c\u4e14\u8fd9\u79cd\u5199\u6cd5\u6bd4\u8f83\u70e6\u7410\u3002 str.format\u65b9\u6cd5\u4e13\u95e8\u7528\u4e00\u5957\u8ff7\u4f60\u8bed\u8a00\u6765\u5b9a\u4e49\u5b83\u7684\u683c\u5f0f\u8bf4\u660e\u7b26\uff0c\u8fd9\u5957\u8bed\u8a00\u7ed9\u6211\u4eec\u63d0\u4f9b\u4e86\u4e00\u4e9b\u6709\u7528\u7684\u6982\u5ff5\uff0c\u4f46\u662f\u5728\u5176\u4ed6\u65b9\u9762\uff0c\u8fd9\u4e2a\u65b9\u6cd5\u8fd8\u662f\u5b58\u5728\u4e0eC\u98ce\u683c\u7684\u683c\u5f0f\u5b57\u7b26\u4e32\u4e00\u6837\u7684\u591a\u79cd\u7f3a\u70b9\uff0c\u6240\u4ee5\u6211\u4eec\u4e5f\u5e94\u8be5\u907f\u514d\u4f7f\u7528\u5b83\u3002 f-string\u91c7\u7528\u65b0\u7684\u5199\u6cd5\uff0c\u5c06\u503c\u586b\u5145\u5230\u5b57\u7b26\u4e32\u4e4b\u4e2d\uff0c\u89e3\u51b3\u4e86C\u98ce\u683c\u7684\u683c\u5f0f\u5b57\u7b26\u4e32\u6240\u5e26\u6765\u7684\u6700\u5927\u95ee\u9898\u3002 f-string\u662f\u4e2a\u7b80\u6d01\u800c\u5f3a\u5927\u7684\u673a\u5236\uff0c\u53ef\u4ee5\u76f4\u63a5\u5728\u683c\u5f0f\u8bf4\u660e\u7b26\u91cc\u5d4c\u5165\u4efb\u610fPython\u8868\u8fbe\u5f0f\u3002","title":"\u7b2c04\u6761 \u7528\u652f\u6301\u63d2\u503c\u7684f-string\u53d6\u4ee3C\u98ce\u683c\u7684\u683c\u5f0f\u5b57\u7b26\u4e32\u4e0estr.format\u65b9\u6cd5"},{"location":"python/Pythonic90Rules/Rule04/#4-f-stringcstrformat","text":"\u683c\u5f0f\u5316\uff08formatting\uff09\u662f\u6307\u628a\u6570\u636e\u586b\u5199\u5230\u9884\u5148\u5b9a\u4e49\u7684\u6587\u672c\u6a21\u677f\u91cc\u9762\uff0c\u5f62\u6210\u4e00\u6761\u7528\u6237\u53ef\u8bfb\u7684\u6d88\u606f\uff0c\u5e76\u628a\u8fd9\u6761\u6d88\u606f\u4fdd\u5b58\u6210\u5b57\u7b26\u4e32\u7684\u8fc7\u7a0b\u3002 \u7528Python\u5bf9\u5b57\u7b26\u4e32\u505a\u683c\u5f0f\u5316\u5904\u7406\u6709\u56db\u79cd\u529e\u6cd5\u53ef\u4ee5\u8003\u8651\uff0c\u8fd9\u4e9b\u529e\u6cd5\u90fd\u5185\u7f6e\u5728\u8bed\u8a00\u548c\u6807\u51c6\u5e93\u91cc\u9762\u3002 \u4f46\u5176\u4e2d\u4e09\u79cd\u529e\u6cd5\u6709\u4e25\u91cd\u7684\u7f3a\u9677\uff0c\u73b0\u5728\u5148\u89e3\u91ca\u4e3a\u4ec0\u4e48\u4e0d\u8981\u4f7f\u7528\u8fd9\u4e09\u79cd\u529e\u6cd5\uff0c\u6700\u540e\u518d\u7ed9\u51fa\u5269\u4e0b\u7684\u90a3\u4e00\u79cd\u3002 Python\u91cc\u9762\u6700\u5e38\u7528\u7684\u5b57\u7b26\u4e32\u683c\u5f0f\u5316\u65b9\u5f0f\u662f\u91c7\u7528%\u683c\u5f0f\u5316\u64cd\u4f5c\u7b26(C\u98ce\u683c\u7684\u683c\u5f0f\u5b57\u7b26\u4e32)\u3002 \u8fd9\u4e2a\u64cd\u4f5c\u7b26\u5de6\u8fb9\u7684\u6587\u672c\u6a21\u677f\u53eb\u4f5c\u683c\u5f0f\u5b57\u7b26\u4e32\uff08format string\uff09\uff0c\u6211\u4eec\u53ef\u4ee5\u5728\u64cd\u4f5c\u7b26\u53f3\u8fb9\u5199\u4e0a\u67d0\u4e2a\u503c\u6216\u8005\u7531\u591a\u4e2a\u503c\u6240\u6784\u6210\u7684\u5143\u7ec4\uff08tuple\uff09\uff0c\u7528\u6765\u66ff\u6362\u683c\u5f0f\u5b57\u7b26\u4e32\u91cc\u7684\u76f8\u5173\u7b26\u53f7\u3002 python\u5b57\u7b26\u4e32\u683c\u5f0f\u5316\u7b26\u53f7\uff1a %c\uff1a\u5b57\u7b26\u53ca\u5176ASCII\u7801 %s\uff1a\u5b57\u7b26\u4e32 %d\uff1a\u6574\u6570 %u\uff1a\u65e0\u7b26\u53f7\u6574\u578b %o\uff1a\u65e0\u7b26\u53f7\u516b\u8fdb\u5236\u6570 %x\uff1a\u65e0\u7b26\u53f7\u5341\u516d\u8fdb\u5236\u6570 %X\uff1a\u65e0\u7b26\u53f7\u5341\u516d\u8fdb\u5236\u6570\uff08\u5927\u5199\uff09 %f\uff1a\u6d6e\u70b9\u6570\u5b57\uff0c\u53ef\u6307\u5b9a\u5c0f\u6570\u70b9\u540e\u7684\u7cbe\u5ea6 %e\uff1a\u7528\u79d1\u5b66\u8ba1\u6570\u6cd5\u683c\u5f0f\u5316\u6d6e\u70b9\u6570 %E\uff1a\u4f5c\u7528\u540c%e\uff0c\u7528\u79d1\u5b66\u8ba1\u6570\u6cd5\u683c\u5f0f\u5316\u6d6e\u70b9\u6570 %g\uff1a%f\u548c%e\u7684\u7b80\u5199 %G\uff1a%f \u548c %E \u7684\u7b80\u5199 %p\uff1a\u7528\u5341\u516d\u8fdb\u5236\u6570\u683c\u5f0f\u5316\u53d8\u91cf\u7684\u5730\u5740 a = 128 b = 3.1415926 print('Binary is %d, Hex is %X, Oct is %o, Float is %e' % (a, a, a, b)) >>> Binary is 128, Hex is 80, Oct is 200, Float is 3.141593e+00 C\u98ce\u683c\u7684\u683c\u5f0f\u5b57\u7b26\u4e32\uff0c\u5728Python\u91cc\u6709\u56db\u4e2a\u7f3a\u70b9\u3002 \u7b2c\u4e00\u4e2a\u7f3a\u70b9\u662f\uff0c\u5982\u679c%\u53f3\u4fa7\u90a3\u4e2a\u5143\u7ec4\u91cc\u9762\u7684\u503c\u5728\u7c7b\u578b\u6216\u987a\u5e8f\u4e0a\u6709\u53d8\u5316\uff0c\u90a3\u4e48\u7a0b\u5e8f\u53ef\u80fd\u4f1a\u56e0\u4e3a\u8f6c\u6362\u7c7b\u578b\u65f6\u53d1\u751f\u4e0d\u517c\u5bb9\u95ee\u9898\u800c\u51fa\u73b0\u9519\u8bef\u3002 >>> key = 'my_var' >>> value = 1.234 >>> formatted = '%-10s = %.2f' % (key, value) # %-10s\u4ee3\u8868=\u5de6\u8fb9\u5b57\u4e32\u603b\u957f\u5ea610,\u4e0d\u8db3\u90e8\u5206\u5728\u5c3e\u90e8\u6dfb\u52a0\u7a7a\u683c >>> formatted 'my_var = 1.23' >>> \u5982\u679c\u628akey\u8ddfvalue\u4e92\u6362\u4f4d\u7f6e\uff0c\u6216\u8005\u5de6\u4fa7\u90a3\u4e2a\u683c\u5f0f\u5b57\u7b26\u4e32\u91cc\u9762\u7684\u4e24\u4e2a\u8bf4\u660e\u7b26\u5bf9\u8c03\u4e86\u987a\u5e8f\uff0c\u90a3\u4e48\u7a0b\u5e8f\u5c31\u4f1a\u5728\u8fd0\u884c\u65f6\u51fa\u73b0\u5f02\u5e38\u3002 >>> key = 'my_var' >>> value = 1.234 >>> formatted = '%-10s = %.2f' % (value, key) Traceback (most recent call last): File \"\", line 1, in TypeError: must be real number, not str >>> key = 'my_var' >>> value = 1.234 >>> formatted = '%.2f = %-10s' % (key, value) Traceback (most recent call last): File \"\", line 1, in TypeError: must be real number, not str \u7b2c\u4e8c\u4e2a\u7f3a\u70b9\u662f\uff0c\u5728\u586b\u5145\u6a21\u677f\u4e4b\u524d\uff0c\u7ecf\u5e38\u8981\u5148\u5bf9\u51c6\u5907\u586b\u5199\u8fdb\u53bb\u7684\u8fd9\u4e2a\u503c\u7a0d\u5fae\u505a\u4e00\u4e9b\u5904\u7406\uff0c\u4f46\u8fd9\u6837\u4e00\u6765\uff0c\u6574\u4e2a\u8868\u8fbe\u5f0f\u53ef\u80fd\u5c31\u4f1a\u5199\u5f97\u5f88\u957f\uff0c\u5f71\u54cd\u7a0b\u5e8f\u7684\u53ef\u8bfb\u6027\u3002 >>> pantry = [ ... ('avocados', 1.25), ... ('bananas', 2.5), ... ('cherries', 15) ... ] >>> for i, (item, count) in enumerate(pantry): ... print( ... '#%d: %-10s = %.2f' % ( ... i + 1, ... item.title(), ... round(count) ... ) ... ) ... #1: Avocados = 1.00 #2: Bananas = 2.00 #3: Cherries = 15.00 \u7b2c\u4e09\u4e2a\u7f3a\u70b9\u662f\uff0c\u5982\u679c\u60f3\u7528\u540c\u4e00\u4e2a\u503c\u6765\u586b\u5145\u683c\u5f0f\u5b57\u7b26\u4e32\u91cc\u7684\u591a\u4e2a\u4f4d\u7f6e\uff0c\u90a3\u4e48\u5fc5\u987b\u5728%\u64cd\u4f5c\u7b26\u53f3\u4fa7\u7684\u5143\u7ec4\u4e2d\u76f8\u5e94\u5730\u591a\u6b21\u91cd\u590d\u8be5\u503c\u3002 >>> template = '%s loves food. See %s cook.' >>> name = 'Max' >>> formatted = template % (name, name) >>> formatted 'Max loves food. See Max cook.' \u4e3a\u4e86\u89e3\u51b3\u4e0a\u9762\u63d0\u5230\u7684\u4e00\u4e9b\u95ee\u9898\uff0cPython\u7684%\u64cd\u4f5c\u7b26\u5141\u8bb8\u6211\u4eec\u7528dict\u53d6\u4ee3tuple\uff0c\u89e3\u51b3\u4e86%\u64cd\u4f5c\u7b26\u4e24\u4fa7\u7684\u987a\u5e8f\u4e0d\u5339\u914d\u95ee\u9898\u3002 >>> key = 'my_var' >>> value = 1.234 >>> old_way = '%-10s = %.2f' % (key, value) >>> new_way = '%(key)-10s = %(value).2f' % {'key': key, 'value': value} # \u5bf9\u5e94 >>> reordered = '%(key)-10s = %(value).2f' % {'value': value, 'key': key} # \u4e92\u6362 >>> assert old_way == new_way == reordered >>> old_way 'my_var = 1.23' >>> new_way 'my_var = 1.23' >>> reordered 'my_var = 1.23' \u7528dict\u53d6\u4ee3tuple\uff0c\u4e5f\u89e3\u51b3\u7528\u540c\u4e00\u4e2a\u503c\u66ff\u6362\u591a\u4e2a\u683c\u5f0f\u8bf4\u660e\u7b26\u7684\u95ee\u9898\uff0c\u6211\u4eec\u5c31\u4e0d\u7528\u5728%\u64cd\u4f5c\u7b26\u53f3\u4fa7\u91cd\u590d\u8fd9\u4e2a\u503c\u4e86\u3002 >>> name = 'Max' >>> template = '%s loves food. See %s cook.' >>> before = template % (name, name) >>> template = '%(name)s loves food. See %(name)s cook.' >>> after = template % {'name': name} >>> assert before == after >>> before 'Max loves food. See Max cook.' >>> after 'Max loves food. See Max cook.' \u4f46\u662f\uff0c\u8fd9\u79cd\u5199\u6cd5\u4f1a\u8ba9\u7b2c\u4e8c\u4e2a\u7f3a\u70b9\u53d8\u5f97\u66f4\u52a0\u4e25\u91cd\uff0c\u683c\u5f0f\u5316\u8868\u8fbe\u5f0f\u53d8\u5f97\u66f4\u52a0\u5197\u957f\uff0c\u770b\u8d77\u6765\u4e5f\u66f4\u52a0\u6df7\u4e71\u3002\u5982\u4e0b\u4f8b\uff1a >>> pantry = [ ... ('avocados', 1.25), ... ('bananas', 2.5), ... ('cherries', 15) ... ] >>> for i, (item, count) in enumerate(pantry): ... before = '#%d: %-10s = %.2f' % ( ... i + 1, ... item.title(), ... round(count) ... ) ... after = '#%(loop)d: %(item)-10s = %(count).2f' % { ... 'loop': i + 1, ... 'item': item.title(), ... 'count': round(count) ... } ... assert before == after ... print(before) ... print(after) ... #1: Avocados = 1.00 #1: Avocados = 1.00 #2: Bananas = 2.00 #2: Bananas = 2.00 #3: Cherries = 15.00 #3: Cherries = 15.00 \u6240\u4ee5\uff0c\u7b2c\u56db\u4e2a\u7f3a\u70b9\u662f\uff0c\u628adict\u5199\u5230\u683c\u5f0f\u5316\u8868\u8fbe\u5f0f\u91cc\u9762\u4f1a\u8ba9\u4ee3\u7801\u53d8\u591a\uff0c\u6bcf\u4e2a\u952e\u90fd\u81f3\u5c11\u8981\u5199\u4e24\u6b21\u3002\u4e3a\u4e86\u67e5\u770b\u683c\u5f0f\u5b57\u7b26\u4e32\u4e2d\u7684\u8bf4\u660e\u7b26\u7a76\u7adf\u5bf9\u5e94\u4e8e\u5b57\u5178\u91cc\u7684\u54ea\u4e2a\u952e\uff0c\u5fc5\u987b\u5728\u8fd9\u4e24\u6bb5\u4ee3\u7801\u4e4b\u95f4\u6765\u56de\u8df3\u8dc3\u3002\u5982\u679c\u8981\u5bf9\u952e\u540d\u7a0d\u505a\u4fee\u6539\uff0c\u90a3\u4e48\u5fc5\u987b\u540c\u6b65\u4fee\u6539\u683c\u5f0f\u5b57\u7b26\u4e32\u91cc\u7684\u8bf4\u660e\u7b26\uff0c\u8fd9\u66f4\u8ba9\u4ee3\u7801\u53d8\u5f97\u76f8\u5f53\u70e6\u7410\uff0c\u53ef\u8bfb\u6027\u66f4\u5dee\u3002","title":"\u7b2c4\u6761\u3000\u7528\u652f\u6301\u63d2\u503c\u7684f-string\u53d6\u4ee3C\u98ce\u683c\u7684\u683c\u5f0f\u5b57\u7b26\u4e32\u4e0estr.format\u65b9\u6cd5"},{"location":"python/Pythonic90Rules/Rule04/#formatstrformat","text":"Python 3\u6dfb\u52a0\u4e86\u9ad8\u7ea7\u5b57\u7b26\u4e32\u683c\u5f0f\u5316\uff08advanced stringformatting\uff09\u673a\u5236\uff0c\u5b83\u7684\u8868\u8fbe\u80fd\u529b\u6bd4\u8001\u5f0fC\u98ce\u683c\u7684\u683c\u5f0f\u5b57\u7b26\u4e32\u8981\u5f3a\uff0c\u4e14\u4e0d\u518d\u4f7f\u7528%\u64cd\u4f5c\u7b26\u3002 \u4e0b\u9762\u8fd9\u6bb5\u4ee3\u7801\uff0c\u6f14\u793a\u4e86\u8fd9\u79cd\u65b0\u7684\u683c\u5f0f\u5316\u65b9\u5f0f\u3002\u5728\u4f20\u7ed9format\u51fd\u6570\u7684\u683c\u5f0f\u91cc\u9762\uff0c\u9017\u53f7\u8868\u793a\u663e\u793a\u5343\u4f4d\u5206\u9694\u7b26\uff0c^\u8868\u793a\u5c45\u4e2d\u5bf9\u9f50\u3002 >>> a = 1234.5678 >>> formatted = format(a, ',.2f') >>> formatted '1,234.57' >>> b = 'my string' >>> formatted = format(b, '^20s') >>> formatted ' my string ' \u5982\u679cstr\u7c7b\u578b\u7684\u5b57\u7b26\u4e32\u91cc\u9762\u6709\u8bb8\u591a\u503c\u90fd\u9700\u8981\u8c03\u6574\u683c\u5f0f\uff0c\u5219\u53ef\u4ee5\u628a\u683c\u5f0f\u6709\u5f85\u8c03\u6574\u7684\u90a3\u4e9b\u4f4d\u7f6e\u5728\u5b57\u7b26\u4e32\u91cc\u9762\u5148\u7528{}\u4ee3\u66ff\uff0c\u7136\u540e\u6309\u4ece\u5de6\u5230\u53f3\u7684\u987a\u5e8f\uff0c\u628a\u9700\u8981\u586b\u5199\u5230\u90a3\u4e9b\u4f4d\u7f6e\u7684\u503c\u4f20\u7ed9format\u65b9\u6cd5\uff0c\u4f7f\u8fd9\u4e9b\u503c\u4f9d\u6b21\u51fa\u73b0\u5728\u5b57\u7b26\u4e32\u4e2d\u7684\u76f8\u5e94\u4f4d\u7f6e\u3002 >>> key = 'my_var' >>> value = 1.234 >>> formatted = '{} = {}'.format(key, value) >>> formatted 'my_var = 1.234' >>> formatted = '{} = {}'.format(value, key) >>> formatted '1.234 = my_var' \u901a\u8fc7\u5728{}\u91cc\u5199\u4e2a\u5192\u53f7\uff0c\u7136\u540e\u628a\u683c\u5f0f\u8bf4\u660e\u7b26\u5199\u5728\u5192\u53f7\u7684\u53f3\u8fb9\uff0c\u6765\u6dfb\u52a0\u683c\u5f0f\u3002\uff08\u6dfb\u52a0\u683c\u5f0f\u540e\uff0c\u4e92\u6362\u4f1a\u62a5\u9519\uff09 >>> formatted = '{:<10} = {:.2f}'.format(key, value) >>> formatted 'my_var = 1.23' >>> formatted = '{:<10} = {:.2f}'.format(value, key) Traceback (most recent call last): File \"\", line 1, in ValueError: Unknown format code 'f' for object of type 'str' \u4e5f\u53ef\u4ee5\u7ed9str\u7684{}\u91cc\u9762\u5199\u4e0a\u6570\u5b57\uff0c\u7528\u6765\u6307\u4ee3format\u65b9\u6cd5\u5728\u8fd9\u4e2a\u4f4d\u7f6e\u6240\u63a5\u6536\u5230\u7684\u53c2\u6570\u503c\u4f4d\u7f6e\u7d22\u5f15\u3002 \u4ee5\u540e\u5373\u4f7f\u8fd9\u4e9b{}\u5728\u683c\u5f0f\u5b57\u7b26\u4e32\u4e2d\u7684\u6b21\u5e8f\u6709\u6240\u53d8\u52a8\uff0c\u4e5f\u4e0d\u7528\u8c03\u6362\u4f20\u7ed9format\u65b9\u6cd5\u7684\u90a3\u4e9b\u53c2\u6570\u3002\u4e8e\u662f\uff0c\u8fd9\u5c31\u907f\u514d\u4e86\u524d\u9762\u8bb2\u7684\u7b2c\u4e00\u4e2a\u7f3a\u70b9\u6240\u63d0\u5230\u7684\u90a3\u4e2a\u987a\u5e8f\u95ee\u9898\u3002 >>> key = 'my_var' >>> value = 1.234 >>> formatted = '{} = {}'.format(key, value) >>> formatted 'my_var = 1.234' >>> formatted = '{1} = {0}'.format(key, value) >>> formatted '1.234 = my_var' >>> formatted = '{2} = {1}'.format(key, value) Traceback (most recent call last): File \"\", line 1, in IndexError: Replacement index 2 out of range for positional args tuple \u540c\u4e00\u4e2a\u4f4d\u7f6e\u7d22\u5f15\u53ef\u4ee5\u51fa\u73b0\u5728str\u7684\u591a\u4e2a{}\u91cc\u9762\uff0c\u8fd9\u5c31\u4e0d\u9700\u8981\u628a\u8fd9\u4e2a\u503c\u91cd\u590d\u5730\u4f20\u7ed9format\u65b9\u6cd5\uff0c\u4e8e\u662f\u5c31\u89e3\u51b3\u4e86\u524d\u9762\u63d0\u5230\u7684\u7b2c\u4e09\u4e2a\u7f3a\u70b9\u3002 >>> name = 'Max' >>> formatted = '%s loves food. See %s cook.' % (name, name) >>> formatted 'Max loves food. See Max cook.' >>> formatted = '%(name)s loves food. See %(name)s cook.' % {'name': name} >>> formatted 'Max loves food. See Max cook.' >>> formatted = '{0} loves food. See {0} cook.'.format(name) >>> formatted 'Max loves food. See Max cook.' \u4e0a\u8ff0\u529f\u80fd\u5206\u6790\uff1a \u7cfb\u7edf\u5148\u628astr.format\u65b9\u6cd5\u63a5\u6536\u5230\u7684\u6bcf\u4e2a\u503c\u4f20\u7ed9\u5185\u7f6e\u7684format\u51fd\u6570\uff0c\u5e76\u627e\u5230\u8fd9\u4e2a\u503c\u5728\u5b57\u7b26\u4e32\u91cc\u5bf9\u5e94\u7684{}\uff0c\u540c\u65f6\u5c06{}\u91cc\u9762\u5199\u7684\u683c\u5f0f\u4e5f\u4f20\u7ed9format\u51fd\u6570\uff0c\u4f8b\u5982\u7cfb\u7edf\u5728\u5904\u7406value\u7684\u65f6\u5019\uff0c\u4f20\u7684\u5c31\u662fformat(value,'.2f')\u3002 \u7136\u540e\uff0c\u7cfb\u7edf\u4f1a\u628aformat\u51fd\u6570\u6240\u8fd4\u56de\u7684\u7ed3\u679c\u5199\u5728\u6574\u4e2a\u683c\u5f0f\u5316\u5b57\u7b26\u4e32{}\u6240\u5728\u7684\u4f4d\u7f6e\u3002 \u53e6\u5916\uff0c\u6bcf\u4e2a\u7c7b\u90fd\u53ef\u4ee5\u901a\u8fc7__format__\u8fd9\u4e2a\u7279\u6b8a\u7684\u65b9\u6cd5\u5b9a\u5236\u76f8\u5e94\u7684\u903b\u8f91\uff0c\u8fd9\u6837\u7684\u8bdd\uff0cformat\u51fd\u6570\u5728\u628a\u8be5\u7c7b\u5b9e\u4f8b\u8f6c\u6362\u6210\u5b57\u7b26\u4e32\u65f6\uff0c\u5c31\u4f1a\u6309\u7167\u8fd9\u79cd\u903b\u8f91\u6765\u8f6c\u6362\u3002 \u8f6c\u4e49\u5904\u7406\uff1a >>> formatted = '%.2f%%' % 12.5 >>> formatted '12.50%' >>> formatted = '{} replace {{}}'.format(1.23) >>> formatted '1.23 replace {}' \u7136\u800c\uff0cstr.format\u65b9\u6cd5\u5e76\u6ca1\u6709\u89e3\u51b3\u4e0a\u9762\u8bb2\u7684\u7b2c\u4e8c\u4e2a\u7f3a\u70b9\u3002\u5982\u679c\u5728\u5bf9\u503c\u505a\u586b\u5145\u4e4b\u524d\u8981\u5148\u5bf9\u8fd9\u4e2a\u503c\u505a\u51fa\u8c03\u6574\uff0c\u90a3\u4e48\u7528\u8fd9\u79cd\u65b9\u6cd5\u5199\u51fa\u6765\u7684\u4ee3\u7801\u8fd8\u662f\u8ddf\u539f\u6765\u4e00\u6837\u4e71\uff0c\u9605\u8bfb\u6027\u5dee\u3002\u5bf9\u6bd4\u4e00\u4e0b\uff1a >>> pantry = [ ... ('avocados', 1.25), ... ('bananas', 2.5), ... ('cherries', 15) ... ] >>> for i, (item, count) in enumerate(pantry): ... before = '#%d: %-10s = %.2f' % ( ... i + 1, ... item.title(), ... round(count) ... ) ... after = '#%(loop)d: %(item)-10s = %(count).2f' % { ... 'loop': i + 1, ... 'item': item.title(), ... 'count': round(count) ... } ... new_style = '#{}: {:<10s} = {:.2f}'.format( ... i + 1, ... item.title(), ... round(count) ... ) ... assert before == after == new_style ... print(before) ... print(after) ... print(new_style) ... #1: Avocados = 1.00 #1: Avocados = 1.00 #1: Avocados = 1.00 #2: Bananas = 2.00 #2: Bananas = 2.00 #2: Bananas = 2.00 #3: Cherries = 15.00 #3: Cherries = 15.00 #3: Cherries = 15.00","title":"\u5185\u7f6e\u7684format\u51fd\u6570\u4e0estr\u7c7b\u7684format\u65b9\u6cd5"},{"location":"python/Pythonic90Rules/Rule04/#f-string","text":"Python 3.6\u6dfb\u52a0\u4e86\u4e00\u79cd\u65b0\u7684\u7279\u6027\uff0c\u53eb\u4f5c\u63d2\u503c\u683c\u5f0f\u5b57\u7b26\u4e32\uff08interpolated format string\uff0c\u7b80\u79f0f-string\uff09\uff0c\u53ef\u4ee5\u89e3\u51b3\u4e0a\u9762\u63d0\u5230\u7684\u6240\u6709\u95ee\u9898\u3002 \u4e0b\u9762\u6309\u7167\u4ece\u77ed\u5230\u957f\u7684\u987a\u5e8f\u628a\u8fd9\u51e0\u79cd\u5199\u6cd5\u6240\u5360\u7684\u7bc7\u5e45\u5bf9\u6bd4\u4e00\u4e0b\uff0c\u8fd9\u6837\u5f88\u5bb9\u6613\u770b\u51fa\u7b26\u53f7\u53f3\u8fb9\u7684\u4ee3\u7801\u5230\u5e95\u6709\u591a\u5c11\u3002C\u98ce\u683c\u7684\u5199\u6cd5\u4e0e\u91c7\u7528str.format\u65b9\u6cd5\u7684\u5199\u6cd5\u53ef\u80fd\u4f1a\u8ba9\u8868\u8fbe\u5f0f\u53d8\u5f97\u5f88\u957f\uff0c\u4f46\u5982\u679c\u6539\u7528f-string\uff0c\u6216\u8bb8\u4e00\u884c\u5c31\u80fd\u5199\u5b8c\u3002 >>> key = 'my_var' >>> value = 1.234 >>> f_string = f'{key:<10} = {value:.2f}' >>> c_tuple = '%-10s = %.2f' % (key, value) >>> str_args = '{:<10} = {:.2f}'.format(key, value) >>> str_kw = '{key:<10} = {value:.2f}'.format(key=key, value=value) >>> c_dict = '%(key)-10s = %(value).2f' % {'key': key, 'value': value} >>> assert c_tuple == c_dict == f_string >>> assert str_args == str_kw == f_string >>> f_string 'my_var = 1.23' >>> c_tuple 'my_var = 1.23' >>> str_args 'my_var = 1.23' >>> str_kw 'my_var = 1.23' >>> c_dict 'my_var = 1.23' \u5bf9\u6bd4\u4e0b\u9762\uff0c\u628astr.format\u65b9\u6cd5\u7684\u5199\u6cd5\u6539\u7528f-string\uff0c\u4e00\u884c\u5c31\u80fd\u5199\u5b8c\u3002 >>> pantry = [ ... ('avocados', 1.25), ... ('bananas', 2.5), ... ('cherries', 15) ... ] >>> for i, (item, count) in enumerate(pantry): ... before = '#%d: %-10s = %.2f' % ( ... i + 1, ... item.title(), ... round(count) ... ) ... after = '#%(loop)d: %(item)-10s = %(count).2f' % { ... 'loop': i + 1, ... 'item': item.title(), ... 'count': round(count) ... } ... new_style = '#{}: {:<10s} = {:.2f}'.format( ... i + 1, ... item.title(), ... round(count) ... ) ... f_string = f'#{i+1}: {item.title():<10s} = {round(count):.2f}' ... assert before == after == new_style == f_string ... print(before) ... print(after) ... print(new_style) ... print(f_string) ... #1: Avocados = 1.00 #1: Avocados = 1.00 #1: Avocados = 1.00 #1: Avocados = 1.00 #2: Bananas = 2.00 #2: Bananas = 2.00 #2: Bananas = 2.00 #2: Bananas = 2.00 #3: Cherries = 15.00 #3: Cherries = 15.00 #3: Cherries = 15.00 #3: Cherries = 15.00 \u8981\u70b9\u603b\u7ed3\uff1a \u91c7\u7528%\u64cd\u4f5c\u7b26\u628a\u503c\u586b\u5145\u5230C\u98ce\u683c\u7684\u683c\u5f0f\u5b57\u7b26\u4e32\u65f6\u4f1a\u9047\u5230\u8bb8\u591a\u95ee\u9898\uff0c\u800c\u4e14\u8fd9\u79cd\u5199\u6cd5\u6bd4\u8f83\u70e6\u7410\u3002 str.format\u65b9\u6cd5\u4e13\u95e8\u7528\u4e00\u5957\u8ff7\u4f60\u8bed\u8a00\u6765\u5b9a\u4e49\u5b83\u7684\u683c\u5f0f\u8bf4\u660e\u7b26\uff0c\u8fd9\u5957\u8bed\u8a00\u7ed9\u6211\u4eec\u63d0\u4f9b\u4e86\u4e00\u4e9b\u6709\u7528\u7684\u6982\u5ff5\uff0c\u4f46\u662f\u5728\u5176\u4ed6\u65b9\u9762\uff0c\u8fd9\u4e2a\u65b9\u6cd5\u8fd8\u662f\u5b58\u5728\u4e0eC\u98ce\u683c\u7684\u683c\u5f0f\u5b57\u7b26\u4e32\u4e00\u6837\u7684\u591a\u79cd\u7f3a\u70b9\uff0c\u6240\u4ee5\u6211\u4eec\u4e5f\u5e94\u8be5\u907f\u514d\u4f7f\u7528\u5b83\u3002 f-string\u91c7\u7528\u65b0\u7684\u5199\u6cd5\uff0c\u5c06\u503c\u586b\u5145\u5230\u5b57\u7b26\u4e32\u4e4b\u4e2d\uff0c\u89e3\u51b3\u4e86C\u98ce\u683c\u7684\u683c\u5f0f\u5b57\u7b26\u4e32\u6240\u5e26\u6765\u7684\u6700\u5927\u95ee\u9898\u3002 f-string\u662f\u4e2a\u7b80\u6d01\u800c\u5f3a\u5927\u7684\u673a\u5236\uff0c\u53ef\u4ee5\u76f4\u63a5\u5728\u683c\u5f0f\u8bf4\u660e\u7b26\u91cc\u5d4c\u5165\u4efb\u610fPython\u8868\u8fbe\u5f0f\u3002","title":"\u63d2\u503c\u683c\u5f0f\u5b57\u7b26\u4e32f-string"},{"location":"python/Pythonic90Rules/Rule05/","text":"\u7b2c5\u6761\u3000\u7528\u8f85\u52a9\u51fd\u6570\u53d6\u4ee3\u590d\u6742\u7684\u8868\u8fbe\u5f0f \u00b6 Python\u7684\u8bed\u6cd5\u76f8\u5f53\u7b80\u660e\uff0c\u6240\u4ee5\u6709\u65f6\u53ea\u7528\u4e00\u6761\u8868\u8fbe\u5f0f\u5c31\u80fd\u5b9e\u73b0\u8bb8\u591a\u903b\u8f91\u3002 \u4f8b\u5982\uff0c\u8981\u628aURL\u4e4b\u4e2d\u7684\u67e5\u8be2\u5b57\u7b26\u4e32\u62c6\u5206\u6210\u952e\u503c\u5bf9\uff0c\u90a3\u4e48\u53ea\u9700\u8981\u4f7f\u7528parse_qs\u51fd\u6570\u5c31\u53ef\u4ee5\u4e86\u3002 >>> from urllib.parse import parse_qs >>> my_value = parse_qs('red=5&blue=0&green=', keep_blank_values=True) >>> my_value {'red': ['5'], 'blue': ['0'], 'green': ['']} \u5728\u89e3\u6790\u67e5\u8be2\u5b57\u7b26\u4e32\u65f6\uff0c\u53ef\u4ee5\u53d1\u73b0\uff0c\u6709\u7684\u53c2\u6570\u53ef\u80fd\u5e26\u6709\u591a\u4e2a\u503c\uff0c\u6709\u7684\u53c2\u6570\u53ef\u80fd\u53ea\u6709\u4e00\u4e2a\u503c\uff0c\u8fd8\u6709\u7684\u53c2\u6570\u53ef\u80fd\u662f\u7a7a\u767d\u503c\uff0c\u53e6\u5916\u4e5f\u4f1a\u9047\u5230\u6839\u672c\u6ca1\u63d0\u4f9b\u8fd9\u4e2a\u53c2\u6570\u7684\u60c5\u51b5\u3002 \u4e0b\u9762\u8fd9\u4e09\u884c\u4ee3\u7801\u5206\u522b\u901a\u8fc7get\u65b9\u6cd5\u67e5\u8be2\u7ed3\u679c\u5b57\u5178\u91cc\u9762\u7684\u4e09\u4e2a\u53c2\u6570\uff0c\u8fd9\u521a\u597d\u5bf9\u5e94\u4e09\u79cd\u4e0d\u540c\u7684\u60c5\u51b5\uff1a >>> red = my_value.get('red') >>> green = my_value.get('green') >>> opacity = my_value.get('Opacity') >>> print('Red ', red) Red ['5'] >>> print('Green ', green) Green [''] >>> print('Opacity ', opacity) Opacity None \u901a\u8fc7Boolean\u8868\u8fbe\u5f0f\u6765\u5b9e\u73b0\u628a\u4e0a\u8ff0\u53c2\u6570\u7f3a\u5931\u4e0e\u53c2\u6570\u4e3a\u7a7a\u8fd9\u4e24\u79cd\u60c5\u51b5\u9ed8\u8ba4\u503c\u90fd\u8bbe\u62100\u3002Boolean\u8868\u8fbe\u5f0f\u4f1a\u628a\u7a7a\u767d\u5b57\u7b26\u4e32\u3001\u7a7a\u767dlist\u4ee5\u53ca0\u503c\uff0c\u5168\u90fd\u5f53\u6210False\u770b\u5f85\u3002 >>> red = my_value.get('red', [''])[0] or 0 >>> green = my_value.get('green', [''])[0] or 0 >>> opacity = my_value.get('Opacity', [''])[0] or 0 >>> print(f'Red : {red!r}') Red : '5' >>> print(f'Green : {green!r}') Green : 0 >>> print(f'Opacity : {opacity!r}') Opacity : 0 \u4e0a\u8ff0\u4ee3\u7801\u89e3\u6790\uff1a \u56e0\u4e3ared\u952e\u5b58\u5728\u4e8emy_value\u5b57\u5178\uff08dict\uff09\u91cc\u9762\uff0c\u5b83\u5bf9\u5e94\u7684\u503c\u662f\u4e2a\u53ea\u6709\u4e00\u4e2a\u5143\u7d20\u7684\u5217\u8868 ['5'] \uff0c\u8fd9\u4e2a\u5143\u7d20\u662f\u5b57\u7b26\u4e32'5'\u3002Python\u4f1a\u628a\u5b57\u7b26\u4e32'5' \u89e3\u6790\u4e3aTrue\uff0c\u6240\u4ee5\u6574\u4e2a\u8868\u8fbe\u5f0f\u7684\u503c\u5c31\u7b49\u4e8eor\u5de6\u4fa7\u90a3\u4e2a\u5b50\u8868\u8fbe\u5f0f\u7684\u503c\uff0c\u5373 my_values.get('red', [''])[0] \u3002 \u5bf9\u4e8egreen\uff0c\u8fd9\u4e2a\u952e\u503c\u4e5f\u5b58\u5728\u4e8emy_value\u5b57\u5178\uff08dict\uff09\u91cc\u9762\uff0c\u5b83\u5bf9\u5e94\u7684\u503c\u662f\u4e2a\u53ea\u6709\u4e00\u4e2a\u5143\u7d20\u7684\u5217\u8868 [''] \uff0c\u8fd9\u4e2a\u5143\u7d20\u662f\u7a7a\u767d\u5b57\u7b26\u4e32\u3002Python\u4f1a\u628a\u7a7a\u767d\u5b57\u7b26\u4e32\u89e3\u6790\u4e3aFalse\uff0c\u6240\u4ee5green\u53d8\u91cf\u7684\u503c\u5c31\u7b49\u4e8eor\u53f3\u4fa7\u90a3\u4e2a\u5b50\u8868\u8fbe\u5f0f\u7684\u503c\uff0c\u4e5f\u5c31\u662f0\u3002 \u5bf9\u4e8eopacity\uff0c\u8fd9\u4e2a\u952e\u503c\u4e0d\u5b58\u5728\u4e8emy_value\u5b57\u5178\uff08dict\uff09\u91cc\u9762\uff0cget\u65b9\u6cd5\u4f1a\u8fd4\u56de\u4f20\u9012\u7ed9\u5b83\u7684\u7b2c\u4e8c\u4e2a\u503c [''] \uff0c\u548cgreen\u7684\u60c5\u51b5\u7c7b\u4f3c\uff0c\u5143\u7d20\u662f\u7a7a\u767d\u5b57\u7b26\u4e32\u3002Python\u4f1a\u628a\u7a7a\u767d\u5b57\u7b26\u4e32\u89e3\u6790\u4e3aFalse\uff0c\u6240\u4ee5opacity\u53d8\u91cf\u7684\u503c\u5c31\u7b49\u4e8eor\u53f3\u4fa7\u90a3\u4e2a\u5b50\u8868\u8fbe\u5f0f\u7684\u503c\uff0c\u4e5f\u5c31\u662f0\u3002 \u4f46\u662f\uff0c\u4e0a\u9762\u7684\u8868\u8fbe\u5f0f\u53ef\u8bfb\u6027\u6bd4\u8f83\u5dee\uff0c\u76f8\u6bd4\u4e4b\u4e0b\uff0c\u6539\u7528if/else\u6761\u4ef6\u8868\u8fbe\u5f0f\uff0c\u4ee3\u7801\u53ef\u8bfb\u6027\u4f1a\u597d\u4e00\u4e9b\u3002 >>> green_str = my_value.get('green', ['']) >>> if green_str[0]: ... green = green_str[0] ... else: ... green =0 ... >>> green 0 \u5982\u679c\u8981\u53cd\u590d\u4f7f\u7528\u8fd9\u5957\u903b\u8f91\uff0c\u5efa\u8bae\u5199\u6210\u8f85\u52a9\u51fd\u6570\u6bd4\u8f83\u597d\uff0c\u5373\u4f7f\u50cf\u4e0a\u9762\u8fd9\u4e2a\u4f8b\u5b50\u4e00\u6837\u53ea\u7528\u4e09\u6b21\u3002 >>> def get_first_value(value, key, default=0): ... found = value.get(key, ['']) ... if found[0]: ... return found[0] ... return default ... >>> green = get_first_value(my_value, 'green') >>> green 0 \u8981\u70b9\uff1a * Python\u7684\u8bed\u6cd5\u5f88\u5bb9\u6613\u628a\u590d\u6742\u7684\u610f\u601d\u6324\u5230\u540c\u4e00\u884c\u8868\u8fbe\u5f0f\u91cc\uff0c\u8fd9\u6837\u5199\u5f88\u96be\u61c2\u3002 * \u590d\u6742\u7684\u8868\u8fbe\u5f0f\uff0c\u5c24\u5176\u662f\u90a3\u79cd\u9700\u8981\u91cd\u590d\u4f7f\u7528\u7684\u590d\u6742\u8868\u8fbe\u5f0f\uff0c\u5e94\u8be5\u5199\u5230\u8f85\u52a9\u51fd\u6570\u91cc\u9762\u3002 * \u7528if/else\u7ed3\u6784\u5199\u6210\u7684\u6761\u4ef6\u8868\u8fbe\u5f0f\uff0c\u8981\u6bd4\u7528or\u4e0eand\u5199\u6210\u7684Boolean\u8868\u8fbe\u5f0f\u66f4\u597d\u61c2\u3002 * \u9075\u5faa\u5faaDRY\u539f\u5219\uff0c\u4e0d\u8981\u91cd\u590d\u81ea\u5df1\u5199\u8fc7\u7684\u4ee3\u7801\uff08Don't Repeat Yourself\uff09\u3002","title":"\u7b2c05\u6761 \u7528\u8f85\u52a9\u51fd\u6570\u53d6\u4ee3\u590d\u6742\u7684\u8868\u8fbe\u5f0f"},{"location":"python/Pythonic90Rules/Rule05/#5","text":"Python\u7684\u8bed\u6cd5\u76f8\u5f53\u7b80\u660e\uff0c\u6240\u4ee5\u6709\u65f6\u53ea\u7528\u4e00\u6761\u8868\u8fbe\u5f0f\u5c31\u80fd\u5b9e\u73b0\u8bb8\u591a\u903b\u8f91\u3002 \u4f8b\u5982\uff0c\u8981\u628aURL\u4e4b\u4e2d\u7684\u67e5\u8be2\u5b57\u7b26\u4e32\u62c6\u5206\u6210\u952e\u503c\u5bf9\uff0c\u90a3\u4e48\u53ea\u9700\u8981\u4f7f\u7528parse_qs\u51fd\u6570\u5c31\u53ef\u4ee5\u4e86\u3002 >>> from urllib.parse import parse_qs >>> my_value = parse_qs('red=5&blue=0&green=', keep_blank_values=True) >>> my_value {'red': ['5'], 'blue': ['0'], 'green': ['']} \u5728\u89e3\u6790\u67e5\u8be2\u5b57\u7b26\u4e32\u65f6\uff0c\u53ef\u4ee5\u53d1\u73b0\uff0c\u6709\u7684\u53c2\u6570\u53ef\u80fd\u5e26\u6709\u591a\u4e2a\u503c\uff0c\u6709\u7684\u53c2\u6570\u53ef\u80fd\u53ea\u6709\u4e00\u4e2a\u503c\uff0c\u8fd8\u6709\u7684\u53c2\u6570\u53ef\u80fd\u662f\u7a7a\u767d\u503c\uff0c\u53e6\u5916\u4e5f\u4f1a\u9047\u5230\u6839\u672c\u6ca1\u63d0\u4f9b\u8fd9\u4e2a\u53c2\u6570\u7684\u60c5\u51b5\u3002 \u4e0b\u9762\u8fd9\u4e09\u884c\u4ee3\u7801\u5206\u522b\u901a\u8fc7get\u65b9\u6cd5\u67e5\u8be2\u7ed3\u679c\u5b57\u5178\u91cc\u9762\u7684\u4e09\u4e2a\u53c2\u6570\uff0c\u8fd9\u521a\u597d\u5bf9\u5e94\u4e09\u79cd\u4e0d\u540c\u7684\u60c5\u51b5\uff1a >>> red = my_value.get('red') >>> green = my_value.get('green') >>> opacity = my_value.get('Opacity') >>> print('Red ', red) Red ['5'] >>> print('Green ', green) Green [''] >>> print('Opacity ', opacity) Opacity None \u901a\u8fc7Boolean\u8868\u8fbe\u5f0f\u6765\u5b9e\u73b0\u628a\u4e0a\u8ff0\u53c2\u6570\u7f3a\u5931\u4e0e\u53c2\u6570\u4e3a\u7a7a\u8fd9\u4e24\u79cd\u60c5\u51b5\u9ed8\u8ba4\u503c\u90fd\u8bbe\u62100\u3002Boolean\u8868\u8fbe\u5f0f\u4f1a\u628a\u7a7a\u767d\u5b57\u7b26\u4e32\u3001\u7a7a\u767dlist\u4ee5\u53ca0\u503c\uff0c\u5168\u90fd\u5f53\u6210False\u770b\u5f85\u3002 >>> red = my_value.get('red', [''])[0] or 0 >>> green = my_value.get('green', [''])[0] or 0 >>> opacity = my_value.get('Opacity', [''])[0] or 0 >>> print(f'Red : {red!r}') Red : '5' >>> print(f'Green : {green!r}') Green : 0 >>> print(f'Opacity : {opacity!r}') Opacity : 0 \u4e0a\u8ff0\u4ee3\u7801\u89e3\u6790\uff1a \u56e0\u4e3ared\u952e\u5b58\u5728\u4e8emy_value\u5b57\u5178\uff08dict\uff09\u91cc\u9762\uff0c\u5b83\u5bf9\u5e94\u7684\u503c\u662f\u4e2a\u53ea\u6709\u4e00\u4e2a\u5143\u7d20\u7684\u5217\u8868 ['5'] \uff0c\u8fd9\u4e2a\u5143\u7d20\u662f\u5b57\u7b26\u4e32'5'\u3002Python\u4f1a\u628a\u5b57\u7b26\u4e32'5' \u89e3\u6790\u4e3aTrue\uff0c\u6240\u4ee5\u6574\u4e2a\u8868\u8fbe\u5f0f\u7684\u503c\u5c31\u7b49\u4e8eor\u5de6\u4fa7\u90a3\u4e2a\u5b50\u8868\u8fbe\u5f0f\u7684\u503c\uff0c\u5373 my_values.get('red', [''])[0] \u3002 \u5bf9\u4e8egreen\uff0c\u8fd9\u4e2a\u952e\u503c\u4e5f\u5b58\u5728\u4e8emy_value\u5b57\u5178\uff08dict\uff09\u91cc\u9762\uff0c\u5b83\u5bf9\u5e94\u7684\u503c\u662f\u4e2a\u53ea\u6709\u4e00\u4e2a\u5143\u7d20\u7684\u5217\u8868 [''] \uff0c\u8fd9\u4e2a\u5143\u7d20\u662f\u7a7a\u767d\u5b57\u7b26\u4e32\u3002Python\u4f1a\u628a\u7a7a\u767d\u5b57\u7b26\u4e32\u89e3\u6790\u4e3aFalse\uff0c\u6240\u4ee5green\u53d8\u91cf\u7684\u503c\u5c31\u7b49\u4e8eor\u53f3\u4fa7\u90a3\u4e2a\u5b50\u8868\u8fbe\u5f0f\u7684\u503c\uff0c\u4e5f\u5c31\u662f0\u3002 \u5bf9\u4e8eopacity\uff0c\u8fd9\u4e2a\u952e\u503c\u4e0d\u5b58\u5728\u4e8emy_value\u5b57\u5178\uff08dict\uff09\u91cc\u9762\uff0cget\u65b9\u6cd5\u4f1a\u8fd4\u56de\u4f20\u9012\u7ed9\u5b83\u7684\u7b2c\u4e8c\u4e2a\u503c [''] \uff0c\u548cgreen\u7684\u60c5\u51b5\u7c7b\u4f3c\uff0c\u5143\u7d20\u662f\u7a7a\u767d\u5b57\u7b26\u4e32\u3002Python\u4f1a\u628a\u7a7a\u767d\u5b57\u7b26\u4e32\u89e3\u6790\u4e3aFalse\uff0c\u6240\u4ee5opacity\u53d8\u91cf\u7684\u503c\u5c31\u7b49\u4e8eor\u53f3\u4fa7\u90a3\u4e2a\u5b50\u8868\u8fbe\u5f0f\u7684\u503c\uff0c\u4e5f\u5c31\u662f0\u3002 \u4f46\u662f\uff0c\u4e0a\u9762\u7684\u8868\u8fbe\u5f0f\u53ef\u8bfb\u6027\u6bd4\u8f83\u5dee\uff0c\u76f8\u6bd4\u4e4b\u4e0b\uff0c\u6539\u7528if/else\u6761\u4ef6\u8868\u8fbe\u5f0f\uff0c\u4ee3\u7801\u53ef\u8bfb\u6027\u4f1a\u597d\u4e00\u4e9b\u3002 >>> green_str = my_value.get('green', ['']) >>> if green_str[0]: ... green = green_str[0] ... else: ... green =0 ... >>> green 0 \u5982\u679c\u8981\u53cd\u590d\u4f7f\u7528\u8fd9\u5957\u903b\u8f91\uff0c\u5efa\u8bae\u5199\u6210\u8f85\u52a9\u51fd\u6570\u6bd4\u8f83\u597d\uff0c\u5373\u4f7f\u50cf\u4e0a\u9762\u8fd9\u4e2a\u4f8b\u5b50\u4e00\u6837\u53ea\u7528\u4e09\u6b21\u3002 >>> def get_first_value(value, key, default=0): ... found = value.get(key, ['']) ... if found[0]: ... return found[0] ... return default ... >>> green = get_first_value(my_value, 'green') >>> green 0 \u8981\u70b9\uff1a * Python\u7684\u8bed\u6cd5\u5f88\u5bb9\u6613\u628a\u590d\u6742\u7684\u610f\u601d\u6324\u5230\u540c\u4e00\u884c\u8868\u8fbe\u5f0f\u91cc\uff0c\u8fd9\u6837\u5199\u5f88\u96be\u61c2\u3002 * \u590d\u6742\u7684\u8868\u8fbe\u5f0f\uff0c\u5c24\u5176\u662f\u90a3\u79cd\u9700\u8981\u91cd\u590d\u4f7f\u7528\u7684\u590d\u6742\u8868\u8fbe\u5f0f\uff0c\u5e94\u8be5\u5199\u5230\u8f85\u52a9\u51fd\u6570\u91cc\u9762\u3002 * \u7528if/else\u7ed3\u6784\u5199\u6210\u7684\u6761\u4ef6\u8868\u8fbe\u5f0f\uff0c\u8981\u6bd4\u7528or\u4e0eand\u5199\u6210\u7684Boolean\u8868\u8fbe\u5f0f\u66f4\u597d\u61c2\u3002 * \u9075\u5faa\u5faaDRY\u539f\u5219\uff0c\u4e0d\u8981\u91cd\u590d\u81ea\u5df1\u5199\u8fc7\u7684\u4ee3\u7801\uff08Don't Repeat Yourself\uff09\u3002","title":"\u7b2c5\u6761\u3000\u7528\u8f85\u52a9\u51fd\u6570\u53d6\u4ee3\u590d\u6742\u7684\u8868\u8fbe\u5f0f"},{"location":"python/Pythonic90Rules/Rule06/","text":"\u7b2c6\u6761\u3000\u628a\u6570\u636e\u7ed3\u6784\u76f4\u63a5\u62c6\u5206\u5230\u591a\u4e2a\u53d8\u91cf\u91cc\uff0c\u4e0d\u8981\u4e13\u95e8\u901a\u8fc7\u4e0b\u6807\u8bbf\u95ee \u00b6 Python\u5185\u7f6e\u7684\u5143\u7ec4\uff08tuple\uff09\u7c7b\u578b\u53ef\u4ee5\u521b\u5efa\u4e0d\u53ef\u53d8\u7684\u5e8f\u5217\uff0c\u628a\u8bb8\u591a\u5143\u7d20\u4f9d\u6b21\u4fdd\u5b58\u8d77\u6765\u3002 \u53ef\u4ee5\u7528\u6574\u6570\u4f5c\u4e0b\u6807\uff0c\u901a\u8fc7\u4e0b\u6807\u6765\u8bbf\u95ee\u5143\u7ec4\u91cc\u9762\u5bf9\u5e94\u7684\u5143\u7d20\u3002\u4f46\u4e0d\u80fd\u901a\u8fc7\u4e0b\u6807\u7ed9\u5143\u7d20\u8d4b\u65b0\u503c\u3002 >>> snack_calories = { ... 'chips': 140, ... 'popcorn': 80, ... 'nuts': 190 ... } >>> items = tuple(snack_calories.items()) >>> type(snack_calories) >>> type(items) >>> snack_calories {'chips': 140, 'popcorn': 80, 'nuts': 190} >>> items (('chips', 140), ('popcorn', 80), ('nuts', 190)) >>> items[2] ('nuts', 190) >>> items[1] = ('apple', 200) Traceback (most recent call last): File \"\", line 1, in TypeError: 'tuple' object does not support item assignment Python\u8fd8\u6709\u4e00\u79cd\u5199\u6cd5\uff0c\u53eb\u4f5c\u62c6\u5206\uff08unpacking\uff09\u3002\u8fd9\u79cd\u5199\u6cd5\u8ba9\u6211\u4eec\u53ea\u7528\u4e00\u6761\u8bed\u53e5\uff0c\u5c31\u53ef\u4ee5\u628a\u5143\u7ec4\u91cc\u9762\u7684\u5143\u7d20\u5206\u522b\u8d4b\u7ed9\u591a\u4e2a\u53d8\u91cf\uff0c\u4e0d\u7528\u518d\u901a\u8fc7\u4e0b\u6807\u53bb\u8bbf\u95ee\u3002 \u5143\u7ec4\u7684\u5143\u7d20\u672c\u8eab\u4e0d\u80fd\u4fee\u6539\uff0c\u4f46\u662f\u90a3\u4e9b\u88ab\u8d4b\u503c\u7684\u53d8\u91cf\u662f\u53ef\u4ee5\u4fee\u6539\u7684\u3002 \u901a\u8fc7unpacking\u6765\u8d4b\u503c\u8981\u6bd4\u901a\u8fc7\u4e0b\u6807\u53bb\u8bbf\u95ee\u5143\u7ec4\u5185\u7684\u5143\u7d20\u66f4\u6e05\u6670\uff0c\u800c\u4e14\u8fd9\u79cd\u5199\u6cd5\u6240\u9700\u7684\u4ee3\u7801\u91cf\u901a\u5e38\u6bd4\u8f83\u5c11\u3002\u5f53\u7136\uff0c\u8d4b\u503c\u64cd\u4f5c\u7684\u5de6\u8fb9\u9664\u4e86\u53ef\u4ee5\u7f57\u5217\u5355\u4e2a\u53d8\u91cf\uff0c\u4e5f\u53ef\u4ee5\u5199\u6210\u5217\u8868\u3001\u5e8f\u5217\u6216\u4efb\u610f\u6df1\u5ea6\u7684\u53ef\u8fed\u4ee3\u5bf9\u8c61\uff08iterable\uff09\u3002 >>> favorite_snacks = { ... 'salty': ('pretzels', 100), ... 'sweet': ('cookies', 280), ... 'veggie': ('carrots', 20) ... } >>> ( ... (type1, (name1, cals1)), ... (type2, (name2, cals2)), ... (type3, (name3, cals3)), ... ) = favorite_snacks.items() >>> print(f'Favorite {type1} is {name1} with {cals1} calories') Favorite salty is pretzels with 100 calories >>> print(f'Favorite {type2} is {name2} with {cals2} calories') Favorite sweet is cookies with 280 calories >>> print(f'Favorite {type3} is {name3} with {cals3} calories') Favorite veggie is carrots with 20 calories \u53ef\u4ee5\u901a\u8fc7unpacking\u539f\u5730\u4ea4\u6362\u4e24\u4e2a\u53d8\u91cf\uff0c\u800c\u4e0d\u7528\u4e13\u95e8\u521b\u5efa\u4e34\u65f6\u53d8\u91cf\u3002 >>> def bubble_sort(a): ... for _ in range(len(a)): ... for i in range(1, len(a)): ... if a[i] < a[i - 1]: ... temp = a[i] ... a[i] = a[i - 1] ... a[i - 1] = temp ... >>> names = ['pretzels', 'carrots', 'arugula', 'bacon'] >>> bubble_sort(names) >>> names ['arugula', 'bacon', 'carrots', 'pretzels'] >>> def bubble_sort(a): ... for _ in range(len(a)): ... for i in range(1, len(a)): ... if a[i] < a[i - 1]: ... a[i], a[i - 1] = a[i - 1], a[i] ... >>> names = ['pretzels', 'carrots', 'arugula', 'bacon'] >>> bubble_sort(names) >>> names ['arugula', 'bacon', 'carrots', 'pretzels'] \u539f\u7406\u5206\u6790\uff1a Python\u5904\u7406\u8d4b\u503c\u64cd\u4f5c\u7684\u65f6\u5019\uff0c\u8981\u5148\u5bf9=\u53f7\u53f3\u4fa7\u6c42\u503c\uff0c\u4e8e\u662f\uff0c\u5b83\u4f1a\u65b0\u5efa\u4e00\u4e2a\u4e34\u65f6\u7684\u5143\u7ec4\uff0c\u628a a[i] \u4e0e a[i-1] \u8fd9\u4e24\u4e2a\u5143\u7d20\u653e\u5230\u8fd9\u4e2a\u5143\u7ec4\u91cc\u9762\u3002\u4f8b\u5982\uff0c\u7b2c\u4e00\u6b21\u8fdb\u5165\u5185\u90e8\u7684for\u5faa\u73af\u65f6\uff0c\u8fd9\u4e24\u4e2a\u5143\u7d20\u5206\u522b\u662f 'carrots' \u4e0e 'pretzels '\uff0c\u4e8e\u662f\uff0c\u7cfb\u7edf\u5c31\u4f1a\u521b\u5efa\u51fa ('carrots','pretzels') \u8fd9\u6837\u4e00\u4e2a\u4e34\u65f6\u7684\u5143\u7ec4\u3002 \u7136\u540e\uff0cPython\u4f1a\u5bf9\u8fd9\u4e2a\u4e34\u65f6\u7684\u5143\u7ec4\u505aunpacking\uff0c\u628a\u5b83\u91cc\u9762\u7684\u4e24\u4e2a\u5143\u7d20\u5206\u522b\u653e\u5230=\u53f7\u5de6\u4fa7\u7684\u90a3\u4e24\u4e2a\u5730\u65b9\uff0c\u4e8e\u662f\uff0c 'carrots' \u5c31\u4f1a\u628a a[i-1] \u91cc\u9762\u539f\u6709\u7684 'pretzels' \u6362\u6389\uff0c 'pretzels' \u4e5f\u4f1a\u628a a[i] \u91cc\u9762\u539f\u6709\u7684 'carrots' \u6362\u6389\u3002 \u73b0\u5728\uff0c\u51fa\u73b0\u5728 a[0] \u8fd9\u4e2a\u4f4d\u7f6e\u4e0a\u9762\u7684\u5b57\u7b26\u4e32\u5c31\u662f 'carrots' \u4e86\uff0c\u51fa\u73b0\u5728 a[1] \u8fd9\u4e2a\u4f4d\u7f6e\u4e0a\u9762\u7684\u5b57\u7b26\u4e32\u5219\u662f 'pretzels' \u3002 \u505a\u5b8cunpacking\u540e\uff0c\u7cfb\u7edf\u4f1a\u6254\u6389\u8fd9\u4e2a\u4e34\u65f6\u7684\u5143\u7ec4\u3002 unpacking\u673a\u5236\u8fd8\u6709\u4e00\u4e2a\u7279\u522b\u91cd\u8981\u7684\u7528\u6cd5\uff0c\u5c31\u662f\u53ef\u4ee5\u5728for\u5faa\u73af\u6216\u8005\u7c7b\u4f3c\u7684\u7ed3\u6784\u91cc\u9762\uff0c\u628a\u590d\u6742\u7684\u6570\u636e\u62c6\u5206\u5230\u76f8\u5173\u7684\u53d8\u91cf\u4e4b\u4e2d\u3002 >>> snacks = [('bacon', 350), ('donut', 240), ('muffin', 190)] >>> for i in range(len(snacks)): ... item = snacks[i] ... name = item[0] ... calories = item[1] ... print(f'#{i+1}: {name} has {calories} calories') ... #1: bacon has 350 calories #2: donut has 240 calories #3: muffin has 190 calories \u4e0a\u9762\u8fd9\u6bb5\u4ee3\u7801\u867d\u7136\u6ca1\u9519\uff0c\u4f46\u770b\u8d77\u6765\u5f88\u4e71\uff0c\u56e0\u4e3asnacks\u7ed3\u6784\u672c\u8eab\u5e76\u4e0d\u662f\u4e00\u4efd\u7b80\u5355\u7684\u5217\u8868\uff0c\u5b83\u7684\u6bcf\u4e2a\u5143\u7d20\u90fd\u662f\u4e00\u4e2a\u5143\u7ec4\uff0c \u6240\u4ee5\u5fc5\u987b\u9010\u5c42\u8bbf\u95ee\u624d\u80fd\u67e5\u5230\u6700\u4e3a\u5177\u4f53\u7684\u6570\u636e\uff0c\u4e5f\u5c31\u662f\u6bcf\u79cd\u96f6\u98df\u7684\u540d\u79f0\uff08name\uff09\u53ca\u5361\u8def\u91cc\uff08calories\uff09\u3002 \u4e0b\u9762\u6362\u4e00\u79cd\u5199\u6cd5\uff0c\u9996\u5148\u8c03\u7528\u5185\u7f6e\u7684enumerate\u51fd\u6570\uff08\u53c2\u89c1\u7b2c7\u6761\uff09\u83b7\u5f97\u5f53\u524d\u8981\u8fed\u4ee3\u7684\u5143\u7ec4\uff0c \u7136\u540e\u9488\u5bf9\u8fd9\u4e2a\u5143\u7ec4\u505aunpacking\uff0c\u8fd9\u6837\u5c31\u53ef\u4ee5\u76f4\u63a5\u5f97\u5230\u5177\u4f53\u7684name\u4e0ecalories\u503c\u4e86\u3002 \u8fd9\u624d\u662f\u7b26\u5408Python\u98ce\u683c\u7684\u5199\u6cd5\uff08Pythonic\u5f0f\u7684\u5199\u6cd5\uff09\u3002 >>> for rank, (name, calories) in enumerate(snacks, 1): ... print(f'#{rank}: {name} has {calories} calories') ... #1: bacon has 350 calories #2: donut has 240 calories #3: muffin has 190 calories Python\u7684unpacking\u673a\u5236\u53ef\u4ee5\u7528\u5728\u8bb8\u591a\u65b9\u9762\uff0c\u4f8b\u5982\u6784\u5efa\u5217\u8868\uff08Rule13\uff09\u3001\u7ed9\u51fd\u6570\u8bbe\u8ba1\u53c2\u6570\u5217\u8868\uff08Rule22\uff09\u3001\u4f20\u9012\u5173\u952e\u5b57\u53c2\u6570\uff08Rule23\uff09\u3001\u63a5\u6536\u591a\u4e2a\u8fd4\u56de\u503c\uff08Rule19\u6761\uff09\u7b49\u3002 \u8981\u70b9\uff1a unpacking\u662f\u4e00\u79cd\u7279\u6b8a\u7684Python\u8bed\u6cd5\uff0c\u53ea\u9700\u8981\u4e00\u884c\u4ee3\u7801\uff0c\u5c31\u80fd\u628a\u6570\u636e\u7ed3\u6784\u91cc\u9762\u7684\u591a\u4e2a\u503c\u5206\u522b\u8d4b\u7ed9\u76f8\u5e94\u7684\u53d8\u91cf\u3002 unpacking\u5728Python\u4e2d\u5e94\u7528\u5e7f\u6cdb\uff0c\u51e1\u662f\u53ef\u8fed\u4ee3\u7684\u5bf9\u8c61\u90fd\u80fd\u62c6\u5206\uff0c\u65e0\u8bba\u5b83\u91cc\u9762\u8fd8\u6709\u591a\u5c11\u5c42\u8fed\u4ee3\u7ed3\u6784\u3002 \u5c3d\u91cf\u901a\u8fc7unpacking\u6765\u62c6\u89e3\u5e8f\u5217\u4e4b\u4e2d\u7684\u6570\u636e\uff0c\u800c\u4e0d\u8981\u901a\u8fc7\u4e0b\u6807\u8bbf\u95ee\uff0c\u8fd9\u6837\u53ef\u4ee5\u8ba9\u4ee3\u7801\u66f4\u7b80\u6d01\u3001\u66f4\u6e05\u6670\u3002 \u62d3\u5c55\uff1aPacking and Unpacking in Python \u00b6 Python allows a tuple (or list) of variables to appear on the left side of an assignment operation. Each variable in the tuple can receive one value (or more, if we use the * operator) from an iterable on the right side of the assignment. Unpacking in Python refers to an operation that consists of assigning an iterable of values to a tuple (or list) of variables in a single assignment statement. In Python, we can put a tuple of variables on the left side of an assignment operator (=) and a tuple of values on the right side. The values on the right will be automatically assigned to the variables on the left according to their position in the tuple. This is commonly known as tuple unpacking in Python. Check out the following example: >>> (a, b, c) = (1, 2, 3) >>> a 1 >>> b 2 >>> c 3 >>> birthday = ('April', 5, 2001) >>> month, day, year = birthday >>> month 'April' >>> day 5 >>> year 2001 The tuple unpacking feature got so popular among Python developers that the syntax was extended to work with any iterable object. The only requirement is that the iterable yields exactly one item per variable in the receiving tuple ( or list). Check out the following examples of how iterable unpacking works in Python: >>> # Unpackage strings >>> a, b, c = '123' >>> a '1' >>> b '2' >>> c '3' >>> # Unpackaging strings >>> a, b, c = '123' >>> a '1' >>> b '2' >>> c '3' >>> # Unpacking lists >>> a, b, c = [1, 2, 3] >>> a 1 >>> b 2 >>> c 3 >>> # Unpacking generators >>> gen = (i ** 2 for i in range(3)) >>> a, b, c = gen >>> a 0 >>> b 1 >>> c 4 >>> # Upacking dictionaries (keys, values, and items) >>> my_dict = {'one': 1, 'two': 2, 'three': 3} >>> a, b, c = my_dict >>> a 'one' >>> b 'two' >>> c 'three' >>> a, b, c = my_dict.values() >>> a 1 >>> b 2 >>> c 3 >>> a, b, c = my_dict.items() >>> a ('one', 1) >>> b ('two', 2) >>> c ('three', 3) >>> # Use a tuple on the right side of assignment statement >>> [a, b, c] = 1, 2, 3 >>> a 1 >>> b 2 >>> c 3 >>> # Use range() iterator >>> x, y, z = range(3) >>> x 0 >>> y 1 >>> z 2 As a complement, the term packing can be used when we collect several values in a single variable using the iterable unpacking operator. The * operator is known, in this context, as the tuple (or iterable) unpacking operator. It extends the unpacking functionality to allow us to collect or pack multiple values in a single variable. In the following example, we pack a tuple of values into a single variable by using the * operator: >>> *a, = 1, 2 >>> a [1, 2] For this code to work, the left side of the assignment must be a tuple (or a list). That's why we use a trailing comma. This tuple can contain as many variables as we need. However, it can only contain one starred expression. >>> # Packing trailing values >>> a, *b = 1, 2, 3 >>> a 1 >>> b [2, 3] >>> *a, b, c = 1, 2, 3 >>> a [1] >>> b 2 >>> c 3 >>> *a, b, c, d, e = 1, 2, 3 Traceback (most recent call last): File \"\", line 1, in ValueError: not enough values to unpack (expected at least 4, got 3) >>> *a, b, c, d = 1, 2, 3 >>> a [] >>> b 1 >>> c 2 >>> d 3 >>> >>> seq = [1, 2, 3, 4] >>> first, *body, last = seq >>> first, body, last (1, [2, 3], 4) >>> first, body, *last = seq >>> first, body, last (1, 2, [3, 4]) >>> ran = range(10) >>> *r, = ran >>> r [0, 1, 2, 3, 4, 5, 6, 7, 8, 9] Using Packing and Unpacking in Practice >>> employee = ['John Doe', '40', 'Software Engineer'] >>> name = employee[0] >>> age = employee[1] >>> job = employee[2] >>> name 'John Doe' >>> age '40' >>> job 'Software Engineer' >>> >>> name, age, job = ['John Doe', '40', 'Software Engineer'] >>> name 'John Doe' >>> age '40' >>> job 'Software Engineer' >>> >>> a = 100 >>> b = 200 >>> a, b = b, a >>> a 200 >>> b 100 Dropping Unneeded Values With * >>> a, b, *_ = 1, 2, 0, 0, 0, 0 >>> a 1 >>> b 2 >>> _ [0, 0, 0, 0] The rest of the information is stored in the dummy variable _, which can be ignored by our program. By default, the underscore character _ is used by the Python interpreter to store the resulting value of the statements we run in an interactive session. So, in this context, the use of this character to identify dummy variables can be ambiguous. Returning Tuples in Functions >>> def powers(num): ... return num, num ** 2, num ** 3 ... >>> # Packaging returned values in a tuple >>> result = powers(3) >>> result (3, 9, 27) >>> # Unpacking returned values to multiple variables >>> number, square, cube = powers(3) >>> number 3 >>> square 9 >>> cube 27 >>> *_, cube = powers(3) >>> cube 27 Merging Iterables With the * Operator The last two examples show that this is also a more readable and efficient way to concatenate iterables. Instead of writing list(my_set) + my_list + list(my_tuple) + list(range(1, 4)) + list(my_str) we just write [*my_set, *my_list, *my_tuple, *range(1, 4), *my_str] . >>> my_tuple = (1, 2, 3) >>> (0, *my_tuple, 4) (0, 1, 2, 3, 4) >>> my_list = [1, 2, 3] >>> [0, *my_list, 4] [0, 1, 2, 3, 4] >>> my_set = {1, 2, 3} >>> {0, *my_set, 4} {0, 1, 2, 3, 4} >>> [*my_set, *my_list, *my_tuple, *range(1, 4)] [1, 2, 3, 1, 2, 3, 1, 2, 3, 1, 2, 3] >>> my_str = \"123\" >>> [*my_set, *my_list, *my_tuple, *range(1, 4), *my_str] [1, 2, 3, 1, 2, 3, 1, 2, 3, 1, 2, 3, '1', '2', '3'] Unpacking Dictionaries With the ** Operator >>> numbers = {'one': 1, 'two': 2, 'three': 3} >>> letters = {'a': 'A', 'b': 'B', 'c': 'C'} >>> combination = {**numbers, **letters} >>> combination {'one': 1, 'two': 2, 'three': 3, 'a': 'A', 'b': 'B', 'c': 'C'} An important point to note is that, if the dictionaries we're trying to merge have repeated or common keys, then the values of the right-most dictionary will override the values of the left-most dictionary. Here's an example: >>> letters = {'a': 'A', 'b': 'B', 'c': 'C'} >>> vowels = {'a': 'a', 'e': 'e', 'i': 'i', 'o': 'o', 'u': 'u'} >>> {**letters, **vowels} {'a': 'a', 'b': 'B', 'c': 'C', 'e': 'e', 'i': 'i', 'o': 'o', 'u': 'u'} >>> {**vowels, **letters} {'a': 'A', 'e': 'e', 'i': 'i', 'o': 'o', 'u': 'u', 'b': 'B', 'c': 'C'} Unpacking in For-Loops We can also use iterable unpacking in the context of for loops. When we run a for loop, the loop assigns one item of its iterable to the target variable in every iteration. If the item to be assigned is an iterable, then we can use a tuple of target variables. The loop will unpack the iterable at hand into the tuple of target variables. We can build a list of two-elements tuples. Each tuple will contain the name of the product, the price, and the sold units. With this information, we want to calculate the income of each product. To do this, we can use a for loop like this: >>> sales = [('Pencle', 0.22, 1500), ('Notebook', 1.30, 550), ('Eraser', 0.75, 1000)] >>> for items in sales: ... print(f\"Income for {item[0]} is: {item[1] * item[2]}\") ... Traceback (most recent call last): File \"\", line 2, in NameError: name 'item' is not defined >>> for items in sales: ... print(f\"Income for {items[0]} is: {items[1] * items[2]}\") ... Income for Pencle is: 330.0 Income for Notebook is: 715.0 Income for Eraser is: 750.0 we're using indices to get access to individual elements of each tuple. This can be difficult to read and to understand by newcomer developers. We're now using iterable unpacking in our for loop in below sample codes, which is an alternative implementation using unpacking in Python: >>> sales = [('Pencle', 0.22, 1500), ('Notebook', 1.30, 550), ('Eraser', 0.75, 1000)] >>> for product, price, sold_units in sales: ... print(f\"Income for {product} is: {price * sold_units}\") ... Income for Pencle is: 330.0 Income for Notebook is: 715.0 Income for Eraser is: 750.0 It's also possible to use the * operator in a for loop to pack several items in a single target variable. In this for loop, we're catching the first element of each sequence in first. Then the * operator catches a list of values in its target variable rest. >>> for first, *rest in [(1, 2, 3),(4, 5, 6)]: ... print('First: ', first) ... print('Rest: ', rest) ... First: 1 Rest: [2, 3] First: 4 Rest: [5, 6] >>> Finally, the structure of the target variables must agree with the structure of the iterable. Otherwise, we'll get an error. Take a look at the following example: >>> data = [((1, 2), 3), ((2, 3), 3)] >>> for (a, b), c in data: ... print(a, b, c) ... 1 2 3 2 3 3 >>> for a, b, c in data: ... print(a, b, c) ... Traceback (most recent call last): File \"\", line 1, in ValueError: not enough values to unpack (expected 3, got 2) Defining Functions With * and ** The below function requires at least one argument called required . It can accept a variable number of positional and keyword arguments as well. In this case, the * operator collects or packs extra positional arguments in a tuple called args and the ** operator collects or packs extra keyword arguments in a dictionary called kwargs . Both, args and kwargs , are optional and automatically default to () and {} respectively. Even though the names args and kwargs are widely used by the Python community, they're not a requirement for these techniques to work. The syntax just requires * or ** followed by a valid identifier. So, if you can give meaningful names to these arguments, then do it. That will certainly improve your code's readability. >>> def func(required, *args, **kwargs): ... print(required) ... print(args) ... print(kwargs) ... >>> func('Welcome to ...', 1, 2, 3, site='CloudAcademy.com') Welcome to ... (1, 2, 3) {'site': 'CloudAcademy.com'} >>> func('Welcome to ...', 1, 2, 3, 4) Welcome to ... (1, 2, 3, 4) {} >>> func('Welcome to ...', 1, 2, 3, (1, 2)) Welcome to ... (1, 2, 3, (1, 2)) {} >>> func('Welcome to ...', 1, 2, 3, [1, 2]) Welcome to ... (1, 2, 3, [1, 2]) {} >>> func('Welcome to ...', 1, 2, 3, ([2, 3], [1, 2])) Welcome to ... (1, 2, 3, ([2, 3], [1, 2])) {} Calling Functions With * and ** When calling functions, we can also benefit from the use of the * and ** operator to unpack collections of arguments into separate positional or keyword arguments respectively. This is the inverse of using * and ** in the signature of a function. In the signature, the operators mean collect or pack a variable number of arguments in one identifier. In the call, they mean unpack an iterable into several arguments. Here's a basic example of how this works. The * operator unpacks sequences like [\"Welcome\", \"to\"] into positional arguments. Similarly, the ** operator unpacks dictionaries into arguments whose names match the keys of the unpacked dictionary. >>> def func(welcome, to, site): ... print(welcome, to, site ... ... ) ... >>> def func(welcome, to, site): ... print(welcome, to, site) ... >>> func(*['Welcome', 'to'], **{'site': 'CloudAcademy.com'}) Welcome to CloudAcademy.com We can also combine this technique and the one covered in the previous section to write quite flexible functions. The use of the * and ** operators, when defining and calling Python functions, will give them extra capabilities and make them more flexible and powerful. Here's an example: >>> def func(required, *args, **kwargs): ... print(required) ... print(args) ... print(kwargs) ... >>> func('Welcome to...', *(1, 2, 3), **{'Site': 'CloudAcademy.com'}) Welcome to... (1, 2, 3) {'Site': 'CloudAcademy.com'} Conclusion Iterable unpacking turns out to be a pretty useful and popular feature in Python. This feature allows us to unpack an iterable into several variables. On the other hand, packing consists of catching several values into one variable using the unpacking operator, *. In this tutorial, we've learned how to use iterable unpacking in Python to write more readable, maintainable, and pythonic code. With this knowledge, we are now able to use iterable unpacking in Python to solve common problems like parallel assignment and swapping values between variables. We're also able to use this Python feature in other structures like for loops, function calls, and function definitions. \u62d3\u5c55\uff1aenumerate \u00b6 enumerate() \u51fd\u6570\u7528\u4e8e\u5c06\u4e00\u4e2a\u53ef\u904d\u5386\u7684\u6570\u636e\u5bf9\u8c61(\u5982\u5217\u8868\u3001\u5143\u7ec4\u6216\u5b57\u7b26\u4e32)\u7ec4\u5408\u4e3a\u4e00\u4e2a\u7d22\u5f15\u5e8f\u5217\uff0c\u540c\u65f6\u5217\u51fa\u6570\u636e\u548c\u6570\u636e\u4e0b\u6807\uff0c\u4e00\u822c\u7528\u5728 for \u5faa\u73af\u5f53\u4e2d\u3002 enumerate() \u65b9\u6cd5: \u8bed\u6cd5 enumerate(sequence, [start=0]) \u53c2\u6570 sequence\uff1a\u4e00\u4e2a\u5e8f\u5217\u3001\u8fed\u4ee3\u5668\u6216\u5176\u4ed6\u652f\u6301\u8fed\u4ee3\u5bf9\u8c61\u3002 start\uff1a\u4e0b\u6807\u8d77\u59cb\u4f4d\u7f6e\u3002 \u8fd4\u56de\u503c \u8fd4\u56de enumerate(\u679a\u4e3e) \u5bf9\u8c61\u3002 \u57fa\u672c\u7528\u6cd5\uff1a \u5b57\u7b26\u4e32 >>> sample = 'abcd' >>> for i, j in enumerate(sample): # \u8f93\u51fa\u7684\u662f\u5143\u7ec4\u5185\u7684\u5143\u7d20 ... print(i, j) ... 0 a 1 b 2 c 3 d >>> for i in enumerate(sample): # \u8f93\u51fa\u7684\u662f\u5143\u7ec4 ... print(i) ... (0, 'a') (1, 'b') (2, 'c') (3, 'd') >>> sample = ('abcd') >>> for i, j in enumerate(sample): ... print(i, j) ... 0 a 1 b 2 c 3 d \u5143\u7ec4 >>> sample = ('abcd', 'hijk') >>> for i, j in enumerate(sample): ... print(i, j) ... 0 abcd 1 hijk >>> sample = ('abcd', 'hijk') >>> for i, j in enumerate(sample, 2): ... print(i, j) ... 2 abcd 3 hijk \u6570\u7ec4 >>> sample = ['abcd', 'hijk'] >>> for i, j in enumerate(sample): ... print(i, j) ... 0 abcd 1 hijk \u5b57\u5178 >>> sample = {'abcd': 1, 'hijk': 2} >>> for i, j in enumerate(sample): ... print(i, j) ... 0 abcd 1 hijk","title":"\u7b2c06\u6761 \u628a\u6570\u636e\u7ed3\u6784\u76f4\u63a5\u62c6\u5206\u5230\u591a\u4e2a\u53d8\u91cf\u91cc\uff0c\u4e0d\u8981\u4e13\u95e8\u901a\u8fc7\u4e0b\u6807\u8bbf\u95ee"},{"location":"python/Pythonic90Rules/Rule06/#6","text":"Python\u5185\u7f6e\u7684\u5143\u7ec4\uff08tuple\uff09\u7c7b\u578b\u53ef\u4ee5\u521b\u5efa\u4e0d\u53ef\u53d8\u7684\u5e8f\u5217\uff0c\u628a\u8bb8\u591a\u5143\u7d20\u4f9d\u6b21\u4fdd\u5b58\u8d77\u6765\u3002 \u53ef\u4ee5\u7528\u6574\u6570\u4f5c\u4e0b\u6807\uff0c\u901a\u8fc7\u4e0b\u6807\u6765\u8bbf\u95ee\u5143\u7ec4\u91cc\u9762\u5bf9\u5e94\u7684\u5143\u7d20\u3002\u4f46\u4e0d\u80fd\u901a\u8fc7\u4e0b\u6807\u7ed9\u5143\u7d20\u8d4b\u65b0\u503c\u3002 >>> snack_calories = { ... 'chips': 140, ... 'popcorn': 80, ... 'nuts': 190 ... } >>> items = tuple(snack_calories.items()) >>> type(snack_calories) >>> type(items) >>> snack_calories {'chips': 140, 'popcorn': 80, 'nuts': 190} >>> items (('chips', 140), ('popcorn', 80), ('nuts', 190)) >>> items[2] ('nuts', 190) >>> items[1] = ('apple', 200) Traceback (most recent call last): File \"\", line 1, in TypeError: 'tuple' object does not support item assignment Python\u8fd8\u6709\u4e00\u79cd\u5199\u6cd5\uff0c\u53eb\u4f5c\u62c6\u5206\uff08unpacking\uff09\u3002\u8fd9\u79cd\u5199\u6cd5\u8ba9\u6211\u4eec\u53ea\u7528\u4e00\u6761\u8bed\u53e5\uff0c\u5c31\u53ef\u4ee5\u628a\u5143\u7ec4\u91cc\u9762\u7684\u5143\u7d20\u5206\u522b\u8d4b\u7ed9\u591a\u4e2a\u53d8\u91cf\uff0c\u4e0d\u7528\u518d\u901a\u8fc7\u4e0b\u6807\u53bb\u8bbf\u95ee\u3002 \u5143\u7ec4\u7684\u5143\u7d20\u672c\u8eab\u4e0d\u80fd\u4fee\u6539\uff0c\u4f46\u662f\u90a3\u4e9b\u88ab\u8d4b\u503c\u7684\u53d8\u91cf\u662f\u53ef\u4ee5\u4fee\u6539\u7684\u3002 \u901a\u8fc7unpacking\u6765\u8d4b\u503c\u8981\u6bd4\u901a\u8fc7\u4e0b\u6807\u53bb\u8bbf\u95ee\u5143\u7ec4\u5185\u7684\u5143\u7d20\u66f4\u6e05\u6670\uff0c\u800c\u4e14\u8fd9\u79cd\u5199\u6cd5\u6240\u9700\u7684\u4ee3\u7801\u91cf\u901a\u5e38\u6bd4\u8f83\u5c11\u3002\u5f53\u7136\uff0c\u8d4b\u503c\u64cd\u4f5c\u7684\u5de6\u8fb9\u9664\u4e86\u53ef\u4ee5\u7f57\u5217\u5355\u4e2a\u53d8\u91cf\uff0c\u4e5f\u53ef\u4ee5\u5199\u6210\u5217\u8868\u3001\u5e8f\u5217\u6216\u4efb\u610f\u6df1\u5ea6\u7684\u53ef\u8fed\u4ee3\u5bf9\u8c61\uff08iterable\uff09\u3002 >>> favorite_snacks = { ... 'salty': ('pretzels', 100), ... 'sweet': ('cookies', 280), ... 'veggie': ('carrots', 20) ... } >>> ( ... (type1, (name1, cals1)), ... (type2, (name2, cals2)), ... (type3, (name3, cals3)), ... ) = favorite_snacks.items() >>> print(f'Favorite {type1} is {name1} with {cals1} calories') Favorite salty is pretzels with 100 calories >>> print(f'Favorite {type2} is {name2} with {cals2} calories') Favorite sweet is cookies with 280 calories >>> print(f'Favorite {type3} is {name3} with {cals3} calories') Favorite veggie is carrots with 20 calories \u53ef\u4ee5\u901a\u8fc7unpacking\u539f\u5730\u4ea4\u6362\u4e24\u4e2a\u53d8\u91cf\uff0c\u800c\u4e0d\u7528\u4e13\u95e8\u521b\u5efa\u4e34\u65f6\u53d8\u91cf\u3002 >>> def bubble_sort(a): ... for _ in range(len(a)): ... for i in range(1, len(a)): ... if a[i] < a[i - 1]: ... temp = a[i] ... a[i] = a[i - 1] ... a[i - 1] = temp ... >>> names = ['pretzels', 'carrots', 'arugula', 'bacon'] >>> bubble_sort(names) >>> names ['arugula', 'bacon', 'carrots', 'pretzels'] >>> def bubble_sort(a): ... for _ in range(len(a)): ... for i in range(1, len(a)): ... if a[i] < a[i - 1]: ... a[i], a[i - 1] = a[i - 1], a[i] ... >>> names = ['pretzels', 'carrots', 'arugula', 'bacon'] >>> bubble_sort(names) >>> names ['arugula', 'bacon', 'carrots', 'pretzels'] \u539f\u7406\u5206\u6790\uff1a Python\u5904\u7406\u8d4b\u503c\u64cd\u4f5c\u7684\u65f6\u5019\uff0c\u8981\u5148\u5bf9=\u53f7\u53f3\u4fa7\u6c42\u503c\uff0c\u4e8e\u662f\uff0c\u5b83\u4f1a\u65b0\u5efa\u4e00\u4e2a\u4e34\u65f6\u7684\u5143\u7ec4\uff0c\u628a a[i] \u4e0e a[i-1] \u8fd9\u4e24\u4e2a\u5143\u7d20\u653e\u5230\u8fd9\u4e2a\u5143\u7ec4\u91cc\u9762\u3002\u4f8b\u5982\uff0c\u7b2c\u4e00\u6b21\u8fdb\u5165\u5185\u90e8\u7684for\u5faa\u73af\u65f6\uff0c\u8fd9\u4e24\u4e2a\u5143\u7d20\u5206\u522b\u662f 'carrots' \u4e0e 'pretzels '\uff0c\u4e8e\u662f\uff0c\u7cfb\u7edf\u5c31\u4f1a\u521b\u5efa\u51fa ('carrots','pretzels') \u8fd9\u6837\u4e00\u4e2a\u4e34\u65f6\u7684\u5143\u7ec4\u3002 \u7136\u540e\uff0cPython\u4f1a\u5bf9\u8fd9\u4e2a\u4e34\u65f6\u7684\u5143\u7ec4\u505aunpacking\uff0c\u628a\u5b83\u91cc\u9762\u7684\u4e24\u4e2a\u5143\u7d20\u5206\u522b\u653e\u5230=\u53f7\u5de6\u4fa7\u7684\u90a3\u4e24\u4e2a\u5730\u65b9\uff0c\u4e8e\u662f\uff0c 'carrots' \u5c31\u4f1a\u628a a[i-1] \u91cc\u9762\u539f\u6709\u7684 'pretzels' \u6362\u6389\uff0c 'pretzels' \u4e5f\u4f1a\u628a a[i] \u91cc\u9762\u539f\u6709\u7684 'carrots' \u6362\u6389\u3002 \u73b0\u5728\uff0c\u51fa\u73b0\u5728 a[0] \u8fd9\u4e2a\u4f4d\u7f6e\u4e0a\u9762\u7684\u5b57\u7b26\u4e32\u5c31\u662f 'carrots' \u4e86\uff0c\u51fa\u73b0\u5728 a[1] \u8fd9\u4e2a\u4f4d\u7f6e\u4e0a\u9762\u7684\u5b57\u7b26\u4e32\u5219\u662f 'pretzels' \u3002 \u505a\u5b8cunpacking\u540e\uff0c\u7cfb\u7edf\u4f1a\u6254\u6389\u8fd9\u4e2a\u4e34\u65f6\u7684\u5143\u7ec4\u3002 unpacking\u673a\u5236\u8fd8\u6709\u4e00\u4e2a\u7279\u522b\u91cd\u8981\u7684\u7528\u6cd5\uff0c\u5c31\u662f\u53ef\u4ee5\u5728for\u5faa\u73af\u6216\u8005\u7c7b\u4f3c\u7684\u7ed3\u6784\u91cc\u9762\uff0c\u628a\u590d\u6742\u7684\u6570\u636e\u62c6\u5206\u5230\u76f8\u5173\u7684\u53d8\u91cf\u4e4b\u4e2d\u3002 >>> snacks = [('bacon', 350), ('donut', 240), ('muffin', 190)] >>> for i in range(len(snacks)): ... item = snacks[i] ... name = item[0] ... calories = item[1] ... print(f'#{i+1}: {name} has {calories} calories') ... #1: bacon has 350 calories #2: donut has 240 calories #3: muffin has 190 calories \u4e0a\u9762\u8fd9\u6bb5\u4ee3\u7801\u867d\u7136\u6ca1\u9519\uff0c\u4f46\u770b\u8d77\u6765\u5f88\u4e71\uff0c\u56e0\u4e3asnacks\u7ed3\u6784\u672c\u8eab\u5e76\u4e0d\u662f\u4e00\u4efd\u7b80\u5355\u7684\u5217\u8868\uff0c\u5b83\u7684\u6bcf\u4e2a\u5143\u7d20\u90fd\u662f\u4e00\u4e2a\u5143\u7ec4\uff0c \u6240\u4ee5\u5fc5\u987b\u9010\u5c42\u8bbf\u95ee\u624d\u80fd\u67e5\u5230\u6700\u4e3a\u5177\u4f53\u7684\u6570\u636e\uff0c\u4e5f\u5c31\u662f\u6bcf\u79cd\u96f6\u98df\u7684\u540d\u79f0\uff08name\uff09\u53ca\u5361\u8def\u91cc\uff08calories\uff09\u3002 \u4e0b\u9762\u6362\u4e00\u79cd\u5199\u6cd5\uff0c\u9996\u5148\u8c03\u7528\u5185\u7f6e\u7684enumerate\u51fd\u6570\uff08\u53c2\u89c1\u7b2c7\u6761\uff09\u83b7\u5f97\u5f53\u524d\u8981\u8fed\u4ee3\u7684\u5143\u7ec4\uff0c \u7136\u540e\u9488\u5bf9\u8fd9\u4e2a\u5143\u7ec4\u505aunpacking\uff0c\u8fd9\u6837\u5c31\u53ef\u4ee5\u76f4\u63a5\u5f97\u5230\u5177\u4f53\u7684name\u4e0ecalories\u503c\u4e86\u3002 \u8fd9\u624d\u662f\u7b26\u5408Python\u98ce\u683c\u7684\u5199\u6cd5\uff08Pythonic\u5f0f\u7684\u5199\u6cd5\uff09\u3002 >>> for rank, (name, calories) in enumerate(snacks, 1): ... print(f'#{rank}: {name} has {calories} calories') ... #1: bacon has 350 calories #2: donut has 240 calories #3: muffin has 190 calories Python\u7684unpacking\u673a\u5236\u53ef\u4ee5\u7528\u5728\u8bb8\u591a\u65b9\u9762\uff0c\u4f8b\u5982\u6784\u5efa\u5217\u8868\uff08Rule13\uff09\u3001\u7ed9\u51fd\u6570\u8bbe\u8ba1\u53c2\u6570\u5217\u8868\uff08Rule22\uff09\u3001\u4f20\u9012\u5173\u952e\u5b57\u53c2\u6570\uff08Rule23\uff09\u3001\u63a5\u6536\u591a\u4e2a\u8fd4\u56de\u503c\uff08Rule19\u6761\uff09\u7b49\u3002 \u8981\u70b9\uff1a unpacking\u662f\u4e00\u79cd\u7279\u6b8a\u7684Python\u8bed\u6cd5\uff0c\u53ea\u9700\u8981\u4e00\u884c\u4ee3\u7801\uff0c\u5c31\u80fd\u628a\u6570\u636e\u7ed3\u6784\u91cc\u9762\u7684\u591a\u4e2a\u503c\u5206\u522b\u8d4b\u7ed9\u76f8\u5e94\u7684\u53d8\u91cf\u3002 unpacking\u5728Python\u4e2d\u5e94\u7528\u5e7f\u6cdb\uff0c\u51e1\u662f\u53ef\u8fed\u4ee3\u7684\u5bf9\u8c61\u90fd\u80fd\u62c6\u5206\uff0c\u65e0\u8bba\u5b83\u91cc\u9762\u8fd8\u6709\u591a\u5c11\u5c42\u8fed\u4ee3\u7ed3\u6784\u3002 \u5c3d\u91cf\u901a\u8fc7unpacking\u6765\u62c6\u89e3\u5e8f\u5217\u4e4b\u4e2d\u7684\u6570\u636e\uff0c\u800c\u4e0d\u8981\u901a\u8fc7\u4e0b\u6807\u8bbf\u95ee\uff0c\u8fd9\u6837\u53ef\u4ee5\u8ba9\u4ee3\u7801\u66f4\u7b80\u6d01\u3001\u66f4\u6e05\u6670\u3002","title":"\u7b2c6\u6761\u3000\u628a\u6570\u636e\u7ed3\u6784\u76f4\u63a5\u62c6\u5206\u5230\u591a\u4e2a\u53d8\u91cf\u91cc\uff0c\u4e0d\u8981\u4e13\u95e8\u901a\u8fc7\u4e0b\u6807\u8bbf\u95ee"},{"location":"python/Pythonic90Rules/Rule06/#packing-and-unpacking-in-python","text":"Python allows a tuple (or list) of variables to appear on the left side of an assignment operation. Each variable in the tuple can receive one value (or more, if we use the * operator) from an iterable on the right side of the assignment. Unpacking in Python refers to an operation that consists of assigning an iterable of values to a tuple (or list) of variables in a single assignment statement. In Python, we can put a tuple of variables on the left side of an assignment operator (=) and a tuple of values on the right side. The values on the right will be automatically assigned to the variables on the left according to their position in the tuple. This is commonly known as tuple unpacking in Python. Check out the following example: >>> (a, b, c) = (1, 2, 3) >>> a 1 >>> b 2 >>> c 3 >>> birthday = ('April', 5, 2001) >>> month, day, year = birthday >>> month 'April' >>> day 5 >>> year 2001 The tuple unpacking feature got so popular among Python developers that the syntax was extended to work with any iterable object. The only requirement is that the iterable yields exactly one item per variable in the receiving tuple ( or list). Check out the following examples of how iterable unpacking works in Python: >>> # Unpackage strings >>> a, b, c = '123' >>> a '1' >>> b '2' >>> c '3' >>> # Unpackaging strings >>> a, b, c = '123' >>> a '1' >>> b '2' >>> c '3' >>> # Unpacking lists >>> a, b, c = [1, 2, 3] >>> a 1 >>> b 2 >>> c 3 >>> # Unpacking generators >>> gen = (i ** 2 for i in range(3)) >>> a, b, c = gen >>> a 0 >>> b 1 >>> c 4 >>> # Upacking dictionaries (keys, values, and items) >>> my_dict = {'one': 1, 'two': 2, 'three': 3} >>> a, b, c = my_dict >>> a 'one' >>> b 'two' >>> c 'three' >>> a, b, c = my_dict.values() >>> a 1 >>> b 2 >>> c 3 >>> a, b, c = my_dict.items() >>> a ('one', 1) >>> b ('two', 2) >>> c ('three', 3) >>> # Use a tuple on the right side of assignment statement >>> [a, b, c] = 1, 2, 3 >>> a 1 >>> b 2 >>> c 3 >>> # Use range() iterator >>> x, y, z = range(3) >>> x 0 >>> y 1 >>> z 2 As a complement, the term packing can be used when we collect several values in a single variable using the iterable unpacking operator. The * operator is known, in this context, as the tuple (or iterable) unpacking operator. It extends the unpacking functionality to allow us to collect or pack multiple values in a single variable. In the following example, we pack a tuple of values into a single variable by using the * operator: >>> *a, = 1, 2 >>> a [1, 2] For this code to work, the left side of the assignment must be a tuple (or a list). That's why we use a trailing comma. This tuple can contain as many variables as we need. However, it can only contain one starred expression. >>> # Packing trailing values >>> a, *b = 1, 2, 3 >>> a 1 >>> b [2, 3] >>> *a, b, c = 1, 2, 3 >>> a [1] >>> b 2 >>> c 3 >>> *a, b, c, d, e = 1, 2, 3 Traceback (most recent call last): File \"\", line 1, in ValueError: not enough values to unpack (expected at least 4, got 3) >>> *a, b, c, d = 1, 2, 3 >>> a [] >>> b 1 >>> c 2 >>> d 3 >>> >>> seq = [1, 2, 3, 4] >>> first, *body, last = seq >>> first, body, last (1, [2, 3], 4) >>> first, body, *last = seq >>> first, body, last (1, 2, [3, 4]) >>> ran = range(10) >>> *r, = ran >>> r [0, 1, 2, 3, 4, 5, 6, 7, 8, 9] Using Packing and Unpacking in Practice >>> employee = ['John Doe', '40', 'Software Engineer'] >>> name = employee[0] >>> age = employee[1] >>> job = employee[2] >>> name 'John Doe' >>> age '40' >>> job 'Software Engineer' >>> >>> name, age, job = ['John Doe', '40', 'Software Engineer'] >>> name 'John Doe' >>> age '40' >>> job 'Software Engineer' >>> >>> a = 100 >>> b = 200 >>> a, b = b, a >>> a 200 >>> b 100 Dropping Unneeded Values With * >>> a, b, *_ = 1, 2, 0, 0, 0, 0 >>> a 1 >>> b 2 >>> _ [0, 0, 0, 0] The rest of the information is stored in the dummy variable _, which can be ignored by our program. By default, the underscore character _ is used by the Python interpreter to store the resulting value of the statements we run in an interactive session. So, in this context, the use of this character to identify dummy variables can be ambiguous. Returning Tuples in Functions >>> def powers(num): ... return num, num ** 2, num ** 3 ... >>> # Packaging returned values in a tuple >>> result = powers(3) >>> result (3, 9, 27) >>> # Unpacking returned values to multiple variables >>> number, square, cube = powers(3) >>> number 3 >>> square 9 >>> cube 27 >>> *_, cube = powers(3) >>> cube 27 Merging Iterables With the * Operator The last two examples show that this is also a more readable and efficient way to concatenate iterables. Instead of writing list(my_set) + my_list + list(my_tuple) + list(range(1, 4)) + list(my_str) we just write [*my_set, *my_list, *my_tuple, *range(1, 4), *my_str] . >>> my_tuple = (1, 2, 3) >>> (0, *my_tuple, 4) (0, 1, 2, 3, 4) >>> my_list = [1, 2, 3] >>> [0, *my_list, 4] [0, 1, 2, 3, 4] >>> my_set = {1, 2, 3} >>> {0, *my_set, 4} {0, 1, 2, 3, 4} >>> [*my_set, *my_list, *my_tuple, *range(1, 4)] [1, 2, 3, 1, 2, 3, 1, 2, 3, 1, 2, 3] >>> my_str = \"123\" >>> [*my_set, *my_list, *my_tuple, *range(1, 4), *my_str] [1, 2, 3, 1, 2, 3, 1, 2, 3, 1, 2, 3, '1', '2', '3'] Unpacking Dictionaries With the ** Operator >>> numbers = {'one': 1, 'two': 2, 'three': 3} >>> letters = {'a': 'A', 'b': 'B', 'c': 'C'} >>> combination = {**numbers, **letters} >>> combination {'one': 1, 'two': 2, 'three': 3, 'a': 'A', 'b': 'B', 'c': 'C'} An important point to note is that, if the dictionaries we're trying to merge have repeated or common keys, then the values of the right-most dictionary will override the values of the left-most dictionary. Here's an example: >>> letters = {'a': 'A', 'b': 'B', 'c': 'C'} >>> vowels = {'a': 'a', 'e': 'e', 'i': 'i', 'o': 'o', 'u': 'u'} >>> {**letters, **vowels} {'a': 'a', 'b': 'B', 'c': 'C', 'e': 'e', 'i': 'i', 'o': 'o', 'u': 'u'} >>> {**vowels, **letters} {'a': 'A', 'e': 'e', 'i': 'i', 'o': 'o', 'u': 'u', 'b': 'B', 'c': 'C'} Unpacking in For-Loops We can also use iterable unpacking in the context of for loops. When we run a for loop, the loop assigns one item of its iterable to the target variable in every iteration. If the item to be assigned is an iterable, then we can use a tuple of target variables. The loop will unpack the iterable at hand into the tuple of target variables. We can build a list of two-elements tuples. Each tuple will contain the name of the product, the price, and the sold units. With this information, we want to calculate the income of each product. To do this, we can use a for loop like this: >>> sales = [('Pencle', 0.22, 1500), ('Notebook', 1.30, 550), ('Eraser', 0.75, 1000)] >>> for items in sales: ... print(f\"Income for {item[0]} is: {item[1] * item[2]}\") ... Traceback (most recent call last): File \"\", line 2, in NameError: name 'item' is not defined >>> for items in sales: ... print(f\"Income for {items[0]} is: {items[1] * items[2]}\") ... Income for Pencle is: 330.0 Income for Notebook is: 715.0 Income for Eraser is: 750.0 we're using indices to get access to individual elements of each tuple. This can be difficult to read and to understand by newcomer developers. We're now using iterable unpacking in our for loop in below sample codes, which is an alternative implementation using unpacking in Python: >>> sales = [('Pencle', 0.22, 1500), ('Notebook', 1.30, 550), ('Eraser', 0.75, 1000)] >>> for product, price, sold_units in sales: ... print(f\"Income for {product} is: {price * sold_units}\") ... Income for Pencle is: 330.0 Income for Notebook is: 715.0 Income for Eraser is: 750.0 It's also possible to use the * operator in a for loop to pack several items in a single target variable. In this for loop, we're catching the first element of each sequence in first. Then the * operator catches a list of values in its target variable rest. >>> for first, *rest in [(1, 2, 3),(4, 5, 6)]: ... print('First: ', first) ... print('Rest: ', rest) ... First: 1 Rest: [2, 3] First: 4 Rest: [5, 6] >>> Finally, the structure of the target variables must agree with the structure of the iterable. Otherwise, we'll get an error. Take a look at the following example: >>> data = [((1, 2), 3), ((2, 3), 3)] >>> for (a, b), c in data: ... print(a, b, c) ... 1 2 3 2 3 3 >>> for a, b, c in data: ... print(a, b, c) ... Traceback (most recent call last): File \"\", line 1, in ValueError: not enough values to unpack (expected 3, got 2) Defining Functions With * and ** The below function requires at least one argument called required . It can accept a variable number of positional and keyword arguments as well. In this case, the * operator collects or packs extra positional arguments in a tuple called args and the ** operator collects or packs extra keyword arguments in a dictionary called kwargs . Both, args and kwargs , are optional and automatically default to () and {} respectively. Even though the names args and kwargs are widely used by the Python community, they're not a requirement for these techniques to work. The syntax just requires * or ** followed by a valid identifier. So, if you can give meaningful names to these arguments, then do it. That will certainly improve your code's readability. >>> def func(required, *args, **kwargs): ... print(required) ... print(args) ... print(kwargs) ... >>> func('Welcome to ...', 1, 2, 3, site='CloudAcademy.com') Welcome to ... (1, 2, 3) {'site': 'CloudAcademy.com'} >>> func('Welcome to ...', 1, 2, 3, 4) Welcome to ... (1, 2, 3, 4) {} >>> func('Welcome to ...', 1, 2, 3, (1, 2)) Welcome to ... (1, 2, 3, (1, 2)) {} >>> func('Welcome to ...', 1, 2, 3, [1, 2]) Welcome to ... (1, 2, 3, [1, 2]) {} >>> func('Welcome to ...', 1, 2, 3, ([2, 3], [1, 2])) Welcome to ... (1, 2, 3, ([2, 3], [1, 2])) {} Calling Functions With * and ** When calling functions, we can also benefit from the use of the * and ** operator to unpack collections of arguments into separate positional or keyword arguments respectively. This is the inverse of using * and ** in the signature of a function. In the signature, the operators mean collect or pack a variable number of arguments in one identifier. In the call, they mean unpack an iterable into several arguments. Here's a basic example of how this works. The * operator unpacks sequences like [\"Welcome\", \"to\"] into positional arguments. Similarly, the ** operator unpacks dictionaries into arguments whose names match the keys of the unpacked dictionary. >>> def func(welcome, to, site): ... print(welcome, to, site ... ... ) ... >>> def func(welcome, to, site): ... print(welcome, to, site) ... >>> func(*['Welcome', 'to'], **{'site': 'CloudAcademy.com'}) Welcome to CloudAcademy.com We can also combine this technique and the one covered in the previous section to write quite flexible functions. The use of the * and ** operators, when defining and calling Python functions, will give them extra capabilities and make them more flexible and powerful. Here's an example: >>> def func(required, *args, **kwargs): ... print(required) ... print(args) ... print(kwargs) ... >>> func('Welcome to...', *(1, 2, 3), **{'Site': 'CloudAcademy.com'}) Welcome to... (1, 2, 3) {'Site': 'CloudAcademy.com'} Conclusion Iterable unpacking turns out to be a pretty useful and popular feature in Python. This feature allows us to unpack an iterable into several variables. On the other hand, packing consists of catching several values into one variable using the unpacking operator, *. In this tutorial, we've learned how to use iterable unpacking in Python to write more readable, maintainable, and pythonic code. With this knowledge, we are now able to use iterable unpacking in Python to solve common problems like parallel assignment and swapping values between variables. We're also able to use this Python feature in other structures like for loops, function calls, and function definitions.","title":"\u62d3\u5c55\uff1aPacking and Unpacking in Python"},{"location":"python/Pythonic90Rules/Rule06/#enumerate","text":"enumerate() \u51fd\u6570\u7528\u4e8e\u5c06\u4e00\u4e2a\u53ef\u904d\u5386\u7684\u6570\u636e\u5bf9\u8c61(\u5982\u5217\u8868\u3001\u5143\u7ec4\u6216\u5b57\u7b26\u4e32)\u7ec4\u5408\u4e3a\u4e00\u4e2a\u7d22\u5f15\u5e8f\u5217\uff0c\u540c\u65f6\u5217\u51fa\u6570\u636e\u548c\u6570\u636e\u4e0b\u6807\uff0c\u4e00\u822c\u7528\u5728 for \u5faa\u73af\u5f53\u4e2d\u3002 enumerate() \u65b9\u6cd5: \u8bed\u6cd5 enumerate(sequence, [start=0]) \u53c2\u6570 sequence\uff1a\u4e00\u4e2a\u5e8f\u5217\u3001\u8fed\u4ee3\u5668\u6216\u5176\u4ed6\u652f\u6301\u8fed\u4ee3\u5bf9\u8c61\u3002 start\uff1a\u4e0b\u6807\u8d77\u59cb\u4f4d\u7f6e\u3002 \u8fd4\u56de\u503c \u8fd4\u56de enumerate(\u679a\u4e3e) \u5bf9\u8c61\u3002 \u57fa\u672c\u7528\u6cd5\uff1a \u5b57\u7b26\u4e32 >>> sample = 'abcd' >>> for i, j in enumerate(sample): # \u8f93\u51fa\u7684\u662f\u5143\u7ec4\u5185\u7684\u5143\u7d20 ... print(i, j) ... 0 a 1 b 2 c 3 d >>> for i in enumerate(sample): # \u8f93\u51fa\u7684\u662f\u5143\u7ec4 ... print(i) ... (0, 'a') (1, 'b') (2, 'c') (3, 'd') >>> sample = ('abcd') >>> for i, j in enumerate(sample): ... print(i, j) ... 0 a 1 b 2 c 3 d \u5143\u7ec4 >>> sample = ('abcd', 'hijk') >>> for i, j in enumerate(sample): ... print(i, j) ... 0 abcd 1 hijk >>> sample = ('abcd', 'hijk') >>> for i, j in enumerate(sample, 2): ... print(i, j) ... 2 abcd 3 hijk \u6570\u7ec4 >>> sample = ['abcd', 'hijk'] >>> for i, j in enumerate(sample): ... print(i, j) ... 0 abcd 1 hijk \u5b57\u5178 >>> sample = {'abcd': 1, 'hijk': 2} >>> for i, j in enumerate(sample): ... print(i, j) ... 0 abcd 1 hijk","title":"\u62d3\u5c55\uff1aenumerate"},{"location":"python/Pythonic90Rules/Rule07/","text":"\u7b2c7\u6761\u3000\u5c3d\u91cf\u7528enumerate\u53d6\u4ee3range \u00b6 Python\u5185\u7f6e\u7684range\u51fd\u6570\u9002\u5408\u7528\u6765\u8fed\u4ee3\u4e00\u7cfb\u5217\u6574\u6570\u3002 >>> from random import randint >>> random_bits = 0 >>> for i in range(32): ... if randint(0, 1): ... random_bits |= 1 << i # \u8fd0\u7b97\u7b26|\u662f\u4e8c\u8fdb\u5236OR\u64cd\u4f5c ... >>> print(bin(random_bits)) 0b110110000110100101001011010 \u5982\u679c\u8981\u8fed\u4ee3\u7684\u662f\u67d0\u79cd\u6570\u636e\u7ed3\u6784\uff0c\u4f8b\u5982\u5b57\u7b26\u4e32\u5217\u8868\uff0c\u90a3\u4e48\u53ef\u4ee5\u76f4\u63a5\u5728\u8fd9\u4e2a\u5e8f\u5217\u4e0a\u9762\u8fed\u4ee3\uff0c\u4e0d\u9700\u8981\u901a\u8fc7range\u3002 >>> flavor_list\u7b2c8\u6761\u3000\u7528zip\u51fd\u6570\u540c\u65f6\u904d\u5386\u4e24\u4e2a\u8fed\u4ee3\u5668 = ['vanilla', 'chocolate', 'pecan', 'strawberry'] >>> for flavor in flavor_list: ... print(f'{flavor} is delicious') ... vanilla is delicious chocolate is delicious pecan is delicious strawberry is delicious \u901a\u8fc7\u4f20\u7edf\u7684range\u65b9\u6cd5\uff0c\u7ed9\u6bcf\u79cd\u53e3\u5473\u6dfb\u52a0\u5e8f\u5217\u53f7\u3002\u4f46\u6b65\u9aa4\u6709\u4e9b\u592a\u591a\uff0c\u5148\u5f97\u77e5\u9053\u5217\u8868\u7684\u957f\u5ea6\uff0c\u7136\u540e\u8981\u6839\u636e\u5217\u8868\u957f\u5ea6\u6784\u9020\u53d6\u503c\u8303\u56f4\uff0c\u7528\u5176\u4e2d\u7684\u6bcf\u4e2a\u6574\u6570\u505a\u4e0b\u6807\uff0c\u5206\u522b\u8bbf\u95ee\u5217\u8868\u91cc\u7684\u5bf9\u5e94\u5143\u7d20\u3002 >>> for i in range(len(flavor_list)): ... flavor = flavor_list[i] ... print(f'{i + 1}: {flavor}') ... 1: vanilla 2: chocolate 3: pecan 4: strawberry Python\u7684\u5185\u7f6e\u7684\u51fd\u6570enumerate\uff0c\u80fd\u591f\u628a\u4efb\u4f55\u4e00\u79cd\u8fed\u4ee3\u5668\uff08iterator\uff09\u5c01\u88c5\u6210\u60f0\u6027\u751f\u6210\u5668\uff08lazy generator\uff0c\u53c2\u89c1Rule30\uff09\u3002 \u8fd9\u6837\u6bcf\u6b21\u5faa\u73af\u7684\u65f6\u5019\uff0c\u5b83\u53ea\u9700\u8981\u4eceiterator\u91cc\u9762\u83b7\u53d6\u4e0b\u4e00\u4e2a\u503c\u5c31\u884c\u4e86\uff0c\u540c\u65f6\u8fd8\u4f1a\u7ed9\u51fa\u672c\u8f6e\u5faa\u73af\u7684\u5e8f\u53f7\uff0c\u5373\u751f\u6210\u5668\u6bcf\u6b21\u4ea7\u751f\u7684\u4e00\u5bf9\u8f93\u51fa\u503c\u3002 \u4e0b\u9762\u901a\u8fc7\u5185\u7f6e\u7684next\u51fd\u6570\u624b\u52a8\u63a8\u8fdbenumerate\u6240\u8fd4\u56de\u7684\u8fd9\u4e2aiterator\uff0c\u6765\u6f14\u793aenumerate\u3002 >>> it = enumerate(flavor_list) >>> print(next(it)) (0, 'vanilla') >>> print(next(it)) (1, 'chocolate') >>> print(next(it)) (2, 'pecan') >>> print(next(it)) (3, 'strawberry') >>> print(next(it)) Traceback (most recent call last): File \"\", line 1, in StopIteration enumerate\u8f93\u51fa\u7684\u6bcf\u4e00\u5bf9\u6570\u636e\uff0c\u90fd\u53ef\u4ee5\u62c6\u5206\uff08unpacking\uff09\u5230for\u8bed\u53e5\u7684\u90a3\u4e24\u4e2a\u53d8\u91cf\u91cc\u9762\uff08unpacking\u673a\u5236\u53c2\u89c1Rule06\uff09\uff0c\u8fd9\u6837\u4f1a\u8ba9\u4ee3\u7801\u66f4\u52a0\u6e05\u6670\u3002 >>> for i, flavor in enumerate(flavor_list): ... print(f'{i + 1}: {flavor}') ... 1: vanilla 2: chocolate 3: pecan 4: strawberry >>> for i, flavor in enumerate(flavor_list, 1): ... print(f'{i}: {flavor}') ... 1: vanilla 2: chocolate 3: pecan 4: strawberry \u8981\u70b9\uff1a enumerate\u51fd\u6570\u53ef\u4ee5\u7528\u7b80\u6d01\u7684\u4ee3\u7801\u8fed\u4ee3iterator\uff0c\u800c\u4e14\u53ef\u4ee5\u6307\u51fa\u5f53\u524d\u8fd9\u8f6e\u5faa\u73af\u7684\u5e8f\u53f7\u3002 \u4e0d\u8981\u5148\u901a\u8fc7range\u6307\u5b9a\u4e0b\u6807\u7684\u53d6\u503c\u8303\u56f4\uff0c\u7136\u540e\u7528\u4e0b\u6807\u53bb\u8bbf\u95ee\u5e8f\u5217\uff0c\u800c\u662f\u5e94\u8be5\u76f4\u63a5\u7528enumerate\u51fd\u6570\u8fed\u4ee3\u3002 \u53ef\u4ee5\u901a\u8fc7enumerate\u7684\u7b2c\u4e8c\u4e2a\u53c2\u6570\u6307\u5b9a\u8d77\u59cb\u5e8f\u53f7\uff08\u9ed8\u8ba4\u4e3a0\uff09\u3002","title":"\u7b2c07\u6761 \u5c3d\u91cf\u7528enumerate\u53d6\u4ee3range"},{"location":"python/Pythonic90Rules/Rule07/#7-enumeraterange","text":"Python\u5185\u7f6e\u7684range\u51fd\u6570\u9002\u5408\u7528\u6765\u8fed\u4ee3\u4e00\u7cfb\u5217\u6574\u6570\u3002 >>> from random import randint >>> random_bits = 0 >>> for i in range(32): ... if randint(0, 1): ... random_bits |= 1 << i # \u8fd0\u7b97\u7b26|\u662f\u4e8c\u8fdb\u5236OR\u64cd\u4f5c ... >>> print(bin(random_bits)) 0b110110000110100101001011010 \u5982\u679c\u8981\u8fed\u4ee3\u7684\u662f\u67d0\u79cd\u6570\u636e\u7ed3\u6784\uff0c\u4f8b\u5982\u5b57\u7b26\u4e32\u5217\u8868\uff0c\u90a3\u4e48\u53ef\u4ee5\u76f4\u63a5\u5728\u8fd9\u4e2a\u5e8f\u5217\u4e0a\u9762\u8fed\u4ee3\uff0c\u4e0d\u9700\u8981\u901a\u8fc7range\u3002 >>> flavor_list\u7b2c8\u6761\u3000\u7528zip\u51fd\u6570\u540c\u65f6\u904d\u5386\u4e24\u4e2a\u8fed\u4ee3\u5668 = ['vanilla', 'chocolate', 'pecan', 'strawberry'] >>> for flavor in flavor_list: ... print(f'{flavor} is delicious') ... vanilla is delicious chocolate is delicious pecan is delicious strawberry is delicious \u901a\u8fc7\u4f20\u7edf\u7684range\u65b9\u6cd5\uff0c\u7ed9\u6bcf\u79cd\u53e3\u5473\u6dfb\u52a0\u5e8f\u5217\u53f7\u3002\u4f46\u6b65\u9aa4\u6709\u4e9b\u592a\u591a\uff0c\u5148\u5f97\u77e5\u9053\u5217\u8868\u7684\u957f\u5ea6\uff0c\u7136\u540e\u8981\u6839\u636e\u5217\u8868\u957f\u5ea6\u6784\u9020\u53d6\u503c\u8303\u56f4\uff0c\u7528\u5176\u4e2d\u7684\u6bcf\u4e2a\u6574\u6570\u505a\u4e0b\u6807\uff0c\u5206\u522b\u8bbf\u95ee\u5217\u8868\u91cc\u7684\u5bf9\u5e94\u5143\u7d20\u3002 >>> for i in range(len(flavor_list)): ... flavor = flavor_list[i] ... print(f'{i + 1}: {flavor}') ... 1: vanilla 2: chocolate 3: pecan 4: strawberry Python\u7684\u5185\u7f6e\u7684\u51fd\u6570enumerate\uff0c\u80fd\u591f\u628a\u4efb\u4f55\u4e00\u79cd\u8fed\u4ee3\u5668\uff08iterator\uff09\u5c01\u88c5\u6210\u60f0\u6027\u751f\u6210\u5668\uff08lazy generator\uff0c\u53c2\u89c1Rule30\uff09\u3002 \u8fd9\u6837\u6bcf\u6b21\u5faa\u73af\u7684\u65f6\u5019\uff0c\u5b83\u53ea\u9700\u8981\u4eceiterator\u91cc\u9762\u83b7\u53d6\u4e0b\u4e00\u4e2a\u503c\u5c31\u884c\u4e86\uff0c\u540c\u65f6\u8fd8\u4f1a\u7ed9\u51fa\u672c\u8f6e\u5faa\u73af\u7684\u5e8f\u53f7\uff0c\u5373\u751f\u6210\u5668\u6bcf\u6b21\u4ea7\u751f\u7684\u4e00\u5bf9\u8f93\u51fa\u503c\u3002 \u4e0b\u9762\u901a\u8fc7\u5185\u7f6e\u7684next\u51fd\u6570\u624b\u52a8\u63a8\u8fdbenumerate\u6240\u8fd4\u56de\u7684\u8fd9\u4e2aiterator\uff0c\u6765\u6f14\u793aenumerate\u3002 >>> it = enumerate(flavor_list) >>> print(next(it)) (0, 'vanilla') >>> print(next(it)) (1, 'chocolate') >>> print(next(it)) (2, 'pecan') >>> print(next(it)) (3, 'strawberry') >>> print(next(it)) Traceback (most recent call last): File \"\", line 1, in StopIteration enumerate\u8f93\u51fa\u7684\u6bcf\u4e00\u5bf9\u6570\u636e\uff0c\u90fd\u53ef\u4ee5\u62c6\u5206\uff08unpacking\uff09\u5230for\u8bed\u53e5\u7684\u90a3\u4e24\u4e2a\u53d8\u91cf\u91cc\u9762\uff08unpacking\u673a\u5236\u53c2\u89c1Rule06\uff09\uff0c\u8fd9\u6837\u4f1a\u8ba9\u4ee3\u7801\u66f4\u52a0\u6e05\u6670\u3002 >>> for i, flavor in enumerate(flavor_list): ... print(f'{i + 1}: {flavor}') ... 1: vanilla 2: chocolate 3: pecan 4: strawberry >>> for i, flavor in enumerate(flavor_list, 1): ... print(f'{i}: {flavor}') ... 1: vanilla 2: chocolate 3: pecan 4: strawberry \u8981\u70b9\uff1a enumerate\u51fd\u6570\u53ef\u4ee5\u7528\u7b80\u6d01\u7684\u4ee3\u7801\u8fed\u4ee3iterator\uff0c\u800c\u4e14\u53ef\u4ee5\u6307\u51fa\u5f53\u524d\u8fd9\u8f6e\u5faa\u73af\u7684\u5e8f\u53f7\u3002 \u4e0d\u8981\u5148\u901a\u8fc7range\u6307\u5b9a\u4e0b\u6807\u7684\u53d6\u503c\u8303\u56f4\uff0c\u7136\u540e\u7528\u4e0b\u6807\u53bb\u8bbf\u95ee\u5e8f\u5217\uff0c\u800c\u662f\u5e94\u8be5\u76f4\u63a5\u7528enumerate\u51fd\u6570\u8fed\u4ee3\u3002 \u53ef\u4ee5\u901a\u8fc7enumerate\u7684\u7b2c\u4e8c\u4e2a\u53c2\u6570\u6307\u5b9a\u8d77\u59cb\u5e8f\u53f7\uff08\u9ed8\u8ba4\u4e3a0\uff09\u3002","title":"\u7b2c7\u6761\u3000\u5c3d\u91cf\u7528enumerate\u53d6\u4ee3range"},{"location":"python/Pythonic90Rules/Rule08/","text":"\u7b2c8\u6761\u3000\u7528zip\u51fd\u6570\u540c\u65f6\u904d\u5386\u4e24\u4e2a\u8fed\u4ee3\u5668 \u00b6 \u5199Python\u4ee3\u7801\u65f6\uff0c\u7ecf\u5e38\u4f1a\u6839\u636e\u67d0\u4efd\u5217\u8868\u4e2d\u7684\u5bf9\u8c61\u521b\u5efa\u8bb8\u591a\u4e0e\u8fd9\u4efd\u5217\u8868\u6709\u5173\u7684\u65b0\u5217\u8868\u3002 \u4e0b\u9762\u8fd9\u6837\u7684\u5217\u8868\u63a8\u5bfc\u673a\u5236\uff0c\u53ef\u4ee5\u628a\u8868\u8fbe\u5f0f\u8fd0\u7528\u5230\u6e90\u5217\u8868\u7684\u6bcf\u4e2a\u5143\u7d20\u4e0a\u9762\uff0c\u4ece\u800c\u751f\u6210\u4e00\u4efd\u6d3e\u751f\u5217\u8868\uff08\u53c2\u89c1Rule27\uff09\u3002 >>> names = ['Cecilia', 'Lise', 'Marie'] >>> counts = [len(n) for n in names] >>> counts [7, 4, 5] \u6d3e\u751f\u5217\u8868\u4e2d\u7684\u5143\u7d20\u4e0e\u6e90\u5217\u8868\u4e2d\u5bf9\u5e94\u4f4d\u7f6e\u4e0a\u9762\u7684\u5143\u7d20\u6709\u7740\u4e00\u5b9a\u7684\u5173\u7cfb\u3002\u5982\u679c\u60f3\u540c\u65f6\u904d\u5386\u8fd9\u4e24\u4efd\u5217\u8868\uff0c\u90a3\u53ef\u4ee5\u6839\u636e\u6e90\u5217\u8868\u7684\u957f\u5ea6\u505a\u8fed\u4ee3\u3002 >>> names = ['Cecilia', 'Lise', 'Marie'] >>> longest_name = None >>> max_count = 0 >>> counts = [len(n) for n in names] >>> for i in range(len(names)): ... count = counts[i] ... if count > max_count: ... longest_name = names[i] ... max_count = count ... >>> longest_name 'Cecilia' \u7528enumerate\u6765\u6539\u5199\u4e0a\u9762\u7684\u4ee3\u7801\uff0c\u6539\u5584\u4e0a\u9762\u4ee3\u7801\u4e2d\u590d\u6742\u7684\u5faa\u73af\u5173\u7cfb\u3002 >>> names = ['Cecilia', 'Lise', 'Marie'] >>> longest_name = None >>> max_count = 0 >>> counts = [len(n) for n in names] >>> for i, name in enumerate(names): ... count = counts[i] ... if count > max_count: ... longest_name = name ... max_count = count ... >>> longest_name 'Cecilia' \u7528zip\u6765\u6539\u5199\u4ee3\u7801\uff0c\u4f7f\u4e4b\u66f4\u7b80\u6d01\u3002 zip\u51fd\u6570\u80fd\u628a\u4e24\u4e2a\u6216\u66f4\u591a\u7684iterator\u5c01\u88c5\u6210\u60f0\u6027\u751f\u6210\u5668\uff08lazy generator\uff09\u3002 \u6bcf\u6b21\u5faa\u73af\u65f6\uff0c\u5b83\u4f1a\u5206\u522b\u4ece\u8fd9\u4e9b\u8fed\u4ee3\u5668\u91cc\u83b7\u53d6\u5404\u81ea\u7684\u4e0b\u4e00\u4e2a\u5143\u7d20\uff0c\u5e76\u628a\u8fd9\u4e9b\u503c\u653e\u5728\u4e00\u4e2a\u5143\u7ec4\u91cc\u9762\u3002 zip\u6bcf\u6b21\u53ea\u4ece\u5b83\u5c01\u88c5\u7684\u90a3\u4e9b\u8fed\u4ee3\u5668\u91cc\u9762\u5404\u81ea\u53d6\u51fa\u4e00\u4e2a\u5143\u7d20\uff0c\u6240\u4ee5\u5373\u4fbf\u6e90\u5217\u8868\u5f88\u957f\uff0c\u7a0b\u5e8f\u4e5f\u4e0d\u4f1a\u56e0\u4e3a\u5360\u7528\u5185\u5b58\u8fc7\u591a\u800c\u5d29\u6e83\u3002 \u800c\u8fd9\u4e2a\u5143\u7ec4\u53ef\u4ee5\u62c6\u5206\u5230for\u8bed\u53e5\u91cc\u7684\u90a3\u4e9b\u53d8\u91cf\u4e4b\u4e2d\uff08\u53c2\u89c1Rule06\uff09\u3002 \u8fd9\u6837\u5199\u51fa\u6765\u7684\u4ee3\u7801\uff0c\u6bd4\u901a\u8fc7\u4e0b\u6807\u8bbf\u95ee\u591a\u4e2a\u5217\u8868\u7684\u90a3\u79cd\u4ee3\u7801\u8981\u6e05\u6670\u5f97\u591a\u3002 >>> names = ['Cecilia', 'Lise', 'Marie'] >>> longest_name = None >>> max_count = 0 >>> counts = [len(n) for n in names] >>> for name, count in zip(names, counts): ... if count > max_count: ... longest_name = name ... max_count = count ... >>> longest_name 'Cecilia' \u4f46\u662f\uff0c\u5982\u679c\u8f93\u5165zip\u7684\u90a3\u4e9b\u5217\u8868\u7684\u957f\u5ea6\u4e0d\u4e00\u81f4\uff0c\u7528zip\u540c\u65f6\u904d\u5386\u90a3\u4e9b\u5217\u8868\uff0c\u4f1a\u4ea7\u751f\u5947\u602a\u7684\u7ed3\u679c\u3002 \u4f8b\u5982\uff0c\u6211\u7ed9names\u5217\u8868\u91cc\u53c8\u6dfb\u52a0\u4e86\u4e00\u4e2a\u540d\u5b57\uff0c\u4f46\u662f\u5fd8\u4e86\u628a\u5b83\u7684\u957f\u5ea6\u66f4\u65b0\u5230counts\u5217\u8868\u4e4b\u4e2d\u3002 \u65b0\u6dfb\u52a0\u7684\u90a3\u4e2a'Rosalind' \u5143\u7d20\u4e0d\u4f1a\u88ab\u6253\u5370\u51fa\u6765\uff0c\u56e0\u4e3azip\u51fd\u6570\u5728\u6267\u884c\u4e2d\uff0c\u53ea\u8981\u5176\u4e2d\u4efb\u4f55\u4e00\u4e2a\u8fed\u4ee3\u5668\u5904\u7406\u5b8c\u6bd5\uff0c\u5b83\u5c31\u4e0d\u518d\u5f80\u4e0b\u8d70\u4e86\u3002 \u4e8e\u662f\uff0c\u5faa\u73af\u7684\u6b21\u6570\u5b9e\u9645\u4e0a\u7b49\u4e8e\u6700\u77ed\u7684\u90a3\u4efd\u5217\u8868\u6240\u5177\u5907\u7684\u957f\u5ea6\u3002 \u4e00\u822c\u60c5\u51b5\u4e0b\uff0c\u6211\u4eec\u90fd\u662f\u6839\u636e\u67d0\u4efd\u5217\u8868\u63a8\u5bfc\u51fa\u5176\u4ed6\u51e0\u4efd\u5217\u8868\uff0c\u7136\u540e\u628a\u8fd9\u4e9b\u5217\u8868\u4e00\u8d77\u5c01\u88c5\u5230zip\u91cc\u9762\uff0c\u5e76\u4fdd\u8bc1\u8fd9\u4e9b\u5217\u8868\u957f\u5ea6\u76f8\u540c\u3002 >>> names.append('Rosalind') >>> names ['Cecilia', 'Lise', 'Marie', 'Rosalind'] >>> for name, count in zip(names, counts): ... print(name) ... Cecilia Lise Marie \u5728\u5217\u8868\u957f\u5ea6\u4e0d\u540c\u7684\u60c5\u51b5\u4e0b\uff0c\u5982\u679c\u65e0\u6cd5\u786e\u5b9a\u8fd9\u4e9b\u5217\u8868\u7684\u957f\u5ea6\u76f8\u540c\uff0c\u90a3\u5c31\u4e0d\u8981\u628a\u5b83\u4eec\u4f20\u7ed9zip\uff0c\u800c\u662f\u5e94\u8be5\u4f20\u7ed9\u53e6\u4e00\u4e2a\u53eb\u4f5czip_longest\u7684\u51fd\u6570\uff0c\u8fd9\u4e2a\u51fd\u6570\u4f4d\u4e8e\u5185\u7f6e\u7684itertools\u6a21\u5757\u91cc\u3002 \u5982\u679c\u5176\u4e2d\u6709\u4e9b\u5217\u8868\u5df2\u7ecf\u904d\u5386\u5b8c\u4e86\uff0c\u90a3\u4e48zip_longest\u4f1a\u7528\u5f53\u521d\u4f20\u7ed9fillvalue\u53c2\u6570\u7684\u90a3\u4e2a\u503c\u6765\u586b\u8865\u7a7a\u7f3a\uff08\u672c\u4f8b\u4e2d\u7a7a\u7f3a\u7684\u4e3a\u5b57\u7b26\u4e32'Rosalind'\u7684\u957f\u5ea6\u503c\uff09\uff0c\u9ed8\u8ba4\u7684\u53c2\u6570\u503c\u662fNone\u3002 >>> import itertools >>> names = ['Cecilia', 'Lise', 'Marie'] >>> longest_name = None >>> max_count = 0 >>> counts = [len(n) for n in names] >>> names.append('Rosalind') >>> names ['Cecilia', 'Lise', 'Marie', 'Rosalind'] >>> counts [7, 4, 5] >>> for name, count in itertools.zip_longest(names, counts): ... print(f'{name}: {count}') ... Cecilia: 7 Lise: 4 Marie: 5 Rosalind: None \u8981\u70b9\uff1a \u5185\u7f6e\u7684zip\u51fd\u6570\u53ef\u4ee5\u540c\u65f6\u904d\u5386\u591a\u4e2a\u8fed\u4ee3\u5668\u3002 zip\u4f1a\u521b\u5efa\u60f0\u6027\u751f\u6210\u5668\uff0c\u8ba9\u5b83\u6bcf\u6b21\u53ea\u751f\u6210\u4e00\u4e2a\u5143\u7ec4\uff0c\u6240\u4ee5\u65e0\u8bba\u8f93\u5165\u7684\u6570\u636e\u6709\u591a\u957f\uff0c\u5b83\u90fd\u662f\u4e00\u4e2a\u4e00\u4e2a\u5904\u7406\u7684\u3002 \u5982\u679c\u63d0\u4f9b\u7684\u8fed\u4ee3\u5668\u7684\u957f\u5ea6\u4e0d\u4e00\u81f4\uff0c\u90a3\u4e48\u53ea\u8981\u5176\u4e2d\u4efb\u4f55\u4e00\u4e2a\u8fed\u4ee3\u5b8c\u6bd5\uff0czip\u5c31\u4f1a\u505c\u6b62\u3002 \u5982\u679c\u60f3\u6309\u6700\u957f\u7684\u90a3\u4e2a\u8fed\u4ee3\u5668\u6765\u904d\u5386\uff0c\u90a3\u5c31\u6539\u7528\u5185\u7f6e\u7684itertools\u6a21\u5757\u4e2d\u7684zip_longest\u51fd\u6570\u3002","title":"\u7b2c08\u6761 \u7528zip\u51fd\u6570\u540c\u65f6\u904d\u5386\u4e24\u4e2a\u8fed\u4ee3\u5668"},{"location":"python/Pythonic90Rules/Rule08/#8-zip","text":"\u5199Python\u4ee3\u7801\u65f6\uff0c\u7ecf\u5e38\u4f1a\u6839\u636e\u67d0\u4efd\u5217\u8868\u4e2d\u7684\u5bf9\u8c61\u521b\u5efa\u8bb8\u591a\u4e0e\u8fd9\u4efd\u5217\u8868\u6709\u5173\u7684\u65b0\u5217\u8868\u3002 \u4e0b\u9762\u8fd9\u6837\u7684\u5217\u8868\u63a8\u5bfc\u673a\u5236\uff0c\u53ef\u4ee5\u628a\u8868\u8fbe\u5f0f\u8fd0\u7528\u5230\u6e90\u5217\u8868\u7684\u6bcf\u4e2a\u5143\u7d20\u4e0a\u9762\uff0c\u4ece\u800c\u751f\u6210\u4e00\u4efd\u6d3e\u751f\u5217\u8868\uff08\u53c2\u89c1Rule27\uff09\u3002 >>> names = ['Cecilia', 'Lise', 'Marie'] >>> counts = [len(n) for n in names] >>> counts [7, 4, 5] \u6d3e\u751f\u5217\u8868\u4e2d\u7684\u5143\u7d20\u4e0e\u6e90\u5217\u8868\u4e2d\u5bf9\u5e94\u4f4d\u7f6e\u4e0a\u9762\u7684\u5143\u7d20\u6709\u7740\u4e00\u5b9a\u7684\u5173\u7cfb\u3002\u5982\u679c\u60f3\u540c\u65f6\u904d\u5386\u8fd9\u4e24\u4efd\u5217\u8868\uff0c\u90a3\u53ef\u4ee5\u6839\u636e\u6e90\u5217\u8868\u7684\u957f\u5ea6\u505a\u8fed\u4ee3\u3002 >>> names = ['Cecilia', 'Lise', 'Marie'] >>> longest_name = None >>> max_count = 0 >>> counts = [len(n) for n in names] >>> for i in range(len(names)): ... count = counts[i] ... if count > max_count: ... longest_name = names[i] ... max_count = count ... >>> longest_name 'Cecilia' \u7528enumerate\u6765\u6539\u5199\u4e0a\u9762\u7684\u4ee3\u7801\uff0c\u6539\u5584\u4e0a\u9762\u4ee3\u7801\u4e2d\u590d\u6742\u7684\u5faa\u73af\u5173\u7cfb\u3002 >>> names = ['Cecilia', 'Lise', 'Marie'] >>> longest_name = None >>> max_count = 0 >>> counts = [len(n) for n in names] >>> for i, name in enumerate(names): ... count = counts[i] ... if count > max_count: ... longest_name = name ... max_count = count ... >>> longest_name 'Cecilia' \u7528zip\u6765\u6539\u5199\u4ee3\u7801\uff0c\u4f7f\u4e4b\u66f4\u7b80\u6d01\u3002 zip\u51fd\u6570\u80fd\u628a\u4e24\u4e2a\u6216\u66f4\u591a\u7684iterator\u5c01\u88c5\u6210\u60f0\u6027\u751f\u6210\u5668\uff08lazy generator\uff09\u3002 \u6bcf\u6b21\u5faa\u73af\u65f6\uff0c\u5b83\u4f1a\u5206\u522b\u4ece\u8fd9\u4e9b\u8fed\u4ee3\u5668\u91cc\u83b7\u53d6\u5404\u81ea\u7684\u4e0b\u4e00\u4e2a\u5143\u7d20\uff0c\u5e76\u628a\u8fd9\u4e9b\u503c\u653e\u5728\u4e00\u4e2a\u5143\u7ec4\u91cc\u9762\u3002 zip\u6bcf\u6b21\u53ea\u4ece\u5b83\u5c01\u88c5\u7684\u90a3\u4e9b\u8fed\u4ee3\u5668\u91cc\u9762\u5404\u81ea\u53d6\u51fa\u4e00\u4e2a\u5143\u7d20\uff0c\u6240\u4ee5\u5373\u4fbf\u6e90\u5217\u8868\u5f88\u957f\uff0c\u7a0b\u5e8f\u4e5f\u4e0d\u4f1a\u56e0\u4e3a\u5360\u7528\u5185\u5b58\u8fc7\u591a\u800c\u5d29\u6e83\u3002 \u800c\u8fd9\u4e2a\u5143\u7ec4\u53ef\u4ee5\u62c6\u5206\u5230for\u8bed\u53e5\u91cc\u7684\u90a3\u4e9b\u53d8\u91cf\u4e4b\u4e2d\uff08\u53c2\u89c1Rule06\uff09\u3002 \u8fd9\u6837\u5199\u51fa\u6765\u7684\u4ee3\u7801\uff0c\u6bd4\u901a\u8fc7\u4e0b\u6807\u8bbf\u95ee\u591a\u4e2a\u5217\u8868\u7684\u90a3\u79cd\u4ee3\u7801\u8981\u6e05\u6670\u5f97\u591a\u3002 >>> names = ['Cecilia', 'Lise', 'Marie'] >>> longest_name = None >>> max_count = 0 >>> counts = [len(n) for n in names] >>> for name, count in zip(names, counts): ... if count > max_count: ... longest_name = name ... max_count = count ... >>> longest_name 'Cecilia' \u4f46\u662f\uff0c\u5982\u679c\u8f93\u5165zip\u7684\u90a3\u4e9b\u5217\u8868\u7684\u957f\u5ea6\u4e0d\u4e00\u81f4\uff0c\u7528zip\u540c\u65f6\u904d\u5386\u90a3\u4e9b\u5217\u8868\uff0c\u4f1a\u4ea7\u751f\u5947\u602a\u7684\u7ed3\u679c\u3002 \u4f8b\u5982\uff0c\u6211\u7ed9names\u5217\u8868\u91cc\u53c8\u6dfb\u52a0\u4e86\u4e00\u4e2a\u540d\u5b57\uff0c\u4f46\u662f\u5fd8\u4e86\u628a\u5b83\u7684\u957f\u5ea6\u66f4\u65b0\u5230counts\u5217\u8868\u4e4b\u4e2d\u3002 \u65b0\u6dfb\u52a0\u7684\u90a3\u4e2a'Rosalind' \u5143\u7d20\u4e0d\u4f1a\u88ab\u6253\u5370\u51fa\u6765\uff0c\u56e0\u4e3azip\u51fd\u6570\u5728\u6267\u884c\u4e2d\uff0c\u53ea\u8981\u5176\u4e2d\u4efb\u4f55\u4e00\u4e2a\u8fed\u4ee3\u5668\u5904\u7406\u5b8c\u6bd5\uff0c\u5b83\u5c31\u4e0d\u518d\u5f80\u4e0b\u8d70\u4e86\u3002 \u4e8e\u662f\uff0c\u5faa\u73af\u7684\u6b21\u6570\u5b9e\u9645\u4e0a\u7b49\u4e8e\u6700\u77ed\u7684\u90a3\u4efd\u5217\u8868\u6240\u5177\u5907\u7684\u957f\u5ea6\u3002 \u4e00\u822c\u60c5\u51b5\u4e0b\uff0c\u6211\u4eec\u90fd\u662f\u6839\u636e\u67d0\u4efd\u5217\u8868\u63a8\u5bfc\u51fa\u5176\u4ed6\u51e0\u4efd\u5217\u8868\uff0c\u7136\u540e\u628a\u8fd9\u4e9b\u5217\u8868\u4e00\u8d77\u5c01\u88c5\u5230zip\u91cc\u9762\uff0c\u5e76\u4fdd\u8bc1\u8fd9\u4e9b\u5217\u8868\u957f\u5ea6\u76f8\u540c\u3002 >>> names.append('Rosalind') >>> names ['Cecilia', 'Lise', 'Marie', 'Rosalind'] >>> for name, count in zip(names, counts): ... print(name) ... Cecilia Lise Marie \u5728\u5217\u8868\u957f\u5ea6\u4e0d\u540c\u7684\u60c5\u51b5\u4e0b\uff0c\u5982\u679c\u65e0\u6cd5\u786e\u5b9a\u8fd9\u4e9b\u5217\u8868\u7684\u957f\u5ea6\u76f8\u540c\uff0c\u90a3\u5c31\u4e0d\u8981\u628a\u5b83\u4eec\u4f20\u7ed9zip\uff0c\u800c\u662f\u5e94\u8be5\u4f20\u7ed9\u53e6\u4e00\u4e2a\u53eb\u4f5czip_longest\u7684\u51fd\u6570\uff0c\u8fd9\u4e2a\u51fd\u6570\u4f4d\u4e8e\u5185\u7f6e\u7684itertools\u6a21\u5757\u91cc\u3002 \u5982\u679c\u5176\u4e2d\u6709\u4e9b\u5217\u8868\u5df2\u7ecf\u904d\u5386\u5b8c\u4e86\uff0c\u90a3\u4e48zip_longest\u4f1a\u7528\u5f53\u521d\u4f20\u7ed9fillvalue\u53c2\u6570\u7684\u90a3\u4e2a\u503c\u6765\u586b\u8865\u7a7a\u7f3a\uff08\u672c\u4f8b\u4e2d\u7a7a\u7f3a\u7684\u4e3a\u5b57\u7b26\u4e32'Rosalind'\u7684\u957f\u5ea6\u503c\uff09\uff0c\u9ed8\u8ba4\u7684\u53c2\u6570\u503c\u662fNone\u3002 >>> import itertools >>> names = ['Cecilia', 'Lise', 'Marie'] >>> longest_name = None >>> max_count = 0 >>> counts = [len(n) for n in names] >>> names.append('Rosalind') >>> names ['Cecilia', 'Lise', 'Marie', 'Rosalind'] >>> counts [7, 4, 5] >>> for name, count in itertools.zip_longest(names, counts): ... print(f'{name}: {count}') ... Cecilia: 7 Lise: 4 Marie: 5 Rosalind: None \u8981\u70b9\uff1a \u5185\u7f6e\u7684zip\u51fd\u6570\u53ef\u4ee5\u540c\u65f6\u904d\u5386\u591a\u4e2a\u8fed\u4ee3\u5668\u3002 zip\u4f1a\u521b\u5efa\u60f0\u6027\u751f\u6210\u5668\uff0c\u8ba9\u5b83\u6bcf\u6b21\u53ea\u751f\u6210\u4e00\u4e2a\u5143\u7ec4\uff0c\u6240\u4ee5\u65e0\u8bba\u8f93\u5165\u7684\u6570\u636e\u6709\u591a\u957f\uff0c\u5b83\u90fd\u662f\u4e00\u4e2a\u4e00\u4e2a\u5904\u7406\u7684\u3002 \u5982\u679c\u63d0\u4f9b\u7684\u8fed\u4ee3\u5668\u7684\u957f\u5ea6\u4e0d\u4e00\u81f4\uff0c\u90a3\u4e48\u53ea\u8981\u5176\u4e2d\u4efb\u4f55\u4e00\u4e2a\u8fed\u4ee3\u5b8c\u6bd5\uff0czip\u5c31\u4f1a\u505c\u6b62\u3002 \u5982\u679c\u60f3\u6309\u6700\u957f\u7684\u90a3\u4e2a\u8fed\u4ee3\u5668\u6765\u904d\u5386\uff0c\u90a3\u5c31\u6539\u7528\u5185\u7f6e\u7684itertools\u6a21\u5757\u4e2d\u7684zip_longest\u51fd\u6570\u3002","title":"\u7b2c8\u6761\u3000\u7528zip\u51fd\u6570\u540c\u65f6\u904d\u5386\u4e24\u4e2a\u8fed\u4ee3\u5668"},{"location":"python/Pythonic90Rules/Rule09/","text":"\u7b2c9\u6761\u3000\u4e0d\u8981\u5728for\u4e0ewhile\u5faa\u73af\u540e\u9762\u5199else\u5757 \u00b6 Python\u7684\u5faa\u73af\u6709\u4e00\u9879\u5927\u591a\u6570\u7f16\u7a0b\u8bed\u8a00\u90fd\u4e0d\u652f\u6301\u7684\u7279\u6027\uff0c\u5373\u53ef\u4ee5\u628aelse\u5757\u7d27\u8ddf\u5728\u6574\u4e2a\u5faa\u73af\u7ed3\u6784\u7684\u540e\u9762\u3002 \u7a0b\u5e8f\u505a\u5b8c\u6574\u4e2afor\u5faa\u73af\u4e4b\u540e\uff0c\u7adf\u7136\u4f1a\u6267\u884celse\u5757\u91cc\u7684\u5185\u5bb9\u3002 >>> for i in range(3): ... print('loop', i) ... else: ... print('Else block!') ... loop 0 loop 1 loop 2 Else block! try/except/else\u7ed3\u6784\u91cc\u7684else\uff08\u53c2\u89c1Rule65\u6761\uff09\uff0c\u5b83\u7684\u610f\u601d\u662f\uff1a\u5982\u679c\u6ca1\u6709\u5f02\u5e38\u9700\u8981\u5904\u7406\uff0c\u90a3\u5c31\u6267\u884c\u8fd9\u5757\u8bed\u53e5\u3002 try/finally\u7ed3\u6784\u91cc\u7684finally\uff0c\u5b83\u7684\u610f\u601d\u662f\uff1a\u4e0d\u7ba1\u524d\u9762\u90a3\u5757\u4ee3\u7801\u6267\u884c\u5f97\u5982\u4f55\uff0c\u6700\u540e\u90fd\u8981\u6267\u884cfinally\u5757\u4ee3\u7801\u3002 for/else\u7ed3\u6784\u91cc\u9762\u7684else\uff0c\u5b83\u7684\u610f\u601d\u662f\uff1a\u5982\u679c\u5faa\u73af\u6ca1\u6709\u4ece\u5934\u5230\u5c3e\u6267\u884c\u5b8c\uff08\u4e5f\u5c31\u662f\u5faa\u73af\u63d0\u524d\u7ec8\u6b62\u4e86\uff09\uff0c\u90a3\u4e48else\u5757\u91cc\u7684\u4ee3\u7801\u662f\u4e0d\u4f1a\u6267\u884c\u7684\u3002\u5728\u5faa\u73af\u4e2d\u4f7f\u7528break\u8bed\u53e5\u5b9e\u9645\u4e0a\u4f1a\u8df3\u8fc7else\u5757\u3002 >>> for i in range(3): ... print('loop', i) ... if i == 1: ... break ... else: ... print('Else block!') ... loop 0 loop 1 \u8fd8\u6709\u4e00\u4e2a\u5947\u602a\u7684\u5730\u65b9\u662f\uff0c\u5982\u679c\u5bf9\u7a7a\u767d\u5e8f\u5217\u505afor\u5faa\u73af\uff0c\u90a3\u4e48\u7a0b\u5e8f\u7acb\u523b\u5c31\u4f1a\u6267\u884celse\u5757\u3002 >>> for x in []: ... print('Never Runs') ... else: ... print('For Else block!') ... For Else block! while\u5faa\u73af\u4e5f\u662f\u8fd9\u6837\uff0c\u5982\u679c\u9996\u6b21\u5faa\u73af\u5c31\u9047\u5230False\uff0c\u90a3\u4e48\u7a0b\u5e8f\u4e5f\u4f1a\u7acb\u523b\u8fd0\u884celse\u5757\u3002 >>> while True: ... print('Never runs') ... break ... else: ... print('While Else block!') ... Never runs >>> while False: ... print('Never runs') ... else: ... print('While Else block!') ... While Else block! Python\u628aelse\u8bbe\u8ba1\u6210\u8fd9\u6837\uff0c\u4e3b\u8981\u76ee\u7684\u662f\u5229\u7528\u5b83\u5b9e\u73b0\u641c\u7d22\u903b\u8f91\u3002 \u4f8b\u5982\u4e0b\u9762\u4ee3\u7801\uff0c\u5982\u679c\u8981\u5224\u65ad\u4e24\u4e2a\u6570\u662f\u5426\u4e92\u8d28\uff08\u4e5f\u5c31\u662f\u9664\u4e861\u4e4b\u5916\uff0c\u662f\u4e0d\u662f\u6ca1\u6709\u522b\u7684\u6570\u80fd\u591f\u540c\u65f6\u6574\u9664\u5b83\u4eec\uff09\uff0c\u5c31\u53ef\u4ee5\u7528\u8fd9\u79cd\u7ed3\u6784\u5b9e\u73b0\u3002 \u5148\u628a\u6709\u53ef\u80fd\u540c\u65f6\u6574\u9664\u5b83\u4eec\u7684\u6570\u9010\u4e2a\u8bd5\u4e00\u904d\uff0c\u5982\u679c\u5168\u90fd\u8bd5\u8fc7\u4e4b\u540e\u8fd8\u662f\u6ca1\u627e\u5230\u8fd9\u6837\u7684\u6570\uff0c \u90a3\u4e48\u5faa\u73af\u5c31\u4f1a\u4ece\u5934\u5230\u5c3e\u6267\u884c\u5b8c\uff08\u8fd9\u610f\u5473\u7740\u5faa\u73af\u6ca1\u6709\u56e0\u4e3abreak\u800c\u63d0\u524d\u8df3\u51fa\uff09\uff0c \u7136\u540e\u7a0b\u5e8f\u5c31\u4f1a\u6267\u884celse\u5757\u91cc\u7684\u4ee3\u7801\u3002 >>> for i in range(2, min(a, b) + 1): ... print('Testing', i) ... if a % i == 0 and b% i == 0: ... print('Not coprime') ... else: ... print('Coprime') ... Testing 2 Testing 3 Testing 4 Coprime \u5b9e\u9645\u5de5\u4f5c\u4e2d\uff0c\u4e0a\u8ff0\u4ee3\u7801\u4f1a\u6539\u7528\u8f85\u52a9\u51fd\u6570\u5b8c\u6210\u3002\u8fd9\u6837\u7684\u8f85\u52a9\u51fd\u6570\u6709\u4e24\u79cd\u5e38\u89c1\u7684\u5199\u6cd5\u3002 \u7b2c\u4e00\u79cd\u5199\u6cd5\u662f\uff0c\u53ea\u8981\u53d1\u73b0\u67d0\u4e2a\u6761\u4ef6\u6210\u7acb\uff0c\u5c31\u7acb\u523b\u8fd4\u56de\uff0c\u5982\u679c\u59cb\u7ec8\u90fd\u6ca1\u78b0\u5230\u8fd9\u79cd\u60c5\u51b5\uff0c\u90a3\u4e48\u5faa\u73af\u5c31\u4f1a\u5b8c\u6574\u5730\u6267\u884c\uff0c\u8ba9\u7a0b\u5e8f\u8fd4\u56de\u51fd\u6570\u672b\u5c3e\u7684\u90a3\u4e2a\u503c\u4f5c\u4e3a\u9ed8\u8ba4\u8fd4\u56de\u503c\u3002 >>> def coprime(a, b): ... for i in range(2, min(a, b) + 1): ... if a % i == 0 and b% i == 0: ... return False ... return True ... >>> assert coprime(4, 9) >>> assert not coprime(4, 9) Traceback (most recent call last): File \"\", line 1, in AssertionError >>> assert coprime(3, 6) Traceback (most recent call last): File \"\", line 1, in AssertionError >>> assert not coprime(3, 6) >>> \u7b2c\u4e8c\u79cd\u5199\u6cd5\u662f\uff0c\u7528\u53d8\u91cf\u6765\u8bb0\u5f55\u5faa\u73af\u8fc7\u7a0b\u4e2d\u6709\u6ca1\u6709\u78b0\u5230\u8fd9\u6837\u7684\u60c5\u51b5\uff0c\u5982\u679c\u6709\uff0c\u90a3\u5c31\u7528break\u63d0\u524d\u8df3\u51fa\u5faa\u73af\uff0c\u5982\u679c\u6ca1\u6709\uff0c\u5faa\u73af\u5c31\u4f1a\u5b8c\u6574\u5730\u6267\u884c\uff0c\u65e0\u8bba\u5982\u4f55\uff0c\u6700\u540e\u90fd\u8fd4\u56de\u8fd9\u4e2a\u53d8\u91cf\u7684\u503c\u3002 >>> def coprime_alternate(a, b): ... is_coprime = True ... for i in range(2, min(a, b) + 1): ... if a % i == 0 and b% i == 0: ... is_coprime = False ... break ... return is_coprime ... >>> assert coprime_alternate(4, 9) >>> assert not coprime_alternate(4, 9) Traceback (most recent call last): File \"\", line 1, in AssertionError >>> assert coprime_alternate(3, 6) Traceback (most recent call last): File \"\", line 1, in AssertionError >>> assert not coprime_alternate(3, 6) >>> \u5bf9\u4e8e\u4e0d\u719f\u6089for/else\u7ed3\u6784\u7684\u4eba\u6765\u8bf4\uff0c\u521a\u624d\u90a3\u4e24\u79cd\u5199\u6cd5\u90fd\u662f\u6bd4\u8f83\u6e05\u6670\u7684\u65b9\u6848\u3002 for/else\u6216while/else\u7ed3\u6784\u672c\u8eab\u867d\u7136\u53ef\u4ee5\u5b9e\u73b0\u67d0\u4e9b\u903b\u8f91\u8868\u8fbe\uff0c\u4f46\u5b83\u5e26\u6765\u7684\u56f0\u60d1\u5df2\u7ecf\u76d6\u8fc7\u4e86\u5b83\u7684\u597d\u5904\uff0c\u4f1a\u8ba9\u4ee3\u7801\u4ea7\u751f\u6b67\u4e49\u3002\u6240\u4ee5\uff0c\u8bf7\u4e0d\u8981\u8fd9\u4e48\u5199\u3002 \u8981\u70b9\uff1a * Python\u6709\u79cd\u7279\u6b8a\u7684\u8bed\u6cd5\uff0c\u53ef\u4ee5\u628aelse\u5757\u7d27\u8ddf\u5728\u6574\u4e2afor\u5faa\u73af\u6216while\u5faa\u73af\u7684\u540e\u9762\u3002 * \u53ea\u6709\u5728\u6574\u4e2a\u5faa\u73af\u6ca1\u6709\u56e0\u4e3abreak\u63d0\u524d\u8df3\u51fa\u7684\u60c5\u51b5\u4e0b\uff0celse\u5757\u624d\u4f1a\u6267\u884c\u3002 * \u628aelse\u5757\u7d27\u8ddf\u5728\u6574\u4e2a\u5faa\u73af\u540e\u9762\uff0c\u4f1a\u8ba9\u4eba\u4e0d\u592a\u5bb9\u6613\u770b\u51fa\u8fd9\u6bb5\u4ee3\u7801\u7684\u610f\u601d\uff0c\u6240\u4ee5\u8981\u907f\u514d\u8fd9\u6837\u5199\u3002","title":"\u7b2c09\u6761 \u4e0d\u8981\u5728for\u4e0ewhile\u5faa\u73af\u540e\u9762\u5199else\u5757"},{"location":"python/Pythonic90Rules/Rule09/#9-forwhileelse","text":"Python\u7684\u5faa\u73af\u6709\u4e00\u9879\u5927\u591a\u6570\u7f16\u7a0b\u8bed\u8a00\u90fd\u4e0d\u652f\u6301\u7684\u7279\u6027\uff0c\u5373\u53ef\u4ee5\u628aelse\u5757\u7d27\u8ddf\u5728\u6574\u4e2a\u5faa\u73af\u7ed3\u6784\u7684\u540e\u9762\u3002 \u7a0b\u5e8f\u505a\u5b8c\u6574\u4e2afor\u5faa\u73af\u4e4b\u540e\uff0c\u7adf\u7136\u4f1a\u6267\u884celse\u5757\u91cc\u7684\u5185\u5bb9\u3002 >>> for i in range(3): ... print('loop', i) ... else: ... print('Else block!') ... loop 0 loop 1 loop 2 Else block! try/except/else\u7ed3\u6784\u91cc\u7684else\uff08\u53c2\u89c1Rule65\u6761\uff09\uff0c\u5b83\u7684\u610f\u601d\u662f\uff1a\u5982\u679c\u6ca1\u6709\u5f02\u5e38\u9700\u8981\u5904\u7406\uff0c\u90a3\u5c31\u6267\u884c\u8fd9\u5757\u8bed\u53e5\u3002 try/finally\u7ed3\u6784\u91cc\u7684finally\uff0c\u5b83\u7684\u610f\u601d\u662f\uff1a\u4e0d\u7ba1\u524d\u9762\u90a3\u5757\u4ee3\u7801\u6267\u884c\u5f97\u5982\u4f55\uff0c\u6700\u540e\u90fd\u8981\u6267\u884cfinally\u5757\u4ee3\u7801\u3002 for/else\u7ed3\u6784\u91cc\u9762\u7684else\uff0c\u5b83\u7684\u610f\u601d\u662f\uff1a\u5982\u679c\u5faa\u73af\u6ca1\u6709\u4ece\u5934\u5230\u5c3e\u6267\u884c\u5b8c\uff08\u4e5f\u5c31\u662f\u5faa\u73af\u63d0\u524d\u7ec8\u6b62\u4e86\uff09\uff0c\u90a3\u4e48else\u5757\u91cc\u7684\u4ee3\u7801\u662f\u4e0d\u4f1a\u6267\u884c\u7684\u3002\u5728\u5faa\u73af\u4e2d\u4f7f\u7528break\u8bed\u53e5\u5b9e\u9645\u4e0a\u4f1a\u8df3\u8fc7else\u5757\u3002 >>> for i in range(3): ... print('loop', i) ... if i == 1: ... break ... else: ... print('Else block!') ... loop 0 loop 1 \u8fd8\u6709\u4e00\u4e2a\u5947\u602a\u7684\u5730\u65b9\u662f\uff0c\u5982\u679c\u5bf9\u7a7a\u767d\u5e8f\u5217\u505afor\u5faa\u73af\uff0c\u90a3\u4e48\u7a0b\u5e8f\u7acb\u523b\u5c31\u4f1a\u6267\u884celse\u5757\u3002 >>> for x in []: ... print('Never Runs') ... else: ... print('For Else block!') ... For Else block! while\u5faa\u73af\u4e5f\u662f\u8fd9\u6837\uff0c\u5982\u679c\u9996\u6b21\u5faa\u73af\u5c31\u9047\u5230False\uff0c\u90a3\u4e48\u7a0b\u5e8f\u4e5f\u4f1a\u7acb\u523b\u8fd0\u884celse\u5757\u3002 >>> while True: ... print('Never runs') ... break ... else: ... print('While Else block!') ... Never runs >>> while False: ... print('Never runs') ... else: ... print('While Else block!') ... While Else block! Python\u628aelse\u8bbe\u8ba1\u6210\u8fd9\u6837\uff0c\u4e3b\u8981\u76ee\u7684\u662f\u5229\u7528\u5b83\u5b9e\u73b0\u641c\u7d22\u903b\u8f91\u3002 \u4f8b\u5982\u4e0b\u9762\u4ee3\u7801\uff0c\u5982\u679c\u8981\u5224\u65ad\u4e24\u4e2a\u6570\u662f\u5426\u4e92\u8d28\uff08\u4e5f\u5c31\u662f\u9664\u4e861\u4e4b\u5916\uff0c\u662f\u4e0d\u662f\u6ca1\u6709\u522b\u7684\u6570\u80fd\u591f\u540c\u65f6\u6574\u9664\u5b83\u4eec\uff09\uff0c\u5c31\u53ef\u4ee5\u7528\u8fd9\u79cd\u7ed3\u6784\u5b9e\u73b0\u3002 \u5148\u628a\u6709\u53ef\u80fd\u540c\u65f6\u6574\u9664\u5b83\u4eec\u7684\u6570\u9010\u4e2a\u8bd5\u4e00\u904d\uff0c\u5982\u679c\u5168\u90fd\u8bd5\u8fc7\u4e4b\u540e\u8fd8\u662f\u6ca1\u627e\u5230\u8fd9\u6837\u7684\u6570\uff0c \u90a3\u4e48\u5faa\u73af\u5c31\u4f1a\u4ece\u5934\u5230\u5c3e\u6267\u884c\u5b8c\uff08\u8fd9\u610f\u5473\u7740\u5faa\u73af\u6ca1\u6709\u56e0\u4e3abreak\u800c\u63d0\u524d\u8df3\u51fa\uff09\uff0c \u7136\u540e\u7a0b\u5e8f\u5c31\u4f1a\u6267\u884celse\u5757\u91cc\u7684\u4ee3\u7801\u3002 >>> for i in range(2, min(a, b) + 1): ... print('Testing', i) ... if a % i == 0 and b% i == 0: ... print('Not coprime') ... else: ... print('Coprime') ... Testing 2 Testing 3 Testing 4 Coprime \u5b9e\u9645\u5de5\u4f5c\u4e2d\uff0c\u4e0a\u8ff0\u4ee3\u7801\u4f1a\u6539\u7528\u8f85\u52a9\u51fd\u6570\u5b8c\u6210\u3002\u8fd9\u6837\u7684\u8f85\u52a9\u51fd\u6570\u6709\u4e24\u79cd\u5e38\u89c1\u7684\u5199\u6cd5\u3002 \u7b2c\u4e00\u79cd\u5199\u6cd5\u662f\uff0c\u53ea\u8981\u53d1\u73b0\u67d0\u4e2a\u6761\u4ef6\u6210\u7acb\uff0c\u5c31\u7acb\u523b\u8fd4\u56de\uff0c\u5982\u679c\u59cb\u7ec8\u90fd\u6ca1\u78b0\u5230\u8fd9\u79cd\u60c5\u51b5\uff0c\u90a3\u4e48\u5faa\u73af\u5c31\u4f1a\u5b8c\u6574\u5730\u6267\u884c\uff0c\u8ba9\u7a0b\u5e8f\u8fd4\u56de\u51fd\u6570\u672b\u5c3e\u7684\u90a3\u4e2a\u503c\u4f5c\u4e3a\u9ed8\u8ba4\u8fd4\u56de\u503c\u3002 >>> def coprime(a, b): ... for i in range(2, min(a, b) + 1): ... if a % i == 0 and b% i == 0: ... return False ... return True ... >>> assert coprime(4, 9) >>> assert not coprime(4, 9) Traceback (most recent call last): File \"\", line 1, in AssertionError >>> assert coprime(3, 6) Traceback (most recent call last): File \"\", line 1, in AssertionError >>> assert not coprime(3, 6) >>> \u7b2c\u4e8c\u79cd\u5199\u6cd5\u662f\uff0c\u7528\u53d8\u91cf\u6765\u8bb0\u5f55\u5faa\u73af\u8fc7\u7a0b\u4e2d\u6709\u6ca1\u6709\u78b0\u5230\u8fd9\u6837\u7684\u60c5\u51b5\uff0c\u5982\u679c\u6709\uff0c\u90a3\u5c31\u7528break\u63d0\u524d\u8df3\u51fa\u5faa\u73af\uff0c\u5982\u679c\u6ca1\u6709\uff0c\u5faa\u73af\u5c31\u4f1a\u5b8c\u6574\u5730\u6267\u884c\uff0c\u65e0\u8bba\u5982\u4f55\uff0c\u6700\u540e\u90fd\u8fd4\u56de\u8fd9\u4e2a\u53d8\u91cf\u7684\u503c\u3002 >>> def coprime_alternate(a, b): ... is_coprime = True ... for i in range(2, min(a, b) + 1): ... if a % i == 0 and b% i == 0: ... is_coprime = False ... break ... return is_coprime ... >>> assert coprime_alternate(4, 9) >>> assert not coprime_alternate(4, 9) Traceback (most recent call last): File \"\", line 1, in AssertionError >>> assert coprime_alternate(3, 6) Traceback (most recent call last): File \"\", line 1, in AssertionError >>> assert not coprime_alternate(3, 6) >>> \u5bf9\u4e8e\u4e0d\u719f\u6089for/else\u7ed3\u6784\u7684\u4eba\u6765\u8bf4\uff0c\u521a\u624d\u90a3\u4e24\u79cd\u5199\u6cd5\u90fd\u662f\u6bd4\u8f83\u6e05\u6670\u7684\u65b9\u6848\u3002 for/else\u6216while/else\u7ed3\u6784\u672c\u8eab\u867d\u7136\u53ef\u4ee5\u5b9e\u73b0\u67d0\u4e9b\u903b\u8f91\u8868\u8fbe\uff0c\u4f46\u5b83\u5e26\u6765\u7684\u56f0\u60d1\u5df2\u7ecf\u76d6\u8fc7\u4e86\u5b83\u7684\u597d\u5904\uff0c\u4f1a\u8ba9\u4ee3\u7801\u4ea7\u751f\u6b67\u4e49\u3002\u6240\u4ee5\uff0c\u8bf7\u4e0d\u8981\u8fd9\u4e48\u5199\u3002 \u8981\u70b9\uff1a * Python\u6709\u79cd\u7279\u6b8a\u7684\u8bed\u6cd5\uff0c\u53ef\u4ee5\u628aelse\u5757\u7d27\u8ddf\u5728\u6574\u4e2afor\u5faa\u73af\u6216while\u5faa\u73af\u7684\u540e\u9762\u3002 * \u53ea\u6709\u5728\u6574\u4e2a\u5faa\u73af\u6ca1\u6709\u56e0\u4e3abreak\u63d0\u524d\u8df3\u51fa\u7684\u60c5\u51b5\u4e0b\uff0celse\u5757\u624d\u4f1a\u6267\u884c\u3002 * \u628aelse\u5757\u7d27\u8ddf\u5728\u6574\u4e2a\u5faa\u73af\u540e\u9762\uff0c\u4f1a\u8ba9\u4eba\u4e0d\u592a\u5bb9\u6613\u770b\u51fa\u8fd9\u6bb5\u4ee3\u7801\u7684\u610f\u601d\uff0c\u6240\u4ee5\u8981\u907f\u514d\u8fd9\u6837\u5199\u3002","title":"\u7b2c9\u6761\u3000\u4e0d\u8981\u5728for\u4e0ewhile\u5faa\u73af\u540e\u9762\u5199else\u5757"},{"location":"python/Pythonic90Rules/Rule10/","text":"\u7b2c10\u6761\u3000\u7528\u8d4b\u503c\u8868\u8fbe\u5f0f\u51cf\u5c11\u91cd\u590d\u4ee3\u7801 \u00b6 \u8d4b\u503c\u8868\u8fbe\u5f0f\uff08assignment expression\uff09\u662fPython 3.8\u65b0\u5f15\u5165\u7684\u8bed\u6cd5\uff0c\u5b83\u4f1a\u7528\u5230\u6d77\u8c61\u64cd\u4f5c\u7b26\uff08walrusoperator\uff09\u3002 a = b\u662f\u666e\u901a\u7684\u8d4b\u503c\u8bed\u53e5\uff0c\u8bfb\u4f5ca equals b\uff0c\u800ca := b\u5219\u662f\u8d4b\u503c\u8868\u8fbe\u5f0f\uff0c\u8bfb\u4f5ca walrus b\u3002 \u8fd9\u4e2a\u7b26\u53f7\u4e3a\u4ec0\u4e48\u53ebwalrus\u5462\uff1f\u56e0\u4e3a\u628a:=\u987a\u65f6\u9488\u65cb\u8f6c90\u00ba\u4e4b\u540e\uff0c\u5192\u53f7\u5c31\u662f\u6d77\u8c61\u7684\u4e00\u53cc\u773c\u775b\uff0c\u7b49\u53f7\u5c31\u662f\u5b83\u7684\u4e00\u5bf9\u7360\u7259\u3002 \u5728Python\u91cc\u9762\u7ecf\u5e38\u8981\u5148\u83b7\u53d6\u67d0\u4e2a\u503c\uff0c\u7136\u540e\u5224\u65ad\u5b83\u662f\u5426\u975e\u96f6\uff0c\u5982\u679c\u662f\u5c31\u6267\u884c\u67d0\u6bb5\u4ee3\u7801\u3002 fresh_fruit = { 'apple': 10, 'banana': 8, 'lemon': 5 } count = fresh_fruit.get('lemon', 0) if count: print('Stock:', count) else: print('Out of Stock') Result: Stock: 5 \u4e0a\u9762\u7684\u4ee3\u7801\u6539\u7528\u6d77\u8c61\u64cd\u4f5c\u7b26\u6765\u5199\uff1a fresh_fruit = { 'apple': 10, 'banana': 8, 'lemon': 5 } if count := fresh_fruit.get('lemon', 0): print('Stock:', count) else: print('Out of Stock') Result: Stock: 5 \u65b0\u4ee3\u7801\u867d\u7136\u53ea\u7701\u4e86\u4e00\u884c\uff0c\u4f46\u8bfb\u8d77\u6765\u5374\u6e05\u6670\u5f88\u591a\uff0c\u56e0\u4e3a\u8fd9\u79cd\u5199\u6cd5\u660e\u786e\u4f53\u73b0\u51facount\u53d8\u91cf\u53ea\u4e0eif\u5757\u6709\u5173\u3002 \u8fd9\u4e2a\u8d4b\u503c\u8868\u8fbe\u5f0f\u5148\u628a:=\u53f3\u8fb9\u7684\u503c\u8d4b\u7ed9\u5de6\u8fb9\u7684count\u53d8\u91cf\uff0c\u7136\u540e\u5bf9\u81ea\u8eab\u6c42\u503c\uff0c\u4e5f\u5c31\u662f\u628a\u53d8\u91cf\u7684\u503c\u5f53\u6210\u6574\u4e2a\u8868\u8fbe\u5f0f\u7684\u503c\u3002 \u7531\u4e8e\u8868\u8fbe\u5f0f\u7d27\u8ddf\u7740if\uff0c\u7a0b\u5e8f\u4f1a\u6839\u636e\u5b83\u7684\u503c\u662f\u5426\u975e\u96f6\u6765\u51b3\u5b9a\u8be5\u4e0d\u8be5\u6267\u884cif\u5757\u3002 \u8fd9\u79cd\u5148\u8d4b\u503c\u518d\u5224\u65ad\u7684\u505a\u6cd5\uff0c\u6b63\u662f\u6d77\u8c61\u64cd\u4f5c\u7b26\u60f3\u8981\u8868\u8fbe\u7684\u610f\u601d\u3002 \u4e0b\u9762\u7684\u4f8b\u5b50\u628a\u8d4b\u503c\u8868\u8fbe\u5f0f\u653e\u5728\u4e00\u5bf9\u62ec\u53f7\u91cc\u9762\u7684\uff0c\u56e0\u4e3a\u6211\u4eec\u8981\u5728if\u8bed\u53e5\u91cc\u9762\u628a\u8fd9\u4e2a\u8868\u8fbe\u5f0f\u7684\u7ed3\u679c\u8ddf4\u8fd9\u4e2a\u503c\u76f8\u6bd4\u8f83\u3002\u800c\u4e14\uff0c\u901a\u8fc7\u4f7f\u7528\u6d77\u8c61\u64cd\u4f5c\u7b26\u628a\u5b9a\u4e49pieces\u653e\u5728if/else\u5206\u652f\u5185\uff0c\u4e5f\u80fd\u8ba9\u4ee3\u7801\u53d8\u5f97\u6e05\u6670 fresh_fruit = { 'apple': 10, 'banana': 8, 'lemon': 5 } pieces = 0 if (count := fresh_fruit.get('apple', 2)) > 4: pieces = count print('Stock:', count) else: pieces = 0 print('Out of Stock') \u4f7f\u7528\u6d77\u8c61\u64cd\u4f5c\u7b26\u7ed3\u6784\u5b9e\u73b0switch/case\u7ed3\u6784\u3002 fresh_fruit = { 'apple': 10, 'banana': 8, 'lemon': 5 } pieces = 0 if (count := fresh_fruit.get('apple', 2)) > 10: pieces = count elif (count := fresh_fruit.get('banana', 2)) > 8: pieces = count elif (count := fresh_fruit.get('lemon', 2)) > 3: pieces = count else: pieces = 0 print(pieces) Result: 5 \u8981\u70b9\uff1a * \u8d4b\u503c\u8868\u8fbe\u5f0f\u901a\u8fc7\u6d77\u8c61\u64cd\u4f5c\u7b26\uff08:=\uff09\u7ed9\u53d8\u91cf\u8d4b\u503c\uff0c\u5e76\u4e14\u8ba9\u8fd9\u4e2a\u503c\u6210\u4e3a\u8fd9\u6761\u8868\u8fbe\u5f0f\u7684\u7ed3\u679c\uff0c\u4e8e\u662f\uff0c\u6211\u4eec\u53ef\u4ee5\u5229\u7528\u8fd9\u9879\u7279\u6027\u6765\u7f29\u51cf\u4ee3\u7801\u3002 * \u5982\u679c\u8d4b\u503c\u8868\u8fbe\u5f0f\u662f\u5927\u8868\u8fbe\u5f0f\u91cc\u7684\u4e00\u90e8\u5206\uff0c\u5c31\u5f97\u7528\u4e00\u5bf9\u62ec\u53f7\u628a\u5b83\u62ec\u8d77\u6765\u3002 * \u867d\u8bf4Python\u4e0d\u652f\u6301switch/case\u4e0edo/while\u7ed3\u6784\uff0c\u4f46\u53ef\u4ee5\u5229\u7528\u8d4b\u503c\u8868\u8fbe\u5f0f\u6e05\u6670\u5730\u6a21\u62df\u51fa\u8fd9\u79cd\u903b\u8f91\u3002 \u8865\u5145\uff1aPEP572: \u6d77\u8c61\u8fd0\u7b97\u7b26 \u00b6 \u7528\u4e8e if-else \u6761\u4ef6\u8868\u8fbe\u5f0f \u00b6 \u4e00\u822c\u5199\u6cd5\uff1a a = 15 if a > 10: print('hello, it''s walrus') \u6d77\u8c61\u8fd0\u7b97\u7b26\uff1a if a := 15 > 10: print('hello, it''s walrus') \u7528\u4e8e while \u5faa\u73af \u00b6 \u5e38\u89c4\u5199\u6cd5\uff1a n = 5 while n: print('hello walrus: ', n) n = n - 1 Result: hello walrus: 4 hello walrus: 3 hello walrus: 2 hello walrus: 1 hello walrus: 0 \u6d77\u8c61\u5199\u6cd5\uff1a n = 5 while (n := n - 1) + 1: print('hello walrus: ', n) Result: hello walrus: 4 hello walrus: 3 hello walrus: 2 hello walrus: 1 hello walrus: 0 \u5bc6\u7801\u6821\u9a8c\u5e38\u89c4\u5199\u6cd5\uff1a while True: psw = input('input password: ') if psw == '123': break \u5bc6\u7801\u6821\u9a8c\u6d77\u8c61\u5199\u6cd5\uff1a while (psw := input('input password: ')) != '123': continue \u7528\u4e8e\u5217\u8868\u63a8\u5bfc\u5f0f \u00b6 \u8ba1\u7b97\u5143\u7d20\u5e73\u65b9\u6839\uff0c\u5e76\u4fdd\u7559\u5e73\u65b9\u6839\u5927\u4e8e 5 \u7684\u503c\uff1a \u5e38\u89c4\u5199\u6cd5\uff1a(\u6ce8\u610f\uff0c\u6267\u884c\u4e867\u6b21\uff0c\u6ee1\u8db3\u6761\u4ef6\u76843\u4e2a\u6570\u5b57\u6267\u884c\u4e86\u4e24\u904d\uff0c\u7b2c\u4e00\u6b21\u6267\u884cfor\u540e\u9762\u7684if f(i) > 5\uff0c\u7b2c\u4e8c\u6b21\u6267\u884cfor\u524d\u9762\u7684f(i))\u3002 nums = [16, 36, 49, 64] def f(x): print('run f(x) 1 time: ', x) return x ** 0.5 print([f(i) for i in nums if f(i) > 5]) Result: run f(x) 1 time: 16 run f(x) 1 time: 36 run f(x) 1 time: 36 run f(x) 1 time: 49 run f(x) 1 time: 49 run f(x) 1 time: 64 run f(x) 1 time: 64 [6.0, 7.0, 8.0] \u6d77\u8c61\u5199\u6cd5\uff1a\uff08\u51fd\u6570\u53ea\u6267\u884c\u4e864\u6b21\uff0c\u6027\u80fd\u4f18\u4e8e\u4f20\u7edf\u5199\u6cd5\uff09 nums = [16, 36, 49, 64] def f(x): print('run f(x) 1 time: ', x) return x ** 0.5 print([n for i in nums if(n := f(i)) > 5]) Result: run f(x) 1 time: 16 run f(x) 1 time: 36 run f(x) 1 time: 49 run f(x) 1 time: 64 [6.0, 7.0, 8.0]","title":"\u7b2c10\u6761 \u7528\u8d4b\u503c\u8868\u8fbe\u5f0f\u51cf\u5c11\u91cd\u590d\u4ee3\u7801"},{"location":"python/Pythonic90Rules/Rule10/#10","text":"\u8d4b\u503c\u8868\u8fbe\u5f0f\uff08assignment expression\uff09\u662fPython 3.8\u65b0\u5f15\u5165\u7684\u8bed\u6cd5\uff0c\u5b83\u4f1a\u7528\u5230\u6d77\u8c61\u64cd\u4f5c\u7b26\uff08walrusoperator\uff09\u3002 a = b\u662f\u666e\u901a\u7684\u8d4b\u503c\u8bed\u53e5\uff0c\u8bfb\u4f5ca equals b\uff0c\u800ca := b\u5219\u662f\u8d4b\u503c\u8868\u8fbe\u5f0f\uff0c\u8bfb\u4f5ca walrus b\u3002 \u8fd9\u4e2a\u7b26\u53f7\u4e3a\u4ec0\u4e48\u53ebwalrus\u5462\uff1f\u56e0\u4e3a\u628a:=\u987a\u65f6\u9488\u65cb\u8f6c90\u00ba\u4e4b\u540e\uff0c\u5192\u53f7\u5c31\u662f\u6d77\u8c61\u7684\u4e00\u53cc\u773c\u775b\uff0c\u7b49\u53f7\u5c31\u662f\u5b83\u7684\u4e00\u5bf9\u7360\u7259\u3002 \u5728Python\u91cc\u9762\u7ecf\u5e38\u8981\u5148\u83b7\u53d6\u67d0\u4e2a\u503c\uff0c\u7136\u540e\u5224\u65ad\u5b83\u662f\u5426\u975e\u96f6\uff0c\u5982\u679c\u662f\u5c31\u6267\u884c\u67d0\u6bb5\u4ee3\u7801\u3002 fresh_fruit = { 'apple': 10, 'banana': 8, 'lemon': 5 } count = fresh_fruit.get('lemon', 0) if count: print('Stock:', count) else: print('Out of Stock') Result: Stock: 5 \u4e0a\u9762\u7684\u4ee3\u7801\u6539\u7528\u6d77\u8c61\u64cd\u4f5c\u7b26\u6765\u5199\uff1a fresh_fruit = { 'apple': 10, 'banana': 8, 'lemon': 5 } if count := fresh_fruit.get('lemon', 0): print('Stock:', count) else: print('Out of Stock') Result: Stock: 5 \u65b0\u4ee3\u7801\u867d\u7136\u53ea\u7701\u4e86\u4e00\u884c\uff0c\u4f46\u8bfb\u8d77\u6765\u5374\u6e05\u6670\u5f88\u591a\uff0c\u56e0\u4e3a\u8fd9\u79cd\u5199\u6cd5\u660e\u786e\u4f53\u73b0\u51facount\u53d8\u91cf\u53ea\u4e0eif\u5757\u6709\u5173\u3002 \u8fd9\u4e2a\u8d4b\u503c\u8868\u8fbe\u5f0f\u5148\u628a:=\u53f3\u8fb9\u7684\u503c\u8d4b\u7ed9\u5de6\u8fb9\u7684count\u53d8\u91cf\uff0c\u7136\u540e\u5bf9\u81ea\u8eab\u6c42\u503c\uff0c\u4e5f\u5c31\u662f\u628a\u53d8\u91cf\u7684\u503c\u5f53\u6210\u6574\u4e2a\u8868\u8fbe\u5f0f\u7684\u503c\u3002 \u7531\u4e8e\u8868\u8fbe\u5f0f\u7d27\u8ddf\u7740if\uff0c\u7a0b\u5e8f\u4f1a\u6839\u636e\u5b83\u7684\u503c\u662f\u5426\u975e\u96f6\u6765\u51b3\u5b9a\u8be5\u4e0d\u8be5\u6267\u884cif\u5757\u3002 \u8fd9\u79cd\u5148\u8d4b\u503c\u518d\u5224\u65ad\u7684\u505a\u6cd5\uff0c\u6b63\u662f\u6d77\u8c61\u64cd\u4f5c\u7b26\u60f3\u8981\u8868\u8fbe\u7684\u610f\u601d\u3002 \u4e0b\u9762\u7684\u4f8b\u5b50\u628a\u8d4b\u503c\u8868\u8fbe\u5f0f\u653e\u5728\u4e00\u5bf9\u62ec\u53f7\u91cc\u9762\u7684\uff0c\u56e0\u4e3a\u6211\u4eec\u8981\u5728if\u8bed\u53e5\u91cc\u9762\u628a\u8fd9\u4e2a\u8868\u8fbe\u5f0f\u7684\u7ed3\u679c\u8ddf4\u8fd9\u4e2a\u503c\u76f8\u6bd4\u8f83\u3002\u800c\u4e14\uff0c\u901a\u8fc7\u4f7f\u7528\u6d77\u8c61\u64cd\u4f5c\u7b26\u628a\u5b9a\u4e49pieces\u653e\u5728if/else\u5206\u652f\u5185\uff0c\u4e5f\u80fd\u8ba9\u4ee3\u7801\u53d8\u5f97\u6e05\u6670 fresh_fruit = { 'apple': 10, 'banana': 8, 'lemon': 5 } pieces = 0 if (count := fresh_fruit.get('apple', 2)) > 4: pieces = count print('Stock:', count) else: pieces = 0 print('Out of Stock') \u4f7f\u7528\u6d77\u8c61\u64cd\u4f5c\u7b26\u7ed3\u6784\u5b9e\u73b0switch/case\u7ed3\u6784\u3002 fresh_fruit = { 'apple': 10, 'banana': 8, 'lemon': 5 } pieces = 0 if (count := fresh_fruit.get('apple', 2)) > 10: pieces = count elif (count := fresh_fruit.get('banana', 2)) > 8: pieces = count elif (count := fresh_fruit.get('lemon', 2)) > 3: pieces = count else: pieces = 0 print(pieces) Result: 5 \u8981\u70b9\uff1a * \u8d4b\u503c\u8868\u8fbe\u5f0f\u901a\u8fc7\u6d77\u8c61\u64cd\u4f5c\u7b26\uff08:=\uff09\u7ed9\u53d8\u91cf\u8d4b\u503c\uff0c\u5e76\u4e14\u8ba9\u8fd9\u4e2a\u503c\u6210\u4e3a\u8fd9\u6761\u8868\u8fbe\u5f0f\u7684\u7ed3\u679c\uff0c\u4e8e\u662f\uff0c\u6211\u4eec\u53ef\u4ee5\u5229\u7528\u8fd9\u9879\u7279\u6027\u6765\u7f29\u51cf\u4ee3\u7801\u3002 * \u5982\u679c\u8d4b\u503c\u8868\u8fbe\u5f0f\u662f\u5927\u8868\u8fbe\u5f0f\u91cc\u7684\u4e00\u90e8\u5206\uff0c\u5c31\u5f97\u7528\u4e00\u5bf9\u62ec\u53f7\u628a\u5b83\u62ec\u8d77\u6765\u3002 * \u867d\u8bf4Python\u4e0d\u652f\u6301switch/case\u4e0edo/while\u7ed3\u6784\uff0c\u4f46\u53ef\u4ee5\u5229\u7528\u8d4b\u503c\u8868\u8fbe\u5f0f\u6e05\u6670\u5730\u6a21\u62df\u51fa\u8fd9\u79cd\u903b\u8f91\u3002","title":"\u7b2c10\u6761\u3000\u7528\u8d4b\u503c\u8868\u8fbe\u5f0f\u51cf\u5c11\u91cd\u590d\u4ee3\u7801"},{"location":"python/Pythonic90Rules/Rule10/#pep572","text":"","title":"\u8865\u5145\uff1aPEP572: \u6d77\u8c61\u8fd0\u7b97\u7b26"},{"location":"python/Pythonic90Rules/Rule10/#if-else","text":"\u4e00\u822c\u5199\u6cd5\uff1a a = 15 if a > 10: print('hello, it''s walrus') \u6d77\u8c61\u8fd0\u7b97\u7b26\uff1a if a := 15 > 10: print('hello, it''s walrus')","title":"\u7528\u4e8e if-else \u6761\u4ef6\u8868\u8fbe\u5f0f"},{"location":"python/Pythonic90Rules/Rule10/#while","text":"\u5e38\u89c4\u5199\u6cd5\uff1a n = 5 while n: print('hello walrus: ', n) n = n - 1 Result: hello walrus: 4 hello walrus: 3 hello walrus: 2 hello walrus: 1 hello walrus: 0 \u6d77\u8c61\u5199\u6cd5\uff1a n = 5 while (n := n - 1) + 1: print('hello walrus: ', n) Result: hello walrus: 4 hello walrus: 3 hello walrus: 2 hello walrus: 1 hello walrus: 0 \u5bc6\u7801\u6821\u9a8c\u5e38\u89c4\u5199\u6cd5\uff1a while True: psw = input('input password: ') if psw == '123': break \u5bc6\u7801\u6821\u9a8c\u6d77\u8c61\u5199\u6cd5\uff1a while (psw := input('input password: ')) != '123': continue","title":"\u7528\u4e8e while \u5faa\u73af"},{"location":"python/Pythonic90Rules/Rule10/#_1","text":"\u8ba1\u7b97\u5143\u7d20\u5e73\u65b9\u6839\uff0c\u5e76\u4fdd\u7559\u5e73\u65b9\u6839\u5927\u4e8e 5 \u7684\u503c\uff1a \u5e38\u89c4\u5199\u6cd5\uff1a(\u6ce8\u610f\uff0c\u6267\u884c\u4e867\u6b21\uff0c\u6ee1\u8db3\u6761\u4ef6\u76843\u4e2a\u6570\u5b57\u6267\u884c\u4e86\u4e24\u904d\uff0c\u7b2c\u4e00\u6b21\u6267\u884cfor\u540e\u9762\u7684if f(i) > 5\uff0c\u7b2c\u4e8c\u6b21\u6267\u884cfor\u524d\u9762\u7684f(i))\u3002 nums = [16, 36, 49, 64] def f(x): print('run f(x) 1 time: ', x) return x ** 0.5 print([f(i) for i in nums if f(i) > 5]) Result: run f(x) 1 time: 16 run f(x) 1 time: 36 run f(x) 1 time: 36 run f(x) 1 time: 49 run f(x) 1 time: 49 run f(x) 1 time: 64 run f(x) 1 time: 64 [6.0, 7.0, 8.0] \u6d77\u8c61\u5199\u6cd5\uff1a\uff08\u51fd\u6570\u53ea\u6267\u884c\u4e864\u6b21\uff0c\u6027\u80fd\u4f18\u4e8e\u4f20\u7edf\u5199\u6cd5\uff09 nums = [16, 36, 49, 64] def f(x): print('run f(x) 1 time: ', x) return x ** 0.5 print([n for i in nums if(n := f(i)) > 5]) Result: run f(x) 1 time: 16 run f(x) 1 time: 36 run f(x) 1 time: 49 run f(x) 1 time: 64 [6.0, 7.0, 8.0]","title":"\u7528\u4e8e\u5217\u8868\u63a8\u5bfc\u5f0f"},{"location":"python/Pythonic90Rules/Rule11/","text":"\u7b2c11\u6761\u3000\u5b66\u4f1a\u5bf9\u5e8f\u5217\u505a\u5207\u7247 \u00b6 Python\u5f00\u53d1\u8005\u6700\u559c\u6b22\u7528\u5217\u8868\uff08list\uff09\u7c7b\u578b\u6765\u5904\u7406\u4e00\u4e9b\u81ea\u52a8\u5904\u7406\u7684\u4efb\u52a1\uff0c\u628a\u6bcf\u9879\u4efb\u52a1\u90fd\u5f53\u6210\u5217\u8868\u4e2d\u7684\u4e00\u4e2a\u5143\u7d20\u3002 \u6709\u4e86\u5217\u8868\uff0c\u81ea\u7136\u5c31\u6709\u8ddf\u5b83\u4e92\u8865\u7684\u7ed3\u6784\uff0c\u4e5f\u5c31\u662f\u5b57\u5178\uff08dict\uff09\uff0c\u8fd9\u79cd\u7ed3\u6784\u53ef\u4ee5\u628a\u67e5\u8be2\u6240\u7528\u7684\u952e\u4e0e\u76f8\u5173\u7684\u503c\u5bf9\u5e94\u8d77\u6765\uff08\u6240\u4ee5\u4e5f\u53eb\u5173\u952e\u77e9\u9635\uff08associative array\uff09\u6216\u54c8\u5e0c\u8868\uff08hash table\uff09\uff09\u3002 \u5bf9\u4e8e\u5b57\u5178\u6765\u8bf4\uff0c\u8bbf\u95ee\u4e0e\u8d4b\u503c\u6240\u82b1\u7684\u65f6\u95f4\u5e73\u5747\u4e0b\u6765\u662f\u4e2a\u5e38\u91cf\uff0c\u6240\u4ee5\u8fd9\u79cd\u7ed3\u6784\u5f88\u9002\u5408\u4fdd\u5b58\u52a8\u6001\u7684\u4fe1\u606f\u3002","title":"\u7b2c11\u6761 \u5b66\u4f1a\u5bf9\u5e8f\u5217\u505a\u5207\u7247"},{"location":"python/Pythonic90Rules/Rule11/#11","text":"Python\u5f00\u53d1\u8005\u6700\u559c\u6b22\u7528\u5217\u8868\uff08list\uff09\u7c7b\u578b\u6765\u5904\u7406\u4e00\u4e9b\u81ea\u52a8\u5904\u7406\u7684\u4efb\u52a1\uff0c\u628a\u6bcf\u9879\u4efb\u52a1\u90fd\u5f53\u6210\u5217\u8868\u4e2d\u7684\u4e00\u4e2a\u5143\u7d20\u3002 \u6709\u4e86\u5217\u8868\uff0c\u81ea\u7136\u5c31\u6709\u8ddf\u5b83\u4e92\u8865\u7684\u7ed3\u6784\uff0c\u4e5f\u5c31\u662f\u5b57\u5178\uff08dict\uff09\uff0c\u8fd9\u79cd\u7ed3\u6784\u53ef\u4ee5\u628a\u67e5\u8be2\u6240\u7528\u7684\u952e\u4e0e\u76f8\u5173\u7684\u503c\u5bf9\u5e94\u8d77\u6765\uff08\u6240\u4ee5\u4e5f\u53eb\u5173\u952e\u77e9\u9635\uff08associative array\uff09\u6216\u54c8\u5e0c\u8868\uff08hash table\uff09\uff09\u3002 \u5bf9\u4e8e\u5b57\u5178\u6765\u8bf4\uff0c\u8bbf\u95ee\u4e0e\u8d4b\u503c\u6240\u82b1\u7684\u65f6\u95f4\u5e73\u5747\u4e0b\u6765\u662f\u4e2a\u5e38\u91cf\uff0c\u6240\u4ee5\u8fd9\u79cd\u7ed3\u6784\u5f88\u9002\u5408\u4fdd\u5b58\u52a8\u6001\u7684\u4fe1\u606f\u3002","title":"\u7b2c11\u6761\u3000\u5b66\u4f1a\u5bf9\u5e8f\u5217\u505a\u5207\u7247"},{"location":"python/Pythonic90Rules/Rule12/","text":"","title":"\u7b2c12\u6761 \u4e0d\u8981\u5728\u5207\u7247\u91cc\u540c\u65f6\u6307\u5b9a\u8d77\u6b62\u4e0b\u6807\u4e0e\u6b65\u8fdb"},{"location":"python/Pythonic90Rules/Rule13/","text":"","title":"\u7b2c13\u6761 \u901a\u8fc7\u5e26\u661f\u53f7\u7684unpacking\u64cd\u4f5c\u6765\u6355\u83b7\u591a\u4e2a\u5143\u7d20,\u4e0d\u8981\u7528\u5207\u7247"},{"location":"python/Pythonic90Rules/Rule14/","text":"","title":"\u7b2c14\u6761 \u7528sort\u65b9\u6cd5\u7684key\u53c2\u6570\u6765\u8868\u793a\u590d\u6742\u7684\u6392\u5e8f\u903b\u8f91"},{"location":"python/Pythonic90Rules/Rule15/","text":"","title":"\u7b2c15\u6761 \u4e0d\u8981\u8fc7\u5206\u4f9d\u8d56\u7ed9\u5b57\u5178\u6dfb\u52a0\u6761\u76ee\u65f6\u6240\u7528\u7684\u987a\u5e8f"},{"location":"python/Pythonic90Rules/Rule16/","text":"","title":"\u7b2c16\u6761 \u7528get\u5904\u7406\u952e\u4e0d\u5728\u5b57\u5178\u4e2d\u7684\u60c5\u51b5,\u4e0d\u8981\u4f7f\u7528in\u4e0eKeyError"},{"location":"python/Pythonic90Rules/Rule17/","text":"","title":"\u7b2c17\u6761 \u7528defaultdict\u5904\u7406\u5185\u90e8\u72b6\u6001\u4e2d\u7f3a\u5931\u7684\u5143\u7d20,\u800c\u4e0d\u8981\u7528setdefault"},{"location":"python/Pythonic90Rules/Rule18/","text":"","title":"\u7b2c18\u6761 \u5b66\u4f1a\u5229\u7528__missing__\u6784\u9020\u4f9d\u8d56\u952e\u7684\u9ed8\u8ba4\u503c"},{"location":"python/Pythonic90Rules/Rule19/","text":"","title":"\u7b2c19\u6761 \u4e0d\u8981\u628a\u51fd\u6570\u8fd4\u56de\u7684\u591a\u4e2a\u6570\u503c\u62c6\u5206\u5230\u4e09\u4e2a\u4ee5\u4e0a\u7684\u53d8\u91cf\u4e2d"},{"location":"python/Pythonic90Rules/Rule20/","text":"","title":"\u7b2c20\u6761 \u9047\u5230\u610f\u5916\u72b6\u51b5\u65f6\u5e94\u8be5\u629b\u51fa\u5f02\u5e38,\u4e0d\u8981\u8fd4\u56deNone"},{"location":"python/Pythonic90Rules/Rule21/","text":"","title":"\u7b2c21\u6761 \u4e86\u89e3\u5982\u4f55\u5728\u95ed\u5305\u91cc\u9762\u4f7f\u7528\u5916\u56f4\u4f5c\u7528\u57df\u4e2d\u7684\u53d8\u91cf"},{"location":"python/Pythonic90Rules/Rule22/","text":"","title":"\u7b2c22\u6761 \u7528\u6570\u91cf\u53ef\u53d8\u7684\u4f4d\u7f6e\u53c2\u6570\u7ed9\u51fd\u6570\u8bbe\u8ba1\u6e05\u6670\u7684\u53c2\u6570\u5217\u8868"},{"location":"python/Pythonic90Rules/Rule23/","text":"","title":"\u7b2c23\u6761 \u7528\u5173\u952e\u5b57\u53c2\u6570\u6765\u8868\u793a\u53ef\u9009\u7684\u884c\u4e3a"},{"location":"python/Pythonic90Rules/Rule24/","text":"","title":"\u7b2c24\u6761 \u7528None\u548cdocstring\u6765\u63cf\u8ff0\u9ed8\u8ba4\u503c\u4f1a\u53d8\u7684\u53c2\u6570"},{"location":"python/Pythonic90Rules/Rule25/","text":"","title":"\u7b2c25\u6761 \u7528\u53ea\u80fd\u4ee5\u5173\u952e\u5b57\u6307\u5b9a\u548c\u53ea\u80fd\u6309\u4f4d\u7f6e\u4f20\u5165\u7684\u53c2\u6570\u6765\u8bbe\u8ba1\u6e05\u6670\u7684\u53c2\u6570\u5217\u8868"},{"location":"python/Pythonic90Rules/Rule26/","text":"","title":"\u7b2c26\u6761 \u7528functools.wraps\u5b9a\u4e49\u51fd\u6570\u4fee\u9970\u5668"},{"location":"python/Pythonic90Rules/Rule27/","text":"","title":"\u7b2c27\u6761 \u7528\u5217\u8868\u63a8\u5bfc\u53d6\u4ee3map\u4e0efilter"},{"location":"python/Pythonic90Rules/Rule28/","text":"","title":"\u7b2c28\u6761 \u63a7\u5236\u63a8\u5bfc\u903b\u8f91\u7684\u5b50\u8868\u8fbe\u5f0f\u4e0d\u8981\u8d85\u8fc7\u4e24\u4e2a"},{"location":"python/Pythonic90Rules/Rule29/","text":"","title":"\u7b2c29\u6761 \u7528\u8d4b\u503c\u8868\u8fbe\u5f0f\u6d88\u9664\u63a8\u5bfc\u4e2d\u7684\u91cd\u590d\u4ee3\u7801"},{"location":"python/Pythonic90Rules/Rule30/","text":"","title":"\u7b2c30\u6761 \u4e0d\u8981\u8ba9\u51fd\u6570\u76f4\u63a5\u8fd4\u56de\u5217\u8868\uff0c\u5e94\u8be5\u8ba9\u5b83\u9010\u4e2a\u751f\u6210\u5217\u8868\u91cc\u7684\u503c"},{"location":"python/Pythonic90Rules/Rule31/","text":"","title":"\u7b2c31\u6761 \u8c28\u614e\u5730\u8fed\u4ee3\u51fd\u6570\u6240\u6536\u5230\u7684\u53c2\u6570"},{"location":"python/Pythonic90Rules/Rule32/","text":"","title":"\u7b2c32\u6761 \u8003\u8651\u7528\u751f\u6210\u5668\u8868\u8fbe\u5f0f\u6539\u5199\u6570\u636e\u91cf\u8f83\u5927\u7684\u5217\u8868\u63a8\u5bfc"},{"location":"python/Pythonic90Rules/Rule33/","text":"","title":"\u7b2c33\u6761 \u901a\u8fc7yield from\u628a\u591a\u4e2a\u751f\u6210\u5668\u8fde\u8d77\u6765\u7528"},{"location":"python/Pythonic90Rules/Rule34/","text":"","title":"\u7b2c34\u6761 \u4e0d\u8981\u7528send\u7ed9\u751f\u6210\u5668\u6ce8\u5165\u6570\u636e"},{"location":"python/Pythonic90Rules/Rule35/","text":"","title":"\u7b2c35\u6761 \u4e0d\u8981\u901a\u8fc7throw\u53d8\u6362\u751f\u6210\u5668\u7684\u72b6\u6001"},{"location":"python/Pythonic90Rules/Rule36/","text":"","title":"\u7b2c36\u6761 \u8003\u8651\u7528itertools\u62fc\u88c5\u8fed\u4ee3\u5668\u4e0e\u751f\u6210\u5668"},{"location":"python/Pythonic90Rules/Rule37/","text":"","title":"\u7b2c37\u6761 \u7528\u7ec4\u5408\u8d77\u6765\u7684\u7c7b\u6765\u5b9e\u73b0\u591a\u5c42\u7ed3\u6784\uff0c\u4e0d\u8981\u7528\u5d4c\u5957\u7684\u5185\u7f6e\u7c7b\u578b"},{"location":"python/Pythonic90Rules/Rule38/","text":"","title":"\u7b2c38\u6761 \u8ba9\u7b80\u5355\u7684\u63a5\u53e3\u63a5\u53d7\u51fd\u6570\uff0c\u800c\u4e0d\u662f\u7c7b\u7684\u5b9e\u4f8b"},{"location":"python/Pythonic90Rules/Rule39/","text":"","title":"\u7b2c39\u6761 \u901a\u8fc7@classmethod\u591a\u6001\u6765\u6784\u9020\u540c\u4e00\u4f53\u7cfb\u4e2d\u7684\u5404\u7c7b\u5bf9\u8c61"},{"location":"python/Pythonic90Rules/Rule40/","text":"","title":"\u7b2c40\u6761 \u901a\u8fc7super\u521d\u59cb\u5316\u8d85\u7c7b"},{"location":"python/Pythonic90Rules/Rule41/","text":"","title":"\u7b2c41\u6761 \u8003\u8651\u7528mix-in\u7c7b\u6765\u8868\u793a\u53ef\u7ec4\u5408\u7684\u529f\u80fd"},{"location":"python/Pythonic90Rules/Rule42/","text":"","title":"\u7b2c42\u6761 \u4f18\u5148\u8003\u8651\u7528public\u5c5e\u6027\u8868\u793a\u5e94\u53d7\u4fdd\u62a4\u7684\u6570\u636e,\u4e0d\u8981\u7528private\u5c5e\u6027\u8868\u793a"},{"location":"python/Pythonic90Rules/Rule43/","text":"","title":"\u7b2c43\u6761 \u81ea\u5b9a\u4e49\u7684\u5bb9\u5668\u7c7b\u578b\u5e94\u8be5\u4ececollections.abc\u7ee7\u627f"},{"location":"python/Pythonic90Rules/Rule44/","text":"","title":"\u7b2c44\u6761 \u7528\u7eaf\u5c5e\u6027\u4e0e\u4fee\u9970\u5668\u53d6\u4ee3\u65e7\u5f0f\u7684setter\u4e0egetter\u65b9\u6cd5"},{"location":"python/Pythonic90Rules/Rule45/","text":"","title":"\u7b2c45\u6761 \u8003\u8651\u7528@property\u5b9e\u73b0\u65b0\u7684\u5c5e\u6027\u8bbf\u95ee\u903b\u8f91,\u4e0d\u8981\u6025\u7740\u91cd\u6784\u539f\u6709\u7684\u4ee3\u7801"},{"location":"python/Pythonic90Rules/Rule46/","text":"","title":"\u7b2c46\u6761 \u7528\u63cf\u8ff0\u7b26\u6765\u6539\u5199\u9700\u8981\u590d\u7528\u7684@property\u65b9\u6cd5"},{"location":"python/Pythonic90Rules/Rule47/","text":"","title":"\u7b2c47\u6761 \u9488\u5bf9\u60f0\u6027\u5c5e\u6027\u4f7f\u7528__getattr__\u3001__getattribute__\u53ca__setattr__"},{"location":"python/Pythonic90Rules/Rule48/","text":"","title":"\u7b2c48\u6761 \u7528__init_subclass__\u9a8c\u8bc1\u5b50\u7c7b\u5199\u5f97\u662f\u5426\u6b63\u786e"},{"location":"python/Pythonic90Rules/Rule49/","text":"","title":"\u7b2c49\u6761 \u7528__init_subclass__\u8bb0\u5f55\u73b0\u6709\u7684\u5b50\u7c7b"},{"location":"python/Pythonic90Rules/Rule50/","text":"","title":"\u7b2c50\u6761 \u7528__set_name__\u7ed9\u7c7b\u5c5e\u6027\u52a0\u6ce8\u89e3"},{"location":"python/Pythonic90Rules/Rule51/","text":"","title":"\u7b2c51\u6761 \u4f18\u5148\u8003\u8651\u901a\u8fc7\u7c7b\u4fee\u9970\u5668\u6765\u63d0\u4f9b\u53ef\u7ec4\u5408\u7684\u6269\u5145\u529f\u80fd\uff0c\u4e0d\u8981\u4f7f\u7528\u5143\u7c7b"},{"location":"python/Pythonic90Rules/Rule52/","text":"","title":"\u7b2c52\u6761 \u7528subprocess\u7ba1\u7406\u5b50\u8fdb\u7a0b"},{"location":"python/Pythonic90Rules/Rule53/","text":"","title":"\u7b2c53\u6761 \u53ef\u4ee5\u7528\u7ebf\u7a0b\u6267\u884c\u963b\u585e\u5f0fI/O,\u4f46\u4e0d\u8981\u7528\u5b83\u505a\u5e76\u884c\u8ba1\u7b97"},{"location":"python/Pythonic90Rules/Rule54/","text":"","title":"\u7b2c54\u6761 \u5229\u7528Lock\u9632\u6b62\u591a\u4e2a\u7ebf\u7a0b\u4e89\u7528\u540c\u4e00\u4efd\u6570\u636e"},{"location":"python/Pythonic90Rules/Rule55/","text":"","title":"\u7b2c55\u6761 \u7528Queue\u6765\u534f\u8c03\u5404\u7ebf\u7a0b\u4e4b\u95f4\u7684\u5de5\u4f5c\u8fdb\u5ea6"},{"location":"python/Pythonic90Rules/Rule56/","text":"","title":"\u7b2c56\u6761 \u5b66\u4f1a\u5224\u65ad\u4ec0\u4e48\u573a\u5408\u5fc5\u987b\u505a\u5e76\u53d1"},{"location":"python/Pythonic90Rules/Rule57/","text":"","title":"\u7b2c57\u6761 \u4e0d\u8981\u5728\u6bcf\u6b21fan-out\u65f6\u90fd\u65b0\u5efa\u4e00\u6279Thread\u5b9e\u4f8b"},{"location":"python/Pythonic90Rules/Rule58/","text":"","title":"\u7b2c58\u6761 \u5b66\u4f1a\u6b63\u786e\u5730\u91cd\u6784\u4ee3\u7801,\u4ee5\u4fbf\u7528Queue\u505a\u5e76\u53d1"},{"location":"python/Pythonic90Rules/Rule59/","text":"","title":"\u7b2c59\u6761 \u5982\u679c\u5fc5\u987b\u7528\u7ebf\u7a0b\u505a\u5e76\u53d1,\u90a3\u5c31\u8003\u8651\u901a\u8fc7ThreadPoolExecutor\u5b9e\u73b0"},{"location":"python/Pythonic90Rules/Rule60/","text":"","title":"\u7b2c60\u6761 \u7528\u534f\u7a0b\u5b9e\u73b0\u9ad8\u5e76\u53d1\u7684I/O"},{"location":"python/Pythonic90Rules/Rule61/","text":"","title":"\u7b2c61\u6761 \u5b66\u4f1a\u7528asyncio\u6539\u5199\u90a3\u4e9b\u901a\u8fc7\u7ebf\u7a0b\u5b9e\u73b0\u7684I/O"},{"location":"python/Pythonic90Rules/Rule62/","text":"","title":"\u7b2c62\u6761 \u7ed3\u5408\u7ebf\u7a0b\u4e0e\u534f\u7a0b,\u5c06\u4ee3\u7801\u987a\u5229\u8fc1\u79fb\u5230asyncio"},{"location":"python/Pythonic90Rules/Rule63/","text":"","title":"\u7b2c63\u6761 \u8ba9asyncio\u7684\u4e8b\u4ef6\u5faa\u73af\u4fdd\u6301\u7545\u901a,\u4ee5\u4fbf\u8fdb\u4e00\u6b65\u63d0\u5347\u7a0b\u5e8f\u7684\u54cd\u5e94\u80fd\u529b"},{"location":"python/Pythonic90Rules/Rule64/","text":"","title":"\u7b2c64\u6761 \u8003\u8651\u7528concurrent.futures\u5b9e\u73b0\u771f\u6b63\u7684\u5e76\u884c\u8ba1\u7b97"},{"location":"python/Pythonic90Rules/Rule65/","text":"","title":"\u7b2c65\u6761 \u5408\u7406\u5229\u7528try/except/else/finally\u7ed3\u6784\u4e2d\u7684\u6bcf\u4e2a\u4ee3\u7801\u5757"},{"location":"python/Pythonic90Rules/Rule66/","text":"","title":"\u7b2c66\u6761 \u8003\u8651\u7528contextlib\u548cwith\u8bed\u53e5\u6765\u6539\u5199\u53ef\u590d\u7528\u7684try/finally\u4ee3\u7801"},{"location":"python/Pythonic90Rules/Rule67/","text":"","title":"\u7b2c67\u6761 \u7528datetime\u6a21\u5757\u5904\u7406\u672c\u5730\u65f6\u95f4,\u4e0d\u8981\u7528time\u6a21\u5757"},{"location":"python/Pythonic90Rules/Rule68/","text":"","title":"\u7b2c68\u6761 \u7528copyreg\u5b9e\u73b0\u53ef\u9760\u7684pickle\u64cd\u4f5c"},{"location":"python/Pythonic90Rules/Rule69/","text":"","title":"\u7b2c69\u6761 \u5728\u9700\u8981\u51c6\u786e\u8ba1\u7b97\u7684\u573a\u5408,\u7528decimal\u8868\u793a\u76f8\u5e94\u7684\u6570\u503c"},{"location":"python/Pythonic90Rules/Rule70/","text":"","title":"\u7b2c70\u6761 \u5148\u5206\u6790\u6027\u80fd\uff0c\u7136\u540e\u518d\u4f18\u5316"},{"location":"python/Pythonic90Rules/Rule71/","text":"","title":"\u7b2c71\u6761 \u4f18\u5148\u8003\u8651\u7528deque\u5b9e\u73b0\u751f\u4ea7\u8005-\u6d88\u8d39\u8005\u961f\u5217"},{"location":"python/Pythonic90Rules/Rule72/","text":"","title":"\u7b2c72\u6761 \u8003\u8651\u7528bisect\u641c\u7d22\u5df2\u6392\u5e8f\u7684\u5e8f\u5217"},{"location":"python/Pythonic90Rules/Rule73/","text":"","title":"\u7b2c73\u6761 \u5b66\u4f1a\u4f7f\u7528heapq\u5236\u4f5c\u4f18\u5148\u7ea7\u961f\u5217"},{"location":"python/Pythonic90Rules/Rule74/","text":"","title":"\u7b2c74\u6761 \u8003\u8651\u7528memoryview\u4e0ebytearray\u6765\u5b9e\u73b0\u65e0\u987b\u62f7\u8d1d\u7684bytes\u64cd\u4f5c"},{"location":"python/Pythonic90Rules/Rule75/","text":"","title":"\u7b2c75\u6761 \u901a\u8fc7repr\u5b57\u7b26\u4e32\u8f93\u51fa\u8c03\u8bd5\u4fe1\u606f"},{"location":"python/Pythonic90Rules/Rule76/","text":"","title":"\u7b2c76\u6761 \u5728TestCase\u5b50\u7c7b\u91cc\u9a8c\u8bc1\u76f8\u5173\u7684\u884c\u4e3a"},{"location":"python/Pythonic90Rules/Rule77/","text":"","title":"\u7b2c77\u6761 \u628a\u6d4b\u8bd5\u524d\u3001\u540e\u7684\u51c6\u5907\u4e0e\u6e05\u7406\u903b\u8f91\u5199\u5728setUp\u3001tearDown\u3001setUpModule\u4e0etearDownModule\u4e2d,\u4ee5\u9632\u7528\u4f8b\u4e4b\u95f4\u4e92\u76f8\u5e72\u6270"},{"location":"python/Pythonic90Rules/Rule78/","text":"","title":"\u7b2c78\u6761 \u7528Mock\u6765\u6a21\u62df\u53d7\u6d4b\u4ee3\u7801\u6240\u4f9d\u8d56\u7684\u590d\u6742\u51fd\u6570"},{"location":"python/Pythonic90Rules/Rule79/","text":"","title":"\u7b2c79\u6761 \u628a\u53d7\u6d4b\u4ee3\u7801\u6240\u4f9d\u8d56\u7684\u7cfb\u7edf\u5c01\u88c5\u8d77\u6765\uff0c\u4ee5\u4fbf\u4e8e\u6a21\u62df\u548c\u6d4b\u8bd5"},{"location":"python/Pythonic90Rules/Rule80/","text":"","title":"\u7b2c80\u6761 \u8003\u8651\u7528pdb\u505a\u4ea4\u4e92\u8c03\u8bd5"},{"location":"python/Pythonic90Rules/Rule81/","text":"","title":"\u7b2c81\u6761 \u7528tracemalloc\u6765\u638c\u63e1\u5185\u5b58\u7684\u4f7f\u7528\u4e0e\u6cc4\u6f0f\u60c5\u51b5"},{"location":"python/Pythonic90Rules/Rule82/","text":"","title":"\u7b2c82\u6761 \u5b66\u4f1a\u5bfb\u627e\u7531\u5176\u4ed6Python\u5f00\u53d1\u8005\u6240\u6784\u5efa\u7684\u6a21\u5757"},{"location":"python/Pythonic90Rules/Rule83/","text":"","title":"\u7b2c83\u6761 \u7528\u865a\u62df\u73af\u5883\u9694\u79bb\u9879\u76ee,\u5e76\u91cd\u5efa\u4f9d\u8d56\u5173\u7cfb"},{"location":"python/Pythonic90Rules/Rule84/","text":"","title":"\u7b2c84\u6761 \u6bcf\u4e00\u4e2a\u51fd\u6570\u3001\u7c7b\u4e0e\u6a21\u5757\u90fd\u8981\u5199docstring"},{"location":"python/Pythonic90Rules/Rule85/","text":"","title":"\u7b2c85\u6761 \u7528\u5305\u6765\u5b89\u6392\u6a21\u5757,\u4ee5\u63d0\u4f9b\u7a33\u56fa\u7684API"},{"location":"python/Pythonic90Rules/Rule86/","text":"","title":"\u7b2c86\u6761 \u8003\u8651\u7528\u6a21\u5757\u7ea7\u522b\u7684\u4ee3\u7801\u914d\u7f6e\u4e0d\u540c\u7684\u90e8\u7f72\u73af\u5883"},{"location":"python/Pythonic90Rules/Rule87/","text":"","title":"\u7b2c87\u6761 \u4e3a\u81ea\u7f16\u7684\u6a21\u5757\u5b9a\u4e49\u6839\u5f02\u5e38,\u8ba9\u8c03\u7528\u8005\u80fd\u591f\u4e13\u95e8\u5904\u7406\u4e0e\u6b64API\u6709\u5173\u7684\u5f02\u5e38"},{"location":"python/Pythonic90Rules/Rule88/","text":"","title":"\u7b2c88\u6761 \u7528\u9002\u5f53\u7684\u65b9\u5f0f\u6253\u7834\u5faa\u73af\u4f9d\u8d56\u5173\u7cfb"},{"location":"python/Pythonic90Rules/Rule89/","text":"","title":"\u7b2c89\u6761 \u91cd\u6784\u65f6\u8003\u8651\u901a\u8fc7warnings\u63d0\u9192\u5f00\u53d1\u8005API\u5df2\u7ecf\u53d1\u751f\u53d8\u5316"},{"location":"python/Pythonic90Rules/Rule90/","text":"","title":"\u7b2c90\u6761 \u8003\u8651\u901a\u8fc7typing\u505a\u9759\u6001\u5206\u6790,\u4ee5\u6d88\u9664bug"}]} \ No newline at end of file diff --git a/sitemap.xml b/sitemap.xml index 0e3e124d..ed454b09 100644 --- a/sitemap.xml +++ b/sitemap.xml @@ -2,972 +2,972 @@ https://huyuhui001.github.io/mySite/ - 2024-02-15 + 2024-02-18 daily https://huyuhui001.github.io/mySite/about/ - 2024-02-15 + 2024-02-18 daily https://huyuhui001.github.io/mySite/Reading/Developers/ - 2024-02-15 + 2024-02-18 daily https://huyuhui001.github.io/mySite/k8s/ - 2024-02-15 + 2024-02-18 daily https://huyuhui001.github.io/mySite/k8s/cka_cn/foundamentals/basics/ - 2024-02-15 + 2024-02-18 daily https://huyuhui001.github.io/mySite/k8s/cka_cn/foundamentals/casestudy-calico/ - 2024-02-15 + 2024-02-18 daily https://huyuhui001.github.io/mySite/k8s/cka_cn/foundamentals/casestudy-health-check/ - 2024-02-15 + 2024-02-18 daily https://huyuhui001.github.io/mySite/k8s/cka_cn/foundamentals/casestudy-operation-resources/ - 2024-02-15 + 2024-02-18 daily https://huyuhui001.github.io/mySite/k8s/cka_cn/foundamentals/clustermgt/ - 2024-02-15 + 2024-02-18 daily https://huyuhui001.github.io/mySite/k8s/cka_cn/foundamentals/configuration/ - 2024-02-15 + 2024-02-18 daily https://huyuhui001.github.io/mySite/k8s/cka_cn/foundamentals/daemonset/ - 2024-02-15 + 2024-02-18 daily https://huyuhui001.github.io/mySite/k8s/cka_cn/foundamentals/deployment/ - 2024-02-15 + 2024-02-18 daily https://huyuhui001.github.io/mySite/k8s/cka_cn/foundamentals/docker/ - 2024-02-15 + 2024-02-18 daily https://huyuhui001.github.io/mySite/k8s/cka_cn/foundamentals/healthcheck/ - 2024-02-15 + 2024-02-18 daily https://huyuhui001.github.io/mySite/k8s/cka_cn/foundamentals/helming/ - 2024-02-15 + 2024-02-18 daily https://huyuhui001.github.io/mySite/k8s/cka_cn/foundamentals/hpa/ - 2024-02-15 + 2024-02-18 daily https://huyuhui001.github.io/mySite/k8s/cka_cn/foundamentals/ingress/ - 2024-02-15 + 2024-02-18 daily https://huyuhui001.github.io/mySite/k8s/cka_cn/foundamentals/job/ - 2024-02-15 + 2024-02-18 daily https://huyuhui001.github.io/mySite/k8s/cka_cn/foundamentals/memo/ - 2024-02-15 + 2024-02-18 daily https://huyuhui001.github.io/mySite/k8s/cka_cn/foundamentals/namespace/ - 2024-02-15 + 2024-02-18 daily https://huyuhui001.github.io/mySite/k8s/cka_cn/foundamentals/networkpolicy/ - 2024-02-15 + 2024-02-18 daily https://huyuhui001.github.io/mySite/k8s/cka_cn/foundamentals/overview/ - 2024-02-15 + 2024-02-18 daily https://huyuhui001.github.io/mySite/k8s/cka_cn/foundamentals/persistence/ - 2024-02-15 + 2024-02-18 daily https://huyuhui001.github.io/mySite/k8s/cka_cn/foundamentals/pod/ - 2024-02-15 + 2024-02-18 daily https://huyuhui001.github.io/mySite/k8s/cka_cn/foundamentals/policy/ - 2024-02-15 + 2024-02-18 daily https://huyuhui001.github.io/mySite/k8s/cka_cn/foundamentals/rbac/ - 2024-02-15 + 2024-02-18 daily https://huyuhui001.github.io/mySite/k8s/cka_cn/foundamentals/scheduling/ - 2024-02-15 + 2024-02-18 daily https://huyuhui001.github.io/mySite/k8s/cka_cn/foundamentals/secrets/ - 2024-02-15 + 2024-02-18 daily https://huyuhui001.github.io/mySite/k8s/cka_cn/foundamentals/service/ - 2024-02-15 + 2024-02-18 daily https://huyuhui001.github.io/mySite/k8s/cka_cn/foundamentals/statefulset/ - 2024-02-15 + 2024-02-18 daily https://huyuhui001.github.io/mySite/k8s/cka_cn/foundamentals/troubleshooting/ - 2024-02-15 + 2024-02-18 daily https://huyuhui001.github.io/mySite/k8s/cka_cn/installation/aliyun-ubuntu/ - 2024-02-15 + 2024-02-18 daily https://huyuhui001.github.io/mySite/k8s/cka_cn/installation/multiple-local/ - 2024-02-15 + 2024-02-18 daily https://huyuhui001.github.io/mySite/k8s/cka_cn/installation/single-local/ - 2024-02-15 + 2024-02-18 daily https://huyuhui001.github.io/mySite/k8s/cka_en/foundamentals/basics/ - 2024-02-15 + 2024-02-18 daily https://huyuhui001.github.io/mySite/k8s/cka_en/foundamentals/casestudy-calico/ - 2024-02-15 + 2024-02-18 daily https://huyuhui001.github.io/mySite/k8s/cka_en/foundamentals/casestudy-health-check/ - 2024-02-15 + 2024-02-18 daily https://huyuhui001.github.io/mySite/k8s/cka_en/foundamentals/casestudy-operation-resources/ - 2024-02-15 + 2024-02-18 daily https://huyuhui001.github.io/mySite/k8s/cka_en/foundamentals/clustermgt/ - 2024-02-15 + 2024-02-18 daily https://huyuhui001.github.io/mySite/k8s/cka_en/foundamentals/configuration/ - 2024-02-15 + 2024-02-18 daily https://huyuhui001.github.io/mySite/k8s/cka_en/foundamentals/daemonset/ - 2024-02-15 + 2024-02-18 daily https://huyuhui001.github.io/mySite/k8s/cka_en/foundamentals/deployment/ - 2024-02-15 + 2024-02-18 daily https://huyuhui001.github.io/mySite/k8s/cka_en/foundamentals/docker/ - 2024-02-15 + 2024-02-18 daily https://huyuhui001.github.io/mySite/k8s/cka_en/foundamentals/healthcheck/ - 2024-02-15 + 2024-02-18 daily https://huyuhui001.github.io/mySite/k8s/cka_en/foundamentals/helming/ - 2024-02-15 + 2024-02-18 daily https://huyuhui001.github.io/mySite/k8s/cka_en/foundamentals/hpa/ - 2024-02-15 + 2024-02-18 daily https://huyuhui001.github.io/mySite/k8s/cka_en/foundamentals/ingress/ - 2024-02-15 + 2024-02-18 daily https://huyuhui001.github.io/mySite/k8s/cka_en/foundamentals/job/ - 2024-02-15 + 2024-02-18 daily https://huyuhui001.github.io/mySite/k8s/cka_en/foundamentals/kyma/ - 2024-02-15 + 2024-02-18 daily https://huyuhui001.github.io/mySite/k8s/cka_en/foundamentals/memo/ - 2024-02-15 + 2024-02-18 daily https://huyuhui001.github.io/mySite/k8s/cka_en/foundamentals/namespace/ - 2024-02-15 + 2024-02-18 daily https://huyuhui001.github.io/mySite/k8s/cka_en/foundamentals/networkpolicy/ - 2024-02-15 + 2024-02-18 daily https://huyuhui001.github.io/mySite/k8s/cka_en/foundamentals/overview/ - 2024-02-15 + 2024-02-18 daily https://huyuhui001.github.io/mySite/k8s/cka_en/foundamentals/persistence/ - 2024-02-15 + 2024-02-18 daily https://huyuhui001.github.io/mySite/k8s/cka_en/foundamentals/pod/ - 2024-02-15 + 2024-02-18 daily https://huyuhui001.github.io/mySite/k8s/cka_en/foundamentals/policy/ - 2024-02-15 + 2024-02-18 daily https://huyuhui001.github.io/mySite/k8s/cka_en/foundamentals/rbac/ - 2024-02-15 + 2024-02-18 daily https://huyuhui001.github.io/mySite/k8s/cka_en/foundamentals/scheduling/ - 2024-02-15 + 2024-02-18 daily https://huyuhui001.github.io/mySite/k8s/cka_en/foundamentals/secrets/ - 2024-02-15 + 2024-02-18 daily https://huyuhui001.github.io/mySite/k8s/cka_en/foundamentals/service/ - 2024-02-15 + 2024-02-18 daily https://huyuhui001.github.io/mySite/k8s/cka_en/foundamentals/statefulset/ - 2024-02-15 + 2024-02-18 daily https://huyuhui001.github.io/mySite/k8s/cka_en/foundamentals/troubleshooting/ - 2024-02-15 + 2024-02-18 daily https://huyuhui001.github.io/mySite/k8s/cka_en/installation/aliyun-ubuntu/ - 2024-02-15 + 2024-02-18 daily https://huyuhui001.github.io/mySite/k8s/cka_en/installation/multiple-local/ - 2024-02-15 + 2024-02-18 daily https://huyuhui001.github.io/mySite/k8s/cka_en/installation/single-local/ - 2024-02-15 + 2024-02-18 daily https://huyuhui001.github.io/mySite/k8s/demo/cap_on_kyma/ - 2024-02-15 + 2024-02-18 daily https://huyuhui001.github.io/mySite/linux/ - 2024-02-15 + 2024-02-18 daily https://huyuhui001.github.io/mySite/linux/Administration/01/ - 2024-02-15 + 2024-02-18 daily https://huyuhui001.github.io/mySite/linux/Administration/02/ - 2024-02-15 + 2024-02-18 daily https://huyuhui001.github.io/mySite/linux/Administration/03/ - 2024-02-15 + 2024-02-18 daily https://huyuhui001.github.io/mySite/linux/SES/linux_ses_demo/ - 2024-02-15 + 2024-02-18 daily https://huyuhui001.github.io/mySite/linux/SES/linux_ses_memo/ - 2024-02-15 + 2024-02-18 daily https://huyuhui001.github.io/mySite/linux/SRE/01-fundamentals/ - 2024-02-15 + 2024-02-18 daily https://huyuhui001.github.io/mySite/linux/SRE/02-filesystem/ - 2024-02-15 + 2024-02-18 daily https://huyuhui001.github.io/mySite/linux/SRE/03-identity-security/ - 2024-02-15 + 2024-02-18 daily https://huyuhui001.github.io/mySite/linux/SRE/04-TextTools/ - 2024-02-15 + 2024-02-18 daily https://huyuhui001.github.io/mySite/linux/SRE/05-RegExpress/ - 2024-02-15 + 2024-02-18 daily https://huyuhui001.github.io/mySite/linux/SRE/06-FileLookup/ - 2024-02-15 + 2024-02-18 daily https://huyuhui001.github.io/mySite/linux/SRE/07-FilePacking/ - 2024-02-15 + 2024-02-18 daily https://huyuhui001.github.io/mySite/python/ - 2024-02-15 + 2024-02-18 daily https://huyuhui001.github.io/mySite/python/DataAnalysis/ch01/ - 2024-02-15 + 2024-02-18 daily https://huyuhui001.github.io/mySite/python/DataAnalysis/ch02/ - 2024-02-15 + 2024-02-18 daily https://huyuhui001.github.io/mySite/python/DataAnalysis/ch03/ - 2024-02-15 + 2024-02-18 daily https://huyuhui001.github.io/mySite/python/DataAnalysis/ch04/ - 2024-02-15 + 2024-02-18 daily https://huyuhui001.github.io/mySite/python/DataAnalysis/ch05/ - 2024-02-15 + 2024-02-18 daily https://huyuhui001.github.io/mySite/python/DataAnalysis/ch06/ - 2024-02-15 + 2024-02-18 daily https://huyuhui001.github.io/mySite/python/DataAnalysis/ch07/ - 2024-02-15 + 2024-02-18 daily https://huyuhui001.github.io/mySite/python/DataAnalysis/ch08/ - 2024-02-15 + 2024-02-18 daily https://huyuhui001.github.io/mySite/python/DataAnalysis/ch09/ - 2024-02-15 + 2024-02-18 daily https://huyuhui001.github.io/mySite/python/DataAnalysis/ch10/ - 2024-02-15 + 2024-02-18 daily https://huyuhui001.github.io/mySite/python/DataAnalysis/ch11/ - 2024-02-15 + 2024-02-18 daily https://huyuhui001.github.io/mySite/python/DataStructure/01_PythonFundmantal/ - 2024-02-15 + 2024-02-18 daily https://huyuhui001.github.io/mySite/python/DataStructure/02_CollectionsOverview/ - 2024-02-15 + 2024-02-18 daily https://huyuhui001.github.io/mySite/python/DataStructure/03_TimeComplexity/ - 2024-02-15 + 2024-02-18 daily https://huyuhui001.github.io/mySite/python/DataStructure/04_ArrayChain/ - 2024-02-15 + 2024-02-18 daily https://huyuhui001.github.io/mySite/python/DataStructure/05_InterfacePolymorphism/ - 2024-02-15 + 2024-02-18 daily https://huyuhui001.github.io/mySite/python/DataStructure/06_InheritanceAbstractClass/ - 2024-02-15 + 2024-02-18 daily https://huyuhui001.github.io/mySite/python/Demo/CourseSystem/ - 2024-02-15 + 2024-02-18 daily https://huyuhui001.github.io/mySite/python/Foundation/ch00/ - 2024-02-15 + 2024-02-18 daily https://huyuhui001.github.io/mySite/python/Foundation/ch01/ - 2024-02-15 + 2024-02-18 daily https://huyuhui001.github.io/mySite/python/Foundation/ch02/ - 2024-02-15 + 2024-02-18 daily https://huyuhui001.github.io/mySite/python/Foundation/ch03/ - 2024-02-15 + 2024-02-18 daily https://huyuhui001.github.io/mySite/python/Foundation/ch04/ - 2024-02-15 + 2024-02-18 daily https://huyuhui001.github.io/mySite/python/Foundation/ch05/ - 2024-02-15 + 2024-02-18 daily https://huyuhui001.github.io/mySite/python/Pythonic90Rules/Rule01/ - 2024-02-15 + 2024-02-18 daily https://huyuhui001.github.io/mySite/python/Pythonic90Rules/Rule02/ - 2024-02-15 + 2024-02-18 daily https://huyuhui001.github.io/mySite/python/Pythonic90Rules/Rule03/ - 2024-02-15 + 2024-02-18 daily https://huyuhui001.github.io/mySite/python/Pythonic90Rules/Rule04/ - 2024-02-15 + 2024-02-18 daily https://huyuhui001.github.io/mySite/python/Pythonic90Rules/Rule05/ - 2024-02-15 + 2024-02-18 daily https://huyuhui001.github.io/mySite/python/Pythonic90Rules/Rule06/ - 2024-02-15 + 2024-02-18 daily https://huyuhui001.github.io/mySite/python/Pythonic90Rules/Rule07/ - 2024-02-15 + 2024-02-18 daily https://huyuhui001.github.io/mySite/python/Pythonic90Rules/Rule08/ - 2024-02-15 + 2024-02-18 daily https://huyuhui001.github.io/mySite/python/Pythonic90Rules/Rule09/ - 2024-02-15 + 2024-02-18 daily https://huyuhui001.github.io/mySite/python/Pythonic90Rules/Rule10/ - 2024-02-15 + 2024-02-18 daily https://huyuhui001.github.io/mySite/python/Pythonic90Rules/Rule11/ - 2024-02-15 + 2024-02-18 daily https://huyuhui001.github.io/mySite/python/Pythonic90Rules/Rule12/ - 2024-02-15 + 2024-02-18 daily https://huyuhui001.github.io/mySite/python/Pythonic90Rules/Rule13/ - 2024-02-15 + 2024-02-18 daily https://huyuhui001.github.io/mySite/python/Pythonic90Rules/Rule14/ - 2024-02-15 + 2024-02-18 daily https://huyuhui001.github.io/mySite/python/Pythonic90Rules/Rule15/ - 2024-02-15 + 2024-02-18 daily https://huyuhui001.github.io/mySite/python/Pythonic90Rules/Rule16/ - 2024-02-15 + 2024-02-18 daily https://huyuhui001.github.io/mySite/python/Pythonic90Rules/Rule17/ - 2024-02-15 + 2024-02-18 daily https://huyuhui001.github.io/mySite/python/Pythonic90Rules/Rule18/ - 2024-02-15 + 2024-02-18 daily https://huyuhui001.github.io/mySite/python/Pythonic90Rules/Rule19/ - 2024-02-15 + 2024-02-18 daily https://huyuhui001.github.io/mySite/python/Pythonic90Rules/Rule20/ - 2024-02-15 + 2024-02-18 daily https://huyuhui001.github.io/mySite/python/Pythonic90Rules/Rule21/ - 2024-02-15 + 2024-02-18 daily https://huyuhui001.github.io/mySite/python/Pythonic90Rules/Rule22/ - 2024-02-15 + 2024-02-18 daily https://huyuhui001.github.io/mySite/python/Pythonic90Rules/Rule23/ - 2024-02-15 + 2024-02-18 daily https://huyuhui001.github.io/mySite/python/Pythonic90Rules/Rule24/ - 2024-02-15 + 2024-02-18 daily https://huyuhui001.github.io/mySite/python/Pythonic90Rules/Rule25/ - 2024-02-15 + 2024-02-18 daily https://huyuhui001.github.io/mySite/python/Pythonic90Rules/Rule26/ - 2024-02-15 + 2024-02-18 daily https://huyuhui001.github.io/mySite/python/Pythonic90Rules/Rule27/ - 2024-02-15 + 2024-02-18 daily https://huyuhui001.github.io/mySite/python/Pythonic90Rules/Rule28/ - 2024-02-15 + 2024-02-18 daily https://huyuhui001.github.io/mySite/python/Pythonic90Rules/Rule29/ - 2024-02-15 + 2024-02-18 daily https://huyuhui001.github.io/mySite/python/Pythonic90Rules/Rule30/ - 2024-02-15 + 2024-02-18 daily https://huyuhui001.github.io/mySite/python/Pythonic90Rules/Rule31/ - 2024-02-15 + 2024-02-18 daily https://huyuhui001.github.io/mySite/python/Pythonic90Rules/Rule32/ - 2024-02-15 + 2024-02-18 daily https://huyuhui001.github.io/mySite/python/Pythonic90Rules/Rule33/ - 2024-02-15 + 2024-02-18 daily https://huyuhui001.github.io/mySite/python/Pythonic90Rules/Rule34/ - 2024-02-15 + 2024-02-18 daily https://huyuhui001.github.io/mySite/python/Pythonic90Rules/Rule35/ - 2024-02-15 + 2024-02-18 daily https://huyuhui001.github.io/mySite/python/Pythonic90Rules/Rule36/ - 2024-02-15 + 2024-02-18 daily https://huyuhui001.github.io/mySite/python/Pythonic90Rules/Rule37/ - 2024-02-15 + 2024-02-18 daily https://huyuhui001.github.io/mySite/python/Pythonic90Rules/Rule38/ - 2024-02-15 + 2024-02-18 daily https://huyuhui001.github.io/mySite/python/Pythonic90Rules/Rule39/ - 2024-02-15 + 2024-02-18 daily https://huyuhui001.github.io/mySite/python/Pythonic90Rules/Rule40/ - 2024-02-15 + 2024-02-18 daily https://huyuhui001.github.io/mySite/python/Pythonic90Rules/Rule41/ - 2024-02-15 + 2024-02-18 daily https://huyuhui001.github.io/mySite/python/Pythonic90Rules/Rule42/ - 2024-02-15 + 2024-02-18 daily https://huyuhui001.github.io/mySite/python/Pythonic90Rules/Rule43/ - 2024-02-15 + 2024-02-18 daily https://huyuhui001.github.io/mySite/python/Pythonic90Rules/Rule44/ - 2024-02-15 + 2024-02-18 daily https://huyuhui001.github.io/mySite/python/Pythonic90Rules/Rule45/ - 2024-02-15 + 2024-02-18 daily https://huyuhui001.github.io/mySite/python/Pythonic90Rules/Rule46/ - 2024-02-15 + 2024-02-18 daily https://huyuhui001.github.io/mySite/python/Pythonic90Rules/Rule47/ - 2024-02-15 + 2024-02-18 daily https://huyuhui001.github.io/mySite/python/Pythonic90Rules/Rule48/ - 2024-02-15 + 2024-02-18 daily https://huyuhui001.github.io/mySite/python/Pythonic90Rules/Rule49/ - 2024-02-15 + 2024-02-18 daily https://huyuhui001.github.io/mySite/python/Pythonic90Rules/Rule50/ - 2024-02-15 + 2024-02-18 daily https://huyuhui001.github.io/mySite/python/Pythonic90Rules/Rule51/ - 2024-02-15 + 2024-02-18 daily https://huyuhui001.github.io/mySite/python/Pythonic90Rules/Rule52/ - 2024-02-15 + 2024-02-18 daily https://huyuhui001.github.io/mySite/python/Pythonic90Rules/Rule53/ - 2024-02-15 + 2024-02-18 daily https://huyuhui001.github.io/mySite/python/Pythonic90Rules/Rule54/ - 2024-02-15 + 2024-02-18 daily https://huyuhui001.github.io/mySite/python/Pythonic90Rules/Rule55/ - 2024-02-15 + 2024-02-18 daily https://huyuhui001.github.io/mySite/python/Pythonic90Rules/Rule56/ - 2024-02-15 + 2024-02-18 daily https://huyuhui001.github.io/mySite/python/Pythonic90Rules/Rule57/ - 2024-02-15 + 2024-02-18 daily https://huyuhui001.github.io/mySite/python/Pythonic90Rules/Rule58/ - 2024-02-15 + 2024-02-18 daily https://huyuhui001.github.io/mySite/python/Pythonic90Rules/Rule59/ - 2024-02-15 + 2024-02-18 daily https://huyuhui001.github.io/mySite/python/Pythonic90Rules/Rule60/ - 2024-02-15 + 2024-02-18 daily https://huyuhui001.github.io/mySite/python/Pythonic90Rules/Rule61/ - 2024-02-15 + 2024-02-18 daily https://huyuhui001.github.io/mySite/python/Pythonic90Rules/Rule62/ - 2024-02-15 + 2024-02-18 daily https://huyuhui001.github.io/mySite/python/Pythonic90Rules/Rule63/ - 2024-02-15 + 2024-02-18 daily https://huyuhui001.github.io/mySite/python/Pythonic90Rules/Rule64/ - 2024-02-15 + 2024-02-18 daily https://huyuhui001.github.io/mySite/python/Pythonic90Rules/Rule65/ - 2024-02-15 + 2024-02-18 daily https://huyuhui001.github.io/mySite/python/Pythonic90Rules/Rule66/ - 2024-02-15 + 2024-02-18 daily https://huyuhui001.github.io/mySite/python/Pythonic90Rules/Rule67/ - 2024-02-15 + 2024-02-18 daily https://huyuhui001.github.io/mySite/python/Pythonic90Rules/Rule68/ - 2024-02-15 + 2024-02-18 daily https://huyuhui001.github.io/mySite/python/Pythonic90Rules/Rule69/ - 2024-02-15 + 2024-02-18 daily https://huyuhui001.github.io/mySite/python/Pythonic90Rules/Rule70/ - 2024-02-15 + 2024-02-18 daily https://huyuhui001.github.io/mySite/python/Pythonic90Rules/Rule71/ - 2024-02-15 + 2024-02-18 daily https://huyuhui001.github.io/mySite/python/Pythonic90Rules/Rule72/ - 2024-02-15 + 2024-02-18 daily https://huyuhui001.github.io/mySite/python/Pythonic90Rules/Rule73/ - 2024-02-15 + 2024-02-18 daily https://huyuhui001.github.io/mySite/python/Pythonic90Rules/Rule74/ - 2024-02-15 + 2024-02-18 daily https://huyuhui001.github.io/mySite/python/Pythonic90Rules/Rule75/ - 2024-02-15 + 2024-02-18 daily https://huyuhui001.github.io/mySite/python/Pythonic90Rules/Rule76/ - 2024-02-15 + 2024-02-18 daily https://huyuhui001.github.io/mySite/python/Pythonic90Rules/Rule77/ - 2024-02-15 + 2024-02-18 daily https://huyuhui001.github.io/mySite/python/Pythonic90Rules/Rule78/ - 2024-02-15 + 2024-02-18 daily https://huyuhui001.github.io/mySite/python/Pythonic90Rules/Rule79/ - 2024-02-15 + 2024-02-18 daily https://huyuhui001.github.io/mySite/python/Pythonic90Rules/Rule80/ - 2024-02-15 + 2024-02-18 daily https://huyuhui001.github.io/mySite/python/Pythonic90Rules/Rule81/ - 2024-02-15 + 2024-02-18 daily https://huyuhui001.github.io/mySite/python/Pythonic90Rules/Rule82/ - 2024-02-15 + 2024-02-18 daily https://huyuhui001.github.io/mySite/python/Pythonic90Rules/Rule83/ - 2024-02-15 + 2024-02-18 daily https://huyuhui001.github.io/mySite/python/Pythonic90Rules/Rule84/ - 2024-02-15 + 2024-02-18 daily https://huyuhui001.github.io/mySite/python/Pythonic90Rules/Rule85/ - 2024-02-15 + 2024-02-18 daily https://huyuhui001.github.io/mySite/python/Pythonic90Rules/Rule86/ - 2024-02-15 + 2024-02-18 daily https://huyuhui001.github.io/mySite/python/Pythonic90Rules/Rule87/ - 2024-02-15 + 2024-02-18 daily https://huyuhui001.github.io/mySite/python/Pythonic90Rules/Rule88/ - 2024-02-15 + 2024-02-18 daily https://huyuhui001.github.io/mySite/python/Pythonic90Rules/Rule89/ - 2024-02-15 + 2024-02-18 daily https://huyuhui001.github.io/mySite/python/Pythonic90Rules/Rule90/ - 2024-02-15 + 2024-02-18 daily \ No newline at end of file diff --git a/sitemap.xml.gz b/sitemap.xml.gz index 50c4c687..30dbcda2 100644 Binary files a/sitemap.xml.gz and b/sitemap.xml.gz differ